diff --git a/.cproject b/.cproject index ee5b854..23d9a73 100644 --- a/.cproject +++ b/.cproject @@ -142,7 +142,6 @@ - @@ -390,7 +389,6 @@ - @@ -571,7 +569,6 @@ - diff --git a/ExampleHTM/dygraph/dygraph.css b/ExampleHTM/dygraph/dygraph.css new file mode 100644 index 0000000..75d5868 --- /dev/null +++ b/ExampleHTM/dygraph/dygraph.css @@ -0,0 +1,117 @@ +/** + * Default styles for the dygraphs charting library. + */ + +.dygraph-legend { + position: absolute; + font-size: 14px; + z-index: 10; + width: 250px; /* labelsDivWidth */ + /* + dygraphs determines these based on the presence of chart labels. + It might make more sense to create a wrapper div around the chart proper. + top: 0px; + right: 2px; + */ + background: white; + line-height: normal; + text-align: left; + overflow: hidden; +} + +/* styles for a solid line in the legend */ +.dygraph-legend-line { + display: inline-block; + position: relative; + bottom: .5ex; + padding-left: 1em; + height: 1px; + border-bottom-width: 2px; + border-bottom-style: solid; + /* border-bottom-color is set based on the series color */ +} + +/* styles for a dashed line in the legend, e.g. when strokePattern is set */ +.dygraph-legend-dash { + display: inline-block; + position: relative; + bottom: .5ex; + height: 1px; + border-bottom-width: 2px; + border-bottom-style: solid; + /* border-bottom-color is set based on the series color */ + /* margin-right is set based on the stroke pattern */ + /* padding-left is set based on the stroke pattern */ +} + +.dygraph-roller { + position: absolute; + z-index: 10; +} + +/* This class is shared by all annotations, including those with icons */ +.dygraph-annotation { + position: absolute; + z-index: 10; + overflow: hidden; +} + +/* This class only applies to annotations without icons */ +/* Old class name: .dygraphDefaultAnnotation */ +.dygraph-default-annotation { + border: 1px solid black; + background-color: white; + text-align: center; +} + +.dygraph-axis-label { + /* position: absolute; */ + /* font-size: 14px; */ + z-index: 10; + line-height: normal; + overflow: hidden; + color: black; /* replaces old axisLabelColor option */ +} + +.dygraph-axis-label-x { +} + +.dygraph-axis-label-y { +} + +.dygraph-axis-label-y2 { +} + +.dygraph-title { + font-weight: bold; + z-index: 10; + text-align: center; + /* font-size: based on titleHeight option */ +} + +.dygraph-xlabel { + text-align: center; + /* font-size: based on xLabelHeight option */ +} + +/* For y-axis label */ +.dygraph-label-rotate-left { + text-align: center; + /* See http://caniuse.com/#feat=transforms2d */ + transform: rotate(90deg); + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); +} + +/* For y2-axis label */ +.dygraph-label-rotate-right { + text-align: center; + /* See http://caniuse.com/#feat=transforms2d */ + transform: rotate(-90deg); + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); +} diff --git a/ExampleHTM/dygraph/dygraph.js b/ExampleHTM/dygraph/dygraph.js new file mode 100644 index 0000000..4790b3f --- /dev/null +++ b/ExampleHTM/dygraph/dygraph.js @@ -0,0 +1,9431 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Dygraph = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } +}; + +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],2:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler implementation for the custom bars option. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _bars = require('./bars'); + +var _bars2 = _interopRequireDefault(_bars); + +/** + * @constructor + * @extends Dygraph.DataHandlers.BarsHandler + */ +var CustomBarsHandler = function CustomBarsHandler() {}; + +CustomBarsHandler.prototype = new _bars2['default'](); + +/** @inheritDoc */ +CustomBarsHandler.prototype.extractSeries = function (rawData, i, options) { + // TODO(danvk): pre-allocate series here. + var series = []; + var x, y, point; + var logScale = options.get('logscale'); + for (var j = 0; j < rawData.length; j++) { + x = rawData[j][0]; + point = rawData[j][i]; + if (logScale && point !== null) { + // On the log scale, points less than zero do not exist. + // This will create a gap in the chart. + if (point[0] <= 0 || point[1] <= 0 || point[2] <= 0) { + point = null; + } + } + // Extract to the unified data format. + if (point !== null) { + y = point[1]; + if (y !== null && !isNaN(y)) { + series.push([x, y, [point[0], point[2]]]); + } else { + series.push([x, y, [y, y]]); + } + } else { + series.push([x, null, [null, null]]); + } + } + return series; +}; + +/** @inheritDoc */ +CustomBarsHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) { + rollPeriod = Math.min(rollPeriod, originalData.length); + var rollingData = []; + var y, low, high, mid, count, i, extremes; + + low = 0; + mid = 0; + high = 0; + count = 0; + for (i = 0; i < originalData.length; i++) { + y = originalData[i][1]; + extremes = originalData[i][2]; + rollingData[i] = originalData[i]; + + if (y !== null && !isNaN(y)) { + low += extremes[0]; + mid += y; + high += extremes[1]; + count += 1; + } + if (i - rollPeriod >= 0) { + var prev = originalData[i - rollPeriod]; + if (prev[1] !== null && !isNaN(prev[1])) { + low -= prev[2][0]; + mid -= prev[1]; + high -= prev[2][1]; + count -= 1; + } + } + if (count) { + rollingData[i] = [originalData[i][0], 1.0 * mid / count, [1.0 * low / count, 1.0 * high / count]]; + } else { + rollingData[i] = [originalData[i][0], null, [null, null]]; + } + } + + return rollingData; +}; + +exports['default'] = CustomBarsHandler; +module.exports = exports['default']; + +},{"./bars":5}],3:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler implementation for the error bars option. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _bars = require('./bars'); + +var _bars2 = _interopRequireDefault(_bars); + +/** + * @constructor + * @extends BarsHandler + */ +var ErrorBarsHandler = function ErrorBarsHandler() {}; + +ErrorBarsHandler.prototype = new _bars2["default"](); + +/** @inheritDoc */ +ErrorBarsHandler.prototype.extractSeries = function (rawData, i, options) { + // TODO(danvk): pre-allocate series here. + var series = []; + var x, y, variance, point; + var sigma = options.get("sigma"); + var logScale = options.get('logscale'); + for (var j = 0; j < rawData.length; j++) { + x = rawData[j][0]; + point = rawData[j][i]; + if (logScale && point !== null) { + // On the log scale, points less than zero do not exist. + // This will create a gap in the chart. + if (point[0] <= 0 || point[0] - sigma * point[1] <= 0) { + point = null; + } + } + // Extract to the unified data format. + if (point !== null) { + y = point[0]; + if (y !== null && !isNaN(y)) { + variance = sigma * point[1]; + // preserve original error value in extras for further + // filtering + series.push([x, y, [y - variance, y + variance, point[1]]]); + } else { + series.push([x, y, [y, y, y]]); + } + } else { + series.push([x, null, [null, null, null]]); + } + } + return series; +}; + +/** @inheritDoc */ +ErrorBarsHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) { + rollPeriod = Math.min(rollPeriod, originalData.length); + var rollingData = []; + var sigma = options.get("sigma"); + + var i, j, y, v, sum, num_ok, stddev, variance, value; + + // Calculate the rolling average for the first rollPeriod - 1 points + // where there is not enough data to roll over the full number of points + for (i = 0; i < originalData.length; i++) { + sum = 0; + variance = 0; + num_ok = 0; + for (j = Math.max(0, i - rollPeriod + 1); j < i + 1; j++) { + y = originalData[j][1]; + if (y === null || isNaN(y)) continue; + num_ok++; + sum += y; + variance += Math.pow(originalData[j][2][2], 2); + } + if (num_ok) { + stddev = Math.sqrt(variance) / num_ok; + value = sum / num_ok; + rollingData[i] = [originalData[i][0], value, [value - sigma * stddev, value + sigma * stddev]]; + } else { + // This explicitly preserves NaNs to aid with "independent + // series". + // See testRollingAveragePreservesNaNs. + v = rollPeriod == 1 ? originalData[i][1] : null; + rollingData[i] = [originalData[i][0], v, [v, v]]; + } + } + + return rollingData; +}; + +exports["default"] = ErrorBarsHandler; +module.exports = exports["default"]; + +},{"./bars":5}],4:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler implementation for the combination + * of error bars and fractions options. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var _bars = require('./bars'); + +var _bars2 = _interopRequireDefault(_bars); + +/** + * @constructor + * @extends Dygraph.DataHandlers.BarsHandler + */ +var FractionsBarsHandler = function FractionsBarsHandler() {}; + +FractionsBarsHandler.prototype = new _bars2["default"](); + +/** @inheritDoc */ +FractionsBarsHandler.prototype.extractSeries = function (rawData, i, options) { + // TODO(danvk): pre-allocate series here. + var series = []; + var x, y, point, num, den, value, stddev, variance; + var mult = 100.0; + var sigma = options.get("sigma"); + var logScale = options.get('logscale'); + for (var j = 0; j < rawData.length; j++) { + x = rawData[j][0]; + point = rawData[j][i]; + if (logScale && point !== null) { + // On the log scale, points less than zero do not exist. + // This will create a gap in the chart. + if (point[0] <= 0 || point[1] <= 0) { + point = null; + } + } + // Extract to the unified data format. + if (point !== null) { + num = point[0]; + den = point[1]; + if (num !== null && !isNaN(num)) { + value = den ? num / den : 0.0; + stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0; + variance = mult * stddev; + y = mult * value; + // preserve original values in extras for further filtering + series.push([x, y, [y - variance, y + variance, num, den]]); + } else { + series.push([x, num, [num, num, num, den]]); + } + } else { + series.push([x, null, [null, null, null, null]]); + } + } + return series; +}; + +/** @inheritDoc */ +FractionsBarsHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) { + rollPeriod = Math.min(rollPeriod, originalData.length); + var rollingData = []; + var sigma = options.get("sigma"); + var wilsonInterval = options.get("wilsonInterval"); + + var low, high, i, stddev; + var num = 0; + var den = 0; // numerator/denominator + var mult = 100.0; + for (i = 0; i < originalData.length; i++) { + num += originalData[i][2][2]; + den += originalData[i][2][3]; + if (i - rollPeriod >= 0) { + num -= originalData[i - rollPeriod][2][2]; + den -= originalData[i - rollPeriod][2][3]; + } + + var date = originalData[i][0]; + var value = den ? num / den : 0.0; + if (wilsonInterval) { + // For more details on this confidence interval, see: + // http://en.wikipedia.org/wiki/Binomial_confidence_interval + if (den) { + var p = value < 0 ? 0 : value, + n = den; + var pm = sigma * Math.sqrt(p * (1 - p) / n + sigma * sigma / (4 * n * n)); + var denom = 1 + sigma * sigma / den; + low = (p + sigma * sigma / (2 * den) - pm) / denom; + high = (p + sigma * sigma / (2 * den) + pm) / denom; + rollingData[i] = [date, p * mult, [low * mult, high * mult]]; + } else { + rollingData[i] = [date, 0, [0, 0]]; + } + } else { + stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0; + rollingData[i] = [date, mult * value, [mult * (value - stddev), mult * (value + stddev)]]; + } + } + + return rollingData; +}; + +exports["default"] = FractionsBarsHandler; +module.exports = exports["default"]; + +},{"./bars":5}],5:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler base implementation for the "bar" + * data formats. This implementation must be extended and the + * extractSeries and rollingAverage must be implemented. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +/*global DygraphLayout:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _datahandler = require('./datahandler'); + +var _datahandler2 = _interopRequireDefault(_datahandler); + +var _dygraphLayout = require('../dygraph-layout'); + +var _dygraphLayout2 = _interopRequireDefault(_dygraphLayout); + +/** + * @constructor + * @extends {Dygraph.DataHandler} + */ +var BarsHandler = function BarsHandler() { + _datahandler2['default'].call(this); +}; +BarsHandler.prototype = new _datahandler2['default'](); + +// TODO(danvk): figure out why the jsdoc has to be copy/pasted from superclass. +// (I get closure compiler errors if this isn't here.) +/** + * @override + * @param {!Array.} rawData The raw data passed into dygraphs where + * rawData[i] = [x,ySeries1,...,ySeriesN]. + * @param {!number} seriesIndex Index of the series to extract. All other + * series should be ignored. + * @param {!DygraphOptions} options Dygraph options. + * @return {Array.<[!number,?number,?]>} The series in the unified data format + * where series[i] = [x,y,{extras}]. + */ +BarsHandler.prototype.extractSeries = function (rawData, seriesIndex, options) { + // Not implemented here must be extended +}; + +/** + * @override + * @param {!Array.<[!number,?number,?]>} series The series in the unified + * data format where series[i] = [x,y,{extras}]. + * @param {!number} rollPeriod The number of points over which to average the data + * @param {!DygraphOptions} options The dygraph options. + * TODO(danvk): be more specific than "Array" here. + * @return {!Array.<[!number,?number,?]>} the rolled series. + */ +BarsHandler.prototype.rollingAverage = function (series, rollPeriod, options) { + // Not implemented here, must be extended. +}; + +/** @inheritDoc */ +BarsHandler.prototype.onPointsCreated_ = function (series, points) { + for (var i = 0; i < series.length; ++i) { + var item = series[i]; + var point = points[i]; + point.y_top = NaN; + point.y_bottom = NaN; + point.yval_minus = _datahandler2['default'].parseFloat(item[2][0]); + point.yval_plus = _datahandler2['default'].parseFloat(item[2][1]); + } +}; + +/** @inheritDoc */ +BarsHandler.prototype.getExtremeYValues = function (series, dateWindow, options) { + var minY = null, + maxY = null, + y; + + var firstIdx = 0; + var lastIdx = series.length - 1; + + for (var j = firstIdx; j <= lastIdx; j++) { + y = series[j][1]; + if (y === null || isNaN(y)) continue; + + var low = series[j][2][0]; + var high = series[j][2][1]; + + if (low > y) low = y; // this can happen with custom bars, + if (high < y) high = y; // e.g. in tests/custom-bars.html + + if (maxY === null || high > maxY) maxY = high; + if (minY === null || low < minY) minY = low; + } + + return [minY, maxY]; +}; + +/** @inheritDoc */ +BarsHandler.prototype.onLineEvaluated = function (points, axis, logscale) { + var point; + for (var j = 0; j < points.length; j++) { + // Copy over the error terms + point = points[j]; + point.y_top = _dygraphLayout2['default'].calcYNormal_(axis, point.yval_minus, logscale); + point.y_bottom = _dygraphLayout2['default'].calcYNormal_(axis, point.yval_plus, logscale); + } +}; + +exports['default'] = BarsHandler; +module.exports = exports['default']; + +},{"../dygraph-layout":13,"./datahandler":6}],6:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview This file contains the managment of data handlers + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + * + * The idea is to define a common, generic data format that works for all data + * structures supported by dygraphs. To make this possible, the DataHandler + * interface is introduced. This makes it possible, that dygraph itself can work + * with the same logic for every data type independent of the actual format and + * the DataHandler takes care of the data format specific jobs. + * DataHandlers are implemented for all data types supported by Dygraphs and + * return Dygraphs compliant formats. + * By default the correct DataHandler is chosen based on the options set. + * Optionally the user may use his own DataHandler (similar to the plugin + * system). + * + * + * The unified data format returend by each handler is defined as so: + * series[n][point] = [x,y,(extras)] + * + * This format contains the common basis that is needed to draw a simple line + * series extended by optional extras for more complex graphing types. It + * contains a primitive x value as first array entry, a primitive y value as + * second array entry and an optional extras object for additional data needed. + * + * x must always be a number. + * y must always be a number, NaN of type number or null. + * extras is optional and must be interpreted by the DataHandler. It may be of + * any type. + * + * In practice this might look something like this: + * default: [x, yVal] + * errorBar / customBar: [x, yVal, [yTopVariance, yBottomVariance] ] + * + */ +/*global Dygraph:false */ +/*global DygraphLayout:false */ + +"use strict"; + +/** + * + * The data handler is responsible for all data specific operations. All of the + * series data it receives and returns is always in the unified data format. + * Initially the unified data is created by the extractSeries method + * @constructor + */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +var DygraphDataHandler = function DygraphDataHandler() {}; + +var handler = DygraphDataHandler; + +/** + * X-value array index constant for unified data samples. + * @const + * @type {number} + */ +handler.X = 0; + +/** + * Y-value array index constant for unified data samples. + * @const + * @type {number} + */ +handler.Y = 1; + +/** + * Extras-value array index constant for unified data samples. + * @const + * @type {number} + */ +handler.EXTRAS = 2; + +/** + * Extracts one series from the raw data (a 2D array) into an array of the + * unified data format. + * This is where undesirable points (i.e. negative values on log scales and + * missing values through which we wish to connect lines) are dropped. + * TODO(danvk): the "missing values" bit above doesn't seem right. + * + * @param {!Array.} rawData The raw data passed into dygraphs where + * rawData[i] = [x,ySeries1,...,ySeriesN]. + * @param {!number} seriesIndex Index of the series to extract. All other + * series should be ignored. + * @param {!DygraphOptions} options Dygraph options. + * @return {Array.<[!number,?number,?]>} The series in the unified data format + * where series[i] = [x,y,{extras}]. + */ +handler.prototype.extractSeries = function (rawData, seriesIndex, options) {}; + +/** + * Converts a series to a Point array. The resulting point array must be + * returned in increasing order of idx property. + * + * @param {!Array.<[!number,?number,?]>} series The series in the unified + * data format where series[i] = [x,y,{extras}]. + * @param {!string} setName Name of the series. + * @param {!number} boundaryIdStart Index offset of the first point, equal to the + * number of skipped points left of the date window minimum (if any). + * @return {!Array.} List of points for this series. + */ +handler.prototype.seriesToPoints = function (series, setName, boundaryIdStart) { + // TODO(bhs): these loops are a hot-spot for high-point-count charts. In + // fact, + // on chrome+linux, they are 6 times more expensive than iterating through + // the + // points and drawing the lines. The brunt of the cost comes from allocating + // the |point| structures. + var points = []; + for (var i = 0; i < series.length; ++i) { + var item = series[i]; + var yraw = item[1]; + var yval = yraw === null ? null : handler.parseFloat(yraw); + var point = { + x: NaN, + y: NaN, + xval: handler.parseFloat(item[0]), + yval: yval, + name: setName, // TODO(danvk): is this really necessary? + idx: i + boundaryIdStart + }; + points.push(point); + } + this.onPointsCreated_(series, points); + return points; +}; + +/** + * Callback called for each series after the series points have been generated + * which will later be used by the plotters to draw the graph. + * Here data may be added to the seriesPoints which is needed by the plotters. + * The indexes of series and points are in sync meaning the original data + * sample for series[i] is points[i]. + * + * @param {!Array.<[!number,?number,?]>} series The series in the unified + * data format where series[i] = [x,y,{extras}]. + * @param {!Array.} points The corresponding points passed + * to the plotter. + * @protected + */ +handler.prototype.onPointsCreated_ = function (series, points) {}; + +/** + * Calculates the rolling average of a data set. + * + * @param {!Array.<[!number,?number,?]>} series The series in the unified + * data format where series[i] = [x,y,{extras}]. + * @param {!number} rollPeriod The number of points over which to average the data + * @param {!DygraphOptions} options The dygraph options. + * @return {!Array.<[!number,?number,?]>} the rolled series. + */ +handler.prototype.rollingAverage = function (series, rollPeriod, options) {}; + +/** + * Computes the range of the data series (including confidence intervals). + * + * @param {!Array.<[!number,?number,?]>} series The series in the unified + * data format where series[i] = [x, y, {extras}]. + * @param {!Array.} dateWindow The x-value range to display with + * the format: [min, max]. + * @param {!DygraphOptions} options The dygraph options. + * @return {Array.} The low and high extremes of the series in the + * given window with the format: [low, high]. + */ +handler.prototype.getExtremeYValues = function (series, dateWindow, options) {}; + +/** + * Callback called for each series after the layouting data has been + * calculated before the series is drawn. Here normalized positioning data + * should be calculated for the extras of each point. + * + * @param {!Array.} points The points passed to + * the plotter. + * @param {!Object} axis The axis on which the series will be plotted. + * @param {!boolean} logscale Weather or not to use a logscale. + */ +handler.prototype.onLineEvaluated = function (points, axis, logscale) {}; + +/** + * Optimized replacement for parseFloat, which was way too slow when almost + * all values were type number, with few edge cases, none of which were strings. + * @param {?number} val + * @return {number} + * @protected + */ +handler.parseFloat = function (val) { + // parseFloat(null) is NaN + if (val === null) { + return NaN; + } + + // Assume it's a number or NaN. If it's something else, I'll be shocked. + return val; +}; + +exports["default"] = DygraphDataHandler; +module.exports = exports["default"]; + +},{}],7:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler implementation for the fractions option. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _datahandler = require('./datahandler'); + +var _datahandler2 = _interopRequireDefault(_datahandler); + +var _default = require('./default'); + +var _default2 = _interopRequireDefault(_default); + +/** + * @extends DefaultHandler + * @constructor + */ +var DefaultFractionHandler = function DefaultFractionHandler() {}; + +DefaultFractionHandler.prototype = new _default2['default'](); + +DefaultFractionHandler.prototype.extractSeries = function (rawData, i, options) { + // TODO(danvk): pre-allocate series here. + var series = []; + var x, y, point, num, den, value; + var mult = 100.0; + var logScale = options.get('logscale'); + for (var j = 0; j < rawData.length; j++) { + x = rawData[j][0]; + point = rawData[j][i]; + if (logScale && point !== null) { + // On the log scale, points less than zero do not exist. + // This will create a gap in the chart. + if (point[0] <= 0 || point[1] <= 0) { + point = null; + } + } + // Extract to the unified data format. + if (point !== null) { + num = point[0]; + den = point[1]; + if (num !== null && !isNaN(num)) { + value = den ? num / den : 0.0; + y = mult * value; + // preserve original values in extras for further filtering + series.push([x, y, [num, den]]); + } else { + series.push([x, num, [num, den]]); + } + } else { + series.push([x, null, [null, null]]); + } + } + return series; +}; + +DefaultFractionHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) { + rollPeriod = Math.min(rollPeriod, originalData.length); + var rollingData = []; + + var i; + var num = 0; + var den = 0; // numerator/denominator + var mult = 100.0; + for (i = 0; i < originalData.length; i++) { + num += originalData[i][2][0]; + den += originalData[i][2][1]; + if (i - rollPeriod >= 0) { + num -= originalData[i - rollPeriod][2][0]; + den -= originalData[i - rollPeriod][2][1]; + } + + var date = originalData[i][0]; + var value = den ? num / den : 0.0; + rollingData[i] = [date, mult * value]; + } + + return rollingData; +}; + +exports['default'] = DefaultFractionHandler; +module.exports = exports['default']; + +},{"./datahandler":6,"./default":8}],8:[function(require,module,exports){ +/** + * @license + * Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DataHandler default implementation used for simple line charts. + * @author David Eberlein (david.eberlein@ch.sauter-bc.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _datahandler = require('./datahandler'); + +var _datahandler2 = _interopRequireDefault(_datahandler); + +/** + * @constructor + * @extends Dygraph.DataHandler + */ +var DefaultHandler = function DefaultHandler() {}; + +DefaultHandler.prototype = new _datahandler2['default'](); + +/** @inheritDoc */ +DefaultHandler.prototype.extractSeries = function (rawData, i, options) { + // TODO(danvk): pre-allocate series here. + var series = []; + var logScale = options.get('logscale'); + for (var j = 0; j < rawData.length; j++) { + var x = rawData[j][0]; + var point = rawData[j][i]; + if (logScale) { + // On the log scale, points less than zero do not exist. + // This will create a gap in the chart. + if (point <= 0) { + point = null; + } + } + series.push([x, point]); + } + return series; +}; + +/** @inheritDoc */ +DefaultHandler.prototype.rollingAverage = function (originalData, rollPeriod, options) { + rollPeriod = Math.min(rollPeriod, originalData.length); + var rollingData = []; + + var i, j, y, sum, num_ok; + // Calculate the rolling average for the first rollPeriod - 1 points + // where + // there is not enough data to roll over the full number of points + if (rollPeriod == 1) { + return originalData; + } + for (i = 0; i < originalData.length; i++) { + sum = 0; + num_ok = 0; + for (j = Math.max(0, i - rollPeriod + 1); j < i + 1; j++) { + y = originalData[j][1]; + if (y === null || isNaN(y)) continue; + num_ok++; + sum += originalData[j][1]; + } + if (num_ok) { + rollingData[i] = [originalData[i][0], sum / num_ok]; + } else { + rollingData[i] = [originalData[i][0], null]; + } + } + + return rollingData; +}; + +/** @inheritDoc */ +DefaultHandler.prototype.getExtremeYValues = function (series, dateWindow, options) { + var minY = null, + maxY = null, + y; + var firstIdx = 0, + lastIdx = series.length - 1; + + for (var j = firstIdx; j <= lastIdx; j++) { + y = series[j][1]; + if (y === null || isNaN(y)) continue; + if (maxY === null || y > maxY) { + maxY = y; + } + if (minY === null || y < minY) { + minY = y; + } + } + return [minY, maxY]; +}; + +exports['default'] = DefaultHandler; +module.exports = exports['default']; + +},{"./datahandler":6}],9:[function(require,module,exports){ +/** + * @license + * Copyright 2006 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview Based on PlotKit.CanvasRenderer, but modified to meet the + * needs of dygraphs. + * + * In particular, support for: + * - grid overlays + * - error bars + * - dygraphs attribute system + */ + +/** + * The DygraphCanvasRenderer class does the actual rendering of the chart onto + * a canvas. It's based on PlotKit.CanvasRenderer. + * @param {Object} element The canvas to attach to + * @param {Object} elementContext The 2d context of the canvas (injected so it + * can be mocked for testing.) + * @param {Layout} layout The DygraphLayout object for this graph. + * @constructor + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +var _dygraph = require('./dygraph'); + +var _dygraph2 = _interopRequireDefault(_dygraph); + +/** + * @constructor + * + * This gets called when there are "new points" to chart. This is generally the + * case when the underlying data being charted has changed. It is _not_ called + * in the common case that the user has zoomed or is panning the view. + * + * The chart canvas has already been created by the Dygraph object. The + * renderer simply gets a drawing context. + * + * @param {Dygraph} dygraph The chart to which this renderer belongs. + * @param {HTMLCanvasElement} element The <canvas> DOM element on which to draw. + * @param {CanvasRenderingContext2D} elementContext The drawing context. + * @param {DygraphLayout} layout The chart's DygraphLayout object. + * + * TODO(danvk): remove the elementContext property. + */ +var DygraphCanvasRenderer = function DygraphCanvasRenderer(dygraph, element, elementContext, layout) { + this.dygraph_ = dygraph; + + this.layout = layout; + this.element = element; + this.elementContext = elementContext; + + this.height = dygraph.height_; + this.width = dygraph.width_; + + // --- check whether everything is ok before we return + if (!utils.isCanvasSupported(this.element)) { + throw "Canvas is not supported."; + } + + // internal state + this.area = layout.getPlotArea(); + + // Set up a clipping area for the canvas (and the interaction canvas). + // This ensures that we don't overdraw. + var ctx = this.dygraph_.canvas_ctx_; + ctx.beginPath(); + ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); + ctx.clip(); + + ctx = this.dygraph_.hidden_ctx_; + ctx.beginPath(); + ctx.rect(this.area.x, this.area.y, this.area.w, this.area.h); + ctx.clip(); +}; + +/** + * Clears out all chart content and DOM elements. + * This is called immediately before render() on every frame, including + * during zooms and pans. + * @private + */ +DygraphCanvasRenderer.prototype.clear = function () { + this.elementContext.clearRect(0, 0, this.width, this.height); +}; + +/** + * This method is responsible for drawing everything on the chart, including + * lines, error bars, fills and axes. + * It is called immediately after clear() on every frame, including during pans + * and zooms. + * @private + */ +DygraphCanvasRenderer.prototype.render = function () { + // attaches point.canvas{x,y} + this._updatePoints(); + + // actually draws the chart. + this._renderLineChart(); +}; + +/** + * Returns a predicate to be used with an iterator, which will + * iterate over points appropriately, depending on whether + * connectSeparatedPoints is true. When it's false, the predicate will + * skip over points with missing yVals. + */ +DygraphCanvasRenderer._getIteratorPredicate = function (connectSeparatedPoints) { + return connectSeparatedPoints ? DygraphCanvasRenderer._predicateThatSkipsEmptyPoints : null; +}; + +DygraphCanvasRenderer._predicateThatSkipsEmptyPoints = function (array, idx) { + return array[idx].yval !== null; +}; + +/** + * Draws a line with the styles passed in and calls all the drawPointCallbacks. + * @param {Object} e The dictionary passed to the plotter function. + * @private + */ +DygraphCanvasRenderer._drawStyledLine = function (e, color, strokeWidth, strokePattern, drawPoints, drawPointCallback, pointSize) { + var g = e.dygraph; + // TODO(konigsberg): Compute attributes outside this method call. + var stepPlot = g.getBooleanOption("stepPlot", e.setName); + + if (!utils.isArrayLike(strokePattern)) { + strokePattern = null; + } + + var drawGapPoints = g.getBooleanOption('drawGapEdgePoints', e.setName); + + var points = e.points; + var setName = e.setName; + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption("connectSeparatedPoints", setName))); + + var stroking = strokePattern && strokePattern.length >= 2; + + var ctx = e.drawingContext; + ctx.save(); + if (stroking) { + if (ctx.setLineDash) ctx.setLineDash(strokePattern); + } + + var pointsOnLine = DygraphCanvasRenderer._drawSeries(e, iter, strokeWidth, pointSize, drawPoints, drawGapPoints, stepPlot, color); + DygraphCanvasRenderer._drawPointsOnLine(e, pointsOnLine, drawPointCallback, color, pointSize); + + if (stroking) { + if (ctx.setLineDash) ctx.setLineDash([]); + } + + ctx.restore(); +}; + +/** + * This does the actual drawing of lines on the canvas, for just one series. + * Returns a list of [canvasx, canvasy] pairs for points for which a + * drawPointCallback should be fired. These include isolated points, or all + * points if drawPoints=true. + * @param {Object} e The dictionary passed to the plotter function. + * @private + */ +DygraphCanvasRenderer._drawSeries = function (e, iter, strokeWidth, pointSize, drawPoints, drawGapPoints, stepPlot, color) { + + var prevCanvasX = null; + var prevCanvasY = null; + var nextCanvasY = null; + var isIsolated; // true if this point is isolated (no line segments) + var point; // the point being processed in the while loop + var pointsOnLine = []; // Array of [canvasx, canvasy] pairs. + var first = true; // the first cycle through the while loop + + var ctx = e.drawingContext; + ctx.beginPath(); + ctx.strokeStyle = color; + ctx.lineWidth = strokeWidth; + + // NOTE: we break the iterator's encapsulation here for about a 25% speedup. + var arr = iter.array_; + var limit = iter.end_; + var predicate = iter.predicate_; + + for (var i = iter.start_; i < limit; i++) { + point = arr[i]; + if (predicate) { + while (i < limit && !predicate(arr, i)) { + i++; + } + if (i == limit) break; + point = arr[i]; + } + + // FIXME: The 'canvasy != canvasy' test here catches NaN values but the test + // doesn't catch Infinity values. Could change this to + // !isFinite(point.canvasy), but I assume it avoids isNaN for performance? + if (point.canvasy === null || point.canvasy != point.canvasy) { + if (stepPlot && prevCanvasX !== null) { + // Draw a horizontal line to the start of the missing data + ctx.moveTo(prevCanvasX, prevCanvasY); + ctx.lineTo(point.canvasx, prevCanvasY); + } + prevCanvasX = prevCanvasY = null; + } else { + isIsolated = false; + if (drawGapPoints || prevCanvasX === null) { + iter.nextIdx_ = i; + iter.next(); + nextCanvasY = iter.hasNext ? iter.peek.canvasy : null; + + var isNextCanvasYNullOrNaN = nextCanvasY === null || nextCanvasY != nextCanvasY; + isIsolated = prevCanvasX === null && isNextCanvasYNullOrNaN; + if (drawGapPoints) { + // Also consider a point to be "isolated" if it's adjacent to a + // null point, excluding the graph edges. + if (!first && prevCanvasX === null || iter.hasNext && isNextCanvasYNullOrNaN) { + isIsolated = true; + } + } + } + + if (prevCanvasX !== null) { + if (strokeWidth) { + if (stepPlot) { + ctx.moveTo(prevCanvasX, prevCanvasY); + ctx.lineTo(point.canvasx, prevCanvasY); + } + + ctx.lineTo(point.canvasx, point.canvasy); + } + } else { + ctx.moveTo(point.canvasx, point.canvasy); + } + if (drawPoints || isIsolated) { + pointsOnLine.push([point.canvasx, point.canvasy, point.idx]); + } + prevCanvasX = point.canvasx; + prevCanvasY = point.canvasy; + } + first = false; + } + ctx.stroke(); + return pointsOnLine; +}; + +/** + * This fires the drawPointCallback functions, which draw dots on the points by + * default. This gets used when the "drawPoints" option is set, or when there + * are isolated points. + * @param {Object} e The dictionary passed to the plotter function. + * @private + */ +DygraphCanvasRenderer._drawPointsOnLine = function (e, pointsOnLine, drawPointCallback, color, pointSize) { + var ctx = e.drawingContext; + for (var idx = 0; idx < pointsOnLine.length; idx++) { + var cb = pointsOnLine[idx]; + ctx.save(); + drawPointCallback.call(e.dygraph, e.dygraph, e.setName, ctx, cb[0], cb[1], color, pointSize, cb[2]); + ctx.restore(); + } +}; + +/** + * Attaches canvas coordinates to the points array. + * @private + */ +DygraphCanvasRenderer.prototype._updatePoints = function () { + // Update Points + // TODO(danvk): here + // + // TODO(bhs): this loop is a hot-spot for high-point-count charts. These + // transformations can be pushed into the canvas via linear transformation + // matrices. + // NOTE(danvk): this is trickier than it sounds at first. The transformation + // needs to be done before the .moveTo() and .lineTo() calls, but must be + // undone before the .stroke() call to ensure that the stroke width is + // unaffected. An alternative is to reduce the stroke width in the + // transformed coordinate space, but you can't specify different values for + // each dimension (as you can with .scale()). The speedup here is ~12%. + var sets = this.layout.points; + for (var i = sets.length; i--;) { + var points = sets[i]; + for (var j = points.length; j--;) { + var point = points[j]; + point.canvasx = this.area.w * point.x + this.area.x; + point.canvasy = this.area.h * point.y + this.area.y; + } + } +}; + +/** + * Add canvas Actually draw the lines chart, including error bars. + * + * This function can only be called if DygraphLayout's points array has been + * updated with canvas{x,y} attributes, i.e. by + * DygraphCanvasRenderer._updatePoints. + * + * @param {string=} opt_seriesName when specified, only that series will + * be drawn. (This is used for expedited redrawing with highlightSeriesOpts) + * @param {CanvasRenderingContext2D} opt_ctx when specified, the drawing + * context. However, lines are typically drawn on the object's + * elementContext. + * @private + */ +DygraphCanvasRenderer.prototype._renderLineChart = function (opt_seriesName, opt_ctx) { + var ctx = opt_ctx || this.elementContext; + var i; + + var sets = this.layout.points; + var setNames = this.layout.setNames; + var setName; + + this.colors = this.dygraph_.colorsMap_; + + // Determine which series have specialized plotters. + var plotter_attr = this.dygraph_.getOption("plotter"); + var plotters = plotter_attr; + if (!utils.isArrayLike(plotters)) { + plotters = [plotters]; + } + + var setPlotters = {}; // series name -> plotter fn. + for (i = 0; i < setNames.length; i++) { + setName = setNames[i]; + var setPlotter = this.dygraph_.getOption("plotter", setName); + if (setPlotter == plotter_attr) continue; // not specialized. + + setPlotters[setName] = setPlotter; + } + + for (i = 0; i < plotters.length; i++) { + var plotter = plotters[i]; + var is_last = i == plotters.length - 1; + + for (var j = 0; j < sets.length; j++) { + setName = setNames[j]; + if (opt_seriesName && setName != opt_seriesName) continue; + + var points = sets[j]; + + // Only throw in the specialized plotters on the last iteration. + var p = plotter; + if (setName in setPlotters) { + if (is_last) { + p = setPlotters[setName]; + } else { + // Don't use the standard plotters in this case. + continue; + } + } + + var color = this.colors[setName]; + var strokeWidth = this.dygraph_.getOption("strokeWidth", setName); + + ctx.save(); + ctx.strokeStyle = color; + ctx.lineWidth = strokeWidth; + p({ + points: points, + setName: setName, + drawingContext: ctx, + color: color, + strokeWidth: strokeWidth, + dygraph: this.dygraph_, + axis: this.dygraph_.axisPropertiesForSeries(setName), + plotArea: this.area, + seriesIndex: j, + seriesCount: sets.length, + singleSeriesName: opt_seriesName, + allSeriesPoints: sets + }); + ctx.restore(); + } + } +}; + +/** + * Standard plotters. These may be used by clients via Dygraph.Plotters. + * See comments there for more details. + */ +DygraphCanvasRenderer._Plotters = { + linePlotter: function linePlotter(e) { + DygraphCanvasRenderer._linePlotter(e); + }, + + fillPlotter: function fillPlotter(e) { + DygraphCanvasRenderer._fillPlotter(e); + }, + + errorPlotter: function errorPlotter(e) { + DygraphCanvasRenderer._errorPlotter(e); + } +}; + +/** + * Plotter which draws the central lines for a series. + * @private + */ +DygraphCanvasRenderer._linePlotter = function (e) { + var g = e.dygraph; + var setName = e.setName; + var strokeWidth = e.strokeWidth; + + // TODO(danvk): Check if there's any performance impact of just calling + // getOption() inside of _drawStyledLine. Passing in so many parameters makes + // this code a bit nasty. + var borderWidth = g.getNumericOption("strokeBorderWidth", setName); + var drawPointCallback = g.getOption("drawPointCallback", setName) || utils.Circles.DEFAULT; + var strokePattern = g.getOption("strokePattern", setName); + var drawPoints = g.getBooleanOption("drawPoints", setName); + var pointSize = g.getNumericOption("pointSize", setName); + + if (borderWidth && strokeWidth) { + DygraphCanvasRenderer._drawStyledLine(e, g.getOption("strokeBorderColor", setName), strokeWidth + 2 * borderWidth, strokePattern, drawPoints, drawPointCallback, pointSize); + } + + DygraphCanvasRenderer._drawStyledLine(e, e.color, strokeWidth, strokePattern, drawPoints, drawPointCallback, pointSize); +}; + +/** + * Draws the shaded error bars/confidence intervals for each series. + * This happens before the center lines are drawn, since the center lines + * need to be drawn on top of the error bars for all series. + * @private + */ +DygraphCanvasRenderer._errorPlotter = function (e) { + var g = e.dygraph; + var setName = e.setName; + var errorBars = g.getBooleanOption("errorBars") || g.getBooleanOption("customBars"); + if (!errorBars) return; + + var fillGraph = g.getBooleanOption("fillGraph", setName); + if (fillGraph) { + console.warn("Can't use fillGraph option with error bars"); + } + + var ctx = e.drawingContext; + var color = e.color; + var fillAlpha = g.getNumericOption('fillAlpha', setName); + var stepPlot = g.getBooleanOption("stepPlot", setName); + var points = e.points; + + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption("connectSeparatedPoints", setName))); + + var newYs; + + // setup graphics context + var prevX = NaN; + var prevY = NaN; + var prevYs = [-1, -1]; + // should be same color as the lines but only 15% opaque. + var rgb = utils.toRGB_(color); + var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')'; + ctx.fillStyle = err_color; + ctx.beginPath(); + + var isNullUndefinedOrNaN = function isNullUndefinedOrNaN(x) { + return x === null || x === undefined || isNaN(x); + }; + + while (iter.hasNext) { + var point = iter.next(); + if (!stepPlot && isNullUndefinedOrNaN(point.y) || stepPlot && !isNaN(prevY) && isNullUndefinedOrNaN(prevY)) { + prevX = NaN; + continue; + } + + newYs = [point.y_bottom, point.y_top]; + if (stepPlot) { + prevY = point.y; + } + + // The documentation specifically disallows nulls inside the point arrays, + // but in case it happens we should do something sensible. + if (isNaN(newYs[0])) newYs[0] = point.y; + if (isNaN(newYs[1])) newYs[1] = point.y; + + newYs[0] = e.plotArea.h * newYs[0] + e.plotArea.y; + newYs[1] = e.plotArea.h * newYs[1] + e.plotArea.y; + if (!isNaN(prevX)) { + if (stepPlot) { + ctx.moveTo(prevX, prevYs[0]); + ctx.lineTo(point.canvasx, prevYs[0]); + ctx.lineTo(point.canvasx, prevYs[1]); + } else { + ctx.moveTo(prevX, prevYs[0]); + ctx.lineTo(point.canvasx, newYs[0]); + ctx.lineTo(point.canvasx, newYs[1]); + } + ctx.lineTo(prevX, prevYs[1]); + ctx.closePath(); + } + prevYs = newYs; + prevX = point.canvasx; + } + ctx.fill(); +}; + +/** + * Proxy for CanvasRenderingContext2D which drops moveTo/lineTo calls which are + * superfluous. It accumulates all movements which haven't changed the x-value + * and only applies the two with the most extreme y-values. + * + * Calls to lineTo/moveTo must have non-decreasing x-values. + */ +DygraphCanvasRenderer._fastCanvasProxy = function (context) { + var pendingActions = []; // array of [type, x, y] tuples + var lastRoundedX = null; + var lastFlushedX = null; + + var LINE_TO = 1, + MOVE_TO = 2; + + var actionCount = 0; // number of moveTos and lineTos passed to context. + + // Drop superfluous motions + // Assumes all pendingActions have the same (rounded) x-value. + var compressActions = function compressActions(opt_losslessOnly) { + if (pendingActions.length <= 1) return; + + // Lossless compression: drop inconsequential moveTos. + for (var i = pendingActions.length - 1; i > 0; i--) { + var action = pendingActions[i]; + if (action[0] == MOVE_TO) { + var prevAction = pendingActions[i - 1]; + if (prevAction[1] == action[1] && prevAction[2] == action[2]) { + pendingActions.splice(i, 1); + } + } + } + + // Lossless compression: ... drop consecutive moveTos ... + for (var i = 0; i < pendingActions.length - 1;) /* incremented internally */{ + var action = pendingActions[i]; + if (action[0] == MOVE_TO && pendingActions[i + 1][0] == MOVE_TO) { + pendingActions.splice(i, 1); + } else { + i++; + } + } + + // Lossy compression: ... drop all but the extreme y-values ... + if (pendingActions.length > 2 && !opt_losslessOnly) { + // keep an initial moveTo, but drop all others. + var startIdx = 0; + if (pendingActions[0][0] == MOVE_TO) startIdx++; + var minIdx = null, + maxIdx = null; + for (var i = startIdx; i < pendingActions.length; i++) { + var action = pendingActions[i]; + if (action[0] != LINE_TO) continue; + if (minIdx === null && maxIdx === null) { + minIdx = i; + maxIdx = i; + } else { + var y = action[2]; + if (y < pendingActions[minIdx][2]) { + minIdx = i; + } else if (y > pendingActions[maxIdx][2]) { + maxIdx = i; + } + } + } + var minAction = pendingActions[minIdx], + maxAction = pendingActions[maxIdx]; + pendingActions.splice(startIdx, pendingActions.length - startIdx); + if (minIdx < maxIdx) { + pendingActions.push(minAction); + pendingActions.push(maxAction); + } else if (minIdx > maxIdx) { + pendingActions.push(maxAction); + pendingActions.push(minAction); + } else { + pendingActions.push(minAction); + } + } + }; + + var flushActions = function flushActions(opt_noLossyCompression) { + compressActions(opt_noLossyCompression); + for (var i = 0, len = pendingActions.length; i < len; i++) { + var action = pendingActions[i]; + if (action[0] == LINE_TO) { + context.lineTo(action[1], action[2]); + } else if (action[0] == MOVE_TO) { + context.moveTo(action[1], action[2]); + } + } + if (pendingActions.length) { + lastFlushedX = pendingActions[pendingActions.length - 1][1]; + } + actionCount += pendingActions.length; + pendingActions = []; + }; + + var addAction = function addAction(action, x, y) { + var rx = Math.round(x); + if (lastRoundedX === null || rx != lastRoundedX) { + // if there are large gaps on the x-axis, it's essential to keep the + // first and last point as well. + var hasGapOnLeft = lastRoundedX - lastFlushedX > 1, + hasGapOnRight = rx - lastRoundedX > 1, + hasGap = hasGapOnLeft || hasGapOnRight; + flushActions(hasGap); + lastRoundedX = rx; + } + pendingActions.push([action, x, y]); + }; + + return { + moveTo: function moveTo(x, y) { + addAction(MOVE_TO, x, y); + }, + lineTo: function lineTo(x, y) { + addAction(LINE_TO, x, y); + }, + + // for major operations like stroke/fill, we skip compression to ensure + // that there are no artifacts at the right edge. + stroke: function stroke() { + flushActions(true);context.stroke(); + }, + fill: function fill() { + flushActions(true);context.fill(); + }, + beginPath: function beginPath() { + flushActions(true);context.beginPath(); + }, + closePath: function closePath() { + flushActions(true);context.closePath(); + }, + + _count: function _count() { + return actionCount; + } + }; +}; + +/** + * Draws the shaded regions when "fillGraph" is set. Not to be confused with + * error bars. + * + * For stacked charts, it's more convenient to handle all the series + * simultaneously. So this plotter plots all the points on the first series + * it's asked to draw, then ignores all the other series. + * + * @private + */ +DygraphCanvasRenderer._fillPlotter = function (e) { + // Skip if we're drawing a single series for interactive highlight overlay. + if (e.singleSeriesName) return; + + // We'll handle all the series at once, not one-by-one. + if (e.seriesIndex !== 0) return; + + var g = e.dygraph; + var setNames = g.getLabels().slice(1); // remove x-axis + + // getLabels() includes names for invisible series, which are not included in + // allSeriesPoints. We remove those to make the two match. + // TODO(danvk): provide a simpler way to get this information. + for (var i = setNames.length; i >= 0; i--) { + if (!g.visibility()[i]) setNames.splice(i, 1); + } + + var anySeriesFilled = (function () { + for (var i = 0; i < setNames.length; i++) { + if (g.getBooleanOption("fillGraph", setNames[i])) return true; + } + return false; + })(); + + if (!anySeriesFilled) return; + + var area = e.plotArea; + var sets = e.allSeriesPoints; + var setCount = sets.length; + + var stackedGraph = g.getBooleanOption("stackedGraph"); + var colors = g.getColors(); + + // For stacked graphs, track the baseline for filling. + // + // The filled areas below graph lines are trapezoids with two + // vertical edges. The top edge is the line segment being drawn, and + // the baseline is the bottom edge. Each baseline corresponds to the + // top line segment from the previous stacked line. In the case of + // step plots, the trapezoids are rectangles. + var baseline = {}; + var currBaseline; + var prevStepPlot; // for different line drawing modes (line/step) per series + + // Helper function to trace a line back along the baseline. + var traceBackPath = function traceBackPath(ctx, baselineX, baselineY, pathBack) { + ctx.lineTo(baselineX, baselineY); + if (stackedGraph) { + for (var i = pathBack.length - 1; i >= 0; i--) { + var pt = pathBack[i]; + ctx.lineTo(pt[0], pt[1]); + } + } + }; + + // process sets in reverse order (needed for stacked graphs) + for (var setIdx = setCount - 1; setIdx >= 0; setIdx--) { + var ctx = e.drawingContext; + var setName = setNames[setIdx]; + if (!g.getBooleanOption('fillGraph', setName)) continue; + + var fillAlpha = g.getNumericOption('fillAlpha', setName); + var stepPlot = g.getBooleanOption('stepPlot', setName); + var color = colors[setIdx]; + var axis = g.axisPropertiesForSeries(setName); + var axisY = 1.0 + axis.minyval * axis.yscale; + if (axisY < 0.0) axisY = 0.0;else if (axisY > 1.0) axisY = 1.0; + axisY = area.h * axisY + area.y; + + var points = sets[setIdx]; + var iter = utils.createIterator(points, 0, points.length, DygraphCanvasRenderer._getIteratorPredicate(g.getBooleanOption("connectSeparatedPoints", setName))); + + // setup graphics context + var prevX = NaN; + var prevYs = [-1, -1]; + var newYs; + // should be same color as the lines but only 15% opaque. + var rgb = utils.toRGB_(color); + var err_color = 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + fillAlpha + ')'; + ctx.fillStyle = err_color; + ctx.beginPath(); + var last_x, + is_first = true; + + // If the point density is high enough, dropping segments on their way to + // the canvas justifies the overhead of doing so. + if (points.length > 2 * g.width_ || _dygraph2['default'].FORCE_FAST_PROXY) { + ctx = DygraphCanvasRenderer._fastCanvasProxy(ctx); + } + + // For filled charts, we draw points from left to right, then back along + // the x-axis to complete a shape for filling. + // For stacked plots, this "back path" is a more complex shape. This array + // stores the [x, y] values needed to trace that shape. + var pathBack = []; + + // TODO(danvk): there are a lot of options at play in this loop. + // The logic would be much clearer if some (e.g. stackGraph and + // stepPlot) were split off into separate sub-plotters. + var point; + while (iter.hasNext) { + point = iter.next(); + if (!utils.isOK(point.y) && !stepPlot) { + traceBackPath(ctx, prevX, prevYs[1], pathBack); + pathBack = []; + prevX = NaN; + if (point.y_stacked !== null && !isNaN(point.y_stacked)) { + baseline[point.canvasx] = area.h * point.y_stacked + area.y; + } + continue; + } + if (stackedGraph) { + if (!is_first && last_x == point.xval) { + continue; + } else { + is_first = false; + last_x = point.xval; + } + + currBaseline = baseline[point.canvasx]; + var lastY; + if (currBaseline === undefined) { + lastY = axisY; + } else { + if (prevStepPlot) { + lastY = currBaseline[0]; + } else { + lastY = currBaseline; + } + } + newYs = [point.canvasy, lastY]; + + if (stepPlot) { + // Step plots must keep track of the top and bottom of + // the baseline at each point. + if (prevYs[0] === -1) { + baseline[point.canvasx] = [point.canvasy, axisY]; + } else { + baseline[point.canvasx] = [point.canvasy, prevYs[0]]; + } + } else { + baseline[point.canvasx] = point.canvasy; + } + } else { + if (isNaN(point.canvasy) && stepPlot) { + newYs = [area.y + area.h, axisY]; + } else { + newYs = [point.canvasy, axisY]; + } + } + if (!isNaN(prevX)) { + // Move to top fill point + if (stepPlot) { + ctx.lineTo(point.canvasx, prevYs[0]); + ctx.lineTo(point.canvasx, newYs[0]); + } else { + ctx.lineTo(point.canvasx, newYs[0]); + } + + // Record the baseline for the reverse path. + if (stackedGraph) { + pathBack.push([prevX, prevYs[1]]); + if (prevStepPlot && currBaseline) { + // Draw to the bottom of the baseline + pathBack.push([point.canvasx, currBaseline[1]]); + } else { + pathBack.push([point.canvasx, newYs[1]]); + } + } + } else { + ctx.moveTo(point.canvasx, newYs[1]); + ctx.lineTo(point.canvasx, newYs[0]); + } + prevYs = newYs; + prevX = point.canvasx; + } + prevStepPlot = stepPlot; + if (newYs && point) { + traceBackPath(ctx, point.canvasx, newYs[1], pathBack); + pathBack = []; + } + ctx.fill(); + } +}; + +exports['default'] = DygraphCanvasRenderer; +module.exports = exports['default']; + +},{"./dygraph":18,"./dygraph-utils":17}],10:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphTickers = require('./dygraph-tickers'); + +var DygraphTickers = _interopRequireWildcard(_dygraphTickers); + +var _dygraphInteractionModel = require('./dygraph-interaction-model'); + +var _dygraphInteractionModel2 = _interopRequireDefault(_dygraphInteractionModel); + +var _dygraphCanvas = require('./dygraph-canvas'); + +var _dygraphCanvas2 = _interopRequireDefault(_dygraphCanvas); + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +// Default attribute values. +var DEFAULT_ATTRS = { + highlightCircleSize: 3, + highlightSeriesOpts: null, + highlightSeriesBackgroundAlpha: 0.5, + highlightSeriesBackgroundColor: 'rgb(255, 255, 255)', + + labelsSeparateLines: false, + labelsShowZeroValues: true, + labelsKMB: false, + labelsKMG2: false, + showLabelsOnHighlight: true, + + digitsAfterDecimal: 2, + maxNumberWidth: 6, + sigFigs: null, + + strokeWidth: 1.0, + strokeBorderWidth: 0, + strokeBorderColor: "white", + + axisTickSize: 3, + axisLabelFontSize: 14, + rightGap: 5, + + showRoller: false, + xValueParser: undefined, + + delimiter: ',', + + sigma: 2.0, + errorBars: false, + fractions: false, + wilsonInterval: true, // only relevant if fractions is true + customBars: false, + fillGraph: false, + fillAlpha: 0.15, + connectSeparatedPoints: false, + + stackedGraph: false, + stackedGraphNaNFill: 'all', + hideOverlayOnMouseOut: true, + + legend: 'onmouseover', + stepPlot: false, + xRangePad: 0, + yRangePad: null, + drawAxesAtZero: false, + + // Sizes of the various chart labels. + titleHeight: 28, + xLabelHeight: 18, + yLabelWidth: 18, + + axisLineColor: "black", + axisLineWidth: 0.3, + gridLineWidth: 0.3, + axisLabelWidth: 50, + gridLineColor: "rgb(128,128,128)", + + interactionModel: _dygraphInteractionModel2['default'].defaultModel, + animatedZooms: false, // (for now) + + // Range selector options + showRangeSelector: false, + rangeSelectorHeight: 40, + rangeSelectorPlotStrokeColor: "#808FAB", + rangeSelectorPlotFillGradientColor: "white", + rangeSelectorPlotFillColor: "#A7B1C4", + rangeSelectorBackgroundStrokeColor: "gray", + rangeSelectorBackgroundLineWidth: 1, + rangeSelectorPlotLineWidth: 1.5, + rangeSelectorForegroundStrokeColor: "black", + rangeSelectorForegroundLineWidth: 1, + rangeSelectorAlpha: 0.6, + showInRangeSelector: null, + + // The ordering here ensures that central lines always appear above any + // fill bars/error bars. + plotter: [_dygraphCanvas2['default']._fillPlotter, _dygraphCanvas2['default']._errorPlotter, _dygraphCanvas2['default']._linePlotter], + + plugins: [], + + // per-axis options + axes: { + x: { + pixelsPerLabel: 70, + axisLabelWidth: 60, + axisLabelFormatter: utils.dateAxisLabelFormatter, + valueFormatter: utils.dateValueFormatter, + drawGrid: true, + drawAxis: true, + independentTicks: true, + ticker: DygraphTickers.dateTicker + }, + y: { + axisLabelWidth: 50, + pixelsPerLabel: 30, + valueFormatter: utils.numberValueFormatter, + axisLabelFormatter: utils.numberAxisLabelFormatter, + drawGrid: true, + drawAxis: true, + independentTicks: true, + ticker: DygraphTickers.numericTicks + }, + y2: { + axisLabelWidth: 50, + pixelsPerLabel: 30, + valueFormatter: utils.numberValueFormatter, + axisLabelFormatter: utils.numberAxisLabelFormatter, + drawAxis: true, // only applies when there are two axes of data. + drawGrid: false, + independentTicks: false, + ticker: DygraphTickers.numericTicks + } + } +}; + +exports['default'] = DEFAULT_ATTRS; +module.exports = exports['default']; + +},{"./dygraph-canvas":9,"./dygraph-interaction-model":12,"./dygraph-tickers":16,"./dygraph-utils":17}],11:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview A wrapper around the Dygraph class which implements the + * interface for a GViz (aka Google Visualization API) visualization. + * It is designed to be a drop-in replacement for Google's AnnotatedTimeline, + * so the documentation at + * http://code.google.com/apis/chart/interactive/docs/gallery/annotatedtimeline.html + * translates over directly. + * + * For a full demo, see: + * - http://dygraphs.com/tests/gviz.html + * - http://dygraphs.com/tests/annotation-gviz.html + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +var _dygraph = require('./dygraph'); + +var _dygraph2 = _interopRequireDefault(_dygraph); + +/** + * A wrapper around Dygraph that implements the gviz API. + * @param {!HTMLDivElement} container The DOM object the visualization should + * live in. + * @constructor + */ +var GVizChart = function GVizChart(container) { + this.container = container; +}; + +/** + * @param {GVizDataTable} data + * @param {Object.<*>} options + */ +GVizChart.prototype.draw = function (data, options) { + // Clear out any existing dygraph. + // TODO(danvk): would it make more sense to simply redraw using the current + // date_graph object? + this.container.innerHTML = ''; + if (typeof this.date_graph != 'undefined') { + this.date_graph.destroy(); + } + + this.date_graph = new _dygraph2['default'](this.container, data, options); +}; + +/** + * Google charts compatible setSelection + * Only row selection is supported, all points in the row will be highlighted + * @param {Array.<{row:number}>} selection_array array of the selected cells + * @public + */ +GVizChart.prototype.setSelection = function (selection_array) { + var row = false; + if (selection_array.length) { + row = selection_array[0].row; + } + this.date_graph.setSelection(row); +}; + +/** + * Google charts compatible getSelection implementation + * @return {Array.<{row:number,column:number}>} array of the selected cells + * @public + */ +GVizChart.prototype.getSelection = function () { + var selection = []; + + var row = this.date_graph.getSelection(); + + if (row < 0) return selection; + + var points = this.date_graph.layout_.points; + for (var setIdx = 0; setIdx < points.length; ++setIdx) { + selection.push({ row: row, column: setIdx + 1 }); + } + + return selection; +}; + +exports['default'] = GVizChart; +module.exports = exports['default']; + +},{"./dygraph":18}],12:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Robert Konigsberg (konigsberg@google.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview The default interaction model for Dygraphs. This is kept out + * of dygraph.js for better navigability. + * @author Robert Konigsberg (konigsberg@google.com) + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +/** + * You can drag this many pixels past the edge of the chart and still have it + * be considered a zoom. This makes it easier to zoom to the exact edge of the + * chart, a fairly common operation. + */ +var DRAG_EDGE_MARGIN = 100; + +/** + * A collection of functions to facilitate build custom interaction models. + * @class + */ +var DygraphInteraction = {}; + +/** + * Checks whether the beginning & ending of an event were close enough that it + * should be considered a click. If it should, dispatch appropriate events. + * Returns true if the event was treated as a click. + * + * @param {Event} event + * @param {Dygraph} g + * @param {Object} context + */ +DygraphInteraction.maybeTreatMouseOpAsClick = function (event, g, context) { + context.dragEndX = utils.dragGetX_(event, context); + context.dragEndY = utils.dragGetY_(event, context); + var regionWidth = Math.abs(context.dragEndX - context.dragStartX); + var regionHeight = Math.abs(context.dragEndY - context.dragStartY); + + if (regionWidth < 2 && regionHeight < 2 && g.lastx_ !== undefined && g.lastx_ != -1) { + DygraphInteraction.treatMouseOpAsClick(g, event, context); + } + + context.regionWidth = regionWidth; + context.regionHeight = regionHeight; +}; + +/** + * Called in response to an interaction model operation that + * should start the default panning behavior. + * + * It's used in the default callback for "mousedown" operations. + * Custom interaction model builders can use it to provide the default + * panning behavior. + * + * @param {Event} event the event object which led to the startPan call. + * @param {Dygraph} g The dygraph on which to act. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.startPan = function (event, g, context) { + var i, axis; + context.isPanning = true; + var xRange = g.xAxisRange(); + + if (g.getOptionForAxis("logscale", "x")) { + context.initialLeftmostDate = utils.log10(xRange[0]); + context.dateRange = utils.log10(xRange[1]) - utils.log10(xRange[0]); + } else { + context.initialLeftmostDate = xRange[0]; + context.dateRange = xRange[1] - xRange[0]; + } + context.xUnitsPerPixel = context.dateRange / (g.plotter_.area.w - 1); + + if (g.getNumericOption("panEdgeFraction")) { + var maxXPixelsToDraw = g.width_ * g.getNumericOption("panEdgeFraction"); + var xExtremes = g.xAxisExtremes(); // I REALLY WANT TO CALL THIS xTremes! + + var boundedLeftX = g.toDomXCoord(xExtremes[0]) - maxXPixelsToDraw; + var boundedRightX = g.toDomXCoord(xExtremes[1]) + maxXPixelsToDraw; + + var boundedLeftDate = g.toDataXCoord(boundedLeftX); + var boundedRightDate = g.toDataXCoord(boundedRightX); + context.boundedDates = [boundedLeftDate, boundedRightDate]; + + var boundedValues = []; + var maxYPixelsToDraw = g.height_ * g.getNumericOption("panEdgeFraction"); + + for (i = 0; i < g.axes_.length; i++) { + axis = g.axes_[i]; + var yExtremes = axis.extremeRange; + + var boundedTopY = g.toDomYCoord(yExtremes[0], i) + maxYPixelsToDraw; + var boundedBottomY = g.toDomYCoord(yExtremes[1], i) - maxYPixelsToDraw; + + var boundedTopValue = g.toDataYCoord(boundedTopY, i); + var boundedBottomValue = g.toDataYCoord(boundedBottomY, i); + + boundedValues[i] = [boundedTopValue, boundedBottomValue]; + } + context.boundedValues = boundedValues; + } + + // Record the range of each y-axis at the start of the drag. + // If any axis has a valueRange, then we want a 2D pan. + // We can't store data directly in g.axes_, because it does not belong to us + // and could change out from under us during a pan (say if there's a data + // update). + context.is2DPan = false; + context.axes = []; + for (i = 0; i < g.axes_.length; i++) { + axis = g.axes_[i]; + var axis_data = {}; + var yRange = g.yAxisRange(i); + // TODO(konigsberg): These values should be in |context|. + // In log scale, initialTopValue, dragValueRange and unitsPerPixel are log scale. + var logscale = g.attributes_.getForAxis("logscale", i); + if (logscale) { + axis_data.initialTopValue = utils.log10(yRange[1]); + axis_data.dragValueRange = utils.log10(yRange[1]) - utils.log10(yRange[0]); + } else { + axis_data.initialTopValue = yRange[1]; + axis_data.dragValueRange = yRange[1] - yRange[0]; + } + axis_data.unitsPerPixel = axis_data.dragValueRange / (g.plotter_.area.h - 1); + context.axes.push(axis_data); + + // While calculating axes, set 2dpan. + if (axis.valueRange) context.is2DPan = true; + } +}; + +/** + * Called in response to an interaction model operation that + * responds to an event that pans the view. + * + * It's used in the default callback for "mousemove" operations. + * Custom interaction model builders can use it to provide the default + * panning behavior. + * + * @param {Event} event the event object which led to the movePan call. + * @param {Dygraph} g The dygraph on which to act. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.movePan = function (event, g, context) { + context.dragEndX = utils.dragGetX_(event, context); + context.dragEndY = utils.dragGetY_(event, context); + + var minDate = context.initialLeftmostDate - (context.dragEndX - context.dragStartX) * context.xUnitsPerPixel; + if (context.boundedDates) { + minDate = Math.max(minDate, context.boundedDates[0]); + } + var maxDate = minDate + context.dateRange; + if (context.boundedDates) { + if (maxDate > context.boundedDates[1]) { + // Adjust minDate, and recompute maxDate. + minDate = minDate - (maxDate - context.boundedDates[1]); + maxDate = minDate + context.dateRange; + } + } + + if (g.getOptionForAxis("logscale", "x")) { + g.dateWindow_ = [Math.pow(utils.LOG_SCALE, minDate), Math.pow(utils.LOG_SCALE, maxDate)]; + } else { + g.dateWindow_ = [minDate, maxDate]; + } + + // y-axis scaling is automatic unless this is a full 2D pan. + if (context.is2DPan) { + + var pixelsDragged = context.dragEndY - context.dragStartY; + + // Adjust each axis appropriately. + for (var i = 0; i < g.axes_.length; i++) { + var axis = g.axes_[i]; + var axis_data = context.axes[i]; + var unitsDragged = pixelsDragged * axis_data.unitsPerPixel; + + var boundedValue = context.boundedValues ? context.boundedValues[i] : null; + + // In log scale, maxValue and minValue are the logs of those values. + var maxValue = axis_data.initialTopValue + unitsDragged; + if (boundedValue) { + maxValue = Math.min(maxValue, boundedValue[1]); + } + var minValue = maxValue - axis_data.dragValueRange; + if (boundedValue) { + if (minValue < boundedValue[0]) { + // Adjust maxValue, and recompute minValue. + maxValue = maxValue - (minValue - boundedValue[0]); + minValue = maxValue - axis_data.dragValueRange; + } + } + if (g.attributes_.getForAxis("logscale", i)) { + axis.valueRange = [Math.pow(utils.LOG_SCALE, minValue), Math.pow(utils.LOG_SCALE, maxValue)]; + } else { + axis.valueRange = [minValue, maxValue]; + } + } + } + + g.drawGraph_(false); +}; + +/** + * Called in response to an interaction model operation that + * responds to an event that ends panning. + * + * It's used in the default callback for "mouseup" operations. + * Custom interaction model builders can use it to provide the default + * panning behavior. + * + * @param {Event} event the event object which led to the endPan call. + * @param {Dygraph} g The dygraph on which to act. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.endPan = DygraphInteraction.maybeTreatMouseOpAsClick; + +/** + * Called in response to an interaction model operation that + * responds to an event that starts zooming. + * + * It's used in the default callback for "mousedown" operations. + * Custom interaction model builders can use it to provide the default + * zooming behavior. + * + * @param {Event} event the event object which led to the startZoom call. + * @param {Dygraph} g The dygraph on which to act. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.startZoom = function (event, g, context) { + context.isZooming = true; + context.zoomMoved = false; +}; + +/** + * Called in response to an interaction model operation that + * responds to an event that defines zoom boundaries. + * + * It's used in the default callback for "mousemove" operations. + * Custom interaction model builders can use it to provide the default + * zooming behavior. + * + * @param {Event} event the event object which led to the moveZoom call. + * @param {Dygraph} g The dygraph on which to act. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.moveZoom = function (event, g, context) { + context.zoomMoved = true; + context.dragEndX = utils.dragGetX_(event, context); + context.dragEndY = utils.dragGetY_(event, context); + + var xDelta = Math.abs(context.dragStartX - context.dragEndX); + var yDelta = Math.abs(context.dragStartY - context.dragEndY); + + // drag direction threshold for y axis is twice as large as x axis + context.dragDirection = xDelta < yDelta / 2 ? utils.VERTICAL : utils.HORIZONTAL; + + g.drawZoomRect_(context.dragDirection, context.dragStartX, context.dragEndX, context.dragStartY, context.dragEndY, context.prevDragDirection, context.prevEndX, context.prevEndY); + + context.prevEndX = context.dragEndX; + context.prevEndY = context.dragEndY; + context.prevDragDirection = context.dragDirection; +}; + +/** + * TODO(danvk): move this logic into dygraph.js + * @param {Dygraph} g + * @param {Event} event + * @param {Object} context + */ +DygraphInteraction.treatMouseOpAsClick = function (g, event, context) { + var clickCallback = g.getFunctionOption('clickCallback'); + var pointClickCallback = g.getFunctionOption('pointClickCallback'); + + var selectedPoint = null; + + // Find out if the click occurs on a point. + var closestIdx = -1; + var closestDistance = Number.MAX_VALUE; + + // check if the click was on a particular point. + for (var i = 0; i < g.selPoints_.length; i++) { + var p = g.selPoints_[i]; + var distance = Math.pow(p.canvasx - context.dragEndX, 2) + Math.pow(p.canvasy - context.dragEndY, 2); + if (!isNaN(distance) && (closestIdx == -1 || distance < closestDistance)) { + closestDistance = distance; + closestIdx = i; + } + } + + // Allow any click within two pixels of the dot. + var radius = g.getNumericOption('highlightCircleSize') + 2; + if (closestDistance <= radius * radius) { + selectedPoint = g.selPoints_[closestIdx]; + } + + if (selectedPoint) { + var e = { + cancelable: true, + point: selectedPoint, + canvasx: context.dragEndX, + canvasy: context.dragEndY + }; + var defaultPrevented = g.cascadeEvents_('pointClick', e); + if (defaultPrevented) { + // Note: this also prevents click / clickCallback from firing. + return; + } + if (pointClickCallback) { + pointClickCallback.call(g, event, selectedPoint); + } + } + + var e = { + cancelable: true, + xval: g.lastx_, // closest point by x value + pts: g.selPoints_, + canvasx: context.dragEndX, + canvasy: context.dragEndY + }; + if (!g.cascadeEvents_('click', e)) { + if (clickCallback) { + // TODO(danvk): pass along more info about the points, e.g. 'x' + clickCallback.call(g, event, g.lastx_, g.selPoints_); + } + } +}; + +/** + * Called in response to an interaction model operation that + * responds to an event that performs a zoom based on previously defined + * bounds.. + * + * It's used in the default callback for "mouseup" operations. + * Custom interaction model builders can use it to provide the default + * zooming behavior. + * + * @param {Event} event the event object which led to the endZoom call. + * @param {Dygraph} g The dygraph on which to end the zoom. + * @param {Object} context The dragging context object (with + * dragStartX/dragStartY/etc. properties). This function modifies the + * context. + */ +DygraphInteraction.endZoom = function (event, g, context) { + g.clearZoomRect_(); + context.isZooming = false; + DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context); + + // The zoom rectangle is visibly clipped to the plot area, so its behavior + // should be as well. + // See http://code.google.com/p/dygraphs/issues/detail?id=280 + var plotArea = g.getArea(); + if (context.regionWidth >= 10 && context.dragDirection == utils.HORIZONTAL) { + var left = Math.min(context.dragStartX, context.dragEndX), + right = Math.max(context.dragStartX, context.dragEndX); + left = Math.max(left, plotArea.x); + right = Math.min(right, plotArea.x + plotArea.w); + if (left < right) { + g.doZoomX_(left, right); + } + context.cancelNextDblclick = true; + } else if (context.regionHeight >= 10 && context.dragDirection == utils.VERTICAL) { + var top = Math.min(context.dragStartY, context.dragEndY), + bottom = Math.max(context.dragStartY, context.dragEndY); + top = Math.max(top, plotArea.y); + bottom = Math.min(bottom, plotArea.y + plotArea.h); + if (top < bottom) { + g.doZoomY_(top, bottom); + } + context.cancelNextDblclick = true; + } + context.dragStartX = null; + context.dragStartY = null; +}; + +/** + * @private + */ +DygraphInteraction.startTouch = function (event, g, context) { + event.preventDefault(); // touch browsers are all nice. + if (event.touches.length > 1) { + // If the user ever puts two fingers down, it's not a double tap. + context.startTimeForDoubleTapMs = null; + } + + var touches = []; + for (var i = 0; i < event.touches.length; i++) { + var t = event.touches[i]; + // we dispense with 'dragGetX_' because all touchBrowsers support pageX + touches.push({ + pageX: t.pageX, + pageY: t.pageY, + dataX: g.toDataXCoord(t.pageX), + dataY: g.toDataYCoord(t.pageY) + // identifier: t.identifier + }); + } + context.initialTouches = touches; + + if (touches.length == 1) { + // This is just a swipe. + context.initialPinchCenter = touches[0]; + context.touchDirections = { x: true, y: true }; + } else if (touches.length >= 2) { + // It's become a pinch! + // In case there are 3+ touches, we ignore all but the "first" two. + + // only screen coordinates can be averaged (data coords could be log scale). + context.initialPinchCenter = { + pageX: 0.5 * (touches[0].pageX + touches[1].pageX), + pageY: 0.5 * (touches[0].pageY + touches[1].pageY), + + // TODO(danvk): remove + dataX: 0.5 * (touches[0].dataX + touches[1].dataX), + dataY: 0.5 * (touches[0].dataY + touches[1].dataY) + }; + + // Make pinches in a 45-degree swath around either axis 1-dimensional zooms. + var initialAngle = 180 / Math.PI * Math.atan2(context.initialPinchCenter.pageY - touches[0].pageY, touches[0].pageX - context.initialPinchCenter.pageX); + + // use symmetry to get it into the first quadrant. + initialAngle = Math.abs(initialAngle); + if (initialAngle > 90) initialAngle = 90 - initialAngle; + + context.touchDirections = { + x: initialAngle < 90 - 45 / 2, + y: initialAngle > 45 / 2 + }; + } + + // save the full x & y ranges. + context.initialRange = { + x: g.xAxisRange(), + y: g.yAxisRange() + }; +}; + +/** + * @private + */ +DygraphInteraction.moveTouch = function (event, g, context) { + // If the tap moves, then it's definitely not part of a double-tap. + context.startTimeForDoubleTapMs = null; + + var i, + touches = []; + for (i = 0; i < event.touches.length; i++) { + var t = event.touches[i]; + touches.push({ + pageX: t.pageX, + pageY: t.pageY + }); + } + var initialTouches = context.initialTouches; + + var c_now; + + // old and new centers. + var c_init = context.initialPinchCenter; + if (touches.length == 1) { + c_now = touches[0]; + } else { + c_now = { + pageX: 0.5 * (touches[0].pageX + touches[1].pageX), + pageY: 0.5 * (touches[0].pageY + touches[1].pageY) + }; + } + + // this is the "swipe" component + // we toss it out for now, but could use it in the future. + var swipe = { + pageX: c_now.pageX - c_init.pageX, + pageY: c_now.pageY - c_init.pageY + }; + var dataWidth = context.initialRange.x[1] - context.initialRange.x[0]; + var dataHeight = context.initialRange.y[0] - context.initialRange.y[1]; + swipe.dataX = swipe.pageX / g.plotter_.area.w * dataWidth; + swipe.dataY = swipe.pageY / g.plotter_.area.h * dataHeight; + var xScale, yScale; + + // The residual bits are usually split into scale & rotate bits, but we split + // them into x-scale and y-scale bits. + if (touches.length == 1) { + xScale = 1.0; + yScale = 1.0; + } else if (touches.length >= 2) { + var initHalfWidth = initialTouches[1].pageX - c_init.pageX; + xScale = (touches[1].pageX - c_now.pageX) / initHalfWidth; + + var initHalfHeight = initialTouches[1].pageY - c_init.pageY; + yScale = (touches[1].pageY - c_now.pageY) / initHalfHeight; + } + + // Clip scaling to [1/8, 8] to prevent too much blowup. + xScale = Math.min(8, Math.max(0.125, xScale)); + yScale = Math.min(8, Math.max(0.125, yScale)); + + var didZoom = false; + if (context.touchDirections.x) { + g.dateWindow_ = [c_init.dataX - swipe.dataX + (context.initialRange.x[0] - c_init.dataX) / xScale, c_init.dataX - swipe.dataX + (context.initialRange.x[1] - c_init.dataX) / xScale]; + didZoom = true; + } + + if (context.touchDirections.y) { + for (i = 0; i < 1 /*g.axes_.length*/; i++) { + var axis = g.axes_[i]; + var logscale = g.attributes_.getForAxis("logscale", i); + if (logscale) { + // TODO(danvk): implement + } else { + axis.valueRange = [c_init.dataY - swipe.dataY + (context.initialRange.y[0] - c_init.dataY) / yScale, c_init.dataY - swipe.dataY + (context.initialRange.y[1] - c_init.dataY) / yScale]; + didZoom = true; + } + } + } + + g.drawGraph_(false); + + // We only call zoomCallback on zooms, not pans, to mirror desktop behavior. + if (didZoom && touches.length > 1 && g.getFunctionOption('zoomCallback')) { + var viewWindow = g.xAxisRange(); + g.getFunctionOption("zoomCallback").call(g, viewWindow[0], viewWindow[1], g.yAxisRanges()); + } +}; + +/** + * @private + */ +DygraphInteraction.endTouch = function (event, g, context) { + if (event.touches.length !== 0) { + // this is effectively a "reset" + DygraphInteraction.startTouch(event, g, context); + } else if (event.changedTouches.length == 1) { + // Could be part of a "double tap" + // The heuristic here is that it's a double-tap if the two touchend events + // occur within 500ms and within a 50x50 pixel box. + var now = new Date().getTime(); + var t = event.changedTouches[0]; + if (context.startTimeForDoubleTapMs && now - context.startTimeForDoubleTapMs < 500 && context.doubleTapX && Math.abs(context.doubleTapX - t.screenX) < 50 && context.doubleTapY && Math.abs(context.doubleTapY - t.screenY) < 50) { + g.resetZoom(); + } else { + context.startTimeForDoubleTapMs = now; + context.doubleTapX = t.screenX; + context.doubleTapY = t.screenY; + } + } +}; + +// Determine the distance from x to [left, right]. +var distanceFromInterval = function distanceFromInterval(x, left, right) { + if (x < left) { + return left - x; + } else if (x > right) { + return x - right; + } else { + return 0; + } +}; + +/** + * Returns the number of pixels by which the event happens from the nearest + * edge of the chart. For events in the interior of the chart, this returns zero. + */ +var distanceFromChart = function distanceFromChart(event, g) { + var chartPos = utils.findPos(g.canvas_); + var box = { + left: chartPos.x, + right: chartPos.x + g.canvas_.offsetWidth, + top: chartPos.y, + bottom: chartPos.y + g.canvas_.offsetHeight + }; + + var pt = { + x: utils.pageX(event), + y: utils.pageY(event) + }; + + var dx = distanceFromInterval(pt.x, box.left, box.right), + dy = distanceFromInterval(pt.y, box.top, box.bottom); + return Math.max(dx, dy); +}; + +/** + * Default interation model for dygraphs. You can refer to specific elements of + * this when constructing your own interaction model, e.g.: + * g.updateOptions( { + * interactionModel: { + * mousedown: DygraphInteraction.defaultInteractionModel.mousedown + * } + * } ); + */ +DygraphInteraction.defaultModel = { + // Track the beginning of drag events + mousedown: function mousedown(event, g, context) { + // Right-click should not initiate a zoom. + if (event.button && event.button == 2) return; + + context.initializeMouseDown(event, g, context); + + if (event.altKey || event.shiftKey) { + DygraphInteraction.startPan(event, g, context); + } else { + DygraphInteraction.startZoom(event, g, context); + } + + // Note: we register mousemove/mouseup on document to allow some leeway for + // events to move outside of the chart. Interaction model events get + // registered on the canvas, which is too small to allow this. + var mousemove = function mousemove(event) { + if (context.isZooming) { + // When the mouse moves >200px from the chart edge, cancel the zoom. + var d = distanceFromChart(event, g); + if (d < DRAG_EDGE_MARGIN) { + DygraphInteraction.moveZoom(event, g, context); + } else { + if (context.dragEndX !== null) { + context.dragEndX = null; + context.dragEndY = null; + g.clearZoomRect_(); + } + } + } else if (context.isPanning) { + DygraphInteraction.movePan(event, g, context); + } + }; + var mouseup = function mouseup(event) { + if (context.isZooming) { + if (context.dragEndX !== null) { + DygraphInteraction.endZoom(event, g, context); + } else { + DygraphInteraction.maybeTreatMouseOpAsClick(event, g, context); + } + } else if (context.isPanning) { + DygraphInteraction.endPan(event, g, context); + } + + utils.removeEvent(document, 'mousemove', mousemove); + utils.removeEvent(document, 'mouseup', mouseup); + context.destroy(); + }; + + g.addAndTrackEvent(document, 'mousemove', mousemove); + g.addAndTrackEvent(document, 'mouseup', mouseup); + }, + willDestroyContextMyself: true, + + touchstart: function touchstart(event, g, context) { + DygraphInteraction.startTouch(event, g, context); + }, + touchmove: function touchmove(event, g, context) { + DygraphInteraction.moveTouch(event, g, context); + }, + touchend: function touchend(event, g, context) { + DygraphInteraction.endTouch(event, g, context); + }, + + // Disable zooming out if panning. + dblclick: function dblclick(event, g, context) { + if (context.cancelNextDblclick) { + context.cancelNextDblclick = false; + return; + } + + // Give plugins a chance to grab this event. + var e = { + canvasx: context.dragEndX, + canvasy: context.dragEndY + }; + if (g.cascadeEvents_('dblclick', e)) { + return; + } + + if (event.altKey || event.shiftKey) { + return; + } + g.resetZoom(); + } +}; + +/* +Dygraph.DEFAULT_ATTRS.interactionModel = DygraphInteraction.defaultModel; + +// old ways of accessing these methods/properties +Dygraph.defaultInteractionModel = DygraphInteraction.defaultModel; +Dygraph.endZoom = DygraphInteraction.endZoom; +Dygraph.moveZoom = DygraphInteraction.moveZoom; +Dygraph.startZoom = DygraphInteraction.startZoom; +Dygraph.endPan = DygraphInteraction.endPan; +Dygraph.movePan = DygraphInteraction.movePan; +Dygraph.startPan = DygraphInteraction.startPan; +*/ + +DygraphInteraction.nonInteractiveModel_ = { + mousedown: function mousedown(event, g, context) { + context.initializeMouseDown(event, g, context); + }, + mouseup: DygraphInteraction.maybeTreatMouseOpAsClick +}; + +// Default interaction model when using the range selector. +DygraphInteraction.dragIsPanInteractionModel = { + mousedown: function mousedown(event, g, context) { + context.initializeMouseDown(event, g, context); + DygraphInteraction.startPan(event, g, context); + }, + mousemove: function mousemove(event, g, context) { + if (context.isPanning) { + DygraphInteraction.movePan(event, g, context); + } + }, + mouseup: function mouseup(event, g, context) { + if (context.isPanning) { + DygraphInteraction.endPan(event, g, context); + } + } +}; + +exports["default"] = DygraphInteraction; +module.exports = exports["default"]; + +},{"./dygraph-utils":17}],13:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview Based on PlotKitLayout, but modified to meet the needs of + * dygraphs. + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +/** + * Creates a new DygraphLayout object. + * + * This class contains all the data to be charted. + * It uses data coordinates, but also records the chart range (in data + * coordinates) and hence is able to calculate percentage positions ('In this + * view, Point A lies 25% down the x-axis.') + * + * Two things that it does not do are: + * 1. Record pixel coordinates for anything. + * 2. (oddly) determine anything about the layout of chart elements. + * + * The naming is a vestige of Dygraph's original PlotKit roots. + * + * @constructor + */ +var DygraphLayout = function DygraphLayout(dygraph) { + this.dygraph_ = dygraph; + /** + * Array of points for each series. + * + * [series index][row index in series] = |Point| structure, + * where series index refers to visible series only, and the + * point index is for the reduced set of points for the current + * zoom region (including one point just outside the window). + * All points in the same row index share the same X value. + * + * @type {Array.>} + */ + this.points = []; + this.setNames = []; + this.annotations = []; + this.yAxes_ = null; + + // TODO(danvk): it's odd that xTicks_ and yTicks_ are inputs, but xticks and + // yticks are outputs. Clean this up. + this.xTicks_ = null; + this.yTicks_ = null; +}; + +/** + * Add points for a single series. + * + * @param {string} setname Name of the series. + * @param {Array.} set_xy Points for the series. + */ +DygraphLayout.prototype.addDataset = function (setname, set_xy) { + this.points.push(set_xy); + this.setNames.push(setname); +}; + +/** + * Returns the box which the chart should be drawn in. This is the canvas's + * box, less space needed for the axis and chart labels. + * + * @return {{x: number, y: number, w: number, h: number}} + */ +DygraphLayout.prototype.getPlotArea = function () { + return this.area_; +}; + +// Compute the box which the chart should be drawn in. This is the canvas's +// box, less space needed for axis, chart labels, and other plug-ins. +// NOTE: This should only be called by Dygraph.predraw_(). +DygraphLayout.prototype.computePlotArea = function () { + var area = { + // TODO(danvk): per-axis setting. + x: 0, + y: 0 + }; + + area.w = this.dygraph_.width_ - area.x - this.dygraph_.getOption('rightGap'); + area.h = this.dygraph_.height_; + + // Let plugins reserve space. + var e = { + chart_div: this.dygraph_.graphDiv, + reserveSpaceLeft: function reserveSpaceLeft(px) { + var r = { + x: area.x, + y: area.y, + w: px, + h: area.h + }; + area.x += px; + area.w -= px; + return r; + }, + reserveSpaceRight: function reserveSpaceRight(px) { + var r = { + x: area.x + area.w - px, + y: area.y, + w: px, + h: area.h + }; + area.w -= px; + return r; + }, + reserveSpaceTop: function reserveSpaceTop(px) { + var r = { + x: area.x, + y: area.y, + w: area.w, + h: px + }; + area.y += px; + area.h -= px; + return r; + }, + reserveSpaceBottom: function reserveSpaceBottom(px) { + var r = { + x: area.x, + y: area.y + area.h - px, + w: area.w, + h: px + }; + area.h -= px; + return r; + }, + chartRect: function chartRect() { + return { x: area.x, y: area.y, w: area.w, h: area.h }; + } + }; + this.dygraph_.cascadeEvents_('layout', e); + + this.area_ = area; +}; + +DygraphLayout.prototype.setAnnotations = function (ann) { + // The Dygraph object's annotations aren't parsed. We parse them here and + // save a copy. If there is no parser, then the user must be using raw format. + this.annotations = []; + var parse = this.dygraph_.getOption('xValueParser') || function (x) { + return x; + }; + for (var i = 0; i < ann.length; i++) { + var a = {}; + if (!ann[i].xval && ann[i].x === undefined) { + console.error("Annotations must have an 'x' property"); + return; + } + if (ann[i].icon && !(ann[i].hasOwnProperty('width') && ann[i].hasOwnProperty('height'))) { + console.error("Must set width and height when setting " + "annotation.icon property"); + return; + } + utils.update(a, ann[i]); + if (!a.xval) a.xval = parse(a.x); + this.annotations.push(a); + } +}; + +DygraphLayout.prototype.setXTicks = function (xTicks) { + this.xTicks_ = xTicks; +}; + +// TODO(danvk): add this to the Dygraph object's API or move it into Layout. +DygraphLayout.prototype.setYAxes = function (yAxes) { + this.yAxes_ = yAxes; +}; + +DygraphLayout.prototype.evaluate = function () { + this._xAxis = {}; + this._evaluateLimits(); + this._evaluateLineCharts(); + this._evaluateLineTicks(); + this._evaluateAnnotations(); +}; + +DygraphLayout.prototype._evaluateLimits = function () { + var xlimits = this.dygraph_.xAxisRange(); + this._xAxis.minval = xlimits[0]; + this._xAxis.maxval = xlimits[1]; + var xrange = xlimits[1] - xlimits[0]; + this._xAxis.scale = xrange !== 0 ? 1 / xrange : 1.0; + + if (this.dygraph_.getOptionForAxis("logscale", 'x')) { + this._xAxis.xlogrange = utils.log10(this._xAxis.maxval) - utils.log10(this._xAxis.minval); + this._xAxis.xlogscale = this._xAxis.xlogrange !== 0 ? 1.0 / this._xAxis.xlogrange : 1.0; + } + for (var i = 0; i < this.yAxes_.length; i++) { + var axis = this.yAxes_[i]; + axis.minyval = axis.computedValueRange[0]; + axis.maxyval = axis.computedValueRange[1]; + axis.yrange = axis.maxyval - axis.minyval; + axis.yscale = axis.yrange !== 0 ? 1.0 / axis.yrange : 1.0; + + if (this.dygraph_.getOption("logscale")) { + axis.ylogrange = utils.log10(axis.maxyval) - utils.log10(axis.minyval); + axis.ylogscale = axis.ylogrange !== 0 ? 1.0 / axis.ylogrange : 1.0; + if (!isFinite(axis.ylogrange) || isNaN(axis.ylogrange)) { + console.error('axis ' + i + ' of graph at ' + axis.g + ' can\'t be displayed in log scale for range [' + axis.minyval + ' - ' + axis.maxyval + ']'); + } + } + } +}; + +DygraphLayout.calcXNormal_ = function (value, xAxis, logscale) { + if (logscale) { + return (utils.log10(value) - utils.log10(xAxis.minval)) * xAxis.xlogscale; + } else { + return (value - xAxis.minval) * xAxis.scale; + } +}; + +/** + * @param {DygraphAxisType} axis + * @param {number} value + * @param {boolean} logscale + * @return {number} + */ +DygraphLayout.calcYNormal_ = function (axis, value, logscale) { + if (logscale) { + var x = 1.0 - (utils.log10(value) - utils.log10(axis.minyval)) * axis.ylogscale; + return isFinite(x) ? x : NaN; // shim for v8 issue; see pull request 276 + } else { + return 1.0 - (value - axis.minyval) * axis.yscale; + } +}; + +DygraphLayout.prototype._evaluateLineCharts = function () { + var isStacked = this.dygraph_.getOption("stackedGraph"); + var isLogscaleForX = this.dygraph_.getOptionForAxis("logscale", 'x'); + + for (var setIdx = 0; setIdx < this.points.length; setIdx++) { + var points = this.points[setIdx]; + var setName = this.setNames[setIdx]; + var connectSeparated = this.dygraph_.getOption('connectSeparatedPoints', setName); + var axis = this.dygraph_.axisPropertiesForSeries(setName); + // TODO (konigsberg): use optionsForAxis instead. + var logscale = this.dygraph_.attributes_.getForSeries("logscale", setName); + + for (var j = 0; j < points.length; j++) { + var point = points[j]; + + // Range from 0-1 where 0 represents left and 1 represents right. + point.x = DygraphLayout.calcXNormal_(point.xval, this._xAxis, isLogscaleForX); + // Range from 0-1 where 0 represents top and 1 represents bottom + var yval = point.yval; + if (isStacked) { + point.y_stacked = DygraphLayout.calcYNormal_(axis, point.yval_stacked, logscale); + if (yval !== null && !isNaN(yval)) { + yval = point.yval_stacked; + } + } + if (yval === null) { + yval = NaN; + if (!connectSeparated) { + point.yval = NaN; + } + } + point.y = DygraphLayout.calcYNormal_(axis, yval, logscale); + } + + this.dygraph_.dataHandler_.onLineEvaluated(points, axis, logscale); + } +}; + +DygraphLayout.prototype._evaluateLineTicks = function () { + var i, tick, label, pos, v, has_tick; + this.xticks = []; + for (i = 0; i < this.xTicks_.length; i++) { + tick = this.xTicks_[i]; + label = tick.label; + has_tick = !('label_v' in tick); + v = has_tick ? tick.v : tick.label_v; + pos = this.dygraph_.toPercentXCoord(v); + if (pos >= 0.0 && pos < 1.0) { + this.xticks.push({ pos: pos, label: label, has_tick: has_tick }); + } + } + + this.yticks = []; + for (i = 0; i < this.yAxes_.length; i++) { + var axis = this.yAxes_[i]; + for (var j = 0; j < axis.ticks.length; j++) { + tick = axis.ticks[j]; + label = tick.label; + has_tick = !('label_v' in tick); + v = has_tick ? tick.v : tick.label_v; + pos = this.dygraph_.toPercentYCoord(v, i); + if (pos > 0.0 && pos <= 1.0) { + this.yticks.push({ axis: i, pos: pos, label: label, has_tick: has_tick }); + } + } + } +}; + +DygraphLayout.prototype._evaluateAnnotations = function () { + // Add the annotations to the point to which they belong. + // Make a map from (setName, xval) to annotation for quick lookups. + var i; + var annotations = {}; + for (i = 0; i < this.annotations.length; i++) { + var a = this.annotations[i]; + annotations[a.xval + "," + a.series] = a; + } + + this.annotated_points = []; + + // Exit the function early if there are no annotations. + if (!this.annotations || !this.annotations.length) { + return; + } + + // TODO(antrob): loop through annotations not points. + for (var setIdx = 0; setIdx < this.points.length; setIdx++) { + var points = this.points[setIdx]; + for (i = 0; i < points.length; i++) { + var p = points[i]; + var k = p.xval + "," + p.name; + if (k in annotations) { + p.annotation = annotations[k]; + this.annotated_points.push(p); + } + } + } +}; + +/** + * Convenience function to remove all the data sets from a graph + */ +DygraphLayout.prototype.removeAllDatasets = function () { + delete this.points; + delete this.setNames; + delete this.setPointsLengths; + delete this.setPointsOffsets; + this.points = []; + this.setNames = []; + this.setPointsLengths = []; + this.setPointsOffsets = []; +}; + +exports['default'] = DygraphLayout; +module.exports = exports['default']; + +},{"./dygraph-utils":17}],14:[function(require,module,exports){ +(function (process){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +var OPTIONS_REFERENCE = null; + +// For "production" code, this gets removed by uglifyjs. +if (typeof process !== 'undefined') { + if ("development" != 'production') { + + // NOTE: in addition to parsing as JS, this snippet is expected to be valid + // JSON. This assumption cannot be checked in JS, but it will be checked when + // documentation is generated by the generate-documentation.py script. For the + // most part, this just means that you should always use double quotes. + OPTIONS_REFERENCE = // + { + "xValueParser": { + "default": "parseFloat() or Date.parse()*", + "labels": ["CSV parsing"], + "type": "function(str) -> number", + "description": "A function which parses x-values (i.e. the dependent series). Must return a number, even when the values are dates. In this case, millis since epoch are used. This is used primarily for parsing CSV data. *=Dygraphs is slightly more accepting in the dates which it will parse. See code for details." + }, + "stackedGraph": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "If set, stack series on top of one another rather than drawing them independently. The first series specified in the input data will wind up on top of the chart and the last will be on bottom. NaN values are drawn as white areas without a line on top, see stackedGraphNaNFill for details." + }, + "stackedGraphNaNFill": { + "default": "all", + "labels": ["Data Line display"], + "type": "string", + "description": "Controls handling of NaN values inside a stacked graph. NaN values are interpolated/extended for stacking purposes, but the actual point value remains NaN in the legend display. Valid option values are \"all\" (interpolate internally, repeat leftmost and rightmost value as needed), \"inside\" (interpolate internally only, use zero outside leftmost and rightmost value), and \"none\" (treat NaN as zero everywhere)." + }, + "pointSize": { + "default": "1", + "labels": ["Data Line display"], + "type": "integer", + "description": "The size of the dot to draw on each point in pixels (see drawPoints). A dot is always drawn when a point is \"isolated\", i.e. there is a missing point on either side of it. This also controls the size of those dots." + }, + "drawPoints": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "Draw a small dot at each point, in addition to a line going through the point. This makes the individual data points easier to see, but can increase visual clutter in the chart. The small dot can be replaced with a custom rendering by supplying a drawPointCallback." + }, + "drawGapEdgePoints": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "Draw points at the edges of gaps in the data. This improves visibility of small data segments or other data irregularities." + }, + "drawPointCallback": { + "default": "null", + "labels": ["Data Line display"], + "type": "function(g, seriesName, canvasContext, cx, cy, color, pointSize)", + "parameters": [["g", "the reference graph"], ["seriesName", "the name of the series"], ["canvasContext", "the canvas to draw on"], ["cx", "center x coordinate"], ["cy", "center y coordinate"], ["color", "series color"], ["pointSize", "the radius of the image."], ["idx", "the row-index of the point in the data."]], + "description": "Draw a custom item when drawPoints is enabled. Default is a small dot matching the series color. This method should constrain drawing to within pointSize pixels from (cx, cy). Also see drawHighlightPointCallback" + }, + "height": { + "default": "320", + "labels": ["Overall display"], + "type": "integer", + "description": "Height, in pixels, of the chart. If the container div has been explicitly sized, this will be ignored." + }, + "zoomCallback": { + "default": "null", + "labels": ["Callbacks"], + "type": "function(minDate, maxDate, yRanges)", + "parameters": [["minDate", "milliseconds since epoch"], ["maxDate", "milliseconds since epoch."], ["yRanges", "is an array of [bottom, top] pairs, one for each y-axis."]], + "description": "A function to call when the zoom window is changed (either by zooming in or out). When animatedZooms is set, zoomCallback is called once at the end of the transition (it will not be called for intermediate frames)." + }, + "pointClickCallback": { + "snippet": "function(e, point){
  alert(point);
}", + "default": "null", + "labels": ["Callbacks", "Interactive Elements"], + "type": "function(e, point)", + "parameters": [["e", "the event object for the click"], ["point", "the point that was clicked See Point properties for details"]], + "description": "A function to call when a data point is clicked. and the point that was clicked." + }, + "color": { + "default": "(see description)", + "labels": ["Data Series Colors"], + "type": "string", + "example": "red", + "description": "A per-series color definition. Used in conjunction with, and overrides, the colors option." + }, + "colors": { + "default": "(see description)", + "labels": ["Data Series Colors"], + "type": "array", + "example": "['red', '#00FF00']", + "description": "List of colors for the data series. These can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\", etc. If not specified, equally-spaced points around a color wheel are used. Overridden by the 'color' option." + }, + "connectSeparatedPoints": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "Usually, when Dygraphs encounters a missing value in a data series, it interprets this as a gap and draws it as such. If, instead, the missing values represents an x-value for which only a different series has data, then you'll want to connect the dots by setting this to true. To explicitly include a gap with this option set, use a value of NaN." + }, + "highlightCallback": { + "default": "null", + "labels": ["Callbacks"], + "type": "function(event, x, points, row, seriesName)", + "description": "When set, this callback gets called every time a new point is highlighted.", + "parameters": [["event", "the JavaScript mousemove event"], ["x", "the x-coordinate of the highlighted points"], ["points", "an array of highlighted points: [ {name: 'series', yval: y-value}, … ]"], ["row", "integer index of the highlighted row in the data table, starting from 0"], ["seriesName", "name of the highlighted series, only present if highlightSeriesOpts is set."]] + }, + "drawHighlightPointCallback": { + "default": "null", + "labels": ["Data Line display"], + "type": "function(g, seriesName, canvasContext, cx, cy, color, pointSize)", + "parameters": [["g", "the reference graph"], ["seriesName", "the name of the series"], ["canvasContext", "the canvas to draw on"], ["cx", "center x coordinate"], ["cy", "center y coordinate"], ["color", "series color"], ["pointSize", "the radius of the image."], ["idx", "the row-index of the point in the data."]], + "description": "Draw a custom item when a point is highlighted. Default is a small dot matching the series color. This method should constrain drawing to within pointSize pixels from (cx, cy) Also see drawPointCallback" + }, + "highlightSeriesOpts": { + "default": "null", + "labels": ["Interactive Elements"], + "type": "Object", + "description": "When set, the options from this object are applied to the timeseries closest to the mouse pointer for interactive highlighting. See also 'highlightCallback'. Example: highlightSeriesOpts: { strokeWidth: 3 }." + }, + "highlightSeriesBackgroundAlpha": { + "default": "0.5", + "labels": ["Interactive Elements"], + "type": "float", + "description": "Fade the background while highlighting series. 1=fully visible background (disable fading), 0=hiddden background (show highlighted series only)." + }, + "highlightSeriesBackgroundColor": { + "default": "rgb(255, 255, 255)", + "labels": ["Interactive Elements"], + "type": "string", + "description": "Sets the background color used to fade out the series in conjunction with 'highlightSeriesBackgroundAlpha'." + }, + "includeZero": { + "default": "false", + "labels": ["Axis display"], + "type": "boolean", + "description": "Usually, dygraphs will use the range of the data plus some padding to set the range of the y-axis. If this option is set, the y-axis will always include zero, typically as the lowest value. This can be used to avoid exaggerating the variance in the data" + }, + "rollPeriod": { + "default": "1", + "labels": ["Error Bars", "Rolling Averages"], + "type": "integer >= 1", + "description": "Number of days over which to average data. Discussed extensively above." + }, + "unhighlightCallback": { + "default": "null", + "labels": ["Callbacks"], + "type": "function(event)", + "parameters": [["event", "the mouse event"]], + "description": "When set, this callback gets called every time the user stops highlighting any point by mousing out of the graph." + }, + "axisTickSize": { + "default": "3.0", + "labels": ["Axis display"], + "type": "number", + "description": "The size of the line to display next to each tick mark on x- or y-axes." + }, + "labelsSeparateLines": { + "default": "false", + "labels": ["Legend"], + "type": "boolean", + "description": "Put <br/> between lines in the label string. Often used in conjunction with labelsDiv." + }, + "valueFormatter": { + "default": "Depends on the type of your data.", + "labels": ["Legend", "Value display/formatting"], + "type": "function(num or millis, opts, seriesName, dygraph, row, col)", + "description": "Function to provide a custom display format for the values displayed on mouseover. This does not affect the values that appear on tick marks next to the axes. To format those, see axisLabelFormatter. This is usually set on a per-axis basis. .", + "parameters": [["num_or_millis", "The value to be formatted. This is always a number. For date axes, it's millis since epoch. You can call new Date(millis) to get a Date object."], ["opts", "This is a function you can call to access various options (e.g. opts('labelsKMB')). It returns per-axis values for the option when available."], ["seriesName", "The name of the series from which the point came, e.g. 'X', 'Y', 'A', etc."], ["dygraph", "The dygraph object for which the formatting is being done"], ["row", "The row of the data from which this point comes. g.getValue(row, 0) will return the x-value for this point."], ["col", "The column of the data from which this point comes. g.getValue(row, col) will return the original y-value for this point. This can be used to get the full confidence interval for the point, or access un-rolled values for the point."]] + }, + "annotationMouseOverHandler": { + "default": "null", + "labels": ["Annotations"], + "type": "function(annotation, point, dygraph, event)", + "description": "If provided, this function is called whenever the user mouses over an annotation." + }, + "annotationMouseOutHandler": { + "default": "null", + "labels": ["Annotations"], + "type": "function(annotation, point, dygraph, event)", + "parameters": [["annotation", "the annotation left"], ["point", "the point associated with the annotation"], ["dygraph", "the reference graph"], ["event", "the mouse event"]], + "description": "If provided, this function is called whenever the user mouses out of an annotation." + }, + "annotationClickHandler": { + "default": "null", + "labels": ["Annotations"], + "type": "function(annotation, point, dygraph, event)", + "parameters": [["annotation", "the annotation left"], ["point", "the point associated with the annotation"], ["dygraph", "the reference graph"], ["event", "the mouse event"]], + "description": "If provided, this function is called whenever the user clicks on an annotation." + }, + "annotationDblClickHandler": { + "default": "null", + "labels": ["Annotations"], + "type": "function(annotation, point, dygraph, event)", + "parameters": [["annotation", "the annotation left"], ["point", "the point associated with the annotation"], ["dygraph", "the reference graph"], ["event", "the mouse event"]], + "description": "If provided, this function is called whenever the user double-clicks on an annotation." + }, + "drawCallback": { + "default": "null", + "labels": ["Callbacks"], + "type": "function(dygraph, is_initial)", + "parameters": [["dygraph", "The graph being drawn"], ["is_initial", "True if this is the initial draw, false for subsequent draws."]], + "description": "When set, this callback gets called every time the dygraph is drawn. This includes the initial draw, after zooming and repeatedly while panning." + }, + "labelsKMG2": { + "default": "false", + "labels": ["Value display/formatting"], + "type": "boolean", + "description": "Show k/M/G for kilo/Mega/Giga on y-axis. This is different than labelsKMB in that it uses base 2, not 10." + }, + "delimiter": { + "default": ",", + "labels": ["CSV parsing"], + "type": "string", + "description": "The delimiter to look for when separating fields of a CSV file. Setting this to a tab is not usually necessary, since tab-delimited data is auto-detected." + }, + "axisLabelFontSize": { + "default": "14", + "labels": ["Axis display"], + "type": "integer", + "description": "Size of the font (in pixels) to use in the axis labels, both x- and y-axis." + }, + "underlayCallback": { + "default": "null", + "labels": ["Callbacks"], + "type": "function(context, area, dygraph)", + "parameters": [["context", "the canvas drawing context on which to draw"], ["area", "An object with {x,y,w,h} properties describing the drawing area."], ["dygraph", "the reference graph"]], + "description": "When set, this callback gets called before the chart is drawn. It details on how to use this." + }, + "width": { + "default": "480", + "labels": ["Overall display"], + "type": "integer", + "description": "Width, in pixels, of the chart. If the container div has been explicitly sized, this will be ignored." + }, + "interactionModel": { + "default": "...", + "labels": ["Interactive Elements"], + "type": "Object", + "description": "TODO(konigsberg): document this" + }, + "ticker": { + "default": "Dygraph.dateTicker or Dygraph.numericTicks", + "labels": ["Axis display"], + "type": "function(min, max, pixels, opts, dygraph, vals) -> [{v: ..., label: ...}, ...]", + "parameters": [["min", ""], ["max", ""], ["pixels", ""], ["opts", ""], ["dygraph", "the reference graph"], ["vals", ""]], + "description": "This lets you specify an arbitrary function to generate tick marks on an axis. The tick marks are an array of (value, label) pairs. The built-in functions go to great lengths to choose good tick marks so, if you set this option, you'll most likely want to call one of them and modify the result. See dygraph-tickers.js for an extensive discussion. This is set on a per-axis basis." + }, + "xAxisHeight": { + "default": "(null)", + "labels": ["Axis display"], + "type": "integer", + "description": "Height, in pixels, of the x-axis. If not set explicitly, this is computed based on axisLabelFontSize and axisTickSize." + }, + "showLabelsOnHighlight": { + "default": "true", + "labels": ["Interactive Elements", "Legend"], + "type": "boolean", + "description": "Whether to show the legend upon mouseover." + }, + "axis": { + "default": "(none)", + "labels": ["Axis display"], + "type": "string", + "description": "Set to either 'y1' or 'y2' to assign a series to a y-axis (primary or secondary). Must be set per-series." + }, + "pixelsPerLabel": { + "default": "70 (x-axis) or 30 (y-axes)", + "labels": ["Axis display", "Grid"], + "type": "integer", + "description": "Number of pixels to require between each x- and y-label. Larger values will yield a sparser axis with fewer ticks. This is set on a per-axis basis." + }, + "labelsDiv": { + "default": "null", + "labels": ["Legend"], + "type": "DOM element or string", + "example": "document.getElementById('foo')or'foo'", + "description": "Show data labels in an external div, rather than on the graph. This value can either be a div element or a div id." + }, + "fractions": { + "default": "false", + "labels": ["CSV parsing", "Error Bars"], + "type": "boolean", + "description": "When set, attempt to parse each cell in the CSV file as \"a/b\", where a and b are integers. The ratio will be plotted. This allows computation of Wilson confidence intervals (see below)." + }, + "logscale": { + "default": "false", + "labels": ["Axis display"], + "type": "boolean", + "description": "When set for the y-axis or x-axis, the graph shows that axis in log scale. Any values less than or equal to zero are not displayed. Showing log scale with ranges that go below zero will result in an unviewable graph.\n\n Not compatible with showZero. connectSeparatedPoints is ignored. This is ignored for date-based x-axes." + }, + "strokeWidth": { + "default": "1.0", + "labels": ["Data Line display"], + "type": "float", + "example": "0.5, 2.0", + "description": "The width of the lines connecting data points. This can be used to increase the contrast or some graphs." + }, + "strokePattern": { + "default": "null", + "labels": ["Data Line display"], + "type": "array", + "example": "[10, 2, 5, 2]", + "description": "A custom pattern array where the even index is a draw and odd is a space in pixels. If null then it draws a solid line. The array should have a even length as any odd lengthed array could be expressed as a smaller even length array. This is used to create dashed lines." + }, + "strokeBorderWidth": { + "default": "null", + "labels": ["Data Line display"], + "type": "float", + "example": "1.0", + "description": "Draw a border around graph lines to make crossing lines more easily distinguishable. Useful for graphs with many lines." + }, + "strokeBorderColor": { + "default": "white", + "labels": ["Data Line display"], + "type": "string", + "example": "red, #ccffdd", + "description": "Color for the line border used if strokeBorderWidth is set." + }, + "wilsonInterval": { + "default": "true", + "labels": ["Error Bars"], + "type": "boolean", + "description": "Use in conjunction with the \"fractions\" option. Instead of plotting +/- N standard deviations, dygraphs will compute a Wilson confidence interval and plot that. This has more reasonable behavior for ratios close to 0 or 1." + }, + "fillGraph": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "Should the area underneath the graph be filled? This option is not compatible with error bars. This may be set on a per-series basis." + }, + "highlightCircleSize": { + "default": "3", + "labels": ["Interactive Elements"], + "type": "integer", + "description": "The size in pixels of the dot drawn over highlighted points." + }, + "gridLineColor": { + "default": "rgb(128,128,128)", + "labels": ["Grid"], + "type": "red, blue", + "description": "The color of the gridlines. This may be set on a per-axis basis to define each axis' grid separately." + }, + "gridLinePattern": { + "default": "null", + "labels": ["Grid"], + "type": "array", + "example": "[10, 2, 5, 2]", + "description": "A custom pattern array where the even index is a draw and odd is a space in pixels. If null then it draws a solid line. The array should have a even length as any odd lengthed array could be expressed as a smaller even length array. This is used to create dashed gridlines." + }, + "visibility": { + "default": "[true, true, ...]", + "labels": ["Data Line display"], + "type": "Array of booleans", + "description": "Which series should initially be visible? Once the Dygraph has been constructed, you can access and modify the visibility of each series using the visibility and setVisibility methods." + }, + "valueRange": { + "default": "Full range of the input is shown", + "labels": ["Axis display"], + "type": "Array of two numbers", + "example": "[10, 110]", + "description": "Explicitly set the vertical range of the graph to [low, high]. This may be set on a per-axis basis to define each y-axis separately. If either limit is unspecified, it will be calculated automatically (e.g. [null, 30] to automatically calculate just the lower bound)" + }, + "colorSaturation": { + "default": "1.0", + "labels": ["Data Series Colors"], + "type": "float (0.0 - 1.0)", + "description": "If colors is not specified, saturation of the automatically-generated data series colors." + }, + "hideOverlayOnMouseOut": { + "default": "true", + "labels": ["Interactive Elements", "Legend"], + "type": "boolean", + "description": "Whether to hide the legend when the mouse leaves the chart area." + }, + "legend": { + "default": "onmouseover", + "labels": ["Legend"], + "type": "string", + "description": "When to display the legend. By default, it only appears when a user mouses over the chart. Set it to \"always\" to always display a legend of some sort. When set to \"follow\", legend follows highlighted points." + }, + "legendFormatter": { + "default": "null", + "labels": ["Legend"], + "type": "function(data): string", + "params": [["data", "An object containing information about the selection (or lack of a selection). This includes formatted values and series information. See here for sample values."]], + "description": "Set this to supply a custom formatter for the legend. See this comment and the legendFormatter demo for usage." + }, + "labelsShowZeroValues": { + "default": "true", + "labels": ["Legend"], + "type": "boolean", + "description": "Show zero value labels in the labelsDiv." + }, + "stepPlot": { + "default": "false", + "labels": ["Data Line display"], + "type": "boolean", + "description": "When set, display the graph as a step plot instead of a line plot. This option may either be set for the whole graph or for single series." + }, + "labelsUTC": { + "default": "false", + "labels": ["Value display/formatting", "Axis display"], + "type": "boolean", + "description": "Show date/time labels according to UTC (instead of local time)." + }, + "labelsKMB": { + "default": "false", + "labels": ["Value display/formatting"], + "type": "boolean", + "description": "Show K/M/B for thousands/millions/billions on y-axis." + }, + "rightGap": { + "default": "5", + "labels": ["Overall display"], + "type": "integer", + "description": "Number of pixels to leave blank at the right edge of the Dygraph. This makes it easier to highlight the right-most data point." + }, + "drawAxesAtZero": { + "default": "false", + "labels": ["Axis display"], + "type": "boolean", + "description": "When set, draw the X axis at the Y=0 position and the Y axis at the X=0 position if those positions are inside the graph's visible area. Otherwise, draw the axes at the bottom or left graph edge as usual." + }, + "xRangePad": { + "default": "0", + "labels": ["Axis display"], + "type": "float", + "description": "Add the specified amount of extra space (in pixels) around the X-axis value range to ensure points at the edges remain visible." + }, + "yRangePad": { + "default": "null", + "labels": ["Axis display"], + "type": "float", + "description": "If set, add the specified amount of extra space (in pixels) around the Y-axis value range to ensure points at the edges remain visible. If unset, use the traditional Y padding algorithm." + }, + "axisLabelFormatter": { + "default": "Depends on the data type", + "labels": ["Axis display"], + "type": "function(number or Date, granularity, opts, dygraph)", + "parameters": [["number or date", "Either a number (for a numeric axis) or a Date object (for a date axis)"], ["granularity", "specifies how fine-grained the axis is. For date axes, this is a reference to the time granularity enumeration, defined in dygraph-tickers.js, e.g. Dygraph.WEEKLY."], ["opts", "a function which provides access to various options on the dygraph, e.g. opts('labelsKMB')."], ["dygraph", "the referenced graph"]], + "description": "Function to call to format the tick values that appear along an axis. This is usually set on a per-axis basis." + }, + "clickCallback": { + "snippet": "function(e, date_millis){
  alert(new Date(date_millis));
}", + "default": "null", + "labels": ["Callbacks"], + "type": "function(e, x, points)", + "parameters": [["e", "The event object for the click"], ["x", "The x value that was clicked (for dates, this is milliseconds since epoch)"], ["points", "The closest points along that date. See Point properties for details."]], + "description": "A function to call when the canvas is clicked." + }, + "labels": { + "default": "[\"X\", \"Y1\", \"Y2\", ...]*", + "labels": ["Legend"], + "type": "array", + "description": "A name for each data series, including the independent (X) series. For CSV files and DataTable objections, this is determined by context. For raw data, this must be specified. If it is not, default values are supplied and a warning is logged." + }, + "dateWindow": { + "default": "Full range of the input is shown", + "labels": ["Axis display"], + "type": "Array of two numbers", + "example": "[
  Date.parse('2006-01-01'),
  (new Date()).valueOf()
]", + "description": "Initially zoom in on a section of the graph. Is of the form [earliest, latest], where earliest/latest are milliseconds since epoch. If the data for the x-axis is numeric, the values in dateWindow must also be numbers." + }, + "showRoller": { + "default": "false", + "labels": ["Interactive Elements", "Rolling Averages"], + "type": "boolean", + "description": "If the rolling average period text box should be shown." + }, + "sigma": { + "default": "2.0", + "labels": ["Error Bars"], + "type": "float", + "description": "When errorBars is set, shade this many standard deviations above/below each point." + }, + "customBars": { + "default": "false", + "labels": ["CSV parsing", "Error Bars"], + "type": "boolean", + "description": "When set, parse each CSV cell as \"low;middle;high\". Error bars will be drawn for each point between low and high, with the series itself going through middle." + }, + "colorValue": { + "default": "1.0", + "labels": ["Data Series Colors"], + "type": "float (0.0 - 1.0)", + "description": "If colors is not specified, value of the data series colors, as in hue/saturation/value. (0.0-1.0, default 0.5)" + }, + "errorBars": { + "default": "false", + "labels": ["CSV parsing", "Error Bars"], + "type": "boolean", + "description": "Does the data contain standard deviations? Setting this to true alters the input format (see above)." + }, + "displayAnnotations": { + "default": "false", + "labels": ["Annotations"], + "type": "boolean", + "description": "Only applies when Dygraphs is used as a GViz chart. Causes string columns following a data series to be interpreted as annotations on points in that series. This is the same format used by Google's AnnotatedTimeLine chart." + }, + "panEdgeFraction": { + "default": "null", + "labels": ["Axis display", "Interactive Elements"], + "type": "float", + "description": "A value representing the farthest a graph may be panned, in percent of the display. For example, a value of 0.1 means that the graph can only be panned 10% pased the edges of the displayed values. null means no bounds." + }, + "title": { + "labels": ["Chart labels"], + "type": "string", + "default": "null", + "description": "Text to display above the chart. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-title' classes." + }, + "titleHeight": { + "default": "18", + "labels": ["Chart labels"], + "type": "integer", + "description": "Height of the chart title, in pixels. This also controls the default font size of the title. If you style the title on your own, this controls how much space is set aside above the chart for the title's div." + }, + "xlabel": { + "labels": ["Chart labels"], + "type": "string", + "default": "null", + "description": "Text to display below the chart's x-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-xlabel' classes." + }, + "xLabelHeight": { + "labels": ["Chart labels"], + "type": "integer", + "default": "18", + "description": "Height of the x-axis label, in pixels. This also controls the default font size of the x-axis label. If you style the label on your own, this controls how much space is set aside below the chart for the x-axis label's div." + }, + "ylabel": { + "labels": ["Chart labels"], + "type": "string", + "default": "null", + "description": "Text to display to the left of the chart's y-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-ylabel' classes. The text will be rotated 90 degrees by default, so CSS rules may behave in unintuitive ways. No additional space is set aside for a y-axis label. If you need more space, increase the width of the y-axis tick labels using the yAxisLabelWidth option. If you need a wider div for the y-axis label, either style it that way with CSS (but remember that it's rotated, so width is controlled by the 'height' property) or set the yLabelWidth option." + }, + "y2label": { + "labels": ["Chart labels"], + "type": "string", + "default": "null", + "description": "Text to display to the right of the chart's secondary y-axis. This label is only displayed if a secondary y-axis is present. See this test for an example of how to do this. The comments for the 'ylabel' option generally apply here as well. This label gets a 'dygraph-y2label' instead of a 'dygraph-ylabel' class." + }, + "yLabelWidth": { + "labels": ["Chart labels"], + "type": "integer", + "default": "18", + "description": "Width of the div which contains the y-axis label. Since the y-axis label appears rotated 90 degrees, this actually affects the height of its div." + }, + "drawGrid": { + "default": "true for x and y, false for y2", + "labels": ["Grid"], + "type": "boolean", + "description": "Whether to display gridlines in the chart. This may be set on a per-axis basis to define the visibility of each axis' grid separately." + }, + "independentTicks": { + "default": "true for y, false for y2", + "labels": ["Axis display", "Grid"], + "type": "boolean", + "description": "Only valid for y and y2, has no effect on x: This option defines whether the y axes should align their ticks or if they should be independent. Possible combinations: 1.) y=true, y2=false (default): y is the primary axis and the y2 ticks are aligned to the the ones of y. (only 1 grid) 2.) y=false, y2=true: y2 is the primary axis and the y ticks are aligned to the the ones of y2. (only 1 grid) 3.) y=true, y2=true: Both axis are independent and have their own ticks. (2 grids) 4.) y=false, y2=false: Invalid configuration causes an error." + }, + "drawAxis": { + "default": "true for x and y, false for y2", + "labels": ["Axis display"], + "type": "boolean", + "description": "Whether to draw the specified axis. This may be set on a per-axis basis to define the visibility of each axis separately. Setting this to false also prevents axis ticks from being drawn and reclaims the space for the chart grid/lines." + }, + "gridLineWidth": { + "default": "0.3", + "labels": ["Grid"], + "type": "float", + "description": "Thickness (in pixels) of the gridlines drawn under the chart. The vertical/horizontal gridlines can be turned off entirely by using the drawGrid option. This may be set on a per-axis basis to define each axis' grid separately." + }, + "axisLineWidth": { + "default": "0.3", + "labels": ["Axis display"], + "type": "float", + "description": "Thickness (in pixels) of the x- and y-axis lines." + }, + "axisLineColor": { + "default": "black", + "labels": ["Axis display"], + "type": "string", + "description": "Color of the x- and y-axis lines. Accepts any value which the HTML canvas strokeStyle attribute understands, e.g. 'black' or 'rgb(0, 100, 255)'." + }, + "fillAlpha": { + "default": "0.15", + "labels": ["Error Bars", "Data Series Colors"], + "type": "float (0.0 - 1.0)", + "description": "Error bars (or custom bars) for each series are drawn in the same color as the series, but with partial transparency. This sets the transparency. A value of 0.0 means that the error bars will not be drawn, whereas a value of 1.0 means that the error bars will be as dark as the line for the series itself. This can be used to produce chart lines whose thickness varies at each point." + }, + "axisLabelWidth": { + "default": "50 (y-axis), 60 (x-axis)", + "labels": ["Axis display", "Chart labels"], + "type": "integer", + "description": "Width (in pixels) of the containing divs for x- and y-axis labels. For the y-axis, this also controls the width of the y-axis. Note that for the x-axis, this is independent from pixelsPerLabel, which controls the spacing between labels." + }, + "sigFigs": { + "default": "null", + "labels": ["Value display/formatting"], + "type": "integer", + "description": "By default, dygraphs displays numbers with a fixed number of digits after the decimal point. If you'd prefer to have a fixed number of significant figures, set this option to that number of sig figs. A value of 2, for instance, would cause 1 to be display as 1.0 and 1234 to be displayed as 1.23e+3." + }, + "digitsAfterDecimal": { + "default": "2", + "labels": ["Value display/formatting"], + "type": "integer", + "description": "Unless it's run in scientific mode (see the sigFigs option), dygraphs displays numbers with digitsAfterDecimal digits after the decimal point. Trailing zeros are not displayed, so with a value of 2 you'll get '0', '0.1', '0.12', '123.45' but not '123.456' (it will be rounded to '123.46'). Numbers with absolute value less than 0.1^digitsAfterDecimal (i.e. those which would show up as '0.00') will be displayed in scientific notation." + }, + "maxNumberWidth": { + "default": "6", + "labels": ["Value display/formatting"], + "type": "integer", + "description": "When displaying numbers in normal (not scientific) mode, large numbers will be displayed with many trailing zeros (e.g. 100000000 instead of 1e9). This can lead to unwieldy y-axis labels. If there are more than maxNumberWidth digits to the left of the decimal in a number, dygraphs will switch to scientific notation, even when not operating in scientific mode. If you'd like to see all those digits, set this to something large, like 20 or 30." + }, + "file": { + "default": "(set when constructed)", + "labels": ["Data"], + "type": "string (URL of CSV or CSV), GViz DataTable or 2D Array", + "description": "Sets the data being displayed in the chart. This can only be set when calling updateOptions; it cannot be set from the constructor. For a full description of valid data formats, see the Data Formats page." + }, + "timingName": { + "default": "null", + "labels": ["Debugging", "Deprecated"], + "type": "string", + "description": "Set this option to log timing information. The value of the option will be logged along with the timimg, so that you can distinguish multiple dygraphs on the same page." + }, + "showRangeSelector": { + "default": "false", + "labels": ["Range Selector"], + "type": "boolean", + "description": "Show or hide the range selector widget." + }, + "rangeSelectorHeight": { + "default": "40", + "labels": ["Range Selector"], + "type": "integer", + "description": "Height, in pixels, of the range selector widget. This option can only be specified at Dygraph creation time." + }, + "rangeSelectorPlotStrokeColor": { + "default": "#808FAB", + "labels": ["Range Selector"], + "type": "string", + "description": "The range selector mini plot stroke color. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\". You can also specify null or \"\" to turn off stroke." + }, + "rangeSelectorPlotFillColor": { + "default": "#A7B1C4", + "labels": ["Range Selector"], + "type": "string", + "description": "The range selector mini plot fill color. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\". You can also specify null or \"\" to turn off fill." + }, + "rangeSelectorPlotFillGradientColor": { + "default": "white", + "labels": ["Range Selector"], + "type": "string", + "description": "The top color for the range selector mini plot fill color gradient. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"rgba(255,100,200,42)\" or \"yellow\". You can also specify null or \"\" to disable the gradient and fill with one single color." + }, + "rangeSelectorBackgroundStrokeColor": { + "default": "gray", + "labels": ["Range Selector"], + "type": "string", + "description": "The color of the lines below and on both sides of the range selector mini plot. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\"." + }, + "rangeSelectorBackgroundLineWidth": { + "default": "1", + "labels": ["Range Selector"], + "type": "float", + "description": "The width of the lines below and on both sides of the range selector mini plot." + }, + "rangeSelectorPlotLineWidth": { + "default": "1.5", + "labels": ["Range Selector"], + "type": "float", + "description": "The width of the range selector mini plot line." + }, + "rangeSelectorForegroundStrokeColor": { + "default": "black", + "labels": ["Range Selector"], + "type": "string", + "description": "The color of the lines in the interactive layer of the range selector. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\"." + }, + "rangeSelectorForegroundLineWidth": { + "default": "1", + "labels": ["Range Selector"], + "type": "float", + "description": "The width the lines in the interactive layer of the range selector." + }, + "rangeSelectorAlpha": { + "default": "0.6", + "labels": ["Range Selector"], + "type": "float (0.0 - 1.0)", + "description": "The transparency of the veil that is drawn over the unselected portions of the range selector mini plot. A value of 0 represents full transparency and the unselected portions of the mini plot will appear as normal. A value of 1 represents full opacity and the unselected portions of the mini plot will be hidden." + }, + "showInRangeSelector": { + "default": "null", + "labels": ["Range Selector"], + "type": "boolean", + "description": "Mark this series for inclusion in the range selector. The mini plot curve will be an average of all such series. If this is not specified for any series, the default behavior is to average all the visible series. Setting it for one series will result in that series being charted alone in the range selector. Once it's set for a single series, it needs to be set for all series which should be included (regardless of visibility)." + }, + "animatedZooms": { + "default": "false", + "labels": ["Interactive Elements"], + "type": "boolean", + "description": "Set this option to animate the transition between zoom windows. Applies to programmatic and interactive zooms. Note that if you also set a drawCallback, it will be called several times on each zoom. If you set a zoomCallback, it will only be called after the animation is complete." + }, + "plotter": { + "default": "[DygraphCanvasRenderer.Plotters.fillPlotter, DygraphCanvasRenderer.Plotters.errorPlotter, DygraphCanvasRenderer.Plotters.linePlotter]", + "labels": ["Data Line display"], + "type": "array or function", + "description": "A function (or array of functions) which plot each data series on the chart. TODO(danvk): more details! May be set per-series." + }, + "axes": { + "default": "null", + "labels": ["Configuration"], + "type": "Object", + "description": "Defines per-axis options. Valid keys are 'x', 'y' and 'y2'. Only some options may be set on a per-axis basis. If an option may be set in this way, it will be noted on this page. See also documentation on per-series and per-axis options." + }, + "series": { + "default": "null", + "labels": ["Series"], + "type": "Object", + "description": "Defines per-series options. Its keys match the y-axis label names, and the values are dictionaries themselves that contain options specific to that series." + }, + "plugins": { + "default": "[]", + "labels": ["Configuration"], + "type": "Array", + "description": "Defines per-graph plugins. Useful for per-graph customization" + }, + "dataHandler": { + "default": "(depends on data)", + "labels": ["Data"], + "type": "Dygraph.DataHandler", + "description": "Custom DataHandler. This is an advanced customization. See http://bit.ly/151E7Aq." + } + }; //
+ // NOTE: in addition to parsing as JS, this snippet is expected to be valid + // JSON. This assumption cannot be checked in JS, but it will be checked when + // documentation is generated by the generate-documentation.py script. For the + // most part, this just means that you should always use double quotes. + + // Do a quick sanity check on the options reference. + var warn = function warn(msg) { + if (window.console) window.console.warn(msg); + }; + var flds = ['type', 'default', 'description']; + var valid_cats = ['Annotations', 'Axis display', 'Chart labels', 'CSV parsing', 'Callbacks', 'Data', 'Data Line display', 'Data Series Colors', 'Error Bars', 'Grid', 'Interactive Elements', 'Range Selector', 'Legend', 'Overall display', 'Rolling Averages', 'Series', 'Value display/formatting', 'Zooming', 'Debugging', 'Configuration', 'Deprecated']; + var i; + var cats = {}; + for (i = 0; i < valid_cats.length; i++) cats[valid_cats[i]] = true; + + for (var k in OPTIONS_REFERENCE) { + if (!OPTIONS_REFERENCE.hasOwnProperty(k)) continue; + var op = OPTIONS_REFERENCE[k]; + for (i = 0; i < flds.length; i++) { + if (!op.hasOwnProperty(flds[i])) { + warn('Option ' + k + ' missing "' + flds[i] + '" property'); + } else if (typeof op[flds[i]] != 'string') { + warn(k + '.' + flds[i] + ' must be of type string'); + } + } + var labels = op.labels; + if (typeof labels !== 'object') { + warn('Option "' + k + '" is missing a "labels": [...] option'); + } else { + for (i = 0; i < labels.length; i++) { + if (!cats.hasOwnProperty(labels[i])) { + warn('Option "' + k + '" has label "' + labels[i] + '", which is invalid.'); + } + } + } + } + } +} + +exports['default'] = OPTIONS_REFERENCE; +module.exports = exports['default']; + +}).call(this,require('_process')) + +},{"_process":1}],15:[function(require,module,exports){ +(function (process){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview DygraphOptions is responsible for parsing and returning + * information about options. + */ + +// TODO: remove this jshint directive & fix the warnings. +/*jshint sub:true */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +var _dygraphDefaultAttrs = require('./dygraph-default-attrs'); + +var _dygraphDefaultAttrs2 = _interopRequireDefault(_dygraphDefaultAttrs); + +var _dygraphOptionsReference = require('./dygraph-options-reference'); + +var _dygraphOptionsReference2 = _interopRequireDefault(_dygraphOptionsReference); + +/* + * Interesting member variables: (REMOVING THIS LIST AS I CLOSURIZE) + * global_ - global attributes (common among all graphs, AIUI) + * user - attributes set by the user + * series_ - { seriesName -> { idx, yAxis, options }} + */ + +/** + * This parses attributes into an object that can be easily queried. + * + * It doesn't necessarily mean that all options are available, specifically + * if labels are not yet available, since those drive details of the per-series + * and per-axis options. + * + * @param {Dygraph} dygraph The chart to which these options belong. + * @constructor + */ +var DygraphOptions = function DygraphOptions(dygraph) { + /** + * The dygraph. + * @type {!Dygraph} + */ + this.dygraph_ = dygraph; + + /** + * Array of axis index to { series : [ series names ] , options : { axis-specific options. } + * @type {Array.<{series : Array., options : Object}>} @private + */ + this.yAxes_ = []; + + /** + * Contains x-axis specific options, which are stored in the options key. + * This matches the yAxes_ object structure (by being a dictionary with an + * options element) allowing for shared code. + * @type {options: Object} @private + */ + this.xAxis_ = {}; + this.series_ = {}; + + // Once these two objects are initialized, you can call get(); + this.global_ = this.dygraph_.attrs_; + this.user_ = this.dygraph_.user_attrs_ || {}; + + /** + * A list of series in columnar order. + * @type {Array.} + */ + this.labels_ = []; + + this.highlightSeries_ = this.get("highlightSeriesOpts") || {}; + this.reparseSeries(); +}; + +/** + * Not optimal, but does the trick when you're only using two axes. + * If we move to more axes, this can just become a function. + * + * @type {Object.} + * @private + */ +DygraphOptions.AXIS_STRING_MAPPINGS_ = { + 'y': 0, + 'Y': 0, + 'y1': 0, + 'Y1': 0, + 'y2': 1, + 'Y2': 1 +}; + +/** + * @param {string|number} axis + * @private + */ +DygraphOptions.axisToIndex_ = function (axis) { + if (typeof axis == "string") { + if (DygraphOptions.AXIS_STRING_MAPPINGS_.hasOwnProperty(axis)) { + return DygraphOptions.AXIS_STRING_MAPPINGS_[axis]; + } + throw "Unknown axis : " + axis; + } + if (typeof axis == "number") { + if (axis === 0 || axis === 1) { + return axis; + } + throw "Dygraphs only supports two y-axes, indexed from 0-1."; + } + if (axis) { + throw "Unknown axis : " + axis; + } + // No axis specification means axis 0. + return 0; +}; + +/** + * Reparses options that are all related to series. This typically occurs when + * options are either updated, or source data has been made available. + * + * TODO(konigsberg): The method name is kind of weak; fix. + */ +DygraphOptions.prototype.reparseSeries = function () { + var labels = this.get("labels"); + if (!labels) { + return; // -- can't do more for now, will parse after getting the labels. + } + + this.labels_ = labels.slice(1); + + this.yAxes_ = [{ series: [], options: {} }]; // Always one axis at least. + this.xAxis_ = { options: {} }; + this.series_ = {}; + + // Series are specified in the series element: + // + // { + // labels: [ "X", "foo", "bar" ], + // pointSize: 3, + // series : { + // foo : {}, // options for foo + // bar : {} // options for bar + // } + // } + // + // So, if series is found, it's expected to contain per-series data, otherwise set a + // default. + var seriesDict = this.user_.series || {}; + for (var idx = 0; idx < this.labels_.length; idx++) { + var seriesName = this.labels_[idx]; + var optionsForSeries = seriesDict[seriesName] || {}; + var yAxis = DygraphOptions.axisToIndex_(optionsForSeries["axis"]); + + this.series_[seriesName] = { + idx: idx, + yAxis: yAxis, + options: optionsForSeries }; + + if (!this.yAxes_[yAxis]) { + this.yAxes_[yAxis] = { series: [seriesName], options: {} }; + } else { + this.yAxes_[yAxis].series.push(seriesName); + } + } + + var axis_opts = this.user_["axes"] || {}; + utils.update(this.yAxes_[0].options, axis_opts["y"] || {}); + if (this.yAxes_.length > 1) { + utils.update(this.yAxes_[1].options, axis_opts["y2"] || {}); + } + utils.update(this.xAxis_.options, axis_opts["x"] || {}); + + // For "production" code, this gets removed by uglifyjs. + if (typeof process !== 'undefined') { + if ("development" != 'production') { + this.validateOptions_(); + } + } +}; + +/** + * Get a global value. + * + * @param {string} name the name of the option. + */ +DygraphOptions.prototype.get = function (name) { + var result = this.getGlobalUser_(name); + if (result !== null) { + return result; + } + return this.getGlobalDefault_(name); +}; + +DygraphOptions.prototype.getGlobalUser_ = function (name) { + if (this.user_.hasOwnProperty(name)) { + return this.user_[name]; + } + return null; +}; + +DygraphOptions.prototype.getGlobalDefault_ = function (name) { + if (this.global_.hasOwnProperty(name)) { + return this.global_[name]; + } + if (_dygraphDefaultAttrs2['default'].hasOwnProperty(name)) { + return _dygraphDefaultAttrs2['default'][name]; + } + return null; +}; + +/** + * Get a value for a specific axis. If there is no specific value for the axis, + * the global value is returned. + * + * @param {string} name the name of the option. + * @param {string|number} axis the axis to search. Can be the string representation + * ("y", "y2") or the axis number (0, 1). + */ +DygraphOptions.prototype.getForAxis = function (name, axis) { + var axisIdx; + var axisString; + + // Since axis can be a number or a string, straighten everything out here. + if (typeof axis == 'number') { + axisIdx = axis; + axisString = axisIdx === 0 ? "y" : "y2"; + } else { + if (axis == "y1") { + axis = "y"; + } // Standardize on 'y'. Is this bad? I think so. + if (axis == "y") { + axisIdx = 0; + } else if (axis == "y2") { + axisIdx = 1; + } else if (axis == "x") { + axisIdx = -1; // simply a placeholder for below. + } else { + throw "Unknown axis " + axis; + } + axisString = axis; + } + + var userAxis = axisIdx == -1 ? this.xAxis_ : this.yAxes_[axisIdx]; + + // Search the user-specified axis option first. + if (userAxis) { + // This condition could be removed if we always set up this.yAxes_ for y2. + var axisOptions = userAxis.options; + if (axisOptions.hasOwnProperty(name)) { + return axisOptions[name]; + } + } + + // User-specified global options second. + // But, hack, ignore globally-specified 'logscale' for 'x' axis declaration. + if (!(axis === 'x' && name === 'logscale')) { + var result = this.getGlobalUser_(name); + if (result !== null) { + return result; + } + } + // Default axis options third. + var defaultAxisOptions = _dygraphDefaultAttrs2['default'].axes[axisString]; + if (defaultAxisOptions.hasOwnProperty(name)) { + return defaultAxisOptions[name]; + } + + // Default global options last. + return this.getGlobalDefault_(name); +}; + +/** + * Get a value for a specific series. If there is no specific value for the series, + * the value for the axis is returned (and afterwards, the global value.) + * + * @param {string} name the name of the option. + * @param {string} series the series to search. + */ +DygraphOptions.prototype.getForSeries = function (name, series) { + // Honors indexes as series. + if (series === this.dygraph_.getHighlightSeries()) { + if (this.highlightSeries_.hasOwnProperty(name)) { + return this.highlightSeries_[name]; + } + } + + if (!this.series_.hasOwnProperty(series)) { + throw "Unknown series: " + series; + } + + var seriesObj = this.series_[series]; + var seriesOptions = seriesObj["options"]; + if (seriesOptions.hasOwnProperty(name)) { + return seriesOptions[name]; + } + + return this.getForAxis(name, seriesObj["yAxis"]); +}; + +/** + * Returns the number of y-axes on the chart. + * @return {number} the number of axes. + */ +DygraphOptions.prototype.numAxes = function () { + return this.yAxes_.length; +}; + +/** + * Return the y-axis for a given series, specified by name. + */ +DygraphOptions.prototype.axisForSeries = function (series) { + return this.series_[series].yAxis; +}; + +/** + * Returns the options for the specified axis. + */ +// TODO(konigsberg): this is y-axis specific. Support the x axis. +DygraphOptions.prototype.axisOptions = function (yAxis) { + return this.yAxes_[yAxis].options; +}; + +/** + * Return the series associated with an axis. + */ +DygraphOptions.prototype.seriesForAxis = function (yAxis) { + return this.yAxes_[yAxis].series; +}; + +/** + * Return the list of all series, in their columnar order. + */ +DygraphOptions.prototype.seriesNames = function () { + return this.labels_; +}; + +// For "production" code, this gets removed by uglifyjs. +if (typeof process !== 'undefined') { + if ("development" != 'production') { + + /** + * Validate all options. + * This requires OPTIONS_REFERENCE, which is only available in debug builds. + * @private + */ + DygraphOptions.prototype.validateOptions_ = function () { + if (typeof _dygraphOptionsReference2['default'] === 'undefined') { + throw 'Called validateOptions_ in prod build.'; + } + + var that = this; + var validateOption = function validateOption(optionName) { + if (!_dygraphOptionsReference2['default'][optionName]) { + that.warnInvalidOption_(optionName); + } + }; + + var optionsDicts = [this.xAxis_.options, this.yAxes_[0].options, this.yAxes_[1] && this.yAxes_[1].options, this.global_, this.user_, this.highlightSeries_]; + var names = this.seriesNames(); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + if (this.series_.hasOwnProperty(name)) { + optionsDicts.push(this.series_[name].options); + } + } + for (var i = 0; i < optionsDicts.length; i++) { + var dict = optionsDicts[i]; + if (!dict) continue; + for (var optionName in dict) { + if (dict.hasOwnProperty(optionName)) { + validateOption(optionName); + } + } + } + }; + + var WARNINGS = {}; // Only show any particular warning once. + + /** + * Logs a warning about invalid options. + * TODO: make this throw for testing + * @private + */ + DygraphOptions.prototype.warnInvalidOption_ = function (optionName) { + if (!WARNINGS[optionName]) { + WARNINGS[optionName] = true; + var isSeries = this.labels_.indexOf(optionName) >= 0; + if (isSeries) { + console.warn('Use new-style per-series options (saw ' + optionName + ' as top-level options key). See http://bit.ly/1tceaJs'); + } else { + console.warn('Unknown option ' + optionName + ' (full list of options at dygraphs.com/options.html'); + } + throw "invalid option " + optionName; + } + }; + + // Reset list of previously-shown warnings. Used for testing. + DygraphOptions.resetWarnings_ = function () { + WARNINGS = {}; + }; + } +} + +exports['default'] = DygraphOptions; +module.exports = exports['default']; + +}).call(this,require('_process')) + +},{"./dygraph-default-attrs":10,"./dygraph-options-reference":14,"./dygraph-utils":17,"_process":1}],16:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview Description of this file. + * @author danvk@google.com (Dan Vanderkam) + * + * A ticker is a function with the following interface: + * + * function(a, b, pixels, options_view, dygraph, forced_values); + * -> [ { v: tick1_v, label: tick1_label[, label_v: label_v1] }, + * { v: tick2_v, label: tick2_label[, label_v: label_v2] }, + * ... + * ] + * + * The returned value is called a "tick list". + * + * Arguments + * --------- + * + * [a, b] is the range of the axis for which ticks are being generated. For a + * numeric axis, these will simply be numbers. For a date axis, these will be + * millis since epoch (convertable to Date objects using "new Date(a)" and "new + * Date(b)"). + * + * opts provides access to chart- and axis-specific options. It can be used to + * access number/date formatting code/options, check for a log scale, etc. + * + * pixels is the length of the axis in pixels. opts('pixelsPerLabel') is the + * minimum amount of space to be allotted to each label. For instance, if + * pixels=400 and opts('pixelsPerLabel')=40 then the ticker should return + * between zero and ten (400/40) ticks. + * + * dygraph is the Dygraph object for which an axis is being constructed. + * + * forced_values is used for secondary y-axes. The tick positions are typically + * set by the primary y-axis, so the secondary y-axis has no choice in where to + * put these. It simply has to generate labels for these data values. + * + * Tick lists + * ---------- + * Typically a tick will have both a grid/tick line and a label at one end of + * that line (at the bottom for an x-axis, at left or right for the y-axis). + * + * A tick may be missing one of these two components: + * - If "label_v" is specified instead of "v", then there will be no tick or + * gridline, just a label. + * - Similarly, if "label" is not specified, then there will be a gridline + * without a label. + * + * This flexibility is useful in a few situations: + * - For log scales, some of the tick lines may be too close to all have labels. + * - For date scales where years are being displayed, it is desirable to display + * tick marks at the beginnings of years but labels (e.g. "2006") in the + * middle of the years. + */ + +/*jshint sub:true */ +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +/** @typedef {Array.<{v:number, label:string, label_v:(string|undefined)}>} */ +var TickList = undefined; // the ' = undefined' keeps jshint happy. + +/** @typedef {function( + * number, + * number, + * number, + * function(string):*, + * Dygraph=, + * Array.= + * ): TickList} + */ +var Ticker = undefined; // the ' = undefined' keeps jshint happy. + +/** @type {Ticker} */ +var numericLinearTicks = function numericLinearTicks(a, b, pixels, opts, dygraph, vals) { + var nonLogscaleOpts = function nonLogscaleOpts(opt) { + if (opt === 'logscale') return false; + return opts(opt); + }; + return numericTicks(a, b, pixels, nonLogscaleOpts, dygraph, vals); +}; + +exports.numericLinearTicks = numericLinearTicks; +/** @type {Ticker} */ +var numericTicks = function numericTicks(a, b, pixels, opts, dygraph, vals) { + var pixels_per_tick = /** @type{number} */opts('pixelsPerLabel'); + var ticks = []; + var i, j, tickV, nTicks; + if (vals) { + for (i = 0; i < vals.length; i++) { + ticks.push({ v: vals[i] }); + } + } else { + // TODO(danvk): factor this log-scale block out into a separate function. + if (opts("logscale")) { + nTicks = Math.floor(pixels / pixels_per_tick); + var minIdx = utils.binarySearch(a, PREFERRED_LOG_TICK_VALUES, 1); + var maxIdx = utils.binarySearch(b, PREFERRED_LOG_TICK_VALUES, -1); + if (minIdx == -1) { + minIdx = 0; + } + if (maxIdx == -1) { + maxIdx = PREFERRED_LOG_TICK_VALUES.length - 1; + } + // Count the number of tick values would appear, if we can get at least + // nTicks / 4 accept them. + var lastDisplayed = null; + if (maxIdx - minIdx >= nTicks / 4) { + for (var idx = maxIdx; idx >= minIdx; idx--) { + var tickValue = PREFERRED_LOG_TICK_VALUES[idx]; + var pixel_coord = Math.log(tickValue / a) / Math.log(b / a) * pixels; + var tick = { v: tickValue }; + if (lastDisplayed === null) { + lastDisplayed = { + tickValue: tickValue, + pixel_coord: pixel_coord + }; + } else { + if (Math.abs(pixel_coord - lastDisplayed.pixel_coord) >= pixels_per_tick) { + lastDisplayed = { + tickValue: tickValue, + pixel_coord: pixel_coord + }; + } else { + tick.label = ""; + } + } + ticks.push(tick); + } + // Since we went in backwards order. + ticks.reverse(); + } + } + + // ticks.length won't be 0 if the log scale function finds values to insert. + if (ticks.length === 0) { + // Basic idea: + // Try labels every 1, 2, 5, 10, 20, 50, 100, etc. + // Calculate the resulting tick spacing (i.e. this.height_ / nTicks). + // The first spacing greater than pixelsPerYLabel is what we use. + // TODO(danvk): version that works on a log scale. + var kmg2 = opts("labelsKMG2"); + var mults, base; + if (kmg2) { + mults = [1, 2, 4, 8, 16, 32, 64, 128, 256]; + base = 16; + } else { + mults = [1, 2, 5, 10, 20, 50, 100]; + base = 10; + } + + // Get the maximum number of permitted ticks based on the + // graph's pixel size and pixels_per_tick setting. + var max_ticks = Math.ceil(pixels / pixels_per_tick); + + // Now calculate the data unit equivalent of this tick spacing. + // Use abs() since graphs may have a reversed Y axis. + var units_per_tick = Math.abs(b - a) / max_ticks; + + // Based on this, get a starting scale which is the largest + // integer power of the chosen base (10 or 16) that still remains + // below the requested pixels_per_tick spacing. + var base_power = Math.floor(Math.log(units_per_tick) / Math.log(base)); + var base_scale = Math.pow(base, base_power); + + // Now try multiples of the starting scale until we find one + // that results in tick marks spaced sufficiently far apart. + // The "mults" array should cover the range 1 .. base^2 to + // adjust for rounding and edge effects. + var scale, low_val, high_val, spacing; + for (j = 0; j < mults.length; j++) { + scale = base_scale * mults[j]; + low_val = Math.floor(a / scale) * scale; + high_val = Math.ceil(b / scale) * scale; + nTicks = Math.abs(high_val - low_val) / scale; + spacing = pixels / nTicks; + if (spacing > pixels_per_tick) break; + } + + // Construct the set of ticks. + // Allow reverse y-axis if it's explicitly requested. + if (low_val > high_val) scale *= -1; + for (i = 0; i <= nTicks; i++) { + tickV = low_val + i * scale; + ticks.push({ v: tickV }); + } + } + } + + var formatter = /**@type{AxisLabelFormatter}*/opts('axisLabelFormatter'); + + // Add labels to the ticks. + for (i = 0; i < ticks.length; i++) { + if (ticks[i].label !== undefined) continue; // Use current label. + // TODO(danvk): set granularity to something appropriate here. + ticks[i].label = formatter.call(dygraph, ticks[i].v, 0, opts, dygraph); + } + + return ticks; +}; + +exports.numericTicks = numericTicks; +/** @type {Ticker} */ +var dateTicker = function dateTicker(a, b, pixels, opts, dygraph, vals) { + var chosen = pickDateTickGranularity(a, b, pixels, opts); + + if (chosen >= 0) { + return getDateAxis(a, b, chosen, opts, dygraph); + } else { + // this can happen if self.width_ is zero. + return []; + } +}; + +exports.dateTicker = dateTicker; +// Time granularity enumeration +var Granularity = { + SECONDLY: 0, + TWO_SECONDLY: 1, + FIVE_SECONDLY: 2, + TEN_SECONDLY: 3, + THIRTY_SECONDLY: 4, + MINUTELY: 5, + TWO_MINUTELY: 6, + FIVE_MINUTELY: 7, + TEN_MINUTELY: 8, + THIRTY_MINUTELY: 9, + HOURLY: 10, + TWO_HOURLY: 11, + SIX_HOURLY: 12, + DAILY: 13, + TWO_DAILY: 14, + WEEKLY: 15, + MONTHLY: 16, + QUARTERLY: 17, + BIANNUAL: 18, + ANNUAL: 19, + DECADAL: 20, + CENTENNIAL: 21, + NUM_GRANULARITIES: 22 +}; + +exports.Granularity = Granularity; +// Date components enumeration (in the order of the arguments in Date) +// TODO: make this an @enum +var DateField = { + DATEFIELD_Y: 0, + DATEFIELD_M: 1, + DATEFIELD_D: 2, + DATEFIELD_HH: 3, + DATEFIELD_MM: 4, + DATEFIELD_SS: 5, + DATEFIELD_MS: 6, + NUM_DATEFIELDS: 7 +}; + +/** + * The value of datefield will start at an even multiple of "step", i.e. + * if datefield=SS and step=5 then the first tick will be on a multiple of 5s. + * + * For granularities <= HOURLY, ticks are generated every `spacing` ms. + * + * At coarser granularities, ticks are generated by incrementing `datefield` by + * `step`. In this case, the `spacing` value is only used to estimate the + * number of ticks. It should roughly correspond to the spacing between + * adjacent ticks. + * + * @type {Array.<{datefield:number, step:number, spacing:number}>} + */ +var TICK_PLACEMENT = []; +TICK_PLACEMENT[Granularity.SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 1, spacing: 1000 * 1 }; +TICK_PLACEMENT[Granularity.TWO_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 2, spacing: 1000 * 2 }; +TICK_PLACEMENT[Granularity.FIVE_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 5, spacing: 1000 * 5 }; +TICK_PLACEMENT[Granularity.TEN_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 10, spacing: 1000 * 10 }; +TICK_PLACEMENT[Granularity.THIRTY_SECONDLY] = { datefield: DateField.DATEFIELD_SS, step: 30, spacing: 1000 * 30 }; +TICK_PLACEMENT[Granularity.MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 1, spacing: 1000 * 60 }; +TICK_PLACEMENT[Granularity.TWO_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 2, spacing: 1000 * 60 * 2 }; +TICK_PLACEMENT[Granularity.FIVE_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 5, spacing: 1000 * 60 * 5 }; +TICK_PLACEMENT[Granularity.TEN_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 10, spacing: 1000 * 60 * 10 }; +TICK_PLACEMENT[Granularity.THIRTY_MINUTELY] = { datefield: DateField.DATEFIELD_MM, step: 30, spacing: 1000 * 60 * 30 }; +TICK_PLACEMENT[Granularity.HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 1, spacing: 1000 * 3600 }; +TICK_PLACEMENT[Granularity.TWO_HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 2, spacing: 1000 * 3600 * 2 }; +TICK_PLACEMENT[Granularity.SIX_HOURLY] = { datefield: DateField.DATEFIELD_HH, step: 6, spacing: 1000 * 3600 * 6 }; +TICK_PLACEMENT[Granularity.DAILY] = { datefield: DateField.DATEFIELD_D, step: 1, spacing: 1000 * 86400 }; +TICK_PLACEMENT[Granularity.TWO_DAILY] = { datefield: DateField.DATEFIELD_D, step: 2, spacing: 1000 * 86400 * 2 }; +TICK_PLACEMENT[Granularity.WEEKLY] = { datefield: DateField.DATEFIELD_D, step: 7, spacing: 1000 * 604800 }; +TICK_PLACEMENT[Granularity.MONTHLY] = { datefield: DateField.DATEFIELD_M, step: 1, spacing: 1000 * 7200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 12 +TICK_PLACEMENT[Granularity.QUARTERLY] = { datefield: DateField.DATEFIELD_M, step: 3, spacing: 1000 * 21600 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 4 +TICK_PLACEMENT[Granularity.BIANNUAL] = { datefield: DateField.DATEFIELD_M, step: 6, spacing: 1000 * 43200 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 / 2 +TICK_PLACEMENT[Granularity.ANNUAL] = { datefield: DateField.DATEFIELD_Y, step: 1, spacing: 1000 * 86400 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 1 +TICK_PLACEMENT[Granularity.DECADAL] = { datefield: DateField.DATEFIELD_Y, step: 10, spacing: 1000 * 864000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 10 +TICK_PLACEMENT[Granularity.CENTENNIAL] = { datefield: DateField.DATEFIELD_Y, step: 100, spacing: 1000 * 8640000 * 365.2524 }; // 1e3 * 60 * 60 * 24 * 365.2524 * 100 + +/** + * This is a list of human-friendly values at which to show tick marks on a log + * scale. It is k * 10^n, where k=1..9 and n=-39..+39, so: + * ..., 1, 2, 3, 4, 5, ..., 9, 10, 20, 30, ..., 90, 100, 200, 300, ... + * NOTE: this assumes that utils.LOG_SCALE = 10. + * @type {Array.} + */ +var PREFERRED_LOG_TICK_VALUES = (function () { + var vals = []; + for (var power = -39; power <= 39; power++) { + var range = Math.pow(10, power); + for (var mult = 1; mult <= 9; mult++) { + var val = range * mult; + vals.push(val); + } + } + return vals; +})(); + +/** + * Determine the correct granularity of ticks on a date axis. + * + * @param {number} a Left edge of the chart (ms) + * @param {number} b Right edge of the chart (ms) + * @param {number} pixels Size of the chart in the relevant dimension (width). + * @param {function(string):*} opts Function mapping from option name -> value. + * @return {number} The appropriate axis granularity for this chart. See the + * enumeration of possible values in dygraph-tickers.js. + */ +var pickDateTickGranularity = function pickDateTickGranularity(a, b, pixels, opts) { + var pixels_per_tick = /** @type{number} */opts('pixelsPerLabel'); + for (var i = 0; i < Granularity.NUM_GRANULARITIES; i++) { + var num_ticks = numDateTicks(a, b, i); + if (pixels / num_ticks >= pixels_per_tick) { + return i; + } + } + return -1; +}; + +/** + * Compute the number of ticks on a date axis for a given granularity. + * @param {number} start_time + * @param {number} end_time + * @param {number} granularity (one of the granularities enumerated above) + * @return {number} (Approximate) number of ticks that would result. + */ +var numDateTicks = function numDateTicks(start_time, end_time, granularity) { + var spacing = TICK_PLACEMENT[granularity].spacing; + return Math.round(1.0 * (end_time - start_time) / spacing); +}; + +/** + * Compute the positions and labels of ticks on a date axis for a given granularity. + * @param {number} start_time + * @param {number} end_time + * @param {number} granularity (one of the granularities enumerated above) + * @param {function(string):*} opts Function mapping from option name -> value. + * @param {Dygraph=} dg + * @return {!TickList} + */ +var getDateAxis = function getDateAxis(start_time, end_time, granularity, opts, dg) { + var formatter = /** @type{AxisLabelFormatter} */opts("axisLabelFormatter"); + var utc = opts("labelsUTC"); + var accessors = utc ? utils.DateAccessorsUTC : utils.DateAccessorsLocal; + + var datefield = TICK_PLACEMENT[granularity].datefield; + var step = TICK_PLACEMENT[granularity].step; + var spacing = TICK_PLACEMENT[granularity].spacing; + + // Choose a nice tick position before the initial instant. + // Currently, this code deals properly with the existent daily granularities: + // DAILY (with step of 1) and WEEKLY (with step of 7 but specially handled). + // Other daily granularities (say TWO_DAILY) should also be handled specially + // by setting the start_date_offset to 0. + var start_date = new Date(start_time); + var date_array = []; + date_array[DateField.DATEFIELD_Y] = accessors.getFullYear(start_date); + date_array[DateField.DATEFIELD_M] = accessors.getMonth(start_date); + date_array[DateField.DATEFIELD_D] = accessors.getDate(start_date); + date_array[DateField.DATEFIELD_HH] = accessors.getHours(start_date); + date_array[DateField.DATEFIELD_MM] = accessors.getMinutes(start_date); + date_array[DateField.DATEFIELD_SS] = accessors.getSeconds(start_date); + date_array[DateField.DATEFIELD_MS] = accessors.getMilliseconds(start_date); + + var start_date_offset = date_array[datefield] % step; + if (granularity == Granularity.WEEKLY) { + // This will put the ticks on Sundays. + start_date_offset = accessors.getDay(start_date); + } + + date_array[datefield] -= start_date_offset; + for (var df = datefield + 1; df < DateField.NUM_DATEFIELDS; df++) { + // The minimum value is 1 for the day of month, and 0 for all other fields. + date_array[df] = df === DateField.DATEFIELD_D ? 1 : 0; + } + + // Generate the ticks. + // For granularities not coarser than HOURLY we use the fact that: + // the number of milliseconds between ticks is constant + // and equal to the defined spacing. + // Otherwise we rely on the 'roll over' property of the Date functions: + // when some date field is set to a value outside of its logical range, + // the excess 'rolls over' the next (more significant) field. + // However, when using local time with DST transitions, + // there are dates that do not represent any time value at all + // (those in the hour skipped at the 'spring forward'), + // and the JavaScript engines usually return an equivalent value. + // Hence we have to check that the date is properly increased at each step, + // returning a date at a nice tick position. + var ticks = []; + var tick_date = accessors.makeDate.apply(null, date_array); + var tick_time = tick_date.getTime(); + if (granularity <= Granularity.HOURLY) { + if (tick_time < start_time) { + tick_time += spacing; + tick_date = new Date(tick_time); + } + while (tick_time <= end_time) { + ticks.push({ v: tick_time, + label: formatter.call(dg, tick_date, granularity, opts, dg) + }); + tick_time += spacing; + tick_date = new Date(tick_time); + } + } else { + if (tick_time < start_time) { + date_array[datefield] += step; + tick_date = accessors.makeDate.apply(null, date_array); + tick_time = tick_date.getTime(); + } + while (tick_time <= end_time) { + if (granularity >= Granularity.DAILY || accessors.getHours(tick_date) % step === 0) { + ticks.push({ v: tick_time, + label: formatter.call(dg, tick_date, granularity, opts, dg) + }); + } + date_array[datefield] += step; + tick_date = accessors.makeDate.apply(null, date_array); + tick_time = tick_date.getTime(); + } + } + return ticks; +}; +exports.getDateAxis = getDateAxis; + +},{"./dygraph-utils":17}],17:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/** + * @fileoverview This file contains utility functions used by dygraphs. These + * are typically static (i.e. not related to any particular dygraph). Examples + * include date/time formatting functions, basic algorithms (e.g. binary + * search) and generic DOM-manipulation functions. + */ + +/*global Dygraph:false, Node:false */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.removeEvent = removeEvent; +exports.cancelEvent = cancelEvent; +exports.hsvToRGB = hsvToRGB; +exports.findPos = findPos; +exports.pageX = pageX; +exports.pageY = pageY; +exports.dragGetX_ = dragGetX_; +exports.dragGetY_ = dragGetY_; +exports.isOK = isOK; +exports.isValidPoint = isValidPoint; +exports.floatFormat = floatFormat; +exports.zeropad = zeropad; +exports.hmsString_ = hmsString_; +exports.dateString_ = dateString_; +exports.round_ = round_; +exports.binarySearch = binarySearch; +exports.dateParser = dateParser; +exports.dateStrToMillis = dateStrToMillis; +exports.update = update; +exports.updateDeep = updateDeep; +exports.isArrayLike = isArrayLike; +exports.isDateLike = isDateLike; +exports.clone = clone; +exports.createCanvas = createCanvas; +exports.getContextPixelRatio = getContextPixelRatio; +exports.Iterator = Iterator; +exports.createIterator = createIterator; +exports.repeatAndCleanup = repeatAndCleanup; +exports.isPixelChangingOptionList = isPixelChangingOptionList; +exports.detectLineDelimiter = detectLineDelimiter; +exports.isNodeContainedBy = isNodeContainedBy; +exports.pow = pow; +exports.toRGB_ = toRGB_; +exports.isCanvasSupported = isCanvasSupported; +exports.parseFloat_ = parseFloat_; +exports.numberValueFormatter = numberValueFormatter; +exports.numberAxisLabelFormatter = numberAxisLabelFormatter; +exports.dateAxisLabelFormatter = dateAxisLabelFormatter; +exports.dateValueFormatter = dateValueFormatter; + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } + +var _dygraphTickers = require('./dygraph-tickers'); + +var DygraphTickers = _interopRequireWildcard(_dygraphTickers); + +var LOG_SCALE = 10; +exports.LOG_SCALE = LOG_SCALE; +var LN_TEN = Math.log(LOG_SCALE); + +exports.LN_TEN = LN_TEN; +/** + * @private + * @param {number} x + * @return {number} + */ +var log10 = function log10(x) { + return Math.log(x) / LN_TEN; +}; + +exports.log10 = log10; +/** + * @private + * @param {number} r0 + * @param {number} r1 + * @param {number} pct + * @return {number} + */ +var logRangeFraction = function logRangeFraction(r0, r1, pct) { + // Computing the inverse of toPercentXCoord. The function was arrived at with + // the following steps: + // + // Original calcuation: + // pct = (log(x) - log(xRange[0])) / (log(xRange[1]) - log(xRange[0]))); + // + // Multiply both sides by the right-side demoninator. + // pct * (log(xRange[1] - log(xRange[0]))) = log(x) - log(xRange[0]) + // + // add log(xRange[0]) to both sides + // log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) = log(x); + // + // Swap both sides of the equation, + // log(x) = log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) + // + // Use both sides as the exponent in 10^exp and we're done. + // x = 10 ^ (log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0]))) + + var logr0 = log10(r0); + var logr1 = log10(r1); + var exponent = logr0 + pct * (logr1 - logr0); + var value = Math.pow(LOG_SCALE, exponent); + return value; +}; + +exports.logRangeFraction = logRangeFraction; +/** A dotted line stroke pattern. */ +var DOTTED_LINE = [2, 2]; +exports.DOTTED_LINE = DOTTED_LINE; +/** A dashed line stroke pattern. */ +var DASHED_LINE = [7, 3]; +exports.DASHED_LINE = DASHED_LINE; +/** A dot dash stroke pattern. */ +var DOT_DASH_LINE = [7, 2, 2, 2]; + +exports.DOT_DASH_LINE = DOT_DASH_LINE; +// Directions for panning and zooming. Use bit operations when combined +// values are possible. +var HORIZONTAL = 1; +exports.HORIZONTAL = HORIZONTAL; +var VERTICAL = 2; + +exports.VERTICAL = VERTICAL; +/** + * Return the 2d context for a dygraph canvas. + * + * This method is only exposed for the sake of replacing the function in + * automated tests. + * + * @param {!HTMLCanvasElement} canvas + * @return {!CanvasRenderingContext2D} + * @private + */ +var getContext = function getContext(canvas) { + return (/** @type{!CanvasRenderingContext2D}*/canvas.getContext("2d") + ); +}; + +exports.getContext = getContext; +/** + * Add an event handler. + * @param {!Node} elem The element to add the event to. + * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. + * @param {function(Event):(boolean|undefined)} fn The function to call + * on the event. The function takes one parameter: the event object. + * @private + */ +var addEvent = function addEvent(elem, type, fn) { + elem.addEventListener(type, fn, false); +}; + +exports.addEvent = addEvent; +/** + * Remove an event handler. + * @param {!Node} elem The element to remove the event from. + * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. + * @param {function(Event):(boolean|undefined)} fn The function to call + * on the event. The function takes one parameter: the event object. + */ + +function removeEvent(elem, type, fn) { + elem.removeEventListener(type, fn, false); +} + +; + +/** + * Cancels further processing of an event. This is useful to prevent default + * browser actions, e.g. highlighting text on a double-click. + * Based on the article at + * http://www.switchonthecode.com/tutorials/javascript-tutorial-the-scroll-wheel + * @param {!Event} e The event whose normal behavior should be canceled. + * @private + */ + +function cancelEvent(e) { + e = e ? e : window.event; + if (e.stopPropagation) { + e.stopPropagation(); + } + if (e.preventDefault) { + e.preventDefault(); + } + e.cancelBubble = true; + e.cancel = true; + e.returnValue = false; + return false; +} + +; + +/** + * Convert hsv values to an rgb(r,g,b) string. Taken from MochiKit.Color. This + * is used to generate default series colors which are evenly spaced on the + * color wheel. + * @param { number } hue Range is 0.0-1.0. + * @param { number } saturation Range is 0.0-1.0. + * @param { number } value Range is 0.0-1.0. + * @return { string } "rgb(r,g,b)" where r, g and b range from 0-255. + * @private + */ + +function hsvToRGB(hue, saturation, value) { + var red; + var green; + var blue; + if (saturation === 0) { + red = value; + green = value; + blue = value; + } else { + var i = Math.floor(hue * 6); + var f = hue * 6 - i; + var p = value * (1 - saturation); + var q = value * (1 - saturation * f); + var t = value * (1 - saturation * (1 - f)); + switch (i) { + case 1: + red = q;green = value;blue = p;break; + case 2: + red = p;green = value;blue = t;break; + case 3: + red = p;green = q;blue = value;break; + case 4: + red = t;green = p;blue = value;break; + case 5: + red = value;green = p;blue = q;break; + case 6: // fall through + case 0: + red = value;green = t;blue = p;break; + } + } + red = Math.floor(255 * red + 0.5); + green = Math.floor(255 * green + 0.5); + blue = Math.floor(255 * blue + 0.5); + return 'rgb(' + red + ',' + green + ',' + blue + ')'; +} + +; + +/** + * Find the coordinates of an object relative to the top left of the page. + * + * @param {Node} obj + * @return {{x:number,y:number}} + * @private + */ + +function findPos(obj) { + var p = obj.getBoundingClientRect(), + w = window, + d = document.documentElement; + + return { + x: p.left + (w.pageXOffset || d.scrollLeft), + y: p.top + (w.pageYOffset || d.scrollTop) + }; +} + +; + +/** + * Returns the x-coordinate of the event in a coordinate system where the + * top-left corner of the page (not the window) is (0,0). + * Taken from MochiKit.Signal + * @param {!Event} e + * @return {number} + * @private + */ + +function pageX(e) { + return !e.pageX || e.pageX < 0 ? 0 : e.pageX; +} + +; + +/** + * Returns the y-coordinate of the event in a coordinate system where the + * top-left corner of the page (not the window) is (0,0). + * Taken from MochiKit.Signal + * @param {!Event} e + * @return {number} + * @private + */ + +function pageY(e) { + return !e.pageY || e.pageY < 0 ? 0 : e.pageY; +} + +; + +/** + * Converts page the x-coordinate of the event to pixel x-coordinates on the + * canvas (i.e. DOM Coords). + * @param {!Event} e Drag event. + * @param {!DygraphInteractionContext} context Interaction context object. + * @return {number} The amount by which the drag has moved to the right. + */ + +function dragGetX_(e, context) { + return pageX(e) - context.px; +} + +; + +/** + * Converts page the y-coordinate of the event to pixel y-coordinates on the + * canvas (i.e. DOM Coords). + * @param {!Event} e Drag event. + * @param {!DygraphInteractionContext} context Interaction context object. + * @return {number} The amount by which the drag has moved down. + */ + +function dragGetY_(e, context) { + return pageY(e) - context.py; +} + +; + +/** + * This returns true unless the parameter is 0, null, undefined or NaN. + * TODO(danvk): rename this function to something like 'isNonZeroNan'. + * + * @param {number} x The number to consider. + * @return {boolean} Whether the number is zero or NaN. + * @private + */ + +function isOK(x) { + return !!x && !isNaN(x); +} + +; + +/** + * @param {{x:?number,y:?number,yval:?number}} p The point to consider, valid + * points are {x, y} objects + * @param {boolean=} opt_allowNaNY Treat point with y=NaN as valid + * @return {boolean} Whether the point has numeric x and y. + * @private + */ + +function isValidPoint(p, opt_allowNaNY) { + if (!p) return false; // null or undefined object + if (p.yval === null) return false; // missing point + if (p.x === null || p.x === undefined) return false; + if (p.y === null || p.y === undefined) return false; + if (isNaN(p.x) || !opt_allowNaNY && isNaN(p.y)) return false; + return true; +} + +; + +/** + * Number formatting function which mimicks the behavior of %g in printf, i.e. + * either exponential or fixed format (without trailing 0s) is used depending on + * the length of the generated string. The advantage of this format is that + * there is a predictable upper bound on the resulting string length, + * significant figures are not dropped, and normal numbers are not displayed in + * exponential notation. + * + * NOTE: JavaScript's native toPrecision() is NOT a drop-in replacement for %g. + * It creates strings which are too long for absolute values between 10^-4 and + * 10^-6, e.g. '0.00001' instead of '1e-5'. See tests/number-format.html for + * output examples. + * + * @param {number} x The number to format + * @param {number=} opt_precision The precision to use, default 2. + * @return {string} A string formatted like %g in printf. The max generated + * string length should be precision + 6 (e.g 1.123e+300). + */ + +function floatFormat(x, opt_precision) { + // Avoid invalid precision values; [1, 21] is the valid range. + var p = Math.min(Math.max(1, opt_precision || 2), 21); + + // This is deceptively simple. The actual algorithm comes from: + // + // Max allowed length = p + 4 + // where 4 comes from 'e+n' and '.'. + // + // Length of fixed format = 2 + y + p + // where 2 comes from '0.' and y = # of leading zeroes. + // + // Equating the two and solving for y yields y = 2, or 0.00xxxx which is + // 1.0e-3. + // + // Since the behavior of toPrecision() is identical for larger numbers, we + // don't have to worry about the other bound. + // + // Finally, the argument for toExponential() is the number of trailing digits, + // so we take off 1 for the value before the '.'. + return Math.abs(x) < 1.0e-3 && x !== 0.0 ? x.toExponential(p - 1) : x.toPrecision(p); +} + +; + +/** + * Converts '9' to '09' (useful for dates) + * @param {number} x + * @return {string} + * @private + */ + +function zeropad(x) { + if (x < 10) return "0" + x;else return "" + x; +} + +; + +/** + * Date accessors to get the parts of a calendar date (year, month, + * day, hour, minute, second and millisecond) according to local time, + * and factory method to call the Date constructor with an array of arguments. + */ +var DateAccessorsLocal = { + getFullYear: function getFullYear(d) { + return d.getFullYear(); + }, + getMonth: function getMonth(d) { + return d.getMonth(); + }, + getDate: function getDate(d) { + return d.getDate(); + }, + getHours: function getHours(d) { + return d.getHours(); + }, + getMinutes: function getMinutes(d) { + return d.getMinutes(); + }, + getSeconds: function getSeconds(d) { + return d.getSeconds(); + }, + getMilliseconds: function getMilliseconds(d) { + return d.getMilliseconds(); + }, + getDay: function getDay(d) { + return d.getDay(); + }, + makeDate: function makeDate(y, m, d, hh, mm, ss, ms) { + return new Date(y, m, d, hh, mm, ss, ms); + } +}; + +exports.DateAccessorsLocal = DateAccessorsLocal; +/** + * Date accessors to get the parts of a calendar date (year, month, + * day of month, hour, minute, second and millisecond) according to UTC time, + * and factory method to call the Date constructor with an array of arguments. + */ +var DateAccessorsUTC = { + getFullYear: function getFullYear(d) { + return d.getUTCFullYear(); + }, + getMonth: function getMonth(d) { + return d.getUTCMonth(); + }, + getDate: function getDate(d) { + return d.getUTCDate(); + }, + getHours: function getHours(d) { + return d.getUTCHours(); + }, + getMinutes: function getMinutes(d) { + return d.getUTCMinutes(); + }, + getSeconds: function getSeconds(d) { + return d.getUTCSeconds(); + }, + getMilliseconds: function getMilliseconds(d) { + return d.getUTCMilliseconds(); + }, + getDay: function getDay(d) { + return d.getUTCDay(); + }, + makeDate: function makeDate(y, m, d, hh, mm, ss, ms) { + return new Date(Date.UTC(y, m, d, hh, mm, ss, ms)); + } +}; + +exports.DateAccessorsUTC = DateAccessorsUTC; +/** + * Return a string version of the hours, minutes and seconds portion of a date. + * @param {number} hh The hours (from 0-23) + * @param {number} mm The minutes (from 0-59) + * @param {number} ss The seconds (from 0-59) + * @return {string} A time of the form "HH:MM" or "HH:MM:SS" + * @private + */ + +function hmsString_(hh, mm, ss, ms) { + var ret = zeropad(hh) + ":" + zeropad(mm); + if (ss) { + ret += ":" + zeropad(ss); + if (ms) { + var str = "" + ms; + ret += "." + ('000' + str).substring(str.length); + } + } + return ret; +} + +; + +/** + * Convert a JS date (millis since epoch) to a formatted string. + * @param {number} time The JavaScript time value (ms since epoch) + * @param {boolean} utc Wether output UTC or local time + * @return {string} A date of one of these forms: + * "YYYY/MM/DD", "YYYY/MM/DD HH:MM" or "YYYY/MM/DD HH:MM:SS" + * @private + */ + +function dateString_(time, utc) { + var accessors = utc ? DateAccessorsUTC : DateAccessorsLocal; + var date = new Date(time); + var y = accessors.getFullYear(date); + var m = accessors.getMonth(date); + var d = accessors.getDate(date); + var hh = accessors.getHours(date); + var mm = accessors.getMinutes(date); + var ss = accessors.getSeconds(date); + var ms = accessors.getMilliseconds(date); + // Get a year string: + var year = "" + y; + // Get a 0 padded month string + var month = zeropad(m + 1); //months are 0-offset, sigh + // Get a 0 padded day string + var day = zeropad(d); + var frac = hh * 3600 + mm * 60 + ss + 1e-3 * ms; + var ret = year + "/" + month + "/" + day; + if (frac) { + ret += " " + hmsString_(hh, mm, ss, ms); + } + return ret; +} + +; + +/** + * Round a number to the specified number of digits past the decimal point. + * @param {number} num The number to round + * @param {number} places The number of decimals to which to round + * @return {number} The rounded number + * @private + */ + +function round_(num, places) { + var shift = Math.pow(10, places); + return Math.round(num * shift) / shift; +} + +; + +/** + * Implementation of binary search over an array. + * Currently does not work when val is outside the range of arry's values. + * @param {number} val the value to search for + * @param {Array.} arry is the value over which to search + * @param {number} abs If abs > 0, find the lowest entry greater than val + * If abs < 0, find the highest entry less than val. + * If abs == 0, find the entry that equals val. + * @param {number=} low The first index in arry to consider (optional) + * @param {number=} high The last index in arry to consider (optional) + * @return {number} Index of the element, or -1 if it isn't found. + * @private + */ + +function binarySearch(_x, _x2, _x3, _x4, _x5) { + var _again = true; + + _function: while (_again) { + var val = _x, + arry = _x2, + abs = _x3, + low = _x4, + high = _x5; + _again = false; + + if (low === null || low === undefined || high === null || high === undefined) { + low = 0; + high = arry.length - 1; + } + if (low > high) { + return -1; + } + if (abs === null || abs === undefined) { + abs = 0; + } + var validIndex = function validIndex(idx) { + return idx >= 0 && idx < arry.length; + }; + var mid = parseInt((low + high) / 2, 10); + var element = arry[mid]; + var idx; + if (element == val) { + return mid; + } else if (element > val) { + if (abs > 0) { + // Accept if element > val, but also if prior element < val. + idx = mid - 1; + if (validIndex(idx) && arry[idx] < val) { + return mid; + } + } + _x = val; + _x2 = arry; + _x3 = abs; + _x4 = low; + _x5 = mid - 1; + _again = true; + validIndex = mid = element = idx = undefined; + continue _function; + } else if (element < val) { + if (abs < 0) { + // Accept if element < val, but also if prior element > val. + idx = mid + 1; + if (validIndex(idx) && arry[idx] > val) { + return mid; + } + } + _x = val; + _x2 = arry; + _x3 = abs; + _x4 = mid + 1; + _x5 = high; + _again = true; + validIndex = mid = element = idx = undefined; + continue _function; + } + return -1; // can't actually happen, but makes closure compiler happy + } +} + +; + +/** + * Parses a date, returning the number of milliseconds since epoch. This can be + * passed in as an xValueParser in the Dygraph constructor. + * TODO(danvk): enumerate formats that this understands. + * + * @param {string} dateStr A date in a variety of possible string formats. + * @return {number} Milliseconds since epoch. + * @private + */ + +function dateParser(dateStr) { + var dateStrSlashed; + var d; + + // Let the system try the format first, with one caveat: + // YYYY-MM-DD[ HH:MM:SS] is interpreted as UTC by a variety of browsers. + // dygraphs displays dates in local time, so this will result in surprising + // inconsistencies. But if you specify "T" or "Z" (i.e. YYYY-MM-DDTHH:MM:SS), + // then you probably know what you're doing, so we'll let you go ahead. + // Issue: http://code.google.com/p/dygraphs/issues/detail?id=255 + if (dateStr.search("-") == -1 || dateStr.search("T") != -1 || dateStr.search("Z") != -1) { + d = dateStrToMillis(dateStr); + if (d && !isNaN(d)) return d; + } + + if (dateStr.search("-") != -1) { + // e.g. '2009-7-12' or '2009-07-12' + dateStrSlashed = dateStr.replace("-", "/", "g"); + while (dateStrSlashed.search("-") != -1) { + dateStrSlashed = dateStrSlashed.replace("-", "/"); + } + d = dateStrToMillis(dateStrSlashed); + } else if (dateStr.length == 8) { + // e.g. '20090712' + // TODO(danvk): remove support for this format. It's confusing. + dateStrSlashed = dateStr.substr(0, 4) + "/" + dateStr.substr(4, 2) + "/" + dateStr.substr(6, 2); + d = dateStrToMillis(dateStrSlashed); + } else { + // Any format that Date.parse will accept, e.g. "2009/07/12" or + // "2009/07/12 12:34:56" + d = dateStrToMillis(dateStr); + } + + if (!d || isNaN(d)) { + console.error("Couldn't parse " + dateStr + " as a date"); + } + return d; +} + +; + +/** + * This is identical to JavaScript's built-in Date.parse() method, except that + * it doesn't get replaced with an incompatible method by aggressive JS + * libraries like MooTools or Joomla. + * @param {string} str The date string, e.g. "2011/05/06" + * @return {number} millis since epoch + * @private + */ + +function dateStrToMillis(str) { + return new Date(str).getTime(); +} + +; + +// These functions are all based on MochiKit. +/** + * Copies all the properties from o to self. + * + * @param {!Object} self + * @param {!Object} o + * @return {!Object} + */ + +function update(self, o) { + if (typeof o != 'undefined' && o !== null) { + for (var k in o) { + if (o.hasOwnProperty(k)) { + self[k] = o[k]; + } + } + } + return self; +} + +; + +/** + * Copies all the properties from o to self. + * + * @param {!Object} self + * @param {!Object} o + * @return {!Object} + * @private + */ + +function updateDeep(self, o) { + // Taken from http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-is-a-dom-object + function isNode(o) { + return typeof Node === "object" ? o instanceof Node : typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"; + } + + if (typeof o != 'undefined' && o !== null) { + for (var k in o) { + if (o.hasOwnProperty(k)) { + if (o[k] === null) { + self[k] = null; + } else if (isArrayLike(o[k])) { + self[k] = o[k].slice(); + } else if (isNode(o[k])) { + // DOM objects are shallowly-copied. + self[k] = o[k]; + } else if (typeof o[k] == 'object') { + if (typeof self[k] != 'object' || self[k] === null) { + self[k] = {}; + } + updateDeep(self[k], o[k]); + } else { + self[k] = o[k]; + } + } + } + } + return self; +} + +; + +/** + * @param {*} o + * @return {boolean} + * @private + */ + +function isArrayLike(o) { + var typ = typeof o; + if (typ != 'object' && !(typ == 'function' && typeof o.item == 'function') || o === null || typeof o.length != 'number' || o.nodeType === 3) { + return false; + } + return true; +} + +; + +/** + * @param {Object} o + * @return {boolean} + * @private + */ + +function isDateLike(o) { + if (typeof o != "object" || o === null || typeof o.getTime != 'function') { + return false; + } + return true; +} + +; + +/** + * Note: this only seems to work for arrays. + * @param {!Array} o + * @return {!Array} + * @private + */ + +function clone(o) { + // TODO(danvk): figure out how MochiKit's version works + var r = []; + for (var i = 0; i < o.length; i++) { + if (isArrayLike(o[i])) { + r.push(clone(o[i])); + } else { + r.push(o[i]); + } + } + return r; +} + +; + +/** + * Create a new canvas element. + * + * @return {!HTMLCanvasElement} + * @private + */ + +function createCanvas() { + return document.createElement('canvas'); +} + +; + +/** + * Returns the context's pixel ratio, which is the ratio between the device + * pixel ratio and the backing store ratio. Typically this is 1 for conventional + * displays, and > 1 for HiDPI displays (such as the Retina MBP). + * See http://www.html5rocks.com/en/tutorials/canvas/hidpi/ for more details. + * + * @param {!CanvasRenderingContext2D} context The canvas's 2d context. + * @return {number} The ratio of the device pixel ratio and the backing store + * ratio for the specified context. + */ + +function getContextPixelRatio(context) { + try { + var devicePixelRatio = window.devicePixelRatio; + var backingStoreRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; + if (devicePixelRatio !== undefined) { + return devicePixelRatio / backingStoreRatio; + } else { + // At least devicePixelRatio must be defined for this ratio to make sense. + // We default backingStoreRatio to 1: this does not exist on some browsers + // (i.e. desktop Chrome). + return 1; + } + } catch (e) { + return 1; + } +} + +; + +/** + * TODO(danvk): use @template here when it's better supported for classes. + * @param {!Array} array + * @param {number} start + * @param {number} length + * @param {function(!Array,?):boolean=} predicate + * @constructor + */ + +function Iterator(array, start, length, predicate) { + start = start || 0; + length = length || array.length; + this.hasNext = true; // Use to identify if there's another element. + this.peek = null; // Use for look-ahead + this.start_ = start; + this.array_ = array; + this.predicate_ = predicate; + this.end_ = Math.min(array.length, start + length); + this.nextIdx_ = start - 1; // use -1 so initial advance works. + this.next(); // ignoring result. +} + +; + +/** + * @return {Object} + */ +Iterator.prototype.next = function () { + if (!this.hasNext) { + return null; + } + var obj = this.peek; + + var nextIdx = this.nextIdx_ + 1; + var found = false; + while (nextIdx < this.end_) { + if (!this.predicate_ || this.predicate_(this.array_, nextIdx)) { + this.peek = this.array_[nextIdx]; + found = true; + break; + } + nextIdx++; + } + this.nextIdx_ = nextIdx; + if (!found) { + this.hasNext = false; + this.peek = null; + } + return obj; +}; + +/** + * Returns a new iterator over array, between indexes start and + * start + length, and only returns entries that pass the accept function + * + * @param {!Array} array the array to iterate over. + * @param {number} start the first index to iterate over, 0 if absent. + * @param {number} length the number of elements in the array to iterate over. + * This, along with start, defines a slice of the array, and so length + * doesn't imply the number of elements in the iterator when accept doesn't + * always accept all values. array.length when absent. + * @param {function(?):boolean=} opt_predicate a function that takes + * parameters array and idx, which returns true when the element should be + * returned. If omitted, all elements are accepted. + * @private + */ + +function createIterator(array, start, length, opt_predicate) { + return new Iterator(array, start, length, opt_predicate); +} + +; + +// Shim layer with setTimeout fallback. +// From: http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// Should be called with the window context: +// Dygraph.requestAnimFrame.call(window, function() {}) +var requestAnimFrame = (function () { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { + window.setTimeout(callback, 1000 / 60); + }; +})(); + +exports.requestAnimFrame = requestAnimFrame; +/** + * Call a function at most maxFrames times at an attempted interval of + * framePeriodInMillis, then call a cleanup function once. repeatFn is called + * once immediately, then at most (maxFrames - 1) times asynchronously. If + * maxFrames==1, then cleanup_fn() is also called synchronously. This function + * is used to sequence animation. + * @param {function(number)} repeatFn Called repeatedly -- takes the frame + * number (from 0 to maxFrames-1) as an argument. + * @param {number} maxFrames The max number of times to call repeatFn + * @param {number} framePeriodInMillis Max requested time between frames. + * @param {function()} cleanupFn A function to call after all repeatFn calls. + * @private + */ + +function repeatAndCleanup(repeatFn, maxFrames, framePeriodInMillis, cleanupFn) { + var frameNumber = 0; + var previousFrameNumber; + var startTime = new Date().getTime(); + repeatFn(frameNumber); + if (maxFrames == 1) { + cleanupFn(); + return; + } + var maxFrameArg = maxFrames - 1; + + (function loop() { + if (frameNumber >= maxFrames) return; + requestAnimFrame.call(window, function () { + // Determine which frame to draw based on the delay so far. Will skip + // frames if necessary. + var currentTime = new Date().getTime(); + var delayInMillis = currentTime - startTime; + previousFrameNumber = frameNumber; + frameNumber = Math.floor(delayInMillis / framePeriodInMillis); + var frameDelta = frameNumber - previousFrameNumber; + // If we predict that the subsequent repeatFn call will overshoot our + // total frame target, so our last call will cause a stutter, then jump to + // the last call immediately. If we're going to cause a stutter, better + // to do it faster than slower. + var predictOvershootStutter = frameNumber + frameDelta > maxFrameArg; + if (predictOvershootStutter || frameNumber >= maxFrameArg) { + repeatFn(maxFrameArg); // Ensure final call with maxFrameArg. + cleanupFn(); + } else { + if (frameDelta !== 0) { + // Don't call repeatFn with duplicate frames. + repeatFn(frameNumber); + } + loop(); + } + }); + })(); +} + +; + +// A whitelist of options that do not change pixel positions. +var pixelSafeOptions = { + 'annotationClickHandler': true, + 'annotationDblClickHandler': true, + 'annotationMouseOutHandler': true, + 'annotationMouseOverHandler': true, + 'axisLineColor': true, + 'axisLineWidth': true, + 'clickCallback': true, + 'drawCallback': true, + 'drawHighlightPointCallback': true, + 'drawPoints': true, + 'drawPointCallback': true, + 'drawGrid': true, + 'fillAlpha': true, + 'gridLineColor': true, + 'gridLineWidth': true, + 'hideOverlayOnMouseOut': true, + 'highlightCallback': true, + 'highlightCircleSize': true, + 'interactionModel': true, + 'labelsDiv': true, + 'labelsKMB': true, + 'labelsKMG2': true, + 'labelsSeparateLines': true, + 'labelsShowZeroValues': true, + 'legend': true, + 'panEdgeFraction': true, + 'pixelsPerYLabel': true, + 'pointClickCallback': true, + 'pointSize': true, + 'rangeSelectorPlotFillColor': true, + 'rangeSelectorPlotFillGradientColor': true, + 'rangeSelectorPlotStrokeColor': true, + 'rangeSelectorBackgroundStrokeColor': true, + 'rangeSelectorBackgroundLineWidth': true, + 'rangeSelectorPlotLineWidth': true, + 'rangeSelectorForegroundStrokeColor': true, + 'rangeSelectorForegroundLineWidth': true, + 'rangeSelectorAlpha': true, + 'showLabelsOnHighlight': true, + 'showRoller': true, + 'strokeWidth': true, + 'underlayCallback': true, + 'unhighlightCallback': true, + 'zoomCallback': true +}; + +/** + * This function will scan the option list and determine if they + * require us to recalculate the pixel positions of each point. + * TODO: move this into dygraph-options.js + * @param {!Array.} labels a list of options to check. + * @param {!Object} attrs + * @return {boolean} true if the graph needs new points else false. + * @private + */ + +function isPixelChangingOptionList(labels, attrs) { + // Assume that we do not require new points. + // This will change to true if we actually do need new points. + + // Create a dictionary of series names for faster lookup. + // If there are no labels, then the dictionary stays empty. + var seriesNamesDictionary = {}; + if (labels) { + for (var i = 1; i < labels.length; i++) { + seriesNamesDictionary[labels[i]] = true; + } + } + + // Scan through a flat (i.e. non-nested) object of options. + // Returns true/false depending on whether new points are needed. + var scanFlatOptions = function scanFlatOptions(options) { + for (var property in options) { + if (options.hasOwnProperty(property) && !pixelSafeOptions[property]) { + return true; + } + } + return false; + }; + + // Iterate through the list of updated options. + for (var property in attrs) { + if (!attrs.hasOwnProperty(property)) continue; + + // Find out of this field is actually a series specific options list. + if (property == 'highlightSeriesOpts' || seriesNamesDictionary[property] && !attrs.series) { + // This property value is a list of options for this series. + if (scanFlatOptions(attrs[property])) return true; + } else if (property == 'series' || property == 'axes') { + // This is twice-nested options list. + var perSeries = attrs[property]; + for (var series in perSeries) { + if (perSeries.hasOwnProperty(series) && scanFlatOptions(perSeries[series])) { + return true; + } + } + } else { + // If this was not a series specific option list, check if it's a pixel + // changing property. + if (!pixelSafeOptions[property]) return true; + } + } + + return false; +} + +; + +var Circles = { + DEFAULT: function DEFAULT(g, name, ctx, canvasx, canvasy, color, radius) { + ctx.beginPath(); + ctx.fillStyle = color; + ctx.arc(canvasx, canvasy, radius, 0, 2 * Math.PI, false); + ctx.fill(); + } + // For more shapes, include extras/shapes.js +}; + +exports.Circles = Circles; +/** + * Determine whether |data| is delimited by CR, CRLF, LF, LFCR. + * @param {string} data + * @return {?string} the delimiter that was detected (or null on failure). + */ + +function detectLineDelimiter(data) { + for (var i = 0; i < data.length; i++) { + var code = data.charAt(i); + if (code === '\r') { + // Might actually be "\r\n". + if (i + 1 < data.length && data.charAt(i + 1) === '\n') { + return '\r\n'; + } + return code; + } + if (code === '\n') { + // Might actually be "\n\r". + if (i + 1 < data.length && data.charAt(i + 1) === '\r') { + return '\n\r'; + } + return code; + } + } + + return null; +} + +; + +/** + * Is one node contained by another? + * @param {Node} containee The contained node. + * @param {Node} container The container node. + * @return {boolean} Whether containee is inside (or equal to) container. + * @private + */ + +function isNodeContainedBy(containee, container) { + if (container === null || containee === null) { + return false; + } + var containeeNode = /** @type {Node} */containee; + while (containeeNode && containeeNode !== container) { + containeeNode = containeeNode.parentNode; + } + return containeeNode === container; +} + +; + +// This masks some numeric issues in older versions of Firefox, +// where 1.0/Math.pow(10,2) != Math.pow(10,-2). +/** @type {function(number,number):number} */ + +function pow(base, exp) { + if (exp < 0) { + return 1.0 / Math.pow(base, -exp); + } + return Math.pow(base, exp); +} + +; + +var RGBA_RE = /^rgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})(?:,\s*([01](?:\.\d+)?))?\)$/; + +/** + * Helper for toRGB_ which parses strings of the form: + * rgb(123, 45, 67) + * rgba(123, 45, 67, 0.5) + * @return parsed {r,g,b,a?} tuple or null. + */ +function parseRGBA(rgbStr) { + var bits = RGBA_RE.exec(rgbStr); + if (!bits) return null; + var r = parseInt(bits[1], 10), + g = parseInt(bits[2], 10), + b = parseInt(bits[3], 10); + if (bits[4]) { + return { r: r, g: g, b: b, a: parseFloat(bits[4]) }; + } else { + return { r: r, g: g, b: b }; + } +} + +/** + * Converts any valid CSS color (hex, rgb(), named color) to an RGB tuple. + * + * @param {!string} colorStr Any valid CSS color string. + * @return {{r:number,g:number,b:number,a:number?}} Parsed RGB tuple. + * @private + */ + +function toRGB_(colorStr) { + // Strategy: First try to parse colorStr directly. This is fast & avoids DOM + // manipulation. If that fails (e.g. for named colors like 'red'), then + // create a hidden DOM element and parse its computed color. + var rgb = parseRGBA(colorStr); + if (rgb) return rgb; + + var div = document.createElement('div'); + div.style.backgroundColor = colorStr; + div.style.visibility = 'hidden'; + document.body.appendChild(div); + var rgbStr = window.getComputedStyle(div, null).backgroundColor; + document.body.removeChild(div); + return parseRGBA(rgbStr); +} + +; + +/** + * Checks whether the browser supports the <canvas> tag. + * @param {HTMLCanvasElement=} opt_canvasElement Pass a canvas element as an + * optimization if you have one. + * @return {boolean} Whether the browser supports canvas. + */ + +function isCanvasSupported(opt_canvasElement) { + try { + var canvas = opt_canvasElement || document.createElement("canvas"); + canvas.getContext("2d"); + } catch (e) { + return false; + } + return true; +} + +; + +/** + * Parses the value as a floating point number. This is like the parseFloat() + * built-in, but with a few differences: + * - the empty string is parsed as null, rather than NaN. + * - if the string cannot be parsed at all, an error is logged. + * If the string can't be parsed, this method returns null. + * @param {string} x The string to be parsed + * @param {number=} opt_line_no The line number from which the string comes. + * @param {string=} opt_line The text of the line from which the string comes. + */ + +function parseFloat_(x, opt_line_no, opt_line) { + var val = parseFloat(x); + if (!isNaN(val)) return val; + + // Try to figure out what happeend. + // If the value is the empty string, parse it as null. + if (/^ *$/.test(x)) return null; + + // If it was actually "NaN", return it as NaN. + if (/^ *nan *$/i.test(x)) return NaN; + + // Looks like a parsing error. + var msg = "Unable to parse '" + x + "' as a number"; + if (opt_line !== undefined && opt_line_no !== undefined) { + msg += " on line " + (1 + (opt_line_no || 0)) + " ('" + opt_line + "') of CSV."; + } + console.error(msg); + + return null; +} + +; + +// Label constants for the labelsKMB and labelsKMG2 options. +// (i.e. '100000' -> '100K') +var KMB_LABELS = ['K', 'M', 'B', 'T', 'Q']; +var KMG2_BIG_LABELS = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; +var KMG2_SMALL_LABELS = ['m', 'u', 'n', 'p', 'f', 'a', 'z', 'y']; + +/** + * @private + * Return a string version of a number. This respects the digitsAfterDecimal + * and maxNumberWidth options. + * @param {number} x The number to be formatted + * @param {Dygraph} opts An options view + */ + +function numberValueFormatter(x, opts) { + var sigFigs = opts('sigFigs'); + + if (sigFigs !== null) { + // User has opted for a fixed number of significant figures. + return floatFormat(x, sigFigs); + } + + var digits = opts('digitsAfterDecimal'); + var maxNumberWidth = opts('maxNumberWidth'); + + var kmb = opts('labelsKMB'); + var kmg2 = opts('labelsKMG2'); + + var label; + + // switch to scientific notation if we underflow or overflow fixed display. + if (x !== 0.0 && (Math.abs(x) >= Math.pow(10, maxNumberWidth) || Math.abs(x) < Math.pow(10, -digits))) { + label = x.toExponential(digits); + } else { + label = '' + round_(x, digits); + } + + if (kmb || kmg2) { + var k; + var k_labels = []; + var m_labels = []; + if (kmb) { + k = 1000; + k_labels = KMB_LABELS; + } + if (kmg2) { + if (kmb) console.warn("Setting both labelsKMB and labelsKMG2. Pick one!"); + k = 1024; + k_labels = KMG2_BIG_LABELS; + m_labels = KMG2_SMALL_LABELS; + } + + var absx = Math.abs(x); + var n = pow(k, k_labels.length); + for (var j = k_labels.length - 1; j >= 0; j--, n /= k) { + if (absx >= n) { + label = round_(x / n, digits) + k_labels[j]; + break; + } + } + if (kmg2) { + // TODO(danvk): clean up this logic. Why so different than kmb? + var x_parts = String(x.toExponential()).split('e-'); + if (x_parts.length === 2 && x_parts[1] >= 3 && x_parts[1] <= 24) { + if (x_parts[1] % 3 > 0) { + label = round_(x_parts[0] / pow(10, x_parts[1] % 3), digits); + } else { + label = Number(x_parts[0]).toFixed(2); + } + label += m_labels[Math.floor(x_parts[1] / 3) - 1]; + } + } + } + + return label; +} + +; + +/** + * variant for use as an axisLabelFormatter. + * @private + */ + +function numberAxisLabelFormatter(x, granularity, opts) { + return numberValueFormatter.call(this, x, opts); +} + +; + +/** + * @type {!Array.} + * @private + * @constant + */ +var SHORT_MONTH_NAMES_ = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + +/** + * Convert a JS date to a string appropriate to display on an axis that + * is displaying values at the stated granularity. This respects the + * labelsUTC option. + * @param {Date} date The date to format + * @param {number} granularity One of the Dygraph granularity constants + * @param {Dygraph} opts An options view + * @return {string} The date formatted as local time + * @private + */ + +function dateAxisLabelFormatter(date, granularity, opts) { + var utc = opts('labelsUTC'); + var accessors = utc ? DateAccessorsUTC : DateAccessorsLocal; + + var year = accessors.getFullYear(date), + month = accessors.getMonth(date), + day = accessors.getDate(date), + hours = accessors.getHours(date), + mins = accessors.getMinutes(date), + secs = accessors.getSeconds(date), + millis = accessors.getMilliseconds(date); + + if (granularity >= DygraphTickers.Granularity.DECADAL) { + return '' + year; + } else if (granularity >= DygraphTickers.Granularity.MONTHLY) { + return SHORT_MONTH_NAMES_[month] + ' ' + year; + } else { + var frac = hours * 3600 + mins * 60 + secs + 1e-3 * millis; + if (frac === 0 || granularity >= DygraphTickers.Granularity.DAILY) { + // e.g. '21 Jan' (%d%b) + return zeropad(day) + ' ' + SHORT_MONTH_NAMES_[month]; + } else { + return hmsString_(hours, mins, secs, millis); + } + } +} + +; +// alias in case anyone is referencing the old method. +// Dygraph.dateAxisFormatter = Dygraph.dateAxisLabelFormatter; + +/** + * Return a string version of a JS date for a value label. This respects the + * labelsUTC option. + * @param {Date} date The date to be formatted + * @param {Dygraph} opts An options view + * @private + */ + +function dateValueFormatter(d, opts) { + return dateString_(d, opts('labelsUTC')); +} + +; + +},{"./dygraph-tickers":16}],18:[function(require,module,exports){ +(function (process){ +/** + * @license + * Copyright 2006 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ /** + * @fileoverview Creates an interactive, zoomable graph based on a CSV file or + * string. Dygraph can handle multiple series with or without error bars. The + * date/value ranges will be automatically set. Dygraph uses the + * <canvas> tag, so it only works in FF1.5+. + * @author danvdk@gmail.com (Dan Vanderkam) + + Usage: +
+ + + The CSV file is of the form + + Date,SeriesA,SeriesB,SeriesC + YYYYMMDD,A1,B1,C1 + YYYYMMDD,A2,B2,C2 + + If the 'errorBars' option is set in the constructor, the input should be of + the form + Date,SeriesA,SeriesB,... + YYYYMMDD,A1,sigmaA1,B1,sigmaB1,... + YYYYMMDD,A2,sigmaA2,B2,sigmaB2,... + + If the 'fractions' option is set, the input should be of the form: + + Date,SeriesA,SeriesB,... + YYYYMMDD,A1/B1,A2/B2,... + YYYYMMDD,A1/B1,A2/B2,... + + And error bars will be calculated automatically using a binomial distribution. + + For further documentation and examples, see http://dygraphs.com/ + */'use strict';Object.defineProperty(exports,'__esModule',{value:true});var _slicedToArray=(function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n = (_s = _i.next()).done);_n = true) {_arr.push(_s.value);if(i && _arr.length === i)break;}}catch(err) {_d = true;_e = err;}finally {try{if(!_n && _i['return'])_i['return']();}finally {if(_d)throw _e;}}return _arr;}return function(arr,i){if(Array.isArray(arr)){return arr;}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i);}else {throw new TypeError('Invalid attempt to destructure non-iterable instance');}};})();function _interopRequireWildcard(obj){if(obj && obj.__esModule){return obj;}else {var newObj={};if(obj != null){for(var key in obj) {if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key] = obj[key];}}newObj['default'] = obj;return newObj;}}function _interopRequireDefault(obj){return obj && obj.__esModule?obj:{'default':obj};}var _dygraphLayout=require('./dygraph-layout');var _dygraphLayout2=_interopRequireDefault(_dygraphLayout);var _dygraphCanvas=require('./dygraph-canvas');var _dygraphCanvas2=_interopRequireDefault(_dygraphCanvas);var _dygraphOptions=require('./dygraph-options');var _dygraphOptions2=_interopRequireDefault(_dygraphOptions);var _dygraphInteractionModel=require('./dygraph-interaction-model');var _dygraphInteractionModel2=_interopRequireDefault(_dygraphInteractionModel);var _dygraphTickers=require('./dygraph-tickers');var DygraphTickers=_interopRequireWildcard(_dygraphTickers);var _dygraphUtils=require('./dygraph-utils');var utils=_interopRequireWildcard(_dygraphUtils);var _dygraphDefaultAttrs=require('./dygraph-default-attrs');var _dygraphDefaultAttrs2=_interopRequireDefault(_dygraphDefaultAttrs);var _dygraphOptionsReference=require('./dygraph-options-reference');var _dygraphOptionsReference2=_interopRequireDefault(_dygraphOptionsReference);var _iframeTarp=require('./iframe-tarp');var _iframeTarp2=_interopRequireDefault(_iframeTarp);var _datahandlerDefault=require('./datahandler/default');var _datahandlerDefault2=_interopRequireDefault(_datahandlerDefault);var _datahandlerBarsError=require('./datahandler/bars-error');var _datahandlerBarsError2=_interopRequireDefault(_datahandlerBarsError);var _datahandlerBarsCustom=require('./datahandler/bars-custom');var _datahandlerBarsCustom2=_interopRequireDefault(_datahandlerBarsCustom);var _datahandlerDefaultFractions=require('./datahandler/default-fractions');var _datahandlerDefaultFractions2=_interopRequireDefault(_datahandlerDefaultFractions);var _datahandlerBarsFractions=require('./datahandler/bars-fractions');var _datahandlerBarsFractions2=_interopRequireDefault(_datahandlerBarsFractions);var _datahandlerBars=require('./datahandler/bars');var _datahandlerBars2=_interopRequireDefault(_datahandlerBars);var _pluginsAnnotations=require('./plugins/annotations');var _pluginsAnnotations2=_interopRequireDefault(_pluginsAnnotations);var _pluginsAxes=require('./plugins/axes');var _pluginsAxes2=_interopRequireDefault(_pluginsAxes);var _pluginsChartLabels=require('./plugins/chart-labels');var _pluginsChartLabels2=_interopRequireDefault(_pluginsChartLabels);var _pluginsGrid=require('./plugins/grid');var _pluginsGrid2=_interopRequireDefault(_pluginsGrid);var _pluginsLegend=require('./plugins/legend');var _pluginsLegend2=_interopRequireDefault(_pluginsLegend);var _pluginsRangeSelector=require('./plugins/range-selector');var _pluginsRangeSelector2=_interopRequireDefault(_pluginsRangeSelector);var _dygraphGviz=require('./dygraph-gviz');var _dygraphGviz2=_interopRequireDefault(_dygraphGviz);"use strict"; /** + * Creates an interactive, zoomable chart. + * + * @constructor + * @param {div | String} div A div or the id of a div into which to construct + * the chart. + * @param {String | Function} file A file containing CSV data or a function + * that returns this data. The most basic expected format for each line is + * "YYYY/MM/DD,val1,val2,...". For more information, see + * http://dygraphs.com/data.html. + * @param {Object} attrs Various other attributes, e.g. errorBars determines + * whether the input data contains error ranges. For a complete list of + * options, see http://dygraphs.com/options.html. + */var Dygraph=function Dygraph(div,data,opts){this.__init__(div,data,opts);};Dygraph.NAME = "Dygraph";Dygraph.VERSION = "2.0.0"; // Various default values +Dygraph.DEFAULT_ROLL_PERIOD = 1;Dygraph.DEFAULT_WIDTH = 480;Dygraph.DEFAULT_HEIGHT = 320; // For max 60 Hz. animation: +Dygraph.ANIMATION_STEPS = 12;Dygraph.ANIMATION_DURATION = 200; /** + * Standard plotters. These may be used by clients. + * Available plotters are: + * - Dygraph.Plotters.linePlotter: draws central lines (most common) + * - Dygraph.Plotters.errorPlotter: draws error bars + * - Dygraph.Plotters.fillPlotter: draws fills under lines (used with fillGraph) + * + * By default, the plotter is [fillPlotter, errorPlotter, linePlotter]. + * This causes all the lines to be drawn over all the fills/error bars. + */Dygraph.Plotters = _dygraphCanvas2['default']._Plotters; // Used for initializing annotation CSS rules only once. +Dygraph.addedAnnotationCSS = false; /** + * Initializes the Dygraph. This creates a new DIV and constructs the PlotKit + * and context <canvas> inside of it. See the constructor for details. + * on the parameters. + * @param {Element} div the Element to render the graph into. + * @param {string | Function} file Source data + * @param {Object} attrs Miscellaneous other options + * @private + */Dygraph.prototype.__init__ = function(div,file,attrs){this.is_initial_draw_ = true;this.readyFns_ = []; // Support two-argument constructor +if(attrs === null || attrs === undefined){attrs = {};}attrs = Dygraph.copyUserAttrs_(attrs);if(typeof div == 'string'){div = document.getElementById(div);}if(!div){throw new Error('Constructing dygraph with a non-existent div!');} // Copy the important bits into the object +// TODO(danvk): most of these should just stay in the attrs_ dictionary. +this.maindiv_ = div;this.file_ = file;this.rollPeriod_ = attrs.rollPeriod || Dygraph.DEFAULT_ROLL_PERIOD;this.previousVerticalX_ = -1;this.fractions_ = attrs.fractions || false;this.dateWindow_ = attrs.dateWindow || null;this.annotations_ = []; // Clear the div. This ensure that, if multiple dygraphs are passed the same +// div, then only one will be drawn. +div.innerHTML = ""; // For historical reasons, the 'width' and 'height' options trump all CSS +// rules _except_ for an explicit 'width' or 'height' on the div. +// As an added convenience, if the div has zero height (like
does +// without any styles), then we use a default height/width. +if(div.style.width === '' && attrs.width){div.style.width = attrs.width + "px";}if(div.style.height === '' && attrs.height){div.style.height = attrs.height + "px";}if(div.style.height === '' && div.clientHeight === 0){div.style.height = Dygraph.DEFAULT_HEIGHT + "px";if(div.style.width === ''){div.style.width = Dygraph.DEFAULT_WIDTH + "px";}} // These will be zero if the dygraph's div is hidden. In that case, +// use the user-specified attributes if present. If not, use zero +// and assume the user will call resize to fix things later. +this.width_ = div.clientWidth || attrs.width || 0;this.height_ = div.clientHeight || attrs.height || 0; // TODO(danvk): set fillGraph to be part of attrs_ here, not user_attrs_. +if(attrs.stackedGraph){attrs.fillGraph = true; // TODO(nikhilk): Add any other stackedGraph checks here. +} // DEPRECATION WARNING: All option processing should be moved from +// attrs_ and user_attrs_ to options_, which holds all this information. +// +// Dygraphs has many options, some of which interact with one another. +// To keep track of everything, we maintain two sets of options: +// +// this.user_attrs_ only options explicitly set by the user. +// this.attrs_ defaults, options derived from user_attrs_, data. +// +// Options are then accessed this.attr_('attr'), which first looks at +// user_attrs_ and then computed attrs_. This way Dygraphs can set intelligent +// defaults without overriding behavior that the user specifically asks for. +this.user_attrs_ = {};utils.update(this.user_attrs_,attrs); // This sequence ensures that Dygraph.DEFAULT_ATTRS is never modified. +this.attrs_ = {};utils.updateDeep(this.attrs_,_dygraphDefaultAttrs2['default']);this.boundaryIds_ = [];this.setIndexByName_ = {};this.datasetIndex_ = [];this.registeredEvents_ = [];this.eventListeners_ = {};this.attributes_ = new _dygraphOptions2['default'](this); // Create the containing DIV and other interactive elements +this.createInterface_(); // Activate plugins. +this.plugins_ = [];var plugins=Dygraph.PLUGINS.concat(this.getOption('plugins'));for(var i=0;i < plugins.length;i++) { // the plugins option may contain either plugin classes or instances. +// Plugin instances contain an activate method. +var Plugin=plugins[i]; // either a constructor or an instance. +var pluginInstance;if(typeof Plugin.activate !== 'undefined'){pluginInstance = Plugin;}else {pluginInstance = new Plugin();}var pluginDict={plugin:pluginInstance,events:{},options:{},pluginOptions:{}};var handlers=pluginInstance.activate(this);for(var eventName in handlers) {if(!handlers.hasOwnProperty(eventName))continue; // TODO(danvk): validate eventName. +pluginDict.events[eventName] = handlers[eventName];}this.plugins_.push(pluginDict);} // At this point, plugins can no longer register event handlers. +// Construct a map from event -> ordered list of [callback, plugin]. +for(var i=0;i < this.plugins_.length;i++) {var plugin_dict=this.plugins_[i];for(var eventName in plugin_dict.events) {if(!plugin_dict.events.hasOwnProperty(eventName))continue;var callback=plugin_dict.events[eventName];var pair=[plugin_dict.plugin,callback];if(!(eventName in this.eventListeners_)){this.eventListeners_[eventName] = [pair];}else {this.eventListeners_[eventName].push(pair);}}}this.createDragInterface_();this.start_();}; /** + * Triggers a cascade of events to the various plugins which are interested in them. + * Returns true if the "default behavior" should be prevented, i.e. if one + * of the event listeners called event.preventDefault(). + * @private + */Dygraph.prototype.cascadeEvents_ = function(name,extra_props){if(!(name in this.eventListeners_))return false; // QUESTION: can we use objects & prototypes to speed this up? +var e={dygraph:this,cancelable:false,defaultPrevented:false,preventDefault:function preventDefault(){if(!e.cancelable)throw "Cannot call preventDefault on non-cancelable event.";e.defaultPrevented = true;},propagationStopped:false,stopPropagation:function stopPropagation(){e.propagationStopped = true;}};utils.update(e,extra_props);var callback_plugin_pairs=this.eventListeners_[name];if(callback_plugin_pairs){for(var i=callback_plugin_pairs.length - 1;i >= 0;i--) {var plugin=callback_plugin_pairs[i][0];var callback=callback_plugin_pairs[i][1];callback.call(plugin,e);if(e.propagationStopped)break;}}return e.defaultPrevented;}; /** + * Fetch a plugin instance of a particular class. Only for testing. + * @private + * @param {!Class} type The type of the plugin. + * @return {Object} Instance of the plugin, or null if there is none. + */Dygraph.prototype.getPluginInstance_ = function(type){for(var i=0;i < this.plugins_.length;i++) {var p=this.plugins_[i];if(p.plugin instanceof type){return p.plugin;}}return null;}; /** + * Returns the zoomed status of the chart for one or both axes. + * + * Axis is an optional parameter. Can be set to 'x' or 'y'. + * + * The zoomed status for an axis is set whenever a user zooms using the mouse + * or when the dateWindow or valueRange are updated. Double-clicking or calling + * resetZoom() resets the zoom status for the chart. + */Dygraph.prototype.isZoomed = function(axis){var isZoomedX=!!this.dateWindow_;if(axis === 'x')return isZoomedX;var isZoomedY=this.axes_.map(function(axis){return !!axis.valueRange;}).indexOf(true) >= 0;if(axis === null || axis === undefined){return isZoomedX || isZoomedY;}if(axis === 'y')return isZoomedY;throw new Error('axis parameter is [' + axis + '] must be null, \'x\' or \'y\'.');}; /** + * Returns information about the Dygraph object, including its containing ID. + */Dygraph.prototype.toString = function(){var maindiv=this.maindiv_;var id=maindiv && maindiv.id?maindiv.id:maindiv;return "[Dygraph " + id + "]";}; /** + * @private + * Returns the value of an option. This may be set by the user (either in the + * constructor or by calling updateOptions) or by dygraphs, and may be set to a + * per-series value. + * @param {string} name The name of the option, e.g. 'rollPeriod'. + * @param {string} [seriesName] The name of the series to which the option + * will be applied. If no per-series value of this option is available, then + * the global value is returned. This is optional. + * @return { ... } The value of the option. + */Dygraph.prototype.attr_ = function(name,seriesName){ // For "production" code, this gets removed by uglifyjs. +if(typeof process !== 'undefined'){if("development" != 'production'){if(typeof _dygraphOptionsReference2['default'] === 'undefined'){console.error('Must include options reference JS for testing');}else if(!_dygraphOptionsReference2['default'].hasOwnProperty(name)){console.error('Dygraphs is using property ' + name + ', which has no ' + 'entry in the Dygraphs.OPTIONS_REFERENCE listing.'); // Only log this error once. +_dygraphOptionsReference2['default'][name] = true;}}}return seriesName?this.attributes_.getForSeries(name,seriesName):this.attributes_.get(name);}; /** + * Returns the current value for an option, as set in the constructor or via + * updateOptions. You may pass in an (optional) series name to get per-series + * values for the option. + * + * All values returned by this method should be considered immutable. If you + * modify them, there is no guarantee that the changes will be honored or that + * dygraphs will remain in a consistent state. If you want to modify an option, + * use updateOptions() instead. + * + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {*} The value of the option. + */Dygraph.prototype.getOption = function(name,opt_seriesName){return this.attr_(name,opt_seriesName);}; /** + * Like getOption(), but specifically returns a number. + * This is a convenience function for working with the Closure Compiler. + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {number} The value of the option. + * @private + */Dygraph.prototype.getNumericOption = function(name,opt_seriesName){return (/** @type{number} */this.getOption(name,opt_seriesName));}; /** + * Like getOption(), but specifically returns a string. + * This is a convenience function for working with the Closure Compiler. + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {string} The value of the option. + * @private + */Dygraph.prototype.getStringOption = function(name,opt_seriesName){return (/** @type{string} */this.getOption(name,opt_seriesName));}; /** + * Like getOption(), but specifically returns a boolean. + * This is a convenience function for working with the Closure Compiler. + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {boolean} The value of the option. + * @private + */Dygraph.prototype.getBooleanOption = function(name,opt_seriesName){return (/** @type{boolean} */this.getOption(name,opt_seriesName));}; /** + * Like getOption(), but specifically returns a function. + * This is a convenience function for working with the Closure Compiler. + * @param {string} name The name of the option (e.g. 'strokeWidth') + * @param {string=} opt_seriesName Series name to get per-series values. + * @return {function(...)} The value of the option. + * @private + */Dygraph.prototype.getFunctionOption = function(name,opt_seriesName){return (/** @type{function(...)} */this.getOption(name,opt_seriesName));};Dygraph.prototype.getOptionForAxis = function(name,axis){return this.attributes_.getForAxis(name,axis);}; /** + * @private + * @param {string} axis The name of the axis (i.e. 'x', 'y' or 'y2') + * @return { ... } A function mapping string -> option value + */Dygraph.prototype.optionsViewForAxis_ = function(axis){var self=this;return function(opt){var axis_opts=self.user_attrs_.axes;if(axis_opts && axis_opts[axis] && axis_opts[axis].hasOwnProperty(opt)){return axis_opts[axis][opt];} // I don't like that this is in a second spot. +if(axis === 'x' && opt === 'logscale'){ // return the default value. +// TODO(konigsberg): pull the default from a global default. +return false;} // user-specified attributes always trump defaults, even if they're less +// specific. +if(typeof self.user_attrs_[opt] != 'undefined'){return self.user_attrs_[opt];}axis_opts = self.attrs_.axes;if(axis_opts && axis_opts[axis] && axis_opts[axis].hasOwnProperty(opt)){return axis_opts[axis][opt];} // check old-style axis options +// TODO(danvk): add a deprecation warning if either of these match. +if(axis == 'y' && self.axes_[0].hasOwnProperty(opt)){return self.axes_[0][opt];}else if(axis == 'y2' && self.axes_[1].hasOwnProperty(opt)){return self.axes_[1][opt];}return self.attr_(opt);};}; /** + * Returns the current rolling period, as set by the user or an option. + * @return {number} The number of points in the rolling window + */Dygraph.prototype.rollPeriod = function(){return this.rollPeriod_;}; /** + * Returns the currently-visible x-range. This can be affected by zooming, + * panning or a call to updateOptions. + * Returns a two-element array: [left, right]. + * If the Dygraph has dates on the x-axis, these will be millis since epoch. + */Dygraph.prototype.xAxisRange = function(){return this.dateWindow_?this.dateWindow_:this.xAxisExtremes();}; /** + * Returns the lower- and upper-bound x-axis values of the data set. + */Dygraph.prototype.xAxisExtremes = function(){var pad=this.getNumericOption('xRangePad') / this.plotter_.area.w;if(this.numRows() === 0){return [0 - pad,1 + pad];}var left=this.rawData_[0][0];var right=this.rawData_[this.rawData_.length - 1][0];if(pad){ // Must keep this in sync with dygraph-layout _evaluateLimits() +var range=right - left;left -= range * pad;right += range * pad;}return [left,right];}; /** + * Returns the lower- and upper-bound y-axis values for each axis. These are + * the ranges you'll get if you double-click to zoom out or call resetZoom(). + * The return value is an array of [low, high] tuples, one for each y-axis. + */Dygraph.prototype.yAxisExtremes = function(){ // TODO(danvk): this is pretty inefficient +var packed=this.gatherDatasets_(this.rolledSeries_,null);var extremes=packed.extremes;var saveAxes=this.axes_;this.computeYAxisRanges_(extremes);var newAxes=this.axes_;this.axes_ = saveAxes;return newAxes.map(function(axis){return axis.extremeRange;});}; /** + * Returns the currently-visible y-range for an axis. This can be affected by + * zooming, panning or a call to updateOptions. Axis indices are zero-based. If + * called with no arguments, returns the range of the first axis. + * Returns a two-element array: [bottom, top]. + */Dygraph.prototype.yAxisRange = function(idx){if(typeof idx == "undefined")idx = 0;if(idx < 0 || idx >= this.axes_.length){return null;}var axis=this.axes_[idx];return [axis.computedValueRange[0],axis.computedValueRange[1]];}; /** + * Returns the currently-visible y-ranges for each axis. This can be affected by + * zooming, panning, calls to updateOptions, etc. + * Returns an array of [bottom, top] pairs, one for each y-axis. + */Dygraph.prototype.yAxisRanges = function(){var ret=[];for(var i=0;i < this.axes_.length;i++) {ret.push(this.yAxisRange(i));}return ret;}; // TODO(danvk): use these functions throughout dygraphs. +/** + * Convert from data coordinates to canvas/div X/Y coordinates. + * If specified, do this conversion for the coordinate system of a particular + * axis. Uses the first axis by default. + * Returns a two-element array: [X, Y] + * + * Note: use toDomXCoord instead of toDomCoords(x, null) and use toDomYCoord + * instead of toDomCoords(null, y, axis). + */Dygraph.prototype.toDomCoords = function(x,y,axis){return [this.toDomXCoord(x),this.toDomYCoord(y,axis)];}; /** + * Convert from data x coordinates to canvas/div X coordinate. + * If specified, do this conversion for the coordinate system of a particular + * axis. + * Returns a single value or null if x is null. + */Dygraph.prototype.toDomXCoord = function(x){if(x === null){return null;}var area=this.plotter_.area;var xRange=this.xAxisRange();return area.x + (x - xRange[0]) / (xRange[1] - xRange[0]) * area.w;}; /** + * Convert from data x coordinates to canvas/div Y coordinate and optional + * axis. Uses the first axis by default. + * + * returns a single value or null if y is null. + */Dygraph.prototype.toDomYCoord = function(y,axis){var pct=this.toPercentYCoord(y,axis);if(pct === null){return null;}var area=this.plotter_.area;return area.y + pct * area.h;}; /** + * Convert from canvas/div coords to data coordinates. + * If specified, do this conversion for the coordinate system of a particular + * axis. Uses the first axis by default. + * Returns a two-element array: [X, Y]. + * + * Note: use toDataXCoord instead of toDataCoords(x, null) and use toDataYCoord + * instead of toDataCoords(null, y, axis). + */Dygraph.prototype.toDataCoords = function(x,y,axis){return [this.toDataXCoord(x),this.toDataYCoord(y,axis)];}; /** + * Convert from canvas/div x coordinate to data coordinate. + * + * If x is null, this returns null. + */Dygraph.prototype.toDataXCoord = function(x){if(x === null){return null;}var area=this.plotter_.area;var xRange=this.xAxisRange();if(!this.attributes_.getForAxis("logscale",'x')){return xRange[0] + (x - area.x) / area.w * (xRange[1] - xRange[0]);}else {var pct=(x - area.x) / area.w;return utils.logRangeFraction(xRange[0],xRange[1],pct);}}; /** + * Convert from canvas/div y coord to value. + * + * If y is null, this returns null. + * if axis is null, this uses the first axis. + */Dygraph.prototype.toDataYCoord = function(y,axis){if(y === null){return null;}var area=this.plotter_.area;var yRange=this.yAxisRange(axis);if(typeof axis == "undefined")axis = 0;if(!this.attributes_.getForAxis("logscale",axis)){return yRange[0] + (area.y + area.h - y) / area.h * (yRange[1] - yRange[0]);}else { // Computing the inverse of toDomCoord. +var pct=(y - area.y) / area.h; // Note reversed yRange, y1 is on top with pct==0. +return utils.logRangeFraction(yRange[1],yRange[0],pct);}}; /** + * Converts a y for an axis to a percentage from the top to the + * bottom of the drawing area. + * + * If the coordinate represents a value visible on the canvas, then + * the value will be between 0 and 1, where 0 is the top of the canvas. + * However, this method will return values outside the range, as + * values can fall outside the canvas. + * + * If y is null, this returns null. + * if axis is null, this uses the first axis. + * + * @param {number} y The data y-coordinate. + * @param {number} [axis] The axis number on which the data coordinate lives. + * @return {number} A fraction in [0, 1] where 0 = the top edge. + */Dygraph.prototype.toPercentYCoord = function(y,axis){if(y === null){return null;}if(typeof axis == "undefined")axis = 0;var yRange=this.yAxisRange(axis);var pct;var logscale=this.attributes_.getForAxis("logscale",axis);if(logscale){var logr0=utils.log10(yRange[0]);var logr1=utils.log10(yRange[1]);pct = (logr1 - utils.log10(y)) / (logr1 - logr0);}else { // yRange[1] - y is unit distance from the bottom. +// yRange[1] - yRange[0] is the scale of the range. +// (yRange[1] - y) / (yRange[1] - yRange[0]) is the % from the bottom. +pct = (yRange[1] - y) / (yRange[1] - yRange[0]);}return pct;}; /** + * Converts an x value to a percentage from the left to the right of + * the drawing area. + * + * If the coordinate represents a value visible on the canvas, then + * the value will be between 0 and 1, where 0 is the left of the canvas. + * However, this method will return values outside the range, as + * values can fall outside the canvas. + * + * If x is null, this returns null. + * @param {number} x The data x-coordinate. + * @return {number} A fraction in [0, 1] where 0 = the left edge. + */Dygraph.prototype.toPercentXCoord = function(x){if(x === null){return null;}var xRange=this.xAxisRange();var pct;var logscale=this.attributes_.getForAxis("logscale",'x');if(logscale === true){ // logscale can be null so we test for true explicitly. +var logr0=utils.log10(xRange[0]);var logr1=utils.log10(xRange[1]);pct = (utils.log10(x) - logr0) / (logr1 - logr0);}else { // x - xRange[0] is unit distance from the left. +// xRange[1] - xRange[0] is the scale of the range. +// The full expression below is the % from the left. +pct = (x - xRange[0]) / (xRange[1] - xRange[0]);}return pct;}; /** + * Returns the number of columns (including the independent variable). + * @return {number} The number of columns. + */Dygraph.prototype.numColumns = function(){if(!this.rawData_)return 0;return this.rawData_[0]?this.rawData_[0].length:this.attr_("labels").length;}; /** + * Returns the number of rows (excluding any header/label row). + * @return {number} The number of rows, less any header. + */Dygraph.prototype.numRows = function(){if(!this.rawData_)return 0;return this.rawData_.length;}; /** + * Returns the value in the given row and column. If the row and column exceed + * the bounds on the data, returns null. Also returns null if the value is + * missing. + * @param {number} row The row number of the data (0-based). Row 0 is the + * first row of data, not a header row. + * @param {number} col The column number of the data (0-based) + * @return {number} The value in the specified cell or null if the row/col + * were out of range. + */Dygraph.prototype.getValue = function(row,col){if(row < 0 || row > this.rawData_.length)return null;if(col < 0 || col > this.rawData_[row].length)return null;return this.rawData_[row][col];}; /** + * Generates interface elements for the Dygraph: a containing div, a div to + * display the current point, and a textbox to adjust the rolling average + * period. Also creates the Renderer/Layout elements. + * @private + */Dygraph.prototype.createInterface_ = function(){ // Create the all-enclosing graph div +var enclosing=this.maindiv_;this.graphDiv = document.createElement("div"); // TODO(danvk): any other styles that are useful to set here? +this.graphDiv.style.textAlign = 'left'; // This is a CSS "reset" +this.graphDiv.style.position = 'relative';enclosing.appendChild(this.graphDiv); // Create the canvas for interactive parts of the chart. +this.canvas_ = utils.createCanvas();this.canvas_.style.position = "absolute"; // ... and for static parts of the chart. +this.hidden_ = this.createPlotKitCanvas_(this.canvas_);this.canvas_ctx_ = utils.getContext(this.canvas_);this.hidden_ctx_ = utils.getContext(this.hidden_);this.resizeElements_(); // The interactive parts of the graph are drawn on top of the chart. +this.graphDiv.appendChild(this.hidden_);this.graphDiv.appendChild(this.canvas_);this.mouseEventElement_ = this.createMouseEventElement_(); // Create the grapher +this.layout_ = new _dygraphLayout2['default'](this);var dygraph=this;this.mouseMoveHandler_ = function(e){dygraph.mouseMove_(e);};this.mouseOutHandler_ = function(e){ // The mouse has left the chart if: +// 1. e.target is inside the chart +// 2. e.relatedTarget is outside the chart +var target=e.target || e.fromElement;var relatedTarget=e.relatedTarget || e.toElement;if(utils.isNodeContainedBy(target,dygraph.graphDiv) && !utils.isNodeContainedBy(relatedTarget,dygraph.graphDiv)){dygraph.mouseOut_(e);}};this.addAndTrackEvent(window,'mouseout',this.mouseOutHandler_);this.addAndTrackEvent(this.mouseEventElement_,'mousemove',this.mouseMoveHandler_); // Don't recreate and register the resize handler on subsequent calls. +// This happens when the graph is resized. +if(!this.resizeHandler_){this.resizeHandler_ = function(e){dygraph.resize();}; // Update when the window is resized. +// TODO(danvk): drop frames depending on complexity of the chart. +this.addAndTrackEvent(window,'resize',this.resizeHandler_);}};Dygraph.prototype.resizeElements_ = function(){this.graphDiv.style.width = this.width_ + "px";this.graphDiv.style.height = this.height_ + "px";var canvasScale=utils.getContextPixelRatio(this.canvas_ctx_);this.canvas_.width = this.width_ * canvasScale;this.canvas_.height = this.height_ * canvasScale;this.canvas_.style.width = this.width_ + "px"; // for IE +this.canvas_.style.height = this.height_ + "px"; // for IE +if(canvasScale !== 1){this.canvas_ctx_.scale(canvasScale,canvasScale);}var hiddenScale=utils.getContextPixelRatio(this.hidden_ctx_);this.hidden_.width = this.width_ * hiddenScale;this.hidden_.height = this.height_ * hiddenScale;this.hidden_.style.width = this.width_ + "px"; // for IE +this.hidden_.style.height = this.height_ + "px"; // for IE +if(hiddenScale !== 1){this.hidden_ctx_.scale(hiddenScale,hiddenScale);}}; /** + * Detach DOM elements in the dygraph and null out all data references. + * Calling this when you're done with a dygraph can dramatically reduce memory + * usage. See, e.g., the tests/perf.html example. + */Dygraph.prototype.destroy = function(){this.canvas_ctx_.restore();this.hidden_ctx_.restore(); // Destroy any plugins, in the reverse order that they were registered. +for(var i=this.plugins_.length - 1;i >= 0;i--) {var p=this.plugins_.pop();if(p.plugin.destroy)p.plugin.destroy();}var removeRecursive=function removeRecursive(node){while(node.hasChildNodes()) {removeRecursive(node.firstChild);node.removeChild(node.firstChild);}};this.removeTrackedEvents_(); // remove mouse event handlers (This may not be necessary anymore) +utils.removeEvent(window,'mouseout',this.mouseOutHandler_);utils.removeEvent(this.mouseEventElement_,'mousemove',this.mouseMoveHandler_); // remove window handlers +utils.removeEvent(window,'resize',this.resizeHandler_);this.resizeHandler_ = null;removeRecursive(this.maindiv_);var nullOut=function nullOut(obj){for(var n in obj) {if(typeof obj[n] === 'object'){obj[n] = null;}}}; // These may not all be necessary, but it can't hurt... +nullOut(this.layout_);nullOut(this.plotter_);nullOut(this);}; /** + * Creates the canvas on which the chart will be drawn. Only the Renderer ever + * draws on this particular canvas. All Dygraph work (i.e. drawing hover dots + * or the zoom rectangles) is done on this.canvas_. + * @param {Object} canvas The Dygraph canvas over which to overlay the plot + * @return {Object} The newly-created canvas + * @private + */Dygraph.prototype.createPlotKitCanvas_ = function(canvas){var h=utils.createCanvas();h.style.position = "absolute"; // TODO(danvk): h should be offset from canvas. canvas needs to include +// some extra area to make it easier to zoom in on the far left and far +// right. h needs to be precisely the plot area, so that clipping occurs. +h.style.top = canvas.style.top;h.style.left = canvas.style.left;h.width = this.width_;h.height = this.height_;h.style.width = this.width_ + "px"; // for IE +h.style.height = this.height_ + "px"; // for IE +return h;}; /** + * Creates an overlay element used to handle mouse events. + * @return {Object} The mouse event element. + * @private + */Dygraph.prototype.createMouseEventElement_ = function(){return this.canvas_;}; /** + * Generate a set of distinct colors for the data series. This is done with a + * color wheel. Saturation/Value are customizable, and the hue is + * equally-spaced around the color wheel. If a custom set of colors is + * specified, that is used instead. + * @private + */Dygraph.prototype.setColors_ = function(){var labels=this.getLabels();var num=labels.length - 1;this.colors_ = [];this.colorsMap_ = {}; // These are used for when no custom colors are specified. +var sat=this.getNumericOption('colorSaturation') || 1.0;var val=this.getNumericOption('colorValue') || 0.5;var half=Math.ceil(num / 2);var colors=this.getOption('colors');var visibility=this.visibility();for(var i=0;i < num;i++) {if(!visibility[i]){continue;}var label=labels[i + 1];var colorStr=this.attributes_.getForSeries('color',label);if(!colorStr){if(colors){colorStr = colors[i % colors.length];}else { // alternate colors for high contrast. +var idx=i % 2?half + (i + 1) / 2:Math.ceil((i + 1) / 2);var hue=1.0 * idx / (1 + num);colorStr = utils.hsvToRGB(hue,sat,val);}}this.colors_.push(colorStr);this.colorsMap_[label] = colorStr;}}; /** + * Return the list of colors. This is either the list of colors passed in the + * attributes or the autogenerated list of rgb(r,g,b) strings. + * This does not return colors for invisible series. + * @return {Array.} The list of colors. + */Dygraph.prototype.getColors = function(){return this.colors_;}; /** + * Returns a few attributes of a series, i.e. its color, its visibility, which + * axis it's assigned to, and its column in the original data. + * Returns null if the series does not exist. + * Otherwise, returns an object with column, visibility, color and axis properties. + * The "axis" property will be set to 1 for y1 and 2 for y2. + * The "column" property can be fed back into getValue(row, column) to get + * values for this series. + */Dygraph.prototype.getPropertiesForSeries = function(series_name){var idx=-1;var labels=this.getLabels();for(var i=1;i < labels.length;i++) {if(labels[i] == series_name){idx = i;break;}}if(idx == -1)return null;return {name:series_name,column:idx,visible:this.visibility()[idx - 1],color:this.colorsMap_[series_name],axis:1 + this.attributes_.axisForSeries(series_name)};}; /** + * Create the text box to adjust the averaging period + * @private + */Dygraph.prototype.createRollInterface_ = function(){var _this=this; // Create a roller if one doesn't exist already. +var roller=this.roller_;if(!roller){this.roller_ = roller = document.createElement("input");roller.type = "text";roller.style.display = "none";roller.className = 'dygraph-roller';this.graphDiv.appendChild(roller);}var display=this.getBooleanOption('showRoller')?'block':'none';var area=this.getArea();var textAttr={"top":area.y + area.h - 25 + "px","left":area.x + 1 + "px","display":display};roller.size = "2";roller.value = this.rollPeriod_;utils.update(roller.style,textAttr);roller.onchange = function(){return _this.adjustRoll(roller.value);};}; /** + * Set up all the mouse handlers needed to capture dragging behavior for zoom + * events. + * @private + */Dygraph.prototype.createDragInterface_ = function(){var context={ // Tracks whether the mouse is down right now +isZooming:false,isPanning:false, // is this drag part of a pan? +is2DPan:false, // if so, is that pan 1- or 2-dimensional? +dragStartX:null, // pixel coordinates +dragStartY:null, // pixel coordinates +dragEndX:null, // pixel coordinates +dragEndY:null, // pixel coordinates +dragDirection:null,prevEndX:null, // pixel coordinates +prevEndY:null, // pixel coordinates +prevDragDirection:null,cancelNextDblclick:false, // see comment in dygraph-interaction-model.js +// The value on the left side of the graph when a pan operation starts. +initialLeftmostDate:null, // The number of units each pixel spans. (This won't be valid for log +// scales) +xUnitsPerPixel:null, // TODO(danvk): update this comment +// The range in second/value units that the viewport encompasses during a +// panning operation. +dateRange:null, // Top-left corner of the canvas, in DOM coords +// TODO(konigsberg): Rename topLeftCanvasX, topLeftCanvasY. +px:0,py:0, // Values for use with panEdgeFraction, which limit how far outside the +// graph's data boundaries it can be panned. +boundedDates:null, // [minDate, maxDate] +boundedValues:null, // [[minValue, maxValue] ...] +// We cover iframes during mouse interactions. See comments in +// dygraph-utils.js for more info on why this is a good idea. +tarp:new _iframeTarp2['default'](), // contextB is the same thing as this context object but renamed. +initializeMouseDown:function initializeMouseDown(event,g,contextB){ // prevents mouse drags from selecting page text. +if(event.preventDefault){event.preventDefault(); // Firefox, Chrome, etc. +}else {event.returnValue = false; // IE +event.cancelBubble = true;}var canvasPos=utils.findPos(g.canvas_);contextB.px = canvasPos.x;contextB.py = canvasPos.y;contextB.dragStartX = utils.dragGetX_(event,contextB);contextB.dragStartY = utils.dragGetY_(event,contextB);contextB.cancelNextDblclick = false;contextB.tarp.cover();},destroy:function destroy(){var context=this;if(context.isZooming || context.isPanning){context.isZooming = false;context.dragStartX = null;context.dragStartY = null;}if(context.isPanning){context.isPanning = false;context.draggingDate = null;context.dateRange = null;for(var i=0;i < self.axes_.length;i++) {delete self.axes_[i].draggingValue;delete self.axes_[i].dragValueRange;}}context.tarp.uncover();}};var interactionModel=this.getOption("interactionModel"); // Self is the graph. +var self=this; // Function that binds the graph and context to the handler. +var bindHandler=function bindHandler(handler){return function(event){handler(event,self,context);};};for(var eventName in interactionModel) {if(!interactionModel.hasOwnProperty(eventName))continue;this.addAndTrackEvent(this.mouseEventElement_,eventName,bindHandler(interactionModel[eventName]));} // If the user releases the mouse button during a drag, but not over the +// canvas, then it doesn't count as a zooming action. +if(!interactionModel.willDestroyContextMyself){var mouseUpHandler=function mouseUpHandler(event){context.destroy();};this.addAndTrackEvent(document,'mouseup',mouseUpHandler);}}; /** + * Draw a gray zoom rectangle over the desired area of the canvas. Also clears + * up any previous zoom rectangles that were drawn. This could be optimized to + * avoid extra redrawing, but it's tricky to avoid interactions with the status + * dots. + * + * @param {number} direction the direction of the zoom rectangle. Acceptable + * values are utils.HORIZONTAL and utils.VERTICAL. + * @param {number} startX The X position where the drag started, in canvas + * coordinates. + * @param {number} endX The current X position of the drag, in canvas coords. + * @param {number} startY The Y position where the drag started, in canvas + * coordinates. + * @param {number} endY The current Y position of the drag, in canvas coords. + * @param {number} prevDirection the value of direction on the previous call to + * this function. Used to avoid excess redrawing + * @param {number} prevEndX The value of endX on the previous call to this + * function. Used to avoid excess redrawing + * @param {number} prevEndY The value of endY on the previous call to this + * function. Used to avoid excess redrawing + * @private + */Dygraph.prototype.drawZoomRect_ = function(direction,startX,endX,startY,endY,prevDirection,prevEndX,prevEndY){var ctx=this.canvas_ctx_; // Clean up from the previous rect if necessary +if(prevDirection == utils.HORIZONTAL){ctx.clearRect(Math.min(startX,prevEndX),this.layout_.getPlotArea().y,Math.abs(startX - prevEndX),this.layout_.getPlotArea().h);}else if(prevDirection == utils.VERTICAL){ctx.clearRect(this.layout_.getPlotArea().x,Math.min(startY,prevEndY),this.layout_.getPlotArea().w,Math.abs(startY - prevEndY));} // Draw a light-grey rectangle to show the new viewing area +if(direction == utils.HORIZONTAL){if(endX && startX){ctx.fillStyle = "rgba(128,128,128,0.33)";ctx.fillRect(Math.min(startX,endX),this.layout_.getPlotArea().y,Math.abs(endX - startX),this.layout_.getPlotArea().h);}}else if(direction == utils.VERTICAL){if(endY && startY){ctx.fillStyle = "rgba(128,128,128,0.33)";ctx.fillRect(this.layout_.getPlotArea().x,Math.min(startY,endY),this.layout_.getPlotArea().w,Math.abs(endY - startY));}}}; /** + * Clear the zoom rectangle (and perform no zoom). + * @private + */Dygraph.prototype.clearZoomRect_ = function(){this.currentZoomRectArgs_ = null;this.canvas_ctx_.clearRect(0,0,this.width_,this.height_);}; /** + * Zoom to something containing [lowX, highX]. These are pixel coordinates in + * the canvas. The exact zoom window may be slightly larger if there are no data + * points near lowX or highX. Don't confuse this function with doZoomXDates, + * which accepts dates that match the raw data. This function redraws the graph. + * + * @param {number} lowX The leftmost pixel value that should be visible. + * @param {number} highX The rightmost pixel value that should be visible. + * @private + */Dygraph.prototype.doZoomX_ = function(lowX,highX){this.currentZoomRectArgs_ = null; // Find the earliest and latest dates contained in this canvasx range. +// Convert the call to date ranges of the raw data. +var minDate=this.toDataXCoord(lowX);var maxDate=this.toDataXCoord(highX);this.doZoomXDates_(minDate,maxDate);}; /** + * Zoom to something containing [minDate, maxDate] values. Don't confuse this + * method with doZoomX which accepts pixel coordinates. This function redraws + * the graph. + * + * @param {number} minDate The minimum date that should be visible. + * @param {number} maxDate The maximum date that should be visible. + * @private + */Dygraph.prototype.doZoomXDates_ = function(minDate,maxDate){var _this2=this; // TODO(danvk): when xAxisRange is null (i.e. "fit to data", the animation +// can produce strange effects. Rather than the x-axis transitioning slowly +// between values, it can jerk around.) +var old_window=this.xAxisRange();var new_window=[minDate,maxDate];var zoomCallback=this.getFunctionOption('zoomCallback');this.doAnimatedZoom(old_window,new_window,null,null,function(){if(zoomCallback){zoomCallback.call(_this2,minDate,maxDate,_this2.yAxisRanges());}});}; /** + * Zoom to something containing [lowY, highY]. These are pixel coordinates in + * the canvas. This function redraws the graph. + * + * @param {number} lowY The topmost pixel value that should be visible. + * @param {number} highY The lowest pixel value that should be visible. + * @private + */Dygraph.prototype.doZoomY_ = function(lowY,highY){var _this3=this;this.currentZoomRectArgs_ = null; // Find the highest and lowest values in pixel range for each axis. +// Note that lowY (in pixels) corresponds to the max Value (in data coords). +// This is because pixels increase as you go down on the screen, whereas data +// coordinates increase as you go up the screen. +var oldValueRanges=this.yAxisRanges();var newValueRanges=[];for(var i=0;i < this.axes_.length;i++) {var hi=this.toDataYCoord(lowY,i);var low=this.toDataYCoord(highY,i);newValueRanges.push([low,hi]);}var zoomCallback=this.getFunctionOption('zoomCallback');this.doAnimatedZoom(null,null,oldValueRanges,newValueRanges,function(){if(zoomCallback){var _xAxisRange=_this3.xAxisRange();var _xAxisRange2=_slicedToArray(_xAxisRange,2);var minX=_xAxisRange2[0];var maxX=_xAxisRange2[1];zoomCallback.call(_this3,minX,maxX,_this3.yAxisRanges());}});}; /** + * Transition function to use in animations. Returns values between 0.0 + * (totally old values) and 1.0 (totally new values) for each frame. + * @private + */Dygraph.zoomAnimationFunction = function(frame,numFrames){var k=1.5;return (1.0 - Math.pow(k,-frame)) / (1.0 - Math.pow(k,-numFrames));}; /** + * Reset the zoom to the original view coordinates. This is the same as + * double-clicking on the graph. + */Dygraph.prototype.resetZoom = function(){var _this4=this;var dirtyX=this.isZoomed('x');var dirtyY=this.isZoomed('y');var dirty=dirtyX || dirtyY; // Clear any selection, since it's likely to be drawn in the wrong place. +this.clearSelection();if(!dirty)return; // Calculate extremes to avoid lack of padding on reset. +var _xAxisExtremes=this.xAxisExtremes();var _xAxisExtremes2=_slicedToArray(_xAxisExtremes,2);var minDate=_xAxisExtremes2[0];var maxDate=_xAxisExtremes2[1];var animatedZooms=this.getBooleanOption('animatedZooms');var zoomCallback=this.getFunctionOption('zoomCallback'); // TODO(danvk): merge this block w/ the code below. +if(!animatedZooms){this.dateWindow_ = null;this.axes_.forEach(function(axis){if(axis.valueRange)delete axis.valueRange;});this.drawGraph_();if(zoomCallback){zoomCallback.call(this,minDate,maxDate,this.yAxisRanges());}return;}var oldWindow=null,newWindow=null,oldValueRanges=null,newValueRanges=null;if(dirtyX){oldWindow = this.xAxisRange();newWindow = [minDate,maxDate];}if(dirtyY){oldValueRanges = this.yAxisRanges();newValueRanges = this.yAxisExtremes();}this.doAnimatedZoom(oldWindow,newWindow,oldValueRanges,newValueRanges,function(){_this4.dateWindow_ = null;_this4.axes_.forEach(function(axis){if(axis.valueRange)delete axis.valueRange;});if(zoomCallback){zoomCallback.call(_this4,minDate,maxDate,_this4.yAxisRanges());}});}; /** + * Combined animation logic for all zoom functions. + * either the x parameters or y parameters may be null. + * @private + */Dygraph.prototype.doAnimatedZoom = function(oldXRange,newXRange,oldYRanges,newYRanges,callback){var _this5=this;var steps=this.getBooleanOption("animatedZooms")?Dygraph.ANIMATION_STEPS:1;var windows=[];var valueRanges=[];var step,frac;if(oldXRange !== null && newXRange !== null){for(step = 1;step <= steps;step++) {frac = Dygraph.zoomAnimationFunction(step,steps);windows[step - 1] = [oldXRange[0] * (1 - frac) + frac * newXRange[0],oldXRange[1] * (1 - frac) + frac * newXRange[1]];}}if(oldYRanges !== null && newYRanges !== null){for(step = 1;step <= steps;step++) {frac = Dygraph.zoomAnimationFunction(step,steps);var thisRange=[];for(var j=0;j < this.axes_.length;j++) {thisRange.push([oldYRanges[j][0] * (1 - frac) + frac * newYRanges[j][0],oldYRanges[j][1] * (1 - frac) + frac * newYRanges[j][1]]);}valueRanges[step - 1] = thisRange;}}utils.repeatAndCleanup(function(step){if(valueRanges.length){for(var i=0;i < _this5.axes_.length;i++) {var w=valueRanges[step][i];_this5.axes_[i].valueRange = [w[0],w[1]];}}if(windows.length){_this5.dateWindow_ = windows[step];}_this5.drawGraph_();},steps,Dygraph.ANIMATION_DURATION / steps,callback);}; /** + * Get the current graph's area object. + * + * Returns: {x, y, w, h} + */Dygraph.prototype.getArea = function(){return this.plotter_.area;}; /** + * Convert a mouse event to DOM coordinates relative to the graph origin. + * + * Returns a two-element array: [X, Y]. + */Dygraph.prototype.eventToDomCoords = function(event){if(event.offsetX && event.offsetY){return [event.offsetX,event.offsetY];}else {var eventElementPos=utils.findPos(this.mouseEventElement_);var canvasx=utils.pageX(event) - eventElementPos.x;var canvasy=utils.pageY(event) - eventElementPos.y;return [canvasx,canvasy];}}; /** + * Given a canvas X coordinate, find the closest row. + * @param {number} domX graph-relative DOM X coordinate + * Returns {number} row number. + * @private + */Dygraph.prototype.findClosestRow = function(domX){var minDistX=Infinity;var closestRow=-1;var sets=this.layout_.points;for(var i=0;i < sets.length;i++) {var points=sets[i];var len=points.length;for(var j=0;j < len;j++) {var point=points[j];if(!utils.isValidPoint(point,true))continue;var dist=Math.abs(point.canvasx - domX);if(dist < minDistX){minDistX = dist;closestRow = point.idx;}}}return closestRow;}; /** + * Given canvas X,Y coordinates, find the closest point. + * + * This finds the individual data point across all visible series + * that's closest to the supplied DOM coordinates using the standard + * Euclidean X,Y distance. + * + * @param {number} domX graph-relative DOM X coordinate + * @param {number} domY graph-relative DOM Y coordinate + * Returns: {row, seriesName, point} + * @private + */Dygraph.prototype.findClosestPoint = function(domX,domY){var minDist=Infinity;var dist,dx,dy,point,closestPoint,closestSeries,closestRow;for(var setIdx=this.layout_.points.length - 1;setIdx >= 0;--setIdx) {var points=this.layout_.points[setIdx];for(var i=0;i < points.length;++i) {point = points[i];if(!utils.isValidPoint(point))continue;dx = point.canvasx - domX;dy = point.canvasy - domY;dist = dx * dx + dy * dy;if(dist < minDist){minDist = dist;closestPoint = point;closestSeries = setIdx;closestRow = point.idx;}}}var name=this.layout_.setNames[closestSeries];return {row:closestRow,seriesName:name,point:closestPoint};}; /** + * Given canvas X,Y coordinates, find the touched area in a stacked graph. + * + * This first finds the X data point closest to the supplied DOM X coordinate, + * then finds the series which puts the Y coordinate on top of its filled area, + * using linear interpolation between adjacent point pairs. + * + * @param {number} domX graph-relative DOM X coordinate + * @param {number} domY graph-relative DOM Y coordinate + * Returns: {row, seriesName, point} + * @private + */Dygraph.prototype.findStackedPoint = function(domX,domY){var row=this.findClosestRow(domX);var closestPoint,closestSeries;for(var setIdx=0;setIdx < this.layout_.points.length;++setIdx) {var boundary=this.getLeftBoundary_(setIdx);var rowIdx=row - boundary;var points=this.layout_.points[setIdx];if(rowIdx >= points.length)continue;var p1=points[rowIdx];if(!utils.isValidPoint(p1))continue;var py=p1.canvasy;if(domX > p1.canvasx && rowIdx + 1 < points.length){ // interpolate series Y value using next point +var p2=points[rowIdx + 1];if(utils.isValidPoint(p2)){var dx=p2.canvasx - p1.canvasx;if(dx > 0){var r=(domX - p1.canvasx) / dx;py += r * (p2.canvasy - p1.canvasy);}}}else if(domX < p1.canvasx && rowIdx > 0){ // interpolate series Y value using previous point +var p0=points[rowIdx - 1];if(utils.isValidPoint(p0)){var dx=p1.canvasx - p0.canvasx;if(dx > 0){var r=(p1.canvasx - domX) / dx;py += r * (p0.canvasy - p1.canvasy);}}} // Stop if the point (domX, py) is above this series' upper edge +if(setIdx === 0 || py < domY){closestPoint = p1;closestSeries = setIdx;}}var name=this.layout_.setNames[closestSeries];return {row:row,seriesName:name,point:closestPoint};}; /** + * When the mouse moves in the canvas, display information about a nearby data + * point and draw dots over those points in the data series. This function + * takes care of cleanup of previously-drawn dots. + * @param {Object} event The mousemove event from the browser. + * @private + */Dygraph.prototype.mouseMove_ = function(event){ // This prevents JS errors when mousing over the canvas before data loads. +var points=this.layout_.points;if(points === undefined || points === null)return;var canvasCoords=this.eventToDomCoords(event);var canvasx=canvasCoords[0];var canvasy=canvasCoords[1];var highlightSeriesOpts=this.getOption("highlightSeriesOpts");var selectionChanged=false;if(highlightSeriesOpts && !this.isSeriesLocked()){var closest;if(this.getBooleanOption("stackedGraph")){closest = this.findStackedPoint(canvasx,canvasy);}else {closest = this.findClosestPoint(canvasx,canvasy);}selectionChanged = this.setSelection(closest.row,closest.seriesName);}else {var idx=this.findClosestRow(canvasx);selectionChanged = this.setSelection(idx);}var callback=this.getFunctionOption("highlightCallback");if(callback && selectionChanged){callback.call(this,event,this.lastx_,this.selPoints_,this.lastRow_,this.highlightSet_);}}; /** + * Fetch left offset from the specified set index or if not passed, the + * first defined boundaryIds record (see bug #236). + * @private + */Dygraph.prototype.getLeftBoundary_ = function(setIdx){if(this.boundaryIds_[setIdx]){return this.boundaryIds_[setIdx][0];}else {for(var i=0;i < this.boundaryIds_.length;i++) {if(this.boundaryIds_[i] !== undefined){return this.boundaryIds_[i][0];}}return 0;}};Dygraph.prototype.animateSelection_ = function(direction){var totalSteps=10;var millis=30;if(this.fadeLevel === undefined)this.fadeLevel = 0;if(this.animateId === undefined)this.animateId = 0;var start=this.fadeLevel;var steps=direction < 0?start:totalSteps - start;if(steps <= 0){if(this.fadeLevel){this.updateSelection_(1.0);}return;}var thisId=++this.animateId;var that=this;var cleanupIfClearing=function cleanupIfClearing(){ // if we haven't reached fadeLevel 0 in the max frame time, +// ensure that the clear happens and just go to 0 +if(that.fadeLevel !== 0 && direction < 0){that.fadeLevel = 0;that.clearSelection();}};utils.repeatAndCleanup(function(n){ // ignore simultaneous animations +if(that.animateId != thisId)return;that.fadeLevel += direction;if(that.fadeLevel === 0){that.clearSelection();}else {that.updateSelection_(that.fadeLevel / totalSteps);}},steps,millis,cleanupIfClearing);}; /** + * Draw dots over the selectied points in the data series. This function + * takes care of cleanup of previously-drawn dots. + * @private + */Dygraph.prototype.updateSelection_ = function(opt_animFraction){ /*var defaultPrevented = */this.cascadeEvents_('select',{selectedRow:this.lastRow_ === -1?undefined:this.lastRow_,selectedX:this.lastx_ === -1?undefined:this.lastx_,selectedPoints:this.selPoints_}); // TODO(danvk): use defaultPrevented here? +// Clear the previously drawn vertical, if there is one +var i;var ctx=this.canvas_ctx_;if(this.getOption('highlightSeriesOpts')){ctx.clearRect(0,0,this.width_,this.height_);var alpha=1.0 - this.getNumericOption('highlightSeriesBackgroundAlpha');var backgroundColor=utils.toRGB_(this.getOption('highlightSeriesBackgroundColor'));if(alpha){ // Activating background fade includes an animation effect for a gradual +// fade. TODO(klausw): make this independently configurable if it causes +// issues? Use a shared preference to control animations? +var animateBackgroundFade=true;if(animateBackgroundFade){if(opt_animFraction === undefined){ // start a new animation +this.animateSelection_(1);return;}alpha *= opt_animFraction;}ctx.fillStyle = 'rgba(' + backgroundColor.r + ',' + backgroundColor.g + ',' + backgroundColor.b + ',' + alpha + ')';ctx.fillRect(0,0,this.width_,this.height_);} // Redraw only the highlighted series in the interactive canvas (not the +// static plot canvas, which is where series are usually drawn). +this.plotter_._renderLineChart(this.highlightSet_,ctx);}else if(this.previousVerticalX_ >= 0){ // Determine the maximum highlight circle size. +var maxCircleSize=0;var labels=this.attr_('labels');for(i = 1;i < labels.length;i++) {var r=this.getNumericOption('highlightCircleSize',labels[i]);if(r > maxCircleSize)maxCircleSize = r;}var px=this.previousVerticalX_;ctx.clearRect(px - maxCircleSize - 1,0,2 * maxCircleSize + 2,this.height_);}if(this.selPoints_.length > 0){ // Draw colored circles over the center of each selected point +var canvasx=this.selPoints_[0].canvasx;ctx.save();for(i = 0;i < this.selPoints_.length;i++) {var pt=this.selPoints_[i];if(isNaN(pt.canvasy))continue;var circleSize=this.getNumericOption('highlightCircleSize',pt.name);var callback=this.getFunctionOption("drawHighlightPointCallback",pt.name);var color=this.plotter_.colors[pt.name];if(!callback){callback = utils.Circles.DEFAULT;}ctx.lineWidth = this.getNumericOption('strokeWidth',pt.name);ctx.strokeStyle = color;ctx.fillStyle = color;callback.call(this,this,pt.name,ctx,canvasx,pt.canvasy,color,circleSize,pt.idx);}ctx.restore();this.previousVerticalX_ = canvasx;}}; /** + * Manually set the selected points and display information about them in the + * legend. The selection can be cleared using clearSelection() and queried + * using getSelection(). + * + * To set a selected series but not a selected point, call setSelection with + * row=false and the selected series name. + * + * @param {number} row Row number that should be highlighted (i.e. appear with + * hover dots on the chart). + * @param {seriesName} optional series name to highlight that series with the + * the highlightSeriesOpts setting. + * @param { locked } optional If true, keep seriesName selected when mousing + * over the graph, disabling closest-series highlighting. Call clearSelection() + * to unlock it. + */Dygraph.prototype.setSelection = function(row,opt_seriesName,opt_locked){ // Extract the points we've selected +this.selPoints_ = [];var changed=false;if(row !== false && row >= 0){if(row != this.lastRow_)changed = true;this.lastRow_ = row;for(var setIdx=0;setIdx < this.layout_.points.length;++setIdx) {var points=this.layout_.points[setIdx]; // Check if the point at the appropriate index is the point we're looking +// for. If it is, just use it, otherwise search the array for a point +// in the proper place. +var setRow=row - this.getLeftBoundary_(setIdx);if(setRow >= 0 && setRow < points.length && points[setRow].idx == row){var point=points[setRow];if(point.yval !== null)this.selPoints_.push(point);}else {for(var pointIdx=0;pointIdx < points.length;++pointIdx) {var point=points[pointIdx];if(point.idx == row){if(point.yval !== null){this.selPoints_.push(point);}break;}}}}}else {if(this.lastRow_ >= 0)changed = true;this.lastRow_ = -1;}if(this.selPoints_.length){this.lastx_ = this.selPoints_[0].xval;}else {this.lastx_ = -1;}if(opt_seriesName !== undefined){if(this.highlightSet_ !== opt_seriesName)changed = true;this.highlightSet_ = opt_seriesName;}if(opt_locked !== undefined){this.lockedSet_ = opt_locked;}if(changed){this.updateSelection_(undefined);}return changed;}; /** + * The mouse has left the canvas. Clear out whatever artifacts remain + * @param {Object} event the mouseout event from the browser. + * @private + */Dygraph.prototype.mouseOut_ = function(event){if(this.getFunctionOption("unhighlightCallback")){this.getFunctionOption("unhighlightCallback").call(this,event);}if(this.getBooleanOption("hideOverlayOnMouseOut") && !this.lockedSet_){this.clearSelection();}}; /** + * Clears the current selection (i.e. points that were highlighted by moving + * the mouse over the chart). + */Dygraph.prototype.clearSelection = function(){this.cascadeEvents_('deselect',{});this.lockedSet_ = false; // Get rid of the overlay data +if(this.fadeLevel){this.animateSelection_(-1);return;}this.canvas_ctx_.clearRect(0,0,this.width_,this.height_);this.fadeLevel = 0;this.selPoints_ = [];this.lastx_ = -1;this.lastRow_ = -1;this.highlightSet_ = null;}; /** + * Returns the number of the currently selected row. To get data for this row, + * you can use the getValue method. + * @return {number} row number, or -1 if nothing is selected + */Dygraph.prototype.getSelection = function(){if(!this.selPoints_ || this.selPoints_.length < 1){return -1;}for(var setIdx=0;setIdx < this.layout_.points.length;setIdx++) {var points=this.layout_.points[setIdx];for(var row=0;row < points.length;row++) {if(points[row].x == this.selPoints_[0].x){return points[row].idx;}}}return -1;}; /** + * Returns the name of the currently-highlighted series. + * Only available when the highlightSeriesOpts option is in use. + */Dygraph.prototype.getHighlightSeries = function(){return this.highlightSet_;}; /** + * Returns true if the currently-highlighted series was locked + * via setSelection(..., seriesName, true). + */Dygraph.prototype.isSeriesLocked = function(){return this.lockedSet_;}; /** + * Fires when there's data available to be graphed. + * @param {string} data Raw CSV data to be plotted + * @private + */Dygraph.prototype.loadedEvent_ = function(data){this.rawData_ = this.parseCSV_(data);this.cascadeDataDidUpdateEvent_();this.predraw_();}; /** + * Add ticks on the x-axis representing years, months, quarters, weeks, or days + * @private + */Dygraph.prototype.addXTicks_ = function(){ // Determine the correct ticks scale on the x-axis: quarterly, monthly, ... +var range;if(this.dateWindow_){range = [this.dateWindow_[0],this.dateWindow_[1]];}else {range = this.xAxisExtremes();}var xAxisOptionsView=this.optionsViewForAxis_('x');var xTicks=xAxisOptionsView('ticker')(range[0],range[1],this.plotter_.area.w, // TODO(danvk): should be area.width +xAxisOptionsView,this); // var msg = 'ticker(' + range[0] + ', ' + range[1] + ', ' + this.width_ + ', ' + this.attr_('pixelsPerXLabel') + ') -> ' + JSON.stringify(xTicks); +// console.log(msg); +this.layout_.setXTicks(xTicks);}; /** + * Returns the correct handler class for the currently set options. + * @private + */Dygraph.prototype.getHandlerClass_ = function(){var handlerClass;if(this.attr_('dataHandler')){handlerClass = this.attr_('dataHandler');}else if(this.fractions_){if(this.getBooleanOption('errorBars')){handlerClass = _datahandlerBarsFractions2['default'];}else {handlerClass = _datahandlerDefaultFractions2['default'];}}else if(this.getBooleanOption('customBars')){handlerClass = _datahandlerBarsCustom2['default'];}else if(this.getBooleanOption('errorBars')){handlerClass = _datahandlerBarsError2['default'];}else {handlerClass = _datahandlerDefault2['default'];}return handlerClass;}; /** + * @private + * This function is called once when the chart's data is changed or the options + * dictionary is updated. It is _not_ called when the user pans or zooms. The + * idea is that values derived from the chart's data can be computed here, + * rather than every time the chart is drawn. This includes things like the + * number of axes, rolling averages, etc. + */Dygraph.prototype.predraw_ = function(){var start=new Date(); // Create the correct dataHandler +this.dataHandler_ = new (this.getHandlerClass_())();this.layout_.computePlotArea(); // TODO(danvk): move more computations out of drawGraph_ and into here. +this.computeYAxes_();if(!this.is_initial_draw_){this.canvas_ctx_.restore();this.hidden_ctx_.restore();}this.canvas_ctx_.save();this.hidden_ctx_.save(); // Create a new plotter. +this.plotter_ = new _dygraphCanvas2['default'](this,this.hidden_,this.hidden_ctx_,this.layout_); // The roller sits in the bottom left corner of the chart. We don't know where +// this will be until the options are available, so it's positioned here. +this.createRollInterface_();this.cascadeEvents_('predraw'); // Convert the raw data (a 2D array) into the internal format and compute +// rolling averages. +this.rolledSeries_ = [null]; // x-axis is the first series and it's special +for(var i=1;i < this.numColumns();i++) { // var logScale = this.attr_('logscale', i); // TODO(klausw): this looks wrong // konigsberg thinks so too. +var series=this.dataHandler_.extractSeries(this.rawData_,i,this.attributes_);if(this.rollPeriod_ > 1){series = this.dataHandler_.rollingAverage(series,this.rollPeriod_,this.attributes_);}this.rolledSeries_.push(series);} // If the data or options have changed, then we'd better redraw. +this.drawGraph_(); // This is used to determine whether to do various animations. +var end=new Date();this.drawingTimeMs_ = end - start;}; /** + * Point structure. + * + * xval_* and yval_* are the original unscaled data values, + * while x_* and y_* are scaled to the range (0.0-1.0) for plotting. + * yval_stacked is the cumulative Y value used for stacking graphs, + * and bottom/top/minus/plus are used for error bar graphs. + * + * @typedef {{ + * idx: number, + * name: string, + * x: ?number, + * xval: ?number, + * y_bottom: ?number, + * y: ?number, + * y_stacked: ?number, + * y_top: ?number, + * yval_minus: ?number, + * yval: ?number, + * yval_plus: ?number, + * yval_stacked + * }} + */Dygraph.PointType = undefined; /** + * Calculates point stacking for stackedGraph=true. + * + * For stacking purposes, interpolate or extend neighboring data across + * NaN values based on stackedGraphNaNFill settings. This is for display + * only, the underlying data value as shown in the legend remains NaN. + * + * @param {Array.} points Point array for a single series. + * Updates each Point's yval_stacked property. + * @param {Array.} cumulativeYval Accumulated top-of-graph stacked Y + * values for the series seen so far. Index is the row number. Updated + * based on the current series's values. + * @param {Array.} seriesExtremes Min and max values, updated + * to reflect the stacked values. + * @param {string} fillMethod Interpolation method, one of 'all', 'inside', or + * 'none'. + * @private + */Dygraph.stackPoints_ = function(points,cumulativeYval,seriesExtremes,fillMethod){var lastXval=null;var prevPoint=null;var nextPoint=null;var nextPointIdx=-1; // Find the next stackable point starting from the given index. +var updateNextPoint=function updateNextPoint(idx){ // If we've previously found a non-NaN point and haven't gone past it yet, +// just use that. +if(nextPointIdx >= idx)return; // We haven't found a non-NaN point yet or have moved past it, +// look towards the right to find a non-NaN point. +for(var j=idx;j < points.length;++j) { // Clear out a previously-found point (if any) since it's no longer +// valid, we shouldn't use it for interpolation anymore. +nextPoint = null;if(!isNaN(points[j].yval) && points[j].yval !== null){nextPointIdx = j;nextPoint = points[j];break;}}};for(var i=0;i < points.length;++i) {var point=points[i];var xval=point.xval;if(cumulativeYval[xval] === undefined){cumulativeYval[xval] = 0;}var actualYval=point.yval;if(isNaN(actualYval) || actualYval === null){if(fillMethod == 'none'){actualYval = 0;}else { // Interpolate/extend for stacking purposes if possible. +updateNextPoint(i);if(prevPoint && nextPoint && fillMethod != 'none'){ // Use linear interpolation between prevPoint and nextPoint. +actualYval = prevPoint.yval + (nextPoint.yval - prevPoint.yval) * ((xval - prevPoint.xval) / (nextPoint.xval - prevPoint.xval));}else if(prevPoint && fillMethod == 'all'){actualYval = prevPoint.yval;}else if(nextPoint && fillMethod == 'all'){actualYval = nextPoint.yval;}else {actualYval = 0;}}}else {prevPoint = point;}var stackedYval=cumulativeYval[xval];if(lastXval != xval){ // If an x-value is repeated, we ignore the duplicates. +stackedYval += actualYval;cumulativeYval[xval] = stackedYval;}lastXval = xval;point.yval_stacked = stackedYval;if(stackedYval > seriesExtremes[1]){seriesExtremes[1] = stackedYval;}if(stackedYval < seriesExtremes[0]){seriesExtremes[0] = stackedYval;}}}; /** + * Loop over all fields and create datasets, calculating extreme y-values for + * each series and extreme x-indices as we go. + * + * dateWindow is passed in as an explicit parameter so that we can compute + * extreme values "speculatively", i.e. without actually setting state on the + * dygraph. + * + * @param {Array.)>>} rolledSeries, where + * rolledSeries[seriesIndex][row] = raw point, where + * seriesIndex is the column number starting with 1, and + * rawPoint is [x,y] or [x, [y, err]] or [x, [y, yminus, yplus]]. + * @param {?Array.} dateWindow [xmin, xmax] pair, or null. + * @return {{ + * points: Array.>, + * seriesExtremes: Array.>, + * boundaryIds: Array.}} + * @private + */Dygraph.prototype.gatherDatasets_ = function(rolledSeries,dateWindow){var boundaryIds=[];var points=[];var cumulativeYval=[]; // For stacked series. +var extremes={}; // series name -> [low, high] +var seriesIdx,sampleIdx;var firstIdx,lastIdx;var axisIdx; // Loop over the fields (series). Go from the last to the first, +// because if they're stacked that's how we accumulate the values. +var num_series=rolledSeries.length - 1;var series;for(seriesIdx = num_series;seriesIdx >= 1;seriesIdx--) {if(!this.visibility()[seriesIdx - 1])continue; // Prune down to the desired range, if necessary (for zooming) +// Because there can be lines going to points outside of the visible area, +// we actually prune to visible points, plus one on either side. +if(dateWindow){series = rolledSeries[seriesIdx];var low=dateWindow[0];var high=dateWindow[1]; // TODO(danvk): do binary search instead of linear search. +// TODO(danvk): pass firstIdx and lastIdx directly to the renderer. +firstIdx = null;lastIdx = null;for(sampleIdx = 0;sampleIdx < series.length;sampleIdx++) {if(series[sampleIdx][0] >= low && firstIdx === null){firstIdx = sampleIdx;}if(series[sampleIdx][0] <= high){lastIdx = sampleIdx;}}if(firstIdx === null)firstIdx = 0;var correctedFirstIdx=firstIdx;var isInvalidValue=true;while(isInvalidValue && correctedFirstIdx > 0) {correctedFirstIdx--; // check if the y value is null. +isInvalidValue = series[correctedFirstIdx][1] === null;}if(lastIdx === null)lastIdx = series.length - 1;var correctedLastIdx=lastIdx;isInvalidValue = true;while(isInvalidValue && correctedLastIdx < series.length - 1) {correctedLastIdx++;isInvalidValue = series[correctedLastIdx][1] === null;}if(correctedFirstIdx !== firstIdx){firstIdx = correctedFirstIdx;}if(correctedLastIdx !== lastIdx){lastIdx = correctedLastIdx;}boundaryIds[seriesIdx - 1] = [firstIdx,lastIdx]; // .slice's end is exclusive, we want to include lastIdx. +series = series.slice(firstIdx,lastIdx + 1);}else {series = rolledSeries[seriesIdx];boundaryIds[seriesIdx - 1] = [0,series.length - 1];}var seriesName=this.attr_("labels")[seriesIdx];var seriesExtremes=this.dataHandler_.getExtremeYValues(series,dateWindow,this.getBooleanOption("stepPlot",seriesName));var seriesPoints=this.dataHandler_.seriesToPoints(series,seriesName,boundaryIds[seriesIdx - 1][0]);if(this.getBooleanOption("stackedGraph")){axisIdx = this.attributes_.axisForSeries(seriesName);if(cumulativeYval[axisIdx] === undefined){cumulativeYval[axisIdx] = [];}Dygraph.stackPoints_(seriesPoints,cumulativeYval[axisIdx],seriesExtremes,this.getBooleanOption("stackedGraphNaNFill"));}extremes[seriesName] = seriesExtremes;points[seriesIdx] = seriesPoints;}return {points:points,extremes:extremes,boundaryIds:boundaryIds};}; /** + * Update the graph with new data. This method is called when the viewing area + * has changed. If the underlying data or options have changed, predraw_ will + * be called before drawGraph_ is called. + * + * @private + */Dygraph.prototype.drawGraph_ = function(){var start=new Date(); // This is used to set the second parameter to drawCallback, below. +var is_initial_draw=this.is_initial_draw_;this.is_initial_draw_ = false;this.layout_.removeAllDatasets();this.setColors_();this.attrs_.pointSize = 0.5 * this.getNumericOption('highlightCircleSize');var packed=this.gatherDatasets_(this.rolledSeries_,this.dateWindow_);var points=packed.points;var extremes=packed.extremes;this.boundaryIds_ = packed.boundaryIds;this.setIndexByName_ = {};var labels=this.attr_("labels");var dataIdx=0;for(var i=1;i < points.length;i++) {if(!this.visibility()[i - 1])continue;this.layout_.addDataset(labels[i],points[i]);this.datasetIndex_[i] = dataIdx++;}for(var i=0;i < labels.length;i++) {this.setIndexByName_[labels[i]] = i;}this.computeYAxisRanges_(extremes);this.layout_.setYAxes(this.axes_);this.addXTicks_(); // Tell PlotKit to use this new data and render itself +this.layout_.evaluate();this.renderGraph_(is_initial_draw);if(this.getStringOption("timingName")){var end=new Date();console.log(this.getStringOption("timingName") + " - drawGraph: " + (end - start) + "ms");}}; /** + * This does the work of drawing the chart. It assumes that the layout and axis + * scales have already been set (e.g. by predraw_). + * + * @private + */Dygraph.prototype.renderGraph_ = function(is_initial_draw){this.cascadeEvents_('clearChart');this.plotter_.clear();var underlayCallback=this.getFunctionOption('underlayCallback');if(underlayCallback){ // NOTE: we pass the dygraph object to this callback twice to avoid breaking +// users who expect a deprecated form of this callback. +underlayCallback.call(this,this.hidden_ctx_,this.layout_.getPlotArea(),this,this);}var e={canvas:this.hidden_,drawingContext:this.hidden_ctx_};this.cascadeEvents_('willDrawChart',e);this.plotter_.render();this.cascadeEvents_('didDrawChart',e);this.lastRow_ = -1; // because plugins/legend.js clears the legend +// TODO(danvk): is this a performance bottleneck when panning? +// The interaction canvas should already be empty in that situation. +this.canvas_.getContext('2d').clearRect(0,0,this.width_,this.height_);var drawCallback=this.getFunctionOption("drawCallback");if(drawCallback !== null){drawCallback.call(this,this,is_initial_draw);}if(is_initial_draw){this.readyFired_ = true;while(this.readyFns_.length > 0) {var fn=this.readyFns_.pop();fn(this);}}}; /** + * @private + * Determine properties of the y-axes which are independent of the data + * currently being displayed. This includes things like the number of axes and + * the style of the axes. It does not include the range of each axis and its + * tick marks. + * This fills in this.axes_. + * axes_ = [ { options } ] + * indices are into the axes_ array. + */Dygraph.prototype.computeYAxes_ = function(){var axis,index,opts,v; // this.axes_ doesn't match this.attributes_.axes_.options. It's used for +// data computation as well as options storage. +// Go through once and add all the axes. +this.axes_ = [];for(axis = 0;axis < this.attributes_.numAxes();axis++) { // Add a new axis, making a copy of its per-axis options. +opts = {g:this};utils.update(opts,this.attributes_.axisOptions(axis));this.axes_[axis] = opts;}for(axis = 0;axis < this.axes_.length;axis++) {if(axis === 0){opts = this.optionsViewForAxis_('y' + (axis?'2':''));v = opts("valueRange");if(v)this.axes_[axis].valueRange = v;}else { // To keep old behavior +var axes=this.user_attrs_.axes;if(axes && axes.y2){v = axes.y2.valueRange;if(v)this.axes_[axis].valueRange = v;}}}}; /** + * Returns the number of y-axes on the chart. + * @return {number} the number of axes. + */Dygraph.prototype.numAxes = function(){return this.attributes_.numAxes();}; /** + * @private + * Returns axis properties for the given series. + * @param {string} setName The name of the series for which to get axis + * properties, e.g. 'Y1'. + * @return {Object} The axis properties. + */Dygraph.prototype.axisPropertiesForSeries = function(series){ // TODO(danvk): handle errors. +return this.axes_[this.attributes_.axisForSeries(series)];}; /** + * @private + * Determine the value range and tick marks for each axis. + * @param {Object} extremes A mapping from seriesName -> [low, high] + * This fills in the valueRange and ticks fields in each entry of this.axes_. + */Dygraph.prototype.computeYAxisRanges_ = function(extremes){var isNullUndefinedOrNaN=function isNullUndefinedOrNaN(num){return isNaN(parseFloat(num));};var numAxes=this.attributes_.numAxes();var ypadCompat,span,series,ypad;var p_axis; // Compute extreme values, a span and tick marks for each axis. +for(var i=0;i < numAxes;i++) {var axis=this.axes_[i];var logscale=this.attributes_.getForAxis("logscale",i);var includeZero=this.attributes_.getForAxis("includeZero",i);var independentTicks=this.attributes_.getForAxis("independentTicks",i);series = this.attributes_.seriesForAxis(i); // Add some padding. This supports two Y padding operation modes: +// +// - backwards compatible (yRangePad not set): +// 10% padding for automatic Y ranges, but not for user-supplied +// ranges, and move a close-to-zero edge to zero, since drawing at the edge +// results in invisible lines. Unfortunately lines drawn at the edge of a +// user-supplied range will still be invisible. If logscale is +// set, add a variable amount of padding at the top but +// none at the bottom. +// +// - new-style (yRangePad set by the user): +// always add the specified Y padding. +// +ypadCompat = true;ypad = 0.1; // add 10% +var yRangePad=this.getNumericOption('yRangePad');if(yRangePad !== null){ypadCompat = false; // Convert pixel padding to ratio +ypad = yRangePad / this.plotter_.area.h;}if(series.length === 0){ // If no series are defined or visible then use a reasonable default +axis.extremeRange = [0,1];}else { // Calculate the extremes of extremes. +var minY=Infinity; // extremes[series[0]][0]; +var maxY=-Infinity; // extremes[series[0]][1]; +var extremeMinY,extremeMaxY;for(var j=0;j < series.length;j++) { // this skips invisible series +if(!extremes.hasOwnProperty(series[j]))continue; // Only use valid extremes to stop null data series' from corrupting the scale. +extremeMinY = extremes[series[j]][0];if(extremeMinY !== null){minY = Math.min(extremeMinY,minY);}extremeMaxY = extremes[series[j]][1];if(extremeMaxY !== null){maxY = Math.max(extremeMaxY,maxY);}} // Include zero if requested by the user. +if(includeZero && !logscale){if(minY > 0)minY = 0;if(maxY < 0)maxY = 0;} // Ensure we have a valid scale, otherwise default to [0, 1] for safety. +if(minY == Infinity)minY = 0;if(maxY == -Infinity)maxY = 1;span = maxY - minY; // special case: if we have no sense of scale, center on the sole value. +if(span === 0){if(maxY !== 0){span = Math.abs(maxY);}else { // ... and if the sole value is zero, use range 0-1. +maxY = 1;span = 1;}}var maxAxisY=maxY,minAxisY=minY;if(ypadCompat){if(logscale){maxAxisY = maxY + ypad * span;minAxisY = minY;}else {maxAxisY = maxY + ypad * span;minAxisY = minY - ypad * span; // Backwards-compatible behavior: Move the span to start or end at zero if it's +// close to zero. +if(minAxisY < 0 && minY >= 0)minAxisY = 0;if(maxAxisY > 0 && maxY <= 0)maxAxisY = 0;}}axis.extremeRange = [minAxisY,maxAxisY];}if(axis.valueRange){ // This is a user-set value range for this axis. +var y0=isNullUndefinedOrNaN(axis.valueRange[0])?axis.extremeRange[0]:axis.valueRange[0];var y1=isNullUndefinedOrNaN(axis.valueRange[1])?axis.extremeRange[1]:axis.valueRange[1];axis.computedValueRange = [y0,y1];}else {axis.computedValueRange = axis.extremeRange;}if(!ypadCompat){ // When using yRangePad, adjust the upper/lower bounds to add +// padding unless the user has zoomed/panned the Y axis range. +if(logscale){y0 = axis.computedValueRange[0];y1 = axis.computedValueRange[1];var y0pct=ypad / (2 * ypad - 1);var y1pct=(ypad - 1) / (2 * ypad - 1);axis.computedValueRange[0] = utils.logRangeFraction(y0,y1,y0pct);axis.computedValueRange[1] = utils.logRangeFraction(y0,y1,y1pct);}else {y0 = axis.computedValueRange[0];y1 = axis.computedValueRange[1];span = y1 - y0;axis.computedValueRange[0] = y0 - span * ypad;axis.computedValueRange[1] = y1 + span * ypad;}}if(independentTicks){axis.independentTicks = independentTicks;var opts=this.optionsViewForAxis_('y' + (i?'2':''));var ticker=opts('ticker');axis.ticks = ticker(axis.computedValueRange[0],axis.computedValueRange[1],this.plotter_.area.h,opts,this); // Define the first independent axis as primary axis. +if(!p_axis)p_axis = axis;}}if(p_axis === undefined){throw "Configuration Error: At least one axis has to have the \"independentTicks\" option activated.";} // Add ticks. By default, all axes inherit the tick positions of the +// primary axis. However, if an axis is specifically marked as having +// independent ticks, then that is permissible as well. +for(var i=0;i < numAxes;i++) {var axis=this.axes_[i];if(!axis.independentTicks){var opts=this.optionsViewForAxis_('y' + (i?'2':''));var ticker=opts('ticker');var p_ticks=p_axis.ticks;var p_scale=p_axis.computedValueRange[1] - p_axis.computedValueRange[0];var scale=axis.computedValueRange[1] - axis.computedValueRange[0];var tick_values=[];for(var k=0;k < p_ticks.length;k++) {var y_frac=(p_ticks[k].v - p_axis.computedValueRange[0]) / p_scale;var y_val=axis.computedValueRange[0] + y_frac * scale;tick_values.push(y_val);}axis.ticks = ticker(axis.computedValueRange[0],axis.computedValueRange[1],this.plotter_.area.h,opts,this,tick_values);}}}; /** + * Detects the type of the str (date or numeric) and sets the various + * formatting attributes in this.attrs_ based on this type. + * @param {string} str An x value. + * @private + */Dygraph.prototype.detectTypeFromString_ = function(str){var isDate=false;var dashPos=str.indexOf('-'); // could be 2006-01-01 _or_ 1.0e-2 +if(dashPos > 0 && str[dashPos - 1] != 'e' && str[dashPos - 1] != 'E' || str.indexOf('/') >= 0 || isNaN(parseFloat(str))){isDate = true;}else if(str.length == 8 && str > '19700101' && str < '20371231'){ // TODO(danvk): remove support for this format. +isDate = true;}this.setXAxisOptions_(isDate);};Dygraph.prototype.setXAxisOptions_ = function(isDate){if(isDate){this.attrs_.xValueParser = utils.dateParser;this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;}else { /** @private (shut up, jsdoc!) */this.attrs_.xValueParser = function(x){return parseFloat(x);}; // TODO(danvk): use Dygraph.numberValueFormatter here? +/** @private (shut up, jsdoc!) */this.attrs_.axes.x.valueFormatter = function(x){return x;};this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;}}; /** + * @private + * Parses a string in a special csv format. We expect a csv file where each + * line is a date point, and the first field in each line is the date string. + * We also expect that all remaining fields represent series. + * if the errorBars attribute is set, then interpret the fields as: + * date, series1, stddev1, series2, stddev2, ... + * @param {[Object]} data See above. + * + * @return [Object] An array with one entry for each row. These entries + * are an array of cells in that row. The first entry is the parsed x-value for + * the row. The second, third, etc. are the y-values. These can take on one of + * three forms, depending on the CSV and constructor parameters: + * 1. numeric value + * 2. [ value, stddev ] + * 3. [ low value, center value, high value ] + */Dygraph.prototype.parseCSV_ = function(data){var ret=[];var line_delimiter=utils.detectLineDelimiter(data);var lines=data.split(line_delimiter || "\n");var vals,j; // Use the default delimiter or fall back to a tab if that makes sense. +var delim=this.getStringOption('delimiter');if(lines[0].indexOf(delim) == -1 && lines[0].indexOf('\t') >= 0){delim = '\t';}var start=0;if(!('labels' in this.user_attrs_)){ // User hasn't explicitly set labels, so they're (presumably) in the CSV. +start = 1;this.attrs_.labels = lines[0].split(delim); // NOTE: _not_ user_attrs_. +this.attributes_.reparseSeries();}var line_no=0;var xParser;var defaultParserSet=false; // attempt to auto-detect x value type +var expectedCols=this.attr_("labels").length;var outOfOrder=false;for(var i=start;i < lines.length;i++) {var line=lines[i];line_no = i;if(line.length === 0)continue; // skip blank lines +if(line[0] == '#')continue; // skip comment lines +var inFields=line.split(delim);if(inFields.length < 2)continue;var fields=[];if(!defaultParserSet){this.detectTypeFromString_(inFields[0]);xParser = this.getFunctionOption("xValueParser");defaultParserSet = true;}fields[0] = xParser(inFields[0],this); // If fractions are expected, parse the numbers as "A/B" +if(this.fractions_){for(j = 1;j < inFields.length;j++) { // TODO(danvk): figure out an appropriate way to flag parse errors. +vals = inFields[j].split("/");if(vals.length != 2){console.error('Expected fractional "num/den" values in CSV data ' + "but found a value '" + inFields[j] + "' on line " + (1 + i) + " ('" + line + "') which is not of this form.");fields[j] = [0,0];}else {fields[j] = [utils.parseFloat_(vals[0],i,line),utils.parseFloat_(vals[1],i,line)];}}}else if(this.getBooleanOption("errorBars")){ // If there are error bars, values are (value, stddev) pairs +if(inFields.length % 2 != 1){console.error('Expected alternating (value, stdev.) pairs in CSV data ' + 'but line ' + (1 + i) + ' has an odd number of values (' + (inFields.length - 1) + "): '" + line + "'");}for(j = 1;j < inFields.length;j += 2) {fields[(j + 1) / 2] = [utils.parseFloat_(inFields[j],i,line),utils.parseFloat_(inFields[j + 1],i,line)];}}else if(this.getBooleanOption("customBars")){ // Bars are a low;center;high tuple +for(j = 1;j < inFields.length;j++) {var val=inFields[j];if(/^ *$/.test(val)){fields[j] = [null,null,null];}else {vals = val.split(";");if(vals.length == 3){fields[j] = [utils.parseFloat_(vals[0],i,line),utils.parseFloat_(vals[1],i,line),utils.parseFloat_(vals[2],i,line)];}else {console.warn('When using customBars, values must be either blank ' + 'or "low;center;high" tuples (got "' + val + '" on line ' + (1 + i));}}}}else { // Values are just numbers +for(j = 1;j < inFields.length;j++) {fields[j] = utils.parseFloat_(inFields[j],i,line);}}if(ret.length > 0 && fields[0] < ret[ret.length - 1][0]){outOfOrder = true;}if(fields.length != expectedCols){console.error("Number of columns in line " + i + " (" + fields.length + ") does not agree with number of labels (" + expectedCols + ") " + line);} // If the user specified the 'labels' option and none of the cells of the +// first row parsed correctly, then they probably double-specified the +// labels. We go with the values set in the option, discard this row and +// log a warning to the JS console. +if(i === 0 && this.attr_('labels')){var all_null=true;for(j = 0;all_null && j < fields.length;j++) {if(fields[j])all_null = false;}if(all_null){console.warn("The dygraphs 'labels' option is set, but the first row " + "of CSV data ('" + line + "') appears to also contain " + "labels. Will drop the CSV labels and use the option " + "labels.");continue;}}ret.push(fields);}if(outOfOrder){console.warn("CSV is out of order; order it correctly to speed loading.");ret.sort(function(a,b){return a[0] - b[0];});}return ret;}; // In native format, all values must be dates or numbers. +// This check isn't perfect but will catch most mistaken uses of strings. +function validateNativeFormat(data){var firstRow=data[0];var firstX=firstRow[0];if(typeof firstX !== 'number' && !utils.isDateLike(firstX)){throw new Error('Expected number or date but got ' + typeof firstX + ': ' + firstX + '.');}for(var i=1;i < firstRow.length;i++) {var val=firstRow[i];if(val === null || val === undefined)continue;if(typeof val === 'number')continue;if(utils.isArrayLike(val))continue; // e.g. error bars or custom bars. +throw new Error('Expected number or array but got ' + typeof val + ': ' + val + '.');}} /** + * The user has provided their data as a pre-packaged JS array. If the x values + * are numeric, this is the same as dygraphs' internal format. If the x values + * are dates, we need to convert them from Date objects to ms since epoch. + * @param {!Array} data + * @return {Object} data with numeric x values. + * @private + */Dygraph.prototype.parseArray_ = function(data){ // Peek at the first x value to see if it's numeric. +if(data.length === 0){console.error("Can't plot empty data set");return null;}if(data[0].length === 0){console.error("Data set cannot contain an empty row");return null;}validateNativeFormat(data);var i;if(this.attr_("labels") === null){console.warn("Using default labels. Set labels explicitly via 'labels' " + "in the options parameter");this.attrs_.labels = ["X"];for(i = 1;i < data[0].length;i++) {this.attrs_.labels.push("Y" + i); // Not user_attrs_. +}this.attributes_.reparseSeries();}else {var num_labels=this.attr_("labels");if(num_labels.length != data[0].length){console.error("Mismatch between number of labels (" + num_labels + ")" + " and number of columns in array (" + data[0].length + ")");return null;}}if(utils.isDateLike(data[0][0])){ // Some intelligent defaults for a date x-axis. +this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter; // Assume they're all dates. +var parsedData=utils.clone(data);for(i = 0;i < data.length;i++) {if(parsedData[i].length === 0){console.error("Row " + (1 + i) + " of data is empty");return null;}if(parsedData[i][0] === null || typeof parsedData[i][0].getTime != 'function' || isNaN(parsedData[i][0].getTime())){console.error("x value in row " + (1 + i) + " is not a Date");return null;}parsedData[i][0] = parsedData[i][0].getTime();}return parsedData;}else { // Some intelligent defaults for a numeric x-axis. +/** @private (shut up, jsdoc!) */this.attrs_.axes.x.valueFormatter = function(x){return x;};this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;this.attrs_.axes.x.axisLabelFormatter = utils.numberAxisLabelFormatter;return data;}}; /** + * Parses a DataTable object from gviz. + * The data is expected to have a first column that is either a date or a + * number. All subsequent columns must be numbers. If there is a clear mismatch + * between this.xValueParser_ and the type of the first column, it will be + * fixed. Fills out rawData_. + * @param {!google.visualization.DataTable} data See above. + * @private + */Dygraph.prototype.parseDataTable_ = function(data){var shortTextForAnnotationNum=function shortTextForAnnotationNum(num){ // converts [0-9]+ [A-Z][a-z]* +// example: 0=A, 1=B, 25=Z, 26=Aa, 27=Ab +// and continues like.. Ba Bb .. Za .. Zz..Aaa...Zzz Aaaa Zzzz +var shortText=String.fromCharCode(65 /* A */ + num % 26);num = Math.floor(num / 26);while(num > 0) {shortText = String.fromCharCode(65 /* A */ + (num - 1) % 26) + shortText.toLowerCase();num = Math.floor((num - 1) / 26);}return shortText;};var cols=data.getNumberOfColumns();var rows=data.getNumberOfRows();var indepType=data.getColumnType(0);if(indepType == 'date' || indepType == 'datetime'){this.attrs_.xValueParser = utils.dateParser;this.attrs_.axes.x.valueFormatter = utils.dateValueFormatter;this.attrs_.axes.x.ticker = DygraphTickers.dateTicker;this.attrs_.axes.x.axisLabelFormatter = utils.dateAxisLabelFormatter;}else if(indepType == 'number'){this.attrs_.xValueParser = function(x){return parseFloat(x);};this.attrs_.axes.x.valueFormatter = function(x){return x;};this.attrs_.axes.x.ticker = DygraphTickers.numericTicks;this.attrs_.axes.x.axisLabelFormatter = this.attrs_.axes.x.valueFormatter;}else {throw new Error("only 'date', 'datetime' and 'number' types are supported " + "for column 1 of DataTable input (Got '" + indepType + "')");} // Array of the column indices which contain data (and not annotations). +var colIdx=[];var annotationCols={}; // data index -> [annotation cols] +var hasAnnotations=false;var i,j;for(i = 1;i < cols;i++) {var type=data.getColumnType(i);if(type == 'number'){colIdx.push(i);}else if(type == 'string' && this.getBooleanOption('displayAnnotations')){ // This is OK -- it's an annotation column. +var dataIdx=colIdx[colIdx.length - 1];if(!annotationCols.hasOwnProperty(dataIdx)){annotationCols[dataIdx] = [i];}else {annotationCols[dataIdx].push(i);}hasAnnotations = true;}else {throw new Error("Only 'number' is supported as a dependent type with Gviz." + " 'string' is only supported if displayAnnotations is true");}} // Read column labels +// TODO(danvk): add support back for errorBars +var labels=[data.getColumnLabel(0)];for(i = 0;i < colIdx.length;i++) {labels.push(data.getColumnLabel(colIdx[i]));if(this.getBooleanOption("errorBars"))i += 1;}this.attrs_.labels = labels;cols = labels.length;var ret=[];var outOfOrder=false;var annotations=[];for(i = 0;i < rows;i++) {var row=[];if(typeof data.getValue(i,0) === 'undefined' || data.getValue(i,0) === null){console.warn("Ignoring row " + i + " of DataTable because of undefined or null first column.");continue;}if(indepType == 'date' || indepType == 'datetime'){row.push(data.getValue(i,0).getTime());}else {row.push(data.getValue(i,0));}if(!this.getBooleanOption("errorBars")){for(j = 0;j < colIdx.length;j++) {var col=colIdx[j];row.push(data.getValue(i,col));if(hasAnnotations && annotationCols.hasOwnProperty(col) && data.getValue(i,annotationCols[col][0]) !== null){var ann={};ann.series = data.getColumnLabel(col);ann.xval = row[0];ann.shortText = shortTextForAnnotationNum(annotations.length);ann.text = '';for(var k=0;k < annotationCols[col].length;k++) {if(k)ann.text += "\n";ann.text += data.getValue(i,annotationCols[col][k]);}annotations.push(ann);}} // Strip out infinities, which give dygraphs problems later on. +for(j = 0;j < row.length;j++) {if(!isFinite(row[j]))row[j] = null;}}else {for(j = 0;j < cols - 1;j++) {row.push([data.getValue(i,1 + 2 * j),data.getValue(i,2 + 2 * j)]);}}if(ret.length > 0 && row[0] < ret[ret.length - 1][0]){outOfOrder = true;}ret.push(row);}if(outOfOrder){console.warn("DataTable is out of order; order it correctly to speed loading.");ret.sort(function(a,b){return a[0] - b[0];});}this.rawData_ = ret;if(annotations.length > 0){this.setAnnotations(annotations,true);}this.attributes_.reparseSeries();}; /** + * Signals to plugins that the chart data has updated. + * This happens after the data has updated but before the chart has redrawn. + * @private + */Dygraph.prototype.cascadeDataDidUpdateEvent_ = function(){ // TODO(danvk): there are some issues checking xAxisRange() and using +// toDomCoords from handlers of this event. The visible range should be set +// when the chart is drawn, not derived from the data. +this.cascadeEvents_('dataDidUpdate',{});}; /** + * Get the CSV data. If it's in a function, call that function. If it's in a + * file, do an XMLHttpRequest to get it. + * @private + */Dygraph.prototype.start_ = function(){var data=this.file_; // Functions can return references of all other types. +if(typeof data == 'function'){data = data();}if(utils.isArrayLike(data)){this.rawData_ = this.parseArray_(data);this.cascadeDataDidUpdateEvent_();this.predraw_();}else if(typeof data == 'object' && typeof data.getColumnRange == 'function'){ // must be a DataTable from gviz. +this.parseDataTable_(data);this.cascadeDataDidUpdateEvent_();this.predraw_();}else if(typeof data == 'string'){ // Heuristic: a newline means it's CSV data. Otherwise it's an URL. +var line_delimiter=utils.detectLineDelimiter(data);if(line_delimiter){this.loadedEvent_(data);}else { // REMOVE_FOR_IE +var req;if(window.XMLHttpRequest){ // Firefox, Opera, IE7, and other browsers will use the native object +req = new XMLHttpRequest();}else { // IE 5 and 6 will use the ActiveX control +req = new ActiveXObject("Microsoft.XMLHTTP");}var caller=this;req.onreadystatechange = function(){if(req.readyState == 4){if(req.status === 200 || // Normal http +req.status === 0){ // Chrome w/ --allow-file-access-from-files +caller.loadedEvent_(req.responseText);}}};req.open("GET",data,true);req.send(null);}}else {console.error("Unknown data format: " + typeof data);}}; /** + * Changes various properties of the graph. These can include: + *
    + *
  • file: changes the source data for the graph
  • + *
  • errorBars: changes whether the data contains stddev
  • + *
+ * + * There's a huge variety of options that can be passed to this method. For a + * full list, see http://dygraphs.com/options.html. + * + * @param {Object} input_attrs The new properties and values + * @param {boolean} block_redraw Usually the chart is redrawn after every + * call to updateOptions(). If you know better, you can pass true to + * explicitly block the redraw. This can be useful for chaining + * updateOptions() calls, avoiding the occasional infinite loop and + * preventing redraws when it's not necessary (e.g. when updating a + * callback). + */Dygraph.prototype.updateOptions = function(input_attrs,block_redraw){if(typeof block_redraw == 'undefined')block_redraw = false; // copyUserAttrs_ drops the "file" parameter as a convenience to us. +var file=input_attrs.file;var attrs=Dygraph.copyUserAttrs_(input_attrs); // TODO(danvk): this is a mess. Move these options into attr_. +if('rollPeriod' in attrs){this.rollPeriod_ = attrs.rollPeriod;}if('dateWindow' in attrs){this.dateWindow_ = attrs.dateWindow;} // TODO(danvk): validate per-series options. +// Supported: +// strokeWidth +// pointSize +// drawPoints +// highlightCircleSize +// Check if this set options will require new points. +var requiresNewPoints=utils.isPixelChangingOptionList(this.attr_("labels"),attrs);utils.updateDeep(this.user_attrs_,attrs);this.attributes_.reparseSeries();if(file){ // This event indicates that the data is about to change, but hasn't yet. +// TODO(danvk): support cancelation of the update via this event. +this.cascadeEvents_('dataWillUpdate',{});this.file_ = file;if(!block_redraw)this.start_();}else {if(!block_redraw){if(requiresNewPoints){this.predraw_();}else {this.renderGraph_(false);}}}}; /** + * Make a copy of input attributes, removing file as a convenience. + * @private + */Dygraph.copyUserAttrs_ = function(attrs){var my_attrs={};for(var k in attrs) {if(!attrs.hasOwnProperty(k))continue;if(k == 'file')continue;if(attrs.hasOwnProperty(k))my_attrs[k] = attrs[k];}return my_attrs;}; /** + * Resizes the dygraph. If no parameters are specified, resizes to fill the + * containing div (which has presumably changed size since the dygraph was + * instantiated. If the width/height are specified, the div will be resized. + * + * This is far more efficient than destroying and re-instantiating a + * Dygraph, since it doesn't have to reparse the underlying data. + * + * @param {number} width Width (in pixels) + * @param {number} height Height (in pixels) + */Dygraph.prototype.resize = function(width,height){if(this.resize_lock){return;}this.resize_lock = true;if(width === null != (height === null)){console.warn("Dygraph.resize() should be called with zero parameters or " + "two non-NULL parameters. Pretending it was zero.");width = height = null;}var old_width=this.width_;var old_height=this.height_;if(width){this.maindiv_.style.width = width + "px";this.maindiv_.style.height = height + "px";this.width_ = width;this.height_ = height;}else {this.width_ = this.maindiv_.clientWidth;this.height_ = this.maindiv_.clientHeight;}if(old_width != this.width_ || old_height != this.height_){ // Resizing a canvas erases it, even when the size doesn't change, so +// any resize needs to be followed by a redraw. +this.resizeElements_();this.predraw_();}this.resize_lock = false;}; /** + * Adjusts the number of points in the rolling average. Updates the graph to + * reflect the new averaging period. + * @param {number} length Number of points over which to average the data. + */Dygraph.prototype.adjustRoll = function(length){this.rollPeriod_ = length;this.predraw_();}; /** + * Returns a boolean array of visibility statuses. + */Dygraph.prototype.visibility = function(){ // Do lazy-initialization, so that this happens after we know the number of +// data series. +if(!this.getOption("visibility")){this.attrs_.visibility = [];} // TODO(danvk): it looks like this could go into an infinite loop w/ user_attrs. +while(this.getOption("visibility").length < this.numColumns() - 1) {this.attrs_.visibility.push(true);}return this.getOption("visibility");}; /** + * Changes the visibility of one or more series. + * + * @param {number|number[]|object} num the series index or an array of series indices + * or a boolean array of visibility states by index + * or an object mapping series numbers, as keys, to + * visibility state (boolean values) + * @param {boolean} value the visibility state expressed as a boolean + */Dygraph.prototype.setVisibility = function(num,value){var x=this.visibility();var numIsObject=false;if(!Array.isArray(num)){if(num !== null && typeof num === 'object'){numIsObject = true;}else {num = [num];}}if(numIsObject){for(var i in num) {if(num.hasOwnProperty(i)){if(i < 0 || i >= x.length){console.warn("Invalid series number in setVisibility: " + i);}else {x[i] = num[i];}}}}else {for(var i=0;i < num.length;i++) {if(typeof num[i] === 'boolean'){if(i >= x.length){console.warn("Invalid series number in setVisibility: " + i);}else {x[i] = num[i];}}else {if(num[i] < 0 || num[i] >= x.length){console.warn("Invalid series number in setVisibility: " + num[i]);}else {x[num[i]] = value;}}}}this.predraw_();}; /** + * How large of an area will the dygraph render itself in? + * This is used for testing. + * @return A {width: w, height: h} object. + * @private + */Dygraph.prototype.size = function(){return {width:this.width_,height:this.height_};}; /** + * Update the list of annotations and redraw the chart. + * See dygraphs.com/annotations.html for more info on how to use annotations. + * @param ann {Array} An array of annotation objects. + * @param suppressDraw {Boolean} Set to "true" to block chart redraw (optional). + */Dygraph.prototype.setAnnotations = function(ann,suppressDraw){ // Only add the annotation CSS rule once we know it will be used. +this.annotations_ = ann;if(!this.layout_){console.warn("Tried to setAnnotations before dygraph was ready. " + "Try setting them in a ready() block. See " + "dygraphs.com/tests/annotation.html");return;}this.layout_.setAnnotations(this.annotations_);if(!suppressDraw){this.predraw_();}}; /** + * Return the list of annotations. + */Dygraph.prototype.annotations = function(){return this.annotations_;}; /** + * Get the list of label names for this graph. The first column is the + * x-axis, so the data series names start at index 1. + * + * Returns null when labels have not yet been defined. + */Dygraph.prototype.getLabels = function(){var labels=this.attr_("labels");return labels?labels.slice():null;}; /** + * Get the index of a series (column) given its name. The first column is the + * x-axis, so the data series start with index 1. + */Dygraph.prototype.indexFromSetName = function(name){return this.setIndexByName_[name];}; /** + * Find the row number corresponding to the given x-value. + * Returns null if there is no such x-value in the data. + * If there are multiple rows with the same x-value, this will return the + * first one. + * @param {number} xVal The x-value to look for (e.g. millis since epoch). + * @return {?number} The row number, which you can pass to getValue(), or null. + */Dygraph.prototype.getRowForX = function(xVal){var low=0,high=this.numRows() - 1;while(low <= high) {var idx=high + low >> 1;var x=this.getValue(idx,0);if(x < xVal){low = idx + 1;}else if(x > xVal){high = idx - 1;}else if(low != idx){ // equal, but there may be an earlier match. +high = idx;}else {return idx;}}return null;}; /** + * Trigger a callback when the dygraph has drawn itself and is ready to be + * manipulated. This is primarily useful when dygraphs has to do an XHR for the + * data (i.e. a URL is passed as the data source) and the chart is drawn + * asynchronously. If the chart has already drawn, the callback will fire + * immediately. + * + * This is a good place to call setAnnotation(). + * + * @param {function(!Dygraph)} callback The callback to trigger when the chart + * is ready. + */Dygraph.prototype.ready = function(callback){if(this.is_initial_draw_){this.readyFns_.push(callback);}else {callback.call(this,this);}}; /** + * Add an event handler. This event handler is kept until the graph is + * destroyed with a call to graph.destroy(). + * + * @param {!Node} elem The element to add the event to. + * @param {string} type The type of the event, e.g. 'click' or 'mousemove'. + * @param {function(Event):(boolean|undefined)} fn The function to call + * on the event. The function takes one parameter: the event object. + * @private + */Dygraph.prototype.addAndTrackEvent = function(elem,type,fn){utils.addEvent(elem,type,fn);this.registeredEvents_.push({elem:elem,type:type,fn:fn});};Dygraph.prototype.removeTrackedEvents_ = function(){if(this.registeredEvents_){for(var idx=0;idx < this.registeredEvents_.length;idx++) {var reg=this.registeredEvents_[idx];utils.removeEvent(reg.elem,reg.type,reg.fn);}}this.registeredEvents_ = [];}; // Installed plugins, in order of precedence (most-general to most-specific). +Dygraph.PLUGINS = [_pluginsLegend2['default'],_pluginsAxes2['default'],_pluginsRangeSelector2['default'], // Has to be before ChartLabels so that its callbacks are called after ChartLabels' callbacks. +_pluginsChartLabels2['default'],_pluginsAnnotations2['default'],_pluginsGrid2['default']]; // There are many symbols which have historically been available through the +// Dygraph class. These are exported here for backwards compatibility. +Dygraph.GVizChart = _dygraphGviz2['default'];Dygraph.DASHED_LINE = utils.DASHED_LINE;Dygraph.DOT_DASH_LINE = utils.DOT_DASH_LINE;Dygraph.dateAxisLabelFormatter = utils.dateAxisLabelFormatter;Dygraph.toRGB_ = utils.toRGB_;Dygraph.findPos = utils.findPos;Dygraph.pageX = utils.pageX;Dygraph.pageY = utils.pageY;Dygraph.dateString_ = utils.dateString_;Dygraph.defaultInteractionModel = _dygraphInteractionModel2['default'].defaultModel;Dygraph.nonInteractiveModel = Dygraph.nonInteractiveModel_ = _dygraphInteractionModel2['default'].nonInteractiveModel_;Dygraph.Circles = utils.Circles;Dygraph.Plugins = {Legend:_pluginsLegend2['default'],Axes:_pluginsAxes2['default'],Annotations:_pluginsAnnotations2['default'],ChartLabels:_pluginsChartLabels2['default'],Grid:_pluginsGrid2['default'],RangeSelector:_pluginsRangeSelector2['default']};Dygraph.DataHandlers = {DefaultHandler:_datahandlerDefault2['default'],BarsHandler:_datahandlerBars2['default'],CustomBarsHandler:_datahandlerBarsCustom2['default'],DefaultFractionHandler:_datahandlerDefaultFractions2['default'],ErrorBarsHandler:_datahandlerBarsError2['default'],FractionsBarsHandler:_datahandlerBarsFractions2['default']};Dygraph.startPan = _dygraphInteractionModel2['default'].startPan;Dygraph.startZoom = _dygraphInteractionModel2['default'].startZoom;Dygraph.movePan = _dygraphInteractionModel2['default'].movePan;Dygraph.moveZoom = _dygraphInteractionModel2['default'].moveZoom;Dygraph.endPan = _dygraphInteractionModel2['default'].endPan;Dygraph.endZoom = _dygraphInteractionModel2['default'].endZoom;Dygraph.numericLinearTicks = DygraphTickers.numericLinearTicks;Dygraph.numericTicks = DygraphTickers.numericTicks;Dygraph.dateTicker = DygraphTickers.dateTicker;Dygraph.Granularity = DygraphTickers.Granularity;Dygraph.getDateAxis = DygraphTickers.getDateAxis;Dygraph.floatFormat = utils.floatFormat;exports['default'] = Dygraph;module.exports = exports['default']; + +}).call(this,require('_process')) + +},{"./datahandler/bars":5,"./datahandler/bars-custom":2,"./datahandler/bars-error":3,"./datahandler/bars-fractions":4,"./datahandler/default":8,"./datahandler/default-fractions":7,"./dygraph-canvas":9,"./dygraph-default-attrs":10,"./dygraph-gviz":11,"./dygraph-interaction-model":12,"./dygraph-layout":13,"./dygraph-options":15,"./dygraph-options-reference":14,"./dygraph-tickers":16,"./dygraph-utils":17,"./iframe-tarp":19,"./plugins/annotations":20,"./plugins/axes":21,"./plugins/chart-labels":22,"./plugins/grid":23,"./plugins/legend":24,"./plugins/range-selector":25,"_process":1}],19:[function(require,module,exports){ +/** + * To create a "drag" interaction, you typically register a mousedown event + * handler on the element where the drag begins. In that handler, you register a + * mouseup handler on the window to determine when the mouse is released, + * wherever that release happens. This works well, except when the user releases + * the mouse over an off-domain iframe. In that case, the mouseup event is + * handled by the iframe and never bubbles up to the window handler. + * + * To deal with this issue, we cover iframes with high z-index divs to make sure + * they don't capture mouseup. + * + * Usage: + * element.addEventListener('mousedown', function() { + * var tarper = new IFrameTarp(); + * tarper.cover(); + * var mouseUpHandler = function() { + * ... + * window.removeEventListener(mouseUpHandler); + * tarper.uncover(); + * }; + * window.addEventListener('mouseup', mouseUpHandler); + * }; + * + * @constructor + */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } + +var _dygraphUtils = require('./dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +function IFrameTarp() { + /** @type {Array.} */ + this.tarps = []; +}; + +/** + * Find all the iframes in the document and cover them with high z-index + * transparent divs. + */ +IFrameTarp.prototype.cover = function () { + var iframes = document.getElementsByTagName("iframe"); + for (var i = 0; i < iframes.length; i++) { + var iframe = iframes[i]; + var pos = utils.findPos(iframe), + x = pos.x, + y = pos.y, + width = iframe.offsetWidth, + height = iframe.offsetHeight; + + var div = document.createElement("div"); + div.style.position = "absolute"; + div.style.left = x + 'px'; + div.style.top = y + 'px'; + div.style.width = width + 'px'; + div.style.height = height + 'px'; + div.style.zIndex = 999; + document.body.appendChild(div); + this.tarps.push(div); + } +}; + +/** + * Remove all the iframe covers. You should call this in a mouseup handler. + */ +IFrameTarp.prototype.uncover = function () { + for (var i = 0; i < this.tarps.length; i++) { + this.tarps[i].parentNode.removeChild(this.tarps[i]); + } + this.tarps = []; +}; + +exports["default"] = IFrameTarp; +module.exports = exports["default"]; + +},{"./dygraph-utils":17}],20:[function(require,module,exports){ +/** + * @license + * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/*global Dygraph:false */ + +"use strict"; + +/** +Current bits of jankiness: +- Uses dygraph.layout_ to get the parsed annotations. +- Uses dygraph.plotter_.area + +It would be nice if the plugin didn't require so much special support inside +the core dygraphs classes, but annotations involve quite a bit of parsing and +layout. + +TODO(danvk): cache DOM elements. +*/ + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var annotations = function annotations() { + this.annotations_ = []; +}; + +annotations.prototype.toString = function () { + return "Annotations Plugin"; +}; + +annotations.prototype.activate = function (g) { + return { + clearChart: this.clearChart, + didDrawChart: this.didDrawChart + }; +}; + +annotations.prototype.detachLabels = function () { + for (var i = 0; i < this.annotations_.length; i++) { + var a = this.annotations_[i]; + if (a.parentNode) a.parentNode.removeChild(a); + this.annotations_[i] = null; + } + this.annotations_ = []; +}; + +annotations.prototype.clearChart = function (e) { + this.detachLabels(); +}; + +annotations.prototype.didDrawChart = function (e) { + var g = e.dygraph; + + // Early out in the (common) case of zero annotations. + var points = g.layout_.annotated_points; + if (!points || points.length === 0) return; + + var containerDiv = e.canvas.parentNode; + + var bindEvt = function bindEvt(eventName, classEventName, pt) { + return function (annotation_event) { + var a = pt.annotation; + if (a.hasOwnProperty(eventName)) { + a[eventName](a, pt, g, annotation_event); + } else if (g.getOption(classEventName)) { + g.getOption(classEventName)(a, pt, g, annotation_event); + } + }; + }; + + // Add the annotations one-by-one. + var area = e.dygraph.getArea(); + + // x-coord to sum of previous annotation's heights (used for stacking). + var xToUsedHeight = {}; + + for (var i = 0; i < points.length; i++) { + var p = points[i]; + if (p.canvasx < area.x || p.canvasx > area.x + area.w || p.canvasy < area.y || p.canvasy > area.y + area.h) { + continue; + } + + var a = p.annotation; + var tick_height = 6; + if (a.hasOwnProperty("tickHeight")) { + tick_height = a.tickHeight; + } + + // TODO: deprecate axisLabelFontSize in favor of CSS + var div = document.createElement("div"); + div.style['fontSize'] = g.getOption('axisLabelFontSize') + "px"; + var className = 'dygraph-annotation'; + if (!a.hasOwnProperty('icon')) { + // camelCase class names are deprecated. + className += ' dygraphDefaultAnnotation dygraph-default-annotation'; + } + if (a.hasOwnProperty('cssClass')) { + className += " " + a.cssClass; + } + div.className = className; + + var width = a.hasOwnProperty('width') ? a.width : 16; + var height = a.hasOwnProperty('height') ? a.height : 16; + if (a.hasOwnProperty('icon')) { + var img = document.createElement("img"); + img.src = a.icon; + img.width = width; + img.height = height; + div.appendChild(img); + } else if (p.annotation.hasOwnProperty('shortText')) { + div.appendChild(document.createTextNode(p.annotation.shortText)); + } + var left = p.canvasx - width / 2; + div.style.left = left + "px"; + var divTop = 0; + if (a.attachAtBottom) { + var y = area.y + area.h - height - tick_height; + if (xToUsedHeight[left]) { + y -= xToUsedHeight[left]; + } else { + xToUsedHeight[left] = 0; + } + xToUsedHeight[left] += tick_height + height; + divTop = y; + } else { + divTop = p.canvasy - height - tick_height; + } + div.style.top = divTop + "px"; + div.style.width = width + "px"; + div.style.height = height + "px"; + div.title = p.annotation.text; + div.style.color = g.colorsMap_[p.name]; + div.style.borderColor = g.colorsMap_[p.name]; + a.div = div; + + g.addAndTrackEvent(div, 'click', bindEvt('clickHandler', 'annotationClickHandler', p, this)); + g.addAndTrackEvent(div, 'mouseover', bindEvt('mouseOverHandler', 'annotationMouseOverHandler', p, this)); + g.addAndTrackEvent(div, 'mouseout', bindEvt('mouseOutHandler', 'annotationMouseOutHandler', p, this)); + g.addAndTrackEvent(div, 'dblclick', bindEvt('dblClickHandler', 'annotationDblClickHandler', p, this)); + + containerDiv.appendChild(div); + this.annotations_.push(div); + + var ctx = e.drawingContext; + ctx.save(); + ctx.strokeStyle = a.hasOwnProperty('tickColor') ? a.tickColor : g.colorsMap_[p.name]; + ctx.lineWidth = a.hasOwnProperty('tickWidth') ? a.tickWidth : g.getOption('strokeWidth'); + ctx.beginPath(); + if (!a.attachAtBottom) { + ctx.moveTo(p.canvasx, p.canvasy); + ctx.lineTo(p.canvasx, p.canvasy - 2 - tick_height); + } else { + var y = divTop + height; + ctx.moveTo(p.canvasx, y); + ctx.lineTo(p.canvasx, y + tick_height); + } + ctx.closePath(); + ctx.stroke(); + ctx.restore(); + } +}; + +annotations.prototype.destroy = function () { + this.detachLabels(); +}; + +exports["default"] = annotations; +module.exports = exports["default"]; + +},{}],21:[function(require,module,exports){ +/** + * @license + * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/*global Dygraph:false */ + +'use strict'; + +/* +Bits of jankiness: +- Direct layout access +- Direct area access +- Should include calculation of ticks, not just the drawing. + +Options left to make axis-friendly. + ('drawAxesAtZero') + ('xAxisHeight') +*/ + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('../dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +/** + * Draws the axes. This includes the labels on the x- and y-axes, as well + * as the tick marks on the axes. + * It does _not_ draw the grid lines which span the entire chart. + */ +var axes = function axes() { + this.xlabels_ = []; + this.ylabels_ = []; +}; + +axes.prototype.toString = function () { + return 'Axes Plugin'; +}; + +axes.prototype.activate = function (g) { + return { + layout: this.layout, + clearChart: this.clearChart, + willDrawChart: this.willDrawChart + }; +}; + +axes.prototype.layout = function (e) { + var g = e.dygraph; + + if (g.getOptionForAxis('drawAxis', 'y')) { + var w = g.getOptionForAxis('axisLabelWidth', 'y') + 2 * g.getOptionForAxis('axisTickSize', 'y'); + e.reserveSpaceLeft(w); + } + + if (g.getOptionForAxis('drawAxis', 'x')) { + var h; + // NOTE: I think this is probably broken now, since g.getOption() now + // hits the dictionary. (That is, g.getOption('xAxisHeight') now always + // has a value.) + if (g.getOption('xAxisHeight')) { + h = g.getOption('xAxisHeight'); + } else { + h = g.getOptionForAxis('axisLabelFontSize', 'x') + 2 * g.getOptionForAxis('axisTickSize', 'x'); + } + e.reserveSpaceBottom(h); + } + + if (g.numAxes() == 2) { + if (g.getOptionForAxis('drawAxis', 'y2')) { + var w = g.getOptionForAxis('axisLabelWidth', 'y2') + 2 * g.getOptionForAxis('axisTickSize', 'y2'); + e.reserveSpaceRight(w); + } + } else if (g.numAxes() > 2) { + g.error('Only two y-axes are supported at this time. (Trying ' + 'to use ' + g.numAxes() + ')'); + } +}; + +axes.prototype.detachLabels = function () { + function removeArray(ary) { + for (var i = 0; i < ary.length; i++) { + var el = ary[i]; + if (el.parentNode) el.parentNode.removeChild(el); + } + } + + removeArray(this.xlabels_); + removeArray(this.ylabels_); + this.xlabels_ = []; + this.ylabels_ = []; +}; + +axes.prototype.clearChart = function (e) { + this.detachLabels(); +}; + +axes.prototype.willDrawChart = function (e) { + var _this = this; + + var g = e.dygraph; + + if (!g.getOptionForAxis('drawAxis', 'x') && !g.getOptionForAxis('drawAxis', 'y') && !g.getOptionForAxis('drawAxis', 'y2')) { + return; + } + + // Round pixels to half-integer boundaries for crisper drawing. + function halfUp(x) { + return Math.round(x) + 0.5; + } + function halfDown(y) { + return Math.round(y) - 0.5; + } + + var context = e.drawingContext; + var containerDiv = e.canvas.parentNode; + var canvasWidth = g.width_; // e.canvas.width is affected by pixel ratio. + var canvasHeight = g.height_; + + var label, x, y, tick, i; + + var makeLabelStyle = function makeLabelStyle(axis) { + return { + position: 'absolute', + fontSize: g.getOptionForAxis('axisLabelFontSize', axis) + 'px', + width: g.getOptionForAxis('axisLabelWidth', axis) + 'px' + }; + }; + + var labelStyles = { + x: makeLabelStyle('x'), + y: makeLabelStyle('y'), + y2: makeLabelStyle('y2') + }; + + var makeDiv = function makeDiv(txt, axis, prec_axis) { + /* + * This seems to be called with the following three sets of axis/prec_axis: + * x: undefined + * y: y1 + * y: y2 + */ + var div = document.createElement('div'); + var labelStyle = labelStyles[prec_axis == 'y2' ? 'y2' : axis]; + utils.update(div.style, labelStyle); + // TODO: combine outer & inner divs + var inner_div = document.createElement('div'); + inner_div.className = 'dygraph-axis-label' + ' dygraph-axis-label-' + axis + (prec_axis ? ' dygraph-axis-label-' + prec_axis : ''); + inner_div.innerHTML = txt; + div.appendChild(inner_div); + return div; + }; + + // axis lines + context.save(); + + var layout = g.layout_; + var area = e.dygraph.plotter_.area; + + // Helper for repeated axis-option accesses. + var makeOptionGetter = function makeOptionGetter(axis) { + return function (option) { + return g.getOptionForAxis(option, axis); + }; + }; + + if (g.getOptionForAxis('drawAxis', 'y')) { + if (layout.yticks && layout.yticks.length > 0) { + var num_axes = g.numAxes(); + var getOptions = [makeOptionGetter('y'), makeOptionGetter('y2')]; + layout.yticks.forEach(function (tick) { + if (tick.label === undefined) return; // this tick only has a grid line. + x = area.x; + var sgn = 1; + var prec_axis = 'y1'; + var getAxisOption = getOptions[0]; + if (tick.axis == 1) { + // right-side y-axis + x = area.x + area.w; + sgn = -1; + prec_axis = 'y2'; + getAxisOption = getOptions[1]; + } + var fontSize = getAxisOption('axisLabelFontSize'); + y = area.y + tick.pos * area.h; + + /* Tick marks are currently clipped, so don't bother drawing them. + context.beginPath(); + context.moveTo(halfUp(x), halfDown(y)); + context.lineTo(halfUp(x - sgn * this.attr_('axisTickSize')), halfDown(y)); + context.closePath(); + context.stroke(); + */ + + label = makeDiv(tick.label, 'y', num_axes == 2 ? prec_axis : null); + var top = y - fontSize / 2; + if (top < 0) top = 0; + + if (top + fontSize + 3 > canvasHeight) { + label.style.bottom = '0'; + } else { + label.style.top = top + 'px'; + } + // TODO: replace these with css classes? + if (tick.axis === 0) { + label.style.left = area.x - getAxisOption('axisLabelWidth') - getAxisOption('axisTickSize') + 'px'; + label.style.textAlign = 'right'; + } else if (tick.axis == 1) { + label.style.left = area.x + area.w + getAxisOption('axisTickSize') + 'px'; + label.style.textAlign = 'left'; + } + label.style.width = getAxisOption('axisLabelWidth') + 'px'; + containerDiv.appendChild(label); + _this.ylabels_.push(label); + }); + + // The lowest tick on the y-axis often overlaps with the leftmost + // tick on the x-axis. Shift the bottom tick up a little bit to + // compensate if necessary. + var bottomTick = this.ylabels_[0]; + // Interested in the y2 axis also? + var fontSize = g.getOptionForAxis('axisLabelFontSize', 'y'); + var bottom = parseInt(bottomTick.style.top, 10) + fontSize; + if (bottom > canvasHeight - fontSize) { + bottomTick.style.top = parseInt(bottomTick.style.top, 10) - fontSize / 2 + 'px'; + } + } + + // draw a vertical line on the left to separate the chart from the labels. + var axisX; + if (g.getOption('drawAxesAtZero')) { + var r = g.toPercentXCoord(0); + if (r > 1 || r < 0 || isNaN(r)) r = 0; + axisX = halfUp(area.x + r * area.w); + } else { + axisX = halfUp(area.x); + } + + context.strokeStyle = g.getOptionForAxis('axisLineColor', 'y'); + context.lineWidth = g.getOptionForAxis('axisLineWidth', 'y'); + + context.beginPath(); + context.moveTo(axisX, halfDown(area.y)); + context.lineTo(axisX, halfDown(area.y + area.h)); + context.closePath(); + context.stroke(); + + // if there's a secondary y-axis, draw a vertical line for that, too. + if (g.numAxes() == 2) { + context.strokeStyle = g.getOptionForAxis('axisLineColor', 'y2'); + context.lineWidth = g.getOptionForAxis('axisLineWidth', 'y2'); + context.beginPath(); + context.moveTo(halfDown(area.x + area.w), halfDown(area.y)); + context.lineTo(halfDown(area.x + area.w), halfDown(area.y + area.h)); + context.closePath(); + context.stroke(); + } + } + + if (g.getOptionForAxis('drawAxis', 'x')) { + if (layout.xticks) { + var getAxisOption = makeOptionGetter('x'); + layout.xticks.forEach(function (tick) { + if (tick.label === undefined) return; // this tick only has a grid line. + x = area.x + tick.pos * area.w; + y = area.y + area.h; + + /* Tick marks are currently clipped, so don't bother drawing them. + context.beginPath(); + context.moveTo(halfUp(x), halfDown(y)); + context.lineTo(halfUp(x), halfDown(y + this.attr_('axisTickSize'))); + context.closePath(); + context.stroke(); + */ + + label = makeDiv(tick.label, 'x'); + label.style.textAlign = 'center'; + label.style.top = y + getAxisOption('axisTickSize') + 'px'; + + var left = x - getAxisOption('axisLabelWidth') / 2; + if (left + getAxisOption('axisLabelWidth') > canvasWidth) { + left = canvasWidth - getAxisOption('axisLabelWidth'); + label.style.textAlign = 'right'; + } + if (left < 0) { + left = 0; + label.style.textAlign = 'left'; + } + + label.style.left = left + 'px'; + label.style.width = getAxisOption('axisLabelWidth') + 'px'; + containerDiv.appendChild(label); + _this.xlabels_.push(label); + }); + } + + context.strokeStyle = g.getOptionForAxis('axisLineColor', 'x'); + context.lineWidth = g.getOptionForAxis('axisLineWidth', 'x'); + context.beginPath(); + var axisY; + if (g.getOption('drawAxesAtZero')) { + var r = g.toPercentYCoord(0, 0); + if (r > 1 || r < 0) r = 1; + axisY = halfDown(area.y + r * area.h); + } else { + axisY = halfDown(area.y + area.h); + } + context.moveTo(halfUp(area.x), axisY); + context.lineTo(halfUp(area.x + area.w), axisY); + context.closePath(); + context.stroke(); + } + + context.restore(); +}; + +exports['default'] = axes; +module.exports = exports['default']; + +},{"../dygraph-utils":17}],22:[function(require,module,exports){ +/** + * @license + * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ +/*global Dygraph:false */ + +"use strict"; + +// TODO(danvk): move chart label options out of dygraphs and into the plugin. +// TODO(danvk): only tear down & rebuild the DIVs when it's necessary. + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var chart_labels = function chart_labels() { + this.title_div_ = null; + this.xlabel_div_ = null; + this.ylabel_div_ = null; + this.y2label_div_ = null; +}; + +chart_labels.prototype.toString = function () { + return "ChartLabels Plugin"; +}; + +chart_labels.prototype.activate = function (g) { + return { + layout: this.layout, + // clearChart: this.clearChart, + didDrawChart: this.didDrawChart + }; +}; + +// QUESTION: should there be a plugin-utils.js? +var createDivInRect = function createDivInRect(r) { + var div = document.createElement('div'); + div.style.position = 'absolute'; + div.style.left = r.x + 'px'; + div.style.top = r.y + 'px'; + div.style.width = r.w + 'px'; + div.style.height = r.h + 'px'; + return div; +}; + +// Detach and null out any existing nodes. +chart_labels.prototype.detachLabels_ = function () { + var els = [this.title_div_, this.xlabel_div_, this.ylabel_div_, this.y2label_div_]; + for (var i = 0; i < els.length; i++) { + var el = els[i]; + if (!el) continue; + if (el.parentNode) el.parentNode.removeChild(el); + } + + this.title_div_ = null; + this.xlabel_div_ = null; + this.ylabel_div_ = null; + this.y2label_div_ = null; +}; + +var createRotatedDiv = function createRotatedDiv(g, box, axis, classes, html) { + // TODO(danvk): is this outer div actually necessary? + var div = document.createElement("div"); + div.style.position = 'absolute'; + if (axis == 1) { + // NOTE: this is cheating. Should be positioned relative to the box. + div.style.left = '0px'; + } else { + div.style.left = box.x + 'px'; + } + div.style.top = box.y + 'px'; + div.style.width = box.w + 'px'; + div.style.height = box.h + 'px'; + div.style.fontSize = g.getOption('yLabelWidth') - 2 + 'px'; + + var inner_div = document.createElement("div"); + inner_div.style.position = 'absolute'; + inner_div.style.width = box.h + 'px'; + inner_div.style.height = box.w + 'px'; + inner_div.style.top = box.h / 2 - box.w / 2 + 'px'; + inner_div.style.left = box.w / 2 - box.h / 2 + 'px'; + // TODO: combine inner_div and class_div. + inner_div.className = 'dygraph-label-rotate-' + (axis == 1 ? 'right' : 'left'); + + var class_div = document.createElement("div"); + class_div.className = classes; + class_div.innerHTML = html; + + inner_div.appendChild(class_div); + div.appendChild(inner_div); + return div; +}; + +chart_labels.prototype.layout = function (e) { + this.detachLabels_(); + + var g = e.dygraph; + var div = e.chart_div; + if (g.getOption('title')) { + // QUESTION: should this return an absolutely-positioned div instead? + var title_rect = e.reserveSpaceTop(g.getOption('titleHeight')); + this.title_div_ = createDivInRect(title_rect); + this.title_div_.style.fontSize = g.getOption('titleHeight') - 8 + 'px'; + + var class_div = document.createElement("div"); + class_div.className = 'dygraph-label dygraph-title'; + class_div.innerHTML = g.getOption('title'); + this.title_div_.appendChild(class_div); + div.appendChild(this.title_div_); + } + + if (g.getOption('xlabel')) { + var x_rect = e.reserveSpaceBottom(g.getOption('xLabelHeight')); + this.xlabel_div_ = createDivInRect(x_rect); + this.xlabel_div_.style.fontSize = g.getOption('xLabelHeight') - 2 + 'px'; + + var class_div = document.createElement("div"); + class_div.className = 'dygraph-label dygraph-xlabel'; + class_div.innerHTML = g.getOption('xlabel'); + this.xlabel_div_.appendChild(class_div); + div.appendChild(this.xlabel_div_); + } + + if (g.getOption('ylabel')) { + // It would make sense to shift the chart here to make room for the y-axis + // label, but the default yAxisLabelWidth is large enough that this results + // in overly-padded charts. The y-axis label should fit fine. If it + // doesn't, the yAxisLabelWidth option can be increased. + var y_rect = e.reserveSpaceLeft(0); + + this.ylabel_div_ = createRotatedDiv(g, y_rect, 1, // primary (left) y-axis + 'dygraph-label dygraph-ylabel', g.getOption('ylabel')); + div.appendChild(this.ylabel_div_); + } + + if (g.getOption('y2label') && g.numAxes() == 2) { + // same logic applies here as for ylabel. + var y2_rect = e.reserveSpaceRight(0); + this.y2label_div_ = createRotatedDiv(g, y2_rect, 2, // secondary (right) y-axis + 'dygraph-label dygraph-y2label', g.getOption('y2label')); + div.appendChild(this.y2label_div_); + } +}; + +chart_labels.prototype.didDrawChart = function (e) { + var g = e.dygraph; + if (this.title_div_) { + this.title_div_.children[0].innerHTML = g.getOption('title'); + } + if (this.xlabel_div_) { + this.xlabel_div_.children[0].innerHTML = g.getOption('xlabel'); + } + if (this.ylabel_div_) { + this.ylabel_div_.children[0].children[0].innerHTML = g.getOption('ylabel'); + } + if (this.y2label_div_) { + this.y2label_div_.children[0].children[0].innerHTML = g.getOption('y2label'); + } +}; + +chart_labels.prototype.clearChart = function () {}; + +chart_labels.prototype.destroy = function () { + this.detachLabels_(); +}; + +exports["default"] = chart_labels; +module.exports = exports["default"]; + +},{}],23:[function(require,module,exports){ +/** + * @license + * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ +/*global Dygraph:false */ + +/* + +Current bits of jankiness: +- Direct layout access +- Direct area access + +*/ + +"use strict"; + +/** + * Draws the gridlines, i.e. the gray horizontal & vertical lines running the + * length of the chart. + * + * @constructor + */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +var grid = function grid() {}; + +grid.prototype.toString = function () { + return "Gridline Plugin"; +}; + +grid.prototype.activate = function (g) { + return { + willDrawChart: this.willDrawChart + }; +}; + +grid.prototype.willDrawChart = function (e) { + // Draw the new X/Y grid. Lines appear crisper when pixels are rounded to + // half-integers. This prevents them from drawing in two rows/cols. + var g = e.dygraph; + var ctx = e.drawingContext; + var layout = g.layout_; + var area = e.dygraph.plotter_.area; + + function halfUp(x) { + return Math.round(x) + 0.5; + } + function halfDown(y) { + return Math.round(y) - 0.5; + } + + var x, y, i, ticks; + if (g.getOptionForAxis('drawGrid', 'y')) { + var axes = ["y", "y2"]; + var strokeStyles = [], + lineWidths = [], + drawGrid = [], + stroking = [], + strokePattern = []; + for (var i = 0; i < axes.length; i++) { + drawGrid[i] = g.getOptionForAxis('drawGrid', axes[i]); + if (drawGrid[i]) { + strokeStyles[i] = g.getOptionForAxis('gridLineColor', axes[i]); + lineWidths[i] = g.getOptionForAxis('gridLineWidth', axes[i]); + strokePattern[i] = g.getOptionForAxis('gridLinePattern', axes[i]); + stroking[i] = strokePattern[i] && strokePattern[i].length >= 2; + } + } + ticks = layout.yticks; + ctx.save(); + // draw grids for the different y axes + ticks.forEach(function (tick) { + if (!tick.has_tick) return; + var axis = tick.axis; + if (drawGrid[axis]) { + ctx.save(); + if (stroking[axis]) { + if (ctx.setLineDash) ctx.setLineDash(strokePattern[axis]); + } + ctx.strokeStyle = strokeStyles[axis]; + ctx.lineWidth = lineWidths[axis]; + + x = halfUp(area.x); + y = halfDown(area.y + tick.pos * area.h); + ctx.beginPath(); + ctx.moveTo(x, y); + ctx.lineTo(x + area.w, y); + ctx.stroke(); + + ctx.restore(); + } + }); + ctx.restore(); + } + + // draw grid for x axis + if (g.getOptionForAxis('drawGrid', 'x')) { + ticks = layout.xticks; + ctx.save(); + var strokePattern = g.getOptionForAxis('gridLinePattern', 'x'); + var stroking = strokePattern && strokePattern.length >= 2; + if (stroking) { + if (ctx.setLineDash) ctx.setLineDash(strokePattern); + } + ctx.strokeStyle = g.getOptionForAxis('gridLineColor', 'x'); + ctx.lineWidth = g.getOptionForAxis('gridLineWidth', 'x'); + ticks.forEach(function (tick) { + if (!tick.has_tick) return; + x = halfUp(area.x + tick.pos * area.w); + y = halfDown(area.y + area.h); + ctx.beginPath(); + ctx.moveTo(x, y); + ctx.lineTo(x, area.y); + ctx.closePath(); + ctx.stroke(); + }); + if (stroking) { + if (ctx.setLineDash) ctx.setLineDash([]); + } + ctx.restore(); + } +}; + +grid.prototype.destroy = function () {}; + +exports["default"] = grid; +module.exports = exports["default"]; + +},{}],24:[function(require,module,exports){ +/** + * @license + * Copyright 2012 Dan Vanderkam (danvdk@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ +/*global Dygraph:false */ + +/* +Current bits of jankiness: +- Uses two private APIs: + 1. Dygraph.optionsViewForAxis_ + 2. dygraph.plotter_.area +- Registers for a "predraw" event, which should be renamed. +- I call calculateEmWidthInDiv more often than needed. +*/ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } + +var _dygraphUtils = require('../dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +/** + * Creates the legend, which appears when the user hovers over the chart. + * The legend can be either a user-specified or generated div. + * + * @constructor + */ +var Legend = function Legend() { + this.legend_div_ = null; + this.is_generated_div_ = false; // do we own this div, or was it user-specified? +}; + +Legend.prototype.toString = function () { + return "Legend Plugin"; +}; + +/** + * This is called during the dygraph constructor, after options have been set + * but before the data is available. + * + * Proper tasks to do here include: + * - Reading your own options + * - DOM manipulation + * - Registering event listeners + * + * @param {Dygraph} g Graph instance. + * @return {object.} Mapping of event names to callbacks. + */ +Legend.prototype.activate = function (g) { + var div; + + var userLabelsDiv = g.getOption('labelsDiv'); + if (userLabelsDiv && null !== userLabelsDiv) { + if (typeof userLabelsDiv == "string" || userLabelsDiv instanceof String) { + div = document.getElementById(userLabelsDiv); + } else { + div = userLabelsDiv; + } + } else { + div = document.createElement("div"); + div.className = "dygraph-legend"; + // TODO(danvk): come up with a cleaner way to expose this. + g.graphDiv.appendChild(div); + this.is_generated_div_ = true; + } + + this.legend_div_ = div; + this.one_em_width_ = 10; // just a guess, will be updated. + + return { + select: this.select, + deselect: this.deselect, + // TODO(danvk): rethink the name "predraw" before we commit to it in any API. + predraw: this.predraw, + didDrawChart: this.didDrawChart + }; +}; + +// Needed for dashed lines. +var calculateEmWidthInDiv = function calculateEmWidthInDiv(div) { + var sizeSpan = document.createElement('span'); + sizeSpan.setAttribute('style', 'margin: 0; padding: 0 0 0 1em; border: 0;'); + div.appendChild(sizeSpan); + var oneEmWidth = sizeSpan.offsetWidth; + div.removeChild(sizeSpan); + return oneEmWidth; +}; + +var escapeHTML = function escapeHTML(str) { + return str.replace(/&/g, "&").replace(/"/g, """).replace(//g, ">"); +}; + +Legend.prototype.select = function (e) { + var xValue = e.selectedX; + var points = e.selectedPoints; + var row = e.selectedRow; + + var legendMode = e.dygraph.getOption('legend'); + if (legendMode === 'never') { + this.legend_div_.style.display = 'none'; + return; + } + + if (legendMode === 'follow') { + // create floating legend div + var area = e.dygraph.plotter_.area; + var labelsDivWidth = this.legend_div_.offsetWidth; + var yAxisLabelWidth = e.dygraph.getOptionForAxis('axisLabelWidth', 'y'); + // determine floating [left, top] coordinates of the legend div + // within the plotter_ area + // offset 50 px to the right and down from the first selection point + // 50 px is guess based on mouse cursor size + var leftLegend = points[0].x * area.w + 50; + var topLegend = points[0].y * area.h - 50; + + // if legend floats to end of the chart area, it flips to the other + // side of the selection point + if (leftLegend + labelsDivWidth + 1 > area.w) { + leftLegend = leftLegend - 2 * 50 - labelsDivWidth - (yAxisLabelWidth - area.x); + } + + e.dygraph.graphDiv.appendChild(this.legend_div_); + this.legend_div_.style.left = yAxisLabelWidth + leftLegend + "px"; + this.legend_div_.style.top = topLegend + "px"; + } + + var html = Legend.generateLegendHTML(e.dygraph, xValue, points, this.one_em_width_, row); + this.legend_div_.innerHTML = html; + this.legend_div_.style.display = ''; +}; + +Legend.prototype.deselect = function (e) { + var legendMode = e.dygraph.getOption('legend'); + if (legendMode !== 'always') { + this.legend_div_.style.display = "none"; + } + + // Have to do this every time, since styles might have changed. + var oneEmWidth = calculateEmWidthInDiv(this.legend_div_); + this.one_em_width_ = oneEmWidth; + + var html = Legend.generateLegendHTML(e.dygraph, undefined, undefined, oneEmWidth, null); + this.legend_div_.innerHTML = html; +}; + +Legend.prototype.didDrawChart = function (e) { + this.deselect(e); +}; + +// Right edge should be flush with the right edge of the charting area (which +// may not be the same as the right edge of the div, if we have two y-axes. +// TODO(danvk): is any of this really necessary? Could just set "right" in "activate". +/** + * Position the labels div so that: + * - its right edge is flush with the right edge of the charting area + * - its top edge is flush with the top edge of the charting area + * @private + */ +Legend.prototype.predraw = function (e) { + // Don't touch a user-specified labelsDiv. + if (!this.is_generated_div_) return; + + // TODO(danvk): only use real APIs for this. + e.dygraph.graphDiv.appendChild(this.legend_div_); + var area = e.dygraph.getArea(); + var labelsDivWidth = this.legend_div_.offsetWidth; + this.legend_div_.style.left = area.x + area.w - labelsDivWidth - 1 + "px"; + this.legend_div_.style.top = area.y + "px"; +}; + +/** + * Called when dygraph.destroy() is called. + * You should null out any references and detach any DOM elements. + */ +Legend.prototype.destroy = function () { + this.legend_div_ = null; +}; + +/** + * Generates HTML for the legend which is displayed when hovering over the + * chart. If no selected points are specified, a default legend is returned + * (this may just be the empty string). + * @param {number} x The x-value of the selected points. + * @param {Object} sel_points List of selected points for the given + * x-value. Should have properties like 'name', 'yval' and 'canvasy'. + * @param {number} oneEmWidth The pixel width for 1em in the legend. Only + * relevant when displaying a legend with no selection (i.e. {legend: + * 'always'}) and with dashed lines. + * @param {number} row The selected row index. + * @private + */ +Legend.generateLegendHTML = function (g, x, sel_points, oneEmWidth, row) { + // Data about the selection to pass to legendFormatter + var data = { + dygraph: g, + x: x, + series: [] + }; + + var labelToSeries = {}; + var labels = g.getLabels(); + if (labels) { + for (var i = 1; i < labels.length; i++) { + var series = g.getPropertiesForSeries(labels[i]); + var strokePattern = g.getOption('strokePattern', labels[i]); + var seriesData = { + dashHTML: generateLegendDashHTML(strokePattern, series.color, oneEmWidth), + label: labels[i], + labelHTML: escapeHTML(labels[i]), + isVisible: series.visible, + color: series.color + }; + + data.series.push(seriesData); + labelToSeries[labels[i]] = seriesData; + } + } + + if (typeof x !== 'undefined') { + var xOptView = g.optionsViewForAxis_('x'); + var xvf = xOptView('valueFormatter'); + data.xHTML = xvf.call(g, x, xOptView, labels[0], g, row, 0); + + var yOptViews = []; + var num_axes = g.numAxes(); + for (var i = 0; i < num_axes; i++) { + // TODO(danvk): remove this use of a private API + yOptViews[i] = g.optionsViewForAxis_('y' + (i ? 1 + i : '')); + } + + var showZeros = g.getOption('labelsShowZeroValues'); + var highlightSeries = g.getHighlightSeries(); + for (i = 0; i < sel_points.length; i++) { + var pt = sel_points[i]; + var seriesData = labelToSeries[pt.name]; + seriesData.y = pt.yval; + + if (pt.yval === 0 && !showZeros || isNaN(pt.canvasy)) { + seriesData.isVisible = false; + continue; + } + + var series = g.getPropertiesForSeries(pt.name); + var yOptView = yOptViews[series.axis - 1]; + var fmtFunc = yOptView('valueFormatter'); + var yHTML = fmtFunc.call(g, pt.yval, yOptView, pt.name, g, row, labels.indexOf(pt.name)); + + utils.update(seriesData, { yHTML: yHTML }); + + if (pt.name == highlightSeries) { + seriesData.isHighlighted = true; + } + } + } + + var formatter = g.getOption('legendFormatter') || Legend.defaultFormatter; + return formatter.call(g, data); +}; + +Legend.defaultFormatter = function (data) { + var g = data.dygraph; + + // TODO(danvk): deprecate this option in place of {legend: 'never'} + // XXX should this logic be in the formatter? + if (g.getOption('showLabelsOnHighlight') !== true) return ''; + + var sepLines = g.getOption('labelsSeparateLines'); + var html; + + if (typeof data.x === 'undefined') { + // TODO: this check is duplicated in generateLegendHTML. Put it in one place. + if (g.getOption('legend') != 'always') { + return ''; + } + + html = ''; + for (var i = 0; i < data.series.length; i++) { + var series = data.series[i]; + if (!series.isVisible) continue; + + if (html !== '') html += sepLines ? '
' : ' '; + html += "" + series.dashHTML + " " + series.labelHTML + ""; + } + return html; + } + + html = data.xHTML + ':'; + for (var i = 0; i < data.series.length; i++) { + var series = data.series[i]; + if (!series.isVisible) continue; + if (sepLines) html += '
'; + var cls = series.isHighlighted ? ' class="highlight"' : ''; + html += " " + series.labelHTML + ": " + series.yHTML + ""; + } + return html; +}; + +/** + * Generates html for the "dash" displayed on the legend when using "legend: always". + * In particular, this works for dashed lines with any stroke pattern. It will + * try to scale the pattern to fit in 1em width. Or if small enough repeat the + * pattern for 1em width. + * + * @param strokePattern The pattern + * @param color The color of the series. + * @param oneEmWidth The width in pixels of 1em in the legend. + * @private + */ +// TODO(danvk): cache the results of this +function generateLegendDashHTML(strokePattern, color, oneEmWidth) { + // Easy, common case: a solid line + if (!strokePattern || strokePattern.length <= 1) { + return "
"; + } + + var i, j, paddingLeft, marginRight; + var strokePixelLength = 0, + segmentLoop = 0; + var normalizedPattern = []; + var loop; + + // Compute the length of the pixels including the first segment twice, + // since we repeat it. + for (i = 0; i <= strokePattern.length; i++) { + strokePixelLength += strokePattern[i % strokePattern.length]; + } + + // See if we can loop the pattern by itself at least twice. + loop = Math.floor(oneEmWidth / (strokePixelLength - strokePattern[0])); + if (loop > 1) { + // This pattern fits at least two times, no scaling just convert to em; + for (i = 0; i < strokePattern.length; i++) { + normalizedPattern[i] = strokePattern[i] / oneEmWidth; + } + // Since we are repeating the pattern, we don't worry about repeating the + // first segment in one draw. + segmentLoop = normalizedPattern.length; + } else { + // If the pattern doesn't fit in the legend we scale it to fit. + loop = 1; + for (i = 0; i < strokePattern.length; i++) { + normalizedPattern[i] = strokePattern[i] / strokePixelLength; + } + // For the scaled patterns we do redraw the first segment. + segmentLoop = normalizedPattern.length + 1; + } + + // Now make the pattern. + var dash = ""; + for (j = 0; j < loop; j++) { + for (i = 0; i < segmentLoop; i += 2) { + // The padding is the drawn segment. + paddingLeft = normalizedPattern[i % normalizedPattern.length]; + if (i < strokePattern.length) { + // The margin is the space segment. + marginRight = normalizedPattern[(i + 1) % normalizedPattern.length]; + } else { + // The repeated first segment has no right margin. + marginRight = 0; + } + dash += "
"; + } + } + return dash; +}; + +exports["default"] = Legend; +module.exports = exports["default"]; + +},{"../dygraph-utils":17}],25:[function(require,module,exports){ +/** + * @license + * Copyright 2011 Paul Felix (paul.eric.felix@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ +/*global Dygraph:false,TouchEvent:false */ + +/** + * @fileoverview This file contains the RangeSelector plugin used to provide + * a timeline range selector widget for dygraphs. + */ + +/*global Dygraph:false */ +"use strict"; + +Object.defineProperty(exports, '__esModule', { + value: true +}); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + +var _dygraphUtils = require('../dygraph-utils'); + +var utils = _interopRequireWildcard(_dygraphUtils); + +var _dygraphInteractionModel = require('../dygraph-interaction-model'); + +var _dygraphInteractionModel2 = _interopRequireDefault(_dygraphInteractionModel); + +var _iframeTarp = require('../iframe-tarp'); + +var _iframeTarp2 = _interopRequireDefault(_iframeTarp); + +var rangeSelector = function rangeSelector() { + this.hasTouchInterface_ = typeof TouchEvent != 'undefined'; + this.isMobileDevice_ = /mobile|android/gi.test(navigator.appVersion); + this.interfaceCreated_ = false; +}; + +rangeSelector.prototype.toString = function () { + return "RangeSelector Plugin"; +}; + +rangeSelector.prototype.activate = function (dygraph) { + this.dygraph_ = dygraph; + if (this.getOption_('showRangeSelector')) { + this.createInterface_(); + } + return { + layout: this.reserveSpace_, + predraw: this.renderStaticLayer_, + didDrawChart: this.renderInteractiveLayer_ + }; +}; + +rangeSelector.prototype.destroy = function () { + this.bgcanvas_ = null; + this.fgcanvas_ = null; + this.leftZoomHandle_ = null; + this.rightZoomHandle_ = null; +}; + +//------------------------------------------------------------------ +// Private methods +//------------------------------------------------------------------ + +rangeSelector.prototype.getOption_ = function (name, opt_series) { + return this.dygraph_.getOption(name, opt_series); +}; + +rangeSelector.prototype.setDefaultOption_ = function (name, value) { + this.dygraph_.attrs_[name] = value; +}; + +/** + * @private + * Creates the range selector elements and adds them to the graph. + */ +rangeSelector.prototype.createInterface_ = function () { + this.createCanvases_(); + this.createZoomHandles_(); + this.initInteraction_(); + + // Range selector and animatedZooms have a bad interaction. See issue 359. + if (this.getOption_('animatedZooms')) { + console.warn('Animated zooms and range selector are not compatible; disabling animatedZooms.'); + this.dygraph_.updateOptions({ animatedZooms: false }, true); + } + + this.interfaceCreated_ = true; + this.addToGraph_(); +}; + +/** + * @private + * Adds the range selector to the graph. + */ +rangeSelector.prototype.addToGraph_ = function () { + var graphDiv = this.graphDiv_ = this.dygraph_.graphDiv; + graphDiv.appendChild(this.bgcanvas_); + graphDiv.appendChild(this.fgcanvas_); + graphDiv.appendChild(this.leftZoomHandle_); + graphDiv.appendChild(this.rightZoomHandle_); +}; + +/** + * @private + * Removes the range selector from the graph. + */ +rangeSelector.prototype.removeFromGraph_ = function () { + var graphDiv = this.graphDiv_; + graphDiv.removeChild(this.bgcanvas_); + graphDiv.removeChild(this.fgcanvas_); + graphDiv.removeChild(this.leftZoomHandle_); + graphDiv.removeChild(this.rightZoomHandle_); + this.graphDiv_ = null; +}; + +/** + * @private + * Called by Layout to allow range selector to reserve its space. + */ +rangeSelector.prototype.reserveSpace_ = function (e) { + if (this.getOption_('showRangeSelector')) { + e.reserveSpaceBottom(this.getOption_('rangeSelectorHeight') + 4); + } +}; + +/** + * @private + * Renders the static portion of the range selector at the predraw stage. + */ +rangeSelector.prototype.renderStaticLayer_ = function () { + if (!this.updateVisibility_()) { + return; + } + this.resize_(); + this.drawStaticLayer_(); +}; + +/** + * @private + * Renders the interactive portion of the range selector after the chart has been drawn. + */ +rangeSelector.prototype.renderInteractiveLayer_ = function () { + if (!this.updateVisibility_() || this.isChangingRange_) { + return; + } + this.placeZoomHandles_(); + this.drawInteractiveLayer_(); +}; + +/** + * @private + * Check to see if the range selector is enabled/disabled and update visibility accordingly. + */ +rangeSelector.prototype.updateVisibility_ = function () { + var enabled = this.getOption_('showRangeSelector'); + if (enabled) { + if (!this.interfaceCreated_) { + this.createInterface_(); + } else if (!this.graphDiv_ || !this.graphDiv_.parentNode) { + this.addToGraph_(); + } + } else if (this.graphDiv_) { + this.removeFromGraph_(); + var dygraph = this.dygraph_; + setTimeout(function () { + dygraph.width_ = 0;dygraph.resize(); + }, 1); + } + return enabled; +}; + +/** + * @private + * Resizes the range selector. + */ +rangeSelector.prototype.resize_ = function () { + function setElementRect(canvas, context, rect) { + var canvasScale = utils.getContextPixelRatio(context); + + canvas.style.top = rect.y + 'px'; + canvas.style.left = rect.x + 'px'; + canvas.width = rect.w * canvasScale; + canvas.height = rect.h * canvasScale; + canvas.style.width = rect.w + 'px'; + canvas.style.height = rect.h + 'px'; + + if (canvasScale != 1) { + context.scale(canvasScale, canvasScale); + } + } + + var plotArea = this.dygraph_.layout_.getPlotArea(); + + var xAxisLabelHeight = 0; + if (this.dygraph_.getOptionForAxis('drawAxis', 'x')) { + xAxisLabelHeight = this.getOption_('xAxisHeight') || this.getOption_('axisLabelFontSize') + 2 * this.getOption_('axisTickSize'); + } + this.canvasRect_ = { + x: plotArea.x, + y: plotArea.y + plotArea.h + xAxisLabelHeight + 4, + w: plotArea.w, + h: this.getOption_('rangeSelectorHeight') + }; + + setElementRect(this.bgcanvas_, this.bgcanvas_ctx_, this.canvasRect_); + setElementRect(this.fgcanvas_, this.fgcanvas_ctx_, this.canvasRect_); +}; + +/** + * @private + * Creates the background and foreground canvases. + */ +rangeSelector.prototype.createCanvases_ = function () { + this.bgcanvas_ = utils.createCanvas(); + this.bgcanvas_.className = 'dygraph-rangesel-bgcanvas'; + this.bgcanvas_.style.position = 'absolute'; + this.bgcanvas_.style.zIndex = 9; + this.bgcanvas_ctx_ = utils.getContext(this.bgcanvas_); + + this.fgcanvas_ = utils.createCanvas(); + this.fgcanvas_.className = 'dygraph-rangesel-fgcanvas'; + this.fgcanvas_.style.position = 'absolute'; + this.fgcanvas_.style.zIndex = 9; + this.fgcanvas_.style.cursor = 'default'; + this.fgcanvas_ctx_ = utils.getContext(this.fgcanvas_); +}; + +/** + * @private + * Creates the zoom handle elements. + */ +rangeSelector.prototype.createZoomHandles_ = function () { + var img = new Image(); + img.className = 'dygraph-rangesel-zoomhandle'; + img.style.position = 'absolute'; + img.style.zIndex = 10; + img.style.visibility = 'hidden'; // Initially hidden so they don't show up in the wrong place. + img.style.cursor = 'col-resize'; + // TODO: change image to more options + img.width = 9; + img.height = 16; + img.src = 'data:image/png;base64,' + 'iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAA' + 'zwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENv' + 'bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl' + '6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7s' + 'qSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII='; + + if (this.isMobileDevice_) { + img.width *= 2; + img.height *= 2; + } + + this.leftZoomHandle_ = img; + this.rightZoomHandle_ = img.cloneNode(false); +}; + +/** + * @private + * Sets up the interaction for the range selector. + */ +rangeSelector.prototype.initInteraction_ = function () { + var self = this; + var topElem = document; + var clientXLast = 0; + var handle = null; + var isZooming = false; + var isPanning = false; + var dynamic = !this.isMobileDevice_; + + // We cover iframes during mouse interactions. See comments in + // dygraph-utils.js for more info on why this is a good idea. + var tarp = new _iframeTarp2['default'](); + + // functions, defined below. Defining them this way (rather than with + // "function foo() {...}" makes JSHint happy. + var toXDataWindow, onZoomStart, onZoom, onZoomEnd, doZoom, isMouseInPanZone, onPanStart, onPan, onPanEnd, doPan, onCanvasHover; + + // Touch event functions + var onZoomHandleTouchEvent, onCanvasTouchEvent, addTouchEvents; + + toXDataWindow = function (zoomHandleStatus) { + var xDataLimits = self.dygraph_.xAxisExtremes(); + var fact = (xDataLimits[1] - xDataLimits[0]) / self.canvasRect_.w; + var xDataMin = xDataLimits[0] + (zoomHandleStatus.leftHandlePos - self.canvasRect_.x) * fact; + var xDataMax = xDataLimits[0] + (zoomHandleStatus.rightHandlePos - self.canvasRect_.x) * fact; + return [xDataMin, xDataMax]; + }; + + onZoomStart = function (e) { + utils.cancelEvent(e); + isZooming = true; + clientXLast = e.clientX; + handle = e.target ? e.target : e.srcElement; + if (e.type === 'mousedown' || e.type === 'dragstart') { + // These events are removed manually. + utils.addEvent(topElem, 'mousemove', onZoom); + utils.addEvent(topElem, 'mouseup', onZoomEnd); + } + self.fgcanvas_.style.cursor = 'col-resize'; + tarp.cover(); + return true; + }; + + onZoom = function (e) { + if (!isZooming) { + return false; + } + utils.cancelEvent(e); + + var delX = e.clientX - clientXLast; + if (Math.abs(delX) < 4) { + return true; + } + clientXLast = e.clientX; + + // Move handle. + var zoomHandleStatus = self.getZoomHandleStatus_(); + var newPos; + if (handle == self.leftZoomHandle_) { + newPos = zoomHandleStatus.leftHandlePos + delX; + newPos = Math.min(newPos, zoomHandleStatus.rightHandlePos - handle.width - 3); + newPos = Math.max(newPos, self.canvasRect_.x); + } else { + newPos = zoomHandleStatus.rightHandlePos + delX; + newPos = Math.min(newPos, self.canvasRect_.x + self.canvasRect_.w); + newPos = Math.max(newPos, zoomHandleStatus.leftHandlePos + handle.width + 3); + } + var halfHandleWidth = handle.width / 2; + handle.style.left = newPos - halfHandleWidth + 'px'; + self.drawInteractiveLayer_(); + + // Zoom on the fly. + if (dynamic) { + doZoom(); + } + return true; + }; + + onZoomEnd = function (e) { + if (!isZooming) { + return false; + } + isZooming = false; + tarp.uncover(); + utils.removeEvent(topElem, 'mousemove', onZoom); + utils.removeEvent(topElem, 'mouseup', onZoomEnd); + self.fgcanvas_.style.cursor = 'default'; + + // If on a slower device, zoom now. + if (!dynamic) { + doZoom(); + } + return true; + }; + + doZoom = function () { + try { + var zoomHandleStatus = self.getZoomHandleStatus_(); + self.isChangingRange_ = true; + if (!zoomHandleStatus.isZoomed) { + self.dygraph_.resetZoom(); + } else { + var xDataWindow = toXDataWindow(zoomHandleStatus); + self.dygraph_.doZoomXDates_(xDataWindow[0], xDataWindow[1]); + } + } finally { + self.isChangingRange_ = false; + } + }; + + isMouseInPanZone = function (e) { + var rect = self.leftZoomHandle_.getBoundingClientRect(); + var leftHandleClientX = rect.left + rect.width / 2; + rect = self.rightZoomHandle_.getBoundingClientRect(); + var rightHandleClientX = rect.left + rect.width / 2; + return e.clientX > leftHandleClientX && e.clientX < rightHandleClientX; + }; + + onPanStart = function (e) { + if (!isPanning && isMouseInPanZone(e) && self.getZoomHandleStatus_().isZoomed) { + utils.cancelEvent(e); + isPanning = true; + clientXLast = e.clientX; + if (e.type === 'mousedown') { + // These events are removed manually. + utils.addEvent(topElem, 'mousemove', onPan); + utils.addEvent(topElem, 'mouseup', onPanEnd); + } + return true; + } + return false; + }; + + onPan = function (e) { + if (!isPanning) { + return false; + } + utils.cancelEvent(e); + + var delX = e.clientX - clientXLast; + if (Math.abs(delX) < 4) { + return true; + } + clientXLast = e.clientX; + + // Move range view + var zoomHandleStatus = self.getZoomHandleStatus_(); + var leftHandlePos = zoomHandleStatus.leftHandlePos; + var rightHandlePos = zoomHandleStatus.rightHandlePos; + var rangeSize = rightHandlePos - leftHandlePos; + if (leftHandlePos + delX <= self.canvasRect_.x) { + leftHandlePos = self.canvasRect_.x; + rightHandlePos = leftHandlePos + rangeSize; + } else if (rightHandlePos + delX >= self.canvasRect_.x + self.canvasRect_.w) { + rightHandlePos = self.canvasRect_.x + self.canvasRect_.w; + leftHandlePos = rightHandlePos - rangeSize; + } else { + leftHandlePos += delX; + rightHandlePos += delX; + } + var halfHandleWidth = self.leftZoomHandle_.width / 2; + self.leftZoomHandle_.style.left = leftHandlePos - halfHandleWidth + 'px'; + self.rightZoomHandle_.style.left = rightHandlePos - halfHandleWidth + 'px'; + self.drawInteractiveLayer_(); + + // Do pan on the fly. + if (dynamic) { + doPan(); + } + return true; + }; + + onPanEnd = function (e) { + if (!isPanning) { + return false; + } + isPanning = false; + utils.removeEvent(topElem, 'mousemove', onPan); + utils.removeEvent(topElem, 'mouseup', onPanEnd); + // If on a slower device, do pan now. + if (!dynamic) { + doPan(); + } + return true; + }; + + doPan = function () { + try { + self.isChangingRange_ = true; + self.dygraph_.dateWindow_ = toXDataWindow(self.getZoomHandleStatus_()); + self.dygraph_.drawGraph_(false); + } finally { + self.isChangingRange_ = false; + } + }; + + onCanvasHover = function (e) { + if (isZooming || isPanning) { + return; + } + var cursor = isMouseInPanZone(e) ? 'move' : 'default'; + if (cursor != self.fgcanvas_.style.cursor) { + self.fgcanvas_.style.cursor = cursor; + } + }; + + onZoomHandleTouchEvent = function (e) { + if (e.type == 'touchstart' && e.targetTouches.length == 1) { + if (onZoomStart(e.targetTouches[0])) { + utils.cancelEvent(e); + } + } else if (e.type == 'touchmove' && e.targetTouches.length == 1) { + if (onZoom(e.targetTouches[0])) { + utils.cancelEvent(e); + } + } else { + onZoomEnd(e); + } + }; + + onCanvasTouchEvent = function (e) { + if (e.type == 'touchstart' && e.targetTouches.length == 1) { + if (onPanStart(e.targetTouches[0])) { + utils.cancelEvent(e); + } + } else if (e.type == 'touchmove' && e.targetTouches.length == 1) { + if (onPan(e.targetTouches[0])) { + utils.cancelEvent(e); + } + } else { + onPanEnd(e); + } + }; + + addTouchEvents = function (elem, fn) { + var types = ['touchstart', 'touchend', 'touchmove', 'touchcancel']; + for (var i = 0; i < types.length; i++) { + self.dygraph_.addAndTrackEvent(elem, types[i], fn); + } + }; + + this.setDefaultOption_('interactionModel', _dygraphInteractionModel2['default'].dragIsPanInteractionModel); + this.setDefaultOption_('panEdgeFraction', 0.0001); + + var dragStartEvent = window.opera ? 'mousedown' : 'dragstart'; + this.dygraph_.addAndTrackEvent(this.leftZoomHandle_, dragStartEvent, onZoomStart); + this.dygraph_.addAndTrackEvent(this.rightZoomHandle_, dragStartEvent, onZoomStart); + + this.dygraph_.addAndTrackEvent(this.fgcanvas_, 'mousedown', onPanStart); + this.dygraph_.addAndTrackEvent(this.fgcanvas_, 'mousemove', onCanvasHover); + + // Touch events + if (this.hasTouchInterface_) { + addTouchEvents(this.leftZoomHandle_, onZoomHandleTouchEvent); + addTouchEvents(this.rightZoomHandle_, onZoomHandleTouchEvent); + addTouchEvents(this.fgcanvas_, onCanvasTouchEvent); + } +}; + +/** + * @private + * Draws the static layer in the background canvas. + */ +rangeSelector.prototype.drawStaticLayer_ = function () { + var ctx = this.bgcanvas_ctx_; + ctx.clearRect(0, 0, this.canvasRect_.w, this.canvasRect_.h); + try { + this.drawMiniPlot_(); + } catch (ex) { + console.warn(ex); + } + + var margin = 0.5; + this.bgcanvas_ctx_.lineWidth = this.getOption_('rangeSelectorBackgroundLineWidth'); + ctx.strokeStyle = this.getOption_('rangeSelectorBackgroundStrokeColor'); + ctx.beginPath(); + ctx.moveTo(margin, margin); + ctx.lineTo(margin, this.canvasRect_.h - margin); + ctx.lineTo(this.canvasRect_.w - margin, this.canvasRect_.h - margin); + ctx.lineTo(this.canvasRect_.w - margin, margin); + ctx.stroke(); +}; + +/** + * @private + * Draws the mini plot in the background canvas. + */ +rangeSelector.prototype.drawMiniPlot_ = function () { + var fillStyle = this.getOption_('rangeSelectorPlotFillColor'); + var fillGradientStyle = this.getOption_('rangeSelectorPlotFillGradientColor'); + var strokeStyle = this.getOption_('rangeSelectorPlotStrokeColor'); + if (!fillStyle && !strokeStyle) { + return; + } + + var stepPlot = this.getOption_('stepPlot'); + + var combinedSeriesData = this.computeCombinedSeriesAndLimits_(); + var yRange = combinedSeriesData.yMax - combinedSeriesData.yMin; + + // Draw the mini plot. + var ctx = this.bgcanvas_ctx_; + var margin = 0.5; + + var xExtremes = this.dygraph_.xAxisExtremes(); + var xRange = Math.max(xExtremes[1] - xExtremes[0], 1.e-30); + var xFact = (this.canvasRect_.w - margin) / xRange; + var yFact = (this.canvasRect_.h - margin) / yRange; + var canvasWidth = this.canvasRect_.w - margin; + var canvasHeight = this.canvasRect_.h - margin; + + var prevX = null, + prevY = null; + + ctx.beginPath(); + ctx.moveTo(margin, canvasHeight); + for (var i = 0; i < combinedSeriesData.data.length; i++) { + var dataPoint = combinedSeriesData.data[i]; + var x = dataPoint[0] !== null ? (dataPoint[0] - xExtremes[0]) * xFact : NaN; + var y = dataPoint[1] !== null ? canvasHeight - (dataPoint[1] - combinedSeriesData.yMin) * yFact : NaN; + + // Skip points that don't change the x-value. Overly fine-grained points + // can cause major slowdowns with the ctx.fill() call below. + if (!stepPlot && prevX !== null && Math.round(x) == Math.round(prevX)) { + continue; + } + + if (isFinite(x) && isFinite(y)) { + if (prevX === null) { + ctx.lineTo(x, canvasHeight); + } else if (stepPlot) { + ctx.lineTo(x, prevY); + } + ctx.lineTo(x, y); + prevX = x; + prevY = y; + } else { + if (prevX !== null) { + if (stepPlot) { + ctx.lineTo(x, prevY); + ctx.lineTo(x, canvasHeight); + } else { + ctx.lineTo(prevX, canvasHeight); + } + } + prevX = prevY = null; + } + } + ctx.lineTo(canvasWidth, canvasHeight); + ctx.closePath(); + + if (fillStyle) { + var lingrad = this.bgcanvas_ctx_.createLinearGradient(0, 0, 0, canvasHeight); + if (fillGradientStyle) { + lingrad.addColorStop(0, fillGradientStyle); + } + lingrad.addColorStop(1, fillStyle); + this.bgcanvas_ctx_.fillStyle = lingrad; + ctx.fill(); + } + + if (strokeStyle) { + this.bgcanvas_ctx_.strokeStyle = strokeStyle; + this.bgcanvas_ctx_.lineWidth = this.getOption_('rangeSelectorPlotLineWidth'); + ctx.stroke(); + } +}; + +/** + * @private + * Computes and returns the combined series data along with min/max for the mini plot. + * The combined series consists of averaged values for all series. + * When series have error bars, the error bars are ignored. + * @return {Object} An object containing combined series array, ymin, ymax. + */ +rangeSelector.prototype.computeCombinedSeriesAndLimits_ = function () { + var g = this.dygraph_; + var logscale = this.getOption_('logscale'); + var i; + + // Select series to combine. By default, all series are combined. + var numColumns = g.numColumns(); + var labels = g.getLabels(); + var includeSeries = new Array(numColumns); + var anySet = false; + var visibility = g.visibility(); + var inclusion = []; + + for (i = 1; i < numColumns; i++) { + var include = this.getOption_('showInRangeSelector', labels[i]); + inclusion.push(include); + if (include !== null) anySet = true; // it's set explicitly for this series + } + + if (anySet) { + for (i = 1; i < numColumns; i++) { + includeSeries[i] = inclusion[i - 1]; + } + } else { + for (i = 1; i < numColumns; i++) { + includeSeries[i] = visibility[i - 1]; + } + } + + // Create a combined series (average of selected series values). + // TODO(danvk): short-circuit if there's only one series. + var rolledSeries = []; + var dataHandler = g.dataHandler_; + var options = g.attributes_; + for (i = 1; i < g.numColumns(); i++) { + if (!includeSeries[i]) continue; + var series = dataHandler.extractSeries(g.rawData_, i, options); + if (g.rollPeriod() > 1) { + series = dataHandler.rollingAverage(series, g.rollPeriod(), options); + } + + rolledSeries.push(series); + } + + var combinedSeries = []; + for (i = 0; i < rolledSeries[0].length; i++) { + var sum = 0; + var count = 0; + for (var j = 0; j < rolledSeries.length; j++) { + var y = rolledSeries[j][i][1]; + if (y === null || isNaN(y)) continue; + count++; + sum += y; + } + combinedSeries.push([rolledSeries[0][i][0], sum / count]); + } + + // Compute the y range. + var yMin = Number.MAX_VALUE; + var yMax = -Number.MAX_VALUE; + for (i = 0; i < combinedSeries.length; i++) { + var yVal = combinedSeries[i][1]; + if (yVal !== null && isFinite(yVal) && (!logscale || yVal > 0)) { + yMin = Math.min(yMin, yVal); + yMax = Math.max(yMax, yVal); + } + } + + // Convert Y data to log scale if needed. + // Also, expand the Y range to compress the mini plot a little. + var extraPercent = 0.25; + if (logscale) { + yMax = utils.log10(yMax); + yMax += yMax * extraPercent; + yMin = utils.log10(yMin); + for (i = 0; i < combinedSeries.length; i++) { + combinedSeries[i][1] = utils.log10(combinedSeries[i][1]); + } + } else { + var yExtra; + var yRange = yMax - yMin; + if (yRange <= Number.MIN_VALUE) { + yExtra = yMax * extraPercent; + } else { + yExtra = yRange * extraPercent; + } + yMax += yExtra; + yMin -= yExtra; + } + + return { data: combinedSeries, yMin: yMin, yMax: yMax }; +}; + +/** + * @private + * Places the zoom handles in the proper position based on the current X data window. + */ +rangeSelector.prototype.placeZoomHandles_ = function () { + var xExtremes = this.dygraph_.xAxisExtremes(); + var xWindowLimits = this.dygraph_.xAxisRange(); + var xRange = xExtremes[1] - xExtremes[0]; + var leftPercent = Math.max(0, (xWindowLimits[0] - xExtremes[0]) / xRange); + var rightPercent = Math.max(0, (xExtremes[1] - xWindowLimits[1]) / xRange); + var leftCoord = this.canvasRect_.x + this.canvasRect_.w * leftPercent; + var rightCoord = this.canvasRect_.x + this.canvasRect_.w * (1 - rightPercent); + var handleTop = Math.max(this.canvasRect_.y, this.canvasRect_.y + (this.canvasRect_.h - this.leftZoomHandle_.height) / 2); + var halfHandleWidth = this.leftZoomHandle_.width / 2; + this.leftZoomHandle_.style.left = leftCoord - halfHandleWidth + 'px'; + this.leftZoomHandle_.style.top = handleTop + 'px'; + this.rightZoomHandle_.style.left = rightCoord - halfHandleWidth + 'px'; + this.rightZoomHandle_.style.top = this.leftZoomHandle_.style.top; + + this.leftZoomHandle_.style.visibility = 'visible'; + this.rightZoomHandle_.style.visibility = 'visible'; +}; + +/** + * @private + * Draws the interactive layer in the foreground canvas. + */ +rangeSelector.prototype.drawInteractiveLayer_ = function () { + var ctx = this.fgcanvas_ctx_; + ctx.clearRect(0, 0, this.canvasRect_.w, this.canvasRect_.h); + var margin = 1; + var width = this.canvasRect_.w - margin; + var height = this.canvasRect_.h - margin; + var zoomHandleStatus = this.getZoomHandleStatus_(); + + ctx.strokeStyle = this.getOption_('rangeSelectorForegroundStrokeColor'); + ctx.lineWidth = this.getOption_('rangeSelectorForegroundLineWidth'); + if (!zoomHandleStatus.isZoomed) { + ctx.beginPath(); + ctx.moveTo(margin, margin); + ctx.lineTo(margin, height); + ctx.lineTo(width, height); + ctx.lineTo(width, margin); + ctx.stroke(); + } else { + var leftHandleCanvasPos = Math.max(margin, zoomHandleStatus.leftHandlePos - this.canvasRect_.x); + var rightHandleCanvasPos = Math.min(width, zoomHandleStatus.rightHandlePos - this.canvasRect_.x); + + ctx.fillStyle = 'rgba(240, 240, 240, ' + this.getOption_('rangeSelectorAlpha').toString() + ')'; + ctx.fillRect(0, 0, leftHandleCanvasPos, this.canvasRect_.h); + ctx.fillRect(rightHandleCanvasPos, 0, this.canvasRect_.w - rightHandleCanvasPos, this.canvasRect_.h); + + ctx.beginPath(); + ctx.moveTo(margin, margin); + ctx.lineTo(leftHandleCanvasPos, margin); + ctx.lineTo(leftHandleCanvasPos, height); + ctx.lineTo(rightHandleCanvasPos, height); + ctx.lineTo(rightHandleCanvasPos, margin); + ctx.lineTo(width, margin); + ctx.stroke(); + } +}; + +/** + * @private + * Returns the current zoom handle position information. + * @return {Object} The zoom handle status. + */ +rangeSelector.prototype.getZoomHandleStatus_ = function () { + var halfHandleWidth = this.leftZoomHandle_.width / 2; + var leftHandlePos = parseFloat(this.leftZoomHandle_.style.left) + halfHandleWidth; + var rightHandlePos = parseFloat(this.rightZoomHandle_.style.left) + halfHandleWidth; + return { + leftHandlePos: leftHandlePos, + rightHandlePos: rightHandlePos, + isZoomed: leftHandlePos - 1 > this.canvasRect_.x || rightHandlePos + 1 < this.canvasRect_.x + this.canvasRect_.w + }; +}; + +exports['default'] = rangeSelector; +module.exports = exports['default']; + +},{"../dygraph-interaction-model":12,"../dygraph-utils":17,"../iframe-tarp":19}]},{},[18])(18) +}); +//# sourceMappingURL=dygraph.js.map diff --git a/ExampleHTM/dygraph/dygraph.min.js b/ExampleHTM/dygraph/dygraph.min.js new file mode 100644 index 0000000..e3851bf --- /dev/null +++ b/ExampleHTM/dygraph/dygraph.min.js @@ -0,0 +1,6 @@ +/*! @license Copyright 2017 Dan Vanderkam (danvdk@gmail.com) MIT-licensed (http://opensource.org/licenses/MIT) */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Dygraph=t()}}(function(){return function t(e,a,i){function n(o,s){if(!a[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var h=new Error("Cannot find module '"+o+"'");throw h.code="MODULE_NOT_FOUND",h}var u=a[o]={exports:{}};e[o][0].call(u.exports,function(t){var a=e[o][1][t];return n(a?a:t)},u,u.exports,t,e,a,i)}return a[o].exports}for(var r="function"==typeof require&&require,o=0;o1)for(var a=1;a=0){var d=t[l-e];null===d[1]||isNaN(d[1])||(n-=d[2][0],o-=d[1],r-=d[2][1],s-=1)}s?u[l]=[t[l][0],1*o/s,[1*n/s,1*r/s]]:u[l]=[t[l][0],null,[null,null]]}return u},a.default=o,e.exports=a.default},{"./bars":5}],3:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./bars"),r=i(n),o=function(){};o.prototype=new r.default,o.prototype.extractSeries=function(t,e,a){for(var i,n,r,o,s=[],l=a.get("sigma"),h=a.get("logscale"),u=0;u=0&&(u-=t[r-e][2][2],d-=t[r-e][2][3]);var p=t[r][0],g=d?u/d:0;if(h)if(d){var f=g<0?0:g,v=d,_=l*Math.sqrt(f*(1-f)/v+l*l/(4*v*v)),y=1+l*l/d;i=(f+l*l/(2*d)-_)/y,n=(f+l*l/(2*d)+_)/y,s[r]=[p,f*c,[i*c,n*c]]}else s[r]=[p,0,[0,0]];else o=d?l*Math.sqrt(g*(1-g)/d):1,s[r]=[p,c*g,[c*(g-o),c*(g+o)]]}return s},a.default=o,e.exports=a.default},{"./bars":5}],5:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./datahandler"),r=i(n),o=t("../dygraph-layout"),s=i(o),l=function(){r.default.call(this)};l.prototype=new r.default,l.prototype.extractSeries=function(t,e,a){},l.prototype.rollingAverage=function(t,e,a){},l.prototype.onPointsCreated_=function(t,e){for(var a=0;ai&&(h=i),ur)&&(r=u),(null===n||h=0&&(r-=t[i-e][2][0],o-=t[i-e][2][1]);var l=t[i][0],h=o?r/o:0;n[i]=[l,s*h]}return n},a.default=s,e.exports=a.default},{"./datahandler":6,"./default":8}],8:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./datahandler"),r=i(n),o=function(){};o.prototype=new r.default,o.prototype.extractSeries=function(t,e,a){for(var i=[],n=a.get("logscale"),r=0;rr)&&(r=i),(null===n||i=2,v=t.drawingContext;v.save(),f&&v.setLineDash&&v.setLineDash(i);var _=h._drawSeries(t,g,a,s,n,d,u,e);h._drawPointsOnLine(t,_,r,e,s),f&&v.setLineDash&&v.setLineDash([]),v.restore()},h._drawSeries=function(t,e,a,i,n,r,o,s){var l,h,u=null,d=null,c=null,p=[],g=!0,f=t.drawingContext;f.beginPath(),f.strokeStyle=s,f.lineWidth=a;for(var v=e.array_,_=e.end_,y=e.predicate_,x=e.start_;x<_;x++){if(h=v[x],y){for(;x<_&&!y(v,x);)x++;if(x==_)break;h=v[x]}if(null===h.canvasy||h.canvasy!=h.canvasy)o&&null!==u&&(f.moveTo(u,d),f.lineTo(h.canvasx,d)),u=d=null;else{if(l=!1,r||null===u){e.nextIdx_=x,e.next(),c=e.hasNext?e.peek.canvasy:null;var m=null===c||c!=c;l=null===u&&m,r&&(!g&&null===u||e.hasNext&&m)&&(l=!0)}null!==u?a&&(o&&(f.moveTo(u,d),f.lineTo(h.canvasx,d)),f.lineTo(h.canvasx,h.canvasy)):f.moveTo(h.canvasx,h.canvasy),(n||l)&&p.push([h.canvasx,h.canvasy,h.idx]),u=h.canvasx,d=h.canvasy}g=!1}return f.stroke(),p},h._drawPointsOnLine=function(t,e,a,i,n){for(var r=t.drawingContext,o=0;o0;a--){var i=e[a];if(i[0]==r){var o=e[a-1];o[1]==i[1]&&o[2]==i[2]&&e.splice(a,1)}}for(var a=0;a2&&!t){var s=0;e[0][0]==r&&s++;for(var l=null,h=null,a=s;ae[h][2]&&(h=a)}}var d=e[l],c=e[h];e.splice(s,e.length-s),lh?(e.push(c),e.push(d)):e.push(d)}}},l=function(a){s(a);for(var l=0,h=e.length;l1,h=o-a>1,u=s||h;l(u),a=o}e.push([t,n,r])};return{moveTo:function(t,e){h(r,t,e)},lineTo:function(t,e){h(n,t,e)},stroke:function(){l(!0),t.stroke()},fill:function(){l(!0),t.fill()},beginPath:function(){l(!0),t.beginPath()},closePath:function(){l(!0),t.closePath()},_count:function(){return o}}},h._fillPlotter=function(t){if(!t.singleSeriesName&&0===t.seriesIndex){for(var e=t.dygraph,a=e.getLabels().slice(1),i=a.length;i>=0;i--)e.visibility()[i]||a.splice(i,1);var n=function(){for(var t=0;t=0;n--){var r=i[n];t.lineTo(r[0],r[1])}},_=c-1;_>=0;_--){var y=t.drawingContext,x=a[_];if(e.getBooleanOption("fillGraph",x)){var m=e.getNumericOption("fillAlpha",x),b=e.getBooleanOption("stepPlot",x),w=g[_],A=e.axisPropertiesForSeries(x),O=1+A.minyval*A.yscale;O<0?O=0:O>1&&(O=1),O=u.h*O+u.y;var T,D=d[_],E=o.createIterator(D,0,D.length,h._getIteratorPredicate(e.getBooleanOption("connectSeparatedPoints",x))),P=NaN,S=[-1,-1],L=o.toRGB_(w),C="rgba("+L.r+","+L.g+","+L.b+","+m+")";y.fillStyle=C,y.beginPath();var M,N=!0;(D.length>2*e.width_||l.default.FORCE_FAST_PROXY)&&(y=h._fastCanvasProxy(y));for(var k,F=[];E.hasNext;)if(k=E.next(),o.isOK(k.y)||b){if(p){if(!N&&M==k.xval)continue;N=!1,M=k.xval,r=f[k.canvasx];var R;R=void 0===r?O:s?r[0]:r,T=[k.canvasy,R],b?S[0]===-1?f[k.canvasx]=[k.canvasy,O]:f[k.canvasx]=[k.canvasy,S[0]]:f[k.canvasx]=k.canvasy}else T=isNaN(k.canvasy)&&b?[u.y+u.h,O]:[k.canvasy,O];isNaN(P)?(y.moveTo(k.canvasx,T[1]),y.lineTo(k.canvasx,T[0])):(b?(y.lineTo(k.canvasx,S[0]),y.lineTo(k.canvasx,T[0])):y.lineTo(k.canvasx,T[0]),p&&(F.push([P,S[1]]),s&&r?F.push([k.canvasx,r[1]]):F.push([k.canvasx,T[1]]))),S=T,P=k.canvasx}else v(y,P,S[1],F),F=[],P=NaN,null===k.y_stacked||isNaN(k.y_stacked)||(f[k.canvasx]=u.h*k.y_stacked+u.y);s=b,T&&k&&(v(y,k.canvasx,T[1],F),F=[]),y.fill()}}}},a.default=h,e.exports=a.default},{"./dygraph":18,"./dygraph-utils":17}],10:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}Object.defineProperty(a,"__esModule",{value:!0});var r=t("./dygraph-tickers"),o=n(r),s=t("./dygraph-interaction-model"),l=i(s),h=t("./dygraph-canvas"),u=i(h),d=t("./dygraph-utils"),c=n(d),p={highlightCircleSize:3,highlightSeriesOpts:null,highlightSeriesBackgroundAlpha:.5,highlightSeriesBackgroundColor:"rgb(255, 255, 255)",labelsSeparateLines:!1,labelsShowZeroValues:!0,labelsKMB:!1,labelsKMG2:!1,showLabelsOnHighlight:!0,digitsAfterDecimal:2,maxNumberWidth:6,sigFigs:null,strokeWidth:1,strokeBorderWidth:0,strokeBorderColor:"white",axisTickSize:3,axisLabelFontSize:14,rightGap:5,showRoller:!1,xValueParser:void 0,delimiter:",",sigma:2,errorBars:!1,fractions:!1,wilsonInterval:!0,customBars:!1,fillGraph:!1,fillAlpha:.15,connectSeparatedPoints:!1,stackedGraph:!1,stackedGraphNaNFill:"all",hideOverlayOnMouseOut:!0,legend:"onmouseover",stepPlot:!1,xRangePad:0,yRangePad:null,drawAxesAtZero:!1,titleHeight:28,xLabelHeight:18,yLabelWidth:18,axisLineColor:"black",axisLineWidth:.3,gridLineWidth:.3,axisLabelWidth:50,gridLineColor:"rgb(128,128,128)",interactionModel:l.default.defaultModel,animatedZooms:!1,showRangeSelector:!1,rangeSelectorHeight:40,rangeSelectorPlotStrokeColor:"#808FAB",rangeSelectorPlotFillGradientColor:"white",rangeSelectorPlotFillColor:"#A7B1C4",rangeSelectorBackgroundStrokeColor:"gray",rangeSelectorBackgroundLineWidth:1,rangeSelectorPlotLineWidth:1.5,rangeSelectorForegroundStrokeColor:"black",rangeSelectorForegroundLineWidth:1,rangeSelectorAlpha:.6,showInRangeSelector:null,plotter:[u.default._fillPlotter,u.default._errorPlotter,u.default._linePlotter],plugins:[],axes:{x:{pixelsPerLabel:70,axisLabelWidth:60,axisLabelFormatter:c.dateAxisLabelFormatter,valueFormatter:c.dateValueFormatter,drawGrid:!0,drawAxis:!0,independentTicks:!0,ticker:o.dateTicker},y:{axisLabelWidth:50,pixelsPerLabel:30,valueFormatter:c.numberValueFormatter,axisLabelFormatter:c.numberAxisLabelFormatter,drawGrid:!0,drawAxis:!0,independentTicks:!0,ticker:o.numericTicks},y2:{axisLabelWidth:50,pixelsPerLabel:30,valueFormatter:c.numberValueFormatter,axisLabelFormatter:c.numberAxisLabelFormatter,drawAxis:!0,drawGrid:!1,independentTicks:!1,ticker:o.numericTicks}}};a.default=p,e.exports=a.default},{"./dygraph-canvas":9,"./dygraph-interaction-model":12,"./dygraph-tickers":16,"./dygraph-utils":17}],11:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./dygraph"),r=i(n),o=function(t){this.container=t};o.prototype.draw=function(t,e){this.container.innerHTML="","undefined"!=typeof this.date_graph&&this.date_graph.destroy(),this.date_graph=new r.default(this.container,t,e)},o.prototype.setSelection=function(t){var e=!1;t.length&&(e=t[0].row),this.date_graph.setSelection(e)},o.prototype.getSelection=function(){var t=[],e=this.date_graph.getSelection();if(e<0)return t;for(var a=this.date_graph.layout_.points,i=0;ia.boundedDates[1]&&(i-=n-a.boundedDates[1],n=i+a.dateRange),e.getOptionForAxis("logscale","x")?e.dateWindow_=[Math.pow(r.LOG_SCALE,i),Math.pow(r.LOG_SCALE,n)]:e.dateWindow_=[i,n],a.is2DPan)for(var o=a.dragEndY-a.dragStartY,s=0;s=10&&a.dragDirection==r.HORIZONTAL){var n=Math.min(a.dragStartX,a.dragEndX),o=Math.max(a.dragStartX,a.dragEndX);n=Math.max(n,i.x),o=Math.min(o,i.x+i.w),n=10&&a.dragDirection==r.VERTICAL){var l=Math.min(a.dragStartY,a.dragEndY),h=Math.max(a.dragStartY,a.dragEndY);l=Math.max(l,i.y),h=Math.min(h,i.y+i.h),l1&&(a.startTimeForDoubleTapMs=null);for(var i=[],n=0;n=2){a.initialPinchCenter={pageX:.5*(i[0].pageX+i[1].pageX),pageY:.5*(i[0].pageY+i[1].pageY),dataX:.5*(i[0].dataX+i[1].dataX),dataY:.5*(i[0].dataY+i[1].dataY)};var o=180/Math.PI*Math.atan2(a.initialPinchCenter.pageY-i[0].pageY,i[0].pageX-a.initialPinchCenter.pageX);o=Math.abs(o),o>90&&(o=90-o),a.touchDirections={x:o<67.5,y:o>22.5}}a.initialRange={x:e.xAxisRange(),y:e.yAxisRange()}},s.moveTouch=function(t,e,a){a.startTimeForDoubleTapMs=null;var i,n=[];for(i=0;i=2){var g=s[1].pageX-l.pageX;c=(n[1].pageX-o.pageX)/g;var f=s[1].pageY-l.pageY;p=(n[1].pageY-o.pageY)/f}c=Math.min(8,Math.max(.125,c)),p=Math.min(8,Math.max(.125,p));var v=!1;if(a.touchDirections.x&&(e.dateWindow_=[l.dataX-h.dataX+(a.initialRange.x[0]-l.dataX)/c,l.dataX-h.dataX+(a.initialRange.x[1]-l.dataX)/c],v=!0),a.touchDirections.y)for(i=0;i<1;i++){var _=e.axes_[i],y=e.attributes_.getForAxis("logscale",i);y||(_.valueRange=[l.dataY-h.dataY+(a.initialRange.y[0]-l.dataY)/p,l.dataY-h.dataY+(a.initialRange.y[1]-l.dataY)/p],v=!0)}if(e.drawGraph_(!1),v&&n.length>1&&e.getFunctionOption("zoomCallback")){var x=e.xAxisRange();e.getFunctionOption("zoomCallback").call(e,x[0],x[1],e.yAxisRanges())}},s.endTouch=function(t,e,a){if(0!==t.touches.length)s.startTouch(t,e,a);else if(1==t.changedTouches.length){var i=(new Date).getTime(),n=t.changedTouches[0];a.startTimeForDoubleTapMs&&i-a.startTimeForDoubleTapMs<500&&a.doubleTapX&&Math.abs(a.doubleTapX-n.screenX)<50&&a.doubleTapY&&Math.abs(a.doubleTapY-n.screenY)<50?e.resetZoom():(a.startTimeForDoubleTapMs=i,a.doubleTapX=n.screenX,a.doubleTapY=n.screenY)}};var l=function(t,e,a){return ta?t-a:0},h=function(t,e){var a=r.findPos(e.canvas_),i={left:a.x,right:a.x+e.canvas_.offsetWidth,top:a.y,bottom:a.y+e.canvas_.offsetHeight},n={x:r.pageX(t),y:r.pageY(t)},o=l(n.x,i.left,i.right),s=l(n.y,i.top,i.bottom);return Math.max(o,s)};s.defaultModel={mousedown:function(t,e,a){if(!t.button||2!=t.button){a.initializeMouseDown(t,e,a),t.altKey||t.shiftKey?s.startPan(t,e,a):s.startZoom(t,e,a);var i=function(t){if(a.isZooming){var i=h(t,e);i=0&&i<1&&this.xticks.push({pos:i,label:a,has_tick:r});for(this.yticks=[],t=0;t0&&i<=1&&this.yticks.push({axis:t,pos:i,label:a,has_tick:r})},o.prototype._evaluateAnnotations=function(){var t,e={};for(t=0;t1&&s.update(this.yAxes_[1].options,o.y2||{}),s.update(this.xAxis_.options,o.x||{})}},d.prototype.get=function(t){var e=this.getGlobalUser_(t);return null!==e?e:this.getGlobalDefault_(t)},d.prototype.getGlobalUser_=function(t){return this.user_.hasOwnProperty(t)?this.user_[t]:null},d.prototype.getGlobalDefault_=function(t){return this.global_.hasOwnProperty(t)?this.global_[t]:h.default.hasOwnProperty(t)?h.default[t]:null},d.prototype.getForAxis=function(t,e){var a,i;if("number"==typeof e)a=e,i=0===a?"y":"y2";else{if("y1"==e&&(e="y"),"y"==e)a=0;else if("y2"==e)a=1;else{if("x"!=e)throw"Unknown axis "+e;a=-1}i=e}var n=a==-1?this.xAxis_:this.yAxes_[a];if(n){var r=n.options;if(r.hasOwnProperty(t))return r[t]}if("x"!==e||"logscale"!==t){var o=this.getGlobalUser_(t);if(null!==o)return o}var s=h.default.axes[i];return s.hasOwnProperty(t)?s[t]:this.getGlobalDefault_(t)},d.prototype.getForSeries=function(t,e){if(e===this.dygraph_.getHighlightSeries()&&this.highlightSeries_.hasOwnProperty(t))return this.highlightSeries_[t];if(!this.series_.hasOwnProperty(e))throw"Unknown series: "+e;var a=this.series_[e],i=a.options;return i.hasOwnProperty(t)?i[t]:this.getForAxis(t,a.yAxis)},d.prototype.numAxes=function(){return this.yAxes_.length},d.prototype.axisForSeries=function(t){return this.series_[t].yAxis},d.prototype.axisOptions=function(t){return this.yAxes_[t].options},d.prototype.seriesForAxis=function(t){return this.yAxes_[t].series},d.prototype.seriesNames=function(){return this.labels_},"undefined"!=typeof i);a.default=d,e.exports=a.default}).call(this,t("_process"))},{"./dygraph-default-attrs":10,"./dygraph-options-reference":14,"./dygraph-utils":17,_process:1}],16:[function(t,e,a){"use strict";function i(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}Object.defineProperty(a,"__esModule",{value:!0});var n=t("./dygraph-utils"),r=i(n),o=function(t,e,a,i,n,r){var o=function(t){return"logscale"!==t&&i(t)};return s(t,e,a,o,n,r)};a.numericLinearTicks=o;var s=function(t,e,a,i,n,o){var s,l,h,u,d=i("pixelsPerLabel"),p=[];if(o)for(s=0;s=u/4){for(var _=f;_>=g;_--){var y=c[_],x=Math.log(y/t)/Math.log(e/t)*a,m={v:y};null===v?v={tickValue:y,pixel_coord:x}:Math.abs(x-v.pixel_coord)>=d?v={tickValue:y,pixel_coord:x}:m.label="",p.push(m)}p.reverse()}}if(0===p.length){var b,w,A=i("labelsKMG2");A?(b=[1,2,4,8,16,32,64,128,256],w=16):(b=[1,2,5,10,20,50,100],w=10);var O,T,D,E,P=Math.ceil(a/d),S=Math.abs(e-t)/P,L=Math.floor(Math.log(S)/Math.log(w)),C=Math.pow(w,L);for(l=0;ld));l++);for(T>D&&(O*=-1),s=0;s<=u;s++)h=T+s*O,p.push({v:h})}}var M=i("axisLabelFormatter");for(s=0;s=0?f(t,e,o,i,n):[]};a.dateTicker=l;var h={SECONDLY:0,TWO_SECONDLY:1,FIVE_SECONDLY:2,TEN_SECONDLY:3,THIRTY_SECONDLY:4,MINUTELY:5,TWO_MINUTELY:6,FIVE_MINUTELY:7,TEN_MINUTELY:8,THIRTY_MINUTELY:9,HOURLY:10,TWO_HOURLY:11,SIX_HOURLY:12,DAILY:13,TWO_DAILY:14,WEEKLY:15,MONTHLY:16,QUARTERLY:17,BIANNUAL:18,ANNUAL:19,DECADAL:20,CENTENNIAL:21,NUM_GRANULARITIES:22};a.Granularity=h;var u={DATEFIELD_Y:0,DATEFIELD_M:1,DATEFIELD_D:2,DATEFIELD_HH:3,DATEFIELD_MM:4,DATEFIELD_SS:5,DATEFIELD_MS:6,NUM_DATEFIELDS:7},d=[];d[h.SECONDLY]={datefield:u.DATEFIELD_SS,step:1,spacing:1e3},d[h.TWO_SECONDLY]={datefield:u.DATEFIELD_SS,step:2,spacing:2e3},d[h.FIVE_SECONDLY]={datefield:u.DATEFIELD_SS,step:5,spacing:5e3},d[h.TEN_SECONDLY]={datefield:u.DATEFIELD_SS,step:10,spacing:1e4},d[h.THIRTY_SECONDLY]={datefield:u.DATEFIELD_SS,step:30,spacing:3e4},d[h.MINUTELY]={datefield:u.DATEFIELD_MM,step:1,spacing:6e4},d[h.TWO_MINUTELY]={datefield:u.DATEFIELD_MM,step:2,spacing:12e4},d[h.FIVE_MINUTELY]={datefield:u.DATEFIELD_MM,step:5,spacing:3e5},d[h.TEN_MINUTELY]={datefield:u.DATEFIELD_MM,step:10,spacing:6e5},d[h.THIRTY_MINUTELY]={datefield:u.DATEFIELD_MM,step:30,spacing:18e5},d[h.HOURLY]={datefield:u.DATEFIELD_HH,step:1,spacing:36e5},d[h.TWO_HOURLY]={datefield:u.DATEFIELD_HH,step:2,spacing:72e5},d[h.SIX_HOURLY]={datefield:u.DATEFIELD_HH,step:6,spacing:216e5},d[h.DAILY]={datefield:u.DATEFIELD_D,step:1,spacing:864e5},d[h.TWO_DAILY]={datefield:u.DATEFIELD_D,step:2,spacing:1728e5},d[h.WEEKLY]={datefield:u.DATEFIELD_D,step:7,spacing:6048e5},d[h.MONTHLY]={datefield:u.DATEFIELD_M,step:1,spacing:2629817280},d[h.QUARTERLY]={datefield:u.DATEFIELD_M,step:3,spacing:216e5*365.2524},d[h.BIANNUAL]={datefield:u.DATEFIELD_M,step:6,spacing:432e5*365.2524},d[h.ANNUAL]={datefield:u.DATEFIELD_Y,step:1,spacing:864e5*365.2524},d[h.DECADAL]={datefield:u.DATEFIELD_Y,step:10,spacing:315578073600},d[h.CENTENNIAL]={datefield:u.DATEFIELD_Y,step:100,spacing:3155780736e3};var c=function(){for(var t=[],e=-39;e<=39;e++)for(var a=Math.pow(10,e),i=1;i<=9;i++){var n=a*i;t.push(n)}return t}(),p=function(t,e,a,i){for(var n=i("pixelsPerLabel"),r=0;r=n)return r}return-1},g=function(t,e,a){var i=d[a].spacing;return Math.round(1*(e-t)/i)},f=function(t,e,a,i,n){var o=i("axisLabelFormatter"),s=i("labelsUTC"),l=s?r.DateAccessorsUTC:r.DateAccessorsLocal,c=d[a].datefield,p=d[a].step,g=d[a].spacing,f=new Date(t),v=[];v[u.DATEFIELD_Y]=l.getFullYear(f),v[u.DATEFIELD_M]=l.getMonth(f),v[u.DATEFIELD_D]=l.getDate(f),v[u.DATEFIELD_HH]=l.getHours(f),v[u.DATEFIELD_MM]=l.getMinutes(f),v[u.DATEFIELD_SS]=l.getSeconds(f),v[u.DATEFIELD_MS]=l.getMilliseconds(f);var _=v[c]%p;a==h.WEEKLY&&(_=l.getDay(f)),v[c]-=_;for(var y=c+1;y=h.DAILY||l.getHours(m)%p===0)&&x.push({v:b,label:o.call(n,m,a,i,n)}),v[c]+=p,m=l.makeDate.apply(null,v),b=m.getTime();return x};a.getDateAxis=f},{"./dygraph-utils":17}],17:[function(t,e,a){"use strict";function i(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}function n(t,e,a){t.removeEventListener(e,a,!1)}function r(t){return t=t?t:window.event,t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.cancelBubble=!0,t.cancel=!0,t.returnValue=!1,!1}function o(t,e,a){var i,n,r;if(0===e)i=a,n=a,r=a;else{var o=Math.floor(6*t),s=6*t-o,l=a*(1-e),h=a*(1-e*s),u=a*(1-e*(1-s));switch(o){case 1:i=h,n=a,r=l;break;case 2:i=l,n=a,r=u;break;case 3:i=l,n=h,r=a;break;case 4:i=u,n=l,r=a;break;case 5:i=a,n=l,r=h;break;case 6:case 0:i=a,n=u,r=l}}return i=Math.floor(255*i+.5),n=Math.floor(255*n+.5),r=Math.floor(255*r+.5),"rgb("+i+","+n+","+r+")"}function s(t){var e=t.getBoundingClientRect(),a=window,i=document.documentElement;return{x:e.left+(a.pageXOffset||i.scrollLeft),y:e.top+(a.pageYOffset||i.scrollTop)}}function l(t){return!t.pageX||t.pageX<0?0:t.pageX}function h(t){return!t.pageY||t.pageY<0?0:t.pageY}function u(t,e){return l(t)-e.px}function d(t,e){return h(t)-e.py}function c(t){return!!t&&!isNaN(t)}function p(t,e){return!!t&&(null!==t.yval&&(null!==t.x&&void 0!==t.x&&(null!==t.y&&void 0!==t.y&&!(isNaN(t.x)||!e&&isNaN(t.y)))))}function g(t,e){var a=Math.min(Math.max(1,e||2),21);return Math.abs(t)<.001&&0!==t?t.toExponential(a-1):t.toPrecision(a)}function f(t){return t<10?"0"+t:""+t}function v(t,e,a,i){var n=f(t)+":"+f(e);if(a&&(n+=":"+f(a),i)){var r=""+i;n+="."+("000"+r).substring(r.length)}return n}function _(t,e){var a=e?nt:it,i=new Date(t),n=a.getFullYear(i),r=a.getMonth(i),o=a.getDate(i),s=a.getHours(i),l=a.getMinutes(i),h=a.getSeconds(i),u=a.getMilliseconds(i),d=""+n,c=f(r+1),p=f(o),g=3600*s+60*l+h+.001*u,_=d+"/"+c+"/"+p;return g&&(_+=" "+v(s,l,h,u)),_}function y(t,e){var a=Math.pow(10,e);return Math.round(t*a)/a}function x(t,e,a,i,n){for(var r=!0;r;){var o=t,s=e,l=a,h=i,u=n;if(r=!1,null!==h&&void 0!==h&&null!==u&&void 0!==u||(h=0,u=s.length-1),h>u)return-1;null!==l&&void 0!==l||(l=0);var d,c=function(t){return t>=0&&to){if(l>0&&(d=p-1,c(d)&&s[d]o))return p;t=o,e=s,a=l,i=p+1,n=u,r=!0,c=p=g=d=void 0}}}function m(t){var e,a;if((t.search("-")==-1||t.search("T")!=-1||t.search("Z")!=-1)&&(a=b(t),a&&!isNaN(a)))return a;if(t.search("-")!=-1){for(e=t.replace("-","/","g");e.search("-")!=-1;)e=e.replace("-","/");a=b(e)}else 8==t.length?(e=t.substr(0,4)+"/"+t.substr(4,2)+"/"+t.substr(6,2),a=b(e)):a=b(t);return a&&!isNaN(a)||console.error("Couldn't parse "+t+" as a date"),a}function b(t){return new Date(t).getTime()}function w(t,e){if("undefined"!=typeof e&&null!==e)for(var a in e)e.hasOwnProperty(a)&&(t[a]=e[a]);return t}function A(t,e){function a(t){return"object"==typeof Node?t instanceof Node:"object"==typeof t&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName}if("undefined"!=typeof e&&null!==e)for(var i in e)e.hasOwnProperty(i)&&(null===e[i]?t[i]=null:O(e[i])?t[i]=e[i].slice():a(e[i])?t[i]=e[i]:"object"==typeof e[i]?("object"==typeof t[i]&&null!==t[i]||(t[i]={}),A(t[i],e[i])):t[i]=e[i]);return t}function O(t){var e=typeof t;return("object"==e||"function"==e&&"function"==typeof t.item)&&null!==t&&"number"==typeof t.length&&3!==t.nodeType}function T(t){return"object"==typeof t&&null!==t&&"function"==typeof t.getTime}function D(t){for(var e=[],a=0;a=e||rt.call(window,function(){var e=(new Date).getTime(),h=e-o;n=r,r=Math.floor(h/a);var u=r-n,d=r+u>s;d||r>=s?(t(s),i()):(0!==u&&t(r),l())})}()}function M(t,e){var a={};if(t)for(var i=1;i=Math.pow(10,r)||Math.abs(t)=0;p--,c/=l)if(d>=c){i=y(t/c,n)+h[p];break}if(s){var f=String(t.toExponential()).split("e-");2===f.length&&f[1]>=3&&f[1]<=24&&(i=f[1]%3>0?y(f[0]/F(10,f[1]%3),n):Number(f[0]).toFixed(2),i+=u[Math.floor(f[1]/3)-1])}}return i}function V(t,e,a){return X.call(this,t,a)}function Z(t,e,a){var i=a("labelsUTC"),n=i?nt:it,r=n.getFullYear(t),o=n.getMonth(t),s=n.getDate(t),l=n.getHours(t),h=n.getMinutes(t),u=n.getSeconds(t),d=n.getMilliseconds(t);if(e>=W.Granularity.DECADAL)return""+r;if(e>=W.Granularity.MONTHLY)return ct[o]+" "+r;var c=3600*l+60*h+u+.001*d;return 0===c||e>=W.Granularity.DAILY?f(s)+" "+ct[o]:v(l,h,u,d)}function B(t,e){return _(t,e("labelsUTC"))}Object.defineProperty(a,"__esModule",{value:!0}),a.removeEvent=n,a.cancelEvent=r,a.hsvToRGB=o,a.findPos=s,a.pageX=l,a.pageY=h,a.dragGetX_=u,a.dragGetY_=d,a.isOK=c,a.isValidPoint=p,a.floatFormat=g,a.zeropad=f,a.hmsString_=v,a.dateString_=_,a.round_=y,a.binarySearch=x,a.dateParser=m,a.dateStrToMillis=b,a.update=w,a.updateDeep=A,a.isArrayLike=O,a.isDateLike=T,a.clone=D,a.createCanvas=E,a.getContextPixelRatio=P,a.Iterator=S,a.createIterator=L,a.repeatAndCleanup=C,a.isPixelChangingOptionList=M,a.detectLineDelimiter=N,a.isNodeContainedBy=k,a.pow=F,a.toRGB_=I,a.isCanvasSupported=H,a.parseFloat_=Y,a.numberValueFormatter=X,a.numberAxisLabelFormatter=V,a.dateAxisLabelFormatter=Z,a.dateValueFormatter=B;var G=t("./dygraph-tickers"),W=i(G),U=10;a.LOG_SCALE=U;var z=Math.log(U);a.LN_TEN=z;var j=function(t){return Math.log(t)/z};a.log10=j;var K=function(t,e,a){var i=j(t),n=j(e),r=i+a*(n-i),o=Math.pow(U,r);return o};a.logRangeFraction=K;var q=[2,2];a.DOTTED_LINE=q;var Q=[7,3];a.DASHED_LINE=Q;var J=[7,2,2,2];a.DOT_DASH_LINE=J;var $=1;a.HORIZONTAL=$;var tt=2;a.VERTICAL=tt;var et=function(t){return t.getContext("2d")};a.getContext=et;var at=function(t,e,a){t.addEventListener(e,a,!1)};a.addEvent=at;var it={getFullYear:function(t){return t.getFullYear()},getMonth:function(t){return t.getMonth()},getDate:function(t){return t.getDate()},getHours:function(t){return t.getHours()},getMinutes:function(t){return t.getMinutes()},getSeconds:function(t){return t.getSeconds()},getMilliseconds:function(t){return t.getMilliseconds()},getDay:function(t){return t.getDay()},makeDate:function(t,e,a,i,n,r,o){return new Date(t,e,a,i,n,r,o)}};a.DateAccessorsLocal=it;var nt={getFullYear:function(t){return t.getUTCFullYear()},getMonth:function(t){return t.getUTCMonth()},getDate:function(t){return t.getUTCDate()},getHours:function(t){return t.getUTCHours()},getMinutes:function(t){return t.getUTCMinutes()},getSeconds:function(t){return t.getUTCSeconds()},getMilliseconds:function(t){return t.getUTCMilliseconds()},getDay:function(t){return t.getUTCDay()},makeDate:function(t,e,a,i,n,r,o){return new Date(Date.UTC(t,e,a,i,n,r,o))}};a.DateAccessorsUTC=nt,S.prototype.next=function(){if(!this.hasNext)return null;for(var t=this.peek,e=this.nextIdx_+1,a=!1;e=0;n--){var r=i[n][0],o=i[n][1];if(o.call(r,a),a.propagationStopped)break}return a.defaultPrevented},Q.prototype.getPluginInstance_=function(t){for(var e=0;e=0;if(null===t||void 0===t)return e||a;if("y"===t)return a;throw new Error("axis parameter is ["+t+"] must be null, 'x' or 'y'.")},Q.prototype.toString=function(){var t=this.maindiv_,e=t&&t.id?t.id:t;return"[Dygraph "+e+"]"},Q.prototype.attr_=function(t,e){return e?this.attributes_.getForSeries(t,e):this.attributes_.get(t)},Q.prototype.getOption=function(t,e){return this.attr_(t,e)},Q.prototype.getNumericOption=function(t,e){return this.getOption(t,e)},Q.prototype.getStringOption=function(t,e){return this.getOption(t,e)},Q.prototype.getBooleanOption=function(t,e){return this.getOption(t,e)},Q.prototype.getFunctionOption=function(t,e){return this.getOption(t,e)},Q.prototype.getOptionForAxis=function(t,e){return this.attributes_.getForAxis(t,e)},Q.prototype.optionsViewForAxis_=function(t){var e=this;return function(a){var i=e.user_attrs_.axes;return i&&i[t]&&i[t].hasOwnProperty(a)?i[t][a]:("x"!==t||"logscale"!==a)&&("undefined"!=typeof e.user_attrs_[a]?e.user_attrs_[a]:(i=e.attrs_.axes,i&&i[t]&&i[t].hasOwnProperty(a)?i[t][a]:"y"==t&&e.axes_[0].hasOwnProperty(a)?e.axes_[0][a]:"y2"==t&&e.axes_[1].hasOwnProperty(a)?e.axes_[1][a]:e.attr_(a)))}},Q.prototype.rollPeriod=function(){return this.rollPeriod_},Q.prototype.xAxisRange=function(){return this.dateWindow_?this.dateWindow_:this.xAxisExtremes()},Q.prototype.xAxisExtremes=function(){var t=this.getNumericOption("xRangePad")/this.plotter_.area.w;if(0===this.numRows())return[0-t,1+t];var e=this.rawData_[0][0],a=this.rawData_[this.rawData_.length-1][0];if(t){var i=a-e;e-=i*t,a+=i*t}return[e,a]},Q.prototype.yAxisExtremes=function(){var t=this.gatherDatasets_(this.rolledSeries_,null),e=t.extremes,a=this.axes_;this.computeYAxisRanges_(e);var i=this.axes_;return this.axes_=a,i.map(function(t){return t.extremeRange})},Q.prototype.yAxisRange=function(t){if("undefined"==typeof t&&(t=0),t<0||t>=this.axes_.length)return null;var e=this.axes_[t];return[e.computedValueRange[0],e.computedValueRange[1]]},Q.prototype.yAxisRanges=function(){for(var t=[],e=0;ethis.rawData_.length?null:e<0||e>this.rawData_[t].length?null:this.rawData_[t][e]},Q.prototype.createInterface_=function(){var t=this.maindiv_;this.graphDiv=document.createElement("div"),this.graphDiv.style.textAlign="left",this.graphDiv.style.position="relative",t.appendChild(this.graphDiv),this.canvas_=x.createCanvas(),this.canvas_.style.position="absolute",this.hidden_=this.createPlotKitCanvas_(this.canvas_),this.canvas_ctx_=x.getContext(this.canvas_),this.hidden_ctx_=x.getContext(this.hidden_),this.resizeElements_(),this.graphDiv.appendChild(this.hidden_),this.graphDiv.appendChild(this.canvas_),this.mouseEventElement_=this.createMouseEventElement_(),this.layout_=new h.default(this);var e=this;this.mouseMoveHandler_=function(t){e.mouseMove_(t)},this.mouseOutHandler_=function(t){var a=t.target||t.fromElement,i=t.relatedTarget||t.toElement;x.isNodeContainedBy(a,e.graphDiv)&&!x.isNodeContainedBy(i,e.graphDiv)&&e.mouseOut_(t)},this.addAndTrackEvent(window,"mouseout",this.mouseOutHandler_),this.addAndTrackEvent(this.mouseEventElement_,"mousemove",this.mouseMoveHandler_),this.resizeHandler_||(this.resizeHandler_=function(t){e.resize()},this.addAndTrackEvent(window,"resize",this.resizeHandler_))},Q.prototype.resizeElements_=function(){this.graphDiv.style.width=this.width_+"px",this.graphDiv.style.height=this.height_+"px";var t=x.getContextPixelRatio(this.canvas_ctx_);this.canvas_.width=this.width_*t,this.canvas_.height=this.height_*t,this.canvas_.style.width=this.width_+"px",this.canvas_.style.height=this.height_+"px",1!==t&&this.canvas_ctx_.scale(t,t);var e=x.getContextPixelRatio(this.hidden_ctx_);this.hidden_.width=this.width_*e,this.hidden_.height=this.height_*e,this.hidden_.style.width=this.width_+"px",this.hidden_.style.height=this.height_+"px",1!==e&&this.hidden_ctx_.scale(e,e)},Q.prototype.destroy=function(){this.canvas_ctx_.restore(),this.hidden_ctx_.restore();for(var t=this.plugins_.length-1;t>=0;t--){var e=this.plugins_.pop();e.plugin.destroy&&e.plugin.destroy()}var a=function t(e){for(;e.hasChildNodes();)t(e.firstChild),e.removeChild(e.firstChild)};this.removeTrackedEvents_(),x.removeEvent(window,"mouseout",this.mouseOutHandler_),x.removeEvent(this.mouseEventElement_,"mousemove",this.mouseMoveHandler_),x.removeEvent(window,"resize",this.resizeHandler_),this.resizeHandler_=null,a(this.maindiv_);var i=function(t){for(var e in t)"object"==typeof t[e]&&(t[e]=null)};i(this.layout_),i(this.plotter_),i(this)},Q.prototype.createPlotKitCanvas_=function(t){var e=x.createCanvas();return e.style.position="absolute",e.style.top=t.style.top,e.style.left=t.style.left,e.width=this.width_,e.height=this.height_,e.style.width=this.width_+"px",e.style.height=this.height_+"px",e},Q.prototype.createMouseEventElement_=function(){return this.canvas_},Q.prototype.setColors_=function(){var t=this.getLabels(),e=t.length-1;this.colors_=[],this.colorsMap_={};for(var a=this.getNumericOption("colorSaturation")||1,i=this.getNumericOption("colorValue")||.5,n=Math.ceil(e/2),r=this.getOption("colors"),o=this.visibility(),s=0;s=0;--u)for(var d=this.layout_.points[u],c=0;c=l.length)){var h=l[s];if(x.isValidPoint(h)){var u=h.canvasy;if(t>h.canvasx&&s+10){var p=(t-h.canvasx)/c;u+=p*(d.canvasy-h.canvasy)}}}else if(t0){var g=l[s-1];if(x.isValidPoint(g)){var c=h.canvasx-g.canvasx;if(c>0){var p=(h.canvasx-t)/c;u+=p*(g.canvasy-h.canvasy)}}}(0===r||u=0){var o=0,s=this.attr_("labels");for(e=1;eo&&(o=l)}var h=this.previousVerticalX_;a.clearRect(h-o-1,0,2*o+2,this.height_)}if(this.selPoints_.length>0){var u=this.selPoints_[0].canvasx;for(a.save(),e=0;e=0){t!=this.lastRow_&&(i=!0),this.lastRow_=t;for(var n=0;n=0&&o=0&&(i=!0),this.lastRow_=-1;return this.selPoints_.length?this.lastx_=this.selPoints_[0].xval:this.lastx_=-1,void 0!==e&&(this.highlightSet_!==e&&(i=!0),this.highlightSet_=e),void 0!==a&&(this.lockedSet_=a),i&&this.updateSelection_(void 0),i},Q.prototype.mouseOut_=function(t){this.getFunctionOption("unhighlightCallback")&&this.getFunctionOption("unhighlightCallback").call(this,t),this.getBooleanOption("hideOverlayOnMouseOut")&&!this.lockedSet_&&this.clearSelection()},Q.prototype.clearSelection=function(){return this.cascadeEvents_("deselect",{}),this.lockedSet_=!1,this.fadeLevel?void this.animateSelection_(-1):(this.canvas_ctx_.clearRect(0,0,this.width_,this.height_),this.fadeLevel=0,this.selPoints_=[],this.lastx_=-1,this.lastRow_=-1,void(this.highlightSet_=null))},Q.prototype.getSelection=function(){if(!this.selPoints_||this.selPoints_.length<1)return-1;for(var t=0;t1&&(a=this.dataHandler_.rollingAverage(a,this.rollPeriod_,this.attributes_)),this.rolledSeries_.push(a)}this.drawGraph_();var i=new Date;this.drawingTimeMs_=i-t},Q.PointType=void 0,Q.stackPoints_=function(t,e,a,i){for(var n=null,r=null,o=null,s=-1,l=function(e){if(!(s>=e))for(var a=e;aa[1]&&(a[1]=p),p=1;a--)if(this.visibility()[a-1]){if(e){s=t[a];var p=e[0],g=e[1];for(n=null,r=null,i=0;i=p&&null===n&&(n=i),s[i][0]<=g&&(r=i);null===n&&(n=0);for(var f=n,v=!0;v&&f>0;)f--,v=null===s[f][1];null===r&&(r=s.length-1);var _=r;for(v=!0;v&&_0;){var n=this.readyFns_.pop();n(this)}},Q.prototype.computeYAxes_=function(){var t,e,a;for(this.axes_=[],t=0;t0&&(v=0),_<0&&(_=0)),v==1/0&&(v=0),_==-(1/0)&&(_=1),a=_-v,0===a&&(0!==_?a=Math.abs(_):(_=1,a=1));var m=_,b=v;e&&(u?(m=_+n*a,b=v):(m=_+n*a,b=v-n*a,b<0&&v>=0&&(b=0),m>0&&_<=0&&(m=0))),h.extremeRange=[b,m]}if(h.valueRange){var w=o(h.valueRange[0])?h.extremeRange[0]:h.valueRange[0],A=o(h.valueRange[1])?h.extremeRange[1]:h.valueRange[1];h.computedValueRange=[w,A]}else h.computedValueRange=h.extremeRange;if(!e)if(u){w=h.computedValueRange[0],A=h.computedValueRange[1];var O=n/(2*n-1),T=(n-1)/(2*n-1);h.computedValueRange[0]=x.logRangeFraction(w,A,O),h.computedValueRange[1]=x.logRangeFraction(w,A,T)}else w=h.computedValueRange[0],A=h.computedValueRange[1],a=A-w,h.computedValueRange[0]=w-a*n,h.computedValueRange[1]=A+a*n;if(c){h.independentTicks=c;var D=this.optionsViewForAxis_("y"+(l?"2":"")),E=D("ticker");h.ticks=E(h.computedValueRange[0],h.computedValueRange[1],this.plotter_.area.h,D,this),r||(r=h)}}if(void 0===r)throw'Configuration Error: At least one axis has to have the "independentTicks" option activated.';for(var l=0;l0&&"e"!=t[a-1]&&"E"!=t[a-1]||t.indexOf("/")>=0||isNaN(parseFloat(t))?e=!0:8==t.length&&t>"19700101"&&t<"20371231"&&(e=!0),this.setXAxisOptions_(e)},Q.prototype.setXAxisOptions_=function(t){t?(this.attrs_.xValueParser=x.dateParser,this.attrs_.axes.x.valueFormatter=x.dateValueFormatter,this.attrs_.axes.x.ticker=_.dateTicker,this.attrs_.axes.x.axisLabelFormatter=x.dateAxisLabelFormatter):(this.attrs_.xValueParser=function(t){return parseFloat(t)},this.attrs_.axes.x.valueFormatter=function(t){return t},this.attrs_.axes.x.ticker=_.numericTicks,this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter)},Q.prototype.parseCSV_=function(t){var e,a,i=[],n=x.detectLineDelimiter(t),r=t.split(n||"\n"),o=this.getStringOption("delimiter");r[0].indexOf(o)==-1&&r[0].indexOf("\t")>=0&&(o="\t");var s=0;"labels"in this.user_attrs_||(s=1,this.attrs_.labels=r[0].split(o),this.attributes_.reparseSeries());for(var l,h=0,u=!1,d=this.attr_("labels").length,c=!1,p=s;p0&&v[0]0;)e=String.fromCharCode(65+(t-1)%26)+e.toLowerCase(),t=Math.floor((t-1)/26);return e},a=t.getNumberOfColumns(),i=t.getNumberOfRows(),n=t.getColumnType(0);if("date"==n||"datetime"==n)this.attrs_.xValueParser=x.dateParser,this.attrs_.axes.x.valueFormatter=x.dateValueFormatter,this.attrs_.axes.x.ticker=_.dateTicker,this.attrs_.axes.x.axisLabelFormatter=x.dateAxisLabelFormatter;else{if("number"!=n)throw new Error("only 'date', 'datetime' and 'number' types are supported for column 1 of DataTable input (Got '"+n+"')");this.attrs_.xValueParser=function(t){return parseFloat(t)},this.attrs_.axes.x.valueFormatter=function(t){return t},this.attrs_.axes.x.ticker=_.numericTicks,this.attrs_.axes.x.axisLabelFormatter=this.attrs_.axes.x.valueFormatter}var r,o,s=[],l={},h=!1;for(r=1;r0&&v[0]0&&this.setAnnotations(f,!0),this.attributes_.reparseSeries()},Q.prototype.cascadeDataDidUpdateEvent_=function(){this.cascadeEvents_("dataDidUpdate",{})},Q.prototype.start_=function(){var t=this.file_;if("function"==typeof t&&(t=t()),x.isArrayLike(t))this.rawData_=this.parseArray_(t),this.cascadeDataDidUpdateEvent_(),this.predraw_();else if("object"==typeof t&&"function"==typeof t.getColumnRange)this.parseDataTable_(t),this.cascadeDataDidUpdateEvent_(),this.predraw_();else if("string"==typeof t){var e=x.detectLineDelimiter(t);if(e)this.loadedEvent_(t);else{var a;a=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP");var i=this;a.onreadystatechange=function(){4==a.readyState&&(200!==a.status&&0!==a.status||i.loadedEvent_(a.responseText))},a.open("GET",t,!0),a.send(null)}}else console.error("Unknown data format: "+typeof t)},Q.prototype.updateOptions=function(t,e){"undefined"==typeof e&&(e=!1);var a=t.file,i=Q.copyUserAttrs_(t);"rollPeriod"in i&&(this.rollPeriod_=i.rollPeriod),"dateWindow"in i&&(this.dateWindow_=i.dateWindow);var n=x.isPixelChangingOptionList(this.attr_("labels"),i);x.updateDeep(this.user_attrs_,i),this.attributes_.reparseSeries(),a?(this.cascadeEvents_("dataWillUpdate",{}),this.file_=a,e||this.start_()):e||(n?this.predraw_():this.renderGraph_(!1))},Q.copyUserAttrs_=function(t){var e={};for(var a in t)t.hasOwnProperty(a)&&"file"!=a&&t.hasOwnProperty(a)&&(e[a]=t[a]);return e},Q.prototype.resize=function(t,e){if(!this.resize_lock){this.resize_lock=!0,null===t!=(null===e)&&(console.warn("Dygraph.resize() should be called with zero parameters or two non-NULL parameters. Pretending it was zero."),t=e=null);var a=this.width_,i=this.height_;t?(this.maindiv_.style.width=t+"px",this.maindiv_.style.height=e+"px",this.width_=t,this.height_=e):(this.width_=this.maindiv_.clientWidth,this.height_=this.maindiv_.clientHeight),a==this.width_&&i==this.height_||(this.resizeElements_(),this.predraw_()),this.resize_lock=!1}},Q.prototype.adjustRoll=function(t){this.rollPeriod_=t,this.predraw_()},Q.prototype.visibility=function(){for(this.getOption("visibility")||(this.attrs_.visibility=[]);this.getOption("visibility").length=a.length?console.warn("Invalid series number in setVisibility: "+n):a[n]=t[n]);else for(var n=0;n=a.length?console.warn("Invalid series number in setVisibility: "+n):a[n]=t[n]:t[n]<0||t[n]>=a.length?console.warn("Invalid series number in setVisibility: "+t[n]):a[t[n]]=e;this.predraw_()},Q.prototype.size=function(){return{width:this.width_,height:this.height_}},Q.prototype.setAnnotations=function(t,e){return this.annotations_=t,this.layout_?(this.layout_.setAnnotations(this.annotations_),void(e||this.predraw_())):void console.warn("Tried to setAnnotations before dygraph was ready. Try setting them in a ready() block. See dygraphs.com/tests/annotation.html")},Q.prototype.annotations=function(){return this.annotations_},Q.prototype.getLabels=function(){var t=this.attr_("labels");return t?t.slice():null},Q.prototype.indexFromSetName=function(t){return this.setIndexByName_[t]},Q.prototype.getRowForX=function(t){for(var e=0,a=this.numRows()-1;e<=a;){var i=a+e>>1,n=this.getValue(i,0);if(nt)a=i-1;else{if(e==i)return i;a=i}}return null},Q.prototype.ready=function(t){this.is_initial_draw_?this.readyFns_.push(t):t.call(this,this)},Q.prototype.addAndTrackEvent=function(t,e,a){x.addEvent(t,e,a),this.registeredEvents_.push({elem:t,type:e,fn:a})},Q.prototype.removeTrackedEvents_=function(){if(this.registeredEvents_)for(var t=0;tr.x+r.w||l.canvasyr.y+r.h)){var h=l.annotation,u=6;h.hasOwnProperty("tickHeight")&&(u=h.tickHeight);var d=document.createElement("div");d.style.fontSize=e.getOption("axisLabelFontSize")+"px";var c="dygraph-annotation";h.hasOwnProperty("icon")||(c+=" dygraphDefaultAnnotation dygraph-default-annotation"),h.hasOwnProperty("cssClass")&&(c+=" "+h.cssClass),d.className=c;var p=h.hasOwnProperty("width")?h.width:16,g=h.hasOwnProperty("height")?h.height:16;if(h.hasOwnProperty("icon")){var f=document.createElement("img");f.src=h.icon,f.width=p,f.height=g,d.appendChild(f)}else l.annotation.hasOwnProperty("shortText")&&d.appendChild(document.createTextNode(l.annotation.shortText));var v=l.canvasx-p/2;d.style.left=v+"px";var _=0;if(h.attachAtBottom){var y=r.y+r.h-g-u; +o[v]?y-=o[v]:o[v]=0,o[v]+=u+g,_=y}else _=l.canvasy-g-u;d.style.top=_+"px",d.style.width=p+"px",d.style.height=g+"px",d.title=l.annotation.text,d.style.color=e.colorsMap_[l.name],d.style.borderColor=e.colorsMap_[l.name],h.div=d,e.addAndTrackEvent(d,"click",n("clickHandler","annotationClickHandler",l,this)),e.addAndTrackEvent(d,"mouseover",n("mouseOverHandler","annotationMouseOverHandler",l,this)),e.addAndTrackEvent(d,"mouseout",n("mouseOutHandler","annotationMouseOutHandler",l,this)),e.addAndTrackEvent(d,"dblclick",n("dblClickHandler","annotationDblClickHandler",l,this)),i.appendChild(d),this.annotations_.push(d);var x=t.drawingContext;if(x.save(),x.strokeStyle=h.hasOwnProperty("tickColor")?h.tickColor:e.colorsMap_[l.name],x.lineWidth=h.hasOwnProperty("tickWidth")?h.tickWidth:e.getOption("strokeWidth"),x.beginPath(),h.attachAtBottom){var y=_+g;x.moveTo(l.canvasx,y),x.lineTo(l.canvasx,y+u)}else x.moveTo(l.canvasx,l.canvasy),x.lineTo(l.canvasx,l.canvasy-2-u);x.closePath(),x.stroke(),x.restore()}}},i.prototype.destroy=function(){this.detachLabels()},a.default=i,e.exports=a.default},{}],21:[function(t,e,a){"use strict";function i(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}Object.defineProperty(a,"__esModule",{value:!0});var n=t("../dygraph-utils"),r=i(n),o=function(){this.xlabels_=[],this.ylabels_=[]};o.prototype.toString=function(){return"Axes Plugin"},o.prototype.activate=function(t){return{layout:this.layout,clearChart:this.clearChart,willDrawChart:this.willDrawChart}},o.prototype.layout=function(t){var e=t.dygraph;if(e.getOptionForAxis("drawAxis","y")){var a=e.getOptionForAxis("axisLabelWidth","y")+2*e.getOptionForAxis("axisTickSize","y");t.reserveSpaceLeft(a)}if(e.getOptionForAxis("drawAxis","x")){var i;i=e.getOption("xAxisHeight")?e.getOption("xAxisHeight"):e.getOptionForAxis("axisLabelFontSize","x")+2*e.getOptionForAxis("axisTickSize","x"),t.reserveSpaceBottom(i)}if(2==e.numAxes()){if(e.getOptionForAxis("drawAxis","y2")){var a=e.getOptionForAxis("axisLabelWidth","y2")+2*e.getOptionForAxis("axisTickSize","y2");t.reserveSpaceRight(a)}}else e.numAxes()>2&&e.error("Only two y-axes are supported at this time. (Trying to use "+e.numAxes()+")")},o.prototype.detachLabels=function(){function t(t){for(var e=0;e0){var x=n.numAxes(),m=[y("y"),y("y2")];v.yticks.forEach(function(t){if(void 0!==t.label){s=_.x;var e=1,a="y1",n=m[0];1==t.axis&&(s=_.x+_.w,e=-1,a="y2",n=m[1]);var r=n("axisLabelFontSize");l=_.y+t.pos*_.h,o=f(t.label,"y",2==x?a:null);var h=l-r/2;h<0&&(h=0),h+r+3>c?o.style.bottom="0":o.style.top=h+"px",0===t.axis?(o.style.left=_.x-n("axisLabelWidth")-n("axisTickSize")+"px",o.style.textAlign="right"):1==t.axis&&(o.style.left=_.x+_.w+n("axisTickSize")+"px",o.style.textAlign="left"),o.style.width=n("axisLabelWidth")+"px",u.appendChild(o),i.ylabels_.push(o)}});var b=this.ylabels_[0],w=n.getOptionForAxis("axisLabelFontSize","y"),A=parseInt(b.style.top,10)+w;A>c-w&&(b.style.top=parseInt(b.style.top,10)-w/2+"px")}var O;if(n.getOption("drawAxesAtZero")){var T=n.toPercentXCoord(0);(T>1||T<0||isNaN(T))&&(T=0),O=e(_.x+T*_.w)}else O=e(_.x);h.strokeStyle=n.getOptionForAxis("axisLineColor","y"),h.lineWidth=n.getOptionForAxis("axisLineWidth","y"),h.beginPath(),h.moveTo(O,a(_.y)),h.lineTo(O,a(_.y+_.h)),h.closePath(),h.stroke(),2==n.numAxes()&&(h.strokeStyle=n.getOptionForAxis("axisLineColor","y2"),h.lineWidth=n.getOptionForAxis("axisLineWidth","y2"),h.beginPath(),h.moveTo(a(_.x+_.w),a(_.y)),h.lineTo(a(_.x+_.w),a(_.y+_.h)),h.closePath(),h.stroke())}if(n.getOptionForAxis("drawAxis","x")){if(v.xticks){var D=y("x");v.xticks.forEach(function(t){if(void 0!==t.label){s=_.x+t.pos*_.w,l=_.y+_.h,o=f(t.label,"x"),o.style.textAlign="center",o.style.top=l+D("axisTickSize")+"px";var e=s-D("axisLabelWidth")/2;e+D("axisLabelWidth")>d&&(e=d-D("axisLabelWidth"),o.style.textAlign="right"),e<0&&(e=0,o.style.textAlign="left"),o.style.left=e+"px",o.style.width=D("axisLabelWidth")+"px",u.appendChild(o),i.xlabels_.push(o)}})}h.strokeStyle=n.getOptionForAxis("axisLineColor","x"),h.lineWidth=n.getOptionForAxis("axisLineWidth","x"),h.beginPath();var E;if(n.getOption("drawAxesAtZero")){var T=n.toPercentYCoord(0,0);(T>1||T<0)&&(T=1),E=a(_.y+T*_.h)}else E=a(_.y+_.h);h.moveTo(e(_.x),E),h.lineTo(e(_.x+_.w),E),h.closePath(),h.stroke()}h.restore()}},a.default=o,e.exports=a.default},{"../dygraph-utils":17}],22:[function(t,e,a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});var i=function(){this.title_div_=null,this.xlabel_div_=null,this.ylabel_div_=null,this.y2label_div_=null};i.prototype.toString=function(){return"ChartLabels Plugin"},i.prototype.activate=function(t){return{layout:this.layout,didDrawChart:this.didDrawChart}};var n=function(t){var e=document.createElement("div");return e.style.position="absolute",e.style.left=t.x+"px",e.style.top=t.y+"px",e.style.width=t.w+"px",e.style.height=t.h+"px",e};i.prototype.detachLabels_=function(){for(var t=[this.title_div_,this.xlabel_div_,this.ylabel_div_,this.y2label_div_],e=0;e=2);o=h.yticks,l.save(),o.forEach(function(t){if(t.has_tick){var r=t.axis;g[r]&&(l.save(),f[r]&&l.setLineDash&&l.setLineDash(v[r]),l.strokeStyle=c[r],l.lineWidth=p[r],i=e(u.x),n=a(u.y+t.pos*u.h),l.beginPath(),l.moveTo(i,n),l.lineTo(i+u.w,n),l.stroke(),l.restore())}}),l.restore()}if(s.getOptionForAxis("drawGrid","x")){o=h.xticks,l.save();var v=s.getOptionForAxis("gridLinePattern","x"),f=v&&v.length>=2;f&&l.setLineDash&&l.setLineDash(v),l.strokeStyle=s.getOptionForAxis("gridLineColor","x"),l.lineWidth=s.getOptionForAxis("gridLineWidth","x"),o.forEach(function(t){t.has_tick&&(i=e(u.x+t.pos*u.w),n=a(u.y+u.h),l.beginPath(),l.moveTo(i,n),l.lineTo(i,u.y),l.closePath(),l.stroke())}),f&&l.setLineDash&&l.setLineDash([]),l.restore()}},i.prototype.destroy=function(){},a.default=i,e.exports=a.default},{}],24:[function(t,e,a){"use strict";function i(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}function n(t,e,a){if(!t||t.length<=1)return'
';var i,n,r,o,s,l=0,h=0,u=[];for(i=0;i<=t.length;i++)l+=t[i%t.length];if(s=Math.floor(a/(l-t[0])),s>1){for(i=0;i';return d}Object.defineProperty(a,"__esModule",{value:!0});var r=t("../dygraph-utils"),o=i(r),s=function(){this.legend_div_=null,this.is_generated_div_=!1};s.prototype.toString=function(){return"Legend Plugin"},s.prototype.activate=function(t){var e,a=t.getOption("labelsDiv");return a&&null!==a?e="string"==typeof a||a instanceof String?document.getElementById(a):a:(e=document.createElement("div"),e.className="dygraph-legend",t.graphDiv.appendChild(e),this.is_generated_div_=!0),this.legend_div_=e,this.one_em_width_=10,{select:this.select,deselect:this.deselect,predraw:this.predraw,didDrawChart:this.didDrawChart}};var l=function(t){var e=document.createElement("span");e.setAttribute("style","margin: 0; padding: 0 0 0 1em; border: 0;"),t.appendChild(e);var a=e.offsetWidth;return t.removeChild(e),a},h=function(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(//g,">")};s.prototype.select=function(t){var e=t.selectedX,a=t.selectedPoints,i=t.selectedRow,n=t.dygraph.getOption("legend");if("never"===n)return void(this.legend_div_.style.display="none");if("follow"===n){var r=t.dygraph.plotter_.area,o=this.legend_div_.offsetWidth,l=t.dygraph.getOptionForAxis("axisLabelWidth","y"),h=a[0].x*r.w+50,u=a[0].y*r.h-50;h+o+1>r.w&&(h=h-100-o-(l-r.x)),t.dygraph.graphDiv.appendChild(this.legend_div_),this.legend_div_.style.left=l+h+"px",this.legend_div_.style.top=u+"px"}var d=s.generateLegendHTML(t.dygraph,e,a,this.one_em_width_,i);this.legend_div_.innerHTML=d,this.legend_div_.style.display=""},s.prototype.deselect=function(t){var e=t.dygraph.getOption("legend");"always"!==e&&(this.legend_div_.style.display="none");var a=l(this.legend_div_);this.one_em_width_=a;var i=s.generateLegendHTML(t.dygraph,void 0,void 0,a,null);this.legend_div_.innerHTML=i},s.prototype.didDrawChart=function(t){this.deselect(t)},s.prototype.predraw=function(t){if(this.is_generated_div_){t.dygraph.graphDiv.appendChild(this.legend_div_);var e=t.dygraph.getArea(),a=this.legend_div_.offsetWidth;this.legend_div_.style.left=e.x+e.w-a-1+"px",this.legend_div_.style.top=e.y+"px"}},s.prototype.destroy=function(){this.legend_div_=null},s.generateLegendHTML=function(t,e,a,i,r){var l={dygraph:t,x:e,series:[]},u={},d=t.getLabels();if(d)for(var c=1;c":" "),a+=""+r.dashHTML+" "+r.labelHTML+"")}return a}a=t.xHTML+":";for(var n=0;n");var o=r.isHighlighted?' class="highlight"':"";a+=" "+r.labelHTML+": "+r.yHTML+""}}return a},a.default=s,e.exports=a.default},{"../dygraph-utils":17}],25:[function(t,e,a){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function n(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(e[a]=t[a]);return e.default=t,e}Object.defineProperty(a,"__esModule",{value:!0});var r=t("../dygraph-utils"),o=n(r),s=t("../dygraph-interaction-model"),l=i(s),h=t("../iframe-tarp"),u=i(h),d=function(){this.hasTouchInterface_="undefined"!=typeof TouchEvent,this.isMobileDevice_=/mobile|android/gi.test(navigator.appVersion),this.interfaceCreated_=!1};d.prototype.toString=function(){return"RangeSelector Plugin"},d.prototype.activate=function(t){return this.dygraph_=t,this.getOption_("showRangeSelector")&&this.createInterface_(),{layout:this.reserveSpace_,predraw:this.renderStaticLayer_,didDrawChart:this.renderInteractiveLayer_}},d.prototype.destroy=function(){this.bgcanvas_=null,this.fgcanvas_=null,this.leftZoomHandle_=null,this.rightZoomHandle_=null},d.prototype.getOption_=function(t,e){return this.dygraph_.getOption(t,e)},d.prototype.setDefaultOption_=function(t,e){this.dygraph_.attrs_[t]=e},d.prototype.createInterface_=function(){this.createCanvases_(),this.createZoomHandles_(),this.initInteraction_(),this.getOption_("animatedZooms")&&(console.warn("Animated zooms and range selector are not compatible; disabling animatedZooms."),this.dygraph_.updateOptions({animatedZooms:!1},!0)),this.interfaceCreated_=!0,this.addToGraph_()},d.prototype.addToGraph_=function(){var t=this.graphDiv_=this.dygraph_.graphDiv;t.appendChild(this.bgcanvas_),t.appendChild(this.fgcanvas_),t.appendChild(this.leftZoomHandle_),t.appendChild(this.rightZoomHandle_)},d.prototype.removeFromGraph_=function(){var t=this.graphDiv_;t.removeChild(this.bgcanvas_),t.removeChild(this.fgcanvas_),t.removeChild(this.leftZoomHandle_),t.removeChild(this.rightZoomHandle_),this.graphDiv_=null},d.prototype.reserveSpace_=function(t){this.getOption_("showRangeSelector")&&t.reserveSpaceBottom(this.getOption_("rangeSelectorHeight")+4)},d.prototype.renderStaticLayer_=function(){this.updateVisibility_()&&(this.resize_(),this.drawStaticLayer_())},d.prototype.renderInteractiveLayer_=function(){this.updateVisibility_()&&!this.isChangingRange_&&(this.placeZoomHandles_(),this.drawInteractiveLayer_())},d.prototype.updateVisibility_=function(){var t=this.getOption_("showRangeSelector");if(t)this.interfaceCreated_?this.graphDiv_&&this.graphDiv_.parentNode||this.addToGraph_():this.createInterface_();else if(this.graphDiv_){this.removeFromGraph_();var e=this.dygraph_;setTimeout(function(){e.width_=0,e.resize()},1)}return t},d.prototype.resize_=function(){function t(t,e,a){var i=o.getContextPixelRatio(e);t.style.top=a.y+"px",t.style.left=a.x+"px",t.width=a.w*i,t.height=a.h*i,t.style.width=a.w+"px",t.style.height=a.h+"px",1!=i&&e.scale(i,i)}var e=this.dygraph_.layout_.getPlotArea(),a=0;this.dygraph_.getOptionForAxis("drawAxis","x")&&(a=this.getOption_("xAxisHeight")||this.getOption_("axisLabelFontSize")+2*this.getOption_("axisTickSize")),this.canvasRect_={x:e.x,y:e.y+e.h+a+4,w:e.w,h:this.getOption_("rangeSelectorHeight")},t(this.bgcanvas_,this.bgcanvas_ctx_,this.canvasRect_),t(this.fgcanvas_,this.fgcanvas_ctx_,this.canvasRect_)},d.prototype.createCanvases_=function(){this.bgcanvas_=o.createCanvas(),this.bgcanvas_.className="dygraph-rangesel-bgcanvas",this.bgcanvas_.style.position="absolute",this.bgcanvas_.style.zIndex=9,this.bgcanvas_ctx_=o.getContext(this.bgcanvas_),this.fgcanvas_=o.createCanvas(),this.fgcanvas_.className="dygraph-rangesel-fgcanvas",this.fgcanvas_.style.position="absolute",this.fgcanvas_.style.zIndex=9,this.fgcanvas_.style.cursor="default",this.fgcanvas_ctx_=o.getContext(this.fgcanvas_)},d.prototype.createZoomHandles_=function(){var t=new Image;t.className="dygraph-rangesel-zoomhandle",t.style.position="absolute",t.style.zIndex=10,t.style.visibility="hidden",t.style.cursor="col-resize",t.width=9,t.height=16,t.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAQCAYAAADESFVDAAAAAXNSR0IArs4c6QAAAAZiS0dEANAAzwDP4Z7KegAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9sHGw0cMqdt1UwAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAaElEQVQoz+3SsRFAQBCF4Z9WJM8KCDVwownl6YXsTmCUsyKGkZzcl7zkz3YLkypgAnreFmDEpHkIwVOMfpdi9CEEN2nGpFdwD03yEqDtOgCaun7sqSTDH32I1pQA2Pb9sZecAxc5r3IAb21d6878xsAAAAAASUVORK5CYII=",this.isMobileDevice_&&(t.width*=2,t.height*=2),this.leftZoomHandle_=t,this.rightZoomHandle_=t.cloneNode(!1)},d.prototype.initInteraction_=function(){var t,e,a,i,n,r,s,h,d,c,p,g,f,v,_=this,y=document,x=0,m=null,b=!1,w=!1,A=!this.isMobileDevice_,O=new u.default;t=function(t){var e=_.dygraph_.xAxisExtremes(),a=(e[1]-e[0])/_.canvasRect_.w,i=e[0]+(t.leftHandlePos-_.canvasRect_.x)*a,n=e[0]+(t.rightHandlePos-_.canvasRect_.x)*a;return[i,n]},e=function(t){return o.cancelEvent(t),b=!0,x=t.clientX,m=t.target?t.target:t.srcElement,"mousedown"!==t.type&&"dragstart"!==t.type||(o.addEvent(y,"mousemove",a),o.addEvent(y,"mouseup",i)),_.fgcanvas_.style.cursor="col-resize",O.cover(),!0},a=function(t){if(!b)return!1;o.cancelEvent(t);var e=t.clientX-x;if(Math.abs(e)<4)return!0;x=t.clientX;var a,i=_.getZoomHandleStatus_();m==_.leftZoomHandle_?(a=i.leftHandlePos+e,a=Math.min(a,i.rightHandlePos-m.width-3),a=Math.max(a,_.canvasRect_.x)):(a=i.rightHandlePos+e,a=Math.min(a,_.canvasRect_.x+_.canvasRect_.w),a=Math.max(a,i.leftHandlePos+m.width+3));var r=m.width/2;return m.style.left=a-r+"px",_.drawInteractiveLayer_(),A&&n(),!0},i=function(t){return!!b&&(b=!1,O.uncover(),o.removeEvent(y,"mousemove",a),o.removeEvent(y,"mouseup",i),_.fgcanvas_.style.cursor="default",A||n(),!0)},n=function(){try{var e=_.getZoomHandleStatus_();if(_.isChangingRange_=!0,e.isZoomed){var a=t(e);_.dygraph_.doZoomXDates_(a[0],a[1])}else _.dygraph_.resetZoom()}finally{_.isChangingRange_=!1}},r=function(t){var e=_.leftZoomHandle_.getBoundingClientRect(),a=e.left+e.width/2;e=_.rightZoomHandle_.getBoundingClientRect();var i=e.left+e.width/2;return t.clientX>a&&t.clientX=_.canvasRect_.x+_.canvasRect_.w?(n=_.canvasRect_.x+_.canvasRect_.w,i=n-r):(i+=e,n+=e);var s=_.leftZoomHandle_.width/2;return _.leftZoomHandle_.style.left=i-s+"px",_.rightZoomHandle_.style.left=n-s+"px",_.drawInteractiveLayer_(),A&&c(),!0},d=function(t){return!!w&&(w=!1,o.removeEvent(y,"mousemove",h),o.removeEvent(y,"mouseup",d),A||c(),!0)},c=function(){try{_.isChangingRange_=!0,_.dygraph_.dateWindow_=t(_.getZoomHandleStatus_()),_.dygraph_.drawGraph_(!1)}finally{_.isChangingRange_=!1}},p=function(t){if(!b&&!w){var e=r(t)?"move":"default";e!=_.fgcanvas_.style.cursor&&(_.fgcanvas_.style.cursor=e)}},g=function(t){"touchstart"==t.type&&1==t.targetTouches.length?e(t.targetTouches[0])&&o.cancelEvent(t):"touchmove"==t.type&&1==t.targetTouches.length?a(t.targetTouches[0])&&o.cancelEvent(t):i(t)},f=function(t){"touchstart"==t.type&&1==t.targetTouches.length?s(t.targetTouches[0])&&o.cancelEvent(t):"touchmove"==t.type&&1==t.targetTouches.length?h(t.targetTouches[0])&&o.cancelEvent(t):d(t)},v=function(t,e){for(var a=["touchstart","touchend","touchmove","touchcancel"],i=0;i1&&(g=c.rollingAverage(g,e.rollPeriod(),p)),d.push(g)}var f=[];for(t=0;t0)&&(m=Math.min(m,w),b=Math.max(b,w))}var A=.25;if(a)for(b=o.log10(b),b+=b*A,m=o.log10(m),t=0;tthis.canvasRect_.x||a+1 + + + + Get data ADC + + + +

Read ADC RTL8711AM

+
+ + diff --git a/ExampleHTM/dygraph/ws_test_ina219.html b/ExampleHTM/dygraph/ws_test_ina219.html new file mode 100644 index 0000000..52fe989 --- /dev/null +++ b/ExampleHTM/dygraph/ws_test_ina219.html @@ -0,0 +1,52 @@ + + + + + Get data INA219 + + + + +

Read regs U & I INA219

+
+ + + diff --git a/USDK/Makefile b/USDK/Makefile new file mode 100644 index 0000000..ac92758 --- /dev/null +++ b/USDK/Makefile @@ -0,0 +1,39 @@ +include userset.mk + +all: ram_all +mp: ram_all_mp + +.PHONY: ram_all +ram_all: + @$(MAKE) -f $(SDK_PATH)sdkbuild.mk + @$(MAKE) -f $(SDK_PATH)flasher.mk genbin1 genbin23 + +.PHONY: ram_all_mp +ram_all_mp: + @$(MAKE) -f $(SDK_PATH)sdkbuild.mk mp + @$(MAKE) -f $(SDK_PATH)flasher.mk mp + +.PHONY: clean clean_all +clean: + @$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean + +clean_all: + @$(MAKE) -f $(SDK_PATH)sdkbuild.mk clean_all + +.PHONY: flashburn runram reset test readfullflash flashwebfs +flashburn: + @$(MAKE) -f $(SDK_PATH)flasher.mk flashburn + +flash_OTA: + @$(MAKE) -f $(SDK_PATH)flasher.mk flash_OTA + + +runram: + @$(MAKE) --f $(SDK_PATH)flasher.mk runram + +reset: + @$(MAKE) -f $(SDK_PATH)flasher.mk reset + +readfullflash: + @$(MAKE) -f $(SDK_PATH)flasher.mk readfullflash + diff --git a/USDK/component/common/api/at_cmd/atcmd_cloud.c b/USDK/component/common/api/at_cmd/atcmd_cloud.c new file mode 100644 index 0000000..61d6a3b --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_cloud.c @@ -0,0 +1,175 @@ +#include +#include "log_service.h" +#include "cmsis_os.h" +#include + +#if CONFIG_JOYLINK +#if 1 +void fATCJ(void *arg) +{ + extern void joylink_erase(void); + printf("\r\n[ATCJ] Erase wifi and joylink info."); + if(arg){ + printf("\r\n[ATCJ]Usage : ATCJ"); + return; + } + joylink_erase(); +} +#else +void fATCJ(void *arg) +{ + extern void cmd_jd_smart(int argc, char **argv); + int argc; + char *argv[MAX_ARGC] = {0}; + printf("[ATCJ]:simple config command for jdsmart\n\r"); + if(!arg){ + printf("[ATCJ]Usage: ATCJ=simple_config\n\r"); + return; + } + argv[0] = "simple_config"; + if((argc = parse_param(arg, argv)) > 1){ + cmd_jd_smart(argc, argv); + } + else + printf("[ATCJ]Usage: ATCJ=simple_config\n\r"); +} +#endif +#endif + + +#if CONFIG_GAGENT +void fATCG(void *arg) +{ + example_gagent(); +} +void fATCE(void *arg) +{//Erase gagent config flash + extern int GAgent_DevEraseConfigData(); + GAgent_DevEraseConfigData(); +} +#endif + +#if CONFIG_QQ_LINK +void fATCQ(void *arg) +{ + int argc; + unsigned char *argv[MAX_ARGC] = {0}; + extern void device_write_sn_license(int argc, unsigned char **argv); + extern void device_erase_all(int argc, unsigned char **argv); + + if(!arg) + { + printf("\r\n[ATCQ] Write sn/license into flash or Erase all info\r\n"); + printf("\r\n[ATCQ] Usage: ATCQ=erase"); + printf("\r\n[ATCQ] Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx"); + return; + } + argv[0] = "sn&&license&&erase"; + argc = parse_param(arg, argv); + if(argc == 3) // Write sn&&license + { + device_write_sn_license(argc, argv); + } + else if(argc == 2) // Erase all info : ATCQ=erase + { + device_erase_all(argc, argv); + } + else + { + printf("\r\n[ATCQ] Usage: ATCQ=erase"); + printf("\r\n[ATCQ]Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx"); + } +} +#endif + +#if CONFIG_AIRKISS_CLOUD +void fATCW(void *arg) +{ + int argc; + unsigned char *argv[MAX_ARGC] = {0}; + extern void airkiss_cloud_write_device_info(int argc, unsigned char **argv); + extern void airkiss_cloud_erase_ap_profile(int argc, unsigned char **argv); + + if(!arg) goto USAGE; + + argv[0] = "type/id/licese/erase"; + argc = parse_param(arg, argv); + if(argc == 3) // Write typw/id/license + { + airkiss_cloud_write_device_info(argc, argv); + return; + } + else if(argc == 2) // Erase wifi profile : ATCW=erase + { + airkiss_cloud_erase_ap_profile(argc, argv); + return; + } + else + goto USAGE; + +USAGE: + printf("\r\n[ATCW] Write ORDERLY device's type/id/license into flash or Erase wifi profile"); + printf("\r\n[ATCW] Usage: ATCW=type,xxxxxxxx"); + printf("\r\n[ATCW] Usage: ATCW=id,xxxxxxxx"); + printf("\r\n[ATCW] Usage: ATCW=licensepart1,xxxxxxxx\t(80-Byte long)"); + printf("\r\n[ATCW] Usage: ATCW=licensepart2,xxxxxxxx\t(80-Byte long)"); + printf("\r\n[ATCW] Usage: ATCW=erase"); + return; +} +#endif + +#if CONFIG_ALINK +extern void example_alink(void); +extern int alink_erase_wifi_config(); +extern void alink_reset_to_factory(void *arg); + +void fATCA(void *arg) +{ + example_alink(); +} + +void fATCZ(void *arg) +{ + //Erase alink config flash + alink_erase_wifi_config(); +} + +void fATCT(void *arg) +{ + alink_reset_to_factory(NULL); +} +#endif + +void fATCx(void *arg) +{ +} + +log_item_t at_cloud_items[ ] = { +#if CONFIG_JOYLINK + {"ATCJ", fATCJ,}, +#endif +#if CONFIG_GAGENT + {"ATCG", fATCG,}, + {"ATCE", fATCE,}, +#endif +#if CONFIG_QQ_LINK + {"ATCQ", fATCQ,}, +#endif +#if CONFIG_AIRKISS_CLOUD + {"ATCW", fATCW}, +#endif +#if CONFIG_ALINK + {"ATCA", fATCA,}, + {"ATCZ", fATCZ,}, + {"ATCT", fATCT,}, +#endif + {"ATC?", fATCx,}, +}; +void at_cloud_init(void) +{ + log_service_add_table(at_cloud_items, sizeof(at_cloud_items)/sizeof(at_cloud_items[0])); +} + +#if SUPPORT_LOG_SERVICE +log_module_init(at_cloud_init); +#endif diff --git a/USDK/component/common/api/at_cmd/atcmd_ethernet.c b/USDK/component/common/api/at_cmd/atcmd_ethernet.c new file mode 100644 index 0000000..d43c5fa --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_ethernet.c @@ -0,0 +1,91 @@ +#include +#include "log_service.h" +#include "platform_opts.h" +#include +#include "cmsis_os.h" +#include +#include +#include + + +#define _AT_DHCP_ETHERNET_MII_ "ATE0" +#define _AT_SET_DEFAULT_INTERFACE "ATE1" + +#if CONFIG_ETHERNET +extern int dhcp_ethernet_mii; +extern int ethernet_if_default; +extern struct netif xnetif[NET_IF_NUM]; + +void fATE0(void *arg) +{ + int argc; + char *argv[MAX_ARGC] = {0}; + printf("[ATE0]:DHCP configure for ethernet\n\r"); + if(!arg){ + printf("[ATE0]Usage to disable DHCP: ATE0=0\n"); + printf("[ATE0]Usage to enable DHCP: ATE0=1\n"); + return; + } + if('0' == *(char *)arg) + { + dhcp_ethernet_mii = 0; + } + + else if('1' == *(char *)arg) + { + dhcp_ethernet_mii = 1; + LwIP_DHCP(NET_IF_NUM - 1, DHCP_START); + } + + else + { + printf("[ATE0]Usage to disable DHCP: ATE0=0\n"); + printf("[ATE0]Usage to enable DHCP: ATE0=1\n"); + } +} + +void fATE1(void *arg) +{ + int argc; + char *argv[MAX_ARGC] = {0}; + printf("[ATE1]:Set/check the default interface\n\r"); + if(!arg){ + if(ethernet_if_default) + printf("Ethernet is the default interface\n"); + else + printf("wlan is the default interface\n"); + return; + } + if('0' == *(char *)arg) + { + ethernet_if_default = 0; + printf("wlan is set to the default interface\n"); + } + + else if('1' == *(char *)arg) + { + ethernet_if_default = 1; + printf("ethernet is set to the default interface\n"); + } + + else + { + printf("[ATE0]Usage to check the default interface: ATE1\n"); + printf("[ATE0]Usage to set ethernet as default interface: ATE1=1\n"); + printf("[ATE0]Usage to set wlan as default interface: ATE1=0\n"); + } +} + +log_item_t at_ethernet_items[ ] = { + {"ATE0", fATE0,}, + {"ATE1", fATE1,} +}; + +void at_ethernet_init(void) +{ + log_service_add_table(at_ethernet_items, sizeof(at_ethernet_items)/sizeof(at_ethernet_items[0])); +} + +log_module_init(at_ethernet_init); + +#endif \ No newline at end of file diff --git a/USDK/component/common/api/at_cmd/atcmd_lwip.c b/USDK/component/common/api/at_cmd/atcmd_lwip.c new file mode 100644 index 0000000..a2b29c8 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_lwip.c @@ -0,0 +1,2263 @@ +#include +#include + +#ifdef CONFIG_AT_LWIP + +#include +#include "log_service.h" +#include "atcmd_wifi.h" +#include "atcmd_lwip.h" +#include "osdep_service.h" +#include "osdep_api.h" + +#include "tcpip.h" +#include "lwip/tcp_impl.h" + + + +#ifndef ATCMD_VER +#define ATVER_1 1 +#define ATVER_2 2 +#define ATCMD_VER ATVER_2 +#if CONFIG_EXAMPLE_UART_ATCMD +#define ATCMD_VER ATVER_2 +#else +#define ATCMD_VER ATVER_1 +#endif +#endif + +//#define MAX_BUFFER 256 +#define MAX_BUFFER (LOG_SERVICE_BUFLEN) +#define ATCP_STACK_SIZE 512//2048 + +extern char log_buf[LOG_SERVICE_BUFLEN]; +extern struct netif xnetif[NET_IF_NUM]; + +static unsigned char tx_buffer[MAX_BUFFER]; +static unsigned char rx_buffer[MAX_BUFFER]; + +#if ATCMD_VER == ATVER_2 +node node_pool[NUM_NS]; + +node* mainlist; + +static int atcmd_lwip_auto_recv = FALSE; +volatile int atcmd_lwip_tt_mode = FALSE; //transparent transmission mode +xTaskHandle atcmd_lwip_tt_task = NULL; +xSemaphoreHandle atcmd_lwip_tt_sema = NULL; +volatile int atcmd_lwip_tt_datasize = 0; +volatile int atcmd_lwip_tt_lasttickcnt = 0; + +#ifdef ERRNO +_WEAK int errno = 0; //LWIP errno +#endif + +static void atcmd_lwip_receive_task(void *param); +int atcmd_lwip_start_autorecv_task(void); +int atcmd_lwip_is_autorecv_mode(void); +void atcmd_lwip_set_autorecv_mode(int enable); +int atcmd_lwip_start_tt_task(void); +int atcmd_lwip_is_tt_mode(void); +void atcmd_lwip_set_tt_mode(int enable); +int atcmd_lwip_write_info_to_flash(struct atcmd_lwip_conn_info *cur_conn, int enable); +#else //#if ATCMD_VER == ATVER_2 + +xTaskHandle server_task = NULL; +xTaskHandle client_task = NULL; + +static int mode = 0; +static int local_port; +static int remote_port; +static char remote_addr[16]; +static int packet_size; + +static int sockfd, newsockfd; +static socklen_t client; +static struct sockaddr_in serv_addr, cli_addr; +static int opt = 1; + +static int type; //TCP SERVER:1, TCP CLIENT: 2, UDP SERVER:3, UDP CLIENT: 4 + +static void init_transport_struct(void) +{ + mode = 0; + local_port = 0; + remote_port = 0; + sockfd = -1; + newsockfd = -1; + packet_size = 0; + _memset(remote_addr, 0, sizeof(remote_addr)); + _memset(&client, 0, sizeof(client)); + _memset(&serv_addr, 0, sizeof(serv_addr)); + +} + +void socket_close(void) +{ + close(sockfd); + if(server_task != NULL) + { + vTaskDelete(server_task); + server_task = NULL; + } + if(client_task != NULL) + { + vTaskDelete(client_task); + client_task = NULL; + } + type = 0; + init_transport_struct(); +} +#endif //#if ATCMD_VER == ATVER_2 + +static void server_start(void *param) +{ + int s_mode; + int s_sockfd, s_newsockfd; + socklen_t s_client; + struct sockaddr_in s_serv_addr, s_cli_addr; + int s_local_port; + int error_no = 0; + int s_opt = 1; +#if ATCMD_VER == ATVER_2 + node* ServerNodeUsed = (node*)param; + if(ServerNodeUsed){ + s_mode = ServerNodeUsed->protocol; + s_local_port = ServerNodeUsed->port; + } +// else +//#endif +#else + { + s_mode = mode; + s_local_port = local_port; + s_opt = opt; + } +#endif + + if(s_mode == NODE_MODE_UDP) + s_sockfd = socket(AF_INET,SOCK_DGRAM,0); + else + s_sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (s_sockfd == INVALID_SOCKET_ID) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"ERROR opening socket"); + error_no = 5; + goto err_exit; + } + + if((setsockopt(s_sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&s_opt, sizeof(s_opt))) < 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"ERROR on setting socket option"); + error_no = 6; + goto err_exit; + } + + memset((char *)&s_serv_addr, 0, sizeof(s_serv_addr)); + s_serv_addr.sin_family = AF_INET; + s_serv_addr.sin_addr.s_addr = INADDR_ANY; + s_serv_addr.sin_port = htons(s_local_port); + + if (bind(s_sockfd, (struct sockaddr *)&s_serv_addr,sizeof(s_serv_addr)) < 0) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"ERROR on binding"); + error_no = 7; + goto err_exit; + } + +#if ATCMD_VER == ATVER_2 + if(ServerNodeUsed != NULL) { + uint8_t *ip = (uint8_t *)LwIP_GetIP(&xnetif[0]); + ServerNodeUsed->sockfd = s_sockfd; + ServerNodeUsed->addr = ntohl(*((u32_t *)ip)); + } +// else +//#endif +#else + { + sockfd = s_sockfd; + memcpy(&serv_addr, &s_serv_addr, sizeof(s_serv_addr)); + } +#endif + + if (s_mode == NODE_MODE_TCP){//TCP MODE + if(listen(s_sockfd , 5) < 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"ERROR on listening"); + error_no = 8; + goto err_exit; + } +#if ATCMD_VER == ATVER_2 + if(param != NULL) { + if(hang_node(ServerNodeUsed) < 0) + { + error_no = 9; + goto err_exit; + }else{ + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPS] OK" + "\r\n[ATPS] con_id=%d", + ServerNodeUsed->con_id); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } + } +#endif + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"The TCP SERVER START OK!"); + s_client = sizeof(s_cli_addr); + while(1){ + if((s_newsockfd = accept(s_sockfd,(struct sockaddr *) &s_cli_addr,&s_client)) < 0){ +#if ATCMD_VER == ATVER_2 + if(param != NULL) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS] ERROR:ERROR on accept"); + } +// else +//#endif +#else + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "ERROR on accept"); + } +#endif + error_no = 10; + goto err_exit; + } + else{ +#if ATCMD_VER == ATVER_2 + if(param != NULL) { + node* seednode = create_node(s_mode, NODE_ROLE_SEED); + if(seednode == NULL){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS]create node failed!"); + error_no = 11; + goto err_exit; + } + seednode->sockfd = s_newsockfd; + seednode->port = ntohs(s_cli_addr.sin_port); + seednode->addr = ntohl(s_cli_addr.sin_addr.s_addr); + if(hang_seednode(ServerNodeUsed,seednode) < 0){ + delete_node(seednode); + seednode = NULL; + } + else{ + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPS] A client connected to server[%d]\r\n" + "con_id:%d," + "seed," + "tcp," + "address:%s," + "port:%d," + "socket:%d", + ServerNodeUsed->con_id, + seednode->con_id, + inet_ntoa(s_cli_addr.sin_addr.s_addr), + ntohs(s_cli_addr.sin_port), + seednode->sockfd + ); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } + } +// else +//#endif +#else + { + newsockfd = s_newsockfd; + memcpy(&cli_addr, &s_cli_addr, sizeof(cli_addr)); + client = s_client; + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "A client connected to this server :\r\n[PORT]: %d\r\n[IP]:%s", + ntohs(cli_addr.sin_port), inet_ntoa(cli_addr.sin_addr.s_addr)); + } +#endif + } + } + } + else{ +#if ATCMD_VER == ATVER_2 + if(ServerNodeUsed != NULL) { + if(hang_node(ServerNodeUsed) < 0){ + error_no = 12; + goto err_exit; + } + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPS] OK" + "\r\n[ATPS] con_id=%d", + ServerNodeUsed->con_id); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + //task will exit itself + ServerNodeUsed->handletask = NULL; + } +#endif + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"The UDP SERVER START OK!"); + } + goto exit; +err_exit: +#if ATCMD_VER == ATVER_2 + if(ServerNodeUsed){ + //task will exit itself if getting here + ServerNodeUsed->handletask = NULL; + delete_node(ServerNodeUsed); + } + //else +//#endif +#else + { + socket_close(); + } +#endif + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPS] ERROR:%d", error_no); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif +exit: + return; +} + +static void client_start(void *param) +{ + int c_mode; + int c_remote_port; + char c_remote_addr[16]; + int c_sockfd; + struct sockaddr_in c_serv_addr; + int error_no = 0; +#if ATCMD_VER == ATVER_2 + struct in_addr c_addr; + node * ClientNodeUsed = (node *)param; + if(ClientNodeUsed){ + c_mode = ClientNodeUsed->protocol; + c_remote_port = ClientNodeUsed->port; + c_addr.s_addr = htonl(ClientNodeUsed->addr); + if(inet_ntoa_r(c_addr, c_remote_addr, sizeof(c_remote_addr))==NULL){ + error_no = 6; + goto err_exit; + } + } + //else +//#endif +#else + { + c_mode = mode; + c_remote_port = remote_port; + memcpy(c_remote_addr, remote_addr, 16*sizeof(char)); + } +#endif + if(c_mode == NODE_MODE_UDP) + c_sockfd = socket(AF_INET,SOCK_DGRAM,0); + else + c_sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (c_sockfd == INVALID_SOCKET_ID) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"Failed to create sock_fd!"); + error_no = 7; + goto err_exit; + } + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"OK to create sock_fd!"); + memset(&c_serv_addr, 0, sizeof(c_serv_addr)); + c_serv_addr.sin_family = AF_INET; + c_serv_addr.sin_addr.s_addr = inet_addr(c_remote_addr); + c_serv_addr.sin_port = htons(c_remote_port); + +#if ATCMD_VER == ATVER_2 + if(ClientNodeUsed){ + ClientNodeUsed->sockfd = c_sockfd; + } + //else +//#endif +#else + { + sockfd = c_sockfd; + memcpy(&serv_addr, &c_serv_addr, sizeof(c_serv_addr)); + } +#endif + if (c_mode == NODE_MODE_TCP){//TCP MODE + if(connect(c_sockfd, (struct sockaddr *)&c_serv_addr, sizeof(c_serv_addr)) == 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"Connect to Server successful!"); +#if ATCMD_VER == ATVER_2 + if(ClientNodeUsed != NULL) { + if(hang_node(ClientNodeUsed) < 0){ + error_no = 8; + goto err_exit; + } + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPC] OK\r\n[ATPC] con_id=%d",ClientNodeUsed->con_id); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } +#endif + }else{ +#if ATCMD_VER == ATVER_2 + if(ClientNodeUsed != NULL) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"[ATPC] ERROR:Connect to Server failed!"); + } + //else +//#endif +#else + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"Connect to Server failed!"); + } +#endif + error_no = 9; + goto err_exit; + } + } + else{ +#if ATCMD_VER == ATVER_2 + if(ClientNodeUsed != NULL) { + if(ClientNodeUsed->local_port){ + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family=AF_INET; + addr.sin_port=htons(ClientNodeUsed->local_port); + addr.sin_addr.s_addr=htonl(INADDR_ANY) ; + if (bind(ClientNodeUsed->sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"bind sock error!"); + error_no = 12; + goto err_exit; + } + } + if(hang_node(ClientNodeUsed) < 0){ + error_no = 10; + goto err_exit; + } + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPC] OK\r\n[ATPC] con_id=%d",ClientNodeUsed->con_id); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } +#endif + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"UDP client starts successful!"); + } + goto exit; +err_exit: +#if ATCMD_VER == ATVER_2 + if(ClientNodeUsed) + { + delete_node(ClientNodeUsed); + } + //else +//#endif +#else + { + socket_close(); + } +#endif + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPC] ERROR:%d", error_no); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif +exit: + return; +} + +static void client_start_task(void *param) +{ + vTaskDelay(1000); +#if ATCMD_VER == ATVER_2 + if(param){ + client_start(param); + vTaskDelete(NULL); + return; + } +//#endif +#else + if(remote_addr == NULL){ + printf("[ERROR] Please using ATP3 to input an valid remote IP address!\n"); + vTaskDelete(client_task); + client_task = NULL; + } + else if(remote_port == 0){ + printf("[ERROR] Please using ATP4 to input an valid remote PORT!\n"); + vTaskDelete(client_task); + client_task = NULL; + } + else{ + printf("\tStart Client\n\t[IP]: %s\n\t[PORT]:%d\n", remote_addr, remote_port); + client_start(param); + } +#endif + vTaskDelete(NULL); +} + +static void server_start_task(void *param) +{ + vTaskDelay(1000); +#if ATCMD_VER == ATVER_2 + if(param != NULL){ + server_start(param); + vTaskDelete(NULL); + return; + } +//#endif +#else + if(local_port == 0){ + printf("[ERROR] Please using ATP2 to input an valid local PORT!\n"); + vTaskDelete(server_task); + server_task = NULL; + } + else{ + uint8_t *ip = (uint8_t *)LwIP_GetIP(&xnetif[0]); + printf("Start Server\n\t[IP]: %d.%d.%d.%d\n\t[PORT]:%d\n", ip[0], ip[1], ip[2], ip[3], local_port); + server_start(param); + } +#endif + vTaskDelete(NULL); +} + +//AT Command function +#if ATCMD_VER == ATVER_1 +void fATP1(void *arg){ + if(!arg){ + printf("[ATP1]Usage: ATP1=MODE\n\r"); + goto exit; + } + mode = atoi((char*)arg); + printf("[ATP1]: _AT_TRANSPORT_MODE_ [%d]\n\r", mode); +exit: + return; +} + +void fATP2(void *arg){ + if(!arg){ + printf("[ATP2]Usage: ATP2=LOCAL_PORT\n\r"); + goto exit; + } + local_port = atoi((char*)arg); + printf("[ATP2]: _AT_TRANSPORT_LOCAL_PORT_ [%d]\n\r", local_port); + +exit: + return; +} + +void fATP3(void *arg){ + if(!arg){ + printf("[ATP3]Usage: ATP3=REMOTE_IP\n\r"); + goto exit; + } + strcpy((char*)remote_addr, (char*)arg); + printf("[ATP3]: _AT_TRANSPORT_REMOTE_IP_ [%s]\n\r", remote_addr); + +exit: + return; +} + +void fATP4(void *arg){ + if(!arg){ + printf("[ATP4]Usage: ATP4=REMOTE_PORT\n\r"); + goto exit; + } + remote_port = atoi((char*)arg); + printf("[ATP4]: _AT_TRANSPORT_REMOTE_PORT_ [%d]\n\r", remote_port); + +exit: + return; +} + +void fATP5(void *arg){ + int server_status = 0; + if(!arg){ + printf("[ATP5]Usage: ATP5=0/1(0:server disable; 1: server enable)\n\r"); + goto exit; + } + server_status = atoi((char*)arg); + printf("[ATP5]: _AT_TRANSPORT_START_SERVER_ [%d]\n\r", server_status); + if(mode == 0){ + if(server_status == 0){ + socket_close(); + type = 0; + } + else if(server_status == 1){ + if(server_task == NULL) + { + if(xTaskCreate(server_start_task, ((const char*)"server_start_task"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, &server_task) != pdPASS) + printf("[ATP5]ERROR: Create tcp server task failed.\r\n"); + } + type = 1; + } + else + printf("[ATP5]ERROR: Just support two mode : 0 or 1\n\r"); + } + else if(mode == 1){ + if(server_status == 0){ + socket_close(); + type = 0; + } + else if(server_status == 1){ + if(server_task == NULL) + { + if(xTaskCreate(server_start_task, ((const char*)"server_start_task"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, &server_task) != pdPASS) + printf("[ATP5]ERROR: Create udp server task failed.\n"); + } + type = 3; + } + else + printf("[ATP5]ERROR: Just support two mode : 0 or 1\n\r"); + } + else + printf("[ATP5]Error: mode(TCP/UDP) can't be empty\n\r"); + +exit: + return; +} + +void fATP6(void *arg){ + int client_status = 0; + if(!arg){ + printf("[ATP6]Usage: ATP6=0/1(0:Client disable; 1: Client enable)\n\r"); + goto exit; + } + client_status = atoi((char*)arg); + printf("[ATP6]: _AT_TRANSPORT_START_CLIENT_ [%d]\n\r", client_status); + if(mode == 0){ + if(client_status == 0){ + socket_close(); + type = 0; + } + else if(client_status == 1){ + printf("[ATP6]TCP Client mode will start\n"); + if(client_task == NULL) + { + if(xTaskCreate(client_start_task, ((const char*)"client_start_task"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, &client_task) != pdPASS) + printf("[ATP6]ERROR: Create tcp client task failed.\n"); + } + type = 2; + } + else + printf("[ATP6]ERROR: Just support two mode : 0 or 1\n\r"); + } + else if(mode == 1){ + if(client_status == 0){ + socket_close(); + type = 0; + } + else if(client_status == 1){ + if(client_task == NULL) + { + if(xTaskCreate(client_start_task, ((const char*)"client_start_task"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, &client_task) != pdPASS) + printf("[ATP6]ERROR: Create udp client task failed.\n"); + } + type = 4; + } + else + printf("[ATP6]ERROR: Just support two mode : 0 or 1\n\r"); + } + else + printf("[ATP6]Error: mode(TCP/UDP) can't be empty\n\r"); + +exit: + return; +} + +void fATPZ(void *arg){ + uint8_t *ip; + printf("\nThe current Transport settings:\n"); + printf("==============================\n"); + if(mode == 0) + printf(" Protocol: TCP\n"); + else if(mode == 1) + printf(" Protocol: UDP\n"); + + ip = (uint8_t *)LwIP_GetIP(&xnetif[0]); + printf(" LOCAL_IP => %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + printf(" LOCAL_PORT => %d\n", local_port); + printf(" REMOTE_IP => %s\n", remote_addr); + printf(" REMOTE_PORT => %d\n", remote_port); + +// printf("\n\r"); +} + +void fATR0(void *arg){ + if(packet_size <= 0){ + packet_size = MAX_BUFFER; + printf("[ATR0]Notice: Didn't set the value of packet_size, will using the MAX_BUFFER: %d\n", MAX_BUFFER); + } + memset(rx_buffer, 0, MAX_BUFFER); + if(type == 1){//tcp server + if((read(newsockfd,rx_buffer,MAX_BUFFER)) > 0) + printf("[ATR0]Receive the data:%s\n with packet_size: %d\n", rx_buffer, packet_size); + else + printf("[ATR0]ERROR: Failed to receive data!\n"); + close(newsockfd); + newsockfd = -1; + } + else{ + if((read(sockfd,rx_buffer,MAX_BUFFER)) > 0) + printf("[ATR0]Receive the data:%s\n with packet_size: %d\n", rx_buffer, packet_size); + else + printf("[ATR0]ERROR: Failed to receive data!\n"); + } +} + +void fATR1(void *arg){ + int size; + if(!arg){ + printf("[ATR1]Usage: ATR1=packet_size(cannot exceed %d)\n\r", MAX_BUFFER); + goto exit; + } + size = atoi((char*)arg); + printf("[ATR1]: _AT_TRANSPORT_RECEIVE_PACKET_SIZE_ [%d]\n\r", size); + if(size < 1) + printf("[ATR1]Error: packet size need be larger than 0!\n\r"); + else if(size > MAX_BUFFER) + printf("[ATR1]Error: packet size exceeds the MAX_BUFFER value: %d!\n\r", MAX_BUFFER); + else + packet_size = size; +exit: + return; +} + + +void fATRA(void *arg){ + if(!arg){ + printf("[ATRA]Usage: ATRA=[data](Data size cannot exceed the MAX_BUFFER SIZE: %d)\n\r", MAX_BUFFER); + return; + } + + if(packet_size <= 0){ + packet_size = MAX_BUFFER; + printf("[ATRA]Notice: Didn't set the value of packet_size, will using the MAX_BUFFER SIZE: %d\n", MAX_BUFFER); + } + + + int argc; + char *argv[MAX_ARGC] = {0}; + + if((argc = parse_param(arg, argv)) != 2){ + printf("[ATRA]Usage: ATRA=[data](Data size cannot exceed the MAX_BUFFER SIZE: %d)\n\r", MAX_BUFFER); + goto exit; + } + else + printf("[ATRA]: _AT_TRANSPORT_WRITE_DATA_ [%s]\n\r", argv[1]); + memset(tx_buffer, 0, MAX_BUFFER); + memcpy(tx_buffer, argv[1], strlen(argv[1])); + + if(type == 1){//tcp server + if((write(newsockfd,tx_buffer,strlen(tx_buffer))) > 0) + printf("[ATRA] Sending data:%s\n with packet_size:%d\n", tx_buffer, packet_size); + else + printf("[ATRA]ERROR: Failed to send data\n"); + close(newsockfd); + newsockfd = -1; + } + else if(type == 4){//udp client + int ret = 0; + ret = sendto(sockfd, tx_buffer, strlen(tx_buffer), 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + + printf("The value of ret is %d\n", ret); + } + else if(type == 3) + printf("The UDP Server mode not support Sending data service!\n"); + else{ + if((write(sockfd,tx_buffer, strlen(tx_buffer))) > 0) + printf("[ATRA] Sending data:%s\n with packet_size:%d\n", tx_buffer, packet_size); + else + printf("[ATRA]ERROR: Failed to send data\n"); + } +exit: + return; +} + +void fATRB(void *arg){ + int size; + if(!arg){ + printf("[ATRB]Usage: ATRB=packet_size(cannot exceed %d)\n\r", MAX_BUFFER); + goto exit; + } + size = atoi((char*)arg); + printf("[ATRB]: _AT_TRANSPORT_WRITE_PACKET_SIZE_ [%d]\n\r", size); + if(size < 1) + printf("[ATRB]Error: packet size need be larger than 0!\n\r"); + else if(size > MAX_BUFFER) + printf("[ATRB]Error: packet size exceeds the MAX_BUFFER value: %d!\n\r", MAX_BUFFER); + else + packet_size = size; +exit: + return; +} +#endif +#if ATCMD_VER == ATVER_2 +void fATP0(void *arg){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATP0]: _AT_TRANSPORT_ERRNO"); +#ifdef ERRNO + at_printf("\r\n[ATP0] OK:%d", errno); +#else + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"errno isn't enabled"); + at_printf("\r\n[ATP0] ERROR"); +#endif +} + +void fATPC(void *arg){ + + int argc; + char* argv[MAX_ARGC] = {0}; + node* clientnode = NULL; + int mode = 0; + int remote_port; + int local_port = 0; + //char remote_addr[DNS_MAX_NAME_LENGTH]; + struct in_addr addr; + int error_no = 0; +#if LWIP_DNS + struct hostent *server_host; +#endif + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPC]: _AT_TRANSPORT_START_CLIENT"); + + if(atcmd_lwip_is_tt_mode() && mainlist->next){ + error_no = 13; + goto err_exit; + } + + argc = parse_param(arg, argv); + if(argc < 4){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPC] Usage: ATPC=,,,[]"); + error_no = 1; + goto err_exit; + } + + mode = atoi((char*)argv[1]);//tcp or udp + //strcpy((char*)remote_addr, (char*)argv[2]); + + remote_port = atoi((char*)argv[3]); + if (inet_aton(argv[2], &addr) == 0) + { +#if LWIP_DNS + server_host = gethostbyname(argv[2]); + if (server_host){ + memcpy(&addr, server_host->h_addr, 4); + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPC] Found name '%s' = %s", + argv[2], + inet_ntoa(addr) + ); + } + else +#endif + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPC] ERROR: Host '%s' not found.", argv[2]); + error_no = 2; + goto err_exit; + } + } + + if(remote_port < 0 || remote_port > 65535) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPC] ERROR: remote port invalid"); + error_no = 3; + goto err_exit; + } + + if(argv[4]){ + local_port = atoi((char*)argv[4]); + if(local_port < 0 || local_port > 65535) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPC] ERROR: local port invalid"); + error_no = 11; + goto err_exit; + } + } + + clientnode = create_node(mode, NODE_ROLE_CLIENT); + if(clientnode == NULL){ + error_no = 4; + goto err_exit; + } + clientnode->port = remote_port; + clientnode->addr = ntohl(addr.s_addr); + clientnode->local_port = local_port; + + if(xTaskCreate(client_start_task, ((const char*)"client_start_task"), ATCP_STACK_SIZE, clientnode, ATCMD_LWIP_TASK_PRIORITY, NULL) != pdPASS) + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPC] ERROR: Create tcp/udp client task failed."); + error_no = 5; + goto err_exit; + } + + goto exit; +err_exit: + if(clientnode) + delete_node(clientnode); + at_printf("\r\n[ATPC] ERROR:%d", error_no); +exit: + return; +} + + +void fATPS(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + node* servernode = NULL; + int mode; + int local_port; + int error_no = 0; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPS]: _AT_TRANSPORT_START_SERVER"); + + if(atcmd_lwip_is_tt_mode()){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS] ERROR: Server can only start when TT is disabled"); + error_no = 13; + goto err_exit; + } + + argc = parse_param(arg, argv); + if(argc != 3){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS] Usage: ATPS=[TCP:0/UDP:1],[Local port(1~65535)]"); + error_no = 1; + goto err_exit; + } + + mode = atoi((char*)argv[1]); + local_port = atoi((char*)argv[2]); + + if(local_port < 0 || local_port > 65535){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS] Usage: ATPS=[TCP:0/UDP:1],[Local port]"); + error_no = 2; + goto err_exit; + } + + servernode = create_node(mode, NODE_ROLE_SERVER); + if(servernode == NULL){ + error_no = 3; + goto err_exit; + } + servernode->port = local_port; + + if(xTaskCreate(server_start_task, ((const char*)"server_start_task"), ATCP_STACK_SIZE, servernode, ATCMD_LWIP_TASK_PRIORITY, &servernode->handletask) != pdPASS) + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPS] ERROR: Create tcp/udp server task failed."); + error_no = 4; + goto err_exit; + } + + goto exit; +err_exit: + if(servernode) + delete_node(servernode); + at_printf("\r\n[ATPS] ERROR:%d", error_no); +exit: + return; +} + +void socket_close_all(void) +{ + node *currNode = mainlist->next; + + while(currNode) + { + delete_node(currNode); + currNode = mainlist->next; + } + currNode = NULL; +} + +void fATPD(void *arg){ + int con_id = INVALID_CON_ID; + int error_no = 0; + node *s_node; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPD]: _AT_TRANSPORT_CLOSE_CONNECTION"); + + if(!arg){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPD] Usage: ATPD=con_id or 0 (close all)"); + error_no = 1; + goto exit; + } + con_id = atoi((char*)arg); + + if(con_id == 0){ + if(atcmd_lwip_is_autorecv_mode()){ + atcmd_lwip_set_autorecv_mode(FALSE); + } + socket_close_all(); + goto exit; + } + + s_node = seek_node(con_id); + if(s_node == NULL){ + error_no = 3; + goto exit; + } + delete_node(s_node); + +exit: + s_node = NULL; + if(error_no) + at_printf("\r\n[ATPD] ERROR:%d", error_no); + else + at_printf("\r\n[ATPD] OK"); + return; +} + +int atcmd_lwip_send_data(node *curnode, u8 *data, u16 data_sz, struct sockaddr_in cli_addr){ + int error_no = 0; + + if((curnode->protocol == NODE_MODE_UDP) && (curnode->role == NODE_ROLE_SERVER)) + { + if (sendto(curnode->sockfd, data, data_sz, 0, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) <= 0 ){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT] ERROR:Failed to send data"); + error_no = 5; + } + }else{ + if(curnode->protocol == NODE_MODE_UDP) //UDP server + { + struct sockaddr_in serv_addr; + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(curnode->port); + serv_addr.sin_addr.s_addr = htonl(curnode->addr); + if(sendto( curnode->sockfd, data, data_sz, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <= 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT] ERROR:Failed to send data\n"); + error_no = 6; + } + }else if(curnode->protocol == NODE_MODE_TCP)//TCP server + { + if(curnode->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT] ERROR: TCP Server must send data to the seed"); + error_no = 7; + goto exit; + } + + if((write(curnode->sockfd, data, data_sz)) <= 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT] ERROR:Failed to send data\n"); + error_no = 8; + } + } + } + +exit: + return error_no; +} + +void fATPT(void *arg){ + + int argc; + char *argv[MAX_ARGC] = {0}; + int con_id = INVALID_CON_ID; + int error_no = 0; + node* curnode = NULL; + struct sockaddr_in cli_addr; + int data_sz; + int data_pos = C_NUM_AT_CMD + C_NUM_AT_CMD_DLT+ strlen(arg) + 1; + u8 *data = (u8 *)log_buf + data_pos; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPT]: _AT_TRANSPORT_SEND_DATA"); + + argc = parse_param(arg, argv); + + if(argc != 3 && argc != 5) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT] Usage: ATPT=," + "[,,]" + ":(MAX %d)", + MAX_BUFFER); + error_no = 1; + goto exit; + } + + data_sz = atoi((char*)argv[1]); + if(data_sz > MAX_BUFFER){ + error_no = 2; + goto exit; + } + + con_id = atoi((char*)argv[2]); + curnode = seek_node(con_id); + if(curnode == NULL){ + error_no = 3; + goto exit; + } + + if((curnode->protocol == NODE_MODE_UDP) + &&(curnode->role == NODE_ROLE_SERVER)) + { + char udp_clientaddr[16]={0}; + strcpy((char*)udp_clientaddr, (char*)argv[3]); + cli_addr.sin_family = AF_INET; + cli_addr.sin_port = htons(atoi((char*)argv[4])); + if (inet_aton(udp_clientaddr , &cli_addr.sin_addr) == 0) + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPT]ERROR:inet_aton() failed"); + error_no = 4; + goto exit; + } + } + error_no = atcmd_lwip_send_data(curnode, data, data_sz, cli_addr); +exit: + if(error_no) + at_printf("\r\n[ATPT] ERROR:%d,%d", error_no, con_id); + else + at_printf("\r\n[ATPT] OK,%d", con_id); + return; +} + +void fATPR(void *arg){ + + int argc,con_id = INVALID_CON_ID; + char *argv[MAX_ARGC] = {0}; + int error_no = 0; + int recv_size = 0; + int packet_size = 0; + node* curnode = NULL; + u8_t udp_clientaddr[16] = {0}; + u16_t udp_clientport = 0; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPR]: _AT_TRANSPORT_RECEIVE_DATA"); + + if(atcmd_lwip_is_autorecv_mode()){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR: Receive changed to auto mode."); + error_no = 10; + goto exit; + } + + argc = parse_param(arg, argv); + if( argc != 3){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] Usage: ATPR =,\n\r"); + error_no = 1; + goto exit; + } + + con_id = atoi((char*)argv[1]); + if(con_id <= 0 || con_id > NUM_NS){ + error_no = 9; + goto exit; + } + + packet_size = atoi((char*)argv[2]); + + if(packet_size <= 0 || packet_size > MAX_BUFFER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] Recv Size(%d) exceeds MAX_BUFFER(%d)", packet_size, + MAX_BUFFER); + error_no = 2; + goto exit; + } + + curnode = seek_node(con_id); + if(curnode == NULL){ + error_no = 3; + goto exit; + } + + if(curnode->protocol == NODE_MODE_TCP && curnode->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR: TCP Server must receive data from the seed"); + error_no = 6; + goto exit; + } + + memset(rx_buffer, 0, MAX_BUFFER); + error_no = atcmd_lwip_receive_data(curnode, rx_buffer, ETH_MAX_MTU, &recv_size, udp_clientaddr, &udp_clientport); +exit: + if(error_no == 0){ + if(curnode->protocol == NODE_MODE_UDP && curnode->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "\r\n[ATPR] OK,%d,%d,%s,%d:", recv_size, con_id, udp_clientaddr, udp_clientport); + at_printf("\r\n[ATPR] OK,%d,%d,%s,%d:", recv_size, con_id, udp_clientaddr, udp_clientport); + } + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "\r\n[ATPR] OK,%d,%d:", recv_size, con_id); + at_printf("\r\n[ATPR] OK,%d,%d:", recv_size, con_id); + } + if(recv_size) + at_print_data(rx_buffer, recv_size); + } + else + at_printf("\r\n[ATPR] ERROR:%d,%d", error_no, con_id); + return; +} + +void fATPK(void *arg){ + + int argc; + int error_no = 0; + int enable = 0; + char *argv[MAX_ARGC] = {0}; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPK]: _AT_TRANSPORT_AUTO_RECV"); + + argc = parse_param(arg, argv); + if( argc < 2){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPK] Usage: ATPK=<0/1>\n\r"); + error_no = 1; + goto exit; + } + + enable = atoi((char*)argv[1]); + + if(enable){ + if(atcmd_lwip_is_autorecv_mode()){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, "[ATPK] already enter auto receive mode"); + } + else{ + if(atcmd_lwip_start_autorecv_task()) + error_no = 2; + } + }else{ + if(atcmd_lwip_is_autorecv_mode()) + atcmd_lwip_set_autorecv_mode(FALSE); + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"[ATPK] already leave auto receive mode"); + } + } + +exit: + if(error_no) + at_printf("\r\n[ATPK] ERROR:%d", error_no); + else + at_printf("\r\n[ATPK] OK"); + return; +} + +void fATPU(void *arg){ + + int argc; + int error_no = 0; + int enable = 0; + char *argv[MAX_ARGC] = {0}; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPU]: _AT_TRANSPORT_TT_MODE"); + + argc = parse_param(arg, argv); + if( argc < 2){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPU] Usage: ATPU=<1>\n\r"); + error_no = 1; + goto exit; + } + + enable = atoi((char*)argv[1]); + + if(enable){ + if(!mainlist->next){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, "[ATPU] No conn found"); + error_no = 2; + }else if(mainlist->next->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, "[ATPU] No TT mode for server"); + error_no = 3; + } + else if(mainlist->next->next || mainlist->next->nextseed){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, "[ATPU] More than one conn found"); + error_no = 4; + } + else{ + if(atcmd_lwip_start_tt_task()){ + error_no = 5; + } + } + } + +exit: + if(error_no) + at_printf("\r\n[ATPU] ERROR:%d", error_no); + else + at_printf("\r\n[ATPU] OK"); + return; +} + +//ATPL= +void fATPL(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "\r\n[ATPL] Usage : ATPL="); + error_no = 1; + goto exit; + } + argc = parse_param(arg, argv); + if(argc != 2){ + error_no = 2; + goto exit; + } + + //ENABLE LWIP FAST CONNECT + if(argv[1] != NULL){ + int enable = atoi(argv[1]); + struct atcmd_lwip_conn_info cur_conn = {0}; + node *cur_node = mainlist->next; + if(enable && cur_node == NULL){ + error_no = 3; + goto exit; + } + cur_conn.role = cur_node->role; + cur_conn.protocol = cur_node->protocol; + cur_conn.remote_addr = cur_node->addr; + cur_conn.remote_port = cur_node->port; + cur_conn.local_addr = cur_node->local_addr; + cur_conn.local_port = cur_node->local_port; + atcmd_lwip_write_info_to_flash(&cur_conn, enable); + } + +exit: + if(error_no == 0) + at_printf("\r\n[ATPL] OK"); + else + at_printf("\r\n[ATPL] ERROR:%d",error_no); + + return; +} + +extern void do_ping_call(char *ip, int loop, int count); +void fATPP(void *arg){ + int count, argc = 0; + char buf[32] = {0}; + char *argv[MAX_ARGC] = {0}; + int con_id=INVALID_CON_ID; + int error_no = 0; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPP]: _AT_TRANSPORT_PING"); + + if(!arg){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"[ATPP] Usage: ATPP=xxxx.xxxx.xxxx.xxxx[y/loop] or ATPP=[con_id],[y/loop]\n\r"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + + if( strlen(argv[1]) < 3 ) + { + node* curnode; + struct in_addr addr; + con_id = atoi( (char*)argv[1] ); + curnode = seek_node(con_id); + if(curnode == NULL){ + error_no = 2; + goto exit; + } + if( curnode->role == 1){ //ping remote server + addr.s_addr = htonl(curnode->addr); + inet_ntoa_r(addr, buf, sizeof(buf)); + }else if( curnode->role == 0){//ping local server + strcpy(buf,SERVER); + }else if( curnode->role == 2){ //ping seed + strcpy(buf,(char*) curnode->addr); + } + }else + strcpy(buf, argv[1]); + + if(argc == 2){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"[ATPP]Repeat Count: 5"); + do_ping_call(buf, 0, 5); //Not loop, count=5 + }else{ + if(strcmp(argv[2], "loop") == 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"[ATPP]Repeat Count: %s", "loop"); + do_ping_call(buf, 1, 0); //loop, no count + }else{ + count = atoi(argv[2]); + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"[ATPP]Repeat Count: %d", count); + do_ping_call(buf, 0, count); //Not loop, with count + } + } + +exit: + if(error_no) + at_printf("\r\n[ATPP] ERROR:%d", error_no); + else + at_printf("\r\n[ATPP] OK"); + return; +} + +void fATPI(void *arg){ + node* n = mainlist->next; + struct in_addr addr; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "[ATPI]: _AT_TRANSPORT_CONNECTION_INFO"); + + while (n != NULL) + { + if(n->con_id == 0) + continue; + + at_printf("\r\ncon_id:%d,", n->con_id); + + if(n->role == 0) + at_printf("server,"); + else + at_printf("client,"); + if(n->protocol == 0) + at_printf("tcp,"); + else + at_printf("udp,"); + + addr.s_addr = htonl(n->addr); + at_printf("address:%s,port:%d,socket:%d", inet_ntoa(addr) ,n->port, n->sockfd); + if(n->nextseed != NULL) + { + node* seed = n; + do{ + seed = seed->nextseed; + at_printf("\r\ncon_id:%d,seed,", seed->con_id); + if(seed->protocol == 0) + at_printf("tcp,"); + else + at_printf("udp,"); + addr.s_addr = htonl(seed->addr); + at_printf("address:%s,port:%d,socket:%d", inet_ntoa(addr), seed->port, seed->sockfd); + }while (seed->nextseed != NULL); + } + n = n->next; + } + + at_printf("\r\n[ATPI] OK"); + + return; +} + +void init_node_pool(void){ + int i; + memset(node_pool, 0, sizeof(node_pool)); + for(i=0;inext ) + { + if(currNode == n){ + prevNode->next = currNode->next; + } + + if(currNode->role != NODE_ROLE_SERVER) + continue; + + precvSeed = currNode; + currSeed = currNode->nextseed; + while (currSeed != NULL) + { + if(currSeed == n){ + precvSeed->nextseed = n->nextseed; + } + precvSeed = currSeed; + currSeed = currSeed->nextseed; + } + } + SYS_ARCH_UNPROTECT(lev); + + if(n->role == NODE_ROLE_SERVER){ + //node may have seed if it's under server mode + while(n->nextseed != NULL){ + currSeed = n->nextseed; + // only tcp seed has its own socket, udp seed uses its server's + // so delete udp seed can't close socket which is used by server + if(currSeed->protocol == NODE_MODE_TCP && currSeed->sockfd != INVALID_SOCKET_ID){ + close(currSeed->sockfd); + currSeed->sockfd = INVALID_SOCKET_ID; + } + // no task created for seed + //if(s->handletask != NULL) + // vTaskDelete(s->handletask); + n->nextseed = currSeed->nextseed; + currSeed->con_id = INVALID_CON_ID; + }; + } + + if(!((n->protocol == NODE_MODE_UDP)&&(n->role == NODE_ROLE_SEED))){ + if(n->sockfd != INVALID_SOCKET_ID){ + close(n->sockfd); + n->sockfd = INVALID_SOCKET_ID; + } + } + //task will exit itself in fail case + if(n->handletask){ + vTaskDelete(n->handletask); + n->handletask = NULL; + } + n->con_id = INVALID_CON_ID; + return; +} + +int hang_node(node* insert_node) +{ + node* n = mainlist; + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); + while (n->next != NULL) + { + n = n->next; + if(insert_node->role == NODE_ROLE_SERVER) //need to check for server in case that two conns are binded to same port, because SO_REUSEADDR is enabled + { + if( (n->port == insert_node->port) && ((n->addr== insert_node->addr) && (n->role == insert_node->role) && (n->protocol == insert_node->protocol) ) ){ + SYS_ARCH_UNPROTECT(lev); + struct in_addr addr; + addr.s_addr = htonl(insert_node->addr); + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "This conn(IP:%s PORT:%d) already exist", + inet_ntoa(addr),insert_node->port); + return -1; + } + } + } + + n->next = insert_node; + SYS_ARCH_UNPROTECT(lev); + return 0; +} + +int hang_seednode(node* main_node ,node* insert_node) +{ + node* n = main_node; + + SYS_ARCH_DECL_PROTECT(lev); + SYS_ARCH_PROTECT(lev); + while (n->nextseed != NULL) + { + n = n->nextseed; + if( (n->port == insert_node->port) && (n->addr == insert_node->addr)){ + SYS_ARCH_UNPROTECT(lev); + struct in_addr addr; + addr.s_addr = htonl(insert_node->addr); + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "This seed IP:%s PORT:%d already exist", + inet_ntoa(addr),insert_node->port); + return -1; + } + } + + n->nextseed = insert_node; + SYS_ARCH_UNPROTECT(lev); + return 0; +} + +node *seek_node(int con_id) +{ + node* n = mainlist; + while (n->next != NULL) + { + n = n->next; + if(n->con_id == con_id) + return n; + + if(n->nextseed != NULL) + { + node* seed = n; + do{ + seed = seed->nextseed; + if(seed->con_id == con_id) + return seed; + }while (seed->nextseed != NULL); + } + } + return NULL; +} + +node *tryget_node(int n) +{ + SYS_ARCH_DECL_PROTECT(lev); + if ((n <= 0) || (n > NUM_NS)) { + return NULL; + } + SYS_ARCH_PROTECT(lev); + if (node_pool[n].con_id == INVALID_CON_ID || node_pool[n].sockfd == INVALID_SOCKET_ID) { + SYS_ARCH_UNPROTECT(lev); + return NULL; + } + SYS_ARCH_UNPROTECT(lev); + return &node_pool[n]; +} + +int atcmd_lwip_receive_data(node *curnode, u8 *buffer, u16 buffer_size, int *recv_size, + u8_t *udp_clientaddr, u16_t *udp_clientport){ + + struct timeval tv; + fd_set readfds; + int error_no = 0, ret = 0, size = 0; + + FD_ZERO(&readfds); + FD_SET(curnode->sockfd, &readfds); + tv.tv_sec = RECV_SELECT_TIMEOUT_SEC; + tv.tv_usec = RECV_SELECT_TIMEOUT_USEC; + ret = select(curnode->sockfd + 1, &readfds, NULL, NULL, &tv); + if(!((ret > 0)&&(FD_ISSET(curnode->sockfd, &readfds)))) + { + //AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + // "[ATPR] No receive event for con_id %d", curnode->con_id); + goto exit; + } + + if(curnode->protocol == NODE_MODE_UDP) //udp server receive from client + { + if(curnode->role == NODE_ROLE_SERVER){ + //node * clinode; + struct sockaddr_in client_addr; + u32_t addr_len = sizeof(struct sockaddr_in); + memset((char *) &client_addr, 0, sizeof(client_addr)); + + if ((size = recvfrom(curnode->sockfd, buffer, buffer_size, 0, (struct sockaddr *) &client_addr, &addr_len)) > 0){ + //at_printf("[ATPR]:%d,%s,%d,%s\r\n with packet_size: %d\r\n",con_id, inet_ntoa(client_addr.sin_addr.s_addr), ntohs(client_addr.sin_port), rx_buffer, packet_size); + //at_printf("\r\nsize: %d\r\n", recv_size); + //at_printf("%s", rx_buffer); + } + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR:Failed to receive data"); + error_no = 4; + } +#if 0 + clinode = create_node(NODE_MODE_UDP, NODE_ROLE_SEED); + clinode->sockfd = curnode->sockfd; + clinode->addr = ntohl(client_addr.sin_addr.s_addr); + clinode->port = ntohs(client_addr.sin_port); + if(hang_seednode(curnode,clinode) < 0){ + delete_node(clinode); + clinode = NULL; + } +#else + inet_ntoa_r(client_addr.sin_addr.s_addr, (char *)udp_clientaddr, 16); + *udp_clientport = ntohs(client_addr.sin_port); +#endif + } + else{ + struct sockaddr_in serv_addr; + u32_t addr_len = sizeof(struct sockaddr_in); + memset((char *) &serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(curnode->port); + serv_addr.sin_addr.s_addr = htonl(curnode->addr); + + if ((size = recvfrom(curnode->sockfd, buffer, buffer_size, 0, (struct sockaddr *) &serv_addr, &addr_len)) > 0){ + //at_printf("[ATPR]:%d,%s,%d,%s\r\n with packet_size: %d\r\n",con_id, inet_ntoa(serv_addr.sin_addr.s_addr), ntohs(serv_addr.sin_port), rx_buffer, packet_size); + //at_printf("\r\nsize: %d\r\n", recv_size); + //at_printf("%s", rx_buffer); + } + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR:Failed to receive data"); + error_no = 5; + } + } + } + else{ + #if 0 + if(curnode->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR: TCP Server must receive data from the seed"); + error_no = 6; + } + #endif + //receive from seed or server + if((size = read(curnode->sockfd,buffer,buffer_size)) > 0) + { + //struct in_addr addr; + //addr.s_addr = htonl(curnode->addr); + //at_printf("[ATPR]:%d,%s,%d,%s\r\n with packet_size: %d\r\n",con_id, inet_ntoa(addr), curnode->port, rx_buffer, packet_size); + //at_printf("\r\nsize: %d\r\n", recv_size); + //at_printf("%s", rx_buffer); + } + else{ + if(size == 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR:Connection is closed!"); + error_no = 7; + } + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "[ATPR] ERROR:Failed to receive data!"); + error_no = 8; + } + } + } +exit: + if(error_no == 0) + *recv_size = size; + else{ + close(curnode->sockfd); + curnode->sockfd = INVALID_SOCKET_ID; + } + return error_no; +} + +static void atcmd_lwip_receive_task(void *param) +{ + + int i; + int packet_size = ETH_MAX_MTU; + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "Enter auto receive mode"); + + while(atcmd_lwip_is_autorecv_mode()) + { + for (i = 0; i < NUM_NS; ++i) { + node* curnode = NULL; + int error_no = 0; + int recv_size = 0; + u8_t udp_clientaddr[16] = {0}; + u16_t udp_clientport = 0; + curnode = tryget_node(i); + if(curnode == NULL) + continue; + if(curnode->protocol == NODE_MODE_TCP && curnode->role == NODE_ROLE_SERVER){ + //TCP Server must receive data from the seed + continue; + } + error_no = atcmd_lwip_receive_data(curnode, rx_buffer, packet_size, &recv_size, udp_clientaddr, &udp_clientport); + + if(atcmd_lwip_is_tt_mode()){ + if((error_no == 0) && recv_size){ + rx_buffer[recv_size] = '\0'; + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"Recv[%d]:%s", recv_size, rx_buffer); + at_print_data(rx_buffer, recv_size); + rtw_msleep_os(20); + } + continue; + } + + if(error_no == 0){ + if(recv_size){ + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + if(curnode->protocol == NODE_MODE_UDP && curnode->role == NODE_ROLE_SERVER){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "\r\n[ATPR] OK,%d,%d,%s,%d:", recv_size, curnode->con_id, udp_clientaddr, udp_clientport); + at_printf("\r\n[ATPR] OK,%d,%d,%s,%d:", recv_size, curnode->con_id, udp_clientaddr, udp_clientport); + } + else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "\r\n[ATPR] OK,%d,%d:", + recv_size, + curnode->con_id); + at_printf("\r\n[ATPR] OK,%d,%d:", recv_size, curnode->con_id); + } + at_print_data(rx_buffer, recv_size); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } + } + else{ + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATPR] ERROR:%d,%d", error_no, curnode->con_id); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + } + } + } + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "Leave auto receive mode"); + + vTaskDelete(NULL); +} + +int atcmd_lwip_start_autorecv_task(void){ + atcmd_lwip_set_autorecv_mode(TRUE); + if(xTaskCreate(atcmd_lwip_receive_task, ((const char*)"atcmd_lwip_receive_task"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, NULL) != pdPASS) + { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "ERROR: Create receive task failed."); + atcmd_lwip_set_autorecv_mode(FALSE); + return -1; + } + return 0; +} + +int atcmd_lwip_is_tt_mode(void){ + return (atcmd_lwip_tt_mode == TRUE); +} +void atcmd_lwip_set_tt_mode(int enable){ + atcmd_lwip_tt_mode = enable; +} + +int atcmd_lwip_is_autorecv_mode(void){ + return (atcmd_lwip_auto_recv == TRUE); +} +void atcmd_lwip_set_autorecv_mode(int enable){ + atcmd_lwip_auto_recv = enable; +} + +static void _tt_wait_rx_complete(){ + s32 tick_current = rtw_get_current_time(); + + while(rtw_systime_to_ms(tick_current -atcmd_lwip_tt_lasttickcnt) < ATCMD_LWIP_TT_MAX_DELAY_TIME_MS ){ + rtw_msleep_os(5); + tick_current = rtw_get_current_time(); + } +} + +static void atcmd_lwip_tt_handler(void* param) +{ + struct sockaddr_in cli_addr; + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "Enter TT data mode"); + while(rtw_down_sema((_Sema *)&atcmd_lwip_tt_sema) == _SUCCESS) { + _lock lock; + _irqL irqL; + int tt_size = 0; + _tt_wait_rx_complete(); + + rtw_enter_critical(&lock, &irqL); + if((atcmd_lwip_tt_datasize >= 4) && (memcmp(log_buf, "----", 4) == 0)){ + atcmd_lwip_set_tt_mode(FALSE); + atcmd_lwip_tt_datasize = 0; + rtw_exit_critical(&lock, &irqL); + break; + } + rtw_memcpy(tx_buffer, log_buf, atcmd_lwip_tt_datasize); + tt_size = atcmd_lwip_tt_datasize; + atcmd_lwip_tt_datasize = 0; + rtw_exit_critical(&lock, &irqL); + tx_buffer[tt_size] = '\0'; + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"Send[%d]:%s", tt_size, tx_buffer); + atcmd_lwip_send_data(mainlist->next, tx_buffer, tt_size, cli_addr); + } + + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "Leave TT data mode"); + rtw_free_sema((_Sema *)&atcmd_lwip_tt_sema); + atcmd_lwip_set_autorecv_mode(FALSE); + at_printf(STR_END_OF_ATCMD_RET); //mark return to command mode + vTaskDelete(NULL); +} + +int atcmd_lwip_start_tt_task(void){ + rtw_init_sema((_Sema *)&atcmd_lwip_tt_sema, 0); + atcmd_lwip_set_tt_mode(TRUE); + if(xTaskCreate(atcmd_lwip_tt_handler, ((const char*)"tt_hdl"), ATCP_STACK_SIZE, NULL, ATCMD_LWIP_TASK_PRIORITY, &atcmd_lwip_tt_task) != pdPASS){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR, + "ERROR: Create tt task failed."); + goto err_exit; + } + rtw_msleep_os(20); + if(atcmd_lwip_is_autorecv_mode() != 1){ + if(atcmd_lwip_start_autorecv_task()){ + vTaskDelete(atcmd_lwip_tt_task); + goto err_exit; + } + } + + return 0; + +err_exit: + atcmd_lwip_set_tt_mode(FALSE); + return -1; +} + +void atcmd_lwip_erase_info(void){ + atcmd_update_partition_info(AT_PARTITION_LWIP, AT_PARTITION_ERASE, NULL, 0); +} + +int atcmd_lwip_write_info_to_flash(struct atcmd_lwip_conn_info *cur_conn, int enable) +{ + struct atcmd_lwip_conf read_data = {0}; + int i = 0, found = 0; + + atcmd_update_partition_info(AT_PARTITION_LWIP, AT_PARTITION_READ, (u8 *) &read_data, sizeof(struct atcmd_lwip_conf)); + + //fake that the conn exists already when disabling or there is no active conn on this moment + if(enable == 0){ + atcmd_lwip_erase_info(); + goto exit; + } + + if(read_data.conn_num < 0 || read_data.conn_num > ATCMD_LWIP_CONN_STORE_MAX_NUM){ + read_data.conn_num = 0; + read_data.last_index = -1; + } + + for(i = 0; i < read_data.conn_num; i++){ + if(memcmp((u8 *)cur_conn, (u8 *)&read_data.conn[i], sizeof(struct atcmd_lwip_conn_info)) == 0) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "the same profile found in flash"); + found = 1; + break; + } + } + + if(!found){ + read_data.last_index++; + if(read_data.last_index >= ATCMD_LWIP_CONN_STORE_MAX_NUM) + read_data.last_index -= ATCMD_LWIP_CONN_STORE_MAX_NUM; + memcpy((u8 *)&read_data.conn[read_data.last_index], (u8 *)cur_conn, sizeof(struct atcmd_lwip_conn_info)); + read_data.conn_num++; + if(read_data.conn_num > ATCMD_LWIP_CONN_STORE_MAX_NUM) + read_data.conn_num = ATCMD_LWIP_CONN_STORE_MAX_NUM; + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "not the same proto/addr/port, write new profile to flash"); + } + if(!found || read_data.enable != enable){ + read_data.enable = enable; + atcmd_update_partition_info(AT_PARTITION_LWIP, AT_PARTITION_WRITE, (u8 *) &read_data, sizeof(struct atcmd_lwip_conf)); + } +exit: + return 0; +} + +int atcmd_lwip_read_info_from_flash(u8 *read_data, u32 read_len) +{ + atcmd_update_partition_info(AT_PARTITION_LWIP, AT_PARTITION_READ, read_data, read_len); + return 0; +} + +int atcmd_lwip_auto_connect(void) +{ + struct atcmd_lwip_conf read_data = {0}; + struct atcmd_lwip_conn_info *re_conn; + node* re_node = NULL; + int i, error_no = 0; + int last_index; + + atcmd_lwip_read_info_from_flash((u8 *)&read_data, sizeof(struct atcmd_lwip_conf)); + if(read_data.enable == 0){ + error_no = 1; + goto exit; + } + if(read_data.conn_num > ATCMD_LWIP_CONN_STORE_MAX_NUM || read_data.conn_num <= 0){ + error_no = 2; + goto exit; + } + + last_index = read_data.last_index; + for(i = 0; i < read_data.conn_num; i++){ + re_conn = &read_data.conn[last_index]; + last_index ++; + if(last_index >= ATCMD_LWIP_CONN_STORE_MAX_NUM) + last_index -= ATCMD_LWIP_CONN_STORE_MAX_NUM; + re_node = create_node(re_conn->protocol, re_conn->role); + if(re_node == NULL){ + error_no = 3; + break; + } + re_node->addr = re_conn->remote_addr; + re_node->port = re_conn->remote_port; + re_node->local_addr = re_conn->local_addr; + re_node->local_port = re_conn->local_port; + if(re_node->protocol == NODE_MODE_UDP) + re_node->sockfd = socket(AF_INET,SOCK_DGRAM,0); + else + re_node->sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (re_node->sockfd == INVALID_SOCKET_ID) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"Failed to create sock_fd!"); + error_no = 4; + break; + } + + struct in_addr addr; + addr.s_addr = htonl(re_node->addr); + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS, + "\r\nTry connect: %d,%d,%s,%d", + re_node->sockfd, re_node->protocol, + inet_ntoa(addr), re_node->port); + + if(re_node->role == NODE_ROLE_SERVER){ + //TODO: start server here + goto exit; + } + + if (re_node->protocol == NODE_MODE_TCP){//TCP MODE + struct sockaddr_in c_serv_addr; + memset(&c_serv_addr, 0, sizeof(c_serv_addr)); + c_serv_addr.sin_family = AF_INET; + c_serv_addr.sin_addr.s_addr = htonl(re_node->addr); + c_serv_addr.sin_port = htons(re_node->port); + if(connect(re_node->sockfd, (struct sockaddr *)&c_serv_addr, sizeof(c_serv_addr)) == 0){ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"Connect to Server successful!"); + if(hang_node(re_node) < 0){ + error_no = 5; + } + break; + }else{ + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"Connect to Server failed(%d)!", errno); + error_no = 6; + delete_node(re_node); + re_node = NULL; + continue; //try next conn + } + } + else{ + if(re_node->local_port){ + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family=AF_INET; + addr.sin_port=htons(re_node->local_port); + addr.sin_addr.s_addr=htonl(INADDR_ANY) ; + if (bind(re_node->sockfd, (struct sockaddr *)&addr, sizeof(addr))<0) { + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ERROR,"bind sock error!"); + error_no = 7; + delete_node(re_node); + re_node = NULL; + continue; + } + } + if(hang_node(re_node) < 0){ + error_no = 8; + } + AT_DBG_MSG(AT_FLAG_LWIP, AT_DBG_ALWAYS,"UDP client starts successful!"); + break; + } + } + +exit: + if(re_node && error_no) + delete_node(re_node); + return error_no; +} + +int atcmd_lwip_restore_from_flash(void){ + int ret = -1; + if(atcmd_lwip_auto_connect() == 0){ + if(atcmd_lwip_start_tt_task() == 0) + ret = 0; + } + return ret; +} +#endif + +//------------------------------------------------------------ Add pvvx Lwip Info +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ + ip4_addr2_16(ipaddr), \ + ip4_addr3_16(ipaddr), \ + ip4_addr4_16(ipaddr) + +#define IPSTR "%d.%d.%d.%d" + +extern const char * const tcp_state_str[]; +/* +static const char * const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; +*/ +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +void print_udp_pcb(void) +{ + struct udp_pcb *pcb; + bool prt_none = true; + rtl_printf("UDP pcbs:\n"); + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv ); + prt_none = false; + } + if(prt_none) rtl_printf("none\n"); +} +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +void print_tcp_pcb(void) +{ + struct tcp_pcb *pcb; + rtl_printf("Active PCB states:\n"); + bool prt_none = true; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + } + if(prt_none) rtl_printf("none\n"); + rtl_printf("Listen PCB states:\n"); + prt_none = true; + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + } + if(prt_none) rtl_printf("none\n"); + rtl_printf("TIME-WAIT PCB states:\n"); + prt_none = true; + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); + prt_none = false; + } + if(prt_none) rtl_printf("none\n"); +} +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +void print_netif(int inum) +{ + rtl_printf("Net Info[%d]: " IPSTR, inum, IP2STR(&xnetif[inum].ip_addr)); + rtl_printf(", " IPSTR ", " IPSTR "\n", IP2STR(&xnetif[inum].netmask), IP2STR(&xnetif[inum].gw)); +} +/****************************************************************************** + * FunctionName : debug + * Parameters : + * Returns : +*******************************************************************************/ +//------------------------------------------------------------------------------ +void fATPx(void *arg) // Info Lwip +{ + printf("=== LwIP Info ===\n"); + print_netif(0); + print_netif(1); + print_udp_pcb(); + print_tcp_pcb(); +} +//------------------------------------------------------------ Add pvvx end +#if CONFIG_TRANSPORT +log_item_t at_transport_items[ ] = { +#if ATCMD_VER == ATVER_1 + {"ATP1", fATP1,},//mode TCP=0,UDP=1 + {"ATP2", fATP2,},//LOCAL PORT + {"ATP3", fATP3,},//REMOTE IP + {"ATP4", fATP4,},//REMOTE PORT + {"ATP5", fATP5,},//START SERVER + {"ATP6", fATP6,},//START CLIENT + {"ATP?", fATPZ,},//SETTING + {"ATR0", fATR0,},//READ DATA + {"ATR1", fATR1,},//SET PACKET SIZE + {"ATRA", fATRA,},//WRITE DATA + {"ATRB", fATRB,},//SET WRITE PACKET SIZE +#endif +#if ATCMD_VER == ATVER_2 + {"ATP0", fATP0,},//query errno if defined + {"ATPS", fATPS,},//Create Server + {"ATPD", fATPD,},//Close Server/Client connection + {"ATPC", fATPC,},//Create Client + {"ATPT", fATPT,},//WRITE DATA + {"ATPR", fATPR,},//READ DATA + {"ATPK", fATPK,},//Auto recv + {"ATPP", fATPP,},//PING + {"ATPI", fATPI,},//printf connection status + {"ATPU", fATPU,}, //transparent transmission mode + {"ATPL", fATPL,}, //lwip auto reconnect setting +#endif + {"ATP?", fATPx,}, //Lwip pcb Info +}; + +#if ATCMD_VER == ATVER_2 +void print_tcpip_at(void *arg){ + int index; + int cmd_len = 0; + + cmd_len = sizeof(at_transport_items)/sizeof(at_transport_items[0]); + for(index = 0; index < cmd_len; index++) + at_printf("\r\n%s", at_transport_items[index].log_cmd); +} +#endif + +void at_transport_init(void) +{ +#if ATCMD_VER == ATVER_2 + init_node_pool(); + mainlist = create_node(-1,-1); +#endif + log_service_add_table(at_transport_items, sizeof(at_transport_items)/sizeof(at_transport_items[0])); +} + +log_module_init(at_transport_init); +#endif +#endif //#ifdef CONFIG_AT_LWIP diff --git a/USDK/component/common/api/at_cmd/atcmd_lwip.h b/USDK/component/common/api/at_cmd/atcmd_lwip.h new file mode 100644 index 0000000..bbdb35c --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_lwip.h @@ -0,0 +1,100 @@ +#ifndef __ATCMD_LWIP_H__ +#define __ATCMD_LWIP_H__ + +#include +#ifdef CONFIG_AT_LWIP + +#include "main.h" +#include +#include "lwip/sockets.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcpip.h" +#include "lwip/pbuf.h" +#include "lwip/netdb.h" +#include "lwip_netconf.h" + + +#define _AT_TRANSPORT_MODE_ "ATP1" +#define _AT_TRANSPORT_LOCAL_PORT_ "ATP2" +#define _AT_TRANSPORT_REMOTE_IP_ "ATP3" +#define _AT_TRANSPORT_REMOTE_PORT_ "ATP4" +#define _AT_TRANSPORT_START_SERVER_ "ATP5" +#define _AT_TRANSPORT_START_CLIENT_ "ATP6" +#define _AT_TRANSPORT_SHOW_SETTING_ "ATP?" +#define _AT_TRANSPORT_RECEIVE_DATA_ "ATR0" +#define _AT_TRANSPORT_RECEIVE_PACKET_SIZE_ "ATR1" +#define _AT_TRANSPORT_WRITE_DATA_ "ATRA" +#define _AT_TRANSPORT_WRITE_PACKET_SIZE_ "ATRB" + +#define NODE_MODE_TCP 0 +#define NODE_MODE_UDP 1 + +#define NODE_ROLE_SERVER 0 +#define NODE_ROLE_CLIENT 1 +#define NODE_ROLE_SEED 2 + +#define INVALID_SOCKET_ID (-1) + +//parameters +#ifndef NET_IF_NUM +#define NET_IF_NUM 2 +#endif + +#define ATCMD_LWIP_TASK_PRIORITY (tskIDLE_PRIORITY + 1) + +#if ATCMD_VER == ATVER_2 + +#define SERVER "127.0.0.1" + +#define NUM_NS (MEMP_NUM_NETCONN) //maximum number of node and seed, same as NUM_SOCKETS + +#define ETH_MAX_MTU 1500 + +#define INVALID_CON_ID (-1) + +#define RECV_SELECT_TIMEOUT_SEC (0) +#define RECV_SELECT_TIMEOUT_USEC (20000) //20ms + +typedef struct ns +{ + int con_id; + int sockfd; + s8_t role; + int protocol; + u32_t addr; + u16_t port; + u32_t local_addr; + u16_t local_port; + xTaskHandle handletask; + struct ns* next; + struct ns* nextseed; +} node; + +extern xTaskHandle atcmd_lwip_tt_task; +extern xSemaphoreHandle atcmd_lwip_tt_sema; +extern volatile int atcmd_lwip_tt_datasize; +extern volatile int atcmd_lwip_tt_lasttickcnt; +#define ATCMD_LWIP_TT_MAX_DELAY_TIME_MS (20) //transparent transmission interval + +extern int atcmd_lwip_is_tt_mode(void); +extern void atcmd_lwip_set_tt_mode(int enable); +int atcmd_lwip_send_data(node *curnode, u8 *data, u16 data_sz, struct sockaddr_in cli_addr); +int atcmd_lwip_receive_data(node *curnode, u8 *buffer, u16 buffer_size, int *recv_size, + u8_t *udp_clientaddr, u16_t *udp_clientport); +node* create_node(int mode, s8_t role); +void init_node_pool(void); +void delete_node(node *n); +int hang_node(node* insert_node); +int hang_seednode(node* main_node ,node* insert_node); +node *seek_node(int con_id); +node *tryget_node(int n); +#endif + +#endif //#ifdef CONFIG_AT_LWIP +#endif //#ifndef __ATCMD_LWIP_H__ diff --git a/USDK/component/common/api/at_cmd/atcmd_mp.c b/USDK/component/common/api/at_cmd/atcmd_mp.c new file mode 100644 index 0000000..d10bf07 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_mp.c @@ -0,0 +1,195 @@ +#include +#include +#include +#include "log_service.h" +#include "atcmd_mp.h" + +#if CONFIG_ATCMD_MP_EXT0 + extern void fATM0(void *arg); // MP ext0 AT command +#endif + +#if CONFIG_ATCMD_MP +//-------- AT MP commands --------------------------------------------------------------- +void fATMG(void *arg) +{ + gpio_t gpio_test; + int argc = 0, val, cnts, i, write=0, data=0; + char *argv[MAX_ARGC] = {0}, port, num; + PinName pin = NC; + u32 tConfigDebugInfo = ConfigDebugInfo; + + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG]: _AT_MP_GPIO_TEST_"); + if(!arg){ + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATSG=w,PINNAMES(ex:A0B1C2...),VALUE(0/1)"); + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATSG=r,PINNAMES(ex:A0B1C2...)"); + return; + } + + argc = parse_param(arg, argv); + cnts = strlen(argv[2]); + if(cnts % 2) return; + cnts /= 2; + if(cnts == 0) return; + + if(strcmp(argv[1], "w") == 0){ + write = 1; + if(strcmp(argv[3], "1") == 0) + data = 1; + } + // Remove debug info massage + _AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] %s: ", argv[1]); + ConfigDebugInfo = 0; + for(i=0; i<(cnts*2); i+=2){ + pin = NC; + port = argv[2][i]; + num = argv[2][i+1]; + if(port >= 'a' && port <= 'z') + port -= ('a' - 'A'); + if(num >= 'a' && num <= 'z') + num -= ('a' - 'A'); + switch(port){ + case 'A': + switch(num){ + case '0': pin = PA_0; break; case '1': pin = PA_1; break; case '2': pin = PA_2; break; case '3': pin = PA_3; break; + case '4': pin = PA_4; break; case '5': pin = PA_5; break; case '6': pin = PA_6; break; case '7': pin = PA_7; break; + } + break; + case 'B': + switch(num){ + case '0': pin = PB_0; break; case '1': pin = PB_1; break; case '2': pin = PB_2; break; case '3': pin = PB_3; break; + case '4': pin = PB_4; break; case '5': pin = PB_5; break; case '6': pin = PB_6; break; case '7': pin = PB_7; break; + } + break; + case 'C': + switch(num){ + case '0': pin = PC_0; break; case '1': pin = PC_1; break; case '2': pin = PC_2; break; case '3': pin = PC_3; break; + case '4': pin = PC_4; break; case '5': pin = PC_5; break; case '6': pin = PC_6; break; case '7': pin = PC_7; break; + case '8': pin = PC_8; break; case '9': pin = PC_9; break; + } + break; + case 'D': + switch(num){ + case '0': pin = PD_0; break; case '1': pin = PD_1; break; case '2': pin = PD_2; break; case '3': pin = PD_3; break; + case '4': pin = PD_4; break; case '5': pin = PD_5; break; case '6': pin = PD_6; break; case '7': pin = PD_7; break; + case '8': pin = PD_8; break; case '9': pin = PD_9; break; + } + break; + case 'E': + switch(num){ + case '0': pin = PE_0; break; case '1': pin = PE_1; break; case '2': pin = PE_2; break; case '3': pin = PE_3; break; + case '4': pin = PE_4; break; case '5': pin = PE_5; break; case '6': pin = PE_6; break; case '7': pin = PE_7; break; + case '8': pin = PE_8; break; case '9': pin = PE_9; break; case 'A': pin = PE_A; break; + } + break; + case 'F': + switch(num){ + case '0': pin = PF_0; break; case '1': pin = PF_1; break; case '2': pin = PF_2; break; case '3': pin = PF_3; break; + case '4': pin = PF_4; break; case '5': pin = PF_5; break; + } + break; + case 'G': + switch(num){ + case '0': pin = PG_0; break; case '1': pin = PG_1; break; case '2': pin = PG_2; break; case '3': pin = PG_3; break; + case '4': pin = PG_4; break; case '5': pin = PG_5; break; case '6': pin = PG_6; break; case '7': pin = PG_7; break; + } + break; + case 'H': + switch(num){ + case '0': pin = PH_0; break; case '1': pin = PH_1; break; case '2': pin = PH_2; break; case '3': pin = PH_3; break; + case '4': pin = PH_4; break; case '5': pin = PH_5; break; case '6': pin = PH_6; break; case '7': pin = PH_7; break; + } + break; + case 'I': + switch(num){ + case '0': pin = PI_0; break; case '1': pin = PI_1; break; case '2': pin = PI_2; break; case '3': pin = PI_3; break; + case '4': pin = PI_4; break; case '5': pin = PI_5; break; case '6': pin = PI_6; break; case '7': pin = PI_7; break; + } + break; + case 'J': + switch(num){ + case '0': pin = PJ_0; break; case '1': pin = PJ_1; break; case '2': pin = PJ_2; break; case '3': pin = PJ_3; break; + case '4': pin = PJ_4; break; case '5': pin = PJ_5; break; case '6': pin = PJ_6; break; + } + break; + case 'K': + switch(num){ + case '0': pin = PK_0; break; case '1': pin = PK_1; break; case '2': pin = PK_2; break; case '3': pin = PK_3; break; + case '4': pin = PK_4; break; case '5': pin = PK_5; break; case '6': pin = PK_6; break; + } + break; + } + if(pin == NC){ + _AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "X,"); + continue; + } + // Initial input control pin + gpio_init(&gpio_test, pin); + if(write){ + gpio_dir(&gpio_test, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_test, PullNone); // No pull + gpio_write(&gpio_test, data); + _AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", data); + }else{ + gpio_dir(&gpio_test, PIN_INPUT); // Direction: Input + gpio_mode(&gpio_test, PullUp); // Pull-High + val = gpio_read(&gpio_test); + _AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", val); + } + } + _AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "\n"); + // Recover debug info massage + ConfigDebugInfo = tConfigDebugInfo; +} + +void fATMR(void *arg) +{ + u32 idx; + + AT_PRINTK("[ATMR]: _AT_MP_SDR_TEST_"); +#ifdef CONFIG_SDR_EN + for (idx = 0; idx < 0x200000; idx = idx+4){ + HAL_WRITE32(0x30000000, idx, 0x12345678); + if (HAL_READ32(0x30000000, idx) != 0x12345678) { + AT_PRINTK("[ATMR]: SDR test fail addr 0x08x, value 0x08%x",(0x30000000+idx),HAL_READ32(0x30000000, idx)); + return; + } + } + AT_PRINTK("[ATMR]: SDR test success"); +#endif +} + +void fATMt(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + + AT_PRINTK("[ATM#]: _AT_MP_TEST_"); + argc = parse_param(arg, argv); +} + +void fATMx(void *arg) +{ + AT_PRINTK("[ATM?]: _AT_MP_HELP_"); +} + +log_item_t at_mp_items[] = { + {"ATMG", fATMG,}, // MP GPIO test + {"ATMR", fATMR,}, // MP SDR test + {"ATM#", fATMt,}, // test command + {"ATM?", fATMx,}, // Help +#if CONFIG_ATCMD_MP_EXT0 + {"ATM0", fATM0,}, // MP ext0 AT command +#endif +}; + +void at_mp_init(void) +{ + log_service_add_table(at_mp_items, sizeof(at_mp_items)/sizeof(at_mp_items[0])); +} + +#if SUPPORT_LOG_SERVICE +log_module_init(at_mp_init); +#endif + +#endif // #if CONFIG_ATCMD_MP + diff --git a/USDK/component/common/api/at_cmd/atcmd_mp.h b/USDK/component/common/api/at_cmd/atcmd_mp.h new file mode 100644 index 0000000..1b2d774 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_mp.h @@ -0,0 +1,12 @@ +#ifndef __ATCMD_MP_H__ +#define __ATCMD_MP_H__ + +#define CONFIG_ATCMD_MP_EXT0 0 //support MP ext0 AT command + +typedef struct _at_command_mp_ext_item_{ + char *mp_ext_cmd; + int (*mp_ext_fun)(void **argv, int argc); + char *mp_ext_usage; +}at_mp_ext_item_t; + +#endif diff --git a/USDK/component/common/api/at_cmd/atcmd_sys.c b/USDK/component/common/api/at_cmd/atcmd_sys.c new file mode 100644 index 0000000..4400517 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_sys.c @@ -0,0 +1,1434 @@ +#include +#ifdef CONFIG_AT_SYS + +#include "platform_stdlib.h" +//#include "platform_autoconf.h" +//#include "main.h" +#include "autoconf.h" +#include "hal_adc.h" +#include "gpio_api.h" // mbed +#include "sys_api.h" +#include "rtl8195a.h" +#include "flash_api.h" +#include "rtl_lib.h" +#include "build_info.h" +#include "analogin_api.h" +#include "log_service.h" +#include "atcmd_sys.h" +#include "osdep_api.h" +#include "atcmd_wifi.h" +#include "tcm_heap.h" +#if CONFIG_OTA_UPDATE +#include "update.h" +#endif + +#ifndef ATCMD_VER +#define ATVER_1 1 +#define ATVER_2 2 +#define ATCMD_VER ATVER_2 +#if CONFIG_EXAMPLE_UART_ATCMD +#define ATCMD_VER ATVER_2 +#else +#define ATCMD_VER ATVER_1 +#endif +#endif + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "freertos_pmu.h" +#endif + +extern u32 ConfigDebugErr; +extern u32 ConfigDebugInfo; +extern u32 ConfigDebugWarn; +extern u32 CmdDumpWord(IN u16 argc, IN u8 *argv[]); +extern u32 CmdWriteWord(IN u16 argc, IN u8 *argv[]); +#if CONFIG_UART_XMODEM +extern void OTU_FW_Update(u8, u8, u32); +#endif + +struct _dev_id2name { + u8 id; + u8 *name; +}; + +struct _dev_id2name dev_id2name[] = { { UART0, "UART0" }, { UART1, "UART1" }, { +UART2, "UART2" }, { SPI0, "SPI0" }, { SPI1, "SPI1" }, { SPI2, "SPI2" }, { +SPI0_MCS, "SPI0_MCS" }, { I2C0, "I2C0" }, { I2C1, "I2C1" }, { I2C2, "I2C2" }, { +I2C3, "I2C3" }, { I2S0, "I2S0" }, { I2S1, "I2S1" }, { PCM0, "PCM0" }, { +PCM1, "PCM1" }, { ADC0, "ADC0" }, { DAC0, "DAC0" }, { DAC1, "DAC1" }, { +SDIOD, "SDIOD" }, { SDIOH, "SDIOH" }, { USBOTG, "USBOTG" }, { MII, "MII" }, { +WL_LED, "WL_LED" }, { WL_ANT0, "WL_ANT0" }, { WL_ANT1, "WL_ANT1" }, { +WL_BTCOEX, "WL_BTCOEX" }, { WL_BTCMD, "WL_BTCMD" }, { NFC, "NFC" }, { +PWM0, "PWM0" }, { PWM1, "PWM1" }, { PWM2, "PWM2" }, { PWM3, "PWM3" }, { +ETE0, "ETE0" }, { ETE1, "ETE1" }, { ETE2, "ETE2" }, { ETE3, "ETE3" }, { +EGTIM, "EGTIM" }, { SPI_FLASH, "SPI_FLASH" }, { SDR, "SDR" }, { JTAG, "JTAG" }, + { TRACE, "TRACE" }, { LOG_UART, "LOG_UART" }, { + LOG_UART_IR, "LOG_UART_IR" }, { SIC, "SIC" }, { EEPROM, "EEPROM" }, { + DEBUG, "DEBUG" }, { 255, "" } }; + +void fATSI(void *arg) { + uint32 x = 0; + int i; + u8 * s; + for (i = 0; dev_id2name[i].id != 255; i++) { + ReadHWPwrState(dev_id2name[i].id, &x); + s = "?"; + switch (x) { + case HWACT: + s = "ACT"; + break; + case HWCG: + s = "CG"; + break; + case HWINACT: + s = "WACT"; + break; + case UNDEF: + s = "UNDEF"; + break; + case ALLMET: + s = "ALLMET"; + break; + } + printf("Dev %s, state = %s\n", dev_id2name[i].name, s); + } + for (i = 0; i < _PORT_MAX; i++) + printf("Port %c state: 0x%04x\n", i + 'A', GPIOState[i]); +} + +//-------- AT SYS commands --------------------------------------------------------------- +void fATSD(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, + "[ATSD]: _AT_SYSTEM_DUMP_REGISTER_"); + if (!arg) { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSD] Usage: ATSD=REGISTER"); + return; + } + argc = parse_param(arg, argv); + if (argc == 2 || argc == 3) + CmdDumpWord(argc - 1, (unsigned char**) (argv + 1)); +} + +#if ATCMD_VER == ATVER_2 +void fATXD(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + + AT_DBG_MSG(AT_FLAG_EDIT, AT_DBG_ALWAYS, + "[ATXD]: _AT_SYSTEM_WRITE_REGISTER_"); + if (!arg) { + AT_DBG_MSG(AT_FLAG_EDIT, AT_DBG_ALWAYS, + "[ATXD] Usage: ATXD=REGISTER,VALUE"); + return; + } + argc = parse_param(arg, argv); + if (argc == 3) + CmdWriteWord(argc - 1, (unsigned char**) (argv + 1)); +} +#endif + +#if ATCMD_VER == ATVER_1 + +void fATSC(void *arg) +{ + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ALWAYS, "[ATSC]: _AT_SYSTEM_CLEAR_OTA_SIGNATURE_"); + sys_clear_ota_signature(); +} + +void fATSR(void *arg) +{ + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ALWAYS, "[ATSR]: _AT_SYSTEM_RECOVER_OTA_SIGNATURE_"); + sys_recover_ota_signature(); +} + +#if CONFIG_UART_XMODEM +void fATSY(void *arg) +{ + if (HalGetChipId() < CHIP_ID_8195AM) { + OTU_FW_Update(0, 0, 115200); + } else { + // use xmodem to update, RX: PA_6, TX: PA_7, baudrate: 1M + OTU_FW_Update(0, 2, 115200); + } +} +#endif + +#if SUPPORT_MP_MODE +void fATSA(void *arg) +{ + u32 tConfigDebugInfo = ConfigDebugInfo; + int argc = 0, channel; + char *argv[MAX_ARGC] = {0}, *ptmp; + u16 offset, gain; + + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA]: _AT_SYSTEM_ADC_TEST_"); + if(!arg) { + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] Usage: ATSA=CHANNEL(0~2)"); + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] Usage: ATSA=k_get"); + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] Usage: ATSA=k_set[offet(hex),gain(hex)]"); + return; + } + + argc = parse_param(arg, argv); + if(strcmp(argv[1], "k_get") == 0) { + sys_adc_calibration(0, &offset, &gain); +// AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain); + } else if(strcmp(argv[1], "k_set") == 0) { + if(argc != 4) { + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] Usage: ATSA=k_set[offet(hex),gain(hex)]"); + return; + } + offset = strtoul(argv[2], &ptmp, 16); + gain = strtoul(argv[3], &ptmp, 16); + sys_adc_calibration(1, &offset, &gain); +// AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] offset = 0x%04X, gain = 0x%04X", offset, gain); + } else { + channel = atoi(argv[1]); + if(channel < 0 || channel > 2) { + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] Usage: ATSA=CHANNEL(0~2)"); + return; + } + analogin_t adc; + u16 adcdat; + + // Remove debug info massage + ConfigDebugInfo = 0; + if(channel == 0) + analogin_init(&adc, AD_1); + else if(channel == 1) + analogin_init(&adc, AD_2); + else + analogin_init(&adc, AD_3); + adcdat = analogin_read_u16(&adc)>>4; + analogin_deinit(&adc); + // Recover debug info massage + ConfigDebugInfo = tConfigDebugInfo; + + AT_DBG_MSG(AT_FLAG_ADC, AT_DBG_ALWAYS, "[ATSA] A%d = 0x%04X", channel, adcdat); + } +} + +void fATSG(void *arg) +{ + gpio_t gpio_test; + int argc = 0, val; + char *argv[MAX_ARGC] = {0}, port, num; + PinName pin = NC; + u32 tConfigDebugInfo = ConfigDebugInfo; + + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG]: _AT_SYSTEM_GPIO_TEST_"); + if(!arg) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG] Usage: ATSG=PINNAME(ex:A0)"); + return; + } else { + argc = parse_param(arg, argv); + if(argc != 2) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG] Usage: ATSG=PINNAME(ex:A0)"); + return; + } + } + port = argv[1][0]; + num = argv[1][1]; + if(port >= 'a' && port <= 'z') + port -= ('a' - 'A'); + if(num >= 'a' && num <= 'z') + num -= ('a' - 'A'); + switch(port) { + case 'A': + switch(num) { + case '0': pin = PA_0; break; case '1': pin = PA_1; break; case '2': pin = PA_2; break; case '3': pin = PA_3; break; + case '4': pin = PA_4; break; case '5': pin = PA_5; break; case '6': pin = PA_6; break; case '7': pin = PA_7; break; + } + break; + case 'B': + switch(num) { + case '0': pin = PB_0; break; case '1': pin = PB_1; break; case '2': pin = PB_2; break; case '3': pin = PB_3; break; + case '4': pin = PB_4; break; case '5': pin = PB_5; break; case '6': pin = PB_6; break; case '7': pin = PB_7; break; + } + break; + case 'C': + switch(num) { + case '0': pin = PC_0; break; case '1': pin = PC_1; break; case '2': pin = PC_2; break; case '3': pin = PC_3; break; + case '4': pin = PC_4; break; case '5': pin = PC_5; break; case '6': pin = PC_6; break; case '7': pin = PC_7; break; + case '8': pin = PC_8; break; case '9': pin = PC_9; break; + } + break; + case 'D': + switch(num) { + case '0': pin = PD_0; break; case '1': pin = PD_1; break; case '2': pin = PD_2; break; case '3': pin = PD_3; break; + case '4': pin = PD_4; break; case '5': pin = PD_5; break; case '6': pin = PD_6; break; case '7': pin = PD_7; break; + case '8': pin = PD_8; break; case '9': pin = PD_9; break; + } + break; + case 'E': + switch(num) { + case '0': pin = PE_0; break; case '1': pin = PE_1; break; case '2': pin = PE_2; break; case '3': pin = PE_3; break; + case '4': pin = PE_4; break; case '5': pin = PE_5; break; case '6': pin = PE_6; break; case '7': pin = PE_7; break; + case '8': pin = PE_8; break; case '9': pin = PE_9; break; case 'A': pin = PE_A; break; + } + break; + case 'F': + switch(num) { + case '0': pin = PF_0; break; case '1': pin = PF_1; break; case '2': pin = PF_2; break; case '3': pin = PF_3; break; + case '4': pin = PF_4; break; case '5': pin = PF_5; break; + } + break; + case 'G': + switch(num) { + case '0': pin = PG_0; break; case '1': pin = PG_1; break; case '2': pin = PG_2; break; case '3': pin = PG_3; break; + case '4': pin = PG_4; break; case '5': pin = PG_5; break; case '6': pin = PG_6; break; case '7': pin = PG_7; break; + } + break; + case 'H': + switch(num) { + case '0': pin = PH_0; break; case '1': pin = PH_1; break; case '2': pin = PH_2; break; case '3': pin = PH_3; break; + case '4': pin = PH_4; break; case '5': pin = PH_5; break; case '6': pin = PH_6; break; case '7': pin = PH_7; break; + } + break; + case 'I': + switch(num) { + case '0': pin = PI_0; break; case '1': pin = PI_1; break; case '2': pin = PI_2; break; case '3': pin = PI_3; break; + case '4': pin = PI_4; break; case '5': pin = PI_5; break; case '6': pin = PI_6; break; case '7': pin = PI_7; break; + } + break; + case 'J': + switch(num) { + case '0': pin = PJ_0; break; case '1': pin = PJ_1; break; case '2': pin = PJ_2; break; case '3': pin = PJ_3; break; + case '4': pin = PJ_4; break; case '5': pin = PJ_5; break; case '6': pin = PJ_6; break; + } + break; + case 'K': + switch(num) { + case '0': pin = PK_0; break; case '1': pin = PK_1; break; case '2': pin = PK_2; break; case '3': pin = PK_3; break; + case '4': pin = PK_4; break; case '5': pin = PK_5; break; case '6': pin = PK_6; break; + } + break; + } + if(pin == NC) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG]: Invalid Pin Name"); + return; + } + // Remove debug info massage + ConfigDebugInfo = 0; + // Initial input control pin + gpio_init(&gpio_test, pin); + gpio_dir(&gpio_test, PIN_INPUT);// Direction: Input + gpio_mode(&gpio_test, PullUp);// Pull-High + val = gpio_read(&gpio_test); + // Recover debug info massage + ConfigDebugInfo = tConfigDebugInfo; + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG] %c%c = %d", port, num, val); +} + +void fATSP(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + + unsigned long timeout; // ms + unsigned long time_begin, time_current; + + gpio_t gpiob_1; + int val_old, val_new; + + int expected_zerocount, zerocount; + int test_result; + + // parameter check + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: _AT_SYSTEM_POWER_PIN_TEST_"); + if(!arg) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: Usage: ATSP=gpiob1[timeout,zerocount]"); + } else { + argc = parse_param(arg, argv); + if (argc < 2) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: Usage: ATSP=gpiob1[timeout,zerocount]"); + return; + } + } + + if ( strcmp(argv[1], "gpiob1" ) == 0 ) { + if (argc < 4) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: Usage: ATSP=gpiob1[timeout,zerocount]"); + return; + } + + // init gpiob1 test + test_result = 0; + timeout = strtoul(argv[2], NULL, 10); + expected_zerocount = atoi(argv[3]); + zerocount = 0; + val_old = 1; + + sys_log_uart_off(); + + gpio_init(&gpiob_1, PB_1); + gpio_dir(&gpiob_1, PIN_INPUT); + gpio_mode(&gpiob_1, PullDown); + + // gpiob1 test ++ + time_begin = time_current = xTaskGetTickCount(); + while (time_current < time_begin + timeout) { + val_new = gpio_read(&gpiob_1); + + if (val_new != val_old && val_new == 0) { + + zerocount ++; + if (zerocount == expected_zerocount) { + test_result = 1; + break; + } + } + + val_old = val_new; + time_current = xTaskGetTickCount(); + } + // gpio test -- + + sys_log_uart_on(); + + if (test_result == 1) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: success"); + } else { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSP]: fail, it only got %d zeros", zerocount); + } + } +} + +int write_otu_to_system_data(flash_t *flash, uint32_t otu_addr) +{ + uint32_t data, i = 0; + flash_read_word(flash, FLASH_SYSTEM_DATA_ADDR+0xc, &data); + //printf("\n\r[%s] data 0x%x otu_addr 0x%x", __FUNCTION__, data, otu_addr); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: data 0x%x otu_addr 0x%x", data, otu_addr); + if(data == ~0x0) { + flash_write_word(flash, FLASH_SYSTEM_DATA_ADDR+0xc, otu_addr); + } else { + //erase backup sector + flash_erase_sector(flash, FLASH_RESERVED_DATA_BASE); + //backup system data to backup sector + for(i = 0; i < 0x1000; i+= 4) { + flash_read_word(flash, FLASH_SYSTEM_DATA_ADDR + i, &data); + if(i == 0xc) + data = otu_addr; + flash_write_word(flash, FLASH_RESERVED_DATA_BASE + i,data); + } + //erase system data + flash_erase_sector(flash, FLASH_SYSTEM_DATA_ADDR); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4) { + flash_read_word(flash, FLASH_RESERVED_DATA_BASE + i, &data); + flash_write_word(flash, FLASH_SYSTEM_DATA_ADDR + i,data); + } + //erase backup sector + flash_erase_sector(flash, FLASH_RESERVED_DATA_BASE); + } + return 0; +} + +void fATSB(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + u32 boot_gpio, rb_boot_gpio; + u8 gpio_pin; + u8 uart_port, uart_index; + u8 gpio_pin_bar; + u8 uart_port_bar; + flash_t flash; + + // parameter check + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: _AT_SYSTEM_BOOT_OTU_PIN_SET_"); + if(!arg) { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: Usage: ATSB=[GPIO_PIN, TRIGER_MODE, UART]"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: GPIO_PIN: PB_1, PC_4 ...."); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: TRIGER_MODE: low_trigger, high_trigger"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: UART: UART0, UART2"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: example: ATSB=[PC_2, low_trigger, UART2]"); + + } else { + argc = parse_param(arg, argv); + if (argc != 4 ) { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: Usage: ATSB=[GPIO_PIN, TRIGER_MODE, UART]"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: GPIO_PIN: PB_1, PC_4 ...."); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: TRIGER_MODE: low_trigger, high_trigger"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: UART: UART0, UART2"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: example: ATSB=[PC_2, low_trigger, UART2]"); + return; + } + } + + if ( strncmp(argv[1], "P", 1) == 0 && strlen(argv[1]) == 4 + && (strcmp(argv[2], "low_trigger") == 0 || strcmp(argv[2], "high_trigger") == 0) + && strncmp(argv[3], "UART", 4) == 0 && strlen(argv[3]) == 5) { + if((0x41 <= argv[1][1] <= 0x45) && (0x30 <= argv[1][3] <= 0x39) &&(0x30 <= argv[1][4] <= 0x32)) { + if(strcmp(argv[2], "high_trigger") == 0) + gpio_pin = 1<< 7 | ((argv[1][1]-0x41)<<4) | (argv[1][3] - 0x30); + else + gpio_pin = ((argv[1][1]-0x41)<<4) | (argv[1][3] - 0x30); + gpio_pin_bar = ~gpio_pin; + uart_index = argv[3][4] - 0x30; + if(uart_index == 0) + uart_port = (uart_index<<4)|2; + else if(uart_index == 2) + uart_port = (uart_index<<4)|0; + else { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: Input UART index error. Please choose UART0 or UART2."); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: example: ATSB=[PC_2, low_trigger, UART2]"); + return; + } + uart_port_bar = ~uart_port; + boot_gpio = uart_port_bar<<24 | uart_port<<16 | gpio_pin_bar<<8 | gpio_pin; + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:gpio_pin 0x%x", gpio_pin); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:gpio_pin_bar 0x%x", gpio_pin_bar); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:uart_port 0x%x", uart_port); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:uart_port_bar 0x%x", uart_port_bar); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:boot_gpio 0x%x", boot_gpio); + write_otu_to_system_data(&flash, boot_gpio); + flash_read_word(&flash, FLASH_SYSTEM_DATA_ADDR+0x0c, &rb_boot_gpio); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]:Read 0x900c 0x%x", rb_boot_gpio); + } else { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: Usage: ATSB=[GPIO_PIN, TRIGER_MODE, UART]"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: GPIO_PIN: PB_1, PC_4 ...."); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: TRIGER_MODE: low_trigger, high_trigger"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: UART: UART0, UART2"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: example: ATSB=[PC_2, low_trigger, UART2]"); + } + } else { + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: Usage: ATSB=[GPIO_PIN, TRIGER_MODE, UART]"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: GPIO_PIN: PB_1, PC_4 ...."); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: TRIGER_MODE: low_trigger, high_trigger"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: UART: UART0, UART2"); + AT_DBG_MSG(AT_FLAG_DUMP, AT_DBG_ALWAYS, "[ATSB]: example: ATSB=[PC_2, low_trigger, UART2]"); + return; + } +} +#endif + +#if (configGENERATE_RUN_TIME_STATS == 1) +void fATSS(void *arg) // Show CPU stats +{ + AT_PRINTK("[ATSS]: _AT_SYSTEM_CPU_STATS_"); + char *cBuffer = pvPortMalloc(512); + if(cBuffer != NULL) { + vTaskGetRunTimeStats((char *)cBuffer); + AT_PRINTK("%s", cBuffer); + } + vPortFree(cBuffer); +} +#endif + +void fATSs(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + + AT_PRINTK("[ATS@]: _AT_SYSTEM_DBG_SETTING_"); + if(!arg) { + AT_PRINTK("[ATS@] Usage: ATS@=[LEVLE,FLAG]"); + } else { + argc = parse_param(arg, argv); + if(argc == 3) { + char *ptmp; + gDbgLevel = atoi(argv[1]); + gDbgFlag = strtoul(argv[2], &ptmp, 16); + } + } + AT_PRINTK("[ATS@] level = %d, flag = 0x%08X", gDbgLevel, gDbgFlag); +} + +void fATSc(void *arg) +{ + int argc = 0, config = 0; + char *argv[MAX_ARGC] = {0}; + + AT_PRINTK("[ATS!]: _AT_SYSTEM_CONFIG_SETTING_"); + if(!arg) { + AT_PRINTK("[ATS!] Usage: ATS!=[CONFIG(0,1,2),FLAG]"); + } else { + argc = parse_param(arg, argv); + if(argc == 3) { + char *ptmp; + config = atoi(argv[1]); + if(config == 0) + ConfigDebugErr = strtoul(argv[2], &ptmp, 16); + if(config == 1) + ConfigDebugInfo = strtoul(argv[2], &ptmp, 16); + if(config == 2) + ConfigDebugWarn = strtoul(argv[2], &ptmp, 16); + } + } + AT_PRINTK("[ATS!] ConfigDebugErr = 0x%08X", ConfigDebugErr); + AT_PRINTK("[ATS!] ConfigDebugInfo = 0x%08X", ConfigDebugInfo); + AT_PRINTK("[ATS!] ConfigDebugWarn = 0x%08X", ConfigDebugWarn); +} + +#define SUPPORT_CP_TEST 0 +#if SUPPORT_CP_TEST +extern void MFi_auth_test(void); +void fATSM(void *arg) +{ + AT_PRINTK("[ATSM]: _AT_SYSTEM_CP_"); + MFi_auth_test(); +} +#endif + +void fATSt(void *arg) +{ + AT_PRINTK("[ATS#]: _AT_SYSTEM_TEST_"); + DBG_8195A("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n", + HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); + dump_mem_block_list(); + tcm_heap_dump(); + DBG_8195A("\n"); +} + +void fATSJ(void *arg) +{ + int argc = 0, config = 0; + char *argv[MAX_ARGC] = {0}; + AT_PRINTK("[ATSJ]: _AT_SYSTEM_JTAG_"); + if(!arg) { + AT_PRINTK("[ATS!] Usage: ATSJ=off"); + } else { + argc = parse_param(arg, argv); + if (strcmp(argv[1], "off" ) == 0) + sys_jtag_off(); + else + AT_PRINTK("ATSL=%s is not supported!", argv[1]); + } +} + +void fATSx(void *arg) +{ +// uint32_t ability = 0; + char buf[64]; + + AT_PRINTK("[ATS?]: _AT_SYSTEM_HELP_"); + AT_PRINTK("[ATS?]: COMPILE TIME: %s", RTL8195AFW_COMPILE_TIME); +// wifi_get_drv_ability(&ability); + strcpy(buf, "v"); +// if(ability & 0x1) +// strcat(buf, "m"); + strcat(buf, ".3.5." RTL8195AFW_COMPILE_DATE); + AT_PRINTK("[ATS?]: SW VERSION: %s", buf); +} +#elif ATCMD_VER == ATVER_2 + +#define ATCMD_VERSION "v2" //ATCMD MAJOR VERSION, AT FORMAT CHANGED +#define ATCMD_SUBVERSION "2" //ATCMD MINOR VERSION, NEW COMMAND ADDED +#define ATCMD_REVISION "2" //ATCMD FIX BUG REVISION +#define SDK_VERSION "v3.5" //SDK VERSION +extern void sys_reset(void); +void print_system_at(void *arg); +extern void print_wifi_at(void *arg); +extern void print_tcpip_at(void *arg); + +// uart version 2 echo info +extern unsigned char gAT_Echo; + +void fATS0(void *arg) { + at_printf("\r\n[AT] OK"); +} + +void fATSh(void *arg) { + // print common AT command + at_printf("\r\n[ATS?] "); + at_printf("\r\nCommon AT Command:"); + print_system_at(arg); +#if CONFIG_WLAN + at_printf("\r\nWi-Fi AT Command:"); + print_wifi_at(arg); +#endif + +#if CONFIG_TRANSPORT + at_printf("\r\nTCP/IP AT Command:"); + print_tcpip_at(arg); +#endif + + at_printf("\r\n[ATS?] OK"); +} + +void fATSR(void *arg) { + at_printf("\r\n[ATSR] OK"); + sys_reset(); +} + +void fATSV(void *arg) { + char at_buf[32]; + char fw_buf[32]; + char cspimode[4] = { 'S', 'D', 'Q', '?' }; + + if (fspic_isinit == 0) { + flash_turnon(); + flash_init(&flashobj); + SpicDisableRtl8195A(); + } + printf( + "DeviceID: %02X, Flash Size: %d bytes, FlashID: %02X%02X%02X/%d, SpicMode: %cIO\n", + HalGetChipId(), (u32) (1 << flashobj.SpicInitPara.id[2]), + flashobj.SpicInitPara.id[0], flashobj.SpicInitPara.id[1], + flashobj.SpicInitPara.id[2], flashobj.SpicInitPara.flashtype, + cspimode[flashobj.SpicInitPara.Mode.BitMode]); + // get at version + strcpy(at_buf, ATCMD_VERSION"."ATCMD_SUBVERSION"."ATCMD_REVISION); + + // get fw version + strcpy(fw_buf, SDK_VERSION); + printf("%s,%s(%s)\n", at_buf, fw_buf, RTL8195AFW_COMPILE_TIME); + at_printf("\r\n[ATSV] OK:%s,%s(%s)", at_buf, fw_buf, + RTL8195AFW_COMPILE_TIME); +} + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + +void fATSP(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + + uint32_t lock_id; + uint32_t bitmap; + + if (!arg) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "\r\n[ATSP] Usage: ATSP="); + at_printf("\r\n[ATSP] ERROR:1"); + return; + } else { + if ((argc = parse_param(arg, argv)) != 2) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "\r\n[ATSP] Usage: ATSP="); + at_printf("\r\n[ATSP] ERROR:1"); + return; + } + } + + switch (argv[1][0]) { + case 'a': // acquire + { + pmu_acquire_wakelock(WAKELOCK_OS); + //at_printf("\r\n[ATSP] wakelock:0x%08x", get_wakelock_status()); + break; + } + + case 'r': // release + { + pmu_release_wakelock(WAKELOCK_OS); + //at_printf("\r\n[ATSP] wakelock:0x%08x", get_wakelock_status()); + break; + } + + case '?': // get status + break; + default: + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "\r\n[ATSP] Usage: ATSP="); + at_printf("\r\n[ATSP] ERROR:2"); + return; + } + bitmap = pmu_get_wakelock_status(); + at_printf("\r\n[ATSP] OK:%s", (bitmap&WAKELOCK_OS)?"1":"0"); +} +#endif + +void fATSE(void *arg) { + int argc = 0; + int echo = 0, mask = gDbgFlag, dbg_lv = gDbgLevel; + char *argv[MAX_ARGC] = { 0 }; + int err_no = 0; + + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, + "[ATSE]: _AT_SYSTEM_ECHO_DBG_SETTING"); + if (!arg) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "[ATSE] Usage: ATSE=,,"); + err_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + + if (argc < 2 || argc > 4) { + err_no = 2; + goto exit; + } + +#if CONFIG_EXAMPLE_UART_ATCMD + if (argv[1] != NULL) { + echo = atoi(argv[1]); + if (echo > 1 || echo < 0) { + err_no = 3; + goto exit; + } + gAT_Echo = echo ? 1 : 0; + } +#endif + + if ((argc > 2) && (argv[2] != NULL)) { + mask = strtoul(argv[2], NULL, 0); + at_set_debug_mask(mask); + } + + if ((argc == 4) && (argv[3] != NULL)) { + dbg_lv = strtoul(argv[3], NULL, 0); + at_set_debug_level(dbg_lv); + } + + exit: if (err_no) + at_printf("\r\n[ATSE] ERROR:%d", err_no); + else + at_printf("\r\n[ATSE] OK"); + return; +} +#if CONFIG_WLAN +#if CONFIG_WEBSERVER +#include "wifi_structures.h" +#include "wifi_constants.h" +extern rtw_wifi_setting_t wifi_setting; +void fATSW(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = {0}; + + if (!arg) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, "\r\n[ATSW] Usage: ATSW="); + at_printf("\r\n[ATSW] ERROR:1"); + return; + } else { + if((argc = parse_param(arg, argv)) != 2) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, "\r\n[ATSW] Usage: ATSW="); + at_printf("\r\n[ATSW] ERROR:1"); + return; + } + } + + if(argv[1][0]!='c'&&argv[1][0]!='s') { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, "\r\n[ATSW] Usage: ATSW="); + at_printf("\r\n[ATSW] ERROR:2"); + return; + } + + // make sure AP mode + LoadWifiConfig(); + if(wifi_setting.mode != RTW_MODE_AP) { + at_printf("\r\n[ATSW] ERROR:3"); + return; + } + + switch(argv[1][0]) { + case 'c': // create webserver + { + start_web_server(); + break; + } + case 's': // stop webserver + { + stop_web_server(); + break; + } + } + at_printf("\r\n[ATSW] OK"); +} +#endif + +extern int EraseApinfo(); +//extern int Erase_Fastconnect_data(); + +void fATSY(void *arg) { +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT +// Erase_Fastconnect_data(); +#endif + +#if CONFIG_WEBSERVER + EraseApinfo(); +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD + extern int reset_uart_atcmd_setting(void); + reset_uart_atcmd_setting(); +#endif + +#if CONFIG_OTA_UPDATE + // Reset ota image signature + cmd_ota_image(0); +#endif + + at_printf("\r\n[ATSY] OK"); + // reboot + sys_reset(); +} + +#if CONFIG_OTA_UPDATE +extern int wifi_is_connected_to_ap(void); +void fATSO(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + + if (!arg) { + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ERROR, + "\r\n[ATSO] Usage: ATSO=,"); + at_printf("\r\n[ATSO] ERROR:1"); + return; + } + argv[0] = "update"; + if ((argc = parse_param(arg, argv)) != 3) { + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ERROR, + "\r\n[ATSO] Usage: ATSO=,"); + at_printf("\r\n[ATSO] ERROR:1"); + return; + } + + // check wifi connect first + if (wifi_is_connected_to_ap() == 0) { + cmd_update(argc, argv); + at_printf("\r\n[ATSO] OK"); + + } else { + at_printf("\r\n[ATSO] ERROR:3"); + } +} + +void fATSC(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + int cmd = 0; + + if (!arg) { + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ERROR, "\r\n[ATSC] Usage: ATSC=<0/1>"); + at_printf("\r\n[ATSC] ERROR:1"); + return; + } + if ((argc = parse_param(arg, argv)) != 2) { + AT_DBG_MSG(AT_FLAG_OTA, AT_DBG_ERROR, "\r\n[ATSC] Usage: ATSC=<0/1>"); + at_printf("\r\n[ATSC] ERROR:1"); + return; + } + + cmd = atoi(argv[1]); + + if ((cmd != 0) && (cmd != 1)) { + at_printf("\r\n[ATSC] ERROR:2"); + return; + } + + at_printf("\r\n[ATSC] OK"); + + if (cmd == 1) { + cmd_ota_image(1); + } else { + cmd_ota_image(0); + } + // reboot + sys_reset(); +} +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD +extern const u32 log_uart_support_rate[]; + +void fATSU(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + u32 baud = 0; + u8 databits = 0; + u8 stopbits = 0; + u8 parity = 0; + u8 flowcontrol = 0; + u8 configmode = 0; + int i; + UART_LOG_CONF uartconf; + + if (!arg) { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "[ATSU] Usage: ATSU=,,,,,"); + at_printf("\r\n[ATSU] ERROR:1"); + return; + } + if ((argc = parse_param(arg, argv)) != 7) { + if(argv[1][0] == '?') { + read_uart_atcmd_setting_from_system_data(&uartconf); + at_printf("\r\n"); + at_printf( "AT_UART_CONF: %d,%d,%d,%d,%d", + uartconf.BaudRate, uartconf.DataBits, uartconf.StopBits, + uartconf.Parity, uartconf.FlowControl); +// return; + } + else { + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ERROR, + "[ATSU] Usage: ATSU=,,,,,"); + at_printf("\r\n[ATSU] ERROR:1"); + return; + } + } + else { + baud = atoi(argv[1]); + databits = atoi(argv[2]); + stopbits = atoi(argv[3]); + parity = atoi(argv[4]); + flowcontrol = atoi(argv[5]); + configmode = atoi(argv[6]); + /* + // Check Baud rate + for (i=0; log_uart_support_rate[i]!=0xFFFFFF; i++) { + if (log_uart_support_rate[i] == baud) { + break; + } + } + + if (log_uart_support_rate[i]== 0xFFFFFF) { + at_printf("\r\n[ATSU] ERROR:2"); + return; + } + */ + if (((databits < 5) || (databits > 8)) || ((stopbits < 1) || (stopbits > 2)) + || ((parity < 0) || (parity > 2)) + || ((flowcontrol < 0) || (flowcontrol > 1)) + || ((configmode < 0) || (configmode > 3)) ) { + at_printf("\r\n[ATSU] ERROR:2"); + return; + } + memset((void*) &uartconf, 0, sizeof(UART_LOG_CONF)); + uartconf.BaudRate = baud; + uartconf.DataBits = databits; + uartconf.StopBits = stopbits; + uartconf.Parity = parity; + uartconf.FlowControl = flowcontrol; + AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "AT_UART_CONF: %d,%d,%d,%d,%d", + uartconf.BaudRate, uartconf.DataBits, uartconf.StopBits, + uartconf.Parity, uartconf.FlowControl); + switch (configmode) { + case 0: // set current configuration, won't save + uart_atcmd_reinit(&uartconf); + break; + case 1: // set current configuration, and save + write_uart_atcmd_setting_to_system_data(&uartconf); + uart_atcmd_reinit(&uartconf); + break; + case 2: // set configuration, reboot to take effect + write_uart_atcmd_setting_to_system_data(&uartconf); + break; + } + } + at_printf("\r\n[ATSU] OK"); +} +#endif //#if CONFIG_EXAMPLE_UART_ATCMD +#endif //#if CONFIG_WLAN + +void fATSG(void *arg) { + gpio_t gpio_ctrl; + int argc = 0, val, error_no = 0; + char *argv[MAX_ARGC] = { 0 }, port, num; + PinName pin = NC; + + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATSG]: _AT_SYSTEM_GPIO_CTRL_"); + + if (!arg) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ERROR, + "[ATSG] Usage: ATSG=,,,,"); + error_no = 1; + goto exit; + } + if ((argc = parse_param(arg, argv)) < 3) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ERROR, + "[ATSG] Usage: ATSG=,,,,"); + error_no = 2; + goto exit; + } + + port = argv[2][1]; + num = strtoul(&argv[2][3], NULL, 0); + port -= 'A'; + pin = (port << 4 | num); + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "PORT: %s[%d]", argv[2], pin); + + if (gpio_set(pin) == 0xff) { + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ERROR, "[ATSG]: Invalid Pin Name [%d]", + pin); + error_no = 3; + goto exit; + } + + gpio_init(&gpio_ctrl, pin); + if (argv[4]) { + int dir = atoi(argv[4]); + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "DIR: %s", argv[4]); + gpio_dir(&gpio_ctrl, dir); + } + if (argv[5]) { + int pull = atoi(argv[5]); + AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "PULL: %s", argv[5]); + gpio_mode(&gpio_ctrl, pull); + } + if (argv[1][0] == 'R') { + val = gpio_read(&gpio_ctrl); + } else { + val = atoi(argv[3]); + gpio_write(&gpio_ctrl, val); + } + + exit: if (error_no) { + at_printf("\r\n[ATSG] ERROR:%d", error_no); + } else { + at_printf("\r\n[ATSG] OK:%d", val); + } +} + +#endif //#elif ATCMD_VER == ATVER_2 +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +/* + * bitmask: + * bit0: OS + * bit1: WLAN + * bit2: LOGUART + * bit3: SDIO + */ +void fATSL(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; + int err_no = 0; + uint32_t lock_id; + + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "[ATSL]: _AT_SYS_WAKELOCK_TEST_"); + + if (!arg) { + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, + "[ATSL] Usage ATSL=[a/r/?][bitmask]"); + err_no = 1; + goto exit; + } else { + argc = parse_param(arg, argv); + if (argc < 2) { + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, + "[ATSL] Usage ATSL=[a/r/?][bitmask]"); + err_no = 2; + goto exit; + } + } + + switch (argv[1][0]) { + case 'a': // acquire + { + if (argc == 3) { + lock_id = strtoul(argv[2], NULL, 16); + pmu_acquire_wakelock(lock_id); + } + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "[ATSL] wakelock:0x%08x", + pmu_get_wakelock_status()); + break; + } + + case 'r': // release + { + if (argc == 3) { + lock_id = strtoul(argv[2], NULL, 16); + pmu_release_wakelock(lock_id); + } + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "[ATSL] wakelock:0x%08x", + pmu_get_wakelock_status()); + break; + } + + case '?': // get status + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "[ATSL] wakelock:0x%08x", + pmu_get_wakelock_status()); +#if (configGENERATE_RUN_TIME_STATS == 1) + char *cBuffer = pvPortMalloc(512); + if (cBuffer != NULL) { + pmu_get_wakelock_hold_stats((char *) cBuffer); + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "%s", cBuffer); + } + vPortFree(cBuffer); +#endif + break; + +#if (configGENERATE_RUN_TIME_STATS == 1) + case 'c': // clean wakelock info (for recalculate wakelock hold time) + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, "[ATSL] clean wakelock stat"); + pmu_clean_wakelock_stat(); + break; +#endif + default: + AT_DBG_MSG(AT_FLAG_OS, AT_DBG_ALWAYS, + "[ATSL] Usage ATSL=[a/r/?][bitmask]"); + err_no = 3; + break; + } + exit: +#if ATCMD_VER == ATVER_2 + if (err_no) + at_printf("\r\n[ATSL] ERROR:%d", err_no); + else + at_printf("\r\n[ATSL] OK:0x%08x", pmu_get_wakelock_status()); +#endif + return; +} + +#if CONFIG_UART_XMODEM +void fATSX(void *arg) +{ + if (HalGetChipId() < CHIP_ID_8195AM) { + + // use xmodem to update, RX: PC_0, TX: PC_3, baudrate: 1M + OTU_FW_Update(0, 0, 115200); + // use xmodem to update, RX: PE_3, TX: PE_0, baudrate: 1M + // JTAG Off! + // OTU_FW_Update(0, 1, 115200); + } + else { + // use xmodem to update, RX: PA_6, TX: PA_7, baudrate: 1M + OTU_FW_Update(0, 2, 115200); + }; + at_printf("\r\n[ATSX] OK"); +} +#endif + +#endif + +void print_hex_dump(uint8_t *buf, int len, unsigned char k) { + uint32_t ss[2]; + ss[0] = 0x78323025; // "%02x" + ss[1] = k; // ","...'\0' + uint8_t * ptr = buf; + while (len--) { + if (len == 0) + ss[1] = 0; + printf((uint8_t *) &ss[0], *ptr++); + } +} + +//ATFD - Flash Data Dump +void fATFD(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; +#if DEBUG_AT_USER_LEVEL > 3 + printf("ATFD: _AT_FLASH_DUMP_\n"); +#endif + if (!arg) { + printf("Usage: ATFD=faddr(HEX),[size]\n"); + } else { + argc = parse_param(arg, argv); + if (argc >= 1) { + int addr; + sscanf(argv[1], "%x", &addr); + int size = 0; + if (argc > 2) + size = atoi(argv[2]); + if (size <= 0 || size > 16384) + size = 1; + u32 symbs_line = 32; + u32 rdsize = 8 * symbs_line; + uint8_t *flash_data = (uint8_t *) malloc(rdsize); + while (size) { + if (size < rdsize) + rdsize = size; + else + rdsize = 8 * symbs_line; + flash_stream_read(&flashobj, addr, rdsize, flash_data); + uint8_t *ptr = flash_data; + while (ptr < flash_data + rdsize) { + if (symbs_line > size) + symbs_line = size; + printf("%08X ", addr); + print_hex_dump(ptr, symbs_line, ' '); + printf("\r\n"); + addr += symbs_line; + ptr += symbs_line; + size -= symbs_line; + if (size == 0) + break; + } + } + free(flash_data); + } + } +} + +void fATFO(void *arg) { + int argc = 0; + char *argv[MAX_ARGC] = { 0 }; +#if DEBUG_AT_USER_LEVEL > 3 + printf("ATFO: _AT_FLASH_OTP_DUMP_\n"); +#endif + if (!arg) { + printf("Usage: ATFO=faddr(HEX),[size]\n"); + } else { + argc = parse_param(arg, argv); + if (argc >= 1) { + int addr; + sscanf(argv[1], "%x", &addr); + int size = 0; + if (argc > 2) + size = atoi(argv[2]); + if (size <= 0 || size > 16384) + size = 1; + u32 symbs_line = 32; + u32 rdsize = 8 * symbs_line; + uint8_t *flash_data = (uint8_t *) malloc(rdsize); + while (size) { + if (size < rdsize) + rdsize = size; + else + rdsize = 8 * symbs_line; + flash_otp_read(&flashobj, addr, rdsize, flash_data); + uint8_t *ptr = flash_data; + while (ptr < flash_data + rdsize) { + if (symbs_line > size) + symbs_line = size; + printf("%08X ", addr); + print_hex_dump(ptr, symbs_line, ' '); + printf("\r\n"); + addr += symbs_line; + ptr += symbs_line; + size -= symbs_line; + if (size == 0) + break; + } + } + free(flash_data); + } + } +} + +// Mem info +void fATST(void *arg) { + extern void dump_mem_block_list(void); // heap_5.c + printf("\nCLK CPU\t\t%d Hz\nRAM heap\t%d bytes\nTCM heap\t%d bytes\n", + HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); +#if CONFIG_DEBUG_LOG > 1 + dump_mem_block_list(); + tcm_heap_dump(); +#endif; + printf("\n"); +#if (configGENERATE_RUN_TIME_STATS == 1) + char *cBuffer = pvPortMalloc(512); + if(cBuffer != NULL) { + vTaskGetRunTimeStats((char *)cBuffer); + printf("%s", cBuffer); + } + vPortFree(cBuffer); +#endif +} + +#if 0 +#if 1 +#include "drv_types.h" // or #include "wlan_lib.h" +#else +#include "wifi_constants.h" +#include "wifi_structures.h" +#include "wlan_lib.h" // or #include "drv_types.h" +#endif +#include "hal_com_reg.h" +// extern Rltk_wlan_t rltk_wlan_info[2]; +void fATXT(void *arg) +{ +#if DEBUG_AT_USER_LEVEL > 3 + printf("ATWT: _AT_CFG_DUMP_\n"); +#endif + int size = 512; + int addr = 0; + uint8_t *blk_data = (uint8_t *)malloc(size); + memset(blk_data, 0xff, size); + if(blk_data) { + uint8_t * ptr = blk_data; + Hal_ReadEFuse(*(_adapter **)(rltk_wlan_info->priv), 0, 0, 512, ptr, 1); + //rtw_flash_map_update(*(_adapter **)(rltk_wlan_info->priv), 512); + u32 symbs_line = 32; + while(addr < size) { + if(symbs_line > size) symbs_line = size; + printf("%08X ", addr); + print_hex_dump(ptr, symbs_line, ' '); + printf("\r\n"); + addr += symbs_line; + ptr += symbs_line; + size -= symbs_line; + if(size == 0) break; + } + free(blk_data); + } +} +#endif +log_item_t at_sys_items[] = { +#if (ATCMD_VER == ATVER_1) + { "ATSD", fATSD}, // Dump register + { "ATSE", fATSE}, // Edit register + { "ATSC", fATSC}, // Clear OTA signature + { "ATSR", fATSR}, // Recover OTA signature +#if CONFIG_UART_XMODEM + { "ATSY", fATSY}, // uart ymodem upgrade +#endif +#if SUPPORT_MP_MODE + { "ATSA", fATSA}, // MP ADC test + { "ATSG", fATSG}, // MP GPIO test + { "ATSP", fATSP}, // MP Power related test + { "ATSB", fATSB}, // OTU PIN setup +#endif +#if (configGENERATE_RUN_TIME_STATS == 1) + { "ATSS", fATSS}, // Show CPU stats +#endif +#if SUPPORT_CP_TEST + { "ATSM", fATSM}, // Apple CP test +#endif + { "ATSJ", fATSJ}, //trun off JTAG + { "ATS@", fATSs}, // Debug message setting + { "ATS!", fATSc}, // Debug config setting + { "ATS#", fATSt}, // test command + { "ATS?", fATSx}, // Help +#elif ATCMD_VER == ATVER_2 //#if ATCMD_VER == ATVER_1 + { "AT", fATS0 }, // test AT command ready + { "ATS?", fATSh }, // list all AT command + { "ATSR", fATSR }, // system restart + { "ATSV", fATSV }, // show version info + { "ATSP", fATSP }, // power saving mode + { "ATSE", fATSE }, // enable and disable echo +#if CONFIG_WLAN +#if CONFIG_WEBSERVER + { "ATSW", fATSW}, // start webserver +#endif + { "ATSY", fATSY }, // factory reset +#if CONFIG_OTA_UPDATE + { "ATSO", fATSO }, // ota upgrate + { "ATSC", fATSC }, // chose the activited image +#endif +#if CONFIG_EXAMPLE_UART_ATCMD + { "ATSU", fATSU }, // AT uart configuration +#endif +#endif + { "ATSG", fATSG }, // GPIO control +#if CONFIG_UART_XMODEM + { "ATSX", fATSX}, // uart xmodem upgrade +#endif + { "ATSD", fATSD }, // Dump register + { "ATXD", fATXD }, // Write register +#endif // end of #if ATCMD_VER == ATVER_1 + +// Following commands exist in two versions +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + { "ATSL", fATSL }, // wakelock test +#endif + { "ATFD", fATFD }, // Flash Data Damp + { "ATFO", fATFO }, // Flash OTP Damp + { "ATST", fATST }, // add pvvx: mem info +// { "ATXT", fATXT }, // add pvvx: cfg_wifi + { "ATSI", fATSI } // Dev/Ports Info +}; + +#if ATCMD_VER == ATVER_2 +void print_system_at(void *arg) { + int index; + int cmd_len = 0; + + cmd_len = sizeof(at_sys_items) / sizeof(at_sys_items[0]); + for (index = 0; index < cmd_len; index++) + at_printf("\r\n%s", at_sys_items[index].log_cmd); +} +#endif +void at_sys_init(void) { + log_service_add_table(at_sys_items, + sizeof(at_sys_items) / sizeof(at_sys_items[0])); +} + +#if SUPPORT_LOG_SERVICE +log_module_init(at_sys_init); +#endif + +#endif //#ifdef CONFIG_AT_SYS diff --git a/USDK/component/common/api/at_cmd/atcmd_sys.h b/USDK/component/common/api/at_cmd/atcmd_sys.h new file mode 100644 index 0000000..9eaee49 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_sys.h @@ -0,0 +1,6 @@ +#ifndef __ATCMD_SYS_H__ +#define __ATCMD_SYS_H__ +#ifdef CONFIG_AT_SYS +#endif // + +#endif diff --git a/USDK/component/common/api/at_cmd/atcmd_wifi.c b/USDK/component/common/api/at_cmd/atcmd_wifi.c new file mode 100644 index 0000000..27b564e --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_wifi.c @@ -0,0 +1,2836 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "log_service.h" +#include "atcmd_wifi.h" +#include +#include "tcpip.h" +#include +#if CONFIG_WLAN +#include +#include +#include +#endif + +#if ATCMD_VER == ATVER_2 +#include "flash_api.h" +#include "device_lock.h" +#include +#endif + +#if ATCMD_VER == ATVER_2 || WIFI_LOGO_CERTIFICATION_CONFIG +#include +#endif + +/******************************************************************************/ +#define _AT_WLAN_SET_SSID_ "ATW0" +#define _AT_WLAN_SET_PASSPHRASE_ "ATW1" +#define _AT_WLAN_SET_KEY_ID_ "ATW2" +#define _AT_WLAN_AP_SET_SSID_ "ATW3" +#define _AT_WLAN_AP_SET_SEC_KEY_ "ATW4" +#define _AT_WLAN_AP_SET_CHANNEL_ "ATW5" +#define _AT_WLAN_SET_BSSID_ "ATW6" +#define _AT_WLAN_AP_ACTIVATE_ "ATWA" +#define _AT_WLAN_AP_STA_ACTIVATE_ "ATWB" +#define _AT_WLAN_JOIN_NET_ "ATWC" +#define _AT_WLAN_DISC_NET_ "ATWD" +#define _AT_WLAN_WEB_SERVER_ "ATWE" +#define _AT_WLAN_P2P_FIND_ "ATWF" +#define _AT_WLAN_P2P_START_ "ATWG" +#define _AT_WLAN_P2P_STOP_ "ATWH" +#define _AT_WLAN_PING_TEST_ "ATWI" +#define _AT_WLAN_P2P_CONNECT_ "ATWJ" +#define _AT_WLAN_P2P_DISCONNECT_ "ATWK" +#define _AT_WLAN_SSL_CLIENT_ "ATWL" +#define _AT_WLAN_PROMISC_ "ATWM" +#define _AT_WLAN_P2P_INFO_ "ATWN" +#define _AT_WLAN_OTA_UPDATE_ "ATWO" +#define _AT_WLAN_POWER_ "ATWP" +#define _AT_WLAN_SIMPLE_CONFIG_ "ATWQ" +#define _AT_WLAN_GET_RSSI_ "ATWR" +#define _AT_WLAN_SCAN_ "ATWS" +#define _AT_WLAN_SCAN_WITH_SSID_ "ATWs" +#define _AT_WLAN_TCP_TEST_ "ATWT" +#define _AT_WLAN_UDP_TEST_ "ATWU" +#define _AT_WLAN_WPS_ "ATWW" +#define _AT_WLAN_AP_WPS_ "ATWw" +#define _AT_WLAN_AIRKISS_ "ATWX" +#define _AT_WLAN_IWPRIV_ "ATWZ" +#define _AT_WLAN_INFO_ "ATW?" + +#define _AT_WLAN_EXTEND_POWER_MODE_ "ATXP" + +#ifndef CONFIG_SSL_CLIENT +#define CONFIG_SSL_CLIENT 0 +#endif +#ifndef CONFIG_WEBSERVER +#define CONFIG_WEBSERVER 0 +#endif +#ifndef CONFIG_OTA_UPDATE +#define CONFIG_OTA_UPDATE 0 +#endif +#ifndef CONFIG_BSD_TCP +#define CONFIG_BSD_TCP 1 +#endif +#ifndef CONFIG_ENABLE_P2P +#define CONFIG_ENABLE_P2P 0 +#endif +#define SCAN_WITH_SSID 0 +#if CONFIG_WEBSERVER +#define CONFIG_READ_FLASH 1 +extern rtw_wifi_setting_t wifi_setting; +#endif + +#ifndef CONFIG_WOWLAN_SERVICE +#define CONFIG_WOWLAN_SERVICE 0 +#endif + +#if CONFIG_LWIP_LAYER +extern void cmd_tcp(int argc, char **argv); +extern void cmd_udp(int argc, char **argv); +extern void cmd_ping(int argc, char **argv); +extern void cmd_ssl_client(int argc, char **argv); +#endif + +#if CONFIG_WLAN +extern void cmd_promisc(int argc, char **argv); +extern void cmd_update(int argc, char **argv); +extern void cmd_simple_config(int argc, char **argv); +#if CONFIG_ENABLE_WPS +extern void cmd_wps(int argc, char **argv); +#endif + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +extern void cmd_ap_wps(int argc, char **argv); +extern int wpas_wps_dev_config(u8 *dev_addr, u8 bregistrar); +#endif +#if CONFIG_ENABLE_P2P +extern void cmd_wifi_p2p_start(int argc, char **argv); +extern void cmd_wifi_p2p_stop(int argc, char **argv); +extern void cmd_p2p_listen(int argc, char **argv); +extern void cmd_p2p_find(int argc, char **argv); +extern void cmd_p2p_peers(int argc, char **argv); +extern void cmd_p2p_info(int argc, char **argv); +extern void cmd_p2p_disconnect(int argc, char **argv); +extern void cmd_p2p_connect(int argc, char **argv); +extern int cmd_wifi_p2p_auto_go_start(int argc, char **argv); +#endif //CONFIG_ENABLE_P2P +#if CONFIG_AIRKISS +extern int airkiss_start(); +#endif +#if CONFIG_LWIP_LAYER +extern struct netif xnetif[NET_IF_NUM]; +#endif +#if CONFIG_WOWLAN_SERVICE +extern void cmd_wowlan_service(int argc, char **argv); +#endif +#if CONFIG_INIC_CMD_RSP +extern void inic_c2h_wifi_info(const char *atcmd, char status); +extern void inic_c2h_msg(const char *atcmd, u8 status, char *msg, u16 msg_len); +#endif + +/* fastconnect use wifi AT command. Not init_wifi_struct when log service disabled + * static initialize all values for using fastconnect when log service disabled + */ +static rtw_network_info_t wifi = { + {0}, // ssid + {0}, // bssid + 0, // security + NULL, // password + 0, // password len + -1 // key id +}; + +static rtw_ap_info_t ap = {0}; +static unsigned char password[65] = {0}; + +#if ATCMD_VER == ATVER_2 || WIFI_LOGO_CERTIFICATION_CONFIG +unsigned char sta_ip[4] = {192,168,1,80}, sta_netmask[4] = {255,255,255,0}, sta_gw[4] = {192,168,1,1}; +#endif + +#if ATCMD_VER == ATVER_2 +unsigned char dhcp_mode_sta = 1, dhcp_mode_ap = 1; +unsigned char ap_ip[4] = {192,168,43,1}, ap_netmask[4] = {255,255,255,0}, ap_gw[4] = {192,168,43,1}; +static void atcmd_wifi_disconn_hdl( char* buf, int buf_len, int flags, void* userdata); +#endif + +extern unsigned char wifi_mode; // = RTW_MODE_NONE; + +static void init_wifi_struct(void) +{ + memset(wifi.ssid.val, 0, sizeof(wifi.ssid.val)); + memset(wifi.bssid.octet, 0, ETH_ALEN); + memset(password, 0, sizeof(password)); + wifi.ssid.len = 0; + wifi.password = NULL; + wifi.password_len = 0; + wifi.key_id = -1; + memset(ap.ssid.val, 0, sizeof(ap.ssid.val)); + ap.ssid.len = 0; + ap.password = NULL; + ap.password_len = 0; + ap.channel = 1; +} + +static void print_scan_result( rtw_scan_result_t* record ) +{ +#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD + at_printf("%s,%d,%s,%d,"MAC_FMT"", record->SSID.val, record->channel, + ( record->security == RTW_SECURITY_OPEN ) ? "Open" : + ( record->security == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( record->security == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( record->security == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( record->security == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( record->security == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( record->security == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + ( record->security == RTW_SECURITY_WPA_WPA2_MIXED ) ? "WPA/WPA2 AES" : "Unknown", + record->signal_strength, MAC_ARG(record->BSSID.octet) ); +#else + RTW_API_INFO( ( "%s\t ", ( record->bss_type == RTW_BSS_TYPE_ADHOC ) ? "Adhoc" : "Infra" ) ); + RTW_API_INFO( ( MAC_FMT, MAC_ARG(record->BSSID.octet) ) ); + RTW_API_INFO( ( " %d\t ", record->signal_strength ) ); + RTW_API_INFO( ( " %d\t ", record->channel ) ); + RTW_API_INFO( ( " %d\t ", record->wps_type ) ); + RTW_API_INFO( ( "%s\t\t ", ( record->security == RTW_SECURITY_OPEN ) ? "Open" : + ( record->security == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( record->security == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( record->security == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( record->security == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( record->security == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( record->security == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + ( record->security == RTW_SECURITY_WPA_WPA2_MIXED ) ? "WPA/WPA2 AES" : + "Unknown" ) ); + + RTW_API_INFO( ( " %s ", record->SSID.val ) ); + RTW_API_INFO( ( "\r\n" ) ); +#endif +} + +static rtw_result_t app_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) +{ + static int ApNum = 0; + + if (malloced_scan_result->scan_complete != RTW_TRUE) { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + +#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD + at_printf("\r\nAP : %d,", ++ApNum); +#else + RTW_API_INFO( ( "%d\t ", ++ApNum ) ); +#endif + print_scan_result(record); +#if CONFIG_INIC_CMD_RSP + if(malloced_scan_result->user_data) + memcpy((void *)((char *)malloced_scan_result->user_data+(ApNum-1)*sizeof(rtw_scan_result_t)), (char *)record, sizeof(rtw_scan_result_t)); +#endif + } else{ +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWS", RTW_SUCCESS, (char *)malloced_scan_result->user_data, ApNum*sizeof(rtw_scan_result_t)); + if(malloced_scan_result->user_data) + free(malloced_scan_result->user_data); + inic_c2h_msg("ATWS", RTW_SUCCESS, NULL, 0); +#endif +#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD + at_printf("\r\n[ATWS] OK"); + at_printf(STR_END_OF_ATCMD_RET); +#endif + ApNum = 0; + } + return RTW_SUCCESS; +} + +void fATWD(void *arg){ + int timeout = 20; + char essid[33]; + int ret = RTW_SUCCESS; +#if ATCMD_VER == ATVER_2 + int error_no = 0; +#endif + + printf("[ATWD]: _AT_WLAN_DISC_NET_\n\r"); + printf("\n\rDeassociating AP ..."); + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("\n\rWIFI disconnected"); + goto exit_success; + } +#if ATCMD_VER == ATVER_2 + wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, atcmd_wifi_disconn_hdl); +#endif + if((ret = wifi_disconnect()) < 0) { + printf("[ATWD]ERROR: Operation failed!\n\r"); +#if ATCMD_VER == ATVER_2 + error_no = 3; +#endif + goto exit; + } + + while(1) { + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("\n\rWIFI disconnected"); + break; + } + + if(timeout == 0) { + printf("[ATWD]ERROR: Deassoc timeout!\n\r"); + ret = RTW_TIMEOUT; +#if ATCMD_VER == ATVER_2 + error_no = 4; +#endif + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } + printf("\n\r"); + +#if CONFIG_LWIP_LAYER + LwIP_ReleaseIP(WLAN0_IDX); +#endif +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWD", ret, NULL, 0); +#endif + init_wifi_struct( ); +#if ATCMD_VER == ATVER_2 + if(error_no==0) + at_printf("\r\n[ATWD] OK"); + else + at_printf("\r\n[ATWD] ERROR:%d",error_no); +#endif + return; +exit_success: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWD", RTW_SUCCESS, NULL, 0); +#endif + init_wifi_struct( ); +#if ATCMD_VER == ATVER_2 + at_printf("\r\n[ATWD] OK"); +#endif + return; +} + +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) +void fATWQ(void *arg){ + int argc=0; + char *argv[2] = {0}; + printf("[ATWQ]: _AT_WLAN_SIMPLE_CONFIG_\n\r"); + argv[argc++] = "wifi_simple_config"; + if(arg){ + argv[argc++] = arg; + } + cmd_simple_config(argc, argv); +} +#endif + +void fATWS(void *arg){ + char buf[32] = {0}; + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + int num_channel = 0; + int i, argc = 0; + char *argv[MAX_ARGC] = {0}; + int ret = RTW_SUCCESS; +#if CONFIG_INIC_CMD_RSP + u8 *inic_scan_buf = NULL; +#endif +#if ATCMD_VER == ATVER_2 + int error_no = 0; +#endif + printf("[ATWS]: _AT_WLAN_SCAN_\n\r"); + if(arg){ + strcpy(buf, arg); + argc = parse_param(buf, argv); + if(argc < 2){ + ret = RTW_BADARG; +#if ATCMD_VER == ATVER_2 + error_no = 1; +#endif + goto exit; + } + num_channel = atoi(argv[1]); + channel_list = (u8*)malloc(num_channel); + if(!channel_list){ + printf("[ATWS]ERROR: Can't malloc memory for channel list\n\r"); + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#if ATCMD_VER == ATVER_2 + error_no = 2; +#endif + goto exit; + } + pscan_config = (u8*)malloc(num_channel); + if(!pscan_config){ + printf("[ATWS]ERROR: Can't malloc memory for pscan_config\n\r"); + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#if ATCMD_VER == ATVER_2 + error_no = 3; +#endif + goto exit; + } + //parse command channel list + for(i = 2; i <= argc -1 ; i++){ + *(channel_list + i - 2) = (u8)atoi(argv[i]); + *(pscan_config + i - 2) = PSCAN_ENABLE; + } + + if((ret = wifi_set_pscan_chan(channel_list, pscan_config, num_channel)) < 0){ + printf("[ATWS]ERROR: wifi set partial scan channel fail\n\r"); +#if ATCMD_VER == ATVER_2 + error_no = 4; +#endif + goto exit; + } + } +#if CONFIG_INIC_CMD_RSP + inic_scan_buf = malloc(65*sizeof(rtw_scan_result_t)); + if(inic_scan_buf == NULL){ + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; + goto exit; + } + memset(inic_scan_buf, 0, 65*sizeof(rtw_scan_result_t)); + if((ret = wifi_scan_networks(app_scan_result_handler, inic_scan_buf)) != RTW_SUCCESS){ + printf("[ATWS]ERROR: wifi scan failed\n\r"); + goto exit; + } +#else + if((ret = wifi_scan_networks(app_scan_result_handler, NULL )) != RTW_SUCCESS){ + printf("[ATWS]ERROR: wifi scan failed\n\r"); +#if ATCMD_VER == ATVER_2 + error_no = 5; +#endif + goto exit; + } +#endif +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS){ + if(inic_scan_buf) + free(inic_scan_buf); + inic_c2h_msg("ATWS", ret, NULL, 0); + } +#endif +#if ATCMD_VER == ATVER_2 + if(error_no) + at_printf("\r\n[ATWS] ERROR:%d",error_no); +#endif + if(arg && channel_list) + free(channel_list); + if(arg && pscan_config) + free(pscan_config); +} + +void fATWx(void *arg){ + int i = 0; +#if CONFIG_LWIP_LAYER + u8 *mac = LwIP_GetMAC(&xnetif[0]); + u8 *ip = LwIP_GetIP(&xnetif[0]); + u8 *gw = LwIP_GetGW(&xnetif[0]); +#endif + u8 *ifname[2] = {WLAN0_NAME,WLAN1_NAME}; + rtw_wifi_setting_t setting; + + printf("[ATW?]: _AT_WLAN_INFO_\n\r"); +#if CONFIG_INIC_CMD_RSP + int ret = RTW_SUCCESS; + int info_sz = 0; + u8 *info = malloc(NET_IF_NUM*sizeof(rtw_wifi_setting_t)+3*sizeof(rtw_mac_t)); + if(info == NULL) + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#endif + for(i=0;i %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ; + printf("\n\r\tIP => %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + printf("\n\r\tGW => %d.%d.%d.%d\n\r", gw[0], gw[1], gw[2], gw[3]); +#endif + if(setting.mode == RTW_MODE_AP || i == 1) + { + int client_number; + struct { + int count; + rtw_mac_t mac_list[AP_STA_NUM]; + } client_info; + + client_info.count = AP_STA_NUM; + wifi_get_associated_client_list(&client_info, sizeof(client_info)); + + printf("\n\rAssociated Client List:"); + printf("\n\r=============================="); + + if(client_info.count == 0) + printf("\n\rClient Num: 0\n\r", client_info.count); + else + { + printf("\n\rClient Num: %d", client_info.count); + for( client_number=0; client_number < client_info.count; client_number++ ) + { + printf("\n\rClient %d:", client_number + 1); + printf("\n\r\tMAC => "MAC_FMT"", + MAC_ARG(client_info.mac_list[client_number].octet)); +#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD + at_printf("\r\nCLIENT : %d,"MAC_FMT"", client_number + 1, MAC_ARG(client_info.mac_list[client_number].octet)); +#endif +#if CONFIG_INIC_CMD_RSP + if(info){ + memcpy(info+info_sz, (void *)&client_info.mac_list[client_number], sizeof(rtw_mac_t)); + info_sz += sizeof(rtw_mac_t); + } +#endif + } + printf("\n\r"); + } + } + } +// show the ethernet interface info + else{ +#if CONFIG_ETHERNET + if(i == NET_IF_NUM - 1){ +#if CONFIG_LWIP_LAYER + mac = LwIP_GetMAC(&xnetif[i]); + ip = LwIP_GetIP(&xnetif[i]); + gw = LwIP_GetGW(&xnetif[i]); + printf("\n\rInterface ethernet\n"); + printf("\n\r=============================="); + printf("\n\r\tMAC => %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ; + printf("\n\r\tIP => %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + printf("\n\r\tGW => %d.%d.%d.%d\n\r", gw[0], gw[1], gw[2], gw[3]); +#endif // end CONFIG_LWIP_LAYER + } +#endif // end CONFIG_ETHERNET + } + } + +#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1) + { + signed char pcWriteBuffer[1024]; + vTaskList((char*)pcWriteBuffer); + printf("\n\rTask List: \n\r%s", pcWriteBuffer); + } +#endif + +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATW?", ret, NULL, 0); + else + inic_c2h_msg("ATW?", RTW_SUCCESS, (char *)info, info_sz); + + if(info) + free(info); + info = NULL; +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD + at_printf("\r\n[ATW?] OK"); +#endif + +} + +#if ATCMD_VER == ATVER_1 +void fATW0(void *arg){ + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW0]Usage: ATW0=SSID(Maximum length is 32)\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(strlen((char*)arg) > 32){ + printf("[ATW0]Error: SSID length can't exceed 32\n\r"); + ret = RTW_BADARG; + goto exit; + } + printf("[ATW0]: _AT_WLAN_SET_SSID_ [%s]\n\r", (char*)arg); + strcpy((char *)wifi.ssid.val, (char*)arg); + wifi.ssid.len = strlen((char*)arg); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW0", ret, NULL, 0); +#endif + return; +} + +void fATW1(void *arg){ + int ret = RTW_SUCCESS; + printf("[ATW1]: _AT_WLAN_SET_PASSPHRASE_ [%s]\n\r", (char*)arg); + strcpy((char *)password, (char*)arg); + wifi.password = password; + wifi.password_len = strlen((char*)arg); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW1", ret, NULL, 0); +#endif + return; +} + +void fATW2(void *arg){ + int ret = RTW_SUCCESS; + printf("[ATW2]: _AT_WLAN_SET_KEY_ID_ [%s]\n\r", (char*)arg); + if((strlen((const char *)arg) != 1 ) || (*(char*)arg <'0' ||*(char*)arg >'3')) { + printf("[ATW2]Error: Wrong WEP key id. Must be one of 0,1,2, or 3.\n\r"); + ret = RTW_BADARG; + goto exit; + } + wifi.key_id = atoi((const char *)(arg)); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW2", ret, NULL, 0); +#endif + return; +} + +void fATW3(void *arg){ + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW3]Usage: ATW3=SSID\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(strlen((char*)arg) > 32){ + printf("[ATW3]Error: SSID length can't exceed 32\n\r"); + ret = RTW_BADARG; + goto exit; + } + strcpy((char *)ap.ssid.val, (char*)arg); + ap.ssid.len = strlen((char*)arg); + + printf("[ATW3]: _AT_WLAN_AP_SET_SSID_ [%s]\n\r", ap.ssid.val); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW3", ret, NULL, 0); +#endif + return; +} + +void fATW4(void *arg){ + int ret = RTW_SUCCESS; + + if(!arg){ + printf("[ATW4]Usage: ATW4=PASSWORD\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(strlen((char*)arg) > 64){ + printf("[ATW4]Error: PASSWORD length can't exceed 64\n\r"); + ret = RTW_BADARG; + goto exit; + } + + strcpy((char *)password, (char*)arg); + ap.password = password; + ap.password_len = strlen((char*)arg); + printf("[ATW4]: _AT_WLAN_AP_SET_SEC_KEY_ [%s]\n\r", ap.password); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW4", ret, NULL, 0); +#endif + return; +} + +void fATW5(void *arg){ + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW5]Usage: ATW5=CHANNEL\n\r"); + ret = RTW_BADARG; + goto exit; + } + ap.channel = (unsigned char) atoi((const char *)arg); + printf("[ATW5]: _AT_WLAN_AP_SET_CHANNEL_ [channel %d]\n\r", ap.channel); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW5", ret, NULL, 0); +#endif + return; +} + +void fATW6(void *arg){ + u32 mac[ETH_ALEN]; + u32 i; + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW6]Usage: ATW6=BSSID\n\r"); + ret = RTW_BADARG; + goto exit; + } + printf("[ATW6]: _AT_WLAN_SET_BSSID_ [%s]\n\r", (char*)arg); + sscanf(arg, MAC_FMT, mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + for(i = 0; i < ETH_ALEN; i ++) + wifi.bssid.octet[i] = (u8)mac[i] & 0xFF; +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW6", ret, NULL, 0); +#endif + return; +} + +void fATWA(void *arg){ +#if CONFIG_LWIP_LAYER + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif = &xnetif[0]; +#endif + int timeout = 20; + int ret = RTW_SUCCESS; + printf("[ATWA]: _AT_WLAN_AP_ACTIVATE_\n\r"); + if(ap.ssid.val[0] == 0){ + printf("[ATWA]Error: SSID can't be empty\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(ap.password == NULL){ + ap.security_type = RTW_SECURITY_OPEN; + } + else{ + if(ap.password_len <= RTW_MAX_PSK_LEN && + ap.password_len >= RTW_MIN_PSK_LEN){ + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + else{ + printf("[ATWA]Error: password length is between 8 to 64 \n\r"); + ret = RTW_INVALID_KEY; + goto exit; + } + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid));; + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password)); + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); + IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask,&gw); +#ifdef CONFIG_DONT_CARE_TP + pnetif->flags |= NETIF_FLAG_IPSWITCH; +#endif +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_AP) < 0){ + printf("\n\rERROR: Wifi on failed!"); + ret = RTW_ERROR; + goto exit; + } + printf("\n\rStarting AP ..."); + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + wpas_wps_dev_config(pnetif->hwaddr, 1); +#endif + if((ret = wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password,/* ap.ssid.len, ap.password_len,*/ ap.channel, 0) )< 0) { + printf("\n\rERROR: Operation failed!"); + goto exit; + } + + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + printf("\n\r%s started\n", ap.ssid.val); + ret = RTW_SUCCESS; + break; + } + } + + if(timeout == 0) { + printf("\n\rERROR: Start AP timeout!"); + ret = RTW_TIMEOUT; + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } + +#if defined( CONFIG_ENABLE_AP_POLLING_CLIENT_ALIVE )&&( CONFIG_ENABLE_AP_POLLING_CLIENT_ALIVE == 1 ) + wifi_set_ap_polling_sta(1); +#endif + +#if CONFIG_LWIP_LAYER + //LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); +#endif + +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWA", ret); +#endif + init_wifi_struct( ); +} + +#if CONFIG_INIC_EN +static int _find_ap_from_scan_buf(char*buf, int buflen, char *target_ssid, void *user_data) +{ + rtw_wifi_setting_t *pwifi = (rtw_wifi_setting_t *)user_data; + int plen = 0; + + while(plen < buflen){ + u8 len, ssid_len, security_mode; + char *ssid; + + // len offset = 0 + len = (int)*(buf + plen); + // check end + if(len == 0) break; + // ssid offset = 14 + ssid_len = len - 14; + ssid = buf + plen + 14 ; + if((ssid_len == strlen(target_ssid)) + && (!memcmp(ssid, target_ssid, ssid_len))) + { + strcpy((char*)pwifi->ssid, target_ssid); + // channel offset = 13 + pwifi->channel = *(buf + plen + 13); + // security_mode offset = 11 + security_mode = (u8)*(buf + plen + 11); + if(security_mode == IW_ENCODE_ALG_NONE) + pwifi->security_type = RTW_SECURITY_OPEN; + else if(security_mode == IW_ENCODE_ALG_WEP) + pwifi->security_type = RTW_SECURITY_WEP_PSK; + else if(security_mode == IW_ENCODE_ALG_CCMP) + pwifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + } + plen += len; + } + return 0; +} + +static int _get_ap_security_mode(IN char * ssid, OUT rtw_security_t *security_mode, OUT u8 * channel) +{ + rtw_wifi_setting_t wifi; + u32 scan_buflen = 1000; + + memset(&wifi, 0, sizeof(wifi)); + + if(wifi_scan_networks_with_ssid(_find_ap_from_scan_buf, (void*)&wifi, scan_buflen, ssid, strlen(ssid)) != RTW_SUCCESS){ + printf("Wifi scan failed!\n"); + return 0; + } + + if(strcmp(wifi.ssid, ssid) == 0){ + *security_mode = wifi.security_type; + *channel = wifi.channel; + return 1; + } + + return 0; +} +#endif + +void fATWC(void *arg){ + int mode, ret; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + char empty_bssid[6] = {0}, assoc_by_bssid = 0; + + printf("[ATWC]: _AT_WLAN_JOIN_NET_\n\r"); + if(memcmp (wifi.bssid.octet, empty_bssid, 6)) + assoc_by_bssid = 1; + else if(wifi.ssid.val[0] == 0){ + printf("[ATWC]Error: SSID can't be empty\n\r"); + ret = RTW_BADARG; + goto EXIT; + } + if(wifi.password != NULL){ + if((wifi.key_id >= 0)&&(wifi.key_id <= 3)) { + wifi.security_type = RTW_SECURITY_WEP_PSK; + } + else{ + wifi.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + } + else{ + wifi.security_type = RTW_SECURITY_OPEN; + } + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("\n\rERROR: Wifi on failed!"); + ret = RTW_ERROR; + goto EXIT; + } + } + +#if CONFIG_INIC_EN //get security mode from scan list + u8 connect_channel; + u8 pscan_config; + //the keyID may be not set for WEP which may be confued with WPA2 + if((wifi.security_type == RTW_SECURITY_UNKNOWN)||(wifi.security_type == RTW_SECURITY_WPA2_AES_PSK)) + { + int security_retry_count = 0; + while (1) { + if (_get_ap_security_mode((char*)wifi.ssid.val, &wifi.security_type, &connect_channel)) + break; + security_retry_count++; + if(security_retry_count >= 3){ + printf("Can't get AP security mode and channel.\n"); + ret = RTW_NOTFOUND; + goto EXIT; + } + } + if(wifi.security_type == RTW_SECURITY_WEP_PSK || wifi.security_type == RTW_SECURITY_WEP_SHARED) + wifi.key_id = (wifi.key_id <0 || wifi.key_id >3)?0:wifi.key_id; +#if 0 //implemented in wifi_connect() + //hex to ascii conversion + if(wifi.security_type == RTW_SECURITY_WEP_PSK) + { + if(wifi.password_len == 10) + { + u32 p[5]; + u8 pwd[6], i = 0; + sscanf((const char*)wifi.password, "%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4]); + for(i=0; i< 5; i++) + pwd[i] = (u8)p[i]; + pwd[5] = '\0'; + memset(wifi.password, 0, 65); + strcpy((char*)wifi.password, (char*)pwd); + wifi.password_len = 5; + }else if(wifi.password_len == 26){ + u32 p[13]; + u8 pwd[14], i = 0; + sscanf((const char*)wifi.password, "%02x%02x%02x%02x%02x%02x%02x"\ + "%02x%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4],\ + &p[5], &p[6], &p[7], &p[8], &p[9], &p[10], &p[11], &p[12]); + for(i=0; i< 13; i++) + pwd[i] = (u8)p[i]; + pwd[13] = '\0'; + memset(wifi.password, 0, 65); + strcpy((char*)wifi.password, (char*)pwd); + wifi.password_len = 13; + } + } +#endif + } + pscan_config = PSCAN_ENABLE; + if(connect_channel > 0 && connect_channel < 14) + wifi_set_pscan_chan(&connect_channel, &pscan_config, 1); +#endif + + if(assoc_by_bssid){ + printf("\n\rJoining BSS by BSSID "MAC_FMT" ...\n\r", MAC_ARG(wifi.bssid.octet)); + } else { + printf("\n\rJoining BSS by SSID %s...\n\r", (char*)wifi.ssid.val); + } + ret = wifi_connect(wifi.bssid.octet, + assoc_by_bssid, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + + if(ret!= RTW_SUCCESS){ + if(ret == RTW_INVALID_KEY) + printf("\n\rERROR:Invalid Key "); + + printf("\n\rERROR: Can't connect to AP"); + goto EXIT; + } + tick2 = xTaskGetTickCount(); + printf("\r\nConnected after %dms.\n", (tick2-tick1)); +#if CONFIG_LWIP_LAYER + /* Start DHCPClient */ + LwIP_DHCP(0, DHCP_START); + tick3 = xTaskGetTickCount(); + printf("\r\n\nGot IP after %dms.\n", (tick3-tick1)); +#endif + printf("\n\r"); +EXIT: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWC", ret); +#endif + + init_wifi_struct( ); +} + +#if SCAN_WITH_SSID +void fATWs(void *arg){ + char buf[32] = {0}; + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + int scan_buf_len = 500; + int num_channel = 0; + int i, argc = 0; + char *argv[MAX_ARGC] = {0}; + printf("[ATWs]: _AT_WLAN_SCAN_WITH_SSID_ [%s]\n\r", (char*)wifi.ssid.val); + if(arg){ + strcpy(buf, arg); + argc = parse_param(buf, argv); + if(argc == 2){ + scan_buf_len = atoi(argv[1]); + if(scan_buf_len < 36){ + printf("[ATWs] BUFFER_LENGTH too short\n\r"); + goto exit; + } + }else if(argc > 2){ + num_channel = atoi(argv[1]); + channel_list = (u8*)malloc(num_channel); + if(!channel_list){ + printf("[ATWs]ERROR: Can't malloc memory for channel list\n\r"); + goto exit; + } + pscan_config = (u8*)malloc(num_channel); + if(!pscan_config){ + printf("[ATWs]ERROR: Can't malloc memory for pscan_config\n\r"); + goto exit; + } + //parse command channel list + for(i = 2; i <= argc -1 ; i++){ + *(channel_list + i - 2) = (u8)atoi(argv[i]); + *(pscan_config + i - 2) = PSCAN_ENABLE; + } + + if(wifi_set_pscan_chan(channel_list, pscan_config, num_channel) < 0){ + printf("[ATWs]ERROR: wifi set partial scan channel fail\n\r"); + goto exit; + } + } + }else{ + printf("[ATWs]For Scan all channel Usage: ATWs=BUFFER_LENGTH\n\r"); + printf("[ATWs]For Scan partial channel Usage: ATWs=num_channels[channel_num1, ...]\n\r"); + goto exit; + } + + if(wifi_scan_networks_with_ssid(NULL, NULL, scan_buf_len, (char*)wifi.ssid.val, wifi.ssid.len) != RTW_SUCCESS){ + printf("[ATWs]ERROR: wifi scan failed\n\r"); + } +exit: + init_wifi_struct( ); + if(arg && channel_list) + free(channel_list); + if(arg && pscan_config) + free(pscan_config); +} +#endif + +void fATWR(void *arg){ + int rssi = 0; + printf("[ATWR]: _AT_WLAN_GET_RSSI_\n\r"); + wifi_get_rssi(&rssi); + printf("\n\rwifi_get_rssi: rssi = %d", rssi); + printf("\n\r"); +} + +void fATWP(void *arg){ + unsigned int parm = atoi((const char *)(arg)); + printf("[ATWP]: _AT_WLAN_POWER_[%s]\n\r", parm?"ON":"OFF"); + if(parm == 1){ + if(wifi_on(RTW_MODE_STA)<0){ + printf("\n\rERROR: Wifi on failed!\n"); + } + } + else if(parm == 0) + { +#if CONFIG_WEBSERVER + stop_web_server(); +#endif + wifi_off(); + } + else + printf("[ATWP]Usage: ATWP=0/1\n\r"); +} + +#if CONFIG_WOWLAN_SERVICE +//for wowlan setting +void fATWV(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWV]: _AT_WLAN_WOWLAN_\r\n"); + + argc = parse_param(arg, argv); + + cmd_wowlan_service(argc, argv); + + return; +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +void fATWB(void *arg) +{ + int timeout = 20;//, mode; + int ret = RTW_SUCCESS; +#if CONFIG_LWIP_LAYER + struct netif * pnetiff = (struct netif *)&xnetif[1]; +#endif + printf("[ATWB](_AT_WLAN_AP_STA_ACTIVATE_)\n\r"); + if(ap.ssid.val[0] == 0){ + printf("[ATWB]Error: SSID can't be empty\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(ap.channel > 14){ + printf("[ATWB]Error:bad channel! channel is from 1 to 14\n\r"); + ret = RTW_BADARG; + goto exit; + } + if(ap.password == NULL){ + ap.security_type = RTW_SECURITY_OPEN; + } + else{ + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid));; + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password));; + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + + wifi_off(); + vTaskDelay(20); + if ((ret = wifi_on(RTW_MODE_STA_AP)) < 0){ + printf("\n\rERROR: Wifi on failed!"); + ret = RTW_ERROR; + goto exit; + } + + printf("\n\rStarting AP ..."); + if((ret = wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password, /*ap.ssid.len, ap.password_len,*/ ap.channel, 0)) < 0) { + printf("\n\rERROR: Operation failed!"); + goto exit; + } + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN1_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + printf("\n\r%s started\n", ap.ssid.val); + ret = RTW_SUCCESS; + break; + } + } + + if(timeout == 0) { + printf("\n\rERROR: Start AP timeout!"); + ret = RTW_TIMEOUT; + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +#if CONFIG_LWIP_LAYER + LwIP_UseStaticIP(&xnetif[1]); +#ifdef CONFIG_DONT_CARE_TP + pnetiff->flags |= NETIF_FLAG_IPSWITCH; +#endif + dhcps_init(pnetiff); +#endif + +#if defined( CONFIG_ENABLE_AP_POLLING_CLIENT_ALIVE )&&( CONFIG_ENABLE_AP_POLLING_CLIENT_ALIVE == 1 ) + wifi_set_ap_polling_sta(1); +#endif +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWB", ret); +#endif + init_wifi_struct(); +} +#endif + +#ifdef CONFIG_PROMISC +void fATWM(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + argv[0] = "wifi_promisc"; + printf("[ATWM]: _AT_WLAN_PROMISC_\n\r"); + if(!arg){ + printf("[ATWM]Usage: ATWM=DURATION_SECONDS[with_len]"); +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWM", RTW_BADARG, NULL, 0); +#endif + return; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_promisc(argc, argv); + } +} +#endif + +#if CONFIG_WEBSERVER +void fATWE(void *arg){ + printf("[ATWE]: _AT_WLAN_START_WEB_SERVER_\n\r"); + start_web_server(); +} +#endif + +void fATWW(void *arg){ +#if CONFIG_ENABLE_WPS + int argc = 0; + char *argv[4]; + printf("[ATWW]: _AT_WLAN_WPS_\n\r"); + if(!arg){ + printf("[ATWW]Usage: ATWW=pbc/pin\n\r"); +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWW", RTW_BADARG, NULL, 0); +#endif + return; + } + argv[argc++] = "wifi_wps"; + argv[argc++] = arg; + cmd_wps(argc, argv); +#else + printf("Please set CONFIG_ENABLE_WPS 1 in platform_opts.h to enable ATWW command\n"); +#endif +} +void fATWw(void *arg){ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + int argc = 0; + char *argv[4]; + printf("[ATWw]: _AT_WLAN_AP_WPS_\n\r"); + if(!arg){ + printf("[ATWw]Usage: ATWw=pbc/pin\n\r"); + return; + } + argv[argc++] = "wifi_ap_wps"; + argv[argc++] = arg; + cmd_ap_wps(argc, argv); +#endif +} + +#if CONFIG_ENABLE_P2P +void fATWG(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWG]: _AT_WLAN_P2P_START_\n\r"); + argv[argc++] = "p2p_start"; + cmd_wifi_p2p_start(argc, argv); +} + +void fATWg(void *arg){ + int argc = 0; + char *argv[4]; + int ret =0; + printf("[ATWg]: _AT_WLAN_P2P_AUTO_GO_START_\n\r"); + argv[argc++] = "p2p_auto_go_start"; + ret = cmd_wifi_p2p_auto_go_start(argc, argv); + if(ret < 0) + printf("\r\n[ATWG]: Nothing to do. Please enter ATWG to initialize P2P.\n\r"); +} + +void fATWH(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWH]: _AT_WLAN_P2P_STOP_\n\r"); + argv[argc++] = "p2p_stop"; + cmd_wifi_p2p_stop(argc, argv); +} +void fATWJ(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWJ]: _AT_WLAN_P2P_CONNECT_\n\r"); + argv[0] = "p2p_connect"; + if(!arg){ + printf("ATWc=[DEST_MAC,pbc/pin]\n\r"); + return; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_p2p_connect(argc, argv); + } +} +void fATWK(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWK]: _AT_WLAN_P2P_DISCONNECT_\n\r"); + argv[argc++] = "p2p_disconnect"; + cmd_p2p_disconnect(argc, argv); +} +void fATWN(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWN]: _AT_WLAN_P2P_INFO_\n\r"); + argv[argc++] = "p2p_info"; + cmd_p2p_info(argc, argv); +} +void fATWF(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWF]: _AT_WLAN_P2P_FIND_\n\r"); + argv[argc++] = "p2p_find"; + cmd_p2p_find(argc, argv); +} +#endif +#if CONFIG_OTA_UPDATE +void fATWO(void *arg){ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + printf("[ATWO]: _AT_WLAN_OTA_UPDATE_\n\r"); + if(!arg){ + printf("[ATWO]Usage: ATWO=IP[PORT] or ATWO= REPOSITORY[FILE_PATH]\n\r"); + return; + } + argv[0] = "update"; + if((argc = parse_param(arg, argv)) != 3){ + printf("[ATWO]Usage: ATWO=IP[PORT] or ATWO= REPOSITORY[FILE_PATH]\n\r"); + return; + } + cmd_update(argc, argv); +} +#endif + +#if CONFIG_AIRKISS +void fATWX(void *arg) +{ + int ret = RTW_SUCCESS; + + ret = airkiss_start(NULL); +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWX", RTW_ERROR, NULL, 0); +#endif +} +#endif + +void fATWZ(void *arg){ + char buf[32] = {0}; + char *copy = buf; + int i = 0; + int len = 0; + int ret = RTW_SUCCESS; + + printf("[ATWZ]: _AT_WLAN_IWPRIV_\n\r"); + if(!arg){ + printf("[ATWZ]Usage: ATWZ=COMMAND[PARAMETERS]\n\r"); + ret = RTW_BADARG; + goto exit; + } + strcpy(copy, arg); + len = strlen(copy); + do{ + if((*(copy+i)=='[')) + *(copy+i)=' '; + if((*(copy+i)==']')||(*(copy+i)=='\0')){ + *(copy+i)='\0'; + break; + } + }while((i++) < len); + + i = 0; + do{ + if((*(copy+i)==',')) { + *(copy+i)=' '; + break; + } + }while((i++) < len); + +#if CONFIG_INIC_CMD_RSP + ret = wext_private_command_with_retval(WLAN0_NAME, copy, buf, 32); + printf("\n\rPrivate Message: %s", (char *) buf); + if(ret == RTW_SUCCESS) + inic_c2h_msg("ATWZ", ret, buf, strlen(buf)); +#else + wext_private_command(WLAN0_NAME, copy, 1); +#endif +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWZ", ret, NULL, 0); +#endif + return; // exit label cannot be last statement +} + +#ifdef CONFIG_POWER_SAVING +void fATXP(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + int ret = 0; + int mode, dtim; + int tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3; +#if CONFIG_INIC_CMD_RSP + char *res = NULL; + int res_len = 0; +#endif + + printf("[ATXP]: _AT_WLAN_POWER_MODE_\r\n"); + + if (!arg) { + printf("[ATXP] Usage: ATXP=lps/ips/dtim/tdma[mode]\r\n"); + ret = RTW_BADARG; + goto exit; + } else { + argc = parse_param(arg, argv); + if (argc < 3) { + printf("[ATXP] Usage: ATXP=lps/ips/dtim/tdma[mode]\r\n"); + ret = RTW_BADARG; + goto exit; + } + } + + if (strcmp(argv[1], "lps") == 0) { + mode = atoi(argv[2]); + if (mode >= 0 && mode < 0xFF) { + printf("lps mode:%d\r\n", mode); + wifi_set_power_mode(0xff, mode); + } + } + + if (strcmp(argv[1], "ips") == 0) { + mode = atoi(argv[2]); + if (mode >= 0 && mode < 0xFF) { + printf("ips mode:%d\r\n", mode); + wifi_set_power_mode(mode, 0xFF); + } + } + + if (strcmp(argv[1], "tdma") == 0) { + if (argc >= 6) { + tdma_slot_period = atoi(argv[2]); + tdma_rfon_period_len_1 = atoi(argv[3]); + tdma_rfon_period_len_2 = atoi(argv[4]); + tdma_rfon_period_len_3 = atoi(argv[5]); + printf("tdma param: %d %d %d %d\r\n", tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3); + wifi_set_tdma_param(tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3); + } + } + + if (strcmp(argv[1], "dtim") == 0) { + dtim = atoi(argv[2]); + printf("dtim: %d\r\n", dtim); + wifi_set_lps_dtim(dtim); + } + + if (strcmp(argv[1], "get") == 0) { +#if CONFIG_INIC_CMD_RSP + char buf[32]; + int index = 0; + memset(buf, 0, sizeof(buf)); + snprintf(buf, 32, "%s,%s,", argv[1], argv[2]); + index = strlen(buf); +#endif + if(strcmp(argv[2], "dtim") == 0){ + wifi_get_lps_dtim((unsigned char *)&dtim); + printf("get dtim: %d\r\n", (unsigned char)dtim); +#if CONFIG_INIC_CMD_RSP + sprintf(buf+index, "0x%02x", (unsigned char)dtim); + res = (char *)buf; + res_len = strlen(buf); +#endif + } + } + +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATXP", ret, res, res_len); + res = NULL; + res_len = 0; +#endif + return; +} +#endif + +void print_wlan_help(void *arg){ + printf("\n\rWLAN AT COMMAND SET:"); + printf("\n\r=============================="); + printf("\n\r1. Wlan Scan for Network Access Point"); + printf("\n\r # ATWS"); + printf("\n\r2. Connect to an AES AP"); + printf("\n\r # ATW0=SSID"); + printf("\n\r # ATW1=PASSPHRASE"); + printf("\n\r # ATWC"); + printf("\n\r3. Create an AES AP"); + printf("\n\r # ATW3=SSID"); + printf("\n\r # ATW4=PASSPHRASE"); + printf("\n\r # ATW5=CHANNEL"); + printf("\n\r # ATWA"); + printf("\n\r4. Ping"); + printf("\n\r # ATWI=xxx.xxx.xxx.xxx"); +} + +#if WIFI_LOGO_CERTIFICATION_CONFIG +void fATPE(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + unsigned int ip_addr = 0; + //unsigned char sta_ip[4] = {192,168,3,80}, sta_netmask[4] = {255,255,255,0}, sta_gw[4] = {192,168,3,1}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPE] Usage : ATPE=(,,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc > 4) || (argc < 2) ){ + //at_printf("\r\n[ATPE] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + ip_addr = inet_addr(argv[1]); + sta_ip[0] = (unsigned char) ip_addr & 0xff; + sta_ip[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_ip[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_ip[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + //at_printf("\r\n[ATPE] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + if(argv[2] != NULL){ + ip_addr = inet_addr(argv[2]); + sta_gw[0] = (unsigned char) ip_addr & 0xff; + sta_gw[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_gw[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_gw[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_gw[0] = sta_ip[0]; + sta_gw[1] = sta_ip[1]; + sta_gw[2] = sta_ip[2]; + sta_gw[3] = 1; + } + + if(argv[3] != NULL){ + ip_addr = inet_addr(argv[3]); + sta_netmask[0] = (unsigned char) ip_addr & 0xff; + sta_netmask[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_netmask[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_netmask[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_netmask[0] = 255; + sta_netmask[1] = 255; + sta_netmask[2] = 255; + sta_netmask[3] = 0; + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPE] OK"); + else + at_printf("\r\n[ATPE] ERROR:%d",error_no); + + return; + +} +#endif + +#elif ATCMD_VER == ATVER_2 // UART module at command + +//ATPA=,,,[,] +void fATPA(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + +#if CONFIG_LWIP_LAYER + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif; +#endif + int timeout = 20; + unsigned char hidden_ssid = 0; + rtw_mode_t wifi_mode_copy; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPA] Usage: ATPA=,,,[,]"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc < 5){ + //at_printf("\r\n[ATPA] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if( (wifi_mode!=RTW_MODE_AP) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPA] ERROR : wifi mode error"); + error_no = 5; + goto exit; + } + wifi_mode_copy = wifi_mode; + + //SSID + if(argv[1] != NULL){ + ap.ssid.len = strlen((char*)argv[1]); + if(ap.ssid.len > 32){ + //at_printf("\r\n[ATPA] ERROR : SSID length can't exceed 32"); + error_no = 2; + goto exit; + } + strcpy((char *)ap.ssid.val, (char*)argv[1]); + } + else{ + //at_printf("\r\n[ATPA] ERROR : SSID can't be empty"); + error_no = 2; + goto exit; + } + + //PASSWORD + if(argv[2] != NULL){ + if( (strlen(argv[2]) < 8) || (strlen(argv[2]) > 64)){ + //at_printf("\r\n[ATPA] ERROR : PASSWORD length error"); + error_no = 2; + goto exit; + } + strcpy((char *)password, (char*)argv[2]); + ap.password = password; + ap.password_len = strlen((char*)argv[2]); + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + else{ + ap.security_type = RTW_SECURITY_OPEN; + } + + //CHANNEL + if(argv[3] != NULL){ + ap.channel = (unsigned char) atoi((const char *)argv[3]); + if( (ap.channel < 0) || (ap.channel > 11) ){ + //at_printf("\r\n[ATPA] ERROR : channel number error"); + error_no = 2; + goto exit; + } + } + + //HIDDEN SSID + if(argv[4] != NULL){ + if( (atoi(argv[4]) != 0) && (atoi(argv[4]) != 1)){ + //at_printf("\r\n[ATPA] ERROR : HIDDEN SSID must be 0 or 1"); + error_no = 2; + goto exit; + } + hidden_ssid = (unsigned char) atoi((const char *)argv[4]); + } + + //MAX NUMBER OF STATION + if(argv[5] != NULL){ + unsigned char max_sta = atoi(argv[5]); + if(wext_set_sta_num(max_sta) != 0){ + error_no = 2; + goto exit; + } + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid)); + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password)); + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + + wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, atcmd_wifi_disconn_hdl); + + wifi_off(); + vTaskDelay(20); + + if (wifi_on(wifi_mode_copy) < 0){ + //at_printf("\r\n[ATPA] ERROR : Wifi on failed"); + error_no = 3; + goto exit; + } + + if(wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password, ap.channel, hidden_ssid) < 0) { + //at_printf("\r\n[ATPA] ERROR : Start AP failed"); + error_no = 4; + goto exit; + } + + while(1) { + char essid[33]; + if(wifi_mode_copy == RTW_MODE_AP ){ + if(wext_get_ssid( WLAN0_NAME , (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + break; + } + } + } + else if(wifi_mode_copy == RTW_MODE_STA_AP ){ + if(wext_get_ssid( WLAN1_NAME , (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + break; + } + } + } + + if(timeout == 0) { + //at_printf("\r\n[ATPA] ERROR : Start AP timeout"); + error_no = 4; + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +#if CONFIG_LWIP_LAYER + if(wifi_mode == RTW_MODE_STA_AP) + pnetif = &xnetif[1]; + else + pnetif = &xnetif[0]; + + LwIP_UseStaticIP(pnetif); + + if(dhcp_mode_ap == 1) + dhcps_init(pnetif); +#endif + +exit: + init_wifi_struct(); + + if(error_no == 0) + at_printf("\r\n[ATPA] OK"); + else + at_printf("\r\n[ATPA] ERROR:%d",error_no); + + return; +} + +/*find ap with "ssid" from scan list*/ +static int _find_ap_from_scan_buf(char*buf, int buflen, char *target_ssid, void *user_data) +{ + rtw_wifi_setting_t *pwifi = (rtw_wifi_setting_t *)user_data; + int plen = 0; + + while(plen < buflen){ + u8 len, ssid_len, security_mode; + char *ssid; + + // len offset = 0 + len = (int)*(buf + plen); + // check end + if(len == 0) break; + // ssid offset = 14 + ssid_len = len - 14; + ssid = buf + plen + 14 ; + if((ssid_len == strlen(target_ssid)) + && (!memcmp(ssid, target_ssid, ssid_len))) + { + strcpy((char*)pwifi->ssid, target_ssid); + // channel offset = 13 + pwifi->channel = *(buf + plen + 13); + // security_mode offset = 11 + security_mode = (u8)*(buf + plen + 11); + if(security_mode == IW_ENCODE_ALG_NONE) + pwifi->security_type = RTW_SECURITY_OPEN; + else if(security_mode == IW_ENCODE_ALG_WEP) + pwifi->security_type = RTW_SECURITY_WEP_PSK; + else if(security_mode == IW_ENCODE_ALG_CCMP) + pwifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + } + plen += len; + } + return 0; +} + +/*get ap security mode from scan list*/ +static int _get_ap_security_mode(IN char * ssid, OUT rtw_security_t *security_mode, OUT u8 * channel) +{ + rtw_wifi_setting_t wifi; + u32 scan_buflen = 1000; + + memset(&wifi, 0, sizeof(wifi)); + + if(wifi_scan_networks_with_ssid(_find_ap_from_scan_buf, (void*)&wifi, scan_buflen, ssid, strlen(ssid)) != RTW_SUCCESS){ + printf("Wifi scan failed!\n"); + return 0; + } + + if(strcmp(wifi.ssid, ssid) == 0){ + *security_mode = wifi.security_type; + *channel = wifi.channel; + return 1; + } + + return 0; +} + +//ATPN=,[,,] +static void atcmd_wifi_disconn_hdl( char* buf, int buf_len, int flags, void* userdata) +{ + #if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); + #endif + at_printf("\r\n[ATWD] OK"); + at_printf(STR_END_OF_ATCMD_RET); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif +} +void fATPN(void *arg) +{ + int argc, error_no = 0; + int i,j; + char *argv[MAX_ARGC] = {0}; + + int mode, ret; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + char empty_bssid[6] = {0}, assoc_by_bssid = 0; + u8 connect_channel; + u8 pscan_config; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPN] Usage : ATPN=,[,,]"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc < 2) || (argc > 5) ){ + //at_printf("\r\n[ATPN] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if( (wifi_mode!=RTW_MODE_STA) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPN] ERROR : wifi mode error"); + error_no = 5; + goto exit; + } + + //SSID + if(argv[1] != NULL){ + strcpy((char *)wifi.ssid.val, (char*)argv[1]); + wifi.ssid.len = strlen((char*)argv[1]); + }else{ + //at_printf("\r\n[ATPN] ERROR : SSID can't be Empty"); + error_no = 2; + goto exit; + } + wifi.security_type = RTW_SECURITY_OPEN; + + //PASSWORD + if(argv[2] != NULL){ + int pwd_len = strlen(argv[2]); + if(pwd_len > 64 || (pwd_len < 8 && pwd_len != 5)){ + //at_printf("\r\n[ATPN] ERROR : PASSWORD format error"); + error_no = 2; + goto exit; + } + strcpy((char *)password, (char*)argv[2]); + wifi.password = password; + wifi.password_len = strlen((char*)argv[2]); + wifi.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + + //KEYID + if(argv[3] != NULL){ + if((strlen((const char *)argv[3]) != 1 ) || (*(char*)argv[3] <'0' ||*(char*)argv[3] >'3')) { + //at_printf("\r\n[ATPN] ERROR : Wrong WEP key id. Must be one of 0,1,2, or 3"); + error_no = 2; + goto exit; + } + wifi.key_id = atoi((const char *)(argv[3])); + wifi.security_type = RTW_SECURITY_WEP_PSK; + } + + //BSSID + if(argv[4] != NULL){ + if(strlen(argv[4]) != 12){ + //at_printf("\r\n[ATPN] ERROR : BSSID format error"); + error_no = 2; + goto exit; + } + for (i=0, j=0; i= 3){ + printf("Can't get AP security mode and channel.\n"); + error_no = 6; + goto exit; + } + } + if(wifi.security_type == RTW_SECURITY_WEP_PSK || wifi.security_type == RTW_SECURITY_WEP_SHARED) + wifi.key_id = (wifi.key_id <0 || wifi.key_id >3)?0:wifi.key_id; + } + pscan_config = PSCAN_ENABLE; + if(connect_channel > 0 && connect_channel < 14) + wifi_set_pscan_chan(&connect_channel, &pscan_config, 1); +#endif + + wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, atcmd_wifi_disconn_hdl); + + ret = wifi_connect( + wifi.bssid.octet, + assoc_by_bssid, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + + if(ret!= RTW_SUCCESS){ + //at_printf("\r\n[ATPN] ERROR: Can't connect to AP"); + error_no = 4; + goto exit; + } + +#if CONFIG_LWIP_LAYER + if (dhcp_mode_sta == 2){ + struct netif * pnetif = &xnetif[0]; + LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); + } + else{ + ret = LwIP_DHCP(0, DHCP_START); + if(ret != DHCP_ADDRESS_ASSIGNED) + error_no = 7; + } +#endif + + +exit: + init_wifi_struct(); + if(error_no == 0){ + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, atcmd_wifi_disconn_hdl, NULL); + at_printf("\r\n[ATPN] OK"); + } + else + at_printf("\r\n[ATPN] ERROR:%d",error_no); + + return; +} + +//ATPH=, +void fATPH(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + int mode,enable; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPH] Usage : ATPH=,"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 3){ + //at_printf("\r\n[ATPH] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + mode = atoi((const char *)(argv[1])); + if(mode != 1 && mode != 2){ + //at_printf("\r\n[ATPH] ERROR : parameter must be 1 or 2"); + error_no = 2; + goto exit; + } + } + + if(argv[2] != NULL){ + enable = atoi((const char *)(argv[2])); + if(enable != 1 && enable != 2){ + //at_printf("\r\n[ATPH] ERROR : parameter must be 1 or 2"); + error_no = 2; + goto exit; + } + if(mode == 1) + dhcp_mode_ap = enable; + else if(mode == 2) + dhcp_mode_sta = enable; + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPH] OK"); + else + at_printf("\r\n[ATPH] ERROR:%d",error_no); + + return; + +} + +//ATPE=(,,) +void fATPE(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + unsigned int ip_addr = 0; + //unsigned char sta_ip[4] = {192,168,3,80}, sta_netmask[4] = {255,255,255,0}, sta_gw[4] = {192,168,3,1}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPE] Usage : ATPE=(,,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc > 4) || (argc < 2) ){ + //at_printf("\r\n[ATPE] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + ip_addr = inet_addr(argv[1]); + sta_ip[0] = (unsigned char) ip_addr & 0xff; + sta_ip[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_ip[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_ip[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + //at_printf("\r\n[ATPE] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + if(argv[2] != NULL){ + ip_addr = inet_addr(argv[2]); + sta_gw[0] = (unsigned char) ip_addr & 0xff; + sta_gw[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_gw[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_gw[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_gw[0] = sta_ip[0]; + sta_gw[1] = sta_ip[1]; + sta_gw[2] = sta_ip[2]; + sta_gw[3] = 1; + } + + if(argv[3] != NULL){ + ip_addr = inet_addr(argv[3]); + sta_netmask[0] = (unsigned char) ip_addr & 0xff; + sta_netmask[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_netmask[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_netmask[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_netmask[0] = 255; + sta_netmask[1] = 255; + sta_netmask[2] = 255; + sta_netmask[3] = 0; + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPE] OK"); + else + at_printf("\r\n[ATPE] ERROR:%d",error_no); + + return; + +} + +//ATPF=,, +void fATPF(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + unsigned int ip_addr = 0; + struct ip_addr start_ip, end_ip; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPF] Usage : ATPF=,,(,,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc != 4) ){ + //at_printf("\r\n[ATPF] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + start_ip.addr = inet_addr(argv[1]); + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + if(argv[2] != NULL){ + end_ip.addr = inet_addr(argv[2]); + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + dhcps_set_addr_pool(1,&start_ip,&end_ip); + + if(argv[3] != NULL){ + ip_addr = inet_addr(argv[3]); + ap_ip[0] = (unsigned char) ip_addr & 0xff; + ap_ip[1] = (unsigned char) (ip_addr >> 8) & 0xff; + ap_ip[2] = (unsigned char) (ip_addr >> 16) & 0xff; + ap_ip[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + ap_gw[0] = ap_ip[0]; + ap_gw[1] = ap_ip[1]; + ap_gw[2] = ap_ip[2]; + ap_gw[3] = ap_ip[3]; + + ap_netmask[0] = 255; + ap_netmask[1] = 255; + ap_netmask[2] = 255; + ap_netmask[3] = 0; + +exit: + if(error_no==0) + at_printf("\r\n[ATPF] OK"); + else + at_printf("\r\n[ATPF] ERROR:%d",error_no); + + return; +} + +int atcmd_wifi_read_info_from_flash(u8 *read_data, u32 read_len) +{ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, read_data, read_len); + return 0; +} + +void atcmd_wifi_write_info_to_flash(rtw_wifi_setting_t *setting, int enable) +{ + struct atcmd_wifi_conf *data_to_flash; + rtw_wifi_setting_t *old_setting; + + flash_t flash; + u32 channel = 0, i, write_needed = 0; + u8 index = 0; + u32 data; + + data_to_flash = (struct atcmd_wifi_conf *)malloc(sizeof(struct atcmd_wifi_conf)); + + if(data_to_flash) { + if(enable){ + memset((u8 *)data_to_flash, 0, sizeof(struct atcmd_wifi_conf)); + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + old_setting = &(data_to_flash->setting); + if(memcmp((u8 *)old_setting, setting, sizeof(rtw_wifi_setting_t))){ + memcpy(old_setting, setting, sizeof(rtw_wifi_setting_t)); + write_needed = 1; + } + if(setting->mode == RTW_MODE_STA || setting->mode == RTW_MODE_STA_AP){ + struct wlan_fast_reconnect reconn; + int found = 0; + /*clean wifi ssid,key and bssid*/ + memset((u8 *)&reconn, 0, sizeof(struct wlan_fast_reconnect)); + + channel = setting->channel; + + memset(psk_essid[index], 0, sizeof(psk_essid[index])); + strncpy(psk_essid[index], setting->ssid, strlen(setting->ssid)); + switch(setting->security_type){ + case RTW_SECURITY_OPEN: + memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + reconn.security_type = RTW_SECURITY_OPEN; + break; + case RTW_SECURITY_WEP_PSK: + channel |= (setting->key_idx) << 28; + memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + memcpy(psk_passphrase[index], setting->password, sizeof(psk_passphrase[index])); + reconn.security_type = RTW_SECURITY_WEP_PSK; + break; + case RTW_SECURITY_WPA_TKIP_PSK: + reconn.security_type = RTW_SECURITY_WPA_TKIP_PSK; + break; + case RTW_SECURITY_WPA2_AES_PSK: + reconn.security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + default: + break; + } + + memcpy(reconn.psk_essid, psk_essid[index], sizeof(reconn.psk_essid)); + if (strlen(psk_passphrase64) == 64) { + memcpy(reconn.psk_passphrase, psk_passphrase64, sizeof(reconn.psk_passphrase)); + } else { + memcpy(reconn.psk_passphrase, psk_passphrase[index], sizeof(reconn.psk_passphrase)); + } + memcpy(reconn.wpa_global_PSK, wpa_global_PSK[index], sizeof(reconn.wpa_global_PSK)); + memcpy(&(reconn.channel), &channel, 4); + + if(data_to_flash->reconn_num < 0 || data_to_flash->reconn_num > ATCMD_WIFI_CONN_STORE_MAX_NUM || + data_to_flash->reconn_last_index < 0 || data_to_flash->reconn_last_index > ATCMD_WIFI_CONN_STORE_MAX_NUM + ){ + data_to_flash->reconn_num = 0; + data_to_flash->reconn_last_index = -1; + } + + reconn.enable = enable; + for(i = 0; i < data_to_flash->reconn_num; i++){ + if(memcmp((u8 *)&reconn, (u8 *)&(data_to_flash->reconn[i]), sizeof(struct wlan_fast_reconnect)) == 0) { + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ALWAYS, + "the same profile found in flash"); + found = 1; + break; + } + } + if(!found){ + data_to_flash->reconn_last_index++; + if(data_to_flash->reconn_last_index >= ATCMD_WIFI_CONN_STORE_MAX_NUM) + data_to_flash->reconn_last_index -= ATCMD_WIFI_CONN_STORE_MAX_NUM; + memcpy((u8 *)&data_to_flash->reconn[data_to_flash->reconn_last_index], (u8 *)&reconn, sizeof(struct wlan_fast_reconnect)); + data_to_flash->reconn_num++; + if(data_to_flash->reconn_num > ATCMD_WIFI_CONN_STORE_MAX_NUM) + data_to_flash->reconn_num = ATCMD_WIFI_CONN_STORE_MAX_NUM; + write_needed = 1; + } + } + if(write_needed || data_to_flash->auto_enable != enable){ + data_to_flash->auto_enable = enable; + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_WRITE, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + } + }else{ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_ERASE, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + } + } + if(data_to_flash) { + free(data_to_flash); + } +} + +int atcmd_wifi_restore_from_flash(void) +{ + flash_t flash; + struct atcmd_wifi_conf *data; + rtw_wifi_setting_t *setting; + struct wlan_fast_reconnect *reconn; + uint32_t channel; + uint32_t security_type; + uint8_t pscan_config; + char key_id[2] = {0}; + int ret = -1, i; + int mode; + rtw_network_info_t wifi = { + {0}, // ssid + {0}, // bssid + 0, // security + NULL, // password + 0, // password len + -1 // key id + }; + + data = (struct atcmd_wifi_conf *)rtw_zmalloc(sizeof(struct atcmd_wifi_conf)); + if(data){ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, (u8 *)data, sizeof(struct atcmd_wifi_conf)); + if(data->auto_enable != 1) + goto exit; + setting = &data->setting; + if(setting->mode == RTW_MODE_AP || setting->mode == RTW_MODE_STA_AP){ + //start AP here + goto exit; + } + + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("\n\rERROR: Wifi on failed!"); + ret = -1; + goto exit; + } + } + +#if CONFIG_AUTO_RECONNECT + //setup reconnection flag + wifi_set_autoreconnect(0); +#endif + int last_index = data->reconn_last_index; + for(i = 0; i < data->reconn_num; i++){ + reconn = &data->reconn[last_index]; + last_index ++; + if(last_index >= ATCMD_WIFI_CONN_STORE_MAX_NUM) + last_index -= ATCMD_WIFI_CONN_STORE_MAX_NUM; + if(reconn->enable != 1){ + continue; + } + memcpy(psk_essid, reconn->psk_essid, sizeof(reconn->psk_essid)); + memcpy(psk_passphrase, reconn->psk_passphrase, sizeof(reconn->psk_passphrase)); + memcpy(wpa_global_PSK, reconn->wpa_global_PSK, sizeof(reconn->wpa_global_PSK)); + channel = reconn->channel; + sprintf(key_id,"%d",(char) (channel>>28)); + channel &= 0xff; + security_type = reconn->security_type; + pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY; + //set partial scan for entering to listen beacon quickly + wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1); + + wifi.security_type = security_type; + //SSID + strcpy((char *)wifi.ssid.val, (char*)psk_essid); + wifi.ssid.len = strlen((char*)psk_essid); + + switch(security_type){ + case RTW_SECURITY_WEP_PSK: + wifi.password = (unsigned char*) psk_passphrase; + wifi.password_len = strlen((char*)psk_passphrase); + wifi.key_id = atoi((const char *)key_id); + break; + case RTW_SECURITY_WPA_TKIP_PSK: + case RTW_SECURITY_WPA2_AES_PSK: + wifi.password = (unsigned char*) psk_passphrase; + wifi.password_len = strlen((char*)psk_passphrase); + break; + default: + break; + } + ret = wifi_connect( + NULL, + 0, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + if(ret == RTW_SUCCESS){ + LwIP_DHCP(0, DHCP_START); + ret = 0; + break; + } + } + } + +exit: + if(ret == 0) + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, atcmd_wifi_disconn_hdl, NULL); + if(data) + rtw_mfree((u8 *)data, sizeof(struct wlan_fast_reconnect)); + return ret; +} + +//ATPG= +void fATPG(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; +// flash_t flash; +// struct wlan_fast_reconnect read_data = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPG] Usage : ATPG="); + error_no = 1; + goto exit; + } + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPG] ERROR : command format error"); + error_no = 1; + goto exit; + } + + //ENABLE FAST CONNECT + if(argv[1] != NULL){ +#if 0 + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data); + read_data.enable = atoi((const char *)(argv[1])); + if(read_data.enable != 0 && read_data.enable != 1){ + //at_printf("\r\n[ATPG] ERROR : parameter must be 0 or 1"); + error_no = 2; + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto exit; + } + flash_erase_sector(&flash, FAST_RECONNECT_DATA); + flash_stream_write(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#else + rtw_wifi_setting_t setting; + int enable = atoi((const char *)(argv[1])); + if(enable != 0 && enable != 1){ + error_no = 2; + goto exit; + } + if(enable == 1){ + u8 *ifname[1] = {WLAN0_NAME}; + if(wifi_get_setting((const char*)ifname[0],&setting)){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "wifi_get_setting fail"); + error_no = 3; + goto exit; + } + } + atcmd_wifi_write_info_to_flash(&setting, enable); +#endif + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPG] OK"); + else + at_printf("\r\n[ATPG] ERROR:%d",error_no); + + return; +} + +//ATPM= +void fATPM(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPM] Usage : ATPM="); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPM] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + if(strlen(argv[1]) != 12){ + //at_printf("\r\n[ATPM] ERROR : BSSID format error"); + error_no = 2; + goto exit; + } + wifi_set_mac_address(argv[1]); + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPM] OK"); + else + at_printf("\r\n[ATPM] ERROR:%d",error_no); + + return; + +} + +//ATPW= +void fATPW(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPW] Usage : ATPW="); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPW] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + wifi_mode = atoi((const char *)(argv[1])); + if((wifi_mode!=RTW_MODE_STA) && (wifi_mode!=RTW_MODE_AP) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPW] ERROR : parameter must be 1 , 2 or 3"); + error_no = 2; + } + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPW] OK"); + else + at_printf("\r\n[ATPW] ERROR:%d",error_no); + + return; +} + +void print_wlan_help(void *arg){ + at_printf("\r\nWLAN AT COMMAND SET:"); + at_printf("\r\n=============================="); + at_printf("\r\n1. Wlan Scan for Network Access Point"); + at_printf("\r\n # ATWS"); + at_printf("\r\n2. Connect to an AES AP"); + at_printf("\r\n # ATPN=,,(,)"); + at_printf("\r\n3. Create an AES AP"); + at_printf("\r\n # ATPA=,,,"); +} + +#endif // end of #if ATCMD_VER == ATVER_1 + +#endif // end of #if CONFIG_WLAN + +#if CONFIG_LWIP_LAYER +#if ATCMD_VER == ATVER_1 +void fATWL(void *arg){ +#if CONFIG_SSL_CLIENT + int argc; + char *argv[MAX_ARGC] = {0}; + printf("[ATWL]: _AT_WLAN_SSL_CLIENT_\n\r"); + argv[0] = "ssl_client"; + if(!arg){ + printf("ATWL=SSL_SERVER_HOST\n\r"); + return; + } + if((argc = parse_param(arg, argv)) > 1){ + if(argc != 2) { + printf("ATWL=SSL_SERVER_HOST\n\r"); + return; + } + + cmd_ssl_client(argc, argv); + } +#else + printf("Please set CONFIG_SSL_CLIENT 1 in platform_opts.h to enable ATWL command\n"); +#endif +} + +void fATWI(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWI]: _AT_WLAN_PING_TEST_\n\r"); + + if(!arg){ + printf("\n\r[ATWI] Usage: ATWI=[host],[options]\n"); + printf("\n\r -t Ping the specified host until stopped\n"); + printf(" \r -n # Number of echo requests to send (default 4 times)\n"); + printf(" \r -l # Send buffer size (default 32 bytes)\n"); + printf("\n\r Example:\n"); + printf(" \r ATWI=192.168.1.2,-n,100,-l,5000\n"); + return; + } + + argv[0] = "ping"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_ping(argc, argv); + } +} + +void fATWT(void *arg) +{ +#if CONFIG_BSD_TCP + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWT]: _AT_WLAN_TCP_TEST_\n\r"); + + if(!arg){ + printf("\n\r[ATWT] Usage: ATWT=[-s|-c,host|stop],[options]\n"); + printf("\n\r Client/Server:\n"); + printf(" \r stop terminate client & server\n"); + printf(" \r -i # seconds between periodic bandwidth reports\n"); + printf(" \r -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" \r -p # server port to listen on/connect to (default 5001)\n"); + printf("\n\r Server specific:\n"); + printf(" \r -s run in server mode\n"); + printf("\n\r Client specific:\n"); + printf(" \r -c run in client mode, connecting to \n"); + printf(" \r -d do a bidirectional test simultaneously\n"); + printf(" \r -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" \r -n #[KM] number of bytes to transmit (instead of -t)\n"); + printf("\n\r Example:\n"); + printf(" \r ATWT=-s,-p,5002\n"); + printf(" \r ATWT=-c,192.168.1.2,-t,100,-p,5002\n"); + return; + } + + argv[0] = "tcp"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_tcp(argc, argv); + } +#else + printf("Please set CONFIG_BSD_TCP 1 in platform_opts.h to enable ATWT command\n"); +#endif +} + +void fATWU(void *arg) +{ +#if CONFIG_BSD_TCP + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWU]: _AT_WLAN_UDP_TEST_\n\r"); + + if(!arg){ + printf("\n\r[ATWU] Usage: ATWU=[-s|-c,host|stop][options]\n"); + printf("\n\r Client/Server:\n"); + printf(" \r stop terminate client & server\n"); + printf(" \r -i # seconds between periodic bandwidth reports\n"); + printf(" \r -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" \r -p # server port to listen on/connect to (default 5001)\n"); + printf("\n\r Server specific:\n"); + printf(" \r -s run in server mode\n"); + printf("\n\r Client specific:\n"); + printf(" \r -b #[KM] for UDP, bandwidth to send at in bits/sec (default 1 Mbit/sec)\n"); + printf(" \r -c run in client mode, connecting to \n"); + printf(" \r -d do a bidirectional test simultaneously\n"); + printf(" \r -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" \r -n #[KM] number of bytes to transmit (instead of -t)\n"); + printf(" \r -S # set the IP 'type of service'\n"); + printf("\n\r Example:\n"); + printf(" \r ATWU=-s,-p,5002\n"); + printf(" \r ATWU=-c,192.168.1.2,-t,100,-p,5002\n"); + return; + } + + argv[0] = "udp"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_udp(argc, argv); + } +#else + printf("Please set CONFIG_BSD_TCP 1 in platform_opts.h to enable ATWU command\n"); +#endif +} +#elif ATCMD_VER == ATVER_2 // uart at command +//move to atcmd_lwip.c +#endif +#endif +log_item_t at_wifi_items[ ] = { +#if ATCMD_VER == ATVER_1 +#if CONFIG_LWIP_LAYER + {"ATWL", fATWL,}, + {"ATWI", fATWI,}, + {"ATWT", fATWT,}, + {"ATWU", fATWU,}, +#endif +#if WIFI_LOGO_CERTIFICATION_CONFIG + {"ATPE", fATPE,}, // set static IP for STA +#endif +#if CONFIG_WLAN + {"ATW0", fATW0,}, + {"ATW1", fATW1,}, + {"ATW2", fATW2,}, + {"ATW3", fATW3,}, + {"ATW4", fATW4,}, + {"ATW5", fATW5,}, + {"ATW6", fATW6,}, + {"ATWA", fATWA,}, +#ifdef CONFIG_CONCURRENT_MODE + {"ATWB", fATWB,}, +#endif + {"ATWC", fATWC,}, + {"ATWD", fATWD,}, + {"ATWP", fATWP,}, +#if CONFIG_WOWLAN_SERVICE + {"ATWV", fATWV,}, +#endif + {"ATWR", fATWR,}, + {"ATWS", fATWS,}, +#if SCAN_WITH_SSID + {"ATWs", fATWs,}, +#endif +#ifdef CONFIG_PROMISC + {"ATWM", fATWM,}, +#endif + {"ATWZ", fATWZ,}, +#if CONFIG_OTA_UPDATE + {"ATWO", fATWO,}, +#endif +#if CONFIG_WEBSERVER + {"ATWE", fATWE,}, +#endif +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + {"ATWQ", fATWQ,}, +#endif +#ifdef CONFIG_WPS + {"ATWW", fATWW,}, + {"ATWw", fATWw,}, //wps registrar for softap +#if CONFIG_ENABLE_P2P + {"ATWG", fATWG,}, //p2p start + {"ATWH", fATWH,}, //p2p stop + {"ATWJ", fATWJ,}, //p2p connect + {"ATWK", fATWK,}, //p2p disconnect + {"ATWN", fATWN,}, //p2p info + {"ATWF", fATWF,}, //p2p find + {"ATWg", fATWg,}, //p2p auto go start +#endif +#endif + +#if CONFIG_AIRKISS + {"ATWX", fATWX,}, +#endif + {"ATW?", fATWx,}, + {"ATW+ABC", fATWx,}, +#ifdef CONFIG_POWER_SAVING + {"ATXP", fATXP,}, +#endif +#endif +#elif ATCMD_VER == ATVER_2 // uart at command +#if CONFIG_WLAN + {"ATPA", fATPA,}, // set AP + {"ATPN", fATPN,}, // connect to Network + {"ATPH", fATPH,}, // set DHCP mode + {"ATPE", fATPE,}, // set static IP for STA + {"ATPF", fATPF,}, // set DHCP rule for AP + {"ATPG", fATPG,}, // set auto connect + {"ATPM", fATPM,}, // set MAC address + {"ATPW", fATPW,}, // set Wifi mode + {"ATWD", fATWD,}, // WiFi Disconnect + {"ATWS", fATWS,}, // WiFi scan + {"ATW?", fATWx,}, // Wlan Info +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + {"ATWQ", fATWQ,}, // WiFi simple config +#endif // #if (CONFIG_INCLUDE_SIMPLE_CONFIG) +#endif // #if CONFIG_WLAN +#endif // end of #if ATCMD_VER == ATVER_1 +}; + +#if ATCMD_VER == ATVER_2 +void print_wifi_at(void *arg){ + int index; + int cmd_len = 0; + + cmd_len = sizeof(at_wifi_items)/sizeof(at_wifi_items[0]); + for(index = 0; index < cmd_len; index++) + at_printf("\r\n%s", at_wifi_items[index].log_cmd); +} +#endif + +void at_wifi_init(void) +{ +#if CONFIG_WLAN + init_wifi_struct(); +#endif + log_service_add_table(at_wifi_items, sizeof(at_wifi_items)/sizeof(at_wifi_items[0])); +} + +#if SUPPORT_LOG_SERVICE +log_module_init(at_wifi_init); +#endif diff --git a/USDK/component/common/api/at_cmd/atcmd_wifi.h b/USDK/component/common/api/at_cmd/atcmd_wifi.h new file mode 100644 index 0000000..d56ad52 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_wifi.h @@ -0,0 +1,166 @@ +#ifndef __ATCMD_WIFI_H__ +#define __ATCMD_WIFI_H__ +#include +#include "main.h" +#include "lwip_netconf.h" +#ifdef USE_FLASH_EEP +#include "flash_eep.h" +#include "feep_config.h" +#endif + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif +/* Give default value if not defined */ +#ifndef NET_IF_NUM + #ifdef CONFIG_CONCURRENT_MODE + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1) + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN)) + #endif // end of CONFIG_CONCURRENT_MODE +#endif // end of NET_IF_NUM + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 3 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 3 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD +#include "wifi_structures.h" +#include +typedef struct _UART_LOG_CONF_{ + u32 BaudRate; + u8 DataBits; + u8 StopBits; + u8 Parity; + u8 FlowControl; +}UART_LOG_CONF, *PUART_LOG_CONF; + +#define ATCMD_WIFI_CONN_STORE_MAX_NUM (1) +struct atcmd_wifi_conf{ + int32_t auto_enable; + rtw_wifi_setting_t setting; + int32_t reconn_num; + int32_t reconn_last_index; + struct wlan_fast_reconnect reconn[ATCMD_WIFI_CONN_STORE_MAX_NUM]; +}; + +#define ATCMD_LWIP_CONN_STORE_MAX_NUM (1) +struct atcmd_lwip_conn_info{ + int32_t role; //client, server or seed + uint32_t protocol; //tcp or udp + uint32_t remote_addr; //remote ip + uint32_t remote_port; //remote port + uint32_t local_addr; //locale ip, not used yet + uint32_t local_port; //locale port, not used yet + uint32_t reserved; //reserve for further use +}; +struct atcmd_lwip_conf { + int32_t enable; //enable or not + int32_t conn_num; + int32_t last_index; + int32_t reserved; //reserve for further use + struct atcmd_lwip_conn_info conn[ATCMD_LWIP_CONN_STORE_MAX_NUM]; +}; + +typedef enum { + AT_PARTITION_ALL = 0, + AT_PARTITION_UART = 1, + AT_PARTITION_WIFI = 2, + AT_PARTITION_LWIP = 3 +} AT_PARTITION; + +typedef enum { + AT_PARTITION_READ = 0, + AT_PARTITION_WRITE = 1, + AT_PARTITION_ERASE = 2 +} AT_PARTITION_OP; + +//first segment for uart +#define UART_SETTING_BACKUP_SECTOR (0x8000) +#define UART_CONF_DATA_OFFSET (0) +#define UART_CONF_DATA_SIZE ((((sizeof(UART_LOG_CONF)-1)>>2) + 1)<<2) + +//second segment for wifi config +#define WIFI_CONF_DATA_OFFSET (UART_CONF_DATA_OFFSET+UART_CONF_DATA_SIZE) +#define WIFI_CONF_DATA_SIZE ((((sizeof(struct atcmd_wifi_conf)-1)>>2) + 1)<<2) + +//fouth segment for lwip config +#define LWIP_CONF_DATA_OFFSET (WIFI_CONF_DATA_OFFSET+WIFI_CONF_DATA_SIZE) +#define LWIP_CONF_DATA_SIZE ((((sizeof(struct atcmd_lwip_conf)-1)>>2) + 1)<<2) + +extern void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len); + +#define ATSTRING_LEN (LOG_SERVICE_BUFLEN) +extern char at_string[ATSTRING_LEN]; + +extern unsigned char gAT_Echo; // default echo on +//extern void uart_at_lock(void); +//extern void uart_at_unlock(void); +extern void uart_at_send_string(char *str); +extern void uart_at_send_buf(u8 *buf, u32 len); + +#define at_printf(fmt, args...) do{\ + /*uart_at_lock();*/\ + snprintf(at_string, ATSTRING_LEN, fmt, ##args); \ + uart_at_send_string(at_string);\ + /*uart_at_unlock();*/\ + }while(0) +#define at_print_data(data, size) do{\ + /*uart_at_lock();*/\ + uart_at_send_buf(data, size);\ + /*uart_at_unlock();*/\ + }while(0) + +#else +#define at_printf(fmt, args...) do{printf(fmt, ##args);}while(0) +#define at_print_data(data, size) do{__rtl_memDump(data, size, NULL);}while(0) +#endif//#if CONFIG_EXAMPLE_UART_ATCMD + +#endif diff --git a/USDK/component/common/api/at_cmd/atcmd_wifi1.c b/USDK/component/common/api/at_cmd/atcmd_wifi1.c new file mode 100644 index 0000000..46dbc5b --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_wifi1.c @@ -0,0 +1,2873 @@ +#include +#ifdef CONFIG_AT_WIFI + +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "log_service.h" +#include "atcmd_wifi.h" +#include +#include "tcpip.h" +#include +#include "osdep_service.h" + +#if CONFIG_WLAN +#include +#include +#include + +extern rtw_mode_t wifi_mode; // = RTW_MODE_STA; + +#endif + +/* Give default value if not defined */ +#ifndef NET_IF_NUM + #ifdef CONFIG_CONCURRENT_MODE + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1) + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN)) + #endif // end of CONFIG_CONCURRENT_MODE +#endif // end of NET_IF_NUM + +#ifndef ATCMD_VER +#define ATVER_1 1 +#define ATVER_2 2 +#define ATCMD_VER ATVER_2 +#if CONFIG_EXAMPLE_UART_ATCMD +#define ATCMD_VER ATVER_2 +#else +#define ATCMD_VER ATVER_1 +#endif +#endif + + +#if ATCMD_VER == ATVER_2 +#include "flash_api.h" +#ifdef USE_FLASH_EEP +#include "flash_eep.h" +#endif +#include "device_lock.h" +#include +#include +#endif + +/******************************************************************************/ +#define _AT_WLAN_SET_SSID_ "ATW0" +#define _AT_WLAN_SET_PASSPHRASE_ "ATW1" +#define _AT_WLAN_SET_KEY_ID_ "ATW2" +#define _AT_WLAN_AP_SET_SSID_ "ATW3" +#define _AT_WLAN_AP_SET_SEC_KEY_ "ATW4" +#define _AT_WLAN_AP_SET_CHANNEL_ "ATW5" +#define _AT_WLAN_SET_BSSID_ "ATW6" +#define _AT_WLAN_AP_ACTIVATE_ "ATWA" +#define _AT_WLAN_AP_STA_ACTIVATE_ "ATWB" +#define _AT_WLAN_JOIN_NET_ "ATWC" +#define _AT_WLAN_DISC_NET_ "ATWD" +#define _AT_WLAN_WEB_SERVER_ "ATWE" +#define _AT_WLAN_P2P_FIND_ "ATWF" +#define _AT_WLAN_P2P_START_ "ATWG" +#define _AT_WLAN_P2P_STOP_ "ATWH" +#define _AT_WLAN_PING_TEST_ "ATWI" +#define _AT_WLAN_P2P_CONNECT_ "ATWJ" +#define _AT_WLAN_P2P_DISCONNECT_ "ATWK" +#define _AT_WLAN_SSL_CLIENT_ "ATWL" +#define _AT_WLAN_PROMISC_ "ATWM" +#define _AT_WLAN_P2P_INFO_ "ATWN" +#define _AT_WLAN_OTA_UPDATE_ "ATWO" +#define _AT_WLAN_POWER_ "ATWP" +#define _AT_WLAN_SIMPLE_CONFIG_ "ATWQ" +#define _AT_WLAN_GET_RSSI_ "ATWR" +#define _AT_WLAN_SCAN_ "ATWS" +#define _AT_WLAN_SCAN_WITH_SSID_ "ATWs" +#define _AT_WLAN_TCP_TEST_ "ATWT" +#define _AT_WLAN_UDP_TEST_ "ATWU" +#define _AT_WLAN_WPS_ "ATWW" +#define _AT_WLAN_AP_WPS_ "ATWw" +#define _AT_WLAN_AIRKISS_ "ATWX" +#define _AT_WLAN_IWPRIV_ "ATWZ" +#define _AT_WLAN_INFO_ "ATW?" + +#define _AT_WLAN_EXTEND_POWER_MODE_ "ATXP" + +#ifndef CONFIG_SSL_CLIENT +#define CONFIG_SSL_CLIENT 0 +#endif +#ifndef CONFIG_WEBSERVER +#define CONFIG_WEBSERVER 0 +#endif +#ifndef CONFIG_OTA_UPDATE +#define CONFIG_OTA_UPDATE 0 +#endif +#ifndef CONFIG_BSD_TCP +#define CONFIG_BSD_TCP 1 +#endif +#ifndef CONFIG_ENABLE_P2P +#define CONFIG_ENABLE_P2P 0 +#endif +#define SCAN_WITH_SSID 0 +#if CONFIG_WEBSERVER +#define CONFIG_READ_FLASH 1 +extern rtw_wifi_setting_t wifi_setting; +#endif + +#ifndef CONFIG_WOWLAN_SERVICE +#define CONFIG_WOWLAN_SERVICE 0 +#endif + +#if CONFIG_LWIP_LAYER +extern void cmd_tcp(int argc, char **argv); +extern void cmd_udp(int argc, char **argv); +extern void cmd_ping(int argc, char **argv); +extern void cmd_ssl_client(int argc, char **argv); +#endif + +#if CONFIG_WLAN +extern void cmd_promisc(int argc, char **argv); +extern void cmd_update(int argc, char **argv); +extern void cmd_simple_config(int argc, char **argv); +#if CONFIG_ENABLE_WPS +extern void cmd_wps(int argc, char **argv); +#endif + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +extern void cmd_ap_wps(int argc, char **argv); +extern int wpas_wps_dev_config(u8 *dev_addr, u8 bregistrar); +#endif +#if CONFIG_ENABLE_P2P +extern void cmd_wifi_p2p_start(int argc, char **argv); +extern void cmd_wifi_p2p_stop(int argc, char **argv); +extern void cmd_p2p_listen(int argc, char **argv); +extern void cmd_p2p_find(int argc, char **argv); +extern void cmd_p2p_peers(int argc, char **argv); +extern void cmd_p2p_info(int argc, char **argv); +extern void cmd_p2p_disconnect(int argc, char **argv); +extern void cmd_p2p_connect(int argc, char **argv); +extern int cmd_wifi_p2p_auto_go_start(int argc, char **argv); +#endif //CONFIG_ENABLE_P2P +#if CONFIG_AIRKISS +extern int airkiss_start(); +#endif +#if CONFIG_LWIP_LAYER +extern struct netif xnetif[NET_IF_NUM]; +#endif +#if CONFIG_WOWLAN_SERVICE +extern void cmd_wowlan_service(int argc, char **argv); +#endif +#if CONFIG_INIC_CMD_RSP +extern void inic_c2h_wifi_info(const char *atcmd, char status); +extern void inic_c2h_msg(const char *atcmd, u8 status, char *msg, u16 msg_len); +#endif + +/* fastconnect use wifi AT command. Not init_wifi_struct when log service disabled + * static initialize all values for using fastconnect when log service disabled + */ +static rtw_network_info_t wifi = { + {0}, // ssid + {0}, // bssid + 0, // security + NULL, // password + 0, // password len + -1 // key id +}; + +static rtw_ap_info_t ap = {0}; +static unsigned char password[65] = {0}; + +#if ATCMD_VER == ATVER_2 +unsigned char dhcp_mode_sta = 1, dhcp_mode_ap = 1; +unsigned char sta_ip[4] = {192,168,3,80}, sta_netmask[4] = {255,255,255,0}, sta_gw[4] = {192,168,3,1}; +unsigned char ap_ip[4] = {192,168,43,1}, ap_netmask[4] = {255,255,255,0}, ap_gw[4] = {192,168,43,1}; +#endif + + +static void init_wifi_struct(void) +{ + memset(wifi.ssid.val, 0, sizeof(wifi.ssid.val)); + memset(wifi.bssid.octet, 0, ETH_ALEN); + memset(password, 0, sizeof(password)); + wifi.ssid.len = 0; + wifi.password = NULL; + wifi.password_len = 0; + wifi.key_id = -1; + memset(ap.ssid.val, 0, sizeof(ap.ssid.val)); + ap.ssid.len = 0; + ap.password = NULL; + ap.password_len = 0; + ap.channel = 1; +} + +static void print_scan_result( rtw_scan_result_t* record ) +{ +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("%s,%d,%s,%d,"MAC_FMT"", record->SSID.val, record->channel, + ( record->security == RTW_SECURITY_OPEN ) ? "Open" : + ( record->security == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( record->security == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( record->security == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( record->security == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( record->security == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( record->security == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + ( record->security == RTW_SECURITY_WPA_WPA2_MIXED ) ? "WPA/WPA2 AES" : "Unknown", + record->signal_strength, MAC_ARG(record->BSSID.octet) ); +#else + RTW_API_INFO( ( "%s\t ", ( record->bss_type == RTW_BSS_TYPE_ADHOC ) ? "Adhoc" : "Infra" ) ); + RTW_API_INFO( ( MAC_FMT, MAC_ARG(record->BSSID.octet) ) ); + RTW_API_INFO( ( " %d\t ", record->signal_strength ) ); + RTW_API_INFO( ( " %d\t ", record->channel ) ); + RTW_API_INFO( ( " %d\t ", record->wps_type ) ); + RTW_API_INFO( ( "%s\t\t ", ( record->security == RTW_SECURITY_OPEN ) ? "Open" : + ( record->security == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( record->security == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( record->security == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( record->security == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( record->security == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( record->security == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + ( record->security == RTW_SECURITY_WPA_WPA2_MIXED ) ? "WPA/WPA2 AES" : + "Unknown" ) ); + + RTW_API_INFO( ( " %s ", record->SSID.val ) ); + RTW_API_INFO( ( "\r\n" ) ); +#endif +} + +static rtw_result_t app_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) +{ + static int ApNum = 0; + + if (malloced_scan_result->scan_complete != RTW_TRUE) { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("\r\nAP : %d,", ++ApNum); +#else + RTW_API_INFO( ( "%d\t ", ++ApNum ) ); +#endif + print_scan_result(record); +#if CONFIG_INIC_CMD_RSP + if(malloced_scan_result->user_data) + memcpy((void *)((char *)malloced_scan_result->user_data+(ApNum-1)*sizeof(rtw_scan_result_t)), (char *)record, sizeof(rtw_scan_result_t)); +#endif + } else{ +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWS", RTW_SUCCESS, (char *)malloced_scan_result->user_data, ApNum*sizeof(rtw_scan_result_t)); + if(malloced_scan_result->user_data) + free(malloced_scan_result->user_data); + inic_c2h_msg("ATWS", RTW_SUCCESS, NULL, 0); +#endif +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("\r\n[ATWS] OK"); + at_printf(STR_END_OF_ATCMD_RET); +#endif + ApNum = 0; + } + return RTW_SUCCESS; +} + +// WIFI disconnect +void fATWD(void *arg){ + int timeout = 10000/200; + char essid[33]; + int ret = RTW_SUCCESS; +#if ATCMD_VER == ATVER_2 + int error_no = 0; +#endif + + printf("[ATWD]: _AT_WLAN_DISC_NET_\n"); + printf("Deassociating AP ...\n"); + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("WIFI disconnected\n"); + goto exit_success; + } + + if((ret = wifi_disconnect()) < 0) { + printf("ERROR: Operation failed!\n"); +#if ATCMD_VER == ATVER_2 + error_no = 3; +#endif + goto exit; + } + + while(1) { + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("WIFI disconnected\n"); + break; + } + + if(timeout == 0) { + printf("ERROR: Deassoc timeout!\n"); + ret = RTW_TIMEOUT; +#if ATCMD_VER == ATVER_2 + error_no = 4; +#endif + break; + } +// vTaskDelay(1 * configTICK_RATE_HZ); + vTaskDelay(200/portTICK_RATE_MS); + timeout --; + } + printf("\n"); +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWD", ret, NULL, 0); +#endif + init_wifi_struct( ); +#if ATCMD_VER == ATVER_2 + if(error_no==0) + at_printf("\r\n[ATWD] OK"); + else + at_printf("\r\n[ATWD] ERROR:%d",error_no); +#endif + return; +exit_success: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWD", RTW_SUCCESS, NULL, 0); +#endif + init_wifi_struct( ); +#if ATCMD_VER == ATVER_2 + at_printf("\r\n[ATWD] OK"); +#endif + return; +} + +// wifi simpleconfig +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) +void fATWQ(void *arg){ + int argc=0; + char *argv[2] = {0}; + printf("[ATWQ]: _AT_WLAN_SIMPLE_CONFIG_\n"); + argv[argc++] = "wifi_simple_config"; + if(arg){ + argv[argc++] = arg; + } + cmd_simple_config(argc, argv); +} +#endif + +// WIFI scan +void fATWS(void *arg){ + char buf[32] = {0}; + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + int num_channel = 0; + int i, argc = 0; + char *argv[MAX_ARGC] = {0}; + int ret = RTW_SUCCESS; +#if CONFIG_INIC_CMD_RSP + u8 *inic_scan_buf = NULL; +#endif +#if ATCMD_VER == ATVER_2 + int error_no = 0; +#endif + printf("[ATWS]: _AT_WLAN_SCAN_\n"); + if(arg){ + strcpy(buf, arg); + argc = parse_param(buf, argv); + if(argc < 2){ + ret = RTW_BADARG; +#if ATCMD_VER == ATVER_2 + error_no = 1; +#endif + goto exit; + } + num_channel = atoi(argv[1]); + channel_list = (u8*)malloc(num_channel); + if(!channel_list){ + printf("[ATWS]ERROR: Can't malloc memory for channel list\n"); + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#if ATCMD_VER == ATVER_2 + error_no = 2; +#endif + goto exit; + } + pscan_config = (u8*)malloc(num_channel); + if(!pscan_config){ + printf("[ATWS]ERROR: Can't malloc memory for pscan_config\n"); + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#if ATCMD_VER == ATVER_2 + error_no = 3; +#endif + goto exit; + } + //parse command channel list + for(i = 2; i <= argc -1 ; i++){ + *(channel_list + i - 2) = (u8)atoi(argv[i]); + *(pscan_config + i - 2) = PSCAN_ENABLE; + } + + if((ret = wifi_set_pscan_chan(channel_list, pscan_config, num_channel)) < 0){ + printf("[ATWS]ERROR: wifi set partial scan channel fail\n"); +#if ATCMD_VER == ATVER_2 + error_no = 4; +#endif + goto exit; + } + } +#if CONFIG_INIC_CMD_RSP + inic_scan_buf = malloc(65*sizeof(rtw_scan_result_t)); + if(inic_scan_buf == NULL){ + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; + goto exit; + } + memset(inic_scan_buf, 0, 65*sizeof(rtw_scan_result_t)); + if((ret = wifi_scan_networks(app_scan_result_handler, inic_scan_buf)) != RTW_SUCCESS){ + printf("[ATWS]ERROR: wifi scan failed\n"); + goto exit; + } +#else + if((ret = wifi_scan_networks(app_scan_result_handler, NULL )) != RTW_SUCCESS){ + printf("[ATWS]ERROR: wifi scan failed\n"); +#if ATCMD_VER == ATVER_2 + error_no = 5; +#endif + goto exit; + } +#endif +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS){ + if(inic_scan_buf) + free(inic_scan_buf); + inic_c2h_msg("ATWS", ret, NULL, 0); + } +#endif +#if ATCMD_VER == ATVER_2 + if(error_no) + at_printf("[ATWS] ERROR:%d\n",error_no); +#endif + if(arg && channel_list) + free(channel_list); + if(arg && pscan_config) + free(pscan_config); +} + +void fATWx(void *arg){ + int i = 0; +#if CONFIG_LWIP_LAYER + u8 *mac = LwIP_GetMAC(&xnetif[0]); + u8 *ip = LwIP_GetIP(&xnetif[0]); + u8 *gw = LwIP_GetGW(&xnetif[0]); +#endif + u8 *ifname[2] = {WLAN0_NAME,WLAN1_NAME}; + rtw_wifi_setting_t setting; + + printf("[ATW?]: _AT_WLAN_INFO_\n"); +#if CONFIG_INIC_CMD_RSP + int ret = RTW_SUCCESS; + int info_sz = 0; + u8 *info = malloc(NET_IF_NUM*sizeof(rtw_wifi_setting_t)+3*sizeof(rtw_mac_t)); + if(info == NULL) + ret = RTW_BUFFER_UNAVAILABLE_TEMPORARY; +#endif + for(i=0;i %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ; + printf("\tIP => %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + printf("\tGW => %d.%d.%d.%d\n", gw[0], gw[1], gw[2], gw[3]); +#endif + if(setting.mode == RTW_MODE_AP || i == 1) + { + int client_number; + struct { + int count; + rtw_mac_t mac_list[AP_STA_NUM]; + } client_info; + + client_info.count = AP_STA_NUM; + wifi_get_associated_client_list(&client_info, sizeof(client_info)); + + printf("Associated Client List:\n"); + printf("==============================\n"); + + if(client_info.count == 0) + printf("Client Num: 0\n", client_info.count); + else + { + printf("Client Num: %d\n", client_info.count); + for( client_number=0; client_number < client_info.count; client_number++ ) + { + printf("Client %d:\n", client_number + 1); + printf("\tMAC => "MAC_FMT"\n", + MAC_ARG(client_info.mac_list[client_number].octet)); +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("CLIENT:%d,"MAC_FMT"\n", client_number + 1, MAC_ARG(client_info.mac_list[client_number].octet)); +#endif +#if CONFIG_INIC_CMD_RSP + if(info){ + memcpy(info+info_sz, (void *)&client_info.mac_list[client_number], sizeof(rtw_mac_t)); + info_sz += sizeof(rtw_mac_t); + } +#endif + } + printf("\n\r"); + } + } + } +// show the ethernet interface info + else + { +#if CONFIG_ETHERNET + if(i == NET_IF_NUM - 1) + { +#if CONFIG_LWIP_LAYER + mac = LwIP_GetMAC(&xnetif[i]); + ip = LwIP_GetIP(&xnetif[i]); + gw = LwIP_GetGW(&xnetif[i]); + printf("\nInterface ethernet\n"); + printf("==============================\n"); + printf("\tMAC => %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ; + printf("\tIP => %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + printf("\tGW => %d.%d.%d.%d\n", gw[0], gw[1], gw[2], gw[3]); +#endif // end CONFIG_LWIP_LAYER + } +#endif // end CONFIG_ETHERNET + } + } + +#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) && (configUSE_STATS_FORMATTING_FUNCTIONS == 1) + { + char * pcWriteBuffer = malloc(1024); + if(pcWriteBuffer) { + vTaskList((char*)pcWriteBuffer); + printf("\nTask List:\n"); + printf("==============================\n"); + printf("Name\t Status Priority HighWaterMark TaskNumber\n%s\n", pcWriteBuffer); + free(pcWriteBuffer); + } + } +#endif + +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATW?", ret, NULL, 0); + else + inic_c2h_msg("ATW?", RTW_SUCCESS, (char *)info, info_sz); + + if(info) + free(info); + info = NULL; +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("\r\n[ATW?] OK"); +#endif + +} + +#if ATCMD_VER == ATVER_1 +void fATW0(void *arg){ + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW0]Usage: ATW0=SSID\n"); + ret = RTW_BADARG; + goto exit; + } + printf("[ATW0]: _AT_WLAN_SET_SSID_ [%s]\n", (char*)arg); + strcpy((char *)wifi.ssid.val, (char*)arg); + wifi.ssid.len = strlen((char*)arg); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW0", ret, NULL, 0); +#endif + return; +} + +void fATW1(void *arg){ + int ret = RTW_SUCCESS; + printf("[ATW1]: _AT_WLAN_SET_PASSPHRASE_ [%s]\n", (char*)arg); + strcpy((char *)password, (char*)arg); + wifi.password = password; + wifi.password_len = strlen((char*)arg); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW1", ret, NULL, 0); +#endif + return; +} + +void fATW2(void *arg){ + int ret = RTW_SUCCESS; + printf("[ATW2]: _AT_WLAN_SET_KEY_ID_ [%s]\n", (char*)arg); + if((strlen((const char *)arg) != 1 ) || (*(char*)arg <'0' ||*(char*)arg >'3')) { + printf("Wrong WEP key id. Must be one of 0,1,2, or 3.\n"); + ret = RTW_BADARG; + goto exit; + } + wifi.key_id = atoi((const char *)(arg)); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW2", ret, NULL, 0); +#endif + return; +} + +void fATW3(void *arg){ + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW3]Usage: ATW3=SSID\n"); + ret = RTW_BADARG; + goto exit; + } + + ap.ssid.len = strlen((char*)arg); + + if(ap.ssid.len > 32){ + printf("[ATW3]Error: SSID length can't exceed 32\n"); + ret = RTW_BADARG; + goto exit; + } + strcpy((char *)ap.ssid.val, (char*)arg); + + printf("[ATW3]: _AT_WLAN_AP_SET_SSID_ [%s]\n", ap.ssid.val); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW3", ret, NULL, 0); +#endif + return; +} + +void fATW4(void *arg){ + int ret = RTW_SUCCESS; + strcpy((char *)password, (char*)arg); + ap.password = password; + ap.password_len = strlen((char*)arg); + printf("[ATW4]: _AT_WLAN_AP_SET_SEC_KEY_ [%s]\n", ap.password); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW4", ret, NULL, 0); +#endif + return; +} + +void fATW5(void *arg){ + int ret = RTW_SUCCESS; + ap.channel = (unsigned char) atoi((const char *)arg); + printf("[ATW5]: _AT_WLAN_AP_SET_CHANNEL_ [channel %d]\n", ap.channel); +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW5", ret, NULL, 0); +#endif + return; +} + +void fATW6(void *arg){ + u32 mac[ETH_ALEN]; + u32 i; + int ret = RTW_SUCCESS; + if(!arg){ + printf("[ATW6]Usage: ATW6=BSSID\n"); + ret = RTW_BADARG; + goto exit; + } + printf("[ATW6]: _AT_WLAN_SET_BSSID_ [%s]\n", (char*)arg); + sscanf(arg, MAC_FMT, mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + for(i = 0; i < ETH_ALEN; i ++) + wifi.bssid.octet[i] = (u8)mac[i] & 0xFF; +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATW6", ret, NULL, 0); +#endif + return; +} + +void fATWA(void *arg){ +#if CONFIG_LWIP_LAYER + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif = &xnetif[0]; +#endif + int timeout = 10000/200; + int ret = RTW_SUCCESS; + printf("[ATWA]: _AT_WLAN_AP_ACTIVATE_\n"); + if(ap.ssid.val[0] == 0){ + printf("[ATWA]Error: SSID can't be empty\n"); + ret = RTW_BADARG; + goto exit; + } + if(ap.password == NULL){ + ap.security_type = RTW_SECURITY_OPEN; + } + else{ + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid));; + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password)); + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); + IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask,&gw); +#ifdef CONFIG_DONT_CARE_TP + pnetif->flags |= NETIF_FLAG_IPSWITCH; +#endif +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_AP) < 0){ + printf("ERROR: Wifi on failed!\n"); + ret = RTW_ERROR; + goto exit; + } + printf("Starting AP ...\n"); + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + wpas_wps_dev_config(pnetif->hwaddr, 1); +#endif + if((ret = wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password, ap.ssid.len, ap.password_len, ap.channel) )< 0) { + printf("ERROR: Operation failed!\n"); + goto exit; + } + + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + printf("%s started\n", ap.ssid.val); + ret = RTW_SUCCESS; + break; + } + } + + if(timeout == 0) { + printf("ERROR: Start AP timeout!\n"); + ret = RTW_TIMEOUT; + break; + } + //vTaskDelay(1 * configTICK_RATE_HZ); + vTaskDelay(200/portTICK_RATE_MS); + timeout --; + } +#if CONFIG_LWIP_LAYER + //LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); +#endif + +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWA", ret); +#endif + init_wifi_struct( ); +} + +#if CONFIG_INIC_EN +static int _find_ap_from_scan_buf(char*buf, int buflen, char *target_ssid, void *user_data) +{ + rtw_wifi_setting_t *pwifi = (rtw_wifi_setting_t *)user_data; + int plen = 0; + + while(plen < buflen){ + u8 len, ssid_len, security_mode; + char *ssid; + + // len offset = 0 + len = (int)*(buf + plen); + // check end + if(len == 0) break; + // ssid offset = 14 + ssid_len = len - 14; + ssid = buf + plen + 14 ; + if((ssid_len == strlen(target_ssid)) + && (!memcmp(ssid, target_ssid, ssid_len))) + { + strcpy((char*)pwifi->ssid, target_ssid); + // channel offset = 13 + pwifi->channel = *(buf + plen + 13); + // security_mode offset = 11 + security_mode = (u8)*(buf + plen + 11); + if(security_mode == IW_ENCODE_ALG_NONE) + pwifi->security_type = RTW_SECURITY_OPEN; + else if(security_mode == IW_ENCODE_ALG_WEP) + pwifi->security_type = RTW_SECURITY_WEP_PSK; + else if(security_mode == IW_ENCODE_ALG_CCMP) + pwifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + } + plen += len; + } + return 0; +} + +static int _get_ap_security_mode(IN char * ssid, OUT rtw_security_t *security_mode, OUT u8 * channel) +{ + rtw_wifi_setting_t wifi; + u32 scan_buflen = 1000; + + memset(&wifi, 0, sizeof(wifi)); + + if(wifi_scan_networks_with_ssid(_find_ap_from_scan_buf, (void*)&wifi, scan_buflen, ssid, strlen(ssid)) != RTW_SUCCESS){ + printf("Wifi scan failed!\n"); + return 0; + } + + if(strcmp(wifi.ssid, ssid) == 0){ + *security_mode = wifi.security_type; + *channel = wifi.channel; + return 1; + } + + return 0; +} +#endif + +void fATWC(void *arg){ + int mode, ret; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + char empty_bssid[6] = {0}, assoc_by_bssid = 0; + + printf("[ATWC]: _AT_WLAN_JOIN_NET_\n"); + if(memcmp (wifi.bssid.octet, empty_bssid, 6)) + assoc_by_bssid = 1; + else if(wifi.ssid.val[0] == 0){ + printf("[ATWC]Error: SSID can't be empty\n"); + ret = RTW_BADARG; + goto EXIT; + } + if(wifi.password != NULL){ + if((wifi.key_id >= 0)&&(wifi.key_id <= 3)) { + wifi.security_type = RTW_SECURITY_WEP_PSK; + } + else{ + wifi.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + } + else{ + wifi.security_type = RTW_SECURITY_OPEN; + } + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("ERROR: Wifi on failed!\n"); + ret = RTW_ERROR; + goto EXIT; + } + } + +#if CONFIG_INIC_EN //get security mode from scan list + u8 connect_channel; + u8 pscan_config; + //the keyID may be not set for WEP which may be confued with WPA2 + if((wifi.security_type == RTW_SECURITY_UNKNOWN)||(wifi.security_type == RTW_SECURITY_WPA2_AES_PSK)) + { + int security_retry_count = 0; + while (1) { + if (_get_ap_security_mode((char*)wifi.ssid.val, &wifi.security_type, &connect_channel)) + break; + security_retry_count++; + if(security_retry_count >= 3){ + printf("Can't get AP security mode and channel.\n"); + ret = RTW_NOTFOUND; + goto EXIT; + } + } + if(wifi.security_type == RTW_SECURITY_WEP_PSK || wifi.security_type == RTW_SECURITY_WEP_SHARED) + wifi.key_id = (wifi.key_id <0 || wifi.key_id >3)?0:wifi.key_id; +#if 0 //implemented in wifi_connect() + //hex to ascii conversion + if(wifi.security_type == RTW_SECURITY_WEP_PSK) + { + if(wifi.password_len == 10) + { + u32 p[5]; + u8 pwd[6], i = 0; + sscanf((const char*)wifi.password, "%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4]); + for(i=0; i< 5; i++) + pwd[i] = (u8)p[i]; + pwd[5] = '\0'; + memset(wifi.password, 0, 65); + strcpy((char*)wifi.password, (char*)pwd); + wifi.password_len = 5; + }else if(wifi.password_len == 26){ + u32 p[13]; + u8 pwd[14], i = 0; + sscanf((const char*)wifi.password, "%02x%02x%02x%02x%02x%02x%02x"\ + "%02x%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4],\ + &p[5], &p[6], &p[7], &p[8], &p[9], &p[10], &p[11], &p[12]); + for(i=0; i< 13; i++) + pwd[i] = (u8)p[i]; + pwd[13] = '\0'; + memset(wifi.password, 0, 65); + strcpy((char*)wifi.password, (char*)pwd); + wifi.password_len = 13; + } + } +#endif + } + pscan_config = PSCAN_ENABLE; + if(connect_channel > 0 && connect_channel < 14) + wifi_set_pscan_chan(&connect_channel, &pscan_config, 1); +#endif + + if(assoc_by_bssid){ + printf("Joining BSS by BSSID "MAC_FMT" ...\n", MAC_ARG(wifi.bssid.octet)); + } else { + printf("Joining BSS by SSID %s...\n", (char*)wifi.ssid.val); + } + ret = wifi_connect(wifi.bssid.octet, + assoc_by_bssid, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + + if(ret!= RTW_SUCCESS){ + printf("ERROR: Can't connect to AP\n"); + goto EXIT; + } + tick2 = xTaskGetTickCount(); + printf("Connected after %dms.\n", (tick2-tick1)); +#if CONFIG_LWIP_LAYER + /* Start DHCPClient */ + LwIP_DHCP(0, DHCP_START); + tick3 = xTaskGetTickCount(); + printf("Got IP after %dms.\n", (tick3-tick1)); +#endif +// printf("\n\r"); +EXIT: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWC", ret); +#endif + + init_wifi_struct( ); +} + +#if SCAN_WITH_SSID +void fATWs(void *arg){ + char buf[32] = {0}; + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + int scan_buf_len = 500; + int num_channel = 0; + int i, argc = 0; + char *argv[MAX_ARGC] = {0}; + printf("[ATWs]: _AT_WLAN_SCAN_WITH_SSID_ [%s]\n", (char*)wifi.ssid.val); + if(arg){ + strcpy(buf, arg); + argc = parse_param(buf, argv); + if(argc == 2){ + scan_buf_len = atoi(argv[1]); + if(scan_buf_len < 36){ + printf("[ATWs] BUFFER_LENGTH too short\n"); + goto exit; + } + }else if(argc > 2){ + num_channel = atoi(argv[1]); + channel_list = (u8*)malloc(num_channel); + if(!channel_list){ + printf("[ATWs]ERROR: Can't malloc memory for channel list\n"); + goto exit; + } + pscan_config = (u8*)malloc(num_channel); + if(!pscan_config){ + printf("[ATWs]ERROR: Can't malloc memory for pscan_config\n"); + goto exit; + } + //parse command channel list + for(i = 2; i <= argc -1 ; i++){ + *(channel_list + i - 2) = (u8)atoi(argv[i]); + *(pscan_config + i - 2) = PSCAN_ENABLE; + } + + if(wifi_set_pscan_chan(channel_list, pscan_config, num_channel) < 0){ + printf("[ATWs]ERROR: wifi set partial scan channel fail\n"); + goto exit; + } + } + }else{ + printf("[ATWs]For Scan all channel Usage: ATWs=BUFFER_LENGTH\n"); + printf("[ATWs]For Scan partial channel Usage: ATWs=num_channels[channel_num1, ...]\n"); + goto exit; + } + + if(wifi_scan_networks_with_ssid(NULL, NULL, scan_buf_len, (char*)wifi.ssid.val, wifi.ssid.len) != RTW_SUCCESS){ + printf("[ATWs]ERROR: wifi scan failed\n"); + } +exit: + init_wifi_struct( ); + if(arg && channel_list) + free(channel_list); + if(arg && pscan_config) + free(pscan_config); +} +#endif + +void fATWR(void *arg){ + int rssi = 0; + printf("[ATWR]: _AT_WLAN_GET_RSSI_\n"); + wifi_get_rssi(&rssi); + printf("wifi_get_rssi: rssi = %d\n", rssi); +// printf(""); +} + +void fATWP(void *arg){ + unsigned int parm = atoi((const char *)(arg)); + printf("[ATWP]: _AT_WLAN_POWER_[%s]\n", parm?"ON":"OFF"); + if(parm == 1){ + if(wifi_on(RTW_MODE_STA)<0){ + printf("ERROR: Wifi on failed!\n"); + } + } + else if(parm == 0) + { +#if CONFIG_WEBSERVER + stop_web_server(); +#endif + wifi_off(); + } + else + printf("[ATWP]Usage: ATWP=0/1\n"); +} + +#if CONFIG_WOWLAN_SERVICE +//for wowlan setting +void fATWV(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWV]: _AT_WLAN_WOWLAN_\n"); + + argc = parse_param(arg, argv); + + cmd_wowlan_service(argc, argv); + + return; +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +void fATWB(void *arg) +{ + int timeout = 10000/200; + int ret = RTW_SUCCESS; +#if CONFIG_LWIP_LAYER + struct netif * pnetiff = (struct netif *)&xnetif[1]; +#endif + printf("[ATWB](_AT_WLAN_AP_STA_ACTIVATE_)\n"); + if(ap.ssid.val[0] == 0){ + printf("[ATWB]Error: SSID can't be empty\n"); + ret = RTW_BADARG; + goto exit; + } + if(ap.channel > 14){ + printf("[ATWB]Error:bad channel! channel is from 1 to 14\n"); + ret = RTW_BADARG; + goto exit; + } + if(ap.password == NULL){ + ap.security_type = RTW_SECURITY_OPEN; + } + else{ + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid));; + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password));; + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + + wifi_off(); + vTaskDelay(20); + if ((ret = wifi_on(RTW_MODE_STA_AP)) < 0){ + printf("ERROR: Wifi on failed!\n"); + ret = RTW_ERROR; + goto exit; + } + + printf("Starting AP ...\n"); + if((ret = wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password, ap.ssid.len, ap.password_len, ap.channel)) < 0) { + printf("ERROR: Operation failed!\n"); + goto exit; + } + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN1_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + printf("%s started\n", ap.ssid.val); + ret = RTW_SUCCESS; + break; + } + } + + if(timeout == 0) { + printf("ERROR: Start AP timeout!\n"); + ret = RTW_TIMEOUT; + break; + } + +// vTaskDelay(1 * configTICK_RATE_HZ); + vTaskDelay(200/portTICK_RATE_MS); + timeout --; + } +#if CONFIG_LWIP_LAYER + LwIP_UseStaticIP(&xnetif[1]); +#ifdef CONFIG_DONT_CARE_TP + pnetiff->flags |= NETIF_FLAG_IPSWITCH; +#endif + dhcps_init(pnetiff); +#endif + +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWB", ret); +#endif + init_wifi_struct(); +} +#endif + +#ifdef CONFIG_PROMISC +void fATWM(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + argv[0] = "wifi_promisc"; + printf("[ATWM]: _AT_WLAN_PROMISC_\n"); + if(!arg){ + printf("[ATWM]Usage: ATWM=DURATION_SECONDS[with_len]\n"); +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWM", RTW_BADARG, NULL, 0); +#endif + return; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_promisc(argc, argv); + } +} +#endif + +#if CONFIG_WEBSERVER +void fATWE(void *arg){ + printf("[ATWE]: _AT_WLAN_START_WEB_SERVER_\n"); + start_web_server(); +} +#endif + +void fATWW(void *arg){ +#if CONFIG_ENABLE_WPS + int argc = 0; + char *argv[4]; + printf("[ATWW]: _AT_WLAN_WPS_\n"); + if(!arg){ + printf("[ATWW]Usage: ATWW=pbc/pin\n"); +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWW", RTW_BADARG, NULL, 0); +#endif + return; + } + argv[argc++] = "wifi_wps"; + argv[argc++] = arg; + cmd_wps(argc, argv); +#else + printf("Please set CONFIG_ENABLE_WPS 1 in platform_opts.h to enable ATWW command\n"); +#endif +} +void fATWw(void *arg){ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + int argc = 0; + char *argv[4]; + printf("[ATWw]: _AT_WLAN_AP_WPS_\n"); + if(!arg){ + printf("[ATWw]Usage: ATWw=pbc/pin\n"); + return; + } + argv[argc++] = "wifi_ap_wps"; + argv[argc++] = arg; + cmd_ap_wps(argc, argv); +#endif +} + +#if CONFIG_ENABLE_P2P +void fATWG(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWG]: _AT_WLAN_P2P_START_\n"); + argv[argc++] = "p2p_start"; + cmd_wifi_p2p_start(argc, argv); +} + +void fATWg(void *arg){ + int argc = 0; + char *argv[4]; + int ret =0; + printf("[ATWg]: _AT_WLAN_P2P_AUTO_GO_START_\n"); + argv[argc++] = "p2p_auto_go_start"; + ret = cmd_wifi_p2p_auto_go_start(argc, argv); + if(ret < 0) + printf("[ATWg]: Nothing to do. Please enter ATWG to initialize P2P.\n"); +} + +void fATWH(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWH]: _AT_WLAN_P2P_STOP_\n"); + argv[argc++] = "p2p_stop"; + cmd_wifi_p2p_stop(argc, argv); +} +void fATWJ(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWJ]: _AT_WLAN_P2P_CONNECT_\n"); + argv[0] = "p2p_connect"; + if(!arg){ + printf("ATWc=[DEST_MAC,pbc/pin]\n"); + return; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_p2p_connect(argc, argv); + } +} +void fATWK(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWK]: _AT_WLAN_P2P_DISCONNECT_\n"); + argv[argc++] = "p2p_disconnect"; + cmd_p2p_disconnect(argc, argv); +} +void fATWN(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWN]: _AT_WLAN_P2P_INFO_\n"); + argv[argc++] = "p2p_info"; + cmd_p2p_info(argc, argv); +} +void fATWF(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWF]: _AT_WLAN_P2P_FIND_\n"); + argv[argc++] = "p2p_find"; + cmd_p2p_find(argc, argv); +} +#endif +#if CONFIG_OTA_UPDATE +void fATWO(void *arg){ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + printf("[ATWO]: _AT_WLAN_OTA_UPDATE_\n"); + if(!arg){ + printf("[ATWO]Usage: ATWO=IP[PORT] or ATWO= REPOSITORY[FILE_PATH]\n"); + return; + } + argv[0] = "update"; + if((argc = parse_param(arg, argv)) != 3){ + printf("[ATWO]Usage: ATWO=IP[PORT] or ATWO= REPOSITORY[FILE_PATH]\n"); + return; + } + cmd_update(argc, argv); +} +#endif + +#if CONFIG_AIRKISS +void fATWX(void *arg) +{ + int ret = RTW_SUCCESS; + + rtw_network_info_t wifi; + memset(&wifi, 0 , sizeof(rtw_network_info_t)); + + ret = airkiss_start(&wifi); +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWX", RTW_ERROR, NULL, 0); +#endif +} +#endif + +void fATWZ(void *arg){ + char buf[32] = {0}; + char *copy = buf; + int i = 0; + int len = 0; + int ret = RTW_SUCCESS; + + printf("[ATWZ]: _AT_WLAN_IWPRIV_\n"); + if(!arg){ + printf("[ATWZ]Usage: ATWZ=COMMAND[PARAMETERS]\n"); + ret = RTW_BADARG; + goto exit; + } + strcpy(copy, arg); + len = strlen(copy); + do{ + if((*(copy+i)=='[')) + *(copy+i)=' '; + if((*(copy+i)==']')||(*(copy+i)=='\0')){ + *(copy+i)='\0'; + break; + } + }while((i++) < len); + + i = 0; + do{ + if((*(copy+i)==',')) { + *(copy+i)=' '; + break; + } + }while((i++) < len); + +#if CONFIG_INIC_CMD_RSP + ret = wext_private_command_with_retval(WLAN0_NAME, copy, buf, 32); + printf("Private Message: %s\n", (char *) buf); + if(ret == RTW_SUCCESS) + inic_c2h_msg("ATWZ", ret, buf, strlen(buf)); +#else + wext_private_command(WLAN0_NAME, copy, 1); +#endif +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != RTW_SUCCESS) + inic_c2h_msg("ATWZ", ret, NULL, 0); +#endif + return; // exit label cannot be last statement +} + +#ifdef CONFIG_POWER_SAVING +void fATXP(void *arg) +{ + int argc = 0; + char *argv[MAX_ARGC] = {0}; + int ret = 0; + int mode, dtim; + int tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3; +#if CONFIG_INIC_CMD_RSP + char *res = NULL; + int res_len = 0; +#endif + + printf("[ATXP]: _AT_WLAN_POWER_MODE_\n"); + + if (!arg) { + printf("[ATXP] Usage: ATXP=lps/ips/dtim/tdma[mode]\n"); + ret = RTW_BADARG; + goto exit; + } else { + argc = parse_param(arg, argv); + if (argc < 3) { + printf("[ATXP] Usage: ATXP=lps/ips/dtim/tdma[mode]\n"); + ret = RTW_BADARG; + goto exit; + } + } + + if (strcmp(argv[1], "lps") == 0) { + mode = atoi(argv[2]); + if (mode >= 0 && mode < 0xFF) { + printf("lps mode:%d\n", mode); + wifi_set_power_mode(0xff, mode); + } + } + + if (strcmp(argv[1], "ips") == 0) { + mode = atoi(argv[2]); + if (mode >= 0 && mode < 0xFF) { + printf("ips mode:%d\n", mode); + wifi_set_power_mode(mode, 0xFF); + } + } + + if (strcmp(argv[1], "tdma") == 0) { + if (argc >= 6) { + tdma_slot_period = atoi(argv[2]); + tdma_rfon_period_len_1 = atoi(argv[3]); + tdma_rfon_period_len_2 = atoi(argv[4]); + tdma_rfon_period_len_3 = atoi(argv[5]); + printf("tdma param: %d %d %d %d\n", tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3); + wifi_set_tdma_param(tdma_slot_period, tdma_rfon_period_len_1, tdma_rfon_period_len_2, tdma_rfon_period_len_3); + } + } + + if (strcmp(argv[1], "dtim") == 0) { + dtim = atoi(argv[2]); + printf("dtim: %d\n", dtim); + wifi_set_lps_dtim(dtim); + } + + if (strcmp(argv[1], "get") == 0) { +#if CONFIG_INIC_CMD_RSP + char buf[32]; + int index = 0; + memset(buf, 0, sizeof(buf)); + snprintf(buf, 32, "%s,%s,", argv[1], argv[2]); + index = strlen(buf); +#endif + if(strcmp(argv[2], "dtim") == 0){ + wifi_get_lps_dtim((unsigned char *)&dtim); + printf("get dtim: %d\n", (unsigned char)dtim); +#if CONFIG_INIC_CMD_RSP + sprintf(buf+index, "0x%02x", (unsigned char)dtim); + res = (char *)buf; + res_len = strlen(buf); +#endif + } + } + +exit: +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATXP", ret, res, res_len); + res = NULL; + res_len = 0; +#endif + return; +} +#endif + +void print_wlan_help(void *arg){ + printf("WLAN AT COMMAND SET:\n==============================\n"); + printf("1. Wlan Scan for Network Access Point\n"); + printf(" # ATWS\n"); + printf("2. Connect to an AES AP\n"); + printf(" # ATW0=SSID\n"); + printf(" # ATW1=PASSPHRASE\n"); + printf(" # ATWC\n"); + printf("3. Create an AES AP\n"); + printf(" # ATW3=SSID\n"); + printf(" # ATW4=PASSPHRASE\n"); + printf(" # ATW5=CHANNEL\n"); + printf(" # ATWA\n"); + printf("4. Ping\n"); + printf(" # ATWI=xxx.xxx.xxx.xxx\n"); +} + +#elif ATCMD_VER == ATVER_2 // UART module at command + +// wifi promisc +// Usage: ATWM=DURATION_SECONDS[with_len] +#ifdef CONFIG_PROMISC +void fATWM(void *arg){ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + argv[0] = "wifi_promisc"; + printf("[ATWM]: _AT_WLAN_PROMISC_\n"); + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "[ATWM]Usage: ATWM=DURATION_MSECONDS[with_len]\n"); +#if CONFIG_INIC_CMD_RSP + inic_c2h_msg("ATWM", RTW_BADARG, NULL, 0); +#endif + error_no = 1; + goto exit; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_promisc(argc, argv); + } +exit: + if(error_no==0) + at_printf("\r\n[ATWM] OK"); + else + at_printf("\r\n[ATWM] ERROR:%d",error_no); + return; +} +#endif + +//ATPA=,,,[,] +void fATPA(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + +#if CONFIG_LWIP_LAYER + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif; +#endif + int timeout = 10000/200; + unsigned char hidden_ssid = 0; + rtw_mode_t wifi_mode_copy; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPA] Usage: ATPA=,,,[,]"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc < 5){ + //at_printf("\r\n[ATPA] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if( (wifi_mode!=RTW_MODE_AP) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPA] ERROR : wifi mode error"); + error_no = 5; + goto exit; + } + wifi_mode_copy = wifi_mode; + + //SSID + if(argv[1] != NULL){ + ap.ssid.len = strlen((char*)argv[1]); + if(ap.ssid.len > 32){ + //at_printf("\r\n[ATPA] ERROR : SSID length can't exceed 32"); + error_no = 2; + goto exit; + } + strcpy((char *)ap.ssid.val, (char*)argv[1]); + } + else{ + //at_printf("\r\n[ATPA] ERROR : SSID can't be empty"); + error_no = 2; + goto exit; + } + + //PASSWORD + if(argv[2] != NULL){ + if( (strlen(argv[2]) < 8) || (strlen(argv[2]) > 64)){ + //at_printf("\r\n[ATPA] ERROR : PASSWORD length error"); + error_no = 2; + goto exit; + } + strcpy((char *)password, (char*)argv[2]); + ap.password = password; + ap.password_len = strlen((char*)argv[2]); + ap.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + else{ + ap.security_type = RTW_SECURITY_OPEN; + } + + //CHANNEL + if(argv[3] != NULL){ + ap.channel = (unsigned char) atoi((const char *)argv[3]); + if( (ap.channel < 0) || (ap.channel > 11) ){ + //at_printf("\r\n[ATPA] ERROR : channel number error"); + error_no = 2; + goto exit; + } + } + + //HIDDEN SSID + if(argv[4] != NULL){ + if( (atoi(argv[4]) != 0) && (atoi(argv[4]) != 1)){ + //at_printf("\r\n[ATPA] ERROR : HIDDEN SSID must be 0 or 1"); + error_no = 2; + goto exit; + } + hidden_ssid = (unsigned char) atoi((const char *)argv[4]); + } + + //MAX NUMBER OF STATION + if(argv[5] != NULL){ + unsigned char max_sta = atoi(argv[5]); + if(wext_set_sta_num(max_sta) != 0){ + error_no = 2; + goto exit; + } + } + +#if CONFIG_WEBSERVER + //store into flash + memset(wifi_setting.ssid, 0, sizeof(wifi_setting.ssid)); + memcpy(wifi_setting.ssid, ap.ssid.val, strlen((char*)ap.ssid.val)); + wifi_setting.ssid[ap.ssid.len] = '\0'; + wifi_setting.security_type = ap.security_type; + if(ap.security_type !=0) + wifi_setting.security_type = 1; + else + wifi_setting.security_type = 0; + if (ap.password) + memcpy(wifi_setting.password, ap.password, strlen((char*)ap.password)); + else + memset(wifi_setting.password, 0, sizeof(wifi_setting.password)); + wifi_setting.channel = ap.channel; +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif +#endif + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + + if (wifi_on(wifi_mode_copy) < 0){ + //at_printf("\r\n[ATPA] ERROR : Wifi on failed"); + error_no = 3; + goto exit; + } + + if(wifi_start_ap((char*)ap.ssid.val, ap.security_type, (char*)ap.password, ap.channel, hidden_ssid) < 0) { + //at_printf("\r\n[ATPA] ERROR : Start AP failed"); + error_no = 4; + goto exit; + } + + while(1) { + char essid[33]; + if(wifi_mode_copy == RTW_MODE_AP ){ + if(wext_get_ssid( WLAN0_NAME , (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + break; + } + } + } + else if(wifi_mode_copy == RTW_MODE_STA_AP ){ + if(wext_get_ssid( WLAN1_NAME , (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)ap.ssid.val) == 0) { + break; + } + } + } + + if(timeout == 0) { + //at_printf("\r\n[ATPA] ERROR : Start AP timeout"); + error_no = 4; + break; + } + vTaskDelay(200/portTICK_RATE_MS); +// vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +#if CONFIG_LWIP_LAYER + if(wifi_mode == RTW_MODE_STA_AP) + pnetif = &xnetif[1]; + else + pnetif = &xnetif[0]; + + LwIP_UseStaticIP(pnetif); + + if(dhcp_mode_ap == 1) + dhcps_init(pnetif); +#endif +exit: + init_wifi_struct(); + + if(error_no == 0) { +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + at_printf("\r\n[ATPA] OK"); + } else + at_printf("\r\n[ATPA] ERROR:%d",error_no); + + return; +} + +/*find ap with "ssid" from scan list*/ +static int _find_ap_from_scan_buf(char*buf, int buflen, char *target_ssid, void *user_data) +{ + rtw_wifi_setting_t *pwifi = (rtw_wifi_setting_t *)user_data; + int plen = 0; + + while(plen < buflen){ + u8 len, ssid_len, security_mode; + char *ssid; + + // len offset = 0 + len = (int)*(buf + plen); + // check end + if(len == 0) break; + // ssid offset = 14 + ssid_len = len - 14; + ssid = buf + plen + 14 ; + if((ssid_len == strlen(target_ssid)) + && (!memcmp(ssid, target_ssid, ssid_len))) + { + strcpy((char*)pwifi->ssid, target_ssid); + // channel offset = 13 + pwifi->channel = *(buf + plen + 13); + // security_mode offset = 11 + security_mode = (u8)*(buf + plen + 11); + if(security_mode == IW_ENCODE_ALG_NONE) + pwifi->security_type = RTW_SECURITY_OPEN; + else if(security_mode == IW_ENCODE_ALG_WEP) + pwifi->security_type = RTW_SECURITY_WEP_PSK; + else if(security_mode == IW_ENCODE_ALG_CCMP) + pwifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + } + plen += len; + } + return 0; +} + +/*get ap security mode from scan list*/ +static int _get_ap_security_mode(IN char * ssid, OUT rtw_security_t *security_mode, OUT u8 * channel) +{ + rtw_wifi_setting_t wifi; + u32 scan_buflen = 1000; + + memset(&wifi, 0, sizeof(wifi)); + + if(wifi_scan_networks_with_ssid(_find_ap_from_scan_buf, (void*)&wifi, scan_buflen, ssid, strlen(ssid)) != RTW_SUCCESS){ + printf("Wifi scan failed!\n"); + return 0; + } + + if(strcmp(wifi.ssid, ssid) == 0){ + *security_mode = wifi.security_type; + *channel = wifi.channel; + return 1; + } + + return 0; +} + +extern u8 key_2char2num(u8 hch, u8 lch); + +//ATPN=,,(,) +void fATPN(void *arg) +{ + int argc, error_no = 0; + int i,j; + char *argv[MAX_ARGC] = {0}; + + int mode, ret; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + char empty_bssid[6] = {0}, assoc_by_bssid = 0; + u8 connect_channel; + u8 pscan_config; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPN] Usage : ATPN=,,(,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc < 2) || (argc > 5) ){ + //at_printf("\r\n[ATPN] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if( (wifi_mode!=RTW_MODE_STA) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPN] ERROR : wifi mode error"); + error_no = 5; + goto exit; + } + + //SSID + if(argv[1] != NULL){ + strcpy((char *)wifi.ssid.val, (char*)argv[1]); + wifi.ssid.len = strlen((char*)argv[1]); + }else{ + //at_printf("\r\n[ATPN] ERROR : SSID can't be Empty"); + error_no = 2; + goto exit; + } + wifi.security_type = RTW_SECURITY_OPEN; + + //PASSWORD + if(argv[2] != NULL){ + int pwd_len = strlen(argv[2]); + if(pwd_len > 64 || (pwd_len < 8 && pwd_len != 5)){ + //at_printf("\r\n[ATPN] ERROR : PASSWORD format error"); + error_no = 2; + goto exit; + } + strcpy((char *)password, (char*)argv[2]); + wifi.password = password; + wifi.password_len = strlen((char*)argv[2]); + wifi.security_type = RTW_SECURITY_WPA2_AES_PSK; + } + + //KEYID + if(argv[3] != NULL){ + if((strlen((const char *)argv[3]) != 1 ) || (*(char*)argv[3] <'0' ||*(char*)argv[3] >'3')) { + //at_printf("\r\n[ATPN] ERROR : Wrong WEP key id. Must be one of 0,1,2, or 3"); + error_no = 2; + goto exit; + } + wifi.key_id = atoi((const char *)(argv[3])); + wifi.security_type = RTW_SECURITY_WEP_PSK; + } + + //BSSID + if(argv[4] != NULL){ + if(strlen(argv[4]) != 12){ + //at_printf("\r\n[ATPN] ERROR : BSSID format error"); + error_no = 2; + goto exit; + } + for (i=0, j=0; i= 3){ + printf("Can't get AP security mode and channel.\n"); + error_no = 6; + goto exit; + } + } + if(wifi.security_type == RTW_SECURITY_WEP_PSK || wifi.security_type == RTW_SECURITY_WEP_SHARED) + wifi.key_id = (wifi.key_id <0 || wifi.key_id >3)?0:wifi.key_id; + } + pscan_config = PSCAN_ENABLE; + if(connect_channel > 0 && connect_channel < 14) + wifi_set_pscan_chan(&connect_channel, &pscan_config, 1); +#endif + + ret = wifi_connect( + wifi.bssid.octet, + assoc_by_bssid, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + + if(ret!= RTW_SUCCESS){ + //at_printf("\r\n[ATPN] ERROR: Can't connect to AP"); + error_no = 4; + goto exit; + } + +#if CONFIG_LWIP_LAYER + if (dhcp_mode_sta == 2){ + struct netif * pnetif = &xnetif[0]; + LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); + } + else{ + ret = LwIP_DHCP(0, DHCP_START); + if(ret != DHCP_ADDRESS_ASSIGNED) + error_no = 7; + } +#endif +exit: + init_wifi_struct(); + if(error_no == 0) { +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + at_printf("\r\n[ATPN] OK"); + } else + at_printf("\r\n[ATPN] ERROR:%d",error_no); + + return; +} + +//ATPH=, +void fATPH(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + int mode,enable; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPH] Usage : ATPH=,"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 3){ + //at_printf("\r\n[ATPH] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + mode = atoi((const char *)(argv[1])); + if(mode != 1 && mode != 2){ + //at_printf("\r\n[ATPH] ERROR : parameter must be 1 or 2"); + error_no = 2; + goto exit; + } + } + + if(argv[2] != NULL){ + enable = atoi((const char *)(argv[2])); + if(enable != 1 && enable != 2){ + //at_printf("\r\n[ATPH] ERROR : parameter must be 1 or 2"); + error_no = 2; + goto exit; + } + if(mode == 1) + dhcp_mode_ap = enable; + else if(mode == 2) + dhcp_mode_sta = enable; + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPH] OK"); + else + at_printf("\r\n[ATPH] ERROR:%d",error_no); + + return; + +} + +//ATPE=(,,) +void fATPE(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + unsigned int ip_addr = 0; + //unsigned char sta_ip[4] = {192,168,3,80}, sta_netmask[4] = {255,255,255,0}, sta_gw[4] = {192,168,3,1}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPE] Usage : ATPE=(,,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc > 4) || (argc < 2) ){ + //at_printf("\r\n[ATPE] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + ip_addr = inet_addr(argv[1]); + sta_ip[0] = (unsigned char) ip_addr & 0xff; + sta_ip[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_ip[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_ip[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + //at_printf("\r\n[ATPE] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + if(argv[2] != NULL){ + ip_addr = inet_addr(argv[2]); + sta_gw[0] = (unsigned char) ip_addr & 0xff; + sta_gw[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_gw[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_gw[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_gw[0] = sta_ip[0]; + sta_gw[1] = sta_ip[1]; + sta_gw[2] = sta_ip[2]; + sta_gw[3] = 1; + } + + if(argv[3] != NULL){ + ip_addr = inet_addr(argv[3]); + sta_netmask[0] = (unsigned char) ip_addr & 0xff; + sta_netmask[1] = (unsigned char) (ip_addr >> 8) & 0xff; + sta_netmask[2] = (unsigned char) (ip_addr >> 16) & 0xff; + sta_netmask[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + sta_netmask[0] = 255; + sta_netmask[1] = 255; + sta_netmask[2] = 255; + sta_netmask[3] = 0; + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPE] OK"); + else + at_printf("\r\n[ATPE] ERROR:%d",error_no); + + return; + +} + +//ATPF=,, +void fATPF(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + unsigned int ip_addr = 0; + struct ip_addr start_ip, end_ip; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPF] Usage : ATPF=,,(,,)"); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if( (argc != 4) ){ + //at_printf("\r\n[ATPF] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + start_ip.addr = inet_addr(argv[1]); + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + if(argv[2] != NULL){ + end_ip.addr = inet_addr(argv[2]); + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + dhcps_set_addr_pool(&start_ip,&end_ip); + + if(argv[3] != NULL){ + ip_addr = inet_addr(argv[3]); + ap_ip[0] = (unsigned char) ip_addr & 0xff; + ap_ip[1] = (unsigned char) (ip_addr >> 8) & 0xff; + ap_ip[2] = (unsigned char) (ip_addr >> 16) & 0xff; + ap_ip[3] = (unsigned char) (ip_addr >> 24) & 0xff; + } + else{ + //at_printf("\r\n[ATPF] ERROR : parameter format error"); + error_no = 2; + goto exit; + } + + ap_gw[0] = ap_ip[0]; + ap_gw[1] = ap_ip[1]; + ap_gw[2] = ap_ip[2]; + ap_gw[3] = ap_ip[3]; + + ap_netmask[0] = 255; + ap_netmask[1] = 255; + ap_netmask[2] = 255; + ap_netmask[3] = 0; + +exit: + if(error_no==0) + at_printf("\r\n[ATPF] OK"); + else + at_printf("\r\n[ATPF] ERROR:%d", error_no); + + return; +} + +int atcmd_wifi_read_info_from_flash(u8 *read_data, u32 read_len) +{ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, read_data, read_len); + return 0; +} + +void atcmd_wifi_write_info_to_flash(rtw_wifi_setting_t *setting, int enable) +{ + struct atcmd_wifi_conf *data_to_flash; + rtw_wifi_setting_t *old_setting; + +// flash_t flash; + u32 channel = 0, i, write_needed = 0; + u8 index = 0; + u32 data; + + data_to_flash = (struct atcmd_wifi_conf *)malloc(sizeof(struct atcmd_wifi_conf)); + + if(data_to_flash) { + if(enable){ + memset((u8 *)data_to_flash, 0, sizeof(struct atcmd_wifi_conf)); + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + old_setting = &(data_to_flash->setting); + if(memcmp((u8 *)old_setting, setting, sizeof(rtw_wifi_setting_t))){ + memcpy(old_setting, setting, sizeof(rtw_wifi_setting_t)); + write_needed = 1; + } + if(setting->mode == RTW_MODE_STA || setting->mode == RTW_MODE_STA_AP){ + struct wlan_fast_reconnect reconn; + int found = 0; + /*clean wifi ssid,key and bssid*/ + memset((u8 *)&reconn, 0, sizeof(struct wlan_fast_reconnect)); + + channel = setting->channel; + + memset(psk_essid[index], 0, sizeof(psk_essid[index])); + strncpy(psk_essid[index], setting->ssid, strlen(setting->ssid)); + switch(setting->security_type){ + case RTW_SECURITY_OPEN: + memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + reconn.security_type = RTW_SECURITY_OPEN; + break; + case RTW_SECURITY_WEP_PSK: + channel |= (setting->key_idx) << 28; + memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + memcpy(psk_passphrase[index], setting->password, sizeof(psk_passphrase[index])); + reconn.security_type = RTW_SECURITY_WEP_PSK; + break; + case RTW_SECURITY_WPA_TKIP_PSK: + reconn.security_type = RTW_SECURITY_WPA_TKIP_PSK; + break; + case RTW_SECURITY_WPA2_AES_PSK: + reconn.security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + default: + break; + } + + memcpy(reconn.psk_essid, psk_essid[index], sizeof(reconn.psk_essid)); + if (strlen(psk_passphrase64) == 64) { + memcpy(reconn.psk_passphrase, psk_passphrase64, sizeof(reconn.psk_passphrase)); + } else { + memcpy(reconn.psk_passphrase, psk_passphrase[index], sizeof(reconn.psk_passphrase)); + } + memcpy(reconn.wpa_global_PSK, wpa_global_PSK[index], sizeof(reconn.wpa_global_PSK)); + memcpy(&(reconn.channel), &channel, 4); + + if(data_to_flash->reconn_num < 0 || data_to_flash->reconn_num > ATCMD_WIFI_CONN_STORE_MAX_NUM || + data_to_flash->reconn_last_index < 0 || data_to_flash->reconn_last_index > ATCMD_WIFI_CONN_STORE_MAX_NUM + ){ + data_to_flash->reconn_num = 0; + data_to_flash->reconn_last_index = -1; + } + + reconn.enable = enable; + for(i = 0; i < data_to_flash->reconn_num; i++){ + if(memcmp((u8 *)&reconn, (u8 *)&(data_to_flash->reconn[i]), sizeof(struct wlan_fast_reconnect)) == 0) { + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ALWAYS, + "the same profile found in flash"); + found = 1; + break; + } + } + if(!found){ + data_to_flash->reconn_last_index++; + if(data_to_flash->reconn_last_index >= ATCMD_WIFI_CONN_STORE_MAX_NUM) + data_to_flash->reconn_last_index -= ATCMD_WIFI_CONN_STORE_MAX_NUM; + memcpy((u8 *)&data_to_flash->reconn[data_to_flash->reconn_last_index], (u8 *)&reconn, sizeof(struct wlan_fast_reconnect)); + data_to_flash->reconn_num++; + if(data_to_flash->reconn_num > ATCMD_WIFI_CONN_STORE_MAX_NUM) + data_to_flash->reconn_num = ATCMD_WIFI_CONN_STORE_MAX_NUM; + write_needed = 1; + } + } + if(write_needed || data_to_flash->auto_enable != enable){ + data_to_flash->auto_enable = enable; + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_WRITE, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + } + }else{ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_ERASE, (u8 *)data_to_flash, sizeof(struct atcmd_wifi_conf)); + } + } + if(data_to_flash) { + free(data_to_flash); + } +} + +int atcmd_wifi_restore_from_flash(void) +{ +// flash_t flash; + struct atcmd_wifi_conf *data; + rtw_wifi_setting_t *setting; + struct wlan_fast_reconnect *reconn; + uint32_t channel; + uint32_t security_type; + uint8_t pscan_config; + char key_id[2] = {0}; + int ret = -1, i; + int mode; + rtw_network_info_t wifi = { + {0}, // ssid + {0}, // bssid + 0, // security + NULL, // password + 0, // password len + -1 // key id + }; + data = (struct atcmd_wifi_conf *)rtw_zmalloc(sizeof(struct atcmd_wifi_conf)); + if(data){ + atcmd_update_partition_info(AT_PARTITION_WIFI, AT_PARTITION_READ, (u8 *)data, sizeof(struct atcmd_wifi_conf)); + if(data->auto_enable != 1) + goto exit; + setting = &data->setting; + if(setting->mode == RTW_MODE_AP || setting->mode == RTW_MODE_STA_AP){ + //start AP here + goto exit; + } + + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("ERROR: Wifi on failed!\n"); + ret = -1; + goto exit; + } + } + +#if CONFIG_AUTO_RECONNECT + //setup reconnection flag + wifi_set_autoreconnect(0); +#endif + int last_index = data->reconn_last_index; + for(i = 0; i < data->reconn_num; i++){ + reconn = &data->reconn[last_index]; + last_index ++; + if(last_index >= ATCMD_WIFI_CONN_STORE_MAX_NUM) + last_index -= ATCMD_WIFI_CONN_STORE_MAX_NUM; + if(reconn->enable != 1){ + continue; + } + memcpy(psk_essid, reconn->psk_essid, sizeof(reconn->psk_essid)); + memcpy(psk_passphrase, reconn->psk_passphrase, sizeof(reconn->psk_passphrase)); + memcpy(wpa_global_PSK, reconn->wpa_global_PSK, sizeof(reconn->wpa_global_PSK)); + channel = reconn->channel; + sprintf(key_id,"%d",(char) (channel>>28)); + channel &= 0xff; + security_type = reconn->security_type; + pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY; + //set partial scan for entering to listen beacon quickly + wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1); + + wifi.security_type = security_type; + //SSID + strcpy((char *)wifi.ssid.val, (char*)psk_essid); + wifi.ssid.len = strlen((char*)psk_essid); + + switch(security_type){ + case RTW_SECURITY_WEP_PSK: + wifi.password = (unsigned char*) psk_passphrase; + wifi.password_len = strlen((char*)psk_passphrase); + wifi.key_id = atoi((const char *)key_id); + break; + case RTW_SECURITY_WPA_TKIP_PSK: + case RTW_SECURITY_WPA2_AES_PSK: + wifi.password = (unsigned char*) psk_passphrase; + wifi.password_len = strlen((char*)psk_passphrase); + break; + default: + break; + } + + ret = wifi_connect( + NULL, + 0, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + if(ret == RTW_SUCCESS){ + LwIP_DHCP(0, DHCP_START); + ret = 0; +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + break; + } + } + } + +exit: + if(data) + rtw_mfree((u8 *)data, sizeof(struct wlan_fast_reconnect)); + return ret; +} + +//ATPG= +void fATPG(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; +// flash_t flash; +// struct wlan_fast_reconnect read_data = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "[ATPG] Usage : ATPG=\r\n"); + error_no = 1; + goto exit; + } + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPG] ERROR : command format error"); + error_no = 1; + goto exit; + } + + //ENABLE FAST CONNECT + if(argv[1] != NULL){ +#if 0 + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data); + read_data.enable = atoi((const char *)(argv[1])); + if(read_data.enable != 0 && read_data.enable != 1){ + //at_printf("\r\n[ATPG] ERROR : parameter must be 0 or 1"); + error_no = 2; + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto exit; + } + flash_erase_sector(&flash, FAST_RECONNECT_DATA); + flash_stream_write(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#else + rtw_wifi_setting_t setting; + int enable = atoi((const char *)(argv[1])); + if(enable != 0 && enable != 1){ + error_no = 2; + goto exit; + } + if(enable == 1){ + u8 *ifname[1] = {WLAN0_NAME}; + if(wifi_get_setting((const char*)ifname[0],&setting)){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "wifi_get_setting fail"); + error_no = 3; + goto exit; + } + } + atcmd_wifi_write_info_to_flash(&setting, enable); +#endif + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPG] OK"); + else + at_printf("\r\n[ATPG] ERROR:%d",error_no); + + return; +} + +// set MAC address +//ATPM= +void fATPM(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPM] Usage : ATPM="); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPM] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + if(strlen(argv[1]) != 12){ + //at_printf("\r\n[ATPM] ERROR : BSSID format error"); + error_no = 2; + goto exit; + } + wifi_set_mac_address(argv[1]); + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPM] OK"); + else + at_printf("\r\n[ATPM] ERROR:%d",error_no); + + return; + +} + +// set Wifi mode +// ATPW= +void fATPW(void *arg) +{ + int argc, error_no = 0; + char *argv[MAX_ARGC] = {0}; + + if(!arg){ + AT_DBG_MSG(AT_FLAG_WIFI, AT_DBG_ERROR, + "\r\n[ATPW] Usage : ATPW="); + error_no = 1; + goto exit; + } + + argc = parse_param(arg, argv); + if(argc != 2){ + //at_printf("\r\n[ATPW] ERROR : command format error"); + error_no = 1; + goto exit; + } + + if(argv[1] != NULL){ + wifi_mode = atoi((const char *)(argv[1])); + if((wifi_mode!=RTW_MODE_STA) && (wifi_mode!=RTW_MODE_AP) && (wifi_mode!=RTW_MODE_STA_AP) ){ + //at_printf("\r\n[ATPW] ERROR : parameter must be 1 , 2 or 3"); + error_no = 2; + } + } + +exit: + if(error_no==0) + at_printf("\r\n[ATPW] OK"); + else + at_printf("\r\n[ATPW] ERROR:%d",error_no); + + return; +} + +//------------------------------------------------------------ +#if CONFIG_ENABLE_P2P +void fATWG(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWG]: _AT_WLAN_P2P_START_\n"); + argv[argc++] = "p2p_start"; + cmd_wifi_p2p_start(argc, argv); +} + +void fATWg(void *arg){ + int argc = 0; + char *argv[4]; + int ret =0; + printf("[ATWg]: _AT_WLAN_P2P_AUTO_GO_START_\n"); + argv[argc++] = "p2p_auto_go_start"; + ret = cmd_wifi_p2p_auto_go_start(argc, argv); + if(ret < 0) + printf("[ATWg]: Nothing to do. Please enter ATWG to initialize P2P.\n"); +} + +void fATWH(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWH]: _AT_WLAN_P2P_STOP_\n"); + argv[argc++] = "p2p_stop"; + cmd_wifi_p2p_stop(argc, argv); +} +void fATWJ(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWJ]: _AT_WLAN_P2P_CONNECT_\n"); + argv[0] = "p2p_connect"; + if(!arg){ + printf("ATWc=[DEST_MAC,pbc/pin]\n"); + return; + } + if((argc = parse_param(arg, argv)) > 1){ + cmd_p2p_connect(argc, argv); + } +} +void fATWK(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWK]: _AT_WLAN_P2P_DISCONNECT_\n"); + argv[argc++] = "p2p_disconnect"; + cmd_p2p_disconnect(argc, argv); +} +void fATWN(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWN]: _AT_WLAN_P2P_INFO_\n"); + argv[argc++] = "p2p_info"; + cmd_p2p_info(argc, argv); +} +void fATWF(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWF]: _AT_WLAN_P2P_FIND_\n"); + argv[argc++] = "p2p_find"; + cmd_p2p_find(argc, argv); +} +void fATWL(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWL]: _AT_WLAN_P2P_LISTEN_\n"); + argv[argc++] = "p2p_listen"; + cmd_p2p_listen(argc, argv); +} +void fATWP(void *arg){ + int argc = 0; + char *argv[4]; + printf("[ATWP]: _AT_WLAN_P2P_PEERS_\n"); + argv[argc++] = "p2p_peers"; + cmd_p2p_peers(argc, argv); +} + +#endif // CONFIG_ENABLE_P2P +//----------------------------------------------------- + +void print_wlan_help(void *arg){ + at_printf("\r\nWLAN AT COMMAND SET:"); + at_printf("\r\n=============================="); + at_printf("\r\n1. Wlan Scan for Network Access Point"); + at_printf("\r\n # ATWS"); + at_printf("\r\n2. Connect to an AES AP"); + at_printf("\r\n # ATPN=,,(,)"); + at_printf("\r\n3. Create an AES AP"); + at_printf("\r\n # ATPA=,,,"); + at_printf("\r\n4. Set auto connect"); + at_printf("\r\n # ATPG=<0/1>"); +} + +#endif // end of #if ATCMD_VER == ATVER_1 +void fATWT(void *arg) +{ +#if CONFIG_BSD_TCP + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWT]: _AT_WLAN_TCP_TEST_\n"); + + if(!arg){ + printf("[ATWT] Usage: ATWT=[-s|-c,host|stop],[options]\n"); + printf(" Client/Server:\n"); + printf(" stop terminate client & server\n"); + printf(" -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" -p # server port to listen on/connect to (default 5001)\n"); + printf(" Server specific:\n"); + printf(" -s run in server mode\n"); + printf(" Client specific:\n"); + printf(" -c run in client mode, connecting to \n"); + printf(" -d do a bidirectional test simultaneously\n"); + printf(" -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" -n #[KM] number of bytes to transmit (instead of -t)\n"); + printf(" Example:\n"); + printf(" ATWT=-s,-p,5002\n"); + printf(" ATWT=-c,192.168.1.2,-t,100,-p,5002\n"); + return; + } + + argv[0] = "tcp"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_tcp(argc, argv); + } +#else + printf("Please set CONFIG_BSD_TCP 1 in platform_opts.h to enable ATWT command\n"); +#endif +} + +void fATWU(void *arg) +{ +#if CONFIG_BSD_TCP + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWU]: _AT_WLAN_UDP_TEST_\n"); + + if(!arg){ + printf("[ATWU] Usage: ATWU=[-s|-c,host|stop][options]\n"); + printf(" Client/Server:\n"); + printf(" stop terminate client & server\n"); + printf(" -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" -p # server port to listen on/connect to (default 5001)\n"); + printf(" Server specific:\n"); + printf(" -s run in server mode\n"); + printf(" Client specific:\n"); + printf(" -b #[KM] for UDP, bandwidth to send at in bits/sec (default 1 Mbit/sec)\n"); + printf(" -c run in client mode, connecting to \n"); + printf(" -d do a bidirectional test simultaneously\n"); + printf(" -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" -n #[KM] number of bytes to transmit (instead of -t)\n"); + printf(" -S # set the IP 'type of service'\n"); + printf(" Example:\n"); + printf(" ATWU=-s,-p,5002\n"); + printf(" ATWU=-c,192.168.1.2,-t,100,-p,5002\n"); + return; + } + + argv[0] = "udp"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_udp(argc, argv); + } +#else + printf("Please set CONFIG_BSD_TCP 1 in platform_opts.h to enable ATWU command\n"); +#endif +} + +#endif // end of #if CONFIG_WLAN + +#if CONFIG_LWIP_LAYER +#if ATCMD_VER == ATVER_1 +void fATWL(void *arg){ +#if CONFIG_SSL_CLIENT + int argc; + char *argv[MAX_ARGC] = {0}; + printf("[ATWL]: _AT_WLAN_SSL_CLIENT_\n"); + argv[0] = "ssl_client"; + if(!arg){ + printf("ATWL=SSL_SERVER_HOST\n"); + return; + } + if((argc = parse_param(arg, argv)) > 1){ + if(argc != 2) { + printf("ATWL=SSL_SERVER_HOST\n"); + return; + } + + cmd_ssl_client(argc, argv); + } +#else + printf("Please set CONFIG_SSL_CLIENT 1 in platform_opts.h to enable ATWL command\n"); +#endif +} + +void fATWI(void *arg){ + int argc; + char *argv[MAX_ARGC] = {0}; + + printf("[ATWI]: _AT_WLAN_PING_TEST_\n"); + + if(!arg){ + printf("[ATWI] Usage: ATWI=[host],[options]\n"); + printf(" -t Ping the specified host until stopped\n"); + printf(" -n # Number of echo requests to send (default 4 times)\n"); + printf(" -l # Send buffer size (default 32 bytes)\n"); + printf(" Example:\n"); + printf(" ATWI=192.168.1.2,-n,100,-l,5000\n"); + return; + } + + argv[0] = "ping"; + + if((argc = parse_param(arg, argv)) > 1){ + cmd_ping(argc, argv); + } +} + +#elif ATCMD_VER == ATVER_2 // uart at command +//move to atcmd_lwip.c +#endif +#endif +log_item_t at_wifi_items[ ] = { +#if ATCMD_VER == ATVER_1 +#if CONFIG_LWIP_LAYER + {"ATWL", fATWL,}, + {"ATWI", fATWI,}, + {"ATWT", fATWT,}, + {"ATWU", fATWU,}, +#endif +#if CONFIG_WLAN + {"ATW0", fATW0,}, + {"ATW1", fATW1,}, + {"ATW2", fATW2,}, + {"ATW3", fATW3,}, + {"ATW4", fATW4,}, + {"ATW5", fATW5,}, + {"ATW6", fATW6,}, + {"ATWA", fATWA,}, +#ifdef CONFIG_CONCURRENT_MODE + {"ATWB", fATWB,}, +#endif + {"ATWC", fATWC,}, + {"ATWD", fATWD,}, + {"ATWP", fATWP,}, +#if CONFIG_WOWLAN_SERVICE + {"ATWV", fATWV,}, +#endif + {"ATWR", fATWR,}, + {"ATWS", fATWS,}, +#if SCAN_WITH_SSID + {"ATWs", fATWs,}, +#endif +#ifdef CONFIG_PROMISC + {"ATWM", fATWM,}, +#endif + {"ATWZ", fATWZ,}, +#if CONFIG_OTA_UPDATE + {"ATWO", fATWO,}, +#endif +#if CONFIG_WEBSERVER + {"ATWE", fATWE,}, +#endif +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + {"ATWQ", fATWQ,}, +#endif +#ifdef CONFIG_WPS + {"ATWW", fATWW,}, + {"ATWw", fATWw,}, //wps registrar for softap +#if CONFIG_ENABLE_P2P + {"ATWG", fATWG,}, //p2p start + {"ATWH", fATWH,}, //p2p stop + {"ATWJ", fATWJ,}, //p2p connect + {"ATWK", fATWK,}, //p2p disconnect + {"ATWN", fATWN,}, //p2p info + {"ATWF", fATWF,}, //p2p find + {"ATWg", fATWg,}, //p2p auto go start +#endif +#endif + +#if CONFIG_AIRKISS + {"ATWX", fATWX,}, +#endif + {"ATW?", fATWx,}, + {"ATW+ABC", fATWx,}, +#ifdef CONFIG_POWER_SAVING + {"ATXP", fATXP,}, +#endif +#endif +#elif ATCMD_VER == ATVER_2 // uart at command +#if CONFIG_WLAN + {"ATPA", fATPA,}, // set AP + {"ATPN", fATPN,}, // connect to Network + {"ATPH", fATPH,}, // set DHCP mode + {"ATPE", fATPE,}, // set static IP for STA + {"ATPF", fATPF,}, // set DHCP rule for AP + {"ATPG", fATPG,}, // set auto connect + {"ATPM", fATPM,}, // set MAC address + {"ATPW", fATPW,}, // set Wifi mode + {"ATWD", fATWD,}, // WIFI disconnect + {"ATWS", fATWS,}, // WIFI scan +#if CONFIG_ENABLE_P2P + {"ATWG", fATWG,}, //p2p start + {"ATWH", fATWH,}, //p2p stop + {"ATWJ", fATWJ,}, //p2p connect + {"ATWK", fATWK,}, //p2p disconnect + {"ATWN", fATWN,}, //p2p info + {"ATWF", fATWF,}, //p2p find + {"ATWg", fATWg,}, //p2p auto go start + {"ATWL", fATWL,}, //p2p listen + {"ATWP", fATWP,}, //p2p peers +#endif +#if CONFIG_LWIP_LAYER + {"ATWT", fATWT,}, + {"ATWU", fATWU,}, +#endif +#ifdef CONFIG_PROMISC + {"ATWM", fATWM,}, // WIFI promisc Usage: ATWM=DURATION_SECONDS[with_len] +#endif + {"ATW?", fATWx,}, // WIFI Info +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + {"ATWQ", fATWQ } // wifi simpleconfig +#endif // #if (CONFIG_INCLUDE_SIMPLE_CONFIG) +#endif // #if CONFIG_WLAN +#endif // end of #if ATCMD_VER == ATVER_1 +}; + +#if ATCMD_VER == ATVER_2 +void print_wifi_at(void *arg){ + int index; + int cmd_len = 0; + + cmd_len = sizeof(at_wifi_items)/sizeof(at_wifi_items[0]); + for(index = 0; index < cmd_len; index++) + at_printf("\r\n%s", at_wifi_items[index].log_cmd); +} +#endif + +void at_wifi_init(void) +{ +#if CONFIG_WLAN + init_wifi_struct(); +#endif + log_service_add_table(at_wifi_items, sizeof(at_wifi_items)/sizeof(at_wifi_items[0])); +} + +#if SUPPORT_LOG_SERVICE +log_module_init(at_wifi_init); +#endif + +#endif //#ifdef CONFIG_AT_WIFI diff --git a/USDK/component/common/api/at_cmd/atcmd_wifi1.h b/USDK/component/common/api/at_cmd/atcmd_wifi1.h new file mode 100644 index 0000000..e367a88 --- /dev/null +++ b/USDK/component/common/api/at_cmd/atcmd_wifi1.h @@ -0,0 +1,171 @@ +#ifndef __ATCMD_WIFI_H__ +#define __ATCMD_WIFI_H__ +#include +#ifdef CONFIG_AT_WIFI +#include "main.h" +#include "lwip_netconf.h" +#ifdef USE_FLASH_EEP +#include "flash_eep.h" +#include "feep_config.h" +#endif + + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif +/* Give default value if not defined */ +#ifndef NET_IF_NUM + #ifdef CONFIG_CONCURRENT_MODE + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1) + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN)) + #endif // end of CONFIG_CONCURRENT_MODE +#endif // end of NET_IF_NUM + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 3 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 3 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +#endif // CONFIG_AT_WIFI + +#if CONFIG_EXAMPLE_UART_ATCMD + +#include "wifi_structures.h" +#include +typedef struct _UART_LOG_CONF_{ + u32 BaudRate; + u8 DataBits; + u8 StopBits; + u8 Parity; + u8 FlowControl; +}UART_LOG_CONF, *PUART_LOG_CONF; + +#define ATCMD_WIFI_CONN_STORE_MAX_NUM (1) +struct atcmd_wifi_conf{ + struct wlan_fast_reconnect reconn[ATCMD_WIFI_CONN_STORE_MAX_NUM]; + int32_t auto_enable; + rtw_wifi_setting_t setting; + int32_t reconn_num; + int32_t reconn_last_index; +}; + +#define ATCMD_LWIP_CONN_STORE_MAX_NUM (1) +struct atcmd_lwip_conn_info{ + int32_t role; //client, server or seed + uint32_t protocol; //tcp or udp + uint32_t remote_addr; //remote ip + uint32_t remote_port; //remote port + uint32_t local_addr; //locale ip, not used yet + uint32_t local_port; //locale port, not used yet + uint32_t reserved; //reserve for further use +}; +struct atcmd_lwip_conf { + int32_t enable; //enable or not + int32_t conn_num; + int32_t last_index; + int32_t reserved; //reserve for further use + struct atcmd_lwip_conn_info conn[ATCMD_LWIP_CONN_STORE_MAX_NUM]; +}; + +typedef enum { + AT_PARTITION_ALL = 0, + AT_PARTITION_UART = FEEP_ID_UART_CFG, + AT_PARTITION_WIFI = FEEP_ID_WIFI_CFG, + AT_PARTITION_LWIP = FEEP_ID_LWIP_CFG +} AT_PARTITION; + +typedef enum { + AT_PARTITION_READ = 0, + AT_PARTITION_WRITE = 1, + AT_PARTITION_ERASE = 2 +} AT_PARTITION_OP; + +//first segment for uart +#define UART_SETTING_BACKUP_SECTOR (0x8000) +#define UART_CONF_DATA_OFFSET (0) +#define UART_CONF_DATA_SIZE ((((sizeof(UART_LOG_CONF)-1)>>2) + 1)<<2) + +//second segment for wifi config +#define WIFI_CONF_DATA_OFFSET (UART_CONF_DATA_OFFSET+UART_CONF_DATA_SIZE) +#define WIFI_CONF_DATA_SIZE ((((sizeof(struct atcmd_wifi_conf)-1)>>2) + 1)<<2) + +//fouth segment for lwip config +#define LWIP_CONF_DATA_OFFSET (WIFI_CONF_DATA_OFFSET+WIFI_CONF_DATA_SIZE) +#define LWIP_CONF_DATA_SIZE ((((sizeof(struct atcmd_lwip_conf)-1)>>2) + 1)<<2) + +extern void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len); + +#define ATSTRING_LEN (LOG_SERVICE_BUFLEN) +extern char at_string[ATSTRING_LEN]; + +extern unsigned char gAT_Echo; // default echo on +//extern void uart_at_lock(void); +//extern void uart_at_unlock(void); +extern void uart_at_send_string(char *str); +extern void uart_at_send_buf(u8 *buf, u32 len); + +#define at_printf(fmt, args...) do{\ + /*uart_at_lock();*/\ + snprintf(at_string, ATSTRING_LEN, fmt, ##args); \ + uart_at_send_string(at_string);\ + /*uart_at_unlock();*/\ + }while(0) +#define at_print_data(data, size) do{\ + /*uart_at_lock();*/\ + uart_at_send_buf(data, size);\ + /*uart_at_unlock();*/\ + }while(0) + +#else +#define at_printf(fmt, args...) do{printf(fmt, ##args);}while(0) +#define at_print_data(data, size) do{__rtl_memDump(data, size, NULL);}while(0) +#endif//#if CONFIG_EXAMPLE_UART_ATCMD + +#endif diff --git a/USDK/component/common/api/at_cmd/log_service.c b/USDK/component/common/api/at_cmd/log_service.c new file mode 100644 index 0000000..9da3a3a --- /dev/null +++ b/USDK/component/common/api/at_cmd/log_service.c @@ -0,0 +1,497 @@ +#include +#include +#include +#include "FreeRTOS.h" +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "freertos_pmu.h" +#endif +#include "log_service.h" +#include "task.h" +#include "semphr.h" +#include "main.h" +#include "wifi_util.h" +#include "atcmd_wifi.h" +#include "osdep_api.h" + +#if CONFIG_EXAMPLE_UART_ATCMD +#include "atcmd_lwip.h" +#endif + +#if SUPPORT_LOG_SERVICE +//====================================================== +struct list_head log_hash[ATC_INDEX_NUM]; +#ifdef CONFIG_AT_USR +extern void at_user_init(void); +#endif +#ifdef CONFIG_AT_WIFI +extern void at_wifi_init(void); +#endif +//extern void at_fs_init(void); + +#ifdef CONFIG_AT_SYS +extern void at_sys_init(void); +#endif +#if CONFIG_ETHERNET +extern void at_ethernet_init(void); +#endif +#if CONFIG_GOOGLE_NEST +extern void at_google_init(void); +#endif +#ifdef CONFIG_AT_LWIP +extern void at_transport_init(void); +#endif +//extern void at_app_init(void); +#if CONFIG_ALINK +extern void at_cloud_init(void); +#endif + + +char log_buf[LOG_SERVICE_BUFLEN]; +#if CONFIG_LOG_HISTORY +char log_history[LOG_HISTORY_LEN][LOG_SERVICE_BUFLEN]; +static unsigned int log_history_count = 0; +#endif +xSemaphoreHandle log_rx_interrupt_sema = NULL; +#if CONFIG_LOG_SERVICE_LOCK +xSemaphoreHandle log_service_sema = NULL; +#endif +extern xSemaphoreHandle uart_rx_interrupt_sema; + +#if CONFIG_INIC_EN +extern unsigned char inic_cmd_ioctl; +#endif + +#if defined (__ICCARM__) +#pragma section=".data.log_init" + +unsigned int __log_init_begin__; +unsigned int __log_init_end__; +#elif defined ( __CC_ARM ) || defined(__GNUC__) +//#pragma section=".data.log_init" +log_init_t* __log_init_begin__; +log_init_t* __log_init_end__; +log_init_t log_init_table[] = { + +#ifdef CONFIG_AT_WIFI + at_wifi_init, +#endif + // at_fs_init, +#ifdef CONFIG_AT_SYS + at_sys_init, +#endif + +#if CONFIG_ETHERNET + at_ethernet_init +#endif + +#if CONFIG_GOOGLE_NEST + at_google_init +#endif + +#if CONFIG_TRANSPORT + at_transport_init +#endif + +#if CONFIG_ALINK + at_cloud_init +#endif + +#ifdef CONFIG_AT_USR + at_user_init +#endif + + // at_app_init +}; +#else +#error "not implement, add to linker script" +extern unsigned int __log_init_begin__; +extern unsigned int __log_init_end__; +#endif + +#if defined(__GNUC__) +#define USE_STRSEP +#endif + +//====================================================== +int hash_index(char *str) +{ + unsigned int seed = 131; // 31 131 1313 13131 131313 etc.. + unsigned int hash = 0; + + while (*str) + { + hash = hash * seed + (*str++); + } + + return (hash & 0x7FFFFFFF); +} + +void log_add_new_command(log_item_t *new) +{ + int index = hash_index(new->log_cmd)%ATC_INDEX_NUM; + + list_add(&new->node, &log_hash[index]); +} +void start_log_service(void); +void log_service_init(void) +{ + int i; + +#if defined (__ICCARM__) + log_init_t *log_init_table; + __log_init_begin__ = (unsigned int)__section_begin(".data.log_init"); + __log_init_end__ = (unsigned int)__section_end(".data.log_init"); + log_init_table = (log_init_t *)__log_init_begin__; +#elif defined(__CC_ARM) || defined(__GNUC__) + __log_init_begin__ = log_init_table; + __log_init_end__ = log_init_table + sizeof(log_init_table); +#else + #error "not implement" +#endif + + + for(i=0;ilog_cmd, cmd) == 0){ + //printf("%s match %s, search cnt %d\n\r", cmd, item->log_cmd, search_cnt); + act = (void*)item->at_act; + break; + } + } + + return act; +} + +void* log_handler(char *cmd) +{ + log_act_t action=NULL; + char buf[LOG_SERVICE_BUFLEN] = {0}; + char *copy=buf; + char *token = NULL; + char *param = NULL; + char tok[5] = {0};//'\0' +#if CONFIG_LOG_HISTORY + strcpy(log_history[((log_history_count++)%LOG_HISTORY_LEN)], log_buf); +#endif + strncpy(copy, cmd,LOG_SERVICE_BUFLEN-1); + +#if defined(USE_STRSEP) + token = _strsep(©, "="); + param = copy; +#else + token = strtok(copy, "="); + param = strtok(NULL, NULL); +#endif + if(token && (strlen(token) <= 4)) + strcpy(tok, token); + else{ + //printf("\n\rAT Cmd format error!\n"); + return NULL; + }; + //printf(" Command %s \n\r ", tok); + //printf(" Param %s \n\r", param); + action = (log_act_t)log_action(tok); + + if(action){ + action(param); + } + return (void*)action; + +} + +int parse_param(char *buf, char **argv) +{ + int argc = 1; + char str_buf[LOG_SERVICE_BUFLEN] = "\0"; + int str_count = 0; + int buf_cnt = 0; + + if(buf == NULL) + goto exit; + + while((argc < MAX_ARGC) && (*buf != '\0')) { + while((*buf == ',') || (*buf == '[') || (*buf == ']')){ + if((*buf == ',') && (*(buf+1) == ',')){ + argv[argc] = NULL; + argc++; + } + *buf = '\0'; + buf++; + } + + if(*buf == '\0') + break; + else if(*buf == '"'){ + memset(str_buf,'\0',LOG_SERVICE_BUFLEN); + str_count = 0; + buf_cnt = 0; + *buf = '\0'; + buf ++; + if(*buf == '\0') + break; + argv[argc] = buf; + while((*buf != '"')&&(*buf != '\0')){ + if(*buf == '\\'){ + buf ++; + buf_cnt++; + } + str_buf[str_count] = *buf; + str_count++; + buf_cnt++; + buf ++; + } + *buf = '\0'; + memcpy(buf-buf_cnt,str_buf,buf_cnt); + } + else{ + argv[argc] = buf; + } + argc++; + buf++; + + while( (*buf != ',')&&(*buf != '\0')&&(*buf != '[')&&(*buf != ']') ) + buf++; + } +exit: + return argc; +} + +unsigned char gDbgLevel = AT_DBG_ERROR; +unsigned int gDbgFlag = 0xFFFFFFFF; +void at_set_debug_level(unsigned char newDbgLevel) +{ + gDbgLevel = newDbgLevel; +} + +void at_set_debug_mask(unsigned int newDbgFlag) +{ + gDbgFlag = newDbgFlag; +} + +#if SUPPORT_INTERACTIVE_MODE +extern char uart_buf[64]; +void legency_interactive_handler(unsigned char argc, unsigned char **argv) +{ +#if 0 //defined(CONFIG_PLATFORM_8195A) + if(argc<1) + { + DiagPrintf("Wrong argument number!\r\n"); + return; + } + + + DiagPrintf("Wlan Normal Mode\n"); + + WlanNormal( argc, argv); +#else + strncpy(uart_buf, log_buf, 63);//uart_buf[64] + xSemaphoreGive(uart_rx_interrupt_sema); +#endif +} +#endif + +#if CONFIG_WLAN +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif +int mp_commnad_handler(char *cmd) +{ + char buf[64] = {0}; + char *token = NULL; + + //strcpy(buf, cmd); + strncpy(buf, cmd, (64-1)); + token = strtok(buf, " "); + if(token && (strcmp(buf, "iwpriv") == 0)){ + token = strtok(NULL, ""); + wext_private_command(WLAN0_NAME, token, 1); + return 0; + } + return -1; +} +#endif +void print_help_msg(void){ +#if CONFIG_WLAN +extern void print_wlan_help(void); + print_wlan_help(); +#endif +//add other help message print here +} + +int print_help_handler(char *cmd){ + if(strcmp(cmd, "help") == 0){ + print_help_msg(); + return 0; + } + return -1; +} + +#if CONFIG_LOG_SERVICE_LOCK +void log_service_lock(void) +{ + rtw_down_sema(&log_service_sema); +} + +u32 log_service_lock_timeout(u32 ms) +{ + return rtw_down_timeout_sema(&log_service_sema, ms); +} + +void log_service_unlock(void) +{ + rtw_up_sema(&log_service_sema); +} + +void log_service_lock_init(void){ + rtw_init_sema(&log_service_sema, 1); +} +#endif + +void log_service(void *param) +{ + _AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\rStart LOG SERVICE MODE\n\r"); + _AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r# "); + while(1){ + while(xSemaphoreTake(log_rx_interrupt_sema, portMAX_DELAY) != pdTRUE); +#if CONFIG_LOG_SERVICE_LOCK + log_service_lock(); +#endif + if(log_handler((char *)log_buf) == NULL){ +#if CONFIG_WLAN + if(mp_commnad_handler((char *)log_buf) < 0) +#endif + { + #if SUPPORT_INTERACTIVE_MODE + print_help_handler((char *)log_buf); + legency_interactive_handler(NULL, NULL); + #if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); + #endif + continue; + #else + if(print_help_handler((char *)log_buf) < 0){ + at_printf("\r\nunknown command '%s'", log_buf); + } + #endif + } + } + log_buf[0] = '\0'; +#if CONFIG_INIC_EN + inic_cmd_ioctl = 0; +#endif + _AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r[MEM] After do cmd, available heap %d+%d\n\r", xPortGetFreeHeapSize(), tcm_heap_freeSpace()); + _AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\r\n\n# "); //"#" is needed for mp tool +#if CONFIG_EXAMPLE_UART_ATCMD + if(atcmd_lwip_is_tt_mode()) + at_printf(STR_END_OF_ATDATA_RET); + else + at_printf(STR_END_OF_ATCMD_RET); +#endif +#if CONFIG_LOG_SERVICE_LOCK + log_service_unlock(); +#endif +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + pmu_release_wakelock(WAKELOCK_LOGUART); +#endif + } +} + +#define STACKSIZE 1280 +void start_log_service(void) +{ + xTaskHandle CreatedTask; + int result; + +#if 0 // CONFIG_USE_TCM_HEAP + extern void *tcm_heap_malloc(int size); + void *stack_addr = tcm_heap_malloc(STACKSIZE * sizeof(int)); + + if(stack_addr == NULL){ + } + + result = xTaskGenericCreate( + log_service, + ( signed portCHAR * ) "log_srv", + STACKSIZE, + NULL, + tskIDLE_PRIORITY + 5, + &CreatedTask, + stack_addr, + NULL); +#else + result = xTaskCreate( log_service, ( signed portCHAR * ) "log_srv", STACKSIZE, NULL, tskIDLE_PRIORITY + 5, &CreatedTask ); +#endif + + if(result != pdPASS) { + printf("\n\r%s xTaskCreate failed", __FUNCTION__); + } + +} + +void fAT_exit(void *arg){ + printf("\n\rLeave LOG SERVICE"); + vTaskDelete(NULL); +} +#if CONFIG_LOG_HISTORY +void fAT_log(void *arg){ + int i = 0; + printf("[AT]log history:\n\n\r"); + if(log_history_count > LOG_HISTORY_LEN){ + for(i=0; i<4; i++) + printf(" %s\n\r", log_history[((log_history_count+i)%LOG_HISTORY_LEN)]); + } + else{ + for(i=0; i<(log_history_count-1); i++) + printf(" %s\n\r", log_history[i]); + } +} +#endif +log_item_t at_log_items[ ] = { + {"AT--", fAT_exit,}, +#if CONFIG_LOG_HISTORY + {"AT??", fAT_log,}, +#endif + {"ATxx", fAT_exit,} +}; +void at_log_init(void) +{ + log_service_add_table(at_log_items, sizeof(at_log_items)/sizeof(at_log_items[0])); +} +log_module_init(at_log_init); +#endif diff --git a/USDK/component/common/api/at_cmd/log_service.h b/USDK/component/common/api/at_cmd/log_service.h new file mode 100644 index 0000000..3e9e7d1 --- /dev/null +++ b/USDK/component/common/api/at_cmd/log_service.h @@ -0,0 +1,123 @@ +#ifndef LOG_SERVICE_H +#define LOG_SERVICE_H + +#include "dlist.h" +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#include "platform_opts.h" +#include "platform_stdlib.h" +#endif + +#ifdef __ICCARM__ +#define STRINGIFY(s) #s +#define SECTION(_name) _Pragma( STRINGIFY(location=_name)) +#define log_module_init(fn) \ + SECTION(".data.log_init") __root static void* log_##fn = (void*)fn +#elif defined(__CC_ARM) +#define log_module_init(fn) \ +static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn; +#define DiagPrintf printf +#elif defined(__GNUC__) +#define log_module_init(fn) \ +static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn; +#else +#error "not implement" +#endif + +#define ATC_INDEX_NUM 32 + +#ifndef SUPPORT_LOG_SERVICE +#define SUPPORT_LOG_SERVICE 1 +#endif + +//LOG_SERVICE_BUFLEN: default, only 63 bytes could be used for keeping input +// cmd, the last byte is for string end ('\0'). +#ifndef LOG_SERVICE_BUFLEN +#define LOG_SERVICE_BUFLEN 64 +#endif + +#ifndef CONFIG_LOG_HISTORY +#define CONFIG_LOG_HISTORY 0 +#if CONFIG_LOG_HISTORY +#define LOG_HISTORY_LEN 5 +#endif +#endif //#ifndef CONFIG_LOG_HISTORY + +#ifndef MAX_ARGC +#define MAX_ARGC 12 +#endif + +#ifndef CONFIG_LOG_SERVICE_LOCK +#define CONFIG_LOG_SERVICE_LOCK 0 // //to protect log_buf[], only one command processed per time +#endif + +#define AT_BIT(n) (1< " //data transparent transmission indicator +#endif diff --git a/USDK/component/common/api/lwip_netconf.c b/USDK/component/common/api/lwip_netconf.c new file mode 100644 index 0000000..0ac869a --- /dev/null +++ b/USDK/component/common/api/lwip_netconf.c @@ -0,0 +1,455 @@ +/* Includes ------------------------------------------------------------------*/ +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/dhcp.h" +#include "lwip/dns.h" +#include "ethernetif.h" +#include "main.h" +#include "lwip_netconf.h" +#if CONFIG_WLAN +#include "wifi_ind.h" +#endif +#if defined(STM32F2XX) +#include "stm322xg_eval_lcd.h" +#elif defined(STM32F4XX) +#include "stm324xg_eval_lcd.h" +#endif +#include + + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 1 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 1 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +/*Static IP ADDRESS FOR ETHERNET*/ +#ifndef ETH_IP_ADDR0 +#define ETH_IP_ADDR0 192 +#define ETH_IP_ADDR1 168 +#define ETH_IP_ADDR2 0 +#define ETH_IP_ADDR3 80 +#endif + +/*NETMASK FOR ETHERNET*/ +#ifndef ETH_NETMASK_ADDR0 +#define ETH_NETMASK_ADDR0 255 +#define ETH_NETMASK_ADDR1 255 +#define ETH_NETMASK_ADDR2 255 +#define ETH_NETMASK_ADDR3 0 +#endif + +/*Gateway address for ethernet*/ +#ifndef ETH_GW_ADDR0 +#define ETH_GW_ADDR0 192 +#define ETH_GW_ADDR1 168 +#define ETH_GW_ADDR2 0 +#define ETH_GW_ADDR3 1 +#endif + +/* Private define ------------------------------------------------------------*/ +#define MAX_DHCP_TRIES 5 + + + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +struct netif xnetif[NET_IF_NUM]; /* network interface structure */ +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes the lwIP stack + * @param None + * @retval None + */ +#if CONFIG_WLAN +extern int error_flag; +extern rtw_mode_t wifi_mode; +#endif + +int lwip_init_done = 0; + +void LwIP_Init(void) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + int8_t idx = 0; + + /* Create tcp_ip stack thread */ + tcpip_init( NULL, NULL ); + + /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, + struct ip_addr *netmask, struct ip_addr *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use.*/ + //printf("NET_IF_NUM:%d\n\r",NET_IF_NUM); + for(idx=0;idx 1) + idx = 1; +#endif + + pnetif = &xnetif[idx]; + if(DHCP_state == 0){ + pnetif->ip_addr.addr = 0; + pnetif->netmask.addr = 0; + pnetif->gw.addr = 0; + } + + for (;;) + { + //printf(" ========DHCP_state:%d============\n",DHCP_state); + switch (DHCP_state) + { + case DHCP_START: + { +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + dhcp_start(pnetif); + IPaddress = 0; + DHCP_state = DHCP_WAIT_ADDRESS; + } + break; + + case DHCP_WAIT_ADDRESS: + { + /* If DHCP stopped by wifi_disconn_hdl*/ + if(pnetif->dhcp->state == 0) + { + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); + printf("LwIP_DHCP: dhcp stop.\n"); + return DHCP_STOP; + } + + /* Read the new IP address */ + IPaddress = pnetif->ip_addr.addr; + + if (IPaddress!=0) + { + DHCP_state = DHCP_ADDRESS_ASSIGNED; +#if CONFIG_WLAN + wifi_reg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl, NULL); +#endif + + /* Stop DHCP */ + // dhcp_stop(pnetif); /* can not stop, need to renew, Robbie*/ + + iptab[0] = (uint8_t)(IPaddress >> 24); + iptab[1] = (uint8_t)(IPaddress >> 16); + iptab[2] = (uint8_t)(IPaddress >> 8); + iptab[3] = (uint8_t)(IPaddress); + printf("Interface %d IP address : %d.%d.%d.%d\n", idx, iptab[3], iptab[2], iptab[1], iptab[0]); +// printf("Time at start %d ms.\n", xTaskGetTickCount()); +#if CONFIG_WLAN + error_flag = RTW_NO_ERROR; +#endif + return DHCP_ADDRESS_ASSIGNED; + } + else + { + /* DHCP timeout */ + if (pnetif->dhcp->tries > MAX_DHCP_TRIES) + { + DHCP_state = DHCP_TIMEOUT; + + /* Stop DHCP */ + dhcp_stop(pnetif); + + /* Static address used */ + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); + + iptab[0] = IP_ADDR3; + iptab[1] = IP_ADDR2; + iptab[2] = IP_ADDR1; + iptab[3] = IP_ADDR0; + printf("Interface %d DHCP timeout\n",idx); + printf("Static IP address : %d.%d.%d.%d\n", iptab[3], iptab[2], iptab[1], iptab[0]); +#if CONFIG_WLAN + error_flag = RTW_DHCP_FAIL; +#endif + +#if CONFIG_ETHERNET + if(idx == NET_IF_NUM -1) // This is the ethernet interface, set it up for static ip address + netif_set_up(pnetif); +#endif + return DHCP_TIMEOUT; + }else + { + //sys_msleep(DHCP_FINE_TIMER_MSECS); + vTaskDelay(DHCP_FINE_TIMER_MSECS); + dhcp_fine_tmr(); + mscnt += DHCP_FINE_TIMER_MSECS; + if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) + { + dhcp_coarse_tmr(); + mscnt = 0; + } + } + } + } + break; + case DHCP_RELEASE_IP: +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + printf("LwIP_DHCP: Release ip\n"); + dhcp_release_unicast(pnetif); + return DHCP_RELEASE_IP; + case DHCP_STOP: +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + printf("LwIP_DHCP: dhcp stop.\n"); + dhcp_stop(pnetif); + return DHCP_STOP; + default: + break; + } + + } +} + +void LwIP_ReleaseIP(uint8_t idx) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif *pnetif = &xnetif[idx]; + + IP4_ADDR(&ipaddr, 0, 0, 0, 0); + IP4_ADDR(&netmask, 255, 255, 255, 0); + IP4_ADDR(&gw, 0, 0, 0, 0); + + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); +} + +uint8_t* LwIP_GetMAC(struct netif *pnetif) +{ + return (uint8_t *) (pnetif->hwaddr); +} + +uint8_t* LwIP_GetIP(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->ip_addr); +} + +uint8_t* LwIP_GetGW(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->gw); +} + +uint8_t* LwIP_GetMASK(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->netmask); +} + +uint8_t* LwIP_GetBC(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->dhcp->offered_bc_addr); +} + +#if LWIP_DNS +void LwIP_GetDNS(struct ip_addr* dns) +{ + *dns = dns_getserver(0); +} + +void LwIP_SetDNS(struct ip_addr* dns) +{ + dns_setserver(0, dns); +} +#endif +void LwIP_UseStaticIP(struct netif *pnetif) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + /* Static address used */ + if(pnetif->name[1] == '0'){ +#if CONFIG_WLAN + if(wifi_mode == RTW_MODE_STA){ + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + } + else if(wifi_mode == RTW_MODE_AP){ + IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3); + IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3); + IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3); + } +#endif + }else{ + IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3); + IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3); + IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3); + } + + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); +} +#if LWIP_AUTOIP +#include + +void LwIP_AUTOIP(struct netif *pnetif) +{ + uint8_t *ip = LwIP_GetIP(pnetif); + + autoip_start(pnetif); + + while((pnetif->autoip->state == AUTOIP_STATE_PROBING) || (pnetif->autoip->state == AUTOIP_STATE_ANNOUNCING)) { + vTaskDelay(1000); + } + + if(*((uint32_t *) ip) == 0) { + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + printf("AUTOIP timeout\n"); + + /* Static address used */ + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); + printf("Static IP address : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + } + else { + printf("Link-local address: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + } +} +#endif +#if LWIP_IPV6 +/* Get IPv6 address with lwip 1.5.0 */ +void LwIP_AUTOIP_IPv6(struct netif *pnetif) +{ + uint8_t *ipv6 = (uint8_t *) &(pnetif->ip6_addr[0].addr[0]); + + netif_create_ip6_linklocal_address(pnetif, 1); + printf("IPv6 link-local address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", + ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7], + ipv6[8], ipv6[9], ipv6[10], ipv6[11], ipv6[12], ipv6[13], ipv6[14], ipv6[15]); +} +#endif diff --git a/USDK/component/common/api/lwip_netconf.h b/USDK/component/common/api/lwip_netconf.h new file mode 100644 index 0000000..8ac0e46 --- /dev/null +++ b/USDK/component/common/api/lwip_netconf.h @@ -0,0 +1,91 @@ +/** + ****************************************************************************** + * @file netconf.h + * @author MCD Application Team + * @version V1.1.0 + * @date 07-October-2011 + * @brief This file contains all the functions prototypes for the netconf.c + * file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __NETCONF_H +#define __NETCONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "tcpip.h" +/* Includes ------------------------------------------------------------------*/ +#include +#include "platform_opts.h" +#include "autoconf.h" + +// macros +/* Give default value if not defined */ +#ifndef NET_IF_NUM + #ifdef CONFIG_CONCURRENT_MODE + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1) + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN)) + #endif // end of CONFIG_CONCURRENT_MODE +#endif // end of NET_IF_NUM + +/* Private typedef -----------------------------------------------------------*/ +typedef enum +{ + DHCP_START=0, + DHCP_WAIT_ADDRESS, + DHCP_ADDRESS_ASSIGNED, + DHCP_RELEASE_IP, + DHCP_STOP, + DHCP_TIMEOUT +} DHCP_State_TypeDef; + +/* Extern functions ------------------------------------------------------------*/ +void wifi_rx_beacon_hdl( char* buf, int buf_len, int flags, void* userdata); + + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void LwIP_Init(void); +uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state); +unsigned char* LwIP_GetMAC(struct netif *pnetif); +unsigned char* LwIP_GetIP(struct netif *pnetif); +unsigned char* LwIP_GetGW(struct netif *pnetif); +uint8_t* LwIP_GetMASK(struct netif *pnetif); +uint8_t* LwIP_GetBC(struct netif *pnetif); +#if LWIP_DNS +void LwIP_GetDNS(struct ip_addr* dns); +void LwIP_SetDNS(struct ip_addr* dns); +#endif +void LwIP_UseStaticIP(struct netif *pnetif); +#if LWIP_AUTOIP +void LwIP_AUTOIP(struct netif *pnetif); +#endif +#if LWIP_IPV6 +void LwIP_AUTOIP_IPv6(struct netif *pnetif); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONF_H */ + + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/USDK/component/common/api/lwip_netconf1.c b/USDK/component/common/api/lwip_netconf1.c new file mode 100644 index 0000000..903bd59 --- /dev/null +++ b/USDK/component/common/api/lwip_netconf1.c @@ -0,0 +1,405 @@ +/* Includes ------------------------------------------------------------------*/ +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/dhcp.h" +#include "lwip/dns.h" +#include "ethernetif.h" +#include "main.h" +#include "lwip_netconf.h" +#if CONFIG_WLAN +#include "wifi_ind.h" +#endif +#if defined(STM32F2XX) +#include "stm322xg_eval_lcd.h" +#elif defined(STM32F4XX) +#include "stm324xg_eval_lcd.h" +#endif +#include + + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 1 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 1 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +/*Static IP ADDRESS FOR ETHERNET*/ +#ifndef ETH_IP_ADDR0 +#define ETH_IP_ADDR0 192 +#define ETH_IP_ADDR1 168 +#define ETH_IP_ADDR2 0 +#define ETH_IP_ADDR3 80 +#endif + +/*NETMASK FOR ETHERNET*/ +#ifndef ETH_NETMASK_ADDR0 +#define ETH_NETMASK_ADDR0 255 +#define ETH_NETMASK_ADDR1 255 +#define ETH_NETMASK_ADDR2 255 +#define ETH_NETMASK_ADDR3 0 +#endif + +/*Gateway address for ethernet*/ +#ifndef ETH_GW_ADDR0 +#define ETH_GW_ADDR0 192 +#define ETH_GW_ADDR1 168 +#define ETH_GW_ADDR2 0 +#define ETH_GW_ADDR3 1 +#endif + +/* Private define ------------------------------------------------------------*/ +#define MAX_DHCP_TRIES 5 + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +struct netif xnetif[NET_IF_NUM]; /* network interface structure */ +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes the lwIP stack + * @param None + * @retval None + */ +#if CONFIG_WLAN +extern char error_flag; +extern unsigned char wifi_mode; // rtw_mode_t +#endif + +int lwip_init_done = 0; + +void LwIP_Init(void) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + int8_t idx = 0; + /* Create tcp_ip stack thread */ + tcpip_init( NULL, NULL ); + + /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, + struct ip_addr *netmask, struct ip_addr *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use.*/ + //printf("NET_IF_NUM:%d\n\r",NET_IF_NUM); + for(idx = NET_IF_NUM - 1; idx >= 0 ; idx--) { + if(idx == 0){ + IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + } +#if CONFIG_ETHERNET + else if(idx == NET_IF_NUM - 1) + { + IP4_ADDR(&ipaddr, ETH_IP_ADDR0, ETH_IP_ADDR1, ETH_IP_ADDR2, ETH_IP_ADDR3); + IP4_ADDR(&netmask, ETH_NETMASK_ADDR0, ETH_NETMASK_ADDR1 , ETH_NETMASK_ADDR2, ETH_NETMASK_ADDR3); + IP4_ADDR(&gw, ETH_GW_ADDR0, ETH_GW_ADDR1, ETH_GW_ADDR2, ETH_GW_ADDR3); + } +#endif + else { + IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3); + IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3); + IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3); + } + xnetif[idx].name[0] = 'r'; + xnetif[idx].name[1] = '0'+idx; + +#if CONFIG_ETHERNET + if(idx == NET_IF_NUM - 1) + netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, ðernetif_mii_init, &tcpip_input); + else + netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); +#else + netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); +#endif + info_printf("interface %d is initialized\n", idx); + } + + /* Registers the default network interface. */ + netif_set_default(&xnetif[0]); + + /* When the netif is fully configured this function must be called.*/ + for(idx = 0; idx < NET_IF_NUM; idx++) + netif_set_up(&xnetif[idx]); + + lwip_init_done = 1; +} + +/** + * @brief LwIP_DHCP_Process_Handle + * @param None + * @retval None + */ +uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state) { + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + uint32_t IPaddress; + uint8_t iptab[4]; + uint8_t DHCP_state; + int mscnt = 0; + struct netif *pnetif = NULL; + + DHCP_state = dhcp_state; + +#if !CONFIG_ETHERNET + if (idx > 1) + idx = 1; +#endif + + pnetif = &xnetif[idx]; + if (DHCP_state == 0) { + pnetif->ip_addr.addr = 0; + pnetif->netmask.addr = 0; + pnetif->gw.addr = 0; + } + + for (;;) { + //info_printf("\n\r ========DHCP_state:%d============\n\r",DHCP_state); + switch (DHCP_state) { + case DHCP_START: { +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + dhcp_start(pnetif); + IPaddress = 0; + DHCP_state = DHCP_WAIT_ADDRESS; + } + break; + + case DHCP_WAIT_ADDRESS: { + /* Read the new IP address */ + IPaddress = pnetif->ip_addr.addr; + + if (IPaddress != 0) { + DHCP_state = DHCP_ADDRESS_ASSIGNED; +#if CONFIG_WLAN + wifi_reg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl, NULL); +#endif + + /* Stop DHCP */ + // dhcp_stop(pnetif); /* can not stop, need to renew, Robbie*/ + iptab[0] = (uint8_t) (IPaddress >> 24); + iptab[1] = (uint8_t) (IPaddress >> 16); + iptab[2] = (uint8_t) (IPaddress >> 8); + iptab[3] = (uint8_t) (IPaddress); + info_printf("Interface %d IP address: %d.%d.%d.%d\n", idx, iptab[3], + iptab[2], iptab[1], iptab[0]); +#if CONFIG_WLAN + error_flag = RTW_NO_ERROR; +#endif + return DHCP_ADDRESS_ASSIGNED; + } else { + /* DHCP timeout */ + if (pnetif->dhcp->tries > MAX_DHCP_TRIES) { + DHCP_state = DHCP_TIMEOUT; + + /* Stop DHCP */ + dhcp_stop(pnetif); + + /* Static address used */ + IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask, &gw); + + iptab[0] = IP_ADDR3; + iptab[1] = IP_ADDR2; + iptab[2] = IP_ADDR1; + iptab[3] = IP_ADDR0; + info_printf("Interface %d DHCP timeout\n", idx); + info_printf("Static IP address: %d.%d.%d.%d\n", iptab[3], iptab[2], iptab[1], iptab[0]); +#if CONFIG_WLAN + error_flag = RTW_DHCP_FAIL; +#endif + return DHCP_TIMEOUT; + } else { + //sys_msleep(DHCP_FINE_TIMER_MSECS); + vTaskDelay(DHCP_FINE_TIMER_MSECS); + dhcp_fine_tmr(); + mscnt += DHCP_FINE_TIMER_MSECS; + if (mscnt >= DHCP_COARSE_TIMER_SECS * 1000) { + dhcp_coarse_tmr(); + mscnt = 0; + } + } + } + } + break; + case DHCP_RELEASE_IP: +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + info_printf("LwIP_DHCP(%d): Release ip\n", idx); + dhcp_release_unicast(pnetif); + return DHCP_RELEASE_IP; + case DHCP_STOP: +#if CONFIG_WLAN + wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl); +#endif + info_printf("LwIP_DHCP(%d): dhcp stop.\n", idx); + dhcp_stop(pnetif); + return DHCP_STOP; + default: + break; + } + } +} + +uint8_t* LwIP_GetMAC(struct netif *pnetif) +{ + return (uint8_t *) (pnetif->hwaddr); +} + +uint8_t* LwIP_GetIP(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->ip_addr); +} + +uint8_t* LwIP_GetGW(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->gw); +} + +uint8_t* LwIP_GetMASK(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->netmask); +} + +uint8_t* LwIP_GetBC(struct netif *pnetif) +{ + return (uint8_t *) &(pnetif->dhcp->offered_bc_addr); +} + +#if LWIP_DNS +void LwIP_GetDNS(struct ip_addr* dns) +{ + *dns = dns_getserver(0); +} + +void LwIP_SetDNS(struct ip_addr* dns) +{ + dns_setserver(0, dns); +} +#endif +void LwIP_UseStaticIP(struct netif *pnetif) +{ + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + /* Static address used */ + if(pnetif->name[1] == '0'){ +#if CONFIG_WLAN + if(wifi_mode == RTW_MODE_STA){ + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + } + else if(wifi_mode == RTW_MODE_AP){ + IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3); + IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3); + IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3); + } +#endif + }else{ + IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3); + IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3); + IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3); + } + + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); +} +#if LWIP_AUTOIP +#include + +void LwIP_AUTOIP(struct netif *pnetif) +{ + uint8_t *ip = LwIP_GetIP(pnetif); + + autoip_start(pnetif); + + while((pnetif->autoip->state == AUTOIP_STATE_PROBING) || (pnetif->autoip->state == AUTOIP_STATE_ANNOUNCING)) { + vTaskDelay(1000); + } + + if(*((uint32_t *) ip) == 0) { + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + printf("AUTOIP timeout\n"); + + /* Static address used */ + IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 ); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr , &netmask, &gw); + printf("Static IP address : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + } + else { + printf("Link-local address: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + } +} +#endif +#if LWIP_IPV6 +/* Get IPv6 address with lwip 1.5.0 */ +void LwIP_AUTOIP_IPv6(struct netif *pnetif) +{ + uint8_t *ipv6 = (uint8_t *) &(pnetif->ip6_addr[0].addr[0]); + + netif_create_ip6_linklocal_address(pnetif, 1); + printf("IPv6 link-local address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", + ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7], + ipv6[8], ipv6[9], ipv6[10], ipv6[11], ipv6[12], ipv6[13], ipv6[14], ipv6[15]); +} +#endif diff --git a/USDK/component/common/api/network/include/main_test.h b/USDK/component/common/api/network/include/main_test.h new file mode 100644 index 0000000..c9f3227 --- /dev/null +++ b/USDK/component/common/api/network/include/main_test.h @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------// +#ifndef __MAIN_TEST_H +#define __MAIN_TEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported test functions ------------------------------------------------------- */ +void do_ping_test(char *ip, int size, int count, int interval); +void do_ping_call(char *ip, int loop, int count); +void interactive_question(char *question, char *choice, char *buf, int buf_size); +void start_interactive_mode(void); + +#ifdef __cplusplus + } +#endif + +#endif // __MAIN_TEST_H + +//----------------------------------------------------------------------------// diff --git a/USDK/component/common/api/network/include/netconf.h b/USDK/component/common/api/network/include/netconf.h new file mode 100644 index 0000000..600cd06 --- /dev/null +++ b/USDK/component/common/api/network/include/netconf.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * @file netconf.h + * @author MCD Application Team + * @version V1.1.0 + * @date 07-October-2011 + * @brief This file contains all the functions prototypes for the netconf.c + * file. + ****************************************************************************** + * @attention + * + * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS + * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE + * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY + * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING + * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE + * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. + * + *

© COPYRIGHT 2011 STMicroelectronics

+ ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __NETCONF_H +#define __NETCONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +// TODO: remove this file +#include "lwip_netconf.h" +#if 0 +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +void LwIP_Init(void); +void LwIP_DHCP(void); +#endif +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONF_H */ + + +/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ diff --git a/USDK/component/common/api/network/include/rtl8195a_it.h b/USDK/component/common/api/network/include/rtl8195a_it.h new file mode 100644 index 0000000..8d5cf19 --- /dev/null +++ b/USDK/component/common/api/network/include/rtl8195a_it.h @@ -0,0 +1,8 @@ + +#ifndef __RTL8195A_IT_H_ +#define __RTL8195A_IT_H_ + + +int irq_alloc_wlan(void *contex); + +#endif //__RTL8195A_IT_H_ \ No newline at end of file diff --git a/USDK/component/common/api/network/include/util.h b/USDK/component/common/api/network/include/util.h new file mode 100644 index 0000000..377c9c8 --- /dev/null +++ b/USDK/component/common/api/network/include/util.h @@ -0,0 +1,47 @@ +#ifndef _UTIL_H +#define _UTIL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi_util.h" +#if 0 +typedef enum _WIFI_EVENT_INDICATE{ + WIFI_EVENT_CONNECT = 0, + WIFI_EVENT_DISCONNECT = 1, + WIFI_EVENT_FOURWAY_HANDSHAKE_DONE = 2, +}WIFI_EVENT_INDICATE; +rtw_event_indicate_t + +int wext_get_ssid(const char *ifname, __u8 *ssid); +int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len); +int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value); +int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len); +int wext_get_enc_ext(const char *ifname, __u16 *alg); +int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len); +int wext_get_passphrase(const char *ifname, __u8 *passphrase); +int wext_set_mode(const char *ifname, int mode); +int wext_get_mode(const char *ifname, int *mode); +int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len); +int wext_set_country(const char *ifname, char *country_code); +int wext_get_rssi(const char *ifname, int *rssi); +int wext_set_channel(const char *ifname, __u8 ch); +int wext_get_channel(const char *ifname, __u8 *ch); +int wext_set_scan(const char *ifname, char *buf, __u16 buf_len); +int wext_get_scan(const char *ifname, char *buf, __u16 buf_len); +int wext_mp_command(const char *ifname, char *cmd, int show_msg); +int wext_wifi_priv(const char *ifname, int argc, char **argv); +void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra); +#endif + +#define wext_handshake_done rltk_wlan_handshake_done + +#ifdef __cplusplus +} +#endif + +#endif /* _UTIL_H */ diff --git a/USDK/component/common/api/network/src/ping_test.c b/USDK/component/common/api/network/src/ping_test.c new file mode 100644 index 0000000..a46578c --- /dev/null +++ b/USDK/component/common/api/network/src/ping_test.c @@ -0,0 +1,222 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" + +#include +#if LWIP_SOCKET +#include +#include +#include +#include + +//#define PING_IP "192.168.0.1" +#define PING_IP "192.168.159.1" +#define PING_TO 1000 +#define PING_ID 0xABCD +#define BUF_SIZE 10000 +#define STACKSIZE 1024 + +static unsigned short ping_seq = 0; +static int infinite_loop, ping_count, data_size, ping_interval, ping_call; +static char ping_ip[16]; + +static void generate_ping_echo(unsigned char *buf, int size) +{ + int i; + struct icmp_echo_hdr *pecho; + + for(i = 0; i < size; i ++) { + buf[sizeof(struct icmp_echo_hdr) + i] = (unsigned char) i; + } + + pecho = (struct icmp_echo_hdr *) buf; + ICMPH_TYPE_SET(pecho, ICMP_ECHO); + ICMPH_CODE_SET(pecho, 0); + pecho->chksum = 0; + pecho->id = PING_ID; + pecho->seqno = htons(++ ping_seq); + + //Checksum includes icmp header and data. Need to calculate after fill up icmp header + pecho->chksum = inet_chksum(pecho, sizeof(struct icmp_echo_hdr) + size); +} + +void ping_test(void *param) +//void ping_test() +{ + int i, ping_socket; + int pint_timeout = PING_TO; + struct sockaddr_in to_addr, from_addr; + int from_addr_len = sizeof(struct sockaddr); + int ping_size, reply_size; + unsigned char *ping_buf, *reply_buf; + unsigned int ping_time, reply_time; + struct ip_hdr *iphdr; + struct icmp_echo_hdr *pecho; + + if(data_size > BUF_SIZE){ + printf("[ERROR] %s: data size error, can't exceed %d\n",__func__,BUF_SIZE); + return; + } + + //Ping size = icmp header(8 bytes) + data size + ping_size = sizeof(struct icmp_echo_hdr) + data_size; + + ping_buf = pvPortMalloc(ping_size); + if(NULL == ping_buf){ + printf("[ERROR] %s: Allocate ping_buf failed\n",__func__); + return; + } + + reply_buf = pvPortMalloc(ping_size); + if(NULL == reply_buf){ + vPortFree(ping_buf); + printf("[ERROR] %s: Allocate reply_buf failed\n",__func__); + return; + } + + printf("[%s] PING %s %d(%d) bytes of data\n", __FUNCTION__, ping_ip, data_size, sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr) + data_size); + + for(i = 0; (i < ping_count) || (infinite_loop == 1); i ++) { + ping_socket = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP); +#ifdef CONFIG_LWIP_1_5_0 + struct timeval timeout; + timeout.tv_sec = pint_timeout / 1000; + timeout.tv_usec = pint_timeout % 1000 * 1000; + setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); +#else + setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &pint_timeout, sizeof(pint_timeout)); +#endif + to_addr.sin_len = sizeof(to_addr); + to_addr.sin_family = AF_INET; + to_addr.sin_addr.s_addr = inet_addr(ping_ip); + + generate_ping_echo(ping_buf, data_size); + sendto(ping_socket, ping_buf, ping_size, 0, (struct sockaddr *) &to_addr, sizeof(to_addr)); + + ping_time = xTaskGetTickCount(); + if((reply_size = recvfrom(ping_socket, reply_buf, ping_size, 0, (struct sockaddr *) &from_addr, (socklen_t *) &from_addr_len)) + >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr))) { + + reply_time = xTaskGetTickCount(); + iphdr = (struct ip_hdr *)reply_buf; + pecho = (struct icmp_echo_hdr *)(reply_buf + (IPH_HL(iphdr) * 4)); + + if((pecho->id == PING_ID) && (pecho->seqno == htons(ping_seq))) { + printf("[%s] %d bytes from %s: icmp_seq=%d time=%d ms\n", __FUNCTION__, reply_size - sizeof(struct ip_hdr), inet_ntoa(from_addr.sin_addr), htons(pecho->seqno), (reply_time - ping_time) * portTICK_RATE_MS); + } + } + else + printf("[%s] Request timeout for icmp_seq %d\n", __FUNCTION__, ping_seq); + + close(ping_socket); + vTaskDelay(ping_interval * configTICK_RATE_HZ); + } + + vPortFree(ping_buf); + vPortFree(reply_buf); + + if(!ping_call) + vTaskDelete(NULL); +} + +void do_ping_call(char *ip, int loop, int count) +{ + ping_call = 1; + ping_seq = 0; + data_size = 120; + ping_interval = 1; + infinite_loop = loop; + ping_count = count; + strcpy(ping_ip, ip); + ping_test(NULL); +} + +void cmd_ping(int argc, char **argv) +{ + int argv_count = 2; + + if(argc < 2) + goto Exit; + + //ping cmd default value + infinite_loop = 0; + ping_count = 4; + data_size = 32; + ping_interval = 1; + ping_call = 1; + ping_seq = 0; + + while(argv_count<=argc){ + //first operation + if(argv_count == 2){ + memset(ping_ip, 0, sizeof(ping_ip)); + strncpy(ping_ip, argv[argv_count-1], (strlen(argv[argv_count-1])>16)?16:strlen(argv[argv_count-1])); + argv_count++; + } + else{ + if(strcmp(argv[argv_count-1], "-t") == 0){ + infinite_loop = 1; + argv_count++; + } + else if(strcmp(argv[argv_count-1], "-n") == 0){ + if(argc < (argv_count+1)) + goto Exit; + ping_count = (int) atoi(argv[argv_count]); + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-l") == 0){ + if(argc < (argv_count+1)) + goto Exit; + data_size = (int) atoi(argv[argv_count]); + argv_count+=2; + } + else{ + goto Exit; + } + } + } + + ping_test(NULL); + + return; + +Exit: + printf("[ATWI] Usage: ATWI=[host],[options]\n"); + printf("\t-t\tPing the specified host until stopped\n"); + printf("\t-n\t# Number of echo requests to send (default 4 times)\n"); + printf("\t-l\t# Send buffer size (default 32 bytes)\n"); + printf("\tExample:\n"); + printf("\t\tATWI=192.168.1.2,-n,100,-l,5000\n"); + return; +} + +void do_ping_test(char *ip, int size, int count, int interval) +{ + if((sizeof(struct icmp_echo_hdr) + size) > BUF_SIZE) { + printf("%s BUF_SIZE(%d) is too small\n", __FUNCTION__, BUF_SIZE); + return; + } + + if(ip == NULL) + strcpy(ping_ip, PING_IP); + else + strcpy(ping_ip, ip); + + ping_call = 0; + ping_seq = 0; + data_size = size; + ping_interval = interval; + + if(count == 0) { + infinite_loop = 1; + ping_count = 0; + } + else { + infinite_loop = 0; + ping_count = count; + } + + if(xTaskCreate(ping_test, ((const signed char*)"ping_test"), STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); +} +#endif // LWIP_SOCKET diff --git a/USDK/component/common/api/network/src/rtl8195a_it.c b/USDK/component/common/api/network/src/rtl8195a_it.c new file mode 100644 index 0000000..91c0667 --- /dev/null +++ b/USDK/component/common/api/network/src/rtl8195a_it.c @@ -0,0 +1,110 @@ +#include "rtl8195a.h" +#include +#include "rtl8195a_it.h" + +/* os dependent*/ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + + +#include +#define printf DiagPrintf + +/*-----------------------------Global Variable ---------------------*/ +//#ifdef CONFIG_WLAN +//#ifdef CONFIG_ISR_THREAD_MODE_INTERRUPT +extern xSemaphoreHandle *pExportWlanIrqSemaphore; +//#endif +//#endif + + +#ifdef CONFIG_WLAN +#ifdef CONFIG_ISR_THREAD_MODE_INTERRUPT + +//TODO: chris +#define IRQ_HANDLED 1 +#define IRQ_NONE 0 + +int wlan_Interrupt ( + IN VOID* Data +) +{ +#if 1 + + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + printf("wlan interrupt\n"); + /* This semaphore is initialized once wlan interrupt handler thread is created and initialized*/ + if(!pExportWlanIrqSemaphore) + { + printf("%s(%d)\n", __FUNCTION__, __LINE__); + goto exit; + } + + printf("%s(%d)\n", __FUNCTION__, __LINE__); + xSemaphoreGiveFromISR( *pExportWlanIrqSemaphore, &xHigherPriorityTaskWoken ); + + printf("%s(%d)\n", __FUNCTION__, __LINE__); + /* Switch tasks if necessary. */ + if( xHigherPriorityTaskWoken != pdFALSE ) + { + printf("%s(%d)\n", __FUNCTION__, __LINE__); + portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); + } + +exit: + + return IRQ_HANDLED; +#else + struct dvobj_priv *dvobj = (struct dvobj_priv *)Data; + _adapter *adapter = dvobj->if1; + DBG_8192C("Dma isr\n"); + + if (dvobj->irq_enabled == 0) { + return IRQ_HANDLED; + } +DBG_871X("%s(%d)\n", __FUNCTION__, __LINE__); + if(rtw_hal_interrupt_handler(adapter) == _FAIL) + return IRQ_HANDLED; + //return IRQ_NONE; +DBG_871X("%s(%d)\n", __FUNCTION__, __LINE__); + return IRQ_HANDLED; +#endif + +} + + +VOID +lextra_bus_dma_Interrupt ( + IN VOID* Data +); + + +/* + * This function register interrupt handler and is called by wlan driver + * Return 0 if success, Others if fail + */ + +int irq_alloc_wlan(void *contex) +{ + int ret = 0; + IRQ_HANDLE IrqHandle = {0}; + + printf("Register Interrupt\n"); + IrqHandle.Data = (u32) (contex); + IrqHandle.IrqNum = WL_DMA_IRQ; + IrqHandle.IrqFun = (IRQ_FUN)wlan_Interrupt; + //IrqHandle.IrqFun = (IRQ_FUN)lextra_bus_dma_Interrupt; + IrqHandle.Priority = 0; + + InterruptRegister(&IrqHandle); + InterruptEn(&IrqHandle); + + return ret; + +} +#endif +#endif + diff --git a/USDK/component/common/api/network/src/wlan_network.c b/USDK/component/common/api/network/src/wlan_network.c new file mode 100644 index 0000000..cac209f --- /dev/null +++ b/USDK/component/common/api/network/src/wlan_network.c @@ -0,0 +1,95 @@ +/* + * Hello World + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +#include "main.h" +#include "main_test.h" +#if CONFIG_WLAN +#include "wifi_conf.h" +#include "wlan_intf.h" +#include "wifi_constants.h" +#endif +#include "lwip_netconf.h" +#include +//#include "wifi_interactive_ext.h" + +#ifndef CONFIG_INIT_NET +#define CONFIG_INIT_NET 1 +#endif +#ifndef CONFIG_INTERACTIVE_MODE +#define CONFIG_INTERACTIVE_MODE 1 +#endif + +#define STACKSIZE (512 + 768) + +xSemaphoreHandle uart_rx_interrupt_sema = NULL; + +void init_thread(void *param) +{ + +#if CONFIG_INIT_NET +#if CONFIG_LWIP_LAYER + /* Initilaize the LwIP stack */ + // DBG_8195A("\nLwIP Init\n"); + LwIP_Init(); +#endif +#endif +#if CONFIG_WIFI_IND_USE_THREAD + wifi_manager_init(); +#endif +#if CONFIG_WLAN + // DBG_8195A("\nWiFi_on(RTW_MODE_STA)\n"); + wifi_on(RTW_MODE_STA); +#if CONFIG_AUTO_RECONNECT + //setup reconnection flag +// u8 mode; +// if(wifi_get_autoreconnect(&mode) > 0 && mode != 1) + wifi_set_autoreconnect(1); +#endif +// printf("\n\r%s(%d), Available heap %d\n\r", __FUNCTION__, __LINE__, xPortGetFreeHeapSize()); +#endif + +#if CONFIG_INTERACTIVE_MODE + /* Initial uart rx swmaphore*/ + vSemaphoreCreateBinary(uart_rx_interrupt_sema); + xSemaphoreTake(uart_rx_interrupt_sema, 1/portTICK_RATE_MS); + start_interactive_mode(); +#endif + + /* Kill init thread after all init tasks done */ + vTaskDelete(NULL); +} + +void wlan_network() +{ +#if 0 + { + void *stack_addr = tcm_heap_malloc(STACKSIZE*sizeof(int)); + if(stack_addr == NULL){ + printf("%s: Out of TCM heap!\n", __FUNCTION__); + } + if (xTaskGenericCreate( + init_thread, + (const char *)"init", + STACKSIZE, + NULL, + tskIDLE_PRIORITY + 3 + PRIORITIE_OFFSET, + NULL, + stack_addr, + NULL) != pdTRUE) + printf("%s: xTaskCreate(init_thread) failed\n", __FUNCTION__); + } +#else + if(xTaskCreate(init_thread, ((const char*)"init"), STACKSIZE, NULL, tskIDLE_PRIORITY + 3 + PRIORITIE_OFFSET, NULL) != pdPASS) // +3 + printf("%s: xTaskCreate(init_thread) failed\n", __FUNCTION__); +#endif +} diff --git a/USDK/component/common/api/platform/dlist.h b/USDK/component/common/api/platform/dlist.h new file mode 100644 index 0000000..5fa8dd1 --- /dev/null +++ b/USDK/component/common/api/platform/dlist.h @@ -0,0 +1,262 @@ +#ifndef __LIST_H +#define __LIST_H + +#if defined ( __CC_ARM ) +#ifndef inline +#define inline __inline +#endif +#endif + +/* This file is from Linux Kernel (include/linux/list.h) + * and modified by simply removing hardware prefetching of list items. + * Here by copyright, credits attributed to wherever they belong. + * Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu) + */ + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_del(struct list_head *prev, struct list_head *next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = (void *) 0; + entry->prev = (void *) 0; +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_move - delete from one list and add as another's head + * @list: the entry to move + * @head: the head that will precede our entry + */ +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +/** + * list_move_tail - delete from one list and add as another's tail + * @list: the entry to move + * @head: the head that will follow our entry + */ +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice(struct list_head *list, struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head); +} + +/** + * list_splice_init - join two lists and reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** +* list_first_entry - get the first element from a list +* @ptr: the list head to take the element from. +* @type: the type of the struct this is embedded in. +* @member: the name of the list_head within the struct. +* +* Note, that list is expected to be not empty. +*/ + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); \ + pos = pos->next) +/** + * list_for_each_prev - iterate over a list backwards + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each_prev(pos, head) \ + for (pos = (head)->prev; pos != (head); \ + pos = pos->prev) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop counter. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member, type) \ + for (pos = list_entry((head)->next, type, member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, type, member)) + +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos: the type * to use as a loop counter. + * @n: another type * to use as temporary storage + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member, type) \ + for (pos = list_entry((head)->next, type, member), \ + n = list_entry(pos->member.next, type, member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, type, member)) + +#endif diff --git a/USDK/component/common/api/platform/esp_comp.h b/USDK/component/common/api/platform/esp_comp.h new file mode 100644 index 0000000..e89795c --- /dev/null +++ b/USDK/component/common/api/platform/esp_comp.h @@ -0,0 +1,154 @@ +#ifndef _INCLUDE_ESP_COMP_H_ +#define _INCLUDE_ESP_COMP_H_ + +#include "platform_autoconf.h" +#include "flash_api.h" + +#define ICACHE_FLASH_ATTR +#define ICACHE_RODATA_ATTR +#define DATA_IRAM_ATTR +#define ICACHE_RAM_ATTR + +#define os_printf(...) rtl_printf(__VA_ARGS__) +#define os_printf_plus(...) rtl_printf(__VA_ARGS__) +#define os_sprintf_fd(...) rtl_sprintf(__VA_ARGS__) +#define ets_sprintf(...) rtl_sprintf(__VA_ARGS__) +#ifndef os_malloc +#define os_malloc pvPortMalloc +#define os_zalloc pvPortZalloc +#define os_calloc pvPortCalloc +#define os_realloc pvPortRealloc +#endif +#undef os_free +#define os_free vPortFree +#define system_get_free_heap_size xPortGetFreeHeapSize +#undef os_realloc +#define os_realloc pvPortReAlloc + + +#define os_bzero rtl_bzero +#define os_delay_us wait_us // HalDelayUs +//#define os_install_putc1 rtl_install_putc1 +//#define os_install_putc2 rtl_install_putc2 +//#define os_intr_lock rtl_intr_lock +//#define os_intr_unlock rtl_intr_unlock +//#define os_isr_attach rtl_isr_attach +//#define os_isr_mask rtl_isr_mask +//#define os_isr_unmask rtl_isr_unmask +#define os_memcmp rtl_memcmp +#define os_memcpy rtl_memcpy +#define ets_memcpy rtl_memcpy +#define os_memmove rtl_memmove +#define os_memset rtl_memset +#define os_putc rtl_putc +//#define os_str2macaddr rtl_str2macaddr +//#define os_strcat strcat +#define os_strchr rtl_strchr +#define os_strrchr rtl_strrchr +#define os_strcmp rtl_strcmp +#define os_strcpy rtl_strcpy +#define os_strlen rtl_strlen +#define os_strncmp rtl_strncmp +#define os_strncpy rtl_strncpy +#define os_strstr rtl_strstr +#define os_random Rand + +//extern uint32 phy_get_rand(void); +#define system_get_os_print() 1 + +#ifdef USE_US_TIMER +#define os_timer_arm_us(a, b, c) rtl_timer_arm_new(a, b, c, 0) +#endif + + +//#define os_timer_arm(a, b, c) rtl_timer_arm_new(a, b, c, 1) +//#define os_timer_disarm rtl_timer_disarm +//#define os_timer_init rtl_timer_init +//#define os_timer_setfn rtl_timer_setfn + +//#define os_timer_done rtl_timer_done +//#define os_timer_handler_isr rtl_timer_handler_isr + +//#define os_update_cpu_frequency rtl_update_cpu_frequency + +//#define os_sprintf ets_sprintf +/* +typedef struct{ + uint32_t deviceId; //+00 + uint32_t chip_size; //+04 chip size in byte + uint32_t block_size; //+08 + uint32_t sector_size; //+0c + uint32_t page_size; //+10 + uint32_t status_mask; //+14 +} SpiFlashChip; + +typedef enum { + SPI_FLASH_RESULT_OK, + SPI_FLASH_RESULT_ERR, + SPI_FLASH_RESULT_TIMEOUT +} SpiFlashOpResult; + +extern SpiFlashChip * flashchip; // in RAM-BIOS: 0x3fffc714 +*/ + +// include "flash_api.h" +#define spi_flash_real_size() flash_get_size(&flashobj) +#define Cache_Read_Disable() SpicDisableRtl8195A() +#define Cache_Read_Enable(a, b, c) flash_turnon() + +#define spi_flash_get_id() ((flashobj.SpicInitPara.id[0] << 16) | (flashobj.SpicInitPara.id[1]<<8) | flashobj.SpicInitPara.id[2]) +//SpiFlashOpResult spi_flash_read_status(uint32_t * sta); +//SpiFlashOpResult spi_flash_write_status(uint32_t sta); +#define spi_flash_erase_sector(sec) flash_erase_sector(&flashobj, (sec)<<12) +#define spi_flash_write(faddr, pbuf, size) flash_stream_write(&flashobj, faddr, size, (uint8_t *)pbuf) +#define spi_flash_read(faddr, pbuf, size) flash_stream_read(&flashobj, faddr, size, (uint8_t *)pbuf) +#define spi_flash_erase_block(blk) flash_erase_block(&flashobj, (blk)<<16); + +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ + ip4_addr2_16(ipaddr), \ + ip4_addr3_16(ipaddr), \ + ip4_addr4_16(ipaddr) + +#define IPSTR "%d.%d.%d.%d" + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + + +#ifndef DEBUGSOO +/* CONFIG_DEBUG_LOG: +=0 Off all diag/debug msg, +=1 Only errors, +=2 errors + warning, (default) +=3 errors + warning + info, +=4 errors + warning + info + debug, +=5 full */ +#if CONFIG_DEBUG_LOG > 3 +#define DEBUGSOO (CONFIG_DEBUG_LOG - 1) +#elif CONFIG_DEBUG_LOG > 1 +#define DEBUGSOO 2 +#else +#define DEBUGSOO CONFIG_DEBUG_LOG +#endif +#endif //#ifndef DEBUGSOO + +//#define system_get_sdk_version() "3.5.3" + +//#define system_get_time xTaskGetTickCount +//#define ets_get_cpu_frequency HalGetCpuClk + + +#endif // _INCLUDE_ESP_COMP_H_ diff --git a/USDK/component/common/api/platform/platform_stdlib.h b/USDK/component/common/api/platform/platform_stdlib.h new file mode 100644 index 0000000..6eb2a76 --- /dev/null +++ b/USDK/component/common/api/platform/platform_stdlib.h @@ -0,0 +1,280 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +#ifndef __PLATFORM_STDLIB_H__ +#define __PLATFORM_STDLIB_H__ + +#define USE_CLIB_PATCH 0 +#if defined (__GNUC__) +/* build rom should set USE_RTL_ROM_CLIB=0 */ +#ifndef CONFIG_MBED_ENABLED +#include +#endif +#endif + +#ifdef CONFIG_BUILD_ROM +#define USE_RTL_ROM_CLIB 0 +#else +#define BUFFERED_PRINTF 0 +#ifndef CONFIG_MBED_ENABLED +#define USE_RTL_ROM_CLIB 1 +#else +#define USE_RTL_ROM_CLIB 0 +#endif +#endif + +#if defined(CONFIG_PLATFORM_8195A) +#if defined (__IARSTDLIB__) + #include + #include + #include + #include + #include "diag.h" + + #define strsep(str, delim) _strsep(str, delim) +#else + #include + #include + #include + #include "diag.h" + #include "strproc.h" + #include "basic_types.h" + #include "hal_misc.h" + #if USE_RTL_ROM_CLIB + #include "rtl_lib.h" + #endif + + #undef printf + #undef sprintf + #undef snprintf + #undef atoi + #undef memcmp + #undef memcpy + #undef memset + #undef strcmp + #undef strcpy + #undef strlen + #undef strncmp + #undef strncpy + #undef strsep + #undef strtok + #if USE_RTL_ROM_CLIB + #undef memchr + #undef memmove + #undef strcat + #undef strchr + #undef strncat + #undef strstr + #endif + + #if USE_RTL_ROM_CLIB +#if BUFFERED_PRINTF + extern int buffered_printf(const char* fmt, ...); + #define printf buffered_printf +#else + #define printf rtl_printf +#endif + #define sprintf rtl_sprintf + #define snprintf rtl_snprintf + #define memchr rtl_memchr + #define memcmp rtl_memcmp + #define memcpy rtl_memcpy + #define memmove rtl_memmove + #define memset rtl_memset + #define strcat rtl_strcat + #define strchr rtl_strchr + #define strcmp rtl_strcmp + #define strcpy rtl_strcpy + #define strlen rtl_strlen + #define strncat rtl_strncat + #define strncmp rtl_strncmp + #define strncpy rtl_strncpy + #define strstr rtl_strstr + #define strsep rtl_strsep + #define strtok rtl_strtok + #else + #if USE_CLIB_PATCH + extern int DiagSscanfPatch(const char *buf, const char *fmt, ...); + extern char* DiagStrtokPatch(char *str, const char* delim); + extern char* DiagStrstrPatch(char *string, char *substring); + extern int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...); + extern u32 DiagPrintfPatch(const char *fmt, ...); + extern u32 DiagSPrintfPatch(u8 *buf, const char *fmt, ...); + #define printf DiagPrintfPatch + #define sprintf DiagSPrintfPatch + #define snprintf DiagSnPrintfPatch + #define strstr(a, b) DiagStrstrPatch((char *)(a), (char *)(b)) + #define strtok DiagStrtokPatch + #else + #define printf DiagPrintf + #define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg) + #if defined (__GNUC__) + #define snprintf DiagSnPrintf // NULL function + #define strstr(str1, str2) prvStrStr(str1, str2) // NULL function + #endif + #define strtok(str, delim) _strsep(str, delim) + #endif + #define memcmp(dst, src, sz) _memcmp(dst, src, sz) + #define memcpy(dst, src, sz) _memcpy(dst, src, sz) + #define memset(dst, val, sz) _memset(dst, val, sz) + #define strchr(s, c) _strchr(s, c) // for B-cut ROM + #define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2) + #define strcpy(dest, src) _strcpy(dest, src) + #define strlen(str) prvStrLen((const unsigned char *) str) + #define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt) + #define strncpy(dest, src, count) _strncpy(dest, src, count) + #define strsep(str, delim) _strsep(str, delim) + #endif + + #define atoi(str) prvAtoi(str) + #define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM + + #if USE_CLIB_PATCH + #undef sscanf + #define sscanf DiagSscanfPatch + #else + #if defined (__GNUC__) + #undef sscanf //_sscanf + //extern int DiagSscanfPatch(const char *buf, const char *fmt, ...); + //#define sscanf DiagSscanfPatch + #define sscanf sscanf // use libc sscanf + #endif + #endif +#endif // defined (__IARSTDLIB__) + +// +// memory management +// +#ifndef CONFIG_MBED_ENABLED +extern void *pvPortMalloc( size_t xWantedSize ); +extern void vPortFree( void *pv ); +#define malloc pvPortMalloc +#define zalloc pvPortZalloc +#define free vPortFree +#endif +#elif defined (CONFIG_PLATFORM_8711B) + +#if defined (__IARSTDLIB__) + #include + #include + #include + #include + #include /* va_list */ + #include "diag.h" + + #define strsep(str, delim) _strsep(str, delim) +#else + #include + #include + #include + #include /* va_list */ + #include "diag.h" + #include "strproc.h" + #include "memproc.h" + #include "basic_types.h" +#if USE_RTL_ROM_CLIB + #include "rtl_lib.h" + #include "rom_libc_string.h" +#endif + + #undef printf + #undef sprintf + #undef snprintf + #undef memchr + #undef memcmp + #undef memcpy + #undef memset + #undef memmove + #undef strcmp + #undef strcpy + #undef strlen + #undef strncmp + #undef strncpy + #undef strsep + #undef strtok + #undef strcat + #undef strchr + #undef strncat + #undef strstr + #undef atol + #undef atoi + #undef strpbrk + +#if USE_RTL_ROM_CLIB +#if BUFFERED_PRINTF + extern int buffered_printf(const char* fmt, ...); + #define printf buffered_printf +#else + #define printf rtl_printf +#endif + #define sprintf rtl_sprintf + #define snprintf rtl_snprintf + #define vsnprintf rtl_vsnprintf +#else + #define printf DiagPrintf + #define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg) + #define snprintf DiagSnPrintf // NULL function + #define vsnprintf(buf, size, fmt, ap) VSprintf(buf, fmt, ap) +#endif + #define memchr __rtl_memchr_v1_00 + #define memcmp(dst, src, sz) _memcmp(dst, src, sz) + #define memcpy(dst, src, sz) _memcpy(dst, src, sz) + #define memmove __rtl_memmove_v1_00 + #define memset(dst, val, sz) _memset(dst, val, sz) + + #define strchr(s, c) _strchr(s, c) // for B-cut ROM + #define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2) + #define strcpy(dest, src) _strcpy(dest, src) + #define strlen(str) prvStrLen((const unsigned char *) str) + #define strsep(str, delim) _strsep(str, delim) + #define strstr(str1, str2) prvStrStr(str1, str2) // NULL function + #define strtok(str, delim) prvStrtok(str, delim)//_strsep(str, delim) + #define strcat __rtl_strcat_v1_00 + + #define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt) + #define strncpy(dest, src, count) _strncpy(dest, src, count) + #define strncat __rtl_strncat_v1_00 + + #define atol(str) strtol(str,NULL,10) + #define atoi(str) prvAtoi(str) + #define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM +#if defined (__GNUC__) + #undef sscanf + #define sscanf _sscanf_patch + #define rand Rand +#endif + //extern int _sscanf_patch(const char *buf, const char *fmt, ...); + //#define sscanf _sscanf_patch + + +#endif // defined (__IARSTDLIB__) + +// +// memory management +// +extern void *pvPortMalloc( size_t xWantedSize ); +extern void vPortFree( void *pv ); +#define malloc pvPortMalloc +#define free vPortFree +#elif defined(USE_STM322xG_EVAL) || defined(USE_STM324xG_EVAL) || defined(STM32F10X_XL) + #include + #include + #include + #include +#endif + + +#endif //__PLATFORM_STDLIB_H__ + diff --git a/USDK/component/common/api/platform/stdlib_patch.c b/USDK/component/common/api/platform/stdlib_patch.c new file mode 100644 index 0000000..b95fb86 --- /dev/null +++ b/USDK/component/common/api/platform/stdlib_patch.c @@ -0,0 +1,915 @@ +/* + + this is the c lib patch, It can help when the clib provided by IAR + does not work well. + + How to use this: + 1.You must include platform_stdlib.h in you source file。 + 2.There is a macro USE_CLIB_PATCH in platform_stdlib.h should be opened. + + If there is some problems using this patch, + You'd better check if you code runs into these functions: + + DiagSscanfPatch + DiagStrtokPatch + DiagStrstrPatch + DiagSnPrintfPatch + DiagPrintfPatch + DiagSPrintfPatch + DiagPrintfPatch + DiagSPrintfPatch + DiagSnPrintfPatch + DiagStrstrPatch + DiagStrtokPatch + + */ +#ifndef CONFIG_PLATFORM_8711B + +#include + +#define DiagPutChar HalSerialPutcRtl8195a + +#define IN +#define NULL 0 + +typedef unsigned int size_t; +typedef unsigned int SIZE_T; +typedef unsigned long long u64; +typedef unsigned int u32; +typedef unsigned short int u16; +typedef unsigned char u8; +typedef signed long long s64; +typedef signed int s32; +typedef signed short int s16; +typedef unsigned char bool; + + +extern u8 txt0123456789ABCDEF[16]; +#define tab0123456789ABCDEF txt0123456789ABCDEF // = "0123456789ABCDEF" + + +#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',') +#define ULLONG_MAX (~0ULL) +#define USHRT_MAX ((u16)(~0U)) +#define KSTRTOX_OVERFLOW (1U << 31) +#define SHRT_MAX ((s16)(USHRT_MAX>>1)) + +static inline char _tolower(const char c) +{ + return c | 0x20; +} + + +extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); +extern s64 div_s64(s64 dividend, s32 divisor); +extern inline char _tolower(const char c); +extern u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder); +extern u64 div_u64(u64 dividend, u32 divisor); +extern unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p); +extern const char *_parse_integer_fixup_radix(const char *s, unsigned int *base); +extern char *skip_spaces(const char *str); +extern int skip_atoi(const char **s); +extern void HalSerialPutcRtl8195a(u8 c); + + +static unsigned long long simple_strtoull_patch(const char *cp, char **endp, unsigned int base) +{ + unsigned long long result; + unsigned int rv; + + cp = _parse_integer_fixup_radix(cp, &base); + rv = _parse_integer(cp, base, &result); + + return result; +} + +static long long simple_strtoll_patch(const char *cp, char **endp, unsigned int base) +{ + if(*cp == '-') + return -simple_strtoull_patch(cp + 1, endp, base); + + return simple_strtoull_patch(cp, endp, base); +} +static unsigned long simple_strtoul_patch(const char *cp, char **endp, unsigned int base) +{ + return simple_strtoull_patch(cp, endp, base); +} + +static long simple_strtol_patch(const char *cp, char **endp, unsigned int base) +{ + if(*cp == '-') + return -simple_strtoul_patch(cp + 1, endp, base); + + return simple_strtoul_patch(cp, endp, base); +} + + + + +static int judge_digit_width(const char *str) +{ + + int width = 0; + + while(isdigit(*str)) { + width++; + str++; + } + + return width; +} + + +static int _vsscanf_patch(const char *buf, const char *fmt, va_list args) +{ + const char *str = buf; + char *next; + char digit; + int num = 0; + int i =0; + u8 qualifier; + unsigned int base; + union { + long long s; + unsigned long long u; + } val; + s16 field_width; + bool is_sign; + + char str_store[20] = {0}; + + + + while(*fmt) { + /* skip any white space in format */ + /* white space in format matchs any amount of + * white space, including none, in the input. + */ + if(isspace(*fmt)) { + fmt = skip_spaces(++fmt); + str = skip_spaces(str); + } + + /* anything that is not a conversion must match exactly */ + if(*fmt != '%' && *fmt) { + if(*fmt++ != *str++) { + break; + } + + continue; + } + + if(!*fmt) { + break; + } + + ++fmt; + + /* skip this conversion. + * advance both strings to next white space + */ + if(*fmt == '*') { + if(!*str) { + break; + } + + while(!isspace(*fmt) && *fmt != '%' && *fmt) + fmt++; + + while(!isspace(*str) && *str) + str++; + + continue; + } + + /* get field width */ + field_width = -1; + + if(isdigit(*fmt)) { + + field_width = skip_atoi(&fmt); + + + + if(field_width <= 0) { + + break; + } + } + + /* get conversion qualifier */ + qualifier = -1; + + if(*fmt == 'h' || _tolower(*fmt) == 'l' || + _tolower(*fmt) == 'z') { + qualifier = *fmt++; + + if(qualifier == *fmt) { + if(qualifier == 'h') { + qualifier = 'H'; + fmt++; + } else if(qualifier == 'l') { + qualifier = 'L'; + fmt++; + } + } + } + + if(!*fmt) { + break; + } + + if(*fmt == 'n') { + /* return number of characters read so far */ + *va_arg(args, int *) = str - buf; + ++fmt; + continue; + } + + if(!*str) { + break; + } + + base = 10; + is_sign = 0; + + switch(*fmt++) { + case 'c': { + char *s = (char *)va_arg(args, char*); + + if(field_width == -1) + field_width = 1; + + do { + *s++ = *str++; + } while(--field_width > 0 && *str); + + num++; + } + + continue; + + case 's': { + char *s = (char *)va_arg(args, char *); + + if(field_width == -1) + field_width = SHRT_MAX; + + /* first, skip leading white space in buffer */ + str = skip_spaces(str); + + /* now copy until next white space */ + while(*str && !isspace(*str) && field_width--) { + *s++ = *str++; + } + + *s = '\0'; + num++; + } + + continue; + + case 'o': + base = 8; + break; + + case 'x': + case 'X': + base = 16; + break; + + case 'i': + base = 0; + + case 'd': + is_sign = 1; + + case 'u': + break; + + case '%': + + /* looking for '%' in str */ + if(*str++ != '%') { + return num; + } + + continue; + + default: + /* invalid format; stop here */ + return num; + } + + /* have some sort of integer conversion. + * first, skip white space in buffer. + */ + str = skip_spaces(str); + + digit = *str; + + if(is_sign && digit == '-') + digit = *(str + 1); + + if(!digit + || (base == 16 && !isxdigit(digit)) + || (base == 10 && !isdigit(digit)) + || (base == 8 && (!isdigit(digit) || digit > '7')) + || (base == 0 && !isdigit(digit))) { + break; + } + + //here problem ******************************************* + + + + //troy add ,fix support %2d, but not support %d + if(field_width <= 0) { + + field_width = judge_digit_width(str); + } + + + /////troy add, fix str passed inwidth wrong + for(i = 0; i 0 && next - str > field_width) { + if(base == 0) + _parse_integer_fixup_radix(str, &base); + + while(next - str > field_width) { + if(is_sign) { + val.s = div_s64(val.s, base); + } else { + val.u = div_u64(val.u, base); + } + + --next; + } + } + + switch(qualifier) { + case 'H': /* that's 'hh' in format */ + if(is_sign) + *va_arg(args, signed char *) = val.s; + else + *va_arg(args, unsigned char *) = val.u; + + break; + + case 'h': + if(is_sign) + *va_arg(args, short *) = val.s; + else + *va_arg(args, unsigned short *) = val.u; + + break; + + case 'l': + if(is_sign) + *va_arg(args, long *) = val.s; + else + *va_arg(args, unsigned long *) = val.u; + + break; + + case 'L': + if(is_sign) + *va_arg(args, long long *) = val.s; + else + *va_arg(args, unsigned long long *) = val.u; + + break; + + case 'Z': + case 'z': + *va_arg(args, size_t *) = val.u; + break; + + default: + if(is_sign) + *va_arg(args, int *) = val.s; + else + *va_arg(args, unsigned int *) = val.u; + + break; + } + + num++; + + if(!next) { + break; + } + + str = next; + } + + return num; +} + + +int DiagSscanfPatch(const char *buf, const char *fmt, ...) +{ + va_list args; + int i; + + va_start(args, fmt); + i = _vsscanf_patch(buf, fmt, args); + va_end(args); + + return i; +} + + + +/*********************************************************/ + + + +char* DiagStrtokPatch(char *str, const char* delim) { + static char* _buffer; + + if(str != NULL) _buffer = str; + + if(_buffer[0] == '\0') return NULL; + + char *ret = _buffer, *b; + const char *d; + + for(b = _buffer; *b !='\0'; b++) { + for(d = delim; *d != '\0'; d++) { + if(*b == *d) { + *b = '\0'; + _buffer = b+1; + + // skip the beginning delimiters + if(b == ret) { + ret++; + continue; + } + + return ret; + } + } + } + + return ret; +} + + + +/*********************************************************/ + + + +char *DiagStrstrPatch(char *string, char *substring) +{ + register char *a, *b; + + /* First scan quickly through the two strings looking for a + * single-character match. When it's found, then compare the + * rest of the substring. + */ + + b = substring; + + if(*b == 0) { + return string; + } + + for(; *string != 0; string += 1) { + if(*string != *b) { + continue; + } + + a = string; + + while(1) { + if(*b == 0) { + return string; + } + + if(*a++ != *b++) { + break; + } + } + + b = substring; + } + + return (char *) 0; +} + + + + + +/*********************************************************/ + + + + +int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...) +{ + + va_list ap; + char *p, *s, *buf_end = NULL; + const int *dp = ((const int *)&fmt)+1; + + if(buf == NULL) + return 0; + + + va_start(ap, fmt); + s = buf; + buf_end = size? (buf + size):(char*)~0; + + for(; *fmt != '\0'; ++fmt) { + + if(*fmt != '%') { + *s++ = *fmt; + + if(s >= buf_end) { + goto Exit; + } + + continue; + } + + if(*++fmt == 's') { + for(p = (char *)*dp++; *p != '\0'; p++) { + *s++ = *p; + + if(s >= buf_end) { + goto Exit; + } + } + } + else { /* Length of item is bounded */ + char tmp[20], *q = tmp; + int alt = 0; + int shift = 0;// = 12; + const long *lpforchk = (const long *)dp; + + if((*lpforchk) < 0x10) { + shift = 0; + } + else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) { + shift = 4; + } + else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) { + shift = 8; + } + else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) { + shift = 12; + } + else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) { + shift = 16; + } + else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) { + shift = 20; + } + else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) { + shift = 24; + } + else if((*lpforchk) >= 0x10000000) { + shift = 28; + } + else { + shift = 28; + } + + if((*fmt >= '0') && (*fmt <= '9')) + { + int width; + unsigned char fch = *fmt; + + for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt) + { width = width * 10 + fch - '0'; + } + + shift=(width-1)*4; + } + + /* + * Before each format q points to tmp buffer + * After each format q points past end of item + */ + if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) { + /* With x86 gcc, sizeof(long) == sizeof(int) */ + const long *lp = (const long *)dp; + long h = *lp++; + int hex_count = 0; + unsigned long h_back = h; + int ncase = (*fmt & 0x20); + dp = (const int *)lp; + + if((*fmt == 'p') || (*fmt == 'P')) + alt=1; + + if(alt) { + *q++ = '0'; + *q++ = 'X' | ncase; + } + + while(h_back) { + hex_count += (h_back & 0xF) ? 1 : 0; + h_back = h_back >> 4; + } + + if(shift < (hex_count - 1)*4) + shift = (hex_count - 1)*4; + + for(; shift >= 0; shift -= 4) + *q++ = tab0123456789ABCDEF[(h >> shift) & 0xF] | ncase; + } + else if(*fmt == 'd') { + int i = *dp++; + char *r; + int digit_space = 0; + + + if(i < 0) { + *q++ = '-'; + i = -i; + digit_space++; + } + + p = q; /* save beginning of digits */ + + + do { + *q++ = '0' + (i % 10); + i /= 10; + digit_space++; + } while(i); + + + for(; shift >= 0; shift -= 4) { + + if(digit_space-- > 0) { + ; //do nothing + } else { + *q++ = '0'; + } + } + + /* reverse digits, stop in middle */ + r = q; /* don't alter q */ + + while(--r > p) { + i = *r; + *r = *p; + *p++ = i; + } + } + else if(*fmt == 'c') + *q++ = *dp++; + else + *q++ = *fmt; + + /* now output the saved string */ + for(p = tmp; p < q; ++p) { + *s++ = *p; + + if(s >= buf_end) { + goto Exit; + } + } + } + } + +Exit: + + if(buf) + *s = '\0'; + + va_end(ap); + return(s-buf); + +} + +/*********************************************************/ + +static int VSprintfPatch(char *buf, const char *fmt, const int *dp) +{ + char *p, *s; + s = buf; + + for(; *fmt != '\0'; ++fmt) { + if(*fmt != '%') { + if(buf) { + *s++ = *fmt; + } else { + DiagPutChar(*fmt); + } + + continue; + } + + if(*++fmt == 's') { + for(p = (char *)*dp++; *p != '\0'; p++) { + if(buf) { + *s++ = *p; + } else { + DiagPutChar(*p); + } + } + } + else { /* Length of item is bounded */ + char tmp[20], *q = tmp; + int alt = 0; + int shift = 0;// = 12; + const long *lpforchk = (const long *)dp; + + if((*lpforchk) < 0x10) { + shift = 0; + } + else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) { + shift = 4; + } + else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) { + shift = 8; + } + else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) { + shift = 12; + } + else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) { + shift = 16; + } + else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) { + shift = 20; + } + else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) { + shift = 24; + } + else if((*lpforchk) >= 0x10000000) { + shift = 28; + } + else { + shift = 28; + } + +#if 1 //wei patch for %02x + + if((*fmt >= '0') && (*fmt <= '9')) + { + int width; + unsigned char fch = *fmt; + + for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt) + { width = width * 10 + fch - '0'; + } + + shift=(width-1)*4; + } + +#endif + + /* + * Before each format q points to tmp buffer + * After each format q points past end of item + */ + + if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) { + /* With x86 gcc, sizeof(long) == sizeof(int) */ + const long *lp = (const long *)dp; + long h = *lp++; + int hex_count = 0; + unsigned long h_back = h; + int ncase = (*fmt & 0x20); + dp = (const int *)lp; + + if((*fmt == 'p') || (*fmt == 'P')) + alt=1; + + if(alt) { + *q++ = '0'; + *q++ = 'X' | ncase; + } + + //hback 是实际得到的数据,hex_count是统计数据的HEX字符个数 + while(h_back) { + hex_count += (h_back & 0xF) ? 1 : 0; + h_back = h_back >> 4; + } + + //这里修复 example: 字符有4个,但是用了%02x导致字符被截断的情况 + if(shift < (hex_count - 1)*4) + shift = (hex_count - 1)*4; + + //printf("(%d,%d)", hex_count, shift); + + for(; shift >= 0; shift -= 4) { + + *q++ = tab0123456789ABCDEF[(h >> shift) & 0xF] | ncase; + } + + } + else if(*fmt == 'd') { + int i = *dp++; + char *r; + int digit_space = 0; + + if(i < 0) { + *q++ = '-'; + i = -i; + digit_space++; + } + + p = q; /* save beginning of digits */ + + do { + *q++ = '0' + (i % 10); + i /= 10; + digit_space++; + } while(i); + + //这里修复 example:用了%08d后,在数字前面没有0的情况 + for(; shift >= 0; shift -= 4) { + + if(digit_space-- > 0) { + ; //do nothing + } else { + *q++ = '0'; + } + } + + /* reverse digits, stop in middle */ + r = q; /* don't alter q */ + + while(--r > p) { + i = *r; + *r = *p; + *p++ = i; + } + } + else if(*fmt == 'c') + *q++ = *dp++; + else + *q++ = *fmt; + + /* now output the saved string */ + for(p = tmp; p < q; ++p) { + if(buf) { + *s++ = *p; + } else { + DiagPutChar(*p); + } + + if((*p) == '\n') { + DiagPutChar('\r'); + } + } + } + } + + if(buf) + *s = '\0'; + + return (s - buf); +} + + +int DiagPrintfPatch( + IN const char *fmt, ... +) +{ + return VSprintfPatch(0, fmt, ((const int *)&fmt)+1); +} + +int DiagSPrintfPatch( + IN u8 *buf, + IN const char *fmt, ... +) +{ + return VSprintfPatch((char*)buf, fmt, ((const int *)&fmt)+1); +} +#endif diff --git a/USDK/component/common/api/wifi/rtw_wowlan/dev_wowlan.c b/USDK/component/common/api/wifi/rtw_wowlan/dev_wowlan.c new file mode 100644 index 0000000..b458346 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wowlan/dev_wowlan.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include + +#define CONFIG_WOWLAN_DEV_NT96658 //build for Nova NT96658 +//#define CONFIG_WOWLAN_DEV_OV788 //build for OmniVision OV788 + +#if defined(CONFIG_WOWLAN_DEV_NT96658) && defined(CONFIG_WOWLAN_DEV_OV788) +#error "CONFIG_WOWLAN_DEV_NT96658 and CONFIG_WOWLAN_DEV_OV788 are mutually exclusive. " +#endif + +#ifdef CONFIG_WOWLAN_DEV_NT96658 +#define WOW_WIFI_IN_PIN PE_4 // JTAG pin, so JTAG must be disable before using this pin as wakeup pin +#define WOW_TRIGGER_INTERVAL 500 +#elif defined(CONFIG_WOWLAN_DEV_OV788) +#define WOW_WIFI_IN_PIN PD_5 +#define WOW_WLAN_ON_PIN PB_3 +#define WOW_TRIGGER_INTERVAL 200 +#else +#error "Either CONFIG_WOWLAN_DEV_NT96658 or CONFIG_WOWLAN_DEV_OV788 should be defined, but not both. " +#endif + +//pin assignment for SDIO, default pull high +#define SD_D2 PA_0 +#define SD_D3 PA_1 +#define SD_CMD PA_2 +#define SD_CLK PA_3 +#define SD_D0 PA_4 +#define SD_D1 PA_5 +#define SD_CD PA_6 + +gpio_t wow_gpio_wifi_in; //WOWLAN WAKEUP TRIGGER PORT +gpio_t wow_gpio_wlan_on; //RECORD WOWLAN STATUS: 1:OFF, 0:ON + +int dev_wowlan_init(void){ + WOWLAN_PRINTK("WOWLAN: device init!"); + +#ifdef CONFIG_WOWLAN_DEV_OV788 + // Initial WLAN_ON pin + gpio_init(&wow_gpio_wlan_on, WOW_WLAN_ON_PIN); + gpio_dir(&wow_gpio_wlan_on, PIN_OUTPUT); + gpio_mode(&wow_gpio_wlan_on, PullNone); + gpio_write(&wow_gpio_wlan_on, 1); +#endif + + return 0; +} + +int dev_wowlan_enable(void){ + WOWLAN_PRINTK("WOWLAN: device enable!"); + + // Init WIFI_IN pin (wakeup pin) + gpio_init(&wow_gpio_wifi_in, WOW_WIFI_IN_PIN); + gpio_dir(&wow_gpio_wifi_in, PIN_OUTPUT); + gpio_mode(&wow_gpio_wifi_in, PullNone); + gpio_write(&wow_gpio_wifi_in, 0); + +#ifdef CONFIG_WOWLAN_DEV_OV788 + gpio_write(&wow_gpio_wlan_on, 0); +#endif + +#if CONFIG_WLAN + wifi_set_power_mode(0xff, 1); +#endif + + return 0; +} + +int dev_wowlan_wakeup_process(void){ + WOWLAN_PRINTK("WOWLAN: device wake up!"); + +#if defined(CONFIG_WOWLAN_DEV_NT96658) || defined(CONFIG_WOWLAN_DEV_OV788) +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + //acquire wakelock to keep system awake + acquire_wakelock(WAKELOCK_SDIO_DEVICE); +#endif +#endif + +#ifdef CONFIG_WOWLAN_DEV_OV788 + //record wowlan status + gpio_write(&wow_gpio_wlan_on, 1); +#endif + +#if defined(CONFIG_WOWLAN_DEV_NT96658) + //restore SDIO pin status for bus communication + pin_mode(SD_D0, PullUp); + pin_mode(SD_D1, PullUp); + pin_mode(SD_D2, PullUp); + pin_mode(SD_D3, PullUp); + pin_mode(SD_CMD, PullUp); + pin_mode(SD_CLK, PullDown); +#endif + + //send signal to awake host + gpio_write(&wow_gpio_wifi_in, 0); + wowlan_mdelay_os(WOW_TRIGGER_INTERVAL); + gpio_write(&wow_gpio_wifi_in, 1); + wowlan_mdelay_os(WOW_TRIGGER_INTERVAL); + gpio_write(&wow_gpio_wifi_in, 0); + wowlan_mdelay_os(WOW_TRIGGER_INTERVAL); + + return 0; +} + +int dev_wowlan_sleep_process(void){ + +#if defined(CONFIG_WOWLAN_DEV_NT96658) + //pull control for SDIO pin only when host is already power off + if(rtw_wowlan_is_enabled() && (rtw_wowlan_get_wk_reason() == 0)){ + WOWLAN_PRINTK("pull control"); + //configure SDIO pin status for avoiding current leakage + pin_mode(SD_D0, PullNone); + pin_mode(SD_D1, PullNone); + pin_mode(SD_D2, PullNone); + pin_mode(SD_D3, PullNone); + pin_mode(SD_CMD, PullNone); + pin_mode(SD_CLK, PullNone); + } +#endif + + return 0; +} + +int dev_wowlan_disable(void){ + WOWLAN_PRINTK("WOWLAN: device disable!"); + +#if CONFIG_WLAN + wifi_set_power_mode(0xff, 0); +#endif + +#ifdef CONFIG_WOWLAN_DEV_OV788 + gpio_write(&wow_gpio_wlan_on, 1); +#endif + + return 0; +} + +void dev_wowlan_ops_init(void *dev_ops){ + struct rtw_wowlan_ops *ops = (struct rtw_wowlan_ops *)dev_ops; + WOWLAN_PRINTK("WOWLAN: device ops init!"); + ops->DevWowlanInit = dev_wowlan_init; + ops->DevWowlanEnable = dev_wowlan_enable; + ops->DevWowlanDisable = dev_wowlan_disable; + ops->DevWowlanWakeUp = dev_wowlan_wakeup_process; + ops->DevWowlanSleep = dev_wowlan_sleep_process; +} diff --git a/USDK/component/common/api/wifi/rtw_wowlan/wifi_wowlan.h b/USDK/component/common/api/wifi/rtw_wowlan/wifi_wowlan.h new file mode 100644 index 0000000..82355fe --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wowlan/wifi_wowlan.h @@ -0,0 +1,381 @@ +#ifndef _WIFI_WOWLAN_H_ +#define _WIFI_WOWLAN_H_ + +#include +#include +#include +#include + +#define WOWLAN_DBG 1 + +enum{ + WOWLAN_DBG_OFF = 0, + WOWLAN_DBG_ALWAYS, + WOWLAN_DBG_ERROR, + WOWLAN_DBG_WARNING, + WOWLAN_DBG_INFO +}; + +#if WOWLAN_DBG + //#define WOWLAN_DUMP_MSG + #define WOWLAN_DUMP_MSG_1 //dump packet when setting + static unsigned char gWowlanDbgLevel = WOWLAN_DBG_ERROR; + #define WOWLAN_PRINTK(fmt, args...) printf(fmt"\r\n",## args) + #define _WOWLAN_PRINTK(fmt, args...) printf(fmt,## args) + #define WOWLAN_DBG_MSG(level, fmt, args...) \ + do{ \ + if(level <= gWowlanDbgLevel){ \ + WOWLAN_PRINTK(fmt,## args); \ + } \ + }while(0) +#else + #define WOWLAN_PRINTK(fmt, args...) + #define WOWLAN_DBG_MSG(level, fmt, args...) +#endif + +#ifndef u8 +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +#endif + +#ifndef BIT +#define BIT(x) ((u32)1 << (x)) +#endif + +#ifndef le16_to_cpu //need a general definition for the whole system +#define cpu_to_le32(x) ((u32)(x)) +#define le32_to_cpu(x) ((u32)(x)) +#define cpu_to_le16(x) ((u16)(x)) +#define le16_to_cpu(x) ((u16)(x)) +#endif + +#ifndef IP_FMT +#define IP_FMT "%d.%d.%d.%d" +#endif + +#ifndef IP_ARG +#define IP_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3] +#endif + +#ifndef MAC_FMT +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#ifndef MAC_ARG +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] +#endif + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif + +#ifndef ethhdr +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; +#endif + +#ifndef wowlan_memcpy + #define wowlan_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n)) +#endif + +#ifndef wowlan_malloc + #define wowlan_malloc(sz) rtw_malloc(sz) +#endif + +#ifndef wowlan_zmalloc + #define wowlan_zmalloc(sz) rtw_zmalloc(sz) +#endif + +#ifndef wowlan_memset + #define wowlan_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz) +#endif + +#ifndef wowlan_mfree + #define wowlan_mfree(p, sz) rtw_mfree(((u8*)(p)), (sz)) +#endif + +#ifndef wowlan_memcmp + #define wowlan_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n)) +#endif + +#ifndef wowlan_mdelay_os + #define wowlan_mdelay_os(ms) rtw_mdelay_os(ms) +#endif + +/*Mutex services*/ +typedef _mutex _wowlock; + +__inline static void _init_wowlock(_wowlock *plock) +{ + rtw_mutex_init(plock); +} + +__inline static void _free_wowlock(_wowlock *plock) +{ + rtw_mutex_free(plock); +} + +__inline static void _enter_wowlock(_wowlock *plock) +{ + rtw_mutex_get(plock); +} + +__inline static void _exit_wowlock(_wowlock *plock) +{ + rtw_mutex_put(plock); +} + +/*Timer services*/ +typedef TimerHandle_t _wowTimer; +#define TMR_AUTO_RELOAD_EN _TRUE +#define TMR_AUTO_RELOAD_DIS _FALSE + +__inline static void +_wowlan_init_timer(_wowTimer *ptimer, void *adapter, TIMER_FUN pfunc,void* cntx, const char *name, u32 auto_reload) +{ + *ptimer = rtw_timerCreate( + (signed const char *)name, // Just a text name, not used by the RTOS kernel. + TIMER_MAX_DELAY, // Timer Period, not 0 + auto_reload, // Whether timer will auto-load themselves when expires + cntx, // Uniq id used to identify which timer expire.. + pfunc // Timer callback + ); +} + +__inline static void +_wowlan_set_timer(_wowTimer *ptimer, u32 delay_time_ms) +{ + if(rtw_timerChangePeriod(*ptimer, rtw_ms_to_systime(delay_time_ms), TIMER_MAX_DELAY) == _FAIL) + WOWLAN_PRINTK("Fail to set timer period"); +} + +__inline static void +_wowlan_cancel_timer(_wowTimer *ptimer) +{ + rtw_timerStop(*ptimer, TIMER_MAX_DELAY); +} + +__inline static void +_wowlan_del_timer(_wowTimer *ptimer) +{ + rtw_timerDelete(*ptimer, TIMER_MAX_DELAY); +} + +__inline static void * +_wowlan_get_timer_cntx(_wowTimer timer) +{ + return pvTimerGetTimerID(timer); +} + +enum rtw_wowlan_wakeup_reason { + RTW_WOWLAN_WAKEUP_BY_PATTERN = BIT(0), + RTW_WOWLAN_WAKEUP_BY_DISCONNECTION = BIT(1), + RTW_WOWLAN_WAKEUP_MAX = 0x7FFFFFFF +}; + +enum rtw_wowlan_cmd_id{ + RTW_WOWLAN_CMD_ENABLE = 0x01, // enable wowlan service + RTW_WOWLAN_CMD_PATTERNS = 0x02, // wowlan pattern setting + RTW_WOWLAN_CMD_PROT_OFFLOAD_CONFIG = 0x03, //ARP offload setting + RTW_WOWLAN_CMD_GET_STATUS = 0x04, // get rtw_wowlan_status + RTW_WOWLAN_CMD_CLEAR_ALL = 0x05, //clear wowlan content + RTW_WOWLAN_CMD_KEEPALIVE = 0x06, //for keep alive packet setting + RTW_WOWLAN_CMD_MAX = 0xff +}; + +#define RTW_WOWLAN_MAX_RX_FILTERS (5) +#define RTW_WOWLAN_RX_FILTER_MAX_FIELDS (8) +#define RTW_WOWLAN_ID_OFFSET (100) //to match some application, ID starts from 100 +#define RTW_WOWLAN_MIN_FILTERS_ID (RTW_WOWLAN_ID_OFFSET) +#define RTW_WOWLAN_MAX_FILTERS_ID (RTW_WOWLAN_ID_OFFSET+RTW_WOWLAN_MAX_RX_FILTERS-1) + +struct rtw_wowlan_rx_filter_field { + u16 offset; + u8 len; + u8 flags; + u8 *mask; + u8 *pattern; +}; + +struct rtw_wowlan_rx_filter { + u8 action; + u8 offset; + u8 num_fields; + struct rtw_wowlan_rx_filter_field fields[RTW_WOWLAN_RX_FILTER_MAX_FIELDS]; +}; + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#else +#error "this structure needs to be packed!" +#endif +struct rtw_wowlan_status { + u32 wakeup_reasons; //record wake up reason + u32 filter_id; //record which pattern is matched +}; +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#else +#error "this structure needs to be packed!" +#endif + +/** + * struct rtw_wowlan_keepalive_packet + * + * @payload_len: data payload length + * @payload: data payload buffer + * @data_interval: interval at which to send data packets +**/ +#define RTW_WOWLAN_MAX_KPALIVE_PKT 3 +#define RTW_WOWLAN_MAX_KPALIVE_PKT_SZ 512 +struct rtw_wowlan_keepalive_packet{ + u8 packet_id; + int payload_len; + u8 *payload; + u32 data_interval; + _wowTimer keepalive_tmr; +}; + +struct rtw_wowlan_ops { + int (*DevWowlanInit)(void); + int (*DevWowlanEnable)(void); + int (*DevWowlanDisable)(void); + int (*DevWowlanWakeUp)(void); + int (*DevWowlanSleep)(void); +}; + +/** + * enum rtw_wowlan_proto_offloads - enabled protocol offloads + * @RTW_WOWLAN_PROTO_OFFLOAD_ARP: ARP data is enabled + */ +enum rtw_wowlan_proto_offloads { + RTW_WOWLAN_PROTO_OFFLOAD_ARP = BIT(0), + RTW_WOWLAN_PROTO_OFFLOAD_MAX = 0x7FFFFFFF +}; + +/** + * struct rtw_wowlan_proto_offload_common - ARP/NS offload common part + * @enabled: enable flags + * @remote_ipv4_addr: remote address to answer to (or zero if all) + * @host_ipv4_addr: our IPv4 address to respond to queries for + * @arp_mac_addr: our MAC address for ARP responses + * @reserved: unused + */ +struct rtw_wowlan_proto_offload_common{ + int proto_enabled; + u32 remote_ipv4_addr; + u32 host_ipv4_addr; + u8 host_mac_addr[ETH_ALEN]; + u16 reserved; +}; + +struct rtw_wowlan { + _wowlock wow_mutex; + bool enabled; + struct rtw_wowlan_status status; + struct rtw_wowlan_ops ops; + struct rtw_wowlan_proto_offload_common proto; + bool proto_offload_enabled; + struct rtw_wowlan_rx_filter *rx_filter[RTW_WOWLAN_MAX_RX_FILTERS]; + bool rx_filter_enabled[RTW_WOWLAN_MAX_RX_FILTERS];/* RX Data filter rule state - enabled/disabled */ + struct rtw_wowlan_keepalive_packet *tx_keepalive[RTW_WOWLAN_MAX_KPALIVE_PKT]; + bool tx_keepalive_enabled[RTW_WOWLAN_MAX_KPALIVE_PKT];/* TX keep avlive rule state - enabled/disabled */ +}; + +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define cpIpAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3]) + +#define RTW_WOWLAN_GET_ARP_PKT_OPERATION(__pHeader) ReadEF2Byte( ((u8*)(__pHeader)) + 6) +#define RTW_WOWLAN_GET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+8) +#define RTW_WOWLAN_GET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+14) +#define RTW_WOWLAN_GET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+18) +#define RTW_WOWLAN_GET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+24) + +#define RTW_WOWLAN_SET_ARP_PKT_HW(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 0, __Value) +#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 2, __Value) +#define RTW_WOWLAN_SET_ARP_PKT_HW_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 4, __Value) +#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 5, __Value) +#define RTW_WOWLAN_SET_ARP_PKT_OPERATION(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 6, __Value) +#define RTW_WOWLAN_SET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+8, (u8*)(_val)) +#define RTW_WOWLAN_SET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+14, (u8*)(_val)) +#define RTW_WOWLAN_SET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+18, (u8*)(_val)) +#define RTW_WOWLAN_SET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+24, (u8*)(_val)) + +#define RTW_WOWLAN_ARP_PKT_LEN 0x2A +#define RTW_WOWLAN_ARP_PKT_OPERATION_REQ 0x0100 //arp request +#define RTW_WOWLAN_ARP_PKT_OPERATION_RSP 0x0200 //arp response + +extern u8 key_2char2num(u8 hch, u8 lch); +extern _LONG_CALL_ void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader); +#define rtw_wowlan_DumpForBytes(pData, Len) __rtl_memDump_v1_00(pData, Len, NULL) + +#define PWOWLAN_TO_STATUS(pwowlan) (&pwowlan->status) +#define PWOWLAN_TO_OPS(pwowlan) (&pwowlan->ops) +#define PWOWLAN_TO_PROTO(pwowlan) (&pwowlan->proto) +#define PWOWLAN_TO_RX_FILTER(pwowlan) (pwowlan->rx_filter) +#define PWOWLAN_TO_TX_KEEPALIVE(pwowlan) (pwowlan->tx_keepalive) + +/** + * rtw_wowlan_init: initialize wowlan service + * arg: None + * return: _SUCCESS or _FAIL + */ +extern int rtw_wowlan_init(void); + +/** + * cmd_wowlan_service: input commands to configure wowlan service + * arg: + * @argc: number of input parameter + * @argv: content of input string + * return: None + */ +extern void cmd_wowlan_service(int argc, char **argv); + +/** + * rtw_wowlan_process_rx_packet: entry for packet process in wowlan service once it starts + * arg: + * @rx_pkt: receive packet from wlan/ethernet + * @pkt_len: receive packet length + * return: _SUCCESS or _FAIL + */ +extern int rtw_wowlan_process_rx_packet(char *rx_pkt, u16 pkt_len); + +/** + * rtw_wowlan_wakeup_process: wake up process once the reasons are matched, + * refer to enum rtw_wowlan_wakeup_reason + * arg: + * @reason: wake up reason, refer to enum rtw_wowlan_wakeup_reason + * return: None + */ +extern void rtw_wowlan_wakeup_process(int reason); + +/** + * rtw_wowlan_is_enabled: if wowlan service is already enabled + * this function is called in rx path and wifi_inidication when wowlan service is running + * arg: None + * return: _True if enable or _False if disable + */ +extern int rtw_wowlan_is_enabled(void); + +/** + * rtw_wowlan_get_wk_reason: query wake up reason, refer to enum rtw_wowlan_wakeup_reason + * arg: None + * return: wakeup_reason + */ +extern int rtw_wowlan_get_wk_reason(void); + +/** + * rtw_wowlan_dev_sleep: sleep process on Ameba side, pull control for example + * this function is linked to dev_wowlan_sleep_process() in dev_wowlan.c + * arg: None + * return: None + */ +extern void rtw_wowlan_dev_sleep(void); + +#endif diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os.h b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os.h new file mode 100644 index 0000000..2a0a4a7 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os.h @@ -0,0 +1,593 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef OS_H +#define OS_H + +//#include "basic_types.h" +#include +#include "osdep_service.h" +#include "freertos/wrapper.h" +#include "utils/rom/rom_wps_os.h" + +typedef void* xqueue_handle_t; + +typedef long os_time_t; + +typedef _timer os_timer; + +/** + * os_sleep - Sleep (sec, usec) + * @sec: Number of seconds to sleep + * @usec: Number of microseconds to sleep + */ +void os_sleep(os_time_t sec, os_time_t usec); + +struct os_time { + os_time_t sec; + os_time_t usec; +}; + +struct os_reltime { + os_time_t sec; + os_time_t usec; +}; + +/** + * os_get_time - Get current time (sec, usec) + * @t: Pointer to buffer for the time + * Returns: 0 on success, -1 on failure + */ +int os_get_time(struct os_time *t); + +int os_get_reltime(struct os_reltime *t); +/* Helper macros for handling struct os_time */ +/* (&timeout->time, &tmp->time) */ +#define os_time_before(a, b) \ + ((a)->sec < (b)->sec || \ + ((a)->sec == (b)->sec && (a)->usec < (b)->usec)) + +#define os_time_sub(a, b, res) do { \ + (res)->sec = (a)->sec - (b)->sec; \ + (res)->usec = (a)->usec - (b)->usec; \ + if ((res)->usec < 0) { \ + (res)->sec--; \ + (res)->usec += 1000000; \ + } \ +} while (0) + +/** + * os_mktime - Convert broken-down time into seconds since 1970-01-01 + * @year: Four digit year + * @month: Month (1 .. 12) + * @day: Day of month (1 .. 31) + * @hour: Hour (0 .. 23) + * @min: Minute (0 .. 59) + * @sec: Second (0 .. 60) + * @t: Buffer for returning calendar time representation (seconds since + * 1970-01-01 00:00:00) + * Returns: 0 on success, -1 on failure + * + * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time + * which is used by POSIX mktime(). + */ +int os_mktime(int year, int month, int day, int hour, int min, int sec, + os_time_t *t); + +struct os_tm { + int sec; /* 0..59 or 60 for leap seconds */ + int min; /* 0..59 */ + int hour; /* 0..23 */ + int day; /* 1..31 */ + int month; /* 1..12 */ + int year; /* Four digit year */ +}; + +int os_gmtime(os_time_t t, struct os_tm *tm); + +/* Helpers for handling struct os_time */ + +/* Helpers for handling struct os_reltime */ + +static inline int os_reltime_before(struct os_reltime *a, + struct os_reltime *b) +{ + return os_time_before(a,b); +} + + +static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b, + struct os_reltime *res) +{ + os_time_sub(a,b,res); +} + + +static inline void os_reltime_age(struct os_reltime *start, + struct os_reltime *age) +{ + struct os_reltime now; + + os_get_time((struct os_time *)&now); + os_reltime_sub(&now, start, age); +} + + +static inline int os_reltime_expired(struct os_reltime *now, + struct os_reltime *ts, + os_time_t timeout_secs) +{ + struct os_reltime age; + + os_reltime_sub(now, ts, &age); + return (age.sec > timeout_secs) || + (age.sec == timeout_secs && age.usec > 0); +} + +/** + * os_daemonize - Run in the background (detach from the controlling terminal) + * @pid_file: File name to write the process ID to or %NULL to skip this + * Returns: 0 on success, -1 on failure + */ +int os_daemonize(const char *pid_file); + +/** + * os_daemonize_terminate - Stop running in the background (remove pid file) + * @pid_file: File name to write the process ID to or %NULL to skip this + */ +void os_daemonize_terminate(const char *pid_file); + +/** + * os_get_random - Get cryptographically strong pseudo random data + * @buf: Buffer for pseudo random data + * @len: Length of the buffer + * Returns: 0 on success, -1 on failure + */ +int os_get_random(unsigned char *buf, size_t len); + +/** + * os_random - Get pseudo random value (not necessarily very strong) + * Returns: Pseudo random value + */ +unsigned long os_random(void); + +/** + * os_rel2abs_path - Get an absolute path for a file + * @rel_path: Relative path to a file + * Returns: Absolute path for the file or %NULL on failure + * + * This function tries to convert a relative path of a file to an absolute path + * in order for the file to be found even if current working directory has + * changed. The returned value is allocated and caller is responsible for + * freeing it. It is acceptable to just return the same path in an allocated + * buffer, e.g., return strdup(rel_path). This function is only used to find + * configuration files when os_daemonize() may have changed the current working + * directory and relative path would be pointing to a different location. + */ +char * os_rel2abs_path(const char *rel_path); + +/** + * os_program_init - Program initialization (called at start) + * Returns: 0 on success, -1 on failure + * + * This function is called when a programs starts. If there are any OS specific + * processing that is needed, it can be placed here. It is also acceptable to + * just return 0 if not special processing is needed. + */ +int os_program_init(void); + +/** + * os_program_deinit - Program deinitialization (called just before exit) + * + * This function is called just before a program exists. If there are any OS + * specific processing, e.g., freeing resourced allocated in os_program_init(), + * it should be done here. It is also acceptable for this function to do + * nothing. + */ +void os_program_deinit(void); + +/** + * os_setenv - Set environment variable + * @name: Name of the variable + * @value: Value to set to the variable + * @overwrite: Whether existing variable should be overwritten + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_setenv(const char *name, const char *value, int overwrite); + +/** + * os_unsetenv - Delete environent variable + * @name: Name of the variable + * Returns: 0 on success, -1 on error + * + * This function is only used for wpa_cli action scripts. OS wrapper does not + * need to implement this if such functionality is not needed. + */ +int os_unsetenv(const char *name); + +/** + * os_readfile - Read a file to an allocated memory buffer + * @name: Name of the file to read + * @len: For returning the length of the allocated buffer + * Returns: Pointer to the allocated buffer or %NULL on failure + * + * This function allocates memory and reads the given file to this buffer. Both + * binary and text files can be read with this function. The caller is + * responsible for freeing the returned buffer with os_free(). + */ +char * os_readfile(const char *name, size_t *len); + +//#if 0 +/** + * os_zalloc - Allocate and zero memory + * @size: Number of bytes to allocate + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_zalloc(size_t size); + +/** + * os_calloc - Allocate and zero memory for an array + * @nmemb: Number of members in the array + * @size: Number of bytes in each member + * Returns: Pointer to allocated and zeroed memory or %NULL on failure + * + * This function can be used as a wrapper for os_zalloc(nmemb * size) when an + * allocation is used for an array. The main benefit over os_zalloc() is in + * having an extra check to catch integer overflows in multiplication. + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +static inline void * os_calloc(size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_zalloc(nmemb * size); +} +//#endif + + +static inline int os_memcmp_const(const void *a, const void *b, size_t len) +{ + const u8 *aa = a; + const u8 *bb = b; + size_t i; + u8 res; + + for (res = 0, i = 0; i < len; i++) + res |= aa[i] ^ bb[i]; + + return res; +} + +/* + * The following functions are wrapper for standard ANSI C or POSIX functions. + * By default, they are just defined to use the standard function name and no + * os_*.c implementation is needed for them. This avoids extra function calls + * by allowing the C pre-processor take care of the function name mapping. + * + * If the target system uses a C library that does not provide these functions, + * build_config.h can be used to define the wrappers to use a different + * function name. This can be done on function-by-function basis since the + * defines here are only used if build_config.h does not define the os_* name. + * If needed, os_*.c file can be used to implement the functions that are not + * included in the C library on the target system. Alternatively, + * OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case + * these functions need to be implemented in os_*.c file for the target system. + */ + +#ifdef OS_NO_C_LIB_DEFINES + +/** + * os_malloc - Allocate dynamic memory + * @size: Size of the buffer to allocate + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +void * os_malloc(size_t size); + +/** + * os_realloc - Re-allocate dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc() + * @size: Size of the new buffer + * Returns: Allocated buffer or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + * If re-allocation fails, %NULL is returned and the original buffer (ptr) is + * not freed and caller is still responsible for freeing it. + */ +void * os_realloc(void *ptr, size_t size); + +/** + * os_free - Free dynamic memory + * @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL + */ +void os_free(void *ptr); + +/** + * os_memcpy - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst must not overlap. os_memmove() can be used with + * overlapping memory. + */ +void * os_memcpy(void *dest, const void *src, size_t n); + +/** + * os_memmove - Copy memory area + * @dest: Destination + * @src: Source + * @n: Number of bytes to copy + * Returns: dest + * + * The memory areas src and dst may overlap. + */ +void *os_memmove(void *dest, const void *src, size_t n); + +/** + * os_memset - Fill memory with a constant byte + * @s: Memory area to be filled + * @c: Constant byte + * @n: Number of bytes started from s to fill with c + * Returns: s + */ +void *os_memset(void *s, int c, size_t n); + +/** + * os_memcmp - Compare memory areas + * @s1: First buffer + * @s2: Second buffer + * @n: Maximum numbers of octets to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_memcmp(const void *s1, const void *s2, size_t n); + +/** + * os_strdup - Duplicate a string + * @s: Source string + * Returns: Allocated buffer with the string copied into it or %NULL on failure + * + * Caller is responsible for freeing the returned buffer with os_free(). + */ +char *os_strdup(const char *s); + +/** + * os_strlen - Calculate the length of a string + * @s: '\0' terminated string + * Returns: Number of characters in s (not counting the '\0' terminator) + */ +size_t os_strlen(const char *s); + +/** + * os_strcasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcasecmp(const char *s1, const char *s2); + +/** + * os_strncasecmp - Compare two strings ignoring case + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncasecmp(const char *s1, const char *s2, size_t n); + +/** + * os_strchr - Locate the first occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char *os_strchr(const char *s, int c); + +/** + * os_strrchr - Locate the last occurrence of a character in string + * @s: String + * @c: Character to search for + * Returns: Pointer to the matched character or %NULL if not found + */ +char *os_strrchr(const char *s, int c); + +/** + * os_strcmp - Compare two strings + * @s1: First string + * @s2: Second string + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greatred than s2 + */ +int os_strcmp(const char *s1, const char *s2); + +/** + * os_strncmp - Compare two strings + * @s1: First string + * @s2: Second string + * @n: Maximum numbers of characters to compare + * Returns: An integer less than, equal to, or greater than zero if s1 is + * found to be less than, to match, or be greater than s2. Only first n + * characters will be compared. + */ +int os_strncmp(const char *s1, const char *s2, size_t n); + +/** + * os_strncpy - Copy a string + * @dest: Destination + * @src: Source + * @n: Maximum number of characters to copy + * Returns: dest + */ +char *os_strncpy(char *dest, const char *src, size_t n); + +/** + * os_strstr - Locate a substring + * @haystack: String (haystack) to search from + * @needle: Needle to search from haystack + * Returns: Pointer to the beginning of the substring or %NULL if not found + */ +char *os_strstr(const char *haystack, const char *needle); + +/** + * os_snprintf - Print to a memory buffer + * @str: Memory buffer to print into + * @size: Maximum length of the str buffer + * @format: printf format + * Returns: Number of characters printed (not including trailing '\0'). + * + * If the output buffer is truncated, number of characters which would have + * been written is returned. Since some C libraries return -1 in such a case, + * the caller must be prepared on that value, too, to indicate truncation. + * + * Note: Some C library implementations of snprintf() may not guarantee null + * termination in case the output is truncated. The OS wrapper function of + * os_snprintf() should provide this guarantee, i.e., to null terminate the + * output buffer if a C library version of the function is used and if that + * function does not guarantee null termination. + * + * If the target system does not include snprintf(), see, e.g., + * http://www.ijs.si/software/snprintf/ for an example of a portable + * implementation of snprintf. + */ +int os_snprintf(char *str, size_t size, const char *format, ...); + +#else /* OS_NO_C_LIB_DEFINES */ + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#ifdef CONFIG_MEM_MONITOR + u8* os_malloc(u32 sz); + void os_mfree(u8 *pbuf, u32 sz); + #ifndef os_free + #define os_free(p, sz) os_mfree(((u8*)(p)), (sz)) + #endif +#else + #ifndef os_malloc + #define os_malloc(sz) _rtw_malloc(sz) + #endif + #ifndef os_free + #define os_free(p, sz) _rtw_mfree(((u8*)(p)), (sz)) + #endif +#endif +#endif + extern void *os_zalloc(size_t size); + extern char *os_strdup(const char *string_copy_from); + + #ifndef os_sleep + #define os_sleep(s, us) rtw_mdelay_os((s)*1000 + (us)/1000) + #endif + #ifndef os_memcpy + #define os_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n)) + #endif + #ifndef os_memmove + #define os_memmove(d, s, n) memmove((d), (s), (n)) + #endif + #ifndef os_memset + #define os_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz) + #endif + #ifndef os_memcmp + #define os_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n)) + #endif + #ifndef os_memcmp_p2p + #define os_memcmp_p2p(s1, s2, n) memcmp((s1), (s2), (n)) + #endif + #ifndef os_get_random_bytes + #define os_get_random_bytes(d,sz) rtw_get_random_bytes(((void*)(d)), (sz)) + #endif + #ifndef os_strlen + #define os_strlen(s) strlen(s) + #endif + #ifndef os_strcasecmp + #ifdef _MSC_VER + #define os_strcasecmp(s1, s2) _stricmp((s1), (s2)) + #else + #define os_strcasecmp(s1, s2) strcasecmp((s1), (s2)) + #endif + #endif + #ifndef os_strncasecmp + #ifdef _MSC_VER + #define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n)) + #else + #define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n)) + #endif + #endif + #ifndef os_init_timer + #define os_init_timer(t, p, f, x, n) rtw_init_timer((t), (p), (f), (x), (n)) + #endif + #ifndef os_set_timer + #define os_set_timer(t, d) rtw_set_timer((t), (d)) + #endif + #ifndef os_cancel_timer + #define os_cancel_timer(t) rtw_cancel_timer(t) + #endif + #ifndef os_del_timer + #define os_del_timer(t) rtw_del_timer(t) + #endif + #ifndef os_atoi + #define os_atoi(s) rtw_atoi(s) + #endif + +#ifndef os_strchr +#define os_strchr(s, c) strchr((s), (c)) +#endif +#ifndef os_strcmp +#define os_strcmp(s1, s2) strcmp((s1), (s2)) +#endif +#ifndef os_strncmp +#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) +#endif +#ifndef os_strncpy +#define os_strncpy(d, s, n) strncpy((d), (s), (n)) +#endif +#ifndef os_strrchr +#define os_strrchr(s, c) strrchr((s), (c)) +#endif +#ifndef os_strstr +#define os_strstr(h, n) strstr((h), (n)) +#endif + +#ifndef os_snprintf + #ifdef _MSC_VER + #define os_snprintf _snprintf + #else + #define os_snprintf snprintf + #endif +#endif + +#endif /* OS_NO_C_LIB_DEFINES */ + + +static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + if (size && nmemb > (~(size_t) 0) / size) + return NULL; + return os_realloc(ptr, nmemb * size, nmemb * size); +} + +void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) ; + +int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait); + +void os_xqueue_delete(xqueue_handle_t xQueue ); + +int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait); + + +#endif /* OS_H */ diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os_freertos.c b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os_freertos.c new file mode 100644 index 0000000..aed28f2 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/os_freertos.c @@ -0,0 +1,119 @@ +/* + * OS specific functions for UNIX/POSIX systems + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ +#include "utils/os.h" + +//#ifdef CONFIG_WPS + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#ifdef CONFIG_MEM_MONITOR +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK +_list wpa_mem_table; +int wpa_mem_used_num; +//int wpa_mem_used_size; +#endif +extern int min_free_heap_size; +u8* os_malloc(u32 sz) +{ + int free_heap_size = rtw_getFreeHeapSize(); + u8 *pbuf = _rtw_malloc(sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + add_mem_usage(&wpa_mem_table, pbuf, sz, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS); +#else + add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WPAS); +#endif + if(min_free_heap_size > free_heap_size) + min_free_heap_size = free_heap_size; + return pbuf; +} + +void os_mfree(u8 *pbuf, u32 sz) +{ + _rtw_mfree(pbuf, sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + del_mem_usage(&wpa_mem_table, pbuf, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS); +#else + del_mem_usage(NULL, pbuf, NULL, MEM_MONITOR_FLAG_WPAS); +#endif +} +#endif//CONFIG_MEM_MONITOR + +#endif// !defined(CONFIG_PLATFORM_8195A) + +#ifndef OS_NO_C_LIB_DEFINES +char *os_strdup(const char *string_copy_from) +{ + char *string_copy_to = NULL; + string_copy_to = os_zalloc(strlen(string_copy_from) + 1); + os_memcpy((void *)string_copy_to, string_copy_from, strlen(string_copy_from)); + string_copy_to[strlen(string_copy_from)] = '\0'; + return string_copy_to; +} +#endif + +int os_get_random(unsigned char *buf, size_t len) +{ + //TODO implement it + rtw_get_random_bytes(buf, len); + return 0; +} + +int os_get_time(struct os_time *t){ + unsigned int tt = rtw_get_current_time(); + t->sec = (os_time_t) (tt / 1000); + t->usec = (os_time_t) (tt % 1000)*1000; + return 0; +} + +int os_get_reltime(struct os_reltime *t){ + os_get_time((struct os_time *)t); + return 0; +} +#if 0 +void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) +{ + return xQueueCreate( uxQueueLength, uxItemSize ); +} + +int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait) +{ + return xQueueReceive((xQueueHandle)xQueue, pvBuffer, (portTickType)(xSecsToWait*configTICK_RATE_HZ)); +} + +void os_xqueue_delete(xqueue_handle_t xQueue ) +{ + vQueueDelete((xQueueHandle)xQueue); +} + +int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait) +{ + return xQueueSendToBack((xQueueHandle)xQueue, pvItemToQueue, (portTickType)(xSecsToWait*configTICK_RATE_HZ)); +} +#else +void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) +{ + void* xQueue = NULL; + rtw_init_xqueue(&xQueue, "queue", uxItemSize, uxQueueLength); + return xQueue; +} + +int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait) +{ + return rtw_pop_from_xqueue(&xQueue, pvBuffer, xSecsToWait*1000); +} + +void os_xqueue_delete(xqueue_handle_t xQueue ) +{ + rtw_deinit_xqueue(&xQueue); +} + +int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait) +{ + return rtw_push_to_xqueue(&xQueue, (void*)pvItemToQueue, xSecsToWait*1000); +} +#endif +//#endif diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/rom/rom_wps_os.h b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/rom/rom_wps_os.h new file mode 100644 index 0000000..cd41061 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/utils/rom/rom_wps_os.h @@ -0,0 +1,24 @@ +/* + * OS specific functions + * Copyright (c) 2005-2009, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef ROM_WPS_OS_H +#define ROM_WPS_OS_H + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + +#include +extern struct _rom_wlan_ram_map rom_wlan_ram_map; +#define os_malloc(sz) rom_wlan_ram_map.rtw_malloc(sz) +#define os_free(p, sz) rom_wlan_ram_map.rtw_mfree(((u8*)(p)), (sz)) + +#endif + +extern u8 *WPS_realloc(u8 *old_buf, u32 old_sz, u32 new_sz); +#define os_realloc(p, os, ns) WPS_realloc(((u8*)(p)),(os),(ns)) + +#endif /* ROM_WPS_OS_H */ diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/wps/wps_defs.h b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/wps/wps_defs.h new file mode 100644 index 0000000..4b408d1 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/src/wps/wps_defs.h @@ -0,0 +1,316 @@ + +/* + * Wi-Fi Protected Setup - message definitions + * Copyright (c) 2008, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef WPS_DEFS_H +#define WPS_DEFS_H + +/* Diffie-Hellman 1536-bit MODP Group; RFC 3526, Group 5 */ +#define WPS_DH_GROUP (5) +#define WPS_UUID_LEN (16) +#define WPS_NONCE_LEN (16) +#define WPS_AUTHENTICATOR_LEN (8) +#define WPS_AUTHKEY_LEN (32) +#define WPS_KEYWRAPKEY_LEN (16) +#define WPS_EMSK_LEN (32) +#define WPS_PSK_LEN (16) +#define WPS_SECRET_NONCE_LEN (16) +#define WPS_HASH_LEN (32) +#define WPS_KWA_LEN (8) +#define WPS_MGMTAUTHKEY_LEN (32) +#define WPS_MGMTENCKEY_LEN (16) +#define WPS_MGMT_KEY_ID_LEN (16) +#define WPS_OOB_DEVICE_PASSWORD_MIN_LEN (16) +#define WPS_OOB_DEVICE_PASSWORD_LEN (32) +#define WPS_OOB_PUBKEY_HASH_LEN (20) + +/* Attribute Types */ +enum wps_attribute { + ATTR_AP_CHANNEL = 0x1001, + ATTR_ASSOC_STATE = 0x1002, + ATTR_AUTH_TYPE = 0x1003, + ATTR_AUTH_TYPE_FLAGS = 0x1004, + ATTR_AUTHENTICATOR = 0x1005, + ATTR_CONFIG_METHODS = 0x1008, + ATTR_CONFIG_ERROR = 0x1009, + ATTR_CONFIRM_URL4 = 0x100a, + ATTR_CONFIRM_URL6 = 0x100b, + ATTR_CONN_TYPE = 0x100c, + ATTR_CONN_TYPE_FLAGS = 0x100d, + ATTR_CRED = 0x100e, + ATTR_ENCR_TYPE = 0x100f, + ATTR_ENCR_TYPE_FLAGS = 0x1010, + ATTR_DEV_NAME = 0x1011, + ATTR_DEV_PASSWORD_ID = 0x1012, + ATTR_E_HASH1 = 0x1014, + ATTR_E_HASH2 = 0x1015, + ATTR_E_SNONCE1 = 0x1016, + ATTR_E_SNONCE2 = 0x1017, + ATTR_ENCR_SETTINGS = 0x1018, + ATTR_ENROLLEE_NONCE = 0x101a, + ATTR_FEATURE_ID = 0x101b, + ATTR_IDENTITY = 0x101c, + ATTR_IDENTITY_PROOF = 0x101d, + ATTR_KEY_WRAP_AUTH = 0x101e, + ATTR_KEY_ID = 0x101f, + ATTR_MAC_ADDR = 0x1020, + ATTR_MANUFACTURER = 0x1021, + ATTR_MSG_TYPE = 0x1022, + ATTR_MODEL_NAME = 0x1023, + ATTR_MODEL_NUMBER = 0x1024, + ATTR_NETWORK_INDEX = 0x1026, + ATTR_NETWORK_KEY = 0x1027, + ATTR_NETWORK_KEY_INDEX = 0x1028, + ATTR_NEW_DEVICE_NAME = 0x1029, + ATTR_NEW_PASSWORD = 0x102a, + ATTR_OOB_DEVICE_PASSWORD = 0x102c, + ATTR_OS_VERSION = 0x102d, + ATTR_POWER_LEVEL = 0x102f, + ATTR_PSK_CURRENT = 0x1030, + ATTR_PSK_MAX = 0x1031, + ATTR_PUBLIC_KEY = 0x1032, + ATTR_RADIO_ENABLE = 0x1033, + ATTR_REBOOT = 0x1034, + ATTR_REGISTRAR_CURRENT = 0x1035, + ATTR_REGISTRAR_ESTABLISHED = 0x1036, + ATTR_REGISTRAR_LIST = 0x1037, + ATTR_REGISTRAR_MAX = 0x1038, + ATTR_REGISTRAR_NONCE = 0x1039, + ATTR_REQUEST_TYPE = 0x103a, + ATTR_RESPONSE_TYPE = 0x103b, + ATTR_RF_BANDS = 0x103c, + ATTR_R_HASH1 = 0x103d, + ATTR_R_HASH2 = 0x103e, + ATTR_R_SNONCE1 = 0x103f, + ATTR_R_SNONCE2 = 0x1040, + ATTR_SELECTED_REGISTRAR = 0x1041, + ATTR_SERIAL_NUMBER = 0x1042, + ATTR_WPS_STATE = 0x1044, + ATTR_SSID = 0x1045, + ATTR_TOTAL_NETWORKS = 0x1046, + ATTR_UUID_E = 0x1047, + ATTR_UUID_R = 0x1048, + ATTR_VENDOR_EXT = 0x1049, + ATTR_VERSION = 0x104a, + ATTR_X509_CERT_REQ = 0x104b, + ATTR_X509_CERT = 0x104c, + ATTR_EAP_IDENTITY = 0x104d, + ATTR_MSG_COUNTER = 0x104e, + ATTR_PUBKEY_HASH = 0x104f, + ATTR_REKEY_KEY = 0x1050, + ATTR_KEY_LIFETIME = 0x1051, + ATTR_PERMITTED_CFG_METHODS = 0x1052, + ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053, + ATTR_PRIMARY_DEV_TYPE = 0x1054, + ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055, + ATTR_PORTABLE_DEV = 0x1056, + ATTR_AP_SETUP_LOCKED = 0x1057, + ATTR_APPLICATION_EXT = 0x1058, + ATTR_EAP_TYPE = 0x1059, + ATTR_IV = 0x1060, + ATTR_KEY_PROVIDED_AUTO = 0x1061, + ATTR_802_1X_ENABLED = 0x1062, + ATTR_APPSESSIONKEY = 0x1063, + ATTR_WEPTRANSMITKEY = 0x1064, + ATTR_REQUESTED_DEV_TYPE = 0x106a, + ATTR_EXTENSIBILITY_TEST = 0x10fa /* _NOT_ defined in the spec */ +}; + +#define WPS_VENDOR_ID_WFA 14122 + +/* WFA Vendor Extension subelements */ +enum { + WFA_ELEM_VERSION2 = 0x00, + WFA_ELEM_AUTHORIZEDMACS = 0x01, + WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02, + WFA_ELEM_REQUEST_TO_ENROLL = 0x03, + WFA_ELEM_SETTINGS_DELAY_TIME = 0x04 +}; + +/* Device Password ID */ +enum wps_dev_password_id { + DEV_PW_DEFAULT = 0x0000, + DEV_PW_USER_SPECIFIED = 0x0001, + DEV_PW_MACHINE_SPECIFIED = 0x0002, + DEV_PW_REKEY = 0x0003, + DEV_PW_PUSHBUTTON = 0x0004, + DEV_PW_REGISTRAR_SPECIFIED = 0x0005 +}; + +/* Message Type */ +enum wps_msg_type { + WPS_START = 0x00, + WPS_Beacon = 0x01, + WPS_ProbeRequest = 0x02, + WPS_ProbeResponse = 0x03, + WPS_M1 = 0x04, + WPS_M2 = 0x05, + WPS_M2D = 0x06, + WPS_M3 = 0x07, + WPS_M4 = 0x08, + WPS_M5 = 0x09, + WPS_M6 = 0x0a, + WPS_M7 = 0x0b, + WPS_M8 = 0x0c, + WPS_WSC_ACK = 0x0d, + WPS_WSC_NACK = 0x0e, + WPS_WSC_DONE = 0x0f +}; + +/* Authentication Type Flags */ +#define WPS_AUTH_OPEN 0x0001 +#define WPS_AUTH_WPAPSK 0x0002 +#define WPS_AUTH_SHARED 0x0004 +#define WPS_AUTH_WPA 0x0008 +#define WPS_AUTH_WPA2 0x0010 +#define WPS_AUTH_WPA2PSK 0x0020 +#define WPS_AUTH_TYPES (WPS_AUTH_OPEN | WPS_AUTH_WPAPSK | WPS_AUTH_SHARED | \ + WPS_AUTH_WPA | WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK) + +/* Encryption Type Flags */ +#define WPS_ENCR_NONE 0x0001 +#define WPS_ENCR_WEP 0x0002 +#define WPS_ENCR_TKIP 0x0004 +#define WPS_ENCR_AES 0x0008 +#define WPS_ENCR_TYPES (WPS_ENCR_NONE | WPS_ENCR_WEP | WPS_ENCR_TKIP | \ + WPS_ENCR_AES) + +/* Configuration Error */ +enum wps_config_error { + WPS_CFG_NO_ERROR = 0, + WPS_CFG_OOB_IFACE_READ_ERROR = 1, + WPS_CFG_DECRYPTION_CRC_FAILURE = 2, + WPS_CFG_24_CHAN_NOT_SUPPORTED = 3, + WPS_CFG_50_CHAN_NOT_SUPPORTED = 4, + WPS_CFG_SIGNAL_TOO_WEAK = 5, + WPS_CFG_NETWORK_AUTH_FAILURE = 6, + WPS_CFG_NETWORK_ASSOC_FAILURE = 7, + WPS_CFG_NO_DHCP_RESPONSE = 8, + WPS_CFG_FAILED_DHCP_CONFIG = 9, + WPS_CFG_IP_ADDR_CONFLICT = 10, + WPS_CFG_NO_CONN_TO_REGISTRAR = 11, + WPS_CFG_MULTIPLE_PBC_DETECTED = 12, + WPS_CFG_ROGUE_SUSPECTED = 13, + WPS_CFG_DEVICE_BUSY = 14, + WPS_CFG_SETUP_LOCKED = 15, + WPS_CFG_MSG_TIMEOUT = 16, + WPS_CFG_REG_SESS_TIMEOUT = 17, + WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18 +}; + +/* RF Bands */ +#define WPS_RF_24GHZ (0x01) +#define WPS_RF_50GHZ (0x02) + +/* Config Methods */ +#define WPS_CONFIG_USBA (0x0001) +#define WPS_CONFIG_ETHERNET (0x0002) +#define WPS_CONFIG_LABEL (0x0004) +#define WPS_CONFIG_DISPLAY (0x0008) +#define WPS_CONFIG_EXT_NFC_TOKEN (0x0010) +#define WPS_CONFIG_INT_NFC_TOKEN (0x0020) +#define WPS_CONFIG_NFC_INTERFACE (0x0040) +#define WPS_CONFIG_PUSHBUTTON (0x0080) +#define WPS_CONFIG_KEYPAD (0x0100) + +#ifdef CONFIG_WPS2 +#define WPS_CONFIG_VIRT_PUSHBUTTON (0x0280) +#define WPS_CONFIG_PHY_PUSHBUTTON (0x0480) +#define WPS_CONFIG_VIRT_DISPLAY (0x2008) +#define WPS_CONFIG_PHY_DISPLAY (0x4008) +#endif /* CONFIG_WPS2 */ + +/* Connection Type Flags */ +#define WPS_CONN_ESS (0x01) +#define WPS_CONN_IBSS (0x02) + +/* Wi-Fi Protected Setup State */ +enum wps_state { + WPS_STATE_NOT_CONFIGURED = 1, + WPS_STATE_CONFIGURED = 2 +}; + +/* Association State */ +enum wps_assoc_state { + WPS_ASSOC_NOT_ASSOC = 0, + WPS_ASSOC_CONN_SUCCESS = 1, + WPS_ASSOC_CFG_FAILURE = 2, + WPS_ASSOC_FAILURE = 3, + WPS_ASSOC_IP_FAILURE = 4 +}; + +#define WPS_DEV_OUI_WFA (0x0050f204) + +enum wps_dev_categ { + WPS_DEV_COMPUTER = 1, + WPS_DEV_INPUT = 2, + WPS_DEV_PRINTER = 3, + WPS_DEV_CAMERA = 4, + WPS_DEV_STORAGE = 5, + WPS_DEV_NETWORK_INFRA = 6, + WPS_DEV_DISPLAY = 7, + WPS_DEV_MULTIMEDIA = 8, + WPS_DEV_GAMING = 9, + WPS_DEV_PHONE = 10 +}; + +enum wps_dev_subcateg { + WPS_DEV_COMPUTER_PC = 1, + WPS_DEV_COMPUTER_SERVER = 2, + WPS_DEV_COMPUTER_MEDIA_CENTER = 3, + + WPS_DEV_PRINTER_PRINTER = 1, + WPS_DEV_PRINTER_SCANNER = 2, + + WPS_DEV_CAMERA_DIGITAL_STILL_CAMERA = 1, + + WPS_DEV_STORAGE_NAS = 1, + + WPS_DEV_NETWORK_INFRA_AP = 1, + WPS_DEV_NETWORK_INFRA_ROUTER = 2, + WPS_DEV_NETWORK_INFRA_SWITCH = 3, + + WPS_DEV_DISPLAY_TV = 1, + WPS_DEV_DISPLAY_PICTURE_FRAME = 2, + WPS_DEV_DISPLAY_PROJECTOR = 3, + + WPS_DEV_MULTIMEDIA_DAR = 1, + WPS_DEV_MULTIMEDIA_PVR = 2, + WPS_DEV_MULTIMEDIA_MCX = 3, + + WPS_DEV_GAMING_XBOX = 1, + WPS_DEV_GAMING_XBOX360 = 2, + WPS_DEV_GAMING_PLAYSTATION = 3, + + WPS_DEV_PHONE_WINDOWS_MOBILE = 1 +}; + + +/* Request Type */ +enum wps_request_type { + WPS_REQ_ENROLLEE_INFO = 0, + WPS_REQ_ENROLLEE = 1, + WPS_REQ_REGISTRAR = 2, + WPS_REQ_WLAN_MANAGER_REGISTRAR = 3 +}; + +/* Response Type */ +enum wps_response_type { + WPS_RESP_ENROLLEE_INFO = 0, + WPS_RESP_ENROLLEE = 1, + WPS_RESP_REGISTRAR = 2, + WPS_RESP_AP = 3 +}; + +/* Walk Time for push button configuration (in seconds) */ +#define WPS_PBC_WALK_TIME (120) + +#define WPS_MAX_AUTHORIZED_MACS (5) + +#endif /* WPS_DEFS_H */ + diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c new file mode 100644 index 0000000..a24c7b0 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c @@ -0,0 +1,476 @@ +#include +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include "queue.h" +#include "utils/os.h" +#include +#include +#include "wifi/wifi_conf.h" +#include +#ifdef CONFIG_ENABLE_EAP +#include +#include +#endif + +#define WLAN0_NAME "wlan0" +#ifndef ENABLE +#define ENABLE (1) +#endif +#ifndef DISABLE +#define DISABLE (0) +#endif + +#ifndef CONFIG_ENABLE_EAP +int get_eap_phase(void){ + return 0; +} + +int get_eap_method(void){ + return 0; +} + +void eap_autoreconnect_hdl(u8 method_id) +{ + (void) method_id; +} +#else + +u8 eap_phase = 0; +u8 eap_method = 0; + +// eap config arguments +char *eap_target_ssid = NULL; +char *eap_identity = NULL; +char *eap_password = NULL; +// if set eap_ca_cert and defined(EAP_SSL_VERIFY_SERVER), client will verify server's cert +const unsigned char *eap_ca_cert = NULL; +// if set eap_client_cert, eap_client_key, and defined(EAP_SSL_VERIFY_CLIENT), client will send its cert to server +const unsigned char *eap_client_cert = NULL; +const unsigned char *eap_client_key = NULL; +char *eap_client_key_pwd = NULL; + +//int max_buf_bio_size = SSL_BUFFER_LEN; // ?pvvx? + +#ifdef CONFIG_ENABLE_EAP +void eap_eapol_recvd_hdl(char *buf, int buf_len, int flags, void* handler_user_data); +void eap_eapol_start_hdl(char *buf, int buf_len, int flags, void* handler_user_data); +#endif + + +int get_eap_phase(void){ + return eap_phase; +} + +int get_eap_method(void){ + return eap_method; +} + +void set_eap_phase(unsigned char is_trigger_eap){ + eap_phase = is_trigger_eap; +} + +void reset_config(void){ + eap_target_ssid = NULL; + eap_identity = NULL; + eap_password = NULL; + eap_ca_cert = NULL; + eap_client_cert = NULL; + eap_client_key = NULL; + eap_client_key_pwd = NULL; +} + +#ifdef CONFIG_ENABLE_EAP + +void judge_station_disconnect(void) +{ + int mode = 0; + unsigned char ssid[33]; + + wext_get_mode(WLAN0_NAME, &mode); + + switch(mode) { + case IW_MODE_MASTER: //In AP mode + wifi_off(); + vTaskDelay(20); + wifi_on(RTW_MODE_STA); + break; + case IW_MODE_INFRA: //In STA mode + if(wext_get_ssid(WLAN0_NAME, ssid) > 0) + wifi_disconnect(); + } +} + +void eap_disconnected_hdl(char *buf, int buf_len, int flags, void* handler_user_data){ +// printf("disconnected\n"); + wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl); + wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl); + eap_peer_unregister_methods(); + eap_sm_deinit(); + //reset_config(); +} +#endif +/* +void eap_config(void){ + eap_target_ssid = "Test_eap"; + eap_identity = "guest2"; + eap_password = "test2"; + + eap_client_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIC9zCCAd8CAQMwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \ +"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \ +"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \ +"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE1MDgwNzEx\r\n" \ +"WhcNMTcwMzE1MDgwNzExWjBzMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \ +"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGjAYBgNVBAMUEXVzZXIyQGV4YW1wbGUu\r\n" \ +"Y29tMSAwHgYJKoZIhvcNAQkBFhF1c2VyMkBleGFtcGxlLmNvbTCBnzANBgkqhkiG\r\n" \ +"9w0BAQEFAAOBjQAwgYkCgYEAqESlV4OYfBcIgZ+Cs8mWpiBjhvKoa0/kIe7saqhC\r\n" \ +"e5q4snox0jdkUpLcc4vOs3vQ7ZGnimqTltA9oF6XNUzTWW4vlJTKEfrCWK085l7c\r\n" \ +"DHFvHavH3E6vuP71lI7jq4PLXbo2TvZK+uBul4ozjzVWihaZBtz8eLHq446h/D/p\r\n" \ +"kzkCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAAfhVAIkNdeeUNJud720uUHVnIcxz\r\n" \ +"GXWI+Svi1qchuTEnRNhLwXmnE+A0WWSHyfdR6FvzdT3xtz3K50iOif8jY2gCGkSK\r\n" \ +"8RjKr97228SwbrGO9y9+dYIjH1uz9cBpoVKcpzdsWpKObrDPDYyReHSWo99jM2+O\r\n" \ +"vfJxnBw4PLiBj7Q0/dpd6o4JXyp7Cxa0mB4/+cZqjCzzuKfuK3WP7j6laMCV6mg4\r\n" \ +"wRZ528IdwDqB7OOqsDm1PVQM8vzny9PM6ikWUCRTVNQJN8RDLkrHR3FRjy15YLdt\r\n" \ +"yOfDqVnT/z0wGBaxnNziSJjqPGHPpRi4bJFGXwXOhtknKmciKzfj9/npoQ==\r\n" \ +"-----END CERTIFICATE-----\r\n"; + + eap_client_key = \ +"-----BEGIN RSA PRIVATE KEY-----\r\n" \ +"MIICXQIBAAKBgQCoRKVXg5h8FwiBn4KzyZamIGOG8qhrT+Qh7uxqqEJ7mriyejHS\r\n" \ +"N2RSktxzi86ze9DtkaeKapOW0D2gXpc1TNNZbi+UlMoR+sJYrTzmXtwMcW8dq8fc\r\n" \ +"Tq+4/vWUjuOrg8tdujZO9kr64G6XijOPNVaKFpkG3Px4serjjqH8P+mTOQIDAQAB\r\n" \ +"AoGARI+LyweshssfxSkIKVc3EcNaqi6PHwJzUrw2ChM624AkR1xwllXJg7ehKVdK\r\n" \ +"xmjprRLO8CASuL1qjsBb3fTKnBl+sIVxIFS0AI4Y3ri8VUKbangvSsI7pCzAFry7\r\n" \ +"p1gmy9WWRV2ZEa+dV8xcrjb3bloT7hcdeLehgBCvExJIQM0CQQDXlSAKdW3AhYyj\r\n" \ +"1A+pfyBSGxJbpSwNyyWgwHIHHjxendxmdUbrc8EbAu1eNKbP58TLgdCZsKcMonAv\r\n" \ +"MY1Y2/nnAkEAx9CrUaCU8pJqXTRypM5JtexLKnYMJhpnA9uUILBQOq4Oe0eruyF5\r\n" \ +"SaSxhyJYXY491ahWYPF0PTb3jkUhoN+l3wJBAJZthjgGDJlEFwjSFkOtYz4nib3N\r\n" \ +"GVpeoFj1MBvrazCScpJDz0LIOLzCZCNSFfwIu3dNk+NKMqZMSn+D0h9pD40CQQC5\r\n" \ +"K9n4NXaTLbjAU2CC9mE85JPr76XmkcUxwAWQHZTcLH1jJdIyAx1hb+zNLLjzSmRn\r\n" \ +"Yi9ae6ibKhtUjyBQ87HFAkA2Bb3z7NUx+AA2g2HZocFZFShBxylACyQkl8FAFZtf\r\n" \ +"osudmKdFQHyAWuBMex4tpz/OLTqJ1ecL1JQeC7OvlpEX\r\n" \ +"-----END RSA PRIVATE KEY-----\r\n"; + + eap_ca_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIEpzCCA4+gAwIBAgIJAPvZaozpdfjkMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\n" \ +"VQQGEwJGUjEPMA0GA1UECBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTAT\r\n" \ +"BgNVBAoTDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\r\n" \ +"ZS5jb20xJjAkBgNVBAMTHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\r\n" \ +"DTE2MDMxNDExMjU0OVoXDTE2MDQxMzExMjU0OVowgZMxCzAJBgNVBAYTAkZSMQ8w\r\n" \ +"DQYDVQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhh\r\n" \ +"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG\r\n" \ +"A1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\r\n" \ +"DQEBAQUAA4IBDwAwggEKAoIBAQC9pireu0aCDLNfMaGv3vId7RXjUhQwSK0jV2Oc\r\n" \ +"SyvlKWH3P/N+5kLrP2iL6SCzyETVDXZ0vOsAMjcBF0zHp16prXV0d51cTUqeWBb0\r\n" \ +"I5UnGxleIuuOfSg8zLUJoBWZPqLv++eZ5WgOKHt7SXocjvg7TU5t/TMB0Y8OCz3H\r\n" \ +"CW2vJ/XKMgMA9HDUu4g57cJu88i1JPRpyFaz/HIQBc7+UNb9z+q09uTZKWTmEMqi\r\n" \ +"E2U0EEIs7EtbxnOze1/8C4XNlmztrEdwvu6UEBU/TFkUoh9M646NkkBK7wP9n9pv\r\n" \ +"T0nPQRJiiCrICzVqUtlEi9lIKpbBSMbQ0KzrGF7lGTgm4rz9AgMBAAGjgfswgfgw\r\n" \ +"HQYDVR0OBBYEFIVyecka74kvOKIW0BjlTc/B+a2NMIHIBgNVHSMEgcAwgb2AFIVy\r\n" \ +"ecka74kvOKIW0BjlTc/B+a2NoYGZpIGWMIGTMQswCQYDVQQGEwJGUjEPMA0GA1UE\r\n" \ +"CBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTATBgNVBAoTDEV4YW1wbGUg\r\n" \ +"SW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xJjAkBgNVBAMT\r\n" \ +"HUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggkA+9lqjOl1+OQwDAYDVR0T\r\n" \ +"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZYHM26sxbKOckVqJJ1QY0U2QFlGP\r\n" \ +"1GYd8v27znxdnRmSonDvv3GjFfhwoyDk0JUuxkK/33ikCxihrgoO/EQTY9BV2OpW\r\n" \ +"qkB1PDtb3i5ZRNvfjmW0pVA4p+GmdTGaEE5pTlcVnorzVrUeFKaZakb+IDFYzmeF\r\n" \ +"xp8B3Bb5wvinDligLOaJnSlgS8QeeIab9HZfaVTTuPmVK6zE6D54Y0dJPnykvDdE\r\n" \ +"cGN0FC+migfilFjJgkDJ0r78nwes55L8zjoofiZuO03rrHww6ARc3v1jYzAufddk\r\n" \ +"QTiZHgjlMQb2XXMmXLn8kBgoDnqkXFNe8j0h8uxIJSrjOoIyn1h1wvX5/w==\r\n" \ +"-----END CERTIFICATE-----\r\n"; +} +*/ + +int eap_start(char *method){ +#ifdef CONFIG_ENABLE_EAP + int ret = -1; + + //unsigned long tick1 = xTaskGetTickCount(); + //unsigned long tick2; + + if(rltk_wlan_running(WLAN1_IDX)){ + printf("\n\rNot support con-current mode!\n\r"); + return -1; + } + + judge_station_disconnect(); + +#if CONFIG_ENABLE_PEAP + if(strcmp(method,"peap") == 0){ + ret = set_eap_peap_method(); + } +#endif + +#if CONFIG_ENABLE_TLS + if(strcmp(method,"tls") == 0){ + ret = set_eap_tls_method(); + } +#endif + +#if CONFIG_ENABLE_TTLS + if(strcmp(method,"ttls") == 0){ + ret = set_eap_ttls_method(); + } +#endif + + if(ret == -1){ + printf("\r\neap method %s not supported\r\n", method); + return -1; + } + + eap_method = get_eap_ctx_method(); + + printf("\n==================== %s_start ====================\n", method); + + //eap_config(); + + set_eap_phase(ENABLE); + wifi_reg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl, NULL); + + + + ret = connect_by_open_system(eap_target_ssid); + +#if CONFIG_LWIP_LAYER + /* Start DHCPClient */ + if(ret == 0) + LwIP_DHCP(0, DHCP_START); +#endif + + wifi_unreg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl); + + // for re-authentication when session timeout + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl, NULL); + //wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl); + + set_eap_phase(DISABLE); + + // eap failed, disconnect + if(ret != 0){ + judge_station_disconnect(); + eap_disconnected_hdl(NULL, 0, 0, NULL); + rtw_msleep_os(200); //wait handler done + printf("\r\nERROR: connect to AP by %s failed\n", method); + } + + eap_sm_deinit(); + printf("\n==================== %s_finish ====================\n", method); + + //tick2 = xTaskGetTickCount(); + //printf("\r\nConnected after %dms.\n", (tick2-tick1)); + + return ret; +#else + return -1; +#endif +} +#ifdef CONFIG_ENABLE_EAP +static int connect_by_open_system(char *target_ssid) +{ + int retry_count = 0, ret; + + if (target_ssid != NULL) { + while (1) { + rtw_msleep_os(500); //wait scan complete. + ret = wifi_connect( + NULL, + 0, + target_ssid, + RTW_SECURITY_OPEN, + NULL, + 0, + NULL); + if (ret == RTW_SUCCESS) { + //printf("\r\n[EAP]Associate with AP success\n"); + break; + } + if (retry_count == 0) { + //printf("\r\n[EAP]Associate with AP failed %d\n", ret); + return -1; + } + retry_count --; + printf("Retry connection...\n"); + + judge_station_disconnect(); + set_eap_phase(ENABLE); + } + } else { + printf("\r\n[EAP]Target SSID is NULL\n"); + return -1; + } + + return 0; +} + +static void eap_autoreconnect_thread(void *method) +{ + eap_start((char*)method); + vTaskDelete(NULL); +} +#endif + +void eap_autoreconnect_hdl(u8 method_id){ +#ifdef CONFIG_ENABLE_EAP + char *method; + switch(method_id){ + case 25: // EAP_TYPE_PEAP + method = "peap"; + break; + case 13: // EAP_TYPE_TLS + method = "tls"; + break; + case 21: // EAP_TYPE_TTLS + method = "ttls"; + break; + default: + printf("invalid eap method\n"); + return; + } + if(xTaskCreate(eap_autoreconnect_thread, ((const char*)"eap_autoreconnect_thread"), 1024, (void*) method, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate failed\n", __FUNCTION__); +#endif +} + +// copy from ssl_client_ext.c +#if ENABLE_EAP_SSL_VERIFY_CLIENT +static x509_crt* _cli_crt = NULL; +static pk_context* _clikey_rsa = NULL; +#endif + +#if ENABLE_EAP_SSL_VERIFY_SERVER +static x509_crt* _ca_crt = NULL; + +static int eap_verify(void *data, x509_crt *crt, int depth, int *flags) +{ + + //char buf[1024]; + ((void) data); + + printf("\nVerify requested for (Depth %d):\n", depth); + //x509_crt_info(buf, sizeof(buf) - 1, "", crt); + //printf("%s", buf); + + if(((*flags) & BADCERT_EXPIRED) != 0) + printf("server certificate has expired\n"); + + if(((*flags) & BADCERT_REVOKED) != 0) + printf(" ! server certificate has been revoked\n"); + + if(((*flags) & BADCERT_CN_MISMATCH) != 0) + printf(" ! CN mismatch\n"); + + if(((*flags) & BADCERT_NOT_TRUSTED) != 0) + printf(" ! self-signed or not signed by a trusted CA\n"); + + if(((*flags) & BADCRL_NOT_TRUSTED) != 0) + printf(" ! CRL not trusted\n"); + + if(((*flags) & BADCRL_EXPIRED) != 0) + printf(" ! CRL expired\n"); + + if(((*flags) & BADCERT_OTHER) != 0) + printf(" ! other (unknown) flag\n"); + + if((*flags) == 0) + printf(" Certificate verified without error flags\n"); + + return(0); +} +#endif + +int eap_cert_init(void) +{ +#if ENABLE_EAP_SSL_VERIFY_CLIENT + if(eap_client_cert != NULL && eap_client_key != NULL){ + _cli_crt = polarssl_malloc(sizeof(x509_crt)); + + if(_cli_crt) + x509_crt_init(_cli_crt); + else + return -1; + + _clikey_rsa = polarssl_malloc(sizeof(pk_context)); + + if(_clikey_rsa) + pk_init(_clikey_rsa); + else + return -1; + } +#endif +#if ENABLE_EAP_SSL_VERIFY_SERVER + if(eap_ca_cert != NULL){ + _ca_crt = polarssl_malloc(sizeof(x509_crt)); + + if(_ca_crt) + x509_crt_init(_ca_crt); + else + return -1; + } +#endif + return 0; +} + +void eap_client_cert_free(void) +{ +#if ENABLE_EAP_SSL_VERIFY_CLIENT + if(eap_client_cert != NULL && eap_client_key != NULL){ + if(_cli_crt) { + x509_crt_free(_cli_crt); + polarssl_free(_cli_crt); + _cli_crt = NULL; + } + + if(_clikey_rsa) { + pk_free(_clikey_rsa); + polarssl_free(_clikey_rsa); + _clikey_rsa = NULL; + } + } +#endif +} + +void eap_server_cert_free(void) +{ +#if ENABLE_EAP_SSL_VERIFY_SERVER + if(eap_ca_cert != NULL){ + if(_ca_crt) { + x509_crt_free(_ca_crt); + polarssl_free(_ca_crt); + _ca_crt = NULL; + } + } +#endif +} + +int eap_cert_setup(ssl_context *ssl) +{ +#if ENABLE_EAP_SSL_VERIFY_CLIENT + if(eap_client_cert != NULL && eap_client_key != NULL){ + if(x509_crt_parse(_cli_crt, eap_client_cert, strlen(eap_client_cert)) != 0) + return -1; + + if(pk_parse_key(_clikey_rsa, eap_client_key, strlen(eap_client_key), eap_client_key_pwd, strlen(eap_client_key_pwd)) != 0) + return -1; + + ssl_set_own_cert(ssl, _cli_crt, _clikey_rsa); + } +#endif +#if ENABLE_EAP_SSL_VERIFY_SERVER + if(eap_ca_cert != NULL){ + if(x509_crt_parse(_ca_crt, eap_ca_cert, strlen(eap_ca_cert)) != 0) + return -1; + ssl_set_ca_chain(ssl, _ca_crt, NULL, NULL); + ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED); + ssl_set_verify(ssl, eap_verify, NULL); + } +#endif + return 0; +} + +#endif //#ifdef CONFIG_ENABLE_EAP diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_p2p_config.c b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_p2p_config.c new file mode 100644 index 0000000..3930d51 --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_p2p_config.c @@ -0,0 +1,267 @@ +#include "FreeRTOS.h" +#include "task.h" + +#include "utils/os.h" +#include +#include +#include "wps/wps_defs.h" + +#if CONFIG_ENABLE_P2P +enum p2p_wps_method { + WPS_NOT_READY, WPS_PIN_DISPLAY, WPS_PIN_KEYPAD, WPS_PBC +}; + +/*NETMASK*/ +#define P2P_NETMASK_ADDR0 255 +#define P2P_NETMASK_ADDR1 255 +#define P2P_NETMASK_ADDR2 255 +#define P2P_NETMASK_ADDR3 0 + +/*Gateway Address*/ +#define P2P_GW_ADDR0 192 +#define P2P_GW_ADDR1 168 +#define P2P_GW_ADDR2 42 +#define P2P_GW_ADDR3 1 + +#define P2P_GO_NEGO_RESULT_SIZE 376//256 + +xqueue_handle_t queue_for_p2p_nego; + +extern void dhcps_init(struct netif * pnetif); + +static int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +/** + * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_aton(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num(*txt++); + if (a < 0) + return -1; + b = hex2num(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + if (i < 5 && *txt++ != ':') + return -1; + } + + return 0; +} + +int wifi_start_p2p_go(char *ssid, char *passphrase, u8 channel) +{ + extern struct netif xnetif[NET_IF_NUM]; + struct netif * pnetif = &xnetif[0]; + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + IP4_ADDR(&ipaddr, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3); + IP4_ADDR(&netmask, P2P_NETMASK_ADDR0, P2P_NETMASK_ADDR1 , P2P_NETMASK_ADDR2, P2P_NETMASK_ADDR3); + IP4_ADDR(&gw, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask,&gw); + + // start ap + if(wifi_start_ap( ssid, + RTW_SECURITY_WPA2_AES_PSK, + passphrase, + channel, + 0) != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return -1; + } + + netif_set_default(pnetif); + + // start dhcp server + dhcps_init(pnetif); + + return 0; +} + +void app_callback(char *msg) +{ + //From Application +} + +void cmd_wifi_p2p_start(int argc, char **argv) +{ + extern struct netif xnetif[NET_IF_NUM]; + int listen_ch = 1; + int op_ch = 5; + int go_intent = 1; +#if 1 + u32 r = 0; + os_get_random((u8 *) &r, sizeof(r)); + go_intent = r%15+1; /*1-15*/ + + os_get_random((u8 *) &r, sizeof(r)); + listen_ch = 1 + (r % 3) * 5; + + os_get_random((u8 *) &r, sizeof(r)); + op_ch = 1 + (r % 3) * 5; +#endif + wifi_off(); + os_sleep(0, 20000); + wifi_on(RTW_MODE_P2P); + wifi_p2p_init(xnetif[0].hwaddr, go_intent, listen_ch, op_ch); +} + +int cmd_wifi_p2p_auto_go_start(int argc, char **argv) +{ + u8 *passphrase = "12345678"; + u8 channel = 6; // 1, 6, 11 + const char *ssid_in = "DIRECT-34-Ameba"; + const char *dev_name = "Ameba1234"; // max strlen 32 + const char *manufacturer = "by customer"; // max strlen 64 + const char *model_name = "customer"; // max strlen 32 + const char *model_number = "v2.0"; // max strlen 32 + const char *serial_number = "9"; // max strlen 32 + const u8 pri_dev_type[8] = {0x00,0x0A,0x00,0x50,0xF2,0x04,0x00,0x01}; // category ID:0x00,0x0A; sub category ID:0x00,0x01 + u8 res[P2P_GO_NEGO_RESULT_SIZE]; + u16 config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | WPS_CONFIG_PUSHBUTTON; + + if(!is_wifi_p2p_initialized()) + return -1; + + wifi_p2p_set_dev_name(dev_name); + wifi_p2p_set_manufacturer(manufacturer); + wifi_p2p_set_model_name(model_name); + wifi_p2p_set_model_number(model_number); + wifi_p2p_set_serial_number(serial_number); + wifi_p2p_set_pri_dev_type(pri_dev_type); + wifi_p2p_set_ssid(ssid_in); + wifi_p2p_set_config_methods(config_methods); + wifi_p2p_init_auto_go_params(res, passphrase, channel); + wifi_p2p_start_auto_go(res); + return 0; +} +void cmd_wifi_p2p_stop(int argc, char **argv) +{ + wifi_p2p_deinit(); + wifi_off(); +} + +void cmd_p2p_listen(int argc, char **argv) +{ + u32 timeout = 0; + + if(argc == 2){ + timeout = os_atoi((u8*)argv[1]); + printf("\r\n%s(): timeout=%d\n", __func__, timeout); + if(timeout > 3600) + timeout = 3600; + } + wifi_cmd_p2p_listen(timeout); +} + +void cmd_p2p_find(int argc, char **argv) +{ + wifi_cmd_p2p_find(); +} + +void cmd_p2p_peers(int argc, char **argv) +{ + wifi_cmd_p2p_peers(); +} + +void cmd_p2p_info(int argc, char **argv) +{ + wifi_cmd_p2p_info(); +} + +void cmd_p2p_disconnect(int argc, char **argv) +{ + wifi_cmd_p2p_disconnect(); +} + +void cmd_p2p_connect(int argc, char **argv) +{ + enum p2p_wps_method config_method = WPS_PBC; + char *pin = NULL; + u8 dest[ETH_ALEN] = {0x44, 0x6d, 0x57, 0xd7, 0xce, 0x41}; + u8 res[P2P_GO_NEGO_RESULT_SIZE]; + int ret = 0; + +#if 1 + if((argc != 2) && (argc != 3) && (argc != 4)) { + printf("Usage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n"); + printf("Example: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n"); + return; + } + if (hwaddr_aton(argv[1], dest)){ + printf("P2P_CONNECT: dest address is not correct!\n"); + return; + } + + //printf("\r\nDEST: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]); + config_method = WPS_PBC; + if(argc == 3) { + if(os_strncmp(argv[2], "pbc", 3) == 0) + config_method = WPS_PBC; + else if(os_strncmp(argv[2], "pin", 3) == 0){ + config_method = WPS_PIN_DISPLAY; + }else{ + printf("Unknown config method!\n"); + printf("Usage: p2p_connect DEST_ADDR [pbc|pin] \n"); + printf("Example: p2p_connect 00:e0:4c:87:00:15 pin\n"); + return; + } + } + else if(argc == 4) { + if(os_strncmp(argv[2], "pin", 3) == 0){ + config_method = WPS_PIN_KEYPAD; + pin = argv[3]; + }else{ + printf("Unknown config method!\n"); + printf("Usage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n"); + printf("Example: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n"); + return; + } + } +#else //For test + u8 dest1[ETH_ALEN] = {0xea, 0x92, 0xa4, 0x9b, 0x61, 0xd6}; //NEXUS 4 + //u8 dest1[ETH_ALEN] = {0x0e, 0x37, 0xdc, 0xfc, 0xc4, 0x12}; //HUAWEI U9508_c001 + //u8 dest1[ETH_ALEN] = {0x42, 0xcb, 0xa8, 0xd3, 0x2c, 0x50}; //HUAWEI G610-T00 + os_memcpy(dest, dest1, ETH_ALEN); + config_method = WPS_PBC; +#endif + + if (queue_for_p2p_nego!= NULL) { + os_xqueue_delete(queue_for_p2p_nego); + queue_for_p2p_nego = NULL; + } + queue_for_p2p_nego = os_xqueue_create(1, P2P_GO_NEGO_RESULT_SIZE); + if(queue_for_p2p_nego != NULL) { + ret = wifi_cmd_p2p_connect(dest, config_method, pin); + if(ret == 0) + os_xqueue_receive(queue_for_p2p_nego, res, 15); + + os_xqueue_delete(queue_for_p2p_nego); + queue_for_p2p_nego = NULL; + + if(ret == 0) + wifi_p2p_start_wps(res); + } +} + +#endif //CONFIG_ENABLE_P2P diff --git a/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_wps_config.c b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_wps_config.c new file mode 100644 index 0000000..e2cd89c --- /dev/null +++ b/USDK/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_wps_config.c @@ -0,0 +1,755 @@ +#include +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include "queue.h" +#include "utils/os.h" +#include +#include +#include "wifi/wifi_conf.h" +#include "wps/wps_defs.h" +#include + +/* + * @brief struct wps_credential - WPS Credential + */ +struct dev_credential { + u8 ssid[32]; /**< SSID */ + size_t ssid_len; /**< Length of SSID */ + u16 auth_type; /**< Authentication Type (WPS_AUTH_OPEN, .. flags) */ + u16 encr_type; /**< Encryption Type (WPS_ENCR_NONE, .. flags) */ + u8 key_idx; /**< Key index */ + u8 key[65]; /**< Key */ + size_t key_len; /**< Key length in octets */ + u8 mac_addr[6]; /**< MAC address of the Credential receiver */ + const u8 *cred_attr; /**< Unparsed Credential attribute data (used only in cred_cb()). + This may be NULL, if not used. */ + size_t cred_attr_len; /**< Length of cred_attr in octets */ + u16 ap_channel; /**< AP channel */ +}; + +typedef struct { + char *target_ssid; + u16 config_method; + _sema scan_sema; + int isoverlap; +} internal_wps_scan_handler_arg_t; + +#define WLAN0_NAME "wlan0" +#ifndef ENABLE +#define ENABLE (1) +#endif +#ifndef DISABLE +#define DISABLE (0) +#endif +#define STACKSIZE 512 + + +//static xSemaphoreHandle wps_reconnect_semaphore; +//static struct _WIFI_NETWORK wifi_get_from_certificate = {0}; + +#define WPS_AUTH_TYPE_OPEN (0x0001) +#define WPS_AUTH_TYPE_WPA_PERSONAL (0x0002) +#define WPS_AUTH_TYPE_SHARED (0x0004) +#define WPS_AUTH_TYPE_WPA_ENTERPRISE (0x0008) +#define WPS_AUTH_TYPE_WPA2_PERSONAL (0x0010) +#define WPS_AUTH_TYPE_WPA2_ENTERPRISE (0x0020) + +#define WPS_ENCR_TYPE_NONE (0x0001) +#define WPS_ENCR_TYPE_WEP (0x0002) +#define WPS_ENCR_TYPE_TKIP (0x0004) +#define WPS_ENCR_TYPE_AES (0x0008) + +#define SCAN_BUFFER_LENGTH (4096) + +#if CONFIG_ENABLE_P2P +extern void _wifi_p2p_wps_success(const u8 *peer_addr, int registrar); +extern void _wifi_p2p_wps_failed(); +#endif +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +extern u32 _wps_registrar_process_msg(void *priv, u32 op_code, const void *pmsg); +extern void * _wps_registrar_get_msg(void *priv, u32 *op_code); +extern void * _wps_registrar_init(void *priv, const void* pcfg); +extern void _wps_registrar_deinit(void *priv); +extern void *_wps_registrar_alloc(); +extern int _wps_registrar_add_pin(void *priv, const u8 *addr, + const u8 *uuid, const u8 *pin, size_t pin_len, + int timeout); +extern int _wps_registrar_button_pushed(void *priv, + const u8 *p2p_dev_addr); +extern int _wps_registrar_wps_cancel(void *priv); +extern void _wpas_wsc_ap_send_eap_reqidentity(void *priv, u8 *rx_buf); +extern void _wpas_wsc_ap_check_eap_rspidentity(void *priv, u8 *rx_buf); +extern void _wpas_wsc_registrar_send_eap_fail(void *priv); +extern void _wpas_wsc_registrar_handle_recvd(void *priv, u8 *rx_buf); +extern void * _eap_wsc_server_process_hdl(void *priv, void* req, u8 id); +extern void *_eap_wsc_server_reset(void *priv); +#endif +extern void wpas_wsc_sta_wps_start_hdl(char *buf, int buf_len, int flags, void *userdata); +extern void wpas_wsc_wps_finish_hdl(char *buf, int buf_len, int flags, void *userdata); +extern void wpas_wsc_eapol_recvd_hdl(char *buf, int buf_len, int flags, void *userdata); + +void wifi_p2p_wps_success(const u8 *peer_addr, int registrar) +{ +#if CONFIG_ENABLE_P2P + _wifi_p2p_wps_success(peer_addr, registrar); +#endif +} + +void wifi_p2p_wps_failed() +{ +#if CONFIG_ENABLE_P2P + _wifi_p2p_wps_failed(); +#endif +} + +void * wps_registrar_init(void *priv, void *pcfg) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_init(priv, pcfg); +#else + return NULL; +#endif +} + +void wps_registrar_deinit(void *priv) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _wps_registrar_deinit(priv); +#endif +} + +void *wps_registrar_alloc() +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_alloc(); +#else + return NULL; +#endif +} + +u32 wps_registrar_process_msg(void *priv, u32 op_code, const void *pmsg) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_process_msg(priv, op_code, pmsg); +#else + return 0; +#endif +} + +void * wps_registrar_get_msg(void *priv, u32 *op_code) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_get_msg(priv, op_code); +#else + return NULL; +#endif +} + + +int wps_registrar_add_pin(void *priv, const u8 *addr, + const u8 *uuid, const u8 *pin, size_t pin_len, + int timeout) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_add_pin(priv, NULL,NULL,pin,pin_len,0); +#else + return 0; +#endif +} + +int wps_registrar_button_pushed(void *priv, + const u8 *p2p_dev_addr) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_button_pushed(priv, p2p_dev_addr); +#else + return 0; +#endif +} + +int wps_registrar_wps_cancel(void *priv) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _wps_registrar_wps_cancel(priv); +#else + return 0; +#endif + +} + +void wpas_wsc_ap_send_eap_reqidentity(void *priv, u8 *rx_buf) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _wpas_wsc_ap_send_eap_reqidentity(priv, rx_buf); +#endif +} + +void wpas_wsc_ap_check_eap_rspidentity(void *priv, u8 *rx_buf) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _wpas_wsc_ap_check_eap_rspidentity(priv, rx_buf); +#endif +} + +void wpas_wsc_registrar_send_eap_fail(void *priv) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _wpas_wsc_registrar_send_eap_fail(priv); +#endif +} + +void wpas_wsc_registrar_handle_recvd(void *priv, u8 *rx_buf) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _wpas_wsc_registrar_handle_recvd(priv, rx_buf); +#endif +} + +void * eap_wsc_server_process_hdl(void *priv, void* req, u8 id) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + return _eap_wsc_server_process_hdl(priv, req, id); +#else + return NULL; +#endif +} + +void eap_wsc_server_reset(void *priv) +{ +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + _eap_wsc_server_reset(priv); +#endif +} + +#if CONFIG_ENABLE_WPS +xqueue_handle_t queue_for_credential; +char wps_pin_code[32]; +u16 config_method; +u8 wps_password_id; +static TaskHandle_t ap_wps_task = NULL; + +void wps_check_and_show_connection_info(void) +{ + rtw_wifi_setting_t setting; +#if CONFIG_LWIP_LAYER + /* Start DHCP Client */ + LwIP_DHCP(0, DHCP_START); +#endif + wifi_get_setting(WLAN0_NAME, &setting); + wifi_show_setting(WLAN0_NAME, &setting); + +#if CONFIG_INIC_CMD_RSP + inic_c2h_wifi_info("ATWW", RTW_SUCCESS); +#endif +} + +static void wps_config_wifi_setting(rtw_network_info_t *wifi, struct dev_credential *dev_cred) +{ + printf("wps_config_wifi_setting\n"); + //memcpy((void *)wifi->ssid, (void *)dev_cred->ssid, dev_cred->ssid_len); + strcpy((char*)wifi->ssid.val, (char*)&dev_cred->ssid[0]); + printf("wps_wifi.ssid = %s\n", wifi->ssid.val); + wifi->ssid.len = dev_cred->ssid_len; + printf("wps_wifi.ssid_len = %d\n", wifi->ssid.len); + + switch(dev_cred->auth_type) { + case WPS_AUTH_TYPE_OPEN : + case WPS_AUTH_TYPE_SHARED : + if(dev_cred->encr_type == WPS_ENCR_TYPE_WEP) { + printf("security_type = RTW_SECURITY_WEP_PSK\n"); + wifi->security_type = RTW_SECURITY_WEP_PSK; + wifi->key_id = dev_cred->key_idx - 1; + } + else { + printf("security_type = RTW_SECURITY_OPEN\n"); + wifi->security_type = RTW_SECURITY_OPEN; + } + break; + case WPS_AUTH_TYPE_WPA_PERSONAL : + case WPS_AUTH_TYPE_WPA_ENTERPRISE : + printf("security_type = RTW_SECURITY_WPA_AES_PSK\n"); + wifi->security_type = RTW_SECURITY_WPA_AES_PSK; + break; + case WPS_AUTH_TYPE_WPA2_PERSONAL : + case WPS_AUTH_TYPE_WPA2_ENTERPRISE : + printf("security_type = RTW_SECURITY_WPA2_AES_PSK\n"); + wifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + } + + printf("wps_wifi.security_type = %d\n", wifi->security_type); + + //memcpy(wifi->password, dev_cred->key, dev_cred->key_len); + wifi->password = dev_cred->key; + printf("wps_wifi.password = %s\n", wifi->password); + wifi->password_len = dev_cred->key_len; + printf("wps_wifi.password_len = %d", wifi->password_len); + //xSemaphoreGive(wps_reconnect_semaphore); + //printf("\r\nrelease wps_reconnect_semaphore"); +} + +static int wps_connect_to_AP_by_certificate(rtw_network_info_t *wifi) +{ +#define RETRY_COUNT 3 + int retry_count = RETRY_COUNT, ret; + + printf("=============== wifi_certificate_info ===============\n"); + printf("wps_wifi.ssid = %s\n", wifi->ssid.val); + printf("security_type = %d\n", wifi->security_type); + printf("wps_wifi.password = %s\n", wifi->password); + printf("ssid_len = %d\n", wifi->ssid.len); + printf("password_len = %d\n", wifi->password_len); + while (1) { + ret = wifi_connect( + NULL, + 0, + (char*)wifi->ssid.val, + wifi->security_type, + (char*)wifi->password, + wifi->key_id, + NULL); + if (ret == RTW_SUCCESS) { + if(retry_count == RETRY_COUNT) + rtw_msleep_os(1000); //When start wps with OPEN AP, AP will send a disassociate frame after STA connected, need reconnect here. + if(RTW_SUCCESS == wifi_is_connected_to_ap( )){ + //printf("\r\n[WPS]Ready to tranceive!\n"); + wps_check_and_show_connection_info(); + break; + } + } + if (retry_count == 0) { + printf("[WPS]Join bss failed\n"); + ret = -1; + break; + } + retry_count --; + } + return ret; +} + +static int wps_connect_to_AP_by_open_system(char *target_ssid) +{ + int retry_count = 3, ret; + + if (target_ssid != NULL) { + rtw_msleep_os(500); //wait scan complete. + while (1) { + ret = wifi_connect( + NULL, + 0, + target_ssid, + RTW_SECURITY_OPEN, + NULL, + 0, + NULL); + if (ret == RTW_SUCCESS) { + //wps_check_and_show_connection_info(); + break; + } + if (retry_count == 0) { + printf("[WPS]Join bss failed\n"); + return -1; + } + retry_count --; + } + // + } else { + printf("[WPS]Target SSID is NULL\n"); + } + + return 0; +} + +static void process_wps_scan_result( rtw_scan_result_t* record, void * user_data ) +{ + internal_wps_scan_handler_arg_t *wps_arg = (internal_wps_scan_handler_arg_t *)user_data; + + if (record->wps_type != 0xff) { + if (wps_arg->config_method == WPS_CONFIG_PUSHBUTTON) { + if (record->wps_type == 0x04) { + wps_password_id = record->wps_type; + if (++wps_arg->isoverlap == 0) { + memcpy(&wps_arg->target_ssid[0], record->SSID.val, record->SSID.len); + wps_arg->target_ssid[record->SSID.len] = '\0'; + printf("[pbc]Record first triger wps AP = %s\n", wps_arg->target_ssid); + } + } + } else if (wps_arg->config_method == WPS_CONFIG_DISPLAY || wps_arg->config_method == WPS_CONFIG_KEYPAD) { + if (record->wps_type == 0x00) { + wps_arg->isoverlap = 0; + wps_password_id = record->wps_type; + memcpy(&wps_arg->target_ssid[0], record->SSID.val, record->SSID.len); + wps_arg->target_ssid[record->SSID.len] = '\0'; + printf("[pin]find out first triger wps AP = %s\n", wps_arg->target_ssid); + } + } + } +} + +static rtw_result_t wps_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) +{ + internal_wps_scan_handler_arg_t *wps_arg = (internal_wps_scan_handler_arg_t *)malloced_scan_result->user_data; + if (malloced_scan_result->scan_complete != RTW_TRUE) + { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + + process_wps_scan_result(record, malloced_scan_result->user_data); + } + else + { + printf("WPS scan done!\n"); + rtw_up_sema(&wps_arg->scan_sema); + } + return RTW_SUCCESS; +} + +extern void wifi_scan_each_report_hdl( char* buf, int buf_len, int flags, void* userdata); +extern void wifi_scan_done_hdl( char* buf, int buf_len, int flags, void* userdata); + +static int wps_find_out_triger_wps_AP(char *target_ssid, u16 config_method) +{ + internal_wps_scan_handler_arg_t wps_arg = {0}; + + wps_password_id = 0xFF; + + wps_arg.isoverlap = -1; + wps_arg.config_method = config_method; + wps_arg.target_ssid = target_ssid; + rtw_init_sema(&wps_arg.scan_sema, 0); + if(wps_arg.scan_sema == NULL) return RTW_ERROR; + + if(wifi_scan_networks(wps_scan_result_handler, &wps_arg ) != RTW_SUCCESS){ + printf("ERROR: wifi scan failed\n"); + goto exit; + } + if(rtw_down_timeout_sema(&wps_arg.scan_sema, SCAN_LONGEST_WAIT_TIME) == RTW_FALSE){ + printf("WPS scan done early!\n"); + } + wifi_unreg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl); + wifi_unreg_event_handler(WIFI_EVENT_SCAN_DONE, wifi_scan_done_hdl); + +exit: + rtw_free_sema(&wps_arg.scan_sema); + + return wps_arg.isoverlap; +} + +int wps_start(u16 wps_config, char *pin, u8 channel, char *ssid) +{ + struct dev_credential dev_cred; + rtw_network_info_t wifi = {0}; + char target_ssid[64]; + int is_overlap = -1; + u32 start_time = rtw_get_current_time(); + int ret = 0; + + memset(&dev_cred, 0, sizeof(struct dev_credential)); + memset(target_ssid, 0, 64); + if((wps_config != WPS_CONFIG_PUSHBUTTON) + && (wps_config != WPS_CONFIG_DISPLAY) + && (wps_config != WPS_CONFIG_KEYPAD)){ + printf("WPS: Wps method(%d) is wrong. Not triger WPS.\n", wps_config); + return -1; + } + config_method = wps_config; + + if(wps_config == WPS_CONFIG_DISPLAY + || wps_config == WPS_CONFIG_KEYPAD) { + if(pin) + strcpy(wps_pin_code, pin); + else{ + printf("WPS: PIN is NULL. Not triger WPS.\n"); + return -1; + } + } + + if(!ssid) { + while (1) { + unsigned int current_time = rtw_get_current_time(); + if (rtw_systime_to_sec(current_time - start_time) < 120) { + is_overlap = wps_find_out_triger_wps_AP(&target_ssid[0], wps_config); + if ((is_overlap == 0) || (is_overlap > 0)) + break; + } else { + printf("WPS: WPS Walking Time Out\n"); + return -2; + } + } + + if (is_overlap > 0) { + printf("WPS: WPS session overlap. Not triger WPS.\n"); + return -2; + } + }else{ + rtw_memcpy(target_ssid, ssid, strlen(ssid)); + } + + if (queue_for_credential != NULL) { + os_xqueue_delete(queue_for_credential); + queue_for_credential = NULL; + } + queue_for_credential = os_xqueue_create(1, sizeof(struct dev_credential)); + if(!queue_for_credential) + return -1; + + wifi_reg_event_handler(WIFI_EVENT_STA_WPS_START, wpas_wsc_sta_wps_start_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_WPS_FINISH, wpas_wsc_wps_finish_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_EAPOL_RECVD, wpas_wsc_eapol_recvd_hdl, NULL); + + wifi_set_wps_phase(ENABLE); + ret = wps_connect_to_AP_by_open_system(target_ssid); + if(ret < 0){ + printf("WPS: WPS Fail!\n"); + goto exit; + } + os_xqueue_receive(queue_for_credential, &dev_cred, 120); + if (dev_cred.ssid[0] != 0 && dev_cred.ssid_len <= 32) { + wps_config_wifi_setting(&wifi, &dev_cred); + wifi_set_wps_phase(DISABLE); + ret = wps_connect_to_AP_by_certificate(&wifi); + goto exit1; + } else { + printf("WPS: WPS FAIL!\n"); +// printf("\n\rWPS: WPS FAIL!\n"); +// printf("\n\rWPS: WPS FAIL!\n"); + ret = -1; + } +exit: + wifi_set_wps_phase(DISABLE); +exit1: + if (queue_for_credential != NULL) { + os_xqueue_delete(queue_for_credential); + queue_for_credential = NULL; + } + + wifi_unreg_event_handler(WIFI_EVENT_STA_WPS_START, wpas_wsc_sta_wps_start_hdl); + wifi_unreg_event_handler(WIFI_EVENT_WPS_FINISH, wpas_wsc_wps_finish_hdl); + wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, wpas_wsc_eapol_recvd_hdl); + + wpas_wps_deinit(); + return ret; +} + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +static int ap_wps_start(u16 wps_config, char *pin) +{ + u8 authorized_mac[ETH_ALEN]; + int ret = 0; + u32 pin_val = 0; + + if (queue_for_credential != NULL) { + os_xqueue_delete(queue_for_credential); + queue_for_credential = NULL; + } + + queue_for_credential = os_xqueue_create(1, sizeof(authorized_mac)); + if(!queue_for_credential) + return -1; + + wifi_reg_event_handler(WIFI_EVENT_STA_WPS_START, wpas_wsc_sta_wps_start_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_WPS_FINISH, wpas_wsc_wps_finish_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_EAPOL_RECVD, wpas_wsc_eapol_recvd_hdl, NULL); + + wifi_set_wps_phase(ENABLE); + + if(wps_config == WPS_CONFIG_KEYPAD) + { + pin_val = atoi(pin); + if (!wps_pin_valid(pin_val)) { + printf("WPS-AP: Enter pin code is unvalid.\n"); + goto exit; + } + ret = wpas_wps_registrar_add_pin((unsigned char const*)pin, strlen(pin)); + } + else if(wps_config == WPS_CONFIG_DISPLAY) + ret = wpas_wps_registrar_add_pin((unsigned char const*)pin, strlen(pin)); + else + ret = wpas_wps_registrar_button_pushed(); + + if(ret<0) + goto exit; + + printf("WPS-AP: wait for STA connect!\n"); + os_xqueue_receive(queue_for_credential, authorized_mac, 120); //max wait 2min + + if(!wpas_wps_registrar_check_done()) + { + ret = -1; + wpas_wps_registrar_wps_cancel(); + } + +exit: + wifi_set_wps_phase(0); + os_xqueue_delete(queue_for_credential); + queue_for_credential = NULL; + printf("WPS-AP: Finished!\n"); + + wifi_unreg_event_handler(WIFI_EVENT_STA_WPS_START, wpas_wsc_sta_wps_start_hdl); + wifi_unreg_event_handler(WIFI_EVENT_WPS_FINISH, wpas_wsc_wps_finish_hdl); + wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, wpas_wsc_eapol_recvd_hdl); + + return ret; +} + +static void wifi_start_ap_wps_thread_hdl( void *param) +{ + ap_wps_start(config_method, wps_pin_code); //Not support WPS_CONFIG_KEYPAD + + ap_wps_task = NULL; + vTaskDelete(NULL); +} + +void wifi_start_ap_wps_thread(u16 config_methods, char *pin) +{ + if((config_methods != WPS_CONFIG_PUSHBUTTON) + && (config_methods != WPS_CONFIG_DISPLAY) + && (config_methods != WPS_CONFIG_KEYPAD)){ + printf("WPS-AP: Wps method(%d) is wrong. Not triger WPS.\n", config_methods); + return; + } + config_method = config_methods; + if(config_methods == WPS_CONFIG_DISPLAY + || config_methods == WPS_CONFIG_KEYPAD) { + if(pin) + strcpy(wps_pin_code, pin); + else{ + printf("WPS-AP: PIN is NULL. Not triger WPS.\n"); + return; + } + } + if(ap_wps_task != NULL){ //push item to wait queue to finish last ap_wps task + printf("WPS-AP: Wait for last ap_wps task exiting...\n"); + if(queue_for_credential) + os_xqueue_send(queue_for_credential, NULL, 0); + while(ap_wps_task != NULL) + vTaskDelay(1); + vTaskDelay(20); + printf("Last ap_wps task completed.\n"); + } + if(xTaskCreate(wifi_start_ap_wps_thread_hdl, ((const char*)"ap_wps"), 256, NULL, tskIDLE_PRIORITY + 3, &ap_wps_task) != pdPASS) + printf("%s xTaskCreate(ap_wps thread) failed\n", __FUNCTION__); +} + +#endif //CONFIG_ENABLE_WPS_AP + +void wps_judge_staion_disconnect(void) +{ + int mode = 0; + unsigned char ssid[33]; + + wext_get_mode(WLAN0_NAME, &mode); + + switch(mode) { + case IW_MODE_MASTER: //In AP mode +// rltk_wlan_deinit(); +// rltk_wlan_init(0,RTW_MODE_STA); +// rltk_wlan_start(0); + //modified by Chris Yang for iNIC + wifi_off(); + vTaskDelay(20); + wifi_on(RTW_MODE_STA); + break; + case IW_MODE_INFRA: //In STA mode + if(wext_get_ssid(WLAN0_NAME, ssid) > 0) + wifi_disconnect(); + } +} + +void cmd_wps(int argc, char **argv) +{ + int ret = -1; + wps_judge_staion_disconnect(); + + if((argc == 2 || argc == 3 ) && (argv[1] != NULL)){ + if(strcmp(argv[1],"pin") == 0){ + unsigned int pin_val = 0; + /* start pin */ + if(argc == 2){ + char device_pin[10]; + pin_val = wps_generate_pin(); + sprintf(device_pin, "%08d", pin_val); + /* Display PIN 3 times to prevent to be overwritten by logs from other tasks */ + printf("WPS: Start WPS PIN Display. PIN: [%s]\n", device_pin); + printf("WPS: Start WPS PIN Display. PIN: [%s]\n", device_pin); + printf("WPS: Start WPS PIN Display. PIN: [%s]\n", device_pin); + ret = wps_start(WPS_CONFIG_DISPLAY, (char*)device_pin, 0, NULL); + }else{ + pin_val = atoi(argv[2]); + if (!wps_pin_valid(pin_val)) { + printf("WPS: Device pin code is invalid. Not triger WPS.\n"); + goto exit; + } + printf("WPS: Start WPS PIN Keypad.\n"); + ret = wps_start(WPS_CONFIG_KEYPAD, argv[2], 0, NULL); + } + }else if(strcmp(argv[1],"pbc") == 0){ + /* start pbc */ + printf("WPS: Start WPS PBC.\n"); + ret = wps_start(WPS_CONFIG_PUSHBUTTON, NULL, 0, NULL); + }else{ + printf("WPS: Wps Method is wrong. Not triger WPS.\n"); + goto exit; + } + } +exit: +#if CONFIG_INIC_CMD_RSP + if(ret != 0) + inic_c2h_msg("ATWW", ret, NULL, 0); +#endif + return; +} + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +/* +cmd_ap_wps for AP WSC setting. command style: +cmd_ap_wps pbc or cmd_ap_wps pin 12345678 +*/ +void cmd_ap_wps(int argc, char **argv) +{ + int mode = 0; + if(rltk_wlan_running(WLAN1_IDX)){ + printf("Not support con-current softAP WSC!\n"); + return; + } + wext_get_mode(WLAN0_NAME, &mode); + if(mode != IW_MODE_MASTER){ + printf("Only valid for IW_MODE_MASTER!\n"); + return; + } + + if((argc == 2 || argc == 3) && (argv[1] != NULL)) { + if (strcmp(argv[1],"pin") == 0 ) { + unsigned int pin_val = 0; + if(argc == 3){ + pin_val = atoi(argv[2]); + if (!wps_pin_valid(pin_val)) { + printf("WPS-AP: Device pin code is invalid. Not trigger WPS.\n"); + return; + } + printf("WPS-AP: Start AP WPS PIN Keypad.\n"); + wifi_start_ap_wps_thread(WPS_CONFIG_KEYPAD, argv[2]); + }else{ + char device_pin[10]; + pin_val = wps_generate_pin(); + sprintf(device_pin, "%08d", pin_val); + printf("WPS: Start WPS PIN Display. PIN: %s\n", device_pin); + wifi_start_ap_wps_thread(WPS_CONFIG_DISPLAY, (char*)device_pin); + } + }else if (strcmp(argv[1],"pbc") == 0) { + printf("WPS-AP: Start AP WPS PBC\n"); + wifi_start_ap_wps_thread(WPS_CONFIG_PUSHBUTTON, NULL); + }else{ + printf("WPS-AP Usage:\"wifi_ap_wps pin [pin_code]\" or \"wifi_ap_wps pbc\"\n"); + return; + } + } else { + printf("WPS-AP Usage:\"wifi_ap_wps pin [pin_code]\" or \"wifi_ap_wps pbc\"\n"); + } + return; +} +#endif //CONFIG_ENABLE_P2P +#endif //CONFIG_ENABLE_WPS diff --git a/USDK/component/common/api/wifi/wifi_conf.c b/USDK/component/common/api/wifi/wifi_conf.c new file mode 100644 index 0000000..f28327f --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_conf.c @@ -0,0 +1,1748 @@ +//----------------------------------------------------------------------------// +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include +#include +#include +#if 1 +#include "drv_types.h" // or #include "wlan_lib.h" +#else +#include "wifi_constants.h" +#include "wifi_structures.h" +//#include "wlan_lib.h" // or #include "drv_types.h" +#endif +#include +#include + +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#include "wlan_fast_connect/example_wlan_fast_connect.h" +#endif +#if CONFIG_EXAMPLE_UART_ATCMD +#include "at_cmd/atcmd_wifi.h" +#endif +#if CONFIG_INIC_EN +extern int inic_start(void); +extern int inic_stop(void); +#endif + +#if CONFIG_DEBUG_LOG > 0 +#undef printf +#define printf(...) rtl_printf(__VA_ARGS__) +#else +#undef printf +#define printf(...) +#endif + +//#define sscanf _sscanf + +#define SHOW_PRIVATE_OUT 0 // =0 - off, = 1 On + +/****************************************************** + * Constants + ******************************************************/ +#define RTW_JOIN_TIMEOUT 15000 + +#define JOIN_ASSOCIATED (uint32_t)(1 << 0) +#define JOIN_AUTHENTICATED (uint32_t)(1 << 1) +#define JOIN_LINK_READY (uint32_t)(1 << 2) +#define JOIN_SECURITY_COMPLETE (uint32_t)(1 << 3) +#define JOIN_COMPLETE (uint32_t)(1 << 4) +#define JOIN_NO_NETWORKS (uint32_t)(1 << 5) +#define JOIN_WRONG_SECURITY (uint32_t)(1 << 6) +#define JOIN_HANDSHAKE_DONE (uint32_t)(1 << 7) +#define JOIN_SIMPLE_CONFIG (uint32_t)(1 << 8) +#define JOIN_AIRKISS (uint32_t)(1 << 9) + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Variables Declarations + ******************************************************/ + + +extern struct netif xnetif[NET_IF_NUM]; + +/****************************************************** + * Variables Definitions + ******************************************************/ +internal_scan_handler_t scan_result_handler_ptr; +static internal_join_result_t* join_user_data; +unsigned char wifi_mode = RTW_MODE_NONE; // rtw_mode_t +//extern rtw_mode_t wifi_mode; +char error_flag = RTW_UNKNOWN; +uint32_t rtw_join_status; +#if ATCMD_VER == ATVER_2 +extern unsigned char dhcp_mode_sta; +#endif + +/****************************************************** + * Variables Definitions + ******************************************************/ + +#ifndef WLAN0_NAME +#define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME +#define WLAN1_NAME "wlan1" +#endif +/* Give default value if not defined */ +#ifndef NET_IF_NUM +#ifdef CONFIG_CONCURRENT_MODE +#define NET_IF_NUM 2 +#else +#define NET_IF_NUM 1 +#endif +#endif + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 1 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 1 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +/****************************************************** + * Function Definitions + ******************************************************/ + +#if CONFIG_WLAN +#define DD_WIFI_CONN 0 // pvvx +//----------------------------------------------------------------------start-patch// +#include "freertos/wrapper.h" +#include "skbuff.h" + +//------------------------------------------------------------------------end-patch// +static int wifi_connect_local(rtw_network_info_t *pWifi) { + int ret = 0; + + if (is_promisc_enabled()) + promisc_set(0, NULL, 0); + + if (!pWifi) + return -1; + switch (pWifi->security_type) { + case RTW_SECURITY_OPEN: + ret = wext_set_key_ext(WLAN0_NAME, IW_ENCODE_ALG_NONE, NULL, 0, 0, 0, 0, + NULL, 0); + break; + case RTW_SECURITY_WEP_PSK: + case RTW_SECURITY_WEP_SHARED: + ret = wext_set_auth_param(WLAN0_NAME, IW_AUTH_80211_AUTH_ALG, + IW_AUTH_ALG_SHARED_KEY); + if (ret == 0) + ret = wext_set_key_ext(WLAN0_NAME, IW_ENCODE_ALG_WEP, NULL, + pWifi->key_id, 1 /* set tx key */, 0, 0, pWifi->password, + pWifi->password_len); + break; + case RTW_SECURITY_WPA_TKIP_PSK: + case RTW_SECURITY_WPA2_TKIP_PSK: + ret = wext_set_auth_param(WLAN0_NAME, IW_AUTH_80211_AUTH_ALG, + IW_AUTH_ALG_OPEN_SYSTEM); + if (ret == 0) + ret = wext_set_key_ext(WLAN0_NAME, IW_ENCODE_ALG_TKIP, NULL, 0, 0, + 0, 0, NULL, 0); + if (ret == 0) + ret = wext_set_passphrase(WLAN0_NAME, pWifi->password, + pWifi->password_len); + break; + case RTW_SECURITY_WPA_AES_PSK: + case RTW_SECURITY_WPA2_AES_PSK: + case RTW_SECURITY_WPA2_MIXED_PSK: + case RTW_SECURITY_WPA_WPA2_MIXED: + ret = wext_set_auth_param(WLAN0_NAME, IW_AUTH_80211_AUTH_ALG, + IW_AUTH_ALG_OPEN_SYSTEM); + if (ret == 0) + ret = wext_set_key_ext(WLAN0_NAME, IW_ENCODE_ALG_CCMP, NULL, 0, 0, + 0, 0, NULL, 0); + if (ret == 0) + ret = wext_set_passphrase(WLAN0_NAME, pWifi->password, + pWifi->password_len); + break; + default: + ret = -1; + error_printf("%s: security type(0x%x) is not supported!\n", + pWifi->security_type, __func__); + break; + } + return ret; +} + +void wifi_rx_beacon_hdl(char* buf, int buf_len, int flags, void* userdata) { + //printf("Beacon!\n"); +} + +static void wifi_no_network_hdl(char* buf, int buf_len, int flags, + void* userdata) { + if (join_user_data != NULL) + rtw_join_status = JOIN_NO_NETWORKS; +} + +static void wifi_connected_hdl(char* buf, int buf_len, int flags, + void* userdata) { +#ifdef CONFIG_ENABLE_EAP + if(get_eap_phase()) { + rtw_join_status = JOIN_COMPLETE | JOIN_SECURITY_COMPLETE | JOIN_ASSOCIATED | JOIN_AUTHENTICATED | JOIN_LINK_READY; + return; + } +#endif /* CONFIG_ENABLE_EAP */ + if ((join_user_data != NULL) + && ((join_user_data->network_info.security_type == RTW_SECURITY_OPEN) + || (join_user_data->network_info.security_type + == RTW_SECURITY_WEP_PSK))) { + rtw_join_status = JOIN_COMPLETE | JOIN_SECURITY_COMPLETE + | JOIN_ASSOCIATED | JOIN_AUTHENTICATED | JOIN_LINK_READY; + rtw_up_sema(&join_user_data->join_sema); + } else if ((join_user_data != NULL) + && ((join_user_data->network_info.security_type + == RTW_SECURITY_WPA2_AES_PSK))) { + rtw_join_status = JOIN_COMPLETE | JOIN_SECURITY_COMPLETE + | JOIN_ASSOCIATED | JOIN_AUTHENTICATED | JOIN_LINK_READY; + } +} +static void wifi_handshake_done_hdl(char* buf, int buf_len, int flags, + void* userdata) { + rtw_join_status = JOIN_COMPLETE | JOIN_SECURITY_COMPLETE | JOIN_ASSOCIATED + | JOIN_AUTHENTICATED | JOIN_LINK_READY | JOIN_HANDSHAKE_DONE; + if (join_user_data != NULL) + rtw_up_sema(&join_user_data->join_sema); +} + +static void wifi_disconn_hdl(char* buf, int buf_len, int flags, void* userdata) { + if (join_user_data != NULL) { + if (join_user_data->network_info.security_type == RTW_SECURITY_OPEN) { + + if (rtw_join_status == JOIN_NO_NETWORKS) + error_flag = RTW_NONE_NETWORK; + + } else if (join_user_data->network_info.security_type + == RTW_SECURITY_WEP_PSK) { + + if (rtw_join_status == JOIN_NO_NETWORKS) + error_flag = RTW_NONE_NETWORK; + + else if (rtw_join_status == 0) + error_flag = RTW_CONNECT_FAIL; + + } else if (join_user_data->network_info.security_type + == RTW_SECURITY_WPA2_AES_PSK) { + + if (rtw_join_status == JOIN_NO_NETWORKS) + error_flag = RTW_NONE_NETWORK; + + else if (rtw_join_status == 0) + error_flag = RTW_CONNECT_FAIL; + + else if (rtw_join_status == JOIN_COMPLETE | JOIN_SECURITY_COMPLETE + | JOIN_ASSOCIATED | JOIN_AUTHENTICATED | JOIN_LINK_READY) + error_flag = RTW_WRONG_PASSWORD; + } + + } else { + if (error_flag == RTW_NO_ERROR) //wifi_disconn_hdl will be dispatched one more time after join_user_data = NULL add by frankie + error_flag = RTW_UNKNOWN; + } + + if (join_user_data != NULL) + rtw_up_sema(&join_user_data->join_sema); +#if CONFIG_DEBUG_LOG > 4 + info_printf("%s: Error flag is %d!\n", __func__, error_flag); +#endif +} + +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#define WLAN0_NAME "wlan0" // ????? + +void restore_wifi_info_to_flash() { + struct wlan_fast_reconnect * data_to_flash; + u32 channel = 0; + u8 index = 0; + u8 *ifname[1] = { WLAN0_NAME }; + rtw_wifi_setting_t setting; + //struct security_priv *psecuritypriv = &padapter->securitypriv; + //WLAN_BSSID_EX *pcur_bss = pmlmepriv->cur_network.network; + + data_to_flash = (struct wlan_fast_reconnect *) rtw_zmalloc( + sizeof(struct wlan_fast_reconnect)); + + if (data_to_flash && p_write_reconnect_ptr) { + if (wifi_get_setting((const char*) ifname[0], &setting) + || setting.mode == RTW_MODE_AP) { + printf(" %s():wifi_get_setting fail or ap mode\n", __func__); + return; + } + channel = setting.channel; + + rtw_memset(psk_essid[index], 0, sizeof(psk_essid[index])); + strncpy(psk_essid[index], setting.ssid, strlen(setting.ssid)); + switch (setting.security_type) { + case RTW_SECURITY_OPEN: + rtw_memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + rtw_memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + data_to_flash->security_type = RTW_SECURITY_OPEN; + break; + case RTW_SECURITY_WEP_PSK: + channel |= (setting.key_idx) << 28; + rtw_memset(psk_passphrase[index], 0, sizeof(psk_passphrase[index])); + rtw_memset(wpa_global_PSK[index], 0, sizeof(wpa_global_PSK[index])); + rtw_memcpy(psk_passphrase[index], setting.password, + sizeof(psk_passphrase[index])); + data_to_flash->security_type = RTW_SECURITY_WEP_PSK; + break; + case RTW_SECURITY_WPA_TKIP_PSK: + data_to_flash->security_type = RTW_SECURITY_WPA_TKIP_PSK; + break; + case RTW_SECURITY_WPA2_AES_PSK: + data_to_flash->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + default: + break; + } + + memcpy(data_to_flash->psk_essid, psk_essid[index], + sizeof(data_to_flash->psk_essid)); + if (strlen(psk_passphrase64) == 64) { + memcpy(data_to_flash->psk_passphrase, psk_passphrase64, + sizeof(data_to_flash->psk_passphrase)); + } else { + memcpy(data_to_flash->psk_passphrase, psk_passphrase[index], + sizeof(data_to_flash->psk_passphrase)); + } + memcpy(data_to_flash->wpa_global_PSK, wpa_global_PSK[index], + sizeof(data_to_flash->wpa_global_PSK)); + memcpy(&(data_to_flash->channel), &channel, 4); + + //call callback function in user program + p_write_reconnect_ptr((u8 *) data_to_flash, + sizeof(struct wlan_fast_reconnect)); + + } + if (data_to_flash) + rtw_free(data_to_flash); +} + +#endif + +//----------------------------------------------------------------------------// +int wifi_connect( + unsigned char bssid[ETH_ALEN], + char use_bssid, // flag + char *ssid, + rtw_security_t security_type, + char *password, + int key_id, + void *semaphore) { + + int ssid_len = 0; + int password_len = 0; + int bssid_len = 6; + xSemaphoreHandle join_semaphore; + rtw_result_t result = RTW_SUCCESS; + u8 wep_hex = 0; + u8 wep_pwd[14] = { 0 }; + + if ((rtw_join_status & JOIN_SIMPLE_CONFIG ) + || (rtw_join_status & JOIN_AIRKISS )) { + return RTW_ERROR; + } + + if(ssid) { + ssid_len = rtl_strlen(ssid); + if(ssid_len > NDIS_802_11_LENGTH_SSID) + ssid_len = NDIS_802_11_LENGTH_SSID; + } + if(password) { + password_len = rtl_strlen(password); + if(password_len > IW_PASSPHRASE_MAX_SIZE) + password_len = IW_PASSPHRASE_MAX_SIZE; + } + + rtw_join_status = 0; //clear for last connect status + error_flag = RTW_UNKNOWN; //clear for last connect status + internal_join_result_t *join_result = + (internal_join_result_t *) rtw_zmalloc( + sizeof(internal_join_result_t)); + if (!join_result) { +#if CONFIG_DEBUG_LOG > 3 + error_printf("%s: Can't malloc memory!\n", __func__); +#endif + return RTW_NOMEM; + } + if (ssid_len && ssid) { + join_result->network_info.ssid.len = ssid_len > 32 ? 32 : ssid_len; + rtw_memcpy(join_result->network_info.ssid.val, ssid, ssid_len); + } + if(bssid) rtw_memcpy(join_result->network_info.bssid.octet, bssid, ETH_ALEN); + + error_flag = RTW_UNKNOWN; //clear for last connect status + if ((((password_len > RTW_MAX_PSK_LEN) || (password_len < RTW_MIN_PSK_LEN)) + && ((security_type == RTW_SECURITY_WPA_TKIP_PSK) + || (security_type == RTW_SECURITY_WPA_AES_PSK) + || (security_type == RTW_SECURITY_WPA2_AES_PSK) + || (security_type == RTW_SECURITY_WPA2_TKIP_PSK) + || (security_type == RTW_SECURITY_WPA2_MIXED_PSK)))) { + error_flag = RTW_WRONG_PASSWORD; + return RTW_INVALID_KEY; + } + + if ((security_type == RTW_SECURITY_WEP_PSK) + || (security_type == RTW_SECURITY_WEP_SHARED)) { + if ((password_len != 5) && (password_len != 13) && (password_len != 10) + && (password_len != 26)) { + error_flag = RTW_WRONG_PASSWORD; + return RTW_INVALID_KEY; + } else { + + if (password_len == 10) { + + u32 g[5] = { 0 }; + u8 i = 0; + sscanf((const char*) password, "%02x%02x%02x%02x%02x", &g[0], + &g[1], &g[2], &g[3], &g[4]); + for (i = 0; i < 5; i++) + wep_pwd[i] = (u8) g[i]; + wep_pwd[5] = '\0'; + password_len = 5; + wep_hex = 1; + } else if (password_len == 26) { + u32 g[13] = { 0 }; + u8 i = 0; + sscanf((const char*) password, "%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x", &g[0], &g[1], &g[2], &g[3], + &g[4], &g[5], &g[6], &g[7], &g[8], &g[9], &g[10], + &g[11], &g[12]); + for (i = 0; i < 13; i++) + wep_pwd[i] = (u8) g[i]; + wep_pwd[13] = '\0'; + password_len = 13; + wep_hex = 1; + } + } + } + + join_result->network_info.password_len = password_len; + + if (password_len) { + /* add \0 to the end */ + join_result->network_info.password = rtw_zmalloc(password_len + 1); + if (!join_result->network_info.password) { + result = RTW_NOMEM; +#if CONFIG_DEBUG_LOG > 3 + error_printf("%s: Can't malloc memory!\n", __func__); +#endif + goto error; + } + if (0 == wep_hex) + rtw_memcpy(join_result->network_info.password, password, + password_len); + else + rtw_memcpy(join_result->network_info.password, wep_pwd, + password_len); + + } + + join_result->network_info.security_type = security_type; + join_result->network_info.key_id = key_id; + + if (semaphore == NULL) { + rtw_init_sema(&join_result->join_sema, 0); + if (!join_result->join_sema) { + result = RTW_NORESOURCE; + goto error; + } + join_semaphore = join_result->join_sema; + } else { + join_result->join_sema = semaphore; + } + wifi_reg_event_handler(WIFI_EVENT_NO_NETWORK, wifi_no_network_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_CONNECT, wifi_connected_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, wifi_disconn_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_FOURWAY_HANDSHAKE_DONE, + wifi_handshake_done_hdl, NULL); + + rtw_network_info_t *pWifi = &join_result->network_info; + + if (wifi_connect_local(pWifi) == 0) { + uint16 flg = 0; + if(use_bssid) { + struct { + u8 bssid[ETH_ALEN + 2]; + void * p; + } bs = { 0 }; + memcpy(bs.bssid, pWifi->bssid.octet, ETH_ALEN); + for(int i = 0; i < ETH_ALEN; i++) { + flg += bs.bssid[i]; + } + if(flg == 0x5FA || flg == 0) { // 0x5FA = 6*0xff + use_bssid = 0; + flg = 0; + } + else { + use_bssid = 1; + wext_set_bssid(WLAN0_NAME, bs.bssid); + } + } + if(!use_bssid) { + wext_set_ssid(WLAN0_NAME, join_result->network_info.ssid.val, + join_result->network_info.ssid.len); + }; + } + join_user_data = join_result; + + if (semaphore == NULL) { +// for eap connection, timeout should be longer (default value in wpa_supplicant: 60s) +#ifdef CONFIG_ENABLE_EAP + if(get_eap_phase()) { + if(rtw_down_timeout_sema( &join_result->join_sema, 60000 ) == RTW_FALSE) { + printf("RTW API: Join bss timeout\n"); + if(password_len) { + rtw_free(join_result->network_info.password); + } + result = RTW_TIMEOUT; + goto error; + } else { + if(wifi_is_connected_to_ap( ) != RTW_SUCCESS) { + result = RTW_ERROR; + goto error; + } + } + } + else +#endif + if (rtw_down_timeout_sema(&join_result->join_sema, RTW_JOIN_TIMEOUT) + == RTW_FALSE) { + warning_printf("RTW API: Join bss timeout\n"); + if (password_len) { + rtw_free(join_result->network_info.password); + } + result = RTW_TIMEOUT; + goto error; + } else { + if (join_result->network_info.password_len) { + rtw_free(join_result->network_info.password); + } + if (wifi_is_connected_to_ap() != RTW_SUCCESS) { + result = RTW_ERROR; + goto error; + } + } + } + + result = RTW_SUCCESS; + +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT + restore_wifi_info_to_flash(); +#endif + + error: if (semaphore == NULL) { + rtw_free_sema(&join_semaphore); + } + join_user_data = NULL; + rtw_free((u8*)join_result); + wifi_unreg_event_handler(WIFI_EVENT_CONNECT, wifi_connected_hdl); + wifi_unreg_event_handler(WIFI_EVENT_NO_NETWORK, wifi_no_network_hdl); + wifi_unreg_event_handler(WIFI_EVENT_FOURWAY_HANDSHAKE_DONE, + wifi_handshake_done_hdl); + return result; +} + +int wifi_disconnect(void) { + int ret = 0; + + //set MAC address last byte to 1 since driver will filter the mac with all 0x00 or 0xff + //add extra 2 zero byte for check of #@ in wext_set_bssid() + const __u8 null_bssid[ETH_ALEN + 2] = { 0, 0, 0, 0, 0, 1, 0, 0 }; + + if (wext_set_bssid(WLAN0_NAME, null_bssid) < 0) { + error_printf("WEXT: Failed to set bogus BSSID to disconnect\n"); + ret = -1; + } + return ret; +} +//----------------------------------------------------------------------------// +int wifi_is_connected_to_ap(void) { + return rltk_wlan_is_connected_to_ap(); +} + +//----------------------------------------------------------------------------// +int wifi_is_up(rtw_interface_t interface) { + if (interface == RTW_AP_INTERFACE && wifi_mode == RTW_MODE_STA_AP) + return rltk_wlan_running(WLAN1_IDX); + return rltk_wlan_running(WLAN0_IDX); +} + +int wifi_is_ready_to_transceive(rtw_interface_t interface) { + switch (interface) { + case RTW_AP_INTERFACE: + return (wifi_is_up(interface) == RTW_TRUE) ? RTW_SUCCESS : RTW_ERROR; + + case RTW_STA_INTERFACE: + if (error_flag == RTW_NO_ERROR) + return RTW_SUCCESS; + break; + } + return RTW_ERROR; +} + +//----------------------------------------------------------------------------// +int wifi_set_mac_address(char * mac) { + char buf[13 + 17 + 1]; + rtw_memset(buf, 0, sizeof(buf)); + snprintf(buf, 13 + 17, "write_mac %s", mac); + return wext_private_command(WLAN0_NAME, buf, SHOW_PRIVATE_OUT); +} + +int wifi_get_mac_address(char * mac) { + int ret = 0; + char buf[32]; + rtw_memset(buf, 0, sizeof(buf)); + rtw_memcpy(buf, "read_mac", 8); + ret = wext_private_command_with_retval(WLAN0_NAME, buf, buf, 32); +#if SHOW_PRIVATE_OUT + rtl_printf("%s\n", buf); +#endif + strcpy(mac, buf); + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_enable_powersave(void) { + return wext_enable_powersave(WLAN0_NAME, 1, 1); +} + +int wifi_disable_powersave(void) { + return wext_disable_powersave(WLAN0_NAME); +} + +#if 0 //Not ready +//----------------------------------------------------------------------------// +int wifi_get_txpower(int *poweridx) { + int ret; + // char buf[11]; + char buf[64]; + + rtw_memset(buf, 0, sizeof(buf)); + rtw_memcpy(buf, "txpower", 11); + ret = wext_private_command_with_retval(WLAN0_NAME, buf, buf, sizeof(buf)); +#if SHOW_PRIVATE_OUT + rtl_printf("%s\n", buf); +#endif + sscanf(buf, "%d", poweridx); + + return ret; +} + +int wifi_set_txpower(int poweridx) { + int ret; + char buf[24]; + + rtw_memset(buf, 0, sizeof(buf)); + snprintf(buf, 24, "txpower patha=%d,pathb=%d", poweridx, poweridx); // patha=%d,pathb=%d ? + ret = wext_private_command(WLAN0_NAME, buf, SHOW_PRIVATE_OUT); + + return ret; +} +#endif + +//----------------------------------------------------------------------------// +int wifi_get_associated_client_list(void * client_list_buffer, + uint16_t buffer_length) { + const char * ifname = WLAN0_NAME; + int ret = 0; + char buf[25]; + + if (wifi_mode == RTW_MODE_STA_AP) { + ifname = WLAN1_NAME; + } + + rtw_memset(buf, 0, sizeof(buf)); + snprintf(buf, 25, "get_client_list %x", client_list_buffer); + ret = wext_private_command(ifname, buf, SHOW_PRIVATE_OUT); + + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_get_ap_info(rtw_bss_info_t * ap_info, rtw_security_t* security) { + const char * ifname = WLAN0_NAME; + int ret = 0; + char buf[24]; + + if (wifi_mode == RTW_MODE_STA_AP) { + ifname = WLAN1_NAME; + } + + rtw_memset(buf, 0, sizeof(buf)); + snprintf(buf, 24, "get_ap_info %x", ap_info); + ret = wext_private_command(ifname, buf, SHOW_PRIVATE_OUT); + + snprintf(buf, 24, "get_security"); + ret = wext_private_command_with_retval(ifname, buf, buf, 24); +#if SHOW_PRIVATE_OUT + rtl_printf("%s\n", buf); +#endif + sscanf(buf, "%d", security); + + return ret; +} + +int wifi_get_drv_ability(uint32_t *ability) { + return wext_get_drv_ability(WLAN0_NAME, ability); +} + +//----------------------------------------------------------------------------// +int wifi_set_country(rtw_country_code_t country_code) { + int ret; + + ret = wext_set_country(WLAN0_NAME, country_code); + + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_set_channel_plan(uint8_t channel_plan) { + const char * ifname = WLAN0_NAME; + int ret = 0; + char buf[24]; + + rtw_memset(buf, 0, sizeof(buf)); + snprintf(buf, 24, "set_ch_plan %x", channel_plan); + ret = wext_private_command(ifname, buf, SHOW_PRIVATE_OUT); + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_get_rssi(int *pRSSI) { + return wext_get_rssi(WLAN0_NAME, pRSSI); +} + +//----------------------------------------------------------------------------// +int wifi_set_channel(int channel) { + return wext_set_channel(WLAN0_NAME, channel); +} + +int wifi_get_channel(int *channel) { + return wext_get_channel(WLAN0_NAME, (u8*) channel); +} + +//----------------------------------------------------------------------------// +int wifi_register_multicast_address(rtw_mac_t *mac) { + return wext_register_multicast_address(WLAN0_NAME, mac); +} + +int wifi_unregister_multicast_address(rtw_mac_t *mac) { + return wext_unregister_multicast_address(WLAN0_NAME, mac); +} + +//----------------------------------------------------------------------------// +void wifi_set_mib(void) { + // adaptivity + wext_set_adaptivity(RTW_ADAPTIVITY_DISABLE); +} + +//----------------------------------------------------------------------------// +int wifi_rf_on(void) { + int ret; + ret = rltk_wlan_rf_on(); + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_rf_off(void) { + int ret; + ret = rltk_wlan_rf_off(); + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_on(rtw_mode_t mode) { + int ret = 0; + int timeout = wifi_test_timeout_ms / wifi_test_timeout_step_ms; + int idx; + int devnum = 1; + static int event_init = 0; + + if (rltk_wlan_running(WLAN0_IDX)) { + warning_printf("WIFI is already running\n"); + return 0; + } + + if (event_init == 0) { + init_event_callback_list(); + event_init = 1; + } + + wifi_mode = mode; + + if (mode == RTW_MODE_STA_AP) + devnum = 2; + + // set wifi mib + wifi_set_mib(); + printf("Initializing WIFI ...\n"); + for (idx = 0; idx < devnum; idx++) { + ret = rltk_wlan_init(idx, mode); + if (ret < 0) + return ret; + } + for (idx = 0; idx < devnum; idx++) + rltk_wlan_start(idx); + + while (1) { + if (rltk_wlan_running(devnum - 1)) { + printf("WIFI initialized\n"); + /* + * printf("set country code here\n"); + * wifi_set_country(RTW_COUNTRY_US); + */ + break; + } + + if (timeout == 0) { + printf("ERROR: Init WIFI timeout!\n"); + break; + } + +// vTaskDelay(1 * configTICK_RATE_HZ); + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + + timeout--; + } + +#if CONFIG_INIC_EN + inic_start(); +#endif + + return ret; +} + +int wifi_off(void) { +// int ret = 0; + + uint32 timeout = xTaskGetTickCount(); + +#if CONFIG_LWIP_LAYER + dhcps_deinit(); + LwIP_DHCP(0, DHCP_STOP); + LwIP_DHCP(1, DHCP_STOP); +#endif + if ((rltk_wlan_running(WLAN0_IDX) == 0) + && (rltk_wlan_running(WLAN1_IDX) == 0)) { + info_printf("WIFI is not running\n"); + return 0; + } + info_printf("Deinitializing WIFI ...\n"); + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + // @todo + wpas_wps_deinit(); +#endif + rltk_wlan_deinit(); + + while (1) { + if ((rltk_wlan_running(WLAN0_IDX) == 0) + && (rltk_wlan_running(WLAN1_IDX) == 0)) { +// info_printf("WIFI deinitialized\n"); + info_printf("WIFI deinitialized (%d ms)\n", xTaskGetTickCount() - timeout); + break; + } + if(xTaskGetTickCount() - timeout > wifi_test_timeout_ms/portTICK_RATE_MS) { + error_printf("WIFI deinitialized timeout!\n"); + break; + } + vTaskDelay(10 / portTICK_RATE_MS); + } + + wifi_mode = RTW_MODE_NONE; + +#if CONFIG_INIC_EN + inic_stop(); +#endif + + return 1; +} + +int wifi_set_power_mode(unsigned char ips_mode, unsigned char lps_mode) { + return wext_enable_powersave(WLAN0_NAME, ips_mode, lps_mode); +} + +int wifi_set_tdma_param(unsigned char slot_period, + unsigned char rfon_period_len_1, unsigned char rfon_period_len_2, + unsigned char rfon_period_len_3) { + return wext_set_tdma_param(WLAN0_NAME, slot_period, rfon_period_len_1, + rfon_period_len_2, rfon_period_len_3); +} + +int wifi_set_lps_dtim(unsigned char dtim) { + return wext_set_lps_dtim(WLAN0_NAME, dtim); +} + +int wifi_get_lps_dtim(unsigned char *dtim) { + return wext_get_lps_dtim(WLAN0_NAME, dtim); +} +//----------------------------------------------------------------------------// +/* +static void wifi_ap_sta_assoc_hdl(char* buf, int buf_len, int flags, + void* userdata) { + //USER TODO + debug_printf("ap_sta_assoc\n"); +} +static void wifi_ap_sta_disassoc_hdl(char* buf, int buf_len, int flags, + void* userdata) { + //USER TODO + debug_printf("ap_sta_disassoc\n"); +} +*/ + +int wifi_get_last_error(void) { + return error_flag; +} + + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +int wpas_wps_init(const char* ifname); +#endif + +int wifi_start_ap(char *ssid, rtw_security_t security_type, char *password, int channel, char ssid_hidden) { + const char *ifname = WLAN0_NAME; + int ssid_len = 0; + int password_len = 0; + int ret = 0; + if(ssid) { + ssid_len = rtl_strlen(ssid); + if(ssid_len > NDIS_802_11_LENGTH_SSID) + ssid_len = NDIS_802_11_LENGTH_SSID; + } + if(password) { + password_len = rtl_strlen(password); + if(password_len > IW_PASSPHRASE_MAX_SIZE) + password_len = IW_PASSPHRASE_MAX_SIZE; + } + + if (wifi_mode == RTW_MODE_STA_AP) { + ifname = WLAN1_NAME; + } + + if (is_promisc_enabled()) + promisc_set(0, NULL, 0); +/* + wifi_unreg_event_handler(WIFI_EVENT_STA_ASSOC, wifi_ap_sta_assoc_hdl); + wifi_reg_event_handler(WIFI_EVENT_STA_ASSOC, wifi_ap_sta_assoc_hdl, NULL); + wifi_unreg_event_handler(WIFI_EVENT_STA_DISASSOC, wifi_ap_sta_disassoc_hdl); + wifi_reg_event_handler(WIFI_EVENT_STA_DISASSOC, wifi_ap_sta_disassoc_hdl, NULL); +*/ + ret = wext_set_mode(ifname, IW_MODE_MASTER); + if (ret < 0) + goto exit; + if(channel < 1 || channel > 14) channel = 1; + ret = wext_set_channel(ifname, channel); //Set channel before starting ap + if (ret < 0) + goto exit; + + if(security_type != RTW_SECURITY_OPEN) { // case RTW_SECURITY_WPA2_AES_PSK: + security_type = RTW_SECURITY_WPA2_AES_PSK; + ret = wext_set_auth_param(ifname, IW_AUTH_80211_AUTH_ALG, + IW_AUTH_ALG_OPEN_SYSTEM); + if (ret == 0) + ret = wext_set_key_ext(ifname, IW_ENCODE_ALG_CCMP, NULL, 0, 0, 0, 0, + NULL, 0); + if (ret == 0) + ret = wext_set_passphrase(ifname, (u8*) password, password_len); + } + if (ret < 0) + goto exit; + + if(ssid_hidden) { + ret = set_hidden_ssid(ifname, 1); + if (ret < 0) + goto exit; + } + + ret = wext_set_ap_ssid(ifname, (u8*) ssid, ssid_len); +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + wpas_wps_init(ifname); +#endif + exit: return ret; +} + +void wifi_scan_each_report_hdl(char* buf, int buf_len, int flags, void* userdata) { + int i = 0; + int j = 0; + int insert_pos = 0; + rtw_scan_result_t** result_ptr = (rtw_scan_result_t**) buf; + rtw_scan_result_t* temp = NULL; + + for (i = 0; i < scan_result_handler_ptr.scan_cnt; i++) { + if (CMP_MAC(scan_result_handler_ptr.pap_details[i]->BSSID.octet, + (*result_ptr)->BSSID.octet)) { + if ((*result_ptr)->signal_strength + > scan_result_handler_ptr.pap_details[i]->signal_strength) { + temp = scan_result_handler_ptr.pap_details[i]; + for (j = i - 1; j >= 0; j--) { + if (scan_result_handler_ptr.pap_details[j]->signal_strength + >= (*result_ptr)->signal_strength) + break; + else + scan_result_handler_ptr.pap_details[j + 1] = + scan_result_handler_ptr.pap_details[j]; + } + scan_result_handler_ptr.pap_details[j + 1] = temp; + scan_result_handler_ptr.pap_details[j + 1]->signal_strength = + (*result_ptr)->signal_strength; + } + memset(*result_ptr, 0, sizeof(rtw_scan_result_t)); + return; + } + } + + scan_result_handler_ptr.scan_cnt++; + + if (scan_result_handler_ptr.scan_cnt + > scan_result_handler_ptr.max_ap_size) { + scan_result_handler_ptr.scan_cnt = scan_result_handler_ptr.max_ap_size; + if ((*result_ptr)->signal_strength + > scan_result_handler_ptr.pap_details[scan_result_handler_ptr.max_ap_size + - 1]->signal_strength) { + rtw_memcpy( + scan_result_handler_ptr.pap_details[scan_result_handler_ptr.max_ap_size + - 1], *result_ptr, sizeof(rtw_scan_result_t)); + temp = + scan_result_handler_ptr.pap_details[scan_result_handler_ptr.max_ap_size + - 1]; + } else + return; + } else { + rtw_memcpy( + &scan_result_handler_ptr.ap_details[scan_result_handler_ptr.scan_cnt + - 1], *result_ptr, sizeof(rtw_scan_result_t)); + } + + for (i = 0; i < scan_result_handler_ptr.scan_cnt - 1; i++) { + if ((*result_ptr)->signal_strength + > scan_result_handler_ptr.pap_details[i]->signal_strength) + break; + } + insert_pos = i; + + for (i = scan_result_handler_ptr.scan_cnt - 1; i > insert_pos; i--) + scan_result_handler_ptr.pap_details[i] = + scan_result_handler_ptr.pap_details[i - 1]; + + if (temp != NULL) + scan_result_handler_ptr.pap_details[insert_pos] = temp; + else + scan_result_handler_ptr.pap_details[insert_pos] = + &scan_result_handler_ptr.ap_details[scan_result_handler_ptr.scan_cnt + - 1]; + rtw_memset(*result_ptr, 0, sizeof(rtw_scan_result_t)); +} + +void wifi_scan_done_hdl(char* buf, int buf_len, int flags, void* userdata) { + int i = 0; + rtw_scan_handler_result_t scan_result_report; + + for (i = 0; i < scan_result_handler_ptr.scan_cnt; i++) { + rtw_memcpy(&scan_result_report.ap_details, + scan_result_handler_ptr.pap_details[i], + sizeof(rtw_scan_result_t)); + scan_result_report.scan_complete = + scan_result_handler_ptr.scan_complete; + scan_result_report.user_data = scan_result_handler_ptr.user_data; + (*scan_result_handler_ptr.gscan_result_handler)(&scan_result_report); + } + + scan_result_handler_ptr.scan_complete = RTW_TRUE; + scan_result_report.scan_complete = RTW_TRUE; + (*scan_result_handler_ptr.gscan_result_handler)(&scan_result_report); + + rtw_free(scan_result_handler_ptr.ap_details); + rtw_free(scan_result_handler_ptr.pap_details); +#if SCAN_USE_SEMAPHORE + rtw_up_sema(&scan_result_handler_ptr.scan_semaphore); +#else + scan_result_handler_ptr.scan_running = 0; +#endif + wifi_unreg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, + wifi_scan_each_report_hdl); + wifi_unreg_event_handler(WIFI_EVENT_SCAN_DONE, wifi_scan_done_hdl); + return; +} + +//int rtk_wifi_scan(char *buf, int buf_len, xSemaphoreHandle * semaphore) +int wifi_scan(rtw_scan_type_t scan_type, rtw_bss_type_t bss_type, + void* result_ptr) { + int ret; + scan_buf_arg * pscan_buf; + u16 flags = scan_type | (bss_type << 8); + if (result_ptr != NULL) { + pscan_buf = (scan_buf_arg *) result_ptr; + ret = wext_set_scan(WLAN0_NAME, (char*) pscan_buf->buf, + pscan_buf->buf_len, flags); + } else { + wifi_reg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, + wifi_scan_each_report_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_SCAN_DONE, wifi_scan_done_hdl, NULL); + ret = wext_set_scan(WLAN0_NAME, NULL, 0, flags); + } + + if (ret == 0) { + if (result_ptr != NULL) { + ret = wext_get_scan(WLAN0_NAME, pscan_buf->buf, pscan_buf->buf_len); + } + } + return ret; +} + +int wifi_scan_networks_with_ssid( + int (results_handler)(char*buf, int buflen, char *ssid, void *user_data), + OUT void* user_data, IN int scan_buflen, IN char* ssid, IN int ssid_len) { + int scan_cnt = 0, add_cnt = 0; + scan_buf_arg scan_buf; + int ret; + + scan_buf.buf_len = scan_buflen; + scan_buf.buf = (char*) pvPortMalloc(scan_buf.buf_len); + if (!scan_buf.buf) { + printf("ERROR: Can't malloc memory(%d)\n", scan_buf.buf_len); + return RTW_NOMEM; + } + //set ssid + memset(scan_buf.buf, 0, scan_buf.buf_len); + memcpy(scan_buf.buf, &ssid_len, sizeof(int)); + memcpy(scan_buf.buf + sizeof(int), ssid, ssid_len); + + //Scan channel + if ((scan_cnt = (wifi_scan(RTW_SCAN_TYPE_ACTIVE, RTW_BSS_TYPE_ANY, + &scan_buf))) < 0) { + printf("ERROR: wifi scan failed\n"); + ret = RTW_ERROR; + } else { + if (NULL == results_handler) { + int plen = 0; + while (plen < scan_buf.buf_len) { + int len, rssi, ssid_len, i, security_mode; + int wps_password_id; + char *mac, *ssid; + //u8 *security_mode; + printf("\n"); + // len + len = (int) *(scan_buf.buf + plen); + printf("len = %d,\t", len); + // check end + if (len == 0) + break; + // mac + mac = scan_buf.buf + plen + 1; + printf("mac = "); + for (i = 0; i < 6; i++) + printf("%02x ", (u8)*(mac+i)); + printf(",\t"); + // rssi + rssi = *(int*) (scan_buf.buf + plen + 1 + 6); + printf(" rssi = %d,\t", rssi); + // security_mode + security_mode = (int) *(scan_buf.buf + plen + 1 + 6 + 4); + switch (security_mode) { + case IW_ENCODE_ALG_NONE: + printf("sec = open ,\t"); + break; + case IW_ENCODE_ALG_WEP: + printf("sec = wep ,\t"); + break; + case IW_ENCODE_ALG_CCMP: + printf("sec = wpa/wpa2,\t"); + break; + } + // password id + wps_password_id = (int) *(scan_buf.buf + plen + 1 + 6 + 4 + 1); + printf("wps password id = %d,\t", wps_password_id); + + printf("channel = %d,\t", + *(scan_buf.buf + plen + 1 + 6 + 4 + 1 + 1)); + // ssid + ssid_len = len - 1 - 6 - 4 - 1 - 1 - 1; + ssid = scan_buf.buf + plen + 1 + 6 + 4 + 1 + 1 + 1; + printf("ssid = "); + for (i = 0; i < ssid_len; i++) + printf("%c", *(ssid + i)); + plen += len; + add_cnt++; + } + + printf("\nwifi_scan: add count = %d, scan count = %d\n", add_cnt, + scan_cnt); + } + ret = RTW_SUCCESS; + } + if (results_handler) + results_handler(scan_buf.buf, scan_buf.buf_len, ssid, user_data); + + if (scan_buf.buf) + vPortFree(scan_buf.buf); + + return ret; +} + +int wifi_scan_networks(rtw_scan_result_handler_t results_handler, void* user_data) { + unsigned int max_ap_size = 64; + +#if SCAN_USE_SEMAPHORE + rtw_bool_t result; + if(NULL == scan_result_handler_ptr.scan_semaphore) + rtw_init_sema(&scan_result_handler_ptr.scan_semaphore, 1); + +// scan_result_handler_ptr.scan_start_time = rtw_get_current_time(); + /* Initialise the semaphore that will prevent simultaneous access - cannot be a mutex, since + * we don't want to allow the same thread to start a new scan */ + result = (rtw_bool_t)rtw_down_timeout_sema(&scan_result_handler_ptr.scan_semaphore, SCAN_LONGEST_WAIT_TIME); + if ( result != RTW_TRUE ) + { + /* Return error result, but set the semaphore to work the next time */ + rtw_up_sema(&scan_result_handler_ptr.scan_semaphore); + return RTW_TIMEOUT; + } +#else + if (scan_result_handler_ptr.scan_running) { + int count = 100; + while (scan_result_handler_ptr.scan_running && count > 0) { + rtw_msleep_os(20); + count--; + } + if (count == 0) { + printf("WiFi: Scan is running. Wait 2s timeout.\n"); + return RTW_TIMEOUT; + } + } +// scan_result_handler_ptr.scan_start_time = rtw_get_current_time(); + scan_result_handler_ptr.scan_running = 1; +#endif + + scan_result_handler_ptr.gscan_result_handler = results_handler; + + scan_result_handler_ptr.max_ap_size = max_ap_size; + scan_result_handler_ptr.ap_details = (rtw_scan_result_t*) rtw_zmalloc( + max_ap_size * sizeof(rtw_scan_result_t)); + if (scan_result_handler_ptr.ap_details == NULL) { + goto err_exit; + } + rtw_memset(scan_result_handler_ptr.ap_details, 0, + max_ap_size * sizeof(rtw_scan_result_t)); + + scan_result_handler_ptr.pap_details = (rtw_scan_result_t**) rtw_zmalloc( + max_ap_size * sizeof(rtw_scan_result_t*)); + if (scan_result_handler_ptr.pap_details == NULL) + goto error2_with_result_ptr; + rtw_memset(scan_result_handler_ptr.pap_details, 0, max_ap_size); + + scan_result_handler_ptr.scan_cnt = 0; + + scan_result_handler_ptr.scan_complete = RTW_FALSE; + scan_result_handler_ptr.user_data = user_data; + + if (wifi_scan(RTW_SCAN_COMMAMD << 4 | RTW_SCAN_TYPE_ACTIVE, + RTW_BSS_TYPE_ANY, NULL) != RTW_SUCCESS) { + goto error1_with_result_ptr; + } + + return RTW_SUCCESS; + +error1_with_result_ptr: + rtw_free((u8*)scan_result_handler_ptr.pap_details); + scan_result_handler_ptr.pap_details = NULL; + +error2_with_result_ptr: + rtw_free((u8*)scan_result_handler_ptr.ap_details); + scan_result_handler_ptr.ap_details = NULL; + +err_exit: + rtw_memset((void *) &scan_result_handler_ptr, 0, + sizeof(scan_result_handler_ptr)); + return RTW_ERROR; +} +//----------------------------------------------------------------------------// +int wifi_set_pscan_chan(__u8 * channel_list, __u8 * pscan_config, __u8 length) { + if (channel_list) + return wext_set_pscan_channel(WLAN0_NAME, channel_list, pscan_config, + length); + else + return -1; +} + +//----------------------------------------------------------------------------// +int wifi_get_setting(const char *ifname, rtw_wifi_setting_t *pSetting) { + int ret = 0; + int mode = 0; + unsigned short security = 0; + + memset(pSetting, 0, sizeof(rtw_wifi_setting_t)); + if (wext_get_mode(ifname, &mode) < 0) + ret = -1; + + switch (mode) { + case IW_MODE_MASTER: + pSetting->mode = RTW_MODE_AP; + break; + case IW_MODE_INFRA: + default: + pSetting->mode = RTW_MODE_STA; + break; + //default: + //printf("\r\n%s(): Unknown mode %d\n", __func__, mode); + //break; + } + + if (wext_get_ssid(ifname, pSetting->ssid) < 0) + ret = -1; + if (wext_get_channel(ifname, &pSetting->channel) < 0) + ret = -1; + if (wext_get_enc_ext(ifname, &security, &pSetting->key_idx, + pSetting->password) < 0) + ret = -1; + + switch (security) { + case IW_ENCODE_ALG_NONE: + pSetting->security_type = RTW_SECURITY_OPEN; + break; + case IW_ENCODE_ALG_WEP: + pSetting->security_type = RTW_SECURITY_WEP_PSK; + break; + case IW_ENCODE_ALG_TKIP: + pSetting->security_type = RTW_SECURITY_WPA_TKIP_PSK; + break; + case IW_ENCODE_ALG_CCMP: + pSetting->security_type = RTW_SECURITY_WPA2_AES_PSK; + break; + default: + break; + } + + if (security == IW_ENCODE_ALG_TKIP || security == IW_ENCODE_ALG_CCMP) + if (wext_get_passphrase(ifname, pSetting->password) < 0) + ret = -1; + + return ret; +} +//----------------------------------------------------------------------------// +extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57 шт +int wifi_show_setting(const char *ifname, rtw_wifi_setting_t *pSetting) { + int ret = 0; + + printf("\nWIFI '%s' Setting:\n", ifname); + printf(&str_rom_57ch3Dch0A[25]); // "================================\n" + + switch (pSetting->mode) { + case RTW_MODE_AP: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("AP:"); +#endif + printf("\tMODE => AP\n"); + break; + case RTW_MODE_STA: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("STA:"); +#endif + printf("\tMODE => STATION\n"); + break; + default: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("UNKNOWN,"); +#endif + printf("\tMODE => UNKNOWN\n"); + } +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("%s,%d,", pSetting->ssid, pSetting->channel); +#endif + printf("\tSSID => %s\n", pSetting->ssid); + printf("\tCHANNEL => %d\n", pSetting->channel); + + switch (pSetting->security_type) { + case RTW_SECURITY_OPEN: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("OPEN,"); +#endif + printf("\tSECURITY => OPEN\n"); + break; + case RTW_SECURITY_WEP_PSK: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("WEP,%d,", pSetting->key_idx); +#endif + printf("\tSECURITY => WEP\n"); + printf("\tKEY INDEX => %d\n", pSetting->key_idx); + break; + case RTW_SECURITY_WPA_TKIP_PSK: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("TKIP,"); +#endif + printf("\tSECURITY => TKIP\n"); + break; + case RTW_SECURITY_WPA2_AES_PSK: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("AES,"); +#endif + printf("\tSECURITY => AES\n"); + break; + default: +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("UNKNOWN,"); +#endif + printf("\tSECURITY => UNKNOWN\n"); + } + +#if CONFIG_EXAMPLE_UART_ATCMD + at_printf("%s,", pSetting->password); +#endif + printf("\tPASSWORD => %s\n", pSetting->password); +// printf("\n"); + + return ret; +} + +//----------------------------------------------------------------------------// +int wifi_set_network_mode(rtw_network_mode_t mode) { + if ((mode == RTW_NETWORK_B) || (mode == RTW_NETWORK_BG) + || (mode == RTW_NETWORK_BGN)) + return rltk_wlan_wireless_mode((unsigned char) mode); + + return -1; +} + +int wifi_set_wps_phase(unsigned char is_trigger_wps) { + return rltk_wlan_set_wps_phase(is_trigger_wps); +} + +//----------------------------------------------------------------------------// +int wifi_set_promisc(rtw_rcr_level_t enabled, + void (*callback)(unsigned char*, unsigned int, void*), + unsigned char len_used) { + return promisc_set(enabled, callback, len_used); +} + +void wifi_enter_promisc_mode() { + int mode = 0; + unsigned char ssid[33]; + + if (wifi_mode == RTW_MODE_STA_AP) { + wifi_off(); + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + wifi_on(RTW_MODE_PROMISC); + } else { + wext_get_mode(WLAN0_NAME, &mode); + + switch (mode) { + case IW_MODE_MASTER: //In AP mode + //rltk_wlan_deinit(); + wifi_off(); //modified by Chris Yang for iNIC + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + //rltk_wlan_init(0, RTW_MODE_PROMISC); + //rltk_wlan_start(0); + wifi_on(RTW_MODE_PROMISC); + break; + case IW_MODE_INFRA: //In STA mode + if (wext_get_ssid(WLAN0_NAME, ssid) > 0) + wifi_disconnect(); + } + } +} + +int wifi_restart_ap(unsigned char *ssid, rtw_security_t security_type, + unsigned char *password, int channel) { + unsigned char idx = 0; + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif = &xnetif[0]; +#ifdef CONFIG_CONCURRENT_MODE + rtw_wifi_setting_t setting; + int sta_linked = 0; +#endif + + if (rltk_wlan_running(WLAN1_IDX)) { + idx = 1; + } + + // stop dhcp server + dhcps_deinit(); + +#ifdef CONFIG_CONCURRENT_MODE + if (idx > 0) { + sta_linked = wifi_get_setting(WLAN0_NAME, &setting); + wifi_off(); + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + wifi_on(RTW_MODE_STA_AP); + } else +#endif + { + IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, + NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask, &gw); + wifi_off(); + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + wifi_on(RTW_MODE_AP); + } + // start ap + if (wifi_start_ap((char*) ssid, security_type, (char*) password, channel, 0) < 0) { + printf("ERROR: Operation failed!\n"); + return -1; + } + +#if (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("WebServer Thread: High Water Mark is %ld\n", uxTaskGetStackHighWaterMark(NULL)); +#endif +#ifdef CONFIG_CONCURRENT_MODE + // connect to ap if wlan0 was linked with ap + if (idx > 0 && sta_linked == 0) { + int ret; + printf("AP: ssid=%s\n", (char* )setting.ssid); + printf("AP: security_type=%d\n", setting.security_type); + printf("AP: password=%s\n", (char* )setting.password); + printf("AP: key_idx =%d\n", setting.key_idx); + ret = wifi_connect((char*) setting.ssid, setting.security_type, + (char*) setting.password, strlen((char* )setting.ssid), + strlen((char* )setting.password), setting.key_idx, + NULL); + if (ret == RTW_SUCCESS) { +#if CONFIG_DHCP_CLIENT + /* Start DHCPClient */ + LwIP_DHCP(0, DHCP_START); +#endif +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + } + } +#endif +#if (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("WebServer Thread: High Water Mark is %ld\n", uxTaskGetStackHighWaterMark(NULL)); +#endif + // start dhcp server + dhcps_init(&xnetif[idx]); + + return 0; +} + +#if CONFIG_AUTO_RECONNECT +extern void (*p_wlan_autoreconnect_hdl)(rtw_security_t, char*, int, char*, int, + int); + +struct wifi_autoreconnect_param { + rtw_security_t security_type; + char *ssid; + int ssid_len; + char *password; + int password_len; + int key_id; +}; + +static void wifi_autoreconnect_thread(void *param) { + int ret = RTW_ERROR; + struct wifi_autoreconnect_param *reconnect_param = + (struct wifi_autoreconnect_param *) param; + printf("auto reconnect ...\n"); + ret = wifi_connect( + NULL, + 0, + reconnect_param->ssid, + reconnect_param->security_type, + reconnect_param->password, + reconnect_param->key_id, + NULL); + if (ret == RTW_SUCCESS) { +#if CONFIG_LWIP_LAYER + +#if ATCMD_VER == ATVER_2 + if (dhcp_mode_sta == 2) { + struct netif * pnetif = &xnetif[0]; + LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); + } + else +#endif + { + LwIP_DHCP(0, DHCP_START); +#if LWIP_AUTOIP + uint8_t *ip = LwIP_GetIP(&xnetif[0]); + if ((ip[0] == 0) && (ip[1] == 0) && (ip[2] == 0) && (ip[3] == 0)) { + printf("IPv4 AUTOIP ...\n"); + LwIP_AUTOIP(&xnetif[0]); + } +#endif + } +#endif //#if CONFIG_LWIP_LAYER +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + } + vTaskDelete(NULL); +} + +void wifi_autoreconnect_hdl(rtw_security_t security_type, char *ssid, + int ssid_len, char *password, int password_len, int key_id) { + static struct wifi_autoreconnect_param param; + param.security_type = security_type; + param.ssid = ssid; + param.ssid_len = ssid_len; + param.password = password; + param.password_len = password_len; + param.key_id = key_id; + xTaskCreate(wifi_autoreconnect_thread, (const char * )"st_recon", 400, + ¶m, tskIDLE_PRIORITY + 1, NULL); +} + +int wifi_config_autoreconnect(__u8 mode, __u8 retyr_times, __u16 timeout) { + p_wlan_autoreconnect_hdl = wifi_autoreconnect_hdl; + return wext_set_autoreconnect(WLAN0_NAME, mode, retyr_times, timeout); +} + +int wifi_set_autoreconnect(__u8 mode) { + p_wlan_autoreconnect_hdl = wifi_autoreconnect_hdl; + return wifi_config_autoreconnect(mode, 3, 5);//default retry 2 times(limit is 3), timeout 5 seconds +} + +int wifi_get_autoreconnect(__u8 *mode) { + return wext_get_autoreconnect(WLAN0_NAME, mode); +} +#endif + +#ifdef CONFIG_CUSTOM_IE +/* + * Example for custom ie + * + * u8 test_1[] = {221, 2, 2, 2}; + * u8 test_2[] = {221, 2, 1, 1}; + * cus_ie buf[2] = {{test_1, PROBE_REQ}, + * {test_2, PROBE_RSP | BEACON}}; + * u8 buf_test2[] = {221, 2, 1, 3} ; + * cus_ie buf_update = {buf_test2, PROBE_REQ}; + * + * add ie list + * static void cmd_add_ie(int argc, char **argv) + * { + * wifi_add_custom_ie((void *)buf, 2); + * } + * + * update current ie + * static void cmd_update_ie(int argc, char **argv) + * { + * wifi_update_custom_ie(&buf_update, 2); + * } + * + * delete all ie + * static void cmd_del_ie(int argc, char **argv) + * { + * wifi_del_custom_ie(); + * } + */ + +int wifi_add_custom_ie(void *cus_ie, int ie_num) { + return wext_add_custom_ie(WLAN0_NAME, cus_ie, ie_num); +} + +int wifi_update_custom_ie(void *cus_ie, int ie_index) { + return wext_update_custom_ie(WLAN0_NAME, cus_ie, ie_index); +} + +int wifi_del_custom_ie() { + return wext_del_custom_ie(WLAN0_NAME); +} + +#endif + +#ifdef CONFIG_PROMISC +extern void promisc_init_packet_filter(void); +extern int promisc_add_packet_filter(u8 filter_id, + rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_e rule); +extern int promisc_enable_packet_filter(u8 filter_id); +extern int promisc_disable_packet_filter(u8 filter_id); +extern int promisc_remove_packet_filter(u8 filter_id); +void wifi_init_packet_filter() { + promisc_init_packet_filter(); +} + +int wifi_add_packet_filter(unsigned char filter_id, + rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_e rule) { + return promisc_add_packet_filter(filter_id, patt, rule); +} + +int wifi_enable_packet_filter(unsigned char filter_id) { + return promisc_enable_packet_filter(filter_id); +} + +int wifi_disable_packet_filter(unsigned char filter_id) { + return promisc_disable_packet_filter(filter_id); +} + +int wifi_remove_packet_filter(unsigned char filter_id) { + return promisc_remove_packet_filter(filter_id); +} +#endif + +#ifdef CONFIG_AP_MODE +int wifi_enable_forwarding(void) { + return wext_enable_forwarding(WLAN0_NAME); +} + +int wifi_disable_forwarding(void) { + return wext_disable_forwarding(WLAN0_NAME); +} +#endif + +/* API to set flag for concurrent mode wlan1 issue_deauth when channel switched by wlan0 + * usage: wifi_set_ch_deauth(0) -> wlan0 wifi_connect -> wifi_set_ch_deauth(1) + */ +#ifdef CONFIG_CONCURRENT_MODE +int wifi_set_ch_deauth(__u8 enable) { + return wext_set_ch_deauth(WLAN1_NAME, enable); +} +#endif + +//----------------------------------------------------------------------------// +#endif //#if CONFIG_WLAN diff --git a/USDK/component/common/api/wifi/wifi_conf.h b/USDK/component/common/api/wifi/wifi_conf.h new file mode 100644 index 0000000..99ff05d --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_conf.h @@ -0,0 +1,712 @@ +//----------------------------------------------------------------------------// +#ifndef __WIFI_CONF_API_H +#define __WIFI_CONF_API_H + +#include "FreeRTOS.h" +#include "wifi_constants.h" +#include "wifi_structures.h" +#include "wifi_util.h" +#include "wifi_ind.h" +#include + + +#ifdef __cplusplus + extern "C" { +#endif + + +/****************************************************** + * Macros + ******************************************************/ + +#define RTW_ENABLE_API_INFO + +#ifdef RTW_ENABLE_API_INFO + #define RTW_API_INFO(args) do {printf args;} while(0) +#else + #define RTW_API_INFO(args) +#endif + +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] +#define CMP_MAC( a, b ) (((a[0])==(b[0]))&& \ + ((a[1])==(b[1]))&& \ + ((a[2])==(b[2]))&& \ + ((a[3])==(b[3]))&& \ + ((a[4])==(b[4]))&& \ + ((a[5])==(b[5]))) + +/****************************************************** + * Constants + ******************************************************/ +#define SCAN_LONGEST_WAIT_TIME (4500) + +#define wifi_test_timeout_step_ms 20 // ms +#define wifi_test_timeout_ms 2000 // ms + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" + +#define PSCAN_ENABLE 0x01 //enable for partial channel scan +#define PSCAN_FAST_SURVEY 0x02 //set to select scan time to FAST_SURVEY_TO, otherwise SURVEY_TO +#define PSCAN_SIMPLE_CONFIG 0x04 //set to select scan time to FAST_SURVEY_TO and resend probe request + +/****************************************************** + * Type Definitions + ******************************************************/ + +/** Scan result callback function pointer type + * + * @param result_ptr : A pointer to the pointer that indicates where to put the next scan result + * @param user_data : User provided data + */ +typedef void (*rtw_scan_result_callback_t)( rtw_scan_result_t** result_ptr, void* user_data ); +typedef rtw_result_t (*rtw_scan_result_handler_t)( rtw_scan_handler_result_t* malloced_scan_result ); + +/****************************************************** + * Structures + ******************************************************/ +typedef struct { + char *buf; + int buf_len; +} scan_buf_arg; + +/****************************************************** + * Structures + ******************************************************/ +#define SCAN_USE_SEMAPHORE 0 + +typedef struct internal_scan_handler{ + rtw_scan_result_t** pap_details; + rtw_scan_result_t * ap_details; + rtw_scan_result_handler_t gscan_result_handler; +#if SCAN_USE_SEMAPHORE + void * scan_semaphore; +#endif + // unsigned int scan_start_time; + void * user_data; + unsigned char scan_cnt; + unsigned char max_ap_size; + volatile unsigned char scan_complete; + volatile unsigned char scan_running; +} internal_scan_handler_t; + +typedef struct { + rtw_network_info_t network_info; + void *join_sema; +} internal_join_result_t; + +/****************************************************** + * Function Declarations + ******************************************************/ +/** + * Initialises Realtek WiFi API System + * + * - Initialises the required parts of the software platform + * i.e. worker, event registering, semaphore, etc. + * + * - Initialises the RTW API thread which handles the asynchronous event + * + * @return RTW_SUCCESS if initialization is successful, RTW_ERROR otherwise + */ +int wifi_manager_init(void); + +/** Joins a Wi-Fi network + * + * Scans for, associates and authenticates with a Wi-Fi network. + * On successful return, the system is ready to send data packets. + * + * @param[in] ssid : A null terminated string containing the SSID name of the network to join + * @param[in] security_type : Authentication type: + * - RTW_SECURITY_OPEN - Open Security + * - RTW_SECURITY_WEP_PSK - WEP Security with open authentication + * - RTW_SECURITY_WEP_SHARED - WEP Security with shared authentication + * - RTW_SECURITY_WPA_TKIP_PSK - WPA Security + * - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher + * - RTW_SECURITY_WPA2_TKIP_PSK - WPA2 Security using TKIP cipher + * - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers + * @param[in] password : A byte array containing either the + * cleartext security key for WPA/WPA2 + * secured networks, or a pointer to + * an array of rtw_wep_key_t + * structures for WEP secured networks + * @param[in] ssid_len : The length of the SSID in + * bytes. + * @param[in] password_len : The length of the security_key in + * bytes. + * @param[in] key_id : The index of the wep key. + * @param[in] semaphore : A user provided semaphore that is flagged when the join is complete + * + * @return RTW_SUCCESS : when the system is joined and ready + * to send data packets + * RTW_ERROR : if an error occurred + */ +int wifi_connect( + unsigned char bssid[ETH_ALEN], + char use_bssid, + char *ssid, + rtw_security_t security_type, + char *password, + int key_id, + void *semaphore); +/* +int wifi_connect_bssid( + unsigned char bssid[ETH_ALEN], + char *ssid, + rtw_security_t security_type, + char *password, + int bssid_len, + int ssid_len, + int password_len, + int key_id, + void *semaphore); +*/ +/** Disassociates from a Wi-Fi network. + * + * @return RTW_SUCCESS : On successful disassociation from + * the AP + * RTW_ERROR : If an error occurred +*/ +int wifi_disconnect(void); + +/** Check if the interface specified is up. + * + * @return RTW_TRUE : If it's up + * RTW_FALSE : If it's not +*/ +int wifi_is_connected_to_ap(void); + +/*check if wifi has connected to AP before dhcp +* +* @return RTW_SUCCESS:if conneced + RTW_ERROR :if not connect +*/ +int wifi_is_up(rtw_interface_t interface); + +/** Determines if a particular interface is ready to transceive ethernet packets + * + * @param Radio interface to check, options are + * RTW_STA_INTERFACE, RTW_AP_INTERFACE + * @return RTW_SUCCESS : if the interface is ready to + * transceive ethernet packets + * @return RTW_NOTFOUND : no AP with a matching SSID was + * found + * @return RTW_NOT_AUTHENTICATED: a matching AP was found but + * it won't let you + * authenticate. This can + * occur if this device is + * in the block list on the + * AP. + * @return RTW_NOT_KEYED: the device has authenticated and + * associated but has not completed + * the key exchange. This can occur + * if the passphrase is incorrect. + * @return RTW_ERROR : if the interface is not ready to + * transceive ethernet packets + */ +int wifi_is_ready_to_transceive(rtw_interface_t interface); + +/** ---------------------------------------------------------------------- + * WARNING : This function is for internal use only! + * ---------------------------------------------------------------------- + * This function sets the current Media Access Control (MAC) address of the + * 802.11 device. + * + * @param[in] mac Wi-Fi MAC address + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_set_mac_address(char * mac); + +/** Retrieves the current Media Access Control (MAC) address + * (or Ethernet hardware address) of the 802.11 device + * + * @param mac Pointer to a variable that the current MAC address will be written to + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_get_mac_address(char * mac); + +/** Enables powersave mode + * + * @return @ref rtw_result_t + */ +int wifi_enable_powersave(void); + +/** Disables 802.11 power save mode + * + * @return RTW_SUCCESS : if power save mode was successfully + * disabled + * RTW_ERROR : if power save mode was not successfully + * disabled + */ +int wifi_disable_powersave(void); + +/** Gets the tx power in index units + * + * @param dbm : The variable to receive the tx power in index. + * + * @return RTW_SUCCESS : if successful + * RTW_ERROR : if not successful + */ +int wifi_get_txpower(int *poweridx); + +/** Sets the tx power in index units + * + * @param dbm : The desired tx power in index. + * + * @return RTW_SUCCESS : if tx power was successfully set + * RTW_ERROR : if tx power was not successfully set + */ +int wifi_set_txpower(int poweridx); + +/** Get the associated clients with SoftAP + * + * @param client_list_buffer : the location where the client + * list will be stored + * @param buffer_length : the buffer length. + * + * @return RTW_SUCCESS : if result was successfully get + * RTW_ERROR : if result was not successfully get + */ +int wifi_get_associated_client_list(void * client_list_buffer, unsigned short buffer_length); + +/** Get the SoftAP information + * + * @param ap_info : the location where the AP info will be + * stored + * @param security : the security type. + * + * @return RTW_SUCCESS : if result was successfully get + * RTW_ERROR : if result was not successfully get + */ +int wifi_get_ap_info(rtw_bss_info_t * ap_info, rtw_security_t* security); + +/** Set the country code to driver to determine the channel set + * + * @param country_code : the country code. + * + * @return RTW_SUCCESS : if result was successfully set + * RTW_ERROR : if result was not successfully set + */ +int wifi_set_country(rtw_country_code_t country_code); + +/** Retrieve the latest RSSI value + * + * @param rssi: The location where the RSSI value will be stored + * + * @return RTW_SUCCESS : if the RSSI was succesfully retrieved + * RTW_ERROR : if the RSSI was not retrieved + */ +int wifi_get_rssi(int *pRSSI); + +/** Set the current channel on STA interface + * + * @param channel : The desired channel + * + * @return RTW_SUCCESS : if the channel was successfully set + * RTW_ERROR : if the channel was not successfully + * set + */ +int wifi_set_channel(int channel); + +/** Get the current channel on STA interface + * + * @param channel : A pointer to the variable where the + * channel value will be written + * + * @return RTW_SUCCESS : if the channel was successfully read + * RTW_ERROR : if the channel was not successfully + * read + */ +int wifi_get_channel(int *channel); + +/** Registers interest in a multicast address + * Once a multicast address has been registered, all packets detected on the + * medium destined for that address are forwarded to the host. + * Otherwise they are ignored. + * + * @param mac: Ethernet MAC address + * + * @return RTW_SUCCESS : if the address was registered + * successfully + * RTW_ERROR : if the address was not registered + */ +int wifi_register_multicast_address(rtw_mac_t *mac); + +/** Unregisters interest in a multicast address + * Once a multicast address has been unregistered, all packets detected on the + * medium destined for that address are ignored. + * + * @param mac: Ethernet MAC address + * + * @return RTW_SUCCESS : if the address was unregistered + * successfully + * RTW_ERROR : if the address was not unregistered + */ +int wifi_unregister_multicast_address(rtw_mac_t *mac); + +int wifi_rf_on(void); +int wifi_rf_off(void); + +/** Turn on the Wi-Fi device + * + * - Bring the Wireless interface "Up" + * - Initialises the driver thread which arbitrates access + * to the SDIO/SPI bus + * + * @param mode: wifi work mode + * + * @return RTW_SUCCESS : if the WiFi chip was initialised + * successfully + * RTW_ERROR : if the WiFi chip was not initialised + * successfully + */ +int wifi_on(rtw_mode_t mode); + +/** + * Turn off the Wi-Fi device + * + * - Bring the Wireless interface "Down" + * - De-Initialises the driver thread which arbitrates access + * to the SDIO/SPI bus + * + * @return RTW_SUCCESS if deinitialization is successful, + * RTW_ERROR otherwise + */ +int wifi_off(void); + +/** + * Set IPS/LPS mode + * + * @param[in] ips_mode : The desired IPS mode. It become effective when wlan enter ips. + * @param[in] lps_mode : The desired LPS mode. It become effective when wlan enter lps. + * + * @return RTW_SUCCESS if setting LPS mode successful + * RTW_ERROR otherwise + */ +int wifi_set_power_mode(unsigned char ips_mode, unsigned char lps_mode); + +/** + * Set TDMA parameters + * + * @param[in] slot_period : We separate TBTT into 2 or 3 slots. + * If we separate TBTT into 2 slots, then slot_period should be larger or equal to 50ms. + * It means 2 slot period is + * slot_period, 100-slot_period + * If we separate TBTT into 3 slots, then slot_period should be less or equal to 33ms. + * It means 3 slot period is + * 100 - 2 * slot_period, slot_period, slot_period + * @param[in] rfon_period_len_1: rf on period of slot 1 + * @param[in] rfon_period_len_2: rf on period of slot 2 + * @param[in] rfon_period_len_3: rf on period of slot 3 + * + * @return RTW_SUCCESS if setting TDMA parameters successful + * RTW_ERROR otherwise + */ +int wifi_set_tdma_param(unsigned char slot_period, unsigned char rfon_period_len_1, unsigned char rfon_period_len_2, unsigned char rfon_period_len_3); + +/** + * Set LPS DTIM + * + * @param[in] dtim : In LPS, the package can be buffered at AP side. + * STA leave LPS until dtim count of packages buffered at AP side. + * + * @return RTW_SUCCESS if setting LPS dtim successful + * RTW_ERROR otherwise + */ +int wifi_set_lps_dtim(unsigned char dtim); +/** + * Get LPS DTIM + * + * @param[out] dtim : In LPS, the package can be buffered at AP side. + * STA leave LPS until dtim count of packages buffered at AP side. + * + * @return RTW_SUCCESS if getting LPS dtim successful + * RTW_ERROR otherwise + */ +int wifi_get_lps_dtim(unsigned char *dtim); + +/** Starts an infrastructure WiFi network + * + * @warning If a STA interface is active when this function is called, the softAP will\n + * start on the same channel as the STA. It will NOT use the channel provided! + * + * @param[in] ssid : A null terminated string containing + * the SSID name of the network to join + * @param[in] security_type : Authentication type: \n + * - RTW_SECURITY_OPEN - Open Security \n + * - RTW_SECURITY_WPA_TKIP_PSK - WPA Security \n + * - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher \n + * - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers \n + * - WEP security is NOT IMPLEMENTED. It is NOT SECURE! \n + * @param[in] password : A byte array containing the cleartext + * security key for the network + * @param[in] ssid_len : The length of the SSID in + * bytes. + * @param[in] password_len : The length of the security_key in + * bytes. + * @param[in] channel : 802.11 channel number + * + * @return RTW_SUCCESS : if successfully creates an AP + * RTW_ERROR : if an error occurred + */ +int wifi_start_ap(char *ssid, rtw_security_t security_type, char *password, int channel, char ssid_hidden); +/* +int wifi_start_ap( + char *ssid, + rtw_security_t security_type, + char *password, + int ssid_len, + int password_len, + int channel); +*/ +/** Starts an infrastructure WiFi network with hidden SSID + * + * @warning If a STA interface is active when this function is called, the softAP will\n + * start on the same channel as the STA. It will NOT use the channel provided! + * + * @param[in] ssid : A null terminated string containing + * the SSID name of the network to join + * @param[in] security_type : Authentication type: \n + * - RTW_SECURITY_OPEN - Open Security \n + * - RTW_SECURITY_WPA_TKIP_PSK - WPA Security \n + * - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher \n + * - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers \n + * - WEP security is NOT IMPLEMENTED. It is NOT SECURE! \n + * @param[in] password : A byte array containing the cleartext + * security key for the network + * @param[in] ssid_len : The length of the SSID in + * bytes. + * @param[in] password_len : The length of the security_key in + * bytes. + * @param[in] channel : 802.11 channel number + * + * @return RTW_SUCCESS : if successfully creates an AP + * RTW_ERROR : if an error occurred + */ +/* +int wifi_start_ap_with_hidden_ssid( + char *ssid, + rtw_security_t security_type, + char *password, + int ssid_len, + int password_len, + int channel); +*/ +/** Initiates a scan to search for 802.11 networks. + * + * The scan progressively accumulates results over time, and + * may take between 1 and 3 seconds to complete. The results of + * the scan will be individually provided to the callback + * function. Note: The callback function will be executed in + * the context of the RTW thread. + * + * @param[in] scan_type : Specifies whether the scan should + * be Active, Passive or scan + * Prohibited channels + * @param[in] bss_type : Specifies whether the scan should + * search for Infrastructure + * networks (those using an Access + * Point), Ad-hoc networks, or both + * types. + * @param result_ptr[in] : Scan specific ssid. The first 4 + * bytes is ssid lenth, and ssid name + * append after it. + * If no specific ssid need to scan, + * PLEASE CLEAN result_ptr before pass + * it into parameter. + * @param result_ptr[out] : a pointer to a pointer to a result + * storage structure. + * + * @note : When scanning specific channels, devices with a + * strong signal strength on nearby channels may be + * detected + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_scan(rtw_scan_type_t scan_type, + rtw_bss_type_t bss_type, + void* result_ptr); + +/** Initiates a scan to search for 802.11 networks, a higher + * level API based on wifi_scan to simplify the scan + * operation. + * + * The scan results will be list by the order of RSSI. + * It may demand hundreds bytes memory during scan + * processing according to the quantity of AP nearby. + * + * @param results_handler[in] : the callback function which + * will receive and process the result data. + * @param user_data[in] : user specific data that will be + * passed directly to the callback function + * + * @note : Callback must not use blocking functions, since it is + * called from the context of the RTW thread. + * @note : The callback, user_data variables will + * be referenced after the function returns. Those + * variables must remain valid until the scan is + * complete. + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_scan_networks(rtw_scan_result_handler_t results_handler, void* user_data); +int wifi_scan_networks_with_ssid(int (results_handler)(char*, int, char *, void *), void* user_data, int scan_buflen, char* ssid, int ssid_len); + +/** Set the partical scan + * + * @param channel_list[in] : the channel set the scan will + * stay on + * @param pscan_config[in] : the pscan_config of the channel set + * + * @param length[in] : the channel list length + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_set_pscan_chan(__u8 * channel_list,__u8 * pscan_config, __u8 length); + +/** Get the network information + * + * @param ifname[in] : the name of the interface we are care + * @param pSetting[in] : the location where the network + * information will be stored + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_get_setting(const char *ifname, rtw_wifi_setting_t *pSetting); + +/** Show the network information + * + * @param ifname[in] : the name of the interface we are care + * @param pSetting[in] : the location where the network + * information was stored + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_show_setting(const char *ifname,rtw_wifi_setting_t *pSetting); + +/** Set the network mode according to the data rate it's + * supported + * + * @param mode[in] : the network mode + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_set_network_mode(rtw_network_mode_t mode); + +/** Set the chip to worke in the promisc mode + * + * @param enabled[in] : enabled can be set 0, 1 and 2. if enabled is zero, disable the promisc, else enable the promisc. + * 0 means disable the promisc + * 1 means enable the promisc + * 2 means enable the promisc special for length is used + * @param callback[in] : the callback function which will + * receive and process the netowork data. + * @param len_used[in] : specify if the the promisc length is + * used. + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_set_promisc(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used); + +/** Set the wps phase + * + * @param is_trigger_wps[in] : to trigger wps function or not + * + * @return RTW_SUCCESS or RTW_ERROR + */ +int wifi_set_wps_phase(unsigned char is_trigger_wps); + +/** Restarts an infrastructure WiFi network + * + * @warning If a STA interface is active when this function is called, the softAP will\n + * start on the same channel as the STA. It will NOT use the channel provided! + * + * @param[in] ssid : A null terminated string containing + * the SSID name of the network to join + * @param[in] security_type : Authentication type: \n + * - RTW_SECURITY_OPEN - Open Security \n + * - RTW_SECURITY_WPA_TKIP_PSK - WPA Security \n + * - RTW_SECURITY_WPA2_AES_PSK - WPA2 Security using AES cipher \n + * - RTW_SECURITY_WPA2_MIXED_PSK - WPA2 Security using AES and/or TKIP ciphers \n + * - WEP security is NOT IMPLEMENTED. It is NOT SECURE! \n + * @param[in] password : A byte array containing the cleartext + * security key for the network + * @param[in] ssid_len : The length of the SSID in + * bytes. + * @param[in] password_len : The length of the security_key in + * bytes. + * @param[in] channel : 802.11 channel number + * + * @return RTW_SUCCESS : if successfully creates an AP + * RTW_ERROR : if an error occurred + */ +int wifi_restart_ap( + unsigned char *ssid, + rtw_security_t security_type, + unsigned char *password, + int channel); + +int wifi_config_autoreconnect(__u8 mode, __u8 retyr_times, __u16 timeout); +int wifi_set_autoreconnect(__u8 mode); +int wifi_get_autoreconnect(__u8 *mode); +int wifi_get_last_error(void); +/** Present device disconnect reason while connecting +* +*@return RTW_NO_ERROR = 0, +* RTW_NONE_NETWORK = 1, +* RTW_CONNECT_FAIL = 2, +* RTW_WRONG_PASSWORD = 3 , +* RTW_DHCP_FAIL = 4, +* RTW_UNKNOWN, initial status +*/ + + +#ifdef CONFIG_CUSTOM_IE +#ifndef BIT +#define BIT(x) ((__u32)1 << (x)) +#endif + +#ifndef _CUSTOM_IE_TYPE_ +#define _CUSTOM_IE_TYPE_ +enum CUSTOM_IE_TYPE{ + PROBE_REQ = BIT(0), + PROBE_RSP = BIT(1), + BEACON = BIT(2), +}; +#endif /* _CUSTOM_IE_TYPE_ */ + +/* ie format + * +-----------+--------+-----------------------+ + * |element ID | length | content in length byte| + * +-----------+--------+-----------------------+ + * + * type: refer to CUSTOM_IE_TYPE + */ +#ifndef _CUS_IE_ +#define _CUS_IE_ +typedef struct _cus_ie{ + __u8 *ie; + __u8 type; +} cus_ie, *p_cus_ie; +#endif /* _CUS_IE_ */ + +int wifi_add_custom_ie(void *cus_ie, int ie_num); + +int wifi_update_custom_ie(void *cus_ie, int ie_index); + +int wifi_del_custom_ie(void); +#endif + +#ifdef CONFIG_PROMISC +void wifi_init_packet_filter(void); +int wifi_add_packet_filter(unsigned char filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_e rule); +int wifi_enable_packet_filter(unsigned char filter_id); +int wifi_disable_packet_filter(unsigned char filter_id); +int wifi_remove_packet_filter(unsigned char filter_id); +#endif + +#ifdef __cplusplus + } +#endif + +#endif // __WIFI_CONF_API_H + +//----------------------------------------------------------------------------// diff --git a/USDK/component/common/api/wifi/wifi_ind.c b/USDK/component/common/api/wifi/wifi_ind.c new file mode 100644 index 0000000..791ea38 --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_ind.c @@ -0,0 +1,269 @@ +//----------------------------------------------------------------------------// +#include "wifi/wifi_ind.h" +#include "wifi/wifi_conf.h" +#include "osdep_service.h" +#include "platform_stdlib.h" + +/****************************************************** + * Constants + ******************************************************/ + +#if CONFIG_DEBUG_LOG > 3 +#define WIFI_INDICATE_MSG 1 +#else +#define WIFI_INDICATE_MSG 0 +#endif +#define WIFI_MANAGER_STACKSIZE 400 // 1300 +#define WIFI_MANAGER_PRIORITY (0) //Actual priority is 4 since calling rtw_create_task +#define WIFI_MANAGER_Q_SZ 8 + +#define WIFI_EVENT_MAX_ROW 3 +/****************************************************** + * Globals + ******************************************************/ + +static event_list_elem_t event_callback_list[WIFI_EVENT_MAX][WIFI_EVENT_MAX_ROW]; +#if CONFIG_WIFI_IND_USE_THREAD +static rtw_worker_thread_t wifi_worker_thread; +#endif + +//----------------------------------------------------------------------------// +#if CONFIG_WIFI_IND_USE_THREAD +static rtw_result_t rtw_send_event_to_worker(int event_cmd, char *buf, + int buf_len, int flags) { + rtw_event_message_t message; + int i; + rtw_result_t ret = RTW_SUCCESS; + char *local_buf = NULL; + + if (event_cmd >= WIFI_EVENT_MAX) + return RTW_BADARG; + + for (i = 0; i < WIFI_EVENT_MAX_ROW; i++) { + if (event_callback_list[event_cmd][i].handler == NULL) + continue; + + message.function = + (event_handler_t) event_callback_list[event_cmd][i].handler; + message.buf_len = buf_len; + if (buf_len) { + local_buf = (char*) pvPortMalloc(buf_len); + if (local_buf == NULL) + return RTW_NOMEM; + memcpy(local_buf, buf, buf_len); + //debug_printf("Allocate %p(%d) for evcmd %d\n", local_buf, buf_len, event_cmd); + } + message.buf = local_buf; + message.flags = flags; + message.user_data = event_callback_list[event_cmd][i].handler_user_data; + + ret = rtw_push_to_xqueue(&wifi_worker_thread.event_queue, &message, 0); + if (ret != RTW_SUCCESS) { + if (local_buf) { + warning_printf( + "rtw_send_event_to_worker: enqueue cmd %d failed and free %p(%d)\n", + event_cmd, local_buf, buf_len); + vPortFree(local_buf); + } + break; + } + } + return ret; +} +#else +static rtw_result_t rtw_indicate_event_handle(int event_cmd, char *buf, int buf_len, int flags) +{ + rtw_event_handler_t handle = NULL; + int i; + + if(event_cmd >= WIFI_EVENT_MAX) + return RTW_BADARG; + + for(i = 0; i < WIFI_EVENT_MAX_ROW; i++) { + handle = event_callback_list[event_cmd][i].handler; + if(handle == NULL) + continue; + handle(buf, buf_len, flags, event_callback_list[event_cmd][i].handler_user_data); + } + + return RTW_SUCCESS; +} +#endif +#if 0 // test beacon +#include "gpio_api.h" // mbed +extern gpio_t gpio_led; +#endif + +void wifi_indication(WIFI_EVENT_INDICATE event, unsigned char *buf, int buf_len, + int flags) { + // + // If upper layer application triggers additional operations on receiving of wext_wlan_indicate, + // please strictly check current stack size usage (by using uxTaskGetStackHighWaterMark() ) + // , and tries not to share the same stack with wlan driver if remaining stack space is + // not available for the following operations. + // ex: using semaphore to notice another thread. + switch (event) { + case WIFI_EVENT_DISCONNECT: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): Disconnection indication received\n", __func__, event); +#endif + break; + case WIFI_EVENT_CONNECT: + // For WPA/WPA2 mode, indication of connection does not mean data can be + // correctly transmitted or received. Data can be correctly transmitted or + // received only when 4-way handshake is done. + // Please check WIFI_EVENT_FOURWAY_HANDSHAKE_DONE event +#if(WIFI_INDICATE_MSG>0) + // Sample: return mac address + if (buf != NULL && buf_len == 6) { + info_printf( + "%s(%d): Connect indication received: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, event, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + } +#endif + break; + case WIFI_EVENT_FOURWAY_HANDSHAKE_DONE: +#if(WIFI_INDICATE_MSG>0) + if (buf != NULL) + info_printf("%s(%d): %s\n", __func__, event, buf); +#endif + break; + case WIFI_EVENT_SCAN_RESULT_REPORT: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_SCAN_RESULT_REPORT\n", __func__, event); +#endif + break; + case WIFI_EVENT_SCAN_DONE: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_SCAN_DONE\n", __func__, event); +//#if CONFIG_DEBUG_LOG > 3 +// debug_printf("Time at start %d ms.\n", xTaskGetTickCount()); +//#endif +#endif + break; + case WIFI_EVENT_RECONNECTION_FAIL: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): %s\n", __func__, event, buf); +#endif + break; + case WIFI_EVENT_NO_NETWORK: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): %s\n", __func__, event, buf); +#endif + break; +#if CONFIG_ENABLE_P2P + case WIFI_EVENT_SEND_ACTION_DONE: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): %s\n", __func__, event, buf); +#endif + break; + case WIFI_EVENT_RX_MGNT: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_RX_MGNT\n", __func__, event); +#endif + break; +#endif //CONFIG_ENABLE_P2P + case WIFI_EVENT_STA_ASSOC: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_STA_ASSOC\n", __func__, event); +#endif + break; + case WIFI_EVENT_STA_DISASSOC: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_STA_DISASSOC\n", __func__, event); +#endif + break; +#ifdef CONFIG_WPS + case WIFI_EVENT_STA_WPS_START: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_STA_WPS_START\n", __func__, event); +#endif + break; + case WIFI_EVENT_WPS_FINISH: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_WPS_FINISH\n", __func__, event); +#endif + break; + case WIFI_EVENT_EAPOL_RECVD: +#if(WIFI_INDICATE_MSG>0) + info_printf("%s(%d): WIFI_EVENT_EAPOL_RECVD\n", __func__, event); +#endif + break; +#endif + case WIFI_EVENT_BEACON_AFTER_DHCP: +#if(WIFI_INDICATE_MSG>1) + info_printf("%s(%d): WIFI_EVENT_BEACON_AFTER_DHCP\n", __func__, event); +#endif +#if 0 // test beacon + gpio_write(&gpio_led, 1); + gpio_write(&gpio_led, 0); +#endif + break; + } + +#if CONFIG_INIC_EN + inic_indicate_event(event, buf, buf_len, flags); +#endif//CONFIG_INIC_EN + +#if CONFIG_WIFI_IND_USE_THREAD + rtw_send_event_to_worker(event, buf, buf_len, flags); +#else + rtw_indicate_event_handle(event, buf, buf_len, flags); +#endif +} + +void wifi_reg_event_handler(unsigned int event_cmds, + rtw_event_handler_t handler_func, void *handler_user_data) { + int i = 0, j = 0; + if (event_cmds < WIFI_EVENT_MAX) { + for (i = 0; i < WIFI_EVENT_MAX_ROW; i++) { + if (event_callback_list[event_cmds][i].handler == NULL) { + for (j = 0; j < WIFI_EVENT_MAX_ROW; j++) { + if (event_callback_list[event_cmds][j].handler + == handler_func) { + return; + } + } + event_callback_list[event_cmds][i].handler = handler_func; + event_callback_list[event_cmds][i].handler_user_data = + handler_user_data; + return; + } + } + } +} + +void wifi_unreg_event_handler(unsigned int event_cmds, + rtw_event_handler_t handler_func) { + int i; + if (event_cmds < WIFI_EVENT_MAX) { + for (i = 0; i < WIFI_EVENT_MAX_ROW; i++) { + if (event_callback_list[event_cmds][i].handler == handler_func) { + event_callback_list[event_cmds][i].handler = NULL; + event_callback_list[event_cmds][i].handler_user_data = NULL; + return; + } + } + } +} + +void init_event_callback_list() { + memset(event_callback_list, 0, sizeof(event_callback_list)); +} + +int wifi_manager_init() { +#if CONFIG_WIFI_IND_USE_THREAD + rtw_create_worker_thread(&wifi_worker_thread, + WIFI_MANAGER_PRIORITY, + WIFI_MANAGER_STACKSIZE, + WIFI_MANAGER_Q_SZ); +#endif + return 0; +} + +void rtw_wifi_manager_deinit() { +#if CONFIG_WIFI_IND_USE_THREAD + rtw_delete_worker_thread(&wifi_worker_thread); +#endif +} + diff --git a/USDK/component/common/api/wifi/wifi_ind.h b/USDK/component/common/api/wifi/wifi_ind.h new file mode 100644 index 0000000..4fb7012 --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_ind.h @@ -0,0 +1,34 @@ +#ifndef _WIFI_INDICATE_H +#define _WIFI_INDICATE_H +#include "wifi_conf.h" + +typedef void (*rtw_event_handler_t)(char *buf, int buf_len, int flags, void* handler_user_data ); + +typedef struct +{ +// WIFI_EVENT_INDICATE event_cmd; + rtw_event_handler_t handler; + void* handler_user_data; +} event_list_elem_t; + +void init_event_callback_list(void); +extern void wifi_indication( rtw_event_indicate_t event, unsigned char *buf, int buf_len, int flags); +/** Register the event listener + * + * @param[in] event_cmds : The event command number indicated + * @param[in] handler_func : the callback function which will + * receive and process the event + * @param[in] handler_user_data : user specific data that will be + * passed directly to the callback function + * + * @note : Set the same event_cmds with empty handler_func will + * unregister the event_cmds + * + * @return RTW_SUCCESS : if successfully registers the event + * RTW_ERROR : if an error occurred + */ +extern void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func, void *handler_user_data); +extern void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func); + +#endif //_WIFI_INDICATE_H + diff --git a/USDK/component/common/api/wifi/wifi_promisc.c b/USDK/component/common/api/wifi/wifi_promisc.c new file mode 100644 index 0000000..38d858d --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_promisc.c @@ -0,0 +1,475 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include "tcpip.h" +#include "wifi/wifi_conf.h" +#include "wifi_simple_config_parser.h" + +#ifndef CONFIG_WLAN +#define CONFIG_WLAN 1 +#endif + +#if CONFIG_WLAN +#include + +#ifdef CONFIG_PROMISC + +#define _adapter void +#define recv_frame void +extern void _promisc_deinit(_adapter *padapter); +extern int _promisc_recv_func(_adapter *padapter, recv_frame *rframe); +extern int _promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char *, unsigned int, void *), unsigned char len_used); +extern unsigned char is_promisc_enabled(void); +extern int promisc_get_fixed_channel(void *fixed_bssid, unsigned char *ssid, int *ssid_length); +extern unsigned char is_promisc_enabled(void); + +#endif + +// Add extra interfaces to make release sdk able to determine promisc API linking +void promisc_deinit(void *padapter) +{ +#ifdef CONFIG_PROMISC + _promisc_deinit(padapter); +#endif +} + +int promisc_recv_func(void *padapter, void *rframe) +{ + // Never reach here if not define CONFIG_PROMISC +#ifdef CONFIG_PROMISC + return _promisc_recv_func(padapter, rframe); +#else + return 0; +#endif +} + +int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used) +{ +#ifdef CONFIG_PROMISC + return _promisc_set(enabled, callback, len_used); +#else + return -1; +#endif +} + +unsigned char is_promisc_enabled(void) +{ +#ifdef CONFIG_PROMISC + return _is_promisc_enabled(); +#else + return 0; +#endif +} + +int promisc_get_fixed_channel(void *fixed_bssid, u8 *ssid, int *ssid_length) +{ +#ifdef CONFIG_PROMISC + return _promisc_get_fixed_channel(fixed_bssid, ssid, ssid_length); +#else + return 0; +#endif +} +// End of Add extra interfaces + +struct eth_frame { + struct eth_frame *prev; + struct eth_frame *next; + unsigned char da[6]; + unsigned char sa[6]; + unsigned int len; + unsigned char type; + signed char rssi; +}; + +#if CONFIG_INIC_CMD_RSP +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif +struct inic_eth_frame { + unsigned char da[6]; + unsigned char sa[6]; + unsigned int len; + unsigned char type; +}; +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + +static struct inic_eth_frame *inic_frame, *inic_frame_tail = NULL; +static int inic_frame_cnt = 0; +#define MAX_INIC_FRAME_NUM 50 //maximum packets for each channel +extern void inic_c2h_msg(const char *atcmd, char status, char *msg, u16 msg_len); +#endif + +struct eth_buffer { + struct eth_frame *head; + struct eth_frame *tail; +}; + +static struct eth_buffer eth_buffer; + +#ifdef CONFIG_PROMISC +#define MAX_PACKET_FILTER_INFO 5 +#define FILTER_ID_INIT_VALUE 10 +rtw_packet_filter_info_t paff_array[MAX_PACKET_FILTER_INFO]={0, 0, 0, 0, 0}; +static u8 packet_filter_enable_num = 0; + +void promisc_init_packet_filter() +{ + int i = 0; + for(i=0; ioffset; + paff_array[i].patt.mask_size = patt->mask_size; + paff_array[i].patt.mask = pvPortMalloc(patt->mask_size); + memcpy(paff_array[i].patt.mask, patt->mask, patt->mask_size); + paff_array[i].patt.pattern= pvPortMalloc(patt->mask_size); + memcpy(paff_array[i].patt.pattern, patt->pattern, patt->mask_size); + + paff_array[i].rule = rule; + paff_array[i].enable = 0; + + return 0; +} + +int promisc_enable_packet_filter(u8 filter_id) +{ + int i = 0; + while(i < MAX_PACKET_FILTER_INFO){ + if(paff_array[i].filter_id == filter_id) + break; + i++; + } + + if(i == MAX_PACKET_FILTER_INFO) + return -1; + + paff_array[i].enable = 1; + packet_filter_enable_num++; + return 0; +} + +int promisc_disable_packet_filter(u8 filter_id) +{ + int i = 0; + while(i < MAX_PACKET_FILTER_INFO){ + if(paff_array[i].filter_id == filter_id) + break; + i++; + } + + if(i == MAX_PACKET_FILTER_INFO) + return -1; + + paff_array[i].enable = 0; + packet_filter_enable_num--; + return 0; +} + +int promisc_remove_packet_filter(u8 filter_id) +{ + int i = 0; + while(i < MAX_PACKET_FILTER_INFO){ + if(paff_array[i].filter_id == filter_id) + break; + i++; + } + + if(i == MAX_PACKET_FILTER_INFO) + return -1; + + paff_array[i].filter_id = FILTER_ID_INIT_VALUE; + paff_array[i].enable = 0; + paff_array[i].patt.mask_size = 0; + paff_array[i].rule = 0; + if(paff_array[i].patt.mask){ + vPortFree(paff_array[i].patt.mask); + paff_array[i].patt.mask = NULL; + } + + if(paff_array[i].patt.pattern){ + vPortFree(paff_array[i].patt.pattern); + paff_array[i].patt.pattern = NULL; + } + return 0; +} +#endif + +/* Make callback simple to prevent latency to wlan rx when promiscuous mode */ +static void promisc_callback(unsigned char *buf, unsigned int len, void* userdata) +{ + struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame)); + + if(frame) { + frame->prev = NULL; + frame->next = NULL; + memcpy(frame->da, buf, 6); + memcpy(frame->sa, buf + 6, 6); + frame->len = len; + frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi; + taskENTER_CRITICAL(); + + if(eth_buffer.tail) { + eth_buffer.tail->next = frame; + frame->prev = eth_buffer.tail; + eth_buffer.tail = frame; + } + else { + eth_buffer.head = frame; + eth_buffer.tail = frame; + } + + taskEXIT_CRITICAL(); + } +} + +struct eth_frame* retrieve_frame(void) +{ + struct eth_frame *frame = NULL; + + taskENTER_CRITICAL(); + + if(eth_buffer.head) { + frame = eth_buffer.head; + + if(eth_buffer.head->next) { + eth_buffer.head = eth_buffer.head->next; + eth_buffer.head->prev = NULL; + } + else { + eth_buffer.head = NULL; + eth_buffer.tail = NULL; + } + } + + taskEXIT_CRITICAL(); + + return frame; +} + +static void promisc_test(int duration, unsigned char len_used) +{ + int ch; + unsigned int start_time; + struct eth_frame *frame; + eth_buffer.head = NULL; + eth_buffer.tail = NULL; + + wifi_enter_promisc_mode(); + wifi_set_promisc(RTW_PROMISC_ENABLE, promisc_callback, len_used); + + for(ch = 1; ch <= 13; ch ++) { + if(wifi_set_channel(ch) == 0) + printf("\n\n\rSwitch to channel(%d)", ch); + + start_time = xTaskGetTickCount(); + + while(1) { + unsigned int current_time = xTaskGetTickCount(); + + if((current_time - start_time) < (duration)) { // duration * configTICK_RATE_HZ + frame = retrieve_frame(); + + if(frame) { + int i; + printf("\n\rDA:"); + for(i = 0; i < 6; i ++) + printf(" %02x", frame->da[i]); + printf(", SA:"); + for(i = 0; i < 6; i ++) + printf(" %02x", frame->sa[i]); + printf(", len=%d", frame->len); + printf(", RSSI=%d", frame->rssi); +#if CONFIG_INIC_CMD_RSP + if(inic_frame_tail){ + if(inic_frame_cnt < MAX_INIC_FRAME_NUM){ + memcpy(inic_frame_tail->da, frame->da, 6); + memcpy(inic_frame_tail->sa, frame->sa, 6); + inic_frame_tail->len = frame->len; + inic_frame_tail++; + inic_frame_cnt++; + } + } +#endif + vPortFree((void *) frame); + } + else + vTaskDelay(1); //delay 1 tick + } + else + break; + } +#if CONFIG_INIC_CMD_RSP + if(inic_frame){ + inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt); + memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM); + inic_frame_tail = inic_frame; + inic_frame_cnt = 0; + rtw_msleep_os(10); + } +#endif + } + + wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0); + + while((frame = retrieve_frame()) != NULL) + vPortFree((void *) frame); +} + +static void promisc_callback_all(unsigned char *buf, unsigned int len, void* userdata) +{ + struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame)); + + if(frame) { + frame->prev = NULL; + frame->next = NULL; + memcpy(frame->da, buf+4, 6); + memcpy(frame->sa, buf+10, 6); + frame->len = len; + /* + * type is the first byte of Frame Control Field of 802.11 frame + * If the from/to ds information is needed, type could be reused as follows: + * frame->type = ((((ieee80211_frame_info_t *)userdata)->i_fc & 0x0100) == 0x0100) ? 2 : 1; + * 1: from ds; 2: to ds + */ + frame->type = *buf; + frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi; + + taskENTER_CRITICAL(); + + if(eth_buffer.tail) { + eth_buffer.tail->next = frame; + frame->prev = eth_buffer.tail; + eth_buffer.tail = frame; + } + else { + eth_buffer.head = frame; + eth_buffer.tail = frame; + } + + taskEXIT_CRITICAL(); + } +} +static void promisc_test_all(int duration, unsigned char len_used) +{ + int ch; + unsigned int start_time; + struct eth_frame *frame; + eth_buffer.head = NULL; + eth_buffer.tail = NULL; + + wifi_enter_promisc_mode(); + wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback_all, len_used); + + for(ch = 1; ch <= 13; ch ++) { + if(wifi_set_channel(ch) == 0) + printf("\n\n\rSwitch to channel(%d)", ch); + + start_time = xTaskGetTickCount(); + + while(1) { + unsigned int current_time = xTaskGetTickCount(); + + if((current_time - start_time) < (duration)) { // duration * configTICK_RATE_HZ + frame = retrieve_frame(); + + if(frame) { + int i; + printf("\n\rTYPE: 0x%x, ", frame->type); + printf("DA:"); + for(i = 0; i < 6; i ++) + printf(" %02x", frame->da[i]); + printf(", SA:"); + for(i = 0; i < 6; i ++) + printf(" %02x", frame->sa[i]); + printf(", len=%d", frame->len); + printf(", RSSI=%d", frame->rssi); +#if CONFIG_INIC_CMD_RSP + if(inic_frame_tail){ + if(inic_frame_cnt < MAX_INIC_FRAME_NUM){ + memcpy(inic_frame_tail->da, frame->da, 6); + memcpy(inic_frame_tail->sa, frame->sa, 6); + inic_frame_tail->len = frame->len; + inic_frame_tail->type = frame->type; + inic_frame_tail++; + inic_frame_cnt++; + } + } +#endif + vPortFree((void *) frame); + } + else + vTaskDelay(1); //delay 1 tick + } + else + break; + } +#if CONFIG_INIC_CMD_RSP + if(inic_frame){ + inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt); + memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM); + inic_frame_tail = inic_frame; + inic_frame_cnt = 0; + rtw_msleep_os(10); + } +#endif + } + + wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0); + + while((frame = retrieve_frame()) != NULL) + vPortFree((void *) frame); +} + +void cmd_promisc(int argc, char **argv) +{ + int duration; +#if CONFIG_INIC_CMD_RSP + inic_frame_tail = inic_frame = pvPortMalloc(sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM); + if(inic_frame == NULL){ + inic_c2h_msg("ATWM", RTW_BUFFER_UNAVAILABLE_TEMPORARY, NULL, 0); + return; + } +#endif +#ifdef CONFIG_PROMISC + wifi_init_packet_filter(); +#endif + if((argc == 2) && ((duration = atoi(argv[1])) > 0)) + //promisc_test(duration, 0); + promisc_test_all(duration, 0); + else if((argc == 3) && ((duration = atoi(argv[1])) > 0) && (strcmp(argv[2], "with_len") == 0)) + promisc_test(duration, 1); + else + printf("\n\rUsage: %s DURATION_MSECONDS [with_len]", argv[0]); +#if CONFIG_INIC_CMD_RSP + if(inic_frame) + vPortFree(inic_frame); + inic_frame_tail = NULL; + inic_frame_cnt = 0; +#endif +} +#endif //#if CONFIG_WLAN diff --git a/USDK/component/common/api/wifi/wifi_simple_config.c b/USDK/component/common/api/wifi/wifi_simple_config.c new file mode 100644 index 0000000..924bb2a --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_simple_config.c @@ -0,0 +1,1086 @@ +#include +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include "udp.h" +#include +#if LWIP_SOCKET +#include +#include +#include "platform_stdlib.h" +#include "wifi_simple_config_parser.h" +#include "wifi_simple_config.h" + +#if CONFIG_EXAMPLE_UART_ATCMD +#include "at_cmd/atcmd_wifi.h" +#endif + +#define STACKSIZE 512 +#define LEAVE_ACK_EARLY 0 + +#if (CONFIG_LWIP_LAYER == 0) +extern u32 _ntohl(u32 n); +#endif + +#if CONFIG_WLAN +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) +#include "wifi/wifi_conf.h" +int is_promisc_callback_unlock = 0; +static int is_fixed_channel; +int fixed_channel_num; +unsigned char g_ssid[32]; +int g_ssid_len; + +extern int promisc_get_fixed_channel( void *, u8 *, int* ); +struct rtk_test_sc; + +#ifdef PACK_STRUCT_USE_INCLUDES +#include "arch/bpstruct.h" +#endif + +// support scan list function from APP, comment by default +//#define SC_SCAN_SUPPORT + +PACK_STRUCT_BEGIN +struct ack_msg { + PACK_STRUCT_FIELD(u8_t flag); + PACK_STRUCT_FIELD(u16_t length); + PACK_STRUCT_FIELD(u8_t smac[6]); + PACK_STRUCT_FIELD(u8_t status); + PACK_STRUCT_FIELD(u16_t device_type); + PACK_STRUCT_FIELD(u32_t device_ip); + PACK_STRUCT_FIELD(u8_t device_name[64]); +}__attribute__((packed)); // PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +#include "arch/epstruct.h" +#endif + + + +#define MULCAST_PORT (8864) + +#define SCAN_BUFFER_LENGTH (1024) + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#define JOIN_SIMPLE_CONFIG (uint32_t)(1 << 8) +extern uint32_t rtw_join_status; +char simple_config_terminate = 0; + +int simple_config_result; +static struct ack_msg *ack_content; +struct rtk_test_sc *backup_sc_ctx; +extern struct netif xnetif[NET_IF_NUM]; + +// listen scan command and ACK +#ifdef SC_SCAN_SUPPORT + +static int pin_enable = 0; +static int scan_start = 0; + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct ack_msg_scan { + u8_t flag; + u16_t length; + u8_t smac[6]; + u8_t status; + u16_t device_type; + u32_t device_ip; + u8_t device_name[64]; + u8_t pin_enabled; +} +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +static void set_device_name(char *device_name) +{ + int pos = 0; + memcpy(device_name, "ameba_", 6); + for(int i = 0; i < 3; i++) + { + sprintf(device_name + 6 + pos, "%02x", xnetif[0].hwaddr[i + 3]); + pos += 2; + if(i != 2) + device_name[6 + pos++] = ':'; + } + return; +} +void SC_scan_thread(void *para) +{ + int sockfd_scan; + struct sockaddr_in device_addr; + unsigned char packet[256]; + struct sockaddr from; + struct sockaddr_in *from_sin = (struct sockaddr_in*) &from; + socklen_t fromLen = sizeof(from); + struct ack_msg_scan ack_msg; + + #ifdef RTW_PACK_STRUCT_USE_INCLUDES + #include "pack_begin.h" + #endif + RTW_PACK_STRUCT_BEGIN + struct scan_msg{ + unsigned char flag; + unsigned short length; + unsigned char sec_level; + unsigned char nonce[64]; + unsigned char digest[16]; + unsigned char smac[6]; + unsigned short device_type; + }; + RTW_PACK_STRUCT_STRUCT; + RTW_PACK_STRUCT_END + #ifdef RTW_PACK_STRUCT_USE_INCLUDES + #include "pack_end.h" + #endif + + struct scan_msg *pMsg; + + if ((sockfd_scan = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { + printf("SC scan socket error\n"); + return; + } + memset(&device_addr, 0, sizeof(struct sockaddr_in)); + device_addr.sin_family = AF_INET; + device_addr.sin_port = htons(18864); + device_addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(sockfd_scan, (struct sockaddr *)&device_addr, sizeof(struct sockaddr)) == -1) + { + printf("SC scan bind error\n"); + close(sockfd_scan); + return; + } + memset(packet, 0, sizeof(packet)); + + // for now, no checking for the validity of received data, wf, 0225 + while(1) + { + if((recvfrom(sockfd_scan, &packet, sizeof(packet), MSG_DONTWAIT, &from, &fromLen)) >= 0) { + uint16_t from_port = ntohs(from_sin->sin_port); + //printf("SC_scan: recv %d bytes from %d.%d.%d.%d:%d\n",packetLen, ip[0], ip[1], ip[2], ip[3], from_port); + + from_sin->sin_port = htons(8864); + // send ACK for scan + pMsg = (struct scan_msg *)packet; + if(pMsg->flag == 0x00) // scan flag + { + ack_msg.flag = 0x21; + ack_msg.length = sizeof(struct ack_msg_scan); + ack_msg.status = 1; + memcpy(ack_msg.smac, xnetif[0].hwaddr, 6); + + ack_msg.device_type = 0; + ack_msg.device_ip = xnetif[0].ip_addr.addr; + memset(ack_msg.device_name, 0, 64); + set_device_name((char*)ack_msg.device_name); + // set the device_name to: ameba_xxxxxx(last 3 bytes of MAC) + ack_msg.pin_enabled = pin_enable; + for(int i = 0; i < 3;i++) + { + int ret = sendto(sockfd_scan,(unsigned char *)&ack_msg,sizeof(struct ack_msg_scan),0,(struct sockaddr *)&from, fromLen); + if(ret < 0) + printf("send ACK for scan fail\n"); + //else + //printf("send %d bytes of ACK to scan\n", ret); + } + } + else + continue; + } + vTaskDelay(500); + } +} + +void SC_listen_ACK_scan() +{ + if(xTaskCreate(SC_scan_thread, ((const char*)"SC_scan_thread"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("%s xTaskCreate(SC_scan_thread) failed\n", __FUNCTION__); +} + +#endif + +void SC_set_ack_content() +{ + memset(ack_content, 0, sizeof(struct ack_msg)); + ack_content->flag = 0x20; + ack_content->length = htons(sizeof(struct ack_msg)-3); + memcpy(ack_content->smac, xnetif[0].hwaddr, 6); + ack_content->status = 0; + ack_content->device_type = 0; + ack_content->device_ip = xnetif[0].ip_addr.addr; + memset(ack_content->device_name, 0, 64); +} + +int SC_send_simple_config_ack(u8 round) +{ +#if CONFIG_LWIP_LAYER + int ack_transmit_round, ack_num_each_sec; + int ack_socket; + //int sended_data = 0; + struct sockaddr_in to_addr; +#if LEAVE_ACK_EARLY + u8 check_phone_ack = 0; +#endif + SC_set_ack_content(); + + ack_socket = socket(PF_INET, SOCK_DGRAM, IP_PROTO_UDP); + if (ack_socket == -1) { + return -1; + } +#if LEAVE_ACK_EARLY + else { + struct sockaddr_in bindAddr; + bindAddr.sin_family = AF_INET; + bindAddr.sin_port = htons(8864); + bindAddr.sin_addr.s_addr = INADDR_ANY; + if(bind(ack_socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr)) == 0) + check_phone_ack = 1; + } +#endif + printf("Sending simple config ack\n"); + FD_ZERO(&to_addr); + to_addr.sin_family = AF_INET; + to_addr.sin_port = htons(8864); + to_addr.sin_addr.s_addr = (backup_sc_ctx->ip_addr); + for (ack_transmit_round = 0;ack_transmit_round < round; ack_transmit_round++) { + for (ack_num_each_sec = 0;ack_num_each_sec < 20; ack_num_each_sec++) { + //sended_data = + sendto(ack_socket, (unsigned char *)ack_content, sizeof(struct ack_msg), 0, (struct sockaddr *) &to_addr, sizeof(struct sockaddr)); + //printf("\r\nAlready send %d bytes data\n", sended_data); + vTaskDelay(50); /* delay 50 ms */ + +#if LEAVE_ACK_EARLY + if(check_phone_ack) { + unsigned char packet[100]; + int packetLen; + struct sockaddr from; + struct sockaddr_in *from_sin = (struct sockaddr_in*) &from; + socklen_t fromLen = sizeof(from); + + if((packetLen = recvfrom(ack_socket, &packet, sizeof(packet), MSG_DONTWAIT, &from, &fromLen)) >= 0) { + uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr; + uint16_t from_port = ntohs(from_sin->sin_port); + printf("recv %d bytes from %d.%d.%d.%d:%d at round=%d, num=%d\n", + packetLen, ip[0], ip[1], ip[2], ip[3], from_port, + ack_transmit_round, ack_num_each_sec); + goto leave_ack; + } + } +#endif + } + } + +leave_ack: + close(ack_socket); +#endif + +#if CONFIG_INIC_CMD_RSP + extern unsigned int inic_sc_ip_addr; + inic_sc_ip_addr = backup_sc_ctx->ip_addr; + inic_c2h_wifi_info("ATWQ", RTW_SUCCESS); +#endif + + return 0; +} + +static int SC_check_and_show_connection_info(void) +{ + rtw_wifi_setting_t setting; + int ret = -1; + +#if CONFIG_LWIP_LAYER + /* If not rise priority, LwIP DHCP may timeout */ + vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 3); + /* Start DHCP Client */ + ret = LwIP_DHCP(0, DHCP_START); + vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 1); +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD == 0 + wifi_get_setting(WLAN0_NAME, &setting); + wifi_show_setting(WLAN0_NAME, &setting); +#endif + +#if CONFIG_LWIP_LAYER + if (ret != DHCP_ADDRESS_ASSIGNED) + return SC_DHCP_FAIL; + else +#endif + return SC_SUCCESS; +} + +static void check_and_set_security_in_connection(rtw_security_t security_mode, rtw_network_info_t *wifi) +{ + + if (security_mode == RTW_SECURITY_WPA2_AES_PSK) { + printf("wifi->security_type = RTW_SECURITY_WPA2_AES_PSK\n"); + wifi->security_type = RTW_SECURITY_WPA2_AES_PSK; + } else if (security_mode == RTW_SECURITY_WEP_PSK) { + printf("wifi->security_type = RTW_SECURITY_WEP_PSK\n"); + wifi->security_type = RTW_SECURITY_WEP_PSK; + wifi->key_id = 0; + } else if (security_mode == RTW_SECURITY_WPA_AES_PSK) { + printf("wifi->security_type = RTW_SECURITY_WPA_AES_PSK\n"); + wifi->security_type = RTW_SECURITY_WPA_AES_PSK; + } else { + printf("wifi->security_type = RTW_SECURITY_OPEN\n"); + wifi->security_type = RTW_SECURITY_OPEN; + } +} + +int get_connection_info_from_profile(rtw_security_t security_mode, rtw_network_info_t *wifi) +{ + + printf("======= Connection Information =======\n"); + check_and_set_security_in_connection(security_mode, wifi); + + wifi->password = backup_sc_ctx->password; + wifi->password_len = (int)strlen((char const *)backup_sc_ctx->password); + + /* 1.both scanned g_ssid and ssid from profile are null, return fail */ + if ((0 == g_ssid_len) && (0 == strlen(backup_sc_ctx->ssid))) { + printf("no ssid info found, connect will fail\n"); + return -1; + } + + /* g_ssid and ssid from profile are same, enter connect and retry */ + if (0 == strcmp(backup_sc_ctx->ssid, g_ssid)) { + wifi->ssid.len = strlen(backup_sc_ctx->ssid); + rtw_memcpy(wifi->ssid.val, backup_sc_ctx->ssid, wifi->ssid.len); + printf("using ssid from profile and scan result\n"); + goto ssid_set_done; + } + + /* if there is profile, but g_ssid and profile are different, using profile to connect and retry */ + if (strlen(backup_sc_ctx->ssid) > 0) { + wifi->ssid.len = strlen(backup_sc_ctx->ssid); + rtw_memcpy(wifi->ssid.val, backup_sc_ctx->ssid, wifi->ssid.len); + printf("using ssid only from profile\n"); + goto ssid_set_done; + +} + + /* if there is no profile but have scanned ssid, using g_ssid to connect and retry + (maybe ssid is right and password is wrong) */ + if (g_ssid_len > 0) { + wifi->ssid.len = g_ssid_len; + rtw_memcpy(wifi->ssid.val, g_ssid, wifi->ssid.len); + printf("using ssid only from scan result\n"); + goto ssid_set_done; + } + + +ssid_set_done: + + + if(wifi->security_type == RTW_SECURITY_WEP_PSK) + { + if(wifi->password_len == 10) + { + u32 p[5] = {0}; + u8 pwd[6], i = 0; + sscanf((const char*)backup_sc_ctx->password, "%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4]); + for(i=0; i< 5; i++) + pwd[i] = (u8)p[i]; + pwd[5] = '\0'; + memset(backup_sc_ctx->password, 0, 65); + strcpy((char*)backup_sc_ctx->password, (char*)pwd); + wifi->password_len = 5; + }else if(wifi->password_len == 26){ + u32 p[13] = {0}; + u8 pwd[14], i = 0; + sscanf((const char*)backup_sc_ctx->password, "%02x%02x%02x%02x%02x%02x%02x"\ + "%02x%02x%02x%02x%02x%02x", &p[0], &p[1], &p[2], &p[3], &p[4],\ + &p[5], &p[6], &p[7], &p[8], &p[9], &p[10], &p[11], &p[12]); + for(i=0; i< 13; i++) + pwd[i] = (u8)p[i]; + pwd[13] = '\0'; + memset(backup_sc_ctx->password, 0, 64); + strcpy((char*)backup_sc_ctx->password, (char*)pwd); + wifi->password_len = 13; + } + } + printf("wifi.password = %s\n", wifi->password); + printf("wifi.password_len = %d\n", wifi->password_len); + printf("wifi.ssid = %s\n", wifi->ssid.val); + printf("wifi.ssid_len = %d\n", wifi->ssid.len); + printf("wifi.channel = %d\n", fixed_channel_num); + printf("===== start to connect target AP =====\n"); + return 0; +} + + + + +#pragma pack(1) +struct scan_with_ssid_result { + u8 len; /* len of a memory area store ap info */ + u8 mac[ETH_ALEN]; + int rssi; + u8 sec_mode; + u8 password_id; + u8 channel; + //char ssid[65]; +}; + + +struct sc_ap_info { + + char *ssid; + int ssid_len; + +}; + + + +rtw_security_t SC_translate_iw_security_mode(u8 security_type) { + + rtw_security_t security_mode = RTW_SECURITY_UNKNOWN; + + + switch (security_type) { + case IW_ENCODE_ALG_NONE: + security_mode = RTW_SECURITY_OPEN; + break; + case IW_ENCODE_ALG_WEP: + security_mode = RTW_SECURITY_WEP_PSK; + break; + case IW_ENCODE_ALG_CCMP: + security_mode = RTW_SECURITY_WPA2_AES_PSK; + break; + default: + printf("error: security type not supported\n"); + break; + }; + + return security_mode; +} + +/* + + scan buf format: + + len mac rssi sec wps channel ssid + 1B 6B 4B 1B 1B 1B (len - 14)B + +*/ +enum sc_result SC_parse_scan_result_and_connect(scan_buf_arg* scan_buf, rtw_network_info_t *wifi) +{ + + struct scan_with_ssid_result scan_result; + + char *buf = scan_buf->buf; + int buf_len = scan_buf->buf_len; + char ssid[65]; + int ssid_len = 0 ; + int parsed_len = 0; + u8 scan_channel = 0; + int i = 0; + int ret = 0; + u8 pscan_config = PSCAN_ENABLE | PSCAN_SIMPLE_CONFIG; + + memset((void*)&scan_result, 0, sizeof(struct scan_with_ssid_result)); + + /* if wifi_is_connected_to_ap and we run here, ther will be hardfault(caused by auto reconnect) */ + printf("Scan result got, start to connect AP with scanned bssid\n"); + + while (1) { + + memcpy(&scan_result, buf, sizeof(struct scan_with_ssid_result)); + /* len maybe 3*/ + if (scan_result.len < sizeof(struct scan_with_ssid_result)) { + printf("length = %d, too small!\n",scan_result.len); + goto sc_connect_wifi_fail; + } + + /* set ssid */ + memset(ssid, 0, 65); + + ssid_len = scan_result.len - sizeof(struct scan_with_ssid_result); + + memcpy(ssid, buf + sizeof(struct scan_with_ssid_result), ssid_len); + + /* run here means there is a match */ + if (ssid_len == wifi->ssid.len) { + if (memcmp(ssid, wifi->ssid.val, ssid_len) == 0) { + + printf("Connecting to MAC=%02x:%02x:%02x:%02x:%02x:%02x, ssid = %s, SEC=%d\n", + scan_result.mac[0], scan_result.mac[1], scan_result.mac[2], + scan_result.mac[3], scan_result.mac[4], scan_result.mac[5], + ssid, scan_result.sec_mode); + + scan_channel = scan_result.channel; + + + /* try 3 times to connect */ + for (i = 0; i < 3; i++) { + if(wifi_set_pscan_chan(&scan_channel, &pscan_config, 1) < 0){ + printf("\n\rERROR: wifi set partial scan channel fail"); + ret = SC_TARGET_CHANNEL_SCAN_FAIL; + goto sc_connect_wifi_fail; + } + ret = wifi_connect( + scan_result.mac, + 1, + (char*)wifi->ssid.val, + SC_translate_iw_security_mode(scan_result.sec_mode), + (char*)wifi->password, + 0, NULL); + if (ret == RTW_SUCCESS) + goto sc_connect_wifi_success; + } + + } + } + + + buf = buf + scan_result.len; + parsed_len += scan_result.len; + if (parsed_len >= buf_len) { + printf("parsed=%d, total = %d\n", parsed_len, buf_len); + break; + } + + } + + +sc_connect_wifi_success: + printf("%s success\n", __FUNCTION__); + return ret; + +sc_connect_wifi_fail: + printf("%s fail\n", __FUNCTION__); + return ret; + + +} + + +/* + + When BSSID_CHECK_SUPPORT is not set, there will be problems: + + 1.AP1 and AP2 (different SSID) both forward simple config packets, + profile is from AP2, but Ameba connect with AP1 + 2.AP1 and AP2 (same SSID, but different crypto or password), both forward simple config packets, + profile is from AP2, but Ameba connect with AP1 + 3. ... + + fix: using SSID to query matched BSSID(s) in scan result, traverse and connect. + + + Consideration: + 1.Only take ssid and password + 2.Assume they have different channel. + 3.Assume they have different encrypt methods + +*/ +int SC_connect_to_candidate_AP (rtw_network_info_t *wifi){ + + int ret; + + scan_buf_arg scan_buf; + int scan_cnt = 0; + char *ssid = (char*)wifi->ssid.val; + int ssid_len = wifi->ssid.len; + + + printf("Connect with SSID=%s password=%s\n", wifi->ssid.val, wifi->password); + + /* scan buf init */ + scan_buf.buf_len = 1000; + scan_buf.buf = (char*)pvPortMalloc(scan_buf.buf_len); + if(!scan_buf.buf){ + printf("ERROR: Can't malloc memory\n"); + return RTW_NOMEM; + } + + /* set ssid_len, ssid to scan buf */ + memset(scan_buf.buf, 0, scan_buf.buf_len); + if(ssid && ssid_len > 0 && ssid_len <= 32){ + memcpy(scan_buf.buf, &ssid_len, sizeof(int)); + memcpy(scan_buf.buf+sizeof(int), ssid, ssid_len); + } + + /* call wifi scan to scan */ + if(scan_cnt = (wifi_scan(RTW_SCAN_TYPE_ACTIVE, RTW_BSS_TYPE_ANY, &scan_buf)) < 0){ + printf("ERROR: wifi scan failed\n"); + ret = RTW_ERROR; + }else{ + ret = SC_parse_scan_result_and_connect(&scan_buf, wifi); + } + + if(scan_buf.buf) + vPortFree(scan_buf.buf); + + return ret; +} + + + + +rtw_security_t SC_translate_security(u8 security_type) +{ + + rtw_security_t security_mode = RTW_SECURITY_UNKNOWN; + + switch (security_type) { + case RTW_ENCRYPTION_OPEN: + security_mode = RTW_SECURITY_OPEN; + break; + case RTW_ENCRYPTION_WEP40: + case RTW_ENCRYPTION_WEP104: + security_mode = RTW_SECURITY_WEP_PSK; + break; + case RTW_ENCRYPTION_WPA_TKIP: + case RTW_ENCRYPTION_WPA_AES: + case RTW_ENCRYPTION_WPA2_TKIP: + case RTW_ENCRYPTION_WPA2_AES: + case RTW_ENCRYPTION_WPA2_MIXED: + security_mode = RTW_SECURITY_WPA2_AES_PSK; + break; + case RTW_ENCRYPTION_UNKNOWN: + case RTW_ENCRYPTION_UNDEF: + default: + printf( "unknow security mode,connect fail\n"); + } + + return security_mode; + +} + + +enum sc_result SC_connect_to_AP(void) +{ + enum sc_result ret = SC_ERROR; + u8 scan_channel; + u8 pscan_config; + int max_retry = 5, retry = 0; + rtw_security_t security_mode; + rtw_network_info_t wifi = {0}; + if(!(fixed_channel_num == 0)){ + scan_channel = fixed_channel_num; + } + pscan_config = PSCAN_ENABLE | PSCAN_SIMPLE_CONFIG; + + security_mode = SC_translate_security(g_security_mode); + g_security_mode = 0xff;//clear it + + if (-1 == get_connection_info_from_profile(security_mode, &wifi)) { + ret = SC_CONTROLLER_INFO_PARSE_FAIL; + goto wifi_connect_fail; + } + +#if CONFIG_AUTO_RECONNECT + /* disable auto reconnect */ + wifi_set_autoreconnect(0); +#endif + +#if 1 + /* optimization: get g_bssid to connect with only pscan */ + while (1) { + if(wifi_set_pscan_chan(&scan_channel, &pscan_config, 1) < 0){ + printf("ERROR: wifi set partial scan channel fail\n"); + ret = SC_TARGET_CHANNEL_SCAN_FAIL; + goto wifi_connect_fail; + } + rtw_join_status = 0;//clear simple config status + ret = wifi_connect(g_bssid, + 1, + (char*)wifi.ssid.val, + wifi.security_type, + (char*)wifi.password, + wifi.key_id, + NULL); + + if (ret == RTW_SUCCESS) + goto wifi_connect_success; + + if (retry == max_retry) { + printf("connect fail with bssid, try ssid instead\n"); + break; + } + retry ++; + } +#endif + +#if 1 + /* when optimization fail: if connect with bssid fail because of we have connect to the wrong AP */ + ret = SC_connect_to_candidate_AP(&wifi); + if (RTW_SUCCESS == ret) { + goto wifi_connect_success; + } else { + ret = SC_JOIN_BSS_FAIL; + goto wifi_connect_fail; + } +#endif + + +wifi_connect_success: + ret = SC_check_and_show_connection_info(); + goto wifi_connect_end; + + +wifi_connect_fail: + printf("SC_connect_to_AP failed\n"); + goto wifi_connect_end; + +wifi_connect_end: +#if CONFIG_AUTO_RECONNECT + wifi_config_autoreconnect(1, 10, 5); +#endif + return ret; + + +} +/* Make callback one by one to wlan rx when promiscuous mode */ + +void simple_config_callback(unsigned char *buf, unsigned int len, void* userdata) +{ + unsigned char * da = buf; + unsigned char * sa = buf + ETH_ALEN; + taskENTER_CRITICAL(); + if (is_promisc_callback_unlock == 1) { + simple_config_result = rtk_start_parse_packet(da, sa, len, userdata, (void *)backup_sc_ctx); + //printf("\r\nresult in callback function = %d\n",simple_config_result); + } + taskEXIT_CRITICAL(); + +} + +static unsigned int simple_config_cmd_start_time; +static unsigned int simple_config_cmd_current_time; +extern int simple_config_status; +extern void rtk_restart_simple_config(void); + + +extern void rtk_sc_deinit(void); + +void init_simple_config_lib_config(struct simple_config_lib_config* config) +{ + config->free = rtw_mfree; + config->malloc = rtw_malloc; + config->memcmp = memcmp; + config->memcpy = memcpy; + config->memset = memset; + config->printf = printf; + config->strcpy = strcpy; + config->strlen = strlen; + config->zmalloc = rtw_zmalloc; +#if CONFIG_LWIP_LAYER + config->_ntohl = lwip_ntohl; +#else + config->_ntohl = _ntohl; +#endif + config->is_promisc_callback_unlock = &is_promisc_callback_unlock; +} + + +int init_test_data(char *custom_pin_code) +{ +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + is_promisc_callback_unlock = 1; + is_fixed_channel = 0; + fixed_channel_num = 0; + simple_config_result = 0; + rtw_memset(g_ssid, 0, 32); + g_ssid_len = 0; + simple_config_cmd_start_time = xTaskGetTickCount(); + + if (ack_content != NULL) { + vPortFree(ack_content); + ack_content = NULL; + } + ack_content = pvPortMalloc(sizeof(struct ack_msg)); + if (!ack_content) { + printf("rtk_sc_init fail by allocate ack\n"); + } + memset(ack_content, 0, sizeof(struct ack_msg)); + +#ifdef SC_SCAN_SUPPORT + if(custom_pin_code) + pin_enable = 1; + else + pin_enable = 0; +#endif + + backup_sc_ctx = pvPortMalloc(sizeof(struct rtk_test_sc)); + if (!backup_sc_ctx) { + printf("[Mem]malloc SC context fail\n"); + } else { + memset(backup_sc_ctx, 0, sizeof(struct rtk_test_sc)); + struct simple_config_lib_config lib_config; + init_simple_config_lib_config(&lib_config); + //custom_pin_code can be null + if (rtk_sc_init(custom_pin_code, &lib_config) < 0) { + printf("Rtk_sc_init fail\n"); + } else { + return 0; + } + } + +#else + printf("Platform no include simple config now\n"); +#endif + return -1; +} + +void deinit_test_data(){ +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + rtk_sc_deinit(); + if (backup_sc_ctx != NULL) { + vPortFree(backup_sc_ctx); + backup_sc_ctx = NULL; + } + if (ack_content != NULL) { + vPortFree(ack_content); + ack_content = NULL; + } + rtw_join_status = 0;//clear simple config status +#endif +} + +void stop_simple_config() +{ + simple_config_terminate = 1; +} + +enum sc_result simple_config_test(rtw_network_info_t *wifi) +{ + int channel = 1; + enum sc_result ret = SC_SUCCESS; + unsigned int start_time; + int is_need_connect_to_AP = 0; + int fix_channel = 0; + int delta_time = 0; + wifi_set_promisc(RTW_PROMISC_ENABLE, simple_config_callback, 1); + start_time = xTaskGetTickCount(); + printf("\n"); + wifi_set_channel(channel); + while (simple_config_terminate != 1) { + vTaskDelay(50); //delay 0.5s to release CPU usage + simple_config_cmd_current_time = xTaskGetTickCount(); +#if CONFIG_GAGENT + if (simple_config_cmd_current_time - simple_config_cmd_start_time < ((50 + delta_time)*configTICK_RATE_HZ)) { +#else + if (simple_config_cmd_current_time - simple_config_cmd_start_time < ((120 + delta_time)*configTICK_RATE_HZ)) { +#endif + unsigned int current_time = xTaskGetTickCount(); + if (((current_time - start_time)*1000 /configTICK_RATE_HZ < 100) + || (is_fixed_channel == 1)) { + if(is_fixed_channel == 0 && get_channel_flag == 1){ + fix_channel = promisc_get_fixed_channel(g_bssid,g_ssid,&g_ssid_len); + if(fix_channel != 0) + { + printf("in simple_config_test fix channel = %d ssid: %s\n",fix_channel, g_ssid); + is_fixed_channel = 1; + fixed_channel_num = fix_channel; + wifi_set_channel(fix_channel); + } + else + printf("get channel fail\n"); + } + + if (simple_config_result == 1) { + is_need_connect_to_AP = 1; + is_fixed_channel = 0; + break; + } + if (simple_config_result == -1) { + printf("simple_config_test restart for result = -1\n"); + delta_time = 60; + wifi_set_channel(1); + is_need_connect_to_AP = 0; + is_fixed_channel = 0; + fixed_channel_num = 0; + memset(g_ssid, 0, 32); + g_ssid_len = 0; + simple_config_result = 0; + g_security_mode = 0xff; + rtk_restart_simple_config(); + } + if (simple_config_result == -2) { + printf("The APP or client must have pin!\n"); + break; + } + } else { + channel++; + if ((1 <= channel) && (channel <= 13)) { + if (wifi_set_channel(channel) == 0) { + start_time = xTaskGetTickCount(); + printf("Switch to channel(%d)\n", channel); + } + } else { + channel = 1; + if (wifi_set_channel(channel) == 0) { + start_time = xTaskGetTickCount(); + printf("Switch to channel(%d)\n", channel); + } + } + + } + } else { + ret = SC_NO_CONTROLLER_FOUND; + break; + } + } + wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0); + if (is_need_connect_to_AP == 1) { + if(NULL == wifi){ + int tmp_res = SC_connect_to_AP(); + if (SC_SUCCESS == tmp_res) { + if(-1 == SC_send_simple_config_ack(10)) + ret = SC_UDP_SOCKET_CREATE_FAIL; + #ifdef SC_SCAN_SUPPORT + // check whether the thread of listen scan command is already created + if(scan_start == 0) + { + scan_start = 1; + SC_listen_ACK_scan(); + } + #endif + } else { + ret = tmp_res; + } + }else{ + if (-1 == get_connection_info_from_profile(wifi->security_type,wifi)) { + ret = SC_CONTROLLER_INFO_PARSE_FAIL; + }else + ret = SC_SUCCESS; + } + }else{ + ret = SC_NO_CONTROLLER_FOUND; + } + return ret; +} + +//Filter packet da[] = {0x01, 0x00, 0x5e} +//add another filter for bcast, {0xff, 0xff, 0xff, 0xff} +#define MASK_SIZE 3 +void filter_add_enable(){ + u8 mask[MASK_SIZE]={0xFF,0xFF,0xFF}; + u8 pattern[MASK_SIZE]={0x01,0x00,0x5e}; + u8 pattern_bcast[MASK_SIZE]={0xff,0xff,0xff}; + + rtw_packet_filter_pattern_t packet_filter; + rtw_packet_filter_pattern_t packet_filter_bcast; + rtw_packet_filter_rule_e rule; + + packet_filter.offset = 0; + packet_filter.mask_size = 3; + packet_filter.mask = mask; + packet_filter.pattern = pattern; + + packet_filter_bcast.offset = 0; + packet_filter_bcast.mask_size = 3; + packet_filter_bcast.mask = mask; + packet_filter_bcast.pattern = pattern_bcast; + + rule = RTW_POSITIVE_MATCHING; + + wifi_init_packet_filter(); + wifi_add_packet_filter(1, &packet_filter,rule); + wifi_add_packet_filter(2, &packet_filter_bcast,rule); + + wifi_enable_packet_filter(1); + wifi_enable_packet_filter(2); +} + +void remove_filter(){ + wifi_disable_packet_filter(1); + wifi_disable_packet_filter(2); + wifi_remove_packet_filter(1); + wifi_remove_packet_filter(2); +} + +void print_simple_config_result(enum sc_result sc_code) +{ + printf("\n"); + switch (sc_code) { + case SC_NO_CONTROLLER_FOUND: + printf("Simple Config timeout! Can't get Ap profile. Please try again\n"); + break; + case SC_CONTROLLER_INFO_PARSE_FAIL: + printf("Simple Config fail, cannot parse target ap info from controller\n"); + break; + case SC_TARGET_CHANNEL_SCAN_FAIL: + printf("Simple Config cannot scan the target channel\n"); + break; + case SC_JOIN_BSS_FAIL: + printf("Simple Config Join bss failed\n"); + break; + case SC_DHCP_FAIL: + printf("Simple Config fail, cannot get dhcp ip address\n"); + break; + case SC_UDP_SOCKET_CREATE_FAIL: + printf("Simple Config Ack socket create fail!\n"); + break; + case SC_TERMINATE: + printf("Simple Config terminate\n"); + break; + case SC_SUCCESS: + printf("Simple Config success\n"); + break; + + case SC_ERROR: + default: + printf("unknown error when simple config!\n"); + + } +} + +#endif //CONFIG_INCLUDE_SIMPLE_CONFIG + +void cmd_simple_config(int argc, char **argv){ +#if CONFIG_INCLUDE_SIMPLE_CONFIG + char *custom_pin_code = NULL; + enum sc_result ret = SC_ERROR; + + if(argc > 2){ + printf("Input Error!\n"); + } + + if(argc == 2) + custom_pin_code = (argv[1]); + + simple_config_terminate = 0; + rtw_join_status |= JOIN_SIMPLE_CONFIG; + + wifi_enter_promisc_mode(); + if(init_test_data(custom_pin_code) == 0){ + filter_add_enable(); + ret = simple_config_test(NULL); + deinit_test_data(); + print_simple_config_result(ret); + remove_filter(); + } +#if CONFIG_INIC_CMD_RSP + if(ret != SC_SUCCESS) + inic_c2h_wifi_info("ATWQ", RTW_ERROR); +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD + if(ret == SC_SUCCESS){ + at_printf("\n\r[ATWQ] OK"); + }else{ + at_printf("\n\r[ATWQ] ERROR:%d",ret); + } +#endif + +#endif +} +#endif //#if CONFIG_WLAN + +#endif // LWIP_SOCKET + diff --git a/USDK/component/common/api/wifi/wifi_simple_config.h b/USDK/component/common/api/wifi/wifi_simple_config.h new file mode 100644 index 0000000..e77972c --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_simple_config.h @@ -0,0 +1,20 @@ +#ifndef __WIFI_SIMPLE_CONFIG_H +#define __WIFI_SIMPLE_CONFIG_H +/*****************************wifi_simple_config.h****************************/ +enum sc_result { + SC_ERROR = -1, /* default error code*/ + SC_NO_CONTROLLER_FOUND = 1, /* cannot get sta(controller) in the air which starts a simple config session */ + SC_CONTROLLER_INFO_PARSE_FAIL, /* cannot parse the sta's info */ + SC_TARGET_CHANNEL_SCAN_FAIL, /* cannot scan the target channel */ + SC_JOIN_BSS_FAIL, /* fail to connect to target ap */ + SC_DHCP_FAIL, /* fail to get ip address from target ap */ + /* fail to create udp socket to send info to controller. note that client isolation + must be turned off in ap. we cannot know if ap has configured this */ + SC_UDP_SOCKET_CREATE_FAIL, + SC_TERMINATE, + SC_SUCCESS, /* default success code */ + +}; +int SC_send_simple_config_ack(u8 round); + +#endif //__WIFI_SIMPLE_CONFIG_H diff --git a/USDK/component/common/api/wifi/wifi_simple_config_parser.h b/USDK/component/common/api/wifi/wifi_simple_config_parser.h new file mode 100644 index 0000000..330ecdb --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_simple_config_parser.h @@ -0,0 +1,99 @@ +#ifndef __SIMPLE_CONFIG_H__ +#define __SIMPLE_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + /* This macro means user take simple config + * lib to another platform such as linux, and + * have no rom crypto libs of simple config, + * so we take simple_config_crypto as a sw lib + * This macro is used by Realtek internal to generate simple config lib + * Please delete this macro after generation. + */ +#define SIMPLE_CONFIG_PLATFORM_LIB 0 + +#include "platform_opts.h" +#include "autoconf.h" + + + +/* platform related settings */ +#if (defined(CONFIG_PLATFORM_8195A)|| defined(CONFIG_PLATFORM_8711B)) +#undef u32 +#undef s32 +#undef u8 +#undef s8 +#undef u16 +#undef s16 +typedef unsigned int u32; +typedef signed int s32; +typedef unsigned char u8; +typedef char s8; +typedef unsigned short int u16; +typedef signed short int s16; +#else +#include "osdep_service.h" +#endif + +typedef int (*simple_config_printf_fn) (char const * fmt, ...); +typedef void* (*simple_config_memset_fn) (u8 *dst0, s32 Val, u32 length); +typedef void* (*simple_config_memcpy_fn) ( void *s1, const void *s2, u32 n ); +typedef u32 (*simple_config_strlen_fn) (const char *s); +typedef char * (*simple_config_strcpy_fn) (char *dest, const char *src); +typedef void (*simple_config_free_fn) (u8 *pbuf, u32 sz); +typedef u8* (*simple_config_zmalloc_fn) (u32 sz); +typedef u8* (*simple_config_malloc_fn) (u32 sz); +typedef int (*simple_config_memcmp_fn) (const void *av, const void *bv, u32 len); +typedef u32 (*simple_config_ntohl_fn)(u32 x); + + + +struct simple_config_lib_config { + simple_config_printf_fn printf; + simple_config_memset_fn memset; + simple_config_memcpy_fn memcpy; + simple_config_strlen_fn strlen; + simple_config_strcpy_fn strcpy; + simple_config_free_fn free; + simple_config_zmalloc_fn zmalloc; + simple_config_malloc_fn malloc; + simple_config_memcmp_fn memcmp; + simple_config_ntohl_fn _ntohl; + + + int *is_promisc_callback_unlock; + +}; + +#pragma pack(1) +struct rtk_test_sc { + /* API exposed to user */ + unsigned char ssid[32]; + unsigned char password[65]; + unsigned int ip_addr; +}; + +/* expose data */ +extern s32 is_promisc_callback_unlock; +extern u8 g_bssid[6]; +extern u8 get_channel_flag; +extern u8 g_security_mode; + +/* expose API */ +extern s32 rtk_sc_init(char *custom_pin_code, struct simple_config_lib_config* config); +extern s32 rtk_start_parse_packet(u8 *da, u8 *sa, s32 len, void * user_data, void *backup_sc); +extern void rtk_restart_simple_config(void); +extern void rtk_sc_deinit(); +extern void wifi_enter_promisc_mode(); +extern void whc_fix_channel(); +extern void whc_unfix_channel(); + + +#ifdef __cplusplus +} +#endif + +#endif /* __SIMPLE_CONFIG_H__*/ diff --git a/USDK/component/common/api/wifi/wifi_util.c b/USDK/component/common/api/wifi/wifi_util.c new file mode 100644 index 0000000..00b860a --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_util.c @@ -0,0 +1,1215 @@ +#include +#include +#include "FreeRTOS.h" +#include +#include +#include +#if 1 +#include "drv_types.h" // or #include "wlan_lib.h" +#else +#include "wifi_constants.h" +#include "wifi_structures.h" +#include "wlan_lib.h" // or #include "drv_types.h" +#endif +#include + +#define USE_WIFI_ADAPTER 1 // использовать прямое обращение в тело драйвера WiFi + +int iw_ioctl(const char * ifname, unsigned long request, struct iwreq * pwrq) { + memcpy(pwrq->ifr_name, ifname, 5); + int ret = rltk_wlan_control(request, (void *) pwrq); +#if CONFIG_DEBUG_LOG > 3 + debug_printf("ioctl[%p, '%s', %02x %02x %02x %02x ...] = %d\n", + request, ifname, pwrq->u.name[0], pwrq->u.name[1], + pwrq->u.name[2], pwrq->u.name[3], ret); +#endif +#if CONFIG_DEBUG_LOG > 4 + if (pwrq->u.data.length) { + extern void dump_bytes(uint32 addr, int size); + dump_bytes(pwrq->u.data.pointer, pwrq->u.data.length); + } +#endif + return ret; +} + +#ifdef USE_WIFI_ADAPTER +extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h +LOCAL _adapter * get_padapter(const char *ifname) { + if(ifname[4] == '0') { + return *(_adapter **)((rltk_wlan_info[0].dev)->priv); + } else { + return *(_adapter **)((rltk_wlan_info[1].dev)->priv); + } + return NULL; +}; +#endif + +/* ssid = NULL -> not connected */ +int wext_get_ssid(const char *ifname, __u8 *ssid) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad != NULL && (pad->mlmepriv.fw_state & 0x41) != 0) { + int len = pad->mlmepriv.cur_network.network.Ssid.SsidLength; + if(len > 32) rtw_memcpy(ssid, pad->mlmepriv.cur_network.network.Ssid.Ssid, 32); + else { + rtw_memcpy(ssid, &pad->mlmepriv.cur_network.network.Ssid.Ssid, len); + ssid[len] = '\0'; + debug_printf("s=[%s]\n", ssid); + } + ret = RTW_SUCCESS; + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.essid.pointer = ssid; + iwr.u.essid.length = 32; + int ret = iw_ioctl(ifname, SIOCGIWESSID, &iwr); + if (ret >= 0) { + ret = iwr.u.essid.length; + if (ret > 32) + ret = 32; + /* Some drivers include nul termination in the SSID, so let's + * remove it here before further processing. WE-21 changes this + * to explicitly require the length _not_ to include nul + * termination. */ + if (ret > 0 && ssid[ret - 1] == '\0') + ret--; + ssid[ret] = '\0'; + } + return ret; +#endif +} + +int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.essid.pointer = (void *) ssid; + iwr.u.essid.length = ssid_len; + iwr.u.essid.flags = (ssid_len != 0); + return iw_ioctl(ifname, SIOCSIWESSID, &iwr); +} + +int wext_set_bssid(const char *ifname, const __u8 *bssid) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwr.u.ap_addr.sa_data, bssid, ETH_ALEN); + if (bssid[ETH_ALEN] == '#' && bssid[ETH_ALEN + 1] == '@') { + memcpy(iwr.u.ap_addr.sa_data + ETH_ALEN, bssid + ETH_ALEN, 6); + } + return iw_ioctl(ifname, SIOCSIWAP, &iwr); +} + +int is_broadcast_ether_addr(const unsigned char *addr) { + return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff; +} + +int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.param.flags = idx & IW_AUTH_INDEX; + iwr.u.param.value = value; + return iw_ioctl(ifname, SIOCSIWAUTH, &iwr); +} + +int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, + int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, + __u16 key_len) { + struct iwreq iwr; + int ret = -1; + struct iw_encode_ext *ext; + + ext = (struct iw_encode_ext *) pvPortMalloc( + sizeof(struct iw_encode_ext) + key_len); + if (ext != NULL) { + memset(ext, 0, sizeof(struct iw_encode_ext) + key_len); + memset(&iwr, 0, sizeof(iwr)); + iwr.u.encoding.flags = key_idx + 1; + iwr.u.encoding.flags |= IW_ENCODE_TEMP; + iwr.u.encoding.pointer = ext; + iwr.u.encoding.length = sizeof(struct iw_encode_ext) + key_len; + if (alg == IW_ENCODE_DISABLED) + iwr.u.encoding.flags |= IW_ENCODE_DISABLED; + if (addr == NULL || is_broadcast_ether_addr(addr)) + ext->ext_flags |= IW_ENCODE_EXT_GROUP_KEY; + if (set_tx) + ext->ext_flags |= IW_ENCODE_EXT_SET_TX_KEY; + ext->addr.sa_family = ARPHRD_ETHER; + if (addr) + memcpy(ext->addr.sa_data, addr, ETH_ALEN); + else + memset(ext->addr.sa_data, 0xff, ETH_ALEN); + if (key && key_len) { + memcpy(ext->key, key, key_len); + ext->key_len = key_len; + } + ext->alg = alg; + if (seq && seq_len) { + ext->ext_flags |= IW_ENCODE_EXT_RX_SEQ_VALID; + memcpy(ext->rx_seq, seq, seq_len); + } + ret = iw_ioctl(ifname, SIOCSIWENCODEEXT, &iwr); + vPortFree(ext); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +int wext_get_enc_ext(const char *ifname, __u16 *alg, __u8 *key_idx, + __u8 *passphrase) { + struct iwreq iwr; + int ret = -1; + struct iw_encode_ext *ext; + + ext = (struct iw_encode_ext *) pvPortMalloc( + sizeof(struct iw_encode_ext) + 16); + if (ext != NULL) { + memset(ext, 0, sizeof(struct iw_encode_ext) + 16); + iwr.u.encoding.pointer = ext; + ret = iw_ioctl(ifname, SIOCGIWENCODEEXT, &iwr); + if (ret >= 0) { + *alg = ext->alg; + if (key_idx) + *key_idx = (__u8 ) iwr.u.encoding.flags; + if (passphrase) + memcpy(passphrase, ext->key, ext->key_len); + } + vPortFree(ext); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +int wext_set_passphrase(const char *ifname, const __u8 *passphrase, + __u16 passphrase_len) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.passphrase.pointer = (void *) passphrase; + iwr.u.passphrase.length = passphrase_len; + iwr.u.passphrase.flags = (passphrase_len != 0); + return iw_ioctl(ifname, SIOCSIWPRIVPASSPHRASE, &iwr); +} + +int wext_get_passphrase(const char *ifname, __u8 *passphrase) { +#if USE_WIFI_ADAPTER + extern int rtw_wx_get_passphrase(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra); + struct net_device * pdev = rltk_wlan_info[0].dev; + if(ifname[4] != '0') + pdev = rltk_wlan_info[1].dev; + rtw_result_t ret = RTW_ERROR; + if(pdev) { + uint16 len[4]; + ret = rtw_wx_get_passphrase(pdev, 0, &len, passphrase); + if(ret == RTW_SUCCESS) passphrase[len[2]] = '\0'; + debug_printf("pas[%d]-<%s>\n", len[2], passphrase); + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.passphrase.pointer = (void *) passphrase; + int ret = iw_ioctl(ifname, SIOCGIWPRIVPASSPHRASE, &iwr); + if (ret >= 0) { + ret = iwr.u.passphrase.length; + passphrase[ret] = '\0'; + } + return ret; +#endif +} + +#if 0 +int wext_set_mac_address(const char *ifname, char * mac) +{ + char buf[13+17+1]; + memset(buf, 0, sizeof(buf)); + snprintf(buf, 13+17, "write_mac %s", mac); + return wext_private_command(ifname, buf, 0); +} + +int wext_get_mac_address(const char *ifname, char * mac) +{ + int ret = 0; + char buf[32]; + + memset(buf, 0, sizeof(buf)); + memcpy(buf, "read_mac", 8); + ret = wext_private_command_with_retval(ifname, buf, buf, 32); + strcpy(mac, buf); + return ret; +} +#endif + +int wext_enable_powersave(const char *ifname, __u8 ips_mode, __u8 lps_mode) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + ret = rtw_pm_set_ips(pad, ips_mode); // 2 режима 1,2 ! + if(ret == RTW_SUCCESS) { + LeaveAllPowerSaveMode(pad); + ret = rtw_pm_set_lps(pad, lps_mode); + } + } + return ret; +#else + struct iwreq iwr; + __u16 pindex = 7; + __u8 para[16]; // 7 + (1+1+1) + (1+1+1) + int cmd_len = sizeof("pm_set"); + memset(&iwr, 0, sizeof(iwr)); + // Encode parameters as TLV (type, length, value) format + snprintf((char*) para, cmd_len, "pm_set"); + para[pindex++] = 0; // type 0 for ips + para[pindex++] = 1; + para[pindex++] = ips_mode; + para[pindex++] = 1; // type 1 for lps + para[pindex++] = 1; + para[pindex++] = lps_mode; + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = pindex; + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +#endif +} +/* +int wext_disable_powersave(const char *ifname) { + struct iwreq iwr; + __u16 pindex = 7; + __u8 para[16]; // 7 + (1+1+1) + (1+1+1) + int cmd_len = sizeof("pm_set"); + memset(&iwr, 0, sizeof(iwr)); + // Encode parameters as TLV (type, length, value) format + snprintf((char*) para, cmd_len, "pm_set"); + para[pindex++] = 0; // type 0 for ips + para[pindex++] = 1; + para[pindex++] = 0; // ips = 0 + para[pindex++] = 1; // type 1 for lps + para[pindex++] = 1; + para[pindex++] = 0; // lps = 0 + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = pindex; + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +} +*/ + +int wext_set_tdma_param(const char *ifname, __u8 slot_period, + __u8 rfon_period_len_1, __u8 rfon_period_len_2, __u8 rfon_period_len_3) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + ret = rtw_pm_set_tdma_param(pad, + slot_period, + rfon_period_len_1, + rfon_period_len_2, + rfon_period_len_3); + } + return ret; +#else + struct iwreq iwr; + int ret = -1; + __u16 pindex = 7; + __u8 para[16]; // 7+(1+1+4) + int cmd_len = sizeof("pm_set"); + memset(&iwr, 0, sizeof(iwr)); + // Encode parameters as TLV (type, length, value) format + snprintf((char*) para, cmd_len, "pm_set"); + para[pindex++] = 2; // type 2 tdma param + para[pindex++] = 4; + para[pindex++] = slot_period; + para[pindex++] = rfon_period_len_1; + para[pindex++] = rfon_period_len_2; + para[pindex++] = rfon_period_len_3; + iwr.u.data.pointer = para; + iwr.u.data.length = pindex; + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +#endif +} + +int wext_set_lps_dtim(const char *ifname, __u8 lps_dtim) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + ret = rtw_pm_set_lps_dtim(pad, lps_dtim); + } + return ret; +#else + struct iwreq iwr; + int ret = -1; + __u16 pindex = 7; + __u8 para[16]; // 7+(1+1+1) + int cmd_len = 0; + + memset(&iwr, 0, sizeof(iwr)); + cmd_len = sizeof("pm_set"); + // Encode parameters as TLV (type, length, value) format + snprintf((char*) para, cmd_len, "pm_set"); + para[pindex++] = 3; // type 3 lps dtim + para[pindex++] = 1; + para[pindex++] = lps_dtim; + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = pindex; + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + return ret; +#endif +} + +int wext_get_lps_dtim(const char *ifname, __u8 *lps_dtim) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + *lps_dtim = rtw_pm_get_lps_dtim(pad); + ret = RTW_SUCCESS; + } + return ret; +#else + struct iwreq iwr; + int ret = -1; + __u16 pindex = 7; + int cmd_len = 0; + __u8 para[16]; // 7+(1+1+1) + memset(&iwr, 0, sizeof(iwr)); + cmd_len = sizeof("pm_get"); + // Encode parameters as TLV (type, length, value) format + snprintf((char*) para, cmd_len, "pm_get"); + para[pindex++] = 3; // type 3 for lps dtim + para[pindex++] = 1; + para[pindex++] = 0; + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = pindex; + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + //get result at the beginning of iwr.u.data.pointer + if ((para[0] == 3) && (para[1] == 1)) + *lps_dtim = para[2]; + else { +#if CONFIG_DEBUG_LOG > 3 + error_printf("%s: error!\n", __func__); +#endif + ret = -1; + } + return ret; +#endif +} + +int wext_set_tos_value(const char *ifname, __u8 *tos_value) { + struct iwreq iwr; + int ret = -1; + __u8 para[sizeof("set_tos_value") + 4]; + int cmd_len = sizeof("set_tos_value"); + memset(&iwr, 0, sizeof(iwr)); + snprintf((char*) para, cmd_len, "set_tos_value"); + if (*tos_value >= 0 && *tos_value <= 32) { + *(para + cmd_len) = 0x4f; + *(para + cmd_len + 1) = 0xa4; + *(para + cmd_len + 2) = 0; + *(para + cmd_len + 3) = 0; + } else if (*tos_value > 32 && *tos_value <= 96) { + *(para + cmd_len) = 0x2b; + *(para + cmd_len + 1) = 0xa4; + *(para + cmd_len + 2) = 0; + *(para + cmd_len + 3) = 0; + } else if (*tos_value > 96 && *tos_value <= 160) { + *(para + cmd_len) = 0x22; + *(para + cmd_len + 1) = 0x43; + *(para + cmd_len + 2) = 0x5e; + *(para + cmd_len + 3) = 0; + } else if (*tos_value > 160) { + *(para + cmd_len) = 0x22; + *(para + cmd_len + 1) = 0x32; + *(para + cmd_len + 2) = 0x2f; + *(para + cmd_len + 3) = 0; + } + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = cmd_len + 4; + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +} + +int wext_get_tx_power(const char *ifname, __u8 *poweridx) { + struct iwreq iwr; + int ret = -1; + __u8 *para; + int cmd_len = sizeof("get_tx_power"); + memset(&iwr, 0, sizeof(iwr)); + //Tx power size : 20 Bytes + //CCK 1M,2M,5.5M,11M : 4 Bytes + //OFDM 6M, 9M, 12M, 18M, 24M, 36M 48M, 54M : 8 Bytes + //MCS 0~7 : 8 Bytes + para = pvPortMalloc(cmd_len + 20); + if (para != NULL) { + snprintf((char*) para, cmd_len, "get_tx_power"); + iwr.u.data.pointer = para; + iwr.u.data.length = cmd_len + 20; + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + if (ret >= 0) + memcpy(poweridx, (__u8 *) (iwr.u.data.pointer), 20); + vPortFree(para); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +#if 0 // work ? +int wext_set_txpower(const char *ifname, int poweridx) { + int ret; + char buf[32]; + + memset(buf, 0, sizeof(buf)); +// snprintf(buf, 24, "txpower patha=%d", poweridx); + snprintf(buf, sizeof(buf), "txpower patha=%d,pathb=%d", poweridx, poweridx); + ret = wext_private_command(ifname, buf, 0); + + return ret; +} + +int wext_get_associated_client_list(const char *ifname, + void * client_list_buffer, uint16_t buffer_length) { + int ret; + char buf[25]; + + memset(buf, 0, sizeof(buf)); + snprintf(buf, 25, "get_client_list %x", client_list_buffer); + ret = wext_private_command(ifname, buf, 0); + + return ret; +} + +int wext_get_ap_info(const char *ifname, rtw_bss_info_t * ap_info, + rtw_security_t* security) { + int ret = 0; + char buf[24]; + + memset(buf, 0, sizeof(buf)); + snprintf(buf, 24, "get_ap_info %x", ap_info); + ret = wext_private_command(ifname, buf, 0); + + snprintf(buf, 24, "get_security"); + ret = wext_private_command_with_retval(ifname, buf, buf, 24); + sscanf(buf, "%d", security); + + return ret; +} +#endif + +int wext_set_mode(const char *ifname, int mode) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + int nwm; + if(rtw_pwr_wakeup(pad) && pad->hw_init_completed) { + switch(mode) { + case IW_MODE_AUTO: + nwm = Ndis802_11AutoUnknown; + break; + case IW_MODE_MASTER: + nwm = Ndis802_11APMode; + break; + case IW_MODE_INFRA: + nwm = Ndis802_11Infrastructure; + break; + case IW_MODE_ADHOC: + nwm = Ndis802_11IBSS; + break; + default: + return RTW_NORESOURCE; + } + if(rtw_set_802_11_infrastructure_mode(pad, nwm)) { + return set_opmode(pad, nwm); + } + } + return RTW_ERROR; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.mode = mode; + return iw_ioctl(ifname, SIOCSIWMODE, &iwr); +#endif +} + +int wext_get_mode(const char *ifname, int *mode) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + uint16 f = pad->mlmepriv.fw_state; + if(f & 8) *mode = 2; + else if(f & 0x60) *mode = 1; + else if(!(f & 0x10)) *mode = 0; + else *mode = 3; + ret = RTW_SUCCESS; + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + int ret = iw_ioctl(ifname, SIOCGIWMODE, &iwr); + if (ret >= 0) + *mode = iwr.u.mode; + return ret; +#endif +} + +int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len) { +#ifdef USE_WIFI_ADAPTER + struct net_device * pdev = rltk_wlan_info[0].dev; + if(ifname[4] != '0') + pdev = rltk_wlan_info[1].dev; + rtw_result_t ret = RTW_ERROR; + if(pdev) { + uint16 len[2]; + len[0] = ssid_len; + len[1] = (ssid_len != 0); + ret = rtw_wx_set_ap_essid(pdev, 0, &len, ssid); + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.essid.pointer = (void *) ssid; + iwr.u.essid.length = ssid_len; + iwr.u.essid.flags = (ssid_len != 0); + return iw_ioctl(ifname, SIOCSIWPRIVAPESSID, &iwr); +#endif +} + +int wext_set_country(const char *ifname, rtw_country_code_t country_code) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.param.value = country_code; + return iw_ioctl(ifname, SIOCSIWPRIVCOUNTRY, &iwr); +} + +int wext_get_rssi(const char *ifname, int *rssi) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + if(pad->mlmepriv.fw_state & 1) { + *rssi = pad->recvpriv.rssi; // +2932 + } + else *rssi = 0; + ret = RTW_SUCCESS; + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + int ret = iw_ioctl(ifname, SIOCGIWSENS, &iwr); + if (ret >= 0) + *rssi = 0 - iwr.u.sens.value; + return ret; +#endif +} + +int wext_set_pscan_channel(const char *ifname, + __u8 *ch, + __u8 *pscan_config, + __u8 length) { + struct iwreq iwr; + int ret = -1; + __u8 *para; + int i = 0; + memset(&iwr, 0, sizeof(iwr)); + //Format of para:function_name num_channel chan1... pscan_config1 ... + para = pvPortMalloc((length + length + 1) + 12); //size:num_chan + num_time + length + function_name + if (para != NULL) { + //Cmd + snprintf((char*) para, 12, "PartialScan"); + //length + *(para + 12) = length; + for (i = 0; i < length; i++) { + *(para + 13 + i) = *(ch + i); + *((__u16 *) (para + 13 + length + i)) = *(pscan_config + i); + } + + iwr.u.data.pointer = para; + iwr.u.data.length = (length + length + 1) + 12; + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + vPortFree(para); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +//extern int rtw_wx_set_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); + +int wext_set_channel(const char *ifname, __u8 ch) { +#if 0 //def USE_WIFI_ADAPTER // link: undefined reference to `rtw_wx_set_freq' -> rtw_wx_set_freq.isra.10 + struct net_device * pdev = rltk_wlan_info[0].dev; + if(ifname[4] != '0') + pdev = rltk_wlan_info[1].dev; + rtw_result_t ret = RTW_ERROR; + if(pdev) { + ret = rtw_wx_set_freq(pdev, ch, NULL, NULL); + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.freq.m = 0; + iwr.u.freq.e = 0; + iwr.u.freq.i = ch; + return iw_ioctl(ifname, SIOCSIWFREQ, &iwr); +#endif +} + +int wext_get_channel(const char *ifname, __u8 *ch) { +#ifdef USE_WIFI_ADAPTER + _adapter * pad = get_padapter(ifname); + rtw_result_t ret = RTW_ERROR; + if(pad) { + if(pad->mlmepriv.fw_state & 1) { + *ch = pad->mlmepriv.cur_network.network.Configuration.DSConfig; + } + else { + *ch = pad->mlmeextpriv.cur_channel; + } + ret = RTW_SUCCESS; + } + return ret; +#else + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + int ret = iw_ioctl(ifname, SIOCGIWFREQ, &iwr); + if (ret >= 0) + *ch = iwr.u.freq.i; + return ret; +#endif +} + +int wext_register_multicast_address(const char *ifname, rtw_mac_t *mac) { + char buf[32]; + memset(buf, 0, sizeof(buf)); + snprintf(buf, 32, "reg_multicast "MAC_FMT, MAC_ARG(mac->octet)); + return wext_private_command(ifname, buf, 0); +} + +int wext_unregister_multicast_address(const char *ifname, rtw_mac_t *mac) { + char buf[36]; + memset(buf, 0, sizeof(buf)); + snprintf(buf, 35, "reg_multicast -d "MAC_FMT, MAC_ARG(mac->octet)); + return wext_private_command(ifname, buf, 0); +} + +int wext_set_scan(const char *ifname, char *buf, __u16 buf_len, __u16 flags) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); +#if 0 //for scan_with_ssid + if(buf) + memset(buf, 0, buf_len); +#endif + iwr.u.data.pointer = buf; + iwr.u.data.flags = flags; + iwr.u.data.length = buf_len; + return iw_ioctl(ifname, SIOCSIWSCAN, &iwr); +} + +int wext_get_scan(const char *ifname, char *buf, __u16 buf_len) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_len; + int ret = iw_ioctl(ifname, SIOCGIWSCAN, &iwr); + if (ret >= 0) + ret = iwr.u.data.flags; + return ret; +} + +int wext_private_command_with_retval(const char *ifname, char *cmd, + char *ret_buf, int ret_len) { + struct iwreq iwr; + int ret = -1, buf_size; + char *buf; + + buf_size = 128; + + if (strlen(cmd) >= buf_size) + buf_size = strlen(cmd) + 1; // 1 : '\0' + buf = (char*) pvPortMalloc(buf_size); + if (buf != NULL) { + memset(buf, 0, buf_size); + strcpy(buf, cmd); + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_size; + iwr.u.data.flags = 0; + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + if (ret >= 0 & ret_buf != NULL) { + if (ret_len > iwr.u.data.length) + ret_len = iwr.u.data.length; + memcpy(ret_buf, (char *) iwr.u.data.pointer, ret_len); + } + vPortFree(buf); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +int wext_private_command(const char *ifname, char *cmd, int show_msg) { + struct iwreq iwr; + int ret = -1, buf_size; + char *buf; + + u8 cmdname[17] = { 0 }; // IFNAMSIZ+1 + + sscanf(cmd, "%16s", cmdname); + if ((strcmp((const char *)cmdname, "config_get") == 0) + || (strcmp((const char *)cmdname, "config_set") == 0) + || (strcmp((const char *)cmdname, "efuse_get") == 0) + || (strcmp((const char *)cmdname, "efuse_set") == 0) + || (strcmp((const char *)cmdname, "mp_psd") == 0)) + buf_size = 2600; //2600 for config_get rmap,0,512 (or realmap) + else + buf_size = 512; + + if (strlen(cmd) >= buf_size) + buf_size = strlen(cmd) + 1; // 1 : '\0' + buf = (char*) pvPortMalloc(buf_size); + if (buf != NULL) { + memset(buf, 0, buf_size); + strcpy(buf, cmd); + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_size; + iwr.u.data.flags = 0; + + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + if (ret >= 0 && show_msg && iwr.u.data.length) { +#if CONFIG_DEBUG_LOG > 3 + if (iwr.u.data.length > buf_size) { + error_printf("%s: Can't malloc memory!\n", __func__); + } + info_printf("Private Message: %s\n", (char * ) iwr.u.data.pointer); +#endif + } + vPortFree(buf); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra) { + unsigned char null_mac[6] = { 0 }; + + switch (cmd) { + case SIOCGIWAP: + if (wrqu->ap_addr.sa_family == ARPHRD_ETHER) { + if (!memcmp(wrqu->ap_addr.sa_data, null_mac, sizeof(null_mac))) + wifi_indication(WIFI_EVENT_DISCONNECT, NULL, 0, 0); + else + wifi_indication(WIFI_EVENT_CONNECT, wrqu->ap_addr.sa_data, + sizeof(null_mac), 0); + } + break; + + case IWEVCUSTOM: + if (extra) { +#if CONFIG_DEBUG_LOG > 4 + info_printf("IWEVCUSTOM '%s'\n", extra); +#endif + if (!memcmp(IW_EXT_STR_FOURWAY_DONE, extra, + strlen(IW_EXT_STR_FOURWAY_DONE))) + wifi_indication(WIFI_EVENT_FOURWAY_HANDSHAKE_DONE, extra, + strlen(IW_EXT_STR_FOURWAY_DONE), 0); + else if (!memcmp(IW_EXT_STR_RECONNECTION_FAIL, extra, + strlen(IW_EXT_STR_RECONNECTION_FAIL))) + wifi_indication(WIFI_EVENT_RECONNECTION_FAIL, extra, + strlen(IW_EXT_STR_RECONNECTION_FAIL), 0); + else if (!memcmp(IW_EVT_STR_NO_NETWORK, extra, + strlen(IW_EVT_STR_NO_NETWORK))) + wifi_indication(WIFI_EVENT_NO_NETWORK, extra, + strlen(IW_EVT_STR_NO_NETWORK), 0); +#if CONFIG_ENABLE_P2P || defined(CONFIG_AP_MODE) + else if (!memcmp(IW_EVT_STR_STA_ASSOC, extra, + strlen(IW_EVT_STR_STA_ASSOC))) + wifi_indication(WIFI_EVENT_STA_ASSOC, wrqu->data.pointer, + wrqu->data.length, 0); + else if (!memcmp(IW_EVT_STR_STA_DISASSOC, extra, + strlen(IW_EVT_STR_STA_DISASSOC))) + wifi_indication(WIFI_EVENT_STA_DISASSOC, wrqu->addr.sa_data, + sizeof(null_mac), 0); + else if (!memcmp(IW_EVT_STR_SEND_ACTION_DONE, extra, + strlen(IW_EVT_STR_SEND_ACTION_DONE))) + wifi_indication(WIFI_EVENT_SEND_ACTION_DONE, NULL, 0, + wrqu->data.flags); +#endif + } + break; + case SIOCGIWSCAN: + if (wrqu->data.pointer == NULL) + wifi_indication(WIFI_EVENT_SCAN_DONE, NULL, 0, 0); + else + wifi_indication(WIFI_EVENT_SCAN_RESULT_REPORT, wrqu->data.pointer, + wrqu->data.length, 0); + break; +#if CONFIG_ENABLE_P2P + case IWEVMGNTRECV: + wifi_indication(WIFI_EVENT_RX_MGNT, wrqu->data.pointer, + wrqu->data.length, wrqu->data.flags); + break; +#endif +#ifdef REPORT_STA_EVENT + case IWEVREGISTERED: + if(wrqu->addr.sa_family == ARPHRD_ETHER) + wifi_indication(WIFI_EVENT_STA_ASSOC, wrqu->addr.sa_data, sizeof(null_mac), 0); + break; + case IWEVEXPIRED: + if(wrqu->addr.sa_family == ARPHRD_ETHER) + wifi_indication(WIFI_EVENT_STA_DISASSOC, wrqu->addr.sa_data, sizeof(null_mac), 0); + break; +#endif + default: +#if CONFIG_DEBUG_LOG > 4 + info_printf("\nwlan_indicate: %p!\n", cmd); +#endif + break; + } +} + +int wext_send_eapol(const char *ifname, char *buf, __u16 buf_len, __u16 flags) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_len; + iwr.u.data.flags = flags; + return iw_ioctl(ifname, SIOCSIWEAPOLSEND, &iwr); +} + +#if CONFIG_ENABLE_P2P +int wext_send_mgnt(const char *ifname, char *buf, __u16 buf_len, __u16 flags) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_len; + iwr.u.data.flags = flags; + return iw_ioctl(ifname, SIOCSIWMGNTSEND, &iwr); +} +#endif + +int wext_set_gen_ie(const char *ifname, char *buf, __u16 buf_len, __u16 flags) { + struct iwreq iwr; + memset(&iwr, 0, sizeof(iwr)); + iwr.u.data.pointer = buf; + iwr.u.data.length = buf_len; + iwr.u.data.flags = flags; + return iw_ioctl(ifname, SIOCSIWGENIE, &iwr); +} + +int wext_set_autoreconnect(const char *ifname, __u8 mode, __u8 retyr_times, + __u16 timeout) { + struct iwreq iwr; + int ret = 0; + __u8 para[sizeof("SetAutoRecnt") + 4]; + int cmd_len = sizeof("SetAutoRecnt"); + memset(&iwr, 0, sizeof(iwr)); + //Cmd + snprintf((char*) para, cmd_len, "SetAutoRecnt"); + //length + *(para + cmd_len) = mode; //para1 + *(para + cmd_len + 1) = retyr_times; //para2 + *(para + cmd_len + 2) = timeout; //para3 + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = sizeof(para); + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +} + +int wext_get_autoreconnect(const char *ifname, __u8 *mode) { + struct iwreq iwr; + __u8 para[sizeof("GetAutoRecnt") + 1]; + int cmd_len = sizeof("GetAutoRecnt"); + memset(&iwr, 0, sizeof(iwr)); + //Cmd + snprintf((char*) para, cmd_len, "GetAutoRecnt"); + //length + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = cmd_len; + int ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + if (ret >= 0) + *mode = *(__u8 *) (iwr.u.data.pointer); + return ret; +} + +int wext_get_drv_ability(const char *ifname, __u32 *ability) { + int ret = -1; + char * buf = (char *) pvPortMalloc(33); + if (buf != NULL) { + memset(buf, 0, 33); + snprintf(buf, 33, "get_drv_ability %x", ability); + ret = wext_private_command(ifname, buf, 0); + vPortFree(buf); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +#ifdef CONFIG_CUSTOM_IE +int wext_add_custom_ie(const char *ifname, void *cus_ie, int ie_num) { + struct iwreq iwr; + int ret = -1; + __u8 *para; + int cmd_len = sizeof("SetCusIE"); + if (ie_num <= 0 || !cus_ie) { +#if CONFIG_DEBUG_LOG > 3 + error_printf("%s: wrong parameter!\n", __func__); +#endif + } else { + memset(&iwr, 0, sizeof(iwr)); + para = pvPortMalloc((4) * 2 + cmd_len); //size:addr len+cmd_len + if (para != NULL) { + //Cmd + snprintf(para, cmd_len, "SetCusIE"); + //addr length + *(__u32 *) (para + cmd_len) = (__u32 ) cus_ie; //ie addr + //ie_num + *(__u32 *) (para + cmd_len + 4) = ie_num; //num of ie + + iwr.u.data.pointer = para; + iwr.u.data.length = (4) * 2 + cmd_len; // 2 input + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + vPortFree(para); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + } + return ret; +} + +int wext_update_custom_ie(const char *ifname, void * cus_ie, int ie_index) { + struct iwreq iwr; + int ret = -1; + __u8 *para = NULL; + int cmd_len = sizeof("UpdateIE"); + if (ie_index <= 0 || !cus_ie) { +#if CONFIG_DEBUG_LOG > 3 + error_printf("%s: wrong parameter!\n", __func__); +#endif + } else { + memset(&iwr, 0, sizeof(iwr)); + cmd_len = para = pvPortMalloc((4) * 2 + cmd_len); //size:addr len+cmd_len + if (para != NULL) { + //Cmd + snprintf(para, cmd_len, "UpdateIE"); + //addr length + *(__u32 *) (para + cmd_len) = (__u32 ) cus_ie; //ie addr + //ie_index + *(__u32 *) (para + cmd_len + 4) = ie_index; //num of ie + + iwr.u.data.pointer = para; + iwr.u.data.length = (4) * 2 + cmd_len; // 2 input + ret = iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); + vPortFree(para); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + } + return ret; +} + +int wext_del_custom_ie(const char *ifname) { + struct iwreq iwr; + __u8 para[sizeof("DelIE")]; + memset(&iwr, 0, sizeof(iwr)); + //Cmd + snprintf(para, sizeof("DelIE"), "DelIE"); + iwr.u.data.pointer = ¶[0]; + iwr.u.data.length = sizeof("DelIE"); + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +} + +#endif + +#ifdef CONFIG_AP_MODE +int wext_set_forwarding(const char *ifname, char flg) { + struct iwreq iwr; + __u8 para[sizeof("forwarding_set") + 1]; + int cmd_len = sizeof("forwarding_set"); + memset(&iwr, 0, sizeof(iwr)); + // forwarding_set 1 + snprintf((char *) para, cmd_len, "forwarding_set"); + *(para + cmd_len) = flg; + iwr.u.essid.pointer = para; + iwr.u.essid.length = cmd_len + 1; + return iw_ioctl(ifname, SIOCDEVPRIVATE, &iwr); +} + +int wext_enable_forwarding(const char *ifname) { + return wext_set_forwarding(ifname, '1'); +} + +int wext_disable_forwarding(const char *ifname) { + return wext_set_forwarding(ifname, '0'); +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +int wext_set_ch_deauth(const char *ifname, __u8 enable) { + char buf[16]; + memset(buf, 0, 16); + snprintf(buf, 16, "SetChDeauth %d", enable); + return wext_private_command(ifname, buf, 0); +} +#endif + +int wext_set_adaptivity(rtw_adaptivity_mode_t adaptivity_mode) { + extern u8 rtw_adaptivity_en; + extern u8 rtw_adaptivity_mode; + + switch (adaptivity_mode) { + case RTW_ADAPTIVITY_NORMAL: + rtw_adaptivity_en = 1; // enable adaptivity + rtw_adaptivity_mode = RTW_ADAPTIVITY_MODE_NORMAL; + break; + case RTW_ADAPTIVITY_CARRIER_SENSE: + rtw_adaptivity_en = 1; // enable adaptivity + rtw_adaptivity_mode = RTW_ADAPTIVITY_MODE_CARRIER_SENSE; + break; + case RTW_ADAPTIVITY_DISABLE: + default: + rtw_adaptivity_en = 0; //disable adaptivity + break; + } + return 0; +} + +int wext_set_adaptivity_th_l2h_ini(__u8 l2h_threshold) { + extern s8 rtw_adaptivity_th_l2h_ini; + rtw_adaptivity_th_l2h_ini = (__s8 ) l2h_threshold; + return 0; +} + +extern int rltk_get_auto_chl(const char *ifname, unsigned char *channel_set, + int channel_num); + +int wext_get_auto_chl(const char *ifname, unsigned char *channel_set, + unsigned char channel_num) { + int ret = -1; + int channel = 0; + wext_disable_powersave(ifname); + if ((channel = rltk_get_auto_chl(ifname, channel_set, channel_num)) != 0) + ret = channel; + wext_enable_powersave(ifname, 1, 1); + return ret; +} + +extern int rltk_set_sta_num(unsigned char ap_sta_num); + +int wext_set_sta_num(unsigned char ap_sta_num) { + return rltk_set_sta_num(ap_sta_num); +} + +extern int rltk_del_station(const char *ifname, unsigned char *hwaddr); + +int wext_del_station(const char *ifname, unsigned char* hwaddr) { + return rltk_del_station(ifname, hwaddr); +} + +extern struct list_head *mf_list_head; +int wext_init_mac_filter(void) { + int ret = -1; + if (mf_list_head == NULL) { + mf_list_head = malloc(sizeof(struct list_head)); + if (mf_list_head != NULL) { + INIT_LIST_HEAD(mf_list_head); + ret = 0; + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + } + return ret; +} + +int wext_deinit_mac_filter(void) { + int ret = -1; + if (mf_list_head != NULL) { + struct list_head *iterator; + rtw_mac_filter_list_t *item; + list_for_each(iterator, mf_list_head) + { + item = list_entry(iterator, rtw_mac_filter_list_t, node); + list_del(iterator); + free(item); + item = NULL; + iterator = mf_list_head; + } + free(mf_list_head); + mf_list_head = NULL; + ret = 0; + } + return ret; +} + +int wext_add_mac_filter(unsigned char* hwaddr) { + int ret = -1; + if (mf_list_head != NULL) { + rtw_mac_filter_list_t *mf_list_new; + mf_list_new = malloc(sizeof(rtw_mac_filter_list_t)); + if (mf_list_new != NULL) { + memcpy(mf_list_new->mac_addr, hwaddr, 6); + list_add(&(mf_list_new->node), mf_list_head); + ret = 0; + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + } + return ret; +} + +int wext_del_mac_filter(unsigned char* hwaddr) { + int ret = -1; + if (mf_list_head != NULL) { + struct list_head *iterator; + rtw_mac_filter_list_t *item; + list_for_each(iterator, mf_list_head) + { + item = list_entry(iterator, rtw_mac_filter_list_t, node); + if (memcmp(item->mac_addr, hwaddr, 6) == 0) { + list_del(iterator); + free(item); + item = NULL; + ret = 0; + } + } + } + return ret; +} diff --git a/USDK/component/common/api/wifi/wifi_util.h b/USDK/component/common/api/wifi/wifi_util.h new file mode 100644 index 0000000..b3c6602 --- /dev/null +++ b/USDK/component/common/api/wifi/wifi_util.h @@ -0,0 +1,76 @@ +#ifndef _UTIL_H +#define _UTIL_H + +#include +#include +#include +#include "wifi_structures.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int wext_get_ssid(const char *ifname, __u8 *ssid); +int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len); +int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value); +int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len); +int wext_get_enc_ext(const char *ifname, __u16 *alg, __u8 *key_idx, __u8 *passphrase); +int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len); +int wext_get_passphrase(const char *ifname, __u8 *passphrase); +int wext_set_mode(const char *ifname, int mode); +int wext_get_mode(const char *ifname, int *mode); +int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len); +int wext_set_country(const char *ifname, rtw_country_code_t country_code); +int wext_get_rssi(const char *ifname, int *rssi); +int wext_set_channel(const char *ifname, __u8 ch); +int wext_get_channel(const char *ifname, __u8 *ch); +int wext_register_multicast_address(const char *ifname, rtw_mac_t *mac); +int wext_unregister_multicast_address(const char *ifname, rtw_mac_t *mac); +int wext_set_scan(const char *ifname, char *buf, __u16 buf_len, __u16 flags); +int wext_get_scan(const char *ifname, char *buf, __u16 buf_len); +int wext_set_mac_address(const char *ifname, char * mac); +int wext_get_mac_address(const char *ifname, char * mac); +int wext_enable_powersave(const char *ifname, __u8 lps_mode, __u8 ips_mode); +int wext_disable_powersave(const char *ifname); +#define wext_disable_powersave(n) wext_enable_powersave(n, 0, 0) +int wext_set_tdma_param(const char *ifname, __u8 slot_period, __u8 rfon_period_len_1, __u8 rfon_period_len_2, __u8 rfon_period_len_3); +int wext_set_lps_dtim(const char *ifname, __u8 lps_dtim); +int wext_get_lps_dtim(const char *ifname, __u8 *lps_dtim); +int wext_get_tx_power(const char *ifname, __u8 *poweridx); +int wext_set_txpower(const char *ifname, int poweridx); +int wext_get_associated_client_list(const char *ifname, void * client_list_buffer, __u16 buffer_length); +int wext_get_ap_info(const char *ifname, rtw_bss_info_t * ap_info, rtw_security_t* security); +int wext_mp_command(const char *ifname, char *cmd, int show_msg); +int wext_private_command(const char *ifname, char *cmd, int show_msg); +int wext_private_command_with_retval(const char *ifname, char *cmd, char *ret_buf, int ret_len); +void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra); +int wext_set_pscan_channel(const char *ifname, __u8 *ch, __u8 *pscan_config, __u8 length); +int wext_set_autoreconnect(const char *ifname, __u8 mode, __u8 retyr_times, __u16 timeout); +int wext_get_autoreconnect(const char *ifname, __u8 *mode); +int wext_set_adaptivity(rtw_adaptivity_mode_t adaptivity_mode); +int wext_set_adaptivity_th_l2h_ini(__u8 l2h_threshold); +int wext_get_auto_chl(const char *ifname, unsigned char *channel_set, unsigned char channel_num); +int wext_set_sta_num(unsigned char ap_sta_num); +int wext_del_station(const char *ifname, unsigned char* hwaddr); +int wext_init_mac_filter(void); +int wext_deinit_mac_filter(void); +int wext_add_mac_filter(unsigned char* hwaddr); +int wext_del_mac_filter(unsigned char* hwaddr); +int wext_set_tos_value(const char *ifname, __u8 *tos_value); +#ifdef CONFIG_CUSTOM_IE +int wext_add_custom_ie(const char *ifname, void * cus_ie, int ie_num); +int wext_update_custom_ie(const char *ifname, void * cus_ie, int ie_index); +int wext_del_custom_ie(const char *ifname); +#endif + +#define wext_handshake_done rltk_wlan_handshake_done + +int wext_send_mgnt(const char *ifname, char *buf, __u16 buf_len, __u16 flags); +int wext_send_eapol(const char *ifname, char *buf, __u16 buf_len, __u16 flags); +int wext_set_gen_ie(const char *ifname, char *buf, __u16 buf_len, __u16 flags); + +#ifdef __cplusplus +} +#endif + +#endif /* _UTIL_H */ diff --git a/USDK/component/common/api/wifi_api.c b/USDK/component/common/api/wifi_api.c new file mode 100644 index 0000000..ca5909b --- /dev/null +++ b/USDK/component/common/api/wifi_api.c @@ -0,0 +1,863 @@ +/* + * wifi_api.c + * + * Created on: 01/11/2017 + * Author: pvvx + */ +#include +#include "rtl8195a.h" +#include "drv_types.h" +#include +#include "FreeRTOS.h" +#if 1 +#include "drv_types.h" // or #include "wlan_lib.h" +#else +#include "wifi_constants.h" +#include "wifi_structures.h" +//#include "wlan_lib.h" // or #include "drv_types.h" +#endif + + +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#error "Udnef CONFIG_EXAMPLE_WLAN_FAST_CONNECT!" +#endif +#ifndef USE_FLASH_EEP +#error "Define USE_FLASH_EEP!" +#endif + +#include "task.h" +#include +#include +#include "flash_api.h" +#include +#include "dhcp/dhcps.h" +#include "ethernetif.h" +#if CONFIG_ETHERNET +#include "ethernet_mii/ethernet_mii.h" +#endif + +#include "flash_eep.h" +#include "feep_config.h" + +#include "wifi_api.h" +#include "main.h" +#include "wifi_user_set.h" + +#if 0 +#undef debug_printf +#define debug_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#undef info_printf +#define info_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#undef warning_printf +#define warning_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#undef error_printf +#define error_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#endif + +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP +extern void cmd_ap_wps(int argc, char **argv); +extern int wpas_wps_dev_config(u8 *dev_addr, u8 bregistrar); +#endif //CONFIG_WPS_AP + +//========================================= +//--- Wlan Config Init------------------- +WIFI_CONFIG wifi_cfg = { + .mode = DEF_WIFI_MODE, // rtw_mode_t + .adaptivity = DEF_WIFI_ADAPTIVITY, // rtw_adaptivity_mode_t + .country_code = DEF_WIFI_COUNTRY,// rtw_country_code_t + .tx_pwr = DEF_WIFI_TX_PWR, // rtw_tx_pwr_percentage_t + .bgn = DEF_WIFI_BGN, // rtw_network_mode_t + .load_flg = DEF_LOAD_CFG, + .save_flg = DEF_SAVE_CFG +}; +//---- Interface 0 - wlan0 - AP - init --- +SOFTAP_CONFIG wifi_ap_cfg = { + .ssid = DEF_AP_SSID, + .password = DEF_AP_PASSWORD, + .security = DEF_AP_SECURITY, // RTW_SECURITY_WPA2_AES_PSK or RTW_SECURITY_OPEN + .beacon_interval = DEF_AP_BEACON, + .channel = DEF_AP_CHANNEL, + .ssid_hidden = 0, + .max_sta = DEF_WIFI_AP_STATIONS // Max number of STAs, should be 1..3, default is 3 +}; +DHCP_CONFIG wifi_ap_dhcp = { + .ip = DEF_AP_IP, + .mask = DEF_AP_MSK, + .gw = DEF_AP_GW, + .mode = 2 +}; +//---- Interface 1 - wlan1 - ST - init --- +STATION_CONFIG wifi_st_cfg = { + .ssid = DEF_ST_SSID, + .password = DEF_ST_PASSWORD, + .bssid = DEF_ST_BSSID, + .flg = DEF_ST_BSSID, + .security = DEF_ST_SECURITY, + .autoreconnect = DEF_ST_AUTORECONNECT, + .reconnect_pause = DEF_ST_RECONNECT_PAUSE, + .sleep = DEF_ST_SLEEP, + .dtim = DEF_ST_LPS_DTIM +}; +DHCP_CONFIG wifi_st_dhcp = { + .ip = DEF_ST_IP, + .mask = DEF_ST_MSK, + .gw = DEF_ST_GW, + .mode = 1 +}; + +unsigned char wifi_run_mode = RTW_MODE_NONE; // rtw_mode_t +unsigned char wifi_st_status; + +typedef int (*wlan_init_done_ptr)(void); +typedef int (*write_reconnect_ptr)(uint8_t *data, uint32_t len); +//Function +#if CONFIG_AUTO_RECONNECT +extern void (*p_wlan_autoreconnect_hdl)(rtw_security_t, char*, int, char*, int, int); +#endif +extern wlan_init_done_ptr p_wlan_init_done_callback; +//extern write_reconnect_ptr p_write_reconnect_ptr; +extern struct netif xnetif[NET_IF_NUM]; +extern uint8_t rtw_power_percentage_idx; +extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h + +#define PARM_RECONNECT 1 + +struct wifi_autoreconnect_param { +#if PARM_RECONNECT + rtw_security_t security_type; + int key_id; +#else + rtw_security_t security_type; + char *ssid; + int ssid_len; + char *password; + int password_len; + int key_id; +#endif +}; + +struct wifi_autoreconnect_param wifi_autoreconnect; + +typedef struct _feep_element { + uint16 id; + uint16 size; + void * obj; +} FEEP_ELEMENT, *PFEEP_ELEMENT; + +FEEP_ELEMENT feep_tab[] = { + { FEEP_ID_WIFI_AP_CFG, sizeof(wifi_ap_cfg), &wifi_ap_cfg }, // Bit0 BID_WIFI_AP_CFG + { FEEP_ID_WIFI_ST_CFG, sizeof(wifi_st_cfg), &wifi_st_cfg }, // Bit1 BID_WIFI_ST_CFG + { FEEP_ID_AP_DHCP_CFG, sizeof(wifi_ap_dhcp), &wifi_ap_dhcp }, // Bit2 BID_AP_DHCP_CFG + { FEEP_ID_ST_DHCP_CFG, sizeof(wifi_st_dhcp), &wifi_st_dhcp }, // Bit3 BID_ST_DHCP_CFG + { FEEP_ID_WIFI_CFG, sizeof(wifi_cfg), &wifi_cfg }, // Bit4 BID_WIFI_CFG + { FEEP_ID_AP_HOSTNAME, LWIP_NETIF_HOSTNAME_SIZE, &lwip_host_name[1] }, // Bit5 BID_AP_HOSTNAME + { FEEP_ID_ST_HOSTNAME, LWIP_NETIF_HOSTNAME_SIZE, &lwip_host_name[0] }, // Bit5 BID_ST_HOSTNAME + { 0, 0, NULL } +}; + +uint32 read_wifi_cfg(uint32 flg) +{ + uint32 ret = 0; + PFEEP_ELEMENT p = feep_tab; + for(int m = 1; m && p->id != 0; m <<= 1, p++) { + if((flg & m) + && flash_read_cfg(p->obj, p->id, p->size) < p->size) { + ret |= m; + }; + }; + return ret; +} + +uint32 write_wifi_cfg(uint32 flg) +{ + uint32 ret = 0; + PFEEP_ELEMENT p = feep_tab; + for(int m = 1; m && p->id != 0; m <<= 1, p++) { + if(flg & m) { + if(!flash_write_cfg(p->obj, p->id, p->size)) { + ret |= m; + }; + }; + }; + return ret; +} + +#if CONFIG_WLAN_CONNECT_CB +_WEAK void connect_start(void) +{ + info_printf("%s: Time at start %d ms.\n", __func__, xTaskGetTickCount()); +} + +_WEAK void connect_close(void) +{ + info_printf("%s: Time at start %d ms.\n", __func__, xTaskGetTickCount()); +} +#endif + +#ifdef NOT_USE_CALLS +LOCAL int wlan_init_done_callback(void) { + printf("WiFi Init after %d ms\n", xTaskGetTickCount()); + return 0; +} +#endif // #ifdef NOT_USE_CALLS + +//char wlan_st_name[] = WLAN0_NAME; +char wlan_st_name[] = WLAN0_NAME; +char wlan_ap_name[] = WLAN1_NAME; +char wlan_st_netifn = 0; +char wlan_ap_netifn = 1; + + +uint32 get_new_ip(void) +{ + if(!(wifi_cfg.mode ^ wifi_run_mode)) { + return current_netif->ip_addr.addr; + } else if(wifi_cfg.mode == RTW_MODE_AP) { + return wifi_ap_dhcp.ip; + } else if(wifi_st_dhcp.mode == 2) { + return wifi_st_dhcp.ip; + } + return 0; +} +uint8 * get_new_hostname(void) +{ + if(!(wifi_cfg.mode ^ wifi_run_mode)) { + return current_netif->hostname; + } else if(wifi_cfg.mode == RTW_MODE_AP) { + return lwip_host_name[1]; + }; + return lwip_host_name[0]; +} + +LOCAL uint8 chk_ap_netif_num(void) +{ + if (wifi_mode == RTW_MODE_AP) { + wlan_st_name[4] = '1'; + wlan_ap_name[4] = '0'; + wlan_st_netifn = 1; + wlan_ap_netifn = 0; + } + else { // if (wifi_mode == RTW_MODE_STA) { + wlan_st_name[4] = '0'; + wlan_ap_name[4] = '1'; + wlan_st_netifn = 0; + wlan_ap_netifn = 1; + } + return wlan_ap_netifn; +} + +extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h + +/*LOCAL _adapter * get_padapter(int num) { + if(rltk_wlan_info[num].enable) { + return *(_adapter **)((rltk_wlan_info[0].dev)->priv); + } + return NULL; +};*/ +#define get_padapter(num) (*(_adapter **)((rltk_wlan_info[num].dev)->priv)); + +LOCAL rtw_result_t _wext_set_lps_dtim(int adapter_num, uint8 lps_dtim ) { + _adapter * pad = get_padapter(adapter_num); + rtw_result_t ret = RTW_ERROR; + if(pad) { + ret = rtw_pm_set_lps_dtim(pad, lps_dtim); + } + return ret; +} + +LOCAL rtw_result_t _wext_enable_powersave(int adapter_num, uint8 ips_mode, uint8 lps_mode) { + _adapter * pad = get_padapter(adapter_num); + rtw_result_t ret = RTW_ERROR; + if(pad) { + ret = rtw_pm_set_ips(pad, ips_mode); // 2 режима 1,2 ! + if(ret == RTW_SUCCESS) { + LeaveAllPowerSaveMode(pad); + ret = rtw_pm_set_lps(pad, lps_mode); + } + } + return ret; +} + +LOCAL int _wext_cmp_ssid(int adapter_num, uint8 *ssid) +{ + _adapter * pad = get_padapter(adapter_num); + int ret = 0; + if((pad != NULL) && (pad->mlmepriv.fw_state & 0x41) != 0) { + int len = pad->mlmepriv.cur_network.network.Ssid.SsidLength; + if(len < 32) len++; + else len = 32; + ret = (rtl_memcmp(ssid, &pad->mlmepriv.cur_network.network.Ssid.Ssid, len) == 0); + debug_printf("%d s[%d]'%s'\n", pad->mlmepriv.fw_state, len, ssid); + } + return ret; +} + +#ifdef NOT_USE_CALLS + +LOCAL rtw_result_t _wext_get_mode(int adapter_num, int *mode) { + _adapter * pad = get_padapter(adapter_num); + rtw_result_t ret = RTW_ERROR; + if(pad) { + uint16 f = pad->mlmepriv.fw_state; + if(f & 8) *mode = 2; + else if(f & 0x60) *mode = 1; + else if(!(f & 0x10)) *mode = 0; + else *mode = 3; + ret = RTW_SUCCESS; + } + return ret; +} + +LOCAL rtw_result_t _wext_get_channel(int adapter_num, uint8 *ch) +{ + _adapter * pad = get_padapter(adapter_num); + rtw_result_t ret = RTW_ERROR; + if(pad) { + if(pad->mlmepriv.fw_state & 1) { + *ch = pad->mlmepriv.htpriv.ch_offset; + } + else { + *ch = pad->mlmeextpriv.cur_channel; + } + ret = RTW_SUCCESS; + } + return ret; +} + +#endif // #ifdef NOT_USE_CALLS + + +LOCAL rtw_result_t wifi_run_ap(void) { + rtw_result_t ret = RTW_NOTAP; + if( (wifi_mode == RTW_MODE_AP) || (wifi_mode == RTW_MODE_STA_AP) ){ + info_printf("Starting AP (%s, netif%d)...\n", wlan_ap_name, wlan_ap_netifn); +/* + netif_set_addr(&xnetif[WLAN_AP_NETIF_NUM], &wifi_ap_dhcp.ip, + &wifi_ap_dhcp.mask, &wifi_ap_dhcp.gw); +*/ + if(wext_set_sta_num(wifi_ap_cfg.max_sta) != 0) { // Max number of STAs, should be 1..3, default is 3 + error_printf("AP not set max connections %d!\n", wifi_ap_cfg.max_sta); + }; +#if defined(CONFIG_ENABLE_WPS_AP) && CONFIG_ENABLE_WPS_AP + // todo: ветка не доделана + wpas_wps_dev_config(xnetif[WLAN_AP_NETIF_NUM].hwaddr, 1); +#endif //CONFIG_WPS_AP + if(wifi_ap_cfg.channel == 0 || wifi_ap_cfg.channel > 14) { + wifi_ap_cfg.channel = 1; + } + ret = wifi_start_ap(wifi_ap_cfg.ssid, //char *ssid, + wifi_ap_cfg.security, //rtw_security_t ecurity_type, + wifi_ap_cfg.password, //char *password, + wifi_ap_cfg.channel, //int channel + wifi_ap_cfg.ssid_hidden); // +// wifi_run_mode |= RTW_MODE_AP; + if (ret != RTW_SUCCESS) { + error_printf("Error(%d): Start AP failed!\n\n", ret);; + } else { + int timeout = wifi_test_timeout_ms / wifi_test_timeout_step_ms; + while (1) { +#if 1 + if (_wext_cmp_ssid(WLAN_AP_NETIF_NUM, &wifi_ap_cfg.ssid )) { +#else + char essid[33]; + if ((wext_get_ssid(wlan_ap_name, (unsigned char *) essid) > 0) + &&(strcmp((const char * ) essid, (const char * )wifi_ap_cfg.ssid) == 0)) { +#endif +#ifdef CONFIG_DONT_CARE_TP + pnetiff->flags |= NETIF_FLAG_IPSWITCH; +#endif + if(wifi_ap_dhcp.mode) { +#if defined(DEF_AP_DHCP_START) && defined(DEF_AP_DHCP_STOP) + dhcps_ip4addr_pool_start = DEF_AP_DHCP_START; + dhcps_ip4addr_pool_end = DEF_AP_DHCP_STOP; +#endif + dhcps_init(&xnetif[WLAN_AP_NETIF_NUM]); + }; + info_printf("AP '%s' started after %d ms\n", + wifi_ap_cfg.ssid, xTaskGetTickCount()); + show_wifi_ap_ip(); + if(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG)) + write_wifi_cfg(wifi_cfg.save_flg & (BID_WIFI_AP_CFG | BID_AP_DHCP_CFG)); + ret = RTW_SUCCESS; +#if CONFIG_WLAN_CONNECT_CB + // extern void connect_start(void); + connect_start(); +#endif + break; + } + if (timeout == 0) { + error_printf("Start AP timeout!\n"); + ret = RTW_TIMEOUT; + break; + } + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + timeout--; + } + } + } + return ret; + +} + +LOCAL rtw_result_t StartStDHCPClient(void) +{ + debug_printf("Start DHCPClient...\n"); + int ret = RTW_SUCCESS; + struct netif * pnetif = &xnetif[WLAN_ST_NETIF_NUM]; + DHCP_CONFIG *p = (dhcp_cfg *)&wifi_st_dhcp; + unsigned char mode = p->mode; + if((mode == 3) // Auto fix + && p->ip != IP4ADDR(255,255,255,255) + && p->ip != IP4ADDR(0,0,0,0)) { + } + else mode = 1; // DHCP On + if(mode == 2) { // fixed ip + netif_set_addr(pnetif, (ip_addr_t *)&p->ip, (ip_addr_t *)&p->mask, (ip_addr_t *)&p->gw); + } + else if(mode) { + UBaseType_t savePriority = uxTaskPriorityGet(NULL); + /* If not rise priority, LwIP DHCP may timeout */ + vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 3); + /* Start DHCP Client */ + ret = LwIP_DHCP(WLAN_ST_NETIF_NUM, DHCP_START); + vTaskPrioritySet(NULL, savePriority); + if (ret == DHCP_ADDRESS_ASSIGNED) { + p->ip = pnetif->ip_addr.addr; + p->gw = pnetif->gw.addr; + p->mask = pnetif->netmask.addr; + if(p->mode == 3) { // Auto fix + p->mode = 2; // fixed ip + write_wifi_cfg(BID_ST_DHCP_CFG); + } + ret = RTW_SUCCESS; + } + else { + debug_printf("LwIP_DHCP ret=%d\n", ret); + ret = RTW_ERROR; + } + } + if(ret == RTW_SUCCESS) { + show_wifi_st_ip(); + wifi_st_status = WIFI_STA_CONNECTED; +#if CONFIG_WLAN_CONNECT_CB + // extern void connect_start(void); + connect_start(); +#endif + } + return ret; +} + +LOCAL void wifi_autoreconnect_thread_(void *param) { + int ret = RTW_ERROR; + struct wifi_autoreconnect_param *reconnect_param = + (struct wifi_autoreconnect_param *) param; + printf("auto reconnect ...\n"); + wifi_st_status = WIFI_STA_RECONNECT; + ret = wifi_connect( + wifi_st_cfg.bssid, + wifi_st_cfg.flg, +#if PARM_RECONNECT + wifi_st_cfg.ssid, + reconnect_param->security_type, + wifi_st_cfg.password, +#else + reconnect_param->ssid, + reconnect_param->security_type, + reconnect_param->password, +#endif + reconnect_param->key_id, + NULL); + if (ret == RTW_SUCCESS) { + if(wifi_cfg.save_flg & BID_WIFI_ST_CFG) + write_wifi_cfg(BID_WIFI_ST_CFG); + // Start DHCPClient + StartStDHCPClient(); + } + vTaskDelete(NULL); +} + +LOCAL void wifi_autoreconnect_hdl_(rtw_security_t security_type, char *ssid, + int ssid_len, char *password, int password_len, int key_id) { + wifi_autoreconnect.security_type = security_type; + wifi_autoreconnect.key_id = key_id; +#if PARM_RECONNECT==0 + wifi_autoreconnect.ssid = ssid; + wifi_autoreconnect.password = password; +#endif + _adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv); + if(ad->mlmeextpriv.reconnect_cnt == 255) { + ad->mlmeextpriv.reconnect_cnt = 0; + }; + xTaskCreate(wifi_autoreconnect_thread_, (const char * )"st_recon", 400, + &wifi_autoreconnect, tskIDLE_PRIORITY + 1, NULL); +} + +LOCAL void st_set_autoreconnect(uint8 mode, uint8 count, uint16 timeout) { + p_wlan_autoreconnect_hdl = wifi_autoreconnect_hdl_; + _adapter * ad = *(_adapter **)((rltk_wlan_info[0].dev)->priv); + ad->mlmeextpriv.reconnect_times = count; + ad->mlmeextpriv.reconnect_timeout = timeout; + ad->mlmeextpriv.reconnect_cnt = 0; + ad->mlmeextpriv.auto_reconnect = (mode != 0); +} + +LOCAL rtw_result_t wifi_run_st(void) { + rtw_result_t ret = RTW_SUCCESS; +// chk_ap_netif_num(); + if((wifi_mode == RTW_MODE_STA) || (wifi_mode == RTW_MODE_STA_AP)) { +#if CONFIG_AUTO_RECONNECT +// p_wlan_autoreconnect_hdl = NULL; + if (wifi_st_cfg.autoreconnect) { + st_set_autoreconnect(1, wifi_st_cfg.autoreconnect, wifi_st_cfg.reconnect_pause); + ret = wext_set_autoreconnect(WLAN0_NAME, 1, wifi_st_cfg.autoreconnect, wifi_st_cfg.reconnect_pause); + if (ret != RTW_SUCCESS) + warning_printf("ERROR: Operation failed! Error=%d\n", ret); + } +#endif + info_printf("Connected to AP (%s, netif%d)...\n", wlan_st_name, wlan_st_netifn); + ret = wifi_connect( + wifi_st_cfg.bssid, + wifi_st_cfg.flg, + wifi_st_cfg.ssid, + idx_to_rtw_security(wifi_st_cfg.security), + wifi_st_cfg.password, + -1, + NULL); + wifi_st_status = WIFI_STA_START; +// wifi_run_mode |= RTW_MODE_STA; + if (ret != RTW_SUCCESS) { + error_printf("%s: Operation failed! Error(%d)\n", __func__, ret); + } else { + if(wifi_cfg.save_flg & BID_WIFI_ST_CFG) + write_wifi_cfg(BID_WIFI_ST_CFG); + // Start DHCPClient + StartStDHCPClient(); + } + }; + return ret; +} + +LOCAL int _wifi_on(rtw_mode_t mode) { + int ret = 0; +/* + if (!((rltk_wlan_running(WLAN0_IDX) == 0) && (rltk_wlan_running(WLAN1_IDX) == 0))) { + warning_printf("WIFI is already running\n"); + return 0; + } +*/ + info_printf("Initializing WIFI...\n"); + + uint8 devnum = (mode == RTW_MODE_STA_AP); // flag = 1 -> 2 netif + wifi_mode = mode; + chk_ap_netif_num(); + + // set wifi mib + wext_set_adaptivity(wifi_cfg.adaptivity & 3); // rtw_adaptivity_mode_t + + ret = rltk_wlan_init(WLAN0_IDX, mode); // rtw_mode_t + + netif_set_up(&xnetif[0]); + if (ret < 0) return ret; + if(devnum) { + ret = rltk_wlan_init(WLAN1_IDX, mode); + if (ret < 0) return ret; + netif_set_up(&xnetif[1]); + } + else { + netif_set_down(&xnetif[1]); + } + + uint32 timeout = xTaskGetTickCount(); + rltk_wlan_start(WLAN0_IDX); + if(devnum) rltk_wlan_start(WLAN1_IDX); + while (1) { + if (rltk_wlan_running(WLAN0_IDX) + && rltk_wlan_running(devnum) ) { +#if CONFIG_DEBUG_LOG > 2 + printf("WIFI initialized (%d ms)\n", xTaskGetTickCount() - timeout); +#endif + break; + } + if(xTaskGetTickCount() - timeout > wifi_test_timeout_ms/portTICK_RATE_MS) { + error_printf("WIFI init timeout!\n"); + break; + } + vTaskDelay(wifi_test_timeout_step_ms / portTICK_RATE_MS); + } + return ret; +} + +extern int lwip_init_done; + +LOCAL void _LwIP_Init(void) +{ + if(!lwip_init_done) { + int idx; + debug_printf("LwIP Init (%d)\n", wifi_mode); + /* Create tcp_ip stack thread */ + tcpip_init( NULL, NULL ); + +// chk_ap_netif_num(); // Исполняется после _wifi_on() + for(idx = 0; idx < NET_IF_NUM; idx++) { + xnetif[idx].name[0] = 'r'; + xnetif[idx].name[1] = '0' + idx; + } + netif_add(&xnetif[WLAN_ST_NETIF_NUM], (struct netif *)&wifi_st_dhcp.ip, (struct netif *)&wifi_st_dhcp.mask, (struct netif *)&wifi_st_dhcp.gw, NULL, ðernetif_init, &tcpip_input); + netif_add(&xnetif[WLAN_AP_NETIF_NUM], (struct netif *)&wifi_ap_dhcp.ip, (struct netif *)&wifi_ap_dhcp.mask, (struct netif *)&wifi_ap_dhcp.gw, NULL, ðernetif_init, &tcpip_input); +#if CONFIG_ETHERNET // && NET_IF_NUM > 2 + { + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + ipaddr.addr = DEF_EH_IP; + netmask.addr = DEF_EH_MSK; + gw.addr = DEF_EH_GW; + netif_add(&xnetif[2], &ipaddr, &netmask, &gw, NULL, ðernetif_mii_init, &tcpip_input); + } +#endif + /* Registers the default network interface. */ + netif_set_default(&xnetif[0]); + /* When the netif is fully configured this function must be called.*/ + for(idx = 0; idx < NET_IF_NUM; idx++) { + netif_set_up(&xnetif[idx]); + } + info_printf("interface %d is initialized\n", idx); + lwip_init_done = 1; + + init_event_callback_list(); + } +} + +int wifi_run(rtw_mode_t mode) { + int ret = 0; +#if CONFIG_DEBUG_LOG > 4 + debug_printf("\n%s(%d), %d\n", __func__, mode, wifi_run_mode); + debug_printf("old mode = %d, new mode = %d\n", wifi_run_mode, mode); +#endif + if(wifi_mode) { // != mode) { + info_printf("Deinitializing WIFI ...\n"); + wifi_off(); + wifi_st_status = WIFI_STA_OFF; +// wifi_run_mode = RTW_MODE_NONE; + vTaskDelay(30); + } + if (mode != RTW_MODE_NONE) { + if (_wifi_on(mode) < 0) { + error_printf("Wifi On failed!\n"); + goto error_end; + }; + if(wifi_set_country(wifi_cfg.country_code) != RTW_SUCCESS) { + error_printf("WiFi: Error set tx country_code (%d)!", wifi_cfg.country_code); + }; + if(rtw_power_percentage_idx != wifi_cfg.tx_pwr) { + if(rltk_set_tx_power_percentage(wifi_cfg.tx_pwr) != RTW_SUCCESS) { + error_printf("WiFi: Error set tx power (%d)!", wifi_cfg.tx_pwr); + }; + } + if(wifi_set_network_mode(wifi_cfg.bgn) != RTW_SUCCESS) { + error_printf("WiFi: Error set network mode (%d)!", wifi_cfg.bgn); + } + debug_printf("mode=%d, wifi_mode=%d, old_mоde=%d\n", mode, wifi_mode, wifi_run_mode); + + if(mode <= RTW_MODE_STA_AP) { + struct netif * pnif = &xnetif[WLAN_ST_NETIF_NUM]; +#if LWIP_NETIF_HOSTNAME + // @todo ethernetif_init()... + pnif->hostname = lwip_host_name[0]; +#ifdef USE_NETBIOS + netbios_set_name(WLAN_ST_NETIF_NUM, lwip_host_name[0]); +#endif +#endif + netif_set_addr(&xnetif[WLAN_ST_NETIF_NUM], &wifi_st_dhcp.ip, + &wifi_st_dhcp.mask, &wifi_st_dhcp.gw); + pnif = &xnetif[WLAN_AP_NETIF_NUM]; +#if LWIP_NETIF_HOSTNAME + // @todo ethernetif_init()... + pnif->hostname = lwip_host_name[1]; +#ifdef USE_NETBIOS + netbios_set_name(WLAN_AP_NETIF_NUM, lwip_host_name[1]); +#endif +#endif + netif_set_addr(&xnetif[WLAN_AP_NETIF_NUM], &wifi_ap_dhcp.ip, + &wifi_ap_dhcp.mask, &wifi_ap_dhcp.gw); + + } + switch(mode) { + case RTW_MODE_STA_AP: + ret = wifi_run_ap() | wifi_run_st(); +// _wext_enable_powersave(0, 0, 0); +// _wext_set_lps_dtim(0, 0); + break; + case RTW_MODE_STA: + ret = wifi_run_st(); + if(_wext_set_lps_dtim(0, wifi_st_cfg.dtim)!= RTW_SUCCESS) { + error_printf("WiFi: Error set DTIM(%d)!", wifi_st_cfg.dtim); + }; + if(_wext_enable_powersave(0, wifi_st_cfg.sleep & 1, (wifi_st_cfg.sleep >> 1) & 1) != RTW_SUCCESS) { + error_printf("WiFi: Error set powersave mode!"); + }; + break; + case RTW_MODE_AP: + ret = wifi_run_ap(); +// _wext_enable_powersave(WLAN0_NAME, 0, 0); + break; +#if 0// CONFIG_ENABLE_?? + case RTW_MODE_PROMISC: + // @todo + break; +#endif +#if CONFIG_ENABLE_P2P + case RTW_MODE_P2P: + // @todo + break; +#endif + default: + ret = 1; + error_printf("WiFi: Error mode(%d)\n", wifi_mode); + }; + wifi_run_mode = mode; + if(ret == 0 && (wifi_cfg.save_flg & BID_WIFI_CFG)) { + wifi_cfg.mode = mode; + write_wifi_cfg(BID_WIFI_CFG); + }; + } else { + ret = 0; +error_end: +#if CONFIG_WLAN_CONNECT_CB + connect_close(); +#endif + if(wifi_run_mode) { + wifi_disconnect(); + }; + wifi_off(); + wifi_st_status = WIFI_STA_OFF; + wifi_run_mode = RTW_MODE_NONE; + chk_ap_netif_num(); + }; + return ret; +} + +/* Load cfg, init WiFi + LwIP init, WiFi start if wifi_cfg.mode != RTW_MODE_NONE */ +void wifi_init(void) { + debug_printf("\nLoad Config\n"); + read_wifi_cfg(wifi_cfg.load_flg); // DEF_LOAD_CFG + // Call back from wlan driver after wlan init done +// p_wlan_init_done_callback = wlan_init_done_callback; + // Call back from application layer after wifi_connection success +// p_write_reconnect_ptr = wlan_write_reconnect_data_to_flash; + p_wlan_autoreconnect_hdl = NULL; + _LwIP_Init(); +#if CONFIG_WIFI_IND_USE_THREAD + wifi_manager_init(); +#endif +// wifi_cfg.mode = RTW_MODE_PROMISC; //RTW_MODE_P2P; + wifi_run(wifi_cfg.mode); +} + +unsigned char *tab_txt_rtw_secyrity[] = { + "OPEN", //0 Open security + "WEP", //1 WEP Security with open authentication + "WEP SHARED", //2 WEP Security with shared authentication + "WPA TKIP", //3 WPA Security with TKIP + "WPA AES", //4 WPA Security with AES + "WPA2 TKIP", //5 WPA2 Security with TKIP + "WPA2 AES", //6 WPA2 Security with AES + "WPA2 Mixed", //7 WPA2 Security with AES & TKIP + "WPA/WPA2 AES", //8 WPA/WPA2 Security + "Unknown" //9 +}; + +unsigned int tab_code_rtw_secyrity[] = { + RTW_SECURITY_OPEN, //0 Open security + RTW_SECURITY_WEP_PSK, //1 WEP Security with open authentication + RTW_SECURITY_WEP_SHARED, //2 WEP Security with shared authentication + RTW_SECURITY_WPA_TKIP_PSK, //3 WPA Security with TKIP + RTW_SECURITY_WPA_AES_PSK, //4 WPA Security with AES + RTW_SECURITY_WPA2_TKIP_PSK, //5 WPA2 Security with TKIP + RTW_SECURITY_WPA2_AES_PSK, //6 WPA2 Security with AES + RTW_SECURITY_WPA2_MIXED_PSK, //7 WPA2 Security with AES & TKIP + RTW_SECURITY_WPA_WPA2_MIXED, //8 WPA/WPA2 Security + RTW_SECURITY_UNKNOWN //9 +}; + +/* +unsigned char *tab_txt_rtw_eccryption[] = { + "Unknown", + "OPEN", + "WEP40", + "WPA_TKIP", + "WPA_AES", + "WPA2_TKIP", + "WPA2_AES", + "WPA2_MIXED", + "???", + "WEP104", + "Udef" // 0xff +}; +*/ + +rtw_security_t idx_to_rtw_security(unsigned char idx) +{ + if(idx > IDX_SECURITY_UNKNOWN - 1) idx = IDX_SECURITY_WPA2_AES_PSK; + return (rtw_security_t)tab_code_rtw_secyrity[idx]; +} + +unsigned char rtw_security_to_idx(rtw_security_t rtw_sec_type) +{ + unsigned char i = 0; + while(rtw_sec_type != tab_code_rtw_secyrity[i] && tab_code_rtw_secyrity[i] != RTW_SECURITY_UNKNOWN) i++; + return i; +} + +unsigned char * idx_security_to_str(unsigned char idx) +{ + if(idx > IDX_SECURITY_UNKNOWN) idx = IDX_SECURITY_UNKNOWN; + return tab_txt_rtw_secyrity[idx]; +} + +unsigned char * rtw_security_to_str(rtw_security_t rtw_sec_type) +{ + return tab_txt_rtw_secyrity[rtw_security_to_idx(rtw_sec_type)]; +} + +void show_wifi_ap_ip(void) { + printf("SoftAP ip: " IPSTR "\n", IP2STR(&xnetif[WLAN_AP_NETIF_NUM].ip_addr)); +} +void show_wifi_st_ip(void) { + printf("Station ip: " IPSTR "\n", IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr)); +} + +void show_wifi_MAC(void) { + printf("MAC: " IPSTR "\n", IP2STR(&xnetif[WLAN_ST_NETIF_NUM].ip_addr)); +} + +void show_wifi_st_cfg(void) { + printf("\tSSID: '%s'\n", wifi_st_cfg.ssid); + printf("\tPassword: '%s'\n", wifi_st_cfg.password); + printf("\tSecurity type: %s\n", idx_security_to_str(wifi_st_cfg.security)); + printf("\tAuto-reconnect: %d\n", wifi_st_cfg.autoreconnect); + printf("\tReconnect pause: %d\n", wifi_st_cfg.reconnect_pause); + printf("\tSleep mode: %p\n", wifi_st_cfg.sleep); + printf("\tDTIM: %d\n", wifi_st_cfg.dtim); +} + +void show_wifi_ap_cfg(void) { + printf("\tSSID: '%s'\n", wifi_ap_cfg.ssid); + printf("\tSSID hidden: %d\n", wifi_ap_cfg.ssid_hidden); + printf("\tPassword: '%s'\n", wifi_ap_cfg.password); + printf("\tSecurity type: %s\n", (wifi_ap_cfg.security)? tab_txt_rtw_secyrity[IDX_SECURITY_WPA2_AES_PSK] : tab_txt_rtw_secyrity[IDX_SECURITY_OPEN]); + printf("\tChannel: %d\n", wifi_ap_cfg.channel); + printf("\tBeacon interval: %d ms\n", wifi_ap_cfg.beacon_interval); + printf("\tMax connections: %d\n", wifi_ap_cfg.max_sta); +} + +void show_wifi_cfg(void) { + printf("\tStart mode: %p\n", wifi_cfg.mode); + printf("\tCountry code: %d\n", wifi_cfg.country_code); + printf("\tNetwork mode: %d\n", wifi_cfg.bgn); + printf("\tTx power: %d\n", wifi_cfg.tx_pwr); + printf("\tAdaptivity: %d\n", wifi_cfg.adaptivity); + printf("\tLoad flags: %p\n", wifi_cfg.load_flg); + printf("\tSave flags: %p\n", wifi_cfg.save_flg); +} + diff --git a/USDK/component/common/api/wifi_api.h b/USDK/component/common/api/wifi_api.h new file mode 100644 index 0000000..156ac93 --- /dev/null +++ b/USDK/component/common/api/wifi_api.h @@ -0,0 +1,188 @@ +/* + * wifi_user_set.h + * + * Created on: 01/04/2017 + * Author: pvvx + */ + +#ifndef _WIFI_API_H_ +#define _WIFI_API_H_ +#include "wifi_constants.h" +#include "queue.h" + +#define ip4_addr1(ipaddr) (((uint8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((uint8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((uint8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((uint8_t*)(ipaddr))[3]) + +#define IPSTR "%d.%d.%d.%d" + +#define IP2STR(ipaddr) \ + ip4_addr1(ipaddr), \ + ip4_addr2(ipaddr), \ + ip4_addr3(ipaddr), \ + ip4_addr4(ipaddr) + +extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57 + +#define BID_WIFI_AP_CFG (1 << 0) +#define BID_WIFI_ST_CFG (1 << 1) +#define BID_AP_DHCP_CFG (1 << 2) +#define BID_ST_DHCP_CFG (1 << 3) +#define BID_WIFI_CFG (1 << 4) +#define BID_AP_HOSTNAME (1 << 5) +#define BID_ST_HOSTNAME (1 << 6) + +#define BID_ALL_WIFI_CFG (BID_WIFI_AP_CFG|BID_WIFI_ST_CFG|BID_AP_DHCP_CFG|BID_ST_DHCP_CFG|BID_AP_HOSTNAME|BID_ST_HOSTNAME) + +#define WLAN_ST_NETIF_NUM wlan_st_netifn +#define WLAN_AP_NETIF_NUM wlan_ap_netifn +//==== FEEP_ID =========================== +#define FEEP_ID_WIFI_CFG 0x4347 // id:'GC' +#define FEEP_ID_WIFI_AP_CFG 0x5041 // id:'AP' +#define FEEP_ID_WIFI_ST_CFG 0x5453 // id:'ST' +#define FEEP_ID_AP_DHCP_CFG 0x4144 // id:'DA' +#define FEEP_ID_ST_DHCP_CFG 0x5344 // id:'DS' +#define FEEP_ID_AP_HOSTNAME 0x4148 // id:'HA' +#define FEEP_ID_ST_HOSTNAME 0x5348 // id:'HP' +//#define FEEP_ID_UART_CFG 0x5530 // id:'0U', type: UART_LOG_CONF +//#define FEEP_ID_LWIP_CFG 0x4C30 // id:'0L', type: struct atcmd_lwip_conf +//#define FEEP_ID_DHCP_CFG 0x4430 // id:'0D', type: struct +//========================================= +#define IW_PASSPHRASE_MAX_SIZE 64 +#define NDIS_802_11_LENGTH_SSID 32 +#define IP4ADDR(a,b,c,d) (((unsigned int)((d) & 0xff) << 24) | \ + ((unsigned int)((c) & 0xff) << 16) | \ + ((unsigned int)((b) & 0xff) << 8) | \ + (unsigned int)((a) & 0xff)) +//========================================= +//--- Wlan Config struct------------------- +typedef struct _wifi_config { + unsigned char mode; // rtw_mode_t + unsigned char adaptivity; // rtw_adaptivity_mode_t + unsigned char country_code; // rtw_country_code_t + unsigned char tx_pwr; // rtw_tx_pwr_percentage_t + unsigned char bgn; // 802.11 rtw_network_mode_t + unsigned char load_flg; // см. BID_WIFI_CFG.. + unsigned char save_flg; +} WIFI_CONFIG, *PWIFI_CONFIG; +//---- Interface 0 - wlan0 - AP - struct -- +typedef struct _softap_config { + unsigned char ssid[NDIS_802_11_LENGTH_SSID+1]; + unsigned char password[IW_PASSPHRASE_MAX_SIZE+1]; + unsigned short beacon_interval; // Note: support 100 ~ 60000 ms, default 100 + unsigned char ssid_hidden; // Note: default 0 + unsigned char security; // 0 = RTW_SECURITY_OPEN, 1 = RTW_SECURITY_WPA2_AES_PSK + unsigned char channel; // 1..14 + unsigned char max_sta; // 1..3 +} SOFTAP_CONFIG, *PSOFTAP_CONFIG; +//---- Interface 1 - wlan1 - ST - struct - +typedef struct _station_config { + unsigned char ssid[NDIS_802_11_LENGTH_SSID+1]; + unsigned char password[IW_PASSPHRASE_MAX_SIZE+1]; + unsigned char bssid[6]; // Note: If bssid set is not ff.ff.ff.ff.ff.ff || 00:00:00:00:00:00 + unsigned char flg; // station will connect to the router with both ssid[], else if set flg - bssid[] matched. + unsigned char security; // IDX_SECURITY + unsigned char autoreconnect; // 0 - none, 1..254 - count, 255 - all + unsigned char reconnect_pause; // in sec + unsigned char sleep; // 0 - Off, 1 - IPS, 2 - LPS, 3 - IPS/LPS mode + unsigned char dtim; // LPS DTIM (2..) +// rtw_adaptivity_mode_t +} STATION_CONFIG, *PSTATION_CONFIG; +//--- LwIP Config ------------------------- +struct lwip_conn_info { + int32_t role; //client, server or seed + unsigned int protocol; //tcp or udp + unsigned int remote_addr; //remote ip + unsigned int remote_port; //remote port + unsigned int local_addr; //locale ip, not used yet + unsigned int local_port; //locale port, not used yet + unsigned int reserved; //reserve for further use +}; +//--- DHCP Config ------------------------- +typedef struct _dhcp_config { + unsigned int ip; + unsigned int mask; + unsigned int gw; + unsigned char mode; // =0 dhcp off, =1 - dhcp on, =2 Static ip, =3 - auto +} DHCP_CONFIG, *PDHCP_CONFIG; + + +extern WIFI_CONFIG wifi_cfg; +extern SOFTAP_CONFIG wifi_ap_cfg; +extern DHCP_CONFIG wifi_ap_dhcp; +extern STATION_CONFIG wifi_st_cfg; +extern DHCP_CONFIG wifi_st_dhcp; +extern unsigned char wifi_run_mode; // rtw_mode_t +extern unsigned char wifi_mode; // rtw_mode_t +extern unsigned char wifi_st_status; // WIFI_STA_ENUM +extern char wlan_st_name[]; +extern char wlan_ap_name[]; +extern char wlan_st_netifn; +extern char wlan_ap_netifn; + +/* WiFi Station & scan security */ +typedef enum { + IDX_SECURITY_OPEN = 0, //0 Open security + IDX_SECURITY_WEP_PSK, //1 WEP Security with open authentication + IDX_SECURITY_WEP_SHARED, //2 WEP Security with shared authentication + IDX_SECURITY_WPA_TKIP_PSK, //3 WPA Security with TKIP + IDX_SECURITY_WPA_AES_PSK, //4 WPA Security with AES + IDX_SECURITY_WPA2_TKIP_PSK, //5 WPA2 Security with TKIP + IDX_SECURITY_WPA2_AES_PSK, //6 WPA2 Security with AES + IDX_SECURITY_WPA2_MIXED_PSK, //7 WPA2 Security with AES & TKIP + IDX_SECURITY_WPA_WPA2_MIXED, //8 WPA/WPA2 Security + IDX_SECURITY_UNKNOWN //9 +} IDX_SECURITY; + +/* wifi_st_status */ +typedef enum { + WIFI_STA_OFF, + WIFI_STA_START, + WIFI_STA_RECONNECT, + WIFI_STA_CONNECTED +} WIFI_STA_ENUM; + + +uint8 * get_new_hostname(void); +uint32 get_new_ip(void); + +void show_wifi_ap_ip(void); +void show_wifi_st_ip(void); +void show_wifi_cfg(void); +void show_wifi_st_cfg(void); +void show_wifi_ap_cfg(void); +uint32 read_wifi_cfg(uint32 flg); +uint32 write_wifi_cfg(uint32 flg); +int wifi_run(rtw_mode_t mode); +void wifi_init(void); + +rtw_security_t idx_to_rtw_security(unsigned char idx); +unsigned char rtw_security_to_idx(rtw_security_t rtw_sec_type); +unsigned char * rtw_security_to_str(rtw_security_t rtw_sec_type); +unsigned char * idx_security_to_str(unsigned char idx); + +/* -------- Api WiFi Scan ------------------------------- */ +#include "wifi_conf.h" +#include "timers.h" + +#define SCAN_CHANNELS 14 +#define MAX_AP_SIZE 32 + +extern QueueHandle_t xQueueWebSrv; + +typedef struct web_scan_handler{ + TimerHandle_t timer; + rtw_scan_result_t * ap_details; + unsigned char ap_count; + unsigned char start_show; + unsigned char used_data; + volatile unsigned char flg; +} web_scan_handler_t; +extern web_scan_handler_t web_scan_handler_ptr; +typedef rtw_result_t (*api_scan_result_handler_t)(internal_scan_handler_t * ap_scan_result); +rtw_result_t api_wifi_scan(api_scan_result_handler_t scan_result_cb); +void wifi_close_scan(void); + + +#endif // _WIFI_API_H_ diff --git a/USDK/component/common/api/wifi_api_scan.c b/USDK/component/common/api/wifi_api_scan.c new file mode 100644 index 0000000..556668e --- /dev/null +++ b/USDK/component/common/api/wifi_api_scan.c @@ -0,0 +1,201 @@ +/* + * wifi_api_scan.c + * + * Created on: 23/04/2017 + * Author: pvvx + */ + +#include "FreeRTOS.h" +#include +#include "main.h" + +#include + +#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#error "Udnef CONFIG_EXAMPLE_WLAN_FAST_CONNECT!" +#endif +#ifndef USE_FLASH_EEP +#error "Define USE_FLASH_EEP!" +#endif + +#include "task.h" +#include +#include +#include "flash_api.h" +#include +#include "dhcp/dhcps.h" +#include "ethernetif.h" +#if CONFIG_ETHERNET +#include "ethernet_mii/ethernet_mii.h" +#endif + +#if 1 +#include "drv_types.h" // or #include "wlan_lib.h" +#else +#include "wifi_constants.h" +#include "wifi_structures.h" +#include "wlan_lib.h" // or #include "drv_types.h" +#endif + +#include "flash_eep.h" +#include "feep_config.h" + +#include "wifi_api.h" +#include "main.h" +#include "wifi_user_set.h" + +/****************************************************** + * + ******************************************************/ + +web_scan_handler_t web_scan_handler_ptr; + +/* -------- WiFi Scan ------------------------------- */ +volatile uint8_t scan_end; + +extern internal_scan_handler_t scan_result_handler_ptr; +void wifi_scan_each_report_hdl(char* buf, int buf_len, int flags, void* userdata); + +LOCAL void _wifi_scan_done_hdl(char* buf, int buf_len, int flags, void* userdata); + +void wifi_set_timer_scan(int ms) { + if(web_scan_handler_ptr.flg) { + if(xTimerChangePeriod(web_scan_handler_ptr.timer, ms, portMAX_DELAY) != pdPASS) { + error_printf("Error xTimerChangePeriod\n"); + } + } +} +/* -------- WiFi Scan Close ------------------------- */ +void wifi_close_scan(void) +{ + internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; + web_scan_handler_t * pwscn_rec = &web_scan_handler_ptr; + printf("Close scan rec\n"); + if(pscan_rec->scan_running) { + wifi_unreg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl); + wifi_unreg_event_handler(WIFI_EVENT_SCAN_DONE, _wifi_scan_done_hdl); + if(pscan_rec->ap_details) rtw_free(pscan_rec->ap_details); + rtw_memset((void *) pscan_rec, 0, sizeof(internal_scan_handler_t)); + } + if(pwscn_rec->flg) { + if(pwscn_rec->timer) xTimerDelete(pwscn_rec->timer, portMAX_DELAY); + if(pwscn_rec->ap_details) rtw_free(pwscn_rec->ap_details); + rtw_memset(pwscn_rec, 0, sizeof(web_scan_handler_t)); + } +// pscan_rec->scan_complete = 1; +} +/* -------- WiFi Scan Done ------------------------- */ +LOCAL void _wifi_scan_done_hdl(char* buf, int buf_len, int flags, void* userdata) { + internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; + web_scan_handler_t * pwscn_rec = &web_scan_handler_ptr; + if(pscan_rec->gscan_result_handler) { + // сторонний вывод + (*pscan_rec->gscan_result_handler)(pscan_rec); + } + else { + // оставить структуру pscan_rec->pap_details[i] для вывода в web scan на 5 сек + if(pwscn_rec->flg && pscan_rec->scan_cnt) { + debug_printf("\nScan done, wait read rec\n"); + if(xTimerChangePeriod(pwscn_rec->timer, 5000, portMAX_DELAY) != pdPASS) { +// error_printf("Error xTimerChangePeriod\n"); + } else { + if(pwscn_rec->ap_details) rtw_free(pwscn_rec->ap_details); + pwscn_rec->ap_details = pscan_rec->ap_details; + pwscn_rec->ap_count = pscan_rec->scan_cnt; + wifi_unreg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl); + wifi_unreg_event_handler(WIFI_EVENT_SCAN_DONE, _wifi_scan_done_hdl); + rtw_memset((void *) pscan_rec, 0, sizeof(internal_scan_handler_t)); + pwscn_rec->flg = 2; + } + return; + }; + } + wifi_close_scan(); + return; +} + +/* -------- WiFi Scan Start ------------------------- */ +LOCAL int _wifi_scan_networks(rtw_scan_result_handler_t results_handler) { + internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; + pscan_rec->gscan_result_handler = results_handler; + pscan_rec->max_ap_size = MAX_AP_SIZE; + pscan_rec->ap_details = (rtw_scan_result_t*) rtw_zmalloc(MAX_AP_SIZE * sizeof(rtw_scan_result_t) + MAX_AP_SIZE * sizeof(rtw_scan_result_t*)); + if (pscan_rec->ap_details != NULL) { + pscan_rec->pap_details = (rtw_scan_result_t**) (&pscan_rec->ap_details[MAX_AP_SIZE]); + pscan_rec->scan_cnt = 0; + pscan_rec->scan_complete = RTW_FALSE; + pscan_rec->user_data = NULL; + wifi_reg_event_handler(WIFI_EVENT_SCAN_RESULT_REPORT, wifi_scan_each_report_hdl, NULL); + wifi_reg_event_handler(WIFI_EVENT_SCAN_DONE, _wifi_scan_done_hdl, NULL); + if(wext_set_scan(WLAN0_NAME, NULL, 0, RTW_SCAN_TYPE_ACTIVE | (RTW_SCAN_COMMAMD << 4) | (RTW_BSS_TYPE_ANY << 8)) == RTW_SUCCESS) { + return RTW_SUCCESS; + } + }; + wifi_close_scan(); + return RTW_ERROR; +} + +/* -------- wext_set_pscan_channels ----------------- */ + +LOCAL int wext_set_pscan_channels(void) { + struct iwreq iwr; + int ret = -1; + __u8 *para; + int i = 0; + rtw_memset(&iwr, 0, sizeof(iwr)); + //Format of para:function_name num_channel chan1... pscan_config1 ... + iwr.u.data.length = (SCAN_CHANNELS + SCAN_CHANNELS + 1) + 12; + para = rtw_malloc(iwr.u.data.length); //size:num_chan + num_time + length + function_name + iwr.u.data.pointer = para; + if (para != NULL) { + rtw_memcpy((char*) para, "PartialScan", 12); //Cmd + *(para + 12) = SCAN_CHANNELS; // length + for (i = 0; i < SCAN_CHANNELS; i++) { + *(para + 13 + i) = i + 1; + *((__u16 *) (para + 13 + SCAN_CHANNELS + i)) = PSCAN_ENABLE; + } + ret = iw_ioctl(WLAN0_NAME, SIOCDEVPRIVATE, &iwr); + rtw_free(para); + } +#if CONFIG_DEBUG_LOG > 3 + else { + error_printf("%s: Can't malloc memory!\n", __func__); + } +#endif + return ret; +} + +/* -------- WiFi Scan ------------------------------- */ +rtw_result_t api_wifi_scan(api_scan_result_handler_t scan_result_cb) +{ + internal_scan_handler_t * pscan_rec = &scan_result_handler_ptr; + web_scan_handler_t * pwscn_rec = &web_scan_handler_ptr; + if ((!pscan_rec->scan_running) + && (!pwscn_rec->flg)) { + pscan_rec->scan_running = 1; + rtw_memset(pwscn_rec, 0, sizeof(web_scan_handler_t)); + pwscn_rec->flg = 1; + debug_printf("\nStart scan...\n"); + pwscn_rec->timer = xTimerCreate("webscan", 2500, pdFALSE, NULL, (TimerCallbackFunction_t)wifi_close_scan); + if(!pwscn_rec->timer) { +// error_printf("Error xTimerCreate\n"); + } else if(xTimerStart(pwscn_rec->timer, portMAX_DELAY) != pdPASS) { +// error_printf("Error xTimerStart\n"); + } else if(wext_set_pscan_channels() < 0) { +// error_printf("ERROR: wifi set partial scan channel fail\n"); + } else if(_wifi_scan_networks(scan_result_cb) != RTW_SUCCESS) { +// error_printf("ERROR: wifi scan failed\n"); + } else if(scan_result_cb) { + int i = 300; + while(i-- && pscan_rec->scan_running) { + vTaskDelay(10); + }; + return RTW_SUCCESS; + } else + return RTW_SUCCESS; + wifi_close_scan(); + return RTW_ERROR; + }; + return RTW_TIMEOUT; +} + diff --git a/USDK/component/common/api/wifi_interactive_ext.h b/USDK/component/common/api/wifi_interactive_ext.h new file mode 100644 index 0000000..7f4afc5 --- /dev/null +++ b/USDK/component/common/api/wifi_interactive_ext.h @@ -0,0 +1,42 @@ +#define CONFIG_EXTERN_TEST 0 +#define CONFIG_EXTERN_HW 0 +#define CONFIG_EXTERN_CLOUD 0 +#define CONFIG_TTCP 0 + +/* External Function */ +#if CONFIG_EXTERN_TEST +extern void cmd_tcpecho(int argc, char **argv); +#endif +#if CONFIG_EXTERN_HW +extern void cmd_led(int argc, char **argv); +extern void cmd_tmp75(int argc, char **argv); +#endif +#if CONFIG_EXTERN_CLOUD +extern void cmd_cloud(int argc, char **argv); +extern void cmd_reboot(int argc, char **argv); +extern void cmd_config(int argc, char **argv); +#endif + +#if CONFIG_TTCP +extern void cmd_ttcp(int argc, char **argv); +#endif + + +static const cmd_entry ext_cmd_table[] = { +#if CONFIG_EXTERN_TEST + {"tcpecho", cmd_tcpecho}, +#endif +#if CONFIG_EXTERN_HW + {"led", cmd_led}, + {"tmp75", cmd_tmp75}, +#endif +#if CONFIG_EXTERN_CLOUD + {"cloud", cmd_cloud}, + {"reboot", cmd_reboot}, + {"config", cmd_config}, +#endif +#if CONFIG_TTCP + {"ttcp", cmd_ttcp}, +#endif + {"", NULL} +}; diff --git a/USDK/component/common/api/wifi_interactive_mode.c b/USDK/component/common/api/wifi_interactive_mode.c new file mode 100644 index 0000000..a0d0436 --- /dev/null +++ b/USDK/component/common/api/wifi_interactive_mode.c @@ -0,0 +1,1238 @@ + +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "main.h" +#include +#include "tcpip.h" +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_INTERACTIVE_EXT +#define CONFIG_INTERACTIVE_EXT 0 +#endif +#ifndef CONFIG_SSL_CLIENT +#if defined(CONFIG_PLATFORM_8711B) +#define CONFIG_SSL_CLIENT 0 +#else +#define CONFIG_SSL_CLIENT 1 +#endif +#endif + +#ifndef CONFIG_GOOGLENEST +#define CONFIG_GOOGLENEST 0 +#endif +#if CONFIG_LWIP_LAYER +#ifndef CONFIG_WEBSERVER +#define CONFIG_WEBSERVER 0 +#endif +#endif +#ifndef CONFIG_OTA_UPDATE +#define CONFIG_OTA_UPDATE 0 +#endif +#ifndef CONFIG_BSD_TCP +#define CONFIG_BSD_TCP 0 +#endif +#define CONFIG_JD_SMART 0 +#ifndef CONFIG_ENABLE_P2P +#define CONFIG_ENABLE_P2P 0 +#endif +#define SCAN_WITH_SSID 0 + +#ifdef CONFIG_WPS +#define STACKSIZE 1280 +#else +#define STACKSIZE 1024 +#endif + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif +/* Give default value if not defined */ +#ifndef NET_IF_NUM +#ifdef CONFIG_CONCURRENT_MODE +#define NET_IF_NUM 2 +#else +#define NET_IF_NUM 1 +#endif +#endif + +/*Static IP ADDRESS*/ +#ifndef IP_ADDR0 +#define IP_ADDR0 192 +#define IP_ADDR1 168 +#define IP_ADDR2 1 +#define IP_ADDR3 80 +#endif + +/*NETMASK*/ +#ifndef NETMASK_ADDR0 +#define NETMASK_ADDR0 255 +#define NETMASK_ADDR1 255 +#define NETMASK_ADDR2 255 +#define NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef GW_ADDR0 +#define GW_ADDR0 192 +#define GW_ADDR1 168 +#define GW_ADDR2 1 +#define GW_ADDR3 1 +#endif + +/*Static IP ADDRESS*/ +#ifndef AP_IP_ADDR0 +#define AP_IP_ADDR0 192 +#define AP_IP_ADDR1 168 +#define AP_IP_ADDR2 43 +#define AP_IP_ADDR3 1 +#endif + +/*NETMASK*/ +#ifndef AP_NETMASK_ADDR0 +#define AP_NETMASK_ADDR0 255 +#define AP_NETMASK_ADDR1 255 +#define AP_NETMASK_ADDR2 255 +#define AP_NETMASK_ADDR3 0 +#endif + +/*Gateway Address*/ +#ifndef AP_GW_ADDR0 +#define AP_GW_ADDR0 192 +#define AP_GW_ADDR1 168 +#define AP_GW_ADDR2 43 +#define AP_GW_ADDR3 1 +#endif + +static void cmd_help(int argc, char **argv); +#if CONFIG_SSL_CLIENT +extern void cmd_ssl_client(int argc, char **argv); +#endif + +#if CONFIG_GOOGLENEST +extern void cmd_googlenest(int argc, char **argv); +#endif +#if CONFIG_JD_SMART +extern void cmd_jd_smart(int argc, char **argv); +#endif +#if CONFIG_WLAN +void cmd_wifi_on(int argc, char **argv); +void cmd_wifi_off(int argc, char **argv); +void cmd_wifi_disconnect(int argc, char **argv); +extern void cmd_promisc(int argc, char **argv); +extern void cmd_simple_config(int argc, char **argv); + +#if CONFIG_OTA_UPDATE +extern void cmd_update(int argc, char **argv); +#endif +#if CONFIG_BSD_TCP +extern void cmd_tcp(int argc, char **argv); +extern void cmd_udp(int argc, char **argv); +#endif +#if CONFIG_WEBSERVER +extern void start_web_server(void); +extern void stop_web_server(void); +#endif +extern void cmd_app(int argc, char **argv); +#ifdef CONFIG_WPS +#if CONFIG_ENABLE_WPS +extern void cmd_wps(int argc, char **argv); +#endif +#ifdef CONFIG_WPS_AP +extern void cmd_ap_wps(int argc, char **argv); +extern int wpas_wps_dev_config(u8 *dev_addr, u8 bregistrar); +#endif //CONFIG_WPS_AP +#endif //CONFIG_WPS +#if CONFIG_ENABLE_P2P +extern void cmd_wifi_p2p_start(int argc, char **argv); +extern void cmd_wifi_p2p_stop(int argc, char **argv); +extern void cmd_p2p_listen(int argc, char **argv); +extern void cmd_p2p_find(int argc, char **argv); +extern void cmd_p2p_peers(int argc, char **argv); +extern void cmd_p2p_info(int argc, char **argv); +extern void cmd_p2p_disconnect(int argc, char **argv); +extern void cmd_p2p_connect(int argc, char **argv); +#endif //CONFIG_ENABLE_P2P +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) +extern u32 CmdDumpWord(IN u16 argc, IN u8 *argv[]); +extern u32 CmdWriteWord(IN u16 argc, IN u8 *argv[]); +#endif +#if CONFIG_LWIP_LAYER +extern struct netif xnetif[NET_IF_NUM]; +#endif +#ifdef CONFIG_CONCURRENT_MODE +static void cmd_wifi_sta_and_ap(int argc, char **argv) +{ + int timeout = 20;//, mode; +#if CONFIG_LWIP_LAYER + struct netif * pnetiff = (struct netif *)&xnetif[1]; +#endif + int channel; + + if((argc != 3) && (argc != 4)) { + printf("Usage: wifi_ap SSID CHANNEL [PASSWORD]\n"); + return; + } + + if(atoi((const char *)argv[2]) > 14){ + printf(" bad channel!Usage: wifi_ap SSID CHANNEL [PASSWORD]\n"); + return; + } +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + +#if 0 + //Check mode + wext_get_mode(WLAN0_NAME, &mode); + + switch(mode) { + case IW_MODE_MASTER: //In AP mode + cmd_wifi_off(0, NULL); + cmd_wifi_on(0, NULL); + break; + case IW_MODE_INFRA: //In STA mode + if(wext_get_ssid(WLAN0_NAME, ssid) > 0) + cmd_wifi_disconnect(0, NULL); + } +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA_AP) < 0){ + printf("ERROR: Wifi on failed!\n"); + return; + } + + printf("Starting AP ...\n"); + channel = atoi((const char *)argv[2]); + if(channel > 13){ + printf("Channel is from 1 to 13. Set channel 1 as default!\n"); + channel = 1; + } + + if(argc == 4) { + if(wifi_start_ap(argv[1], + RTW_SECURITY_WPA2_AES_PSK, + argv[3], + channel, + 0 + ) != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n\n"); + return; + } + } + else { + if(wifi_start_ap(argv[1], + RTW_SECURITY_OPEN, + NULL, + channel, + 0 + ) != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return; + } + } + + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN1_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)argv[1]) == 0) { + printf("%s started\n", argv[1]); + break; + } + } + + if(timeout == 0) { + printf("ERROR: Start AP timeout!\n"); + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +#if CONFIG_LWIP_LAYER + LwIP_UseStaticIP(&xnetif[1]); +#ifdef CONFIG_DONT_CARE_TP + pnetiff->flags |= NETIF_FLAG_IPSWITCH; +#endif + dhcps_init(pnetiff); +#endif +} +#endif + +static void cmd_wifi_ap(int argc, char **argv) +{ + int timeout = 20; +#if CONFIG_LWIP_LAYER + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + struct netif * pnetif = &xnetif[0]; +#endif + int channel; + + if((argc != 3) && (argc != 4)) { + printf("Usage: wifi_ap SSID CHANNEL [PASSWORD]\n"); + return; + } +#if CONFIG_LWIP_LAYER + dhcps_deinit(); + IP4_ADDR(&ipaddr, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3); + IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + netif_set_addr(pnetif, &ipaddr, &netmask,&gw); +#ifdef CONFIG_DONT_CARE_TP + pnetif->flags |= NETIF_FLAG_IPSWITCH; +#endif +#endif +#if 0 + //Check mode + wext_get_mode(WLAN0_NAME, &mode); + + switch(mode) { + case IW_MODE_MASTER: //In AP mode + wifi_off(); + wifi_on(1); + break; + case IW_MODE_INFRA: //In STA mode + if(wext_get_ssid(WLAN0_NAME, ssid) > 0) + cmd_wifi_disconnect(0, NULL); + } +#else + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_AP) < 0){ + printf("ERROR: Wifi on failed!\n"); + return; + } +#endif + + printf("Starting AP ...\n"); + channel = atoi((const char *)argv[2]); + if(channel > 13){ + printf("Channel is from 1 to 13. Set channel 1 as default!\n"); + channel = 1; + } +#ifdef CONFIG_WPS_AP + wpas_wps_dev_config(pnetif->hwaddr, 1); +#endif + + if(argc == 4) { + if(wifi_start_ap(argv[1], + RTW_SECURITY_WPA2_AES_PSK, + argv[3], + channel, + 0 + ) != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return; + } + } + else { + if(wifi_start_ap(argv[1], + RTW_SECURITY_OPEN, + NULL, + channel, + 0 + ) != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return; + } + } + + while(1) { + char essid[33]; + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) > 0) { + if(strcmp((const char *) essid, (const char *)argv[1]) == 0) { + printf("%s started\n", argv[1]); + break; + } + } + + if(timeout == 0) { + printf("ERROR: Start AP timeout!\n"); + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +#if CONFIG_LWIP_LAYER + //LwIP_UseStaticIP(pnetif); + dhcps_init(pnetif); +#endif +} + +static void cmd_wifi_connect(int argc, char **argv) +{ + int ret = RTW_ERROR; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + int mode; + char *ssid; + rtw_security_t security_type; + char *password; + int ssid_len; + int password_len; + int key_id; + void *semaphore; + + if((argc != 2) && (argc != 3) && (argc != 4)) { + printf("Usage: wifi_connect SSID [WPA PASSWORD / (5 or 13) ASCII WEP KEY] [WEP KEY ID 0/1/2/3]\n"); + return; + } + + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("ERROR: Wifi on failed!\n"); + return; + } + } + + ssid = argv[1]; + if(argc == 2){ + security_type = RTW_SECURITY_OPEN; + password = NULL; + ssid_len = strlen((const char *)argv[1]); + password_len = 0; + key_id = 0; + semaphore = NULL; + }else if(argc ==3){ + security_type = RTW_SECURITY_WPA2_AES_PSK; + password = argv[2]; + ssid_len = strlen((const char *)argv[1]); + password_len = strlen((const char *)argv[2]); + key_id = 0; + semaphore = NULL; + }else{ + security_type = RTW_SECURITY_WEP_PSK; + password = argv[2]; + ssid_len = strlen((const char *)argv[1]); + password_len = strlen((const char *)argv[2]); + key_id = atoi(argv[3]); + if(( password_len != 5) && (password_len != 13)) { + printf("Wrong WEP key length. Must be 5 or 13 ASCII characters.\n"); + return; + } + if((key_id < 0) || (key_id > 3)) { + printf("Wrong WEP key id. Must be one of 0,1,2, or 3.\n"); + return; + } + semaphore = NULL; + } + + ret = wifi_connect( + NULL, + 0, + ssid, + security_type, + password, + key_id, + semaphore); + + tick2 = xTaskGetTickCount(); + printf("Connected after %dms.\n", (tick2-tick1)); + if(ret != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return; + } else { +#if CONFIG_LWIP_LAYER + /* Start DHCPClient */ + LwIP_DHCP(0, DHCP_START); + tick3 = xTaskGetTickCount(); + printf("Got IP after %dms.\n", (tick3-tick1)); +#endif +#if CONFIG_WLAN_CONNECT_CB + extern void connect_start(void); + connect_start(); +#endif + } +} + +static void cmd_wifi_connect_bssid(int argc, char **argv) +{ + int ret = RTW_ERROR; + unsigned long tick1 = xTaskGetTickCount(); + unsigned long tick2, tick3; + int mode; + unsigned char bssid[ETH_ALEN]; + char *ssid = NULL; + rtw_security_t security_type; + char *password; + int ssid_len = 0; + int password_len; + int key_id; + void *semaphore; + u32 mac[ETH_ALEN]; + u32 i; + u32 index = 0; + + if((argc != 3) && (argc != 4) && (argc != 5) && (argc != 6)) { + printf("Usage: wifi_connect_bssid 0/1 [SSID] BSSID / xx:xx:xx:xx:xx:xx [WPA PASSWORD / (5 or 13) ASCII WEP KEY] [WEP KEY ID 0/1/2/3]\n"); + return; + } + + //Check if in AP mode + wext_get_mode(WLAN0_NAME, &mode); + + if(mode == IW_MODE_MASTER) { +#if CONFIG_LWIP_LAYER + dhcps_deinit(); +#endif + wifi_off(); + vTaskDelay(20); + if (wifi_on(RTW_MODE_STA) < 0){ + printf("ERROR: Wifi on failed!\n"); + return; + } + } + //check ssid + if(memcmp(argv[1], "0", 1)){ + index = 1; + ssid_len = strlen((const char *)argv[2]); + if((ssid_len <= 0) || (ssid_len > 32)) { + printf("Wrong ssid. Length must be less than 32.\n"); + return; + } + ssid = argv[2]; + } + sscanf(argv[2 + index], MAC_FMT, mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + for(i=0; i 3)) { + printf("Wrong WEP key id. Must be one of 0,1,2, or 3.\n"); + return; + } + semaphore = NULL; + } + + ret = wifi_connect( + bssid, + 1, + ssid, + security_type, + password, + key_id, + semaphore); + + tick2 = xTaskGetTickCount(); + printf("Connected after %dms.\n", (tick2-tick1)); + if(ret != RTW_SUCCESS) { + printf("ERROR: Operation failed!\n"); + return; + } else { +#if CONFIG_LWIP_LAYER + /* Start DHCPClient */ + LwIP_DHCP(0, DHCP_START); +#endif + } + tick3 = xTaskGetTickCount(); + printf("Got IP after %dms.\n", (tick3-tick1)); +} + +void cmd_wifi_disconnect(int argc, char **argv) +{ + int timeout = 20; + char essid[33]; + + printf("Deassociating AP ...\n"); + + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("WIFI disconnected\n"); + return; + } + + if(wifi_disconnect() < 0) { + printf("ERROR: Operation failed!\n"); + return; + } + + while(1) { + if(wext_get_ssid(WLAN0_NAME, (unsigned char *) essid) < 0) { + printf("WIFI disconnected\n"); + break; + } + + if(timeout == 0) { + printf("ERROR: Deassoc timeout!\n"); + break; + } + + vTaskDelay(1 * configTICK_RATE_HZ); + timeout --; + } +} + +static void cmd_wifi_info(int argc, char **argv) +{ + int i = 0; +#if CONFIG_LWIP_LAYER + u8 *mac = LwIP_GetMAC(&xnetif[0]); + u8 *ip = LwIP_GetIP(&xnetif[0]); + u8 *gw = LwIP_GetGW(&xnetif[0]); +#endif + u8 *ifname[2] = {WLAN0_NAME,WLAN1_NAME}; +#ifdef CONFIG_MEM_MONITOR + extern int min_free_heap_size; +#endif + + rtw_wifi_setting_t setting; + for(i=0;i %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) ; + printf("\tIP => %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); + printf("\tGW => %d.%d.%d.%d\n", gw[0], gw[1], gw[2], gw[3]); +#endif + if(setting.mode == RTW_MODE_AP || i == 1) + { + int client_number; + struct { + int count; + rtw_mac_t mac_list[AP_STA_NUM]; + } client_info; + + client_info.count = AP_STA_NUM; + wifi_get_associated_client_list(&client_info, sizeof(client_info)); + + printf("Associated Client List:\n==============================\n"); + + if(client_info.count == 0) + printf("Client Num: 0\n"); + else + { + printf("Client Num: %d\n", client_info.count); + for( client_number=0; client_number < client_info.count; client_number++ ) + { + printf("Client [%d]:\n", client_number); + printf("\tMAC => "MAC_FMT"\n", + MAC_ARG(client_info.mac_list[client_number].octet)); + } +// printf("\n\r"); + } + } + + { + int error = wifi_get_last_error(); + printf("Last Link Error\n==============================\n"); + switch(error) + { + case RTW_NO_ERROR: + printf("\tNo Error\n"); + break; + case RTW_NONE_NETWORK: + printf("\tTarget AP Not Found\n"); + break; + case RTW_CONNECT_FAIL: + printf("\tAssociation Failed\n"); + break; + case RTW_WRONG_PASSWORD: + printf("\tWrong Password\n"); + break; + case RTW_DHCP_FAIL: + printf("\tDHCP Failed\n"); + break; + default: + printf("\tUnknown Error(%d)\n", error); + } +// printf("\n\r"); + } + } + } + +#if defined(configUSE_TRACE_FACILITY) && (configUSE_TRACE_FACILITY == 1) + { + signed char pcWriteBuffer[1024]; + vTaskList((char*)pcWriteBuffer); + printf("Task List: \n%s\n", pcWriteBuffer); + } +#endif +#ifdef CONFIG_MEM_MONITOR + printf("Memory Usage\n==============================\n"); + printf("Min Free Heap Size: %d\n", min_free_heap_size); + printf("Cur Free Heap Size: %d\n", xPortGetFreeHeapSize()); +#endif +} + +void cmd_wifi_on(int argc, char **argv) +{ + if(wifi_on(RTW_MODE_STA)<0){ + printf("ERROR: Wifi on failed!\n"); + } +} + +void cmd_wifi_off(int argc, char **argv) +{ +#if CONFIG_WEBSERVER + stop_web_server(); +#endif +#if CONFIG_ENABLE_P2P + cmd_wifi_p2p_stop(0, NULL); +#else + wifi_off(); +#endif +} + +static void print_scan_result( rtw_scan_result_t* record ) +{ + RTW_API_INFO( ( "%s\t ", ( record->bss_type == RTW_BSS_TYPE_ADHOC ) ? "Adhoc" : "Infra" ) ); + RTW_API_INFO( ( MAC_FMT, MAC_ARG(record->BSSID.octet) ) ); + RTW_API_INFO( ( " %d\t ", record->signal_strength ) ); + RTW_API_INFO( ( " %d\t ", record->channel ) ); + RTW_API_INFO( ( " %d\t ", record->wps_type ) ); + RTW_API_INFO( ( "%s\t\t ", ( record->security == RTW_SECURITY_OPEN ) ? "Open" : + ( record->security == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( record->security == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( record->security == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( record->security == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( record->security == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( record->security == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + ( record->security == RTW_SECURITY_WPA_WPA2_MIXED ) ? "WPA/WPA2 AES" : + "Unknown" ) ); + + RTW_API_INFO( ( " %s ", record->SSID.val ) ); + RTW_API_INFO( ( "\r\n" ) ); +} + +static rtw_result_t app_scan_result_handler( rtw_scan_handler_result_t* malloced_scan_result ) +{ + static int ApNum = 0; + + if (malloced_scan_result->scan_complete != RTW_TRUE) { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + + RTW_API_INFO( ( "%d\t ", ++ApNum ) ); + + print_scan_result(record); + } else{ + ApNum = 0; + } + return RTW_SUCCESS; +} +#if SCAN_WITH_SSID +static void cmd_wifi_scan_with_ssid(int argc, char **argv) +{ + + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + + char *ssid = NULL; + int ssid_len = 0; + //Fully scan + int scan_buf_len = 500; + if(argc == 3 && argv[1] && argv[2]){ + ssid = argv[1]; + ssid_len = strlen((const char *)argv[1]); + if((ssid_len <= 0) || (ssid_len > 32)) { + printf("Wrong ssid. Length must be less than 32.\n"); + goto exit; + } + scan_buf_len = atoi(argv[2]); + if(scan_buf_len < 36){ + printf("BUFFER_LENGTH too short\n"); + goto exit; + } + }else if(argc > 3){ + int i = 0; + int num_channel = atoi(argv[2]); + ssid = argv[1]; + ssid_len = strlen((const char *)argv[1]); + if((ssid_len <= 0) || (ssid_len > 32)) { + printf("Wrong ssid. Length must be less than 32.\n"); + goto exit; + } + channel_list = (u8*)pvPortMalloc(num_channel); + if(!channel_list){ + printf("ERROR: Can't malloc memory for channel list\n"); + goto exit; + } + pscan_config = (u8*)pvPortMalloc(num_channel); + if(!pscan_config){ + printf("ERROR: Can't malloc memory for pscan_config\n"); + goto exit; + } + //parse command channel list + for(i = 3; i <= argc -1 ; i++){ + *(channel_list + i - 3) = (u8)atoi(argv[i]); + *(pscan_config + i - 3) = PSCAN_ENABLE; + } + if(wifi_set_pscan_chan(channel_list, pscan_config, num_channel) < 0){ + printf("ERROR: wifi set partial scan channel fail\n"); + goto exit; + } + }else{ + printf(" For Scan all channel Usage: wifi_scan_with_ssid ssid BUFFER_LENGTH\n"); + printf(" For Scan partial channel Usage: wifi_scan_with_ssid ssid num_channels channel_num1 ...\n"); + return; + } + + if(wifi_scan_networks_with_ssid(NULL, &scan_buf_len, ssid, ssid_len) != RTW_SUCCESS){ + printf("ERROR: wifi scan failed\n"); + goto exit; + } + +exit: + if(argc > 2 && channel_list) + vPortFree(channel_list); + +} +#endif +static void cmd_wifi_scan(int argc, char **argv) +{ + + u8 *channel_list = NULL; + u8 *pscan_config = NULL; + + if(argc > 2){ + int i = 0; + int num_channel = atoi(argv[1]); + + channel_list = (u8*)pvPortMalloc(num_channel); + if(!channel_list){ + printf(" ERROR: Can't malloc memory for channel list\n"); + goto exit; + } + pscan_config = (u8*)pvPortMalloc(num_channel); + if(!pscan_config){ + printf(" ERROR: Can't malloc memory for pscan_config\n"); + goto exit; + } + //parse command channel list + for(i = 2; i <= argc -1 ; i++){ + *(channel_list + i - 2) = (u8)atoi(argv[i]); + *(pscan_config + i - 2) = PSCAN_ENABLE; + } + + if(wifi_set_pscan_chan(channel_list, pscan_config, num_channel) < 0){ + printf("ERROR: wifi set partial scan channel fail\n"); + goto exit; + } + + } + + if(wifi_scan_networks(app_scan_result_handler, NULL ) != RTW_SUCCESS){ + printf("ERROR: wifi scan failed\n"); + goto exit; + } +exit: + if(argc > 2 && channel_list) + vPortFree(channel_list); + +} + +#if CONFIG_WEBSERVER +static void cmd_wifi_start_webserver(int argc, char **argv) +{ + start_web_server(); +} +#endif + +static void cmd_wifi_iwpriv(int argc, char **argv) +{ + if(argc == 2 && argv[1]) { + wext_private_command(WLAN0_NAME, argv[1], 1); + } + else { + printf("Usage: iwpriv COMMAND PARAMETERS\n"); + } +} +#endif //#if CONFIG_WLAN + +static void cmd_ping(int argc, char **argv) +{ + if(argc == 2) { + do_ping_call(argv[1], 0, 5); //Not loop, count=5 + } + else if(argc == 3) { + if(strcmp(argv[2], "loop") == 0) + do_ping_call(argv[1], 1, 0); //loop, no count + else + do_ping_call(argv[1], 0, atoi(argv[2])); //Not loop, with count + } + else { + printf("Usage: ping IP [COUNT/loop]\n"); + } +} +#if ( configGENERATE_RUN_TIME_STATS == 1 ) +static char cBuffer[ 512 ]; +static void cmd_cpustat(int argc, char **argv) +{ + vTaskGetRunTimeStats( ( char * ) cBuffer ); + printf( cBuffer ); +} +#endif +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) +static void cmd_dump_reg(int argc, char **argv) +{ + CmdDumpWord(argc-1, (u8**)(argv+1)); +} +static void cmd_edit_reg(int argc, char **argv) +{ + CmdWriteWord(argc-1, (u8**)(argv+1)); +} +#endif +static void cmd_exit(int argc, char **argv) +{ + printf("Leave INTERACTIVE MODE\n"); + vTaskDelete(NULL); +} + +static void cmd_debug(int argc, char **argv) +{ + if(strcmp(argv[1], "ready_trx") == 0) { + printf("%d\n", wifi_is_ready_to_transceive((rtw_interface_t)rtw_atoi((u8*)argv[2]))); + } else if(strcmp(argv[1], "is_up") == 0) { + printf("%d\n", wifi_is_up((rtw_interface_t)rtw_atoi((u8*)argv[2]))); + } else if(strcmp(argv[1], "set_mac") == 0) { + printf("%d\n", wifi_set_mac_address(argv[2])); + } else if(strcmp(argv[1], "get_mac") == 0) { + u8 mac[18] = {0}; + wifi_get_mac_address((char*)mac); + printf("%s\n", mac); + } else if(strcmp(argv[1], "ps_on") == 0) { + printf("%d\n", wifi_enable_powersave()); + } else if(strcmp(argv[1], "ps_off") == 0) { + printf("%d\n", wifi_disable_powersave()); +#if 0 //TODO + } else if(strcmp(argv[1], "get_txpwr") == 0) { + int idx; + wifi_get_txpower(&idx); + printf("%d\n", idx); + } else if(strcmp(argv[1], "set_txpwr") == 0) { + printf("%d\n", wifi_set_txpower(rtw_atoi((u8*)argv[2]))); +#endif + } else if(strcmp(argv[1], "get_clientlist") == 0) { + int client_number; + struct { + int count; + rtw_mac_t mac_list[3]; + } client_info; + + client_info.count = 3; + + printf("%d\n", wifi_get_associated_client_list(&client_info, sizeof(client_info))); + + if( client_info.count == 0 ) + { + RTW_API_INFO(("Clients connected 0..\r\n")); + } + else + { + RTW_API_INFO(("Clients connected %d..\r\n", client_info.count)); + for( client_number=0; client_number < client_info.count; client_number++ ) + { + RTW_API_INFO(("------------------------------------\r\n")); + RTW_API_INFO(("| %d | "MAC_FMT" |\r\n", + client_number, + MAC_ARG(client_info.mac_list[client_number].octet) + )); + } + RTW_API_INFO(("------------------------------------\r\n")); + } + } else if(strcmp(argv[1], "get_apinfo") == 0) { + rtw_bss_info_t ap_info; + rtw_security_t sec; + if(wifi_get_ap_info(&ap_info, &sec) == RTW_SUCCESS) { + RTW_API_INFO( ("\r\nSSID : %s\r\n", (char*)ap_info.SSID ) ); + RTW_API_INFO( ("BSSID : "MAC_FMT"\r\n", MAC_ARG(ap_info.BSSID.octet)) ); + RTW_API_INFO( ("RSSI : %d\r\n", ap_info.RSSI) ); + //RTW_API_INFO( ("SNR : %d\r\n", ap_info.SNR) ); + RTW_API_INFO( ("Beacon period : %d\r\n", ap_info.beacon_period) ); + RTW_API_INFO( ( "Security : %s\r\n", ( sec == RTW_SECURITY_OPEN ) ? "Open" : + ( sec == RTW_SECURITY_WEP_PSK ) ? "WEP" : + ( sec == RTW_SECURITY_WPA_TKIP_PSK ) ? "WPA TKIP" : + ( sec == RTW_SECURITY_WPA_AES_PSK ) ? "WPA AES" : + ( sec == RTW_SECURITY_WPA2_AES_PSK ) ? "WPA2 AES" : + ( sec == RTW_SECURITY_WPA2_TKIP_PSK ) ? "WPA2 TKIP" : + ( sec == RTW_SECURITY_WPA2_MIXED_PSK ) ? "WPA2 Mixed" : + "Unknown" ) ); + } + } else if(strcmp(argv[1], "reg_mc") == 0) { + rtw_mac_t mac; + sscanf(argv[2], MAC_FMT, (int*)(mac.octet+0), (int*)(mac.octet+1), (int*)(mac.octet+2), (int*)(mac.octet+3), (int*)(mac.octet+4), (int*)(mac.octet+5)); + printf("%d\n", wifi_register_multicast_address(&mac)); + } else if(strcmp(argv[1], "unreg_mc") == 0) { + rtw_mac_t mac; + sscanf(argv[2], MAC_FMT, (int*)(mac.octet+0), (int*)(mac.octet+1), (int*)(mac.octet+2), (int*)(mac.octet+3), (int*)(mac.octet+4), (int*)(mac.octet+5)); + printf("%d\n", wifi_unregister_multicast_address(&mac)); + } else if(strcmp(argv[1], "get_rssi") == 0) { + int rssi = 0; + wifi_get_rssi(&rssi); + printf("wifi_get_rssi: rssi = %d\n", rssi); + } else { + printf("Unknown CMD\n"); + } +} + +typedef struct _cmd_entry { + char *command; + void (*function)(int, char **); +} cmd_entry; + +static const cmd_entry cmd_table[] = { +#if CONFIG_WLAN + {"wifi_connect", cmd_wifi_connect}, + {"wifi_connect_bssid", cmd_wifi_connect_bssid}, + {"wifi_disconnect", cmd_wifi_disconnect}, + {"wifi_info", cmd_wifi_info}, + {"wifi_on", cmd_wifi_on}, + {"wifi_off", cmd_wifi_off}, + {"wifi_ap", cmd_wifi_ap}, + {"wifi_scan", cmd_wifi_scan}, +#if SCAN_WITH_SSID + {"wifi_scan_with_ssid", cmd_wifi_scan_with_ssid}, +#endif + {"iwpriv", cmd_wifi_iwpriv}, + {"wifi_promisc", cmd_promisc}, +#if CONFIG_OTA_UPDATE + {"wifi_update", cmd_update}, +#endif +#if CONFIG_WEBSERVER + {"wifi_start_webserver", cmd_wifi_start_webserver}, +#endif +#if (CONFIG_INCLUDE_SIMPLE_CONFIG) + {"wifi_simple_config", cmd_simple_config}, +#endif +#ifdef CONFIG_WPS +#if CONFIG_ENABLE_WPS + {"wifi_wps", cmd_wps}, +#endif +#ifdef CONFIG_WPS_AP + {"wifi_ap_wps", cmd_ap_wps}, +#endif +#if CONFIG_ENABLE_P2P + {"wifi_p2p_start", cmd_wifi_p2p_start}, + {"wifi_p2p_stop", cmd_wifi_p2p_stop}, + {"p2p_find", cmd_p2p_find}, + {"p2p_info", cmd_p2p_info}, + {"p2p_disconnect", cmd_p2p_disconnect}, + {"p2p_connect", cmd_p2p_connect}, +#endif +#endif +#ifdef CONFIG_CONCURRENT_MODE + {"wifi_sta_ap",cmd_wifi_sta_and_ap}, +#endif + +#if CONFIG_SSL_CLIENT + {"ssl_client", cmd_ssl_client}, +#endif +#if CONFIG_GOOGLENEST + {"gn", cmd_googlenest}, +#endif + +#endif +#if CONFIG_LWIP_LAYER +// {"app", cmd_app}, + {"wifi_debug", cmd_debug}, +#if CONFIG_BSD_TCP + {"tcp", cmd_tcp}, + {"udp", cmd_udp}, +#endif +#if CONFIG_JD_SMART + {"jd_smart", cmd_jd_smart}, +#endif + {"ping", cmd_ping}, +#endif +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + {"cpu", cmd_cpustat}, +#endif +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) + {"dw", cmd_dump_reg}, + {"ew", cmd_edit_reg}, +#endif + {"exit", cmd_exit}, + {"help", cmd_help} +}; + +#if CONFIG_INTERACTIVE_EXT +/* must include here, ext_cmd_table in wifi_interactive_ext.h uses struct cmd_entry */ +#include +#endif + +static void cmd_help(int argc, char **argv) +{ + int i; + + printf("COMMAND LIST:\n"); + printf("==============================\n"); + + for(i = 0; i < sizeof(cmd_table) / sizeof(cmd_table[0]); i ++) + printf("\t%s\n", cmd_table[i].command); +#if CONFIG_INTERACTIVE_EXT + for(i = 0; i < sizeof(ext_cmd_table) / sizeof(ext_cmd_table[0]); i ++) + printf("\t%s\n", ext_cmd_table[i].command); +#endif +} + +#define MAX_ARGC 6 + +static int parse_cmd(char *buf, char **argv) +{ + int argc = 0; + + memset(argv, 0, sizeof(argv)*MAX_ARGC); + while((argc < MAX_ARGC) && (*buf != '\0')) { + argv[argc] = buf; + argc ++; + buf ++; + + while((*buf != ' ') && (*buf != '\0')) + buf ++; + + while(*buf == ' ') { + *buf = '\0'; + buf ++; + } + // Don't replace space + if(argc == 1){ + if(strcmp(argv[0], "iwpriv") == 0){ + if(*buf != '\0'){ + argv[1] = buf; + argc ++; + } + break; + } + } + } + + return argc; +} + +char uart_buf[64]; +void interactive_mode(void *param) +{ + int i, argc; + char *argv[MAX_ARGC]; + extern xSemaphoreHandle uart_rx_interrupt_sema; + + printf("Enter INTERACTIVE MODE\n"); + printf("\n# "); + + while(1){ + while(xSemaphoreTake(uart_rx_interrupt_sema, portMAX_DELAY) != pdTRUE); + + if((argc = parse_cmd(uart_buf, argv)) > 0) { + int found = 0; + + for(i = 0; i < sizeof(cmd_table) / sizeof(cmd_table[0]); i ++) { + if(strcmp((const char *)argv[0], (const char *)(cmd_table[i].command)) == 0) { + cmd_table[i].function(argc, argv); + found = 1; + break; + } + } +#if CONFIG_INTERACTIVE_EXT + if(!found) { + for(i = 0; i < sizeof(ext_cmd_table) / sizeof(ext_cmd_table[0]); i ++) { + if(strcmp(argv[0], ext_cmd_table[i].command) == 0) { + ext_cmd_table[i].function(argc, argv); + found = 1; + break; + } + } + } +#endif + if(!found) + printf("unknown command '%s'\n", argv[0]); + printf("\n[MEM] After do cmd, available heap %d+%d\n", xPortGetFreeHeapSize(), tcm_heap_freeSpace()); + } + + printf("\n# "); + uart_buf[0] = '\0'; + } +} + +void start_interactive_mode(void) +{ +#ifdef SERIAL_DEBUG_RX + if(xTaskCreate(interactive_mode, (char const *)"interactive_mode", STACKSIZE, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); +#else + printf("ERROR: No SERIAL_DEBUG_RX to support interactive mode!\n"); +#endif +} + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +VOID WlanNormal( IN u16 argc, IN u8 *argv[]) +{ + u8 i, j= 0; + u8* pbuf = (u8*)uart_buf; + extern xSemaphoreHandle uart_rx_interrupt_sema; + + memset(uart_buf, 0, sizeof(uart_buf)); + + printf("argc=%d\n", argc); + for(i = 0 ; i < argc ; i++) + { + printf("command element [%d] = %s\n", i, argv[i]); + for(j = 0; j + +/* This include is used to find 8 & 32 bit unsigned integer types */ +#include "rom_wac_brg_types.h" + +/* Use AES encrypt/decrypt in wlan ROM codes */ +#include "rom_aes.h" +extern int aes_set_key( aes_context *ctx, u8 *key, int nbits ); + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define AES_128 /* if a fast 128 bit key scheduler is needed */ +#define AES_192 /* if a fast 192 bit key scheduler is needed */ +#define AES_256 /* if a fast 256 bit key scheduler is needed */ +#define AES_VAR /* if variable key size scheduler is needed */ +#define AES_MODES /* if support is needed for modes */ + +/* The following must also be set in assembler files if being used */ + +#define AES_ENCRYPT /* if support for encryption is needed */ +#define AES_DECRYPT /* if support for decryption is needed */ +#define AES_REV_DKS /* define to reverse decryption key schedule */ + +#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ +#define N_COLS 4 /* the number of columns in the state */ + +/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ +/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ +/* or 44, 52 or 60 32-bit words. */ + +#if defined( AES_VAR ) || defined( AES_256 ) +#define KS_LENGTH 60 +#elif defined( AES_192 ) +#define KS_LENGTH 52 +#else +#define KS_LENGTH 44 +#endif + +#define AES_RETURN INT_RETURN + +/* the character array 'inf' in the following structures is used */ +/* to hold AES context information. This AES code uses cx->inf.b[0] */ +/* to hold the number of rounds multiplied by 16. The other three */ +/* elements can be used by code that implements additional modes */ + +typedef union +{ uint_32t l; + uint_8t b[4]; +} aes_inf; + +typedef struct +{ +#if 0 + uint_32t ks[KS_LENGTH]; +#else + aes_context ctx; +#endif + aes_inf inf; +} aes_encrypt_ctx; + +typedef struct +{ +#if 0 + uint_32t ks[KS_LENGTH]; +#else + aes_context ctx; +#endif + aes_inf inf; +} aes_decrypt_ctx; + +/* This routine must be called before first use if non-static */ +/* tables are being used */ + +AES_RETURN aes_init(void); + +/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ +/* those in the range 128 <= key_len <= 256 are given in bits */ + +#if defined( AES_ENCRYPT ) + +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); +#endif + +#if defined( AES_VAR ) +AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); +#endif + +#if 0 +AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); +#else +extern void aes_encrypt( aes_context *ctx, u8 input[16], u8 output[16] ); +#endif + +#endif + +#if defined( AES_DECRYPT ) + +#if defined( AES_128 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_192 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_256 ) || defined( AES_VAR) +AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); +#endif + +#if defined( AES_VAR ) +AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); +#endif + +#if 0 +AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); +#else +extern void aes_decrypt( aes_context *ctx, u8 input[16], u8 output[16] ); +#endif + +#endif + +#if defined( AES_MODES ) + +/* Multiple calls to the following subroutines for multiple block */ +/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ +/* long messages incremantally provided that the context AND the iv */ +/* are preserved between all such calls. For the ECB and CBC modes */ +/* each individual call within a series of incremental calls must */ +/* process only full blocks (i.e. len must be a multiple of 16) but */ +/* the CFB, OFB and CTR mode calls can handle multiple incremental */ +/* calls of any length. Each mode is reset when a new AES key is */ +/* set but ECB and CBC operations can be reset without setting a */ +/* new key by setting a new IV value. To reset CFB, OFB and CTR */ +/* without setting the key, aes_mode_reset() must be called and the */ +/* IV must be set. NOTE: All these calls update the IV on exit so */ +/* this has to be reset if a new operation with the same IV as the */ +/* previous one is required (or decryption follows encryption with */ +/* the same IV array). */ + +AES_RETURN aes_test_alignment_detection(unsigned int n); + +AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, const aes_decrypt_ctx cx[1]); + +AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); + +AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +#define aes_ofb_encrypt aes_ofb_crypt +#define aes_ofb_decrypt aes_ofb_crypt + +AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *iv, aes_encrypt_ctx cx[1]); + +typedef void cbuf_inc(unsigned char *cbuf); + +#define aes_ctr_encrypt aes_ctr_crypt +#define aes_ctr_decrypt aes_ctr_crypt + +AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, + int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/USDK/component/common/application/apple/WACServer/External/GladmanAES/rom_wac_brg_types.h b/USDK/component/common/application/apple/WACServer/External/GladmanAES/rom_wac_brg_types.h new file mode 100644 index 0000000..e990603 --- /dev/null +++ b/USDK/component/common/application/apple/WACServer/External/GladmanAES/rom_wac_brg_types.h @@ -0,0 +1,229 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + The unsigned integer types defined here are of the form uint_t where + is the length of the type; for example, the unsigned 32-bit type is + 'uint_32t'. These are NOT the same as the 'C99 integer types' that are + defined in the inttypes.h and stdint.h headers since attempts to use these + types have shown that support for them is still highly variable. However, + since the latter are of the form uint_t, a regular expression search + and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') + can be used to convert the types used here to the C99 standard types. +*/ + +#ifndef _BRG_TYPES_H +#define _BRG_TYPES_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#if 0 +#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) +# include +# define ptrint_t intptr_t +#elif defined( __ECOS__ ) +# define intptr_t unsigned int +# define ptrint_t intptr_t +#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) +# include +# define ptrint_t intptr_t +#else +# define ptrint_t int +#endif +#else +# include +# define ptrint_t intptr_t +#ifndef u8 + typedef uint8_t u8; +#endif +#ifndef u32 + typedef uint32_t u32; +#endif +#endif + +#ifndef BRG_UI8 +# define BRG_UI8 +# if UCHAR_MAX == 255u + typedef unsigned char uint_8t; +# else +# error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI16 +# define BRG_UI16 +# if USHRT_MAX == 65535u + typedef unsigned short uint_16t; +# else +# error Please define uint_16t as a 16-bit unsigned short type in brg_types.h +# endif +#endif + +#ifndef BRG_UI32 +# define BRG_UI32 +# if UINT_MAX == 4294967295u +# define li_32(h) 0x##h##u + typedef unsigned int uint_32t; +# elif ULONG_MAX == 4294967295u +# define li_32(h) 0x##h##ul + typedef unsigned long uint_32t; +# elif defined( _CRAY ) +# error This code needs 32-bit data types, which Cray machines do not provide +# else +# error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI64 +# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 + typedef unsigned __int64 uint_64t; +# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 + typedef unsigned __int64 uint_64t; +# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# elif defined( __MVS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned int long long uint_64t; +# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u +# if UINT_MAX == 18446744073709551615u +# define BRG_UI64 +# define li_64(h) 0x##h##u + typedef unsigned int uint_64t; +# endif +# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u +# if ULONG_MAX == 18446744073709551615ul +# define BRG_UI64 +# define li_64(h) 0x##h##ul + typedef unsigned long uint_64t; +# endif +# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u +# if ULLONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif +# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u +# if ULONG_LONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull + typedef unsigned long long uint_64t; +# endif +# endif +#endif + +#if !defined( BRG_UI64 ) +# if defined( NEED_UINT_64T ) +# error Please define uint_64t as an unsigned 64 bit type in brg_types.h +# endif +#endif + +#ifndef RETURN_VALUES +# define RETURN_VALUES +# if defined( DLL_EXPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllexport ) void __stdcall +# define INT_RETURN __declspec( dllexport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllexport__ ) void +# define INT_RETURN __declspec( __dllexport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( DLL_IMPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllimport ) void __stdcall +# define INT_RETURN __declspec( dllimport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllimport__ ) void +# define INT_RETURN __declspec( __dllimport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( __WATCOMC__ ) +# define VOID_RETURN void __cdecl +# define INT_RETURN int __cdecl +# else +# define VOID_RETURN void +# define INT_RETURN int +# endif +#endif + +/* These defines are used to detect and set the memory alignment of pointers. + Note that offsets are in bytes. + + ALIGN_OFFSET(x,n) return the positive or zero offset of + the memory addressed by the pointer 'x' + from an address that is aligned on an + 'n' byte boundary ('n' is a power of 2) + + ALIGN_FLOOR(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not higher than the memory address + pointed to by 'x' ('n' is a power of 2) + + ALIGN_CEIL(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not lower than the memory address + pointed to by 'x' ('n' is a power of 2) +*/ + +#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) +#define ALIGN_FLOOR(x,n) ((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) +#define ALIGN_CEIL(x,n) ((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) + +/* These defines are used to declare buffers in a way that allows + faster operations on longer variables to be used. In all these + defines 'size' must be a power of 2 and >= 8. NOTE that the + buffer size is in bytes but the type length is in bits + + UNIT_TYPEDEF(x,size) declares a variable 'x' of length + 'size' bits + + BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' + bytes defined as an array of variables + each of 'size' bits (bsize must be a + multiple of size / 8) + + UNIT_CAST(x,size) casts a variable to a type of + length 'size' bits + + UPTR_CAST(x,size) casts a pointer to a pointer to a + varaiable of length 'size' bits +*/ + +#define UI_TYPE(size) uint_##size##t +#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x +#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] +#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) +#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/USDK/component/common/application/google/google_nest.h b/USDK/component/common/application/google/google_nest.h new file mode 100644 index 0000000..c98e612 --- /dev/null +++ b/USDK/component/common/application/google/google_nest.h @@ -0,0 +1,23 @@ +#ifndef GOOGLENEST_H +#define GOOGLENEST_H + +#include + +typedef struct { + int socket; + char *host; + ssl_context ssl; +} googlenest_context; + +int gn_connect(googlenest_context *googlenest, char *host, int port); +void gn_close(googlenest_context *googlenest); +int gn_put(googlenest_context *googlenest, char *uri, char *content); +int gn_patch(googlenest_context *googlenest, char *uri, char *content); +int gn_post(googlenest_context *googlenest, char *uri, char *content, unsigned char *out_buffer, size_t out_len); +int gn_get(googlenest_context *googlenest, char *uri, unsigned char *out_buffer, size_t out_len); +int gn_delete(googlenest_context *googlenest, char *uri); +int gn_stream(googlenest_context *googlenest, char *uri); +void google_retrieve_data_hook_callback(void (*callback)(char *)); + +#endif + diff --git a/USDK/component/common/application/jd_joinlink/example_joinlink.c b/USDK/component/common/application/jd_joinlink/example_joinlink.c new file mode 100644 index 0000000..669095c --- /dev/null +++ b/USDK/component/common/application/jd_joinlink/example_joinlink.c @@ -0,0 +1,679 @@ +/*******************************example_joinlink **************************/ + +#include "autoconf.h" +#include "platform_stdlib.h" +#include "wifi_conf.h" +#include "wifi_structures.h" +#include "osdep_service.h" +#include "lwip_netconf.h" +#include "task.h" +#include "joinlink.h" +#include "cJSON.h" + +#include +#include +#include +#include +#include + +#define MASK_SIZE_JOINLINK 3 +#define SOURCE_PORT 101 + +//gloable +static unsigned char cur_channel = 1; +static unsigned char lock_channel = 1; +static _timer timer_handler_phase2; +static _timer timer_handler_phase1; +static u8 joinlink_finished = 0; +static u8 security_type = 0xff; +static u8 jl_rx_flag = 0; +static rtw_scan_result_t *all_channel_scan_result = NULL; +static rtw_scan_result_t *p_result = NULL; +static int all_channel_ret = 0; +static int phase1_finished = 0; +static int phase2_started = 0; +static u32 start_time = 0; +static u32 current_time = 0; +static int idx = 1; +static int phase1_scanned_channel[14]; +static char ap_bssid[6]; +static char aes_key[] = "123456789"; + +static void* pre_scan_sema; +static int ack_socket; +static struct sockaddr_in to_addr; +static struct sockaddr_in from_addr; +static char header_cmd[] = "cmd"; +static cJSON *ack_content = NULL; +extern struct netif xnetif[]; + +void example_joinlink(void); + +static rtw_result_t joinlink_scan_result_handler(rtw_scan_handler_result_t* malloced_scan_result ) +{ + + static int ApNum = 0; + //TODO: add timer of 2s, wf, 1021 + if (malloced_scan_result->scan_complete != RTW_TRUE) { + rtw_scan_result_t* record = &malloced_scan_result->ap_details; + record->SSID.val[record->SSID.len] = 0; /* Ensure the SSID is null terminated */ + ++ApNum; + + if(malloced_scan_result->user_data) + memcpy((void *)((char *)malloced_scan_result->user_data+(ApNum-1)*sizeof(rtw_scan_result_t)), (char *)record, sizeof(rtw_scan_result_t)); + } + // scan finished, wf, 1022 + else + { + rtw_up_sema(&pre_scan_sema); + ApNum = 0; + } + return RTW_SUCCESS; +} + +void* joinlink_all_scan() +{ + int ret = 0; + rtw_scan_result_t *joinlink_scan_buf = NULL; + + if(joinlink_scan_buf != NULL) + free(joinlink_scan_buf); + + joinlink_scan_buf = (rtw_scan_result_t *)malloc(65*sizeof(rtw_scan_result_t)); + if(joinlink_scan_buf == NULL){ + return 0; + } + memset(joinlink_scan_buf, 0, 65*sizeof(rtw_scan_result_t)); + + if((ret = wifi_scan_networks(joinlink_scan_result_handler, joinlink_scan_buf)) != RTW_SUCCESS){ + printf("[ATWS]ERROR: wifi scan failed\n\r"); + free(joinlink_scan_buf); + return 0; + } + return joinlink_scan_buf; +} + +void joinlink_deinit_content() +{ + rtw_del_timer(&timer_handler_phase2); + rtw_del_timer(&timer_handler_phase1); + if(all_channel_scan_result) + { + free(all_channel_scan_result); + all_channel_scan_result = NULL; + } + rtw_free_sema(&pre_scan_sema); + joinlink_deinit(); + + return; +} +static char *jl_itoa(int value) +{ + char *val_str; + int tmp = value, len = 1; + + while((tmp /= 10) > 0) + len ++; + + val_str = (char *) malloc(len + 1); + sprintf(val_str, "%d", value); + + return val_str; +} + +static void get_ip_str(int *ip_int, char *ip_ch) +{ + char *ip_single = NULL; + u8 pos = 0, len = 0; + + for(int i = 0; i < 4; i++) + { + ip_single = jl_itoa(ip_int[i]); + len = strlen(ip_single); + memcpy(ip_ch + pos, ip_single,len); + free(ip_single); + ip_single = NULL; + pos += len; + if(i == 3) + { + *(ip_ch + pos) = 0; + break; + } + *(ip_ch + pos) = '.'; + pos++; + } +} + +static int joinlink_set_ack_content(u8 check_sum) +{ + cJSON_Hooks memoryHook; + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + + if(ack_content != NULL) + { + cJSON_Delete(ack_content); + ack_content = NULL; + } + if((ack_content = cJSON_CreateObject()) != NULL) + { + char mac_str[18]; + u8 pos = 0; + memset(mac_str, 0, sizeof(mac_str)); + for(int i = 0; i < 6; i++) + { + sprintf(mac_str + pos, "%02x", xnetif[0].hwaddr[i]); + pos += 2; + if(i != 5) + mac_str[pos++] = ':'; + } + + cJSON_AddItemToObject(ack_content, "deviceid", cJSON_CreateString(mac_str)); + cJSON_AddItemToObject(ack_content, "code", cJSON_CreateNumber(check_sum)); + } + else + { + printf("create jSON object failure\n"); + return -1; + } + + return 0; +} + +#if 1 + +static void recv_cmd(void *para) +{ + int rev_len = 0; + char pkt_buf[16]; + while(1) + { + vTaskDelay(500); + if((rev_len = recvfrom(ack_socket, pkt_buf, sizeof(pkt_buf), 0, NULL, NULL)) >= 0) + { + if(memcmp(pkt_buf, header_cmd, sizeof(header_cmd)) == 0) + { + printf("received reboot command, restart join_link process\n"); + // do we need to reboot? + example_joinlink(); + close(ack_socket); + break; + } + } + } + vTaskDelete(NULL); + return; +} + +static int send_ack(int *dest_ip, int dest_port, u8 sum) +{ +#if CONFIG_LWIP_LAYER + int ack_transmit_round; + char ip[16]; + char *jsonString = NULL; + int sended_data = 0; + + if(joinlink_set_ack_content(sum) == -1) + return -1; + + jsonString = cJSON_Print(ack_content); + if(jsonString == NULL) + { + printf("json string convert failure\n"); + cJSON_Delete(ack_content); + return -1; + } + + get_ip_str(dest_ip, ip); + + ack_socket = socket(PF_INET, SOCK_DGRAM, IP_PROTO_UDP); + if (ack_socket == -1) { + printf("create socket failure\n"); + return -1; + } + + FD_ZERO(&to_addr); + to_addr.sin_family = AF_INET; + to_addr.sin_port = htons(dest_port); + to_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + FD_ZERO(&from_addr); + from_addr.sin_family = AF_INET; + from_addr.sin_port = htons(SOURCE_PORT); + to_addr.sin_addr.s_addr = inet_addr(ip); + + if(bind(ack_socket, (struct sockaddr *)&from_addr, sizeof(from_addr)) < 0) + { + printf("bind to source port error\n"); + return -1; + } + + for (ack_transmit_round = 0; ack_transmit_round < 5; ack_transmit_round++) { + sended_data = sendto(ack_socket, (unsigned char *)jsonString, strlen(jsonString), 0, (struct sockaddr *) &to_addr, sizeof(struct sockaddr)); + //printf("\r\nAlready send %d bytes data\n", sended_data); + vTaskDelay(100); /* delay 100 ms */ + } + + if(xTaskCreate(recv_cmd, (char const *)"recv_cmd", 1512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); + + close(ack_socket); + if(jsonString) + { + free(jsonString); + jsonString = NULL; + } + cJSON_Delete(ack_content); +#endif + + return 0; +} +#endif +static void remove_filter() +{ + wifi_disable_packet_filter(1); + wifi_disable_packet_filter(2); + wifi_remove_packet_filter(1); + wifi_remove_packet_filter(2); +} + +int joinlink_finish(unsigned char security_type) +{ + int ret = 0; + int retry = 3; + unsigned char pscan_config = 1; + joinlink_result_t result; + rtw_security_t security_mode; + + wifi_set_promisc(RTW_PROMISC_DISABLE,NULL,0); + remove_filter(); + + pscan_config = PSCAN_ENABLE | PSCAN_SIMPLE_CONFIG; + ret = joinlink_get_result(&result); + if (ret == 0) { + printf("get result OK\n"); + //printf("\r\n joinlink get result ok,ssid = %s, pwd = %s,ssid length = %d,pwd length = %d", + // result.ssid, result.pwd, result.ssid_length,result.pwd_length); + } + else{ + printf("joinlink result not get!\n"); + joinlink_deinit_content(); + return -1; + } + //ap security type + switch(security_type){ + case RTW_ENCRYPTION_OPEN: + security_mode = RTW_SECURITY_OPEN; + break; + case RTW_ENCRYPTION_WEP40: + case RTW_ENCRYPTION_WEP104: + security_mode = RTW_SECURITY_WEP_PSK; + break; + case RTW_ENCRYPTION_WPA_TKIP: + case RTW_ENCRYPTION_WPA_AES: + case RTW_ENCRYPTION_WPA2_TKIP: + case RTW_ENCRYPTION_WPA2_AES: + case RTW_ENCRYPTION_WPA2_MIXED: + security_mode = RTW_SECURITY_WPA2_AES_PSK; + break; + case RTW_ENCRYPTION_UNKNOWN: + case RTW_ENCRYPTION_UNDEF: + default: + printf("unknow security mode,connect fail!\n"); + } + +#if 1 + while(1){ + if(wifi_set_pscan_chan(&lock_channel, &pscan_config, 1) < 0){ + printf("ERROR: wifi set partial scan channel fail\n"); + break; + } + printf("wifi_connect\n"); + //printf("ap_bssid: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", ap_bssid[0],ap_bssid[1],ap_bssid[2],ap_bssid[3],ap_bssid[4],ap_bssid[5]); + + + ret = wifi_connect( + NULL, + 0, + (unsigned char *)result.ssid, + security_mode, + (unsigned char *)result.pwd, + 0, + NULL); + + if(ret == RTW_SUCCESS){ + printf("Connect ok!\n"); +#if CONFIG_LWIP_LAYER + /* If not rise priority, LwIP DHCP may timeout */ + vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 3); + /* Start DHCP Client */ + ret = LwIP_DHCP(0, DHCP_START); + vTaskPrioritySet(NULL, tskIDLE_PRIORITY + 1); +#endif + break; + } + if (retry == 0) { + break; + } + + retry--; + } + if(send_ack(result.source_ip, result.source_port, result.sum) != 0) + printf("send ack failure\n"); +#endif + + joinlink_deinit_content(); + return 0; + +} +// handler for phase2 +void timer_handler_phase2_func(void *FunctionContext) +{ + // do not switch channel while handle frames, wf, 1021 + if(jl_rx_flag){ + rtw_set_timer(&timer_handler_phase2, CHANNEL_SWITCH_TIME - 25); + } else { + if(cur_channel >= 13) + {cur_channel = 1;} + else + cur_channel ++; + wifi_set_channel(cur_channel); + rtw_set_timer(&timer_handler_phase2, CHANNEL_SWITCH_TIME); + } + + //printf("phase2:wifi switch channel to %d\n",cur_channel); + return; +} + +// timer handler for the 1st phase, wf, 1022 +void timer_handler_phase1_func(void *FunctionContext) +{ + // do not switch channel while handle frames, wf, 1021 + if(jl_rx_flag){ + rtw_set_timer(&timer_handler_phase1, SSID_SWITCH_TIME - 25); + } + // switch ssid, wf, 1022 + else + { + if(idx >= 14) + { + phase1_finished = 1; + printf("wifi: phase1 scan finished\n"); + printf("wifi: start phase2 scan\n"); +// move from pkt handler to here in case no pkt to trigue phase2 +#if 1 + if(phase1_finished) + { + phase1_finished = 0; + phase2_started = 1; + rtw_cancel_timer(&timer_handler_phase1); + //start phase2 for ch1~ch13 + cur_channel = 1; + wifi_set_channel(cur_channel); + + rtw_init_timer(&timer_handler_phase2, NULL, &timer_handler_phase2_func, NULL, "phase_2"); + rtw_set_timer(&timer_handler_phase2, CHANNEL_SWITCH_TIME); + } +#endif + return; + } + + while(idx < 14) + { + if(phase1_scanned_channel[idx]) + { + wifi_set_channel(idx); + rtw_set_timer(&timer_handler_phase1, SSID_SWITCH_TIME); + //printf("phase1: wifi switch channel to %d\n",idx); + idx++; + break; + } + else + { + if(idx == 13) + rtw_set_timer(&timer_handler_phase1, SSID_SWITCH_TIME); + idx++; + } + + } + + } + return; +} + +static void rtl_frame_recv_handle(unsigned char *buf, int len, unsigned char *da, unsigned char *sa, void *user_data) { + + int ret = 0; + int fixed_channel; + char scanned_ssid[50] = {0}; + unsigned char *current_bssid = NULL; + int scanned_ssid_len = 0; + + //set this flag prevent joinlink_recv interruptted by timer,since timer has higher priority + jl_rx_flag = 1; + if (joinlink_finished) { + jl_rx_flag = 0; + return; + } + + ret = joinlink_recv(da, sa, len, user_data); + if(ret == JOINLINK_STATUS_CHANNEL_LOCKED) + { + if(phase2_started) + { + phase2_started = 0; + rtw_cancel_timer(&timer_handler_phase2); + } + else + rtw_cancel_timer(&timer_handler_phase1); + + lock_channel = cur_channel; + security_type = ((ieee80211_frame_info_t *)user_data)->encrypt; + printf("JoinLink locked to channel[%d]\n",lock_channel); + + current_bssid = buf + 4 + ETH_ALEN; + memcpy(ap_bssid, current_bssid, 6); + + fixed_channel = promisc_get_fixed_channel(current_bssid, scanned_ssid, &scanned_ssid_len); + if (fixed_channel != 0) { + printf("JoinLink force fixed to channel[%d]\r\n",fixed_channel); + printf("JoinLink ssid scanned[%s]\r\n",scanned_ssid); + wifi_set_channel(fixed_channel); + } + + } + else if(ret == JOINLINK_STATUS_COMPLETE){ + //wifi_set_promisc(RTW_PROMISC_DISABLE,NULL,0); + joinlink_finished = 1; + printf("quit promisc mode!\r\n"); + } + //release flag + jl_rx_flag = 0; + + return; +} + + +// callback for promisc packets, like rtk_start_parse_packet in SC, wf, 1021 +void wifi_promisc_rx(unsigned char* buf, unsigned int len, void* user_data) +{ + unsigned char * da = buf; + unsigned char * sa = buf + ETH_ALEN; + + if (joinlink_finished) + return; + + rtl_frame_recv_handle(buf, len, da, sa, user_data); + return; + +} + +// the entry point for joinlink +void joinlink_process(void *param) +{ + + while(1) + { + current_time = xTaskGetTickCount(); + + if(joinlink_finished) + { + printf("joinlink finished\n"); + break; + } + + if((current_time - start_time) > JOINLINK_TIME * configTICK_RATE_HZ) + { + printf("joinlink timeout\n"); + break; + } + + vTaskDelay(500); + } + + joinlink_finish(security_type); + + vTaskDelete(NULL); + return; +} + +int joinlink_init_content() +{ + + int ret = 0; + ret = joinlink_init(); + if(ret < 0){ + printf("JoinLink init failed!\n"); + return ret; + } + memset(phase1_scanned_channel, 0, sizeof(phase1_scanned_channel)); + security_type = 0xff; + cur_channel = 1; + lock_channel = 1; + joinlink_finished = 0; + jl_rx_flag = 0; + p_result = NULL; + all_channel_ret = 0; + phase1_finished = 0; + phase2_started = 0; + idx = 1; + rtw_init_sema(&pre_scan_sema, 0); + memset(ap_bssid, 0, sizeof(ap_bssid)); + set_aes_key(aes_key, sizeof(aes_key) - 1); + + return 0; +} + +// ret:1 indicate suc, else fail +int scan_all_channel() +{ + all_channel_scan_result = (rtw_scan_result_t *)joinlink_all_scan(); + + if(all_channel_scan_result == NULL) + return 0; + else + return 1; + +} + +void get_phase1_channel() +{ + p_result = all_channel_scan_result; + while(p_result->channel) + { + if((p_result->channel >= 1) && (p_result->channel <= 13)) + phase1_scanned_channel[p_result->channel] = 1; + p_result++; + } + return; +} + +// now only accept mcast and bcast pkt +static void filter_add_enable() +{ + u8 mask[MASK_SIZE_JOINLINK]={0xFF,0xFF,0xFF}; + u8 pattern[MASK_SIZE_JOINLINK]={0x01,0x00,0x5e}; + u8 pattern_bcast[MASK_SIZE_JOINLINK]={0xff,0xff,0xff}; + + rtw_packet_filter_pattern_t packet_filter; + rtw_packet_filter_pattern_t packet_filter_bcast; + rtw_packet_filter_rule_e rule; + + packet_filter.offset = 0; + packet_filter.mask_size = 3; + packet_filter.mask = mask; + packet_filter.pattern = pattern; + + packet_filter_bcast.offset = 0; + packet_filter_bcast.mask_size = 3; + packet_filter_bcast.mask = mask; + packet_filter_bcast.pattern = pattern_bcast; + + rule = RTW_POSITIVE_MATCHING; + + wifi_init_packet_filter(); + wifi_add_packet_filter(1, &packet_filter,rule); + wifi_add_packet_filter(2, &packet_filter_bcast,rule); + + wifi_enable_packet_filter(1); + wifi_enable_packet_filter(2); +} + + +void joinlink_start(void *param) +{ + joinlink_finished = 0; + start_time = xTaskGetTickCount(); + + if(xTaskCreate(joinlink_process, (char const *)"JoinLink", 1512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); + + if (joinlink_init_content() < 0) + printf("joinlink init fail!\n"); + while(1) + { + if(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS) + break; + else + vTaskDelay(3000); + } + all_channel_ret = scan_all_channel(); + + if (rtw_down_sema(&pre_scan_sema) == _FAIL) + printf("%s, Take Semaphore Fail\n", __FUNCTION__); + + //printf("\npre scan finished\n"); + + //set wifi to station mode,enable promisc mode and timer to change channel + wifi_enter_promisc_mode(); + filter_add_enable(); + + /* enable all 802.11 packets*/ + wifi_set_promisc(RTW_PROMISC_ENABLE, wifi_promisc_rx, 1); + + //init timer handler,and set timer hanler funcion + if(all_channel_ret) + { + printf("\nstart the phase1 scan\n"); + get_phase1_channel(); + rtw_init_timer(&timer_handler_phase1, NULL, &timer_handler_phase1_func, NULL, "phase1_timer"); + rtw_set_timer(&timer_handler_phase1, SSID_SWITCH_TIME); + } + else + { + printf("phase1 scan fail, start phase2 scan\n"); + rtw_init_timer(&timer_handler_phase2, NULL, &timer_handler_phase2_func, NULL, "phase2_timer"); + wifi_set_channel(cur_channel); + rtw_set_timer(&timer_handler_phase2, CHANNEL_SWITCH_TIME); + } + + vTaskDelete(NULL); + return; +} + +void example_joinlink(void) +{ + if(xTaskCreate(joinlink_start, (char const *)"JoinLink_entry", 1512, NULL, tskIDLE_PRIORITY + 2, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); +} \ No newline at end of file diff --git a/USDK/component/common/application/jd_joinlink/joinlink.c b/USDK/component/common/application/jd_joinlink/joinlink.c new file mode 100644 index 0000000..d576814 --- /dev/null +++ b/USDK/component/common/application/jd_joinlink/joinlink.c @@ -0,0 +1,1100 @@ +/******************************* joinlink **************************/ +//includes +#include "joinlink.h" + +// macro +#define NUM_MCAST 53 // the max len of pkt in mcast, original: 13 +#define NUM_BCAST 36 // the max number of index of bcast +#define HEAD_LEN 9 // sum(1 byte) + pwd_len(1 byte) + port(2 byte) + ip(4 byte) + ssid_len(1 byte) +#define NUM_IDX 10 // number of index in bcast +#define NUM_PKT 4 // number of packets for every index +#define SEQ_INCREMENT_ONE_BCAST 1 // only the increment of 1 in seq of pkt is accepted + +static char smac[6]; +static u8 decoded_state = 0; +static int joinlink_state_mcast = 0; +static int joinlink_state_bcast = 0; +static u8 sync_label_mcast = 0; +static u8 version_mcast = 0; +// every pkt has two byte +static u8 *raw_data_mcast = NULL; +static u8 *decrypted_data_mcast = NULL; +static u8 count_mcast = 0; +static u8 sum_mcast = 0; // the total len of ssid and pwd +static char pass_len = -1; +static u8 ssid_len = 0; +static u8 ssid_offset = 0; +static u8 odd_check = 0; +static u8 total_len_mcast = 0; +static u8 *recved_flag_mcast = NULL; +static u8 range_mcast[NUM_MCAST >> 3]; // the range for aes decryption +static u8 decryp_flag_mcast[NUM_MCAST >> 3]; + +static u8 sync_label_bcast = 0; +static u8 version_bcast_ready = 0; +static u8 version_bcast = 0; +static u8 count_in_idx_bcast = 0; +static u8 count_decoded_bcast = 0; +static unsigned short seq_now_bcast = 0; +static u8 locked_bssid_bcast[6]; +static u8 ssid_offset_bcast = 0; + +// for data phase in bcast +// 0: wating index pkt, 1: waiting info pkt +// TODO: need to fix bssid/ssid for bcast to filter unnecessary pkt +static u8 data_phase_state_bcast = 0; +static u8 *raw_data_bcast = NULL; +static u8 *decrypted_data_bcast = NULL; + +static u8 version_CRC = 0; +static u8 *decoded_flag_bcast = NULL; +static u8 current_idx_bcast = 0; + +static u8 sum_bcast = 0; +static char pass_len_bcast = -1; +static u8 ssid_len_bcast = 0; +static u8 fc_version_bcast = 0; +static u8 fc_data_bcast = 0; +static u8 idx_CRC = 0; +static u8 idx_data = 0; + +//store decode result of AP profile +joinlink_result_t *AP_profile = NULL; + +// AES decryption related +static u8 aes_iv[16]; +static u8 aes_key[16]; +static u8 ssid_range_mcast = 255; +static u8 decryp_data_buf[16]; +/* +ret: 0, success, -1, failure +*/ +int joinlink_init() +{ + decoded_state = 0; + joinlink_state_mcast = 0; + joinlink_state_bcast = 0; + sync_label_mcast = 0; + version_mcast = 0; + + raw_data_mcast = (u8 *)malloc(NUM_MCAST*2); + decrypted_data_mcast = (u8 *)malloc(NUM_MCAST*2); + recved_flag_mcast = (u8 *)malloc(NUM_MCAST); + raw_data_bcast = (u8 *)malloc(NUM_BCAST*NUM_PKT); + decrypted_data_bcast = (u8 *)malloc(NUM_BCAST*NUM_PKT); + decoded_flag_bcast = (u8 *)malloc(NUM_BCAST); + AP_profile = (joinlink_result_t *)malloc(sizeof(joinlink_result_t)); + + if(!raw_data_mcast || !decrypted_data_mcast || !recved_flag_mcast|| + !raw_data_bcast || !decrypted_data_bcast || !decoded_flag_bcast|| + !AP_profile) + { + printf("join_link: malloc memory fail\n"); + return -1; + } + + memset(raw_data_mcast, 0, NUM_MCAST*2); + count_mcast = 0; + sum_mcast = 0; + pass_len = -1; + ssid_len = 0; + ssid_offset = 0; + odd_check = 0; + total_len_mcast = 0; + memset(recved_flag_mcast, 0, NUM_MCAST); + + sync_label_bcast = 0; + version_bcast_ready = 0; + version_bcast = 0; + seq_now_bcast = 0; + memset(locked_bssid_bcast, 0, sizeof(locked_bssid_bcast)); + + data_phase_state_bcast = 0; + memset(raw_data_bcast, 0, NUM_BCAST*NUM_PKT); + version_CRC = 0; + count_in_idx_bcast = 0; + count_decoded_bcast = 0; + memset(decoded_flag_bcast, 0, NUM_BCAST); + current_idx_bcast = 0; + sum_bcast = 0; + pass_len_bcast = -1; + ssid_len_bcast = 0; + fc_version_bcast = 0; + fc_data_bcast = 0; + idx_CRC = 0; + idx_data = 0; + + memset(AP_profile, 0, sizeof(joinlink_result_t)); + memset(smac, 0, sizeof(smac)); + + memset(aes_iv, 0, sizeof(aes_iv)); + memset(aes_key, 0, sizeof(aes_key)); + memset(range_mcast, 0, sizeof(range_mcast)); + memset(decryp_flag_mcast, 0, sizeof(decryp_flag_mcast)); + ssid_range_mcast = 255; + memset(decrypted_data_mcast, 0, NUM_MCAST*2); + memset(decryp_data_buf, 0, sizeof(decryp_data_buf)); + memset(decrypted_data_bcast, 0, NUM_BCAST*NUM_PKT); + ssid_offset_bcast = 0; + + return 0; +} + +// set the aes_key, the max len should be 16 +int set_aes_key(char *key, int len) +{ + if (len <= 0 || len > 16) + return 0; + + memcpy(aes_key, key, len); + if (rtl_crypto_aes_cbc_init(aes_key, sizeof(aes_key)) != 0) + { + printf("AES CBC init failed\n"); + return 0; + } + printf("the AES key is set to %s\n", aes_key); + return 1; +} +// free memory +void joinlink_deinit() +{ + free(raw_data_mcast); + free(decrypted_data_mcast); + free(recved_flag_mcast); + free(raw_data_bcast); + free(decrypted_data_bcast); + free(decoded_flag_bcast); + free(AP_profile); + + raw_data_mcast = NULL; + decrypted_data_mcast = NULL; + recved_flag_mcast = NULL; + raw_data_bcast = NULL; + decrypted_data_bcast = NULL; + decoded_flag_bcast = NULL; + AP_profile = NULL; + + return; +} +// restart joinlink when error +static void joinlink_restart() +{ + joinlink_deinit(); + joinlink_init(); + return; +} +/* +ret: 0, failure; 1 true. +*/ +static int check_sync_mcast(u8 *da) +{ + if((da[3] == 0) && (da[4] == 1) && (da[5] >= 1) && (da[5] <= 3)) + { + sync_label_mcast |= 0x01 << (da[5] - 1); + if(sync_label_mcast == 0x07) + return 1; + else + return 0; + } + else + return 0; +} +// ret: 0, failure; 1 true +static int check_version_mcast(u8 *da) +{ + // 239.0.{Version}.4 + if((da[3] == 0) && (da[5] == 4)) + { + version_mcast = da[4]; + return 1; + } + else + return 0; +} + +static u8 getCrc(u8 *ptr, u8 len) +{ + u8 crc; + u8 i; + crc = 0; + while (len--) + { + crc ^= *ptr++; + for (i = 0; i < 8; i++) + { + if (crc & 0x01) + { + crc = (crc >> 1) ^ 0x8C; + } + else + crc >>= 1; + } + } + return crc; +} +// check whether received enough pkt to decrypt +static u8 decryp_ready(u8 range) +{ + int first = (range << 3) + 1; + u8 count = 0; + while(count < 8) + { + if(!recved_flag_mcast[first + count]) + return 0; + ++count; + } + return 1; +} +// ret: 0 suc, ret: -1 failure +static int decryp_data(u8 decryp_range) +{ + // before decryption dump + memset(decryp_data_buf, 0, sizeof(decryp_data_buf)); + + // this decrpytion API only accept 16 byte size + if (rtl_crypto_aes_cbc_decrypt(raw_data_mcast + (decryp_range << 4), 16, aes_iv, sizeof(aes_iv), decryp_data_buf) != 0 ) + { + printf("AES CBC decrypt failed\n"); + return -1; + } + memcpy(decrypted_data_mcast + (decryp_range << 4), decryp_data_buf, 16); + // dump encrypted and decrypted data +#if 0 + printf("range %d encryp data:", decryp_range); + for(int i = 0; i < 16; i++) + printf("0x%02x ", raw_data_mcast[(decryp_range << 4) + i]); + printf("\n"); + + printf("range %d decrypted to:", decryp_range); + for(int i = 0; i < 16; i++) + printf("0x%02x ", decrypted_data_mcast[(decryp_range << 4) + i]); + printf("\n"); +#endif + return 0; +} + +// for aes_cbc, need to remove the chain using xor +static void dechain_aes_mcast(u8 range) +{ + if(range != 0) + { + for(int i = 0; i < 16; i++) + decrypted_data_mcast[(range << 4) + i] ^= raw_data_mcast[(range - 1 << 4) + i]; + } + // dump data +#if 0 + printf("range %d dechained to: ", range); + for(int i = 0; i < 16; i++) + printf("0x%02x ", decrypted_data_mcast[(range << 4) + i]); + printf("\n"); +#endif + printf("mcast: block %d is dechained\n", range); + decryp_flag_mcast[range] = 2; + count_mcast += 8; + return; +} +/* +ret: 1, enough data; 0 error or not enough +239.{index}.{byte[i]}{byte[i+1]} +{index} = (CRCLSB*3bit) + (Index*5bit) +*/ +static int check_data_mcast(u8 *da) +{ + u8 raw_index = da[3]; + u8 CRC_index = (raw_index & 0x40) >> 6; + u8 idx = raw_index & 0x3f; + u8 first, second; + u8 range = 0; + int first_in_range = 0; + // check CRC + + // idx is invalid, start with 1 + if((idx > NUM_MCAST) || (idx < 1)) + return 0; + + // CRC check pass + if(((da[4] ^ da[5]) & 0x01) == CRC_index) + { + // already received + if(recved_flag_mcast[idx] == 1) + return 0; + + // new pkt + recved_flag_mcast[idx] = 1; + first = (idx -1) * 2; + second = first + 1; + + raw_data_mcast[first] = da[4]; + raw_data_mcast[second] = da[5]; + printf("mcast: new pkt, idx is %d\n", idx); + // range begins with 0, every 8 pkts belongs to 1 range,e.g idx: {1~8} -> range:0 + range = (idx - 1) >> 3; + // not enough pkt for decryption + if(!decryp_ready(range)) + return 0; + // start to decrypt + first_in_range = range << 4; + if(decryp_data(range) == -1) + { + // clear the received flag for this range + for (int i = 1; i < 9; i++) + recved_flag_mcast[first_in_range + i] = 0; + printf("decryped error in range %d\n",range); + return 0; + } + // decryption success here; + decryp_flag_mcast[range] = 1; + printf("mcast: block %d is decrypted\n", range); + + // this is the sum and pass_len + //if((idx == 1) && (!sum_mcast)) + if(range == 0) + { + dechain_aes_mcast(range); + + sum_mcast = decrypted_data_mcast[0]; + pass_len = decrypted_data_mcast[1]; + printf("mcast: sum_mcast 0x%02x pass_len %d \n",sum_mcast, pass_len); + + // check whether the pass_len is valid + if(pass_len < 0 || pass_len > 64) + { + printf("mcast: pass_len is wrong, clear\n"); + decryp_flag_mcast[range] = 0; + count_mcast -= 8; + for (int i = 1; i < 9; i++) + recved_flag_mcast[first_in_range + i] = 0; + return 0; + } + + // printf("[DEBUG]_mcast: the 2nd flag is %d\n", decryp_flag_mcast[range + 1]); + // check whether 2nd block is ready + if(decryp_flag_mcast[range + 1] == 1) + { + printf("here\n"); + dechain_aes_mcast(range + 1); + } + + if((pass_len & 0x01) == 0) + odd_check = 2; // even + else + odd_check = 1; // odd + // get the idx of pkt which contains the ssid_len info + ssid_offset = 1 + (u8)((8 + pass_len)/2); + ssid_range_mcast = (ssid_offset - 1) >> 3; + printf("ssid_offset %d ssid_range_mcast %d\n",ssid_offset, ssid_range_mcast); +#if 1 + // already dechained + if(decryp_flag_mcast[ssid_range_mcast] == 2) + { + if(total_len_mcast == 0) + { + if(ssid_len == 0) + { + if(odd_check == 2) + ssid_len = decrypted_data_mcast[2 * (ssid_offset - 1)]; + if(odd_check == 1) + ssid_len = decrypted_data_mcast[2 * (ssid_offset - 1) + 1]; + printf("ssid_len is %d\n",ssid_len); + } + total_len_mcast = (u8)((pass_len + ssid_len + HEAD_LEN + 1)/2); + printf("total_len_mcast is recalculated as %d\n",total_len_mcast); + } + } +#endif + } + // need to dechain for the 2nd and following block + else + { + if(decryp_flag_mcast[range - 1] > 0) + dechain_aes_mcast(range); + + if(decryp_flag_mcast[range + 1] == 1) + dechain_aes_mcast(range + 1); + + if(!decryp_flag_mcast[range - 1] && !decryp_flag_mcast[range + 1]) + return 0; + } + // 8 new pkts has been de chained for AES + + // set the ssid_len + if(ssid_range_mcast != 255 && decryp_flag_mcast[ssid_range_mcast] == 2) + { + if(ssid_len == 0) + { + if(odd_check == 2) + ssid_len = decrypted_data_mcast[2 * (ssid_offset - 1)]; + if(odd_check == 1) + ssid_len = decrypted_data_mcast[2 * (ssid_offset - 1) + 1]; + printf("ssid_len is %d\n",ssid_len); + } + } + + // set the total_len + if((pass_len != -1) && (ssid_len != 0)) + { + if(total_len_mcast == 0) + { + total_len_mcast = (u8)((pass_len + ssid_len + HEAD_LEN + 1)/2); + printf("total_len_mcast is calculated as %d\n",total_len_mcast); + } + } + + printf("total_len needed is %d already decrypted %d\n", total_len_mcast, count_mcast); + + if(!total_len_mcast) + { + if(count_mcast >= NUM_MCAST) + return 1; + else + return 0; + } + else + { + //printf("count_mcast is %d total_len_mcast is %d\n"); + if(count_mcast >= total_len_mcast) + { + // check CRC + u8 crc_ret = 0; + printf("enough decrypted pkt, start to check sum\n"); + if((pass_len + ssid_len) & 0x01) + crc_ret = getCrc(decrypted_data_mcast + 1, total_len_mcast * 2 - 1); + else + crc_ret = getCrc(decrypted_data_mcast + 1, total_len_mcast * 2 - 2); + + if(crc_ret == sum_mcast) + {printf("sum check pass\n"); return 1;} + else + { + printf("sum crc check failure, restart\n"); + joinlink_restart(); // fine tune: only restart the mcast part + return 0; + } + } + else + return 0; + } + } + // check CRC failure + else + { + //printf("CRC failure in mcast, getCrc is 0x%02x, CRC is 0x%02x\n",(da[4] ^ da[5]), CRC_index); + return 0; + } + +} +/* +ret: 0, failure; 1 true. +*/ +static int check_sync_bcast(int len) +{ + // make sure the bits larger than 9 is 0 + if(len >= 256) + return 0; + // only the least 9 bits are useful + len &= 0x01ff; + if((len >=1) && (len <=4)) + { + sync_label_bcast |= 0x01 << (len - 1); + if(sync_label_bcast == 0x0f) + return 1; + else + return 0; + } + else + return 0; +} + +/* +{0b10000*5bit}+{CRCLSB*4bit} +{0*1bit}{Version} + ret: 0, failure; 1 true + */ +static int check_version_bcast(int len, u8 i_fc) +{ + version_bcast = 0; + + if(!version_bcast_ready) + { + u8 version_pre_CRC = len & 0x0007; + u8 version_pre_data = (len & 0x01f8) >> 3; + + if(len >= 512) + return 0; + + if(version_pre_data == 0x20) + { + version_bcast_ready = 1; + version_CRC = version_pre_CRC; + // fix the direction(fromDS/toDS) to receive version info + fc_version_bcast = i_fc; + +// printf("get the CRC of version, change to wait version state\n"); + } + + return 0; + } + else + { + if(i_fc != fc_version_bcast) + return 0; + + if((len & 0xff00) != 0) + return 0; + + version_bcast = len & 0x00ff; + if((getCrc(&version_bcast,1) & 0x07) == version_CRC) + { + printf("version CRC pass\n"); + return 1; + } + else + { + //printf("version CRC failure,reset this state, version is 0x%02x calculated CRC is 0x%02x, CRC is 0x%02x\n", + // version_bcast, getCrc(&version_bcast,1), version_CRC); + version_bcast_ready = 0; + } + + } + return 0; +} + +/*ret 1: valid seq, ret 0: invalid seq*/ +static u8 check_and_update_seq(unsigned short frame_seq) +{ + int seq_delta = frame_seq - seq_now_bcast; + +#if SEQ_INCREMENT_ONE_BCAST + if((seq_delta == 1) || (seq_now_bcast == 4095) && (frame_seq == 0)) + { + seq_now_bcast = frame_seq; + return 1; + } + else + { + seq_now_bcast = frame_seq; + return 0; + } +#else + if(((seq_delta <= 10) && (seq_delta >= 0)) || + ((seq_now_bcast > 4085) && (seq_delta + 4096 <= 10) && (seq_delta + 4096 >= 0))) + { + seq_now_bcast = frame_seq; + //printf("valid seq, seq_delta %d seq_now is updated to %d\n", seq_delta, seq_now_bcast); + return 1; + } + else + { + seq_now_bcast = frame_seq; + //printf("invalid seq, seq_delta %d seq_now is updated to %d\n", seq_delta, seq_now_bcast); + return 0; + } +#endif +} +// idx starts with 1, every 4 is one decryption block +static int decryp_ready_bcast(u8 first_idx) +{ + for(int i = 0; i < 4; i++) + { + if(decoded_flag_bcast[first_idx + i] == 0) + return 0; + } + return 1; +} +// decryption for bcast +static int decryp_data_bcast(u8 idx) +{ + memset(decryp_data_buf, 0, sizeof(decryp_data_buf)); +// dump the encryption info +#if 0 + printf("before decryption of idx %d:", idx); + for(int i = 0; i < 16; i++) + printf("0x%02x ", raw_data_bcast[((idx >> 2) << 4) + i]); + printf("\n"); +#endif + + // this decrpytion API only accept 16 byte size + if (rtl_crypto_aes_cbc_decrypt(raw_data_bcast + ((idx >> 2) << 4), 16, aes_iv, sizeof(aes_iv), decryp_data_buf) != 0 ) + { + printf("AES CBC decrypt failed\n"); + return -1; + } + memcpy(decrypted_data_bcast + ((idx >> 2) << 4), decryp_data_buf, 16); + printf("bcast: blcok %d is decrypted\n", idx >> 2); +// dump the info after decryption +#if 0 + printf("after decryption of idx %d:", idx); + for(int i = 0; i < 16; i++) + printf("0x%02x ", decrypted_data_bcast[((idx >> 2) << 4) + i]); + printf("\n"); +#endif + + return 0; +} +// remove chain for aes cbc for bcast mode +static void dechain_aes_bcast(u8 idx) +{ + u8 first_idx = (idx >> 2) << 4; + if(idx != 1) + { + for(int i = 0; i < 16; i++) + decrypted_data_bcast[first_idx + i] ^= raw_data_bcast[first_idx - 16 + i]; + } + count_decoded_bcast += 4; + // set the dechained flag + for(int i = 0; i < 4; i++) + decoded_flag_bcast[idx + i] = 3; + // dump the info after dechain +#if 0 + printf("idx %d is de chained to: ", idx); + for(int i = 0; i < 16; i++) + printf("0x%02x ", decrypted_data_bcast[first_idx + i]); + printf("\n"); +#endif + printf("bcast: block %d is dechained\n", idx >> 2); + return; +} + +/* +{EncodeIndex*5bit}+{CRCLSB*4bit} +{0*1bit}{Byte(i+0) *8bit} +{0*1bit}{Byte(i+1) *8bit} +{0*1bit}{Byte(i+2) *8bit} +{0*1bit}{Byte(i+3) *8bit} +*/ +static int check_data_bcast(int len, u8 i_fc, unsigned short frame_seq, unsigned const char *temp_bssid) +{ + // waiting index pkt + if(!data_phase_state_bcast) + { + + // make sure the 9th bit is 1 and bit larger than 9 is 0 + if(((len & 0x0fff) >= 512) || ((len & 0x0fff) <= 256)) + return 0; + // idx_data is increase from 1, not 0 + idx_data = (len & 0x00f8) >> 3; + if(idx_data == 0) + return 0; + + if(idx_data > NUM_BCAST) + { + printf("index is too large\n"); + return 0; + } + + // already decoded this idx + if(decoded_flag_bcast[idx_data] >= 1) + return 0; + else + { + current_idx_bcast = idx_data; + count_in_idx_bcast = 0; + data_phase_state_bcast = 1; + idx_CRC = len & 0x0007; + seq_now_bcast = frame_seq; + //printf("idx_CRC is 0x%02x len is 0x%02x\n",idx_CRC, len); + fc_data_bcast = i_fc; + //printf("waiting data pkt of idx %d, locked in i_fc %d, seq_now %d\n", + // current_idx_bcast,fc_data_bcast,seq_now_bcast); + return 0; + } + + } + // waiting info pkt + else + { + u8 array_idx = 0; + // check whether the data is valid, the 9th bit should be 0 + if(len >= 256) + { + //printf("not info pkt\n"); + return 0; + } + + // only receive the data from the previous idx direction + if(i_fc != fc_data_bcast) + return 0; + + array_idx = 4 * (current_idx_bcast - 1); + + //printf("from bssid 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + // temp_bssid[0],temp_bssid[1],temp_bssid[2],temp_bssid[3],temp_bssid[4],temp_bssid[5]); + // check whether seq is valid + if(check_and_update_seq(frame_seq) == 0) + { + //memset(raw_data_bcast + array_idx, 0, 4); + data_phase_state_bcast = 0; + return 0; + } + + raw_data_bcast[array_idx + count_in_idx_bcast] = len & 0x00ff; + count_in_idx_bcast++; + + //printf("len 0x%02x, info 0x%02x, i_fc %d i_seq %d\n",len, len & 0x00ff, i_fc, frame_seq); + if(count_in_idx_bcast != NUM_PKT) + return 0; + else + { + u8 temp_ret = 0; + u8 first_idx = 0; + +#if 0 + printf("enough data pkt for idx, check CRC\n",current_idx_bcast); + printf("data to be decoded in idx %d: 0x%02x 0x%02x 0x%02x 0x%02x\n",current_idx_bcast, + *(raw_data_bcast + array_idx),*(raw_data_bcast + array_idx + 1), + *(raw_data_bcast + array_idx + 2),*(raw_data_bcast + array_idx + 3)); +#endif + + // assume first encryption and then CRC, so CRC check first and then decryption for receiver. + temp_ret = getCrc(raw_data_bcast + array_idx, 4) & 0x07; + //printf("calculated CRC is 0x%02x true CRC is 0x%02x\n",temp_ret, idx_CRC); + // CRC pass + if(temp_ret == idx_CRC) + { + printf("bcast: idx %d is decoded\n",current_idx_bcast); + // the first idx in every decryption block + first_idx = 1 + ((current_idx_bcast - 1 >> 2) << 2); + // set the flag of this idx to 1, indicate pass CRC but not yet to decrypt + decoded_flag_bcast[current_idx_bcast] = 1; + // not enough neighbor idx for decryption + if(decryp_ready_bcast(first_idx) == 0) + return 0; + + if(decryp_data_bcast(first_idx) == -1) + { + for(int i = 0; i < 4; i++) + decoded_flag_bcast[first_idx + i] = 0; + // clear the 4 idx data in this block; + memset(raw_data_bcast + ((current_idx_bcast - 1 >> 2) << 4), 0, 16); + data_phase_state_bcast = 0; + return 0; + } + // decryption PASS + // set the decryption flag + for(int i = 0; i < 4; i++) + decoded_flag_bcast[first_idx + i] = 2; + + // if 1st block, get the pass_len + if(current_idx_bcast <= 4) + { + dechain_aes_bcast(first_idx); + sum_bcast = *decrypted_data_bcast; + pass_len_bcast = *(decrypted_data_bcast + 1); + // make sure the pass len is in the right range {0,63} + if((pass_len_bcast > 63) || (pass_len_bcast < 0)) + { + printf("pass_len is wrong, clear\n"); + for(int i = 0; i < 4; i++) + decoded_flag_bcast[first_idx + i] = 0; + count_decoded_bcast -= 4; + // clear the 4 idx data in this block; + memset(raw_data_bcast + ((current_idx_bcast - 1 >> 2) << 4), 0, 16); + data_phase_state_bcast = 0; + return 0; + } + printf("sum_bcast is %d pass_len_bcast is %d\n",sum_bcast, pass_len_bcast); + // recalculate ssid_len if the idx containning ssid_len is already decoded + + // to de chain the neighbor block + if(decryp_ready_bcast(first_idx + 4)) + dechain_aes_bcast(first_idx + 4); + + ssid_offset_bcast = (8 + pass_len_bcast)/4 + 1; + if(decoded_flag_bcast[ssid_offset_bcast] == 3) + { + ssid_len_bcast = *(decrypted_data_bcast + 8 + pass_len_bcast); + // check whether ssid len is in the right range {0,32} + if(ssid_len_bcast > 32) + { + //memset(raw_data_bcast + 4 * (2 + pass_len_bcast/4), 0, 4); + data_phase_state_bcast = 0; + for(int i = 0; i < 4; i++) + decoded_flag_bcast[(ssid_len_bcast - 1 >> 2) + i] = 0; + count_decoded_bcast -= 4; + printf("ssid_len_bcast is wrong, clear idx %d\n", ((8 + pass_len_bcast)/4 + 1)); + return 0; + } + printf("recalculated ssid_len_bcast is %d\n",ssid_len_bcast); + } + } + // for the 2nd and following block, need the preceeding block to de chain + else + { + if(decryp_ready_bcast(first_idx - 4)) + dechain_aes_bcast(first_idx); + + if(decryp_ready_bcast(first_idx + 4)) + dechain_aes_bcast(first_idx + 4); + + if(!decryp_ready_bcast(first_idx - 4) && !decryp_ready_bcast(first_idx + 4)) + return 0; + } + // check whether ssid_len idx has been dechained + for(int i = 0; i < 4; i++) + { + if((pass_len_bcast != -1) && (decoded_flag_bcast[ssid_offset_bcast] == 3)) + { + ssid_len_bcast = *(decrypted_data_bcast + 8 + pass_len_bcast); + // make sure ssid_len is valid in the range {0, 32} + if(ssid_len_bcast > 32) + { + //memset(raw_data_bcast + 4 * (2 + pass_len_bcast/4), 0, 4); + data_phase_state_bcast = 0; + for(int i = 0; i < 4; i++) + decoded_flag_bcast[(ssid_offset_bcast >> 2) << 2 + i + 1] = 0; + count_decoded_bcast -= 4; + printf("ssid_len_bcast is wrong\n"); + return 0; + } + printf("ssid_len_bcast is %d\n",ssid_len_bcast); + break; + } + } + // check whether enough + if((ssid_len_bcast != 0) && (pass_len_bcast != -1)) + { + u8 total_len_bcast = HEAD_LEN + ssid_len_bcast + pass_len_bcast; + printf("needed %d pkt, decoded %d\n",(u8)((total_len_bcast + 3)/4),count_decoded_bcast); + if(count_decoded_bcast >= (u8)((total_len_bcast + 3)/4)) + { + printf("enough decoded packets, start to check sum\n"); + if(getCrc(decrypted_data_bcast + 1,total_len_bcast - 1) == sum_bcast) + { + printf("sum check pass in bcast\n"); + return 1; + } + else + { + //printf("bcast sum check failure, restart\n"); + joinlink_restart(); // fine tune: only restart the bcast part + return 0; + } + } + } + + data_phase_state_bcast = 0; + } + else + { + memset(raw_data_bcast + 4 * (current_idx_bcast - 1), 0, 4); + data_phase_state_bcast = 0; + printf("CRC failure of idx %d\n",current_idx_bcast); + return 0; + } + } + + } + + return 0; +} +/* +ret: 0, failure, 1 true +if success, assign the AP profile to a structure. +*/ +static int decode_AP_profile(u8 *raw_data) +{ + int pos = 0; + + AP_profile->sum = raw_data[pos]; + pos++; + printf("AP_profile: sum %d\n",AP_profile->sum); + + AP_profile->pwd_length = raw_data[pos]; + pos++; + printf("AP_profile: pwd_len %d\n",AP_profile->pwd_length); + + if(AP_profile->pwd_length > 64) + { + printf("the pwd len: %d, larger than 64\n",AP_profile->pwd_length); + return 0; + } + + memcpy(AP_profile->pwd, (raw_data + pos), AP_profile->pwd_length); + pos += AP_profile->pwd_length; + printf("AP_profile: pwd %s\n",AP_profile->pwd); + + AP_profile->source_ip[0] = *(raw_data + pos); + AP_profile->source_ip[1] = *(raw_data + pos + 1); + AP_profile->source_ip[2] = *(raw_data + pos + 2); + AP_profile->source_ip[3] = *(raw_data + pos + 3); + + pos += 4; + printf("AP_profile: sip %d %d %d %d\n",AP_profile->source_ip[0], + AP_profile->source_ip[1], + AP_profile->source_ip[2], + AP_profile->source_ip[3]); + // assume the high byte is the most significant + #if 1 + AP_profile->source_port = ((unsigned int)(*(raw_data + pos + 1)) << 8) | (*(raw_data + pos)); + //printf("port high_part, low_part: %d %d\n", *(raw_data + pos + 1), *(raw_data + pos)); + #endif + + pos += 2; + printf("AP_profile: port %d\n",AP_profile->source_port); + + AP_profile->ssid_length = *(raw_data + pos); + pos++; + printf("AP_profile: ssid_len %d\n",AP_profile->ssid_length); + + if(AP_profile->ssid_length > 64) + { + printf("the ssid len: %d, larger than 64\n",AP_profile->ssid_length); + return 0; + } + memcpy(AP_profile->ssid, (raw_data + pos), AP_profile->ssid_length); + printf("AP_profile: ssid %s\n",AP_profile->ssid); + + return 1; +} + +joinlink_status_t joinlink_recv(u8 *da, u8 *sa, int len, void *user_data) +{ + joinlink_status_t ret; + const ieee80211_frame_info_t *promisc_info = user_data; + // 1 from ds, 2 to ds + u8 i_fc = ((promisc_info->i_fc & 0x0100) == 0x0100)? 2: 1; + unsigned short frame_seq = promisc_info->i_seq; + unsigned const char *temp_bssid = promisc_info->bssid; + + // for mcast + if(!((da[0] == 0xff) && (da[1] == 0xff) && (da[2] == 0xff) && + (da[3] == 0xff) && (da[4] == 0xff) && (da[5] == 0xff))) + { + if(joinlink_state_mcast == 0) + { + if(!check_sync_mcast(da)) + return JOINLINK_STATUS_CONTINUE; + else + { + // TODO: consider to fix source mac here + joinlink_state_mcast = 1; + memcpy(smac, sa, 6); + printf("turn to wait version state\n"); + return JOINLINK_STATUS_CONTINUE; + } + + } + else if(joinlink_state_mcast == 1) + { + // only accept the pkt from fixed source mac + if(memcmp(smac, sa, 6)) + return JOINLINK_STATUS_CONTINUE; + + if(!check_version_mcast(da)) + return JOINLINK_STATUS_CONTINUE; + else + { + joinlink_state_mcast = 2; + printf("mcast version is %d\n",version_mcast); + printf("turn to wait data state\n"); + return JOINLINK_STATUS_CHANNEL_LOCKED; + } + } + else if(joinlink_state_mcast == 2) + { + if(memcmp(smac, sa, 6)) + return JOINLINK_STATUS_CONTINUE; + + if(!check_data_mcast(da)) + return JOINLINK_STATUS_CONTINUE; + else + { + printf("enough packets, start to decode AP profile\n"); + // AP profile has been gotten + if(!decode_AP_profile(decrypted_data_mcast)) + { + printf("decode failure, restart joinlink\n"); + joinlink_restart(); + //TODO: intialize the data structure to restart receive data + return JOINLINK_STATUS_CONTINUE; + } + else + { + decoded_state = 1; + return JOINLINK_STATUS_COMPLETE; + } + } + } + } + // for bcast + else + { + len -= 42; // remove the unnecessary part + + if(joinlink_state_bcast == 0) + { + if(!check_sync_bcast(len)) + return JOINLINK_STATUS_CONTINUE; + else + { + // fix the smac and bssid + memcpy(smac, sa, 6); + memcpy(locked_bssid_bcast, temp_bssid, 6); + joinlink_state_bcast = 1; + printf("change to bcast_state_1, lock channel\n"); + return /*JOINLINK_STATUS_CONTINUE*/JOINLINK_STATUS_CHANNEL_LOCKED; + } + + } + else if(joinlink_state_bcast == 1) + { + if(memcmp(smac, sa, 6) || memcmp(temp_bssid, locked_bssid_bcast, 6)) + return JOINLINK_STATUS_CONTINUE; + + if(!check_version_bcast(len, i_fc)) + return JOINLINK_STATUS_CONTINUE; + else + { + joinlink_state_bcast = 2; + printf("change to bcast_state_2\n"); + return /*JOINLINK_STATUS_CHANNEL_LOCKED*/JOINLINK_STATUS_CONTINUE; + } + } + else if(joinlink_state_bcast == 2) + { + if(memcmp(smac, sa, 6) || memcmp(temp_bssid, locked_bssid_bcast, 6)) + return JOINLINK_STATUS_CONTINUE; + + if(!check_data_bcast(len, i_fc, frame_seq, temp_bssid)) + return JOINLINK_STATUS_CONTINUE; + else + { + // AP profile has been gotten + if(!decode_AP_profile(decrypted_data_bcast)) + { + printf("decode failure, restart joinlink\n"); + //TODO: intialize the data structure to restart receive data + return JOINLINK_STATUS_CONTINUE; + } + else + { + decoded_state = 1; + return JOINLINK_STATUS_COMPLETE; + } + } + } + } + ret = JOINLINK_STATUS_CONTINUE; + return ret; +} + +/* + * copy the decode AP info to user space +* store the AP profile to result; +* ret: 0, success +* ret: -1, failure + */ +int joinlink_get_result(joinlink_result_t *result) +{ + if(decoded_state == 0) + return -1; + else + { + memcpy(result, AP_profile, sizeof(joinlink_result_t)); + return 0; + } +} + + + +/*********************************************************/ diff --git a/USDK/component/common/application/jd_joinlink/joinlink.h b/USDK/component/common/application/jd_joinlink/joinlink.h new file mode 100644 index 0000000..647606f --- /dev/null +++ b/USDK/component/common/application/jd_joinlink/joinlink.h @@ -0,0 +1,64 @@ +/******************************* joinlink **************************/ +#ifndef __JOINLINK_H +#define __JOINLINK_H + +#include "autoconf.h" +#include "platform_stdlib.h" +#include "wifi_conf.h" +#include "wifi_structures.h" +#include "osdep_service.h" +#include "lwip_netconf.h" +#include "task.h" +#include "hal_crypto.h" + +#define SSID_SWITCH_TIME 500 //ssid switch time in phase1,units:ms, 50 +#define CHANNEL_SWITCH_TIME 500 //channel switch time in phase2,units:ms, 50 +#define JOINLINK_TIME 120 //timeout for joinlink process, units: s + +/* + * store AP profile after successfully decode + * SUM +lengthpass+IP+Port+lengthSSID) + */ +typedef struct +{ + unsigned char sum; + unsigned char pwd_length; + char pwd[65]; + int source_ip[4]; + unsigned int source_port; + unsigned char ssid_length; + char ssid[65]; +} joinlink_result_t; + +/* + * return value of joinlink_recv() + */ +typedef enum +{ + JOINLINK_STATUS_CONTINUE = 0, + JOINLINK_STATUS_CHANNEL_LOCKED = 1, + JOINLINK_STATUS_COMPLETE = 2 +} joinlink_status_t; + +//initialize the related data structure +int joinlink_init(); +/* + handler to decode pkt + */ +joinlink_status_t joinlink_recv(unsigned char *da, unsigned char *sa, int len, void *user_data); + +/* + * get the AP profile after decode + */ +int joinlink_get_result(joinlink_result_t *result); + +/* + * set the aes_key, the max len should be 16 + * ret 1: success; ret 0: the len is invalid; + */ +int set_aes_key(char *key, int len); + +// call this after finish join_link process +void joinlink_deinit(); + +#endif //__JOINLINK_H diff --git a/USDK/component/common/application/uart_adapter/uart_adapter.c b/USDK/component/common/application/uart_adapter/uart_adapter.c new file mode 100644 index 0000000..db44023 --- /dev/null +++ b/USDK/component/common/application/uart_adapter/uart_adapter.c @@ -0,0 +1,2251 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" +#include +#include +#include +#include "serial_api.h" +#include "serial_ex_api.h" +#include "uart_adapter.h" +#include "wifi_conf.h" +#include "gpio_api.h" // mbed +#include "gpio_irq_api.h" // mbed +#include "osdep_service.h" +#include "flash_api.h" +#include "device_lock.h" +//#include +#include +#include + +#if CONFIG_UART_SOCKET + +/*********************************************************************** + * Macros * + ***********************************************************************/ + +/*********************************************************************** + * Variables Declarations * + ***********************************************************************/ +char ua_tcp_server_ip[16]; + +_Sema ua_exception_sema; +_Sema ua_print_sema; + +int ua_gpio_irq_happen = 0; +int ua_debug_print_en = 0; +int ua_wifi_connected = 0; +int ua_reconnect_started = 0; +int ua_reconnect_ip_change = 0; + +ua_socket_t *ua_global_socket = NULL; +gpio_irq_t gpio_rx_wake; + +/************************************************************************ + * extern variables * + ************************************************************************/ +extern struct netif xnetif[NET_IF_NUM]; + +extern unsigned char psk_essid[NET_IF_NUM][NDIS_802_11_LENGTH_SSID+4]; +extern unsigned char psk_passphrase[NET_IF_NUM][IW_PASSPHRASE_MAX_SIZE + 1]; +extern unsigned char wpa_global_PSK[NET_IF_NUM][A_SHA_DIGEST_LEN * 2]; + +extern wlan_init_done_ptr p_wlan_uart_adapter_callback; +/************************************************************************ + * extern funtions * + ************************************************************************/ +#if CONFIG_INCLUDE_SIMPLE_CONFIG +extern enum sc_result simple_config_test(rtw_network_info_t *); +extern int init_test_data(char *custom_pin_code); +extern void deinit_test_data(void); +extern void filter_add_enable(); +extern void remove_filter(); +extern void wifi_enter_promisc_mode(); +#endif + +/************************************************************************* +* uart releated * +*************************************************************************/ +#define ____________UART__RELATED____________________ +static void uartadapter_uart_irq(uint32_t id, SerialIrq event) +{ + ua_socket_t *ua_socket = (ua_socket_t *)id; + + if(event == RxIrq) { + ua_socket->uart.recv_buf[ua_socket->uart.pwrite++] = serial_getc(&ua_socket->uart.uart_sobj); + RtlUpSemaFromISR(&ua_socket->uart.action_sema); //up action semaphore + + if(ua_socket->uart.pwrite > (UA_UART_RECV_BUFFER_LEN -1)){ //restart from head if reach tail + ua_socket->uart.pwrite = 0; + ua_socket->uart.overlap = 1; + } + + if(ua_socket->uart.overlap && (ua_socket->uart.pwrite > ua_socket->uart.pread) ){ + ua_socket->uart.miss_cnt ++; + ua_socket->uart.pread = ua_socket->uart.pwrite; //if pwrite overhead pread ,pread is always flow rwrite + } + ua_socket->uart.tick_last_update = xTaskGetTickCountFromISR(); // update tick everytime recved data + ua_socket->uart.rx_cnt ++; + } +} + +static int uartadapter_uart_recv_data(ua_socket_t *ua_socket) +{ + int uart_recv_len = 0; + + UA_SOCKET_CHECK_2(ua_socket); + + ua_socket->uart.tick_current = xTaskGetTickCount(); + while((ua_socket->uart.tick_current -ua_socket->uart.tick_last_update) < (UA_UART_MAX_DELAY_TIME/portTICK_RATE_MS) + || ua_socket->uart.tick_current <= ua_socket->uart.tick_last_update){ + if(!ua_socket->uart.overlap){ + uart_recv_len = ua_socket->uart.pwrite - ua_socket->uart.pread; + }else{ + uart_recv_len = (UA_UART_RECV_BUFFER_LEN - ua_socket->uart.pread) + ua_socket->uart.pwrite; + } + + if(uart_recv_len >= UA_UART_FRAME_LEN){ + return 2; + } + //vTaskDelay(10); + ua_socket->uart.tick_current = xTaskGetTickCount(); + } + + return 1; +} + +int uartadapter_uart_read(ua_socket_t *ua_socket, void *read_buf, size_t size) +{ + int ret = 0; + int read_bytes; + int pread_local,pwrite_local; + char *ptr; + + ua_printf(UA_DEBUG, "==>uart adapter read uart"); + + UA_SOCKET_CHECK_2(ua_socket); + + if(!size || !read_buf){ + ua_printf(UA_ERROR, "inpua error,size should not be null"); + ret = -1; + return ret; + } + + pread_local = ua_socket->uart.pread; + pwrite_local = ua_socket->uart.pwrite; + ptr = (char *)read_buf; + + /*calculate how much data not read */ + if(!ua_socket->uart.overlap){ + ua_socket->uart.recv_bytes = pwrite_local - pread_local; + }else{ + ua_socket->uart.recv_bytes = (UA_UART_RECV_BUFFER_LEN - pread_local) + pwrite_local; + } + + /*decide how much data shoule copy to application*/ + if(size >= ua_socket->uart.recv_bytes ){ + read_bytes = ua_socket->uart.recv_bytes; + ret = ua_socket->uart.recv_bytes; + }else{ + read_bytes = size; + ret = size; + } + + if(!ua_socket->uart.overlap){ + memcpy(ptr, (ua_socket->uart.recv_buf+ pread_local), read_bytes ); + }else { + ua_printf(UA_DEBUG, "uart recv buf is write overlap!"); + if((pread_local + read_bytes) > UA_UART_RECV_BUFFER_LEN){ + memcpy(ptr,(ua_socket->uart.recv_buf+ pread_local),(UA_UART_RECV_BUFFER_LEN-pread_local)); + memcpy(ptr+(UA_UART_RECV_BUFFER_LEN-pread_local), ua_socket->uart.recv_buf,read_bytes-(UA_UART_RECV_BUFFER_LEN- pread_local)); + }else{ + memcpy(ptr,(ua_socket->uart.recv_buf+ pread_local),read_bytes); + } + } + + ua_socket->uart.recv_bytes = 0; + if((pread_local + read_bytes) >= UA_UART_RECV_BUFFER_LEN){ //update pread + ua_socket->uart.pread = (pread_local + read_bytes) - UA_UART_RECV_BUFFER_LEN; + ua_socket->uart.overlap = 0; //clean overlap flags + }else{ + ua_socket->uart.pread = pread_local + read_bytes; + } + + return ret; +} + +int uartadapter_uart_write(ua_socket_t *ua_socket, char *pbuf, size_t size) +{ + int ret = -1; + + UA_SOCKET_CHECK_2(ua_socket); + + if(!size || !pbuf) { + ret = -1; + return ret; + } + + while(RtlDownSema(&ua_socket->uart.dma_tx) == pdTRUE){ + ret = serial_send_stream_dma(&ua_socket->uart.uart_sobj, pbuf, size); + if(ret != HAL_OK){ + ua_printf(UA_ERROR, "uart dma tx error %d!", ret); + RtlUpSema(&ua_socket->uart.dma_tx); + return -1; + }else{ + return 0; + } + } + + return ret; +} + +void uartadapter_uart_send_stream_done(uint32_t id) +{ + ua_socket_t *ua_socket = (ua_socket_t *)id; + + RtlUpSemaFromISR(&ua_socket->uart.dma_tx); +} + +static void uartadapter_uart_rx_thread(void* param) +{ + ua_socket_t *ua_socket = (ua_socket_t *)param; + char *rxbuf = NULL; + int ret =0; + int read_len = 0; + + UA_SOCKET_CHECK(ua_socket); + + rxbuf = pvPortMalloc(UA_UART_FRAME_LEN); + if(NULL == rxbuf){ + ua_printf(UA_ERROR, "TCP: Allocate rx buffer failed.\n"); + return; + } + + + while(1){ + if(RtlDownSemaWithTimeout(&ua_socket->uart.action_sema, 1000) == pdTRUE){ + ret = uartadapter_uart_recv_data(ua_socket); + if(ret == -1){ + ua_printf(UA_ERROR, "uart recv data error!"); + }else{ + read_len = uartadapter_uart_read(ua_socket, rxbuf, UA_UART_FRAME_LEN); + if(read_len > 0){ + uartadapter_tcp_send_data(ua_socket, rxbuf, read_len); + }else if(read_len < 0){ + ua_printf(UA_ERROR, "tcp send read_len = %d", read_len); + } + } + } +#if UA_PS_ENABLE + else{ + ua_socket->uart.uart_ps_cnt++; + if(ua_socket->uart.uart_ps_cnt >5){ + ua_socket->uart.uart_ps_cnt = 5; + ua_socket->uart.uart_ps = 1; + if(ua_socket->uart.uart_ps && ua_socket->tcp.tcp_ps){ + release_wakelock(UA_WAKELOCK); + } + } + } +#endif + } + +} + +void uartadapter_uart_gpio_wakeup_callback (uint32_t id, gpio_irq_event event) { + acquire_wakelock(UA_WAKELOCK); + ua_socket_t *ua_socket = (ua_socket_t *)id; + ua_socket->uart.uart_ps = 0; + ua_socket->uart.uart_ps_cnt = 0; +} + +int uartadapter_uart_open(ua_socket_t *ua_socket, ua_uart_set_str *puartpara) +{ + PinName uart_tx,uart_rx; + + UA_SOCKET_CHECK_2(ua_socket); + + uart_tx = UA_UART_TX_PIN; + uart_rx = UA_UART_RX_PIN; + ua_socket->uart.uart_param.BaudRate = puartpara->BaudRate; + ua_socket->uart.uart_param.FlowControl = puartpara->FlowControl; + ua_socket->uart.uart_param.WordLen = puartpara->number; + ua_socket->uart.uart_param.Parity = puartpara->parity; + ua_socket->uart.uart_param.StopBit = puartpara->StopBits; + + /*initial uart */ + serial_init(&ua_socket->uart.uart_sobj, uart_tx, uart_rx); + serial_baud(&ua_socket->uart.uart_sobj,puartpara->BaudRate); + serial_format(&ua_socket->uart.uart_sobj, puartpara->number, (SerialParity)puartpara->parity, puartpara->StopBits); +// serial_format(&at_cmd_sobj, uartconf.DataBits, (SerialParity)uartconf.Parity, uartconf.StopBits); + serial_rx_fifo_level(&ua_socket->uart.uart_sobj, FifoLvHalf); + + //---------------------------- add Flow + #define rxflow UA_UART_RTS_PIN + #define txflow UA_UART_CTS_PIN + if(puartpara->FlowControl){ + pin_mode(txflow, PullDown); // init CTS in low + serial_set_flow_control(&ua_socket->uart.uart_sobj, FlowControlRTSCTS, rxflow, txflow); + } + else + serial_set_flow_control(&ua_socket->uart.uart_sobj, FlowControlNone, rxflow, txflow); + //---------------------------- add Flow + + /*uart irq handle*/ + serial_irq_handler(&ua_socket->uart.uart_sobj, uartadapter_uart_irq, (uint32_t)ua_socket); + serial_irq_set(&ua_socket->uart.uart_sobj, RxIrq, 1); + serial_irq_set(&ua_socket->uart.uart_sobj, TxIrq, 1); + + serial_send_comp_handler(&ua_socket->uart.uart_sobj, (void*)uartadapter_uart_send_stream_done, (uint32_t)ua_socket); + +#if UA_PS_ENABLE + //config uart rx as gpio wakeup pin + gpio_irq_t gpio_rx_wake; + gpio_irq_init(&gpio_rx_wake, UA_GPIO_WAKEUP_PIN, uartadapter_uart_gpio_wakeup_callback, (uint32_t)ua_socket); + gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_rx_wake); +#endif + + return 0; +} + +int uartadapter_uart_baud(ua_socket_t *ua_socket, int baud_rate) +{ + int ret = 0; + + UA_SOCKET_CHECK_2(ua_socket); + + ua_socket->uart.uart_param.BaudRate = baud_rate; + + serial_baud(&ua_socket->uart.uart_sobj, baud_rate); + + return ret; +} + +int uartadapter_uart_para(ua_socket_t *ua_socket, int word_len, int parity, int stop_bits) +{ + int ret = 0; + + UA_SOCKET_CHECK_2(ua_socket); + + ua_socket->uart.uart_param.WordLen = word_len; + ua_socket->uart.uart_param.Parity = parity; + ua_socket->uart.uart_param.StopBit = stop_bits; + + serial_format(&ua_socket->uart.uart_sobj, word_len, (SerialParity)parity, stop_bits); + + return ret; +} + +int uartadapter_uart_getpara(ua_socket_t *ua_socket, ua_uart_get_str *uart_para) +{ + UA_SOCKET_CHECK_2(ua_socket); + + uart_para->BaudRate = ua_socket->uart.uart_param.BaudRate; + uart_para->FlowControl = ua_socket->uart.uart_param.FlowControl; + uart_para->number = ua_socket->uart.uart_param.WordLen; + uart_para->parity = ua_socket->uart.uart_param.Parity; + uart_para->StopBits = ua_socket->uart.uart_param.StopBit; + + return 0; +} + +void uartadapter_uart_init(ua_socket_t *ua_socket) +{ + ua_uart_set_str uartset; + ua_uart_get_str uartget; + char uarttest[]="uart0"; + + UA_SOCKET_CHECK(ua_socket); + + uartset.BaudRate = 9600; + uartset.number = 8; + uartset.StopBits = 1; + uartset.FlowControl = 3; + uartset.parity = 0; + strcpy(uartset.UartName,uarttest); + + uartadapter_uart_open(ua_socket, &uartset); + + if(uartadapter_uart_getpara(ua_socket, &uartget)) + ua_printf(UA_ERROR, "get uart failed!"); + else + ua_printf(UA_DEBUG,"uart pata:\r\n"\ + "uart->BaudRate = %d\r\n"\ + "uart->number = %d\r\n"\ + "uart->FlowControl = %d\r\n"\ + "uart->parity = %d\r\n"\ + "uart->StopBits = %d\r\n"\ + "\r\n",\ + uartget.BaudRate,\ + uartget.number,\ + uartget.FlowControl,\ + uartget.parity,\ + uartget.StopBits\ + ); +} + +#define _________FLASH___RELATED________________________ +int uartadapter_flashread(int flashadd, char *pbuf, int len) +{ + int ret = 0; + flash_t flash; + + if( len == 0){ + ua_printf(UA_ERROR, "input error,data length should not be null!"); + ret = -1; + return ret; + }else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented. + len += 4 - ((len%4)==0 ? 4 : (len%4)); + + while(len){ + if(flash_read_word(&flash, flashadd, (unsigned int *)pbuf) !=1 ){ + ua_printf(UA_ERROR, "read flash error!"); + ret = -1; + return ret; + } + len -= 4; + pbuf += 4; + flashadd += 4; + } + + return len; +} + +int uartadapter_flashwrite(int flashadd, char *pbuf, int len) +{ + int ret = 0; + flash_t flash; + + if( len == 0){ + ua_printf(UA_ERROR, "input error,data length should not be null!"); + ret = -1; + return ret; + } + else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented. + len += 4 - ((len%4)==0 ? 4 : (len%4)); + + while(len){ + if(flash_write_word(&flash, flashadd, *(unsigned int *)pbuf) !=1 ){ + ua_printf(UA_ERROR, "write flash error!"); + ret = -1; + return ret; + } + len -= 4; + pbuf += 4; + flashadd += 4; + } + + return ret; +} + +int uartadapter_flasherase(int flashadd, int erase_bytelen) +{ + int ret = 0; + flash_t flash; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash, flashadd); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + return ret; +} + +#define _________GPIO___RELATED________________________ +void uartadapter_systemreload(void) +{ + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ +} + +void uartadapter_gpio_irq (uint32_t id, gpio_irq_event event) +{ + ua_printf(UA_DEBUG, "GPIO push button!"); + + ua_gpio_irq_happen = 1; + RtlUpSemaFromISR(&ua_exception_sema); +} + +void uartadapter_gtimer_timeout_handler(uint32_t id) +{ + gpio_t *gpio_led = (gpio_t *)id; + + gpio_write(gpio_led, !gpio_read(gpio_led)); +} + +void uartadapter_gpio_init(ua_socket_t *ua_socket) +{ + gpio_init(&ua_socket->gpio.gpio_led, UA_GPIO_LED_PIN); + gpio_dir(&ua_socket->gpio.gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&ua_socket->gpio.gpio_led, PullNone); // No pull + + gpio_init(&ua_socket->gpio.gpio_btn, UA_GPIO_IRQ_PIN); + gpio_dir(&ua_socket->gpio.gpio_btn, PIN_INPUT); // Direction: Output + gpio_mode(&ua_socket->gpio.gpio_btn, PullNone); // No pull + + gpio_irq_init(&ua_socket->gpio.gpio_btn_irq, UA_GPIO_IRQ_PIN, uartadapter_gpio_irq, (uint32_t)(&ua_socket->gpio.gpio_btn)); + gpio_irq_set(&ua_socket->gpio.gpio_btn_irq, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&ua_socket->gpio.gpio_btn_irq); + + // Initial a periodical timer + gtimer_init(&ua_socket->gpio.gpio_timer, TIMER0); + //gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 100000, (void*)timer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led); +} + +void uartadapter_gpio_led_mode(ua_socket_t *ua_socket, ua_led_mode_t mode) +{ + gtimer_stop(&ua_socket->gpio.gpio_timer); + switch(mode){ + case UART_ADAPTER_LED_ON: + gpio_write(&ua_socket->gpio.gpio_led, 1); + break; + case UART_ADAPTER_LED_OFF: + gpio_write(&ua_socket->gpio.gpio_led, 0); + break; + case UART_ADAPTER_LED_FAST_TWINKLE: + gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 100000, + (void*)uartadapter_gtimer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led); + break; + case UART_ADAPTER_LED_SLOW_TWINKLE: + gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 2000000, + (void*)uartadapter_gtimer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led); + break; + default: + ua_printf(UA_ERROR, "Unknown GPIO LED mode!"); + break; + } +} + +#define _________CONTROL__DATA__RELATED________________________ +int uartadapter_strncmp(char *cs, char *ct, size_t count) +{ + unsigned char c1, c2; + + while (count) { + c1 = *cs++; + c2 = *ct++; + if (c1 != c2) + return c1 < c2 ? -1 : 1; + if (!c1) + break; + count--; + } + + return 0; +} + +int uartadapter_control_write_tcp_info_into_flash(ua_socket_t *ua_socket) +{ + int ret; + UA_SOCKET_CHECK_2(ua_socket); + + ua_printf(UA_INFO, "\r\nWrite Uart Adapter tcp connection new profile to flash"); + + uartadapter_flasherase(UA_FAST_RECONNECT_TCP_DATA, 0x1000); + ret = uartadapter_flashwrite(UA_FAST_RECONNECT_TCP_DATA, (char *)&ua_socket->tcp, sizeof(ua_tcp_socket_t)); + return ret; +} + +int uartadapter_control_read_tcp_info_and_connect(ua_socket_t *ua_socket) +{ + int ret = 0; + ua_tcp_socket_t tcp = {0}; + + UA_SOCKET_CHECK_2(ua_socket); + + ua_printf(UA_INFO, "\r\nRead Uart Adapter tcp connection profile from flash"); + + uartadapter_flashread(UA_FAST_RECONNECT_TCP_DATA, (u8*)&tcp, sizeof(ua_tcp_socket_t)); + if(tcp.group_id != ~0x0){ + if(tcp.group_id){ + ua_socket->tcp.group_id = tcp.group_id; + ua_socket->tcp.server_port = tcp.server_port; + ua_socket->tcp.client_port = tcp.client_port; + memcpy(ua_socket->tcp.client_ip, tcp.client_ip, 16); + + if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)ua_socket->tcp.server_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__); + + strncpy(ua_tcp_server_ip, ua_socket->tcp.client_ip, 16); + if(xTaskCreate(uartadapter_tcp_transmit_client_forever_thread, ((const char*)"tclient"), 256, (void *)ua_socket->tcp.client_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__); + } + } + return 0; +} + +int uartadapter_control_set_req_handle(ua_socket_t *ua_socket, u8 *pbuf, u32 sz) +{ + u8 *p = pbuf; + u8 len = 0; + u16 type = 0; + u32 port = 0; + u32 server_ip = 0; + int ret = 0; + struct sockaddr_in server_addr; + int server_addr_len = sizeof(server_addr); + TXTRecordRef txtRecord; + unsigned char txt_buf[100] = {0}; // use fixed buffer for text record to prevent malloc/free + unsigned char txt_buf2[100] = {0}; // use fixed buffer for text record to prevent malloc/free + + + ua_printf(UA_DEBUG, "\n===>uartadapter_control_set_req_handle()"); + + UA_SOCKET_CHECK_2(ua_socket); + + UA_PRINT_DATA(pbuf, sz); + + while(p < (pbuf+sz)){ + type = (*p)<<8 | *(p+1); + p = p + 2; + len = *p++; + ua_printf(UA_DEBUG, "type=%d len=%d\n", type, len); + switch(type) + { + case UART_CTRL_TYPE_BAUD_RATE: + ua_socket->uart.uart_param.BaudRate = *(u32 *)p; + ua_printf(UA_INFO, "SET UART BAUD_RATE to %d.\n", ua_socket->uart.uart_param.BaudRate); + serial_baud(&ua_socket->uart.uart_sobj, ua_socket->uart.uart_param.BaudRate); + break; + case UART_CTRL_TYPE_WORD_LEN: + ua_socket->uart.uart_param.WordLen = *p; + ua_printf(UA_INFO, "SET UART WORD_LEN to %d.\n", ua_socket->uart.uart_param.WordLen); + serial_format(&ua_socket->uart.uart_sobj, + ua_socket->uart.uart_param.WordLen, + (SerialParity)ua_socket->uart.uart_param.Parity, + ua_socket->uart.uart_param.StopBit); + break; + case UART_CTRL_TYPE_PARITY: + ua_socket->uart.uart_param.Parity = *p; + ua_printf(UA_INFO, "SET UART PARITY to %d.\n", ua_socket->uart.uart_param.Parity); + serial_format(&ua_socket->uart.uart_sobj, + ua_socket->uart.uart_param.WordLen, + (SerialParity)ua_socket->uart.uart_param.Parity, + ua_socket->uart.uart_param.StopBit); + break; + case UART_CTRL_TYPE_STOP_BIT: + ua_socket->uart.uart_param.StopBit = *p; + ua_printf(UA_INFO, "SET UART STOP_BIT to %d.\n", ua_socket->uart.uart_param.StopBit); + serial_format(&ua_socket->uart.uart_sobj, + ua_socket->uart.uart_param.WordLen, + (SerialParity)ua_socket->uart.uart_param.Parity, + ua_socket->uart.uart_param.StopBit); + break; + case UART_CTRL_TYPE_TCP_SERVER_CREATE: + port = (*p)<<8 | *(p+1); + + if(ua_socket->tcp.transmit_server_listen_socket != -1){ + ua_printf(UA_INFO, "Close old transmit server socket %d", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + } + if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__); + ua_socket->tcp.server_port = port; + uartadapter_control_write_tcp_info_into_flash(ua_socket); + vTaskDelay(50); + ua_printf(UA_DEBUG, "CREATE TCP SERVER WITH PORT %d.\n", port); + //TODO + break; + case UART_CTRL_TYPE_TCP_SERVER_DELETE: + port = (*p)<<8 | *(p+1); + + if(ua_socket->tcp.transmit_server_listen_socket != -1){ + getsockname (ua_socket->tcp.transmit_server_listen_socket, (struct sockaddr *)&server_addr, &server_addr_len); + if(server_addr.sin_port == ntohs((u16)port)){ + ua_printf(UA_INFO,"uart tcp transmit server socket %d closed by control socket!", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket = -1; + if(ua_socket->tcp.transmit_recv_socket != -1){ + ua_printf(UA_INFO,"uart tcp transmit receive socket %d closed by control socket!", ua_socket->tcp.transmit_recv_socket); + close(ua_socket->tcp.transmit_recv_socket); + ua_socket->tcp.transmit_recv_socket = -1; + } + + if(ua_socket->tcp.transmit_send_socket != -1){ + ua_printf(UA_INFO,"uart tcp transmit send socket %d closed by control socket!", ua_socket->tcp.transmit_send_socket); + close(ua_socket->tcp.transmit_send_socket); + ua_socket->tcp.transmit_send_socket = -1; + ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER.\n"); + memset(ua_socket->tcp.client_ip, 0, 16); + ua_socket->tcp.client_port = 0; + } + ua_printf(UA_INFO, "DELETE TCP SERVER \n"); + ua_socket->tcp.server_port = 0; + uartadapter_control_write_tcp_info_into_flash(ua_socket); + }else{ + ua_printf(UA_INFO, "DELETE TCP SERVER FAILED: port not match\n"); + return -1; + } + }else{ + ua_printf(UA_INFO, "DELETE TCP SERVER FAILED: server not exist\n"); + return -1; + } + + break; + case UART_CTRL_TYPE_TCP_CLIENT_CONNECT: + server_ip = (*(p+3))<<24 | (*(p+2))<<16 | (*(p+1))<<8 | *p; + p = p + 4; + memcpy(ua_tcp_server_ip, inet_ntoa(server_ip), 16); + port = (*p)<<8 | *(p+1); + ret = uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, (unsigned short)port); + if(ret == 0){ + ua_printf(UA_INFO, "CONNECT TO TCP SERVER, IP %s PORT %d Success.\n", ua_tcp_server_ip, port); + }else{ + ua_printf(UA_INFO, "CONNECT TO TCP SERVER, IP %s PORT %d Failed.\n", ua_tcp_server_ip, port); + return -1; + } + memcpy(ua_socket->tcp.client_ip, ua_tcp_server_ip, 16); + ua_socket->tcp.client_port = port; + uartadapter_control_write_tcp_info_into_flash(ua_socket); + break; + case UART_CTRL_TYPE_TCP_CLIENT_DISCONNECT: + server_ip = (*(p+3))<<24 | (*(p+2))<<16 | (*(p+1))<<8 | *p; + p = p + 4; + memcpy(ua_tcp_server_ip, inet_ntoa(server_ip), 16); + port = (*p)<<8 | *(p+1); + + if(ua_socket->tcp.transmit_send_socket != -1){ + getpeername(ua_socket->tcp.transmit_send_socket, (struct sockaddr *)&server_addr, &server_addr_len); + if(server_addr.sin_port == ntohs((u16)port) && server_addr.sin_addr.s_addr == server_ip){ + ua_printf(UA_INFO,"uart tcp transmit send socket %d closed by control socket!", ua_socket->tcp.transmit_send_socket); + close(ua_socket->tcp.transmit_send_socket); + ua_socket->tcp.transmit_send_socket = -1; + ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER.\n"); + memset(ua_socket->tcp.client_ip, 0, 16); + ua_socket->tcp.client_port = 0; + uartadapter_control_write_tcp_info_into_flash(ua_socket); + }else{ + ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER FAILED: port or IP not match.\n"); + return -1; + } + }else{ + ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER FAILED: connection not exist\n"); + return -1; + } + break; + case UART_CTRL_TYPE_TCP_GROUP_ID: + ua_socket->tcp.group_id = *p; + ua_printf(UA_INFO,"SET TCP GROUP ID to %d!", *p); +#ifdef MDNS_LIB_EN + sprintf(txt_buf2, "groupid:%d, tcpserver:%d", ua_socket->tcp.group_id, ua_socket->tcp.server_port); + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + TXTRecordSetValue(&txtRecord, "groupid", strlen(txt_buf2), txt_buf2); + mDNSUpdateService(ua_socket->dnsServiceRef, &txtRecord, 0); + mDNSUpdateService(ua_socket->dnsServiceRef2, &txtRecord, 0); */ +#endif + + uartadapter_control_write_tcp_info_into_flash(ua_socket); + + break; + default: + ua_printf(UA_DEBUG, "Unknown Type, just skip\n"); + break; + + } + p += len; + } + return 0; +} + +int uartadapter_control_get_req_handle(ua_socket_t *ua_socket, u16 type, u8 *prsp, u32 *sz) +{ + u8 *p = prsp; + + ua_printf(UA_DEBUG, "===>uartadapter_control_get_req_handle()"); + + UA_SOCKET_CHECK_2(ua_socket); + + sprintf((char *)p, UA_CONTROL_PREFIX); + p += strlen(UA_CONTROL_PREFIX); + *p++ = UART_CTRL_MODE_GET_RSP; + + if(type & UART_CTRL_TYPE_BAUD_RATE){ + *p++ = 0; + *p++ = UART_CTRL_TYPE_BAUD_RATE; + *p++ = 4; + *(u32*)p = ua_socket->uart.uart_param.BaudRate; + p += 4; + } + if(type & UART_CTRL_TYPE_WORD_LEN){ + *p++ = 0; + *p++ = UART_CTRL_TYPE_WORD_LEN; + *p++ = 1; + *p = ua_socket->uart.uart_param.WordLen; + p += 1; + } + if(type & UART_CTRL_TYPE_PARITY){ + *p++ = 0; + *p++ = UART_CTRL_TYPE_PARITY; + *p++ = 1; + *p = ua_socket->uart.uart_param.Parity; + p += 1; + } + if(type & UART_CTRL_TYPE_STOP_BIT){ + *p++ = 0; + *p++ = UART_CTRL_TYPE_STOP_BIT; + *p++ = 1; + *p = ua_socket->uart.uart_param.StopBit; + p += 1; + } +#if 0 + if(type & UART_CTRL_TYPE_FLOW_CTRL){ + *p++ = UART_CTRL_TYPE_FLOW_CTRL; + *p++ = 1; + *p = ua_socket->uart.uart_param.FlowControl; + p += 1; + } +#endif + *sz = p - prsp; + + UA_PRINT_DATA(prsp, *sz); + return 0; +} + +int uartadapter_control_process(ua_socket_t *ua_socket, char *pbuf, size_t size) +{ + /*the same as socket*/ + int ret = 0; + + UA_SOCKET_CHECK_2(ua_socket); + + if(!size || !pbuf){ + //ua_printf(UA_ERROR, "control data input error,please check!"); + ret = -1; + return ret; + } + + UA_PRINT_DATA(pbuf, size); + if (size <= strlen(UA_CONTROL_PREFIX)) { + ua_printf(UA_ERROR, "no control data prefix!"); + return -1; + } + + if(uartadapter_strncmp(pbuf, UA_CONTROL_PREFIX, 10) != 0) + { + ua_printf(UA_ERROR, "control data prefix wrong!"); + return -1; + } + else + { + u8 *p = (u8*)pbuf + strlen(UA_CONTROL_PREFIX); + u8 mode = *p++; + switch(mode) + { + case UART_CTRL_MODE_SET_REQ: //AMEBA_UART-MODE-TYPE-LEN-VAL-TYPE-LEN-VAL... + { + char rsp[32] = {0}; //AMEBA_UART-MODE + u32 sz = strlen(UA_CONTROL_PREFIX); + ret = uartadapter_control_set_req_handle(ua_socket, p, (size - strlen(UA_CONTROL_PREFIX) - 1)); + if(0 == ret){ + sprintf(rsp, UA_CONTROL_PREFIX); + *(rsp + sz) = UART_CTRL_MODE_SET_RSP; + sz ++; + sprintf(rsp + sz, "\n"); + sz ++; + vTaskDelay(100); + uartadapter_tcp_send_control(ua_socket, rsp, sz); + } + break; + } + case UART_CTRL_MODE_GET_REQ: //AMEBA_UART-MODE-TYPE + { + char rsp[128] = {0}; + u32 sz = 0; + u16 type = (*p)<<8 | *(p+1); + uartadapter_control_get_req_handle(ua_socket, type, (u8*)rsp, &sz); + sprintf(rsp + sz, "\n"); + sz ++; + vTaskDelay(100); + uartadapter_tcp_send_control(ua_socket, rsp, sz); + break; + } + default: + ua_printf(UA_ERROR, UA_CONTROL_PREFIX": Mode (%d) not support!", mode); + break; + } + } + return 0; +} + +#define _________TCP__RELATED________________________ +int uartadapter_tcpclient(ua_socket_t *ua_socket, const char *host_ip, unsigned short usPort) +{ + int iAddrSize; + int iSockFD = -1; + int iStatus; + int enable = 1; + struct sockaddr_in sAddr; + int send_timeout = 3000; + + UA_SOCKET_CHECK_2(ua_socket); + + FD_ZERO(&sAddr); + sAddr.sin_family = AF_INET; + sAddr.sin_port = htons(usPort); + sAddr.sin_addr.s_addr = inet_addr(host_ip); + + iAddrSize = sizeof(struct sockaddr_in); + + iSockFD = socket(AF_INET, SOCK_STREAM, 0); + if( iSockFD < 0 ) { + ua_printf(UA_ERROR, "TCP ERROR: create tcp client socket fd error!"); + return -1; + } + + ua_printf(UA_DEBUG, "TCP: ServerIP=%s port=%d.", host_ip, usPort); + ua_printf(UA_DEBUG, "TCP: Create socket %d.", iSockFD); + // connecting to TCP server + iStatus = connect(iSockFD, (struct sockaddr *)&sAddr, iAddrSize); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client connect server error %d!", iStatus); + goto Exit; + } + + iStatus = setsockopt(iSockFD, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set TCP_NODELAY error! "); + goto Exit; + } + + iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set SO_KEEPALIVE error! "); + goto Exit; + } + +#if LWIP_SO_SNDTIMEO + iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(int)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set SO_SNDTIMEO error! "); + goto Exit; + } +#endif + +#if LWIP_SO_RCVTIMEO + iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(int)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set SO_RCVTIMEO error! "); + goto Exit; + } +#endif + + if(ua_socket->tcp.transmit_send_socket != -1){ + close(ua_socket->tcp.transmit_send_socket); + ua_printf(UA_INFO, "Close old transmit send socket %d.", ua_socket->tcp.transmit_send_socket); + } + + ua_printf(UA_INFO, "Connect to transmit server successfully."); + ua_socket->tcp.transmit_send_socket = iSockFD; + + return 0; + +Exit: + close(iSockFD); + return -1; +} + +int uartadapter_tcpserver(ua_socket_t *ua_socket, unsigned short usPort, u8 socket_type) +{ + struct sockaddr_in sLocalAddr; + int iAddrSize; + int iSockFD; + int iStatus; + int enable = 1; + + UA_SOCKET_CHECK_2(ua_socket); + + iSockFD = socket(AF_INET, SOCK_STREAM, 0); + if( iSockFD < 0 ) { + ua_printf(UA_ERROR, "create server_socket error!"); + goto Exit; + } + + iStatus = setsockopt( iSockFD, SOL_SOCKET, SO_REUSEADDR, + (const char *) &enable, sizeof( enable ) ); + if( iStatus < 0 ) { + ua_printf(UA_ERROR, "set tcp server socket SO_REUSEADDR error %d! ", iStatus); + goto Exit; + } + + ua_printf(UA_DEBUG, "TCP: Create Tcp server socket %d", iSockFD); + + //filling the TCP server socket address + memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr)); + sLocalAddr.sin_family = AF_INET; + sLocalAddr.sin_len = sizeof(sLocalAddr); + sLocalAddr.sin_port = htons(usPort); + sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + iAddrSize = sizeof(sLocalAddr); + + iStatus = bind(iSockFD, (struct sockaddr *)&sLocalAddr, iAddrSize); + if( iStatus < 0 ) { + ua_printf(UA_ERROR, "bind tcp server socket fd error %d! ", iStatus); + goto Exit; + } + ua_printf(UA_DEBUG, "TCP: Bind successfully."); + + iStatus = listen(iSockFD, 10); + if( iStatus != 0 ) { + ua_printf(UA_ERROR, "listen tcp server socket fd error %d!", iStatus); + goto Exit; + } + + if(0 == socket_type){ + ua_socket->tcp.chat_server_listen_socket = iSockFD; + ua_printf(UA_INFO, "TCP Chat Server: Listen on port %d", usPort); + }else if(1 == socket_type){ + ua_socket->tcp.control_server_listen_socket = iSockFD; + ua_printf(UA_INFO, "TCP Control Server: Listen on port %d", usPort); + }else{ + ua_socket->tcp.transmit_server_listen_socket = iSockFD; + ua_printf(UA_INFO, "TCP Transmit Server: Listen on port %d", usPort); + } + + return 0; + +Exit: + close(iSockFD); + ua_printf(UA_DEBUG, "Tcp server listen on port %d closed!", usPort); + return 0; +} + +void uartadapter_tcp_chat_server_thread(void *param) +{ + ua_socket_t *ua_socket = (ua_socket_t *)param; + unsigned short port = UA_CHAT_SOCKET_PORT; + + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Data Server!"); + uartadapter_tcpserver(ua_socket, port, 0); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + ua_printf(UA_DEBUG, "TCP: Tcp data server stopped!"); + vTaskDelete(NULL); +} + +void uartadapter_tcp_control_server_thread(void *param) +{ + ua_socket_t *ua_socket = (ua_socket_t *)param; + unsigned short port = UA_CONTROL_SOCKET_PORT; + + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Control Server!"); + uartadapter_tcpserver(ua_socket, port, 1); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + ua_printf(UA_DEBUG, "TCP: Tcp control server stopped!"); + vTaskDelete(NULL); +} + +void uartadapter_tcp_transmit_server_thread(void *param) +{ + ua_socket_t *ua_socket = ua_global_socket; + unsigned short port = (int)param; + + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Transmit Server!"); + uartadapter_tcpserver(ua_socket, port, 2); + + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + ua_printf(UA_DEBUG, "TCP: Tcp transmit server thread delete!"); + vTaskDelete(NULL); +} + +void uartadapter_tcp_transmit_client_thread(void *param) +{ + ua_socket_t *ua_socket = ua_global_socket; + unsigned short port = (int)param; + + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Data Client!"); + uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, port); + + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + ua_printf(UA_DEBUG, "TCP: Tcp transmit client thread delete!"); + vTaskDelete(NULL); +} + +void uartadapter_tcp_transmit_client_forever_thread(void *param) +{ + ua_socket_t *ua_socket = ua_global_socket; + unsigned short port = (int)param; + int ret = 0; + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Transmit Client forever thread!"); + + do{ + ret = uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, port); + if(ret != 0){ + ua_printf(UA_INFO, "Uart Adapter: Try to connect to TCP server again"); + vTaskDelay(3000); + } + }while(ret != 0); + + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + ua_printf(UA_DEBUG, "TCP: Tcp transmit client thread delete!"); + vTaskDelete(NULL); +} + +void uartadapter_tcp_send_data(ua_socket_t *ua_socket, char *buffer, int size) +{ + int iStatus; + + UA_SOCKET_CHECK(ua_socket); + + if(ua_socket->tcp.chat_socket != -1){ + ua_socket->tcp.send_flag = 1; + RtlDownSema(&ua_socket->uart.tcp_tx_rx_sema); + iStatus = send(ua_socket->tcp.chat_socket, buffer, size, 0 ); + RtlUpSema(&ua_socket->uart.tcp_tx_rx_sema); + ua_socket->tcp.send_flag = 0; + if( iStatus <= 0 ){ + ua_printf(UA_ERROR, "tcp chat socket send data error! iStatus:%d!", iStatus); + }else{ + ua_socket->tcp.tx_cnt += iStatus; + } + } + + if(ua_socket->tcp.transmit_send_socket != -1){ + ua_socket->tcp.send_flag = 1; + iStatus = send(ua_socket->tcp.transmit_send_socket, buffer, size, 0 ); + ua_socket->tcp.send_flag = 0; + if( iStatus <= 0 ){ + ua_printf(UA_ERROR, "tcp transmit send socket send data error! iStatus:%d!", iStatus); + }else{ + ua_socket->tcp.tx_cnt += iStatus; + } + } + + return; +} + +void uartadapter_tcp_send_control(ua_socket_t *ua_socket, char *buffer, int size) +{ + int iStatus; + + UA_SOCKET_CHECK(ua_socket); + + if(ua_socket->tcp.control_socket != -1){ + ua_socket->tcp.send_flag = 1; + iStatus = send(ua_socket->tcp.control_socket, buffer, size, 0 ); + ua_socket->tcp.send_flag = 0; + if( iStatus <= 0 ){ + ua_printf(UA_ERROR,"tcp control socket send data error! iStatus:%d!", iStatus); + } + + if(ua_debug_print_en){ + ua_printf(UA_INFO,"uart tcp control socket send %d bytes, ret %d!", size, iStatus); + } + } + + return; +} + +void uartadapter_tcp_except_handler(ua_socket_t *ua_socket, fd_set *exceptfds) +{ + if(ua_socket->tcp.chat_socket != -1 && FD_ISSET(ua_socket->tcp.chat_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp chat socket %d exception happen, need to close!", ua_socket->tcp.chat_socket); + close(ua_socket->tcp.chat_socket); + ua_socket->tcp.chat_socket = -1; + } + + if(ua_socket->tcp.control_socket != -1 && FD_ISSET(ua_socket->tcp.control_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp control socket %d exception happen, need to close!", ua_socket->tcp.control_socket); + close(ua_socket->tcp.control_socket); + ua_socket->tcp.control_socket = -1; + } + + if(ua_socket->tcp.transmit_recv_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_recv_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp transmit recv socket %d exception happen, need to close!", ua_socket->tcp.transmit_recv_socket); + close(ua_socket->tcp.transmit_recv_socket); + ua_socket->tcp.transmit_recv_socket = -1; + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); +#if 0 + if(ua_socket->tcp.transmit_server_listen_socket != -1){ + ua_printf(UA_INFO,"uart tcp transmit server socket %d exception happen, need to close!", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket = -1; + } +#endif + } + + if(ua_socket->tcp.transmit_send_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_send_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp transmit send socket %d exception happen, need to close!", ua_socket->tcp.transmit_send_socket); + close(ua_socket->tcp.transmit_send_socket); + ua_socket->tcp.transmit_send_socket = -1; + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); + + strncpy(ua_tcp_server_ip, ua_socket->tcp.client_ip, 16); + if(xTaskCreate(uartadapter_tcp_transmit_client_forever_thread, ((const char*)"tclient"), 256, (void *)ua_socket->tcp.client_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__); + } + + if(ua_socket->tcp.chat_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.chat_server_listen_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp chat server socket %d exception happen, need to restart!", ua_socket->tcp.chat_server_listen_socket); + close(ua_socket->tcp.chat_server_listen_socket); + ua_socket->tcp.chat_server_listen_socket = -1; + uartadapter_tcpserver(ua_socket, UA_CHAT_SOCKET_PORT, 0); + } + + if(ua_socket->tcp.control_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.control_server_listen_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp control server socket %d exception happen, need to restart!", ua_socket->tcp.control_server_listen_socket); + close(ua_socket->tcp.control_server_listen_socket); + ua_socket->tcp.control_server_listen_socket = -1; + uartadapter_tcpserver(ua_socket, UA_CONTROL_SOCKET_PORT, 1); + } + + if(ua_socket->tcp.transmit_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_server_listen_socket, exceptfds)){ + ua_printf(UA_INFO,"uart tcp transmit server socket %d exception happen, need to close!", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket = -1; + //uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); + uartadapter_tcpserver(ua_socket, ua_socket->tcp.server_port, 2); + } + +} + +void uartadapter_tcp_chat_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf) +{ + int recv_len; + + UA_SOCKET_CHECK(ua_socket); + + ua_socket->tcp.recv_flag = 1; + RtlDownSema(&ua_socket->uart.tcp_tx_rx_sema); + recv_len = recv(ua_socket->tcp.chat_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT); + RtlUpSema(&ua_socket->uart.tcp_tx_rx_sema); + ua_socket->tcp.recv_flag = 0; + if(recv_len < 0){ + ua_printf(UA_ERROR, "Tcp Chat Socket %d Recv Error, ret = %d", ua_socket->tcp.chat_socket, recv_len); + }else if(recv_len == 0){ + ua_printf(UA_INFO, "Tcp Chat Socket %d closed", ua_socket->tcp.chat_socket); + close(ua_socket->tcp.chat_socket); + ua_socket->tcp.chat_socket = -1; + }else{ + ua_printf(UA_DEBUG, "Tcp Chat Socket %d Recv %d Data", ua_socket->tcp.chat_socket, recv_len); + uartadapter_uart_write(ua_socket, tcp_rxbuf, recv_len); + ua_socket->tcp.rx_cnt += recv_len; + } + + return; +} + +void uartadapter_tcp_control_socket_handler(ua_socket_t *ua_socket) +{ + char tcp_rxbuf[UA_UART_FRAME_LEN]; + int recv_len; + + UA_SOCKET_CHECK(ua_socket); + + recv_len = recv(ua_socket->tcp.control_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT); //MSG_DONTWAIT MSG_WAITALL + if(recv_len<0){ + ua_printf(UA_ERROR, "Tcp Control Socket %d Recv Error", ua_socket->tcp.control_socket); + }else if(recv_len == 0){ + ua_printf(UA_INFO, "Tcp Control Socket %d closed", ua_socket->tcp.control_socket); + close(ua_socket->tcp.control_socket); + ua_socket->tcp.control_socket = -1; + }else{ + ua_printf(UA_DEBUG, "Tcp Control Socket %d Recv %d Data", ua_socket->tcp.control_socket, recv_len); + uartadapter_control_process(ua_socket, (void*)tcp_rxbuf, recv_len); + } + + return; +} + +void uartadapter_tcp_transmit_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf) +{ + int recv_len; + + UA_SOCKET_CHECK(ua_socket); + + ua_socket->tcp.recv_flag = 1; + recv_len = recv(ua_socket->tcp.transmit_recv_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT); + ua_socket->tcp.recv_flag = 0; + if(recv_len < 0){ + ua_printf(UA_ERROR, "Tcp Transmit Recv Socket %d Recv Error, ret = %d", ua_socket->tcp.transmit_recv_socket, recv_len); + }else if(recv_len == 0){ + ua_printf(UA_INFO, "Tcp Transmit Recv Socket %d closed", ua_socket->tcp.transmit_recv_socket); + close(ua_socket->tcp.transmit_recv_socket); + ua_socket->tcp.transmit_recv_socket = -1; +#if 0 + if(ua_socket->tcp.transmit_server_listen_socket != -1){ + ua_printf(UA_INFO, "Tcp Transmit Server Socket %d closed", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket = -1; + } +#endif + }else{ + uartadapter_uart_write(ua_socket, tcp_rxbuf, recv_len); + ua_socket->tcp.rx_cnt += recv_len; + } + + return; +} + +void uartadapter_tcp_chat_listen_socket_handler(ua_socket_t *ua_socket) +{ + int old_chat_socket; + struct sockaddr_in sAddr; + int addrlen = sizeof(sAddr); + int iStatus; + int enable = 1; + int send_timeout = 3000; + + UA_SOCKET_CHECK(ua_socket); + + old_chat_socket = ua_socket->tcp.chat_socket; + + ua_socket->tcp.chat_socket = accept(ua_socket->tcp.chat_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen); + if( ua_socket->tcp.chat_socket< 0 ) { + ua_printf(UA_ERROR, "Accept tcp chat socket error"); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.chat_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp chat socket set opt TCP_NODELAY error! "); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp chat socket set opt SO_KEEPALIVE error! "); + goto EXIT; + } + +#if LWIP_SO_SNDTIMEO + iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + +#if LWIP_SO_RCVTIMEO + iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + + ua_printf(UA_INFO, "Accept new chat socket %d on port %d successfully.", ua_socket->tcp.chat_socket, htons(sAddr.sin_port)); + if(old_chat_socket != -1) + { + close(old_chat_socket); + ua_printf(UA_INFO, "Close old chat socket %d.", old_chat_socket); + } + + return; + +EXIT: + if(ua_socket->tcp.chat_server_listen_socket != -1){ + close(ua_socket->tcp.chat_server_listen_socket); + ua_socket->tcp.chat_server_listen_socket = -1; + } +} + +void uartadapter_tcp_control_listen_socket_handler(ua_socket_t *ua_socket) +{ + int old_control_socket; + struct sockaddr_in sAddr; + int addrlen = sizeof(sAddr); + int iStatus; + int enable = 1; + int send_timeout = 3000; + + UA_SOCKET_CHECK(ua_socket); + + old_control_socket = ua_socket->tcp.control_socket; + + ua_socket->tcp.control_socket = accept(ua_socket->tcp.control_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen); + if( ua_socket->tcp.control_socket< 0 ) { + ua_printf(UA_ERROR, "Accept tcp control socket error"); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.control_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp chat socket set opt TCP_NODELAY error! "); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp chat socket set opt SO_KEEPALIVE error! "); + goto EXIT; + } + +#if LWIP_SO_SNDTIMEO + iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + +#if LWIP_SO_RCVTIMEO + iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + + ua_printf(UA_INFO, "Accept new control socket %d on port %d successfully.", ua_socket->tcp.control_socket, htons(sAddr.sin_port)); + if(old_control_socket != -1) + { + close(old_control_socket); + ua_printf(UA_INFO, "Close old control socket %d.", old_control_socket); + } + + return; + +EXIT: + if(ua_socket->tcp.control_server_listen_socket!= -1){ + close(ua_socket->tcp.control_server_listen_socket); + ua_socket->tcp.control_server_listen_socket= -1; + } +} + +void uartadapter_tcp_transmit_listen_socket_handler(ua_socket_t *ua_socket) +{ + int old_transmit_recv_socket; + struct sockaddr_in sAddr; + int addrlen = sizeof(sAddr); + int iStatus; + int enable = 1; + int send_timeout = 3000; + + UA_SOCKET_CHECK(ua_socket); + + old_transmit_recv_socket = ua_socket->tcp.transmit_recv_socket; + + ua_socket->tcp.transmit_recv_socket = accept(ua_socket->tcp.transmit_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen); + if( ua_socket->tcp.transmit_recv_socket < 0 ) { + ua_printf(UA_ERROR, "Accept tcp control socket error"); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp transmit recv socket set opt TCP_NODELAY error! "); + goto EXIT; + } + + iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp transmit recv socket set opt SO_KEEPALIVE error! "); + goto EXIT; + } + +#if LWIP_SO_SNDTIMEO + iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + +#if LWIP_SO_RCVTIMEO + iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout)); + if (iStatus < 0) { + ua_printf(UA_ERROR, "tcp client socket set opt error! "); + goto EXIT; + } +#endif + + ua_printf(UA_INFO, "Accept new transmit recv socket %d on port %d successfully.", ua_socket->tcp.transmit_recv_socket, htons(sAddr.sin_port)); + if(old_transmit_recv_socket != -1) + { + close(old_transmit_recv_socket); + ua_printf(UA_INFO, "Close old transmit recv socket %d.", old_transmit_recv_socket); + } + + return; + +EXIT: + if(ua_socket->tcp.transmit_server_listen_socket!= -1){ + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket= -1; + } +} + +void uartadapter_tcp_select_restart_handler(ua_socket_t *ua_socket) +{ + if(ua_socket->tcp.chat_socket != -1){ + ua_printf(UA_INFO,"IP changed, uart tcp chat socket %d need to close!", ua_socket->tcp.chat_socket); + close(ua_socket->tcp.chat_socket); + ua_socket->tcp.chat_socket = -1; + } + + if(ua_socket->tcp.control_socket != -1){ + ua_printf(UA_INFO,"IP changed, uart tcp control socket %d need to close!", ua_socket->tcp.control_socket); + close(ua_socket->tcp.control_socket); + ua_socket->tcp.control_socket = -1; + } + + if(ua_socket->tcp.transmit_recv_socket != -1){ + ua_printf(UA_INFO,"IP changed, uart tcp transmit recv socket %d need to close!", ua_socket->tcp.transmit_recv_socket); + close(ua_socket->tcp.transmit_recv_socket); + ua_socket->tcp.transmit_recv_socket = -1; + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); + } + + if(ua_socket->tcp.transmit_send_socket != -1){ + ua_printf(UA_INFO,"IP changed, uart tcp transmit send socket %d need to close!", ua_socket->tcp.transmit_send_socket); + close(ua_socket->tcp.transmit_send_socket); + ua_socket->tcp.transmit_send_socket = -1; + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); + } + + if(ua_socket->tcp.chat_server_listen_socket!= -1){ + ua_printf(UA_INFO,"IP changed, uart tcp chat server socket %d need to restart!", ua_socket->tcp.chat_server_listen_socket); + close(ua_socket->tcp.chat_server_listen_socket); + ua_socket->tcp.chat_server_listen_socket = -1; + uartadapter_tcpserver(ua_socket, UA_CHAT_SOCKET_PORT, 0); + } + + if(ua_socket->tcp.control_server_listen_socket!= -1){ + ua_printf(UA_INFO,"IP changed, uart tcp control server socket %d need to restart!", ua_socket->tcp.control_server_listen_socket); + close(ua_socket->tcp.control_server_listen_socket); + ua_socket->tcp.control_server_listen_socket = -1; + uartadapter_tcpserver(ua_socket, UA_CONTROL_SOCKET_PORT, 1); + } + + if(ua_socket->tcp.transmit_server_listen_socket!= -1){ + ua_printf(UA_INFO,"IP changed, uart tcp transmit server socket %d need to close!", ua_socket->tcp.transmit_server_listen_socket); + close(ua_socket->tcp.transmit_server_listen_socket); + ua_socket->tcp.transmit_server_listen_socket = -1; + uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE); + } + +} + +void uartadapter_tcp_select_thread(void *param) +{ + ua_socket_t *ua_socket = (ua_socket_t *)param; + int max_fd; + struct timeval tv; + fd_set readfds; + fd_set exceptfds; + int ret = 0; + char *tcp_rxbuf; + + UA_SOCKET_CHECK(ua_socket); + + tcp_rxbuf = pvPortMalloc(UA_UART_FRAME_LEN); + if(NULL == tcp_rxbuf){ + ua_printf(UA_ERROR, "Allocate select buffer failed.\n"); + return; + } + + while(1){ + if(ua_reconnect_ip_change){ + uartadapter_tcp_select_restart_handler(ua_socket); + ua_reconnect_ip_change = 0; + } + + FD_ZERO(&readfds); + FD_ZERO(&exceptfds); + max_fd = -1; + + if(ua_socket->tcp.chat_socket != -1){ + FD_SET(ua_socket->tcp.chat_socket, &readfds); + FD_SET(ua_socket->tcp.chat_socket, &exceptfds); + if(ua_socket->tcp.chat_socket > max_fd) + max_fd = ua_socket->tcp.chat_socket; + } + + if(ua_socket->tcp.control_socket != -1){ + FD_SET(ua_socket->tcp.control_socket, &readfds); + FD_SET(ua_socket->tcp.control_socket, &exceptfds); + if(ua_socket->tcp.control_socket > max_fd) + max_fd = ua_socket->tcp.control_socket; + } + + if(ua_socket->tcp.control_server_listen_socket != -1){ + FD_SET(ua_socket->tcp.control_server_listen_socket, &readfds); + FD_SET(ua_socket->tcp.control_server_listen_socket, &exceptfds); + if(ua_socket->tcp.control_server_listen_socket > max_fd) + max_fd = ua_socket->tcp.control_server_listen_socket; + } + + if(ua_socket->tcp.chat_server_listen_socket != -1){ + FD_SET(ua_socket->tcp.chat_server_listen_socket, &readfds); + FD_SET(ua_socket->tcp.chat_server_listen_socket, &exceptfds); + if(ua_socket->tcp.chat_server_listen_socket > max_fd) + max_fd = ua_socket->tcp.chat_server_listen_socket; + } + + if(ua_socket->tcp.transmit_recv_socket != -1){ + FD_SET(ua_socket->tcp.transmit_recv_socket, &readfds); + FD_SET(ua_socket->tcp.transmit_recv_socket, &exceptfds); + if(ua_socket->tcp.transmit_recv_socket > max_fd) + max_fd = ua_socket->tcp.transmit_recv_socket; + } + + if(ua_socket->tcp.transmit_send_socket != -1){ + FD_SET(ua_socket->tcp.transmit_send_socket, &exceptfds); + if(ua_socket->tcp.transmit_send_socket > max_fd) + max_fd = ua_socket->tcp.transmit_send_socket; + } + + if(ua_socket->tcp.transmit_server_listen_socket != -1){ + FD_SET(ua_socket->tcp.transmit_server_listen_socket, &readfds); + FD_SET(ua_socket->tcp.transmit_server_listen_socket, &exceptfds); + if(ua_socket->tcp.transmit_server_listen_socket> max_fd) + max_fd = ua_socket->tcp.transmit_server_listen_socket; + } + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = select(max_fd + 1, &readfds, NULL, &exceptfds, &tv); + + if(ua_debug_print_en){ + ua_printf(UA_INFO, "uart adapter test select ret = %x",ret); + } + if(ret > 0){ +#if UA_PS_ENABLE + //printf("select get lock \r\n"); + acquire_wakelock(UA_WAKELOCK); + ua_socket->tcp.tcp_ps = 0; + ua_socket->tcp.tcp_ps_cnt = 0; +#endif + + uartadapter_tcp_except_handler(ua_socket, &exceptfds); + + if(ua_socket->tcp.chat_socket != -1 && FD_ISSET(ua_socket->tcp.chat_socket, &readfds)){ + uartadapter_tcp_chat_socket_handler(ua_socket, tcp_rxbuf); + } + + if(ua_socket->tcp.control_socket != -1 && FD_ISSET(ua_socket->tcp.control_socket, &readfds)){ + uartadapter_tcp_control_socket_handler(ua_socket); + } + + if(ua_socket->tcp.transmit_recv_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_recv_socket, &readfds)){ + uartadapter_tcp_transmit_socket_handler(ua_socket, tcp_rxbuf); + } + + if(ua_socket->tcp.chat_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.chat_server_listen_socket, &readfds)){ + uartadapter_tcp_chat_listen_socket_handler(ua_socket); + } + + if(ua_socket->tcp.control_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.control_server_listen_socket, &readfds)){ + uartadapter_tcp_control_listen_socket_handler(ua_socket); + } + + if(ua_socket->tcp.transmit_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.transmit_server_listen_socket, &readfds)){ + uartadapter_tcp_transmit_listen_socket_handler(ua_socket); + } + + + } +#if UA_PS_ENABLE + else{ + ua_socket->tcp.tcp_ps_cnt++; + if(ua_socket->tcp.tcp_ps_cnt > 5){ + ua_socket->tcp.tcp_ps_cnt = 5; + ua_socket->tcp.tcp_ps = 1; + if(ua_socket->uart.uart_ps && ua_socket->tcp.tcp_ps){ + release_wakelock(UA_WAKELOCK); + } + } + } +#endif + } + + //vTaskDelete(NULL); +} + +#define _________WIFI__RELATED________________________ + +int uartadapter_connect_wifi(rtw_network_info_t *p_wifi, uint32_t channel, uint8_t pscan_config) +{ + int retry = 3; + rtw_wifi_setting_t setting; + int ret; + while (1) { + if(wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1) < 0){ + ua_printf(UA_ERROR, "wifi set partial scan channel fail"); + ret = SC_TARGET_CHANNEL_SCAN_FAIL; + return ret; + } + + ret = wifi_connect( + NULL, + 0, + (char*)p_wifi->ssid.val, + p_wifi->security_type, + (char*)p_wifi->password, + p_wifi->key_id, + NULL); + + if (ret == RTW_SUCCESS) { + ret = LwIP_DHCP(0, DHCP_START); + wifi_get_setting(WLAN0_NAME, &setting); + wifi_show_setting(WLAN0_NAME, &setting); + if (ret == DHCP_ADDRESS_ASSIGNED) + return SC_SUCCESS; + else + return SC_DHCP_FAIL; + } + + if (retry == 0) { + ret = SC_JOIN_BSS_FAIL; + break; + } + retry --; + } + + return ret; +} + + +static int uartadapter_load_wifi_config() +{ + flash_t flash; + struct wlan_fast_reconnect *data; + uint32_t channel; + uint8_t pscan_config; + char key_id; + rtw_network_info_t wifi = {0}; + int ret = SC_SUCCESS; + + + data = (struct wlan_fast_reconnect *)rtw_zmalloc(sizeof(struct wlan_fast_reconnect)); + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (uint8_t *)data); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + if(*((uint32_t *) data) != ~0x0){ + memcpy(psk_essid, data->psk_essid, sizeof(data->psk_essid)); + memcpy(psk_passphrase, data->psk_passphrase, sizeof(data->psk_passphrase)); + memcpy(wpa_global_PSK, data->wpa_global_PSK, sizeof(data->wpa_global_PSK)); + memcpy(&channel, &(data->channel), 4); + sprintf(&key_id,"%d",(channel >> 28)); + channel &= 0xff; + pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY; + //set partial scan for entering to listen beacon quickly + //wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1); + + //set wifi connect + wifi.ssid.len = (int)strlen((char*)psk_essid); + memcpy(wifi.ssid.val, psk_essid, wifi.ssid.len); + wifi.key_id = key_id; + + //open mode + if(!strlen((char*)psk_passphrase)){ + wifi.security_type = RTW_SECURITY_OPEN; + } + //wep mode + else if( strlen((char*)psk_passphrase) == 5 || strlen((char*)psk_passphrase) == 13){ + wifi.security_type = RTW_SECURITY_WEP_PSK; + wifi.password = (unsigned char *)psk_passphrase; + wifi.password_len = (int)strlen((char const *)psk_passphrase); + } + //WPA/WPA2 + else{ + wifi.security_type = RTW_SECURITY_WPA2_AES_PSK; + wifi.password = (unsigned char *)psk_passphrase; + wifi.password_len = (int)strlen((char const *)psk_passphrase); + } + + ret = uartadapter_connect_wifi(&wifi, channel, pscan_config); + + //print_simple_config_result((enum ua_sc_result)ret); + + if(data) + rtw_mfree((u8*)data, sizeof(sizeof(struct wlan_fast_reconnect))); + + if(ret == SC_SUCCESS) + return RTW_SUCCESS; + else + return RTW_ERROR; + }else{ + ua_printf(UA_INFO, "No AP Profile read from FLASH, start simple configure"); + + if(data) + rtw_mfree((u8*)data, sizeof(sizeof(struct wlan_fast_reconnect))); + + return RTW_ERROR; + } +} + +#if CONFIG_INCLUDE_SIMPLE_CONFIG +int uartadapter_simple_config(char *pin_code){ + + enum sc_result ret = SC_ERROR; + wifi_enter_promisc_mode(); + if(init_test_data(pin_code) == 0){ + filter_add_enable(); + ret = simple_config_test(NULL); + //print_simple_config_result(ret); + remove_filter(); + if(ret == SC_SUCCESS) + return RTW_SUCCESS; + else + return RTW_ERROR; + }else{ + return RTW_ERROR; + } +} +#endif + +#ifdef MDNS_LIB_EN +#define _________MDNS__RELATED________________________ +static void uartadapter_mdns_start(ua_socket_t *ua_socket, int is_restart) +{ + TXTRecordRef txtRecord; + unsigned char txt_buf[100] = {0}; // use fixed buffer for text record to prevent malloc/free + unsigned char txt_buf2[100] = {0}; // use fixed buffer for text record to prevent malloc/free + struct sockaddr_in server_addr; + int server_addr_len = sizeof(server_addr); + + struct netif * pnetif = &xnetif[0]; + + if(is_restart){ + ua_printf(UA_INFO, "Uart Adapter mDNS Restart"); + mDNSResponderDeinit(); + vTaskDelay(1000); + } + + ua_printf(UA_DEBUG, "Uart Adapter mDNS Init"); + + if(mDNSResponderInit() == 0) { + ua_printf(UA_INFO, "mDNS Register service"); + char hostname[32] = {0}; //AMEBA_UART-MODE + u32 prefix_len = strlen("AMEBA_"); + sprintf(hostname, "AMEBA_"); + sprintf(hostname+prefix_len, "%02x%02x%02x%02x%02x%02x", + pnetif->hwaddr[0], pnetif->hwaddr[1], pnetif->hwaddr[2], + pnetif->hwaddr[3], pnetif->hwaddr[4], pnetif->hwaddr[5]); + + sprintf(txt_buf2, "groupid:%d, tcpserver:%d", ua_socket->tcp.group_id, ua_socket->tcp.server_port); + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + TXTRecordSetValue(&txtRecord, "groupid", strlen(txt_buf2), txt_buf2); + + ua_socket->dnsServiceRef = mDNSRegisterService(hostname, "_uart_data._tcp", "local", 5001, &txtRecord); + if(ua_socket->dnsServiceRef == NULL) + ua_printf(UA_ERROR, "mdns data service register failed!"); + ua_socket->dnsServiceRef2 = mDNSRegisterService(hostname, "_uart_control._tcp", "local", 6001, &txtRecord); + if(ua_socket->dnsServiceRef2 == NULL) + ua_printf(UA_ERROR, "mdns control service register failed!"); + TXTRecordDeallocate(&txtRecord); + + }else{ + ua_printf(UA_INFO, "mDNS Init Failed"); + } + + //vTaskDelete(NULL); +} +#endif + + +#define _________INIT__RELATED________________________ +static void uartadapter_auto_reconnect(void* param) +{ + ua_socket_t *ua_socket = (ua_socket_t *)param; + uint32_t IPaddress, IPaddress2; + uint8_t iptab[4], iptab2[4]; + //int ret = 0; + + ua_reconnect_started = 1; + +#if CONFIG_AUTO_RECONNECT + wifi_set_autoreconnect(0); +#endif + vTaskDelay(1000); + while(uartadapter_load_wifi_config() != RTW_SUCCESS){ + vTaskDelay(2000); + } +#if CONFIG_AUTO_RECONNECT + wifi_set_autoreconnect(1); +#endif + + ua_printf(UA_INFO, "uart adapter reconnect successful"); + //uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_OFF); + + if(0 == memcmp(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t))){ + IPaddress = ua_socket->ip.addr; + iptab[0] = (uint8_t)(IPaddress >> 24); + iptab[1] = (uint8_t)(IPaddress >> 16); + iptab[2] = (uint8_t)(IPaddress >> 8); + iptab[3] = (uint8_t)(IPaddress); + ua_printf(UA_INFO, "reconnect IP address no change, %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]); + }else{ + IPaddress = ua_socket->ip.addr; + iptab[0] = (uint8_t)(IPaddress >> 24); + iptab[1] = (uint8_t)(IPaddress >> 16); + iptab[2] = (uint8_t)(IPaddress >> 8); + iptab[3] = (uint8_t)(IPaddress); + IPaddress2 = xnetif[0].ip_addr.addr; + iptab2[0] = (uint8_t)(IPaddress2 >> 24); + iptab2[1] = (uint8_t)(IPaddress2 >> 16); + iptab2[2] = (uint8_t)(IPaddress2 >> 8); + iptab2[3] = (uint8_t)(IPaddress2); + ua_printf(UA_INFO, "reconnect IP address changed from %d.%d.%d.%d to %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0], iptab2[3], iptab2[2], iptab2[1], iptab2[0]); + memcpy(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t)); + ua_reconnect_ip_change = 1; + + ua_printf(UA_INFO,"IP changed, remove TCP information in FLASH!"); + ua_socket->tcp.group_id = 0; + ua_socket->tcp.client_port = 0; + ua_socket->tcp.server_port = 0; + memset(ua_socket->tcp.client_ip, 0, 16); + +#ifdef MDNS_LIB_EN + uartadapter_mdns_start(ua_socket, 1); +#endif + } + + + ua_reconnect_started = 0; + vTaskDelete(NULL); +} + +void uartadapter_auto_connect(void *param) +{ + int ret = 0; + ua_socket_t *ua_socket = (ua_socket_t *)param; + + UA_SOCKET_CHECK(ua_socket); + + if(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS) { + ua_printf(UA_INFO, "wifi connect successfully!"); + }else{ +#if CONFIG_AUTO_RECONNECT + wifi_set_autoreconnect(0); +#endif +RETRY: + vTaskDelay(2000); + ret = uartadapter_load_wifi_config(); + if(ret != RTW_SUCCESS){ + vTaskDelay(2000); +#if CONFIG_INCLUDE_SIMPLE_CONFIG + ret = uartadapter_simple_config(NULL); + if(ret != RTW_SUCCESS){ + ua_printf(UA_INFO, "Simple configure connect failed, try again!"); + goto RETRY; + } +#endif + } +#if CONFIG_AUTO_RECONNECT + wifi_set_autoreconnect(1); +#endif + } + + ua_wifi_connected = 1; + //uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_OFF); + + memcpy(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t)); + + if(!sys_thread_new("tcp data server", uartadapter_tcp_chat_server_thread, (void *)ua_socket, 256, UA_UART_THREAD_PRIORITY)) + ua_printf(UA_ERROR, "%s sys_thread_new data server failed\n", __FUNCTION__); + + vTaskDelay(50); + if(!sys_thread_new("tcp control server", uartadapter_tcp_control_server_thread, (void *)ua_socket, 256, UA_UART_THREAD_PRIORITY)) + ua_printf(UA_ERROR, "%s sys_thread_new control server failed\n", __FUNCTION__); + + vTaskDelay(50); + + if(!sys_thread_new("tcp select", uartadapter_tcp_select_thread, (void *)ua_socket, 768, UA_UART_THREAD_PRIORITY)) + ua_printf(UA_ERROR, "%s sys_thread_new tcp select failed\n", __FUNCTION__); + + vTaskDelay(50); + + uartadapter_control_read_tcp_info_and_connect(ua_socket); + + vTaskDelay(50); +#ifdef MDNS_LIB_EN + uartadapter_mdns_start(ua_socket, 0); + + vTaskDelay(50); +#endif + + ua_printf(UA_INFO, "[MEM] After auao connect, available heap %d", xPortGetFreeHeapSize()); + + /* Kill init thread after all init tasks done */ + vTaskDelete(NULL); +} + +void uartadapter_exception_thread(void *param) +{ + int ret = 0; + unsigned int tick_start; + unsigned int tick_current; + int pin_high = 0; + int address = FAST_RECONNECT_DATA; + + ua_socket_t *ua_socket = (ua_socket_t *)param; + + while(RtlDownSema(&ua_exception_sema) == pdTRUE){ + if(ua_gpio_irq_happen){ + pin_high = 0; + tick_start = xTaskGetTickCount(); + tick_current = xTaskGetTickCount(); + while(tick_current - tick_start < 3000){ + if (gpio_read(&ua_socket->gpio.gpio_btn)){ + pin_high = 1; + break; + }else{ + tick_current = xTaskGetTickCount(); + } + vTaskDelay(10); + } + + ua_gpio_irq_happen = 0; + if(!pin_high){ + ret = uartadapter_flasherase(address, sizeof(rtw_wifi_config_t)); + if(ret < 0){ + ua_printf(UA_ERROR, "flash erase error!"); + } + + ret = uartadapter_flasherase(UA_FAST_RECONNECT_TCP_DATA, sizeof(ua_tcp_socket_t)); + if(ret < 0){ + ua_printf(UA_ERROR, "flash erase error!"); + } + + uartadapter_systemreload(); + } + } + } + + vTaskDelete(NULL); +} + +ua_socket_t* uartadapter_socket_init() +{ + ua_socket_t* ua_socket = NULL; + //int ret = 0; + + ua_socket = pvPortMalloc(sizeof(ua_socket_t)); + + if(NULL == ua_socket){ + ua_printf(UA_ERROR, "Allocate uart adapter socket failed."); + goto Exit2; + } + + ua_socket->uart.rcv_ch = 0; + ua_socket->uart.overlap = 0; + ua_socket->uart.recv_bytes = 0; + ua_socket->uart.pread = 0; + ua_socket->uart.pwrite = 0; + ua_socket->uart.tick_last_update = 0; + ua_socket->uart.tick_current = 0; + ua_socket->uart.rx_cnt = 0; + ua_socket->uart.miss_cnt = 0; + ua_socket->uart.tx_busy = 0; + RtlInitSema(&ua_socket->uart.action_sema, 0); + RtlInitSema(&ua_socket->uart.tcp_tx_rx_sema, 1); + RtlInitSema(&ua_socket->uart.dma_tx, 1); + + ua_socket->tcp.chat_socket= -1; + ua_socket->tcp.control_socket= -1; + ua_socket->tcp.chat_server_listen_socket= -1; + ua_socket->tcp.control_server_listen_socket= -1; + + ua_socket->tcp.transmit_recv_socket = -1; + ua_socket->tcp.transmit_send_socket = -1; + ua_socket->tcp.transmit_server_listen_socket = -1; + + ua_socket->tcp.group_id = 0; + ua_socket->tcp.server_port = 0; + ua_socket->tcp.client_port = 0; + memset(ua_socket->tcp.client_ip, 0, 16); + + ua_socket->tcp.send_flag = 0; + ua_socket->tcp.recv_flag = 0; + ua_socket->tcp.rx_cnt = 0; + ua_socket->tcp.tx_cnt = 0; + + ua_socket->uart.uart_ps = 0; + ua_socket->uart.uart_ps_cnt = 0; + ua_socket->tcp.tcp_ps = 0; + ua_socket->tcp.tcp_ps_cnt = 0; + + ua_socket->dnsServiceRef = NULL; + ua_socket->dnsServiceRef2 = NULL; + + return ua_socket; + +Exit2: + return NULL; + +} + +void uartadapter_disconnect_handler(char *buf, int buf_len, int flags, void *userdata) +{ + if(!ua_wifi_connected || ua_reconnect_started) + return; + + ua_printf(UA_DEBUG, "start uart adapter reconnect thread\r\n"); + //uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_FAST_TWINKLE); + + if(xTaskCreate(uartadapter_auto_reconnect, ((const char*)"reconnect"), 512, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(uart_rx) failed", __FUNCTION__); + +} + +int uartadapter_init() +{ + int ret = 0; + + RtlInitSema(&ua_print_sema, 1); + + ua_printf(UA_INFO, "==============>%s()\n", __func__); + + ua_global_socket = uartadapter_socket_init(); + if(ua_global_socket == NULL){ + ua_printf(UA_ERROR, "ua_socket init failed"); + ret = -1; + goto Exit; + } + +#if !UA_PS_ENABLE + acquire_wakelock(UA_WAKELOCK); +#endif + + RtlInitSema(&ua_exception_sema, 0); + + uartadapter_uart_init(ua_global_socket); + + uartadapter_gpio_init(ua_global_socket); + //uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_FAST_TWINKLE); + + wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, uartadapter_disconnect_handler, NULL); + + if(xTaskCreate(uartadapter_uart_rx_thread, ((const char*)"uart_rx"), 256, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(uart_rx) failed", __FUNCTION__); + + vTaskDelay(50); + + if(xTaskCreate(uartadapter_auto_connect, ((const char*)"auto connnect"), 1024, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(auao connnect) failed", __FUNCTION__); + + vTaskDelay(50); + + if(xTaskCreate(uartadapter_exception_thread, ((const char*)"uart main"), 128, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(auao connnect) failed", __FUNCTION__); + + return 0; +Exit: + ua_printf(UA_ERROR, "%s(): Initialization failed!", __func__); + return ret; +} + +void example_uart_adapter_init() +{ + // Call back from wlan driver after wlan init done + p_wlan_uart_adapter_callback = uartadapter_init; +} + +#define _________CMD__RELATED________________________ +void uartadapter_print_irq_rx_count(ua_socket_t *ua_socket) +{ + UA_SOCKET_CHECK(ua_socket); + + ua_printf(UA_INFO, "ua_tick_last_update: %d!\n", ua_socket->uart.tick_last_update); + ua_printf(UA_INFO, "ua_tick_current: %d!\n", ua_socket->uart.tick_current); + ua_printf(UA_INFO, "ua current tick: %d!\n", xTaskGetTickCount()); + ua_printf(UA_INFO, "ua_pwrite: %d!\n", ua_socket->uart.pwrite); + ua_printf(UA_INFO, "ua_pread: %d!\n", ua_socket->uart.pread); + ua_printf(UA_INFO, "ua_overlap: %d!\n", ua_socket->uart.overlap); + ua_printf(UA_INFO, "ua_rcv_ch: %d!\n", ua_socket->uart.rcv_ch); + ua_printf(UA_INFO, "ua_uart_recv_bytes: %d!\n", ua_socket->uart.recv_bytes); + ua_printf(UA_INFO, "irq_rx_cnt: %d!\n", ua_socket->uart.rx_cnt); + ua_printf(UA_INFO, "irq_miss_cnt: %d!\n", ua_socket->uart.miss_cnt); + ua_printf(UA_INFO, "tcp_tx_cnt: %d!\n", ua_socket->tcp.tx_cnt); + ua_printf(UA_INFO, "tcp_rx_cnt: %d!\n", ua_socket->tcp.rx_cnt); + ua_printf(UA_INFO, "tcp_send_flag: %d!\n", ua_socket->tcp.send_flag); + ua_printf(UA_INFO, "tcp_recv_flag: %d!\n", ua_socket->tcp.recv_flag); + ua_printf(UA_INFO, "tcp_chat_socket: %d!\n", ua_socket->tcp.chat_socket); + ua_printf(UA_INFO, "tcp_control_socket: %d!\n", ua_socket->tcp.control_socket); + ua_printf(UA_INFO, "tcp_transmit_recv_socket: %d!\n", ua_socket->tcp.transmit_recv_socket); + ua_printf(UA_INFO, "tcp_transmit_send_socket: %d!\n", ua_socket->tcp.transmit_send_socket); + ua_printf(UA_INFO, "tcp_chat_server_listen_socket: %d!\n", ua_socket->tcp.chat_server_listen_socket); + ua_printf(UA_INFO, "tcp_control_server_listen_socket: %d!\n", ua_socket->tcp.control_server_listen_socket); + ua_printf(UA_INFO, "tcp_transmit_server_listen_socket: %d!\n", ua_socket->tcp.transmit_server_listen_socket); + +} + +void uartadapter_reset_irq_rx_count(ua_socket_t *ua_socket) +{ + UA_SOCKET_CHECK(ua_socket); + + ua_socket->uart.rx_cnt = 0; + ua_socket->uart.miss_cnt = 0; + ua_socket->tcp.rx_cnt = 0; + ua_socket->tcp.tx_cnt = 0; +} + +void uartadapter_set_debug_print(bool enable) +{ + ua_debug_print_en = enable; +} + +void cmd_uart_adapter(int argc, char **argv) +{ + if(argc < 2) { + printf(" input error\n"); + return; + } + + if(strcmp(argv[1], "help") == 0){ + printf("UART THROUGH COMMAND LIST:\n"); + printf("==============================\n"); + printf("tuart_baud\n"); + printf("\n"); + }else if(strcmp(argv[1], "irq_rx_get") == 0){ + uartadapter_print_irq_rx_count(ua_global_socket); + }else if(strcmp(argv[1], "debug_print_en") == 0){ + uartadapter_set_debug_print(TRUE); + }else if(strcmp(argv[1], "debug_print_dis") == 0){ + uartadapter_set_debug_print(FALSE); + }else if(strcmp(argv[1], "irq_rx_reset") == 0){ + uartadapter_reset_irq_rx_count(ua_global_socket); + }else if(strcmp(argv[1], "tcp") == 0){ + unsigned int port; + if(strcmp(argv[2], "-c") == 0 || strcmp(argv[2], "c") == 0){ + strncpy(ua_tcp_server_ip, argv[3], (strlen(argv[3])>16)?16:strlen(argv[3])); + port = atoi(argv[4]); + if(xTaskCreate(uartadapter_tcp_transmit_client_thread, ((const char*)"tclient"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__); + }else if(strcmp(argv[2], "-s") == 0 || strcmp(argv[2], "s") == 0){ + port = atoi(argv[3]); + if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS) + ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__); + } + }else if(strcmp(argv[1], "uart_baud") == 0){ + uartadapter_uart_baud(ua_global_socket, atoi(argv[2])); + }else if(strcmp(argv[1], "uart_para") == 0){ + uartadapter_uart_para(ua_global_socket, atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); + }else if(strcmp(argv[1], "led") == 0){ + //uartadapter_gpio_led_mode(ua_global_socket, atoi(argv[2])); + }else{ + printf("Can not find the input command!\n"); + } +} + +#endif // #if CONFIG_UART_SOCKET diff --git a/USDK/component/common/application/uart_adapter/uart_adapter.h b/USDK/component/common/application/uart_adapter/uart_adapter.h new file mode 100644 index 0000000..89f526f --- /dev/null +++ b/USDK/component/common/application/uart_adapter/uart_adapter.h @@ -0,0 +1,272 @@ +#include "osdep_api.h" +#include "serial_api.h" +#include +#include "freertos_pmu.h" +#include + +#if CONFIG_UART_SOCKET + +/****************************************************** + * Macros + ******************************************************/ +#define UA_ERROR 0 +#define UA_WARNING 1 +#define UA_INFO 2 +#define UA_DEBUG 2 //pvvx! было 3 +#define UA_NONE 0xFF +#define UA_DEBUG_LEVEL UA_INFO + +#define UA_UART_THREAD_PRIORITY 5 +#define UA_UART_THREAD_STACKSIZE 512 + +#define UA_TCP_SERVER_FD_NUM 1 +#define UA_TCP_CLIENT_FD_NUM 1 + +#define UA_UART_RECV_BUFFER_LEN 8196 +#define UA_UART_FRAME_LEN 1400 +#define UA_UART_MAX_DELAY_TIME 100 + +#define UA_CHAT_SOCKET_PORT 5001 +#define UA_CONTROL_SOCKET_PORT 6001 + +#define UA_UART_TX_PIN PA_4 +#define UA_UART_RX_PIN PA_0 +#define UA_UART_RTS_PIN PA_2 +#define UA_UART_CTS_PIN PA_1 + +#define UA_GPIO_LED_PIN PC_5 +#define UA_GPIO_IRQ_PIN PC_4 + +#define UA_CONTROL_PREFIX "AMEBA_UART" + +#define UA_PS_ENABLE 0 +#define UA_GPIO_WAKEUP_PIN PC_3 +#define UA_WAKELOCK WAKELOCK_USER_BASE + +#define UA_FAST_RECONNECT_TCP_DATA (0x80000 - 0x2000) + + +#if (UA_DEBUG_LEVEL== UA_NONE) +#define ua_printf(level, fmt, arg...) +#else +#define ua_printf(level, fmt, arg...) \ +do {\ + if (level <= UA_DEBUG_LEVEL) {\ + if (level <= UA_ERROR) {\ + RtlDownSema(&ua_print_sema);\ + printf("\r\nERROR: " fmt, ##arg);\ + RtlUpSema(&ua_print_sema);\ + } \ + else {\ + RtlDownSema(&ua_print_sema);\ + printf("\r\n"fmt, ##arg);\ + RtlUpSema(&ua_print_sema);\ + } \ + }\ +}while(0) +#endif + +#define UA_PRINT_DATA(_HexData, _HexDataLen) \ + if(UA_DEBUG_LEVEL == UA_DEBUG) \ + { \ + int __i; \ + u8 *ptr = (u8 *)_HexData; \ + printf("--------Len=%d\n\r", _HexDataLen); \ + for( __i=0; __i<(int)_HexDataLen; __i++ ) \ + { \ + printf("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \ + if (((__i + 1) % 16) == 0) printf("\n\r"); \ + } \ + printf("\n\r"); \ + } + +#define UA_SOCKET_CHECK(_ua_socket) \ + if(_ua_socket == NULL) \ + { \ + printf("ERROR: ua_socket = NULL\n\r"); \ + return; \ + } + +#define UA_SOCKET_CHECK_2(_ua_socket) \ + if(_ua_socket == NULL) \ + { \ + printf("ERROR: ua_socket = NULL\n\r"); \ + return -1; \ + } + +/****************************************************** + * Constants + ******************************************************/ +typedef enum +{ + UART_ADAPTER_LED_ON = 0, + UART_ADAPTER_LED_OFF = 1, + UART_ADAPTER_LED_FAST_TWINKLE = 2, + UART_ADAPTER_LED_SLOW_TWINKLE = 3, +}ua_led_mode_t; + +typedef enum +{ + UART_CTRL_MODE_SET_REQ = 0, + UART_CTRL_MODE_SET_RSP = 1, + UART_CTRL_MODE_GET_REQ = 2, + UART_CTRL_MODE_GET_RSP = 3, +}ua_ctrl_mode_t; + +typedef enum +{ + UART_CTRL_TYPE_BAUD_RATE = 0x01, + UART_CTRL_TYPE_WORD_LEN = 0x02, + UART_CTRL_TYPE_PARITY = 0x04, + UART_CTRL_TYPE_STOP_BIT = 0x08, + UART_CTRL_TYPE_TCP_SERVER_CREATE = 0x10, + UART_CTRL_TYPE_TCP_SERVER_DELETE = 0x20, + UART_CTRL_TYPE_TCP_CLIENT_CONNECT = 0x40, + UART_CTRL_TYPE_TCP_CLIENT_DISCONNECT = 0x80, + UART_CTRL_TYPE_TCP_GROUP_ID = 0x100, +}ua_ctrl_type_t; + +enum sc_result { + SC_ERROR = -1, /* default error code*/ + SC_NO_CONTROLLER_FOUND = 1, /* cannot get sta(controller) in the air which starts a simple config session */ + SC_CONTROLLER_INFO_PARSE_FAIL, /* cannot parse the sta's info */ + SC_TARGET_CHANNEL_SCAN_FAIL, /* cannot scan the target channel */ + SC_JOIN_BSS_FAIL, /* fail to connect to target ap */ + SC_DHCP_FAIL, /* fail to get ip address from target ap */ + /* fail to create udp socket to send info to controller. note that client isolation + must be turned off in ap. we cannot know if ap has configured this */ + SC_UDP_SOCKET_CREATE_FAIL, + SC_SUCCESS, /* default success code */ +}; + + +/****************************************************** + * Structures + ******************************************************/ + typedef struct _ua_uart_param_t +{ + u8 WordLen; + u8 Parity; + u8 StopBit; + u8 FlowControl; + int BaudRate; +}ua_uart_param_t; + + +typedef struct _ua_uart_socket_t +{ + int fd; + char rcv_ch; + volatile char overlap; + int recv_bytes; + volatile int pread; + volatile int pwrite; + + volatile unsigned int tick_last_update; + unsigned int tick_current; + + volatile int tx_busy; + + volatile int uart_ps; + volatile int uart_ps_cnt; + + char recv_buf[UA_UART_RECV_BUFFER_LEN]; + + long rx_cnt; + long miss_cnt; + + serial_t uart_sobj; + ua_uart_param_t uart_param; + + _Sema action_sema; + _Sema tcp_tx_rx_sema; + _Sema dma_tx; +}ua_uart_socket_t; + +typedef struct _ua_tcp_socket_t +{ + int chat_socket; + int control_socket; + int chat_server_listen_socket; + int control_server_listen_socket; + + int transmit_recv_socket; + int transmit_send_socket; + int transmit_server_listen_socket; + + int group_id; + u32 server_port; + u32 client_port; + char client_ip[16]; + + + int send_flag; + int recv_flag; + long rx_cnt; + long tx_cnt; + + volatile int tcp_ps; + volatile int tcp_ps_cnt; +}ua_tcp_socket_t; + +typedef struct _ua_gpio_t +{ + gpio_t gpio_led; + gpio_t gpio_btn; + gpio_irq_t gpio_btn_irq; + gtimer_t gpio_timer; +}ua_gpio_t; + +typedef struct _ua_socket_t +{ + ua_uart_socket_t uart; + ua_tcp_socket_t tcp; + ua_gpio_t gpio; + ip_addr_t ip; + DNSServiceRef dnsServiceRef; + DNSServiceRef dnsServiceRef2; +}ua_socket_t; + +typedef struct _ua_mbox_buffer +{ + char data[UA_UART_FRAME_LEN]; + int data_len; +}ua_mbox_buffer_t; + +//Save Uart Settings when get uart information +typedef struct _ua_uart_get_str +{ + int BaudRate; //The baud rate + char number; //The number of data bits + char parity; //The parity(0: none, 1:odd, 2:evn, default:0) + char StopBits; //The number of stop bits + char FlowControl; //support flow control is 1 +}ua_uart_get_str; + +//Uart Setting information +typedef struct _ua_uart_set_str +{ + char UartName[8]; // the name of uart + int BaudRate; //The baud rate + char number; //The number of data bits + char parity; //The parity(default NONE) + char StopBits; //The number of stop bits + char FlowControl; //support flow control is 1 +}ua_uart_set_str; + + +int uartadapter_init(); +void uartadapter_tcp_send_data(ua_socket_t *ua_socket, char *buffer, int size); +void uartadapter_tcp_send_control(ua_socket_t *ua_socket, char *buffer, int size); +void uartadapter_tcp_transmit_server_thread(void *param); +void uartadapter_tcp_transmit_client_thread(void *param); +int uartadapter_tcpclient(ua_socket_t *ua_socket, const char *host_ip, unsigned short usPort); +void uartadapter_tcp_transmit_client_forever_thread(void *param); + + +void example_uart_adapter_init(); +void cmd_uart_adapter(int argc, char **argv); + +void uartadapter_tcp_transmit_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf); + +#endif // CONFIG_UART_SOCKET diff --git a/USDK/component/common/application/wigadget/cloud_link.c b/USDK/component/common/application/wigadget/cloud_link.c new file mode 100644 index 0000000..2206168 --- /dev/null +++ b/USDK/component/common/application/wigadget/cloud_link.c @@ -0,0 +1,83 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "wifi_conf.h" +#include "wifi_ind.h" +#include "google_nest.h" +#include "flash_api.h" +#include "wigadget.h" +#include +#include "lwip_netconf.h" +#include "shtc1.h" + +#define CLOUD_PORT 443 +extern struct netif xnetif[NET_IF_NUM]; + +void cloud_link_task(void *param){ + googlenest_context googlenest; + unsigned char URI[64]; + unsigned char data[97] = {0}; + unsigned char host_addr[64] = {0}; + flash_t cloud_flash; + u8 *mac = (u8 *)LwIP_GetMAC(&xnetif[0]); + char i[16], j[16]; + float temperature = 1.123f; + float humidity = 2.456f; + int ret = 0; + + vTaskDelay(2000); + + + sprintf(URI, "ht_sensor/%02x%02x%02x%02x%02x%02x.json", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + memset(host_addr, 0, sizeof(host_addr)); + if(flash_stream_read(&cloud_flash, FLASH_IOT_DATA, 97, (uint8_t *) data) == 1){ + + memset(host_addr, 0 , 64); + memcpy(host_addr, data+33, 64); + while(1) { + printf("\n=====>START CLOUD LINKING\n"); + memset(i, 0, 16); + memset(j, 0, 16); +#if PSEUDO_DATA + sprintf(i,"%.2f", temperature++); + sprintf(j, "%.2f", humidity++); + if(temperature > 60) + temperature = 1.123f; + if(humidity > 98) + humidity = 2.456f; +#else + ret = SHTC_GetTempAndHumi(&temperature, &humidity); + sprintf(i,"%.2f", temperature); + sprintf(j, "%.2f", humidity); +#endif + if(ret < 0) + printf("\n<-----LOCAL LINK FAILED!(get infor failed)\n"); + else{ + gen_json_data(i,j, data); + printf("\nCLOUD-LINK--Sending data : \n%s\n", data); + memset(&googlenest, 0, sizeof(googlenest_context)); + if(gn_connect(&googlenest, host_addr, CLOUD_PORT) == 0) { + if(gn_put(&googlenest, URI, data) != 0) + printf("PUT data failed!\n"); + gn_close(&googlenest); + printf("\n<=====CLOUD LINK OK!\n"); + } + else{ + printf("\n<=====CLOUD LINK FAILED!(google nest connecting)\n"); + } + free(data); + vTaskDelay(10000); + } + } + + } + else + printf("\n<=====CLOUD LINK FAILED!(flash reading)\n"); + +} + +void start_cloud_link(void) +{ +if(xTaskCreate(cloud_link_task, ((const char*)"cloud_link_task"), 3584, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); +} diff --git a/USDK/component/common/application/wigadget/cloud_link.h b/USDK/component/common/application/wigadget/cloud_link.h new file mode 100644 index 0000000..650c1f6 --- /dev/null +++ b/USDK/component/common/application/wigadget/cloud_link.h @@ -0,0 +1,11 @@ +#ifndef CLOUD_LINK_H +#define CLOUD_LINK_THREAD_H + +#include "wigadget.h" + +void start_cloud_link(void); +void cloud_link_task(void *param); + + +#endif + diff --git a/USDK/component/common/application/wigadget/shtc1.c b/USDK/component/common/application/wigadget/shtc1.c new file mode 100644 index 0000000..8965c99 --- /dev/null +++ b/USDK/component/common/application/wigadget/shtc1.c @@ -0,0 +1,186 @@ +#include "device.h" +#include "PinNames.h" +#include "osdep_api.h" +#include "i2c_api.h" +#include "pinmap.h" +#include "shtc1.h" +#include "platform_stdlib.h" + +#ifdef CONFIG_I2C_EN + +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 + +#define MBED_I2C_SLAVE_ADDR0 0x70 +#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001 + +#define MBED_I2C_BUS_CLK 100000 //hz +#define I2C_DATA_MAX_LENGTH 16 + +static uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +static uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +static int i2cdata_read_pos; + +static i2c_t i2cmaster; + +// Sensor Commands +#define READ_ID 0xEFC8 // command: read ID register +#define SOFT_RESET 0x805D // soft resetSample Code for SHTC1 +#define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled +#define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled +#define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled +#define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled + + +static int SHTC1_GetID(uint16_t *id); +static void SHTC1_WriteCommand(uint16_t cmd); +static int SHTC1_Read2BytesAndCrc(uint16_t *data); +static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum); +static float SHTC1_CalcTemperature(uint16_t rawValue); +static float SHTC1_CalcHumidity(uint16_t rawValue); + + +int SHTC_Init(uint16_t *pID) +{ + int error = NO_ERROR; + + DiagPrintf("SHTC1_Init\n"); + + i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK); + + if (pID == NULL ) + return NULL_ERROR; + error = SHTC1_GetID(pID); + + return error; +} + +static int SHTC1_GetID(uint16_t *id) +{ + int error = NO_ERROR; + uint8_t bytes[2]; + uint8_t checksum; + + SHTC1_WriteCommand(READ_ID); + + i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1); + i2cdata_read_pos = 0; + error = SHTC1_Read2BytesAndCrc(id); + + return error; +} + +static int SHTC1_Read2BytesAndCrc(uint16_t *data) +{ + int error; + int readed; + uint8_t bytes[2]; + uint8_t checksum; + + bytes[0] = i2cdata_read[i2cdata_read_pos++]; + bytes[1] = i2cdata_read[i2cdata_read_pos++]; + checksum = i2cdata_read[i2cdata_read_pos++]; + + error = SHTC1_CheckCrc(bytes, 2, checksum); + *data = (bytes[0] << 8) | bytes[1]; + + return error; +} + +static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum) +{ + uint8_t bit; // bit mask + uint8_t crc = 0xFF; // calculated checksum + uint8_t byteCtr; // byte counter + + for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++){ + crc ^= (data[byteCtr]); + for(bit = 8; bit > 0; --bit){ + if(crc & 0x80) + crc = (crc << 1) ^ POLYNOMIAL; + else + crc = (crc << 1); + } + } + + if(crc != checksum) + return CHECKSUM_ERROR; + else + return NO_ERROR; +} + +static void SHTC1_WriteCommand(uint16_t cmd) +{ + int writebytes; + + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} + +static float SHTC1_CalcTemperature(uint16_t rawValue) +{ + return 175.0 * (float)rawValue / 65536.0 - 45.0; +} + +static float SHTC1_CalcHumidity(uint16_t rawValue) +{ + return 100.0 * (float)rawValue / 65536.0; +} + +int SHTC_GetTempAndHumi(float *temp, float *humi) +{ + int error; + uint16_t rawValueTemp; + uint16_t rawValueHumi; + + SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR); + + i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1); + i2cdata_read_pos = 0; + error = NO_ERROR; + error |= SHTC1_Read2BytesAndCrc(&rawValueTemp); + error |= SHTC1_Read2BytesAndCrc(&rawValueHumi); + + if ( error == NO_ERROR ) { + *temp = SHTC1_CalcTemperature(rawValueTemp); + *humi = SHTC1_CalcHumidity(rawValueHumi); + } + + return error; +} + +static void example_shtc1_thread(void *param) +{ + int error; + uint16_t shtc1_id; + float temperature = 1.123f; + float humidity = 2.456f; + + DBG_8195A("sleep 10 sec. to wait for UART console\n"); + RtlMsleepOS(10000); + DBG_8195A("start i2c example - SHTC1\n"); + + error = SHTC_Init(&shtc1_id); + if ( error == NO_ERROR ) + DiagPrintf("SHTC1 init ok, id=0x%x\n", shtc1_id); + else { + DiagPrintf("SHTC1 init FAILED!\n"); + for(;;); + } + + while(1){ + error = SHTC_GetTempAndHumi(&temperature, &humidity); + rtl_printf("temp=%f, humidity=%f, error=%d\n", temperature, humidity, error); + RtlMsleepOS(1000); + } +} + +void example_shtc1(void) +{ + if(xTaskCreate(example_shtc1_thread, ((const char*)"example_shtc1_thread"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("%s xTaskCreate(init_thread) failed\n", __FUNCTION__); +} + +#endif //#ifdef CONFIG_I2C_EN diff --git a/USDK/component/common/application/wigadget/shtc1.h b/USDK/component/common/application/wigadget/shtc1.h new file mode 100644 index 0000000..f5259dc --- /dev/null +++ b/USDK/component/common/application/wigadget/shtc1.h @@ -0,0 +1,13 @@ +#ifndef SHTC1_H +#define SHTC1_H + +#define NO_ERROR 0x00 +#define ACK_ERROR 0x01 +#define CHECKSUM_ERROR 0x02 +#define NULL_ERROR 0x03 + +int SHTC_GetTempAndHumi(float *temp, float *humi); +int SHTC_Init(uint16_t *pID); +void example_shtc1(void); + +#endif diff --git a/USDK/component/common/application/wigadget/wigadget.c b/USDK/component/common/application/wigadget/wigadget.c new file mode 100644 index 0000000..3e4cdf4 --- /dev/null +++ b/USDK/component/common/application/wigadget/wigadget.c @@ -0,0 +1,743 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "wifi_conf.h" +#include "wifi_ind.h" +#include "sockets.h" +#include +#include +#include +#include "flash_api.h" +#include +#include "rom_wac_curve25519-donna.h" +#include "gpio_api.h" +#include "gpio_irq_api.h" +#include "cJSON.h" +#include "cloud_link.h" +#include "wigadget.h" +#include "shtc1.h" + +#if LWIP_SOCKET + +#define PORT 6866 +#define MAX_BUFFER_SIZE 256 +#define ENC_SIZE 64 +#define CONTROL_TYPE 1 +#define GPIO_SOFTAP_RESET_PIN PC_4 + +flash_t iot_flash; +uint8_t aes_key[16]; +static unsigned char tx_buffer[MAX_BUFFER_SIZE]; +static unsigned char rx_buffer[MAX_BUFFER_SIZE]; + +extern struct netif xnetif[NET_IF_NUM]; + +#define DEBUG_IOT 1 + +#define IOT_LOG(level, fmt, ...) printf("\n\r[IOT %s] %s: " fmt "\n", level, __FUNCTION__, ##__VA_ARGS__) +#if DEBUG_IOT == 2 +#define IOT_DEBUG(fmt, ...) IOT_LOG("DEBUG", fmt, ##__VA_ARGS__) +#else +#define IOT_DEBUG(fmt, ...) +#endif +#if DEBUG_IOT +#define IOT_ERROR(fmt, ...) IOT_LOG("ERROR", fmt, ##__VA_ARGS__) +#else +#define IOT_ERROR(fmt, ...) +#endif + +void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data); +void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len); + + + +#ifdef __GNUC__ +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else +#define GCC_VERSION 0 +#endif + +/* Test for GCC < 5.4.0 */ +#if GCC_VERSION > 50300 +extern unsigned int _freertos_arc4random(void); +#define wgg_arc4random _freertos_arc4random +// or #define wgg_arc4random _ws_arc4random +#else +static unsigned int wgg_arc4random(void) +{ + unsigned int res = xTaskGetTickCount(); + static unsigned int seed = 0xDEADB00B; + + seed = ((seed & 0x007F00FF) << 7) ^ + ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits + (res << 13) ^ (res >> 9); // using the clock too! + return seed; + +} +#endif + +static char *iot_itoa(int value) +{ + char *val_str; + int tmp = value, len = 1; + + while((tmp /= 10) > 0) + len ++; + + val_str = (char *) malloc(len + 1); + sprintf(val_str, "%d", value); + + return val_str; +} + + void gen_json_data(char *i, char *j, unsigned char *json_data) +{ + cJSON_Hooks memoryHook; + + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + memset(json_data, 0, ENC_SIZE); + + + cJSON *IOTJSObject = NULL; + char *data; + + + if((IOTJSObject = cJSON_CreateObject()) != NULL) { + + cJSON_AddItemToObject(IOTJSObject, "TEM", cJSON_CreateString(i)); + cJSON_AddItemToObject(IOTJSObject, "HUM", cJSON_CreateString(j)); + + data = cJSON_Print(IOTJSObject); + memcpy(json_data, data, strlen(data)); + cJSON_Delete(IOTJSObject); + free(data); + } + +} + +void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data) +{ + unsigned char iv[16] = {0}; + unsigned char* iv_bak = "AAAAAAAAAAAAAAAA"; + aes_encrypt_ctx enc_ctx; + + memset(&enc_ctx, 0, sizeof(enc_ctx)); + memset(iv, 0, sizeof(iv)); + memcpy(iv, iv_bak, sizeof(iv)); + memset(enc_data, 0, sizeof(enc_data)); + + aes_init(); + aes_encrypt_key(aes_key, 16, &enc_ctx); + aes_cbc_encrypt(plaint_text, enc_data, ENC_SIZE, iv, &enc_ctx); +} + +void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len) +{ + unsigned char iv[16] = {0}; + unsigned char* iv_bak = "AAAAAAAAAAAAAAAA"; + aes_decrypt_ctx dec_ctx; + + memset(&dec_ctx, 0, sizeof(dec_ctx)); + memset(iv, 0, sizeof(iv)); + memcpy(iv, iv_bak, sizeof(iv)); + memset(dec_data, 0, sizeof(dec_data)); + + aes_init(); + aes_decrypt_key(aes_key, 16, &dec_ctx); + aes_cbc_decrypt(enc_data, dec_data, data_len, iv, &dec_ctx); + IOT_DEBUG("Decrypt data: %s\r\n",dec_data); +} + +void iotapp_platform_reset(void) +{ + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); + osDelay(100); + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | + (1 << 2)); + while(1) osDelay(1000); +} + +void iotapp_reset_irq_handler(uint32_t id, gpio_irq_event event) +{ + printf("\n\r\n\r\n\r\n\r<<<<<>>>>>>\n\r\n\r\n\r\n\r"); + flash_erase_sector(&iot_flash, FLASH_IOT_DATA); + iotapp_platform_reset(); +} + +int local_link(unsigned char *tx_data) +{ + int sockfd, newsockfd; + socklen_t client; + struct sockaddr_in serv_addr, cli_addr; + uint8_t rx_data[ENC_SIZE]; + unsigned char enc_data[ENC_SIZE]; + unsigned char dec_data[ENC_SIZE]; + int ret = 0, opt = 1, k = 1, j; + char *result = NULL, *backup = NULL; + unsigned char *data = NULL; + char *delims = ", "; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + IOT_ERROR("ERROR opening socket"); + ret = -1; + goto exit2; + } + + if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){ + IOT_ERROR("ERROR on setting socket option"); + ret = -1; + goto exit2; + } + + memset((char *)&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(PORT); + + if (bind(sockfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) { + IOT_ERROR("ERROR on binding"); + ret = -1; + goto exit2; + } + if(listen(sockfd , 20) < 0){ + IOT_ERROR("ERROR on listening"); + ret = -1; + goto exit2; + } + client = sizeof(cli_addr); + if((newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&client)) < 0){ + IOT_ERROR("ERROR on accept"); + ret = -1; + goto exit; + } + if ((ret = read(newsockfd,rx_buffer,sizeof(rx_buffer))) < 0){ + IOT_ERROR("ERROR reading from socket"); + ret = -1; + goto exit; + } + IOT_DEBUG("cmd received: %s, length: %d\r\n",rx_buffer, ret); + +//Changing received data to string + if (!strncmp(rx_buffer, "[", strlen("["))){ + data = rx_buffer + strlen("["); + for(j = 1; j < 5; j++){ + if (data[ret - j] == ']') + data[ret -j] = '\0'; + } + } + else + strcpy(data, rx_buffer); + memset(rx_data, 0, sizeof(rx_data)); + result = strtok_r(data, delims, &backup); + rx_data[0]=(uint8_t)atoi(result); + while((result = strtok_r(NULL, delims, &backup)) != NULL) + rx_data[k++]=(uint8_t)atoi(result); + memset(dec_data, 0, sizeof(dec_data)); + +//Decrpyt the received data + decrypt_data_aes(rx_data, dec_data, 16); + + if(strncmp(dec_data, "request", strlen("request")) == 0){ +//Encrypt the sending data + memset(enc_data, 0, strlen(enc_data)); + encrypt_data_aes(tx_data, enc_data); +//Changing encrpyt data to JAVA type string + for (j = 0; j < ENC_SIZE; j++){ + char *temp; + temp = iot_itoa(enc_data[j]); + if(j == 0) + strcpy(tx_buffer, "["); + strcat(tx_buffer,temp); + if (j == (ENC_SIZE - 1)) + strcat(tx_buffer,"]"); + else + strcat(tx_buffer,","); + free(temp); + temp = NULL; + } + IOT_DEBUG("Data reply to APP: %s\r\nLength of data: %d\r\n", tx_buffer, strlen(tx_buffer)); + + if ((ret = write(newsockfd,tx_buffer,strlen(tx_buffer))) < 0){ + IOT_ERROR("ERROR writing to socket"); + ret = -1; + goto exit; + } + else + IOT_DEBUG("Sending %d bytes data OK!\r\n", ret); + } + else if(strncmp(dec_data, "remove", strlen("remove")) == 0){ + printf("\n\r\n\r\n\r\n\r<<<<<>>>>>>\n\r\n\r\n\r\n\r"); + flash_erase_sector(&iot_flash, FLASH_IOT_DATA); + write(newsockfd,"Remove OK",strlen("Remove OK")); + close(newsockfd); + close(sockfd); + iotapp_platform_reset(); + } + else{ + IOT_ERROR("ERROR wrong KEY or wrong request!"); + write(newsockfd,"The KEY or the request is not correct!",strlen("The KEY or the request is not correct!")); + ret = -1; + goto exit; + } + +exit: + if(close(newsockfd) != 0) + goto exit; + +exit2: + if(close(sockfd) != 0) + goto exit2; + return ret; +} + +static void local_link_task(void *param) +{ + unsigned char data[ENC_SIZE] = {0}; + vTaskDelay(1000); + char i[16], j[16]; + float temperature = 1.123f; + float humidity = 2.456f; + int ret = 0; + + while(1){ + memset(i, 0, 16); + memset(j, 0, 16); +#if PSEUDO_DATA + sprintf(i,"%.2f", temperature++); + sprintf(j, "%.2f", humidity++); + if(temperature > 60) + temperature = 1.123f; + if(humidity > 98) + humidity = 2.456f; +#else + ret = SHTC_GetTempAndHumi(&temperature, &humidity); + sprintf(i,"%.2f", temperature); + sprintf(j, "%.2f", humidity); +#endif + if(ret < 0) + printf("\r\n\r\n<-----LOCAL LINK FAILED!(get infor failed)\r\n\r\n"); + else{ + printf("\r\n\r\n----->START LOCAL LINKING\r\n\r\n"); + gen_json_data(i, j, data); + printf("Sending data : %s\r\n", data); + if (local_link(data) < 0) + printf("\r\n\r\n<-----LOCAL LINK FAILED!\r\n\r\n"); + else + printf("\r\n\r\n<-----LOCAL LINK OK!\r\n\r\n"); + vTaskDelay(1000); + } + } +} + +void start_local_link(void) +{ + if(xTaskCreate(local_link_task, ((const char*)"local_link_task"), 5376, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS) + printf("\n\r%s xTaskCreate failed", __FUNCTION__); +} +int pair_device(unsigned char *tx_buffer, unsigned char *rx_buffer, int handshake) +{ + int sockfd, newsockfd; + socklen_t clilen; + struct sockaddr_in serv_addr, cli_addr; + int ret = 0; + int opt = 1; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + IOT_ERROR("ERROR opening socket"); + ret = -1; + goto exit; + } + + if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){ + IOT_ERROR("ERROR on setting socket option"); + ret = -1; + goto exit; + } + + memset((char *)&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_len = sizeof(serv_addr); + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(PORT); + + if ((bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) { + IOT_ERROR("ERROR on binding"); + ret = -1; + goto exit; + } + if ((listen(sockfd, 5)) < 0){ + IOT_ERROR("ERROR on listening tcp server socket fd"); + ret = -1; + goto exit; + } + clilen = sizeof(cli_addr); + newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen); + if (newsockfd < 0) { + IOT_ERROR("ERROR on accept"); + ret = -1; + goto exit2; + } + ret = read(newsockfd, rx_buffer, MAX_BUFFER_SIZE); + if (ret <= 0){ + IOT_ERROR("ERROR reading from socket"); + ret = -1; + goto exit2; + } + IOT_DEBUG("Request received: %s, byte: %d\r\n",rx_buffer, ret); + if(handshake == 1){ + if(strncmp(rx_buffer,"PAIR", strlen("PAIR")) != 0){ + write(newsockfd, "ERROR", strlen("ERROR")); + IOT_ERROR("ERROR on first handshake!"); + ret = -1; + goto exit2; + } + } + else if(handshake == 2){ + if((rx_buffer == NULL) ||(strlen(rx_buffer) < 32)){ + write(newsockfd, "ERROR", strlen("ERROR")); + IOT_ERROR("ERROR on second handshake!"); + ret = -1; + goto exit2; + } + } + else if(handshake == 3){ + unsigned char account[64]; + unsigned char enc_acc[64]; + char *result = NULL, *backup = NULL; + unsigned char *data = NULL; + char *delims = ", "; + int j, k = 1; + if (!strncmp(rx_buffer, "[", strlen("["))){ + data = rx_buffer + strlen("["); + for(j = 1; j < 5; j++){ + if (data[ret - j] == ']') + data[ret -j] = '\0'; + } + } + else + strcpy(data, rx_buffer); + memset(enc_acc, 0, sizeof(enc_acc)); + result = strtok_r(data, delims, &backup); + enc_acc[0]=(uint8_t)atoi(result); + while((result = strtok_r(NULL, delims, &backup)) != NULL) + enc_acc[k++]=(uint8_t)atoi(result); + IOT_DEBUG("The value of k: %d", k); + memset(account, 0, sizeof(account)); + decrypt_data_aes(enc_acc, account, k); + + if((strncmp(account,"https://", strlen("https://"))) != 0){ + write(newsockfd, "ERROR", strlen("ERROR")); + IOT_ERROR("ERROR on third handshake!"); + ret = -1; + goto exit2; + } + else{ + IOT_DEBUG("The received Firebase URL:%s", account); + memset(rx_buffer, 0, strlen(rx_buffer)); + memcpy(rx_buffer, (account+strlen("https://")), (strlen(account) + strlen("https://"))); + } + } + ret = write(newsockfd, tx_buffer, strlen(tx_buffer)); + IOT_DEBUG("Data send: %s\r\n",tx_buffer); + + if (ret < 0){ + IOT_ERROR("ERROR writing to socket"); + } + +exit: + if(close(newsockfd) != 0) + goto exit; + +exit2: + if(close(sockfd) != 0) + goto exit2; + return ret; + +} + +static void pair_device_task(void) +{ + int i, j, k, HANDSHAKE; + uint8_t PAIR_STATE[1] = {0}; + + if(CONTROL_TYPE == 1){ + printf("\r\n\r\n<<<<<>>>>>\r\n\r\n"); + HANDSHAKE = 3; + } + else{ + printf("\r\n\r\n<<<<<>>>>>\r\n\r\n"); + HANDSHAKE = 2; + } + printf("\r\n\r\n=========>PAIR_STATE = 0 Start to pair\r\n\r\n"); + for(i = 0; i < HANDSHAKE; i++){ + static const uint8_t basepoint[32] = {9}; + uint8_t mysecret[32]; + uint8_t mypublic[32]; + uint8_t theirpublic[32] = {0}; + uint8_t shared_key[32]; +//First handshake + if(i == 0){ + printf("\r\n\r\n===>Start the first handshake\r\n\r\n"); + memset(tx_buffer, 0, sizeof(tx_buffer)); + memset(rx_buffer, 0, sizeof(rx_buffer)); + for(j = 0; j < 32; j ++) + mysecret[j] = (uint8_t) wgg_arc4random(); + mysecret[j] = '\0'; + curve25519_donna(mypublic, mysecret, basepoint); + for (j = 0; j < 32; j++){ + char *temp; + temp = iot_itoa(mypublic[j]); + if(j == 0) + strcpy(tx_buffer, "["); + strcat(tx_buffer,temp); + if (j == 31) + strcat(tx_buffer,"]"); + else + strcat(tx_buffer,","); + free(temp); + temp = NULL; + } + if(pair_device(tx_buffer, rx_buffer, 1) >= 0) + printf("\r\n\r\n<===First handshake OK!\r\n\r\n"); + else{ + i--; + printf("\r\n\r\n<===First handshake FAILED!\r\n\r\n"); + } + } +//Second handshake + if(i == 1){ + printf("\r\n\r\n=====>Start the second handshake\r\n\r\n"); + vTaskDelay(200); + memset(tx_buffer, 0, sizeof(tx_buffer)); + if(CONTROL_TYPE == 1) + memcpy(tx_buffer, "FIREBASE URL", sizeof("FIREBASE URL")); + else + memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK")); + memset(rx_buffer, 0, sizeof(rx_buffer)); + + if(pair_device(tx_buffer, rx_buffer, 2) >= 0){ + char *result = NULL, *backup = NULL; + unsigned char *data = NULL; + char *delims = ", "; + k = 1; + if (!strncmp(rx_buffer, "[", strlen("["))){ + data = rx_buffer + strlen("["); + int len; + len = strlen(data); + for(j = 1; j < 5; j++){ + if (data[len - j] == ']') + data[len -j] = '\0'; + } + } + else + strcpy(data, rx_buffer); + + memset(theirpublic, 0, sizeof(theirpublic)); + + result = strtok_r(data, delims, &backup); + theirpublic[0]=(uint8_t)atoi(result); + + while((result = strtok_r(NULL, delims, &backup)) != NULL) + theirpublic[k++] = (uint8_t)atoi(result); + + curve25519_donna(shared_key, mysecret, theirpublic); + for(j = 0; j < 16; j ++) + aes_key[j] = shared_key[j]; +//Store the KEY in FLASH + if(CONTROL_TYPE == 0){ + PAIR_STATE[0] = 1; + uint8_t data[33]; + memset(data, 0, 33); + memcpy(data, PAIR_STATE, 1); + memcpy(data+1, shared_key, 32); + flash_erase_sector(&iot_flash, FLASH_IOT_DATA); + flash_stream_write(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *) data); + IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]); + } + printf("\r\n\r\n<=====Second handshake OK!\r\n\r\n"); + } + else{ + i = i - 2; + printf("\r\n\r\n<=====Second handshake FAILED!\r\n\r\n"); + } + } +//Third handshake + if(i == 2){ + printf("\r\n\r\n=======>Start the third handshake\r\n\r\n"); + vTaskDelay(200); + + memset(tx_buffer, 0, sizeof(tx_buffer)); + memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK")); + memset(rx_buffer, 0, sizeof(rx_buffer)); + + if(pair_device(tx_buffer, rx_buffer, 3) >= 0){ + IOT_DEBUG("rx_buffer: %s, sizeof rx_buffer:%d\r\n", rx_buffer, sizeof(rx_buffer)); + PAIR_STATE[0] = 1; + uint8_t data[97]; + memset(data, 0, 97); + memcpy(data, PAIR_STATE, 1); + memcpy(data+1, shared_key, 32); + memcpy(data+33, rx_buffer, 64); + flash_erase_sector(&iot_flash, FLASH_IOT_DATA); + flash_stream_write(&iot_flash, FLASH_IOT_DATA, 97, (uint8_t *) data); + IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]); + + printf("\r\n\r\n<=======Third handshake OK!\r\n\r\n"); + } + else{ + i = i - 3; + printf("\r\n\r\n<=======Third handshake FAILED!\r\n\r\n"); + } + } + } + printf("\r\n\r\n<=========Pairing OK!\r\n\r\n"); +} + +static void mdns_task(void *param) +{ + DNSServiceRef dnsServiceRef = NULL; + TXTRecordRef txtRecord; + unsigned char txt_buf[128]; + uint8_t *mac, *ip; + int j, ret = 0; + uint8_t *flash_data; + uint8_t PAIR_STATE[1] = {0}; + static unsigned char MAC_ADD[21]; + static unsigned char IP[16]; + static unsigned char port[6]; + uint16_t shtc1_id; + +// Delay to wait for IP by DHCP and get the information of IP and MAC + printf("\n\r\n\r\n\r\n\r<<<<<>>>>>>\n\r\n\r\n\r\n\r"); + vTaskDelay(20000); + ip = LwIP_GetIP(&xnetif[0]); + mac = LwIP_GetMAC(&xnetif[0]); + + sprintf(MAC_ADD, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(IP, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + sprintf(port, "%d", PORT); + + IOT_DEBUG("MAC => %s\r\n", MAC_ADD) ; + IOT_DEBUG("IP => %s\r\n", IP); + IOT_DEBUG("PORT => %s\r\n", port); + +//Get the value of PAIR_STATE and the AES key in flash + flash_data = (uint8_t *)malloc(33); + flash_stream_read(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *)flash_data); + memcpy(PAIR_STATE, flash_data, 1); + if(PAIR_STATE[0] != 0x1) + PAIR_STATE[0] = 0; + else{ + for(j = 0;j < 16; j++){ + aes_key[j] = flash_data[j+1]; + } + } + free(flash_data); + IOT_DEBUG("PAIR_STATE now: %d\r\n", PAIR_STATE[0]); + + IOT_DEBUG("=>mDNS Init\r\n"); + if(mDNSResponderInit() == 0) { + printf("\r\n\r\n========>Start to register mDNS service\r\n\r\n"); +//The device not paired before + if(PAIR_STATE[0] == 0){ + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + + TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP); + TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port); + TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD); + TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("0"), "0"); + TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor"); + if(CONTROL_TYPE == 1) + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1"); + else + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0"); + dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord); + TXTRecordDeallocate(&txtRecord); + printf("\r\n\r\n<========Registering mDNS service OK!\r\n\r\n"); + pair_device_task(); + } +//The device was paired + else if(PAIR_STATE[0] == 0x1){ + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + + TXTRecordSetValue(&txtRecord, "IP", strlen(ip), ip); + TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port); + TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD); + TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1"); + TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor"); + if(CONTROL_TYPE == 1) + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1"); + else + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0"); + + dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord); + TXTRecordDeallocate(&txtRecord); + printf("\r\n\r\n<========Registering mDNS service OK! PAIR_STATE = 1\r\n\r\n"); + } +#if PSEUDO_DATA + printf("\r\n\r\n========>Using the speudo data\r\n\r\n"); + if(CONTROL_TYPE == 1) start_cloud_link(); + start_local_link(); +#else +//Init the shtc1 sensor + printf("\r\n\r\n========>Init the temperature and humidity sensor\r\n\r\n"); + ret = SHTC_Init(&shtc1_id); + if ( ret == NO_ERROR ){ + printf("\r\n\r\n<========Senser init OK! ID = 0x%x \r\n\r\n", shtc1_id); + if(CONTROL_TYPE == 1) start_cloud_link(); + start_local_link(); + } + else { + printf("\r\n\r\n<========Senser init FAILED! ID = 0x%x \r\n\r\n", shtc1_id); + ret = -1; + } +#endif + + } + else + ret = -1; + if(ret == 0){ + while(1){ + IOT_DEBUG("Update the mDNS textrecord!\r\n"); + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP); + TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port); + TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD); + TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1"); + if(CONTROL_TYPE == 1) + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1"); + else + TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0"); + TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor"); + + mDNSUpdateService(dnsServiceRef, &txtRecord, 0); + TXTRecordDeallocate(&txtRecord); + vTaskDelay(2*60*1000); + } + } + else{ + if(dnsServiceRef) + mDNSDeregisterService(dnsServiceRef); + IOT_DEBUG("<=mDNS Deinit\r\n\r\n"); + mDNSResponderDeinit(); + } +} + +void example_wigadget(void) +{ + if(xTaskCreate(mdns_task, ((const char*)"mdns_task"), 3072, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate failed", __FUNCTION__); + + gpio_t gpio_softap_reset_button; + gpio_irq_t gpioirq_softap_reset_button; + + gpio_irq_init(&gpioirq_softap_reset_button, GPIO_SOFTAP_RESET_PIN, iotapp_reset_irq_handler, (uint32_t)(&gpio_softap_reset_button)); + gpio_irq_set(&gpioirq_softap_reset_button, IRQ_FALL, 1); + gpio_irq_enable(&gpioirq_softap_reset_button); +} + +#endif // LWIP_SOCKET diff --git a/USDK/component/common/application/wigadget/wigadget.h b/USDK/component/common/application/wigadget/wigadget.h new file mode 100644 index 0000000..e8301c8 --- /dev/null +++ b/USDK/component/common/application/wigadget/wigadget.h @@ -0,0 +1,11 @@ +#ifndef WIGADGET_H +#define WIGADGET_H + +#define FLASH_IOT_DATA (0x0007E000) +#define PSEUDO_DATA 1 + +void example_wigadget(void); +void gen_json_data(char *i, char *j, unsigned char *json_data); + +#endif /* WIGADGET_H */ + diff --git a/USDK/component/common/application/xmodem/uart_fw_update.c b/USDK/component/common/application/xmodem/uart_fw_update.c new file mode 100644 index 0000000..2aceb5f --- /dev/null +++ b/USDK/component/common/application/xmodem/uart_fw_update.c @@ -0,0 +1,1127 @@ +/******************************************************************************** + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "xmport_uart.h" +#include "xmport_loguart.h" +#include "rtl8195a.h" +#include "xmodem.h" +#include "xmport_uart.h" +#include "hal_spi_flash.h" +#include "rtl8195a_spi_flash.h" +#include +#include + +#if CONFIG_UART_SOCKET +#if /*CONFIG_PERI_UPDATE_IMG*/1 + + +#define USE_FLASH_API 1 + +#if USE_FLASH_API +#include "device_lock.h" +#include "flash_api.h" +#endif + +#ifndef FLASH_SECTOR_SIZE + #define FLASH_SECTOR_SIZE 4096 +#endif + +#define IMG1_SIGN_OFFSET 0x34 + +enum { + XMODEM_UART_0 = 0, + XMODEM_UART_1 = 1, + XMODEM_UART_2 = 2, + XMODEM_LOG_UART = 3 +}; + +FWU_DATA_SECTION char * xMFrameBuf; // [XM_BUFFER_SIZE]; +FWU_DATA_SECTION XMODEM_CTRL xMCtrl; + +FWU_DATA_SECTION static u32 fw_img1_size; +FWU_DATA_SECTION static u32 fw_img2_size; +FWU_DATA_SECTION static u32 fw_img2_addr; +FWU_DATA_SECTION static u32 fw_img3_size; +FWU_DATA_SECTION static u32 fw_img3_addr; +FWU_DATA_SECTION static u32 flash_wr_offset; +FWU_DATA_SECTION static u32 flash_erased_addr; +FWU_DATA_SECTION static u8 start_with_img1; +FWU_DATA_SECTION static u32 flash_wr_err_cnt; + +FWU_DATA_SECTION HAL_RUART_ADAPTER xmodem_uart_adp; // we can dynamic allocate memory for this object to save memory + +FWU_RODATA_SECTION const char Img2Signature[8] = IMG_SIGN_RUN; +extern u32 SpicCalibrationPattern[4]; +extern const u8 ROM_IMG1_VALID_PATTEN[]; +extern HAL_RUART_ADAPTER *pxmodem_uart_adp; + +#ifdef CONFIG_GPIO_EN +//extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter; +//extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; +#endif + +extern BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode); +_LONG_CALL_ +extern VOID SpicWaitBusyDoneRtl8195A(VOID); +extern VOID SpicWaitWipDoneRefinedRtl8195A(SPIC_INIT_PARA SpicInitPara); + +VOID WriteImg1Sign(u32 Image2Addr); + +void xDelayUs(u32 us) +{ + HalDelayUs(us); +} + +FWU_TEXT_SECTION void FWU_WriteWord(u32 Addr, u32 FData) +{ + SPIC_INIT_PARA SpicInitPara; + + HAL_WRITE32(SPI_FLASH_BASE, Addr, FData); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); +} + +FWU_TEXT_SECTION u32 xModem_MemCmp(const u32 *av, const u32 *bv, u32 len) +{ + const u32 *a = av; + const u32 *b = (u32*)((u8*)bv+SPI_FLASH_BASE); + u32 len4b = len >> 2; + u32 i; + + for (i=0; i 0) && (idx < frame_size)) { + flash_wr_offset--; + idx++; + skip_sz++; + } + + // "fw_img2_size" here is used as the memory length to write + // "fw_img2_addr" is used as the start memory address to write + while (idx < frame_size) { + if (fw_img2_size == 0) { + return idx; + } + + if (((fw_img2_addr & 0x03) == 0) && + (fw_img2_size > 3) && + ((frame_size - idx) > 3)) { + // write address is 4-byte aligned + *((u32*)fw_img2_addr) = (*((u32*)(ptr+idx))); + fw_img2_addr += 4; + fw_img2_size -= 4; + idx += 4; + } else if (fw_img2_size > 0){ + *((u8*)fw_img2_addr) = (*((u8*)(ptr+idx))); + fw_img2_addr++; + fw_img2_size--; + idx++; + } + } + + return (idx - skip_sz); +} + +FWU_TEXT_SECTION +u32 xModem_Frame_FlashWrite(char *ptr, unsigned int frame_num, unsigned int frame_size) +{ + u32 idx=0; + u32 skip_sz=0; + u32 temp; + u32 i; + + // "flash_wr_offset" here is used as the skip bytes from the head + while ((flash_wr_offset > 0) && (idx < frame_size)) { + flash_wr_offset--; + idx++; + skip_sz++; + } + + // "fw_img2_size" here is used as the memory length to write + // "fw_img2_addr" is used as the start memory address to write + while (idx < frame_size) { + if (fw_img2_size == 0) { + return idx; + } + + if ((fw_img2_size > 3) && ((frame_size - idx) > 3)) { + FWU_WriteWord(fw_img2_addr, (*((u32*)(ptr+idx)))); + fw_img2_addr += 4; + fw_img2_size -= 4; + idx += 4; + } else { + temp = 0xFFFFFFFF; + for (i=0;i<4;i++) { + // Just for little endian + *((((u8*)&temp) + i)) = (*((u8*)(ptr+idx))); + idx++; + fw_img2_size--; + if ((fw_img2_size == 0) || (idx >= frame_size)) { + break; + } + } + FWU_WriteWord(fw_img2_addr, temp); + fw_img2_addr += 4; + } + } + + return (idx - skip_sz); +} + +FWU_TEXT_SECTION +u32 xModem_Frame_Img2(char *ptr, unsigned int frame_num, unsigned int frame_size) +{ + u32 address; + u32 ImageIndex=0; + u32 rx_len=0; + u32 *chk_sr; + u32 *chk_dr; + u32 err_addr; + + if (frame_num == 1) { + // Parse Image2 header + flash_wr_offset = fw_img2_addr; + fw_img2_size = rtk_le32_to_cpu(*((u32*)ptr)) + 0x10; +/* + if ((fw_img2_size & 0x03) != 0) { + DBG_MISC_ERR("OTU: fw_img2_addr=0x%x fw_img2_size(%d) isn't 4-bytes aligned\n", fw_img2_addr, fw_img2_size); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + } +*/ + if (fw_img2_size > ((HalGetChipId() < CHIP_ID_8195AM) ? (0x80000-0x0B000) : (2*1024*1024))) { + DBG_MISC_ERR("OTU: fw_img2_addr=0x%x fw_img2_size(%d) to Big!\n", fw_img2_addr, fw_img2_size); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + } + printf("fw_img2_addr=0x%x fw_img2_size(%d)\n", fw_img2_addr, fw_img2_size); + fw_img3_addr = fw_img2_addr + fw_img2_size; + + // erase Flash first + address = fw_img2_addr & (~(FLASH_SECTOR_SIZE-1)); // 4k aligned, 4k is the page size of flash memory + while ((address) < (fw_img2_addr+fw_img2_size)) { + DBG_MISC_INFO("Flash Erase: %p\n", address); + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += FLASH_SECTOR_SIZE; + } + flash_erased_addr = address; + } + + if (fw_img2_size > 0) { + // writing image2 + chk_sr = (u32*)((u8*)ptr+ImageIndex); + chk_dr = (u32*)flash_wr_offset; + while (ImageIndex < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImageIndex)))); + ImageIndex += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img2_size -= 4; + if (fw_img2_size == 0) { + // Image2 write done, + break; + } + } + + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } + } + + if (ImageIndex >= frame_size) { + return rx_len; + } + + // Skip the gap between image2 and image3, + // there is no gap in current image format + if (flash_wr_offset < fw_img3_addr) { + if ((flash_wr_offset + (frame_size-ImageIndex)) <= fw_img3_addr) { + flash_wr_offset += (frame_size-ImageIndex); + return rx_len; + } else { + while (ImageIndex < frame_size) { + if (flash_wr_offset == fw_img3_addr) { + break; + } + ImageIndex += 4; + flash_wr_offset += 4; + } + } + } + + if (fw_img3_addr == flash_wr_offset) { + if (ImageIndex < frame_size) { + fw_img3_size = rtk_le32_to_cpu(*((u32*)(ptr+ImageIndex))); + if (fw_img3_size == 0x1A1A1A1A) { + // all padding bytes, no image3 + fw_img3_size = 0; + return rx_len; + } +/* + if ((fw_img3_size & 0x03) != 0) { + DBG_MISC_ERR("OTU Err#5: fw_img3_addr=0x%x fw_img3_size(%d) isn't 4-bytes aligned\n", fw_img3_addr, fw_img3_size); + fw_img3_size = 0; + return rx_len; + } +*/ + if (fw_img2_size > ((HalGetChipId() < CHIP_ID_8195AM) ? (0x80000 - fw_img3_addr) : (2*1024*1024))) { + DBG_MISC_ERR("OTU: fw_img3_addr=0x%x fw_img2_size(%d) to Big!\n", fw_img3_addr, fw_img3_size); + fw_img3_size = 0; + return rx_len; + } + + // Flash sector erase for image2 writing + if (flash_erased_addr >= fw_img3_addr) { + address = flash_erased_addr; + } else { + address = fw_img3_addr & (~(FLASH_SECTOR_SIZE-1)); // 4k aligned, 4k is the page size of flash memory + } + + while ((address) < (fw_img3_addr+fw_img3_size)) { + DBG_MISC_INFO("Flash Erase: %p\n", address); +#if 0 + if ((address & 0xFFFF) == 0) { + SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += FLASH_SECTOR_SIZE; // 1 block = 64k bytes + } + else +#endif + { + + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += FLASH_SECTOR_SIZE; // 1 sector = 4k bytes + } + } + flash_erased_addr = address; + } + } + + if (fw_img3_size > 0) { + // writing image3 + chk_sr = (u32*)((u8*)ptr+ImageIndex); + chk_dr = (u32*)flash_wr_offset; + while (ImageIndex < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImageIndex)))); + ImageIndex += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img3_size -= 4; + if (fw_img3_size == 0) { + // Image3 write done, + break; + } + } + + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } + } + + return rx_len; +} + +FWU_TEXT_SECTION +u32 xModem_Frame_ImgAll(char *ptr, unsigned int frame_num, unsigned int frame_size) +{ + int i; + u32 address; + u32 img_size; + u32 img_addr; + u32 ImgIdx=0; + u32 Img1Sign; + u32 rx_len=0; + u32 *chk_sr; + u32 *chk_dr; + u32 err_addr; + + if (frame_num == 1) { + // Check is it the start patten of image1 + start_with_img1 = 1; + for(i=0; i<4; i++) { + Img1Sign = rtk_le32_to_cpu(*((u32*)(ptr + i*4))); + if(Img1Sign != SpicCalibrationPattern[i]) { + start_with_img1 = 0; + break; + } + } + + // Get the image size: the first 4 bytes + if (start_with_img1) { + // Image1 + Image2 + // Check the Image1 Signature + i=0; + while (ROM_IMG1_VALID_PATTEN[i] != 0xff) { + if (ptr[i+IMG1_SIGN_OFFSET] != ROM_IMG1_VALID_PATTEN[i]) { + // image1 validation patten miss match + DBG_MISC_ERR("OTU: Image1 Signature Incorrect\n"); + fw_img1_size = 0; + fw_img2_size = 0; + fw_img2_addr = 0; + fw_img3_size = 0; + fw_img3_addr = 0; + return 0; + } else { + // make the signature all 0xff for now, write the signature when image1 download is done + ptr[i+IMG1_SIGN_OFFSET] = 0xff; + } + i++; + } + + flash_wr_offset = 0; + fw_img1_size = rtk_le32_to_cpu(*((u32*)(ptr + 0x10))) + 0x20; +/* if ((fw_img1_size & 0x03) != 0) { + DBG_MISC_WARN("OTU: fw_img1_size(0x%x) isn't 4-bytes aligned\n", fw_img1_size); + fw_img1_size = 0; + fw_img2_size = 0; + fw_img2_addr = 0; + fw_img3_size = 0; + fw_img3_addr = 0; + return 0; + } */ + address = 0; + img_size = fw_img1_size; + img_addr = 0; + fw_img2_addr = rtk_le16_to_cpu(*((u16*)(ptr + 0x18))) * 1024; + if (fw_img2_addr == 0) { + // it's old format: image1 & image2 is cascaded directly + fw_img2_addr = fw_img1_size; + } + fw_img2_size = 0; + DBG_MISC_INFO("Update Image All: Image1 Size=%d, Image2 Addr=0x%x\n", fw_img1_size, fw_img2_addr); + } else { + // It's image2(+image3) only + if (fw_img2_addr == 0) { + DBG_MISC_WARN("The single-image format in flash now, it cannot just update the image2\n"); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + } + + flash_wr_offset = fw_img2_addr; + fw_img1_size = 0; + fw_img2_size = rtk_le32_to_cpu(*((u32*)ptr)) + 0x10; + fw_img3_addr = fw_img2_addr + fw_img2_size; +/* if ((fw_img2_size & 0x03) != 0) { + DBG_MISC_ERR("OTU: fw_img2_size(0x%x) isn't 4-bytes aligned\n", fw_img2_size); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + } */ + address = fw_img2_addr & (~0xfff); // 4k aligned, 4k is the page size of flash memory + img_size = fw_img2_size; + img_addr = fw_img2_addr; + + DBG_MISC_INFO("Update Image2: Addr=0x%x, Size=%d\n", fw_img2_addr, fw_img2_size); + + } + + // erase Flash sector first + while ((address) < (img_addr+img_size)) { +// DBG_MISC_INFO("Flash Erase: 0x%x\n", address); + if ((address >= 0x10000 ) && ((address & 0xFFFF) == 0)) { + SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x10000; // 1 Block = 64k bytes + } + else + { + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x1000; // 1 sector = 4k bytes + } + } + flash_erased_addr = address; + } + + { + if (!start_with_img1) { + if (fw_img2_size > 0) { + chk_sr = (u32*)((u8*)ptr+ImgIdx); + chk_dr = (u32*)flash_wr_offset; + while (ImgIdx < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImgIdx)))); + ImgIdx += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img2_size -= 4; + if (fw_img2_size == 0) { + break; + } + + } + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } + } + } else { + ImgIdx = 0; + if (fw_img1_size > 0) { + // still writing image1 + chk_sr = (u32*)((u8*)ptr+ImgIdx); + chk_dr = (u32*)flash_wr_offset; + while (ImgIdx < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImgIdx)))); + ImgIdx += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img1_size -= 4; + if (fw_img1_size == 0) { + // Image1 write done, + break; + } + } + + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } else { + if (fw_img1_size == 0) { + // Write Image1 signature + WriteImg1Sign(IMG1_SIGN_OFFSET); + } + } + } + + if (ImgIdx >= frame_size) { + return rx_len; + } + + if (fw_img2_addr == 0) { + return rx_len; + } + + // Skip the section of system data + if (flash_wr_offset < fw_img2_addr) { + if ((flash_wr_offset + (frame_size-ImgIdx)) <= fw_img2_addr) { + flash_wr_offset += (frame_size-ImgIdx); + return rx_len; + } else { + while (ImgIdx < frame_size) { + if (flash_wr_offset == fw_img2_addr) { + break; + } + ImgIdx += 4; + flash_wr_offset += 4; + rx_len += 4; + } + } + } + + if (fw_img2_addr == flash_wr_offset) { + if (ImgIdx < frame_size) { + fw_img2_size = rtk_le32_to_cpu(*((u32*)(ptr+ImgIdx))) + 0x10; + fw_img3_addr = fw_img2_addr + fw_img2_size; +/* if ((fw_img2_size & 0x03) != 0) { + DBG_MISC_ERR("OTU: fw_img2_addr=0x%x fw_img2_size(%d) isn't 4-bytes aligned\n", fw_img2_addr, fw_img2_size); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + }*/ + + if (fw_img2_size > (2*1024*1024)) { + DBG_MISC_ERR("OTU: fw_img2_addr=0x%x fw_img2_size(%d) to Big\n", fw_img2_addr, fw_img2_size); + fw_img1_size = 0; + fw_img2_size = 0; + return rx_len; + } + + // Flash sector erase for image2 writing + if (flash_erased_addr >= fw_img2_addr) { + address = flash_erased_addr; + } else { + address = fw_img2_addr & (~0xfff); // 4k aligned, 4k is the page size of flash memory + } + + while ((address) < (fw_img2_addr+fw_img2_size)) { + DBG_MISC_INFO("Flash Erase: 0x%x\n", address); + if ((address & 0xFFFF) == 0) { + SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x10000; // 1 block = 64k bytes + } + else + { + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x1000; // 1 sector = 4k bytes + } + } + flash_erased_addr = address; + } + } + + if (fw_img2_size > 0) { + // writing image2 + chk_sr = (u32*)((u8*)ptr+ImgIdx); + chk_dr = (u32*)flash_wr_offset; + while (ImgIdx < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImgIdx)))); + ImgIdx += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img2_size -= 4; + if (fw_img2_size == 0) { + // Image2 write done, + break; + } + } + + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } + } + + if (ImgIdx >= frame_size) { + return rx_len; + } + + if (fw_img3_addr == flash_wr_offset) { + if (ImgIdx < frame_size) { + fw_img3_size = rtk_le32_to_cpu(*((u32*)(ptr+ImgIdx))); + if (fw_img3_size == 0x1A1A1A1A) { + // all padding bytes, no image3 + fw_img3_size = 0; +// DBG_8195A("No Img3\n"); + return rx_len; + } +/* if ((fw_img3_size & 0x03) != 0) { + DBG_MISC_ERR("OTU: fw_img3_addr=0x%x fw_img3_size(%d) isn't 4-bytes aligned\n", fw_img3_addr, fw_img3_size); + fw_img3_size = 0; + return rx_len; + } */ + + if (fw_img3_size > (2*1024*1024)) { + DBG_MISC_ERR("OTU: fw_img3_addr=0x%x fw_img2_size(%d) to Big!\n", fw_img3_addr, fw_img3_size); + fw_img3_size = 0; + return rx_len; + } + + // Flash sector erase for image2 writing + if (flash_erased_addr >= fw_img3_addr) { + address = flash_erased_addr; + } else { + address = fw_img3_addr & (~0xfff); // 4k aligned, 4k is the page size of flash memory + } + + while ((address) < (fw_img3_addr+fw_img3_size)) { + DBG_MISC_INFO("Flash Erase: 0x%x\n", address); + if ((address & 0xFFFF) == 0) { + SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x10000; // 1 block = 64k bytes + } + else + { + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + address += 0x1000; // 1 sector = 4k bytes + } + } + flash_erased_addr = address; + } + } + + if (fw_img3_size > 0) { + // writing image3 + chk_sr = (u32*)((u8*)ptr+ImgIdx); + chk_dr = (u32*)flash_wr_offset; + while (ImgIdx < frame_size) { + FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImgIdx)))); + ImgIdx += 4; + flash_wr_offset += 4; + rx_len += 4; + fw_img3_size -= 4; + if (fw_img3_size == 0) { + // Image3 write done, + break; + } + } + err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr)); + if (err_addr) { + flash_wr_err_cnt++; + } + } + + } + } + + return rx_len; +} + +FWU_TEXT_SECTION +s32 +xModem_Init_UART_Port(u8 uart_idx, u8 pin_mux, u32 baud_rate) +{ + if (uart_idx <= XMODEM_UART_2) { + // update firmware via generic UART + pxmodem_uart_adp = &xmodem_uart_adp; // we can use dynamic allocate to save memory +// pxmodem_uart_adp = RtlZmalloc(sizeof(HAL_RUART_ADAPTER)); + xmodem_uart_init(uart_idx, pin_mux, baud_rate); + xmodem_uart_func_hook(&(xMCtrl.ComPort)); + } else if(uart_idx == XMODEM_LOG_UART) { + // update firmware via Log UART +// DiagPrintf("Open xModem Transfer on Log UART...\n"); +// xmodem_loguart_init(); + xmodem_loguart_init(baud_rate); + xmodem_loguart_func_hook(&(xMCtrl.ComPort)); +// DiagPrintf("Please Start the xModem Sender...\n"); + } else { + // invalid UART port + DBG_MISC_ERR("OTU: Invaild UART port(%d)\n", uart_idx); + return -1; + } + + return 0; +} + +FWU_TEXT_SECTION +VOID +xModem_DeInit_UART_Port(u8 uart_idx) +{ + if (uart_idx <= XMODEM_UART_2) { + xmodem_uart_deinit(); + } else if (uart_idx == XMODEM_LOG_UART) { + xmodem_loguart_deinit(); + } +} + +FWU_TEXT_SECTION +__weak s32 +UpdatedImg2AddrValidate( + u32 Image2Addr, + u32 DefImage2Addr, + u32 DefImage2Size +) +{ + if (Image2Addr == 0xffffffff) { + // Upgraded Image2 isn't exist + return 0; // invalid address + } + + if ((Image2Addr & 0xfff) != 0) { + // Not 4K aligned + return 0; // invalid address + } + + if (Image2Addr <= DefImage2Addr) { + // Updated image2 address must bigger than the addrss of default image2 + return 0; // invalid address + } + + if (Image2Addr < (DefImage2Addr+DefImage2Size)) { + // Updated image2 overlap with the default image2 + return 0; // invalid address + } + + return 1; // this address is valid +} + +FWU_TEXT_SECTION +__weak s32 +Img2SignValidate( + u32 Image2Addr +) +{ + u32 img2_sig[3]; + s32 sign_valid=0; + + // Image2 header: Size(4B) + Addr(4B) + Signature(8B) + img2_sig[0] = HAL_READ32(SPI_FLASH_BASE, Image2Addr + 8); + img2_sig[1] = HAL_READ32(SPI_FLASH_BASE, Image2Addr + 12); + img2_sig[2] = 0; // end of string + + if (_memcmp((void*)img2_sig, (void*)Img2Signature, 8)) { + DBG_MISC_INFO("Invalid Image2 Signature:%s\n", img2_sig); + } else { + sign_valid = 1; + } + + return sign_valid; + +} + + +FWU_TEXT_SECTION +VOID +MarkImg2SignOld( + u32 Image2Addr +) +{ + u32 img2_sig; + + _memcpy((void*)&img2_sig, (void*)Img2Signature, 4); + *((char*)(&img2_sig)) = '0'; // '8' -> the latest image; '0' -> the older image + FWU_WriteWord((Image2Addr + 8), img2_sig); +} + +FWU_TEXT_SECTION +VOID +WriteImg1Sign( + u32 Image2Addr +) +{ + u32 img1_sig; + + _memcpy((void*)&img1_sig, (void*)ROM_IMG1_VALID_PATTEN, 4); + FWU_WriteWord(IMG1_SIGN_OFFSET, img1_sig); +} + +FWU_TEXT_SECTION +VOID +WriteImg2Sign( + u32 Image2Addr +) +{ + u32 img2_sig[2]; + + _memcpy((void*)img2_sig, (void*)Img2Signature, 8); + FWU_WriteWord((Image2Addr + 8), img2_sig[0]); + FWU_WriteWord((Image2Addr + 12), img2_sig[1]); +} + +FWU_TEXT_SECTION +u32 +SelectImg2ToUpdate( + u32 *OldImg2Addr +) +{ + u32 DefImage2Addr=0xFFFFFFFF; // the default Image2 addr. + u32 SecImage2Addr=0xFFFFFFFF; // the 2nd image2 addr. + u32 ATSCAddr=0xFFFFFFFF; + u32 UpdImage2Addr; // the addr of the image2 to be updated + u32 DefImage2Len; +#ifdef CONFIG_UPDATE_TOGGLE_IMG2 + u32 SigImage0,SigImage1; +#endif + + *OldImg2Addr = 0; + DefImage2Addr = (HAL_READ32(SPI_FLASH_BASE, 0x18)&0xFFFF) * 1024; + if ((DefImage2Addr != 0) && ((DefImage2Addr < (16*1024*1024)))) { + // Valid Default Image2 Addr: != 0 & located in 16M + DefImage2Len = HAL_READ32(SPI_FLASH_BASE, DefImage2Addr); + + // Get the pointer of the upgraded Image2 + SecImage2Addr = HAL_READ32(SPI_FLASH_BASE, FLASH_SYSTEM_DATA_ADDR); + + if (UpdatedImg2AddrValidate(SecImage2Addr, DefImage2Addr, DefImage2Len)) { + UpdImage2Addr = SecImage2Addr; // Update the 2nd image2 +#ifdef CONFIG_UPDATE_TOGGLE_IMG2 + // read Part1/Part2 signature + SigImage0 = HAL_READ32(SPI_FLASH_BASE, DefImage2Addr + 8); + SigImage1 = HAL_READ32(SPI_FLASH_BASE, DefImage2Addr + 12); + + DBG_8195A("\n\rPart1 Sig %x", SigImage0); + if(SigImage0==0x30303030 && SigImage1==0x30303030) + ATSCAddr = DefImage2Addr; // ATSC signature + else if(SigImage0==0x35393138 && SigImage1==0x31313738) + *OldImg2Addr = DefImage2Addr; // newer version, change to older version + else + UpdImage2Addr = DefImage2Addr; // update to older version + + SigImage0 = HAL_READ32(SPI_FLASH_BASE, SecImage2Addr + 8); + SigImage1 = HAL_READ32(SPI_FLASH_BASE, SecImage2Addr + 12); + DBG_8195A("\n\rPart2 Sig %x\n\r", SigImage0); + if(SigImage0==0x30303030 && SigImage1==0x30303030) + ATSCAddr = SecImage2Addr; // ATSC signature + else if(SigImage0==0x35393138 && SigImage1==0x31313738) + *OldImg2Addr = SecImage2Addr; + else + UpdImage2Addr = SecImage2Addr; + + // update ATSC clear partitin first + if(ATSCAddr != ~0x0){ + *OldImg2Addr = UpdImage2Addr; + UpdImage2Addr = ATSCAddr; + } +#endif // end of SWAP_UPDATE, wf, 1006 + } else { + // The upgraded image2 isn't exist or invalid so we can just update the default image2 + UpdImage2Addr = DefImage2Addr; // Update the default image2 + #ifdef CONFIG_UPDATE_TOGGLE_IMG2 + *OldImg2Addr = DefImage2Addr; +#endif + } + } else { + UpdImage2Addr = 0; + } + + return UpdImage2Addr; +} + + +FWU_TEXT_SECTION +void OTU_FW_Update(u8 uart_idx, u8 pin_mux, u32 baud_rate) +{ + u32 wr_len; + u32 OldImage2Addr=0; // the addr of the image2 will become old one + SPIC_INIT_PARA SpicInitPara; + + fw_img1_size = 0; + fw_img2_size = 0; + fw_img2_addr = 0; + fw_img3_size = 0; + fw_img3_addr = 0; + flash_wr_offset = 0; + flash_erased_addr = 0; + start_with_img1 = 0;; + flash_wr_err_cnt = 0; + xMFrameBuf = malloc(XM_BUFFER_SIZE); + if(xMFrameBuf == NULL) { + DBG_MISC_ERR("OTU: SPI Init Fail!\n"); + return; + } + +#if USE_FLASH_API + device_mutex_lock(RT_DEV_LOCK_FLASH); +#endif + SPI_FLASH_PIN_FCTRL(ON); + if (!SpicFlashInitRtl8195A(SpicOneBitMode)){ + SPI_FLASH_PIN_FCTRL(OFF); + DBG_MISC_ERR("OTU: SPI Init Fail!\n"); + goto end_error; + } + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + printf("FW Update Over UART%d, PinMux=%d, Baud=%d\n", uart_idx, pin_mux, baud_rate); + // Get the address of the image2 to be updated + fw_img2_addr = SelectImg2ToUpdate(&OldImage2Addr); + + // Start to update the Image2 through xModem on peripheral device + printf("FW Update Image2 @ 0x%x\n", fw_img2_addr); + // We update the image via xModem on UART now, if we want to uase other peripheral device + // to update the image then we need to redefine the API + if (xModem_Init_UART_Port(uart_idx, pin_mux, baud_rate) < 0) { + goto end_error; + } + +// xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_ImgAll); // Support Image format: Image1+Image2 or Image2 only + xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_Img2); // Support Image format: Image2 only +// xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_Dump); // for debugging + wr_len = xModemRxBuffer(&xMCtrl, (2*1024*1024)); + xModemEnd(&xMCtrl); + + xModem_DeInit_UART_Port(uart_idx); + + if ((wr_len > 0) && (flash_wr_err_cnt == 0)) { + // Firmware update OK, now write the signature to active this image + WriteImg2Sign(fw_img2_addr); +#ifdef CONFIG_UPDATE_TOGGLE_IMG2 + // Mark the other image2 as old one by modify its signature + if (OldImage2Addr != 0) { + printf("Mark Image2 @ 0x%x as Old\n", OldImage2Addr); + MarkImg2SignOld(OldImage2Addr); + } +#endif + } + printf("OTU_FW_Update Done, Write Len=%d\n", wr_len); +end_error: + SPI_FLASH_PIN_FCTRL(OFF); +#if USE_FLASH_API + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif + if(xMFrameBuf) { + free(xMFrameBuf); + xMFrameBuf = NULL; + } +} + +FWU_TEXT_SECTION +u8 OTU_check_gpio(void) +{ +#ifdef CONFIG_GPIO_EN + HAL_GPIO_PIN GPIO_Pin; + u8 enter_update; + + GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(0x21); //pin PC_1 + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + +// _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; + + HAL_GPIO_Init_8195a(&GPIO_Pin); + if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == GPIO_PIN_LOW) { + enter_update = 1; + } + else { + enter_update = 0; + } + HAL_GPIO_DeInit_8195a(&GPIO_Pin); + +// _pHAL_Gpio_Adapter = NULL; + return enter_update; +#else + return 0; +#endif +} + +FWU_TEXT_SECTION +u8 OTU_check_uart(u32 UpdateImgCfg){ + + if(((UpdateImgCfg>>4)&0x03) == 2){ + ACTCK_SDIOD_CCTRL(OFF); + + /* SDIO Function Disable */ + SDIOD_ON_FCTRL(OFF); + SDIOD_OFF_FCTRL(OFF); + + // SDIO Pin Mux off + SDIOD_PIN_FCTRL(OFF); + } + + if (xModem_Init_UART_Port(((UpdateImgCfg>>4)&0x03), (UpdateImgCfg&0x03), 115200) < 0) { + return 0; + } + + + char ch; + u8 x_count = 0; + int timeout1 = 500; + while (timeout1 != 0) { + if (xMCtrl.ComPort.poll()) { + ch = xMCtrl.ComPort.get(); + if(ch != 0x78){ + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 0; + } + x_count ++; + if(x_count == 5){ + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 1; + } + } + HalDelayUs(200); + timeout1--; + } + + if(!x_count){ + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 0; + } + + int timeout2 = 4500; + while (timeout2 != 0) { + if (xMCtrl.ComPort.poll()) { + ch = xMCtrl.ComPort.get(); + if(ch != 0x78){ + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 0; + } + x_count ++; + if(x_count == 5) + { + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 1; + } + } + HalDelayUs(200); + timeout2--; + } + + xModem_DeInit_UART_Port(((UpdateImgCfg>>4)&0x03)); + return 0; +} + +FWU_TEXT_SECTION +void OTU_Img_Download(u8 uart_idx, u8 pin_mux, u32 baud_rate, + u32 start_offset, u32 start_addr, u32 max_size) +{ + SPIC_INIT_PARA SpicInitPara; + u32 wr_len; + u8 is_flash=0; + + if (xModem_Init_UART_Port(uart_idx, pin_mux, baud_rate) < 0) { + return; + } + if(xMFrameBuf == NULL) { + DBG_MISC_ERR("OTU: SPI Init Fail!\n"); + return; + } + + DBG_MISC_INFO("Image Download: StartOffset=%d StartAddr=0x%x MaxSize=%d\n", start_offset, start_addr, max_size); + + fw_img2_addr = start_addr; + flash_wr_offset = start_offset; + fw_img2_size = max_size; + + if ((start_addr & 0xFF000000) == SPI_FLASH_BASE) { + // it's going to write the Flash memory + if (((start_addr & 0x03) != 0) || ((start_offset&0x03) != 0)) { + DiagPrintf("StartAddr(0x%x), StartOffset(0x%x) Must 4-bytes Aligned\n", start_addr, start_offset); + return; + } +#if USE_FLASH_API + device_mutex_lock(RT_DEV_LOCK_FLASH); +#endif + SPI_FLASH_PIN_FCTRL(ON); + if (!SpicFlashInitRtl8195A(SpicOneBitMode)){ + DBG_MISC_ERR("OTU: SPI Init Fail!\n"); + SPI_FLASH_PIN_FCTRL(OFF); + goto end_error; + } + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + is_flash = 1; + fw_img2_addr = start_addr & 0x00FFFFFF; + xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_FlashWrite); + } else { + xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_MemWrite); + } + wr_len = xModemRxBuffer(&xMCtrl, ((((max_size+flash_wr_offset-1)>>7)+1) << 7)); + xModemEnd(&xMCtrl); + + xModem_DeInit_UART_Port(uart_idx); + + DBG_MISC_INFO("OTU_Img_Download Done, Write Len=%d\n", wr_len); +end_error: + if (is_flash) { + SPI_FLASH_PIN_FCTRL(OFF); +#if USE_FLASH_API + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif + } + if(xMFrameBuf) { + free(xMFrameBuf); + xMFrameBuf = NULL; + } +} + +#endif //#if CONFIG_PERI_UPDATE_IMG + +#endif // #if CONFIG_UART_SOCKET diff --git a/USDK/component/common/application/xmodem/xmodem.h b/USDK/component/common/application/xmodem/xmodem.h new file mode 100644 index 0000000..8ce40ee --- /dev/null +++ b/USDK/component/common/application/xmodem/xmodem.h @@ -0,0 +1,86 @@ +/* + X-Modem Header File + + 1999/09/03 sprite, support Xmode Tx & Rx +*/ + +#ifndef _XMODE_H_ +#define _XMODE_H_ + +#include + +/***************** + * X-Modem status + *****************/ +#define XMODEM_OK 1 +#define XMODEM_CANCEL 2 +#define XMODEM_ACK 3 +#define XMODEM_NAK 4 +#define XMODEM_COMPLETE 5 +#define XMODEM_NO_SESSION 6 +#define XMODEM_ABORT 7 +#define XMODEM_TIMEOUT 8 + +/**************************** + * flow control character + ****************************/ +#define SOH 0x01 /* Start of header */ +#define STX 0x02 /* Start of header XModem-1K */ +#define EOT 0x04 /* End of transmission */ +#define ACK 0x06 /* Acknowledge */ +#define NAK 0x15 /* Not acknowledge */ +#define CAN 0x18 /* Cancel */ +#define ESC 0x1b /* User Break */ + +/**************************** + * Xmode paramters + ****************************/ +#define FRAME_SIZE 132 /* X-modem structure */ +#define FRAME_SIZE_1K 1028 /* X-modem structure */ +#define XM_BUFFER_SIZE 1024 /* X-modem buffer */ +#define TIMEOUT 180 /* max timeout */ +#define RETRY_COUNT 20 /* Try times */ +#define xWAITTIME 0x00400000 /* waitiing time */ +#define WAIT_FRAME_TIME (10000*100) /* 10 sec, wait frame timeout */ +#define WAIT_CHAR_TIME (1000*100) /* 1 sec, wait char timeout */ + +/*********************** + * frame structure + ***********************/ +typedef struct +{ + unsigned char soh; + unsigned char recordNo; + unsigned char recordNoInverted; + unsigned char buffer[XM_BUFFER_SIZE]; + unsigned char CRC; +} XMODEM_FRAME; + +typedef struct _XMODEM_COM_PORT_ { + char (*poll) (void); + char (*get)(void); + void (*put)(char c); +}XMODEM_COM_PORT, *PXMODEM_COM_PORT; + +typedef struct _XMODEM_CTRL_ { + u16 xMUsing; + u16 currentFrame; /* current frame number */ + u16 previousFrame; /* previous frame number */ + u16 expected; + s16 rStatus; + s32 rFinish; + u32 total_frame; + u32 rx_len; + char *pXFrameBuf; + u32 (*RxFrameHandler)(char *ptr, u32 frame_num, u32 frame_size); + XMODEM_COM_PORT ComPort; +}XMODEM_CTRL, *PXMODEM_CTRL; + +typedef u32 (*RxFrameHandler_t)(char *ptr, u32 frame_num, u32 frame_size); + +extern s16 xModemStart(XMODEM_CTRL *pXMCtrl, char *FrameBuf, RxFrameHandler_t RxFrameHdl); +extern s16 xModemEnd(XMODEM_CTRL *pXMCtrl); +extern s32 xModemRxBuffer(XMODEM_CTRL *pXMCtrl, s32 MaxSize); + +#endif /* _XMODE_H_ */ + diff --git a/USDK/component/common/application/xmodem/xmport_loguart.h b/USDK/component/common/application/xmodem/xmport_loguart.h new file mode 100644 index 0000000..27c3abf --- /dev/null +++ b/USDK/component/common/application/xmodem/xmport_loguart.h @@ -0,0 +1,25 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _XMPORT_LOGUART_H_ +#define _XMPORT_LOGUART_H_ + +#include "xmodem.h" + +//void xmodem_loguart_init(void); +void xmodem_loguart_init(u32 BaudRate); +void xmodem_loguart_func_hook(XMODEM_COM_PORT *pXComPort); +void xmodem_loguart_deinit(void); +char xmodem_loguart_readable(void); +char xmodem_loguart_writable(void); +char xmodem_loguart_getc(void); +void xmodem_loguart_putc(char c); + +#endif // end of "#define _XMPORT_LOGUART_H_" + diff --git a/USDK/component/common/application/xmodem/xmport_uart.h b/USDK/component/common/application/xmodem/xmport_uart.h new file mode 100644 index 0000000..2d8134c --- /dev/null +++ b/USDK/component/common/application/xmodem/xmport_uart.h @@ -0,0 +1,24 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _XMPORT_UART_H_ +#define _XMPORT_UART_H_ + +#include "xmodem.h" + +void xmodem_uart_init(u8 uart_idx, u8 pin_mux, u32 baud_rate); +void xmodem_uart_func_hook(XMODEM_COM_PORT *pXComPort); +void xmodem_uart_deinit(void); +char xmodem_uart_readable(void); +char xmodem_uart_writable(void); +char xmodem_uart_getc(void); +void xmodem_uart_putc(char c); + +#endif // end of "#define _XMPORT_UART_H_" + diff --git a/USDK/component/common/audio/g711_codec.h b/USDK/component/common/audio/g711_codec.h new file mode 100644 index 0000000..d074b74 --- /dev/null +++ b/USDK/component/common/audio/g711_codec.h @@ -0,0 +1,24 @@ +#ifndef _G711_CODEC_H +#define _G711_CODEC_H +#include "basic_types.h" + +typedef enum { + I2S_MODE_UNKNOWN = -1, + I2S_MODE_G711A = 1, + I2S_MODE_G711U = 2 +}I2S_mode; + +typedef struct { + I2S_mode mode; //intend to encode as G711A or G711U + int len; //data length +// _sema RWSema; + unsigned char *raw_data; //address of buffered data (not encoded + int data_start; // a shift value to show where the data starts + int data_end; // a shift value shows data ending +}i2s_buf_context; + +//void encoder_init(int mode); +int G711_encoder(short *source, unsigned char *des, int mode, int size); +int G711_decoder(unsigned char *source, short *des, int mode, int size); +int mono2stereo(unsigned char *src, unsigned char *dst, int size, int wl); +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/ethernet_mii/ethernet_mii.c b/USDK/component/common/drivers/ethernet_mii/ethernet_mii.c new file mode 100644 index 0000000..a65ccdc --- /dev/null +++ b/USDK/component/common/drivers/ethernet_mii/ethernet_mii.c @@ -0,0 +1,251 @@ +#include "rtl8195a.h" +#include "build_info.h" +#ifdef PLATFORM_FREERTOS +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#endif +#include "osdep_service.h" +#include "lwip_netconf.h" +#include "ethernet_api.h" +#include "lwip_intf.h" +#include "ethernet_mii.h" +#include "platform_opts.h" +#include "ethernet_ex_api.h" + +#if defined(CONFIG_MII_EN) + +static _sema mii_rx_sema; +static _mutex mii_tx_mutex; + +extern struct netif xnetif[NET_IF_NUM]; + +static u8 TX_BUFFER[1518]; +static u8 RX_BUFFER[1518]; + +static u8 *pTmpTxDesc = NULL; +static u8 *pTmpRxDesc = NULL; +static u8 *pTmpTxPktBuf = NULL; +static u8 *pTmpRxPktBuf = NULL; + + +int dhcp_ethernet_mii = 1; +int ethernet_if_default = 0; + +extern int lwip_init_done; + +static _sema mii_linkup_sema; + +void mii_rx_thread(void* param){ + u32 len = 0; + u8* pbuf = RX_BUFFER; + while(1){ + if (rtw_down_sema(&mii_rx_sema) == _FAIL){ + DBG_8195A("%s, Take Semaphore Fail\n", __FUNCTION__); + goto exit; + } + // continues read the rx ring until its empty + while(1){ + len = ethernet_receive(); + if(len){ + //DBG_8195A("mii_recv len = %d\n\r", len); + ethernet_read(pbuf, len); +// calculate the time duration + ethernetif_mii_recv(&xnetif[NET_IF_NUM - 1], len); + //__rtl_memDump_v1_00(pbuf, len, "ethernet_receive Data:"); + //rtw_memset(pbuf, 0, len); + }else if(len == 0){ + break; + } + } + } +exit: + rtw_free_sema(&mii_rx_sema); + vTaskDelete(NULL); +} + +void dhcp_start_mii(void* param) +{ + while(1) + { + if (rtw_down_sema(&mii_linkup_sema) == _FAIL){ + DBG_8195A("%s, Take Semaphore Fail\n", __FUNCTION__); + break; + } + LwIP_DHCP(NET_IF_NUM - 1, DHCP_START); + } + rtw_free_sema(&mii_linkup_sema); + vTaskDelete(NULL); +} + + +void mii_intr_handler(u32 Event, u32 Data) +{ + switch(Event) + { + case ETH_TXDONE: + //DBG_8195A("TX Data = %d\n", Data); + break; + case ETH_RXDONE: + //DBG_8195A("\r\nRX Data = %d\n", Data); + // wake up rx thread to receive data + rtw_up_sema_from_isr(&mii_rx_sema); + break; + case ETH_LINKUP: + DBG_8195A("Link Up\n"); + + if(dhcp_ethernet_mii == 1) + rtw_up_sema_from_isr(&mii_linkup_sema); + + break; + case ETH_LINKDOWN: + DBG_8195A("Link Down\n"); + + break; + default: + DBG_8195A("Unknown event!\n"); + break; + } +} + +void ethernet_demo(void* param){ + u8 mac[6]; + /* Initilaize the LwIP stack */ + // can not init twice + if(!lwip_init_done) + LwIP_Init(); + DBG_8195A("LWIP Init done\n"); + + ethernet_irq_hook(mii_intr_handler); + + if(pTmpTxDesc) + { + free(pTmpTxDesc); + pTmpTxDesc = NULL; + } + if(pTmpRxDesc) + { + free(pTmpRxDesc); + pTmpRxDesc = NULL; + } + if(pTmpTxPktBuf) + { + free(pTmpTxPktBuf); + pTmpTxPktBuf = NULL; + } + if(pTmpRxPktBuf) + { + free(pTmpRxPktBuf); + pTmpRxPktBuf = NULL; + } + + pTmpTxDesc = (u8 *)malloc(/*MII_TX_DESC_CNT*/MII_TX_DESC_NO * ETH_TX_DESC_SIZE); + pTmpRxDesc = (u8 *)malloc(/*MII_RX_DESC_CNT*/MII_RX_DESC_NO * ETH_RX_DESC_SIZE); + pTmpTxPktBuf = (u8 *)malloc(/*MII_TX_DESC_CNT*/MII_TX_DESC_NO * ETH_PKT_BUF_SIZE); + pTmpRxPktBuf = (u8 *)malloc(/*MII_RX_DESC_CNT*/MII_RX_DESC_NO * ETH_PKT_BUF_SIZE); + if(pTmpTxDesc == NULL || pTmpRxDesc == NULL || pTmpTxPktBuf == NULL || pTmpRxPktBuf == NULL) + { + printf("TX/RX descriptor malloc fail\n"); + return; + } + memset(pTmpTxDesc, 0, MII_TX_DESC_NO * ETH_TX_DESC_SIZE); + memset(pTmpRxDesc, 0, MII_RX_DESC_NO * ETH_RX_DESC_SIZE); + memset(pTmpTxPktBuf, 0, MII_TX_DESC_NO * ETH_PKT_BUF_SIZE); + memset(pTmpRxPktBuf, 0, MII_RX_DESC_NO * ETH_PKT_BUF_SIZE); + //size 160 128 12288 12288 + + ethernet_set_descnum(MII_TX_DESC_NO, MII_RX_DESC_NO); + printf("TRX descriptor number setting done\n"); + ethernet_trx_pre_setting(pTmpTxDesc, pTmpRxDesc, pTmpTxPktBuf, pTmpRxPktBuf); + printf("TRX pre setting done\n"); + + ethernet_init(); +#if 0 + DBG_INFO_MSG_OFF(_DBG_MII_); + DBG_WARN_MSG_OFF(_DBG_MII_); + DBG_ERR_MSG_ON(_DBG_MII_); +#endif + /*get mac*/ + ethernet_address(mac); + memcpy((void*)xnetif[NET_IF_NUM - 1].hwaddr,(void*)mac, 6); + + rtw_init_sema(&mii_rx_sema,0); + rtw_mutex_init(&mii_tx_mutex); + + if(xTaskCreate(mii_rx_thread, ((const char*)"mii_rx_th"), 1024, NULL, tskIDLE_PRIORITY+5, NULL) != pdPASS) + DBG_8195A("\n\r%s xTaskCreate(mii_rx_thread) failed", __FUNCTION__); + + DBG_8195A("\nEthernet_mii Init done, interface %d",NET_IF_NUM - 1); + + if(dhcp_ethernet_mii == 1) + LwIP_DHCP(NET_IF_NUM - 1, DHCP_START); + + vTaskDelete(NULL); +} + +void ethernet_mii_init() +{ + printf("\ninitializing Ethernet_mii......\n"); + + // set the ethernet interface as default + ethernet_if_default = 1; + rtw_init_sema(&mii_linkup_sema,0); + + if( xTaskCreate((TaskFunction_t)dhcp_start_mii, "DHCP_MII", 1024, NULL, 2, NULL) != pdPASS) { + DBG_8195A("Cannot create demo task\n\r"); + } + + if( xTaskCreate((TaskFunction_t)ethernet_demo, "ETH_DEMO", 1024, NULL, 2, NULL) != pdPASS) { + DBG_8195A("Cannot create demo task\n\r"); + } + +} + + +void rltk_mii_recv(struct eth_drv_sg *sg_list, int sg_len){ + struct eth_drv_sg *last_sg; + u8* pbuf = RX_BUFFER; + + for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { + if (sg_list->buf != 0) { + rtw_memcpy((void *)(sg_list->buf), pbuf, sg_list->len); + pbuf+=sg_list->len; + } + } +} + + +s8 rltk_mii_send(struct eth_drv_sg *sg_list, int sg_len, int total_len){ + int ret =0; + struct eth_drv_sg *last_sg; + u8* pdata = TX_BUFFER; + u8 retry_cnt = 0; + u32 size = 0; + for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { + rtw_memcpy(pdata, (void *)(sg_list->buf), sg_list->len); + pdata += sg_list->len; + size += sg_list->len; + } + pdata = TX_BUFFER; + //DBG_8195A("mii_send len= %d\n\r", size); + rtw_mutex_get(&mii_tx_mutex); + while(1){ + ret = ethernet_write(pdata, size); + if(ret > 0){ + ethernet_send(); + ret = 0; + break; + } + if(++retry_cnt > 3){ + DBG_8195A("TX drop\n\r"); + ret = -1; + } + else + rtw_udelay_os(1); + } + rtw_mutex_put(&mii_tx_mutex); + + return ret; +} + +#endif //CONFIG_MII_EN diff --git a/USDK/component/common/drivers/ethernet_mii/ethernet_mii.h b/USDK/component/common/drivers/ethernet_mii/ethernet_mii.h new file mode 100644 index 0000000..4edec6f --- /dev/null +++ b/USDK/component/common/drivers/ethernet_mii/ethernet_mii.h @@ -0,0 +1,12 @@ +#ifndef __MII_ETHERNETIF_H__ +#define __MII_ETHERNETIF_H__ + +#include "lwip_netconf.h" + +#define MII_TX_DESC_CNT 4 +#define MII_RX_DESC_CNT 10 +#if CONFIG_ETHERNET +extern s8 rltk_mii_send(struct eth_drv_sg *sg_list, int sg_len, int total_len); +extern void rltk_mii_recv(struct eth_drv_sg *sg_list, int sg_len); +#endif +#endif // __MII_ETHERNETIF_H__ diff --git a/USDK/component/common/drivers/i2s/alc5651.c b/USDK/component/common/drivers/i2s/alc5651.c new file mode 100644 index 0000000..f3365b4 --- /dev/null +++ b/USDK/component/common/drivers/i2s/alc5651.c @@ -0,0 +1,196 @@ +#include +#include "PinNames.h" +#include "basic_types.h" +#include "diag.h" +#include + +#include "i2c_api.h" +#include "pinmap.h" + +//#define I2C_MTR_SDA PC_4//PB_3 +//#define I2C_MTR_SCL PC_5//PB_2 +#define I2C_MTR_SDA PB_3 +#define I2C_MTR_SCL PB_2 +#define I2C_BUS_CLK 100000 //hz + +#define I2C_ALC5651_ADDR (0x34/2) + +#define RT5651_PRIV_INDEX 0x6a +#define RT5651_PRIV_DATA 0x6c + +#if defined (__ICCARM__) +i2c_t alc5651_i2c; +#else +volatile i2c_t alc5651_i2c; +#define printf DBG_8195A +#endif + +static void alc5651_delay(void) +{ + int i; + + i=10000; + while (i) { + i--; + asm volatile ("nop\n\t"); + } +} + +void alc5651_reg_write(unsigned int reg, unsigned int value) +{ + char buf[4]; + buf[0] = (char)reg; + buf[1] = (char)(value>>8); + buf[2] = (char)(value&0xff); + + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1); + alc5651_delay(); +} + +void alc5651_reg_read(unsigned int reg, unsigned int *value) +{ + int tmp; + char *buf = (char*)&tmp; + + buf[0] = (char)reg; + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1); + alc5651_delay(); + + buf[0] = 0xaa; + buf[1] = 0xaa; + + i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1); + alc5651_delay(); + + *value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF); +} + +void alc5651_index_write(unsigned int reg, unsigned int value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_write(RT5651_PRIV_DATA, value); +} + +void alc5651_index_read(unsigned int reg, unsigned int *value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_read(RT5651_PRIV_DATA, value); +} + +void alc5651_reg_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec reg dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_reg_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_index_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec index dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_index_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_init(void) +{ + i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL); + i2c_frequency(&alc5651_i2c, I2C_BUS_CLK); +} + +void alc5651_set_word_len(int len_idx) // interface2 +{ + // 0: 16 1: 20 2: 24 3: 8 + unsigned int val; + alc5651_reg_read(0x71,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x71,val); + alc5651_reg_read(0x70,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x70,val); + +} + +void alc5651_init_interface1(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x27,0x3820); + alc5651_reg_write(0x77,0x0000); +} + +void alc5651_init_interface2(void) +{ + int reg_value=0; + alc5651_reg_write(0x00,0x0021);//reset all, device id 1 + alc5651_reg_write(0x63,0xE8FE);//Power managerment control 3: + //VREF1&2 on, both slow VREF, MBIAS on, MBIAS bandcap power on, L & R HP Amp on, improve HP Amp driving enabled + alc5651_reg_write(0x61,0x5800);//power managerment control 1: + //I2S2 digital interface on, Analog DACL1 & DACR1 on. + alc5651_reg_write(0x62,0x0C00);//stereo1 & 2 DAC filter power on + alc5651_reg_write(0x73,0x0000);//ADC/DAC Clock control 1: + //I2S Clock Pre-Divider 1 & 2: /1. Stereo DAC Over Sample Rate : 128Fs + alc5651_reg_write(0x2A,0x4242);//Stereo DAC digital mixer control + //Un-mute DACL2 to Stereo DAC Left & Right Mixer + alc5651_reg_write(0x45,0x2000);//HPOMIX: Un-mute DAC1 to HPOMIX + alc5651_reg_write(0x02,0x4848);//HP Output Control: + //Unmute HPOL, HPOR +// alc5651_reg_write(0x0F,0x1F1F);//INL & INR Volume Control +// alc5651_reg_write(0x0D,0x0800);//IN1/2 Input Control +// alc5651_reg_write(0x1C,0x7F7F);//Stereo1 ADC Digital Volume Control +// alc5651_reg_write(0x1E,0xF000);// ADC Digital Boost Gain Control + alc5651_reg_write(0x8E,0x0019);//HP Amp Control 1 +// Enable HP Output, Charge Pump Power On, HP Amp All Power On + alc5651_reg_write(0x8F,0x3100);//HP Amp Control 2, HP Depop Mode 2 + alc5651_reg_write(0x91,0x0E00);//HP Amp Control 3, select HP capless power mode + alc5651_index_write(0x3D,0x3E00);//unknown + alc5651_reg_write(0xFA,0x0011);//enable input clock + alc5651_reg_write(0x83,0x0800);//default ASRC control 1 + alc5651_reg_write(0x84,0xA000);//ASRC control 2: I2S1 enable ASRC mode, Sterol1 DAC filter ASRC mode. +// alc5651_reg_write(0xFA,0x0C11);//? ? ? MX-FAh[15:4]reserved + alc5651_reg_write(0x64,0x4010);//power managerment control 4: + //MIC BST2 Power On; MIC2 SE Mode single-end mode or line-input mode + alc5651_reg_write(0x65,0x0C00);//power managerment control 5: RECMIX L & R power on + alc5651_reg_write(0x61,0x5806);//power managerment control 1: +// I2S2 Digital Interface On, Analog DACL1, DACR1 power on; Analog ADCL, ADCR power on + alc5651_reg_write(0x62,0xCC00);//power managerment control 2: Stereo1&2 ADC/DAC digital filter power on + alc5651_reg_write(0x3C,0x004F);//RECMIXL + alc5651_reg_write(0x3E,0x004F);//RECMIXR + alc5651_reg_write(0x28,0x3030);//stereo2 ADC digital mixer control : Mute Stereo2 ADC L&R channel, ADCR + alc5651_reg_write(0x2F,0x0080); //Interface DAC/ADC Data control: Select IF2 ADCDAT Data Source IF1_ADC2 +} \ No newline at end of file diff --git a/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sd.h b/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sd.h new file mode 100644 index 0000000..b23bdf9 --- /dev/null +++ b/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sd.h @@ -0,0 +1,39 @@ +#ifndef _SD_DRIVER_H +#define _SD_DRIVER_H + +#include "basic_types.h" + +#define CONFIG_SD_SDIO 1 +#define CONFIG_SD_SPI 0 + +typedef enum +{ + SD_OK = 0, + SD_PROTECTED, + SD_NODISK, + SD_INITERR, + SD_ERROR, +}SD_RESULT; + +typedef enum{ + SD_CLK_LOW, // 10.4MHz + SD_CLK_MID, // 20.8MHz + SD_CLK_HIGH, // 41.6MHz + SD_CLK_RSV, // 5.2MHz +}SD_CLK; + +SD_RESULT SD_WaitReady(void); +SD_RESULT SD_Init(void); +SD_RESULT SD_DeInit(void); +SD_RESULT SD_SetCLK(SD_CLK CLK); + +SD_RESULT SD_Status(void); + +SD_RESULT SD_GetCID(u8 *cid_data); // read sd card CID +SD_RESULT SD_GetCSD(u8 *csd_data); // read sd card CSD +SD_RESULT SD_GetCapacity(u32* sector_count); // read sd card Capacity + +SD_RESULT SD_ReadBlocks(u32 sector,u8 *data,u32 count); //read multi sector +SD_RESULT SD_WriteBlocks(u32 sector,const u8 *data,u32 count); //write multi sector + +#endif diff --git a/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sdio_host.h b/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sdio_host.h new file mode 100644 index 0000000..ff174d0 --- /dev/null +++ b/USDK/component/common/drivers/sdio/realtek/sdio_host/inc/sdio_host.h @@ -0,0 +1,43 @@ +#ifndef _SDIO_HOST_H +#define _SDIO_HOST_H +#include "basic_types.h" +#include "rtl8195a_sdio_host.h" + +#define SDIO_HOST_BYTES_ALINGMENT 4 + +typedef enum{ + SDIO_INIT_NONE = -1, + SDIO_INIT_FAIL = 0, + SDIO_INIT_OK = 1, + SDIO_SD_NONE = 2, + SDIO_SD_OK = 3, +}_sdio_init_s; + +extern _sdio_init_s sdio_status; + +typedef void (*sdio_sd_irq_handler)(void* param); + + +s8 sdio_init_host(void); // init sdio host interface +void sdio_deinit_host(void); + +s8 sdio_sd_init(void); // init sd card through sdio +void sdio_sd_deinit(void); //de-init sd card through sdio +s8 sdio_sd_status(void); +u32 sdio_sd_getCapacity(void); +s8 sdio_sd_getProtection(void); +s8 sdio_sd_setProtection(bool protection); +s8 sdio_sd_getCSD(u8* CSD); +s8 sdio_sd_isReady(); +s8 sdio_sd_setClock(SD_CLK_FREQUENCY SDCLK); + + +s8 sdio_read_blocks(u32 sector, u8 *buffer, u32 count); +s8 sdio_write_blocks(u32 sector, const u8 *buffer, u32 count); + +s8 sdio_sd_hook_xfer_cmp_cb(IN sdio_sd_irq_handler CallbackFun,IN VOID *param); +s8 sdio_sd_hook_remove_cb(IN sdio_sd_irq_handler CallbackFun,IN VOID *param); +s8 sdio_sd_hook_insert_cb(IN sdio_sd_irq_handler CallbackFun,IN VOID *param); +s8 sdio_sd_hook_xfer_err_cb(IN sdio_sd_irq_handler CallbackFun,IN VOID *param); + +#endif diff --git a/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sd.c b/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sd.c new file mode 100644 index 0000000..dd81f93 --- /dev/null +++ b/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sd.c @@ -0,0 +1,176 @@ +/* + * sd.c (disasm ds.o) + * + * RTL8710/11 pvvx 12/2016 + */ + +#include "rtl8195a.h" +#ifdef CONFIG_SDIO_HOST_EN +#include "sd.h" +#include "sdio_host.h" + +#define SIZE_BLOCK_ADMA 512 + +SemaphoreHandle_t sdWSema; + +void sd_xfer_done_callback(void *obj) { + RtlUpSema(&sdWSema); +} + +void sd_xfer_err_callback(void *obj) { + DBG_SDIO_ERR("sd_xfer_err_callback \r\n"); +} + +//----- SD_WaitReady +SD_RESULT SD_WaitReady() { + return SD_OK; +} + +//----- SD_Init +SD_RESULT SD_Init() { + SD_RESULT result; + + if (sdio_sd_init() != 0) + result = SD_INITERR; + else { + if (sdio_sd_getProtection() != 0) + result = SD_PROTECTED; + RtlInitSema(&sdWSema, 0); + sdio_sd_hook_xfer_cmp_cb(sd_xfer_done_callback, 0); + sdio_sd_hook_xfer_err_cb(sd_xfer_err_callback, 0); + } + return result; +} + +//----- SD_DeInit +SD_RESULT SD_DeInit() { + sdio_sd_deinit(); + RtlFreeSema(&sdWSema); + return SD_OK; +} + +//----- SD_SetCLK +SD_RESULT SD_SetCLK(SD_CLK CLK) { + SD_RESULT result; + switch (CLK) { + case SD_CLK_HIGH: + result = sdio_sd_setClock(SD_CLK_41_6MHZ); + break; + case SD_CLK_MID: + result = sdio_sd_setClock(SD_CLK_20_8MHZ); + break; + case SD_CLK_LOW: + result = sdio_sd_setClock(SD_CLK_10_4MHZ); + break; + case SD_CLK_RSV: + result = sdio_sd_setClock(SD_CLK_5_2MHZ); + break; + default: +// DBG_SDIO_INFO("clk = %d ?\n", CLK); + return SD_ERROR; + } + if (result) + return SD_ERROR; + return SD_OK; +} + +//----- SD_Status +SD_RESULT SD_Status() { + if (sdio_sd_isReady()) + return SD_NODISK; + else + return sdio_sd_getProtection() != 0; +} + +//----- SD_GetCID +SD_RESULT SD_GetCID(u8 *cid_data) { + return SD_OK; +} + +//----- SD_GetCSD +SD_RESULT SD_GetCSD(u8 *csd_data) { + if (sdio_sd_getCSD(csd_data)) + return SD_ERROR; + else + return SD_OK; +} + +//----- SD_GetCapacity +SD_RESULT SD_GetCapacity(uint32_t *sector_count) { + + u32 sc = sdio_sd_getCapacity(); + *sector_count = sc; + if (sc != 0) + return SD_OK; + else + return SD_ERROR; +} + +//----- SD_ReadBlocks +SD_RESULT SD_ReadBlocks(u32 sector, u8 *data, u32 count) { + int rd_count; + unsigned char * buf; + + if ((u32) data & 3) { + buf = pvPortMalloc(SIZE_BLOCK_ADMA); + if (buf == NULL) + DBG_SDIO_ERR("Fail to malloc cache for SDIO host!\n"); + u32 end_sector = count + sector; + while (sector < end_sector) { + rd_count = sdio_read_blocks(sector, buf, 1); +// rtl_printf("rd_counts = %d\n", rd_count); + if (rd_count == 0 && RtlDownSemaWithTimeout(&sdWSema, 1000) != 1) { + DBG_SDIO_ERR("SD_ReadBlocks timeout\n"); + return SD_ERROR; + } + rtl_memcpy(data, buf, SIZE_BLOCK_ADMA); + sector++; + data += SIZE_BLOCK_ADMA; + } + vPortFree(buf); + if (rd_count) + return SD_ERROR; + return SD_OK; + } else { + if (sdio_read_blocks(sector, data, count) == 0) { + if (RtlDownSemaWithTimeout(&sdWSema, 1000) == 1) + return SD_OK; + DBG_SDIO_ERR("SD_ReadBlocks timeout\n"); + } + } + + return SD_ERROR; +} + +//----- SD_WriteBlocks +SD_RESULT SD_WriteBlocks(u32 sector, const u8 *data, u32 count) { + int wr_count; + unsigned char * buf; + + if ((u32) data & 3) { + buf = pvPortMalloc(SIZE_BLOCK_ADMA); + if (buf == NULL) + DBG_SDIO_ERR("Fail to malloc cache for SDIO host!\n"); + u32 end_sector = count + sector; + while (sector != end_sector) { + rtl_memcpy(buf, data, SIZE_BLOCK_ADMA); + wr_count = sdio_write_blocks(sector, buf, 1); + if (wr_count == 0 && RtlDownSemaWithTimeout(&sdWSema, 1000) != 1) { + DBG_SDIO_ERR("SD_WriteBlocks timeout\n"); + return SD_ERROR; + } + sector++; + data += SIZE_BLOCK_ADMA; + } + vPortFree(buf); + if (wr_count == 0) + return SD_OK; + } else if (sdio_write_blocks(sector, data, count) == 0) { + if (RtlDownSemaWithTimeout(&sdWSema, 1000) == 1) + return SD_OK; + DBG_SDIO_ERR("SD_WriteBlocks timeout\n"); + } + return SD_ERROR; + +} +#endif // CONFIG_SDIO_HOST_EN diff --git a/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sdio_host.c b/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sdio_host.c new file mode 100644 index 0000000..1d4c8a9 --- /dev/null +++ b/USDK/component/common/drivers/sdio/realtek/sdio_host/src/sdio_host.c @@ -0,0 +1,408 @@ +/* + * sdio_host.c (disasm sdio_host.o) + * + * RTL8710/11 pvvx 12/2016 + */ + +#include "rtl8195a.h" +#ifdef CONFIG_SDIO_HOST_EN +#include "sd.h" +#include "sdio_host.h" +#include "hal_sdio_host.h" +#include "rtl8195a_sdio_host.h" +//#include "hal_sdio.h" +//#include "PinNames.h" +//#include "pinmap.h" + +#define MAX_BUF_ADMA 64 +#define SIZE_BLOCK_ADMA 512 +//------------------------------------------------------------------------- +// Function declarations +//------------------------------------------------------------------------- +// Data declarations +sdio_sd_irq_handler xfer_done_irq_handler; +uint32_t xfer_err_irq_data; +uint32_t xfer_done_irq_data; +sdio_sd_irq_handler xfer_err_irq_handler; +_sdio_init_s sdio_status = SDIO_INIT_NONE; +sdio_sd_irq_handler card_remove_irq_handler; +uint32_t card_remove_irq_data; +sdio_sd_irq_handler card_insert_irq_handler; +uint32_t card_insert_irq_data; +HAL_SDIO_HOST_OP HalSdioHostOp; +s8 sd_protected = -1; +HAL_SDIO_HOST_ADAPTER SdioHostAdapter; +SRAM_BF_DATA_SECTION ADMA2_DESC_FMT gAdmaTbls[MAX_BUF_ADMA]; +//------------------------------------------------------------------------- + +void xfer_done_callback(void *param) { + if (xfer_done_irq_handler) + xfer_done_irq_handler((void *) xfer_done_irq_data); +} + +void xfer_err_callback(void *param) { + if (xfer_err_irq_handler) + xfer_err_irq_handler((void *) xfer_err_irq_data); +} + +void card_insert_callback(void *param) { +#if CONFIG_DEBUG_LOG > 1 + rtl_printf("SD card insert\n"); +#endif + if (card_insert_irq_handler) + card_insert_irq_handler((void *) card_insert_irq_data); +} + +void card_remove_callback(void *param) { +#if CONFIG_DEBUG_LOG > 1 + rtl_printf("SD card removed\n"); +#endif + sdio_status = SDIO_SD_NONE; + if (card_remove_irq_handler) + card_remove_irq_handler((void *) card_remove_irq_data); +} + +//----- sdio_init_host +s8 sdio_init_host() { + s8 result; + HAL_Status stat; + + DBG_SDIO_INFO("SDIO Init Host Begin...\n"); + if (sdio_status > SDIO_INIT_FAIL) { + DBG_SDIO_INFO("SDIO Host init already.\n"); + result = 0; + } else { + rtl_memset(&SdioHostAdapter, 0, sizeof(SdioHostAdapter)); + HalSdioHostOpInit(&HalSdioHostOp); + stat = HalSdioHostOp.HalSdioHostInitHost(&SdioHostAdapter); + SdioHostAdapter.CardInsertCbPara = &SdioHostAdapter; + SdioHostAdapter.CardInsertCallBack = + (void (*)(void *)) card_insert_callback; + SdioHostAdapter.CardRemoveCbPara = &SdioHostAdapter; + SdioHostAdapter.CardRemoveCallBack = + (void (*)(void *)) card_remove_callback; + SdioHostAdapter.XferCompCbPara = &SdioHostAdapter; + SdioHostAdapter.XferCompCallback = + (void (*)(void *)) xfer_done_callback; + SdioHostAdapter.ErrorCbPara = &SdioHostAdapter; + SdioHostAdapter.ErrorCallback = (void (*)(void *)) xfer_err_callback; + if (stat == HAL_OK) { + sdio_status = SDIO_INIT_OK; + DBG_SDIO_INFO("SDIO Host init Success.\n"); + result = 0; + } else { + sdio_status = SDIO_INIT_FAIL; + DBG_SDIO_ERR("SDIO Host init Fail.\n"); + result = -1; + } + } + return result; +} + +//----- +void sdio_deinit_host(void) { + if (sdio_status > 0) { + HAL_Status hs = HalSdioHostOp.HalSdioHostDeInit(&SdioHostAdapter); + if (hs == HAL_OK) { + SdioHostAdapter.CardInsertCallBack = NULL; + SdioHostAdapter.CardRemoveCallBack = NULL; + sdio_status = SDIO_INIT_NONE; + } + } +} + +//----- +s8 sdio_read_blocks(u32 sector, u8 *buffer, u32 count) { + + if (!count) { + DBG_SDIO_ERR("Parameter error, try to read %d count\n"); + return -1; + } + if (sdio_status <= SDIO_SD_NONE) { + DBG_SDIO_ERR("SD card is not ready\n"); + return -1; + } + if (count > MAX_BUF_ADMA) { + count = MAX_BUF_ADMA; + DBG_SDIO_ERR("Not enough ADMA table(maximum %d), reduce blocks count\n", + count); + } + rtl_memset(gAdmaTbls, 0, sizeof(ADMA2_DESC_FMT) * count); + if (1) { + ADMA2_DESC_FMT *p = gAdmaTbls; + u8 * pbuf = buffer; + int i = 0; + while (i < count) { + i++; + p->Addr1 = (u32) pbuf; + p->Len1 = SIZE_BLOCK_ADMA; + if (i == count) { + p->Attrib1.Valid = 1; // 0x23 + p->Attrib1.End = 1; + p->Attrib1.Act2 = 1; + } else { + p->Attrib1.Valid = 1; // 0x21 + p->Attrib1.Act2 = 1; + p->Attrib2.Valid = 1; // 0x31 + p->Attrib2.Act1 = 1; + p->Attrib2.Act2 = 1; + p->Len2 = 0; + p->Addr2 = (u32) (&p[1]); + } + pbuf += SIZE_BLOCK_ADMA; + p++; + } + SdioHostAdapter.AdmaDescTbl = gAdmaTbls; + } + HAL_Status result = HalSdioHostOp.HalSdioHostReadBlocksDma(&SdioHostAdapter, + (unsigned long long) sector * SIZE_BLOCK_ADMA, count); + if (result) { + DBG_SDIO_ERR("sdio_read_blocks fail(0x%02x)\n", result); + return -1; + } + return 0; +} + +//----- +s8 sdio_write_blocks(uint32_t sector, const uint8_t *buffer, uint32_t count) { + + if (!count) { + DBG_SDIO_ERR("Parameter error, try to read %d count\n"); + return -1; + } + if (sdio_status <= SDIO_SD_NONE) { + DBG_SDIO_ERR("SD card is not ready\n"); + return -1; + } + if (count > MAX_BUF_ADMA) { + count = MAX_BUF_ADMA; + DBG_SDIO_ERR("Not enough ADMA table(maximum %d), reduce blocks count\n", + count); + } + if (sd_protected) { + DBG_SDIO_ERR("SD card is write protected\n"); + return -1; + } + rtl_memset(gAdmaTbls, 0, sizeof(ADMA2_DESC_FMT) * count); + if (1) { + ADMA2_DESC_FMT *p = gAdmaTbls; + u8 * pbuf = buffer; + int i = 0; + while (i < count) { + i++; + p->Addr1 = (u32) pbuf; + p->Len1 = SIZE_BLOCK_ADMA; + if (i == count) { + p->Attrib1.Valid = 1; // 0x23 + p->Attrib1.End = 1; + p->Attrib1.Act2 = 1; + } else { + p->Attrib1.Valid = 1; // 0x21 + p->Attrib1.Act2 = 1; + p->Attrib2.Valid = 1; // 0x31 + p->Attrib2.Act1 = 1; + p->Attrib2.Act2 = 1; + p->Len2 = 0; + p->Addr2 = (u32) (&p[1]); + } + pbuf += SIZE_BLOCK_ADMA; + p++; + } + SdioHostAdapter.AdmaDescTbl = gAdmaTbls; + } + HAL_Status result = HalSdioHostOp.HalSdioHostWriteBlocksDma( + &SdioHostAdapter, (unsigned long long) sector * SIZE_BLOCK_ADMA, + count); + if (result != HAL_OK) { + DBG_SDIO_ERR("write fail(0x%02x)\n", result); + return -1; + } + return 0; +} + +//----- +s8 sdio_sd_init(void) { + if (sdio_status != SDIO_SD_OK) { + SdioHostAdapter.AdmaDescTbl = gAdmaTbls; + if (sdio_status <= SDIO_INIT_FAIL) + sdio_init_host(); + if (sdio_status != SDIO_INIT_OK) { + return -1; + } + DBG_SDIO_INFO("Init sd card.\n"); + if (HalSdioHostOp.HalSdioHostInitCard(&SdioHostAdapter)) { + return -1; + } + sdio_status = SDIO_SD_OK; + if (HalSdioHostOp.HalSdioHostChangeSdClock(&SdioHostAdapter, + SD_CLK_41_6MHZ) != HAL_OK) + DBG_SDIO_INFO("SD card does not support high speed.\n"); + } + return 0; +} + +//----- +void sdio_sd_deinit() { + if (sdio_status > SDIO_SD_NONE) + sdio_status = SDIO_INIT_OK; + sdio_deinit_host(); // add pvvx (fix SD_DeInit()) +} + +//----- +s8 sdio_sd_setClock(SD_CLK_FREQUENCY SDCLK) { + HAL_Status sta; + if (sdio_status <= SDIO_SD_NONE) { + return -1; + } + ADMA2_DESC_FMT * padma = rtw_zmalloc(sizeof(ADMA2_DESC_FMT)); + if (!padma) { + DBG_SDIO_ERR("Malloc ADMA2 table fail.\n"); + return -1; + } + DBG_SDIO_INFO("SD card set CLK %d Hz\n", PLATFORM_CLOCK/(4<<(8-SDCLK))); + sta = HalSdioHostOp.HalSdioHostChangeSdClock(&SdioHostAdapter, SDCLK); + rtw_mfree(padma, sizeof(ADMA2_DESC_FMT)); + if (sta) + return -1; + return 0; +} + +//----- +s8 sdio_sd_setProtection(bool protection) { + s8 result; + ADMA2_DESC_FMT *padma; + HAL_Status hls; + if (sdio_status > SDIO_SD_NONE) { + padma = (ADMA2_DESC_FMT *) rtw_zmalloc(sizeof(ADMA2_DESC_FMT)); + if (!padma) { + DBG_SDIO_ERR("Malloc ADMA2 table fail.\n"); + return -1; + } + SdioHostAdapter.AdmaDescTbl = padma; + if (protection) { + if (sd_protected == 1) + goto LABEL_8; + hls = HalSdioHostOp.HalSdioHostSetWriteProtect(&SdioHostAdapter, 1); + } else { + if (sd_protected == 0) + goto LABEL_8; + hls = HalSdioHostOp.HalSdioHostSetWriteProtect(&SdioHostAdapter, 0); + } + if (hls) { + DBG_SDIO_ERR("Set SD card Protection fail.\n"); + result = -1; + goto LABEL_17; + } +LABEL_8: + sd_protected = protection; +LABEL_7: + DBG_SDIO_INFO("Set SD card Protection done.\n"); + result = 0; +LABEL_17: + rtw_mfree(padma, sizeof(ADMA2_DESC_FMT)); + return result; + } + return -1; +} + +//----- sdio_sd_getProtection +s8 sdio_sd_getProtection() { + s8 result; + + result = sd_protected; + if (sd_protected != -1) + return result; + if (sdio_status <= SDIO_SD_NONE) { + result = -1; + return result; + } + if (HalSdioHostOp.HalSdioHostGetWriteProtect(&SdioHostAdapter)) { + DBG_SDIO_ERR("Get SD card Protection fail.\n"); + result = -1; + return result; + } + if (SdioHostAdapter.IsWriteProtect) + DBG_SDIO_INFO("SD card is Write Protected.\n"); + result = (s8) SdioHostAdapter.IsWriteProtect; + sd_protected = SdioHostAdapter.IsWriteProtect; + return result; +} + +//----- sdio_sd_status +s8 sdio_sd_status() { + s8 result; + + DBG_SDIO_INFO("sdio_get_sdcard_status.\n"); + if (sdio_status <= SDIO_SD_NONE + || HalSdioHostOp.HalSdioHostGetCardStatus(&SdioHostAdapter)) + result = -1; + else + result = SdioHostAdapter.CardCurState; + return result; +} + +//----- sdio_sd_getCSD +s8 sdio_sd_getCSD(u8* CSD) { + s8 result; + + if (sdio_status <= SDIO_SD_NONE) + result = -1; + else { + rtl_memcpy(CSD, SdioHostAdapter.Csd, CSD_REG_LEN); + result = 0; + } + return result; +} + +//----- sdio_sd_isReady +s8 sdio_sd_isReady() { + s8 result = sdio_status - SDIO_SD_OK; + if (sdio_status != SDIO_SD_OK) + result = -1; + return result; +} + +//----- sdio_sd_getCapacity +u32 sdio_sd_getCapacity(void) { + u32 result; + uint8_t csd[CSD_REG_LEN]; + if (sdio_status <= SDIO_SD_NONE) + result = 0; // -1; + else { + rtl_memcpy(csd, SdioHostAdapter.Csd, CSD_REG_LEN); + if ((csd[0] & 0xC0) == 64) + result = (u16) (csd[9] + 1 + (csd[8] << 8)) << 9; + else + result = (4 * csd[7] + ((u32) csd[8] >> 6) + 1 + + ((csd[6] & 3) << 10)) + << ((csd[5] & 0xF) + (csd[10] >> 7) + 2 * (csd[9] & 3) - 8); + result *= 2; + } + return result; +} + +s8 sdio_sd_hook_insert_cb(sdio_sd_irq_handler CallbackFun, void *param) { + card_insert_irq_handler = CallbackFun; + card_insert_irq_data = (uint32_t) param; + return 0; +} + +s8 sdio_sd_hook_remove_cb(sdio_sd_irq_handler CallbackFun, void *param) { + card_remove_irq_handler = CallbackFun; + card_remove_irq_data = (uint32_t) param; + return 0; +} + +s8 sdio_sd_hook_xfer_cmp_cb(sdio_sd_irq_handler CallbackFun, void *param) { + xfer_done_irq_handler = CallbackFun; + xfer_done_irq_data = (uint32_t) param; + return 0; +} + +s8 sdio_sd_hook_xfer_err_cb(sdio_sd_irq_handler CallbackFun, void *param) { + xfer_err_irq_handler = CallbackFun; + xfer_err_irq_data = (uint32_t) param; + return 0; +} + +#endif // CONFIG_SDIO_HOST_EN diff --git a/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/eth_debug.h b/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/eth_debug.h new file mode 100644 index 0000000..71fe0bc --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/eth_debug.h @@ -0,0 +1,22 @@ +#ifndef _ETH_DEBUG_H_ +#define _ETH_DEBUG_H_ + +#define ETH_DEBUG 0 + +#if ETH_DEBUG +#define ETH_PRINT(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args) +#define ETH_ERROR(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args) +#define ETH_WARM(fmt, args...) printf("\n\r[%s]%s: " fmt, __FUNCTION__, ## args) +#define FUN_ENTER printf("\n\r[%s ==>]\n", __func__) +#define FUN_EXIT printf("\n\r[%s <==]\n", __func__) +#define FUN_TRACE printf("\n\r[%s]:%d \n", __func__, __LINE__) +#else +#define ETH_PRINT(fmt, args...) +#define ETH_ERROR(fmt, args...) printf("\n\r%s: " fmt,__FUNCTION__, ## args) +#define ETH_WARM(fmt, args...) +#define FUN_ENTER +#define FUN_EXIT +#define FUN_TRACE +#endif + +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/usb_ethernet.h b/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/usb_ethernet.h new file mode 100644 index 0000000..17b481c --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/ethernet/inc/usb_ethernet.h @@ -0,0 +1,358 @@ +/* + * Ethernet gadget driver -- with CDC and non-CDC options + * Builds on hardware support for a full duplex link. + * + * CDC Ethernet is the standard USB solution for sending Ethernet frames + * using USB. Real hardware tends to use the same framing protocol but look + * different for control features. This driver strongly prefers to use + * this USB-IF standard as its open-systems interoperability solution; + * most host side USB stacks (except from Microsoft) support it. + * + * There's some hardware that can't talk CDC. We make that hardware + * implement a "minimalist" vendor-agnostic CDC core: same framing, but + * link-level setup only requires activating the configuration. + * Linux supports it, but other host operating systems may not. + * (This is a subset of CDC Ethernet.) + * + * A third option is also in use. Rather than CDC Ethernet, or something + * simpler, Microsoft pushes their own approach: RNDIS. The published + * RNDIS specs are ambiguous and appear to be incomplete, and are also + * needlessly complex. + */ +#ifndef __USB_ETHERNET_H +#define __USB_ETHERNET_H + +#include "usb.h" +#include "usb_gadget.h" +#include "core/inc/usb_composite.h" + +//#define DRIVER_DESC "Ethernet Gadget" +#define DRIVER_DESC "USB Network Interface" +#define DRIVER_VERSION "May Day 2015" +#define ETH_ADDR "00E04C8196C8" + +static const char shortname [] = "ether"; +static const char driver_desc [] = DRIVER_DESC; + +#define CONFIG_USB_ETH_RNDIS 1 + + +#define RNDIS_VENDOR_NUM ULINKER_ETHER_VID +#define RNDIS_PRODUCT_NUM ULINKER_ETHER_PID + + +/* Thanks to NetChip Technologies for donating this product ID. + * It's for devices with only CDC Ethernet configurations. + */ +#define CDC_VENDOR_NUM 0x0525 /* NetChip */ +#define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ + +/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly + * ep0 implementation: descriptors, config management, setup(). + * also optional class-specific notification interrupt transfer. + */ + +/* + * DESCRIPTORS ... most are static, but strings and (full) configuration + * descriptors are built on demand. For now we do either full CDC, or + * our simple subset, with RNDIS as an optional second configuration. + * + * RNDIS includes some CDC ACM descriptors ... like CDC Ethernet. But + * the class descriptors match a modem (they're ignored; it's really just + * Ethernet functionality), they don't need the NOP altsetting, and the + * status transfer endpoint isn't optional. + */ + +#define STRING_MANUFACTURER 1 +#define STRING_PRODUCT 2 +#define STRING_ETHADDR 3 +#define STRING_DATA 4 +#define STRING_CONTROL 5 +#define STRING_RNDIS_CONTROL 6 +#define STRING_CDC 7 +#define STRING_SUBSET 8 +#define STRING_RNDIS 9 +#define STRING_SERIALNUMBER 10 + +/* holds our biggest descriptor (or RNDIS response) */ +#define USB_BUFSIZ 256 + +#define BUFSIZ_IN 512 +#define BUFSIZ_OUT 512 +/* + * This device advertises one configuration, eth_config, unless RNDIS + * is enabled (rndis_config) on hardware supporting at least two configs. + * + * NOTE: Controllers like superh_udc should probably be able to use + * an RNDIS-only configuration. + * + * FIXME define some higher-powered configurations to make it easier + * to recharge batteries ... + */ + +//#define DEV_CONFIG_VALUE 1 /* cdc or subset */ +//#define DEV_RNDIS_CONFIG_VALUE 2 /* rndis; optional */ +#define DEV_CONFIG_VALUE 2 /* cdc or subset */ +#define DEV_RNDIS_CONFIG_VALUE 1 /* rndis; optional */ + + +#define DEVSPEED USB_SPEED_HIGH + + +/* descriptors that are built on-demand */ + +static char manufacturer [50]; +static char product_desc [40] = DRIVER_DESC; +static char serial_number [20]; + + +/* address that the host will use ... usually assigned at random */ +//ModifiedByJD static char ethaddr [2 * ETH_ALEN + 1]; +static char ethaddr [2 * 6 + 1] = ETH_ADDR; + +/* static strings, in UTF-8 */ +static struct usb_string strings [] = { + { STRING_MANUFACTURER, manufacturer, }, + { STRING_PRODUCT, product_desc, }, + { STRING_SERIALNUMBER, serial_number, }, + { STRING_DATA, "Ethernet Data", }, +#if 1//def DEV_CONFIG_CDC//ModifiedByJD + { STRING_CDC, "CDC Ethernet", }, + { STRING_ETHADDR, ethaddr, }, + { STRING_CONTROL, "CDC Communications Control", }, +#endif +#if 1//def DEV_CONFIG_SUBSET//ModifiedByJD + { STRING_SUBSET, "CDC Ethernet Subset", }, +#endif +#if 1//def CONFIG_USB_ETH_RNDIS//ModifiedByJD + { STRING_RNDIS, "RNDIS", }, + { STRING_RNDIS_CONTROL, "RNDIS Communications Control", }, +#endif /* end of list */ +}; + +static struct usb_gadget_strings stringtab = { + .language = 0x0409, /* en-us */ + .strings = strings, +}; + +static struct usb_gadget_strings *dev_strings[] = { + &stringtab, + NULL, +}; + +static struct usb_device_descriptor +device_desc = { + .bLength = sizeof device_desc, + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = (0x0200), + + .bDeviceClass = USB_CLASS_COMM, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + + .idVendor = (CDC_VENDOR_NUM), + .idProduct = (CDC_PRODUCT_NUM), + .iManufacturer = STRING_MANUFACTURER, + .iProduct = STRING_PRODUCT, + .bNumConfigurations = 1, +}; + +static struct usb_config_descriptor +eth_config = { + .bLength = sizeof eth_config, + .bDescriptorType = USB_DT_CONFIG, + + /* compute wTotalLength on the fly */ + .bNumInterfaces = 1, + .bConfigurationValue = DEV_CONFIG_VALUE, + .iConfiguration = STRING_CDC, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 50, +}; + +static struct usb_otg_descriptor +otg_descriptor = { + .bLength = sizeof otg_descriptor, + .bDescriptorType = USB_DT_OTG, + + .bmAttributes = USB_OTG_SRP, +}; + + +#ifdef CONFIG_USB_ETH_RNDIS + +/* RNDIS doesn't activate by changing to the "real" altsetting */ + +static struct usb_interface_descriptor +rndis_data_intf = { + .bLength = sizeof rndis_data_intf, + .bDescriptorType = USB_DT_INTERFACE, + + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = STRING_DATA, +}; + +#endif + + +static struct usb_endpoint_descriptor +hs_source_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (512),//ModifiedByJD +}; + +static struct usb_endpoint_descriptor +hs_sink_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (512),//ModifiedByJD +}; + +static struct usb_endpoint_descriptor +fs_source_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, +}; + +static struct usb_endpoint_descriptor +fs_sink_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, +}; + + +static const struct usb_descriptor_header *fs_rndis_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + /* control interface matches ACM, not Ethernet */ +#if 0//ModifiedByJD + (struct usb_descriptor_header *) &rndis_control_intf, + (struct usb_descriptor_header *) &header_desc, + (struct usb_descriptor_header *) &call_mgmt_descriptor, + (struct usb_descriptor_header *) &acm_descriptor, + (struct usb_descriptor_header *) &union_desc, + (struct usb_descriptor_header *) &fs_status_desc, +#endif + /* data interface has no altsetting */ + (struct usb_descriptor_header *) &rndis_data_intf, + (struct usb_descriptor_header *) &fs_source_desc, + (struct usb_descriptor_header *) &fs_sink_desc, + NULL, +}; + + + + +static const struct usb_descriptor_header *fs_eth_function [11] = { + (struct usb_descriptor_header *) &otg_descriptor, +#ifdef DEV_CONFIG_CDC + /* "cdc" mode descriptors */ + (struct usb_descriptor_header *) &control_intf, + (struct usb_descriptor_header *) &header_desc, + (struct usb_descriptor_header *) &union_desc, + (struct usb_descriptor_header *) ðer_desc, + /* NOTE: status endpoint may need to be removed */ + (struct usb_descriptor_header *) &fs_status_desc, + /* data interface, with altsetting */ + (struct usb_descriptor_header *) &data_nop_intf, + (struct usb_descriptor_header *) &data_intf, + (struct usb_descriptor_header *) &fs_source_desc, + (struct usb_descriptor_header *) &fs_sink_desc, + NULL, +#endif /* DEV_CONFIG_CDC */ +}; + +#ifdef CONFIG_USB_ETH_RNDIS +static const struct usb_descriptor_header *hs_rndis_function [] = { + (struct usb_descriptor_header *) &otg_descriptor, + /* control interface matches ACM, not Ethernet */ +#if 0//ModifiedByJD + (struct usb_descriptor_header *) &rndis_control_intf, + (struct usb_descriptor_header *) &header_desc, + (struct usb_descriptor_header *) &call_mgmt_descriptor, + (struct usb_descriptor_header *) &acm_descriptor, + (struct usb_descriptor_header *) &union_desc, + (struct usb_descriptor_header *) &hs_status_desc, +#endif + /* data interface has no altsetting */ + (struct usb_descriptor_header *) &rndis_data_intf, + (struct usb_descriptor_header *) &hs_source_desc, + (struct usb_descriptor_header *) &hs_sink_desc, + NULL, +}; +#endif + +static struct usb_config_descriptor +rndis_config = { + .bLength = sizeof rndis_config, + .bDescriptorType = USB_DT_CONFIG, + + /* compute wTotalLength on the fly */ + .bNumInterfaces = 1, + .bConfigurationValue = DEV_RNDIS_CONFIG_VALUE, + .iConfiguration = STRING_RNDIS, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 50, +}; + +static struct usb_configuration eth_configuration = { + .label = "eth_configuration", + .bConfigurationValue = DEV_CONFIG_VALUE, +// .bConfigurationValue = 1, + /* .iConfiguration = DYNAMIC */ + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, +}; + + +static struct eth_dev{ + struct usb_gadget *gadget; + struct usb_request *req; /* for control responses */ + /* when configured, we have one of two configs: + * - source data (in to host) and sink it (out from host) + * - or loop it back (out from host back in to host) + */ + u8 config; + struct usb_ep *in_ep; + struct usb_ep *out_ep; + const struct usb_endpoint_descriptor + *in, *out, *status; + // lock is held when accessing usb + _Lock lock; + + struct usb_function func; + + + + /*send (depends on host)*/ + _Sema xmit_sema; + xTaskHandle xmit_task; + unsigned int qlen; + _Mutex xmit_mutex; + _LIST eth2wlan_list; + /*receive (debuf_poolpends on host)*/ + _Sema recv_sema; + xTaskHandle recv_task; + _Mutex recv_mutex; + _LIST wlan2eth_list; +}; + + +extern int usb_eth_init(void); + +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc.h b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc.h new file mode 100644 index 0000000..b4237af --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc.h @@ -0,0 +1,183 @@ +#ifndef USBD_MSC_H +#define USBD_MSC_H + +#include "usb.h" +#include "usb_gadget.h" +#include "core/inc/usb_composite.h" +#include "msc/inc/usbd_msc_config.h" + +/* config usb msc device debug inforation */ +#define USBD_MSC_DEBUG 0 + +#if USBD_MSC_DEBUG +#define USBD_PRINTF(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args) +#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args) +#define USBD_WARN(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args) +#define FUN_ENTER DBG_8195A("\n\r%s ==>\n", __func__) +#define FUN_EXIT DBG_8195A("\n\r%s <==\n", __func__) +#define FUN_TRACE DBG_8195A("\n\r%s:%d \n", __func__, __LINE__) +#else +#define USBD_PRINTF(fmt, args...) +#define USBD_ERROR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args) +#define USBD_WARN(fmt, args...) +#define FUN_ENTER +#define FUN_EXIT +#define FUN_TRACE +#endif + +/* MSC Request Codes */ +#define MSC_REQUEST_RESET 0xFF +#define MSC_REQUEST_GET_MAX_LUN 0xFE + +/* MSC LUN */ +#define MSC_MAX_LOGIC_UNIT_NUMBER 1 + +enum data_direction{ + DATA_DIR_UNKNOWN = 0, + DATA_DIR_FROM_HOST, + DATA_DIR_TO_HOST, + DATA_DIR_NONE +}; + +typedef enum _disk_type{ + DISK_SDCARD, + DISK_FLASH +}disk_type; + +//structure predefine +struct msc_dev; +struct msc_bufhd; + +struct msc_opts{ + int (*disk_init)(void); + int (*disk_deinit)(void); + int (*disk_getcapacity)(u32* sectors); + int (*disk_read)(u32 sector,u8 *buffer,u32 count); + int (*disk_write)(u32 sector,const u8 *buffer,u32 count); +}; + +struct msc_lun { + unsigned int initially_ro:1; + unsigned int ro:1; + unsigned int removable:1; + unsigned int cdrom:1; + unsigned int prevent_medium_removal:1; + unsigned int registered:1; + unsigned int info_valid:1; + unsigned int nofua:1; + + u32 sense_data; + u32 sense_data_info; + u32 unit_attention_data; + + u64 file_length; + unsigned int num_sectors; /* */ + unsigned int blkbits; /* Bits of logical block size + of bound block device */ + unsigned int blksize; /* logical block size of bound block device */ + const char *name; /* "lun.name" */ + + unsigned int lba; // the current read and write logical block address + u8 is_open; + _mutex lun_mutex; + struct msc_opts *lun_opts; +}; + + +struct msc_common{ + struct msc_dev *mscdev; + + struct msc_lun **luns; + struct msc_lun *curlun; + + struct usb_gadget *gadget; + struct usb_ep *ep0; + struct usb_request *req0; /* for control responses */ + + /* scsi cbw relevant */ + enum data_direction data_dir; + u32 data_size; + u32 data_size_from_cmnd; + u32 tag; + u32 residue; + u32 usb_amount_left; + u8 scsi_cmnd[16]; // max command + u8 cmnd_size; + + u8 lun; /* current lun*/ + u8 nluns; + + u8 nbufhd; + u8 nbufhd_a; + _list bufhd_pool; + _mutex bufhd_mutex; + /* bulk out cmd*/ + _list boc_list; + _mutex boc_mutex; + + /* bolk out data*/ + _mutex bod_mutex; + _list bod_list; + /**/ + struct msc_bufhd* curbh; // current buffer header + struct msc_bufhd* cbw_bh; // buffer header for CBW + struct msc_bufhd* csw_bh; // buffer header for CSW + + unsigned int can_stall:1; + unsigned int phase_error:1; + unsigned int short_packet_received:1; + unsigned int bad_lun_okay:1; + unsigned int running:1; +}; + +typedef enum _bufhd_type{ + BUFHD_CBW = 0, + BUFHD_CSW, + BUFHD_DATA, +}bufhd_type; + +struct msc_bufhd{ + u8* buf; + int buf_size; + bufhd_type type; + _list list; + struct usb_request *reqin; /* for bulkin responses */ + struct usb_request *reqout; +}; + +struct msc_dev{ + struct msc_common *common; + + u16 interface_number; + u8 config; + + struct usb_ep *in_ep; + struct usb_ep *out_ep; + unsigned int bulk_in_enabled:1; + unsigned int bulk_out_enabled:1; + + const struct usb_endpoint_descriptor + *in, *out, *status; + // lock is held when accessing usb + struct task_struct msc_outCmdTask; + struct task_struct msc_outDataTask; + struct usb_function func; +}; + +u32 min(u32 value1,u32 value2); + +int usbd_msc_halt_bulk_in_endpoint(struct msc_dev *mscdev); +void usbd_msc_put_bufhd(struct msc_common *common, struct msc_bufhd* bufhd); +struct msc_bufhd* usbd_msc_get_bufhd(struct msc_common *common); +int usbd_msc_bulk_in_transfer(struct msc_dev *mscdev, struct usb_request *req); +int usbd_msc_bulk_out_transfer(struct msc_dev *mscdev, struct usb_request *req); + +/* +* N_bh : number of buffer header +* Size_bh: buffer size per buffer +* type:msc physical disk type +*/ +int usbd_msc_init(int N_bh, int Size_bh, disk_type type); +void usbd_msc_deinit(void); + +#endif diff --git a/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_config.h b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_config.h new file mode 100644 index 0000000..c978748 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_config.h @@ -0,0 +1,8 @@ +#ifndef _USBD_MSC_CONFIG_H +#define _USBD_MSC_CONFIG_H + +/* config usb MSC device buffer resource */ +#define MSC_NBR_BUFHD 2 /* number of buffer header for bulk in/out data*/ +#define MSC_BUFLEN (20*512)/* Default size of buffer length. Minmun of 512 byte*/ + +#endif diff --git a/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_desc.h b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_desc.h new file mode 100644 index 0000000..35e4f5c --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_msc_desc.h @@ -0,0 +1,196 @@ +#include "usb_ch9.h" +#include "usb_defs.h" +#include "usb_gadget.h" + +// Enable high-speed functionality (if device supports it) +#define USBD_HS_ENABLE 1 + + +// define string index +#define STRING_MANUFACTURER 1 +#define STRING_PRODUCT 2 +#define STRING_SERIALNUMBER 3 +#define STRING_INTERFACE 4 +#define STRING_MSC 5 + + +#define DEV_CONFIG_VALUE 1 + +#define DRIVER_DESC "USB Mass Storage" +#define DRIVER_VERSION "Feb 2016" + +#define MANUFACTURER "Realtek Singapore Semiconductor" + +static char string_manufacturer [50] = MANUFACTURER; +static char string_product [40] = DRIVER_DESC; +static char string_serial [20] = "0123456789"; + +struct usb_string +usbd_msc_strings [] = { + { STRING_MANUFACTURER, string_manufacturer, }, + { STRING_PRODUCT, string_product, }, + { STRING_SERIALNUMBER, string_serial, }, + { STRING_INTERFACE, "USB MSC Interface", }, + { STRING_MSC, "USB MSC", }, +}; + +struct usb_gadget_strings msc_stringtab = { + .language = 0x0409, /* en-us */ + .strings = usbd_msc_strings, +}; + +struct usb_gadget_strings *dev_msc_strings[] = { + &msc_stringtab, + NULL, +}; + +static struct usb_device_descriptor +usbd_msc_device_desc = { + .bLength = sizeof usbd_msc_device_desc, + .bDescriptorType = USB_DT_DEVICE, + + .bcdUSB = (0x0200), + + .bDeviceClass = 0x00,// define in interface descriptor + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + + .bMaxPacketSize0 = 64, // this will be set automatically depends on ep0 setting + .idVendor = 0x0BDA, + .idProduct = 0x8195, +// .bcdDevice = , + .iManufacturer = STRING_MANUFACTURER, + .iProduct = STRING_PRODUCT, + .iSerialNumber = STRING_SERIALNUMBER, + .bNumConfigurations=0x01, +}; +#if 0 +struct usb_config_descriptor +usbd_msc_config_desc = { + .bLength = sizeof usbd_msc_config_desc, + .bDescriptorType = USB_DT_CONFIG, + + /* compute wTotalLength on the fly */ + .bNumInterfaces = 1, + .bConfigurationValue = DEV_CONFIG_VALUE, + .iConfiguration = STRING_MSC, + .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, + .bMaxPower = 0x32, +}; +#endif + +#if USBD_HS_ENABLE +/* USB Device Qualifier Descriptor (for Full Speed) */ +static struct usb_qualifier_descriptor +usbd_msc_qualifier_desc_FS = { + .bLength = sizeof usbd_msc_qualifier_desc_FS, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = 0x0200, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = 64, + .bNumConfigurations = 0x01, + .bRESERVED = 0x00, +}; + +/* USB Device Qualifier Descriptor for High Speed */ +static struct usb_qualifier_descriptor +usbd_msc_qualifier_desc_HS = { + .bLength = sizeof usbd_msc_qualifier_desc_HS, + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = 0x0200, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = 64, + .bNumConfigurations = 0x01, + .bRESERVED = 0x00, +}; +#else +/* USB Device Qualifier Descriptor (for Full Speed) */ +static struct usb_qualifier_descriptor +usbd_msc_qualifier_desc_FS = { 0 }; + +/* USB Device Qualifier Descriptor for High Speed */ +static struct usb_qualifier_descriptor +usbd_msc_qualifier_desc_HS = { 0 }; +#endif + +/* MSC Interface, Alternate Setting 0*/ +struct usb_interface_descriptor +usbd_msc_intf_desc = { + .bLength = sizeof usbd_msc_intf_desc, + .bDescriptorType = USB_DT_INTERFACE, + + .bInterfaceNumber = 0x00, // this will be assign automatically + .bAlternateSetting =0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = USB_CLASS_MASS_STORAGE, + .bInterfaceSubClass = US_SC_SCSI, + .bInterfaceProtocol = US_PR_BULK, + .iInterface = STRING_INTERFACE, +}; + +/* MSC Endpoints for Low-speed/Full-speed */ +/* Endpoint, EP Bulk IN */ +struct usb_endpoint_descriptor +usbd_msc_source_desc_FS = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (64), + .bInterval = 0x00, + +}; +/* Endpoint, EP Bulk OUT */ +struct usb_endpoint_descriptor +usbd_msc_sink_desc_FS = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (64), + .bInterval = 0x00, +}; + +/* MSC Endpoints for High-speed */ +/* Endpoint, EP Bulk IN */ +struct usb_endpoint_descriptor +usbd_msc_source_desc_HS = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (512), + .bInterval = 0x00, +}; + +/* Endpoint, EP Bulk OUT */ +struct usb_endpoint_descriptor +usbd_msc_sink_desc_HS = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = (512), + .bInterval = 0x00, +}; + +struct usb_descriptor_header *usbd_msc_descriptors_FS [] = { + /* data interface has no altsetting */ + (struct usb_descriptor_header *) &usbd_msc_intf_desc, + (struct usb_descriptor_header *) &usbd_msc_source_desc_FS, + (struct usb_descriptor_header *) &usbd_msc_sink_desc_FS, + NULL, +}; +struct usb_descriptor_header *usbd_msc_descriptors_HS [] = { + /* data interface has no altsetting */ + (struct usb_descriptor_header *) &usbd_msc_intf_desc, + (struct usb_descriptor_header *) &usbd_msc_source_desc_HS, + (struct usb_descriptor_header *) &usbd_msc_sink_desc_HS, + NULL, +}; \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_scsi.h b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_scsi.h new file mode 100644 index 0000000..5a12fb5 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/class/msc/inc/usbd_scsi.h @@ -0,0 +1,110 @@ +#ifndef USBD_SCSI_H +#define USBD_SCSI_H +#include "basic_types.h" +#include "msc/inc/usbd_msc.h" + +#define MAX_COMMAND_SIZE 16 +#define MSC_MAX_LUNS 8 + +/* SCSI Commands */ +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_MODE_SENSE10 0x5A +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_READ6 0x08 +#define SCSI_READ10 0x28 +#define SCSI_READ12 0xA8 +#define SCSI_READ16 0x88 + +#define SCSI_READ_CAPACITY10 0x25 +#define SCSI_READ_CAPACITY16 0x9E + +#define SCSI_SYNCHRONIZE_CACHE 0x35 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_WRITE6 0x0A +#define SCSI_WRITE10 0x2A +#define SCSI_WRITE12 0xAA +#define SCSI_WRITE16 0x8A + +#define SCSI_VERIFY10 0x2F +#define SCSI_VERIFY12 0xAF +#define SCSI_VERIFY16 0x8F + +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_FORMAT_CAPACITIES 0x23 + +#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C +#define READ_CAPACITY10_DATA_LEN 0x08 +#define MODE_SENSE10_DATA_LEN 0x08 +#define MODE_SENSE6_DATA_LEN 0x04 +#define REQUEST_SENSE_DATA_LEN 0x12 +#define STANDARD_INQUIRY_DATA_LEN 0x24 + +/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ +#define SS_NO_SENSE 0 +#define SS_COMMUNICATION_FAILURE 0x040800 +#define SS_INVALID_COMMAND 0x052000 +#define SS_INVALID_FIELD_IN_CDB 0x052400 +#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 +#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 +#define SS_MEDIUM_NOT_PRESENT 0x023a00 +#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 +#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 +#define SS_RESET_OCCURRED 0x062900 +#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 +#define SS_UNRECOVERED_READ_ERROR 0x031100 +#define SS_WRITE_ERROR 0x030c02 +#define SS_WRITE_PROTECTED 0x072700 + + + +#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ +#define ASC(x) ((u8) ((x) >> 8)) +#define ASCQ(x) ((u8) (x)) + +/* +* Bulk only data structures +*/ + +/* command block wrapper */ +struct bulk_cb_wrap { + unsigned int Signature; /* contains 'USBC', denote bulk_cb_wrap */ + unsigned int Tag; /* unique per command id */ + unsigned int DataTransferLength; /* size of data for transfer */ + unsigned char Flags; /* data transfer direction */ + unsigned char Lun; /* LUN normally 0, (which command block is sent) */ + unsigned char Length; /* length of the CDB */ + unsigned char CDB[16]; /* max command */ +}; + +#define US_BULK_CB_WRAP_LEN 31 +#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */ +#define US_BULK_FLAG_IN (1 << 7) +#define US_BULK_FLAG_OUT 0 + +/* command status wrapper */ +struct bulk_cs_wrap { + unsigned int Signature; /* should = 'USBS' */ + unsigned int Tag; /* same as original command, echoed by the device as received */ + unsigned int Residue; /* amount not transferred */ + unsigned char Status; /* execute command status */ +}; + +#define US_BULK_CS_WRAP_LEN 13 +#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */ +// execute command status +#define US_BULK_STAT_OK 0 +#define US_BULK_STAT_FAIL 1 +#define US_BULK_STAT_PHASE 2 + +/* bulk-only class specific requests */ +#define US_BULK_RESET_REQUEST 0xff +#define US_BULK_GET_MAX_LUN 0xfe + +extern int usbd_msc_receive_cbw(struct msc_dev *mscdev, struct usb_request *req); +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/core/inc/gadget_debug.h b/USDK/component/common/drivers/usb_class/device/core/inc/gadget_debug.h new file mode 100644 index 0000000..7d65e14 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/core/inc/gadget_debug.h @@ -0,0 +1,24 @@ +#ifndef _GADEGT_DEBUG_H_ +#define _GADGET_DEBUG_H_ + +#include "diag.h" + +#define GADGET_DEBUG 0 + +#if GADGET_DEBUG +#define GADGET_PRINT(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args) +#define GADGET_ERROR(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args) +#define GADGET_WARN(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args) +#define FUN_ENTER DBG_8195A("\n\r[%s ==>]\n", __func__) +#define FUN_EXIT DBG_8195A("\n\r[%s <==]\n", __func__) +#define FUN_TRACE DBG_8195A("\n\r[%s]:%d \n", __func__, __LINE__) +#else +#define GADGET_PRINT(fmt, args...) +#define GADGET_ERROR(fmt, args...) DBG_8195A("\n\r[%s]: " fmt, __FUNCTION__, ## args) +#define GADGET_WARN(fmt, args...) +#define FUN_ENTER +#define FUN_EXIT +#define FUN_TRACE +#endif + +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/core/inc/os_wrapper.h b/USDK/component/common/drivers/usb_class/device/core/inc/os_wrapper.h new file mode 100644 index 0000000..7cf4e2e --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/core/inc/os_wrapper.h @@ -0,0 +1,30 @@ +#ifndef _OS_WRAPPER_H_ +#define _OS_WRAPPER_H_ + +#include "osdep_api.h" + +#ifndef spinlock_t +#define spinlock_t _Lock +#endif + +#ifndef _atomic_spin_lock_irqsave +#define _atomic_spin_lock_irqsave(p, flags) SaveAndCli() +#endif +#ifndef _atomic_spin_unlock_irqrestore +#define _atomic_spin_unlock_irqrestore(p, flags) RestoreFlags() +#endif + +/* spin lock */ +#ifndef spin_lock_init + #define spin_lock_init(plock) RtlSpinlockInit((plock)) +#endif +#ifndef spin_lock_free + #define spin_lock_free(plock) RtlSpinlockFree((plock)) +#endif +#ifndef spin_lock + #define spin_lock(plock) RtlSpinlock((plock)) +#endif +#ifndef spin_unlock + #define spin_unlock(plock) RtlSpinunlock((plock)) +#endif +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/device/core/inc/usb_composite.h b/USDK/component/common/drivers/usb_class/device/core/inc/usb_composite.h new file mode 100644 index 0000000..7b37100 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/core/inc/usb_composite.h @@ -0,0 +1,398 @@ +#ifndef _USB_COMPOSITE_H_ +#define _USB_COMPOSITE_H_ + +#include "usb_gadget.h" +#include "usb.h" + +/* + * USB function drivers should return USB_GADGET_DELAYED_STATUS if they + * wish to delay the data/status stages of the control transfer till they + * are ready. The control transfer will then be kept from completing till + * all the function drivers that requested for USB_GADGET_DELAYED_STAUS + * invoke usb_composite_setup_continue(). + */ +#define USB_GADGET_DELAYED_STATUS 0x7fff /* Impossibly large value */ + + +/* big enough to hold our biggest descriptor */ +#define USB_COMP_EP0_BUFSIZ 1024+24 +#define MAX_CONFIG_INTERFACES 16 /* arbitrary; max 255 */ +// predefine structure +struct usb_composite_dev; +struct usb_composite_driver; + +enum control_request_return_codes { + USBD_REQ_NOTSUPP = 0, + USBD_REQ_HANDLED = 1, + USBD_REQ_NEXT_CALLBACK = 2, +}; + + +/** + * struct usb_composite_driver - groups configurations into a gadget + * @name: For diagnostics, identifies the driver. + * @dev: Template descriptor for the device, including default device + * identifiers. + * @strings: tables of strings, keyed by identifiers assigned during @bind + * and language IDs provided in control requests. Note: The first entries + * are predefined. The first entry that may be used is + * USB_GADGET_FIRST_AVAIL_IDX + * @max_speed: Highest speed the driver supports. + * @needs_serial: set to 1 if the gadget needs userspace to provide + * a serial number. If one is not provided, warning will be printed. + * @bind: (REQUIRED) Used to allocate resources that are shared across the + * whole device, such as string IDs, and add its configurations using + * @usb_add_config(). This may fail by returning a negative errno + * value; it should return zero on successful initialization. + * @unbind: Reverses @bind; called as a side effect of unregistering + * this driver. + * @disconnect: optional driver disconnect method + * @suspend: Notifies when the host stops sending USB traffic, + * after function notifications + * @resume: Notifies configuration when the host restarts USB traffic, + * before function notifications + * @gadget_driver: Gadget driver controlling this driver + * + * Devices default to reporting self powered operation. Devices which rely + * on bus powered operation should report this in their @bind method. + * + * Before returning from @bind, various fields in the template descriptor + * may be overridden. These include the idVendor/idProduct/bcdDevice values + * normally to bind the appropriate host side driver, and the three strings + * (iManufacturer, iProduct, iSerialNumber) normally used to provide user + * meaningful device identifiers. (The strings will not be defined unless + * they are defined in @dev and @strings.) The correct ep0 maxpacket size + * is also reported, as defined by the underlying controller driver. + */ + +struct usb_composite_driver { + const char *name; + const struct usb_device_descriptor *dev; + struct usb_gadget_strings **strings; + enum usb_device_speed max_speed; + unsigned needs_serial:1; + + int (*bind)(struct usb_composite_dev *cdev); + int (*unbind)(struct usb_composite_dev *); + + void (*disconnect)(struct usb_composite_dev *); + + /* global suspend hooks */ + void (*suspend)(struct usb_composite_dev *); + void (*resume)(struct usb_composite_dev *); + struct usb_gadget_driver gadget_driver; +}; +/** + * struct usb_composite_device - represents one composite usb gadget + * @gadget: read-only, abstracts the gadget's usb peripheral controller + * @req: used for control responses; buffer is pre-allocated + * @os_desc_req: used for OS descriptors responses; buffer is pre-allocated + * @config: the currently active configuration + * @qw_sign: qwSignature part of the OS string + * @b_vendor_code: bMS_VendorCode part of the OS string + * @use_os_string: false by default, interested gadgets set it + * @os_desc_config: the configuration to be used with OS descriptors + * + * One of these devices is allocated and initialized before the + * associated device driver's bind() is called. + * + * OPEN ISSUE: it appears that some WUSB devices will need to be + * built by combining a normal (wired) gadget with a wireless one. + * This revision of the gadget framework should probably try to make + * sure doing that won't hurt too much. + * + * One notion for how to handle Wireless USB devices involves: + * (a) a second gadget here, discovery mechanism TBD, but likely + * needing separate "register/unregister WUSB gadget" calls; + * (b) updates to usb_gadget to include flags "is it wireless", + * "is it wired", plus (presumably in a wrapper structure) + * bandgroup and PHY info; + * (c) presumably a wireless_ep wrapping a usb_ep, and reporting + * wireless-specific parameters like maxburst and maxsequence; + * (d) configurations that are specific to wireless links; + * (e) function drivers that understand wireless configs and will + * support wireless for (additional) function instances; + * (f) a function to support association setup (like CBAF), not + * necessarily requiring a wireless adapter; + * (g) composite device setup that can create one or more wireless + * configs, including appropriate association setup support; + * (h) more, TBD. + */ + +#define MAX_USER_CONTROL_CALLBACK 2 + +typedef int (*user_control_callback)(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl); + +struct usb_composite_dev { + struct usb_gadget *gadget; + struct usb_request *req; + struct usb_request *os_desc_req; + + struct usb_configuration *config; +// +// /* OS String is a custom (yet popular) extension to the USB standard. */ +// u8 qw_sign[OS_STRING_QW_SIGN_LEN]; +// u8 b_vendor_code; +// struct usb_configuration *os_desc_config; +// unsigned int use_os_string:1; +// +// /* private: */ +// /* internals */ + unsigned int suspended:1; + struct usb_device_descriptor desc; + + //_LIST config_list; + dwc_list_link_t config_list; // by jimmy + //_LIST gstring_list; + dwc_list_link_t gstring_list;// by jimmy + + struct usb_composite_driver *driver; +// u8 next_string_id; +// char *def_manufacturer; +// +// /* the gadget driver won't enable the data pullup +// * while the deactivation count is nonzero. +// */ +// unsigned deactivations; +// +// /* the composite driver won't complete the control transfer's +// * data/status stages till delayed_status is zero. +// */ +// int delayed_status; +// +// /* protects deactivations and delayed_status counts*/ + _Lock lock; + /* for unstandard control request handler */ + + user_control_callback control_cb[MAX_USER_CONTROL_CALLBACK]; +}; + + +#if 0 +#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n)) + +static inline struct usb_composite_driver *to_cdriver( + struct usb_gadget_driver *gdrv) +{ + return container_of(gdrv, struct usb_composite_driver, gadget_driver); +} +#endif +#if 1 +/** + * struct usb_configuration - represents one gadget configuration + * @label: For diagnostics, describes the configuration. + * @strings: Tables of strings, keyed by identifiers assigned during @bind() + * and by language IDs provided in control requests. + * @descriptors: Table of descriptors preceding all function descriptors. + * Examples include OTG and vendor-specific descriptors. + * @unbind: Reverses @bind; called as a side effect of unregistering the + * driver which added this configuration. + * @setup: Used to delegate control requests that aren't handled by standard + * device infrastructure or directed at a specific interface. + * @bConfigurationValue: Copied into configuration descriptor. + * @iConfiguration: Copied into configuration descriptor. + * @bmAttributes: Copied into configuration descriptor. + * @MaxPower: Power consumtion in mA. Used to compute bMaxPower in the + * configuration descriptor after considering the bus speed. + * @cdev: assigned by @usb_add_config() before calling @bind(); this is + * the device associated with this configuration. + * + * Configurations are building blocks for gadget drivers structured around + * function drivers. Simple USB gadgets require only one function and one + * configuration, and handle dual-speed hardware by always providing the same + * functionality. Slightly more complex gadgets may have more than one + * single-function configuration at a given speed; or have configurations + * that only work at one speed. + * + * Composite devices are, by definition, ones with configurations which + * include more than one function. + * + * The lifecycle of a usb_configuration includes allocation, initialization + * of the fields described above, and calling @usb_add_config() to set up + * internal data and bind it to a specific device. The configuration's + * @bind() method is then used to initialize all the functions and then + * call @usb_add_function() for them. + * + * Those functions would normally be independent of each other, but that's + * not mandatory. CDC WMC devices are an example where functions often + * depend on other functions, with some functions subsidiary to others. + * Such interdependency may be managed in any way, so long as all of the + * descriptors complete by the time the composite driver returns from + * its bind() routine. + */ +struct usb_configuration { + const char *label; + struct usb_gadget_strings **strings; + const struct usb_descriptor_header **descriptors; + + /* REVISIT: bind() functions can be marked __init, which + * makes trouble for section mismatch analysis. See if + * we can't restructure things to avoid mismatching... + */ + + /* configuration management: unbind/setup */ + void (*unbind)(struct usb_configuration *); + int (*setup)(struct usb_configuration *, + const struct usb_ctrlrequest *); + + /* fields in the config descriptor */ + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u16 MaxPower; + + struct usb_composite_dev *cdev; + + /* private: */ + /* internals */ + //_LIST list; + //_LIST function_lists; + dwc_list_link_t list; + dwc_list_link_t function_lists; // by jimmy + + u8 next_interface_id; + unsigned superspeed:1; + unsigned highspeed:1; + unsigned fullspeed:1; + struct usb_function *interface[MAX_CONFIG_INTERFACES]; +}; + +_LONG_CALL_ int usb_interface_id(struct usb_configuration *config, + struct usb_function *function); + +_LONG_CALL_ int usb_add_config(struct usb_composite_dev *, + struct usb_configuration *, + int (*)(struct usb_configuration *)); + +_LONG_CALL_ void usb_remove_config(struct usb_composite_dev *, + struct usb_configuration *); + +/** + * struct usb_function - describes one function of a configuration + * @name: For diagnostics, identifies the function. + * @strings: tables of strings, keyed by identifiers assigned during bind() + * and by language IDs provided in control requests + * @fs_descriptors: Table of full (or low) speed descriptors, using interface and + * string identifiers assigned during @bind(). If this pointer is null, + * the function will not be available at full speed (or at low speed). + * @hs_descriptors: Table of high speed descriptors, using interface and + * string identifiers assigned during @bind(). If this pointer is null, + * the function will not be available at high speed. + * @ss_descriptors: Table of super speed descriptors, using interface and + * string identifiers assigned during @bind(). If this + * pointer is null after initiation, the function will not + * be available at super speed. + * @config: assigned when @usb_add_function() is called; this is the + * configuration with which this function is associated. + * @os_desc_table: Table of (interface id, os descriptors) pairs. The function + * can expose more than one interface. If an interface is a member of + * an IAD, only the first interface of IAD has its entry in the table. + * @os_desc_n: Number of entries in os_desc_table + * @bind: Before the gadget can register, all of its functions bind() to the + * available resources including string and interface identifiers used + * in interface or class descriptors; endpoints; I/O buffers; and so on. + * @unbind: Reverses @bind; called as a side effect of unregistering the + * driver which added this function. + * @free_func: free the struct usb_function. + * @mod: (internal) points to the module that created this structure. + * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may + * initialize usb_ep.driver data at this time (when it is used). + * Note that setting an interface to its current altsetting resets + * interface state, and that all interfaces have a disabled state. + * @get_alt: Returns the active altsetting. If this is not provided, + * then only altsetting zero is supported. + * @disable: (REQUIRED) Indicates the function should be disabled. Reasons + * include host resetting or reconfiguring the gadget, and disconnection. + * @setup: Used for interface-specific control requests. + * @suspend: Notifies functions when the host stops sending USB traffic. + * @resume: Notifies functions when the host restarts USB traffic. + * @get_status: Returns function status as a reply to + * GetStatus() request when the recipient is Interface. + * @func_suspend: callback to be called when + * SetFeature(FUNCTION_SUSPEND) is reseived + * + * A single USB function uses one or more interfaces, and should in most + * cases support operation at both full and high speeds. Each function is + * associated by @usb_add_function() with a one configuration; that function + * causes @bind() to be called so resources can be allocated as part of + * setting up a gadget driver. Those resources include endpoints, which + * should be allocated using @usb_ep_autoconfig(). + * + * To support dual speed operation, a function driver provides descriptors + * for both high and full speed operation. Except in rare cases that don't + * involve bulk endpoints, each speed needs different endpoint descriptors. + * + * Function drivers choose their own strategies for managing instance data. + * The simplest strategy just declares it "static', which means the function + * can only be activated once. If the function needs to be exposed in more + * than one configuration at a given speed, it needs to support multiple + * usb_function structures (one for each configuration). + * + * A more complex strategy might encapsulate a @usb_function structure inside + * a driver-specific instance structure to allows multiple activations. An + * example of multiple activations might be a CDC ACM function that supports + * two or more distinct instances within the same configuration, providing + * several independent logical data links to a USB host. + */ + +struct usb_function { + const char *name; + struct usb_gadget_strings **strings; + struct usb_descriptor_header **fs_descriptors; + struct usb_descriptor_header **hs_descriptors; +// struct usb_descriptor_header **ss_descriptors; + + struct usb_configuration *config; + +// struct usb_os_desc_table *os_desc_table; +// unsigned os_desc_n; + + /* REVISIT: bind() functions can be marked __init, which + * makes trouble for section mismatch analysis. See if + * we can't restructure things to avoid mismatching. + * Related: unbind() may kfree() but bind() won't... + */ + + /* configuration management: bind/unbind */ + int (*bind)(struct usb_configuration *, + struct usb_function *); + void (*unbind)(struct usb_configuration *, + struct usb_function *); + void (*free_func)(struct usb_function *f); + struct module *mod; + + /* runtime state management */ + int (*set_alt)(struct usb_function *, + unsigned interface, unsigned alt); + int (*get_alt)(struct usb_function *, + unsigned interface); + void (*disable)(struct usb_function *); + int (*setup)(struct usb_function *, + const struct usb_ctrlrequest *); + void (*suspend)(struct usb_function *); + void (*resume)(struct usb_function *); + + /* USB 3.0 additions */ + int (*get_status)(struct usb_function *); + int (*func_suspend)(struct usb_function *, + u8 suspend_opt); + /* private: */ + /* internals */ + //_LIST list; + dwc_list_link_t list; // by jimmy +// DECLARE_BITMAP(endpoints, 32); +// const struct usb_function_instance *fi; +}; + +#endif +extern _LONG_CALL_ int usb_add_function(struct usb_configuration *, struct usb_function *); +extern _LONG_CALL_ void usb_remove_function(struct usb_configuration *, struct usb_function *); +extern _LONG_CALL_ void usb_put_function(struct usb_function *); +extern _LONG_CALL_ int usb_function_deactivate(struct usb_function *); +extern _LONG_CALL_ int usb_function_activate(struct usb_function *); + +extern _LONG_CALL_ int usb_interface_id(struct usb_configuration *, struct usb_function *); +extern _LONG_CALL_ int usb_composite_probe(struct usb_composite_driver *driver); +extern _LONG_CALL_ int register_class_vendor_control_request_cb(struct usb_composite_dev *cdev, user_control_callback cb); +extern _LONG_CALL_ void usb_composite_unregister(struct usb_composite_driver *driver); +#endif diff --git a/USDK/component/common/drivers/usb_class/device/core/inc/usb_config.h b/USDK/component/common/drivers/usb_class/device/core/inc/usb_config.h new file mode 100644 index 0000000..112fa53 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/core/inc/usb_config.h @@ -0,0 +1,12 @@ +#ifndef _USB_CONFIG_H_ +#define _USB_CONFIG_H_ + +#include "core/inc/usb_composite.h" + +extern _LONG_CALL_ int usb_assign_descriptors(struct usb_function *f, + struct usb_descriptor_header **fs, + struct usb_descriptor_header **hs, + struct usb_descriptor_header **ss); + +extern _LONG_CALL_ void usb_free_all_descriptors(struct usb_function *f); +#endif diff --git a/USDK/component/common/drivers/usb_class/device/core/inc/usb_transport.h b/USDK/component/common/drivers/usb_class/device/core/inc/usb_transport.h new file mode 100644 index 0000000..5dd7ed3 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/device/core/inc/usb_transport.h @@ -0,0 +1,5 @@ +#ifndef _USB_BOT_H +#define _USB_BOT_H +#include "basic_types.h" + +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/quirks/quirks.h b/USDK/component/common/drivers/usb_class/host/storage/inc/quirks/quirks.h new file mode 100644 index 0000000..56782a3 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/quirks/quirks.h @@ -0,0 +1,34 @@ +/* + * This file holds the definitions of quirks found in USB devices. + * Only quirks that affect the whole device, not an interface, + * belong here. + */ + +#ifndef __QUIRKS_H +#define __QUIRKS_H + +/* string descriptors must not be fetched using a 255-byte read */ +#define USB_QUIRK_STRING_FETCH_255 0x00000001 + +/* device can't resume correctly so reset it instead */ +#define USB_QUIRK_RESET_RESUME 0x00000002 + +/* device can't handle Set-Interface requests */ +#define USB_QUIRK_NO_SET_INTF 0x00000004 + +/* device can't handle its Configuration or Interface strings */ +#define USB_QUIRK_CONFIG_INTF_STRINGS 0x00000008 + +/* device can't be reset(e.g morph devices), don't use reset */ +#define USB_QUIRK_RESET 0x00000010 + +/* device has more interface descriptions than the bNumInterfaces count, + and can't handle talking to these interfaces */ +#define USB_QUIRK_HONOR_BNUMINTERFACES 0x00000020 + +/* device needs a pause during initialization, after we read the device + descriptor */ +#define USB_QUIRK_DELAY_INIT 0x00000040 + +#endif /* __QUIRKS_H */ + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/scatterlist/scatterlist.h b/USDK/component/common/drivers/usb_class/host/storage/inc/scatterlist/scatterlist.h new file mode 100644 index 0000000..fc50557 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/scatterlist/scatterlist.h @@ -0,0 +1,20 @@ +#ifndef _SCATTERLIST_H +#define _SCATTERLIST_H + +struct scatterlist { + unsigned long sg_magic; + unsigned long page_link; + unsigned int offset; + + unsigned int length; + + dma_addr_t dma_address; + __u32 dma_length; +}; + +struct sg_table { + struct scatterlist *sgl; /* the list */ + unsigned int nents; /* number of mapped entries */ + unsigned int orig_nents; /* original size of list */ +}; +#endif diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/dma_direction.h b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/dma_direction.h new file mode 100644 index 0000000..de244ab --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/dma_direction.h @@ -0,0 +1,12 @@ +#ifndef _DMA_DIRECTION_H +#define _DMA_DIRECTION_H + +enum dma_data_direction { + DMA_BIDIRECTIONAL = 0, + DMA_TO_DEVICE = 1, + DMA_FROM_DEVICE = 2, + DMA_NONE = 3, +}; + +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi.h b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi.h new file mode 100644 index 0000000..c856a26 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi.h @@ -0,0 +1,585 @@ +/* + * This header file contains public constants and structures used by + * the scsi code for linux. + * + * For documentation on the OPCODES, MESSAGES, and SENSE values, + * please consult the SCSI standard. + */ +#ifndef _SCSI_SCSI_H +#define _SCSI_SCSI_H + +#include "us_os_wrap_via_osdep_api.h" + +#define HZ 1024 + +struct scsi_cmnd; + +enum scsi_timeouts { + SCSI_DEFAULT_EH_TIMEOUT = 10 * HZ, +}; + +/* + * The maximum number of SG segments that we will put inside a + * scatterlist (unless chaining is used). Should ideally fit inside a + * single page, to avoid a higher order allocation. We could define this + * to SG_MAX_SINGLE_ALLOC to pack correctly at the highest order. The + * minimum value is 32 + */ +#define SCSI_MAX_SG_SEGMENTS 128 + +/* + * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit + * is totally arbitrary, a setting of 2048 will get you at least 8mb ios. + */ +#ifdef ARCH_HAS_SG_CHAIN +#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048 +#else +#define SCSI_MAX_SG_CHAIN_SEGMENTS SCSI_MAX_SG_SEGMENTS +#endif + +/* + * DIX-capable adapters effectively support infinite chaining for the + * protection information scatterlist + */ +#define SCSI_MAX_PROT_SG_SEGMENTS 0xFFFF + +/* + * Special value for scanning to specify scanning or rescanning of all + * possible channels, (target) ids, or luns on a given shost. + */ +#define SCAN_WILD_CARD ~0 + +/* + * SCSI opcodes + */ + +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define INITIALIZE_ELEMENT_STATUS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e + +#define READ_FORMAT_CAPACITIES 0x23 +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define POSITION_TO_ELEMENT 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define UNMAP 0x42 +#define READ_TOC 0x43 +#define READ_HEADER 0x44 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define XDWRITEREAD_10 0x53 +#define MODE_SELECT_10 0x55 +#define RESERVE_10 0x56 +#define RELEASE_10 0x57 +#define MODE_SENSE_10 0x5a +#define PERSISTENT_RESERVE_IN 0x5e +#define PERSISTENT_RESERVE_OUT 0x5f +#define VARIABLE_LENGTH_CMD 0x7f +#define REPORT_LUNS 0xa0 +#define SECURITY_PROTOCOL_IN 0xa2 +#define MAINTENANCE_IN 0xa3 +#define MAINTENANCE_OUT 0xa4 +#define MOVE_MEDIUM 0xa5 +#define EXCHANGE_MEDIUM 0xa6 +#define READ_12 0xa8 +#define WRITE_12 0xaa +#define READ_MEDIA_SERIAL_NUMBER 0xab +#define WRITE_VERIFY_12 0xae +#define VERIFY_12 0xaf +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define SECURITY_PROTOCOL_OUT 0xb5 +#define READ_ELEMENT_STATUS 0xb8 +#define SEND_VOLUME_TAG 0xb6 +#define WRITE_LONG_2 0xea +#define EXTENDED_COPY 0x83 +#define RECEIVE_COPY_RESULTS 0x84 +#define ACCESS_CONTROL_IN 0x86 +#define ACCESS_CONTROL_OUT 0x87 +#define READ_16 0x88 +#define COMPARE_AND_WRITE 0x89 +#define WRITE_16 0x8a +#define READ_ATTRIBUTE 0x8c +#define WRITE_ATTRIBUTE 0x8d +#define VERIFY_16 0x8f +#define SYNCHRONIZE_CACHE_16 0x91 +#define WRITE_SAME_16 0x93 +#define SERVICE_ACTION_IN 0x9e +/* values for service action in */ +#define SAI_READ_CAPACITY_16 0x10 +#define SAI_GET_LBA_STATUS 0x12 +#define SAI_REPORT_REFERRALS 0x13 +/* values for VARIABLE_LENGTH_CMD service action codes + * see spc4r17 Section D.3.5, table D.7 and D.8 */ +#define VLC_SA_RECEIVE_CREDENTIAL 0x1800 +/* values for maintenance in */ +#define MI_REPORT_IDENTIFYING_INFORMATION 0x05 +#define MI_REPORT_TARGET_PGS 0x0a +#define MI_REPORT_ALIASES 0x0b +#define MI_REPORT_SUPPORTED_OPERATION_CODES 0x0c +#define MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS 0x0d +#define MI_REPORT_PRIORITY 0x0e +#define MI_REPORT_TIMESTAMP 0x0f +#define MI_MANAGEMENT_PROTOCOL_IN 0x10 +/* value for MI_REPORT_TARGET_PGS ext header */ +#define MI_EXT_HDR_PARAM_FMT 0x20 +/* values for maintenance out */ +#define MO_SET_IDENTIFYING_INFORMATION 0x06 +#define MO_SET_TARGET_PGS 0x0a +#define MO_CHANGE_ALIASES 0x0b +#define MO_SET_PRIORITY 0x0e +#define MO_SET_TIMESTAMP 0x0f +#define MO_MANAGEMENT_PROTOCOL_OUT 0x10 +/* values for variable length command */ +#define XDREAD_32 0x03 +#define XDWRITE_32 0x04 +#define XPWRITE_32 0x06 +#define XDWRITEREAD_32 0x07 +#define READ_32 0x09 +#define VERIFY_32 0x0a +#define WRITE_32 0x0b +#define WRITE_SAME_32 0x0d + +/* Values for T10/04-262r7 */ +#define ATA_16 0x85 /* 16-byte pass-thru */ +#define ATA_12 0xa1 /* 12-byte pass-thru */ + +/* + * SCSI command lengths + */ + +#define SCSI_MAX_VARLEN_CDB_SIZE 260 + +/* defined in T10 SCSI Primary Commands-2 (SPC2) */ +struct scsi_varlen_cdb_hdr { + __u8 opcode; /* opcode always == VARIABLE_LENGTH_CMD */ + __u8 control; + __u8 misc[5]; + __u8 additional_cdb_length; /* total cdb length - 8 */ + __be16 service_action; + /* service specific data follows */ +}; + +static inline unsigned +scsi_varlen_cdb_length(const void *hdr) +{ + return ((struct scsi_varlen_cdb_hdr *)hdr)->additional_cdb_length + 8; +} + +extern const unsigned char scsi_command_size_tbl[8]; +#define COMMAND_SIZE(opcode) scsi_command_size_tbl[((opcode) >> 5) & 7] + +static inline unsigned +scsi_command_size(const unsigned char *cmnd) +{ + return (cmnd[0] == VARIABLE_LENGTH_CMD) ? + scsi_varlen_cdb_length(cmnd) : COMMAND_SIZE(cmnd[0]); +} + +#ifdef CONFIG_ACPI +struct acpi_bus_type; + +extern int +scsi_register_acpi_bus_type(struct acpi_bus_type *bus); + +extern void +scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus); +#endif + +/* + * SCSI Architecture Model (SAM) Status codes. Taken from SAM-3 draft + * T10/1561-D Revision 4 Draft dated 7th November 2002. + */ +#define SAM_STAT_GOOD 0x00 +#define SAM_STAT_CHECK_CONDITION 0x02 +#define SAM_STAT_CONDITION_MET 0x04 +#define SAM_STAT_BUSY 0x08 +#define SAM_STAT_INTERMEDIATE 0x10 +#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14 +#define SAM_STAT_RESERVATION_CONFLICT 0x18 +#define SAM_STAT_COMMAND_TERMINATED 0x22 /* obsolete in SAM-3 */ +#define SAM_STAT_TASK_SET_FULL 0x28 +#define SAM_STAT_ACA_ACTIVE 0x30 +#define SAM_STAT_TASK_ABORTED 0x40 + +/** scsi_status_is_good - check the status return. + * + * @status: the status passed up from the driver (including host and + * driver components) + * + * This returns true for known good conditions that may be treated as + * command completed normally + */ +static inline int scsi_status_is_good(int status) +{ + /* + * FIXME: bit0 is listed as reserved in SCSI-2, but is + * significant in SCSI-3. For now, we follow the SCSI-2 + * behaviour and ignore reserved bits. + */ + status &= 0xfe; + return ((status == SAM_STAT_GOOD) || + (status == SAM_STAT_INTERMEDIATE) || + (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || + /* FIXME: this is obsolete in SAM-3 */ + (status == SAM_STAT_COMMAND_TERMINATED)); +} + +/* + * Status codes. These are deprecated as they are shifted 1 bit right + * from those found in the SCSI standards. This causes confusion for + * applications that are ported to several OSes. Prefer SAM Status codes + * above. + */ + +#define GOOD 0x00 +#define CHECK_CONDITION 0x01 +#define CONDITION_GOOD 0x02 +#define BUSY 0x04 +#define INTERMEDIATE_GOOD 0x08 +#define INTERMEDIATE_C_GOOD 0x0a +#define RESERVATION_CONFLICT 0x0c +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 +#define ACA_ACTIVE 0x18 +#define TASK_ABORTED 0x20 + +#define STATUS_MASK 0xfe + +/* + * SENSE KEYS + */ + +#define NO_SENSE 0x00 +#define RECOVERED_ERROR 0x01 +#define NOT_READY 0x02 +#define MEDIUM_ERROR 0x03 +#define HARDWARE_ERROR 0x04 +#define ILLEGAL_REQUEST 0x05 +#define UNIT_ATTENTION 0x06 +#define DATA_PROTECT 0x07 +#define BLANK_CHECK 0x08 +#define COPY_ABORTED 0x0a +#define ABORTED_COMMAND 0x0b +#define VOLUME_OVERFLOW 0x0d +#define MISCOMPARE 0x0e + + +/* + * DEVICE TYPES + * Please keep them in 0x%02x format for $MODALIAS to work + */ + +#define TYPE_DISK 0x00 +#define TYPE_TAPE 0x01 +#define TYPE_PRINTER 0x02 +#define TYPE_PROCESSOR 0x03 /* HP scanners use this */ +#define TYPE_WORM 0x04 /* Treated as ROM by our system */ +#define TYPE_ROM 0x05 +#define TYPE_SCANNER 0x06 +#define TYPE_MOD 0x07 /* Magneto-optical disk - + * - treated as TYPE_DISK */ +#define TYPE_MEDIUM_CHANGER 0x08 +#define TYPE_COMM 0x09 /* Communications device */ +#define TYPE_RAID 0x0c +#define TYPE_ENCLOSURE 0x0d /* Enclosure Services Device */ +#define TYPE_RBC 0x0e +#define TYPE_OSD 0x11 +#define TYPE_NO_LUN 0x7f + +/* SCSI protocols; these are taken from SPC-3 section 7.5 */ +enum scsi_protocol { + SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ + SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ + SCSI_PROTOCOL_SSA = 2, /* Serial Storage Architecture - Obsolete */ + SCSI_PROTOCOL_SBP = 3, /* firewire */ + SCSI_PROTOCOL_SRP = 4, /* Infiniband RDMA */ + SCSI_PROTOCOL_ISCSI = 5, + SCSI_PROTOCOL_SAS = 6, + SCSI_PROTOCOL_ADT = 7, /* Media Changers */ + SCSI_PROTOCOL_ATA = 8, + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ +}; + +/* Returns a human-readable name for the device */ +extern const char * scsi_device_type(unsigned type); + +/* + * standard mode-select header prepended to all mode-select commands + */ + +struct ccs_modesel_head { + __u8 _r1; /* reserved */ + __u8 medium; /* device-specific medium type */ + __u8 _r2; /* reserved */ + __u8 block_desc_length; /* block descriptor length */ + __u8 density; /* device-specific density code */ + __u8 number_blocks_hi; /* number of blocks in this block desc */ + __u8 number_blocks_med; + __u8 number_blocks_lo; + __u8 _r3; + __u8 block_length_hi; /* block length for blocks in this desc */ + __u8 block_length_med; + __u8 block_length_lo; +}; + +/* + * ScsiLun: 8 byte LUN. + */ +struct scsi_lun { + __u8 scsi_lun[8]; +}; + +/* + * The Well Known LUNS (SAM-3) in our int representation of a LUN + */ +#define SCSI_W_LUN_BASE 0xc100 +#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1) +#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2) +#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3) + +static inline int scsi_is_wlun(unsigned int lun) +{ + return (lun & 0xff00) == SCSI_W_LUN_BASE; +} + + +/* + * MESSAGE CODES + */ + +#define COMMAND_COMPLETE 0x00 +#define EXTENDED_MESSAGE 0x01 +#define EXTENDED_MODIFY_DATA_POINTER 0x00 +#define EXTENDED_SDTR 0x01 +#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ +#define EXTENDED_WDTR 0x03 +#define EXTENDED_PPR 0x04 +#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05 +#define SAVE_POINTERS 0x02 +#define RESTORE_POINTERS 0x03 +#define DISCONNECT 0x04 +#define INITIATOR_ERROR 0x05 +#define ABORT_TASK_SET 0x06 +#define MESSAGE_REJECT 0x07 +#define NOP 0x08 +#define MSG_PARITY_ERROR 0x09 +#define LINKED_CMD_COMPLETE 0x0a +#define LINKED_FLG_CMD_COMPLETE 0x0b +#define TARGET_RESET 0x0c +#define ABORT_TASK 0x0d +#define CLEAR_TASK_SET 0x0e +#define INITIATE_RECOVERY 0x0f /* SCSI-II only */ +#define RELEASE_RECOVERY 0x10 /* SCSI-II only */ +#define CLEAR_ACA 0x16 +#define LOGICAL_UNIT_RESET 0x17 +#define SIMPLE_QUEUE_TAG 0x20 +#define HEAD_OF_QUEUE_TAG 0x21 +#define ORDERED_QUEUE_TAG 0x22 +#define IGNORE_WIDE_RESIDUE 0x23 +#define ACA 0x24 +#define QAS_REQUEST 0x55 + +/* Old SCSI2 names, don't use in new code */ +#define BUS_DEVICE_RESET TARGET_RESET +#define ABORT ABORT_TASK_SET + +/* + * Host byte codes + */ + +#define DID_OK 0x00 /* NO error */ +#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ +#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ +#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ +#define DID_BAD_TARGET 0x04 /* BAD target. */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody. */ +#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */ +#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */ +#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */ +#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also + * without decrementing the retry count */ +#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution + * and the driver blocked the port to + * recover the link. Transport class will + * retry or fail IO */ +#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */ +#define DID_TARGET_FAILURE 0x10 /* Permanent target failure, do not retry on + * other paths */ +#define DID_NEXUS_FAILURE 0x11 /* Permanent nexus failure, retry on other + * paths might yield different results */ +#define DID_ALLOC_FAILURE 0x12 /* Space allocation on the device failed */ +#define DID_MEDIUM_ERROR 0x13 /* Medium error */ +#define DRIVER_OK 0x00 /* Driver status */ + +/* + * These indicate the error that occurred, and what is available. + */ + +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 + +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 + +/* + * Internal return values. + */ + +#define NEEDS_RETRY 0x2001 +#define SUCCESS 0x2002 +#define FAILED 0x2003 +#define QUEUED 0x2004 +#define SOFT_ERROR 0x2005 +#define ADD_TO_MLQUEUE 0x2006 +#define TIMEOUT_ERROR 0x2007 +#define SCSI_RETURN_NOT_HANDLED 0x2008 +#define FAST_IO_FAIL 0x2009 + +/* + * Midlevel queue return values. + */ +#define SCSI_MLQUEUE_HOST_BUSY 0x1055 +#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 +#define SCSI_MLQUEUE_EH_RETRY 0x1057 +#define SCSI_MLQUEUE_TARGET_BUSY 0x1058 + +/* + * Use these to separate status msg and our bytes + * + * These are set by: + * + * status byte = set from target device + * msg_byte = return status from host adapter itself. + * host_byte = set by low-level driver to indicate status. + * driver_byte = set by mid-level. + */ +#define status_byte(result) (((result) >> 1) & 0x7f) +#define msg_byte(result) (((result) >> 8) & 0xff) +#define host_byte(result) (((result) >> 16) & 0xff) +#define driver_byte(result) (((result) >> 24) & 0xff) + +#define sense_class(sense) (((sense) >> 4) & 0x7) +#define sense_error(sense) ((sense) & 0xf) +#define sense_valid(sense) ((sense) & 0x80) + +/* + * default timeouts +*/ +#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ) +#define START_STOP_TIMEOUT (60 * HZ) +#define MOVE_MEDIUM_TIMEOUT (5 * 60 * HZ) +#define READ_ELEMENT_STATUS_TIMEOUT (5 * 60 * HZ) +#define READ_DEFECT_DATA_TIMEOUT (60 * HZ ) + + +#define IDENTIFY_BASE 0x80 +#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\ + ((can_disconnect) ? 0x40 : 0) |\ + ((lun) & 0x07)) + +/* + * struct scsi_device::scsi_level values. For SCSI devices other than those + * prior to SCSI-2 (i.e. over 12 years old) this value is (resp[2] + 1) + * where "resp" is a byte array of the response to an INQUIRY. The scsi_level + * variable is visible to the user via sysfs. + */ + +#define SCSI_UNKNOWN 0 +#define SCSI_1 1 +#define SCSI_1_CCS 2 +#define SCSI_2 3 +#define SCSI_3 4 /* SPC */ +#define SCSI_SPC_2 5 +#define SCSI_SPC_3 6 + +/* + * INQ PERIPHERAL QUALIFIERS + */ +#define SCSI_INQ_PQ_CON 0x00 +#define SCSI_INQ_PQ_NOT_CON 0x01 +#define SCSI_INQ_PQ_NOT_CAP 0x03 + + +/* + * Here are some scsi specific ioctl commands which are sometimes useful. + * + * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395 + */ + +/* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */ +#define SCSI_IOCTL_GET_IDLUN 0x5382 + +/* 0x5383 and 0x5384 were used for SCSI_IOCTL_TAGGED_{ENABLE,DISABLE} */ + +/* Used to obtain the host number of a device. */ +#define SCSI_IOCTL_PROBE_HOST 0x5385 + +/* Used to obtain the bus number for a device */ +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 + +/* Used to obtain the PCI location of a device */ +#define SCSI_IOCTL_GET_PCI 0x5387 + +/* Pull a u32 out of a SCSI message (using BE SCSI conventions) */ +static inline __u32 scsi_to_u32(__u8 *ptr) +{ + return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3]; +} + +#endif /* _SCSI_SCSI_H */ diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_cmnd.h b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_cmnd.h new file mode 100644 index 0000000..4e53d11 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_cmnd.h @@ -0,0 +1,84 @@ +#ifndef __SCSI_CMND_H_ +#define __SCSI_CMND_H_ + +#include "us_usb.h" +#include "us_os_wrap_via_osdep_api.h" +#include +#include +#include +/** + * define flash block size + */ +#define BLOCK_SIZE 512 + +struct scsi_data_buffer { + struct sg_table table; + unsigned char *data_buffer; /* Data buffer to store read data */ + unsigned length; + int resid; +}; + +struct scsi_cmnd{ + int result; /* Status code from lower level driver */ + + unsigned int channel,id,lun; + enum dma_data_direction sc_data_direction; + unsigned short cmd_len; + unsigned length; + _Sema cmnd_done; + + int eh_eflags; /* Used by error handlr */ + + struct scsi_data_buffer sdb; + + unsigned long sector;/* Sector address in LBA */ + unsigned int count;/* Number of sectors to read */ + void *request_buffer; + + /* These elements define the operation we are about to perform */ +#define MAX_COMMAND_SIZE 16 + unsigned char cmnd[MAX_COMMAND_SIZE]; + +#define SCSI_SENSE_BUFFERSIZE 96 + unsigned char *sense_buffer; /* obtained by REQUEST SENSE + * when CHECK CONDITION is + * received on original command + * (auto-sense) */ + + /* Low-level done function - can be used by low-level driver to point + * to completion function. Not used by mid/upper level code. */ + void (*scsi_done) (struct scsi_cmnd *); + + unsigned underflow; /* Return error if less than + this amount is transferred */ +}; + +static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.nents; +} + +static inline struct scatterlist *scsi_sglist(struct scsi_cmnd *cmd) +{ + return cmd->sdb.table.sgl; +} + +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->sdb.resid = resid; +} +// +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->sdb.resid; +} +static inline unsigned scsi_bufflen(struct scsi_cmnd *cmd) +{ + return cmd->sdb.length; +} + +extern int scsi_cmnd_execute(char cmnd, unsigned char * _buff, + unsigned long _sector, unsigned int _count); + +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_eh.h b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_eh.h new file mode 100644 index 0000000..e9d69d1 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/scsi/scsi_eh.h @@ -0,0 +1,52 @@ +#ifndef _SCSI_EH_H_ +#define _SCSI_EH_H_ + +#include "scsi/scsi_cmnd.h" +#include "dma_direction.h" + +#define BLK_MAX_CDB 16 +/* + * This is a slightly modified SCSI sense "descriptor" format header. + * The addition is to allow the 0x70 and 0x71 response codes. The idea + * is to place the salient data from either "fixed" or "descriptor" sense + * format into one structure to ease application processing. + * + * The original sense buffer should be kept around for those cases + * in which more information is required (e.g. the LBA of a MEDIUM ERROR). + */ +struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ + u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ + u8 sense_key; + u8 asc; + u8 ascq; + u8 byte4; + u8 byte5; + u8 byte6; + u8 additional_length; /* always 0 for fixed sense format */ +}; + +static inline int scsi_sense_valid(struct scsi_sense_hdr *sshdr) +{ + if (!sshdr) + return 0; + return (sshdr->response_code & 0x70) == 0x70; +} + +struct scsi_eh_save { + /* saved state */ + int result; + enum dma_data_direction data_direction; + unsigned underflow; + unsigned char cmd_len; +// unsigned char prot_op; + unsigned char cmnd[BLK_MAX_CDB]; + struct scsi_data_buffer sdb; +// struct request *next_rq; + /* new command support */ + unsigned char eh_cmnd[BLK_MAX_CDB]; +// struct scatterlist sense_sgl; +}; +const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, + int desc_type); +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/storage.h b/USDK/component/common/drivers/usb_class/host/storage/inc/storage.h new file mode 100644 index 0000000..ab1327d --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/storage.h @@ -0,0 +1,78 @@ +#ifndef __STORAGE_H +#define __STORAGE_H + +#include "us_os_wrap_via_osdep_api.h" +/* Storage subclass codes */ + +#define USB_SC_RBC 0x01 /* Typically, flash devices */ +#define USB_SC_8020 0x02 /* CD-ROM */ +#define USB_SC_QIC 0x03 /* QIC-157 Tapes */ +#define USB_SC_UFI 0x04 /* Floppy */ +#define USB_SC_8070 0x05 /* Removable media */ +#define USB_SC_SCSI 0x06 /* Transparent */ +#define USB_SC_LOCKABLE 0x07 /* Password-protected */ + +#define USB_SC_ISD200 0xf0 /* ISD200 ATA */ +#define USB_SC_CYP_ATACB 0xf1 /* Cypress ATACB */ +#define USB_SC_DEVICE 0xff /* Use device's value */ + +/* Storage protocol codes */ + +#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */ +#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */ +#define USB_PR_BULK 0x50 /* bulk only */ +#define USB_PR_UAS 0x62 /* USB Attached SCSI */ + +#define USB_PR_USBAT 0x80 /* SCM-ATAPI bridge */ +#define USB_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ +#define USB_PR_SDDR55 0x82 /* SDDR-55 (made up) */ +#define USB_PR_DPCM_USB 0xf0 /* Combination CB/SDDR09 */ +#define USB_PR_FREECOM 0xf1 /* Freecom */ +#define USB_PR_DATAFAB 0xf2 /* Datafab chipsets */ +#define USB_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */ +#define USB_PR_ALAUDA 0xf4 /* Alauda chipsets */ +#define USB_PR_KARMA 0xf5 /* Rio Karma */ + +#define USB_PR_DEVICE 0xff /* Use device's value */ + +/* +* Bulk only data structures +*/ + +/* command block wrapper */ +struct bulk_cb_wrap { + __le32 Signature; /* contains 'USBC', denote bulk_cb_wrap */ + __u32 Tag; /* unique per command id */ + __le32 DataTransferLength; /* size of data for transfer */ + __u8 Flags; /* data transfer direction */ + __u8 Lun; /* LUN normally 0, (which command block is sent) */ + __u8 Length; /* length of the CDB */ + __u8 CDB[16]; /* max command */ +}; + +#define US_BULK_CB_WRAP_LEN 31 +#define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */ +#define US_BULK_FLAG_IN (1 << 7) +#define US_BULK_FLAG_OUT 0 + +/* command status wrapper */ +struct bulk_cs_wrap { + __le32 Signature; /* should = 'USBS' */ + __u32 Tag; /* same as original command, echoed by the device as received */ + __le32 Residue; /* amount not transferred */ + __u8 Status; /* execute command status */ +}; + +#define US_BULK_CS_WRAP_LEN 13 +#define US_BULK_CS_SIGN 0x53425355 /* spells out 'USBS' */ +// execute command status +#define US_BULK_STAT_OK 0 +#define US_BULK_STAT_FAIL 1 +#define US_BULK_STAT_PHASE 2 + +/* bulk-only class specific requests */ +#define US_BULK_RESET_REQUEST 0xff +#define US_BULK_GET_MAX_LUN 0xfe + +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/transport.h b/USDK/component/common/drivers/usb_class/host/storage/inc/transport.h new file mode 100644 index 0000000..a91ab46 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/transport.h @@ -0,0 +1,102 @@ +/* Driver for USB Mass Storage compliant devices + * Transport Functions Header File + * + * Current development and maintenance by: + * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) + * + * This driver is based on the 'USB Mass Storage Class' document. This + * describes in detail the protocol used to communicate with such + * devices. Clearly, the designers had SCSI and ATAPI commands in + * mind when they created this document. The commands are all very + * similar to commands in the SCSI-II and ATAPI specifications. + * + * It is important to note that in a number of cases this class + * exhibits class-specific exemptions from the USB specification. + * Notably the usage of NAK, STALL and ACK differs from the norm, in + * that they are used to communicate wait, failed and OK on commands. + * + * Also, for certain devices, the interrupt endpoint is used to convey + * status of a command. + * + * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more + * information about this driver. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _US_TRANSPORT_H_ +#define _US_TRANSPORT_H_ +#if 0 +#include +#endif +/* + * usb_stor_bulk_transfer_xxx() return codes, in order of severity + */ + +#define USB_STOR_XFER_GOOD 0 /* good transfer */ +#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */ +#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ +#define USB_STOR_XFER_LONG 3 /* device tried to send too much */ +#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */ + +/* + * Transport return codes + */ + +#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */ +#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */ +#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ +#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ + +/* + * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED + * return codes. But now the transport and low-level transfer routines + * treat an abort as just another error (-ENOENT for a cancelled URB). + * It is up to the invoke_transport() function to test for aborts and + * distinguish them from genuine communication errors. + */ + +/* + * CBI accept device specific command + */ +#define US_CBI_ADSC 0 + +//extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*); +//extern int usb_stor_CB_reset(struct us_data*); +// +//extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*); +//extern int usb_stor_Bulk_max_lun(struct us_data*); +//extern int usb_stor_Bulk_reset(struct us_data*); +// +//extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*); +//extern void usb_stor_stop_transport(struct us_data*); + +//extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, +// u8 request, u8 requesttype, u16 value, u16 index, +// void *data, u16 size, int timeout); +//extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe); +// +//extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, +// u8 request, u8 requesttype, u16 value, u16 index, +// void *data, u16 size); +//extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, +// void *buf, unsigned int length, unsigned int *act_len); +//extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe, +// void *buf, unsigned int length, int use_sg, int *residual); +//extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, +// struct scsi_cmnd* srb); +// +//extern int usb_stor_port_reset(struct us_data *us); +#endif diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_devs.h b/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_devs.h new file mode 100644 index 0000000..913c72c --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_devs.h @@ -0,0 +1,2087 @@ +/* Driver for USB Mass Storage compliant devices + * Unusual Devices File + */ + +#define CONFIG_SUPPORT_OPTS_MS_INIT 0 +#define CONFIG_SUPPORT_SERRIA_MS_INIT 0 + +#if !defined(CONFIG_USB_STORAGE_SDDR09) && \ + !defined(CONFIG_USB_STORAGE_SDDR09_MODULE) +#define NO_SDDR09 +#endif + +/* patch submitted by Vivian Bregier + */ +UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, + "ATMEL", + "SND1 Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE), + +/* Reported by Rodolfo Quesada */ +UNUSUAL_DEV( 0x03ee, 0x6906, 0x0003, 0x0003, + "VIA Technologies Inc.", + "Mitsumi multi cardreader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, + "HP", + "CD-Writer+", + USB_SC_8070, USB_PR_CB, NULL, 0), + +/* Reported by Ben Efros */ +UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000, + "HP", + "Personal Media Drive", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE ), + +/* Reported by Grant Grundler + * HP r707 camera in "Disk" mode with 2.00.23 or 2.00.24 firmware. + */ +UNUSUAL_DEV( 0x03f0, 0x4002, 0x0001, 0x0001, + "HP", + "PhotoSmart R707", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), + +/* Reported by Sebastian Kapfer + * and Olaf Hering (different bcd's, same vendor/product) + * for USB floppies that need the SINGLE_LUN enforcement. + */ +UNUSUAL_DEV( 0x0409, 0x0040, 0x0000, 0x9999, + "NEC", + "NEC USB UF000x", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Patch submitted by Mihnea-Costin Grigore */ +UNUSUAL_DEV( 0x040d, 0x6205, 0x0003, 0x0003, + "VIA Technologies Inc.", + "USB 2.0 Card Reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Deduced by Jonathan Woithe + * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message + * always fails and confuses drive. + */ +UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, + "Buffalo", + "DUB-P40G HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Ernestas Vaiciukevicius */ +UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100, + "Samsung Info. Systems America, Inc.", + "MP3 Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Orgad Shaneh */ +UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100, + "Samsung", "MP3 Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Christian Leber */ +UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, + "TrekStor", + "i.Beat 115 2.0", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_NOT_LOCKABLE ), + +/* Reported by Stefan Werner */ +UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, + "TrekStor", + "i.Beat Joy 2.0", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Pete Zaitcev , bz#176584 */ +UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, + "GENERIC", "MP3 PLAYER", /* MyMusix PD-205 on the outside. */ + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Andrew Nayenko + * Updated for new firmware by Phillip Potter */ +UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0610, + "Nokia", + "Nokia 6288", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Mario Rettig */ +UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, + "Nokia", + "Nokia 3250", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by */ +UNUSUAL_DEV( 0x0421, 0x0433, 0x0100, 0x0100, + "Nokia", + "E70", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by Jon Hart */ +UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, + "Nokia", + "E60", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), + +/* Reported by Sumedha Swamy and + * Einar Th. Einarsson */ +UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, + "Nokia", + "N91", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by Jiri Slaby and + * Rene C. Castberg */ +UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100, + "Nokia", + "N80", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by Matthew Bloch */ +UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100, + "Nokia", + "E61", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by Bardur Arantsson */ +UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, + "Nokia", + "6131", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Manuel Osdoba */ +UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, + "Nokia", + "Nokia 6233", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Alex Corcoles */ +UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, + "Nokia", + "6234", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Daniele Forsi */ +UNUSUAL_DEV( 0x0421, 0x04b9, 0x0350, 0x0350, + "Nokia", + "5300", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Patch submitted by Victor A. Santos */ +UNUSUAL_DEV( 0x0421, 0x05af, 0x0742, 0x0742, + "Nokia", + "305", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + +/* Patch submitted by Mikhail Zolotaryov */ +UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, + "Nokia", + "502", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +#ifdef NO_SDDR09 +UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, + "Microtech", + "CameraMate", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN ), +#endif + +/* Patch submitted by Daniel Drake + * Device reports nonsense bInterfaceProtocol 6 when connected over USB2 */ +UNUSUAL_DEV( 0x0451, 0x5416, 0x0100, 0x0100, + "Neuros Audio", + "USB 2.0 HD 2.5", + USB_SC_DEVICE, USB_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), + +/* + * Pete Zaitcev , from Patrick C. F. Ernzer, bz#162559. + * The key does not actually break, but it returns zero sense which + * makes our SCSI stack to print confusing messages. + */ +UNUSUAL_DEV( 0x0457, 0x0150, 0x0100, 0x0100, + "USBest Technology", /* sold by Transcend */ + "USB Mass Storage Device", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + +/* +* Bohdan Linda +* 1GB USB sticks MyFlash High Speed. I have restricted +* the revision to my model only +*/ +UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100, + "USB 2.0", + "Flash Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE ), + +/* Reported by Tamas Kerecsen + * Obviously the PROM has not been customized by the VAR; + * the Vendor and Product string descriptors are: + * Generic Mass Storage (PROTOTYPE--Remember to change idVendor) + * Generic Manufacturer (PROTOTYPE--Remember to change idVendor) + */ +UNUSUAL_DEV( 0x045e, 0xffff, 0x0000, 0x0000, + "Mitac", + "GPS", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* + * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.) + * Reported by Pete Zaitcev + * This device chokes on both version of MODE SENSE which we have, so + * use_10_for_ms is not effective, and we use US_FL_NO_WP_DETECT. + */ +UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100, + "AMI", + "Virtual Floppy", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT), + +/* Patch submitted by Philipp Friedrich */ +UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, + "Kyocera", + "Finecam S3x", + USB_SC_8070, USB_PR_CB, NULL, US_FL_FIX_INQUIRY), + +/* Patch submitted by Philipp Friedrich */ +UNUSUAL_DEV( 0x0482, 0x0101, 0x0100, 0x0100, + "Kyocera", + "Finecam S4", + USB_SC_8070, USB_PR_CB, NULL, US_FL_FIX_INQUIRY), + +/* Patch submitted by Stephane Galles */ +UNUSUAL_DEV( 0x0482, 0x0103, 0x0100, 0x0100, + "Kyocera", + "Finecam S5", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), + +/* Patch submitted by Jens Taprogge */ +UNUSUAL_DEV( 0x0482, 0x0107, 0x0100, 0x0100, + "Kyocera", + "CONTAX SL300R T*", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE), + +/* Reported by Paul Stewart + * This entry is needed because the device reports Sub=ff */ +UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, + "Hitachi", + "DVD-CAM DZ-MV100A Camcorder", + USB_SC_SCSI, USB_PR_CB, NULL, US_FL_SINGLE_LUN), + +/* BENQ DC5330 + * Reported by Manuel Fombuena and + * Frank Copeland */ +UNUSUAL_DEV( 0x04a5, 0x3010, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "300_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Patch for Nikon coolpix 2000 + * Submitted by Fabien Cosse */ +UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, + "NIKON", + "NIKON DSC E2000", + USB_SC_DEVICE, USB_PR_DEVICE,NULL, + US_FL_NOT_LOCKABLE ), + +/* Reported by Doug Maxey (dwm@austin.ibm.com) */ +UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, + "IBM", + "IBM RSA2", + USB_SC_DEVICE, USB_PR_CB, NULL, + US_FL_MAX_SECTORS_MIN), + +/* Reported by Simon Levitt + * This entry needs Sub and Proto fields */ +UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, + "Epson", + "875DC Storage", + USB_SC_SCSI, USB_PR_CB, NULL, US_FL_FIX_INQUIRY), + +/* Reported by Khalid Aziz + * This entry is needed because the device reports Sub=ff */ +UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x0110, + "Epson", + "785EPX Storage", + USB_SC_SCSI, USB_PR_BULK, NULL, US_FL_SINGLE_LUN), + +/* Not sure who reported this originally but + * Pavel Machek reported that the extra US_FL_SINGLE_LUN + * flag be added */ +UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210, + "Fujifilm", + "FinePix 1400Zoom", + USB_SC_UFI, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN), + +/* Reported by Ondrej Zary + * The device reports one sector more and breaks when that sector is accessed + */ +UNUSUAL_DEV( 0x04ce, 0x0002, 0x026c, 0x026c, + "ScanLogic", + "SL11R-IDE", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Reported by Kriston Fincher + * Patch submitted by Sean Millichamp + * This is to support the Panasonic PalmCam PV-SD4090 + * This entry is needed because the device reports Sub=ff + */ +UNUSUAL_DEV( 0x04da, 0x0901, 0x0100, 0x0200, + "Panasonic", + "LS-120 Camera", + USB_SC_UFI, USB_PR_DEVICE, NULL, 0), + +/* From Yukihiro Nakai, via zaitcev@yahoo.com. + * This is needed for CB instead of CBI */ +UNUSUAL_DEV( 0x04da, 0x0d05, 0x0000, 0x0000, + "Sharp CE-CW05", + "CD-R/RW Drive", + USB_SC_8070, USB_PR_CB, NULL, 0), + +/* Reported by Adriaan Penning */ +UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999, + "Panasonic", + "DMC-LCx Camera", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), + +/* Reported by Simeon Simeonov */ +UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999, + "LEICA", + "D-LUX Camera", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), + +/* Most of the following entries were developed with the help of + * Shuttle/SCM directly. + */ +UNUSUAL_DEV( 0x04e6, 0x0001, 0x0200, 0x0200, + "Matshita", + "LS-120", + USB_SC_8020, USB_PR_CB, NULL, 0), + +UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, + "Shuttle", + "eUSCSI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +#ifdef NO_SDDR09 +UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, + "SCM Microsystems", + "eUSB CompactFlash Adapter", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN), +#endif + +/* Reported by Markus Demleitner */ +UNUSUAL_DEV( 0x04e6, 0x0006, 0x0100, 0x0100, + "SCM Microsystems Inc.", + "eUSB MMC Adapter", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN), + +/* Reported by Daniel Nouri */ +UNUSUAL_DEV( 0x04e6, 0x0006, 0x0205, 0x0205, + "Shuttle", + "eUSB MMC Adapter", + USB_SC_SCSI, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN), + +UNUSUAL_DEV( 0x04e6, 0x0007, 0x0100, 0x0200, + "Sony", + "Hifd", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN), + +UNUSUAL_DEV( 0x04e6, 0x0009, 0x0200, 0x0200, + "Shuttle", + "eUSB ATA/ATAPI Adapter", + USB_SC_8020, USB_PR_CB, NULL, 0), + +UNUSUAL_DEV( 0x04e6, 0x000a, 0x0200, 0x0200, + "Shuttle", + "eUSB CompactFlash Adapter", + USB_SC_8020, USB_PR_CB, NULL, 0), + +UNUSUAL_DEV( 0x04e6, 0x000B, 0x0100, 0x0100, + "Shuttle", + "eUSCSI Bridge", + USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +UNUSUAL_DEV( 0x04e6, 0x000C, 0x0100, 0x0100, + "Shuttle", + "eUSCSI Bridge", + USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, + "Shuttle", + "CD-RW Device", + USB_SC_8020, USB_PR_CB, NULL, 0), + +/* Reported by Dmitry Khlystov */ +UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, + "Samsung", + "YP-U3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + +/* Reported by Vitaly Kuznetsov */ +UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, + "Samsung", + "YP-CP3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), + +/* Added by Dmitry Artamonow */ +UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999, + "Samsung", + "YP-Z3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + +/* Entry and supporting patch by Theodore Kilgore . + * Device uses standards-violating 32-byte Bulk Command Block Wrappers and + * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. + */ +UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, + "Kobian Mercury", + "Binocam DCB-132", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK32), + +/* Reported by Bob Sass -- only rev 1.33 tested */ +UNUSUAL_DEV( 0x050d, 0x0115, 0x0133, 0x0133, + "Belkin", + "USB SCSI Adaptor", + USB_SC_SCSI, USB_PR_BULK, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +/* Iomega Clik! Drive + * Reported by David Chatenay + * The reason this is needed is not fully known. + */ +UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, + "Iomega", + "USB Clik! 40", + USB_SC_8070, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Added by Alan Stern */ +COMPLIANT_DEV(0x0525, 0xa4a5, 0x0000, 0x9999, + "Linux", + "File-backed Storage Gadget", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_CAPACITY_OK ), + +/* Yakumo Mega Image 37 + * Submitted by Stephan Fuhrmann */ +UNUSUAL_DEV( 0x052b, 0x1801, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "300_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Another Yakumo camera. + * Reported by Michele Alzetta */ +UNUSUAL_DEV( 0x052b, 0x1804, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "300_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Iacopo Spalletti */ +UNUSUAL_DEV( 0x052b, 0x1807, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "300_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Yakumo Mega Image 47 + * Reported by Bjoern Paetzel */ +UNUSUAL_DEV( 0x052b, 0x1905, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "400_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Paul Ortyl + * Note that it's similar to the device above, only different prodID */ +UNUSUAL_DEV( 0x052b, 0x1911, 0x0100, 0x0100, + "Tekom Technologies, Inc", + "400_CAMERA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, + "Sony", + "DSC-S30/S70/S75/505V/F505/F707/F717/P8", + USB_SC_SCSI, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ), + +/* Submitted by Lars Jacob + * This entry is needed because the device reports Sub=ff */ +UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0610, + "Sony", + "DSC-T1/T5/H5", + USB_SC_8070, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + + +/* Reported by wim@geeks.nl */ +UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100, + "Sony", + "Memorystick NW-MS7", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Olaf Hering, SuSE Bugzilla #49049 */ +UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, + "Sony", + "USB Floppy Drive", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +UNUSUAL_DEV( 0x054c, 0x002d, 0x0100, 0x0100, + "Sony", + "Memorystick MSAC-US1", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Klaus Mueller */ +UNUSUAL_DEV( 0x054c, 0x002e, 0x0106, 0x0310, + "Sony", + "Handycam", + USB_SC_SCSI, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Rajesh Kumble Nayak */ +UNUSUAL_DEV( 0x054c, 0x002e, 0x0500, 0x0500, + "Sony", + "Handycam HC-85", + USB_SC_UFI, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +UNUSUAL_DEV( 0x054c, 0x0032, 0x0000, 0x9999, + "Sony", + "Memorystick MSC-U01N", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Michal Mlotek */ +UNUSUAL_DEV( 0x054c, 0x0058, 0x0000, 0x9999, + "Sony", + "PEG N760c Memorystick", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +UNUSUAL_DEV( 0x054c, 0x0069, 0x0000, 0x9999, + "Sony", + "Memorystick MSC-U03", + USB_SC_UFI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Nathan Babb */ +UNUSUAL_DEV( 0x054c, 0x006d, 0x0000, 0x9999, + "Sony", + "PEG Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Frank Engel */ +UNUSUAL_DEV( 0x054c, 0x0099, 0x0000, 0x9999, + "Sony", + "PEG Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Mike Alborn */ +UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x9999, + "Sony", + "PEG Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Ren Bigcren */ +UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, + "Sony Corp.", + "MicroVault Flash Drive", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_CAPACITY_16 ), + +/* floppy reports multiple luns */ +UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, + "SAMSUNG", + "SFD-321U [FW 0C]", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* We keep this entry to force the transport; firmware 3.00 and later is ok. */ +UNUSUAL_DEV( 0x057b, 0x0000, 0x0000, 0x0299, + "Y-E Data", + "Flashbuster-U", + USB_SC_DEVICE, USB_PR_CB, NULL, + US_FL_SINGLE_LUN), + +/* Reported by Johann Cardon + * This entry is needed only because the device reports + * bInterfaceClass = 0xff (vendor-specific) + */ +UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, + "Y-E Data", + "Silicon Media R/W", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0), + +/* Reported by RTE */ +UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141, + "JetFlash", + "TS1GJF2A/120", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Fabrizio Fellini */ +UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, + "Fujifilm", + "Digital Camera EX-20 DSC", + USB_SC_8070, USB_PR_DEVICE, NULL, 0 ), + +/* Reported by Andre Welter + * This antique device predates the release of the Bulk-only Transport + * spec, and if it gets a Get-Max-LUN then it requires the host to do a + * Clear-Halt on the bulk endpoints. The SINGLE_LUN flag will prevent + * us from sending the request. + */ +UNUSUAL_DEV( 0x059b, 0x0001, 0x0100, 0x0100, + "Iomega", + "ZIP 100", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Reported by */ +UNUSUAL_DEV( 0x059f, 0x0643, 0x0000, 0x0000, + "LaCie", + "DVD+-RW", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_GO_SLOW ), + +/* Submitted by Joel Bourquard + * Some versions of this device need the SubClass and Protocol overrides + * while others don't. + */ +UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, + "In-System", + "PyroGate External CD-ROM Enclosure (FCD-523)", + USB_SC_SCSI, USB_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), + +/* Submitted by Sven Anderson + * There are at least four ProductIDs used for iPods, so I added 0x1202 and + * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears + * to change with firmware updates, I changed the range to maximum for all + * iPod entries. + */ +UNUSUAL_DEV( 0x05ac, 0x1202, 0x0000, 0x9999, + "Apple", + "iPod", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Avi Kivity */ +UNUSUAL_DEV( 0x05ac, 0x1203, 0x0000, 0x9999, + "Apple", + "iPod", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +UNUSUAL_DEV( 0x05ac, 0x1204, 0x0000, 0x9999, + "Apple", + "iPod", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), + +UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, + "Apple", + "iPod", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* + * Reported by Tyson Vinson + * This particular productId is the iPod Nano + */ +UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999, + "Apple", + "iPod", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Dan Williams + * Option N.V. mobile broadband modems + * Ignore driver CD mode and force into modem mode by default. + */ + +/* Globetrotter HSDPA; mass storage shows up as Qualcomm for vendor */ +#if CONFIG_SUPPORT_OPTS_MS_INIT +UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999, + "Option N.V.", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init, + 0), +#endif +/* Reported by Blake Matheny */ +UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, + "Lexar", + "USB CF Reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* The following two entries are for a Genesys USB to IDE + * converter chip, but it changes its ProductId depending + * on whether or not a disk or an optical device is enclosed + * They were originally reported by Alexander Oltu + * and Peter Marks + * respectively. + * + * US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz + * as these flags were made and hard-coded + * special-cases were pulled from scsiglue.c. + */ +UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, + "Genesys Logic", + "USB to IDE Optical", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), + +UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, + "Genesys Logic", + "USB to IDE Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), + +/* Reported by Ben Efros */ +UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, + "Genesys Logic", + "USB to SATA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE ), + +/* Reported by Hanno Boeck + * Taken from the Lycoris Kernel */ +UNUSUAL_DEV( 0x0636, 0x0003, 0x0000, 0x9999, + "Vivitar", + "Vivicam 35Xx", + USB_SC_SCSI, USB_PR_BULK, NULL, + US_FL_FIX_INQUIRY ), + +UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, + "TEAC", + "Floppy Drive", + USB_SC_UFI, USB_PR_CB, NULL, 0 ), + +/* Reported by Darsen Lu */ +UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, + "SigmaTel", + "USBMSC Audio Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Daniel Kukula */ +UNUSUAL_DEV( 0x067b, 0x1063, 0x0100, 0x0100, + "Prolific Technology, Inc.", + "Prolific Storage Gadget", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), + +/* Reported by Rogerio Brito */ +UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001, + "Prolific Technology, Inc.", + "Mass Storage Device", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE ), + +/* Reported by Richard -=[]=- */ +/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by + * Thomas Bartosik */ +UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, + "Prolific Technology Inc.", + "Mass Storage Device", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_GO_SLOW ), + +/* Reported by Alex Butcher */ +UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0101, + "Prolific Technology Inc.", + "ATAPI-6 Bridge Controller", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_GO_SLOW ), + +/* Submitted by Benny Sjostrand */ +UNUSUAL_DEV( 0x0686, 0x4011, 0x0001, 0x0001, + "Minolta", + "Dimage F300", + USB_SC_SCSI, USB_PR_BULK, NULL, 0 ), + +/* Reported by Miguel A. Fosas */ +UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001, + "Minolta", + "DIMAGE E223", + USB_SC_SCSI, USB_PR_DEVICE, NULL, 0 ), + +UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100, + "Hagiwara", + "Flashgate", + USB_SC_SCSI, USB_PR_BULK, NULL, 0 ), + +/* Reported by David Hamilton */ +UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, + "Thomson Multimedia Inc.", + "RCA RD1080 MP3 Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Adrian Pilchowiec */ +UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, + "RockChip", + "MP3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64 | + US_FL_NO_READ_CAPACITY_16), + +/* Reported by Jean-Baptiste Onofre + * Support the following product : + * "Dane-Elec MediaTouch" + */ +UNUSUAL_DEV( 0x071b, 0x32bb, 0x0000, 0x0000, + "RockChip", + "MTP", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), + +/* Reported by Massimiliano Ghilardi + * This USB MP3/AVI player device fails and disconnects if more than 128 + * sectors (64kB) are read/written in a single command, and may be present + * at least in the following products: + * "Magnex Digital Video Panel DVP 1800" + * "MP4 AIGO 4GB SLOT SD" + * "Teclast TL-C260 MP3" + * "i.Meizu PMP MP3/MP4" + * "Speed MV8 MP4 Audio Player" + */ +UNUSUAL_DEV( 0x071b, 0x3203, 0x0100, 0x0100, + "RockChip", + "ROCK MP3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + +/* Reported by Olivier Blondeau */ +UNUSUAL_DEV( 0x0727, 0x0306, 0x0100, 0x0100, + "ATMEL", + "SND1 Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE), + +/* Submitted by Roman Hodek */ +UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, + "Sandisk", + "ImageMate SDDR-05a", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN ), + +UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, + "SanDisk Corporation", + "ImageMate CompactFlash USB", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, + "Sandisk", + "ImageMate SDDR-12", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN ), + +/* Reported by Eero Volotinen */ +UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, + "Freecom Technologies", + "FHD-Classic", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133, + "Microtech", + "USB-SCSI-DB25", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, + "Microtech", + "USB-SCSI-HD50", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_euscsi_init, + US_FL_SCM_MULT_TARG ), + +#ifdef NO_SDDR09 +UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, + "Microtech", + "CameraMate", + USB_SC_SCSI, USB_PR_CB, NULL, + US_FL_SINGLE_LUN ), +#endif + +/* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 + * Only revision 1.13 tested (same for all of the above devices, + * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. + * Submitted by Marek Michalkiewicz . + * See also http://martin.wilck.bei.t-online.de/#kecf . + */ +UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, + "Datafab", + "KECF-USB", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), + +/* Reported by Rauch Wolke + * and augmented by binbin (Bugzilla #12882) + */ +UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, + "Simple Tech/Datafab", + "CF+SM Reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_MAX_SECTORS_64 ), + +/* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant + * to the USB storage specification in two ways: + * - They tell us they are using transport protocol CBI. In reality they + * are using transport protocol CB. + * - They don't like the INQUIRY command. So we must handle this command + * of the SCSI layer ourselves. + * - Some cameras with idProduct=0x1001 and bcdDevice=0x1000 have + * bInterfaceProtocol=0x00 (USB_PR_CBI) while others have 0x01 (USB_PR_CB). + * So don't remove the USB_PR_CB override! + * - Cameras with bcdDevice=0x9009 require the USB_SC_8070 override. + */ +UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, + "Casio", + "QV DigitalCamera", + USB_SC_8070, USB_PR_CB, NULL, + US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), + +/* Submitted by Oleksandr Chumachenko */ +UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, + "Casio", + "EX-N1 DigitalCamera", + USB_SC_8070, USB_PR_DEVICE, NULL, 0), + +/* Submitted by Hartmut Wahl */ +UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, + "Samsung", + "Digimax 410", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY), + +/* Reported by Luciano Rocha */ +UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001, + "Argosy", + "Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Reported and patched by Nguyen Anh Quynh */ +UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001, + "Argosy", + "Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Reported by Martijn Hijdra */ +UNUSUAL_DEV( 0x0840, 0x0085, 0x0001, 0x0001, + "Argosy", + "Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Entry and supporting patch by Theodore Kilgore . + * Flag will support Bulk devices which use a standards-violating 32-byte + * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with + * Grandtech GT892x chip, which request "Proprietary SCSI Bulk" support. + */ + +UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, + "Grandtech", + "DC2MEGA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK32), + +/* Reported by + * The device reports a vendor-specific device class, requiring an + * explicit vendor/product match. + */ +UNUSUAL_DEV( 0x0851, 0x1542, 0x0002, 0x0002, + "MagicPixel", + "FW_Omega2", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0), + +/* Andrew Lunn + * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL + * on LUN 4. + * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera" +*/ +UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, + "PanDigital", + "Photo Frame", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE), + +/* Submitted by Jan De Luyck */ +UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, + "CITIZEN", + "X1DE-USB", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN), + +/* Submitted by Dylan Taft + * US_FL_IGNORE_RESIDUE Needed + */ +UNUSUAL_DEV( 0x08ca, 0x3103, 0x0100, 0x0100, + "AIPTEK", + "Aiptek USB Keychain MP3 Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE), + +/* Entry needed for flags. Moreover, all devices with this ID use + * bulk-only transport, but _some_ falsely report Control/Bulk instead. + * One example is "Trumpion Digital Research MYMP3". + * Submitted by Bjoern Brill + */ +UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, + "Trumpion", + "t33520 USB Flash Card Controller", + USB_SC_DEVICE, USB_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), + +/* Reported by Filippo Bardelli + * The device reports a subclass of RBC, which is wrong. + */ +UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100, + "Trumpion Microelectronics, Inc.", + "33520 USB Digital Voice Recorder", + USB_SC_UFI, USB_PR_DEVICE, NULL, + 0), + +/* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ +UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, + "Trumpion", + "MP3 player", + USB_SC_RBC, USB_PR_BULK, NULL, + 0 ), + +/* aeb */ +UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + "Feiya", + "5-in-1 Card Reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Paul Hartman + * This card reader returns "Illegal Request, Logical Block Address + * Out of Range" for the first READ(10) after a new card is inserted. + */ +UNUSUAL_DEV( 0x090c, 0x6000, 0x0100, 0x0100, + "Feiya", + "SD/SDHC Card Reader", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_INITIAL_READ10 ), + +/* This Pentax still camera is not conformant + * to the USB storage specification: - + * - It does not like the INQUIRY command. So we must handle this command + * of the SCSI layer ourselves. + * Tested on Rev. 10.00 (0x1000) + * Submitted by James Courtier-Dutton + */ +UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000, + "Pentax", + "Optio 2/3/400", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* These are virtual windows driver CDs, which the zd1211rw driver + * automatically converts into WLAN devices. */ +UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, + "ZyXEL", + "G-220F USB-WLAN Install", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + +UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, + "SiteCom", + "WL-117 USB-WLAN Install", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE ), + +/* Reported by Dan Williams + * Option N.V. mobile broadband modems + * Ignore driver CD mode and force into modem mode by default. + */ +#if CONFIG_SUPPORT_OPTS_MS_INIT +/* iCON 225 */ +UNUSUAL_DEV( 0x0af0, 0x6971, 0x0000, 0x9999, + "Option N.V.", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init, + 0), +#endif + +/* Reported by F. Aben + * This device (wrongly) has a vendor-specific device descriptor. + * The entry is needed so usb-storage can bind to it's mass-storage + * interface as an interface driver */ +UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, + "Option", + "GI 0401 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +/* Reported by Jan Dumon + * These devices (wrongly) have a vendor-specific device descriptor. + * These entries are needed so usb-storage can bind to their mass-storage + * interface as an interface driver */ +UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, + "Option", + "GI 0431 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7701, 0x0000, 0x0000, + "Option", + "GI 0451 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7706, 0x0000, 0x0000, + "Option", + "GI 0451 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7901, 0x0000, 0x0000, + "Option", + "GI 0452 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7A01, 0x0000, 0x0000, + "Option", + "GI 0461 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x7A05, 0x0000, 0x0000, + "Option", + "GI 0461 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8300, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8302, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0000, + "Option", + "GI 033x SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000, + "Option", + "GI 070x SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd057, 0x0000, 0x0000, + "Option", + "GI 1505 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd058, 0x0000, 0x0000, + "Option", + "GI 1509 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd157, 0x0000, 0x0000, + "Option", + "GI 1515 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd257, 0x0000, 0x0000, + "Option", + "GI 1215 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +UNUSUAL_DEV( 0x0af0, 0xd357, 0x0000, 0x0000, + "Option", + "GI 1505 SD-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0 ), + +/* Reported by Namjae Jeon */ +UNUSUAL_DEV(0x0bc2, 0x2300, 0x0000, 0x9999, + "Seagate", + "Portable HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_WRITE_CACHE), + +/* Reported by Ben Efros */ +UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, + "Seagate", + "FreeAgent Pro", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE ), + +UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, + "Maxtor", + "USB to SATA", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE), + +/* + * Pete Zaitcev , bz#164688. + * The device blatantly ignores LUN and returns 1 in GetMaxLUN. + */ +UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100, + "Unknown", + "Unknown", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SINGLE_LUN ), + +/* Submitted by Joris Struyve */ +UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, + "Medion", + "MD 7425", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY), + +/* + * Entry for Jenoptik JD 5200z3 + * + * email: car.busse@gmx.de + */ +UNUSUAL_DEV( 0x0d96, 0x5200, 0x0001, 0x0200, + "Jenoptik", + "JD 5200 z3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), + +/* Reported by Jason Johnston */ +UNUSUAL_DEV( 0x0dc4, 0x0073, 0x0000, 0x0000, + "Macpower Technology Co.LTD.", + "USB 2.0 3.5\" DEVICE", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* Reported by Lubomir Blaha + * I _REALLY_ don't know what 3rd, 4th number and all defines mean, but this + * works for me. Can anybody correct these values? (I able to test corrected + * version.) + */ +UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff, + "Netac", + "USB-CF-Card", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Reported by Edward Chapman (taken from linux-usb mailing list) + Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */ +UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999, + "Netac", + "USB Flash Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + + +/* Patch by Stephan Walter + * I don't know why, but it works... */ +UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012, + "WINWARD", + "Music Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Ian McConnell */ +UNUSUAL_DEV( 0x0dda, 0x0301, 0x0012, 0x0012, + "PNP_MP3", + "PNP_MP3 PLAYER", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Jim McCloskey */ +UNUSUAL_DEV( 0x0e21, 0x0520, 0x0100, 0x0100, + "Cowon Systems", + "iAUDIO M5", + USB_SC_DEVICE, USB_PR_BULK, NULL, + US_FL_NEED_OVERRIDE ), + +/* Submitted by Antoine Mairesse */ +UNUSUAL_DEV( 0x0ed1, 0x6660, 0x0100, 0x0300, + "USB", + "Solid state disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), + +/* Submitted by Daniel Drake + * Reported by dayul on the Gentoo Forums */ +UNUSUAL_DEV( 0x0ea0, 0x2168, 0x0110, 0x0110, + "Ours Technology", + "Flash Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Rastislav Stanik */ +UNUSUAL_DEV( 0x0ea0, 0x6828, 0x0110, 0x0110, + "USB", + "Flash Disk", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Benjamin Schiller + * It is also sold by Easylite as DJ 20 */ +UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103, + "Typhoon", + "My DJ 1820", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), + +/* Patch by Leonid Petrov mail at lpetrov.net + * Reported by Robert Spitzenpfeil + * http://www.qbik.ch/usb/devices/showdev.php?id=1705 + * Updated to 103 device by MJ Ray mjr at phonecoop.coop + */ +UNUSUAL_DEV( 0x0f19, 0x0103, 0x0100, 0x0100, + "Oracom Co., Ltd", + "ORC-200M", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* David Kuehling : + * for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI + * errors when trying to write. + */ +UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, + "C-MEX", + "A-VOX", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Submitted by Nick Holloway */ +UNUSUAL_DEV( 0x0f88, 0x042e, 0x0100, 0x0100, + "VTech", + "Kidizoom", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Reported by Moritz Moeller-Herrmann */ +UNUSUAL_DEV( 0x0fca, 0x8004, 0x0201, 0x0201, + "Research In Motion", + "BlackBerry Bold 9000", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Michael Stattmann */ +UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, + "Sony Ericsson", + "V800-Vodafone 802", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT ), + +/* Reported by The Solutor */ +UNUSUAL_DEV( 0x0fce, 0xd0e1, 0x0000, 0x0000, + "Sony Ericsson", + "MD400", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_DEVICE), + +/* Reported by Jan Mate + * and by Soeren Sonnenburg */ +UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, + "Sony Ericsson", + "P990i", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), + +/* Reported by Emmanuel Vasilakis */ +UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, + "Sony Ericsson", + "M600i", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), + +/* Reported by Ricardo Barberis */ +UNUSUAL_DEV( 0x0fce, 0xe092, 0x0000, 0x0000, + "Sony Ericsson", + "P1i", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Kevin Cernekee + * Tested on hardware version 1.10. + * Entry is needed only for the initializer function override. + * Devices with bcd > 110 seem to not need it while those + * with bcd < 110 appear to need it. + */ +UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, + "Desknote", + "UCR-61S2B", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_ucr61s2b_init, + 0 ), + +UNUSUAL_DEV( 0x1058, 0x0704, 0x0000, 0x9999, + "Western Digital", + "External HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_SANE_SENSE), + +/* Reported by Namjae Jeon */ +UNUSUAL_DEV(0x1058, 0x070a, 0x0000, 0x9999, + "Western Digital", + "My Passport HDD", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_WRITE_CACHE), + +/* Reported by Fabio Venturi + * The device reports a vendor-specific bDeviceClass. + */ +UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, + "Actions Semiconductor", + "Mtp device", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + 0), + +/* Reported by Pascal Terjan + * Ignore driver CD mode and force into modem mode by default. + */ +#if CONFIG_SUPPORT_OPTS_MS_INIT +UNUSUAL_DEV( 0x1186, 0x3e04, 0x0000, 0x0000, + "D-Link", + "USB Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, option_ms_init, US_FL_IGNORE_DEVICE), +#endif +/* Reported by Kevin Lloyd + * Entry is needed for the initializer function override, + * which instructs the device to load as a modem + * device. + */ +#if CONFIG_SUPPORT_SERRIA_MS_INIT +UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, + "Sierra Wireless", + "USB MMC Storage", + USB_SC_DEVICE, USB_PR_DEVICE, sierra_ms_init, + 0), +#endif +/* Reported by Jaco Kroon + * The usb-storage module found on the Digitech GNX4 (and supposedly other + * devices) misbehaves and causes a bunch of invalid I/O errors. + */ +UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, + "Digitech HMG", + "DigiTech Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by fangxiaozhi + * This brings the HUAWEI data card devices into multi-port mode + */ +UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), + +/* Reported by Vilius Bilinkevicius */ +UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, + "SWISSBIT", + "Black Silver", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Qinglin Ye */ +UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, + "Kingston", + "DT 101 G2", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK_IGNORE_TAG ), + +/* Reported by Francesco Foresti */ +UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, + "Super Top", + "IDE DEVICE", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Michael Büsch */ +UNUSUAL_DEV( 0x152d, 0x0567, 0x0114, 0x0114, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BROKEN_FUA ), + +/* Reported by Alexandre Oliva + * JMicron responds to USN and several other SCSI ioctls with a + * residue that causes subsequent I/O requests to fail. */ +UNUSUAL_DEV( 0x152d, 0x2329, 0x0100, 0x0100, + "JMicron", + "USB to ATA/ATAPI Bridge", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), + +/* Reported by Robert Schedel + * Note: this is a 'super top' device like the above 14cd/6600 device */ +UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, + "Teac", + "HD-35PUK-B", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Oliver Neukum */ +UNUSUAL_DEV( 0x174c, 0x55aa, 0x0100, 0x0100, + "ASMedia", + "AS2105", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NEEDS_CAP16), + +/* Reported by Jesse Feddema */ +UNUSUAL_DEV( 0x177f, 0x0400, 0x0000, 0x0000, + "Yarvik", + "PMP400", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), + +/* Reported by Hans de Goede + * These Appotech controllers are found in Picture Frames, they provide a + * (buggy) emulation of a cdrom drive which contains the windows software + * Uploading of pictures happens over the corresponding /dev/sg device. */ +UNUSUAL_DEV( 0x1908, 0x1315, 0x0000, 0x0000, + "BUILDWIN", + "Photo Frame", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), +UNUSUAL_DEV( 0x1908, 0x1320, 0x0000, 0x0000, + "BUILDWIN", + "Photo Frame", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BAD_SENSE ), +UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, + "BUILDWIN", + "Photo Frame", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_DISC_INFO ), + +/* Reported by Sven Geggus + * This encrypted pen drive returns bogus data for the initial READ(10). + */ +UNUSUAL_DEV( 0x1b1c, 0x1ab5, 0x0200, 0x0200, + "Corsair", + "Padlock v2", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_INITIAL_READ10 ), + +/* Patch by Richard Schütz + * This external hard drive enclosure uses a JMicron chip which + * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ +UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, + "TrekStor GmbH & Co. KG", + "DataStation maxi g.u", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), + +/* Reported by Jasper Mackenzie */ +UNUSUAL_DEV( 0x1e74, 0x4621, 0x0000, 0x0000, + "Coby Electronics", + "MP3 Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK_IGNORE_TAG | US_FL_MAX_SECTORS_64 ), + +UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, + "ST", + "2A", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + +/* patch submitted by Davide Perini + * and Renato Perini + */ +UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001, + "Motorola", + "RAZR V3x", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), + +/* + * Patch by Constantin Baranov + * Report by Andreas Koenecke. + * Motorola ROKR Z6. + */ +UNUSUAL_DEV( 0x22b8, 0x6426, 0x0101, 0x0101, + "Motorola", + "MSnc.", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY | US_FL_BULK_IGNORE_TAG), + +/* Reported by Radovan Garabik */ +UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, + "MPIO", + "HS200", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_GO_SLOW ), + +/* Reported by Frederic Marchal + * Mio Moov 330 + */ +UNUSUAL_DEV( 0x3340, 0xffff, 0x0000, 0x0000, + "Mitac", + "Mio DigiWalker USB Sync", + USB_SC_DEVICE,USB_PR_DEVICE,NULL, + US_FL_MAX_SECTORS_64 ), + +/* Reported by Andrey Rahmatullin */ +UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100, + "iRiver", + "MP3 T10", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + +/* Reported by Sergey Pinaev */ +UNUSUAL_DEV( 0x4102, 0x1059, 0x0000, 0x0000, + "iRiver", + "P7K", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64 ), + +/* + * David Härdeman + * The key makes the SCSI stack print confusing (but harmless) messages + */ +UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, + "Iomega", + "Micro Mini 1GB", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + +/* + * Nick Bowler + * SCSI stack spams (otherwise harmless) error messages. + */ +UNUSUAL_DEV( 0xc251, 0x4003, 0x0100, 0x0100, + "Keil Software, Inc.", + "V2M MotherBoard", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE), + +/* Reported by Andrew Simmons */ +UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, + "DataStor", + "USB4500 FW1.04", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_CAPACITY_HEURISTICS), + +/* Reported by Alessio Treglia */ +UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001, + "TGE", + "Digital MP3 Audio Player", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + +#if 0 +/* Unusual uas devices */ +#if IS_ENABLED(CONFIG_USB_UAS) +#include "unusual_uas.h" +#endif +#endif +/* Control/Bulk transport for all SubClass values */ +USUAL_DEV(USB_SC_RBC, USB_PR_CB), +USUAL_DEV(USB_SC_8020, USB_PR_CB), +USUAL_DEV(USB_SC_QIC, USB_PR_CB), +USUAL_DEV(USB_SC_UFI, USB_PR_CB), +USUAL_DEV(USB_SC_8070, USB_PR_CB), +USUAL_DEV(USB_SC_SCSI, USB_PR_CB), + +/* Control/Bulk/Interrupt transport for all SubClass values */ +USUAL_DEV(USB_SC_RBC, USB_PR_CBI), +USUAL_DEV(USB_SC_8020, USB_PR_CBI), +USUAL_DEV(USB_SC_QIC, USB_PR_CBI), +USUAL_DEV(USB_SC_UFI, USB_PR_CBI), +USUAL_DEV(USB_SC_8070, USB_PR_CBI), +USUAL_DEV(USB_SC_SCSI, USB_PR_CBI), + +/* Bulk-only transport for all SubClass values */ +USUAL_DEV(USB_SC_RBC, USB_PR_BULK), +USUAL_DEV(USB_SC_8020, USB_PR_BULK), +USUAL_DEV(USB_SC_QIC, USB_PR_BULK), +USUAL_DEV(USB_SC_UFI, USB_PR_BULK), +USUAL_DEV(USB_SC_8070, USB_PR_BULK), +USUAL_DEV(USB_SC_SCSI, USB_PR_BULK), + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_usbat.h b/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_usbat.h new file mode 100644 index 0000000..fe563d0 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/unusual_usbat.h @@ -0,0 +1,32 @@ +#ifndef __UNUSUAL_USBAT_H +#define __UNUSUAL_USBAT_H + +#if defined(CONFIG_USB_STORAGE_USBAT) || \ + defined(CONFIG_USB_STORAGE_USBAT_MODULE) + +UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, + "HP", + "CD-Writer+ 8200e", + USB_SC_8070, USB_PR_USBAT, init_usbat_cd, 0), + +UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, + "HP", + "CD-Writer+ CD-4e", + USB_SC_8070, USB_PR_USBAT, init_usbat_cd, 0), + +UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, + "Shuttle/SCM", + "USBAT-02", + USB_SC_SCSI, USB_PR_USBAT, init_usbat_flash, + US_FL_SINGLE_LUN), + +UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, + "Sandisk", + "ImageMate SDDR-05b", + USB_SC_SCSI, USB_PR_USBAT, init_usbat_flash, + US_FL_SINGLE_LUN), + +#endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */ + +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_debug.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_debug.h new file mode 100644 index 0000000..1804b86 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_debug.h @@ -0,0 +1,26 @@ +#ifndef _US_DEBUG_H_ +#define _US_DEBUG_H_ + +#include "diag.h" + + +#define US_DEBUG 0 +#define US_DRIVER "US_DRIVER" + +#if US_DEBUG +#define US_INFO(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER, __FUNCTION__, ## args) +#define US_ERR(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args) +#define US_WARN(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args) +#define FUN_ENTER DBG_8195A("\n\r[%s]%s ==>\n", US_DRIVER,__FUNCTION__) +#define FUN_EXIT DBG_8195A("\n\r[%s]%s <==\n", US_DRIVER,__FUNCTION__) +#define FUN_TRACE DBG_8195A("\n\r[%s]%s:%d \n", US_DRIVER,__FUNCTION__, __LINE__) +#else +#define US_INFO(fmt, args...) +#define US_ERR(fmt, args...) DBG_8195A("\n\r[%s]%s: " fmt, US_DRIVER,__FUNCTION__, ## args) +#define US_WARN(fmt, args...) +#define FUN_ENTER +#define FUN_EXIT +#define FUN_TRACE +#endif + +#endif /* _US_DEBUG_H_ */ diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_initializers.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_initializers.h new file mode 100644 index 0000000..484866a --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_initializers.h @@ -0,0 +1,14 @@ +#include "usb.h" +#include "transport.h" + +/* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target + * mode */ +int usb_stor_euscsi_init(struct us_data *us); + +/* This function is required to activate all four slots on the UCR-61S2B + * flash reader */ +int usb_stor_ucr61s2b_init(struct us_data *us); + +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us); + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_intf.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_intf.h new file mode 100644 index 0000000..aad1338 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_intf.h @@ -0,0 +1,34 @@ +#ifndef __US_INTF_H_ +#define __US_INTF_H_ + +#include "basic_types.h" + +typedef enum +{ + MSC_OK = 0, + MSC_NOT_READY, + MSC_W_PROTECT, + MSC_ERROR, +}MSC_RESULT; + +extern MSC_RESULT us_init(void); +extern MSC_RESULT us_isready (void); + +extern MSC_RESULT us_getStatus(void); +extern MSC_RESULT us_getmaxlun (u8* lun_num); +extern MSC_RESULT us_unitisready (u8 lun); + +extern MSC_RESULT us_inquiry (u8 *pbuf); + +extern MSC_RESULT us_getcap(u32 *last_blk_addr, u32 *block_size); + +extern MSC_RESULT us_read_blocks( u8 *pbuf, u32 sector, u32 count); + +extern MSC_RESULT us_write_blocks( const u8 *pbuf, u32 sector, u32 count); + + +// indicate usb storage driver status +extern bool USB_STORAGE_READY; + +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_os_wrap_via_osdep_api.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_os_wrap_via_osdep_api.h new file mode 100644 index 0000000..a62f865 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_os_wrap_via_osdep_api.h @@ -0,0 +1,313 @@ +/* + * umsc_os_wrap_via_osdep_api.h + * + * Created on: Sep 5, 2014 + * Author: jimmysqf + */ + +#ifndef US_OS_WRAP_VIA_OSDEP_API_H_ +#define US_OS_WRAP_VIA_OSDEP_API_H_ + +#include "basic_types.h" +#include "osdep_api.h" + +#define GFP_KERNEL 1 +#define GFP_ATOMIC 1 + + +typedef unsigned int gfp_t; + +/* misc items */ +#ifndef ssize_t +#define ssize_t SSIZE_T +#endif +#ifndef size_t +#define size_t SIZE_T +#endif + +#ifndef __user +#define __user +#endif + +#ifndef loff_t +#define loff_t long +#endif +#ifndef __u8 +#define __u8 u8 +#endif +#ifndef __u16 +#define __u16 u16 +#endif +#ifndef __u32 +#define __u32 u32 +#endif +#ifndef __u64 +#define __u64 u64 +#endif +#ifndef __s8 +#define __s8 s8 +#endif +#ifndef __s16 +#define __s16 s16 +#endif +#ifndef __s32 +#define __s32 s32 +#endif +#ifndef __s64 +#define __s64 s64 +#endif + +typedef __u16 __le16; +typedef __u16 __be16; +typedef __u32 __le32; +typedef __u32 __be32; +typedef __u64 __le64; +typedef __u64 __be64; +typedef __u16 __sum16; +typedef __u32 __wsum; + + +#ifndef cpu_to_le32 + +#define cpu_to_le32(x) rtk_cpu_to_le32(x) +#endif +#ifndef le32_to_cpu + +#define le32_to_cpu(x) rtk_le32_to_cpu(x) +#endif +#ifndef cpu_to_le16 + +#define cpu_to_le16(x) rtk_cpu_to_le16(x) +#endif +#ifndef le16_to_cpu + +#define le16_to_cpu(x) rtk_le16_to_cpu(x) +#endif +#ifndef cpu_to_be32 + +#define cpu_to_be32(x) rtk_cpu_to_be32(x) +#endif +#ifndef be32_to_cpu + +#define be32_to_cpu(x) rtk_be32_to_cpu(x) +#endif +#ifndef cpu_to_be16 + +#define cpu_to_be16(x) rtk_cpu_to_be16(x) +#endif +#ifndef be16_to_cpu + +#define be16_to_cpu(x) rtk_be16_to_cpu(x) +#endif + +#ifndef DIV_ROUND_UP +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#endif +#ifndef BITS_PER_LONG +#define BITS_PER_LONG (32) +#endif +#ifndef BITS_PER_LONG_LONG +#define BITS_PER_LONG_LONG (32) +#endif +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif +#ifndef BIT_ULL +#define BIT_ULL(nr) (1ULL << (nr)) +#endif +#ifndef BIT_MASK +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#endif +#ifndef BIT_WORD +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#endif +#ifndef BIT_ULL_MASK +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#endif +#ifndef BIT_ULL_WORD +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) +#endif +#ifndef BITS_PER_BYTE +#define BITS_PER_BYTE (8) +#endif +#ifndef BITS_TO_LONGS +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#endif + +#ifndef min +#define min(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef max +#define max(x, y) ((x) > (y) ? (x) : (y)) +#endif + +#ifndef min_t +#define min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1 : __min2; }) +#endif +#ifndef max_t +#define max_t(type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + __max1 > __max2 ? __max1 : __max2; }) +#endif + +/** + * container_of - cast a member of a structure out to the containing structure + * @p(ptr): the pointer to the member. + * @t(type): the type of the container struct this is embedded in. + * @m(member): the name of the member within the struct. + * + */ +#ifndef container_of + #define container_of(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#endif + +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; +} +/** +* set_bit - Atomically set a bit in memory +* @nr: the bit to set +* @addr: the address to start counting from +* +* This function is atomic and may not be reordered. See __set_bit() +* if you do not require the atomic guarantees. +* +* Note: there are no guarantees that this function will not be reordered +* on non x86 architectures, so if you are writing portable code, +* make sure not to rely on its reordering guarantees. +* +* Note that @nr may be almost arbitrarily large; this function is not +* restricted to acting on a single-word quantity. +*/ +static inline void set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + SaveAndCli(); + *p |= mask; + RestoreFlags(); +} + +/** +* clear_bit - Clears a bit in memory +* @nr: Bit to clear +* @addr: Address to start counting from +* +* clear_bit() is atomic and may not be reordered. However, it does +* not contain a memory barrier, so if it is used for locking purposes, +* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() +* in order to ensure changes are visible on other processors. +*/ +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + SaveAndCli(); + *p &= ~mask; + RestoreFlags(); +} + +/** +* change_bit - Toggle a bit in memory +* @nr: Bit to change +* @addr: Address to start counting from +* +* change_bit() is atomic and may not be reordered. It may be +* reordered on other architectures than x86. +* Note that @nr may be almost arbitrarily large; this function is not +* restricted to acting on a single-word quantity. +*/ +static inline void change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + SaveAndCli(); + *p ^= mask; + RestoreFlags(); +} + +/** +* test_and_set_bit - Set a bit and return its old value +* @nr: Bit to set +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It may be reordered on other architectures than x86. +* It also implies a memory barrier. +*/ +static inline int test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + + SaveAndCli(); + old = *p; + *p = old | mask; + RestoreFlags(); + return (old & mask) != 0; +} + +/** +* test_and_clear_bit - Clear a bit and return its old value +* @nr: Bit to clear +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It can be reorderdered on other architectures other than x86. +* It also implies a memory barrier. +*/ +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + + SaveAndCli(); + old = *p; + *p = old & ~mask; + RestoreFlags(); + + return (old & mask) != 0; +} +/** +* test_and_change_bit - Change a bit and return its old value +* @nr: Bit to change +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It also implies a memory barrier. +*/ +static inline int test_and_change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + + SaveAndCli(); + old = *p; + *p = old ^ mask; + RestoreFlags(); + + return (old & mask) != 0; +} + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +#endif /* US_OS_WRAP_VIA_OSDEP_API_H_ */ diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_scsi.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_scsi.h new file mode 100644 index 0000000..e3a459a --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_scsi.h @@ -0,0 +1,19 @@ +#ifndef _US_SCSI_H +#define _US_SCSI_H + +/** + * define transfer length + */ +#define TRANS_LEN_READ_10 512 +#define TRANS_LEN_WRITE_10 512 +#define TRANS_LEN_INQUIRY 36 +#define TRANS_LEN_TEST_UNIT_READY 0 +#define TRANS_LEN_READ_CAPACITY_10 8 +#define TRANS_LEN_READ_CAPACITY_16 12 +#define TRANS_LEN_REQUEST_SENSE 18 +#define TRANS_LEN_MODE_SENSE 192 + +extern int scsi_cmnd_execute(char cmnd, unsigned char * _buff, + unsigned long _sector, unsigned int _count); + +#endif diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_strings.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_strings.h new file mode 100644 index 0000000..d452425 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_strings.h @@ -0,0 +1,28 @@ +#ifndef _US_STRINGS_H +#define _US_STRINGS_H +/* description of the sense key values */ +static const char * const snstext[] = { + "No Sense", /* 0: There is no sense information */ + "Recovered Error", /* 1: The last command completed successfully + but used error correction */ + "Not Ready", /* 2: The addressed target is not ready */ + "Medium Error", /* 3: Data error detected on the medium */ + "Hardware Error", /* 4: Controller or device failure */ + "Illegal Request", /* 5: Error in request */ + "Unit Attention", /* 6: Removable medium was changed, or + the target has been reset, or ... */ + "Data Protect", /* 7: Access to the data is blocked */ + "Blank Check", /* 8: Reached unexpected written or unwritten + region of the medium */ + "Vendor Specific(9)", + "Copy Aborted", /* A: COPY or COMPARE was aborted */ + "Aborted Command", /* B: The target aborted the command */ + "Equal", /* C: A SEARCH DATA command found data equal, + reserved in SPC-4 rev 36 */ + "Volume Overflow", /* D: Medium full with still data to be written */ + "Miscompare", /* E: Source data and data on the medium + do not agree */ + "Completed", /* F: command completed sense data reported, + may occur for successful command */ +}; +#endif diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_transport.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_transport.h new file mode 100644 index 0000000..60674a5 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_transport.h @@ -0,0 +1,67 @@ +/* Driver for USB Mass Storage compliant devices + * Transport Functions Header File + */ + +#ifndef _US_TRANSPORT_H_ +#define _US_TRANSPORT_H_ + +/* + * usb_stor_bulk_transfer_xxx() return codes, in order of severity + */ + +#define USB_STOR_XFER_GOOD 0 /* good transfer */ +#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */ +#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */ +#define USB_STOR_XFER_LONG 3 /* device tried to send too much */ +#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */ + +/* + * Transport return codes + */ + +#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */ +#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */ +#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ +#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ + +/* + * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED + * return codes. But now the transport and low-level transfer routines + * treat an abort as just another error (-ENOENT for a cancelled URB). + * It is up to the invoke_transport() function to test for aborts and + * distinguish them from genuine communication errors. + */ + +/* + * CBI accept device specific command + */ +#define US_CBI_ADSC 0 + +//extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*); +//extern int usb_stor_CB_reset(struct us_data*); +// +//extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*); +//extern int usb_stor_Bulk_max_lun(struct us_data*); +//extern int usb_stor_Bulk_reset(struct us_data*); +// +//extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*); +//extern void usb_stor_stop_transport(struct us_data*); + +//extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe, +// u8 request, u8 requesttype, u16 value, u16 index, +// void *data, u16 size, int timeout); +//extern int usb_stor_clear_halt(struct us_data *us, unsigned int pipe); +// +//extern int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, +// u8 request, u8 requesttype, u16 value, u16 index, +// void *data, u16 size); +//extern int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, +// void *buf, unsigned int length, unsigned int *act_len); +//extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe, +// void *buf, unsigned int length, int use_sg, int *residual); +//extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, +// struct scsi_cmnd* srb); +// +//extern int usb_stor_port_reset(struct us_data *us); +#endif + diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_usb.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_usb.h new file mode 100644 index 0000000..326006d --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_usb.h @@ -0,0 +1,245 @@ +#ifndef _US_USB_H_ +#define _US_USB_H_ + +#include "usb.h" +#include "us_os_wrap_via_osdep_api.h" +#include "us_debug.h" +//#include "sg.h" + +struct us_data; +struct scsi_cmnd; + +#define CONFIG_SG 0 +#define CONFIG_DMA 0 + +/* + * Unusual device list definitions + */ + +struct us_unusual_dev { + const char* vendorName; + const char* productName; + __u8 useProtocol; + __u8 useTransport; + int (*initFunction)(struct us_data *); +}; + +/* Flag definitions: these entries are static */ +#define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */ +//#define US_FL_MODE_XLATE 0 /* [no longer used] */ +#define US_FL_NEED_OVERRIDE 0x00000004 /* unusual_devs entry is necessary */ +//#define US_FL_IGNORE_SER 0 /* [no longer used] */ +#define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */ +#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs faking */ +#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ +#define US_FL_IGNORE_RESIDUE 0x00000100 /* reported residue is wrong */ +#define US_FL_BULK32 0x00000200 /* Uses 32-byte CBW length */ + + +/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */ +#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */ +#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */ +#define US_FLIDX_ABORTING 2 /* abort is in progress */ +#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ +#define US_FLIDX_RESETTING 4 /* device reset in progress */ +#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ +#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */ +#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ +#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ + +#define USB_STOR_STRING_LEN 32 + +/* + * We provide a DMA-mapped I/O buffer for use with small USB transfers. + * It turns out that CB[I] needs a 12-byte buffer and Bulk-only needs a + * 31-byte buffer. But Freecom needs a 64-byte buffer, so that's the + * size we'll allocate. + */ + +#define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ +#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */ + +typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); +typedef int (*trans_reset)(struct us_data*); +typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*); +typedef void (*extra_data_destructor)(void *); /* extra data destructor */ +typedef void (*pm_hook)(struct us_data *, int); /* power management hook */ + +#define US_SUSPEND 0 +#define US_RESUME 1 + +/* we allocate one of these for every device that we remember */ +struct us_data { + /* The device we're working with + * It's important to note: + * (o) you must hold dev_mutex to change pusb_dev + */ + _Mutex dev_mutex; + struct usb_device *pusb_dev; /* this usb_device */ + struct usb_interface *pusb_intf; /* this interface */ + struct us_unusual_dev *unusual_dev; /* device-filter entry */ + unsigned long fflags; /* fixed flags from filter */ + unsigned long dflags; /* dynamic atomic bitflags */ + unsigned int send_bulk_pipe; /* cached pipe values */ + unsigned int recv_bulk_pipe; + unsigned int send_ctrl_pipe; + unsigned int recv_ctrl_pipe; + unsigned int recv_intr_pipe; + + /* information about the device */ + char *transport_name; + char *protocol_name; + __le32 bcs_signature; + u8 subclass; + u8 protocol; + u8 max_lun; // max number of logical unit (0,1,2,3...) + + u8 ifnum; /* interface number */ + u8 ep_bInterval; /* interrupt interval */ + + /* function pointers for this device */ + trans_cmnd transport; /* transport function */ + trans_reset transport_reset; /* transport device reset */ + proto_cmnd proto_handler; /* protocol handler */ + + /* SCSI interfaces */ + struct scsi_cmnd *srb; /* current srb */ + unsigned int tag; /* current dCBWTag */ + + /* control and bulk communications data */ + struct urb *current_urb; /* USB requests */ + struct usb_ctrlrequest *cr; /* control requests */ +// struct usb_sg_request current_sg; /* scatter-gather req. */ + unsigned char *iobuf; /* I/O buffer */ + dma_addr_t iobuf_dma; /* buffer DMA addresses */ + + xTaskHandle ctl_task; /*the control task handle*/ + + /* mutual exclusion and synchronization structures */ + _Sema cmnd_ready; /* to sleep thread on */ + _Mutex notify; /* thread begin/end */ + + unsigned no_sg_constraint:1; /* no sg constraint */ + unsigned sg_tablesize; /* 0 or largest number of sg list entries */ + + /* subdriver information */ + void *extra; /* Any extra data */ +}; + +/* Convert between us_data and the corresponding Scsi_Host */ +//static inline struct Scsi_Host *us_to_host(struct us_data *us) { +// return container_of((void *) us, struct Scsi_Host, hostdata); +//} +//static inline struct us_data *host_to_us(struct Scsi_Host *host) { +// return (struct us_data *) host->hostdata; +//} + +/* Function to fill an inquiry response. See usb.c for details */ +extern void fill_inquiry_response(struct us_data *us, + unsigned char *data, unsigned int data_len); + +/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the + * single queue element srb for write access */ +//#define scsi_unlock(host) spin_unlock_irq(host->host_lock) +//#define scsi_lock(host) spin_lock_irq(host->host_lock) + +#define scsi_unlock(host) spin_unlock(host->host_lock) +#define scsi_lock(host) spin_lock(host->host_lock) + +/* General routines provided by the usb-storage standard core */ +#ifdef CONFIG_PM +extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message); +extern int usb_stor_resume(struct usb_interface *iface); +extern int usb_stor_reset_resume(struct usb_interface *iface); +#else +#define usb_stor_suspend NULL +#define usb_stor_resume NULL +#define usb_stor_reset_resume NULL +#endif + +extern int usb_stor_pre_reset(struct usb_interface *iface); +extern int usb_stor_post_reset(struct usb_interface *iface); + +extern int usb_stor_probe1(struct us_data *us, + struct usb_interface *intf, + const struct usb_device_id *id, + struct us_unusual_dev *unusual_dev); +extern int usb_stor_probe2(struct us_data *us); +extern void usb_stor_disconnect(struct usb_interface *intf); + +extern void usb_stor_adjust_quirks(struct usb_device *dev, + unsigned long *fflags); + +// the follow definition should be prot to usb.h for other usb device + + +/* USB autosuspend and autoresume */ + +#ifdef CONFIG_PM_RUNTIME +extern void usb_enable_autosuspend(struct usb_device *udev); +extern void usb_disable_autosuspend(struct usb_device *udev); + +extern int usb_autopm_get_interface(struct usb_interface *intf); +extern void usb_autopm_put_interface(struct usb_interface *intf); +extern int usb_autopm_get_interface_async(struct usb_interface *intf); +extern void usb_autopm_put_interface_async(struct usb_interface *intf); +extern void usb_autopm_get_interface_no_resume(struct usb_interface *intf); +extern void usb_autopm_put_interface_no_suspend(struct usb_interface *intf); + +static inline void usb_mark_last_busy(struct usb_device *udev) +{ + pm_runtime_mark_last_busy(&udev->dev); +} + +#else + +static inline int usb_enable_autosuspend(struct usb_device *udev) +{ return 0; } +static inline int usb_disable_autosuspend(struct usb_device *udev) +{ return 0; } + +static inline int usb_autopm_get_interface(struct usb_interface *intf) +{ return 0; } +static inline int usb_autopm_get_interface_async(struct usb_interface *intf) +{ return 0; } + +static inline void usb_autopm_put_interface(struct usb_interface *intf) +{ } +static inline void usb_autopm_put_interface_async(struct usb_interface *intf) +{ } +static inline void usb_autopm_get_interface_no_resume( + struct usb_interface *intf) +{ } +static inline void usb_autopm_put_interface_no_suspend( + struct usb_interface *intf) +{ } +static inline void usb_mark_last_busy(struct usb_device *udev) +{ } +#endif + +/* USB port reset for device reinitialization */ +extern int usb_reset_device(struct usb_device *dev); +extern void usb_queue_reset_device(struct usb_interface *dev); + +extern void *usb_alloc_coherent(struct usb_device *dev, size_t size, + gfp_t mem_flags, dma_addr_t *dma); +extern void usb_free_coherent(struct usb_device *dev, size_t size, + void *addr, dma_addr_t dma); + + +// copy from transport.h +extern int usb_stor_CB_transport(struct scsi_cmnd *, struct us_data*); +extern int usb_stor_CB_reset(struct us_data*); +extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*); +extern int usb_stor_Bulk_max_lun(struct us_data*); +extern int usb_stor_Bulk_reset(struct us_data*); + +extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*); +extern void usb_stor_stop_transport(struct us_data*); + +// copy form protocol.h +extern void usb_stor_transparent_scsi_command(struct scsi_cmnd* srb, struct us_data* ); + +extern unsigned char usb_stor_sense_invalidCDB[18]; + +#endif diff --git a/USDK/component/common/drivers/usb_class/host/storage/inc/us_usual.h b/USDK/component/common/drivers/usb_class/host/storage/inc/us_usual.h new file mode 100644 index 0000000..9b8d823 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/storage/inc/us_usual.h @@ -0,0 +1,37 @@ +#ifndef __US_USUAL_H +#define __US_USUAL_H + +#include "usb.h" +#include "storage.h" + +#define US_FL_SINGLE_LUN 0x00000001/* allow access to only LUN 0 */ +//#define US_FL_NEED_OVERRIDE 0x00000002/* unusual_devs entry is necessary */ +//#define US_FL_SCM_MULT_TARG 0x00000004/* supports multiple targets */ +//#define US_FL_FIX_INQUIRY 0x00000008/* INQUIRY response needs faking */ +//#define US_FL_FIX_CAPACITY 0x00000010/* READ CAPACITY response too big */ +//#define US_FL_IGNORE_RESIDUE 0x00000020/* reported residue is wrong */ +//#define US_FL_BULK32 0x00000040/* Uses 32-byte CBW length */ +#define US_FL_NOT_LOCKABLE 0x00000080/* PREVENT/ALLOW not supported */ +#define US_FL_GO_SLOW 0x00000100/* Need delay after Command phase */ +#define US_FL_NO_WP_DETECT 0x00000200/* Don't check for write-protect */ +#define US_FL_MAX_SECTORS_64 0x00000400/* Sets max_sectors to 64 */ +#define US_FL_IGNORE_DEVICE 0x00000800/* Don't claim device */ +#define US_FL_CAPACITY_HEURISTICS 0x00001000/* sometimes sizes is too big */ +#define US_FL_MAX_SECTORS_MIN 0x00002000/* Sets max_sectors to arch min */ +#define US_FL_BULK_IGNORE_TAG 0x00004000/* Ignore tag mismatch in bulk operations */ +#define US_FL_SANE_SENSE 0x00008000/* Sane Sense (> 18 bytes) */ +#define US_FL_CAPACITY_OK 0x00010000/* READ CAPACITY response is correct */ +#define US_FL_BAD_SENSE 0x00020000/* Bad Sense (never more than 18 bytes) */ +#define US_FL_NO_READ_DISC_INFO 0x00040000/* cannot handle READ_DISC_INFO */ +#define US_FL_NO_READ_CAPACITY_16 0x00080000/* cannot handle READ_CAPACITY_16*/ +#define US_FL_INITIAL_READ10 0x00100000/* Initial READ(10) (and others) must be retried */ +#define US_FL_WRITE_CACHE 0x00200000/* Write Cache status is not available */ +#define US_FL_NEEDS_CAP16 0x00400000/* cannot handle READ_CAPACITY_10 */ +#define US_FL_IGNORE_UAS 0x00800000/* Device advertises UAS but it is broken */ +#define US_FL_BROKEN_FUA 0x01000000/* Cannot handle FUA in WRITE or READ CDBs */ + +extern int usb_usual_ignore_device(struct usb_interface *intf); +extern struct usb_device_id usb_storage_usb_ids[]; + +#endif /* __US_USUAL_H */ + diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/mjpeg/mjpeg_api.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/mjpeg/mjpeg_api.h new file mode 100644 index 0000000..38a88da --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/mjpeg/mjpeg_api.h @@ -0,0 +1,41 @@ +#ifndef _MJPEG_API_H +#define _MJPEG_API_H + + +/* memory disk type */ +typedef enum _medium_type{ + medium_SD, + medium_USB, + medium_FLASH, + medium_CACHE +}medium_type; + +/* time unit*/ +typedef enum _time_unit{ + unit_HR, // hour + unit_MIN, // minute + unit_SEC, //second +}time_unit; + +typedef struct _mjpeg_cache{ + unsigned char* addr; + int size; +}mjpeg_cache; + +struct mjpeg_context{ + /* mjpeg size*/ + int width;//frame width + int height;//frame height + /* */ + medium_type disktype; + time_unit timeunit; + int interval; + unsigned char* name; + unsigned char is_periodic; + /* store mjpeg in a RAM cache */ + mjpeg_cache cache; +}; + +int mjpeg_get(struct mjpeg_context *context); + +#endif diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/uapi_uvcvideo.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/uapi_uvcvideo.h new file mode 100644 index 0000000..e34edfb --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/uapi_uvcvideo.h @@ -0,0 +1,71 @@ +#ifndef __LINUX_UVCVIDEO_H_ +#define __LINUX_UVCVIDEO_H_ +#if 0 +#include +#include +#endif +#include "uvc_os_wrap_via_osdep_api.h" +/* + * Dynamic controls + */ + +/* Data types for UVC control data */ +#define UVC_CTRL_DATA_TYPE_RAW 0 +#define UVC_CTRL_DATA_TYPE_SIGNED 1 +#define UVC_CTRL_DATA_TYPE_UNSIGNED 2 +#define UVC_CTRL_DATA_TYPE_BOOLEAN 3 +#define UVC_CTRL_DATA_TYPE_ENUM 4 +#define UVC_CTRL_DATA_TYPE_BITMASK 5 + +/* Control flags */ +#define UVC_CTRL_FLAG_SET_CUR (1 << 0) +#define UVC_CTRL_FLAG_GET_CUR (1 << 1) +#define UVC_CTRL_FLAG_GET_MIN (1 << 2) +#define UVC_CTRL_FLAG_GET_MAX (1 << 3) +#define UVC_CTRL_FLAG_GET_RES (1 << 4) +#define UVC_CTRL_FLAG_GET_DEF (1 << 5) +/* Control should be saved at suspend and restored at resume. */ +#define UVC_CTRL_FLAG_RESTORE (1 << 6) +/* Control can be updated by the camera. */ +#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7) + +#define UVC_CTRL_FLAG_GET_RANGE \ + (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | \ + UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \ + UVC_CTRL_FLAG_GET_DEF) + +struct uvc_menu_info { + __u32 value; + __u8 name[32]; +}; + +struct uvc_xu_control_mapping { + __u32 id; + __u8 name[32]; + __u8 entity[16]; + __u8 selector; + + __u8 size; + __u8 offset; + __u32 v4l2_type; + __u32 data_type; + + struct uvc_menu_info __user *menu_info; + __u32 menu_count; + + __u32 reserved[4]; +}; + +struct uvc_xu_control_query { + __u8 unit; + __u8 selector; + __u8 query; /* Video Class-Specific Request Code, */ + /* defined in linux/usb/video.h A.8. */ + __u16 size; + __u8 __user *data; +}; + +#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) +#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) + +#endif diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_intf.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_intf.h new file mode 100644 index 0000000..3768d06 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_intf.h @@ -0,0 +1,55 @@ +#ifndef _UVC_INTF_H_ +#define _UVC_INTF_H_ + +enum uvc_format_type{ + UVC_FORMAT_MJPEG = 1, + UVC_FORMAT_H264 = 2, + UVC_FORMAT_UNKNOWN = -1, +}; + +typedef enum uvc_format_type uvc_fmt_t; + +struct uvc_context +{ + uvc_fmt_t fmt_type; //video format type + int width;//video frame width + int height;//video frame height + int frame_rate;//video frame rate + int compression_ratio;//compression format video compression ratio +}; + +#define USER_CTRL_SATURATION 1 + +struct uvc_user_ctrl +{ + u32 ctrl_id; + s32 ctrl_value; +}; + +struct uvc_buf_context +{ + int index; //index of internal uvc buffer + unsigned char *data; //address of uvc data + int len; //length of uvc data + u32 timestamp; //timestamp +}; + +int uvc_stream_init(void); //entry function to start uvc +void uvc_stream_free(void); // free streaming resources +int uvc_is_stream_ready(void); // return true if uvc device is initialized successfully +int uvc_is_stream_on(void); //return true if uvc device is streaming now +int uvc_is_stream_off(void); //return true if uvc device is free already +int uvc_stream_on(void); //enable camera streaming +void uvc_stream_off(void); //disable camera streaming +int uvc_set_param(uvc_fmt_t fmt_type, int *width, int *height, int *frame_rate, int *compression_ratio);//set camera streaming video parameters:video format, resolution and frame rate. +int uvc_get_user_ctrl(struct uvc_user_ctrl *user_ctrl); +int uvc_set_user_ctrl(struct uvc_user_ctrl *user_ctrl); +int uvc_buf_check(struct uvc_buf_context *b); //check if uvc_buf_context is legal (return 0 is legal otherwise -1) +int uvc_dqbuf(struct uvc_buf_context *b); //dequeue internal buffer & get internal buffer info +int uvc_qbuf(struct uvc_buf_context *b); //queue internal buffer +int is_pure_thru_on(void); //return 1 if pure throughput test mode is on otherwise return 0 +void uvc_pure_thru_on(void); //turn on pure uvc throughput test mode (i.e. no decoding is involved) +void uvc_dec_thru_on(void); //turn on uvc throughput test mode with uvc payload decoding +void uvc_thru_off(void); //turn off uvc throughput log service + +#endif diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_os_wrap_via_osdep_api.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_os_wrap_via_osdep_api.h new file mode 100644 index 0000000..2eb5615 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvc_os_wrap_via_osdep_api.h @@ -0,0 +1,573 @@ +#ifndef _UVC_OSDEP_WRAP_H_ +#define _UVC_OSDEP_WRAP_H_ + +//#include "rtl_utility.h" +#include "platform/platform_stdlib.h" +#include "basic_types.h" +#include "osdep_api.h" +#include "usb_defs.h" + +#include "errno.h" +#include "dlist.h" + + + +#define UVC_LAYER_DEBUG 0 +#if UVC_LAYER_DEBUG +#define UVC_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define UVC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define FUN_ENTER //printf("\n\r%s ==>\n", __func__) +#define FUN_EXIT //printf("\n\r%s <==\n", __func__) +#define FUN_TRACE //printf("\n\r%s:%d \n", __func__, __LINE__) +#else +#define UVC_PRINTF(fmt, args...) +#define UVC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define FUN_ENTER +#define FUN_EXIT +#define FUN_TRACE +#endif + +/* add by Ian -- define uvc task priority */ +#define UVC_TASK_PRIORITY 2 + +#ifndef __u8 +#define __u8 u8 +#endif +#ifndef __u16 +#define __u16 u16 +#endif +#ifndef __u32 +#define __u32 u32 +#endif +#ifndef __u64 +#define __u64 u64 +#endif +#ifndef __s8 +#define __s8 s8 +#endif +#ifndef __s16 +#define __s16 s16 +#endif +#ifndef __s32 +#define __s32 s32 +#endif +#ifndef __s64 +#define __s64 s64 +#endif + +#ifndef gfp_t +#define gfp_t u32 +#endif + +#define ALIGN(x, a, type_of_x) (((x) + ((type_of_x)(a) - 1)) & ~((type_of_x)(a) - 1)) + +#ifndef IS_ALIGNED +#define IS_ALIGNED(x, a, type_of_x) (((x) & ((type_of_x)(a) - 1)) == 0) +#endif +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +#ifndef BITS_PER_LONG +#define BITS_PER_LONG (32) +#endif +#ifndef BITS_PER_LONG_LONG +#define BITS_PER_LONG_LONG (32) +#endif + +/* Atomic integer operations */ +#ifndef atomic_set + #define atomic_set(v, i) RTL_ATOMIC_SET((v), (i)) +#endif +#ifndef atomic_read + #define atomic_read(v) RTL_ATOMIC_READ((v)) +#endif +#ifndef atomic_add + #define atomic_add(v, i) RTL_ATOMIC_ADD((v), (i)) +#endif +#ifndef atomic_sub + #define atomic_sub(v, i) RTL_ATOMIC_SUB((v), (i)) +#endif +#ifndef atomic_inc + #define atomic_inc(v) RTL_ATOMIC_INC((v)) +#endif +#ifndef atomic_dec + #define atomic_dec(v) RTL_ATOMIC_DEC((v)) +#endif + +#ifndef MEDIA_PAD_FL_SINK +#define MEDIA_PAD_FL_SINK (1 << 0) +#endif +#ifndef MEDIA_PAD_FL_SOURCE +#define MEDIA_PAD_FL_SOURCE (1 << 1) +#endif +#ifndef MEDIA_PAD_FL_MUST_CONNECT +#define MEDIA_PAD_FL_MUST_CONNECT (1 << 2) +#endif + +static inline u16 __get_unaligned_le16(const u8 *p) +{ + return p[0] | p[1] << 8; +} + +static inline u32 __get_unaligned_le32(const u8 *p) +{ + return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; +} + +static inline u64 __get_unaligned_le64(const u8 *p) +{ + return (u64)__get_unaligned_le32(p + 4) << 32 | + __get_unaligned_le32(p); +} + +static inline void __put_unaligned_le16(u16 val, u8 *p) +{ + *p++ = val; + *p++ = val >> 8; +} + +static inline void __put_unaligned_le32(u32 val, u8 *p) +{ + __put_unaligned_le16(val >> 16, p + 2); + __put_unaligned_le16(val, p); +} + +static inline void __put_unaligned_le64(u64 val, u8 *p) +{ + __put_unaligned_le32(val >> 32, p + 4); + __put_unaligned_le32(val, p); +} + +static inline u16 get_unaligned_le16(const void *p) +{ + return __get_unaligned_le16((const u8 *)p); +} + +static inline u32 get_unaligned_le32(const void *p) +{ + return __get_unaligned_le32((const u8 *)p); +} + +static inline u64 get_unaligned_le64(const void *p) +{ + return __get_unaligned_le64((const u8 *)p); +} + +static inline void put_unaligned_le16(u16 val, void *p) +{ + __put_unaligned_le16(val, p); +} + +static inline void put_unaligned_le32(u32 val, void *p) +{ + __put_unaligned_le32(val, p); +} + +static inline void put_unaligned_le64(u64 val, void *p) +{ + __put_unaligned_le64(val, p); +} + +/** +* kmemdup - duplicate region of memory +* +* @src: memory region to duplicate +* @len: memory region length +* @gfp: GFP mask to use +*/ +static inline void *kmemdup(const void *src, size_t len, gfp_t gfp) +{ + void *p; + + //p = kmalloc_track_caller(len, gfp); + //p = kmalloc(len, gfp); + p = malloc(len); + if (p) + memcpy(p, src, len); + return p; +} +#ifndef __force +#define __force __attribute__((force)) +#endif + +#if 0 +typedef __u16 __bitwise __le16; +typedef __u16 __bitwise __be16; +typedef __u32 __bitwise __le32; +typedef __u32 __bitwise __be32; +typedef __u64 __bitwise __le64; +typedef __u64 __bitwise __be64; +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; +#endif +//edit by Ian -- remove duplicated definitions +#if 0 +typedef __u16 __le16; +typedef __u16 __be16; +typedef __u32 __le32; +typedef __u32 __be32; +typedef __u64 __le64; +typedef __u64 __be64; +typedef __u16 __sum16; +typedef __u32 __wsum; +#endif + +#ifndef __le16 +#define __le16 __u16 +#endif +#ifndef __be16 +#define __be16 __u16 +#endif +#ifndef __le32 +#define __le32 __u32 +#endif +#ifndef __be32 +#define __be32 __u32 +#endif +static inline __u32 le32_to_cpup(const __le32 *p) +{ + //return (__force __u32)*p; + return (__u32)*p; +} +static inline __u16 le16_to_cpup(const __le16 *p) +{ + //return (__force __u16)*p; + return (__u16)*p; +} + + +/* Endian macros */ +#ifndef htonl +#define htonl(x) rtk_cpu_to_be32(x) +#endif + +#ifndef ntohl +#define ntohl(x) rtk_be32_to_cpu(x) +#endif + +#ifndef htons +#define htons(x) rtk_cpu_to_be16(x) +#endif + +#ifndef ntohs +#define ntohs(x) rtk_be16_to_cpu(x) +#endif + +#ifndef cpu_to_le32 +#define cpu_to_le32(x) rtk_cpu_to_le32(x) +#endif + +#ifndef le32_to_cpu +#define le32_to_cpu(x) rtk_le32_to_cpu(x) +#endif + +#ifndef cpu_to_le16 +#define cpu_to_le16(x) rtk_cpu_to_le16(x) +#endif + +#ifndef le16_to_cpu +#define le16_to_cpu(x) rtk_le16_to_cpu(x) +#endif + +#ifndef cpu_to_be32 +#define cpu_to_be32(x) rtk_cpu_to_be32(x) +#endif + +#ifndef be32_to_cpu +#define be32_to_cpu(x) rtk_be32_to_cpu(x) +#endif + +#ifndef cpu_to_be16 +#define cpu_to_be16(x) rtk_cpu_to_be16(x) +#endif + +#ifndef be16_to_cpu +#define be16_to_cpu(x) rtk_be16_to_cpu(x) +#endif + +/* Parameters used to convert the timespec values: */ +#ifndef MSEC_PER_SEC +#define MSEC_PER_SEC 1000L +#endif +#ifndef USEC_PER_MSEC +#define USEC_PER_MSEC 1000L +#endif +#ifndef NSEC_PER_USEC +#define NSEC_PER_USEC 1000L +#endif +#ifndef NSEC_PER_MSEC +#define NSEC_PER_MSEC 1000000L +#endif +#ifndef USEC_PER_SEC +#define USEC_PER_SEC 1000000L +#endif +#ifndef NSEC_PER_SEC +#define NSEC_PER_SEC 1000000000L +#endif +#ifndef FSEC_PER_SEC +#define FSEC_PER_SEC 1000000000000000LL +#endif +#ifndef TIME_T_MAX +#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) +#endif + +#ifndef __GFP_WAIT +#define __GFP_WAIT (0x10u) +#endif +#ifndef __GFP_HIGH +#define __GFP_HIGH (0x20u) +#endif +#ifndef __GFP_IO +#define __GFP_IO (0x40u) +#endif +#ifndef __GFP_FS +#define __GFP_FS (0x80u) +#endif +#ifndef GFP_NOIO +#define GFP_NOIO (0x10u) +#endif +#ifndef __GFP_NOWARN +#define __GFP_NOWARN (0x200u) +#endif +#ifndef GFP_KERNEL +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#endif + +#ifndef copy_from_user +#define copy_from_user(to, from, sz) _memcpy((to), (from), (sz)) +#endif +#ifndef copy_to_user +#define copy_to_user(to, from, sz) _memcpy((to), (from), (sz)) +#endif + +typedef u32 compat_caddr_t; //used for compatibility in uvc_v4l2.c + +/** +* strlcpy - Copy a %NUL terminated string into a sized buffer +* @dest: Where to copy the string to +* @src: Where to copy the string from +* @size: size of destination buffer +* +* Compatible with *BSD: the result is always a valid +* NUL-terminated string that fits in the buffer (unless, +* of course, the buffer size is zero). It does not pad +* out the result like strncpy() does. +*/ +#ifndef __GNUC__ +static inline size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = _strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} +#endif + +/** +* clamp - return a value clamped to a given range with strict typechecking +* @val: current value +* @min: minimum allowable value +* @max: maximum allowable value +* +* This macro does strict typechecking of min/max to make sure they are of the +* same type as val. See the unnecessary pointer comparisons. +*/ + +#ifndef clamp +#define clamp(new_val, val, min, max, type) do{ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + (void) (&__val == &__min); \ + (void) (&__val == &__max); \ + __val = (__val < __min) ? __min: __val; \ + new_val = (__val > __max) ? __max: __val; }while(0) +#endif + +/* + * Compile time versions of __arch_hweightN() + */ +#ifndef __const_hweight8 +#define __const_hweight8(w) \ + ( (!!((w) & (1ULL << 0))) + \ + (!!((w) & (1ULL << 1))) + \ + (!!((w) & (1ULL << 2))) + \ + (!!((w) & (1ULL << 3))) + \ + (!!((w) & (1ULL << 4))) + \ + (!!((w) & (1ULL << 5))) + \ + (!!((w) & (1ULL << 6))) + \ + (!!((w) & (1ULL << 7))) ) +#endif +#ifndef hweight8 +#define hweight8(w) __const_hweight8(w) +#endif +#ifndef BITMAP_LAST_WORD_MASK +#define BITMAP_LAST_WORD_MASK(nbits) \ +( \ + ((nbits) % BITS_PER_LONG) ? \ + (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL \ +) +#endif +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ +static inline unsigned int hweight32(unsigned int w) +{ + unsigned int res = w - ((w >> 1) & 0x55555555); + res = (res & 0x33333333) + ((res >> 2) & 0x33333333); + res = (res + (res >> 4)) & 0x0F0F0F0F; + res = res + (res >> 8); + return (res + (res >> 16)) & 0x000000FF; +} + +static inline unsigned long hweight64(__u64 w) +{ +#if BITS_PER_LONG == 32 + return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w); +#elif BITS_PER_LONG == 64 + __u64 res = w - ((w >> 1) & 0x5555555555555555ul); + res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul); + res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful; + res = res + (res >> 8); + res = res + (res >> 16); + return (res + (res >> 32)) & 0x00000000000000FFul; +#endif +} + + +static inline unsigned long hweight_long(unsigned long w) +{ + return sizeof(w) == 4 ? hweight32(w) : hweight64(w); +} + +static inline int __bitmap_weight(const unsigned long *bitmap, int bits) +{ + int k, w = 0, lim = bits/BITS_PER_LONG; + + for (k = 0; k < lim; k++) + w += hweight_long(bitmap[k]); + + if (bits % BITS_PER_LONG) + w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); + + return w; +} + +static inline int bitmap_weight(const unsigned long *src, int nbits) +{ + // if (small_const_nbits(nbits)) + // return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits)); + return __bitmap_weight(src, nbits); +} + +/** + * memweight - count the total number of bits set in memory area + * @ptr: pointer to the start of the area + * @bytes: the size of the area + */ +static inline size_t memweight(const void *ptr, size_t bytes) +{ + size_t ret = 0; + size_t longs; + const unsigned char *bitmap = ptr; + + for (; bytes > 0 && ((unsigned long)bitmap) % sizeof(long); + bytes--, bitmap++) + ret += hweight8(*bitmap); + + longs = bytes / sizeof(long); + if (longs) { + //BUG_ON(longs >= INT_MAX / BITS_PER_LONG); + ret += bitmap_weight((unsigned long *)bitmap, longs * BITS_PER_LONG); + bytes -= longs * sizeof(long); + bitmap += longs * sizeof(long); + } + /* + * The reason that this last loop is distinct from the preceding + * bitmap_weight() call is to compute 1-bits in the last region smaller + * than sizeof(long) properly on big-endian systems. + */ + for (; bytes > 0; bytes--, bitmap++) + ret += hweight8(*bitmap); + + return ret; +} + + /** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to +* @src: The string to append to it +* @count: The size of the destination buffer. +*/ +#ifndef __GNUC__ +static inline size_t strlcat(char *dest, const char *src, size_t count) +{ + size_t dsize = _strlen(dest); + size_t len = _strlen(src); + size_t res = dsize + len; + + /* This would be a bug */ + //BUG_ON(dsize >= count); + + dest += dsize; + count -= dsize; + if (len >= count) + len = count-1; + memcpy(dest, src, len); + dest[len] = 0; + return res; +} +#endif + +/** + * atomic_dec_and_test - decrement and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. + */ +static inline int atomic_dec_and_test(atomic_t *v) +{ + atomic_dec(v); + if (v->counter == 0) + return TRUE; + else + return FALSE; +} + +/** + * kcalloc - allocate memory for an array. The memory is set to zero. + * @n: number of elements. + * @size: element size. + * @flags: the type of memory to allocate (see kmalloc). + */ +static inline void *kcalloc(size_t n, size_t size, gfp_t flags) +{ + return RtlZmalloc(((n) * (size))); +} + +#ifndef GFP_ATOMIC +#define GFP_ATOMIC GFP_KERNEL +#endif +#ifndef offsetof +#define offsetof(s,m) (size_t)&(((s *)0)->m) +#endif + +//enum linux kernel version +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif +#ifndef LINUX_VERSION_CODE +#define LINUX_VERSION_CODE KERNEL_VERSION(3, 12, 0) +#endif + +#endif //_UVC_OSDEP_WRAP_H_ diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/uvcvideo.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvcvideo.h new file mode 100644 index 0000000..977f116 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/uvcvideo.h @@ -0,0 +1,774 @@ +#ifndef _USB_VIDEO_H_ +#define _USB_VIDEO_H_ +#if 0 +#ifndef __KERNEL__ +#error "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead." +#endif /* __KERNEL__ */ + +#include +#include +#endif + +#include "usb.h" +#include "video.h" +#include "uvcvideo.h" + +#include "videodev2.h" +#include "media-device.h" +#include "v4l2-device.h" +#include "v4l2-event.h" +#include "v4l2-fh.h" +#include "videobuf2-core.h" + + + +/* -------------------------------------------------------------------------- + * UVC constants + */ + +#define UVC_TERM_INPUT 0x0000 +#define UVC_TERM_OUTPUT 0x8000 +#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000) + +#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff) +#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) +#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) +#define UVC_ENTITY_IS_ITERM(entity) \ + (UVC_ENTITY_IS_TERM(entity) && \ + ((entity)->type & 0x8000) == UVC_TERM_INPUT) +#define UVC_ENTITY_IS_OTERM(entity) \ + (UVC_ENTITY_IS_TERM(entity) && \ + ((entity)->type & 0x8000) == UVC_TERM_OUTPUT) + + +/* ------------------------------------------------------------------------ + * GUIDs + */ +#define UVC_GUID_UVC_CAMERA \ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} +#define UVC_GUID_UVC_OUTPUT \ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02} +#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03} +#define UVC_GUID_UVC_PROCESSING \ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01} +#define UVC_GUID_UVC_SELECTOR \ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} + +#define UVC_GUID_FORMAT_MJPEG \ + { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_YUY2 \ + { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_YUY2_ISIGHT \ + { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_NV12 \ + { 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_YV12 \ + { 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_I420 \ + { 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_UYVY \ + { 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y800 \ + { 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y8 \ + { 'Y', '8', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y10 \ + { 'Y', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y12 \ + { 'Y', '1', '2', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_Y16 \ + { 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_BY8 \ + { 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_RGBP \ + { 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_M420 \ + { 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} + +#define UVC_GUID_FORMAT_H264 \ + { 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +/* edit by Ian -- patch for GEO add two new guids*/ +#define UVC_GUID_FORMAT_MPEG \ + { 'M', 'P', 'E', 'G', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_MUX \ + { 'M', 'U', 'X', 0x00, 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +/* ------------------------------------------------------------------------ + * Driver specific constants. + */ + +#define DRIVER_VERSION "1.1.1" + +/* Number of isochronous URBs. */ +#define UVC_URBS 2 +/* Maximum number of packets per URB. */ +#define UVC_MAX_PACKETS 32 +/* Maximum number of video buffers. */ +#define UVC_MAX_VIDEO_BUFFERS 8 +/* Maximum status buffer size in bytes of interrupt URB. */ +#define UVC_MAX_STATUS_SIZE 16 + +//modified by Ian +#define UVC_REQBUF_SIZE (150000) + +#define UVC_CTRL_CONTROL_TIMEOUT 300 +#define UVC_CTRL_STREAMING_TIMEOUT 5000 + +/* Maximum allowed number of control mappings per device */ +#define UVC_MAX_CONTROL_MAPPINGS 1024 +#define UVC_MAX_CONTROL_MENU_ENTRIES 32 + +/* Devices quirks */ +#define UVC_QUIRK_STATUS_INTERVAL 0x00000001 +#define UVC_QUIRK_PROBE_MINMAX 0x00000002 +#define UVC_QUIRK_PROBE_EXTRAFIELDS 0x00000004 +#define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 +#define UVC_QUIRK_STREAM_NO_FID 0x00000010 +#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 +#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 +#define UVC_QUIRK_PROBE_DEF 0x00000100 +#define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 + +/* Format flags */ +#define UVC_FMT_FLAG_COMPRESSED 0x00000001 +#define UVC_FMT_FLAG_STREAM 0x00000002 + +/* ------------------------------------------------------------------------ + * Structures. + */ + +struct uvc_device; + +/* TODO: Put the most frequently accessed fields at the beginning of + * structures to maximize cache efficiency. + */ +struct uvc_control_info { + struct list_head mappings; + __u8 entity[16]; + __u8 index; /* Bit index in bmControls */ + __u8 selector; + + __u16 size; + __u32 flags; +}; + +struct uvc_control_mapping { + struct list_head list; + struct list_head ev_subs; + + __u32 id; + __u8 name[32]; + __u8 entity[16]; + __u8 selector; + + __u8 size; + __u8 offset; + enum v4l2_ctrl_type v4l2_type; + __u32 data_type; + + struct uvc_menu_info *menu_info; + __u32 menu_count; + + __u32 master_id; + __s32 master_manual; + __u32 slave_ids[2]; + + __s32 (*get) (struct uvc_control_mapping *mapping, __u8 query, + const __u8 *data); + void (*set) (struct uvc_control_mapping *mapping, __s32 value, + __u8 *data); +}; + +struct uvc_control { + struct uvc_entity *entity; + struct uvc_control_info info; + + __u8 index; /* Used to match the uvc_control entry with a + uvc_control_info. */ + __u8 dirty:1, + loaded:1, + modified:1, + cached:1, + initialized:1; + + __u8 *uvc_data; +}; + +struct uvc_format_desc { + char *name; + __u8 guid[16]; + __u32 fcc; +}; + +/* The term 'entity' refers to both UVC units and UVC terminals. + * + * The type field is either the terminal type (wTerminalType in the terminal + * descriptor), or the unit type (bDescriptorSubtype in the unit descriptor). + * As the bDescriptorSubtype field is one byte long, the type value will + * always have a null MSB for units. All terminal types defined by the UVC + * specification have a non-null MSB, so it is safe to use the MSB to + * differentiate between units and terminals as long as the descriptor parsing + * code makes sure terminal types have a non-null MSB. + * + * For terminals, the type's most significant bit stores the terminal + * direction (either UVC_TERM_INPUT or UVC_TERM_OUTPUT). The type field should + * always be accessed with the UVC_ENTITY_* macros and never directly. + */ + +#define UVC_ENTITY_FLAG_DEFAULT (1 << 0) + +struct uvc_entity { + struct list_head list; /* Entity as part of a UVC device. */ + struct list_head chain; /* Entity as part of a video device + * chain. */ + unsigned int flags; + + __u8 id; + __u16 type; + char name[64]; + + /* Media controller-related fields. */ + struct video_device *vdev; + struct v4l2_subdev subdev; + unsigned int num_pads; + unsigned int num_links; + struct media_pad *pads; + + union { + struct { + __u16 wObjectiveFocalLengthMin; + __u16 wObjectiveFocalLengthMax; + __u16 wOcularFocalLength; + __u8 bControlSize; + __u8 *bmControls; + } camera; + + struct { + __u8 bControlSize; + __u8 *bmControls; + __u8 bTransportModeSize; + __u8 *bmTransportModes; + } media; +#if 0 + struct { + } output; +#endif + struct { + __u16 wMaxMultiplier; + __u8 bControlSize; + __u8 *bmControls; + __u8 bmVideoStandards; + } processing; +#if 0 + struct { + } selector; +#endif + struct { + __u8 guidExtensionCode[16]; + __u8 bNumControls; + __u8 bControlSize; + __u8 *bmControls; + __u8 *bmControlsType; + } extension; + }; + + __u8 bNrInPins; + __u8 *baSourceID; + + unsigned int ncontrols; + struct uvc_control *controls; +}; + +// total (27)-> 28 Bytes +struct uvc_frame { + __u8 bFrameIndex; + __u8 bmCapabilities; + __u16 wWidth; + __u16 wHeight; + __u32 dwMinBitRate; + __u32 dwMaxBitRate; + __u32 dwMaxVideoFrameBufferSize; + __u8 bFrameIntervalType; + __u32 dwDefaultFrameInterval; + __u32 *dwFrameInterval; +}; + +// total 52 Bytes +struct uvc_format { + __u8 type; + __u8 index; + __u8 bpp; + __u8 colorspace; + __u32 fcc; + __u32 flags; + + char name[32]; + + unsigned int nframes; + struct uvc_frame *frame; +}; + +struct uvc_streaming_header { + __u8 bNumFormats; + __u8 bEndpointAddress; + __u8 bTerminalLink; + __u8 bControlSize; + __u8 *bmaControls; + /* The following fields are used by input headers only. */ + __u8 bmInfo; + __u8 bStillCaptureMethod; + __u8 bTriggerSupport; + __u8 bTriggerUsage; +}; + +enum uvc_buffer_state { + UVC_BUF_STATE_IDLE = 0, + UVC_BUF_STATE_QUEUED = 1, + UVC_BUF_STATE_ACTIVE = 2, + UVC_BUF_STATE_READY = 3, + UVC_BUF_STATE_DONE = 4, + UVC_BUF_STATE_ERROR = 5, +}; + +struct uvc_buffer { + struct vb2_buffer buf; + struct list_head queue; + _Mutex mutex; + enum uvc_buffer_state state; + unsigned int error; + + void *mem; + unsigned int length; + unsigned int bytesused; + + u32 pts; +}; + +#define UVC_QUEUE_DISCONNECTED (1 << 0) +#define UVC_QUEUE_DROP_CORRUPTED (1 << 1) + +struct uvc_video_queue { + struct vb2_queue queue; + //struct mutex mutex; /* Protects queue */ + _Mutex mutex; + unsigned int flags; + unsigned int buf_used; + + //spinlock_t irqlock; /* Protects irqqueue */ + //_LOCK_T irqlock; + _Mutex irqlock; + struct list_head irqqueue; +}; + +struct uvc_video_chain { + struct uvc_device *dev; + struct list_head list; + + struct list_head entities; /* All entities */ + struct uvc_entity *processing; /* Processing unit */ + struct uvc_entity *selector; /* Selector unit */ + + //struct mutex ctrl_mutex; /* Protects ctrl.info */ + _Mutex ctrl_mutex; + + struct v4l2_prio_state prio; /* V4L2 priority state */ + u32 caps; /* V4L2 chain-wide caps */ +}; + +struct uvc_stats_frame { + unsigned int size; /* Number of bytes captured */ + unsigned int first_data; /* Index of the first non-empty packet */ + + unsigned int nb_packets; /* Number of packets */ + unsigned int nb_empty; /* Number of empty packets */ + unsigned int nb_invalid; /* Number of packets with an invalid header */ + unsigned int nb_errors; /* Number of packets with the error bit set */ + + unsigned int nb_pts; /* Number of packets with a PTS timestamp */ + unsigned int nb_pts_diffs; /* Number of PTS differences inside a frame */ + unsigned int last_pts_diff; /* Index of the last PTS difference */ + bool has_initial_pts; /* Whether the first non-empty packet has a PTS */ + bool has_early_pts; /* Whether a PTS is present before the first non-empty packet */ + u32 pts; /* PTS of the last packet */ + + unsigned int nb_scr; /* Number of packets with a SCR timestamp */ + unsigned int nb_scr_diffs; /* Number of SCR.STC differences inside a frame */ + u16 scr_sof; /* SCR.SOF of the last packet */ + u32 scr_stc; /* SCR.STC of the last packet */ +}; + +struct uvc_stats_stream { + //struct timespec start_ts; /* Stream start timestamp */ + //struct timespec stop_ts; /* Stream stop timestamp */ + u32 start_ts; + u32 stop_ts; + + + unsigned int nb_frames; /* Number of frames */ + + unsigned int nb_packets; /* Number of packets */ + unsigned int nb_empty; /* Number of empty packets */ + unsigned int nb_invalid; /* Number of packets with an invalid header */ + unsigned int nb_errors; /* Number of packets with the error bit set */ + + unsigned int nb_pts_constant; /* Number of frames with constant PTS */ + unsigned int nb_pts_early; /* Number of frames with early PTS */ + unsigned int nb_pts_initial; /* Number of frames with initial PTS */ + + unsigned int nb_scr_count_ok; /* Number of frames with at least one SCR per non empty packet */ + unsigned int nb_scr_diffs_ok; /* Number of frames with varying SCR.STC */ + unsigned int scr_sof_count; /* STC.SOF counter accumulated since stream start */ + unsigned int scr_sof; /* STC.SOF of the last packet */ + unsigned int min_sof; /* Minimum STC.SOF value */ + unsigned int max_sof; /* Maximum STC.SOF value */ +}; + +struct uvc_streaming { + struct list_head list; + struct uvc_device *dev; + struct video_device *vdev; + struct uvc_video_chain *chain; + atomic_t active; + + struct usb_interface *intf; + int intfnum; + __u16 maxpsize; + + struct uvc_streaming_header header; + enum v4l2_buf_type type; + + unsigned int nformats; + struct uvc_format *format; + + struct uvc_streaming_control ctrl; + struct uvc_format *def_format; + struct uvc_format *cur_format; + struct uvc_frame *cur_frame; + /* Protect access to ctrl, cur_format, cur_frame and hardware video + * probe control. + */ + //struct mutex mutex; + _Mutex mutex; + + /* Buffers queue. */ + unsigned int frozen : 1; + struct uvc_video_queue queue; + void (*decode) (struct urb *urb, struct uvc_streaming *video, + struct uvc_buffer *buf); + + /* Context data used by the bulk completion handler. */ + struct { + __u8 header[256]; + unsigned int header_size; + int skip_payload; + __u32 payload_size; + __u32 max_payload_size; + } bulk; + + struct urb *urb[UVC_URBS]; + char *urb_buffer[UVC_URBS]; + dma_addr_t urb_dma[UVC_URBS]; + unsigned int urb_size; + + + + + + + __u32 sequence; + __u8 last_fid; + + /* debugfs */ + //struct dentry *debugfs_dir; + struct { + struct uvc_stats_frame frame; + struct uvc_stats_stream stream; + } stats; + + /* Timestamps support. */ + struct uvc_clock { + struct uvc_clock_sample { + u32 dev_stc; + u16 dev_sof; + //struct timespec host_ts; + u32 host_ts; //change to tick + u16 host_sof; + } *samples; + + unsigned int head; + unsigned int count; + unsigned int size; + + u16 last_sof; + u16 sof_offset; + + //spinlock_t lock; + _Lock lock; + } clock; +}; + +enum uvc_device_state { + UVC_DEV_DISCONNECTED = 1, +}; + +struct uvc_device { + struct usb_device *udev; + struct usb_interface *intf; + unsigned long warnings; + __u32 quirks; + int intfnum; + char name[32]; + + enum uvc_device_state state; + //struct mutex lock; /* Protects users */ + _Mutex lock; + unsigned int users; + atomic_t nmappings; + + /* Video control interface */ +#ifdef CONFIG_MEDIA_CONTROLLER + struct media_device mdev; +#endif + struct v4l2_device vdev; + __u16 uvc_version; + __u32 clock_frequency; + + struct list_head entities; // VC_EXTENSION_UNIT ->VC_INPUT_TERMINAL ->VC_PROCESSING_UNIT ->VC_OUTPUT_TERMINAL + struct list_head chains; + + /* Video Streaming interfaces */ + struct list_head streams; + atomic_t nstreams; + + /* Status Interrupt Endpoint */ + struct usb_host_endpoint *int_ep; + struct urb *int_urb; + __u8 *status; + //struct input_dev *input; + char input_phys[64]; +}; + +enum uvc_handle_state { + UVC_HANDLE_PASSIVE = 0, + UVC_HANDLE_ACTIVE = 1, +}; + +/* uvc file handle */ +struct uvc_fh { + struct v4l2_fh vfh; + struct uvc_video_chain *chain; + struct uvc_streaming *stream; + enum uvc_handle_state state; +}; +#if 0 +/* uvc_driver = usb_driver for interface + * - identifies USB interface driver to usbcore + */ +struct uvc_driver { + struct usb_driver driver; +}; +#endif + +/* ------------------------------------------------------------------------ + * Debugging, printing and logging + */ + +#define UVC_TRACE_PROBE (1 << 0) +#define UVC_TRACE_DESCR (1 << 1) +#define UVC_TRACE_CONTROL (1 << 2) +#define UVC_TRACE_FORMAT (1 << 3) +#define UVC_TRACE_CAPTURE (1 << 4) +#define UVC_TRACE_CALLS (1 << 5) +#define UVC_TRACE_IOCTL (1 << 6) +#define UVC_TRACE_FRAME (1 << 7) +#define UVC_TRACE_SUSPEND (1 << 8) +#define UVC_TRACE_STATUS (1 << 9) +#define UVC_TRACE_VIDEO (1 << 10) +#define UVC_TRACE_STATS (1 << 11) +#define UVC_TRACE_CLOCK (1 << 12) + +#define UVC_WARN_MINMAX 0 +#define UVC_WARN_PROBE_DEF 1 +#define UVC_WARN_XU_GET_RES 2 + +extern unsigned int uvc_clock_param; +extern unsigned int uvc_no_drop_param; +extern unsigned int uvc_trace_param; +extern unsigned int uvc_timeout_param; + +#if 0 +#define uvc_trace(flag, msg...) \ + do { \ + if (uvc_trace_param & flag) \ + printk(KERN_DEBUG "uvcvideo: " msg); \ + } while (0) + +#define uvc_warn_once(dev, warn, msg...) \ + do { \ + if (!test_and_set_bit(warn, &dev->warnings)) \ + printk(KERN_INFO "uvcvideo: " msg); \ + } while (0) + +#define uvc_printk(level, msg...) \ + printk(level "uvcvideo: " msg) +#endif + +/* -------------------------------------------------------------------------- + * Internal functions. + */ + +/* Core driver */ +extern struct uvc_driver uvc_driver; + +extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id); + +/* Video buffers queue management. */ +extern int uvc_queue_init(struct uvc_video_queue *queue, + enum v4l2_buf_type type, int drop_corrupted); +extern int uvc_alloc_buffers(struct uvc_video_queue *queue, + struct v4l2_requestbuffers *rb); +extern void uvc_free_buffers(struct uvc_video_queue *queue); +extern int uvc_query_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf); +extern int uvc_queue_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf); +extern int uvc_dequeue_buffer(struct uvc_video_queue *queue, + struct v4l2_buffer *v4l2_buf, int nonblocking); +extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); +extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); +extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, + struct uvc_buffer *buf); +extern int uvc_queue_mmap(struct uvc_video_queue *queue); +#if 0 +extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, + struct file *file, poll_table *wait); +#endif + +#ifndef CONFIG_MMU +extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, + unsigned long pgoff); +#endif + +extern int uvc_queue_allocated(struct uvc_video_queue *queue); +static inline int uvc_queue_streaming(struct uvc_video_queue *queue) +{ + return vb2_is_streaming(&queue->queue); +} + +/* V4L2 interface */ +extern const struct v4l2_file_operations uvc_fops; + +/* Media controller */ +extern int uvc_mc_register_entities(struct uvc_video_chain *chain); +extern void uvc_mc_cleanup_entity(struct uvc_entity *entity); + +/* Video */ +extern int uvc_video_init(struct uvc_streaming *stream); +extern int uvc_video_suspend(struct uvc_streaming *stream); +extern int uvc_video_resume(struct uvc_streaming *stream, int reset); +extern int uvc_video_enable(struct uvc_streaming *stream, int enable); +extern int uvc_probe_video(struct uvc_streaming *stream, + struct uvc_streaming_control *probe); +/* edit by Ian -- patch for GEO */ +extern int uvc_commit_video(struct uvc_streaming *stream, + struct uvc_streaming_control *probe); + +extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, + __u8 intfnum, __u8 cs, void *data, __u16 size); +/* edit by Ian -- disable uvc clock api*/ +#if 0 +void uvc_video_clock_update(struct uvc_streaming *stream, + struct v4l2_buffer *v4l2_buf, + struct uvc_buffer *buf); +#endif +/* Status */ +//#define UVC_STATUS_EN +#ifdef UVC_STATUS_EN +extern int uvc_status_init(struct uvc_device *dev); +extern void uvc_status_cleanup(struct uvc_device *dev); +extern int uvc_status_start(struct uvc_device *dev, gfp_t flags); +extern void uvc_status_stop(struct uvc_device *dev); +#endif + +/* Controls */ +extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops; + +extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, + struct v4l2_queryctrl *v4l2_ctrl); +extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, + struct v4l2_querymenu *query_menu); + +extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, + const struct uvc_control_mapping *mapping); +extern int uvc_ctrl_init_device(struct uvc_device *dev); +extern void uvc_ctrl_cleanup_device(struct uvc_device *dev); +extern int uvc_ctrl_resume_device(struct uvc_device *dev); +extern int uvc_ctrl_begin(struct uvc_video_chain *chain); +extern int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, + const struct v4l2_ext_control *xctrls, + unsigned int xctrls_count); +static inline int uvc_ctrl_commit(struct uvc_fh *handle, + const struct v4l2_ext_control *xctrls, + unsigned int xctrls_count) +{ + return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count); +} +static inline int uvc_ctrl_rollback(struct uvc_fh *handle) +{ + return __uvc_ctrl_commit(handle, 1, NULL, 0); +} + +extern int uvc_ctrl_get(struct uvc_video_chain *chain, + struct v4l2_ext_control *xctrl); +extern int uvc_ctrl_set(struct uvc_video_chain *chain, + struct v4l2_ext_control *xctrl); + +//edit by Ian -- remove uvc_xu_ctrl_query declaration +//extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); + +/* Utility functions */ +extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator, + unsigned int n_terms, unsigned int threshold); +extern uint32_t uvc_fraction_to_interval(uint32_t numerator, + uint32_t denominator); +extern struct usb_host_endpoint *uvc_find_endpoint( + struct usb_host_interface *alts, __u8 epaddr); + +/* Quirks support */ +void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, + struct uvc_buffer *buf); + +/* debugfs and statistics */ +#if 0 +int uvc_debugfs_init(void); +void uvc_debugfs_cleanup(void); +int uvc_debugfs_init_stream(struct uvc_streaming *stream); +void uvc_debugfs_cleanup_stream(struct uvc_streaming *stream); + +size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf, + size_t size); +#endif +#endif diff --git a/USDK/component/common/drivers/usb_class/host/uvc/inc/video.h b/USDK/component/common/drivers/usb_class/host/uvc/inc/video.h new file mode 100644 index 0000000..a73ac29 --- /dev/null +++ b/USDK/component/common/drivers/usb_class/host/uvc/inc/video.h @@ -0,0 +1,726 @@ +/* + * USB Video Class definitions. + * + * Copyright (C) 2009 Laurent Pinchart + * + * This file holds USB constants and structures defined by the USB Device + * Class Definition for Video Devices. Unless otherwise stated, comments + * below reference relevant sections of the USB Video Class 1.1 specification + * available at + * + * http://www.usb.org/developers/devclass_docs/USB_Video_Class_1_1.zip + */ + +#ifndef __LINUX_USB_VIDEO_H +#define __LINUX_USB_VIDEO_H +#if 0 +#include +#endif +#include "uvc_os_wrap_via_osdep_api.h" + +/* -------------------------------------------------------------------------- + * UVC constants + */ + +/* A.2. Video Interface Subclass Codes */ +#define UVC_SC_UNDEFINED 0x00 +#define UVC_SC_VIDEOCONTROL 0x01 +#define UVC_SC_VIDEOSTREAMING 0x02 +#define UVC_SC_VIDEO_INTERFACE_COLLECTION 0x03 + +/* A.3. Video Interface Protocol Codes */ +#define UVC_PC_PROTOCOL_UNDEFINED 0x00 + +/* A.5. Video Class-Specific VC Interface Descriptor Subtypes */ +#define UVC_VC_DESCRIPTOR_UNDEFINED 0x00 +#define UVC_VC_HEADER 0x01 +#define UVC_VC_INPUT_TERMINAL 0x02 +#define UVC_VC_OUTPUT_TERMINAL 0x03 +#define UVC_VC_SELECTOR_UNIT 0x04 +#define UVC_VC_PROCESSING_UNIT 0x05 +#define UVC_VC_EXTENSION_UNIT 0x06 + +/* A.6. Video Class-Specific VS Interface Descriptor Subtypes */ +#define UVC_VS_UNDEFINED 0x00 +#define UVC_VS_INPUT_HEADER 0x01 +#define UVC_VS_OUTPUT_HEADER 0x02 +#define UVC_VS_STILL_IMAGE_FRAME 0x03 +#define UVC_VS_FORMAT_UNCOMPRESSED 0x04 +#define UVC_VS_FRAME_UNCOMPRESSED 0x05 +#define UVC_VS_FORMAT_MJPEG 0x06 +#define UVC_VS_FRAME_MJPEG 0x07 +#define UVC_VS_FORMAT_MPEG2TS 0x0a +#define UVC_VS_FORMAT_DV 0x0c +#define UVC_VS_COLORFORMAT 0x0d +#define UVC_VS_FORMAT_FRAME_BASED 0x10 +#define UVC_VS_FRAME_FRAME_BASED 0x11 +#define UVC_VS_FORMAT_STREAM_BASED 0x12 + +/* A.7. Video Class-Specific Endpoint Descriptor Subtypes */ +#define UVC_EP_UNDEFINED 0x00 +#define UVC_EP_GENERAL 0x01 +#define UVC_EP_ENDPOINT 0x02 +#define UVC_EP_INTERRUPT 0x03 + +/* A.8. Video Class-Specific Request Codes */ +#define UVC_RC_UNDEFINED 0x00 +#define UVC_SET_CUR 0x01 +#define UVC_GET_CUR 0x81 +#define UVC_GET_MIN 0x82 +#define UVC_GET_MAX 0x83 +#define UVC_GET_RES 0x84 +#define UVC_GET_LEN 0x85 +#define UVC_GET_INFO 0x86 +#define UVC_GET_DEF 0x87 + +/* A.9.1. VideoControl Interface Control Selectors */ +#define UVC_VC_CONTROL_UNDEFINED 0x00 +#define UVC_VC_VIDEO_POWER_MODE_CONTROL 0x01 +#define UVC_VC_REQUEST_ERROR_CODE_CONTROL 0x02 + +/* A.9.2. Terminal Control Selectors */ +#define UVC_TE_CONTROL_UNDEFINED 0x00 + +/* A.9.3. Selector Unit Control Selectors */ +#define UVC_SU_CONTROL_UNDEFINED 0x00 +#define UVC_SU_INPUT_SELECT_CONTROL 0x01 + +/* A.9.4. Camera Terminal Control Selectors */ +#define UVC_CT_CONTROL_UNDEFINED 0x00 +#define UVC_CT_SCANNING_MODE_CONTROL 0x01 +#define UVC_CT_AE_MODE_CONTROL 0x02 +#define UVC_CT_AE_PRIORITY_CONTROL 0x03 +#define UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 +#define UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 +#define UVC_CT_FOCUS_ABSOLUTE_CONTROL 0x06 +#define UVC_CT_FOCUS_RELATIVE_CONTROL 0x07 +#define UVC_CT_FOCUS_AUTO_CONTROL 0x08 +#define UVC_CT_IRIS_ABSOLUTE_CONTROL 0x09 +#define UVC_CT_IRIS_RELATIVE_CONTROL 0x0a +#define UVC_CT_ZOOM_ABSOLUTE_CONTROL 0x0b +#define UVC_CT_ZOOM_RELATIVE_CONTROL 0x0c +#define UVC_CT_PANTILT_ABSOLUTE_CONTROL 0x0d +#define UVC_CT_PANTILT_RELATIVE_CONTROL 0x0e +#define UVC_CT_ROLL_ABSOLUTE_CONTROL 0x0f +#define UVC_CT_ROLL_RELATIVE_CONTROL 0x10 +#define UVC_CT_PRIVACY_CONTROL 0x11 + +/* A.9.5. Processing Unit Control Selectors */ +#define UVC_PU_CONTROL_UNDEFINED 0x00 +#define UVC_PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 +#define UVC_PU_BRIGHTNESS_CONTROL 0x02 +#define UVC_PU_CONTRAST_CONTROL 0x03 +#define UVC_PU_GAIN_CONTROL 0x04 +#define UVC_PU_POWER_LINE_FREQUENCY_CONTROL 0x05 +#define UVC_PU_HUE_CONTROL 0x06 +#define UVC_PU_SATURATION_CONTROL 0x07 +#define UVC_PU_SHARPNESS_CONTROL 0x08 +#define UVC_PU_GAMMA_CONTROL 0x09 +#define UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a +#define UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b +#define UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c +#define UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d +#define UVC_PU_DIGITAL_MULTIPLIER_CONTROL 0x0e +#define UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f +#define UVC_PU_HUE_AUTO_CONTROL 0x10 +#define UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 +#define UVC_PU_ANALOG_LOCK_STATUS_CONTROL 0x12 + +/* A.9.7. VideoStreaming Interface Control Selectors */ +#define UVC_VS_CONTROL_UNDEFINED 0x00 +#define UVC_VS_PROBE_CONTROL 0x01 +#define UVC_VS_COMMIT_CONTROL 0x02 +#define UVC_VS_STILL_PROBE_CONTROL 0x03 +#define UVC_VS_STILL_COMMIT_CONTROL 0x04 +#define UVC_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 +#define UVC_VS_STREAM_ERROR_CODE_CONTROL 0x06 +#define UVC_VS_GENERATE_KEY_FRAME_CONTROL 0x07 +#define UVC_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 +#define UVC_VS_SYNC_DELAY_CONTROL 0x09 + +/* B.1. USB Terminal Types */ +#define UVC_TT_VENDOR_SPECIFIC 0x0100 +#define UVC_TT_STREAMING 0x0101 + +/* B.2. Input Terminal Types */ +#define UVC_ITT_VENDOR_SPECIFIC 0x0200 +#define UVC_ITT_CAMERA 0x0201 +#define UVC_ITT_MEDIA_TRANSPORT_INPUT 0x0202 + +/* B.3. Output Terminal Types */ +#define UVC_OTT_VENDOR_SPECIFIC 0x0300 +#define UVC_OTT_DISPLAY 0x0301 +#define UVC_OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 + +/* B.4. External Terminal Types */ +#define UVC_EXTERNAL_VENDOR_SPECIFIC 0x0400 +#define UVC_COMPOSITE_CONNECTOR 0x0401 +#define UVC_SVIDEO_CONNECTOR 0x0402 +#define UVC_COMPONENT_CONNECTOR 0x0403 + +/* 2.4.2.2. Status Packet Type */ +#define UVC_STATUS_TYPE_CONTROL 1 +#define UVC_STATUS_TYPE_STREAMING 2 + +/* 2.4.3.3. Payload Header Information */ +#define UVC_STREAM_EOH (1 << 7) +#define UVC_STREAM_ERR (1 << 6) +#define UVC_STREAM_STI (1 << 5) +#define UVC_STREAM_RES (1 << 4) +#define UVC_STREAM_SCR (1 << 3) +#define UVC_STREAM_PTS (1 << 2) +#define UVC_STREAM_EOF (1 << 1) +#define UVC_STREAM_FID (1 << 0) + +/* 4.1.2. Control Capabilities */ +#define UVC_CONTROL_CAP_GET (1 << 0) +#define UVC_CONTROL_CAP_SET (1 << 1) +#define UVC_CONTROL_CAP_DISABLED (1 << 2) +#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3) +#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4) + +/* ------------------------------------------------------------------------ + * UVC structures + */ + +/* All UVC descriptors have these 3 fields at the beginning */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_descriptor_header { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; +} //__attribute__((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/* 3.7.2. Video Control Interface Header Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_header_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u16 bcdUVC; + __u16 wTotalLength; + __u32 dwClockFrequency; + __u8 bInCollection; + __u8 baInterfaceNr[]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_HEADER_SIZE(n) (12+(n)) + +#define UVC_HEADER_DESCRIPTOR(n) \ + uvc_header_descriptor_##n + +#define DECLARE_UVC_HEADER_DESCRIPTOR(n) \ +struct UVC_HEADER_DESCRIPTOR(n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u16 bcdUVC; \ + __u16 wTotalLength; \ + __u32 dwClockFrequency; \ + __u8 bInCollection; \ + __u8 baInterfaceNr[n]; \ +} __attribute__ ((packed)) + +/* 3.7.2.1. Input Terminal Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_input_terminal_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 iTerminal; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_INPUT_TERMINAL_SIZE 8 + +/* 3.7.2.2. Output Terminal Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_output_terminal_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 bSourceID; + __u8 iTerminal; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_OUTPUT_TERMINAL_SIZE 9 + +/* 3.7.2.3. Camera Terminal Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_camera_terminal_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bTerminalID; + __u16 wTerminalType; + __u8 bAssocTerminal; + __u8 iTerminal; + __u16 wObjectiveFocalLengthMin; + __u16 wObjectiveFocalLengthMax; + __u16 wOcularFocalLength; + __u8 bControlSize; + __u8 bmControls[3]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_CAMERA_TERMINAL_SIZE(n) (15+(n)) + +/* 3.7.2.4. Selector Unit Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_selector_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bUnitID; + __u8 bNrInPins; +// __u8 baSourceID[0]; + __u8 * baSourceID; + __u8 iSelector; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_SELECTOR_UNIT_SIZE(n) (6+(n)) + +#define UVC_SELECTOR_UNIT_DESCRIPTOR(n) \ + uvc_selector_unit_descriptor_##n + +#define DECLARE_UVC_SELECTOR_UNIT_DESCRIPTOR(n) \ +struct UVC_SELECTOR_UNIT_DESCRIPTOR(n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bUnitID; \ + __u8 bNrInPins; \ + __u8 baSourceID[n]; \ + __u8 iSelector; \ +} __attribute__ ((packed)) + +/* 3.7.2.5. Processing Unit Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_processing_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bUnitID; + __u8 bSourceID; + __u16 wMaxMultiplier; + __u8 bControlSize; + __u8 bmControls[2]; + __u8 iProcessing; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_PROCESSING_UNIT_SIZE(n) (9+(n)) + +/* 3.7.2.6. Extension Unit Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_extension_unit_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bUnitID; + __u8 guidExtensionCode[16]; + __u8 bNumControls; + __u8 bNrInPins; +// __u8 baSourceID[0]; + __u8 * baSourceID; + __u8 bControlSize; +// __u8 bmControls[0]; + __u8 * bmControls; + __u8 iExtension; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_EXTENSION_UNIT_SIZE(p, n) (24+(p)+(n)) + +#define UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \ + uvc_extension_unit_descriptor_##p_##n + +#define DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) \ +struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bUnitID; \ + __u8 guidExtensionCode[16]; \ + __u8 bNumControls; \ + __u8 bNrInPins; \ + __u8 baSourceID[p]; \ + __u8 bControlSize; \ + __u8 bmControls[n]; \ + __u8 iExtension; \ +} __attribute__ ((packed)) + +/* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_control_endpoint_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u16 wMaxTransferSize; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_CONTROL_ENDPOINT_SIZE 5 + +/* 3.9.2.1. Input Header Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_input_header_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bNumFormats; + __u16 wTotalLength; + __u8 bEndpointAddress; + __u8 bmInfo; + __u8 bTerminalLink; + __u8 bStillCaptureMethod; + __u8 bTriggerSupport; + __u8 bTriggerUsage; + __u8 bControlSize; + __u8 bmaControls[]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_INPUT_HEADER_SIZE(n, p) (13+(n*p)) + +#define UVC_INPUT_HEADER_DESCRIPTOR(n, p) \ + uvc_input_header_descriptor_##n_##p + +#define DECLARE_UVC_INPUT_HEADER_DESCRIPTOR(n, p) \ +struct UVC_INPUT_HEADER_DESCRIPTOR(n, p) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bNumFormats; \ + __u16 wTotalLength; \ + __u8 bEndpointAddress; \ + __u8 bmInfo; \ + __u8 bTerminalLink; \ + __u8 bStillCaptureMethod; \ + __u8 bTriggerSupport; \ + __u8 bTriggerUsage; \ + __u8 bControlSize; \ + __u8 bmaControls[p][n]; \ +} __attribute__ ((packed)) + +/* 3.9.2.2. Output Header Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_output_header_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bNumFormats; + __u16 wTotalLength; + __u8 bEndpointAddress; + __u8 bTerminalLink; + __u8 bControlSize; + __u8 bmaControls[]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_OUTPUT_HEADER_SIZE(n, p) (9+(n*p)) + +#define UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \ + uvc_output_header_descriptor_##n_##p + +#define DECLARE_UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) \ +struct UVC_OUTPUT_HEADER_DESCRIPTOR(n, p) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bNumFormats; \ + __u16 wTotalLength; \ + __u8 bEndpointAddress; \ + __u8 bTerminalLink; \ + __u8 bControlSize; \ + __u8 bmaControls[p][n]; \ +} __attribute__ ((packed)) + +/* 3.9.2.6. Color matching descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_color_matching_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bColorPrimaries; + __u8 bTransferCharacteristics; + __u8 bMatrixCoefficients; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_COLOR_MATCHING_SIZE 6 + +/* 4.3.1.1. Video Probe and Commit Controls */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_streaming_control { + __u16 bmHint; + __u8 bFormatIndex; + __u8 bFrameIndex; + __u32 dwFrameInterval; + __u16 wKeyFrameRate; + __u16 wPFrameRate; + __u16 wCompQuality; + __u16 wCompWindowSize; + __u16 wDelay; + __u32 dwMaxVideoFrameSize; + __u32 dwMaxPayloadTransferSize; + __u32 dwClockFrequency; + __u8 bmFramingInfo; + __u8 bPreferedVersion; + __u8 bMinVersion; + __u8 bMaxVersion; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/* Uncompressed Payload - 3.1.1. Uncompressed Video Format Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_format_uncompressed { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFormatIndex; + __u8 bNumFrameDescriptors; + __u8 guidFormat[16]; + __u8 bBitsPerPixel; + __u8 bDefaultFrameIndex; + __u8 bAspectRatioX; + __u8 bAspectRatioY; + __u8 bmInterfaceFlags; + __u8 bCopyProtect; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_FORMAT_UNCOMPRESSED_SIZE 27 + +/* Uncompressed Payload - 3.1.2. Uncompressed Video Frame Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_frame_uncompressed { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFrameIndex; + __u8 bmCapabilities; + __u16 wWidth; + __u16 wHeight; + __u32 dwMinBitRate; + __u32 dwMaxBitRate; + __u32 dwMaxVideoFrameBufferSize; + __u32 dwDefaultFrameInterval; + __u8 bFrameIntervalType; + __u32 dwFrameInterval[]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_FRAME_UNCOMPRESSED_SIZE(n) (26+4*(n)) + +#define UVC_FRAME_UNCOMPRESSED(n) \ + uvc_frame_uncompressed_##n + +#define DECLARE_UVC_FRAME_UNCOMPRESSED(n) \ +struct UVC_FRAME_UNCOMPRESSED(n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bFrameIndex; \ + __u8 bmCapabilities; \ + __u16 wWidth; \ + __u16 wHeight; \ + __u32 dwMinBitRate; \ + __u32 dwMaxBitRate; \ + __u32 dwMaxVideoFrameBufferSize; \ + __u32 dwDefaultFrameInterval; \ + __u8 bFrameIntervalType; \ + __u32 dwFrameInterval[n]; \ +} __attribute__ ((packed)) + +/* MJPEG Payload - 3.1.1. MJPEG Video Format Descriptor */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct uvc_format_mjpeg { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFormatIndex; + __u8 bNumFrameDescriptors; + __u8 bmFlags; + __u8 bDefaultFrameIndex; + __u8 bAspectRatioX; + __u8 bAspectRatioY; + __u8 bmInterfaceFlags; + __u8 bCopyProtect; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_FORMAT_MJPEG_SIZE 11 +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +/* MJPEG Payload - 3.1.2. MJPEG Video Frame Descriptor */ + +struct uvc_frame_mjpeg { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + __u8 bFrameIndex; + __u8 bmCapabilities; + __u16 wWidth; + __u16 wHeight; + __u32 dwMinBitRate; + __u32 dwMaxBitRate; + __u32 dwMaxVideoFrameBufferSize; + __u32 dwDefaultFrameInterval; + __u8 bFrameIntervalType; + __u32 dwFrameInterval[]; +} //__attribute__((__packed__)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define UVC_DT_FRAME_MJPEG_SIZE(n) (26+4*(n)) + +#define UVC_FRAME_MJPEG(n) \ + uvc_frame_mjpeg_##n + +#define DECLARE_UVC_FRAME_MJPEG(n) \ +struct UVC_FRAME_MJPEG(n) { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubType; \ + __u8 bFrameIndex; \ + __u8 bmCapabilities; \ + __u16 wWidth; \ + __u16 wHeight; \ + __u32 dwMinBitRate; \ + __u32 dwMaxBitRate; \ + __u32 dwMaxVideoFrameBufferSize; \ + __u32 dwDefaultFrameInterval; \ + __u8 bFrameIntervalType; \ + __u32 dwFrameInterval[n]; \ +} __attribute__ ((packed)) + +#endif /* __LINUX_USB_VIDEO_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/HalPwrSeqCmd.h b/USDK/component/common/drivers/wlan/realtek/include/HalPwrSeqCmd.h new file mode 100644 index 0000000..51b8210 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/HalPwrSeqCmd.h @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HALPWRSEQCMD_H__ +#define __HALPWRSEQCMD_H__ + +/*---------------------------------------------*/ +//3 The value of cmd: 4 bits +/*---------------------------------------------*/ +#define PWR_CMD_READ 0x00 + // offset: the read register offset + // msk: the mask of the read value + // value: N/A, left by 0 + // note: dirver shall implement this function by read & msk + +#define PWR_CMD_WRITE 0x01 + // offset: the read register offset + // msk: the mask of the write bits + // value: write value + // note: driver shall implement this cmd by read & msk after write + +#define PWR_CMD_POLLING 0x02 + // offset: the read register offset + // msk: the mask of the polled value + // value: the value to be polled, masked by the msd field. + // note: driver shall implement this cmd by + // do{ + // if( (Read(offset) & msk) == (value & msk) ) + // break; + // } while(not timeout); + +#define PWR_CMD_DELAY 0x03 + // offset: the value to delay + // msk: N/A + // value: the unit of delay, 0: us, 1: ms + +#define PWR_CMD_END 0x04 + // offset: N/A + // msk: N/A + // value: N/A + +/*---------------------------------------------*/ +//3 The value of base: 4 bits +/*---------------------------------------------*/ + // define the base address of each block +#define PWR_BASEADDR_MAC 0x00 +#define PWR_BASEADDR_USB 0x01 +#define PWR_BASEADDR_PCIE 0x02 +#define PWR_BASEADDR_SDIO 0x03 + +/*---------------------------------------------*/ +//3 The value of interface_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_INTF_SDIO_MSK BIT(0) +#define PWR_INTF_USB_MSK BIT(1) +#define PWR_INTF_PCI_MSK BIT(2) +#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of fab_msk: 4 bits +/*---------------------------------------------*/ +#define PWR_FAB_TSMC_MSK BIT(0) +#define PWR_FAB_UMC_MSK BIT(1) +#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) + +/*---------------------------------------------*/ +//3 The value of cut_msk: 8 bits +/*---------------------------------------------*/ +#define PWR_CUT_TESTCHIP_MSK BIT(0) +#define PWR_CUT_A_MSK BIT(1) +#define PWR_CUT_B_MSK BIT(2) +#define PWR_CUT_C_MSK BIT(3) +#define PWR_CUT_D_MSK BIT(4) +#define PWR_CUT_E_MSK BIT(5) +#define PWR_CUT_F_MSK BIT(6) +#define PWR_CUT_G_MSK BIT(7) +#define PWR_CUT_ALL_MSK 0xFF + + +typedef enum _PWRSEQ_CMD_DELAY_UNIT_ +{ + PWRSEQ_DELAY_US, + PWRSEQ_DELAY_MS, +} PWRSEQ_DELAY_UNIT; + +typedef struct _WL_PWR_CFG_ +{ + u16 offset; + u8 cut_msk; + u8 fab_msk:4; + u8 interface_msk:4; + u8 base:4; + u8 cmd:4; + u8 msk; + u8 value; +} WLAN_PWR_CFG, *PWLAN_PWR_CFG; + + +#define GET_PWR_CFG_OFFSET(__PWR_CMD) __PWR_CMD.offset +#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) __PWR_CMD.cut_msk +#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) __PWR_CMD.fab_msk +#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) __PWR_CMD.interface_msk +#define GET_PWR_CFG_BASE(__PWR_CMD) __PWR_CMD.base +#define GET_PWR_CFG_CMD(__PWR_CMD) __PWR_CMD.cmd +#define GET_PWR_CFG_MASK(__PWR_CMD) __PWR_CMD.msk +#define GET_PWR_CFG_VALUE(__PWR_CMD) __PWR_CMD.value + + +//================================================================================ +// Prototype of protected function. +//================================================================================ +u8 HalPwrSeqCmdParsing( + _adapter * padapter, + u8 CutVersion, + u8 FabVersion, + u8 InterfaceType, + WLAN_PWR_CFG PwrCfgCmd[]); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/HalVerDef.h b/USDK/component/common/drivers/wlan/realtek/include/HalVerDef.h new file mode 100644 index 0000000..bdb0f06 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/HalVerDef.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_VERSION_DEF_H__ +#define __HAL_VERSION_DEF_H__ + +#ifndef TRUE +#define TRUE _TRUE +#endif +#ifndef FALSE +#define FALSE _FALSE +#endif + +// HAL_IC_TYPE_E +typedef enum tag_HAL_IC_Type_Definition +{ + CHIP_8192S = 0, + CHIP_8188C = 1, + CHIP_8192C = 2, + CHIP_8192D = 3, + CHIP_8723A = 4, + CHIP_8188E = 5, + CHIP_8812 = 6, + CHIP_8821 = 7, + CHIP_8723B = 8, + CHIP_8192E = 9, + CHIP_8195A = 10, + CHIP_8710B = 11, + CHIP_8188F = 12, +}HAL_IC_TYPE_E; + +//HAL_CHIP_TYPE_E +typedef enum tag_HAL_CHIP_Type_Definition +{ + TEST_CHIP = 0, + NORMAL_CHIP = 1, + FPGA = 2, +}HAL_CHIP_TYPE_E; + +//HAL_CUT_VERSION_E +typedef enum tag_HAL_Cut_Version_Definition +{ + A_CUT_VERSION = 0, + B_CUT_VERSION = 1, + C_CUT_VERSION = 2, + D_CUT_VERSION = 3, + E_CUT_VERSION = 4, + F_CUT_VERSION = 5, + G_CUT_VERSION = 6, + H_CUT_VERSION = 7, + I_CUT_VERSION = 8, + J_CUT_VERSION = 9, + K_CUT_VERSION = 10, +}HAL_CUT_VERSION_E; + +// HAL_Manufacturer +typedef enum tag_HAL_Manufacturer_Version_Definition +{ + CHIP_VENDOR_TSMC = 0, + CHIP_VENDOR_UMC = 1, + CHIP_VENDOR_SMIC = 2, +}HAL_VENDOR_E; + +typedef enum tag_HAL_RF_Type_Definition +{ + RF_TYPE_1T1R = 0, + RF_TYPE_1T2R = 1, + RF_TYPE_2T2R = 2, + RF_TYPE_2T3R = 3, + RF_TYPE_2T4R = 4, + RF_TYPE_3T3R = 5, + RF_TYPE_3T4R = 6, + RF_TYPE_4T4R = 7, +}HAL_RF_TYPE_E; + +typedef struct tag_HAL_VERSION +{ + HAL_IC_TYPE_E ICType; + HAL_CHIP_TYPE_E ChipType; + HAL_CUT_VERSION_E CUTVersion; + HAL_VENDOR_E VendorType; + HAL_RF_TYPE_E RFType; + u8 ROMVer; +}HAL_VERSION,*PHAL_VERSION; + +//VERSION_8192C VersionID; +//HAL_VERSION VersionID; + +// Get element +#define GET_CVID_IC_TYPE(version) ((HAL_IC_TYPE_E)((version).ICType) ) +#define GET_CVID_CHIP_TYPE(version) ((HAL_CHIP_TYPE_E)((version).ChipType) ) +#define GET_CVID_RF_TYPE(version) ((HAL_RF_TYPE_E)((version).RFType)) +#define GET_CVID_MANUFACTUER(version) ((HAL_VENDOR_E)((version).VendorType)) +#define GET_CVID_CUT_VERSION(version) ((HAL_CUT_VERSION_E)((version).CUTVersion)) +#define GET_CVID_ROM_VERSION(version) (((version).ROMVer) & ROM_VERSION_MASK) + +//---------------------------------------------------------------------------- +//Common Macro. -- +//---------------------------------------------------------------------------- +//HAL_VERSION VersionID + +// HAL_IC_TYPE_E +#define IS_81XXC(version) (((GET_CVID_IC_TYPE(version) == CHIP_8192C)||(GET_CVID_IC_TYPE(version) == CHIP_8188C))? TRUE : FALSE) +#define IS_8723_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723A)? TRUE : FALSE) +#define IS_92D(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192D)? TRUE : FALSE) +#define IS_8188E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188E)? TRUE : FALSE) +#define IS_8192E(version) ((GET_CVID_IC_TYPE(version) == CHIP_8192E)? TRUE : FALSE) +#define IS_8812_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8812)? TRUE : FALSE) +#define IS_8821_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8821)? TRUE : FALSE) +#define IS_8723B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8723B)? TRUE : FALSE) +#define IS_8710B_SERIES(version) ((GET_CVID_IC_TYPE(version) == CHIP_8710B)? TRUE : FALSE) +#define IS_8188F(version) ((GET_CVID_IC_TYPE(version) == CHIP_8188F)? TRUE : FALSE) + +//HAL_CHIP_TYPE_E +#define IS_TEST_CHIP(version) ((GET_CVID_CHIP_TYPE(version)==TEST_CHIP)? TRUE: FALSE) +#define IS_NORMAL_CHIP(version) ((GET_CVID_CHIP_TYPE(version)==NORMAL_CHIP)? TRUE: FALSE) + +//HAL_CUT_VERSION_E +#define IS_A_CUT(version) ((GET_CVID_CUT_VERSION(version) == A_CUT_VERSION) ? TRUE : FALSE) +#define IS_B_CUT(version) ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? TRUE : FALSE) +#define IS_C_CUT(version) ((GET_CVID_CUT_VERSION(version) == C_CUT_VERSION) ? TRUE : FALSE) +#define IS_D_CUT(version) ((GET_CVID_CUT_VERSION(version) == D_CUT_VERSION) ? TRUE : FALSE) +#define IS_E_CUT(version) ((GET_CVID_CUT_VERSION(version) == E_CUT_VERSION) ? TRUE : FALSE) +#define IS_I_CUT(version) ((GET_CVID_CUT_VERSION(version) == I_CUT_VERSION) ? TRUE : FALSE) +#define IS_J_CUT(version) ((GET_CVID_CUT_VERSION(version) == J_CUT_VERSION) ? TRUE : FALSE) +#define IS_K_CUT(version) ((GET_CVID_CUT_VERSION(version) == K_CUT_VERSION) ? TRUE : FALSE) + +//HAL_VENDOR_E +#define IS_CHIP_VENDOR_TSMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_TSMC)? TRUE: FALSE) +#define IS_CHIP_VENDOR_UMC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_UMC)? TRUE: FALSE) +#define IS_CHIP_VENDOR_SMIC(version) ((GET_CVID_MANUFACTUER(version) == CHIP_VENDOR_SMIC)? TRUE: FALSE) + +//HAL_RF_TYPE_E +#define IS_1T1R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T1R)? TRUE : FALSE ) +#define IS_1T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_1T2R)? TRUE : FALSE) +#define IS_2T2R(version) ((GET_CVID_RF_TYPE(version) == RF_TYPE_2T2R)? TRUE : FALSE) + + +//---------------------------------------------------------------------------- +//Chip version Macro. -- +//---------------------------------------------------------------------------- +#define IS_81XXC_TEST_CHIP(version) ((IS_81XXC(version) && (!IS_NORMAL_CHIP(version)))? TRUE: FALSE) + +#define IS_92C_SERIAL(version) ((IS_81XXC(version) && IS_2T2R(version)) ? TRUE : FALSE) +#define IS_81xxC_VENDOR_UMC_A_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_A_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) +#define IS_81xxC_VENDOR_UMC_B_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_B_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) +#define IS_81xxC_VENDOR_UMC_C_CUT(version) (IS_81XXC(version)?(IS_CHIP_VENDOR_UMC(version) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE): FALSE) + +#define IS_NORMAL_CHIP92D(version) (( IS_92D(version))?((GET_CVID_CHIP_TYPE(version)==NORMAL_CHIP)? TRUE: FALSE):FALSE) + +#define IS_92D_SINGLEPHY(version) ((IS_92D(version)) ? (IS_2T2R(version) ? TRUE: FALSE) : FALSE) +#define IS_92D_C_CUT(version) ((IS_92D(version)) ? (IS_C_CUT(version) ? TRUE : FALSE) : FALSE) +#define IS_92D_D_CUT(version) ((IS_92D(version)) ? (IS_D_CUT(version) ? TRUE : FALSE) : FALSE) +#define IS_92D_E_CUT(version) ((IS_92D(version)) ? (IS_E_CUT(version) ? TRUE : FALSE) : FALSE) + +#define IS_8723A_A_CUT(version) ((IS_8723_SERIES(version)) ? ( IS_A_CUT(version)?TRUE : FALSE) : FALSE) +#define IS_8723A_B_CUT(version) ((IS_8723_SERIES(version)) ? ( IS_B_CUT(version)?TRUE : FALSE) : FALSE) + +#define IS_VENDOR_8188E_I_CUT_SERIES(_Adapter) ((IS_8188E(GET_HAL_DATA(_Adapter)->VersionID)) ? ((GET_CVID_CUT_VERSION(GET_HAL_DATA(_Adapter)->VersionID) >= I_CUT_VERSION) ? TRUE : FALSE) : FALSE) + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/autoconf.h b/USDK/component/common/drivers/wlan/realtek/include/autoconf.h new file mode 100644 index 0000000..45c290d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/autoconf.h @@ -0,0 +1,515 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef WLANCONFIG_H +#define WLANCONFIG_H + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) || defined(CONFIG_HARDWARE_8188F) +#include "platform_opts.h" +#endif + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#define CONFIG_PLATFORM_AMEBA_X +#endif + +#if !defined(CONFIG_PLATFORM_AMEBA_X) +#define PLATFORM_FREERTOS 1 +#define CONFIG_GSPI_HCI +#else +#define CONFIG_LX_HCI +#endif + +#ifndef CONFIG_INIC_EN +#define CONFIG_INIC_EN 0 //For iNIC project +#endif + +#if CONFIG_INIC_EN +#define CONFIG_LWIP_LAYER 0 +#endif + +#define CONFIG_LITTLE_ENDIAN +#define CONFIG_80211N_HT +//#define CONFIG_RECV_REORDERING_CTRL +#define RTW_NOTCH_FILTER 0 +#define CONFIG_EMBEDDED_FWIMG +#define CONFIG_PHY_SETTING_WITH_ODM +#if !defined(CONFIG_PLATFORM_AMEBA_X) +#define CONFIG_ODM_REFRESH_RAMASK +#define HAL_MAC_ENABLE 1 +#define HAL_BB_ENABLE 1 +#define HAL_RF_ENABLE 1 +#endif +#if defined(CONFIG_PLATFORM_AMEBA_X) +/* Patch when dynamic mechanism is not ready */ +//#define CONFIG_DM_PATCH +#endif + +//#define CONFIG_DEBUG +//#define CONFIG_DEBUG_RTL871X +#if defined(CONFIG_PLATFORM_AMEBA_X) + #define CONFIG_MEM_MONITOR MEM_MONITOR_SIMPLE + #define WLAN_INTF_DBG 0 + //#define CONFIG_DEBUG_DYNAMIC + //#define DBG_TX 1 + //#define DBG_XMIT_BUF 1 + //#define DBG_XMIT_BUF_EXT 1 + #define DBG_TX_DROP_FRAME +#else + #define CONFIG_MEM_MONITOR MEM_MONITOR_LEAK + //#define CONFIG_TRACE_SKB + //#define WLAN_INTF_DBG +#endif // CONFIG_PLATFORM_AMEBA_X + +//#define CONFIG_DONT_CARE_TP +//#define CONFIG_HIGH_TP +//#define CONFIG_MEMORY_ACCESS_ALIGNED +#ifndef PLATFORM_CMSIS_RTOS // unsupported feature +#define CONFIG_POWER_SAVING +#endif +#ifdef CONFIG_POWER_SAVING + #define CONFIG_IPS + #define CONFIG_LPS + //#define CONFIG_LPS_LCLK + #define CONFIG_LPS_32K + #define TDMA_POWER_SAVING + #define CONFIG_WAIT_PS_ACK +#endif + +#define BAD_MIC_COUNTERMEASURE 1 +#define DEFRAGMENTATION 1 + +#define WIFI_LOGO_CERTIFICATION 0 +#if WIFI_LOGO_CERTIFICATION + #define RX_AGGREGATION 1 + #define RX_AMSDU 1 +#else + #define RX_AGGREGATION 0 + #define RX_AMSDU 0 +#endif + +#if defined(CONFIG_PLATFORM_AMEBA_X) + #if !defined(CONFIG_PLATFORM_8711B) + #ifndef CONFIG_USE_TCM_HEAP + #define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */ + #endif + #endif + #define CONFIG_RECV_TASKLET_THREAD + #define CONFIG_XMIT_TASKLET_THREAD +#else + #define CONFIG_XMIT_THREAD_MODE +#endif // CONFIG_PLATFORM_AMEBA_X +//#define CONFIG_RECV_THREAD_MODE /* Wlan IRQ Polling Mode*/ +//#define CONFIG_ISR_THREAD_MODE_POLLING /* Wlan IRQ Polling Mode*/ + +//1 Chris +#ifndef CONFIG_SDIO_HCI +#define CONFIG_ISR_THREAD_MODE_INTERRUPT /* Wlan IRQ Interrupt Mode*/ +#endif + +#if defined(CONFIG_ISR_THREAD_MODE_POLLING) && defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) +#error "CONFIG_ISR_THREAD_MODE_POLLING and CONFIG_ISR_THREAD_MODE_INTERRUPT are mutually exclusive. " +#endif + +#if defined(CONFIG_PLATFORM_AMEBA_X) +/* CRC DMEM optimized mode consume 1k less SRM memory consumption */ +#define CRC_IMPLEMENTATION_MODE CRC_IMPLEMENTATION_DMEM_OPTIMIZED +#endif + +/* AES DMEM optimized mode comsume 10k less memory compare to + IMEM optimized mode AES_IMPLEMENTATION_IMEM_OPTIMIZED */ +#define AES_IMPLEMENTATION_MODE AES_IMPLEMENTATION_DMEM_OPTIMIZED + +#define USE_SKB_AS_XMITBUF 1 +#if defined(CONFIG_PLATFORM_AMEBA_X) +#define USE_XMIT_EXTBUFF 1 +#else +#define USE_XMIT_EXTBUFF 0 +#endif +#define USE_MUTEX_FOR_SPINLOCK 1 + +// remove function to reduce code +#define NOT_SUPPORT_5G +#define NOT_SUPPORT_RF_MULTIPATH +#define NOT_SUPPORT_VHT +#define NOT_SUPPORT_40M +#define NOT_SUPPORT_80M +#ifndef CONFIG_PLATFORM_8711B +#define NOT_SUPPORT_BBSWING +#endif +#define NOT_SUPPORT_OLD_CHANNEL_PLAN +#define NOT_SUPPORT_BT + +#define CONFIG_WIFI_SPEC 0 +#define CONFIG_FAKE_EFUSE 0 +#if CONFIG_FAKE_EFUSE + #define FAKE_CHIPID CHIPID_8710BN +#endif + +#define CONFIG_AUTO_RECONNECT 1 +#define ENABLE_HWPDN_PIN +#define SUPPORT_SCAN_BUF 1 +#if !defined(CONFIG_PLATFORM_AMEBA_X) +#define BE_I_CUT 1 +#endif + +/* For WPA2 */ +#define CONFIG_INCLUDE_WPA_PSK +#ifdef CONFIG_INCLUDE_WPA_PSK +#define CONFIG_MULTIPLE_WPA_STA +//#define CONFIG_WPA2_PREAUTH +#define PSK_SUPPORT_TKIP 1 +#endif +//#define AP_PSK_SUPPORT_TKIP + +/* For promiscuous mode */ +#define CONFIG_PROMISC + +#define PROMISC_DENY_PAIRWISE 0 + +/* For Simple Link */ +#ifndef CONFIG_INCLUDE_SIMPLE_CONFIG +//#define CONFIG_INCLUDE_SIMPLE_CONFIG 1 +#endif + +// for probe request with custom vendor specific IE +#define CONFIG_CUSTOM_IE + +#if !defined(CONFIG_PLATFORM_AMEBA_X) +/* For multicast */ +#define CONFIG_MULTICAST +#endif + +/* For STA+AP Concurrent MODE */ +#define CONFIG_CONCURRENT_MODE +#ifdef CONFIG_CONCURRENT_MODE + #if defined(CONFIG_PLATFORM_8195A) + #define CONFIG_RUNTIME_PORT_SWITCH + #endif + #if defined(CONFIG_HARDWARE_8188F) + #define NET_IF_NUM 2 + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1) + #endif +#else + #if defined(CONFIG_HARDWARE_8188F) + #define NET_IF_NUM 1 + #else + #define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN)) + #endif +#endif + + +/****************** For EAP auth configurations *******************/ +#define CONFIG_TLS 0 +#define CONFIG_PEAP 0 +#define CONFIG_TTLS 0 + +// DO NOT change the below config of EAP +#ifdef PRE_CONFIG_EAP +#define CONFIG_TLS 1 +#define CONFIG_PEAP 1 +#define CONFIG_TTLS 1 +#endif + +// enable 1X code in lib_wlan as default (increase 380 bytes) +#ifndef PLATFORM_CMSIS_RTOS // unsupported feature +#define CONFIG_EAP +#endif +#if CONFIG_TLS || CONFIG_PEAP || CONFIG_TTLS +#define EAP_REMOVE_UNUSED_CODE 1 +#endif + +#define EAP_SSL_VERIFY_SERVER + +#if CONFIG_TLS +#define EAP_SSL_VERIFY_CLIENT +#endif + +#if CONFIG_TTLS +#define EAP_MSCHAPv2 +#define EAP_TTLS_MSCHAPv2 +//#define EAP_TTLS_EAP +//#define EAP_TTLS_MSCHAP +//#define EAP_TTLS_PAP +//#define EAP_TTLS_CHAP +#endif +/****************** End of EAP configurations *******************/ + +/* For WPS and P2P */ +#define CONFIG_WPS +#if 0 +#define CONFIG_WPS_AP +#define CONFIG_P2P_NEW +#if (!defined(SUPPORT_SCAN_BUF)||!defined(CONFIG_WPS_AP)) && defined(CONFIG_P2P_NEW) +#error "If CONFIG_P2P_NEW, need to SUPPORT_SCAN_BUF" +#endif +#endif + +#define CONFIG_NEW_SIGNAL_STAT_PROCESS +#define CONFIG_SKIP_SIGNAL_SCALE_MAPPING + +/* For AP_MODE */ +#define CONFIG_AP_MODE +extern unsigned char g_user_ap_sta_num; +#define USER_AP_STA_NUM g_user_ap_sta_num +#if defined(CONFIG_PLATFORM_AMEBA_X) +#define AP_STA_NUM 3 //2014/10/27 modify to 3 +#define USE_DEDICATED_BCN_TX 0 +#if USE_DEDICATED_BCN_TX +#error "WLAN driver for Ameba should not enable USE_DEDICATED_BCN_TX" +#endif +#else +extern unsigned int g_ap_sta_num; +#define AP_STA_NUM 3//g_ap_sta_num +#endif +#ifdef CONFIG_AP_MODE +#if defined(CONFIG_PLATFORM_8195A) + //softap sent qos null0 polling client alive or not + #define CONFIG_AP_POLLING_CLIENT_ALIVE +#endif + #define CONFIG_NATIVEAP_MLME +#if defined(CONFIG_PLATFORM_AMEBA_X) + #define CONFIG_INTERRUPT_BASED_TXBCN +#endif + #ifdef CONFIG_INTERRUPT_BASED_TXBCN + //#define CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + #define CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + #endif +// #define CONFIG_GK_REKEY +#if !defined(CONFIG_PLATFORM_AMEBA_X) + #define USE_DEDICATED_BCN_TX 1 +#endif +#if CONFIG_INIC_EN +// #define REPORT_STA_EVENT //useless +#endif +#else +#if !defined(CONFIG_PLATFORM_AMEBA_X) + #define USE_DEDICATED_BCN_TX 0 +#endif +#endif + +#if defined(CONFIG_AP_MODE) && defined(CONFIG_GK_REKEY) && !defined(CONFIG_MULTIPLE_WPA_STA) +#error "If CONFIG_GK_REKEY when CONFIG_AP_MODE, need to CONFIG_MULTIPLE_WPA_STA" +#endif + +#if !defined(CONFIG_PLATFORM_AMEBA_X) +#if !defined(CONFIG_AP_MODE) && defined(CONFIG_CONCURRENT_MODE) +#error "If CONFIG_CONCURRENT_MODEE, need to CONFIG_AP_MODE" +#endif +#endif + +/* For efuse or flash config */ +#if defined(CONFIG_PLATFORM_AMEBA_X) + #define CONFIG_RW_PHYSICAL_EFUSE 0 // Mask efuse user blocks + #define CONFIG_HIDE_PROTECT_EFUSE 1 + #define CONFIG_ADAPTOR_INFO_CACHING_FLASH 1 + #define CHECK_FLASH_VALID_MASK 1 + #define CHECK_EFUSE_VALID_MASK 1 + /* For K-free */ +// #if !defined(CONFIG_PLATFORM_8711B) + #define CONFIG_RF_GAIN_OFFSET +// #endif +#endif // CONFIG_PLATFORM_AMEBA_X + +/* For MP_MODE */ +//#define CONFIG_MP_INCLUDED +#ifdef CONFIG_MP_INCLUDED + #define MP_DRIVER 1 + #define CONFIG_MP_IWPRIV_SUPPORT +// #define HAL_EFUSE_MEMORY + #if defined(CONFIG_PLATFORM_AMEBA_X) + #define MP_REG_TEST + #endif +#else + #define MP_DRIVER 0 + #if defined(CONFIG_PLATFORM_8195A) + //Control wifi mcu function + #define CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD + #define CONFIG_ODM_REFRESH_RAMASK + #endif +#endif // #ifdef CONFIG_MP_INCLUDED + +#if defined(CONFIG_PLATFORM_AMEBA_X) + #if defined(CONFIG_PLATFORM_8195A) + #undef CONFIG_RTL8195A + #define CONFIG_RTL8195A + #endif + #if defined(CONFIG_PLATFORM_8711B) + #ifndef CONFIG_RTL8711B + #define CONFIG_RTL8711B + #endif + #undef CONFIG_ADAPTOR_INFO_CACHING_FLASH + #define CONFIG_ADAPTOR_INFO_CACHING_FLASH 0 + //#undef CONFIG_EAP + //#undef CONFIG_IPS + #define CONFIG_8710B_MOVE_TO_ROM + #define CONFIG_EFUSE_SEPARATE + #define CONFIG_MOVE_PSK_TO_ROM + #define CONFIG_WOWLAN + #define CONFIG_TRAFFIC_PROTECT + #endif +#elif defined(CONFIG_HARDWARE_8188F) +#define CONFIG_RTL8188F +#else +#define CONFIG_RTL8188E +#endif +#define RTL8192C_SUPPORT 0 +#define RTL8192CE_SUPPORT 0 +#define RTL8192CU_SUPPORT 0 +#define RTL8192D_SUPPORT 0 +#define RTL8192DE_SUPPORT 0 +#define RTL8192DU_SUPPORT 0 +#define RTL8723A_SUPPORT 0 +#define RTL8723AU_SUPPORT 0 +#define RTL8723AS_SUPPORT 0 +#define RTL8192E_SUPPORT 0 +#define RTL8812A_SUPPORT 0 +#define RTL8821A_SUPPORT 0 +#define RTL8723B_SUPPORT 0 +#define RTL8195A_SUPPORT 0 +#define RTL8188E_SUPPORT 0 +#define RTL8188F_SUPPORT 0 +#define RTL8711B_SUPPORT 0 +#if defined(CONFIG_PLATFORM_8195A) +#undef RTL8195A_SUPPORT +#define RTL8195A_SUPPORT 1 +#elif defined(CONFIG_PLATFORM_8711B) +#undef RTL8711B_SUPPORT +#define RTL8711B_SUPPORT 1 +#elif defined(CONFIG_HARDWARE_8188F) +#undef RTL8188F_SUPPORT +#define RTL8188F_SUPPORT 1 +#else +#undef RTL8188E_SUPPORT +#define RTL8188E_SUPPORT 1 +#endif + +#define TEST_CHIP_SUPPORT 0 + +#define RTL8188E_FOR_TEST_CHIP 0 +#define RTL8188E_FPGA_TRUE_PHY_VERIFICATION 0 + +// for Debug message +#define DBG 0 +#if defined(CONFIG_PLATFORM_AMEBA_X) +#if(DBG == 0) + #define ROM_E_RTW_MSG 1 + /* For DM debug*/ + // BB + #define DBG_RX_INFO 1 + #define DBG_TX_RATE 1 // DebugComponents: bit9 + #define DBG_DM_RA 1 // DebugComponents: bit9 + #define DBG_DM_DIG 1 // DebugComponents: bit0 + #define DBG_DM_ADAPTIVITY 1 // DebugComponents: bit16 + // RF + #define DBG_PWR_TRACKING 1 // DebugComponents: bit24 + #define DBG_RF_IQK 1 // DebugComponents: bit26 + // Common + #define DBG_PWR_INDEX 1 // DebugComponents: bit30 +#endif +#endif + +/* For DM support */ +#if defined(CONFIG_RTL8188F) +#define RATE_ADAPTIVE_SUPPORT 0 +#elif defined(CONFIG_PLATFORM_8711B) +#define RATE_ADAPTIVE_SUPPORT 1 +#define CONFIG_ODM_REFRESH_RAMASK +#else +#define RATE_ADAPTIVE_SUPPORT 1 +#endif +// adaptivity +#define RTW_ADAPTIVITY_EN_DISABLE 0 +#define RTW_ADAPTIVITY_EN_ENABLE 1 +#define CONFIG_RTW_ADAPTIVITY_EN RTW_ADAPTIVITY_EN_DISABLE +#define RTW_ADAPTIVITY_MODE_NORMAL 0 +#define RTW_ADAPTIVITY_MODE_CARRIER_SENSE 1 +#define CONFIG_RTW_ADAPTIVITY_MODE RTW_ADAPTIVITY_MODE_CARRIER_SENSE +#define CONFIG_RTW_ADAPTIVITY_DML 0 + + +#if defined(CONFIG_PLATFORM_AMEBA_X) + #define CONFIG_POWER_TRAINING_WIL 0 // in RA +#else + #define POWER_BY_RATE_SUPPORT 0 +#endif + +#if defined(CONFIG_PLATFORM_AMEBA_X) +#define RTL8195A_FOR_TEST_CHIP 0 + +//#define CONFIG_WIFI_TEST 1 +//#define CONFIG_MAC_LOOPBACK_DRIVER 1 +//#define CONFIG_WLAN_HAL_TEST 1 +//#define SKB_PRE_ALLOCATE_TX 1 +#define SKB_PRE_ALLOCATE_RX 0 +#define TX_CHECK_DSEC_ALWAYS 1 +#define CONFIG_DBG_DISABLE_RDU_INTERRUPT +//#define CONFIG_WLAN_HAL_RX_TASK +#if (SKB_PRE_ALLOCATE_RX == 1) + #define EXCHANGE_LXBUS_RX_SKB 0 +#endif +#ifdef CONFIG_FPGA + //Enable mac loopback for test mode (Ameba) + #define CONFIG_TWO_MAC_DRIVER // for test mode +#endif + +#ifdef ENABLE_MAC_LB_FOR_TEST_MODE + #define CONFIG_SUDO_PHY_SETTING + #define INT_HANDLE_IN_ISR 1 + #define CONFIG_LWIP_LAYER 0 + #define CONFIG_WLAN_HAL_TEST + #define CONFIG_WLAN_HAL_RX_TASK + #define CONFIG_MAC_LOOPBACK_DRIVER_RTL8711B 1 + #define HAL_MAC_ENABLE 1 + #define CONFIG_TWO_MAC_TEST_MODE + #define DISABLE_BB_RF 1 +#else + //#define CONFIG_TWO_MAC_DRIVER //for mornal driver; two mac + #ifdef CONFIG_TWO_MAC_DRIVER + #define CONFIG_SUDO_PHY_SETTING + #define HAL_MAC_ENABLE 1 + #define DISABLE_BB_RF 1 + #else + #define HAL_MAC_ENABLE 1 + #define HAL_BB_ENABLE 1 + #define HAL_RF_ENABLE 1 + #define DISABLE_BB_RF 0 + #endif + //#define INT_HANDLE_IN_ISR 1 +#endif +#endif // CONFIG_PLATFORM_AMEBA_X + +#ifndef CONFIG_LWIP_LAYER +#define CONFIG_LWIP_LAYER 1 +#endif +#define CONFIG_MAC_ADDRESS 0 +//fast reconnection +//#define CONFIG_FAST_RECONNECTION 1 +#if defined(CONFIG_INIC_EN)&&(CONFIG_INIC_EN==1) +#define CONFIG_RECV_REORDERING_CTRL //enable reordering for iNIC high throughput +#undef RX_AGGREGATION +#define RX_AGGREGATION 1 +#undef NOT_SUPPORT_40M +#undef CONFIG_CONCURRENT_MODE +#endif +#endif //WLANCONFIG_H diff --git a/USDK/component/common/drivers/wlan/realtek/include/byteorder/generic.h b/USDK/component/common/drivers/wlan/realtek/include/byteorder/generic.h new file mode 100644 index 0000000..13fdbf3 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/byteorder/generic.h @@ -0,0 +1,223 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _LINUX_BYTEORDER_GENERIC_H +#define _LINUX_BYTEORDER_GENERIC_H + +/* + * linux/byteorder_generic.h + * Generic Byte-reordering support + * + * Francois-Rene Rideau 19970707 + * gathered all the good ideas from all asm-foo/byteorder.h into one file, + * cleaned them up. + * I hope it is compliant with non-GCC compilers. + * I decided to put __BYTEORDER_HAS_U64__ in byteorder.h, + * because I wasn't sure it would be ok to put it in types.h + * Upgraded it to 2.1.43 + * Francois-Rene Rideau 19971012 + * Upgraded it to 2.1.57 + * to please Linus T., replaced huge #ifdef's between little/big endian + * by nestedly #include'd files. + * Francois-Rene Rideau 19971205 + * Made it to 2.1.71; now a facelift: + * Put files under include/linux/byteorder/ + * Split swab from generic support. + * + * TODO: + * = Regular kernel maintainers could also replace all these manual + * byteswap macros that remain, disseminated among drivers, + * after some grep or the sources... + * = Linus might want to rename all these macros and files to fit his taste, + * to fit his personal naming scheme. + * = it seems that a few drivers would also appreciate + * nybble swapping support... + * = every architecture could add their byteswap macro in asm/byteorder.h + * see how some architectures already do (i386, alpha, ppc, etc) + * = cpu_to_beXX and beXX_to_cpu might some day need to be well + * distinguished throughout the kernel. This is not the case currently, + * since little endian, big endian, and pdp endian machines needn't it. + * But this might be the case for, say, a port of Linux to 20/21 bit + * architectures (and F21 Linux addict around?). + */ + +/* + * The following macros are to be defined by : + * + * Conversion of long and short int between network and host format + * ntohl(__u32 x) + * ntohs(__u16 x) + * htonl(__u32 x) + * htons(__u16 x) + * It seems that some programs (which? where? or perhaps a standard? POSIX?) + * might like the above to be functions, not macros (why?). + * if that's true, then detect them, and take measures. + * Anyway, the measure is: define only ___ntohl as a macro instead, + * and in a separate file, have + * unsigned long inline ntohl(x){return ___ntohl(x);} + * + * The same for constant arguments + * __constant_ntohl(__u32 x) + * __constant_ntohs(__u16 x) + * __constant_htonl(__u32 x) + * __constant_htons(__u16 x) + * + * Conversion of XX-bit integers (16- 32- or 64-) + * between native CPU format and little/big endian format + * 64-bit stuff only defined for proper architectures + * cpu_to_[bl]eXX(__uXX x) + * [bl]eXX_to_cpu(__uXX x) + * + * The same, but takes a pointer to the value to convert + * cpu_to_[bl]eXXp(__uXX x) + * [bl]eXX_to_cpup(__uXX x) + * + * The same, but change in situ + * cpu_to_[bl]eXXs(__uXX x) + * [bl]eXX_to_cpus(__uXX x) + * + * See asm-foo/byteorder.h for examples of how to provide + * architecture-optimized versions + * + */ + + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) || defined(PLATFORM_MPIXEL) || defined(PLATFORM_FREEBSD) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +/* + * inside the kernel, we can use nicknames; + * outside of it, we must avoid POSIX namespace pollution... + */ + +//TODO +#if 0 + +#define cpu_to_le64 __cpu_to_le64 +#define le64_to_cpu __le64_to_cpu + +#endif //#if 0 + +#define cpu_to_le32 __cpu_to_le32 +#define le32_to_cpu __le32_to_cpu +#define cpu_to_le16 __cpu_to_le16 +#define le16_to_cpu __le16_to_cpu +#define cpu_to_be64 __cpu_to_be64 +#define be64_to_cpu __be64_to_cpu +#define cpu_to_be32 __cpu_to_be32 +#define be32_to_cpu __be32_to_cpu +#define cpu_to_be16 __cpu_to_be16 +#define be16_to_cpu __be16_to_cpu +#define cpu_to_le64p __cpu_to_le64p +#define le64_to_cpup __le64_to_cpup +#define cpu_to_le32p __cpu_to_le32p +#define le32_to_cpup __le32_to_cpup +#define cpu_to_le16p __cpu_to_le16p +#define le16_to_cpup __le16_to_cpup +#define cpu_to_be64p __cpu_to_be64p +#define be64_to_cpup __be64_to_cpup +#define cpu_to_be32p __cpu_to_be32p +#define be32_to_cpup __be32_to_cpup +#define cpu_to_be16p __cpu_to_be16p +#define be16_to_cpup __be16_to_cpup +#define cpu_to_le64s __cpu_to_le64s +#define le64_to_cpus __le64_to_cpus +#define cpu_to_le32s __cpu_to_le32s +#define le32_to_cpus __le32_to_cpus +#define cpu_to_le16s __cpu_to_le16s +#define le16_to_cpus __le16_to_cpus +#define cpu_to_be64s __cpu_to_be64s +#define be64_to_cpus __be64_to_cpus +#define cpu_to_be32s __cpu_to_be32s +#define be32_to_cpus __be32_to_cpus +#define cpu_to_be16s __cpu_to_be16s +#define be16_to_cpus __be16_to_cpus +#endif + +//TODO +#if 0 + +/* + * Handle ntohl and suches. These have various compatibility + * issues - like we want to give the prototype even though we + * also have a macro for them in case some strange program + * wants to take the address of the thing or something.. + * + * Note that these used to return a "long" in libc5, even though + * long is often 64-bit these days.. Thus the casts. + * + * They have to be macros in order to do the constant folding + * correctly - if the argument passed into a inline function + * it is no longer constant according to gcc.. + */ + +#undef ntohl +#undef ntohs +#undef htonl +#undef htons + +/* + * Do the prototypes. Somebody might want to take the + * address or some such sick thing.. + */ +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +extern __u32 ntohl(__u32); +extern __u32 htonl(__u32); +#else //defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#ifndef PLATFORM_FREEBSD +extern unsigned long int ntohl(unsigned long int); +extern unsigned long int htonl(unsigned long int); +#endif +#endif +#ifndef PLATFORM_FREEBSD +extern unsigned short int ntohs(unsigned short int); +extern unsigned short int htons(unsigned short int); +#endif + +#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__) || defined(PLATFORM_MPIXEL) + +#define ___htonl(x) __cpu_to_be32(x) +#define ___htons(x) __cpu_to_be16(x) +#define ___ntohl(x) __be32_to_cpu(x) +#define ___ntohs(x) __be16_to_cpu(x) + +#if defined(PLATFORM_LINUX) || (defined (__GLIBC__) && __GLIBC__ >= 2) +#define htonl(x) ___htonl(x) +#define ntohl(x) ___ntohl(x) +#else +#define htonl(x) ((unsigned long)___htonl(x)) +#define ntohl(x) ((unsigned long)___ntohl(x)) +#endif +#define htons(x) ___htons(x) +#define ntohs(x) ___ntohs(x) + +#endif /* OPTIMIZE */ + + +#if defined (PLATFORM_WINDOWS) + +#define htonl(x) __cpu_to_be32(x) +#define ntohl(x) __be32_to_cpu(x) +#define htons(x) __cpu_to_be16(x) +#define ntohs(x) __be16_to_cpu(x) + +#endif + +#endif //#if 0 + +#endif /* _LINUX_BYTEORDER_GENERIC_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/byteorder/little_endian.h b/USDK/component/common/drivers/wlan/realtek/include/byteorder/little_endian.h new file mode 100644 index 0000000..6c12102 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/byteorder/little_endian.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H +#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 1234 +#endif +#ifndef __LITTLE_ENDIAN_BITFIELD +#define __LITTLE_ENDIAN_BITFIELD +#endif + +#include + +#ifndef __constant_htonl + +//TODO +#if 0 + +#define __constant_htonl(x) ___constant_swab32((x)) +#define __constant_ntohl(x) ___constant_swab32((x)) +#define __constant_htons(x) ___constant_swab16((x)) +#define __constant_ntohs(x) ___constant_swab16((x)) +#define __constant_cpu_to_le64(x) ((__u64)(x)) +#define __constant_le64_to_cpu(x) ((__u64)(x)) +#define __constant_cpu_to_le32(x) ((__u32)(x)) +#define __constant_le32_to_cpu(x) ((__u32)(x)) +#define __constant_cpu_to_le16(x) ((__u16)(x)) +#define __constant_le16_to_cpu(x) ((__u16)(x)) +#define __constant_cpu_to_be64(x) ___constant_swab64((x)) +#define __constant_be64_to_cpu(x) ___constant_swab64((x)) +#define __constant_cpu_to_be32(x) ___constant_swab32((x)) +#define __constant_be32_to_cpu(x) ___constant_swab32((x)) +#define __constant_cpu_to_be16(x) ___constant_swab16((x)) +#define __constant_be16_to_cpu(x) ___constant_swab16((x)) +#define __cpu_to_le64(x) ((__u64)(x)) +#define __le64_to_cpu(x) ((__u64)(x)) + +#endif //#if 0 + +#define __cpu_to_le32(x) ((__u32)(x)) +#define __le32_to_cpu(x) ((__u32)(x)) +#define __cpu_to_le16(x) ((__u16)(x)) +#define __le16_to_cpu(x) ((__u16)(x)) +#define __cpu_to_be64(x) __swab64((x)) +#define __be64_to_cpu(x) __swab64((x)) +#define __cpu_to_be32(x) __swab32((x)) +#define __be32_to_cpu(x) __swab32((x)) +#define __cpu_to_be16(x) __swab16((x)) +#define __be16_to_cpu(x) __swab16((x)) +#define __cpu_to_le64p(x) (*(__u64*)(x)) +#define __le64_to_cpup(x) (*(__u64*)(x)) +#define __cpu_to_le32p(x) (*(__u32*)(x)) +#define __le32_to_cpup(x) (*(__u32*)(x)) +#define __cpu_to_le16p(x) (*(__u16*)(x)) +#define __le16_to_cpup(x) (*(__u16*)(x)) +#define __cpu_to_be64p(x) __swab64p((x)) +#define __be64_to_cpup(x) __swab64p((x)) +#define __cpu_to_be32p(x) __swab32p((x)) +#define __be32_to_cpup(x) __swab32p((x)) +#define __cpu_to_be16p(x) __swab16p((x)) +#define __be16_to_cpup(x) __swab16p((x)) +#define __cpu_to_le64s(x) do {} while (0) +#define __le64_to_cpus(x) do {} while (0) +#define __cpu_to_le32s(x) do {} while (0) +#define __le32_to_cpus(x) do {} while (0) +#define __cpu_to_le16s(x) do {} while (0) +#define __le16_to_cpus(x) do {} while (0) +#define __cpu_to_be64s(x) __swab64s((x)) +#define __be64_to_cpus(x) __swab64s((x)) +#define __cpu_to_be32s(x) __swab32s((x)) +#define __be32_to_cpus(x) __swab32s((x)) +#define __cpu_to_be16s(x) __swab16s((x)) +#define __be16_to_cpus(x) __swab16s((x)) +#endif // __constant_htonl + +#include + +#endif /* _LINUX_BYTEORDER_LITTLE_ENDIAN_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/byteorder/swab.h b/USDK/component/common/drivers/wlan/realtek/include/byteorder/swab.h new file mode 100644 index 0000000..a956a0b --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/byteorder/swab.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _LINUX_BYTEORDER_SWAB_H +#define _LINUX_BYTEORDER_SWAB_H +/* +#if !defined(CONFIG_PLATFORM_MSTAR_TITANIA12) && !defined(PLATFORM_ECOS) && \ + !defined(CONFIG_PLATFORM_8195A) +*/ +#if !defined(CONFIG_PLATFORM_MSTAR_TITANIA12) && !defined(PLATFORM_ECOS) + +#if !defined(PLATFORM_FREERTOS) && !defined (PLATFORM_CMSIS_RTOS) +#ifndef __u16 +typedef unsigned short __u16; +#endif + +#ifndef __u32 +typedef unsigned int __u32; +#endif + +#ifndef __u8 +typedef unsigned char __u8; +#endif + +#ifndef __u64 +typedef unsigned long long __u64; +#endif +#endif +__inline static __u16 ___swab16(__u16 x) +{ + __u16 __x = x; + return + ((__u16)( + (((__u16)(__x) & (__u16)0x00ffU) << 8) | + (((__u16)(__x) & (__u16)0xff00U) >> 8) )); + +} + +__inline static __u32 ___swab32(__u32 x) +{ + __u32 __x = (x); + return ((__u32)( + (((__u32)(__x) & (__u32)0x000000ffUL) << 24) | + (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | + (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | + (((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); +} + +__inline static __u64 ___swab64(__u64 x) +{ + __u64 __x = (x); + + return + ((__u64)( \ + (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \ + (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \ + (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \ + (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \ +} +#endif // CONFIG_PLATFORM_MSTAR_TITANIA12 + +#ifndef __arch__swab16 +__inline static __u16 __arch__swab16(__u16 x) +{ + return ___swab16(x); +} + +#endif + +#ifndef __arch__swab32 +__inline static __u32 __arch__swab32(__u32 x) +{ + __u32 __tmp = (x) ; + return ___swab32(__tmp); +} +#endif + +#ifndef __arch__swab64 + +__inline static __u64 __arch__swab64(__u64 x) +{ + __u64 __tmp = (x) ; + return ___swab64(__tmp); +} + + +#endif + +#ifndef __swab16 +#define __swab16(x) __fswab16(x) +#define __swab32(x) __fswab32(x) +#define __swab64(x) __fswab64(x) +#endif // __swab16 + +#ifdef PLATFORM_FREEBSD +__inline static __u16 __fswab16(__u16 x) +#else +__inline static __u16 __fswab16(__u16 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab16(x); +} +#ifdef PLATFORM_FREEBSD +__inline static __u32 __fswab32(__u32 x) +#else +__inline static __u32 __fswab32(__u32 x) +#endif //PLATFORM_FREEBSD +{ + return __arch__swab32(x); +} + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_WINDOWS) +#define swab16 __swab16 +#define swab32 __swab32 +#define swab64 __swab64 +#define swab16p __swab16p +#define swab32p __swab32p +#define swab64p __swab64p +#define swab16s __swab16s +#define swab32s __swab32s +#define swab64s __swab64s +#endif + +#endif /* _LINUX_BYTEORDER_SWAB_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/drv_conf.h b/USDK/component/common/drivers/wlan/realtek/include/drv_conf.h new file mode 100644 index 0000000..3590c04 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/drv_conf.h @@ -0,0 +1,106 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __DRV_CONF_H__ +#define __DRV_CONF_H__ + +#include "autoconf.h" +#if ((RTL8195A_SUPPORT==1) || (RTL8711B_SUPPORT==1)) +#include "platform_autoconf.h" +#endif + +#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS) + +#error "Shall be Linux or Windows, but not both!\n" + +#endif + +//Older Android kernel doesn't has CONFIG_ANDROID defined, +//add this to force CONFIG_ANDROID defined +#ifdef CONFIG_PLATFORM_ANDROID +#define CONFIG_ANDROID +#endif + +#ifdef CONFIG_ANDROID +//Some Android build will restart the UI while non-printable ascii is passed +//between java and c/c++ layer (JNI). We force CONFIG_VALIDATE_SSID +//for Android here. If you are sure there is no risk on your system about this, +//mask this macro define to support non-printable ascii ssid. +//#define CONFIG_VALIDATE_SSID +#ifdef CONFIG_PLATFORM_ARM_SUNxI + #ifdef CONFIG_VALIDATE_SSID + #undef CONFIG_VALIDATE_SSID + #endif +#endif + +//Android expect dbm as the rx signal strength unit +#define CONFIG_SIGNAL_DISPLAY_DBM +#endif + +#if defined(CONFIG_HAS_EARLYSUSPEND) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_HAS_EARLYSUSPEND enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif + +#if defined(CONFIG_ANDROID_POWER) && defined (CONFIG_RESUME_IN_WORKQUEUE) + #warning "You have CONFIG_ANDROID_POWER enabled in your system, we disable CONFIG_RESUME_IN_WORKQUEUE automatically" + #undef CONFIG_RESUME_IN_WORKQUEUE +#endif + +#ifdef CONFIG_RESUME_IN_WORKQUEUE //this can be removed, because there is no case for this... + #if !defined( CONFIG_WAKELOCK) && !defined(CONFIG_ANDROID_POWER) + #error "enable CONFIG_RESUME_IN_WORKQUEUE without CONFIG_WAKELOCK or CONFIG_ANDROID_POWER will suffer from the danger of wifi's unfunctionality..." + #error "If you still want to enable CONFIG_RESUME_IN_WORKQUEUE in this case, mask this preprossor checking and GOOD LUCK..." + #endif +#endif + +//About USB VENDOR REQ +#if defined(CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif +#if defined(CONFIG_VENDOR_REQ_RETRY) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX) + #warning "define CONFIG_USB_VENDOR_REQ_MUTEX for CONFIG_VENDOR_REQ_RETRY automatically" + #define CONFIG_USB_VENDOR_REQ_MUTEX +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_EN + #define CONFIG_RTW_ADAPTIVITY_EN 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_MODE + #define CONFIG_RTW_ADAPTIVITY_MODE 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_DML + #define CONFIG_RTW_ADAPTIVITY_DML 0 +#endif + +#ifndef CONFIG_RTW_ADAPTIVITY_DC_BACKOFF + #define CONFIG_RTW_ADAPTIVITY_DC_BACKOFF 4 +#endif + +#ifndef CONFIG_RTW_NHM_EN + #define CONFIG_RTW_NHM_EN 0 +#endif + +//#include + +#endif // __DRV_CONF_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/drv_types.h b/USDK/component/common/drivers/wlan/realtek/include/drv_types.h new file mode 100644 index 0000000..49bedcc --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/drv_types.h @@ -0,0 +1,863 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +/*------------------------------------------------------------------------------- + + For type defines and data structure defines + +--------------------------------------------------------------------------------*/ + + +#ifndef __DRV_TYPES_H__ +#define __DRV_TYPES_H__ + +#include + + +#ifdef PLATFORM_OS_XP +#include +#endif + +#ifdef PLATFORM_OS_CE +#include +#endif + +#ifdef PLATFORM_LINUX +#include +#endif + + +#if defined (__ICCARM__) +#define _PACKED __packed +#define _WEAK __weak +#else +#define _PACKED __attribute__ ((packed)) +#define _WEAK __attribute__ ((weak)) +#endif + +// Assign memory sectinon usage +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#include +//#include "rtl_utility_ram.h" +#include "platform/platform_stdlib.h" +#else +#define SRAM_BD_DATA_SECTION +#define WLAN_ROM_TEXT_SECTION +#define WLAN_ROM_DATA_SECTION +#define _LONG_CALL_ +#endif + +#ifdef CONFIG_TRACE_SKB +#define SKBLIST_ALL 0xFFFFFFFF +// receive +#define SKBLIST_RECVBUF_MASK 0x0000000F +#define SKBLIST_RECVBUF 0x00000001 +#define SKBLIST_RECVBUF_FREEQUEUE 0x00000002 +#define SKBLIST_RECVBUF_PENDINGQUEUE 0x00000004 + +#define SKBLIST_RECVFRAME_MASK 0x000000F0 +#define SKBLIST_RECVFRAME 0x00000010 +#define SKBLIST_RECVFRAME_FREEQUEUE 0x00000020 +#define SKBLIST_RECVFRAME_SWDECQUEUE 0x00000040 +#ifdef CONFIG_RECV_REORDERING_CTRL +#define SKBLIST_RECVFRAME_REORDERQUEUE 0x00000080 +#endif + +// transmit +#define SKBLIST_XMITBUF_MASK 0x0000FF00 +#define SKBLIST_XMITBUF 0x00000100 +#define SKBLIST_XMITEXTBUF 0x00000200 +#define SKBLIST_XMITBUF_FREEQUEUE 0x00000400 +#define SKBLIST_XMITEXTBUF_FREEQUEUE 0x00000800 +#define SKBLIST_XMITBUF_PENDINGQUEUE 0x00001000 +#ifdef CONFIG_SDIO_TX_MULTI_QUEUE +#define SKBLIST_XMITBUF_PENDING0QUEUE 0x00002000 +#define SKBLIST_XMITBUF_PENDING1QUEUE 0x00004000 +#define SKBLIST_XMITBUF_PENDING2QUEUE 0x00008000 +#endif + +#define SKBLIST_XMITFRAME_MASK 0x0FFF0000 +#define SKBLIST_XMITFRAME 0x00010000 +#define SKBLIST_XMITFRAME_FREEQUEUE 0x00020000 +#define SKBLIST_XMITFRAME_SLEEPQUEUE 0x00040000 +#define SKBLIST_XMITFRAME_VOQUEUE 0x00100000 +#define SKBLIST_XMITFRAME_VIQUEUE 0x00200000 +#define SKBLIST_XMITFRAME_BEQUEUE 0x00400000 +#define SKBLIST_XMITFRAME_BKQUEUE 0x00800000 +#define SKBLIST_XMITFRAME_BMQUEUE 0x01000000 + +#define SKBLIST_POOL 0x10000000 +#endif + +enum _NIC_VERSION { + + RTL8711_NIC, + RTL8712_NIC, + RTL8713_NIC, + RTL8716_NIC + +}; + +typedef struct _ADAPTER _adapter, ADAPTER,*PADAPTER; + +#include "wireless.h" +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_80211N_HT +#include +#endif + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_INCLUDE_WPA_PSK +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_P2P_NEW +#include +#endif +//#include +#include +#include + +#include + +#include + +#ifdef CONFIG_WAPI_SUPPORT +#include +#endif + +#ifdef CONFIG_DRVEXT_MODULE +#include +#endif + +#ifdef CONFIG_MP_INCLUDED +#include +#endif + +#ifdef CONFIG_BR_EXT +#include +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_IOCTL_CFG80211 + #include "ioctl_cfg80211.h" +#endif //CONFIG_IOCTL_CFG80211 + +#define SPEC_DEV_ID_NONE BIT(0) +#define SPEC_DEV_ID_DISABLE_HT BIT(1) +#define SPEC_DEV_ID_ENABLE_PS BIT(2) +#define SPEC_DEV_ID_RF_CONFIG_1T1R BIT(3) +#define SPEC_DEV_ID_RF_CONFIG_2T2R BIT(4) +#define SPEC_DEV_ID_ASSIGN_IFNAME BIT(5) + +struct specific_device_id{ + + u32 flags; + + u16 idVendor; + u16 idProduct; + +}; + +struct registry_priv +{ + u8 chip_version; +// u8 rfintfs; +// u8 lbkmode; + u8 hci; + NDIS_802_11_SSID ssid; +// u8 network_mode; //infra, ad-hoc, auto + u8 channel;//ad-hoc support requirement + u8 wireless_mode;//A, B, G, auto + u8 scan_mode;//active, passive +// u8 radio_enable; +// u8 preamble;//long, short, auto + u8 vrtl_carrier_sense;//Enable, Disable, Auto + u8 vcs_type;//RTS/CTS, CTS-to-self + u16 rts_thresh; +// u8 adhoc_tx_pwr; + u8 soft_ap; + u8 power_mgnt; + u8 ps_enable; + u8 ips_mode; + u8 smart_ps; +// u8 long_retry_lmt; +// u8 short_retry_lmt; +// u16 busy_thresh; +// u8 ack_policy; + u8 mp_mode; + u8 software_encrypt; + u8 software_decrypt; + #ifdef CONFIG_TX_EARLY_MODE + u8 early_mode; + #endif + u8 acm_method; + //UAPSD + u8 wmm_enable; + u8 uapsd_enable; +// u8 uapsd_max_sp; +// u8 uapsd_acbk_en; +// u8 uapsd_acbe_en; +// u8 uapsd_acvi_en; +// u8 uapsd_acvo_en; + +// WLAN_BSSID_EX dev_network; + u32 beacon_period; + +#ifdef CONFIG_80211N_HT + u8 ht_enable; +#if !defined(NOT_SUPPORT_40M) + u8 cbw40_enable; +#endif + u8 ampdu_enable;//for tx + u8 rx_stbc; + u8 ampdu_amsdu;//A-MPDU Supports A-MSDU is permitted +#endif + //u8 lowrate_two_xmit; + + u8 rf_config ; +// u8 low_power ; + u8 power_percentage_idx; + + u8 wifi_spec;// !turbo_mode + + u8 channel_plan; +#ifdef CONFIG_BT_COEXIST + u8 btcoex; + u8 bt_iso; + u8 bt_sco; + u8 bt_ampdu; +#endif +#if RX_AGGREGATION + BOOLEAN bAcceptAddbaReq; +#endif +// u8 antdiv_cfg; +// u8 antdiv_type; + +#ifdef CONFIG_AUTOSUSPEND + u8 usbss_enable;//0:disable,1:enable +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED + u8 hwpdn_mode;//0:disable,1:enable,2:decide by EFUSE config + u8 hwpwrp_detect;//0:disable,1:enable +#endif +#ifdef CONFIG_SUPPORT_HW_WPS_PBC + u8 hw_wps_pbc;//0:disable,1:enable +#endif + +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE + char adaptor_info_caching_file_path[PATH_LENGTH_MAX]; +#endif + +#ifdef CONFIG_LAYER2_ROAMING + u8 max_roaming_times; // the max number driver will try to roaming +#endif + +#ifdef CONFIG_IOL + bool force_iol; //enable iol without other concern +#endif + +#ifdef CONFIG_80211D + u8 enable80211d; +#endif + + u8 ifname[16]; + u8 if2name[16]; + +#if (RTW_NOTCH_FILTER != 0) + u8 notch_filter; +#endif + +#ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + u8 force_ant;//0 normal,1 main,2 aux + u8 force_igi;//0 normal +#endif + + //define for tx power adjust + u8 RegEnableTxPowerLimit; + u8 RegEnableTxPowerByRate; +#ifdef CONFIG_RF_GAIN_OFFSET + u8 RegEnableKFree; +#endif + u8 RegPowerBase; + u8 RegPwrTblSel; + + u8 adaptivity_en; + u8 adaptivity_mode; + u8 adaptivity_dml; + u8 adaptivity_dc_backoff; + s8 adaptivity_th_l2h_ini; +// u8 nhm_en; +}; + +//For registry parameters +#define RGTRY_OFT(field) ((u32)FIELD_OFFSET(struct registry_priv,field)) +#define RGTRY_SZ(field) sizeof(((struct registry_priv*) 0)->field) +#define BSSID_OFT(field) ((u32)FIELD_OFFSET(WLAN_BSSID_EX,field)) +#define BSSID_SZ(field) sizeof(((PWLAN_BSSID_EX) 0)->field) + +#define MAX_CONTINUAL_URB_ERR 4 + +#ifdef CONFIG_CONCURRENT_MODE +#define is_primary_adapter(adapter) (adapter->adapter_type == PRIMARY_ADAPTER) +#define get_iface_type(adapter) (adapter->iface_type) +#else +#define is_primary_adapter(adapter) (1) +#define get_iface_type(adapter) (IFACE_PORT0) +#endif + +enum _IFACE_TYPE { + IFACE_PORT0, //mapping to port0 for C/D series chips + IFACE_PORT1, //mapping to port1 for C/D series chip + MAX_IFACE_PORT, +}; + +enum _ADAPTER_TYPE { + PRIMARY_ADAPTER, + SECONDARY_ADAPTER, + MAX_ADAPTER, +}; + +struct dvobj_priv +{ + void *if1; +#ifdef CONFIG_CONCURRENT_MODE + void *if2; +#endif + + //For 92D, DMDP have 2 interface. + //u8 InterfaceNumber; + //u8 NumInterfaces; +#ifdef CONFIG_CONCURRENT_MODE + void *padapters[MAX_IFACE_PORT]; + u8 iface_nums; // total number of ifaces used runtime +#endif + //In /Out Pipe information + //int RtInPipe[2]; + u8 RtOutPipe[3];//int RtOutPipe[3]; + u8 Queue2Pipe[HW_QUEUE_ENTRY];//for out pipe mapping + + //u8 irq_alloc; + +/*-------- below is for SDIO INTERFACE --------*/ +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + // + // SDIO ISR Related + // + u32 sdio_himr; + + // + // SDIO Tx FIFO related. + // + // HIQ, MID, LOW, PUB free pages; padapter->xmitpriv.free_txpg + u8 SdioTxFIFOFreePage[TX_FREE_PG_QUEUE]; + _lock SdioTxFIFOFreePageLock; + + // + // SDIO Rx FIFO related. + // + u16 SdioRxFIFOSize; + +#ifdef INTF_DATA + INTF_DATA intf_data; +#endif +#endif //CONFIG_SDIO_HCI + +/*-------- below is for USB INTERFACE --------*/ + +#ifdef CONFIG_USB_HCI + + u8 irq_alloc; + u8 nr_endpoint; + u8 ishighspeed; + u8 RtNumInPipes; + u8 RtNumOutPipes; + int ep_num[5]; //endpoint number + + int RegUsbSS; + + _sema usb_suspend_sema; + +#ifdef CONFIG_USB_VENDOR_REQ_MUTEX + _mutex usb_vendor_req_mutex; +#endif + +#ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC + u8 * usb_alloc_vendor_req_buf; + u8 * usb_vendor_req_buf; +#endif + +#ifdef PLATFORM_WINDOWS + //related device objects + PDEVICE_OBJECT pphysdevobj;//pPhysDevObj; + PDEVICE_OBJECT pfuncdevobj;//pFuncDevObj; + PDEVICE_OBJECT pnextdevobj;//pNextDevObj; + + u8 nextdevstacksz;//unsigned char NextDeviceStackSize; //= (CHAR)CEdevice->pUsbDevObj->StackSize + 1; + + //urb for control diescriptor request + +#ifdef PLATFORM_OS_XP + struct _URB_CONTROL_DESCRIPTOR_REQUEST descriptor_urb; + PUSB_CONFIGURATION_DESCRIPTOR pconfig_descriptor;//UsbConfigurationDescriptor; +#endif + +#ifdef PLATFORM_OS_CE + WCHAR active_path[MAX_ACTIVE_REG_PATH]; // adapter regpath + USB_EXTENSION usb_extension; + + _nic_hdl pipehdls_r8192c[0x10]; +#endif + + u32 config_descriptor_len;//u32 UsbConfigurationDescriptorLength; +#endif//PLATFORM_WINDOWS + +#ifdef PLATFORM_LINUX + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + struct usb_interface *pusbintf; + struct usb_device *pusbdev; +#endif//PLATFORM_FREEBSD + ATOMIC_T continual_urb_error; +#endif//CONFIG_USB_HCI + +/*-------- below is for PCIE INTERFACE --------*/ + +#ifdef CONFIG_PCI_HCI + u8 irq_alloc; + +#ifdef PLATFORM_LINUX + struct pci_dev *ppcidev; + + //PCI MEM map + unsigned long pci_mem_end; /* shared mem end */ + unsigned long pci_mem_start; /* shared mem start */ + + //PCI IO map + unsigned long pci_base_addr; /* device I/O address */ + + //PciBridge + struct pci_priv pcipriv; + + u16 irqline; + u8 irq_enabled; + RT_ISR_CONTENT isr_content; + _lock irq_th_lock; + + //ASPM + u8 const_pci_aspm; + u8 const_amdpci_aspm; + u8 const_hwsw_rfoff_d3; + u8 const_support_pciaspm; + // pci-e bridge */ + u8 const_hostpci_aspm_setting; + // pci-e device */ + u8 const_devicepci_aspm_setting; + u8 b_support_aspm; // If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. + u8 b_support_backdoor; + u8 bdma64; +#endif//PLATFORM_LINUX + +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + u8 irq_enabled; + _lock irq_th_lock; +#endif //PLATFORM_FREERTOS + +#endif//CONFIG_PCI_HCI + +#ifdef CONFIG_LX_HCI + u8 irq_alloc; +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + u8 irq_enabled; + _lock irq_th_lock; +#endif //PLATFORM_FREERTOS +#endif + +}; + +#ifdef PLATFORM_LINUX +static struct device *dvobj_to_dev(struct dvobj_priv *dvobj) +{ + /* todo: get interface type from dvobj and the return the dev accordingly */ +#ifdef RTW_DVOBJ_CHIP_HW_TYPE +#endif + +#ifdef CONFIG_USB_HCI + return &dvobj->pusbintf->dev; +#endif +#ifdef CONFIG_SDIO_HCI + return &dvobj->intf_data.func->dev; +#endif +#ifdef CONFIG_GSPI_HCI + return &dvobj->intf_data.func->dev; +#endif +#ifdef CONFIG_PCI_HCI + return &dvobj->ppcidev->dev; +#endif +} +#endif + +#ifdef CONFIG_CONCURRENT_MODE +struct co_data_priv{ + + //george@20120518 + //current operating channel/bw/ch_offset + //save the correct ch/bw/ch_offset whatever the inputted values are + //when calling set_channel_bwmode() at concurrent mode + //for debug check or reporting to layer app (such as wpa_supplicant for nl80211) + u8 co_ch; + u8 co_bw; + u8 co_ch_offset; + u8 rsvd; + +}; +#endif //CONFIG_CONCURRENT_MODE + +typedef enum _DRIVER_STATE{ + DRIVER_NORMAL = 0, + DRIVER_DISAPPEAR = 1, + DRIVER_REPLACE_DONGLE = 2, +}DRIVER_STATE; + +#ifdef CONFIG_INTEL_PROXIM +struct proxim { + bool proxim_support; + bool proxim_on; + + void *proximity_priv; + int (*proxim_rx)(_adapter *padapter, + union recv_frame *precv_frame); + u8 (*proxim_get_var)(_adapter* padapter, u8 type); +}; +#endif //CONFIG_INTEL_PROXIM + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER +typedef struct loopbackdata +{ + _sema sema; + _thread_hdl_ lbkthread; + u8 bstop; + u32 cnt; + u16 size; + u16 txsize; + u8 txbuf[0x8000]; + u16 rxsize; + u8 rxbuf[0x8000]; + u8 msg[100]; + +}LOOPBACKDATA, *PLOOPBACKDATA; +#endif + +struct _ADAPTER{ +#ifdef CONFIG_EASY_REPLACEMENT + int DriverState;// for disable driver using module, use dongle to replace module. + int bDongle;//build-in module or external dongle + +#endif +#ifdef PLATFORM_LINUX + int pid[3];//process id from UI, 0:wps, 1:hostapd, 2:dhcpcd +#endif + +#ifdef CONFIG_PROC_DEBUG + u16 chip_type; +#endif + + u16 HardwareType; + u16 interface_type;//USB,SDIO,SPI,PCI + u32 work_mode; //STA, AP, STA+AP, PROMISC, P2P + + struct dvobj_priv *dvobj; + struct mlme_priv mlmepriv; + struct mlme_ext_priv mlmeextpriv; + struct cmd_priv cmdpriv; + struct evt_priv evtpriv; + //struct io_queue *pio_queue; + struct io_priv iopriv; + struct xmit_priv xmitpriv; + struct recv_priv recvpriv; + struct sta_priv stapriv; + struct security_priv securitypriv; + struct registry_priv registrypriv; + struct pwrctrl_priv pwrctrlpriv; + struct eeprom_priv eeprompriv; +//TODO +// struct led_priv ledpriv; + + +#ifdef CONFIG_MP_INCLUDED + struct mp_priv mppriv; +#endif + +#ifdef CONFIG_DRVEXT_MODULE + struct drvext_priv drvextpriv; +#endif + +#if defined(CONFIG_HOSTAPD_MLME) && defined (CONFIG_AP_MODE) + struct hostapd_priv *phostapdpriv; +#endif + +#ifdef CONFIG_IOCTL_CFG80211 +#ifdef CONFIG_P2P + struct cfg80211_wifidirect_info cfg80211_wdinfo; +#endif //CONFIG_P2P +#endif //CONFIG_IOCTL_CFG80211 + +#ifdef CONFIG_P2P_NEW + struct wifidirect_info wdinfo; +#endif //CONFIG_P2P + +#ifdef CONFIG_TDLS + struct tdls_info tdlsinfo; +#endif //CONFIG_TDLS + +#ifdef CONFIG_WAPI_SUPPORT + u8 WapiSupport; + RT_WAPI_T wapiInfo; +#endif + + +#ifdef CONFIG_WFD + struct wifi_display_info wfd_info; +#endif //CONFIG_WFD + + PVOID HalData; + u32 hal_data_sz; + struct hal_ops HalFunc; + + s32 bDriverStopped; + s32 bSurpriseRemoved; + s32 bCardDisableWOHSM; + u8 RxStop; //Used to stop rx thread as early as possible + + u32 IsrContent; + u32 ImrContent; + + u8 EepromAddressSize; + u8 hw_init_completed; + u8 bDriverIsGoingToUnload; + u8 init_adpt_in_progress; + u8 bMpDriver; + +#ifdef CONFIG_AP_MODE + u8 bForwardingDisabled; +#endif + +#if defined(CONFIG_EVENT_THREAD_MODE) + _thread_hdl_ evtThread; +#endif +#if defined(CONFIG_ISR_THREAD_MODE_POLLING) || defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) + struct task_struct isrThread; +#endif + struct task_struct cmdThread; +#ifdef CONFIG_XMIT_THREAD_MODE + struct task_struct xmitThread; +#endif +#if defined(CONFIG_RECV_THREAD_MODE) + struct task_struct recvThread; +#endif +#ifdef CONFIG_RECV_TASKLET_THREAD + struct task_struct recvtasklet_thread; +#endif +#ifdef CONFIG_XMIT_TASKLET_THREAD +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#else + struct task_struct xmittasklet_thread; +#endif +#endif +#ifdef CONFIG_SDIO_XMIT_THREAD + struct task_struct SdioXmitThread; +#endif //CONFIG_XMIT_TASKLET_THREAD + + +#if !defined(PLATFORM_LINUX) && !defined(PLATFORM_ECOS) && !defined(PLATFORM_FREERTOS) && !defined(PLATFORM_CMSIS_RTOS) + NDIS_STATUS (*dvobj_init)(struct dvobj_priv *dvobj); + void (*dvobj_deinit)(struct dvobj_priv *dvobj); +#endif + + void (*intf_start)(_adapter * adapter); + void (*intf_stop)(_adapter * adapter); + +#ifdef PLATFORM_WINDOWS + _nic_hdl hndis_adapter;//hNdisAdapter(NDISMiniportAdapterHandle); + _nic_hdl hndis_config;//hNdisConfiguration; + NDIS_STRING fw_img; + + u32 NdisPacketFilter; + u8 MCList[MAX_MCAST_LIST_NUM][6]; + u32 MCAddrCount; +#endif //end of PLATFORM_WINDOWS + +#ifdef PLATFORM_ECOS + _nic_hdl pnetdev; + int bup; + struct net_device_stats stats; +#endif //#ifdef PLATFORM_ECOS + +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + _nic_hdl pnetdev; + int bup; + struct net_device_stats stats; +#endif //#ifdef PLATFORM_FREERTOS + +#ifdef PLATFORM_LINUX + _nic_hdl pnetdev; + + // used by rtw_rereg_nd_name related function + struct rereg_nd_name_data { + _nic_hdl old_pnetdev; + char old_ifname[IFNAMSIZ]; + u8 old_ips_mode; + u8 old_bRegUseLed; + } rereg_nd_name_priv; + + int bup; + struct net_device_stats stats; + struct iw_statistics iwstats; + struct proc_dir_entry *dir_dev;// for proc directory + +#ifdef CONFIG_IOCTL_CFG80211 + struct wireless_dev *rtw_wdev; +#endif //CONFIG_IOCTL_CFG80211 + +#endif //end of PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + _nic_hdl pifp; + int bup; + _lock glock; +#endif //PLATFORM_FREEBSD + u8 net_closed; + + u8 bFWReady; + //u8 bBTFWReady; + //u8 bReadPortCancel; + //u8 bWritePortCancel; + u8 bLinkInfoDump; + u8 bRxRSSIDisplay; +#ifdef CONFIG_AUTOSUSPEND + u8 bDisableAutosuspend; +#endif + + _adapter *pbuddy_adapter; + + _mutex *hw_init_mutex; +#if defined(CONFIG_CONCURRENT_MODE) + u8 isprimary; //is primary adapter or not + u8 adapter_type; + u8 iface_type; //interface port type + + //for global synchronization + _mutex *ph2c_fwcmd_mutex; + _mutex *psetch_mutex; + _mutex *psetbw_mutex; + + struct co_data_priv *pcodatapriv;//data buffer shared among interfaces +#endif + +#ifdef CONFIG_BR_EXT + _lock br_ext_lock; + //unsigned int macclone_completed; + struct nat25_network_db_entry *nethash[NAT25_HASH_SIZE]; + int pppoe_connection_in_progress; + unsigned char pppoe_addr[MACADDRLEN]; + unsigned char scdb_mac[MACADDRLEN]; + unsigned char scdb_ip[4]; + struct nat25_network_db_entry *scdb_entry; + unsigned char br_mac[MACADDRLEN]; + unsigned char br_ip[4]; + + struct br_ext_info ethBrExtInfo; +#endif // CONFIG_BR_EXT + +#ifdef CONFIG_INTEL_PROXIM + /* intel Proximity, should be alloc mem + * in intel Proximity module and can only + * be used in intel Proximity mode */ + struct proxim proximity; +#endif //CONFIG_INTEL_PROXIM + +#ifdef CONFIG_MAC_LOOPBACK_DRIVER + PLOOPBACKDATA ploopback; +#endif + + u8 fix_rate; +#ifdef CONFIG_CAC_TEST + unsigned char in_cta_test; +#endif + /* This flag is used to dynamically enabling debug message if + certain sympton happen. Use iwpriv command to enable it */ +#if defined(CONFIG_DEBUG_DYNAMIC) + u8 debug_level; +#endif + +}; + +#define adapter_to_dvobj(adapter) (adapter->dvobj) +#define adapter_to_pwrctl(adapter) (&adapter->pwrctrlpriv) + +int rtw_handle_dualmac(_adapter *adapter, bool init); + +__inline static u8 *myid(struct eeprom_priv *peepriv) +{ + return (peepriv->mac_addr); +} + +#if 0 //#if (CONFIG_LWIP_LAYER == 0) +// For FPGA test program +#define _htons(x) (x) +#define _htons(x) (x) +#define _htons(x) (x) +#define _htons(x) (x) +#endif + +//fast reconnection function prototype +typedef int (*init_done_ptr)(void); +#endif //__DRV_TYPES_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/ethernet.h b/USDK/component/common/drivers/wlan/realtek/include/ethernet.h new file mode 100644 index 0000000..e6c220e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/ethernet.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +/*! \file */ +#ifndef __INC_ETHERNET_H +#define __INC_ETHERNET_H + +#define ETHERNET_ADDRESS_LENGTH 6 //!< Ethernet Address Length +#define ETHERNET_HEADER_SIZE 14 //!< Ethernet Header Length +#define LLC_HEADER_SIZE 6 //!< LLC Header Length +#define TYPE_LENGTH_FIELD_SIZE 2 //!< Type/Length Size +#define MINIMUM_ETHERNET_PACKET_SIZE 60 //!< Minimum Ethernet Packet Size +#define MAXIMUM_ETHERNET_PACKET_SIZE 1514 //!< Maximum Ethernet Packet Size + +#define RT_ETH_IS_MULTICAST(_pAddr) ((((u8 *)(_pAddr))[0]&0x01)!=0) //!< Is Multicast Address? +#define RT_ETH_IS_BROADCAST(_pAddr) ( \ + ((u8 *)(_pAddr))[0]==0xff && \ + ((u8 *)(_pAddr))[1]==0xff && \ + ((u8 *)(_pAddr))[2]==0xff && \ + ((u8 *)(_pAddr))[3]==0xff && \ + ((u8 *)(_pAddr))[4]==0xff && \ + ((u8 *)(_pAddr))[5]==0xff ) //!< Is Broadcast Address? + + +#endif // #ifndef __INC_ETHERNET_H + diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_com.h b/USDK/component/common/drivers/wlan/realtek/include/hal_com.h new file mode 100644 index 0000000..d096386 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_com.h @@ -0,0 +1,287 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_COMMON_H__ +#define __HAL_COMMON_H__ + +#include "HalVerDef.h" +#include "hal_pg.h" +#include "hal_intf.h" +#include "hal_phy.h" +#include "hal_phy_reg.h" +#include "hal_com_reg.h" +#include "hal_com_phycfg.h" + +//---------------------------------------------------------------------------- +// Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +//CCK +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +//OFDM +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +//MCS 1 Spatial Stream +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +//MCS 2 Spatial Stream +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\ + RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + +/*------------------------------ Tx Desc definition Macro ------------------------*/ +//#pragma mark -- Tx Desc related definition. -- +//---------------------------------------------------------------------------- +//----------------------------------------------------------- +// Rate +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC_RATE1M 0x00 +#define DESC_RATE2M 0x01 +#define DESC_RATE5_5M 0x02 +#define DESC_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC_RATE6M 0x04 +#define DESC_RATE9M 0x05 +#define DESC_RATE12M 0x06 +#define DESC_RATE18M 0x07 +#define DESC_RATE24M 0x08 +#define DESC_RATE36M 0x09 +#define DESC_RATE48M 0x0a +#define DESC_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC_RATEMCS0 0x0c +#define DESC_RATEMCS1 0x0d +#define DESC_RATEMCS2 0x0e +#define DESC_RATEMCS3 0x0f +#define DESC_RATEMCS4 0x10 +#define DESC_RATEMCS5 0x11 +#define DESC_RATEMCS6 0x12 +#define DESC_RATEMCS7 0x13 +#define DESC_RATEMCS8 0x14 +#define DESC_RATEMCS9 0x15 +#define DESC_RATEMCS10 0x16 +#define DESC_RATEMCS11 0x17 +#define DESC_RATEMCS12 0x18 +#define DESC_RATEMCS13 0x19 +#define DESC_RATEMCS14 0x1a +#define DESC_RATEMCS15 0x1b +#define DESC_RATEMCS16 0x1C +#define DESC_RATEMCS17 0x1D +#define DESC_RATEMCS18 0x1E +#define DESC_RATEMCS19 0x1F +#define DESC_RATEMCS20 0x20 +#define DESC_RATEMCS21 0x21 +#define DESC_RATEMCS22 0x22 +#define DESC_RATEMCS23 0x23 +#define DESC_RATEMCS24 0x24 +#define DESC_RATEMCS25 0x25 +#define DESC_RATEMCS26 0x26 +#define DESC_RATEMCS27 0x27 +#define DESC_RATEMCS28 0x28 +#define DESC_RATEMCS29 0x29 +#define DESC_RATEMCS30 0x2A +#define DESC_RATEMCS31 0x2B + +#define DESC_RATEVHTSS1MCS0 0x2c +#define DESC_RATEVHTSS1MCS1 0x2d +#define DESC_RATEVHTSS1MCS2 0x2e +#define DESC_RATEVHTSS1MCS3 0x2f +#define DESC_RATEVHTSS1MCS4 0x30 +#define DESC_RATEVHTSS1MCS5 0x31 +#define DESC_RATEVHTSS1MCS6 0x32 +#define DESC_RATEVHTSS1MCS7 0x33 +#define DESC_RATEVHTSS1MCS8 0x34 +#define DESC_RATEVHTSS1MCS9 0x35 +#define DESC_RATEVHTSS2MCS0 0x36 +#define DESC_RATEVHTSS2MCS1 0x37 +#define DESC_RATEVHTSS2MCS2 0x38 +#define DESC_RATEVHTSS2MCS3 0x39 +#define DESC_RATEVHTSS2MCS4 0x3a +#define DESC_RATEVHTSS2MCS5 0x3b +#define DESC_RATEVHTSS2MCS6 0x3c +#define DESC_RATEVHTSS2MCS7 0x3d +#define DESC_RATEVHTSS2MCS8 0x3e +#define DESC_RATEVHTSS2MCS9 0x3f +#define DESC_RATEVHTSS3MCS0 0x40 +#define DESC_RATEVHTSS3MCS1 0x41 +#define DESC_RATEVHTSS3MCS2 0x42 +#define DESC_RATEVHTSS3MCS3 0x43 +#define DESC_RATEVHTSS3MCS4 0x44 +#define DESC_RATEVHTSS3MCS5 0x45 +#define DESC_RATEVHTSS3MCS6 0x46 +#define DESC_RATEVHTSS3MCS7 0x47 +#define DESC_RATEVHTSS3MCS8 0x48 +#define DESC_RATEVHTSS3MCS9 0x49 +#define DESC_RATEVHTSS4MCS0 0x4A +#define DESC_RATEVHTSS4MCS1 0x4B +#define DESC_RATEVHTSS4MCS2 0x4C +#define DESC_RATEVHTSS4MCS3 0x4D +#define DESC_RATEVHTSS4MCS4 0x4E +#define DESC_RATEVHTSS4MCS5 0x4F +#define DESC_RATEVHTSS4MCS6 0x50 +#define DESC_RATEVHTSS4MCS7 0x51 +#define DESC_RATEVHTSS4MCS8 0x52 +#define DESC_RATEVHTSS4MCS9 0x53 + +typedef enum _FIRMWARE_SOURCE { + FW_SOURCE_IMG_FILE = 0, + FW_SOURCE_HEADER_FILE = 1, //from header file +} FIRMWARE_SOURCE, *PFIRMWARE_SOURCE; + +// BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. +//#define MAX_TX_QUEUE 9 + +#define TX_SELE_HQ BIT(0) // High Queue +#define TX_SELE_LQ BIT(1) // Low Queue +#define TX_SELE_NQ BIT(2) // Normal Queue +#define TX_SELE_EQ BIT(3) // Extern Queue + +#define PageNum_128(_Len) (u32)(((_Len)>>7) + ((_Len)&0x7F ? 1:0)) +#define PageNum_256(_Len) (u32)(((_Len)>>8) + ((_Len)&0xFF ? 1:0)) +#define PageNum_512(_Len) (u32)(((_Len)>>9) + ((_Len)&0x1FF ? 1:0)) +#define PageNum(_Len, _Size) (u32)(((_Len)/(_Size)) + ((_Len)&((_Size) - 1) ? 1:0)) + +#define DYNAMIC_FUNC_DISABLE (0x0) +#define DYNAMIC_ALL_FUNC_ENABLE 0xFFFFFFF + +void dump_chip_info(HAL_VERSION ChipVersion); + + +u8 //return the final channel plan decision +hal_com_get_channel_plan( + IN PADAPTER padapter, + IN u8 hw_channel_plan, //channel plan from HW (efuse/eeprom) + IN u8 sw_channel_plan, //channel plan from SW (registry/module param) + IN u8 def_channel_plan, //channel plan used when the former two is invalid + IN BOOLEAN AutoLoadFail + ); + +u8 MRateToHwRate(u8 rate); + +void HalSetBrateCfg( + IN PADAPTER Adapter, + IN u8 *mBratesOS, + OUT u16 *pBrateCfg); + +BOOLEAN +Hal_MappingOutPipe( + IN PADAPTER pAdapter, + IN u8 NumOutPipe + ); + +BOOLEAN +HAL_IsLegalChannel( + IN _adapter * Adapter, + IN u32 Channel + ); + +void hal_init_macaddr(_adapter *adapter); +void SetHwReg(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg(PADAPTER padapter, u8 variable, u8 *val); + +#if defined (CONFIG_RTL8188F) || defined (CONFIG_RTL8711B) +typedef enum _RT_MEDIA_STATUS { + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +} RT_MEDIA_STATUS; + + +void GetHalODMVar( + PADAPTER Adapter, + HAL_ODM_VARIABLE eVariable, + PVOID pValue1, + PVOID pValue2); + +void SetHalODMVar( + PADAPTER Adapter, + HAL_ODM_VARIABLE eVariable, + PVOID pValue1, + BOOLEAN bSet); + +u8 SetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); +u8 GetHalDefVar(_adapter *adapter, HAL_DEF_VARIABLE variable, void *value); +void rtw_hal_wow_enable(_adapter *adapter); +void rtw_hal_wow_disable(_adapter *adapter); +#endif +#endif //__HAL_COMMON_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_com_phycfg.h b/USDK/component/common/drivers/wlan/realtek/include/hal_com_phycfg.h new file mode 100644 index 0000000..5cb5366 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_com_phycfg.h @@ -0,0 +1,288 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_COM_PHYCFG_H__ +#define __HAL_COM_PHYCFG_H__ + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +typedef enum _RATE_SECTION { + CCK = 0, + OFDM, + HT_MCS0_MCS7, + HT_MCS8_MCS15, + HT_MCS16_MCS23, + HT_MCS24_MCS31, + VHT_1SSMCS0_1SSMCS9, + VHT_2SSMCS0_2SSMCS9, + VHT_3SSMCS0_3SSMCS9, + VHT_4SSMCS0_4SSMCS9, +} RATE_SECTION; + +typedef enum _RF_TX_NUM { + RF_1TX = 0, + RF_2TX, + RF_3TX, + RF_4TX, + RF_MAX_TX_NUM, + RF_TX_NUM_NONIMPLEMENT, +} RF_TX_NUM; + +#define MAX_POWER_INDEX 0x3F + +typedef enum _REGULATION_TXPWR_LMT { + TXPWR_LMT_FCC = 0, + TXPWR_LMT_MKK = 1, + TXPWR_LMT_ETSI = 2, + TXPWR_LMT_WW = 3, // WW13, The mininum of ETSI,MKK + TXPWR_LMT_GL = 4, // Global, The mininum of ETSI,MKK,FCC + TXPWR_LMT_MAX_REGULATION_NUM = 5 +} REGULATION_TXPWR_LMT; + +/*------------------------------Define structure----------------------------*/ +typedef struct _BB_REGISTER_DEFINITION{ + u32 rfintfs; // set software control: + // 0x870~0x877[8 bytes] + + u32 rfintfo; // output data: + // 0x860~0x86f [16 bytes] + + u32 rfintfe; // output enable: + // 0x860~0x86f [16 bytes] + + u32 rf3wireOffset; // LSSI data: + // 0x840~0x84f [16 bytes] + + u32 rfHSSIPara2; // wire parameter control2 : + // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] + + u32 rfLSSIReadBack; //LSSI RF readback data SI mode + // 0x8a0~0x8af [16 bytes] + + u32 rfLSSIReadBackPi; //LSSI RF readback data PI mode 0x8b8-8bc for Path A and B + +}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; + + +//---------------------------------------------------------------------- +s32 +phy_TxPwrIdxToDbm( + IN PADAPTER Adapter, + IN WIRELESS_MODE WirelessMode, + IN u8 TxPwrIdx + ); + +u8 +PHY_GetTxPowerByRateBase( + IN PADAPTER Adapter, + IN u8 Band, + IN u8 RfPath, + IN u8 TxNum, + IN RATE_SECTION RateSection + ); + +u8 +PHY_GetRateSectionIndexOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_GetRateValuesOfTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Value, + OUT u8* RateIndex, + OUT s8* PwrByRateVal, + OUT u8* RateNum + ); + +u8 +PHY_GetRateIndexOfTxPowerByRate( + IN u8 Rate + ); + +VOID +PHY_SetTxPowerIndexByRateSection( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Channel, + IN u8 RateSection + ); + +s8 +PHY_GetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 RateIndex + ); + +VOID +PHY_SetTxPowerByRate( + IN PADAPTER pAdapter, + IN u8 Band, + IN u8 RFPath, + IN u8 TxNum, + IN u8 Rate, + IN s8 Value + ); + +VOID +PHY_SetTxPowerLevelByPath( + IN PADAPTER Adapter, + IN u8 channel, + IN u8 path + ); + +VOID +PHY_SetTxPowerIndexByRateArray( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + IN u8* Rates, + IN u8 RateArraySize + ); + +VOID +PHY_InitTxPowerByRate( + IN PADAPTER pAdapter + ); + +VOID +PHY_StoreTxPowerByRate( + IN PADAPTER pAdapter, + IN u32 Band, + IN u32 RfPath, + IN u32 TxNum, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +VOID +PHY_TxPowerByRateConfiguration( + IN PADAPTER pAdapter + ); + +u8 +PHY_GetTxPowerIndexBase( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel, + OUT PBOOLEAN bIn24G + ); + +s8 +PHY_GetTxPowerLimit( + IN PADAPTER Adapter, + IN u32 RegPwrTblSel, + IN BAND_TYPE Band, + IN CHANNEL_WIDTH Bandwidth, + IN u8 RfPath, + IN u8 DataRate, + IN u8 Channel + ); + +VOID +PHY_SetTxPowerLimit( + IN PADAPTER Adapter, + IN u8 Regulation, + IN u8 Band, + IN u8 Bandwidth, + IN u8 RateSection, + IN u8 RfPath, + IN u8 Channel, + IN u8 PowerLimit + ); + +VOID +PHY_ConvertTxPowerLimitToPowerIndex( + IN PADAPTER Adapter + ); + +VOID +PHY_InitTxPowerLimit( + IN PADAPTER Adapter + ); + +s8 +PHY_GetTxPowerTrackingOffset( + PADAPTER pAdapter, + u8 Rate, + u8 RFPath + ); + +u8 +PHY_GetTxPowerIndex( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_SetTxPowerIndex( + IN PADAPTER pAdapter, + IN u32 PowerIndex, + IN u8 RFPath, + IN u8 Rate + ); + +#ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE +#define MAX_PARA_FILE_BUF_LEN 25600 + +#define LOAD_MAC_PARA_FILE BIT0 +#define LOAD_BB_PARA_FILE BIT1 +#define LOAD_BB_PG_PARA_FILE BIT2 +#define LOAD_BB_MP_PARA_FILE BIT3 +#define LOAD_RF_PARA_FILE BIT4 +#define LOAD_RF_TXPWR_TRACK_PARA_FILE BIT5 +#define LOAD_RF_TXPWR_LMT_PARA_FILE BIT6 + +int phy_ConfigMACWithParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int phy_ConfigBBWithParaFile(IN PADAPTER Adapter, IN char* pFileName, IN u32 ConfigType); + +int phy_ConfigBBWithPgParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int phy_ConfigBBWithMpParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int PHY_ConfigRFWithParaFile(IN PADAPTER Adapter, IN char* pFileName, IN u8 eRFPath); + +int PHY_ConfigRFWithTxPwrTrackParaFile(IN PADAPTER Adapter, IN char* pFileName); + +int PHY_ConfigRFWithPowerLimitTableParaFile(IN PADAPTER Adapter, IN char* pFileName); + +void phy_free_filebuf(_adapter *padapter); +#endif //CONFIG_LOAD_PHY_PARA_FROM_FILE + + +#endif //__HAL_COMMON_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_com_reg.h b/USDK/component/common/drivers/wlan/realtek/include/hal_com_reg.h new file mode 100644 index 0000000..4e176f4 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_com_reg.h @@ -0,0 +1,2075 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_COMMON_REG_H__ +#define __HAL_COMMON_REG_H__ + + +#define MAC_ADDR_LEN 6 + +#define HAL_NAV_UPPER_UNIT 128 // micro-second + +// 8188E PKT_BUFF_ACCESS_CTRL value +#define TXPKT_BUF_SELECT 0x69 +#define RXPKT_BUF_SELECT 0xA5 +#define DISABLE_TRXPKT_BUF_ACCESS 0x0 + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL 0x0000 +#define REG_SYS_FUNC_EN 0x0002 +#define REG_APS_FSMCO 0x0004 +#define REG_SYS_CLKR 0x0008 +#define REG_9346CR 0x000A +#define REG_SYS_EEPROM_CTRL 0x000A +#define REG_EE_VPD 0x000C +#define REG_AFE_MISC 0x0010 +#define REG_SPS0_CTRL 0x0011 +#define REG_SPS0_CTRL_6 0x0016 +#define REG_POWER_OFF_IN_PROCESS 0x0017 +#define REG_SPS_OCP_CFG 0x0018 +#define REG_RSV_CTRL 0x001C +#define REG_RF_CTRL 0x001F +#define REG_LDOA15_CTRL 0x0020 +#define REG_LDOV12D_CTRL 0x0021 +#define REG_LDOHCI12_CTRL 0x0022 +#define REG_LPLDO_CTRL 0x0023 +#define REG_AFE_XTAL_CTRL 0x0024 +#define REG_AFE_LDO_CTRL 0x0027 // 1.5v for 8188EE test chip, 1.4v for MP chip +#define REG_AFE_PLL_CTRL 0x0028 +#define REG_MAC_PHY_CTRL 0x002c //for 92d, DMDP,SMSP,DMSP contrl +#define REG_APE_PLL_CTRL_EXT 0x002c +#define REG_EFUSE_CTRL 0x0030 +#define REG_EFUSE_TEST 0x0034 +#define REG_PWR_DATA 0x0038 +#define REG_CAL_TIMER 0x003C +#define REG_ACLK_MON 0x003E +#define REG_GPIO_MUXCFG 0x0040 +#define REG_GPIO_IO_SEL 0x0042 +#define REG_MAC_PINMUX_CFG 0x0043 +#define REG_GPIO_PIN_CTRL 0x0044 +#define REG_GPIO_INTM 0x0048 +#define REG_LEDCFG0 0x004C +#define REG_LEDCFG1 0x004D +#define REG_LEDCFG2 0x004E +#define REG_LEDCFG3 0x004F +#define REG_FSIMR 0x0050 +#define REG_FSISR 0x0054 +#define REG_HSIMR 0x0058 +#define REG_HSISR 0x005c +#define REG_GPIO_PIN_CTRL_2 0x0060 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. +#define REG_GPIO_IO_SEL_2 0x0062 // RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. +#define REG_MULTI_FUNC_CTRL 0x0068 // RTL8723 WIFI/BT/GPS Multi-Function control source. +#define REG_GSSR 0x006c +#define REG_AFE_XTAL_CTRL_EXT 0x0078 //RTL8188E +#define REG_XCK_OUT_CTRL 0x007c //RTL8188E +#define REG_MCUFWDL 0x0080 +#define REG_WOL_EVENT 0x0081 //RTL8188E +#define REG_MCUTSTCFG 0x0084 +#define REG_FDHM0 0x0088 +#define REG_HOST_SUSP_CNT 0x00BC // RTL8192C Host suspend counter on FPGA platform +#define REG_SYSTEM_ON_CTRL 0x00CC // For 8723AE Reset after S3 +#define REG_EFUSE_ACCESS 0x00CF // Efuse access protection for RTL8723 +#define REG_BIST_SCAN 0x00D0 +#define REG_BIST_RPT 0x00D4 +#define REG_BIST_ROM_RPT 0x00D8 +#define REG_USB_SIE_INTF 0x00E0 +#define REG_PCIE_MIO_INTF 0x00E4 +#define REG_PCIE_MIO_INTD 0x00E8 +#define REG_HPON_FSM 0x00EC +#define REG_SYS_CFG 0x00F0 +#define REG_GPIO_OUTSTS 0x00F4 // For RTL8723 only. +#define REG_TYPE_ID 0x00FC + + +#define REG_WL_CLK_CTRL 0x0002 +#define REG_WL_FUNC_EN 0x0004 +#define REG_WL_PMC_CTRL 0x0020 +#define REG_WL_AFE_CTRL 0x0050 +#define REG_WL_PMC_IMR 0x0080 +#define REG_WL_PMC_ISR 0x0084 + + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR 0x0100 +#define REG_PBP 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL 0x0106 +#define REG_TRXDMA_CTRL 0x010C +#define REG_TRXFF_BNDY 0x0114 +#define REG_TRXFF_STATUS 0x0118 +#define REG_RXFF_PTR 0x011C +#define REG_HIMR 0x0120 +#define REG_HISR 0x0124 +#define REG_HIMRE 0x0128 +#define REG_HISRE 0x012C +#define REG_CPWM 0x012F +#define REG_FWIMR 0x0130 +#define REG_FWISR 0x0134 +#define REG_FTIMR 0x0138 +#define REG_FTISR 0x013C //RTL8192C +#define REG_PKTBUF_DBG_CTRL 0x0140 +#define REG_RXPKTBUF_CTRL (REG_PKTBUF_DBG_CTRL+2) +#define REG_PKTBUF_DBG_DATA_L 0x0144 +#define REG_PKTBUF_DBG_DATA_H 0x0148 + +#define REG_TC0_CTRL 0x0150 +#define REG_TC1_CTRL 0x0154 +#define REG_TC2_CTRL 0x0158 +#define REG_TC3_CTRL 0x015C +#define REG_TC4_CTRL 0x0160 +#define REG_TCUNIT_BASE 0x0164 +#define REG_MBIST_START 0x0174 +#define REG_MBIST_DONE 0x0178 +#define REG_MBIST_FAIL 0x017C +#define REG_32K_CTRL 0x0194 //RTL8188E +#define REG_C2HEVT_MSG_NORMAL 0x01A0 +#define REG_C2HEVT_CLEAR 0x01AF +#define REG_MCUTST_1 0x01c0 +#define REG_MCUTST_WOWLAN 0x01C7 // Defined after 8188E series. +#define REG_FMETHR 0x01C8 +#define REG_HMETFR 0x01CC +#define REG_HMEBOX_0 0x01D0 +#define REG_HMEBOX_1 0x01D4 +#define REG_HMEBOX_2 0x01D8 +#define REG_HMEBOX_3 0x01DC +#define REG_LLT_INIT 0x01E0 + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN 0x0200 +#define REG_FIFOPAGE 0x0204 +#define REG_TDECTRL 0x0208 +#define REG_TXDMA_OFFSET_CHK 0x020C +#define REG_TXDMA_STATUS 0x0210 +#define REG_RQPN_NPQ 0x0214 +#define REG_AUTO_LLT 0x0224 + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH 0x0280 +#define REG_RXPKT_NUM 0x0284 +#define REG_RXDMA_STATUS 0x0288 +#define REG_C2H_PKT_8723B 0x0294 + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG 0x0300 +#define REG_INT_MIG 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA 0x0340 // RX Queue Descriptor Address +//sherry added for DBI Read/Write 20091126 +#define REG_DBI_WDATA 0x0348 // Backdoor REG for Access Configuration +#define REG_DBI_RDATA 0x034C //Backdoor REG for Access Configuration +#define REG_DBI_CTRL 0x0350 //Backdoor REG for Access Configuration +#define REG_DBI_FLAG 0x0352 //Backdoor REG for Access Configuration +#define REG_MDIO 0x0354 // MDIO for Access PCIE PHY +#define REG_DBG_SEL 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM 0x0363 //PCIe CPWM +#define REG_WATCH_DOG 0x0368 + +// For new buffer descriptor ring architecture + +#define REG_LX_CTRL1 0x0300 // 4 Bytes + +#define REG_BCNQ_TXBD_DESA 0x0308 // 8 Bytes +#define REG_MGQ_TXBD_DESA 0x0310 // 8 Bytes +#define REG_VOQ_TXBD_DESA 0x0318 // 8 Bytes +#define REG_VIQ_TXBD_DESA 0x0320 // 8 Bytes +#define REG_BEQ_TXBD_DESA 0x0328 // 8 Bytes +#define REG_BKQ_TXBD_DESA 0x0330 // 8 Bytes +#define REG_RXQ_RXBD_DESA 0x0338 // 8 Bytes +#define REG_HI0Q_TXBD_DESA 0x0340 // 8 Bytes +#define REG_HI1Q_TXBD_DESA 0x0348 // 8 Bytes +#define REG_HI2Q_TXBD_DESA 0x0350 // 8 Bytes +#define REG_HI3Q_TXBD_DESA 0x0358 // 8 Bytes +#define REG_HI4Q_TXBD_DESA 0x0360 // 8 Bytes +#define REG_HI5Q_TXBD_DESA 0x0368 // 8 Bytes +#define REG_HI6Q_TXBD_DESA 0x0370 // 8 Bytes +#define REG_HI7Q_TXBD_DESA 0x0378 // 8 Bytes + +#define REG_MGQ_TXBD_NUM 0x0380 // 2 Bytes +#define REG_RX_RXBD_NUM 0x0382 // 2 Bytes +#define REG_VOQ_TXBD_NUM 0x0384 // 2 Bytes +#define REG_VIQ_TXBD_NUM 0x0386 // 2 Bytes +#define REG_BEQ_TXBD_NUM 0x0388 // 2 Bytes +#define REG_BKQ_TXBD_NUM 0x038A // 2 Bytes +#define REG_HI0Q_TXBD_NUM 0x038C // 2 Bytes +#define REG_HI1Q_TXBD_NUM 0x038E // 2 Bytes +#define REG_HI2Q_TXBD_NUM 0x0390 // 2 Bytes +#define REG_HI3Q_TXBD_NUM 0x0392 // 2 Bytes +#define REG_HI4Q_TXBD_NUM 0x0394 // 2 Bytes +#define REG_HI5Q_TXBD_NUM 0x0396 // 2 Bytes +#define REG_HI6Q_TXBD_NUM 0x0398 // 2 Bytes +#define REG_HI7Q_TXBD_NUM 0x039A // 2 Bytes + +#define REG_BD_RWPTR_CLR 0x039C // 4 Bytes +#define REG_VOQ_TXBD_IDX 0x03A0 // 4 Bytes +#define REG_VIQ_TXBD_IDX 0x03A4 // 4 Bytes +#define REG_BEQ_TXBD_IDX 0x03A8 // 4 Bytes +#define REG_BKQ_TXBD_IDX 0x03AC // 4 Bytes +#define REG_MGQ_TXBD_IDX 0x03B0 // 4 Bytes +#define REG_RXQ_RXBD_IDX 0x03B4 // 4 Bytes +#define REG_HI0Q_TXBD_IDX 0x03B8 // 4 Bytes +#define REG_HI1Q_TXBD_IDX 0x03BC // 4 Bytes +#define REG_HI2Q_TXBD_IDX 0x03C0 // 4 Bytes +#define REG_HI3Q_TXBD_IDX 0x03C4 // 4 Bytes +#define REG_HI4Q_TXBD_IDX 0x03C8 // 4 Bytes +#define REG_HI5Q_TXBD_IDX 0x03CC // 4 Bytes +#define REG_HI6Q_TXBD_IDX 0x03D0 // 4 Bytes +#define REG_HI7Q_TXBD_IDX 0x03D4 // 4 Bytes + +//CPWM &RPWM +#define REG_LX_HRPWM_8711B 0x03D9 // 1 Bytes +#define REG_LX_HCPWM_8711B 0x03DA // 1 Bytes //from 0x14c + +#define REG_LX_CTRL2 0x03DB // 1 Bytes + +#define REG_LX_HRPWM2_8711B 0x03DC // 2 Bytes //REG_LX_HCPWM1_8711B +#define REG_LX_HCPWM2_8711B 0x03DE // 2 Bytes +#define REG_LX_H2C_MSG_V1 0x03E0 // 4 Bytes +#define REG_LX_C2H_MSG_V1 0x03E4 // 4 Bytes + + +#define REG_LX_DMA_ISR 0x03E8 // 4 Bytes +#define REG_LX_DMA_IMR 0x03EC // 4 Bytes +#define REG_LX_DMA_DBG 0x03F0 // 4 Bytes + +#define REG_BUS_MIX_CFG 0x03F8 // 4 Bytes# +#define REG_BUS_MIX_CFG1 0x03FC // 4 Bytes + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_VOQ_INFORMATION 0x0400 +#define REG_VIQ_INFORMATION 0x0404 +#define REG_BEQ_INFORMATION 0x0408 +#define REG_BKQ_INFORMATION 0x040C +#define REG_MGQ_INFORMATION 0x0410 +#define REG_HGQ_INFORMATION 0x0414 +#define REG_BCNQ_INFORMATION 0x0418 +#define REG_TXPKT_EMPTY 0x041A +#define REG_CPU_MGQ_INFORMATION 0x041C +#define REG_FWHW_TXQ_CTRL 0x0420 +#define REG_HWSEQ_CTRL 0x0423 +#define REG_BCNQ_BDNY 0x0424 +#define REG_MGQ_BDNY 0x0425 +#define REG_LIFETIME_CTRL 0x0426 +#define REG_MULTI_BCNQ_OFFSET 0x0427 +#define REG_SPEC_SIFS 0x0428 +#define REG_RL 0x042A +#define REG_DARFRC 0x0430 +#define REG_RARFRC 0x0438 +#define REG_RRSR 0x0440 +#define REG_ARFR0 0x0444 +#define REG_ARFR1 0x0448 +#define REG_ARFR2 0x044C +#define REG_ARFR3 0x0450 +#define REG_BCNQ1_BDNY 0x0457 + +#define REG_AGGLEN_LMT 0x0458 +#define REG_AMPDU_MIN_SPACE 0x045C +#define REG_WMAC_LBK_BF_HD 0x045D +#define REG_FAST_EDCA_CTRL 0x0460 +#define REG_RD_RESP_PKT_TH 0x0463 + +#define REG_INIRTS_RATE_SEL 0x0480 +//#define REG_INIDATA_RATE_SEL 0x0484 +#define REG_MACID_SLEEP_3 0x0484 +#define REG_MACID_SLEEP_1 0x0488 + +#define REG_POWER_STAGE1 0x04B4 +#define REG_POWER_STAGE2 0x04B8 +#define REG_PKT_VO_VI_LIFE_TIME 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME 0x04C2 +#define REG_STBC_SETTING 0x04C4 +#define REG_QUEUE_CTRL 0x04C6 +#define REG_SINGLE_AMPDU_CTRL 0x04c7 +#define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA +#define REG_RTS_MAX_AGGR_NUM 0x04CB +#define REG_BAR_MODE_CTRL 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT 0x04CF +//#define REG_EARLY_MODE_CONTROL 0x04D0 +#define REG_MACID_SLEEP_2 0x04D0 +#define REG_MACID_SLEEP 0x04D4 +#define REG_NQOS_SEQ 0x04DC +#define REG_QOS_SEQ 0x04DE +#define REG_NEED_CPU_HANDLE 0x04E0 +#define REG_PKT_LOSE_RPT 0x04E1 +#define REG_PTCL_ERR_STATUS 0x04E2 +#define REG_TX_RPT_CTRL 0x04EC +#define REG_TX_RPT_TIME 0x04F0 // 2 byte +#define REG_DUMMY 0x04FC + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM 0x0500 +#define REG_EDCA_VI_PARAM 0x0504 +#define REG_EDCA_BE_PARAM 0x0508 +#define REG_EDCA_BK_PARAM 0x050C +#define REG_BCNTCFG 0x0510 +#define REG_PIFS 0x0512 +#define REG_RDG_PIFS 0x0513 +#define REG_SIFS_CTX 0x0514 +#define REG_SIFS_TRX 0x0516 +#define REG_TSFTR_SYN_OFFSET 0x0518 +#define REG_AGGR_BREAK_TIME 0x051A +#define REG_SLOT 0x051B +#define REG_TX_PTCL_CTRL 0x0520 +#define REG_TXPAUSE 0x0522 +#define REG_DIS_TXREQ_CLR 0x0523 +#define REG_RD_CTRL 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT 0x0540 +#define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 +#define REG_BCN_CTRL 0x0550 +#define REG_BCN_CTRL_1 0x0551 +#define REG_MBID_NUM 0x0552 +#define REG_DUAL_TSF_RST 0x0553 +#define REG_BCN_INTERVAL 0x0554 // The same as REG_MBSSID_BCN_SPACE +#define REG_DRVERLYINT 0x0558 +#define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A +#define REG_USTIME_TSF 0x055C +#define REG_BCN_MAX_ERR 0x055D +#define REG_RXTSF_OFFSET_CCK 0x055E +#define REG_RXTSF_OFFSET_OFDM 0x055F +#define REG_TSFTR 0x0560 +#define REG_TSFTR1 0x0568 // HW Port 1 TSF Register +#define REG_ATIMWND_1 0x0570 +#define REG_P2P_CTWIN 0x0572 // 1 Byte long (in unit of TU) +#define REG_PSTIMER 0x0580 +#define REG_TIMER0 0x0584 +#define REG_TIMER1 0x0588 +#define REG_ACMHWCTRL 0x05C0 +#define REG_NOA_DESC_SEL 0x05CF +#define REG_NOA_DESC_DURATION 0x05E0 +#define REG_NOA_DESC_INTERVAL 0x05E4 +#define REG_NOA_DESC_START 0x05E8 +#define REG_NOA_DESC_COUNT 0x05EC + +#define REG_DMC 0x05F0 //Dual MAC Co-Existence Register +#define REG_SCH_TX_CMD 0x05F8 + +#define REG_FW_RESET_TSF_CNT_1 0x05FC +#define REG_FW_RESET_TSF_CNT_0 0x05FD +#define REG_FW_BCN_DIS_CNT 0x05FE + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_APSD_CTRL 0x0600 +#define REG_BWOPMODE 0x0603 +#define REG_TCR 0x0604 +#define REG_RCR 0x0608 +#define REG_RX_PKT_LIMIT 0x060C +#define REG_RX_DLK_TIME 0x060D +#define REG_RX_DRVINFO_SZ 0x060F + +#define REG_MACID 0x0610 +#define REG_BSSID 0x0618 +#define REG_MAR 0x0620 +#define REG_MBIDCAMCFG 0x0628 + +#define REG_USTIME_EDCA 0x0638 +#define REG_MAC_SPEC_SIFS 0x063A +// 20100719 Joseph: Hardware register definition change. (HW datasheet v54) +#define REG_RESP_SIFS_CCK 0x063C // [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK +#define REG_RESP_SIFS_OFDM 0x063E // [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK + +#define REG_ACKTO 0x0640 +#define REG_CTS2TO 0x0641 +#define REG_EIFS 0x0642 + +#define REG_PORT_CTRL 0x076D + +//RXERR_RPT +#define RXERR_TYPE_OFDM_PPDU 0 +#define RXERR_TYPE_OFDM_FALSE_ALARM 1 +#define RXERR_TYPE_OFDM_MPDU_OK 2 +#define RXERR_TYPE_OFDM_MPDU_FAIL 3 +#define RXERR_TYPE_CCK_PPDU 4 +#define RXERR_TYPE_CCK_FALSE_ALARM 5 +#define RXERR_TYPE_CCK_MPDU_OK 6 +#define RXERR_TYPE_CCK_MPDU_FAIL 7 +#define RXERR_TYPE_HT_PPDU 8 +#define RXERR_TYPE_HT_FALSE_ALARM 9 +#define RXERR_TYPE_HT_MPDU_TOTAL 10 +#define RXERR_TYPE_HT_MPDU_OK 11 +#define RXERR_TYPE_HT_MPDU_FAIL 12 +#define RXERR_TYPE_RX_FULL_DROP 15 + +#define RXERR_COUNTER_MASK 0xFFFFF +#define RXERR_RPT_RST BIT(27) +#define _RXERR_RPT_SEL(type) ((type) << 28) + +// +// Note: +// The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. The default value is +// always too small, but the WiFi TestPlan test by 25,000 microseconds of NAV through sending +// CTS in the air. We must update this value greater than 25,000 microseconds to pass the item. +// The offset of NAV_UPPER in 8192C Spec is incorrect, and the offset should be 0x0652. Commented +// by SD1 Scott. +// By Bruce, 2011-07-18. +// +#define REG_NAV_UPPER 0x0652 // unit of 128 + +//WMA, BA, CCX +#define REG_NAV_CTRL 0x0650 +#define REG_BACAMCMD 0x0654 +#define REG_BACAMCONTENT 0x0658 +#define REG_LBDLY 0x0660 +#define REG_FWDLY 0x0661 +#define REG_RXERR_RPT 0x0664 +#define REG_WMAC_TRXPTCL_CTL 0x0668 + +// Security +#define REG_CAMCMD 0x0670 +#define REG_CAMWRITE 0x0674 +#define REG_CAMREAD 0x0678 +#define REG_CAMDBG 0x067C +#define REG_SECCFG 0x0680 + +// Power +#define REG_WOW_CTRL 0x0690 +#define REG_PS_RX_INFO 0x0692 +#define REG_UAPSD_TID 0x0693 +#define REG_WKFMCAM_CMD 0x0698 +#define REG_WKFMCAM_NUM REG_WKFMCAM_CMD +#define REG_WKFMCAM_RWD 0x069C +#define REG_RXFLTMAP0 0x06A0 +#define REG_RXFLTMAP1 0x06A2 +#define REG_RXFLTMAP2 0x06A4 +#define REG_BCN_PSR_RPT 0x06A8 +#define REG_BT_COEX_TABLE 0x06C0 + +// Hardware Port 2 +#define REG_MACID1 0x0700 +#define REG_BSSID1 0x0708 + +/* port0 & port1 enable */ +#define REG_PORT_CTRL 0x76D + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +// for 92DU high_Queue low_Queue Normal_Queue select +#define REG_USB_High_NORMAL_Queue_Select_MAC0 0xFE44 +//#define REG_USB_LOW_Queue_Select_MAC0 0xFE45 +#define REG_USB_High_NORMAL_Queue_Select_MAC1 0xFE47 +//#define REG_USB_LOW_Queue_Select_MAC1 0xFE48 + +// For test chip +#define REG_TEST_USB_TXQS 0xFE48 +#define REG_TEST_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_TEST_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_TEST_SIE_OPTIONAL 0xFE64 +#define REG_TEST_SIE_CHIRP_K 0xFE65 +#define REG_TEST_SIE_PHY 0xFE66 // 0xFE66~0xFE6B +#define REG_TEST_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_TEST_SIE_STRING 0xFE80 // 0xFE80~0xFEB9 + + +// For normal chip +#define REG_NORMAL_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_NORMAL_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 // 0xFE65~0xFE67 +#define REG_NORMAL_SIE_PHY 0xFE68 // 0xFE68~0xFE6B +#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C +#define REG_NORMAL_SIE_GPS_EP 0xFE6D // 0xFE6D, for RTL8723 only. +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_NORMAL_SIE_STRING 0xFE80 // 0xFE80~0xFEDF + + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. + +#define EFUSE_CTRL REG_EFUSE_CTRL // E-Fuse Control. +#define EFUSE_TEST REG_EFUSE_TEST // E-Fuse Test. +#define MSR (REG_CR + 2) // Media Status register +//#define ISR REG_HISR + +#define TSFR REG_TSFTR // Timing Sync Function Timer Register. +#define TSFR1 REG_TSFTR1 // HW Port 1 TSF Register + +#define PBP REG_PBP + +// Redifine MACID register, to compatible prior ICs. +#define IDR0 REG_MACID // MAC ID Register, Offset 0x0050-0x0053 +#define IDR4 (REG_MACID + 4) // MAC ID Register, Offset 0x0054-0x0055 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM REG_CAMCMD //IN 8190 Data Sheet is called CAMcmd +#define WCAMI REG_CAMWRITE // Software write CAM input content +#define RCAMO REG_CAMREAD // Software read/write CAM config +#define CAMDBG REG_CAMDBG +#define SECR REG_SECCFG //Security Configuration Register + +// Unused register +#define UnusedRegister 0x1BF +#define DCAM UnusedRegister +#define PSR UnusedRegister +#define BBAddr UnusedRegister +#define PhyDataR UnusedRegister + +// Min Spacing related settings. +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + +//---------------------------------------------------------------------------- +// 8192C Cmd9346CR bits (Offset 0xA, 16bit) +//---------------------------------------------------------------------------- +#define CmdEEPROM_En BIT5 // EEPROM enable when set 1 +#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 +#define Cmd9346CR_9356SEL BIT4 + +//---------------------------------------------------------------------------- +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO 0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) + +//---------------------------------------------------------------------------- +// 8811A GPIO PIN Control Register (offset 0x60, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN_8811A REG_GPIO_PIN_CTRL_2 // GPIO pins input value +#define GPIO_OUT_8811A (REG_GPIO_PIN_CTRL_2+1) // GPIO pins output value +#define GPIO_IO_SEL_8811A (REG_GPIO_PIN_CTRL_2+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD_8811A (REG_GPIO_PIN_CTRL_2+3) + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) +//---------------------------------------------------------------------------- +#define HSIMR_GPIO12_0_INT_EN BIT0 +#define HSIMR_SPS_OCP_INT_EN BIT5 +#define HSIMR_RON_INT_EN BIT6 +#define HSIMR_PDN_INT_EN BIT7 +#define HSIMR_GPIO9_INT_EN BIT25 + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) +//---------------------------------------------------------------------------- +#define HSISR_GPIO12_0_INT BIT0 +#define HSISR_SPS_OCP_INT BIT5 +#define HSISR_RON_INT BIT6 +#define HSISR_PDNINT BIT7 +#define HSISR_GPIO9_INT BIT25 + +//---------------------------------------------------------------------------- +// 8192C (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +/* +Network Type +00: No link +01: Link in ad hoc network +10: Link in infrastructure network +11: AP mode +Default: 00b. +*/ +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +//---------------------------------------------------------------------------- +// USB INTR CONTENT +//---------------------------------------------------------------------------- +#define USB_C2H_CMDID_OFFSET 0 +#define USB_C2H_SEQ_OFFSET 1 +#define USB_C2H_EVENT_OFFSET 2 +#define USB_INTR_CPWM_OFFSET 16 +#define USB_INTR_CONTENT_C2H_OFFSET 0 +#define USB_INTR_CONTENT_CPWM1_OFFSET 16 +#define USB_INTR_CONTENT_CPWM2_OFFSET 20 +#define USB_INTR_CONTENT_HISR_OFFSET 48 +#define USB_INTR_CONTENT_HISRE_OFFSET 52 +#define USB_INTR_CONTENT_LENGTH 56 + +//---------------------------------------------------------------------------- +// Response Rate Set Register (offset 0x440, 24bits) +//---------------------------------------------------------------------------- +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 + +#define RRSR_CCK_RATES (RRSR_11M|RRSR_5_5M|RRSR_2M|RRSR_1M) +#define RRSR_OFDM_RATES (RRSR_54M|RRSR_48M|RRSR_36M|RRSR_24M|RRSR_18M|RRSR_12M|RRSR_9M|RRSR_6M) +// WOL bit information +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT0 +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT1 +#define HAL92C_WOL_DISASSOC_EVENT BIT2 +#define HAL92C_WOL_DEAUTH_EVENT BIT3 +#define HAL92C_WOL_FW_DISCONNECT_EVENT BIT4 + +//---------------------------------------------------------------------------- +// Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + +//CCK +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +//OFDM +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +//MCS 1 Spatial Stream +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +//MCS 2 Spatial Stream +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + + +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\ + RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + +#define RATE_BITMAP_ALL 0xFFFFF + +// Only use CCK 1M rate for ACK +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 +#define RATE_RRSR_WITHOUT_CCK 0xFFFF0 + +//---------------------------------------------------------------------------- +// BW_OPMODE bits (Offset 0x603, 8bit) +//---------------------------------------------------------------------------- +#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_5G BIT1 + +//---------------------------------------------------------------------------- +// CAM Config Setting (offset 0x680, 1 byte) +//---------------------------------------------------------------------------- +#define CAM_VALID BIT15 +#define CAM_NOTVALID 0x0000 +#define CAM_USEDK BIT5 + +#define CAM_CONTENT_COUNT 8 + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_CONFIG_USEDK _TRUE +#define CAM_CONFIG_NO_USEDK _FALSE + +#define CAM_WRITE BIT16 +#define CAM_READ 0x00000000 +#define CAM_POLLINIG BIT31 + +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 + +// +// 10. Power Save Control Registers +// +#define WOW_PMEN BIT0 // Power management Enable. +#define WOW_WOMEN BIT1 // WoW function on or off. +#define WOW_MAGIC BIT2 // Magic packet +#define WOW_UWF BIT3 // Unicast Wakeup frame. + +// +// 12. Host Interrupt Status Registers +// +//---------------------------------------------------------------------------- +// 8190 IMR/ISR bits +//---------------------------------------------------------------------------- +#define IMR8190_DISABLED 0x0 +#define IMR_DISABLED 0x0 +// IMR DW0 Bit 0-31 +#define IMR_BCNDMAINT6 BIT31 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5 BIT30 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4 BIT29 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3 BIT28 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2 BIT27 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1 BIT26 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK8 BIT25 // Beacon Queue DMA OK Interrup 8 +#define IMR_BCNDOK7 BIT24 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6 BIT23 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5 BIT22 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4 BIT21 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3 BIT20 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2 BIT19 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1 BIT18 // Beacon Queue DMA OK Interrup 1 +#define IMR_TIMEOUT2 BIT17 // Timeout interrupt 2 +#define IMR_TIMEOUT1 BIT16 // Timeout interrupt 1 +#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow +#define IMR_PSTIMEOUT BIT14 // Power save time out interrupt +#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 +#define IMR_RXFOVW BIT12 // Receive FIFO Overflow +#define IMR_RDU BIT11 // Receive Descriptor Unavailable +#define IMR_ATIMEND BIT10 // For 92C,ATIM Window End Interrupt. For 8723 and later ICs, it also means P2P CTWin End interrupt. +#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup +#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt +#define IMR_TBDOK BIT7 // Transmit Beacon OK interrup +#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define IMR_TBDER BIT5 // For 92C,Transmit Beacon Error Interrupt +#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt +#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt +#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt +#define IMR_VODOK BIT1 // AC_VO DMA Interrupt +#define IMR_ROK BIT0 // Receive DMA OK Interrupt + +// 13. Host Interrupt Status Extension Register (Offset: 0x012C-012Eh) +#define IMR_TSF_BIT32_TOGGLE BIT15 +#define IMR_BcnInt_E BIT12 +#define IMR_TXERR BIT11 +#define IMR_RXERR BIT10 +#define IMR_C2HCMD BIT9 +#define IMR_CPWM BIT8 +//RSVD [2-7] +#define IMR_OCPINT BIT1 +#define IMR_WLANOFF BIT0 + +//---------------------------------------------------------------------------- +// 8723E series PCIE Host IMR/ISR bit +//---------------------------------------------------------------------------- +// IMR DW0 Bit 0-31 +#define PHIMR_TIMEOUT2 BIT31 +#define PHIMR_TIMEOUT1 BIT30 +#define PHIMR_PSTIMEOUT BIT29 +#define PHIMR_GTINT4 BIT28 +#define PHIMR_GTINT3 BIT27 +#define PHIMR_TXBCNERR BIT26 +#define PHIMR_TXBCNOK BIT25 +#define PHIMR_TSF_BIT32_TOGGLE BIT24 +#define PHIMR_BCNDMAINT3 BIT23 +#define PHIMR_BCNDMAINT2 BIT22 +#define PHIMR_BCNDMAINT1 BIT21 +#define PHIMR_BCNDMAINT0 BIT20 +#define PHIMR_BCNDOK3 BIT19 +#define PHIMR_BCNDOK2 BIT18 +#define PHIMR_BCNDOK1 BIT17 +#define PHIMR_BCNDOK0 BIT16 +#define PHIMR_HSISR_IND_ON BIT15 +#define PHIMR_BCNDMAINT_E BIT14 +#define PHIMR_ATIMEND_E BIT13 +#define PHIMR_ATIM_CTW_END BIT12 +#define PHIMR_HISRE_IND BIT11 // RO. HISRE Indicator (HISRE & HIMRE is true, this bit is set to 1) +#define PHIMR_C2HCMD BIT10 +#define PHIMR_CPWM2 BIT9 +#define PHIMR_CPWM BIT8 +#define PHIMR_HIGHDOK BIT7 // High Queue DMA OK Interrupt +#define PHIMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define PHIMR_BKDOK BIT5 // AC_BK DMA OK Interrupt +#define PHIMR_BEDOK BIT4 // AC_BE DMA OK Interrupt +#define PHIMR_VIDOK BIT3 // AC_VI DMA OK Interrupt +#define PHIMR_VODOK BIT2 // AC_VO DMA Interrupt +#define PHIMR_RDU BIT1 // Receive Descriptor Unavailable +#define PHIMR_ROK BIT0 // Receive DMA OK Interrupt + +// PCIE Host Interrupt Status Extension bit +#define PHIMR_BCNDMAINT7 BIT23 +#define PHIMR_BCNDMAINT6 BIT22 +#define PHIMR_BCNDMAINT5 BIT21 +#define PHIMR_BCNDMAINT4 BIT20 +#define PHIMR_BCNDOK7 BIT19 +#define PHIMR_BCNDOK6 BIT18 +#define PHIMR_BCNDOK5 BIT17 +#define PHIMR_BCNDOK4 BIT16 +// bit12 15: RSVD +#define PHIMR_TXERR BIT11 +#define PHIMR_RXERR BIT10 +#define PHIMR_TXFOVW BIT9 +#define PHIMR_RXFOVW BIT8 +// bit2-7: RSVD +#define PHIMR_OCPINT BIT1 +// bit0: RSVD + +#define UHIMR_TIMEOUT2 BIT31 +#define UHIMR_TIMEOUT1 BIT30 +#define UHIMR_PSTIMEOUT BIT29 +#define UHIMR_GTINT4 BIT28 +#define UHIMR_GTINT3 BIT27 +#define UHIMR_TXBCNERR BIT26 +#define UHIMR_TXBCNOK BIT25 +#define UHIMR_TSF_BIT32_TOGGLE BIT24 +#define UHIMR_BCNDMAINT3 BIT23 +#define UHIMR_BCNDMAINT2 BIT22 +#define UHIMR_BCNDMAINT1 BIT21 +#define UHIMR_BCNDMAINT0 BIT20 +#define UHIMR_BCNDOK3 BIT19 +#define UHIMR_BCNDOK2 BIT18 +#define UHIMR_BCNDOK1 BIT17 +#define UHIMR_BCNDOK0 BIT16 +#define UHIMR_HSISR_IND BIT15 +#define UHIMR_BCNDMAINT_E BIT14 +//RSVD BIT13 +#define UHIMR_CTW_END BIT12 +//RSVD BIT11 +#define UHIMR_C2HCMD BIT10 +#define UHIMR_CPWM2 BIT9 +#define UHIMR_CPWM BIT8 +#define UHIMR_HIGHDOK BIT7 // High Queue DMA OK Interrupt +#define UHIMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt +#define UHIMR_BKDOK BIT5 // AC_BK DMA OK Interrupt +#define UHIMR_BEDOK BIT4 // AC_BE DMA OK Interrupt +#define UHIMR_VIDOK BIT3 // AC_VI DMA OK Interrupt +#define UHIMR_VODOK BIT2 // AC_VO DMA Interrupt +#define UHIMR_RDU BIT1 // Receive Descriptor Unavailable +#define UHIMR_ROK BIT0 // Receive DMA OK Interrupt + +// USB Host Interrupt Status Extension bit +#define UHIMR_BCNDMAINT7 BIT23 +#define UHIMR_BCNDMAINT6 BIT22 +#define UHIMR_BCNDMAINT5 BIT21 +#define UHIMR_BCNDMAINT4 BIT20 +#define UHIMR_BCNDOK7 BIT19 +#define UHIMR_BCNDOK6 BIT18 +#define UHIMR_BCNDOK5 BIT17 +#define UHIMR_BCNDOK4 BIT16 +// bit14-15: RSVD +#define UHIMR_ATIMEND_E BIT13 +#define UHIMR_ATIMEND BIT12 +#define UHIMR_TXERR BIT11 +#define UHIMR_RXERR BIT10 +#define UHIMR_TXFOVW BIT9 +#define UHIMR_RXFOVW BIT8 +// bit2-7: RSVD +#define UHIMR_OCPINT BIT1 +// bit0: RSVD + + +#define HAL_NIC_UNPLUG_ISR 0xFFFFFFFF // The value when the NIC is unplugged for PCI. +#define HAL_NIC_UNPLUG_PCI_ISR 0xEAEAEAEA // The value when the NIC is unplugged for PCI in PCI interrupt (page 3). + +//---------------------------------------------------------------------------- +// 8188 IMR/ISR bits +//---------------------------------------------------------------------------- +#define IMR_DISABLED_88E 0x0 +// IMR DW0(0x0060-0063) Bit 0-31 +#define IMR_TXCCK_88E BIT30 // TXRPT interrupt when CCX bit of the packet is set +#define IMR_PSTIMEOUT_88E BIT29 // Power Save Time Out Interrupt +#define IMR_GTINT4_88E BIT28 // When GTIMER4 expires, this bit is set to 1 +#define IMR_GTINT3_88E BIT27 // When GTIMER3 expires, this bit is set to 1 +#define IMR_TBDER_88E BIT26 // Transmit Beacon0 Error +#define IMR_TBDOK_88E BIT25 // Transmit Beacon0 OK +#define IMR_TSF_BIT32_TOGGLE_88E BIT24 // TSF Timer BIT32 toggle indication interrupt +#define IMR_BCNDMAINT0_88E BIT20 // Beacon DMA Interrupt 0 +#define IMR_BCNDERR0_88E BIT16 // Beacon Queue DMA Error 0 +#define IMR_HSISR_IND_ON_INT_88E BIT15 // HSISR Indicator (HSIMR & HSISR is true, this bit is set to 1) +#define IMR_BCNDMAINT_E_88E BIT14 // Beacon DMA Interrupt Extension for Win7 +#define IMR_ATIMEND_88E BIT12 // CTWidnow End or ATIM Window End +#define IMR_HISR1_IND_INT_88E BIT11 // HISR1 Indicator (HISR1 & HIMR1 is true, this bit is set to 1) +#define IMR_C2HCMD_88E BIT10 // CPU to Host Command INT Status, Write 1 clear +#define IMR_CPWM2_88E BIT9 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_CPWM_88E BIT8 // CPU power Mode exchange INT Status, Write 1 clear +#define IMR_HIGHDOK_88E BIT7 // High Queue DMA OK +#define IMR_MGNTDOK_88E BIT6 // Management Queue DMA OK +#define IMR_BKDOK_88E BIT5 // AC_BK DMA OK +#define IMR_BEDOK_88E BIT4 // AC_BE DMA OK +#define IMR_VIDOK_88E BIT3 // AC_VI DMA OK +#define IMR_VODOK_88E BIT2 // AC_VO DMA OK +#define IMR_RDU_88E BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_88E BIT0 // Receive DMA OK + +// IMR DW1(0x00B4-00B7) Bit 0-31 +#define IMR_BCNDMAINT7_88E BIT27 // Beacon DMA Interrupt 7 +#define IMR_BCNDMAINT6_88E BIT26 // Beacon DMA Interrupt 6 +#define IMR_BCNDMAINT5_88E BIT25 // Beacon DMA Interrupt 5 +#define IMR_BCNDMAINT4_88E BIT24 // Beacon DMA Interrupt 4 +#define IMR_BCNDMAINT3_88E BIT23 // Beacon DMA Interrupt 3 +#define IMR_BCNDMAINT2_88E BIT22 // Beacon DMA Interrupt 2 +#define IMR_BCNDMAINT1_88E BIT21 // Beacon DMA Interrupt 1 +#define IMR_BCNDOK7_88E BIT20 // Beacon Queue DMA OK Interrup 7 +#define IMR_BCNDOK6_88E BIT19 // Beacon Queue DMA OK Interrup 6 +#define IMR_BCNDOK5_88E BIT18 // Beacon Queue DMA OK Interrup 5 +#define IMR_BCNDOK4_88E BIT17 // Beacon Queue DMA OK Interrup 4 +#define IMR_BCNDOK3_88E BIT16 // Beacon Queue DMA OK Interrup 3 +#define IMR_BCNDOK2_88E BIT15 // Beacon Queue DMA OK Interrup 2 +#define IMR_BCNDOK1_88E BIT14 // Beacon Queue DMA OK Interrup 1 +#define IMR_ATIMEND_E_88E BIT13 // ATIM Window End Extension for Win7 +#define IMR_TXERR_88E BIT11 // Tx Error Flag Interrupt Status, write 1 clear. +#define IMR_RXERR_88E BIT10 // Rx Error Flag INT Status, Write 1 clear +#define IMR_TXFOVW_88E BIT9 // Transmit FIFO Overflow +#define IMR_RXFOVW_88E BIT8 // Receive FIFO Overflow + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ + //---------------------------------------------------------------------------- + // 8192C (TXPAUSE) transmission pause (Offset 0x522, 8 bits) + //---------------------------------------------------------------------------- +// Note: +// The the bits of stoping AC(VO/VI/BE/BK) queue in datasheet RTL8192S/RTL8192C are wrong, +// the correct arragement is VO - Bit0, VI - Bit1, BE - Bit2, and BK - Bit3. +// 8723 and 88E may be not correct either in the eralier version. Confirmed with DD Tim. +// By Bruce, 2011-09-22. +#define StopBecon BIT6 +#define StopHigh BIT5 +#define StopMgt BIT4 +#define StopBK BIT3 +#define StopBE BIT2 +#define StopVI BIT1 +#define StopVO BIT0 + +//---------------------------------------------------------------------------- +// 8192C (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +#define RCR_APPFCS BIT31 // WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // MACRX will retain the MIC at the bottom of the packet. +#define RCR_APP_ICV BIT29 // MACRX will retain the ICV at the bottom of the packet. +#define RCR_APP_PHYST_RXFF BIT28 // PHY Status is appended before RX packet in RXFF +#define RCR_APP_BA_SSN BIT27 // SSN of previous TXBA is appended as after original RXDESC as the 4-th DW of RXDESC. +#define RCR_NONQOS_VHT BIT26 // Reserved +#define RCR_RSVD_BIT25 BIT25 // Reserved +#define RCR_ENMBID BIT24 // Enable Multiple BssId. Only response ACK to the packets whose DID(A1) matching to the addresses in the MBSSID CAM Entries. +#define RCR_LSIGEN BIT23 // Enable LSIG TXOP Protection function. Search KEYCAM for each rx packet to check if LSIGEN bit is set. +#define RCR_MFBEN BIT22 // Enable immediate MCS Feedback function. When Rx packet with MRQ = 1'b1, then search KEYCAM to find sender's MCS Feedback function and send response. +#define RCR_RSVD_BIT21 BIT21 // Reserved +#define RCR_RSVD_BIT20 BIT20 // Reserved +#define RCR_RSVD_BIT19 BIT19 // Reserved +#define RCR_TIM_PARSER_EN BIT18 // RX Beacon TIM Parser. +#define RCR_BM_DATA_EN BIT17 // Broadcast data packet interrupt enable. +#define RCR_UC_DATA_EN BIT16 // Unicast data packet interrupt enable. +#define RCR_RSVD_BIT15 BIT15 // Reserved +#define RCR_HTC_LOC_CTRL BIT14 // MFC<--HTC=1 MFC-->HTC=0 +#define RCR_AMF BIT13 // Accept management type frame +#define RCR_ACF BIT12 // Accept control type frame. Control frames BA, BAR, and PS-Poll (when in AP mode) are not controlled by this bit. They are controlled by ADF. +#define RCR_ADF BIT11 // Accept data type frame. This bit also regulates BA, BAR, and PS-Poll (AP mode only). +#define RCR_RSVD_BIT10 BIT10 // Reserved +#define RCR_AICV BIT9 // Accept ICV error packet +#define RCR_ACRC32 BIT8 // Accept CRC32 error packet +#define RCR_CBSSID_BCN BIT7 // Accept BSSID match packet (Rx beacon, probe rsp) +#define RCR_CBSSID_DATA BIT6 // Accept BSSID match packet (Data) +#define RCR_CBSSID RCR_CBSSID_DATA // Accept BSSID match packet +#define RCR_APWRMGT BIT5 // Accept power management packet +#define RCR_ADD3 BIT4 // Accept address 3 match packet +#define RCR_AB BIT3 // Accept broadcast packet +#define RCR_AM BIT2 // Accept multicast packet +#define RCR_APM BIT1 // Accept physical match packet +#define RCR_AAP BIT0 // Accept all unicast packet + + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- + +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +//#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) + + +//2 9346CR /REG_SYS_EEPROM_CTRL +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROMSEL BIT(4) +#define EEPROM_EN BIT(5) + + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + + +//2 EFUSE_TEST (For RTL8723 partially) +#define EF_TRPT BIT(7) +#define EF_CELL_SEL (BIT(8)|BIT(9)) // 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 +#define LDOE25_EN BIT(31) +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +#define EFUSE_BT_SEL_0 0x1 +#define EFUSE_BT_SEL_1 0x2 +#define EFUSE_BT_SEL_2 0x3 + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define RAM_DL_SEL BIT(7) +#define ROM_DLEN BIT(19) +#define CPRST BIT(23) + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define SW_OFFLOAD_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define EXT_VENDOR_ID (BIT(18)|BIT(19)) //Currently only for RTL8723B +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) // RTL ID +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) +#define RF_TYPE_ID BIT(27) + +#define RTL_ID BIT(23) // TestChip ID, 1:Test(RLE); 0:MP(RL) +#define SPS_SEL BIT(24) // 1:LDO regulator mode; 0:Switching regulator mode + + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 +#define EXT_VENDOR_ID_SHIFT 18 + +//2 REG_GPIO_OUTSTS (For RTL8723 only) +#define EFS_HCI_SEL (BIT(0)|BIT(1)) +#define PAD_HCI_SEL (BIT(2)|BIT(3)) +#define HCI_SEL (BIT(4)|BIT(5)) +#define PKG_SEL_HCI BIT(6) +#define FEN_GPS BIT(7) +#define FEN_BT BIT(8) +#define FEN_WL BIT(9) +#define FEN_PCI BIT(10) +#define FEN_USB BIT(11) +#define BTRF_HWPDN_N BIT(12) +#define WLRF_HWPDN_N BIT(13) +#define PDN_BT_N BIT(14) +#define PDN_GPS_N BIT(15) +#define BT_CTL_HWPDN BIT(16) +#define GPS_CTL_HWPDN BIT(17) +#define PPHY_SUSB BIT(20) +#define UPHY_SUSB BIT(21) +#define PCI_SUSEN BIT(22) +#define USB_SUSEN BIT(23) +#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) + + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + +//2 Function Enable Registers +//2 CR +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) +#define CALTMR_EN BIT(10) // 32k CAL TMR enable + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + +//2 PBP - Page Size Register +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_CMQ_MAP(x) (((x)&0x3) << 16) +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_EXTRA 0 +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + +//2 TRXFF_BNDY + + +//2 LLT_INIT +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((u32)(x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +//2 RQPN +#define _HPQ(x) ((x) & 0xFF) +#define _LPQ(x) (((x) & 0xFF) << 8) +#define _PUBQ(x) (((x) & 0xFF) << 16) +#define _NPQ(x) ((x) & 0xFF) // NOTE: in RQPN_NPQ register +#define _EPQ(x) (((x) & 0xFF) << 16) // NOTE: in RQPN_EPQ register + + +#define HPQ_PUBLIC_DIS BIT(24) +#define LPQ_PUBLIC_DIS BIT(25) +#define LD_RQPN BIT(31) + + +//2 TDECTL +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK +#define DROP_DATA_EN BIT(9) + +//2 AUTO_LLT +#define BIT_SHIFT_TXPKTNUM 24 +#define BIT_MASK_TXPKTNUM 0xff +#define BIT_TXPKTNUM(x) (((x) & BIT_MASK_TXPKTNUM) << BIT_SHIFT_TXPKTNUM) + +#define BIT_TDE_DBG_SEL BIT(23) +#define BIT_AUTO_INIT_LLT BIT(16) + +#define BIT_SHIFT_Tx_OQT_free_space 8 +#define BIT_MASK_Tx_OQT_free_space 0xff +#define BIT_Tx_OQT_free_space(x) (((x) & BIT_MASK_Tx_OQT_free_space) << BIT_SHIFT_Tx_OQT_free_space) + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x028Bh RX DMA Configuration +// +//----------------------------------------------------- + +//2 REG_RXDMA_CONTROL, 0x0286h +// Write only. When this bit is set, RXDMA will decrease RX PKT counter by one. Before +// this bit is polled, FW shall update RXFF_RD_PTR first. This register is write pulse and auto clear. +//#define RXPKT_RELEASE_POLL BIT(0) +// Read only. When RXMA finishes on-going DMA operation, RXMDA will report idle state in +// this bit. FW can start releasing packets after RXDMA entering idle mode. +//#define RXDMA_IDLE BIT(1) +// When this bit is set, RXDMA will enter this mode after on-going RXDMA packet to host +// completed, and stop DMA packet to host. RXDMA will then report Default: 0; +//#define RW_RELEASE_EN BIT(2) + +//2 REG_RXPKT_NUM, 0x0284 +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +//2 CPU_MGT_INFORMATION +#define CPUMGT_POLL BIT(5) + +//2 FWHW_TXQ_CTRL +#define EN_AMPDU_RTY_NEW BIT(7) + + +//2 SPEC SIFS +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +//2 RL +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//2 EDCA setting +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) + + +//2 BCN_CTRL +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) +#define STOP_BCNQ BIT(6) +#define DIS_RX_BSSID_FIT BIT(6) + +#define DIS_ATIM BIT(0) +#define DIS_BCNQ_SUB BIT(1) +#define DIS_TSF_UDT BIT(4) + +// The same function but different bit field. +#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) +#define DIS_TSF_UDT0_TEST_CHIP BIT(5) + + +//2 ACMHWCTRL +#define AcmHw_HwEn BIT(0) +#define AcmHw_BeqEn BIT(1) +#define AcmHw_ViqEn BIT(2) +#define AcmHw_VoqEn BIT(3) +#define AcmHw_BeqStatus BIT(4) +#define AcmHw_ViqStatus BIT(5) +#define AcmHw_VoqStatus BIT(6) + +//2 //REG_DUAL_TSF_RST (0x553) +#define DUAL_TSF_RST_P2P BIT(4) + +//2 // REG_NOA_DESC_SEL (0x5CF) +#define NOA_DESC_SEL_0 0 +#define NOA_DESC_SEL_1 BIT(4) + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +//2 APSD_CTRL +#define APSDOFF BIT(6) + +//2 TCR +#define TSFRST BIT(0) +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + + +//2 RCR +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define FORCEACK BIT(26) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +#define APP_FCS BIT(31) + + +//2 SECCFG +#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key +#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key +#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption +#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption +#define SCR_SKByA2 BIT(4) //Search kEY BY A2 +#define SCR_NoSKMC BIT(5) //No Key Search Multicast +#define SCR_TXBCUSEDK BIT(6) // Force Tx Broadcast packets Use Default Key +#define SCR_RXBCUSEDK BIT(7) // Force Rx Broadcast packets Use Default Key + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe/LBus +// +//----------------------------------------------------- + + +//4 REG_LX_CTRL1(0x300) +#define BIT_WT_LIT_EDN BIT(25) +#define BIT_RD_LITT_EDN BIT(24) + +#define BIT_SHIFT_MAX_RXDMA 20 +#define BIT_MASK_MAX_RXDMA 0x7 +#define BIT_MAX_RXDMA(x) (((x) & BIT_MASK_MAX_RXDMA)<HardwareType >=HARDWARE_TYPE_RTL8192EE) +// +// RTL8192C Series +// +#define IS_HARDWARE_TYPE_8192CE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192CE) +#define IS_HARDWARE_TYPE_8192CU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192CU) +#define IS_HARDWARE_TYPE_8192C(_Adapter) \ +(IS_HARDWARE_TYPE_8192CE(_Adapter) || IS_HARDWARE_TYPE_8192CU(_Adapter)) + +// +// RTL8192D Series +// +#define IS_HARDWARE_TYPE_8192DE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192DE) +#define IS_HARDWARE_TYPE_8192DU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192DU) +#define IS_HARDWARE_TYPE_8192D(_Adapter) \ +(IS_HARDWARE_TYPE_8192DE(_Adapter) || IS_HARDWARE_TYPE_8192DU(_Adapter)) + +// +// RTL8723A Series +// +#define IS_HARDWARE_TYPE_8723AE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AE) +#define IS_HARDWARE_TYPE_8723AU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AU) +#define IS_HARDWARE_TYPE_8723AS(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723AS) +#define IS_HARDWARE_TYPE_8723A(_Adapter) \ +(IS_HARDWARE_TYPE_8723AE(_Adapter) || IS_HARDWARE_TYPE_8723AU(_Adapter) || IS_HARDWARE_TYPE_8723AS(_Adapter)) +// +// RTL8188E Series +// +#define IS_HARDWARE_TYPE_8188EE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188EE) +#define IS_HARDWARE_TYPE_8188EU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188EU) +#define IS_HARDWARE_TYPE_8188ES(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188ES) +#define IS_HARDWARE_TYPE_8188E(_Adapter) \ +(IS_HARDWARE_TYPE_8188EE(_Adapter) || IS_HARDWARE_TYPE_8188EU(_Adapter) || IS_HARDWARE_TYPE_8188ES(_Adapter)) +// +//RTL8188F Series +// +#define IS_HARDWARE_TYPE_8188FE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188FE) +#define IS_HARDWARE_TYPE_8188FU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188EU) +#define IS_HARDWARE_TYPE_8188FS(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8188FS) +#define IS_HARDWARE_TYPE_8188F(_Adapter) \ +(IS_HARDWARE_TYPE_8188FE(_Adapter) || IS_HARDWARE_TYPE_8188FU(_Adapter) || IS_HARDWARE_TYPE_8188FS(_Adapter)) +// +// RTL8812 Series +// +#define IS_HARDWARE_TYPE_8812E(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8812E) +#define IS_HARDWARE_TYPE_8812AU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8812AU) +#define IS_HARDWARE_TYPE_8812(_Adapter) \ +(IS_HARDWARE_TYPE_8812E(_Adapter) || IS_HARDWARE_TYPE_8812AU(_Adapter)) + +// RTL8821 Series +#define IS_HARDWARE_TYPE_8821E(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8821E) +#define IS_HARDWARE_TYPE_8821U(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8821U ||\ + ((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8811AU) +#define IS_HARDWARE_TYPE_8821S(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8821S) +#define IS_HARDWARE_TYPE_8821(_Adapter) \ +(IS_HARDWARE_TYPE_8821E(_Adapter) || IS_HARDWARE_TYPE_8821U(_Adapter)|| IS_HARDWARE_TYPE_8821S(_Adapter)) + +#define IS_HARDWARE_TYPE_JAGUAR(_Adapter) \ +(IS_HARDWARE_TYPE_8812(_Adapter) || IS_HARDWARE_TYPE_8821(_Adapter)) + +//RTL8192E Series +#define IS_HARDWARE_TYPE_8192EE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192EE) +#define IS_HARDWARE_TYPE_8192EU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192EU) +#define IS_HARDWARE_TYPE_8192ES(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8192ES) + +#define IS_HARDWARE_TYPE_8192E(_Adapter) \ +(IS_HARDWARE_TYPE_8192EE(_Adapter) || IS_HARDWARE_TYPE_8192EU(_Adapter) ||IS_HARDWARE_TYPE_8192ES(_Adapter)) + +#define IS_HARDWARE_TYPE_8723BE(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723BE) +#define IS_HARDWARE_TYPE_8723BU(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723BU) +#define IS_HARDWARE_TYPE_8723BS(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8723BS) + + +#define IS_HARDWARE_TYPE_8723B(_Adapter) \ + (IS_HARDWARE_TYPE_8723BE(_Adapter) || IS_HARDWARE_TYPE_8723BU(_Adapter) ||IS_HARDWARE_TYPE_8723BS(_Adapter)) + +#define IS_HARDWARE_TYPE_8195A(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8195A) + +#define IS_HARDWARE_TYPE_8711B(_Adapter) (((_adapter *)_Adapter)->HardwareType==HARDWARE_TYPE_RTL8711B) + +typedef struct eeprom_priv EEPROM_EFUSE_PRIV, *PEEPROM_EFUSE_PRIV; +#define GET_EEPROM_EFUSE_PRIV(adapter) (&adapter->eeprompriv) +#define is_boot_from_eeprom(adapter) (adapter->eeprompriv.EepromOrEfuse) + +//TODO + +#ifdef CONFIG_WOWLAN +typedef enum _wowlan_subcode{ + WOWLAN_PATTERN_MATCH = 1, + WOWLAN_MAGIC_PACKET = 2, + WOWLAN_UNICAST = 3, + WOWLAN_SET_PATTERN = 4, + WOWLAN_DUMP_REG = 5, + WOWLAN_ENABLE = 6, + WOWLAN_DISABLE = 7, + WOWLAN_STATUS = 8, + WOWLAN_DEBUG_RELOAD_FW = 9, + WOWLAN_DEBUG_1 =10, + WOWLAN_DEBUG_2 =11 +}wowlan_subcode; + +struct wowlan_ioctl_param{ + unsigned int subcode; + unsigned int subcode_value; + unsigned int wakeup_reason; + unsigned int len; + unsigned char pattern[0]; +}; + +#define Rx_Pairwisekey 0x01 +#define Rx_GTK 0x02 +#define Rx_DisAssoc 0x04 +#define Rx_DeAuth 0x08 +#define FWDecisionDisconnect 0x10 +#define Rx_MagicPkt 0x21 +#define Rx_UnicastPkt 0x22 +#define Rx_PatternPkt 0x23 +#endif // CONFIG_WOWLAN + +void rtw_hal_def_value_init(_adapter *padapter); + +void rtw_hal_free_data(_adapter *padapter); + +void rtw_hal_dm_init(_adapter *padapter); +void rtw_hal_dm_deinit(_adapter *padapter); +#if 0 +void rtw_hal_sw_led_init(_adapter *padapter); +void rtw_hal_sw_led_deinit(_adapter *padapter); +#endif +u32 rtw_hal_power_on(_adapter *padapter); +uint rtw_hal_init(_adapter *padapter); +uint rtw_hal_deinit(_adapter *padapter); +void rtw_hal_stop(_adapter *padapter); +void rtw_hal_set_hwreg(PADAPTER padapter, u8 variable, u8 *val); +void rtw_hal_get_hwreg(PADAPTER padapter, u8 variable, u8 *val); + +void rtw_hal_chip_configure(_adapter *padapter); +void rtw_hal_read_chip_info(_adapter *padapter); +void rtw_hal_read_chip_version(_adapter *padapter); + +u8 rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); +u8 rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); + +void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet); +void rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1,BOOLEAN bSet); + +void rtw_hal_enable_interrupt(_adapter *padapter); +void rtw_hal_disable_interrupt(_adapter *padapter); +void rtw_hal_clear_interrupt(_adapter *padapter); +#ifdef CONFIG_WOWLAN +void rtw_hal_disable_interrupt_but_cpwm2(_adapter *padapter); +#endif + +u32 rtw_hal_inirp_init(_adapter *padapter); +u32 rtw_hal_inirp_deinit(_adapter *padapter); + +void rtw_hal_irp_reset(_adapter *padapter); +#if 0 +u8 rtw_hal_intf_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id, u8* val); +#endif +s32 rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); + +s32 rtw_hal_init_xmit_priv(_adapter *padapter); +void rtw_hal_free_xmit_priv(_adapter *padapter); + +#if 1 +s32 rtw_hal_init_recv_priv(_adapter *padapter); +void rtw_hal_free_recv_priv(_adapter *padapter); +#endif + +void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level); +void rtw_hal_add_ra_tid(_adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_level); +void rtw_hal_clone_data(_adapter *dst_padapter, _adapter *src_padapter); +#ifdef CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD +void rtw_hal_start_thread(_adapter *padapter); +void rtw_hal_stop_thread(_adapter *padapter); +#endif +void rtw_hal_bcn_related_reg_setting(_adapter *padapter); + +u32 rtw_hal_read_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask); +void rtw_hal_write_bbreg(_adapter *padapter, u32 RegAddr, u32 BitMask, u32 Data); +u32 rtw_hal_read_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask); +void rtw_hal_write_rfreg(_adapter *padapter, u32 eRFPath, u32 RegAddr, u32 BitMask, u32 Data); + +s32 rtw_hal_interrupt_handler(_adapter *padapter); + +void rtw_hal_set_bwmode(_adapter *padapter, CHANNEL_WIDTH Bandwidth, u8 Offset); +void rtw_hal_set_chan(_adapter *padapter, u8 channel); +void rtw_hal_set_chnl_bw(_adapter *padapter, u8 channel, CHANNEL_WIDTH Bandwidth, u8 Offset40, u8 Offset80); +void rtw_hal_dm_watchdog(_adapter *padapter); +#if 1 +void rtw_hal_update_txdesc(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pbuf); +#endif +s32 rtw_hal_fill_h2c_cmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); + +void rtw_hal_fill_fake_txdesc(_adapter* padapter, u8* pDesc, u32 BufferLen, + u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +u8 rtw_hal_get_txbuff_rsvd_page_num(_adapter *padapter, bool wowlan); + + +void rtw_hal_set_wowlan_fw(_adapter *padapter, u8 sleep); + + +c2h_id_filter rtw_hal_c2h_id_filter_ccx(_adapter *padapter); + +s32 rtw_hal_c2h_handler(_adapter *padapter, u8 *c2h_evt); + + +#ifdef CONFIG_ANTENNA_DIVERSITY +u8 rtw_hal_antdiv_before_linked(_adapter *padapter); +void rtw_hal_antdiv_rssi_compared(_adapter *padapter, WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src); +#endif + +#ifdef CONFIG_HOSTAPD_MLME +s32 rtw_hal_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt); +#endif + +#ifdef DBG_CONFIG_ERROR_DETECT +void rtw_hal_sreset_init(_adapter *padapter); +void rtw_hal_sreset_reset(_adapter *padapter); +void rtw_hal_sreset_reset_value(_adapter *padapter); +void rtw_hal_sreset_xmit_status_check(_adapter *padapter); +void rtw_hal_sreset_linked_status_check (_adapter *padapter); +u8 rtw_hal_sreset_get_wifi_status(_adapter *padapter); +#endif + +#ifdef CONFIG_IOL +int rtw_hal_iol_cmd(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) +#endif + +#if 0//def CONFIG_XMIT_THREAD_MODE +s32 rtw_hal_xmit_thread_handler(_adapter *padapter); +#endif + +s32 rtw_hal_recv_tasklet(_adapter *padapter); +#if (RTW_NOTCH_FILTER != 0) +void rtw_hal_notch_filter(_adapter * adapter, bool enable); +#endif +#if 0 +void rtw_hal_reset_security_engine(_adapter * adapter); +#endif + +void decide_chip_type_by_device_id(_adapter *padapter); + + +#ifdef CONFIG_RTL8723A +void rtl8723as_set_hal_ops(PADAPTER padapter); +#define hal_set_hal_ops(__adapter) rtl8723as_set_hal_ops(__adapter) +#endif + +#ifdef CONFIG_RTL8188E +u32 rtl8188e_set_hal_ops(PADAPTER padapter); +#define hal_set_hal_ops(__adapter) rtl8188e_set_hal_ops(__adapter) +#endif + +#ifdef CONFIG_RTL8188F +u32 rtl8188fs_set_hal_ops(PADAPTER padapter); +#define hal_set_hal_ops(__adapter) rtl8188fs_set_hal_ops(__adapter) +#endif + +#ifdef CONFIG_RTL8195A +u32 rtl8195ab_set_hal_ops(_adapter * padapter); +#define hal_set_hal_ops rtl8195ab_set_hal_ops +#define hal_interuupt_recognized InterruptRecognized8195a +#elif defined(CONFIG_RTL8711B) +u32 rtl8711bb_set_hal_ops(_adapter * padapter); +#define hal_set_hal_ops rtl8711bb_set_hal_ops +#define hal_interuupt_recognized InterruptRecognized8711b +#endif + + +#endif //__HAL_INTF_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_pg.h b/USDK/component/common/drivers/wlan/realtek/include/hal_pg.h new file mode 100644 index 0000000..70d4734 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_pg.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __HAL_PG_H__ +#define __HAL_PG_H__ + +#include + +// +// For VHT series TX power by rate table. +// VHT TX power by rate off setArray = +// Band:-2G&5G = 0 / 1 +// RF: at most 4*4 = ABCD=0/1/2/3 +// CCK=0 OFDM=1/2 HT-MCS 0-15=3/4/56 VHT=7/8/9/10/11 +// +#define PPG_BB_GAIN_2G_TX_OFFSET_MASK 0x0F +#define PPG_BB_GAIN_2G_TXB_OFFSET_MASK 0xF0 + +#define PPG_BB_GAIN_5G_TX_OFFSET_MASK 0x1F +#define PPG_THERMAL_OFFSET_MASK 0x1F +#define KFREE_BB_GAIN_2G_TX_OFFSET(_ppg_v) (((_ppg_v) == PPG_BB_GAIN_2G_TX_OFFSET_MASK) ? 0 : (((_ppg_v) & 0x01) ? ((_ppg_v) >> 1) : (-((_ppg_v) >> 1)))) +#define KFREE_THERMAL_OFFSET(_ppg_v) (((_ppg_v) == PPG_THERMAL_OFFSET_MASK) ? 0 : (((_ppg_v) & 0x01) ? ((_ppg_v) >> 1) : (-((_ppg_v) >> 1)))) + + + +#if defined(NOT_SUPPORT_5G) +#define TX_PWR_BY_RATE_NUM_BAND 1 +#else +#define TX_PWR_BY_RATE_NUM_BAND 2 +#endif + +#if defined(NOT_SUPPORT_RF_MULTIPATH) && defined(NOT_SUPPORT_VHT) +#define TX_PWR_BY_RATE_NUM_RF 1 +#define TX_PWR_BY_RATE_NUM_RATE 20 // CCK 1M~11M, OFDM 6M~54M, MCS0~7 +#else +#define TX_PWR_BY_RATE_NUM_RF 4 +#define TX_PWR_BY_RATE_NUM_RATE 84 +#endif + +#if defined(NOT_SUPPORT_RF_MULTIPATH) +#define MAX_RF_PATH 1 +#define MAX_TX_COUNT 1 +#else +#define MAX_RF_PATH 2 // Max 4 for ss larger than 2 +#define MAX_TX_COUNT 4 //It must always set to 4, otherwise read efuse table secquence will be wrong. +#endif +#define MAX_CHNL_GROUP_24G 6 // ch1~2, ch3~5, ch6~8,ch9~11,ch12~13,CH 14 total three groups +#define MAX_CHNL_GROUP_5G 14 + +typedef struct _TxPowerInfo24G{ + u8 IndexCCK_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + u8 IndexBW40_Base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; + //If only one tx, only BW20 and OFDM are used. + s8 OFDM_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +#if !defined(NOT_SUPPORT_RF_MULTIPATH) + s8 CCK_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +#endif +}TxPowerInfo24G, *PTxPowerInfo24G; + +#endif + + diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_phy.h b/USDK/component/common/drivers/wlan/realtek/include/hal_phy.h new file mode 100644 index 0000000..1488005 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_phy.h @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_PHY_H__ +#define __HAL_PHY_H__ + +#define RF6052_MAX_TX_PWR 0x3F +#define RF6052_MAX_REG_88E 0xFF +#define RF6052_MAX_REG_92C 0x7F + +#define RF6052_MAX_REG \ + (RF6052_MAX_REG_88E > RF6052_MAX_REG_92C) ? RF6052_MAX_REG_88E: RF6052_MAX_REG_92C + +#define GET_RF6052_REAL_MAX_REG(_Adapter) \ + IS_HARDWARE_TYPE_8188E(_Adapter) ? RF6052_MAX_REG_88E : RF6052_MAX_REG_92C + +#define RF6052_MAX_PATH 2 + +/*--------------------------Define Parameters-------------------------------*/ +typedef enum _BAND_TYPE{ + BAND_ON_2_4G = 0, + BAND_ON_5G, + BAND_ON_BOTH, + BANDMAX +}BAND_TYPE,*PBAND_TYPE; + +typedef enum _RF_TYPE{ + RF_TYPE_MIN = 0, // 0 + RF_8225=1, // 1 11b/g RF for verification only + RF_8256=2, // 2 11b/g/n + RF_8258=3, // 3 11a/b/g/n RF + RF_6052=4, // 4 11b/g/n RF + RF_PSEUDO_11N=5, // 5, It is a temporality RF. + RF_TYPE_MAX +}RF_TYPE_E,*PRF_TYPE_E; + +typedef enum _RF_PATH{ + RF_PATH_A = 0, + RF_PATH_B, + RF_PATH_C, + RF_PATH_D +}RF_PATH, *PRF_PATH; + +#define TX_1S 0 +#define TX_2S 1 +#define TX_3S 2 +#define TX_4S 3 + +typedef enum _BaseBand_Config_Type{ + BaseBand_Config_PHY_REG = 0, //Radio Path A + BaseBand_Config_AGC_TAB = 1, //Radio Path B + BaseBand_Config_AGC_TAB_2G = 2, + BaseBand_Config_AGC_TAB_5G = 3, + BaseBand_Config_PHY_REG_PG +}BaseBand_Config_Type, *PBaseBand_Config_Type; + +typedef enum _WIRELESS_MODE { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20, + WIRELESS_MODE_AC_5G = 0x40, + WIRELESS_MODE_AC_24G = 0x80, + WIRELESS_MODE_AC_ONLY = 0x100, +} WIRELESS_MODE; + +typedef struct RF_Shadow_Compare_Map { + // Shadow register value + u32 Value; + // Compare or not flag + u8 Compare; + // Record If it had ever modified unpredicted + u8 ErrorOrNot; + // Recorver Flag + u8 Recorver; + // + u8 Driver_Write; +}RF_SHADOW_T; + +#endif //__HAL_PHY_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/include/hal_phy_reg.h b/USDK/component/common/drivers/wlan/realtek/include/hal_phy_reg.h new file mode 100644 index 0000000..723eddb --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/hal_phy_reg.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HAL_PHY_REG_H__ +#define __HAL_PHY_REG_H__ + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#if (RTL92SE_FPGA_VERIFY == 1) +//#define bRFRegOffsetMask 0xfff +//#else +#define bRFRegOffsetMask 0xfffff +//#endif + +#endif //__HAL_PHY_REG_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/ieee80211.h b/USDK/component/common/drivers/wlan/realtek/include/ieee80211.h new file mode 100644 index 0000000..69b98d7 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/ieee80211.h @@ -0,0 +1,1527 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __IEEE80211_H +#define __IEEE80211_H + +#ifndef CONFIG_RTL8711FW + +// #include + + #if defined PLATFORM_OS_XP + #include + #endif + #if defined PLATFORM_LINUX + #include + #endif +#else + + #include + +#endif + +#define MGMT_QUEUE_NUM 5 + +#define ETH_ALEN 6 +#define ETH_TYPE_LEN 2 +#define PAYLOAD_TYPE_LEN 1 + +#ifdef CONFIG_AP_MODE + +#define RTL_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 28) + +/* RTL871X_IOCTL_HOSTAPD ioctl() cmd: */ +enum { + RTL871X_HOSTAPD_FLUSH = 1, + RTL871X_HOSTAPD_ADD_STA = 2, + RTL871X_HOSTAPD_REMOVE_STA = 3, + RTL871X_HOSTAPD_GET_INFO_STA = 4, + /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ + RTL871X_HOSTAPD_GET_WPAIE_STA = 5, + RTL871X_SET_ENCRYPTION = 6, + RTL871X_GET_ENCRYPTION = 7, + RTL871X_HOSTAPD_SET_FLAGS_STA = 8, + RTL871X_HOSTAPD_GET_RID = 9, + RTL871X_HOSTAPD_SET_RID = 10, + RTL871X_HOSTAPD_SET_ASSOC_AP_ADDR = 11, + RTL871X_HOSTAPD_SET_GENERIC_ELEMENT = 12, + RTL871X_HOSTAPD_MLME = 13, + RTL871X_HOSTAPD_SCAN_REQ = 14, + RTL871X_HOSTAPD_STA_CLEAR_STATS = 15, + RTL871X_HOSTAPD_SET_BEACON=16, + RTL871X_HOSTAPD_SET_WPS_BEACON = 17, + RTL871X_HOSTAPD_SET_WPS_PROBE_RESP = 18, + RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP = 19, + RTL871X_HOSTAPD_SET_HIDDEN_SSID = 20, + RTL871X_HOSTAPD_SET_MACADDR_ACL = 21, + RTL871X_HOSTAPD_ACL_ADD_STA = 22, + RTL871X_HOSTAPD_ACL_REMOVE_STA = 23, +}; + +/* STA flags */ +#define WLAN_STA_AUTH BIT(0) +#define WLAN_STA_ASSOC BIT(1) +#define WLAN_STA_PS BIT(2) +#define WLAN_STA_TIM BIT(3) +#define WLAN_STA_PERM BIT(4) +#define WLAN_STA_AUTHORIZED BIT(5) +#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */ +#define WLAN_STA_SHORT_PREAMBLE BIT(7) +#define WLAN_STA_PREAUTH BIT(8) +#define WLAN_STA_WME BIT(9) +#define WLAN_STA_MFP BIT(10) +#define WLAN_STA_HT BIT(11) +#define WLAN_STA_WPS BIT(12) +#define WLAN_STA_MAYBE_WPS BIT(13) +#define WLAN_STA_NONERP BIT(31) + +#endif + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +#define IEEE_PARAM_WPAX_SELECT 7 + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 +#define AUTH_ALG_LEAP 0x00000004 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 + + +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define WPA_CIPHER_NONE BIT(0) +#define WPA_CIPHER_WEP40 BIT(1) +#define WPA_CIPHER_WEP104 BIT(2) +#define WPA_CIPHER_TKIP BIT(3) +#define WPA_CIPHER_CCMP BIT(4) + + + +#define WPA_SELECTOR_LEN 4 +//extern u16 RTW_WPA_VERSION ; +//extern u8 WPA_AUTH_KEY_MGMT_NONE[]; +//extern u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +//extern u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +//extern u8 WPA_CIPHER_SUITE_WRAP[]; + +#define RSN_HEADER_LEN 4 +#define RSN_SELECTOR_LEN 4 + +//tern u8 RSN_CIPHER_SUITE_WRAP[]; + +typedef enum _RATEID_IDX_ { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, +} RATEID_IDX, *PRATEID_IDX; + +enum NETWORK_TYPE +{ + WIRELESS_INVALID = 0, + //Sub-Element + WIRELESS_11B = BIT(0), // tx: cck only , rx: cck only, hw: cck + WIRELESS_11G = BIT(1), // tx: ofdm only, rx: ofdm & cck, hw: cck & ofdm + WIRELESS_11A = BIT(2), // tx: ofdm only, rx: ofdm only, hw: ofdm only + WIRELESS_11_24N = BIT(3), // tx: MCS only, rx: MCS & cck, hw: MCS & cck + WIRELESS_11_5N = BIT(4), // tx: MCS only, rx: MCS & ofdm, hw: ofdm only + //WIRELESS_AUTO = BIT(5), + WIRELESS_11AC = BIT(6), + + //Combination + WIRELESS_11BG = (WIRELESS_11B|WIRELESS_11G), // tx: cck & ofdm, rx: cck & ofdm & MCS, hw: cck & ofdm + WIRELESS_11G_24N = (WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & MCS, rx: ofdm & cck & MCS, hw: cck & ofdm + WIRELESS_11A_5N = (WIRELESS_11A|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11BG_24N = (WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N), // tx: ofdm & cck & MCS, rx: ofdm & cck & MCS, hw: ofdm & cck + WIRELESS_11AGN = (WIRELESS_11A|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), // tx: ofdm & MCS, rx: ofdm & MCS, hw: ofdm only + WIRELESS_11ABGN = (WIRELESS_11A|WIRELESS_11B|WIRELESS_11G|WIRELESS_11_24N|WIRELESS_11_5N), +}; + + +#define SUPPORTED_24G_NETTYPE_MSK (WIRELESS_11B | WIRELESS_11G | WIRELESS_11_24N) +#define SUPPORTED_5G_NETTYPE_MSK (WIRELESS_11A | WIRELESS_11_5N) + +#define IsSupported24G(NetType) ((NetType) & SUPPORTED_24G_NETTYPE_MSK ? _TRUE : _FALSE) +#define IsSupported5G(NetType) ((NetType) & SUPPORTED_5G_NETTYPE_MSK ? _TRUE : _FALSE) + +//TODO +#if 0 +#define IsEnableHWCCK(NetType) IsSupported24G(NetType) +#define IsEnableHWOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11_24N|SUPPORTED_5G_NETTYPE_MSK) ? _TRUE : _FALSE) + +#define IsSupportedRxCCK(NetType) IsEnableHWCCK(NetType) +#define IsSupportedRxOFDM(NetType) IsEnableHWOFDM(NetType) +#define IsSupportedRxMCS(NetType) IsEnableHWOFDM(NetType) + +#define IsSupportedTxCCK(NetType) ((NetType) & (WIRELESS_11B) ? _TRUE : _FALSE) +#define IsSupportedTxOFDM(NetType) ((NetType) & (WIRELESS_11G|WIRELESS_11A) ? _TRUE : _FALSE) +#define IsSupportedTxMCS(NetType) ((NetType) & (WIRELESS_11_24N|WIRELESS_11_5N) ? _TRUE : _FALSE) + +#endif //#if 0 + +typedef struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; +#ifdef __CC_ARM + u8 data[1]; +#else + u8 data[0]; +#endif + } wpa_ie; + struct{ + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; +#ifdef __CC_ARM + u8 key[1]; +#else + u8 key[0]; +#endif + } crypt; +#ifdef CONFIG_AP_MODE + struct { + u16 aid; + u16 capability; + int flags; + u8 tx_supp_rates[16]; + struct rtw_ieee80211_ht_cap ht_cap; + } add_sta; + struct { + u8 reserved[2];//for set max_num_sta +#ifdef __CC_ARM + u8 buf[1]; +#else + u8 buf[0]; +#endif + } bcn_ie; +#endif + + } u; +}ieee_param; + +//TODO +#if 0 + +#ifdef CONFIG_AP_MODE +typedef struct ieee_param_ex { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + u8 data[0]; +}ieee_param_ex; + +struct sta_data{ + u16 aid; + u16 capability; + int flags; + u32 sta_set; + u8 tx_supp_rates[16]; + u32 tx_supp_rates_len; + struct rtw_ieee80211_ht_cap ht_cap; + u64 rx_pkts; + u64 rx_bytes; + u64 rx_drops; + u64 tx_pkts; + u64 tx_bytes; + u64 tx_drops; +}; +#endif + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#define IEEE80211_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + + +#define IEEE80211_HLEN 30 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 + +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + _list list; +}; + +#endif //#if 0 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW)||defined(PLATFORM_FREEBSD) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct rtw_ieee80211_hdr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; + u16 qc; +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct rtw_ieee80211_hdr_3addr_qos { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u16 qc; +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#endif //defined PLATFORM_LINUX/CONFIG_RTL8711FW/PLATFORM_FREEBSD/PLATFORM_ECOSPLATFORM_FREERTOS + +//TODO +#if 0 + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +struct rtw_ieee80211_hdr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; + u8 addr4[ETH_ALEN]; +}; + +struct rtw_ieee80211_hdr_3addr { + u16 frame_ctl; + u16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + u16 seq_ctl; +}; + + +struct rtw_ieee80211_hdr_qos { + struct rtw_ieee80211_hdr wlan_hdr; + u16 qc; +}; + +struct rtw_ieee80211_hdr_3addr_qos { + struct rtw_ieee80211_hdr_3addr wlan_hdr; + u16 qc; +}; + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +}; +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + + + +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +#endif //#if 0 + +#define IEEE80211_3ADDR_LEN 24 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_FCS_LEN 4 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U + +/* Frame control field constants */ +#define RTW_IEEE80211_FCTL_VERS 0x0002 +#define RTW_IEEE80211_FCTL_FTYPE 0x000c +#define RTW_IEEE80211_FCTL_STYPE 0x00f0 +#define RTW_IEEE80211_FCTL_TODS 0x0100 +#define RTW_IEEE80211_FCTL_FROMDS 0x0200 +#define RTW_IEEE80211_FCTL_MOREFRAGS 0x0400 +#define RTW_IEEE80211_FCTL_RETRY 0x0800 +#define RTW_IEEE80211_FCTL_PM 0x1000 +#define RTW_IEEE80211_FCTL_MOREDATA 0x2000 +#define RTW_IEEE80211_FCTL_WEP 0x4000 +#define RTW_IEEE80211_FCTL_ORDER 0x8000 + +#define RTW_IEEE80211_FTYPE_MGMT 0x0000 +#define RTW_IEEE80211_FTYPE_CTL 0x0004 +#define RTW_IEEE80211_FTYPE_DATA 0x0008 + +/* management */ +#define RTW_IEEE80211_STYPE_ASSOC_REQ 0x0000 +#define RTW_IEEE80211_STYPE_ASSOC_RESP 0x0010 +#define RTW_IEEE80211_STYPE_REASSOC_REQ 0x0020 +#define RTW_IEEE80211_STYPE_REASSOC_RESP 0x0030 +#define RTW_IEEE80211_STYPE_PROBE_REQ 0x0040 +#define RTW_IEEE80211_STYPE_PROBE_RESP 0x0050 +#define RTW_IEEE80211_STYPE_BEACON 0x0080 +#define RTW_IEEE80211_STYPE_ATIM 0x0090 +#define RTW_IEEE80211_STYPE_DISASSOC 0x00A0 +#define RTW_IEEE80211_STYPE_AUTH 0x00B0 +#define RTW_IEEE80211_STYPE_DEAUTH 0x00C0 + +/* control */ +#define RTW_IEEE80211_STYPE_PSPOLL 0x00A0 +#define RTW_IEEE80211_STYPE_RTS 0x00B0 +#define RTW_IEEE80211_STYPE_CTS 0x00C0 +#define RTW_IEEE80211_STYPE_ACK 0x00D0 +#define RTW_IEEE80211_STYPE_CFEND 0x00E0 +#define RTW_IEEE80211_STYPE_CFENDACK 0x00F0 + +/* data */ +#define RTW_IEEE80211_STYPE_DATA 0x0000 +#define RTW_IEEE80211_STYPE_DATA_CFACK 0x0010 +#define RTW_IEEE80211_STYPE_DATA_CFPOLL 0x0020 +#define RTW_IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 +#define RTW_IEEE80211_STYPE_NULLFUNC 0x0040 +#define RTW_IEEE80211_STYPE_CFACK 0x0050 +#define RTW_IEEE80211_STYPE_CFPOLL 0x0060 +#define RTW_IEEE80211_STYPE_CFACKPOLL 0x0070 +#define RTW_IEEE80211_QOS_DATAGRP 0x0080 +#define RTW_IEEE80211_QoS_DATAGRP RTW_IEEE80211_QOS_DATAGRP + +#define RTW_IEEE80211_SCTL_FRAG 0x000F +#define RTW_IEEE80211_SCTL_SEQ 0xFFF0 + + +#define RTW_ERP_INFO_NON_ERP_PRESENT BIT(0) +#define RTW_ERP_INFO_USE_PROTECTION BIT(1) +#define RTW_ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + +/* QoS,QOS */ +#define NORMAL_ACK 0 +#define NO_ACK 1 +#define NON_EXPLICIT_ACK 2 +#define BLOCK_ACK 3 + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#define ETH_P_ECONET 0x0018 + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) || defined(PLATFORM_FREEBSD) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) +RTW_PACK_STRUCT_BEGIN +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +}; +#pragma pack() + +#endif + + +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) + +#define WLAN_FC_GET_TYPE(fc) ((fc) & RTW_IEEE80211_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & RTW_IEEE80211_FCTL_STYPE) + +#define WLAN_QC_GET_TID(qc) ((qc) & 0x0f) + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTW_IEEE80211_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & RTW_IEEE80211_SCTL_SEQ) + + + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_BSS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) + +/* Status codes */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +/* 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/* Reason codes */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#define WLAN_REASON_JOIN_WRONG_CHANNEL 65534 + +/* Information Element IDs */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARAMS 2 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_CHALLENGE 16 +/* EIDs defined by IEEE 802.11h - START */ +#define WLAN_EID_PWR_CONSTRAINT 32 +#define WLAN_EID_PWR_CAPABILITY 33 +#define WLAN_EID_TPC_REQUEST 34 +#define WLAN_EID_TPC_REPORT 35 +#define WLAN_EID_SUPPORTED_CHANNELS 36 +#define WLAN_EID_CHANNEL_SWITCH 37 +#define WLAN_EID_MEASURE_REQUEST 38 +#define WLAN_EID_MEASURE_REPORT 39 +#define WLAN_EID_QUITE 40 +#define WLAN_EID_IBSS_DFS 41 +/* EIDs defined by IEEE 802.11h - END */ +#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_SUPP_RATES 50 +#define WLAN_EID_MOBILITY_DOMAIN 54 +#define WLAN_EID_FAST_BSS_TRANSITION 55 +#define WLAN_EID_TIMEOUT_INTERVAL 56 +#define WLAN_EID_RIC_DATA 57 +#define WLAN_EID_HT_OPERATION 61 +#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 +#define WLAN_EID_20_40_BSS_COEXISTENCE 72 +#define WLAN_EID_20_40_BSS_INTOLERANT 73 +#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 +#define WLAN_EID_MMIE 76 +#define WLAN_EID_VENDOR_SPECIFIC 221 +#define WLAN_EID_GENERIC (WLAN_EID_VENDOR_SPECIFIC) + +#define IEEE80211_MGMT_HDR_LEN 24 +#define IEEE80211_DATA_HDR3_LEN 24 +#define IEEE80211_DATA_HDR4_LEN 30 + + +#define IEEE80211_STATMASK_SIGNAL (1<<0) +#define IEEE80211_STATMASK_RSSI (1<<1) +#define IEEE80211_STATMASK_NOISE (1<<2) +#define IEEE80211_STATMASK_RATE (1<<3) +#define IEEE80211_STATMASK_WEMASK 0x7 + + +#define IEEE80211_CCK_MODULATION (1<<0) +#define IEEE80211_OFDM_MODULATION (1<<1) + +#define IEEE80211_24GHZ_BAND (1<<0) +#define IEEE80211_52GHZ_BAND (1<<1) + +#define IEEE80211_CCK_RATE_LEN 4 +#define IEEE80211_NUM_OFDM_RATESLEN 8 + + +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_LEN 8 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + +#define IEEE80211_NUM_OFDM_RATES 8 +#define IEEE80211_NUM_CCK_RATES 4 +#define IEEE80211_OFDM_SHIFT_MASK_A 4 + + +/* BIT 7 HT Rate*/ +enum MGN_RATE{ + MGN_1M = 0x02, + MGN_2M = 0x04, + MGN_5_5M = 0x0B, + MGN_6M = 0x0C, + MGN_9M = 0x12, + MGN_11M = 0x16, + MGN_12M = 0x18, + MGN_18M = 0x24, + MGN_24M = 0x30, + MGN_36M = 0x48, + MGN_48M = 0x60, + MGN_54M = 0x6C, + MGN_MCS32 = 0x7F, + MGN_MCS0, + MGN_MCS1, + MGN_MCS2, + MGN_MCS3, + MGN_MCS4, + MGN_MCS5, + MGN_MCS6, + MGN_MCS7, + MGN_MCS8, + MGN_MCS9, + MGN_MCS10, + MGN_MCS11, + MGN_MCS12, + MGN_MCS13, + MGN_MCS14, + MGN_MCS15, + MGN_MCS16, + MGN_MCS17, + MGN_MCS18, + MGN_MCS19, + MGN_MCS20, + MGN_MCS21, + MGN_MCS22, + MGN_MCS23, + MGN_MCS24, + MGN_MCS25, + MGN_MCS26, + MGN_MCS27, + MGN_MCS28, + MGN_MCS29, + MGN_MCS30, + MGN_MCS31, + MGN_VHT1SS_MCS0, + MGN_VHT1SS_MCS1, + MGN_VHT1SS_MCS2, + MGN_VHT1SS_MCS3, + MGN_VHT1SS_MCS4, + MGN_VHT1SS_MCS5, + MGN_VHT1SS_MCS6, + MGN_VHT1SS_MCS7, + MGN_VHT1SS_MCS8, + MGN_VHT1SS_MCS9, + MGN_VHT2SS_MCS0, + MGN_VHT2SS_MCS1, + MGN_VHT2SS_MCS2, + MGN_VHT2SS_MCS3, + MGN_VHT2SS_MCS4, + MGN_VHT2SS_MCS5, + MGN_VHT2SS_MCS6, + MGN_VHT2SS_MCS7, + MGN_VHT2SS_MCS8, + MGN_VHT2SS_MCS9, + MGN_VHT3SS_MCS0, + MGN_VHT3SS_MCS1, + MGN_VHT3SS_MCS2, + MGN_VHT3SS_MCS3, + MGN_VHT3SS_MCS4, + MGN_VHT3SS_MCS5, + MGN_VHT3SS_MCS6, + MGN_VHT3SS_MCS7, + MGN_VHT3SS_MCS8, + MGN_VHT3SS_MCS9, + MGN_VHT4SS_MCS0, + MGN_VHT4SS_MCS1, + MGN_VHT4SS_MCS2, + MGN_VHT4SS_MCS3, + MGN_VHT4SS_MCS4, + MGN_VHT4SS_MCS5, + MGN_VHT4SS_MCS6, + MGN_VHT4SS_MCS7, + MGN_VHT4SS_MCS8, + MGN_VHT4SS_MCS9, + MGN_UNKNOWN +}; + + +#define MGN_MCS0_SG 0xc0 +#define MGN_MCS1_SG 0xc1 +#define MGN_MCS2_SG 0xc2 +#define MGN_MCS3_SG 0xc3 +#define MGN_MCS4_SG 0xc4 +#define MGN_MCS5_SG 0xc5 +#define MGN_MCS6_SG 0xc6 +#define MGN_MCS7_SG 0xc7 +#define MGN_MCS8_SG 0xc8 +#define MGN_MCS9_SG 0xc9 +#define MGN_MCS10_SG 0xca +#define MGN_MCS11_SG 0xcb +#define MGN_MCS12_SG 0xcc +#define MGN_MCS13_SG 0xcd +#define MGN_MCS14_SG 0xce +#define MGN_MCS15_SG 0xcf + +#define IS_HT_RATE(_rate) (((_rate) & 0x80) ? _TRUE : _FALSE) +#define IS_CCK_RATE(_rate) (MGN_1M == _rate || _rate == MGN_2M || _rate == MGN_5_5M || _rate == MGN_11M ) +#define IS_OFDM_RATE(_rate) (MGN_6M <= _rate && _rate <= MGN_54M ) + + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct ieee80211_rx_stats { + //u32 mac_time[2]; + s8 rssi; + u8 signal; + u8 noise; + u8 received_channel; + u16 rate; /* in 100 kbps */ + //u8 control; + u8 mask; + u8 freq; + u16 len; +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define IEEE80211_FRAG_CACHE_LEN 4 + +struct ieee80211_frag_entry { + u32 first_frag_time; + uint seq; + uint last_frag; + uint qos; //jackson + uint tid; //jackson + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined +struct ieee80211_stats { + uint tx_unicast_frames; + uint tx_multicast_frames; + uint tx_fragments; + uint tx_unicast_octets; + uint tx_multicast_octets; + uint tx_deferred_transmissions; + uint tx_single_retry_frames; + uint tx_multiple_retry_frames; + uint tx_retry_limit_exceeded; + uint tx_discards; + uint rx_unicast_frames; + uint rx_multicast_frames; + uint rx_fragments; + uint rx_unicast_octets; + uint rx_multicast_octets; + uint rx_fcs_errors; + uint rx_discards_no_buffer; + uint tx_discards_wrong_sa; + uint rx_discards_undecryptable; + uint rx_message_in_msg_fragments; + uint rx_message_in_bad_msg_fragments; +}; +#endif //PLATFORM_FREEBSD +struct ieee80211_softmac_stats{ + uint rx_ass_ok; + uint rx_ass_err; + uint rx_probe_rq; + uint tx_probe_rs; + uint tx_beacons; + uint rx_auth_rq; + uint rx_auth_rs_ok; + uint rx_auth_rs_err; + uint tx_auth_rq; + uint no_auth_rs; + uint no_ass_rs; + uint tx_ass_rq; + uint rx_ass_rq; + uint tx_probe_rq; + uint reassoc; + uint swtxstop; + uint swtxawake; +}; + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 + + + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} __attribute__ ((packed)); + +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][WEP_KEY_LEN]; + u8 level; + u16 flags; +} ; +#pragma pack() + +#endif + +/* + + 802.11 data frame from AP + + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' + +Total: 28-2340 bytes + +*/ + +struct ieee80211_header_data { + u16 frame_ctl; + u16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + u16 seq_ctrl; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +/* Management Frame Information Element Types */ +#define MFIE_TYPE_SSID 0 +#define MFIE_TYPE_RATES 1 +#define MFIE_TYPE_FH_SET 2 +#define MFIE_TYPE_DS_SET 3 +#define MFIE_TYPE_CF_SET 4 +#define MFIE_TYPE_TIM 5 +#define MFIE_TYPE_IBSS_SET 6 +#define MFIE_TYPE_CHALLENGE 16 +#define MFIE_TYPE_ERP 42 +#define MFIE_TYPE_RSN 48 +#define MFIE_TYPE_RATES_EX 50 +#define MFIE_TYPE_GENERIC 221 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} __attribute__ ((packed)); + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} __attribute__ ((packed)); +#endif + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) +struct ieee80211_info_element_hdr { + u8 id; + u8 len; +} ; + +struct ieee80211_info_element { + u8 id; + u8 len; + u8 data[0]; +} ; +#pragma pack() + +#endif + + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __attribute__ ((packed)); + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define IEEE80211_DEFAULT_TX_ESSID "Penguin" +#define IEEE80211_DEFAULT_BASIC_RATE 10 + + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8711FW) + + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} __attribute__ ((packed)); + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} __attribute__ ((packed)); + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} __attribute__ ((packed)); + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +} __attribute__ ((packed)); +#endif + + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct ieee80211_authentication { + struct ieee80211_header_data header; + u16 algorithm; + u16 transaction; + u16 status; + //struct ieee80211_info_element_hdr info_element; +} ; + + +struct ieee80211_probe_response { + struct ieee80211_header_data header; + u32 time_stamp[2]; + u16 beacon_interval; + u16 capability; + struct ieee80211_info_element info_element; +} ; + +struct ieee80211_probe_request { + struct ieee80211_header_data header; + /*struct ieee80211_info_element info_element;*/ +} ; + +struct ieee80211_assoc_request_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 listen_interval; + //u8 current_ap[ETH_ALEN]; + struct ieee80211_info_element_hdr info_element; +} ; + +struct ieee80211_assoc_response_frame { + struct rtw_ieee80211_hdr_3addr header; + u16 capability; + u16 status; + u16 aid; +// struct ieee80211_info_element info_element; /* supported rates */ +}; + +#pragma pack() + +#endif + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 128 +#define MAX_CHANNEL_NUMBER 161 +#define IEEE80211_SOFTMAC_SCAN_TIME 400 +//(HZ / 2) +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN (256) +#define MAX_WPS_IE_LEN (512) +#define MAX_P2P_IE_LEN (256) +#define MAX_WFD_IE_LEN (128) + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +#define IEEE80211_DTIM_MBCAST 4 +#define IEEE80211_DTIM_UCAST 2 +#define IEEE80211_DTIM_VALID 1 +#define IEEE80211_DTIM_INVALID 0 + +#define IEEE80211_PS_DISABLED 0 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST +#define IW_ESSID_MAX_SIZE 32 +#define IW_PASSPHRASE_MAX_SIZE 64 +#if 0 +struct ieee80211_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + u8 rssi; //relative signal strength + u8 sq; //signal quality + + /* These are network statistics */ + //struct ieee80211_rx_stats stats; + u16 capability; + u16 aid; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + + u8 edca_parmsets[18]; + + u8 mode; + u8 flags; + u8 time_stamp[8]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + u8 country[6]; + u8 dtim_period; + u8 dtim_data; + u8 power_constraint; + u8 qosinfo; + u8 qbssload[5]; + u8 network_type; + int join_res; + unsigned long last_scanned; +}; +#endif +/* +join_res: +-1: authentication fail +-2: association fail +> 0: TID +*/ + +#ifndef PLATFORM_FREEBSD //Baron BSD has already defined + +enum ieee80211_state { + + /* the card is not linked at all */ + IEEE80211_NOLINK = 0, + + /* IEEE80211_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + IEEE80211_ASSOCIATING, + IEEE80211_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + IEEE80211_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + IEEE80211_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + IEEE80211_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + IEEE80211_LINKED_SCANNING, + +}; +#endif //PLATFORM_FREEBSD + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] + +#ifdef PLATFORM_FREEBSD //Baron change func to macro +#define is_multicast_mac_addr(Addr) ((((Addr[0]) & 0x01) == 0x01) && ((Addr[0]) != 0xff)) +#define is_broadcast_mac_addr(Addr) ((((Addr[0]) & 0xff) == 0xff) && (((Addr[1]) & 0xff) == 0xff) && \ +(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \ +(((Addr[5]) & 0xff) == 0xff)) +#else +#if 0 +extern __inline int is_multicast_mac_addr(const u8 *addr) +{ + return ((addr[0] != 0xff) && (0x01 & addr[0])); +} + +extern __inline int is_broadcast_mac_addr(const u8 *addr) +{ + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); +} +#endif +#endif //PLATFORM_FREEBSD + +#define CFG_IEEE80211_RESERVE_FCS (1<<0) +#define CFG_IEEE80211_COMPUTE_FCS (1<<1) + +#define MAXTID 16 + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +//Baron move to ieee80211.c +int ieee80211_is_empty_essid(const char *essid, int essid_len); +int ieee80211_get_hdrlen(u16 fc); + +#if 0 +/* Action frame categories (IEEE 802.11-2007, 7.3.1.11, Table 7-24) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_WMM 17 +#endif + + +/* Action category code */ +enum rtw_ieee80211_category { + RTW_WLAN_CATEGORY_SPECTRUM_MGMT = 0, + RTW_WLAN_CATEGORY_QOS = 1, + RTW_WLAN_CATEGORY_DLS = 2, + RTW_WLAN_CATEGORY_BACK = 3, + RTW_WLAN_CATEGORY_PUBLIC = 4, //IEEE 802.11 public action frames + RTW_WLAN_CATEGORY_RADIO_MEASUREMENT = 5, + RTW_WLAN_CATEGORY_FT = 6, + RTW_WLAN_CATEGORY_HT = 7, + RTW_WLAN_CATEGORY_SA_QUERY = 8, + RTW_WLAN_CATEGORY_TDLS = 12, + RTW_WLAN_CATEGORY_WMM = 17, + RTW_WLAN_CATEGORY_P2P = 0x7f,//P2P action frames +}; + +/* SPECTRUM_MGMT action code */ +enum rtw_ieee80211_spectrum_mgmt_actioncode { + RTW_WLAN_ACTION_SPCT_MSR_REQ = 0, + RTW_WLAN_ACTION_SPCT_MSR_RPRT = 1, + RTW_WLAN_ACTION_SPCT_TPC_REQ = 2, + RTW_WLAN_ACTION_SPCT_TPC_RPRT = 3, + RTW_WLAN_ACTION_SPCT_CHL_SWITCH = 4, + RTW_WLAN_ACTION_SPCT_EXT_CHL_SWITCH = 5, +}; + +enum _PUBLIC_ACTION{ + ACT_PUBLIC_BSSCOEXIST = 0, // 20/40 BSS Coexistence + ACT_PUBLIC_DSE_ENABLE = 1, + ACT_PUBLIC_DSE_DEENABLE = 2, + ACT_PUBLIC_DSE_REG_LOCATION = 3, + ACT_PUBLIC_EXT_CHL_SWITCH = 4, + ACT_PUBLIC_DSE_MSR_REQ = 5, + ACT_PUBLIC_DSE_MSR_RPRT = 6, + ACT_PUBLIC_MP = 7, // Measurement Pilot + ACT_PUBLIC_DSE_PWR_CONSTRAINT = 8, + ACT_PUBLIC_VENDOR = 9, // for WIFI_DIRECT + ACT_PUBLIC_GAS_INITIAL_REQ = 10, + ACT_PUBLIC_GAS_INITIAL_RSP = 11, + ACT_PUBLIC_GAS_COMEBACK_REQ = 12, + ACT_PUBLIC_GAS_COMEBACK_RSP = 13, + ACT_PUBLIC_TDLS_DISCOVERY_RSP = 14, + ACT_PUBLIC_LOCATION_TRACK = 15, + ACT_PUBLIC_MAX +}; + +#ifdef CONFIG_TDLS +enum TDLS_ACTION_FIELD{ + TDLS_SETUP_REQUEST = 0, + TDLS_SETUP_RESPONSE = 1, + TDLS_SETUP_CONFIRM = 2, + TDLS_TEARDOWN = 3, + TDLS_PEER_TRAFFIC_INDICATION = 4, + TDLS_CHANNEL_SWITCH_REQUEST = 5, + TDLS_CHANNEL_SWITCH_RESPONSE = 6, + TDLS_PEER_PSM_REQUEST = 7, + TDLS_PEER_PSM_RESPONSE = 8, + TDLS_PEER_TRAFFIC_RESPONSE = 9, + TDLS_DISCOVERY_REQUEST = 10, + TDLS_DISCOVERY_RESPONSE = 14, //it's used in public action frame +}; + +#define TUNNELED_PROBE_REQ 15 +#define TUNNELED_PROBE_RSP 16 +#endif //CONFIG_TDLS + +/* BACK action code */ +enum rtw_ieee80211_back_actioncode { + RTW_WLAN_ACTION_ADDBA_REQ = 0, + RTW_WLAN_ACTION_ADDBA_RESP = 1, + RTW_WLAN_ACTION_DELBA = 2, +}; + +/* HT features action code */ +enum rtw_ieee80211_ht_actioncode { + RTW_WLAN_ACTION_NOTIFY_CH_WIDTH = 0, + RTW_WLAN_ACTION_SM_PS = 1, + RTW_WLAN_ACTION_PSPM = 2, + RTW_WLAN_ACTION_PCO_PHASE = 3, + RTW_WLAN_ACTION_MIMO_CSI_MX = 4, + RTW_WLAN_ACTION_MIMO_NONCP_BF = 5, + RTW_WLAN_ACTION_MIMP_CP_BF = 6, + RTW_WLAN_ACTION_ASEL_INDICATES_FB = 7, + RTW_WLAN_ACTION_HI_INFO_EXCHG = 8, +}; + +/* BACK (block-ack) parties */ +enum rtw_ieee80211_back_parties { + RTW_WLAN_BACK_RECIPIENT = 0, + RTW_WLAN_BACK_INITIATOR = 1, + RTW_WLAN_BACK_TIMER = 2, +}; + + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ +#ifndef PLATFORM_FREEBSD //Baron BSD has defined +#define WME_OUI_TYPE 2 +#endif //PLATFORM_FREEBSD +#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WME_VERSION 1 + +#define WME_ACTION_CODE_SETUP_REQUEST 0 +#define WME_ACTION_CODE_SETUP_RESPONSE 1 +#define WME_ACTION_CODE_TEARDOWN 2 + +#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 +#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 +#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 + +#define WME_TSPEC_DIRECTION_UPLINK 0 +#define WME_TSPEC_DIRECTION_DOWNLINK 1 +#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + + +#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ + +#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ + +u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen); +int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len); + +int rtw_get_wapi_ie(u8 *in_ie,uint in_len,u8 *wapi_ie,u16 *wapi_len); + +u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen); + +void dump_ies(u8 *buf, u32 buf_len); +void dump_wps_ie(u8 *ie, u32 ie_len); + +#ifdef CONFIG_P2P_NEW +u8 *rtw_get_p2p_ie(u8 *in_ie, uint in_len, u8 *p2p_ie, uint *p2p_ielen); +u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr); +#endif //CONFIG_P2P +#ifdef CONFIG_P2P +void dump_p2p_ie(u8 *ie, u32 ie_len); +u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content); +u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr); +void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id); +#endif + +#ifdef CONFIG_WFD +int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen); +int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen); +#endif // CONFIG_WFD + +//struct registry_priv; +//int rtw_generate_ie(struct registry_priv *pregistrypriv); + +void rtw_get_bcn_info(struct wlan_network *pnetwork); + +void rtw_macaddr_cfg(u8 *mac_addr); + +u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char * MCS_rate); +#endif /* __IEEE80211_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/if_ether.h b/USDK/component/common/drivers/wlan/realtek/include/if_ether.h new file mode 100644 index 0000000..7e06597 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/if_ether.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef _LINUX_IF_ETHER_H +#define _LINUX_IF_ETHER_H + +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ + +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ +#define ETH_DATA_LEN 1500 /* Max. octets in payload */ +#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + +/* + * These are the defined Ethernet Protocol ID's. + */ + +#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ +#define ETH_P_PUP 0x0200 /* Xerox PUP packet */ +#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_X25 0x0805 /* CCITT X.25 */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */ +#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */ +#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ +#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ +#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ +#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ +#define ETH_P_LAT 0x6004 /* DEC LAT */ +#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ +#define ETH_P_CUST 0x6006 /* DEC Customer use */ +#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ +#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ +#define ETH_P_ATALK 0x809B /* Appletalk DDP */ +#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ +#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define ETH_P_IPX 0x8137 /* IPX over DIX */ +#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */ +#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */ +#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */ +#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport + * over Ethernet + */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + +#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ +#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ +#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ +#define ETH_P_802_2 0x0004 /* 802.2 frames */ +#define ETH_P_SNAP 0x0005 /* Internal only */ +#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ +#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ +#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ +#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ +#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */ +#define ETH_P_CONTROL 0x0016 /* Card specific control frames */ +#define ETH_P_IRDA 0x0017 /* Linux-IrDA */ +#define ETH_P_ECONET 0x0018 /* Acorn Econet */ + +/* + * This is an Ethernet frame header. + */ +//CONFIG_MEMORY_ACCESS_ALIGNED for 4byte aligned,ethdhr size is 16,leading error in wlanhdr_to_ethdr +RTW_PACK_STRUCT_BEGIN +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +} RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END + +struct _vlan { + unsigned short h_vlan_TCI; // Encapsulates priority and VLAN ID + unsigned short h_vlan_encapsulated_proto; +}; + + + +#define get_vlan_id(pvlan) ((_htons((unsigned short )pvlan->h_vlan_TCI)) & 0xfff) +#define get_vlan_priority(pvlan) ((_htons((unsigned short )pvlan->h_vlan_TCI))>>13) +#define get_vlan_encap_proto(pvlan) (_htons((unsigned short )pvlan->h_vlan_encapsulated_proto)) + + +#endif /* _LINUX_IF_ETHER_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/ip.h b/USDK/component/common/drivers/wlan/realtek/include/ip.h new file mode 100644 index 0000000..3911608 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/ip.h @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _LINUX_IP_H +#define _LINUX_IP_H +#include + +/* SOL_IP socket options */ +#ifndef IPTOS_TOS_MASK +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_MINCOST 0x02 + +#define IPTOS_PREC_MASK 0xE0 +#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 +#endif + +/* IP options */ +#define IPOPT_COPY 0x80 +#define IPOPT_CLASS_MASK 0x60 +#define IPOPT_NUMBER_MASK 0x1f + +#define IPOPT_COPIED(o) ((o)&IPOPT_COPY) +#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK) +#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_MEASUREMENT 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_END (0 |IPOPT_CONTROL) +#define IPOPT_NOOP (1 |IPOPT_CONTROL) +#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT) +#define IPOPT_RR (7 |IPOPT_CONTROL) +#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY) +#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY) + +#define IPVERSION 4 +#define MAXTTL 255 +#define IPDEFTTL 64 + +/* struct timestamp, struct route and MAX_ROUTES are removed. + + REASONS: it is clear that nobody used them because: + - MAX_ROUTES value was wrong. + - "struct route" was wrong. + - "struct timestamp" had fatally misaligned bitfields and was completely unusable. + */ + +#define IPOPT_OPTVAL 0 +#define IPOPT_OLEN 1 +#define IPOPT_OFFSET 2 +#define IPOPT_MINOFF 4 +#define MAX_IPOPTLEN 40 +#define IPOPT_NOP IPOPT_NOOP +#define IPOPT_EOL IPOPT_END +#define IPOPT_TS IPOPT_TIMESTAMP + +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +#ifdef PLATFORM_LINUX + +struct ip_options { + __u32 faddr; /* Saved first hop address */ + unsigned char optlen; + unsigned char srr; + unsigned char rr; + unsigned char ts; + unsigned char is_setbyuser:1, /* Set by setsockopt? */ + is_data:1, /* Options in __data, rather than skb */ + is_strictroute:1, /* Strict source route */ + srr_is_hit:1, /* Packet destination addr was our one */ + is_changed:1, /* IP checksum more not valid */ + rr_needaddr:1, /* Need to record addr of outgoing dev */ + ts_needtime:1, /* Need to record timestamp */ + ts_needaddr:1; /* Need to record addr of outgoing dev */ + unsigned char router_alert; + unsigned char __pad1; + unsigned char __pad2; + unsigned char __data[0]; +}; + +#define optlength(opt) (sizeof(struct ip_options) + opt->optlen) +#endif + +struct iphdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ihl:4, + version:4; +#elif defined (__BIG_ENDIAN_BITFIELD) + __u8 version:4, + ihl:4; +#else +#error "Please fix " +#endif + __u8 tos; + __u16 tot_len; + __u16 id; + __u16 frag_off; + __u8 ttl; + __u8 protocol; + __u16 check; + __u32 saddr; + __u32 daddr; + /*The options start here. */ +}; + +#endif /* _LINUX_IP_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/lxbus_hal.h b/USDK/component/common/drivers/wlan/realtek/include/lxbus_hal.h new file mode 100644 index 0000000..74a161d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/lxbus_hal.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __LXBUS_HAL_H__ +#define __LXBUS_HAL_H__ + +#endif //__LXBUS_HAL_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/lxbus_ops.h b/USDK/component/common/drivers/wlan/realtek/include/lxbus_ops.h new file mode 100644 index 0000000..aca3698 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/lxbus_ops.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __LXBUS_OPS_H__ +#define __LXBUS_OPS_H__ + + +#if defined(CONFIG_RTL8195A) +//extern u32 TxbdRxbdInitRtl8195a(PADAPTER Adapter); +//extern u32 TxbdRxbdResetRtl8195a(PADAPTER Adapter); + +extern VOID InitLxDmaRtl8195a(_adapter * Adapter); +extern u32 rtl8195a_init_desc_ring(_adapter * padapter); +extern u32 rtl8195a_free_desc_ring(_adapter * padapter); +extern void rtl8195a_reset_desc_ring(_adapter * padapter); +extern void EnableDMA8195a(PADAPTER padapter); +extern void EnableInterrupt8195a(PADAPTER padapter); +extern void DisableDMA8195a(PADAPTER padapter); +extern void DisableInterrupt8195a(PADAPTER padapter); +extern s32 InterruptHandle8195a(PADAPTER Adapter); +extern void lxbus_set_intf_ops(struct _io_ops *pops); +extern void rtl8195a_xmit_tasklet(void *priv); +extern void rtl8195a_recv_tasklet(void *priv); +extern void rtl8195a_prepare_bcn_tasklet(void *priv); +extern void rtl8195a_tx_int_handler(_adapter *padapter); +extern void InitInterrupt8195a(PADAPTER padapter); +extern VOID UpdateInterruptMask8195a(PADAPTER Adapter, u32 *pAddMSRB, u32 *pRemoveMSR); + +#ifdef CONFIG_WOWLAN +extern void ClearInterrupt8195a(PADAPTER padapter); +#endif + +extern void ClearWlPmcInterrupt8195a(PADAPTER padapter); +extern BOOLEAN InterruptRecognized8195a(PADAPTER Adapter); +#elif defined(CONFIG_RTL8711B) + +extern u32 rtl8711b_init_desc_ring(_adapter * padapter); +extern u32 rtl8711b_free_desc_ring(_adapter * padapter); +extern void rtl8711b_reset_desc_ring(_adapter * padapter); +extern void EnableDMA8711b(PADAPTER padapter); +extern void EnableInterrupt8711b(PADAPTER padapter); +extern void DisableDMA8711b(PADAPTER padapter); +extern void DisableInterrupt8711b(PADAPTER padapter); +extern s32 InterruptHandle8711b(PADAPTER Adapter); +extern void lxbus_set_intf_ops(struct _io_ops *pops); +extern void rtl8711b_xmit_tasklet(void *priv); +extern void rtl8711b_recv_tasklet(void *priv); +extern void rtl8711b_prepare_bcn_tasklet(void *priv); +extern void rtl8711b_tx_int_handler(_adapter *padapter); +extern void InitInterrupt8711b(PADAPTER padapter); +extern VOID UpdateInterruptMask8711b(PADAPTER Adapter, u32 *pAddMSRB, u32 *pRemoveMSR); + +#ifdef CONFIG_WOWLAN +extern void ClearInterrupt8711b(PADAPTER padapter); +extern void DisableInterruptButCpwm28711b(PADAPTER padapter); +#endif + +extern void ClearWlPmcInterrupt8711b(PADAPTER padapter); +extern BOOLEAN InterruptRecognized8711b(PADAPTER Adapter); +#endif + + +#endif // !__LXBUS_OPS_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/lxbus_osintf.h b/USDK/component/common/drivers/wlan/realtek/include/lxbus_osintf.h new file mode 100644 index 0000000..0c80793 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/lxbus_osintf.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __LXBUS_OSINTF_H +#define __LXBUS_OSINTF_H + + +//void rtw_pci_disable_aspm(_adapter *padapter); +//void rtw_pci_enable_aspm(_adapter *padapter); +//void PlatformClearPciPMEStatus(PADAPTER Adapter); + +#endif //__LXBUS_OSINTF_H + diff --git a/USDK/component/common/drivers/wlan/realtek/include/pack_begin.h b/USDK/component/common/drivers/wlan/realtek/include/pack_begin.h new file mode 100644 index 0000000..7f1de7c --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/pack_begin.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * Define the start point of packed structure + * + ******************************************************************************/ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + +#if defined(PLATFORM_WINDOWS) +#pragma pack(push) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/pack_end.h b/USDK/component/common/drivers/wlan/realtek/include/pack_end.h new file mode 100644 index 0000000..e34640c --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/pack_end.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * Define the end point of packed structure + * + ******************************************************************************/ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + +#if defined(PLATFORM_WINDOWS) +#pragma pack(pop) +#endif + + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_aes.h b/USDK/component/common/drivers/wlan/realtek/include/rom_aes.h new file mode 100644 index 0000000..c89c6cc --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_aes.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * This is ROM code section. + * + ******************************************************************************/ +#ifndef ROM_AES_H +#define ROM_AES_H + +typedef struct +{ + u32 erk[64]; /* encryption round keys */ + u32 drk[64]; /* decryption round keys */ + int nr; /* number of rounds */ +}aes_context; + + +#define AES_BLOCKSIZE8 8 +#define AES_BLK_SIZE 16 // # octets in an AES block +typedef union _aes_block // AES cipher block +{ + unsigned long x[AES_BLK_SIZE/4]; // access as 8-bit octets or 32-bit words + unsigned char b[AES_BLK_SIZE]; +}aes_block; + + +void AES_WRAP(unsigned char * plain, int plain_len, + unsigned char * iv, int iv_len, + unsigned char * kek, int kek_len, + unsigned char *cipher, unsigned short *cipher_len); + +void AES_UnWRAP(unsigned char * cipher, int cipher_len, + unsigned char * kek, int kek_len, + unsigned char * plain); + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_arc4.h b/USDK/component/common/drivers/wlan/realtek/include/rom_arc4.h new file mode 100644 index 0000000..1eb2391 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_arc4.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * This is ROM code section. + * + ******************************************************************************/ +#ifndef ROM_ARC4_H +#define ROM_ARC4_H + +struct arc4context +{ + u32 x; + u32 y; + u8 state[256]; +}; + +u32 crc32_get(u8 *buf, sint len); +void rt_arc4_init(struct arc4context *parc4ctx, u8 * key,u32 key_len); +void rt_arc4_crypt( struct arc4context *parc4ctx, u8 * dest, u8 * src, u32 len); + + +#endif //ROM_ARC4_H diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_ieee80211.h b/USDK/component/common/drivers/wlan/realtek/include/rom_ieee80211.h new file mode 100644 index 0000000..064729d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_ieee80211.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ROM_IEEE80211_H +#define __ROM_IEEE80211_H + +extern const u8 RTW_WPA_OUI_TYPE[] ; +extern const u8 WPA_CIPHER_SUITE_NONE[]; +extern const u8 WPA_CIPHER_SUITE_WEP40[]; +extern const u8 WPA_CIPHER_SUITE_TKIP[]; +extern const u8 WPA_CIPHER_SUITE_CCMP[]; +extern const u8 WPA_CIPHER_SUITE_WEP104[]; +extern const u16 RSN_VERSION_BSD; +extern const u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[]; +extern const u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[]; +extern const u8 RSN_CIPHER_SUITE_NONE[]; +extern const u8 RSN_CIPHER_SUITE_WEP40[]; +extern const u8 RSN_CIPHER_SUITE_TKIP[]; +extern const u8 RSN_CIPHER_SUITE_CCMP[]; +extern const u8 RSN_CIPHER_SUITE_WEP104[]; + +/* Parsed Information Elements */ +struct rtw_ieee802_11_elems { + u8 *ssid; + u8 ssid_len; + u8 *supp_rates; + u8 supp_rates_len; + u8 *fh_params; + u8 fh_params_len; + u8 *ds_params; + u8 ds_params_len; + u8 *cf_params; + u8 cf_params_len; + u8 *tim; + u8 tim_len; + u8 *ibss_params; + u8 ibss_params_len; + u8 *challenge; + u8 challenge_len; + u8 *erp_info; + u8 erp_info_len; + u8 *ext_supp_rates; + u8 ext_supp_rates_len; + u8 *wpa_ie; + u8 wpa_ie_len; + u8 *rsn_ie; + u8 rsn_ie_len; + u8 *wme; + u8 wme_len; + u8 *wme_tspec; + u8 wme_tspec_len; + u8 *wps_ie; + u8 wps_ie_len; + u8 *power_cap; + u8 power_cap_len; + u8 *supp_channels; + u8 supp_channels_len; + u8 *mdie; + u8 mdie_len; + u8 *ftie; + u8 ftie_len; + u8 *timeout_int; + u8 timeout_int_len; + u8 *ht_capabilities; + u8 ht_capabilities_len; + u8 *ht_operation; + u8 ht_operation_len; + u8 *vendor_ht_cap; + u8 vendor_ht_cap_len; +}; + +typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; + +ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len, + struct rtw_ieee802_11_elems *elems, + int show_errors); + +u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen); +u8 *rtw_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen); +u8 *rtw_get_ie(u8*pbuf, sint index, u32 *len, sint limit); + +void rtw_set_supported_rate(u8* SupportedRates, uint mode) ; + +unsigned char *rtw_get_wpa_ie(unsigned char *pie, u32 *wpa_ie_len, int limit); +unsigned char *rtw_get_wpa2_ie(unsigned char *pie, u32 *rsn_ie_len, int limit); +int rtw_get_wpa_cipher_suite(u8 *s); +int rtw_get_wpa2_cipher_suite(u8 *s); + +int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x); +int rtw_parse_wpa2_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher, int *is_8021x); + +int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len); + +u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen); +u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr); +u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content); + +uint rtw_get_rateset_len(u8 *rateset); + +int rtw_get_bit_value_from_ieee_value(u8 val); + +uint rtw_is_cckrates_included(u8 *rate); + +uint rtw_is_cckratesonly_included(u8 *rate); + +int rtw_check_network_type(unsigned char *rate, int ratelen, int channel); + +u8 key_2char2num(u8 hch, u8 lch); + +#endif /* __ROM_IEEE80211_H */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_md5.h b/USDK/component/common/drivers/wlan/realtek/include/rom_md5.h new file mode 100644 index 0000000..fb6e9d2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_md5.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * This is ROM code section. + * + ******************************************************************************/ + +#ifndef ROM_MD5_H +#define ROM_MD5_H + +#if PSK_SUPPORT_TKIP + +/* MD5 context. */ +typedef struct { + u32 state[4]; /* state (ABCD) */ + u32 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + u8 buffer[64]; /* input buffer */ +} md5_ctx; + +void rt_md5_init(md5_ctx *context); +void rt_md5_append(md5_ctx *context, u8 *input, u32 inputLen); +void rt_md5_final(u8 digest[16], md5_ctx *context); +void rt_md5_hmac(unsigned char *text, int text_len, unsigned char *key, + int key_len, void * digest); + + +#endif //#if PSK_SUPPORT_TKIP +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_rc4.h b/USDK/component/common/drivers/wlan/realtek/include/rom_rc4.h new file mode 100644 index 0000000..5c40252 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_rc4.h @@ -0,0 +1,89 @@ +/* crypto/rc4/rc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +#define HEADER_RC4_H + +#ifdef OPENSSL_NO_RC4 +#error RC4 is disabled. +#endif + +//#include /* RC4_INT */ +#define RC4_INT unsigned int + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st + { + RC4_INT x,y; + RC4_INT data[256]; + } RC4_KEY; + + +//const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message.h b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message.h new file mode 100644 index 0000000..81115ae --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _ROM_RTW_MESSAGE_ +#define _ROM_RTW_MESSAGE_ + +#include + +typedef enum { +#define ROM_E_RTW_MSGPOOL(name,str) ROM_E_RTW_MSGP_##name, +#include "rom_rtw_message_e.h" + ROM_E_RTW_MSGP_MAX +} rom_e_rtw_msgp_t; + +#if ROM_E_RTW_MSG +extern const char *rom_e_rtw_msgp_str_[]; +#define rom_e_rtw_msg_printf(name, fmt, args...) printf((char*)rom_e_rtw_msgp_str_[ROM_E_RTW_MSGP_##name], ## args) +#define rom_e_rtw_msg_871X_LEVEL(name, level, fmt, args...) \ + do {\ + printf("\n\r");\ + printf((char*)rom_e_rtw_msgp_str_[ROM_E_RTW_MSGP_##name], ## args);\ + }while(0) +#else +#define rom_e_rtw_msg_printf(name, fmt, args...) printf(fmt, ## args) +#define rom_e_rtw_msg_871X_LEVEL(name, level, fmt, args...) \ + do {\ + printf("\n\r");\ + printf(DRIVER_PREFIX ##fmt, ## args);\ + }while(0) +#endif //ROM_E_RTW_MSG + +#endif //_ROM_RTW_MESSAGE_ diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message_e.h b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message_e.h new file mode 100644 index 0000000..8740be2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_message_e.h @@ -0,0 +1,174 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +// Debug message +// DBG_PWR_INDEX +ROM_E_RTW_MSGPOOL(PWR_INDEX_1, "BandWidth = %d, Rate = %d, Channel = %d\n\r") +ROM_E_RTW_MSGPOOL(PWR_INDEX_2, "Base = %d, DiffByRate = %d, limit = %d, DiffByTrack = %d, Tx Power = %d\n\n\r") +// DBG_RX_INFO +ROM_E_RTW_MSGPOOL(RX_INFO_1, "============ Rx Info dump ===================\n") +ROM_E_RTW_MSGPOOL(RX_INFO_2, "bLinked = %d, RSSI_Min = %d(%%), CurrentIGI = 0x%x\n") +ROM_E_RTW_MSGPOOL(RX_INFO_3, "Cnt_Cck_fail = %d, Cnt_Ofdm_fail = %d, Total False Alarm = %d\n") +ROM_E_RTW_MSGPOOL(RX_INFO_4, "RxRate = 0x%x, RSSI_A = %d(%%), RSSI_B = %d(%%)\n") +// DBG_TX_RATE +ROM_E_RTW_MSGPOOL(TX_RATE_1, "Rate: 0x%x\n\r") +ROM_E_RTW_MSGPOOL(TX_RATE_2, "%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n") +// DBG_DM_RA +ROM_E_RTW_MSGPOOL(DM_RA_1, "==> ReadRateMask = 0x%x RAMASK[%d] = 0x%x\n") +ROM_E_RTW_MSGPOOL(DM_RA_2, "==> TMP_rate = %x highest_rate = 0x%02X, lowest_rate = 0x%02X\n") +ROM_E_RTW_MSGPOOL(DM_RA_3, "==> MacID = %d rateid = 0x%x sgi = %d bw_idx = %d\n\r") +ROM_E_RTW_MSGPOOL(DM_RA_4, "%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\r\n") +// DBG_DM_DIG +ROM_E_RTW_MSGPOOL(DM_DIG_1, "CurrentIGI(0x%02x)\n\n") +// DBG_PWR_TRACKING +ROM_E_RTW_MSGPOOL(PWR_TRACKING_1, "Thermal = 0x%02X\r\n") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_2, "delta = %d, AVG Thermal = 0x%02X, EFUSE = 0x%02X, PackageType = 0x%02X\r\n") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_3, "Channel = %d, CCK PwrBase = 0x%02X, HT40M PwrBase = 0x%02X, OFDMdiff = %d, 20Mdiff = %d \n\r") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_4, "Remnant_CCKSwingIdx = %d\n\r") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_5, "Remnant_OFDMSwingIdx = %d\n\r") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_6, "CCK2~11: 0x86c = 0x%08X\r\n") +ROM_E_RTW_MSGPOOL(PWR_TRACKING_7, "MCS7~4 : 0xe14 = 0x%08X\r\n") +// DBG_RF_IQK +ROM_E_RTW_MSGPOOL(RF_IQK_1, "Path A Tx IQK Success!\n") +ROM_E_RTW_MSGPOOL(RF_IQK_2, "Path A Rx IQK Success!\n") +ROM_E_RTW_MSGPOOL(RF_IQK_3, "Path A IQK failed!\n") +ROM_E_RTW_MSGPOOL(RF_IQK_4, "IQK finished\n") +ROM_E_RTW_MSGPOOL(RF_IQK_5, "LCK finished\n") +// DBG_DM_ADAPTIVITY +ROM_E_RTW_MSGPOOL(DM_ADAPTIVITY_1, "IGI_Base=0x%x, TH_L2H_ini = %d, TH_EDCCA_HL_diff = %d\n") +ROM_E_RTW_MSGPOOL(DM_ADAPTIVITY_2, "DynamicLinkAdaptivity = %d, Adaptivity_enable = %d\n") +ROM_E_RTW_MSGPOOL(DM_ADAPTIVITY_3, "IGI=0x%x, TH_L2H_dmc = 0x%x, TH_H2L_dmc = 0x%x\n\n") + +// freertos_ioctl.c +// mac_reg_dump, bb_reg_dump, rf_reg_dump +ROM_E_RTW_MSGPOOL(MAC_REG_DUMP_1, "\n======= MAC REG =======\n") +ROM_E_RTW_MSGPOOL(BB_REG_DUMP_1, "\n======= BB REG =======\n") +ROM_E_RTW_MSGPOOL(RF_REG_DUMP_1, "\n======= RF REG =======\n") +ROM_E_RTW_MSGPOOL(RF_REG_DUMP_2, "\nRF_Path(%x)\n") +ROM_E_RTW_MSGPOOL(REG_DUMP_1, "0x%02x ") +ROM_E_RTW_MSGPOOL(REG_DUMP_2, " 0x%08x ") +ROM_E_RTW_MSGPOOL(REG_DUMP_3, "\n") +// 0x70 read reg +ROM_E_RTW_MSGPOOL(READ_REG_1, "rtw_read8(0x%x)=0x%02x\n") +ROM_E_RTW_MSGPOOL(READ_REG_2, "rtw_read16(0x%x)=0x%04x\n") +ROM_E_RTW_MSGPOOL(READ_REG_3, "rtw_read32(0x%x)=0x%08x\n") +// 0x71 write reg +ROM_E_RTW_MSGPOOL(WRITE_REG_1, "rtw_write8(0x%x)=0x%02x\n") +ROM_E_RTW_MSGPOOL(WRITE_REG_2, "rtw_write16(0x%x)=0x%04x\n") +ROM_E_RTW_MSGPOOL(WRITE_REG_3, "rtw_write32(0x%x)=0x%08x\n") +// 0x72 read bb +ROM_E_RTW_MSGPOOL(READ_BB_1, "read_bbreg(0x%x)=0x%x\n") +// 0x73 write bb +ROM_E_RTW_MSGPOOL(WRITE_BB_1, "write_bbreg(0x%x)=0x%x\n") +// 0x74 read rf +ROM_E_RTW_MSGPOOL(READ_RF_1, "read RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n") +// 0x75 write rf +ROM_E_RTW_MSGPOOL(WRITE_RF_1, "write RF_reg path(0x%02x),offset(0x%x),value(0x%08x)\n") +// 0x17 fix channel +ROM_E_RTW_MSGPOOL(FIX_CHANNEL_1, "=>Fixed channel to %d\n") +ROM_E_RTW_MSGPOOL(FIX_CHANNEL_2, "Invalid channel number(%d)\n") +// 0x22 enable / disable power saving mode +ROM_E_RTW_MSGPOOL(PWR_SAVE_MODE_1, "wlan power saving mode = %s\n") +// 0xaa fix rate +ROM_E_RTW_MSGPOOL(FIX_RATE_1, "chang data rate to :0x%02x\n") +// 0xc0 get odm dbg flag +ROM_E_RTW_MSGPOOL(GET_ODM_DBG_FLAG_1, "get odm dbg flag : 0x%08x\n") +// 0xc1 set odm dbg flag +ROM_E_RTW_MSGPOOL(SET_ODM_DBG_FLAG_1, "set odm dbg flag : 0x%08x\n") +// 0xcc open power index debug message (power by rate, power limit, power tracking) +ROM_E_RTW_MSGPOOL(DUMP_PWR_IDX_1, "Fixed rate = %d\n") +// 0xdd dump info +ROM_E_RTW_MSGPOOL(DUMP_INFO_1, "Tx power:\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_2, "CCK 1(0xe08)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_3, "CCK 11~2(0x86c)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_4, "OFDM 18~6(0xe00)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_5, "OFDM 54~24(0xe04)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_6, "MCS 3~0(0xe10)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_7, "MCS 7~4(0xe14)= 0x%x\n") +ROM_E_RTW_MSGPOOL(DUMP_INFO_8, "Country code: 0x%x\n") +// 0xee turn on/off dynamic funcs +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_1, " === DMFlag(0x%08x) === \n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_2, "extra_arg = 0 - disable all dynamic func\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_3, "extra_arg = 1 - enable all dynamic func\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_4, "extra_arg = 2 - disable DIG\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_5, "extra_arg = 3 - enable DIG\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_6, "extra_arg = 4 - disable tx power tracking\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_7, "extra_arg = 5 - enable tx power tracking\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_8, "extra_arg = 6 - disable adaptivity\n") +ROM_E_RTW_MSGPOOL(DM_FUNC_FLAG_9, "extra_arg = 7 - enable adaptivity\n") + +// lxbus_ops.c +ROM_E_RTW_MSGPOOL(RX_MPDU_1, "Drop packet! crc_err = %d, icv_err = %d, rx_pkt_len = %d, skb_pkt_len = %d\n") + +// wlan driver DBG_871X_LEVEL +#define ROM_E_RTW_MSGPOOL_871X(name,str) ROM_E_RTW_MSGPOOL(name,DRIVER_PREFIX str) +// rtw_ap.c +ROM_E_RTW_MSGPOOL_871X(AP_TIMEOUT_CHK_1, "Asoc expire "MAC_FMT"\n") +// rtw_intfs.c +ROM_E_RTW_MSGPOOL_871X(INIT_DRV_SW_1, "The driver is for MP\n") +// rtw_ioctl_set.c +ROM_E_RTW_MSGPOOL_871X(SET_BSSID_1, "set BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n") +ROM_E_RTW_MSGPOOL_871X(SET_SSID_1, "set ssid [%s] \n") +// rtw_mlme_ext.c +ROM_E_RTW_MSGPOOL_871X(ON_BEACON_1, "ap has changed, disconnect now\n ") +ROM_E_RTW_MSGPOOL_871X(ON_AUTH_1, "+OnAuth: "MAC_FMT"\n") +ROM_E_RTW_MSGPOOL_871X(ON_AUTH_2, " Exceed the upper limit(%d) of supported clients...\n") +ROM_E_RTW_MSGPOOL_871X(ON_AUTH_CLIENT_1, "auth success, start assoc\n") +ROM_E_RTW_MSGPOOL_871X(ON_ASSOC_REQ_1, "+OnAssocReq\n") +ROM_E_RTW_MSGPOOL_871X(ON_ASSOC_RSP_1, "association success(res=%d)\n") +ROM_E_RTW_MSGPOOL_871X(ON_DE_AUTH_1, "ap recv deauth reason code(%d) sta:"MAC_FMT"\n") +ROM_E_RTW_MSGPOOL_871X(ON_DE_AUTH_2, "sta recv deauth reason code(%d) sta:"MAC_FMT"\n") +ROM_E_RTW_MSGPOOL_871X(ON_DISASSOC_1, "ap recv disassoc reason code(%d) sta:"MAC_FMT"\n") +ROM_E_RTW_MSGPOOL_871X(ON_DISASSOC_2, "sta recv disassoc reason code(%d) sta:"MAC_FMT"\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_BEACON_1, "beacon frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_PROBERSP_1, "probersp frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_PROBEREQ_1, "probereq frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_AUTH_1, "auth frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_ASSOCRSP_1, "assocrsp frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_ASSOCREQ_1, "assocreq frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_NULLDATA_1, "nulldata frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_QOS_NULLDATA_1, "qos nulldata frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_DEAUTH_1, "deauth frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_ACTION_BA_1, "action BA frame too large\n") +ROM_E_RTW_MSGPOOL_871X(ISSUE_BSS_COEXIST_1, "action BSSCoexist frame too large\n") +ROM_E_RTW_MSGPOOL_871X(START_CLNT_AUTH_1, "start auth to %02x:%02x:%02x:%02x:%02x:%02x\n") +ROM_E_RTW_MSGPOOL_871X(LINKED_STATUS_CHK_1, "no beacon for a long time, disconnect or roaming\n") +ROM_E_RTW_MSGPOOL_871X(SETKEY_HDL_1, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) keyid:%d\n") +ROM_E_RTW_MSGPOOL_871X(SET_STAKEY_HDL_1, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4)\n") +ROM_E_RTW_MSGPOOL_871X(SET_STAKEY_HDL_2, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) for %x:%x:%x:%x:%x:%x\n") +// rtw_p2p.c +ROM_E_RTW_MSGPOOL_871X(P2P_BUILD_MGNT_FRAME_1, "p2p mgnt frame too large\n") +// rtw_psk.c +ROM_E_RTW_MSGPOOL_871X(SEND_EAPOL_1, "ap mode 4-1\n") +ROM_E_RTW_MSGPOOL_871X(SEND_EAPOL_2, "ap mode 4-3\n") +ROM_E_RTW_MSGPOOL_871X(SEND_EAPOL_3, "ap mode 2-1 to WPA_STA(%d)\n") +ROM_E_RTW_MSGPOOL_871X(EAPOL_KEY_RECVD_1, "ap mode 4-2\n") +ROM_E_RTW_MSGPOOL_871X(EAPOL_KEY_RECVD_2, "ap mode 4-4\n") +ROM_E_RTW_MSGPOOL_871X(EAPOL_KEY_RECVD_3, "ap mode 2-2 from WPA_STA(%d)\n") +// rtw_recv.c +ROM_E_RTW_MSGPOOL_871X(FREE_RECVFRAME_1, "%s free_recvframe_cnt:%d > %d refree happen !!!!\n") +// hal_com.c +ROM_E_RTW_MSGPOOL_871X(VAR_PORT_SWITCH_1, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n") +ROM_E_RTW_MSGPOOL_871X(VAR_PORT_SWITCH_2, "port switch - port0("ADPT_FMT"), port1("ADPT_FMT")\n") +// osdep_service.c +ROM_E_RTW_MSGPOOL_871X(DOWN_SEMA_1, "%s(%p) failed, retry\n") + + +#undef ROM_E_RTW_MSGPOOL +#undef ROM_E_RTW_MSGPOOL_871X diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_psk.h b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_psk.h new file mode 100644 index 0000000..14787ce --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_psk.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * This is ROM code section. + * + ******************************************************************************/ +#ifndef __ROM_RTW_PSK_H_ +#define __ROM_RTW_PSK_H_ + +int rom_psk_PasswordHash ( + unsigned char *password, + int passwordlength, + unsigned char *ssid, + int ssidlength, + unsigned char *output); + +void rom_psk_CalcPTK( unsigned char *addr1, unsigned char *addr2, + unsigned char *nonce1, unsigned char *nonce2, + unsigned char *keyin, int keyinlen, + unsigned char *keyout, int keyoutlen); + +void rom_psk_CalcGTK(unsigned char *addr, unsigned char *nonce, + unsigned char *keyin, int keyinlen, + unsigned char *keyout, int keyoutlen); + +#endif //__ROM_RTW_PSK_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_security.h b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_security.h new file mode 100644 index 0000000..28436b4 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_rtw_security.h @@ -0,0 +1,104 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * This is ROM code section. + * + ******************************************************************************/ +#ifndef __ROM_RTW_SECURITY_H_ +#define __ROM_RTW_SECURITY_H_ + +struct mic_data +{ + u32 K0, K1; // Key + u32 L, R; // Current state + u32 M; // Message accumulator (single word) + u32 nBytesInM; // # bytes in M +}; + +union u_crc +{ + unsigned char ch[4]; + int i; +}; + +//=============================== +// WEP related +//=============================== +void wep_80211_encrypt( + u8 *pframe, u32 wlan_hdr_len, \ + u32 iv_len, u32 payload_len,\ + u8* key, u32 key_len); + +u8 wep_80211_decrypt( + u8 *pframe, u32 wlan_hdr_len, + u32 iv_len, u32 payload_len, + u8* key, u32 key_len, + union u_crc *pcrc\ + ); + +//=============================== +// TKIP related +//=============================== +void tkip_80211_encrypt( + u8 *pframe, u32 wlan_hdr_len, \ + u32 iv_len, u32 payload_len,\ + u8* key, u32 key_len,\ + u8* ta); + +u8 tkip_80211_decrypt( + u8 *pframe, u32 wlan_hdr_len, \ + u32 iv_len, u32 payload_len,\ + u8* key, u32 key_len,\ + u8* ta, union u_crc *pcrc); + +void tkip_micappendbyte(struct mic_data *pmicdata, u8 b ); +void rtw_secmicsetkey(struct mic_data *pmicdata, u8 * key); +void rtw_secmicappend(struct mic_data *pmicdata, u8 * src, u32 nbytes ); +void rtw_secgetmic(struct mic_data *pmicdata, u8 * dst ); +void rtw_seccalctkipmic(u8 * key,u8 *header,u8 *data,u32 data_len,u8 *mic_code, u8 pri); +void tkip_phase1(u16 *p1k,const u8 *tk,const u8 *ta,u32 iv32); +void tkip_phase2(u8 *rc4key,const u8 *tk,const u16 *p1k,u16 iv16); + + +//=============================== +// AES related +//=============================== +void aes1_encrypt(u8 *key, u8 *data, u8 *ciphertext); +void aesccmp_construct_mic_iv( + u8 *mic_iv, sint qc_exists, sint a4_exists, + u8 *mpdu, uint payload_length,u8 *pn_vector); +void aesccmp_construct_mic_header1(u8 *mic_header1, sint header_length, u8 *mpdu); +void aesccmp_construct_mic_header2( + u8 *mic_header2, u8 *mpdu, sint a4_exists, sint qc_exists); +void aesccmp_construct_ctr_preload( + u8 *ctr_preload, sint a4_exists, sint qc_exists, + u8 *mpdu, u8 *pn_vector, sint c); + +u32 aes_80211_encrypt( + u8 *pframe, u32 wlan_hdr_len, \ + u32 payload_len, u8 *key, \ + u32 frame_type, u8 *mic); + +u32 aes_80211_decrypt( + u8 *pframe, u32 wlan_hdr_len, \ + u32 payload_len, u8 *key, \ + u32 frame_type, u8 *mic); +#endif //__ROM_RTW_SECURITY_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rom_sha1.h b/USDK/component/common/drivers/wlan/realtek/include/rom_sha1.h new file mode 100644 index 0000000..dc0dba0 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rom_sha1.h @@ -0,0 +1,71 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _ROM_SHA1_ +#define _ROM_SHA1_ + + +#ifndef _SHA_enum_ +#define _SHA_enum_ +enum +{ + shaSuccess = 0, + shaNull, /* Null pointer parameter */ + shaInputTooLong, /* input data too long */ + shaStateError /* called Input after Result */ +}; +#endif + + +#define SHA1HashSize 20 + +/* + * This structure will hold context information for the SHA-1 + * hashing operation + */ +typedef struct SHA1Context +{ + u32 Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ + + u32 Length_Low; /* Message length in bits */ + u32 Length_High; /* Message length in bits */ + + /* Index into message block array */ + u16 Message_Block_Index; + u8 Message_Block[64]; /* 512-bit message blocks */ + + int Computed; /* Is the digest computed? */ + int Corrupted; /* Is the message digest corrupted? */ +} SHA1Context; + + +/* + * Function Prototypes + */ + + +int rt_sha1_init( SHA1Context *); +int rt_sha1_update( SHA1Context *, const u8 *, unsigned int); +int rt_sha1_finish( SHA1Context *, u8 Message_Digest[SHA1HashSize]); + +void rt_hmac_sha1(unsigned char *text, int text_len, unsigned char *key, + int key_len, unsigned char *digest); + + +#endif //_ROM_SHA1_ diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtl8195a_hal.h b/USDK/component/common/drivers/wlan/realtek/include/rtl8195a_hal.h new file mode 100644 index 0000000..aca8be2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtl8195a_hal.h @@ -0,0 +1,618 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __RTL8195A_HAL_H__ +#define __RTL8195A_HAL_H__ + +#include "drv_types.h" +#include "rtl8195a/rtl8195a_pmu_task.h" +#include "hal_data.h" + +#include "rtl8195a/rtl8195a_spec.h" +#include "rtl8195a/rtl8195a_rf.h" +#include "rtl8195a/rtl8195a_dm.h" +#include "rtl8195a/rtl8195a_recv.h" +#include "rtl8195a/rtl8195a_xmit.h" +#include "rtl8195a/rtl8195a_cmd.h" +#include "rtl8195a/rtl8195a_pmu_cmd.h" +#include "rtl8195a/rtl8195a_led.h" +#include "rtl8195a/Hal8195APwrSeq.h" +#include "rtl8195a/Hal8195APhyReg.h" +#include "rtl8195a/Hal8195APhyCfg.h" +#include "rtl8195a/rom_Hal8195APhyCfg.h" + +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8195a/rtl8195a_sreset.h" +#endif + +#include "../src/hal/OUTSRC/phydm_precomp.h" + +#if (RTL8195A_SUPPORT==1) + //2TODO: We should define 8192S firmware related macro settings here!! + #define RTL819X_DEFAULT_RF_TYPE RF_1T2R + #define RTL819X_TOTAL_RF_PATH 2 + +//--------------------------------------------------------------------- +// RTL8723BS From file +//--------------------------------------------------------------------- + #define RTL8723B_FW_IMG "rtl8723B\\rtl8723bfw.bin" + #define RTL8195A_PHY_REG "rtl8195A\\PHY_REG_1T.txt" + #define RTL8195A_PHY_RADIO_A "rtl8195A\\radio_a_1T.txt" + #define RTL8195A_PHY_RADIO_B "rtl8195A\\radio_b_1T.txt" + #define RTL8195A_TXPWR_TRACK "rtl8195A\\TxPowerTrack.txt" + #define RTL8195A_AGC_TAB "rtl8195A\\AGC_TAB_1T.txt" + #define RTL8195A_PHY_MACREG "rtl87195A\\MAC_REG.txt" + #define RTL8195A_PHY_REG_PG "rtl8195A\\PHY_REG_PG.txt" + #define RTL8195A_PHY_REG_MP "rtl8195A\\PHY_REG_MP.txt" + #define RTL8195A_TXPWR_LMT "rtl8195A\\TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8723BS From header +//--------------------------------------------------------------------- + + //#define Rtl8723B_FwImageArray Array_MP_8723B_FW_NIC + //#define Rtl8723B_FwImgArrayLength ArrayLength_MP_8723B_FW_NIC + //#define Rtl8723B_FwWoWImageArray Array_MP_8723B_FW_WoWLAN + //#define Rtl8723B_FwWoWImgArrayLength ArrayLength_MP_8723B_FW_WoWLAN + + #define Rtl8723B_PHY_REG_Array_PG Rtl8723SPHY_REG_Array_PG + #define Rtl8723B_PHY_REG_Array_PGLength Rtl8723SPHY_REG_Array_PGLength + +#if MP_DRIVER == 1 + #define Rtl8723B_FwBTImgArray Rtl8723BFwBTImgArray + #define Rtl8723B_FwBTImgArrayLength Rtl8723BFwBTImgArrayLength + + #define Rtl8723B_FwMPImageArray Rtl8723BFwMPImgArray + #define Rtl8723B_FwMPImgArrayLength Rtl8723BMPImgArrayLength + + #define Rtl8723B_PHY_REG_Array_MP Rtl8723B_PHYREG_Array_MP + #define Rtl8723B_PHY_REG_Array_MPLength Rtl8723B_PHYREG_Array_MPLength +#endif + +#endif // RTL8195A_SUPPORT + +#define FW_8723B_SIZE 0x8000 +#define FW_8723B_START_ADDRESS 0x1000 +#define FW_8723B_END_ADDRESS 0x1FFF //0x5FFF + +#define IS_FW_HEADER_EXIST_8723B(_pFwHdr) ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x5300) + +typedef struct _RT_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_8723B_SIZE]; +#endif + u32 ulFwLength; + +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szBTFwBuffer; +#else + u8 szBTFwBuffer[FW_8723B_SIZE]; +#endif + u32 ulBTFwLength; + +#ifdef CONFIG_WOWLAN + u8* szWoWLANFwBuffer; + u32 ulWoWLANFwLength; +#endif //CONFIG_WOWLAN +} RT_FIRMWARE_8723B, *PRT_FIRMWARE_8723B; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8723B_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u8 Subversion; // FW Subversion, default 0x00 + u16 Rsvd1; + + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8723B_FIRMWARE_HDR, *PRT_8723B_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME_8195A 0x05 // 5ms +#define BCN_DMA_ATIME_INT_TIME_8195A 0x02 // 2ms + +// for 8195A +// TX 32K, RX 16K, Page size 128B for TX, 8B for RX +#define PAGE_SIZE_TX_8195A 128 +#define PAGE_SIZE_RX_8195A 8 + +#define RX_DMA_SIZE_8195A 0x4000 // 16K +#define RX_DMA_RESERVED_SIZE_8195A 0x80 // 128B, reserved for tx report +#define RX_DMA_BOUNDARY_8195A (RX_DMA_SIZE_8195A - RX_DMA_RESERVED_SIZE_8195A - 1) + + +// Note: We will divide number of page equally for each queue other than public queue! + +//For General Reserved Page Number(Beacon Queue is reserved page) +//Beacon:2, PS-Poll:1, Null Data:1,Qos Null Data:1,BT Qos Null Data:1 +#ifdef CONFIG_WLAN_HAL_TEST +#define BCNQ_PAGE_NUM_8195A 0x00 +#else +#define BCNQ_PAGE_NUM_8195A 0x08 +#endif + +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8195A 0x04 +#else +#define BCNQ1_PAGE_NUM_8195A 0x00 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8195A 0x07 +#else +#define WOWLAN_PAGE_NUM_8195A 0x00 +#endif + +#ifdef CONFIG_WLAN_HAL_TEST +#define TX_TOTAL_PAGE_NUMBER_8195A 0x40 +#define TX_PAGE_BOUNDARY_8195A (TX_TOTAL_PAGE_NUMBER_8195A + 1) +#else +#define TX_TOTAL_PAGE_NUMBER_8195A (0xFF - BCNQ_PAGE_NUM_8195A - BCNQ1_PAGE_NUM_8195A - WOWLAN_PAGE_NUM_8195A) +#define TX_PAGE_BOUNDARY_8195A (TX_TOTAL_PAGE_NUMBER_8195A + 1) +#endif + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER TX_TOTAL_PAGE_NUMBER_8195A +#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8195A +#ifdef CONFIG_WLAN_HAL_TEST +#define NORMAL_PAGE_NUM_HPQ_8195A 0x10 +#define NORMAL_PAGE_NUM_LPQ_8195A 0x10 +#define NORMAL_PAGE_NUM_NPQ_8195A 0x10 +#else +#define NORMAL_PAGE_NUM_HPQ_8195A 0x0C +#define NORMAL_PAGE_NUM_LPQ_8195A 0x02 +#define NORMAL_PAGE_NUM_NPQ_8195A 0x02 +#endif + +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8195A 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8195A 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8195A 0x20 + +#include "HalVerDef.h" +#include "hal_com.h" + +#define EFUSE_OOB_PROTECT_BYTES (52+28+16+32) // Security + RF + MAC + OTP = 128 + +#define HWSET_MAX_SIZE_8195A 512 +#define EFUSE_REAL_CONTENT_LEN_8195A 256 +#define EFUSE_MAP_LEN_8195A 512 +#define EFUSE_MAX_SECTION_8195A 64 + +#define EFUSE_IC_ID_OFFSET 506 //For some inferiority IC purpose. added by Roger, 2009.09.02. +#define AVAILABLE_EFUSE_ADDR(addr) (addr < EFUSE_REAL_CONTENT_LEN_8195A) + +#define EFUSE_ACCESS_ON 0x69 // For RTL8723 only. +#define EFUSE_ACCESS_OFF 0x00 // For RTL8723 only. + +#ifdef CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD +#define LITTLE_WIFI_STACKSIZE 512 +#ifdef PLATFORM_CMSIS_RTOS +#define LITTLE_WIFI_TASK_PRIORITY 3 // osPriorityRealtime +#ifdef CONFIG_POWER_SAVING +#define CHECK_IN_REQ_STATE_STACKSIZE 256 +#define CHECK_IN_REQ_STATE_TASK_PRIORITY 0//osPriorityNormal + +#ifdef TDMA_POWER_SAVING +#define TDMA_CHANGE_STATE_STACKSIZE 256 +#define TDMA_CHANGE_STATE_TASK_PRIORITY 2//osPriorityRealtime +#endif //#ifdef TDMA_POWER_SAVING + +#endif +#else +#define LITTLE_WIFI_TASK_PRIORITY 6//TASK_PRORITY_LOW + +#ifdef CONFIG_POWER_SAVING +#define CHECK_IN_REQ_STATE_STACKSIZE 256 +#define CHECK_IN_REQ_STATE_TASK_PRIORITY 1 + +#ifdef TDMA_POWER_SAVING +#define TDMA_CHANGE_STATE_STACKSIZE 256 +#define TDMA_CHANGE_STATE_TASK_PRIORITY 3 +#endif //#ifdef TDMA_POWER_SAVING + +#endif +#endif +#endif + +#define LX_DMA_IMR_DISABLED 0 +#define FW_IMR_DISABLED 0 +#define WL_PMC_IMR_DISABLED 0 + + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) + +// Description: Determine the types of C2H events that are the same in driver and Fw. +// Fisrt constructed by tynli. 2009.10.09. +typedef enum _C2H_EVT +{ + C2H_DBG = 0, + C2H_TSF = 1, + C2H_AP_RPT_RSP = 2, + C2H_CCX_TX_RPT = 3, // The FW notify the report of the specific tx packet. + C2H_BT_RSSI = 4, + C2H_BT_OP_MODE = 5, + C2H_EXT_RA_RPT = 6, + C2H_8723B_BT_INFO = 9, + C2H_HW_INFO_EXCH = 10, + C2H_8723B_BT_MP_INFO = 11, + MAX_C2HEVENT +} C2H_EVT; + +typedef _PACKED struct _C2H_EVT_HDR +{ + u8 CmdID; + u8 CmdLen; + u8 CmdSeq; +} C2H_EVT_HDR, *PC2H_EVT_HDR; + +typedef enum tag_Package_Definition +{ + PACKAGE_DEFAULT, + PACKAGE_QFN56, + PACKAGE_QFN48, + PACKAGE_BGA96, + PACKAGE_QFN88, + PACKAGE_QFN216 +}PACKAGE_TYPE_E; + +typedef enum tag_ChipID_Definition +{ + CHIPID_8711AM = 0xFF, + CHIPID_8195AM = 0xFE, + CHIPID_8711AF = 0xFD, + CHIPID_8710AF = 0xFC, + CHIPID_8711AN = 0xFB, + CHIPID_8710AM = 0xFA +}CHIP_TD_E; + + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +//======================================================== +// TXBD and RXBD definition +//======================================================== +#ifdef CONFIG_MP_INCLUDED // For MP Tx no idle +#define TX_VIQ_DESC_NUM 4 +#define TX_VOQ_DESC_NUM 4 +#define TX_BKQ_DESC_NUM 4 +#define TX_BEQ_DESC_NUM 32 +#else +#define TX_VIQ_DESC_NUM 4 +#define TX_VOQ_DESC_NUM 4 +#define TX_BKQ_DESC_NUM 4 +#define TX_BEQ_DESC_NUM 4 +#endif +#define TX_BCNQ_DESC_NUM 2 +#define TX_MGQ_DESC_NUM 4 +#define TX_H0Q_DESC_NUM 2 +#define TX_H1Q_DESC_NUM 2 +#define TX_H2Q_DESC_NUM 2 +#define TX_H3Q_DESC_NUM 2 +#define TX_H4Q_DESC_NUM 2 +#define TX_H5Q_DESC_NUM 2 +#define TX_H6Q_DESC_NUM 2 +#define TX_H7Q_DESC_NUM 2 +#define RX_Q_DESC_NUM 4 //16 Reduce rx desc number due to memory limitation + +#define SET_VIQ_DES_NUM (TX_VIQ_DESC_NUM<<16) +#define SET_VOQ_DES_NUM (TX_VOQ_DESC_NUM) +#define SET_RXQ_DES_NUM (RX_Q_DESC_NUM<<16) +#define SET_MGQ_DES_NUM (TX_MGQ_DESC_NUM) +#define SET_BKQ_DES_NUM (TX_BKQ_DESC_NUM<<16) +#define SET_BEQ_DES_NUM (TX_BEQ_DESC_NUM) +#define SET_H1Q_DES_NUM (TX_H1Q_DESC_NUM<<16) +#define SET_H0Q_DES_NUM (TX_H0Q_DESC_NUM) +#define SET_H3Q_DES_NUM (TX_H3Q_DESC_NUM<<16) +#define SET_H2Q_DES_NUM (TX_H2Q_DESC_NUM) +#define SET_H5Q_DES_NUM (TX_H5Q_DESC_NUM<<16) +#define SET_H4Q_DES_NUM (TX_H4Q_DESC_NUM) +#define SET_H7Q_DES_NUM (TX_H7Q_DESC_NUM<<16) +#define SET_H6Q_DES_NUM (TX_H6Q_DESC_NUM) + +#define TX_DESC_MODE 1 + +//0: 2 segment +//1: 4 segment +//2: 8 segment +//#define TX_DESC_MODE 2 + +#define MAX_TXBD_SEQMENT_NUM ((TX_DESC_MODE)? (4*TX_DESC_MODE): 2) +#define TXBD_SEGMENT_SIZE 8 + + + +typedef struct _RXBD_ELEMENT_ { + u32 Dword0; + u32 PhyAddr; +}RXBD_ELEMENT,*PRXBD_ELEMENT; + + +typedef struct _TXBD_ELEMENT_ { + u32 Dword0; + u32 AddrLow; +}TXBD_ELEMENT,*PTXBD_ELEMENT; + +typedef struct _LX_DMA_ELEMENT_ { + u32 QueueTRxBdBase; + u32 HwIndex; + u32 HostIndex; + u32 AvaliableCnt; +}LX_DMA_ELEMENT, *PLX_DMA_ELEMENT; +#if 1 + +typedef enum _LX_DMA_QUEUE_TYPE_{ + VO_QUEUE = 0, + VI_QUEUE = 1, + BE_QUEUE = 2, + BK_QUEUE = 3, + MG_QUEUE = 4, + RX_QUEUE = 5, + H0_QUEUE = 6, + H1_QUEUE = 7, + H2_QUEUE = 8, + H3_QUEUE = 9, + H4_QUEUE = 10, + H5_QUEUE = 11, + H6_QUEUE = 12, + H7_QUEUE = 13, + BCN_QUEUE = 14, + MAX_TX_QUEUE = 15, + ERROR_QUEUE = 16, +}LX_DMA_QUEUE_TYPE, *PLX_DMA_QUEUE_TYPE; + +typedef struct _TX_FREE_QUEUE_ { + _queue FreeQueue; + u32 Qlen; +}TX_FREE_QUEUE, *PTX_FREE_QUEUE; + +typedef struct _LX_DMA_MANAGER_ { + LX_DMA_ELEMENT QueueTRxBd[MAX_TX_QUEUE]; + u32 QueueMaxValue[MAX_TX_QUEUE]; + u32 RxBdSkb[RX_Q_DESC_NUM]; + u32 RxLen; + u32 RemainLen; + u16 RxAggregateNum; + u16 RxExpectTag; + u16 RxSegFlow; + u16 Flagls; + TX_FREE_QUEUE TxFreeQueue[MAX_TX_QUEUE]; + +}LX_DMA_MANAGER, *PLX_DMA_MANAGER; + +#else + +typedef struct _LX_DMA_MANAGER_ { + u32 *pVoqTXBD; + u32 *pViqTXBD; + u32 *pBeqTXBD; + u32 *pBkqTXBD; + u32 *pBcnqTXBD; + u32 *pMgqTXBD; + u32 *pH0qTXBD; + u32 *pH1qTXBD; + u32 *pH2qTXBD; + u32 *pH3qTXBD; + u32 *pH4qTXBD; + u32 *pH5qTXBD; + u32 *pH6qTXBD; + u32 *pH7qTXBD; + u32 *pExViqTXBD; + u32 *pExVoqTXBD; + u32 *pExBeqTXBD; + u32 *pExBkqTXBD; + u32 *pExMgqTXBD; + u32 *pRXBD; +// u4Byte RxAggBufEntry[RX_Q_DESC_NUM]; +// u4Byte RxAggLenEntry[RX_Q_DESC_NUM]; + u32 RxLen; + u32 RemainLen; + u16 ViqTxWritePoint; + u16 ViqTxReadPoint; + u16 VoqTxWritePoint; + u16 VoqTxReadPoint; + u16 BeqTxWritePoint; + u16 BeqTxReadPoint; + u16 BkqTxWritePoint; + u16 BkqTxReadPoint; + u16 RxWritePoint; + u16 RxReadPoint; + u16 RxAggregateNum; + u16 RxExpectTag; + u16 RxSegFlow; + u16 Flagls; +}LX_DMA_MANAGER, *PLX_DMA_MANAGER; +#endif + +// rtl8723a_hal_init.c +s32 rtl8195a_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void rtl8195a_FirmwareSelfReset(PADAPTER padapter); +void rtl8195a_InitializeFirmwareVars(PADAPTER padapter); + +void rtl8195a_InitAntenna_Selection(PADAPTER padapter); +void rtl8195a_DeinitAntenna_Selection(PADAPTER padapter); +void rtl8195a_CheckAntenna_Selection(PADAPTER padapter); +void rtl8195a_init_default_value(PADAPTER padapter); + +s32 rtl8195a_InitLLTTable(PADAPTER padapter); + +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU); +s32 CardDisableWithoutHWSM(PADAPTER padapter); + +// EFuse +//u8 GetEEPROMSize8195a(PADAPTER padapter); +void Hal_InitPGData(PADAPTER padapter, u8 *PROMContent); +void Hal_EfuseParseIDCode(PADAPTER padapter, u8 *hwinfo); +void Hal_EfuseParseTxPowerInfo_8195A(PADAPTER padapter, u8 *PROMContent, BOOLEAN AutoLoadFail); +void Hal_EfuseParseBTCoexistInfo_8195A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseEEPROMVer_8195A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseChnlPlan_8195A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID_8195A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseAntennaDiversity_8195A(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8195A(PADAPTER pAdapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseThermalMeter_8195A(PADAPTER padapter, u8 *hwinfo, u8 AutoLoadFail); + +u8 rtw_flash_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_flash_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_config_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data, u8 efuse); +u8 rtw_config_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data, u8 efuse); + +void rtl8195a_set_hal_ops(struct hal_ops *pHalFunc); +void lxbus_set_intf_ops(struct _io_ops *pops); +void SetHwReg8195A(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg8195A(PADAPTER padapter, u8 variable, u8 *val); +u8 SetHalDefVar8195A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8195A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +void SetHalODMVar8195A( PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); +void GetHalODMVar8195A(PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); + +// register +void rtl8195a_InitBeaconParameters(PADAPTER padapter); +void rtl8195a_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode); +void _InitBurstPktLen_8195AB(PADAPTER Adapter); +#ifdef CONFIG_WOWLAN +void _8051Reset8195a(PADAPTER padapter); +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void rtl8195a_start_thread(_adapter *padapter); +void rtl8195a_stop_thread(_adapter *padapter); + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +void rtl8195ab_init_checkbthang_workqueue(_adapter * adapter); +void rtl8195ab_free_checkbthang_workqueue(_adapter * adapter); +void rtl8195ab_cancle_checkbthang_workqueue(_adapter * adapter); +void rtl8195ab_hal_check_bt_hang(_adapter * adapter); +#endif + +#ifdef CONFIG_WOWLAN +void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip); +void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr); +#endif + +#ifdef CONFIG_GPIO_WAKEUP +void HalSetOutPutGPIO(PADAPTER padapter, u8 index, u8 OutPutValue); +#endif + +#ifdef CONFIG_RF_GAIN_OFFSET +void Hal_ReadRFGainOffset(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +#endif //CONFIG_RF_GAIN_OFFSET + + +//1TODO: Chris +#if 1 + +//============= +// [1] Rx Buffer Descriptor (for PCIE) buffer descriptor architecture +//DWORD 0 +#define SET_RX_BUFFER_DESC_DATA_LENGTH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc,__Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 14, 1, __Value) +#define SET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 15, 1, __Value) +#define SET_RX_BUFFER_DESC_RX_TAG_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 16, 13, __Value) + +#define GET_RX_BUFFER_DESC_OWN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) +#define GET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_BUFFER_DESC_RX_TAG_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 13) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH_92E(__pRxStatusDesc)LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) + + +//DWORD 1 +#define SET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+4, 0, 32, __Value) +#define GET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 0, 32) + +//DWORD 2 +#define SET_RX_BUFFER_PHYSICAL_HIGH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+8, 0, 32, __Value) + + +//=====Tx Desc Buffer content + +// config element for each tx buffer +/* +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) +*/ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) + +// Dword 0 +#define SET_TX_BUFF_DESC_LEN_0_92E(__pTxDesc, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Valeu) +#define SET_TX_BUFF_DESC_PSB_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_BUFF_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +// Dword 1 +#define SET_TX_BUFF_DESC_ADDR_LOW_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_92E(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+4, 0,32) + + +// Dword 2 +#define SET_TX_BUFF_DESC_ADDR_HIGH_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 32, __Value) +// Dword 3, RESERVED + + +#define SET_TX_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +#endif + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtl8711b_hal.h b/USDK/component/common/drivers/wlan/realtek/include/rtl8711b_hal.h new file mode 100644 index 0000000..6f97db2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtl8711b_hal.h @@ -0,0 +1,595 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __RTL8711B_HAL_H__ +#define __RTL8711B_HAL_H__ + +#include "drv_types.h" +//#include "rtl8711b/rtl8711b_pmu_task.h" +#include "hal_data.h" + +#include "rtl8711b/rtl8711b_spec.h" +#include "rtl8711b/rtl8711b_rf.h" +#include "rtl8711b/rtl8711b_dm.h" +#include "rtl8711b/rtl8711b_recv.h" +#include "rtl8711b/rtl8711b_xmit.h" +#include "rtl8711b/rtl8711b_cmd.h" +//#include "rtl8711b/rtl8711b_pmu_cmd.h" +#include "rtl8711b/rtl8711b_led.h" +#include "rtl8711b/Hal8711BPwrSeq.h" +#include "rtl8711b/Hal8711BPhyReg.h" +#include "rtl8711b/Hal8711BPhyCfg.h" +#include "rtl8711b/rom_Hal8711BPhyCfg.h" + +#ifdef DBG_CONFIG_ERROR_DETECT +#include "rtl8711b/rtl8711b_sreset.h" +#endif + +#include "../src/hal/OUTSRC/phydm_precomp.h" + +#if (RTL8711B_SUPPORT==1) + //2TODO: We should define 8192S firmware related macro settings here!! + #define RTL819X_DEFAULT_RF_TYPE RF_1T2R + #define RTL819X_TOTAL_RF_PATH 2 + +//--------------------------------------------------------------------- +// RTL8723BS From file +//--------------------------------------------------------------------- + #define RTL8723B_FW_IMG "rtl8723B\\rtl8723bfw.bin" + #define RTL8711B_PHY_REG "rtl8711B\\PHY_REG_1T.txt" + #define RTL8711B_PHY_RADIO_A "rtl8711B\\radio_a_1T.txt" + #define RTL8711B_PHY_RADIO_B "rtl8711B\\radio_b_1T.txt" + #define RTL8711B_TXPWR_TRACK "rtl8711B\\TxPowerTrack.txt" + #define RTL8711B_AGC_TAB "rtl8711B\\AGC_TAB_1T.txt" + #define RTL8711B_PHY_MACREG "rtl87195A\\MAC_REG.txt" + #define RTL8711B_PHY_REG_PG "rtl8711B\\PHY_REG_PG.txt" + #define RTL8711B_PHY_REG_MP "rtl8711B\\PHY_REG_MP.txt" + #define RTL8711B_TXPWR_LMT "rtl8711B\\TXPWR_LMT.txt" + +//--------------------------------------------------------------------- +// RTL8723BS From header +//--------------------------------------------------------------------- + + //#define Rtl8723B_FwImageArray Array_MP_8723B_FW_NIC + //#define Rtl8723B_FwImgArrayLength ArrayLength_MP_8723B_FW_NIC + //#define Rtl8723B_FwWoWImageArray Array_MP_8723B_FW_WoWLAN + //#define Rtl8723B_FwWoWImgArrayLength ArrayLength_MP_8723B_FW_WoWLAN + + #define Rtl8711B_PHY_REG_Array_PG Rtl8723SPHY_REG_Array_PG + #define Rtl8711B_PHY_REG_Array_PGLength Rtl8723SPHY_REG_Array_PGLength + +#if MP_DRIVER == 1 + #define Rtl8711B_FwBTImgArray Rtl8723BFwBTImgArray + #define Rtl8711B_FwBTImgArrayLength Rtl8723BFwBTImgArrayLength + + #define Rtl8711B_FwMPImageArray Rtl8723BFwMPImgArray + #define Rtl8711B_FwMPImgArrayLength Rtl8723BMPImgArrayLength + + #define Rtl8711B_PHY_REG_Array_MP Rtl8723B_PHYREG_Array_MP + #define Rtl8711B_PHY_REG_Array_MPLength Rtl8723B_PHYREG_Array_MPLength +#endif + +#endif // RTL8711B_SUPPORT + +#define FW_8711B_SIZE 0x8000 +#define FW_8711B_START_ADDRESS 0x1000 +#define FW_8711B_END_ADDRESS 0x1FFF //0x5FFF + +#define IS_FW_HEADER_EXIST_8711B(_pFwHdr) ((GET_FIRMWARE_HDR_SIGNATURE(_pFwHdr)&0xFFF0) == 0x10B0) + +typedef struct _RT_FIRMWARE { + FIRMWARE_SOURCE eFWSource; +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szFwBuffer; +#else + u8 szFwBuffer[FW_8711B_SIZE]; +#endif + u32 ulFwLength; + +#ifdef CONFIG_EMBEDDED_FWIMG + u8* szBTFwBuffer; +#else + u8 szBTFwBuffer[FW_8711B_SIZE]; +#endif + u32 ulBTFwLength; + +#ifdef CONFIG_WOWLAN + u8* szWoWLANFwBuffer; + u32 ulWoWLANFwLength; +#endif //CONFIG_WOWLAN +} RT_FIRMWARE_8711B, *PRT_FIRMWARE_8711B; + +// +// This structure must be cared byte-ordering +// +// Added by tynli. 2009.12.04. +typedef struct _RT_8723B_FIRMWARE_HDR +{ + // 8-byte alinment required + + //--- LONG WORD 0 ---- + u16 Signature; // 92C0: test chip; 92C, 88C0: test chip; 88C1: MP A-cut; 92C1: MP A-cut + u8 Category; // AP/NIC and USB/PCI + u8 Function; // Reserved for different FW function indcation, for further use when driver needs to download different FW in different conditions + u16 Version; // FW Version + u8 Subversion; // FW Subversion, default 0x00 + u16 Rsvd1; + + + //--- LONG WORD 1 ---- + u8 Month; // Release time Month field + u8 Date; // Release time Date field + u8 Hour; // Release time Hour field + u8 Minute; // Release time Minute field + u16 RamCodeSize; // The size of RAM code + u16 Rsvd2; + + //--- LONG WORD 2 ---- + u32 SvnIdx; // The SVN entry index + u32 Rsvd3; + + //--- LONG WORD 3 ---- + u32 Rsvd4; + u32 Rsvd5; +}RT_8723B_FIRMWARE_HDR, *PRT_8723B_FIRMWARE_HDR; + +#define DRIVER_EARLY_INT_TIME_8711B 0x05 // 5ms +#define BCN_DMA_ATIME_INT_TIME_8711B 0x02 // 2ms + +// for 8711B +// TX 32K, RX 16K, Page size 128B for TX, 8B for RX +#define PAGE_SIZE_TX_8711B 128 +#define PAGE_SIZE_RX_8711B 8 + +#define RX_DMA_SIZE_8711B 0x4000 // 16K +#define RX_DMA_RESERVED_SIZE_8711B 0x80 // 128B, reserved for tx report +#define RX_DMA_BOUNDARY_8711B (RX_DMA_SIZE_8711B - RX_DMA_RESERVED_SIZE_8711B - 1) + +// Note: We will divide number of page equally for each queue other than public queue! + +//For General Reserved Page Number(Beacon Queue is reserved page) +//Beacon:2, PS-Poll:1, Null Data:1,Qos Null Data:1,BT Qos Null Data:1 +#ifdef CONFIG_WLAN_HAL_TEST +#define BCNQ_PAGE_NUM_8711B 0x00 +#else +#define BCNQ_PAGE_NUM_8711B 0x08 +#endif + +#ifdef CONFIG_CONCURRENT_MODE +#define BCNQ1_PAGE_NUM_8711B 0x04 +#else +#define BCNQ1_PAGE_NUM_8711B 0x00 +#endif + +//For WoWLan , more reserved page +//ARP Rsp:1, RWC:1, GTK Info:1,GTK RSP:2,GTK EXT MEM:2 +#ifdef CONFIG_WOWLAN +#define WOWLAN_PAGE_NUM_8711B 0x07 +#else +#define WOWLAN_PAGE_NUM_8711B 0x00 +#endif + +#ifdef CONFIG_WLAN_HAL_TEST +#define TX_TOTAL_PAGE_NUMBER_8711B (0xF8 - BCNQ_PAGE_NUM_8711B - BCNQ1_PAGE_NUM_8711B - WOWLAN_PAGE_NUM_8711B) +//#define TX_TOTAL_PAGE_NUMBER_8711B 0x40 +#define TX_PAGE_BOUNDARY_8711B (TX_TOTAL_PAGE_NUMBER_8711B + 1) +#else +#define TX_TOTAL_PAGE_NUMBER_8711B (0xFF - BCNQ_PAGE_NUM_8711B - BCNQ1_PAGE_NUM_8711B - WOWLAN_PAGE_NUM_8711B) +#define TX_PAGE_BOUNDARY_8711B (TX_TOTAL_PAGE_NUMBER_8711B + 1) +#endif + +#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER TX_TOTAL_PAGE_NUMBER_8711B +#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER + 1) + +// For Normal Chip Setting +// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER_8711B +#ifdef CONFIG_WLAN_HAL_TEST +#define NORMAL_PAGE_NUM_HPQ_8711B 0x10 +#define NORMAL_PAGE_NUM_LPQ_8711B 0x10 +#define NORMAL_PAGE_NUM_NPQ_8711B 0x10 +#else +#define NORMAL_PAGE_NUM_HPQ_8711B 0x0C +#define NORMAL_PAGE_NUM_LPQ_8711B 0x02 +#define NORMAL_PAGE_NUM_NPQ_8711B 0x02 +#endif + +#ifdef CONFIG_WLAN_HAL_TEST +#define WMM_NORMAL_PAGE_NUM_HPQ_8711B 0x10 +#define WMM_NORMAL_PAGE_NUM_LPQ_8711B 0x10 +#define WMM_NORMAL_PAGE_NUM_NPQ_8711B 0x10 +#else +// Note: For Normal Chip Setting, modify later +#define WMM_NORMAL_PAGE_NUM_HPQ_8711B 0x30 +#define WMM_NORMAL_PAGE_NUM_LPQ_8711B 0x20 +#define WMM_NORMAL_PAGE_NUM_NPQ_8711B 0x20 +#endif + +#include "HalVerDef.h" +#include "hal_com.h" + +#define LX_DMA_IMR_DISABLED 0 +#define FW_IMR_DISABLED 0 +#define WL_PMC_IMR_DISABLED 0 + + +//======================================================== +// EFUSE for BT definition +//======================================================== +#define EFUSE_BT_REAL_BANK_CONTENT_LEN 512 +#define EFUSE_BT_REAL_CONTENT_LEN 1536 // 512*3 +#define EFUSE_BT_MAP_LEN 1024 // 1k bytes +#define EFUSE_BT_MAX_SECTION 128 // 1024/8 + +#define EFUSE_PROTECT_BYTES_BANK 16 + +#define GET_RF_TYPE(priv) (GET_HAL_DATA(priv)->rf_type) + +// Description: Determine the types of C2H events that are the same in driver and Fw. +// Fisrt constructed by tynli. 2009.10.09. +typedef enum _C2H_EVT +{ + C2H_DBG = 0, + C2H_TSF = 1, + C2H_AP_RPT_RSP = 2, + C2H_CCX_TX_RPT = 3, // The FW notify the report of the specific tx packet. + C2H_BT_RSSI = 4, + C2H_BT_OP_MODE = 5, + C2H_EXT_RA_RPT = 6, + C2H_8723B_BT_INFO = 9, + C2H_HW_INFO_EXCH = 10, + C2H_8723B_BT_MP_INFO = 11, + MAX_C2HEVENT +} C2H_EVT; + +typedef _PACKED struct _C2H_EVT_HDR +{ + u8 CmdID; + u8 CmdLen; + u8 CmdSeq; +} C2H_EVT_HDR, *PC2H_EVT_HDR; + +typedef enum tag_Package_Definition +{ + PACKAGE_QFN32, + PACKAGE_QFN48_MCM, + PACKAGE_QFN48, + PACKAGE_QFN68, +}PACKAGE_TYPE_E; + +typedef enum tag_ChipID_Definition +{ + CHIPID_8710BN = 0xFF, /* PACKAGE_QFN32 */ + CHIPID_8710BU = 0xFE, /* PACKAGE_QFN48_MCM */ + CHIPID_8711BN = 0xFD, /* PACKAGE_QFN48 */ + CHIPID_8711BG = 0xFC, /* PACKAGE_QFN68 */ +}CHIP_TD_E; + + +#define INCLUDE_MULTI_FUNC_BT(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_BT) +#define INCLUDE_MULTI_FUNC_GPS(_Adapter) (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) + +//======================================================== +// TXBD and RXBD definition +//======================================================== +#ifdef CONFIG_MP_INCLUDED // For MP Tx no idle +#define TX_VIQ_DESC_NUM 4 +#define TX_VOQ_DESC_NUM 4 +#define TX_BKQ_DESC_NUM 4 +#define TX_BEQ_DESC_NUM 32 +#else +#define TX_VIQ_DESC_NUM 4 +#define TX_VOQ_DESC_NUM 4 +#define TX_BKQ_DESC_NUM 4 +#define TX_BEQ_DESC_NUM 4 +#endif +#ifdef CONFIG_CONCURRENT_MODE +#define TX_BCNQ_DESC_NUM 4 +#else +#define TX_BCNQ_DESC_NUM 2 +#endif +#define TX_MGQ_DESC_NUM 4 +#define TX_H0Q_DESC_NUM 2 +#define TX_H1Q_DESC_NUM 2 +#define TX_H2Q_DESC_NUM 2 +#define TX_H3Q_DESC_NUM 2 +#define TX_H4Q_DESC_NUM 2 +#define TX_H5Q_DESC_NUM 2 +#define TX_H6Q_DESC_NUM 2 +#define TX_H7Q_DESC_NUM 2 +#define RX_Q_DESC_NUM 4 //16 Reduce rx desc number due to memory limitation + +#define SET_VIQ_DES_NUM (TX_VIQ_DESC_NUM<<16) +#define SET_VOQ_DES_NUM (TX_VOQ_DESC_NUM) +#define SET_RXQ_DES_NUM (RX_Q_DESC_NUM<<16) +#define SET_MGQ_DES_NUM (TX_MGQ_DESC_NUM) +#define SET_BKQ_DES_NUM (TX_BKQ_DESC_NUM<<16) +#define SET_BEQ_DES_NUM (TX_BEQ_DESC_NUM) +#define SET_H1Q_DES_NUM (TX_H1Q_DESC_NUM<<16) +#define SET_H0Q_DES_NUM (TX_H0Q_DESC_NUM) +#define SET_H3Q_DES_NUM (TX_H3Q_DESC_NUM<<16) +#define SET_H2Q_DES_NUM (TX_H2Q_DESC_NUM) +#define SET_H5Q_DES_NUM (TX_H5Q_DESC_NUM<<16) +#define SET_H4Q_DES_NUM (TX_H4Q_DESC_NUM) +#define SET_H7Q_DES_NUM (TX_H7Q_DESC_NUM<<16) +#define SET_H6Q_DES_NUM (TX_H6Q_DESC_NUM) + +#define TX_DESC_MODE 1 + +//0: 2 segment +//1: 4 segment +//2: 8 segment +//#define TX_DESC_MODE 2 + +#define MAX_TXBD_SEQMENT_NUM ((TX_DESC_MODE)? (4*TX_DESC_MODE): 2) +#define TXBD_SEGMENT_SIZE 8 + + + +typedef struct _RXBD_ELEMENT_ { + u32 Dword0; + u32 PhyAddr; +}RXBD_ELEMENT,*PRXBD_ELEMENT; + + +typedef struct _TXBD_ELEMENT_ { + u32 Dword0; + u32 AddrLow; +}TXBD_ELEMENT,*PTXBD_ELEMENT; + +typedef struct _LX_DMA_ELEMENT_ { + u32 QueueTRxBdBase; + u32 HwIndex; + u32 HostIndex; + u32 AvaliableCnt; +}LX_DMA_ELEMENT, *PLX_DMA_ELEMENT; +#if 1 + +typedef enum _LX_DMA_QUEUE_TYPE_{ + VO_QUEUE = 0, + VI_QUEUE = 1, + BE_QUEUE = 2, + BK_QUEUE = 3, + MG_QUEUE = 4, + RX_QUEUE = 5, + H0_QUEUE = 6, + H1_QUEUE = 7, + H2_QUEUE = 8, + H3_QUEUE = 9, + H4_QUEUE = 10, + H5_QUEUE = 11, + H6_QUEUE = 12, + H7_QUEUE = 13, + BCN_QUEUE = 14, + MAX_TX_QUEUE = 15, + ERROR_QUEUE = 16, +}LX_DMA_QUEUE_TYPE, *PLX_DMA_QUEUE_TYPE; + +typedef struct _TX_FREE_QUEUE_ { + _queue FreeQueue; + u32 Qlen; +}TX_FREE_QUEUE, *PTX_FREE_QUEUE; + +typedef struct _LX_DMA_MANAGER_ { + LX_DMA_ELEMENT QueueTRxBd[MAX_TX_QUEUE]; + u32 QueueMaxValue[MAX_TX_QUEUE]; + u32 RxBdSkb[RX_Q_DESC_NUM]; + u32 RxLen; + u32 RemainLen; + u16 RxAggregateNum; + u16 RxExpectTag; + u16 RxSegFlow; + u16 Flagls; + TX_FREE_QUEUE TxFreeQueue[MAX_TX_QUEUE]; + +}LX_DMA_MANAGER, *PLX_DMA_MANAGER; + +#else + +typedef struct _LX_DMA_MANAGER_ { + u32 *pVoqTXBD; + u32 *pViqTXBD; + u32 *pBeqTXBD; + u32 *pBkqTXBD; + u32 *pBcnqTXBD; + u32 *pMgqTXBD; + u32 *pH0qTXBD; + u32 *pH1qTXBD; + u32 *pH2qTXBD; + u32 *pH3qTXBD; + u32 *pH4qTXBD; + u32 *pH5qTXBD; + u32 *pH6qTXBD; + u32 *pH7qTXBD; + u32 *pExViqTXBD; + u32 *pExVoqTXBD; + u32 *pExBeqTXBD; + u32 *pExBkqTXBD; + u32 *pExMgqTXBD; + u32 *pRXBD; +// u4Byte RxAggBufEntry[RX_Q_DESC_NUM]; +// u4Byte RxAggLenEntry[RX_Q_DESC_NUM]; + u32 RxLen; + u32 RemainLen; + u16 ViqTxWritePoint; + u16 ViqTxReadPoint; + u16 VoqTxWritePoint; + u16 VoqTxReadPoint; + u16 BeqTxWritePoint; + u16 BeqTxReadPoint; + u16 BkqTxWritePoint; + u16 BkqTxReadPoint; + u16 RxWritePoint; + u16 RxReadPoint; + u16 RxAggregateNum; + u16 RxExpectTag; + u16 RxSegFlow; + u16 Flagls; +}LX_DMA_MANAGER, *PLX_DMA_MANAGER; +#endif + +// rtl8723a_hal_init.c +s32 rtl8711b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +void rtl8711b_FirmwareSelfReset(PADAPTER padapter); +void rtl8711b_InitializeFirmwareVars(PADAPTER padapter); + +void rtl8711b_InitAntenna_Selection(PADAPTER padapter); +void rtl8711b_DeinitAntenna_Selection(PADAPTER padapter); +void rtl8711b_CheckAntenna_Selection(PADAPTER padapter); +void rtl8711b_init_default_value(PADAPTER padapter); + +s32 rtl8711b_InitLLTTable(PADAPTER padapter); + +s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU); +s32 CardDisableWithoutHWSM(PADAPTER padapter); + +// EFuse +//u8 GetEEPROMSize8711b(PADAPTER padapter); +void Hal_InitPGData(PADAPTER padapter, u8 *PROMContent); +void Hal_EfuseParseIDCode(PADAPTER padapter, u8 *hwinfo); +void Hal_EfuseParseTxPowerInfo_8711B(PADAPTER padapter, u8 *PROMContent, BOOLEAN AutoLoadFail); +void Hal_EfuseParseBTCoexistInfo_8711B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseEEPROMVer_8711B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseChnlPlan_8711B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseCustomerID_8711B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseAntennaDiversity_8711B(PADAPTER padapter, u8 *hwinfo, BOOLEAN AutoLoadFail); +void Hal_EfuseParseXtal_8711B(PADAPTER pAdapter, u8 *hwinfo, u8 AutoLoadFail); +void Hal_EfuseParseThermalMeter_8711B(PADAPTER padapter, u8 *hwinfo, u8 AutoLoadFail); + +#ifdef CONFIG_C2H_PACKET_EN +void C2HPacketHandler_8711B(PADAPTER padapter, u8 *pbuffer, u16 length); +#endif + +u8 rtw_flash_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_flash_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_config_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data, u8 efuse); +u8 rtw_config_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data, u8 efuse); + +void rtl8711b_set_hal_ops(struct hal_ops *pHalFunc); +void lxbus_set_intf_ops(struct _io_ops *pops); +void SetHwReg8711B(PADAPTER padapter, u8 variable, u8 *val); +void GetHwReg8711B(PADAPTER padapter, u8 variable, u8 *val); +u8 SetHalDefVar8711B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +u8 GetHalDefVar8711B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +void SetHalODMVar8711B( PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); +void GetHalODMVar8711B(PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); + +// register +void rtl8711b_InitBeaconParameters(PADAPTER padapter); +void rtl8711b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode); +void _InitBurstPktLen_8711BB(PADAPTER Adapter); +#ifdef CONFIG_WOWLAN +void _8051Reset8711b(PADAPTER padapter); +void Hal_DetectWoWMode(PADAPTER pAdapter); +#endif //CONFIG_WOWLAN + +void rtl8711b_start_thread(_adapter *padapter); +void rtl8711b_stop_thread(_adapter *padapter); + +#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST) +void rtl8711bb_init_checkbthang_workqueue(_adapter * adapter); +void rtl8711bb_free_checkbthang_workqueue(_adapter * adapter); +void rtl8711bb_cancle_checkbthang_workqueue(_adapter * adapter); +void rtl8711bb_hal_check_bt_hang(_adapter * adapter); +#endif + +#ifdef CONFIG_WOWLAN +void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip); +void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr); +#endif + +u32 rtl8710b_wlan_suspend(u32 expected_idle_time, void *param); +u32 rtl8710b_wlan_late_resume(u32 expected_idle_time, void *param); +u32 rtl8710b_wlan_resume(u32 expected_idle_time, void *param); + +#ifdef CONFIG_GPIO_WAKEUP +void HalSetOutPutGPIO(PADAPTER padapter, u8 index, u8 OutPutValue); +#endif + +void CCX_FwC2HTxRpt_8711B(PADAPTER padapter, u8 *pdata, u8 len); +s32 c2h_id_filter_ccx_8711B(u8 *buf); +s32 c2h_handler_8711B(PADAPTER padapter, u8 *pC2hEvent); +u8 MRateToHwRate8723B(u8 rate); +u8 HwRateToMRate8723B(u8 rate); + +#ifdef CONFIG_RF_GAIN_OFFSET +void Hal_ReadRFGainOffset(PADAPTER pAdapter,u8* hwinfo,BOOLEAN AutoLoadFail); +#endif //CONFIG_RF_GAIN_OFFSET + + +//1TODO: Chris +#if 1 + +//============= +// [1] Rx Buffer Descriptor (for PCIE) buffer descriptor architecture +//DWORD 0 +#define SET_RX_BUFFER_DESC_DATA_LENGTH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc,__Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 14, 1, __Value) +#define SET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 15, 1, __Value) +#define SET_RX_BUFFER_DESC_RX_TAG_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 16, 13, __Value) + +#define GET_RX_BUFFER_DESC_OWN_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) +#define GET_RX_BUFFER_DESC_LS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_BUFFER_DESC_FS_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_BUFFER_DESC_RX_TAG_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 13) +#define GET_RX_BUFFER_DESC_TOTAL_LENGTH_92E(__pRxStatusDesc)LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) + + +//DWORD 1 +#define SET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+4, 0, 32, __Value) +#define GET_RX_BUFFER_PHYSICAL_LOW_92E(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+4, 0, 32) + +//DWORD 2 +#define SET_RX_BUFFER_PHYSICAL_HIGH_92E(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc+8, 0, 32, __Value) + + +//=====Tx Desc Buffer content + +// config element for each tx buffer +/* +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) +*/ +#define SET_TXBUFFER_DESC_LEN_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 0, 16, __Valeu) +#define SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8), 31, 1, __Valeu) +#define SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*8)+4, 0, 32, __Valeu) +#define SET_TXBUFFER_DESC_ADD_HIGT_WITH_OFFSET(__pTxDesc, __Offset, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc+(__Offset*16)+8, 0, 32, __Valeu) + +// Dword 0 +#define SET_TX_BUFF_DESC_LEN_0_92E(__pTxDesc, __Valeu) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Valeu) +#define SET_TX_BUFF_DESC_PSB_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_BUFF_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) +// Dword 1 +#define SET_TX_BUFF_DESC_ADDR_LOW_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 32, __Value) +#define GET_TX_DESC_TX_BUFFER_ADDRESS_92E(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc+4, 0,32) + + +// Dword 2 +#define SET_TX_BUFF_DESC_ADDR_HIGH_0_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 32, __Value) +// Dword 3, RESERVED + + +#define SET_TX_DESC_OWN_92E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +#endif + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_ap.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_ap.h new file mode 100644 index 0000000..1a6e5d1 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_ap.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_AP_H_ +#define __RTW_AP_H_ + +//#include + + +#ifdef CONFIG_AP_MODE + +//external function +extern void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta); +extern void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta); + + +void init_mlme_ap_info(_adapter *padapter); +void free_mlme_ap_info(_adapter *padapter); +//void update_BCNTIM(_adapter *padapter); +void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len); +void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index); +void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx); +void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level); +void expire_timeout_chk(_adapter *padapter); +void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta); +int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len); +void rtw_set_macaddr_acl(_adapter *padapter, int mode); +int rtw_acl_add_sta(_adapter *padapter, u8 *addr); +int rtw_acl_remove_sta(_adapter *padapter, u8 *addr); +int rtw_generate_bcn_ie(_adapter *adapter, u8 *ssid, u16 ssid_len, u8 *ie); +#if USE_DEDICATED_BCN_TX +struct xmit_frame *alloc_bcn_xmitframe(_adapter *padapter); +#endif + +#ifdef CONFIG_NATIVEAP_MLME +void associated_clients_update(_adapter *padapter, u8 updated); +void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); +u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); +void sta_info_update(_adapter *padapter, struct sta_info *psta); +void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); +u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, u16 reason); +int rtw_sta_flush(_adapter *padapter); +void start_ap_mode(_adapter *padapter); +void stop_ap_mode(_adapter *padapter); +#endif +#endif //end of CONFIG_AP_MODE + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_byteorder.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_byteorder.h new file mode 100644 index 0000000..2f3b6f6 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_byteorder.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTL871X_BYTEORDER_H_ +#define _RTL871X_BYTEORDER_H_ + +#include + +#if defined (CONFIG_LITTLE_ENDIAN) && defined (CONFIG_BIG_ENDIAN) +#error "Shall be CONFIG_LITTLE_ENDIAN or CONFIG_BIG_ENDIAN, but not both!\n" +#endif + +#if defined (CONFIG_LITTLE_ENDIAN) +#ifndef CONFIG_PLATFORM_MSTAR389 +# include +#endif +#elif defined (CONFIG_BIG_ENDIAN) +# include +#else +# error "Must be LITTLE/BIG Endian Host" +#endif + +#ifdef CONFIG_BIG_ENDIAN +#define _htons(x) (x) +#define _ntohs(x) (x) +#define _htonl(x) (x) +#define _ntohl(x) (x) +#else /* !CONFIG_BIG_ENDIAN */ +u16 _htons(u16 x); +u16 _ntohs(u16 x); +u32 _htonl(u32 x); +u32 _ntohl(u32 x); +#endif /* CONFIG_BIG_ENDIAN */ + + +#endif /* _RTL871X_BYTEORDER_H_ */ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_cmd.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_cmd.h new file mode 100644 index 0000000..79b6ce1 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_cmd.h @@ -0,0 +1,1184 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_CMD_H_ +#define __RTW_CMD_H_ + +#include +#include + +#define C2H_MEM_SZ (16*1024) +//#define CMD_RSP_BUF 0 +//#define CMD_DBG 0 + +#ifndef CONFIG_RTL8711FW + + #include // + #include // + + #define FREE_CMDOBJ_SZ 128 + + #define MAX_CMDSZ 1024 + #define MAX_RSPSZ 512 + #define MAX_EVTSZ 1024 + +#if defined(PLATFORM_OS_CE) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + #define CMDBUFF_ALIGN_SZ 4 +#else + #define CMDBUFF_ALIGN_SZ 512 +#endif + + struct cmd_obj { + _adapter *padapter; + u16 cmdcode; + u8 res; + u8 *parmbuf; + u32 cmdsz; + u8 *rsp; + u32 rspsz; + //_sema cmd_sem; + _list list; + }; + + struct cmd_priv { + //_sema cmd_done_sema; + _queue cmd_queue; +#ifdef CMD_BUF + u8 *cmd_buf; //shall be non-paged, and 4 bytes aligned + u8 *cmd_allocated_buf; +#endif +#ifdef CMD_RSP_BUF + u8 *rsp_buf; //shall be non-paged, and 4 bytes aligned + u8 *rsp_allocated_buf; + u32 rsp_cnt; +#endif +#ifdef CMD_DBG + u8 cmd_seq; + u32 cmd_issued_cnt; + u32 cmd_done_cnt; +#endif + u8 cmdthd_running; + _adapter *padapter; + }; + +#ifdef CONFIG_EVENT_THREAD_MODE + struct evt_obj { + u16 evtcode; + u8 res; + u8 *parmbuf; + u32 evtsz; + _list list; + }; +#endif + + struct evt_priv { +#ifdef CONFIG_EVENT_THREAD_MODE + _sema evt_notify; + _sema terminate_evtthread_sema; + _queue evt_queue; +#endif + +#ifdef CONFIG_H2CLBK + _sema lbkevt_done; + u8 lbkevt_limit; + u8 lbkevt_num; + u8 *cmdevt_parm; +#endif + ATOMIC_T event_seq; + u8 *evt_buf; //shall be non-paged, and 4 bytes aligned + u8 *evt_allocated_buf; + u32 evt_done_cnt; +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 *c2h_mem; + u8 *allocated_c2h_mem; +#ifdef PLATFORM_OS_XP + PMDL pc2h_mdl; +#endif +#endif + + }; + +#define init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code) \ +do {\ + rtw_init_listhead(&pcmd->list);\ + pcmd->cmdcode = code;\ + pcmd->parmbuf = (u8 *)(pparm);\ + pcmd->cmdsz = sizeof (*pparm);\ + pcmd->rsp = NULL;\ + pcmd->rspsz = 0;\ +} while(0) + +extern u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj); +extern struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv); +extern void rtw_free_cmd_obj(struct cmd_obj *pcmd); + +#ifdef CONFIG_EVENT_THREAD_MODE +extern u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj); +extern struct evt_obj *rtw_dequeue_evt(_queue *queue); +extern void rtw_free_evt_obj(struct evt_obj *pcmd); +#endif + +thread_return rtw_cmd_thread(thread_context context); + +extern u32 rtw_init_cmd_priv (struct cmd_priv *pcmdpriv); +extern void rtw_free_cmd_priv (struct cmd_priv *pcmdpriv); + +extern u32 rtw_init_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_free_evt_priv (struct evt_priv *pevtpriv); +extern void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv); +extern void rtw_evt_notify_isr(struct evt_priv *pevtpriv); +#ifdef CONFIG_P2P +u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType ); +#endif //CONFIG_P2P + +#else /* CONFIG_RTL8711FW */ + #include +#endif /* CONFIG_RTL8711FW */ + +enum rtw_drvextra_cmd_id +{ + NONE_WK_CID, + DYNAMIC_CHK_WK_CID, + DM_CTRL_WK_CID, + PBC_POLLING_WK_CID, + POWER_SAVING_CTRL_WK_CID,//IPS,AUTOSuspend + LPS_CTRL_WK_CID, + ANT_SELECT_WK_CID, + P2P_PS_WK_CID, + //P2P_PROTO_WK_CID, + CHECK_HIQ_WK_CID,//for softap mode, check hi queue if empty + INTEl_WIDI_WK_CID, + C2H_WK_CID, + RTP_TIMER_CFG_WK_CID, + MAX_WK_CID +}; + +enum LPS_CTRL_TYPE +{ + LPS_CTRL_SCAN=0, + LPS_CTRL_JOINBSS=1, + LPS_CTRL_CONNECT=2, + LPS_CTRL_DISCONNECT=3, + LPS_CTRL_SPECIAL_PACKET=4, + LPS_CTRL_LEAVE=5, +}; + +enum RFINTFS { + SWSI, + HWSI, + HWPI, +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To enter USB suspend mode + +Command Mode + +*/ +struct usb_suspend_parm { + u32 action;// 1: sleep, 0:resume +}; + +/* +Caller Mode: Infra, Ad-HoC + +Notes: To join a known BSS. + +Command-Event Mode + +*/ + +/* +Caller Mode: Infra, Ad-Hoc + +Notes: To join the specified bss + +Command Event Mode + +*/ +struct joinbss_parm { + WLAN_BSSID_EX network; +}; + +/* +Caller Mode: Infra, Ad-HoC(C) + +Notes: To disconnect the current associated BSS + +Command Mode + +*/ +struct disconnect_parm { + u32 rsvd; +}; + +/* +Caller Mode: AP, Ad-HoC(M) + +Notes: To create a BSS + +Command Mode +*/ +struct createbss_parm { + WLAN_BSSID_EX network; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To set the NIC mode of RTL8711 + +Command Mode + +The definition of mode: + +#define IW_MODE_AUTO 0 // Let the driver decides which AP to join +#define IW_MODE_ADHOC 1 // Single cell network (Ad-Hoc Clients) +#define IW_MODE_INFRA 2 // Multi cell network, roaming, .. +#define IW_MODE_MASTER 3 // Synchronisation master or Access Point +#define IW_MODE_REPEAT 4 // Wireless Repeater (forwarder) +#define IW_MODE_SECOND 5 // Secondary master/repeater (backup) +#define IW_MODE_MONITOR 6 // Passive monitor (listen only) + +*/ +struct setopmode_parm { + u8 mode; + u8 rsvd[3]; +}; + +/* +Caller Mode: AP, Ad-HoC, Infra + +Notes: To ask RTL8711 performing site-survey + +Command-Event Mode + +*/ + +#if defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#define RTW_SSID_SCAN_AMOUNT 1 //Reduce ssid scan amount due to memory limitation - Alex Fang +#else +#define RTW_SSID_SCAN_AMOUNT 9 // for WEXT_CSCAN_AMOUNT 9 +#endif + +struct sitesurvey_parm { + sint scan_mode; //active: 1, passive: 0 + sint bsslimit; // 1 ~ 48 + // for up to 9 probreq with specific ssid + NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT]; +}; + +/* +Caller Mode: Any + +Notes: To set the auth type of RTL8711. open/shared/802.1x + +Command Mode + +*/ +struct setauth_parm { + u8 mode; //0: legacy open, 1: legacy shared 2: 802.1x + u8 _1x; //0: PSK, 1: TLS + u8 rsvd[2]; +}; + +/* +Caller Mode: Infra + +a. algorithm: wep40, wep104, tkip & aes +b. keytype: grp key/unicast key +c. key contents + +when shared key ==> keyid is the camid +when 802.1x ==> keyid [0:1] ==> grp key +when 802.1x ==> keyid > 2 ==> unicast key + +*/ +struct setkey_parm { + u8 algorithm; // encryption algorithm, could be none, wep40, TKIP, CCMP, wep104 + u8 keyid; + u8 grpkey; // 1: this is the grpkey for 802.1x. 0: this is the unicast key for 802.1x + u8 set_tx; // 1: main tx key for wep. 0: other key. + u8 key[16]; // this could be 40 or 104 +}; + +/* +When in AP or Ad-Hoc mode, this is used to +allocate an sw/hw entry for a newly associated sta. + +Command + +when shared key ==> algorithm/keyid + +*/ +struct set_stakey_parm { + u8 addr[ETH_ALEN]; + u8 algorithm; + u8 id;// currently for erasing cam entry if algorithm == _NO_PRIVACY_ + u8 key[16]; +}; + +struct set_stakey_rsp { + u8 addr[ETH_ALEN]; + u8 keyid; + u8 rsvd; +}; + +/* +Caller Ad-Hoc/AP + +Command -Rsp(AID == CAMID) mode + +This is to force fw to add an sta_data entry per driver's request. + +FW will write an cam entry associated with it. + +*/ +struct set_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +struct set_assocsta_rsp { + u8 cam_id; + u8 rsvd[3]; +}; + +/* + Caller Ad-Hoc/AP + + Command mode + + This is to force fw to del an sta_data entry per driver's request + + FW will invalidate the cam entry associated with it. + +*/ +struct del_assocsta_parm { + u8 addr[ETH_ALEN]; +}; + +/* +Caller Mode: AP/Ad-HoC(M) + +Notes: To notify fw that given staid has changed its power state + +Command Mode + +*/ +struct setstapwrstate_parm { + u8 staid; + u8 status; + u8 hwaddr[6]; +}; + +/* +Caller Mode: Any + +Notes: To setup the basic rate of RTL8711 + +Command Mode + +*/ +struct setbasicrate_parm { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To read the current basic rate + +Command-Rsp Mode + +*/ +struct getbasicrate_parm { + u32 rsvd; +}; + +struct getbasicrate_rsp { + u8 basicrates[NumRates]; +}; + +/* +Caller Mode: Any + +Notes: To setup the data rate of RTL8711 + +Command Mode + +*/ +struct setdatarate_parm { +#ifdef MP_FIRMWARE_OFFLOAD + u32 curr_rateidx; +#else + u8 mac_id; + u8 datarates[NumRates]; +#endif +}; + +/* +Caller Mode: Any + +Notes: To read the current data rate + +Command-Rsp Mode + +*/ +struct getdatarate_parm { + u32 rsvd; + +}; +struct getdatarate_rsp { + u8 datarates[NumRates]; +}; + + +/* +Caller Mode: Any +AP: AP can use the info for the contents of beacon frame +Infra: STA can use the info when sitesurveying +Ad-HoC(M): Like AP +Ad-HoC(C): Like STA + + +Notes: To set the phy capability of the NIC + +Command Mode + +*/ + +struct setphyinfo_parm { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +struct getphyinfo_parm { + u32 rsvd; +}; + +struct getphyinfo_rsp { + struct regulatory_class class_sets[NUM_REGULATORYS]; + u8 status; +}; + +/* +Caller Mode: Any + +Notes: To set the channel/modem/band +This command will be used when channel/modem/band is changed. + +Command Mode + +*/ +struct setphy_parm { + u8 rfchannel; + u8 modem; +}; + +/* +Caller Mode: Any + +Notes: To get the current setting of channel/modem/band + +Command-Rsp Mode + +*/ +struct getphy_parm { + u32 rsvd; + +}; +struct getphy_rsp { + u8 rfchannel; + u8 modem; +}; + +struct readBB_parm { + u8 offset; +}; +struct readBB_rsp { + u8 value; +}; + +struct readTSSI_parm { + u8 offset; +}; +struct readTSSI_rsp { + u8 value; +}; + +struct writeBB_parm { + u8 offset; + u8 value; +}; + +struct readRF_parm { + u8 offset; +}; +struct readRF_rsp { + u32 value; +}; + +struct writeRF_parm { + u32 offset; + u32 value; +}; + +struct getrfintfs_parm { + u8 rfintfs; +}; + + +struct Tx_Beacon_param +{ + WLAN_BSSID_EX network; +}; + +/* + Notes: This command is used for H2C/C2H loopback testing + + mac[0] == 0 + ==> CMD mode, return H2C_SUCCESS. + The following condition must be ture under CMD mode + mac[1] == mac[4], mac[2] == mac[3], mac[0]=mac[5]= 0; + s0 == 0x1234, s1 == 0xabcd, w0 == 0x78563412, w1 == 0x5aa5def7; + s2 == (b1 << 8 | b0); + + mac[0] == 1 + ==> CMD_RSP mode, return H2C_SUCCESS_RSP + + The rsp layout shall be: + rsp: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = mac[3]; + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = s1; + s1 = swap16(s0); + w0 = swap32(w1); + b0 = b1 + s2 = s0 + s1 + b1 = b0 + w1 = w0 + + mac[0] == 2 + ==> CMD_EVENT mode, return H2C_SUCCESS + The event layout shall be: + event: parm: + mac[0] = mac[5]; + mac[1] = mac[4]; + mac[2] = event's sequence number, starting from 1 to parm's marc[3] + mac[3] = mac[2]; + mac[4] = mac[1]; + mac[5] = mac[0]; + s0 = swap16(s0) - event.mac[2]; + s1 = s1 + event.mac[2]; + w0 = swap32(w0); + b0 = b1 + s2 = s0 + event.mac[2] + b1 = b0 + w1 = swap32(w1) - event.mac[2]; + + parm->mac[3] is the total event counts that host requested. + + + event will be the same with the cmd's param. + +*/ + +#ifdef CONFIG_H2CLBK + +struct seth2clbk_parm { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +struct geth2clbk_parm { + u32 rsv; +}; + +struct geth2clbk_rsp { + u8 mac[6]; + u16 s0; + u16 s1; + u32 w0; + u8 b0; + u16 s2; + u8 b1; + u32 w1; +}; + +#endif /* CONFIG_H2CLBK */ + +// CMD param Formart for driver extra cmd handler +struct drvextra_cmd_parm { + int ec_id; //extra cmd id + int type_size; // Can use this field as the type id or command size + unsigned char *pbuf; +}; + +#ifdef CONFIG_P2P_NEW +// CMD param Formart for p2p cmd handler +struct p2p_cmd_parm { + int id; //p2p cmd id + int type_size; // Can use this field as the type id or command size + unsigned char *pbuf; +}; +#endif +/*------------------- Below are used for RF/BB tunning ---------------------*/ + +struct setantenna_parm { + u8 tx_antset; + u8 rx_antset; + u8 tx_antenna; + u8 rx_antenna; +}; + +struct enrateadaptive_parm { + u32 en; +}; + +struct settxagctbl_parm { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct gettxagctbl_parm { + u32 rsvd; +}; +struct gettxagctbl_rsp { + u32 txagc[MAX_RATES_LENGTH]; +}; + +struct setagcctrl_parm { + u32 agcctrl; // 0: pure hw, 1: fw +}; + + +struct setssup_parm { + u32 ss_ForceUp[MAX_RATES_LENGTH]; +}; + +struct getssup_parm { + u32 rsvd; +}; +struct getssup_rsp { + u8 ss_ForceUp[MAX_RATES_LENGTH]; +}; + + +struct setssdlevel_parm { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct getssdlevel_parm { + u32 rsvd; +}; +struct getssdlevel_rsp { + u8 ss_DLevel[MAX_RATES_LENGTH]; +}; + +struct setssulevel_parm { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + +struct getssulevel_parm { + u32 rsvd; +}; +struct getssulevel_rsp { + u8 ss_ULevel[MAX_RATES_LENGTH]; +}; + + +struct setcountjudge_parm { + u8 count_judge[MAX_RATES_LENGTH]; +}; + +struct getcountjudge_parm { + u32 rsvd; +}; +struct getcountjudge_rsp { + u8 count_judge[MAX_RATES_LENGTH]; +}; + + +struct setratable_parm { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + +struct getratable_parm { + uint rsvd; +}; +struct getratable_rsp { + u8 ss_ForceUp[NumRates]; + u8 ss_ULevel[NumRates]; + u8 ss_DLevel[NumRates]; + u8 count_judge[NumRates]; +}; + + +//to get TX,RX retry count +struct gettxretrycnt_parm{ + unsigned int rsvd; +}; +struct gettxretrycnt_rsp{ + unsigned long tx_retrycnt; +}; + +struct getrxretrycnt_parm{ + unsigned int rsvd; +}; +struct getrxretrycnt_rsp{ + unsigned long rx_retrycnt; +}; + +//to get BCNOK,BCNERR count +struct getbcnokcnt_parm{ + unsigned int rsvd; +}; +struct getbcnokcnt_rsp{ + unsigned long bcnokcnt; +}; + +struct getbcnerrcnt_parm{ + unsigned int rsvd; +}; +struct getbcnerrcnt_rsp{ + unsigned long bcnerrcnt; +}; + +// to get current TX power level +struct getcurtxpwrlevel_parm{ + unsigned int rsvd; +}; +struct getcurtxpwrlevel_rsp{ + unsigned short tx_power; +}; + +///TODO +#if 0 + +struct setprobereqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocreqextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setproberspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +struct setassocrspextraie_parm { + unsigned char e_id; + unsigned char ie_len; + unsigned char ie[0]; +}; + +#endif //#if 0 + +struct addBaReq_parm +{ + unsigned int tid; + u8 addr[ETH_ALEN]; +}; + +/*H2C Handler index: 46 */ +struct SetChannel_parm +{ + u32 curr_ch; +}; + +#ifdef MP_FIRMWARE_OFFLOAD +/*H2C Handler index: 47 */ +struct SetTxPower_parm +{ + u8 TxPower; +}; + +/*H2C Handler index: 48 */ +struct SwitchAntenna_parm +{ + u16 antenna_tx; + u16 antenna_rx; +// R_ANTENNA_SELECT_CCK cck_txrx; + u8 cck_txrx; +}; + +/*H2C Handler index: 49 */ +struct SetCrystalCap_parm +{ + u32 curr_crystalcap; +}; + +/*H2C Handler index: 50 */ +struct SetSingleCarrierTx_parm +{ + u8 bStart; +}; + +/*H2C Handler index: 51 */ +struct SetSingleToneTx_parm +{ + u8 bStart; + u8 curr_rfpath; +}; + +/*H2C Handler index: 52 */ +struct SetCarrierSuppressionTx_parm +{ + u8 bStart; + u32 curr_rateidx; +}; + +/*H2C Handler index: 53 */ +struct SetContinuousTx_parm +{ + u8 bStart; + u8 CCK_flag; /*1:CCK 2:OFDM*/ + u32 curr_rateidx; +}; + +/*H2C Handler index: 54 */ +struct SwitchBandwidth_parm +{ + u8 curr_bandwidth; +}; + +#endif /* MP_FIRMWARE_OFFLOAD */ + +/*H2C Handler index: 59 */ +struct SetChannelPlan_param +{ + u8 channel_plan; +}; + +//TODO +#if 0 +/*H2C Handler index: 60 */ +struct LedBlink_param +{ + PLED_871x pLed; +}; +#endif //#if 0 + +/*H2C Handler index: 61 */ +struct SetChannelSwitch_param +{ + u8 new_ch_no; +}; + +/*H2C Handler index: 62 */ +struct TDLSoption_param +{ + u8 addr[ETH_ALEN]; + u8 option; +}; + +#define GEN_CMD_CODE(cmd) cmd ## _CMD_ + + +/* + +Result: +0x00: success +0x01: sucess, and check Response. +0x02: cmd ignored due to duplicated sequcne number +0x03: cmd dropped due to invalid cmd code +0x04: reserved. + +*/ + +#define H2C_RSP_OFFSET 512 + +#define H2C_SUCCESS 0x00 +#define H2C_SUCCESS_RSP 0x01 +#define H2C_DUPLICATED 0x02 +#define H2C_DROPPED 0x03 +#define H2C_PARAMETERS_ERROR 0x04 +#define H2C_REJECTED 0x05 +#define H2C_CMD_OVERFLOW 0x06 +#define H2C_RESERVED 0x07 + +extern u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr); +extern u8 rtw_setstandby_cmd(_adapter *padapter, uint action); +extern u8 rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +extern u8 rtw_createbss_cmd(_adapter *padapter); +extern u8 rtw_createbss_cmd_ex(_adapter *padapter, unsigned char *pbss, unsigned int sz); +extern u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch); +extern u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key); +extern u8 rtw_clearstakey_cmd(_adapter *padapter, u8 *psta, u8 entry, u8 enqueue); +extern u8 rtw_joinbss_cmd(_adapter *padapter, struct wlan_network* pnetwork); +extern u8 rtw_disassoc_cmd(_adapter *padapter); +extern u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +extern u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset); +extern u8 rtw_setbbreg_cmd(_adapter * padapter, u8 offset, u8 val); +extern u8 rtw_setrfreg_cmd(_adapter * padapter, u8 offset, u32 val); +extern u8 rtw_getbbreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_getrfreg_cmd(_adapter * padapter, u8 offset, u8 * pval); +extern u8 rtw_setrfintfs_cmd(_adapter *padapter, u8 mode); +extern u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table); +extern u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval); + +extern u8 rtw_gettssi_cmd(_adapter *padapter, u8 offset,u8 *pval); +extern u8 rtw_setfwdig_cmd(_adapter*padapter, u8 type); +extern u8 rtw_setfwra_cmd(_adapter*padapter, u8 type); + +extern u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr); + +extern u8 rtw_dynamic_chk_wk_cmd(_adapter *adapter); +#ifdef CONFIG_P2P_NEW +u8 rtw_p2p_cmd(_adapter*padapter, int subid); +#endif +u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue); +#if (RATE_ADAPTIVE_SUPPORT==1) +u8 rtw_rpt_timer_cfg_cmd(_adapter*padapter, u16 minRptTime); +#endif + +#ifdef CONFIG_ANTENNA_DIVERSITY +extern u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue); +#endif + +extern u8 rtw_ps_cmd(_adapter*padapter); + +#ifdef CONFIG_AP_MODE +u8 rtw_chk_hi_queue_cmd(_adapter*padapter); +#endif + +extern u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enaueue); +//TODO +//extern u8 rtw_led_blink_cmd(_adapter*padapter, PLED_871x pLed); +extern u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no); +extern u8 rtw_tdls_cmd(_adapter*padapter, u8 *addr, u8 option); + +extern u8 rtw_c2h_wk_cmd(PADAPTER padapter); + +u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf); +#ifdef CONFIG_P2P_NEW +u8 rtw_p2p_cmd_hdl(_adapter *padapter, unsigned char *pbuf); +#endif +extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_createbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getbbrfreg_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); + +extern void rtw_setstaKey_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_setassocsta_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_getrttbl_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_set_channel_plan_cmd_callback(_adapter* padapter, struct cmd_obj *pcmd); + + +struct _cmd_callback { + u32 cmd_code; + void (*callback)(_adapter *padapter, struct cmd_obj *cmd); +}; + +enum rtw_h2c_cmd +{ + GEN_CMD_CODE(_Read_MACREG) , /*0*/ + GEN_CMD_CODE(_Write_MACREG) , + GEN_CMD_CODE(_Read_BBREG) , + GEN_CMD_CODE(_Write_BBREG) , + GEN_CMD_CODE(_Read_RFREG) , + GEN_CMD_CODE(_Write_RFREG) , /*5*/ + GEN_CMD_CODE(_Read_EEPROM) , + GEN_CMD_CODE(_Write_EEPROM) , + GEN_CMD_CODE(_Read_EFUSE) , + GEN_CMD_CODE(_Write_EFUSE) , + + GEN_CMD_CODE(_Read_CAM) , /*10*/ + GEN_CMD_CODE(_Write_CAM) , + GEN_CMD_CODE(_setBCNITV), + GEN_CMD_CODE(_setMBIDCFG), + GEN_CMD_CODE(_JoinBss), /*14*/ + GEN_CMD_CODE(_DisConnect) , /*15*/ + GEN_CMD_CODE(_CreateBss) , + GEN_CMD_CODE(_SetOpMode) , + GEN_CMD_CODE(_SiteSurvey), /*18*/ + GEN_CMD_CODE(_SetAuth) , + + GEN_CMD_CODE(_SetKey) , /*20*/ + GEN_CMD_CODE(_SetStaKey) , + GEN_CMD_CODE(_SetAssocSta) , + GEN_CMD_CODE(_DelAssocSta) , + GEN_CMD_CODE(_SetStaPwrState) , + GEN_CMD_CODE(_SetBasicRate) , /*25*/ + GEN_CMD_CODE(_GetBasicRate) , + GEN_CMD_CODE(_SetDataRate) , + GEN_CMD_CODE(_GetDataRate) , + GEN_CMD_CODE(_SetPhyInfo) , + + GEN_CMD_CODE(_GetPhyInfo) , /*30*/ + GEN_CMD_CODE(_SetPhy) , + GEN_CMD_CODE(_GetPhy) , + GEN_CMD_CODE(_readRssi) , + GEN_CMD_CODE(_readGain) , + GEN_CMD_CODE(_SetAtim) , /*35*/ + GEN_CMD_CODE(_SetPwrMode) , + GEN_CMD_CODE(_JoinbssRpt), + GEN_CMD_CODE(_SetRaTable) , + GEN_CMD_CODE(_GetRaTable) , + + GEN_CMD_CODE(_GetCCXReport), /*40*/ + GEN_CMD_CODE(_GetDTMReport), + GEN_CMD_CODE(_GetTXRateStatistics), + GEN_CMD_CODE(_SetUsbSuspend), + GEN_CMD_CODE(_SetH2cLbk), + GEN_CMD_CODE(_AddBAReq) , /*45*/ + GEN_CMD_CODE(_SetChannel), /*46*/ + GEN_CMD_CODE(_SetTxPower), + GEN_CMD_CODE(_SwitchAntenna), + GEN_CMD_CODE(_SetCrystalCap), + GEN_CMD_CODE(_SetSingleCarrierTx), /*50*/ + + GEN_CMD_CODE(_SetSingleToneTx),/*51*/ + GEN_CMD_CODE(_SetCarrierSuppressionTx), + GEN_CMD_CODE(_SetContinuousTx), + GEN_CMD_CODE(_SwitchBandwidth), /*54*/ + GEN_CMD_CODE(_TX_Beacon), /*55*/ + + GEN_CMD_CODE(_Set_MLME_EVT), /*56*/ + GEN_CMD_CODE(_Set_Drv_Extra), /*57*/ + GEN_CMD_CODE(_Set_H2C_MSG), /*58*/ + + GEN_CMD_CODE(_SetChannelPlan), /*59*/ + GEN_CMD_CODE(_LedBlink), /*60*/ + + GEN_CMD_CODE(_SetChannelSwitch), /*61*/ + GEN_CMD_CODE(_TDLS), /*62*/ + GEN_CMD_CODE(_P2P), /*63*/ + + MAX_H2CCMD +}; + +#define _GetBBReg_CMD_ _Read_BBREG_CMD_ +#define _SetBBReg_CMD_ _Write_BBREG_CMD_ +#define _GetRFReg_CMD_ _Read_RFREG_CMD_ +#define _SetRFReg_CMD_ _Write_RFREG_CMD_ + +#ifdef _RTW_CMD_C_ +const struct _cmd_callback rtw_cmd_callback[] = +{ + {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ + {GEN_CMD_CODE(_Write_MACREG), NULL}, +//TODO +// {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Read_BBREG), NULL}, + {GEN_CMD_CODE(_Write_BBREG), NULL}, +//TODO +// {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, + {GEN_CMD_CODE(_Read_RFREG), NULL}, + {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ + {GEN_CMD_CODE(_Read_EEPROM), NULL}, + {GEN_CMD_CODE(_Write_EEPROM), NULL}, + {GEN_CMD_CODE(_Read_EFUSE), NULL}, + {GEN_CMD_CODE(_Write_EFUSE), NULL}, + + {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ + {GEN_CMD_CODE(_Write_CAM), NULL}, + {GEN_CMD_CODE(_setBCNITV), NULL}, + {GEN_CMD_CODE(_setMBIDCFG), NULL}, + {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ + {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ +//TODO +// {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, + {GEN_CMD_CODE(_CreateBss), NULL}, + {GEN_CMD_CODE(_SetOpMode), NULL}, + {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ + {GEN_CMD_CODE(_SetAuth), NULL}, + + {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ + {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, +//TODO +// {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, + {GEN_CMD_CODE(_SetAssocSta), NULL}, + {GEN_CMD_CODE(_DelAssocSta), NULL}, + {GEN_CMD_CODE(_SetStaPwrState), NULL}, + {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ + {GEN_CMD_CODE(_GetBasicRate), NULL}, + {GEN_CMD_CODE(_SetDataRate), NULL}, + {GEN_CMD_CODE(_GetDataRate), NULL}, + {GEN_CMD_CODE(_SetPhyInfo), NULL}, + + {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ + {GEN_CMD_CODE(_SetPhy), NULL}, + {GEN_CMD_CODE(_GetPhy), NULL}, + {GEN_CMD_CODE(_readRssi), NULL}, + {GEN_CMD_CODE(_readGain), NULL}, + {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ + {GEN_CMD_CODE(_SetPwrMode), NULL}, + {GEN_CMD_CODE(_JoinbssRpt), NULL}, + {GEN_CMD_CODE(_SetRaTable), NULL}, + {GEN_CMD_CODE(_GetRaTable) , NULL}, + + {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ + {GEN_CMD_CODE(_GetDTMReport), NULL}, + {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, + {GEN_CMD_CODE(_SetUsbSuspend), NULL}, + {GEN_CMD_CODE(_SetH2cLbk), NULL}, + {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ + {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ + {GEN_CMD_CODE(_SetTxPower), NULL}, + {GEN_CMD_CODE(_SwitchAntenna), NULL}, + {GEN_CMD_CODE(_SetCrystalCap), NULL}, + {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ + + {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ + {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, + {GEN_CMD_CODE(_SetContinuousTx), NULL}, + {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ + {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ + + {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ + {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ + {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ + {GEN_CMD_CODE(_SetChannelPlan), rtw_set_channel_plan_cmd_callback},/*59*/ + {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ + + {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ + {GEN_CMD_CODE(_TDLS), NULL},/*62*/ +#ifdef CONFIG_P2P_NEW + {GEN_CMD_CODE(_P2P), NULL},/*63*/ +#endif +}; +#endif + +#endif // _CMD_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_debug.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_debug.h new file mode 100644 index 0000000..a7d7b7d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_debug.h @@ -0,0 +1,456 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_DEBUG_H__ +#define __RTW_DEBUG_H__ + + +#define _drv_always_ 1 +#define _drv_emerg_ 2 +#define _drv_alert_ 3 +#define _drv_crit_ 4 +#define _drv_err_ 5 +#define _drv_warning_ 6 +#define _drv_notice_ 7 +#define _drv_info_ 8 +#define _drv_dump_ 9 +#define _drv_debug_ 10 + + +#define _module_rtl871x_xmit_c_ BIT(0) +#define _module_xmit_osdep_c_ BIT(1) +#define _module_rtl871x_recv_c_ BIT(2) +#define _module_recv_osdep_c_ BIT(3) +#define _module_rtl871x_mlme_c_ BIT(4) +#define _module_mlme_osdep_c_ BIT(5) +#define _module_rtl871x_sta_mgt_c_ BIT(6) +#define _module_rtl871x_cmd_c_ BIT(7) +#define _module_cmd_osdep_c_ BIT(8) +#define _module_rtl871x_io_c_ BIT(9) +#define _module_io_osdep_c_ BIT(10) +#define _module_os_intfs_c_ BIT(11) +#define _module_rtl871x_security_c_ BIT(12) +#define _module_rtl871x_eeprom_c_ BIT(13) +#define _module_hal_init_c_ BIT(14) +#define _module_hci_hal_init_c_ BIT(15) +#define _module_rtl871x_ioctl_c_ BIT(16) +#define _module_rtl871x_ioctl_set_c_ BIT(17) +#define _module_rtl871x_ioctl_query_c_ BIT(18) +#define _module_rtl871x_pwrctrl_c_ BIT(19) +#define _module_hci_intfs_c_ BIT(20) +#define _module_hci_ops_c_ BIT(21) +#define _module_osdep_service_c_ BIT(22) +#define _module_mp_ BIT(23) +#define _module_hci_ops_os_c_ BIT(24) +#define _module_rtl871x_ioctl_os_c BIT(25) +#define _module_rtl8712_cmd_c_ BIT(26) +#define _module_fwcmd_c_ BIT(27) +#define _module_rtl8192c_xmit_c_ BIT(28) +#define _module_hal_xmit_c_ BIT(28) +#define _module_efuse_ BIT(29) +#define _module_rtl8712_recv_c_ BIT(30) +#define _module_rtl8712_led_c_ BIT(31) + +#undef _MODULE_DEFINE_ + +#if defined _RTW_XMIT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_xmit_c_ +#elif defined _XMIT_OSDEP_C_ + #define _MODULE_DEFINE_ _module_xmit_osdep_c_ +#elif defined _RTW_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl871x_recv_c_ +#elif defined _RECV_OSDEP_C_ + #define _MODULE_DEFINE_ _module_recv_osdep_c_ +#elif defined _RTW_MLME_C_ + #define _MODULE_DEFINE_ _module_rtl871x_mlme_c_ +#elif defined _MLME_OSDEP_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MLME_EXT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTW_STA_MGT_C_ + #define _MODULE_DEFINE_ _module_rtl871x_sta_mgt_c_ +#elif defined _RTW_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl871x_cmd_c_ +#elif defined _CMD_OSDEP_C_ + #define _MODULE_DEFINE_ _module_cmd_osdep_c_ +#elif defined _RTW_IO_C_ + #define _MODULE_DEFINE_ _module_rtl871x_io_c_ +#elif defined _IO_OSDEP_C_ + #define _MODULE_DEFINE_ _module_io_osdep_c_ +#elif defined _OS_INTFS_C_ + #define _MODULE_DEFINE_ _module_os_intfs_c_ +#elif defined _RTW_SECURITY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_security_c_ +#elif defined _RTW_EEPROM_C_ + #define _MODULE_DEFINE_ _module_rtl871x_eeprom_c_ +#elif defined _HAL_INTF_C_ + #define _MODULE_DEFINE_ _module_hal_init_c_ +#elif (defined _HCI_HAL_INIT_C_) || (defined _SDIO_HALINIT_C_) + #define _MODULE_DEFINE_ _module_hci_hal_init_c_ +#elif defined _RTL871X_IOCTL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_c_ +#elif defined _RTL871X_IOCTL_SET_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_set_c_ +#elif defined _RTL871X_IOCTL_QUERY_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_query_c_ +#elif defined _RTL871X_PWRCTRL_C_ + #define _MODULE_DEFINE_ _module_rtl871x_pwrctrl_c_ +#elif defined _RTW_PWRCTRL_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _HCI_OPS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_c_ +#elif defined _SDIO_OPS_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _OSDEP_HCI_INTF_C_ + #define _MODULE_DEFINE_ _module_hci_intfs_c_ +#elif defined _OSDEP_SERVICE_C_ + #define _MODULE_DEFINE_ _module_osdep_service_c_ +#elif defined _HCI_OPS_OS_C_ + #define _MODULE_DEFINE_ _module_hci_ops_os_c_ +#elif defined _RTL871X_IOCTL_LINUX_C_ + #define _MODULE_DEFINE_ _module_rtl871x_ioctl_os_c +#elif defined _RTL8712_CMD_C_ + #define _MODULE_DEFINE_ _module_rtl8712_cmd_c_ +#elif defined _RTL8192C_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8723AS_XMIT_C_ + #define _MODULE_DEFINE_ 1 +#elif defined _RTL8712_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL8192CU_RECV_C_ + #define _MODULE_DEFINE_ _module_rtl8712_recv_c_ +#elif defined _RTL871X_MLME_EXT_C_ + #define _MODULE_DEFINE_ _module_mlme_osdep_c_ +#elif defined _RTW_MP_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_MP_IOCTL_C_ + #define _MODULE_DEFINE_ _module_mp_ +#elif defined _RTW_EFUSE_C_ + #define _MODULE_DEFINE_ _module_efuse_ +#endif + +#ifdef PLATFORM_OS_CE +extern void rtl871x_cedbg(const char *fmt, ...); +#endif + +#define RT_TRACE(_Comp, _Level, Fmt) do{}while(0) +#define _func_enter_ do{}while(0) +#define _func_exit_ do{}while(0) +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) do{}while(0) + +#ifdef PLATFORM_WINDOWS + #define DBG_871X do {} while(0) + #define MSG_8192C do {} while(0) + #define DBG_8192C do {} while(0) + #define DBG_871X_LEVEL do {} while(0) +#else + #define DBG_871X(x, ...) do {} while(0) + #define MSG_8192C(x, ...) do {} while(0) + #define DBG_8192C(x,...) do {} while(0) + #define DBG_871X_LEVEL(x,...) do {} while(0) +#endif + +#undef _dbgdump +#ifdef PLATFORM_WINDOWS + + #ifdef PLATFORM_OS_XP + #define _dbgdump DbgPrint + #elif defined PLATFORM_OS_CE + #define _dbgdump rtl871x_cedbg + #endif + +#elif defined PLATFORM_LINUX + #define _dbgdump printk +#elif defined PLATFORM_ECOS + #define _dbgdump diag_printf +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + #define _dbgdump printf("\n\r"); printf +#elif defined PLATFORM_FREEBSD + #define _dbgdump printf +#endif + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#define DRIVER_PREFIX "RTL871X: " +#endif + +#define DEBUG_LEVEL (_drv_err_) +#if defined (_dbgdump) + #undef DBG_871X_LEVEL +#if defined (__ICCARM__) || defined (__CC_ARM) ||defined(__GNUC__)|| defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + #define DBG_871X_LEVEL(level, ...) \ + do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) +#else + #define DBG_871X_LEVEL(level, fmt, arg...) \ + do {\ + if (level <= DEBUG_LEVEL) {\ + if (level <= _drv_err_ && level > _drv_always_) {\ + _dbgdump(DRIVER_PREFIX"ERROR " fmt, ##arg);\ + } \ + else {\ + _dbgdump(DRIVER_PREFIX fmt, ##arg);\ + } \ + }\ + }while(0) +#endif //#ifdef __CC_ARM +#endif + +#ifdef CONFIG_DEBUG +#if defined (_dbgdump) + #undef DBG_871X + #define DBG_871X(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) + + #undef MSG_8192C + #define MSG_8192C(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) + + #undef DBG_8192C + #define DBG_8192C(...) do {\ + _dbgdump(DRIVER_PREFIX __VA_ARGS__);\ + }while(0) +#endif +#endif /* CONFIG_DEBUG */ + +#ifdef CONFIG_DEBUG_RTL871X +#ifndef _RTL871X_DEBUG_C_ + extern u32 GlobalDebugLevel; + extern u64 GlobalDebugComponents; +#endif + +#if defined (_dbgdump) && defined (_MODULE_DEFINE_) + + #undef RT_TRACE + #define RT_TRACE(_Comp, _Level, Fmt)\ + do {\ + if((_Comp & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) {\ + _dbgdump("%s [0x%08x,%d]", DRIVER_PREFIX, (unsigned int)_Comp, _Level);\ + _dbgdump Fmt;\ + }\ + }while(0) + +#endif + + +#if defined (_dbgdump) + + #undef _func_enter_ + #define _func_enter_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s enters at %d\n", DRIVER_PREFIX, __FUNCTION__, __LINE__);\ + } \ + } while(0) + + #undef _func_exit_ + #define _func_exit_ \ + do { \ + if (GlobalDebugLevel >= _drv_debug_) \ + { \ + _dbgdump("\n %s : %s exits at %d\n", DRIVER_PREFIX, __FUNCTION__, __LINE__); \ + } \ + } while(0) + + #undef RT_PRINT_DATA + #define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \ + if(((_Comp) & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) \ + { \ + int __i; \ + u8 *ptr = (u8 *)_HexData; \ + printf("\r\n%s", DRIVER_PREFIX); \ + printf(_TitleString "--------Len=%d\n\r", _HexDataLen); \ + for( __i=0; __i<(int)_HexDataLen; __i++ ) \ + { \ + printf("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \ + if (((__i + 1) % 16) == 0) printf("\n\r"); \ + } \ + printf("\n\r"); \ + } +#endif +#endif /* CONFIG_DEBUG_RTL871X */ + + +#ifdef CONFIG_PROC_DEBUG + + int proc_get_drv_version(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_write_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_write_reg(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_read_reg(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_read_reg(struct file *file, const char *buffer, + unsigned long count, void *data); + + + int proc_get_fwstate(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_sec_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mlmext_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_qos_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_ht_option(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_ap_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_adapter_state(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_trx_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_mac_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_bb_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump1(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump2(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump3(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rf_reg_dump4(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + +#ifdef CONFIG_AP_MODE + + int proc_get_all_sta_info(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + +#endif + +#ifdef DBG_MEMORY_LEAK + int proc_get_malloc_cnt(char *page, char **start, + off_t offset, int count, + int *eof, void *data); +#endif + +#ifdef CONFIG_FIND_BEST_CHANNEL + int proc_get_best_channel(char *page, char **start, + off_t offset, int count, + int *eof, void *data); +#endif + + int proc_get_rx_signal(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rx_signal(struct file *file, const char *buffer, + unsigned long count, void *data); +#ifdef CONFIG_80211N_HT + int proc_get_cbw40_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_cbw40_enable(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_ampdu_enable(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_ampdu_enable(struct file *file, const char *buffer, + unsigned long count, void *data); + + int proc_get_rx_stbc(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rx_stbc(struct file *file, const char *buffer, + unsigned long count, void *data); +#endif //CONFIG_80211N_HT + + int proc_get_two_path_rssi(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_get_rssi_disp(char *page, char **start, + off_t offset, int count, + int *eof, void *data); + + int proc_set_rssi_disp(struct file *file, const char *buffer, + unsigned long count, void *data); + + +#endif //CONFIG_PROC_DEBUG + +#endif //__RTW_DEBUG_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_eeprom.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_eeprom.h new file mode 100644 index 0000000..9891783 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_eeprom.h @@ -0,0 +1,158 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_EEPROM_H__ +#define __RTW_EEPROM_H__ + +#define RTL8712_EEPROM_ID 0x8712 +//#define EEPROM_MAX_SIZE 256 + +#define HWSET_MAX_SIZE_512 512 +#define EEPROM_MAX_SIZE HWSET_MAX_SIZE_512 + +#define CLOCK_RATE 50 //100us + +//- EEPROM opcodes +#define EEPROM_READ_OPCODE 06 +#define EEPROM_WRITE_OPCODE 05 +#define EEPROM_ERASE_OPCODE 07 +#define EEPROM_EWEN_OPCODE 19 // Erase/write enable +#define EEPROM_EWDS_OPCODE 16 // Erase/write disable + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_ALPHA 0x1 +#define EEPROM_CID_Senao 0x3 +#define EEPROM_CID_NetCore 0x5 +#define EEPROM_CID_CAMEO 0X8 +#define EEPROM_CID_SITECOM 0x9 +#define EEPROM_CID_COREGA 0xB +#define EEPROM_CID_EDIMAX_BELKIN 0xC +#define EEPROM_CID_SERCOMM_BELKIN 0xE +#define EEPROM_CID_CAMEO1 0xF +#define EEPROM_CID_WNC_COREGA 0x12 +#define EEPROM_CID_CLEVO 0x13 +#define EEPROM_CID_WHQL 0xFE // added by chiyoko for dtm, 20090108 + +// +// Customer ID, note that: +// This variable is initiailzed through EEPROM or registry, +// however, its definition may be different with that in EEPROM for +// EEPROM size consideration. So, we have to perform proper translation between them. +// Besides, CustomerID of registry has precedence of that of EEPROM. +// defined below. 060703, by rcnjko. +// +typedef enum _RT_CUSTOMER_ID +{ + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31. + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_CHINA_MOBILE = 15, + RT_CID_819x_ALPHA = 16, + RT_CID_819x_Sitecom = 17, + RT_CID_CCX = 18, // It's set under CCX logo test and isn't demanded for CCX functions, but for test behavior like retry limit and tx report. By Bruce, 2009-02-17. + RT_CID_819x_Lenovo = 19, + RT_CID_819x_QMI = 20, + RT_CID_819x_Edimax_Belkin = 21, + RT_CID_819x_Sercomm_Belkin = 22, + RT_CID_819x_CAMEO1 = 23, + RT_CID_819x_MSI = 24, + RT_CID_819x_Acer = 25, + RT_CID_819x_AzWave_ASUS = 26, + RT_CID_819x_AzWave = 27, // For AzWave in PCIe, The ID is AzWave use and not only Asus + RT_CID_819x_HP = 28, + RT_CID_819x_WNC_COREGA = 29, + RT_CID_819x_Arcadyan_Belkin = 30, + RT_CID_819x_SAMSUNG = 31, + RT_CID_819x_CLEVO = 32, + RT_CID_819x_DELL = 33, + RT_CID_819x_PRONETS = 34, + RT_CID_819x_Edimax_ASUS = 35, + RT_CID_819x_CAMEO_NETGEAR = 36, + RT_CID_PLANEX = 37, + RT_CID_CC_C = 38, + RT_CID_819x_Xavi = 39, + RT_CID_819x_FUNAI_TV = 40, + RT_CID_819x_ALPHA_WD=41, +}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; + +struct eeprom_priv +{ + u8 bautoload_fail_flag; + //u8 bempty; + //u8 sys_config; + u8 mac_addr[6]; //PermanentAddress + //u8 config0; +// u16 channel_plan; + u16 CustomerID; + //u8 country_string[3]; + //u8 tx_power_b[15]; + //u8 tx_power_g[15]; + //u8 tx_power_a[201]; + + u8 EepromOrEfuse; +#ifdef CONFIG_MEMORY_ACCESS_ALIGNED + u8 rsvd; //For byte aligned. By Fangyuan, 141201 +#endif + u8 efuse_eeprom_data[HWSET_MAX_SIZE_512]; //92C:256bytes, 88E:512bytes, we use union set (512bytes) + +#ifdef CONFIG_RF_GAIN_OFFSET + u8 EEPROMRFGainOffset; + u8 EEPROMRFGainVal; +#endif //CONFIG_RF_GAIN_OFFSET +}; + +//TODO +#if 0 + +extern void eeprom_write16(_adapter *padapter, u16 reg, u16 data); +extern u16 eeprom_read16(_adapter *padapter, u16 reg); +extern void read_eeprom_content(_adapter *padapter); +extern void eeprom_read_sz(_adapter * padapter, u16 reg,u8* data, u32 sz); + +extern void read_eeprom_content_by_attrib(_adapter * padapter ); + +#ifdef PLATFORM_LINUX +#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE +extern int isAdaptorInfoFileValid(void); +extern int storeAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv); +extern int retriveAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv); +#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE +#endif //PLATFORM_LINUX + +#endif //#if 0 + +#endif //__RTL871X_EEPROM_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_efuse.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_efuse.h new file mode 100644 index 0000000..d08f088 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_efuse.h @@ -0,0 +1,163 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_EFUSE_H__ +#define __RTW_EFUSE_H__ + +#if (RTL8195A_SUPPORT == 1) +#include "rtl8195a.h" +#endif +#if (RTL8711B_SUPPORT == 1) +#include "ameba_soc.h" +#endif +/*--------------------------Define efuse Parameters-------------------------*/ +#define EFUSE_ERROE_HANDLE 1 + +#define PG_STATE_HEADER 0x01 +#define PG_STATE_WORD_0 0x02 +#define PG_STATE_WORD_1 0x04 +#define PG_STATE_WORD_2 0x08 +#define PG_STATE_WORD_3 0x10 +#define PG_STATE_DATA 0x20 + +#define PG_SWBYTE_H 0x01 +#define PG_SWBYTE_L 0x02 + +#define PGPKT_DATA_SIZE 8 + +#define EFUSE_WIFI 0 +#define EFUSE_BT 1 + +enum _EFUSE_DEF_TYPE { + TYPE_EFUSE_MAX_SECTION = 0, + TYPE_EFUSE_REAL_CONTENT_LEN = 1, + TYPE_AVAILABLE_EFUSE_BYTES_BANK = 2, + TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 3, + TYPE_EFUSE_MAP_LEN = 4, + TYPE_EFUSE_PROTECT_BYTES_BANK = 5, + TYPE_EFUSE_CONTENT_LEN_BANK = 6, +}; + +#define EFUSE_MAP_SIZE 512 +#define EFUSE_MAX_SIZE 256 + +#define EFUSE_MAX_MAP_LEN 512 +#define EFUSE_MAX_HW_SIZE 256 +#define EFUSE_MAX_SECTION_BASE 16 + +#define EXT_HEADER(header) ((header & 0x1F ) == 0x0F) +#define ALL_WORDS_DISABLED(wde) ((wde & 0x0F) == 0x0F) +#define GET_HDR_OFFSET_2_0(header) ( (header & 0xE0) >> 5) + +#define EFUSE_REPEAT_THRESHOLD_ 3 +#define EFUSE_MAX_WORD_UNIT 4 + +//============================================= +// The following is for BT Efuse definition +//============================================= +#define EFUSE_BT_MAX_MAP_LEN 1024 +#define EFUSE_MAX_BANK 4 +#define EFUSE_MAX_BT_BANK (EFUSE_MAX_BANK-1) +//============================================= + +/*--------------------------Define flash Parameters-------------------------*/ +#if CONFIG_ADAPTOR_INFO_CACHING_FLASH +#if defined CONFIG_RTL8195A || defined(CONFIG_RTL8711B) + #define FLASH_MAX_SIZE FLASH_CAL_DATA_SIZE + #define FLASH_MAGIC_NUMBER 0x8195 // magic number + #define FLASH_HEADER_SIZE 4 // 2: address, 2: length +#endif +#endif // CONFIG_ADAPTOR_INFO_CACHING_FLASH +/*------------------------------Define structure----------------------------*/ +typedef struct PG_PKT_STRUCT_A{ + u8 offset; + u8 word_en; + u8 data[8]; + u8 word_cnts; +}PGPKT_STRUCT,*PPGPKT_STRUCT; + +#ifdef HAL_EFUSE_MEMORY +typedef struct _EFUSE_HAL{ + u8 fakeEfuseBank; + u32 fakeEfuseUsedBytes; + u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE]; + u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]; + u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]; + + u16 BTEfuseUsedBytes; + u8 BTEfuseUsedPercentage; + u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; + u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; + u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; + + u16 fakeBTEfuseUsedBytes; + u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; + u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]; + u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; +}EFUSE_HAL, *PEFUSE_HAL; +#endif // HAL_EFUSE_MEMORY + +/*------------------------Export global variable----------------------------*/ +#if CONFIG_FAKE_EFUSE +extern u8 fakeEfuseBank; +extern u32 fakeEfuseUsedBytes; +extern u8 fakeEfuseContent[]; +extern u8 fakeEfuseInitMap[]; +extern u8 fakeEfuseModifiedMap[]; +#endif + +#ifdef CONFIG_BT_COEXIST +extern u32 BTEfuseUsedBytes; +extern u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 BTEfuseInitMap[]; +extern u8 BTEfuseModifiedMap[]; +#if CONFIG_FAKE_EFUSE +extern u32 fakeBTEfuseUsedBytes; +extern u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +extern u8 fakeBTEfuseInitMap[]; +extern u8 fakeBTEfuseModifiedMap[]; +#endif +#endif + +/*------------------------Export global variable----------------------------*/ + +u8 efuse_GetCurrentSize(_adapter * padapter, u16 *size); +u8 rtw_efuse_access(_adapter * padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_read(_adapter * padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_efuse_map_write(_adapter * padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_BT_efuse_map_read(_adapter * padapter, u16 addr, u16 cnts, u8 *data); +u8 rtw_BT_efuse_map_write(_adapter * padapter, u16 addr, u16 cnts, u8 *data); + +u16 Efuse_GetCurrentSize(_adapter * pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +u8 Efuse_CalculateWordCnts(u8 word_en); +void EFUSE_GetEfuseDefinition(_adapter * pAdapter, u8 efuseType, u8 type, void *pOut, BOOLEAN bPseudoTest); +u8 efuse_OneByteRead(_adapter * pAdapter, u16 addr, u8 *data, BOOLEAN bPseudoTest); +u8 efuse_OneByteWrite(_adapter * pAdapter, u16 addr, u8 data, BOOLEAN bPseudoTest); + +void Efuse_PowerSwitch(_adapter * pAdapter,u8 bWrite,u8 PwrState); +//int Efuse_PgPacketRead(_adapter * pAdapter, u8 offset, u8 *data, BOOLEAN bPseudoTest); +int Efuse_PgPacketWrite(_adapter * pAdapter, u8 offset, u8 word_en, u8 *data, BOOLEAN bPseudoTest); +void efuse_WordEnableDataRead(u8 word_en, u8 *sourdata, u8 *targetdata); +u8 Efuse_WordEnableDataWrite(_adapter * pAdapter, u16 efuse_addr, u8 word_en, u8 *data, BOOLEAN bPseudoTest); + +void EFUSE_ShadowMapUpdate(_adapter * pAdapter, u8 efuseType, BOOLEAN bPseudoTest); +void EFUSE_ShadowRead(_adapter * pAdapter, u8 Type, u16 Offset, u32 *Value); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_event.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_event.h new file mode 100644 index 0000000..83b29b9 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_event.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_EVENT_H_ +#define _RTW_EVENT_H_ + +#ifndef CONFIG_RTL8711FW +#ifdef PLATFORM_LINUX +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) +#include +#else +#include +#endif +#include +#endif +#endif//CONFIG_RTL8711FW + + + +#ifdef CONFIG_H2CLBK +#include +#endif + +/* +Used to report a bss has been scanned + +*/ +struct survey_event { + WLAN_BSSID_EX bss; +}; + +/* +Used to report that the requested site survey has been done. + +bss_cnt indicates the number of bss that has been reported. + + +*/ +struct surveydone_event { + unsigned int bss_cnt; + +}; + +/* +Used to report the link result of joinning the given bss + + +join_res: +-1: authentication fail +-2: association fail +> 0: TID + +*/ +struct joinbss_event { + //struct wlan_network network; + int join_res; +}; + +/* +Used to report a given STA has joinned the created BSS. +It is used in AP/Ad-HoC(M) mode. + + +*/ +struct stassoc_event { + unsigned char macaddr[6]; + unsigned char rsvd[2]; + int cam_id; + +}; + +struct stadel_event { + unsigned char macaddr[6]; + unsigned char rsvd[2]; //for reason + int mac_id; +}; + +struct addba_event +{ + unsigned int tid; +}; + + +#ifdef CONFIG_H2CLBK +struct c2hlbk_event{ + unsigned char mac[6]; + unsigned short s0; + unsigned short s1; + unsigned int w0; + unsigned char b0; + unsigned short s2; + unsigned char b1; + unsigned int w1; +}; +#endif//CONFIG_H2CLBK + +#define GEN_EVT_CODE(event) event ## _EVT_ + +struct fwevent { + u32 parmsize; + void (*event_callback)(_adapter *dev, u8 *pbuf); +}; + +//TODO +#if 0 + +#define C2HEVENT_SZ 32 + +struct event_node{ + unsigned char *node; + unsigned char evt_code; + unsigned short evt_sz; + volatile int *caller_ff_tail; + int caller_ff_sz; +}; + +struct c2hevent_queue { + volatile int head; + volatile int tail; + struct event_node nodes[C2HEVENT_SZ]; + unsigned char seq; +}; + +#define NETWORK_QUEUE_SZ 4 + +struct network_queue { + volatile int head; + volatile int tail; + WLAN_BSSID_EX networks[NETWORK_QUEUE_SZ]; +}; + +#endif //#if 0 + +#endif // _WLANEVENT_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_ht.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_ht.h new file mode 100644 index 0000000..5910986 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_ht.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_HT_H_ +#define _RTW_HT_H_ + +#include "wifi.h" + +struct ht_priv +{ + u32 ht_option; + u32 ampdu_enable;//for enable Tx A-MPDU + //u8 baddbareq_issued[16]; + //u32 tx_amsdu_enable;//for enable Tx A-MSDU + //u32 tx_amdsu_maxlen; // 1: 8k, 0:4k ; default:8k, for tx + //u32 rx_ampdu_maxlen; //for rx reordering ctrl win_sz, updated when join_callback. + + u8 bwmode;// + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + + //for processing Tx A-MPDU + u8 agg_enable_bitmap; + //u8 ADDBA_retry_count; + u8 candidate_tid_bitmap; + + u8 stbc_cap; + + struct rtw_ieee80211_ht_cap ht_cap; + +}; + +#define STBC_HT_ENABLE_RX BIT0 +#define STBC_HT_ENABLE_TX BIT1 +#define STBC_HT_TEST_TX_ENABLE BIT2 +#define STBC_HT_CAP_TX BIT3 + +typedef enum AGGRE_SIZE{ + HT_AGG_SIZE_8K = 0, + HT_AGG_SIZE_16K = 1, + HT_AGG_SIZE_32K = 2, + HT_AGG_SIZE_64K = 3, + VHT_AGG_SIZE_128K = 4, + VHT_AGG_SIZE_256K = 5, + VHT_AGG_SIZE_512K = 6, + VHT_AGG_SIZE_1024K = 7, +}AGGRE_SIZE_E, *PAGGRE_SIZE_E; + +#endif //_RTL871X_HT_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_intfs.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_intfs.h new file mode 100644 index 0000000..1a8594e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_intfs.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_INTFS_H_ +#define _RTW_INTFS_H_ + +extern u8 rtw_init_default_value(_adapter *padapter); +#ifdef CONFIG_WOWLAN +void rtw_cancel_dynamic_chk_timer(_adapter *padapter); +#endif +extern void rtw_cancel_all_timer(_adapter *padapter); + +extern u8 rtw_init_drv_sw(_adapter *padapter); +extern u8 rtw_free_drv_sw(_adapter *padapter); +extern u8 rtw_reset_drv_sw(_adapter *padapter); + +extern int rtw_drv_init(ADAPTER *padapter); +extern void rtw_drv_deinit(ADAPTER *Adapter); + +extern u32 rtw_start_drv_threads(_adapter *padapter); +extern void rtw_stop_drv_threads (_adapter *padapter); + +#endif //_RTW_INTFS_H_ diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_io.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_io.h new file mode 100644 index 0000000..2801cce --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_io.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef _RTW_IO_H_ +#define _RTW_IO_H_ + +//IO Bus domain address mapping +#define DEFUALT_OFFSET 0x0 +#define WLAN_LOCAL_OFFSET 0x10250000 +#define WLAN_IOREG_OFFSET 0x10260000 +#define FW_FIFO_OFFSET 0x10270000 +#define TX_HIQ_OFFSET 0x10310000 +#define TX_MIQ_OFFSET 0x1032000 +#define TX_LOQ_OFFSET 0x10330000 +#define RX_RXOFF_OFFSET 0x10340000 + +struct fifo_more_data { + u32 more_data; + u32 len; +}; + +struct dvobj_priv; + +typedef struct _io_ops { + int (*init_io_priv)(struct dvobj_priv *pdvobj); + int (*write8_endian)(struct dvobj_priv *pdvobj, u32 addr, u32 buf, u32 big); + + u8 (*_read8)(struct dvobj_priv *pdvobj, u32 addr, s32 *err); + u16 (*_read16)(struct dvobj_priv *pdvobj, u32 addr, s32 *err); + u32 (*_read32)(struct dvobj_priv *pdvobj, u32 addr, s32 *err); + + s32 (*_write8)(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err); + s32 (*_write16)(struct dvobj_priv *pdvobj, u32 addr,u16 buf, s32 *err); + s32 (*_write32)(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err); + + int (*read_rx_fifo)(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len, struct fifo_more_data *more_data); + int (*write_tx_fifo)(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len); +} IO_OPS_T; + +struct bus_transfer { + void *tx_buf; + void *rx_buf; + unsigned int len; +}; + +typedef struct _bus_drv_ops { + int (*bus_drv_init)(ADAPTER *Adapter); + int (*bus_send_msg)(PADAPTER Adapter, struct bus_transfer xfers[], u32 RegAction); +} BUS_DRV_OPS_T; + +/* +struct intf_hdl { + + u32 intf_option; + u32 bus_status; + u32 do_flush; + u8 *adapter; + u8 *intf_dev; + struct intf_priv *pintfpriv; + u8 cnt; + void (*intf_hdl_init)(u8 *priv); + void (*intf_hdl_unload)(u8 *priv); + void (*intf_hdl_open)(u8 *priv); + void (*intf_hdl_close)(u8 *priv); + struct _io_ops io_ops; + //u8 intf_status;//moved to struct intf_priv + u16 len; + u16 done_len; + + _adapter *padapter; + struct dvobj_priv *pintf_dev;// pointer to &(padapter->dvobjpriv); + + struct _io_ops io_ops; + +}; +*/ + +struct io_priv{ + struct _io_ops io_ops; +}; + + +extern u8 rtw_read8(ADAPTER *adapter, u32 addr); +extern u16 rtw_read16(ADAPTER *adapter, u32 addr); +extern u32 rtw_read32(ADAPTER *adapter, u32 addr); +extern s32 rtw_write8(ADAPTER *adapter, u32 addr, u8 val); +extern s32 rtw_write16(ADAPTER *adapter, u32 addr, u16 val); +extern s32 rtw_write32(ADAPTER *adapter, u32 addr, u32 val); + +#define PlatformEFIOWrite1Byte(_a,_b,_c) \ + rtw_write8(_a,_b,_c) +#define PlatformEFIOWrite2Byte(_a,_b,_c) \ + rtw_write16(_a,_b,_c) +#define PlatformEFIOWrite4Byte(_a,_b,_c) \ + rtw_write32(_a,_b,_c) + +#define PlatformEFIORead1Byte(_a,_b) \ + rtw_read8(_a,_b) +#define PlatformEFIORead2Byte(_a,_b) \ + rtw_read16(_a,_b) +#define PlatformEFIORead4Byte(_a,_b) \ + rtw_read32(_a,_b) + +extern IO_OPS_T io_ops; + +extern u32 rtw_write_port( + ADAPTER *adapter, + u32 addr, + u32 cnt, + u8 *mem); +extern u32 rtw_read_port( + ADAPTER *adapter, + u32 addr, + u32 cnt, + u8 *mem, + struct fifo_more_data *more_data); +extern void rtw_set_chip_endian(PADAPTER padapter); +extern int rtw_get_chip_endian(PADAPTER padapter); + +int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops)); + +#endif //_RTW_IO_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_ioctl_set.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_ioctl_set.h new file mode 100644 index 0000000..8e247e3 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_ioctl_set.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_IOCTL_SET_H_ +#define __RTW_IOCTL_SET_H_ + + +#ifdef PLATFORM_OS_XP +typedef struct _NDIS_802_11_PMKID { + u32 Length; + u32 BSSIDInfoCount; + BSSIDInfo BSSIDInfo[1]; +} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID; +#endif + + +#ifdef PLATFORM_WINDOWS +typedef u8 NDIS_802_11_PMKID_VALUE[16]; + +typedef struct _BSSIDInfo { + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_PMKID_VALUE PMKID; +} BSSIDInfo, *PBSSIDInfo; + +u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults); +u8 rtw_set_802_11_test(_adapter * padapter, NDIS_802_11_TEST * test); +u8 rtw_set_802_11_pmkid(_adapter *pdapter, NDIS_802_11_PMKID *pmkid); + +u8 rtw_pnp_set_power_sleep(_adapter* padapter); +u8 rtw_pnp_set_power_wakeup(_adapter* padapter); + +void rtw_pnp_resume_wk(void *context); +void rtw_pnp_sleep_wk(void * context); + +#endif + +u8 rtw_set_802_11_add_key(_adapter * padapter, NDIS_802_11_KEY * key); +u8 rtw_set_802_11_authentication_mode(_adapter *pdapter, NDIS_802_11_AUTHENTICATION_MODE authmode); +u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid); +u8 rtw_set_802_11_add_wep(_adapter * padapter, NDIS_802_11_WEP * wep); +u8 rtw_set_802_11_disassociate(_adapter * padapter); +u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +u8 rtw_set_802_11_infrastructure_mode(_adapter * padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +u8 rtw_set_802_11_remove_wep(_adapter * padapter, u32 keyindex); +u8 rtw_set_802_11_ssid(_adapter * padapter, NDIS_802_11_SSID * ssid); +u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid); +u8 rtw_set_802_11_remove_key(_adapter * padapter, NDIS_802_11_REMOVE_KEY * key); + +u8 rtw_validate_bssid(u8 *bssid); +u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid); + +u16 rtw_get_cur_max_rate(_adapter *adapter); +//int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode); +int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan); +int rtw_set_country(_adapter *adapter, const char *country_code); +//int rtw_set_band(_adapter *adapter, enum _BAND band); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_led.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_led.h new file mode 100644 index 0000000..e6b6d8a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_led.h @@ -0,0 +1,250 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_LED_H_ +#define __RTW_LED_H_ + +//TODO +#if 0 + +//#include + +#define MSECS(t) (HZ * ((t) / 1000) + (HZ * ((t) % 1000)) / 1000) + +#define LED_BLINK_NORMAL_INTERVAL 100 +#define LED_BLINK_SLOWLY_INTERVAL 200 +#define LED_BLINK_LONG_INTERVAL 400 + +#define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 +#define LED_BLINK_LINK_INTERVAL_ALPHA 500 //500 +#define LED_BLINK_SCAN_INTERVAL_ALPHA 180 //150 +#define LED_BLINK_FASTER_INTERVAL_ALPHA 50 +#define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 + +#define LED_BLINK_NORMAL_INTERVAL_NETTRONIX 100 +#define LED_BLINK_SLOWLY_INTERVAL_NETTRONIX 2000 + +#define LED_BLINK_SLOWLY_INTERVAL_PORNET 1000 +#define LED_BLINK_NORMAL_INTERVAL_PORNET 100 + +#define LED_BLINK_FAST_INTERVAL_BITLAND 30 + +// 060403, rcnjko: Customized for AzWave. +#define LED_CM2_BLINK_ON_INTERVAL 250 +#define LED_CM2_BLINK_OFF_INTERVAL 4750 + +#define LED_CM8_BLINK_INTERVAL 500 //for QMI +#define LED_CM8_BLINK_OFF_INTERVAL 3750 //for QMI + +// 080124, lanhsin: Customized for RunTop +#define LED_RunTop_BLINK_INTERVAL 300 + +// 060421, rcnjko: Customized for Sercomm Printer Server case. +#define LED_CM3_BLINK_INTERVAL 1500 + +#endif //#if 0 + +typedef enum _LED_CTL_MODE{ + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, + LED_CTL_START_WPS_BOTTON = 11, //added for runtop + LED_CTL_STOP_WPS_FAIL = 12, //added for ALPHA + LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, //added for BELKIN + LED_CTL_CONNECTION_NO_TRANSFER = 14, +}LED_CTL_MODE; + +//TODO +#if 0 + +typedef enum _LED_STATE_871x{ + LED_UNKNOWN = 0, + RTW_LED_ON = 1, + RTW_LED_OFF = 2, + LED_BLINK_NORMAL = 3, + LED_BLINK_SLOWLY = 4, + LED_BLINK_POWER_ON = 5, + LED_BLINK_SCAN = 6, // LED is blinking during scanning period, the # of times to blink is depend on time for scanning. + LED_BLINK_NO_LINK = 7, // LED is blinking during no link state. + LED_BLINK_StartToBlink = 8,// Customzied for Sercomm Printer Server case + LED_BLINK_TXRX = 9, + LED_BLINK_WPS = 10, // LED is blinkg during WPS communication + LED_BLINK_WPS_STOP = 11, //for ALPHA + LED_BLINK_WPS_STOP_OVERLAP = 12, //for BELKIN + LED_BLINK_RUNTOP = 13, // Customized for RunTop + LED_BLINK_CAMEO = 14, + LED_BLINK_XAVI = 15, + LED_BLINK_ALWAYS_ON = 16, +}LED_STATE_871x; + +typedef enum _LED_PIN_871x{ + LED_PIN_NULL = 0, + LED_PIN_LED0 = 1, + LED_PIN_LED1 = 2, + LED_PIN_LED2 = 3, + LED_PIN_GPIO0 = 4, +}LED_PIN_871x; + +typedef struct _LED_871x{ + _adapter *padapter; + + LED_PIN_871x LedPin; // Identify how to implement this SW led. + LED_STATE_871x CurrLedState; // Current LED state. + LED_STATE_871x BlinkingLedState; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. + + u8 bLedOn; // true if LED is ON, false if LED is OFF. + + u8 bLedBlinkInProgress; // true if it is blinking, false o.w.. + + u8 bLedWPSBlinkInProgress; + + u32 BlinkTimes; // Number of times to toggle led state for blinking. + + _timer BlinkTimer; // Timer object for led blinking. + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 bSWLedCtrl; + + // ALPHA, added by chiyoko, 20090106 + u8 bLedNoLinkBlinkInProgress; + u8 bLedLinkBlinkInProgress; + u8 bLedStartToLinkBlinkInProgress; + u8 bLedScanBlinkInProgress; + + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)|| defined PLATFORM_FREEBSD + _workitem BlinkWorkItem; // Workitem used by BlinkTimer to manipulate H/W to blink LED. + #endif +#endif //defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) + u8 bLedSlowBlinkInProgress;//added by vivi, for led new mode +#endif + +} LED_871x, *PLED_871x; + +#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#define IS_LED_WPS_BLINKING(_LED_871x) (((PLED_871x)_LED_871x)->CurrLedState==LED_BLINK_WPS \ + || ((PLED_871x)_LED_871x)->CurrLedState==LED_BLINK_WPS_STOP \ + || ((PLED_871x)_LED_871x)->bLedWPSBlinkInProgress) + +#define IS_LED_BLINKING(_LED_871x) (((PLED_871x)_LED_871x)->bLedWPSBlinkInProgress \ + ||((PLED_871x)_LED_871x)->bLedScanBlinkInProgress) + +//================================================================================ +// LED customization. +//================================================================================ + +typedef enum _LED_STRATEGY_871x{ + SW_LED_MODE0 = 0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1= 1, // 2 LEDs, through LED0 and LED1. For ALPHA. + SW_LED_MODE2 = 2, // SW control 1 LED via GPIO0, customized for AzWave 8187 minicard. + SW_LED_MODE3 = 3, // SW control 1 LED via GPIO0, customized for Sercomm Printer Server case. + SW_LED_MODE4 = 4, //for Edimax / Belkin + SW_LED_MODE5 = 5, //for Sercomm / Belkin + SW_LED_MODE6 = 6, //for 88CU minicard, porting from ce SW_LED_MODE7 + HW_LED = 50, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes, see MAC.CONFIG1 for details.) + LED_ST_NONE = 99, +}LED_STRATEGY_871x, *PLED_STRATEGY_871x; + +void +LedControl871x( + _adapter *padapter, + LED_CTL_MODE LedAction + ); +#endif //defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +//================================================================================ +// LED customization. +//================================================================================ + +typedef enum _LED_STRATEGY_871x{ + SW_LED_MODE0 = 0, // SW control 1 LED via GPIO0. It is default option. + SW_LED_MODE1 = 1, // SW control for PCI Express + SW_LED_MODE2 = 2, // SW control for Cameo. + SW_LED_MODE3 = 3, // SW contorl for RunTop. + SW_LED_MODE4 = 4, // SW control for Netcore + SW_LED_MODE5 = 5, //added by vivi, for led new mode, DLINK + SW_LED_MODE6 = 6, //added by vivi, for led new mode, PRONET + SW_LED_MODE7 = 7, //added by chiyokolin, for Lenovo, PCI Express Minicard Spec Rev.1.2 spec + SW_LED_MODE8 = 8, //added by chiyokolin, for QMI + SW_LED_MODE9 = 9, //added by chiyokolin, for BITLAND, PCI Express Minicard Spec Rev.1.1 + SW_LED_MODE10 = 10, //added by chiyokolin, for Edimax-ASUS + HW_LED = 50, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) + LED_ST_NONE = 99, +}LED_STRATEGY_871x, *PLED_STRATEGY_871x; +#endif //defined(CONFIG_PCI_HCI) + +struct led_priv{ + /* add for led controll */ + LED_871x SwLed0; + LED_871x SwLed1; + LED_STRATEGY_871x LedStrategy; + u8 bRegUseLed; + void (*LedControlHandler)(_adapter *padapter, LED_CTL_MODE LedAction); + /* add for led controll */ +}; + +#endif //#if 0 + +#ifdef CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) \ + do { \ + if((adapter)->ledpriv.LedControlHandler) \ + (adapter)->ledpriv.LedControlHandler((adapter), (LedAction)); \ + } while(0) +#else //CONFIG_SW_LED +#define rtw_led_control(adapter, LedAction) +#endif //CONFIG_SW_LED + +//TODO +#if 0 + +void BlinkTimerCallback(void *data); +void BlinkWorkItemCallback(struct work_struct *work); + +void ResetLedStatus(PLED_871x pLed); + +void +InitLed871x( + _adapter *padapter, + PLED_871x pLed, + LED_PIN_871x LedPin + ); + +void +DeInitLed871x( + PLED_871x pLed + ); + +//hal... +extern void BlinkHandler(PLED_871x pLed); + +#endif //#if 0 + +#endif //__RTW_LED_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme.h new file mode 100644 index 0000000..f80fc61 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme.h @@ -0,0 +1,795 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_MLME_H_ +#define __RTW_MLME_H_ + +#ifdef CONFIG_INTEL_WIDI +#include +#endif + +#if defined(PLATFORM_ECOS) +#define MAX_BSS_CNT 10 //alloc less wlan_network due to memory limitation - Alex Fang +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#define MAX_BSS_CNT 1 //alloc less wlan_network due to memory limitation - Alex Fang +#else +#define MAX_BSS_CNT 128 +#endif +//#define MAX_JOIN_TIMEOUT 2000 +//#define MAX_JOIN_TIMEOUT 2500 +#define MAX_JOIN_TIMEOUT 6500 + +#ifdef CONFIG_MULTICAST +#define MULTICAST_LIST_SIZE 4 +#endif + +// Commented by Albert 20101105 +// Increase the scanning timeout because of increasing the SURVEY_TO value. + +#define SCANNING_TIMEOUT 8000 + +#define SCAN_INTERVAL (30) // unit:2sec, 30*2=60sec + +#ifdef PALTFORM_OS_WINCE +#define SCANQUEUE_LIFETIME 12000000 // unit:us +#else +#define SCANQUEUE_LIFETIME 20 // unit:sec +#endif + +#define WIFI_NULL_STATE 0x00000000 +#define WIFI_ASOC_STATE 0x00000001 // Under Linked state... +#define WIFI_REASOC_STATE 0x00000002 +#define WIFI_SLEEP_STATE 0x00000004 +#define WIFI_STATION_STATE 0x00000008 +#define WIFI_AP_STATE 0x00000010 +#define WIFI_ADHOC_STATE 0x00000020 +#define WIFI_ADHOC_MASTER_STATE 0x00000040 +#define WIFI_UNDER_LINKING 0x00000080 +//#define WIFI_UNDER_CMD 0x00000200 +// ========== P2P Section Start =============== +#define WIFI_P2P_LISTEN_STATE 0x00010000 +#define WIFI_P2P_GROUP_FORMATION_STATE 0x00020000 +// ========== P2P Section End =============== +#define WIFI_UNDER_WPS 0x00000100 +#define WIFI_SITE_MONITOR 0x00000800 //to indicate the station is under site surveying + +#ifdef WDS +#define WIFI_WDS 0x00001000 +#define WIFI_WDS_RX_BEACON 0x00002000 // already rx WDS AP beacon +#endif +#ifdef AUTO_CONFIG +#define WIFI_AUTOCONF 0x00004000 +#define WIFI_AUTOCONF_IND 0x00008000 +#endif + +//#ifdef UNDER_MPTEST +#define WIFI_MP_STATE 0x00010000 +#define WIFI_MP_CTX_BACKGROUND 0x00020000 // in continous tx background +#define WIFI_MP_CTX_ST 0x00040000 // in continous tx with single-tone +#define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 // pending in continous tx background due to out of skb +#define WIFI_MP_CTX_CCK_HW 0x00100000 // in continous tx +#define WIFI_MP_CTX_CCK_CS 0x00200000 // in continous tx with carrier suppression +#define WIFI_MP_LPBK_STATE 0x00400000 +//#endif + +//#define _FW_UNDER_CMD WIFI_UNDER_CMD +#define _FW_UNDER_LINKING WIFI_UNDER_LINKING +#define _FW_LINKED WIFI_ASOC_STATE +#define _FW_UNDER_SURVEY WIFI_SITE_MONITOR + +enum dot11AuthAlgrthmNum { + dot11AuthAlgrthm_Open = 0, + dot11AuthAlgrthm_Shared, + dot11AuthAlgrthm_8021X, + dot11AuthAlgrthm_Auto, + dot11AuthAlgrthm_WAPI, + dot11AuthAlgrthm_MaxNum +}; + +// Scan type including active and passive scan. +typedef enum _RT_SCAN_TYPE +{ + SCAN_PASSIVE, + SCAN_ACTIVE, + SCAN_MIX, +} RT_SCAN_TYPE, *PRT_SCAN_TYPE; + +/* + +there are several "locks" in mlme_priv, +since mlme_priv is a shared resource between many threads, +like ISR/Call-Back functions, the OID handlers, and even timer functions. + + +Each _queue has its own locks, already. +Other items are protected by mlme_priv.lock. + +To avoid possible dead lock, any thread trying to modifiying mlme_priv +SHALL not lock up more than one locks at a time! + +*/ + + +#define traffic_threshold 10 +#define traffic_scan_period 500 + +struct sitesurvey_ctrl { + u64 last_tx_pkts; + uint last_rx_pkts; + sint traffic_busy; + _timer sitesurvey_ctrl_timer; +}; + +typedef struct _RT_LINK_DETECT_T{ + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + u32 NumRxUnicastOkInPeriod; + BOOLEAN bBusyTraffic; + BOOLEAN bTxBusyTraffic; + BOOLEAN bRxBusyTraffic; + BOOLEAN bHigherBusyTraffic; // For interrupt migration purpose. + BOOLEAN bHigherBusyRxTraffic; // We may disable Tx interrupt according as Rx traffic. + BOOLEAN bHigherBusyTxTraffic; // We may disable Tx interrupt according as Tx traffic. +} RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; + +//TODO +#if 0 + +struct profile_info { + u8 ssidlen; + u8 ssid[ WLAN_SSID_MAXLEN ]; + u8 peermac[ ETH_ALEN ]; +}; + +struct tx_invite_req_info{ + u8 token; + u8 benable; + u8 go_ssid[ WLAN_SSID_MAXLEN ]; + u8 ssidlen; + u8 go_bssid[ ETH_ALEN ]; + u8 peer_macaddr[ ETH_ALEN ]; + u8 operating_ch; // This information will be set by using the p2p_set op_ch=x + u8 peer_ch; // The listen channel for peer P2P device + +}; + +struct tx_invite_resp_info{ + u8 token; // Used to record the dialog token of p2p invitation request frame. +}; + +#ifdef CONFIG_WFD + +struct wifi_display_info{ + u16 wfd_enable; // Eanble/Disable the WFD function. + u16 rtsp_ctrlport; // TCP port number at which the this WFD device listens for RTSP messages + u16 peer_rtsp_ctrlport; // TCP port number at which the peer WFD device listens for RTSP messages + // This filed should be filled when receiving the gropu negotiation request + + u8 peer_session_avail; // WFD session is available or not for the peer wfd device. + // This variable will be set when sending the provisioning discovery request to peer WFD device. + // And this variable will be reset when it is read by using the iwpriv p2p_get wfd_sa command. + u8 ip_address[4]; + u8 peer_ip_address[4]; + u8 wfd_pc; // WFD preferred connection + // 0 -> Prefer to use the P2P for WFD connection on peer side. + // 1 -> Prefer to use the TDLS for WFD connection on peer side. + + u8 wfd_device_type; // WFD Device Type + // 0 -> WFD Source Device + // 1 -> WFD Primary Sink Device + +}; +#endif //CONFIG_WFD + +struct tx_provdisc_req_info{ + u16 wps_config_method_request; // Used when sending the provisioning request frame + u16 peer_channel_num[2]; // The channel number which the receiver stands. + NDIS_802_11_SSID ssid; + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 peerIFAddr[ ETH_ALEN ]; // Peer interface address + u8 benable; // This provision discovery request frame is trigger to send or not +}; + +struct rx_provdisc_req_info{ //When peer device issue prov_disc_req first, we should store the following informations + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 strconfig_method_desc_of_prov_disc_req[4]; // description for the config method located in the provisioning discovery request frame. + // The UI must know this information to know which config method the remote p2p device is requiring. +}; + +struct tx_nego_req_info{ + u16 peer_channel_num[2]; // The channel number which the receiver stands. + u8 peerDevAddr[ ETH_ALEN ]; // Peer device address + u8 benable; // This negoitation request frame is trigger to send or not +}; + +struct group_id_info{ + u8 go_device_addr[ ETH_ALEN ]; // The GO's device address of this P2P group + u8 ssid[ WLAN_SSID_MAXLEN ]; // The SSID of this P2P group +}; + +#ifdef CONFIG_IOCTL_CFG80211 +struct cfg80211_wifidirect_info{ + _timer remain_on_ch_timer; + u8 restore_channel; + struct ieee80211_channel remain_on_ch_channel; + enum nl80211_channel_type remain_on_ch_type; + u64 remain_on_ch_cookie; + struct net_device *remain_on_ch_dev; + bool is_ro_ch; +}; +#endif //CONFIG_IOCTL_CFG80211 + +#endif + +struct wifidirect_info{ + enum P2P_ROLE role; + enum P2P_STATE p2p_state; + u8 baction_tx_pending; + u8 pending_peer[ETH_ALEN]; + struct xmit_frame *pending_action; + _timer pre_tx_scan_timer; + +#if 0 + _adapter* padapter; + _timer find_phase_timer; + _timer restore_p2p_state_timer; + + // Used to do the scanning. After confirming the peer is availalble, the driver transmits the P2P frame to peer. + _timer pre_tx_scan_timer; +#ifdef CONFIG_CONCURRENT_MODE + // Used to switch the channel between legacy AP and listen state. + _timer ap_p2p_switch_timer; +#endif + struct tx_provdisc_req_info tx_prov_disc_info; + struct rx_provdisc_req_info rx_prov_disc_info; + struct tx_invite_req_info invitereq_info; + struct profile_info profileinfo[ P2P_MAX_PERSISTENT_GROUP_NUM ]; // Store the profile information of persistent group + struct tx_invite_resp_info inviteresp_info; + struct tx_nego_req_info nego_req_info; + struct group_id_info groupid_info; // Store the group id information when doing the group negotiation handshake. +#ifdef CONFIG_WFD + struct wifi_display_info *wfd_info; +#endif + enum P2P_ROLE role; + enum P2P_STATE pre_p2p_state; + enum P2P_STATE p2p_state; + u8 device_addr[ETH_ALEN]; // The device address should be the mac address of this device. + u8 interface_addr[ETH_ALEN]; + u8 social_chan[4]; + u8 listen_channel; + u8 operating_channel; + u8 listen_dwell; // This value should be between 1 and 3 + u8 support_rate[8]; + u8 p2p_wildcard_ssid[P2P_WILDCARD_SSID_LEN]; + u8 intent; // should only include the intent value. + u8 p2p_peer_interface_addr[ ETH_ALEN ]; + u8 p2p_peer_device_addr[ ETH_ALEN ]; + u8 peer_intent; // Included the intent value and tie breaker value. + u8 device_name[ WPS_MAX_DEVICE_NAME_LEN ]; // Device name for displaying on searching device screen + u8 device_name_len; + u8 profileindex; // Used to point to the index of profileinfo array + u8 peer_operating_ch; + u8 find_phase_state_exchange_cnt; + u16 device_password_id_for_nego; // The device password ID for group negotation + u8 negotiation_dialog_token; + u8 nego_ssid[ WLAN_SSID_MAXLEN ]; // SSID information for group negotitation + u8 nego_ssidlen; + u8 p2p_group_ssid[WLAN_SSID_MAXLEN]; + u8 p2p_group_ssid_len; + u8 persistent_supported; // Flag to know the persistent function should be supported or not. + // In the Sigma test, the Sigma will provide this enable from the sta_set_p2p CAPI. + // 0: disable + // 1: enable + u8 session_available; // Flag to set the WFD session available to enable or disable "by Sigma" + // In the Sigma test, the Sigma will disable the session available by using the sta_preset CAPI. + // 0: disable + // 1: enable + + u8 wfd_tdls_enable; // Flag to enable or disable the TDLS by WFD Sigma + // 0: disable + // 1: enable + u8 wfd_tdls_weaksec; // Flag to enable or disable the weak security function for TDLS by WFD Sigma + // 0: disable + // In this case, the driver can't issue the tdsl setup request frame. + // 1: enable + // In this case, the driver can issue the tdls setup request frame + // even the current security is weak security. + + enum P2P_WPSINFO ui_got_wps_info; // This field will store the WPS value (PIN value or PBC) that UI had got from the user. + u16 supported_wps_cm; // This field describes the WPS config method which this driver supported. + // The value should be the combination of config method defined in page104 of WPS v2.0 spec. + uint channel_list_attr_len; // This field will contain the length of body of P2P Channel List attribute of group negotitation response frame. + u8 channel_list_attr[100]; // This field will contain the body of P2P Channel List attribute of group negotitation response frame. + // We will use the channel_cnt and channel_list fields when constructing the group negotitation confirm frame. +#ifdef CONFIG_CONCURRENT_MODE + u16 ext_listen_interval; // The interval to be available with legacy AP (ms) + u16 ext_listen_period; // The time period to be available for P2P listen state (ms) +#endif + u8 p2p_ps_enable; + enum P2P_PS p2p_ps; // indicate p2p ps state + u8 noa_index; // Identifies and instance of Notice of Absence timing. + u8 ctwindow; // Client traffic window. A period of time in TU after TBTT. + u8 opp_ps; // opportunistic power save. + u8 noa_num; // number of NoA descriptor in P2P IE. + u8 noa_count[P2P_MAX_NOA_NUM]; // Count for owner, Type of client. + u32 noa_duration[P2P_MAX_NOA_NUM]; // Max duration for owner, preferred or min acceptable duration for client. + u32 noa_interval[P2P_MAX_NOA_NUM]; // Length of interval for owner, preferred or max acceptable interval of client. + u32 noa_start_time[P2P_MAX_NOA_NUM]; // schedule expressed in terms of the lower 4 bytes of the TSF timer. +#endif +}; +#if 0 +struct tdls_ss_record{ //signal strength record + u8 macaddr[ETH_ALEN]; + u8 RxPWDBAll; + u8 is_tdls_sta; // _TRUE: direct link sta, _FALSE: else +}; + +struct tdls_info{ + u8 ap_prohibited; + uint setup_state; + u8 sta_cnt; + u8 sta_maximum; // 1:tdls sta is equal (NUM_STA-1), reach max direct link number; 0: else; + struct tdls_ss_record ss_record; + u8 macid_index; //macid entry that is ready to write + u8 clear_cam; //cam entry that is trying to clear, using it in direct link teardown + u8 ch_sensing; + u8 cur_channel; + u8 candidate_ch; + u8 collect_pkt_num[MAX_CHANNEL_NUM]; + _lock cmd_lock; + _lock hdl_lock; + u8 watchdog_count; + u8 dev_discovered; //WFD_TDLS: for sigma test + u8 enable; +#ifdef CONFIG_WFD + struct wifi_display_info *wfd_info; +#endif +}; + +#endif //#if 0 + +struct mlme_priv { + + _lock lock; + sint fw_state; //shall we protect this variable? maybe not necessarily... + u8 bScanInProcess; + u8 to_join; //flag + #ifdef CONFIG_LAYER2_ROAMING + u8 to_roaming; // roaming trying times + #endif + + u8 *nic_hdl; //can be removed + + //u8 not_indic_disco; + _list *pscanned; + _queue free_bss_pool; + _queue scanned_queue; + u8 *free_bss_buf; + u16 num_of_scanned; + +#if SUPPORT_SCAN_BUF // Cloud 2013/12/20 + u8 *scan_buf; + u32 scan_buf_len; + u16 scan_cnt; + u16 scan_type; +#endif + + NDIS_802_11_SSID assoc_ssid; + u8 assoc_bssid[6]; + + struct wlan_network cur_network; + + //uint wireless_mode; no used, remove it + + u32 scan_interval; + + _timer assoc_timer; + + u8 assoc_by_bssid; + u8 assoc_by_rssi; + + _timer scan_to_timer; // driver itself handles scan_timeout status. + u32 scan_start_time; // used to evaluate the time spent in scanning + + #ifdef CONFIG_SET_SCAN_DENY_TIMER + _timer set_scan_deny_timer; + ATOMIC_T set_scan_deny; //0: allowed, 1: deny + #endif + + struct qos_priv qospriv; + +#ifdef CONFIG_80211N_HT + + /* Number of non-HT AP/stations */ + u16 num_sta_no_ht; //int num_sta_no_ht; + + /* Number of HT AP/stations 20 MHz */ + //int num_sta_ht_20mhz; + + + u16 num_FortyMHzIntolerant; //int num_FortyMHzIntolerant; + + struct ht_priv htpriv; + +#endif + + RT_LINK_DETECT_T LinkDetectInfo; + _timer dynamic_chk_timer; //dynamic/periodic check timer + + u8 key_mask; //use for ips to set wep key after ips_leave + u8 acm_mask; // for wmm acm mask + u8 ChannelPlan; + RT_SCAN_TYPE scan_mode; // active: 1, passive: 0 + +#ifdef CONFIG_WPS + u8 *wps_probe_req_ie; + u32 wps_probe_req_ie_len; + u8 *wps_assoc_req_ie; + u32 wps_assoc_req_ie_len; +#endif + +#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + /* Number of associated Non-ERP stations (i.e., stations using 802.11b + * in 802.11g BSS) */ + u16 num_sta_non_erp; + + /* Number of associated stations that do not support Short Slot Time */ + u16 num_sta_no_short_slot_time; + + /* Number of associated stations that do not support Short Preamble */ + u16 num_sta_no_short_preamble; + + //int olbc; /* Overlapping Legacy BSS Condition */ + + /* Number of HT associated stations that do not support greenfield */ + u16 num_sta_ht_no_gf; + + /* Number of associated non-HT stations */ + //int num_sta_no_ht; + + /* Number of HT associated stations 20 MHz */ + u16 num_sta_ht_20mhz; + + /* Overlapping BSS information */ + u8 olbc_ht; + +#ifdef CONFIG_80211N_HT + u16 ht_op_mode; +#endif /* CONFIG_80211N_HT */ + +#ifdef CONFIG_WPS + u8 *wps_beacon_ie; + u8 *wps_probe_resp_ie; + u8 *wps_assoc_resp_ie; // for CONFIG_IOCTL_CFG80211, this IE could include p2p ie + + u32 wps_beacon_ie_len; + u32 wps_probe_resp_ie_len; + u32 wps_assoc_resp_ie_len; + + +#ifdef CONFIG_P2P_NEW + u8 *p2p_beacon_ie; + u8 *p2p_probe_req_ie; + u8 *p2p_probe_resp_ie; +// u8 *p2p_go_probe_resp_ie; //for GO + u8 *p2p_assoc_req_ie; + u8 *p2p_assoc_rsp_ie; + + u32 p2p_beacon_ie_len; + u32 p2p_probe_req_ie_len; + u32 p2p_probe_resp_ie_len; +// u32 p2p_go_probe_resp_ie_len; //for GO + u32 p2p_assoc_req_ie_len; + u32 p2p_assoc_rsp_ie_len; +#endif //CONFIG_P2P +#endif //CONFIG_WPS + + _lock bcn_update_lock; + u8 update_bcn; +#if USE_DEDICATED_BCN_TX + //Dedicated xmit frame and buffer for beacon update - Alex Fang + struct xmit_frame bcn_xmit_frame; + struct xmit_buf bcn_xmit_buf; + //u8 bcn_buf[256]; + u8 bcn_buf[320]; //p2p go beacon size is about 272+32 bytes +#endif +#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) + +#ifdef RTK_DMP_PLATFORM + // DMP kobject_hotplug function signal need in passive level + _workitem Linkup_workitem; + _workitem Linkdown_workitem; +#endif + +#ifdef CONFIG_INTEL_WIDI + int widi_state; + int listen_state; + _timer listen_timer; + ATOMIC_T rx_probe_rsp; // 1:receive probe respone from RDS source. + u8 *l2sdTaBuffer; + u8 channel_idx; + u8 group_cnt; //In WiDi 3.5, they specified another scan algo. for WFD/RDS co-existed + u8 sa_ext[L2SDTA_SERVICE_VE_LEN]; +#endif // CONFIG_INTEL_WIDI + +#ifdef CONFIG_CONCURRENT_MODE + u8 scanning_via_buddy_intf; +#endif + +#ifdef CONFIG_FTP_PROTECT + u8 ftp_lock_flag; +#endif //CONFIG_FTP_PROTECT + +#ifdef CONFIG_MULTICAST + u32 multicast_list[MULTICAST_LIST_SIZE]; +#endif + //For fast reconnection to keep frame info temporarily + union recv_frame *p_copy_recv_frame; +}; + +#ifdef CONFIG_AP_MODE + +struct hostapd_priv +{ + _adapter *padapter; + +#ifdef CONFIG_HOSTAPD_MLME + struct net_device *pmgnt_netdev; + struct usb_anchor anchored; +#endif + +}; + +extern int hostapd_mode_init(_adapter *padapter); +extern void hostapd_mode_unload(_adapter *padapter); +#endif + + +extern void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf); +extern void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_atimdone_event_callback(_adapter *adapter, u8 *pbuf); +extern void rtw_cpwm_event_callback(_adapter *adapter, u8 *pbuf); + +#ifdef PLATFORM_WINDOWS +extern thread_return event_thread(void *context); + +extern void rtw_join_timeout_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); + +extern void _rtw_scan_timeout_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); + +#endif + +#if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD) +extern int event_thread(void *context); +extern void rtw_join_timeout_handler(void* FunctionContext); +extern void _rtw_scan_timeout_handler(void* FunctionContext); +#endif + +extern void rtw_free_network_queue(_adapter *adapter,u8 isfreeall); +extern int rtw_init_mlme_priv(_adapter *adapter);// (struct mlme_priv *pmlmepriv); + +extern void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv); + + +extern sint rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv); +extern sint rtw_set_key(_adapter *adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx); +extern sint rtw_set_auth(_adapter *adapter,struct security_priv *psecuritypriv); +extern sint rtw_linked_check(_adapter *padapter); + +__inline static u8 *get_bssid(struct mlme_priv *pmlmepriv) +{ //if sta_mode:pmlmepriv->cur_network.network.MacAddress=> bssid + // if adhoc_mode:pmlmepriv->cur_network.network.MacAddress=> ibss mac address + return pmlmepriv->cur_network.network.MacAddress; +} + +__inline static sint check_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + if (pmlmepriv->fw_state & state) + return _TRUE; + + return _FALSE; +} + +__inline static sint get_fwstate(struct mlme_priv *pmlmepriv) +{ + return pmlmepriv->fw_state; +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + * + * ### NOTE:#### (!!!!) + * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock + */ +__inline static void set_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state |= state; + //FOR HW integration + if(_FW_UNDER_SURVEY==state){ + pmlmepriv->bScanInProcess = _TRUE; + } +} + +__inline static void _clr_fwstate_(struct mlme_priv *pmlmepriv, sint state) +{ + pmlmepriv->fw_state &= ~state; + //FOR HW integration + if(_FW_UNDER_SURVEY==state){ + pmlmepriv->bScanInProcess = _FALSE; + } +} + +/* + * No Limit on the calling context, + * therefore set it to be the critical section... + */ +__inline static void clr_fwstate(struct mlme_priv *pmlmepriv, sint state) +{ + _irqL irqL; + + rtw_enter_critical_bh(&pmlmepriv->lock, &irqL); + if (check_fwstate(pmlmepriv, state) == _TRUE) + pmlmepriv->fw_state ^= state; + rtw_exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void clr_fwstate_ex(struct mlme_priv *pmlmepriv, sint state) +{ + _irqL irqL; + + rtw_enter_critical_bh(&pmlmepriv->lock, &irqL); + _clr_fwstate_(pmlmepriv, state); + rtw_exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void up_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + rtw_enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned++; + rtw_exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +#ifdef CONFIG_CONCURRENT_MODE +sint rtw_buddy_adapter_up(_adapter *padapter); +sint check_buddy_fwstate(_adapter *padapter, sint state); +#endif //CONFIG_CONCURRENT_MODE + +__inline static void down_scanned_network(struct mlme_priv *pmlmepriv) +{ + _irqL irqL; + + rtw_enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned--; + rtw_exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +__inline static void set_scanned_network_val(struct mlme_priv *pmlmepriv, sint val) +{ + _irqL irqL; + + rtw_enter_critical_bh(&pmlmepriv->lock, &irqL); + pmlmepriv->num_of_scanned = val; + rtw_exit_critical_bh(&pmlmepriv->lock, &irqL); +} + +extern u16 rtw_get_capability(WLAN_BSSID_EX *bss); +extern void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target); +extern void rtw_disconnect_hdl_under_linked(_adapter* adapter, struct sta_info *psta, u8 free_assoc); +extern void rtw_generate_random_ibss(u8 *pibss); +extern struct wlan_network* rtw_find_network(_queue *scanned_queue, u8 *addr); +extern struct wlan_network* rtw_get_oldest_wlan_network(_queue *scanned_queue); + +extern void rtw_free_assoc_resources(_adapter* adapter, int lock_scanned_queue); +extern void rtw_indicate_disconnect(_adapter* adapter); +extern void rtw_indicate_connect(_adapter* adapter); +void rtw_indicate_scan_done( _adapter *padapter, bool aborted); +void rtw_scan_abort(_adapter *adapter); + +extern int rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie,u8 *out_ie,uint in_len); +extern int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len); +//extern void rtw_init_registrypriv_dev_network(_adapter *adapter); + +//extern void rtw_update_registrypriv_dev_network(_adapter *adapter); + +extern void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter); + +extern void _rtw_join_timeout_handler(_adapter *adapter); +extern void rtw_scan_timeout_handler(_adapter *adapter); + +extern void rtw_dynamic_check_timer_handlder(_adapter *adapter); +#ifdef CONFIG_SET_SCAN_DENY_TIMER +extern void rtw_set_scan_deny_timer_hdl(_adapter *adapter); +void rtw_set_scan_deny(struct mlme_priv *mlmepriv, u32 ms); +#endif + + +extern int _rtw_init_mlme_priv(_adapter *padapter); + +void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); + +extern void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); + +extern int _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); + +extern struct wlan_network* _rtw_dequeue_network(_queue *queue); + +extern struct wlan_network* _rtw_alloc_network(struct mlme_priv *pmlmepriv); + + +extern void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 isfreeall); +extern void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork); + + +extern struct wlan_network* _rtw_find_network(_queue *scanned_queue, u8 *addr); + +extern void _rtw_free_network_queue(_adapter* padapter, u8 isfreeall); + +extern sint rtw_if_up(_adapter *padapter); + + +u8 *rtw_get_capability_from_ie(u8 *ie); +u8 *rtw_get_timestampe_from_ie(u8 *ie); +u8 *rtw_get_beacon_interval_from_ie(u8 *ie); + + +void rtw_joinbss_reset(_adapter *padapter); + +#ifdef CONFIG_80211N_HT +unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len); +void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len); +void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif + +int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork); +int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst); + +#ifdef CONFIG_LAYER2_ROAMING +void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network); +void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network); +#endif + + +#ifdef CONFIG_INTEL_PROXIM +void rtw_proxim_enable(_adapter *padapter); +void rtw_proxim_disable(_adapter *padapter); +void rtw_proxim_send_packet(_adapter *padapter,u8 *pbuf,u16 len,u8 hw_rate); +#endif //CONFIG_INTEL_PROXIM + +extern void rtw_os_indicate_disconnect( _adapter *adapter ); +extern void rtw_os_indicate_scan_done( _adapter *padapter, bool aborted); +extern void rtw_reset_securitypriv( _adapter *adapter ); +#endif //__RTL871X_MLME_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme_ext.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme_ext.h new file mode 100644 index 0000000..4d14c3d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_mlme_ext.h @@ -0,0 +1,1014 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_MLME_EXT_H_ +#define __RTW_MLME_EXT_H_ + + +// Commented by Albert 20101105 +// Increase the SURVEY_TO value from 100 to 150 ( 100ms to 150ms ) +// The Realtek 8188CE SoftAP will spend around 100ms to send the probe response after receiving the probe request. +// So, this driver tried to extend the dwell time for each scanning channel. +// This will increase the chance to receive the probe response from SoftAP. + +#if CONFIG_AUTO_RECONNECT + +#endif + +//TODO +#define FAST_SURVEY_TO (25) //Fast connection time, scan only partial channel +#define SURVEY_TO (100) //Reduce connection time +//#define SURVEY_TO (300) //Increase time to stay each channel - Alex Fang +#define REAUTH_TO (300) //(50) +#define REASSOC_TO (300) //(50) +//#define DISCONNECT_TO (3000) +#define ADDBA_TO (2000) + +#define LINKED_TO (1) //unit:2 sec, 1x2=2 sec + +#define REAUTH_LIMIT (4) +#define REASSOC_LIMIT (4) +#define READDBA_LIMIT (2) + +#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) + #define ROAMING_LIMIT 5 +#else + #define ROAMING_LIMIT 8 +#endif +//#define IOCMD_REG0 0x10250370 +//#define IOCMD_REG1 0x10250374 +//#define IOCMD_REG2 0x10250378 + +//#define FW_DYNAMIC_FUN_SWITCH 0x10250364 + +//#define WRITE_BB_CMD 0xF0000001 +//#define SET_CHANNEL_CMD 0xF3000000 +//#define UPDATE_RA_CMD 0xFD0000A2 + +#define _HW_STATE_NOLINK_ 0x00 +#define _HW_STATE_ADHOC_ 0x01 +#define _HW_STATE_STATION_ 0x02 +#define _HW_STATE_AP_ 0x03 +#define _HW_STATE_MONITOR_ 0x04 + + +#define _1M_RATE_ 0 +#define _2M_RATE_ 1 +#define _5M_RATE_ 2 +#define _11M_RATE_ 3 +#define _6M_RATE_ 4 +#define _9M_RATE_ 5 +#define _12M_RATE_ 6 +#define _18M_RATE_ 7 +#define _24M_RATE_ 8 +#define _36M_RATE_ 9 +#define _48M_RATE_ 10 +#define _54M_RATE_ 11 + +#define MAX_COUNTRY_NUM 250 + +extern const u8 WMM_OUI[]; +extern const u8 WPS_OUI[]; +extern const u8 WFD_OUI[]; +extern const u8 P2P_OUI[]; + +//extern const unsigned char WMM_INFO_OUI[]; +extern const u8 WMM_PARA_OUI[]; + + +// +// Channel Plan Type. +// Note: +// We just add new channel plan when the new channel plan is different from any of the following +// channel plan. +// If you just wnat to customize the acitions(scan period or join actions) about one of the channel plan, +// customize them in RT_CHANNEL_INFO in the RT_CHANNEL_LIST. +// +typedef enum _RT_CHANNEL_DOMAIN +{ + //===== old channel plan mapping =====// + RT_CHANNEL_DOMAIN_FCC = 0x00, + RT_CHANNEL_DOMAIN_IC = 0x01, + RT_CHANNEL_DOMAIN_ETSI = 0x02, + RT_CHANNEL_DOMAIN_SPAIN = 0x03, + RT_CHANNEL_DOMAIN_FRANCE = 0x04, + RT_CHANNEL_DOMAIN_MKK = 0x05, + RT_CHANNEL_DOMAIN_MKK1 = 0x06, + RT_CHANNEL_DOMAIN_ISRAEL = 0x07, + RT_CHANNEL_DOMAIN_TELEC = 0x08, + RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x09, + RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0x0A, + RT_CHANNEL_DOMAIN_TAIWAN = 0x0B, + RT_CHANNEL_DOMAIN_CHINA = 0x0C, + RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0x0D, + RT_CHANNEL_DOMAIN_KOREA = 0x0E, + RT_CHANNEL_DOMAIN_TURKEY = 0x0F, + RT_CHANNEL_DOMAIN_JAPAN = 0x10, + RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11, + RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12, + RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = 0x13, + RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14, + + //===== new channel plan mapping, (2GDOMAIN_5GDOMAIN) =====// + // 2.4 G only + RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, // ETSI, MKK ch1~13 + RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21, + RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22, // FCC ch1~11 + RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23, // MKK ch1~14 + RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24, + // 2.4 G + 5G type 1 + RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25, + RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26, + RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27, + RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28, + RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29, + RT_CHANNEL_DOMAIN_FCC2_NULL = 0x2A, // FCC ch1~13 + RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30, + RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31, + RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32, + RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33, + RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34, + RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35, + RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36, + RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37, + RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38, + RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39, + RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40, + RT_CHANNEL_DOMAIN_GLOBAL_NULL = 0x41, + RT_CHANNEL_DOMAIN_ETSI1_ETSI4 = 0x42, + RT_CHANNEL_DOMAIN_FCC1_FCC2 = 0x43, + RT_CHANNEL_DOMAIN_FCC1_NCC3 = 0x44, + RT_CHANNEL_DOMAIN_WORLD_ETSI5 = 0x45, + RT_CHANNEL_DOMAIN_FCC1_FCC8 = 0x46, + RT_CHANNEL_DOMAIN_WORLD_ETSI6 = 0x47, // ETSI, MKK, FCC ch1~13 + RT_CHANNEL_DOMAIN_WORLD_ETSI7 = 0x48, + RT_CHANNEL_DOMAIN_WORLD_ETSI8 = 0x49, + RT_CHANNEL_DOMAIN_WORLD_ETSI9 = 0x50, + RT_CHANNEL_DOMAIN_WORLD_ETSI10 = 0x51, + RT_CHANNEL_DOMAIN_WORLD_ETSI11 = 0x52, + RT_CHANNEL_DOMAIN_FCC1_NCC4 = 0x53, + RT_CHANNEL_DOMAIN_WORLD_ETSI12 = 0x54, + RT_CHANNEL_DOMAIN_FCC1_FCC9 = 0x55, + RT_CHANNEL_DOMAIN_WORLD_ETSI13 = 0x56, + RT_CHANNEL_DOMAIN_FCC1_FCC10 = 0x57, + RT_CHANNEL_DOMAIN_MKK2_MKK4 = 0x58, // MKK ch1~13 + //===== Add new channel plan above this line===============// + RT_CHANNEL_DOMAIN_MAX, + RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, +}RT_CHANNEL_DOMAIN, *PRT_CHANNEL_DOMAIN; + +typedef enum _RT_CHANNEL_DOMAIN_2G +{ + RT_CHANNEL_DOMAIN_2G_WORLD1 = 0x00, //Worldwird 13, ch1~13 (ETSI, MKK) + RT_CHANNEL_DOMAIN_2G_ETSI1 = 0x01, //Europe, ch1~13 + RT_CHANNEL_DOMAIN_2G_FCC1 = 0x02, //US, ch1~11 + RT_CHANNEL_DOMAIN_2G_MKK1 = 0x03, //Japan, ch1~14 + RT_CHANNEL_DOMAIN_2G_ETSI2 = 0x04, //France, ch10~13 + RT_CHANNEL_DOMAIN_2G_RCC2 = 0x05, //US, ch1~13 + RT_CHANNEL_DOMAIN_2G_MKK2 = 0x06, //Japan, ch1~13 + RT_CHANNEL_DOMAIN_2G_WORLD2 = 0x07, //Worldwird 13, ch1~13 (ETSI, MKK, FCC) + //===== Add new channel plan above this line===============// + RT_CHANNEL_DOMAIN_2G_MAX, +}RT_CHANNEL_DOMAIN_2G, *PRT_CHANNEL_DOMAIN_2G; + +typedef enum _RT_CHANNEL_DOMAIN_5G +{ + RT_CHANNEL_DOMAIN_5G_NULL = 0x00, + RT_CHANNEL_DOMAIN_5G_ETSI1 = 0x01, //Europe + RT_CHANNEL_DOMAIN_5G_ETSI2 = 0x02, //Australia, New Zealand + RT_CHANNEL_DOMAIN_5G_ETSI3 = 0x03, //Russia + RT_CHANNEL_DOMAIN_5G_FCC1 = 0x04, //US + RT_CHANNEL_DOMAIN_5G_FCC2 = 0x05, //FCC o/w DFS Channels + RT_CHANNEL_DOMAIN_5G_FCC3 = 0x06, //India, Mexico + RT_CHANNEL_DOMAIN_5G_FCC4 = 0x07, //Venezuela + RT_CHANNEL_DOMAIN_5G_FCC5 = 0x08, //China + RT_CHANNEL_DOMAIN_5G_FCC6 = 0x09, //Israel + RT_CHANNEL_DOMAIN_5G_FCC7_IC1 = 0x0A, //US, Canada + RT_CHANNEL_DOMAIN_5G_KCC1 = 0x0B, //Korea + RT_CHANNEL_DOMAIN_5G_MKK1 = 0x0C, //Japan + RT_CHANNEL_DOMAIN_5G_MKK2 = 0x0D, //Japan (W52, W53) + RT_CHANNEL_DOMAIN_5G_MKK3 = 0x0E, //Japan (W56) + RT_CHANNEL_DOMAIN_5G_NCC1 = 0x0F, //Taiwan + RT_CHANNEL_DOMAIN_5G_NCC2 = 0x10, //Taiwan o/w DFS + //===== Add new channel plan above this line===============// + //===== Driver Self Defined =====// + RT_CHANNEL_DOMAIN_5G_FCC = 0x11, + RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS = 0x12, + RT_CHANNEL_DOMAIN_5G_MAX, +}RT_CHANNEL_DOMAIN_5G, *PRT_CHANNEL_DOMAIN_5G; + +#define rtw_is_channel_plan_valid(chplan) (chplancur_network.network. YJ,del,140408 + struct FW_Sta_Info FW_sta_info[NUM_STA]; + +#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE + u8 scan_cnt; +#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE +}; + +// The channel information about this channel including joining, scanning, and power constraints. +#define PSCAN_ENABLE 0x01 //enable for partial channel scan +#define PSCAN_FAST_SURVEY 0x02 //set to select scan time to FAST_SURVEY_TO and resend probe request +#define PSCAN_SIMPLE_CONFIG 0x04 //set to select scan time to FAST_SURVEY_TO and resend probe request +#define PSCAN_SET_SSID_DONE 0x80 //When receive probe response, this bit is set to 1 + +#define PSCAN_DISABLE_MASK 0xFE //disable PSCAN_ENABLE +#define PSCAN_CLEAR_SSID_DONE 0x7F //clear PSCAN_SET_SSID_DONE +#define PSCAN_RETRY_TIMES 7 //the retry times of resending probe request when PSCAN_FAST_SURVEY is set + +typedef struct _RT_CHANNEL_INFO +{ + u8 ChannelNum; // The channel number. + RT_SCAN_TYPE ScanType; // Scan type such as passive or active scan. + //u16 ScanPeriod; // Listen time in millisecond in this channel. + //s32 MaxTxPwrDbm; // Max allowed tx power. + //u32 ExInfo; // Extended Information for this channel. +#ifdef CONFIG_FIND_BEST_CHANNEL + u32 rx_count; +#endif + u8 pscan_config; +}RT_CHANNEL_INFO, *PRT_CHANNEL_INFO; + +extern int rtw_is_channel_set_contains_channel(RT_CHANNEL_INFO *channel_set, const u32 channel_num, int *pchannel_idx); + +//#ifdef CONFIG_CUSTOM_IE +//#ifndef _CUS_IE_ +//#define _CUS_IE_ +typedef struct __cus_ie +{ + u8 *ie; + u8 type; +}_rtw_custom_ie_t, *_p_rtw_custom_ie_t; +//#endif /* _CUS_IE_ */ +//#endif + +struct mlme_ext_priv +{ + _adapter *padapter; + u8 mlmeext_init; + ATOMIC_T event_seq; + u16 mgnt_seq; + + //struct fw_priv fwpriv; + + u8 cur_channel; + u8 cur_bwmode; + u8 cur_ch_offset;//PRIME_CHNL_OFFSET + u8 cur_wireless_mode; // NETWORK_TYPE + u8 max_chan_nums; + RT_CHANNEL_INFO channel_set[MAX_CHANNEL_NUM]; +#ifdef CONFIG_P2P_NEW + RT_CHANNEL_INFO social_channel_set[4]; + RT_CHANNEL_INFO special_channel[2]; + u8 special_mac[ETH_ALEN]; + u16 scan_mode; + u8 bremain_on_channel; + _timer remainon_timer; +#endif + u8 basicrate[NumRates]; + u8 datarate[NumRates]; + + struct ss_res sitesurvey_res; + struct mlme_ext_info mlmext_info;//for sta/adhoc mode, including current scanning/connecting/connected related info. + //for ap mode, network includes ap's cap_info + _timer survey_timer; + _timer link_timer; + //_timer ADDBA_timer; + u16 chan_scan_time; + + u8 scan_abort; + u8 tx_rate; // TXRATE when USERATE is set. + + u8 retry; //retry for issue probereq + + u64 TSFValue; + +#ifdef CONFIG_AP_MODE + unsigned char bstart_bss; +#endif + +#ifdef CONFIG_80211D + u8 update_channel_plan_by_ap_done; +#endif + //recv_decache check for Action_public frame + u16 action_public_rxseq; + + /* for softap power save */ +#ifdef CONFIG_P2P_NEW + u8 action_public_dialog_token; +#endif +#if CONFIG_AUTO_RECONNECT + _timer reconnect_timer; + u8 reconnect_deauth_filtered; + u8 reconnect_times; + u8 reconnect_cnt; + u16 reconnect_timeout; // the unit is second + u8 saved_alg; + u8 saved_essid[32+1]; + u8 saved_key[32]; + u16 saved_key_len; + u8 saved_key_idx; + u8 saved_wpa_passphrase[IW_PASSPHRASE_MAX_SIZE + 1]; + u8 saved_eap_method; + u8 auto_reconnect; +#endif + u8 partial_scan; +#ifdef CONFIG_CUSTOM_IE + _p_rtw_custom_ie_t cus_ven_ie; + u8 ie_num; +#endif + +#ifdef CONFIG_CONCURRENT_MODE + u8 bChDeauthDisabled; + u8 bConcurrentFlushingSTA; +#endif +}; + +int init_mlme_ext_priv(_adapter* padapter); +int init_hw_mlme_ext(_adapter *padapter); +void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext); +extern void init_mlme_ext_timer(_adapter *padapter); +extern void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta); +extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); +extern struct xmit_frame *alloc_FwRsvdframe(struct xmit_priv *pxmitpriv, u32 size); +//void fill_fwpriv(_adapter * padapter, struct fw_priv *pfwpriv); + +unsigned char networktype_to_raid(unsigned char network_type); +u8 judge_network_type(_adapter *padapter, unsigned char *rate, int ratelen); +void get_rate_set(_adapter *padapter, unsigned char *pbssrate, int *bssrate_len); +void UpdateBrateTbl(_adapter *padapter,u8 *mBratesOS); +void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen); + +void Save_DM_Func_Flag(_adapter *padapter); +void Restore_DM_Func_Flag(_adapter *padapter); +void Switch_DM_Func(_adapter *padapter, u32 mode, u8 enable); + +//void Set_NETYPE1_MSR(_adapter *padapter, u8 type); +//void Set_NETYPE0_MSR(_adapter *padapter, u8 type); +void Set_MSR(_adapter *padapter, u8 type); + +u8 set_opmode(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +void set_channel_bwmode(_adapter *padapter, unsigned char channel, unsigned char channel_offset, unsigned short bwmode); +void SelectChannel(_adapter *padapter, unsigned char channel); +void SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset); + +unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); + +void write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key); +void clear_cam_entry(_adapter *padapter, u8 entry); + +void invalidate_cam_all(_adapter *padapter); +void CAM_empty_entry(PADAPTER Adapter, u8 ucIndex); + + +int allocate_fw_sta_entry(_adapter *padapter); +void flush_all_cam_entry(_adapter *padapter); + +BOOLEAN IsLegal5GChannel(PADAPTER Adapter, u8 channel); + +void site_survey(_adapter *padapter); +u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid); +void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, _adapter * padapter, bool update_ie); + +int get_bsstype(unsigned short capability); +u8* get_my_bssid(WLAN_BSSID_EX *pnetwork); +u16 get_beacon_interval(WLAN_BSSID_EX *bss); + +int is_client_associated_to_ap(_adapter *padapter); +int is_client_associated_to_ibss(_adapter *padapter); +int is_IBSS_empty(_adapter *padapter); + +unsigned char check_assoc_AP(u8 *pframe, uint len); + +int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +#ifdef CONFIG_WFD +int WFD_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +#endif +void WMMOnAssocRsp(_adapter *padapter); + +void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void HTOnAssocRsp(_adapter *padapter); + +void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +void VCS_update(_adapter *padapter, struct sta_info *psta); + +void update_beacon_info(_adapter *padapter, u8 *pframe, uint len, struct sta_info *psta); +int rtw_check_bcn_info(ADAPTER *Adapter, u8 *pframe, u32 packet_len); +#ifdef CONFIG_DFS +void process_csa_ie(_adapter *padapter, u8 *pframe, uint len); +#endif //CONFIG_DFS +void update_IOT_info(_adapter *padapter); +void update_capinfo(PADAPTER Adapter, u16 updateCap); +void update_wireless_mode(_adapter * padapter); +void update_tx_basic_rate(_adapter *padapter, u8 modulation); +void update_bmc_sta_support_rate(_adapter *padapter, u32 mac_id); +int update_sta_support_rate(_adapter *padapter, u8* pvar_ie, uint var_ie_len, int cam_idx); + +//for sta/adhoc mode +void update_sta_info(_adapter *padapter, struct sta_info *psta); +unsigned int update_basic_rate(unsigned char *ptn, unsigned int ptn_sz); +unsigned int update_supported_rate(unsigned char *ptn, unsigned int ptn_sz); +unsigned int update_MCS_rate(struct HT_caps_element *pHT_caps); +void Update_RA_Entry(_adapter *padapter, struct sta_info *psta); +void set_sta_rate(_adapter *padapter, struct sta_info *psta); + +unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason); + +unsigned char get_highest_rate_idx(u32 mask); +int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps); +unsigned int is_ap_in_tkip(_adapter *padapter); +unsigned int is_ap_in_wep(_adapter *padapter); +unsigned int should_forbid_n_rate(_adapter * padapter); + +void report_join_res(_adapter *padapter, int res); +void report_survey_event(_adapter *padapter, union recv_frame *precv_frame); +void report_surveydone_event(_adapter *padapter); +void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason); +void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx); + +void beacon_timing_control(_adapter *padapter); +extern u8 set_tx_beacon_cmd(_adapter*padapter); +unsigned int setup_beacon_frame(_adapter *padapter, unsigned char *beacon_frame); +void update_mgnt_tx_rate(_adapter *padapter, u8 rate); +void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); +s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms); + +#ifdef CONFIG_P2P +void issue_probersp_p2p(_adapter *padapter, unsigned char *da); +void issue_p2p_provision_request( _adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr); +void issue_p2p_GO_request(_adapter *padapter, u8* raddr); +void issue_probereq_p2p(_adapter *padapter); +void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 success); +void issue_p2p_invitation_request(_adapter *padapter, u8* raddr ); +#endif //CONFIG_P2P +void issue_beacon(_adapter *padapter); +void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq); +void issue_assocreq(_adapter *padapter); +void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type); +void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status); +// Added by Albert 2010/07/26 +// blnbc: 1 -> broadcast probe request +// blnbc: 0 -> unicast probe request. The address 1 will be the BSSID. +void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 blnbc); +void issue_nulldata(_adapter *padapter, unsigned int power_mode); +void issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid); +void issue_deauth(_adapter *padapter, unsigned char *da, u32 reason); +void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status); +unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr); +unsigned int send_beacon(_adapter *padapter); + +void start_clnt_assoc(_adapter *padapter); +void start_clnt_auth(_adapter* padapter); +void start_clnt_join(_adapter* padapter); +void start_create_ibss(_adapter* padapter); + +unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame); +unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame); + +unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_public(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame); +unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame); + + +void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res); +void mlmeext_sta_del_event_callback(_adapter *padapter); +void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta); + +void linked_status_chk(_adapter *padapter); + +void survey_timer_hdl (_adapter *padapter); +void link_timer_hdl (_adapter *padapter); +void addba_timer_hdl(struct sta_info *psta); +//void reauth_timer_hdl(_adapter *padapter); +//void reassoc_timer_hdl(_adapter *padapter); + +#define set_survey_timer(mlmeext, ms) \ + do { \ + /*DBG_871X("%s set_survey_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms));*/ \ + rtw_set_timer(&(mlmeext)->survey_timer, (ms)); \ + } while(0) + +#define set_link_timer(mlmeext, ms) \ + do { \ + /*DBG_871X("%s set_link_timer(%p, %d)\n", __FUNCTION__, (mlmeext), (ms));*/ \ + rtw_set_timer(&(mlmeext)->link_timer, (ms)); \ + } while(0) + +//TODO +#if 0 +extern int cckrates_included(unsigned char *rate, int ratelen); +extern int cckratesonly_included(unsigned char *rate, int ratelen); +extern void process_addba_req(_adapter *padapter, u8 *paddba_req, u8 *addr); +#endif + +extern void update_TSF(struct mlme_ext_priv *pmlmeext, u8 *pframe, uint len); +extern void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext); + +#ifdef CONFIG_CONCURRENT_MODE + sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state); +int concurrent_chk_start_clnt_join(_adapter *padapter); +void concurrent_chk_joinbss_done(_adapter *padapter, int join_res); +#endif //CONFIG_CONCURRENT_MODE + + +struct cmd_hdl { + uint parmsize; + u8 (*h2cfuns)(struct _ADAPTER *padapter, u8 *pbuf); +}; + +//TODO +#if 0 + +u8 read_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_macreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_bbreg_hdl(_adapter *padapter, u8 *pbuf); +u8 read_rfreg_hdl(_adapter *padapter, u8 *pbuf); +u8 write_rfreg_hdl(_adapter *padapter, u8 *pbuf); + +#endif //#if 0 + +u8 NULL_hdl(_adapter *padapter, u8 *pbuf); +u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 disconnect_hdl(_adapter *padapter, u8 *pbuf); +u8 createbss_hdl(_adapter *padapter, u8 *pbuf); +u8 setopmode_hdl(_adapter *padapter, u8 *pbuf); +u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf); +u8 setauth_hdl(_adapter *padapter, u8 *pbuf); +u8 setkey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf); +u8 set_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 del_assocsta_hdl(_adapter *padapter, u8 *pbuf); +u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf); + +u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf); +u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf); +u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf); +u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf); +u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf); +u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf); //Kurt: Handling DFS channel switch announcement ie. +u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf); + +#if CONFIG_AUTO_RECONNECT +extern void reconnect_timer_hdl(void *FunctionContext); +#endif + +#define GEN_DRV_CMD_HANDLER(size, cmd) {size, &cmd ## _hdl}, +#define GEN_MLME_EXT_HANDLER(size, cmd) {size, cmd}, + +#ifdef _RTW_CMD_C_ + +const struct cmd_hdl wlancmds[] = +{ + GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_DRV_CMD_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct joinbss_parm), join_cmd_hdl) /*14*/ + GEN_MLME_EXT_HANDLER(sizeof (struct disconnect_parm), disconnect_hdl) +//TODO +// GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), createbss_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct createbss_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setopmode_parm), setopmode_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setauth_parm), setauth_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct setkey_parm), setkey_hdl) /*20*/ + GEN_MLME_EXT_HANDLER(sizeof (struct set_stakey_parm), set_stakey_hdl) + GEN_MLME_EXT_HANDLER(sizeof (struct set_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct del_assocsta_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setstapwrstate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getbasicrate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getdatarate_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct setphyinfo_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphyinfo_parm), NULL) /*30*/ + GEN_MLME_EXT_HANDLER(sizeof (struct setphy_parm), NULL) + GEN_MLME_EXT_HANDLER(sizeof (struct getphy_parm), NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) +//TODO +#if RX_AGGREGATION + GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) +#else + GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), NULL) +#endif + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(0, NULL) + GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ + GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ + GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ +//TODO +// GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ + GEN_MLME_EXT_HANDLER(0, NULL) /*58*/ +//TODO +// GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ + GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), NULL) /*59*/ +//TODO +// GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/ + GEN_MLME_EXT_HANDLER(0, NULL) /*60*/ +//TODO +// GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*61*/ + GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), NULL) /*61*/ +//TODO +// GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/ + GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), NULL) /*62*/ +#ifdef CONFIG_P2P_NEW + GEN_MLME_EXT_HANDLER(0, rtw_p2p_cmd_hdl) /*63*/ +#endif +}; + +#endif + +struct C2HEvent_Header +{ + +#ifdef CONFIG_LITTLE_ENDIAN + + unsigned int len:16; + unsigned int ID:8; + unsigned int seq:8; + +#elif defined(CONFIG_BIG_ENDIAN) + + unsigned int seq:8; + unsigned int ID:8; + unsigned int len:16; + +#else + +# error "Must be LITTLE or BIG Endian" + +#endif + + unsigned int rsvd; + +}; + +void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf); +void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf); + +enum rtw_c2h_event +{ + GEN_EVT_CODE(_Read_MACREG)=0, /*0*/ + GEN_EVT_CODE(_Read_BBREG), + GEN_EVT_CODE(_Read_RFREG), + GEN_EVT_CODE(_Read_EEPROM), + GEN_EVT_CODE(_Read_EFUSE), + GEN_EVT_CODE(_Read_CAM), /*5*/ + GEN_EVT_CODE(_Get_BasicRate), + GEN_EVT_CODE(_Get_DataRate), + GEN_EVT_CODE(_Survey), /*8*/ + GEN_EVT_CODE(_SurveyDone), /*9*/ + + GEN_EVT_CODE(_JoinBss) , /*10*/ + GEN_EVT_CODE(_AddSTA), + GEN_EVT_CODE(_DelSTA), + GEN_EVT_CODE(_AtimDone) , + GEN_EVT_CODE(_TX_Report), + GEN_EVT_CODE(_CCX_Report), /*15*/ + GEN_EVT_CODE(_DTM_Report), + GEN_EVT_CODE(_TX_Rate_Statistics), + GEN_EVT_CODE(_C2HLBK), + GEN_EVT_CODE(_FWDBG), + GEN_EVT_CODE(_C2HFEEDBACK), /*20*/ + GEN_EVT_CODE(_ADDBA), + GEN_EVT_CODE(_C2HBCN), + GEN_EVT_CODE(_ReportPwrState), //filen: only for PCIE, USB + GEN_EVT_CODE(_CloseRF), //filen: only for PCIE, work around ASPM + MAX_C2HEVT +}; + + +#ifdef _RTW_MLME_EXT_C_ + +const static struct fwevent wlanevents[] = +{ + {0, rtw_dummy_event_callback}, /*0*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, NULL}, + {0, &rtw_survey_event_callback}, /*8*/ + {sizeof (struct surveydone_event), &rtw_surveydone_event_callback}, /*9*/ + {0, &rtw_joinbss_event_callback}, /*10*/ + {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, + {sizeof(struct stadel_event), &rtw_stadel_event_callback}, +//TODO +// {0, &rtw_atimdone_event_callback}, + {0, NULL}, /*rtw_atimdone_event_callback*/ + {0, rtw_dummy_event_callback}, + {0, NULL}, /*15*/ + {0, NULL}, + {0, NULL}, + {0, NULL}, +//TODO +// {0, rtw_fwdbg_event_callback}, + {0, NULL}, /*rtw_fwdbg_event_callback*/ + {0, NULL}, /*20*/ + {0, NULL}, + {0, NULL}, +//TODO +// {0, &rtw_cpwm_event_callback}, + {0, NULL}, /*rtw_cpwm_event_callback*/ +}; + +#endif//_RTL8192C_CMD_C_ + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_mp.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_mp.h new file mode 100644 index 0000000..f8f8253 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_mp.h @@ -0,0 +1,722 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_MP_H_ +#define _RTW_MP_H_ + +#ifndef PLATFORM_WINDOWS +// 00 - Success +// 11 - Error +#define STATUS_SUCCESS (0x00000000L) +#define STATUS_PENDING (0x00000103L) + +#define STATUS_UNSUCCESSFUL (0xC0000001L) +#define STATUS_INSUFFICIENT_RESOURCES (0xC000009AL) +#define STATUS_NOT_SUPPORTED (0xC00000BBL) + +#define NDIS_STATUS_SUCCESS ((NDIS_STATUS)STATUS_SUCCESS) +#define NDIS_STATUS_PENDING ((NDIS_STATUS)STATUS_PENDING) +#define NDIS_STATUS_NOT_RECOGNIZED ((NDIS_STATUS)0x00010001L) +#define NDIS_STATUS_NOT_COPIED ((NDIS_STATUS)0x00010002L) +#define NDIS_STATUS_NOT_ACCEPTED ((NDIS_STATUS)0x00010003L) +#define NDIS_STATUS_CALL_ACTIVE ((NDIS_STATUS)0x00010007L) + +#define NDIS_STATUS_FAILURE ((NDIS_STATUS)STATUS_UNSUCCESSFUL) +#define NDIS_STATUS_RESOURCES ((NDIS_STATUS)STATUS_INSUFFICIENT_RESOURCES) +#define NDIS_STATUS_CLOSING ((NDIS_STATUS)0xC0010002L) +#define NDIS_STATUS_BAD_VERSION ((NDIS_STATUS)0xC0010004L) +#define NDIS_STATUS_BAD_CHARACTERISTICS ((NDIS_STATUS)0xC0010005L) +#define NDIS_STATUS_ADAPTER_NOT_FOUND ((NDIS_STATUS)0xC0010006L) +#define NDIS_STATUS_OPEN_FAILED ((NDIS_STATUS)0xC0010007L) +#define NDIS_STATUS_DEVICE_FAILED ((NDIS_STATUS)0xC0010008L) +#define NDIS_STATUS_MULTICAST_FULL ((NDIS_STATUS)0xC0010009L) +#define NDIS_STATUS_MULTICAST_EXISTS ((NDIS_STATUS)0xC001000AL) +#define NDIS_STATUS_MULTICAST_NOT_FOUND ((NDIS_STATUS)0xC001000BL) +#define NDIS_STATUS_REQUEST_ABORTED ((NDIS_STATUS)0xC001000CL) +#define NDIS_STATUS_RESET_IN_PROGRESS ((NDIS_STATUS)0xC001000DL) +#define NDIS_STATUS_CLOSING_INDICATING ((NDIS_STATUS)0xC001000EL) +#define NDIS_STATUS_NOT_SUPPORTED ((NDIS_STATUS)STATUS_NOT_SUPPORTED) +#define NDIS_STATUS_INVALID_PACKET ((NDIS_STATUS)0xC001000FL) +#define NDIS_STATUS_OPEN_LIST_FULL ((NDIS_STATUS)0xC0010010L) +#define NDIS_STATUS_ADAPTER_NOT_READY ((NDIS_STATUS)0xC0010011L) +#define NDIS_STATUS_ADAPTER_NOT_OPEN ((NDIS_STATUS)0xC0010012L) +#define NDIS_STATUS_NOT_INDICATING ((NDIS_STATUS)0xC0010013L) +#define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L) +#define NDIS_STATUS_INVALID_DATA ((NDIS_STATUS)0xC0010015L) +#define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L) +#define NDIS_STATUS_INVALID_OID ((NDIS_STATUS)0xC0010017L) +#define NDIS_STATUS_ADAPTER_REMOVED ((NDIS_STATUS)0xC0010018L) +#define NDIS_STATUS_UNSUPPORTED_MEDIA ((NDIS_STATUS)0xC0010019L) +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE ((NDIS_STATUS)0xC001001AL) +#define NDIS_STATUS_FILE_NOT_FOUND ((NDIS_STATUS)0xC001001BL) +#define NDIS_STATUS_ERROR_READING_FILE ((NDIS_STATUS)0xC001001CL) +#define NDIS_STATUS_ALREADY_MAPPED ((NDIS_STATUS)0xC001001DL) +#define NDIS_STATUS_RESOURCE_CONFLICT ((NDIS_STATUS)0xC001001EL) +#define NDIS_STATUS_NO_CABLE ((NDIS_STATUS)0xC001001FL) + +#define NDIS_STATUS_INVALID_SAP ((NDIS_STATUS)0xC0010020L) +#define NDIS_STATUS_SAP_IN_USE ((NDIS_STATUS)0xC0010021L) +#define NDIS_STATUS_INVALID_ADDRESS ((NDIS_STATUS)0xC0010022L) +#define NDIS_STATUS_VC_NOT_ACTIVATED ((NDIS_STATUS)0xC0010023L) +#define NDIS_STATUS_DEST_OUT_OF_ORDER ((NDIS_STATUS)0xC0010024L) // cause 27 +#define NDIS_STATUS_VC_NOT_AVAILABLE ((NDIS_STATUS)0xC0010025L) // cause 35,45 +#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE ((NDIS_STATUS)0xC0010026L) // cause 37 +#define NDIS_STATUS_INCOMPATABLE_QOS ((NDIS_STATUS)0xC0010027L) // cause 49 +#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED ((NDIS_STATUS)0xC0010028L) // cause 93 +#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION ((NDIS_STATUS)0xC0010029L) // cause 3 +#endif /* #ifndef PLATFORM_WINDOWS */ + +#if 0 +#define MPT_NOOP 0 +#define MPT_READ_MAC_1BYTE 1 +#define MPT_READ_MAC_2BYTE 2 +#define MPT_READ_MAC_4BYTE 3 +#define MPT_WRITE_MAC_1BYTE 4 +#define MPT_WRITE_MAC_2BYTE 5 +#define MPT_WRITE_MAC_4BYTE 6 +#define MPT_READ_BB_CCK 7 +#define MPT_WRITE_BB_CCK 8 +#define MPT_READ_BB_OFDM 9 +#define MPT_WRITE_BB_OFDM 10 +#define MPT_READ_RF 11 +#define MPT_WRITE_RF 12 +#define MPT_READ_EEPROM_1BYTE 13 +#define MPT_WRITE_EEPROM_1BYTE 14 +#define MPT_READ_EEPROM_2BYTE 15 +#define MPT_WRITE_EEPROM_2BYTE 16 +#define MPT_SET_CSTHRESHOLD 21 +#define MPT_SET_INITGAIN 22 +#define MPT_SWITCH_BAND 23 +#define MPT_SWITCH_CHANNEL 24 +#define MPT_SET_DATARATE 25 +#define MPT_SWITCH_ANTENNA 26 +#define MPT_SET_TX_POWER 27 +#define MPT_SET_CONT_TX 28 +#define MPT_SET_SINGLE_CARRIER 29 +#define MPT_SET_CARRIER_SUPPRESSION 30 +#define MPT_GET_RATE_TABLE 31 +#define MPT_READ_TSSI 32 +#define MPT_GET_THERMAL_METER 33 +#endif + +typedef enum _ANTENNA_PATH{ + ANTENNA_NONE = 0x00, + ANTENNA_D , + ANTENNA_C , + ANTENNA_CD , + ANTENNA_B , + ANTENNA_BD , + ANTENNA_BC , + ANTENNA_BCD , + ANTENNA_A , + ANTENNA_AD , + ANTENNA_AC , + ANTENNA_ACD , + ANTENNA_AB , + ANTENNA_ABD , + ANTENNA_ABC , + ANTENNA_ABCD +} ANTENNA_PATH; + + +#define MAX_MP_XMITBUF_SZ 2048 +#define NR_MP_XMITFRAME 8 + +struct mp_xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + +#ifdef CONFIG_USB_HCI + + //insert urb, irp, and irpcnt info below... + //max frag_cnt = 8 + + u8 *mem_addr; + u32 sz[8]; + +#if defined(PLATFORM_OS_XP) || defined(PLATFORM_LINUX) + PURB pxmit_urb[8]; +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + + u8 bpending[8]; + s32 ac_tag[8]; + s32 last[8]; + uint irpcnt; + uint fragcnt; +#endif /* CONFIG_USB_HCI */ + + uint mem[(MAX_MP_XMITBUF_SZ >> 2)]; +}; + +struct mp_wiparam +{ + u32 bcompleted; + u32 act_type; + u32 io_offset; + u32 io_value; +}; + +typedef void(*wi_act_func)(void* padapter); + +#ifdef PLATFORM_WINDOWS +struct mp_wi_cntx +{ + u8 bmpdrv_unload; + + // Work Item + NDIS_WORK_ITEM mp_wi; + NDIS_EVENT mp_wi_evt; + _lock mp_wi_lock; + u8 bmp_wi_progress; + wi_act_func curractfunc; + // Variable needed in each implementation of CurrActFunc. + struct mp_wiparam param; +}; +#endif + +struct mp_tx +{ + u8 stop; + u32 count, sended; + u8 payload; + struct pkt_attrib attrib; + struct tx_desc desc; + u8 *pallocated_buf; + u8 *buf; + u32 buf_size, write_size; + //_thread_hdl_ PktTxThread; + struct task_struct MpXmitThread; +}; + +#define MP_MAX_LINES 1000 +#define MP_MAX_LINES_BYTES 256 + + +typedef void (*MPT_WORK_ITEM_HANDLER)(IN void *Adapter); +typedef struct _MPT_CONTEXT +{ + // Indicate if we have started Mass Production Test. + BOOLEAN bMassProdTest; + + // Indicate if the driver is unloading or unloaded. + BOOLEAN bMptDrvUnload; + + _sema MPh2c_Sema; + _timer MPh2c_timeout_timer; +// Event used to sync H2c for BT control + + BOOLEAN MptH2cRspEvent; + BOOLEAN MptBtC2hEvent; + BOOLEAN bMPh2c_timeout; + + /* 8190 PCI does not support NDIS_WORK_ITEM. */ + // Work Item for Mass Production Test. + //NDIS_WORK_ITEM MptWorkItem; +// RT_WORK_ITEM MptWorkItem; + // Event used to sync the case unloading driver and MptWorkItem is still in progress. +// NDIS_EVENT MptWorkItemEvent; + // To protect the following variables. +// NDIS_SPIN_LOCK MptWorkItemSpinLock; + // Indicate a MptWorkItem is scheduled and not yet finished. + BOOLEAN bMptWorkItemInProgress; + // An instance which implements function and context of MptWorkItem. + MPT_WORK_ITEM_HANDLER CurrMptAct; + + // 1=Start, 0=Stop from UI. + u32 MptTestStart; + // _TEST_MODE, defined in MPT_Req2.h + u32 MptTestItem; + // Variable needed in each implementation of CurrMptAct. + u32 MptActType; // Type of action performed in CurrMptAct. + // The Offset of IO operation is depend of MptActType. + u32 MptIoOffset; + // The Value of IO operation is depend of MptActType. + u32 MptIoValue; + // The RfPath of IO operation is depend of MptActType. + u32 MptRfPath; + + WIRELESS_MODE MptWirelessModeToSw; // Wireless mode to switch. + u8 MptChannelToSw; // Channel to switch. + u8 MptInitGainToSet; // Initial gain to set. + //u32 bMptAntennaA; // TRUE if we want to use antenna A. + u32 MptBandWidth; // bandwidth to switch. + u32 MptRateIndex; // rate index. + // Register value kept for Single Carrier Tx test. + u8 btMpCckTxPower; + // Register value kept for Single Carrier Tx test. + u8 btMpOfdmTxPower; + // For MP Tx Power index + u8 TxPwrLevel[2]; // rf-A, rf-B + + // Content of RCR Regsiter for Mass Production Test. + u32 MptRCR; + // TRUE if we only receive packets with specific pattern. + BOOLEAN bMptFilterPattern; + // Rx OK count, statistics used in Mass Production Test. + u32 MptRxOkCnt; + // Rx CRC32 error count, statistics used in Mass Production Test. + u32 MptRxCrcErrCnt; + + BOOLEAN bCckContTx; // TRUE if we are in CCK Continuous Tx test. + BOOLEAN bOfdmContTx; // TRUE if we are in OFDM Continuous Tx test. + BOOLEAN bStartContTx; // TRUE if we have start Continuous Tx test. + // TRUE if we are in Single Carrier Tx test. + BOOLEAN bSingleCarrier; + // TRUE if we are in Carrier Suppression Tx Test. + BOOLEAN bCarrierSuppression; + //TRUE if we are in Single Tone Tx test. + BOOLEAN bSingleTone; + + // ACK counter asked by K.Y.. + BOOLEAN bMptEnableAckCounter; + u32 MptAckCounter; + + // SD3 Willis For 8192S to save 1T/2T RF table for ACUT Only fro ACUT delete later ~~~! + //s8 BufOfLines[2][MAX_LINES_HWCONFIG_TXT][MAX_BYTES_LINE_HWCONFIG_TXT]; + //s8 BufOfLines[2][MP_MAX_LINES][MP_MAX_LINES_BYTES]; + //s32 RfReadLine[2]; + + u8 APK_bound[2]; //for APK path A/path B + BOOLEAN bMptIndexEven; + + u8 backup0xc50; + u8 backup0xc58; + u8 backup0xc30; + u8 backup0x52_RF_A; + u8 backup0x52_RF_B; + + u8 h2cReqNum; + u8 c2hBuf[20]; + + u8 btInBuf[100]; + u32 mptOutLen; + u8 mptOutBuf[100]; + +}MPT_CONTEXT, *PMPT_CONTEXT; +//#endif + +//#define RTPRIV_IOCTL_MP ( SIOCIWFIRSTPRIV + 0x17) +enum { + WRITE_REG = 1, + READ_REG, + WRITE_RF, + READ_RF, + MP_START, + MP_STOP, + MP_RATE, + MP_CHANNEL, + MP_BANDWIDTH, + MP_TXPOWER, + MP_ANT_TX, + MP_ANT_RX, + MP_CTX, + MP_QUERY, + MP_ARX, + MP_PSD, + MP_PWRTRK, + MP_THER, + MP_IOCTL, + EFUSE_GET, + EFUSE_SET, + CONFIG_GET, + CONFIG_SET, + MP_RESET_STATS, + MP_DUMP, + MP_PHYPARA, + MP_SetRFPathSwh, + MP_QueryDrvStats, + MP_SetBT, + TEST_CFG, + MP_NULL, + MP_GET_TXPOWER_INX, + MP_SET_PREAMBLE, + MP_DISABLE_BT_COEXIST, + MP_PwrCtlDM, + MP_IQK, + MP_LCK, + MP_DRV_ABILITY +}; + +struct mp_priv +{ + _adapter *papdater; + + //Testing Flag + u32 mode;//0 for normal type packet, 1 for loopback packet (16bytes TXCMD) + + u32 prev_fw_state; + + //OID cmd handler + struct mp_wiparam workparam; +// u8 act_in_progress; + + //Tx Section + u8 TID; + u32 tx_pktcount; + struct mp_tx tx; + + //Rx Section + u8 rx_pkt_by_mac; + u32 rx_pktcount; + u32 rx_crcerrpktcount; + u32 rx_macpktcount; + u32 rx_pktloss; + + struct recv_stat rxstat; + + //RF/BB relative + u8 channel; + u8 bandwidth; + u8 prime_channel_offset; + u8 txpoweridx; + u8 txpoweridx_b; + u8 rateidx; + u32 preamble; +// u8 modem; + u32 CrystalCap; +// u32 curr_crystalcap; + + u16 antenna_tx; + u16 antenna_rx; +// u8 curr_rfpath; + + u8 check_mp_pkt; + + u8 bSetTxPower; + u8 bCCKTxPowerAdjust; + u8 bFAStatistics; +// uint ForcedDataRate; + u8 mp_dm; + struct wlan_network mp_network; + NDIS_802_11_MAC_ADDRESS network_macaddr; + +#ifdef PLATFORM_WINDOWS + u32 rx_testcnt; + u32 rx_testcnt1; + u32 rx_testcnt2; + u32 tx_testcnt; + u32 tx_testcnt1; + + struct mp_wi_cntx wi_cntx; + + u8 h2c_result; + u8 h2c_seqnum; + u16 h2c_cmdcode; + u8 h2c_resp_parambuf[512]; + _lock h2c_lock; + _lock wkitm_lock; + u32 h2c_cmdcnt; + NDIS_EVENT h2c_cmd_evt; + NDIS_EVENT c2h_set; + NDIS_EVENT h2c_clr; + NDIS_EVENT cpwm_int; + + NDIS_EVENT scsir_full_evt; + NDIS_EVENT scsiw_empty_evt; +#endif + + u8 *pallocated_mp_xmitframe_buf; + u8 *pmp_xmtframe_buf; + _queue free_mp_xmitqueue; + u32 free_mp_xmitframe_cnt; + + MPT_CONTEXT MptCtx; +}; + +typedef struct _IOCMD_STRUCT_ { + u8 cmdclass; + u16 value; + u8 index; +}IOCMD_STRUCT; + +struct rf_reg_param { + u32 path; + u32 offset; + u32 value; +}; + +struct bb_reg_param { + u32 offset; + u32 value; +}; +//======================================================================= + +#define LOWER _TRUE +#define RAISE _FALSE + +/* Hardware Registers */ +#if 0 +#if 0 +#define IOCMD_CTRL_REG 0x102502C0 +#define IOCMD_DATA_REG 0x102502C4 +#else +#define IOCMD_CTRL_REG 0x10250370 +#define IOCMD_DATA_REG 0x10250374 +#endif + +#define IOCMD_GET_THERMAL_METER 0xFD000028 + +#define IOCMD_CLASS_BB_RF 0xF0 +#define IOCMD_BB_READ_IDX 0x00 +#define IOCMD_BB_WRITE_IDX 0x01 +#define IOCMD_RF_READ_IDX 0x02 +#define IOCMD_RF_WRIT_IDX 0x03 +#endif +#define BB_REG_BASE_ADDR 0x800 + +/* MP variables */ +#if 0 +#define _2MAC_MODE_ 0 +#define _LOOPBOOK_MODE_ 1 +#endif +typedef enum _MP_MODE_ { + MP_OFF, + MP_ON, + MP_ERR, + MP_CONTINUOUS_TX, + MP_SINGLE_CARRIER_TX, + MP_CARRIER_SUPPRISSION_TX, + MP_SINGLE_TONE_TX, + MP_PACKET_TX, + MP_PACKET_RX +} MP_MODE; + + +#define MAX_RF_PATH_NUMS MAX_RF_PATH + + +extern u8 mpdatarate[NumRates]; + +/* MP set force data rate base on the definition. */ +typedef enum _MPT_RATE_INDEX +{ + /* CCK rate. */ + MPT_RATE_1M, /* 0 */ + MPT_RATE_2M, + MPT_RATE_55M, + MPT_RATE_11M, /* 3 */ + + /* OFDM rate. */ + MPT_RATE_6M, /* 4 */ + MPT_RATE_9M, + MPT_RATE_12M, + MPT_RATE_18M, + MPT_RATE_24M, + MPT_RATE_36M, + MPT_RATE_48M, + MPT_RATE_54M, /* 11 */ + + /* HT rate. */ + MPT_RATE_MCS0, /* 12 */ + MPT_RATE_MCS1, + MPT_RATE_MCS2, + MPT_RATE_MCS3, + MPT_RATE_MCS4, + MPT_RATE_MCS5, + MPT_RATE_MCS6, + MPT_RATE_MCS7, /* 19 */ + MPT_RATE_MCS8, + MPT_RATE_MCS9, + MPT_RATE_MCS10, + MPT_RATE_MCS11, + MPT_RATE_MCS12, + MPT_RATE_MCS13, + MPT_RATE_MCS14, + MPT_RATE_MCS15, /* 27 */ + MPT_RATE_LAST +}MPT_RATE_E, *PMPT_RATE_E; + +#define MAX_TX_PWR_INDEX_N_MODE 64 // 0x3F + +typedef enum _POWER_MODE_ { + POWER_LOW = 0, + POWER_NORMAL +}POWER_MODE; + + +#define RX_PKT_BROADCAST 1 +#define RX_PKT_DEST_ADDR 2 +#define RX_PKT_PHY_MATCH 3 + +#if 0 +#define RPTMaxCount 0x000FFFFF; + +// parameter 1 : BitMask +// bit 0 : OFDM PPDU +// bit 1 : OFDM False Alarm +// bit 2 : OFDM MPDU OK +// bit 3 : OFDM MPDU Fail +// bit 4 : CCK PPDU +// bit 5 : CCK False Alarm +// bit 6 : CCK MPDU ok +// bit 7 : CCK MPDU fail +// bit 8 : HT PPDU counter +// bit 9 : HT false alarm +// bit 10 : HT MPDU total +// bit 11 : HT MPDU OK +// bit 12 : HT MPDU fail +// bit 15 : RX full drop +typedef enum _RXPHY_BITMASK_ +{ + OFDM_PPDU_BIT = 0, + OFDM_FALSE_BIT, + OFDM_MPDU_OK_BIT, + OFDM_MPDU_FAIL_BIT, + CCK_PPDU_BIT, + CCK_FALSE_BIT, + CCK_MPDU_OK_BIT, + CCK_MPDU_FAIL_BIT, + HT_PPDU_BIT, + HT_FALSE_BIT, + HT_MPDU_BIT, + HT_MPDU_OK_BIT, + HT_MPDU_FAIL_BIT, +} RXPHY_BITMASK; +#endif + +typedef enum _ENCRY_CTRL_STATE_ { + HW_CONTROL, //hw encryption& decryption + SW_CONTROL, //sw encryption& decryption + HW_ENCRY_SW_DECRY, //hw encryption & sw decryption + SW_ENCRY_HW_DECRY //sw encryption & hw decryption +}ENCRY_CTRL_STATE; + +typedef enum _PREAMBLE { + Long_Preamble = 0x01, + Short_Preamble , + Long_GI , + Short_GI +} PREAMBLE; + + + +//======================================================================= +//extern struct mp_xmit_frame *alloc_mp_xmitframe(struct mp_priv *pmp_priv); +//extern int free_mp_xmitframe(struct xmit_priv *pxmitpriv, struct mp_xmit_frame *pmp_xmitframe); + +extern s32 init_mp_priv(_adapter * padapter); +extern void free_mp_priv(struct mp_priv *pmp_priv); +extern s32 MPT_InitializeAdapter(_adapter * padapter, u8 Channel); +extern void MPT_DeInitAdapter(_adapter * padapter); +extern s32 mp_start_test(_adapter * padapter); +extern void mp_stop_test(_adapter * padapter); + +//======================================================================= +//extern void IQCalibrateBcut(_adapter * pAdapter); + +//extern u32 bb_reg_read(_adapter * Adapter, u16 offset); +//extern u8 bb_reg_write(_adapter * Adapter, u16 offset, u32 value); +//extern u32 rf_reg_read(_adapter * Adapter, u8 path, u8 offset); +//extern u8 rf_reg_write(_adapter * Adapter, u8 path, u8 offset, u32 value); + +//extern u32 get_bb_reg(_adapter * Adapter, u16 offset, u32 bitmask); +//extern u8 set_bb_reg(_adapter * Adapter, u16 offset, u32 bitmask, u32 value); +//extern u32 get_rf_reg(_adapter * Adapter, u8 path, u8 offset, u32 bitmask); +//extern u8 set_rf_reg(_adapter * Adapter, u8 path, u8 offset, u32 bitmask, u32 value); + +extern u32 _read_rfreg(_adapter * padapter, u8 rfpath, u32 addr, u32 bitmask); +extern void _write_rfreg(_adapter * padapter, u8 rfpath, u32 addr, u32 bitmask, u32 val); + +extern u32 read_macreg(_adapter *padapter, u32 addr, u32 sz); +extern void write_macreg(_adapter *padapter, u32 addr, u32 val, u32 sz); +extern u32 read_bbreg(_adapter *padapter, u32 addr, u32 bitmask); +extern void write_bbreg(_adapter *padapter, u32 addr, u32 bitmask, u32 val); +extern u32 read_rfreg(_adapter * padapter, u8 rfpath, u32 addr); +extern void write_rfreg(_adapter * padapter, u8 rfpath, u32 addr, u32 val); + +extern void SetChannel(_adapter * pAdapter); +extern void SetBandwidth(_adapter * pAdapter); +extern void SetTxPower(_adapter * pAdapter); +extern void SetAntennaPathPower(_adapter * pAdapter); +//extern void SetTxAGCOffset(_adapter * pAdapter, u32 ulTxAGCOffset); +extern void SetDataRate(_adapter * pAdapter); + +extern void SetAntenna(_adapter * pAdapter); + +//extern void SetCrystalCap(_adapter * pAdapter); + +extern s32 SetThermalMeter(_adapter * pAdapter, u8 target_ther); +extern void GetThermalMeter(_adapter * pAdapter, u8 *value); + +extern void SetContinuousTx(_adapter * pAdapter, u8 bStart); +extern void SetSingleCarrierTx(_adapter * pAdapter, u8 bStart); +extern void SetSingleToneTx(_adapter * pAdapter, u8 bStart); +extern void SetCarrierSuppressionTx(_adapter * pAdapter, u8 bStart); +extern void PhySetTxPowerLevel(_adapter * pAdapter); + +extern void fill_txdesc_for_mp(_adapter * padapter, struct tx_desc *ptxdesc); +extern void SetPacketTx(_adapter * padapter); +extern void SetPacketRx(_adapter * pAdapter, u8 bStartRx); + +extern void ResetPhyRxPktCount(_adapter * pAdapter); +extern u32 GetPhyRxPktReceived(_adapter * pAdapter); +extern u32 GetPhyRxPktCRC32Error(_adapter * pAdapter); + +extern s32 SetPowerTracking(_adapter * padapter, u8 enable); +extern void GetPowerTracking(_adapter * padapter, u8 *enable); + +extern u32 mp_query_psd(_adapter * pAdapter, u8 *data); + + +extern void Hal_SetAntenna(_adapter * pAdapter); +extern void Hal_SetBandwidth(_adapter * pAdapter); + +extern void Hal_SetTxPower(_adapter * pAdapter); +extern void Hal_SetCarrierSuppressionTx(_adapter * pAdapter, u8 bStart); +extern void Hal_SetSingleToneTx ( _adapter * pAdapter , u8 bStart ); +extern void Hal_SetSingleCarrierTx (_adapter * pAdapter, u8 bStart); +extern void Hal_SetContinuousTx (_adapter * pAdapter, u8 bStart); +extern void Hal_SetBandwidth(_adapter * pAdapter); + +extern void Hal_SetDataRate(_adapter * pAdapter); +extern void Hal_SetChannel(_adapter * pAdapter); +extern void Hal_SetAntennaPathPower(_adapter * pAdapter); +extern s32 Hal_SetThermalMeter(_adapter * pAdapter, u8 target_ther); +extern s32 Hal_SetPowerTracking(_adapter * padapter, u8 enable); +extern void Hal_GetPowerTracking(_adapter * padapter, u8 * enable); +extern void Hal_GetThermalMeter(_adapter * pAdapter, u8 *value); +extern void Hal_mpt_SwitchRfSetting(_adapter * pAdapter); +extern void Hal_MPT_CCKTxPowerAdjust(_adapter * Adapter); +extern void Hal_MPT_CCKTxPowerAdjustbyIndex(_adapter * pAdapter, BOOLEAN beven); +extern void Hal_SetCCKTxPower(_adapter * pAdapter, u8 * TxPower); +extern void Hal_SetOFDMTxPower(_adapter * pAdapter, u8 * TxPower); +extern void Hal_TriggerRFThermalMeter(_adapter * pAdapter); +extern u8 Hal_ReadRFThermalMeter(_adapter * pAdapter); +extern void Hal_SetCCKContinuousTx(_adapter * pAdapter, u8 bStart); +extern void Hal_SetOFDMContinuousTx(_adapter * pAdapter, u8 bStart); +extern void Hal_ProSetCrystalCap (_adapter * pAdapter , u32 CrystalCapVal); +extern void _rtw_mp_xmit_priv(struct xmit_priv *pxmitpriv); +extern void MP_PHY_SetRFPathSwitch(_adapter * pAdapter ,BOOLEAN bMain); +extern u32 mpt_ProQueryCalTxPower(_adapter * pAdapter, u8 RfPath); +extern void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart); + +#endif //_RTW_MP_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_p2p.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_p2p.h new file mode 100644 index 0000000..610a75a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_p2p.h @@ -0,0 +1,58 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_P2P_H_ +#define _RTW_P2P_H_ + +#define P2P_WILDCARD_SSID "DIRECT-" +#define P2P_WILDCARD_SSID_LEN 7 + +#define P2P_SEND_ACTION_AFTER_PROBE_RSP 1 + +#define RTW_P2P_SEND_ACTION_SUCCESS 0 +#define RTW_P2P_SEND_ACTION_FAILED 2 + +static inline bool rtw_p2p_chk_state(struct wifidirect_info *wdinfo, enum P2P_STATE state) +{ + return wdinfo->p2p_state == state; +} +static inline bool rtw_p2p_chk_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role) +{ + return wdinfo->role == role; +} + +extern void rtw_p2p_remain_on_channel(_adapter *padapter, u8 channel, u8 wait_time); +extern void rtw_p2p_cancel_remain_on_channel(_adapter *padapter); +extern void rtw_p2p_special_scan_param(_adapter *padapter, u8 channel, u8 *mac); +extern void rtw_p2p_set_p2p_role(_adapter *padapter, u32 role); +extern void rtw_p2p_set_p2p_state(_adapter *padapter, u32 state); +extern int rtw_p2p_send_mgnt(_adapter *padapter, u8 *data, u16 len, u16 flags); +extern void rtw_p2p_indicate_mgnt(_adapter *padapter, u8 *data, u16 len, u8 channel); +extern void rtw_indicate_sta_assoc(_adapter *padapter, u8 *addr, u8 *buf, u16 len); +extern void rtw_p2p_indicate_sta_disassoc(_adapter *padapter, u8 *addr); +extern void rtw_p2p_indicate_send_action_done(_adapter *padapter, u16 status); + +extern int rtw_p2p_init_mlme_ext(_adapter *padapter); +extern void rtw_p2p_deinit_mlme_ext(_adapter *padapter); +extern int rtw_init_p2p_wdinfo(_adapter *padapter); +extern void rtw_deinit_p2p_wdinfo(_adapter *padapter); +extern void rtw_p2p_pre_tx_scan_cmd_callback(_adapter *padapter); + +#endif //_RTW_P2P_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_promisc.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_promisc.h new file mode 100644 index 0000000..918d840 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_promisc.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef _RTW_PROMISC_H_ +#define _RTW_PROMISC_H_ +#include +#ifdef CONFIG_PROMISC +void promisc_deinit(_adapter *padapter); +//void promisc_set_enable(_adapter *padapter, u8 enabled, u8 len_used); +int promisc_recv_func(_adapter *padapter, union recv_frame *rframe); +#endif +int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used); +unsigned char is_promisc_enabled(void); +int promisc_get_fixed_channel(void * fixed_bssid, u8 * ssid, int *ssid_length); +void promisc_issue_probereq(void); +void promisc_issue_probersp(unsigned char *da); +void promisc_stop_tx_beacn(void); +void promisc_resume_tx_beacn(void); +void promisc_get_ap_info(rtw_result_t (*func)(char *ssid, u8 ssid_len, s16 rssi, char channel, char security)); +#endif //_RTW_PROMISC_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_psk.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_psk.h new file mode 100644 index 0000000..75c275d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_psk.h @@ -0,0 +1,341 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef _RTW_PSK_H_ +#define _RTW_PSK_H_ + +#define GMK_LEN 32 +#define GTK_LEN 32 +#define PMK_LEN 32 +#define KEY_NONCE_LEN 32 +#define NumGroupKey 4 +#define KEY_RC_LEN 8 +#define KEY_IV_LEN 16 +#define KEY_RSC_LEN 8 +#define KEY_ID_LEN 8 +#define KEY_MIC_LEN 16 +#define KEY_MATERIAL_LEN 2 +#define PTK_LEN_EAPOLMIC 16 +#define PTK_LEN_EAPOLENC 16 +#define PTK_LEN_TKIP 64 +#define PTK_LEN_CCMP 48 +#define LIB1X_ETHER_EAPOL_TYPE 0x888E + +#define DescTypePos 0 +#define KeyInfoPos 1 +#define KeyLenPos 3 +#define ReplayCounterPos 5 +#define KeyNoncePos 13 +#define KeyIVPos 45 +#define KeyRSCPos 61 +#define KeyIDPos 69 +#define KeyMICPos 77 +#define KeyDataLenPos 93 +#define KeyDataPos 95 +#define LIB1X_EAPOL_VER 1 //0000 0001B +#define LIB1X_EAPOL_EAPPKT 0 //0000 0000B +#define LIB1X_EAPOL_START 1 //0000 0001B +#define LIB1X_EAPOL_LOGOFF 2 //0000 0010B +#define LIB1X_EAPOL_KEY 3 //0000 0011B +#define LIB1X_EAPOL_ENCASFALERT 4 //0000 0100B + + +#define A_SHA_DIGEST_LEN 20 +#define ETHER_HDRLEN 14 +#define LIB1X_EAPOL_HDRLEN 4 +#define INFO_ELEMENT_SIZE 128 +#define MAX_EAPOLMSG_LEN 512 +#define MAX_EAPOLKEYMSG_LEN (MAX_EAPOLMSG_LEN-(ETHER_HDRLEN+LIB1X_EAPOL_HDRLEN)) +#define EAPOLMSG_HDRLEN 95 //EAPOL-key payload length without KeyData +#define WPA_ELEMENT_ID 0xDD +#define WPA2_ELEMENT_ID 0x30 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#define ETHER_ADDRLEN 6 +#define PMK_EXPANSION_CONST "Pairwise key expansion" +#define PMK_EXPANSION_CONST_SIZE 22 +#define GMK_EXPANSION_CONST "Group key expansion" +#define GMK_EXPANSION_CONST_SIZE 19 +#define RANDOM_EXPANSION_CONST "Init Counter" +#define RANDOM_EXPANSION_CONST_SIZE 12 + +#define WLAN_REASON_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 + +/* + 2008-12-16, For Corega CG-WLCB54GL 54Mbps NIC interoperability issue. + The behavior of this NIC when it connect to the other AP with WPA/TKIP is: + AP <----------------------> STA + .................... + ------------> Assoc Rsp (ok) + ------------> EAPOL-key (4-way msg 1) + <------------ unknown TKIP encryption data + ------------> EAPOL-key (4-way msg 1) + <------------ unknown TKIP encryption data + ..................... + <------------ disassoc (code=8, STA is leaving) when the 5 seconds timer timeout counting from Assoc_Rsp is got. + .................... + ------------> Assoc Rsp (ok) + <-----------> EAPOL-key (4-way handshake success) + + If MAX_RESEND_NUM=3, our AP will send disassoc (code=15, 4-way timeout) to STA before STA sending disassoc to AP. + And this NIC will always can not connect to our AP. + set MAX_RESEND_NUM=5 can fix this issue. + */ +//#define MAX_RESEND_NUM 3 +#define MAX_RESEND_NUM 5 +#define RESEND_TIME 1000 + +#define GK_REKEY_TIME 3600000 //Set rekey period to 1 hour + +typedef enum { + desc_type_RSN = 2, + desc_type_WPA = 254 +} DescTypeRSN; + +typedef enum { + type_Group = 0, + type_Pairwise = 1 +} KeyType; + +typedef enum { + key_desc_ver1 = 1, + key_desc_ver2 = 2 +} KeyDescVer; + +enum { + PSK_WPA = 1, + PSK_WPA2 = 2 +}; + +enum { + PSK_STATE_IDLE, + PSK_STATE_PTKSTART, + PSK_STATE_PTKINITNEGOTIATING, + PSK_STATE_PTKINITDONE, +}; + +enum { + PSK_GSTATE_REKEYNEGOTIATING, + PSK_GSTATE_REKEYESTABLISHED, + PSK_GSTATE_KEYERROR, +}; + +typedef struct _OCTET_STRING { + unsigned char *Octet; + int Length; +} OCTET_STRING; + +typedef union _LARGE_INTEGER { + unsigned char charData[8]; + struct { + unsigned long HighPart; + unsigned long LowPart; + } field; +} LARGE_INTEGER, *PLARGE_INTEGER; + +typedef union _OCTET16_INTEGER { + unsigned char charData[16]; + struct { + LARGE_INTEGER HighPart; + LARGE_INTEGER LowPart; + } field; +} OCTET16_INTEGER; + +typedef union _OCTET32_INTEGER { + unsigned char charData[32]; + struct { + OCTET16_INTEGER HighPart; + OCTET16_INTEGER LowPart; + } field; +} OCTET32_INTEGER; + +// group key info +typedef struct _wpa_global_info { + OCTET32_INTEGER Counter; +//Save PSK to global array +// unsigned char PSK[A_SHA_DIGEST_LEN * 2]; + int GTKAuthenticator; + int GKeyDoneStations; + int GInitAKeys; + int GUpdateStationKeys; + int GkeyReady; + OCTET_STRING AuthInfoElement; + unsigned char AuthInfoBuf[INFO_ELEMENT_SIZE]; + unsigned char MulticastCipher; + OCTET_STRING GNonce; + unsigned char GNonceBuf[KEY_NONCE_LEN]; + unsigned char GTK[NumGroupKey][GTK_LEN]; + unsigned char GMK[GMK_LEN]; + int GN; + int GM; + int GTKRekey; +#ifdef CONFIG_GK_REKEY + struct timer_list GKRekeyTimer; +#endif +} WPA_GLOBAL_INFO; + +// wpa sta info +typedef struct _wpa_sta_info { + int state; + int gstate; + int RSNEnabled; // bit0-WPA, bit1-WPA2 + int PInitAKeys; + unsigned char UnicastCipher; + LARGE_INTEGER CurrentReplayCounter; + LARGE_INTEGER ReplayCounterStarted; // david+1-12-2007 + OCTET_STRING ANonce; + OCTET_STRING SNonce; + unsigned char AnonceBuf[KEY_NONCE_LEN]; + unsigned char SnonceBuf[KEY_NONCE_LEN]; + unsigned char PMK[PMK_LEN]; + unsigned char PTK[PTK_LEN_TKIP]; + OCTET_STRING EAPOLMsgRecvd; + OCTET_STRING EAPOLMsgSend; + OCTET_STRING EapolKeyMsgRecvd; + OCTET_STRING EapolKeyMsgSend; + + unsigned char eapSendBuf[MAX_EAPOLMSG_LEN]; +// unsigned char eapRecvdBuf[MAX_EAPOLMSG_LEN]; + struct timer_list resendTimer; + int resendCnt; + int clientHndshkProcessing; + int clientHndshkDone; + int clientGkeyUpdate; + LARGE_INTEGER clientMICReportReplayCounter; +} WPA_STA_INFO; + +typedef struct _LIB1X_EAPOL_KEY +{ + unsigned char key_desc_ver; + unsigned char key_info[2]; + unsigned char key_len[2]; + unsigned char key_replay_counter[KEY_RC_LEN]; + unsigned char key_nounce[KEY_NONCE_LEN]; + unsigned char key_iv[KEY_IV_LEN]; + unsigned char key_rsc[KEY_RSC_LEN]; + unsigned char key_id[KEY_ID_LEN]; + unsigned char key_mic[KEY_MIC_LEN]; + unsigned char key_data_len[KEY_MATERIAL_LEN]; + unsigned char *key_data; +} lib1x_eapol_key; + +struct lib1x_eapol +{ + unsigned char protocol_version; + unsigned char packet_type; // This makes it odd in number ! + unsigned short packet_body_length; +}; + +struct wlan_ethhdr_t +{ + unsigned char daddr[WLAN_ETHADDR_LEN]; + unsigned char saddr[WLAN_ETHADDR_LEN]; + unsigned short type; +}; + +typedef enum{ + DOT11_PortStatus_Unauthorized, + DOT11_PortStatus_Authorized, + DOT11_PortStatus_Guest +}DOT11_PORT_STATUS; + +#ifdef CONFIG_MOVE_PSK_TO_ROM +static __inline__ OCTET_STRING SubStr(OCTET_STRING f, unsigned short s, unsigned short l) +{ + OCTET_STRING res; + + res.Length = l; + res.Octet = f.Octet + s; + + return res; +} +#endif + +#define SetSubStr(f,a,l) memcpy(f.Octet+l,a.Octet,a.Length) +#define GetKeyInfo0(f, mask) ((f.Octet[KeyInfoPos + 1] & mask) ? 1 : 0) +#define SetKeyInfo0(f,mask,b) (f.Octet[KeyInfoPos + 1] = (f.Octet[KeyInfoPos + 1] & ~mask) | ( b?mask:0x0) ) +#define GetKeyInfo1(f, mask) ((f.Octet[KeyInfoPos] & mask) ? 1 : 0) +#define SetKeyInfo1(f,mask,b) (f.Octet[KeyInfoPos] = (f.Octet[KeyInfoPos] & ~mask) | ( b?mask:0x0) ) + +// EAPOLKey +#define Message_DescType(f) (f.Octet[DescTypePos]) +#define Message_setDescType(f, type) (f.Octet[DescTypePos] = type) +// Key Information Filed +#define Message_KeyDescVer(f) (f.Octet[KeyInfoPos+1] & 0x07) +#define Message_setKeyDescVer(f, v) (f.Octet[KeyInfoPos+1] &= 0xf8) , f.Octet[KeyInfoPos+1] |= (v & 0x07) +#define Message_KeyType(f) GetKeyInfo0(f, 0x08) +#define Message_setKeyType(f, b) SetKeyInfo0(f,0x08,b) +#define Message_KeyIndex(f) ((f.Octet[KeyInfoPos+1] & 0x30) >> 4) & 0x03 +#define Message_setKeyIndex(f, v) (f.Octet[KeyInfoPos+1] &= 0xcf), f.Octet[KeyInfoPos+1] |= ((v<<4) & 0x30) +#define Message_setInstall(f, b) SetKeyInfo0(f,0x40,b) +#define Message_setKeyAck(f, b) SetKeyInfo0(f,0x80,b) + +#define Message_KeyMIC(f) GetKeyInfo1(f, 0x01) +#define Message_setKeyMIC(f, b) SetKeyInfo1(f,0x01,b) +#define Message_Secure(f) GetKeyInfo1(f,0x02) +#define Message_setSecure(f, b) SetKeyInfo1(f,0x02,b) +#define Message_Error(f) GetKeyInfo1(f,0x04) +#define Message_setError(f, b) SetKeyInfo1(f,0x04,b) +#define Message_Request(f) GetKeyInfo1(f,0x08) +#define Message_setRequest(f, b) SetKeyInfo1(f,0x08,b) +#define Message_setReserved(f, v) (f.Octet[KeyInfoPos] |= (v<<4&0xff)) +#define Message_KeyLength(f) ((unsigned short)(f.Octet[KeyLenPos] <<8) + (unsigned short)(f.Octet[KeyLenPos+1])) +#define Message_setKeyLength(f, v) (f.Octet[KeyLenPos] = (v&0xff00) >>8 , f.Octet[KeyLenPos+1] = (v&0x00ff)) + +#define Message_KeyNonce(f) SubStr(f, KeyNoncePos, KEY_NONCE_LEN) +#define Message_setKeyNonce(f, v) SetSubStr(f, v, KeyNoncePos) +#define Message_EqualKeyNonce(f1, f2) memcmp(f1.Octet + KeyNoncePos, f2.Octet, KEY_NONCE_LEN)? 0:1 +#define Message_setKeyIV(f, v) SetSubStr(f, v, KeyIVPos) +#define Message_setKeyRSC(f, v) SetSubStr(f, v, KeyRSCPos) +#define Message_setKeyID(f, v) SetSubStr(f, v, KeyIDPos) +#define Message_setMIC(f, v) SetSubStr(f, v, KeyMICPos) +#define Message_KeyDataLength(f) ((unsigned short)(f.Octet[KeyDataLenPos] <<8) + (unsigned short)(f.Octet[KeyDataLenPos+1])) +#define Message_setKeyDataLength(f, v) (f.Octet[KeyDataLenPos] = (v&0xff00) >>8 , f.Octet[KeyDataLenPos+1] = (v&0x00ff)) +#define Message_setKeyData(f, v) SetSubStr(f, v, KeyDataPos); + +#define Message_CopyReplayCounter(f1, f2) memcpy(f1.Octet + ReplayCounterPos, f2.Octet + ReplayCounterPos, KEY_RC_LEN) +#define Message_DefaultReplayCounter(li) (((li.field.HighPart == 0xffffffff) && (li.field.LowPart == 0xffffffff) ) ?1:0) + +#define GET_MY_HWADDR(padapter) ((padapter)->eeprompriv.mac_addr) +#define LargeIntegerOverflow(x) (x.field.HighPart == 0xffffffff) && (x.field.LowPart == 0xffffffff) +#define LargeIntegerZero(x) memset(&x.charData, 0, 8) +#define Octet16IntegerOverflow(x) LargeIntegerOverflow(x.field.HighPart) && LargeIntegerOverflow(x.field.LowPart) +#define Octet16IntegerZero(x) memset(&x.charData, 0, 16) +#define SetNonce(ocDst, oc32Counter) SetEAPOL_KEYIV(ocDst, oc32Counter) + +void ClientSendEAPOL(_adapter *padapter, struct sta_info *psta, int resend); +void SendEAPOL(_adapter *padapter, struct sta_info *psta, int resend); +void EAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta); +void ClientEAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta); +void init_wpa_sta_info(_adapter *padapter, struct sta_info *psta); +void psk_init(_adapter *padapter, unsigned char *pie, unsigned short ielen); +void psk_derive(_adapter *padapter, unsigned char *passphrase, unsigned char *ssid); +u16 psk_strip_rsn_pairwise(u8 *ie, u16 ie_len); +u16 psk_strip_wpa_pairwise(u8 *ie, u16 ie_len); + +#endif // _RTW_PSK_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_pwrctrl.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_pwrctrl.h new file mode 100644 index 0000000..c90c200 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_pwrctrl.h @@ -0,0 +1,386 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_PWRCTRL_H_ +#define __RTW_PWRCTRL_H_ + + +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif //CONFIG_HAS_EARLYSUSPEND + +#define FW_PWR0 0 +#define FW_PWR1 1 +#define FW_PWR2 2 +#define FW_PWR3 3 + + +#define HW_PWR0 7 +#define HW_PWR1 6 +#define HW_PWR2 2 +#define HW_PWR3 0 +#define HW_PWR4 8 + +#define FW_PWRMSK 0x7 + + +#define XMIT_ALIVE BIT(0) +#define RECV_ALIVE BIT(1) +#define CMD_ALIVE BIT(2) +#define EVT_ALIVE BIT(3) + + +enum Power_Mgnt +{ + PS_MODE_ACTIVE = 0 , + PS_MODE_MIN , + PS_MODE_MAX , + PS_MODE_DTIM , + PS_MODE_VOIP , + PS_MODE_UAPSD_WMM , + PS_MODE_UAPSD , + PS_MODE_IBSS , + PS_MODE_WWLAN , + PM_Radio_Off , + PM_Card_Disable , + PS_MODE_NUM +}; + + +/* + BIT[2:0] = HW state + BIT[3] = Protocol PS state, 0: register active state , 1: register sleep state + BIT[4] = sub-state +*/ + +#define PS_DPS BIT(0) +#define PS_LCLK (PS_DPS) +#define PS_RF_OFF BIT(1) +#define PS_ALL_ON BIT(2) +#define PS_ST_ACTIVE BIT(3) + +#define PS_ISR_ENABLE BIT(4) +#define PS_IMR_ENABLE BIT(5) +#define PS_ACK BIT(6) +#define PS_TOGGLE BIT(7) + +#define PS_STATE_MASK (0x0F) +#define PS_STATE_HW_MASK (0x07) +#define PS_SEQ_MASK (0xc0) + +#define PS_STATE(x) (PS_STATE_MASK & (x)) +#define PS_STATE_HW(x) (PS_STATE_HW_MASK & (x)) +#define PS_SEQ(x) (PS_SEQ_MASK & (x)) + +#define PS_STATE_S0 (PS_DPS) +#define PS_STATE_S1 (PS_LCLK) +#define PS_STATE_S2 (PS_RF_OFF) +#define PS_STATE_S3 (PS_ALL_ON) +#define PS_STATE_S4 ((PS_ST_ACTIVE) | (PS_ALL_ON)) + + +#define PS_IS_RF_ON(x) ((x) & (PS_ALL_ON)) +#define PS_IS_ACTIVE(x) ((x) & (PS_ST_ACTIVE)) +#define CLR_PS_STATE(x) ((x) = ((x) & (0xF0))) + + +struct reportpwrstate_parm { + unsigned char mode; + unsigned char state; //the CPWM value + unsigned short rsvd; +}; + + +typedef _sema _pwrlock; + + +__inline static void _init_pwrlock(_pwrlock *plock) +{ + rtw_init_sema(plock, 1); +} + +__inline static void _free_pwrlock(_pwrlock *plock) +{ + rtw_free_sema(plock); +} + + +__inline static void _enter_pwrlock(_pwrlock *plock) +{ + rtw_down_sema(plock); +} + + +__inline static void _exit_pwrlock(_pwrlock *plock) +{ + rtw_up_sema(plock); +} + +#define LPS_DELAY_TIME 1 // 1 sec + +#define EXE_PWR_NONE 0x01 +#define EXE_PWR_IPS 0x02 +#define EXE_PWR_LPS 0x04 + +// RF state. +typedef enum _rt_rf_power_state +{ + rf_on, // RF is on after RFSleep or RFOff + rf_sleep, // 802.11 Power Save mode + rf_off, // HW/SW Radio OFF or Inactive Power Save + //=====Add the new RF state above this line=====// + rf_max +}rt_rf_power_state; + +// RF Off Level for IPS or HW/SW radio off +#define RT_RF_OFF_LEVL_ASPM BIT(0) // PCI ASPM +#define RT_RF_OFF_LEVL_CLK_REQ BIT(1) // PCI clock request +#define RT_RF_OFF_LEVL_PCI_D3 BIT(2) // PCI D3 mode +#define RT_RF_OFF_LEVL_HALT_NIC BIT(3) // NIC halt, re-initialize hw parameters +#define RT_RF_OFF_LEVL_FREE_FW BIT(4) // FW free, re-download the FW +#define RT_RF_OFF_LEVL_FW_32K BIT(5) // FW in 32k +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) // Always enable ASPM and Clock Req in initialization. +#define RT_RF_LPS_DISALBE_2R BIT(30) // When LPS is on, disable 2R if no packet is received or transmittd. +#define RT_RF_LPS_LEVEL_ASPM BIT(31) // LPS with ASPM + +#define RT_IN_PS_LEVEL(ppsc, _PS_FLAG) ((ppsc->cur_ps_level & _PS_FLAG) ? _TRUE : _FALSE) +#define RT_CLEAR_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(ppsc, _PS_FLAG) (ppsc->cur_ps_level |= _PS_FLAG) + + +enum _PS_BBRegBackup_ { + PSBBREG_RF0 = 0, + PSBBREG_RF1, + PSBBREG_RF2, + PSBBREG_AFE0, + PSBBREG_TOTALCNT +}; + +enum { // for ips_mode + IPS_NONE=0, + IPS_NORMAL, + IPS_LEVEL_2, + IPS_NUM +}; + +struct pwrctrl_priv +{ + _pwrlock lock; + volatile u8 rpwm; // requested power state for fw + volatile u8 cpwm; // fw current power state. updated when 1. read from HCPWM 2. driver lowers power level + volatile u8 tog; // toggling + volatile u8 cpwm_tog; // toggling + + u8 pwr_mode; + u8 smart_ps; + u8 bcn_ant_mode; + + u32 alives; + u64 wowlan_fw_iv; +//TODO +// _workitem cpwm_event; +#ifdef CONFIG_LPS_RPWM_TIMER + u8 brpwmtimeout; + _workitem rpwmtimeoutwi; + _timer pwr_rpwm_timer; +#endif // CONFIG_LPS_RPWM_TIMER + u8 bpower_saving; + + u8 b_hw_radio_off; + u8 reg_rfoff; + u8 reg_pdnmode; //powerdown mode + u32 rfoff_reason; + + //RF OFF Level + u32 cur_ps_level; + u32 reg_rfps_level; + + + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) + //just for PCIE ASPM + u8 b_support_aspm; // If it supports ASPM, Offset[560h] = 0x40, otherwise Offset[560h] = 0x00. + u8 b_support_backdoor; + + //just for PCIE ASPM + u8 const_amdpci_aspm; +#endif + + uint ips_enter_cnts; + uint ips_leave_cnts; + + u8 ps_enable; + u8 ips_mode; + u8 ips_org_mode; + u8 ips_mode_req; // used to accept the mode setting request, will update to ipsmode later + uint bips_processing; + u32 ips_deny_time; /* will deny IPS when system time is smaller than this */ + u8 ps_processing; /* temporarily used to mark whether in rtw_ps_processor */ + + u8 bLeisurePs; + u8 LpsIdleCount; + u8 power_mgnt; + u8 org_power_mgnt; + u8 bFwCurrentInPSMode; + u32 DelayLPSLastTimeStamp; + u8 btcoex_rfon; + s32 pnp_current_pwr_state; + u8 pnp_bstop_trx; + + + u8 bInternalAutoSuspend; + u8 bInSuspend; +#ifdef CONFIG_BT_COEXIST + u8 bAutoResume; + u8 autopm_cnt; +#endif + u8 bSupportRemoteWakeup; +#ifdef CONFIG_WOWLAN + u8 wowlan_txpause_status; + u8 wowlan_mode; + u8 wowlan_pattern; + u8 wowlan_magic; + u8 wowlan_unicast; + u8 wowlan_pattern_idx; + u8 wowlan_wake_reason; + u32 wowlan_pattern_context[8][5]; +#endif // CONFIG_WOWLAN + _timer pwr_state_check_timer; + int pwr_state_check_interval; + u8 pwr_state_check_cnts; + + int ps_flag; + + rt_rf_power_state rf_pwrstate;//cur power state + //rt_rf_power_state current_rfpwrstate; + rt_rf_power_state change_rfpwrstate; + + u8 wepkeymask; + u8 bHWPowerdown;//if support hw power down + u8 bHWPwrPindetect; + u8 bkeepfwalive; + u8 brfoffbyhw; + unsigned long PS_BBRegBackup[PSBBREG_TOTALCNT]; + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + struct workqueue_struct *rtw_workqueue; + _workitem resume_work; + #endif + + #ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; + u8 do_late_resume; + #endif //CONFIG_HAS_EARLYSUSPEND + + #ifdef CONFIG_ANDROID_POWER + android_early_suspend_t early_suspend; + u8 do_late_resume; + #endif + + #ifdef CONFIG_INTEL_PROXIM + u8 stored_power_mgnt; + #endif + + #ifdef TDMA_POWER_SAVING + u8 tdma_slot_period; + u8 tdma_rfon_period_len_1; + u8 tdma_rfon_period_len_2; + u8 tdma_rfon_period_len_3; + #endif + + u8 lps_dtim; +}; + +#define rtw_get_ips_mode_req(pwrctrlpriv) \ + (pwrctrlpriv)->ips_mode_req + +#define rtw_ips_mode_req(pwrctrlpriv, ips_mode) \ + (pwrctrlpriv)->ips_mode_req = (ips_mode) + +#define RTW_PWR_STATE_CHK_INTERVAL 2000 + +#define _rtw_set_pwr_state_check_timer(pwrctrlpriv, ms) \ + do { \ + /*DBG_871X("%s _rtw_set_pwr_state_check_timer(%p, %d)\n", __FUNCTION__, (pwrctrlpriv), (ms));*/ \ + rtw_set_timer(&(pwrctrlpriv)->pwr_state_check_timer, (ms)); \ + } while(0) + +#define rtw_set_pwr_state_check_timer(pwrctrlpriv) \ + _rtw_set_pwr_state_check_timer((pwrctrlpriv), (pwrctrlpriv)->pwr_state_check_interval) + +extern void rtw_init_pwrctrl_priv(_adapter *adapter); +extern void rtw_free_pwrctrl_priv(_adapter * adapter); + +#ifdef CONFIG_LPS_LCLK +extern s32 rtw_register_tx_alive(PADAPTER padapter); +extern void rtw_unregister_tx_alive(PADAPTER padapter); +extern s32 rtw_register_rx_alive(PADAPTER padapter); +extern void rtw_unregister_rx_alive(PADAPTER padapter); +extern s32 rtw_register_cmd_alive(PADAPTER padapter); +extern void rtw_unregister_cmd_alive(PADAPTER padapter); +extern s32 rtw_register_evt_alive(PADAPTER padapter); +extern void rtw_unregister_evt_alive(PADAPTER padapter); +extern void cpwm_int_hdl(PADAPTER padapter, struct reportpwrstate_parm *preportpwrstate); +extern void LPS_Leave_check(PADAPTER padapter); +#endif + +extern void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode); +extern void rtw_set_rpwm(_adapter * padapter, u8 val8); +extern void LeaveAllPowerSaveMode(PADAPTER Adapter); +#ifdef CONFIG_IPS +void ips_enter(_adapter * padapter); +int ips_leave(_adapter * padapter); +#endif + +void rtw_ps_processor(_adapter*padapter); + +#ifdef CONFIG_AUTOSUSPEND +int autoresume_enter(_adapter* padapter); +#endif +#ifdef SUPPORT_HW_RFOFF_DETECTED +rt_rf_power_state RfOnOffDetect(IN PADAPTER pAdapter ); +#endif + + +#ifdef CONFIG_LPS +s32 LPS_RF_ON_check(PADAPTER padapter, u32 delay_ms); +void LPS_Enter(PADAPTER padapter); +void LPS_Leave(PADAPTER padapter); +#endif + +#ifdef CONFIG_RESUME_IN_WORKQUEUE +void rtw_resume_in_workqueue(struct pwrctrl_priv *pwrpriv); +#endif //CONFIG_RESUME_IN_WORKQUEUE + +#if defined(CONFIG_HAS_EARLYSUSPEND ) || defined(CONFIG_ANDROID_POWER) +#define rtw_is_earlysuspend_registered(pwrpriv) (pwrpriv)->early_suspend.suspend +void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv); +void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv); +#endif //CONFIG_HAS_EARLYSUSPEND || CONFIG_ANDROID_POWER +//TODO +//u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val); +int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller); +#define rtw_pwr_wakeup(adapter) _rtw_pwr_wakeup(adapter, RTW_PWR_STATE_CHK_INTERVAL, __FUNCTION__) +int rtw_pm_set_ips(_adapter *padapter, u8 mode); +int rtw_pm_set_lps(_adapter *padapter, u8 mode); +int rtw_pm_set_tdma_param(_adapter *padapter, u8 tdma_slot_period, u8 tdma_rfon_period_len_1, u8 tdma_rfon_period_len_2, u8 tdma_rfon_period_len_3); +int rtw_pm_set_lps_dtim(_adapter *padapter, u8 lps_dtim); +u8 rtw_pm_get_lps_dtim(_adapter *padapter); +#endif //__RTL871X_PWRCTRL_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_qos.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_qos.h new file mode 100644 index 0000000..0d6c8c4 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_qos.h @@ -0,0 +1,33 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef _RTW_QOS_H_ +#define _RTW_QOS_H_ + +struct qos_priv { + + u32 qos_option; //bit mask option: u-apsd, s-apsd, ts, block ack... + +}; + + +#endif //_RTL871X_QOS_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_recv.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_recv.h new file mode 100644 index 0000000..523c4d0 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_recv.h @@ -0,0 +1,918 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_RECV_H_ +#define _RTW_RECV_H_ +#include + +#if defined(PLATFORM_ECOS) +#define NR_RECVFRAME 16 //Decrease recv frame due to memory limitation - Alex Fang +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#ifdef CONFIG_RECV_REORDERING_CTRL +#define NR_RECVFRAME 16 //Increase recv frame due to rx reorder - Andy Sun +#else +#if WIFI_LOGO_CERTIFICATION + #define NR_RECVFRAME 8 //Decrease recv frame due to memory limitation - Alex Fang +#else +#ifndef CONFIG_HIGH_TP + #define NR_RECVFRAME 2 //Decrease recv frame due to memory limitation - YangJue +#else + #define NR_RECVFRAME 256 +#endif +#endif +#endif +#else +#define NR_RECVFRAME 256 +#endif + +#ifdef PLATFORM_OS_XP + #define NR_RECVBUFF (16) +#elif defined(PLATFORM_OS_CE) + #define NR_RECVBUFF (4) +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#ifndef CONFIG_HIGH_TP +// #define NR_RECVBUFF (8) //Decrease recv buffer due to memory limitation - Alex Fang + #define NR_RECVBUFF (1) //Decrease recv buffer due to memory limitation - YangJue +#else + #define NR_RECVBUFF (32) +#endif +#else + #if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) + #define NR_RECVBUFF (32) + #else + #define NR_RECVBUFF (4) + #endif + + #define NR_PREALLOC_RECV_SKB (8) +#endif + +#define RECV_BULK_IN_ADDR 0x80 +#define RECV_INT_IN_ADDR 0x81 + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_LINKQUALITY_SLID_WIN_MAX 20 + +// Rx smooth factor +#define Rx_Smooth_Factor (20) + +#define RXFRAME_ALIGN 8 +#define RXFRAME_ALIGN_SZ (1<signal_stat_timer, (recvpriv)->signal_stat_sampling_interval) +#endif //CONFIG_NEW_SIGNAL_STAT_PROCESS + +struct sta_recv_priv { + + _lock lock; + sint option; + + //_queue blk_strms[MAX_RX_NUMBLKS]; + _queue defrag_q; //keeping the fragment frame until defrag + + struct stainfo_rxcache rxcache; + + //uint sta_rx_bytes; + //uint sta_rx_pkts; + //uint sta_rx_fail; + +}; + +struct recv_buf +{ + _list list; + +// _lock recvbuf_lock; + +// u32 ref_cnt; + + PADAPTER adapter; + +// u8 *pbuf; +// u8 *pallocated_buf; + + u32 len; + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + +#ifdef CONFIG_USB_HCI + + #if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX)||defined(PLATFORM_FREEBSD) + PURB purb; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ + u32 alloc_sz; + #endif + + #ifdef PLATFORM_OS_XP + PIRP pirp; + #endif + + #ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_read_port; + #endif + + u8 irp_pending; + int transfer_len; + +#endif + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + _pkt *pskb; +// u8 reuse; +#endif +#ifdef PLATFORM_FREEBSD //skb solution + struct sk_buff *pskb; + u8 reuse; +#endif //PLATFORM_FREEBSD //skb solution +}; + +/* + head -----> + + data -----> + + payload + + tail -----> + + + end -----> + + len = (unsigned int )(tail - data); + +*/ +struct recv_frame_hdr +{ + _list list; +#ifndef CONFIG_BSD_RX_USE_MBUF + struct sk_buff *pkt; + struct sk_buff *pkt_newalloc; +#else // CONFIG_BSD_RX_USE_MBUF + _pkt *pkt; + _pkt *pkt_newalloc; +#endif // CONFIG_BSD_RX_USE_MBUF + + _adapter *adapter; + + u8 fragcnt; + + int frame_tag; + + struct rx_pkt_attrib attrib; + + uint len; + u8 *rx_head; + u8 *rx_data; + u8 *rx_tail; + u8 *rx_end; + + void *precvbuf; + + + // + struct sta_info *psta; +#ifdef CONFIG_RECV_REORDERING_CTRL + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl *preorder_ctrl; +#endif +#ifdef CONFIG_WAPI_SUPPORT + u8 UserPriority; + u8 WapiTempPN[16]; + u8 WapiSrcAddr[6]; + u8 bWapiCheckPNInDecrypt; + u8 bIsWaiPacket; +#endif + +}; + +union recv_frame{ + + union{ + _list list; + struct recv_frame_hdr hdr; + uint mem[RECVFRAME_HDR_ALIGN>>2]; + }u; + + //uint mem[MAX_RXSZ>>2]; + +}; + +typedef enum _RX_PACKET_TYPE{ + NORMAL_RX,//Normal rx packet + TX_REPORT1,//CCX + TX_REPORT2,//TX RPT + HIS_REPORT,// USB HISR RPT + C2H_PACKET +}RX_PACKET_TYPE, *PRX_PACKET_TYPE; + +extern union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +extern void rtw_init_recvframe(union recv_frame *precvframe ,struct recv_priv *precvpriv); +extern int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue); + +#define rtw_dequeue_recvframe(queue) rtw_alloc_recvframe(queue) +extern int _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); + +#ifdef CONFIG_TRACE_SKB +int __rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); +union recv_frame *__rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue + +#define rtw_enqueue_recvframe(precvframe, queue, Q) \ + do{\ + set_skb_list_flag(precvframe->u.hdr.pkt, SKBLIST_RECVFRAME_##Q);\ + __rtw_enqueue_recvframe(precvframe, queue);\ + }while (0) +#define rtw_alloc_recvframe(queue, precvframe, Q) \ + (\ + precvframe = __rtw_alloc_recvframe(queue),\ + precvframe ? clear_skb_list_flag(precvframe->u.hdr.pkt, SKBLIST_RECVFRAME_##Q):0,\ + precvframe\ + ) +#else +extern int rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue); +extern union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue); //get a free recv_frame from pfree_recv_queue +#endif + +extern void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue); +u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter); + +#ifdef CONFIG_TRACE_SKB +sint _rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); +sint _rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); +struct recv_buf *_rtw_dequeue_recvbuf (_queue *queue); + +#define rtw_enqueue_recvbuf_to_head(precvbuf, queue, Q) \ + do{\ + set_skb_list_flag(precvbuf->pskb, SKBLIST_RECVBUF_##Q);\ + _rtw_enqueue_recvbuf_to_head(precvbuf, queue);\ + }while (0) +#define rtw_enqueue_recvbuf(precvbuf, queue, Q) \ + do{\ + set_skb_list_flag(precvbuf->pskb, SKBLIST_RECVBUF_##Q);\ + _rtw_enqueue_recvbuf(precvbuf, queue);\ + }while (0) +#define rtw_dequeue_recvbuf(queue, precvbuf, Q) \ + (\ + precvbuf = _rtw_dequeue_recvbuf(queue),\ + precvbuf ? clear_skb_list_flag(precvbuf->pskb, SKBLIST_RECVBUF_##Q):0,\ + precvbuf\ + ) + +#else +sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); +sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); +struct recv_buf *rtw_dequeue_recvbuf (_queue *queue); +#endif + +void rtw_reordering_ctrl_timeout_handler(void *pcontext); + + +__inline static u8 *get_rxmem(union recv_frame *precvframe) +{ + //always return rx_head... + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_head; +} + +__inline static u8 *get_rx_status(union recv_frame *precvframe) +{ + + return get_rxmem(precvframe); + +} + + + +__inline static u8 *get_recvframe_data(union recv_frame *precvframe) +{ + + //alwasy return rx_data + if(precvframe==NULL) + return NULL; + + return precvframe->u.hdr.rx_data; + +} + +//TODO +#if 0 + +__inline static u8 *recvframe_push(union recv_frame *precvframe, sint sz) +{ + // append data before rx_data + + /* add data to the start of recv_frame + * + * This function extends the used data area of the recv_frame at the buffer + * start. rx_data must be still larger than rx_head, after pushing. + */ + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data -= sz ; + if( precvframe->u.hdr.rx_data < precvframe->u.hdr.rx_head ) + { + precvframe->u.hdr.rx_data += sz ; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_data; + +} + +#endif //#if 0 + +__inline static u8 *recvframe_pull(union recv_frame *precvframe, sint sz) +{ + // rx_data += sz; move rx_data sz bytes hereafter + + //used for extract sz bytes from rx_data, update rx_data and return the updated rx_data to the caller + + + if(precvframe==NULL) + return NULL; + + + precvframe->u.hdr.rx_data += sz; + + if(precvframe->u.hdr.rx_data > precvframe->u.hdr.rx_tail) + { + precvframe->u.hdr.rx_data -= sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_data; + +} + +__inline static u8 *recvframe_put(union recv_frame *precvframe, sint sz) +{ + // rx_tai += sz; move rx_tail sz bytes hereafter + + //used for append sz bytes from ptr to rx_tail, update rx_tail and return the updated rx_tail to the caller + //after putting, rx_tail must be still larger than rx_end. + + if(precvframe==NULL) + return NULL; + + precvframe->u.hdr.rx_tail += sz; + + if(precvframe->u.hdr.rx_tail > precvframe->u.hdr.rx_end) + { + precvframe->u.hdr.rx_tail -= sz; + return NULL; + } + + precvframe->u.hdr.len +=sz; + + return precvframe->u.hdr.rx_tail; + +} + + + +__inline static u8 *recvframe_pull_tail(union recv_frame *precvframe, sint sz) +{ + // rmv data from rx_tail (by yitsen) + + //used for extract sz bytes from rx_end, update rx_end and return the updated rx_end to the caller + //after pulling, rx_end must be still larger than rx_data. + + if(precvframe==NULL) + return NULL; + + precvframe->u.hdr.rx_tail -= sz; + + if(precvframe->u.hdr.rx_tail < precvframe->u.hdr.rx_data) + { + precvframe->u.hdr.rx_tail += sz; + return NULL; + } + + precvframe->u.hdr.len -=sz; + + return precvframe->u.hdr.rx_tail; + +} + +__inline static _buffer * get_rxbuf_desc(union recv_frame *precvframe) +{ + _buffer * buf_desc = NULL; + + if(precvframe==NULL) + return NULL; +#ifdef PLATFORM_WINDOWS + NdisQueryPacket(precvframe->u.hdr.pkt, NULL, NULL, &buf_desc, NULL); +#endif + + return buf_desc; +} + + +__inline static union recv_frame *rxmem_to_recvframe(u8 *rxmem) +{ + //due to the design of 2048 bytes alignment of recv_frame, we can reference the union recv_frame + //from any given member of recv_frame. + // rxmem indicates the any member/address in recv_frame + + return (union recv_frame*)(((SIZE_PTR)rxmem >> RXFRAME_ALIGN) << RXFRAME_ALIGN); + +} + +__inline static union recv_frame *pkt_to_recvframe(_pkt *pkt) +{ + + u8 * buf_star = NULL; + union recv_frame * precv_frame = NULL; +#ifdef PLATFORM_WINDOWS + _buffer * buf_desc; + uint len; + + NdisQueryPacket(pkt, NULL, NULL, &buf_desc, &len); + NdisQueryBufferSafe(buf_desc, &buf_star, &len, HighPagePriority); +#endif + precv_frame = rxmem_to_recvframe((unsigned char*)buf_star); + + return precv_frame; +} + +__inline static u8 *pkt_to_recvmem(_pkt *pkt) +{ + // return the rx_head + + union recv_frame * precv_frame = pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_head; + +} + +__inline static u8 *pkt_to_recvdata(_pkt *pkt) +{ + // return the rx_data + + union recv_frame * precv_frame =pkt_to_recvframe(pkt); + + return precv_frame->u.hdr.rx_data; + +} + + +__inline static sint get_recvframe_len(union recv_frame *precvframe) +{ + return precvframe->u.hdr.len; +} + + +__inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex) +{ + s32 SignalPower; // in dBm. + +#ifndef CONFIG_SKIP_SIGNAL_SCALE_MAPPING + // Translate to dBm (x=0.9y-95). + SignalPower = (s32)((SignalStrengthIndex *18) /20); + SignalPower -= 95; +#else + /* Translate to dBm (x=y-100) */ + SignalPower = SignalStrengthIndex - 100; +#endif + + return SignalPower; +} + + +struct sta_info; + +extern void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); +extern void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame); +int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe); + +void rtw_rxhandler(_adapter * padapter, struct recv_buf *precvbuf); +u32 rtw_free_buf_pending_queue(_adapter *adapter); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_rf.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_rf.h new file mode 100644 index 0000000..a9f8220 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_rf.h @@ -0,0 +1,175 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_RF_H_ +#define __RTW_RF_H_ + + +#define OFDM_PHY 1 +#define MIXED_PHY 2 +#define CCK_PHY 3 + +#define NumRates (13) + +// slot time for 11g +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + +#define RTL8711_RF_MAX_SENS 6 +#define RTL8711_RF_DEF_SENS 4 + +// +// We now define the following channels as the max channels in each channel plan. +// 2G, total 14 chnls +// {1,2,3,4,5,6,7,8,9,10,11,12,13,14} +// 5G, total 24 chnls +// {36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165} +#define MAX_CHANNEL_NUM_2G 14 +#define MAX_CHANNEL_NUM_5G 24 +#if defined(NOT_SUPPORT_5G) +#define MAX_CHANNEL_NUM 14 +#else +#define MAX_CHANNEL_NUM 38//14+24 +#endif + +//#define NUM_REGULATORYS 21 +#define NUM_REGULATORYS 1 + +//Country codes +#define USA 0x555320 +#define EUROPE 0x1 //temp, should be provided later +#define JAPAN 0x2 //temp, should be provided later + +struct regulatory_class { + u32 starting_freq; //MHz, + u8 channel_set[MAX_CHANNEL_NUM]; + u8 channel_cck_power[MAX_CHANNEL_NUM];//dbm + u8 channel_ofdm_power[MAX_CHANNEL_NUM];//dbm + u8 txpower_limit; //dbm + u8 channel_spacing; //MHz + u8 modem; +}; + +typedef enum _CAPABILITY{ + cESS = 0x0001, + cIBSS = 0x0002, + cPollable = 0x0004, + cPollReq = 0x0008, + cPrivacy = 0x0010, + cShortPreamble = 0x0020, + cPBCC = 0x0040, + cChannelAgility = 0x0080, + cSpectrumMgnt = 0x0100, + cQos = 0x0200, // For HCCA, use with CF-Pollable and CF-PollReq + cShortSlotTime = 0x0400, + cAPSD = 0x0800, + cRM = 0x1000, // RRM (Radio Request Measurement) + cDSSS_OFDM = 0x2000, + cDelayedBA = 0x4000, + cImmediateBA = 0x8000, +}CAPABILITY, *PCAPABILITY; + +enum _REG_PREAMBLE_MODE{ + PREAMBLE_LONG = 1, + PREAMBLE_AUTO = 2, + PREAMBLE_SHORT = 3, +}; + + +enum _RTL8712_RF_MIMO_CONFIG_{ + RTL8712_RFCONFIG_1T=0x10, + RTL8712_RFCONFIG_2T=0x20, + RTL8712_RFCONFIG_1R=0x01, + RTL8712_RFCONFIG_2R=0x02, + RTL8712_RFCONFIG_1T1R=0x11, + RTL8712_RFCONFIG_1T2R=0x12, + RTL8712_RFCONFIG_TURBO=0x92, + RTL8712_RFCONFIG_2T2R=0x22 +}; + + +typedef enum _RF90_RADIO_PATH{ + RF90_PATH_A = 0, //Radio Path A + RF90_PATH_B = 1, //Radio Path B + RF90_PATH_C = 2, //Radio Path C + RF90_PATH_D = 3 //Radio Path D + //RF90_PATH_MAX //Max RF number 90 support +}RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; + +// Bandwidth Offset +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + +// Represent Channel Width in HT Capabilities +// +typedef enum _CHANNEL_WIDTH{ + CHANNEL_WIDTH_20 = 0, + CHANNEL_WIDTH_40 = 1, + CHANNEL_WIDTH_80 = 2, + CHANNEL_WIDTH_160 = 3, + CHANNEL_WIDTH_80_80 = 4, + CHANNEL_WIDTH_MAX = 5, +}CHANNEL_WIDTH, *PCHANNEL_WIDTH; + +// +// Represent Extention Channel Offset in HT Capabilities +// This is available only in 40Mhz mode. +// +typedef enum _EXTCHNL_OFFSET{ + EXTCHNL_OFFSET_NO_EXT = 0, + EXTCHNL_OFFSET_UPPER = 1, + EXTCHNL_OFFSET_NO_DEF = 2, + EXTCHNL_OFFSET_LOWER = 3, +}EXTCHNL_OFFSET, *PEXTCHNL_OFFSET; + +typedef enum _VHT_DATA_SC{ + VHT_DATA_SC_DONOT_CARE = 0, + VHT_DATA_SC_20_UPPER_OF_80MHZ = 1, + VHT_DATA_SC_20_LOWER_OF_80MHZ = 2, + VHT_DATA_SC_20_UPPERST_OF_80MHZ = 3, + VHT_DATA_SC_20_LOWEST_OF_80MHZ = 4, + VHT_DATA_SC_20_RECV1 = 5, + VHT_DATA_SC_20_RECV2 = 6, + VHT_DATA_SC_20_RECV3 = 7, + VHT_DATA_SC_20_RECV4 = 8, + VHT_DATA_SC_40_UPPER_OF_80MHZ = 9, + VHT_DATA_SC_40_LOWER_OF_80MHZ = 10, +}VHT_DATA_SC, *PVHT_DATA_SC_E; + + + +/* 2007/11/15 MH Define different RF type. */ +typedef enum _RT_RF_TYPE_DEFINITION +{ + RF_1T2R = 0, + RF_2T4R = 1, + RF_2T2R = 2, + RF_1T1R = 3, + RF_2T2R_GREEN = 4, + RF_819X_MAX_TYPE = 5, +}RT_RF_TYPE_DEF_E; + + +u32 rtw_ch2freq(u32 ch); +u32 rtw_freq2ch(u32 freq); + + +#endif //_RTL8711_RF_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_security.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_security.h new file mode 100644 index 0000000..958be9d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_security.h @@ -0,0 +1,446 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTW_SECURITY_H_ +#define __RTW_SECURITY_H_ + + +#define _NO_PRIVACY_ 0x0 +#define _WEP40_ 0x1 +#define _TKIP_ 0x2 +#define _TKIP_WTMIC_ 0x3 +#define _AES_ 0x4 +#define _WEP104_ 0x5 +#define _WEP_WPA_MIXED_ 0x07 // WEP + WPA +#define _SMS4_ 0x06 + +#define is_wep_enc(alg) (((alg) == _WEP40_) || ((alg) == _WEP104_)) + +#define _WPA_IE_ID_ 0xdd +#define _WPA2_IE_ID_ 0x30 + +#define SHA256_MAC_LEN 32 +#define AES_BLOCK_SIZE 16 +#define AES_PRIV_SIZE (4 * 44) +#define _AES_IV_LEN_ 8 + +typedef enum { + ENCRYP_PROTOCOL_OPENSYS, //open system + ENCRYP_PROTOCOL_WEP, //WEP + ENCRYP_PROTOCOL_WPA, //WPA + ENCRYP_PROTOCOL_WPA2, //WPA2 + ENCRYP_PROTOCOL_WAPI, //WAPI: Not support in this version + ENCRYP_PROTOCOL_MAX +}ENCRYP_PROTOCOL_E; + + +#ifndef Ndis802_11AuthModeWPA2 +#define Ndis802_11AuthModeWPA2 (Ndis802_11AuthModeWPANone + 1) +#endif + +#ifndef Ndis802_11AuthModeWPA2PSK +#define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2) +#endif + +union pn48 { + + u64 val; + +#ifdef CONFIG_LITTLE_ENDIAN + +struct { + u8 TSC0; + u8 TSC1; + u8 TSC2; + u8 TSC3; + u8 TSC4; + u8 TSC5; + u8 TSC6; + u8 TSC7; +} _byte_; + +#elif defined(CONFIG_BIG_ENDIAN) + +struct { + u8 TSC7; + u8 TSC6; + u8 TSC5; + u8 TSC4; + u8 TSC3; + u8 TSC2; + u8 TSC1; + u8 TSC0; +} _byte_; + +#endif + +}; + +union Keytype { + u8 skey[16]; + u32 lkey[4]; +}; + + +typedef struct _RT_PMKID_LIST +{ + u8 bUsed; + u8 Bssid[6]; + u8 PMKID[16]; + u8 SsidBuf[33]; + u8* ssid_octet; + u16 ssid_length; +} RT_PMKID_LIST, *PRT_PMKID_LIST; + + +struct security_priv +{ + u32 dot11AuthAlgrthm; // 802.11 auth, could be open, shared, 8021x and authswitch + u32 dot11PrivacyAlgrthm; // This specify the privacy for shared auth. algorithm. + + /* WEP */ + u32 dot11PrivacyKeyIndex; // this is only valid for legendary wep, 0~3 for key id. (tx key index) + union Keytype dot11DefKey[4]; // this is only valid for def. key + u32 dot11DefKeylen[4]; + + u32 dot118021XGrpPrivacy; // This specify the privacy algthm. used for Grp key + u32 dot118021XGrpKeyid; // key id used for Grp Key ( tx key index) + union Keytype dot118021XGrpKey[4]; // 802.1x Group Key, for inx0 and inx1 + union Keytype dot118021XGrptxmickey[4]; + union Keytype dot118021XGrprxmickey[4]; + union pn48 dot11Grptxpn; // PN48 used for Grp Key xmit. + union pn48 dot11Grprxpn; // PN48 used for Grp Key recv. + +#ifdef CONFIG_AP_MODE + //extend security capabilities for AP_MODE + unsigned int dot8021xalg;//0:disable, 1:psk, 2:802.1x + unsigned int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + unsigned int wpa_group_cipher; + unsigned int wpa2_group_cipher; + unsigned int wpa_pairwise_cipher; + unsigned int wpa2_pairwise_cipher; +#endif + +#ifdef CONFIG_WPS + u8 wps_ie[MAX_WPS_IE_LEN];//added in assoc req + int wps_ie_len; +#endif + + u8 binstallGrpkey; + u8 busetkipkey; + //_timer tkip_timer; + u8 bcheck_grpkey; + u8 bgrpkey_handshake; + + //u8 packet_cnt;//unused, removed + + s32 sw_encrypt;//from registry_priv + s32 sw_decrypt;//from registry_priv + + s32 hw_decrypted;//if the rx packets is hw_decrypted==_FALSE, it means the hw has not been ready. + + + //keeps the auth_type & enc_status from upper layer ioctl(wpa_supplicant or wzc) + u32 ndisauthtype; // NDIS_802_11_AUTHENTICATION_MODE + u32 ndisencryptstatus; // NDIS_802_11_ENCRYPTION_STATUS + + //WLAN_BSSID_EX sec_bss; //for joinbss (h2c buffer) usage //YJ,del,140410 + + NDIS_802_11_WEP ndiswep; +#ifdef PLATFORM_WINDOWS + u8 KeyMaterial[16];// variable length depending on above field. +#endif + +//TODO +#if 0 //Remove unused wpa2 data - Alex Fang + u8 assoc_info[600]; + u8 szofcapability[256]; //for wpa2 usage + u8 oidassociation[512]; //for wpa/wpa2 usage + u8 authenticator_ie[256]; //store ap security information element +#endif + u8 supplicant_ie[256]; //store sta security information element + + + //for tkip countermeasure + u32 last_mic_err_time; + u8 btkip_countermeasure; + u8 btkip_wait_report; + u32 btkip_countermeasure_time; +#ifdef CONFIG_WPA2_PREAUTH + //--------------------------------------------------------------------------- + // For WPA2 Pre-Authentication. + //--------------------------------------------------------------------------- + //u8 RegEnablePreAuth; // Default value: Pre-Authentication enabled or not, from registry "EnablePreAuth". Added by Annie, 2005-11-01. + //u8 EnablePreAuthentication; // Current Value: Pre-Authentication enabled or not. + RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE]; // Renamed from PreAuthKey[NUM_PRE_AUTH_KEY]. Annie, 2006-10-13. + u8 PMKIDIndex; + //u32 PMKIDCount; // Added by Annie, 2006-10-13. + //u8 szCapability[256]; // For WPA2-PSK using zero-config, by Annie, 2005-09-20. +#endif + +#ifdef CONFIG_INCLUDE_WPA_PSK + WPA_GLOBAL_INFO wpa_global_info; +#if defined(CONFIG_AP_MODE) && defined(CONFIG_MULTIPLE_WPA_STA) +// WPA_STA_INFO wpa_sta_info[AP_STA_NUM]; + u8 *palloc_wpastainfo_buf; + u32 alloc_wpastainfo_size; + WPA_STA_INFO *wpa_sta_info[NUM_STA-2]; +#else + WPA_STA_INFO wpa_sta_info; +#endif + u8 wpa_passphrase[IW_PASSPHRASE_MAX_SIZE + 1]; +#endif +#ifdef CONFIG_WPS + u8 wps_phase; +#endif +}; + +struct sha256_state { + u64 length; + u32 state[8], curlen; + u8 buf[64]; +}; + + +#define GET_ENCRY_ALGO(psecuritypriv, psta, encry_algo, bmcst)\ +do{\ + switch(psecuritypriv->dot11AuthAlgrthm)\ + {\ + case dot11AuthAlgrthm_Open:\ + case dot11AuthAlgrthm_Shared:\ + case dot11AuthAlgrthm_Auto:\ + encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;\ + break;\ + case dot11AuthAlgrthm_8021X:\ + if(bmcst)\ + encry_algo = (u8)psecuritypriv->dot118021XGrpPrivacy;\ + else\ + encry_algo =(u8) psta->dot118021XPrivacy;\ + break;\ + case dot11AuthAlgrthm_WAPI:\ + encry_algo = (u8)psecuritypriv->dot11PrivacyAlgrthm;\ + break;\ + }\ +}while(0) + + +#define SET_ICE_IV_LEN( iv_len, icv_len, encrypt)\ +do{\ + switch(encrypt)\ + {\ + case _WEP40_:\ + case _WEP104_:\ + iv_len = 4;\ + icv_len = 4;\ + break;\ + case _TKIP_:\ + iv_len = 8;\ + icv_len = 4;\ + break;\ + case _AES_:\ + iv_len = 8;\ + icv_len = 8;\ + break;\ + case _SMS4_:\ + iv_len = 18;\ + icv_len = 16;\ + break;\ + default:\ + iv_len = 0;\ + icv_len = 0;\ + break;\ + }\ +}while(0) + + +#define GET_TKIP_PN(iv,dot11txpn)\ +do{\ + dot11txpn._byte_.TSC0=iv[2];\ + dot11txpn._byte_.TSC1=iv[0];\ + dot11txpn._byte_.TSC2=iv[4];\ + dot11txpn._byte_.TSC3=iv[5];\ + dot11txpn._byte_.TSC4=iv[6];\ + dot11txpn._byte_.TSC5=iv[7];\ +}while(0) + + +#define ROL32( A, n ) ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ROR32( A, n ) ROL32( (A), 32-(n) ) + +extern const u32 Te0[256]; +extern const u32 Te1[256]; +extern const u32 Te2[256]; +extern const u32 Te3[256]; +extern const u32 Te4[256]; +extern const u32 Td0[256]; +extern const u32 Td1[256]; +extern const u32 Td2[256]; +extern const u32 Td3[256]; +extern const u32 Td4[256]; +extern const u32 rcon[10]; +extern const u8 Td4s[256]; +extern const u8 rcons[10]; + +#define RCON(i) (rcons[(i)] << 24) + +static inline u32 rotr(u32 val, int bits) +{ + return (val >> bits) | (val << (32 - bits)); +} + +#define TE0(i) Te0[((i) >> 24) & 0xff] +#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8) +#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16) +#define TE3(i) rotr(Te0[(i) & 0xff], 24) +#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000) +#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000) +#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00) +#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff) +#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000) +#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000) +#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00) +#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff) +#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff) + +#define TD0(i) Td0[((i) >> 24) & 0xff] +#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8) +#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16) +#define TD3(i) rotr(Td0[(i) & 0xff], 24) +#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24) +#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16) +#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8) +#define TD44(i) (Td4s[(i) & 0xff]) +#define TD0_(i) Td0[(i) & 0xff] +#define TD1_(i) rotr(Td0[(i) & 0xff], 8) +#define TD2_(i) rotr(Td0[(i) & 0xff], 16) +#define TD3_(i) rotr(Td0[(i) & 0xff], 24) + +#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \ + ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) + +#define PUTU32(ct, st) { \ +(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ +(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } + +#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) + +#define WPA_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define WPA_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define WPA_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +/* ===== start - public domain SHA256 implementation ===== */ + +/* This is based on SHA256 implementation in LibTomCrypt that was released into + * public domain by Tom St Denis. */ + +/* the K array */ +static const unsigned long K[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + + +/* Various logical functions */ +#define RORc(x, y) \ +( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \ + ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL) +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x), (n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +u32 rtw_aes_encrypt(_adapter *padapter, u8 *pxmitframe); +u32 rtw_tkip_encrypt(_adapter *padapter, u8 *pxmitframe); +void rtw_wep_encrypt(_adapter *padapter, u8 *pxmitframe); + +u32 rtw_aes_decrypt(_adapter *padapter, u8 *precvframe); +u32 rtw_tkip_decrypt(_adapter *padapter, u8 *precvframe); +void rtw_wep_decrypt(_adapter *padapter, u8 *precvframe); + +#ifdef CONFIG_TDLS +void wpa_tdls_generate_tpk(_adapter *padapter, struct sta_info *psta); +int wpa_tdls_ftie_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie, + u8 *mic); +int tdls_verify_mic(u8 *kck, u8 trans_seq, + u8 *lnkid, u8 *rsnie, u8 *timeoutie, u8 *ftie); +#endif //CONFIG_TDLS + +#ifdef PLATFORM_WINDOWS +void rtw_use_tkipkey_handler ( + IN PVOID SystemSpecific1, + IN PVOID FunctionContext, + IN PVOID SystemSpecific2, + IN PVOID SystemSpecific3 + ); +#endif +#ifdef PLATFORM_LINUX +void rtw_use_tkipkey_handler(void* FunctionContext); +#endif + +#ifdef PLATFORM_FREEBSD +void rtw_use_tkipkey_handler(void* FunctionContext); +#endif //PLATFORM_FREEBSD + +u32 rtw_init_sec_priv(_adapter *padapter); +void rtw_free_sec_priv(struct security_priv *psecpriv); + +#endif //__RTL871X_SECURITY_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/rtw_xmit.h b/USDK/component/common/drivers/wlan/realtek/include/rtw_xmit.h new file mode 100644 index 0000000..46e3379 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/rtw_xmit.h @@ -0,0 +1,839 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTW_XMIT_H_ +#define _RTW_XMIT_H_ + +/*--------------------------------------- + Define MAX_XMITBUF_SZ +---------------------------------------*/ +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_LX_HCI) + +#ifdef CONFIG_TX_AGGREGATION //effect only for SDIO and GSPI Interface +#define MAX_XMITBUF_SZ (20480) // 20k +#else +#if defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + + #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + #define HAL_INTERFACE_OVERHEAD_XMIT_BUF 12 //HAL_INTERFACE_CMD (4) + HAL_INTERFACE_STATUS (8) + #elif defined(CONFIG_LX_HCI) + #define HAL_INTERFACE_OVERHEAD_XMIT_BUF 0 + #endif + +// Consideration for MAX_XMITBUF_SZ size +// Check more detail information in MAX_SKB_BUF_SIZE +// Tx: [INTF_CMD][TX_DESC][WLAN_HDR][QoS][IV][SNAP][Data][MIC][ICV][INTF_STATUS] +// HAL_INTERFACE_OVERHEAD: HAL_INTERFACE_CMD is 4/0 for SPI/PCIE, HAL_INTERFACE_STATUS is 8/0 for SPI/PCIE +// WLAN_MAX_ETHFRM_LEN : May not be required because WLAN_HEADER +SNAP can totally +// cover ethernet header.Keep in only for safety. + +#ifndef CONFIG_DONT_CARE_TP +#define MAX_XMITBUF_SZ (HAL_INTERFACE_OVERHEAD_XMIT_BUF+\ + TXDESC_SIZE+\ + WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_ETHFRM_LEN +\ + SKB_RESERVED_FOR_SAFETY) +#else +#define MAX_XMITBUF_SZ (HAL_INTERFACE_OVERHEAD_XMIT_BUF+\ + TXDESC_SIZE+\ + WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_TX_ETHFRM_LEN +\ + SKB_RESERVED_FOR_SAFETY) +#endif + + +#else // Other OS +#define MAX_XMITBUF_SZ (12288) //12k 1536*8 +#endif //#ifdef PLATFORM_ECOS || defined(PLATFORM_FREERTOS) +#endif //#ifdef CONFIG_TX_AGGREGATION + +#elif defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI) + #errof "Undefined bus interface for MAX_XMITBUF_SZ" +#endif //interface define. SDIO/GSPI/LXbus/PCI/USB + + + +/*--------------------------------------------------------------*/ +/* Define MAX_XMITBUF_SZ */ +/*--------------------------------------------------------------*/ +#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) + +#if defined(PLATFORM_ECOS) +#define NR_XMITBUFF (8) +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#ifndef CONFIG_HIGH_TP +#define NR_XMITBUFF (2) //Decrease recv frame (8->2) due to memory limitation - YangJue +#else +#define NR_XMITBUFF (128) +#endif +#else +#define NR_XMITBUFF (128) +#endif //#ifdef PLATFORM_ECOS + +#elif defined(CONFIG_LX_HCI) +#define NR_XMITBUFF (8) + +#elif defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI) + #errof "Undefined bus interface for MAX_XMITBUF_SZ" +#endif //interface define + + +/*--------------------------------------------------------------*/ +/* Define XMITBUF_ALIGN_SZ */ +/*--------------------------------------------------------------*/ +#if defined(PLATFORM_OS_CE) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) +#define XMITBUF_ALIGN_SZ 4 +#else +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#define XMITBUF_ALIGN_SZ 4 +#else +#define XMITBUF_ALIGN_SZ 512 +#endif +#endif + +#define MAX_CMDBUF_SZ (5120) //(4096) +/*--------------------------------------------------------------*/ +/* Define xmit extension buff, size/numbers */ +/*--------------------------------------------------------------*/ +#define MAX_XMIT_EXTBUF_SZ (1536) + +#if defined(PLATFORM_ECOS) +#define NR_XMIT_EXTBUFF (16) //Decrease ext xmit buffer due to memory limitation - Alex Fang +#elif defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) +#define NR_XMIT_EXTBUFF (8) //Decrease ext xmit buffer due to memory limitation - Alex Fang +#else +#define NR_XMIT_EXTBUFF (32) +#endif //#ifdef PLATFORM_ECOS + +#define MAX_NUMBLKS (1) + +#define XMIT_VO_QUEUE (0) +#define XMIT_VI_QUEUE (1) +#define XMIT_BE_QUEUE (2) +#define XMIT_BK_QUEUE (3) + +#define VO_QUEUE_INX 0 +#define VI_QUEUE_INX 1 +#define BE_QUEUE_INX 2 +#define BK_QUEUE_INX 3 +#define BCN_QUEUE_INX 4 +#define MGT_QUEUE_INX 5 +#define HIGH_QUEUE_INX 6 +#define TXCMD_QUEUE_INX 7 +#ifdef CONFIG_WLAN_HAL_TEST +#define HIGH1_QUEUE_INX 8 +#define HIGH2_QUEUE_INX 9 +#define HIGH3_QUEUE_INX 10 +#define HIGH4_QUEUE_INX 11 +#define HIGH5_QUEUE_INX 12 +#define HIGH6_QUEUE_INX 13 +#define HIGH7_QUEUE_INX 14 +#define HW_QUEUE_ENTRY 15 +#else +#define HW_QUEUE_ENTRY 8 +#endif + +#define WEP_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC0;\ + pattrib_iv[1] = dot11txpn._byte_.TSC1;\ + pattrib_iv[2] = dot11txpn._byte_.TSC2;\ + pattrib_iv[3] = ((keyidx & 0x3)<<6);\ + dot11txpn.val = (dot11txpn.val == 0xffffff) ? 0: (dot11txpn.val+1);\ +}while(0) + + +#define TKIP_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC1;\ + pattrib_iv[1] = (dot11txpn._byte_.TSC1 | 0x20) & 0x7f;\ + pattrib_iv[2] = dot11txpn._byte_.TSC0;\ + pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ + pattrib_iv[4] = dot11txpn._byte_.TSC2;\ + pattrib_iv[5] = dot11txpn._byte_.TSC3;\ + pattrib_iv[6] = dot11txpn._byte_.TSC4;\ + pattrib_iv[7] = dot11txpn._byte_.TSC5;\ + dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0: (dot11txpn.val+1);\ +}while(0) + +#define AES_IV(pattrib_iv, dot11txpn, keyidx)\ +do{\ + pattrib_iv[0] = dot11txpn._byte_.TSC0;\ + pattrib_iv[1] = dot11txpn._byte_.TSC1;\ + pattrib_iv[2] = 0;\ + pattrib_iv[3] = BIT(5) | ((keyidx & 0x3)<<6);\ + pattrib_iv[4] = dot11txpn._byte_.TSC2;\ + pattrib_iv[5] = dot11txpn._byte_.TSC3;\ + pattrib_iv[6] = dot11txpn._byte_.TSC4;\ + pattrib_iv[7] = dot11txpn._byte_.TSC5;\ + dot11txpn.val = dot11txpn.val == 0xffffffffffffULL ? 0: (dot11txpn.val+1);\ +}while(0) + + +#define HWXMIT_ENTRY 4 + +#if defined(CONFIG_RTL8812A) || defined(CONFIG_RTL8821A)|| defined(CONFIG_RTL8723B) || defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) ||defined(CONFIG_RTL8188F) +#define TXDESC_SIZE 40 +#else +#define TXDESC_SIZE 32 +#endif + +#ifdef CONFIG_TX_EARLY_MODE +#define EARLY_MODE_INFO_SIZE 8 +#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) +#define TXDESC_OFFSET TXDESC_SIZE + +#endif + +#ifdef CONFIG_USB_HCI +#define PACKET_OFFSET_SZ (8) +#define TXDESC_OFFSET (TXDESC_SIZE + PACKET_OFFSET_SZ) +#endif + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B)// buffer descriptor architecture +#define TXDESC_OFFSET TXDESC_SIZE +#else +#define TXDESC_OFFSET 0 +#endif +#define TX_DESC_NEXT_DESC_OFFSET 40 +#endif + +#define TX_FRAGMENTATION_THRESHOLD 2346 + +// Suppose (TX_DESC_MODE=1) ==> Segment number for each tx_buf_desc is 4. 2X4 = 8 (double words). +struct tx_buf_desc { + unsigned int txdw0; + unsigned int txdw1; + unsigned int txdw2; + unsigned int txdw3; + unsigned int txdw4; + unsigned int txdw5; + unsigned int txdw6; + unsigned int txdw7; +}; + +struct tx_desc{ + + //DWORD 0 + unsigned int txdw0; + + unsigned int txdw1; + + unsigned int txdw2; + + unsigned int txdw3; + + unsigned int txdw4; + + unsigned int txdw5; + + unsigned int txdw6; + + unsigned int txdw7; +#ifdef CONFIG_PCI_HCI + unsigned int txdw8; + + unsigned int txdw9; + + unsigned int txdw10; + + unsigned int txdw11; + + // 2008/05/15 MH Because PCIE HW memory R/W 4K limit. And now, our descriptor + // size is 40 bytes. If you use more than 102 descriptor( 103*40>4096), HW will execute + // memoryR/W CRC error. And then all DMA fetch will fail. We must decrease descriptor + // number or enlarge descriptor size as 64 bytes. + unsigned int txdw12; + + unsigned int txdw13; + + unsigned int txdw14; + + unsigned int txdw15; +#endif +#if defined(CONFIG_LX_HCI)||defined(CONFIG_RTL8188F) + unsigned int txdw8; + + unsigned int txdw9; +#endif +}; + + +union txdesc { + struct tx_desc txdesc; + unsigned int value[TXDESC_SIZE>>2]; +}; + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#ifdef CONFIG_WLAN_HAL_TEST +#define PCI_MAX_TX_QUEUE_COUNT HW_QUEUE_ENTRY +#else +#define PCI_MAX_TX_QUEUE_COUNT 8 +#endif + +struct rtw_tx_ring { + +#if ((RTL8195A_SUPPORT ==1) ||(RTL8711B_SUPPORT == 1)) + struct tx_buf_desc *desc; +#else + struct tx_desc *desc; +#endif + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + _queue queue; + u32 qlen; +}; +#endif + +struct hw_xmit { + //_lock xmit_lock; + //_list pending; + _queue *sta_queue; + //struct hw_txqueue *phwtxqueue; + //sint txcmdcnt; + int accnt; +}; + +#if 0 +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + int pktlen; //the original 802.3 pkt raw_data len (not include ether_hdr data) + int pkt_hdrlen; //the original 802.3 pkt header len + int hdrlen; //the WLAN Header Len + int nr_frags; + int last_txcmdsz; + int encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv[8]; + int iv_len; + u8 icv[8]; + int icv_len; + int priority; + int ack_policy; + int mac_id; + int vcs_mode; //virtual carrier sense method + + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + + u8 key_idx; + + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 mdata;//more data bit + u8 eosp; + + u8 pctrl;//per packet txdesc control enable + u8 triggered;//for ap mode handling Power Saving sta + + u32 qsel; + u16 seqnum; + + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif +}; +#else +//reduce size +struct pkt_attrib +{ + u8 type; + u8 subtype; + u8 bswenc; + u8 dhcp_pkt; + u16 ether_type; + u16 seqnum; + u16 pkt_hdrlen; //the original 802.3 pkt header len + u16 hdrlen; //the WLAN Header Len + u32 pktlen; //the original 802.3 pkt raw_data len (not include ether_hdr data) + u32 last_txcmdsz; + u8 encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith + u8 iv_len; + u8 icv_len; + u8 iv[18]; + u8 icv[16]; + u8 priority; + u8 ack_policy; + u8 mac_id; + u8 vcs_mode; //virtual carrier sense method + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 ra[ETH_ALEN]; + u8 key_idx; + u8 qos_en; + u8 ht_en; + u8 raid;//rate adpative id + u8 bwmode; + u8 ch_offset;//PRIME_CHNL_OFFSET + u8 sgi;//short GI + u8 ampdu_en;//tx ampdu enable + u8 mdata;//more data bit + u8 pctrl;//per packet txdesc control enable + u8 triggered;//for ap mode handling Power Saving sta + u8 qsel; + u8 eosp; + u8 rate; + u8 intel_proxim; + u8 retry_ctrl; + struct sta_info * psta; +#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX + u8 hw_tcp_csum; +#endif +}; +#endif + +#ifdef PLATFORM_FREEBSD +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ + +/*struct rtw_ieee80211_hdr { + uint16_t frame_control; + uint16_t duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + uint16_t seq_ctrl; + u8 addr4[6]; +} ;*/ +#endif //PLATFORM_FREEBSD + +#define WLANHDR_OFFSET 64 + +#define NULL_FRAMETAG (0x0) +#define DATA_FRAMETAG 0x01 +#define L2_FRAMETAG 0x02 +#define MGNT_FRAMETAG 0x03 +#define AMSDU_FRAMETAG 0x04 + +#define EII_FRAMETAG 0x05 +#define IEEE8023_FRAMETAG 0x06 + +#define MP_FRAMETAG 0x07 + +#define TXAGG_FRAMETAG 0x08 + +enum { + XMITBUF_DATA = 0, + XMITBUF_MGNT = 1, + XMITBUF_CMD = 2, +}; + +struct submit_ctx{ + u32 submit_time; /* */ + u32 timeout_ms; /* <0: not synchronous, 0: wait forever, >0: up to ms waiting */ + int status; /* status for operation */ +#ifdef PLATFORM_LINUX + struct completion done; +#endif +}; + +enum { + RTW_SCTX_DONE_SUCCESS = 0, + RTW_SCTX_DONE_UNKNOWN, + RTW_SCTX_DONE_BUF_ALLOC, + RTW_SCTX_DONE_BUF_FREE, + RTW_SCTX_DONE_WRITE_PORT_ERR, + RTW_SCTX_DONE_TX_DESC_NA, + RTW_SCTX_DONE_TX_DENY, +}; + + +void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms); +int rtw_sctx_wait(struct submit_ctx *sctx); +void rtw_sctx_done_err(struct submit_ctx **sctx, int status); +void rtw_sctx_done(struct submit_ctx **sctx); + +typedef struct _XIMT_BUF_ { + u32 AllocatBufAddr; + u32 BufAddr; + u32 BufLen; +}XIMT_BUF, *PXIMT_BUF; + +struct xmit_buf +{ + _list list; + + _adapter *padapter; + +#if USE_SKB_AS_XMITBUF + _pkt *pkt; +#else + u8 *pallocated_buf; +#endif + u8 *pbuf; + + void *priv_data; + + u16 buf_tag; // 0: Normal xmitbuf, 1: extension xmitbuf, 2:cmd xmitbuf + u16 flags; + u32 alloc_sz; + + u32 len; + + struct submit_ctx *sctx; + +#ifdef CONFIG_USB_HCI + + //u32 sz[8]; + u32 ff_hwaddr; + +#if defined(PLATFORM_OS_XP)||defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) + PURB pxmit_urb[8]; + dma_addr_t dma_transfer_addr; /* (in) dma addr for transfer_buffer */ +#endif + +#ifdef PLATFORM_OS_XP + PIRP pxmit_irp[8]; +#endif + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +#endif + + u8 bpending[8]; + + sint last[8]; + +#endif + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 *phead; + u8 *pdata; + u8 *ptail; + u8 *pend; + u32 ff_hwaddr; + u8 pg_num; + u8 agg_num; +#ifdef PLATFORM_OS_XP + PMDL pxmitbuf_mdl; + PIRP pxmitbuf_irp; + PSDBUS_REQUEST_PACKET pxmitbuf_sdrp; +#endif +#endif + +#if defined(DBG_XMIT_BUF )|| defined(DBG_XMIT_BUF_EXT) + u8 no; +#endif + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#if ((RTL8195A_SUPPORT ==1) ||(RTL8711B_SUPPORT == 1)) + XIMT_BUF BufInfo[4]; + u32 BlockNum; +#endif +#endif +}; + + +struct xmit_frame +{ + _list list; + + struct pkt_attrib attrib; + + _pkt *pkt; + + int frame_tag; + + _adapter *padapter; + + u8 *buf_addr; + + struct xmit_buf *pxmitbuf; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + u8 pg_num; + u8 agg_num; +#endif + +#ifdef CONFIG_USB_HCI +#ifdef CONFIG_USB_TX_AGGREGATION + u8 agg_num; +#endif + s8 pkt_offset; +#ifdef CONFIG_RTL8192D + u8 EMPktNum; + u16 EMPktLen[5];//The max value by HW +#endif +#endif + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#if ((RTL8195A_SUPPORT ==1) ||(RTL8711B_SUPPORT == 1)) + u32 TxDexAddr; + u32 HdrLen; + u32 PayLoadAddr; + u32 PayLoadLen; + u32 TotalLen; + u32 BlockNum; + XIMT_BUF BufInfo[4]; + BOOLEAN NoCoalesce; +#endif +#endif +}; + +struct tx_servq { + _list tx_pending; + _queue sta_pending; + int qcnt; +}; + +struct sta_xmit_priv +{ + _lock lock; + sint option; + sint apsd_setting; //When bit mask is on, the associated edca queue supports APSD. + + + //struct tx_servq blk_q[MAX_NUMBLKS]; + struct tx_servq be_q; //priority == 0,3 + struct tx_servq bk_q; //priority == 1,2 + struct tx_servq vi_q; //priority == 4,5 + struct tx_servq vo_q; //priority == 6,7 + _list legacy_dz; + _list apsd; + + u16 txseq_tid[16]; + + //uint sta_tx_bytes; + //u64 sta_tx_pkts; + //uint sta_tx_fail; + + +}; + + +struct hw_txqueue { + volatile sint head; + volatile sint tail; + volatile sint free_sz; //in units of 64 bytes + volatile sint free_cmdsz; + volatile sint txsz[8]; + uint ff_hwaddr; + uint cmd_hwaddr; + sint ac_tag; +}; + +struct agg_pkt_info{ + u16 offset; + u16 pkt_len; +}; + + +struct xmit_priv { + + _lock lock; + + //_queue blk_strms[MAX_NUMBLKS]; + _queue be_pending; + _queue bk_pending; + _queue vi_pending; + _queue vo_pending; + _queue bm_pending; + + //_queue legacy_dz_queue; + //_queue apsd_queue; + + u8 *pallocated_frame_buf; + u8 *pxmit_frame_buf; + uint free_xmitframe_cnt; + + //uint mapping_addr; + //uint pkt_sz; + + _queue free_xmit_queue; + + //struct hw_txqueue be_txqueue; + //struct hw_txqueue bk_txqueue; + //struct hw_txqueue vi_txqueue; + //struct hw_txqueue vo_txqueue; + //struct hw_txqueue bmc_txqueue; + + _adapter *adapter; + + u8 vcs_setting; + u8 vcs; + u8 vcs_type; + //u16 rts_thresh; + + u64 tx_bytes; + u64 tx_pkts; + u64 tx_drop; + u64 last_tx_bytes; + u64 last_tx_pkts; + + struct hw_xmit *hwxmits; + u8 hwxmit_entry; + +#ifdef CONFIG_USB_HCI + _sema tx_retevt;//all tx return event; + u8 txirp_cnt;// + +#ifdef PLATFORM_OS_CE + USB_TRANSFER usb_transfer_write_port; +// USB_TRANSFER usb_transfer_write_mem; +#endif +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#ifdef PLATFORM_FREEBSD + struct task xmit_tasklet; +#endif + //per AC pending irp + int beq_cnt; + int bkq_cnt; + int viq_cnt; + int voq_cnt; + +#endif + +#if defined(CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) + // Tx + struct rtw_tx_ring tx_ring[PCI_MAX_TX_QUEUE_COUNT]; + int txringcount[PCI_MAX_TX_QUEUE_COUNT]; + u8 beaconDMAing; //flag of indicating beacon is transmiting to HW by DMA +#ifdef PLATFORM_LINUX + struct tasklet_struct xmit_tasklet; +#endif +#endif + + _queue free_xmitbuf_queue; + _queue pending_xmitbuf_queue; + u8 *pallocated_xmitbuf; + u8 *pxmitbuf; + uint free_xmitbuf_cnt; +#if USE_XMIT_EXTBUFF + _queue free_xmit_extbuf_queue; + u8 *pallocated_xmit_extbuf; + u8 *pxmit_extbuf; + uint free_xmit_extbuf_cnt; +#endif + u16 nqos_ssn; + #ifdef CONFIG_TX_EARLY_MODE + + #define MAX_AGG_PKT_NUM 256 //Max tx ampdu coounts + + struct agg_pkt_info agg_pkt[MAX_AGG_PKT_NUM]; + #endif +}; + +#ifdef CONFIG_TRACE_SKB +extern struct xmit_buf *_rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv, u32 size); + +//extern struct xmit_frame *_rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +//extern s32 _rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); +//extern void _rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); + +#define rtw_alloc_xmitbuf_ext(pxmitpriv, pxmitbuf, size) \ + (\ + pxmitbuf = _rtw_alloc_xmitbuf_ext(pxmitpriv, size),\ + pxmitbuf ? set_skb_list_flag(pxmitbuf->pkt, SKBLIST_XMITEXTBUF):0,\ + pxmitbuf\ + ) +#else +extern struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv, u32 size); +#endif +extern s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +extern struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); + +extern struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv); +extern s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); +extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); +struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, u8 *ac); +extern s32 rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +extern struct xmit_frame* rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); + +void rtw_count_tx_stats(_adapter *padapter, struct xmit_frame *pxmitframe, int sz); +extern void rtw_update_protection(_adapter *padapter, u8 *ie, uint ie_len); +extern s32 rtw_make_wlanhdr(_adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib); +extern s32 rtw_put_snap(u8 *data, u16 h_proto); + +extern s32 rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); +extern u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); +#define rtw_wlan_pkt_size(f) rtw_calculate_wlan_pkt_size_by_attribue(&f->attrib) +extern s32 rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +#ifdef CONFIG_TDLS +s32 rtw_xmit_tdls_coalesce(_adapter *padapter, struct xmit_frame *pxmitframe, u8 action); +#endif +s32 _rtw_init_hw_txqueue(struct hw_txqueue* phw_txqueue, u8 ac_tag); +void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); + + +s32 rtw_txframes_pending(_adapter *padapter); +s32 rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib); +void rtw_txframes_update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry); + + +s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter); +void _rtw_free_xmit_priv (struct xmit_priv *pxmitpriv); + + +void rtw_alloc_hwxmits(_adapter *padapter); +void rtw_free_hwxmits(_adapter *padapter); + + +s32 rtw_xmit(_adapter *padapter, _pkt **pkt); + +#if defined(CONFIG_AP_MODE) || defined(CONFIG_TDLS) +sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); +void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); +void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta); +#endif + +u8 qos_acm(u8 acm_mask, u8 priority); + +s32 xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe); + +#ifdef CONFIG_XMIT_THREAD_MODE +void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf); +struct xmit_buf* dequeue_pending_xmitbuf(struct xmit_priv *pxmitpriv); +struct xmit_buf* dequeue_pending_xmitbuf_under_survey(struct xmit_priv *pxmitpriv); +sint check_pending_xmitbuf(struct xmit_priv *pxmitpriv); +thread_return rtw_xmit_thread(thread_context context); +#endif + +u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe); + +extern s32 rtw_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe); +extern s32 rtw_xmit_data(PADAPTER padapter, struct xmit_frame *pxmitframe); +extern s32 rtw_xmit_xmitbuf(_adapter * padapter, struct xmit_buf *pxmitbuf); +extern u32 ffaddr2deviceId(struct dvobj_priv *pdvobj, u32 addr); +extern unsigned int nr_xmitframe; +extern unsigned int nr_xmitbuff; +#endif //_RTL871X_XMIT_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/sta_info.h b/USDK/component/common/drivers/wlan/realtek/include/sta_info.h new file mode 100644 index 0000000..3ea91a5 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/sta_info.h @@ -0,0 +1,400 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __STA_INFO_H_ +#define __STA_INFO_H_ + +#define IBSS_START_MAC_ID 2 + +#if 0 //move to wifi.h +#if defined(PLATFORM_ECOS) +#define NUM_STA 10 //Decrease STA due to memory limitation - Alex Fang +#elif defined(PLATFORM_FREERTOS) +//Decrease STA due to memory limitation - Alex Fang +#ifdef CONFIG_AP_MODE +#define NUM_STA (2 + AP_STA_NUM) //2 + supported clients +#else +#define NUM_STA 2 //Client mode sta for AP and broadcast +#endif +#else +#define NUM_STA 32 +#endif +#endif + +#define NUM_ACL 16 + +//if mode ==0, then the sta is allowed once the addr is hit. +//if mode ==1, then the sta is rejected once the addr is non-hit. +struct rtw_wlan_acl_node { + _list list; + u8 addr[ETH_ALEN]; + u8 valid; +}; + +//mode=0, disable +//mode=1, accept unless in deny list +//mode=2, deny unless in accept list +struct wlan_acl_pool { + int mode; + int num; + struct rtw_wlan_acl_node aclnode[NUM_ACL]; + _queue acl_node_q; +}; + +typedef struct _RSSI_STA{ + s32 UndecoratedSmoothedPWDB; + s32 UndecoratedSmoothedCCK; + s32 UndecoratedSmoothedOFDM; + u64 PacketMap; + u8 ValidBit; + u32 OFDM_pkt; +}RSSI_STA, *PRSSI_STA; + +struct stainfo_stats { + + //u64 rx_pkts; + u64 rx_mgnt_pkts; + u64 rx_ctrl_pkts; + u64 rx_data_pkts; + + //u64 last_rx_pkts; + u64 last_rx_mgnt_pkts; + u64 last_rx_ctrl_pkts; + u64 last_rx_data_pkts; + + u64 rx_bytes; +// u64 rx_drops; + + u64 tx_pkts; + u64 tx_bytes; +// u64 tx_drops; + +}; + +#ifdef CONFIG_TDLS +struct TDLS_PeerKey { + u8 kck[16]; /* TPK-KCK */ + u8 tk[16]; /* TPK-TK; only CCMP will be used */ +} ; +#endif //CONFIG_TDLS + +struct sta_info { + + _lock lock; + _list list; //free_sta_queue + _list hash_list; //sta_hash + //_list asoc_list; //20061114 + //_list sleep_list;//sleep_q + //_list wakeup_list;//wakeup_q + _adapter *padapter; + + struct sta_xmit_priv sta_xmitpriv; + struct sta_recv_priv sta_recvpriv; + + _queue sleep_q; + unsigned int sleepq_len; + + uint state; + uint aid; + uint mac_id; + uint qos_option; + u8 hwaddr[ETH_ALEN]; + + uint ieee8021x_blocked; //0: allowed, 1:blocked + uint dot118021XPrivacy; //aes, tkip... + union Keytype dot11tkiptxmickey; + union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; + union pn48 dot11txpn; // PN48 used for Unicast xmit. + union pn48 dot11rxpn; // PN48 used for Unicast recv. + + + u8 bssrateset[16]; + u32 bssratelen; + s32 rssi; + s32 signal_quality; + + u8 cts2self; + u8 rtsen; + + u8 raid; + u8 init_rate; + u32 ra_mask; + u8 wireless_mode; // NETWORK_TYPE + struct stainfo_stats sta_stats; + +#ifdef CONFIG_TDLS + u32 tdls_sta_state; + u8 dialog; + u8 SNonce[32]; + u8 ANonce[32]; + u32 TDLS_PeerKey_Lifetime; + u16 TPK_count; + _timer TPK_timer; + struct TDLS_PeerKey tpk; + u16 stat_code; + u8 off_ch; + u16 ch_switch_time; + u16 ch_switch_timeout; + u8 option; + _timer option_timer; + _timer base_ch_timer; + _timer off_ch_timer; + + _timer handshake_timer; + _timer alive_timer1; + _timer alive_timer2; + u8 timer_flag; + u8 alive_count; +#endif //CONFIG_TDLS + + //for A-MPDU TX, ADDBA timeout check + _timer addba_retry_timer; +#ifdef CONFIG_RECV_REORDERING_CTRL + //for A-MPDU Rx reordering buffer control + struct recv_reorder_ctrl recvreorder_ctrl[16]; +#endif + //for A-MPDU Tx + //unsigned char ampdu_txen_bitmap; + u16 BA_starting_seqctrl[16]; + + +#ifdef CONFIG_80211N_HT + struct ht_priv htpriv; +#endif + + //Notes: + //STA_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) + sta_info: (STA & AP) CAP/INFO + //scan_q: AP CAP/INFO + + //AP_Mode: + //curr_network(mlme_priv/security_priv/qos/ht) : AP CAP/INFO + //sta_info: (AP & STA) CAP/INFO + +#ifdef CONFIG_AP_MODE + + _list asoc_list; + _list auth_list; + + unsigned int expire_to; +#ifdef CONFIG_AP_POLLING_CLIENT_ALIVE + unsigned int tx_null0; + unsigned int tx_null0_fail; + unsigned int tx_null0_retry; +#endif + unsigned int auth_seq; + unsigned int authalg; + unsigned char chg_txt[128]; + + u16 capability; + u32 flags; + + int dot8021xalg;//0:disable, 1:psk, 2:802.1x + int wpa_psk;//0:disable, bit(0): WPA, bit(1):WPA2 + int wpa_group_cipher; + int wpa2_group_cipher; + int wpa_pairwise_cipher; + int wpa2_pairwise_cipher; + + u8 bpairwise_key_installed; + +#ifdef CONFIG_NATIVEAP_MLME + u8 wpa_ie[32]; + + u8 nonerp_set; + u8 no_short_slot_time_set; + u8 no_short_preamble_set; + u8 no_ht_gf_set; + u8 no_ht_set; + u8 ht_20mhz_set; +#endif // CONFIG_NATIVEAP_MLME + + unsigned int tx_ra_bitmap; + u8 qos_info; + + u8 max_sp_len; + u8 uapsd_bk;//BIT(0): Delivery enabled, BIT(1): Trigger enabled + u8 uapsd_be; + u8 uapsd_vi; + u8 uapsd_vo; + + u8 has_legacy_ac; + unsigned int sleepq_ac_len; + +#ifdef CONFIG_P2P + //p2p priv data + u8 is_p2p_device; + u8 p2p_status_code; + + //p2p client info + u8 dev_addr[ETH_ALEN]; + //u8 iface_addr[ETH_ALEN];//= hwaddr[ETH_ALEN] + u8 dev_cap; + u16 config_methods; + u8 primary_dev_type[8]; + u8 num_of_secdev_type; + u8 secdev_types_list[32];// 32/8 == 4; + u16 dev_name_len; + u8 dev_name[32]; +#endif //CONFIG_P2P + +#ifdef CONFIG_TX_MCAST2UNI + u8 under_exist_checking; +#endif // CONFIG_TX_MCAST2UNI + +#endif // CONFIG_AP_MODE + +#ifdef CONFIG_IOCTL_CFG80211 + u8 *passoc_req; + u32 assoc_req_len; +#endif + + //for DM + RSSI_STA rssi_stat; + + // + // ================ODM Relative Info======================= + // Please be care, dont declare too much structure here. It will cost memory * STA support num. + // + // + // 2011/10/20 MH Add for ODM STA info. + // + // Driver Write + u8 bValid; // record the sta status link or not? + //u8 WirelessMode; // + u8 IOTPeer; // Enum value. HT_IOT_PEER_E + u8 rssi_level; //for Refresh RA mask + // ODM Write + //1 PHY_STATUS_INFO + u8 RSSI_Path[4]; // + u8 RSSI_Ave; + u8 RXEVM[4]; + u8 RXSNR[4]; + + // ODM Write + //1 TX_INFO (may changed by IC) + //TX_INFO_T pTxInfo; // Define in IC folder. Move lower layer. + // + // ================ODM Relative Info======================= + // +}; + +#define sta_rx_pkts(sta) \ + (sta->sta_stats.rx_mgnt_pkts \ + + sta->sta_stats.rx_ctrl_pkts \ + + sta->sta_stats.rx_data_pkts) + +#define sta_last_rx_pkts(sta) \ + (sta->sta_stats.last_rx_mgnt_pkts \ + + sta->sta_stats.last_rx_ctrl_pkts \ + + sta->sta_stats.last_rx_data_pkts) + +#define sta_update_last_rx_pkts(sta) \ + do { \ + sta->sta_stats.last_rx_mgnt_pkts = sta->sta_stats.rx_mgnt_pkts; \ + sta->sta_stats.last_rx_ctrl_pkts = sta->sta_stats.rx_ctrl_pkts; \ + sta->sta_stats.last_rx_data_pkts = sta->sta_stats.rx_data_pkts; \ + } while(0) + +#define STA_RX_PKTS_ARG(sta) \ + sta->sta_stats.rx_mgnt_pkts \ + , sta->sta_stats.rx_ctrl_pkts \ + , sta->sta_stats.rx_data_pkts + +#define STA_LAST_RX_PKTS_ARG(sta) \ + sta->sta_stats.last_rx_mgnt_pkts \ + , sta->sta_stats.last_rx_ctrl_pkts \ + , sta->sta_stats.last_rx_data_pkts + +#define STA_PKTS_FMT "(m:%llu, c:%llu, d:%llu)" + +struct sta_priv { + + u8 *pallocated_stainfo_buf; + u32 allocated_stainfo_size; + u8 *pstainfo_buf; + _queue free_sta_queue; + + _lock sta_hash_lock; + _list sta_hash[NUM_STA]; + int asoc_sta_count; + _queue sleep_q; + _queue wakeup_q; + + _adapter *padapter; + + +#ifdef CONFIG_AP_MODE + _list asoc_list; + _list auth_list; + _lock asoc_list_lock; + _lock auth_list_lock; + + unsigned int auth_to; //sec, time to expire in authenticating. + unsigned int assoc_to; //sec, time to expire before associating. + unsigned int expire_to; //sec , time to expire after associated. + + /* pointers to STA info; based on allocated AID or NULL if AID free + * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1 + * and so on + */ + struct sta_info *sta_aid[NUM_STA]; + + u16 sta_dz_bitmap;//only support 15 stations, staion aid bitmap for sleeping sta. + u16 tim_bitmap;//only support 15 stations, aid=0~15 mapping bit0~bit15 + + u16 max_num_sta; +//TODO: AP +// struct wlan_acl_pool acl_list; +#endif + +}; + + +__inline static u32 wifi_mac_hash(u8 *mac) +{ + u32 x; + + x = mac[0]; + x = (x << 2) ^ mac[1]; + x = (x << 2) ^ mac[2]; + x = (x << 2) ^ mac[3]; + x = (x << 2) ^ mac[4]; + x = (x << 2) ^ mac[5]; + + x ^= x >> 8; + x = x & (NUM_STA - 1); + + return x; +} + + +extern u32 _rtw_init_sta_priv(_adapter *padapter); +extern u32 _rtw_free_sta_priv(struct sta_priv *pstapriv); +extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_free_stainfo(_adapter *padapter , struct sta_info *psta); +extern void rtw_free_all_stainfo(_adapter *padapter); +extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr); +extern u32 rtw_init_bcmc_stainfo(_adapter* padapter); +extern struct sta_info* rtw_get_bcmc_stainfo(_adapter* padapter); +extern u8 rtw_access_ctrl(_adapter *padapter, u8 *mac_addr); + +#endif //_STA_INFO_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/wifi.h b/USDK/component/common/drivers/wlan/realtek/include/wifi.h new file mode 100644 index 0000000..1ab28fe --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wifi.h @@ -0,0 +1,1369 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _WIFI_H_ +#define _WIFI_H_ + +#include +#include + + +#ifdef BIT +//#error "BIT define occurred earlier elsewhere!\n" +#undef BIT +#endif +#define BIT(x) ((u32)1 << (x)) + +#if defined(PLATFORM_ECOS) +#define NUM_STA 10 //Decrease STA due to memory limitation - Alex Fang +#elif defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) +//Decrease STA due to memory limitation - Alex Fang +#ifdef CONFIG_AP_MODE +#define NUM_STA (2 + AP_STA_NUM) //2 + supported clients +#else +#define NUM_STA 2 //Client mode sta for AP and broadcast +#endif +#else +#define NUM_STA 32 +#endif + +#define WLAN_ETHHDR_LEN 14 +#define WLAN_ETHADDR_LEN 6 +#define WLAN_IEEE_OUI_LEN 3 +#define WLAN_ADDR_LEN 6 +#define WLAN_CRC_LEN 4 +#define WLAN_BSSID_LEN 6 +#define WLAN_BSS_TS_LEN 8 +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +#define WLAN_HDR_A3_QOS_LEN 26 +#define WLAN_HDR_A4_QOS_LEN 32 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_DATA_MAXLEN 2312 + +#define WLAN_A3_PN_OFFSET 24 +#define WLAN_A4_PN_OFFSET 30 + +#define WLAN_MIN_ETHFRM_LEN 60 +#ifndef CONFIG_DONT_CARE_TP +#if WIFI_LOGO_CERTIFICATION +#define WLAN_MAX_ETHFRM_LEN 4000 +#else +#define WLAN_MAX_ETHFRM_LEN 1514 +#endif +#else +#define WLAN_MAX_RX_ETHFRM_LEN 1514 +#define WLAN_MAX_TX_ETHFRM_LEN 590 +#endif +#define WLAN_ETHHDR_LEN 14 +#define WLAN_SNAP_HEADER 8 +#define WLAN_MAX_IV_LEN 8 +#define WLAN_MAX_ICV_LEN 8 +#define WLAN_MAX_MIC_LEN 8 +#define WLAN_MAX_PROTOCOL_OVERHEAD (WLAN_HDR_A4_QOS_LEN+WLAN_MAX_IV_LEN\ + +WLAN_SNAP_HEADER+WLAN_MAX_MIC_LEN+WLAN_MAX_ICV_LEN) //=64 + +#define P80211CAPTURE_VERSION 0x80211001 + +// This value is tested by WiFi 11n Test Plan 5.2.3. +// This test verifies the WLAN NIC can update the NAV through sending the CTS with large duration. +#define WiFiNavUpperUs 30000 // 30 ms +// enum WLAN_IDX{ +// WLAN0_IDX = 0, +// WLAN1_IDX, +// WLAN_UNDEF = -1 +// }; + +#ifdef GREEN_HILL +#pragma pack(1) +#endif + +enum WIFI_FRAME_TYPE { + WIFI_MGT_TYPE = (0), + WIFI_CTRL_TYPE = (BIT(2)), + WIFI_DATA_TYPE = (BIT(3)), + WIFI_QOS_DATA_TYPE = (BIT(7)|BIT(3)), //!< QoS Data +}; + +enum WIFI_FRAME_SUBTYPE { + + // below is for mgt frame + WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), + WIFI_ASSOCRSP = (BIT(4) | WIFI_MGT_TYPE), + WIFI_REASSOCREQ = (BIT(5) | WIFI_MGT_TYPE), + WIFI_REASSOCRSP = (BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), + WIFI_PROBERSP = (BIT(6) | BIT(4) | WIFI_MGT_TYPE), + WIFI_BEACON = (BIT(7) | WIFI_MGT_TYPE), + WIFI_ATIM = (BIT(7) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DISASSOC = (BIT(7) | BIT(5) | WIFI_MGT_TYPE), + WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), + WIFI_DEAUTH = (BIT(7) | BIT(6) | WIFI_MGT_TYPE), + WIFI_ACTION = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE), + + // below is for control frame + WIFI_PSPOLL = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_RTS = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CTS = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE), + WIFI_ACK = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE), + WIFI_CFEND = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE), + WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE), + + // below is for data frame + WIFI_DATA = (0 | WIFI_DATA_TYPE), + WIFI_DATA_CFACK = (BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_CFPOLL = (BIT(5) | WIFI_DATA_TYPE), + WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_DATA_NULL = (BIT(6) | WIFI_DATA_TYPE), + WIFI_CF_ACK = (BIT(6) | BIT(4) | WIFI_DATA_TYPE), + WIFI_CF_POLL = (BIT(6) | BIT(5) | WIFI_DATA_TYPE), + WIFI_CF_ACKPOLL = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE), + WIFI_QOS_DATA_NULL = (BIT(6) | WIFI_QOS_DATA_TYPE), +}; + +enum WIFI_REASON_CODE { + _RSON_RESERVED_ = 0, + _RSON_UNSPECIFIED_ = 1, + _RSON_AUTH_NO_LONGER_VALID_ = 2, + _RSON_DEAUTH_STA_LEAVING_ = 3, + _RSON_INACTIVITY_ = 4, + _RSON_UNABLE_HANDLE_ = 5, + _RSON_CLS2_ = 6, + _RSON_CLS3_ = 7, + _RSON_DISAOC_STA_LEAVING_ = 8, + _RSON_ASOC_NOT_AUTH_ = 9, + + // WPA reason + _RSON_INVALID_IE_ = 13, + _RSON_MIC_FAILURE_ = 14, + _RSON_4WAY_HNDSHK_TIMEOUT_ = 15, + _RSON_GROUP_KEY_UPDATE_TIMEOUT_ = 16, + _RSON_DIFF_IE_ = 17, + _RSON_MLTCST_CIPHER_NOT_VALID_ = 18, + _RSON_UNICST_CIPHER_NOT_VALID_ = 19, + _RSON_AKMP_NOT_VALID_ = 20, + _RSON_UNSUPPORT_RSNE_VER_ = 21, + _RSON_INVALID_RSNE_CAP_ = 22, + _RSON_IEEE_802DOT1X_AUTH_FAIL_ = 23, + + //belowing are Realtek definition + _RSON_PMK_NOT_AVAILABLE_ = 24, + _RSON_TDLS_TEAR_TOOFAR_ = 25, + _RSON_TDLS_TEAR_UN_RSN_ = 26, +}; + +/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */ +#if 0 +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#endif +/* IEEE 802.11h */ +#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 +#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 +#if 0 +/* IEEE 802.11i */ +#define WLAN_REASON_INVALID_IE 13 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 +#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 +#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 +#define WLAN_REASON_AKMP_NOT_VALID 20 +#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 +#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 +#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#endif + +enum WIFI_STATUS_CODE { + _STATS_SUCCESSFUL_ = 0, + _STATS_FAILURE_ = 1, + _STATS_CAP_FAIL_ = 10, + _STATS_NO_ASOC_ = 11, + _STATS_OTHER_ = 12, + _STATS_NO_SUPP_ALG_ = 13, + _STATS_OUT_OF_AUTH_SEQ_ = 14, + _STATS_CHALLENGE_FAIL_ = 15, + _STATS_AUTH_TIMEOUT_ = 16, + _STATS_UNABLE_HANDLE_STA_ = 17, + _STATS_RATE_FAIL_ = 18, +}; + +/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) */ +#if 0 +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +#endif +//entended +/* IEEE 802.11b */ +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 +/* IEEE 802.11h */ +#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 +#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 +#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 +/* IEEE 802.11g */ +#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +#define WLAN_STATUS_ASSOC_DENIED_NO_ER_PBCC 26 +#define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27 +/* IEEE 802.11w */ +#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 +#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +/* IEEE 802.11i */ +#define WLAN_STATUS_INVALID_IE 40 +#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 +#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 +#define WLAN_STATUS_AKMP_NOT_VALID 43 +#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 +#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 +#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 +/* IEEE 802.11r */ +#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 +#define WLAN_STATUS_INVALID_PMKID 53 +#define WLAN_STATUS_INVALID_MDIE 54 +#define WLAN_STATUS_INVALID_FTIE 55 + + +enum WIFI_REG_DOMAIN { + DOMAIN_FCC = 1, + DOMAIN_IC = 2, + DOMAIN_ETSI = 3, + DOMAIN_SPAIN = 4, + DOMAIN_FRANCE = 5, + DOMAIN_MKK = 6, + DOMAIN_ISRAEL = 7, + DOMAIN_MKK1 = 8, + DOMAIN_MKK2 = 9, + DOMAIN_MKK3 = 10, + DOMAIN_MAX +}; + +#define _TO_DS_ BIT(8) +#define _FROM_DS_ BIT(9) +#define _MORE_FRAG_ BIT(10) +#define _RETRY_ BIT(11) +#define _PWRMGT_ BIT(12) +#define _MORE_DATA_ BIT(13) +#define _PRIVACY_ BIT(14) +#define _ORDER_ BIT(15) + +#define SetToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_TO_DS_); \ + } while(0) + +#define GetToDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_TO_DS_)) != 0) + +#define ClearToDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_TO_DS_)); \ + } while(0) + +#define SetFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_FROM_DS_); \ + } while(0) + +#define GetFrDs(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_FROM_DS_)) != 0) + +#define ClearFrDs(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_FROM_DS_)); \ + } while(0) + +#define get_tofr_ds(pframe) ((GetToDs(pframe) << 1) | GetFrDs(pframe)) + + +#define SetMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_FRAG_); \ + } while(0) + +#define GetMFrag(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_FRAG_)) != 0) + +#define ClearMFrag(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_FRAG_)); \ + } while(0) + +#define SetRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_RETRY_); \ + } while(0) + +#define GetRetry(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_RETRY_)) != 0) + +#define ClearRetry(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_RETRY_)); \ + } while(0) + +#define SetPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PWRMGT_); \ + } while(0) + +#define GetPwrMgt(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PWRMGT_)) != 0) + +#define ClearPwrMgt(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PWRMGT_)); \ + } while(0) + +#define SetMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_MORE_DATA_); \ + } while(0) + +#define GetMData(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_MORE_DATA_)) != 0) + +#define ClearMData(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_MORE_DATA_)); \ + } while(0) + +#define SetPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_PRIVACY_); \ + } while(0) + +#define GetPrivacy(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_PRIVACY_)) != 0) + +#define ClearPrivacy(pbuf) \ + do { \ + *(unsigned short *)(pbuf) &= (~cpu_to_le16(_PRIVACY_)); \ + } while(0) + + +#define GetOrder(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + +#define GetFrameType(pbuf) (le16_to_cpu(*(unsigned short *)(pbuf)) & (BIT(3) | BIT(2))) + +#define SetFrameType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + } while(0) + +#define GetFrameSubType(pbuf) (cpu_to_le16(*(unsigned short *)(pbuf)) & (BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))) + +#define SetFrameSubType(pbuf,type) \ + do { \ + *(unsigned short *)(pbuf) &= cpu_to_le16(~(BIT(7) | BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2))); \ + *(unsigned short *)(pbuf) |= cpu_to_le16(type); \ + } while(0) + +#define GetSequence(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) >> 4) + +#define GetFragNum(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & 0x0f) + +#define GetTupleCache(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 22))) + +#define SetFragNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu(~(0x000f))) | \ + cpu_to_le16(0x0f & (num)); \ + } while(0) + +#define SetSeqNum(pbuf, num) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 22) = \ + ((*(unsigned short *)((SIZE_PTR)(pbuf) + 22)) & le16_to_cpu((unsigned short)~0xfff0)) | \ + le16_to_cpu((unsigned short)(0xfff0 & (num << 4))); \ + } while(0) +#define GetFrameControl(pbuf)(cpu_to_le16(*(unsigned short*)((SIZE_PTR)(pbuf)))) +#define GetDuration(pbuf) (cpu_to_le16(*(unsigned short*)((SIZE_PTR)(pbuf) + 2))) +#define SetDuration(pbuf, dur) \ + do { \ + *(unsigned short *)((SIZE_PTR)(pbuf) + 2) = cpu_to_le16(0xffff & (dur)); \ + } while(0) + + +#define SetPriority(pbuf, tid) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(tid & 0xf); \ + } while(0) + +#define GetPriority(pbuf) ((le16_to_cpu(*(unsigned short *)(pbuf))) & 0xf) + +#define SetEOSP(pbuf, eosp) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (eosp & 1) << 4); \ + } while(0) + +#define SetAckpolicy(pbuf, ack) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (ack & 3) << 5); \ + } while(0) + +#define GetAckpolicy(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 5) & 0x3) + +#define GetAMsdu(pbuf) (((le16_to_cpu(*(unsigned short *)pbuf)) >> 7) & 0x1) + +#define SetAMsdu(pbuf, amsdu) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16( (amsdu & 1) << 7); \ + } while(0) + +#define GetAid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + 2)) & 0x3fff) + +#define GetTid(pbuf) (cpu_to_le16(*(unsigned short *)((SIZE_PTR)(pbuf) + (((GetToDs(pbuf)<<1)|GetFrDs(pbuf))==3?30:24))) & 0x000f) + +#define GetAddr1Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 4)) + +#define GetAddr2Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 10)) + +#define GetAddr3Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 16)) + +#define GetAddr4Ptr(pbuf) ((unsigned char *)((SIZE_PTR)(pbuf) + 24)) + +#define MacAddr_isBcst(addr) \ +( \ + ( (addr[0] == 0xff) && (addr[1] == 0xff) && \ + (addr[2] == 0xff) && (addr[3] == 0xff) && \ + (addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \ +) + +__inline static int IS_MCAST(unsigned char *da) +{ + if ((*da) & 0x01) + return _TRUE; + else + return _FALSE; +} + +__inline static unsigned char * get_ta(unsigned char *pframe) +{ + unsigned char *ta; + ta = GetAddr2Ptr(pframe); + return ta; +} + +__inline static unsigned char * get_da(unsigned char *pframe) +{ + unsigned char *da; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + da = GetAddr1Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + da = GetAddr1Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + da = GetAddr3Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + da = GetAddr3Ptr(pframe); + break; + } + + return da; +} + + +__inline static unsigned char * get_sa(unsigned char *pframe) +{ + unsigned char *sa; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr3Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr2Ptr(pframe); + break; + default: // ToDs=1, FromDs=1 + sa = GetAddr4Ptr(pframe); + break; + } + + return sa; +} + +__inline static unsigned char * get_hdr_bssid(unsigned char *pframe) +{ + unsigned char *sa; + unsigned int to_fr_ds = (GetToDs(pframe) << 1) | GetFrDs(pframe); + + switch (to_fr_ds) { + case 0x00: // ToDs=0, FromDs=0 + sa = GetAddr3Ptr(pframe); + break; + case 0x01: // ToDs=0, FromDs=1 + sa = GetAddr2Ptr(pframe); + break; + case 0x02: // ToDs=1, FromDs=0 + sa = GetAddr1Ptr(pframe); + break; + case 0x03: // ToDs=1, FromDs=1 + sa = GetAddr1Ptr(pframe); + break; + default: + sa =NULL; //??????? + break; + } + + return sa; +} + + +__inline static int IsFrameTypeCtrl(unsigned char *pframe) +{ + if(WIFI_CTRL_TYPE == GetFrameType(pframe)) + return _TRUE; + else + return _FALSE; +} +/*----------------------------------------------------------------------------- + Below is for the security related definition +------------------------------------------------------------------------------*/ +#define _RESERVED_FRAME_TYPE_ 0 +#define _SKB_FRAME_TYPE_ 2 +#define _PRE_ALLOCMEM_ 1 +#define _PRE_ALLOCHDR_ 3 +#define _PRE_ALLOCLLCHDR_ 4 +#define _PRE_ALLOCICVHDR_ 5 +#define _PRE_ALLOCMICHDR_ 6 + +#define _SIFSTIME_ ((priv->pmib->dot11BssType.net_work_type&WIRELESS_11A)?16:10) +#define _ACKCTSLNG_ 14 //14 bytes long, including crclng +#define _CRCLNG_ 4 + +#define _ASOCREQ_IE_OFFSET_ 4 // excluding wlan_hdr +#define _ASOCRSP_IE_OFFSET_ 6 +#define _REASOCREQ_IE_OFFSET_ 10 +#define _REASOCRSP_IE_OFFSET_ 6 +#define _PROBEREQ_IE_OFFSET_ 0 +#define _PROBERSP_IE_OFFSET_ 12 +#define _AUTH_IE_OFFSET_ 6 +#define _DEAUTH_IE_OFFSET_ 0 +#define _BEACON_IE_OFFSET_ 12 +#define _PUBLIC_ACTION_IE_OFFSET_ 8 + +#define _FIXED_IE_LENGTH_ _BEACON_IE_OFFSET_ + +#define _SSID_IE_ 0 +#define _SUPPORTEDRATES_IE_ 1 +#define _DSSET_IE_ 3 +#define _TIM_IE_ 5 +#define _IBSS_PARA_IE_ 6 +#define _COUNTRY_IE_ 7 +#define _CHLGETXT_IE_ 16 +#define _SUPPORTED_CH_IE_ 36 +#define _CH_SWTICH_ANNOUNCE_ 37 //Secondary Channel Offset +#define _RSN_IE_2_ 48 +#define _SSN_IE_1_ 221 +#define _ERPINFO_IE_ 42 +#define _EXT_SUPPORTEDRATES_IE_ 50 + +#define _HT_CAPABILITY_IE_ 45 +#define _FTIE_ 55 +#define _TIMEOUT_ITVL_IE_ 56 +#define _SRC_IE_ 59 +#define _HT_EXTRA_INFO_IE_ 61 +#define _HT_ADD_INFO_IE_ 61 //_HT_EXTRA_INFO_IE_ +#define _WAPI_IE_ 68 + + +#define EID_BSSCoexistence 72 // 20/40 BSS Coexistence +#define EID_BSSIntolerantChlReport 73 +#define _RIC_Descriptor_IE_ 75 + +#define _LINK_ID_IE_ 101 +#define _CH_SWITCH_TIMING_ 104 +#define _PTI_BUFFER_STATUS_ 106 +#define _EXT_CAP_IE_ 127 +#define _VENDOR_SPECIFIC_IE_ 221 + +#define _RESERVED47_ 47 + +/* --------------------------------------------------------------------------- + Below is the fixed elements... +-----------------------------------------------------------------------------*/ +#define _AUTH_ALGM_NUM_ 2 +#define _AUTH_SEQ_NUM_ 2 +#define _BEACON_ITERVAL_ 2 +#define _CAPABILITY_ 2 +#define _CURRENT_APADDR_ 6 +#define _LISTEN_INTERVAL_ 2 +#define _RSON_CODE_ 2 +#define _ASOC_ID_ 2 +#define _STATUS_CODE_ 2 +#define _TIMESTAMP_ 8 + +#define AUTH_ODD_TO 0 +#define AUTH_EVEN_TO 1 + +#define WLAN_ETHCONV_ENCAP 1 +#define WLAN_ETHCONV_RFC1042 2 +#define WLAN_ETHCONV_8021h 3 + +#define cap_ESS BIT(0) +#define cap_IBSS BIT(1) +#define cap_CFPollable BIT(2) +#define cap_CFRequest BIT(3) +#define cap_Privacy BIT(4) +#define cap_ShortPremble BIT(5) +#define cap_PBCC BIT(6) +#define cap_ChAgility BIT(7) +#define cap_SpecMgmt BIT(8) +#define cap_QoS BIT(9) +#define cap_ShortSlot BIT(10) + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11i / 802.1x +------------------------------------------------------------------------------*/ +#define _IEEE8021X_MGT_ 1 // WPA +#define _IEEE8021X_PSK_ 2 // WPA with pre-shared key + +/* +#define _NO_PRIVACY_ 0 +#define _WEP_40_PRIVACY_ 1 +#define _TKIP_PRIVACY_ 2 +#define _WRAP_PRIVACY_ 3 +#define _CCMP_PRIVACY_ 4 +#define _WEP_104_PRIVACY_ 5 +#define _WEP_WPA_MIXED_PRIVACY_ 6 // WEP + WPA +*/ + +/*----------------------------------------------------------------------------- + Below is the definition for WMM +------------------------------------------------------------------------------*/ +#define _WMM_IE_Length_ 7 // for WMM STA +#define _WMM_Para_Element_Length_ 24 + +//TODO +#if 0 + +/*----------------------------------------------------------------------------- + Below is the definition for 802.11n +------------------------------------------------------------------------------*/ + +//#ifdef CONFIG_80211N_HT + +#define SetOrderBit(pbuf) \ + do { \ + *(unsigned short *)(pbuf) |= cpu_to_le16(_ORDER_); \ + } while(0) + +#define GetOrderBit(pbuf) (((*(unsigned short *)(pbuf)) & le16_to_cpu(_ORDER_)) != 0) + + +/** + * struct rtw_ieee80211_bar - HT Block Ack Request + * + * This structure refers to "HT BlockAckReq" as + * described in 802.11n draft section 7.2.1.7.1 + */ + #if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) +struct rtw_ieee80211_bar { + unsigned short frame_control; + unsigned short duration; + unsigned char ra[6]; + unsigned char ta[6]; + unsigned short control; + unsigned short start_seq_num; +} __attribute__((packed)); + #endif + +/* 802.11 BAR control masks */ +#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 +#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 + +#endif //#if 0 + +#if defined(PLATFORM_LINUX) || defined(CONFIG_RTL8712FW) || defined(PLATFORM_FREEBSD) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) + + + + /** + * struct rtw_ieee80211_ht_cap - HT capabilities + * + * This structure refers to "HT capabilities element" as + * described in 802.11n draft section 7.3.2.52 + */ + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +}RTW_PACK_STRUCT_STRUCT; +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + + +/** + * struct rtw_ieee80211_ht_cap - HT additional information + * + * This structure refers to "HT information element" as + * described in 802.11n draft section 7.3.2.53 + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } +#ifdef __CC_ARM + __attribute__ ((packed)) +#endif + HT_cap_element; + unsigned char HT_cap[26]; + } +#ifdef __CC_ARM + __attribute__ ((packed)) +#endif + u; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +}RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#endif //#if defined PLATFORM_LINUX/CONFIG_RTL8712FW/PLATFORM_FREEBSD/PLATFORM_ECOS/PLATFORM_FREERTOS + + +#ifdef PLATFORM_WINDOWS + +#pragma pack(1) + +struct rtw_ieee80211_ht_cap { + unsigned short cap_info; + unsigned char ampdu_params_info; + unsigned char supp_mcs_set[16]; + unsigned short extended_ht_cap_info; + unsigned int tx_BF_cap_info; + unsigned char antenna_selection_info; +}; + + +struct ieee80211_ht_addt_info { + unsigned char control_chan; + unsigned char ht_param; + unsigned short operation_mode; + unsigned short stbc_param; + unsigned char basic_set[16]; +}; + +struct HT_caps_element +{ + union + { + struct + { + unsigned short HT_caps_info; + unsigned char AMPDU_para; + unsigned char MCS_rate[16]; + unsigned short HT_ext_caps; + unsigned int Beamforming_caps; + unsigned char ASEL_caps; + } HT_cap_element; + unsigned char HT_cap[26]; + }; +}; + +struct HT_info_element +{ + unsigned char primary_channel; + unsigned char infos[5]; + unsigned char MCS_rate[16]; +}; + +struct AC_param +{ + unsigned char ACI_AIFSN; + unsigned char CW; + unsigned short TXOP_limit; +}; + +struct WMM_para_element +{ + unsigned char QoS_info; + unsigned char reserved; + struct AC_param ac_param[4]; +}; + +struct ADDBA_request +{ + unsigned char dialog_token; + unsigned short BA_para_set; + unsigned short BA_timeout_value; + unsigned short BA_starting_seqctrl; +}; + + +#pragma pack() + +#endif + +typedef enum _HT_CAP_AMPDU_FACTOR { + MAX_AMPDU_FACTOR_8K = 0, + MAX_AMPDU_FACTOR_16K = 1, + MAX_AMPDU_FACTOR_32K = 2, + MAX_AMPDU_FACTOR_64K = 3, +}HT_CAP_AMPDU_FACTOR; + +/* 802.11n HT capabilities masks */ +#define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 +#define IEEE80211_HT_CAP_SM_PS 0x000C +#define IEEE80211_HT_CAP_GRN_FLD 0x0010 +#define IEEE80211_HT_CAP_SGI_20 0x0020 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_TX_STBC 0x0080 +#define IEEE80211_HT_CAP_RX_STBC 0x0300 +#define IEEE80211_HT_CAP_DELAY_BA 0x0400 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 +/* 802.11n HT capability AMPDU settings */ +#define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03 +#define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C +/* 802.11n HT capability MSC set */ +#define IEEE80211_SUPP_MCS_SET_UEQM 4 +#define IEEE80211_HT_CAP_MAX_STREAMS 4 +#define IEEE80211_SUPP_MCS_SET_LEN 10 +/* maximum streams the spec allows */ +#define IEEE80211_HT_CAP_MCS_TX_DEFINED 0x01 +#define IEEE80211_HT_CAP_MCS_TX_RX_DIFF 0x02 +#define IEEE80211_HT_CAP_MCS_TX_STREAMS 0x0C +#define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 +/* 802.11n HT IE masks */ +#define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 +#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 +#define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 +#define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 +#define IEEE80211_HT_IE_CHA_WIDTH 0x04 +#define IEEE80211_HT_IE_HT_PROTECTION 0x0003 +#define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 +#define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 + +/* block-ack parameters */ +#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C +#define RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0 +#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 +#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 + +/* + * A-PMDU buffer sizes + * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) + */ +#define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_MAX_AMPDU_BUF 0x40 + + +/* Spatial Multiplexing Power Save Modes */ +#define WLAN_HT_CAP_SM_PS_STATIC 0 +#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 +#define WLAN_HT_CAP_SM_PS_INVALID 2 +#define WLAN_HT_CAP_SM_PS_DISABLED 3 + + +#define OP_MODE_PURE 0 +#define OP_MODE_MAY_BE_LEGACY_STAS 1 +#define OP_MODE_20MHZ_HT_STA_ASSOCED 2 +#define OP_MODE_MIXED 3 + +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH ((u8) BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) +#define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY ((u8) BIT(4)) +#define HT_INFO_HT_PARAM_SRV_INTERVAL_GRANULARITY ((u8) BIT(5)) + +#define HT_INFO_OPERATION_MODE_OP_MODE_MASK \ + ((u16) (0x0001 | 0x0002)) +#define HT_INFO_OPERATION_MODE_OP_MODE_OFFSET 0 +#define HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT ((u8) BIT(2)) +#define HT_INFO_OPERATION_MODE_TRANSMIT_BURST_LIMIT ((u8) BIT(3)) +#define HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT ((u8) BIT(4)) + +#define HT_INFO_STBC_PARAM_DUAL_BEACON ((u16) BIT(6)) +#define HT_INFO_STBC_PARAM_DUAL_STBC_PROTECT ((u16) BIT(7)) +#define HT_INFO_STBC_PARAM_SECONDARY_BCN ((u16) BIT(8)) +#define HT_INFO_STBC_PARAM_LSIG_TXOP_PROTECT_ALLOWED ((u16) BIT(9)) +#define HT_INFO_STBC_PARAM_PCO_ACTIVE ((u16) BIT(10)) +#define HT_INFO_STBC_PARAM_PCO_PHASE ((u16) BIT(11)) + + + +//#endif + +// ===============WPS Section=============== +// For WPSv1.0 +#define WPSOUI 0x0050f204 +// WPS attribute ID +#define WPS_ATTR_VER1 0x104A +#define WPS_ATTR_SIMPLE_CONF_STATE 0x1044 +#define WPS_ATTR_RESP_TYPE 0x103B +#define WPS_ATTR_UUID_E 0x1047 +#define WPS_ATTR_MANUFACTURER 0x1021 +#define WPS_ATTR_MODEL_NAME 0x1023 +#define WPS_ATTR_MODEL_NUMBER 0x1024 +#define WPS_ATTR_SERIAL_NUMBER 0x1042 +#define WPS_ATTR_PRIMARY_DEV_TYPE 0x1054 +#define WPS_ATTR_SEC_DEV_TYPE_LIST 0x1055 +#define WPS_ATTR_DEVICE_NAME 0x1011 +#define WPS_ATTR_CONF_METHOD 0x1008 +#define WPS_ATTR_RF_BANDS 0x103C +#define WPS_ATTR_DEVICE_PWID 0x1012 +#define WPS_ATTR_REQUEST_TYPE 0x103A +#define WPS_ATTR_ASSOCIATION_STATE 0x1002 +#define WPS_ATTR_CONFIG_ERROR 0x1009 +#define WPS_ATTR_VENDOR_EXT 0x1049 +#define WPS_ATTR_SELECTED_REGISTRAR 0x1041 + +// Value of WPS attribute "WPS_ATTR_DEVICE_NAME +#define WPS_MAX_DEVICE_NAME_LEN 32 + +// Value of WPS Request Type Attribute +#define WPS_REQ_TYPE_ENROLLEE_INFO_ONLY 0x00 +#define WPS_REQ_TYPE_ENROLLEE_OPEN_8021X 0x01 +#define WPS_REQ_TYPE_REGISTRAR 0x02 +#define WPS_REQ_TYPE_WLAN_MANAGER_REGISTRAR 0x03 + +// Value of WPS Response Type Attribute +#define WPS_RESPONSE_TYPE_INFO_ONLY 0x00 +#define WPS_RESPONSE_TYPE_8021X 0x01 +#define WPS_RESPONSE_TYPE_REGISTRAR 0x02 +#define WPS_RESPONSE_TYPE_AP 0x03 + +// Value of WPS WiFi Simple Configuration State Attribute +#define WPS_WSC_STATE_NOT_CONFIG 0x01 +#define WPS_WSC_STATE_CONFIG 0x02 + +// Value of WPS Version Attribute +#define WPS_VERSION_1 0x10 + +// Value of WPS Configuration Method Attribute +#define WPS_CONFIG_METHOD_FLASH 0x0001 +#define WPS_CONFIG_METHOD_ETHERNET 0x0002 +#define WPS_CONFIG_METHOD_LABEL 0x0004 +#define WPS_CONFIG_METHOD_DISPLAY 0x0008 +#define WPS_CONFIG_METHOD_E_NFC 0x0010 +#define WPS_CONFIG_METHOD_I_NFC 0x0020 +#define WPS_CONFIG_METHOD_NFC 0x0040 +#define WPS_CONFIG_METHOD_PBC 0x0080 +#define WPS_CONFIG_METHOD_KEYPAD 0x0100 +#define WPS_CONFIG_METHOD_VPBC 0x0280 +#define WPS_CONFIG_METHOD_PPBC 0x0480 +#define WPS_CONFIG_METHOD_VDISPLAY 0x2008 +#define WPS_CONFIG_METHOD_PDISPLAY 0x4008 + +// Value of Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_CID_DISPLAYS 0x0007 +#define WPS_PDT_CID_MULIT_MEDIA 0x0008 +#define WPS_PDT_CID_RTK_WIDI WPS_PDT_CID_MULIT_MEDIA + +// Value of Sub Category ID of WPS Primary Device Type Attribute +#define WPS_PDT_SCID_MEDIA_SERVER 0x0005 +#define WPS_PDT_SCID_RTK_DMP WPS_PDT_SCID_MEDIA_SERVER + +// Value of Device Password ID +#define WPS_DPID_PIN 0x0000 +#define WPS_DPID_USER_SPEC 0x0001 +#define WPS_DPID_MACHINE_SPEC 0x0002 +#define WPS_DPID_REKEY 0x0003 +#define WPS_DPID_PBC 0x0004 +#define WPS_DPID_REGISTRAR_SPEC 0x0005 + +// Value of WPS RF Bands Attribute +#define WPS_RF_BANDS_2_4_GHZ 0x01 +#define WPS_RF_BANDS_5_GHZ 0x02 + +// Value of WPS Association State Attribute +#define WPS_ASSOC_STATE_NOT_ASSOCIATED 0x00 +#define WPS_ASSOC_STATE_CONNECTION_SUCCESS 0x01 +#define WPS_ASSOC_STATE_CONFIGURATION_FAILURE 0x02 +#define WPS_ASSOC_STATE_ASSOCIATION_FAILURE 0x03 +#define WPS_ASSOC_STATE_IP_FAILURE 0x04 + +// =====================P2P Section===================== +// For P2P +#define P2POUI 0x506F9A09 + +// P2P Attribute ID +#define P2P_ATTR_STATUS 0x00 +#define P2P_ATTR_MINOR_REASON_CODE 0x01 +#define P2P_ATTR_CAPABILITY 0x02 +#define P2P_ATTR_DEVICE_ID 0x03 +#define P2P_ATTR_GO_INTENT 0x04 +#define P2P_ATTR_CONF_TIMEOUT 0x05 +#define P2P_ATTR_LISTEN_CH 0x06 +#define P2P_ATTR_GROUP_BSSID 0x07 +#define P2P_ATTR_EX_LISTEN_TIMING 0x08 +#define P2P_ATTR_INTENTED_IF_ADDR 0x09 +#define P2P_ATTR_MANAGEABILITY 0x0A +#define P2P_ATTR_CH_LIST 0x0B +#define P2P_ATTR_NOA 0x0C +#define P2P_ATTR_DEVICE_INFO 0x0D +#define P2P_ATTR_GROUP_INFO 0x0E +#define P2P_ATTR_GROUP_ID 0x0F +#define P2P_ATTR_INTERFACE 0x10 +#define P2P_ATTR_OPERATING_CH 0x11 +#define P2P_ATTR_INVITATION_FLAGS 0x12 + +// Value of Status Attribute +#define P2P_STATUS_SUCCESS 0x00 +#define P2P_STATUS_FAIL_INFO_UNAVAILABLE 0x01 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PARAM 0x02 +#define P2P_STATUS_FAIL_LIMIT_REACHED 0x03 +#define P2P_STATUS_FAIL_INVALID_PARAM 0x04 +#define P2P_STATUS_FAIL_REQUEST_UNABLE 0x05 +#define P2P_STATUS_FAIL_PREVOUS_PROTO_ERR 0x06 +#define P2P_STATUS_FAIL_NO_COMMON_CH 0x07 +#define P2P_STATUS_FAIL_UNKNOWN_P2PGROUP 0x08 +#define P2P_STATUS_FAIL_BOTH_GOINTENT_15 0x09 +#define P2P_STATUS_FAIL_INCOMPATIBLE_PROVSION 0x0A +#define P2P_STATUS_FAIL_USER_REJECT 0x0B + +// Value of Inviation Flags Attribute +#define P2P_INVITATION_FLAGS_PERSISTENT BIT(0) + +#define DMP_P2P_DEVCAP_SUPPORT (P2P_DEVCAP_SERVICE_DISCOVERY | \ + P2P_DEVCAP_CLIENT_DISCOVERABILITY | \ + P2P_DEVCAP_CONCURRENT_OPERATION | \ + P2P_DEVCAP_INVITATION_PROC) + +#define DMP_P2P_GRPCAP_SUPPORT (P2P_GRPCAP_INTRABSS) + +// Value of Device Capability Bitmap +#define P2P_DEVCAP_SERVICE_DISCOVERY BIT(0) +#define P2P_DEVCAP_CLIENT_DISCOVERABILITY BIT(1) +#define P2P_DEVCAP_CONCURRENT_OPERATION BIT(2) +#define P2P_DEVCAP_INFRA_MANAGED BIT(3) +#define P2P_DEVCAP_DEVICE_LIMIT BIT(4) +#define P2P_DEVCAP_INVITATION_PROC BIT(5) + +// Value of Group Capability Bitmap +#define P2P_GRPCAP_GO BIT(0) +#define P2P_GRPCAP_PERSISTENT_GROUP BIT(1) +#define P2P_GRPCAP_GROUP_LIMIT BIT(2) +#define P2P_GRPCAP_INTRABSS BIT(3) +#define P2P_GRPCAP_CROSS_CONN BIT(4) +#define P2P_GRPCAP_PERSISTENT_RECONN BIT(5) +#define P2P_GRPCAP_GROUP_FORMATION BIT(6) + +// P2P Public Action Frame ( Management Frame ) +#define P2P_PUB_ACTION_ACTION 0x09 + +// P2P Public Action Frame Type +#define P2P_GO_NEGO_REQ 0 +#define P2P_GO_NEGO_RESP 1 +#define P2P_GO_NEGO_CONF 2 +#define P2P_INVIT_REQ 3 +#define P2P_INVIT_RESP 4 +#define P2P_DEVDISC_REQ 5 +#define P2P_DEVDISC_RESP 6 +#define P2P_PROVISION_DISC_REQ 7 +#define P2P_PROVISION_DISC_RESP 8 + +// P2P Action Frame Type +#define P2P_NOTICE_OF_ABSENCE 0 +#define P2P_PRESENCE_REQUEST 1 +#define P2P_PRESENCE_RESPONSE 2 +#define P2P_GO_DISC_REQUEST 3 + + +#define P2P_MAX_PERSISTENT_GROUP_NUM 10 + +#define P2P_PROVISIONING_SCAN_CNT 3 + +#define P2P_WILDCARD_SSID_LEN 7 + +#define P2P_FINDPHASE_EX_NONE 0 // default value, used when: (1)p2p disabed or (2)p2p enabled but only do 1 scan phase +#define P2P_FINDPHASE_EX_FULL 1 // used when p2p enabled and want to do 1 scan phase and P2P_FINDPHASE_EX_MAX-1 find phase +#define P2P_FINDPHASE_EX_SOCIAL_FIRST (P2P_FINDPHASE_EX_FULL+1) +#define P2P_FINDPHASE_EX_MAX 4 +#define P2P_FINDPHASE_EX_SOCIAL_LAST P2P_FINDPHASE_EX_MAX + +#define P2P_PROVISION_TIMEOUT 5000 // 5 seconds timeout for sending the provision discovery request +#define P2P_CONCURRENT_PROVISION_TIMEOUT 3000 // 3 seconds timeout for sending the provision discovery request under concurrent mode +#define P2P_GO_NEGO_TIMEOUT 5000 // 5 seconds timeout for receiving the group negotation response +#define P2P_CONCURRENT_GO_NEGO_TIMEOUT 3000 // 3 seconds timeout for sending the negotiation request under concurrent mode +#define P2P_TX_PRESCAN_TIMEOUT 100 // 100ms +#define P2P_INVITE_TIMEOUT 5000 // 5 seconds timeout for sending the invitation request +#define P2P_CONCURRENT_INVITE_TIMEOUT 3000 // 3 seconds timeout for sending the invitation request under concurrent mode + +#define P2P_MAX_INTENT 15 + +#define P2P_MAX_NOA_NUM 2 + +// WPS Configuration Method +#define WPS_CM_NONE 0x0000 +#define WPS_CM_LABEL 0x0004 +#define WPS_CM_DISPLYA 0x0008 +#define WPS_CM_EXTERNAL_NFC_TOKEN 0x0010 +#define WPS_CM_INTEGRATED_NFC_TOKEN 0x0020 +#define WPS_CM_NFC_INTERFACE 0x0040 +#define WPS_CM_PUSH_BUTTON 0x0080 +#define WPS_CM_KEYPAD 0x0100 +#define WPS_CM_SW_PUHS_BUTTON 0x0280 +#define WPS_CM_HW_PUHS_BUTTON 0x0480 +#define WPS_CM_SW_DISPLAY_PIN 0x2008 +#define WPS_CM_LCD_DISPLAY_PIN 0x4008 + +enum gen_ie_type{ + P2PWPS_PROBE_REQ_IE = 0, + P2PWPS_PROBE_RSP_IE, + P2PWPS_BEACON_IE, + P2PWPS_ASSOC_REQ_IE, + P2PWPS_ASSOC_RSP_IE +}; + +enum P2P_ROLE { + P2P_ROLE_DISABLE = 0, + P2P_ROLE_DEVICE = 1, + P2P_ROLE_CLIENT = 2, + P2P_ROLE_GO = 3 +}; + +enum P2P_STATE { + P2P_STATE_NONE = 0, // P2P disable + P2P_STATE_IDLE = 1, // P2P had enabled and do nothing + P2P_STATE_LISTEN = 2, // In pure listen state + P2P_STATE_SCAN = 3, // In scan phase + P2P_STATE_FIND_PHASE_LISTEN = 4, // In the listen state of find phase + P2P_STATE_FIND_PHASE_SEARCH = 5, // In the search state of find phase + P2P_STATE_TX_PROVISION_DIS_REQ = 6, // In P2P provisioning discovery + P2P_STATE_RX_PROVISION_DIS_RSP = 7, + P2P_STATE_RX_PROVISION_DIS_REQ = 8, + P2P_STATE_GONEGO_ING = 9, // Doing the group owner negoitation handshake + P2P_STATE_GONEGO_OK = 10, // finish the group negoitation handshake with success + P2P_STATE_GONEGO_FAIL = 11, // finish the group negoitation handshake with failure + P2P_STATE_RECV_INVITE_REQ_MATCH = 12, // receiving the P2P Inviation request and match with the profile. + P2P_STATE_PROVISIONING_ING = 13, // Doing the P2P WPS + P2P_STATE_PROVISIONING_DONE = 14, // Finish the P2P WPS + P2P_STATE_TX_INVITE_REQ = 15, // Transmit the P2P Invitation request + P2P_STATE_RX_INVITE_RESP = 16, // Receiving the P2P Invitation response + P2P_STATE_RECV_INVITE_REQ_DISMATCH = 17, // receiving the P2P Inviation request and dismatch with the profile. + P2P_STATE_RECV_INVITE_REQ_GO = 18, // receiving the P2P Inviation request and this wifi is GO. + P2P_STATE_RECV_INVITE_REQ_JOIN = 19, // receiving the P2P Inviation request to join an existing P2P Group. + P2P_STATE_FORMATION_COMPLETE = 20, + P2P_STATE_CONNECTED = 21, +}; + +enum P2P_WPSINFO { + P2P_NO_WPSINFO = 0, + P2P_GOT_WPSINFO_PEER_DISPLAY_PIN = 1, + P2P_GOT_WPSINFO_SELF_DISPLAY_PIN = 2, + P2P_GOT_WPSINFO_PBC = 3, +}; + +#define P2P_PRIVATE_IOCTL_SET_LEN 64 + +enum P2P_PROTO_WK_ID +{ + P2P_FIND_PHASE_WK = 0, + P2P_RESTORE_STATE_WK = 1, + P2P_PRE_TX_PROVDISC_PROCESS_WK = 2, + P2P_PRE_TX_NEGOREQ_PROCESS_WK = 3, + P2P_PRE_TX_INVITEREQ_PROCESS_WK = 4, + P2P_AP_P2P_CH_SWITCH_PROCESS_WK =5, + P2P_RO_CH_WK = 6, +}; + +enum P2P_PS +{ + P2P_PS_DISABLE=0, + P2P_PS_ENABLE=1, + P2P_PS_SCAN=2, + P2P_PS_SCAN_DONE=3, + P2P_PS_ALLSTASLEEP=4, // for owner +}; + +// =====================WFD Section===================== +// For Wi-Fi Display +#define WFD_ATTR_DEVICE_INFO 0x00 +#define WFD_ATTR_ASSOC_BSSID 0x01 +#define WFD_ATTR_COUPLED_SINK_INFO 0x06 +#define WFD_ATTR_LOCAL_IP_ADDR 0x08 +#define WFD_ATTR_SESSION_INFO 0x09 +#define WFD_ATTR_ALTER_MAC 0x0a + +// For WFD Device Information Attribute +#define WFD_DEVINFO_SOURCE 0x0000 +#define WFD_DEVINFO_PSINK 0x0001 +#define WFD_DEVINFO_SSINK 0x0002 + +#define WFD_DEVINFO_SESSION_AVAIL 0x0010 +#define WFD_DEVINFO_WSD 0x0040 +#define WFD_DEVINFO_PC_TDLS 0x0080 + + +#ifdef CONFIG_TX_MCAST2UNI +#define IP_MCAST_MAC(mac) ((mac[0]==0x01)&&(mac[1]==0x00)&&(mac[2]==0x5e)) +#define ICMPV6_MCAST_MAC(mac) ((mac[0]==0x33)&&(mac[1]==0x33)&&(mac[2]!=0xff)) +#endif // CONFIG_TX_MCAST2UNI + + + +#ifdef CONFIG_WAPI_SUPPORT +#ifndef IW_AUTH_WAPI_VERSION_1 +#define IW_AUTH_WAPI_VERSION_1 0x00000008 +#endif +#ifndef IW_AUTH_KEY_MGMT_WAPI_PSK +#define IW_AUTH_KEY_MGMT_WAPI_PSK 0x04 +#endif +#ifndef IW_AUTH_WAPI_ENABLED +#define IW_AUTH_WAPI_ENABLED 0x20 +#endif +#ifndef IW_ENCODE_ALG_SM4 +#define IW_ENCODE_ALG_SM4 0x20 +#endif +#endif + +#ifndef _CUSTOM_IE_TYPE_ +#define _CUSTOM_IE_TYPE_ +typedef enum CUSTOM_IE_TYPE{ + PROBE_REQ = BIT(0), + PROBE_RSP = BIT(1), + BEACON = BIT(2), +}rtw_custom_ie_type_t; +#endif /* _CUSTOM_IE_TYPE_ */ + +#endif // _WIFI_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/wifi_constants.h b/USDK/component/common/drivers/wlan/realtek/include/wifi_constants.h new file mode 100644 index 0000000..dd67dc1 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wifi_constants.h @@ -0,0 +1,527 @@ +/** + ****************************************************************************** + * @file wifi_constants.h + * @author + * @version + * @brief This file provides the data types used for wlan API. + ****************************************************************************** + * @attention + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + * + * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. + ****************************************************************************** + */ + +#ifndef _WIFI_CONSTANTS_H +#define _WIFI_CONSTANTS_H + +/** @addtogroup nic NIC + * @ingroup wlan + * @brief NIC functions + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif + +#define WEP_ENABLED 0x0001 +#define TKIP_ENABLED 0x0002 +#define AES_ENABLED 0x0004 +#define WSEC_SWFLAG 0x0008 + +#define SHARED_ENABLED 0x00008000 +#define WPA_SECURITY 0x00200000 +#define WPA2_SECURITY 0x00400000 +#define WPS_ENABLED 0x10000000 + +#define RTW_MAX_PSK_LEN (64) +#define RTW_MIN_PSK_LEN (8) + +#define MCSSET_LEN 16 + +/** + * @brief The enumeration lists the results of the function. + */ +typedef enum +{ + RTW_SUCCESS = 0, /**< Success */ + RTW_PENDING = 1, /**< Pending */ + RTW_TIMEOUT = 2, /**< Timeout */ + RTW_PARTIAL_RESULTS = 3, /**< Partial results */ + RTW_INVALID_KEY = 4, /**< Invalid key */ + RTW_DOES_NOT_EXIST = 5, /**< Does not exist */ + RTW_NOT_AUTHENTICATED = 6, /**< Not authenticated */ + RTW_NOT_KEYED = 7, /**< Not keyed */ + RTW_IOCTL_FAIL = 8, /**< IOCTL fail */ + RTW_BUFFER_UNAVAILABLE_TEMPORARY = 9, /**< Buffer unavailable temporarily */ + RTW_BUFFER_UNAVAILABLE_PERMANENT = 10, /**< Buffer unavailable permanently */ + RTW_WPS_PBC_OVERLAP = 11, /**< WPS PBC overlap */ + RTW_CONNECTION_LOST = 12, /**< Connection lost */ + + RTW_ERROR = -1, /**< Generic Error */ + RTW_BADARG = -2, /**< Bad Argument */ + RTW_BADOPTION = -3, /**< Bad option */ + RTW_NOTUP = -4, /**< Not up */ + RTW_NOTDOWN = -5, /**< Not down */ + RTW_NOTAP = -6, /**< Not AP */ + RTW_NOTSTA = -7, /**< Not STA */ + RTW_BADKEYIDX = -8, /**< BAD Key Index */ + RTW_RADIOOFF = -9, /**< Radio Off */ + RTW_NOTBANDLOCKED = -10, /**< Not band locked */ + RTW_NOCLK = -11, /**< No Clock */ + RTW_BADRATESET = -12, /**< BAD Rate valueset */ + RTW_BADBAND = -13, /**< BAD Band */ + RTW_BUFTOOSHORT = -14, /**< Buffer too short */ + RTW_BUFTOOLONG = -15, /**< Buffer too long */ + RTW_BUSY = -16, /**< Busy */ + RTW_NOTASSOCIATED = -17, /**< Not Associated */ + RTW_BADSSIDLEN = -18, /**< Bad SSID len */ + RTW_OUTOFRANGECHAN = -19, /**< Out of Range Channel */ + RTW_BADCHAN = -20, /**< Bad Channel */ + RTW_BADADDR = -21, /**< Bad Address */ + RTW_NORESOURCE = -22, /**< Not Enough Resources */ + RTW_UNSUPPORTED = -23, /**< Unsupported */ + RTW_BADLEN = -24, /**< Bad length */ + RTW_NOTREADY = -25, /**< Not Ready */ + RTW_EPERM = -26, /**< Not Permitted */ + RTW_NOMEM = -27, /**< No Memory */ + RTW_ASSOCIATED = -28, /**< Associated */ + RTW_RANGE = -29, /**< Not In Range */ + RTW_NOTFOUND = -30, /**< Not Found */ + RTW_WME_NOT_ENABLED = -31, /**< WME Not Enabled */ + RTW_TSPEC_NOTFOUND = -32, /**< TSPEC Not Found */ + RTW_ACM_NOTSUPPORTED = -33, /**< ACM Not Supported */ + RTW_NOT_WME_ASSOCIATION = -34, /**< Not WME Association */ + RTW_SDIO_ERROR = -35, /**< SDIO Bus Error */ + RTW_WLAN_DOWN = -36, /**< WLAN Not Accessible */ + RTW_BAD_VERSION = -37, /**< Incorrect version */ + RTW_TXFAIL = -38, /**< TX failure */ + RTW_RXFAIL = -39, /**< RX failure */ + RTW_NODEVICE = -40, /**< Device not present */ + RTW_UNFINISHED = -41, /**< To be finished */ + RTW_NONRESIDENT = -42, /**< access to nonresident overlay */ + RTW_DISABLED = -43 /**< Disabled in this build */ +} rtw_result_t; + +/** + * @brief The enumeration lists the possible security types to set when connection.\n + * Station mode supports OPEN, WEP, and WPA2.\n + * AP mode support OPEN and WPA2. + */ +typedef enum { + RTW_SECURITY_OPEN = 0, /**< Open security */ + RTW_SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP Security with open authentication */ + RTW_SECURITY_WEP_SHARED = ( WEP_ENABLED | SHARED_ENABLED ), /**< WEP Security with shared authentication */ + RTW_SECURITY_WPA_TKIP_PSK = ( WPA_SECURITY | TKIP_ENABLED ), /**< WPA Security with TKIP */ + RTW_SECURITY_WPA_AES_PSK = ( WPA_SECURITY | AES_ENABLED ), /**< WPA Security with AES */ + RTW_SECURITY_WPA2_AES_PSK = ( WPA2_SECURITY | AES_ENABLED ), /**< WPA2 Security with AES */ + RTW_SECURITY_WPA2_TKIP_PSK = ( WPA2_SECURITY | TKIP_ENABLED ), /**< WPA2 Security with TKIP */ + RTW_SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ), /**< WPA2 Security with AES & TKIP */ + RTW_SECURITY_WPA_WPA2_MIXED = ( WPA_SECURITY | WPA2_SECURITY ), /**< WPA/WPA2 Security */ + + RTW_SECURITY_WPS_OPEN = WPS_ENABLED, /**< WPS with open security */ + RTW_SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /**< WPS with AES security */ + + RTW_SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */ + + RTW_SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force rtw_security_t type to 32 bits */ +} rtw_security_t; + +typedef enum { + RTW_ENCRYPTION_UNKNOWN = 0, + RTW_ENCRYPTION_OPEN = 1, + RTW_ENCRYPTION_WEP40 = 2, + RTW_ENCRYPTION_WPA_TKIP = 3, + RTW_ENCRYPTION_WPA_AES = 4, + RTW_ENCRYPTION_WPA2_TKIP = 5, + RTW_ENCRYPTION_WPA2_AES = 6, + RTW_ENCRYPTION_WPA2_MIXED = 7, + RTW_ENCRYPTION_WEP104 = 9, + RTW_ENCRYPTION_UNDEF = 0xFF, +} rtw_encryption_t; + +typedef enum { + RTW_FALSE = 0, + RTW_TRUE = 1 +} rtw_bool_t; + +/** + * @brief The enumeration lists the band types. + */ +typedef enum { + RTW_802_11_BAND_5GHZ = 0, /**< Denotes 5GHz radio band */ + RTW_802_11_BAND_2_4GHZ = 1 /**< Denotes 2.4GHz radio band */ +} rtw_802_11_band_t; + +/** + * @brief The enumeration lists all the country codes able to set to Wi-Fi driver. + */ +typedef enum { + /* CHANNEL PLAN */ + RTW_COUNTRY_WORLD1, // 0x20 + RTW_COUNTRY_ETSI1, // 0x21 + RTW_COUNTRY_FCC1, // 0x22 + RTW_COUNTRY_MKK1, // 0x23 + RTW_COUNTRY_ETSI2, // 0x24 + RTW_COUNTRY_FCC2, // 0x2A + RTW_COUNTRY_WORLD2, // 0x47 + RTW_COUNTRY_MKK2, // 0x58 + RTW_COUNTRY_GLOBAL, // 0x41 + + /* SPECIAL */ + RTW_COUNTRY_WORLD, // WORLD1 + RTW_COUNTRY_EU, // ETSI1 + + /* JAPANESE */ + RTW_COUNTRY_JP, // MKK1 + + /* FCC , 19 countries*/ + RTW_COUNTRY_AS, // FCC2 + RTW_COUNTRY_BM, + RTW_COUNTRY_CA, + RTW_COUNTRY_DM, + RTW_COUNTRY_DO, + RTW_COUNTRY_FM, + RTW_COUNTRY_GD, + RTW_COUNTRY_GT, + RTW_COUNTRY_GU, + RTW_COUNTRY_HT, + RTW_COUNTRY_MH, + RTW_COUNTRY_MP, + RTW_COUNTRY_NI, + RTW_COUNTRY_PA, + RTW_COUNTRY_PR, + RTW_COUNTRY_PW, + RTW_COUNTRY_TW, + RTW_COUNTRY_US, + RTW_COUNTRY_VI, + + /* others, ETSI */ + RTW_COUNTRY_AD, // ETSI1 + RTW_COUNTRY_AE, + RTW_COUNTRY_AF, + RTW_COUNTRY_AI, + RTW_COUNTRY_AL, + RTW_COUNTRY_AM, + RTW_COUNTRY_AN, + RTW_COUNTRY_AR, + RTW_COUNTRY_AT, + RTW_COUNTRY_AU, + RTW_COUNTRY_AW, + RTW_COUNTRY_AZ, + RTW_COUNTRY_BA, + RTW_COUNTRY_BB, + RTW_COUNTRY_BD, + RTW_COUNTRY_BE, + RTW_COUNTRY_BF, + RTW_COUNTRY_BG, + RTW_COUNTRY_BH, + RTW_COUNTRY_BL, + RTW_COUNTRY_BN, + RTW_COUNTRY_BO, + RTW_COUNTRY_BR, + RTW_COUNTRY_BS, + RTW_COUNTRY_BT, + RTW_COUNTRY_BY, + RTW_COUNTRY_BZ, + RTW_COUNTRY_CF, + RTW_COUNTRY_CH, + RTW_COUNTRY_CI, + RTW_COUNTRY_CL, + RTW_COUNTRY_CN, + RTW_COUNTRY_CO, + RTW_COUNTRY_CR, + RTW_COUNTRY_CX, + RTW_COUNTRY_CY, + RTW_COUNTRY_CZ, + RTW_COUNTRY_DE, + RTW_COUNTRY_DK, + RTW_COUNTRY_DZ, + RTW_COUNTRY_EC, + RTW_COUNTRY_EE, + RTW_COUNTRY_EG, + RTW_COUNTRY_ES, + RTW_COUNTRY_ET, + RTW_COUNTRY_FI, + RTW_COUNTRY_FR, + RTW_COUNTRY_GB, + RTW_COUNTRY_GE, + RTW_COUNTRY_GF, + RTW_COUNTRY_GH, + RTW_COUNTRY_GL, + RTW_COUNTRY_GP, + RTW_COUNTRY_GR, + RTW_COUNTRY_GY, + RTW_COUNTRY_HK, + RTW_COUNTRY_HN, + RTW_COUNTRY_HR, + RTW_COUNTRY_HU, + RTW_COUNTRY_ID, + RTW_COUNTRY_IE, + RTW_COUNTRY_IL, + RTW_COUNTRY_IN, + RTW_COUNTRY_IQ, + RTW_COUNTRY_IR, + RTW_COUNTRY_IS, + RTW_COUNTRY_IT, + RTW_COUNTRY_JM, + RTW_COUNTRY_JO, + RTW_COUNTRY_KE, + RTW_COUNTRY_KH, + RTW_COUNTRY_KN, + RTW_COUNTRY_KP, + RTW_COUNTRY_KR, + RTW_COUNTRY_KW, + RTW_COUNTRY_KY, + RTW_COUNTRY_KZ, + RTW_COUNTRY_LA, + RTW_COUNTRY_LB, + RTW_COUNTRY_LC, + RTW_COUNTRY_LI, + RTW_COUNTRY_LK, + RTW_COUNTRY_LR, + RTW_COUNTRY_LS, + RTW_COUNTRY_LT, + RTW_COUNTRY_LU, + RTW_COUNTRY_LV, + RTW_COUNTRY_MA, + RTW_COUNTRY_MC, + RTW_COUNTRY_MD, + RTW_COUNTRY_ME, + RTW_COUNTRY_MF, + RTW_COUNTRY_MK, + RTW_COUNTRY_MN, + RTW_COUNTRY_MO, + RTW_COUNTRY_MQ, + RTW_COUNTRY_MR, + RTW_COUNTRY_MT, + RTW_COUNTRY_MU, + RTW_COUNTRY_MV, + RTW_COUNTRY_MW, + RTW_COUNTRY_MX, + RTW_COUNTRY_MY, + RTW_COUNTRY_NG, + RTW_COUNTRY_NL, + RTW_COUNTRY_NO, + RTW_COUNTRY_NP, + RTW_COUNTRY_NZ, + RTW_COUNTRY_OM, + RTW_COUNTRY_PE, + RTW_COUNTRY_PF, + RTW_COUNTRY_PG, + RTW_COUNTRY_PH, + RTW_COUNTRY_PK, + RTW_COUNTRY_PL, + RTW_COUNTRY_PM, + RTW_COUNTRY_PT, + RTW_COUNTRY_PY, + RTW_COUNTRY_QA, + RTW_COUNTRY_RS, + RTW_COUNTRY_RU, + RTW_COUNTRY_RW, + RTW_COUNTRY_SA, + RTW_COUNTRY_SE, + RTW_COUNTRY_SG, + RTW_COUNTRY_SI, + RTW_COUNTRY_SK, + RTW_COUNTRY_SN, + RTW_COUNTRY_SR, + RTW_COUNTRY_SV, + RTW_COUNTRY_SY, + RTW_COUNTRY_TC, + RTW_COUNTRY_TD, + RTW_COUNTRY_TG, + RTW_COUNTRY_TH, + RTW_COUNTRY_TN, + RTW_COUNTRY_TR, + RTW_COUNTRY_TT, + RTW_COUNTRY_TZ, + RTW_COUNTRY_UA, + RTW_COUNTRY_UG, + RTW_COUNTRY_UY, + RTW_COUNTRY_UZ, + RTW_COUNTRY_VC, + RTW_COUNTRY_VE, + RTW_COUNTRY_VN, + RTW_COUNTRY_VU, + RTW_COUNTRY_WF, + RTW_COUNTRY_WS, + RTW_COUNTRY_YE, + RTW_COUNTRY_YT, + RTW_COUNTRY_ZA, + RTW_COUNTRY_ZW, + + RTW_COUNTRY_MAX + +}rtw_country_code_t; + +/** + * @brief The enumeration lists the adaptivity types. + */ +typedef enum { + RTW_ADAPTIVITY_DISABLE = 0, + RTW_ADAPTIVITY_NORMAL, // CE + RTW_ADAPTIVITY_CARRIER_SENSE // MKK +} rtw_adaptivity_mode_t; + +/** + * @brief The enumeration lists the supported operation mode by WIFI driver, + * including station and AP mode. + */ +typedef enum { + RTW_MODE_NONE = 0, + RTW_MODE_STA, + RTW_MODE_AP, + RTW_MODE_STA_AP, + RTW_MODE_PROMISC, + RTW_MODE_P2P +}rtw_mode_t; + +typedef enum { + RTW_SCAN_FULL = 0, + RTW_SCAN_SOCIAL, + RTW_SCAN_ONE +}rtw_scan_mode_t; + +/** + * @brief The enumeration lists the status to describe the connection link. + */ +typedef enum { + RTW_LINK_DISCONNECTED = 0, + RTW_LINK_CONNECTED +} rtw_link_status_t; + +/** + * @brief The enumeration lists the scan types. + */ +typedef enum { + RTW_SCAN_TYPE_ACTIVE = 0x00, /**< Actively scan a network by sending 802.11 probe(s) */ + RTW_SCAN_TYPE_PASSIVE = 0x01, /**< Passively scan a network by listening for beacons from APs */ + RTW_SCAN_TYPE_PROHIBITED_CHANNELS = 0x04 /**< Passively scan on channels not enabled by the country code */ +} rtw_scan_type_t; + +/** + * @brief The enumeration lists the bss types. + */ +typedef enum { + RTW_BSS_TYPE_INFRASTRUCTURE = 0, /**< Denotes infrastructure network */ + RTW_BSS_TYPE_ADHOC = 1, /**< Denotes an 802.11 ad-hoc IBSS network */ + RTW_BSS_TYPE_ANY = 2, /**< Denotes either infrastructure or ad-hoc network */ + + RTW_BSS_TYPE_UNKNOWN = -1 /**< May be returned by scan function if BSS type is unknown. Do not pass this to the Join function */ +} rtw_bss_type_t; + +typedef enum { + RTW_SCAN_COMMAMD = 0x01 +} rtw_scan_command_t; + +typedef enum{ + COMMAND1 = 0x01 +}rtw_command_type; + +typedef enum { + RTW_WPS_TYPE_DEFAULT = 0x0000, + RTW_WPS_TYPE_USER_SPECIFIED = 0x0001, + RTW_WPS_TYPE_MACHINE_SPECIFIED = 0x0002, + RTW_WPS_TYPE_REKEY = 0x0003, + RTW_WPS_TYPE_PUSHBUTTON = 0x0004, + RTW_WPS_TYPE_REGISTRAR_SPECIFIED = 0x0005, + RTW_WPS_TYPE_NONE = 0x0006, + RTW_WPS_TYPE_WSC = 0x0007 +} rtw_wps_type_t; + +/** + * @brief The enumeration lists all the network bgn mode. + */ +typedef enum { + RTW_NETWORK_B = 1, + RTW_NETWORK_BG = 3, + RTW_NETWORK_BGN = 11 +} rtw_network_mode_t; + +/** + * @brief The enumeration lists the interfaces. + */ +typedef enum { + RTW_STA_INTERFACE = 0, /**< STA or Client Interface */ + RTW_AP_INTERFACE = 1, /**< SoftAP Interface */ +} rtw_interface_t; + +/** + * @brief The enumeration lists the packet filter rules. + */ +typedef enum { + RTW_POSITIVE_MATCHING = 0, /**< Receive the data matching with this pattern and discard the other data */ + RTW_NEGATIVE_MATCHING = 1 /**< Discard the data matching with this pattern and receive the other data */ +} rtw_packet_filter_rule_t, rtw_packet_filter_rule_e; + +/** + * @brief The enumeration lists the promisc levels. + */ +typedef enum { + RTW_PROMISC_DISABLE = 0, /**< Disable the promisc */ + RTW_PROMISC_ENABLE = 1, /**< Fetch all ethernet packets */ + RTW_PROMISC_ENABLE_1 = 2, /**< Fetch only B/M packets */ + RTW_PROMISC_ENABLE_2 = 3, /**< Fetch all 802.11 packets*/ + RTW_PROMISC_ENABLE_3 = 4, /**< Fetch only B/M 802.11 packets*/ +} rtw_rcr_level_t; + +/** + * @brief The enumeration lists the disconnect reasons. + */ +typedef enum{ + RTW_NO_ERROR = 0, + RTW_NONE_NETWORK = 1, + RTW_CONNECT_FAIL = 2, + RTW_WRONG_PASSWORD = 3 , + RTW_DHCP_FAIL = 4, + RTW_UNKNOWN, +}rtw_connect_error_flag_t; + +typedef enum { + RTW_TX_PWR_PERCENTAGE_100 = 0, /* 100%, default target output power. */ + RTW_TX_PWR_PERCENTAGE_75 = 1, /* 75% */ + RTW_TX_PWR_PERCENTAGE_50 = 2, /* 50% */ + RTW_TX_PWR_PERCENTAGE_25 = 3, /* 25% */ + RTW_TX_PWR_PERCENTAGE_12_5 = 4, /* 12.5% */ +}rtw_tx_pwr_percentage_t; + +/** + * @brief The enumeration is event type indicated from wlan driver. + */ +typedef enum _WIFI_EVENT_INDICATE{ + WIFI_EVENT_CONNECT = 0, + WIFI_EVENT_DISCONNECT = 1, + WIFI_EVENT_FOURWAY_HANDSHAKE_DONE = 2, + WIFI_EVENT_SCAN_RESULT_REPORT = 3, + WIFI_EVENT_SCAN_DONE = 4, + WIFI_EVENT_RECONNECTION_FAIL = 5, + WIFI_EVENT_SEND_ACTION_DONE = 6, + WIFI_EVENT_RX_MGNT = 7, + WIFI_EVENT_STA_ASSOC = 8, + WIFI_EVENT_STA_DISASSOC = 9, + WIFI_EVENT_STA_WPS_START = 10, + WIFI_EVENT_WPS_FINISH = 11, + WIFI_EVENT_EAPOL_START = 12, + WIFI_EVENT_EAPOL_RECVD = 13, + WIFI_EVENT_NO_NETWORK = 14, + WIFI_EVENT_BEACON_AFTER_DHCP = 15, + WIFI_EVENT_MAX, +}rtw_event_indicate_t, WIFI_EVENT_INDICATE; +#ifdef __cplusplus +} +#endif + +/*\@}*/ + +#endif /* _WIFI_CONSTANTS_H */ diff --git a/USDK/component/common/drivers/wlan/realtek/include/wifi_lib.h b/USDK/component/common/drivers/wlan/realtek/include/wifi_lib.h new file mode 100644 index 0000000..2ecfeee --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wifi_lib.h @@ -0,0 +1,3437 @@ +/* + wifi_lib.h + RTL871x pvvx + */ +#ifndef _WLAN_LIB_H +#define _WLAN_LIB_H + +#include "osdep_service.h" +#include "freertos/wrapper.h" +#include "rtl_bios_data.h" + +#define _atr_aligned2_ __attribute__((aligned(2))) +#define _atr_aligned4_ __attribute__((aligned(4))) +#define _atr_aligned8_ __attribute__((aligned(4))) + +#define sint8_t char +#define sint16_t short +#define sint32_t int +//#define sint64_t long long // warning align(8)! +/* + struct _ADAPTER; + struct dvobj_priv; + union recv_frame; + struct sk_buff; + struct sk_buff_head; + struct sta_info; + struct _cus_ie; + struct fifo_more_data; + struct hw_xmit; + struct tx_buf_desc; + struct recv_buf_stat; + struct _wpa_sta_info; + struct xmit_frame; + struct xmit_buf; + struct submit_ctx; + struct net_device; + struct iwreq; + struct co_data_priv; + */ +//typedef int sint32_t_t; +//typedef char sint8_t_t; +//typedef sint8_t_t int8_t; +//typedef uint32_t __uint32_t; +//typedef sint32_t_t int32_t; +//typedef __uint32_t uint32_t; +//typedef uint32_t dma_addr_t; // basic_types.h +//typedef uint8_t uint8_t; +//typedef uint16_t uint16_t; +//typedef unsigned sint64_t u8Byte; +typedef int sint; +typedef uint8_t BOOL; +typedef uint8_t bool; +typedef uint8_t BOOLEAN; + +typedef uint8_t u1Byte; +typedef uint16_t u2Byte; +typedef uint32_t u4Byte; +typedef uint64_t u8Byte; +typedef uint64_t __attribute__((aligned(4))) _u8Byte; +typedef sint8_t s1Byte; +typedef sint16_t s2Byte; +typedef sint32_t s4Byte; +typedef sint8_t *ps1Byte; +typedef uint8_t *pu1Byte; +typedef uint16_t *pu2Byte; +typedef uint32_t *pu4Byte; + +typedef uint32_t sizetype; +typedef struct _ADAPTER _adapter; +typedef void *_lock; +typedef struct list_head _list; +typedef void *PVOID; +typedef struct __queue _queue; +typedef void *_mutex; + +typedef int (*init_done_ptr)(void); + +enum _EFUSE_DEF_TYPE // : sint32_t +{ + TYPE_EFUSE_MAX_SECTION = 0x0, + TYPE_EFUSE_REAL_CONTENT_LEN = 0x1, + TYPE_AVAILABLE_EFUSE_BYTES_BANK = 0x2, + TYPE_AVAILABLE_EFUSE_BYTES_TOTAL = 0x3, + TYPE_EFUSE_MAP_LEN = 0x4, + TYPE_EFUSE_PROTECT_BYTES_BANK = 0x5, + TYPE_EFUSE_CONTENT_LEN_BANK = 0x6, +}; + +enum _IFACE_TYPE //: sint32_t +{ + IFACE_PORT0 = 0x0, IFACE_PORT1 = 0x1, MAX_IFACE_PORT = 0x2, +}; + +enum _FW_ERR0_STATUS_ //: sint32_t +{ + FES0_H2C_CMDID = 0x1, + FES0_H2C_PTR = 0x2, + FES0_BB_RW = 0x4, + FES0_TXPKT_TXPAUSE = 0x8, + FES0_TSF_STABLE = 0x10, + FES0_TXSM_STABLE = 0x20, + FES0_RPWM_STABLE = 0x40, + FES0_C2H_TIMEOUT_ERR = 0x80, +}; + +enum _TRPC_ //: sint32_t +{ + TPRC_ISSUENULLDATA_1 = 0x26, + TPRC_ISSUENULLDATA_2 = 0x27, + TPRC_PSS2TS3 = 0x2B, + TPRC_PSS0TS1 = 0x2C, + TPRC_PSS2TS4 = 0x2D, + TPRC_PSS2TS5 = 0x2E, + TPRC_PSS0TS6 = 0x2F, +}; + +enum _PS_MODE_SETTING_SELECTION_ // : sint32_t +{ + MODE_SETTING_ACTIVE = 0x0, + MODE_SETTING_LEGACY = 0x1, + MODE_SETTING_WMMPS = 0x2, + MODE_SETTING_TDMA = 0x3, +}; + +enum _RxListenBeaconMode_ // : sint32_t +{ + RLBM_MIN = 0x0, RLBM_MAX = 0x1, RLBM_SELF_DEFINED = 0x2, +}; + +enum _SMART_PS_MODE_FOR_LEGACY_ // : sint32_t +{ + SMART_PS_MODE_LEGACY_PWR1 = 0x0, + SMART_PS_MODE_TX_PWR0 = 0x1, + SMART_PS_MODE_TRX_PWR0 = 0x2, +}; + +enum $BFA04BDFA6C0C275C890D1E658AFCEEF // : sint32_t +{ + ROM_E_RTW_MSGP_PWR_INDEX_1 = 0x0, + ROM_E_RTW_MSGP_PWR_INDEX_2 = 0x1, + ROM_E_RTW_MSGP_RX_INFO_1 = 0x2, + ROM_E_RTW_MSGP_RX_INFO_2 = 0x3, + ROM_E_RTW_MSGP_RX_INFO_3 = 0x4, + ROM_E_RTW_MSGP_RX_INFO_4 = 0x5, + ROM_E_RTW_MSGP_TX_RATE_1 = 0x6, + ROM_E_RTW_MSGP_TX_RATE_2 = 0x7, + ROM_E_RTW_MSGP_DM_RA_1 = 0x8, + ROM_E_RTW_MSGP_DM_RA_2 = 0x9, + ROM_E_RTW_MSGP_DM_RA_3 = 0xA, + ROM_E_RTW_MSGP_DM_RA_4 = 0xB, + ROM_E_RTW_MSGP_DM_DIG_1 = 0xC, + ROM_E_RTW_MSGP_PWR_TRACKING_1 = 0xD, + ROM_E_RTW_MSGP_PWR_TRACKING_2 = 0xE, + ROM_E_RTW_MSGP_PWR_TRACKING_3 = 0xF, + ROM_E_RTW_MSGP_PWR_TRACKING_4 = 0x10, + ROM_E_RTW_MSGP_PWR_TRACKING_5 = 0x11, + ROM_E_RTW_MSGP_PWR_TRACKING_6 = 0x12, + ROM_E_RTW_MSGP_PWR_TRACKING_7 = 0x13, + ROM_E_RTW_MSGP_RF_IQK_1 = 0x14, + ROM_E_RTW_MSGP_RF_IQK_2 = 0x15, + ROM_E_RTW_MSGP_RF_IQK_3 = 0x16, + ROM_E_RTW_MSGP_RF_IQK_4 = 0x17, + ROM_E_RTW_MSGP_RF_IQK_5 = 0x18, + ROM_E_RTW_MSGP_DM_ADAPTIVITY_1 = 0x19, + ROM_E_RTW_MSGP_DM_ADAPTIVITY_2 = 0x1A, + ROM_E_RTW_MSGP_DM_ADAPTIVITY_3 = 0x1B, + ROM_E_RTW_MSGP_DM_ANT_DIV_1 = 0x1C, + ROM_E_RTW_MSGP_DM_ANT_DIV_2 = 0x1D, + ROM_E_RTW_MSGP_DM_ANT_DIV_3 = 0x1E, + ROM_E_RTW_MSGP_DM_ANT_DIV_4 = 0x1F, + ROM_E_RTW_MSGP_DM_ANT_DIV_5 = 0x20, + ROM_E_RTW_MSGP_MAC_REG_DUMP_1 = 0x21, + ROM_E_RTW_MSGP_BB_REG_DUMP_1 = 0x22, + ROM_E_RTW_MSGP_RF_REG_DUMP_1 = 0x23, + ROM_E_RTW_MSGP_RF_REG_DUMP_2 = 0x24, + ROM_E_RTW_MSGP_REG_DUMP_1 = 0x25, + ROM_E_RTW_MSGP_REG_DUMP_2 = 0x26, + ROM_E_RTW_MSGP_REG_DUMP_3 = 0x27, + ROM_E_RTW_MSGP_READ_REG_1 = 0x28, + ROM_E_RTW_MSGP_READ_REG_2 = 0x29, + ROM_E_RTW_MSGP_READ_REG_3 = 0x2A, + ROM_E_RTW_MSGP_WRITE_REG_1 = 0x2B, + ROM_E_RTW_MSGP_WRITE_REG_2 = 0x2C, + ROM_E_RTW_MSGP_WRITE_REG_3 = 0x2D, + ROM_E_RTW_MSGP_READ_BB_1 = 0x2E, + ROM_E_RTW_MSGP_WRITE_BB_1 = 0x2F, + ROM_E_RTW_MSGP_READ_RF_1 = 0x30, + ROM_E_RTW_MSGP_WRITE_RF_1 = 0x31, + ROM_E_RTW_MSGP_READ_SYS_1 = 0x32, + ROM_E_RTW_MSGP_WRITE_SYS_1 = 0x33, + ROM_E_RTW_MSGP_FIX_CHANNEL_1 = 0x34, + ROM_E_RTW_MSGP_FIX_CHANNEL_2 = 0x35, + ROM_E_RTW_MSGP_PWR_SAVE_MODE_1 = 0x36, + ROM_E_RTW_MSGP_FIX_RATE_1 = 0x37, + ROM_E_RTW_MSGP_GET_ODM_DBG_FLAG_1 = 0x38, + ROM_E_RTW_MSGP_SET_ODM_DBG_FLAG_1 = 0x39, + ROM_E_RTW_MSGP_DUMP_PWR_IDX_1 = 0x3A, + ROM_E_RTW_MSGP_DUMP_INFO_1 = 0x3B, + ROM_E_RTW_MSGP_DUMP_INFO_2 = 0x3C, + ROM_E_RTW_MSGP_DUMP_INFO_3 = 0x3D, + ROM_E_RTW_MSGP_DUMP_INFO_4 = 0x3E, + ROM_E_RTW_MSGP_DUMP_INFO_5 = 0x3F, + ROM_E_RTW_MSGP_DUMP_INFO_6 = 0x40, + ROM_E_RTW_MSGP_DUMP_INFO_7 = 0x41, + ROM_E_RTW_MSGP_DUMP_INFO_8 = 0x42, + ROM_E_RTW_MSGP_DUMP_INFO_9 = 0x43, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_1 = 0x44, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_2 = 0x45, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_3 = 0x46, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_4 = 0x47, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_5 = 0x48, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_6 = 0x49, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_7 = 0x4A, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_8 = 0x4B, + ROM_E_RTW_MSGP_DM_FUNC_FLAG_9 = 0x4C, + ROM_E_RTW_MSGP_RX_MPDU_1 = 0x4D, + ROM_E_RTW_MSGP_AP_TIMEOUT_CHK_1 = 0x4E, + ROM_E_RTW_MSGP_INIT_DRV_SW_1 = 0x4F, + ROM_E_RTW_MSGP_SET_BSSID_1 = 0x50, + ROM_E_RTW_MSGP_SET_SSID_1 = 0x51, + ROM_E_RTW_MSGP_ON_BEACON_1 = 0x52, + ROM_E_RTW_MSGP_ON_AUTH_1 = 0x53, + ROM_E_RTW_MSGP_ON_AUTH_2 = 0x54, + ROM_E_RTW_MSGP_ON_AUTH_CLIENT_1 = 0x55, + ROM_E_RTW_MSGP_ON_ASSOC_REQ_1 = 0x56, + ROM_E_RTW_MSGP_ON_ASSOC_RSP_1 = 0x57, + ROM_E_RTW_MSGP_ON_DE_AUTH_1 = 0x58, + ROM_E_RTW_MSGP_ON_DE_AUTH_2 = 0x59, + ROM_E_RTW_MSGP_ON_DISASSOC_1 = 0x5A, + ROM_E_RTW_MSGP_ON_DISASSOC_2 = 0x5B, + ROM_E_RTW_MSGP_ISSUE_BEACON_1 = 0x5C, + ROM_E_RTW_MSGP_ISSUE_PROBERSP_1 = 0x5D, + ROM_E_RTW_MSGP_ISSUE_PROBEREQ_1 = 0x5E, + ROM_E_RTW_MSGP_ISSUE_AUTH_1 = 0x5F, + ROM_E_RTW_MSGP_ISSUE_ASSOCRSP_1 = 0x60, + ROM_E_RTW_MSGP_ISSUE_ASSOCREQ_1 = 0x61, + ROM_E_RTW_MSGP_ISSUE_NULLDATA_1 = 0x62, + ROM_E_RTW_MSGP_ISSUE_QOS_NULLDATA_1 = 0x63, + ROM_E_RTW_MSGP_ISSUE_DEAUTH_1 = 0x64, + ROM_E_RTW_MSGP_ISSUE_ACTION_BA_1 = 0x65, + ROM_E_RTW_MSGP_ISSUE_BSS_COEXIST_1 = 0x66, + ROM_E_RTW_MSGP_START_CLNT_AUTH_1 = 0x67, + ROM_E_RTW_MSGP_LINKED_STATUS_CHK_1 = 0x68, + ROM_E_RTW_MSGP_SETKEY_HDL_1 = 0x69, + ROM_E_RTW_MSGP_SET_STAKEY_HDL_1 = 0x6A, + ROM_E_RTW_MSGP_SET_STAKEY_HDL_2 = 0x6B, + ROM_E_RTW_MSGP_P2P_BUILD_MGNT_FRAME_1 = 0x6C, + ROM_E_RTW_MSGP_SEND_EAPOL_1 = 0x6D, + ROM_E_RTW_MSGP_SEND_EAPOL_2 = 0x6E, + ROM_E_RTW_MSGP_SEND_EAPOL_3 = 0x6F, + ROM_E_RTW_MSGP_EAPOL_KEY_RECVD_1 = 0x70, + ROM_E_RTW_MSGP_EAPOL_KEY_RECVD_2 = 0x71, + ROM_E_RTW_MSGP_EAPOL_KEY_RECVD_3 = 0x72, + ROM_E_RTW_MSGP_FREE_RECVFRAME_1 = 0x73, + ROM_E_RTW_MSGP_VAR_PORT_SWITCH_1 = 0x74, + ROM_E_RTW_MSGP_VAR_PORT_SWITCH_2 = 0x75, + ROM_E_RTW_MSGP_DOWN_SEMA_1 = 0x76, + ROM_E_RTW_MSGP_MAX = 0x77 +}; + +struct _atr_aligned4_ _PS_PARM_ { + uint8_t Enter32KHzPermission; + uint8_t bAllQueueUAPSD; + uint8_t ps_dtim_flag; + uint8_t pstrx_rxcnt_period; + uint8_t NoConnect32k; + uint8_t ack_last_rpwm; + uint8_t TxNull0; + uint8_t TxNull1; + uint8_t TxNull0ok; + uint8_t TxNull1ok; + uint8_t RfOffLicenseForBCNRx; + uint8_t BCNAggEn; + uint8_t IsGoingTo32K; + uint8_t bMaxTrackingBcnMode; + uint8_t BcnTraceDone; + uint8_t smart_ps :4; + uint8_t RLBM :4; + uint8_t AwakeInterval; + uint8_t ps_mode; + uint8_t ClkRequestEnable; + uint8_t last_rpwm; + uint8_t current_ps_state; + uint8_t ps_data_open; + uint8_t ps_bcn_pass_time; + uint8_t ps_dtim_period; + uint8_t ps_dtim_cnt; + uint8_t ps_bcn_to; + uint8_t bcn_to_cnt; + uint8_t bcn_to_times_cnt; + uint8_t min_rate_in_rrsr; + uint16_t ps_drv_early_itv; + uint32_t null1_ok_cnt; + uint8_t SlotPeriod; + uint8_t FirstOnPeriod; + uint8_t SecondOnPeriod; + uint8_t ThirdOnPeriod; + uint8_t CurrentSlot; + BOOLEAN TDMAOnPeriod; +}; +typedef struct _PS_PARM_ PS_PARM; +typedef struct _PS_PARM_ *PPS_PARM; + +struct _LEGACY_PS_PPARM_ { + uint8_t ps_mode :7; + uint8_t ClkRequestEnable :1; + uint8_t RLBM :4; + uint8_t smart_ps :4; + uint8_t AwakeInterval; + uint8_t bAllQueueUAPSD :1; + uint8_t bMaxTrackingBcnMode :1; + uint8_t rsvd :6; + uint8_t PwrState; + uint8_t LowPwrRxBCN :1; + uint8_t AntAutoSwitch :1; + uint8_t PSAllowBTHighPri :1; + uint8_t ProtectBCN :1; + uint8_t SilencePeriod :1; + uint8_t FastBTConnect :1; + uint8_t TwoAntennaEn :1; + uint8_t rsvd2 :1; + uint8_t AdoptUserSetting :1; + uint8_t DrvBcnEarlyShift :3; + uint8_t DrvBcnTimeOut :4; + uint8_t SlotPeriod; + uint8_t FirstOnPeriod; + uint8_t SecondOnPeriod; + uint8_t ThirdOnPeriod; +}; +typedef struct _LEGACY_PS_PPARM_ LEGACY_PS_PARM; +typedef struct _LEGACY_PS_PPARM_ *PLEGACY_PS_PARM; + +struct _H2CParam_SetPwrMode_parm_ { + LEGACY_PS_PARM PwrModeParm; +}; +typedef struct _H2CParam_SetPwrMode_parm_ *PH2CParam_PwrMode; + +struct atomic_t { + volatile int counter; +}; + +/* + // dlist.h + struct list_head + { + _list *next; + _list *prev; + }; + + // freertos_service.h + struct __queue + { + _list queue; + _lock lock; + }; + */ + +struct iw_request_info { + uint16_t cmd; + uint16_t flags; +}; + +typedef int (*iw_handler)(struct net_device *, struct iw_request_info *, + union iwreq_data *, char *); + +struct _NDIS_802_11_SSID { + uint32_t SsidLength; //+164 + uint8_t Ssid[36]; +}; +typedef struct _NDIS_802_11_SSID NDIS_802_11_SSID; +typedef uint8_t NDIS_802_11_MAC_ADDRESS[6]; +typedef int NDIS_802_11_RSSI; + +enum _NDIS_802_11_NETWORK_TYPE //sint32_t +{ + Ndis802_11FH = 0x0, + Ndis802_11DS = 0x1, + Ndis802_11OFDM5 = 0x2, + Ndis802_11OFDM24 = 0x3, + Ndis802_11NetworkTypeMax = 0x4, +}; +typedef enum _NDIS_802_11_NETWORK_TYPE NDIS_802_11_NETWORK_TYPE; + +struct _NDIS_802_11_CONFIGURATION_FH { + uint32_t Length; + uint32_t HopPattern; + uint32_t HopSet; + uint32_t DwellTime; +}; +typedef struct _NDIS_802_11_CONFIGURATION_FH NDIS_802_11_CONFIGURATION_FH; + +struct _NDIS_802_11_CONFIGURATION { + uint32_t Length; + uint32_t BeaconPeriod; + uint32_t ATIMWindow; + uint32_t DSConfig; + NDIS_802_11_CONFIGURATION_FH FHConfig; +}; +typedef struct _NDIS_802_11_CONFIGURATION NDIS_802_11_CONFIGURATION; + +enum _NDIS_802_11_NETWORK_INFRASTRUCTURE // : sint32_t +{ + Ndis802_11IBSS = 0x0, + Ndis802_11Infrastructure = 0x1, + Ndis802_11AutoUnknown = 0x2, + Ndis802_11InfrastructureMax = 0x3, + Ndis802_11APMode = 0x4, +}; +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE NDIS_802_11_NETWORK_INFRASTRUCTURE; + +typedef uint8_t NDIS_802_11_RATES_EX[16]; + +struct _WLAN_PHY_INFO { + uint8_t SignalStrength; + uint8_t SignalQuality; + uint8_t Optimum_antenna; + uint8_t Reserved_0; +}; +typedef struct _WLAN_PHY_INFO WLAN_PHY_INFO; + +struct _WLAN_BSSID_EX { + uint32_t Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + uint8_t Reserved[2]; + NDIS_802_11_SSID Ssid; // +164 + uint32_t Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + WLAN_PHY_INFO PhyInfo; + uint32_t IELength; + uint8_t IEs[768]; +}; +typedef struct _WLAN_BSSID_EX WLAN_BSSID_EX; + +struct _atr_aligned2_ _WLAN_BCN_INFO { // __attribute__((packed))!? + uint8_t encryp_protocol; + int group_cipher; + int pairwise_cipher; + int is_8021x; + uint16_t ht_cap_info; + uint8_t ht_info_infos_0; +}; +typedef struct _WLAN_BCN_INFO WLAN_BCN_INFO; + +struct wlan_network { + _list list; + int network_type; + int fixed; + uint32_t last_scanned; + int aid; + int join_res; + WLAN_BSSID_EX network; + WLAN_BCN_INFO BcnInfo; +}; + +/* osdep_service.h + typedef void *_timerHandle; + + struct timer_list + { + _timerHandle timer_hdl; + uint32_t data; + void (*function)(void *); + }; + + typedef struct timer_list _timer; + */ + +struct qos_priv { + uint32_t qos_option; +}; + +struct __attribute__((packed)) _atr_aligned2_ rtw_ieee80211_ht_cap { + uint16_t cap_info; + uint8_t ampdu_params_info; + uint8_t supp_mcs_set[16]; + uint16_t extended_ht_cap_info; + uint32_t tx_BF_cap_info; + uint8_t antenna_selection_info; +}; + +struct ht_priv { + uint32_t ht_option; + uint32_t ampdu_enable; + uint8_t bwmode; + uint8_t ch_offset; + uint8_t sgi; + uint8_t agg_enable_bitmap; + uint8_t candidate_tid_bitmap; + uint8_t stbc_cap; + struct rtw_ieee80211_ht_cap ht_cap; +}; + +struct _atr_aligned4_ _RT_LINK_DETECT_T { + uint32_t NumTxOkInPeriod; + uint32_t NumRxOkInPeriod; + uint32_t NumRxUnicastOkInPeriod; + BOOLEAN bBusyTraffic; + BOOLEAN bTxBusyTraffic; + BOOLEAN bRxBusyTraffic; + BOOLEAN bHigherBusyTraffic; + BOOLEAN bHigherBusyRxTraffic; + BOOLEAN bHigherBusyTxTraffic; +}; +typedef struct _RT_LINK_DETECT_T RT_LINK_DETECT_T; + +enum _RT_SCAN_TYPE //: sint32_t +{ + SCAN_PASSIVE = 0x0, SCAN_ACTIVE = 0x1, SCAN_MIX = 0x2 +}; +typedef enum _RT_SCAN_TYPE RT_SCAN_TYPE; + +struct mlme_priv { + _lock lock; //+12 + sint fw_state; //+16 + uint8_t bScanInProcess; //+20 + uint8_t to_join; //+21 + uint8_t *nic_hdl; //+24 + _list *pscanned; //+28 + _queue free_bss_pool; //+32 + _queue scanned_queue; //+44 + uint8_t *free_bss_buf; //+56 + uint16_t num_of_scanned; //+60 + uint8_t *scan_buf; //+64 + uint32_t scan_buf_len; //+68 + uint16_t scan_cnt; //+72 + uint16_t scan_type; //+74 + NDIS_802_11_SSID assoc_ssid; //+76 + uint8_t assoc_bssid[6]; + struct wlan_network cur_network; + uint32_t scan_interval; + _timer assoc_timer; + uint8_t assoc_by_bssid; + uint8_t assoc_by_rssi; + _timer scan_to_timer; + uint32_t scan_start_time; + struct qos_priv qospriv; + uint16_t num_sta_no_ht; + uint16_t num_FortyMHzIntolerant; + struct ht_priv htpriv; + RT_LINK_DETECT_T LinkDetectInfo; + _timer dynamic_chk_timer; + uint8_t key_mask; + uint8_t acm_mask; + uint8_t ChannelPlan; + uint8_t scan_mode; // RT_SCAN_TYPE scan_mode; byte/dword ?? + uint8_t *wps_probe_req_ie; + uint32_t wps_probe_req_ie_len; + uint8_t *wps_assoc_req_ie; + uint32_t wps_assoc_req_ie_len; + uint16_t num_sta_non_erp; + uint16_t num_sta_no_short_slot_time; + uint16_t num_sta_no_short_preamble; + uint16_t num_sta_ht_no_gf; + uint16_t num_sta_ht_20mhz; + uint8_t olbc_ht; + uint16_t ht_op_mode; + uint8_t *wps_beacon_ie; + uint8_t *wps_probe_resp_ie; + uint8_t *wps_assoc_resp_ie; + uint32_t wps_beacon_ie_len; + uint32_t wps_probe_resp_ie_len; + uint32_t wps_assoc_resp_ie_len; + _lock bcn_update_lock; + uint8_t update_bcn; + uint8_t scanning_via_buddy_intf; + struct recv_frame *p_copy_recv_frame; +}; + +struct _atr_aligned4_ _RT_CHANNEL_INFO { + uint8_t ChannelNum; + RT_SCAN_TYPE ScanType; // uint8_t ScanType; // byte/dword? + uint8_t pscan_config; +}; +typedef struct _RT_CHANNEL_INFO RT_CHANNEL_INFO; + +struct ss_res { + int state; + int bss_cnt; + int channel_idx; + int scan_mode; + NDIS_802_11_SSID ssid[1]; +}; + +struct __attribute__((packed)) __attribute__((aligned(1))) ADDBA_request { + uint8_t dialog_token; + uint16_t BA_para_set; + uint16_t BA_timeout_value; + uint16_t BA_starting_seqctrl; +}; + +struct AC_param { + uint8_t ACI_AIFSN; + uint8_t CW; + uint16_t TXOP_limit; +}; + +struct WMM_para_element { + uint8_t QoS_info; + uint8_t reserved; + struct AC_param ac_param[4]; +}; + +struct HT_caps_element { + union { + struct _atr_aligned4_ { + uint16_t HT_caps_info; + uint8_t AMPDU_para; + uint8_t MCS_rate[16]; + uint16_t HT_ext_caps; + uint32_t Beamforming_caps; + uint8_t ASEL_caps; + } HT_cap_element; + uint8_t HT_cap[26]; + }u; +}; + +struct HT_info_element { + uint8_t primary_channel; + uint8_t infos[5]; + uint8_t MCS_rate[16]; +}; + +struct FW_Sta_Info { + struct sta_info *psta; + uint32_t status; + uint32_t rx_pkt; + uint32_t retry; + NDIS_802_11_RATES_EX SupportedRates; +}; + +struct mlme_ext_info { + uint32_t state; + uint32_t reauth_count; + uint32_t reassoc_count; + uint32_t link_count; + uint32_t auth_seq; + uint32_t auth_algo; + uint32_t authModeToggle; + uint32_t enc_algo; + uint32_t key_index; + uint32_t iv; + uint8_t chg_txt[128]; + uint16_t aid; + uint16_t bcn_interval; + uint16_t capability; + uint8_t assoc_AP_vendor; + uint8_t slotTime; + uint8_t preamble_mode; + uint8_t WMM_enable; + uint8_t ERP_enable; + uint8_t ERP_IE; + uint8_t HT_enable; + uint8_t HT_caps_enable; + uint8_t HT_info_enable; + uint8_t HT_protection; + uint8_t turboMode_cts2self; + uint8_t turboMode_rtsen; + uint8_t SM_PS; + uint8_t agg_enable_bitmap; + uint8_t ADDBA_retry_count; + uint8_t candidate_tid_bitmap; + uint8_t dialogToken; + uint8_t bwmode_updated; + uint8_t hidden_ssid_mode; + struct ADDBA_request ADDBA_req; + struct WMM_para_element WMM_param; + struct __attribute__((packed)) __attribute__((aligned(1))) HT_caps_element HT_caps; + struct HT_info_element HT_info; + struct FW_Sta_Info FW_sta_info[5]; +}; + +#ifndef _CUS_IE_ +#define _CUS_IE_ +typedef struct _cus_ie{ + __u8 *ie; + __u8 type; +} cus_ie, *p_cus_ie; +#endif /* _CUS_IE_ */ +// typedef struct _cus_ie *p_cus_ie; + +struct mlme_ext_priv { //__attribute__((packed))? + _adapter *padapter; //+0 padapter+1256 [912] + uint8_t mlmeext_init; + struct atomic_t event_seq; + uint16_t mgnt_seq; + uint8_t cur_channel; // padapter+1270 + uint8_t cur_bwmode; + uint8_t cur_ch_offset; + uint8_t cur_wireless_mode; + uint8_t max_chan_nums; + RT_CHANNEL_INFO channel_set[14]; + uint8_t basicrate[13]; + uint8_t datarate[13]; + struct ss_res sitesurvey_res; //padapter+1472 + struct mlme_ext_info mlmext_info; //padapter+1528 + _timer survey_timer; + _timer link_timer; + uint16_t chan_scan_time; //padapter+1984 + uint8_t scan_abort; //padapter+1986 + uint8_t tx_rate; //padapter+1987 + uint8_t retry; //padapter+1988 + _u8Byte TSFValue; //+740? padapter+1992 + uint8_t bstart_bss; + uint16_t action_public_rxseq; + _timer reconnect_timer; + uint8_t reconnect_deauth_filtered; + uint8_t reconnect_times; //+2017 + uint8_t reconnect_cnt; + uint16_t reconnect_timeout; //+ 2020 + uint8_t saved_alg; + uint8_t saved_essid[33]; + uint8_t saved_key[32]; + uint16_t saved_key_len; + uint8_t saved_key_idx; + uint8_t saved_wpa_passphrase[65]; + uint8_t saved_eap_method; + uint8_t auto_reconnect; // + 2157 ? + uint8_t partial_scan; + p_cus_ie cus_ven_ie; + uint8_t ie_num; + uint8_t bChDeauthDisabled; + uint8_t bConcurrentFlushingSTA; +}; + +struct cmd_priv { + _queue cmd_queue; + uint8_t cmdthd_running; + _adapter *padapter; +}; + +struct evt_priv { + struct atomic_t event_seq; + uint8_t *evt_buf; + uint8_t *evt_allocated_buf; + uint32_t evt_done_cnt; +}; + +struct _io_ops { + int (*init_io_priv)(struct dvobj_priv *); + int (*write8_endian)(struct dvobj_priv *, uint32_t, uint32_t, uint32_t); + uint8_t (*_read8)(struct dvobj_priv *, uint32_t, int32_t *); + uint16_t (*_read16)(struct dvobj_priv *, uint32_t, int32_t *); + uint32_t (*_read32)(struct dvobj_priv *, uint32_t, int32_t *); + int32_t (*_write8)(struct dvobj_priv *, uint32_t, uint8_t, int32_t *); + int32_t (*_write16)(struct dvobj_priv *, uint32_t, uint16_t, int32_t *); + int32_t (*_write32)(struct dvobj_priv *, uint32_t, uint32_t, int32_t *); + int (*read_rx_fifo)(struct dvobj_priv *, uint32_t, uint8_t *, uint32_t, + struct fifo_more_data *); + int (*write_tx_fifo)(struct dvobj_priv *, uint32_t, uint8_t *, uint32_t); +}; + +struct io_priv { + struct _io_ops io_ops; +}; + +struct rtw_tx_ring { + struct tx_buf_desc *desc; + dma_addr_t dma; + uint32_t idx; + uint32_t entries; + _queue queue; + uint32_t qlen; +}; + +struct _atr_aligned8_ xmit_priv { + _lock lock; + _queue be_pending; + _queue bk_pending; + _queue vi_pending; + _queue vo_pending; + _queue bm_pending; + uint8_t *pallocated_frame_buf; + uint8_t *pxmit_frame_buf; + uint32_t free_xmitframe_cnt; + _queue free_xmit_queue; + _adapter *adapter; + uint8_t vcs_setting; + uint8_t vcs; + uint8_t vcs_type; + u8Byte tx_bytes; + u8Byte tx_pkts; + u8Byte tx_drop; + u8Byte last_tx_bytes; + u8Byte last_tx_pkts; + struct hw_xmit *hwxmits; + uint8_t hwxmit_entry; + struct rtw_tx_ring tx_ring[8]; + int txringcount[8]; + uint8_t beaconDMAing; + _queue free_xmitbuf_queue; + _queue pending_xmitbuf_queue; + uint8_t *pallocated_xmitbuf; + uint8_t *pxmitbuf; + uint32_t free_xmitbuf_cnt; + _queue free_xmit_extbuf_queue; + uint8_t *pallocated_xmit_extbuf; + uint8_t *pxmit_extbuf; + uint32_t free_xmit_extbuf_cnt; + uint16_t nqos_ssn; +}; + +struct rtw_rx_ring { + struct recv_buf_stat *desc; + dma_addr_t dma; + uint32_t idx; + struct sk_buff *rx_buf[4]; +}; + +struct signal_stat { + uint8_t update_req; + uint8_t avg_val; + uint32_t total_num; + uint32_t total_val; +}; + +struct _atr_aligned8_ recv_priv { + _lock lock; + _queue free_recv_queue; + _queue recv_pending_queue; + _queue uc_swdec_pending_queue; + uint8_t *pallocated_frame_buf; + uint8_t *precv_frame_buf; + uint32_t free_recvframe_cnt; + _adapter *adapter; + uint32_t bIsAnyNonBEPkts; + u8Byte rx_bytes; + u8Byte rx_pkts; + u8Byte rx_drop; + u8Byte rx_overflow; + u8Byte last_rx_bytes; + uint32_t rx_icv_err; + uint32_t rx_largepacket_crcerr; + uint32_t rx_smallpacket_crcerr; + uint32_t rx_middlepacket_crcerr; + uint8_t *pallocated_recv_buf; + uint8_t *precv_buf; + _queue free_recv_buf_queue; + uint32_t free_recv_buf_queue_cnt; + struct rtw_rx_ring rx_ring[1]; + int rxringcount; + uint16_t rxbuffersize; + uint8_t is_signal_dbg; + uint8_t signal_strength_dbg; + int8_t rssi; // +2932 + int8_t rxpwdb; + uint8_t signal_strength; + uint8_t signal_qual; + uint8_t noise; + int RxSNRdB[2]; + int8_t RxRssi[2]; + int FalseAlmCnt_all; + _timer signal_stat_timer; + uint32_t signal_stat_sampling_interval; + struct signal_stat signal_qual_data; + struct signal_stat signal_strength_data; + uint8_t promisc_enabled; + uint8_t promisc_len_used; + _list promisc_list; + _lock promisc_lock; + uint32_t promisc_bk_rcr; + uint16_t promisc_bk_rxfltmap2; + uint8_t promisc_mgntframe_enabled; +}; + +struct _atr_aligned4_ sta_priv { + uint8_t *pallocated_stainfo_buf; + uint32_t allocated_stainfo_size; + uint8_t *pstainfo_buf; + _queue free_sta_queue; + _lock sta_hash_lock; + _list sta_hash[5]; + int asoc_sta_count; + _queue sleep_q; + _queue wakeup_q; + _adapter *padapter; + _list asoc_list; + _list auth_list; + _lock asoc_list_lock; + _lock auth_list_lock; + uint32_t auth_to; + uint32_t assoc_to; + uint32_t expire_to; + struct sta_info *sta_aid[5]; + uint16_t sta_dz_bitmap; + uint16_t tim_bitmap; + uint16_t max_num_sta; +}; + +union Keytype { + uint8_t skey[16]; + uint32_t lkey[4]; +}; + + + +union pn48 { + u8Byte val; + struct { + uint8_t TSC0; + uint8_t TSC1; + uint8_t TSC2; + uint8_t TSC3; + uint8_t TSC4; + uint8_t TSC5; + uint8_t TSC6; + uint8_t TSC7; + }_byte_; +}; + +struct _NDIS_802_11_WEP { + uint32_t Length; + uint32_t KeyIndex; + uint32_t KeyLength; + uint8_t KeyMaterial[16]; +}; +typedef struct _NDIS_802_11_WEP NDIS_802_11_WEP; + +struct $D75518714447A990003EBC933C23F70E { + uint32_t HighPart; + uint32_t LowPart; +}; + +union _LARGE_INTEGER { + uint8_t charData[8]; + struct $D75518714447A990003EBC933C23F70E field; +}; +typedef union _LARGE_INTEGER LARGE_INTEGER; + +struct $121C25F90E4E195D1524BBC5399ADEBE { + LARGE_INTEGER HighPart; + LARGE_INTEGER LowPart; +}; + +union _OCTET16_INTEGER { + uint8_t charData[16]; + struct $121C25F90E4E195D1524BBC5399ADEBE field; +}; +typedef union _OCTET16_INTEGER OCTET16_INTEGER; + +struct $BB6DA6E37D48DEE353E02A8C8F92DDF7 { + OCTET16_INTEGER HighPart; + OCTET16_INTEGER LowPart; +}; + +union _OCTET32_INTEGER { + uint8_t charData[32]; + struct $BB6DA6E37D48DEE353E02A8C8F92DDF7 field; +}; +typedef union _OCTET32_INTEGER OCTET32_INTEGER; + +struct _OCTET_STRING { + uint8_t *Octet; + int Length; +}; +typedef struct _OCTET_STRING OCTET_STRING; + +struct _wpa_global_info { + OCTET32_INTEGER Counter; + int GTKAuthenticator; + int GKeyDoneStations; + int GInitAKeys; + int GUpdateStationKeys; + int GkeyReady; + OCTET_STRING AuthInfoElement; + uint8_t AuthInfoBuf[128]; + uint8_t MulticastCipher; + OCTET_STRING GNonce; + uint8_t GNonceBuf[32]; + uint8_t GTK[4][32]; + uint8_t GMK[32]; + int GN; + int GM; + int GTKRekey; +}; +typedef struct _wpa_global_info WPA_GLOBAL_INFO; + +typedef struct _wpa_sta_info WPA_STA_INFO; + +struct _atr_aligned4_ security_priv { + uint32_t dot11AuthAlgrthm; + uint32_t dot11PrivacyAlgrthm; + uint32_t dot11PrivacyKeyIndex; + union Keytype dot11DefKey[4]; + uint32_t dot11DefKeylen[4]; + uint32_t dot118021XGrpPrivacy; + uint32_t dot118021XGrpKeyid; + union Keytype dot118021XGrpKey[4]; + union Keytype dot118021XGrptxmickey[4]; + union Keytype dot118021XGrprxmickey[4]; + union pn48 dot11Grptxpn; + union pn48 dot11Grprxpn; + uint32_t dot8021xalg; + uint32_t wpa_psk; + uint32_t wpa_group_cipher; + uint32_t wpa2_group_cipher; + uint32_t wpa_pairwise_cipher; + uint32_t wpa2_pairwise_cipher; + uint8_t wps_ie[512]; + int wps_ie_len; + uint8_t binstallGrpkey; + uint8_t busetkipkey; + uint8_t bcheck_grpkey; + uint8_t bgrpkey_handshake; + int32_t sw_encrypt; + int32_t sw_decrypt; + int32_t hw_decrypted; + uint32_t ndisauthtype; + uint32_t ndisencryptstatus; + NDIS_802_11_WEP ndiswep; + uint8_t supplicant_ie[256]; + uint32_t last_mic_err_time; + uint8_t btkip_countermeasure; + uint8_t btkip_wait_report; + uint32_t btkip_countermeasure_time; + WPA_GLOBAL_INFO wpa_global_info; + uint8_t *palloc_wpastainfo_buf; + uint32_t alloc_wpastainfo_size; + WPA_STA_INFO *wpa_sta_info[3]; + uint8_t wpa_passphrase[65]; + uint8_t wps_phase; +}; + +struct _atr_aligned4_ registry_priv { + uint8_t chip_version; + uint8_t hci; + NDIS_802_11_SSID ssid; + uint8_t channel; + uint8_t wireless_mode; + uint8_t scan_mode; + uint8_t vrtl_carrier_sense; + uint8_t vcs_type; + uint16_t rts_thresh; + uint8_t soft_ap; + uint8_t power_mgnt; + uint8_t ps_enable; + uint8_t ips_mode; + uint8_t smart_ps; + uint8_t mp_mode; + uint8_t software_encrypt; + uint8_t software_decrypt; + uint8_t acm_method; + uint8_t wmm_enable; + uint8_t uapsd_enable; + uint32_t beacon_period; + uint8_t ht_enable; + uint8_t ampdu_enable; + uint8_t rx_stbc; + uint8_t ampdu_amsdu; + uint8_t rf_config; + uint8_t power_percentage_idx; + uint8_t wifi_spec; + uint8_t channel_plan; + uint8_t ifname[16]; + uint8_t if2name[16]; + uint8_t RegEnableTxPowerLimit; + uint8_t RegEnableTxPowerByRate; + uint8_t RegEnableKFree; + uint8_t RegPowerBase; + uint8_t RegPwrTblSel; + uint8_t adaptivity_en; + uint8_t adaptivity_mode; + uint8_t adaptivity_dml; + uint8_t adaptivity_dc_backoff; + int8_t adaptivity_th_l2h_ini; +}; + +typedef void *_sema; + +typedef _sema _pwrlock; + +enum _rt_rf_power_state //: sint32_t +{ + rf_on = 0x0, rf_sleep = 0x1, rf_off = 0x2, rf_max = 0x3, +}; +typedef enum _rt_rf_power_state rt_rf_power_state; + +struct _atr_aligned4_ pwrctrl_priv { + _pwrlock lock; + volatile uint8_t rpwm; + volatile uint8_t cpwm; + volatile uint8_t tog; + volatile uint8_t cpwm_tog; + uint8_t pwr_mode; + uint8_t smart_ps; + uint8_t bcn_ant_mode; + uint32_t alives; + u8Byte wowlan_fw_iv; + uint8_t bpower_saving; + uint8_t b_hw_radio_off; + uint8_t reg_rfoff; + uint8_t reg_pdnmode; + uint32_t rfoff_reason; + uint32_t cur_ps_level; + uint32_t reg_rfps_level; + uint8_t b_support_aspm; + uint8_t b_support_backdoor; + uint8_t const_amdpci_aspm; + uint32_t ips_enter_cnts; + uint32_t ips_leave_cnts; + uint8_t ps_enable; + uint8_t ips_mode; + uint8_t ips_org_mode; + uint8_t ips_mode_req; + uint32_t bips_processing; + uint32_t ips_deny_time; + uint8_t ps_processing; + uint8_t bLeisurePs; + uint8_t LpsIdleCount; + uint8_t power_mgnt; + uint8_t org_power_mgnt; + uint8_t bFwCurrentInPSMode; + uint32_t DelayLPSLastTimeStamp; + uint8_t btcoex_rfon; + int32_t pnp_current_pwr_state; + uint8_t pnp_bstop_trx; + uint8_t bInternalAutoSuspend; + uint8_t bInSuspend; + uint8_t bSupportRemoteWakeup; + _timer pwr_state_check_timer; + int pwr_state_check_interval; + uint8_t pwr_state_check_cnts; + int ps_flag; + rt_rf_power_state rf_pwrstate; + rt_rf_power_state change_rfpwrstate; + uint8_t wepkeymask; + uint8_t bHWPowerdown; + uint8_t bHWPwrPindetect; + uint8_t bkeepfwalive; + uint8_t brfoffbyhw; + uint32_t PS_BBRegBackup[4]; + uint8_t tdma_slot_period; + uint8_t tdma_rfon_period_len_1; + uint8_t tdma_rfon_period_len_2; + uint8_t tdma_rfon_period_len_3; + uint8_t lps_dtim; +}; + +struct _atr_aligned2_ eeprom_priv { // __attribute__((packed))!? + uint8_t bautoload_fail_flag; + uint8_t mac_addr[6]; + uint16_t CustomerID; + uint8_t EepromOrEfuse; + uint8_t efuse_eeprom_data[512]; + uint8_t EEPROMRFGainOffset; + uint8_t EEPROMRFGainVal; +}; + +enum _CHANNEL_WIDTH // : sint32_t +{ + CHANNEL_WIDTH_20 = 0x0, + CHANNEL_WIDTH_40 = 0x1, + CHANNEL_WIDTH_80 = 0x2, + CHANNEL_WIDTH_160 = 0x3, + CHANNEL_WIDTH_80_80 = 0x4, + CHANNEL_WIDTH_MAX = 0x5, +}; +typedef enum _CHANNEL_WIDTH CHANNEL_WIDTH; + +enum _HAL_DEF_VARIABLE // : sint32_t +{ + HAL_DEF_UNDERCORATEDSMOOTHEDPWDB = 0x0, + HAL_DEF_IS_SUPPORT_ANT_DIV = 0x1, + HAL_DEF_CURRENT_ANTENNA = 0x2, + HAL_DEF_DRVINFO_SZ = 0x3, + HAL_DEF_MAX_RECVBUF_SZ = 0x4, + HAL_DEF_RX_PACKET_OFFSET = 0x5, + HAL_DEF_RX_DMA_SZ_WOW = 0x6, + HAL_DEF_RX_DMA_SZ = 0x7, + HAL_DEF_RX_PAGE_SIZE = 0x8, + HAL_DEF_DBG_DM_FUNC = 0x9, + HAL_DEF_RA_DECISION_RATE = 0xA, + HAL_DEF_RA_SGI = 0xB, + HAL_DEF_PT_PWR_STATUS = 0xC, + HW_VAR_MAX_RX_AMPDU_FACTOR = 0xD, + HW_DEF_RA_INFO_DUMP = 0xE, + HAL_DEF_DBG_DUMP_TXPKT = 0xF, + HW_DEF_ODM_DBG_FLAG = 0x10, + HW_DEF_ODM_DBG_LEVEL = 0x11, + HAL_DEF_TX_PAGE_SIZE = 0x12, + HAL_DEF_TX_PAGE_BOUNDARY = 0x13, + HAL_DEF_MACID_SLEEP = 0x14, + HAL_DEF_DBG_RX_INFO_DUMP = 0x15, +}; +typedef enum _HAL_DEF_VARIABLE HAL_DEF_VARIABLE; + +enum _HAL_ODM_VARIABLE // : sint32_t +{ + HAL_ODM_STA_INFO = 0x0, + HAL_ODM_DBG_FLAG = 0x1, + HAL_ODM_RX_INFO_DUMP = 0x2, + HAL_ODM_NOISE_MONITOR = 0x3, + HAL_ODM_REGULATION = 0x4, +}; +typedef enum _HAL_ODM_VARIABLE HAL_ODM_VARIABLE; + +typedef void *_thread_hdl_; + +/* + // osdep_service.h + struct task_struct + { + const char *task_name; + _thread_hdl_ task; + _sema wakeup_sema; + _sema terminate_sema; + uint32_t blocked; + uint32_t callback_running; + }; + */ + +typedef struct net_device *_nic_hdl; +/* + // wrapper.h + struct net_device_stats + { + uint32_t rx_packets; + uint32_t tx_packets; + uint32_t rx_dropped; + uint32_t tx_dropped; + uint32_t rx_bytes; + uint32_t tx_bytes; + uint32_t rx_overflow; + }; + */ + +struct dvobj_priv { + void *if1; + void *if2; + void *padapters[2]; + uint8_t iface_nums; + uint8_t RtOutPipe[3]; + uint8_t Queue2Pipe[8]; + uint8_t irq_alloc; + uint8_t irq_enabled; + _lock irq_th_lock; +}; + +struct phy_info { + uint8_t RxPWDBAll; + uint8_t SignalQuality; + uint8_t RxMIMOSignalStrength[1]; + int8_t RecvSignalPower; + uint8_t SignalStrength; +}; + +struct _atr_aligned4_ rx_pkt_attrib { + uint16_t pkt_len; + uint8_t physt; + uint8_t drvinfo_sz; + uint8_t shift_sz; + uint8_t hdrlen; + uint8_t to_fr_ds; + uint8_t amsdu; + uint8_t qos; + uint8_t priority; + uint8_t pw_save; + uint8_t mdata; + uint16_t seq_num; + uint8_t frag_num; + uint8_t mfrag; + uint8_t order; + uint8_t privacy; + uint8_t bdecrypted; + uint8_t encrypt; + uint8_t iv_len; + uint8_t icv_len; + uint8_t crc_err; + uint8_t icv_err; + uint16_t eth_type; + uint8_t dst[6]; + uint8_t src[6]; + uint8_t ta[6]; + uint8_t ra[6]; + uint8_t bssid[6]; + uint8_t ack_policy; + uint8_t tcpchk_valid; + uint8_t ip_chkrpt; + uint8_t tcp_chkrpt; + uint8_t key_index; + uint8_t mcs_rate; + uint8_t rxht; + uint8_t sgi; + uint8_t pkt_rpt_type; + uint32_t MacIDValidEntry[2]; + uint8_t data_rate; + struct phy_info phy_info; +}; + +struct recv_frame_hdr { + _list list; + struct sk_buff *pkt; + struct sk_buff *pkt_newalloc; + _adapter *adapter; + uint8_t fragcnt; + int frame_tag; + struct rx_pkt_attrib attrib; + uint32_t len; + uint8_t *rx_head; + uint8_t *rx_data; + uint8_t *rx_tail; + uint8_t *rx_end; + void *precvbuf; + struct sta_info *psta; +}; + +struct recv_frame { +union { + _list list; + struct recv_frame_hdr hdr; + uint32_t mem[32]; + }; +}; +/* +union $AB04817EA6EB89125E28056B7464A4D7 { + _list list; + struct recv_frame_hdr hdr; + uint32_t mem[32]; +}; + +union recv_frame { + union $AB04817EA6EB89125E28056B7464A4D7 u; +}; +*/ +/* + // skbuff.h + struct sk_buff + { + struct sk_buff *next; + struct sk_buff *prev; + struct sk_buff_head *list; + uint8_t *head; + uint8_t *data; + uint8_t *tail; + uint8_t *end; + void *dev; + uint32_t len; + }; + + struct sk_buff_head + { + struct list_head *next; + struct list_head *prev; + uint32_t qlen; + }; + */ + +struct tx_servq { + _list tx_pending; + _queue sta_pending; + int qcnt; +}; + +struct sta_xmit_priv { + _lock lock; + sint option; + sint apsd_setting; + struct tx_servq be_q; + struct tx_servq bk_q; + struct tx_servq vi_q; + struct tx_servq vo_q; + _list legacy_dz; + _list apsd; + uint16_t txseq_tid[16]; +}; + +struct stainfo_rxcache { + uint16_t tid_rxseq[16]; +}; + +struct sta_recv_priv { + _lock lock; + sint option; + _queue defrag_q; + struct stainfo_rxcache rxcache; +}; + +struct stainfo_stats { + u8Byte rx_mgnt_pkts; + u8Byte rx_ctrl_pkts; + u8Byte rx_data_pkts; + u8Byte last_rx_mgnt_pkts; + u8Byte last_rx_ctrl_pkts; + u8Byte last_rx_data_pkts; + u8Byte rx_bytes; + u8Byte tx_pkts; + u8Byte tx_bytes; +}; + +struct _RSSI_STA { + int32_t UndecoratedSmoothedPWDB; + int32_t UndecoratedSmoothedCCK; + int32_t UndecoratedSmoothedOFDM; + u8Byte PacketMap; + uint8_t ValidBit; + uint32_t OFDM_pkt; +}; +typedef struct _RSSI_STA RSSI_STA; + +struct sta_info { + _lock lock; + _list list; + _list hash_list; + _adapter *padapter; + struct sta_xmit_priv sta_xmitpriv; + struct sta_recv_priv sta_recvpriv; + _queue sleep_q; + uint32_t sleepq_len; + uint32_t state; + uint32_t aid; + uint32_t mac_id; + uint32_t qos_option; + uint8_t hwaddr[6]; + uint32_t ieee8021x_blocked; + uint32_t dot118021XPrivacy; + union Keytype dot11tkiptxmickey; + union Keytype dot11tkiprxmickey; + union Keytype dot118021x_UncstKey; + union pn48 dot11txpn; + union pn48 dot11rxpn; + uint8_t bssrateset[16]; + uint32_t bssratelen; + int32_t rssi; + int32_t signal_quality; + uint8_t cts2self; + uint8_t rtsen; + uint8_t raid; + uint8_t init_rate; + uint32_t ra_mask; + uint8_t wireless_mode; + struct stainfo_stats sta_stats; + _timer addba_retry_timer; + uint16_t BA_starting_seqctrl[16]; + struct ht_priv htpriv; + _list asoc_list; + _list auth_list; + uint32_t expire_to; + uint32_t auth_seq; + uint32_t authalg; + uint8_t chg_txt[128]; + uint16_t capability; + uint32_t flags; + int dot8021xalg; + int wpa_psk; + int wpa_group_cipher; + int wpa2_group_cipher; + int wpa_pairwise_cipher; + int wpa2_pairwise_cipher; + uint8_t bpairwise_key_installed; + uint8_t wpa_ie[32]; + uint8_t nonerp_set; + uint8_t no_short_slot_time_set; + uint8_t no_short_preamble_set; + uint8_t no_ht_gf_set; + uint8_t no_ht_set; + uint8_t ht_20mhz_set; + uint32_t tx_ra_bitmap; + uint8_t qos_info; + uint8_t max_sp_len; + uint8_t uapsd_bk; + uint8_t uapsd_be; + uint8_t uapsd_vi; + uint8_t uapsd_vo; + uint8_t has_legacy_ac; + uint32_t sleepq_ac_len; + RSSI_STA rssi_stat; + uint8_t bValid; + uint8_t IOTPeer; + uint8_t rssi_level; + uint8_t RSSI_Path[4]; + uint8_t RSSI_Ave; + uint8_t RXEVM[4]; + uint8_t RXSNR[4]; +}; +/* + // wifi_conf.h + struct _atr_aligned4_ _cus_ie + { + uint8_t *ie; + uint8_t type; + }; + */ + +struct fifo_more_data { + uint32_t more_data; + uint32_t len; +}; + +struct hw_xmit { + _queue *sta_queue; + int accnt; +}; + +struct tx_buf_desc { + uint32_t txdw0; + uint32_t txdw1; + uint32_t txdw2; + uint32_t txdw3; + uint32_t txdw4; + uint32_t txdw5; + uint32_t txdw6; + uint32_t txdw7; +}; + +struct recv_buf_stat { + uint32_t rxdw0; + uint32_t rxdw1; +}; + +struct _wpa_sta_info { + int state; + int gstate; + int RSNEnabled; + int PInitAKeys; + uint8_t UnicastCipher; + LARGE_INTEGER CurrentReplayCounter; + LARGE_INTEGER ReplayCounterStarted; + OCTET_STRING ANonce; + OCTET_STRING SNonce; + uint8_t AnonceBuf[32]; + uint8_t SnonceBuf[32]; + uint8_t PMK[32]; + uint8_t PTK[64]; + OCTET_STRING EAPOLMsgRecvd; + OCTET_STRING EAPOLMsgSend; + OCTET_STRING EapolKeyMsgRecvd; + OCTET_STRING EapolKeyMsgSend; + uint8_t eapSendBuf[512]; + struct timer_list resendTimer; + int resendCnt; + int clientHndshkProcessing; + int clientHndshkDone; + int clientGkeyUpdate; + LARGE_INTEGER clientMICReportReplayCounter; +}; + +struct pkt_attrib { + uint8_t type; + uint8_t subtype; + uint8_t bswenc; + uint8_t dhcp_pkt; + uint16_t ether_type; + uint16_t seqnum; + uint16_t pkt_hdrlen; + uint16_t hdrlen; + uint32_t pktlen; + uint32_t last_txcmdsz; + uint8_t encrypt; + uint8_t iv_len; + uint8_t icv_len; + uint8_t iv[18]; + uint8_t icv[16]; + uint8_t priority; + uint8_t ack_policy; + uint8_t mac_id; + uint8_t vcs_mode; + uint8_t dst[6]; + uint8_t src[6]; + uint8_t ta[6]; + uint8_t ra[6]; + uint8_t key_idx; + uint8_t qos_en; + uint8_t ht_en; + uint8_t raid; + uint8_t bwmode; + uint8_t ch_offset; + uint8_t sgi; + uint8_t ampdu_en; + uint8_t mdata; + uint8_t pctrl; + uint8_t triggered; + uint8_t qsel; + uint8_t eosp; + uint8_t rate; + uint8_t intel_proxim; + uint8_t retry_ctrl; + struct sta_info *psta; +}; + +typedef struct sk_buff _pkt; + +struct _XIMT_BUF_ { + uint32_t AllocatBufAddr; + uint32_t BufAddr; + uint32_t BufLen; +}; +typedef struct _XIMT_BUF_ XIMT_BUF; + +struct _atr_aligned4_ xmit_frame { + _list list; + struct pkt_attrib attrib; + _pkt *pkt; + int frame_tag; + _adapter *padapter; + uint8_t *buf_addr; + struct xmit_buf *pxmitbuf; + uint32_t TxDexAddr; + uint32_t HdrLen; + uint32_t PayLoadAddr; + uint32_t PayLoadLen; + uint32_t TotalLen; + uint32_t BlockNum; + XIMT_BUF BufInfo[4]; + BOOLEAN NoCoalesce; +}; + +struct xmit_buf { + _list list; + _adapter *padapter; + _pkt *pkt; + uint8_t *pbuf; + void *priv_data; + uint16_t buf_tag; + uint16_t flags; + uint32_t alloc_sz; + uint32_t len; + struct submit_ctx *sctx; + XIMT_BUF BufInfo[4]; + uint32_t BlockNum; +}; + +struct submit_ctx { + uint32_t submit_time; + uint32_t timeout_ms; + int status; +}; +/* + // wrapper.h + struct net_device + { + char name[16]; + void *priv; + uint8_t dev_addr[6]; + int (*init)(void); + int (*open)(struct net_device *); + int (*stop)(struct net_device *); + int (*hard_start_xmit)(struct sk_buff *, struct net_device *); + int (*do_ioctl)(struct net_device *, struct iwreq *, int); + struct net_device_stats *(*get_stats)(struct net_device *); + }; + */ +/* + // wireless.h + struct iw_point + { + void *pointer; + uint16_t length; + uint16_t flags; + }; + + struct iw_param + { + sint32_t value; + uint8_t fixed; + uint8_t disabled; + uint16_t flags; + }; + + + struct iw_freq + { + sint32_t m; + sint16_t e; + uint8_t i; + uint8_t flags; + }; + + struct iw_quality + { + uint8_t qual; + uint8_t level; + uint8_t noise; + uint8_t updated; + }; + + struct sockaddr_t + { + uint8_t sa_len; + uint8_t sa_family; + char sa_data[14]; + }; + + union iwreq_data + { + char name[16]; + struct iw_point essid; + struct iw_param nwid; + struct iw_freq freq; + struct iw_param sens; + struct iw_param bitrate; + struct iw_param txpower; + struct iw_param rts; + struct iw_param frag; + uint32_t mode; + struct iw_param retry; + struct iw_point encoding; + struct iw_param power; + struct iw_quality qual; + struct sockaddr_t ap_addr; + struct sockaddr_t addr; + struct iw_param param; + struct iw_point data; + struct iw_point passphrase; + }; + + struct iwreq + { + char ifr_name[16]; + union iwreq_data u; + }; + */ +struct co_data_priv { + uint8_t co_ch; + uint8_t co_bw; + uint8_t co_ch_offset; + uint8_t rsvd; +}; + +enum _HARDWARE_TYPE // : sint32_t +{ + HARDWARE_TYPE_RTL8180 = 0x0, + HARDWARE_TYPE_RTL8185 = 0x1, + HARDWARE_TYPE_RTL8187 = 0x2, + HARDWARE_TYPE_RTL8188 = 0x3, + HARDWARE_TYPE_RTL8190P = 0x4, + HARDWARE_TYPE_RTL8192E = 0x5, + HARDWARE_TYPE_RTL819xU = 0x6, + HARDWARE_TYPE_RTL8192SE = 0x7, + HARDWARE_TYPE_RTL8192SU = 0x8, + HARDWARE_TYPE_RTL8192CE = 0x9, + HARDWARE_TYPE_RTL8192CU = 0xA, + HARDWARE_TYPE_RTL8192DE = 0xB, + HARDWARE_TYPE_RTL8192DU = 0xC, + HARDWARE_TYPE_RTL8723AE = 0xD, + HARDWARE_TYPE_RTL8723AU = 0xE, + HARDWARE_TYPE_RTL8723AS = 0xF, + HARDWARE_TYPE_RTL8188EE = 0x10, + HARDWARE_TYPE_RTL8188EU = 0x11, + HARDWARE_TYPE_RTL8188ES = 0x12, + HARDWARE_TYPE_RTL8192EE = 0x13, + HARDWARE_TYPE_RTL8192EU = 0x14, + HARDWARE_TYPE_RTL8192ES = 0x15, + HARDWARE_TYPE_RTL8812E = 0x16, + HARDWARE_TYPE_RTL8812AU = 0x17, + HARDWARE_TYPE_RTL8811AU = 0x18, + HARDWARE_TYPE_RTL8821E = 0x19, + HARDWARE_TYPE_RTL8821U = 0x1A, + HARDWARE_TYPE_RTL8821S = 0x1B, + HARDWARE_TYPE_RTL8723BE = 0x1C, + HARDWARE_TYPE_RTL8723BU = 0x1D, + HARDWARE_TYPE_RTL8723BS = 0x1E, + HARDWARE_TYPE_RTL8195A = 0x1F, + HARDWARE_TYPE_RTL8711B = 0x20, + HARDWARE_TYPE_RTL8188FE = 0x21, + HARDWARE_TYPE_RTL8188FU = 0x22, + HARDWARE_TYPE_RTL8188FS = 0x23, + HARDWARE_TYPE_MAX = 0x24, +}; + +struct RF_Shadow_Compare_Map { + uint32_t Value; + uint8_t Compare; + uint8_t ErrorOrNot; + uint8_t Recorver; + uint8_t Driver_Write; +}; +typedef struct RF_Shadow_Compare_Map RF_SHADOW_T; + +enum _PS_BBRegBackup_ // : sint32_t +{ + PSBBREG_RF0 = 0x0, + PSBBREG_RF1 = 0x1, + PSBBREG_RF2 = 0x2, + PSBBREG_AFE0 = 0x3, + PSBBREG_TOTALCNT = 0x4, +}; + +/* + // hal_irqn.h + enum _IRQn_Type_ // : sint32_t + { + NonMaskableInt_IRQn = 0xFFFFFFF2, + HardFault_IRQn = 0xFFFFFFF3, + MemoryManagement_IRQn = 0xFFFFFFF4, + BusFault_IRQn = 0xFFFFFFF5, + UsageFault_IRQn = 0xFFFFFFF6, + SVCall_IRQn = 0xFFFFFFFB, + DebugMonitor_IRQn = 0xFFFFFFFC, + PendSV_IRQn = 0xFFFFFFFE, + SysTick_IRQn = 0xFFFFFFFF, + SYSTEM_ON_IRQ = 0x0, + WDG_IRQ = 0x1, + TIMER0_IRQ = 0x2, + TIMER1_IRQ = 0x3, + I2C3_IRQ = 0x4, + TIMER2_7_IRQ = 0x5, + SPI0_IRQ = 0x6, + GPIO_IRQ = 0x7, + UART0_IRQ = 0x8, + SPI_FLASH_IRQ = 0x9, + USB_OTG_IRQ = 0xA, + SDIO_HOST_IRQ = 0xB, + SDIO_DEVICE_IRQ = 0xC, + I2S0_PCM0_IRQ = 0xD, + I2S1_PCM1_IRQ = 0xE, + WL_DMA_IRQ = 0xF, + WL_PROTOCOL_IRQ = 0x10, + CRYPTO_IRQ = 0x11, + GMAC_IRQ = 0x12, + PERIPHERAL_IRQ = 0x13, + GDMA0_CHANNEL0_IRQ = 0x14, + GDMA0_CHANNEL1_IRQ = 0x15, + GDMA0_CHANNEL2_IRQ = 0x16, + GDMA0_CHANNEL3_IRQ = 0x17, + GDMA0_CHANNEL4_IRQ = 0x18, + GDMA0_CHANNEL5_IRQ = 0x19, + GDMA1_CHANNEL0_IRQ = 0x1A, + GDMA1_CHANNEL1_IRQ = 0x1B, + GDMA1_CHANNEL2_IRQ = 0x1C, + GDMA1_CHANNEL3_IRQ = 0x1D, + GDMA1_CHANNEL4_IRQ = 0x1E, + GDMA1_CHANNEL5_IRQ = 0x1F, + I2C0_IRQ = 0x40, + I2C1_IRQ = 0x41, + I2C2_IRQ = 0x42, + SPI1_IRQ = 0x48, + SPI2_IRQ = 0x49, + UART1_IRQ = 0x50, + UART2_IRQ = 0x51, + UART_LOG_IRQ = 0x58, + ADC_IRQ = 0x59, + DAC0_IRQ = 0x5B, + DAC1_IRQ = 0x5C, + LP_EXTENSION_IRQ = 0x5D, + PTA_TRX_IRQ = 0x5F, + RXI300_IRQ = 0x60, + NFC_IRQ = 0x61, + }; + + typedef enum _IRQn_Type_ IRQn_Type; + + typedef void (*IRQ_FUN)(void *); + + struct _IRQ_HANDLE_ + { + IRQ_FUN IrqFun; + IRQn_Type IrqNum; + uint32_t Data; + uint32_t Priority; + }; + typedef struct _IRQ_HANDLE_ IRQ_HANDLE; + */ +/* + // hal_soc_ps_monitor.h + struct _power_state_ + { + uint8_t FuncIdx; + uint8_t PowerState; + }; + + typedef struct _power_state_ POWER_STATE; + + struct _atr_aligned4_ _power_mgn_ + { + uint8_t ActFuncCount; + POWER_STATE PwrState[10]; + uint8_t CurrentState; + uint8_t SDREn; + uint32_t MSPbackup[129]; + uint32_t CPURegbackup[25]; + uint32_t CPUPSP; + uint32_t WakeEventFlag; + BOOL SleepFlag; + }; + typedef struct _power_mgn_ Power_Mgn; + + /* + // hal_gpio.h + enum $E1AD70AB12E7AA6E98B8D89D9B965EB5 //: sint32_t + { + _PORT_A = 0x0, + _PORT_B = 0x1, + _PORT_C = 0x2, + _PORT_D = 0x3, + _PORT_E = 0x4, + _PORT_F = 0x5, + _PORT_G = 0x6, + _PORT_H = 0x7, + _PORT_I = 0x8, + _PORT_J = 0x9, + _PORT_K = 0xA, + _PORT_MAX = 0xB, + }; + + typedef void (*GPIO_IRQ_FUN)(void *, uint32_t); + + typedef void (*GPIO_USER_IRQ_FUN)(uint32_t); + + struct _atr_aligned4_ _HAL_GPIO_ADAPTER_ + { + IRQ_HANDLE IrqHandle; + GPIO_USER_IRQ_FUN UserIrqHandler; + GPIO_IRQ_FUN PortA_IrqHandler[32]; + void *PortA_IrqData[32]; + void (*EnterCritical)(void); + void (*ExitCritical)(void); + uint32_t Local_Gpio_Dir[3]; + uint8_t Gpio_Func_En; + uint8_t Locked; + }; + typedef struct _HAL_GPIO_ADAPTER_ *PHAL_GPIO_ADAPTER; + */ + +struct hal_ops { + uint32_t (*hal_power_on)(_adapter *); + uint32_t (*hal_init)(_adapter *); + uint32_t (*hal_deinit)(_adapter *); + void (*free_hal_data)(_adapter *); + uint32_t (*inirp_init)(_adapter *); + uint32_t (*inirp_deinit)(_adapter *); + void (*irp_reset)(_adapter *); + int32_t (*init_xmit_priv)(_adapter *); + void (*free_xmit_priv)(_adapter *); + int32_t (*init_recv_priv)(_adapter *); + void (*free_recv_priv)(_adapter *); + void (*update_txdesc)(struct xmit_frame *, uint8_t *); + void (*InitSwLeds)(_adapter *); + void (*DeInitSwLeds)(_adapter *); + void (*dm_init)(_adapter *); + void (*dm_deinit)(_adapter *); + void (*read_chip_version)(_adapter *); + void (*init_default_value)(_adapter *); + void (*intf_chip_configure)(_adapter *); + void (*read_adapter_info)(_adapter *); + void (*enable_interrupt)(_adapter *); + void (*disable_interrupt)(_adapter *); + int32_t (*interrupt_handler)(_adapter *); + void (*set_bwmode_handler)(_adapter *, CHANNEL_WIDTH, uint8_t); + void (*set_channel_handler)(_adapter *, uint8_t); + void (*set_chnl_bw_handler)(_adapter *, uint8_t, CHANNEL_WIDTH, uint8_t, + uint8_t); + void (*hal_dm_watchdog)(_adapter *); + void (*SetHwRegHandler)(_adapter *, uint8_t, uint8_t *); + void (*GetHwRegHandler)(_adapter *, uint8_t, uint8_t *); + uint8_t (*GetHalDefVarHandler)(_adapter *, HAL_DEF_VARIABLE, PVOID); + uint8_t (*SetHalDefVarHandler)(_adapter *, HAL_DEF_VARIABLE, PVOID); + void (*GetHalODMVarHandler)(_adapter *, HAL_ODM_VARIABLE, PVOID, BOOLEAN); + void (*SetHalODMVarHandler)(_adapter *, HAL_ODM_VARIABLE, PVOID, BOOLEAN); + void (*UpdateRAMaskHandler)(_adapter *, uint32_t, uint8_t); + void (*Add_RateATid)(_adapter *, uint32_t, uint8_t *, uint8_t); + void (*clone_haldata)(_adapter *, _adapter *); + void (*run_thread)(_adapter *); + void (*cancel_thread)(_adapter *); + int32_t (*hal_xmit)(_adapter *, struct xmit_frame *); + int32_t (*mgnt_xmit)(_adapter *, struct xmit_frame *); + uint32_t (*read_bbreg)(_adapter *, uint32_t, uint32_t); + void (*write_bbreg)(_adapter *, uint32_t, uint32_t, uint32_t); + uint32_t (*read_rfreg)(_adapter *, uint32_t, uint32_t, uint32_t); + void (*write_rfreg)(_adapter *, uint32_t, uint32_t, uint32_t, uint32_t); + void (*EfusePowerSwitch)(_adapter *, uint8_t, uint8_t); + void (*ReadEFuse)(_adapter *, uint8_t, uint16_t, uint16_t, uint8_t *, + BOOLEAN); + void (*EFUSEGetEfuseDefinition)(_adapter *, uint8_t, uint8_t, void *, + BOOLEAN); + uint16_t (*EfuseGetCurrentSize)(_adapter *, uint8_t, BOOLEAN); + int (*Efuse_PgPacketWrite)(_adapter *, uint8_t, uint8_t, uint8_t *, + BOOLEAN); + uint8_t (*Efuse_WordEnableDataWrite)(_adapter *, uint16_t, uint8_t, + uint8_t *, BOOLEAN); + void (*recv_tasklet)(void *); + int32_t (*fill_h2c_cmd)(_adapter *, uint8_t, uint32_t, uint8_t *); + void (*fill_fake_txdesc)(_adapter *, uint8_t *, uint32_t, uint8_t, uint8_t, + uint8_t); + uint8_t (*hal_get_tx_buff_rsvd_page_num)(_adapter *, bool); +}; + +struct _atr_aligned4_ _ADAPTER { + uint16_t HardwareType; + uint16_t interface_type; //+2 + uint32_t work_mode; //+4 + struct dvobj_priv *dvobj; //+8 + struct mlme_priv mlmepriv; //+12 [1244] + struct mlme_ext_priv mlmeextpriv; //+1256 [912] + struct cmd_priv cmdpriv; //+2168 + struct evt_priv evtpriv; //+ + struct io_priv iopriv; + struct xmit_priv xmitpriv; //+2248 + struct recv_priv recvpriv; //+2752 + struct sta_priv stapriv; //+3024 [164] + struct security_priv securitypriv; + struct registry_priv registrypriv; + struct pwrctrl_priv pwrctrlpriv; // pwrctrlpriv.bInternalAutoSuspend //+5061 + struct eeprom_priv eeprompriv; + PVOID HalData; + uint32_t hal_data_sz; + struct hal_ops HalFunc; + int32_t bDriverStopped; //+5880 + int32_t bSurpriseRemoved; //+5884 + int32_t bCardDisableWOHSM; //+5888 + uint8_t RxStop; //+5892 + uint32_t IsrContent; + uint32_t ImrContent; + uint8_t EepromAddressSize; + uint8_t hw_init_completed; //+5905 + uint8_t bDriverIsGoingToUnload; + uint8_t init_adpt_in_progress; + uint8_t bMpDriver; + uint8_t bForwardingDisabled; + struct task_struct isrThread; //+5888 + struct task_struct cmdThread; //+5920 + struct task_struct recvtasklet_thread; //+5952 + struct task_struct xmittasklet_thread; //+5984 + void (*intf_start)(_adapter *); //+6008 + void (*intf_stop)(_adapter *); //+6012 + _nic_hdl pnetdev; //+6016 + int bup; //+6020 + struct net_device_stats stats; + uint8_t net_closed; //+6052 + uint8_t bFWReady; + uint8_t bLinkInfoDump; + uint8_t bRxRSSIDisplay; + _adapter *pbuddy_adapter; //+6056 + _mutex *hw_init_mutex; //+6060 + uint8_t isprimary; //+6064 + uint8_t adapter_type; //+6065 + uint8_t iface_type; //+6056 + _mutex *ph2c_fwcmd_mutex; //+6068 + _mutex *psetch_mutex; //+6072 + _mutex *psetbw_mutex; //+6076 + struct co_data_priv *pcodatapriv; //+6080 + uint8_t fix_rate; //+6084 +}; // [6088] (!) +typedef struct _ADAPTER *PADAPTER; +// if sizeof(struct _ADAPTER) != 6088 #error "Check aligned struct!" ! + +enum tag_HAL_IC_Type_Definition // : sint32_t +{ + CHIP_8192S = 0x0, + CHIP_8188C = 0x1, + CHIP_8192C = 0x2, + CHIP_8192D = 0x3, + CHIP_8723A = 0x4, + CHIP_8188E = 0x5, + CHIP_8812 = 0x6, + CHIP_8821 = 0x7, + CHIP_8723B = 0x8, + CHIP_8192E = 0x9, + CHIP_8195A = 0xA, + CHIP_8711B = 0xB, + CHIP_8188F = 0xC, +}; +typedef enum tag_HAL_IC_Type_Definition HAL_IC_TYPE_E; + +enum tag_HAL_CHIP_Type_Definition // : sint32_t +{ + TEST_CHIP = 0x0, NORMAL_CHIP = 0x1, FPGA = 0x2, +}; +typedef enum tag_HAL_CHIP_Type_Definition HAL_CHIP_TYPE_E; + +enum tag_HAL_Cut_Version_Definition // : sint32_t +{ + A_CUT_VERSION = 0x0, + B_CUT_VERSION = 0x1, + C_CUT_VERSION = 0x2, + D_CUT_VERSION = 0x3, + E_CUT_VERSION = 0x4, + F_CUT_VERSION = 0x5, + G_CUT_VERSION = 0x6, + H_CUT_VERSION = 0x7, + I_CUT_VERSION = 0x8, + J_CUT_VERSION = 0x9, + K_CUT_VERSION = 0xA, +}; +typedef enum tag_HAL_Cut_Version_Definition HAL_CUT_VERSION_E; + +enum tag_HAL_Manufacturer_Version_Definition //: sint32_t +{ + CHIP_VENDOR_TSMC = 0x0, CHIP_VENDOR_UMC = 0x1, CHIP_VENDOR_SMIC = 0x2, +}; +typedef enum tag_HAL_Manufacturer_Version_Definition HAL_VENDOR_E; + +enum tag_HAL_RF_Type_Definition //: sint32_t +{ + RF_TYPE_1T1R = 0x0, + RF_TYPE_1T2R = 0x1, + RF_TYPE_2T2R = 0x2, + RF_TYPE_2T3R = 0x3, + RF_TYPE_2T4R = 0x4, + RF_TYPE_3T3R = 0x5, + RF_TYPE_3T4R = 0x6, + RF_TYPE_4T4R = 0x7, +}; +typedef enum tag_HAL_RF_Type_Definition HAL_RF_TYPE_E; + +struct _atr_aligned4_ tag_HAL_VERSION { + HAL_IC_TYPE_E ICType; + HAL_CHIP_TYPE_E ChipType; + HAL_CUT_VERSION_E CUTVersion; + HAL_VENDOR_E VendorType; + HAL_RF_TYPE_E RFType; + uint8_t ROMVer; +}; +typedef struct tag_HAL_VERSION HAL_VERSION; + +enum _HW_VARIABLES //: sint32_t +{ + HW_VAR_MEDIA_STATUS = 0x0, + HW_VAR_MEDIA_STATUS1 = 0x1, + HW_VAR_SET_OPMODE = 0x2, + HW_VAR_MAC_ADDR = 0x3, + HW_VAR_BSSID = 0x4, + HW_VAR_INIT_RTS_RATE = 0x5, + HW_VAR_BASIC_RATE = 0x6, + HW_VAR_TXPAUSE = 0x7, + HW_VAR_BCN_FUNC = 0x8, + HW_VAR_CORRECT_TSF = 0x9, + HW_VAR_CHECK_BSSID = 0xA, + HW_VAR_MLME_DISCONNECT = 0xB, + HW_VAR_MLME_SITESURVEY = 0xC, + HW_VAR_MLME_JOIN = 0xD, + HW_VAR_ON_RCR_AM = 0xE, + HW_VAR_OFF_RCR_AM = 0xF, + HW_VAR_BEACON_INTERVAL = 0x10, + HW_VAR_SLOT_TIME = 0x11, + HW_VAR_RESP_SIFS = 0x12, + HW_VAR_ACK_PREAMBLE = 0x13, + HW_VAR_SEC_CFG = 0x14, + HW_VAR_SEC_DK_CFG = 0x15, + HW_VAR_RF_TYPE = 0x16, + HW_VAR_DM_FLAG = 0x17, + HW_VAR_DM_FUNC_OP = 0x18, + HW_VAR_DM_FUNC_SET = 0x19, + HW_VAR_DM_FUNC_CLR = 0x1A, + HW_VAR_CAM_EMPTY_ENTRY = 0x1B, + HW_VAR_CAM_INVALID_ALL = 0x1C, + HW_VAR_CAM_WRITE = 0x1D, + HW_VAR_CAM_READ = 0x1E, + HW_VAR_AC_PARAM_VO = 0x1F, + HW_VAR_AC_PARAM_VI = 0x20, + HW_VAR_AC_PARAM_BE = 0x21, + HW_VAR_AC_PARAM_BK = 0x22, + HW_VAR_ACM_CTRL = 0x23, + HW_VAR_AMPDU_MIN_SPACE = 0x24, + HW_VAR_AMPDU_FACTOR = 0x25, + HW_VAR_RXDMA_AGG_PG_TH = 0x26, + HW_VAR_SET_RPWM = 0x27, + HW_VAR_GET_RPWM = 0x28, + HW_VAR_CPWM = 0x29, + HW_VAR_H2C_FW_PWRMODE = 0x2A, + HW_VAR_H2C_PS_TUNE_PARAM = 0x2B, + HW_VAR_H2C_FW_JOINBSSRPT = 0x2C, + HW_VAR_FWLPS_RF_ON = 0x2D, + HW_VAR_H2C_FW_P2P_PS_OFFLOAD = 0x2E, + HW_VAR_TDLS_WRCR = 0x2F, + HW_VAR_TDLS_INIT_CH_SEN = 0x30, + HW_VAR_TDLS_RS_RCR = 0x31, + HW_VAR_TDLS_DONE_CH_SEN = 0x32, + HW_VAR_INITIAL_GAIN = 0x33, + HW_VAR_TRIGGER_GPIO_0 = 0x34, + HW_VAR_CURRENT_ANTENNA = 0x35, + HW_VAR_ANTENNA_DIVERSITY_LINK = 0x36, + HW_VAR_ANTENNA_DIVERSITY_SELECT = 0x37, + HW_VAR_SWITCH_EPHY_WoWLAN = 0x38, + HW_VAR_EFUSE_USAGE = 0x39, + HW_VAR_EFUSE_BYTES = 0x3A, + HW_VAR_FIFO_CLEARN_UP = 0x3B, + HW_VAR_RESTORE_HW_SEQ = 0x3C, + HW_VAR_HCI_SUS_STATE = 0x3D, + HW_VAR_CHECK_TXBUF = 0x3E, + HW_VAR_APFM_ON_MAC = 0x3F, + HW_VAR_NAV_UPPER = 0x40, + HW_VAR_C2H_HANDLE = 0x41, + HW_VAR_RPT_TIMER_SETTING = 0x42, + HW_VAR_TX_RPT_MAX_MACID = 0x43, + HW_VAR_H2C_MEDIA_STATUS_RPT = 0x44, + HW_VAR_CHK_HI_QUEUE_EMPTY = 0x45, + HW_VAR_DL_BCN_SEL = 0x46, + HW_VAR_PORT_SWITCH = 0x47, + HW_VAR_DM_IN_LPS = 0x48, + HW_VAR_SET_REQ_FW_PS = 0x49, + HW_VAR_FW_PS_STATE = 0x4A, + HW_VAR_DL_RSVD_PAGE = 0x4B, + HW_VAR_MACID_SLEEP = 0x4C, + HW_VAR_MACID_WAKEUP = 0x4D, + HW_VAR_DUMP_MAC_QUEUE_INFO = 0x4E, + HW_VAR_ASIX_IOT = 0x4F, + HW_VAR_PROMISC = 0x50, +}; + +enum _BAND_TYPE // : sint32_t +{ + BAND_ON_2_4G = 0x0, BAND_ON_5G = 0x1, BAND_ON_BOTH = 0x2, BANDMAX = 0x3, +}; +typedef enum _BAND_TYPE BAND_TYPE; + +struct _BB_REGISTER_DEFINITION { + uint32_t rfintfs; + uint32_t rfintfo; + uint32_t rfintfe; + uint32_t rf3wireOffset; + uint32_t rfHSSIPara2; + uint32_t rfLSSIReadBack; + uint32_t rfLSSIReadBackPi; +}; +typedef struct _BB_REGISTER_DEFINITION BB_REGISTER_DEFINITION_T; + +enum dot11AuthAlgrthmNum //: sint32_t +{ + dot11AuthAlgrthm_Open = 0x0, + dot11AuthAlgrthm_Shared = 0x1, + dot11AuthAlgrthm_8021X = 0x2, + dot11AuthAlgrthm_Auto = 0x3, + dot11AuthAlgrthm_WAPI = 0x4, + dot11AuthAlgrthm_MaxNum = 0x5, +}; + +enum _RT_CHANNEL_DOMAIN //: sint32_t +{ + RT_CHANNEL_DOMAIN_FCC = 0x0, + RT_CHANNEL_DOMAIN_IC = 0x1, + RT_CHANNEL_DOMAIN_ETSI = 0x2, + RT_CHANNEL_DOMAIN_SPAIN = 0x3, + RT_CHANNEL_DOMAIN_FRANCE = 0x4, + RT_CHANNEL_DOMAIN_MKK = 0x5, + RT_CHANNEL_DOMAIN_MKK1 = 0x6, + RT_CHANNEL_DOMAIN_ISRAEL = 0x7, + RT_CHANNEL_DOMAIN_TELEC = 0x8, + RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN = 0x9, + RT_CHANNEL_DOMAIN_WORLD_WIDE_13 = 0xA, + RT_CHANNEL_DOMAIN_TAIWAN = 0xB, + RT_CHANNEL_DOMAIN_CHINA = 0xC, + RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO = 0xD, + RT_CHANNEL_DOMAIN_KOREA = 0xE, + RT_CHANNEL_DOMAIN_TURKEY = 0xF, + RT_CHANNEL_DOMAIN_JAPAN = 0x10, + RT_CHANNEL_DOMAIN_FCC_NO_DFS = 0x11, + RT_CHANNEL_DOMAIN_JAPAN_NO_DFS = 0x12, + RT_CHANNEL_DOMAIN_WORLD_WIDE_5G = 0x13, + RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS = 0x14, + RT_CHANNEL_DOMAIN_WORLD_NULL = 0x20, + RT_CHANNEL_DOMAIN_ETSI1_NULL = 0x21, + RT_CHANNEL_DOMAIN_FCC1_NULL = 0x22, + RT_CHANNEL_DOMAIN_MKK1_NULL = 0x23, + RT_CHANNEL_DOMAIN_ETSI2_NULL = 0x24, + RT_CHANNEL_DOMAIN_FCC1_FCC1 = 0x25, + RT_CHANNEL_DOMAIN_WORLD_ETSI1 = 0x26, + RT_CHANNEL_DOMAIN_MKK1_MKK1 = 0x27, + RT_CHANNEL_DOMAIN_WORLD_KCC1 = 0x28, + RT_CHANNEL_DOMAIN_WORLD_FCC2 = 0x29, + RT_CHANNEL_DOMAIN_FCC2_NULL = 0x2A, + RT_CHANNEL_DOMAIN_WORLD_FCC3 = 0x30, + RT_CHANNEL_DOMAIN_WORLD_FCC4 = 0x31, + RT_CHANNEL_DOMAIN_WORLD_FCC5 = 0x32, + RT_CHANNEL_DOMAIN_WORLD_FCC6 = 0x33, + RT_CHANNEL_DOMAIN_FCC1_FCC7 = 0x34, + RT_CHANNEL_DOMAIN_WORLD_ETSI2 = 0x35, + RT_CHANNEL_DOMAIN_WORLD_ETSI3 = 0x36, + RT_CHANNEL_DOMAIN_MKK1_MKK2 = 0x37, + RT_CHANNEL_DOMAIN_MKK1_MKK3 = 0x38, + RT_CHANNEL_DOMAIN_FCC1_NCC1 = 0x39, + RT_CHANNEL_DOMAIN_FCC1_NCC2 = 0x40, + RT_CHANNEL_DOMAIN_GLOBAL_NULL = 0x41, + RT_CHANNEL_DOMAIN_ETSI1_ETSI4 = 0x42, + RT_CHANNEL_DOMAIN_FCC1_FCC2 = 0x43, + RT_CHANNEL_DOMAIN_FCC1_NCC3 = 0x44, + RT_CHANNEL_DOMAIN_WORLD_ETSI5 = 0x45, + RT_CHANNEL_DOMAIN_FCC1_FCC8 = 0x46, + RT_CHANNEL_DOMAIN_WORLD_ETSI6 = 0x47, + RT_CHANNEL_DOMAIN_WORLD_ETSI7 = 0x48, + RT_CHANNEL_DOMAIN_WORLD_ETSI8 = 0x49, + RT_CHANNEL_DOMAIN_WORLD_ETSI9 = 0x50, + RT_CHANNEL_DOMAIN_WORLD_ETSI10 = 0x51, + RT_CHANNEL_DOMAIN_WORLD_ETSI11 = 0x52, + RT_CHANNEL_DOMAIN_FCC1_NCC4 = 0x53, + RT_CHANNEL_DOMAIN_WORLD_ETSI12 = 0x54, + RT_CHANNEL_DOMAIN_FCC1_FCC9 = 0x55, + RT_CHANNEL_DOMAIN_WORLD_ETSI13 = 0x56, + RT_CHANNEL_DOMAIN_FCC1_FCC10 = 0x57, + RT_CHANNEL_DOMAIN_MKK2_MKK4 = 0x58, + RT_CHANNEL_DOMAIN_MAX = 0x59, + RT_CHANNEL_DOMAIN_REALTEK_DEFINE = 0x7F, +}; + +struct _driver_priv { + int drv_registered; + _mutex hw_init_mutex; + _mutex h2c_fwcmd_mutex; + _mutex setch_mutex; + _mutex setbw_mutex; +}; +typedef struct _driver_priv drv_priv; + +struct _ADAPTIVITY_STATISTICS { + s1Byte TH_L2H_ini_mode2; + s1Byte TH_EDCCA_HL_diff_mode2; + s1Byte TH_EDCCA_HL_diff_backup; + s1Byte IGI_Base; + u1Byte IGI_target; + u1Byte NHMWait; + s1Byte H2L_lb; + s1Byte L2H_lb; + BOOLEAN bFirstLink; + BOOLEAN bCheck; + BOOLEAN DynamicLinkAdaptivity; + u1Byte APNumTH; + u1Byte AdajustIGILevel; +}; +typedef struct _ADAPTIVITY_STATISTICS ADAPTIVITY_STATISTICS; + +struct _ODM_NOISE_MONITOR_ { + s1Byte noise[1]; + s2Byte noise_all; +}; +typedef struct _ODM_NOISE_MONITOR_ ODM_NOISE_MONITOR; +/* in rtl_bios_data.h +struct _FALSE_ALARM_STATISTICS { + u4Byte Cnt_Parity_Fail; + u4Byte Cnt_Rate_Illegal; + u4Byte Cnt_Crc8_fail; + u4Byte Cnt_Mcs_fail; + u4Byte Cnt_Ofdm_fail; + u4Byte Cnt_Ofdm_fail_pre; + u4Byte Cnt_Cck_fail; + u4Byte Cnt_all; + u4Byte Cnt_Fast_Fsync; + u4Byte Cnt_SB_Search_fail; + u4Byte Cnt_OFDM_CCA; + u4Byte Cnt_CCK_CCA; + u4Byte Cnt_CCA_all; + u4Byte Cnt_BW_USC; + u4Byte Cnt_BW_LSC; +}; +typedef struct _FALSE_ALARM_STATISTICS FALSE_ALARM_STATISTICS; +*/ + +enum _BASEBAND_CONFIG_PHY_REG_PG_VALUE_TYPE //: sint32_t +{ + PHY_REG_PG_RELATIVE_VALUE = 0x0, PHY_REG_PG_EXACT_VALUE = 0x1, +}; +typedef enum _BASEBAND_CONFIG_PHY_REG_PG_VALUE_TYPE PHY_REG_PG_TYPE; + +/* in rtl_bios_data.h +struct _atr_aligned4_ _CFO_TRACKING_ { + BOOLEAN bATCStatus; + BOOLEAN largeCFOHit; + BOOLEAN bAdjust; + u1Byte CrystalCap; + u1Byte DefXCap; + int CFO_tail[2]; + int CFO_ave_pre; + u4Byte packetCount; + u4Byte packetCount_pre; + BOOLEAN bForceXtalCap; + BOOLEAN bReset; + u1Byte CFO_TH_XTAL_HIGH; + u1Byte CFO_TH_XTAL_LOW; + u1Byte CFO_TH_ATC; +}; +typedef struct _CFO_TRACKING_ CFO_TRACKING; +*/ +/* in rtl_bios_data.h +struct _atr_aligned8_ _ROM_INFO { + u1Byte EEPROMVersion; + u1Byte CrystalCap; + u8Byte DebugComponents; + u4Byte DebugLevel; +}; +typedef struct _ROM_INFO ROM_INFO; +*/ + +typedef struct _ROM_INFO *PROM_INFO; + +typedef struct sta_info *PSTA_INFO_T; + +struct _ODM_Phy_Dbg_Info_ { + s1Byte RxSNRdB[4]; + u4Byte NumQryPhyStatus; + u4Byte NumQryPhyStatusCCK; + u4Byte NumQryPhyStatusOFDM; + u1Byte NumQryBeaconPkt; + s4Byte RxEVM[4]; +}; +typedef struct _ODM_Phy_Dbg_Info_ ODM_PHY_DBG_INFO_T; + +struct _ODM_Mac_Status_Info_ { + u1Byte test; +}; +typedef struct _ODM_Mac_Status_Info_ ODM_MAC_INFO; + +struct _atr_aligned4_ _ODM_RA_Info_ { + u1Byte RateID; + u4Byte RateMask; + u4Byte RAUseRate; + u1Byte RateSGI; + u1Byte RssiStaRA; + u1Byte PreRssiStaRA; + u1Byte SGIEnable; + u1Byte DecisionRate; + u1Byte PreRate; + u1Byte HighestRate; + u1Byte LowestRate; + u4Byte NscUp; + u4Byte NscDown; + u2Byte RTY[5]; + u4Byte TOTAL; + u2Byte DROP; + u1Byte Active; + u2Byte RptTime; + u1Byte RAWaitingCounter; + u1Byte RAPendingCounter; + u1Byte RAINFO; + u1Byte Initial_BW; + u1Byte BW_setting; + u1Byte DISPT; + u1Byte DISRA; + u1Byte Stage_RA; + u1Byte PRE_BW; + u1Byte MacID; + u1Byte Try_state; + u1Byte Try_done_cnt; + u2Byte RA_counter; + u1Byte Init_Rate_H; + u1Byte Init_Rate_M; + u1Byte Init_Rate_L; + u4Byte Total_TX; + u1Byte TRAINING_RATE; + u1Byte STOP_PT_COUNTER; + u1Byte MODE_SS; + u1Byte PT_smooth_factor; + u1Byte PTActive; + u1Byte PTTryState; + u1Byte PTStage; + u1Byte PTStopCount; + u1Byte PTPreRate; + u1Byte PTPreRssi; + u1Byte PTModeSS; + u1Byte RAstage; + u1Byte PTSmoothFactor; +}; +typedef struct _ODM_RA_Info_ ODM_RA_INFO_T; +typedef struct _ODM_RA_Info_ *PODM_RA_INFO_T; + +struct _FAST_ANTENNA_TRAINNING_ { + u1Byte Bssid[6]; + u1Byte antsel_rx_keep_0; + u1Byte antsel_rx_keep_1; + u1Byte antsel_rx_keep_2; + u4Byte antSumRSSI[7]; + u4Byte antRSSIcnt[7]; + u4Byte antAveRSSI[7]; + u1Byte FAT_State; + u4Byte TrainIdx; + u1Byte antsel_a[7]; + u1Byte antsel_b[7]; + u1Byte antsel_c[7]; + u4Byte MainAnt_Sum[7]; + u4Byte AuxAnt_Sum[7]; + u4Byte MainAnt_Cnt[7]; + u4Byte AuxAnt_Cnt[7]; + u4Byte MainAnt_Sum_CCK[7]; + u4Byte AuxAnt_Sum_CCK[7]; + u4Byte MainAnt_Cnt_CCK[7]; + u4Byte AuxAnt_Cnt_CCK[7]; + u1Byte RxIdleAnt; + BOOLEAN bBecomeLinked; + u4Byte MinMaxRSSI; + u1Byte idx_AntDiv_counter_2G; + u1Byte idx_AntDiv_counter_5G; + u4Byte AntDiv_2G_5G; + u4Byte CCK_counter_main; + u4Byte CCK_counter_aux; + u4Byte OFDM_counter_main; + u4Byte OFDM_counter_aux; +}; +typedef struct _FAST_ANTENNA_TRAINNING_ FAT_T; + +struct _Dynamic_Initial_Gain_Threshold_ { + BOOLEAN bStopDIG; + BOOLEAN bPauseDIG; + BOOLEAN bIgnoreDIG; + BOOLEAN bPSDInProgress; + u1Byte Dig_Enable_Flag; + u1Byte Dig_Ext_Port_Stage; + int RssiLowThresh; + int RssiHighThresh; + u4Byte FALowThresh; + u4Byte FAHighThresh; + u1Byte CurSTAConnectState; + u1Byte PreSTAConnectState; + u1Byte CurMultiSTAConnectState; + u1Byte PreIGValue; + u1Byte CurIGValue; + u1Byte BackupIGValue; + u1Byte BT30_CurIGI; + u1Byte IGIBackup; + s1Byte BackoffVal; + s1Byte BackoffVal_range_max; + s1Byte BackoffVal_range_min; + u1Byte rx_gain_range_max; + u1Byte rx_gain_range_min; + u1Byte Rssi_val_min; + u1Byte PreCCK_CCAThres; + u1Byte CurCCK_CCAThres; + u1Byte PreCCKPDState; + u1Byte CurCCKPDState; + u1Byte CCKPDBackup; + u1Byte LargeFAHit; + u1Byte ForbiddenIGI; + u4Byte Recover_cnt; + u1Byte DIG_Dynamic_MIN_0; + u1Byte DIG_Dynamic_MIN_1; + BOOLEAN bMediaConnect_0; + BOOLEAN bMediaConnect_1; + u4Byte AntDiv_RSSI_max; + u4Byte RSSI_max; + u1Byte *pbP2pLinkInProgress; +}; +typedef struct _Dynamic_Initial_Gain_Threshold_ DIG_T; + +struct _ODM_RATE_ADAPTIVE { + u1Byte Type; + u1Byte HighRSSIThresh; + u1Byte LowRSSIThresh; + u1Byte RATRState; + u1Byte LdpcThres; + BOOLEAN bLowerRtsRate; + BOOLEAN bUseLdpc; +}; +typedef struct _ODM_RATE_ADAPTIVE ODM_RATE_ADAPTIVE; + +struct _Dynamic_Power_Saving_ { + u1Byte PreCCAState; + u1Byte CurCCAState; + u1Byte PreRFState; + u1Byte CurRFState; + int Rssi_val_min; + u1Byte initialize; + u4Byte Reg874; + u4Byte RegC70; + u4Byte Reg85C; + u4Byte RegA74; +}; +typedef struct _Dynamic_Power_Saving_ PS_T; + +struct _Dynamic_Primary_CCA { + u1Byte PriCCA_flag; + u1Byte intf_flag; + u1Byte intf_type; + u1Byte DupRTS_flag; + u1Byte Monitor_flag; + u1Byte CH_offset; + u1Byte MF_state; +}; +typedef struct _Dynamic_Primary_CCA Pri_CCA_T; + +struct _RX_High_Power_ { + u1Byte RXHP_flag; + u1Byte PSD_func_trigger; + u1Byte PSD_bitmap_RXHP[80]; + u1Byte Pre_IGI; + u1Byte Cur_IGI; + u1Byte Pre_pw_th; + u1Byte Cur_pw_th; + BOOLEAN First_time_enter; + BOOLEAN RXHP_enable; + u1Byte TP_Mode; +}; +typedef struct _RX_High_Power_ RXHP_T; + +struct _Rate_Adaptive_Table_ { + u1Byte firstconnect; +}; +typedef struct _Rate_Adaptive_Table_ RA_T; + +struct _atr_aligned8_ _SW_Antenna_Switch_ { + u1Byte Double_chk_flag; + u1Byte try_flag; + s4Byte PreRSSI; + u1Byte CurAntenna; + u1Byte PreAntenna; + u1Byte RSSI_Trying; + u1Byte TestMode; + u1Byte bTriggerAntennaSwitch; + u1Byte SelectAntennaMap; + u1Byte RSSI_target; + u1Byte reset_idx; + u1Byte SWAS_NoLink_State; + u4Byte SWAS_NoLink_BK_Reg860; + u4Byte SWAS_NoLink_BK_Reg92c; + BOOLEAN ANTA_ON; + BOOLEAN ANTB_ON; + u1Byte Ant5G; + u1Byte Ant2G; + s4Byte RSSI_sum_A; + s4Byte RSSI_sum_B; + s4Byte RSSI_cnt_A; + s4Byte RSSI_cnt_B; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u8Byte TXByteCnt_A; + u8Byte TXByteCnt_B; + u8Byte RXByteCnt_A; + u8Byte RXByteCnt_B; + u1Byte TrafficLoad; + u1Byte Train_time; + u1Byte Train_time_flag; +}; +typedef struct _SW_Antenna_Switch_ SWAT_T; + +struct _EDCA_TURBO_ { + BOOLEAN bCurrentTurboEDCA; + BOOLEAN bIsCurRDLState; +}; +typedef struct _EDCA_TURBO_ EDCA_T; + +struct _ANT_DETECTED_INFO { + BOOLEAN bAntDetected; + u4Byte dBForAntA; + u4Byte dBForAntB; + u4Byte dBForAntO; +}; +typedef struct _ANT_DETECTED_INFO ANT_DETECTED_INFO; + +struct _IQK_MATRIX_REGS_SETTING { + BOOLEAN bIQKDone; + s4Byte Value[1][8]; +}; +typedef struct _IQK_MATRIX_REGS_SETTING IQK_MATRIX_REGS_SETTING; + +struct _atr_aligned8_ ODM_RF_Calibration_Structure { + u4Byte RegA24; + s4Byte RegE94; + s4Byte RegE9C; + s4Byte RegEB4; + s4Byte RegEBC; + u1Byte TXPowercount; + BOOLEAN bTXPowerTrackingInit; + BOOLEAN bTXPowerTracking; + u1Byte TxPowerTrackControl; + u1Byte TM_Trigger; + u1Byte InternalPA5G[2]; + u1Byte ThermalMeter[2]; + u1Byte ThermalValue; + u1Byte ThermalValue_LCK; + u1Byte ThermalValue_IQK; + u1Byte ThermalValue_DPK; + u1Byte ThermalValue_AVG[8]; + u1Byte ThermalValue_AVG_index; + u1Byte ThermalValue_RxGain; + u1Byte ThermalValue_Crystal; + u1Byte ThermalValue_DPKstore; + u1Byte ThermalValue_DPKtrack; + BOOLEAN TxPowerTrackingInProgress; + BOOLEAN bReloadtxpowerindex; + u1Byte bRfPiEnable; + u4Byte TXPowerTrackingCallbackCnt; + u1Byte bCCKinCH14; + u1Byte CCK_index[1]; + s1Byte PowerIndexOffset_CCK[1]; + s1Byte DeltaPowerIndex_CCK[1]; + s1Byte DeltaPowerIndexLast_CCK[1]; + u1Byte OFDM_index[1]; + s1Byte PowerIndexOffset_OFDM[1]; + s1Byte DeltaPowerIndex_OFDM[1]; + s1Byte DeltaPowerIndexLast_OFDM[1]; + BOOLEAN bTxPowerChanged; + s1Byte XtalOffset; + s1Byte XtalOffsetLast; + u1Byte ThermalValue_HP[8]; + u1Byte ThermalValue_HP_index; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[14]; + u1Byte Delta_LCK; + s1Byte BBSwingDiff2G; + s1Byte BBSwingDiff5G; + s1Byte DeltaSwingTableIdx_2GCCKA_P[30]; + s1Byte DeltaSwingTableIdx_2GCCKA_N[30]; + s1Byte DeltaSwingTableIdx_2GA_P[30]; + s1Byte DeltaSwingTableIdx_2GA_N[30]; + s1Byte DeltaSwingTableXtal_P[30]; + s1Byte DeltaSwingTableXtal_N[30]; + u4Byte RegC04; + u4Byte Reg874; + u4Byte RegC08; + u4Byte RegB68; + u4Byte RegB6C; + u4Byte Reg870; + u4Byte Reg860; + u4Byte Reg864; + BOOLEAN bIQKInitialized; + BOOLEAN bLCKInProgress; + BOOLEAN bAntennaDetected; + BOOLEAN bNeedIQK; + BOOLEAN bIQKInProgress; + u1Byte Delta_IQK; + u4Byte ADDA_backup[16]; + u4Byte IQK_MAC_backup[4]; + u4Byte IQK_BB_backup_recover[9]; + u4Byte IQK_BB_backup[9]; + u4Byte TxIQC_8723B[2][3][2]; + u4Byte RxIQC_8723B[2][2][2]; + u8Byte IQK_StartTime; + u8Byte IQK_ProgressingTime; + u4Byte LOK_Result; + u4Byte APKoutput[2][2]; + u1Byte bAPKdone; + u1Byte bAPKThermalMeterIgnore; + BOOLEAN bDPKFail; + u1Byte bDPdone; + u1Byte bDPPathAOK; + u1Byte bDPPathBOK; + u4Byte TxLOK[2]; + u4Byte DpkTxAGC; + s4Byte DpkGain; + u4Byte DpkThermal[4]; +}; +typedef struct ODM_RF_Calibration_Structure ODM_RF_CAL_T; + +struct _atr_aligned8_ DM_Out_Source_Dynamic_Mechanism_Structure { + PADAPTER Adapter; + BOOLEAN odm_ready; + PHY_REG_PG_TYPE PhyRegPgValueType; + u1Byte PhyRegPgVersion; + u4Byte NumQryPhyStatusAll; + u4Byte LastNumQryPhyStatusAll; + u4Byte RxPWDBAve; + BOOLEAN MPDIG_2G; + u1Byte Times_2G; + BOOLEAN bCckHighPower; + u1Byte RFPathRxEnable; + u1Byte ControlChannel; + u1Byte SupportPlatform; + u4Byte SupportAbility; + u1Byte SupportInterface; + u4Byte SupportICType; + u1Byte CutVersion; + u1Byte FabVersion; + u1Byte RFType; + u1Byte RFEType; + u1Byte BoardType; + u1Byte PackageType; + u1Byte TypeGLNA; + u1Byte TypeGPA; + u1Byte TypeALNA; + u1Byte TypeAPA; + u1Byte ExtLNA; + u1Byte ExtLNA5G; + u1Byte ExtPA; + u1Byte ExtPA5G; + u1Byte ExtTRSW; + u1Byte PatchID; + BOOLEAN bInHctTest; + BOOLEAN bWIFITest; + BOOLEAN bDualMacSmartConcurrent; + u4Byte BK_SupportAbility; + u1Byte AntDivType; + u1Byte odm_Regulation2_4G; + u1Byte odm_Regulation5G; + u1Byte u1Byte_temp; + PADAPTER PADAPTER_temp; + u1Byte *pMacPhyMode; + u8Byte *pNumTxBytesUnicast; + u8Byte *pNumRxBytesUnicast; + u1Byte *pWirelessMode; + u1Byte *pBandType; + u1Byte *pSecChOffset; + u1Byte *pSecurity; + u1Byte *pBandWidth; + u1Byte *pChannel; + BOOLEAN DPK_Done; + BOOLEAN *pbGetValueFromOtherMac; + PADAPTER *pBuddyAdapter; + BOOLEAN *pbMasterOfDMSP; + BOOLEAN *pbScanInProcess; + BOOLEAN *pbPowerSaving; + u1Byte *pOnePathCCA; + u1Byte *pAntennaTest; + BOOLEAN *pbNet_closed; + u1Byte *mp_mode; + u1Byte *pu1ForcedIgiLb; + BOOLEAN *pIsFcsModeEnable; + pu2Byte pForcedDataRate; + BOOLEAN bLinkInProcess; + BOOLEAN bWIFI_Direct; + BOOLEAN bWIFI_Display; + BOOLEAN bLinked; + BOOLEAN bsta_state; + u1Byte RSSI_Min; + u1Byte InterfaceIndex; + BOOLEAN bIsMPChip; + BOOLEAN bOneEntryOnly; + BOOLEAN bBtEnabled; + BOOLEAN bBtConnectProcess; + u1Byte btHsRssi; + BOOLEAN bBtHsOperation; + BOOLEAN bBtDisableEdcaTurbo; + BOOLEAN bBtLimitedDig; + u1Byte RSSI_A; + u1Byte RSSI_B; + u8Byte RSSI_TRSW; + u8Byte RSSI_TRSW_H; + u8Byte RSSI_TRSW_L; + u8Byte RSSI_TRSW_iso; + u1Byte RxRate; + BOOLEAN bNoisyState; + u1Byte TxRate; + u1Byte LinkedInterval; + u1Byte preChannel; + u4Byte TxagcOffsetValueA; + BOOLEAN IsTxagcOffsetPositiveA; + u4Byte TxagcOffsetValueB; + BOOLEAN IsTxagcOffsetPositiveB; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u4Byte BbSwingOffsetA; + BOOLEAN IsBbSwingOffsetPositiveA; + u4Byte BbSwingOffsetB; + BOOLEAN IsBbSwingOffsetPositiveB; + u1Byte antdiv_rssi; + u1Byte AntType; + u1Byte pre_AntType; + u1Byte antdiv_period; + u1Byte antdiv_select; + u1Byte NdpaPeriod; + BOOLEAN H2C_RARpt_connect; + u2Byte NHM_cnt_0; + u2Byte NHM_cnt_1; + s1Byte TH_L2H_ini; + s1Byte TH_EDCCA_HL_diff; + s1Byte TH_L2H_ini_backup; + BOOLEAN Carrier_Sense_enable; + u1Byte Adaptivity_IGI_upper; + BOOLEAN adaptivity_flag; + u1Byte DCbackoff; + BOOLEAN Adaptivity_enable; + u1Byte APTotalNum; + ADAPTIVITY_STATISTICS Adaptivity; + ODM_NOISE_MONITOR noise_level; + PSTA_INFO_T pODM_StaInfo[7]; + u2Byte CurrminRptTime; + ODM_RA_INFO_T RAInfo[7]; + BOOLEAN RaSupport88E; + ODM_PHY_DBG_INFO_T PhyDbgInfo; + ODM_MAC_INFO *pMacInfo; + FAT_T DM_FatTable; + DIG_T DM_DigTable; + PS_T DM_PSTable; + Pri_CCA_T DM_PriCCA; + RXHP_T DM_RXHP_Table; + RA_T DM_RA_Table; + PROM_INFO pROMInfo; + FALSE_ALARM_STATISTICS FalseAlmCnt; + CFO_TRACKING DM_CfoTrack; + FALSE_ALARM_STATISTICS FlaseAlmCntBuddyAdapter; + SWAT_T DM_SWAT_Table; + BOOLEAN RSSI_test; + BOOLEAN bNoBeaconIn2s; + EDCA_T DM_EDCA_Table; + u4Byte WMMEDCA_BE; + BOOLEAN *pbDriverStopped; + BOOLEAN *pbDriverIsGoingToPnpSetPowerSleep; + BOOLEAN *pinit_adpt_in_progress; + u1Byte bUseRAMask; + ODM_RATE_ADAPTIVE RateAdaptive; + ANT_DETECTED_INFO AntDetectedInfo; + ODM_RF_CAL_T RFCalibrateInfo; + u1Byte BbSwingIdxOfdm[1]; + u1Byte BbSwingIdxOfdmCurrent; + u1Byte BbSwingIdxOfdmBase[1]; + BOOLEAN BbSwingFlagOfdm; + u1Byte BbSwingIdxCck[1]; + u1Byte BbSwingIdxCckCurrent; + u1Byte BbSwingIdxCckBase[1]; + u1Byte DefaultOfdmIndex; + u1Byte DefaultCckIndex; + BOOLEAN BbSwingFlagCck; + s1Byte Absolute_OFDMSwingIdx[1]; + s1Byte Absolute_CCKSwingIdx[1]; + s1Byte Remnant_OFDMSwingIdx[1]; + s1Byte Remnant_CCKSwingIdx[1]; + s1Byte Modify_TxAGC_Value; + BOOLEAN Modify_TxAGC_Flag_PathA; + BOOLEAN Modify_TxAGC_Flag_PathB; + BOOLEAN Modify_TxAGC_Flag_PathA_CCK; +}; +typedef struct DM_Out_Source_Dynamic_Mechanism_Structure DM_ODM_T; +typedef struct DM_Out_Source_Dynamic_Mechanism_Structure *PDM_ODM_T; + +enum _PWRTRACK_CONTROL_METHOD //: sint32_t +{ + BBSWING = 0x0, TXAGC = 0x1, MIX_MODE = 0x2, +}; +typedef enum _PWRTRACK_CONTROL_METHOD PWRTRACK_METHOD; + +typedef void (*FuncSetPwr)(PDM_ODM_T, PWRTRACK_METHOD, u1Byte, u1Byte); +typedef void (*FuncIQK)(PDM_ODM_T, u1Byte, u1Byte, u1Byte); +typedef void (*FuncLCK)(PDM_ODM_T); +typedef void (*FuncSwing)(PDM_ODM_T, ps1Byte *, ps1Byte *, ps1Byte *, ps1Byte *); +typedef void (*FuncSwingXtal)(PDM_ODM_T, ps1Byte *, ps1Byte *); +typedef void (*FuncSetXtal)(PDM_ODM_T); + +struct _TXPWRTRACK_CFG { + u1Byte SwingTableSize_CCK; + u1Byte SwingTableSize_OFDM; + u1Byte Threshold_IQK; + u1Byte AverageThermalNum; + u1Byte RfPathCount; + u4Byte ThermalRegAddr; + FuncSetPwr ODM_TxPwrTrackSetPwr; + FuncIQK DoIQK; + FuncLCK PHY_LCCalibrate; + FuncSwing GetDeltaSwingTable; + FuncSwingXtal GetDeltaSwingXtalTable; + FuncSetXtal ODM_TxXtalTrackSetXtal; +}; +typedef struct _TXPWRTRACK_CFG *PTXPWRTRACK_CFG; + +struct _RSVDPAGE_LOC { + uint8_t LocProbeRsp; + uint8_t LocPsPoll; + uint8_t LocNullData; + uint8_t LocQosNull; + uint8_t LocBTQosNull; +}; +typedef struct _RSVDPAGE_LOC RSVDPAGE_LOC_8195A; +typedef struct _RSVDPAGE_LOC *PRSVDPAGE_LOC_8195A; + +enum _RT_MEDIA_STATUS //: sint32_t +{ + RT_MEDIA_DISCONNECT = 0x0, RT_MEDIA_CONNECT = 0x1, +}; + +struct _H2CParam_RsvdPage_ { + RSVDPAGE_LOC_8195A RsvdPageLoc; + uint8_t *ReservedPagePacket; + uint32_t TotalPacketLen; +}; +typedef struct _H2CParam_RsvdPage_ H2CParam_RsvdPage; +typedef struct _H2CParam_RsvdPage_ *PH2CParam_RsvdPage; + +struct _NDIS_802_11_VARIABLE_IEs { + uint8_t ElementID; + uint8_t Length; + uint8_t data[1]; +}; +typedef struct _NDIS_802_11_VARIABLE_IEs *PNDIS_802_11_VARIABLE_IEs; + +enum _NDIS_802_11_AUTHENTICATION_MODE //: sint32_t +{ + Ndis802_11AuthModeOpen = 0x0, + Ndis802_11AuthModeShared = 0x1, + Ndis802_11AuthModeAutoSwitch = 0x2, + Ndis802_11AuthModeWPA = 0x3, + Ndis802_11AuthModeWPAPSK = 0x4, + Ndis802_11AuthModeWPANone = 0x5, + Ndis802_11AuthModeWAPI = 0x6, + Ndis802_11AuthModeMax = 0x7, +}; +typedef enum _NDIS_802_11_AUTHENTICATION_MODE NDIS_802_11_AUTHENTICATION_MODE; + +enum _NDIS_802_11_WEP_STATUS //: sint32_t +{ + Ndis802_11WEPEnabled = 0x0, + Ndis802_11Encryption1Enabled = 0x0, + Ndis802_11WEPDisabled = 0x1, + Ndis802_11EncryptionDisabled = 0x1, + Ndis802_11WEPKeyAbsent = 0x2, + Ndis802_11Encryption1KeyAbsent = 0x2, + Ndis802_11WEPNotSupported = 0x3, + Ndis802_11EncryptionNotSupported = 0x3, + Ndis802_11Encryption2Enabled = 0x4, + Ndis802_11Encryption2KeyAbsent = 0x5, + Ndis802_11Encryption3Enabled = 0x6, + Ndis802_11Encryption3KeyAbsent = 0x7, + Ndis802_11_EncrypteionWAPI = 0x8, +}; +typedef enum _NDIS_802_11_WEP_STATUS NDIS_802_11_WEP_STATUS; + +struct __attribute__((packed)) __attribute__((aligned(1))) rtk_sc { + u8 pattern_type; + u8 smac[6]; + u8 bssid[2][6]; + u8 ssid[32]; + u8 password[64]; + u32 ip_addr; + u8 sync_pkt[9][6]; + u8 profile_pkt[256][6]; + u32 profile_pkt_len; + u8 plain_buf[256]; + u32 plain_len; + u8 key_buf[32]; + u32 key_len; + u8 crypt_buf[256]; + u32 crypt_len; + s32 pattern_index; + struct pattern_ops *pattern[5]; + u8 max_pattern_num; + u8 pin[65]; + u8 default_pin[65]; + u8 have_pin; + u16 device_type; + u8 device_name[64]; + u8 bcast_crypt_buf[256]; +}; + +struct pattern_ops; + +typedef s32 (*sc_check_pattern_call_back)(struct pattern_ops *, struct rtk_sc *); +typedef s32 (*sc_get_cipher_info_call_back)(struct pattern_ops *, struct rtk_sc *); +typedef s32 (*sc_generate_key_call_back)(struct pattern_ops *, struct rtk_sc *); +typedef s32 (*sc_decode_profile_call_back)(struct pattern_ops *, struct rtk_sc *); +typedef s32 (*sc_get_tlv_info_call_back)(struct pattern_ops *, struct rtk_sc *); + +struct pattern_ops { + u32 index; + u32 flag; + u8 name[32]; + sc_check_pattern_call_back check_pattern; + sc_get_cipher_info_call_back get_cipher_info; + sc_generate_key_call_back generate_key; + sc_decode_profile_call_back decode_profile; + sc_get_tlv_info_call_back get_tlv_info; +}; + +struct _atr_aligned2_ _WL_PWR_CFG_ { // __attribute__((packed))!? + uint16_t offset; + uint8_t cut_msk; + u8 fab_msk :4; + u8 interface_msk :4; + u8 base :4; + u8 cmd :4; + uint8_t msk; + uint8_t value; +}; +typedef struct _WL_PWR_CFG_ WLAN_PWR_CFG; + +struct cmd_hdl { + uint32_t parmsize; + uint8_t (*h2cfuns)(struct _ADAPTER *, uint8_t *); +}; + +struct _cmd_callback { + uint32_t cmd_code; + void (*callback)(_adapter *, struct cmd_obj *); +}; + +enum _ODM_Common_Info_Definition //: sint32_t +{ + ODM_CMNINFO_PLATFORM = 0x0, + ODM_CMNINFO_ABILITY = 0x1, + ODM_CMNINFO_INTERFACE = 0x2, + ODM_CMNINFO_MP_TEST_CHIP = 0x3, + ODM_CMNINFO_IC_TYPE = 0x4, + ODM_CMNINFO_CUT_VER = 0x5, + ODM_CMNINFO_FAB_VER = 0x6, + ODM_CMNINFO_RF_TYPE = 0x7, + ODM_CMNINFO_RFE_TYPE = 0x8, + ODM_CMNINFO_BOARD_TYPE = 0x9, + ODM_CMNINFO_PACKAGE_TYPE = 0xA, + ODM_CMNINFO_EXT_LNA = 0xB, + ODM_CMNINFO_5G_EXT_LNA = 0xC, + ODM_CMNINFO_EXT_PA = 0xD, + ODM_CMNINFO_5G_EXT_PA = 0xE, + ODM_CMNINFO_GPA = 0xF, + ODM_CMNINFO_APA = 0x10, + ODM_CMNINFO_GLNA = 0x11, + ODM_CMNINFO_ALNA = 0x12, + ODM_CMNINFO_EXT_TRSW = 0x13, + ODM_CMNINFO_PATCH_ID = 0x14, + ODM_CMNINFO_BINHCT_TEST = 0x15, + ODM_CMNINFO_BWIFI_TEST = 0x16, + ODM_CMNINFO_SMART_CONCURRENT = 0x17, + ODM_CMNINFO_DOMAIN_CODE_2G = 0x18, + ODM_CMNINFO_DOMAIN_CODE_5G = 0x19, + ODM_CMNINFO_EEPROMVERSION = 0x1A, + ODM_CMNINFO_CRYSTALCAP = 0x1B, + ODM_CMNINFO_MAC_PHY_MODE = 0x1C, + ODM_CMNINFO_TX_UNI = 0x1D, + ODM_CMNINFO_RX_UNI = 0x1E, + ODM_CMNINFO_WM_MODE = 0x1F, + ODM_CMNINFO_BAND = 0x20, + ODM_CMNINFO_SEC_CHNL_OFFSET = 0x21, + ODM_CMNINFO_SEC_MODE = 0x22, + ODM_CMNINFO_BW = 0x23, + ODM_CMNINFO_CHNL = 0x24, + ODM_CMNINFO_FORCED_RATE = 0x25, + ODM_CMNINFO_DMSP_GET_VALUE = 0x26, + ODM_CMNINFO_BUDDY_ADAPTOR = 0x27, + ODM_CMNINFO_DMSP_IS_MASTER = 0x28, + ODM_CMNINFO_SCAN = 0x29, + ODM_CMNINFO_POWER_SAVING = 0x2A, + ODM_CMNINFO_ONE_PATH_CCA = 0x2B, + ODM_CMNINFO_DRV_STOP = 0x2C, + ODM_CMNINFO_PNP_IN = 0x2D, + ODM_CMNINFO_INIT_ON = 0x2E, + ODM_CMNINFO_ANT_TEST = 0x2F, + ODM_CMNINFO_NET_CLOSED = 0x30, + ODM_CMNINFO_MP_MODE = 0x31, + ODM_CMNINFO_FORCED_IGI_LB = 0x32, + ODM_CMNINFO_P2P_LINK = 0x33, + ODM_CMNINFO_FCS_MODE = 0x34, + ODM_CMNINFO_WIFI_DIRECT = 0x35, + ODM_CMNINFO_WIFI_DISPLAY = 0x36, + ODM_CMNINFO_LINK_IN_PROGRESS = 0x37, + ODM_CMNINFO_LINK = 0x38, + ODM_CMNINFO_STATION_STATE = 0x39, + ODM_CMNINFO_RSSI_MIN = 0x3A, + ODM_CMNINFO_DBG_COMP = 0x3B, + ODM_CMNINFO_DBG_LEVEL = 0x3C, + ODM_CMNINFO_RA_THRESHOLD_HIGH = 0x3D, + ODM_CMNINFO_RA_THRESHOLD_LOW = 0x3E, + ODM_CMNINFO_RF_ANTENNA_TYPE = 0x3F, + ODM_CMNINFO_BT_ENABLED = 0x40, + ODM_CMNINFO_BT_HS_CONNECT_PROCESS = 0x41, + ODM_CMNINFO_BT_HS_RSSI = 0x42, + ODM_CMNINFO_BT_OPERATION = 0x43, + ODM_CMNINFO_BT_LIMITED_DIG = 0x44, + ODM_CMNINFO_BT_DISABLE_EDCA = 0x45, + ODM_CMNINFO_NO_BEACON_IN_2S = 0x46, + ODM_CMNINFO_STA_STATUS = 0x47, + ODM_CMNINFO_PHY_STATUS = 0x48, + ODM_CMNINFO_MAC_STATUS = 0x49, + ODM_CMNINFO_MAX = 0x4A, +}; +typedef enum _ODM_Common_Info_Definition ODM_CMNINFO_E; + +enum _ODM_Support_Ability_Definition // : sint32_t +{ + ODM_BB_DIG = 0x1, + ODM_BB_RA_MASK = 0x2, + ODM_BB_DYNAMIC_TXPWR = 0x4, + ODM_BB_FA_CNT = 0x8, + ODM_BB_RSSI_MONITOR = 0x10, + ODM_BB_CCK_PD = 0x20, + ODM_BB_ANT_DIV = 0x40, + ODM_BB_PWR_SAVE = 0x80, + ODM_BB_PWR_TRAIN = 0x100, + ODM_BB_RATE_ADAPTIVE = 0x200, + ODM_BB_PATH_DIV = 0x400, + ODM_BB_PSD = 0x800, + ODM_BB_RXHP = 0x1000, + ODM_BB_ADAPTIVITY = 0x2000, + ODM_BB_CFO_TRACKING = 0x4000, + ODM_BB_NHM_CNT = 0x8000, + ODM_BB_PRIMARY_CCA = 0x10000, + ODM_MAC_EDCA_TURBO = 0x100000, + ODM_MAC_EARLY_MODE = 0x200000, + ODM_RF_TX_PWR_TRACK = 0x1000000, + ODM_RF_RX_GAIN_TRACK = 0x2000000, + ODM_RF_CALIBRATION = 0x4000000, +}; + +enum _RF_PATH //: sint32_t +{ + RF_PATH_A = 0x0, RF_PATH_B = 0x1, RF_PATH_C = 0x2, RF_PATH_D = 0x3, +}; +typedef enum _RF_PATH RF_PATH; + +enum _EXTCHNL_OFFSET //: sint32_t +{ + EXTCHNL_OFFSET_NO_EXT = 0x0, + EXTCHNL_OFFSET_UPPER = 0x1, + EXTCHNL_OFFSET_NO_DEF = 0x2, + EXTCHNL_OFFSET_LOWER = 0x3, +}; +typedef enum _EXTCHNL_OFFSET EXTCHNL_OFFSET; + +enum MGN_RATE //: sint32_t +{ + MGN_1M = 0x2, + MGN_2M = 0x4, + MGN_5_5M = 0xB, + MGN_6M = 0xC, + MGN_9M = 0x12, + MGN_11M = 0x16, + MGN_12M = 0x18, + MGN_18M = 0x24, + MGN_24M = 0x30, + MGN_36M = 0x48, + MGN_48M = 0x60, + MGN_54M = 0x6C, + MGN_MCS32 = 0x7F, + MGN_MCS0 = 0x80, + MGN_MCS1 = 0x81, + MGN_MCS2 = 0x82, + MGN_MCS3 = 0x83, + MGN_MCS4 = 0x84, + MGN_MCS5 = 0x85, + MGN_MCS6 = 0x86, + MGN_MCS7 = 0x87, + MGN_MCS8 = 0x88, + MGN_MCS9 = 0x89, + MGN_MCS10 = 0x8A, + MGN_MCS11 = 0x8B, + MGN_MCS12 = 0x8C, + MGN_MCS13 = 0x8D, + MGN_MCS14 = 0x8E, + MGN_MCS15 = 0x8F, + MGN_MCS16 = 0x90, + MGN_MCS17 = 0x91, + MGN_MCS18 = 0x92, + MGN_MCS19 = 0x93, + MGN_MCS20 = 0x94, + MGN_MCS21 = 0x95, + MGN_MCS22 = 0x96, + MGN_MCS23 = 0x97, + MGN_MCS24 = 0x98, + MGN_MCS25 = 0x99, + MGN_MCS26 = 0x9A, + MGN_MCS27 = 0x9B, + MGN_MCS28 = 0x9C, + MGN_MCS29 = 0x9D, + MGN_MCS30 = 0x9E, + MGN_MCS31 = 0x9F, + MGN_VHT1SS_MCS0 = 0xA0, + MGN_VHT1SS_MCS1 = 0xA1, + MGN_VHT1SS_MCS2 = 0xA2, + MGN_VHT1SS_MCS3 = 0xA3, + MGN_VHT1SS_MCS4 = 0xA4, + MGN_VHT1SS_MCS5 = 0xA5, + MGN_VHT1SS_MCS6 = 0xA6, + MGN_VHT1SS_MCS7 = 0xA7, + MGN_VHT1SS_MCS8 = 0xA8, + MGN_VHT1SS_MCS9 = 0xA9, + MGN_VHT2SS_MCS0 = 0xAA, + MGN_VHT2SS_MCS1 = 0xAB, + MGN_VHT2SS_MCS2 = 0xAC, + MGN_VHT2SS_MCS3 = 0xAD, + MGN_VHT2SS_MCS4 = 0xAE, + MGN_VHT2SS_MCS5 = 0xAF, + MGN_VHT2SS_MCS6 = 0xB0, + MGN_VHT2SS_MCS7 = 0xB1, + MGN_VHT2SS_MCS8 = 0xB2, + MGN_VHT2SS_MCS9 = 0xB3, + MGN_VHT3SS_MCS0 = 0xB4, + MGN_VHT3SS_MCS1 = 0xB5, + MGN_VHT3SS_MCS2 = 0xB6, + MGN_VHT3SS_MCS3 = 0xB7, + MGN_VHT3SS_MCS4 = 0xB8, + MGN_VHT3SS_MCS5 = 0xB9, + MGN_VHT3SS_MCS6 = 0xBA, + MGN_VHT3SS_MCS7 = 0xBB, + MGN_VHT3SS_MCS8 = 0xBC, + MGN_VHT3SS_MCS9 = 0xBD, + MGN_VHT4SS_MCS0 = 0xBE, + MGN_VHT4SS_MCS1 = 0xBF, + MGN_VHT4SS_MCS2 = 0xC0, + MGN_VHT4SS_MCS3 = 0xC1, + MGN_VHT4SS_MCS4 = 0xC2, + MGN_VHT4SS_MCS5 = 0xC3, + MGN_VHT4SS_MCS6 = 0xC4, + MGN_VHT4SS_MCS7 = 0xC5, + MGN_VHT4SS_MCS8 = 0xC6, + MGN_VHT4SS_MCS9 = 0xC7, + MGN_UNKNOWN = 0xC8, +}; + +struct _RT_CHANNEL_PLAN_2G { + uint8_t Channel[14]; + uint8_t Len; +}; +typedef struct _RT_CHANNEL_PLAN_2G RT_CHANNEL_PLAN_2G; + +struct _RT_CHANNEL_PLAN_MAP { + uint8_t ChannelPlan; + uint8_t Index2G; + uint8_t PwrLmt; +}; +typedef struct _RT_CHANNEL_PLAN_MAP RT_CHANNEL_PLAN_MAP; + +typedef int (*mac_monitor_ptr)(uint8_t *, char); + +struct mlme_handler { + uint32_t num; + uint32_t (*func)(_adapter *, struct recv_frame *); +}; + +struct fwevent { + uint32_t parmsize; + void (*event_callback)(_adapter *, uint8_t *); +}; + +struct recv_buf { + _list list; + PADAPTER adapter; + uint32_t len; + uint8_t *phead; + uint8_t *pdata; + uint8_t *ptail; + uint8_t *pend; + _pkt *pskb; +}; + +struct recv_reorder_ctrl { + _adapter *padapter; + uint8_t enable; + uint16_t indicate_seq; + uint16_t wend_b; + uint8_t wsize_b; + _queue pending_recvframe_queue; + _timer reordering_ctrl_timer; +}; + +enum _ODM_RF_RADIO_PATH // : sint32_t +{ + ODM_RF_PATH_A = 0x0, + ODM_RF_PATH_B = 0x1, + ODM_RF_PATH_C = 0x2, + ODM_RF_PATH_D = 0x3, + ODM_RF_PATH_AB = 0x4, + ODM_RF_PATH_AC = 0x5, + ODM_RF_PATH_AD = 0x6, + ODM_RF_PATH_BC = 0x7, + ODM_RF_PATH_BD = 0x8, + ODM_RF_PATH_CD = 0x9, + ODM_RF_PATH_ABC = 0xA, + ODM_RF_PATH_ACD = 0xB, + ODM_RF_PATH_BCD = 0xC, + ODM_RF_PATH_ABCD = 0xD, +}; +typedef enum _ODM_RF_RADIO_PATH ODM_RF_RADIO_PATH_E; + +enum tag_PhyDM_TRx_MUX_Type //: sint32_t +{ + PhyDM_SHUTDOWN = 0x0, + PhyDM_STANDBY_MODE = 0x1, + PhyDM_TX_MODE = 0x2, + PhyDM_RX_MODE = 0x3, +}; +typedef enum tag_PhyDM_TRx_MUX_Type PhyDM_Trx_MUX_Type; + +enum tag_PhyDM_MACEDCCA_Type //: sint32_t +{ + PhyDM_IGNORE_EDCCA = 0x0, PhyDM_DONT_IGNORE_EDCCA = 0x1, +}; +typedef enum tag_PhyDM_MACEDCCA_Type PhyDM_MACEDCCA_Type; + +enum tag_ODM_PauseDIG_Type //: sint32_t +{ + ODM_PAUSE_DIG = 0x1, ODM_RESUME_DIG = 0x2, +}; +typedef enum tag_ODM_PauseDIG_Type ODM_Pause_DIG_TYPE; + +enum tag_ODM_PauseCCKPD_Type //: sint32_t +{ + ODM_PAUSE_CCKPD = 0x1, ODM_RESUME_CCKPD = 0x2, +}; +typedef enum tag_ODM_PauseCCKPD_Type ODM_Pause_CCKPD_TYPE; + +struct _ODM_Per_Pkt_Info_ { + u1Byte DataRate; + u1Byte StationID; + BOOLEAN bPacketMatchBSSID; + BOOLEAN bPacketToSelf; + BOOLEAN bPacketBeacon; +}; +typedef struct _ODM_Per_Pkt_Info_ *PODM_PACKET_INFO_T; + +enum _HAL_STATUS //: sint32_t +{ + HAL_STATUS_SUCCESS = 0x0, HAL_STATUS_FAILURE = 0x1, +}; +typedef enum _HAL_STATUS HAL_STATUS; + +struct _ODM_Phy_Status_Info_ { + u1Byte RxPWDBAll; + u1Byte SignalQuality; + u1Byte RxMIMOSignalStrength[1]; + s1Byte RecvSignalPower; + u1Byte SignalStrength; +}; +typedef struct _ODM_Phy_Status_Info_ *PODM_PHY_INFO_T; + +enum _ODM_RF_Config_Type // : sint32_t +{ + CONFIG_RF_RADIO = 0x0, CONFIG_RF_TXPWR_LMT = 0x1, +}; +typedef enum _ODM_RF_Config_Type ODM_RF_Config_Type; + +enum _ODM_BB_Config_Type //: sint32_t +{ + CONFIG_BB_PHY_REG = 0x0, + CONFIG_BB_AGC_TAB = 0x1, + CONFIG_BB_AGC_TAB_2G = 0x2, + CONFIG_BB_AGC_TAB_5G = 0x3, + CONFIG_BB_PHY_REG_PG = 0x4, + CONFIG_BB_PHY_REG_MP = 0x5, + CONFIG_BB_AGC_TAB_DIFF = 0x6, +}; +typedef enum _ODM_BB_Config_Type ODM_BB_Config_Type; + +enum _ODM_FW_Config_Type //: sint32_t +{ + CONFIG_FW_NIC = 0x0, + CONFIG_FW_NIC_2 = 0x1, + CONFIG_FW_AP = 0x2, + CONFIG_FW_MP = 0x3, + CONFIG_FW_WoWLAN = 0x4, + CONFIG_FW_WoWLAN_2 = 0x5, + CONFIG_FW_AP_WoWLAN = 0x6, + CONFIG_FW_BT = 0x7, +}; +typedef enum _ODM_FW_Config_Type ODM_FW_Config_Type; + +enum _RATE_SECTION //: sint32_t +{ + CCK = 0x0, + OFDM = 0x1, + HT_MCS0_MCS7 = 0x2, + HT_MCS8_MCS15 = 0x3, + HT_MCS16_MCS23 = 0x4, + HT_MCS24_MCS31 = 0x5, + VHT_1SSMCS0_1SSMCS9 = 0x6, + VHT_2SSMCS0_2SSMCS9 = 0x7, + VHT_3SSMCS0_3SSMCS9 = 0x8, + VHT_4SSMCS0_4SSMCS9 = 0x9, +}; +typedef enum _RATE_SECTION RATE_SECTION; + +struct map_mask_s { + uint16_t mask_start; + uint16_t mask_end; +}; + +struct _TxPowerInfo24G { + uint8_t IndexCCK_Base[1][6]; + uint8_t IndexBW40_Base[1][6]; + int8_t OFDM_Diff[1][1]; + int8_t BW20_Diff[1][1]; +}; +typedef struct _TxPowerInfo24G TxPowerInfo24G; +typedef struct _TxPowerInfo24G *PTxPowerInfo24G; + +#endif // _WLAN_LIB_H + diff --git a/USDK/component/common/drivers/wlan/realtek/include/wifi_structures.h b/USDK/component/common/drivers/wlan/realtek/include/wifi_structures.h new file mode 100644 index 0000000..3634d8a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wifi_structures.h @@ -0,0 +1,233 @@ +/** + ****************************************************************************** + * @file wifi_structures.h + * @author + * @version + * @brief This file provides the data structures used for wlan API. + ****************************************************************************** + * @attention + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + * + * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. + ****************************************************************************** + */ + +#ifndef _WIFI_STRUCTURES_H +#define _WIFI_STRUCTURES_H + +/** @addtogroup nic NIC + * @ingroup wlan + * @brief NIC functions + * @{ + */ + +//#include +#include "wifi_constants.h" +#include "dlist.h" +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__) +#pragma pack(1) +#endif + +/** + * @brief The structure is used to describe the SSID. + */ +typedef struct rtw_ssid { + unsigned char len; /**< SSID length */ + unsigned char val[33]; /**< SSID name (AP name) */ +} rtw_ssid_t; +#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__) +#pragma pack() +#endif + +#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__) +#pragma pack(1) +#endif + +/** + * @brief The structure is used to describe the unique 6-byte MAC address. + */ +typedef struct rtw_mac { + unsigned char octet[6]; /**< Unique 6-byte MAC address */ +} rtw_mac_t; +#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__) +#pragma pack() +#endif + +/** + * @brief The structure is used to describe the setting about SSID, + * security type, password and default channel, used to start AP mode. + * @note The data length of string pointed by ssid and password should not exceed 32. + */ +typedef struct rtw_ap_info { + rtw_ssid_t ssid; + rtw_security_t security_type; + unsigned char *password; + int password_len; + int channel; +}rtw_ap_info_t; + +/** + * @brief The structure is used to describe the station mode setting about SSID, + * security type and password, used when connecting to an AP. + * @note The data length of string pointed by ssid and password should not exceed 32. + */ +typedef struct rtw_network_info { + rtw_ssid_t ssid; + rtw_mac_t bssid; + rtw_security_t security_type; + unsigned char *password; + int password_len; + int key_id; +}rtw_network_info_t; + +#if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) +#pragma pack(1) +#endif + +/** + * @brief The structure is used to describe the scan result of the AP. + */ +typedef struct rtw_scan_result { + rtw_ssid_t SSID; /**< Service Set Identification (i.e. Name of Access Point) */ + rtw_mac_t BSSID; /**< Basic Service Set Identification (i.e. MAC address of Access Point) */ + signed short signal_strength; /**< Receive Signal Strength Indication in dBm. <-90=Very poor, >-30=Excellent */ + rtw_bss_type_t bss_type; /**< Network type */ + rtw_security_t security; /**< Security type */ + rtw_wps_type_t wps_type; /**< WPS type */ + unsigned int channel; /**< Radio channel that the AP beacon was received on */ + rtw_802_11_band_t band; /**< Radio band */ +} rtw_scan_result_t; +#if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) +#pragma pack() +#endif + +/** + * @brief The structure is used to describe the data needed by scan result handler function. + */ +typedef struct rtw_scan_handler_result { + rtw_scan_result_t ap_details; + rtw_bool_t scan_complete; + void* user_data; + +} rtw_scan_handler_result_t; + +#if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) +#pragma pack(1) +#endif + +/** + * @brief The structure is used to store the WIFI setting gotten from WIFI driver. + */ +typedef struct rtw_wifi_setting { + rtw_mode_t mode; + unsigned char ssid[33]; + unsigned char channel; + rtw_security_t security_type; + unsigned char password[65]; + unsigned char key_idx; +}rtw_wifi_setting_t; +#if defined(__IAR_SYSTEMS_ICC__) || defined(__GNUC__) +#pragma pack() +#endif + +/** + * @brief The structure is used to describe the setting when configure the network. + */ +typedef struct rtw_wifi_config { + unsigned int boot_mode; + unsigned char ssid[32]; + unsigned char ssid_len; + unsigned char security_type; + unsigned char password[65]; + unsigned char password_len; + unsigned char channel; +} rtw_wifi_config_t; + +/** + * @brief The structure is used to describe the maclist. + */ +typedef struct +{ + unsigned int count; /**< Number of MAC addresses in the list */ + rtw_mac_t mac_list[1]; /**< Variable length array of MAC addresses */ +} rtw_maclist_t; + +/** + * @brief The structure is used to describe the bss info of the network.\n + * It include the version, BSSID, beacon_period, capability, SSID, + * channel, atm_window, dtim_period, RSSI e.g. + */ +typedef struct { + unsigned int version; /**< version field */ + unsigned int length; /**< byte length of data in this record, */ + /* starting at version and including IEs */ + rtw_mac_t BSSID; + unsigned short beacon_period; /**< units are Kusec */ + unsigned short capability; /**< Capability information */ + unsigned char SSID_len; + unsigned char SSID[32]; + unsigned char channel; +// struct { +// uint32_t count; /* # rates in this set */ +// uint8_t rates[16]; /* rates in 500kbps units w/hi bit set if basic */ +// } rateset; /* supported rates */ +// rtw_chanspec_t chanspec; /* chanspec for bss */ + unsigned short atim_window; /**< units are Kusec */ + unsigned char dtim_period; /**< DTIM period */ + signed short RSSI; /**< receive signal strength (in dBm) */ + + unsigned char n_cap; /**< BSS is 802.11N Capable */ + unsigned int nbss_cap; /**< 802.11N BSS Capabilities (based on HT_CAP_*) */ + unsigned char basic_mcs[MCSSET_LEN]; /**< 802.11N BSS required MCS set */ + + unsigned short ie_offset; /**< offset at which IEs start, from beginning */ + unsigned int ie_length; /**< byte length of Information Elements */ +} rtw_bss_info_t; + +/** + * @brief The structure is used to set WIFI packet filter pattern. + */ +typedef struct { + unsigned short offset; /**< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */ + unsigned short mask_size; /**< Size of the mask in bytes */ + unsigned char* mask; /**< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */ + unsigned char* pattern; /**< Pattern bytes used to filter eg. "\x0800" (must be in network byte order) */ +} rtw_packet_filter_pattern_t; + +typedef struct ieee80211_frame_info{ + unsigned short i_fc; + unsigned short i_dur; + unsigned char i_addr1[6]; + unsigned char i_addr2[6]; + unsigned char i_addr3[6]; + unsigned short i_seq; + unsigned char bssid[6]; + unsigned char encrypt; + signed char rssi; +}ieee80211_frame_info_t; + +typedef struct { + char filter_id; + rtw_packet_filter_pattern_t patt; + rtw_packet_filter_rule_t rule; + unsigned char enable; +}rtw_packet_filter_info_t; + +typedef struct rtw_mac_filter_list{ + struct list_head node; + unsigned char mac_addr[6]; +}rtw_mac_filter_list_t; + +#ifdef __cplusplus +} +#endif + +/*\@}*/ + +#endif /* _WIFI_STRUCTURES_H */ diff --git a/USDK/component/common/drivers/wlan/realtek/include/wlan_basic_types.h b/USDK/component/common/drivers/wlan/realtek/include/wlan_basic_types.h new file mode 100644 index 0000000..f7bd19f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wlan_basic_types.h @@ -0,0 +1,610 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __WLAN_BASIC_TYPES_H__ +#define __WLAN_BASIC_TYPES_H__ + + +/* ================================================ + * Sections (1) rtl8195a and (2) other MCU based wlan driver + * For 8195a, some of the definitions are already defined in system wise "basic_types.h" + *================================================ */ +#define _SUCCESS 1 +#define _PASS 1 +#define _FAIL 0 + +//ERRNO Define +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + + +#define ENSROK 0 /* DNS server returned answer with no data */ +#define ENSRNODATA 160 /* DNS server returned answer with no data */ +#define ENSRFORMERR 161 /* DNS server claims query was misformatted */ +#define ENSRSERVFAIL 162 /* DNS server returned general failure */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */ +#define ENSRREFUSED 165 /* DNS server refused query */ +#define ENSRBADQUERY 166 /* Misformatted DNS query */ +#define ENSRBADNAME 167 /* Misformatted domain name */ +#define ENSRBADFAMILY 168 /* Unsupported address family */ +#define ENSRBADRESP 169 /* Misformatted DNS reply */ +#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */ +#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */ +#define ENSROF 172 /* End of file */ +#define ENSRFILE 173 /* Error reading file */ +#define ENSRNOMEM 174 /* Out of memory */ +#define ENSRDESTRUCTION 175 /* Application terminated lookup */ +#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */ +#define ENSRCNAMELOOP 177 /* Domain name is too long */ + + + + + + + +/* ================================================ + * Sections only for other MCU based wlan driver + *========================================== ======*/ + #if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#include + +#define SUCCESS 0 +#define FAIL (-1) + +#ifndef TRUE + #define _TRUE 1 +#else + #define _TRUE TRUE +#endif + +#ifndef FALSE + #define _FALSE 0 +#else + #define _FALSE FALSE +#endif + +// +// pack & weak attribute +// +#if defined (__ICCARM__) + +#define RTW_PACK_STRUCT_BEGIN +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END +#define RTW_PACK_STRUCT_USE_INCLUDES + +#define RTW_WEAK __weak + +#elif defined (__CC_ARM) + +#define RTW_PACK_STRUCT_BEGIN __packed +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END + +#define RTW_WEAK __weak + +#elif defined (__GNUC__) + +#define RTW_PACK_STRUCT_BEGIN +#define RTW_PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define RTW_PACK_STRUCT_END + +#define RTW_WEAK __attribute__ ((weak)) + +#elif defined(PLATFORM_WINDOWS) + +#define RTW_PACK_STRUCT_BEGIN +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END +#define RTW_PACK_STRUCT_USE_INCLUDES +#endif + +#ifndef BIT + #define BIT(x) ((u32)1 << (x)) +#endif + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 +#define BIT32 0x0100000000 +#define BIT33 0x0200000000 +#define BIT34 0x0400000000 +#define BIT35 0x0800000000 +#define BIT36 0x1000000000 +#endif + + +#ifdef PLATFORM_ECOS + + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + typedef unsigned int uint; + typedef signed int sint; + + #ifndef PVOID + typedef void * PVOID; + #endif + + + typedef unsigned int __kernel_size_t; + typedef int __kernel_ssize_t; + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + + +#ifdef PLATFORM_WINDOWS + + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed long s32; + typedef unsigned long u32; + + typedef unsigned int uint; + typedef signed int sint; + + + typedef signed long long s64; + typedef unsigned long long u64; + + #ifdef NDIS50_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 0 + + #endif + + #ifdef NDIS51_MINIPORT + + #define NDIS_MAJOR_VERSION 5 + #define NDIS_MINOR_VERSION 1 + + #endif + + typedef NDIS_PROC proc_t; + + typedef LONG atomic_t; + +#endif + + +#ifdef PLATFORM_LINUX + + #include + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + typedef signed int sint; + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + + typedef void (*proc_t)(void*); + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + + +#ifdef PLATFORM_FREEBSD + typedef signed char s8; + typedef unsigned char u8; + + typedef signed short s16; + typedef unsigned short u16; + + typedef signed int s32; + typedef unsigned int u32; + + typedef unsigned int uint; + typedef signed int sint; + typedef long atomic_t; + + typedef signed long long s64; + typedef unsigned long long u64; + #define IN + #define OUT + #define VOID void + #define NDIS_OID uint + #define NDIS_STATUS uint + + #ifndef PVOID + typedef void * PVOID; + //#define PVOID (void *) + #endif + typedef u32 dma_addr_t; + + typedef void (*proc_t)(void*); + + typedef unsigned int __kernel_size_t; + typedef int __kernel_ssize_t; + + typedef __kernel_size_t SIZE_T; + typedef __kernel_ssize_t SSIZE_T; + #define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#endif + + +#define MEM_ALIGNMENT_OFFSET (sizeof (SIZE_T)) +#define MEM_ALIGNMENT_PADDING (sizeof(SIZE_T) - 1) + +#define SIZE_PTR SIZE_T +#define SSIZE_PTR SSIZE_T + +//port from fw by thomas +// TODO: Belows are Sync from SD7-Driver. It is necessary to check correctness + +/* + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. +*/ + +// +// Byte Swapping routine. +// +#define EF1Byte +#define EF2Byte le16_to_cpu +#define EF4Byte le32_to_cpu + +// +// Read LE format data from memory +// +#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr))) +#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr))) +#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr))) + +// +// Write LE data to memory +// +#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr)))=EF1Byte(_val) +#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr)))=EF2Byte(_val) +#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr)))=EF4Byte(_val) + +// +// Example: +// BIT_LEN_MASK_32(0) => 0x00000000 +// BIT_LEN_MASK_32(1) => 0x00000001 +// BIT_LEN_MASK_32(2) => 0x00000003 +// BIT_LEN_MASK_32(32) => 0xFFFFFFFF +// +#define BIT_LEN_MASK_32(__BitLen) \ + (0xFFFFFFFF >> (32 - (__BitLen))) +// +// Example: +// BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +// BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 +// +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) + +// +// Description: +// Return 4-byte value in host byte ordering from +// 4-byte pointer in litten-endian system. +// +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + (EF4Byte(*((u32 *)(__pStart)))) + +// +// Description: +// Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to +// 4-byte value in host byte ordering. +// +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_32(__BitLen) \ + ) + +// +// Description: +// Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering +// and return the result in 4-byte value in host byte ordering. +// +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \ + ) + +// +// Description: +// Set subfield of little-endian 4-byte value to specified value. +// +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u32 *)(__pStart)) = \ + EF4Byte( \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \ + ); + + +#define BIT_LEN_MASK_16(__BitLen) \ + (0xFFFF >> (16 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_16(__BitLen) << (__BitOffset)) + +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + (EF2Byte(*((u16 *)(__pStart)))) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_16(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u16 *)(__pStart)) = \ + EF2Byte( \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \ + ); + +#define BIT_LEN_MASK_8(__BitLen) \ + (0xFF >> (8 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_8(__BitLen) << (__BitOffset)) + +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + (EF1Byte(*((u8 *)(__pStart)))) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_8(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u8 *)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \ + ); + +//pclint +#define LE_BITS_CLEARED_TO_1BYTE_8BIT(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + ) + +//pclint +#define SET_BITS_TO_LE_1BYTE_8BIT(__pStart, __BitOffset, __BitLen, __Value) \ +{ \ + *((u8*)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE_8BIT(__pStart, __BitOffset, __BitLen) \ + | \ + ((u8)__Value) \ + ); \ +} + +// Get the N-bytes aligment offset from the current length +#define N_BYTE_ALIGMENT(__Value, __Aligment) ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / __Aligment) * __Aligment)) + +typedef unsigned char BOOLEAN,*PBOOLEAN; + +#define TEST_FLAG(__Flag,__testFlag) (((__Flag) & (__testFlag)) != 0) + + + +#endif//! defined(CONFIG_PLATFORM_8195A) + +#endif //__WLAN_BASIC_TYPES_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/wlan_bssdef.h b/USDK/component/common/drivers/wlan/realtek/include/wlan_bssdef.h new file mode 100644 index 0000000..2c86f31 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wlan_bssdef.h @@ -0,0 +1,756 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __WLAN_BSSDEF_H__ +#define __WLAN_BSSDEF_H__ + + +#define MAX_IE_SZ 768 //384// + +#if defined(PLATFORM_LINUX) || defined(PLATFORM_ECOS) || defined(PLATFORM_FREERTOS) || defined(PLATFORM_CMSIS_RTOS) +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef u32 NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + u32 SsidLength; + u8 Ssid[NDIS_802_11_LENGTH_SSID+4]; +} +#ifdef __CC_ARM +__attribute__((packed)) +#endif +NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + u32 Length; // Length of structure + u32 HopPattern; // As defined by 802.11, MSB set + u32 HopSet; // to one if non-802.11 + u32 DwellTime; // units are Kusec +} +#ifdef __CC_ARM +__attribute__((packed)) +#endif +NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + u32 Length; // Length of structure + u32 BeaconPeriod; // units are Kusec + u32 ATIMWindow; // units are Kusec + u32 DSConfig; // Frequency, units are kHz + NDIS_802_11_CONFIGURATION_FH FHConfig; +} +#ifdef __CC_ARM +__attribute__((packed)) +#endif +NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + u8 Timestamp[8]; + u16 BeaconInterval; + u16 Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + u8 ElementID; + u8 Length; + u8 data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (u32) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + u32 Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + u8 Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + u32 Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + u32 IELength; + u8 IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + u32 NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeWAPI, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent, + Ndis802_11_EncrypteionWAPI +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + u16 Capabilities; + u16 ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + u16 Capabilities; + u16 StatusCode; + u16 AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + u32 Length; + u16 AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + u32 RequestIELength; + u32 OffsetRequestIEs; + u16 AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + u32 ResponseIELength; + u32 OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + u32 Length; // Length of this structure + u32 KeyIndex; + u32 KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + u8 KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + u32 Length; // Length of this structure + u32 KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + u32 Length; // Length of this structure + u32 KeyIndex; // 0 is the per-client key, 1-N are the global keys + u32 KeyLength; // length of key in bytes + u8 KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + u32 Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + u32 Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + u32 Length; + u32 Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //end of #ifdef PLATFORM_LINUX + +#ifdef PLATFORM_FREEBSD + +#define NDIS_802_11_LENGTH_SSID 32 +#define NDIS_802_11_LENGTH_RATES 8 +#define NDIS_802_11_LENGTH_RATES_EX 16 + +typedef unsigned char NDIS_802_11_MAC_ADDRESS[6]; +typedef long NDIS_802_11_RSSI; // in dBm +typedef unsigned char NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates +typedef unsigned char NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates + + +typedef u32 NDIS_802_11_KEY_INDEX; +typedef unsigned long long NDIS_802_11_KEY_RSC; + + +typedef struct _NDIS_802_11_SSID +{ + u32 SsidLength; + u8 Ssid[32]; +} NDIS_802_11_SSID, *PNDIS_802_11_SSID; + +typedef enum _NDIS_802_11_NETWORK_TYPE +{ + Ndis802_11FH, + Ndis802_11DS, + Ndis802_11OFDM5, + Ndis802_11OFDM24, + Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE; + +typedef struct _NDIS_802_11_CONFIGURATION_FH +{ + u32 Length; // Length of structure + u32 HopPattern; // As defined by 802.11, MSB set + u32 HopSet; // to one if non-802.11 + u32 DwellTime; // units are Kusec +} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH; + + +/* + FW will only save the channel number in DSConfig. + ODI Handler will convert the channel number to freq. number. +*/ +typedef struct _NDIS_802_11_CONFIGURATION +{ + u32 Length; // Length of structure + u32 BeaconPeriod; // units are Kusec + u32 ATIMWindow; // units are Kusec + u32 DSConfig; // Frequency, units are kHz + NDIS_802_11_CONFIGURATION_FH FHConfig; +} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION; + + + +typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE +{ + Ndis802_11IBSS, + Ndis802_11Infrastructure, + Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax, // Not a real value, defined as upper bound + Ndis802_11APMode +} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE; + + + + + +typedef struct _NDIS_802_11_FIXED_IEs +{ + u8 Timestamp[8]; + u16 BeaconInterval; + u16 Capabilities; +} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs; + + + +typedef struct _NDIS_802_11_VARIABLE_IEs +{ + u8 ElementID; + u8 Length; + u8 data[1]; +} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs; + + + +/* + + + +Length is the 4 bytes multiples of the sume of + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 + sizeof (NDIS_802_11_SSID) + sizeof (u32) ++ sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) + sizeof (NDIS_802_11_CONFIGURATION) ++ sizeof (NDIS_802_11_RATES_EX) + IELength + +Except the IELength, all other fields are fixed length. Therefore, we can define a marco to present the +partial sum. + +*/ +#if 0 +typedef struct _NDIS_WLAN_BSSID_EX +{ + u32 Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + u8 Reserved[2];//[0]: IS beacon frame, [1]:optimum_antenna=>For antenna diversity; + NDIS_802_11_SSID Ssid; + u32 Privacy; + NDIS_802_11_RSSI Rssi; + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + u32 IELength; + u8 IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX; + + +typedef struct _NDIS_802_11_BSSID_LIST_EX +{ + u32 NumberOfItems; + NDIS_WLAN_BSSID_EX Bssid[1]; +} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX; +#endif + +typedef enum _NDIS_802_11_AUTHENTICATION_MODE +{ + Ndis802_11AuthModeOpen, + Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, + Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, + Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeMax // Not a real mode, defined as upper bound +} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE; + +typedef enum _NDIS_802_11_WEP_STATUS +{ + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, + Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, + Ndis802_11Encryption3KeyAbsent +} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS, + NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS; + + +#define NDIS_802_11_AI_REQFI_CAPABILITIES 1 +#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2 +#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4 + +#define NDIS_802_11_AI_RESFI_CAPABILITIES 1 +#define NDIS_802_11_AI_RESFI_STATUSCODE 2 +#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4 + +typedef struct _NDIS_802_11_AI_REQFI +{ + u16 Capabilities; + u16 ListenInterval; + NDIS_802_11_MAC_ADDRESS CurrentAPAddress; +} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; + +typedef struct _NDIS_802_11_AI_RESFI +{ + u16 Capabilities; + u16 StatusCode; + u16 AssociationId; +} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; + +typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION +{ + u32 Length; + u16 AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + u32 RequestIELength; + u32 OffsetRequestIEs; + u16 AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + u32 ResponseIELength; + u32 OffsetResponseIEs; +} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; + +typedef enum _NDIS_802_11_RELOAD_DEFAULTS +{ + Ndis802_11ReloadWEPKeys +} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS; + + +// Key mapping keys require a BSSID +typedef struct _NDIS_802_11_KEY +{ + u32 Length; // Length of this structure + u32 KeyIndex; + u32 KeyLength; // length of key in bytes + NDIS_802_11_MAC_ADDRESS BSSID; + NDIS_802_11_KEY_RSC KeyRSC; + u8 KeyMaterial[32]; // variable length depending on above field +} NDIS_802_11_KEY, *PNDIS_802_11_KEY; + +typedef struct _NDIS_802_11_REMOVE_KEY +{ + u32 Length; // Length of this structure + u32 KeyIndex; + NDIS_802_11_MAC_ADDRESS BSSID; +} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY; + +typedef struct _NDIS_802_11_WEP +{ + u32 Length; // Length of this structure + u32 KeyIndex; // 0 is the per-client key, 1-N are the global keys + u32 KeyLength; // length of key in bytes + u8 KeyMaterial[16];// variable length depending on above field +} NDIS_802_11_WEP, *PNDIS_802_11_WEP; + +typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST +{ + u32 Length; // Length of structure + NDIS_802_11_MAC_ADDRESS Bssid; + u32 Flags; +} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST; + +typedef enum _NDIS_802_11_STATUS_TYPE +{ + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusTypeMax // not a real type, defined as an upper bound +} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE; + +typedef struct _NDIS_802_11_STATUS_INDICATION +{ + NDIS_802_11_STATUS_TYPE StatusType; +} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION; + +// mask for authentication/integrity fields +#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f +#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 +#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 +#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 +#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E + +// MIC check time, 60 seconds. +#define MIC_CHECK_TIME 60000000 + +typedef struct _NDIS_802_11_AUTHENTICATION_EVENT +{ + NDIS_802_11_STATUS_INDICATION Status; + NDIS_802_11_AUTHENTICATION_REQUEST Request[1]; +} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT; + +typedef struct _NDIS_802_11_TEST +{ + u32 Length; + u32 Type; + union + { + NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent; + NDIS_802_11_RSSI RssiTrigger; + }tt; +} NDIS_802_11_TEST, *PNDIS_802_11_TEST; + + +#endif //PLATFORM_FREEBSD + +typedef struct _WLAN_PHY_INFO +{ + u8 SignalStrength; //(in percentage) + u8 SignalQuality; //(in percentage) + u8 Optimum_antenna; //for Antenna diversity + u8 Reserved_0; +} +#ifdef __CC_ARM +__attribute__((packed)) +#endif +WLAN_PHY_INFO,*PWLAN_PHY_INFO; + +typedef struct _WLAN_BCN_INFO +{ + /* these infor get from rtw_get_encrypt_info when + * * translate scan to UI */ + u8 encryp_protocol; //ENCRYP_PROTOCOL_E: OPEN/WEP/WPA/WPA2/WAPI + int group_cipher; //WPA/WPA2 group cipher + int pairwise_cipher; //WPA/WPA2/WEP pairwise cipher + int is_8021x; + + /* bwmode 20/40 and ch_offset UP/LOW */ + unsigned short ht_cap_info; + unsigned char ht_info_infos_0; +} WLAN_BCN_INFO,*PWLAN_BCN_INFO; + +/* temporally add #pragma pack for structure alignment issue of +* WLAN_BSSID_EX and get_WLAN_BSSID_EX_sz() +*/ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +typedef struct _WLAN_BSSID_EX +{ + u32 Length; + NDIS_802_11_MAC_ADDRESS MacAddress; + #ifdef CONFIG_P2P_NEW + u8 Reserved[1]; //[0]: IS beacon frame + u8 bP2pNetwork; + #else + u8 Reserved[2]; //[0]: IS beacon frame (padapter+163) + #endif + NDIS_802_11_SSID Ssid; + u32 Privacy; + NDIS_802_11_RSSI Rssi; //(in dBM,raw data ,get from PHY) + NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; + NDIS_802_11_CONFIGURATION Configuration; + NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; + NDIS_802_11_RATES_EX SupportedRates; + WLAN_PHY_INFO PhyInfo; + u32 IELength; + u8 IEs[MAX_IE_SZ]; //(timestamp, beacon interval, and capability information) +} +RTW_PACK_STRUCT_STRUCT +WLAN_BSSID_EX, *PWLAN_BSSID_EX; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + + +__inline static uint get_WLAN_BSSID_EX_sz(WLAN_BSSID_EX *bss) +{ +#if 0 + uint t_len; + + t_len = sizeof (u32) + + sizeof (NDIS_802_11_MAC_ADDRESS) + + 2 + + sizeof (NDIS_802_11_SSID) + + sizeof (u32) + + sizeof (NDIS_802_11_RSSI) + + sizeof (NDIS_802_11_NETWORK_TYPE) + + sizeof (NDIS_802_11_CONFIGURATION) + + sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) + + sizeof (NDIS_802_11_RATES_EX) + //all new member add here + + sizeof(WLAN_PHY_INFO) + //all new member add here + + sizeof (u32) + + bss->IELength; + return t_len; +#else + return (sizeof(WLAN_BSSID_EX) -MAX_IE_SZ + bss->IELength); +#endif +} + +struct wlan_network { + _list list; + int network_type; //refer to ieee80211.h for WIRELESS_11A/B/G + int fixed; // set to fixed when not to be removed as site-surveying + unsigned long last_scanned; //timestamp for the network + int aid; //will only be valid when a BSS is joinned. + int join_res; + WLAN_BSSID_EX network; //must be the last item + WLAN_BCN_INFO BcnInfo; +#ifdef PLATFORM_WINDOWS + unsigned char iebuf[MAX_IE_SZ]; +#endif + +}; + +enum VRTL_CARRIER_SENSE +{ + DISABLE_VCS, + ENABLE_VCS, + AUTO_VCS +}; + +enum VCS_TYPE +{ + NONE_VCS, + RTS_CTS, + CTS_TO_SELF +}; + + + + +#define PWR_CAM 0 +#define PWR_MINPS 1 +#define PWR_MAXPS 2 +#define PWR_UAPSD 3 +#define PWR_VOIP 4 + + +enum UAPSD_MAX_SP +{ + NO_LIMIT, + TWO_MSDU, + FOUR_MSDU, + SIX_MSDU +}; + + +#define NUM_PRE_AUTH_KEY 16 +#define NUM_PMKID_CACHE NUM_PRE_AUTH_KEY + +/* +* WPA2 +*/ + +#ifndef PLATFORM_OS_CE +typedef struct _PMKID_CANDIDATE { + NDIS_802_11_MAC_ADDRESS BSSID; + u32 Flags; +} PMKID_CANDIDATE, *PPMKID_CANDIDATE; + +typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST +{ + u32 Version; // Version of the structure + u32 NumCandidates; // No. of pmkid candidates + PMKID_CANDIDATE CandidateList[1]; +} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST; + + +typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION +{ + NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; + NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; + +} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION; + +typedef struct _NDIS_802_11_CAPABILITY +{ + u32 Length; + u32 Version; + u32 NoOfPMKIDs; + u32 NoOfAuthEncryptPairsSupported; + NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1]; + +} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY; +#endif + + +#endif //#ifndef WLAN_BSSDEF_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/include/wlan_lib.h b/USDK/component/common/drivers/wlan/realtek/include/wlan_lib.h new file mode 100644 index 0000000..33364c2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/include/wlan_lib.h @@ -0,0 +1,1759 @@ +/* + wlan_lib.h + RTL871x pvvx +*/ +#ifndef _WIFI_LIB_H +#define _WIFI_LIB_H + +//#include "wifi_constants.h" +//#include "wifi_structures.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wireless.h" +#include "wifi_lib.h" + +// rom_rtw_message.o +//-------------------------------- +// freertos_ioctl.o +// Function declarations +extern int rtw_wx_set_autoreconnect(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_get_autoreconnect(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_forwarding_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_set_ch_deauth(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int get_priv_size(int args); +extern int rtw_wx_del_custome_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_set_pscan_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_update_custome_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_set_tos_value(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_get_tx_power(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_set_custome_ie(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_pm_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_pm_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_read32(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_write32(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_set_freq(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_ex_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wdata, char *extra); +extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra); +extern void indicate_wx_custom_event(_adapter *padapter, char *msg); +extern void indicate_wx_scan_result_present(uint64_t padapter, uint64_t a2); +extern void indicate_wx_scan_complete_event(uint64_t padapter, uint64_t a2); +extern void rtw_indicate_sta_assoc(uint64_t padapter, uint64_t buf); +extern void rtw_indicate_sta_disassoc(_adapter *padapter, uint8_t *addr); +extern void rtw_indicate_wx_assoc_event(uint64_t padapter, uint64_t a2); +extern void rtw_indicate_wx_disassoc_event(uint64_t padapter, uint64_t a2); +extern int rtw_set_wpa_ie(_adapter *padapter, char *pie, int ielen); +extern void strtopsk(uint8_t *des, uint8_t *src, int len); +extern int rtw_wx_get_passphrase(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra); +extern int rtw_wx_set_ap_essid(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra); +extern void mac_reg_dump(_adapter *padapter); +extern void bb_reg_dump(_adapter *padapter); +extern void rf_reg_dump(_adapter *padapter); // , int a2, int a3); +extern int rtw_dbg_port(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +extern int rtw_get_auto_channel(struct net_device *dev, u8 *channel_set, int channel_num); +extern int rtw_set_sta_num(int ap_sta_num); +extern int rtw_del_sta(struct net_device *dev, u8 *sta_addr); +extern int rtw_ex_get_drv_ability(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrqu, char *extra); +extern int rtw_ex_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wdata, char *extra); +extern void *rtw_ioctl(struct net_device *dev, struct iwreq *rq, int cmd); +// Data declarations +extern u8 g_user_ap_sta_num; // = 5u; +extern const struct iw_priv_args rtw_private_args[26]; /* = +{ + { 35808u, 10239u, 0u, "write" }, + { 35809u, 10239u, 10256u, "read" }, + { 35819u, 10239u, 0u, "dbg" }, + { 35830u, 8256u, 0u, "pm_set" }, + { 35831u, 8256u, 0u, "pm_get" }, + { 35840u, 10239u, 0u, "PartialScan" }, + { 35841u, 10239u, 0u, "SetAutoRecnt" }, + { 35842u, 10239u, 10239u, "GetAutoRecnt" }, + { 35843u, 26623u, 0u, "SetCusIE" }, + { 35844u, 26623u, 0u, "UpdateIE" }, + { 35845u, 0u, 0u, "DelIE" }, + { 35846u, 8193u, 0u, "forwarding_set" }, + { 35847u, 10239u, 10239u, "get_tx_power" }, + { 35848u, 10239u, 0u, "set_tos_value" }, + { 35849u, 8193u, 0u, "SetChDeauth" }, + { 35822u, 9216u, 0u, "" }, + { 35823u, 9216u, 10239u, "" }, + { 0u, 9216u, 0u, "write_mac" }, + { 1u, 9216u, 0u, "set_ch_plan" }, + { 2u, 9216u, 10239u, "read_mac" }, + { 3u, 9216u, 10239u, "txpower" }, + { 4u, 9216u, 10239u, "get_client_list" }, + { 5u, 9216u, 10239u, "get_ap_info" }, + { 6u, 9216u, 10239u, "get_security" }, + { 8u, 9216u, 10239u, "get_drv_ability" }, + { 9u, 9216u, 10239u, "get_ch_plan" } +}; */ +extern iw_handler rtw_private_handler[17]; /* = +{ + (iw_handler)0x58D, + (iw_handler)0x4E1, + (iw_handler)0xD59, + (iw_handler)0x42D, + (iw_handler)0x3E9, + (iw_handler)0xE5, + (iw_handler)5, + (iw_handler)0x33, + (iw_handler)0x33D, + (iw_handler)0x167, + (iw_handler)0x99, + (iw_handler)0x41, + (iw_handler)0x1F9, + (iw_handler)0x1D9, + (iw_handler)0x63, + (iw_handler)0x699, + (iw_handler)0x165D +}; */ +extern char iw_priv_type_size[8]; // = { '\0', '\x01', '\x01', '\0', '\x04', '\b', '\x10', '\0' }; +//-------------------------------- +// freertos_intfs.o +// Function declarations +extern struct net_device_stats *rtw_net_get_stats(struct net_device *pnetdev); +extern int netdev_if2_close(struct net_device *pnetdev); +extern int netdev_close(struct net_device *pnetdev); +extern void rtw_if1_deinit(PADAPTER if1); +extern void rtw_reset_securitypriv(_adapter *adapter); +extern void rtw_os_indicate_disconnect(_adapter *adapter); +extern int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); +extern struct net_device *rtw_init_netdev(_adapter *old_padapter); +extern int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *)); +extern _adapter *rtw_drv_if2_init(_adapter *primary_padapter, char *name, void (*set_intf_ops)(struct _io_ops *)); +extern void rtw_drv_if2_stop(_adapter *if2); +extern void rtw_drv_if2_free(_adapter *primary_padapter); +extern init_done_ptr netdev_open(struct net_device *pnetdev); +extern int netdev_if2_open(struct net_device *pnetdev); +extern int netdev_if2_open(struct net_device *pnetdev); +extern init_done_ptr netdev_open(struct net_device *pnetdev); +extern struct net_device *rtw_drv_probe(struct net_device *parent_dev, uint32_t mode); +extern int rtw_dev_remove(struct net_device *pnetdev); +extern void rtw_drv_entry(); +extern void rtw_drv_halt(); +// Data declarations +extern init_done_ptr p_wlan_init_done_callback; +extern uint8_t rtw_power_percentage_idx; +extern init_done_ptr p_wlan_uart_adapter_callback; +extern uint8_t rtw_adaptivity_en; +extern uint8_t rtw_adaptivity_mode; +extern int8_t rtw_adaptivity_th_l2h_ini; +extern drv_priv drvpriv; +//-------------------------------- +// hal_com.o +extern void dump_chip_info(int a1, int a2, int a3, int a4, HAL_VERSION ChipVersion); +extern int hal_com_get_channel_plan(_adapter *padapter, uint8_t hw_channel_plan, int sw_channel_plan, int def_channel_plan, BOOLEAN AutoLoadFail); +extern int HAL_IsLegalChannel(_adapter *Adapter, uint32_t Channel); +extern int MRateToHwRate(uint8_t rate); +extern signed int HwRateToMRate(uint8_t rate); +extern void HalSetBrateCfg(_adapter *Adapter, uint8_t *mBratesOS, uint16_t *pBrateCfg); +extern signed int Hal_MappingOutPipe(_adapter *pAdapter, uint8_t NumOutPipe); +extern void hal_init_macaddr(_adapter *adapter); +extern void hw_var_port_switch(_adapter *adapter); +extern void SetHwReg(PADAPTER padapter, int variable, uint8_t *val); +extern signed int eqNByte(uint8_t *str1, uint8_t *str2, uint32_t num); +extern signed int GetU1ByteIntegerFromStringInDecimal(char *Str, uint8_t *pInt); +extern void switch_power_saving_mode(_adapter *padapter, int benable); +extern void rtw_bb_rf_gain_offset(_adapter *padapter); +// Data declarations +extern u8 CSWTCH_15[132]; +extern u8 CSWTCH_17[19]; +//-------------------------------- +// HalHWImg8195A_MAC.o +// Function declarations +extern void ODM_ReadAndConfig_MP_8195A_MAC_REG(PDM_ODM_T pDM_Odm); +extern signed int ODM_GetVersion_MP_8195A_MAC_REG(); // return 26; +// Data declarations +extern u32 Array_MP_8195A_MAC_REG[194]; +//-------------------------------- +// HalHWImg8195A_RF.o +// Function declarations +extern signed int CheckPositive(PDM_ODM_T pDM_Odm, const u4Byte Condition1, const u4Byte Condition2, const u4Byte Condition3, const u4Byte Condition4); +extern void ODM_ReadAndConfig_MP_8195A_RadioA(PDM_ODM_T pDM_Odm); +extern signed int ODM_GetVersion_MP_8195A_RadioA(); +extern void ODM_ReadAndConfig_MP_8195A_RADIO_DIFF(PDM_ODM_T pDM_Odm, u4Byte *Array, u4Byte ArrayLen, u4Byte a4); +extern signed int ODM_GetVersion_MP_8195A_RADIO_DIFF(); +extern void ODM_ReadAndConfig_MP_8195A_TxPowerTrack_QFN48(PDM_ODM_T pDM_Odm); +extern void ODM_ReadAndConfig_MP_8195A_TxPowerTrack_QFN56(PDM_ODM_T pDM_Odm); +extern void ODM_ReadAndConfig_MP_8195A_TxPowerTrack_TFBGA96(PDM_ODM_T pDM_Odm); +extern void ODM_ReadAndConfig_MP_8195A_TXPWR_LMT(PDM_ODM_T pDM_Odm); +extern void ODM_ReadAndConfig_MP_8195A_TxXtalTrack(PDM_ODM_T pDM_Odm); +// Data declarations +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_TFBGA96_8195A[32]; +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_TFBGA96_8195A[32]; +extern u8 gDeltaSwingTableXtal_MP_N_TxXtalTrack_8195A[30]; +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_QFN56_8195A[30]; +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_N_TxPowerTrack_QFN48_8195A[30]; +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_QFN56_8195A[30]; +extern const u8 Array_MP_8195A_TXPWR_LMT[1176]; +extern u8 gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_QFN56_8195A[30]; +extern u32 Array_MP_8195A_RadioA[370]; +extern u8 gDeltaSwingTableXtal_MP_P_TxXtalTrack_8195A[30]; +extern u8 gDeltaSwingTableIdx_MP_2GA_P_TxPowerTrack_TFBGA96_8195A[32]; +extern u8 gDeltaSwingTableIdx_MP_2GCCKA_P_TxPowerTrack_QFN48_8195A[30]; +//-------------------------------- +// HalPhyRf_8195A.o +// Function declarations +extern void GetDeltaSwingTable_8195A(PDM_ODM_T pDM_Odm, ps1Byte *TemperatureUP_A, ps1Byte *TemperatureDOWN_A, ps1Byte *TemperatureUP_B, ps1Byte *TemperatureDOWN_B); +extern void GetDeltaSwingXtalTable_8195A(PDM_ODM_T pDM_Odm, ps1Byte *TemperatureUP_Xtal, ps1Byte *TemperatureDOWN_Xtal); +extern void ODM_TxXtalTrackSetXtal_8195A(PDM_ODM_T pDM_Odm); +extern void setIqkMatrix_8195A(PDM_ODM_T pDM_Odm, int OFDM_index, int RFPath, s4Byte IqkResult_X, s4Byte IqkResult_Y); +extern void Hal_MPT_CCKTxPowerAdjust(PADAPTER Adapter); +extern void ODM_TxPwrTrackSetPwr_8195A(PDM_ODM_T pDM_Odm, PWRTRACK_METHOD Method, int RFPath, u8 ChannelMappedIndex); +extern void ConfigureTxpowerTrack_8195A(PTXPWRTRACK_CFG pConfig); +extern int phy_PathA_IQK_8195A(PADAPTER pAdapter, BOOLEAN configPathB); +extern signed int phy_PathA_RxIQK8195A(PADAPTER pAdapter, BOOLEAN configPathB); +extern int phy_PathB_IQK_8195A(PADAPTER pAdapter); +extern signed int phy_PathB_RxIQK8195A(PADAPTER pAdapter, BOOLEAN configPathB); +extern void PHY_PathAFillIQKMatrix8195A(PADAPTER pAdapter, int bIQKOK, s4Byte (*result)[8], int final_candidate, BOOLEAN bTxOnly); +extern void PHY_PathBFillIQKMatrix8195A(PADAPTER pAdapter, int bIQKOK, s4Byte (*result)[8], int final_candidate, BOOLEAN bTxOnly); +extern signed int ODM_CheckPowerStatus(PADAPTER Adapter); +extern void PHY_SaveADDARegisters8195A(PADAPTER pAdapter, pu4Byte ADDAReg, pu4Byte ADDABackup, u4Byte RegisterNum); +extern void PHY_SaveMACRegisters8195A(PADAPTER pAdapter, pu4Byte MACReg, pu4Byte MACBackup); +extern void PHY_ReloadADDARegisters8195A(PADAPTER pAdapter, pu4Byte ADDAReg, pu4Byte ADDABackup, u4Byte RegiesterNum); +extern void PHY_ReloadMACRegisters8195A(PADAPTER pAdapter, pu4Byte MACReg, pu4Byte MACBackup); +extern void PHY_PathADDAOn8195A(PADAPTER pAdapter, pu4Byte ADDAReg, BOOLEAN isPathAOn, int is2T); +extern void PHY_MACSettingCalibration8195A(PADAPTER pAdapter, pu4Byte MACReg, pu4Byte MACBackup); +extern void PHY_PathAStandBy8195A(PADAPTER pAdapter); +extern void PHY_PIModeSwitch8195A(PADAPTER pAdapter, int PIMode); +extern signed int phy_SimularityCompare_8195A(PADAPTER pAdapter, s4Byte (*result)[8], int c1, int c2); +extern void phy_IQCalibrate_8195A(PADAPTER pAdapter, s4Byte (*result)[8], int t, int is2T); +extern void phy_LCCalibrate_8195A(PDM_ODM_T pDM_Odm, BOOLEAN is2T); +extern void PHY_LCCalibrate_8195A(PDM_ODM_T pDM_Odm); +extern void PHY_IQCalibrate_8195A(PADAPTER pAdapter, int bReCovery, int bRestore); +extern void DoIQK_8195A(PDM_ODM_T pDM_Odm, u8 DeltaThermalIndex, u8 ThermalValue, u8 Threshold); +extern void phy_SetRFPathSwitch_8195A(PADAPTER pAdapter, int bMain, BOOLEAN is2T); +extern void PHY_SetRFPathSwitch_8195A(PADAPTER pAdapter, int bMain); +//-------------------------------- +// rtk_wlan_if.o +// Function declarations +extern void timer_wrapper(_timerHandle timer_hdl); +extern struct net_device *alloc_etherdev(int sizeof_priv); +extern void free_netdev(struct net_device *dev); +extern int dev_alloc_name(struct net_device *net_dev, const char *ifname); +extern void init_timer_wrapper(); +extern void deinit_timer_wrapper(); +extern void init_timer(struct timer_list *timer); +extern void mod_timer(struct timer_list *timer, uint32_t delay_time_ms); +extern BOOL timer_pending(const struct timer_list *timer); +extern void cancel_timer_ex(struct timer_list *timer); +extern void del_timer_sync(struct timer_list *timer); +extern void rtw_init_timer(_timer *ptimer, void *adapter, TIMER_FUN pfunc, void *cntx, const char *name); +extern u8 rtw_cancel_timer(_timer *ptimer); +extern BOOL rltk_get_idx_bydev(struct net_device *dev); +extern int rltk_wlan_init(int idx_wlan, rtw_mode_t mode); +extern void rltk_wlan_deinit(); +extern int rltk_wlan_start(int idx_wlan); +extern int rltk_wlan_check_isup(int idx); +extern void rltk_wlan_tx_inc(int idx); +extern void rltk_wlan_tx_dec(int idx); +extern struct sk_buff *rltk_wlan_get_recv_skb(int idx); +extern struct sk_buff *rltk_wlan_alloc_skb(unsigned int total_len); +extern void rltk_wlan_send_skb(int idx, struct sk_buff *skb); +extern void rltk_netif_rx(struct sk_buff *skb); +extern int rltk_del_station(const char *ifname, u8 *hwaddr); +extern int rltk_get_auto_chl(const char *ifname, u8 *channel_set, int channel_num); +extern int rltk_set_tx_power_percentage(rtw_tx_pwr_percentage_t power_percentage_idx); +extern int rltk_wlan_control(unsigned long cmd, void *data); +extern unsigned char rltk_wlan_running(unsigned char idx); +extern void rltk_wlan_statistic(unsigned char idx); +extern int rltk_wlan_handshake_done(); +extern int rltk_wlan_rf_on(); +extern int rltk_wlan_rf_off(); +extern int rltk_wlan_check_bus(); +extern int rltk_wlan_wireless_mode(u8 mode); +extern int rltk_wlan_set_wps_phase(unsigned char is_trigger_wps); +extern void rltk_wlan_PRE_SLEEP_PROCESSING(); +extern int rltk_wlan_is_connected_to_ap(); +extern int rtw_ps_enable(int enable); +extern int rltk_wifi_fw_test(int argc, char **argv); +// Data declarations +extern _list timer_table; +extern Rltk_wlan_t rltk_wlan_info[2]; // in wrapper.h +extern int timer_used_num; +extern int max_timer_used_num; +//-------------------------------- +// rtl8195a_cmd.o +// Function declarations +extern int32_t FillH2CCmd8195A(PADAPTER padapter, int ElementID, uint64_t CmdLen); +extern void rtl8195a_set_FwRsvdPage_cmd(PADAPTER padapter, PH2CParam_RsvdPage pRsvdPage); +extern void rtl8195a_set_FwMediaStatusRpt_cmd(PADAPTER padapter, int mstatus, int macid); +extern void rtl8195a_set_FwMacIdConfig_cmd(_adapter *padapter, int mac_id, int raid, int bw, uint8_t sgi, uint32_t mask); +extern void rtl8195a_set_FwPwrMode_cmd(PADAPTER padapter, int psmode); +extern void rtl8195a_download_rsvd_page(PADAPTER padapter, int mstatus); +extern void rtl8195a_set_FwJoinBssRpt_cmd(PADAPTER padapter, int mstatus); +extern void rtl8195a_Add_RateATid(PADAPTER pAdapter, uint32_t bitmap, uint8_t *arg_ary, int rssi_level); +extern PADAPTER rtl8195a_set_BcnIgnoreEDCCA_cmd(PADAPTER result, int enable, int a3); +//-------------------------------- +// rtl8195a_rf6052.o +// Function declarations +extern int PHY_ConfigRFWithTxPwrTrackParaFile(PADAPTER Adapter, char *pFileName); +extern void PHY_RF6052SetBandwidth8195A(PADAPTER Adapter, CHANNEL_WIDTH Bandwidth); +extern int PHY_RF6052_Config8195A(PADAPTER Adapter); +//-------------------------------- +// rtw_efuse.o +// Function declarations +extern void Efuse_PowerSwitch(PADAPTER pAdapter, uint8_t bWrite, uint8_t PwrState); +extern int Efuse_GetCurrentSize(PADAPTER pAdapter, uint8_t efuseType, BOOLEAN bPseudoTest); +extern int Efuse_CalculateWordCnts(uint8_t word_en); +extern void EFUSE_GetEfuseDefinition(PADAPTER pAdapter, int efuseType, uint8_t type, void *pOut, BOOLEAN bPseudoTest); +extern int efuse_OneByteRead(PADAPTER pAdapter, int addr, uint8_t *data, int bPseudoTest); +extern int efuse_read8(PADAPTER padapter, int address, uint8_t *value); +extern int efuse_OneByteWrite(PADAPTER pAdapter, int addr, int data, int bPseudoTest); +extern int efuse_write8(PADAPTER padapter, int address, uint8_t *value); +extern int Efuse_PgPacketWrite(PADAPTER pAdapter, int offset, int word_en, uint8_t *data, BOOLEAN bPseudoTest); +extern void efuse_WordEnableDataRead(uint8_t word_en, uint8_t *sourdata, uint8_t *targetdata); +extern int Efuse_WordEnableDataWrite(PADAPTER pAdapter, int efuse_addr, uint8_t word_en, uint8_t *data, BOOLEAN bPseudoTest); +extern int rtw_efuse_access(PADAPTER padapter, int bWrite, int start_addr, int cnts, uint8_t *data); +extern signed int efuse_GetCurrentSize(PADAPTER padapter, uint16_t *size); +extern signed int rtw_efuse_map_read(PADAPTER padapter, int addr, int cnts, uint8_t *data); +extern signed int rtw_efuse_map_write(PADAPTER padapter, int addr, int cnts, uint8_t *data); +extern void Efuse_ReadAllMap(PADAPTER pAdapter, int efuseType, uint8_t *Efuse, BOOLEAN bPseudoTest); +extern void EFUSE_ShadowRead(PADAPTER pAdapter, int Type, int Offset, uint32_t *Value); +extern void EFUSE_ShadowMapUpdate(PADAPTER pAdapter, int efuseType, BOOLEAN bPseudoTest, int a4); +//-------------------------------- +// rtw_ieee80211.o +// Function declarations +extern void rtw_macaddr_cfg(uint8_t *mac_addr, int a2); +extern int rtw_get_cipher_info(struct wlan_network *pnetwork); +extern void rtw_get_bcn_info(struct wlan_network *pnetwork); +//-------------------------------- +// rtw_wlan_util.o +// Function declarations +extern int cckrates_included(u8 *rate, int ratelen); +extern int cckratesonly_included(u8 *rate, int ratelen); +extern signed int networktype_to_raid_ex(PADAPTER padapter, int network_type); +extern signed int judge_network_type(_adapter *padapter, u8 *rate, int ratelen); +extern int ratetbl_val_2wifirate(u8 rate); +extern int is_basicrate(_adapter *padapter, int rate); +extern int ratetbl2rateset(_adapter *padapter, u8 *rateset); +extern void get_rate_set(_adapter *padapter, u8 *pbssrate, int *bssrate_len, int a4); +extern void UpdateBrateTbl(PADAPTER Adapter, uint8_t *mBratesOS); +extern void UpdateBrateTblForSoftAP(uint8_t *bssrateset, uint32_t bssratelen); +extern void Save_DM_Func_Flag(_adapter *padapter, int a2, int a3); +extern void Restore_DM_Func_Flag(_adapter *padapter); +extern void Switch_DM_Func(_adapter *padapter, uint32_t mode, int enable); +extern void Set_MSR(_adapter *padapter, uint8_t type); +extern int set_opmode(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +extern void SelectChannel(_adapter *padapter, int channel); +extern void SetBWMode(_adapter *padapter, int bwmode, int channel_offset); +extern void set_channel_bwmode(_adapter *padapter, int channel, int channel_offset, int bwmode); +extern uint8_t *get_my_bssid(WLAN_BSSID_EX *pnetwork); +extern int get_beacon_interval(WLAN_BSSID_EX *bss, int a2, int a3); +extern int is_client_associated_to_ap(int result); +extern BOOL is_client_associated_to_ibss(_adapter *padapter); +extern int is_IBSS_empty(_adapter *padapter); +extern unsigned int decide_wait_for_beacon_timeout(unsigned int bcn_interval); +extern void invalidate_cam_all(_adapter *padapter); +extern void write_cam(_adapter *padapter, uint8_t entry, int ctrl, uint8_t *mac, uint8_t *key); +extern void clear_cam_entry(_adapter *padapter, uint8_t entry); +extern void flush_all_cam_entry(_adapter *padapter); +extern int WMM_param_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +extern void WMMOnAssocRsp(_adapter *padapter); +extern void HT_caps_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +extern void HT_info_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +extern void HTOnAssocRsp(_adapter *padapter); +extern void ERP_IE_handler(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE); +extern void VCS_update(_adapter *padapter, struct sta_info *psta); +extern int rtw_check_bcn_info(_adapter *Adapter, uint8_t *pframe, uint32_t packet_len); +extern void update_beacon_info(_adapter *padapter, uint8_t *pframe, unsigned int pkt_len, struct sta_info *psta); +extern signed int is_ap_in_tkip(_adapter *padapter); +extern int wifirate2_ratetbl_inx(u8 rate); +extern int update_basic_rate(u8 *ptn, unsigned int ptn_sz); +extern int update_supported_rate(u8 *ptn, unsigned int ptn_sz); +extern int update_MCS_rate(struct HT_caps_element *pHT_caps); +extern int support_short_GI(_adapter *padapter, struct HT_caps_element *pHT_caps); +extern int get_highest_rate_idx(uint32_t mask); +extern void Update_RA_Entry(_adapter *padapter, struct sta_info *psta); +extern void enable_rate_adaptive(_adapter *padapter, struct sta_info *psta); +extern void set_sta_rate(_adapter *padapter, struct sta_info *psta); +extern void update_tx_basic_rate(_adapter *padapter, int wirelessmode); +extern signed int check_assoc_AP(uint8_t *pframe, unsigned int len); +extern void update_IOT_info(_adapter *padapter); +extern void update_capinfo(PADAPTER Adapter, uint16_t updateCap); +extern void update_wireless_mode(_adapter *padapter, uint32_t a2, int a3); +extern void update_bmc_sta_support_rate(_adapter *padapter, uint32_t mac_id); +extern void update_TSF(struct mlme_ext_priv *pmlmeext, uint8_t *pframe, unsigned int len); +extern void correct_TSF(_adapter *padapter, struct mlme_ext_priv *pmlmeext); +// Data declarations +extern u8 CSWTCH_36[12]; // = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; +extern const uint8_t ARTHEROS_OUI1[3]; // = { 0u, 3u, 127u }; +extern const uint8_t ARTHEROS_OUI2[3]; // = { 0u, 19u, 116u }; +extern const uint8_t REALTEK_OUI[3]; // = { 0u, 224u, 76u }; +extern const uint8_t RALINK_OUI[3]; // = { 0u, 12u, 67u }; +extern const uint8_t MARVELL_OUI[3]; // = { 0u, 80u, 67u }; +extern const uint8_t CISCO_OUI[3]; // = { 0u, 64u, 150u }; +extern const uint8_t rtw_basic_rate_cck[4]; // = { 130u, 132u, 139u, 150u }; +extern const uint8_t BROADCOM_OUI1[3]; // = { 0u, 16u, 24u }; +extern const uint8_t BROADCOM_OUI2[3]; // = { 0u, 10u, 247u }; +extern const uint8_t rtw_basic_rate_mix[7]; // = { 130u, 132u, 139u, 150u, 140u, 152u, 176u }; +extern const uint8_t rtw_basic_rate_ofdm[3]; // = { 140u, 152u, 176u }; +extern const uint8_t AIRGOCAP_OUI[3]; // = { 0u, 10u, 245u }; +//-------------------------------- +// wifi_simple_config_parser.o +// Function declarations +extern s32 bytecopy(u8 *src, u8 *dst, u32 len); +extern s32 rtk_sc_register_pattern(struct pattern_ops *pp); +extern s32 rtk_sc_generate_key(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 rtk_sc_decode_profile(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 rtk_sc_get_tlv_info(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 mcast_udp_get_cipher_info(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 mcast_udp_get_pattern(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 bcast_udp_get_pattern(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 bcast_udp_get_cipher_info(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 rtk_clean_profile_value(); +extern s32 mcast_udp_decode_profile(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 mcast_udp_generate_key(struct pattern_ops *pp, struct rtk_sc *pSc); +extern s32 rtk_sc_check_packet(u8 *da, u8 *bssid, s32 length); +extern void whc_fix_channel(); +extern void whc_unfix_channel(); +extern void simple_config_lib_init(struct simple_config_lib_config *config); +extern void simple_config_lib_deinit(); +extern int parse_tlv_info_bcast(struct rtk_sc *pSc, u8 *plain_info, int len); +extern s32 mcast_udp_get_profile(struct pattern_ops *pp, struct rtk_sc *pSc); +extern void rtk_restart_simple_config(); +extern void rtk_stop_simple_config(); +extern s32 rtk_sc_init(char *custom_pin_code, struct simple_config_lib_config *lib_config); +extern void rtk_sc_deinit(); +extern int rtk_sc_check_profile(struct pattern_ops *pp, struct rtk_sc *pSc, void *backup_sc_ctx); +extern signed int softAP_simpleConfig_parse(u8 *buf, int len, void *backup_sc_ctx, void *psoftAP_ctx); +extern int rtl_pre_parse(u8 *mac_addr, u8 *buf, void *userdata, u8 **da, u8 **sa, unsigned int *len); +extern s32 rtk_start_parse_packet(u8 *da, u8 *sa, s32 len, void *user_data, void *backup_sc_ctx); +// Data declarations +// Data declarations +extern char algn_1; // weak +extern const u8 default_key_iv[8]; // = { 166u, 166u, 166u, 166u, 166u, 166u, 166u, 166u }; +extern struct pattern_ops udp_bcast; /* = +{ + 4u, 10u, + { + 115u, 99u, 95u, 98u, 99u, 97u, 115u, 116u, 95u, 117u, + 100u, 112u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u + }, + (sc_check_pattern_call_back)0x20D, + (sc_get_cipher_info_call_back)0x2C9, + (sc_generate_key_call_back)0x3B5, + (sc_decode_profile_call_back)0x389, + (sc_get_tlv_info_call_back)0x62D +}; */ +extern u8 g_bssid[6]; +extern s32 simple_config_status; +extern u8 g_ios_mac[6]; // = { 2u, 0u, 0u, 0u, 0u, 0u }; +extern u8 use_ios7_mac; +extern u8 *custom_pin; +extern struct pattern_ops udp_mcast_pin; /* = +{ + 3u, 10u, + { + 115u, 99u, 95u, 109u, 99u, 97u, 115u, 116u, 95u, 117u, + 100u, 112u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u + }, + (sc_check_pattern_call_back)0x95, + (sc_get_cipher_info_call_back)0x6B, + (sc_generate_key_call_back)0x3B5, + (sc_decode_profile_call_back)0x389, + (sc_get_tlv_info_call_back)0x62D +}; */ +extern struct pattern_ops udp_bcast_pin; /* = +{ + 5u, 10u, + { + 115u, 99u, 95u, 98u, 99u, 97u, 115u, 116u, 95u, 117u, 100u, + 112u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u + }, + (sc_check_pattern_call_back)0x20D, + (sc_get_cipher_info_call_back)0x2C9, + (sc_generate_key_call_back)0x3B5, + (sc_decode_profile_call_back)0x389, + (sc_get_tlv_info_call_back)0x62D +}; */ +extern u8 get_channel_flag; +extern u8 g_security_mode; // = 255u; +extern u8 radom_value[4]; +extern s32 profile_pkt_index; +extern const u8 default_pin[9]; // = { 53u, 55u, 50u, 56u, 57u, 57u, 54u, 49u, 0u }; +extern const u8 sc_device_name[21]; /* = +{ + 115u, 105u, 109u, 112u, 108u, 101u, 95u, 99u, 111u, 110u, 102u, 105u, 103u, + 95u, 99u, 108u, 105u, 101u, 110u, 116u, 0u +}; */ +extern struct simple_config_lib_config sc_api_fun; +extern u8 fix_sa; +extern u32 g_sc_pin_len; +extern struct pattern_ops *pp; +extern struct pattern_ops udp_mcast; /* = +{ + 2u, 10u, + { + 115u, 99u, 95u, 109u, 99u, 97u, 115u, 116u, 95u, 117u, 100u, + 112u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, + 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u + }, + (sc_check_pattern_call_back)0x95, + (sc_get_cipher_info_call_back)0x6B, + (sc_generate_key_call_back)0x3B5, + (sc_decode_profile_call_back)0x389, + (sc_get_tlv_info_call_back)0x62D +}; */ +extern s32 sync_pkt_index; +extern const u8 mcast_udp_buffer[65]; /* = +{ + 56u, 67u, 109u, 84u, 47u, 32u, 74u, 40u, 51u, 95u, 97u, 69u, 32u, 82u, 95u, + 85u, 70u, 82u, 125u, 96u, 109u, 116u, 119u, 70u, 61u, 41u, 81u, 102u, 106u, 116u, + 110u, 94u, 83u, 95u, 49u, 47u, 102u, 102u, 103u, 60u, 95u, 67u, 55u, 121u, 119u, + 39u, 115u, 125u, 63u, 39u, 95u, 39u, 110u, 38u, 50u, 126u, 66u, 108u, 109u, 38u, + 95u, 107u, 63u, 54u, 0u +}; */ +extern struct rtk_sc *g_sc_ctx; +//-------------------------------- +// wlan_ram_map.o +// Function declarations +extern void init_rom_wlan_ram_map(); +//-------------------------------- +// freertos_isr.o +// Function declarations +extern void rtw_interrupt_thread(thread_context context); +// Data declarations +extern _sema *pExportWlanIrqSemaphore; + +//-------------------------------- +// freertos_recv.o +// Function declarations +extern int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter); +extern int rtw_os_recv_resource_alloc(_adapter *padapter, struct recv_frame *precvframe); +extern int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +extern int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); +extern int rtw_tkip_countermeasure(_adapter *padapter); +extern void rtw_handle_tkip_mic_err(_adapter *padapter, int bgroup); +extern int rtw_recv_indicatepkt(_adapter *padapter, struct recv_frame *precv_frame); +extern void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); + +//-------------------------------- +// freertos_skbuff.o +// Function declarations +extern void skb_fail_inc(int a1); +extern int skb_fail_get_and_rst(int a1); +extern void init_skb_pool(); +extern void init_skb_data_pool(); +extern struct sk_buff *alloc_skb(int size); +extern void kfree_skb(struct sk_buff *skb); +extern u8 *skb_put(struct sk_buff *skb, unsigned int len); +extern void skb_reserve(struct sk_buff *skb, unsigned int len); +extern struct sk_buff *dev_alloc_skb(unsigned int length, unsigned int reserve_len); +extern void skb_assign_buf(struct sk_buff *skb, u8 *buf, unsigned int len); +extern u8 *skb_tail_pointer(const struct sk_buff *skb); +extern u8 *skb_end_pointer(const struct sk_buff *skb); +extern void skb_set_tail_pointer(struct sk_buff *skb, const int offset); +extern u8 *skb_pull(struct sk_buff *skb, unsigned int len); +extern struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask, unsigned int reserve_len); +extern struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask); +// Data declarations +extern int skbbuf_used_num; +extern struct list_head skbdata_list; +/* +// skbuff.h, wifi_skbuf.c, rtw_opt_skbuf.c +struct skb_buf { + struct list_head list; + struct sk_buff skb; +}; + +struct skb_data { + struct list_head list; + unsigned char buf[MAX_SKB_BUF_SIZE]; + atomic_t ref; +}; +extern struct skb_data skb_data_pool[8]; +extern struct skb_buf skb_pool[10]; +*/ +extern int skbdata_used_num; +extern int max_local_skb_num; // = 10; +extern struct list_head wrapper_skbbuf_list; +extern int max_skbdata_used_num; +extern int max_skbbuf_used_num; +extern int skb_fail_count; +extern int max_skb_buf_num; // = 8; +//-------------------------------- +// freertos_xmit.o +// Function declarations +extern signed int rtw_remainder_len(struct pkt_file *pfile); +extern void rtw_open_pktfile(_pkt *pktptr, struct pkt_file *pfile); +extern unsigned int rtw_pktfile_read(struct pkt_file *pfile, uint8_t *rmem, unsigned int rlen); +extern BOOL rtw_endofpktfile(struct pkt_file *pfile); +extern int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf, uint32_t alloc_sz); +extern void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt); +extern void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe); +extern void rtw_os_xmit_schedule(_adapter *padapter, _irqL a2, int a3); +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev, int a3); +extern int rtw_os_can_xmit(struct net_device *dev); +//-------------------------------- +// hal_intf.o +// Function declarations +extern int32_t rtw_hal_fill_h2c_cmd(int32_t result, uint8_t ElementID, uint32_t CmdLen, uint8_t *pCmdBuffer); +extern void rtw_hal_fill_fake_txdesc(_adapter *padapter, uint8_t *pDesc, uint32_t BufferLen, uint8_t IsPsPoll, uint8_t IsBTQosNull, uint8_t bDataFrame); +extern _adapter *rtw_hal_get_txbuff_rsvd_page_num(_adapter *result, bool wowlan); +extern void rtw_hal_chip_configure(_adapter *padapter); +extern void rtw_hal_read_chip_info(_adapter *padapter); +extern void rtw_hal_read_chip_version(_adapter *padapter); +extern void rtw_hal_def_value_init(_adapter *padapter); +extern void rtw_hal_free_data(_adapter *padapter); +extern void rtw_hal_dm_init(_adapter *padapter); +extern void rtw_hal_dm_deinit(_adapter *padapter); +extern int rtw_hal_init(_adapter *padapter); +extern int rtw_hal_deinit(_adapter *padapter); +extern void rtw_hal_set_hwreg(_adapter *padapter, uint8_t variable, uint8_t *val); +extern void rtw_hal_get_hwreg(_adapter *padapter, uint8_t variable, uint8_t *val); +extern int rtw_hal_set_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); +extern int rtw_hal_get_def_var(_adapter *padapter, HAL_DEF_VARIABLE eVariable, PVOID pValue); +extern void rtw_hal_set_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); +extern void rtw_hal_get_odm_var(_adapter *padapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); +extern void rtw_hal_enable_interrupt(_adapter *padapter); +extern void rtw_hal_disable_interrupt(_adapter *padapter); +extern int rtw_hal_inirp_init(_adapter *padapter); +extern int rtw_hal_inirp_deinit(_adapter *padapter); +extern void rtw_hal_irp_reset(_adapter *padapter); +extern int32_t rtw_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +extern int32_t rtw_hal_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); +extern int32_t rtw_hal_init_xmit_priv(_adapter *padapter); +extern void rtw_hal_free_xmit_priv(_adapter *padapter); +extern int32_t rtw_hal_init_recv_priv(_adapter *padapter); +extern void rtw_hal_free_recv_priv(_adapter *padapter); +extern void rtw_hal_update_ra_mask(struct sta_info *psta, uint8_t rssi_level); +extern void rtw_hal_add_ra_tid(_adapter *padapter, uint32_t bitmap, uint8_t *arg, uint8_t rssi_level); +extern void rtw_hal_update_txdesc(_adapter *padapter, struct xmit_frame *pxmitframe, uint8_t *pbuf); +extern void rtw_hal_clone_data(_adapter *dst_padapter, _adapter *src_padapter); +extern void rtw_hal_start_thread(_adapter *padapter); +extern void rtw_hal_stop_thread(_adapter *padapter); +extern int rtw_hal_read_bbreg(_adapter *padapter, uint32_t RegAddr, uint32_t BitMask); +extern void rtw_hal_write_bbreg(_adapter *padapter, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern int rtw_hal_read_rfreg(_adapter *padapter, uint32_t eRFPath, uint32_t RegAddr, uint32_t BitMask); +extern void rtw_hal_write_rfreg(_adapter *padapter, uint32_t eRFPath, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern int32_t rtw_hal_interrupt_handler(_adapter *padapter); +extern void rtw_hal_set_bwmode(_adapter *padapter, CHANNEL_WIDTH Bandwidth, uint8_t Offset); +extern void rtw_hal_set_chan(_adapter *padapter, uint8_t channel); +extern void rtw_hal_set_chnl_bw(_adapter *padapter, int channel, CHANNEL_WIDTH Bandwidth, uint8_t Offset40, uint8_t Offset80); +extern void rtw_hal_dm_watchdog(_adapter *padapter); +extern int32_t rtw_hal_recv_tasklet(_adapter *padapter); +extern int32_t rtw_hal_macid_sleep(PADAPTER padapter, int macid, int a3); +extern int32_t rtw_hal_macid_wakeup(PADAPTER padapter, int macid, int a3); +extern void decide_chip_type_by_device_id(_adapter *padapter); +//-------------------------------- +// hal_phy.o +// Function declarations +extern uint32_t PHY_RFShadowRead(_adapter *Adapter, int eRFPath, uint32_t Offset); +extern void PHY_RFShadowWrite(_adapter *Adapter, int eRFPath, uint32_t Offset, uint32_t Data); +extern int PHY_RFShadowCompare(_adapter *Adapter, int eRFPath, uint32_t Offset); +extern void PHY_RFShadowRecorver(_adapter *Adapter, int eRFPath, uint32_t Offset); +extern void PHY_RFShadowCompareAll(_adapter *Adapter); +extern void PHY_RFShadowRecorverAll(_adapter *Adapter); +extern void PHY_RFShadowCompareFlagSet(_adapter *Adapter, int eRFPath, uint32_t Offset, uint8_t Type); +extern void PHY_RFShadowRecorverFlagSet(_adapter *Adapter, int eRFPath, uint32_t Offset, uint8_t Type); +extern void PHY_RFShadowCompareFlagSetAll(_adapter *Adapter); +extern void PHY_RFShadowRecorverFlagSetAll(_adapter *Adapter); +extern void PHY_RFShadowRefresh(_adapter *Adapter); +// Data declarations +extern RF_SHADOW_T RF_Shadow[2][255]; +//-------------------------------- +// Hal8195ARateAdaptive.o +// Function declarations +extern void ODM_InitRAInfo(PDM_ODM_T pDM_Odm); +extern signed int PT_Mode_Sel(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo, int rate_idx); +extern void InitialRateUpdate(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo, int rate, int trybit, u8 BW); +extern unsigned int RateUp_search_RateMask(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo, u8 init_rate_idx); +extern int RateDown_search_RateMask(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo, u8 init_rate_idx, int mod_step); +extern void StartRateByRSSI(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern signed int b64QamRate(int rate_idx, int Up_Down); +extern void RateUpRAM8195A(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern void RateDownTrying(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern void TryDone(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern void RateDownStepRAM8195A(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo, int step); +extern void RateDecisionRAM8195A(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern void ArfrRefresh(PDM_ODM_T pDM_Odm, PODM_RA_INFO_T pRaInfo); +extern void H2CHDL_Set_MACID_Config(PDM_ODM_T pDM_Odm, u8 *pbuf); +extern void PHY_DM_RA_SetRSSI_8195A(PDM_ODM_T pDM_Odm, int MacID, u8 Rssi); +// Data declarations +extern u8 Noisy_State; +extern u8 ARFB_table[9][7]; /* = +{ + { 21u, 240u, 255u, 15u, 0u, 0u, 0u }, + { 21u, 240u, 15u, 0u, 0u, 0u, 0u }, + { 5u, 240u, 255u, 15u, 0u, 0u, 0u }, + { 5u, 240u, 15u, 0u, 0u, 0u, 0u }, + { 16u, 240u, 255u, 15u, 0u, 0u, 0u }, + { 16u, 240u, 15u, 0u, 0u, 0u, 0u }, + { 245u, 15u, 0u, 0u, 0u, 0u, 0u }, + { 240u, 15u, 0u, 0u, 0u, 0u, 0u }, + { 15u, 0u, 0u, 0u, 0u, 0u, 0u } +}; */ +extern u8 TRYING_NECESSARY_idx[20]; /* = +{ + 1u, 1u, 1u, 2u, 1u, 2u, 3u, 3u, 4u, 4u, 5u, + 5u, 2u, 4u, 6u, 7u, 7u, 8u, 8u, 8u +}; */ +extern u8 DROPING_NECESSARY[20]; /* = +{ + 1u, 1u, 1u, 1u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, + 8u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u +}; */ +extern u8 PER_RATE_UP[20]; /* = +{ + 10u, 10u, 10u, 10u, 20u, 20u, 10u, 10u, 2u, 2u, + 2u, 2u, 20u, 20u, 10u, 10u, 1u, 2u, 2u, 4u +}; */ +extern u8 PER_RATE_DOWN[20]; /* = +{ + 100u, 50u, 50u, 50u, 40u, 47u, 29u, 36u, 31u, 24u, + 7u, 10u, 40u, 45u, 35u, 30u, 33u, 25u, 11u, 10u +}; */ +//-------------------------------- +// HalPhyRf.o +// Function declarations +extern void ConfigureTxpowerTrack(PDM_ODM_T pDM_Odm, PTXPWRTRACK_CFG pConfig); +extern void ODM_ClearTxPowerTrackingState(PDM_ODM_T pDM_Odm); +extern void ODM_TXPowerTrackingCallback_ThermalMeter(PADAPTER Adapter); +extern void ODM_ResetIQKResult(PDM_ODM_T pDM_Odm); +extern int ODM_GetRightChnlPlaceforIQK(int chnl); +// Data declarations +//-------------------------------- +// HalPwrSeqCmd.o +// Function declarations +extern signed int HalPwrSeqCmdParsing(_adapter *padapter, uint8_t CutVersion, uint8_t FabVersion, int InterfaceType, WLAN_PWR_CFG *PwrSeqCmd); +// Data declarations +//-------------------------------- +// hci_intfs.o +// Function declarations +extern struct dvobj_priv *hci_dvobj_init(); +extern void hci_dvobj_deinit(struct dvobj_priv *dvobj); +extern void hci_dvobj_request_irq(struct dvobj_priv *dvobj); +extern void hci_dvobj_free_irq(struct dvobj_priv *dvobj); +// Data declarations +//-------------------------------- +// rtw_ioctl_set.o +// Function declarations +extern int rtw_do_join(_adapter *padapter, _irqL a2); +extern int rtw_set_802_11_bssid(_adapter *padapter, uint8_t *bssid); +extern int rtw_set_802_11_ssid(_adapter *padapter, NDIS_802_11_SSID *ssid, int a3); +extern signed int rtw_set_802_11_infrastructure_mode(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +extern signed int rtw_set_802_11_bssid_list_scan(_adapter *padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +extern int rtw_set_802_11_authentication_mode(_adapter *padapter, struct NDIS_802_11_AUTHENTICATION_MODE authmode); +extern int rtw_set_802_11_add_wep(_adapter *padapter, NDIS_802_11_WEP *wep); +// Data declarations +//-------------------------------- +// rtw_io.o +// Function declarations +extern int rtw_read8(_adapter *adapter, uint32_t addr); +extern int rtw_read16(_adapter *adapter, uint32_t addr); +extern int rtw_read32(_adapter *adapter, uint32_t addr); +extern int32_t rtw_write8(_adapter *adapter, uint32_t addr, int val); +extern int32_t rtw_write16(_adapter *adapter, uint32_t addr, int val); +extern int32_t rtw_write32(_adapter *adapter, uint32_t addr, uint32_t val); +extern signed int rtw_read_port(_adapter *adapter, uint32_t addr, uint32_t cnt, uint8_t *mem, struct fifo_more_data *more_data); +extern signed int rtw_write_port(_adapter *adapter, uint32_t addr, uint32_t cnt, uint8_t *mem); +extern void rtw_set_chip_endian(_adapter *adapter); +extern int rtw_get_chip_endian(_adapter padapter); +// Data declarations +//-------------------------------- +// rtw_cmd.o +// Function declarations +extern sint rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); +extern sint rtw_init_evt_priv(struct evt_priv *pevtpriv); +extern void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv); +extern sint rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj); +extern struct cmd_obj *rtw_dequeue_cmd(_queue *queue, _irqL a2, int a3); +extern struct list_head *rtw_observequeue_cmd(_queue *queue); +extern signed int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv); +extern int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); +extern void rtw_free_cmd_obj(struct cmd_obj *pcmd); +//extern int rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); +extern void rtw_set_channel_plan_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_survey_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_disassoc_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd, int a3); +extern void rtw_joinbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_setstaKey_cmdrsp_callback(_adapter *padapter, struct cmd_obj *pcmd); +extern void rtw_cmd_thread(thread_context context); +extern int rtw_createbss_cmd(_adapter *padapter); +extern int rtw_joinbss_cmd(_adapter *padapter, struct wlan_network *pnetwork); +extern int rtw_disassoc_cmd(_adapter *padapter); +extern int rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype); +extern int rtw_setstakey_cmd(_adapter *padapter, uint8_t *psta, int unicast_key); +extern int rtw_clearstakey_cmd(_adapter *padapter, uint8_t *psta, uint8_t entry, int enqueue); +extern int rtw_addbareq_cmd(_adapter *padapter, int tid, uint8_t *addr); +extern int rtw_dynamic_chk_wk_cmd(_adapter *padapter); +extern struct cmd_obj *rtw_set_chplan_cmd(_adapter *padapter, int chplan, int enqueue); +extern void dynamic_chk_wk_hdl(_adapter *padapter, uint8_t *pbuf, int sz); +extern void lps_ctrl_wk_hdl(_adapter *padapter, int lps_ctrl_type, int a3); +extern int rtw_lps_ctrl_wk_cmd(_adapter *padapter, int lps_ctrl_type, int enqueue); +extern struct cmd_obj *rtw_sitesurvey_cmd(_adapter *padapter, NDIS_802_11_SSID *pssid, int ssid_max_num); +extern void rpt_timer_setting_wk_hdl(_adapter *padapter, uint16_t minRptTime, int a3); +extern int rtw_rpt_timer_cfg_cmd(_adapter *padapter, int minRptTime); +extern int rtw_ps_cmd(_adapter *padapter); +extern int rtw_chk_hi_queue_cmd(_adapter *padapter); +extern signed int rtw_drvextra_cmd_hdl(_adapter *padapter, u8 *pbuf, int a3); +extern int rtw_c2h_wk_cmd(PADAPTER padapter); +// Data declarations +extern const struct cmd_hdl wlancmds[63]; +extern const struct _cmd_callback rtw_cmd_callback[63]; +//-------------------------------- +// netdev.o +// Function declarations +extern struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); +extern struct net_device *rtw_alloc_etherdev(int sizeof_priv); +extern void rtw_free_netdev(struct net_device *netdev); +// Data declarations +//-------------------------------- +// phydm.o +// Function declarations +extern void ODM_CmnInfoInit(PDM_ODM_T pDM_Odm, ODM_CMNINFO_E CmnInfo, u4Byte Value); +extern void ODM_CmnInfoHook(PDM_ODM_T pDM_Odm, ODM_CMNINFO_E CmnInfo, PVOID pValue); +extern void ODM_CmnInfoPtrArrayHook(PDM_ODM_T pDM_Odm, ODM_CMNINFO_E CmnInfo, int Index, PVOID pValue); +extern void ODM_CmnInfoUpdate(PDM_ODM_T pDM_Odm, u4Byte CmnInfo, u8Byte Value); +extern void odm_CommonInfoSelfInit(PDM_ODM_T pDM_Odm); +extern void ODM_DMInit(PDM_ODM_T pDM_Odm); +extern void odm_CommonInfoSelfUpdate(PDM_ODM_T pDM_Odm); +extern void ODM_DMWatchdog(PDM_ODM_T pDM_Odm); +extern void odm_CommonInfoSelfReset(PDM_ODM_T pDM_Odm); +extern ADAPTIVITY_STATISTICS *PhyDM_Get_Structure(PDM_ODM_T pDM_Odm, int Structure_Type); +extern void odm_SwAntDetectInit(PDM_ODM_T pDM_Odm); +// Data declarations +//-------------------------------- +// rtl8195a_phycfg.o +// Function declarations +extern int PHY_QueryBBReg_8195A_Safe(PADAPTER Adapter, uint32_t RegAddr, uint32_t BitMask); +extern void PHY_SetBBReg_8195A_Safe(PADAPTER Adapter, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern int phy_RFSerialRead_8195A(PADAPTER Adapter, RF_PATH eRFPath, uint32_t Offset); +extern uint32_t PHY_QueryRFReg_8195A(PADAPTER Adapter, uint32_t eRFPath, uint32_t RegAddr, uint32_t BitMask); +extern void PHY_SetRFReg_8195A(PADAPTER Adapter, uint32_t eRFPath, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern BOOL PHY_MACConfig8195A(PADAPTER Adapter); +extern int PHY_BBConfig8195A(PADAPTER Adapter); +extern int PHY_ConfigRFWithParaFile_8195A(PADAPTER Adapter, uint8_t *pFileName, RF_PATH eRFPath); +extern void phy_PowerIndexCheck8195A(PADAPTER Adapter, uint8_t channel, uint8_t *cckPowerLevel, uint8_t *ofdmPowerLevel, uint8_t *BW20PowerLevel, uint8_t *BW40PowerLevel); +extern void PHY_SetTxPowerIndex_8195A(PADAPTER Adapter, uint32_t PowerIndex, int RFPath, int Rate); +extern void phy_TxPwrAdjInPercentage(PADAPTER Adapter, uint8_t *pTxPwrIdx); +extern int PHY_GetTxPowerIndex_8195A(PADAPTER pAdapter, int RFPath, int Rate, CHANNEL_WIDTH BandWidth, uint8_t Channel); +extern void PHY_SetTxPowerLevel8195A(PADAPTER Adapter, int Channel); +extern void phy_SpurCalibration_8195A(PADAPTER pAdapter); +extern void phy_SetRegBW_8195A(PADAPTER Adapter, CHANNEL_WIDTH CurrentBW); +extern int phy_GetSecondaryChnl_8195A(PADAPTER Adapter); +extern void phy_PostSetBwMode8195A(PADAPTER Adapter); +extern void phy_SwChnl8195A(PADAPTER pAdapter); +extern void phy_SwChnlAndSetBwMode8195A(PADAPTER Adapter); +extern void PHY_HandleSwChnlAndSetBW8195A(PADAPTER Adapter, int bSwitchChannel, int bSetBandWidth, uint8_t ChannelNum, CHANNEL_WIDTH ChnlWidth, EXTCHNL_OFFSET ExtChnlOffsetOf40MHz, EXTCHNL_OFFSET ExtChnlOffsetOf80MHz, uint8_t CenterFrequencyIndex1); +extern void PHY_SetBWMode8195A(PADAPTER Adapter, CHANNEL_WIDTH Bandwidth, int Offset); +extern void PHY_SwChnl8195A(PADAPTER Adapter, uint8_t channel); +extern void PHY_SetSwChnlBWMode8195A(PADAPTER Adapter, uint8_t channel, CHANNEL_WIDTH Bandwidth, int Offset40, uint8_t Offset80); +// Data declarations +//-------------------------------- +// rtl8195a_pmu_cmd.o +// Function declarations +extern void MediaConnection(PADAPTER padapter, int macid); +extern void MediaDisconnection(PADAPTER padapter, int macid); +extern void RATaskEnable(PADAPTER padapter); +extern void SetMediaStatus(PADAPTER padapter, int macid, int status); +extern void H2CHDL_JoinInfo(PADAPTER padapter, uint8_t *pCmdBuffer); +extern void H2CHDL_SetRsvdPage(PADAPTER padapter, uint8_t *pCmdBuffer); +extern uint32_t H2CCmdCommon(PADAPTER padapter, int ElementID, uint8_t *pCmdBuffer); +// Data declarations +//-------------------------------- +// rtl8195a_pmu_task.o +// Function declarations +extern void HalTimerEnable(uint32_t TimerId); +extern void InitTDMATimer(int Period); +extern void ChangeStateByTDMA(PADAPTER padapter); +extern void GetMinRateInRRSR(PADAPTER padapter); +extern void CheckInReqState(PADAPTER padapter); +extern void InitCheckStateTimer(); +extern void InitGTimer1ms(PADAPTER padapter, uint8_t IRQDis, int TimerID, uint32_t Period); +extern void DeInitGTimer1ms(PADAPTER padapter, int TimerID); +extern void ChangeTransmiteRate(int offset, uint8_t rate); +extern void PowerBitSetting(int bPowerBit, int offset); +extern void ChkandChangePS(PPS_PARM pPSParm, int bPowerBit); +extern int IssueRsvdPagePacketSetting(int PageNum, int bHwSEQEn, uint8_t RtyLmt); +extern void InitRsvdPgPkt(); +extern void IssuePSPoll(); +extern signed int WaitTxStateMachineOk(); +extern signed int IssueNullData(PPS_PARM pPSParm, int bPowerBit, uint8_t RtyLmt); +extern void WriteTxPause(uint8_t value, uint8_t rcode); +extern void PsCloseRF(); +extern void PsOpenRF(); +extern void SetPwrStateReg(PPS_PARM pPSParm, int PwrStateType, uint8_t value); +extern BOOL ChkTxQueueIsEmpty(); +extern void InitPS(PADAPTER padapter); +extern void ConfigListenBeaconPeriod(PPS_PARM pPSParm, int RLBM, int AwakeInterval); +extern signed int PS_S2_Condition_Match(PPS_PARM pPSParm); +extern signed int PS_S4_Condition_Match(PADAPTER padapter); +extern unsigned int PS_32K_Condition_Match(); +extern void PS_S2ToS3ToS0State(PADAPTER padapter, int nulldata0Allow); +extern void PS_S2ToS0State(PPS_PARM pPSParm); +extern void PS_S3ToS2orS0State(PPS_PARM pPSParm); +extern void PS_S0ToS1ToS2State(PADAPTER padapter); +extern void PS_S1ToS0orS2State(PPS_PARM pPSParm); +extern void PS_S2ToS4State(PADAPTER padapter); +extern void PS_S2ToS5State(PPS_PARM pPSParm); +extern void PS_S5ToS2State(PPS_PARM pPSParm); +extern void PS_S0ToS6State(PADAPTER padapter); +extern void PS_S6ToS0State(PPS_PARM pPSParm); +extern void CheckTSFIsStable(int ReqState); +extern void WaitHWStateReady(); +extern void SysClkDown(PPS_PARM pPSParm); +extern void SysClkUp(PPS_PARM pPSParm); +extern void ResetPSParm(PADAPTER padapter); +extern void PS_S4ToS2State(PPS_PARM pPSParm, int ReleaseTxPause); +extern void SleepTo32K(PPS_PARM pPSParm); +extern void Change_PS_State(PADAPTER padapter, int request_ps_state, int nulldata0Allow); +extern void Legacy_PS_Setting(PADAPTER padapter); +extern void PSModeSetting(PADAPTER padapter, int on); +extern void ChangePSStateByRPWM(PADAPTER padapter); +extern void ChangeTDMAState(PADAPTER padapter); +extern void TDMAChangeStateTask(PADAPTER padapter, _irqL a2); +extern void EnterPS(PADAPTER padapter); +extern void SetSmartPSTimer(PADAPTER padapter); +extern void GTimer7Handle(void *Data); +extern void SmartPS2InitTimerAndToGetRxPkt(PADAPTER padapter); +extern void PS_OnBeacon(PADAPTER padapter); +extern void PSBcnEarlyProcess(PADAPTER padapter); +extern void PSMtiBcnEarlyProcess(PADAPTER padapter); +extern void PSRxBcnProcess(PADAPTER padapter); +extern void TxPktInPSOn(PADAPTER padapter); +extern void PsBcnToProcess(PADAPTER padapter); +extern void GTimer6Handle(void *Data); +extern signed int RPWMProcess(PADAPTER padapter, int benter32k); +extern void PSSetMode(PADAPTER padapter, PLEGACY_PS_PARM pparm); +extern void SpeRPT(PADAPTER padapter); +extern void ISR_BcnEarly(PADAPTER padapter); +extern void ISR_MtiBcnEarly(PADAPTER padapter); +extern void ISR_RxBcn(PADAPTER padapter); +extern void ISR_RxBCMD1(PADAPTER padapter); +extern void ISR_RxBCMD0(PADAPTER padapter); +extern void ISR_RxUCMD1(PADAPTER padapter); +extern void ISR_RxUCMD0(PADAPTER padapter); +extern void ISR_TxPktIn(PADAPTER padapter); +extern void H2CHDL_SetPwrMode(PADAPTER padapter, uint8_t *pCmdBuffer); +extern void CheckInReqStateTask(PADAPTER padapter, int a2, int a3); +extern uint32_t HalGetNullTxRpt(PADAPTER padapter); +extern void ISR_TBTT(PADAPTER padapter); +extern void H2CHDL_BcnIgnoreEDCCA(PADAPTER padapter, uint8_t *pCmdBuffer); +extern void PMUInitial(PADAPTER padapter); +extern void PMUTask(PADAPTER padapter); +// Data declarations +extern BOOL bCheckStateTIMER; +extern uint32_t WifiMcuCmdBitMap_20974; +//-------------------------------- +// rtl8195a_recv.o +// Function declarations +extern int32_t rtl8195a_init_recv_priv(_adapter *padapter); +// Data declarations +//-------------------------------- +// rtl8195a_rxdesc.o +// Function declarations +extern void process_rssi(_adapter *padapter, struct recv_frame *prframe); +extern int32_t translate2dbm(int signal_strength_idx); +extern void rtl8195a_query_rx_desc_status(struct recv_frame *precvframe, uint8_t *pdesc); +extern void rtl8195a_query_rx_phy_status(struct recv_frame *precvframe, uint8_t *pphy_status, int a3); +// Data declarations +//-------------------------------- +// rtl8195a_xmit.o +// Function declarations +extern uint8_t *GetTxBufDesc(_adapter *padapter, int queue_index); +extern void UpdateFirstTxbdtoXmitBuf(_adapter *padapter, struct xmit_frame *pxmitframe); +extern BOOL check_nic_enough_desc(_adapter *padapter, struct pkt_attrib *pattrib); +extern int32_t rtl8195ab_init_xmit_priv(PADAPTER padapter); +extern void rtl8195ab_free_xmit_priv(PADAPTER padapter); +extern uint32_t GetDmaTxbdIdx(uint32_t ff_hwaddr); +extern struct xmit_buf *rtl8195a_enqueue_xmitbuf(struct rtw_tx_ring *ring, struct xmit_buf *pxmitbuf); +extern struct list_head *rtl8195a_dequeue_xmitbuf(struct rtw_tx_ring *ring); +extern signed int SetTxbdForLxDMARtl8195ab(_adapter *padapter, struct xmit_frame *pxmitframe, struct tx_buf_desc *pTxbd); +extern void UpdateTxbdHostIndex(_adapter *padapter, uint32_t ff_hwaddr); +extern struct xmit_buf *SetXimtBuf(struct xmit_frame *pxmitframe); +extern int FreeXimtBuf(struct xmit_buf *pxmitbuf); +extern int rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe); +extern BOOL check_tx_desc_resource(_adapter *padapter, int prio); +extern struct list_head *rtw_dequeue_xframe(struct xmit_priv *pxmitpriv, struct hw_xmit *phwxmit_i, sint entry); +extern int32_t rtw_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe); +extern void rtl8195ab_xmitframe_resume(_adapter *padapter); +extern int32_t rtl8195ab_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); +extern int32_t rtl8195ab_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +extern int32_t rtl8195ab_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +// Data declarations +//-------------------------------- +// rtw_intfs.o +// Function declarations +extern signed int rtw_init_default_value(_adapter *padapter); +extern void rtw_cancel_all_timer(_adapter *padapter); +extern signed int rtw_free_drv_sw(_adapter *padapter); +extern signed int rtw_reset_drv_sw(_adapter *padapter); +extern signed int rtw_init_drv_sw(_adapter *padapter); +extern int rtw_start_drv_threads(_adapter *padapter); +extern void rtw_stop_drv_threads(_adapter *padapter); +// Data declarations +//-------------------------------- +// rtw_mlme.o +// Function declarations +extern void rtw_free_mlme_ie_data(uint8_t **ppie, uint32_t *plen); +extern void rtw_init_mlme_timer(_adapter *padapter); +extern void rtw_del_mlme_timer(struct mlme_priv *pmlmepriv); +extern void reconnect_timer_hdl(void *FunctionContext); +extern uint8_t *rtw_init_mlme_priv(_adapter *padapter, int a2, int a3); +extern void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv); +extern void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv); +extern void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv); +extern sint rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork); +extern struct list_head *rtw_alloc_network(struct mlme_priv *pmlmepriv, _irqL a2, int a3); +extern void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, int isfreeall); +extern void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork); +extern _queue *rtw_find_network(_queue *scanned_queue, uint8_t *addr); +extern void rtw_free_network_queue(_adapter *padapter, int isfreeall, int a3); +extern sint rtw_if_up(_adapter *padapter); +extern void rtw_generate_random_ibss(uint8_t *pibss); +extern uint8_t *rtw_get_capability_from_ie(uint8_t *ie); +extern int rtw_get_capability(WLAN_BSSID_EX *bss, int a2, int a3); +extern uint8_t *rtw_get_beacon_interval_from_ie(uint8_t *ie); +extern uint8_t *rtw_init_mlme_priv(_adapter *padapter, int a2, int a3); +extern uint32_t rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork); +extern int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, int a3); +extern struct list_head *rtw_get_oldest_wlan_network(_queue *scanned_queue); +extern void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src, _adapter *padapter, int update_ie); +extern void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target); +extern void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork, int a3); +extern void rtw_survey_event_callback(_adapter *adapter, uint8_t *pbuf, int a3); +extern void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue); +extern void rtw_indicate_connect(_adapter *padapter); +extern void rtw_indicate_disconnect(_adapter *padapter); +extern void rtw_joinbss_event_callback(_adapter *adapter, uint8_t *pbuf); +extern signed int search_max_mac_id(_adapter *padapter); +extern void rtw_stassoc_hw_rpt(_adapter *adapter, struct sta_info *psta); +extern void rtw_stassoc_event_callback(_adapter *adapter, uint8_t *pbuf); +extern void rtw_stadel_event_callback(_adapter *adapter, uint8_t *pbuf); +extern void rtw_join_timeout_handler(_adapter *adapter, _irqL a2, int a3, int a4); +//void rtw_join_timeout_handler(void *FunctionContext, _irqL a2, int a3, int a4); +extern void rtw_scan_timeout_handler(_adapter *adapter, _irqL a2, int a3); +//void rtw_scan_timeout_handler(void *FunctionContext); +extern void rtw_dynamic_check_timer_handlder(_adapter *adapter); +extern void dynamic_check_timer_handlder(void *FunctionContext); +extern int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv, _irqL a2, int a3); +extern void rtw_surveydone_event_callback(_adapter *adapter, uint8_t *pbuf); +extern sint rtw_set_auth(_adapter *adapter, struct security_priv *psecuritypriv); +extern sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint keyid, uint8_t set_tx); +extern unsigned int rtw_restruct_wmm_ie(_adapter *adapter, uint8_t *in_ie, uint8_t *out_ie, unsigned int in_len, unsigned int initial_out_len); +extern sint rtw_restruct_sec_ie(_adapter *adapter, uint8_t *in_ie, uint8_t *out_ie, unsigned int in_len); +extern void rtw_joinbss_reset(_adapter *padapter); +extern unsigned int rtw_restructure_ht_ie(_adapter *padapter, uint8_t *in_ie, uint8_t *out_ie, unsigned int in_len, unsigned int *pout_len); +extern void rtw_update_ht_cap(_adapter *padapter, uint8_t *pie, unsigned int ie_len); +extern void rtw_joinbss_event_prehandle(_adapter *adapter, uint8_t *pbuf, int a3); +extern void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe); +extern sint rtw_linked_check(_adapter *padapter); +extern sint rtw_buddy_adapter_up(sint result); +extern sint check_buddy_fwstate(sint result, sint state); +// Data declarations +extern uint8_t auto_reconnect_running; +extern void (*p_wlan_autoreconnect_hdl)(rtw_security_t, char *, int, char *, int, int); +//-------------------------------- +// rtw_mlme_ext.o +// Function declarations +extern u8 *get_da(u8 *pframe); +extern u8 *get_sa(u8 *pframe); +extern signed int OnAction(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int DoReserved(_adapter *padapter, struct recv_frame *precv_frame); +extern void mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, struct recv_frame *precv_frame); +extern int rtw_is_channel_set_contains_channel(RT_CHANNEL_INFO *channel_set, const uint32_t channel_num, int *pchannel_idx); +extern int init_hw_mlme_ext(_adapter *padapter); +extern unsigned int init_channel_set(_adapter *padapter, int ChannelPlan, RT_CHANNEL_INFO *channel_set); +extern void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext); +//void mgt_dispatcher(_adapter *padapter, struct recv_frame *precv_frame, int a3); +extern unsigned int OnAction_public(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int OnAction_p2p(_adapter *padapter, struct recv_frame *precv_frame); +extern struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv); +extern struct xmit_frame *alloc_FwRsvdframe(struct xmit_priv *pxmitpriv, uint32_t size); +extern void update_mgnt_tx_rate(_adapter *padapter, uint8_t rate); +extern void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib); +extern struct xmit_frame *rtw_build_mgnt_frame(_adapter *padapter, uint8_t *data, int len); +extern void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe); +extern int rtw_send_mgnt(_adapter *padapter, uint8_t *data, int len, uint16_t flags); +extern void issue_action_BSSCoexistPacket(_adapter *padapter); +extern uint32_t update_hidden_ssid(uint8_t *ies, uint32_t ies_len, int hidden_ssid_mode); +extern void issue_beacon(_adapter *padapter); +extern void issue_probersp(_adapter *padapter, u8 *da, uint8_t is_valid_p2p_probereq); +extern signed int OnProbeReq(_adapter *padapter, struct recv_frame *precv_frame); +extern void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, int blnbc); +extern void issue_auth(_adapter *padapter, struct sta_info *psta, int status); +extern signed int OnAuth(_adapter *padapter, struct recv_frame *precv_frame); +extern void issue_asocrsp(_adapter *padapter, uint16_t status, struct sta_info *pstat, int pkt_type); +extern void issue_assocreq(_adapter *padapter); +extern void issue_nulldata(_adapter *padapter, unsigned int power_mode); +extern void issue_qos_nulldata(_adapter *padapter, u8 *da, uint16_t tid); +extern void issue_deauth(_adapter *padapter, u8 *da, uint32_t reason); +extern void issue_action_BA(_adapter *padapter, u8 *raddr, u8 action, uint16_t status); +extern signed int OnAction_back(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int send_beacon(_adapter *padapter); +extern signed int collect_bss_info(_adapter *padapter, struct recv_frame *precv_frame, WLAN_BSSID_EX *bssid); +extern void start_clnt_auth(_adapter *padapter); +extern void start_clnt_assoc(_adapter *padapter); +extern signed int OnAuthClient(_adapter *padapter, struct recv_frame *precv_frame); +extern int report_scan_result_one(_adapter *padapter, WLAN_BSSID_EX *bssid); +extern int add_site_survey(_adapter *padapter, WLAN_BSSID_EX *bssid); +extern void report_survey_event(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int OnProbeRsp(_adapter *padapter, struct recv_frame *precv_frame); +extern void report_surveydone_event(_adapter *padapter); +extern void report_join_res(_adapter *padapter, int res); +extern signed int OnAssocRsp(_adapter *padapter, struct recv_frame *precv_frame); +extern void report_del_sta_event(_adapter *padapter, u8 *MacAddr, uint16_t reason); +extern signed int receive_disconnect(_adapter *padapter, u8 *MacAddr, uint16_t reason); +extern signed int OnBeacon(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int OnDeAuth(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int OnDisassoc(_adapter *padapter, struct recv_frame *precv_frame); +extern void report_add_sta_event(_adapter *padapter, u8 *MacAddr, int cam_idx); +extern signed int OnAssocReq(_adapter *padapter, struct recv_frame *precv_frame); +extern signed int rtw_port_switch_chk(_adapter *adapter); +extern void update_sta_info(_adapter *padapter, struct sta_info *psta); +extern void mlmeext_sta_del_event_callback(_adapter *padapter); +extern void linked_info_dump(_adapter *padapter, _irqL a2, int a3); +extern void linked_rx_signal_strehgth_display(_adapter *padapter, int a2); +extern void linked_status_chk(_adapter *padapter, int a2); +extern void survey_timer_hdl(_adapter *padapter, int a2); +//void survey_timer_hdl(void *FunctionContext); +extern void link_timer_hdl(_adapter *padapter); +//void link_timer_hdl(void *FunctionContext); +extern void addba_timer_hdl(struct sta_info *psta); +extern int NULL_hdl(_adapter *padapter, uint8_t *pbuf); +extern int setopmode_hdl(_adapter *padapter, uint8_t *pbuf, int a3); +extern int disconnect_hdl(_adapter *padapter, u8 *pbuf, int a3); +extern int setauth_hdl(_adapter *padapter, u8 *pbuf); +extern int setkey_hdl(_adapter *padapter, uint8_t *pbuf, int a3, int a4); +extern signed int set_stakey_hdl(_adapter *padapter, uint8_t *pbuf); +extern int set_tx_beacon_cmd(_adapter *padapter); +extern int mlme_evt_hdl(_adapter *padapter, u8 *pbuf); +extern int tx_beacon_hdl(_adapter *padapter, u8 *pbuf, int a3); +extern sint check_buddy_mlmeinfo_state(sint result, uint32_t state); +extern void site_survey(_adapter *padapter, int a2, int a3); +extern int sitesurvey_cmd_hdl(_adapter *padapter, uint8_t *pbuf, int a3); +extern int concurrent_chk_start_clnt_join(_adapter *padapter); +extern void start_clnt_join(_adapter *padapter, int a2, int a3); +extern signed int join_cmd_hdl(_adapter *padapter, uint8_t *pbuf, int a3); +extern void concurrent_chk_joinbss_done(_adapter *padapter, int join_res); +extern void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res, int a3); +extern signed int set_chplan_hdl(_adapter *padapter, u8 *pbuf); +extern void init_mlme_ext_timer(_adapter *padapter); +extern int init_mlme_ext_priv(_adapter *padapter); +// Data declarations +extern const RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[8]; /* = +{ + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 0u }, 13u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 0u }, 13u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 0u, 0u, 0u }, 11u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u }, 14u }, + { { 10u, 11u, 12u, 13u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, 4u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 0u }, 13u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 0u }, 13u }, + { { 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 0u }, 13u } +}; */ +extern const uint8_t WPS_OUI[4]; // = { 0u, 80u, 242u, 4u }; +extern mac_monitor_ptr mac_monitor_callback; +extern struct mlme_handler mlme_sta_tbl[14]; /* = +{ + { 0u, (unsigned int (*)(_adapter *, recv_frame *))0x2FA1 }, + { 16u, (unsigned int (*)(_adapter *, recv_frame *))0x28A9 }, + { 32u, (unsigned int (*)(_adapter *, recv_frame *))0x2FA1 }, + { 48u, (unsigned int (*)(_adapter *, recv_frame *))0x28A9 }, + { 64u, (unsigned int (*)(_adapter *, recv_frame *))0xAB5 }, + { 80u, (unsigned int (*)(_adapter *, recv_frame *))0x27A1 }, + { 0u, (unsigned int (*)(_adapter *, recv_frame *))0x61 }, + { 0u, (unsigned int (*)(_adapter *, recv_frame *))0x61 }, + { 128u, (unsigned int (*)(_adapter *, recv_frame *))0x2ADD }, + { 144u, (unsigned int (*)(_adapter *, recv_frame *))0x61 }, + { 160u, (unsigned int (*)(_adapter *, recv_frame *))0x2DBD }, + { 176u, (unsigned int (*)(_adapter *, recv_frame *))0x213D }, + { 192u, (unsigned int (*)(_adapter *, recv_frame *))0x2C65 }, + { 208u, (unsigned int (*)(_adapter *, recv_frame *))0x4F } +}; */ +//_UNKNOWN unk_4AE4; // weak +extern struct list_head *mf_list_head; +extern const uint8_t WMM_INFO_OUI[6]; // = { 0u, 80u, 242u, 2u, 0u, 1u }; +extern uint8_t pscan_retry_cnt_21430; +extern const uint8_t RTW_WPA_OUI[4]; // = { 0u, 80u, 242u, 1u }; +extern const uint8_t WMM_PARA_OUI[6]; // = { 0u, 80u, 242u, 2u, 1u, 1u }; +extern const RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[8]; /* = +{ + { 32u, 0u, 3u }, + { 33u, 1u, 2u }, + { 34u, 2u, 0u }, + { 35u, 3u, 1u }, + { 36u, 4u, 2u }, + { 42u, 5u, 0u }, + { 71u, 7u, 4u }, + { 88u, 6u, 1u } +}; */ +extern const uint8_t null_addr[6]; // = { 0u, 0u, 0u, 0u, 0u, 0u }; +extern const uint8_t WMM_OUI[4]; // = { 0u, 80u, 242u, 2u }; +extern const struct fwevent wlanevents[24]; /* = +{ + { 0u, &rtw_dummy_event_callback }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, &rtw_survey_event_callback }, + { 4u, &rtw_surveydone_event_callback }, + { 0u, &rtw_joinbss_event_callback }, + { 12u, &rtw_stassoc_event_callback }, + { 12u, &rtw_stadel_event_callback }, + { 0u, NULL }, + { 0u, &rtw_dummy_event_callback }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL }, + { 0u, NULL } +}; */ +//-------------------------------- +// rtw_promisc.o +// Function declarations +extern u8 *get_hdr_bssid(u8 *pframe); +extern int filter_packet(u8 *buf, int length); +extern signed int promisc_get_encrypt(_adapter *padapter, uint8_t *bssid); +extern void promisc_info_get(_adapter *padapter, struct recv_frame *prframe, ieee80211_frame_info_t *ppromisc_info, int a4); +extern void promisc_set_enable(_adapter *padapter, int enabled, int len_used); +extern void promisc_deinit(_adapter *padapter); +extern int promisc_recv_func(_adapter *padapter, struct recv_frame *rframe); +extern int promisc_set(rtw_rcr_level_t enabled, void (*callback)(u8 *, unsigned int, void *), int len_used); +extern int promisc_set_mgntframe(int result); +extern int is_promisc_enabled(); +extern void promisc_issue_probereq(); +extern void promisc_issue_probersp(u8 *da); +extern int promisc_get_fixed_channel(void *fixed_bssid, uint8_t *ssid, int *ssid_length); +// Data declarations +extern void (*promisc_callback_all)(u8 *, unsigned int, void *); +extern _sema promisc_sema; +extern const u8 zero_bssid[6]; // = { 0u, 0u, 0u, 0u, 0u, 0u }; +extern void (*promisc_callback)(u8 *, unsigned int, void *); +//-------------------------------- +// rtw_psk.o +// Function declarations +extern void SetEAPOL_KEYIV(OCTET_STRING ocDst, uint64_t a2, OCTET32_INTEGER oc32Counter); +extern void ToDrv_SetPTK(_adapter *padapter, struct sta_info *psta); +extern void Message_ReplayCounter_OC2LI(int a1, LARGE_INTEGER *li); +extern int Message_SmallerEqualReplayCounter(LARGE_INTEGER li1, int a2); +extern void Message_setReplayCounter(int a1, unsigned int h, unsigned int l); +extern void INCLargeInteger(LARGE_INTEGER *x); +extern void INCOctet16_INTEGER(OCTET16_INTEGER *x); +extern OCTET32_INTEGER *INCOctet32_INTEGER(OCTET32_INTEGER *x); +extern void ToDrv_DisconnectSTA(_adapter *padapter, struct sta_info *psta, int reason); +extern int CheckMIC(OCTET_STRING EAPOLMsgRecvd, u8 *key, int keylen); +extern void CalcMIC(OCTET_STRING EAPOLMsgSend, int algo, u8 *key, int keylen); +extern int DecWPA2KeyData(WPA_STA_INFO *pStaInfo, u8 *key, int keylen, u8 *kek, int keklen, u8 *kout); +extern int DecGTK(OCTET_STRING EAPOLMsgRecvd, u8 *kek, int keklen, int keylen, u8 *kout); +extern void ToDrv_SetGTK(_adapter *padapter); +extern void init_wpa_sta_info(_adapter *padapter, struct sta_info *psta); +extern void SendEAPOL(_adapter *padapter, struct sta_info *psta, int resend); +extern void ClientSendEAPOL(_adapter *padapter, struct sta_info *psta, int resend); +extern void ResendTimeout(void *task_psta, _irqL a2); +extern void EAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta); +extern void ClientEAPOLKeyRecvd(_adapter *padapter, struct sta_info *psta); +extern void set_wpa_global_PSK(u8 *key); +extern void psk_derive(_adapter *padapter, u8 *passphrase, u8 *ssid); +extern void psk_init(_adapter *padapter, u8 *pie, int ielen); +extern int psk_strip_rsn_pairwise(uint8_t *ie, int ie_len); +extern int psk_strip_wpa_pairwise(uint8_t *ie, int ie_len); +extern int tkip_send_mic_failure_report(_adapter *padapter); +// Data declarations +extern uint8_t psk_essid[2][36]; +extern uint8_t psk_passphrase[2][65]; +extern char PMKID_KDE_TYPE_17744[6]; +extern uint8_t wpa_global_PSK[2][40]; +//-------------------------------- +// rtw_pwrctrl.o +// Function declarations +extern void pwr_state_check_handler(void *FunctionContext); +extern void ips_enter(_adapter *padapter); +extern int ips_leave(_adapter *padapter); +extern signed int rtw_pwr_unassociated_idle(_adapter *adapter); +extern void rtw_ps_processor(_adapter *padapter); +extern void rtw_set_rpwm(PADAPTER padapter, uint8_t pslv); +extern int PS_RDY_CHECK(_adapter *padapter); +extern void rtw_set_ps_mode(PADAPTER padapter, int ps_mode, int smart_ps, int bcn_ant_mode); +extern int32_t LPS_RF_ON_check(PADAPTER padapter, uint32_t delay_ms); +extern void LPS_Enter(PADAPTER padapter); +extern void LPS_Leave(PADAPTER padapter); +extern void LeaveAllPowerSaveMode(PADAPTER Adapter); +extern void rtw_init_pwrctrl_priv(PADAPTER padapter); +extern void rtw_free_pwrctrl_priv(PADAPTER adapter); +extern int rtw_pwr_wakeup(_adapter *padapter, uint32_t ips_deffer_ms, const char *caller); +extern int rtw_pm_set_lps(_adapter *padapter, int mode); +extern int rtw_pm_set_ips(_adapter *padapter, int mode); +extern int rtw_pm_set_tdma_param(_adapter *padapter, uint8_t tdma_slot_period, uint8_t tdma_rfon_period_len_1, uint8_t tdma_rfon_period_len_2, uint8_t tdma_rfon_period_len_3); +extern int rtw_pm_set_lps_dtim(_adapter *padapter, uint8_t lps_dtim); +extern int rtw_pm_get_lps_dtim(_adapter *padapter); +// Data declarations +//-------------------------------- +// rtw_recv.o +// Function declarations +extern uint8_t *recvframe_pull(uint8_t *result, sint sz); +extern uint8_t *recvframe_pull_tail(uint8_t *result, sint sz); +extern void rtw_signal_stat_timer_hdl(void *FunctionContext); +extern void rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv); +extern sint rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +extern void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv); +extern struct list_head *rtw_alloc_recvframe(_queue *pfree_recv_queue); +//struct list_head *rtw_alloc_recvframe(_queue *pfree_recv_queue, _irqL a2, int a3); +extern int rtw_free_recvframe(struct recv_frame *precvframe, _queue *pfree_recv_queue); +extern sint rtw_enqueue_recvframe(struct recv_frame *precvframe, _queue *queue); +extern sint rtw_enqueue_recvframe(struct recv_frame *precvframe, _queue *queue); +extern void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue); +extern int rtw_free_uc_swdec_pending_queue(_adapter *adapter, _irqL a2, int a3); +extern void rtw_free_recv_priv(struct recv_priv *precvpriv); +extern sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue); +extern uint32_t rtw_free_buf_pending_queue(_adapter *adapter); +extern sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue); +extern struct list_head *rtw_dequeue_recvbuf(_queue *queue, _irqL a2, int a3); +extern sint recvframe_chkmic(_adapter *adapter, struct recv_frame *precvframe, int a3, int a4); +extern struct recv_frame *decryptor(_adapter *padapter, struct recv_frame *precv_frame); +extern struct recv_frame *portctrl(_adapter *adapter, struct recv_frame *precv_frame); +extern sint recv_decache(struct recv_frame *precv_frame, uint8_t bretry, struct stainfo_rxcache *prxcache); +extern void process_pwrbit_data(_adapter *padapter, struct recv_frame *precv_frame, int a3, int a4); +extern void process_wmmps_data(_adapter *padapter, struct recv_frame *precv_frame); +extern void count_rx_stats(_adapter *padapter, struct recv_frame *prframe, struct sta_info *sta); +extern sint sta2sta_data_frame(_adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta, int a4); +extern sint ap2sta_data_frame(_adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta); +extern sint sta2ap_data_frame(_adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta); +extern sint validate_recv_ctrl_frame(_adapter *padapter, struct recv_frame *precv_frame); +extern sint validate_recv_data_frame(_adapter *adapter, struct recv_frame *precv_frame); +extern sint wlanhdr_to_ethhdr(struct recv_frame *precvframe, int a2, int a3); +extern struct recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q); +extern _queue *recvframe_chk_defrag(PADAPTER padapter, struct recv_frame *precv_frame); +extern sint validate_recv_mgnt_frame(PADAPTER padapter, struct recv_frame **pprecv_frame); +extern sint validate_recv_frame(_adapter *adapter, struct recv_frame **pprecv_frame); +extern int amsdu_to_msdu(_adapter *padapter, struct recv_frame *prframe); +extern int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, int seq_num); +extern int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe); +extern int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced); +extern int recv_indicatepkt_reorder(_adapter *padapter, struct recv_frame *prframe, int a3); +extern void rtw_reordering_ctrl_timeout_handler(void *pcontext, _irqL a2); +extern int process_recv_indicatepkts(_adapter *padapter, struct recv_frame *prframe, int a3); +extern int recv_func_prehandle(_adapter *padapter, struct recv_frame *rframe, int a3); +extern int recv_func_posthandle(_adapter *padapter, struct recv_frame *prframe); +extern int recv_func(_adapter *padapter, struct recv_frame *rframe, int a3); +extern int32_t rtw_recv_entry(struct recv_frame *precvframe, int a2, int a3); +extern void rtw_recv_tasklet(thread_context context); +// Data declarations +extern const uint8_t SNAP_ETH_TYPE_APPLETALK_AARP[2]; // = { 128u, 243u }; +extern const uint8_t SNAP_ETH_TYPE_IPX[2]; // = { 129u, 55u }; +extern const uint8_t rtw_bridge_tunnel_header[6]; // = { 170u, 170u, 3u, 0u, 0u, 248u }; +extern const uint8_t oui_8021h[3]; // = { 0u, 0u, 248u }; +extern const uint8_t rtw_rfc1042_header[6]; // = { 170u, 170u, 3u, 0u, 0u, 0u }; +extern const uint8_t SNAP_HDR_APPLETALK_DDP[3]; // = { 8u, 0u, 7u }; +extern const uint8_t SNAP_ETH_TYPE_APPLETALK_DDP[2]; // = { 128u, 155u }; +extern const uint8_t oui_rfc1042[3]; // = { 0u, 0u, 0u }; +//-------------------------------- +// rtw_security.o +// Function declarations +extern void rtw_wep_encrypt(_adapter *padapter, uint8_t *pxmitframe); +extern void rtw_wep_decrypt(_adapter *padapter, uint8_t *precvframe); +extern signed int rtw_tkip_encrypt(_adapter *padapter, uint8_t *pxmitframe); +extern int rtw_tkip_decrypt(_adapter *padapter, uint8_t *precvframe); +extern signed int rtw_aes_encrypt(_adapter *padapter, uint8_t *pxmitframe, int a3, int a4); +extern int rtw_aes_decrypt(_adapter *padapter, uint8_t *precvframe, int a3, int a4); +extern void rtw_use_tkipkey_handler(void *FunctionContext); +extern int rtw_init_sec_priv(_adapter *padapter); +extern void rtw_free_sec_priv(struct security_priv *psecpriv); +// Data declarations +//-------------------------------- +// rtw_sta_mgt.o +// Function declarations +extern int wifi_mac_hash(uint8_t *mac); +extern void rtw_init_stainfo(struct sta_info *psta); +extern int rtw_init_sta_priv(_adapter *padapter); +extern void rtw_free_sta_xmit_priv_lock(struct sta_xmit_priv *psta_xmitpriv); +extern void rtw_mfree_stainfo(struct sta_info *psta); +extern void rtw_mfree_sta_priv_lock(struct sta_priv *pstapriv); +extern signed int rtw_free_sta_priv(struct sta_priv *pstapriv); +extern void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta); +extern struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, uint8_t *hwaddr, _irqL a3, _irqL a4); +extern signed int rtw_free_stainfo(_adapter *padapter, struct sta_info *psta, int a3); +extern struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, uint8_t *hwaddr, int a3, int a4); +extern signed int rtw_init_bcmc_stainfo(_adapter *padapter, int a2, int a3); +extern struct sta_info *rtw_get_bcmc_stainfo(_adapter *padapter, int a2, int a3); +extern void rtw_free_all_stainfo(_adapter *padapter, _irqL a2, int a3); +// Data declarations +//-------------------------------- +// rtw_xmit.o +// Function declarations +extern void init_txservq(struct tx_servq *ptxservq); +extern void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib); +extern void rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv); +extern void rtw_mfree_xmit_priv_lock(struct xmit_priv *pxmitpriv); +extern int qos_acm(uint8_t acm_mask, int priority); +extern int32_t xmitframe_addmic(_adapter *padapter, struct xmit_frame *pxmitframe); +extern int32_t xmitframe_swencrypt(_adapter *padapter, struct xmit_frame *pxmitframe); +extern int32_t rtw_make_wlanhdr(_adapter *padapter, uint8_t *hdr, struct pkt_attrib *pattrib); +extern int32_t rtw_txframes_pending(_adapter *padapter); +extern int32_t rtw_txframes_sta_ac_pending(_adapter *padapter, struct pkt_attrib *pattrib); +extern void rtw_txframes_update_attrib_vcs_info(_adapter *padapter, struct xmit_frame *pxmitframe); +extern int rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib); +extern int32_t rtw_put_snap(uint8_t *data, int h_proto); +extern void rtw_update_protection(_adapter *padapter, uint8_t *ie, unsigned int ie_len); +extern void rtw_count_tx_stats(PADAPTER padapter, struct xmit_frame *pxmitframe, uint64_t sz); +extern int32_t rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf, int a3); +extern struct list_head *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv, _irqL a2); +extern int32_t rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe); +extern void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, _queue *pframequeue); +extern struct tx_servq *rtw_get_sta_pending(_adapter *padapter, struct sta_info *psta, sint up, uint8_t *ac); +extern struct sta_info *rtw_xmit_classifier(_adapter *padapter, struct xmit_frame *pxmitframe); +extern BOOL rtw_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +extern void rtw_alloc_hwxmits(_adapter *padapter); +extern void rtw_free_hwxmits(_adapter *padapter); +extern void rtw_free_xmit_priv(struct xmit_priv *pxmitpriv); +extern void rtw_init_hwxmits(struct hw_xmit *phwxmit, sint entry); +extern int32_t rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, _adapter *padapter); +extern signed int rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe); +extern sint xmitframe_enqueue_for_sleeping_sta(_adapter *padapter, struct xmit_frame *pxmitframe); +extern void dequeue_xmitframes_to_sleeping_queue(_adapter *padapter, struct sta_info *psta, _queue *pframequeue); +extern void stop_sta_xmit(_adapter *padapter, struct sta_info *psta); +extern void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta); +extern void xmit_delivery_enabled_frames(_adapter *padapter, struct sta_info *psta, int a3); +extern void rtw_xmit_tasklet(thread_context context); +extern int32_t rtw_xmit(_adapter *padapter, _pkt **ppkt); +extern BOOL rtw_sctx_chk_waring_status(int status); +extern void rtw_sctx_done_err(struct submit_ctx **sctx, int status); +extern struct list_head *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv, _irqL a2); +extern int32_t rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf, int a3); +extern struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv, uint32_t size, int a3); +extern void rtw_sctx_done(struct submit_ctx **sctx); +// Data declarations +//-------------------------------- +// phydm_RegConfig8195A.o +// Function declarations +extern void odm_ConfigRFReg_8195A(PDM_ODM_T pDM_Odm, u4Byte Addr, u4Byte Data, ODM_RF_RADIO_PATH_E RF_PATH, u4Byte RegAddr); +extern void odm_ConfigRF_RadioA_8195A(PDM_ODM_T pDM_Odm, u4Byte Addr, u4Byte Data); +extern void odm_ConfigBB_AGC_8195A(PDM_ODM_T pDM_Odm, u4Byte Addr, u4Byte Bitmask, u4Byte Data); +extern void odm_ConfigBB_PHY_REG_PG_8195A(PDM_ODM_T pDM_Odm, u4Byte Band, u4Byte RfPath, u4Byte TxNum, u4Byte Addr, u4Byte Bitmask, u4Byte Data); +extern void odm_ConfigBB_PHY_8195A(PDM_ODM_T pDM_Odm, u4Byte Addr, u4Byte Bitmask, u4Byte Data); +extern void odm_ConfigBB_TXPWR_LMT_8195A(PDM_ODM_T pDM_Odm, int Regulation, int Band, int Bandwidth, u1Byte RateSection, u1Byte RfPath, u1Byte Channel, u1Byte PowerLimit); +// Data declarations +//-------------------------------- +// lxbus_hci_intf.o +// Function declarations +extern struct dvobj_priv *hci_lxbus_dvobj_init(); +extern void hci_lxbus_dvobj_deinit(struct dvobj_priv *dvobj); +extern void hci_lxbus_dvobj_request_irq(struct dvobj_priv *dvobj); +extern void hci_lxbus_free_irq(struct dvobj_priv *dvobj); +extern void hci_lxbus_intf_stop(PADAPTER padapter); +// Data declarations +//-------------------------------- +// lxbus_intf.o +// Function declarations +extern signed int lextra_bus_dma_Interrupt(void *data); +// Data declarations +//-------------------------------- +// lxbus_ops.o +// Function declarations +extern void rtl8195a_free_rx_ring(_adapter *padapter); +extern int bus_write32(struct dvobj_priv *pintfhdl, uint32_t addr, uint32_t val, int32_t *err); +extern int bus_write16(struct dvobj_priv *pintfhdl, uint32_t addr, int val, int32_t *err); +extern int bus_write8(struct dvobj_priv *pintfhdl, uint32_t addr, int val, int32_t *err); +extern uint32_t bus_read32(struct dvobj_priv *pintfhdl, uint32_t addr, int32_t *err); +extern int bus_read16(struct dvobj_priv *pintfhdl, uint32_t addr, int32_t *err); +extern int bus_read8(struct dvobj_priv *pintfhdl, uint32_t addr, int32_t *err); +extern void rtl8195a_free_tx_ring(_adapter *padapter, unsigned int prio); +extern signed int rtl8195a_init_desc_ring(_adapter *padapter); +extern signed int rtl8195a_free_desc_ring(_adapter *padapter); +extern void rtl8195a_reset_desc_ring(_adapter *padapter, _irqL a2, int a3); +extern void InitLxDmaRtl8195a(_adapter *Adapter); +extern void rtl8195a_prepare_bcn_tasklet(void *priv); +extern signed int get_txdesc_buf_addr(int ff_hwaddr); +extern signed int rtl8195a_check_txdesc_closed(_adapter *padapter, uint32_t queue_idx, uint32_t index); +extern void rtl8195a_tx_isr(PADAPTER Adapter, int prio); +extern signed int InterruptRecognized8195a(PADAPTER Adapter); +extern void InitInterrupt8195a(PADAPTER padapter); +extern void EnableDMA8195a(PADAPTER padapter); +extern void EnableInterrupt8195a(PADAPTER padapter); +extern void DisableDMA8195a(PADAPTER padapter); +extern void DisableInterrupt8195a(PADAPTER padapter); +extern void UpdateInterruptMask8195a(PADAPTER Adapter, uint32_t *pAddMSRB, uint32_t *pRemoveMSR); +extern signed int CheckRxTgRtl8195a(_adapter *padapter, uint8_t *rx_desc, uint16_t rx_queue_idx); +extern int rtl8192ee_check_rxdesc_remain(_adapter *padapter, int rx_queue_idx); +extern void rtl8195a_recv_tasklet(void *priv); +extern void rtl8195a_tx_int_handler(_adapter *padapter, int a2, int a3); +extern int32_t InterruptHandle8195a(_adapter *padapter, int a2, int a3); +extern void rtl8195a_xmit_tasklet(void *priv); +extern void lxbus_set_intf_ops(struct _io_ops *pops); +// Data declarations +extern uint8_t rx_ring_pool[4][2104]; +extern u16 CSWTCH_48[8]; // = { 928, 932, 936, 940, 936, 944, 952, 936 }; +extern uint8_t stop_report_count_20629; +//-------------------------------- +// phydm_ACS.o +// Function declarations +extern void phydm_CLMInit(PVOID pDM_VOID, u2Byte sampleNum); +extern void phydm_CLMtrigger(PVOID pDM_VOID); +extern int phydm_checkCLMready(PVOID pDM_VOID); +extern int phydm_getCLMresult(PVOID pDM_VOID); +extern void phydm_NHMInit(PVOID pDM_VOID, u2Byte sampleNum, int round); +extern void phydm_NHMtrigger(PVOID pDM_VOID); +extern void phydm_FalseAlarmCounterStatistics(PVOID pDM_VOID); +extern void phydm_getNHMresult(PVOID pDM_VOID, unsigned int *fa_crc32_total_cnt, unsigned int *cca_count, unsigned int *nhm_cnt_exp_sum, u8 round); +// Data declarations +//-------------------------------- +// PhyDM_Adaptivity.o +// Function declarations +extern void Phydm_CheckAdaptivity(PVOID pDM_VOID); +extern void Phydm_NHMCounterStatisticsInit(PVOID pDM_VOID); +extern void Phydm_GetNHMCounterStatistics(PVOID pDM_VOID); +extern void Phydm_NHMCounterStatisticsReset(PVOID pDM_VOID); +extern void Phydm_NHMCounterStatistics(PVOID pDM_VOID); +extern void Phydm_SetEDCCAThreshold(PVOID pDM_VOID, s1Byte H2L, s1Byte L2H); +extern void Phydm_SetTRxMux(PVOID pDM_VOID, PhyDM_Trx_MUX_Type txMode, PhyDM_Trx_MUX_Type rxMode); +extern void Phydm_MACEDCCAState(PVOID pDM_VOID, PhyDM_MACEDCCA_Type State); +extern BOOL Phydm_CalNHMcnt(PVOID pDM_VOID); +extern void Phydm_CheckEnvironment(PVOID pDM_VOID); +extern void Phydm_SearchPwdBLowerBound(PVOID pDM_VOID); +extern void Phydm_AdaptivityInit(PVOID pDM_VOID); +extern void Phydm_Adaptivity(PVOID pDM_VOID, int IGI); +// Data declarations +//-------------------------------- +// PhyDM_AntDiv.o +// Function declarations +extern void ODM_SwAntDivRestAfterLink(PDM_ODM_T pDM_Odm); +// Data declarations +//-------------------------------- +// phydm_CfoTracking.o +// Function declarations +extern void ODM_CfoTrackingInit(PVOID pDM_VOID); +extern void ODM_CfoTracking(PVOID pDM_VOID); +extern void ODM_ParsingCFO(PVOID pDM_VOID, PVOID pPktinfo_VOID, s1Byte *pcfotail); +// Data declarations +//-------------------------------- +// phydm_debug.o +// Function declarations +extern void ODM_InitDebugSetting(PDM_ODM_T pDM_Odm); +// Data declarations +//-------------------------------- +// phydm_DIG.o +// Function declarations +extern void ODM_ChangeDynamicInitGainThresh(PVOID pDM_VOID, u4Byte DM_Type, u4Byte DM_Value); +extern int getIGIForDiff(int value_IGI); +extern void ODM_Write_DIG(PVOID pDM_VOID, u1Byte CurrentIGI); +extern void odm_PauseDIG(PVOID pDM_VOID, ODM_Pause_DIG_TYPE PauseType, u1Byte IGIValue); +extern u1Byte odm_ForbiddenIGICheck(PVOID pDM_VOID, u1Byte DIG_Dynamic_MIN, u1Byte CurrentIGI); +extern void ODM_Write_CCK_CCA_Thres(PVOID pDM_VOID, u1Byte CurCCK_CCAThres); +extern void odm_PauseCCKPacketDetection(PVOID pDM_VOID, ODM_Pause_CCKPD_TYPE PauseType, u1Byte CCKPDThreshold); +extern void odm_DIGInit(PVOID pDM_VOID); +extern BOOLEAN odm_DigAbort(PVOID pDM_VOID); +extern void odm_DIGbyRSSI_LPS(PVOID pDM_VOID); +extern void odm_FAThresholdCheck(PVOID pDM_VOID, u4Byte *dm_FA_thres); +extern void odm_DIG(PVOID pDM_VOID); +extern void odm_FalseAlarmCounterStatistics(PVOID pDM_VOID); +extern void odm_CCKPacketDetectionThresh(PVOID pDM_VOID); +// Data declarations +extern BOOLEAN bPaused_20545; +//-------------------------------- +// phydm_HWConfig.o +// Function declarations +extern u1Byte odm_QueryRxPwrPercentage(s1Byte AntPower); +extern s4Byte odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Lenovo(PDM_ODM_T pDM_Odm, s4Byte CurrSig); +extern s4Byte odm_SignalScaleMapping_92CSeries_patch_RT_CID_819x_Netcore(PDM_ODM_T pDM_Odm, s4Byte CurrSig); +extern s4Byte odm_SignalScaleMapping_92CSeries(PDM_ODM_T pDM_Odm, s4Byte CurrSig); +extern s4Byte odm_SignalScaleMapping(PDM_ODM_T pDM_Odm, s4Byte CurrSig); +extern void odm_RxPhyStatus8195A_Parsing(PDM_ODM_T pDM_Odm, PODM_PHY_INFO_T pPhyInfo, pu1Byte pPhyStatus, PODM_PACKET_INFO_T pPktinfo); +extern void odm_Process_RSSIForDM_8195A(PDM_ODM_T pDM_Odm, PODM_PHY_INFO_T pPhyInfo, PODM_PACKET_INFO_T pPktinfo, pu1Byte pPhyStatus); +extern void ODM_PhyStatusQuery_8195A(PDM_ODM_T pDM_Odm, PODM_PHY_INFO_T pPhyInfo, pu1Byte pPhyStatus, PODM_PACKET_INFO_T pPktinfo); +extern HAL_STATUS ODM_ConfigRFWithHeaderFile(PDM_ODM_T pDM_Odm, ODM_RF_Config_Type ConfigType, ODM_RF_RADIO_PATH_E eRFPath); +extern HAL_STATUS ODM_ConfigRFWithTxPwrTrackHeaderFile(PDM_ODM_T pDM_Odm); +extern HAL_STATUS ODM_ConfigBBWithHeaderFile(PDM_ODM_T pDM_Odm, ODM_BB_Config_Type ConfigType); +extern HAL_STATUS ODM_ConfigMACWithHeaderFile(PDM_ODM_T pDM_Odm); +extern HAL_STATUS ODM_ConfigFWWithHeaderFile(PDM_ODM_T pDM_Odm, ODM_FW_Config_Type ConfigType, u1Byte *pFirmware, u4Byte *pSize); +extern u4Byte ODM_GetHWImgVersion(PDM_ODM_T pDM_Odm); +// Data declarations +//-------------------------------- +// phydm_interface.o +// Function declarations +extern u1Byte ODM_Read1Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr); +extern u2Byte ODM_Read2Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr); +extern u4Byte ODM_Read4Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr); +extern void ODM_Write1Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u1Byte Data); +extern void ODM_Write2Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u2Byte Data); +extern void ODM_Write4Byte(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u4Byte Data); +extern void ODM_SetMACReg(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u4Byte BitMask, u4Byte Data); +extern u4Byte ODM_GetMACReg(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u4Byte BitMask); +extern void ODM_SetBBReg(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u4Byte BitMask, u4Byte Data); +extern u4Byte ODM_GetBBReg(PDM_ODM_T pDM_Odm, u4Byte RegAddr, u4Byte BitMask); +// void __usercall ODM_SetRFReg(PDM_ODM_T pDM_Odm@, ODM_RF_RADIO_PATH_E eRFPath@, u4Byte RegAddr@, u4Byte BitMask@, u4Byte Data); +extern u4Byte ODM_GetRFReg(PDM_ODM_T pDM_Odm, ODM_RF_RADIO_PATH_E eRFPath, u4Byte RegAddr, u4Byte BitMask); +extern void ODM_AllocateMemory(PDM_ODM_T pDM_Odm, PVOID *pPtr, u4Byte length); +extern void ODM_FreeMemory(PDM_ODM_T pDM_Odm, PVOID pPtr, u4Byte length); +extern void ODM_MoveMemory(PDM_ODM_T pDM_Odm, PVOID pDest, PVOID pSrc, u4Byte Length); +extern u8Byte ODM_GetCurrentTime(PDM_ODM_T pDM_Odm); +extern u8Byte ODM_GetProgressingTime(PDM_ODM_T pDM_Odm, u8Byte Start_Time); +// Data declarations +//-------------------------------- +// phydm_PowerTracking.o +// Function declarations +extern signed int getSwingIndex(PVOID pDM_VOID); +extern void odm_TXPowerTrackingThermalMeterInit(PVOID pDM_VOID); +extern void odm_TXPowerTrackingCheckIOT(PVOID pDM_VOID); +extern void ODM_TXPowerTrackingCheck(PVOID pDM_VOID); +// Data declarations +extern const u4Byte OFDMSwingTable_New[43]; /* = +{ + 188743725u, 201326640u, 213909555u, 226492470u, 239075385u, 251658300u, 268435520u, + 285212740u, 301989960u, 318767180u, 339738705u, 360710230u, 381681755u, 402653280u, + 427819110u, 452984940u, 478150770u, 507510905u, 536871040u, 570425480u, 603979920u, + 637534360u, 679477410u, 717226155u, 759169205u, 805306560u, 851443915u, 901775575u, + 956301540u, 1015021810u, 1073742080u, 1136656655u, 1203765535u, 1275068720u, 1350566210u, + 1430258005u, 1514144105u, 1606418815u, 1698693525u, 1803551150u, 1908408775u, 2021655010u, + 2139095550u +}; */ +//-------------------------------- +// phydm_RaInfo.o +// Function declarations +extern void odm_RSSIMonitorInit(PVOID pDM_VOID); +extern void ODM_RAPostActionOnAssoc(PVOID pDM_VOID); +extern void odm_RSSIMonitorCheckIOT(PVOID pDM_VOID); +extern void odm_RSSIMonitorCheck(PVOID pDM_VOID); +extern void odm_RateAdaptiveMaskInit(PVOID pDM_VOID); +extern BOOLEAN ODM_RAStateCheck(PVOID pDM_VOID, s4Byte RSSI, BOOLEAN bForceUpdate, pu1Byte pRATRState); +extern void odm_RefreshRateAdaptiveMaskIOT(PVOID pDM_VOID); +extern void odm_RefreshRateAdaptiveMask(PVOID pDM_VOID); +extern u4Byte ODM_Get_Rate_Bitmap(PVOID pDM_VOID, u4Byte macid, u4Byte ra_mask, u1Byte rssi_level); +//------------------------------------------------------------------------- +// hal_com_phycfg.o +// Function declarations +extern int PHY_GetTxPowerByRateBase(PADAPTER Adapter, int Band, int RfPath, int TxNum, RATE_SECTION RateSection); +extern void phy_SetTxPowerByRateBase(PADAPTER Adapter, int Band, int RfPath, RATE_SECTION RateSection, uint8_t TxNum, uint8_t Value); +extern void PHY_GetRateValuesOfTxPowerByRate(PADAPTER pAdapter, uint32_t RegAddr, uint32_t BitMask, uint32_t Value, uint8_t *RateIndex, int8_t *PwrByRateVal, uint8_t *RateNum); +extern void PHY_StoreTxPowerByRateNew(PADAPTER pAdapter, uint32_t Band, uint32_t RfPath, uint32_t TxNum, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern void PHY_InitTxPowerByRate(PADAPTER pAdapter); +extern void PHY_StoreTxPowerByRate(PADAPTER pAdapter, uint32_t Band, uint32_t RfPath, uint32_t TxNum, uint32_t RegAddr, uint32_t BitMask, uint32_t Data); +extern signed int phy_GetChnlIndex(int Channel, uint8_t *ChannelIdx); +extern signed int PHY_GetTxPowerIndexBase(PADAPTER pAdapter, int RFPath, int Rate, CHANNEL_WIDTH BandWidth, uint8_t Channel, PBOOLEAN bIn24G); +extern PADAPTER PHY_GetTxPowerTrackingOffset(PADAPTER result, int RFPath, int Rate); +extern int PHY_GetRateIndexOfTxPowerByRate(uint8_t Rate); +extern unsigned int PHY_GetTxPowerByRate(PADAPTER pAdapter, int Band, int RFPath, int TxNum, uint8_t Rate); +extern void phy_StoreTxPowerByRateBase(PADAPTER pAdapter); +extern void PHY_SetTxPowerByRate(PADAPTER pAdapter, int Band, int RFPath, int TxNum, uint8_t Rate, int8_t Value); +extern void phy_ConvertTxPowerByRateInDbmToRelativeValues(PADAPTER pAdapter); +extern void PHY_TxPowerByRateConfiguration(PADAPTER pAdapter); +extern void PHY_SetTxPowerIndexByRateArray(PADAPTER pAdapter, int RFPath, CHANNEL_WIDTH BandWidth, uint8_t Channel, uint8_t *Rates, uint8_t RateArraySize); +extern void PHY_SetTxPowerIndexByRateSection(PADAPTER pAdapter, int RFPath, uint8_t Channel, int RateSection); +extern void PHY_SetTxPowerLevelByPath(PADAPTER Adapter, uint8_t channel, int path); +extern signed int phy_GetWorldWideLimit(int8_t *LimitTable, int regulation, int16_t channel); +extern int phy_GetChannelIndexOfTxPowerLimit(int Band, uint8_t Channel); +extern int PHY_GetTxPowerLimit(PADAPTER Adapter, uint32_t RegPwrTblSel, BAND_TYPE Band, CHANNEL_WIDTH Bandwidth, uint8_t RfPath, uint8_t DataRate, uint8_t Channel); +extern void PHY_ConvertTxPowerLimitToPowerIndex(PADAPTER Adapter); +extern void PHY_InitTxPowerLimit(PADAPTER Adapter); +extern void PHY_SetTxPowerLimit(PADAPTER Adapter, int Regulation, int Band, int Bandwidth, uint8_t RateSection, uint8_t RfPath, uint8_t Channel, uint8_t PowerLimit); +extern int PHY_GetTxPowerIndex(PADAPTER pAdapter, int RFPath, int Rate, CHANNEL_WIDTH BandWidth, uint8_t Channel); +// Data declarations +//------------------------------------------------------------------------- +// Data declarations + +extern int dword_A50; // = 605557260; // weak +extern int dword_A58; // = 2206368128; // weak +extern u8 CSWTCH_14[132];/* = +{ + 1, 0, 0, 0, 0, 0, 0, 2, 4, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 3, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, + 14, 15, 16, 17, 18, 19 }; */ +//-------------------------------- +// rtl8195a_hal_init.o +// Function declarations +extern void Hal_GetEfuseDefinition(PADAPTER padapter, uint8_t efuseType, int type, void *pOut, uint8_t bPseudoTest); +extern void ResumeTxBeacon(PADAPTER padapter); +extern void UpdateHalRAMask8195A(PADAPTER padapter, uint32_t mac_id, uint8_t rssi_level); +extern void HalLittleWifiMCUThreadRtl8195a(thread_context context); +extern void HalCheckInReqStateThreadRtl8195a(thread_context context); +extern void HalTDMAChangeStateThreadRtl8195a(thread_context context); +extern void rtl8195a_read_chip_version(PADAPTER padapter); +extern signed int Hal_EfuseWordEnableDataWrite(PADAPTER padapter, int efuse_addr, uint8_t word_en, uint8_t *data, uint8_t bPseudoTest); +extern void Hal_EfusePowerSwitch(PADAPTER padapter, int bWrite, int PwrState); +extern void rtl8195a_free_hal_data(PADAPTER padapter); +extern void StopTxBeacon(PADAPTER padapter); +extern void SetHalODMVar8195A(PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, int bSet); +extern void rtl8195a_start_thread(_adapter *padapter); +extern void rtl8195a_stop_thread(_adapter *padapter); +extern void Hal_ReadEFuse(PADAPTER padapter, int efuseType, int _offset, int _size_byte, uint8_t *pbuf, uint8_t bPseudoTest); +extern void GetHalODMVar8195A(PADAPTER Adapter, HAL_ODM_VARIABLE eVariable, PVOID pValue1, BOOLEAN bSet); +extern signed int rtw_flash_map_update(PADAPTER padapter, uint8_t *configTbl); +extern void rtw_flash_map_erase(PADAPTER padapter, int a2, int a3, uint32_t a4); +extern int32_t Hal_EfusePgPacketWrite(PADAPTER padapter, uint8_t offset, int word_en, uint8_t *pData, uint8_t bPseudoTest); +extern int Hal_EfuseGetCurrentSize(PADAPTER pAdapter, uint8_t efuseType, int bPseudoTest); +extern signed int rtw_flash_map_write(PADAPTER padapter, uint16_t addr, uint16_t cnts, uint8_t *data); +extern int32_t rtl8195a_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw); +extern void rtl8195a_InitBeaconParameters(PADAPTER padapter); +extern void InitBurstPktLen_8195AB(PADAPTER Adapter); +extern void rtl8195a_set_hal_ops(struct hal_ops *pHalFunc); +extern int32_t rtl8195a_InitLLTTable(PADAPTER padapter); +extern signed int Hal_GetChnlGroup8195A(int Channel, uint8_t *pGroup); +extern signed int rtw_flash_read(PADAPTER padapter, int addr, int cnts, uint8_t *data); +extern signed int rtw_flash_write(PADAPTER padapter, int addr, int cnts, uint8_t *data); +extern int rtw_config_map_read(PADAPTER padapter, int addr, int cnts, uint8_t *data, uint8_t efuse); +extern int rtw_config_map_write(PADAPTER padapter, int addr, int cnts, uint8_t *data, uint8_t efuse); +extern void Hal_InitPGData(PADAPTER padapter, uint8_t *PROMContent, int a3, int a4); +extern void Hal_EfuseParseIDCode(PADAPTER padapter, uint8_t *hwinfo); +extern void Hal_ReadPowerValueFromPROM_8195A(PADAPTER Adapter, PTxPowerInfo24G pwrInfo24G, uint8_t *PROMContent, int AutoLoadFail); +extern void Hal_EfuseParseTxPowerInfo_8195A(PADAPTER padapter, uint8_t *PROMContent, int AutoLoadFail); +extern void Hal_EfuseParseEEPROMVer_8195A(PADAPTER padapter, uint8_t *hwinfo, int AutoLoadFail); +extern void Hal_EfuseParsePackageType_8195A(PADAPTER pAdapter, uint8_t *hwinfo, int a3); +extern void Hal_EfuseParseChnlPlan_8195A(PADAPTER padapter, uint8_t *hwinfo, BOOLEAN AutoLoadFail); +extern void Hal_EfuseParseCustomerID_8195A(PADAPTER padapter, uint8_t *hwinfo, int AutoLoadFail); +extern void Hal_EfuseParseXtal_8195A(PADAPTER pAdapter, uint8_t *hwinfo, int AutoLoadFail); +extern void Hal_EfuseParseThermalMeter_8195A(PADAPTER padapter, uint8_t *PROMContent, int AutoLoadFail); +extern void Hal_ReadRFGainOffset(PADAPTER Adapter, uint8_t *PROMContent, int AutoloadFail); +extern int BWMapping_8195A(PADAPTER Adapter, struct pkt_attrib *pattrib); +extern signed int SCMapping_8195A(PADAPTER Adapter, struct pkt_attrib *pattrib); +extern void rtl8195a_update_txdesc(struct xmit_frame *pxmitframe, uint8_t *pbuf); +extern void rtl8195a_fill_fake_txdesc(PADAPTER padapter, uint8_t *pDesc, uint32_t BufferLen, int IsPsPoll, uint8_t IsBTQosNull, uint8_t bDataFrame); +extern void SetHwReg8195A(PADAPTER padapter, int variable, uint8_t *val); +extern void GetHwReg8195A(PADAPTER padapter, int variable, uint8_t *val); +extern signed int SetHalDefVar8195A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +extern signed int GetHalDefVar8195A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval); +// Data declarations +extern const struct map_mask_s efuse_map_mask[4]; // = { { 32u, 207u }, { 220u, 221u }, { 282u, 311u }, { 313u, 319u } }; +extern const struct map_mask_s flash_map_mask[2]; // = { { 32u, 311u }, { 313u, 319u } }; +//-------------------------------- +// rtw_ap.o +// Function declarations +extern int rtw_ht_operation_update(_adapter *padapter); +extern void associated_clients_update_0(_adapter *padapter, int updated, int a3); +extern signed int chk_sta_is_alive(struct sta_info *psta); +extern void add_RATid(_adapter *padapter, struct sta_info *psta, int rssi_level); +extern void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta, int a3); +extern void update_beacon(_adapter *padapter, int ie_id, uint8_t *oui, uint8_t tx); +extern int rtw_check_beacon_data(_adapter *padapter, uint8_t *pbuf, int len); +extern void associated_clients_update(_adapter *padapter, int updated, int a3); +extern void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta); +extern signed int bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta); +extern signed int ap_free_sta(_adapter *padapter, struct sta_info *psta, int reason); +extern void expire_timeout_chk(_adapter *padapter); +extern int rtw_sta_flush(_adapter *padapter); +extern void free_mlme_ap_info(_adapter *padapter, _irqL a2); +extern void sta_info_update(_adapter *padapter, struct sta_info *psta); +extern void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta); +extern void start_ap_mode(_adapter *padapter); +extern void init_mlme_ap_info(_adapter *padapter); +extern void stop_ap_mode(_adapter *padapter, _irqL a2); +extern uint32_t rtw_generate_bcn_ie(_adapter *adapter, uint8_t *ssid, int ssid_len, uint8_t *ie); +extern int set_hidden_ssid(const char *ifname, uint8_t value); +// Data declarations +//-------------------------------- + +#ifdef __cplusplus +} +#endif +#endif // _WIFI_LIB_H + diff --git a/USDK/component/common/drivers/wlan/realtek/src/core/option/rtw_opt_skbuf.c b/USDK/component/common/drivers/wlan/realtek/src/core/option/rtw_opt_skbuf.c new file mode 100644 index 0000000..6639a2e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/core/option/rtw_opt_skbuf.c @@ -0,0 +1,32 @@ +#include +#include +#include + +#define MAX_SKB_BUF_SIZE 1650 // should >= the size in wlan driver +#define MAX_SKB_BUF_NUM 8 +#define MAX_LOCAL_SKB_NUM (MAX_SKB_BUF_NUM + 2) + +/* DO NOT modify skb_buf and skb_data structure */ +struct skb_buf { + struct list_head list; + struct sk_buff skb; +}; + +struct skb_data { + struct list_head list; + unsigned char buf[MAX_SKB_BUF_SIZE]; + atomic_t ref; +}; + +unsigned int nr_xmitframe = MAX_SKB_BUF_NUM; +unsigned int nr_xmitbuff = MAX_SKB_BUF_NUM; +int max_local_skb_num = MAX_LOCAL_SKB_NUM; +int max_skb_buf_num = MAX_SKB_BUF_NUM; + +/* DO NOT access skb_pool and skb_data_pool out of wlan driver */ +struct skb_buf skb_pool[MAX_LOCAL_SKB_NUM]; + +// SRAM_BD_DATA_SECTION default in SRAM. Can modify image2.icf to link to the end of SDRAM +SRAM_BD_DATA_SECTION +struct skb_data skb_data_pool[MAX_SKB_BUF_NUM]; + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/HalPhyRf.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/HalPhyRf.h new file mode 100644 index 0000000..0d5c32a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/HalPhyRf.h @@ -0,0 +1,102 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + #ifndef __HAL_PHY_RF_H__ + #define __HAL_PHY_RF_H__ + +typedef enum _SPUR_CAL_METHOD { + PLL_RESET, + AFE_PHASE_SEL +} SPUR_CAL_METHOD; + +typedef enum _PWRTRACK_CONTROL_METHOD { + BBSWING, + TXAGC, + MIX_MODE +} PWRTRACK_METHOD; + +typedef VOID (*FuncSetPwr)(PDM_ODM_T, PWRTRACK_METHOD, u1Byte, u1Byte); +typedef VOID (*FuncIQK)(PDM_ODM_T, u1Byte, u1Byte, u1Byte); +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) +typedef VOID (*FuncLCK)(PDM_ODM_T); +#else +typedef VOID (*FuncLCK)(PADAPTER); +#endif +#else +typedef VOID (*FuncLCK)(PDM_ODM_T); +#endif +typedef VOID (*FuncSwing)(PDM_ODM_T, ps1Byte*, ps1Byte*, ps1Byte*, ps1Byte*); +typedef VOID (*FuncSwingXtal)(PDM_ODM_T, ps1Byte*, ps1Byte*); +typedef VOID (*FuncSetXtal)(PDM_ODM_T); + + +typedef struct _TXPWRTRACK_CFG { + u1Byte SwingTableSize_CCK; + u1Byte SwingTableSize_OFDM; + u1Byte Threshold_IQK; + u1Byte AverageThermalNum; + u1Byte RfPathCount; + u4Byte ThermalRegAddr; + FuncSetPwr ODM_TxPwrTrackSetPwr; + FuncIQK DoIQK; + FuncLCK PHY_LCCalibrate; + FuncSwing GetDeltaSwingTable; + FuncSwingXtal GetDeltaSwingXtalTable; + FuncSetXtal ODM_TxXtalTrackSetXtal; +} TXPWRTRACK_CFG, *PTXPWRTRACK_CFG; + +void ConfigureTxpowerTrack( + IN PDM_ODM_T pDM_Odm, + OUT PTXPWRTRACK_CFG pConfig + ); + + +VOID +ODM_ClearTxPowerTrackingState( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_TXPowerTrackingCallback_ThermalMeter( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER Adapter +#endif + ); + + + +#define ODM_TARGET_CHNL_NUM_2G_5G 59 + + +VOID +ODM_ResetIQKResult( + IN PDM_ODM_T pDM_Odm +); +u1Byte +ODM_GetRightChnlPlaceforIQK( + IN u1Byte chnl +); + + +#endif // #ifndef __HAL_PHY_RF_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/PhyDM_Adaptivity.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/PhyDM_Adaptivity.h new file mode 100644 index 0000000..ac29d6f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/PhyDM_Adaptivity.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMADAPTIVITY_H__ +#define __PHYDMADAPTIVITY_H__ + +#define ADAPTIVITY_VERSION "8.4" + +#define PwdBUpperBound 7 +#define DFIRloss 5 + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +typedef enum _tag_PhyDM_REGULATION_Type { + REGULATION_FCC = 0, + REGULATION_MKK = 1, + REGULATION_ETSI = 2, + REGULATION_WW = 3, + + MAX_REGULATION_NUM = 4 +} PhyDM_REGULATION_TYPE; +#endif + + +typedef enum tag_PhyDM_TRx_MUX_Type +{ + PhyDM_SHUTDOWN = 0, + PhyDM_STANDBY_MODE = 1, + PhyDM_TX_MODE = 2, + PhyDM_RX_MODE = 3 +}PhyDM_Trx_MUX_Type; + +typedef enum tag_PhyDM_MACEDCCA_Type +{ + PhyDM_IGNORE_EDCCA = 0, + PhyDM_DONT_IGNORE_EDCCA = 1 +}PhyDM_MACEDCCA_Type; + +typedef struct _ADAPTIVITY_STATISTICS { + s1Byte TH_L2H_ini_mode2; + s1Byte TH_EDCCA_HL_diff_mode2; + s1Byte TH_EDCCA_HL_diff_backup; + s1Byte IGI_Base; + u1Byte IGI_target; + u1Byte NHMWait; + s1Byte H2L_lb; + s1Byte L2H_lb; + BOOLEAN bFirstLink; + BOOLEAN bCheck; + BOOLEAN DynamicLinkAdaptivity; + u1Byte APNumTH; + u1Byte AdajustIGILevel; + BOOLEAN bStopEDCCA; +} ADAPTIVITY_STATISTICS, *PADAPTIVITY_STATISTICS; + +VOID +Phydm_CheckAdaptivity( + IN PVOID pDM_VOID + ); + +VOID +Phydm_CheckEnvironment( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMCounterStatisticsInit( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMCounterStatistics( + IN PVOID pDM_VOID + ); + +VOID +Phydm_NHMCounterStatisticsReset( + IN PVOID pDM_VOID +); + +VOID +Phydm_GetNHMCounterStatistics( + IN PVOID pDM_VOID +); + +VOID +Phydm_MACEDCCAState( + IN PVOID pDM_VOID, + IN PhyDM_MACEDCCA_Type State +); + +VOID +Phydm_SetEDCCAThreshold( + IN PVOID pDM_VOID, + IN s1Byte H2L, + IN s1Byte L2H +); + +VOID +Phydm_SetTRxMux( + IN PVOID pDM_VOID, + IN PhyDM_Trx_MUX_Type txMode, + IN PhyDM_Trx_MUX_Type rxMode +); + +BOOLEAN +Phydm_CalNHMcnt( + IN PVOID pDM_VOID +); + +VOID +Phydm_SearchPwdBLowerBound( + IN PVOID pDM_VOID +); + +VOID +Phydm_AdaptivityInit( + IN PVOID pDM_VOID + ); + +VOID +Phydm_Adaptivity( + IN PVOID pDM_VOID, + IN u1Byte IGI + ); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +Phydm_DisableEDCCA( + IN PVOID pDM_VOID +); + +VOID +Phydm_DynamicEDCCA( + IN PVOID pDM_VOID +); + +VOID +Phydm_AdaptivityBSOD( + IN PVOID pDM_VOID +); + +#endif + + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/mp_precomp.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/mp_precomp.h new file mode 100644 index 0000000..4e376e7 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/mp_precomp.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +//#include +//#include "phydm_precomp.h" +//#include "../phydm_precomp.h" + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm.h new file mode 100644 index 0000000..e7f015e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm.h @@ -0,0 +1,2088 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __HALDMOUTSRC_H__ +#define __HALDMOUTSRC_H__ + + +#include "phydm_EdcaTurboCheck.h" +#include "phydm_DIG.h" +#include "phydm_PathDiv.h" +#include "phydm_RaInfo.h" +#include "phydm_DynamicBBPowerSaving.h" +#include "phydm_DynamicTxPower.h" +#include "phydm_CfoTracking.h" +#include "phydm_PowerTracking.h" +#include "PhyDM_Adaptivity.h" +#include "phydm_NoiseMonitor.h" +#if RTL8195A_SUPPORT +#include "rtl8195a/ROM_RTL8195A_PHYDM.h" +#endif + +#if RTL8711B_SUPPORT +#include "rtl8711b/ROM_RTL8711B_PHYDM.h" +#endif + +//============================================================ +// Definition +//============================================================ +// +// 2011/09/22 MH Define all team supprt ability. +// + +// +// 2011/09/22 MH Define for all teams. Please Define the constan in your precomp header. +// +//#define DM_ODM_SUPPORT_AP 0 +//#define DM_ODM_SUPPORT_ADSL 0 +//#define DM_ODM_SUPPORT_CE 0 +//#define DM_ODM_SUPPORT_MP 1 + +// +// 2011/09/28 MH Define ODM SW team support flag. +// + + + +// +// Antenna Switch Relative Definition. +// + +// +// 20100503 Joseph: +// Add new function SwAntDivCheck8192C(). +// This is the main function of Antenna diversity function before link. +// Mainly, it just retains last scan result and scan again. +// After that, it compares the scan result to see which one gets better RSSI. +// It selects antenna with better receiving power and returns better scan result. +// +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 + + +//============================================================ +//3 Tx Power Tracking +//3============================================================ +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define TXSCALE_TABLE_SIZE 37 +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define BAND_NUM 4 + +//============================================================ +//3 PSD Handler +//3============================================================ + +#define AFH_PSD 1 //0:normal PSD scan, 1: only do 20 pts PSD +#define MODE_40M 0 //0:20M, 1:40M +#define PSD_TH2 3 +#define PSD_CHMIN 20 // Minimum channel number for BT AFH +#define SIR_STEP_SIZE 3 +#define Smooth_Size_1 5 +#define Smooth_TH_1 3 +#define Smooth_Size_2 10 +#define Smooth_TH_2 4 +#define Smooth_Size_3 20 +#define Smooth_TH_3 4 +#define Smooth_Step_Size 5 +#define Adaptive_SIR 1 +#if(RTL8723_FPGA_VERIFICATION == 1) +#define PSD_RESCAN 1 +#else +#define PSD_RESCAN 4 +#endif +#define PSD_SCAN_INTERVAL 700 //ms + + + +//8723A High Power IGI Setting +#define DM_DIG_HIGH_PWR_IGI_LOWER_BOUND 0x22 +#define DM_DIG_Gmode_HIGH_PWR_IGI_LOWER_BOUND 0x28 +#define DM_DIG_HIGH_PWR_THRESHOLD 0x3a +#define DM_DIG_LOW_PWR_THRESHOLD 0x14 + +//ANT Test +#define ANTTESTALL 0x00 //Ant A or B will be Testing +#define ANTTESTA 0x01 //Ant A will be Testing +#define ANTTESTB 0x02 //Ant B will be testing + +//for 8723A Ant Definition--2012--06--07 due to different IC may be different ANT define +#define MAIN_ANT 1 //Ant A or Ant Main +#define AUX_ANT 2 //AntB or Ant Aux +#define MAX_ANT 3 // 3 for AP using + + +//Antenna Diversity Type +#define SW_ANTDIV 0 +#define HW_ANTDIV 1 +//============================================================ +// structure and define +//============================================================ + +// +// 2011/09/20 MH Add for AP/ADSLpseudo DM structuer requirement. +// We need to remove to other position??? +// +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) +typedef struct rtl8192cd_priv { + u1Byte temp; + +}rtl8192cd_priv, *prtl8192cd_priv; +#endif + + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +typedef struct _ADAPTER{ + u1Byte temp; + #ifdef AP_BUILD_WORKAROUND + HAL_DATA_TYPE* temp2; + prtl8192cd_priv priv; + #endif +}ADAPTER, *PADAPTER; +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + +typedef struct _WLAN_STA{ + u1Byte temp; +} WLAN_STA, *PRT_WLAN_STA; + +#endif + +//Remove DIG by Yuchen + +//Remoce BB power saving by Yuchn + +//Remove DIG by yuchen + +typedef struct _Dynamic_Primary_CCA{ + u1Byte PriCCA_flag; + u1Byte intf_flag; + u1Byte intf_type; + u1Byte DupRTS_flag; + u1Byte Monitor_flag; + u1Byte CH_offset; + u1Byte MF_state; +}Pri_CCA_T, *pPri_CCA_T; + +//Remove RA_T,*pRA_T by RS_James + +typedef struct _RX_High_Power_ +{ + u1Byte RXHP_flag; + u1Byte PSD_func_trigger; + u1Byte PSD_bitmap_RXHP[80]; + u1Byte Pre_IGI; + u1Byte Cur_IGI; + u1Byte Pre_pw_th; + u1Byte Cur_pw_th; + BOOLEAN First_time_enter; + BOOLEAN RXHP_enable; + u1Byte TP_Mode; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) + RT_TIMER PSDTimer; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM PSDTimeWorkitem; + #endif +#endif + +}RXHP_T, *pRXHP_T; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE)) + #define ASSOCIATE_ENTRY_NUM MACID_NUM_SW_LIMIT /* Max size of AsocEntry[].*/ + #define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM +#elif(DM_ODM_SUPPORT_TYPE & (ODM_IOT)) + #ifdef CONFIG_CONCURRENT_MODE + #define ASSOCIATE_ENTRY_NUM NUM_STA+2 // 2 is for station mod + #else + #define ASSOCIATE_ENTRY_NUM NUM_STA//8 // Max size of AsocEntry[]. + #endif + #define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM +#elif(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + #define ASSOCIATE_ENTRY_NUM NUM_STAT + #define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM+1 +#else + #define ODM_ASSOCIATE_ENTRY_NUM ASSOCIATE_ENTRY_NUM+1// Default port only one +#endif + +//#ifdef CONFIG_ANTENNA_DIVERSITY +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 +#define TRAFFIC_UltraLOW 2 + +typedef struct _SW_Antenna_Switch_ +{ + u1Byte Double_chk_flag; + u1Byte try_flag; + s4Byte PreRSSI; + u1Byte CurAntenna; + u1Byte PreAntenna; + u1Byte RSSI_Trying; + u1Byte TestMode; + u1Byte bTriggerAntennaSwitch; + u1Byte SelectAntennaMap; + u1Byte RSSI_target; + u1Byte reset_idx; + + // Before link Antenna Switch check + u1Byte SWAS_NoLink_State; + u4Byte SWAS_NoLink_BK_Reg860; + u4Byte SWAS_NoLink_BK_Reg92c; + BOOLEAN ANTA_ON; //To indicate Ant A is or not + BOOLEAN ANTB_ON; //To indicate Ant B is on or not + u1Byte Ant5G; + u1Byte Ant2G; + + s4Byte RSSI_sum_A; + s4Byte RSSI_sum_B; + s4Byte RSSI_cnt_A; + s4Byte RSSI_cnt_B; + + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u8Byte TXByteCnt_A; + u8Byte TXByteCnt_B; + u8Byte RXByteCnt_A; + u8Byte RXByteCnt_B; + u1Byte TrafficLoad; + u1Byte Train_time; + u1Byte Train_time_flag; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) + RT_TIMER SwAntennaSwitchTimer; +#endif +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + RT_TIMER SwAntennaSwitchTimer_8723B; +#endif +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM SwAntennaSwitchWorkitem; + #if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) + RT_WORK_ITEM SwAntennaSwitchWorkitem_8723B; + #endif + #endif +#endif +/* CE Platform use +#ifdef CONFIG_SW_ANTENNA_DIVERSITY + _timer SwAntennaSwitchTimer; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u8Byte TXByteCnt_A; + u8Byte TXByteCnt_B; + u8Byte RXByteCnt_A; + u8Byte RXByteCnt_B; + u1Byte DoubleComfirm; + u1Byte TrafficLoad; + //SW Antenna Switch + + +#endif +*/ +#ifdef CONFIG_HW_ANTENNA_DIVERSITY + //Hybrid Antenna Diversity + u4Byte CCK_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; + u4Byte CCK_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; + u4Byte OFDM_Ant1_Cnt[ASSOCIATE_ENTRY_NUM]; + u4Byte OFDM_Ant2_Cnt[ASSOCIATE_ENTRY_NUM]; + u4Byte RSSI_Ant1_Sum[ASSOCIATE_ENTRY_NUM]; + u4Byte RSSI_Ant2_Sum[ASSOCIATE_ENTRY_NUM]; + u1Byte TxAnt[ASSOCIATE_ENTRY_NUM]; + u1Byte TargetSTA; + u1Byte antsel; + u1Byte RxIdleAnt; + +#endif + +}SWAT_T, *pSWAT_T; +//#endif + +//Remove Edca by YuChen + +//Remove ODM_RATE_ADAPTIVE by RS_James + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + + +#ifdef ADSL_AP_BUILD_WORKAROUND +#define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 //ms +#endif + +// +// Indicate different AP vendor for IOT issue. +// +typedef enum _HT_IOT_PEER +{ + HT_IOT_PEER_UNKNOWN = 0, + HT_IOT_PEER_REALTEK = 1, + HT_IOT_PEER_REALTEK_92SE = 2, + HT_IOT_PEER_BROADCOM = 3, + HT_IOT_PEER_RALINK = 4, + HT_IOT_PEER_ATHEROS = 5, + HT_IOT_PEER_CISCO = 6, + HT_IOT_PEER_MERU = 7, + HT_IOT_PEER_MARVELL = 8, + HT_IOT_PEER_REALTEK_SOFTAP = 9,// peer is RealTek SOFT_AP, by Bohn, 2009.12.17 + HT_IOT_PEER_SELF_SOFTAP = 10, // Self is SoftAP + HT_IOT_PEER_AIRGO = 11, + HT_IOT_PEER_INTEL = 12, + HT_IOT_PEER_RTK_APCLIENT = 13, + HT_IOT_PEER_REALTEK_81XX = 14, + HT_IOT_PEER_REALTEK_WOW = 15, + HT_IOT_PEER_MAX = 16 +}HT_IOT_PEER_E, *PHTIOT_PEER_E; +#endif//#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + +#define DM_Type_ByFW 0 +#define DM_Type_ByDriver 1 + +// +// Declare for common info +// +#define MAX_PATH_NUM_92CS 2 +#define MAX_PATH_NUM_8188E 1 +#define MAX_PATH_NUM_8192E 2 +#define MAX_PATH_NUM_8723B 1 +#define MAX_PATH_NUM_8812A 2 +#define MAX_PATH_NUM_8821A 1 +#define MAX_PATH_NUM_8195A MAX_RF_PATH // 1 +#define MAX_PATH_NUM_8711B 1 + +//Max RF path +#if ((RTL8195A_SUPPORT == 1) || (RTL8711B_SUPPORT == 1) ) +#define ODM_RF_PATH_MAX MAX_PATH_NUM_8195A +#else +#define ODM_RF_PATH_MAX 2 //92c-series +#endif +#define ODM_RF_PATH_MAX_JAGUAR 4 //jaguar - series + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_IOT)) +#ifdef RTK_AC_SUPPORT +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#else +#define ODM_IC_11AC_SERIES_SUPPORT 0 +#endif +#else +#define ODM_IC_11AC_SERIES_SUPPORT 1 +#endif + +#if (RTL8711B_SUPPORT == 1) +#define ODM_PHY_STATUS_NEW_TYPE_SUPPORT 1 +#else +#define ODM_PHY_STATUS_NEW_TYPE_SUPPORT 0 +#endif + +#define IQK_THRESHOLD 8 +#if 1 //(RTL8195A_SUPPORT == 1) +typedef struct _ODM_Phy_Status_Info_ +{ + // + // Be care, if you want to add any element please insert between + // RxPWDBAll & SignalStrength. + // +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + u4Byte RxPWDBAll; +#else + u1Byte RxPWDBAll; +#endif +#if (DM_ODM_SUPPORT_TYPE & (ODM_IOT)) +#if (RTL8195A_SUPPORT == 1) + u1Byte SignalQuality; // in 0-100 index. + u1Byte RxMIMOSignalStrength[ODM_RF_PATH_MAX]; // in 0~100 index + s1Byte RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. + u1Byte SignalStrength; // in 0-100 index. + #if (ODM_IC_11AC_SERIES_SUPPORT) + u1Byte RxMIMOEVMdbm[ODM_RF_PATH_MAX]; // per-path's EVM dbm + s2Byte Cfo_short[ODM_RF_PATH_MAX]; // per-path's Cfo_short + s2Byte Cfo_tail[ODM_RF_PATH_MAX]; // per-path's Cfo_tail + u1Byte BandWidth; + #endif +#elif (RTL8711B_SUPPORT == 1) + u1Byte SignalQuality; /* in 0-100 index. */ + s1Byte RxMIMOSignalQuality[4]; /* per-path's EVM */ + u1Byte RxMIMOEVMdbm[4]; /* per-path's EVM dbm */ + u1Byte RxMIMOSignalStrength[4]; /* in 0~100 index */ + s2Byte Cfo_short[4]; /* per-path's Cfo_short */ + s2Byte Cfo_tail[4]; /* per-path's Cfo_tail */ + s1Byte RxPower; /* in dBm Translate from PWdB */ + s1Byte RecvSignalPower; /* Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. */ + u1Byte BTRxRSSIPercentage; + u1Byte SignalStrength; /* in 0-100 index. */ + s1Byte RxPwr[4]; /* per-path's pwdb */ + s1Byte RxSNR[4]; /* per-path's SNR */ +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + u1Byte RxCount:2; /* RX path counter---*/ + u1Byte BandWidth:2; + u1Byte rxsc:4; /* sub-channel---*/ +#else + u1Byte BandWidth; +#endif + u1Byte btCoexPwrAdjust; +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + u1Byte channel; /* channel number---*/ + BOOLEAN bMuPacket; /* is MU packet or not---*/ + BOOLEAN bBeamformed; /* BF packet---*/ +#endif +#endif +#else + u1Byte SignalQuality; // in 0-100 index. + s1Byte RxMIMOSignalQuality[4]; //per-path's EVM + u1Byte RxMIMOEVMdbm[4]; //per-path's EVM dbm + u1Byte RxMIMOSignalStrength[4];// in 0~100 index + u2Byte Cfo_short[4]; // per-path's Cfo_short + u2Byte Cfo_tail[4]; // per-path's Cfo_tail + #if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + s1Byte RxPower; // in dBm Translate from PWdB + s1Byte RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. + u1Byte BTRxRSSIPercentage; + u1Byte SignalStrength; // in 0-100 index. + s1Byte RxPwr[4]; //per-path's pwdb + #endif + u1Byte RxSNR[4]; //per-path's SNR + u1Byte BandWidth; + u1Byte btCoexPwrAdjust; +#endif +}ODM_PHY_INFO_T,*PODM_PHY_INFO_T; +#else + +typedef struct _ODM_Phy_Status_Info_ { + // + // Be care, if you want to add any element please insert between + // RxPWDBAll & SignalStrength. + // +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + u4Byte RxPWDBAll; +#else + u1Byte RxPWDBAll; +#endif + u1Byte SignalQuality; /* in 0-100 index. */ + s1Byte RxMIMOSignalQuality[ODM_RF_PATH_MAX]; /* per-path's EVM */ + u1Byte RxMIMOEVMdbm[ODM_RF_PATH_MAX]; /* per-path's EVM dbm */ + u1Byte RxMIMOSignalStrength[ODM_RF_PATH_MAX]; /* in 0~100 index */ + s2Byte Cfo_short[ODM_RF_PATH_MAX]; /* per-path's Cfo_short */ + s2Byte Cfo_tail[ODM_RF_PATH_MAX]; /* per-path's Cfo_tail */ + s1Byte RxPower; /* in dBm Translate from PWdB */ + s1Byte RecvSignalPower; /* Real power in dBm for this packet, no beautification and aggregation. Keep this raw info to be used for the other procedures. */ + u1Byte BTRxRSSIPercentage; + u1Byte SignalStrength; /* in 0-100 index. */ + s1Byte RxPwr[ODM_RF_PATH_MAX]; /* per-path's pwdb */ + s1Byte RxSNR[ODM_RF_PATH_MAX]; /* per-path's SNR */ +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + u1Byte RxCount:2; /* RX path counter---*/ + u1Byte BandWidth:2; + u1Byte rxsc:4; /* sub-channel---*/ +#else + u1Byte BandWidth; +#endif +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_IOT)) + u1Byte btCoexPwrAdjust; +#endif +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + u1Byte channel; /* channel number---*/ + BOOLEAN bMuPacket; /* is MU packet or not---*/ + BOOLEAN bBeamformed; /* BF packet---*/ +#endif +} ODM_PHY_INFO_T, *PODM_PHY_INFO_T; + +#endif +typedef struct _ODM_Per_Pkt_Info_ +{ + //u1Byte Rate; + u1Byte DataRate; + u1Byte StationID; + BOOLEAN bPacketMatchBSSID; + BOOLEAN bPacketToSelf; + BOOLEAN bPacketBeacon; +}ODM_PACKET_INFO_T,*PODM_PACKET_INFO_T; + + +typedef struct _ODM_Phy_Dbg_Info_ +{ + //ODM Write,debug info + s1Byte RxSNRdB[4]; + u4Byte NumQryPhyStatus; + u4Byte NumQryPhyStatusCCK; + u4Byte NumQryPhyStatusOFDM; +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + u4Byte NumQryMuPkt; + u4Byte NumQryBfPkt; + u4Byte NumQryMuVhtPkt[40]; + u4Byte NumQryVhtPkt[40]; + BOOLEAN bLdpcPkt; + BOOLEAN bStbcPkt; +#endif + u1Byte NumQryBeaconPkt; + //Others + s4Byte RxEVM[4]; + +}ODM_PHY_DBG_INFO_T; + + +typedef struct _ODM_Mac_Status_Info_ +{ + u1Byte test; + +}ODM_MAC_INFO; + + +typedef enum tag_Dynamic_ODM_Support_Ability_Type +{ + // BB Team + ODM_DIG = 0x00000001, + ODM_HIGH_POWER = 0x00000002, + ODM_CCK_CCA_TH = 0x00000004, + ODM_FA_STATISTICS = 0x00000008, + ODM_RAMASK = 0x00000010, + ODM_RSSI_MONITOR = 0x00000020, + ODM_SW_ANTDIV = 0x00000040, + ODM_HW_ANTDIV = 0x00000080, + ODM_BB_PWRSV = 0x00000100, + ODM_2TPATHDIV = 0x00000200, + ODM_1TPATHDIV = 0x00000400, + ODM_PSD2AFH = 0x00000800 +}ODM_Ability_E; + +// +// 2011/20/20 MH For MP driver RT_WLAN_STA = STA_INFO_T +// Please declare below ODM relative info in your STA info structure. +// +#if 1 +typedef struct _ODM_STA_INFO{ + // Driver Write + BOOLEAN bUsed; // record the sta status link or not? + //u1Byte WirelessMode; // + u1Byte IOTPeer; // Enum value. HT_IOT_PEER_E + + // ODM Write + //1 PHY_STATUS_INFO + u1Byte RSSI_Path[4]; // + u1Byte RSSI_Ave; + u1Byte RXEVM[4]; + u1Byte RXSNR[4]; + + // ODM Write + //1 TX_INFO (may changed by IC) + //TX_INFO_T pTxInfo; // Define in IC folder. Move lower layer. +#if 0 + u1Byte ANTSEL_A; //in Jagar: 4bit; others: 2bit + u1Byte ANTSEL_B; //in Jagar: 4bit; others: 2bit + u1Byte ANTSEL_C; //only in Jagar: 4bit + u1Byte ANTSEL_D; //only in Jagar: 4bit + u1Byte TX_ANTL; //not in Jagar: 2bit + u1Byte TX_ANT_HT; //not in Jagar: 2bit + u1Byte TX_ANT_CCK; //not in Jagar: 2bit + u1Byte TXAGC_A; //not in Jagar: 4bit + u1Byte TXAGC_B; //not in Jagar: 4bit + u1Byte TXPWR_OFFSET; //only in Jagar: 3bit + u1Byte TX_ANT; //only in Jagar: 4bit for TX_ANTL/TX_ANTHT/TX_ANT_CCK +#endif + + // + // Please use compile flag to disabe the strcutrue for other IC except 88E. + // Move To lower layer. + // + // ODM Write Wilson will handle this part(said by Luke.Lee) + //TX_RPT_T pTxRpt; // Define in IC folder. Move lower layer. +#if 0 + //1 For 88E RA (don't redefine the naming) + u1Byte rate_id; + u1Byte rate_SGI; + u1Byte rssi_sta_ra; + + u1Byte SGI_enable; + u1Byte Decision_rate; + u1Byte Pre_rate; + u1Byte Active; + + // Driver write Wilson handle. + //1 TX_RPT (don't redefine the naming) + u2Byte RTY[4]; // ??? + u2Byte TOTAL; // ??? + u2Byte DROP; // ??? + // + // Please use compile flag to disabe the strcutrue for other IC except 88E. + // +#endif + +}ODM_STA_INFO_T, *PODM_STA_INFO_T; +#endif + +// +// 2011/10/20 MH Define Common info enum for all team. +// +typedef enum _ODM_Common_Info_Definition +{ +//-------------REMOVED CASE-----------// + //ODM_CMNINFO_CCK_HP, + //ODM_CMNINFO_RFPATH_ENABLE, // Define as ODM write??? + //ODM_CMNINFO_BT_COEXIST, // ODM_BT_COEXIST_E + //ODM_CMNINFO_OP_MODE, // ODM_OPERATION_MODE_E +//-------------REMOVED CASE-----------// + + // + // Fixed value: + // + + //-----------HOOK BEFORE REG INIT-----------// + ODM_CMNINFO_PLATFORM = 0, + ODM_CMNINFO_ABILITY, // ODM_ABILITY_E + ODM_CMNINFO_INTERFACE, // ODM_INTERFACE_E + ODM_CMNINFO_MP_TEST_CHIP, + ODM_CMNINFO_IC_TYPE, // ODM_IC_TYPE_E + ODM_CMNINFO_CUT_VER, // ODM_CUT_VERSION_E + ODM_CMNINFO_FAB_VER, // ODM_FAB_E + ODM_CMNINFO_RF_TYPE, // ODM_RF_PATH_E or ODM_RF_TYPE_E? + ODM_CMNINFO_RFE_TYPE, + ODM_CMNINFO_BOARD_TYPE, // ODM_BOARD_TYPE_E + ODM_CMNINFO_PACKAGE_TYPE, + ODM_CMNINFO_EXT_LNA, // TRUE + ODM_CMNINFO_5G_EXT_LNA, + ODM_CMNINFO_EXT_PA, + ODM_CMNINFO_5G_EXT_PA, + ODM_CMNINFO_GPA, + ODM_CMNINFO_APA, + ODM_CMNINFO_GLNA, + ODM_CMNINFO_ALNA, + ODM_CMNINFO_EXT_TRSW, + ODM_CMNINFO_PATCH_ID, //CUSTOMER ID + ODM_CMNINFO_BINHCT_TEST, + ODM_CMNINFO_BWIFI_TEST, + ODM_CMNINFO_SMART_CONCURRENT, + ODM_CMNINFO_DOMAIN_CODE_2G, + ODM_CMNINFO_DOMAIN_CODE_5G, + ODM_CMNINFO_EEPROMVERSION, + ODM_CMNINFO_CRYSTALCAP, + //-----------HOOK BEFORE REG INIT-----------// + + + // + // Dynamic value: + // +//--------- POINTER REFERENCE-----------// + ODM_CMNINFO_MAC_PHY_MODE, // ODM_MAC_PHY_MODE_E + ODM_CMNINFO_TX_UNI, + ODM_CMNINFO_RX_UNI, + ODM_CMNINFO_WM_MODE, // ODM_WIRELESS_MODE_E + ODM_CMNINFO_BAND, // ODM_BAND_TYPE_E + ODM_CMNINFO_SEC_CHNL_OFFSET, // ODM_SEC_CHNL_OFFSET_E + ODM_CMNINFO_SEC_MODE, // ODM_SECURITY_E + ODM_CMNINFO_BW, // ODM_BW_E + ODM_CMNINFO_CHNL, + ODM_CMNINFO_FORCED_RATE, + + ODM_CMNINFO_DMSP_GET_VALUE, + ODM_CMNINFO_BUDDY_ADAPTOR, + ODM_CMNINFO_DMSP_IS_MASTER, + ODM_CMNINFO_SCAN, + ODM_CMNINFO_POWER_SAVING, + ODM_CMNINFO_ONE_PATH_CCA, // ODM_CCA_PATH_E + ODM_CMNINFO_DRV_STOP, + ODM_CMNINFO_PNP_IN, + ODM_CMNINFO_INIT_ON, + ODM_CMNINFO_ANT_TEST, + ODM_CMNINFO_NET_CLOSED, + ODM_CMNINFO_MP_MODE, + //ODM_CMNINFO_RTSTA_AID, // For win driver only? + ODM_CMNINFO_FORCED_IGI_LB, + ODM_CMNINFO_P2P_LINK, + ODM_CMNINFO_FCS_MODE, +//--------- POINTER REFERENCE-----------// + +//------------CALL BY VALUE-------------// + ODM_CMNINFO_WIFI_DIRECT, + ODM_CMNINFO_WIFI_DISPLAY, + ODM_CMNINFO_LINK_IN_PROGRESS, + ODM_CMNINFO_LINK, + ODM_CMNINFO_STATION_STATE, + ODM_CMNINFO_RSSI_MIN, + ODM_CMNINFO_DBG_COMP, // u8Byte + ODM_CMNINFO_DBG_LEVEL, // u4Byte + ODM_CMNINFO_RA_THRESHOLD_HIGH, // u1Byte + ODM_CMNINFO_RA_THRESHOLD_LOW, // u1Byte + ODM_CMNINFO_RF_ANTENNA_TYPE, // u1Byte + ODM_CMNINFO_BT_ENABLED, + ODM_CMNINFO_BT_HS_CONNECT_PROCESS, + ODM_CMNINFO_BT_HS_RSSI, + ODM_CMNINFO_BT_OPERATION, + ODM_CMNINFO_BT_LIMITED_DIG, //Need to Limited Dig or not + ODM_CMNINFO_BT_DISABLE_EDCA, + ODM_CMNINFO_NO_BEACON_IN_2S, +//------------CALL BY VALUE-------------// + + // + // Dynamic ptr array hook itms. + // + ODM_CMNINFO_STA_STATUS, + ODM_CMNINFO_PHY_STATUS, + ODM_CMNINFO_MAC_STATUS, + + ODM_CMNINFO_MAX, + + +}ODM_CMNINFO_E; + +// +// 2011/10/20 MH Define ODM support ability. ODM_CMNINFO_ABILITY +// +typedef enum _ODM_Support_Ability_Definition +{ + // + // BB ODM section BIT 0-19 + // + ODM_BB_DIG = BIT0, + ODM_BB_RA_MASK = BIT1, + ODM_BB_DYNAMIC_TXPWR = BIT2, + ODM_BB_FA_CNT = BIT3, + ODM_BB_RSSI_MONITOR = BIT4, + ODM_BB_CCK_PD = BIT5, + ODM_BB_ANT_DIV = BIT6, + ODM_BB_PWR_SAVE = BIT7, + ODM_BB_PWR_TRAIN = BIT8, + ODM_BB_RATE_ADAPTIVE = BIT9, + ODM_BB_PATH_DIV = BIT10, + ODM_BB_PSD = BIT11, + ODM_BB_RXHP = BIT12, + ODM_BB_ADAPTIVITY = BIT13, + ODM_BB_CFO_TRACKING = BIT14, + ODM_BB_NHM_CNT = BIT15, + ODM_BB_PRIMARY_CCA = BIT16, + + // + // MAC DM section BIT 20-23 + // + ODM_MAC_EDCA_TURBO = BIT20, + ODM_MAC_EARLY_MODE = BIT21, + + // + // RF ODM section BIT 24-31 + // + ODM_RF_TX_PWR_TRACK = BIT24, + ODM_RF_RX_GAIN_TRACK = BIT25, + ODM_RF_CALIBRATION = BIT26, + +}ODM_ABILITY_E; + +// ODM_CMNINFO_INTERFACE +typedef enum tag_ODM_Support_Interface_Definition +{ + ODM_ITRF_PCIE = 0x1, + ODM_ITRF_USB = 0x2, + ODM_ITRF_SDIO = 0x4, + ODM_ITRF_GSPI = 0x8, + ODM_ITRF_LXBUS = 0x10, + ODM_ITRF_ALL = 0xFF, +}ODM_INTERFACE_E; + +// ODM_CMNINFO_IC_TYPE +typedef enum tag_ODM_Support_IC_Type_Definition +{ + ODM_RTL8192S = BIT0, + ODM_RTL8192C = BIT1, + ODM_RTL8192D = BIT2, + ODM_RTL8723A = BIT3, + ODM_RTL8188E = BIT4, + ODM_RTL8812 = BIT5, + ODM_RTL8821 = BIT6, + ODM_RTL8192E = BIT7, + ODM_RTL8723B = BIT8, + ODM_RTL8814A = BIT9, + ODM_RTL8881A = BIT10, + ODM_RTL8821B = BIT11, + ODM_RTL8822B = BIT12, + ODM_RTL8195A = BIT13, + ODM_RTL8711B = BIT14 +}ODM_IC_TYPE_E; + +#define ODM_IC_11N_SERIES (ODM_RTL8192S|ODM_RTL8192C|ODM_RTL8192D|ODM_RTL8723A|ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8195A|ODM_RTL8711B) +#define ODM_IC_11AC_SERIES (ODM_RTL8812|ODM_RTL8821|ODM_RTL8814A|ODM_RTL8881A|ODM_RTL8821B|ODM_RTL8822B) + +//ODM_CMNINFO_CUT_VER +typedef enum tag_ODM_Cut_Version_Definition +{ + ODM_CUT_A = 0, + ODM_CUT_B = 1, + ODM_CUT_C = 2, + ODM_CUT_D = 3, + ODM_CUT_E = 4, + ODM_CUT_F = 5, + + ODM_CUT_I = 8, + ODM_CUT_TEST = 15, +}ODM_CUT_VERSION_E; + +// ODM_CMNINFO_FAB_VER +typedef enum tag_ODM_Fab_Version_Definition +{ + ODM_TSMC = 0, + ODM_UMC = 1, +}ODM_FAB_E; + +// ODM_CMNINFO_RF_TYPE +// +// For example 1T2R (A+AB = BIT0|BIT4|BIT5) +// +typedef enum tag_ODM_RF_Path_Bit_Definition +{ + ODM_RF_TX_A = BIT0, + ODM_RF_TX_B = BIT1, + ODM_RF_TX_C = BIT2, + ODM_RF_TX_D = BIT3, + ODM_RF_RX_A = BIT4, + ODM_RF_RX_B = BIT5, + ODM_RF_RX_C = BIT6, + ODM_RF_RX_D = BIT7, +}ODM_RF_PATH_E; + + +typedef enum tag_ODM_RF_Type_Definition +{ + ODM_1T1R = 0, + ODM_1T2R = 1, + ODM_2T2R = 2, + ODM_2T3R = 3, + ODM_2T4R = 4, + ODM_3T3R = 5, + ODM_3T4R = 6, + ODM_4T4R = 7, +}ODM_RF_TYPE_E; + + +// +// ODM Dynamic common info value definition +// + +//typedef enum _MACPHY_MODE_8192D{ +// SINGLEMAC_SINGLEPHY, +// DUALMAC_DUALPHY, +// DUALMAC_SINGLEPHY, +//}MACPHY_MODE_8192D,*PMACPHY_MODE_8192D; +// Above is the original define in MP driver. Please use the same define. THX. +typedef enum tag_ODM_MAC_PHY_Mode_Definition +{ + ODM_SMSP = 0, + ODM_DMSP = 1, + ODM_DMDP = 2, +}ODM_MAC_PHY_MODE_E; + + +typedef enum tag_BT_Coexist_Definition +{ + ODM_BT_BUSY = 1, + ODM_BT_ON = 2, + ODM_BT_OFF = 3, + ODM_BT_NONE = 4, +}ODM_BT_COEXIST_E; + +// ODM_CMNINFO_OP_MODE +typedef enum tag_Operation_Mode_Definition +{ + ODM_NO_LINK = BIT0, + ODM_LINK = BIT1, + ODM_SCAN = BIT2, + ODM_POWERSAVE = BIT3, + ODM_AP_MODE = BIT4, + ODM_CLIENT_MODE = BIT5, + ODM_AD_HOC = BIT6, + ODM_WIFI_DIRECT = BIT7, + ODM_WIFI_DISPLAY = BIT8, +}ODM_OPERATION_MODE_E; + +// ODM_CMNINFO_WM_MODE +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_CE|ODM_IOT)) +typedef enum tag_Wireless_Mode_Definition +{ + ODM_WM_UNKNOW = 0x0, + ODM_WM_B = BIT0, + ODM_WM_G = BIT1, + ODM_WM_A = BIT2, + ODM_WM_N24G = BIT3, + ODM_WM_N5G = BIT4, + ODM_WM_AUTO = BIT5, + ODM_WM_AC = BIT6, +}ODM_WIRELESS_MODE_E; +#else +typedef enum tag_Wireless_Mode_Definition +{ + ODM_WM_UNKNOWN = 0x00, + ODM_WM_A = BIT0, + ODM_WM_B = BIT1, + ODM_WM_G = BIT2, + ODM_WM_AUTO = BIT3, + ODM_WM_N24G = BIT4, + ODM_WM_N5G = BIT5, + ODM_WM_AC_5G = BIT6, + ODM_WM_AC_24G = BIT7, + ODM_WM_AC_ONLY = BIT8, + ODM_WM_MAX = BIT9 +}ODM_WIRELESS_MODE_E; +#endif + +// ODM_CMNINFO_BAND +typedef enum tag_Band_Type_Definition +{ + ODM_BAND_2_4G = 0, + ODM_BAND_5G, + ODM_BAND_ON_BOTH, + ODM_BANDMAX + +}ODM_BAND_TYPE_E; + +// ODM_CMNINFO_SEC_CHNL_OFFSET +typedef enum tag_Secondary_Channel_Offset_Definition +{ + ODM_DONT_CARE = 0, + ODM_BELOW = 1, + ODM_ABOVE = 2 +}ODM_SEC_CHNL_OFFSET_E; + +// ODM_CMNINFO_SEC_MODE +typedef enum tag_Security_Definition +{ + ODM_SEC_OPEN = 0, + ODM_SEC_WEP40 = 1, + ODM_SEC_TKIP = 2, + ODM_SEC_RESERVE = 3, + ODM_SEC_AESCCMP = 4, + ODM_SEC_WEP104 = 5, + ODM_WEP_WPA_MIXED = 6, // WEP + WPA + ODM_SEC_SMS4 = 7, +}ODM_SECURITY_E; + +// ODM_CMNINFO_BW +typedef enum tag_Bandwidth_Definition +{ + ODM_BW20M = 0, + ODM_BW40M = 1, + ODM_BW80M = 2, + ODM_BW160M = 3, + ODM_BW10M = 4, +}ODM_BW_E; + + +// ODM_CMNINFO_BOARD_TYPE +// For non-AC-series IC , ODM_BOARD_5G_EXT_PA and ODM_BOARD_5G_EXT_LNA are ignored +// For AC-series IC, external PA & LNA can be indivisuallly added on 2.4G and/or 5G +typedef enum tag_Board_Definition +{ + ODM_BOARD_DEFAULT = 0, // The DEFAULT case. + ODM_BOARD_MINICARD = BIT(0), // 0 = non-mini card, 1= mini card. + ODM_BOARD_SLIM = BIT(1), // 0 = non-slim card, 1 = slim card + ODM_BOARD_BT = BIT(2), // 0 = without BT card, 1 = with BT + ODM_BOARD_EXT_PA = BIT(3), // 0 = no 2G ext-PA, 1 = existing 2G ext-PA + ODM_BOARD_EXT_LNA = BIT(4), // 0 = no 2G ext-LNA, 1 = existing 2G ext-LNA + ODM_BOARD_EXT_TRSW = BIT(5), // 0 = no ext-TRSW, 1 = existing ext-TRSW + ODM_BOARD_EXT_PA_5G = BIT(6), // 0 = no 5G ext-PA, 1 = existing 5G ext-PA + ODM_BOARD_EXT_LNA_5G= BIT(7), // 0 = no 5G ext-LNA, 1 = existing 5G ext-LNA +}ODM_BOARD_TYPE_E; + +typedef enum tag_ODM_Package_Definition +{ + ODM_PACKAGE_DEFAULT = 0, + ODM_PACKAGE_QFN68 = BIT(0), + ODM_PACKAGE_TFBGA90 = BIT(1), + ODM_PACKAGE_TFBGA79 = BIT(2), +}ODM_Package_TYPE_E; + +typedef enum tag_ODM_TYPE_GPA_Definition +{ + TYPE_GPA0 = 0, + TYPE_GPA1 = BIT(1)|BIT(0) +}ODM_TYPE_GPA_E; + +typedef enum tag_ODM_TYPE_APA_Definition +{ + TYPE_APA0 = 0, + TYPE_APA1 = BIT(1)|BIT(0) +}ODM_TYPE_APA_E; + +typedef enum tag_ODM_TYPE_GLNA_Definition +{ + TYPE_GLNA0 = 0, + TYPE_GLNA1 = BIT(2)|BIT(0), + TYPE_GLNA2 = BIT(3)|BIT(1), + TYPE_GLNA3 = BIT(3)|BIT(2)|BIT(1)|BIT(0) +}ODM_TYPE_GLNA_E; + +typedef enum tag_ODM_TYPE_ALNA_Definition +{ + TYPE_ALNA0 = 0, + TYPE_ALNA1 = BIT(2)|BIT(0), + TYPE_ALNA2 = BIT(3)|BIT(1), + TYPE_ALNA3 = BIT(3)|BIT(2)|BIT(1)|BIT(0) +}ODM_TYPE_ALNA_E; + +// ODM_CMNINFO_ONE_PATH_CCA +typedef enum tag_CCA_Path +{ + ODM_CCA_2R = 0, + ODM_CCA_1R_A = 1, + ODM_CCA_1R_B = 2, +}ODM_CCA_PATH_E; + + +typedef struct _ODM_RA_Info_ +{ + u1Byte RateID; + u4Byte RateMask; + u4Byte RAUseRate; + u1Byte RateSGI; + u1Byte RssiStaRA; + u1Byte PreRssiStaRA; + u1Byte SGIEnable; + u1Byte DecisionRate; + u1Byte PreRate; + u1Byte HighestRate; + u1Byte LowestRate; + u4Byte NscUp; + u4Byte NscDown; + u2Byte RTY[5]; + u4Byte TOTAL; + u2Byte DROP; + u1Byte Active; + u2Byte RptTime; + u1Byte RAWaitingCounter; + u1Byte RAPendingCounter; +#if ((RTL8195A_SUPPORT == 1) || (RTL8711B_SUPPORT == 1)) + //---------Gary----------// //TODO: James + u1Byte RAINFO; + // BIT0: UL/DL state + // BIT1: EN_STBC + // BIT2: LDPC_CAP + // Add by Wilson 20130320 + // BIT3,BIT4 : 2SS short cut + // BIT5 : init rate by rssi + // BIT6: BF state + // BIT7: delay try rate + + u1Byte Initial_BW; + u1Byte BW_setting; + u1Byte DISPT; + u1Byte DISRA; + u1Byte Stage_RA; + u1Byte PRE_BW; + u1Byte MacID; + u1Byte Try_state; + u1Byte Try_done_cnt; + u2Byte RA_counter; + u1Byte Init_Rate_H; + u1Byte Init_Rate_M; + u1Byte Init_Rate_L; + u4Byte Total_TX; + + //2 Power Trainning + u1Byte TRAINING_RATE; + u1Byte STOP_PT_COUNTER; + u1Byte MODE_SS; + u1Byte PT_smooth_factor; +#endif + +#if 1 //POWER_TRAINING_ACTIVE == 1 // For compile pass only~! + u1Byte PTActive; // on or off + u1Byte PTTryState; // 0 trying state, 1 for decision state + u1Byte PTStage; // 0~6 + u1Byte PTStopCount; //Stop PT counter + u1Byte PTPreRate; // if rate change do PT + u1Byte PTPreRssi; // if RSSI change 5% do PT + u1Byte PTModeSS; // decide whitch rate should do PT + u1Byte RAstage; // StageRA, decide how many times RA will be done between PT + u1Byte PTSmoothFactor; +#endif +} ODM_RA_INFO_T,*PODM_RA_INFO_T; + +// +// ODM Dynamic common info value definition +// + +typedef struct _FAST_ANTENNA_TRAINNING_ +{ + u1Byte Bssid[6]; + u1Byte antsel_rx_keep_0; + u1Byte antsel_rx_keep_1; + u1Byte antsel_rx_keep_2; + u1Byte antsel_rx_keep_3; + u4Byte antSumRSSI[7]; + u4Byte antRSSIcnt[7]; + u4Byte antAveRSSI[7]; + u1Byte FAT_State; + u4Byte TrainIdx; + u1Byte antsel_a[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte antsel_b[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte antsel_c[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MainAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAnt_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte MainAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte AuxAnt_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte RxIdleAnt; + BOOLEAN bBecomeLinked; + u4Byte MinMaxRSSI; + u1Byte idx_AntDiv_counter_2G; + u1Byte idx_AntDiv_counter_5G; + u4Byte AntDiv_2G_5G; + u4Byte CCK_counter_main; + u4Byte CCK_counter_aux; + u4Byte OFDM_counter_main; + u4Byte OFDM_counter_aux; + +}FAT_T,*pFAT_T; +#if !((RTL8195A_SUPPORT == 1) || (RTL8711B_SUPPORT == 1)) +typedef struct _ROM_INFO{ + u1Byte EEPROMVersion; + u1Byte CrystalCap; + u8Byte DebugComponents; + u4Byte DebugLevel; +}ROM_INFO, *PROM_INFO; +#endif + +typedef enum _FAT_STATE +{ + FAT_NORMAL_STATE = 0, + FAT_TRAINING_STATE = 1, +}FAT_STATE_E, *PFAT_STATE_E; + +typedef enum _ANT_DIV_TYPE +{ + NO_ANTDIV = 0xFF, + CG_TRX_HW_ANTDIV = 0x01, + CGCS_RX_HW_ANTDIV = 0x02, + FIXED_HW_ANTDIV = 0x03, + CG_TRX_SMART_ANTDIV = 0x04, + CGCS_RX_SW_ANTDIV = 0x05, + S0S1_SW_ANTDIV = 0x06 //8723B intrnal switch S0 S1 +}ANT_DIV_TYPE_E, *PANT_DIV_TYPE_E; + +#if (RTL8812A_SUPPORT == 1) +typedef struct _ODM_PATH_DIVERSITY_ +{ + u1Byte RespTxPath; + u1Byte PathSel[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathA_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathB_Sum[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathA_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; + u4Byte PathB_Cnt[ODM_ASSOCIATE_ENTRY_NUM]; +}PATHDIV_T, *pPATHDIV_T; +#endif + +typedef enum _BASEBAND_CONFIG_PHY_REG_PG_VALUE_TYPE{ + PHY_REG_PG_RELATIVE_VALUE = 0, + PHY_REG_PG_EXACT_VALUE = 1 +} PHY_REG_PG_TYPE; + + +// +// Antenna detection information from single tone mechanism, added by Roger, 2012.11.27. +// +typedef struct _ANT_DETECTED_INFO{ + BOOLEAN bAntDetected; + u4Byte dBForAntA; + u4Byte dBForAntB; + u4Byte dBForAntO; +}ANT_DETECTED_INFO, *PANT_DETECTED_INFO; + +// +// 2011/09/22 MH Copy from SD4 defined structure. We use to support PHY DM integration. +// +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) +#if (RT_PLATFORM != PLATFORM_LINUX) +typedef +#endif +struct DM_Out_Source_Dynamic_Mechanism_Structure +#else// for AP,ADSL,CE,IOT Team +typedef struct DM_Out_Source_Dynamic_Mechanism_Structure +#endif +{ + //RT_TIMER FastAntTrainingTimer; + // + // Add for different team use temporarily + // + PADAPTER Adapter; // For CE/NIC team +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + prtl8192cd_priv priv; // For AP/ADSL team +#endif + // WHen you use Adapter or priv pointer, you must make sure the pointer is ready. + BOOLEAN odm_ready; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_WIN)) + rtl8192cd_priv fake_priv; +#endif +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + // ADSL_AP_BUILD_WORKAROUND + ADAPTER fake_adapter; +#endif + + PHY_REG_PG_TYPE PhyRegPgValueType; + u1Byte PhyRegPgVersion; + + u4Byte NumQryPhyStatusAll; //CCK + OFDM + u4Byte LastNumQryPhyStatusAll; + u4Byte RxPWDBAve; + BOOLEAN MPDIG_2G; //off MPDIG + u1Byte Times_2G; + +//------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------// + BOOLEAN bCckHighPower; + u1Byte RFPathRxEnable; // ODM_CMNINFO_RFPATH_ENABLE + u1Byte ControlChannel; +//------ ODM HANDLE, DRIVER NEEDS NOT TO HOOK------// + +//--------REMOVED COMMON INFO----------// + //u1Byte PseudoMacPhyMode; + //BOOLEAN *BTCoexist; + //BOOLEAN PseudoBtCoexist; + //u1Byte OPMode; + //BOOLEAN bAPMode; + //BOOLEAN bClientMode; + //BOOLEAN bAdHocMode; + //BOOLEAN bSlaveOfDMSP; +//--------REMOVED COMMON INFO----------// + + +//1 COMMON INFORMATION + + // + // Init Value + // +//-----------HOOK BEFORE REG INIT-----------// + // ODM Platform info AP/ADSL/CE/MP = 1/2/3/4 + u1Byte SupportPlatform; + // ODM Support Ability DIG/RATR/TX_PWR_TRACK/ KK = 1/2/3/K + u4Byte SupportAbility; + // ODM PCIE/USB/SDIO = 1/2/3 + u1Byte SupportInterface; + // ODM composite or independent. Bit oriented/ 92C+92D+ .... or any other type = 1/2/3/... + u4Byte SupportICType; + // Cut Version TestChip/A-cut/B-cut... = 0/1/2/3/... + u1Byte CutVersion; + // Fab Version TSMC/UMC = 0/1 + u1Byte FabVersion; + // RF Type 4T4R/3T3R/2T2R/1T2R/1T1R/... + u1Byte RFType; + u1Byte RFEType; + // Board Type Normal/HighPower/MiniCard/SLIM/Combo/... = 0/1/2/3/4/... + u1Byte BoardType; + u1Byte PackageType; + u1Byte TypeGLNA; + u1Byte TypeGPA; + u1Byte TypeALNA; + u1Byte TypeAPA; + // with external LNA NO/Yes = 0/1 + u1Byte ExtLNA; + u1Byte ExtLNA5G; + // with external PA NO/Yes = 0/1 + u1Byte ExtPA; + u1Byte ExtPA5G; + // with external TRSW NO/Yes = 0/1 + u1Byte ExtTRSW; + u1Byte PatchID; //Customer ID + BOOLEAN bInHctTest; + BOOLEAN bWIFITest; + + BOOLEAN bDualMacSmartConcurrent; + u4Byte BK_SupportAbility; + u1Byte AntDivType; + + u1Byte odm_Regulation2_4G; + u1Byte odm_Regulation5G; + BOOLEAN cck_new_agc; +//-----------HOOK BEFORE REG INIT-----------// + + // + // Dynamic Value + // +//--------- POINTER REFERENCE-----------// + + u1Byte u1Byte_temp; +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_AP|ODM_ADSL)) + BOOLEAN BOOLEAN_temp; +#endif + PADAPTER PADAPTER_temp; + + // MAC PHY Mode SMSP/DMSP/DMDP = 0/1/2 + u1Byte *pMacPhyMode; + //TX Unicast byte count + u8Byte *pNumTxBytesUnicast; + //RX Unicast byte count + u8Byte *pNumRxBytesUnicast; + // Wireless mode B/G/A/N = BIT0/BIT1/BIT2/BIT3 + u1Byte *pWirelessMode; //ODM_WIRELESS_MODE_E + // Frequence band 2.4G/5G = 0/1 + u1Byte *pBandType; + // Secondary channel offset don't_care/below/above = 0/1/2 + u1Byte *pSecChOffset; + // Security mode Open/WEP/AES/TKIP = 0/1/2/3 + u1Byte *pSecurity; + // BW info 20M/40M/80M = 0/1/2 + u1Byte *pBandWidth; + // Central channel location Ch1/Ch2/.... + u1Byte *pChannel; //central channel number + BOOLEAN DPK_Done; + // Common info for 92D DMSP + + BOOLEAN *pbGetValueFromOtherMac; + PADAPTER *pBuddyAdapter; + BOOLEAN *pbMasterOfDMSP; //MAC0: master, MAC1: slave + // Common info for Status + BOOLEAN *pbScanInProcess; + BOOLEAN *pbPowerSaving; + // CCA Path 2-path/path-A/path-B = 0/1/2; using ODM_CCA_PATH_E. + u1Byte *pOnePathCCA; + //pMgntInfo->AntennaTest + u1Byte *pAntennaTest; + BOOLEAN *pbNet_closed; + u1Byte *mp_mode; + //u1Byte *pAidMap; + u1Byte *pu1ForcedIgiLb; + BOOLEAN *pIsFcsModeEnable; +//--------- POINTER REFERENCE-----------// + pu2Byte pForcedDataRate; +//------------CALL BY VALUE-------------// + BOOLEAN bLinkInProcess; + BOOLEAN bWIFI_Direct; + BOOLEAN bWIFI_Display; + BOOLEAN bLinked; + + BOOLEAN bsta_state; + u1Byte RSSI_Min; + u1Byte InterfaceIndex; // Add for 92D dual MAC: 0--Mac0 1--Mac1 + BOOLEAN bIsMPChip; + BOOLEAN bOneEntryOnly; + // Common info for BTDM + BOOLEAN bBtEnabled; // BT is disabled + BOOLEAN bBtConnectProcess; // BT HS is under connection progress. + u1Byte btHsRssi; // BT HS mode wifi rssi value. + BOOLEAN bBtHsOperation; // BT HS mode is under progress + BOOLEAN bBtDisableEdcaTurbo; // Under some condition, don't enable the EDCA Turbo + BOOLEAN bBtLimitedDig; // BT is busy. +//------------CALL BY VALUE-------------// + u1Byte RSSI_A; + u1Byte RSSI_B; + u8Byte RSSI_TRSW; + u8Byte RSSI_TRSW_H; + u8Byte RSSI_TRSW_L; + u8Byte RSSI_TRSW_iso; + u1Byte RXAntStatus; + u1Byte TXAntStatus; + u1Byte RxRate; + BOOLEAN bNoisyState; + u1Byte TxRate; + u1Byte LinkedInterval; + u1Byte preChannel; + u4Byte TxagcOffsetValueA; + BOOLEAN IsTxagcOffsetPositiveA; + u4Byte TxagcOffsetValueB; + BOOLEAN IsTxagcOffsetPositiveB; + u8Byte lastTxOkCnt; + u8Byte lastRxOkCnt; + u4Byte BbSwingOffsetA; + BOOLEAN IsBbSwingOffsetPositiveA; + u4Byte BbSwingOffsetB; + BOOLEAN IsBbSwingOffsetPositiveB; + u1Byte antdiv_rssi; + u1Byte AntType; + u1Byte pre_AntType; + u1Byte antdiv_period; + u1Byte antdiv_select; + u1Byte NdpaPeriod; + + BOOLEAN H2C_RARpt_connect; + + //For Adaptivtiy + u2Byte NHM_cnt_0; + u2Byte NHM_cnt_1; + s1Byte TH_L2H_ini; + s1Byte TH_EDCCA_HL_diff; + s1Byte TH_L2H_ini_backup; + BOOLEAN Carrier_Sense_enable; + u1Byte Adaptivity_IGI_upper; + BOOLEAN adaptivity_flag; + u1Byte DCbackoff; + BOOLEAN Adaptivity_enable; + u1Byte APTotalNum; + BOOLEAN EDCCA_enable; + ADAPTIVITY_STATISTICS Adaptivity; + //For Adaptivtiy + + ODM_NOISE_MONITOR noise_level;//[ODM_MAX_CHANNEL_NUM]; + /*for noise detection*/ + BOOLEAN NoisyDecision; /*b_noisy*/ + BOOLEAN pre_b_noisy; + u4Byte NoisyDecision_Smooth; + +#if (ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) + s4Byte AccumulatePWDB[ODM_ASSOCIATE_ENTRY_NUM]; +#endif + + // + //2 Define STA info. + // _ODM_STA_INFO + // 2012/01/12 MH For MP, we need to reduce one array pointer for default port.?? + PSTA_INFO_T pODM_StaInfo[ODM_ASSOCIATE_ENTRY_NUM]; + +#if (RATE_ADAPTIVE_SUPPORT == 1) + u2Byte CurrminRptTime; + ODM_RA_INFO_T RAInfo[ODM_ASSOCIATE_ENTRY_NUM]; //See HalMacID support +#endif + // + // 2012/02/14 MH Add to share 88E ra with other SW team. + // We need to colelct all support abilit to a proper area. + // + BOOLEAN RaSupport88E; + + // Define ........... + + // Latest packet phy info (ODM write) + ODM_PHY_DBG_INFO_T PhyDbgInfo; + //PHY_INFO_88E PhyInfo; + + // Latest packet phy info (ODM write) + ODM_MAC_INFO *pMacInfo; + //MAC_INFO_88E MacInfo; + + // Different Team independt structure?? + + // + //TX_RTP_CMN TX_retrpo; + //TX_RTP_88E TX_retrpo; + //TX_RTP_8195 TX_retrpo; + + // + //ODM Structure + // + FAT_T DM_FatTable; + DIG_T DM_DigTable; + PS_T DM_PSTable; + Pri_CCA_T DM_PriCCA; + RXHP_T DM_RXHP_Table; +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_IOT)) + RA_T DM_RA_Table; +#endif + PROM_INFO pROMInfo; + + FALSE_ALARM_STATISTICS FalseAlmCnt; + CFO_TRACKING DM_CfoTrack; + + FALSE_ALARM_STATISTICS FlaseAlmCntBuddyAdapter; + //#ifdef CONFIG_ANTENNA_DIVERSITY + SWAT_T DM_SWAT_Table; + BOOLEAN RSSI_test; + + //#endif + + BOOLEAN bNoBeaconIn2s; + +#if (DM_ODM_SUPPORT_TYPE & ODM_WIN) + //Path Div Struct + PATHDIV_PARA pathIQK; +#endif + + EDCA_T DM_EDCA_Table; + u4Byte WMMEDCA_BE; +#if (RTL8812A_SUPPORT == 1) + PATHDIV_T DM_PathDiv; +#endif + // Copy from SD4 structure + // + // ================================================== + // + + //common + //u1Byte DM_Type; + //u1Byte PSD_Report_RXHP[80]; // Add By Gary + //u1Byte PSD_func_flag; // Add By Gary + //for DIG + //u1Byte bDMInitialGainEnable; + //u1Byte binitialized; // for dm_initial_gain_Multi_STA use. + //for Antenna diversity + //u8 AntDivCfg;// 0:OFF , 1:ON, 2:by efuse + //PSTA_INFO_T RSSI_target; + + BOOLEAN *pbDriverStopped; + BOOLEAN *pbDriverIsGoingToPnpSetPowerSleep; + BOOLEAN *pinit_adpt_in_progress; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) + //PSD + BOOLEAN bUserAssignLevel; + RT_TIMER PSDTimer; + u1Byte RSSI_BT; //come from BT + BOOLEAN bPSDinProcess; + BOOLEAN bPSDactive; + BOOLEAN bDMInitialGainEnable; + + //MPT DIG + RT_TIMER MPT_DIGTimer; +#endif + + //for rate adaptive, in fact, 88c/92c fw will handle this + u1Byte bUseRAMask; + + ODM_RATE_ADAPTIVE RateAdaptive; + + ANT_DETECTED_INFO AntDetectedInfo; // Antenna detected information for RSSI tool + + ODM_RF_CAL_T RFCalibrateInfo; + + // + // TX power tracking + // + u1Byte BbSwingIdxOfdm[MAX_RF_PATH]; + u1Byte BbSwingIdxOfdmCurrent; + u1Byte BbSwingIdxOfdmBase[MAX_RF_PATH]; + BOOLEAN BbSwingFlagOfdm; + u1Byte BbSwingIdxCck[MAX_RF_PATH]; + u1Byte BbSwingIdxCckCurrent; + u1Byte BbSwingIdxCckBase[MAX_RF_PATH]; + u1Byte DefaultOfdmIndex; + u1Byte DefaultCckIndex; + BOOLEAN BbSwingFlagCck; + + s1Byte Absolute_OFDMSwingIdx[MAX_RF_PATH]; + s1Byte Absolute_CCKSwingIdx[MAX_RF_PATH]; + s1Byte Remnant_OFDMSwingIdx[MAX_RF_PATH]; + s1Byte Remnant_CCKSwingIdx[MAX_RF_PATH]; + s1Byte Modify_TxAGC_Value; //Remnat compensate value at TxAGC + BOOLEAN Modify_TxAGC_Flag_PathA; + BOOLEAN Modify_TxAGC_Flag_PathB; + BOOLEAN Modify_TxAGC_Flag_PathA_CCK; + + // + // ODM system resource. + // + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) + // + // Power Training + // + BOOLEAN bDisablePowerTraining; + u1Byte ForcePowerTrainingState; + BOOLEAN bChangeState; + u4Byte PT_score; + u8Byte OFDM_RX_Cnt; + u8Byte CCK_RX_Cnt; +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) + // ODM relative time. + RT_TIMER PathDivSwitchTimer; + //2011.09.27 add for Path Diversity + RT_TIMER CCKPathDiversityTimer; + RT_TIMER FastAntTrainingTimer; +#endif + + // ODM relative workitem. +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #if USE_WORKITEM + RT_WORK_ITEM PathDivSwitchWorkitem; + RT_WORK_ITEM CCKPathDiversityWorkitem; + RT_WORK_ITEM FastAntTrainingWorkitem; + RT_WORK_ITEM MPT_DIGWorkitem; + RT_WORK_ITEM RaRptWorkitem; + #endif +#endif + +#if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + +#if (RT_PLATFORM != PLATFORM_LINUX) +} DM_ODM_T, *PDM_ODM_T; // DM_Dynamic_Mechanism_Structure +#else +}; +#endif + +#else// for AP,ADSL,CE Team +} DM_ODM_T, *PDM_ODM_T; // DM_Dynamic_Mechanism_Structure +#endif + +typedef enum _PhyDM_Structure_Type{ + PhyDM_FalseAlmCnt, + PhyDM_CfoTrack, + PHYDM_ADAPTIVITY, + PhyDM_ROMInfo, + +}PhyDM_Structure_Type; + +typedef enum _ODM_RF_RADIO_PATH { + ODM_RF_PATH_A = 0, //Radio Path A + ODM_RF_PATH_B = 1, //Radio Path B + ODM_RF_PATH_C = 2, //Radio Path C + ODM_RF_PATH_D = 3, //Radio Path D + ODM_RF_PATH_AB, + ODM_RF_PATH_AC, + ODM_RF_PATH_AD, + ODM_RF_PATH_BC, + ODM_RF_PATH_BD, + ODM_RF_PATH_CD, + ODM_RF_PATH_ABC, + ODM_RF_PATH_ACD, + ODM_RF_PATH_BCD, + ODM_RF_PATH_ABCD, + // ODM_RF_PATH_MAX, //Max RF number 90 support +} ODM_RF_RADIO_PATH_E, *PODM_RF_RADIO_PATH_E; + + typedef enum _ODM_RF_CONTENT{ + odm_radioa_txt = 0x1000, + odm_radiob_txt = 0x1001, + odm_radioc_txt = 0x1002, + odm_radiod_txt = 0x1003 +} ODM_RF_CONTENT; + +typedef enum _ODM_BB_Config_Type{ + CONFIG_BB_PHY_REG, + CONFIG_BB_AGC_TAB, + CONFIG_BB_AGC_TAB_2G, + CONFIG_BB_AGC_TAB_5G, + CONFIG_BB_PHY_REG_PG, + CONFIG_BB_PHY_REG_MP, + CONFIG_BB_AGC_TAB_DIFF, +} ODM_BB_Config_Type, *PODM_BB_Config_Type; + +typedef enum _ODM_RF_Config_Type{ + CONFIG_RF_RADIO, + CONFIG_RF_TXPWR_LMT, +} ODM_RF_Config_Type, *PODM_RF_Config_Type; + +typedef enum _ODM_FW_Config_Type{ + CONFIG_FW_NIC, + CONFIG_FW_NIC_2, + CONFIG_FW_AP, + CONFIG_FW_MP, + CONFIG_FW_WoWLAN, + CONFIG_FW_WoWLAN_2, + CONFIG_FW_AP_WoWLAN, + CONFIG_FW_BT, + CONFIG_FW_ROM, +} ODM_FW_Config_Type; + +// Status code +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +typedef enum _RT_STATUS{ + RT_STATUS_SUCCESS, + RT_STATUS_FAILURE, + RT_STATUS_PENDING, + RT_STATUS_RESOURCE, + RT_STATUS_INVALID_CONTEXT, + RT_STATUS_INVALID_PARAMETER, + RT_STATUS_NOT_SUPPORT, + RT_STATUS_OS_API_FAILED, +}RT_STATUS,*PRT_STATUS; +#endif // end of RT_STATUS definition + +#ifdef REMOVE_PACK +#pragma pack() +#endif + +//#include "odm_function.h" + +//3=========================================================== +//3 DIG +//3=========================================================== + +//Remove DIG by Yuchen + +//3=========================================================== +//3 AGC RX High Power Mode +//3=========================================================== +#define LNA_Low_Gain_1 0x64 +#define LNA_Low_Gain_2 0x5A +#define LNA_Low_Gain_3 0x58 + +#define FA_RXHP_TH1 5000 +#define FA_RXHP_TH2 1500 +#define FA_RXHP_TH3 800 +#define FA_RXHP_TH4 600 +#define FA_RXHP_TH5 500 + +//3=========================================================== +//3 EDCA +//3=========================================================== + +//3=========================================================== +//3 Dynamic Tx Power +//3=========================================================== +//Dynamic Tx Power Control Threshold + +//Remove By YuChen + +//3=========================================================== +//3 Tx Power Tracking +//3=========================================================== +#if 0 //mask this, since these have been defined in typdef.h, vivi +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#endif + + +//3=========================================================== +//3 Rate Adaptive +//3=========================================================== +//Remove to odm_RaInfo.h by RS_James + +//3=========================================================== +//3 BB Power Save +//3=========================================================== + +typedef enum tag_1R_CCA_Type_Definition +{ + CCA_1R =0, + CCA_2R = 1, + CCA_MAX = 2, +}DM_1R_CCA_E; + +typedef enum tag_RF_Type_Definition +{ + RF_Save =0, + RF_Normal = 1, + RF_MAX = 2, +}DM_RF_E; + +//3=========================================================== +//3 Antenna Diversity +//3=========================================================== +typedef enum tag_SW_Antenna_Switch_Definition +{ + Antenna_A = 1, + Antenna_B = 2, + Antenna_MAX = 3, +}DM_SWAS_E; + + +// Maximal number of antenna detection mechanism needs to perform, added by Roger, 2011.12.28. +#define MAX_ANTENNA_DETECTION_CNT 10 + +// +// Extern Global Variables. +// +// +// check Sta pointer valid or not +// +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define IS_STA_VALID(pSta) (pSta && pSta->expire_to) +#elif (DM_ODM_SUPPORT_TYPE & ODM_WIN) +#define IS_STA_VALID(pSta) (pSta && pSta->bUsed) +#else +#define IS_STA_VALID(pSta) (pSta) +#endif +// 20100514 Joseph: Add definition for antenna switching test after link. +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +//Remove DIG by yuchen + +//Remove BB power saving by Yuchen + +//Remove ODM_RAStateCheck() by RS_James + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_AP|ODM_ADSL)) +//============================================================ +// function prototype +//============================================================ +//#define DM_ChangeDynamicInitGainThresh ODM_ChangeDynamicInitGainThresh +//void ODM_ChangeDynamicInitGainThresh(IN PADAPTER pAdapter, +// IN INT32 DM_Type, +// IN INT32 DM_Value); + +//Remove DIG by yuchen + + +BOOLEAN +ODM_CheckPowerStatus( + IN PADAPTER Adapter + ); + + +//Remove ODM_RateAdaptiveStateApInit() by RS_James + +//Remove Edca by Yuchen + + +#define SwAntDivCheckBeforeLink ODM_SwAntDivCheckBeforeLink + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PDM_ODM_T pDM_Odm + ); + + +#endif + + + +#if((DM_ODM_SUPPORT_TYPE==ODM_WIN)||(DM_ODM_SUPPORT_TYPE==ODM_CE)) + +u4Byte ConvertTo_dB(u4Byte Value); + +u4Byte +GetPSDData( + PDM_ODM_T pDM_Odm, + unsigned int point, + u1Byte initial_gain_psd); + +#endif + +//Remove ODM_Get_Rate_Bitmap() by RS_James + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) +#define dm_PSDMonitorCallback odm_PSDMonitorCallback +VOID odm_PSDMonitorCallback(PRT_TIMER pTimer); + +VOID +odm_PSDMonitorWorkItemCallback( + IN PVOID pContext + ); + +VOID +PatchDCTone( + IN PDM_ODM_T pDM_Odm, + pu4Byte PSD_report, + u1Byte initial_gain_psd +); +VOID +ODM_PSDMonitor( + IN PDM_ODM_T pDM_Odm + ); +VOID odm_PSD_Monitor(PDM_ODM_T pDM_Odm); +VOID odm_PSDMonitorInit(PDM_ODM_T pDM_Odm); + +VOID +ODM_PSDDbgControl( + IN PADAPTER Adapter, + IN u4Byte mode, + IN u4Byte btRssi + ); + +#endif // DM_ODM_SUPPORT_TYPE + + +#if (BEAMFORMING_SUPPORT == 1) +BEAMFORMING_CAP +Beamforming_GetEntryBeamCapByMacId( + IN PMGNT_INFO pMgntInfo, + IN u1Byte MacId + ); +#endif + +VOID ODM_DMInit( IN PDM_ODM_T pDM_Odm); + +VOID +ODM_DMWatchdog( + IN PDM_ODM_T pDM_Odm // For common use in the future + ); + +VOID +ODM_CmnInfoInit( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u4Byte Value + ); + +VOID +ODM_CmnInfoHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN PVOID pValue + ); + +VOID +ODM_CmnInfoPtrArrayHook( + IN PDM_ODM_T pDM_Odm, + IN ODM_CMNINFO_E CmnInfo, + IN u2Byte Index, + IN PVOID pValue + ); + +VOID +ODM_CmnInfoUpdate( + IN PDM_ODM_T pDM_Odm, + IN u4Byte CmnInfo, + IN u8Byte Value + ); + +VOID +ODM_InitAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_CancelAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_ReleaseAllTimers( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_ResetIQKResult( + IN PDM_ODM_T pDM_Odm + ); + +VOID phydm_NoisyDetection( + IN PDM_ODM_T pDM_Odm + ); + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID ODM_InitAllWorkItems(IN PDM_ODM_T pDM_Odm ); +VOID ODM_FreeAllWorkItems(IN PDM_ODM_T pDM_Odm ); + + +//===========================================// +// Neil Chen----2011--06--15-- + +//3 Path Diversity +//=========================================================== + +#define TP_MODE 0 +#define RSSI_MODE 1 +#define TRAFFIC_LOW 0 +#define TRAFFIC_HIGH 1 + +//#define PATHDIV_ENABLE 1 +//#define dm_PathDiv_RSSI_Check ODM_PathDivChkPerPktRssi + +u8Byte +PlatformDivision64( + IN u8Byte x, + IN u8Byte y +); + + +// 20100514 Joseph: Add definition for antenna switching test after link. +// This indicates two different the steps. +// In SWAW_STEP_PEAK, driver needs to switch antenna and listen to the signal on the air. +// In SWAW_STEP_DETERMINE, driver just compares the signal captured in SWAW_STEP_PEAK +// with original RSSI to determine if it is necessary to switch antenna. +#define SWAW_STEP_PEAK 0 +#define SWAW_STEP_DETERMINE 1 + +//==================================================== +//3 PathDiV End +//==================================================== + +//#define PathDivCheckBeforeLink8192C ODM_PathDiversityBeforeLink92C + +#define DM_ChangeDynamicInitGainThresh ODM_ChangeDynamicInitGainThresh +//void ODM_ChangeDynamicInitGainThresh(IN PADAPTER pAdapter, +// IN INT32 DM_Type, +// IN INT32 DM_Value); +// + + +typedef enum tag_DIG_Connect_Definition +{ + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MultiSTA_DISCONNECT = 3, + DIG_MultiSTA_CONNECT = 4, + DIG_CONNECT_MAX +}DM_DIG_CONNECT_E; + + + +// +// 2012/01/12 MH Check afapter status. Temp fix BSOD. +// +#define HAL_ADAPTER_STS_CHK(pDM_Odm)\ + if (pDM_Odm->Adapter == NULL)\ + {\ + return;\ + }\ + + +// +// For new definition in MP temporarily fro power tracking, +// +#define odm_TXPowerTrackingDirectCall(_Adapter) \ + IS_HARDWARE_TYPE_8192D(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_92D(_Adapter) : \ + IS_HARDWARE_TYPE_8192C(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_92C(_Adapter) : \ + IS_HARDWARE_TYPE_8723A(_Adapter) ? odm_TXPowerTrackingCallback_ThermalMeter_8723A(_Adapter) :\ + ODM_TXPowerTrackingCallback_ThermalMeter(_Adapter) + +#endif // #if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) + +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ); + +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ); + +#endif // #if((DM_ODM_SUPPORT_TYPE==ODM_WIN)||(DM_ODM_SUPPORT_TYPE==ODM_CE)) +VOID +ODM_UpdateNoisyState( + IN PDM_ODM_T pDM_Odm, + IN BOOLEAN bNoisyStateFromC2H +); + +u4Byte +Set_RA_DM_Ratrbitmap_by_Noisy( + IN PDM_ODM_T pDM_Odm, + IN WIRELESS_MODE WirelessMode, + IN u4Byte ratr_bitmap, + IN u1Byte rssi_level +); + +VOID +ODM_UpdateInitRate( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Rate + ); + +//Remove ODM_DynamicARFBSelect() by RS_James + +PVOID +PhyDM_Get_Structure( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Structure_Type +); + +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +void odm_dtc(PDM_ODM_T pDM_Odm); +#endif /* #if (DM_ODM_SUPPORT_TYPE == ODM_CE) */ + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_ACS.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_ACS.h new file mode 100644 index 0000000..f046c49 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_ACS.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMACS_H__ +#define __PHYDMACS_H__ + +#include "phydm_types.h" + +#define ACS_VERSION "1.1" /*20150729 by YuChen*/ +#define CLM_VERSION "1.0" + +#define ODM_MAX_CHANNEL_2G 14 +#define ODM_MAX_CHANNEL_5G 24 + +// For phydm_AutoChannelSelectSettingAP() +#define STORE_DEFAULT_NHM_SETTING 0 +#define RESTORE_DEFAULT_NHM_SETTING 1 +#define ACS_NHM_SETTING 2 + +#define ODM_REG_CLM_TIME_PERIOD_11AC 0x990 +#define ODM_REG_CLM_TIME_PERIOD_11N 0x894 +#define ODM_REG_CLM_RESULT_11AC 0xfa4 +#define ODM_REG_CLM_RESULT_11N 0x8d0 +#define ODM_REG_CLM_11AC 0x994 +#define ODM_REG_CLM_11N 0x890 +#define ODM_REG_CLM_READY_11N 0x8b4 + +typedef struct _ACS_ +{ + BOOLEAN bForceACSResult; + u1Byte CleanChannel_2G; + u1Byte CleanChannel_5G; + u2Byte Channel_Info_2G[2][ODM_MAX_CHANNEL_2G]; //Channel_Info[1]: Channel Score, Channel_Info[2]:Channel_Scan_Times + u2Byte Channel_Info_5G[2][ODM_MAX_CHANNEL_5G]; + +#if ( DM_ODM_SUPPORT_TYPE & ODM_AP ) + u1Byte ACS_Step; + // NHM Count 0-11 + u1Byte NHM_Cnt[14][11]; + + // AC-Series, for storing previous setting + u4Byte Reg0x990; + u4Byte Reg0x994; + u4Byte Reg0x998; + u4Byte Reg0x99C; + u1Byte Reg0x9A0; // u1Byte + + // N-Series, for storing previous setting + u4Byte Reg0x890; + u4Byte Reg0x894; + u4Byte Reg0x898; + u4Byte Reg0x89C; + u1Byte Reg0xE28; // u1Byte +#endif + +}ACS, *PACS; + +VOID +phydm_CLMInit( + IN PVOID pDM_VOID, + IN u2Byte sampleNum +); + +VOID +phydm_CLMtrigger( + IN PVOID pDM_VOID +); + +BOOLEAN +phydm_checkCLMready( + IN PVOID pDM_VOID +); + +u2Byte +phydm_getCLMresult( + IN PVOID pDM_VOID +); + + +#endif //#ifndef __PHYDMACS_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDect.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDect.h new file mode 100644 index 0000000..7dc1d6e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDect.h @@ -0,0 +1,76 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMANTDECT_H__ +#define __PHYDMANTDECT_H__ + +#define ANTDECT_VERSION "1.0" + +#if( DM_ODM_SUPPORT_TYPE & (ODM_WIN |ODM_CE)) +//1 [1. Single Tone Method] =================================================== + + + +VOID +ODM_SingleDualAntennaDefaultSetting( + IN PDM_ODM_T pDM_Odm + ); + +BOOLEAN +ODM_SingleDualAntennaDetection( + IN PDM_ODM_T pDM_Odm, + IN u1Byte mode + ); + +//1 [2. Scan AP RSSI Method] ================================================== + +VOID +odm_SwAntDetectInit( + IN PDM_ODM_T pDM_Odm + ); + + +#define SwAntDivCheckBeforeLink ODM_SwAntDivCheckBeforeLink + +BOOLEAN +ODM_SwAntDivCheckBeforeLink( + IN PDM_ODM_T pDM_Odm + ); + + + + +//1 [3. PSD Method] ========================================================== + + +VOID +ODM_SingleDualAntennaDetection_PSD( + IN PDM_ODM_T pDM_Odm +); + + + + + + +#endif +#endif + + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDiv.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDiv.h new file mode 100644 index 0000000..f762e71 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_AntDiv.h @@ -0,0 +1,144 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMANTDIV_H__ +#define __PHYDMANTDIV_H__ + +#define ANTDIV_VERSION "1.0" + +#define ANT1_2G 0 // = ANT2_5G +#define ANT2_2G 1 // = ANT1_5G + +//Antenna Diversty Control Type +#define ODM_AUTO_ANT 0 +#define ODM_FIX_MAIN_ANT 1 +#define ODM_FIX_AUX_ANT 2 + +#define TX_BY_REG 0 + +#if (DM_ODM_SUPPORT_TYPE != ODM_AP) +#define ODM_RTL8881A 0 //Just for windows driver to jointly use ODM-driver +#endif + +#define ODM_ANTDIV_SUPPORT (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_N_ANTDIV_SUPPORT (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B) +#define ODM_AC_ANTDIV_SUPPORT (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_SMART_ANT_SUPPORT (ODM_RTL8188E|ODM_RTL8192E) + +#define ODM_ANTDIV_2G_SUPPORT_IC (ODM_RTL8188E|ODM_RTL8192E|ODM_RTL8723B|ODM_RTL8881A) +#define ODM_ANTDIV_5G_SUPPORT_IC (ODM_RTL8821|ODM_RTL8881A|ODM_RTL8812) +#define ODM_ANTDIV_2G BIT0 +#define ODM_ANTDIV_5G BIT1 + +#define ANTDIV_ON 1 +#define ANTDIV_OFF 0 + +#define SwAntDivRestAfterLink ODM_SwAntDivRestAfterLink +VOID ODM_SwAntDivRestAfterLink( IN PDM_ODM_T pDM_Odm); + +VOID +odm_AntennaDiversityReset( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_AntDivInit( + IN PDM_ODM_T pDM_Odm +); + +VOID +ODM_AntDiv( + IN PDM_ODM_T pDM_Odm +); + +#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) + +VOID +ODM_UpdateRxIdleAnt( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Ant +); + +#if (RTL8723B_SUPPORT == 1)||(RTL8821A_SUPPORT == 1) +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_SW_AntDiv_Callback( + IN PRT_TIMER pTimer +); + +VOID +ODM_SW_AntDiv_WorkitemCallback( + IN PVOID pContext +); +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +VOID +ODM_SW_AntDiv_Callback(void *FunctionContext); +#endif //#if (DM_ODM_SUPPORT_TYPE == ODM_CE) +#endif + +#if(RTL8188E_SUPPORT == 1 || RTL8192E_SUPPORT == 1) +#if ( !(DM_ODM_SUPPORT_TYPE == ODM_CE)) +VOID +odm_FastAntTraining( + IN PDM_ODM_T pDM_Odm +); + +VOID +odm_FastAntTrainingCallback( + IN PDM_ODM_T pDM_Odm +); + +VOID +odm_FastAntTrainingWorkItemCallback( + IN PDM_ODM_T pDM_Odm +); +#endif +#endif + +VOID +ODM_Process_RSSIForAntDiv( + IN OUT PDM_ODM_T pDM_Odm, + IN PODM_PHY_INFO_T pPhyInfo, + IN PODM_PACKET_INFO_T pPktinfo +); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +ODM_SetTxAntByTxInfo( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pDesc, + IN u1Byte macId +); + +#else// (DM_ODM_SUPPORT_TYPE == ODM_AP) +VOID +ODM_SetTxAntByTxInfo( + //IN PDM_ODM_T pDM_Odm, + struct rtl8192cd_priv *priv, + struct tx_desc *pdesc, + struct tx_insn *txcfg, + unsigned short aid +); + +#endif + +#endif //#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) +#endif //#ifndef __ODMANTDIV_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_CfoTracking.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_CfoTracking.h new file mode 100644 index 0000000..3d473d5 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_CfoTracking.h @@ -0,0 +1,73 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMCFOTRACK_H__ +#define __PHYDMCFOTRACK_H__ + +#define CFO_TRACKING_VERSION "1.0" + +//#define CFO_TH_XTAL_HIGH 20 // kHz +//#define CFO_TH_XTAL_LOW 10 // kHz +//#define CFO_TH_ATC 80 // kHz + +#if ((RTL8195A_SUPPORT==0) && (RTL8711B_SUPPORT == 0)) +typedef struct _CFO_TRACKING_ +{ + BOOLEAN bATCStatus; + BOOLEAN largeCFOHit; + BOOLEAN bAdjust; + u1Byte CrystalCap; + u1Byte DefXCap; + int CFO_tail[2]; + int CFO_ave_pre; + u4Byte packetCount; + u4Byte packetCount_pre; + BOOLEAN bForceXtalCap; + BOOLEAN bReset; + u1Byte CFO_TH_XTAL_HIGH; + u1Byte CFO_TH_XTAL_LOW; + u1Byte CFO_TH_ATC; +}CFO_TRACKING, *PCFO_TRACKING; +#endif + +VOID +ODM_CfoTrackingReset( + IN PVOID pDM_VOID +); + +VOID +ODM_CfoTrackingInit( + IN PVOID pDM_VOID +); + +VOID +ODM_CfoTracking( + IN PVOID pDM_VOID +); + +VOID +ODM_ParsingCFO( + IN PVOID pDM_VOID, + IN PVOID pPktinfo_VOID, + IN s1Byte* pcfotail, + IN u1Byte num_ss +); + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DIG.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DIG.h new file mode 100644 index 0000000..58da5f8 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DIG.h @@ -0,0 +1,476 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODMDIG_H__ +#define __ODMDIG_H__ + +typedef struct _Dynamic_Initial_Gain_Threshold_ +{ + BOOLEAN bStopDIG; // for debug + BOOLEAN bPauseDIG; + BOOLEAN bIgnoreDIG; + BOOLEAN bPSDInProgress; + + u1Byte Dig_Enable_Flag; + u1Byte Dig_Ext_Port_Stage; + + int RssiLowThresh; + int RssiHighThresh; + + u4Byte FALowThresh; + u4Byte FAHighThresh; + + u1Byte CurSTAConnectState; + u1Byte PreSTAConnectState; + u1Byte CurMultiSTAConnectState; + + u1Byte PreIGValue; + u1Byte CurIGValue; + u1Byte BackupIGValue; //MP DIG + u1Byte BT30_CurIGI; + u1Byte IGIBackup; + + s1Byte BackoffVal; + s1Byte BackoffVal_range_max; + s1Byte BackoffVal_range_min; + u1Byte rx_gain_range_max; + u1Byte rx_gain_range_min; + u1Byte Rssi_val_min; + + u1Byte PreCCK_CCAThres; + u1Byte CurCCK_CCAThres; + u1Byte PreCCKPDState; + u1Byte CurCCKPDState; + u1Byte CCKPDBackup; + + u1Byte LargeFAHit; + u1Byte ForbiddenIGI; + u4Byte Recover_cnt; + + u1Byte DIG_Dynamic_MIN_0; + u1Byte DIG_Dynamic_MIN_1; + BOOLEAN bMediaConnect_0; + BOOLEAN bMediaConnect_1; + + u4Byte AntDiv_RSSI_max; + u4Byte RSSI_max; + + u1Byte *pbP2pLinkInProgress; + u4Byte cckFaMa; + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) + BOOLEAN bTpTarget; + BOOLEAN bNoiseEst; + u4Byte TpTrainTH_min; + u1Byte IGIOffset_A; + u1Byte IGIOffset_B; +#endif +}DIG_T,*pDIG_T; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) +typedef struct _FALSE_ALARM_STATISTICS{ + u4Byte Cnt_Parity_Fail; + u4Byte Cnt_Rate_Illegal; + u4Byte Cnt_Crc8_fail; + u4Byte Cnt_Mcs_fail; + u4Byte Cnt_Ofdm_fail; + u4Byte Cnt_Ofdm_fail_pre; //For RTL8881A + u4Byte Cnt_Cck_fail; + u4Byte Cnt_all; + u4Byte Cnt_Fast_Fsync; + u4Byte Cnt_SB_Search_fail; + u4Byte Cnt_OFDM_CCA; + u4Byte Cnt_CCK_CCA; + u4Byte Cnt_CCA_all; + u4Byte Cnt_BW_USC; //Gary + u4Byte Cnt_BW_LSC; //Gary +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; +#endif + +typedef enum tag_Dynamic_Init_Gain_Operation_Type_Definition +{ + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_BACKOFF = 2, + DIG_TYPE_RX_GAIN_MIN = 3, + DIG_TYPE_RX_GAIN_MAX = 4, + DIG_TYPE_ENABLE = 5, + DIG_TYPE_DISABLE = 6, + DIG_OP_TYPE_MAX +}DM_DIG_OP_E; + +typedef enum tag_ODM_PauseDIG_Type { + ODM_PAUSE_DIG = BIT0, + ODM_RESUME_DIG = BIT1 +} ODM_Pause_DIG_TYPE; + +typedef enum tag_ODM_PauseCCKPD_Type { + ODM_PAUSE_CCKPD = BIT0, + ODM_RESUME_CCKPD = BIT1 +} ODM_Pause_CCKPD_TYPE; + +typedef enum tag_ODM_TRx_MUX_Type +{ + ODM_SHUTDOWN = 0, + ODM_STANDBY_MODE = 1, + ODM_TX_MODE = 2, + ODM_RX_MODE = 3 +}ODM_Trx_MUX_Type; + +typedef enum tag_ODM_MACEDCCA_Type +{ + ODM_IGNORE_EDCCA = 0, + ODM_DONT_IGNORE_EDCCA = 1 +}ODM_MACEDCCA_Type; + +/* +typedef enum tag_CCK_Packet_Detection_Threshold_Type_Definition +{ + CCK_PD_STAGE_LowRssi = 0, + CCK_PD_STAGE_HighRssi = 1, + CCK_PD_STAGE_MAX = 3, +}DM_CCK_PDTH_E; + +typedef enum tag_DIG_EXT_PORT_ALGO_Definition +{ + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}DM_DIG_EXT_PORT_ALG_E; + +typedef enum tag_DIG_Connect_Definition +{ + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_MultiSTA_DISCONNECT = 3, + DIG_MultiSTA_CONNECT = 4, + DIG_CONNECT_MAX +}DM_DIG_CONNECT_E; + + +#define DM_MultiSTA_InitGainChangeNotify(Event) {DM_DigTable.CurMultiSTAConnectState = Event;} + +#define DM_MultiSTA_InitGainChangeNotify_CONNECT(_ADAPTER) \ + DM_MultiSTA_InitGainChangeNotify(DIG_MultiSTA_CONNECT) + +#define DM_MultiSTA_InitGainChangeNotify_DISCONNECT(_ADAPTER) \ + DM_MultiSTA_InitGainChangeNotify(DIG_MultiSTA_DISCONNECT) +*/ +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 400 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_MAX_NIC 0x3e +#define DM_DIG_MIN_NIC 0x20 //0x1e +#define DM_DIG_MAX_OF_MIN_NIC 0x3e + +#define DM_DIG_MAX_AP 0x3e +#define DM_DIG_MIN_AP 0x1c +#define DM_DIG_MAX_OF_MIN 0x2A //0x32 +#define DM_DIG_MIN_AP_DFS 0x20 + +#define DM_DIG_MAX_NIC_HP 0x46 +#define DM_DIG_MIN_NIC_HP 0x2e + +#define DM_DIG_MAX_AP_HP 0x42 +#define DM_DIG_MIN_AP_HP 0x30 + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define DM_DIG_MAX_AP_COVERAGR 0x26 +#define DM_DIG_MIN_AP_COVERAGE 0x1c +#define DM_DIG_MAX_OF_MIN_COVERAGE 0x22 + +#define DM_DIG_TP_Target_TH0 500 +#define DM_DIG_TP_Target_TH1 1000 +#define DM_DIG_TP_Training_Period 10 +#endif + +//vivi 92c&92d has different definition, 20110504 +//this is for 92c +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_IOT)) + #ifdef CONFIG_SPECIAL_SETTING_FOR_FUNAI_TV + #define DM_DIG_FA_TH0 0x80//0x20 + #else + #define DM_DIG_FA_TH0 0x200//0x20 + #endif +#else + #define DM_DIG_FA_TH0 0x200//0x20 +#endif + +#define DM_DIG_FA_TH1 0x300 +#define DM_DIG_FA_TH2 0x400 +//this is for 92d +#define DM_DIG_FA_TH0_92D 0x100 +#define DM_DIG_FA_TH1_92D 0x400 +#define DM_DIG_FA_TH2_92D 0x600 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 +#define DM_DIG_BACKOFF_DEFAULT 10 + +#define DM_DIG_FA_TH0_LPS 4 //-> 4 in lps +#define DM_DIG_FA_TH1_LPS 15 //-> 15 lps +#define DM_DIG_FA_TH2_LPS 30 //-> 30 lps +#define RSSI_OFFSET_DIG 0x05 + + +VOID +odm_CheckAdaptivity( + IN PVOID pDM_VOID + ); + +VOID +odm_CheckEnvironment( + IN PVOID pDM_VOID + ); + +VOID +ODM_ChangeDynamicInitGainThresh( + IN PVOID pDM_VOID, + IN u4Byte DM_Type, + IN u4Byte DM_Value + ); + +VOID +odm_NHMCounterStatisticsInit( + IN PVOID pDM_VOID + ); + +VOID +odm_NHMCounterStatistics( + IN PVOID pDM_VOID + ); + +VOID +odm_NHMBBInit( + IN PVOID pDM_VOID +); + +VOID +odm_NHMBB( + IN PVOID pDM_VOID +); + +VOID +odm_NHMCounterStatisticsReset( + IN PVOID pDM_VOID +); + +VOID +odm_GetNHMCounterStatistics( + IN PVOID pDM_VOID +); + +VOID +odm_MACEDCCAState( + IN PVOID pDM_VOID, + IN ODM_MACEDCCA_Type State +); + +VOID +odm_SetEDCCAThreshold( + IN PVOID pDM_VOID, + IN s1Byte H2L, + IN s1Byte L2H +); + +VOID +odm_SetTRxMux( + IN PVOID pDM_VOID, + IN ODM_Trx_MUX_Type txMode, + IN ODM_Trx_MUX_Type rxMode +); + +BOOLEAN +odm_CalNHMcnt( + IN PVOID pDM_VOID + ); + +VOID +odm_SearchPwdBLowerBound( + IN PVOID pDM_VOID +); + +VOID +odm_AdaptivityInit( + IN PVOID pDM_VOID + ); + +BOOLEAN +odm_Adaptivity( + IN PVOID pDM_VOID, + IN u1Byte IGI + ); + +VOID +ODM_Write_DIG( + IN PVOID pDM_VOID, + IN u1Byte CurrentIGI + ); + +VOID +odm_PauseDIG( + IN PVOID pDM_VOID, + IN ODM_Pause_DIG_TYPE PauseType, + IN u1Byte IGIValue + ); + +VOID +odm_DIGInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DIG( + IN PVOID pDM_VOID + ); + +VOID +odm_DIGbyRSSI_LPS( + IN PVOID pDM_VOID + ); + +VOID +odm_DigForBtHsMode( + IN PVOID pDM_VOID + ); + +VOID +odm_FalseAlarmCounterStatistics( + IN PVOID pDM_VOID + ); + +#if (DM_ODM_SUPPORT_TYPE & ODM_IOT) +VOID +odm_FAThresholdCheck( + IN PVOID pDM_VOID, + OUT u4Byte* dm_FA_thres + ); +#else +VOID +odm_FAThresholdCheck( + IN PVOID pDM_VOID, + IN BOOLEAN bDFSBand, + IN BOOLEAN bPerformance, + IN u4Byte RxTp, + IN u4Byte TxTp, + OUT u4Byte* dm_FA_thres + ); +#endif +u1Byte +odm_ForbiddenIGICheck( + IN PVOID pDM_VOID, + IN u1Byte DIG_Dynamic_MIN, + IN u1Byte CurrentIGI + ); + +VOID +odm_InbandNoiseCalculate ( + IN PVOID pDM_VOID + ); + +BOOLEAN +odm_DigAbort( + IN PVOID pDM_VOID + ); + +VOID +odm_PauseCCKPacketDetection( + IN PVOID pDM_VOID, + IN ODM_Pause_CCKPD_TYPE PauseType, + IN u1Byte CCKPDThreshold + ); + +VOID +odm_CCKPacketDetectionThresh( + IN PVOID pDM_VOID + ); + +VOID +ODM_Write_CCK_CCA_Thres( + IN PVOID pDM_VOID, + IN u1Byte CurCCK_CCAThres + ); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +VOID +odm_DisableEDCCA( + IN PVOID pDM_VOID +); + +VOID +odm_DynamicEDCCA( + IN PVOID pDM_VOID +); + +VOID +odm_MPT_DIGCallback( + PRT_TIMER pTimer +); + +VOID +odm_MPT_DIGWorkItemCallback( + IN PVOID pContext + ); + +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +VOID +odm_MPT_DIGCallback( + IN PVOID pDM_VOID +); +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_AP|ODM_ADSL)) +VOID +ODM_MPT_DIG( + IN PVOID pDM_VOID +); +#endif + + +#endif + +VOID +odm_DIGInit_8195A( + IN PVOID pDM_VOID + ); + +VOID +odm_DIG_8195A( + IN PVOID pDM_VOID + ); + +VOID +odm_FalseAlarmCounterStatistics_8195A( + IN PVOID pDM_VOID + ); + +VOID +odm_CCKPacketDetectionThresh_8195A( + IN PVOID pDM_VOID + ); \ No newline at end of file diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicBBPowerSaving.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicBBPowerSaving.h new file mode 100644 index 0000000..bf473f9 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicBBPowerSaving.h @@ -0,0 +1,63 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMDYNAMICBBPOWERSAVING_H__ +#define __PHYDMDYNAMICBBPOWERSAVING_H__ + +#define DYNAMIC_BBPWRSAV_VERSION "1.0" + +typedef struct _Dynamic_Power_Saving_ +{ + u1Byte PreCCAState; + u1Byte CurCCAState; + + u1Byte PreRFState; + u1Byte CurRFState; + + int Rssi_val_min; + + u1Byte initialize; + u4Byte Reg874,RegC70,Reg85C,RegA74; + +}PS_T,*pPS_T; + +#define dm_RF_Saving ODM_RF_Saving + +void ODM_RF_Saving( + IN PVOID pDM_VOID, + IN u1Byte bForceInNormal + ); + +VOID +odm_DynamicBBPowerSavingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicBBPowerSaving( + IN PVOID pDM_VOID + ); + +VOID +odm_1R_CCA( + IN PVOID pDM_VOID + ); + +#endif \ No newline at end of file diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicTxPower.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicTxPower.h new file mode 100644 index 0000000..9a38013 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_DynamicTxPower.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMDYNAMICTXPOWER_H__ +#define __PHYDMDYNAMICTXPOWER_H__ + +#define DYNAMIC_TXPWR_VERSION "1.0" + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 +#define TX_POWER_NEAR_FIELD_THRESH_AP 0x3F +#define TX_POWER_NEAR_FIELD_THRESH_8812 60 + +#define TxHighPwrLevel_Normal 0 +#define TxHighPwrLevel_Level1 1 +#define TxHighPwrLevel_Level2 2 +#define TxHighPwrLevel_BT1 3 +#define TxHighPwrLevel_BT2 4 +#define TxHighPwrLevel_15 5 +#define TxHighPwrLevel_35 6 +#define TxHighPwrLevel_50 7 +#define TxHighPwrLevel_70 8 +#define TxHighPwrLevel_100 9 + +VOID +odm_DynamicTxPowerInit( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerRestorePowerIndex( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerNIC( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +VOID +odm_DynamicTxPowerSavePowerIndex( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerWritePowerIndex( + IN PVOID pDM_VOID, + IN u1Byte Value); + +VOID +odm_DynamicTxPower_92C( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPower_92D( + IN PVOID pDM_VOID + ); +#endif + +VOID +odm_DynamicTxPower( + IN PVOID pDM_VOID + ); + +VOID +odm_DynamicTxPowerAP( + IN PVOID pDM_VOID + ); + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_EdcaTurboCheck.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_EdcaTurboCheck.h new file mode 100644 index 0000000..65be74f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_EdcaTurboCheck.h @@ -0,0 +1,152 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMEDCATURBOCHECK_H__ +#define __PHYDMEDCATURBOCHECK_H__ + +#define EDCATURBO_VERSION "1.0" + +typedef struct _EDCA_TURBO_ +{ + BOOLEAN bCurrentTurboEDCA; + BOOLEAN bIsCurRDLState; + + #if(DM_ODM_SUPPORT_TYPE == ODM_CE ) + u4Byte prv_traffic_idx; // edca turbo + #endif + +}EDCA_T,*pEDCA_T; + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE)) +static u4Byte edca_setting_UL[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU MARVELL 92U_AP SELF_AP(DownLink/Tx) +{ 0x5e4322, 0xa44f, 0x5e4322, 0x5ea32b, 0x5ea422, 0x5ea322, 0x3ea430, 0x5ea42b, 0x5ea44f, 0x5e4322, 0x5e4322}; + + +static u4Byte edca_setting_DL[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP(UpLink/Rx) +{ 0xa44f, 0x5ea44f, 0x5e4322, 0x5ea42b, 0xa44f, 0xa630, 0x5ea630, 0x5ea42b, 0xa44f, 0xa42b, 0xa42b}; + +static u4Byte edca_setting_DL_GMode[HT_IOT_PEER_MAX] = +// UNKNOWN REALTEK_90 REALTEK_92SE BROADCOM RALINK ATHEROS CISCO MERU, MARVELL 92U_AP SELF_AP +{ 0x4322, 0xa44f, 0x5e4322, 0xa42b, 0x5e4322, 0x4322, 0xa42b, 0x5ea42b, 0xa44f, 0x5e4322, 0x5ea42b}; + + +//============================================================ +// EDCA Paramter for AP/ADSL by Mingzhi 2011-11-22 +//============================================================ +#elif (DM_ODM_SUPPORT_TYPE &ODM_ADSL) +enum qos_prio { BK, BE, VI, VO, VI_AG, VO_AG }; + +static const struct ParaRecord rtl_ap_EDCA[] = +{ +//ACM,AIFSN, ECWmin, ECWmax, TXOplimit + {0, 7, 4, 10, 0}, //BK + {0, 3, 4, 6, 0}, //BE + {0, 1, 3, 4, 188}, //VI + {0, 1, 2, 3, 102}, //VO + {0, 1, 3, 4, 94}, //VI_AG + {0, 1, 2, 3, 47}, //VO_AG +}; + +static const struct ParaRecord rtl_sta_EDCA[] = +{ +//ACM,AIFSN, ECWmin, ECWmax, TXOplimit + {0, 7, 4, 10, 0}, + {0, 3, 4, 10, 0}, + {0, 2, 3, 4, 188}, + {0, 2, 2, 3, 102}, + {0, 2, 3, 4, 94}, + {0, 2, 2, 3, 47}, +}; +#endif + + +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#ifdef WIFI_WMM +VOID +ODM_IotEdcaSwitch( + IN PVOID pDM_VOID, + IN unsigned char enable + ); +#endif + +BOOLEAN +ODM_ChooseIotMainSTA( + IN PVOID pDM_VOID, + IN PSTA_INFO_T pstat + ); +#endif + +VOID +odm_EdcaTurboCheck( + IN PVOID pDM_VOID + ); +VOID +ODM_EdcaTurboInit( + IN PVOID pDM_VOID +); + +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) +VOID +odm_EdcaTurboCheckMP( + IN PVOID pDM_VOID + ); + +//check if edca turbo is disabled +BOOLEAN +odm_IsEdcaTurboDisable( + IN PVOID pDM_VOID +); +//choose edca paramter for special IOT case +VOID +ODM_EdcaParaSelByIot( + IN PVOID pDM_VOID, + OUT u4Byte *EDCA_BE_UL, + OUT u4Byte *EDCA_BE_DL + ); +//check if it is UL or DL +VOID +odm_EdcaChooseTrafficIdx( + IN PVOID pDM_VOID, + IN u8Byte cur_tx_bytes, + IN u8Byte cur_rx_bytes, + IN BOOLEAN bBiasOnRx, + OUT BOOLEAN *pbIsCurRDLState + ); + +#elif (DM_ODM_SUPPORT_TYPE==ODM_CE) +VOID +odm_EdcaTurboCheckCE( + IN PVOID pDM_VOID + ); +#else +VOID +odm_IotEngine( + IN PVOID pDM_VOID + ); + +VOID +odm_EdcaParaInit( + IN PVOID pDM_VOID + ); +#endif + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_HWConfig.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_HWConfig.h new file mode 100644 index 0000000..6d33de1 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_HWConfig.h @@ -0,0 +1,508 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __HALHWOUTSRC_H__ +#define __HALHWOUTSRC_H__ + + +/*--------------------------Define -------------------------------------------*/ +//#define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = Array[i]; v2 = Array[i+1]; } while(0) +#define AGC_DIFF_CONFIG_MP(ic, band) (ODM_ReadAndConfig_MP_##ic##_AGC_TAB_DIFF(pDM_Odm, Array_MP_##ic##_AGC_TAB_DIFF_##band, \ + sizeof(Array_MP_##ic##_AGC_TAB_DIFF_##band)/sizeof(u4Byte))) +#define AGC_DIFF_CONFIG_TC(ic, band) (ODM_ReadAndConfig_TC_##ic##_AGC_TAB_DIFF(pDM_Odm, Array_TC_##ic##_AGC_TAB_DIFF_##band, \ + sizeof(Array_TC_##ic##_AGC_TAB_DIFF_##band)/sizeof(u4Byte))) + +#define AGC_DIFF_CONFIG(ic, band) do {\ + if (pDM_Odm->bIsMPChip)\ + AGC_DIFF_CONFIG_MP(ic,band);\ + else\ + AGC_DIFF_CONFIG_TC(ic,band);\ + } while(0) + + +//============================================================ +// structure and define +//============================================================ + +typedef struct _Phy_Rx_AGC_Info +{ + #if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain:7,trsw:1; + #else + u1Byte trsw:1,gain:7; + #endif +} PHY_RX_AGC_INFO_T,*pPHY_RX_AGC_INFO_T; + +typedef struct _Phy_Status_Rpt_8192cd +{ + PHY_RX_AGC_INFO_T path_agc[2]; + u1Byte ch_corr[2]; + u1Byte cck_sig_qual_ofdm_pwdb_all; + u1Byte cck_agc_rpt_ofdm_cfosho_a; + u1Byte cck_rpt_b_ofdm_cfosho_b; + u1Byte rsvd_1;//ch_corr_msb; + u1Byte noise_power_db_msb; + s1Byte path_cfotail[2]; + u1Byte pcts_mask[2]; + s1Byte stream_rxevm[2]; + u1Byte path_rxsnr[2]; + u1Byte noise_power_db_lsb; + u1Byte rsvd_2[3]; + u1Byte stream_csi[2]; + u1Byte stream_target_csi[2]; + s1Byte sig_evm; + u1Byte rsvd_3; + +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antsel_rx_keep_2:1; //ex_intf_flg:1; + u1Byte sgi_en:1; + u1Byte rxsc:2; + u1Byte idle_long:1; + u1Byte r_ant_train_en:1; + u1Byte ant_sel_b:1; + u1Byte ant_sel:1; +#else // _BIG_ENDIAN_ + u1Byte ant_sel:1; + u1Byte ant_sel_b:1; + u1Byte r_ant_train_en:1; + u1Byte idle_long:1; + u1Byte rxsc:2; + u1Byte sgi_en:1; + u1Byte antsel_rx_keep_2:1; //ex_intf_flg:1; +#endif +} PHY_STATUS_RPT_8192CD_T,*PPHY_STATUS_RPT_8192CD_T; + + +typedef struct _Phy_Status_Rpt_8812 +{ +#if 0 + PHY_RX_AGC_INFO_T path_agc[2]; + u1Byte ch_num[2]; + u1Byte cck_sig_qual_ofdm_pwdb_all; + u1Byte cck_agc_rpt_ofdm_cfosho_a; + u1Byte cck_bb_pwr_ofdm_cfosho_b; + u1Byte cck_rx_path; //CCK_RX_PATH [3:0] (with regA07[3:0] definition) + u1Byte rsvd_1; + u1Byte path_cfotail[2]; + u1Byte pcts_mask[2]; + s1Byte stream_rxevm[2]; + u1Byte path_rxsnr[2]; + u1Byte rsvd_2[2]; + u1Byte stream_snr[2]; + u1Byte stream_csi[2]; + u1Byte rsvd_3[2]; + s1Byte sig_evm; + u1Byte rsvd_4; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_anta:3; + u1Byte antidx_antb:3; + u1Byte rsvd_5:2; +#else // _BIG_ENDIAN_ + u1Byte rsvd_5:2; + u1Byte antidx_antb:3; + u1Byte antidx_anta:3; +#endif +#endif + + //2012.05.24 LukeLee: This structure should take big/little endian in consideration later..... + + //DWORD 0 + u1Byte gain_trsw[2]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u2Byte chl_num:10; + u2Byte sub_chnl:4; + u2Byte r_RFMOD:2; +#else // _BIG_ENDIAN_ + u2Byte r_RFMOD:2; + u2Byte sub_chnl:4; + u2Byte chl_num:10; +#endif + + //DWORD 1 + u1Byte pwdb_all; + u1Byte cfosho[4]; // DW 1 byte 1 DW 2 byte 0 + + //DWORD 2 + s1Byte cfotail[4]; // DW 2 byte 1 DW 3 byte 0 + + //DWORD 3 + s1Byte rxevm[2]; // DW 3 byte 1 DW 3 byte 2 + s1Byte rxsnr[2]; // DW 3 byte 3 DW 4 byte 0 + + //DWORD 4 + u1Byte PCTS_MSK_RPT[2]; + u1Byte pdsnr[2]; // DW 4 byte 3 DW 5 Byte 0 + + //DWORD 5 + u1Byte csi_current[2]; + u1Byte rx_gain_c; + + //DWORD 6 + u1Byte rx_gain_d; + s1Byte sigevm; + u1Byte resvd_0; + u1Byte antidx_anta:3; + u1Byte antidx_antb:3; + u1Byte resvd_1:2; +} PHY_STATUS_RPT_8812_T,*PPHY_STATUS_RPT_8812_T; + + +VOID +odm_Init_RSSIForDM( + IN OUT PDM_ODM_T pDM_Odm + ); + +VOID +ODM_PhyStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + OUT PODM_PHY_INFO_T pPhyInfo, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo + ); + +VOID +ODM_MacStatusQuery( + IN OUT PDM_ODM_T pDM_Odm, + IN pu1Byte pMacStatus, + IN u1Byte MacID, + IN BOOLEAN bPacketMatchBSSID, + IN BOOLEAN bPacketToSelf, + IN BOOLEAN bPacketBeacon + ); +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_IOT)) + +HAL_STATUS +ODM_ConfigRFWithTxPwrTrackHeaderFile( + IN PDM_ODM_T pDM_Odm + ); + +HAL_STATUS +ODM_ConfigRFWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_Config_Type ConfigType, + IN ODM_RF_RADIO_PATH_E eRFPath + ); + +HAL_STATUS +ODM_ConfigBBWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_BB_Config_Type ConfigType + ); + +HAL_STATUS +ODM_ConfigMACWithHeaderFile( + IN PDM_ODM_T pDM_Odm + ); + +HAL_STATUS +ODM_ConfigFWWithHeaderFile( + IN PDM_ODM_T pDM_Odm, + IN ODM_FW_Config_Type ConfigType, + OUT u1Byte *pFirmware, + OUT u4Byte *pSize + ); + +u4Byte +ODM_GetHWImgVersion( + IN PDM_ODM_T pDM_Odm + ); + +s4Byte +odm_SignalScaleMapping( + IN OUT PDM_ODM_T pDM_Odm, + IN s4Byte CurrSig + ); + +#endif + +#if(ODM_PHY_STATUS_NEW_TYPE_SUPPORT == 1) +//For New RX PHY Status Report Format, include 8723D/8710B +VOID +phydm_RxPhyStatusNewType( + IN PDM_ODM_T pPhydm, + IN pu1Byte pPhyStatus, + IN PODM_PACKET_INFO_T pPktinfo, + OUT PODM_PHY_INFO_T pPhyInfo +); + +typedef struct _Phy_Status_Rpt_Jaguar2_Type0 { + /* DW0 */ + u1Byte page_num; + u1Byte pwdb; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain: 6; + u1Byte rsvd_0: 1; + u1Byte trsw: 1; +#else + u1Byte trsw: 1; + u1Byte rsvd_0: 1; + u1Byte gain: 6; +#endif + u1Byte rsvd_1; + + /* DW1 */ + u1Byte rsvd_2; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte rxsc: 4; + u1Byte agc_table: 4; +#else + u1Byte agc_table: 4; + u1Byte rxsc: 4; +#endif + u1Byte channel; + u1Byte band; + + /* DW2 */ + u2Byte length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_a: 3; + u1Byte antidx_b: 3; + u1Byte rsvd_3: 2; + u1Byte antidx_c: 3; + u1Byte antidx_d: 3; + u1Byte rsvd_4:2; +#else + u1Byte rsvd_3: 2; + u1Byte antidx_b: 3; + u1Byte antidx_a: 3; + u1Byte rsvd_4:2; + u1Byte antidx_d: 3; + u1Byte antidx_c: 3; +#endif + + /* DW3 */ + u1Byte signal_quality; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte vga:5; + u1Byte lna_l:3; + u1Byte bb_power:6; + u1Byte rsvd_9:1; + u1Byte lna_h:1; +#else + u1Byte lna_l:3; + u1Byte vga:5; + u1Byte lna_h:1; + u1Byte rsvd_9:1; + u1Byte bb_power:6; +#endif + u1Byte rsvd_5; + + /* DW4 */ + u4Byte rsvd_6; + + /* DW5 */ + u4Byte rsvd_7; + + /* DW6 */ + u4Byte rsvd_8; +} PHY_STATUS_RPT_JAGUAR2_TYPE0, *PPHY_STATUS_RPT_JAGUAR2_TYPE0; //for CCK Format + +typedef struct _Phy_Status_Rpt_Jaguar2_Type1 { + /* DW0 and DW1 */ + u1Byte page_num; + u1Byte pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte l_rxsc: 4; + u1Byte ht_rxsc: 4; +#else + u1Byte ht_rxsc: 4; + u1Byte l_rxsc: 4; +#endif + u1Byte channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte band: 2; + u1Byte rsvd_0: 1; + u1Byte hw_antsw_occu: 1; + u1Byte gnt_bt: 1; + u1Byte ldpc: 1; + u1Byte stbc: 1; + u1Byte beamformed: 1; +#else + u1Byte beamformed: 1; + u1Byte stbc: 1; + u1Byte ldpc: 1; + u1Byte gnt_bt: 1; + u1Byte hw_antsw_occu: 1; + u1Byte rsvd_0: 1; + u1Byte band: 2; +#endif + + /* DW2 */ + u2Byte lsig_length; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte antidx_a: 3; + u1Byte antidx_b: 3; + u1Byte rsvd_1: 2; + u1Byte antidx_c: 3; + u1Byte antidx_d: 3; + u1Byte rsvd_2: 2; +#else + u1Byte rsvd_1: 2; + u1Byte antidx_b: 3; + u1Byte antidx_a: 3; + u1Byte rsvd_2: 2; + u1Byte antidx_d: 3; + u1Byte antidx_c: 3; +#endif + + /* DW3 */ + u1Byte paid; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte paid_msb: 1; + u1Byte gid: 6; + u1Byte rsvd_3: 1; +#else + u1Byte rsvd_3: 1; + u1Byte gid: 6; + u1Byte paid_msb: 1; +#endif + u1Byte intf_pos; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte intf_pos_msb: 1; + u1Byte rsvd_4: 2; + u1Byte nb_intf_flag: 1; + u1Byte rf_mode: 2; + u1Byte rsvd_5: 2; +#else + u1Byte rsvd_5: 2; + u1Byte rf_mode: 2; + u1Byte nb_intf_flag: 1; + u1Byte rsvd_4: 2; + u1Byte intf_pos_msb: 1; +#endif + + /* DW4 */ + s1Byte rxevm[4]; /* s(8,1) */ + + /* DW5 */ + s1Byte cfo_tail[4]; /* s(8,7) */ + + /* DW6 */ + s1Byte rxsnr[4]; /* s(8,1) */ +} PHY_STATUS_RPT_JAGUAR2_TYPE1, *PPHY_STATUS_RPT_JAGUAR2_TYPE1;//for OFDM Format + +typedef struct _Phy_Status_Rpt_Jaguar2_Type2 { + /* DW0 ane DW1 */ + u1Byte page_num; + u1Byte pwdb[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte l_rxsc: 4; + u1Byte ht_rxsc: 4; +#else + u1Byte ht_rxsc: 4; + u1Byte l_rxsc: 4; +#endif + u1Byte channel; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte band: 2; + u1Byte rsvd_0: 1; + u1Byte hw_antsw_occu: 1; + u1Byte gnt_bt: 1; + u1Byte ldpc: 1; + u1Byte stbc: 1; + u1Byte beamformed: 1; +#else + u1Byte beamformed: 1; + u1Byte stbc: 1; + u1Byte ldpc: 1; + u1Byte gnt_bt: 1; + u1Byte hw_antsw_occu: 1; + u1Byte rsvd_0: 1; + u1Byte band: 2; +#endif + + /* DW2 */ +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte shift_l_map: 6; + u1Byte rsvd_1: 2; +#else + u1Byte rsvd_1: 2; + u1Byte shift_l_map: 6; +#endif + u1Byte cnt_pw2cca; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte agc_table_a: 4; + u1Byte agc_table_b: 4; + u1Byte agc_table_c: 4; + u1Byte agc_table_d: 4; +#else + u1Byte agc_table_b: 4; + u1Byte agc_table_a: 4; + u1Byte agc_table_d: 4; + u1Byte agc_table_c: 4; +#endif + + /* DW3 ~ DW6*/ + u1Byte cnt_cca2agc_rdy; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte gain_a: 6; + u1Byte rsvd_2: 1; + u1Byte trsw_a: 1; + u1Byte gain_b: 6; + u1Byte rsvd_3: 1; + u1Byte trsw_b: 1; + u1Byte gain_c: 6; + u1Byte rsvd_4: 1; + u1Byte trsw_c: 1; + u1Byte gain_d: 6; + u1Byte rsvd_5: 1; + u1Byte trsw_d: 1; + u1Byte aagc_step_a: 2; + u1Byte aagc_step_b: 2; + u1Byte aagc_step_c: 2; + u1Byte aagc_step_d: 2; +#else + u1Byte trsw_a: 1; + u1Byte rsvd_2: 1; + u1Byte gain_a: 6; + u1Byte trsw_b: 1; + u1Byte rsvd_3: 1; + u1Byte gain_b: 6; + u1Byte trsw_c: 1; + u1Byte rsvd_4: 1; + u1Byte gain_c: 6; + u1Byte trsw_d: 1; + u1Byte rsvd_5: 1; + u1Byte gain_d: 6; + u1Byte aagc_step_d: 2; + u1Byte aagc_step_c: 2; + u1Byte aagc_step_b: 2; + u1Byte aagc_step_a: 2; +#endif + u1Byte ht_aagc_gain[4]; + u1Byte dagc_gain[4]; +#if (ODM_ENDIAN_TYPE == ODM_ENDIAN_LITTLE) + u1Byte counter: 6; + u1Byte rsvd_6: 2; + u1Byte syn_count: 5; + u1Byte rsvd_7:3; +#else + u1Byte rsvd_6: 2; + u1Byte counter: 6; + u1Byte rsvd_7:3; + u1Byte syn_count: 5; +#endif +} PHY_STATUS_RPT_JAGUAR2_TYPE2, *PPHY_STATUS_RPT_JAGUAR2_TYPE2;//for debug mode: AGC&SBD + +#endif + +#endif /*#ifndef __HALHWOUTSRC_H__*/ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_NoiseMonitor.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_NoiseMonitor.h new file mode 100644 index 0000000..022cefe --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_NoiseMonitor.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + *****************************************************************************/ +#ifndef __ODMNOISEMONITOR_H__ +#define __ODMNOISEMONITOR_H__ + +#define ODM_MAX_CHANNEL_NUM 38//14+24 +struct noise_level +{ + //u1Byte value_a, value_b; + u1Byte value[MAX_RF_PATH]; + //s1Byte sval_a, sval_b; + s1Byte sval[MAX_RF_PATH]; + + //s4Byte noise_a=0, noise_b=0,sum_a=0, sum_b=0; + //s4Byte noise[ODM_RF_PATH_MAX]; + s4Byte sum[MAX_RF_PATH]; + //u1Byte valid_cnt_a=0, valid_cnt_b=0, + u1Byte valid[MAX_RF_PATH]; + u1Byte valid_cnt[MAX_RF_PATH]; + +}; + + +typedef struct _ODM_NOISE_MONITOR_ +{ + s1Byte noise[MAX_RF_PATH]; + s2Byte noise_all; +}ODM_NOISE_MONITOR; + +s2Byte ODM_InbandNoise_Monitor(PVOID pDM_VOID,u8 bPauseDIG,u8 IGIValue,u32 max_time); + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PathDiv.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PathDiv.h new file mode 100644 index 0000000..693f413 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PathDiv.h @@ -0,0 +1,193 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMPATHDIV_H__ +#define __PHYDMPATHDIV_H__ + +#define PATHDIV_VERSION "1.0" + +VOID +odm_PathDiversityInit( + IN PVOID pDM_VOID + ); + +VOID +odm_PathDiversity( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + +//#define PATHDIV_ENABLE 1 +#define dm_PathDiv_RSSI_Check ODM_PathDivChkPerPktRssi +#define PathDivCheckBeforeLink8192C ODM_PathDiversityBeforeLink92C + +typedef struct _PathDiv_Parameter_define_ +{ + u4Byte org_5g_RegE30; + u4Byte org_5g_RegC14; + u4Byte org_5g_RegCA0; + u4Byte swt_5g_RegE30; + u4Byte swt_5g_RegC14; + u4Byte swt_5g_RegCA0; + //for 2G IQK information + u4Byte org_2g_RegC80; + u4Byte org_2g_RegC4C; + u4Byte org_2g_RegC94; + u4Byte org_2g_RegC14; + u4Byte org_2g_RegCA0; + + u4Byte swt_2g_RegC80; + u4Byte swt_2g_RegC4C; + u4Byte swt_2g_RegC94; + u4Byte swt_2g_RegC14; + u4Byte swt_2g_RegCA0; +}PATHDIV_PARA,*pPATHDIV_PARA; + +VOID +odm_PathDiversityInit_92C( + IN PADAPTER Adapter + ); + +VOID +odm_2TPathDiversityInit_92C( + IN PADAPTER Adapter + ); + +VOID +odm_1TPathDiversityInit_92C( + IN PADAPTER Adapter + ); + +BOOLEAN +odm_IsConnected_92C( + IN PADAPTER Adapter + ); + +BOOLEAN +ODM_PathDiversityBeforeLink92C( + //IN PADAPTER Adapter + IN PDM_ODM_T pDM_Odm + ); + +VOID +odm_PathDiversityAfterLink_92C( + IN PADAPTER Adapter + ); + +VOID +odm_SetRespPath_92C( + IN PADAPTER Adapter, + IN u1Byte DefaultRespPath + ); + +VOID +odm_OFDMTXPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_CCKTXPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_ResetPathDiversity_92C( + IN PADAPTER Adapter + ); + +VOID +odm_CCKTXPathDiversityCallback( + PRT_TIMER pTimer + ); + +VOID +odm_CCKTXPathDiversityWorkItemCallback( + IN PVOID pContext + ); + +VOID +odm_PathDivChkAntSwitchCallback( + PRT_TIMER pTimer + ); + +VOID +odm_PathDivChkAntSwitchWorkitemCallback( + IN PVOID pContext + ); + + +VOID +odm_PathDivChkAntSwitch( + PDM_ODM_T pDM_Odm + ); + +VOID +ODM_CCKPathDiversityChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd, + pu1Byte pDesc + ); + +VOID +ODM_PathDivChkPerPktRssi( + PADAPTER Adapter, + BOOLEAN bIsDefPort, + BOOLEAN bMatchBSSID, + PRT_WLAN_STA pEntry, + PRT_RFD pRfd + ); + +VOID +ODM_PathDivRestAfterLink( + IN PDM_ODM_T pDM_Odm + ); + +VOID +ODM_FillTXPathInTXDESC( + IN PADAPTER Adapter, + IN PRT_TCB pTcb, + IN pu1Byte pDesc + ); + +VOID +odm_PathDivInit_92D( + IN PDM_ODM_T pDM_Odm + ); + +u1Byte +odm_SwAntDivSelectScanChnl( + IN PADAPTER Adapter + ); + +VOID +odm_SwAntDivConstructScanChnl( + IN PADAPTER Adapter, + IN u1Byte ScanChnl + ); + + #endif //#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + + + #endif //#ifndef __ODMPATHDIV_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PowerTracking.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PowerTracking.h new file mode 100644 index 0000000..ea4350d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_PowerTracking.h @@ -0,0 +1,306 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMPOWERTRACKING_H__ +#define __PHYDMPOWERTRACKING_H__ + +#define POWRTRACKING_VERSION "1.0" + +#define DPK_DELTA_MAPPING_NUM 13 +#define index_mapping_HP_NUM 15 +#define OFDM_TABLE_SIZE 43 +#define CCK_TABLE_SIZE 33 +#define TXSCALE_TABLE_SIZE 37 +#define TXPWR_TRACK_TABLE_SIZE 30 +#define DELTA_SWINGIDX_SIZE 30 +#define BAND_NUM 4 +#define CCK_TABLE_SIZE_8711B 41 + +#define AVG_THERMAL_NUM 8 +#define HP_THERMAL_NUM 8 +#define IQK_MAC_REG_NUM 4 +#define IQK_ADDA_REG_NUM 16 +#define IQK_BB_REG_NUM_MAX 10 +#if (RTL8192D_SUPPORT==1) +#define IQK_BB_REG_NUM 10 +#else +#define IQK_BB_REG_NUM 9 +#endif + + +#define IQK_Matrix_REG_NUM 8 +#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8195A) || defined (CONFIG_RTL8711B) +#define IQK_Matrix_Settings_NUM 14 +#else +#define IQK_Matrix_Settings_NUM 14+24+21 // Channels_2_4G_NUM + Channels_5G_20M_NUM + Channels_5G +#endif + +//extern u4Byte OFDMSwingTable[OFDM_TABLE_SIZE]; +//extern u1Byte CCKSwingTable_Ch1_Ch13[CCK_TABLE_SIZE][8]; +//extern u1Byte CCKSwingTable_Ch14 [CCK_TABLE_SIZE][8]; +#if (RTL8195A_SUPPORT == 1) +extern const u1Byte CCKSwingTable_Ch1_Ch13_8195A[CCK_TABLE_SIZE][9]; +extern const u1Byte CCKSwingTable_Ch14_8195A[CCK_TABLE_SIZE][9]; +extern const u1Byte CCKFCCTable_8195A[16]; +extern const u1Byte CCKCETable_8195A[16]; +extern const u1Byte CCKFCCTable_Ch14_8195A[16]; +#endif + +#if (RTL8711B_SUPPORT == 1) + +extern const u1Byte CCKFCCTable_8711B[16]; +extern const u1Byte CCKCETable_8711B[16]; +extern const u1Byte CCKFCCTable_Ch14_8711B[16]; +extern const u4Byte CCKSwingTable_Ch1_Ch14_8711B[CCK_TABLE_SIZE_8711B]; +#endif + +extern const u4Byte OFDMSwingTable_New[OFDM_TABLE_SIZE]; +extern const u1Byte CCKSwingTable_Ch1_Ch13_New[CCK_TABLE_SIZE][8]; +extern const u1Byte CCKSwingTable_Ch14_New [CCK_TABLE_SIZE][8]; +//extern u4Byte TxScalingTable_Jaguar[TXSCALE_TABLE_SIZE]; + +// <20121018, Kordan> In case fail to read TxPowerTrack.txt, we use the table of 88E as the default table. +//static u1Byte DeltaSwingTableIdx_2GA_P_8188E[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9}; +//static u1Byte DeltaSwingTableIdx_2GA_N_8188E[] = {0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11}; + +#define dm_CheckTXPowerTracking ODM_TXPowerTrackingCheck + +typedef struct _IQK_MATRIX_REGS_SETTING{ + BOOLEAN bIQKDone; +#if defined(CONFIG_RTL8188E) || defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) + s4Byte Value[1][IQK_Matrix_REG_NUM]; +#else + s4Byte Value[3][IQK_Matrix_REG_NUM]; + BOOLEAN bBWIqkResultSaved[3]; +#endif +}IQK_MATRIX_REGS_SETTING,*PIQK_MATRIX_REGS_SETTING; + +typedef struct ODM_RF_Calibration_Structure +{ + //for tx power tracking + + u4Byte RegA24; // for TempCCK + s4Byte RegE94; + s4Byte RegE9C; + s4Byte RegEB4; + s4Byte RegEBC; + + u1Byte TXPowercount; + BOOLEAN bTXPowerTrackingInit; + BOOLEAN bTXPowerTracking; + u1Byte TxPowerTrackControl; //for mp mode, turn off txpwrtracking as default + u1Byte TM_Trigger; + u1Byte InternalPA5G[2]; //pathA / pathB + + u1Byte ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 + u1Byte ThermalValue; + u1Byte ThermalValue_LCK; + u1Byte ThermalValue_IQK; + u1Byte ThermalValue_DPK; + u1Byte ThermalValue_AVG[AVG_THERMAL_NUM]; + u1Byte ThermalValue_AVG_index; + u1Byte ThermalValue_RxGain; + u1Byte ThermalValue_Crystal; + u1Byte ThermalValue_DPKstore; + u1Byte ThermalValue_DPKtrack; + BOOLEAN TxPowerTrackingInProgress; + + BOOLEAN bReloadtxpowerindex; + u1Byte bRfPiEnable; + u4Byte TXPowerTrackingCallbackCnt; //cosa add for debug + + + //------------------------- Tx power Tracking -------------------------// + u1Byte bCCKinCH14; + u1Byte CCK_index[MAX_RF_PATH]; + s1Byte PowerIndexOffset_CCK[MAX_RF_PATH]; + s1Byte DeltaPowerIndex_CCK[MAX_RF_PATH]; + s1Byte DeltaPowerIndexLast_CCK[MAX_RF_PATH]; + u1Byte OFDM_index[MAX_RF_PATH]; + s1Byte PowerIndexOffset_OFDM[MAX_RF_PATH]; + s1Byte DeltaPowerIndex_OFDM[MAX_RF_PATH]; + s1Byte DeltaPowerIndexLast_OFDM[MAX_RF_PATH]; + BOOLEAN bTxPowerChanged; + s1Byte XtalOffset; + s1Byte XtalOffsetLast; + + u1Byte ThermalValue_HP[HP_THERMAL_NUM]; + u1Byte ThermalValue_HP_index; + IQK_MATRIX_REGS_SETTING IQKMatrixRegSetting[IQK_Matrix_Settings_NUM]; + u1Byte Delta_LCK; + s1Byte BBSwingDiff2G, BBSwingDiff5G; // Unit: dB + s1Byte DeltaSwingTableIdx_2GCCKA_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKA_N[DELTA_SWINGIDX_SIZE]; +#if !defined(NOT_SUPPORT_RF_MULTIPATH) + s1Byte DeltaSwingTableIdx_2GCCKB_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKB_N[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKC_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKC_N[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKD_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GCCKD_N[DELTA_SWINGIDX_SIZE]; +#endif + s1Byte DeltaSwingTableIdx_2GA_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GA_N[DELTA_SWINGIDX_SIZE]; +#if !defined(NOT_SUPPORT_RF_MULTIPATH) + s1Byte DeltaSwingTableIdx_2GB_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GB_N[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GC_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GC_N[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GD_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_2GD_N[DELTA_SWINGIDX_SIZE]; +#endif +#if !defined(NOT_SUPPORT_5G) + s1Byte DeltaSwingTableIdx_5GA_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GA_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GB_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GB_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GC_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GC_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GD_P[BAND_NUM][DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableIdx_5GD_N[BAND_NUM][DELTA_SWINGIDX_SIZE]; +#endif +// u1Byte DeltaSwingTableIdx_2GA_P_8188E[DELTA_SWINGIDX_SIZE]; +// u1Byte DeltaSwingTableIdx_2GA_N_8188E[DELTA_SWINGIDX_SIZE]; + + s1Byte DeltaSwingTableXtal_P[DELTA_SWINGIDX_SIZE]; + s1Byte DeltaSwingTableXtal_N[DELTA_SWINGIDX_SIZE]; + + + + //--------------------------------------------------------------------// + + //for IQK + u4Byte RegC04; + u4Byte Reg874; + u4Byte RegC08; + u4Byte RegB68; + u4Byte RegB6C; + u4Byte Reg870; + u4Byte Reg860; + u4Byte Reg864; + + BOOLEAN bIQKInitialized; + BOOLEAN bLCKInProgress; + BOOLEAN bAntennaDetected; + BOOLEAN bNeedIQK; + BOOLEAN bIQKInProgress; + u1Byte Delta_IQK; + u4Byte ADDA_backup[IQK_ADDA_REG_NUM]; + u4Byte IQK_MAC_backup[IQK_MAC_REG_NUM]; + u4Byte IQK_BB_backup_recover[9]; + u4Byte IQK_BB_backup[IQK_BB_REG_NUM]; + u4Byte TxIQC_8723B[2][3][2]; // { {S1: 0xc94, 0xc80, 0xc4c} , {S0: 0xc9c, 0xc88, 0xc4c}} + u4Byte RxIQC_8723B[2][2][2]; // { {S1: 0xc14, 0xca0} , {S0: 0xc14, 0xca0}} + + // IQK time measurement + u8Byte IQK_StartTime; + u8Byte IQK_ProgressingTime; + u4Byte LOK_Result; + + //for APK + u4Byte APKoutput[2][2]; //path A/B; output1_1a/output1_2a + u1Byte bAPKdone; + u1Byte bAPKThermalMeterIgnore; + + // DPK + BOOLEAN bDPKFail; + u1Byte bDPdone; + u1Byte bDPPathAOK; + u1Byte bDPPathBOK; + + u4Byte TxLOK[2]; + u4Byte DpkTxAGC; + s4Byte DpkGain; + u4Byte DpkThermal[4]; +}ODM_RF_CAL_T,*PODM_RF_CAL_T; + + +VOID +ODM_TXPowerTrackingCheck( + IN PVOID pDM_VOID + ); + + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingCheckAP( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingThermalMeterInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingInit( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingCheckMP( + IN PVOID pDM_VOID + ); + + +VOID +odm_TXPowerTrackingCheckCE( + IN PVOID pDM_VOID + ); + +VOID +odm_TXPowerTrackingCheckIOT( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN)) + +VOID +odm_TXPowerTrackingCallbackThermalMeter92C( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingCallbackRXGainThermalMeter92D( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingCallbackThermalMeter92D( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingDirectCall92C( + IN PADAPTER Adapter + ); + +VOID +odm_TXPowerTrackingThermalMeterCheck( + IN PADAPTER Adapter + ); + +#endif + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RXHP.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RXHP.h new file mode 100644 index 0000000..98b3aa6 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RXHP.h @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __PHYDMRXHP_H__ +#define __PHYDMRXHP_H__ + +#define RXHP_VERSION "1.0" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#define AFH_PSD 1 //0:normal PSD scan, 1: only do 20 pts PSD +#define MODE_40M 0 //0:20M, 1:40M +#define PSD_TH2 3 +#define PSD_CHMIN 20 // Minimum channel number for BT AFH +#define SIR_STEP_SIZE 3 +#define Smooth_Size_1 5 +#define Smooth_TH_1 3 +#define Smooth_Size_2 10 +#define Smooth_TH_2 4 +#define Smooth_Size_3 20 +#define Smooth_TH_3 4 +#define Smooth_Step_Size 5 +#define Adaptive_SIR 1 +#define PSD_RESCAN 4 +#define PSD_SCAN_INTERVAL 700 //ms + +typedef struct _RX_High_Power_ +{ + u1Byte RXHP_flag; + u1Byte PSD_func_trigger; + u1Byte PSD_bitmap_RXHP[80]; + u1Byte Pre_IGI; + u1Byte Cur_IGI; + u1Byte Pre_pw_th; + u1Byte Cur_pw_th; + BOOLEAN First_time_enter; + BOOLEAN RXHP_enable; + u1Byte TP_Mode; + RT_TIMER PSDTimer; + #if USE_WORKITEM + RT_WORK_ITEM PSDTimeWorkitem; + #endif +}RXHP_T, *pRXHP_T; + +#define dm_PSDMonitorCallback odm_PSDMonitorCallback +VOID odm_PSDMonitorCallback(PRT_TIMER pTimer); + +VOID +odm_PSDMonitorInit( + IN PVOID pDM_VOID + ); + +void odm_RXHPInit( + IN PVOID pDM_VOID); + +void odm_RXHP( + IN PVOID pDM_VOID); + +VOID +odm_PSD_RXHPCallback( + PRT_TIMER pTimer +); + + VOID +ODM_PSDDbgControl( + IN PADAPTER Adapter, + IN u4Byte mode, + IN u4Byte btRssi + ); + + VOID +odm_PSD_RXHPCallback( + PRT_TIMER pTimer +); + +VOID +odm_PSD_RXHPWorkitemCallback( + IN PVOID pContext + ); + +VOID +odm_PSDMonitorWorkItemCallback( + IN PVOID pContext + ); + + #endif + + #endif + \ No newline at end of file diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RaInfo.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RaInfo.h new file mode 100644 index 0000000..ae5371e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RaInfo.h @@ -0,0 +1,210 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __PHYDMRAINFO_H__ +#define __PHYDMRAINFO_H__ + +#define RAINFO_VERSION "1.0" + +#define H2C_0X42_LENGTH 5 +#define H2C_MAX_LENGTH 7 + +#define RA_FLOOR_UP_GAP 3 +#define RA_FLOOR_TABLE_SIZE 7 + +#define ACTIVE_TP_THRESHOLD 150 +#define RA_RETRY_DESCEND_NUM 2 +#define RA_RETRY_LIMIT_LOW 4 +#define RA_RETRY_LIMIT_HIGH 32 + +#define RAINFO_BE_RX_STATE BIT0 // 1:RX //ULDL +#define RAINFO_STBC_STATE BIT1 +//#define RAINFO_LDPC_STATE BIT2 +#define RAINFO_NOISY_STATE BIT2 // set by Noisy_Detection +#define RAINFO_SHURTCUT_STATE BIT3 +#define RAINFO_SHURTCUT_FLAG BIT4 +#define RAINFO_INIT_RSSI_RATE_STATE BIT5 +#define RAINFO_BF_STATE BIT6 +#define RAINFO_BE_TX_STATE BIT7 // 1:TX + +#define AP_InitRateAdaptiveState ODM_RateAdaptiveStateApInit + +#define DM_RATR_STA_INIT 0 +#define DM_RATR_STA_HIGH 1 +#define DM_RATR_STA_MIDDLE 2 +#define DM_RATR_STA_LOW 3 +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL)) +#define DM_RATR_STA_ULTRA_LOW 4 +#endif + +#if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_IOT)) +typedef struct _Rate_Adaptive_Table_{ + u1Byte firstconnect; + #if(DM_ODM_SUPPORT_TYPE==ODM_WIN) + BOOLEAN PT_collision_pre; + #endif + + //u1Byte link_tx_rate[ODM_ASSOCIATE_ENTRY_NUM]; + u1Byte highest_client_tx_order; + u2Byte highest_client_tx_rate_order; + u1Byte power_tracking_flag; + u1Byte RA_threshold_offset; + u1Byte RA_offset_direction; + +}RA_T, *pRA_T; +#endif + +typedef struct _ODM_RATE_ADAPTIVE +{ + u1Byte Type; // DM_Type_ByFW/DM_Type_ByDriver + u1Byte HighRSSIThresh; // if RSSI > HighRSSIThresh => RATRState is DM_RATR_STA_HIGH + u1Byte LowRSSIThresh; // if RSSI <= LowRSSIThresh => RATRState is DM_RATR_STA_LOW + u1Byte RATRState; // Current RSSI level, DM_RATR_STA_HIGH/DM_RATR_STA_MIDDLE/DM_RATR_STA_LOW + + #if(DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_IOT)) + u1Byte LdpcThres; // if RSSI > LdpcThres => switch from LPDC to BCC + BOOLEAN bLowerRtsRate; + #endif + + #if(DM_ODM_SUPPORT_TYPE & ODM_WIN) + u1Byte RtsThres; + #elif(DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_IOT)) + BOOLEAN bUseLdpc; + #else + u1Byte UltraLowRSSIThresh; + u4Byte LastRATR; // RATR Register Content + #endif + +} ODM_RATE_ADAPTIVE, *PODM_RATE_ADAPTIVE; + +VOID +odm_RSSIMonitorInit( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheck( + IN PVOID pDM_VOID + ); + +#if(DM_ODM_SUPPORT_TYPE==ODM_WIN) +VOID +odm_RSSIDumpToRegister( + IN PVOID pDM_VOID + ); +#endif + +VOID +odm_RSSIMonitorCheckMP( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheckCE( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheckIOT( + IN PVOID pDM_VOID + ); + +VOID +odm_RSSIMonitorCheckAP( + IN PVOID pDM_VOID + ); + + +VOID +odm_RateAdaptiveMaskInit( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMask( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskMP( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskCE( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskIOT( + IN PVOID pDM_VOID + ); + +VOID +odm_RefreshRateAdaptiveMaskAPADSL( + IN PVOID pDM_VOID + ); + +BOOLEAN +ODM_RAStateCheck( + IN PVOID pDM_VOID, + IN s4Byte RSSI, + IN BOOLEAN bForceUpdate, + OUT pu1Byte pRATRState + ); + +VOID +odm_RefreshBasicRateMask( + IN PVOID pDM_VOID + ); + +VOID +phydm_ra_info_init( + IN PVOID pDM_VOID + ); + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +VOID +ODM_DynamicARFBSelect( + IN PVOID pDM_VOID, + IN u1Byte rate, + IN BOOLEAN Collision_State + ); + +VOID +ODM_RateAdaptiveStateApInit( + IN PVOID PADAPTER_VOID, + IN PRT_WLAN_STA pEntry + ); +#endif + +#if (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_IOT)) +u4Byte +ODM_Get_Rate_Bitmap( + IN PVOID pDM_VOID, + IN u4Byte macid, + IN u4Byte ra_mask, + IN u1Byte rssi_level + ); +#endif + +#endif //#ifndef __ODMRAINFO_H__ + + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11AC.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11AC.h new file mode 100644 index 0000000..9b83c55 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11AC.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_REGDEFINE11AC_H__ +#define __ODM_REGDEFINE11AC_H__ + +//2 RF REG LIST + + + +//2 BB REG LIST +//PAGE 8 +#define ODM_REG_CCK_RPT_FORMAT_11AC 0x804 +#define ODM_REG_BB_RX_PATH_11AC 0x808 +#define ODM_REG_BB_TX_PATH_11AC 0x80c +#define ODM_REG_BB_ATC_11AC 0x860 +#define ODM_REG_EDCCA_POWER_CAL 0x8dc +#define ODM_REG_DBG_RPT_11AC 0x8fc +//PAGE 9 +#define ODM_REG_EDCCA_DOWN_OPT 0x900 +#define ODM_REG_ACBB_EDCCA_ENHANCE 0x944 +#define ODM_REG_OFDM_FA_RST_11AC 0x9A4 +#define ODM_REG_NHM_TIMER_11AC 0x990 +#define ODM_REG_NHM_TH9_TH10_11AC 0x994 +#define ODM_REG_NHM_TH3_TO_TH0_11AC 0x998 +#define ODM_REG_NHM_TH7_TO_TH4_11AC 0x99c +#define ODM_REG_NHM_TH8_11AC 0x9a0 +#define ODM_REG_NHM_9E8_11AC 0x9e8 +//PAGE A +#define ODM_REG_CCK_CCA_11AC 0xA0A +#define ODM_REG_CCK_FA_RST_11AC 0xA2C +#define ODM_REG_CCK_FA_11AC 0xA5C +//PAGE B +#define ODM_REG_RST_RPT_11AC 0xB58 +//PAGE C +#define ODM_REG_TRMUX_11AC 0xC08 +#define ODM_REG_IGI_A_11AC 0xC50 +//PAGE E +#define ODM_REG_IGI_B_11AC 0xE50 +#define ODM_REG_TRMUX_11AC_B 0xE08 +//PAGE F +#define ODM_REG_CCK_CCA_CNT_11AC 0xF08 +#define ODM_REG_OFDM_FA_11AC 0xF48 +#define ODM_REG_RPT_11AC 0xfa0 +#define ODM_REG_NHM_CNT_11AC 0xfa8 +//PAGE 18 +#define ODM_REG_IGI_C_11AC 0x1850 +//PAGE 1A +#define ODM_REG_IGI_D_11AC 0x1A50 + +//2 MAC REG LIST +#define ODM_REG_RESP_TX_11AC 0x6D8 + + + +//DIG Related +#define ODM_BIT_IGI_11AC 0xFFFFFFFF +#define ODM_BIT_CCK_RPT_FORMAT_11AC BIT16 +#define ODM_BIT_BB_RX_PATH_11AC 0xF +#define ODM_BIT_BB_TX_PATH_11AC 0xF +#define ODM_BIT_BB_ATC_11AC BIT14 + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11N.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11N.h new file mode 100644 index 0000000..c1d91d7 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_RegDefine11N.h @@ -0,0 +1,186 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_REGDEFINE11N_H__ +#define __ODM_REGDEFINE11N_H__ + + +//2 RF REG LIST +#define ODM_REG_RF_MODE_11N 0x00 +#define ODM_REG_RF_0B_11N 0x0B +#define ODM_REG_CHNBW_11N 0x18 +#define ODM_REG_T_METER_11N 0x24 +#define ODM_REG_RF_25_11N 0x25 +#define ODM_REG_RF_26_11N 0x26 +#define ODM_REG_RF_27_11N 0x27 +#define ODM_REG_RF_2B_11N 0x2B +#define ODM_REG_RF_2C_11N 0x2C +#define ODM_REG_RXRF_A3_11N 0x3C +#define ODM_REG_T_METER_92D_11N 0x42 +#define ODM_REG_T_METER_88E_11N 0x42 + + + +//2 BB REG LIST +//PAGE 8 +#define ODM_REG_BB_CTRL_11N 0x800 +#define ODM_REG_RF_PIN_11N 0x804 +#define ODM_REG_PSD_CTRL_11N 0x808 +#define ODM_REG_TX_ANT_CTRL_11N 0x80C +#define ODM_REG_BB_PWR_SAV5_11N 0x818 +#define ODM_REG_CCK_RPT_FORMAT_11N 0x824 +#define ODM_REG_CCK_RPT_FORMAT_11N_B 0x82C +#define ODM_REG_RX_DEFUALT_A_11N 0x858 +#define ODM_REG_RX_DEFUALT_B_11N 0x85A +#define ODM_REG_BB_PWR_SAV3_11N 0x85C +#define ODM_REG_ANTSEL_CTRL_11N 0x860 +#define ODM_REG_RX_ANT_CTRL_11N 0x864 +#define ODM_REG_PIN_CTRL_11N 0x870 +#define ODM_REG_BB_PWR_SAV1_11N 0x874 +#define ODM_REG_ANTSEL_PATH_11N 0x878 +#define ODM_REG_BB_3WIRE_11N 0x88C +#define ODM_REG_SC_CNT_11N 0x8C4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_PSD_DATA_11N 0x8B4 +#define ODM_REG_NHM_TIMER_11N 0x894 +#define ODM_REG_NHM_TH9_TH10_11N 0x890 +#define ODM_REG_NHM_TH3_TO_TH0_11N 0x898 +#define ODM_REG_NHM_TH7_TO_TH4_11N 0x89c +#define ODM_REG_NHM_CNT_11N 0x8d8 +//PAGE 9 +#define ODM_REG_DBG_RPT_11N 0x908 +#define ODM_REG_BB_TX_PATH_11N 0x90c +#define ODM_REG_ANT_MAPPING1_11N 0x914 +#define ODM_REG_ANT_MAPPING2_11N 0x918 +#define ODM_REG_EDCCA_DOWN_OPT_11N 0x948 + +//PAGE A +#define ODM_REG_CCK_ANTDIV_PARA1_11N 0xA00 +#define ODM_REG_CCK_CCA_11N 0xA0A +#define ODM_REG_CCK_ANTDIV_PARA2_11N 0xA0C +#define ODM_REG_CCK_ANTDIV_PARA3_11N 0xA10 +#define ODM_REG_CCK_ANTDIV_PARA4_11N 0xA14 +#define ODM_REG_CCK_FILTER_PARA1_11N 0xA22 +#define ODM_REG_CCK_FILTER_PARA2_11N 0xA23 +#define ODM_REG_CCK_FILTER_PARA3_11N 0xA24 +#define ODM_REG_CCK_FILTER_PARA4_11N 0xA25 +#define ODM_REG_CCK_FILTER_PARA5_11N 0xA26 +#define ODM_REG_CCK_FILTER_PARA6_11N 0xA27 +#define ODM_REG_CCK_FILTER_PARA7_11N 0xA28 +#define ODM_REG_CCK_FILTER_PARA8_11N 0xA29 +#define ODM_REG_CCK_FA_RST_11N 0xA2C +#define ODM_REG_CCK_FA_MSB_11N 0xA58 +#define ODM_REG_CCK_FA_LSB_11N 0xA5C +#define ODM_REG_CCK_CCA_CNT_11N 0xA60 +#define ODM_REG_BB_PWR_SAV4_11N 0xA74 +//PAGE B +#define ODM_REG_LNA_SWITCH_11N 0xB2C +#define ODM_REG_PATH_SWITCH_11N 0xB30 +#define ODM_REG_RSSI_CTRL_11N 0xB38 +#define ODM_REG_CONFIG_ANTA_11N 0xB68 +#define ODM_REG_RSSI_BT_11N 0xB9C +//PAGE C +#define ODM_REG_OFDM_FA_HOLDC_11N 0xC00 +#define ODM_REG_BB_RX_PATH_11N 0xC04 +#define ODM_REG_TRMUX_11N 0xC08 +#define ODM_REG_OFDM_FA_RSTC_11N 0xC0C +#define ODM_REG_RXIQI_MATRIX_11N 0xC14 +#define ODM_REG_TXIQK_MATRIX_LSB1_11N 0xC4C +#define ODM_REG_IGI_A_11N 0xC50 +#define ODM_REG_ANTDIV_PARA2_11N 0xC54 +#define ODM_REG_IGI_B_11N 0xC58 +#define ODM_REG_ANTDIV_PARA3_11N 0xC5C +#define ODM_REG_L1SBD_PD_CH_11N 0XC6C +#define ODM_REG_BB_PWR_SAV2_11N 0xC70 +#define ODM_REG_RX_OFF_11N 0xC7C +#define ODM_REG_TXIQK_MATRIXA_11N 0xC80 +#define ODM_REG_TXIQK_MATRIXB_11N 0xC88 +#define ODM_REG_TXIQK_MATRIXA_LSB2_11N 0xC94 +#define ODM_REG_TXIQK_MATRIXB_LSB2_11N 0xC9C +#define ODM_REG_RXIQK_MATRIX_LSB_11N 0xCA0 +#define ODM_REG_ANTDIV_PARA1_11N 0xCA4 +#define ODM_REG_OFDM_FA_TYPE1_11N 0xCF0 +//PAGE D +#define ODM_REG_OFDM_FA_RSTD_11N 0xD00 +#define ODM_REG_BB_ATC_11N 0xD2C +#define ODM_REG_OFDM_FA_TYPE2_11N 0xDA0 +#define ODM_REG_OFDM_FA_TYPE3_11N 0xDA4 +#define ODM_REG_OFDM_FA_TYPE4_11N 0xDA8 +#define ODM_REG_RPT_11N 0xDF4 +//PAGE E +#define ODM_REG_TXAGC_A_6_18_11N 0xE00 +#define ODM_REG_TXAGC_A_24_54_11N 0xE04 +#define ODM_REG_TXAGC_A_1_MCS32_11N 0xE08 +#define ODM_REG_TXAGC_A_MCS0_3_11N 0xE10 +#define ODM_REG_TXAGC_A_MCS4_7_11N 0xE14 +#define ODM_REG_TXAGC_A_MCS8_11_11N 0xE18 +#define ODM_REG_TXAGC_A_MCS12_15_11N 0xE1C +#define DOM_REG_EDCCA_DCNF_11N 0xE24 +#define ODM_REG_FPGA0_IQK_11N 0xE28 +#define ODM_REG_TXIQK_TONE_A_11N 0xE30 +#define ODM_REG_RXIQK_TONE_A_11N 0xE34 +#define ODM_REG_TXIQK_PI_A_11N 0xE38 +#define ODM_REG_RXIQK_PI_A_11N 0xE3C +#define ODM_REG_TXIQK_11N 0xE40 +#define ODM_REG_RXIQK_11N 0xE44 +#define ODM_REG_IQK_AGC_PTS_11N 0xE48 +#define ODM_REG_IQK_AGC_RSP_11N 0xE4C +#define ODM_REG_BLUETOOTH_11N 0xE6C +#define ODM_REG_RX_WAIT_CCA_11N 0xE70 +#define ODM_REG_TX_CCK_RFON_11N 0xE74 +#define ODM_REG_TX_CCK_BBON_11N 0xE78 +#define ODM_REG_OFDM_RFON_11N 0xE7C +#define ODM_REG_OFDM_BBON_11N 0xE80 +#define ODM_REG_TX2RX_11N 0xE84 +#define ODM_REG_TX2TX_11N 0xE88 +#define ODM_REG_RX_CCK_11N 0xE8C +#define ODM_REG_RX_OFDM_11N 0xED0 +#define ODM_REG_RX_WAIT_RIFS_11N 0xED4 +#define ODM_REG_RX2RX_11N 0xED8 +#define ODM_REG_STANDBY_11N 0xEDC +#define ODM_REG_SLEEP_11N 0xEE0 +#define ODM_REG_PMPD_ANAEN_11N 0xEEC +#define ODM_REG_IGI_C_11N 0xF84 +#define ODM_REG_IGI_D_11N 0xF88 + +//2 MAC REG LIST +#define ODM_REG_BB_RST_11N 0x02 +#define ODM_REG_ANTSEL_PIN_11N 0x4C +#define ODM_REG_EARLY_MODE_11N 0x4D0 +#define ODM_REG_RSSI_MONITOR_11N 0x4FE +#define ODM_REG_EDCA_VO_11N 0x500 +#define ODM_REG_EDCA_VI_11N 0x504 +#define ODM_REG_EDCA_BE_11N 0x508 +#define ODM_REG_EDCA_BK_11N 0x50C +#define ODM_REG_TXPAUSE_11N 0x522 +#define ODM_REG_RESP_TX_11N 0x6D8 +#define ODM_REG_ANT_TRAIN_PARA1_11N 0x7b0 +#define ODM_REG_ANT_TRAIN_PARA2_11N 0x7b4 + + +//DIG Related +#define ODM_BIT_IGI_11N 0x0000007F +#define ODM_BIT_CCK_RPT_FORMAT_11N BIT9 +#define ODM_BIT_BB_RX_PATH_11N 0xF +#define ODM_BIT_BB_TX_PATH_11N 0xF +#define ODM_BIT_BB_ATC_11N BIT11 + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_debug.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_debug.h new file mode 100644 index 0000000..366e306 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_debug.h @@ -0,0 +1,900 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __ODM_DBG_H__ +#define __ODM_DBG_H__ + + +//----------------------------------------------------------------------------- +// Define the debug levels +// +// 1. DBG_TRACE and DBG_LOUD are used for normal cases. +// So that, they can help SW engineer to develope or trace states changed +// and also help HW enginner to trace every operation to and from HW, +// e.g IO, Tx, Rx. +// +// 2. DBG_WARNNING and DBG_SERIOUS are used for unusual or error cases, +// which help us to debug SW or HW. +// +//----------------------------------------------------------------------------- +// +// Never used in a call to ODM_RT_TRACE()! +// +#define ODM_DBG_OFF 1 + +// +// Fatal bug. +// For example, Tx/Rx/IO locked up, OS hangs, memory access violation, +// resource allocation failed, unexpected HW behavior, HW BUG and so on. +// +#define ODM_DBG_SERIOUS 2 + +// +// Abnormal, rare, or unexpeted cases. +// For example, IRP/Packet/OID canceled, device suprisely unremoved and so on. +// +#define ODM_DBG_WARNING 3 + +// +// Normal case with useful information about current SW or HW state. +// For example, Tx/Rx descriptor to fill, Tx/Rx descriptor completed status, +// SW protocol state change, dynamic mechanism state change and so on. +// +#define ODM_DBG_LOUD 4 + +// +// Normal case with detail execution flow or information. +// +#define ODM_DBG_TRACE 5 + +//----------------------------------------------------------------------------- +// Define the tracing components +// +//----------------------------------------------------------------------------- +//BB Functions +#define ODM_COMP_DIG BIT0 +#define ODM_COMP_RA_MASK BIT1 +#define ODM_COMP_DYNAMIC_TXPWR BIT2 +#define ODM_COMP_FA_CNT BIT3 +#define ODM_COMP_RSSI_MONITOR BIT4 +#define ODM_COMP_CCK_PD BIT5 +#define ODM_COMP_ANT_DIV BIT6 +#define ODM_COMP_PWR_SAVE BIT7 +#define ODM_COMP_PWR_TRAIN BIT8 +#define ODM_COMP_RATE_ADAPTIVE BIT9 +#define ODM_COMP_PATH_DIV BIT10 +#define ODM_COMP_PSD BIT11 +#define ODM_COMP_DYNAMIC_PRICCA BIT12 +#define ODM_COMP_RXHP BIT13 +#define ODM_COMP_MP BIT14 +#define ODM_COMP_CFO_TRACKING BIT15 +#define ODM_COMP_ACS BIT16 +#define PHYDM_COMP_ADAPTIVITY BIT17 + +//MAC Functions +#define ODM_COMP_EDCA_TURBO BIT18 +#define ODM_COMP_EARLY_MODE BIT19 +//RF Functions +#define ODM_COMP_TX_PWR_TRACK BIT24 +#define ODM_COMP_RX_GAIN_TRACK BIT25 +#define ODM_COMP_CALIBRATION BIT26 +//Common Functions +#define ODM_COMP_INIT BIT29 +#define ODM_COMP_COMMON BIT30 +#define ODM_COMP_FIX BIT31 + +/*------------------------Export Marco Definition---------------------------*/ +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #define RT_PRINTK DbgPrint +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #define DbgPrint printk + #define RT_PRINTK(fmt, args...) DbgPrint( "%s(): " fmt, __FUNCTION__, ## args); + #define RT_DISP(dbgtype, dbgflag, printstr) +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) + #define DbgPrint printf + #define RT_PRINTK(fmt, args...) DbgPrint( "%s(): " fmt, __FUNCTION__, ## args); + #define RT_DISP(dbgtype, dbgflag, printstr) +#else + #define DbgPrint panic_printk + #define RT_PRINTK(fmt, args...) DbgPrint( "%s(): " fmt, __FUNCTION__, ## args); +#endif + +#ifndef ASSERT + #define ASSERT(expr) +#endif + +#if DBG +#define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) \ + if(((comp) & ROMInfo.DebugComponents) && (level <= ROMInfo.DebugLevel || level == ODM_DBG_SERIOUS)) \ + { \ + RT_PRINTK fmt; \ + } + +#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) \ + if(((comp) & ROMInfo.DebugComponents) && (level <= ROMInfo.DebugLevel)) \ + { \ + RT_PRINTK fmt; \ + } + +#define ODM_RT_ASSERT(pDM_Odm, expr, fmt) \ + if(!(expr)) { \ + DbgPrint( "Assertion failed! %s at ......\n", #expr); \ + DbgPrint( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ + RT_PRINTK fmt; \ + ASSERT(FALSE); \ + } +#define ODM_dbg_enter() { DbgPrint("==> %s\n", __FUNCTION__); } +#define ODM_dbg_exit() { DbgPrint("<== %s\n", __FUNCTION__); } +#define ODM_dbg_trace(str) { DbgPrint("%s:%s\n", __FUNCTION__, str); } + +#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) \ + if(((comp) & ROMInfo.DebugComponents) && (level <= ROMInfo.DebugLevel)) \ + { \ + int __i; \ + pu1Byte __ptr = (pu1Byte)ptr; \ + DbgPrint("[ODM] "); \ + DbgPrint(title_str); \ + DbgPrint(" "); \ + for( __i=0; __i<6; __i++ ) \ + DbgPrint("%02X%s", __ptr[__i], (__i==5)?"":"-"); \ + DbgPrint("\n"); \ + } +#else +#define ODM_RT_TRACE(pDM_Odm, comp, level, fmt) +#define ODM_RT_TRACE_F(pDM_Odm, comp, level, fmt) +#define ODM_RT_ASSERT(pDM_Odm, expr, fmt) +#define ODM_dbg_enter() +#define ODM_dbg_exit() +#define ODM_dbg_trace(str) +#define ODM_PRINT_ADDR(pDM_Odm, comp, level, title_str, ptr) +#endif + + +VOID +ODM_InitDebugSetting( + IN PDM_ODM_T pDM_Odm + ); + + + +#if 0 +#if DBG +#define DbgPrint printk + +#define PRINT_DATA(_TitleString, _HexData, _HexDataLen) \ + { \ + char *szTitle = _TitleString; \ + pu1Byte pbtHexData = _HexData; \ + u4Byte u4bHexDataLen = _HexDataLen; \ + u4Byte __i; \ + DbgPrint("%s", szTitle); \ + for (__i=0;__i=' ' &&_ch<='~' ) // I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22. + +#define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) \ + if(((_Comp) & ODM_GlobalDebugComponents) && (_Level <= ODM_GlobalDebugLevel)) \ + { \ + int __i; \ + u1Byte buffer[MAX_STR_LEN]; \ + int length = (_Len\n", _Len, buffer); \ + } + +#else // of #if DBG +#define DbgPrint(...) +#define PRINT_DATA(_TitleString, _HexData, _HexDataLen) +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) +#define RT_PRINT_ADDR(_Comp, _Level, _TitleString, _Ptr) +#define RT_PRINT_ADDRS(_Comp, _Level, _TitleString, _Ptr, _AddNum) +#define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) +#endif // of #if DBG + +#endif + + +#if 0 +/* Define debug print header for every service module.*/ +typedef struct tag_ODM_DBGP_Service_Module_Header_Name_Structure +{ + const char *pMANS; + const char *pRTOS; + const char *pALM; + const char *pPEM; + const char *pCMPK; + const char *pRAPD; + const char *pTXPB; + const char *pQUMG; +}ODM_DBGP_HEAD_T; + + +/* Define different debug flag for dedicated service modules in debug flag array. */ +// Each module has independt 32 bit debug flag you cnn define the flag as yout require. +typedef enum tag_ODM_DBGP_Flag_Type_Definition +{ + ODM_FTX = 0, + ODM_FRX , + ODM_FPHY , + ODM_FPWR , + ODM_FDM , + ODM_FC2H , + ODM_FBT , + ODM_DBGP_TYPE_MAX +}ODM_DBGP_FLAG_E; + + +// Define TX relative debug bit --> FTX +#define ODM_TX_DESC BIT0 +#define ODM_TX_DESC_TID BIT1 +#define ODM_TX_PATH BIT2 + +// Define RX relative debug bit --> FRX +#define ODM_RX_DATA BIT0 +#define ODM_RX_PHY_STS BIT1 +#define ODM_RX_PHY_SS BIT2 +#define ODM_RX_PHY_SQ BIT3 +#define ODM_RX_PHY_ASTS BIT4 +#define ODM_RX_ERR_LEN BIT5 +#define ODM_RX_DEFRAG BIT6 +#define ODM_RX_ERR_RATE BIT7 +#define ODM_RX_PATH BIT8 +#define ODM_RX_BEACON BIT9 + +// Define PHY-BB/RF/MAC check module bit --> FPHY +#define ODM_PHY_BBR BIT0 +#define ODM_PHY_BBW BIT1 +#define ODM_PHY_RFR BIT2 +#define ODM_PHY_RFW BIT3 +#define ODM_PHY_MACR BIT4 +#define ODM_PHY_MACW BIT5 +#define ODM_PHY_ALLR BIT6 +#define ODM_PHY_ALLW BIT7 +#define ODM_PHY_TXPWR BIT8 +#define ODM_PHY_PWRDIFF BIT9 +#define ODM_PHY_SICR BIT10 +#define ODM_PHY_SICW BIT11 + + + + +extern u4Byte ODM_GlobalDebugLevel; + + +#if DBG +extern u8Byte ODM_GlobalDebugComponents; +#endif +#endif +#if 0 + +//----------------------------------------------------------------------------- +// Define the debug levels +// +// 1. DBG_TRACE and DBG_LOUD are used for normal cases. +// So that, they can help SW engineer to develope or trace states changed +// and also help HW enginner to trace every operation to and from HW, +// e.g IO, Tx, Rx. +// +// 2. DBG_WARNNING and DBG_SERIOUS are used for unusual or error cases, +// which help us to debug SW or HW. +// +//----------------------------------------------------------------------------- +// +// Never used in a call to ODM_RT_TRACE(pDM_Odm,)! +// +#define DBG_OFF 0 + +// +// Deprecated! Don't use it! +// TODO: fix related debug message! +// +//#define DBG_SEC 1 + +// +// Fatal bug. +// For example, Tx/Rx/IO locked up, OS hangs, memory access violation, +// resource allocation failed, unexpected HW behavior, HW BUG and so on. +// +#define DBG_SERIOUS 2 + +// +// Abnormal, rare, or unexpeted cases. +// For example, IRP/Packet/OID canceled, device suprisely unremoved and so on. +// +#define DBG_WARNING 3 + +// +// Normal case with useful information about current SW or HW state. +// For example, Tx/Rx descriptor to fill, Tx/Rx descriptor completed status, +// SW protocol state change, dynamic mechanism state change and so on. +// +#define DBG_LOUD 4 + +// +// Normal case with detail execution flow or information. +// +#define DBG_TRACE 5 + + + +//----------------------------------------------------------------------------- +// Define the tracing components +// +//----------------------------------------------------------------------------- +#define COMP_TRACE BIT0 // For function call tracing. +#define COMP_DBG BIT1 // Only for temporary debug message. +#define COMP_INIT BIT2 // during driver initialization / halt / reset. +#define COMP_OID_QUERY BIT3 // Query OID. +#define COMP_OID_SET BIT4 // Set OID. +#define COMP_RECV BIT5 // Reveive part data path. +#define COMP_SEND BIT6 // Send part path. +#define COMP_IO BIT7 // I/O Related. Added by Annie, 2006-03-02. +#define COMP_POWER BIT8 // 802.11 Power Save mode or System/Device Power state related. +#define COMP_MLME BIT9 // 802.11 link related: join/start BSS, leave BSS. +#define COMP_SCAN BIT10 // For site survey. +#define COMP_SYSTEM BIT11 // For general platform function. +#define COMP_SEC BIT12 // For Security. +#define COMP_AP BIT13 // For AP mode related. +#define COMP_TURBO BIT14 // For Turbo Mode related. By Annie, 2005-10-21. +#define COMP_QOS BIT15 // For QoS. +#define COMP_AUTHENTICATOR BIT16 // For AP mode Authenticator. Added by Annie, 2006-01-30. +#define COMP_BEACON BIT17 // For Beacon related, by rcnjko. +#define COMP_ANTENNA BIT18 // For Antenna diversity related, by rcnjko. +#define COMP_RATE BIT19 // For Rate Adaptive mechanism, 2006.07.02, by rcnjko. #define COMP_EVENTS 0x00000080 // Event handling +#define COMP_EVENTS BIT20 // Event handling +#define COMP_FPGA BIT21 // For FPGA verfication +#define COMP_RM BIT22 // For Radio Measurement. +#define COMP_MP BIT23 // For mass production test, by shien chang, 2006.07.13 +#define COMP_RXDESC BIT24 // Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15. +#define COMP_CKIP BIT25 // For CCX 1 S13: CKIP. Added by Annie, 2006-08-14. +#define COMP_DIG BIT26 // For DIG, 2006.09.25, by rcnjko. +#define COMP_TXAGC BIT27 // For Tx power, 060928, by rcnjko. +#define COMP_HIPWR BIT28 // For High Power Mechanism, 060928, by rcnjko. +#define COMP_HALDM BIT29 // For HW Dynamic Mechanism, 061010, by rcnjko. +#define COMP_RSNA BIT30 // For RSNA IBSS , 061201, by CCW. +#define COMP_INDIC BIT31 // For link indication +#define COMP_LED BIT32 // For LED. +#define COMP_RF BIT33 // For RF. +//1!!!!!!!!!!!!!!!!!!!!!!!!!!! +//1//1Attention Please!!!<11n or 8190 specific code should be put below this line> +//1!!!!!!!!!!!!!!!!!!!!!!!!!!! + +#define COMP_HT BIT34 // For 802.11n HT related information. by Emily 2006-8-11 +#define COMP_POWER_TRACKING BIT35 //FOR 8190 TX POWER TRACKING +#define COMP_RX_REORDER BIT36 // 8190 Rx Reorder +#define COMP_AMSDU BIT37 // For A-MSDU Debugging +#define COMP_WPS BIT38 //WPS Debug Message +#define COMP_RATR BIT39 +#define COMP_RESET BIT40 +// For debug command to print on dbgview!! +#define COMP_CMD BIT41 +#define COMP_EFUSE BIT42 +#define COMP_MESH_INTERWORKING BIT43 +#define COMP_CCX BIT44 //CCX Debug Flag +#define COMP_IOCTL BIT45 // IO Control +#define COMP_GP BIT46 // For generic parser. +#define COMP_TXAGG BIT47 +#define COMP_HVL BIT48 // For Ndis 6.2 Context Swirch and Hardware Virtualiztion Layer +#define COMP_TEST BIT49 +#define COMP_BB_POWERSAVING BIT50 +#define COMP_SWAS BIT51 // For SW Antenna Switch +#define COMP_P2P BIT52 +#define COMP_MUX BIT53 +#define COMP_FUNC BIT54 +#define COMP_TDLS BIT55 +#define COMP_OMNIPEEK BIT56 +#define COMP_DUALMACSWITCH BIT60 // 2010/12/27 Add for Dual mac mode debug +#define COMP_EASY_CONCURRENT BIT61 // 2010/12/27 Add for easy cncurrent mode debug +#define COMP_PSD BIT63 //2011/3/9 Add for WLAN PSD for BT AFH + +#define COMP_DFS BIT62 + +#define COMP_ALL UINT64_C(0xFFFFFFFFFFFFFFFF) // All components +// For debug print flag to use +/*------------------------------Define structure----------------------------*/ +/* 2007/07/13 MH *//*------For DeBuG Print modeue------*/ + +/* Defnie structure to store different debug flag variable. Every debug flag + is a UINT32 integer and you can assign 32 different events. */ +typedef struct tag_DBGP_Debug_Flag_Structure +{ + u4Byte Mans; /* Main Scheduler module. */ + u4Byte Rtos; /* RTOS module. */ + u4Byte Alarm; /* Alarm module. */ + u4Byte Pm; /* Performance monitor module. */ +}DBGP_FLAG_T; + +/* Define debug print header for every service module.*/ +typedef struct tag_DBGP_Service_Module_Header_Name_Structure +{ + const char *pMANS; + const char *pRTOS; + const char *pALM; + const char *pPEM; + const char *pCMPK; + const char *pRAPD; + const char *pTXPB; + const char *pQUMG; +}DBGP_HEAD_T; + + +/* Define different debug flag for dedicated service modules in debug flag array. */ +// Each module has independt 32 bit debug flag you cnn define the flag as yout require. +typedef enum tag_DBGP_Flag_Type_Definition +{ + FQoS = 0, + FTX = 1, + FRX = 2, + FSEC = 3, + FMGNT = 4, + FMLME = 5, + FRESOURCE = 6, + FBEACON = 7, + FISR = 8, + FPHY = 9, + FMP = 10, + FEEPROM = 11, + FPWR = 12, + FDM = 13, + FDBG_CTRL = 14, + FC2H = 15, + FBT = 16, + FINIT = 17, + FIOCTL = 18, + FSHORT_CUT = 19, + DBGP_TYPE_MAX +}DBGP_FLAG_E; + + +// Define Qos Relative debug flag bit --> FQoS +#define QoS_INIT BIT0 +#define QoS_VISTA BIT1 + +// Define TX relative debug bit --> FTX +#define TX_DESC BIT0 +#define TX_DESC_TID BIT1 +#define TX_PATH BIT2 + +// Define RX relative debug bit --> FRX +#define RX_DATA BIT0 +#define RX_PHY_STS BIT1 +#define RX_PHY_SS BIT2 +#define RX_PHY_SQ BIT3 +#define RX_PHY_ASTS BIT4 +#define RX_ERR_LEN BIT5 +#define RX_DEFRAG BIT6 +#define RX_ERR_RATE BIT7 +#define RX_PATH BIT8 +#define RX_BEACON BIT9 + +// Define Security relative debug bit --> FSEC + +// Define MGNT relative debug bit --> FMGNT + +// Define MLME relative debug bit --> FMLME +#define MEDIA_STS BIT0 +#define LINK_STS BIT1 + +// Define OS resource check module bit --> FRESOURCE +#define OS_CHK BIT0 + +// Define beacon content check module bit --> FBEACON +#define BCN_SHOW BIT0 +#define BCN_PEER BIT1 + +// Define ISR/IMR check module bit --> FISR +#define ISR_CHK BIT0 + +// Define PHY-BB/RF/MAC check module bit --> FPHY +#define PHY_BBR BIT0 +#define PHY_BBW BIT1 +#define PHY_RFR BIT2 +#define PHY_RFW BIT3 +#define PHY_MACR BIT4 +#define PHY_MACW BIT5 +#define PHY_ALLR BIT6 +#define PHY_ALLW BIT7 +#define PHY_TXPWR BIT8 +#define PHY_PWRDIFF BIT9 +#define PHY_SICR BIT10 +#define PHY_SICW BIT11 + +// Define MPT driver check module bit --> FMP +#define MP_RX BIT0 +#define MP_SWICH_CH BIT1 + +// Define EEPROM and EFUSE check module bit --> FEEPROM +#define EEPROM_W BIT0 +#define EFUSE_PG BIT1 +#define EFUSE_READ_ALL BIT2 +#define EFUSE_ANALYSIS BIT3 +#define EFUSE_PG_DETAIL BIT4 + +// Define power save check module bit --> FPWR +#define LPS BIT0 +#define IPS BIT1 +#define PWRSW BIT2 +#define PWRHW BIT3 +#define PWRHAL BIT4 + +// Define Dynamic Mechanism check module bit --> FDM +#define WA_IOT BIT0 +#define DM_PWDB BIT1 +#define DM_Monitor BIT2 +#define DM_DIG BIT3 +#define DM_EDCA_Turbo BIT4 +#define DM_BT30 BIT5 + +// Define Dbg Control module bit --> FDBG_CTRL +#define DBG_CTRL_TRACE BIT0 +#define DBG_CTRL_INBAND_NOISE BIT1 + +// Define FW C2H Cmd check module bit --> FC2H +#define C2H_Summary BIT0 +#define C2H_PacketData BIT1 +#define C2H_ContentData BIT2 +// Define BT Cmd check module bit --> FBT +#define BT_TRACE BIT0 +#define BT_RFPoll BIT1 + +// Define init check for module bit --> FINIT +#define INIT_EEPROM BIT0 +#define INIT_TxPower BIT1 +#define INIT_IQK BIT2 +#define INIT_RF BIT3 + +// Define IOCTL Cmd check module bit --> FIOCTL +// section 1 : IRP related +#define IOCTL_IRP BIT0 +#define IOCTL_IRP_DETAIL BIT1 +#define IOCTL_IRP_STATISTICS BIT2 +#define IOCTL_IRP_HANDLE BIT3 +// section 2 : HCI command/event +#define IOCTL_BT_HCICMD BIT8 +#define IOCTL_BT_HCICMD_DETAIL BIT9 +#define IOCTL_BT_HCICMD_EXT BIT10 +#define IOCTL_BT_EVENT BIT11 +#define IOCTL_BT_EVENT_DETAIL BIT12 +#define IOCTL_BT_EVENT_PERIODICAL BIT13 +// section 3 : BT tx/rx data and throughput +#define IOCTL_BT_TX_ACLDATA BIT16 +#define IOCTL_BT_TX_ACLDATA_DETAIL BIT17 +#define IOCTL_BT_RX_ACLDATA BIT18 +#define IOCTL_BT_RX_ACLDATA_DETAIL BIT19 +#define IOCTL_BT_TP BIT20 +// section 4 : BT connection state machine. +#define IOCTL_STATE BIT21 +#define IOCTL_BT_LOGO BIT22 +// section 5 : BT function trace +#define IOCTL_CALLBACK_FUN BIT24 +#define IOCTL_PARSE_BT_PKT BIT25 +#define IOCTL_BT_TX_PKT BIT26 +#define IOCTL_BT_FLAG_MON BIT27 + +// +// Define init check for module bit --> FSHORT_CUT +// 2011/07/20 MH Add for short but definition. +// +#define SHCUT_TX BIT0 +#define SHCUT_RX BIT1 + + +/* 2007/07/13 MH *//*------For DeBuG Print modeue------*/ +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +#define RT_PRINTK(fmt, args...) printk( "%s(): " fmt, __FUNCTION__, ## args); + +#if DBG +#define ODM_RT_TRACE(pDM_Odm,comp, level, fmt) \ + if(((comp) & GlobalDebugComponents) && (level <= GlobalDebugLevel)) \ + { \ + RT_PRINTK fmt; \ + } + +#define RT_TRACE_F(comp, level, fmt) \ + if(((comp) & GlobalDebugComponents) && (level <= GlobalDebugLevel)) \ + { \ + RT_PRINTK fmt; \ + } + +#define RT_ASSERT(expr,fmt) \ + if(!(expr)) { \ + printk( "Assertion failed! %s at ......\n", #expr); \ + printk( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ + } +#define dbg_enter() { printk("==> %s\n", __FUNCTION__); } +#define dbg_exit() { printk("<== %s\n", __FUNCTION__); } +#define dbg_trace(str) { printk("%s:%s\n", __FUNCTION__, str); } +#else +#define ODM_RT_TRACE(pDM_Odm,comp, level, fmt) +#define RT_TRACE_F(comp, level, fmt) +#define RT_ASSERT(expr, fmt) +#define dbg_enter() +#define dbg_exit() +#define dbg_trace(str) +#endif + +#if DBG +#define DbgPrint printk + +#define PRINT_DATA(_TitleString, _HexData, _HexDataLen) \ + { \ + char *szTitle = _TitleString; \ + pu1Byte pbtHexData = _HexData; \ + u4Byte u4bHexDataLen = _HexDataLen; \ + u4Byte __i; \ + DbgPrint("%s", szTitle); \ + for (__i=0;__i=' ' &&_ch<='~' ) // I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22. + +#define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) \ + if(((_Comp) & GlobalDebugComponents) && (_Level <= GlobalDebugLevel)) \ + { \ + int __i; \ + u1Byte buffer[MAX_STR_LEN]; \ + int length = (_Len\n", _Len, buffer); \ + } + +#else // of #if DBG +#define DbgPrint(...) +#define PRINT_DATA(_TitleString, _HexData, _HexDataLen) +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) +#define RT_PRINT_ADDR(_Comp, _Level, _TitleString, _Ptr) +#define RT_PRINT_ADDRS(_Comp, _Level, _TitleString, _Ptr, _AddNum) +#define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len) +#endif // of #if DBG + + + +#endif // #if (DM_ODM_SUPPORT_TYPE != ODM_WIN) + +#define DEBUG_PRINT 1 + +// Please add new OS's print API by yourself + +//#if (RT_PLATFORM==PLATFORM_WINDOWS) +#if (DEBUG_PRINT == 1) && DBG +#define RT_DISP(dbgtype, dbgflag, printstr)\ +{\ + if (DBGP_Type[dbgtype] & dbgflag)\ + {\ + DbgPrint printstr;\ + }\ +} + +#define RT_DISP_ADDR(dbgtype, dbgflag, printstr, _Ptr)\ +{\ + if (DBGP_Type[dbgtype] & dbgflag)\ + {\ + int __i; \ + pu1Byte ptr = (pu1Byte)_Ptr; \ + DbgPrint printstr; \ + DbgPrint(" "); \ + for( __i=0; __i<6; __i++ ) \ + DbgPrint("%02X%s", ptr[__i], (__i==5)?"":"-"); \ + DbgPrint("\n"); \ + }\ +} + +#define RT_DISP_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\ +{\ + if (DBGP_Type[dbgtype] & dbgflag)\ + {\ + int __i; \ + pu1Byte ptr = (pu1Byte)_HexData; \ + DbgPrint(_TitleString); \ + for( __i=0; __i<(int)_HexDataLen; __i++ ) \ + { \ + DbgPrint("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" ");\ + if (((__i + 1) % 16) == 0) DbgPrint("\n");\ + } \ + DbgPrint("\n"); \ + }\ +} + +#define FunctionIn(_comp) ODM_RT_TRACE(pDM_Odm,(_comp), DBG_LOUD, ("==========> %s\n", __FUNCTION__)) +#define FunctionOut(_comp) ODM_RT_TRACE(pDM_Odm,(_comp), DBG_LOUD, ("<========== %s\n", __FUNCTION__)) + + +#else + +#define RT_DISP(dbgtype, dbgflag, printstr) +#define RT_DISP_ADDR(dbgtype, dbgflag, printstr, _Ptr) +#define RT_DISP_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen) + +#define FunctionIn(_comp) +#define FunctionOut(_comp) +#endif +/*------------------------Export Marco Definition---------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +extern u4Byte DBGP_Type[DBGP_TYPE_MAX]; +extern DBGP_HEAD_T DBGP_Head; + +/*------------------------Export global variable----------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +extern void DBGP_Flag_Init(void); +extern void DBG_PrintAllFlag(void); +extern void DBG_PrintAllComp(void); +extern void DBG_PrintFlagEvent(u1Byte DbgFlag); +extern void DBG_DumpMem(const u1Byte DbgComp, + const u1Byte DbgLevel, + pu1Byte pMem, + u2Byte Len); + +/*--------------------------Exported Function prototype---------------------*/ + + + + + + + + + +extern u4Byte GlobalDebugLevel; +extern u8Byte GlobalDebugComponents; + + +#endif + + +#endif // __ODM_DBG_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_interface.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_interface.h new file mode 100644 index 0000000..d5732ba --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_interface.h @@ -0,0 +1,413 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __ODM_INTERFACE_H__ +#define __ODM_INTERFACE_H__ + + + +// +// =========== Constant/Structure/Enum/... Define +// + + + +// +// =========== Macro Define +// + +#define _reg_all(_name) ODM_##_name +#define _reg_ic(_name, _ic) ODM_##_name##_ic +#define _bit_all(_name) BIT_##_name +#define _bit_ic(_name, _ic) BIT_##_name##_ic + +// _cat: implemented by Token-Pasting Operator. +#if 0 +#define _cat(_name, _ic_type, _func) \ + ( \ + _func##_all(_name) \ + ) +#endif + +/*=================================== + +#define ODM_REG_DIG_11N 0xC50 +#define ODM_REG_DIG_11AC 0xDDD + +ODM_REG(DIG,_pDM_Odm) +=====================================*/ + +#define _reg_11N(_name) ODM_REG_##_name##_11N +#define _reg_11AC(_name) ODM_REG_##_name##_11AC +#define _bit_11N(_name) ODM_BIT_##_name##_11N +#define _bit_11AC(_name) ODM_BIT_##_name##_11AC + +#ifdef __ECOS +#define _rtk_cat(_name, _ic_type, _func) \ + ( \ + ((_ic_type) & ODM_IC_11N_SERIES)? _func##_11N(_name): \ + _func##_11AC(_name) \ + ) +#else + +#define _cat(_name, _ic_type, _func) \ + ( \ + ((_ic_type) & ODM_IC_11N_SERIES)? _func##_11N(_name): \ + _func##_11AC(_name) \ + ) +#endif +/* +// only sample code +//#define _cat(_name, _ic_type, _func) \ +// ( \ +// ((_ic_type) & ODM_RTL8192C)? _func##_ic(_name, _8192C): \ +// ((_ic_type) & ODM_RTL8192D)? _func##_ic(_name, _8192D): \ +// ((_ic_type) & ODM_RTL8192S)? _func##_ic(_name, _8192S): \ +// ((_ic_type) & ODM_RTL8723A)? _func##_ic(_name, _8723A): \ +// ((_ic_type) & ODM_RTL8188E)? _func##_ic(_name, _8188E): \ +// _func##_ic(_name, _8195) \ +// ) +*/ + +// _name: name of register or bit. +// Example: "ODM_REG(R_A_AGC_CORE1, pDM_Odm)" +// gets "ODM_R_A_AGC_CORE1" or "ODM_R_A_AGC_CORE1_8192C", depends on SupportICType. +#ifdef __ECOS +#define ODM_REG(_name, _pDM_Odm) _rtk_cat(_name, _pDM_Odm->SupportICType, _reg) +#define ODM_BIT(_name, _pDM_Odm) _rtk_cat(_name, _pDM_Odm->SupportICType, _bit) +#else +#define ODM_REG(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _reg) +#define ODM_BIT(_name, _pDM_Odm) _cat(_name, _pDM_Odm->SupportICType, _bit) +#endif +typedef enum _ODM_H2C_CMD +{ + /*ODM_H2C_RSSI_REPORT = 0, + ODM_H2C_PSD_RESULT=1, + ODM_H2C_PathDiv = 2, + ODM_H2C_WIFI_CALIBRATION = 3, + ODM_H2C_IQ_CALIBRATION = 4, + ODM_H2C_RA_PARA_ADJUST=5, + ODM_MAX_H2CCMD*/ + PHYDM_H2C_TXBF = 0x41, + ODM_H2C_RSSI_REPORT = 0x42, + ODM_H2C_IQ_CALIBRATION = 0x45, + ODM_H2C_RA_PARA_ADJUST = 0x47, + PHYDM_H2C_DYNAMIC_TX_PATH = 0x48, + PHYDM_H2C_FW_TRACE_EN = 0x49, + ODM_H2C_WIFI_CALIBRATION = 0x6d, + PHYDM_H2C_MU = 0x4a, + ODM_MAX_H2CCMD +}ODM_H2C_CMD; + + +// +// 2012/02/17 MH For non-MP compile pass only. Linux does not support workitem. +// Suggest HW team to use thread instead of workitem. Windows also support the feature. +// +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +typedef void *PRT_WORK_ITEM ; +typedef void RT_WORKITEM_HANDLE,*PRT_WORKITEM_HANDLE; +typedef VOID (*RT_WORKITEM_CALL_BACK)(PVOID pContext); + +#if 0 +typedef struct tasklet_struct RT_WORKITEM_HANDLE, *PRT_WORKITEM_HANDLE; + +typedef struct _RT_WORK_ITEM +{ + + RT_WORKITEM_HANDLE Handle; // Platform-dependent handle for this workitem, e.g. Ndis Workitem object. + PVOID Adapter; // Pointer to Adapter object. + PVOID pContext; // Parameter to passed to CallBackFunc(). + RT_WORKITEM_CALL_BACK CallbackFunc; // Callback function of the workitem. + u1Byte RefCount; // 0: driver is going to unload, 1: No such workitem scheduled, 2: one workitem is schedueled. + PVOID pPlatformExt; // Pointer to platform-dependent extension. + BOOLEAN bFree; + char szID[36]; // An identity string of this workitem. +}RT_WORK_ITEM, *PRT_WORK_ITEM; + +#endif + + +#endif + +// +// =========== Extern Variable ??? It should be forbidden. +// + + +// +// =========== EXtern Function Prototype +// + + +u1Byte +ODM_Read1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +u2Byte +ODM_Read2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +u4Byte +ODM_Read4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr + ); + +VOID +ODM_Write1Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u1Byte Data + ); + +VOID +ODM_Write2Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u2Byte Data + ); + +VOID +ODM_Write4Byte( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte Data + ); + +VOID +ODM_SetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetMACReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + +VOID +ODM_SetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetBBReg( + IN PDM_ODM_T pDM_Odm, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + +VOID +ODM_SetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask, + IN u4Byte Data + ); + +u4Byte +ODM_GetRFReg( + IN PDM_ODM_T pDM_Odm, + IN ODM_RF_RADIO_PATH_E eRFPath, + IN u4Byte RegAddr, + IN u4Byte BitMask + ); + + +// +// Memory Relative Function. +// +VOID +ODM_AllocateMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID *pPtr, + IN u4Byte length + ); +VOID +ODM_FreeMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pPtr, + IN u4Byte length + ); + +VOID +ODM_MoveMemory( + IN PDM_ODM_T pDM_Odm, + OUT PVOID pDest, + IN PVOID pSrc, + IN u4Byte Length + ); + +s4Byte ODM_CompareMemory( + IN PDM_ODM_T pDM_Odm, + IN PVOID pBuf1, + IN PVOID pBuf2, + IN u4Byte length + ); + +void ODM_Memory_Set + (IN PDM_ODM_T pDM_Odm, + IN PVOID pbuf, + IN s1Byte value, + IN u4Byte length); + +// +// ODM MISC-spin lock relative API. +// +#if( DM_ODM_SUPPORT_TYPE & (ODM_AP|ODM_ADSL|ODM_CE)) +VOID +ODM_AcquireSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ); + +VOID +ODM_ReleaseSpinLock( + IN PDM_ODM_T pDM_Odm, + IN RT_SPINLOCK_TYPE type + ); +#endif + +// +// ODM MISC-workitem relative API. +// +VOID +ODM_InitializeWorkItem( + IN PDM_ODM_T pDM_Odm, + IN PRT_WORK_ITEM pRtWorkItem, + IN RT_WORKITEM_CALL_BACK RtWorkItemCallback, + IN PVOID pContext, + IN const char* szID + ); + +VOID +ODM_StartWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_StopWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_FreeWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_ScheduleWorkItem( + IN PRT_WORK_ITEM pRtWorkItem + ); + +VOID +ODM_IsWorkItemScheduled( + IN PRT_WORK_ITEM pRtWorkItem + ); + +// +// ODM Timer relative API. +// +VOID +ODM_StallExecution( + IN u4Byte usDelay + ); + +VOID +ODM_delay_ms(IN u4Byte ms); + + + +VOID +ODM_delay_us(IN u4Byte us); + +VOID +ODM_sleep_ms(IN u4Byte ms); + +VOID +ODM_sleep_us(IN u4Byte us); + +#if (DM_ODM_SUPPORT_TYPE & (ODM_WIN|ODM_CE|ODM_AP|ODM_ADSL)) +VOID +ODM_SetTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN u4Byte msDelay + ); + +VOID +ODM_InitializeTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer, + IN RT_TIMER_CALL_BACK CallBackFunc, + IN PVOID pContext, + IN const char* szID + ); + +VOID +ODM_CancelTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ); + +VOID +ODM_ReleaseTimer( + IN PDM_ODM_T pDM_Odm, + IN PRT_TIMER pTimer + ); +#endif + +// +// ODM FW relative API. +// +VOID +ODM_FillH2CCmd( + IN PDM_ODM_T pDM_Odm, + IN u1Byte ElementID, + IN u4Byte CmdLen, + IN pu1Byte pCmdBuffer +); + +u8Byte +ODM_GetCurrentTime( + IN PDM_ODM_T pDM_Odm + ); +u8Byte +ODM_GetProgressingTime( + IN PDM_ODM_T pDM_Odm, + IN u8Byte Start_Time + ); + +#endif // __ODM_INTERFACE_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_precomp.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_precomp.h new file mode 100644 index 0000000..84e0bf4 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_precomp.h @@ -0,0 +1,349 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __ODM_PRECOMP_H__ +#define __ODM_PRECOMP_H__ + +#include "phydm_types.h" + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#include "Precomp.h" // We need to include mp_precomp.h due to batch file setting. + +#else + +#define TEST_FALG___ 1 + +#endif + +//2 Config Flags and Structs - defined by each ODM Type + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) + #include "../8192cd_cfg.h" + #include "../odm_inc.h" + + #include "../8192cd.h" + #include "../8192cd_util.h" + #ifdef _BIG_ENDIAN_ + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #else + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #endif + + #ifdef AP_BUILD_WORKAROUND + #include "../8192cd_headers.h" + #include "../8192cd_debug.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + // Flags + #include "../8192cd_cfg.h" // OUTSRC needs ADSL config flags. + #include "../odm_inc.h" // OUTSRC needs some extra flags. + // Data Structure + #include "../common_types.h" // OUTSRC and rtl8192cd both needs basic type such as UINT8 and BIT0. + #include "../8192cd.h" // OUTSRC needs basic ADSL struct definition. + #include "../8192cd_util.h" // OUTSRC needs basic I/O function. + #ifdef _BIG_ENDIAN_ + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #else + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #endif + + #ifdef ADSL_AP_BUILD_WORKAROUND + // NESTED_INC: Functions defined outside should not be included!! Marked by Annie, 2011-10-14. + #include "../8192cd_headers.h" + #include "../8192cd_debug.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE ==ODM_CE) +#define BEAMFORMING_SUPPORT 0 +#elif (DM_ODM_SUPPORT_TYPE ==ODM_IOT) +#define BEAMFORMING_SUPPORT 0 +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #include "mp_precomp.h" + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE +#endif + + +//2 Hardware Parameter Files + + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#if (RTL8192C_SUPPORT==1) + #include "rtl8192c/Hal8192CEFWImg_AP.h" + #include "rtl8192c/Hal8192CEPHYImg_AP.h" + #include "rtl8192c/Hal8192CEMACImg_AP.h" +#endif +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + #include "rtl8192c/Hal8192CEFWImg_ADSL.h" + #include "rtl8192c/Hal8192CEPHYImg_ADSL.h" + #include "rtl8192c/Hal8192CEMACImg_ADSL.h" + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #if(RTL8192CE_SUPPORT ==1) + #include "rtl8192c/Hal8192CEFWImg_CE.h" + #include "rtl8192c/Hal8192CEPHYImg_CE.h" + #include "rtl8192c/Hal8192CEMACImg_CE.h" + #endif + + #if(RTL8192CU_SUPPORT ==1) + #include "rtl8192c/Hal8192CUFWImg_CE.h" + #include "rtl8192c/Hal8192CUPHYImg_CE.h" + #include "rtl8192c/Hal8192CUMACImg_CE.h" + #endif + + #if(RTL8192DE_SUPPORT ==1) + #include "rtl8192d/Hal8192DEFWImg_CE.h" + #include "rtl8192d/Hal8192DEPHYImg_CE.h" + #include "rtl8192d/Hal8192DEMACImg_CE.h" + #endif + + #if(RTL8192DU_SUPPORT ==1) + #include "rtl8192d/Hal8192DUFWImg_CE.h" + #include "rtl8192d/Hal8192DUPHYImg_CE.h" + #include "rtl8192d/Hal8192DUMACImg_CE.h" + #endif + + #if(RTL8723AS_SUPPORT==1) + #include "rtl8723a/Hal8723SHWImg_CE.h" + #endif + + #if(RTL8723AU_SUPPORT==1) + #include "rtl8723a/Hal8723UHWImg_CE.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_WIN) + +#endif + + +//2 OutSrc Header Files +#if (RTL8188E_SUPPORT==1) +// Old ODM +#include "rtl8188e\odm.h" +#include "rtl8188e\odm_HWConfig.h" +#include "rtl8188e\odm_debug.h" +#include "rtl8188e\odm_RegDefine11AC.h" +#include "rtl8188e\odm_RegDefine11N.h" +#include "rtl8188e\odm_interface.h" +#include "rtl8188e\odm_reg.h" +#include "rtl8188e\Hal8188EAdaptivity.h" +#else +// new ODM +#include "phydm.h" +#include "phydm_HWConfig.h" +#include "phydm_debug.h" +#include "phydm_RegDefine11AC.h" +#include "phydm_RegDefine11N.h" +#include "phydm_AntDiv.h" +#include "phydm_EdcaTurboCheck.h" +#include "phydm_DIG.h" +#include "PhyDM_Adaptivity.h" +#include "phydm_PathDiv.h" +#include "phydm_RaInfo.h" +#include "phydm_DynamicBBPowerSaving.h" +#include "phydm_DynamicTxPower.h" +#include "phydm_CfoTracking.h" +#include "phydm_NoiseMonitor.h" +#include "phydm_interface.h" +#include "phydm_reg.h" +#endif + +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#if (RTL8192C_SUPPORT==1) + #include "rtl8192c/HalDMOutSrc8192C_AP.h" +#endif +#if (RTL8188E_SUPPORT==1) + #include "rtl8188e/Hal8188ERateAdaptive.h"//for RA,Power training +#endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + #include "rtl8192c/HalDMOutSrc8192C_ADSL.h" + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + //#include "hal_com.h" + #include "HalPhyRf.h" + #if (RTL8192C_SUPPORT==1) + #ifdef CONFIG_INTEL_PROXIM + #include "../proxim/intel_proxim.h" + #endif + #include "rtl8192c/HalDMOutSrc8192C_CE.h" + #include + #endif + + #if (RTL8192D_SUPPORT==1) + #include "rtl8192d/HalDMOutSrc8192D_CE.h" + #include "rtl8192d_hal.h" + #endif + + #if (RTL8723A_SUPPORT==1) + #include "rtl8192c/HalDMOutSrc8192C_CE.h" //for IQK,LCK,Power-tracking + #include "../rtl8723a/rtl8723a_hal.h" + #endif + + #if (RTL8188E_SUPPORT==1) + #include "rtl8188e/HalPhyRf_8188e.h"//for IQK,LCK,Power-tracking + #include "rtl8188e/Hal8188ERateAdaptive.h"//for RA,Power training + #include "../rtl8188e/rtl8188e_hal.h" + #endif + + #if (RTL8192E_SUPPORT==1) + #include "rtl8192e/HalPhyRf_8192e.h"//for IQK,LCK,Power-tracking + #include "rtl8192e_hal.h" + #endif + + #if (RTL8812A_SUPPORT==1) + #include "rtl8812a/HalPhyRf_8812A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a_hal.h" + #endif + + #if (RTL8821A_SUPPORT==1) + #include "rtl8821a/HalPhyRf_8821A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a/HalPhyRf_8812A.h"//for IQK,LCK,Power-tracking + #include "rtl8812a_hal.h" + #endif + + #if (RTL8723B_SUPPORT==1) + #include "rtl8723b/HalPhyRf_8723B.h"//for IQK,LCK,Power-tracking + #include "rtl8723b_hal.h" + #endif + +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) + #include "HalPhyRf.h" + #if (RTL8195A_SUPPORT==1) + #include "rtl8195a/HalPhyRf_8195A.h"//for IQK,LCK,Power-tracking + #include "rtl8195a_hal.h" + #endif + + #if (RTL8711B_SUPPORT==1) + #include "rtl8711b/HalPhyRf_8711b.h"//for IQK,LCK,Power-tracking + #include "rtl8711b_hal.h" + #endif +#endif + + +#if (RTL8192C_SUPPORT==1) +#if (DM_ODM_SUPPORT_TYPE == ODM_AP) +#include "rtl8192c/Hal8192CHWImg_MAC.h" +#include "rtl8192c/Hal8192CHWImg_RF.h" +#include "rtl8192c/Hal8192CHWImg_BB.h" +#include "rtl8192c/Hal8192CHWImg_FW.h" +#endif +#include "rtl8192c/phydm_RTL8192C.h" +#endif +#if (RTL8192D_SUPPORT==1) +#include "rtl8192d/phydm_RTL8192D.h" +#endif + +#if (RTL8723A_SUPPORT==1) +#include "rtl8723a/HalHWImg8723A_MAC.h" +#include "rtl8723a/HalHWImg8723A_RF.h" +#include "rtl8723a/HalHWImg8723A_BB.h" +#include "rtl8723a/HalHWImg8723A_FW.h" +#include "rtl8723a/phydm_RegConfig8723A.h" +#endif + +#if (RTL8188E_SUPPORT==1) +#include "rtl8188e/HalHWImg8188E_MAC.h" +#include "rtl8188e/HalHWImg8188E_RF.h" +#include "rtl8188e/HalHWImg8188E_BB.h" +#include "rtl8188e/HalHWImg8188E_FW.h" +#include "rtl8188e/Hal8188EReg.h" + +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) +#include "rtl8188e/HalPhyRf_8188e.h" +#endif + +#if (TEST_CHIP_SUPPORT == 1) +#include "rtl8188e/HalHWImg8188E_TestChip_MAC.h" +#include "rtl8188e/HalHWImg8188E_TestChip_RF.h" +#include "rtl8188e/HalHWImg8188E_TestChip_BB.h" +#endif + + +#include "rtl8188e/odm_RegConfig8188E.h" +#include "rtl8188e/odm_RTL8188E.h" +#endif + +#if (RTL8192E_SUPPORT==1) +#include "rtl8192e/HalHWImg8192E_MAC.h" +#include "rtl8192e/HalHWImg8192E_RF.h" +#include "rtl8192e/HalHWImg8192E_BB.h" +#include "rtl8192e/HalHWImg8192E_FW.h" +#include "rtl8192e/Hal8192EReg.h" +#include "rtl8192e/phydm_RegConfig8192E.h" +#include "rtl8192e/phydm_RTL8192E.h" +#endif + +#if (RTL8723B_SUPPORT==1) +#include "rtl8723b/HalHWImg8723B_MAC.h" +#include "rtl8723b/HalHWImg8723B_RF.h" +#include "rtl8723b/HalHWImg8723B_BB.h" +#include "rtl8723b/HalHWImg8723B_FW.h" +#include "rtl8723b/HalHWImg8723B_MP.h" +#include "rtl8723b/Hal8723BReg.h" +#include "rtl8723b/phydm_RTL8723B.h" +#include "rtl8723b/phydm_RegConfig8723B.h" +#endif + +#if (RTL8812A_SUPPORT==1) +#include "rtl8812a/HalHWImg8812A_MAC.h" +#include "rtl8812a/HalHWImg8812A_RF.h" +#include "rtl8812a/HalHWImg8812A_BB.h" +#include "rtl8812a/HalHWImg8812A_FW.h" +#include "rtl8812a/phydm_RegConfig8812A.h" +#include "rtl8812a/phydm_RTL8812A.h" +#endif + + +#if (RTL8821A_SUPPORT==1) +#include "rtl8821a/HalHWImg8821A_MAC.h" +#include "rtl8821a/HalHWImg8821A_RF.h" +#include "rtl8821a/HalHWImg8821A_BB.h" +#include "rtl8821a/HalHWImg8821A_FW.h" +#include "rtl8821a/phydm_RegConfig8821A.h" +#include "rtl8821a/phydm_RTL8821A.h" +#endif + +#if (RTL8195A_SUPPORT==1) +#include "rtl8195a/halhwimg8195a_mac.h" +#include "rtl8195a/halhwimg8195a_rf.h" +#include "rtl8195a/halhwimg8195a_bb.h" +#include "rtl8195a/Hal8195AReg.h" +#include "rtl8195a/phydm_RTL8195A.h" +#include "rtl8195a/phydm_RegConfig8195A.h" +#include "rtl8195a/ROM_RTL8195A_PHYDM.h" +#include "rtl8195a/Hal8195ARateAdaptive.h" +#endif + +#if (RTL8711B_SUPPORT==1) +#include "rtl8711b/HalHWImg8711B_MAC.h" +#include "rtl8711b/HalHWImg8711B_RF.h" +#include "rtl8711b/HalHWImg8711B_BB.h" +#include "rtl8711b/HalHWImg8711B_FW.h" +#include "rtl8711b/HalHWImg8711B_MP.h" +#include "rtl8711b/Hal8711BReg.h" +#include "rtl8711b/phydm_RTL8711B.h" +#include "rtl8711b/phydm_RegConfig8711B.h" +#include "rtl8711b/ROM_RTL8711B_PHYDM.h" +#include "rtl8711b/Hal8711BRateAdaptive.h" +#endif + +#endif // __ODM_PRECOMP_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_reg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_reg.h new file mode 100644 index 0000000..e842413 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_reg.h @@ -0,0 +1,208 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +//============================================================ +// File Name: odm_reg.h +// +// Description: +// +// This file is for general register definition. +// +// +//============================================================ +#ifndef __HAL_ODM_REG_H__ +#define __HAL_ODM_REG_H__ + +// +// Register Definition +// + +//MAC REG +#define ODM_BB_RESET 0x002 +#define ODM_DUMMY 0x4fe +#define RF_T_METER_OLD 0x24 +#define RF_T_METER_NEW 0x42 + +#define ODM_EDCA_VO_PARAM 0x500 +#define ODM_EDCA_VI_PARAM 0x504 +#define ODM_EDCA_BE_PARAM 0x508 +#define ODM_EDCA_BK_PARAM 0x50C +#define ODM_TXPAUSE 0x522 + +//BB REG +#define ODM_FPGA_PHY0_PAGE8 0x800 +#define ODM_PSD_SETTING 0x808 +#define ODM_AFE_SETTING 0x818 +#define ODM_TXAGC_B_6_18 0x830 +#define ODM_TXAGC_B_24_54 0x834 +#define ODM_TXAGC_B_MCS32_5 0x838 +#define ODM_TXAGC_B_MCS0_MCS3 0x83c +#define ODM_TXAGC_B_MCS4_MCS7 0x848 +#define ODM_TXAGC_B_MCS8_MCS11 0x84c +#define ODM_ANALOG_REGISTER 0x85c +#define ODM_RF_INTERFACE_OUTPUT 0x860 +#define ODM_TXAGC_B_MCS12_MCS15 0x868 +#define ODM_TXAGC_B_11_A_2_11 0x86c +#define ODM_AD_DA_LSB_MASK 0x874 +#define ODM_ENABLE_3_WIRE 0x88c +#define ODM_PSD_REPORT 0x8b4 +#define ODM_R_ANT_SELECT 0x90c +#define ODM_CCK_ANT_SELECT 0xa07 +#define ODM_CCK_PD_THRESH 0xa0a +#define ODM_CCK_RF_REG1 0xa11 +#define ODM_CCK_MATCH_FILTER 0xa20 +#define ODM_CCK_RAKE_MAC 0xa2e +#define ODM_CCK_CNT_RESET 0xa2d +#define ODM_CCK_TX_DIVERSITY 0xa2f +#define ODM_CCK_FA_CNT_MSB 0xa5b +#define ODM_CCK_FA_CNT_LSB 0xa5c +#define ODM_CCK_NEW_FUNCTION 0xa75 +#define ODM_OFDM_PHY0_PAGE_C 0xc00 +#define ODM_OFDM_RX_ANT 0xc04 +#define ODM_R_A_RXIQI 0xc14 +#define ODM_R_A_AGC_CORE1 0xc50 +#define ODM_R_A_AGC_CORE2 0xc54 +#define ODM_R_B_AGC_CORE1 0xc58 +#define ODM_R_AGC_PAR 0xc70 +#define ODM_R_HTSTF_AGC_PAR 0xc7c +#define ODM_TX_PWR_TRAINING_A 0xc90 +#define ODM_TX_PWR_TRAINING_B 0xc98 +#define ODM_OFDM_FA_CNT1 0xcf0 +#define ODM_OFDM_PHY0_PAGE_D 0xd00 +#define ODM_OFDM_FA_CNT2 0xda0 +#define ODM_OFDM_FA_CNT3 0xda4 +#define ODM_OFDM_FA_CNT4 0xda8 +#define ODM_TXAGC_A_6_18 0xe00 +#define ODM_TXAGC_A_24_54 0xe04 +#define ODM_TXAGC_A_1_MCS32 0xe08 +#define ODM_TXAGC_A_MCS0_MCS3 0xe10 +#define ODM_TXAGC_A_MCS4_MCS7 0xe14 +#define ODM_TXAGC_A_MCS8_MCS11 0xe18 +#define ODM_TXAGC_A_MCS12_MCS15 0xe1c + +//RF REG +#define ODM_GAIN_SETTING 0x00 +#define ODM_CHANNEL 0x18 +#define ODM_RF_T_METER 0x24 +#define ODM_RF_T_METER_92D 0x42 +#define ODM_RF_T_METER_88E 0x42 +#define ODM_RF_T_METER_92E 0x42 +#define ODM_RF_T_METER_8812 0x42 + +//Ant Detect Reg +#define ODM_DPDT 0x300 + +//PSD Init +#define ODM_PSDREG 0x808 + +//92D Path Div +#define PATHDIV_REG 0xB30 +#define PATHDIV_TRI 0xBA0 + + +// +// Bitmap Definition +// +#if(DM_ODM_SUPPORT_TYPE & (ODM_AP)) +// TX AGC +#define rTxAGC_A_CCK11_CCK1_JAguar 0xc20 +#define rTxAGC_A_Ofdm18_Ofdm6_JAguar 0xc24 +#define rTxAGC_A_Ofdm54_Ofdm24_JAguar 0xc28 +#define rTxAGC_A_MCS3_MCS0_JAguar 0xc2c +#define rTxAGC_A_MCS7_MCS4_JAguar 0xc30 +#define rTxAGC_A_MCS11_MCS8_JAguar 0xc34 +#define rTxAGC_A_MCS15_MCS12_JAguar 0xc38 +#define rTxAGC_A_Nss1Index3_Nss1Index0_JAguar 0xc3c +#define rTxAGC_A_Nss1Index7_Nss1Index4_JAguar 0xc40 +#define rTxAGC_A_Nss2Index1_Nss1Index8_JAguar 0xc44 +#define rTxAGC_A_Nss2Index5_Nss2Index2_JAguar 0xc48 +#define rTxAGC_A_Nss2Index9_Nss2Index6_JAguar 0xc4c +#if defined(CONFIG_WLAN_HAL_8814AE) +#define rTxAGC_A_MCS19_MCS16_JAguar 0xcd8 +#define rTxAGC_A_MCS23_MCS20_JAguar 0xcdc +#define rTxAGC_A_Nss3Index3_Nss3Index0_JAguar 0xce0 +#define rTxAGC_A_Nss3Index7_Nss3Index4_JAguar 0xce4 +#define rTxAGC_A_Nss3Index9_Nss3Index8_JAguar 0xce8 +#endif +#define rTxAGC_B_CCK11_CCK1_JAguar 0xe20 +#define rTxAGC_B_Ofdm18_Ofdm6_JAguar 0xe24 +#define rTxAGC_B_Ofdm54_Ofdm24_JAguar 0xe28 +#define rTxAGC_B_MCS3_MCS0_JAguar 0xe2c +#define rTxAGC_B_MCS7_MCS4_JAguar 0xe30 +#define rTxAGC_B_MCS11_MCS8_JAguar 0xe34 +#define rTxAGC_B_MCS15_MCS12_JAguar 0xe38 +#define rTxAGC_B_Nss1Index3_Nss1Index0_JAguar 0xe3c +#define rTxAGC_B_Nss1Index7_Nss1Index4_JAguar 0xe40 +#define rTxAGC_B_Nss2Index1_Nss1Index8_JAguar 0xe44 +#define rTxAGC_B_Nss2Index5_Nss2Index2_JAguar 0xe48 +#define rTxAGC_B_Nss2Index9_Nss2Index6_JAguar 0xe4c +#if defined(CONFIG_WLAN_HAL_8814AE) +#define rTxAGC_B_MCS19_MCS16_JAguar 0xed8 +#define rTxAGC_B_MCS23_MCS20_JAguar 0xedc +#define rTxAGC_B_Nss3Index3_Nss3Index0_JAguar 0xee0 +#define rTxAGC_B_Nss3Index7_Nss3Index4_JAguar 0xee4 +#define rTxAGC_B_Nss3Index9_Nss3Index8_JAguar 0xee8 +#define rTxAGC_C_CCK11_CCK1_JAguar 0x1820 +#define rTxAGC_C_Ofdm18_Ofdm6_JAguar 0x1824 +#define rTxAGC_C_Ofdm54_Ofdm24_JAguar 0x1828 +#define rTxAGC_C_MCS3_MCS0_JAguar 0x182c +#define rTxAGC_C_MCS7_MCS4_JAguar 0x1830 +#define rTxAGC_C_MCS11_MCS8_JAguar 0x1834 +#define rTxAGC_C_MCS15_MCS12_JAguar 0x1838 +#define rTxAGC_C_Nss1Index3_Nss1Index0_JAguar 0x183c +#define rTxAGC_C_Nss1Index7_Nss1Index4_JAguar 0x1840 +#define rTxAGC_C_Nss2Index1_Nss1Index8_JAguar 0x1844 +#define rTxAGC_C_Nss2Index5_Nss2Index2_JAguar 0x1848 +#define rTxAGC_C_Nss2Index9_Nss2Index6_JAguar 0x184c +#define rTxAGC_C_MCS19_MCS16_JAguar 0x18d8 +#define rTxAGC_C_MCS23_MCS20_JAguar 0x18dc +#define rTxAGC_C_Nss3Index3_Nss3Index0_JAguar 0x18e0 +#define rTxAGC_C_Nss3Index7_Nss3Index4_JAguar 0x18e4 +#define rTxAGC_C_Nss3Index9_Nss3Index8_JAguar 0x18e8 +#define rTxAGC_D_CCK11_CCK1_JAguar 0x1a20 +#define rTxAGC_D_Ofdm18_Ofdm6_JAguar 0x1a24 +#define rTxAGC_D_Ofdm54_Ofdm24_JAguar 0x1a28 +#define rTxAGC_D_MCS3_MCS0_JAguar 0x1a2c +#define rTxAGC_D_MCS7_MCS4_JAguar 0x1a30 +#define rTxAGC_D_MCS11_MCS8_JAguar 0x1a34 +#define rTxAGC_D_MCS15_MCS12_JAguar 0x1a38 +#define rTxAGC_D_Nss1Index3_Nss1Index0_JAguar 0x1a3c +#define rTxAGC_D_Nss1Index7_Nss1Index4_JAguar 0x1a40 +#define rTxAGC_D_Nss2Index1_Nss1Index8_JAguar 0x1a44 +#define rTxAGC_D_Nss2Index5_Nss2Index2_JAguar 0x1a48 +#define rTxAGC_D_Nss2Index9_Nss2Index6_JAguar 0x1a4c +#define rTxAGC_D_MCS19_MCS16_JAguar 0x1ad8 +#define rTxAGC_D_MCS23_MCS20_JAguar 0x1adc +#define rTxAGC_D_Nss3Index3_Nss3Index0_JAguar 0x1ae0 +#define rTxAGC_D_Nss3Index7_Nss3Index4_JAguar 0x1ae4 +#define rTxAGC_D_Nss3Index9_Nss3Index8_JAguar 0x1ae8 +#endif + +#define bTxAGC_byte0_Jaguar 0xff +#define bTxAGC_byte1_Jaguar 0xff00 +#define bTxAGC_byte2_Jaguar 0xff0000 +#define bTxAGC_byte3_Jaguar 0xff000000 +#endif + +#define BIT_FA_RESET BIT0 + + + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_types.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_types.h new file mode 100644 index 0000000..71cbafc --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/phydm_types.h @@ -0,0 +1,442 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ODM_TYPES_H__ +#define __ODM_TYPES_H__ + +#define ODM_RATEMCS15_SG 0x1c +#define ODM_RATEMCS32 0x20 + + +// CCK Rates, TxHT = 0 +#define ODM_RATE1M 0x00 +#define ODM_RATE2M 0x01 +#define ODM_RATE5_5M 0x02 +#define ODM_RATE11M 0x03 +// OFDM Rates, TxHT = 0 +#define ODM_RATE6M 0x04 +#define ODM_RATE9M 0x05 +#define ODM_RATE12M 0x06 +#define ODM_RATE18M 0x07 +#define ODM_RATE24M 0x08 +#define ODM_RATE36M 0x09 +#define ODM_RATE48M 0x0A +#define ODM_RATE54M 0x0B +// MCS Rates, TxHT = 1 +#define ODM_RATEMCS0 0x0C +#define ODM_RATEMCS1 0x0D +#define ODM_RATEMCS2 0x0E +#define ODM_RATEMCS3 0x0F +#define ODM_RATEMCS4 0x10 +#define ODM_RATEMCS5 0x11 +#define ODM_RATEMCS6 0x12 +#define ODM_RATEMCS7 0x13 +#define ODM_RATEMCS8 0x14 +#define ODM_RATEMCS9 0x15 +#define ODM_RATEMCS10 0x16 +#define ODM_RATEMCS11 0x17 +#define ODM_RATEMCS12 0x18 +#define ODM_RATEMCS13 0x19 +#define ODM_RATEMCS14 0x1A +#define ODM_RATEMCS15 0x1B +#define ODM_RATEMCS16 0x1C +#define ODM_RATEMCS17 0x1D +#define ODM_RATEMCS18 0x1E +#define ODM_RATEMCS19 0x1F +#define ODM_RATEMCS20 0x20 +#define ODM_RATEMCS21 0x21 +#define ODM_RATEMCS22 0x22 +#define ODM_RATEMCS23 0x23 +#define ODM_RATEMCS24 0x24 +#define ODM_RATEMCS25 0x25 +#define ODM_RATEMCS26 0x26 +#define ODM_RATEMCS27 0x27 +#define ODM_RATEMCS28 0x28 +#define ODM_RATEMCS29 0x29 +#define ODM_RATEMCS30 0x2A +#define ODM_RATEMCS31 0x2B +#define ODM_RATEVHTSS1MCS0 0x2C +#define ODM_RATEVHTSS1MCS1 0x2D +#define ODM_RATEVHTSS1MCS2 0x2E +#define ODM_RATEVHTSS1MCS3 0x2F +#define ODM_RATEVHTSS1MCS4 0x30 +#define ODM_RATEVHTSS1MCS5 0x31 +#define ODM_RATEVHTSS1MCS6 0x32 +#define ODM_RATEVHTSS1MCS7 0x33 +#define ODM_RATEVHTSS1MCS8 0x34 +#define ODM_RATEVHTSS1MCS9 0x35 +#define ODM_RATEVHTSS2MCS0 0x36 +#define ODM_RATEVHTSS2MCS1 0x37 +#define ODM_RATEVHTSS2MCS2 0x38 +#define ODM_RATEVHTSS2MCS3 0x39 +#define ODM_RATEVHTSS2MCS4 0x3A +#define ODM_RATEVHTSS2MCS5 0x3B +#define ODM_RATEVHTSS2MCS6 0x3C +#define ODM_RATEVHTSS2MCS7 0x3D +#define ODM_RATEVHTSS2MCS8 0x3E +#define ODM_RATEVHTSS2MCS9 0x3F +#define ODM_RATEVHTSS3MCS0 0x40 +#define ODM_RATEVHTSS3MCS1 0x41 +#define ODM_RATEVHTSS3MCS2 0x42 +#define ODM_RATEVHTSS3MCS3 0x43 +#define ODM_RATEVHTSS3MCS4 0x44 +#define ODM_RATEVHTSS3MCS5 0x45 +#define ODM_RATEVHTSS3MCS6 0x46 +#define ODM_RATEVHTSS3MCS7 0x47 +#define ODM_RATEVHTSS3MCS8 0x48 +#define ODM_RATEVHTSS3MCS9 0x49 +#define ODM_RATEVHTSS4MCS0 0x4A +#define ODM_RATEVHTSS4MCS1 0x4B +#define ODM_RATEVHTSS4MCS2 0x4C +#define ODM_RATEVHTSS4MCS3 0x4D +#define ODM_RATEVHTSS4MCS4 0x4E +#define ODM_RATEVHTSS4MCS5 0x4F +#define ODM_RATEVHTSS4MCS6 0x50 +#define ODM_RATEVHTSS4MCS7 0x51 +#define ODM_RATEVHTSS4MCS8 0x52 +#define ODM_RATEVHTSS4MCS9 0x53 + + +// +// Define Different SW team support +// +#define ODM_AP 0x01 //BIT0 +#define ODM_ADSL 0x02 //BIT1 +#define ODM_CE 0x04 //BIT2 +#define ODM_WIN 0x08 //BIT3 +#define ODM_IOT 0x10 //BIT4 + +#define DM_ODM_SUPPORT_TYPE ODM_IOT + +// Deifne HW endian support +#define ODM_ENDIAN_BIG 0 +#define ODM_ENDIAN_LITTLE 1 + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) +#define GET_PDM_ODM(__pAdapter) ((PDM_ODM_T)(&((GET_HAL_DATA(__pAdapter))->DM_OutSrc))) +#elif (DM_ODM_SUPPORT_TYPE & (ODM_CE|ODM_IOT)) +#define GET_PDM_ODM(__pAdapter) ((PDM_ODM_T)(&((GET_HAL_DATA(__pAdapter))->odmpriv))) +#endif + +#if (DM_ODM_SUPPORT_TYPE != ODM_WIN) +#define RT_PCI_INTERFACE 1 +#define RT_USB_INTERFACE 2 +#define RT_SDIO_INTERFACE 3 +#define RT_LXBUS_INTERFACE 4 +#endif + +typedef enum _HAL_STATUS{ + HAL_STATUS_SUCCESS, + HAL_STATUS_FAILURE, + /*RT_STATUS_PENDING, + RT_STATUS_RESOURCE, + RT_STATUS_INVALID_CONTEXT, + RT_STATUS_INVALID_PARAMETER, + RT_STATUS_NOT_SUPPORT, + RT_STATUS_OS_API_FAILED,*/ +}HAL_STATUS,*PHAL_STATUS; + + +#if( (DM_ODM_SUPPORT_TYPE == ODM_AP) ||(DM_ODM_SUPPORT_TYPE == ODM_ADSL) || (DM_ODM_SUPPORT_TYPE == ODM_CE)) + +#define VISTA_USB_RX_REVISE 0 + +// +// Declare for ODM spin lock defintion temporarily fro compile pass. +// +typedef enum _RT_SPINLOCK_TYPE{ + RT_TX_SPINLOCK = 1, + RT_RX_SPINLOCK = 2, + RT_RM_SPINLOCK = 3, + RT_CAM_SPINLOCK = 4, + RT_SCAN_SPINLOCK = 5, + RT_LOG_SPINLOCK = 7, + RT_BW_SPINLOCK = 8, + RT_CHNLOP_SPINLOCK = 9, + RT_RF_OPERATE_SPINLOCK = 10, + RT_INITIAL_SPINLOCK = 11, + RT_RF_STATE_SPINLOCK = 12, // For RF state. Added by Bruce, 2007-10-30. +#if VISTA_USB_RX_REVISE + RT_USBRX_CONTEXT_SPINLOCK = 13, + RT_USBRX_POSTPROC_SPINLOCK = 14, // protect data of Adapter->IndicateW/ IndicateR +#endif + //Shall we define Ndis 6.2 SpinLock Here ? + RT_PORT_SPINLOCK=16, + RT_H2C_SPINLOCK = 20, // For H2C cmd. Added by tynli. 2009.11.09. + + RT_BTData_SPINLOCK=25, + + RT_WAPI_OPTION_SPINLOCK=26, + RT_WAPI_RX_SPINLOCK=27, + + // add for 92D CCK control issue + RT_CCK_PAGEA_SPINLOCK = 28, + RT_BUFFER_SPINLOCK = 29, + RT_CHANNEL_AND_BANDWIDTH_SPINLOCK = 30, + RT_GEN_TEMP_BUF_SPINLOCK = 31, + RT_AWB_SPINLOCK = 32, + RT_FW_PS_SPINLOCK = 33, + RT_HW_TIMER_SPIN_LOCK = 34, + RT_MPT_WI_SPINLOCK = 35, + RT_P2P_SPIN_LOCK = 36, // Protect P2P context + RT_DBG_SPIN_LOCK = 37, + RT_IQK_SPINLOCK = 38, + RT_PENDED_OID_SPINLOCK = 39, + RT_CHNLLIST_SPINLOCK = 40, + RT_INDIC_SPINLOCK = 41, //protect indication +}RT_SPINLOCK_TYPE; + +#endif + + +#if (DM_ODM_SUPPORT_TYPE == ODM_WIN) + #define STA_INFO_T RT_WLAN_STA + #define PSTA_INFO_T PRT_WLAN_STA + +// typedef unsigned long u4Byte,*pu4Byte; +#define CONFIG_HW_ANTENNA_DIVERSITY +#define CONFIG_SW_ANTENNA_DIVERSITY + +#elif (DM_ODM_SUPPORT_TYPE == ODM_AP) + + // To let ADSL/AP project compile ok; it should be removed after all conflict are solved. Added by Annie, 2011-10-07. + #define ADSL_AP_BUILD_WORKAROUND + #define AP_BUILD_WORKAROUND + // +#ifdef CONFIG_ANT_SWITCH + #define CONFIG_HW_ANTENNA_DIVERSITY + #if ( defined(CONFIG_NO_2G_DIVERSITY) && defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_NOT_SUPPORT_ANTDIV + #elif( !defined(CONFIG_NO_2G_DIVERSITY) && defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_2G_SUPPORT_ANTDIV + #elif( defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_5G_SUPPORT_ANTDIV + #elif( !defined(CONFIG_NO_2G_DIVERSITY) && !defined(CONFIG_NO_5G_DIVERSITY) ) + #define CONFIG_2G5G_SUPPORT_ANTDIV + #endif +#endif + + #ifdef AP_BUILD_WORKAROUND + #include "../typedef.h" + #else + typedef void VOID,*PVOID; + typedef unsigned char BOOLEAN,*PBOOLEAN; + typedef unsigned char u1Byte,*pu1Byte; + typedef unsigned short u2Byte,*pu2Byte; + typedef unsigned int u4Byte,*pu4Byte; + typedef unsigned long long u8Byte,*pu8Byte; + typedef char s1Byte,*ps1Byte; + typedef short s2Byte,*ps2Byte; + typedef long s4Byte,*ps4Byte; + typedef long long s8Byte,*ps8Byte; + #endif + + typedef struct rtl8192cd_priv *prtl8192cd_priv; + typedef struct stat_info STA_INFO_T,*PSTA_INFO_T; + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + + #define DEV_BUS_TYPE RT_PCI_INTERFACE + + #define _TRUE 1 + #define _FALSE 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_ADSL) + + // To let ADSL/AP project compile ok; it should be removed after all conflict are solved. Added by Annie, 2011-10-07. + #define ADSL_AP_BUILD_WORKAROUND + #define ADSL_BUILD_WORKAROUND + // + + typedef unsigned char BOOLEAN,*PBOOLEAN; + typedef unsigned char u1Byte,*pu1Byte; + typedef unsigned short u2Byte,*pu2Byte; + typedef unsigned int u4Byte,*pu4Byte; + typedef unsigned long long u8Byte,*pu8Byte; + typedef char s1Byte,*ps1Byte; + typedef short s2Byte,*ps2Byte; + typedef long s4Byte,*ps4Byte; + typedef long long s8Byte,*ps8Byte; + + typedef struct rtl8192cd_priv *prtl8192cd_priv; + typedef struct stat_info STA_INFO_T,*PSTA_INFO_T; + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + + #define DEV_BUS_TYPE RT_PCI_INTERFACE + + #define _TRUE 1 + #define _FALSE 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_CE) + #include + +#if 0 + typedef u8 u1Byte, *pu1Byte; + typedef u16 u2Byte,*pu2Byte; + typedef u32 u4Byte,*pu4Byte; + typedef u64 u8Byte,*pu8Byte; + typedef s8 s1Byte,*ps1Byte; + typedef s16 s2Byte,*ps2Byte; + typedef s32 s4Byte,*ps4Byte; + typedef s64 s8Byte,*ps8Byte; +#else + #define u1Byte u8 + #define pu1Byte u8* + + #define u2Byte u16 + #define pu2Byte u16* + + #define u4Byte u32 + #define pu4Byte u32* + + #define u8Byte u64 + #define pu8Byte u64* + + #define s1Byte s8 + #define ps1Byte s8* + + #define s2Byte s16 + #define ps2Byte s16* + + #define s4Byte s32 + #define ps4Byte s32* + + #define s8Byte s64 + #define ps8Byte s64* + +#endif + #ifdef CONFIG_USB_HCI + #define DEV_BUS_TYPE RT_USB_INTERFACE + #elif defined(CONFIG_PCI_HCI) + #define DEV_BUS_TYPE RT_PCI_INTERFACE + #elif defined(CONFIG_SDIO_HCI) + #define DEV_BUS_TYPE RT_SDIO_INTERFACE + #elif defined(CONFIG_GSPI_HCI) + #define DEV_BUS_TYPE RT_SDIO_INTERFACE + #elif defined(CONFIG_LX_HCI) + #define DEV_BUS_TYPE RT_PCI_INTERFACE + #endif + + + #if defined(CONFIG_LITTLE_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #elif defined (CONFIG_BIG_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #endif + + typedef struct timer_list RT_TIMER, *PRT_TIMER; + typedef void * RT_TIMER_CALL_BACK; + #define STA_INFO_T struct sta_info + #define PSTA_INFO_T struct sta_info * + + + +#ifndef TRUE + #define TRUE _TRUE +#endif +#ifndef FALSE + #define FALSE _FALSE +#endif + + + #define SET_TX_DESC_ANTSEL_A_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 1, __Value) + #define SET_TX_DESC_ANTSEL_B_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 25, 1, __Value) + #define SET_TX_DESC_ANTSEL_C_88E(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 29, 1, __Value) + + //define useless flag to avoid compile warning + #define USE_WORKITEM 0 + #define FOR_BRAZIL_PRETEST 0 + #define FPGA_TWO_MAC_VERIFICATION 0 + #define RTL8881A_SUPPORT 0 + +#elif (DM_ODM_SUPPORT_TYPE == ODM_IOT) + #include + + #define RA_MASK_PHYDMLIZE_CE 1 + + typedef unsigned char u1Byte,*pu1Byte; + typedef unsigned short u2Byte,*pu2Byte; + typedef unsigned int u4Byte,*pu4Byte; + typedef unsigned long long u8Byte,*pu8Byte; + typedef signed char s1Byte,*ps1Byte; /* GCC ROM char = unsigned char */ + typedef signed short s2Byte,*ps2Byte; + typedef signed long s4Byte,*ps4Byte; + typedef long long s8Byte,*ps8Byte; + + typedef struct sta_info STA_INFO_T,*PSTA_INFO_T; + + #if defined(CONFIG_GSPI_HCI) + #define DEV_BUS_TYPE RT_SDIO_INTERFACE + #elif defined(CONFIG_LX_HCI) + #define DEV_BUS_TYPE RT_LXBUS_INTERFACE + #endif + + // Array_MP_8195A_TXPWR_LMT[] + typedef enum _ODM_PW_LMT_REGULATION_TYPE{ + PW_LMT_REGU_NULL = 0, + PW_LMT_REGU_FCC = 1, + PW_LMT_REGU_ETSI = 2, + PW_LMT_REGU_MKK = 3, + PW_LMT_REGU_WW13 = 4 + }ODM_PW_LMT_REGULATION_TYPE; + + typedef enum _ODM_PW_LMT_BAND_TYPE{ + PW_LMT_BAND_NULL = 0, + PW_LMT_BAND_2_4G = 1, + PW_LMT_BAND_5G = 2 + }ODM_PW_LMT_BAND_TYPE; + + typedef enum _ODM_PW_LMT_BANDWIDTH_TYPE{ + PW_LMT_BW_NULL = 0, + PW_LMT_BW_20M = 1, + PW_LMT_BW_40M = 2, + PW_LMT_BW_80M = 3 + }ODM_PW_LMT_BANDWIDTH_TYPE; + + typedef enum _ODM_PW_LMT_RATESECTION_TYPE{ + PW_LMT_RS_NULL = 0, + PW_LMT_RS_CCK = 1, + PW_LMT_RS_OFDM = 2, + PW_LMT_RS_HT = 3, + PW_LMT_RS_VHT = 4 + }ODM_PW_LMT_RATESECTION_TYPE; + + typedef enum _ODM_PW_LMT_RFPATH_TYPE{ + PW_LMT_PH_NULL = 0, + PW_LMT_PH_1T = 1, + PW_LMT_PH_2T = 2, + PW_LMT_PH_3T = 3, + PW_LMT_PH_4T = 4 + }ODM_PW_LMT_RFPATH_TYPE; + + #if defined(CONFIG_LITTLE_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_LITTLE + #elif defined (CONFIG_BIG_ENDIAN) + #define ODM_ENDIAN_TYPE ODM_ENDIAN_BIG + #endif + +#endif + +#define READ_NEXT_PAIR(v1, v2, i) do { if (i+2 >= ArrayLen) break; i += 2; v1 = Array[i]; v2 = Array[i+1]; } while(0) +#define COND_ELSE 2 +#define COND_ENDIF 3 + +#endif // __ODM_TYPES_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rom_odm_interface.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rom_odm_interface.h new file mode 100644 index 0000000..ddf25cf --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rom_odm_interface.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#ifndef __ROM_ODM_INTERFACE_H__ +#define __ROM_ODM_INTERFACE_H__ + +#include "hal_api.h" + +// +// =========== Macro Define +// +#define ODM_Read1Byte(pDM_Odm, RegAddr) HAL_READ8(WIFI_REG_BASE, RegAddr) +#define ODM_Read2Byte(pDM_Odm, RegAddr) HAL_READ16(WIFI_REG_BASE, RegAddr) +#define ODM_Read4Byte(pDM_Odm, RegAddr) HAL_READ32(WIFI_REG_BASE, RegAddr) +#define ODM_Write1Byte(pDM_Odm, RegAddr, Data) HAL_WRITE8(WIFI_REG_BASE, RegAddr, Data) +#define ODM_Write2Byte(pDM_Odm, RegAddr, Data) HAL_WRITE16(WIFI_REG_BASE, addr, value) +#define ODM_Write4Byte(pDM_Odm, RegAddr, Data) HAL_WRITE32(WIFI_REG_BASE, addr, value) +#if (RTL8195A_SUPPORT == 1) +#define ODM_GetMACReg(pDM_Odm,RegAddr, BitMask) PHY_QueryBBReg_8195A((pDM_Odm->Adapter), (RegAddr), (BitMask)) +#define ODM_SetMACReg(pDM_Odm, RegAddr, BitMask, Data) PHY_SetBBReg_8195A((pDM_Odm->Adapter), (RegAddr), (BitMask), (Data)) +#define ODM_GetBBReg(pDM_Odm, RegAddr, BitMask) PHY_QueryBBReg_8195A((pDM_Odm->Adapter), (RegAddr), (BitMask)) +#define ODM_SetBBReg(pDM_Odm, RegAddr, BitMask, Data) PHY_SetBBReg_8195A((pDM_Odm->Adapter), (RegAddr), (BitMask), (Data)) +#endif + +#if (RTL8711B_SUPPORT ==1) +#define ODM_GetMACReg(pDM_Odm,RegAddr, BitMask) PHY_QueryBBReg_8711B((pDM_Odm->Adapter), (RegAddr), (BitMask)) +#define ODM_SetMACReg(pDM_Odm, RegAddr, BitMask, Data) PHY_SetBBReg_8711B((pDM_Odm->Adapter), (RegAddr), (BitMask), (Data)) +#define ODM_GetBBReg(pDM_Odm, RegAddr, BitMask) PHY_QueryBBReg_8711B((pDM_Odm->Adapter), (RegAddr), (BitMask)) +#define ODM_SetBBReg(pDM_Odm, RegAddr, BitMask, Data) PHY_SetBBReg_8711B((pDM_Odm->Adapter), (RegAddr), (BitMask), (Data)) +#endif +// +// =========== Extern Variable +// + +// +// =========== EXtern Function Prototype +// + + +#endif // __ROM_ODM_INTERFACE_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195ARateAdaptive.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195ARateAdaptive.h new file mode 100644 index 0000000..b6d240e --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195ARateAdaptive.h @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HALCOM_RATE_ADAPTIVE_RAM_H__ +#define __HALCOM_RATE_ADAPTIVE_RAM_H__ + +#if RATE_ADAPTIVE_SUPPORT + +/*--------------------------Define -------------------------------------------*/ + +#define FIRST_MACID 0 // This is the connection of STA to AP +// Rate index mapping +#define RATE_CCK_1M ODM_RATE1M +#define RATE_CCK_2M ODM_RATE2M +#define RATE_CCK_5M ODM_RATE5_5M +#define RATE_CCK_11M ODM_RATE11M +#define RATE_OFDM_6M ODM_RATE6M +#define RATE_OFDM_9M ODM_RATE9M +#define RATE_OFDM_12M ODM_RATE12M +#define RATE_OFDM_18M ODM_RATE18M +#define RATE_OFDM_24M ODM_RATE24M +#define RATE_OFDM_36M ODM_RATE36M +#define RATE_OFDM_48M ODM_RATE48M +#define RATE_OFDM_54M ODM_RATE54M +#define RATE_HT_MCS0 ODM_RATEMCS0 +#define RATE_HT_MCS1 ODM_RATEMCS1 +#define RATE_HT_MCS2 ODM_RATEMCS2 +#define RATE_HT_MCS3 ODM_RATEMCS3 +#define RATE_HT_MCS4 ODM_RATEMCS4 +#define RATE_HT_MCS5 ODM_RATEMCS5 +#define RATE_HT_MCS6 ODM_RATEMCS6 +#define RATE_HT_MCS7 ODM_RATEMCS7 +#define RATE_HT_MCS8 ODM_RATEMCS8 +#define RATE_HT_MCS9 ODM_RATEMCS9 +#define RATE_HT_MCS10 ODM_RATEMCS10 +#define RATE_HT_MCS11 ODM_RATEMCS11 +#define RATE_HT_MCS12 ODM_RATEMCS12 +#define RATE_HT_MCS13 ODM_RATEMCS13 +#define RATE_HT_MCS14 ODM_RATEMCS14 +#define RATE_HT_MCS15 ODM_RATEMCS15 + +#define MACID_NUM 128 + + + +// TX report format +#define TXRPT_SIZE 16 +//offset 0 +#define TXRPT_DATARATE (BIT0|BIT1|BIT2|BIT3|BIT4|BIT5|BIT6) +#define TXRPT_SGI BIT7 +//offset 1 +#define TXRPT_PWRSTS (BIT0|BIT1|BIT2) +#define TXRPT_TRYNESSCNT (BIT3|BIT4|BIT5|BIT6) +#define TXRPT_TRYRATE BIT7 +//offset 2 +#define TXRPT_TRYRESULT BIT6 +#define TXRPT_TRYFINISH BIT7 +//offset 3 +#define TXRPT_PAUSERPT BIT6 +#define TXRPT_RESETRPT BIT7 +//offset 4 + +//offset 5 +#define TXRPT_BW (BIT0|BIT1) +#define TXRPT_PKTDROP BIT2 + + + +#define RATE_UP 1 +#define RATE_DOWN 2 + +#define RSSI_TH1 45 +#define RSSI_TH2 25 + +#define PERENTRY 27 +#define RETRYSIZE 5 +#define RATESIZE 20 +#define RAMASK_SIZE 8 + +#define SS_PT_TH_High 66 +#define SS_PT_TH_low 57 +#define SS_PT_off 48 +#define SS_RA_INIT_RATE_RSSI 30 +#define STEP_DROP 1 +#define CONFIG_SGI 0 +#define TRY_WAITING 10 + +// RA mask +#define Mask_length_REG 8 +#define Rate_id_NUM 9 // 6 rate id from reg +#define ARFB_table_NUM 7 + +#define TRY_NESS_CNT_IDX_SIZE 16 + +/*------------------------------Define Enum-----------------------------------*/ +typedef enum _RTL8195_RATEID_IDX_ { + MODE_BGN_40M_2SS = 0, + MODE_BGN_40M_1SS = 1, + MODE_BGN_20M_2SS_BN = 2, + MODE_BGN_20M_1SS_BN = 3, + MODE_GN_N2SS = 4, + MODE_GN_N1SS = 5, + MODE_BG = 6, + MODE_G = 7, + MODE_B = 8 +} RTL8195_RATEID_IDX, *PRTL8195_RATEID_IDX; + +typedef enum _VHT_HT_SWITCH_ { + TYPE_HT = 0, + TYPE_VHT = 1, + TYPE_MIX1 = 2, + TYPE_MIX2 = 3 +} VHT_SEL_SWITCH, *PVHT_SEL_SWITCH; + +/*--------------------------Define MACRO--------------------------------------*/ +#define TRYING_DISABLE 0 +#define TRYING_ENABLE 1 + +//RA MASK: INIT_RATE_MASK + +//if VHT_HT_SWITCH = 1, it means VHT. +//Bit[51:12] : VHT 1SS ~ VHT 4SS +//if VHT_HT_SWITCH = 0, it means HT. +//Bit[43:12] : HT 1SS ~ HT4SS + +//offset6 +//#define VHT_HT_SWITCH BIT4 + + +// H2C CMD +//offset0 +#define H2CID13_MACID 0x7F +//offset1 +#define H2CID13_RATEID 0x1F +#define H2CID13_SGI BIT7 + + + +//offset2 +#define H2CID13_BW (BIT0|BIT1) +#define H2CID13_enldpc BIT2 +#define H2CID13_NOUPDATE BIT3 +#define H2CID13_VHT_EN (BIT5|BIT4) +#define H2CID13_DISPT BIT6 +#define H2CID13_DISRA BIT7 + +//H2C AP_Req_Tx_Rpt +#define H2CID43_RTY_OK_TOTAL BIT0 +#define H2CID43_RTY_CNT_MACID BIT1 + + +//RAInfo +#define MASK_RA_ULDL_STATE BIT0 +#define MASK_RA_STBC_STATE BIT1 +#define MASK_RA_LDPC_CAP_STATE BIT2 +#define MASK_RA_SHORTCUT_STATE BIT3 +#define MASK_RA_SHORTCUT_FLAG BIT4 +#define MASK_RA_INIT_RATE_RSSI_STATE BIT5 +#define MASK_RA_BF_STATE BIT6 +#define MASK_RA_DELAY_RATE BIT7 + + + +#define RA_ULDL_STATE_SHT 0 +#define RA_STBC_STATE_SHT 1 +#define RA_LDPC_CAP_STATE_SHT 2 +#define RA_SHORTCUT_STATE_SHT 3 +#define RA_SHORTCUT_FLAG_SHT 4 +#define RA_INIT_RATE_RSSI_SHT 5 +#define RA_BF_STATE_SHT 6 +#define RA_DELAY_RATE_SHT 7 + +/*------------------------Export global variable------------------------------*/ +//2 Rate Adaptive +//HW Statistic +//extern MEMTYPE_XDATA u16 TOTAL[MACID_NUM]; +//extern MEMTYPE_XDATA u1Byte DROP[MACID_NUM]; +//extern MEMTYPE_XDATA u16 RTY[MACID_NUM][5]; + +//extern MEMTYPE_XDATA STAINFO_RA stainfo_ra[MACID_NUM]; +//extern MEMTYPE_XDATA u16 Nsc[MACID_NUM]; +//extern MEMTYPE_XDATA u1Byte RSSI[MACID_NUM]; // add by Gary +//extern MEMTYPE_XDATA u1Byte BUPDATE[MACID_NUM]; + +/*------------------------------Function declaration--------------------------*/ +VOID +InitBBNHM( + void +); + +VOID +BBNHM( + void +); + +VOID +ODM_InitRAInfo( + IN PDM_ODM_T pDM_Odm +); + +VOID +H2CHDL_Set_MACID_Config( + IN PDM_ODM_T pDM_Odm, + IN u1Byte *pbuf +); + +VOID +H2CHDL_SetRssiSingle( + u1Byte *pbuf +); + + +VOID +H2CHDL_APReqTxrpt( + u1Byte *pbuf +); + +VOID +H2CHDL_InitRateCollect( + u1Byte *pbuf +); + + +VOID +TryDone( + IN PDM_ODM_T pDM_Odm, + IN PODM_RA_INFO_T pRaInfo +); + +VOID +RateDownTrying( + IN PDM_ODM_T pDM_Odm, + IN PODM_RA_INFO_T pRaInfo +); + +VOID +RateDecisionRAM8195A( + IN PDM_ODM_T pDM_Odm, + IN PODM_RA_INFO_T pRaInfo +); + +VOID +GetRATRfromREG( + IN u16 reg_addr, + IN u1Byte macid +); + +VOID +PHY_DM_RA_SetRSSI_8195A( + IN PDM_ODM_T pDM_Odm, + IN u1Byte MacID, + IN u1Byte Rssi + ); + +#if 0 +extern void +Rate_trying_decision( + IN u1Byte macid, + IN u1Byte rate, + IN u1Byte datarc, + IN u1Byte aggnum +); +#endif + + +//debug +VOID +ArfrRefresh( + IN PDM_ODM_T pDM_Odm, + IN PODM_RA_INFO_T pRaInfo +); + +#endif //#if CONFIG_RATE_ADAPTIVE + +#endif //#ifndef __HALCOM_RATE_ADAPTIVE_RAM_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195AReg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195AReg.h new file mode 100644 index 0000000..0ee85a6 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/Hal8195AReg.h @@ -0,0 +1,1371 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * + * Module: __INC_HAL8723BREG_H + * + * + * Note: 1. Define Mac register address and corresponding bit mask map + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * + *****************************************************************************/ +#ifndef __INC_HAL8195AREG_H +#define __INC_HAL8195AREG_H + + + +//============================================================ +// +//============================================================ + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_SYS_ISO_CTRL_8723B 0x0000 // 2 Byte +#define REG_SYS_FUNC_EN_8723B 0x0002 // 2 Byte +#define REG_APS_FSMCO_8723B 0x0004 // 4 Byte +#define REG_SYS_CLKR_8723B 0x0008 // 2 Byte +#define REG_9346CR_8723B 0x000A // 2 Byte +#define REG_EE_VPD_8723B 0x000C // 2 Byte +#define REG_AFE_MISC_8723B 0x0010 // 1 Byte +#define REG_SPS0_CTRL_8723B 0x0011 // 7 Byte +#define REG_SPS_OCP_CFG_8723B 0x0018 // 4 Byte +#define REG_RSV_CTRL_8723B 0x001C // 3 Byte +#define REG_RF_CTRL_8723B 0x001F // 1 Byte +#define REG_LPLDO_CTRL_8723B 0x0023 // 1 Byte +#define REG_AFE_XTAL_CTRL_8723B 0x0024 // 4 Byte +#define REG_AFE_PLL_CTRL_8723B 0x0028 // 4 Byte +#define REG_MAC_PLL_CTRL_EXT_8723B 0x002c // 4 Byte +#define REG_EFUSE_CTRL_8723B 0x0030 +#define REG_EFUSE_TEST_8723B 0x0034 +#define REG_PWR_DATA_8723B 0x0038 +#define REG_CAL_TIMER_8723B 0x003C +#define REG_ACLK_MON_8723B 0x003E +#define REG_GPIO_MUXCFG_8723B 0x0040 +#define REG_GPIO_IO_SEL_8723B 0x0042 +#define REG_MAC_PINMUX_CFG_8723B 0x0043 +#define REG_GPIO_PIN_CTRL_8723B 0x0044 +#define REG_GPIO_INTM_8723B 0x0048 +#define REG_LEDCFG0_8723B 0x004C +#define REG_LEDCFG1_8723B 0x004D +#define REG_LEDCFG2_8723B 0x004E +#define REG_LEDCFG3_8723B 0x004F +#define REG_FSIMR_8723B 0x0050 +#define REG_FSISR_8723B 0x0054 +#define REG_HSIMR_8723B 0x0058 +#define REG_HSISR_8723B 0x005c +#define REG_GPIO_EXT_CTRL 0x0060 +#define REG_MULTI_FUNC_CTRL_8723B 0x0068 +#define REG_GPIO_STATUS_8723B 0x006C +#define REG_SDIO_CTRL_8723B 0x0070 +#define REG_OPT_CTRL_8723B 0x0074 +#define REG_AFE_XTAL_CTRL_EXT_8723B 0x0078 +#define REG_MCUFWDL_8723B 0x0080 +#define REG_BT_PATCH_STATUS_8723B 0x0088 +#define REG_HIMR0_8723B 0x00B0 +#define REG_HISR0_8723B 0x00B4 +#define REG_HIMR1_8723B 0x00B8 +#define REG_HISR1_8723B 0x00BC +#define REG_PMC_DBG_CTRL2_8723B 0x00CC +#define REG_EFUSE_BURN_GNT_8723B 0x00CF +#define REG_HPON_FSM_8723B 0x00EC +#define REG_SYS_CFG_8723B 0x00F0 +#define REG_SYS_CFG1_8723B 0x00FC +#define REG_ROM_VERSION 0x00FD + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_CR_8723B 0x0100 +#define REG_PBP_8723B 0x0104 +#define REG_PKT_BUFF_ACCESS_CTRL_8723B 0x0106 +#define REG_TRXDMA_CTRL_8723B 0x010C +#define REG_TRXFF_BNDY_8723B 0x0114 +#define REG_TRXFF_STATUS_8723B 0x0118 +#define REG_RXFF_PTR_8723B 0x011C +#define REG_CPWM_8723B 0x012F +#define REG_FWIMR_8723B 0x0130 +#define REG_FWISR_8723B 0x0134 +#define REG_FTIMR_8723B 0x0138 +#define REG_PKTBUF_DBG_CTRL_8723B 0x0140 +#define REG_RXPKTBUF_CTRL_8723B 0x0142 +#define REG_PKTBUF_DBG_DATA_L_8723B 0x0144 +#define REG_PKTBUF_DBG_DATA_H_8723B 0x0148 + +#define REG_TC0_CTRL_8723B 0x0150 +#define REG_TC1_CTRL_8723B 0x0154 +#define REG_TC2_CTRL_8723B 0x0158 +#define REG_TC3_CTRL_8723B 0x015C +#define REG_TC4_CTRL_8723B 0x0160 +#define REG_TCUNIT_BASE_8723B 0x0164 +#define REG_RSVD3_8723B 0x0168 +#define REG_C2HEVT_MSG_NORMAL_8723B 0x01A0 +#define REG_C2HEVT_CMD_SEQ_88XX 0x01A1 +#define REG_C2hEVT_CMD_CONTENT_88XX 0x01A2 +#define REG_C2HEVT_CMD_LEN_88XX 0x01AE +#define REG_C2HEVT_CLEAR_8723B 0x01AF +#define REG_MCUTST_1_8723B 0x01C0 +#define REG_MCUTST_WOWLAN_8723B 0x01C7 +#define REG_FMETHR_8723B 0x01C8 +#define REG_HMETFR_8723B 0x01CC +#define REG_HMEBOX_0_8723B 0x01D0 +#define REG_HMEBOX_1_8723B 0x01D4 +#define REG_HMEBOX_2_8723B 0x01D8 +#define REG_HMEBOX_3_8723B 0x01DC +#define REG_LLT_INIT_8723B 0x01E0 +#define REG_HMEBOX_EXT0_8723B 0x01F0 +#define REG_HMEBOX_EXT1_8723B 0x01F4 +#define REG_HMEBOX_EXT2_8723B 0x01F8 +#define REG_HMEBOX_EXT3_8723B 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +#define REG_RQPN_8723B 0x0200 +#define REG_FIFOPAGE_8723B 0x0204 +#define REG_TDECTRL_8723B 0x0208 +#define REG_TXDMA_OFFSET_CHK_8723B 0x020C +#define REG_TXDMA_STATUS_8723B 0x0210 +#define REG_RQPN_NPQ_8723B 0x0214 +#define REG_TDECTRL1_8195A 0x0228 + + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_AGG_PG_TH_8723B 0x0280 +#define REG_FW_UPD_RDPTR_8723B 0x0284 // FW shall update this register before FW write RXPKT_RELEASE_POLL to 1 +#define REG_RXDMA_CONTROL_8723B 0x0286 // Control the RX DMA. +#define REG_RXPKT_NUM_8723B 0x0287 // The number of packets in RXPKTBUF. +#define REG_RXDMA_STATUS_8723B 0x0288 +#define REG_RXDMA_PRO_8723B 0x0290 +#define REG_EARLY_MODE_CONTROL_8723B 0x02BC +#define REG_RSVD5_8723B 0x02F0 +#define REG_RSVD6_8723B 0x02F4 + + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- +#define REG_PCIE_CTRL_REG_8723B 0x0300 +#define REG_INT_MIG_8723B 0x0304 // Interrupt Migration +#define REG_BCNQ_DESA_8723B 0x0308 // TX Beacon Descriptor Address +#define REG_HQ_DESA_8723B 0x0310 // TX High Queue Descriptor Address +#define REG_MGQ_DESA_8723B 0x0318 // TX Manage Queue Descriptor Address +#define REG_VOQ_DESA_8723B 0x0320 // TX VO Queue Descriptor Address +#define REG_VIQ_DESA_8723B 0x0328 // TX VI Queue Descriptor Address +#define REG_BEQ_DESA_8723B 0x0330 // TX BE Queue Descriptor Address +#define REG_BKQ_DESA_8723B 0x0338 // TX BK Queue Descriptor Address +#define REG_RX_DESA_8723B 0x0340 // RX Queue Descriptor Address +#define REG_DBI_WDATA_8723B 0x0348 // DBI Write Data +#define REG_DBI_RDATA_8723B 0x034C // DBI Read Data +#define REG_DBI_ADDR_8723B 0x0350 // DBI Address +#define REG_DBI_FLAG_8723B 0x0352 // DBI Read/Write Flag +#define REG_MDIO_WDATA_8723B 0x0354 // MDIO for Write PCIE PHY +#define REG_MDIO_RDATA_8723B 0x0356 // MDIO for Reads PCIE PHY +#define REG_MDIO_CTL_8723B 0x0358 // MDIO for Control +#define REG_DBG_SEL_8723B 0x0360 // Debug Selection Register +#define REG_PCIE_HRPWM_8723B 0x0361 //PCIe RPWM +#define REG_PCIE_HCPWM_8723B 0x0363 //PCIe CPWM +#define REG_PCIE_MULTIFET_CTRL_8723B 0x036A //PCIE Multi-Fethc Control + + +// spec version 11 +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_VOQ_INFORMATION_8723B 0x0400 +#define REG_VIQ_INFORMATION_8723B 0x0404 +#define REG_BEQ_INFORMATION_8723B 0x0408 +#define REG_BKQ_INFORMATION_8723B 0x040C +#define REG_MGQ_INFORMATION_8723B 0x0410 +#define REG_HGQ_INFORMATION_8723B 0x0414 +#define REG_BCNQ_INFORMATION_8723B 0x0418 +#define REG_TXPKT_EMPTY_8723B 0x041A + +#define REG_FWHW_TXQ_CTRL_8723B 0x0420 +#define REG_HWSEQ_CTRL_8723B 0x0423 +#define REG_TXPKTBUF_BCNQ_BDNY_8723B 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8723B 0x0425 +#define REG_LIFECTRL_CTRL_8723B 0x0426 +#define REG_MULTI_BCNQ_OFFSET_8723B 0x0427 +#define REG_SPEC_SIFS_8723B 0x0428 +#define REG_RL_8723B 0x042A +#define REG_TXBF_CTRL_8723B 0x042C +#define REG_DARFRC_8723B 0x0430 +#define REG_RARFRC_8723B 0x0438 +#define REG_RRSR_8723B 0x0440 +#define REG_ARFR0_8723B 0x0444 +#define REG_ARFR1_8723B 0x044C +#define REG_CCK_CHECK_8723B 0x0454 +#define REG_AMPDU_MAX_TIME_8723B 0x0456 +#define REG_TXPKTBUF_BCNQ_BDNY1_8723B 0x0457 + +#define REG_AMPDU_MAX_LENGTH_8195A 0x0458 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8723B 0x045D +#define REG_NDPA_OPT_CTRL_8723B 0x045F +#define REG_FAST_EDCA_CTRL_8723B 0x0460 +#define REG_RD_RESP_PKT_TH_8723B 0x0463 +#define REG_SPC_W_PTR 0x47E +#define REG_SPC_R_PTR 0x47F +#define REG_DATA_SC_8723B 0x0483 +#define REG_TXRPT_START_OFFSET 0x04AC +#define REG_POWER_STAGE1_8723B 0x04B4 +#define REG_POWER_STAGE2_8723B 0x04B8 +#define REG_AMPDU_BURST_MODE_8723B 0x04BC +#define REG_PKT_VO_VI_LIFE_TIME_8723B 0x04C0 +#define REG_PKT_BE_BK_LIFE_TIME_8723B 0x04C2 +#define REG_STBC_SETTING_8723B 0x04C4 +#define REG_HT_SINGLE_AMPDU_8723B 0x04C7 +#define REG_PROT_MODE_CTRL_8723B 0x04C8 +#define REG_MAX_AGGR_NUM_8723B 0x04CA +#define REG_RTS_MAX_AGGR_NUM_8723B 0x04CB +#define REG_BAR_MODE_CTRL_8723B 0x04CC +#define REG_RA_TRY_RATE_AGG_LMT_8723B 0x04CF +#define REG_MACID_PKT_DROP0_8723B 0x04D0 + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_EDCA_VO_PARAM_8723B 0x0500 +#define REG_EDCA_VI_PARAM_8723B 0x0504 +#define REG_EDCA_BE_PARAM_8723B 0x0508 +#define REG_EDCA_BK_PARAM_8723B 0x050C +#define REG_BCNTCFG_8723B 0x0510 +#define REG_PIFS_8723B 0x0512 +#define REG_RDG_PIFS_8723B 0x0513 +#define REG_SIFS_CTX_8723B 0x0514 +#define REG_SIFS_TRX_8723B 0x0516 +#define REG_AGGR_BREAK_TIME_8723B 0x051A +#define REG_SLOT_8723B 0x051B +#define REG_TX_PTCL_CTRL_8723B 0x0520 +#define REG_TXPAUSE_8723B 0x0522 +#define REG_DIS_TXREQ_CLR_8723B 0x0523 +#define REG_RD_CTRL_8723B 0x0524 +// +// Format for offset 540h-542h: +// [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting beacon content before TBTT. +// [7:4]: Reserved. +// [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding to send the beacon packet. +// [23:20]: Reserved +// Description: +// | +// |<--Setup--|--Hold------------>| +// --------------|---------------------- +// | +// TBTT +// Note: We cannot update beacon content to HW or send any AC packets during the time between Setup and Hold. +// Described by Designer Tim and Bruce, 2011-01-14. +// +#define REG_TBTT_PROHIBIT_8723B 0x0540 +#define REG_RD_NAV_NXT_8723B 0x0544 +#define REG_NAV_PROT_LEN_8723B 0x0546 +#define REG_BCN_CTRL_8723B 0x0550 +#define REG_BCN_CTRL_1_8723B 0x0551 +#define REG_MBID_NUM_8723B 0x0552 +#define REG_DUAL_TSF_RST_8723B 0x0553 +#define REG_BCN_INTERVAL_8723B 0x0554 +#define REG_DRVERLYINT_8723B 0x0558 +#define REG_BCNDMATIM_8723B 0x0559 +#define REG_ATIMWND_8723B 0x055A +#define REG_USTIME_TSF_8723B 0x055C +#define REG_BCN_MAX_ERR_8723B 0x055D +#define REG_RXTSF_OFFSET_CCK_8723B 0x055E +#define REG_RXTSF_OFFSET_OFDM_8723B 0x055F +#define REG_TSFTR_8723B 0x0560 +#define REG_CTWND_8723B 0x0572 +#define REG_BCNIVLCUNT_8723B 0x0573 +#define REG_SECONDARY_CCA_CTRL_8723B 0x0577 +#define REG_PSTIMER_8723B 0x0580 +#define REG_TIMER0_8723B 0x0584 +#define REG_TIMER1_8723B 0x0588 +#define REG_ACMHWCTRL_8723B 0x05C0 +#define REG_SCH_TXCMD_8723B 0x05F8 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- +#define REG_MAC_CR_8723B 0x0600 +#define REG_TCR_8723B 0x0604 +#define REG_RCR_8723B 0x0608 +#define REG_RX_PKT_LIMIT_8723B 0x060C +#define REG_RX_DLK_TIME_8723B 0x060D +#define REG_RX_DRVINFO_SZ_8723B 0x060F + +#define REG_MACID_8723B 0x0610 +#define REG_BSSID_8723B 0x0618 +#define REG_MAR_8723B 0x0620 +#define REG_MBIDCAMCFG_8723B 0x0628 + +#define REG_USTIME_EDCA_8723B 0x0638 +#define REG_MAC_SPEC_SIFS_8723B 0x063A +#define REG_RESP_SIFP_CCK_8723B 0x063C +#define REG_RESP_SIFS_OFDM_8723B 0x063E +#define REG_ACKTO_8723B 0x0640 +#define REG_CTS2TO_8723B 0x0641 +#define REG_EIFS_8723B 0x0642 + +#define REG_NAV_UPPER_8723B 0x0652 // unit of 128 +#define REG_RTR_8723B 0x0662 +#define REG_TRXPTCL_CTL_8723B 0x0668 + +// Security +#define REG_CAMCMD_8723B 0x0670 +#define REG_CAMWRITE_8723B 0x0674 +#define REG_CAMREAD_8723B 0x0678 +#define REG_CAMDBG_8723B 0x067C +#define REG_SECCFG_8723B 0x0680 + +// Power +#define REG_WOW_CTRL_8723B 0x0690 +#define REG_PS_RX_INFO_8723B 0x0692 +#define REG_UAPSD_TID_8723B 0x0693 +#define REG_WKFMCAM_CMD_8723B 0x0698 +#define REG_WKFMCAM_NUM_8723B 0x0698 +#define REG_WKFMCAM_RWD_8723B 0x069C +#define REG_RXFLTMAP0_8723B 0x06A0 +#define REG_RXFLTMAP1_8723B 0x06A2 +#define REG_RXFLTMAP2_8723B 0x06A4 +#define REG_BCN_PSR_RPT_8723B 0x06A8 +#define REG_BT_COEX_TABLE_8723B 0x06C0 +#define REG_BFMER0_INFO_8723B 0x06E4 +#define REG_BFMER1_INFO_8723B 0x06EC +#define REG_CSI_RPT_PARAM_BW20_8723B 0x06F4 +#define REG_CSI_RPT_PARAM_BW40_8723B 0x06F8 +#define REG_CSI_RPT_PARAM_BW80_8723B 0x06FC + +// Hardware Port 2 +#define REG_MACID1_8723B 0x0700 +#define REG_BSSID1_8723B 0x0708 +#define REG_BFMEE_SEL_8723B 0x0714 +#define REG_SND_PTCL_CTRL_8723B 0x0718 + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +/* +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + + +// For normal chip +#define REG_NORMAL_SIE_VID 0xFE60 // 0xFE60~0xFE61 +#define REG_NORMAL_SIE_PID 0xFE62 // 0xFE62~0xFE63 +#define REG_NORMAL_SIE_OPTIONAL 0xFE64 +#define REG_NORMAL_SIE_EP 0xFE65 // 0xFE65~0xFE67 +#define REG_NORMAL_SIE_PHY 0xFE68 // 0xFE68~0xFE6B +#define REG_NORMAL_SIE_OPTIONAL2 0xFE6C +#define REG_NORMAL_SIE_GPS_EP 0xFE6D // 0xFE6D, for RTL8723 only. +#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 // 0xFE70~0xFE75 +#define REG_NORMAL_SIE_STRING 0xFE80 // 0xFE80~0xFEDF +*/ + +//----------------------------------------------------- +// +// Redifine 8192C register definition for compatibility +// +//----------------------------------------------------- + +// TODO: use these definition when using REG_xxx naming rule. +// NOTE: DO NOT Remove these definition. Use later. +#define EFUSE_CTRL_8723B REG_EFUSE_CTRL_8723B // E-Fuse Control. +#define EFUSE_TEST_8723B REG_EFUSE_TEST_8723B // E-Fuse Test. +#define MSR_8723B (REG_CR_8723B + 2) // Media Status register +#define ISR_8723B REG_HISR0_8723B +#define TSFR_8723B REG_TSFTR_8723B // Timing Sync Function Timer Register. + +#define PBP_8723B REG_PBP_8723B + +// Redifine MACID register, to compatible prior ICs. +#define IDR0_8723B REG_MACID_8723B // MAC ID Register, Offset 0x0050-0x0053 +#define IDR4_8723B (REG_MACID_8723B + 4) // MAC ID Register, Offset 0x0054-0x0055 + + +// +// 9. Security Control Registers (Offset: ) +// +#define RWCAM_8723B REG_CAMCMD_8723B //IN 8190 Data Sheet is called CAMcmd +#define WCAMI_8723B REG_CAMWRITE_8723B // Software write CAM input content +#define RCAMO_8723B REG_CAMREAD_8723B // Software read/write CAM config +#define CAMDBG_8723B REG_CAMDBG_8723B +#define SECR_8723B REG_SECCFG_8723B //Security Configuration Register + +/* + +// Unused register +#define UnusedRegister 0x1BF +#define DCAM UnusedRegister +#define PSR UnusedRegister +#define BBAddr UnusedRegister +#define PhyDataR UnusedRegister + + + +//---------------------------------------------------------------------------- +// 8192C Cmd9346CR bits (Offset 0xA, 16bit) +//---------------------------------------------------------------------------- +#define CmdEEPROM_En BIT5 // EEPROM enable when set 1 +#define CmdEERPOMSEL BIT4 // System EEPROM select, 0: boot from E-FUSE, 1: The EEPROM used is 9346 +#define Cmd9346CR_9356SEL BIT4 + +//---------------------------------------------------------------------------- +// 8192C GPIO MUX Configuration Register (offset 0x40, 4 byte) +//---------------------------------------------------------------------------- +#define GPIOSEL_GPIO BIT0 +#define GPIOSEL_ENBT BIT5 + +//---------------------------------------------------------------------------- +// 8192C GPIO PIN Control Register (offset 0x44, 4 byte) +//---------------------------------------------------------------------------- +#define GPIO_IN REG_GPIO_PIN_CTRL_8195 // GPIO pins input value +#define GPIO_OUT (REG_GPIO_PIN_CTRL_8195+1) // GPIO pins output value +#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL_8195+2) // GPIO pins output enable when a bit is set to "1"; otherwise, input is configured. +#define GPIO_MOD (REG_GPIO_PIN_CTRL_8195+3) +#define HAL_8192C_HW_GPIO_WPS_BIT BIT2 + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Mask Register (offset 0x58, 32 byte) +//---------------------------------------------------------------------------- +#define HSIMR_GPIO12_0_INT_EN BIT0 +#define HSIMR_SPS_OCP_INT_EN BIT5 +#define HSIMR_RON_INT_EN BIT6 +#define HSIMR_PDN_INT_EN BIT7 +#define HSIMR_GPIO9_INT_EN BIT25 + + +//---------------------------------------------------------------------------- +// 8723/8188E Host System Interrupt Status Register (offset 0x5C, 32 byte) +//---------------------------------------------------------------------------- +#define HSISR_GPIO12_0_INT BIT0 +#define HSISR_SPS_OCP_INT BIT5 +#define HSISR_RON_INT_EN BIT6 +#define HSISR_PDNINT BIT7 +#define HSISR_GPIO9_INT BIT25 + +//---------------------------------------------------------------------------- +// 8195 (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + +//---------------------------------------------------------------------------- +// 88EU (MSR) Media Status Register (Offset 0x4C, 8 bits) +//---------------------------------------------------------------------------- +#define USB_INTR_CONTENT_HISR_OFFSET 48 +#define USB_INTR_CONTENT_HISRE_OFFSET 52 + + +// +// 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) +// +//---------------------------------------------------------------------------- +// 8192C Response Rate Set Register (offset 0x181, 24bits) +//---------------------------------------------------------------------------- +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 + + +//---------------------------------------------------------------------------- +// 8192C Response Rate Set Register (offset 0x1BF, 8bits) +//---------------------------------------------------------------------------- +// WOL bit information +#define HAL92C_WOL_PTK_UPDATE_EVENT BIT0 +#define HAL92C_WOL_GTK_UPDATE_EVENT BIT1 + + +//---------------------------------------------------------------------------- +// 8192C Rate Definition +//---------------------------------------------------------------------------- +//CCK +#define RATR_1M 0x00000001 +#define RATR_2M 0x00000002 +#define RATR_55M 0x00000004 +#define RATR_11M 0x00000008 +//OFDM +#define RATR_6M 0x00000010 +#define RATR_9M 0x00000020 +#define RATR_12M 0x00000040 +#define RATR_18M 0x00000080 +#define RATR_24M 0x00000100 +#define RATR_36M 0x00000200 +#define RATR_48M 0x00000400 +#define RATR_54M 0x00000800 +//MCS 1 Spatial Stream +#define RATR_MCS0 0x00001000 +#define RATR_MCS1 0x00002000 +#define RATR_MCS2 0x00004000 +#define RATR_MCS3 0x00008000 +#define RATR_MCS4 0x00010000 +#define RATR_MCS5 0x00020000 +#define RATR_MCS6 0x00040000 +#define RATR_MCS7 0x00080000 +//MCS 2 Spatial Stream +#define RATR_MCS8 0x00100000 +#define RATR_MCS9 0x00200000 +#define RATR_MCS10 0x00400000 +#define RATR_MCS11 0x00800000 +#define RATR_MCS12 0x01000000 +#define RATR_MCS13 0x02000000 +#define RATR_MCS14 0x04000000 +#define RATR_MCS15 0x08000000 + + +// NOTE: For 92CU - Ziv +//CCK +#define RATE_1M BIT(0) +#define RATE_2M BIT(1) +#define RATE_5_5M BIT(2) +#define RATE_11M BIT(3) +//OFDM +#define RATE_6M BIT(4) +#define RATE_9M BIT(5) +#define RATE_12M BIT(6) +#define RATE_18M BIT(7) +#define RATE_24M BIT(8) +#define RATE_36M BIT(9) +#define RATE_48M BIT(10) +#define RATE_54M BIT(11) +//MCS 1 Spatial Stream +#define RATE_MCS0 BIT(12) +#define RATE_MCS1 BIT(13) +#define RATE_MCS2 BIT(14) +#define RATE_MCS3 BIT(15) +#define RATE_MCS4 BIT(16) +#define RATE_MCS5 BIT(17) +#define RATE_MCS6 BIT(18) +#define RATE_MCS7 BIT(19) +//MCS 2 Spatial Stream +#define RATE_MCS8 BIT(20) +#define RATE_MCS9 BIT(21) +#define RATE_MCS10 BIT(22) +#define RATE_MCS11 BIT(23) +#define RATE_MCS12 BIT(24) +#define RATE_MCS13 BIT(25) +#define RATE_MCS14 BIT(26) +#define RATE_MCS15 BIT(27) + + + + +// ALL CCK Rate +#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M +#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|\ + RATR_36M|RATR_48M|RATR_54M +#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 |\ + RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 +#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11|\ + RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 + +#define RATE_BITMAP_ALL 0xFFFFF + +// Only use CCK 1M rate for ACK +#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 +//---------------------------------------------------------------------------- +// 8192C BW_OPMODE bits (Offset 0x203, 8bit) +//---------------------------------------------------------------------------- +#define BW_OPMODE_20MHZ BIT2 +#define BW_OPMODE_5G BIT1 + +// +// 10. Power Save Control Registers (Offset: 0x0260 - 0x02DF) +// +#define WOW_PMEN BIT0 // Power management Enable. +#define WOW_WOMEN BIT1 // WoW function on or off. +#define WOW_MAGIC BIT2 // Magic packet +#define WOW_UWF BIT3 // Unicast Wakeup frame. + +*/ + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0x80, 8bits) +//---------------------------------------------------------------------------- +#define IMR_WL_FTINT_MSK_8195A BIT31 //The interrupt mask from WL page 1 interrupt source +#define IMR_TSF_BIT32_TOGGLE_MSK_V1_8195A BIT10 //Enable TSF_BIT32_TOGGLE interrupt source +#define IMR_P2P_RFOFF_INT_MSK_8195A BIT9 //P2P NoA RF off time indication interrupt mask +#define IMR_P2P_RFON_INT_MSK_8195A BIT8 //P2P NoA RF on time indication interrupt mask +#define IMR_PSTIMER_MSK_8195A BIT6 //Enable PSTimer interrupt source +#define IMR_TIMEOUT1_MSK_8195A BIT5 //Enable Timer1 interrupt source +#define IMR_TIMEOUT0_MSK_8195A BIT4 //Enable Timer0 interrupt source +#define IMR_MTI_BCNIVLEAR_INT_MSK_8195A BIT1 //Enable MTI_BCNIVLEAR _INT +#define IMR_BCNERLY_MSK_8195A BIT0 //This interrupt is issued at the time set by DRVERLYINT register before TBTT time. + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0x134, 8bits) +//---------------------------------------------------------------------------- +#define IMR_SOUND_DONE_MSK_8195A BIT30 //Be a beamformer, this interrupt is issued at the time after sounding finish +#define IMR_TRY_DONE_MSK_8195A BIT29 //When TRY_FINISH is deasserted, this interrupt is issued to inform MCU +#define IMR_TXRPT_CNT_FULL_MSK_8195A BIT28 +#define IMR_WLACTOFF_INT_EN_8195A BIT27 +#define IMR_WLACTON_INT_EN_8195A BIT26 +#define IMR_TXPKTIN_INT_EN_8195A BIT25 +#define IMR_TXBCN0OK_8195A BIT24 // Transmit Beacon0 OK +#define IMR_TXBCN0ERR_8195A BIT23 // Transmit Beacon0 Error +#define IMR_RX_UMD0_EN_8195A BIT22 +#define IMR_RX_UMD1_EN_8195A BIT21 +#define IMR_RX_BMD0_EN_8195A BIT20 +#define IMR_RX_BMD1_EN_8195A BIT19 +#define IMR_BCN_RX_INT_EN_8195A BIT18 +#define IMR_TBTTINT_MSK_8195A BIT17 + +#define IMR_BCNDMA7_MSK_8195A BIT15 //When BCNDMA interval arrives before TBTT7, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA6_MSK_8195A BIT14 //When BCNDMA interval arrives before TBTT6, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA5_MSK_8195A BIT13 //When BCNDMA interval arrives before TBTT5, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA4_MSK_8195A BIT12 //When BCNDMA interval arrives before TBTT4, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA3_MSK_8195A BIT11 //When BCNDMA interval arrives before TBTT3, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA2_MSK_8195A BIT10 //When BCNDMA interval arrives before TBTT2, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA1_MSK_8195A BIT9 //When BCNDMA interval arrives before TBTT1, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_BCNDMA0_MSK_8195A BIT8 //When BCNDMA interval arrives before TBTT0, + //this interrupt informs MCU to prepare related beacon tasks. +#define IMR_STBY_MSK_8195A BIT7 //Lower Power Standby Interrupt mask +#define IMR_CTWEndINT_MSK_8195A BIT6 //This bit masks the CTWindow End interrupt. +#define IMR_TXFOVW_MSK_8195A BIT5 //"Transmit packet buffer Overflow.This bit is set to 1 when one or more of the hardware transmit queues is full" +#define IMR_FOVW_MSK_8195A BIT4 //"Rx packet buffer OverflowSet this bit to one when Rx packet buffer write pointer hits read pointer. " +#define IMR_RXDONE_MSK_8195A BIT3 //Rx Packet done for 8051 +#define IMR_ERRORHDL_MSK_8195A BIT2 //FWHW/ TXDMA/ RXDMA/ WMAC error status interrupt +#define IMR_TXCCX_MSK_FW_8195A BIT1 //CCX PKT TX Report Interrupt +#define IMR_TXCLOSE_MSK_8195A BIT0 //TX Finish (Ack/BA process Finish) Interrupt. + + +//---------------------------------------------------------------------------- +// 8195 IMR/ISR bits (offset 0x3EC, 8bits) +//---------------------------------------------------------------------------- +#define IMR_BCNDERR7_8195A BIT31 // Beacon Queue DMA Error +#define IMR_BCNDERR6_8195A BIT30 // Beacon Queue DMA Error +#define IMR_BCNDERR5_8195A BIT29 // Beacon Queue DMA Error +#define IMR_BCNDERR4_8195A BIT28 // Beacon Queue DMA Error +#define IMR_BCNDERR3_8195A BIT27 // Beacon Queue DMA Error +#define IMR_BCNDERR2_8195A BIT26 // Beacon Queue DMA Error +#define IMR_BCNDERR1_8195A BIT25 // Beacon Queue DMA Error +#define IMR_BCNDERR0_8195A BIT24 // Beacon Queue DMA Error +#define IMR_BCNDMAOK7_8195A BIT23 // Beacon DMA OK Interrupt 7 +#define IMR_BCNDMAOK6_8195A BIT22 // Beacon DMA OK Interrupt 6 +#define IMR_BCNDMAOK5_8195A BIT21 // Beacon DMA OK Interrupt 5 +#define IMR_BCNDMAOK4_8195A BIT20 // Beacon DMA OK Interrupt 4 +#define IMR_BCNDMAOK3_8195A BIT19 // Beacon DMA OK Interrupt 3 +#define IMR_BCNDMAOK2_8195A BIT18 // Beacon DMA OK Interrupt 2 +#define IMR_BCNDMAOK1_8195A BIT17 // Beacon DMA OK Interrupt 1 +#define IMR_BCNDMAOK0_8195A BIT16 // Beacon DMA OK Interrupt 0 +#define IMR_H7DOK_8195A BIT15 // High Queue DMA OK Interrup 7 +#define IMR_H6DOK_8195A BIT14 // High Queue DMA OK Interrup 6 +#define IMR_H5DOK_8195A BIT13 // High Queue DMA OK Interrup 5 +#define IMR_H4DOK_8195A BIT12 // High Queue DMA OK Interrup 4 +#define IMR_H3DOK_8195A BIT11 // High Queue DMA OK Interrup 3 +#define IMR_H2DOK_8195A BIT10 // High Queue DMA OK Interrup 2 +#define IMR_H1DOK_8195A BIT9 // High Queue DMA OK Interrup 1 +#define IMR_H0DOK_8195A BIT8 // High Queue DMA OK Interrup 1 +#define IMR_MGNTDOK_8195A BIT6 // Management Queue DMA OK +#define IMR_BKDOK_8195A BIT5 // AC_BK DMA OK +#define IMR_BEDOK_8195A BIT4 // AC_BE DMA OK +#define IMR_VIDOK_8195A BIT3 // AC_VI DMA OK +#define IMR_VODOK_8195A BIT2 // AC_VO DMA OK +#define IMR_RDU_8195A BIT1 // Rx Descriptor Unavailable +#define IMR_ROK_8195A BIT0 // Receive DMA OK + + + + + + + +/*=================================================================== +===================================================================== +Here the register defines are for 92C. When the define is as same with 92C, +we will use the 92C's define for the consistency +So the following defines for 92C is not entire!!!!!! +===================================================================== +=====================================================================*/ +/* +Based on Datasheet V33---090401 +Register Summary +Current IOREG MAP +0x0000h ~ 0x00FFh System Configuration (256 Bytes) +0x0100h ~ 0x01FFh MACTOP General Configuration (256 Bytes) +0x0200h ~ 0x027Fh TXDMA Configuration (128 Bytes) +0x0280h ~ 0x02FFh RXDMA Configuration (128 Bytes) +0x0300h ~ 0x03FFh PCIE EMAC Reserved Region (256 Bytes) +0x0400h ~ 0x04FFh Protocol Configuration (256 Bytes) +0x0500h ~ 0x05FFh EDCA Configuration (256 Bytes) +0x0600h ~ 0x07FFh WMAC Configuration (512 Bytes) +0x2000h ~ 0x3FFFh 8051 FW Download Region (8196 Bytes) +*/ +//---------------------------------------------------------------------------- +// 8195 (TXPAUSE) transmission pause (Offset 0x522, 8 bits) +//---------------------------------------------------------------------------- +/* +#define StopBecon BIT6 +#define StopHigh BIT5 +#define StopMgt BIT4 +#define StopVO BIT3 +#define StopVI BIT2 +#define StopBE BIT1 +#define StopBK BIT0 +*/ + + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h USB Configuration +// +//----------------------------------------------------- +/*#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + +#define REG_USB_HRPWM 0xFE58 +#define REG_USB_HCPWM 0xFE57 + +//2 USB Information (0xFE17) +#define USB_IS_HIGH_SPEED 0 +#define USB_IS_FULL_SPEED 1 +#define USB_SPEED_MASK BIT(5) + +#define USB_NORMAL_SIE_EP_MASK 0xF +#define USB_NORMAL_SIE_EP_SHIFT 4 + +//2 Special Option +#define USB_AGG_EN BIT(3) + +*/ +//============================================================================ +// 8192C Regsiter Bit and Content definition +//============================================================================ +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +/* +//2 SYS_ISO_CTRL +#define ISO_MD2PP BIT(0) +#define ISO_UA2USB BIT(1) +#define ISO_UD2CORE BIT(2) +#define ISO_PA2PCIE BIT(3) +#define ISO_PD2CORE BIT(4) +#define ISO_IP2MAC BIT(5) +#define ISO_DIOP BIT(6) +#define ISO_DIOE BIT(7) +#define ISO_EB2CORE BIT(8) +#define ISO_DIOR BIT(9) +#define PWC_EV12V BIT(15) + + +//2 SYS_FUNC_EN +#define FEN_BBRSTB BIT(0) +#define FEN_BB_GLB_RSTn BIT(1) +#define FEN_USBA BIT(2) +#define FEN_UPLL BIT(3) +#define FEN_USBD BIT(4) +#define FEN_DIO_PCIE BIT(5) +#define FEN_PCIEA BIT(6) +#define FEN_PPLL BIT(7) +#define FEN_PCIED BIT(8) +#define FEN_DIOE BIT(9) +#define FEN_CPUEN BIT(10) +#define FEN_DCORE BIT(11) +#define FEN_ELDR BIT(12) +#define FEN_DIO_RF BIT(13) +#define FEN_HWPDN BIT(14) +#define FEN_MREGEN BIT(15) + +//2 APS_FSMCO +#define PFM_LDALL BIT(0) +#define PFM_ALDN BIT(1) +#define PFM_LDKP BIT(2) +#define PFM_WOWL BIT(3) +#define EnPDN BIT(4) +#define PDN_PL BIT(5) +#define APFM_ONMAC BIT(8) +#define APFM_OFF BIT(9) +#define APFM_RSM BIT(10) +#define AFSM_HSUS BIT(11) +#define AFSM_PCIE BIT(12) +#define APDM_MAC BIT(13) +#define APDM_HOST BIT(14) +#define APDM_HPDN BIT(15) +#define RDY_MACON BIT(16) +#define SUS_HOST BIT(17) +#define ROP_ALD BIT(20) +#define ROP_PWR BIT(21) +#define ROP_SPS BIT(22) +#define SOP_MRST BIT(25) +#define SOP_FUSE BIT(26) +#define SOP_ABG BIT(27) +#define SOP_AMB BIT(28) +#define SOP_RCK BIT(29) +#define SOP_A8M BIT(30) +#define XOP_BTCK BIT(31) + +//2 SYS_CLKR +#define ANAD16V_EN BIT(0) +#define ANA8M BIT(1) +#define MACSLP BIT(4) +#define LOADER_CLK_EN BIT(5) + + +//2 9346CR + +#define BOOT_FROM_EEPROM BIT(4) +#define EEPROM_EN BIT(5) + + +//2 RF_CTRL +#define RF_EN BIT(0) +#define RF_RSTB BIT(1) +#define RF_SDMRSTB BIT(2) + +//2 LDOV12D_CTRL +#define LDV12_EN BIT(0) +#define LDV12_SDBY BIT(1) +#define LPLDO_HSM BIT(2) +#define LPLDO_LSM_DIS BIT(3) +#define _LDV12_VADJ(x) (((x) & 0xF) << 4) + + +//2 EFUSE_TEST (For RTL8723 partially) +#define EF_TRPT BIT(7) +#define EF_CELL_SEL (BIT(8)|BIT(9)) // 00: Wifi Efuse, 01: BT Efuse0, 10: BT Efuse1, 11: BT Efuse2 +#define LDOE25_EN BIT(31) +#define EFUSE_SEL(x) (((x) & 0x3) << 8) +#define EFUSE_SEL_MASK 0x300 +#define EFUSE_WIFI_SEL_0 0x0 +#define EFUSE_BT_SEL_0 0x1 +#define EFUSE_BT_SEL_1 0x2 +#define EFUSE_BT_SEL_2 0x3 + + +//2 8051FWDL +//2 MCUFWDL +#define MCUFWDL_EN BIT(0) +#define MCUFWDL_RDY BIT(1) +#define FWDL_ChkSum_rpt BIT(2) +#define MACINI_RDY BIT(3) +#define BBINI_RDY BIT(4) +#define RFINI_RDY BIT(5) +#define WINTINI_RDY BIT(6) +#define RAM_DL_SEL BIT(7) +#define ROM_DLEN BIT(19) +#define CPRST BIT(23) + + + +//2 REG_SYS_CFG +#define XCLK_VLD BIT(0) +#define ACLK_VLD BIT(1) +#define UCLK_VLD BIT(2) +#define PCLK_VLD BIT(3) +#define PCIRSTB BIT(4) +#define V15_VLD BIT(5) +#define TRP_B15V_EN BIT(7) +#define SIC_IDLE BIT(8) +#define BD_MAC2 BIT(9) +#define BD_MAC1 BIT(10) +#define IC_MACPHY_MODE BIT(11) +#define CHIP_VER (BIT(12)|BIT(13)|BIT(14)|BIT(15)) +#define BT_FUNC BIT(16) +#define VENDOR_ID BIT(19) +#define PAD_HWPD_IDN BIT(22) +#define TRP_VAUX_EN BIT(23) // RTL ID +#define TRP_BT_EN BIT(24) +#define BD_PKG_SEL BIT(25) +#define BD_HCI_SEL BIT(26) +#define TYPE_ID BIT(27) + +#define CHIP_VER_RTL_MASK 0xF000 //Bit 12 ~ 15 +#define CHIP_VER_RTL_SHIFT 12 + +*/ +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +/* + +//2 Function Enable Registers +//2 CR 0x0100-0x0103 + + +#define HCI_TXDMA_EN BIT(0) +#define HCI_RXDMA_EN BIT(1) +#define TXDMA_EN BIT(2) +#define RXDMA_EN BIT(3) +#define PROTOCOL_EN BIT(4) +#define SCHEDULE_EN BIT(5) +#define MACTXEN BIT(6) +#define MACRXEN BIT(7) +#define ENSWBCN BIT(8) +#define ENSEC BIT(9) +#define CALTMR_EN BIT(10) // 32k CAL TMR enable + +// Network type +#define _NETTYPE(x) (((x) & 0x3) << 16) +#define MASK_NETTYPE 0x30000 +#define NT_NO_LINK 0x0 +#define NT_LINK_AD_HOC 0x1 +#define NT_LINK_AP 0x2 +#define NT_AS_AP 0x3 + + +//2 PBP - Page Size Register 0x0104 +#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) +#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) +#define _PSRX_MASK 0xF +#define _PSTX_MASK 0xF0 +#define _PSRX(x) (x) +#define _PSTX(x) ((x) << 4) + +#define PBP_64 0x0 +#define PBP_128 0x1 +#define PBP_256 0x2 +#define PBP_512 0x3 +#define PBP_1024 0x4 + + +//2 TX/RXDMA 0x010C +#define RXDMA_ARBBW_EN BIT(0) +#define RXSHFT_EN BIT(1) +#define RXDMA_AGG_EN BIT(2) +#define QS_VO_QUEUE BIT(8) +#define QS_VI_QUEUE BIT(9) +#define QS_BE_QUEUE BIT(10) +#define QS_BK_QUEUE BIT(11) +#define QS_MANAGER_QUEUE BIT(12) +#define QS_HIGH_QUEUE BIT(13) + +#define HQSEL_VOQ BIT(0) +#define HQSEL_VIQ BIT(1) +#define HQSEL_BEQ BIT(2) +#define HQSEL_BKQ BIT(3) +#define HQSEL_MGTQ BIT(4) +#define HQSEL_HIQ BIT(5) + +// For normal driver, 0x10C +#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) +#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) +#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) +#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8 ) +#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6 ) +#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4 ) + +#define QUEUE_LOW 1 +#define QUEUE_NORMAL 2 +#define QUEUE_HIGH 3 + + +//2 REG_C2HEVT_CLEAR 0x01AF +#define C2H_EVT_HOST_CLOSE 0x00 // Set by driver and notify FW that the driver has read the C2H command message +#define C2H_EVT_FW_CLOSE 0xFF // Set by FW indicating that FW had set the C2H command message and it's not yet read by driver. + + + +//2 LLT_INIT 0x01E0 +#define _LLT_NO_ACTIVE 0x0 +#define _LLT_WRITE_ACCESS 0x1 +#define _LLT_READ_ACCESS 0x2 + +#define _LLT_INIT_DATA(x) ((x) & 0xFF) +#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) +#define _LLT_OP(x) (((x) & 0x3) << 30) +#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) + +*/ +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- +/* +//2 TDECTL 0x0208 +#define BLK_DESC_NUM_SHIFT 4 +#define BLK_DESC_NUM_MASK 0xF + + +//2 TXDMA_OFFSET_CHK 0x020C +#define DROP_DATA_EN BIT(9) +*/ +//----------------------------------------------------- +// +// 0x0280h ~ 0x028Bh RX DMA Configuration +// +//----------------------------------------------------- +/* +//2 REG_RXDMA_CONTROL, 0x0286h + +// Write only. When this bit is set, RXDMA will decrease RX PKT counter by one. Before +// this bit is polled, FW shall update RXFF_RD_PTR first. This register is write pulse and auto clear. +#define RXPKT_RELEASE_POLL BIT(0) +// Read only. When RXMA finishes on-going DMA operation, RXMDA will report idle state in +// this bit. FW can start releasing packets after RXDMA entering idle mode. +#define RXDMA_IDLE BIT(1) +// When this bit is set, RXDMA will enter this mode after on-going RXDMA packet to host +// completed, and stop DMA packet to host. RXDMA will then report Default: 0; +#define RW_RELEASE_EN BIT(2) +*/ +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +/* +//2 FWHW_TXQ_CTRL 0x0420 +#define EN_AMPDU_RTY_NEW BIT(7) + + +//2 REG_LIFECTRL_CTRL 0x0426 +#define HAL92C_EN_PKT_LIFE_TIME_BK BIT3 +#define HAL92C_EN_PKT_LIFE_TIME_BE BIT2 +#define HAL92C_EN_PKT_LIFE_TIME_VI BIT1 +#define HAL92C_EN_PKT_LIFE_TIME_VO BIT0 + +#define HAL92C_MSDU_LIFE_TIME_UNIT 128 // in us, said by Tim. + + +//2 SPEC SIFS 0x0428 +#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) +#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) + +//2 RL 0x042A +#define RETRY_LIMIT_SHORT_SHIFT 8 +#define RETRY_LIMIT_LONG_SHIFT 0 + +#define _LRL(x) ((x) & 0x3F) +#define _SRL(x) (((x) & 0x3F) << 8) +*/ + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +/* +//2 EDCA setting 0x050C +#define AC_PARAM_TXOP_LIMIT_OFFSET 16 +#define AC_PARAM_ECW_MAX_OFFSET 12 +#define AC_PARAM_ECW_MIN_OFFSET 8 +#define AC_PARAM_AIFS_OFFSET 0 + + +//2 BCN_CTRL 0x0550 +#define EN_TXBCN_RPT BIT(2) +#define EN_BCN_FUNCTION BIT(3) + +//2 TxPause 0x0522 +#define STOP_BCNQ BIT(6) +*/ + + +//2 ACMHWCTRL 0x05C0 +#define AcmHw_HwEn_8723B BIT(0) +#define AcmHw_VoqEn_8723B BIT(1) +#define AcmHw_ViqEn_8723B BIT(2) +#define AcmHw_BeqEn_8723B BIT(3) +#define AcmHw_VoqStatus_8723B BIT(5) +#define AcmHw_ViqStatus_8723B BIT(6) +#define AcmHw_BeqStatus_8723B BIT(7) + + + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + + +//2 TCR 0x0604 +#define DIS_GCLK BIT(1) +#define PAD_SEL BIT(2) +#define PWR_ST BIT(6) +#define PWRBIT_OW_EN BIT(7) +#define ACRC BIT(8) +#define CFENDFORM BIT(9) +#define ICV BIT(10) + + +//---------------------------------------------------------------------------- +// 8195 (RCR) Receive Configuration Register (Offset 0x608, 32 bits) +//---------------------------------------------------------------------------- +/* +#define RCR_APPFCS BIT31 // WMAC append FCS after pauload +#define RCR_APP_MIC BIT30 // MACRX will retain the MIC at the bottom of the packet. +#define RCR_APP_ICV BIT29 // MACRX will retain the ICV at the bottom of the packet. +#define RCR_APP_PHYST_RXFF BIT28 // HY Status is appended before RX packet in RXFF +#define RCR_APP_BA_SSN BIT27 // SSN of previous TXBA is appended as after original RXDESC as the 4-th DW of RXDESC. +#define RCR_RSVD_BIT26 BIT26 // Reserved +*/ +#define RCR_TCPOFLD_EN BIT25 // Enable TCP checksum offload +/*#define RCR_ENMBID BIT24 // Enable Multiple BssId. Only response ACK to the packets whose DID(A1) matching to the addresses in the MBSSID CAM Entries. +#define RCR_LSIGEN BIT23 // Enable LSIG TXOP Protection function. Search KEYCAM for each rx packet to check if LSIGEN bit is set. +#define RCR_MFBEN BIT22 // Enable immediate MCS Feedback function. When Rx packet with MRQ = 1'b1, then search KEYCAM to find sender's MCS Feedback function and send response. +*/ +#define RCR_MAC_RESET BIT19 // WMAC clock stop and reset after BB transmitting end, 0: enable, 1: disable. +#define RCR_TIM_PARSER_EN BIT18 // RX Beacon TIM Parser. +#define RCR_BM_DATA_EN BIT17 // Broadcast data packet interrupt enable. +#define RCR_UC_DATA_EN BIT16 // Unicast data packet interrupt enable. + +/*#define RCR_HTC_LOC_CTRL BIT14 // MFC<--HTC=1 MFC-->HTC=0 +#define RCR_AMF BIT13 // Accept management type frame +#define RCR_ACF BIT12 // Accept control type frame. Control frames BA, BAR, and PS-Poll (when in AP mode) are not controlled by this bit. They are controlled by ADF. +#define RCR_ADF BIT11 // Accept data type frame. This bit also regulates BA, BAR, and PS-Poll (AP mode only). +*/ +/*#define RCR_AICV BIT9 // Accept ICV error packet +#define RCR_ACRC32 BIT8 // Accept CRC32 error packet +#define RCR_CBSSID_BCN BIT7 // Accept BSSID match packet (Rx beacon, probe rsp) +#define RCR_CBSSID_DATA BIT6 // Accept BSSID match packet (Data) +#define RCR_CBSSID RCR_CBSSID_DATA // Accept BSSID match packet +#define RCR_APWRMGT BIT5 // Accept power management packet +#define RCR_ADD3 BIT4 // Accept address 3 match packet +#define RCR_AB BIT3 // Accept broadcast packet +#define RCR_AM BIT2 // Accept multicast packet +#define RCR_APM BIT1 // Accept physical match packet +#define RCR_AAP BIT0 // Accept all unicast packet + +#define AAP BIT(0) +#define APM BIT(1) +#define AM BIT(2) +#define AB BIT(3) +#define ADD3 BIT(4) +#define APWRMGT BIT(5) +#define CBSSID BIT(6) +#define CBSSID_DATA BIT(6) +#define CBSSID_BCN BIT(7) +#define ACRC32 BIT(8) +#define AICV BIT(9) +#define ADF BIT(11) +#define ACF BIT(12) +#define AMF BIT(13) +#define HTC_LOC_CTRL BIT(14) +#define UC_DATA_EN BIT(16) +#define BM_DATA_EN BIT(17) +#define MFBEN BIT(22) +#define LSIGEN BIT(23) +#define EnMBID BIT(24) +#define APP_BASSN BIT(27) +#define APP_PHYSTS BIT(28) +#define APP_ICV BIT(29) +#define APP_MIC BIT(30) +*/ + +//---------------------------------------------------------------------------- +// 8195 CAM Config Setting (offset 0x680, 1 byte) +//---------------------------------------------------------------------------- +/* +#define SCR_TxUseDK BIT(0) //Force Tx Use Default Key +#define SCR_RxUseDK BIT(1) //Force Rx Use Default Key +#define SCR_TxEncEnable BIT(2) //Enable Tx Encryption +#define SCR_RxDecEnable BIT(3) //Enable Rx Decryption +#define SCR_SKByA2 BIT(4) //Search kEY BY A2 +#define SCR_NoSKMC BIT(5) //No Key Search Multicast +#define SCR_TXBCUSEDK BIT(6) // Force Tx Broadcast packets Use Default Key +#define SCR_RXBCUSEDK BIT(7) // Force Rx Broadcast packets Use Default Key + +#define CAM_NONE 0x0 +#define CAM_WEP40 0x01 +#define CAM_TKIP 0x02 +#define CAM_AES 0x04 +#define CAM_WEP104 0x05 +#define CAM_SMS4 0x6 + +#define TOTAL_CAM_ENTRY 32 +#define HALF_CAM_ENTRY 16 + +#define CAM_CONFIG_USEDK TRUE +#define CAM_CONFIG_NO_USEDK FALSE + + +#define SCR_UseDK 0x01 +#define SCR_TxSecEnable 0x02 +#define SCR_RxSecEnable 0x04 +*/ + +//---------------------------------------------------------------------------- +// 8195 REG_BCN_PSR_RPT (Beacon Parser Report Register) (Offset 0x6A8, 32 bits) +//---------------------------------------------------------------------------- + +#define PS_TIM BIT14 +#define PS_DTIM BIT15 + +//----------------------------------------------------- +// +// 0xFE00h ~ 0xFE55h RTL8723 SDIO Configuration +// +//----------------------------------------------------- +/* +//SDIO host local register space mapping. +#define SDIO_LOCAL_MSK 0x0FFF +#define WLAN_IOREG_MSK 0x7FFF +#define WLAN_FIFO_MSK 0x1FFF // Aggregation Length[12:0] + +#define SDIO_WITHOUT_REF_DEVICE_ID 0 // Without reference to the SDIO Device ID +#define SDIO_LOCAL_DEVICE_ID 0 // 0b[16], 000b[15:13] +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13] +#define WLAN_IOREG_DEVICE_ID 8 // 1b[16] + +//SDIO Tx Free Page Index +#define HI_QUEUE_IDX 0 +#define MID_QUEUE_IDX 1 +#define LOW_QUEUE_IDX 2 +#define PUBLIC_QUEUE_IDX 3 + +#define SDIO_REG_TX_CTRL 0x0000 // SDIO Tx Control +#define SDIO_REG_HIMR 0x0014 // SDIO Host Interrupt Mask +#define SDIO_REG_HISR 0x0018 // SDIO Host Interrupt Service Routine +#define SDIO_REG_HCPWM 0x0019 // HCI Current Power Mode +#define SDIO_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length +#define SDIO_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page +#define SDIO_REG_HCPWM1 0x0024 // HCI Current Power Mode 1 +#define SDIO_REG_HCPWM2 0x0026 // HCI Current Power Mode 2 +#define SDIO_REG_HTSFR_INFO 0x0030 // HTSF Informaion +#define SDIO_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 +#define SDIO_REG_HRPWM2 0x0082 // HCI Request Power Mode 2 +#define SDIO_REG_HPS_CLKR 0x0084 // HCI Power Save Clock +#define SDIO_REG_HSUS_CTRL 0x0086 // SDIO HCI Suspend Control +#define SDIO_REG_HIMR_ON 0x0090 //SDIO Host Extension Interrupt Mask Always +#define SDIO_REG_HISR_ON 0x0091 //SDIO Host Extension Interrupt Status Always + +#define SDIO_HIMR_DISABLED 0 + +// RTL8723/RTL8188E SDIO Host Interrupt Mask Register +#define SDIO_HIMR_RX_REQUEST_MSK BIT0 +#define SDIO_HIMR_AVAL_MSK BIT1 +#define SDIO_HIMR_TXERR_MSK BIT2 +#define SDIO_HIMR_RXERR_MSK BIT3 +#define SDIO_HIMR_TXFOVW_MSK BIT4 +#define SDIO_HIMR_RXFOVW_MSK BIT5 +#define SDIO_HIMR_TXBCNOK_MSK BIT6 +#define SDIO_HIMR_TXBCNERR_MSK BIT7 +#define SDIO_HIMR_BCNERLY_INT_MSK BIT16 +#define SDIO_HIMR_C2HCMD_MSK BIT17 +#define SDIO_HIMR_CPWM1_MSK BIT18 +#define SDIO_HIMR_CPWM2_MSK BIT19 +#define SDIO_HIMR_HSISR_IND_MSK BIT20 +#define SDIO_HIMR_GTINT3_IND_MSK BIT21 +#define SDIO_HIMR_GTINT4_IND_MSK BIT22 +#define SDIO_HIMR_PSTIMEOUT_MSK BIT23 +#define SDIO_HIMR_OCPINT_MSK BIT24 +#define SDIO_HIMR_ATIMEND_MSK BIT25 +#define SDIO_HIMR_ATIMEND_E_MSK BIT26 +#define SDIO_HIMR_CTWEND_MSK BIT27 + +//RTL8188E SDIO Specific +#define SDIO_HIMR_MCU_ERR_MSK BIT28 +#define SDIO_HIMR_TSF_BIT32_TOGGLE_MSK BIT29 + +// SDIO Host Interrupt Service Routine +#define SDIO_HISR_RX_REQUEST BIT0 +#define SDIO_HISR_AVAL BIT1 +#define SDIO_HISR_TXERR BIT2 +#define SDIO_HISR_RXERR BIT3 +#define SDIO_HISR_TXFOVW BIT4 +#define SDIO_HISR_RXFOVW BIT5 +#define SDIO_HISR_TXBCNOK BIT6 +#define SDIO_HISR_TXBCNERR BIT7 +#define SDIO_HISR_BCNERLY_INT BIT16 +#define SDIO_HISR_C2HCMD BIT17 +#define SDIO_HISR_CPWM1 BIT18 +#define SDIO_HISR_CPWM2 BIT19 +#define SDIO_HISR_HSISR_IND BIT20 +#define SDIO_HISR_GTINT3_IND BIT21 +#define SDIO_HISR_GTINT4_IND BIT22 +#define SDIO_HISR_PSTIMEOUT BIT23 +#define SDIO_HISR_OCPINT BIT24 +#define SDIO_HISR_ATIMEND BIT25 +#define SDIO_HISR_ATIMEND_E BIT26 +#define SDIO_HISR_CTWEND BIT27 + +//RTL8188E SDIO Specific +#define SDIO_HISR_MCU_ERR BIT28 +#define SDIO_HISR_TSF_BIT32_TOGGLE BIT29 + + +// SDIO HCI Suspend Control Register +#define HCI_RESUME_PWR_RDY BIT1 +#define HCI_SUS_CTRL BIT0 + + +#if DEV_BUS_TYPE == RT_SDIO_INTERFACE + #define MAX_TX_AGG_PACKET_NUMBER 0x8 +#else + #define MAX_TX_AGG_PACKET_NUMBER 0xFF +#endif + +*/ +#endif // #ifndef __INC_HAL8195AREG_H diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/HalPhyRf_8195A.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/HalPhyRf_8195A.h new file mode 100644 index 0000000..3f22d3f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/HalPhyRf_8195A.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __HAL_PHY_RF_8195A_H__ +#define __HAL_PHY_RF_8195A_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define IQK_DELAY_TIME_8195A 10 //ms +#define IQK_DEFERRED_TIME_8195A 4 +#define index_mapping_NUM_8195A 15 +#define AVG_THERMAL_NUM_8195A 4 +#define RF_T_METER_8195A 0x42 // + + +void ConfigureTxpowerTrack_8195A( + PTXPWRTRACK_CFG pConfig + ); + +void DoIQK_8195A( + PDM_ODM_T pDM_Odm, + u1Byte DeltaThermalIndex, + u1Byte ThermalValue, + u1Byte Threshold + ); + +VOID +ODM_TxPwrTrackSetPwr_8195A( + PDM_ODM_T pDM_Odm, + PWRTRACK_METHOD Method, + u1Byte RFPath, + u1Byte ChannelMappedIndex + ); + +VOID +ODM_TxXtalTrackSetXtal_8195A( + PDM_ODM_T pDM_Odm +); + + +//1 7. IQK + +void +PHY_IQCalibrate_8195A( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER Adapter, +#endif + IN BOOLEAN bReCovery, + IN BOOLEAN bRestore); + + +// +// LC calibrate +// +void +PHY_LCCalibrate_8195A( + IN PDM_ODM_T pDM_Odm +); + + +VOID +_PHY_SaveADDARegisters_8195A( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN pu4Byte ADDABackup, + IN u4Byte RegisterNum + ); + +VOID +_PHY_PathADDAOn_8195A( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte ADDAReg, + IN BOOLEAN isPathAOn, + IN BOOLEAN is2T + ); + +VOID +_PHY_MACSettingCalibration_8195A( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm, +#else + IN PADAPTER pAdapter, +#endif + IN pu4Byte MACReg, + IN pu4Byte MACBackup + ); + + +VOID +_PHY_PathAStandBy( +#if (DM_ODM_SUPPORT_TYPE & ODM_AP) + IN PDM_ODM_T pDM_Odm +#else + IN PADAPTER pAdapter +#endif + ); + + +#endif // #ifndef __HAL_PHY_RF_8188E_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/ROM_RTL8195A_PHYDM.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/ROM_RTL8195A_PHYDM.h new file mode 100644 index 0000000..7123055 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/ROM_RTL8195A_PHYDM.h @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ROM_RTL8195A_PHYDM_H__ +#define __ROM_RTL8195A_PHYDM_H__ + +typedef struct _FALSE_ALARM_STATISTICS{ + u4Byte Cnt_Parity_Fail; + u4Byte Cnt_Rate_Illegal; + u4Byte Cnt_Crc8_fail; + u4Byte Cnt_Mcs_fail; + u4Byte Cnt_Ofdm_fail; + u4Byte Cnt_Ofdm_fail_pre; //For RTL8881A + u4Byte Cnt_Cck_fail; + u4Byte Cnt_all; + u4Byte Cnt_Fast_Fsync; + u4Byte Cnt_SB_Search_fail; + u4Byte Cnt_OFDM_CCA; + u4Byte Cnt_CCK_CCA; + u4Byte Cnt_CCA_all; + u4Byte Cnt_BW_USC; //Gary + u4Byte Cnt_BW_LSC; //Gary +}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; + +typedef struct _CFO_TRACKING_ +{ + BOOLEAN bATCStatus; + BOOLEAN largeCFOHit; + BOOLEAN bAdjust; + u1Byte CrystalCap; + u1Byte DefXCap; + int CFO_tail[2]; + int CFO_ave_pre; + u4Byte packetCount; + u4Byte packetCount_pre; + BOOLEAN bForceXtalCap; + BOOLEAN bReset; + u1Byte CFO_TH_XTAL_HIGH; + u1Byte CFO_TH_XTAL_LOW; + u1Byte CFO_TH_ATC; +}CFO_TRACKING, *PCFO_TRACKING; + +typedef struct _ROM_INFO{ + u1Byte EEPROMVersion; + u1Byte CrystalCap; + u8Byte DebugComponents; + u4Byte DebugLevel; +}ROM_INFO, *PROM_INFO; + +extern FALSE_ALARM_STATISTICS FalseAlmCnt; +extern CFO_TRACKING DM_CfoTrack; +extern ROM_INFO ROMInfo; + +u1Byte +ROM_odm_QueryRxPwrPercentage( + IN s1Byte AntPower +); + + +u1Byte +ROM_odm_EVMdbToPercentage( + IN s1Byte Value +); + +s4Byte +ROM_odm_SignalScaleMapping_8195A( + IN u1Byte SupportInterface, + IN s4Byte CurrSig +); + +VOID +ROM_odm_FalseAlarmCounterStatistics( + IN PVOID pDM_VOID +); + +VOID +ROM_odm_SetEDCCAThreshold( + IN PVOID pDM_VOID, + IN s1Byte H2L, + IN s1Byte L2H +); + +VOID +ROM_odm_SetTRxMux( + IN PVOID pDM_VOID, + IN ODM_Trx_MUX_Type txMode, + IN ODM_Trx_MUX_Type rxMode +); + + +VOID +ROM_odm_SetCrystalCap( + IN PVOID pDM_VOID, + IN u1Byte CrystalCap +); + +u1Byte +ROM_odm_GetDefaultCrytaltalCap( + IN PVOID pDM_VOID +); + +VOID +ROM_ODM_CfoTrackingReset( + IN PVOID pDM_VOID +); + +VOID +ROM_odm_CfoTrackingFlow( + IN PVOID pDM_VOID +); + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_bb.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_bb.h new file mode 100644 index 0000000..e352ab4 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_bb.h @@ -0,0 +1,59 @@ +/****************************************************************************** +* +* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of version 2 of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.23*/ +#if (RTL8195A_SUPPORT == 1) +#ifndef __INC_MP_BB_HW_IMG_8195A_H +#define __INC_MP_BB_HW_IMG_8195A_H + + +/****************************************************************************** +* AGC_TAB.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_AGC_TAB(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_AGC_TAB(void); + +/****************************************************************************** +* PHY_REG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_PHY_REG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_PHY_REG(void); + +/****************************************************************************** +* PHY_REG_PG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_PHY_REG_PG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_PHY_REG_PG(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_mac.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_mac.h new file mode 100644 index 0000000..23cdd26 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_mac.h @@ -0,0 +1,39 @@ +/****************************************************************************** +* +* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of version 2 of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.23*/ +#if (RTL8195A_SUPPORT == 1) +#ifndef __INC_MP_MAC_HW_IMG_8195A_H +#define __INC_MP_MAC_HW_IMG_8195A_H + + +/****************************************************************************** +* MAC_REG.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_MAC_REG(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_MAC_REG(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_rf.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_rf.h new file mode 100644 index 0000000..fa7b2ed --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/halhwimg8195a_rf.h @@ -0,0 +1,104 @@ +/****************************************************************************** +* +* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of version 2 of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program; if not, write to the Free Software Foundation, Inc., +* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +* +* +******************************************************************************/ + +/*Image2HeaderVersion: 2.23*/ +#if (RTL8195A_SUPPORT == 1) +#ifndef __INC_MP_RF_HW_IMG_8195A_H +#define __INC_MP_RF_HW_IMG_8195A_H + + +/****************************************************************************** +* RadioA.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_RadioA(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_RadioA(void); + +/****************************************************************************** +* RADIO_DIFF.TXT +******************************************************************************/ + +extern u4Byte Array_MP_8195A_RADIO_DIFF_LB[50]; +extern u4Byte Array_MP_8195A_RADIO_DIFF_MB[50]; +extern u4Byte Array_MP_8195A_RADIO_DIFF_HB[50]; +void +ODM_ReadAndConfig_MP_8195A_RADIO_DIFF( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Array[], + IN u4Byte ArrayLen +); +u4Byte ODM_GetVersion_MP_8195A_RADIO_DIFF(void); + +/****************************************************************************** +* TxPowerTrack_QFN48.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_TxPowerTrack_QFN48(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_TxPowerTrack_QFN48(void); + +/****************************************************************************** +* TxPowerTrack_QFN56.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_TxPowerTrack_QFN56(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_TxPowerTrack_QFN56(void); + +/****************************************************************************** +* TxPowerTrack_TFBGA96.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_TxPowerTrack_TFBGA96(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_TxPowerTrack_TFBGA96(void); + +/****************************************************************************** +* TXPWR_LMT.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_TXPWR_LMT(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_TXPWR_LMT(void); + +/****************************************************************************** +* TxXtalTrack.TXT +******************************************************************************/ + +void +ODM_ReadAndConfig_MP_8195A_TxXtalTrack(/* TC: Test Chip, MP: MP Chip*/ + IN PDM_ODM_T pDM_Odm +); +u4Byte ODM_GetVersion_MP_8195A_TxXtalTrack(void); + +#endif +#endif /* end of HWIMG_SUPPORT*/ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RTL8195A.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RTL8195A.h new file mode 100644 index 0000000..5b73912 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RTL8195A.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ODM_RTL8723B_H__ +#define __ODM_RTL8723B_H__ + +#define DM_DIG_MIN_NIC_8723 0x1C + +#if (defined(CONFIG_HW_ANTENNA_DIVERSITY)) + +VOID +ODM_AntennaDiversityInit_8723B( IN PDM_ODM_T pDM_Odm); + +VOID +ODM_AntselStatistics_8723B( + IN PDM_ODM_T pDM_Odm, + IN u1Byte antsel_tr_mux, + IN u4Byte MacId, + IN u4Byte RxPWDBAll); + +VOID +ODM_AntennaDiversity_8723B( IN PDM_ODM_T pDM_Odm); + + +VOID +ODM_UpdateRxIdleAnt_8723B(IN PDM_ODM_T pDM_Odm, IN u1Byte Ant); + +VOID +ODM_SetTxAntByTxInfo_8723B( + IN PDM_ODM_T pDM_Odm, + IN pu1Byte pDesc, + IN u1Byte macId +); + +#endif + +VOID +odm_DIG_8723(IN PDM_ODM_T pDM_Odm); + +s1Byte +odm_CCKRSSI_8723B( + IN u1Byte LNA_idx, + IN u1Byte VGA_idx + ); + +s1Byte +odm_RSSIOFDM_8723B( + IN s1Byte rx_pwr_new + ); + + + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RegConfig8195A.h b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RegConfig8195A.h new file mode 100644 index 0000000..4dbf0dd --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/OUTSRC/rtl8195a/phydm_RegConfig8195A.h @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __INC_ODM_REGCONFIG_H_8195A +#define __INC_ODM_REGCONFIG_H_8195A + +#if (RTL8195A_SUPPORT == 1) + +void +odm_ConfigRFReg_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data, + IN ODM_RF_RADIO_PATH_E RF_PATH, + IN u4Byte RegAddr + ); + +void +odm_ConfigRF_RadioA_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Data + ); + +void +odm_ConfigMAC_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u1Byte Data + ); + +void +odm_ConfigBB_AGC_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_PHY_REG_PG_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Band, + IN u4Byte RfPath, + IN u4Byte TxNum, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_PHY_8195A( + IN PDM_ODM_T pDM_Odm, + IN u4Byte Addr, + IN u4Byte Bitmask, + IN u4Byte Data + ); + +void +odm_ConfigBB_TXPWR_LMT_8195A( + IN PDM_ODM_T pDM_Odm, + IN u1Byte Regulation, + IN u1Byte Band, + IN u1Byte Bandwidth, + IN u1Byte RateSection, + IN u1Byte RfPath, + IN u1Byte Channel, + IN u1Byte PowerLimit + ); + +#endif +#endif // end of SUPPORT + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/hal_data.h b/USDK/component/common/drivers/wlan/realtek/src/hal/hal_data.h new file mode 100644 index 0000000..cb52109 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/hal_data.h @@ -0,0 +1,498 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +#ifndef __HAL_DATA_H__ +#define __HAL_DATA_H__ + + +#include "hal_com.h" +#ifdef CONFIG_RTL8188F +#include "OUTSRC/rtl8188f/phydm_precomp.h" +#else +#include "OUTSRC/phydm_precomp.h" +#endif + +#ifdef CONFIG_RTL8723A +#include "rtl8723a/rtl8723a_hal.h" +#endif +#ifdef CONFIG_RTL8188E +#include "rtl8188e/rtl8188e_hal.h" +#endif +#ifdef CONFIG_RTL8195A +#include "rtl8195a_hal.h" +#endif +#if (CONFIG_RTL8711B ==1) +#include "rtl8711b_hal.h" +#endif +#ifdef CONFIG_RTL8188F +#include "rtl8188f/rtl8188f_hal.h" +#endif +// +// For RTL8723 WiFi/BT/GPS multi-function configuration. 2010.10.06. +// +typedef enum _RT_MULTI_FUNC{ + RT_MULTI_FUNC_NONE = 0x00, + RT_MULTI_FUNC_WIFI = 0x01, + RT_MULTI_FUNC_BT = 0x02, + RT_MULTI_FUNC_GPS = 0x04, +}RT_MULTI_FUNC,*PRT_MULTI_FUNC; +// +// For RTL8723 WiFi PDn/GPIO polarity control configuration. 2010.10.08. +// +typedef enum _RT_POLARITY_CTL { + RT_POLARITY_LOW_ACT = 0, + RT_POLARITY_HIGH_ACT = 1, +} RT_POLARITY_CTL, *PRT_POLARITY_CTL; + +// For RTL8723 regulator mode. by tynli. 2011.01.14. +typedef enum _RT_REGULATOR_MODE { + RT_SWITCHING_REGULATOR = 0, + RT_LDO_REGULATOR = 1, +} RT_REGULATOR_MODE, *PRT_REGULATOR_MODE; + +#define CHANNEL_MAX_NUMBER 14 // 14 is the max channel number +#define CHANNEL_MAX_NUMBER_2G 14 +#define CHANNEL_MAX_NUMBER_5G 54 // Please refer to "phy_GetChnlGroup8812A" and "Hal_ReadTxPowerInfo8812A" +#define CHANNEL_MAX_NUMBER_5G_80M 7 + +// Tx Power Limit Table Size +#define MAX_REGULATION_NUM 3 // FCC, ETSI, MKK +#define MAX_2_4G_BANDWITH_NUM 2 // 20M, 40M +#if defined(NOT_SUPPORT_RF_MULTIPATH) && defined(NOT_SUPPORT_VHT) +#define MAX_RATE_SECTION_NUM 3 // CCk, OFDM, HT +#define MAX_BASE_NUM_IN_PHY_REG_PG_2_4G 3 // CCK:1,OFDM:1, HT:1(MCS0_MCS7) +#else +#define MAX_RATE_SECTION_NUM 10 +#define MAX_BASE_NUM_IN_PHY_REG_PG_2_4G 10 // CCK:1,OFDM:1, HT:4, VHT:4 +#endif +#define MAX_5G_BANDWITH_NUM 4 +#define MAX_BASE_NUM_IN_PHY_REG_PG_5G 9 // OFDM:1, HT:4, VHT:4 + +#define HCI_SUS_ENTER 0 +#define HCI_SUS_LEAVING 1 +#define HCI_SUS_LEAVE 2 +#define HCI_SUS_ENTERING 3 +#define HCI_SUS_ERR 4 + + +struct dm_priv +{ + u8 DM_Type; + u8 DMFlag; + u8 InitDMFlag; + u32 InitODMFlag; + + //* Upper and Lower Signal threshold for Rate Adaptive*/ + int UndecoratedSmoothedPWDB; + int UndecoratedSmoothedCCK; + int EntryMinUndecoratedSmoothedPWDB; + int EntryMaxUndecoratedSmoothedPWDB; + int MinUndecoratedPWDBForDM; + int LastMinUndecoratedPWDBForDM; + + + //for High Power + u8 bDynamicTxPowerEnable; + u8 LastDTPLvl; + u8 DynamicTxHighPowerLvl;//Add by Jacken Tx Power Control for Near/Far Range 2008/03/06 + + //for tx power tracking + u8 bTXPowerTracking; + u8 TXPowercount; + u8 bTXPowerTrackingInit; + u8 TxPowerTrackControl; //for mp mode, turn off txpwrtracking as default + + u8 PowerIndex_backup[6]; + + s32 OFDM_Pkt_Cnt; + + // Add for Reading Initial Data Rate SEL Register 0x484 during watchdog. Using for fill tx desc. 2011.3.21 by Thomas + u8 INIDATA_RATE[32]; +}; + +#ifdef CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD +#define MCUCMDQUEUEDEPTH 15 +#define MCUCMDLENGTH 2 +#define MACIDNUM 128 +typedef struct _cmd_queue_{ + u32 FwCmdContent[MCUCMDLENGTH]; +}CMD_QUEUE; +#endif + + +#ifdef CONFIG_RF_GAIN_OFFSET +#ifdef CONFIG_RTL8188F +struct kfree_data_t { + u8 flag; + s8 bb_gain[BB_GAIN_NUM][RF_PATH_MAX]; + s8 thermal; +}; + +#define KFREE_FLAG_ON BIT0 +#define KFREE_FLAG_THERMAL_K_ON BIT1 +#endif +#endif + +typedef struct hal_com_data +{ + HAL_VERSION VersionID; +// RT_MULTI_FUNC MultiFunc; // For multi-function consideration. +// RT_POLARITY_CTL PolarityCtl; // For Wifi PDn Polarity control. + RT_REGULATOR_MODE RegulatorMode; // switching regulator or LDO + u16 CustomerID; +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) ||defined (CONFIG_RTL8188F) + u16 ForcedDataRate;// Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M. +#endif + + u16 FirmwareVersion; + u16 FirmwareVersionRev; + u16 FirmwareSubVersion; + u16 FirmwareSignature; +// u8 PGMaxGroup; + //current WIFI_PHY values + u32 ReceiveConfig; +// WIRELESS_MODE CurrentWirelessMode; + CHANNEL_WIDTH CurrentChannelBW; +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)||defined (CONFIG_RTL8188F) + BAND_TYPE CurrentBandType; //0:2.4G, 1:5G +#endif + u8 CurrentChannel; + u8 nCur40MhzPrimeSC;// Control channel sub-carrier + u8 CurrentCenterFrequencyIndex1; +#if !defined(NOT_SUPPORT_80M) + u8 nCur80MhzPrimeSC; //used for primary 40MHz of 80MHz mode +#endif + + u16 BasicRateSet; + u8 hci_sus_state; + //rf_ctrl + u8 rf_chip; + u8 rf_type; +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)||defined (CONFIG_RTL8188F) + u8 PackageType; + u8 ChipID; +#endif + u8 NumTotalRFPath; + + u8 BoardType; + + // + // EEPROM setting. + // +// u16 EEPROMVID; +// u16 EEPROMPID; +// u16 EEPROMSVID; +// u16 EEPROMSDID; + u8 EEPROMCustomerID; +// u8 EEPROMSubCustomerID; + u8 EEPROMVersion; + u8 EEPROMRegulatory; + +#ifdef CONFIG_RF_GAIN_OFFSET +#ifdef CONFIG_RTL8188F + struct kfree_data_t kfree_data; +#endif +#endif +// u8 bTXPowerDataReadFromEEPORM; + u8 EEPROMThermalMeter; +// u8 bAPKThermalMeterIgnore; + +// BOOLEAN EepromOrEfuse; + //u8 EfuseMap[2][HWSET_MAX_SIZE_512]; //92C:256bytes, 88E:512bytes, we use union set (512bytes) + //u8 EfuseUsedPercentage; +#ifdef HAL_EFUSE_MEMORY + EFUSE_HAL EfuseHal; +#endif + //u8 bIQKInitialized; + + u8 Regulation2_4G; +#if !defined(NOT_SUPPORT_5G) + u8 Regulation5G; +#endif +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B)||defined (CONFIG_RTL8188F) + s8 TxPwrByRateOffset[TX_PWR_BY_RATE_NUM_BAND] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RATE]; +#endif + //---------------------------------------------------------------------------------// +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B)||defined (CONFIG_RTL8188F) + u8 Index24G_CCK_Base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + u8 Index24G_BW40_Base[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + //If only one tx, only BW20 and OFDM are used. + s8 OFDM_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW20_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +#if !defined(NOT_SUPPORT_RF_MULTIPATH) + s8 CCK_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; + s8 BW40_24G_Diff[MAX_RF_PATH][MAX_TX_COUNT]; +#endif + + //2 Power Limit Table + // Power Limit Table for 2.4G + s8 TxPwrLimit_2_4G[MAX_REGULATION_NUM] + [MAX_2_4G_BANDWITH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_2G] + [MAX_RF_PATH]; + #if !defined(NOT_SUPPORT_5G) + // Power Limit Table for 5G + s8 TxPwrLimit_5G[MAX_REGULATION_NUM] + [MAX_5G_BANDWITH_NUM] + [MAX_RATE_SECTION_NUM] + [CHANNEL_MAX_NUMBER_5G] + [MAX_RF_PATH]; + #endif + + // Store the original power by rate value of the base of each rate section of rf path A & B + u8 TxPwrByRateBase2_4G[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_2_4G]; + #if !defined(NOT_SUPPORT_5G) + u8 TxPwrByRateBase5G[TX_PWR_BY_RATE_NUM_RF] + [TX_PWR_BY_RATE_NUM_RF] + [MAX_BASE_NUM_IN_PHY_REG_PG_5G]; + #endif +#else + u8 TxPwrLevelCck[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + u8 TxPwrLevelHT40_1S[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrLevelHT40_2S[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; // For HT 40MHZ pwr + u8 TxPwrHt20Diff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];// HT 20<->40 Pwr diff + u8 TxPwrLegacyHtDiff[MAX_RF_PATH][CHANNEL_MAX_NUMBER];// For HT<->legacy pwr diff +#endif + + // For power group +// u8 PwrGroupHT20[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; +// u8 PwrGroupHT40[MAX_RF_PATH][CHANNEL_MAX_NUMBER]; + +// u8 LegacyHTTxPowerDiff;// Legacy to HT rate power diff + // The current Tx Power Level + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + u8 CurrentBW2024GTxPwrIdx; + u8 CurrentBW4024GTxPwrIdx; + + u8 CrystalCap; + //u32 AntennaTxPath; // Antenna path Tx + //u32 AntennaRxPath; // Antenna path Rx + //u8 BluetoothCoexist; +// u8 ExternalPA; + +#if defined(CONFIG_RTL8188F) + + /* PHY DM & DM Section */ + u8 INIDATA_RATE[32/*MACID_NUM_SW_LIMIT*/]; + /* Upper and Lower Signal threshold for Rate Adaptive*/ + int EntryMinUndecoratedSmoothedPWDB; + int EntryMaxUndecoratedSmoothedPWDB; + int MinUndecoratedPWDBForDM; +#endif + + //u8 bLedOpenDrain; // Support Open-drain arrangement for controlling the LED. Added by Roger, 2009.10.16. + + //u32 LedControlNum; + //u32 LedControlMode; + //u8 b1x1RecvCombine; // for 1T1R receive combining + + //u8 bCurrentTurboEDCA; +#if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B)||defined (CONFIG_RTL8188F) + BOOLEAN bSwChnl; + BOOLEAN bSetChnlBW; + BOOLEAN bChnlBWInitialized; +#endif + +// BOOLEAN bNeedIQK; + + u32 AcParam_BE; //Original parameter for BE, use for EDCA turbo. +#if defined(NOT_SUPPORT_RF_MULTIPATH) + BB_REGISTER_DEFINITION_T PHYRegDef[1]; //Radio A + u32 RfRegChnlVal[1]; +#else + BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D + u32 RfRegChnlVal[2]; +#endif + + //RDG enable +// BOOLEAN bRDGEnable; + +#if (defined(CONFIG_RTL8711B) || defined(CONFIG_RTL8188F)) + //for host message to fw + u8 LastHMEBoxNum; +#endif + + u8 fw_ractrl; +// u8 RegTxPause; + // Beacon function related global variable. +// u32 RegBcnCtrlVal; + u8 RegFwHwTxQCtrl; + u8 RegReg542; +// u8 RegCR_1; + u16 RegRRSR; + + struct dm_priv dmpriv; + DM_ODM_T odmpriv; + //_lock odm_stainfo_lock; +#ifdef DBG_CONFIG_ERROR_DETECT + struct sreset_priv srestpriv; +#endif + +#ifdef CONFIG_BT_COEXIST + struct btcoexist_priv bt_coexist; +#endif + +//#ifdef CONFIG_ANTENNA_DIVERSITY + u8 CurAntenna; + u8 AntDivCfg; + u8 TRxAntDivType; +//#endif + +// u8 bDumpRxPkt;//for debug +// u8 bDumpTxPkt;//for debug +// u8 FwRsvdPageStartOffset; //2010.06.23. Added by tynli. Reserve page start offset except beacon in TxQ. + + // 2010/08/09 MH Add CU power down mode. +// BOOLEAN pwrdown; + + // Add for dual MAC 0--Mac0 1--Mac1 +// u32 interfaceIndex; + + u8 OutEpQueueSel; + u8 OutEpNumber; + + // 2010/12/10 MH Add for USB aggreation mode dynamic shceme. +// BOOLEAN UsbRxHighSpeedMode; + + // 2010/11/22 MH Add for slim combo debug mode selective. + // This is used for fix the drawback of CU TSMC-A/UMC-A cut. HW auto suspend ability. Close BT clock. + //BOOLEAN SlimComboDbg; + + u16 EfuseUsedBytes; + +#ifdef CONFIG_P2P + struct P2P_PS_Offload_t p2p_ps_offload; +#endif + + u8 AMPDUDensity; + + // Auto FSM to Turn On, include clock, isolation, power control for MAC only + u8 bMacPwrCtrlOn; + +#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) + + // + // For SDIO Interface HAL related + // + + // + // SDIO ISR Related + // +// u32 IntrMask[1]; +// u32 IntrMaskToSet[1]; +// LOG_INTERRUPT InterruptLog; +// u32 sdio_himr; +// u32 sdio_hisr; + + // + // SDIO Tx FIFO related. + // + // HIQ, MID, LOW, PUB free pages; padapter->xmitpriv.free_txpg +// u8 SdioTxFIFOFreePage[TX_FREE_PG_QUEUE]; +// _lock SdioTxFIFOFreePageLock; +// _thread_hdl_ SdioXmitThread; +// _sema SdioXmitSema; +// _sema SdioXmitTerminateSema; + + // + // SDIO Rx FIFO related. + // +// u8 SdioRxFIFOCnt; +// u16 SdioRxFIFOSize; +#endif //CONFIG_SDIO_HCI + +#ifdef CONFIG_USB_HCI + u32 UsbBulkOutSize; + + // Interrupt relatd register information. + u32 IntArray[3];//HISR0,HISR1,HSISR + u32 IntrMask[3]; + //u8 C2hArray[16]; +#ifdef CONFIG_USB_TX_AGGREGATION + u8 UsbTxAggMode; + u8 UsbTxAggDescNum; +#endif +#ifdef CONFIG_USB_RX_AGGREGATION + u16 HwRxPageSize; // Hardware setting + u32 MaxUsbRxAggBlock; + + USB_RX_AGG_MODE UsbRxAggMode; + u8 UsbRxAggBlockCount; // USB Block count. Block size is 512-byte in hight speed and 64-byte in full speed + u8 UsbRxAggBlockTimeout; + u8 UsbRxAggPageCount; // 8192C DMA page count + u8 UsbRxAggPageTimeout; +#endif +#endif //CONFIG_USB_HCI + + +#if defined (CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +// u32 TransmitConfig; + u32 IntArray[3]; + u32 IntrMask[3]; +// u8 bDefaultAntenna; +// u8 bIQKInitialized; + +// u8 bInterruptMigration; +// u8 bDisableTxInt; +#ifdef CONFIG_SUPPORT_HW_WPS_PBC + u8 bGpioHwWpsPbc; +#endif + u16 RxExpectTag; +#ifdef CONFIG_DEBUG_DYNAMIC + struct hal_debug debug_info; +#endif + +#endif //CONFIG_PCI_HCI || CONFIG_LX_HCI + + +#ifdef CONFIG_TX_EARLY_MODE + u8 bEarlyModeEnable; +#endif + +#ifdef CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD + struct task_struct littlewifipriv; + //CMD_QUEUE FwCmdQueue[MCUCMDQUEUEDEPTH]; + //fw section + u32 WifiMcuCmdBitMap; + u8 bConnected[MACIDNUM/8]; + BOOLEAN PMUTaskRAEn; + + u8 BcnIgnoreEdccaEn; + + #ifdef CONFIG_POWER_SAVING + struct task_struct enter32kpriv; + + #ifdef TDMA_POWER_SAVING + struct task_struct TDMApriv; + #endif //#ifdef TDMA_POWER_SAVING + + PS_PARM PSParmpriv; + u8 ScanEn; + #endif //#ifdef CONFIG_POWER_SAVING +#endif + +} HAL_DATA_COMMON, *PHAL_DATA_COMMON; + +typedef struct hal_com_data HAL_DATA_TYPE, *PHAL_DATA_TYPE; +#define GET_HAL_DATA(__pAdapter) ((HAL_DATA_TYPE *)((__pAdapter)->HalData)) + +#endif //__HAL_DATA_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8192CPhyReg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8192CPhyReg.h new file mode 100644 index 0000000..81b226a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8192CPhyReg.h @@ -0,0 +1,1125 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +/***************************************************************************** + * + * Module: __INC_HAL8192CPHYREG_H + * + * + * Note: 1. Define PMAC/BB register map + * 2. Define RF register map + * 3. PMAC/BB register bit mask. + * 4. RF reg bit mask. + * 5. Other BB/RF relative definition. + * + * + * Export: Constants, macro, functions(API), global variables(None). + * + * Abbrev: + * + * History: + * Data Who Remark + * 08/07/2007 MHC 1. Porting from 9x series PHYCFG.h. + * 2. Reorganize code architecture. + * 09/25/2008 MH 1. Add RL6052 register definition + * + *****************************************************************************/ +#ifndef __INC_HAL8192CPHYREG_H +#define __INC_HAL8192CPHYREG_H + + +/*--------------------------Define Parameters-------------------------------*/ + +//============================================================ +// 8192S Regsiter offset definition +//============================================================ + +// +// BB-PHY register PMAC 0x100 PHY 0x800 - 0xEFF +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 2. 0x800/0x900/0xA00/0xC00/0xD00/0xE00 +// 3. RF register 0x00-2E +// 4. Bit Mask for BB/RF register +// 5. Other defintion for BB/RF R/W +// + + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// 1. Page1(0x100) +// +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +// +// 2. Page2(0x200) +// +// The following two definition are only used for USB interface. +#define RF_BB_CMD_ADDR 0x02c0 // RF/BB read/write command address. +#define RF_BB_CMD_DATA 0x02c4 // RF/BB read/write command data. + +// +// 3. Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? + +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_PSDFunction 0x808 + +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? + +#define rFPGA0_RFTiming1 0x810 // Useless now +#define rFPGA0_RFTiming2 0x814 + +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c + +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c + +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 + +#define rFPGA0_RFWakeUpParameter 0x850 // Useless now +#define rFPGA0_RFSleepUpParameter 0x854 + +#define rFPGA0_XAB_SwitchControl 0x858 // RF Channel switch +#define rFPGA0_XCD_SwitchControl 0x85c + +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 + +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c + +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 + +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XCD_RFParameter 0x87c + +#define rFPGA0_AnalogParameter1 0x880 // Crystal cap setting RF-R/W protection for parameter4?? +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 // Useless now +#define rFPGA0_AnalogParameter4 0x88c + +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac + +#define rFPGA0_PSDReport 0x8b4 // Useless now +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 // Useless now // RF Interface Readback Value +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 // Useless now + +// +// 4. Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? + +#define rFPGA1_TxBlock 0x904 // Useless now +#define rFPGA1_DebugSelect 0x908 // Useless now +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? + +// +// 5. PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 + +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI +#define rCCK0_CCA 0xa08 // Disable init gain now // Init gain + +#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level // Antenna Diversity, RX AGC, LNA Threshold, RX LNA Threshold useless now. Not the same as 90 series +#define rCCK0_RxAGC2 0xa10 //AGC & DAGC + +#define rCCK0_RxHP 0xa14 + +#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold +#define rCCK0_DSPParameter2 0xa1c //SQ threshold + +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 +#define rCCK0_FalseAlarmReport 0xa2c //0xa2d useless now 0xa30-a4f channel report +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 //0xa57 +#define rCCK0_FACounterLower 0xa5c //0xa5b +#define rCCK0_FACounterUpper 0xa58 //0xa5c +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rConfig_Pmpd_AntB 0xb98 +#define rAPK 0xbd8 + +// +// 6. PageC(0xC00) +// +#define rOFDM0_LSTF 0xc00 + +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c + +#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c + +#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD // DM tune init gain +#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. +#define rOFDM0_RxDetector3 0xc38 //Frame Sync. +#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI + +#define rOFDM0_RxDSP 0xc40 //Rx Sync Path +#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC +#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA + +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c + +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c + +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c + +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 + +// +// 7. PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +#define rOFDM1_CFO 0xd08 // No setting now +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 + +#define rOFDM_PHYCounter1 0xda0 //cca, parity fail +#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail +#define rOFDM_PHYCounter3 0xda8 //MCS not support + +#define rOFDM_ShortCFOAB 0xdac // No setting now +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + + +// +// 8. PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c + +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c + +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 + +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c + +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c + +#define rRx_Power_Before_IQK_A 0xea0 +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A 0xea8 +#define rRx_Power_After_IQK_A_2 0xeac + +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc + +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc + +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + +// +// 7. RF Register 0x00-0x2E (RF 8256) +// RF-0222D 0x00-3F +// +//Zebra1 +#define rZebra1_HSSIEnable 0x0 // Useless now +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 // RF channel switch + +//#endif +#define rZebra1_TxGain 0x8 // Useless now +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +//Zebra4 +#define rGlobalCtrl 0 // Useless now +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +//RTL8258 +#define rRTL8258_TxLPF 0x11 // Useless now +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // + +#define RF_IQADJ_G1 0x01 // +#define RF_IQADJ_G2 0x02 // +#define RF_BS_PA_APSET_G1_G4 0x03 +#define RF_BS_PA_APSET_G5_G8 0x04 +#define RF_POW_TRSW 0x05 // + +#define RF_GAIN_RX 0x06 // +#define RF_GAIN_TX 0x07 // + +#define RF_TXM_IDAC 0x08 // +#define RF_IPA_G 0x09 // +#define RF_TXBIAS_G 0x0A +#define RF_TXPA_AG 0x0B +#define RF_IPA_A 0x0C // +#define RF_TXBIAS_A 0x0D +#define RF_BS_PA_APSET_G9_G11 0x0E +#define RF_BS_IQGEN 0x0F // + +#define RF_MODE1 0x10 // +#define RF_MODE2 0x11 // + +#define RF_RX_AGC_HP 0x12 // +#define RF_TX_AGC 0x13 // +#define RF_BIAS 0x14 // +#define RF_IPA 0x15 // +#define RF_TXBIAS 0x16 // +#define RF_POW_ABILITY 0x17 // +#define RF_MODE_AG 0x18 // +#define rRfChannel 0x18 // RF channel and BW switch +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_TOP 0x19 // + +#define RF_RX_G1 0x1A // +#define RF_RX_G2 0x1B // + +#define RF_RX_BB2 0x1C // +#define RF_RX_BB1 0x1D // + +#define RF_RCK1 0x1E // +#define RF_RCK2 0x1F // + +#define RF_TX_G1 0x20 // +#define RF_TX_G2 0x21 // +#define RF_TX_G3 0x22 // + +#define RF_TX_BB1 0x23 // + +#define RF_T_METER 0x24 // + +#define RF_SYN_G1 0x25 // RF TX Power control +#define RF_SYN_G2 0x26 // RF TX Power control +#define RF_SYN_G3 0x27 // RF TX Power control +#define RF_SYN_G4 0x28 // RF TX Power control +#define RF_SYN_G5 0x29 // RF TX Power control +#define RF_SYN_G6 0x2A // RF TX Power control +#define RF_SYN_G7 0x2B // RF TX Power control +#define RF_SYN_G8 0x2C // RF TX Power control + +#define RF_RCK_OS 0x30 // RF TX PA control + +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_TXPA_G3 0x33 // RF TX PA control + +#define RF_MIXER_BW 0x87 // RF Mixer bandwidth + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define IS_BB_REG_OFFSET_92S(_Offset) ((_Offset >= 0x800) && (_Offset <= 0xfff)) + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 + +#define bOFDMRxADCPhase 0x10000 // Useless now +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f + +#define bAntennaSelect 0x0300 + +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 + +#define bPAStart 0xf0000000 // Useless now +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf //Reg0x814 +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 //T2R +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 + +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 + +#define b3WireRFPowerDown 0x1 // Useless now +//#define bHWSISelect 0x8 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf + +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW + +#define bRFSI_TRSW 0x20 // Useless now +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 + +#define bLSSIReadAddress 0x7f800000 // T65 RF + +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal + +#define bLSSIReadBackData 0xfffff // T65 RF + +#define bLSSIReadOKFlag 0x1000 // Useless now +#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 + +#define bADClkPhase 0x4000000 // Reg 0x880 rFPGA0_AnalogParameter1 20/40 CCK support switch 40/80 BB MHZ + +#define b80MClkDelay 0x18000000 // Useless +#define bAFEWatchDogEnable 0x20000000 + +#define bXtalCap01 0xc0000000 // Reg 0x884 rFPGA0_AnalogParameter2 Crystal cap +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bXtalCap 0x0f000000 + +#define bIntDifClkEnable 0x400 // Useless +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 +#define bCCKRxAGCFormat 0x200 +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +// 3. Page9(0x900) +#define bOFDMTxSC 0x30000000 // Useless +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff //reset debug page and also HWord, LWord +#define bDebugItem 0xff //reset debug page and LWord +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 // Useless +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 + +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch + +#define bCCKScramble 0x8 // Useless +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 //CCK Rx Iinital gain polarity +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKFixedRxAGC 0x8000 +//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +// 5. PageC(0xC00) +#define bNumOfSTF 0x3 // Useless +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 //the threshold for high power +#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +//#define bRxMF_Hold 0x3800 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 +#define bDAFormat 0x40000 +#define bTxChEmuEnable 0x01000000 +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 +#define bExtLNAGain 0x7c00 + +// 6. PageE(0xE00) +#define bSTBCEn 0x4 // Useless +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +//#define bRxPath1 0x01 +//#define bRxPath2 0x02 +//#define bRxPath3 0x04 +//#define bRxPath4 0x08 +//#define bTxPath1 0x10 +//#define bTxPath2 0x20 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 //total +#define bShortCFOFLength 11 //fraction +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf // Useless +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 // Useless +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 // Useless +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +//Rx Pseduo noise +#define bRxPesudoNoiseOn 0x20000000 // Useless +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +//7. RF Register +//Zebra1 +#define bZebra1_HSSIEnable 0x8 // Useless +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +//Zebra4 +#define bRTL8256RegModeCtrl1 0x100 // Useless +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +//RTL8258 +#define bRTL8258_TxLPFBW 0xc // Useless +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + + +// +// Other Definition +// + +//byte endable for sb_write +#define bByte0 0x1 // Useless +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff // Reg 0xc50 rOFDM0_XAAGCCore~0xC6f +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 +#define bMaskOFDM_D 0xffc00000 +#define bMaskCCK 0x3f3f3f3f + +//for PutRFRegsetting & GetRFRegSetting BitMask +//#define bMask12Bits 0xfffff // RF Reg mask bits +//#define bMask20Bits 0xfffff // RF Reg mask bits T65 RF +#define bRFRegOffsetMask 0xfffff + +#define bEnable 0x1 // Useless +#define bDisable 0x0 + +#define LeftAntenna 0x0 // Useless +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 //500ms // Useless +#define tUpdateRxCounter 100 //100ms + +#define rateCCK 0 // Useless +#define rateOFDM 1 +#define rateHT 2 + +//define Register-End +#define bPMAC_End 0x1ff // Useless +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + +//define max debug item in each debug page +//#define bMaxItem_FPGA_PHY0 0x9 +//#define bMaxItem_FPGA_PHY1 0x3 +//#define bMaxItem_PHY_11B 0x16 +//#define bMaxItem_OFDM_PHY0 0x29 +//#define bMaxItem_OFDM_PHY1 0x0 + +#define bPMACControl 0x0 // Useless +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 // Useless +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +/*--------------------------Define Parameters-------------------------------*/ + + +#endif //__INC_HAL8192SPHYREG_H + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyCfg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyCfg.h new file mode 100644 index 0000000..c8e7b4c --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyCfg.h @@ -0,0 +1,186 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __INC_HAL8195APHYCFG_H__ +#define __INC_HAL8195APHYCFG_H__ + +/*--------------------------Define Parameters-------------------------------*/ +#define LOOP_LIMIT 5 +#define MAX_STALL_TIME 50 //us +#define AntennaDiversityValue 0x80 //(Adapter->bSoftwareAntennaDiversity ? 0x00:0x80) +#define MAX_TXPWR_IDX_NMODE_92S 63 +#define Reset_Cnt_Limit 3 + +#if defined (CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#define MAX_AGGR_NUM 0x0B +#else +#define MAX_AGGR_NUM 0x07 +#endif // CONFIG_PCI_HCI + + +/*--------------------------Define Parameters End-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ + +/* BB/RF related */ + +typedef struct _R_ANTENNA_SELECT_OFDM{ + u32 r_tx_antenna:4; + u32 r_ant_l:4; + u32 r_ant_non_ht:4; + u32 r_ant_ht1:4; + u32 r_ant_ht2:4; + u32 r_ant_ht_s1:4; + u32 r_ant_non_ht_s1:4; + u32 OFDM_TXSC:2; + u32 Reserved:2; +}R_ANTENNA_SELECT_OFDM; + +typedef struct _R_ANTENNA_SELECT_CCK{ + u8 r_cckrx_enable_2:2; + u8 r_cckrx_enable:2; + u8 r_ccktx_enable:4; +}R_ANTENNA_SELECT_CCK; + +/*------------------------------Define structure End----------------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ + +u32 +PHY_QueryBBReg_8195A( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetBBReg_8195A( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +u32 +PHY_QueryRFReg_8195A( + IN PADAPTER Adapter, + IN u32 eRFPath, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetRFReg_8195A( + IN PADAPTER Adapter, + IN u32 eRFPath, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +u32 PHY_QueryBBReg_8195A_Safe( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask +); + +VOID PHY_SetBBReg_8195A_Safe( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data +); + +#define PHY_QueryBBReg(Adapter, RegAddr, BitMask) PHY_QueryBBReg_8195A_Safe((Adapter), (RegAddr), (BitMask)) +#define PHY_SetBBReg(Adapter, RegAddr, BitMask, Data) PHY_SetBBReg_8195A_Safe((Adapter), (RegAddr), (BitMask), (Data)) +#define PHY_QueryRFReg(Adapter, eRFPath, RegAddr, BitMask) PHY_QueryRFReg_8195A((Adapter), (eRFPath), (RegAddr), (BitMask)) +#define PHY_SetRFReg(Adapter, eRFPath, RegAddr, BitMask, Data) PHY_SetRFReg_8195A((Adapter), (eRFPath), (RegAddr), (BitMask), (Data)) + +#define PHY_SetMacReg PHY_SetBBReg +#define PHY_QueryMacReg PHY_QueryBBReg +/* MAC/BB/RF HAL config */ +int PHY_BBConfig8195A(PADAPTER Adapter ); + +int PHY_RFConfig8195A(PADAPTER Adapter ); + +s32 PHY_MACConfig8195A(PADAPTER padapter); + +#ifdef CONFIG_SUDO_PHY_SETTING +int PHY_SudoPhyConfig8195A(PADAPTER Adapter); +#endif + +int +PHY_ConfigRFWithParaFile_8195A( + IN PADAPTER Adapter, + IN u8* pFileName, + RF_PATH eRFPath +); +int +PHY_ConfigRFWithHeaderFile_8723B( + IN PADAPTER Adapter, + RF_PATH eRFPath +); + +u8 +PHY_GetTxPowerIndex_8195A( + IN PADAPTER pAdapter, + IN u8 RFPath, + IN u8 Rate, + IN CHANNEL_WIDTH BandWidth, + IN u8 Channel + ); + +VOID +PHY_SetTxPowerLevel8195A( + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetBWMode8195A( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth, // 20M or 40M + IN unsigned char Offset // Upper, Lower, or Don't care +); + +VOID +PHY_SwChnl8195A( // Call after initialization + IN PADAPTER Adapter, + IN u8 channel + ); + +VOID +PHY_SetSwChnlBWMode8195A( + IN PADAPTER Adapter, + IN u8 channel, + IN CHANNEL_WIDTH Bandwidth, + IN u8 Offset40, + IN u8 Offset80 +); + +VOID PHY_SetRFPathSwitch_8723B( + IN PADAPTER pAdapter, + IN BOOLEAN bMain + ); + +/*--------------------------Exported Function prototype End---------------------*/ + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyReg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyReg.h new file mode 100644 index 0000000..1ae9e30 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APhyReg.h @@ -0,0 +1,272 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __INC_HAL8195APHYREG_H__ +#define __INC_HAL8195APHYREG_H__ + +// +// 1. PMAC duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF +// Page1(0x100) +// +#define rPMAC_Reset 0x100 + +// +// Page8(0x800) +// +#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC // RF BW Setting?? +#define rFPGA0_TxInfo 0x804 // Status report?? +#define rFPGA0_TxGainStage 0x80c // Set TX PWR init gain? +#define rFPGA0_XA_HSSIParameter1 0x820 // RF 3 wire register +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rTxAGC_B_Rate18_06 0x830 +#define rTxAGC_B_Rate54_24 0x834 +#define rTxAGC_B_CCK1_55_Mcs32 0x838 +#define rTxAGC_B_Mcs03_Mcs00 0x83c +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 +#define rTxAGC_B_Mcs07_Mcs04 0x848 +#define rTxAGC_B_Mcs11_Mcs08 0x84c +#define rFPGA0_XCD_SwitchControl 0x85c +#define rFPGA0_XA_RFInterfaceOE 0x860 // RF Channel switch +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rTxAGC_B_CCK11_A_CCK2_11 0x86c +#define rTxAGC_B_Mcs15_Mcs12 0x868 +#define rFPGA0_XAB_RFInterfaceSW 0x870 // RF Interface Software Control +#define rFPGA0_XCD_RFInterfaceSW 0x874 +#define rFPGA0_XAB_RFParameter 0x878 // RF Parameter +#define rFPGA0_XA_LSSIReadBack 0x8a0 // Tranceiver LSSI Readback +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac +#define TransceiverA_HSPI_Readback 0x8b8 // Transceiver A HSPI Readback +#define TransceiverB_HSPI_Readback 0x8bc // Transceiver B HSPI Readback + +// +// Page9(0x900) +// +#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC // RF BW Setting?? +#define rFPGA1_TxInfo 0x90c // Useless now // Status report?? +#define rS0S1_PathSwitch 0x948 +#define rRXDFIR_Filter 0x954 + +// +// PageA(0xA00) +// +// Set Control channel to upper or lower. These settings are required only for 40MHz +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 // Disable init gain now // Select RX path by RSSI + +// +// PageB(0xB00) +// +#define rPdp_AntA 0xb00 +#define rPdp_AntA_4 0xb04 +#define rPdp_AntA_8 0xb08 +#define rPdp_AntA_C 0xb0c +#define rPdp_AntA_10 0xb10 +#define rPdp_AntA_14 0xb14 +#define rPdp_AntA_18 0xb18 +#define rPdp_AntA_1C 0xb1c +#define rPdp_AntA_20 0xb20 +#define rPdp_AntA_24 0xb24 + +#define rConfig_Pmpd_AntA 0xb28 +#define rConfig_ram64x16 0xb2c + +#define rBndA 0xb30 +#define rHssiPar 0xb34 + +#define rConfig_AntA 0xb68 +#define rConfig_AntB 0xb6c + +#define rPdp_AntB 0xb70 +#define rPdp_AntB_4 0xb74 +#define rPdp_AntB_8 0xb78 +#define rPdp_AntB_C 0xb7c +#define rPdp_AntB_10 0xb80 +#define rPdp_AntB_14 0xb84 +#define rPdp_AntB_18 0xb88 +#define rPdp_AntB_1C 0xb8c +#define rPdp_AntB_20 0xb90 +#define rPdp_AntB_24 0xb94 + +#define rConfig_Pmpd_AntB 0xb98 + +#define rBndB 0xba0 + +#define rAPK 0xbd8 +#define rPm_Rx0_AntA 0xbdc +#define rPm_Rx1_AntA 0xbe0 +#define rPm_Rx2_AntA 0xbe4 +#define rPm_Rx3_AntA 0xbe8 +#define rPm_Rx0_AntB 0xbec +#define rPm_Rx1_AntB 0xbf0 +#define rPm_Rx2_AntB 0xbf4 +#define rPm_Rx3_AntB 0xbf8 + +// +// PageC(0xC00) +// +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_XARxAFE 0xc10 // RxIQ DC offset, Rx digital filter, DC notch filter +#define rOFDM0_XARxIQImbalance 0xc14 // RxIQ imblance matrix +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_RxDetector1 0xc30 // PD,BW & SBD // DM tune init gain +#define rOFDM0_ECCAThreshold 0xc4c // energy CCA +#define rOFDM0_XAAGCCore1 0xc50 // DIG +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_XATxIQImbalance 0xc80 // TX PWR TRACK and DIG +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_RxIQExtAnta 0xca0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 // Double ADC + +// +// PageD(0xD00) +// +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 + +// +// PageE(0xE00) +// +#define rTxAGC_A_Rate18_06 0xe00 +#define rTxAGC_A_Rate54_24 0xe04 +#define rTxAGC_A_CCK1_Mcs32 0xe08 +#define rTxAGC_A_Mcs03_Mcs00 0xe10 +#define rTxAGC_A_Mcs07_Mcs04 0xe14 +#define rTxAGC_A_Mcs11_Mcs08 0xe18 +#define rTxAGC_A_Mcs15_Mcs12 0xe1c +#define rFPGA0_IQK 0xe28 +#define rTx_IQK_Tone_A 0xe30 +#define rRx_IQK_Tone_A 0xe34 +#define rTx_IQK_PI_A 0xe38 +#define rRx_IQK_PI_A 0xe3c +#define rTx_IQK 0xe40 +#define rRx_IQK 0xe44 +#define rIQK_AGC_Pts 0xe48 +#define rIQK_AGC_Rsp 0xe4c +#define rTx_IQK_Tone_B 0xe50 +#define rRx_IQK_Tone_B 0xe54 +#define rTx_IQK_PI_B 0xe58 +#define rRx_IQK_PI_B 0xe5c +#define rIQK_AGC_Cont 0xe60 +#define rBlue_Tooth 0xe6c +#define rRx_Wait_CCA 0xe70 // Rx ADC clock +#define rTx_CCK_RFON 0xe74 +#define rTx_CCK_BBON 0xe78 +#define rTx_OFDM_RFON 0xe7c +#define rTx_OFDM_BBON 0xe80 +#define rTx_To_Rx 0xe84 +#define rTx_To_Tx 0xe88 +#define rRx_CCK 0xe8c +#define rTx_Power_Before_IQK_A 0xe94 +#define rTx_Power_After_IQK_A 0xe9c +#define rRx_Power_Before_IQK_A_2 0xea4 +#define rRx_Power_After_IQK_A_2 0xeac +#define rTx_Power_Before_IQK_B 0xeb4 +#define rTx_Power_After_IQK_B 0xebc +#define rRx_Power_Before_IQK_B 0xec0 +#define rRx_Power_Before_IQK_B_2 0xec4 +#define rRx_Power_After_IQK_B 0xec8 +#define rRx_Power_After_IQK_B_2 0xecc +#define rRx_OFDM 0xed0 +#define rRx_Wait_RIFS 0xed4 +#define rRx_TO_Rx 0xed8 +#define rStandby 0xedc +#define rSleep 0xee0 +#define rPMPD_ANAEN 0xeec + + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskH3Bytes 0xffffff00 + +// +// RL6052 Register definition +// +#define RF_AC 0x00 // +#define RF_TXM_IDAC 0x08 // +#define RF_CHNLBW 0x18 // RF channel and BW switch +#define RF_RCK_OS 0x30 // RF TX PA control +#define RF_TXPA_G1 0x31 // RF TX PA control +#define RF_TXPA_G2 0x32 // RF TX PA control +#define RF_WE_LUT 0xEF + +// +//Bit Mask +// +// 1. Page1(0x100) +#define bBBResetB 0x100 // Useless now? + +// 2. Page8(0x800) +#define bRFMOD 0x1 // Reg 0x800 rFPGA0_RFMOD +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bXBTxAGC 0xf00 // Reg 80c rFPGA0_TxGainStage +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 +#define b3WireDataLength 0x800 // Reg 0x820~84f rFPGA0_XA_HSSIParameter1 +#define b3WireAddressLength 0x400 +#define bRFSI_RFENV 0x10 // Reg 0x870 rFPGA0_XAB_RFInterfaceSW +#define bLSSIReadAddress 0x7f800000 // T65 RF +#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal +#define bLSSIReadBackData 0xfffff // T65 RF + +// 3. Page9(0x900) + +// 4. PageA(0xA00) +#define bCCKBBMode 0x3 +#define bCCKSideBand 0x10 // Reg 0xa00 rCCK0_System 20/40 switch +#define bCCKScramble 0x8 +#define bCCKTxRate 0x3000 + + +// 5. PageC(0xC00) + +// 6. PageE(0xE00) +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 + +// +// Other Definition +// + +//for PutRegsetting & GetRegSetting BitMask +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff +#define bMask12Bits 0xfff +#define bMaskH4Bits 0xf0000000 + +#define bEnable 0x1 +#define bDisable 0x0 + + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APwrSeq.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APwrSeq.h new file mode 100644 index 0000000..2de0a12 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/Hal8195APwrSeq.h @@ -0,0 +1,397 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef REALTEK_POWER_SEQUENCE_8195A +#define REALTEK_POWER_SEQUENCE_8195A + +#include "HalPwrSeqCmd.h" + +/* + Check document WM-20130111-JackieLau-RTL8723B_Power_Architecture v02.vsd + There are 6 HW Power States: + 0: POFF--Power Off + 1: PDN--Power Down + 2: CARDEMU--Card Emulation + 3: ACT--Active Mode + 4: LPS--Low Power State + 5: SUS--Suspend + + The transision from different states are defined below + TRANS_CARDEMU_TO_ACT + TRANS_ACT_TO_CARDEMU + TRANS_CARDEMU_TO_SUS + TRANS_SUS_TO_CARDEMU + TRANS_CARDEMU_TO_PDN + TRANS_ACT_TO_LPS + TRANS_LPS_TO_ACT + + TRANS_END +*/ +#define RTL8195A_TRANS_CARDEMU_TO_ACT_STEPS 4 +#define RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS 4 +#define RTL8195A_TRANS_CARDEMU_TO_SUS_STEPS 7 +#define RTL8195A_TRANS_SUS_TO_CARDEMU_STEPS 15 +#define RTL8195A_TRANS_CARDEMU_TO_PDN_STEPS 15 +#define RTL8195A_TRANS_PDN_TO_CARDEMU_STEPS 15 +#define RTL8195A_TRANS_ACT_TO_LPS_STEPS 15 +#define RTL8195A_TRANS_LPS_TO_ACT_STEPS 15 +#define RTL8195A_TRANS_ACT_TO_SWLPS_STEPS 22 +#define RTL8195A_TRANS_SWLPS_TO_ACT_STEPS 15 +#define RTL8195A_TRANS_END_STEPS 1 +//1TODO:chris +#if 1 +#define RTL8195A_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0004, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},\ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},\ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ + + +#define RTL8195A_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT0|BIT1|BIT2), 0},/*0x04[24:26] = 0 turn off RF*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT0|BIT1), 0},/*0x04[16:17] = 0 BB reset*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x20[1] = 1 turn off MAC by HW state machine*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x20[1] = 0 polling until return 0 to disable*/ \ + +#define RTL8195A_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8195A_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8195A_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + +#define RTL8195A_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + + +#define RTL8195A_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8195A_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8195A_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ + + +#define RTL8195A_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + + #define RTL8195A_TRANS_ACT_TO_SWLPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable 32 K source*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*disable security engine*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x40},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*reset dual TSF*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/*Reset CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*Reset MCUFWDL register*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*Reset CPU IO Wrapper*/ \ + {0x0287, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*polling RXFF packet number = 0 */ \ + {0x0286, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/*polling RXDMA idle */ \ + {0x013D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Clear FW RPWM interrupt */\ + {0x0139, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW RPWM interrupt source*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/*polling TSF stable*/\ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW LPS*/ \ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/*polling FW LPS ready */ + + +#define RTL8195A_TRANS_SWLPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*polling TSF stable*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1, enable security engine*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x06B7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x09}, /*. reset MAC rx state machine*/\ + {0x06B4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x86}, /*. reset MAC rx state machine*/\ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/* set CPU RAM code ready*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* Enable CPU*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2},/* Enable CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, BIT7},/*polling FW init ready */ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT6, BIT6},/*polling FW init ready */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + + +#else + +#define RTL8723B_TRANS_CARDEMU_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*0x20[0] = 1b'1 enable LDOA12 MACRO block for all interface*/ \ + {0x0067, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x67[0] = 0 to disable BT_GPS_SEL pins*/ \ + {0x0001, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 1, PWRSEQ_DELAY_MS},/*Delay 1ms*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, 0}, /*0x00[5] = 1b'0 release analog Ips to digital ,1:isolation*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* disable SW LPS 0x04[10]=0*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/* wait till 0x04[17] = 1 power ready*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* release WLON reset 0x04[16]=1*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* disable HWPDN 0x04[15]=0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, (BIT4|BIT3), 0},/* disable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/* polling until return 0*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/**/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/* Enable WL control XTAL setting*/ \ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable falling edge triggering interrupt*/\ + {0x0063, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable GPIO9 interrupt mode*/\ + {0x0062, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable GPIO9 input mode*/\ + {0x0058, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Enable HSISR GPIO[C:0] interrupt*/\ + {0x005A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/*Enable HSISR GPIO9 interrupt*/\ + {0x0068, PWR_CUT_TESTCHIP_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3, BIT3},/*For GPIO9 internal pull high setting by test chip*/\ + {0x0069, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, BIT6},/*For GPIO9 internal pull high setting*/ + +#define RTL8723B_TRANS_ACT_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*0x1F[7:0] = 0 turn off RF*/ \ + {0x004F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*0x4C[24] = 0x4F[0] = 0, switch DPDT_SEL_P output from register 0x65[2] */\ + {0x0049, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Enable rising edge triggering interrupt*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*0x04[9] = 1 turn off MAC by HW state machine*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, 0}, /*wait till 0x04[9] = 0 polling until return 0 to disable*/ \ + {0x0010, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6, 0},/* Enable BT control XTAL setting*/ \ + {0x0000, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5}, /*0x00[5] = 1b'1 analog Ips to digital ,1:isolation*/ \ + {0x0020, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x20[0] = 1b'0 disable LDOA12 MACRO block*/ \ + + +#define RTL8723B_TRANS_CARDEMU_TO_SUS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4|BIT3, (BIT4|BIT3)}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SDIO SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3|BIT4}, /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723B_TRANS_SUS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/ + +#define RTL8723B_TRANS_CARDEMU_TO_CARDDIS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07=0x20 , SOP option to disable BG/MB*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, BIT3}, /*0x04[12:11] = 2b'01 enable WL suspend*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2}, /*0x04[10] = 1, enable SW LPS*/ \ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1}, /*0x48[16] = 1 to enable GPIO9 as EXT WAKEUP*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, BIT0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, 0}, /*wait power state to suspend*/ + +#define RTL8723B_TRANS_CARDDIS_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3 | BIT7, 0}, /*clear suspend enable and power down enable*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, BIT0, 0}, /*Set SDIO suspend local register*/ \ + {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_POLLING, BIT1, BIT1}, /*wait power state to suspend*/\ + {0x004A, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0}, /*0x48[16] = 0 to disable GPIO9 as EXT WAKEUP*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT3|BIT4, 0}, /*0x04[12:11] = 2b'01enable WL suspend*/\ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*0x23[4] = 1b'0 12H LDO enter normal mode*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*PCIe DMA start*/ + + +#define RTL8723B_TRANS_CARDEMU_TO_PDN \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0023, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4}, /*0x23[4] = 1b'1 12H LDO enter sleep mode*/ \ + {0x0007, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK|PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x20}, /*0x07[7:0] = 0x20 SOP option to disable BG/MB/ACK/SWR*/ \ + {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/* 0x04[16] = 0*/\ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/* 0x04[15] = 1*/ + +#define RTL8723B_TRANS_PDN_TO_CARDEMU \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/* 0x04[15] = 0*/ + +#define RTL8723B_TRANS_ACT_TO_LPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*PCIe DMA stop*/ \ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF},/*Tx Pause*/ \ + {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*Should be zero if no packet is transmitting*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US},/*Delay 1us*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*Whole BB is reset*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x03},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*check if removed later*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x00},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*Respond TxOK to scheduler*/ + + +#define RTL8723B_TRANS_LPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_SDIO,PWR_CMD_WRITE, 0xFF, 0x84}, /*SDIO RPWM*/\ + {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*USB RPWM*/\ + {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x84}, /*PCIe RPWM*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, /*Delay*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0}, /*. 0x08[4] = 0 switch TSF to 40M*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, 0}, /*Polling 0x109[7]=0 TSF in 40M*/\ + {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT6|BIT7, 0}, /*. 0x29[7:6] = 2b'00 enable BB clock*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1|BIT0, BIT1|BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + + #define RTL8723B_TRANS_ACT_TO_SWLPS \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0194, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable 32 K source*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*CCK and OFDM are enable*/ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*CCK and OFDM are disabled,and clock are gated*/ \ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x3F},/*Reset MAC TRX*/ \ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, 0},/*disable security engine*/ \ + {0x0093, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x40},/*When driver enter Sus/ Disable, enable LOP for BT*/ \ + {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT5, BIT5},/*reset dual TSF*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/*Reset CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0},/*Reset MCUFWDL register*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 1},/*Reset CPU IO Wrapper*/ \ + {0x0287, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, 0xFF, 0},/*polling RXFF packet number = 0 */ \ + {0x0286, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT1, BIT1},/*polling RXDMA idle */ \ + {0x013D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Clear FW RPWM interrupt */\ + {0x0139, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW RPWM interrupt source*/\ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, BIT4},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, BIT7},/*polling TSF stable*/\ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*Set FW LPS*/ \ + {0x0090, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT0, 0},/*polling FW LPS ready */ + + +#define RTL8723B_TRANS_SWLPS_TO_ACT \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT4, 0},/*switch TSF to 32K*/\ + {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT7, 0},/*polling TSF stable*/\ + {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1}, /*. 0x101[1] = 1, enable security engine*/\ + {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0xFF}, /*. 0x100[7:0] = 0xFF enable WMAC TRX*/\ + {0x06B7, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x09}, /*. reset MAC rx state machine*/\ + {0x06B4, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0x86}, /*. reset MAC rx state machine*/\ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT1, BIT1},/* set CPU RAM code ready*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, 0},/*Reset CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, 0},/* Enable CPU*/ \ + {0x001D, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0},/*enable CPU IO Wrapper*/ \ + {0x0003, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT2, BIT2},/* Enable CPU*/ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT7, BIT7},/*polling FW init ready */ \ + {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_POLLING, BIT6, BIT6},/*polling FW init ready */ \ + {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, BIT0, BIT0}, /*. 0x02[1:0] = 2b'11 enable BB macro*/\ + {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK,PWR_BASEADDR_MAC,PWR_CMD_WRITE, 0xFF, 0}, /*. 0x522 = 0*/ + + +#endif + + + +#define RTL8195A_TRANS_END \ + /* format */ \ + /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, // comments here*/ \ + {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,0,PWR_CMD_END, 0, 0}, // + + +extern WLAN_PWR_CFG rtl8195A_power_on_flow[RTL8195A_TRANS_CARDEMU_TO_ACT_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_radio_off_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_card_disable_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_card_enable_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_suspend_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_resume_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_CARDEMU_TO_SUS_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_hwpdn_flow[RTL8195A_TRANS_ACT_TO_CARDEMU_STEPS+RTL8195A_TRANS_CARDEMU_TO_PDN_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_enter_lps_flow[RTL8195A_TRANS_ACT_TO_LPS_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_leave_lps_flow[RTL8195A_TRANS_LPS_TO_ACT_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_enter_swlps_flow[RTL8195A_TRANS_ACT_TO_SWLPS_STEPS+RTL8195A_TRANS_END_STEPS]; +extern WLAN_PWR_CFG rtl8195A_leave_swlps_flow[RTL8195A_TRANS_SWLPS_TO_ACT_STEPS+RTL8195A_TRANS_END_STEPS]; +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rom_Hal8195APhyCfg.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rom_Hal8195APhyCfg.h new file mode 100644 index 0000000..5dce5ce --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rom_Hal8195APhyCfg.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __ROM_HAL8195APHYCFG_H__ +#define __ROM_HAL8195APHYCFG_H__ + +/*--------------------------Define Parameters-------------------------------*/ + +/*--------------------------Define Parameters End-------------------------------*/ + +/*------------------------------Define structure----------------------------*/ + +/*------------------------------Define structure End----------------------------*/ + +/*--------------------------Exported Function prototype---------------------*/ + +u32 +phy_CalculateBitShift( + u32 BitMask + ); + +u32 +PHY_QueryBBReg_8195A( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask + ); + +VOID +PHY_SetBBReg_8195A( + IN PADAPTER Adapter, + IN u32 RegAddr, + IN u32 BitMask, + IN u32 Data + ); + +/*--------------------------Exported Function prototype End---------------------*/ + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_cmd.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_cmd.h new file mode 100644 index 0000000..3ef53e9 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_cmd.h @@ -0,0 +1,337 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_CMD_H__ +#define __RTL8195A_CMD_H__ + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD DEFINITION ------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +enum h2c_cmd_8195A{ + //Common Class: 000 + H2C_8195A_RSVD_PAGE = 0x00, + H2C_8195A_MEDIA_STATUS_RPT = 0x01, + H2C_8195A_SCAN_ENABLE = 0x02, + H2C_8195A_KEEP_ALIVE = 0x03, + H2C_8195A_DISCON_DECISION = 0x04, + H2C_8195A_PSD_OFFLOAD = 0x05, + H2C_8195A_AP_OFFLOAD = 0x08, + H2C_8195A_BCN_RSVDPAGE = 0x09, + H2C_8195A_PROBERSP_RSVDPAGE = 0x0A, + H2C_8195A_FCS_RSVDPAGE = 0x10, + H2C_8195A_FCS_INFO = 0x11, + + //PoweSave Class: 001 + H2C_8195A_SET_PWR_MODE = 0x20, + H2C_8195A_PS_TUNING_PARA = 0x21, + H2C_8195A_PS_TUNING_PARA2 = 0x22, + H2C_8195A_P2P_LPS_PARAM = 0x23, + H2C_8195A_P2P_PS_OFFLOAD = 0x24, + H2C_8195A_PS_SCAN_ENABLE = 0x25, + H2C_8195A_SAP_PS_ = 0x26, + H2C_8195A_INACTIVE_PS_ = 0x27, //Inactive_PS + H2C_8195A_FWLPS_IN_IPS_ = 0x28, + + + //Dynamic Mechanism Class: 010 + H2C_8195A_MACID_CFG = 0x40, + H2C_8195A_TXBF = 0x41, + H2C_8195A_RSSI_SETTING = 0x42, + H2C_8195A_AP_REQ_TXRPT = 0x43, + H2C_8195A_INIT_RATE_COLLECT = 0x44, + + //BT Class: 011 + H2C_8195A_B_TYPE_TDMA = 0x60, + H2C_8195A_BT_INFO = 0x61, + H2C_8195A_FORCE_BT_TXPWR = 0x62, + H2C_8195A_BT_IGNORE_WLANACT = 0x63, + H2C_8195A_DAC_SWING_VALUE = 0x64, + H2C_8195A_ANT_SEL_RSV = 0x65, + H2C_8195A_WL_OPMODE = 0x66, + H2C_8195A_BT_MP_OPER = 0x67, + H2C_8195A_BT_CONTROL = 0x68, + H2C_8195A_BT_WIFI_CTRL = 0x69, + H2C_8195A_BT_FW_PATCH = 0x6A, + + //WOWLAN Class: 100 + H2C_8195A_WOWLAN = 0x80, + H2C_8195A_REMOTE_WAKE_CTRL = 0x81, + H2C_8195A_AOAC_GLOBAL_INFO = 0x82, + H2C_8195A_AOAC_RSVD_PAGE = 0x83, + H2C_8195A_AOAC_RSVD_PAGE2 = 0x84, + H2C_8195A_D0_SCAN_OFFLOAD_INFO = 0x85, + H2C_8195A_D0_SCAN_OFFLOAD_CTRL = 0x86, + H2C_8195A_CHNL_SWITCH_OFFLOAD = 0x87, + + H2C_8195A_RESET_TSF = 0xC0, + H2C_8195A_BCN_IGNORE_EDCCA = 0xC2, + + H2C_8195A_MAXID, +}; + +#define H2C_8195A_RSVDPAGE_LOC_LEN 5 +#define H2C_8195A_MEDIA_STATUS_RPT_LEN 3 +#define H2C_8195A_KEEP_ALIVE_CTRL_LEN 2 +#define H2C_8195A_DISCON_DECISION_LEN 3 +//#define H2C_8195A_AP_OFFLOAD_LEN 3 +#define H2C_8195A_PWRMODE_LEN 11 +#define H2C_8195A_PSTUNEPARAM_LEN 4 +#define H2C_8195A_MACID_CFG_LEN 7 +#define H2C_8195A_BTMP_OPER_LEN 4 +#define H2C_8195A_WOWLAN_LEN 3 +#define H2C_8195A_REMOTE_WAKE_CTRL_LEN 1 +#define H2C_8195A_AOAC_GLOBAL_INFO_LEN 2 +#define H2C_8195A_AOAC_RSVDPAGE_LOC_LEN 7 +//#define H2C_8723B_SCAN_OFFLOAD_CTRL_LEN 4 +#define H2C_8195A_BT_FW_PATCH_LEN 6 +#define H2C_8195A_RSSI_SETTING_LEN 4 +#define H2C_8195A_AP_REQ_TXRPT_LEN 2 +#define H2C_8195A_FORCE_BT_TXPWR_LEN 3 +#define H2C_8195A_BCN_IGNORE_EDCCA_LEN 1 + + +#ifdef CONFIG_WOWLAN +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) +#define cpIpAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3]) + +// +// ARP packet +// +// LLC Header +#define GET_ARP_PKT_LLC_TYPE(__pHeader) ReadEF2Byte( ((u8*)(__pHeader)) + 6) + +//ARP element +#define GET_ARP_PKT_OPERATION(__pHeader) ReadEF2Byte( ((u8*)(__pHeader)) + 6) +#define GET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+8) +#define GET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+14) +#define GET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+18) +#define GET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+24) + +#define SET_ARP_PKT_HW(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 0, __Value) +#define SET_ARP_PKT_PROTOCOL(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 2, __Value) +#define SET_ARP_PKT_HW_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 4, __Value) +#define SET_ARP_PKT_PROTOCOL_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 5, __Value) +#define SET_ARP_PKT_OPERATION(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 6, __Value) +#define SET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+8, (u8*)(_val)) +#define SET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+14, (u8*)(_val)) +#define SET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+18, (u8*)(_val)) +#define SET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+24, (u8*)(_val)) + +#define FW_WOWLAN_FUN_EN BIT(0) +#define FW_WOWLAN_PATTERN_MATCH BIT(1) +#define FW_WOWLAN_MAGIC_PKT BIT(2) +#define FW_WOWLAN_UNICAST BIT(3) +#define FW_WOWLAN_ALL_PKT_DROP BIT(4) +#define FW_WOWLAN_GPIO_ACTIVE BIT(5) +#define FW_WOWLAN_REKEY_WAKEUP BIT(6) +#define FW_WOWLAN_DEAUTH_WAKEUP BIT(7) + +#define FW_WOWLAN_GPIO_WAKEUP_EN BIT(0) +#define FW_FW_PARSE_MAGIC_PKT BIT(1) + +#define FW_REMOTE_WAKE_CTRL_EN BIT(0) +#define FW_REALWOWLAN_EN BIT(5) + +#endif //CONFIG_WOWLAN + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- H2C CMD CONTENT --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +//_RSVDPAGE_LOC_CMD_0x00 +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_PSPOLL(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) + +//_MEDIA_STATUS_RPT_PARM_CMD_0x01 +#define SET_8723B_H2CCMD_MSRRPT_PARM_OPMODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_MSRRPT_PARM_MACID_IND(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_MSRRPT_PARM_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_MSRRPT_PARM_MACID_END(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +//_KEEP_ALIVE_CMD_0x03 +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +//_DISCONNECT_DECISION_CMD_0x04 +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) + +// _PWR_MOD_CMD_0x20 +#define SET_8723B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 4, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 4, 4, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_PWR_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_BYTE5(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_TDMA_SLOT_LEN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+7, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_TDMA_PERIOD_LEN_1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+8, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_TDMA_PERIOD_LEN_2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+9, 0, 8, __Value) +#define SET_8723B_H2CCMD_PWRMODE_PARM_TDMA_PERIOD_LEN_3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+10, 0, 8, __Value) + +#define GET_8723B_H2CCMD_PWRMODE_PARM_MODE(__pH2CCmd) LE_BITS_TO_1BYTE(__pH2CCmd, 0, 8) + +// _PS_TUNE_PARAM_CMD_0x21 +#define SET_8723B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_ADOPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 1, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 1, 7, __Value) +#define SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +//_MACID_CFG_CMD_0x40 +#define SET_8723B_H2CCMD_MACID_CFG_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RAID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 5, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_SGI_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 7, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_BW(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 2, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_NO_UPDATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 3, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_VHT_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 4, 2, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_DISPT(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 6, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_DISRA(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 7, 1, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+5, 0, 8, __Value) +#define SET_8723B_H2CCMD_MACID_CFG_RATE_MASK3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+6, 0, 8, __Value) + +//_RSSI_SETTING_CMD_0x42 +#define SET_8723B_H2CCMD_RSSI_SETTING_MACID(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_RSSI_SETTING_RSSI(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 7, __Value) +#define SET_8723B_H2CCMD_RSSI_SETTING_ULDL_STATE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +// _AP_REQ_TXRPT_CMD_0x43 +#define SET_8723B_H2CCMD_APREQRPT_PARM_MACID1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_APREQRPT_PARM_MACID2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) + +// _FORCE_BT_TXPWR_CMD_0x62 +#define SET_8723B_H2CCMD_BT_PWR_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE_8BIT(__pH2CCmd, 0, 8, __Value) + +// _FORCE_BT_MP_OPER_CMD_0x67 +#define SET_8723B_H2CCMD_BT_MPOPER_VER(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 4, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_REQNUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 4, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_IDX(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_PARAM1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_MPOPER_PARAM2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd+3, 0, 8, __Value) + +// _BT_FW_PATCH_0x6A +#define SET_8723B_H2CCMD_BT_FW_PATCH_SIZE(__pH2CCmd, __Value) SET_BITS_TO_LE_2BYTE((pu1Byte)(__pH2CCmd), 0, 16, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR0(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR1(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR2(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_BT_FW_PATCH_ADDR3(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) + +// _WoWLAN PARAM_CMD_0x80 +#define SET_8723B_H2CCMD_WOWLAN_FUNC_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_ALL_PKT_DROP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 4, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_GPIO_ACTIVE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 5, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_REKEY_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 6, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_GPIONUM(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 7, __Value) +#define SET_8723B_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 7, 1, __Value) +#define SET_8723B_H2CCMD_WOWLAN_GPIO_DURATION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) + +// _REMOTE_WAKEUP_CMD_0x81 +#define SET_8723B_H2CCMD_REMOTE_WAKECTRL_ENABLE(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 1, __Value) +#define SET_8723B_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 1, 1, __Value) +#define SET_8723B_H2CCMD_REMOTE_WAKE_CTRL_NDP_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 2, 1, __Value) +#define SET_8723B_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 3, 1, __Value) +#define SET_8723B_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 7, 1, __Value) +#define SET_8723B_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 1, __Value) + +// AOAC_GLOBAL_INFO_0x82 +#define SET_8723B_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE(__pH2CCmd, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) + +// AOAC_RSVDPAGE_LOC_0x83 +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd), 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+1, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+2, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+3, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+4, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_REQ(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+5, 0, 8, __Value) +#define SET_8723B_H2CCMD_AOAC_RSVDPAGE_LOC_NETWORK_LIST(__pH2CCmd, __Value) SET_BITS_TO_LE_1BYTE((__pH2CCmd)+6, 0, 8, __Value) + +//---------------------------------------------------------------------------------------------------------// +//------------------------------------------- Structure --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// +typedef struct _RSVDPAGE_LOC { + u8 LocProbeRsp; + u8 LocPsPoll; + u8 LocNullData; + u8 LocQosNull; + u8 LocBTQosNull; +#ifdef CONFIG_WOWLAN + u8 LocRemoteCtrlInfo; + u8 LocArpRsp; + u8 LocNbrAdv; + u8 LocGTKRsp; + u8 LocGTKInfo; + u8 LocProbeReq; + u8 LocNetList; +#endif //CONFIG_WOWLAN +} RSVDPAGE_LOC_8195A, *PRSVDPAGE_LOC_8195A; + + +//---------------------------------------------------------------------------------------------------------// +//---------------------------------- Function Statement --------------------------------------------------// +//---------------------------------------------------------------------------------------------------------// + +// host message to firmware cmd +void rtl8195a_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode); +void rtl8195a_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus); +#ifdef CONFIG_BT_COEXIST +void rtl8195a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(PADAPTER padapter); +#endif +void rtl8195a_set_rssi_cmd(PADAPTER padapter, u8 *param); +void rtl8195a_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8* arg, u8 rssi_level); +void rtl8195a_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack); +//s32 rtl8723b_set_lowpwr_lps_cmd(PADAPTER padapter, u8 enable); +void rtl8195a_set_FwPsTuneParam_cmd(PADAPTER padapter); +void rtl8195a_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask); +void rtl8195a_set_FwMediaStatusRpt_cmd(PADAPTER padapter, u8 mstatus, u8 macid); +void rtl8195a_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param); +void rtl8195a_download_rsvd_page(PADAPTER padapter, u8 mstatus); +#ifdef CONFIG_P2P +void rtl8195a_set_p2p_ps_offload_cmd(PADAPTER padapter, u8 p2p_ps_state); +#endif //CONFIG_P2P + +void CheckFwRsvdPageContent(PADAPTER padapter); + +#ifdef CONFIG_WOWLAN +void rtl8195a_set_wowlan_cmd(_adapter* padapter, u8 enable); +void SetFwRelatedForWoWLAN8195a(_adapter* padapter, u8 bHostIsGoingtoSleep); +#endif//CONFIG_WOWLAN + +void rtl8195a_set_FwPwrModeInIPS_cmd(PADAPTER padapter); + +#ifdef CONFIG_TSF_RESET_OFFLOAD +u8 rtl8195a_reset_tsf(_adapter *padapter, u8 reset_port); +#endif // CONFIG_TSF_RESET_OFFLOAD +s32 FillH2CCmd8195A(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer); + +#define FillH2CCmd FillH2CCmd8195A +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_dm.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_dm.h new file mode 100644 index 0000000..3bafb95 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_dm.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_DM_H__ +#define __RTL8195A_DM_H__ +enum{ + UP_LINK, + DOWN_LINK, +}; + +enum{ + LLT, + TXRPT, + RXBUFF, + TXBUFF, +}; + +//============================================================ +// Description: +// +// This file is for 8723B dynamic mechanism only +// +// +//============================================================ + +//0x8000: TXRPT:2K +//max macid : 128 +//TXRPT SIZE 16 bytes +//0x8800: Rate Mask:1K +//Ramask size 8bytes + + +#define DYNAMIC_FUNC_BT BIT(0) + + +#define REPORT_OFFSET 0x8100 +#define RAMASK_OFFSET 0x8900 +#define LLT_H_ADDR 0x650 +#define TXREPORT_H_ADDR 0x660 +#define RXBUFF_H_ADDR 0x670 +#define TXBUFF_H_ADDR 0x680 + + + +//============================================================ +// structure and define +//============================================================ + +//============================================================ +// function prototype +//============================================================ + +void rtl8195a_init_dm_priv(PADAPTER padapter); +void rtl8195a_deinit_dm_priv(PADAPTER padapter); + +void rtl8195a_InitHalDm(PADAPTER padapter); +void rtl8195a_HalDmWatchDog(PADAPTER padapter); +void rtl8195a_HalDmWatchDog_in_LPS(PADAPTER padapter); +void rtl8195a_hal_dm_in_lps(PADAPTER padapter); +u8 ReadTxrpt8(IN PADAPTER padapter, IN u8 Macid, IN u8 Offset); +VOID WriteTxrpt8(IN PADAPTER padapter, IN u8 Macid, IN u8 Offset, IN u8 Val); +BOOLEAN GetMediaStatusCommon(IN PADAPTER pAdapter, IN u8 macid); +VOID GetTxrptStatistic(IN PDM_ODM_T pDM_Odm, IN PODM_RA_INFO_T pRaInfo,IN u8 Reset_var); +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_led.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_led.h new file mode 100644 index 0000000..700e32f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_led.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_LED_H__ +#define __RTL8195A_LED_H__ + +#include +#include +#include + + +//================================================================================ +// Interface to manipulate LED objects. +//================================================================================ +void rtl8195a_InitSwLeds(PADAPTER padapter); +void rtl8195a_DeInitSwLeds(PADAPTER padapter); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_cmd.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_cmd.h new file mode 100644 index 0000000..eb79ded --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_cmd.h @@ -0,0 +1,130 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_PMU_CMD_H__ +#define __RTL8195A_PMU_CMD_H__ + +typedef enum _RT_MEDIA_STATUS{ + RT_MEDIA_DISCONNECT = 0, + RT_MEDIA_CONNECT = 1 +}RT_MEDIA_STATUS; + +typedef enum _H2C_CMD_ { + //1 Class1: Common + H2CID_RSVDPAGE = 0x00, + H2CID_JOININFO = 0x01, + H2CID_SCAN = 0x02, + H2CID_KEEP_ALIVE = 0x03, + H2CID_DISCONNECT_DECISION = 0x04, + H2CID_PSD_OFFLOAD = 0x05, + rsvd2 = 0x06, + rsvd3 = 0x07, + H2CID_AP_OFFLOAD = 0x08, + H2CID_BCN_RsvdPage = 0x09, + H2CID_Probersp_RsvdPage = 0x0A, + H2CID_AP_OFFLOAD_STAINFO = 0x0B, + + H2CID_FAST_CS_RSVDPAGE = 0x10, + H2CID_FAST_CHANNEL_SWITCH = 0x11, + H2CID_BB_GAIN_REPORT = 0x12, + H2CID_GPIO_CTRL = 0x13, + H2CID_HW_INFO = 0x14, + + //1 Class2: Power Save + H2CID_SETPWRMODE = 0x20, + H2CID_PSTURNINGPARM = 0x21, + H2CID_PSTURNINGPARM2 = 0x22, + H2CID_PSLPSPARM = 0x23, + H2CID_P2PPS_OFFLOAD = 0x24, + H2CID_PS_SCAN = 0x25, + H2CID_SAPPS = 0x26, + H2CID_INACTIVE_PS = 0x27, + H2CID_NOLINK_PS = 0x28, + + //1 Class3: Dynamic Mechaism + H2CID_MACID_CFG = 0x40, + H2CID_TxBF = 0x41, + H2CID_RSSI_SETTING = 0x42, + H2CID_AP_REQ_TXRPT = 0x43, + H2CID_INIT_RATE_COLLECT = 0x44, + H2CID_IQK_OFFLOAD = 0x45, + + //1 Class4: BT Coex + H2CID_B_TYPE_TDMA = 0x60, + H2CID_BT_INFO = 0x61, + H2CID_FORCE_BT_TXPWR = 0x62, + H2CID_BT_IGNORE_WLANACT = 0x63, + H2CID_DAC_SWING_VALUE = 0x64, + H2CID_ANT_SEL_REVERSE = 0x65, + H2CID_WL_OPMODE = 0x66, + H2CID_BT_MP_OPERATION = 0x67, + H2CID_BT_CONTROL = 0x68, + H2CID_BT_WIFICTRL = 0x69, + H2CID_BT_PATCH_DOWNLOAD = 0x6A, + H2CID_BT_SCO_eSCO_OPERATION = 0x6B, + H2CID_BT_Page_Scan_Interval = 0x6C, + H2CID_WL_Calibraion = 0x6D, + H2CID_GNT_BT_CTRL = 0x6E, + H2CID_BT_ONLY_TEST = 0x6F, + + //1 Class5: WOWLAN + H2CID_WoWLAN = 0x80, + H2CID_RemoteWakeCtrl = 0x81, + H2CID_AOAC_Global_info = 0x82, + H2CID_AOAC_Rsvdpage1 = 0x83, + H2CID_AOAC_Rsvdpage2 = 0x84, + H2CID_D0_Scan_offload_info = 0x85, + H2CID_D0_Scan_offload_ctrl = 0x86, + H2CID_Switch_channel = 0x87, + H2CID_AOAC_Rsvdpage3 = 0x88, + H2CID_GPIO_WF_Customize = 0x89, + H2CID_P2P_RsvdPage = 0x8A, + H2CID_P2P_Offload = 0x8B, + + //1 Class6: LTECOEX + H2CID_LTECOEX_EN = 0xA0, + H2CID_WLAN_High_Priority = 0xA1, + + //1 Class7: Patch + H2CID_TSF_RESET = 0xC0, + H2CID_BB_NHM = 0xC1, + H2CID_BCN_IGNORE_EDCCA = 0xC2, + + //1 Class8: Testing + H2CID_H2C2HLB = 0xE0 + +} H2C_CMD, *PH2C_CMD; + +typedef struct _H2CParam_JoinInfo_ { + BOOLEAN bConnected:1; + BOOLEAN bMacid_ind:1; + u8 rsvd:6; + u8 macid; + u8 macid_end; +}H2CParam_JoinInfo, *PH2CParam_JoinInfo; + +typedef struct _H2CParam_RsvdPage_ { + RSVDPAGE_LOC_8195A RsvdPageLoc; + u8 *ReservedPagePacket; + u32 TotalPacketLen; +} H2CParam_RsvdPage, *PH2CParam_RsvdPage; + +u32 H2CCmdCommon(PADAPTER padapter, u8 ElementID, u8 *pCmdBuffer); + +#endif //__RTL8195A_PMU_CMD_H__ \ No newline at end of file diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_task.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_task.h new file mode 100644 index 0000000..c44f33d --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_pmu_task.h @@ -0,0 +1,491 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_PMU_TASK_H__ +#define __RTL8195A_PMU_TASK_H__ +#ifdef CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD +//BitMAPDefine +#define RATEADAPTIVE BIT0 +#define H2CEVENT BIT1 +#define C2HEVENT BIT2 +#define RATRYDONE BIT3 +#define REMOTEWAKEEVENT BIT4 +#define APOFFLOADEVENT BIT5 +#define MAILBOXEVENT BIT6 +#define SWTIMEREVENT BIT7 + +#define BBNHMEVENT BIT8 +#define DBGPKTEVENT BIT9 +#define SIDEBANDWoWLAN BIT10 + +#if 0 +#ifdef CONFIG_POWER_SAVING +#define BCNEARLY BIT11 +#define MTIBCNIVLEAR BIT12 +#define BCNRX BIT13 +#define RXBMD1 BIT14 +#define RXBMD0 BIT15 +#define RXUMD1 BIT16 +#define RXUMD0 BIT17 +#define TXPKTIN BIT18 +#define GTIMER6TO BIT19 +#define GTIMER7TO BIT20 +#endif //#ifdef CONFIG_POWER_SAVING +#endif + +//BT mailbox +#define SETDATA BIT2 +#define SETACK BIT1 +#define GETDATA BIT0 + +/*--------------------------Define -------------------------------------------*/ +#ifdef CONFIG_POWER_SAVING +#define MACID_CLIENT 0 +#endif //#ifdef CONFIG_POWER_SAVING + +/*------------------------------Define Enum-----------------------------------*/ +#ifdef CONFIG_POWER_SAVING + +//REGDUMP_FW_ERR0 +typedef enum _FW_ERR0_STATUS_ +{ + FES0_H2C_CMDID = BIT0, + FES0_H2C_PTR = BIT1, + FES0_BB_RW = BIT2, + FES0_TXPKT_TXPAUSE = BIT3, + FES0_TSF_STABLE = BIT4, + FES0_TXSM_STABLE = BIT5, + FES0_RPWM_STABLE = BIT6, + FES0_C2H_TIMEOUT_ERR = BIT7, + +}FW_ERR0_STATUS, *PFW_ERR0_STATUS; + + +//TxPauseReasonCode +typedef enum _TRPC_ { + TPRC_ISSUENULLDATA_1 = 0x26, + TPRC_ISSUENULLDATA_2 = 0x27, + TPRC_PSS2TS3 = 0x2B, + TPRC_PSS0TS1 = 0x2C, + TPRC_PSS2TS4 = 0x2D, + TPRC_PSS2TS5 = 0x2E, + TPRC_PSS0TS6 = 0x2F, +} TRPC, *PTRPC; + + +typedef enum _PS_MODE_SETTING_SELECTION_ +{ + MODE_SETTING_ACTIVE = 0, + MODE_SETTING_LEGACY = 1, + MODE_SETTING_WMMPS = 2, + #ifdef TDMA_POWER_SAVING + MODE_SETTING_TDMA = 3 + #endif //#ifdef TDMA_POWER_SAVING +}PS_MODE_SETTING_SELECTION, *PPS_MODE_SETTING_SELECTION; + +typedef enum _RxListenBeaconMode_ +{ + RLBM_MIN = 0, + RLBM_MAX = 1, + RLBM_SELF_DEFINED = 2 + +}RxListenBeaconMode, *PRxListenBeaconMode; + +typedef enum _SMART_PS_MODE_FOR_LEGACY_ +{ + SMART_PS_MODE_LEGACY_PWR1 = 0, // TRX all use PS_POLL + SMART_PS_MODE_TX_PWR0 = 1, // TX: pwr bit = 0, RX: PS_POLL + SMART_PS_MODE_TRX_PWR0 = 2 // TX: pwr bit = 0, RX: NULL(0) +}SMART_PS_MODE_FOR_LEGACY, *PSMART_PS_MODE_FOR_LEGACY; + +#endif //#ifdef CONFIG_POWER_SAVING + +/*--------------------------Define MACRO--------------------------------------*/ + +#define HAL_WL_READ32(addr) \ + HAL_READ32(WIFI_REG_BASE, addr) +#define HAL_WL_WRITE32(addr, value) \ + HAL_WRITE32(WIFI_REG_BASE, addr, value) +#define HAL_WL_READ16(addr) \ + HAL_READ16(WIFI_REG_BASE, addr) +#define HAL_WL_WRITE16(addr, value) \ + HAL_WRITE16(WIFI_REG_BASE, addr, value) +#define HAL_WL_READ8(addr) \ + HAL_READ8(WIFI_REG_BASE, addr) +#define HAL_WL_WRITE8(addr, value) \ + HAL_WRITE8(WIFI_REG_BASE, addr, value) + +#ifdef CONFIG_POWER_SAVING +#define mtou(x) ((x)<<10) //ms->us + +#define WAIT_TSF_STABLE_BREAK_CNT 5000 +#define WAIT_TSF_STABLE_CNT 50 +#define WAIT_TSF_STABLE_ONCE_TIME 20 +#define TSFIS32K 1 +#define TSFIS40M 0 +#define GET_TSF_STATE() (((HAL_WL_READ16(0xF0) & BIT8) && (HAL_WL_READ16(0xF0) & BIT9)) ? TSFIS32K : TSFIS40M) + + +#define REG_ARFR5_8723B 0x04A4 +#define WAIT_TXSM_STABLE_CNT 1000 +#define WAIT_TXSM_STABLE_ONCE_TIME 50 + +#define MODE_TIMER 1 +#define MODE_COUNTER 0 + + +#define GTIMER6 6 +#define GTIMER7 7 + +#define TIMER_BCNTO GTIMER6 //6 +#define TIMER_DTIM GTIMER6 //6 +#define TIMER_CHECKSTATE GTIMER6 //6 +#define TIMER_PSTRX GTIMER7 //7 +#ifdef TDMA_POWER_SAVING +#define TIMER_TDMA GTIMER7 //7 +#endif //#ifdef TDMA_POWER_SAVING + +#define RTY_LMT_NULLDATA 8 +#define RTY_LMT_PSPOLL 24 +#define RTY_LMT_MORE_NULLDATA 24 + + +/* + PS_RX_INFO[7:0]: Power Save RX Information Register + initial value: 0x00 + REG III.220 (Offset 0x 0692h) PS_RX_INFO Register Definition +*/ +#define RXDATAIN0 BIT0 //PSTX +#define RXDATAIN1 BIT1 //PSRX +#define RXDATAIN2 BIT2 +#define RXMGTIN0 BIT3 +#define RXCTRLIN0 BIT4 + +//CPWM Definition +#define CLK_DOWN_RDY BIT4 + +//Power Save Tuning Parameter +//#if IS_CATEGORY_WOWLAN(CONFIG_CATEGORY_SEL) +//#define DEFAULT_BCN_TO_LIMIT 5 // 1 +//#define DEFAULT_BCN_TO_PERIOD 8 //5 +//#else +#define DEFAULT_BCN_TO_LIMIT 2 // 1 +#define DEFAULT_BCN_TO_PERIOD 4 //5 +//#endif + +#define DEFAULT_BCN_TO_TIMES_LIMIT 2 // 20140806 +#define DEFAULT_DTIM_TIMEOUT 15 // 7 // 7 ms +#define DEFAULT_PS_TIMEOUT 15 // 20 // 20 ms +#define DEFAULT_PS_DTIM_PERIOD 7 +#define DEFAULT_PS_DRV_EARLY 2 +#define DEFAULT_ENTER32K_TIMER 1000 //us +//#define PS_DRV_BCN_SHIFT_MAX DEFAULT_PS_DRV_EARLY-1 + + +#define NULL_DATA0_ALLOW 1 +#define NULL_DATA0_DENY 0 + +#define PS_RF_OFF_8723B 0 +#define PS_GO_ON BIT0 +#define PS_TX_NULL BIT1 +#define PS_RF_ON BIT2 +#define PS_REGISTER_ACTIVE BIT3 +//#define PS_ACK BIT6 +//#define PS_TOGGLE BIT7 + + +#define PS_STATE_MASK (0x0F) +//#define PS_STATE(x) (PS_STATE_MASK & (x)) +#define PS_IS_TX_NULL(x) ((x) & PS_TX_NULL ) +//#define PS_IS_ACK(x) ((x) & PS_ACK ) +#define PS_IS_CLK_ON(x) ((x) & (PS_RF_OFF_8723B |PS_ALL_ON )) +#define PS_IS_RF_OFF(x) ((x)|PS_RF_OFF_8723B) +//#define PS_IS_RF_ON(x) ((x) & (PS_RF_ON)) +//#define PS_IS_ACTIVE(x) ((x) & (PS_REGISTER_ACTIVE)) + +#define PS_STATUS_S0 (PS_REGISTER_ACTIVE | PS_RF_ON) //(1,1,0) all on = register active + rf on +#define PS_STATUS_S1 (PS_REGISTER_ACTIVE | PS_RF_ON | PS_TX_NULL) //(1,1,1) all on + tx null(1) +#define PS_STATUS_S2 (PS_RF_ON) //(0,1,0) register sleep + rf on +#define PS_STATUS_S3 (PS_RF_ON | PS_TX_NULL) //(0,1,1) register sleep + rf on + tx null(0) +#define PS_STATUS_S4 0 //(0,0,0) all OFF +#define PS_STATUS_S5 (PS_TX_NULL ) //(0,0,1) SCAN = register sleep + rf on + scan enable +#define PS_STATUS_S6 (PS_REGISTER_ACTIVE) //(1,0,0) NoA off = register active + rf off + + +/* DATA FIN Condition Flags */ +#define STA_DATA_OPEN BIT0 // indicate that FW open due to TIM = 1 condition. (PS-POLL as trigger frame) +#define BC_DATA_OPEN BIT1 // indicate that FW open due to DTIM = 1 condition. (BC & MC) +#define QOS_DATA_OPEN BIT2 // indicate that FW open due to UAPSD trigger condition. (QNULL) + +#define ALL_80211_DATA_OPEN (STA_DATA_OPEN | BC_DATA_OPEN | QOS_DATA_OPEN) +#define IS_80211_DATA_OPEN(x) ((x) & ALL_80211_DATA_OPEN) + +#define C2H_DATA_OPEN BIT3 // indicate that FW open due to C2H event +#define IS_C2H_DATA_OPEN(x) ((x) & C2H_DATA_OPEN) + +#define BCN_DATA_OPEN BIT4 +#define APP_DATA_OPEN BIT5 + +#define SET_DATA_OPEN(x, type) ((x) |= (type)) +#define CLR_DATA_OPEN(x, type) ((x) &= (~type)) +#define IS_DATA_OPEN(x, type) ((x) & (type)) + +//pwr state +#define PS_TYPE_32KPERMISSION 0 +#define PS_TYPE_CURRENT_PS_STATE 1 +#define PS_TYPE_LASTRPWM 2 + +#define CCXRPT_START_ADDR 0x0000 +#define SW_DEFINE_NULL0 0x123 +#define SW_DEFINE_NULL1 0x321 +#define SW_DEFINE_OFFSET 6 +#define RETRY_OVER BIT7 + +#define CCXRPT_OFFSET(x) (x << 3) + +#define WLAN_ENTERCRITICAL() __disable_irq() +#define WLAN_EXITCRITICAL() __enable_irq() + +#endif //#ifdef CONFIG_POWER_SAVING + +/*------------------------------Define Struct---------------------------------*/ +#ifdef CONFIG_POWER_SAVING +typedef struct _PS_PARM_ { + + u8 Enter32KHzPermission; + u8 bAllQueueUAPSD; + u8 ps_dtim_flag; // indicate dtim of current beacon. + u8 pstrx_rxcnt_period; + u8 NoConnect32k; + u8 ack_last_rpwm; + u8 TxNull0; + u8 TxNull1; + + u8 TxNull0ok; + u8 TxNull1ok; + u8 RfOffLicenseForBCNRx; //filen: After we received ps_bcn_cnt beacons, we can sleep(rf off). + u8 BCNAggEn; + u8 IsGoingTo32K; + u8 bMaxTrackingBcnMode; + u8 BcnTraceDone; + +/* + filen: to indicate whether it is smart power saving or not + 0: Legacy PS + 1: Smart PS(RX use ps_poll) + 2: Smart PS (RX use null_data(0)) +*/ + u8 smart_ps:4; //enum SMART_PS_MODE + u8 RLBM:4; // RX BCN MODE (min, max, active, ...) + u8 AwakeInterval; + u8 ps_mode; // ps type (avtive, legacy, wmmps) + u8 ClkRequestEnable; + u8 last_rpwm; + u8 current_ps_state; + u8 ps_data_open; + u8 ps_bcn_pass_time; // fw will only report one beacon information to driver after ps_bcn_pass_time ms. Unit: 100ms + + u8 ps_dtim_period; + u8 ps_dtim_cnt; + u8 ps_bcn_to; // beacon timeout (ms). + u8 bcn_to_cnt; // indicate the total number of contnuous BCN_TO we have received. + u8 bcn_to_times_cnt; //20140806 + u8 min_rate_in_rrsr; +// u8 lps_control; + u16 ps_drv_early_itv; +// u32 RFECtrl; + u32 null1_ok_cnt; + #ifdef TDMA_POWER_SAVING + u8 SlotPeriod; + u8 FirstOnPeriod; + u8 SecondOnPeriod; + u8 ThirdOnPeriod; + u8 CurrentSlot; + BOOLEAN TDMAOnPeriod; + #endif // #ifdef TDMA_POWER_SAVING + +#if 0 + u8 BcnAheadShift; + u8 BcnEarlyShift; + u8 BcnEarlyShiftMax; + u8 DefaultBcnEarly; + u8 RxBcnCount; + u8 TBTTCount; + u8 CurrentEarly; + u8 CurrentTimeOut; + u8 ReachBcnLimitCount; + u8 BcnDelayInAheadGroupOfAP; + u8 BcnDelayInRearGroupOfAP; + u8 BcnDelay[BCN_CALCULATION_MAX]; + u8 XtalDelay; + + u16 TSFOnTBTT; //unit in TU + u32 TSFOnRxBcn; + u32 TSFOnBcnEarly; +#endif + +#if 0 +#if CONFIG_BCNEARLY_ADJUST + u8 BcnEalyIndex; + u8 BcnEarlyAdjustPosition; + u8 BcnAdjustTogo; + u8 RxBcnArray[BCN_ADJUST_COUNT]; +#endif +#endif +}PS_PARM, *PPS_PARM; + +typedef struct _LEGACY_PS_PPARM_ { + u8 ps_mode:7; + u8 ClkRequestEnable:1; + u8 RLBM:4; //RX Listen BCN Mode + u8 smart_ps:4; + u8 AwakeInterval; //Unit: beacon interval, this field is only valid in PS Self-Defined mode + u8 bAllQueueUAPSD:1; // 1: all queue are uapsd 0: not all queue are uapsd + u8 bMaxTrackingBcnMode:1; + u8 rsvd:6; +//#if CONFIG_FAST_CPWM + u8 PwrState; +//#else +// u8 permission32k:1; +// u8 rsvd1:7; +//#endif + + u8 LowPwrRxBCN :1; + u8 AntAutoSwitch :1; + u8 PSAllowBTHighPri:1; + u8 ProtectBCN :1; + u8 SilencePeriod :1; + u8 FastBTConnect :1; + u8 TwoAntennaEn :1; + u8 rsvd2 :1; + u8 AdoptUserSetting:1; + u8 DrvBcnEarlyShift :3; + u8 DrvBcnTimeOut :4; + #ifdef TDMA_POWER_SAVING + u8 SlotPeriod; + u8 FirstOnPeriod; + u8 SecondOnPeriod; + u8 ThirdOnPeriod; + #endif //#ifdef TDMA_POWER_SAVING +}LEGACY_PS_PARM, *PLEGACY_PS_PARM; + +//H2C Index: 0x20 +typedef struct _H2CParam_SetPwrMode_parm_ { + LEGACY_PS_PARM PwrModeParm; +}H2CParam_PwrMode, *PH2CParam_PwrMode; + +#endif //#ifdef CONFIG_POWER_SAVING + +/*------------------------------Function declaration--------------------------*/ + +#ifdef CONFIG_POWER_SAVING +#if 0 +extern void ClockDown(PADAPTER padapter); +extern void ClockUp(PADAPTER padapter); +extern void PrintBcnFunction(void); +extern void DisDbgMsg(void); +extern void EnDbgMsg(void); +extern void UpChGain(void); +extern void StartCount(PADAPTER padapter); +extern void StopCount(PADAPTER padapter); +extern void IssueNullDataTest(PADAPTER padapter); +extern void ShowPowerState(PADAPTER padapter); +#endif +#ifdef TDMA_POWER_SAVING +extern void TDMAChangeStateTask(PADAPTER padapter); +#endif //#ifdef TDMA_POWER_SAVING +extern void EnterPS(PADAPTER padapter); +extern void GTimer6Handle(VOID *Data); +extern void GTimer7Handle(VOID *Data); +extern void InitGTimer1ms(PADAPTER padapter, u8 IRQDis, u8 TimerID, u32 Period); +extern void DeInitGTimer1ms(PADAPTER padapter, u8 TimerID); +extern void ChangeTransmiteRate(u16 offset, u8 rate); +extern void PowerBitSetting(BOOLEAN bPowerBit, u16 offset); +extern void ChkandChangePS(PPS_PARM pPSParm, BOOLEAN bPowerBit); +extern u16 IssueRsvdPagePacketSetting(u8 PageNum, BOOLEAN bHwSEQEn, u8 RtyLmt); +extern void InitRsvdPgPkt(void); +extern BOOLEAN IssueNullData(PPS_PARM pPSParm, BOOLEAN bPowerBit, u8 RtyLmt); +extern void IssuePSPoll(void); +extern BOOLEAN WaitTxStateMachineOk(void); +extern void WriteTxPause(u8 value, u8 rcode); +extern void PsCloseRF(void); +extern void PsOpenRF(void); +extern void SetPwrStateReg(PPS_PARM pPSParm, u8 PwrStateType, u8 value); +extern BOOLEAN ChkTxQueueIsEmpty(void); +extern void InitPS(PADAPTER padapter); +extern void ResetPSParm(PADAPTER padapter); +extern void Legacy_PS_Setting(PADAPTER padapter); +extern void PSModeSetting(PADAPTER padapter, u8 on); +extern void ConfigListenBeaconPeriod(PPS_PARM pPSParm, u8 RLBM, u8 AwakeInterval); +extern void PSSetMode(PADAPTER padapter, PLEGACY_PS_PARM pparm); +extern BOOLEAN PS_S2_Condition_Match(PPS_PARM pPSParm); +extern BOOLEAN PS_S4_Condition_Match(PADAPTER padapter); +extern BOOLEAN PS_32K_Condition_Match(void); +extern void PS_S2ToS3ToS0State(PADAPTER padapter, u8 nulldata0Allow); +extern void PS_S2ToS0State(PPS_PARM pPSParm); +extern void PS_S3ToS2orS0State(PPS_PARM pPSParm); +extern void PS_S0ToS1ToS2State(PADAPTER padapter); +extern void PS_S1ToS0orS2State(PPS_PARM pPSParm); +extern void PS_S2ToS4State(PADAPTER padapter); +extern void PS_S2ToS5State(PPS_PARM pPSParm); +extern void PS_S4ToS2State(PPS_PARM pPSParm, u8 ReleaseTxPause); +extern void PS_S5ToS2State(PPS_PARM pPSParm); +extern void PS_S0ToS6State(PADAPTER padapter); +extern void PS_S6ToS0State(PPS_PARM pPSParm); +extern void CheckTSFIsStable(u8 ReqState); +extern void WaitHWStateReady(void); +extern void SysClkDown(PPS_PARM pPSParm); +extern void SysClkUp(PPS_PARM pPSParm); +extern void SleepTo32K(PPS_PARM pPSParm); +extern void Change_PS_State(PADAPTER padapter, u8 request_ps_state, u8 nulldata0Allow); +extern void ChangePSStateByRPWM(PADAPTER padapter); +extern void SetSmartPSTimer(PADAPTER padapter); +extern void SmartPS2InitTimerAndToGetRxPkt(PADAPTER padapter); +extern void PS_OnBeacon(PADAPTER padapter); +extern void PSBcnEarlyProcess(PADAPTER padapter); +extern void PSMtiBcnEarlyProcess(PADAPTER padapter); +extern void PSRxBcnProcess(PADAPTER padapter); +extern void TxPktInPSOn(PADAPTER padapter); +extern void PsBcnToProcess(PADAPTER padapter); +extern BOOL RPWMProcess(PADAPTER padapter, BOOLEAN benter32k); +extern void ISR_MtiBcnEarly(PADAPTER padapter); +extern void ISR_BcnEarly(PADAPTER padapter); +extern void ISR_RxBcn(PADAPTER padapter); +extern void ISR_RxBCMD1(PADAPTER padapter); +extern void ISR_RxBCMD0(PADAPTER padapter); +extern void ISR_RxUCMD1(PADAPTER padapter); +extern void ISR_RxUCMD0(PADAPTER padapter); +extern void ISR_TxPktIn(PADAPTER padapter); +extern void ISR_TXCCX(PADAPTER padapter); +extern void H2CHDL_SetPwrMode(PADAPTER padapter, u8* pCmdBuffer); +extern void CheckInReqStateTask(PADAPTER padapter); +extern void HalSetRPWM(PADAPTER padapter, BOOLEAN benter32k); +extern u32 HalGetNullTxRpt(PADAPTER padapter); +//extern thread_return HalEnter32KThreadRtl8195a(thread_context context); +#endif //#ifdef CONFIG_POWER_SAVING + +extern void ISR_TBTT(PADAPTER padapter); +extern void H2CHDL_BcnIgnoreEDCCA(PADAPTER padapter, u8* pCmdBuffer); + +void PMUTask(PADAPTER padapter); +void PMUInitial(PADAPTER padapter); + +#endif //CONFIG_LITTLE_WIFI_MCU_FUNCTION_THREAD +#endif //__RTL8195A_PMU_TASK_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_recv.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_recv.h new file mode 100644 index 0000000..7fad730 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_recv.h @@ -0,0 +1,232 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_RECV_H__ +#define __RTL8195A_RECV_H__ + +#ifdef CONFIG_WLAN_HAL_TEST +#define MAX_RECVBUF_SZ 1200//(RX_DMA_SIZE_8195A - RX_DMA_RESERVED_SIZE_8195A) +#else +#if (SKB_PRE_ALLOCATE_RX==1) +#define MAX_RECVBUF_SZ MAX_SKB_BUF_SIZE //1650 //(RX_DMA_SIZE_8195A - RX_DMA_RESERVED_SIZE_8195A) +#else +#define MAX_RECVBUF_SZ (HAL_INTERFACE_OVERHEAD_SKB_DATA+RX_DRIVER_INFO+\ + RXDESC_SIZE +\ + (MAX_RX_PKT_LIMIT * 512) +\ + SKB_RESERVED_FOR_SAFETY) // 0+32+24+512*4+0 = 2104 +#endif +#endif + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8812(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8812(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8812(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8812(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + +typedef struct rxreport_8723b +{ + //DWORD 0 + u32 pktlen:14; + u32 crc32:1; + u32 icverr:1; + u32 drvinfosize:4; + u32 security:3; + u32 qos:1; + u32 shift:2; + u32 physt:1; + u32 swdec:1; + u32 rsvd0028:2; + u32 eor:1; + u32 rsvd0031:1; + + //DWORD 1 + u32 macid:7; + u32 rsvd0407:1; + u32 tid:4; + u32 macid_vld:1; + u32 amsdu:1; + u32 rxid_match:1; + u32 paggr:1; + u32 a1fit:4; + u32 chkerr:1; //20 + u32 rx_ipv:1; + u32 rx_is_tcp_udp:1; + u32 chk_vld:1; //23 + u32 pam:1; + u32 pwr:1; + u32 md:1; + u32 mf:1; + u32 type:2; + u32 mc:1; + u32 bc:1; + + //DWORD 2 + u32 seq:12; + u32 frag:4; + u32 rx_is_qos:1; + u32 rsvd0817:1; + u32 wlanhd_iv_len:6; + u32 hwrsvd0824:4; + u32 c2h_ind:1; + u32 rsvd0829:2; + u32 fcs_ok:1; + + //DWORD 3 + u32 rx_rate:7; + u32 rsvd1207:3; + u32 htc:1; + u32 esop:1; + u32 bssid_fit:2; + u32 rsvd1214:2; + u32 dma_agg_num:8; + u32 rsvd1224:5; + u32 patternmatch:1; + u32 unicastwake:1; + u32 magicwake:1; + + //DWORD 4 + u32 splcp:1; //Ofdm sgi or cck_splcp + u32 ldpc:1; + u32 stbc:1; + u32 not_sounding:1; + u32 bw:2; + u32 rsvd1606:26; + + //DWORD 5 + u32 tsfl; +} RXREPORT, *PRXREPORT; + +typedef struct phystatus_8723b +{ + u32 rxgain_a:7; + u32 trsw_a:1; + u32 rxgain_b:7; + u32 trsw_b:1; + u32 chcorr_l:16; + + u32 sigqualcck:8; + u32 cfo_a:8; + u32 cfo_b:8; + u32 chcorr_h:8; + + u32 noisepwrdb_h:8; + u32 cfo_tail_a:8; + u32 cfo_tail_b:8; + u32 rsvd0824:8; + + u32 rsvd1200:8; + u32 rxevm_a:8; + u32 rxevm_b:8; + u32 rxsnr_a:8; + + u32 rxsnr_b:8; + u32 noisepwrdb_l:8; + u32 rsvd1616:8; + u32 postsnr_a:8; + + u32 postsnr_b:8; + u32 csi_a:8; + u32 csi_b:8; + u32 targetcsi_a:8; + + u32 targetcsi_b:8; + u32 sigevm:8; + u32 maxexpwr:8; + u32 exintflag:1; + u32 sgien:1; + u32 rxsc:2; + u32 idlelong:1; + u32 anttrainen:1; + u32 antselb:1; + u32 antsel:1; +} PHYSTATUS, *PPHYSTATUS; + + +s32 rtl8195a_init_recv_priv(PADAPTER padapter); +void rtl8195a_free_recv_priv(PADAPTER padapter); +void rtl8195a_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc); +void rtl8195a_query_rx_phy_status(union recv_frame *precvframe, u8 *pphy_status); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_rf.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_rf.h new file mode 100644 index 0000000..f02cdea --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_rf.h @@ -0,0 +1,32 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_RF_H__ +#define __RTL8195A_RF_H__ + + +int PHY_RF6052_Config8195A( IN PADAPTER Adapter ); + +VOID +PHY_RF6052SetBandwidth8195A( + IN PADAPTER Adapter, + IN CHANNEL_WIDTH Bandwidth); + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_spec.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_spec.h new file mode 100644 index 0000000..e6136e7 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_spec.h @@ -0,0 +1,345 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ +#ifndef __RTL8195A_SPEC_H__ +#define __RTL8195A_SPEC_H__ + +#include + + +#define HAL_NAV_UPPER_UNIT_8723B 128 // micro-second + +//----------------------------------------------------- +// +// 0x0000h ~ 0x00FFh System Configuration +// +//----------------------------------------------------- +#define REG_BT_WIFI_ANTENNA_SWITCH_8723B 0x0038 +#define REG_PAD_CTRL1_8723B 0x0064 +#define REG_AFE_CTRL_4_8723B 0x0078 +#define REG_HMEBOX_DBG_0_8723B 0x0088 +#define REG_HMEBOX_DBG_1_8723B 0x008A +#define REG_HMEBOX_DBG_2_8723B 0x008C +#define REG_HMEBOX_DBG_3_8723B 0x008E + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- +#define REG_C2HEVT_CMD_ID_8723B 0x01A0 +#define REG_C2HEVT_CMD_LEN_8723B 0x01AE +#ifdef CONFIG_WOWLAN +#define REG_WOWLAN_WAKE_REASON 0x01C7 +#endif + +#define REG_HMEBOX_EXT0_8723B 0x01F0 +#define REG_HMEBOX_EXT1_8723B 0x01F4 +#define REG_HMEBOX_EXT2_8723B 0x01F8 +#define REG_HMEBOX_EXT3_8723B 0x01FC + +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#define REG_RXDMA_MODE_CTRL_8723B 0x0290 + +//----------------------------------------------------- +// +// 0x0300h ~ 0x03FFh PCIe +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- +#define REG_TXPKTBUF_BCNQ_BDNY_8195A 0x0424 +#define REG_TXPKTBUF_MGQ_BDNY_8195A 0x0425 +#define REG_TXPKTBUF_WMAC_LBK_BF_HD_8195A 0x045D +#ifdef CONFIG_WOWLAN +#define REG_TXPKTBUF_IV_LOW 0x0484 +#define REG_TXPKTBUF_IV_HIGH 0x0488 +#endif + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- +#define REG_SECONDARY_CCA_CTRL_8723B 0x0577 + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + + +//============================================================ +// SDIO Bus Specification +//============================================================ + +//----------------------------------------------------- +// SDIO CMD Address Mapping +//----------------------------------------------------- + +//----------------------------------------------------- +// I/O bus domain (Host) +//----------------------------------------------------- + +//----------------------------------------------------- +// SDIO register +//----------------------------------------------------- +#define SDIO_REG_HCPWM1_8723B 0x025 // HCI Current Power Mode 1 + + +//============================================================================ +// 8723 Regsiter Bit and Content definition +//============================================================================ + +//2 HSISR +// interrupt mask which needs to clear +#define MASK_HSISR_CLEAR (HSISR_GPIO12_0_INT |\ + HSISR_SPS_OCP_INT |\ + HSISR_RON_INT |\ + HSISR_PDNINT |\ + HSISR_GPIO9_INT) + +//----------------------------------------------------- +// +// 0x0100h ~ 0x01FFh MACTOP General Configuration +// +//----------------------------------------------------- + +#define RXDMA_AGG_MODE_EN BIT(1) +//----------------------------------------------------- +// +// 0x0200h ~ 0x027Fh TXDMA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0280h ~ 0x02FFh RXDMA Configuration +// +//----------------------------------------------------- +#ifdef CONFIG_WOWLAN +#define RXPKT_RELEASE_POLL BIT(16) +#define RXDMA_IDLE BIT(17) +#define RW_RELEASE_EN BIT(18) +#endif + +//----------------------------------------------------- +// +// 0x0400h ~ 0x047Fh Protocol Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0500h ~ 0x05FFh EDCA Configuration +// +//----------------------------------------------------- + +//----------------------------------------------------- +// +// 0x0600h ~ 0x07FFh WMAC Configuration +// +//----------------------------------------------------- + +#endif + +//==================================================== +// EEPROM/Efuse PG Offset for 8195A +//==================================================== +// 0x10 ~ 0x63 = TX power area. +#define EEPROM_TX_PWR_INX_8195A 0x20 +#define EEPROM_ChannelPlan_8195A 0xC8 +#define EEPROM_XTAL_8195A 0xC9 +#define EEPROM_THERMAL_METER_8195A 0xCA + +#define EEPROM_IQK_LCK_8195A 0xCB +#define EEPROM_2G_5G_PA_TYPE_8195A 0xCC +#define EEPROM_2G_LNA_TYPE_GAIN_SEL_8195A 0xCD +#define EEPROM_5G_LNA_TYPE_GAIN_SEL_8195A 0xCE + +#define EEPROM_RF_BOARD_OPTION_8195A 0x131 + +#define EEPROM_FEATURE_OPTION_8195A 0x132 +#define EEPROM_RF_BT_SETTING_8195A 0x133 + +#define EEPROM_VERSION_8195A 0x134 +#define EEPROM_CustomID_8195A 0x135 + +#define EEPROM_TX_BBSWING_2G_8195A 0x136 +#define EEPROM_TX_PWR_CAL_RATE_8195A 0x138 +#define EEPROM_RF_ANTENNA_OPT_8195A 0x139 +#define EEPROM_RFE_OPTION_8195A 0x13A + +//RTL8723BU +#define EEPROM_MAC_ADDR_8723BU 0x107 +#define EEPROM_VID_8723BU 0x100 +#define EEPROM_PID_8723BU 0x102 +#define EEPROM_PA_TYPE_8723BU 0xBC +#define EEPROM_LNA_TYPE_2G_8723BU 0xBD + +//RTL8723BS +#define EEPROM_MAC_ADDR_8723BS 0x11A +#define EEPROM_MAC_ADDR_8195A 0x11A + +#define EEPROM_Voltage_ADDR_8723B 0x8 + +#define EEPROM_TX_KFREE_8195A 0xEE + +#define EEPROM_PACKAGE_TYPE_8195A 0xF8 + +//==================================================== +// EEPROM/Efuse Value Type +//==================================================== +#define EETYPE_TX_PWR 0x0 +//==================================================== +// EEPROM/Efuse Default Value +//==================================================== +#define EEPROM_CID_DEFAULT 0x0 +#define EEPROM_CID_DEFAULT_EXT 0xFF // Reserved for Realtek +#define EEPROM_CID_TOSHIBA 0x4 +#define EEPROM_CID_CCX 0x10 +#define EEPROM_CID_QMI 0x0D +#define EEPROM_CID_WHQL 0xFE + +#define EEPROM_CHANNEL_PLAN_FCC 0x0 +#define EEPROM_CHANNEL_PLAN_IC 0x1 +#define EEPROM_CHANNEL_PLAN_ETSI 0x2 +#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 +#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 +#define EEPROM_CHANNEL_PLAN_MKK 0x5 +#define EEPROM_CHANNEL_PLAN_MKK1 0x6 +#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 +#define EEPROM_CHANNEL_PLAN_TELEC 0x8 +#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA +#define EEPROM_CHANNEL_PLAN_NCC_TAIWAN 0xB +#define EEPROM_CHANNEL_PLAN_CHIAN 0XC +#define EEPROM_CHANNEL_PLAN_SINGAPORE_INDIA_MEXICO 0XD +#define EEPROM_CHANNEL_PLAN_KOREA 0xE +#define EEPROM_CHANNEL_PLAN_TURKEY 0xF +#define EEPROM_CHANNEL_PLAN_JAPAN 0x10 +#define EEPROM_CHANNEL_PLAN_FCC_NO_DFS 0x11 +#define EEPROM_CHANNEL_PLAN_JAPAN_NO_DFS 0x12 +#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_5G 0x13 +#define EEPROM_CHANNEL_PLAN_TAIWAN_NO_DFS 0x14 + +#define EEPROM_USB_OPTIONAL1 0xE +#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 + +#define RTL_EEPROM_ID 0x8129 +#define EEPROM_Default_TSSI 0x0 +#define EEPROM_Default_BoardType 0x02 +#define EEPROM_Default_ThermalMeter 0x12 +#define EEPROM_Default_ThermalMeter_92SU 0x7 +#define EEPROM_Default_ThermalMeter_88E 0x18 +#define EEPROM_Default_ThermalMeter_8812 0x18 +#define EEPROM_Default_ThermalMeter_8192E 0x1A +#define EEPROM_Default_ThermalMeter_8723B 0x18 +#define EEPROM_Default_ThermalMeter_8195A 0x1A + + +#define EEPROM_Default_CrystalCap 0x0 +#define EEPROM_Default_CrystalCap_8723B 0x20 +#define EEPROM_Default_CrystalCap_8195A 0x20 +#define EEPROM_Default_CrystalFreq 0x0 +#define EEPROM_Default_TxPowerLevel_92C 0x22 +#define EEPROM_Default_TxPowerLevel_2G 0x2C +#define EEPROM_Default_TxPowerLevel_5G 0x22 +#define EEPROM_Default_TxPowerLevel 0x22 +#define EEPROM_Default_HT40_2SDiff 0x0 +#define EEPROM_Default_HT20_Diff 2 +#define EEPROM_Default_LegacyHTTxPowerDiff 0x3 +#define EEPROM_Default_LegacyHTTxPowerDiff_92C 0x3 +#define EEPROM_Default_LegacyHTTxPowerDiff_92D 0x4 +#define EEPROM_Default_HT40_PwrMaxOffset 0 +#define EEPROM_Default_HT20_PwrMaxOffset 0 + +#define EEPROM_Default_PID 0x1234 +#define EEPROM_Default_VID 0x5678 +#define EEPROM_Default_CustomerID 0xAB +#define EEPROM_Default_CustomerID_8188E 0x00 +#define EEPROM_Default_SubCustomerID 0xCD +#define EEPROM_Default_Version 0 + +#define EEPROM_Default_externalPA_C9 0x00 +#define EEPROM_Default_externalPA_CC 0xFF +#define EEPROM_Default_internalPA_SP3T_C9 0xAA +#define EEPROM_Default_internalPA_SP3T_CC 0xAF +#define EEPROM_Default_internalPA_SPDT_C9 0xAA +#ifdef CONFIG_PCI_HCI +#define EEPROM_Default_internalPA_SPDT_CC 0xA0 +#else +#define EEPROM_Default_internalPA_SPDT_CC 0xFA +#endif +#define EEPROM_Default_PAType 0 +#define EEPROM_Default_LNAType 0 + +//New EFUSE deafult value +#define EEPROM_DEFAULT_24G_CCK_INDEX 0x20 +#define EEPROM_DEFAULT_24G_40M_INDEX 0x20 +#define EEPROM_DEFAULT_24G_HT20_DIFF 0X00 +#define EEPROM_DEFAULT_24G_OFDM_DIFF 0X02 + +#define EEPROM_DEFAULT_5G_INDEX 0X2A +#define EEPROM_DEFAULT_5G_HT20_DIFF 0X00 +#define EEPROM_DEFAULT_5G_OFDM_DIFF 0X04 + +#define EEPROM_DEFAULT_DIFF 0XFE +#define EEPROM_DEFAULT_CHANNEL_PLAN 0x7F +#define EEPROM_DEFAULT_BOARD_OPTION 0x01 // Enable power by rate and power limit +#define EEPROM_DEFAULT_RFE_OPTION 0x04 +#define EEPROM_DEFAULT_FEATURE_OPTION 0x00 +#define EEPROM_DEFAULT_BT_OPTION 0x10 +#define EEPROM_DEFAULT_TX_CALIBRATE_RATE 0x00 + + + + + + +#ifdef CONFIG_USB_HCI +//should be renamed and moved to another file +typedef enum _BOARD_TYPE_8192CUSB{ + BOARD_USB_DONGLE = 0, // USB dongle + BOARD_USB_High_PA = 1, // USB dongle with high power PA + BOARD_MINICARD = 2, // Minicard + BOARD_USB_SOLO = 3, // USB solo-Slim module + BOARD_USB_COMBO = 4, // USB Combo-Slim module +} BOARD_TYPE_8723BUSB, *PBOARD_TYPE_8723BUSB; + +#endif + +#if defined (CONFIG_PCI_HCI) || defined(CONFIG_LX_HCI) +#define RT_BCN_INT_MASKS (IMR_BcnInt | IMR_TBDOK | IMR_TBDER) +#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_sreset.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_sreset.h new file mode 100644 index 0000000..e990627 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_sreset.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _RTL8195A_SRESET_H_ +#define _RTL8195A_SRESET_H_ + +#include + +#ifdef DBG_CONFIG_ERROR_DETECT +extern void rtl8723b_sreset_xmit_status_check(_adapter *padapter); +extern void rtl8723b_sreset_linked_status_check(_adapter *padapter); +#endif +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_xmit.h b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_xmit.h new file mode 100644 index 0000000..c5925fb --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hal/rtl8195a/rtl8195a_xmit.h @@ -0,0 +1,473 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL8195A_XMIT_H__ +#define __RTL8195A_XMIT_H__ + +// +// Queue Select Value in TxDesc +// +#define QSLT_BK 0x2//0x01 +#define QSLT_BE 0x0 +#define QSLT_VI 0x5//0x4 +#define QSLT_VO 0x7//0x6 +#define QSLT_BEACON 0x10 +#define QSLT_HIGH 0x11 +#define QSLT_MGNT 0x12 +#define QSLT_CMD 0x13 + +#define MAX_TID (15) + +//OFFSET 0 +#define OFFSET_SZ 0 +#define OFFSET_SHT 16 +#define BMC BIT(24) +#define LSG BIT(26) +#define FSG BIT(27) +#define OWN BIT(31) + + +//OFFSET 4 +#define PKT_OFFSET_SZ 0 +#define BK BIT(6) +#define QSEL_SHT 8 +#define Rate_ID_SHT 16 +#define NAVUSEHDR BIT(20) +#define PKT_OFFSET_SHT 26 +#define HWPC BIT(31) + +//OFFSET 8 +#define AGG_EN BIT(29) + +//OFFSET 12 +#define SEQ_SHT 16 + +//OFFSET 16 +#define QoS BIT(6) +#define HW_SEQ_EN BIT(7) +#define USERATE BIT(8) +#define DISDATAFB BIT(10) +#define DATA_SHORT BIT(24) +#define DATA_BW BIT(25) + +//OFFSET 20 +#define SGI BIT(6) + +// +//defined for TX DESC Operation +// +typedef struct txdesc_8723b +{ + // Offset 0 + u32 pktlen:16; + u32 offset:8; + u32 bmc:1; + u32 htc:1; + u32 rsvd0026:1; + u32 rsvd0027:1; + u32 linip:1; + u32 noacm:1; + u32 gf:1; + u32 rsvd0031:1; + + // Offset 4 + u32 macid:7; + u32 rsvd0407:1; + u32 qsel:5; + u32 rdg_nav_ext:1; + u32 lsig_txop_en:1; + u32 pifs:1; + u32 rate_id:5; + u32 en_desc_id:1; + u32 sectype:2; + u32 pkt_offset:5; // unit: 8 bytes + u32 moredata:1; + u32 txop_ps_cap:1; + u32 txop_ps_mode:1; + + // Offset 8 + u32 p_aid:9; + u32 rsvd0809:1; + u32 cca_rts:2; + u32 agg_en:1; + u32 rdg_en:1; + u32 null_0:1; + u32 null_1:1; + u32 bk:1; + u32 morefrag:1; + u32 raw:1; + u32 spe_rpt:1; + u32 ampdu_density:3; + u32 bt_null:1; + u32 g_id:6; + u32 rsvd0830:2; + + // Offset 12 + u32 wheader_len:4; + u32 chk_en:1; + u32 early_rate:1; + u32 hw_ssn_sel:2; + u32 userate:1; + u32 disrtsfb:1; + u32 disdatafb:1; + u32 cts2self:1; + u32 rtsen:1; + u32 hw_rts_en:1; + u32 port_id:1; + u32 navusehdr:1; + u32 use_max_len:1; + u32 max_agg_num:5; + u32 ndpa:2; + u32 ampdu_max_time:8; + + // Offset 16 + u32 datarate:7; + u32 try_rate:1; + u32 data_ratefb_lmt:5; + u32 rts_ratefb_lmt:4; + u32 rty_lmt_en:1; + u32 data_rt_lmt:6; + u32 rtsrate:5; + u32 pcts_en:1; + u32 pcts_mask_idx:2; + + // Offset 20 + u32 data_sc:4; + u32 data_short:1; + u32 data_bw:2; + u32 data_ldpc:1; + u32 data_stbc:2; + u32 vcs_stbc:2; + u32 rts_short:1; + u32 rts_sc:4; + u32 rsvd2016:7; + u32 tx_ant:4; + u32 txpwr_offset:3; + u32 rsvd2031:1; + + // Offset 24 + u32 sw_define:12; + u32 mbssid:4; + u32 antsel_A:3; + u32 antsel_B:3; + u32 antsel_C:3; + u32 antsel_D:3; + u32 rsvd2428:4; + + // Offset 28 + u32 checksum:16; + u32 rsvd2816:8; + u32 usb_txagg_num:8; + + // Offset 32 + u32 rts_rc:6; + u32 bar_rty_th:2; + u32 data_rc:6; + u32 rsvd3214:1; + u32 en_hwseq:1; + u32 nextneadpage:8; + u32 tailpage:8; + + // Offset 36 + u32 padding_len:11; + u32 txbf_path:1; + u32 seq:12; + u32 final_data_rate:8; +}TXDESC_8723B, *PTXDESC_8723B; + +#ifndef __INC_HAL8723BDESC_H +#define __INC_HAL8723BDESC_H + +#define RX_STATUS_DESC_SIZE_8723B 24 +#define RX_DRV_INFO_SIZE_UNIT_8723B 8 + + +//DWORD 0 +#define SET_RX_STATUS_DESC_PKT_LEN_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 0, 14, __Value) +#define SET_RX_STATUS_DESC_EOR_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 30, 1, __Value) +#define SET_RX_STATUS_DESC_OWN_8723B(__pRxStatusDesc, __Value) SET_BITS_TO_LE_4BYTE( __pRxStatusDesc, 31, 1, __Value) + +#define GET_RX_STATUS_DESC_PKT_LEN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 0, 14) +#define GET_RX_STATUS_DESC_CRC32_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 14, 1) +#define GET_RX_STATUS_DESC_ICV_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 15, 1) +#define GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 16, 4) +#define GET_RX_STATUS_DESC_SECURITY_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 20, 3) +#define GET_RX_STATUS_DESC_QOS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 23, 1) +#define GET_RX_STATUS_DESC_SHIFT_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 24, 2) +#define GET_RX_STATUS_DESC_PHY_STATUS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 26, 1) +#define GET_RX_STATUS_DESC_SWDEC_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 27, 1) +#define GET_RX_STATUS_DESC_LAST_SEG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 28, 1) +#define GET_RX_STATUS_DESC_FIRST_SEG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 29, 1) +#define GET_RX_STATUS_DESC_EOR_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 30, 1) +#define GET_RX_STATUS_DESC_OWN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc, 31, 1) + +//DWORD 1 +#define GET_RX_STATUS_DESC_MACID_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 0, 7) +#define GET_RX_STATUS_DESC_TID_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 8, 4) +#define GET_RX_STATUS_DESC_AMSDU_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 13, 1) +#define GET_RX_STATUS_DESC_RXID_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 14, 1) +#define GET_RX_STATUS_DESC_PAGGR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 15, 1) +#define GET_RX_STATUS_DESC_A1_FIT_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 16, 4) +#define GET_RX_STATUS_DESC_CHKERR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 20, 1) +#define GET_RX_STATUS_DESC_IPVER_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 21, 1) +#define GET_RX_STATUS_DESC_IS_TCPUDP__8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 22, 1) +#define GET_RX_STATUS_DESC_CHK_VLD_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+4, 23, 1) +#define GET_RX_STATUS_DESC_PAM_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 24, 1) +#define GET_RX_STATUS_DESC_PWR_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 25, 1) +#define GET_RX_STATUS_DESC_MORE_DATA_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 26, 1) +#define GET_RX_STATUS_DESC_MORE_FRAG_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 27, 1) +#define GET_RX_STATUS_DESC_TYPE_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 28, 2) +#define GET_RX_STATUS_DESC_MC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 30, 1) +#define GET_RX_STATUS_DESC_BC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+4, 31, 1) + +//DWORD 2 +#define GET_RX_STATUS_DESC_SEQ_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 0, 12) +#define GET_RX_STATUS_DESC_FRAG_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 12, 4) +#define GET_RX_STATUS_DESC_RX_IS_QOS_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 16, 1) +#define GET_RX_STATUS_DESC_WLANHD_IV_LEN_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 18, 6) +#define GET_RX_STATUS_DESC_RPT_SEL_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+8, 28, 1) + +//DWORD 3 +#define GET_RX_STATUS_DESC_RX_RATE_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 0, 7) +#define GET_RX_STATUS_DESC_HTC_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 10, 1) +#define GET_RX_STATUS_DESC_EOSP_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 11, 1) +#define GET_RX_STATUS_DESC_BSSID_FIT_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 12, 2) +#ifdef CONFIG_USB_RX_AGGREGATION +#define GET_RX_STATUS_DESC_USB_AGG_PKTNUM_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+12, 16, 8) +#endif +#define GET_RX_STATUS_DESC_PATTERN_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 29, 1) +#define GET_RX_STATUS_DESC_UNICAST_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 30, 1) +#define GET_RX_STATUS_DESC_MAGIC_MATCH_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+12, 31, 1) + +//DWORD 6 +#define GET_RX_STATUS_DESC_SPLCP_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 0, 1) +#define GET_RX_STATUS_DESC_LDPC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 1, 1) +#define GET_RX_STATUS_DESC_STBC_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 2, 1) +#define GET_RX_STATUS_DESC_BW_8723B(__pRxDesc) LE_BITS_TO_4BYTE( __pRxDesc+16, 4, 2) + +//DWORD 5 +#define GET_RX_STATUS_DESC_TSFL_8723B(__pRxStatusDesc) LE_BITS_TO_4BYTE( __pRxStatusDesc+20, 0, 32) + +#define GET_RX_STATUS_DESC_BUFF_ADDR_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+24, 0, 32) +#define GET_RX_STATUS_DESC_BUFF_ADDR64_8723B(__pRxDesc) LE_BITS_TO_4BYTE(__pRxDesc+28, 0, 32) + +#define SET_RX_STATUS_DESC_BUFF_ADDR_8723B(__pRxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pRxDesc+24, 0, 32, __Value) + + +// Dword 0 +#define GET_TX_DESC_OWN_8723B(__pTxDesc) LE_BITS_TO_4BYTE(__pTxDesc, 31, 1) + +#define SET_TX_DESC_PKT_SIZE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 0, 16, __Value) +#define SET_TX_DESC_OFFSET_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 16, 8, __Value) +#define SET_TX_DESC_BMC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 24, 1, __Value) +#define SET_TX_DESC_HTC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 25, 1, __Value) +#define SET_TX_DESC_LAST_SEG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 26, 1, __Value) +#define SET_TX_DESC_FIRST_SEG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 27, 1, __Value) +#define SET_TX_DESC_LINIP_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 28, 1, __Value) +#define SET_TX_DESC_NO_ACM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 29, 1, __Value) +#define SET_TX_DESC_GF_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 30, 1, __Value) +#define SET_TX_DESC_OWN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc, 31, 1, __Value) + +// Dword 1 +#define SET_TX_DESC_MACID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 0, 7, __Value) +#define SET_TX_DESC_QUEUE_SEL_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 8, 5, __Value) +#define SET_TX_DESC_RDG_NAV_EXT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 13, 1, __Value) +#define SET_TX_DESC_LSIG_TXOP_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 14, 1, __Value) +#define SET_TX_DESC_PIFS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 15, 1, __Value) +#define SET_TX_DESC_RATE_ID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 16, 5, __Value) +#define SET_TX_DESC_EN_DESC_ID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 21, 1, __Value) +#define SET_TX_DESC_SEC_TYPE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 22, 2, __Value) +#define SET_TX_DESC_PKT_OFFSET_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+4, 24, 5, __Value) + + +// Dword 2 +#define SET_TX_DESC_PAID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 0, 9, __Value) +#define SET_TX_DESC_CCA_RTS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 10, 2, __Value) +#define SET_TX_DESC_AGG_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 12, 1, __Value) +#define SET_TX_DESC_RDG_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 13, 1, __Value) +#define SET_TX_DESC_AGG_BREAK_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 16, 1, __Value) +#define SET_TX_DESC_MORE_FRAG_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 17, 1, __Value) +#define SET_TX_DESC_RAW_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 18, 1, __Value) +#define SET_TX_DESC_SPE_RPT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 19, 1, __Value) +#define SET_TX_DESC_AMPDU_DENSITY_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 20, 3, __Value) +#define SET_TX_DESC_BT_INT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 23, 1, __Value) +#define SET_TX_DESC_GID_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+8, 24, 6, __Value) + + +// Dword 3 +#define SET_TX_DESC_WHEADER_LEN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 0, 4, __Value) +#define SET_TX_DESC_CHK_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 4, 1, __Value) +#define SET_TX_DESC_EARLY_MODE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 5, 1, __Value) +#define SET_TX_DESC_HWSEQ_SEL_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 6, 2, __Value) +#define SET_TX_DESC_USE_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 8, 1, __Value) +#define SET_TX_DESC_DISABLE_RTS_FB_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 9, 1, __Value) +#define SET_TX_DESC_DISABLE_FB_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 10, 1, __Value) +#define SET_TX_DESC_CTS2SELF_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 11, 1, __Value) +#define SET_TX_DESC_RTS_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 12, 1, __Value) +#define SET_TX_DESC_HW_RTS_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 13, 1, __Value) +#define SET_TX_DESC_NAV_USE_HDR_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 15, 1, __Value) +#define SET_TX_DESC_USE_MAX_LEN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 16, 1, __Value) +#define SET_TX_DESC_MAX_AGG_NUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 17, 5, __Value) +#define SET_TX_DESC_NDPA_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 22, 2, __Value) +#define SET_TX_DESC_AMPDU_MAX_TIME_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+12, 24, 8, __Value) + +// Dword 4 +#define SET_TX_DESC_TX_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 0, 7, __Value) +#define SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 8, 5, __Value) +#define SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 13, 4, __Value) +#define SET_TX_DESC_RETRY_LIMIT_ENABLE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 17, 1, __Value) +#define SET_TX_DESC_DATA_RETRY_LIMIT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 18, 6, __Value) +#define SET_TX_DESC_RTS_RATE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 24, 5, __Value) + + +// Dword 5 +#define SET_TX_DESC_DATA_SC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 0, 4, __Value) +#define SET_TX_DESC_DATA_SHORT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 4, 1, __Value) +#define SET_TX_DESC_DATA_BW_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 5, 2, __Value) +#define SET_TX_DESC_DATA_LDPC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 7, 1, __Value) +#define SET_TX_DESC_DATA_STBC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 8, 2, __Value) +#define SET_TX_DESC_CTROL_STBC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 10, 2, __Value) +#define SET_TX_DESC_RTS_SHORT_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 12, 1, __Value) +#define SET_TX_DESC_RTS_SC_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+20, 13, 4, __Value) + + +// Dword 6 +#define SET_TX_DESC_SW_DEFINE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 0, 12, __Value) +#define SET_TX_DESC_ANTSEL_A_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 16, 3, __Value) +#define SET_TX_DESC_ANTSEL_B_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 19, 3, __Value) +#define SET_TX_DESC_ANTSEL_C_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 22, 3, __Value) +#define SET_TX_DESC_ANTSEL_D_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+24, 25, 3, __Value) + +// Dword 7 +#if(DEV_BUS_TYPE == RT_PCI_INTERFACE) +#define SET_TX_DESC_TX_BUFFER_SIZE_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#else +#define SET_TX_DESC_TX_DESC_CHECKSUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 0, 16, __Value) +#endif +#define SET_TX_DESC_USB_TXAGG_NUM_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 24, 8, __Value) +#if(DEV_BUS_TYPE == RT_SDIO_INTERFACE) +#define SET_TX_DESC_SDIO_TXSEQ_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+28, 16, 8, __Value) +#endif + +// Dword 8 +#define SET_TX_DESC_HWSEQ_EN_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+32, 15, 1, __Value) + +// Dword 9 +#define SET_TX_DESC_SEQ_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+36, 12, 12, __Value) + +// Dword 10 +#define SET_TX_DESC_TX_BUFFER_ADDRESS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+40, 0, 32, __Value) + + +// Dword 11 +#define SET_TX_DESC_NEXT_DESC_ADDRESS_8723B(__pTxDesc, __Value) SET_BITS_TO_LE_4BYTE(__pTxDesc+48, 0, 32, __Value) + + +#define SET_EARLYMODE_PKTNUM_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 0, 4, __Value) +#define SET_EARLYMODE_LEN0_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 4, 15, __Value) +#define SET_EARLYMODE_LEN1_1_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr, 19, 13, __Value) +#define SET_EARLYMODE_LEN1_2_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 0, 2, __Value) +#define SET_EARLYMODE_LEN2_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 2, 15, __Value) +#define SET_EARLYMODE_LEN3_8723B(__pAddr, __Value) SET_BITS_TO_LE_4BYTE(__pAddr+4, 17, 15, __Value) + +#endif +//----------------------------------------------------------- +// +// Rate +// +//----------------------------------------------------------- +// CCK Rates, TxHT = 0 +#define DESC8723B_RATE1M 0x00 +#define DESC8723B_RATE2M 0x01 +#define DESC8723B_RATE5_5M 0x02 +#define DESC8723B_RATE11M 0x03 + +// OFDM Rates, TxHT = 0 +#define DESC8723B_RATE6M 0x04 +#define DESC8723B_RATE9M 0x05 +#define DESC8723B_RATE12M 0x06 +#define DESC8723B_RATE18M 0x07 +#define DESC8723B_RATE24M 0x08 +#define DESC8723B_RATE36M 0x09 +#define DESC8723B_RATE48M 0x0a +#define DESC8723B_RATE54M 0x0b + +// MCS Rates, TxHT = 1 +#define DESC8723B_RATEMCS0 0x0c +#define DESC8723B_RATEMCS1 0x0d +#define DESC8723B_RATEMCS2 0x0e +#define DESC8723B_RATEMCS3 0x0f +#define DESC8723B_RATEMCS4 0x10 +#define DESC8723B_RATEMCS5 0x11 +#define DESC8723B_RATEMCS6 0x12 +#define DESC8723B_RATEMCS7 0x13 +#define DESC8723B_RATEMCS8 0x14 +#define DESC8723B_RATEMCS9 0x15 +#define DESC8723B_RATEMCS10 0x16 +#define DESC8723B_RATEMCS11 0x17 +#define DESC8723B_RATEMCS12 0x18 +#define DESC8723B_RATEMCS13 0x19 +#define DESC8723B_RATEMCS14 0x1a +#define DESC8723B_RATEMCS15 0x1b +#define DESC8723B_RATEVHTSS1MCS0 0x2c +#define DESC8723B_RATEVHTSS1MCS1 0x2d +#define DESC8723B_RATEVHTSS1MCS2 0x2e +#define DESC8723B_RATEVHTSS1MCS3 0x2f +#define DESC8723B_RATEVHTSS1MCS4 0x30 +#define DESC8723B_RATEVHTSS1MCS5 0x31 +#define DESC8723B_RATEVHTSS1MCS6 0x32 +#define DESC8723B_RATEVHTSS1MCS7 0x33 +#define DESC8723B_RATEVHTSS1MCS8 0x34 +#define DESC8723B_RATEVHTSS1MCS9 0x35 +#define DESC8723B_RATEVHTSS2MCS0 0x36 +#define DESC8723B_RATEVHTSS2MCS1 0x37 +#define DESC8723B_RATEVHTSS2MCS2 0x38 +#define DESC8723B_RATEVHTSS2MCS3 0x39 +#define DESC8723B_RATEVHTSS2MCS4 0x3a +#define DESC8723B_RATEVHTSS2MCS5 0x3b +#define DESC8723B_RATEVHTSS2MCS6 0x3c +#define DESC8723B_RATEVHTSS2MCS7 0x3d +#define DESC8723B_RATEVHTSS2MCS8 0x3e +#define DESC8723B_RATEVHTSS2MCS9 0x3f + + +#define RX_HAL_IS_CCK_RATE_8723B(pDesc)\ + (GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE1M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE2M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE5_5M ||\ + GET_RX_STATUS_DESC_RX_RATE_8723B(pDesc) == DESC8723B_RATE11M) + + +void rtl8195a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem); +void rtl8195a_fill_fake_txdesc(PADAPTER padapter, u8 *pDesc, u32 BufferLen, u8 IsPsPoll, u8 IsBTQosNull, u8 bDataFrame); + +s32 rtl8195ab_init_xmit_priv(PADAPTER padapter); +void rtl8195ab_free_xmit_priv(PADAPTER padapter); +s32 rtl8195ab_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe); +s32 rtl8195ab_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe); +s32 rtl8195ab_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe); +void rtl8195ab_xmitframe_resume(_adapter *padapter); +u32 GetDmaTxbdIdx(u32 ff_hwaddr); +struct xmit_buf * rtl8195a_dequeue_xmitbuf(struct rtw_tx_ring *ring); +BOOLEAN FreeXimtBuf(struct xmit_buf *pxmitbuf); +u8 check_tx_desc_resource(_adapter *padapter, int prio); + + +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_intf.c b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_intf.c new file mode 100644 index 0000000..4bbb072 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_intf.c @@ -0,0 +1,493 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#define _GSPI_INTF_C_ + +#include + +#ifdef CONFIG_GSPI_HCI + +struct dvobj_priv *gspi_dvobj_init(void) +{ +// int status = _FAIL; + struct dvobj_priv *dvobj = NULL; + PGSPI_DATA pgspi_data; + +_func_enter_; + + dvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*dvobj)); + if (NULL == dvobj) { + goto exit; + } + + pgspi_data = &dvobj->intf_data; + + rtw_mutex_init(&pgspi_data->spi_mutex); + //pgspi_data->block_transfer_len = 512; //512 blocks r/w is not required for GSPI interface + //pgspi_data->tx_block_mode = 0; + //pgspi_data->rx_block_mode = 0; + +// status = _SUCCESS; + +#if 0 +free_dvobj: + if (status != _SUCCESS && dvobj) { + rtw_mfree((u8*)dvobj, sizeof(*dvobj)); + dvobj = NULL; + } +#endif +exit: +_func_exit_; + + return dvobj; +} + +void gspi_dvobj_deinit(struct dvobj_priv *dvobj) +{ +//TODO +// struct dvobj_priv *dvobj = spi_get_drvdata(spi); + +_func_enter_; +//TODO +// spi_set_drvdata(spi, NULL); + if (dvobj) { +//TODO +// gspi_deinit(dvobj); + rtw_mutex_free(&dvobj->intf_data.spi_mutex); + rtw_mfree((u8*)dvobj, sizeof(*dvobj)); + } + +_func_exit_; +} + +s32 gspi_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe) +{ + s32 ret = _SUCCESS; + struct pkt_attrib *pattrib; + struct xmit_buf *pxmitbuf; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 *pframe = NULL; + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("+rtw_xmit_mgnt()\n")); + + pattrib = &pmgntframe->attrib; + pxmitbuf = pmgntframe->pxmitbuf; + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + rtw_hal_update_txdesc(padapter, pmgntframe, pmgntframe->buf_addr); + + pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; + //pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size + //pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len; + pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe); + + rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz); + + //RT_TRACE(_module_rtl871x_xmit_c_, _drv_always_, ("+rtw_xmit_mgnt(): type=%d\n", GetFrameSubType(pframe))); + if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly + { +//When using dedicated xmit frame for issue bcn on ap mode +//free xmit frame for bcn reserved page on station mode - Alex Fang +#if USE_DEDICATED_BCN_TX + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) { + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + } + rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, pxmitbuf->pbuf); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); +#else + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + rtw_xmit_xmitbuf(padapter, pxmitbuf); +#endif + } + else + { + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + rtw_xmit_xmitbuf(padapter, pxmitbuf); + } + + if (ret != _SUCCESS) + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("-rtw_xmit_mgnt\n")); + return ret; +} + +//#include +s32 gspi_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irql; + s32 err; + +#ifdef CONFIG_80211N_HT + if ((pxmitframe->frame_tag == DATA_FRAMETAG) && + (pxmitframe->attrib.ether_type != 0x0806) && + (pxmitframe->attrib.ether_type != 0x888e) && + (pxmitframe->attrib.dhcp_pkt != 1)) + { + if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) + rtw_issue_addbareq_cmd(padapter, pxmitframe); + } +#endif + +#if USE_SKB_AS_XMITBUF + rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); +#endif + + rtw_enter_critical_bh(&pxmitpriv->lock, &irql); +#if 1 //FIX_XMITFRAME_FAULT, move from rtw_xmit(). +#ifdef CONFIG_AP_MODE + if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) + { + rtw_exit_critical_bh(&pxmitpriv->lock, &irql); + return 1; + } +#endif +#endif + err = rtw_xmitframe_enqueue(padapter, pxmitframe); + rtw_exit_critical_bh(&pxmitpriv->lock, &irql); + + if (err != _SUCCESS) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_data(): enqueue xmitframe fail\n")); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + // Trick, make the statistics correct + pxmitpriv->tx_pkts--; + pxmitpriv->tx_drop++; + return _TRUE; + } + + rtw_count_tx_stats(padapter, pxmitframe, pxmitframe->attrib.last_txcmdsz); +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type > PRIMARY_ADAPTER){ + padapter = padapter->pbuddy_adapter; + } +#endif + + rtw_wakeup_task(&padapter->xmitThread); + + return _FALSE; +} + +const struct host_ctrl_intf_ops hci_ops = { + gspi_dvobj_init, + gspi_dvobj_deinit, + NULL, + NULL +}; + + +//TODO +#if 0 + +unsigned int oob_irq; +static irqreturn_t spi_interrupt_thread(int irq, void *data) +{ + struct dvobj_priv *dvobj; + PGSPI_DATA pgspi_data; + + + dvobj = (struct dvobj_priv*)data; + pgspi_data = &dvobj->intf_data; + + //spi_int_hdl(padapter); + if (pgspi_data->priv_wq) + queue_delayed_work(pgspi_data->priv_wq, &pgspi_data->irq_work, 0); + + return IRQ_HANDLED; +} + +static u8 gspi_alloc_irq(struct dvobj_priv *dvobj) +{ + PGSPI_DATA pgspi_data; + struct spi_device *spi; + int err; + + + pgspi_data = &dvobj->intf_data; + spi = pgspi_data->func; + + err = request_irq(oob_irq, spi_interrupt_thread, + IRQF_TRIGGER_FALLING,//IRQF_TRIGGER_HIGH;//|IRQF_ONESHOT, + DRV_NAME, dvobj); + //err = request_threaded_irq(oob_irq, NULL, spi_interrupt_thread, + // IRQF_TRIGGER_FALLING, + // DRV_NAME, dvobj); + if (err < 0) { + DBG_871X("Oops: can't allocate irq %d err:%d\n", oob_irq, err); + goto exit; + } + enable_irq_wake(oob_irq); + disable_irq(oob_irq); + +exit: + return err?_FAIL:_SUCCESS; +} + +#endif //#if 0 +//TODO +#if 0 + +static void spi_irq_work(void *data) +{ + struct delayed_work *dwork; + PGSPI_DATA pgspi; + struct dvobj_priv *dvobj; + + + dwork = container_of(data, struct delayed_work, work); + pgspi = container_of(dwork, GSPI_DATA, irq_work); + + dvobj = spi_get_drvdata(pgspi->func); + if (!dvobj->if1) { + DBG_871X("%s if1 == NULL !!\n", __FUNCTION__); + return; + } + spi_int_hdl(dvobj->if1); +} + +#endif //#if 0 + + +//TODO +#if 0 + +static int rtw_gspi_suspend(struct spi_device *spi, pm_message_t mesg) +{ + struct dvobj_priv *dvobj = spi_get_drvdata(spi); + PADAPTER padapter = (_adapter *)dvobj->if1; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct net_device *pnetdev = padapter->pnetdev; + int ret = 0; + + u32 start_time = rtw_get_current_time(); + + _func_enter_; + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + pwrpriv->bInSuspend = _TRUE; + + while (pwrpriv->bips_processing == _TRUE) + rtw_msleep_os(1); + + if((!padapter->bup) || (padapter->bDriverStopped)||(padapter->bSurpriseRemoved)) + { + DBG_871X("%s bup=%d bDriverStopped=%d bSurpriseRemoved = %d\n", __FUNCTION__ + ,padapter->bup, padapter->bDriverStopped,padapter->bSurpriseRemoved); + goto exit; + } + + rtw_cancel_all_timer(padapter); + LeaveAllPowerSaveMode(padapter); + + //padapter->net_closed = _TRUE; + //s1. + if(pnetdev) + { + netif_carrier_off(pnetdev); + rtw_netif_stop_queue(pnetdev); + } +#ifdef CONFIG_WOWLAN + padapter->pwrctrlpriv.bSupportWakeOnWlan=_TRUE; +#else + //s2. + //s2-1. issue rtw_disassoc_cmd to fw + disconnect_hdl(padapter, NULL); + //rtw_disassoc_cmd(padapter); +#endif + +#ifdef CONFIG_LAYER2_ROAMING_RESUME + if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) ) + { + DBG_871X("%s %s(" MAC_FMT "), length:%d assoc_ssid.length:%d\n",__FUNCTION__, + pmlmepriv->cur_network.network.Ssid.Ssid, + MAC_ARG(pmlmepriv->cur_network.network.MacAddress), + pmlmepriv->cur_network.network.Ssid.SsidLength, + pmlmepriv->assoc_ssid.SsidLength); + + pmlmepriv->to_roaming = 1; + } +#endif + + //s2-2. indicate disconnect to os + rtw_indicate_disconnect(padapter); + //s2-3. + rtw_free_assoc_resources(padapter, 1); + + //s2-4. + rtw_free_network_queue(padapter, _TRUE); + + rtw_led_control(padapter, LED_CTL_POWER_OFF); + + rtw_dev_unload(padapter); + + if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) + rtw_indicate_scan_done(padapter, 1); + + if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) + rtw_indicate_disconnect(padapter); + + // interface deinit + gspi_deinit(dvobj); + RT_TRACE(_module_hci_intfs_c_, _drv_notice_, ("%s: deinit GSPI complete!\n", __FUNCTION__)); + + rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_OFF); + rtw_mdelay_os(1); +exit: + DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ + , ret, rtw_get_passing_time_ms(start_time)); + + _func_exit_; + return ret; +} + +extern int pm_netdev_open(struct net_device *pnetdev,u8 bnormal); +int rtw_resume_process(_adapter *padapter) +{ + struct net_device *pnetdev; + struct pwrctrl_priv *pwrpriv; + u8 is_pwrlock_hold_by_caller; + u8 is_directly_called_by_auto_resume; + int ret = 0; + u32 start_time = rtw_get_current_time(); + + _func_enter_; + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + rtw_wifi_gpio_wlan_ctrl(WLAN_PWDN_ON); + rtw_mdelay_os(1); + + rtw_set_chip_endian(adapter); + + if (padapter) { + pnetdev = padapter->pnetdev; + pwrpriv = &padapter->pwrctrlpriv; + } else { + ret = -1; + goto exit; + } + + // interface init + if (gspi_init(adapter_to_dvobj(padapter)) != _SUCCESS) + { + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: initialize SDIO Failed!!\n", __FUNCTION__)); + goto exit; + } + rtw_hal_disable_interrupt(padapter); + if (gspi_alloc_irq(adapter_to_dvobj(padapter)) != _SUCCESS) + { + ret = -1; + RT_TRACE(_module_hci_intfs_c_, _drv_err_, ("%s: gspi_alloc_irq Failed!!\n", __FUNCTION__)); + goto exit; + } + + rtw_reset_drv_sw(padapter); + pwrpriv->bkeepfwalive = _FALSE; + + DBG_871X("bkeepfwalive(%x)\n",pwrpriv->bkeepfwalive); + if(pm_netdev_open(pnetdev,_TRUE) != 0) { + ret = -1; + goto exit; + } + + netif_device_attach(pnetdev); + netif_carrier_on(pnetdev); + + if( padapter->pid[1]!=0) { + DBG_871X("pid[1]:%d\n",padapter->pid[1]); + rtw_signal_process(padapter->pid[1], SIGUSR2); + } + + #ifdef CONFIG_LAYER2_ROAMING_RESUME + rtw_roaming(padapter, NULL); + #endif + + #ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_unlock_suspend(); + #endif //CONFIG_RESUME_IN_WORKQUEUE + + pwrpriv->bInSuspend = _FALSE; +exit: + DBG_871X("<=== %s return %d.............. in %dms\n", __FUNCTION__ + , ret, rtw_get_passing_time_ms(start_time)); + + _func_exit_; + + return ret; +} + +static int rtw_gspi_resume(struct spi_device *spi) +{ + struct dvobj_priv *dvobj = spi_get_drvdata(spi); + PADAPTER padapter = (_adapter *)dvobj->if1; + struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; + int ret = 0; + + + DBG_871X("==> %s (%s:%d)\n",__FUNCTION__, current->comm, current->pid); + + if(pwrpriv->bInternalAutoSuspend ){ + ret = rtw_resume_process(padapter); + } else { +#ifdef CONFIG_RESUME_IN_WORKQUEUE + rtw_resume_in_workqueue(pwrpriv); +#elif defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER) + if(rtw_is_earlysuspend_registered(pwrpriv)) { + //jeff: bypass resume here, do in late_resume + pwrpriv->do_late_resume = _TRUE; + } else { + ret = rtw_resume_process(padapter); + } +#else // Normal resume process + ret = rtw_resume_process(padapter); +#endif //CONFIG_RESUME_IN_WORKQUEUE + } + + DBG_871X("<======== %s return %d\n", __FUNCTION__, ret); + return ret; + +} + + +static struct spi_driver rtw_spi_drv = { + .probe = rtw_drv_probe, + .remove = rtw_dev_remove, + .suspend = rtw_gspi_suspend, + .resume = rtw_gspi_resume, + .driver = { + .name = "wlan_spi", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + } + +}; + +#endif //#if 0 +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_io.c b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_io.c new file mode 100644 index 0000000..f042c3f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_io.c @@ -0,0 +1,566 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ +#define _GSPI_IO_C_ + +#include + +#ifdef CONFIG_GSPI_HCI + +u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err); +s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err); +s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err); + +static u32 rtw_spi_transfer( + struct dvobj_priv *pdvobj, + bool pool, + u8* buf, + u32 buf_len) +{ + _mutex *spi_mutex; + u32 ret_value = _SUCCESS; + + spi_mutex = &(pdvobj->intf_data.spi_mutex); + + rtw_enter_critical_mutex(spi_mutex, NULL); + if(!WLAN_BSP_Transfer(buf, buf_len)) + ret_value = _FAIL; + rtw_exit_critical_mutex(spi_mutex, NULL); + + return ret_value; +} +static int addr_convert(u32 addr) +{ + u32 domain_id = 0 ; + u32 temp_addr = addr&0xffff0000; + + if (temp_addr == 0 ) { + domain_id = WLAN_IOREG_DOMAIN; + return domain_id; + } + + switch (temp_addr) { + case WLAN_LOCAL_OFFSET: + domain_id = SPI_LOCAL_DOMAIN; + break; + case WLAN_IOREG_OFFSET: + domain_id = WLAN_IOREG_DOMAIN; + break; + case FW_FIFO_OFFSET: + domain_id = FW_FIFO_DOMAIN; + break; + case TX_HIQ_OFFSET: + domain_id = TX_HIQ_DOMAIN; + break; + case TX_MIQ_OFFSET: + domain_id = TX_MIQ_DOMAIN; + break; + case TX_LOQ_OFFSET: + domain_id = TX_LOQ_DOMAIN; + break; + case RX_RXOFF_OFFSET: + domain_id = RX_RXFIFO_DOMAIN; + break; + default: + break; + } + + return domain_id; +} + +/* + * Description: + * Translate sdio fifo address to Domain ID in each WLAN FIFO + */ +static u32 hwaddr2txfifo(u32 addr) +{ + u32 fifo_domain_id; + switch (addr) + { + case WLAN_TX_HIQ_DEVICE_ID: + fifo_domain_id = TX_HIQ_DOMAIN; + break; + + case WLAN_TX_MIQ_DEVICE_ID: + fifo_domain_id = TX_MIQ_DOMAIN; + break; + + case WLAN_TX_LOQ_DEVICE_ID: + fifo_domain_id = TX_LOQ_DOMAIN; + break; + default: + fifo_domain_id = TX_LOQ_DOMAIN; + break; + } + + return fifo_domain_id; +} + +static u32 buf_endian_reverse(u32 src) +{ + return (((src&0x000000ff)<<24)|((src&0x0000ff00)<<8)| + ((src&0x00ff0000)>>8)|((src&0xff000000)>>24)); +} + +// +// Description: +// Query SDIO Local register to query current the number of Free TxPacketBuffer page. +// +// Assumption: +// 1. Running at PASSIVE_LEVEL +// 2. RT_TX_SPINLOCK is NOT acquired. +// +// Created by Roger, 2011.01.28. +// +#ifdef CONFIG_RTL8188F +u8 spi_query_status_info(struct dvobj_priv *pdvobj) +{ + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG, NULL); + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] =spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+2, NULL); + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+4, NULL); + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = spi_read8(pdvobj, LOCAL_REG_FREE_TXPG+6, NULL); + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n", + __FUNCTION__, + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); + //_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + + return _TRUE; +} +#else +u8 spi_query_status_info(struct dvobj_priv *pdvobj) +{ + u32 NumOfFreePage; + + NumOfFreePage = spi_read32(pdvobj, LOCAL_REG_FREE_TXPG, NULL); + +// _enter_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql); + rtw_memcpy(pdvobj->SdioTxFIFOFreePage, &NumOfFreePage, 4); + + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n", + __FUNCTION__, + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); +// _exit_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql); + + return _TRUE; +} + +#endif +static void spi_get_status_info(struct dvobj_priv *pdvobj, unsigned char *status) +{ +#ifdef CONFIG_MEMORY_ACCESS_ALIGNED + u32 local_status[2]; + u8 *pstatus = (u8*)(&local_status[0]); + + memcpy(pstatus, status, GSPI_STATUS_LEN); +#else + u8 *pstatus = status; +#endif + +#ifdef CONFIG_RTL8188F + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = GET_STATUS_PUB_PAGE_NUM(pstatus)*2; +#else + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = GET_STATUS_PUB_PAGE_NUM(pstatus); +#endif + + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = GET_STATUS_HI_PAGE_NUM(pstatus); + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] = GET_STATUS_MID_PAGE_NUM(pstatus); + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = GET_STATUS_LOW_PAGE_NUM(pstatus); + + RT_TRACE(_module_hci_ops_c_, _drv_dump_, + ("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n", + __FUNCTION__, + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); +} + +static int spi_read_write_reg(struct dvobj_priv *pdvobj, int write_flag, u32 addr, char * buf, int len, u32 eddien) +{ + int fun = 1, domain_id = 0x0; //LOCAL + unsigned int cmd = 0 ; + int byte_en = 0 ;//,i = 0 ; + int ret = 1; + unsigned char status[8] = {0}; + unsigned int data_tmp = 0; + u32 force_bigendian = eddien; + + u32 spi_buf[4] = {0}; + bool polled = TRUE; + + if (len!=1 && len!=2 && len != 4) { + return -1; + } + + domain_id = addr_convert(addr); + + addr &= 0x7fff; + len &= 0xff; + if (write_flag) //write register + { + int remainder = addr % 4; + u32 val32 = *(u32 *)buf; + switch(len) { + case 1: + byte_en = (0x1 << remainder); + data_tmp = (val32& 0xff)<< (remainder*8); + break; + case 2: + byte_en = (0x3 << remainder); + data_tmp = (val32 & 0xffff)<< (remainder*8); + break; + case 4: + byte_en = 0xf; + data_tmp = val32 & 0xffffffff; + break; + default: + byte_en = 0xf; + data_tmp = val32 & 0xffffffff; + break; + } + } + else //read register + { + switch(len) { + case 1: + byte_en = 0x1; + break; + case 2: + byte_en = 0x3; + break; + case 4: + byte_en = 0xf; + break; + default: + byte_en = 0xf; + break; + } + + if(domain_id == SPI_LOCAL_DOMAIN) + byte_en = 0; + } + + //addr = 0xF0 4byte: 0x2800f00f + REG_LEN_FORMAT(&cmd, byte_en); + REG_ADDR_FORMAT(&cmd, (addr&0xfffffffc)); + REG_DOMAIN_ID_FORMAT(&cmd, domain_id); + REG_FUN_FORMAT(&cmd, fun); + REG_RW_FORMAT(&cmd, write_flag); + + if (force_bigendian) { + cmd = buf_endian_reverse(cmd); + } + + if (!write_flag && (domain_id!= RX_RXFIFO_DOMAIN)) { + u32 read_data = 0; + + rtw_memset(spi_buf, 0x00, sizeof(spi_buf)); + + spi_buf[0] = cmd; + spi_buf[1] = 0; + spi_buf[2] = 0; + spi_buf[3] = 0; + + rtw_spi_transfer(pdvobj, polled, (u8*)spi_buf, sizeof(spi_buf)); + + rtw_memcpy(status, (u8 *) &spi_buf[1], sizeof(status)); + read_data = EF4Byte(spi_buf[3]); + + //add for 8810 +#ifdef CONFIG_BIG_ENDIAN + if (!force_bigendian) + read_data = buf_endian_reverse(read_data); +#else + if (force_bigendian) + read_data = buf_endian_reverse(read_data); +#endif + *(u32*)buf = read_data; + } else if (write_flag ) { + +#ifdef CONFIG_BIG_ENDIAN + if (!force_bigendian) + data_tmp = buf_endian_reverse(data_tmp); +#else + if (force_bigendian) + data_tmp = buf_endian_reverse(data_tmp); +#endif + + spi_buf[0] = cmd; + spi_buf[1] = data_tmp; + spi_buf[2] = 0; + spi_buf[3] = 0; + + rtw_spi_transfer(pdvobj, polled, (u8*)spi_buf, sizeof(spi_buf)); + + rtw_memcpy(status, (u8 *) &spi_buf[2], sizeof(status)); + } + + spi_get_status_info(pdvobj, (unsigned char*)status); + + return ret; +} + +static int spi_io_priv(struct dvobj_priv *pdvobj) +{ + //struct dvobj_priv *pdvobj = &Adapter->dvobjpriv; + + return _SUCCESS; +} + +static int spi_write8_endian(struct dvobj_priv *pdvobj, u32 addr, u32 buf, u32 big) +{ + return spi_read_write_reg(pdvobj,1,addr,(char *)&buf,1, big); +} + +u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u32 ret = 0; + int val32 = 0 , remainder = 0 ; + s32 _err = 0; + + _err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0); + remainder = addr % 4; + val32 = ret; + val32 = (val32& (0xff<< (remainder<<3)))>>(remainder<<3); + + if (err) + *err = _err; + + return (u8)val32; + +} + +u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u32 ret = 0; + int val32 = 0 , remainder = 0 ; + s32 _err = 0; + + _err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0); + remainder = addr % 4; + val32 = ret; + val32 = (val32& (0xffff<< (remainder<<3)))>>(remainder<<3); + + if (err) + *err = _err; + + return (u16)val32; +} + +u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u32 ret = 0; + s32 _err = 0; + + _err = spi_read_write_reg(pdvobj,0,addr&0xFFFFFFFC,(char *)&ret,4,0); + if (err) + *err = _err; + + return ret; +} + +s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err) +{ + int ret = 0; + + ret = spi_read_write_reg(pdvobj,1,addr,(char *)&buf,1,0); + if (err) + *err = ret; + return ret; +} + +s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err) +{ + int ret = 0; + + ret = spi_read_write_reg(pdvobj,1,addr,(char *)&buf,2,0); + if (err) + *err = ret; + return ret; +} + +s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err) +{ + int ret = 0; + + ret = spi_read_write_reg(pdvobj, 1,addr,(char *)&buf,4,0); + if (err) + *err = ret; + return ret; +} + +static int spi_read_rx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len, struct fifo_more_data *pmore_data) +{ + int fun = 1, domain_id = RX_RXFIFO_DOMAIN; + unsigned int cmd = 0; + unsigned char *status = buf + len; + u8 *spi_buf = (u8 *) (buf - GSPI_CMD_LEN); + int spi_buf_len = 0; + bool polled = TRUE; + bool use_alloc = FALSE; + u32 max_skb_len = 0; + +#ifndef CONFIG_DONT_CARE_TP + max_skb_len = MAX_SKB_BUF_SIZE; +#else + max_skb_len = MAX_RX_SKB_BUF_SIZE; +#endif + + if(((GSPI_CMD_LEN + len + GSPI_STATUS_LEN) > max_skb_len) || (!buf)) { + #if !defined(CONFIG_MP_INCLUDED) || !defined(CONFIG_MP_IWPRIV_SUPPORT) // Cloud 2013/09/06 + DBG_871X("data len=%d, MAX_SKB_BUF_SIZE(%d) is not enough, change to dynamic alloc\n", len, max_skb_len); + #endif + use_alloc = TRUE; + spi_buf_len = GSPI_CMD_LEN + len + GSPI_STATUS_LEN; + spi_buf = rtw_malloc(spi_buf_len); + + if(spi_buf == NULL) { + DBG_871X("Failed to alloc %d bytes\n", len); + return _FAIL; + } + else { + buf = spi_buf + GSPI_CMD_LEN; + status = spi_buf + GSPI_CMD_LEN + len; + } + } + + FIFO_LEN_FORMAT(&cmd, len); //TX Agg len + FIFO_DOMAIN_ID_FORMAT(&cmd, domain_id); + FIFO_FUN_FORMAT(&cmd, fun); + FIFO_RW_FORMAT(&cmd, 0); //read + + rtw_memset(status, 0x00, GSPI_STATUS_LEN); + rtw_memset(buf, 0x0, len); + +#ifdef CONFIG_MEMORY_ACCESS_ALIGNED + memcpy(spi_buf, (u8 *)&cmd, sizeof(int)); +#else + *((u32 *) spi_buf) = cmd; +#endif + + rtw_spi_transfer(pdvobj, polled, (u8 *) spi_buf, GSPI_CMD_LEN + len + GSPI_STATUS_LEN); + + spi_get_status_info(pdvobj, status); + pmore_data->more_data = GET_STATUS_HISR_LOW8BIT(status) & BIT(0); + pmore_data->len = GET_STATUS_RX_LENGTH(status); + + if(use_alloc) { + //Drop the data + rtw_mfree(spi_buf, spi_buf_len); + return _FAIL; + } + + return _SUCCESS; +} + +static int spi_write_tx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *buf, u32 len) +{ + int fun = 1; //TX_HIQ_FIFO + unsigned int cmd = 0; + unsigned char *status = buf + len; + u8 *spi_buf = (u8 *) (buf - GSPI_CMD_LEN); + u32 page_num = 0; + u32 wait_num = 100; + bool polled = TRUE; + u32 fifo = 0; + +_func_enter_; + fifo = hwaddr2txfifo(addr); + + spi_query_status_info(pdvobj); + if (fifo == TX_HIQ_DOMAIN) + page_num = pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX]; + else if (fifo == TX_LOQ_DOMAIN) + page_num = pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX]; + else + page_num = pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX]; + + while (page_num + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < 15) { + DBG_871X("Oops: spi_write_tx_fifo(): page_num is %d, padapter->pub_page is %d, wait_num is %d", + page_num, pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX], wait_num); + + rtw_msleep_os(1); + //rtw_udelay_os(20); + spi_read32(pdvobj, 0x608, NULL); + + if (fifo == TX_HIQ_DOMAIN) + page_num = pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX]; + else if (fifo == TX_LOQ_DOMAIN) + page_num = pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX]; + else + page_num = pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX]; + + if (wait_num <= 2) { + DBG_871X("%s(): wait_num is <= 2 drop", __FUNCTION__); + return _FAIL; + } + wait_num --; + } + + FIFO_LEN_FORMAT(&cmd, len); //TX Agg len + FIFO_DOMAIN_ID_FORMAT(&cmd, fifo); + FIFO_FUN_FORMAT(&cmd, fun); + FIFO_RW_FORMAT(&cmd, (unsigned int) 1); //write + + //DBG_871X("%s(): len = %d\n", __FUNCTION__, len); + //RT_PRINT_DATA(_module_hal_xmit_c_, _drv_always_, "Tx:\n", buf, GSPI_CMD_LEN + len); + rtw_memset(status, 0x00, GSPI_STATUS_LEN); + +#ifdef CONFIG_MEMORY_ACCESS_ALIGNED + memcpy(spi_buf, (u8 *)&cmd, sizeof(int)); +#else + *((u32 *) spi_buf) = cmd; +#endif + + rtw_spi_transfer(pdvobj, polled, (u8 *) spi_buf, GSPI_CMD_LEN + len + GSPI_STATUS_LEN); + + spi_get_status_info(pdvobj, status); + +_func_exit_; + + return _SUCCESS; +} + +void spi_set_intf_ops(struct _io_ops *pops) +{ + pops->init_io_priv = &spi_io_priv; + pops->write8_endian = &spi_write8_endian; + + pops->_read8 = &spi_read8; + pops->_read16 = &spi_read16; + pops->_read32 = &spi_read32; + + pops->_write8 = &spi_write8; + pops->_write16 = &spi_write16; + pops->_write32 = &spi_write32; + + pops->read_rx_fifo = &spi_read_rx_fifo; + pops->write_tx_fifo = &spi_write_tx_fifo; +} +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_isr.c b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_isr.c new file mode 100644 index 0000000..741a879 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_isr.c @@ -0,0 +1,236 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + ******************************************************************************/ +#define _GSPI_ISR_C_ + +#include + +#ifdef CONFIG_GSPI_HCI + +extern struct recv_buf* rtw_recv_rxfifo(_adapter * padapter, u32 size, struct fifo_more_data* more_data); +u8 spi_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +u16 spi_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +u32 spi_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err); +s32 spi_write8(struct dvobj_priv *pdvobj, u32 addr, u8 buf, s32 *err); +s32 spi_write16(struct dvobj_priv *pdvobj, u32 addr, u16 buf, s32 *err); +s32 spi_write32(struct dvobj_priv *pdvobj, u32 addr, u32 buf, s32 *err); + +void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr) +{ + struct dvobj_priv *pdvobj = padapter->dvobj; + +#ifdef CONFIG_LPS_LCLK + if (sdio_hisr & HCI_HISR_CPWM1) + { + struct reportpwrstate_parm report; + + report.state = spi_read8(pdvobj, LOCAL_REG_HCPWM1, NULL); + if(report.state == 0xEA) + report.state = PS_STATE_S0; + else + report.state = PS_STATE_S2; + cpwm_int_hdl(padapter, &report); + } +#endif + + if (sdio_hisr & HCI_HISR_TXERR) + { + u32 status; + + status = rtw_read32(padapter, REG_TXDMA_STATUS); + rtw_write32(padapter, REG_TXDMA_STATUS, status); + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, status)); + } + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN + + #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + if (sdio_hisr & HCI_HISR_BCNERLY_INT) + #endif + #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + if (sdio_hisr & (HCI_HISR_TXBCNOK|HCI_HISR_TXBCNERR)) + #endif + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + #if 0 //for debug + if (sdio_hisr & SDIO_HISR_BCNERLY_INT) + DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__); + + if (sdio_hisr & SDIO_HISR_TXBCNOK) + DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); + + if (sdio_hisr & SDIO_HISR_TXBCNERR) { + u1Byte v422, v550, v419; + v422 = rtw_read8(padapter, 0x422); + v419 = rtw_read8(padapter, 0x419); + v550 = rtw_read8(padapter, 0x550); + + DBG_8192C("%s: SDIO_HISR_TXBCNERR 422=%02x, 419=%02x, 550=%02x\n", __func__, v422, v419, v550); + } + #endif + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + //send_beacon(padapter); + if(pmlmepriv->update_bcn == _TRUE) + { + //tx_beacon_hdl(padapter, NULL); + set_tx_beacon_cmd(padapter); + } + } + +#if 0//def CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, WIFI_AP_STATE)) + { + //send_beacon(padapter); + if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE) + { + //tx_beacon_hdl(padapter, NULL); + set_tx_beacon_cmd(padapter->pbuddy_adapter); + } + } +#endif + } +#endif //CONFIG_INTERRUPT_BASED_TXBCN + + if (sdio_hisr & HCI_HISR_C2HCMD) + { + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: C2H Command\n", __func__)); +//TODO +// rtw_c2h_wk_cmd(padapter); + } + + if (sdio_hisr & HCI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW) + { + struct recv_buf *precvbuf; + struct fifo_more_data more_data = {0}; + + //RT_TRACE(_module_hci_ops_c_,_drv_info_, ("%s: RX Request, size=%d\n", __func__, pdvobj->SdioRxFIFOSize)); + + sdio_hisr ^= HCI_HISR_RX_REQUEST; + + do { + more_data.more_data = 0; + more_data.len = 0; + + if (pdvobj->SdioRxFIFOSize == 0) + { + u16 val = 0; + s32 ret; + + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize)); + + val = spi_read16(pdvobj, LOCAL_REG_RX0_REQ_LEN_1_BYTE, &ret); + if (!ret) { + pdvobj->SdioRxFIFOSize = val; + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize again size=%d\n", __func__, pdvobj->SdioRxFIFOSize)); + } else { + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize ERROR!!\n", __func__)); + } + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize)); + } + + if (pdvobj->SdioRxFIFOSize != 0) + { +#ifdef RTL8723A_SDIO_LOOPBACK + sd_recv_loopback(padapter, pdvobj->SdioRxFIFOSize); +#else + if (sdio_hisr & HCI_HISR_RXFOVW) + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s RXFOVW RX\n", __func__)); + + precvbuf = rtw_recv_rxfifo(padapter, pdvobj->SdioRxFIFOSize, &more_data); + if (precvbuf) + rtw_rxhandler(padapter, precvbuf); + + if (more_data.more_data) { + pdvobj->SdioRxFIFOSize = more_data.len; + } else { + pdvobj->SdioRxFIFOSize = 0; + } +#endif + //If Rx_request ISR is set, execute receive tasklet (sdio_hisr & SPI_HISR_RX_REQUEST) +#if defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) && defined(CONFIG_RECV_TASKLET_THREAD) + rtw_wakeup_task(&padapter->recvtasklet_thread); +#endif + } + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN +{ + //Prevent BCN update not realtime in ap mode - Alex Fang + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && (pmlmepriv->update_bcn == _TRUE)) + break; +} +#endif + } while (more_data.more_data); +#ifdef PLATFORM_LINUX +#ifdef CONFIG_GSPI_HCI + tasklet_schedule(&padapter->recvpriv.recv_tasklet); +#endif +#endif + } +} + + +void spi_int_hdl(PADAPTER padapter) +{ + struct dvobj_priv *pdvobj = padapter->dvobj; + u32 sdio_hisr = 0; + s32 ret; + + if ((padapter->bDriverStopped == _TRUE) || + (padapter->bSurpriseRemoved == _TRUE)) + return; + + sdio_hisr = spi_read32(pdvobj, LOCAL_REG_HISR, &ret); + if (!ret) { + RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SDIO_REG_HISR FAIL!!\n", __func__)); + return; + } + pdvobj->SdioRxFIFOSize = spi_read16(pdvobj, LOCAL_REG_RX0_REQ_LEN_1_BYTE, &ret); + + if (!ret) { + RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SPI_REG_RX0_REQ_LEN FAIL!!\n", __func__)); + return; + } + + if (sdio_hisr & pdvobj->sdio_himr) + { + u32 v32; + + sdio_hisr &= pdvobj->sdio_himr; + + // clear HISR + v32 = sdio_hisr & MASK_SPI_HISR_CLEAR; + if (v32) { + spi_write32(pdvobj, LOCAL_REG_HISR, v32, &ret); + } + + spi_int_dpc(padapter, sdio_hisr); + } else { + RT_TRACE(_module_hci_ops_c_, _drv_err_, + ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n", + __FUNCTION__, sdio_hisr, pdvobj->sdio_himr)); + if(sdio_hisr) + spi_write32(pdvobj, LOCAL_REG_HISR, sdio_hisr, &ret); + } +} + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_spec.h b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_spec.h new file mode 100644 index 0000000..1018d94 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/gspi/gspi_spec.h @@ -0,0 +1,257 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ + +#ifndef __GSPI_SPEC_H__ +#define __GSPI_SPEC_H__ + + +#define SPI_LOCAL_DOMAIN 0x0 +#define WLAN_IOREG_DOMAIN 0x8 +#define FW_FIFO_DOMAIN 0x4 +#define TX_HIQ_DOMAIN 0xc +#define TX_MIQ_DOMAIN 0xd +#define TX_LOQ_DOMAIN 0xe +#define RX_RXFIFO_DOMAIN 0x1f + +//IO Bus domain address mapping +#define DEFUALT_OFFSET 0x0 +#define LOCAL_OFFSET 0x10250000 +#define SPI_LOCAL_OFFSET 0x10250000 +#define WLAN_IOREG_OFFSET 0x10260000 +#define FW_FIFO_OFFSET 0x10270000 +#define TX_HIQ_OFFSET 0x10310000 +#define TX_MIQ_OFFSET 0x1032000 +#define TX_LOQ_OFFSET 0x10330000 +#define RX_RXOFF_OFFSET 0x10340000 + +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define WLAN_TX_EXQ_DEVICE_ID 3 // 0b[16], 011b[15:13] +#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13] +#define WLAN_IOREG_DEVICE_ID 8 // 1b[16] + +//SPI Tx Free Page Index +#define HI_QUEUE_IDX 0 +#define MID_QUEUE_IDX 1 +#define LOW_QUEUE_IDX 2 +#define PUBLIC_QUEUE_IDX 3 + +#define MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ +#define MAX_RX_QUEUE 1 + +//SPI Local registers +#ifdef CONFIG_RTL8188F +#define SPI_REG_TX_CTRL 0x0000 // SPI Tx Control +#define SPI_REG_STATUS_RECOVERY 0x0004 +#define SPI_REG_INT_TIMEOUT 0x0006 +#define SPI_REG_HIMR 0x0014 // SPI Host Interrupt Mask +#define SPI_REG_HISR 0x0018 // SPI Host Interrupt Service Routine +#define SPI_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length +#define SPI_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page +#define SPI_REG_HTSFR_INFO 0x0030 // HTSF Informaion +#define SPI_REG_HCPWM1 0x0038 // HCI Current Power Mode 1 +#define SPI_REG_HCPWM2 0x003A // HCI Current Power Mode 2 +#define SPI_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 need check for 8188f??? +#define SPI_REG_HPS_CLKR 0x0084 // HCI Power Save Clock +#define SPI_REG_HSUS_CTRL 0x0086 // SPI HCI Suspend Control +#else +#define SPI_REG_TX_CTRL 0x0000 // SPI Tx Control +#define SPI_REG_STATUS_RECOVERY 0x0004 +#define SPI_REG_INT_TIMEOUT 0x0006 +#define SPI_REG_HIMR 0x0014 // SPI Host Interrupt Mask +#define SPI_REG_HISR 0x0018 // SPI Host Interrupt Service Routine +#define SPI_REG_RX0_REQ_LEN 0x001C // RXDMA Request Length +#define SPI_REG_FREE_TXPG 0x0020 // Free Tx Buffer Page +#define SPI_REG_HCPWM1 0x0024 // HCI Current Power Mode 1 +#define SPI_REG_HCPWM2 0x0026 // HCI Current Power Mode 2 +#define SPI_REG_HTSFR_INFO 0x0030 // HTSF Informaion +#define SPI_REG_HRPWM1 0x0080 // HCI Request Power Mode 1 +#define SPI_REG_HRPWM2 0x0082 // HCI Request Power Mode 2 +#define SPI_REG_HPS_CLKR 0x0084 // HCI Power Save Clock +#define SPI_REG_HSUS_CTRL 0x0086 // SPI HCI Suspend Control +#define SPI_REG_HIMR_ON 0x0090 //SPI Host Extension Interrupt Mask Always +#define SPI_REG_HISR_ON 0x0091 //SPI Host Extension Interrupt Status Always +#define SPI_REG_CFG 0x00F0 //SPI Configuration Register +#endif + +#define LOCAL_REG_TX_CTRL (SPI_REG_TX_CTRL |SPI_LOCAL_OFFSET) +#define LOCAL_REG_STATUS_RECOVERY (SPI_REG_STATUS_RECOVERY |SPI_LOCAL_OFFSET) +#define LOCAL_REG_INT_TIMEOUT (SPI_REG_INT_TIMEOUT |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HIMR (SPI_REG_HIMR |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HISR (SPI_REG_HISR |SPI_LOCAL_OFFSET) +#define LOCAL_REG_RX0_REQ_LEN_1_BYTE (SPI_REG_RX0_REQ_LEN |SPI_LOCAL_OFFSET) +#define LOCAL_REG_FREE_TXPG (SPI_REG_FREE_TXPG |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HRPWM1 (SPI_REG_HRPWM1 |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HCPWM1 (SPI_REG_HCPWM1 |SPI_LOCAL_OFFSET) +#define LOCAL_REG_SUSPEND_NORMAL (SPI_REG_HSUS_CTRL|SPI_LOCAL_OFFSET) +#define HCI_HIMR_DISABLED 0 + +//SPI HIMR MASK diff with SDIO +#ifdef CONFIG_RTL8188F +#define HCI_HISR_RX_REQUEST BIT(0) +#define HCI_HISR_AVAL BIT(1) +#define HCI_HISR_TXERR BIT(2) +#define HCI_HISR_RXERR BIT(3) +#define HCI_HISR_TXFOVW BIT(4) +#define HCI_HISR_RXFOVW BIT(5) +#define HCI_HISR_TXBCNOK BIT(6) +#define HCI_HISR_TXBCNERR BIT(7) +#define HCI_HISR_BCNERLY_INT BIT(16) +#define HCI_HISR_C2HCMD BIT(17) +#define HCI_HISR_CPWM1 BIT(18) +#define HCI_HISR_CPWM2 BIT(19) +#define HCI_HISR_HSISR_IND BIT(20) +#define HCI_HISR_GTINT3_IND BIT(21) +#define HCI_HISR_GTINT4_IND BIT(22) +#define HCI_HISR_PSTIMEOUT BIT(23) +#define HCI_HISR_OCPINT BIT(24) +#define HCI_HISR_ATIMEND BIT(25) +#define HCI_HISR_ATIMEND_E BIT(26) +#define HCI_HISR_CTWEND BIT(27) +#define HCI_HISR_TSF_BIT32_TOGGLE BIT(29) +#define HCI_HISR_PSTIMEOUT_E BIT(30) +//SPI HIMR MASK diff with SDIO +#define HCI_HIMR_RX_REQUEST BIT(0) +#define HCI_HIMR_AVAL BIT(1) +#define HCI_HIMR_TXERR BIT(2) +#define HCI_HIMR_RXERR BIT(3) +#define HCI_HIMR_TXFOVW BIT(4) +#define HCI_HIMR_RXFOVW BIT(5) +#define HCI_HIMR_TXBCNOK BIT(6) +#define HCI_HIMR_TXBCNERR BIT(7) +#define HCI_HIMR_BCNERLY_INT BIT(16) +#define HCI_HIMR_C2HCMD BIT(17) +#define HCI_HIMR_CPWM1 BIT(18) +#define HCI_HIMR_CPWM2 BIT(19) +#define HCI_HIMR_HSISR_IND BIT(20) +#define HCI_HIMR_GTINT3_IND BIT(21) +#define HCI_HIMR_GTINT4_IND BIT(22) +#define HCI_HIMR_PSTIMEOUT BIT(23) +#define HCI_HIMR_OCPINT BIT(24) +#define HCI_HIMR_ATIMEND BIT(25) +#define HCI_HIMR_ATIMEND_E BIT(26) +#define HCI_HIMR_CTWEND BIT(27) +#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29) +#define HCI_HIMR_PSTIMEOUT_E BIT(30) +#else +#define HCI_HISR_RX_REQUEST BIT(0) +#define HCI_HISR_AVAL BIT(1) +#define HCI_HISR_TXERR BIT(2) +#define HCI_HISR_RXERR BIT(3) +#define HCI_HISR_TXFOVW BIT(4) +#define HCI_HISR_RXFOVW BIT(5) +#define HCI_HISR_TXBCNOK BIT(6) +#define HCI_HISR_TXBCNERR BIT(7) +#define HCI_HISR_BCNERLY_INT BIT(16) +#define HCI_HISR_ATIMEND BIT(17) +#define HCI_HISR_ATIMEND_E BIT(18) +#define HCI_HISR_CTWEND BIT(19) +#define HCI_HISR_C2HCMD BIT(20) +#define HCI_HISR_CPWM1 BIT(21) +#define HCI_HISR_CPWM2 BIT(22) +#define HCI_HISR_HSISR_IND BIT(23) +#define HCI_HISR_GTINT3_IND BIT(24) +#define HCI_HISR_GTINT4_IND BIT(25) +#define HCI_HISR_PSTIMEOUT BIT(26) +#define HCI_HISR_OCPINT BIT(27) +#define HCI_HISR_TSF_BIT32_TOGGLE BIT(29) +//SPI HIMR MASK diff with SDIO +#define HCI_HIMR_RX_REQUEST BIT(0) +#define HCI_HIMR_AVAL BIT(1) +#define HCI_HIMR_TXERR BIT(2) +#define HCI_HIMR_RXERR BIT(3) +#define HCI_HIMR_TXFOVW BIT(4) +#define HCI_HIMR_RXFOVW BIT(5) +#define HCI_HIMR_TXBCNOK BIT(6) +#define HCI_HIMR_TXBCNERR BIT(7) +#define HCI_HIMR_BCNERLY_INT BIT(16) +#define HCI_HIMR_ATIMEND BIT(17) +#define HCI_HIMR_ATIMEND_E BIT(18) +#define HCI_HIMR_CTWEND BIT(19) +#define HCI_HIMR_C2HCMD BIT(20) +#define HCI_HIMR_CPWM1 BIT(21) +#define HCI_HIMR_CPWM2 BIT(22) +#define HCI_HIMR_HSISR_IND BIT(23) +#define HCI_HIMR_GTINT3_IND BIT(24) +#define HCI_HIMR_GTINT4_IND BIT(25) +#define HCI_HIMR_PSTIMEOUT BIT(26) +#define HCI_HIMR_OCPINT BIT(27) +#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29) +#endif +#define MASK_SPI_HISR_CLEAR (HCI_HIMR_TXERR |\ + HCI_HIMR_RXERR |\ + HCI_HIMR_TXFOVW |\ + HCI_HIMR_RXFOVW |\ + HCI_HIMR_TXBCNOK |\ + HCI_HIMR_TXBCNERR |\ + HCI_HIMR_C2HCMD |\ + HCI_HIMR_CPWM1 |\ + HCI_HIMR_CPWM2 |\ + HCI_HIMR_HSISR_IND |\ + HCI_HIMR_GTINT3_IND |\ + HCI_HIMR_GTINT4_IND |\ + HCI_HIMR_PSTIMEOUT |\ + HCI_HIMR_OCPINT) + +#define REG_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 8, x)//(x<<(unsigned int)24) +#define REG_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define REG_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define REG_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define REG_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + +#define FIFO_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 16, x)//(x<<(unsigned int)24) +//#define FIFO_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define FIFO_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define FIFO_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define FIFO_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + + +//get status dword0 +#define GET_STATUS_PUB_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 24, 8) +#define GET_STATUS_HI_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 18, 6) +#define GET_STATUS_MID_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 12, 6) +#define GET_STATUS_LOW_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 6, 6) +#define GET_STATUS_HISR_HI6BIT(status) LE_BITS_TO_4BYTE(status, 0, 6) + +//get status dword1 +#define GET_STATUS_HISR_MID8BIT(status) LE_BITS_TO_4BYTE(status + 4, 24, 8) +#define GET_STATUS_HISR_LOW8BIT(status) LE_BITS_TO_4BYTE(status + 4, 16, 8) +#define GET_STATUS_ERROR(status) LE_BITS_TO_4BYTE(status + 4, 17, 1) +#define GET_STATUS_INT(status) LE_BITS_TO_4BYTE(status + 4, 16, 1) +#define GET_STATUS_RX_LENGTH(status) LE_BITS_TO_4BYTE(status + 4, 0, 16) + + +#define RXDESC_SIZE 24 + +#define TX_FREE_PG_QUEUE 4 // The number of Tx FIFO free page +#define TX_FIFO_PAGE_SZ 128 + +struct spi_more_data { + unsigned long more_data; + unsigned long len; +}; + +extern BUS_DRV_OPS_T bus_driver_ops; + +extern u8 spi_query_status_info(struct dvobj_priv *pdvobj); + +extern void spi_set_intf_ops(struct _io_ops *pops); + +#endif //__GSPI_SPEC_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/hci_intfs.h b/USDK/component/common/drivers/wlan/realtek/src/hci/hci_intfs.h new file mode 100644 index 0000000..bc205b5 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/hci_intfs.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _HCI_INTFS_H_ +#define _HCI_INTFS_H_ + +#include + +struct host_ctrl_intf_ops +{ + struct dvobj_priv * (*dvobj_init)(void); + void (*dvobj_deinit)(struct dvobj_priv *dvobj); + void (*dvobj_request_irq)(struct dvobj_priv *dvobj); + void (*dvobj_free_irq)(struct dvobj_priv *dvobj); +}; + +extern struct dvobj_priv *hci_dvobj_init(void); +extern void hci_dvobj_deinit(struct dvobj_priv *dvobj); +extern void hci_dvobj_request_irq(struct dvobj_priv *dvobj); +extern void hci_dvobj_free_irq(struct dvobj_priv *dvobj); + +#if defined(CONFIG_GSPI_HCI) +#define hci_bus_intf_type RTW_GSPI +#define hci_set_intf_ops spi_set_intf_ops +#define hci_intf_start rtw_hal_enable_interrupt +#define hci_intf_stop rtw_hal_disable_interrupt +extern s32 gspi_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe); +extern s32 gspi_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe); +#endif + +#if defined(CONFIG_SDIO_HCI) +#define hci_bus_intf_type RTW_SDIO +#define hci_set_intf_ops sdio_set_intf_ops +#define hci_intf_start rtw_hal_enable_interrupt +#define hci_intf_stop rtw_hal_disable_interrupt +extern s32 sdio_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe); +extern s32 sdio_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe); + +#endif + +#if defined(CONFIG_LX_HCI) +#define hci_bus_intf_type RTW_LXBUS +#define hci_set_intf_ops lxbus_set_intf_ops +#define hci_intf_start rtw_hal_enable_interrupt +#define hci_intf_stop hci_lxbus_intf_stop +void hci_lxbus_intf_stop(_adapter *padapter); +u32 lextra_bus_dma_Interrupt (void* data); +#endif + + +#endif //_HCI_INTFS_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/hci_spec.h b/USDK/component/common/drivers/wlan/realtek/src/hci/hci_spec.h new file mode 100644 index 0000000..8843305 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/hci_spec.h @@ -0,0 +1,433 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __HCI_SPEC_H__ +#define __HCI_SPEC_H__ + + +#if defined(CONFIG_GSPI_HCI) +#include "gspi/gspi_spec.h" + +// SPI Header Files +#ifdef PLATFORM_LINUX +#include +#endif + +#define GSPI_CMD_LEN 4 +#define HAL_INTERFACE_CMD_LEN GSPI_CMD_LEN +#define GSPI_STATUS_LEN 8 +#define HAL_INTERFACE_CMD_STATUS_LEN GSPI_STATUS_LEN +#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_OVERHEAD) +//reserve tx headroom in case of softap forwarding unicase packet +#define RX_RESERV_HEADROOM (SKB_WLAN_TX_EXTRA_LEN>RX_DRIVER_INFO+RXDESC_SIZE)?(SKB_WLAN_TX_EXTRA_LEN-RX_DRIVER_INFO-RXDESC_SIZE):0 +typedef struct gspi_data +{ + //u8 func_number; + + //u8 tx_block_mode; + //u8 rx_block_mode; + u16 block_transfer_len; //u32 block_transfer_len; + +#ifdef PLATFORM_LINUX + struct spi_device *func; + + struct workqueue_struct *priv_wq; + struct delayed_work irq_work; +#endif + +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + _mutex spi_mutex; +#endif +} GSPI_DATA, *PGSPI_DATA; + +#define INTF_DATA GSPI_DATA + +//extern void spi_set_intf_ops(struct _io_ops *pops); +extern void spi_int_hdl(PADAPTER padapter); +#define rtw_hci_interrupt_handler(__adapter) spi_int_hdl(__adapter) + +#elif defined(CONFIG_SDIO_HCI) +#include "sdio/sdio_spec.h" + +#define GSPI_CMD_LEN 0 +#define HAL_INTERFACE_CMD_LEN GSPI_CMD_LEN +#define GSPI_STATUS_LEN 8 +#define HAL_INTERFACE_CMD_STATUS_LEN GSPI_STATUS_LEN +#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_OVERHEAD) +#define RX_RESERV_HEADROOM (SKB_WLAN_TX_EXTRA_LEN>RX_DRIVER_INFO+RXDESC_SIZE)?(SKB_WLAN_TX_EXTRA_LEN-RX_DRIVER_INFO-RXDESC_SIZE):0 + +typedef struct gspi_data +{ + //u8 func_number; + + //u8 tx_block_mode; + //u8 rx_block_mode; + u16 block_transfer_len; //u32 block_transfer_len; + +#ifdef PLATFORM_LINUX + struct spi_device *func; + + struct workqueue_struct *priv_wq; + struct delayed_work irq_work; +#endif + + struct sdio_func *func; + +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + _mutex spi_mutex; +#endif +} GSPI_DATA, *PGSPI_DATA; + +#define INTF_DATA GSPI_DATA + +//extern void spi_set_intf_ops(struct _io_ops *pops); +extern void spi_int_hdl(PADAPTER padapter); +#define rtw_hci_interrupt_handler(__adapter) spi_int_hdl(__adapter) + +#elif defined(CONFIG_USB_HCI) +#include +#include + +#elif defined(CONFIG_PCI_HCI) +#include +#ifdef PLATFORM_LINUX +#include +#endif + +#define INTF_CMD_LEN 0 + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define PCI_MAX_BRIDGE_NUMBER 255 +#define PCI_MAX_DEVICES 32 +#define PCI_MAX_FUNCTION 8 + +#define PCI_CONF_ADDRESS 0x0CF8 // PCI Configuration Space Address +#define PCI_CONF_DATA 0x0CFC // PCI Configuration Space Data + +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 + +#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define PCI_VENDER_ID_REALTEK 0x10ec + +#define HAL_HW_PCI_8180_DEVICE_ID 0x8180 +#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 //8185 or 8185b +#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 //8185b +#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 //8185b +#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 //8190 +#define HAL_HW_PCI_8723E_DEVICE_ID 0x8723 //8723E +#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 //8192 PCI-E +#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 //8192 SE +#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 //8192 SE +#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 //8191 SE Crab +#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 //8191 SE RE +#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 //8191 SE Unicron +#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 //8190 PCI for Ceraga +#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 //8190 Cardbus for Ceraga +#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 //8192e PCIE for Ceraga +#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 //8192e Express Card for Ceraga +#define HAL_HW_PCI_700F_DEVICE_ID 0x700F +#define HAL_HW_PCI_701F_DEVICE_ID 0x701F +#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304 +#define HAL_HW_PCI_8192CET_DEVICE_ID 0x8191 //8192ce +#define HAL_HW_PCI_8192CE_DEVICE_ID 0x8178 //8192ce +#define HAL_HW_PCI_8191CE_DEVICE_ID 0x8177 //8192ce +#define HAL_HW_PCI_8188CE_DEVICE_ID 0x8176 //8192ce +#define HAL_HW_PCI_8192CU_DEVICE_ID 0x8191 //8192ce +#define HAL_HW_PCI_8192DE_DEVICE_ID 0x8193 //8192de +#define HAL_HW_PCI_002B_DEVICE_ID 0x002B //8192de, provided by HW SD +#define HAL_HW_PCI_8188EE_DEVICE_ID 0x8179 + +#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 //8190 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192SE 0x10 +#define HAL_HW_PCI_REVISION_ID_8192CE 0x1 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 //8192 support 16 pages of IO registers +#define HAL_HW_PCI_REVISION_ID_8192DE 0x0 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 //8192 support 16 pages of IO registers + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0,//0b'0000,0001 + PCI_BRIDGE_VENDOR_ATI, //= 0x02,//0b'0000,0010 + PCI_BRIDGE_VENDOR_AMD, //= 0x04,//0b'0000,0100 + PCI_BRIDGE_VENDOR_SIS ,//= 0x08,//0b'0000,1000 + PCI_BRIDGE_VENDOR_UNKNOWN, //= 0x40,//0b'0100,0000 + PCI_BRIDGE_VENDOR_MAX ,//= 0x80 +} ; + +// copy this data structor defination from MSDN SDK +typedef struct _PCI_COMMON_CONFIG { + u16 VendorID; + u16 DeviceID; + u16 Command; + u16 Status; + u8 RevisionID; + u8 ProgIf; + u8 SubClass; + u8 BaseClass; + u8 CacheLineSize; + u8 LatencyTimer; + u8 HeaderType; + u8 BIST; + + union { + struct _PCI_HEADER_TYPE_0 { + u32 BaseAddresses[6]; + u32 CIS; + u16 SubVendorID; + u16 SubSystemID; + u32 ROMBaseAddress; + u8 CapabilitiesPtr; + u8 Reserved1[3]; + u32 Reserved2; + + u8 InterruptLine; + u8 InterruptPin; + u8 MinimumGrant; + u8 MaximumLatency; + } type0; +#if 0 + struct _PCI_HEADER_TYPE_1 { + u32 BaseAddresses[PCI_TYPE1_ADDRESSES]; + u8 PrimaryBusNumber; + u8 SecondaryBusNumber; + u8 SubordinateBusNumber; + u8 SecondaryLatencyTimer; + u8 IOBase; + u8 IOLimit; + u16 SecondaryStatus; + u16 MemoryBase; + u16 MemoryLimit; + u16 PrefetchableMemoryBase; + u16 PrefetchableMemoryLimit; + u32 PrefetchableMemoryBaseUpper32; + u32 PrefetchableMemoryLimitUpper32; + u16 IOBaseUpper; + u16 IOLimitUpper; + u32 Reserved2; + u32 ExpansionROMBase; + u8 InterruptLine; + u8 InterruptPin; + u16 BridgeControl; + } type1; + + struct _PCI_HEADER_TYPE_2 { + u32 BaseAddress; + u8 CapabilitiesPtr; + u8 Reserved2; + u16 SecondaryStatus; + u8 PrimaryBusNumber; + u8 CardbusBusNumber; + u8 SubordinateBusNumber; + u8 CardbusLatencyTimer; + u32 MemoryBase0; + u32 MemoryLimit0; + u32 MemoryBase1; + u32 MemoryLimit1; + u16 IOBase0_LO; + u16 IOBase0_HI; + u16 IOLimit0_LO; + u16 IOLimit0_HI; + u16 IOBase1_LO; + u16 IOBase1_HI; + u16 IOLimit1_LO; + u16 IOLimit1_HI; + u8 InterruptLine; + u8 InterruptPin; + u16 BridgeControl; + u16 SubVendorID; + u16 SubSystemID; + u32 LegacyBaseAddress; + u8 Reserved3[56]; + u32 SystemControl; + u8 MultiMediaControl; + u8 GeneralStatus; + u8 Reserved4[2]; + u8 GPIO0Control; + u8 GPIO1Control; + u8 GPIO2Control; + u8 GPIO3Control; + u32 IRQMuxRouting; + u8 RetryStatus; + u8 CardControl; + u8 DeviceControl; + u8 Diagnostic; + } type2; +#endif + } u; + + u8 DeviceSpecific[108]; +} PCI_COMMON_CONFIG , *PPCI_COMMON_CONFIG; + +typedef struct _RT_PCI_CAPABILITIES_HEADER { + u8 CapabilityID; + u8 Next; +} RT_PCI_CAPABILITIES_HEADER, *PRT_PCI_CAPABILITIES_HEADER; + +struct pci_priv{ + BOOLEAN pci_clk_req; + + u8 pciehdr_offset; + // PCIeCap is only differece between B-cut and C-cut. + // Configuration Space offset 72[7:4] + // 0: A/B cut + // 1: C cut and later. + u8 pcie_cap; + u8 linkctrl_reg; + + u8 busnumber; + u8 devnumber; + u8 funcnumber; + + u8 pcibridge_busnum; + u8 pcibridge_devnum; + u8 pcibridge_funcnum; + u8 pcibridge_vendor; + u16 pcibridge_vendorid; + u16 pcibridge_deviceid; + u8 pcibridge_pciehdr_offset; + u8 pcibridge_linkctrlreg; + + u8 amd_l1_patch; +}; + +typedef struct _RT_ISR_CONTENT +{ + union{ + u32 IntArray[2]; + u32 IntReg4Byte; + u16 IntReg2Byte; + }; +}RT_ISR_CONTENT, *PRT_ISR_CONTENT; + +//#define RegAddr(addr) (addr + 0xB2000000UL) +//some platform macros will def here +static inline void NdisRawWritePortUlong(u32 port, u32 val) +{ + outl(val, port); + //writel(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawWritePortUchar(u32 port, u8 val) +{ + outb(val, port); + //writeb(val, (u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUchar(u32 port, u8 *pval) +{ + *pval = inb(port); + //*pval = readb((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUshort(u32 port, u16 *pval) +{ + *pval = inw(port); + //*pval = readw((u8 *)RegAddr(port)); +} + +static inline void NdisRawReadPortUlong(u32 port, u32 *pval) +{ + *pval = inl(port); + //*pval = readl((u8 *)RegAddr(port)); +} +#elif defined(CONFIG_LX_HCI) +#define GSPI_CMD_LEN 0 +#define GSPI_STATUS_LEN 0 +#include "lxbus/lxbus_spec.h" +#endif // interface define + +#if 0 //TODO +struct intf_priv { + + u8 *intf_dev; + u32 max_iosz; //USB2.0: 128, USB1.1: 64, SDIO:64 + u32 max_xmitsz; //USB2.0: unlimited, SDIO:512 + u32 max_recvsz; //USB2.0: unlimited, SDIO:512 + + volatile u8 *io_rwmem; + volatile u8 *allocated_io_rwmem; + u32 io_wsz; //unit: 4bytes + u32 io_rsz;//unit: 4bytes + u8 intf_status; + + void (*_bus_io)(u8 *priv); + +/* +Under Sync. IRP (SDIO/USB) +A protection mechanism is necessary for the io_rwmem(read/write protocol) + +Under Async. IRP (SDIO/USB) +The protection mechanism is through the pending queue. +*/ + + _mutex ioctl_mutex; + + +#ifdef PLATFORM_LINUX + #ifdef CONFIG_USB_HCI + // when in USB, IO is through interrupt in/out endpoints + struct usb_device *udev; + PURB piorw_urb; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + _timer io_timer; + u8 bio_irp_timeout; + u8 bio_timer_cancel; + #endif +#endif + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + // below is for io_rwmem... + PMDL pmdl; + PSDBUS_REQUEST_PACKET sdrp; + PSDBUS_REQUEST_PACKET recv_sdrp; + PSDBUS_REQUEST_PACKET xmit_sdrp; + + PIRP piorw_irp; + + #endif + #ifdef CONFIG_USB_HCI + PURB piorw_urb; + PIRP piorw_irp; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + #endif +#endif + +}; +#endif +#endif //__HCI_SPEC_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/lxbus/lxbus_spec.h b/USDK/component/common/drivers/wlan/realtek/src/hci/lxbus/lxbus_spec.h new file mode 100644 index 0000000..e12b099 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/lxbus/lxbus_spec.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __LXBUS_SPEC_H__ +#define __LXBUS_SPEC_H__ + +#include +//#include + + +#define HAL_INTERFACE_CMD_LEN 0 +#define HAL_INTERFACE_CMD_STATUS_LEN 0 +#define HAL_INTERFACE_OVERHEAD (HAL_INTERFACE_CMD_LEN+HAL_INTERFACE_CMD_STATUS_LEN) + +/* + * The following data structure is used for 8195a debug, and should not + * declared this parameter in release version to save sram usage + * It is used for debugging tx/rx and r/w pointer + */ +struct hal_debug +{ + unsigned int int_count; + unsigned int crc_err; + u16 last_write_be; + u16 last_write_mgt; + u16 last_closed_be; + u16 last_closed_mgt; + +}; + + +// The following section should be removed? +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define SDIO_MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ + +#endif //__LXBUS_SPEC_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_drvio.c b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_drvio.c new file mode 100644 index 0000000..2909340 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_drvio.c @@ -0,0 +1,818 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ +#define _GSPI_IO_C_ + +#include + +#ifdef CONFIG_SDIO_HCI +#include "wifi_io.h" //from sdio_host driver +//#include +//#include +//#define SDIO_CMD52_IO + +//SDIO host local register space mapping. +#define SDIO_LOCAL_MSK 0x0FFF +#define WLAN_IOREG_MSK 0x7FFF +#define WLAN_FIFO_MSK 0x1FFF // Aggregation Length[12:0] +#define WLAN_RX0FF_MSK 0x0003 + +#define SDIO_WITHOUT_REF_DEVICE_ID 0 // Without reference to the SDIO Device ID +#define SDIO_LOCAL_DEVICE_ID 0 // 0b[16], 000b[15:13] +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13] +#define WLAN_IOREG_DEVICE_ID 8 // 1b[16] + +// +// Description: +// Query SDIO Local register to query current the number of Free TxPacketBuffer page. +// +// Assumption: +// 1. Running at PASSIVE_LEVEL +// 2. RT_TX_SPINLOCK is NOT acquired. +// +// Created by Roger, 2011.01.28. +// +#ifdef CONFIG_RTL8188F +u8 spi_query_status_info(struct dvobj_priv *pdvobj) +{ + + ADAPTER *padapter = pdvobj->if1; + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG); + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+2); + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+4); + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] = rtw_read8(padapter, LOCAL_REG_FREE_TXPG+6); + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n", + __FUNCTION__, + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); + //_exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); + + return _TRUE; +} +#else +u8 spi_query_status_info(struct dvobj_priv *pdvobj) +{ + u32 NumOfFreePage; + ADAPTER *padapter = pdvobj->if1; + + NumOfFreePage = rtw_read32(padapter, LOCAL_REG_FREE_TXPG); + +// _enter_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql); + rtw_memcpy(pdvobj->SdioTxFIFOFreePage, &NumOfFreePage, 4); + + RT_TRACE(_module_hci_ops_c_, _drv_notice_, + ("%s: Free page for HIQ(%x),MIDQ(%x),LOWQ(%x),PUBQ(%x)\n", + __FUNCTION__, + pdvobj->SdioTxFIFOFreePage[HI_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[MID_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + pdvobj->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); +// _exit_critical_bh(&pdvobj->SdioTxFIFOFreePageLock, &irql); + + return _TRUE; +} +#endif +static unsigned char get_deviceid(unsigned int addr) +{ + unsigned char devideId; + unsigned short pseudoId; + + + pseudoId = (unsigned short)(addr >> 16); + switch (pseudoId) + { + case 0x1025: + devideId = SDIO_LOCAL_DEVICE_ID; + break; + + case 0x1026: + devideId = WLAN_IOREG_DEVICE_ID; + break; + +// case 0x1027: +// devideId = SDIO_FIRMWARE_FIFO; +// break; + + case 0x1031: + devideId = WLAN_TX_HIQ_DEVICE_ID; + break; + + case 0x1032: + devideId = WLAN_TX_MIQ_DEVICE_ID; + break; + + case 0x1033: + devideId = WLAN_TX_LOQ_DEVICE_ID; + break; + + case 0x1034: + devideId = WLAN_RX0FF_DEVICE_ID; + break; + + default: +// devideId = (u8)((addr >> 13) & 0xF); + devideId = WLAN_IOREG_DEVICE_ID; + break; + } + + return devideId; +} + +static unsigned int _cvrt2ftaddr(const unsigned int addr, unsigned char *pdeviceId, unsigned short *poffset) +{ + unsigned char deviceId; + unsigned short offset; + unsigned int ftaddr; + + + deviceId = get_deviceid(addr); + offset = 0; + + switch (deviceId) + { + case SDIO_LOCAL_DEVICE_ID: + offset = addr & SDIO_LOCAL_MSK; + break; + + case WLAN_TX_HIQ_DEVICE_ID: + case WLAN_TX_MIQ_DEVICE_ID: + case WLAN_TX_LOQ_DEVICE_ID: + offset = addr & WLAN_FIFO_MSK; + break; + + case WLAN_RX0FF_DEVICE_ID: + offset = addr & WLAN_RX0FF_MSK; + break; + + case WLAN_IOREG_DEVICE_ID: + default: + deviceId = WLAN_IOREG_DEVICE_ID; + offset = addr & WLAN_IOREG_MSK; + break; + } + ftaddr = (deviceId << 13) | offset; + + if (pdeviceId) *pdeviceId = deviceId; + if (poffset) *poffset = offset; + + return ftaddr; +} + +unsigned char sdio_read8(ADAPTER *Adapter, unsigned int addr, int *err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned char val; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + val = rtw_sdio_bus_ops.readb(psdiodev->intf_data.func, ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; + +} + +unsigned short sdio_read16(ADAPTER *Adapter, unsigned int addr, int *err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned short val; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + + if (addr & 1) + DBG_871X( "sdio_read16 addr is wrong addr:0x%08x\n", addr); + + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + val = rtw_sdio_bus_ops.readw(psdiodev->intf_data.func, ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; +} + +unsigned int sdio_read32(ADAPTER *Adapter, unsigned int addr, int *err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned int val; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + + if (addr & 3) + DBG_871X( "sdio_read32 addr is wrong addr:0x%08x\n", addr); + + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + val = rtw_sdio_bus_ops.readl(psdiodev->intf_data.func, ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; + +} + + +unsigned int sdio_write8(ADAPTER *Adapter, unsigned int addr, unsigned int buf, int*err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned int val = 0; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + rtw_sdio_bus_ops.writeb(psdiodev->intf_data.func, buf&0xFF,ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; +} + +unsigned int sdio_write16(ADAPTER *Adapter, unsigned int addr,unsigned int buf, int *err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned int val = 0; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + + if (addr & 1) + DBG_871X( "sdio_write16 addr is wrong addr:0x%08x\n", addr); + + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + rtw_sdio_bus_ops.writew(psdiodev->intf_data.func, buf&0xFFFF,ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; +} + +unsigned int sdio_write32(ADAPTER *Adapter, unsigned int addr, unsigned int buf, int *err) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned int val = 0; + +_func_enter_; + + psdiodev = adapter_to_dvobj(Adapter); + + if (addr & 3) + DBG_871X( "sdio_write32 addr is wrong addr:0x%08x\n", addr); + + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + rtw_sdio_bus_ops.writel(psdiodev->intf_data.func, buf&0xFFFFFFFF,ftaddr, err); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if(err && *err) + DBG_871X( "%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr); + +_func_exit_; + + return val; +} + +unsigned int _fifoqueue2ftaddr(unsigned int fifo, unsigned int addr) +{ + unsigned int cmdaddr = TX_HIQ_DOMAIN; + + switch(fifo) { + case TX_LOQ_DOMAIN: + cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); + break; + case TX_HIQ_DOMAIN: + cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); + break; + case TX_MIQ_DOMAIN: + cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); + break; + case RX_RXFIFO_DOMAIN: + cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK)); + break; + default: + cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); + break; + + } + return cmdaddr; +} + +void sdio_write_tx_fifo(ADAPTER *Adapter, unsigned char *buf, int reallen, unsigned int fifo) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned char *mem = buf; + int free_mem = 0; + int status; + unsigned int cnt = (unsigned int)reallen; + unsigned int page_num = 0; + unsigned int wait_num = 100; + unsigned int use_page = 0; + +_func_enter_; + use_page = (cnt + TX_FIFO_PAGE_SZ - 1) / TX_FIFO_PAGE_SZ; + + if (cnt > 512) + cnt = _RND(cnt, 512); + else + cnt = _RND(cnt, 4); + + if (((u32)buf) % 4) { + mem = rtw_zmalloc(cnt); + while(!mem) { + DBG_871X("rtw_zmalloc fail, cannot write tx fifo now\n"); + rtw_yield_os(); + mem = rtw_zmalloc(cnt); + } + + free_mem = 1; + //DBG_871X("sdio_write_tx_fifo tem_buf:%p ", mem); + rtw_memcpy(mem, buf, reallen); + + } else { + mem = buf; + } + + if (((u32)mem) % 4) { + DBG_871X("sdio_write_tx_fifo: Oops mem %p not 4 byte Alignment this will cause DMA wrong \n", mem); + } + + psdiodev = adapter_to_dvobj(Adapter); + + + if (fifo == TX_HIQ_DOMAIN) + page_num = psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX]; + else if (fifo == TX_LOQ_DOMAIN) + page_num = psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX]; + else + page_num = psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX]; + + if (page_num + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < use_page) { + spi_query_status_info(Adapter->dvobj); + } + + while (page_num + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] < use_page) { + DBG_871X("Oops: spi_write_tx_fifo(): page_num is %d, padapter->pub_page is %d, wait_num is %d", + page_num, psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX], wait_num); + + rtw_msleep_os(1); + //rtw_udelay_os(20); + spi_query_status_info(Adapter->dvobj); + + if (fifo == TX_HIQ_DOMAIN) + page_num = psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX]; + else if (fifo == TX_LOQ_DOMAIN) + page_num = psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX]; + else + page_num = psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX]; + + if (wait_num <= 2) { + DBG_871X("%s(): wait_num is <= 2 drop", __FUNCTION__); + return; + } + wait_num --; + } + + if (fifo == TX_HIQ_DOMAIN) { + if (use_page <= page_num) { + psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX] -= page_num; + } else { + psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX] = 0; + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[HI_QUEUE_IDX]; + } + } else if (fifo == TX_LOQ_DOMAIN) { + if (use_page <= page_num) { + psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX] -= page_num; + } else { + psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX] = 0; + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[LOW_QUEUE_IDX]; + } + } else { + if (use_page <= page_num) { + psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX] -= page_num; + } else { + psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX] = 0; + psdiodev->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX] -= use_page - psdiodev->SdioTxFIFOFreePage[MID_QUEUE_IDX]; + } + } + + //must reallen here or tx will wrong when RND(512) + ftaddr = _fifoqueue2ftaddr(fifo, reallen >> 2); + + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + status = rtw_sdio_bus_ops.memcpy_toio(psdiodev->intf_data.func, ftaddr, mem, cnt); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if (free_mem) { + rtw_mfree(mem, cnt); + } + + if (status) { + DBG_871X("sdio_write_tx_fifo:status:%x ftaddr:%x Length:%d fifo:%x ", status, ftaddr, cnt, fifo); + } + +_func_exit_; + + return; +} + +void sdio_read_rx_fifo(ADAPTER *Adapter, unsigned char *buf, int reallen) +{ + struct dvobj_priv *psdiodev; + unsigned int ftaddr; + unsigned char *mem = buf; + int free_mem = 0; + int status; + unsigned int cnt = (unsigned int)reallen; + static unsigned int sdio_rxfifo_cnt = 0; + unsigned int fifo = RX_RXFIFO_DOMAIN; + +_func_enter_; + + if (cnt > 512) + cnt = _RND(cnt, 512); + else + cnt = _RND(cnt, 4); + + mem = rtw_zmalloc(cnt); + if (mem) { + free_mem = 1; + //DBG_871X("sdio_read_rx_fifo tem_buf:%p ", mem); + } else { + //DBG_871X("sdio_read_rx_fifo tem_buf:Oops %p ", mem); + mem = buf; + } + + if (mem == NULL) { + DBG_871X("sdio_read_rx_fifo: Oops mem is NULL \n"); + return; + } + + if (((u32)mem) % 4) { + DBG_871X("sdio_read_rx_fifo: Oops mem %p not 4 byte Alignment this will cause DMA wrong \n", mem); + } + + psdiodev = adapter_to_dvobj(Adapter); + + ftaddr = _fifoqueue2ftaddr(fifo, sdio_rxfifo_cnt++); + + rtw_sdio_bus_ops.claim_host(psdiodev->intf_data.func); + status = rtw_sdio_bus_ops.memcpy_fromio(psdiodev->intf_data.func, mem, ftaddr, cnt); + rtw_sdio_bus_ops.release_host(psdiodev->intf_data.func); + + if (free_mem) { + if (buf) + rtw_memcpy(buf, mem, reallen); + rtw_mfree(mem, cnt); + } + + if (status) { + //error + DBG_871X("rtw_sdio_read_rx_fifo error 0x%x\n" + "***** Addr = %x *****\n" + "***** Length = %d *****\n", status, ftaddr, cnt); + } + + +_func_exit_; + + return; +} + + +void sdio_cmd52_read(ADAPTER *Adapter, u32 addr, u32 cnt, u8 *pdata, int *err) +{ + int i = 0; + + for (i = 0; i < cnt; i++) { + pdata[i] = sdio_read8(Adapter, addr + i, err); + if (err && *err) + break; + } +} + +void sdio_cmd52_write(ADAPTER *Adapter, u32 addr, u32 cnt, u8 *pdata, int *err) +{ + int i = 0; + + for (i = 0; i < cnt; i++) { + sdio_write8(Adapter, addr + i, pdata[i], err); + if (err && *err) + break; + } +} + +u8 _sdio_read8(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u8 val; + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + + val = sdio_read8(Adapter, addr, err); + +_func_exit_; + + return val; +} + +u16 _sdio_read16(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u8 bMacPwrCtrlOn = _FALSE; + u16 val; + u8 cmd52_io = 0; + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + /* we should use CMD 52 before bMacPwrCtrlOn */ + rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + cmd52_io = !bMacPwrCtrlOn; +#ifdef SDIO_CMD52_IO + cmd52_io = 1; +#endif + if (cmd52_io) { + sdio_cmd52_read(Adapter, addr, 2, (u8*)&val, err); + val = le16_to_cpu(val); + return val; + } + + val = sdio_read16(Adapter, addr, err); + +_func_exit_; + + return val; +} + +u32 _sdio_read32(struct dvobj_priv *pdvobj, u32 addr, s32 *err) +{ + u8 bMacPwrCtrlOn = _FALSE; + u32 val; + u8 cmd52_io = 0; + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + + /* we should use CMD 52 before bMacPwrCtrlOn */ + rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + cmd52_io = !bMacPwrCtrlOn; +#ifdef SDIO_CMD52_IO + cmd52_io = 1; +#endif + if (cmd52_io) { + sdio_cmd52_read(Adapter, addr, 4, (u8*)&val, err); + val = le32_to_cpu(val); + return val; + } + + val = sdio_read32(Adapter, addr, err); + +_func_exit_; + + return val; +} + +s32 _sdio_write8(struct dvobj_priv *pdvobj, u32 addr, u8 val, s32 *err) +{ + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + + sdio_write8(Adapter, addr, (u32)val, err); + +_func_exit_; + + return _SUCCESS; +} + +s32 _sdio_write16(struct dvobj_priv *pdvobj, u32 addr, u16 val, s32 *err) +{ + u8 bMacPwrCtrlOn = _FALSE; + u8 cmd52_io = 0; + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + /* we should use CMD 52 before bMacPwrCtrlOn */ + rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + cmd52_io = !bMacPwrCtrlOn; +#ifdef SDIO_CMD52_IO + cmd52_io = 1; +#endif + if (cmd52_io) { + val = cpu_to_le16(val); + sdio_cmd52_write(Adapter, addr, 2, (u8*)&val, err); + return _SUCCESS; + } + + sdio_write16(Adapter, addr, (u32)val, err); + +_func_exit_; + + return _SUCCESS; +} + +s32 _sdio_write32(struct dvobj_priv *pdvobj, u32 addr, u32 val, s32 *err) +{ + u8 bMacPwrCtrlOn = _FALSE; + u8 cmd52_io = 0; + ADAPTER *Adapter = pdvobj->if1; + +_func_enter_; + /* we should use CMD 52 before bMacPwrCtrlOn */ + rtw_hal_get_hwreg(Adapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + cmd52_io = !bMacPwrCtrlOn; +#ifdef SDIO_CMD52_IO + cmd52_io = 1; +#endif + if (cmd52_io) { + val = cpu_to_le32(val); + sdio_cmd52_write(Adapter, addr, 4, (u8*)&val, err); + return _SUCCESS; + } + + sdio_write32(Adapter, addr, val, err); + +_func_exit_; + + return _SUCCESS; +} + +/* + * Description: + * Read from RX FIFO + * Round read size to block size, + * and make sure data transfer will be done in one command. + * + * Parameters: + * pintfhdl a pointer of intf_hdl + * addr port ID + * cnt size to read + * rmem address to put data + * + * Return: + * _SUCCESS(1) Success + * _FAIL(0) Fail + */ +static int _sdio_read_rx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *mem, u32 cnt, struct fifo_more_data *pmore_data) +{ + ADAPTER *Adapter = pdvobj->if1; + + //struct spi_more_data more_data = {0}; + + //DBG_8192C("%s \n", __func__); + rtw_memset(pmore_data, 0, sizeof(struct fifo_more_data)); + + sdio_read_rx_fifo(Adapter, mem, cnt); + + return _SUCCESS; +} + +/* + * Description: + * Translate sdio fifo address to Domain ID in each WLAN FIFO + */ +static u32 hwaddr2txfifo(u32 addr) +{ + u32 fifo_domain_id; + switch (addr) + { + case WLAN_TX_HIQ_DEVICE_ID: + fifo_domain_id = TX_HIQ_DOMAIN; + break; + + case WLAN_TX_MIQ_DEVICE_ID: + fifo_domain_id = TX_MIQ_DOMAIN; + break; + + case WLAN_TX_LOQ_DEVICE_ID: + fifo_domain_id = TX_LOQ_DOMAIN; + break; + default: + fifo_domain_id = TX_LOQ_DOMAIN; + break; + } + + return fifo_domain_id; +} + + +static int _sdio_write_tx_fifo(struct dvobj_priv *pdvobj, u32 addr, u8 *mem, u32 cnt) +{ + u8 remain_len = 0; + u32 w_sz = cnt; + ADAPTER *Adapter = pdvobj->if1; + + remain_len = w_sz%4; + if (remain_len != 0) + w_sz += 4 -remain_len; + +#if 0//ndef LZM_TEST + if (1) { + int i = 0; + for(i = 0; i < w_sz; i += 4) { + DBG_871X("_sdio_write_port[%d]: 0x%08x ", i, *(u32*)(mem + i)); + } + } +#endif + +#if 0 + { + static u32 write_test = 0; + u32 now_time = 0; + write_test++; + if(write_test==1000) { + now_time = xTaskGetTickCount() * portTICK_RATE_MS; + DBG_8192C("%s fifo:%d cnt:%d w_sz:%d mem:%p, now time:%d\n", __func__, addr, cnt, w_sz, mem, now_time); + write_test = 0; + } + } +#endif + sdio_write_tx_fifo(Adapter, mem, w_sz, hwaddr2txfifo(addr)); + + return _SUCCESS; +} + +static int sdio_io_priv(struct dvobj_priv *pdvobj) +{ + ADAPTER *Adapter = pdvobj->if1; + //struct dvobj_priv *pdvobj = &Adapter->dvobjpriv; + + return _SUCCESS; +} + +void sdio_set_intf_ops(struct _io_ops *pops) +{ + pops->init_io_priv = &sdio_io_priv; + pops->write8_endian = NULL; + + pops->_read8 = &_sdio_read8; + pops->_read16 = &_sdio_read16; + pops->_read32 = &_sdio_read32; + + pops->_write8 = &_sdio_write8; + pops->_write16 = &_sdio_write16; + pops->_write32 = &_sdio_write32; + + pops->read_rx_fifo = &_sdio_read_rx_fifo; + pops->write_tx_fifo = &_sdio_write_tx_fifo; +} + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_intf.c b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_intf.c new file mode 100644 index 0000000..3a83d9b --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_intf.c @@ -0,0 +1,264 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#define _GSPI_INTF_C_ + +#include + +#ifdef CONFIG_SDIO_HCI +#include "wifi_io.h" //from sdio_driver + +#ifndef CONFIG_SDIO_HCI +#error "CONFIG_SDIO_HCI should be on!\n" +#endif + +struct dvobj_priv *gspi_dvobj_init(void) +{ +// int status = _FAIL; + struct dvobj_priv *dvobj = NULL; + PGSPI_DATA pgspi_data; + +_func_enter_; + + dvobj = (struct dvobj_priv*)rtw_zmalloc(sizeof(*dvobj)); + if (NULL == dvobj) { + goto exit; + } + + pgspi_data = &dvobj->intf_data; + + rtw_mutex_init(&pgspi_data->spi_mutex); + //pgspi_data->block_transfer_len = 512; //512 blocks r/w is not required for GSPI interface + //pgspi_data->tx_block_mode = 0; + //pgspi_data->rx_block_mode = 0; + +// status = _SUCCESS; + + if(wifi_sdio_func) { + DBG_871X("[gspi_dvobj_init] get wifi_func:%p\n", wifi_sdio_func); + dvobj->intf_data.func = wifi_sdio_func; + } else { + DBG_871X("[gspi_dvobj_init] Oops: get wifi sdio function fail"); + } + +exit: +_func_exit_; + + return dvobj; +} + +void gspi_dvobj_deinit(struct dvobj_priv *dvobj) +{ +//TODO +// struct dvobj_priv *dvobj = spi_get_drvdata(spi); + +_func_enter_; +//TODO +// spi_set_drvdata(spi, NULL); + if (dvobj) { +//TODO +// gspi_deinit(dvobj); + rtw_mutex_free(&dvobj->intf_data.spi_mutex); + rtw_mfree((u8*)dvobj, sizeof(*dvobj)); + } + +_func_exit_; +} + +void sdio_dvobj_interrupt_entry(struct sdio_func *func) +{ + //DBG_871X("[sdio_wifi_interrupt_entry] func :%p\n", func); + + //sdio irq have claim host, we should release it + //and claim it after SDIO IO, or SDIO IO will deadlock + rtw_sdio_bus_ops.release_host(func); + rtw_hci_interrupt_handler(func->drv_priv); + rtw_sdio_bus_ops.claim_host(func); +} + +void sdio_dvobj_request_irq(struct dvobj_priv *dvobj) +{ +_func_enter_; + if(dvobj->intf_data.func) { + dvobj->intf_data.func->drv_priv = (void*)dvobj->if1; + + rtw_sdio_bus_ops.claim_host(dvobj->intf_data.func); + rtw_sdio_bus_ops.claim_irq(dvobj->intf_data.func, sdio_dvobj_interrupt_entry); + rtw_sdio_bus_ops.release_host(dvobj->intf_data.func); + } + +_func_exit_; +} + +void sdio_dvobj_free_irq(struct dvobj_priv *dvobj) +{ +_func_enter_; + if(dvobj->intf_data.func) { + dvobj->intf_data.func->drv_priv = (void*)dvobj->if1; + + rtw_sdio_bus_ops.claim_host(dvobj->intf_data.func); + rtw_sdio_bus_ops.release_irq(dvobj->intf_data.func); + rtw_sdio_bus_ops.release_host(dvobj->intf_data.func); + } + +_func_exit_; +} + + +static inline u32 ffaddr2deviceId(struct dvobj_priv *pdvobj, u32 addr) +{ + return pdvobj->Queue2Pipe[addr]; +} + +static s32 rtw_xmit_xmitbuf(_adapter * padapter, struct xmit_buf *pxmitbuf) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u32 deviceId; + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("@@@rtw_xmit_xmitbuf(): pxmitbuf->len=%d\n", pxmitbuf->len)); + //translate queue index to Device Id + deviceId = ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr); + + rtw_write_port(padapter, deviceId, pxmitbuf->len, (u8*)pxmitbuf->pbuf); + + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); + return _SUCCESS; +} + +s32 sdio_dvobj_xmit_mgnt(_adapter * padapter, struct xmit_frame *pmgntframe) +{ + s32 ret = _SUCCESS; + struct pkt_attrib *pattrib; + struct xmit_buf *pxmitbuf; + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); + u8 *pframe = NULL; + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("+rtw_xmit_mgnt()\n")); + + pattrib = &pmgntframe->attrib; + pxmitbuf = pmgntframe->pxmitbuf; + pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; + + //rtw_hal_update_txdesc(padapter, pmgntframe, pmgntframe->buf_addr); + + pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz; + //pxmitbuf->pg_num = (pxmitbuf->len + 127)/128; // 128 is tx page size + //pxmitbuf->ptail = pmgntframe->buf_addr + pxmitbuf->len; + pxmitbuf->ff_hwaddr = rtw_get_ff_hwaddr(pmgntframe); + + rtw_count_tx_stats(padapter, pmgntframe, pattrib->last_txcmdsz); + + //RT_TRACE(_module_rtl871x_xmit_c_, _drv_always_, ("+rtw_xmit_mgnt(): type=%d\n", GetFrameSubType(pframe))); + if(GetFrameSubType(pframe)==WIFI_BEACON) //dump beacon directly + { +//When using dedicated xmit frame for issue bcn on ap mode +//free xmit frame for bcn reserved page on station mode - Alex Fang +#if USE_DEDICATED_BCN_TX + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) { + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + } + rtw_write_port(padapter, ffaddr2deviceId(pdvobjpriv, pxmitbuf->ff_hwaddr), pxmitbuf->len, pxmitbuf->pbuf); + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE) + rtw_free_xmitbuf(pxmitpriv, pxmitbuf); +#else + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + rtw_xmit_xmitbuf(padapter, pxmitbuf); +#endif + } + else + { + rtw_free_xmitframe(pxmitpriv, pmgntframe); + pxmitbuf->priv_data = NULL; + rtw_xmit_xmitbuf(padapter, pxmitbuf); + } + + if (ret != _SUCCESS) + rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN); + + RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("-rtw_xmit_mgnt\n")); + return ret; +} + +s32 sdio_dvobj_xmit_data(_adapter *padapter, struct xmit_frame *pxmitframe) +{ + struct xmit_priv *pxmitpriv = &padapter->xmitpriv; + _irqL irql; + s32 err; + +#ifdef CONFIG_80211N_HT + if ((pxmitframe->frame_tag == DATA_FRAMETAG) && + (pxmitframe->attrib.ether_type != 0x0806) && + (pxmitframe->attrib.ether_type != 0x888e) && + (pxmitframe->attrib.dhcp_pkt != 1)) + { + if (padapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE) + rtw_issue_addbareq_cmd(padapter, pxmitframe); + } +#endif + +#if USE_SKB_AS_XMITBUF + rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); +#endif + + rtw_enter_critical_bh(&pxmitpriv->lock, &irql); +#if 1 //FIX_XMITFRAME_FAULT, move from rtw_xmit(). +#ifdef CONFIG_AP_MODE + if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE) + { + rtw_exit_critical_bh(&pxmitpriv->lock, &irql); + return 1; + } +#endif +#endif + err = rtw_xmitframe_enqueue(padapter, pxmitframe); + rtw_exit_critical_bh(&pxmitpriv->lock, &irql); + + if (err != _SUCCESS) { + RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("rtw_xmit_data(): enqueue xmitframe fail\n")); + rtw_free_xmitframe(pxmitpriv, pxmitframe); + + // Trick, make the statistics correct + pxmitpriv->tx_pkts--; + pxmitpriv->tx_drop++; + return _TRUE; + } +#ifdef CONFIG_CONCURRENT_MODE + if (padapter->adapter_type > PRIMARY_ADAPTER){ + padapter = padapter->pbuddy_adapter; + } +#endif + + rtw_wakeup_task(&padapter->xmitThread); + + return _FALSE; +} + +const struct host_ctrl_intf_ops hci_ops = { + gspi_dvobj_init, + gspi_dvobj_deinit, + sdio_dvobj_request_irq, + sdio_dvobj_free_irq +}; +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_isr.c b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_isr.c new file mode 100644 index 0000000..870008f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_isr.c @@ -0,0 +1,223 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ +#define _GSPI_ISR_C_ + +#include + +#ifdef CONFIG_SDIO_HCI +extern struct recv_buf* rtw_recv_rxfifo(_adapter * padapter, u32 size, struct fifo_more_data* more_data); + +void spi_int_dpc(PADAPTER padapter, u32 sdio_hisr) +{ + struct dvobj_priv *pdvobj = padapter->dvobj; + +#ifdef CONFIG_LPS_LCLK + if (sdio_hisr & HCI_HISR_CPWM1) + { + struct reportpwrstate_parm report; + + report.state = rtw_read8(padapter, LOCAL_REG_HCPWM1); + cpwm_int_hdl(padapter, &report); + } +#endif + + if (sdio_hisr & HCI_HISR_TXERR) + { + u32 status; + + status = rtw_read32(padapter, REG_TXDMA_STATUS); + rtw_write32(padapter, REG_TXDMA_STATUS, status); + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, status)); + } + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN + + #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT + if (sdio_hisr & HCI_HISR_BCNERLY_INT) + #endif + #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR + if (sdio_hisr & (HCI_HISR_TXBCNOK|HCI_HISR_TXBCNERR)) + #endif + { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + #if 0 //for debug + if (sdio_hisr & SDIO_HISR_BCNERLY_INT) + DBG_8192C("%s: SDIO_HISR_BCNERLY_INT\n", __func__); + + if (sdio_hisr & SDIO_HISR_TXBCNOK) + DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); + + if (sdio_hisr & SDIO_HISR_TXBCNERR) { + u1Byte v422, v550, v419; + v422 = rtw_read8(padapter, 0x422); + v419 = rtw_read8(padapter, 0x419); + v550 = rtw_read8(padapter, 0x550); + + DBG_8192C("%s: SDIO_HISR_TXBCNERR 422=%02x, 419=%02x, 550=%02x\n", __func__, v422, v419, v550); + } + #endif + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) + { + //send_beacon(padapter); + if(pmlmepriv->update_bcn == _TRUE) + { + //tx_beacon_hdl(padapter, NULL); + set_tx_beacon_cmd(padapter); + } + } + +#ifdef CONFIG_CONCURRENT_MODE + if(check_buddy_fwstate(padapter, WIFI_AP_STATE)) + { + //send_beacon(padapter); + if(padapter->pbuddy_adapter->mlmepriv.update_bcn == _TRUE) + { + //tx_beacon_hdl(padapter, NULL); + set_tx_beacon_cmd(padapter->pbuddy_adapter); + } + } +#endif + } +#endif //CONFIG_INTERRUPT_BASED_TXBCN + + if (sdio_hisr & HCI_HISR_C2HCMD) + { + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: C2H Command\n", __func__)); +//TODO +// rtw_c2h_wk_cmd(padapter); + } + + if (sdio_hisr & HCI_HISR_RX_REQUEST)// || sdio_hisr & SPI_HISR_RXFOVW) + { + struct recv_buf *precvbuf; + struct fifo_more_data more_data = {0}; + + //RT_TRACE(_module_hci_ops_c_,_drv_info_, ("%s: RX Request, size=%d\n", __func__, pdvobj->SdioRxFIFOSize)); + + sdio_hisr ^= HCI_HISR_RX_REQUEST; + + do { + more_data.more_data = 0; + more_data.len = 0; + + if (pdvobj->SdioRxFIFOSize == 0) + { + u16 val = 0; + //s32 ret; //LZM_TODO + + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize)); + + val = rtw_read16(padapter, LOCAL_REG_RX0_REQ_LEN_1_BYTE); + //if (!ret) { + pdvobj->SdioRxFIFOSize = val; + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize again size=%d\n", __func__, pdvobj->SdioRxFIFOSize)); + //} else { + // RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s: RX_REQUEST, read RXFIFOsize ERROR!!\n", __func__)); + //} + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s, %d, read RXFIFOsize again size=%d\n", __FUNCTION__, __LINE__, pdvobj->SdioRxFIFOSize)); + } + + if (pdvobj->SdioRxFIFOSize != 0) + { +#ifdef RTL8723A_SDIO_LOOPBACK + sd_recv_loopback(padapter, pdvobj->SdioRxFIFOSize); +#else + if (sdio_hisr & HCI_HISR_RXFOVW) + RT_TRACE(_module_hci_ops_c_, _drv_info_, ("%s RXFOVW RX\n", __func__)); + + precvbuf = rtw_recv_rxfifo(padapter, pdvobj->SdioRxFIFOSize, &more_data); + if (precvbuf) + rtw_rxhandler(padapter, precvbuf); + + if (more_data.more_data) { + pdvobj->SdioRxFIFOSize = more_data.len; + } else { + pdvobj->SdioRxFIFOSize = 0; + } +#endif + //If Rx_request ISR is set, execute receive tasklet (sdio_hisr & SPI_HISR_RX_REQUEST) +#if defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) && defined(CONFIG_RECV_TASKLET_THREAD) + rtw_wakeup_task(&padapter->recvtasklet_thread); +#endif + } + +#ifdef CONFIG_INTERRUPT_BASED_TXBCN +{ + //Prevent BCN update not realtime in ap mode - Alex Fang + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + + if((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) && (pmlmepriv->update_bcn == _TRUE)) + break; +} +#endif + } while (more_data.more_data || pdvobj->SdioRxFIFOSize); +#ifdef PLATFORM_LINUX +#ifdef CONFIG_GSPI_HCI + tasklet_schedule(&padapter->recvpriv.recv_tasklet); +#endif +#endif + } +} + + +void spi_int_hdl(PADAPTER padapter) +{ + struct dvobj_priv *pdvobj = padapter->dvobj; + u32 sdio_hisr = 0; + //s32 ret; + + if ((padapter->bDriverStopped == _TRUE) || + (padapter->bSurpriseRemoved == _TRUE)) + return; + + sdio_hisr = rtw_read32(padapter, LOCAL_REG_HISR);//, &ret); + //if (!ret) { + // RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SDIO_REG_HISR FAIL!!\n", __func__)); + // return; + //} + pdvobj->SdioRxFIFOSize = rtw_read16(padapter, LOCAL_REG_RX0_REQ_LEN_1_BYTE);//, &ret); + + //if (!ret) { + // RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: read SPI_REG_RX0_REQ_LEN FAIL!!\n", __func__)); + // return; + //} + + if (sdio_hisr & pdvobj->sdio_himr) + { + u32 v32; + + sdio_hisr &= pdvobj->sdio_himr; + + // clear HISR + v32 = sdio_hisr & MASK_SPI_HISR_CLEAR; + if (v32) { + rtw_write32(padapter, LOCAL_REG_HISR, v32);//, &ret); + } + + spi_int_dpc(padapter, sdio_hisr); + } else { + //RT_TRACE(_module_hci_ops_c_, _drv_err_, + // ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n", + // __FUNCTION__, sdio_hisr, pdvobj->sdio_himr)); + } +} + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_spec.h b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_spec.h new file mode 100644 index 0000000..5b3b8d5 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/hci/sdio/sdio_spec.h @@ -0,0 +1,193 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ + +#ifndef __GSDIO_SPEC_H__ +#define __GSDIO_SPEC_H__ + + +#define SPI_LOCAL_DOMAIN 0x0 +#define WLAN_IOREG_DOMAIN 0x8 +#define FW_FIFO_DOMAIN 0x4 +#define TX_HIQ_DOMAIN 0xc +#define TX_MIQ_DOMAIN 0xd +#define TX_LOQ_DOMAIN 0xe +#define RX_RXFIFO_DOMAIN 0x1f + +//IO Bus domain address mapping +#define DEFUALT_OFFSET 0x0 +#define SPI_LOCAL_OFFSET 0x10250000 +#define WLAN_IOREG_OFFSET 0x10260000 +#define FW_FIFO_OFFSET 0x10270000 +#define TX_HIQ_OFFSET 0x10310000 +#define TX_MIQ_OFFSET 0x1032000 +#define TX_LOQ_OFFSET 0x10330000 +#define RX_RXOFF_OFFSET 0x10340000 + +#define WLAN_TX_HIQ_DEVICE_ID 4 // 0b[16], 100b[15:13] +#define WLAN_TX_MIQ_DEVICE_ID 5 // 0b[16], 101b[15:13] +#define WLAN_TX_LOQ_DEVICE_ID 6 // 0b[16], 110b[15:13] +#define WLAN_TX_EXQ_DEVICE_ID 3 // 0b[16], 011b[15:13] +#define WLAN_RX0FF_DEVICE_ID 7 // 0b[16], 111b[15:13] +#define WLAN_IOREG_DEVICE_ID 8 // 1b[16] + +//SPI Tx Free Page Index +#define HI_QUEUE_IDX 0 +#define MID_QUEUE_IDX 1 +#define LOW_QUEUE_IDX 2 +#define PUBLIC_QUEUE_IDX 3 + +#define MAX_TX_QUEUE 3 // HIQ, MIQ and LOQ +#define MAX_RX_QUEUE 1 + +//SPI Local registers +#define SPI_REG_TX_CTRL (SPI_LOCAL_OFFSET | 0x0000) // SPI Tx Control +#define SPI_REG_STATUS_RECOVERY (SPI_LOCAL_OFFSET | 0x0004) +#define SPI_REG_INT_TIMEOUT (SPI_LOCAL_OFFSET | 0x0006) +#define SPI_REG_HIMR (SPI_LOCAL_OFFSET | 0x0014) // SPI Host Interrupt Mask +#define SPI_REG_HISR (SPI_LOCAL_OFFSET | 0x0018) // SPI Host Interrupt Service Routine +#define SPI_REG_RX0_REQ_LEN (SPI_LOCAL_OFFSET | 0x001C) // RXDMA Request Length +#define SPI_REG_FREE_TXPG (SPI_LOCAL_OFFSET | 0x0020) // Free Tx Buffer Page +#define SPI_REG_HCPWM1 (SPI_LOCAL_OFFSET | 0x0024) // HCI Current Power Mode 1 +#define SPI_REG_HCPWM2 (SPI_LOCAL_OFFSET | 0x0026) // HCI Current Power Mode 2 +#define SPI_REG_HTSFR_INFO (SPI_LOCAL_OFFSET | 0x0030) // HTSF Informaion +#define SPI_REG_HRPWM1 (SPI_LOCAL_OFFSET | 0x0080) // HCI Request Power Mode 1 +#define SPI_REG_HRPWM2 (SPI_LOCAL_OFFSET | 0x0082) // HCI Request Power Mode 2 +#define SPI_REG_HPS_CLKR (SPI_LOCAL_OFFSET | 0x0084) // HCI Power Save Clock +#define SPI_REG_HSUS_CTRL (SPI_LOCAL_OFFSET | 0x0086) // SPI HCI Suspend Control +#define SPI_REG_HIMR_ON (SPI_LOCAL_OFFSET | 0x0090) //SPI Host Extension Interrupt Mask Always +#define SPI_REG_HISR_ON (SPI_LOCAL_OFFSET | 0x0091) //SPI Host Extension Interrupt Status Always +#define SPI_REG_CFG (SPI_LOCAL_OFFSET | 0x00F0) //SPI Configuration Register + +#define LOCAL_REG_TX_CTRL (SPI_REG_TX_CTRL |SPI_LOCAL_OFFSET) +#define LOCAL_REG_STATUS_RECOVERY (SPI_REG_STATUS_RECOVERY |SPI_LOCAL_OFFSET) +#define LOCAL_REG_INT_TIMEOUT (SPI_REG_INT_TIMEOUT |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HIMR (SPI_REG_HIMR |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HISR (SPI_REG_HISR |SPI_LOCAL_OFFSET) +#define LOCAL_REG_RX0_REQ_LEN_1_BYTE (SPI_REG_RX0_REQ_LEN |SPI_LOCAL_OFFSET) +#define LOCAL_REG_FREE_TXPG (SPI_REG_FREE_TXPG |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HRPWM1 (SPI_REG_HRPWM1 |SPI_LOCAL_OFFSET) +#define LOCAL_REG_HCPWM1 (SPI_REG_HCPWM1 |SPI_LOCAL_OFFSET) + +#define HCI_HIMR_DISABLED 0 + +//SPI HIMR MASK diff with SDIO +#define HCI_HISR_RX_REQUEST BIT(0) +#define HCI_HISR_AVAL BIT(1) +#define HCI_HISR_TXERR BIT(2) +#define HCI_HISR_RXERR BIT(3) +#define HCI_HISR_TXFOVW BIT(4) +#define HCI_HISR_RXFOVW BIT(5) +#define HCI_HISR_TXBCNOK BIT(6) +#define HCI_HISR_TXBCNERR BIT(7) +#define HCI_HISR_BCNERLY_INT BIT(16) +#define HCI_HISR_C2HCMD BIT(17) +#define HCI_HISR_CPWM1 BIT(18) +#define HCI_HISR_CPWM2 BIT(19) +#define HCI_HISR_HSISR_IND BIT(20) +#define HCI_HISR_GTINT3_IND BIT(21) +#define HCI_HISR_GTINT4_IND BIT(22) +#define HCI_HISR_PSTIMEOUT BIT(23) +#define HCI_HISR_OCPINT BIT(24) +#define HCI_HISR_ATIMEND BIT(25) +#define HCI_HISR_ATIMEND_E BIT(26) +#define HCI_HISR_CTWEND BIT(27) + +//SPI HIMR MASK diff with SDIO +#define HCI_HIMR_RX_REQUEST BIT(0) +#define HCI_HIMR_AVAL BIT(1) +#define HCI_HIMR_TXERR BIT(2) +#define HCI_HIMR_RXERR BIT(3) +#define HCI_HIMR_TXFOVW BIT(4) +#define HCI_HIMR_RXFOVW BIT(5) +#define HCI_HIMR_TXBCNOK BIT(6) +#define HCI_HIMR_TXBCNERR BIT(7) +#define HCI_HIMR_BCNERLY_INT BIT(16) +#define HCI_HIMR_ATIMEND BIT(17) +#define HCI_HIMR_ATIMEND_E BIT(18) +#define HCI_HIMR_CTWEND BIT(19) +#define HCI_HIMR_C2HCMD BIT(20) +#define HCI_HIMR_CPWM1 BIT(21) +#define HCI_HIMR_CPWM2 BIT(22) +#define HCI_HIMR_HSISR_IND BIT(23) +#define HCI_HIMR_GTINT3_IND BIT(24) +#define HCI_HIMR_GTINT4_IND BIT(25) +#define HCI_HIMR_PSTIMEOUT BIT(26) +#define HCI_HIMR_OCPINT BIT(27) +#define HCI_HIMR_TSF_BIT32_TOGGLE BIT(29) + +#define MASK_SPI_HISR_CLEAR (HCI_HIMR_TXERR |\ + HCI_HIMR_RXERR |\ + HCI_HIMR_TXFOVW |\ + HCI_HIMR_RXFOVW |\ + HCI_HIMR_TXBCNOK |\ + HCI_HIMR_TXBCNERR |\ + HCI_HIMR_C2HCMD |\ + HCI_HIMR_CPWM1 |\ + HCI_HIMR_CPWM2 |\ + HCI_HIMR_HSISR_IND |\ + HCI_HIMR_GTINT3_IND |\ + HCI_HIMR_GTINT4_IND |\ + HCI_HIMR_PSTIMEOUT |\ + HCI_HIMR_OCPINT) + +#define REG_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 8, x)//(x<<(unsigned int)24) +#define REG_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define REG_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define REG_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define REG_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + +#define FIFO_LEN_FORMAT(pcmd, x) SET_BITS_TO_LE_4BYTE(pcmd, 0, 16, x)//(x<<(unsigned int)24) +//#define FIFO_ADDR_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 8, 16, x)//(x<<(unsigned int)16) +#define FIFO_DOMAIN_ID_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 24, 5, x)//(x<<(unsigned int)0) +#define FIFO_FUN_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 29, 2, x)//(x<<(unsigned int)5) +#define FIFO_RW_FORMAT(pcmd,x) SET_BITS_TO_LE_4BYTE(pcmd, 31, 1, x)//(x<<(unsigned int)7) + + +//get status dword0 +#define GET_STATUS_PUB_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 24, 8) +#define GET_STATUS_HI_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 18, 6) +#define GET_STATUS_MID_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 12, 6) +#define GET_STATUS_LOW_PAGE_NUM(status) LE_BITS_TO_4BYTE(status, 6, 6) +#define GET_STATUS_HISR_HI6BIT(status) LE_BITS_TO_4BYTE(status, 0, 6) + +//get status dword1 +#define GET_STATUS_HISR_MID8BIT(status) LE_BITS_TO_4BYTE(status + 4, 24, 8) +#define GET_STATUS_HISR_LOW8BIT(status) LE_BITS_TO_4BYTE(status + 4, 16, 8) +#define GET_STATUS_ERROR(status) LE_BITS_TO_4BYTE(status + 4, 17, 1) +#define GET_STATUS_INT(status) LE_BITS_TO_4BYTE(status + 4, 16, 1) +#define GET_STATUS_RX_LENGTH(status) LE_BITS_TO_4BYTE(status + 4, 0, 16) + + +#define RXDESC_SIZE 24 + +#define TX_FREE_PG_QUEUE 4 // The number of Tx FIFO free page +#define TX_FIFO_PAGE_SZ 128 + +struct spi_more_data { + unsigned long more_data; + unsigned long len; +}; + +extern BUS_DRV_OPS_T bus_driver_ops; + +extern u8 spi_query_status_info(struct dvobj_priv *pdvobj); + +extern void sdio_set_intf_ops(struct _io_ops *pops); + +#endif //__GSPI_SPEC_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_intfs.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_intfs.h new file mode 100644 index 0000000..46b3453 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_intfs.h @@ -0,0 +1,161 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __FREERTOS_INTFS_H_ +#define __FREERTOS_INTFS_H_ + +//TODO +#if 0 + +struct intf_priv { + + u8 *intf_dev; + u32 max_iosz; //USB2.0: 128, USB1.1: 64, SDIO:64 + u32 max_xmitsz; //USB2.0: unlimited, SDIO:512 + u32 max_recvsz; //USB2.0: unlimited, SDIO:512 + + volatile u8 *io_rwmem; + volatile u8 *allocated_io_rwmem; + u32 io_wsz; //unit: 4bytes + u32 io_rsz;//unit: 4bytes + u8 intf_status; + + void (*_bus_io)(u8 *priv); + +/* +Under Sync. IRP (SDIO/USB) +A protection mechanism is necessary for the io_rwmem(read/write protocol) + +Under Async. IRP (SDIO/USB) +The protection mechanism is through the pending queue. +*/ + + _mutex ioctl_mutex; + + +#ifdef PLATFORM_LINUX + #ifdef CONFIG_USB_HCI + // when in USB, IO is through interrupt in/out endpoints + struct usb_device *udev; + PURB piorw_urb; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + _timer io_timer; + u8 bio_irp_timeout; + u8 bio_timer_cancel; + #endif +#endif + +#ifdef PLATFORM_OS_XP + #ifdef CONFIG_SDIO_HCI + // below is for io_rwmem... + PMDL pmdl; + PSDBUS_REQUEST_PACKET sdrp; + PSDBUS_REQUEST_PACKET recv_sdrp; + PSDBUS_REQUEST_PACKET xmit_sdrp; + + PIRP piorw_irp; + + #endif + #ifdef CONFIG_USB_HCI + PURB piorw_urb; + PIRP piorw_irp; + u8 io_irp_cnt; + u8 bio_irp_pending; + _sema io_retevt; + #endif +#endif + +}; + + +#ifdef CONFIG_R871X_TEST +int rtw_start_pseudo_adhoc(_adapter *padapter); +int rtw_stop_pseudo_adhoc(_adapter *padapter); +#endif + +#endif //#if 0 + +typedef struct _driver_priv { + int drv_registered; + + _mutex hw_init_mutex; +#if defined(CONFIG_CONCURRENT_MODE) || defined(CONFIG_DUALMAC_CONCURRENT) + //global variable + _mutex h2c_fwcmd_mutex; + _mutex setch_mutex; + _mutex setbw_mutex; +#endif +} drv_priv, *pdrv_priv; + + +struct net_device *rtw_init_netdev(_adapter *padapter); +void rtw_os_indicate_disconnect( _adapter *adapter ); + +#ifdef CONFIG_PROC_DEBUG +void rtw_proc_init_one(struct net_device *dev); +void rtw_proc_remove_one(struct net_device *dev); +#else +//static void should be declared in .c file +//proc is not supported in freertos +//static void rtw_proc_init_one(struct net_device *dev){} +//static void rtw_proc_remove_one(struct net_device *dev){} +#define rtw_proc_init_one(dev) +#define rtw_proc_remove_one(dev) +#endif + +extern int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen); +extern void rtw_os_indicate_connect(_adapter *adapter); +extern void indicate_wx_custom_event(_adapter *padapter, char *msg); +extern int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); +extern void netdev_lwip_post_sleep_processing(void); +extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra); + +#ifdef CONFIG_CONCURRENT_MODE +struct _io_ops; +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, char *name, void (*set_intf_ops)(struct _io_ops *pops)); +void rtw_drv_if2_free(_adapter *pbuddy_padapter); +#endif + +#if defined(CONFIG_ISR_THREAD_MODE_POLLING) || defined(CONFIG_ISR_THREAD_MODE_INTERRUPT) +extern thread_return rtw_interrupt_thread(thread_context context); +#endif + +#ifdef CONFIG_RECV_TASKLET_THREAD +extern thread_return rtw_recv_tasklet(thread_context context); +#endif + +#ifdef CONFIG_XMIT_TASKLET_THREAD +extern thread_return rtw_xmit_tasklet(thread_context context); +#endif + +extern struct net_device *rtw_drv_probe(struct net_device* parent_dev, u32 mode); //Wlan driver init entry +extern void rtw_drv_entry(void); +extern void rtw_drv_halt(void); +extern int rtw_dev_remove(struct net_device *pnetdev); +extern int rtw_ioctl(struct net_device *dev, struct iwreq *rq, int cmd); + +#if defined(CONFIG_LX_HCI) +u32 lextra_bus_dma_Interrupt (void* data); +#endif + +#endif //__FREERTOS_INTFS_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_recv.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_recv.h new file mode 100644 index 0000000..3cd391c --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_recv.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __FREERTOS_RECV_H_ +#define __FREERTOS_RECV_H_ + +extern sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +extern void _rtw_free_recv_priv (struct recv_priv *precvpriv); + + +extern s32 rtw_recv_entry(union recv_frame *precv_frame); +extern int rtw_recv_indicatepkt(_adapter *adapter, union recv_frame *precv_frame); +extern void rtw_recv_returnpacket(IN _nic_hdl cnxt, IN _pkt *preturnedpkt); + +extern void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame); +#if BAD_MIC_COUNTERMEASURE +extern void rtw_handle_tkip_mic_err(_adapter *padapter,u8 bgroup); +#endif + +int rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter); +void rtw_free_recv_priv (struct recv_priv *precvpriv); + + +int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter); +int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe); +void rtw_os_recv_resource_free(struct recv_priv *precvpriv); + + +int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf); +int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf); + +void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf); + +void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl); + +void rltk_netif_rx(struct sk_buff *skb); + +#endif //__FREERTOS_RECV_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_skbuff.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_skbuff.h new file mode 100644 index 0000000..1daf180 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_skbuff.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef _FREERTOS_SKBUFF_H_ +#define _FREERTOS_SKBUFF_H_ + +#if (RTL8195A_SUPPORT == 1) +// For Lextra(PCI-E like interface), RX buffer along with its skb is required to be +// pre-allocation and set into rx buffer descriptor ring during initialization. + #if (SKB_PRE_ALLOCATE_RX==1) + #define MAX_SKB_BUF_NUM (8 + 4) //tx+rx (8 + RX_Q_DESC_NUM) Reduce rx skb number due to memory limitation + #define MAX_LOCAL_SKB_NUM (10 + 18) //tx+rx + #else + #if WIFI_LOGO_CERTIFICATION + #define MAX_SKB_BUF_NUM 10 //tx+rx, ping 10k test + #elif defined(CONFIG_INIC_EN)&&(CONFIG_INIC_EN==1) //For iNIC throughput request + #define MAX_SKB_BUF_NUM 59 + #else + #define MAX_SKB_BUF_NUM 8 //tx+rx + #endif + #define MAX_LOCAL_SKB_NUM (MAX_SKB_BUF_NUM + 2) //tx+rx, +2: AP mode broadcast + #endif +#elif (RTL8711B_SUPPORT == 1) + #if (SKB_PRE_ALLOCATE_RX==1) + #define MAX_SKB_BUF_NUM (8 + 4) //tx+rx (8 + RX_Q_DESC_NUM) Reduce rx skb number due to memory limitation + #define MAX_LOCAL_SKB_NUM (10 + 18) //tx+rx + #else + #if WIFI_LOGO_CERTIFICATION + #define MAX_SKB_BUF_NUM 10 //tx+rx, ping 10k test + #elif defined(CONFIG_INIC_EN)&&(CONFIG_INIC_EN==1) //For iNIC throughput request + #define MAX_SKB_BUF_NUM 59 + #else + #define MAX_SKB_BUF_NUM 8 //tx+rx + #endif + #define MAX_LOCAL_SKB_NUM (MAX_SKB_BUF_NUM + 2) //tx+rx, +2: AP mode broadcast + #endif +#else +#ifndef CONFIG_DONT_CARE_TP +#ifndef CONFIG_HIGH_TP +#define MAX_LOCAL_SKB_NUM 10 +#define MAX_SKB_BUF_NUM 7 +#else +#define MAX_LOCAL_SKB_NUM 100 +#define MAX_SKB_BUF_NUM 100 +#endif +#else +#define MAX_LOCAL_SKB_NUM 10 +#define MAX_TX_SKB_BUF_NUM 6 +#define MAX_RX_SKB_BUF_NUM 1 +#endif +#endif + +extern int max_local_skb_num; +extern int max_skb_buf_num; + +#endif diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_xmit.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_xmit.h new file mode 100644 index 0000000..279c012 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/freertos_xmit.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __FREERTOS_XMIT_H_ +#define __FREERTOS_XMIT_H_ + +struct pkt_file { + _pkt *pkt; + SIZE_T pkt_len; //the remainder length of the open_file + _buffer *cur_buffer; + u8 *buf_start; + u8 *cur_addr; + SIZE_T buf_len; +}; + +//Decrease xmit frame due to memory limitation - Alex Fang +#if USE_XMIT_EXTBUFF +#define NR_XMITFRAME 16 //NR_XMITBUFF + NR_XMIT_EXTBUFF +#else +#ifndef CONFIG_HIGH_TP +//#define NR_XMITFRAME 8 +#define NR_XMITFRAME 6 //Decrease recv frame due to memory limitation - YangJue +#else +#define NR_XMITFRAME 100 +#endif +#endif + +extern int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev); +extern void rtw_os_xmit_schedule(_adapter *padapter); + +extern int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz); +extern void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz); + +extern void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib); + +extern uint rtw_remainder_len(struct pkt_file *pfile); +extern void _rtw_open_pktfile(_pkt *pkt, struct pkt_file *pfile); +extern uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen); +extern sint rtw_endofpktfile (struct pkt_file *pfile); + +extern void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt); +extern void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe); + + +#endif //__FREERTOS_XMIT_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/wrapper.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/wrapper.h new file mode 100644 index 0000000..52870d2 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/freertos/wrapper.h @@ -0,0 +1,460 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ****************************************************************************** + * Wrapper provide a linux-like interface + ************************************************************************/ +#ifndef __WRAPPER_H__ +#define __WRAPPER_H__ + + +//----- ------------------------------------------------------------------ +// Include Files +//----- ------------------------------------------------------------------ +#include +#include +#include "wireless.h" +#include +#ifdef PLATFORM_FREERTOS +#include "freertos_service.h" +#elif defined(PLATFORM_CMSIS_RTOS) +#include "rtx_service.h" +#endif +#ifndef __LIST_H +#warning "DLIST_NOT_DEFINE!!!!!!" +//----- ------------------------------------------------------------------ +// Linled List +//----- ------------------------------------------------------------------ +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ +// struct list_head { +// struct list_head *next, *prev; +// }; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline void __list_add(struct list_head * new, + struct list_head * prev, + struct list_head * next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline void __list_del(struct list_head * prev, + struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static __inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static __inline int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static __inline void list_splice(struct list_head *list, struct list_head *head) +{ + struct list_head *first = list->next; + + if (first != list) { + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; + } +} + +void list_add(struct list_head *new, struct list_head *head); +void list_add_tail(struct list_head *new, struct list_head *head); +#endif + +extern void save_and_cli(void); +extern void restore_flags(void); +//----- ------------------------------------------------------------------ +// SKB Operation +//----- ------------------------------------------------------------------ + +#define SMP_CACHE_BYTES 4 +#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & ~(SMP_CACHE_BYTES - 1)) + +// Consideration for SKB size +// Tx: [INTF_CMD][TX_DESC][WLAN_HDR][QoS][IV][SNAP][Data][MIC][ICV][INTF_STATUS] +// Since SKB is used to accept ethernet packet from upper layer, SKB length of WLAN_MAX_ETHFRM_LEN +// (= 1514) is enough. But since SKB is also used to get spi receive packet, overall buffer space +// should be taken into consideration. +// RX: [INTF_CMD][RX_DESC][Drv_Info][WLAN_HDR][QoS][IV][SNAP][Data][MIC][ICV][CRC][INTF_STATUS] +// +// 32: Driver_Info that carry phy related information for each packets. Required only for receive case. +// WLAN_MAX_ETHFRM_LEN : May not be required because WLAN_HEADER +SNAP can totally +// cover ethernet header. Keep in only for safety. +// +// **Notes** SDIO requires 512 blocks r/w, so 512*4 = 2048 is required. +// 2003/12/26. The value is reduced from 2048 to 1658 for GSPI +// 2014/02/05. The value is 1650 for 8195A LX_BUS +#define SKB_RESERVED_FOR_SAFETY 0 +#define SKB_WLAN_TX_EXTRA_LEN (TXDESC_SIZE + WLAN_HDR_A4_QOS_LEN + WLAN_MAX_IV_LEN + WLAN_SNAP_HEADER - WLAN_ETHHDR_LEN) +#define RX_DRIVER_INFO 32 + +#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) +#define HAL_INTERFACE_OVERHEAD_SKB_DATA 12 //HAL_INTERFACE_CMD (4) + HAL_INTERFACE_STATUS (8) +#elif defined(CONFIG_LX_HCI) +#define HAL_INTERFACE_OVERHEAD_SKB_DATA 0 +#endif + +#if defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI || defined(CONFIG_LX_HCI) + #if defined(CONFIG_RTL8195A) || defined(CONFIG_RTL8711B) + #if defined(CONFIG_MP_INCLUDED) + #ifdef CONFIG_DONT_CARE_TP + #define MAX_RX_PKT_LIMIT ((WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_RX_ETHFRM_LEN + 511) / 512) // 4, for lxbus + #else + #define MAX_RX_PKT_LIMIT ((WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_ETHFRM_LEN + 511) / 512) // 4, for lxbus + #endif + #define MAX_RX_PKT_SIZE MAX_RX_PKT_LIMIT*512 // MAX_SKB_BUF_SIZE = 0+32+40+512*4+0 = 2120 + #else + #ifdef CONFIG_DONT_CARE_TP + #define MAX_RX_PKT_SIZE WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_RX_ETHFRM_LEN + #else + #define MAX_RX_PKT_SIZE WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_ETHFRM_LEN // MAX_RX_PKT_SIZE = 64+1514 = 1578 + #endif + #define MAX_RX_PKT_LIMIT ((MAX_RX_PKT_SIZE + 511) / 512) // ((1578 + 512) / 512) = 4 + #endif + #else + #ifdef CONFIG_DONT_CARE_TP + #define MAX_RX_PKT_SIZE WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_RX_ETHFRM_LEN + #else + #define MAX_RX_PKT_SIZE WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_ETHFRM_LEN + #endif + #endif + + #ifdef CONFIG_DONT_CARE_TP + #define MAX_TX_SKB_BUF_SIZE (HAL_INTERFACE_OVERHEAD_SKB_DATA+RX_DRIVER_INFO+\ + ((TXDESC_SIZE>RXDESC_SIZE)? TXDESC_SIZE:RXDESC_SIZE) +\ + WLAN_MAX_PROTOCOL_OVERHEAD + WLAN_MAX_TX_ETHFRM_LEN +\ + SKB_RESERVED_FOR_SAFETY) + #define MAX_RX_SKB_BUF_SIZE (HAL_INTERFACE_OVERHEAD_SKB_DATA+RX_DRIVER_INFO+\ + ((TXDESC_SIZE>RXDESC_SIZE)? TXDESC_SIZE:RXDESC_SIZE) +\ + MAX_RX_PKT_SIZE +\ + SKB_RESERVED_FOR_SAFETY) + #else + #define MAX_SKB_BUF_SIZE (HAL_INTERFACE_OVERHEAD_SKB_DATA+RX_DRIVER_INFO+\ + ((TXDESC_SIZE>RXDESC_SIZE)? TXDESC_SIZE:RXDESC_SIZE) +\ + MAX_RX_PKT_SIZE +\ + SKB_RESERVED_FOR_SAFETY) // 0+32+40+1578+0 = 1650 + #endif +#else +#define MAX_SKB_BUF_SIZE 2048 +#endif + +#if 0 +struct sk_buff_head { + struct list_head *next, *prev; + u32 qlen; +}; + +struct sk_buff { + /* These two members must be first. */ + struct sk_buff *next; /* Next buffer in list */ + struct sk_buff *prev; /* Previous buffer in list */ + + struct sk_buff_head *list; /* List we are on */ + unsigned char *head; /* Head of buffer */ + unsigned char *data; /* Data head pointer */ + unsigned char *tail; /* Tail pointer */ + unsigned char *end; /* End pointer */ + struct net_device *dev; /* Device we arrived on/are leaving by */ + unsigned int len; /* Length of actual data */ +}; + +/** + * skb_put - add data to a buffer + * @skb: buffer to use + * @len: amount of data to add + * + * This function extends the used data area of the buffer. If this would + * exceed the total buffer size the kernel will panic. A pointer to the + * first byte of the extra data is returned. + */ + +static __inline__ unsigned char *skb_put(struct sk_buff *skb, unsigned int len) +{ + unsigned char *tmp=skb->tail; + skb->tail+=len; + skb->len+=len; + if(skb->tail>skb->end) { + ASSERT(0); + } + + return tmp; +} + +static __inline__ unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len) +{ + skb->len-=len; + skb->data = (unsigned char *)(((unsigned int)skb->data) + len); + + return skb->data; +} + +/** + * skb_reserve - adjust headroom + * @skb: buffer to alter + * @len: bytes to move + * + * Increase the headroom of an empty &sk_buff by reducing the tail + * room. This is only allowed for an empty buffer. + */ + +static __inline__ void skb_reserve(struct sk_buff *skb, unsigned int len) +{ + skb->data+=len; + skb->tail+=len; +} + +static __inline__ void skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = (struct list_head *)list; + list->next = (struct list_head *)list; + list->qlen = 0; +} + +/** + * __skb_queue_tail - queue a buffer at the list tail + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the end of a list. This function takes no locks + * and you must therefore hold required locks before calling it. + * + * A buffer cannot be placed on two lists at the same time. + */ + +static __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + struct sk_buff *prev, *next; + + newsk->list = list; + list->qlen++; + next = (struct sk_buff *)list; + prev = next->prev; + newsk->next = next; + newsk->prev = prev; + next->prev = newsk; + prev->next = newsk; +} + +/** + * skb_queue_tail - queue a buffer at the list tail + * @list: list to use + * @newsk: buffer to queue + * + * Queue a buffer at the tail of the list. This function takes the + * list lock and can be used safely with other locking &sk_buff functions + * safely. + * + * A buffer cannot be placed on two lists at the same time. + */ + +static __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) +{ + save_and_cli(); + __skb_queue_tail(list, newsk); + restore_flags(); +} + +static __inline__ void skb_assign_buf(struct sk_buff *skb, unsigned char *buf, unsigned int len) +{ + skb->head = buf; + skb->data = buf; + skb->tail = buf; + skb->end = buf + len; +} + +static __inline__ unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->tail; +} + +static __inline__ void skb_reset_tail_pointer(struct sk_buff *skb) +{ + skb->tail = skb->data; +} + +static __inline__ void skb_set_tail_pointer(struct sk_buff *skb, const int offset) +{ + skb->tail = skb->data + offset; +} + +static __inline__ unsigned char *skb_end_pointer(const struct sk_buff *skb) +{ + return skb->end; +} +#endif +/* + * External functions + */ +struct net_device; +extern void kfree_skb_chk_key(struct sk_buff *skb, struct net_device *root_dev); +#ifdef CONFIG_TRACE_SKB +extern void show_skb(void); +extern int _set_skb_list_flag(struct sk_buff *skb, unsigned int queueflag); +extern void dump_skb_list(void); +#define set_skb_list_flag(skb, queueflag) \ + (\ + _set_skb_list_flag((skb), queueflag), \ + (skb) ? (skb)->funcname[(skb)->list_idx] = __FUNCTION__:NULL \ + ) +extern int _clear_skb_list_flag(struct sk_buff *skb, unsigned int queueflag); +#define clear_skb_list_flag(skb, queueflag) \ + (\ + _clear_skb_list_flag((skb), queueflag), \ + (skb) ? (skb)->funcname[(skb)->list_idx] = __FUNCTION__ : NULL \ + ) +#define dev_kfree_skb_any(trx, holder, skb) \ + do{\ + clear_skb_list_flag(skb, SKBLIST_##trx##holder##_MASK);\ + set_skb_list_flag(skb, SKBLIST_POOL);\ + kfree_skb_chk_key(skb, skb->dev);\ + }while (0) +#else +#define dev_kfree_skb_any(skb) kfree_skb_chk_key(skb, skb->dev) +#endif +extern struct sk_buff *dev_alloc_skb(unsigned int length, unsigned int reserve_len); +extern struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask); +extern struct sk_buff *skb_copy(const struct sk_buff *skb, int gfp_mask, unsigned int reserve_len); +extern unsigned char *skb_pull(struct sk_buff *skb, unsigned int len); + +//----- ------------------------------------------------------------------ +// Device structure +//----- ------------------------------------------------------------------ +struct net_device_stats { + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_overflow; /* rx fifo overflow count */ +}; + +struct net_device { + char name[16]; + void *priv; /* pointer to private data */ + unsigned char dev_addr[6]; /* set during bootup */ + int (*init)(void); + int (*open)(struct net_device *dev); + int (*stop)(struct net_device *dev); + int (*hard_start_xmit)(struct sk_buff *skb, struct net_device *dev); + int (*do_ioctl)(struct net_device *dev, struct iwreq *ifr, int cmd); + struct net_device_stats* (*get_stats)(struct net_device *dev); +}; + +typedef struct { + struct net_device *dev; /* Binding wlan driver netdev */ + void *skb; /* pending Rx packet */ + unsigned int tx_busy; + unsigned int rx_busy; + unsigned char enable; + unsigned char mac[6]; +} Rltk_wlan_t; + +#define netdev_priv(dev) dev->priv + +extern struct net_device *alloc_etherdev(int sizeof_priv); +void free_netdev(struct net_device *dev); +int dev_alloc_name(struct net_device *net_dev, const char *ifname); + + +//----- ------------------------------------------------------------------ +// Timer Operation +//----- ------------------------------------------------------------------ +void init_timer(struct timer_list *timer); +void mod_timer(struct timer_list *timer, u32 delay_time_ms); +void cancel_timer_ex(struct timer_list * timer); +void del_timer_sync(struct timer_list * timer); +void init_timer_wrapper(void); +void deinit_timer_wrapper(void); + +void rtw_init_timer(_timer *ptimer, void *adapter, TIMER_FUN pfunc,void* cntx, const char *name); +void rtw_set_timer(_timer *ptimer,u32 delay_time); +u8 rtw_cancel_timer(_timer *ptimer); +void rtw_del_timer(_timer *ptimer); + +#endif //__WRAPPER_H__ + + + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.c b/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.c new file mode 100644 index 0000000..249b007 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.c @@ -0,0 +1,278 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +//#define _LWIP_INTF_C_ + +#include +#include +#include +#if !DEVICE_EMAC +#include +#include +#endif +#include +#include + +//----- ------------------------------------------------------------------ +// External Reference +//----- ------------------------------------------------------------------ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC + extern struct netif *xnetif[]; +#else + extern struct netif xnetif[]; //LWIP netif +#endif +#endif + + +/** + * rltk_wlan_set_netif_info - set netif hw address and register dev pointer to netif device + * @idx_wlan: netif index + * 0 for STA only or SoftAP only or STA in STA+SoftAP concurrent mode, + * 1 for SoftAP in STA+SoftAP concurrent mode + * @dev: register netdev pointer to LWIP. Reserved. + * @dev_addr: set netif hw address + * + * Return Value: None + */ +void rltk_wlan_set_netif_info(int idx_wlan, void * dev, unsigned char * dev_addr) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC + rtw_memcpy(xnetif[idx_wlan]->hwaddr, dev_addr, 6); +#else + rtw_memcpy(xnetif[idx_wlan].hwaddr, dev_addr, 6); + xnetif[idx_wlan].state = dev; +#endif +#endif +} + +/** + * rltk_wlan_send - send IP packets to WLAN. Called by low_level_output(). + * @idx: netif index + * @sg_list: data buffer list + * @sg_len: size of each data buffer + * @total_len: total data len + * + * Return Value: None + */ +int rltk_wlan_send(int idx, struct eth_drv_sg *sg_list, int sg_len, int total_len) +{ +#if (CONFIG_LWIP_LAYER == 1) + struct eth_drv_sg *last_sg; + struct sk_buff *skb = NULL; + int ret = 0; + + if(idx == -1){ + DBG_ERR("netif is DOWN"); + return -1; + } + DBG_TRACE("%s is called", __FUNCTION__); + + save_and_cli(); + if(rltk_wlan_check_isup(idx)) + rltk_wlan_tx_inc(idx); + else { + DBG_ERR("netif is DOWN"); + restore_flags(); + return -1; + } + restore_flags(); + + skb = rltk_wlan_alloc_skb(total_len); + if (skb == NULL) { + //DBG_ERR("rltk_wlan_alloc_skb() for data len=%d failed!", total_len); + ret = -1; + goto exit; + } + + for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { + rtw_memcpy(skb->tail, (void *)(sg_list->buf), sg_list->len); + skb_put(skb, sg_list->len); + } + + rltk_wlan_send_skb(idx, skb); + +exit: + save_and_cli(); + rltk_wlan_tx_dec(idx); + restore_flags(); + return ret; +#endif +} + +/** + * rltk_wlan_recv - indicate packets to LWIP. Called by ethernetif_recv(). + * @idx: netif index + * @sg_list: data buffer list + * @sg_len: size of each data buffer + * + * Return Value: None + */ +void rltk_wlan_recv(int idx, struct eth_drv_sg *sg_list, int sg_len) +{ +#if (CONFIG_LWIP_LAYER == 1) + struct eth_drv_sg *last_sg; + struct sk_buff *skb; + + DBG_TRACE("%s is called", __FUNCTION__); + + if (!rltk_wlan_check_isup(idx)) + return; + + if(idx == -1){ + DBG_ERR("skb is NULL"); + return; + } + + skb = rltk_wlan_get_recv_skb(idx); + DBG_ASSERT(skb, "No pending rx skb"); + + for (last_sg = &sg_list[sg_len]; sg_list < last_sg; ++sg_list) { + if (sg_list->buf != 0) { + rtw_memcpy((void *)(sg_list->buf), skb->data, sg_list->len); + skb_pull(skb, sg_list->len); + } + } +#endif +} + +int netif_is_valid_IP(int idx, unsigned char *ip_dest) +{ +#if CONFIG_LWIP_LAYER == 1 +#if DEVICE_EMAC + struct netif *pnetif = xnetif[idx]; +#else + struct netif *pnetif = &xnetif[idx]; +#endif + + ip_addr_t addr = { 0 }; + +#ifdef CONFIG_MEMORY_ACCESS_ALIGNED + unsigned int temp; + memcpy(&temp, ip_dest, sizeof(unsigned int)); + u32_t *ip_dest_addr = &temp; +#else + u32_t *ip_dest_addr = (u32_t*)ip_dest; +#endif + addr.addr = *ip_dest_addr; + + if(pnetif->ip_addr.addr == 0) + return 1; + + if(ip_addr_ismulticast(&addr) || ip_addr_isbroadcast(&addr,pnetif)){ + return 1; + } + + //if(ip_addr_netcmp(&(pnetif->ip_addr), &addr, &(pnetif->netmask))) //addr&netmask + // return 1; + + if(ip_addr_cmp(&(pnetif->ip_addr),&addr)) + return 1; + + DBG_TRACE("invalid IP: %d.%d.%d.%d ",ip_dest[0],ip_dest[1],ip_dest[2],ip_dest[3]); +#endif +#ifdef CONFIG_DONT_CARE_TP + if(pnetif->flags & NETIF_FLAG_IPSWITCH) + return 1; + else +#endif + return 0; +} + +int netif_get_idx(struct netif *pnetif) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC + if (pnetif == xnetif[0]) + return 0; +#else + int idx = pnetif - xnetif; + + switch(idx) { + case 0: + return 0; + case 1: + return 1; + default: + return -1; + } +#endif +#else + return -1; +#endif +} + +unsigned char *netif_get_hwaddr(int idx_wlan) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC + return xnetif[idx_wlan]->hwaddr; +#else + return xnetif[idx_wlan].hwaddr; +#endif +#else + return NULL; +#endif +} + +void netif_rx(int idx, unsigned int len) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC + wlan_emac_recv(xnetif[idx], len); +#else + ethernetif_recv(&xnetif[idx], len); +#endif +#endif +#if (CONFIG_INIC_EN == 1) + inic_netif_rx(idx, len); +#endif +} + +void netif_post_sleep_processing(void) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC +#else + lwip_POST_SLEEP_PROCESSING(); //For FreeRTOS tickless to enable Lwip ARP timer when leaving IPS - Alex Fang +#endif +#endif +} + +void netif_pre_sleep_processing(void) +{ +#if (CONFIG_LWIP_LAYER == 1) +#if DEVICE_EMAC +#else + lwip_PRE_SLEEP_PROCESSING(); +#endif +#endif +} + +#ifdef CONFIG_WOWLAN +unsigned char *rltk_wlan_get_ip(int idx){ +#if (CONFIG_LWIP_LAYER == 1) + return LwIP_GetIP(&xnetif[idx]); +#else + return NULL; +#endif +} +#endif + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.h new file mode 100644 index 0000000..2553c99 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.h @@ -0,0 +1,84 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __LWIP_INTF_H__ +#define __LWIP_INTF_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +struct netif; + +//----- ------------------------------------------------------------------ +// Ethernet Buffer +//----- ------------------------------------------------------------------ +#if DEVICE_EMAC +struct eth_drv_sg { + unsigned int buf; + unsigned int len; +}; + +#define MAX_ETH_DRV_SG 32 +#define MAX_ETH_MSG 1540 +extern void wlan_emac_recv(struct netif *netif, int len); +#else +#include "ethernetif.h" // moved to ethernetif.h by jimmy 12/2/2015 +#endif +//----- ------------------------------------------------------------------ +// Wlan Interface Provided +//----- ------------------------------------------------------------------ +unsigned char rltk_wlan_check_isup(int idx); +void rltk_wlan_tx_inc(int idx); +void rltk_wlan_tx_dec(int idx); +struct sk_buff * rltk_wlan_get_recv_skb(int idx); +struct sk_buff * rltk_wlan_alloc_skb(unsigned int total_len); +void rltk_wlan_set_netif_info(int idx_wlan, void * dev, unsigned char * dev_addr); +void rltk_wlan_send_skb(int idx, struct sk_buff *skb); //struct sk_buff as defined above comment line +int rltk_wlan_send(int idx, struct eth_drv_sg *sg_list, int sg_len, int total_len); +void rltk_wlan_recv(int idx, struct eth_drv_sg *sg_list, int sg_len); +unsigned char rltk_wlan_running(unsigned char idx); // interface is up. 0: interface is down + +//----- ------------------------------------------------------------------ +// Network Interface provided +//----- ------------------------------------------------------------------ + +int netif_is_valid_IP(int idx,unsigned char * ip_dest); +int netif_get_idx(struct netif *pnetif); +unsigned char *netif_get_hwaddr(int idx_wlan); +void netif_rx(int idx, unsigned int len); +void netif_post_sleep_processing(void); +void netif_pre_sleep_processing(void); +#if (CONFIG_LWIP_LAYER == 1) +#if !DEVICE_EMAC +extern void ethernetif_recv(struct netif *netif, int total_len); +#endif +extern void lwip_PRE_SLEEP_PROCESSING(void); +extern void lwip_POST_SLEEP_PROCESSING(void); +#endif //CONFIG_LWIP_LAYER == 1 + + +#ifdef CONFIG_WOWLAN +extern unsigned char *rltk_wlan_get_ip(int idx); +#endif + +#ifdef __cplusplus +} +#endif + +#endif //#ifndef __LWIP_INTF_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/netdev.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/netdev.h new file mode 100644 index 0000000..ae5046a --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/netdev.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __NETDEV_H_ +#define __NETDEV_H_ + +/* Define compilor specific symbol */ +// +// inline function +// + +#if defined ( __ICCARM__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition //In dialect C99, inline means that a function's definition is provided + //only for inlining, and that there is another definition + //(without inline) somewhere else in the program. + //That means that this program is incomplete, because if + //add isn't inlined (for example, when compiling without optimization), + //then main will have an unresolved reference to that other definition. + + // Do not inline function is the function body is defined .c file and this + // function will be called somewhere else, otherwise there is compile error +#elif defined ( __CC_ARM ) +#define __inline__ __inline //__linine__ is not supported in keil compilor, use __inline instead +#define inline __inline +#define __inline_definition // for dialect C99 +#elif defined ( __GNUC__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition inline +#endif + +#include +#include +#if defined( PLATFORM_FREERTOS) +#include "freertos_service.h" +#elif defined( PLATFORM_ECOS) +#include "ecos/ecos_service.h" +#elif defined(PLATFORM_CMSIS_RTOS) +#include "rtx_service.h" +#endif + + +// rtl8195a uses receive_tasklet for wps +// 8189em uses interrupt_thread for wps +#if defined(CONFIG_WPS) +#define RECV_STACK_FOR_WPS 448//512//384 //Change to 512 for WPS (IAR STM32) stack overflow +#else +#define RECV_STACK_FOR_WPS 0 +#endif + +#ifdef CONFIG_DONT_CARE_TP +#define XMIT_STACKSIZE 192 //256 +#define CMD_STACKSIZE 384 //512 +#else +#define XMIT_STACKSIZE 256 +#define CMD_STACKSIZE 512 //1024 +#endif //CONFIG_DONT_CARE_TP + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#define RECV_STACKSIZE 256 +#else //CONFIG_PLATFORM_8195A +#ifdef CONFIG_INCLUDE_WPA_PSK +#if PSK_SUPPORT_TKIP +#define RECV_STACKSIZE (512 + 256 + 128 + RECV_STACK_FOR_WPS) +#else +#define RECV_STACKSIZE (512 + 256 + RECV_STACK_FOR_WPS ) +#endif +#else +#define RECV_STACKSIZE (512 + 256 + RECV_STACK_FOR_WPS) //Can be reduced +#endif +#endif //CONFIG_PLATFORM_8195A + +#define XMIT_TASKLET_STACKSIZE 256 +#define RECV_TASKLET_STACKSIZE (1024 + RECV_STACK_FOR_WPS) +#define SDIOXMIT_STACKSIZE 256 + + +struct rtw_netdev_priv_indicator { + void *priv; + u32 sizeof_priv; +}; + +#define rtw_netdev_priv(netdev) ( ((struct rtw_netdev_priv_indicator *)netdev_priv(netdev))->priv ) + +#define ADPT_FMT "%s" +#define ADPT_ARG(adapter) adapter->pnetdev->name +#define FUNC_NDEV_FMT "%s" +#define FUNC_NDEV_ARG(ndev) __func__ +#define FUNC_ADPT_FMT "%s(%s)" +#define FUNC_ADPT_ARG(adapter) __func__, adapter->pnetdev->name + +#include "wifi_constants.h" +#include "wifi_structures.h" +int rtw_if_wifi_thread(char *name); +#endif //#ifndef __OSDEP_SERVICE_H_ diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/osdep_intf.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/osdep_intf.h new file mode 100644 index 0000000..3096bb8 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/osdep_intf.h @@ -0,0 +1,116 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + +#ifndef __OSDEP_INTF_H_ +#define __OSDEP_INTF_H_ + +typedef struct net_device * _nic_hdl; +struct iw_request_info { + u16 cmd; /* Wireless Extension command */ + u16 flags; /* More to come ;-) */ +}; +typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +struct pkt_buff { + _list list; + u32 len; + unsigned char *data; +}; + +#if defined(PLATFORM_FREERTOS) || defined (PLATFORM_CMSIS_RTOS) + +#include "freertos/wrapper.h" +#include "freertos/freertos_intfs.h" +#include "freertos/freertos_xmit.h" +#include "freertos/freertos_recv.h" + +#elif defined(PLATFORM_ECOS) + +#include "ecos/ecos_xmit.h" +#include "ecos/ecos_recv.h" +#include "ecos/ecos_mlme.h" +#include "ecos/ecos_intfs.h" + +#ifdef CONFIG_PROC_DEBUG //need move to ecos/ecos_intfs.h +void rtw_proc_init_one(struct net_device *dev); +void rtw_proc_remove_one(struct net_device *dev); +#else +static void rtw_proc_init_one(struct net_device *dev){} +static void rtw_proc_remove_one(struct net_device *dev){} +#endif //CONFIG_PROC_DEBUG + +#elif defined(PLATFORM_LINUX) +int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); + +int rtw_init_netdev_name(struct net_device *pnetdev, const char *ifname); +struct net_device *rtw_init_netdev(_adapter *padapter); + +#ifdef CONFIG_PROC_DEBUG +void rtw_proc_init_one(struct net_device *dev); +void rtw_proc_remove_one(struct net_device *dev); +#else +static void rtw_proc_init_one(struct net_device *dev){} +static void rtw_proc_remove_one(struct net_device *dev){} +#endif //CONFIG_PROC_DEBUG +#endif + +#ifdef CONFIG_CONCURRENT_MODE +struct _io_ops; +_adapter *rtw_drv_if2_init(_adapter *primary_padapter, char *name, void (*set_intf_ops)(struct _io_ops *pops)); +void rtw_drv_if2_free(_adapter *pbuddy_padapter); +#endif + +struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv); +struct net_device * rtw_alloc_etherdev(int sizeof_priv); +void rtw_free_netdev(struct net_device * netdev); + +int rtw_netif_queue_stopped(struct net_device *pnetdev); +void rtw_netif_wake_queue(struct net_device *pnetdev); +void rtw_netif_start_queue(struct net_device *pnetdev); +void rtw_netif_stop_queue(struct net_device *pnetdev); + +struct pkt_buff *rtw_alloc_pktbuf(unsigned int size); +void rtw_free_pktbuf(struct pkt_buff *skb); + +#if 0 +int RTW_STATUS_CODE(int error_code); + +//flags used for rtw_update_mem_stat() +enum { + MEM_STAT_VIR_ALLOC_SUCCESS, + MEM_STAT_VIR_ALLOC_FAIL, + MEM_STAT_VIR_FREE, + MEM_STAT_PHY_ALLOC_SUCCESS, + MEM_STAT_PHY_ALLOC_FAIL, + MEM_STAT_PHY_FREE, + MEM_STAT_TX, //used to distinguish TX/RX, asigned from caller + MEM_STAT_TX_ALLOC_SUCCESS, + MEM_STAT_TX_ALLOC_FAIL, + MEM_STAT_TX_FREE, + MEM_STAT_RX, //used to distinguish TX/RX, asigned from caller + MEM_STAT_RX_ALLOC_SUCCESS, + MEM_STAT_RX_ALLOC_FAIL, + MEM_STAT_RX_FREE +}; +#endif + +#endif //_OSDEP_INTF_H_ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/skbuff.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/skbuff.h new file mode 100644 index 0000000..aab44fe --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/skbuff.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +#ifndef __SKBUFF_H__ +#define __SKBUFF_H__ + +struct sk_buff_head { + struct list_head *next, *prev; + unsigned int qlen; +}; + +#ifdef CONFIG_TRACE_SKB +#define TRACE_SKB_DEPTH 8 +#endif + +struct sk_buff { + /* These two members must be first. */ + struct sk_buff *next; /* Next buffer in list */ + struct sk_buff *prev; /* Previous buffer in list */ + + struct sk_buff_head *list; /* List we are on */ + unsigned char *head; /* Head of buffer */ + unsigned char *data; /* Data head pointer */ + unsigned char *tail; /* Tail pointer */ + unsigned char *end; /* End pointer */ + void *dev; /* Device we arrived on/are leaving by */ + unsigned int len; /* Length of actual data */ +#ifdef CONFIG_TRACE_SKB + unsigned int liston[TRACE_SKB_DEPTH]; /* Trace the Lists we went through */ + const char *funcname[TRACE_SKB_DEPTH]; + unsigned int list_idx; /* Trace the List we are on */ +#endif +//#ifdef CONFIG_DONT_CARE_TP + int dyalloc_flag; +//#endif +}; + +unsigned char *skb_put(struct sk_buff *skb, unsigned int len); +unsigned char *skb_pull(struct sk_buff *skb, unsigned int len); +void skb_reserve(struct sk_buff *skb, unsigned int len); +void skb_assign_buf(struct sk_buff *skb, unsigned char *buf, unsigned int len); +unsigned char *skb_tail_pointer(const struct sk_buff *skb); +void skb_set_tail_pointer(struct sk_buff *skb, const int offset); +unsigned char *skb_end_pointer(const struct sk_buff *skb); + +void init_skb_pool(void); +void init_skb_data_pool(void); + +#ifndef CONFIG_DONT_CARE_TP +struct sk_buff *dev_alloc_skb(unsigned int length, unsigned int reserve_len); +#else +struct sk_buff *dev_alloc_tx_skb(unsigned int length, unsigned int reserve_len); +struct sk_buff *dev_alloc_rx_skb(unsigned int length, unsigned int reserve_len); +#define dev_alloc_skb dev_alloc_tx_skb +#endif +void kfree_skb(struct sk_buff *skb); + + +#endif //__SKBUFF_H__ + diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/wireless.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/wireless.h new file mode 100644 index 0000000..c874909 --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/wireless.h @@ -0,0 +1,1209 @@ +/* + * This file define a set of standard wireless extensions + * + * Version : 22 16.3.07 + * + * Authors : Jean Tourrilhes - HPL - + * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. + */ + +#ifndef _LINUX_WIRELESS_H +#define _LINUX_WIRELESS_H + +/************************** DOCUMENTATION **************************/ +/* + * Initial APIs (1996 -> onward) : + * ----------------------------- + * Basically, the wireless extensions are for now a set of standard ioctl + * call + /proc/net/wireless + * + * The entry /proc/net/wireless give statistics and information on the + * driver. + * This is better than having each driver having its entry because + * its centralised and we may remove the driver module safely. + * + * Ioctl are used to configure the driver and issue commands. This is + * better than command line options of insmod because we may want to + * change dynamically (while the driver is running) some parameters. + * + * The ioctl mechanimsm are copied from standard devices ioctl. + * We have the list of command plus a structure descibing the + * data exchanged... + * Note that to add these ioctl, I was obliged to modify : + * # net/core/dev.c (two place + add include) + * # net/ipv4/af_inet.c (one place + add include) + * + * /proc/net/wireless is a copy of /proc/net/dev. + * We have a structure for data passed from the driver to /proc/net/wireless + * Too add this, I've modified : + * # net/core/dev.c (two other places) + * # include/linux/netdevice.h (one place) + * # include/linux/proc_fs.h (one place) + * + * New driver API (2002 -> onward) : + * ------------------------------- + * This file is only concerned with the user space API and common definitions. + * The new driver API is defined and documented in : + * # include/net/iw_handler.h + * + * Note as well that /proc/net/wireless implementation has now moved in : + * # net/core/wireless.c + * + * Wireless Events (2002 -> onward) : + * -------------------------------- + * Events are defined at the end of this file, and implemented in : + * # net/core/wireless.c + * + * Other comments : + * -------------- + * Do not add here things that are redundant with other mechanisms + * (drivers init, ifconfig, /proc/net/dev, ...) and with are not + * wireless specific. + * + * These wireless extensions are not magic : each driver has to provide + * support for them... + * + * IMPORTANT NOTE : As everything in the kernel, this is very much a + * work in progress. Contact me if you have ideas of improvements... + */ + +/***************************** INCLUDES *****************************/ + +/* This header is used in user-space, therefore need to be sanitised + * for that purpose. Those includes are usually not compatible with glibc. + * To know which includes to use in user-space, check iwlib.h. */ +#ifdef __KERNEL__ +#include /* for "caddr_t" et al */ +#include /* for "struct sockaddr" et al */ +#include /* for IFNAMSIZ and co... */ +#endif /* __KERNEL__ */ + +//#include +#define IFNAMSIZ 16 +#define ARPHRD_ETHER 1 /* ethernet hardware format */ + +/***************************** VERSION *****************************/ +/* + * This constant is used to know the availability of the wireless + * extensions and to know which version of wireless extensions it is + * (there is some stuff that will be added in the future...) + * I just plan to increment with each new version. + */ +#define WIRELESS_EXT 22 + +/* + * Changes : + * + * V2 to V3 + * -------- + * Alan Cox start some incompatibles changes. I've integrated a bit more. + * - Encryption renamed to Encode to avoid US regulation problems + * - Frequency changed from float to struct to avoid problems on old 386 + * + * V3 to V4 + * -------- + * - Add sensitivity + * + * V4 to V5 + * -------- + * - Missing encoding definitions in range + * - Access points stuff + * + * V5 to V6 + * -------- + * - 802.11 support (ESSID ioctls) + * + * V6 to V7 + * -------- + * - define IW_ESSID_MAX_SIZE and IW_MAX_AP + * + * V7 to V8 + * -------- + * - Changed my e-mail address + * - More 802.11 support (nickname, rate, rts, frag) + * - List index in frequencies + * + * V8 to V9 + * -------- + * - Support for 'mode of operation' (ad-hoc, managed...) + * - Support for unicast and multicast power saving + * - Change encoding to support larger tokens (>64 bits) + * - Updated iw_params (disable, flags) and use it for NWID + * - Extracted iw_point from iwreq for clarity + * + * V9 to V10 + * --------- + * - Add PM capability to range structure + * - Add PM modifier : MAX/MIN/RELATIVE + * - Add encoding option : IW_ENCODE_NOKEY + * - Add TxPower ioctls (work like TxRate) + * + * V10 to V11 + * ---------- + * - Add WE version in range (help backward/forward compatibility) + * - Add retry ioctls (work like PM) + * + * V11 to V12 + * ---------- + * - Add SIOCSIWSTATS to get /proc/net/wireless programatically + * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space + * - Add new statistics (frag, retry, beacon) + * - Add average quality (for user space calibration) + * + * V12 to V13 + * ---------- + * - Document creation of new driver API. + * - Extract union iwreq_data from struct iwreq (for new driver API). + * - Rename SIOCSIWNAME as SIOCSIWCOMMIT + * + * V13 to V14 + * ---------- + * - Wireless Events support : define struct iw_event + * - Define additional specific event numbers + * - Add "addr" and "param" fields in union iwreq_data + * - AP scanning stuff (SIOCSIWSCAN and friends) + * + * V14 to V15 + * ---------- + * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg + * - Make struct iw_freq signed (both m & e), add explicit padding + * - Add IWEVCUSTOM for driver specific event/scanning token + * - Add IW_MAX_GET_SPY for driver returning a lot of addresses + * - Add IW_TXPOW_RANGE for range of Tx Powers + * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points + * - Add IW_MODE_MONITOR for passive monitor + * + * V15 to V16 + * ---------- + * - Increase the number of bitrates in iw_range to 32 (for 802.11g) + * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a) + * - Reshuffle struct iw_range for increases, add filler + * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses + * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support + * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" + * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index + * + * V16 to V17 + * ---------- + * - Add flags to frequency -> auto/fixed + * - Document (struct iw_quality *)->updated, add new flags (INVALID) + * - Wireless Event capability in struct iw_range + * - Add support for relative TxPower (yick !) + * + * V17 to V18 (From Jouni Malinen ) + * ---------- + * - Add support for WPA/WPA2 + * - Add extended encoding configuration (SIOCSIWENCODEEXT and + * SIOCGIWENCODEEXT) + * - Add SIOCSIWGENIE/SIOCGIWGENIE + * - Add SIOCSIWMLME + * - Add SIOCSIWPMKSA + * - Add struct iw_range bit field for supported encoding capabilities + * - Add optional scan request parameters for SIOCSIWSCAN + * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA + * related parameters (extensible up to 4096 parameter values) + * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE, + * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND + * + * V18 to V19 + * ---------- + * - Remove (struct iw_point *)->pointer from events and streams + * - Remove header includes to help user space + * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64 + * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros + * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM + * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros + * + * V19 to V20 + * ---------- + * - RtNetlink requests support (SET/GET) + * + * V20 to V21 + * ---------- + * - Remove (struct net_device *)->get_wireless_stats() + * - Change length in ESSID and NICK to strlen() instead of strlen()+1 + * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers + * - Power/Retry relative values no longer * 100000 + * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI + * + * V21 to V22 + * ---------- + * - Prevent leaking of kernel space in stream on 64 bits. + */ + +/**************************** CONSTANTS ****************************/ +typedef unsigned char __u8; +typedef char __s8; +typedef unsigned short __u16; +typedef short __s16; +typedef unsigned int __u32; +typedef int __s32; +typedef unsigned long long __u64; +typedef long long __i64; + +#define E2BIG 7 /* Argument list too long */ + +#define ETH_ALEN 6 /* Octets in one ethernet addr */ + +/* Device private ioctl calls */ + +/* + * These 16 ioctls are available to devices via the do_ioctl() device + * vector. Each device should include this file and redefine these names + * as their own. Because these are device dependent it is a good idea + * _NOT_ to issue them to random objects and hope. + * + * THESE IOCTLS ARE _DEPRECATED_ AND WILL DISAPPEAR IN 2.5.X -DaveM + */ + +#define SIOCDEVPRIVATE 0x89F0 /* to 89FF */ + +/* + * These 16 ioctl calls are protocol private + */ + +#define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */ + +/* -------------------------- IOCTL LIST -------------------------- */ + +/* Wireless Identification */ +#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */ +#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ +/* SIOCGIWNAME is used to verify the presence of Wireless Extensions. + * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"... + * Don't put the name of your driver there, it's useless. */ + +/* Basic operations */ +#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */ +#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */ +#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */ +#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */ +#define SIOCSIWMODE 0x8B06 /* set operation mode */ +#define SIOCGIWMODE 0x8B07 /* get operation mode */ +#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */ +#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */ + +/* Informative stuff */ +#define SIOCSIWRANGE 0x8B0A /* Unused */ +#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */ +#define SIOCSIWPRIV 0x8B0C /* Unused */ +#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */ +#define SIOCSIWSTATS 0x8B0E /* Unused */ +#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */ +/* SIOCGIWSTATS is strictly used between user space and the kernel, and + * is never passed to the driver (i.e. the driver will never see it). */ + +/* Spy support (statistics per MAC address - used for Mobile IP support) */ +#define SIOCSIWSPY 0x8B10 /* set spy addresses */ +#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ +#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */ +#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */ + +/* Access Point manipulation */ +#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */ +#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */ +#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */ +#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */ +#define SIOCGIWSCAN 0x8B19 /* get scanning results */ + +/* 802.11 specific support */ +#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */ +#define SIOCGIWESSID 0x8B1B /* get ESSID */ +#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */ +#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */ +/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit + * within the 'iwreq' structure, so we need to use the 'data' member to + * point to a string in user space, like it is done for RANGE... */ + +/* Other parameters useful in 802.11 and some other devices */ +#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */ +#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */ +#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */ +#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */ +#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */ +#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */ +#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */ +#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */ +#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */ +#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */ + +/* Encoding stuff (scrambling, hardware security, WEP...) */ +#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */ +#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */ +/* Power saving stuff (power management, unicast and multicast) */ +#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ +#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ +/* Modulation bitmask */ +#define SIOCSIWMODUL 0x8B2E /* set Modulations settings */ +#define SIOCGIWMODUL 0x8B2F /* get Modulations settings */ + +/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). + * This ioctl uses struct iw_point and data buffer that includes IE id and len + * fields. More than one IE may be included in the request. Setting the generic + * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers + * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers + * are required to report the used IE as a wireless event, e.g., when + * associating with an AP. */ +#define SIOCSIWGENIE 0x8B30 /* set generic IE */ +#define SIOCGIWGENIE 0x8B31 /* get generic IE */ + +/* WPA : IEEE 802.11 MLME requests */ +#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses + * struct iw_mlme */ +/* WPA : Authentication mode parameters */ +#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ +#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ + +/* WPA : Extended version of encoding configuration */ +#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ +#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ + +/* WPA2 : PMKSA cache management */ +#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ + +/* Send Mgnt Frame or Action Frame */ +#define SIOCSIWMGNTSEND 0x8B37 /* Send Mgnt Frame or Action Frame */ + +/* Send WPS EAPOL Frame */ +#define SIOCSIWEAPOLSEND 0x8B38 /* Send WPS EAPOL Frame */ +/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ + +/* These 32 ioctl are wireless device private, for 16 commands. + * Each driver is free to use them for whatever purpose it chooses, + * however the driver *must* export the description of those ioctls + * with SIOCGIWPRIV and *must* use arguments as defined below. + * If you don't follow those rules, DaveM is going to hate you (reason : + * it make mixed 32/64bit operation impossible). + */ +#define SIOCIWFIRSTPRIV 0x8BE0 +#define SIOCIWLASTPRIV 0x8BFF + +#define SIOCSIWPRIVADAPTIVITY 0x8BFB +#define SIOCGIWPRIVPASSPHRASE 0x8BFC +#define SIOCSIWPRIVCOUNTRY 0x8BFD +#define SIOCSIWPRIVAPESSID 0x8BFE +#define SIOCSIWPRIVPASSPHRASE 0x8BFF +/* Previously, we were using SIOCDEVPRIVATE, but we now have our + * separate range because of collisions with other tools such as + * 'mii-tool'. + * We now have 32 commands, so a bit more space ;-). + * Also, all 'even' commands are only usable by root and don't return the + * content of ifr/iwr to user (but you are not obliged to use the set/get + * convention, just use every other two command). More details in iwpriv.c. + * And I repeat : you are not forced to use them with iwpriv, but you + * must be compliant with it. + */ + +/* ------------------------- IOCTL STUFF ------------------------- */ + +/* The first and the last (range) */ +#define SIOCIWFIRST 0x8B00 +#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ +#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) + +/* Odd : get (world access), even : set (root access) */ +#define IW_IS_SET(cmd) (!((cmd) & 0x1)) +#define IW_IS_GET(cmd) ((cmd) & 0x1) + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* Those are *NOT* ioctls, do not issue request on them !!! */ +/* Most events use the same identifier as ioctl requests */ + +#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */ +#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */ +#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ +#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ +#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ +#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) + * (scan results); This includes id and + * length fields. One IWEVGENIE may + * contain more than one IE. Scan + * results may contain one or more + * IWEVGENIE events. */ +#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure + * (struct iw_michaelmicfailure) + */ +#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. + * The data includes id and length + * fields and may contain more than one + * IE. This event is required in + * Managed mode if the driver + * generates its own WPA/RSN IE. This + * should be sent just before + * IWEVREGISTERED event for the + * association. */ +#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association + * Response. The data includes id and + * length fields and may contain more + * than one IE. This may be sent + * between IWEVASSOCREQIE and + * IWEVREGISTERED events for the + * association. */ +#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN + * pre-authentication + * (struct iw_pmkid_cand) */ + +#define IWEVFIRST 0x8C00 +#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) + +/* Indicate Mgnt Frame and Action Frame to uplayer*/ +#define IWEVMGNTRECV 0x8C10 /* Indicate Mgnt Frame to uplayer */ + +/* ------------------------- PRIVATE INFO ------------------------- */ +/* + * The following is used with SIOCGIWPRIV. It allow a driver to define + * the interface (name, type of data) for its private ioctl. + * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV + */ + +#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */ +#define IW_PRIV_TYPE_NONE 0x0000 +#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */ +#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */ +#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */ +#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */ +#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */ + +#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */ + +#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */ + +/* + * Note : if the number of args is fixed and the size < 16 octets, + * instead of passing a pointer we will put args in the iwreq struct... + */ + +/* ----------------------- OTHER CONSTANTS ----------------------- */ + +/* Maximum frequencies in the range struct */ +#define IW_MAX_FREQUENCIES 32 +/* Note : if you have something like 80 frequencies, + * don't increase this constant and don't fill the frequency list. + * The user will be able to set by channel anyway... */ + +/* Maximum bit rates in the range struct */ +#define IW_MAX_BITRATES 32 + +/* Maximum tx powers in the range struct */ +#define IW_MAX_TXPOWER 8 +/* Note : if you more than 8 TXPowers, just set the max and min or + * a few of them in the struct iw_range. */ + +/* Maximum of address that you may set with SPY */ +#define IW_MAX_SPY 8 + +/* Maximum of address that you may get in the + list of access points in range */ +#define IW_MAX_AP 64 + +/* Maximum size of the ESSID and NICKN strings */ +#define IW_ESSID_MAX_SIZE 32 + +/* Modes of operation */ +#define IW_MODE_AUTO 0 /* Let the driver decides */ +#define IW_MODE_ADHOC 1 /* Single cell network */ +#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */ +#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */ +#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */ +#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ +#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ + +/* Statistics flags (bitmask in updated) */ +#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */ +#define IW_QUAL_LEVEL_UPDATED 0x02 +#define IW_QUAL_NOISE_UPDATED 0x04 +#define IW_QUAL_ALL_UPDATED 0x07 +#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */ +#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */ +#define IW_QUAL_ALL_INVALID 0x70 + +/* Frequency flags */ +#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ +#define IW_FREQ_FIXED 0x01 /* Force a specific value */ + +/* Maximum number of size of encoding token available + * they are listed in the range structure */ +#define IW_MAX_ENCODING_SIZES 8 + +/* Maximum size of the encoding token in bytes */ +#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */ + +/* Flags for encoding (along with the token) */ +#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ +#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ +#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ +#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ +#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ +#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ +#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ + +/* Power management flags available (along with the value, if any) */ +#define IW_POWER_ON 0x0000 /* No details... */ +#define IW_POWER_TYPE 0xF000 /* Type of parameter */ +#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */ +#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */ +#define IW_POWER_SAVING 0x4000 /* Value is relative (how aggressive)*/ +#define IW_POWER_MODE 0x0F00 /* Power Management mode */ +#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */ +#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */ +#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */ +#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */ +#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */ +#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ +#define IW_POWER_MIN 0x0001 /* Value is a minimum */ +#define IW_POWER_MAX 0x0002 /* Value is a maximum */ +#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ + +/* Transmit Power flags available */ +#define IW_TXPOW_TYPE 0x00FF /* Type of value */ +#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ +#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ +#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ +#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ + +/* Retry limits and lifetime flags available */ +#define IW_RETRY_ON 0x0000 /* No details... */ +#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ +#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ +#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ +#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */ +#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ +#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ +#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ +#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */ +#define IW_RETRY_LONG 0x0020 /* Value is for long packets */ + +/* Scanning request flags */ +#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ +#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */ +#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */ +#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */ +#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */ +#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */ +#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */ +#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */ +#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */ +/* struct iw_scan_req scan_type */ +#define IW_SCAN_TYPE_ACTIVE 0 +#define IW_SCAN_TYPE_PASSIVE 1 +/* Maximum size of returned data */ +#define IW_SCAN_MAX_DATA 4096 /* In bytes */ + +/* Max number of char in custom event - use multiple of them if needed */ +#define IW_CUSTOM_MAX 256 /* In bytes */ + +/* Generic information element */ +#define IW_GENERIC_IE_MAX 1024 + +/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ +#define IW_MLME_DEAUTH 0 +#define IW_MLME_DISASSOC 1 +#define IW_MLME_AUTH 2 +#define IW_MLME_ASSOC 3 + +/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ +#define IW_AUTH_INDEX 0x0FFF +#define IW_AUTH_FLAGS 0xF000 +/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) + * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the + * parameter that is being set/get to; value will be read/written to + * struct iw_param value field) */ +#define IW_AUTH_WPA_VERSION 0 +#define IW_AUTH_CIPHER_PAIRWISE 1 +#define IW_AUTH_CIPHER_GROUP 2 +#define IW_AUTH_KEY_MGMT 3 +#define IW_AUTH_TKIP_COUNTERMEASURES 4 +#define IW_AUTH_DROP_UNENCRYPTED 5 +#define IW_AUTH_80211_AUTH_ALG 6 +#define IW_AUTH_WPA_ENABLED 7 +#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 +#define IW_AUTH_ROAMING_CONTROL 9 +#define IW_AUTH_PRIVACY_INVOKED 10 + +/* IW_AUTH_WPA_VERSION values (bit field) */ +#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 +#define IW_AUTH_WPA_VERSION_WPA 0x00000002 +#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 + +/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ +#define IW_AUTH_CIPHER_NONE 0x00000001 +#define IW_AUTH_CIPHER_WEP40 0x00000002 +#define IW_AUTH_CIPHER_TKIP 0x00000004 +#define IW_AUTH_CIPHER_CCMP 0x00000008 +#define IW_AUTH_CIPHER_WEP104 0x00000010 + +/* IW_AUTH_KEY_MGMT values (bit field) */ +#define IW_AUTH_KEY_MGMT_802_1X 1 +#define IW_AUTH_KEY_MGMT_PSK 2 + +/* IW_AUTH_80211_AUTH_ALG values (bit field) */ +#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 +#define IW_AUTH_ALG_SHARED_KEY 0x00000002 +#define IW_AUTH_ALG_LEAP 0x00000004 + +/* IW_AUTH_ROAMING_CONTROL values */ +#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ +#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming + * control */ + +/* SIOCSIWENCODEEXT definitions */ +#define IW_ENCODE_SEQ_MAX_SIZE 8 +/* struct iw_encode_ext ->alg */ +#define IW_ENCODE_ALG_NONE 0 +#define IW_ENCODE_ALG_WEP 1 +#define IW_ENCODE_ALG_TKIP 2 +#define IW_ENCODE_ALG_CCMP 3 +/* struct iw_encode_ext ->ext_flags */ +#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 +#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 +#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 +#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 + +/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */ +#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */ +#define IW_MICFAILURE_GROUP 0x00000004 +#define IW_MICFAILURE_PAIRWISE 0x00000008 +#define IW_MICFAILURE_STAKEY 0x00000010 +#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported) + */ + +/* Bit field values for enc_capa in struct iw_range */ +#define IW_ENC_CAPA_WPA 0x00000001 +#define IW_ENC_CAPA_WPA2 0x00000002 +#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004 +#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008 + +/* Event capability macros - in (struct iw_range *)->event_capa + * Because we have more than 32 possible events, we use an array of + * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ +#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ + (cmd - SIOCIWFIRSTPRIV + 0x60) : \ + (cmd - SIOCSIWCOMMIT)) +#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) +#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) +/* Event capability constants - event autogenerated by the kernel + * This list is valid for most 802.11 devices, customise as needed... */ +#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ + IW_EVENT_CAPA_MASK(0x8B06) | \ + IW_EVENT_CAPA_MASK(0x8B1A)) +#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) +/* "Easy" macro to set events in iw_range (less efficient) */ +#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) +#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } + +/* Modulations bitmasks */ +#define IW_MODUL_ALL 0x00000000 /* Everything supported */ +#define IW_MODUL_FH 0x00000001 /* Frequency Hopping */ +#define IW_MODUL_DS 0x00000002 /* Original Direct Sequence */ +#define IW_MODUL_CCK 0x00000004 /* 802.11b : 5.5 + 11 Mb/s */ +#define IW_MODUL_11B (IW_MODUL_DS | IW_MODUL_CCK) +#define IW_MODUL_PBCC 0x00000008 /* TI : 5.5 + 11 + 22 Mb/s */ +#define IW_MODUL_OFDM_A 0x00000010 /* 802.11a : 54 Mb/s */ +#define IW_MODUL_11A (IW_MODUL_OFDM_A) +#define IW_MODUL_11AB (IW_MODUL_11B | IW_MODUL_11A) +#define IW_MODUL_OFDM_G 0x00000020 /* 802.11g : 54 Mb/s */ +#define IW_MODUL_11G (IW_MODUL_11B | IW_MODUL_OFDM_G) +#define IW_MODUL_11AG (IW_MODUL_11G | IW_MODUL_11A) +#define IW_MODUL_TURBO 0x00000040 /* ATH : bonding, 108 Mb/s */ +/* In here we should define MIMO stuff. Later... */ +#define IW_MODUL_CUSTOM 0x40000000 /* Driver specific */ + +/* Bitrate flags available */ +#define IW_BITRATE_TYPE 0x00FF /* Type of value */ +#define IW_BITRATE_UNICAST 0x0001 /* Maximum/Fixed unicast bitrate */ +#define IW_BITRATE_BROADCAST 0x0002 /* Fixed broadcast bitrate */ + +/****************************** TYPES ******************************/ + +/* --------------------------- SUBTYPES --------------------------- */ + +struct sockaddr_t { + __u8 sa_len; + __u8 sa_family; + char sa_data[14]; +}; + +/* + * Generic format for most parameters that fit in an int + */ +struct iw_param +{ + __s32 value; /* The value of the parameter itself */ + __u8 fixed; /* Hardware should not use auto select */ + __u8 disabled; /* Disable the feature */ + __u16 flags; /* Various specifc flags (if any) */ +}; + +/* + * For all data larger than 16 octets, we need to use a + * pointer to memory allocated in user space. + */ +struct iw_point +{ + void *pointer; /* Pointer to the data (in user space) */ + __u16 length; /* number of fields or size in bytes */ + __u16 flags; /* Optional params */ +}; + +/* + * A frequency + * For numbers lower than 10^9, we encode the number in 'm' and + * set 'e' to 0 + * For number greater than 10^9, we divide it by the lowest power + * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')... + * The power of 10 is in 'e', the result of the division is in 'm'. + */ +struct iw_freq +{ + __s32 m; /* Mantissa */ + __s16 e; /* Exponent */ + __u8 i; /* List index (when in range struct) */ + __u8 flags; /* Flags (fixed/auto) */ +}; + +/* + * Quality of the link + */ +struct iw_quality +{ + __u8 qual; /* link quality (%retries, SNR, + %missed beacons or better...) */ + __u8 level; /* signal level (dBm) */ + __u8 noise; /* noise level (dBm) */ + __u8 updated; /* Flags to know if updated */ +}; + +/* + * Packet discarded in the wireless adapter due to + * "wireless" specific problems... + * Note : the list of counter and statistics in net_device_stats + * is already pretty exhaustive, and you should use that first. + * This is only additional stats... + */ +struct iw_discarded +{ + __u32 nwid; /* Rx : Wrong nwid/essid */ + __u32 code; /* Rx : Unable to code/decode (WEP) */ + __u32 fragment; /* Rx : Can't perform MAC reassembly */ + __u32 retries; /* Tx : Max MAC retries num reached */ + __u32 misc; /* Others cases */ +}; + +/* + * Packet/Time period missed in the wireless adapter due to + * "wireless" specific problems... + */ +struct iw_missed +{ + __u32 beacon; /* Missed beacons/superframe */ +}; + +/* + * Quality range (for spy threshold) + */ +struct iw_thrspy +{ + struct sockaddr_t addr; /* Source address (hw/mac) */ + struct iw_quality qual; /* Quality of the link */ + struct iw_quality low; /* Low threshold */ + struct iw_quality high; /* High threshold */ +}; + +/* + * Optional data for scan request + * + * Note: these optional parameters are controlling parameters for the + * scanning behavior, these do not apply to getting scan results + * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and + * provide a merged results with all BSSes even if the previous scan + * request limited scanning to a subset, e.g., by specifying an SSID. + * Especially, scan results are required to include an entry for the + * current BSS if the driver is in Managed mode and associated with an AP. + */ +struct iw_scan_req +{ + __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */ + __u8 essid_len; + __u8 num_channels; /* num entries in channel_list; + * 0 = scan all allowed channels */ + __u8 flags; /* reserved as padding; use zero, this may + * be used in the future for adding flags + * to request different scan behavior */ + struct sockaddr_t bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or + * individual address of a specific BSS */ + + /* + * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using + * the current ESSID. This allows scan requests for specific ESSID + * without having to change the current ESSID and potentially breaking + * the current association. + */ + __u8 essid[IW_ESSID_MAX_SIZE]; + + /* + * Optional parameters for changing the default scanning behavior. + * These are based on the MLME-SCAN.request from IEEE Std 802.11. + * TU is 1.024 ms. If these are set to 0, driver is expected to use + * reasonable default values. min_channel_time defines the time that + * will be used to wait for the first reply on each channel. If no + * replies are received, next channel will be scanned after this. If + * replies are received, total time waited on the channel is defined by + * max_channel_time. + */ + __u32 min_channel_time; /* in TU */ + __u32 max_channel_time; /* in TU */ + + struct iw_freq channel_list[IW_MAX_FREQUENCIES]; +}; + +/* ------------------------- WPA SUPPORT ------------------------- */ + +/* + * Extended data structure for get/set encoding (this is used with + * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_* + * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and + * only the data contents changes (key data -> this structure, including + * key data). + * + * If the new key is the first group key, it will be set as the default + * TX key. Otherwise, default TX key index is only changed if + * IW_ENCODE_EXT_SET_TX_KEY flag is set. + * + * Key will be changed with SIOCSIWENCODEEXT in all cases except for + * special "change TX key index" operation which is indicated by setting + * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY. + * + * tx_seq/rx_seq are only used when respective + * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal + * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start + * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally + * used only by an Authenticator (AP or an IBSS station) to get the + * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and + * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for + * debugging/testing. + */ +struct iw_encode_ext +{ + __u32 ext_flags; /* IW_ENCODE_EXT_* */ + __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ + struct sockaddr_t addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast + * (group) keys or unicast address for + * individual keys */ + __u16 alg; /* IW_ENCODE_ALG_* */ + __u16 key_len; +#ifdef __CC_ARM //Fix Keil compile error, must modify sizeof iw_encode_ext - Alex Fang + __u8 key[1]; +#else + __u8 key[0]; +#endif +}; + +/* SIOCSIWMLME data */ +struct iw_mlme +{ + __u16 cmd; /* IW_MLME_* */ + __u16 reason_code; + struct sockaddr_t addr; +}; + +/* SIOCSIWPMKSA data */ +#define IW_PMKSA_ADD 1 +#define IW_PMKSA_REMOVE 2 +#define IW_PMKSA_FLUSH 3 + +#define IW_PMKID_LEN 16 + +struct iw_pmksa +{ + __u32 cmd; /* IW_PMKSA_* */ + struct sockaddr_t bssid; + __u8 pmkid[IW_PMKID_LEN]; +}; + +/* IWEVMICHAELMICFAILURE data */ +struct iw_michaelmicfailure +{ + __u32 flags; + struct sockaddr_t src_addr; + __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ +}; + +/* IWEVPMKIDCAND data */ +#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */ +struct iw_pmkid_cand +{ + __u32 flags; /* IW_PMKID_CAND_* */ + __u32 index; /* the smaller the index, the higher the + * priority */ + struct sockaddr_t bssid; +}; + +/* ------------------------ WIRELESS STATS ------------------------ */ +/* + * Wireless statistics (used for /proc/net/wireless) + */ +struct iw_statistics +{ + __u16 status; /* Status + * - device dependent for now */ + + struct iw_quality qual; /* Quality of the link + * (instant/mean/max) */ + struct iw_discarded discard; /* Packet discarded counts */ + struct iw_missed miss; /* Packet missed counts */ +}; + +/* ------------------------ IOCTL REQUEST ------------------------ */ +/* + * This structure defines the payload of an ioctl, and is used + * below. + * + * Note that this structure should fit on the memory footprint + * of iwreq (which is the same as ifreq), which mean a max size of + * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... + * You should check this when increasing the structures defined + * above in this file... + */ +union iwreq_data +{ + /* Config - generic */ + char name[IFNAMSIZ]; + /* Name : used to verify the presence of wireless extensions. + * Name of the protocol/provider... */ + + struct iw_point essid; /* Extended network name */ + struct iw_param nwid; /* network id (or domain - the cell) */ + struct iw_freq freq; /* frequency or channel : + * 0-1000 = channel + * > 1000 = frequency in Hz */ + + struct iw_param sens; /* signal level threshold */ + struct iw_param bitrate; /* default bit rate */ + struct iw_param txpower; /* default transmit power */ + struct iw_param rts; /* RTS threshold threshold */ + struct iw_param frag; /* Fragmentation threshold */ + __u32 mode; /* Operation mode */ + struct iw_param retry; /* Retry limits & lifetime */ + + struct iw_point encoding; /* Encoding stuff : tokens */ + struct iw_param power; /* PM duration/timeout */ + struct iw_quality qual; /* Quality part of statistics */ + + struct sockaddr_t ap_addr; /* Access point address */ + struct sockaddr_t addr; /* Destination address (hw/mac) */ + + struct iw_param param; /* Other small parameters */ + struct iw_point data; /* Other large parameters */ + struct iw_point passphrase; /* Extended network name */ +}; + +/* + * The structure to exchange data for ioctl. + * This structure is the same as 'struct ifreq', but (re)defined for + * convenience... + * Do I need to remind you about structure size (32 octets) ? + */ +struct iwreq +{ +#if 0 + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + } ifr_ifrn; +#endif + char ifr_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ + + /* Data part (defined just above) */ + union iwreq_data u; +}; + +/* -------------------------- IOCTL DATA -------------------------- */ +/* + * For those ioctl which want to exchange mode data that what could + * fit in the above structure... + */ + +/* + * Range of parameters + */ + +struct iw_range +{ + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Wireless event capability bitmasks */ + __u32 event_capa[6]; + + /* signal level threshold range */ + __s32 sensitivity; + + /* Quality of link & SNR stuff */ + /* Quality range (link, level, noise) + * If the quality is absolute, it will be in the range [0 ; max_qual], + * if the quality is dBm, it will be in the range [max_qual ; 0]. + * Don't forget that we use 8 bit arithmetics... */ + struct iw_quality max_qual; /* Quality of the link */ + /* This should contain the average/typical values of the quality + * indicator. This should be the threshold between a "good" and + * a "bad" link (example : monitor going from green to orange). + * Currently, user space apps like quality monitors don't have any + * way to calibrate the measurement. With this, they can split + * the range between 0 and max_qual in different quality level + * (using a geometric subdivision centered on the average). + * I expect that people doing the user space apps will feedback + * us on which value we need to put in each driver... */ + struct iw_quality avg_qual; /* Quality of the link */ + + /* Rates */ + __u8 num_bitrates; /* Number of entries in the list */ + __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */ + + /* RTS threshold */ + __s32 min_rts; /* Minimal RTS threshold */ + __s32 max_rts; /* Maximal RTS threshold */ + + /* Frag threshold */ + __s32 min_frag; /* Minimal frag threshold */ + __s32 max_frag; /* Maximal frag threshold */ + + /* Power Management duration & timeout */ + __s32 min_pmp; /* Minimal PM period */ + __s32 max_pmp; /* Maximal PM period */ + __s32 min_pmt; /* Minimal PM timeout */ + __s32 max_pmt; /* Maximal PM timeout */ + __u16 pmp_flags; /* How to decode max/min PM period */ + __u16 pmt_flags; /* How to decode max/min PM timeout */ + __u16 pm_capa; /* What PM options are supported */ + + /* Encoder stuff */ + __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */ + __u8 num_encoding_sizes; /* Number of entry in the list */ + __u8 max_encoding_tokens; /* Max number of tokens */ + /* For drivers that need a "login/passwd" form */ + __u8 encoding_login_index; /* token index for login token */ + + /* Transmit power */ + __u16 txpower_capa; /* What options are supported */ + __u8 num_txpower; /* Number of entries in the list */ + __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */ + + /* Wireless Extension version info */ + __u8 we_version_compiled; /* Must be WIRELESS_EXT */ + __u8 we_version_source; /* Last update of source */ + + /* Retry limits and lifetime */ + __u16 retry_capa; /* What retry options are supported */ + __u16 retry_flags; /* How to decode max/min retry limit */ + __u16 r_time_flags; /* How to decode max/min retry life */ + __s32 min_retry; /* Minimal number of retries */ + __s32 max_retry; /* Maximal number of retries */ + __s32 min_r_time; /* Minimal retry lifetime */ + __s32 max_r_time; /* Maximal retry lifetime */ + + /* Frequency */ + __u16 num_channels; /* Number of channels [0; num - 1] */ + __u8 num_frequency; /* Number of entry in the list */ + struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ + /* Note : this frequency list doesn't need to fit channel numbers, + * because each entry contain its channel index */ + + __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ + + /* More power management stuff */ + __s32 min_pms; /* Minimal PM saving */ + __s32 max_pms; /* Maximal PM saving */ + __u16 pms_flags; /* How to decode max/min PM saving */ + + /* All available modulations for driver (hw may support less) */ + __s32 modul_capa; /* IW_MODUL_* bit field */ + + /* More bitrate stuff */ + __u32 bitrate_capa; /* Types of bitrates supported */ +}; + +/* + * Private ioctl interface information + */ + +struct iw_priv_args +{ + __u32 cmd; /* Number of the ioctl to issue */ + __u16 set_args; /* Type and number of args */ + __u16 get_args; /* Type and number of args */ + char name[IFNAMSIZ]; /* Name of the extension */ +}; + +/* ----------------------- WIRELESS EVENTS ----------------------- */ +/* + * Wireless events are carried through the rtnetlink socket to user + * space. They are encapsulated in the IFLA_WIRELESS field of + * a RTM_NEWLINK message. + */ + +/* + * A Wireless Event. Contains basically the same data as the ioctl... + */ +struct iw_event +{ + __u16 len; /* Real lenght of this stuff */ + __u16 cmd; /* Wireless IOCTL */ + union iwreq_data u; /* IOCTL fixed payload */ +}; + +/* Size of the Event prefix (including padding and alignement junk) */ +#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data)) +/* Size of the various events */ +#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ) +#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32)) +#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq)) +#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param)) +#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr_t)) +#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality)) + +/* iw_point events are special. First, the payload (extra data) come at + * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second, + * we omit the pointer, so start at an offset. */ +#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ + (char *) NULL) +#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ + IW_EV_POINT_OFF) + +/* Size of the Event prefix when packed in stream */ +#define IW_EV_LCP_PK_LEN (4) +/* Size of the various events when packed in stream */ +#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ) +#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32)) +#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq)) +#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) +#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr_t)) +#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) +#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4) + +#define IW_EXT_STR_FOURWAY_DONE "WPA/WPA2 handshake done" +#define IW_EXT_STR_RECONNECTION_FAIL "RECONNECTION FAILURE" +#define IW_EVT_STR_STA_ASSOC "STA Assoc" +#define IW_EVT_STR_STA_DISASSOC "STA Disassoc" +#define IW_EVT_STR_SEND_ACTION_DONE "Send Action Done" +#define IW_EVT_STR_NO_NETWORK "No Assoc Network After Scan Done" +#endif /* _LINUX_WIRELESS_H */ diff --git a/USDK/component/common/drivers/wlan/realtek/src/osdep/wlan_intf.h b/USDK/component/common/drivers/wlan/realtek/src/osdep/wlan_intf.h new file mode 100644 index 0000000..b586e0c --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/osdep/wlan_intf.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * Copyright (c) 2013-2016 Realtek Semiconductor Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ +#ifndef __WLAN_INTF_H__ +#define __WLAN_INTF_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#include +#include "wifi_constants.h" + +#ifndef WLAN0_IDX + #define WLAN0_IDX 0 +#endif +#ifndef WLAN1_IDX + #define WLAN1_IDX 1 +#endif +#ifndef WLAN_UNDEF + #define WLAN_UNDEF -1 +#endif + +/***********************************************************/ +/* +struct sk_buff { + // These two members must be first. + struct sk_buff *next; // Next buffer in list + struct sk_buff *prev; // Previous buffer in list + + struct sk_buff_head *list; // List we are on + unsigned char *head; // Head of buffer + unsigned char *data; // Data head pointer + unsigned char *tail; // Tail pointer + unsigned char *end; //End pointer + struct net_device *dev; //Device we arrived on/are leaving by + unsigned int len; // Length of actual data +}; +*/ +/************************************************************/ + +//----- ------------------------------------------------------------------ +// Wlan Interface opened for upper layer +//----- ------------------------------------------------------------------ +int rltk_wlan_init(int idx_wlan, rtw_mode_t mode); //return 0: success. -1:fail +void rltk_wlan_deinit(void); +void rltk_wlan_deinit_fastly(void); +int rltk_wlan_start(int idx_wlan); +void rltk_wlan_statistic(unsigned char idx); +unsigned char rltk_wlan_running(unsigned char idx); // interface is up. 0: interface is down +int rltk_wlan_control(unsigned long cmd, void *data); +int rltk_wlan_handshake_done(void); +int rltk_wlan_rf_on(void); +int rltk_wlan_rf_off(void); +int rltk_wlan_check_bus(void); +int rltk_wlan_wireless_mode(unsigned char mode); +int rltk_wlan_set_wps_phase(unsigned char is_trigger_wps); +int rtw_ps_enable(int enable); +int rltk_wlan_is_connected_to_ap(void); + + +#ifdef __cplusplus +} +#endif + + + +#endif //#ifndef __WLAN_INTF_H__ diff --git a/USDK/component/common/drivers/wlan/realtek/src/wifi_skbuf.c b/USDK/component/common/drivers/wlan/realtek/src/wifi_skbuf.c new file mode 100644 index 0000000..1e4dd3f --- /dev/null +++ b/USDK/component/common/drivers/wlan/realtek/src/wifi_skbuf.c @@ -0,0 +1,14 @@ +#include +#include +#undef MAX_SKB_BUF_NUM +#define MAX_SKB_BUF_NUM 16 + +// DO NOT modify this structure +struct skb_data { + struct list_head list; + unsigned char buf[MAX_SKB_BUF_SIZE]; + atomic_t ref; +}; + +SRAM_BD_DATA_SECTION +struct skb_data skb_data_pool[MAX_SKB_BUF_NUM]; diff --git a/USDK/component/common/example/bcast/example_bcast.c b/USDK/component/common/example/bcast/example_bcast.c new file mode 100644 index 0000000..dfb1675 --- /dev/null +++ b/USDK/component/common/example/bcast/example_bcast.c @@ -0,0 +1,81 @@ +#include "FreeRTOS.h" +#include "task.h" +#include + +#include +#include +#include + +static void example_bcast_thread(void *param) +{ + int socket = -1; + int broadcast = 1; + struct sockaddr_in bindAddr; + uint16_t port = 49152; + unsigned char packet[1024]; + + // Create socket + if((socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("ERROR: socket failed\n"); + goto err; + } + + // Set broadcast socket option + if(setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0){ + printf("ERROR: setsockopt failed\n"); + goto err; + } + + // Set the bind address + memset(&bindAddr, 0, sizeof(bindAddr)); + bindAddr.sin_family = AF_INET; + bindAddr.sin_port = htons(port); + bindAddr.sin_addr.s_addr = INADDR_ANY; + if(bind(socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr)) < 0){ + printf("ERROR: bind failed\n"); + goto err; + } + + + while(1) { + // Receive broadcast + int packetLen; + struct sockaddr from; + struct sockaddr_in *from_sin = (struct sockaddr_in*) &from; + socklen_t fromLen = sizeof(from); + + if((packetLen = recvfrom(socket, &packet, sizeof(packet), 0, &from, &fromLen)) >= 0) { + uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr; + uint16_t from_port = ntohs(from_sin->sin_port); + printf("recvfrom - %d bytes from %d.%d.%d.%d:%d\n", packetLen, ip[0], ip[1], ip[2], ip[3], from_port); + } + + // Send broadcast + if(packetLen > 0) { + int sendLen; + struct sockaddr to; + struct sockaddr_in *to_sin = (struct sockaddr_in*) &to; + to_sin->sin_family = AF_INET; + to_sin->sin_port = htons(port); + to_sin->sin_addr.s_addr = INADDR_ANY; + + if((sendLen = sendto(socket, packet, packetLen, 0, &to, sizeof(struct sockaddr))) < 0) + printf("ERROR: sendto broadcast\n"); + else + printf("sendto - %d bytes to broadcast:%d\n", sendLen, port); + } + } + + +err: + printf("ERROR: broadcast example failed\n"); + close(socket); + vTaskDelete(NULL); + return; +} + +void example_bcast(void) +{ + if(xTaskCreate(example_bcast_thread, ((const char*)"example_bcast_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/USDK/component/common/example/bcast/example_bcast.h b/USDK/component/common/example/bcast/example_bcast.h new file mode 100644 index 0000000..56e557c --- /dev/null +++ b/USDK/component/common/example/bcast/example_bcast.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_BCAST_H +#define EXAMPLE_BCAST_H + +void example_bcast(void); + +#endif /* EXAMPLE_BCAST_H */ diff --git a/USDK/component/common/example/bcast/readme.txt b/USDK/component/common/example/bcast/readme.txt new file mode 100644 index 0000000..95e70a2 --- /dev/null +++ b/USDK/component/common/example/bcast/readme.txt @@ -0,0 +1,28 @@ +LWIP BROADCAST EXAMPLE + +Description: +Listen broadcast message on port 49152. +Send packet with the content of received packet to broadcast address. + +Configuration: +[lwipopts.h] + #define LWIP_UDP 1 +[platform_opts.h] + #define CONFIG_EXAMPLE_BCAST 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A broadcast example thread will be started automatically when booting. + +Test: +1. Prepare a NB and connect to the same AP Ameba connected. +2. NB: iperf -c 192.168.1.255 -t 60 -i 1 -p 49152 -u +3. The recv/send messages should be printed out on Ameba console. +4. Use sniffer to make sure the packets send from Ameba are broadcast messages. + +Note: +If you encounter some message like: + ERROR: sendto broadcast + [Driver]: skb_unavailable=1 in last 2 seconds +It means that the skb buffer is not enough for the massive UDP packets to be sent. +If you want to prevent the error you can add some delay time between sending packets or enlarge the skb buffer configuration. \ No newline at end of file diff --git a/USDK/component/common/example/cJSON/cJSON_example.c b/USDK/component/common/example/cJSON/cJSON_example.c new file mode 100644 index 0000000..f336a36 --- /dev/null +++ b/USDK/component/common/example/cJSON/cJSON_example.c @@ -0,0 +1,84 @@ +#include "cmsis_os.h" +#include + +#define malloc pvPortMalloc +#define free vPortFree + +/* The data structure for this example + +{ + "Motion_Sensor" : "i", + "Light" : { + "Red" : "0", + "Green" : "0", + "Blue" : "0", + } + +} + +*/ +static void gen_json_data(int i, int r, int g, int b) +{ + + + cJSON_Hooks memoryHook; + + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + + + cJSON *IOTJSObject = NULL, *colorJSObject = NULL; + char *iot_json = NULL; + + if((IOTJSObject = cJSON_CreateObject()) != NULL) { + + cJSON_AddItemToObject(IOTJSObject, "Motion_Sensor", cJSON_CreateNumber(i)); + cJSON_AddItemToObject(IOTJSObject, "Light", colorJSObject = cJSON_CreateObject()); + + cJSON_AddItemToObject(colorJSObject, "Red", cJSON_CreateNumber(r)); + cJSON_AddItemToObject(colorJSObject, "Green", cJSON_CreateNumber(g)); + cJSON_AddItemToObject(colorJSObject, "Blue", cJSON_CreateNumber(b)); + + iot_json = cJSON_Print(IOTJSObject); + cJSON_Delete(IOTJSObject); + + } + +} + +static void handle_json_data(char *iot_json) +{ + cJSON_Hooks memoryHook; + + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + + + cJSON *IOTJSObject, *sensorJSObject, *lightJSObject, *redJSObject, *greenJSObject, *blueJSObject; + int sensor_data, red, green, blue; + + if((IOTJSObject = cJSON_Parse(iot_json)) != NULL) { + sensorJSObject = cJSON_GetObjectItem(IOTJSObject, "Motion_Sensor"); + if(sensorJSObject) + sensor_data = sensorJSObject->valueint; + + lightJSObject = cJSON_GetObjectItem(IOTJSObject, "Light"); + + if(lightJSObject){ + redJSObject = cJSON_GetObjectItem(lightJSObject, "Red"); + greenJSObject = cJSON_GetObjectItem(lightJSObject, "Green"); + blueJSObject = cJSON_GetObjectItem(lightJSObject, "Blue"); + + if(redJSObject) + red = redJSObject->valueint; + if(greenJSObject) + green = greenJSObject->valueint; + if(blueJSObject) + blue = blueJSObject->valueint; + } + + cJSON_Delete(IOTJSObject); + } +} diff --git a/USDK/component/common/example/dct/README.txt b/USDK/component/common/example/dct/README.txt new file mode 100644 index 0000000..f3441bd --- /dev/null +++ b/USDK/component/common/example/dct/README.txt @@ -0,0 +1,16 @@ +DCT example + +Description: +This example shows device configuration table API usage, and user can use DCT api to replace file system. + +Configuration: +1. [platform_opts.h] + #define CONFIG_EXAMPLE_DCT 1 + +Execution: +it will show: + variable0: value0 + variable1: value1 + Delete variable0 success. + Remaining amount: 61 +if DCT is correctly used. \ No newline at end of file diff --git a/USDK/component/common/example/dct/example_dct.c b/USDK/component/common/example/dct/example_dct.c new file mode 100644 index 0000000..a55d58d --- /dev/null +++ b/USDK/component/common/example/dct/example_dct.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include + +#if CONFIG_EXAMPLE_DCT + +#define DCT_BEGIN_ADDR 0x100000 /*!< DCT begin address of flash, ex: 0x100000 = 1M */ +#define MODULE_NUM 6 /*!< max number of module */ +#define VARIABLE_NAME_SIZE 32 /*!< max size of the variable name */ +#define VARIABLE_VALUE_SIZE 32 /*!< max size of the variable value */ + +static char example_dct_module[] = "dct_test_module"; +static char example_dct_variable0[] = "variable0"; +static char example_dct_variable1[] = "variable1"; +static char example_dct_value0[] = "value0"; +static char example_dct_value1[] = "value1"; + +void example_dct_thread(void* param){ + int32_t ret = -1; + dct_handle_t dct_handle; + char value[16]; + + // format DCT, use for the first time + ret = dct_format(DCT_BEGIN_ADDR, MODULE_NUM, VARIABLE_NAME_SIZE, VARIABLE_VALUE_SIZE, 1); + + // initial DCT + ret = dct_init(DCT_BEGIN_ADDR); + + // register module + ret = dct_register_module(example_dct_module); + + // open module + ret = dct_open_module(&dct_handle, example_dct_module); + + if(ret == DCT_SUCCESS){ + // set test variable 0 + ret = dct_set_variable(&dct_handle, example_dct_variable0, example_dct_value0); + + // set test variable 1 + ret = dct_set_variable(&dct_handle, example_dct_variable1, example_dct_value1); + + // get value of test variable 0 + memset(value, 0, sizeof(value)); + ret = dct_get_variable(&dct_handle, example_dct_variable0, value, sizeof(value)); + if(ret == DCT_SUCCESS) + printf("%s: %s\n", example_dct_variable0, value); + + // get value of test variable 1 + memset(value, 0, sizeof(value)); + ret = dct_get_variable(&dct_handle, example_dct_variable1, value, sizeof(value)); + if(ret == DCT_SUCCESS) + printf("%s: %s\n", example_dct_variable1, value); + + // delete test variable 0 + ret = dct_delete_variable(&dct_handle, example_dct_variable0); + + // get value of test variable 0 + memset(value, 0, sizeof(value)); + ret = dct_get_variable(&dct_handle, example_dct_variable0, value, sizeof(value)); + if(ret == DCT_ERR_NOT_FIND) + printf("Delete %s success.\n", example_dct_variable0); + + // get variable remaining amount + ret = dct_remain_variable(&dct_handle); + if(ret > 0) + printf("Remaining variable amount:%d\n", ret); + + // close module + ret = dct_close_module(&dct_handle); + } + + vTaskDelete(NULL); +} + + +void example_dct(void) +{ + if(xTaskCreate(example_dct_thread, ((const char*)"example_dct_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(example_dct_thread) failed", __FUNCTION__); +} + +#endif // #if CONFIG_DCT diff --git a/USDK/component/common/example/dct/example_dct.h b/USDK/component/common/example/dct/example_dct.h new file mode 100644 index 0000000..ea0b4f7 --- /dev/null +++ b/USDK/component/common/example/dct/example_dct.h @@ -0,0 +1,7 @@ +#ifndef _EXAMPLE_DCT_H +#define _EXAMPLE_DCT_H + +void example_dct(void); + +#endif /* _EXAMPLE_DCT_H */ + diff --git a/USDK/component/common/example/eap/example_eap.c b/USDK/component/common/example/eap/example_eap.c new file mode 100644 index 0000000..05bbe63 --- /dev/null +++ b/USDK/component/common/example/eap/example_eap.c @@ -0,0 +1,164 @@ +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include + +#if CONFIG_EXAMPLE_EAP + +// get config arguments from wifi_eap_config.c +extern char *eap_target_ssid; +extern char *eap_identity; +extern char *eap_password; +extern const unsigned char *eap_ca_cert; +extern const unsigned char *eap_client_cert; +extern const unsigned char *eap_client_key; +extern char *eap_client_key_pwd; + +void example_eap_config(void){ + eap_target_ssid = "Test_eap"; + eap_identity = "guest2"; + eap_password = "test2"; + +/* + Set client cert is only used for EAP-TLS connection. + If you are not using EAP-TLS method, no need to set eap_client_cert and eap_client_key value. (leave them to NULL value) +*/ +/* + eap_client_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIC9TCCAd0CAQIwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \ +"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \ +"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \ +"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE0MTEzNjMy\r\n" \ +"WhcNMTcwMzE0MTEzNjMyWjBxMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \ +"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGTAXBgNVBAMUEHVzZXJAZXhhbXBsZS5j\r\n" \ +"b20xHzAdBgkqhkiG9w0BCQEWEHVzZXJAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcN\r\n" \ +"AQEBBQADgY0AMIGJAoGBAODvCWRRjVQnUyQS/OqHS8MA94Dc5UOtLagKTOMJayB5\r\n" \ +"3MZyreWBkNg6sDfDG6OSD9tkVzwcp8CtZNflJc3i+d+nAnPM+kJedPJN5YVO+uwc\r\n" \ +"+K+QObH7fEOq8hnFIvOtYOfnMAxQKaVIKk0EOqqQv06BDvLyxoDCZNpAn4NQ8ZkR\r\n" \ +"AgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAItqpmFftRu8ugTy4fRFwpjJNUuMRe83\r\n" \ +"Pm5Dv3V/byCHHdmIy0UI+6ZiMEtYrpvz4ZPgk0BDeytYooT7/kEUb8niQ64bDLYo\r\n" \ +"NcXctCmn5fjyX2M6Z3lQXCxX0XdFiukWlR21w4HO0nx7OJjrcjdpP9Tyk/kzCFl7\r\n" \ +"pblIavkfSmFtcxzcp0IoCupkUjFkA+MftZF82eQx4bE0jjiw2KgGwnzyYAdgtFXv\r\n" \ +"Ednj3ZyOuTlOQNGJgLQxyHooEJ/Tol/8p9EO5S6eQaHgZhbGP3AZ3SWV5oA0e6eT\r\n" \ +"D5JXti/LhyZhcbbJFawGXFI96ZOpHJ0EW12Osx/21oqmMp12AotS5Vw=\r\n" \ +"-----END CERTIFICATE-----\r\n"; + eap_client_key = \ +"-----BEGIN RSA PRIVATE KEY-----\r\n" \ +"Proc-Type: 4,ENCRYPTED\r\n" \ +"DEK-Info: DES-EDE3-CBC,79675299AD6E2237\r\n" \ +"\r\n" \ +"ZYY2hv1PYEsrhYbCip98XNpS6XxbntynEEp6aO9UgWeQ4I1pNOUptPUE+yNhbA7X\r\n" \ +"59ueT3yzx5L2ObImlJ3eIEvWq+iB8DdcPqFAo3c4dgfw/wPEhmxVPKvIyDQfaEuA\r\n" \ +"kWUno6b07n5uLTpQjIXQSdMTMYjYS+yPQy7ONC/vl/Ce+RMzrQAZkp5xcNNarUpl\r\n" \ +"2J1D2t+eRih/zRrgeVXztMiW2uyIT5a0IPoeBTPkPVb00kWYzn8eT9doN/ZCyr83\r\n" \ +"mv/uXF5ZOHnSNleOn1NiCZ8Uu3SHnmGhMBBMI75OghpEezQQCmtefYvtRxzGjMVB\r\n" \ +"UoRIlbATAleUjk3bmqRxfA2QZJj/GFWc9grxEerHWrdThSQ0w+fvwKBjTmEtUO2+\r\n" \ +"stKBJQi9RKFq4naM8UhtxojHIscXCx/wKrRZHS4QJYOQYelzfhTRUuTf3Czm/iTh\r\n" \ +"MQvX7dITNlLE3SW2MjzHb2ON9qUaKVnQPk53DO1zYgoxgDbQrw6FXDNMtYVv8SYf\r\n" \ +"JJZp66jGX6e1t4ziPHVqlDi5D2nWQ2DPNHO/rsoydA7icncKsC0iVzeUm7XgesxD\r\n" \ +"QEZoQIQDVS1aRE7qJCk9S2Hfe5Gfqnrp4110YuN/4khjMW2cOCKa/Yjgjyy2QQXT\r\n" \ +"nn6dBAeSWGzRM059VzhOyls5FIfnJIisZvF3JG518SzBU/YUGHEVN1XsfDS2M9/q\r\n" \ +"VkqhJ8/vbmIddKGeYULYW+xs3LvU1hnWiOodd9tuSeg5PxAbkJsV1nW06mVkgBqA\r\n" \ +"zqqEvwvY+6+9QW4PClKNKSocvM6yC+uhRi0sOZ+ckOv7f+uuMyw5FQ==\r\n" \ +"-----END RSA PRIVATE KEY-----\r\n"; + eap_client_key_pwd = "testca"; +*/ + eap_client_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIC9zCCAd8CAQMwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \ +"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \ +"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \ +"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE1MDgwNzEx\r\n" \ +"WhcNMTcwMzE1MDgwNzExWjBzMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \ +"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGjAYBgNVBAMUEXVzZXIyQGV4YW1wbGUu\r\n" \ +"Y29tMSAwHgYJKoZIhvcNAQkBFhF1c2VyMkBleGFtcGxlLmNvbTCBnzANBgkqhkiG\r\n" \ +"9w0BAQEFAAOBjQAwgYkCgYEAqESlV4OYfBcIgZ+Cs8mWpiBjhvKoa0/kIe7saqhC\r\n" \ +"e5q4snox0jdkUpLcc4vOs3vQ7ZGnimqTltA9oF6XNUzTWW4vlJTKEfrCWK085l7c\r\n" \ +"DHFvHavH3E6vuP71lI7jq4PLXbo2TvZK+uBul4ozjzVWihaZBtz8eLHq446h/D/p\r\n" \ +"kzkCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAAfhVAIkNdeeUNJud720uUHVnIcxz\r\n" \ +"GXWI+Svi1qchuTEnRNhLwXmnE+A0WWSHyfdR6FvzdT3xtz3K50iOif8jY2gCGkSK\r\n" \ +"8RjKr97228SwbrGO9y9+dYIjH1uz9cBpoVKcpzdsWpKObrDPDYyReHSWo99jM2+O\r\n" \ +"vfJxnBw4PLiBj7Q0/dpd6o4JXyp7Cxa0mB4/+cZqjCzzuKfuK3WP7j6laMCV6mg4\r\n" \ +"wRZ528IdwDqB7OOqsDm1PVQM8vzny9PM6ikWUCRTVNQJN8RDLkrHR3FRjy15YLdt\r\n" \ +"yOfDqVnT/z0wGBaxnNziSJjqPGHPpRi4bJFGXwXOhtknKmciKzfj9/npoQ==\r\n" \ +"-----END CERTIFICATE-----\r\n"; + eap_client_key = \ +"-----BEGIN RSA PRIVATE KEY-----\r\n" \ +"MIICXQIBAAKBgQCoRKVXg5h8FwiBn4KzyZamIGOG8qhrT+Qh7uxqqEJ7mriyejHS\r\n" \ +"N2RSktxzi86ze9DtkaeKapOW0D2gXpc1TNNZbi+UlMoR+sJYrTzmXtwMcW8dq8fc\r\n" \ +"Tq+4/vWUjuOrg8tdujZO9kr64G6XijOPNVaKFpkG3Px4serjjqH8P+mTOQIDAQAB\r\n" \ +"AoGARI+LyweshssfxSkIKVc3EcNaqi6PHwJzUrw2ChM624AkR1xwllXJg7ehKVdK\r\n" \ +"xmjprRLO8CASuL1qjsBb3fTKnBl+sIVxIFS0AI4Y3ri8VUKbangvSsI7pCzAFry7\r\n" \ +"p1gmy9WWRV2ZEa+dV8xcrjb3bloT7hcdeLehgBCvExJIQM0CQQDXlSAKdW3AhYyj\r\n" \ +"1A+pfyBSGxJbpSwNyyWgwHIHHjxendxmdUbrc8EbAu1eNKbP58TLgdCZsKcMonAv\r\n" \ +"MY1Y2/nnAkEAx9CrUaCU8pJqXTRypM5JtexLKnYMJhpnA9uUILBQOq4Oe0eruyF5\r\n" \ +"SaSxhyJYXY491ahWYPF0PTb3jkUhoN+l3wJBAJZthjgGDJlEFwjSFkOtYz4nib3N\r\n" \ +"GVpeoFj1MBvrazCScpJDz0LIOLzCZCNSFfwIu3dNk+NKMqZMSn+D0h9pD40CQQC5\r\n" \ +"K9n4NXaTLbjAU2CC9mE85JPr76XmkcUxwAWQHZTcLH1jJdIyAx1hb+zNLLjzSmRn\r\n" \ +"Yi9ae6ibKhtUjyBQ87HFAkA2Bb3z7NUx+AA2g2HZocFZFShBxylACyQkl8FAFZtf\r\n" \ +"osudmKdFQHyAWuBMex4tpz/OLTqJ1ecL1JQeC7OvlpEX\r\n" \ +"-----END RSA PRIVATE KEY-----\r\n"; + +/* + Verify server's certificate is an optional feature. + If you want to use it please make sure ENABLE_EAP_SSL_VERIFY_SERVER in platform_opts.h is set to 1, + and the eap_ca_cert is set correctly. +*/ + eap_ca_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIEpzCCA4+gAwIBAgIJAPvZaozpdfjkMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\n" \ +"VQQGEwJGUjEPMA0GA1UECBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTAT\r\n" \ +"BgNVBAoTDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\r\n" \ +"ZS5jb20xJjAkBgNVBAMTHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\r\n" \ +"DTE2MDMxNDExMjU0OVoXDTE2MDQxMzExMjU0OVowgZMxCzAJBgNVBAYTAkZSMQ8w\r\n" \ +"DQYDVQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhh\r\n" \ +"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG\r\n" \ +"A1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\r\n" \ +"DQEBAQUAA4IBDwAwggEKAoIBAQC9pireu0aCDLNfMaGv3vId7RXjUhQwSK0jV2Oc\r\n" \ +"SyvlKWH3P/N+5kLrP2iL6SCzyETVDXZ0vOsAMjcBF0zHp16prXV0d51cTUqeWBb0\r\n" \ +"I5UnGxleIuuOfSg8zLUJoBWZPqLv++eZ5WgOKHt7SXocjvg7TU5t/TMB0Y8OCz3H\r\n" \ +"CW2vJ/XKMgMA9HDUu4g57cJu88i1JPRpyFaz/HIQBc7+UNb9z+q09uTZKWTmEMqi\r\n" \ +"E2U0EEIs7EtbxnOze1/8C4XNlmztrEdwvu6UEBU/TFkUoh9M646NkkBK7wP9n9pv\r\n" \ +"T0nPQRJiiCrICzVqUtlEi9lIKpbBSMbQ0KzrGF7lGTgm4rz9AgMBAAGjgfswgfgw\r\n" \ +"HQYDVR0OBBYEFIVyecka74kvOKIW0BjlTc/B+a2NMIHIBgNVHSMEgcAwgb2AFIVy\r\n" \ +"ecka74kvOKIW0BjlTc/B+a2NoYGZpIGWMIGTMQswCQYDVQQGEwJGUjEPMA0GA1UE\r\n" \ +"CBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTATBgNVBAoTDEV4YW1wbGUg\r\n" \ +"SW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xJjAkBgNVBAMT\r\n" \ +"HUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggkA+9lqjOl1+OQwDAYDVR0T\r\n" \ +"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZYHM26sxbKOckVqJJ1QY0U2QFlGP\r\n" \ +"1GYd8v27znxdnRmSonDvv3GjFfhwoyDk0JUuxkK/33ikCxihrgoO/EQTY9BV2OpW\r\n" \ +"qkB1PDtb3i5ZRNvfjmW0pVA4p+GmdTGaEE5pTlcVnorzVrUeFKaZakb+IDFYzmeF\r\n" \ +"xp8B3Bb5wvinDligLOaJnSlgS8QeeIab9HZfaVTTuPmVK6zE6D54Y0dJPnykvDdE\r\n" \ +"cGN0FC+migfilFjJgkDJ0r78nwes55L8zjoofiZuO03rrHww6ARc3v1jYzAufddk\r\n" \ +"QTiZHgjlMQb2XXMmXLn8kBgoDnqkXFNe8j0h8uxIJSrjOoIyn1h1wvX5/w==\r\n" \ +"-----END CERTIFICATE-----\r\n"; + +} + +static void example_eap_thread(void *method){ + example_eap_config(); + + if(strcmp(method, "tls") == 0){ + // tls must present client_cert, client_key + eap_start("tls"); + } + else if(strcmp(method, "peap") == 0){ + eap_start("peap"); + } + else if(strcmp(method, "ttls") == 0){ + eap_start("ttls"); + } + else + printf("Invalid method\n"); + + vTaskDelete(NULL); +} + +void example_eap(char *method){ + if(xTaskCreate(example_eap_thread, ((const char*)"example_eap_thread"), 1024, method, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate failed\n", __FUNCTION__); +} + +#endif /* CONFIG_EXAMPLE_EAP */ \ No newline at end of file diff --git a/USDK/component/common/example/eap/example_eap.h b/USDK/component/common/example/eap/example_eap.h new file mode 100644 index 0000000..2eefcaf --- /dev/null +++ b/USDK/component/common/example/eap/example_eap.h @@ -0,0 +1,9 @@ +#ifndef EXAMPLE_EAP_H +#define EXAMPLE_EAP_H + +#include +#include "platform_opts.h" + +void example_eap(char *method); + +#endif diff --git a/USDK/component/common/example/eap/readme.txt b/USDK/component/common/example/eap/readme.txt new file mode 100644 index 0000000..4ec0730 --- /dev/null +++ b/USDK/component/common/example/eap/readme.txt @@ -0,0 +1,34 @@ +802.1X EAP METHOD SUPPLICANT EXAMPLE + +Description: +Use 802.1X EAP methods to connect to AP and authenticate with backend radius server. +Current supported methods are EAP-TLS, PEAPv0/EAP-MSCHAPv2, and EAP-TTLS/MSCHAPv2. + +Configuration: +Modify the argument of example_eap() in example_entry.c to set which EAP methods you want to use. +Modify the connection config (ssid, identity, password, cert) in example_eap_config() of example_eap.c based on your server's setting. +[FreeRTOSConfig.h] + #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 70 * 1024 ) ) +[platform_opts.h] + # define CONFIG_EXAMPLE_EAP 1 + + // Turn on/off the specified method + # define CONFIG_ENABLE_PEAP 1 + # define CONFIG_ENABLE_TLS 1 + # define CONFIG_ENABLE_TTLS 1 + + // If you want to verify the certificate of radius server, turn this on + # define ENABLE_EAP_SSL_VERIFY_SERVER 1 + +Execution: +An EAP connection thread will be started automatically when booting. + +Note: +Please make sure the lib_wps, polarssl, ssl_ram_map are also builded. + +If the connection failed, you can try the following directions to make it work: +1. Make sure the config_rsa.h of PolarSSL include the SSL/TLS cipher suite supported by radius server. +2. Set a larger value to SSL_MAX_CONTENT_LEN in config_rsa.h +3. Increase the FreeRTOS heap in FreeRTOSConfig.h, for example you can increase the heap to 80kbytes: + #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 80 * 1024 ) ) +4. Try to change using SW crypto instead of HW crypto. diff --git a/USDK/component/common/example/example_entry.c b/USDK/component/common/example/example_entry.c new file mode 100644 index 0000000..3b628f7 --- /dev/null +++ b/USDK/component/common/example/example_entry.c @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#include +#include "main.h" +#if CONFIG_EXAMPLE_UART_ATCMD +#include "uart_atcmd/example_uart_atcmd.h" +#endif +#ifdef CONFIG_EXAMPLE_MDNS +#include +#endif + +/* + Preprocessor of example +*/ +void pre_example_entry(void) +{ + // +#if defined(CONFIG_EXAMPLE_WLAN_FAST_CONNECT) && CONFIG_EXAMPLE_WLAN_FAST_CONNECT && !CONFIG_EXAMPLE_UART_ATCMD + example_wlan_fast_connect(); +#endif +#ifdef CONFIG_EXAMPLE_MDNS + example_mdns(); +#endif +} + +/* + All of the examples are disabled by default for code size consideration + The configuration is enabled in platform_opts.h +*/ +void example_entry(void) +{ +#if CONFIG_EXAMPLE_UART_ATCMD + example_uart_atcmd(); +#endif +} diff --git a/USDK/component/common/example/example_entry.h b/USDK/component/common/example/example_entry.h new file mode 100644 index 0000000..2cdd514 --- /dev/null +++ b/USDK/component/common/example/example_entry.h @@ -0,0 +1,8 @@ +#ifndef __EXAMPLE_ENTRY_H__ +#define __EXAMPLE_ENTRY_H__ + + +void example_entry(void); +void pre_example_entry(void); + +#endif //#ifndef __EXAMPLE_ENTRY_H__ diff --git a/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.c b/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.c new file mode 100644 index 0000000..beaa281 --- /dev/null +++ b/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.c @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#include +#include +#include +#include "FreeRTOS.h" +#include "task.h" + +typedef int (*get_beacon_frame_func_ptr)(BEACON_INFO_T beacon_frame); +extern get_beacon_frame_func_ptr get_beacon_frame_callback; + +int get_beacon_frame_func(BEACON_INFO_T beacon_frame) +{ + printf("\nbeacon frame_ctl = %02x %02x\n",beacon_frame.frame_ctl[0],beacon_frame.frame_ctl[1]); + printf("\nbeacon duration_id = %02x %02x\n",beacon_frame.duration_id[0],beacon_frame.duration_id[1]); + printf("\nbeacon addr1 = %02x:%02x:%02x:%02x:%02x:%02x\n",\ + beacon_frame.addr1[0],beacon_frame.addr1[1],beacon_frame.addr1[2],beacon_frame.addr1[3],beacon_frame.addr1[4],beacon_frame.addr1[5]); + printf("\nbeacon addr2 = %02x:%02x:%02x:%02x:%02x:%02x\n",\ + beacon_frame.addr2[0],beacon_frame.addr2[1],beacon_frame.addr2[2],beacon_frame.addr2[3],beacon_frame.addr2[4],beacon_frame.addr2[5]); + printf("\nbeacon addr3 = %02x:%02x:%02x:%02x:%02x:%02x\n",\ + beacon_frame.addr3[0],beacon_frame.addr3[1],beacon_frame.addr3[2],beacon_frame.addr3[3],beacon_frame.addr3[4],beacon_frame.addr3[5]); + printf("\nbeacon seq_ctl = %02x %02x\n",beacon_frame.seq_ctl[0],beacon_frame.seq_ctl[1]); + printf("\nbeacon timestamp = %02x %02x %02x %02x %02x %02x %02x %02x\n",\ + beacon_frame.timestamp[0],beacon_frame.timestamp[1],beacon_frame.timestamp[2],beacon_frame.timestamp[3],beacon_frame.timestamp[4],beacon_frame.timestamp[5],beacon_frame.timestamp[6],beacon_frame.timestamp[7]); + + return 0; +} + +void get_beacon_frame_thread(void *param) +{ + vTaskDelay(10000);//a rough time for waiting wifi connected + //Register callback function until wifi connected + get_beacon_frame_callback = get_beacon_frame_func; + vTaskDelete(NULL); + return; +} + +void example_get_beacon_frame(void) +{ + if(xTaskCreate(get_beacon_frame_thread, ((const char*)"get_beacon_frame_thread"), 256, NULL, tskIDLE_PRIORITY , NULL) != pdPASS) + printf("\n\r%s xTaskCreate(get_beacon_frame_thread) failed", __FUNCTION__); + return; +} + diff --git a/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.h b/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.h new file mode 100644 index 0000000..bba4633 --- /dev/null +++ b/USDK/component/common/example/get_beacon_frame/example_get_beacon_frame.h @@ -0,0 +1,26 @@ +#ifndef __EXAMPLE_GET_BEACON_FRAME_H__ +#define __EXAMPLE_GET_BEACON_FRAME_H__ + +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ + +typedef struct beacon_info_str{ + //802.11 MAC header + unsigned char frame_ctl[2]; + unsigned char duration_id[2]; + unsigned char addr1[6]; + unsigned char addr2[6]; + unsigned char addr3[6]; + unsigned char seq_ctl[2]; + //802.11 beacon IE + unsigned char timestamp[8]; +}BEACON_INFO_T; + +void example_get_beacon_frame(void); +int get_beacon_frame_func(BEACON_INFO_T beacon_frame); + +#endif //#ifndef __EXAMPLE_GET_BEACON_FRAME_H__ diff --git a/USDK/component/common/example/get_beacon_frame/readme.txt b/USDK/component/common/example/get_beacon_frame/readme.txt new file mode 100644 index 0000000..ac80b14 --- /dev/null +++ b/USDK/component/common/example/get_beacon_frame/readme.txt @@ -0,0 +1,13 @@ +GET BEACON FRAME EXAMPLE + +Description: +Get beacon frame information in station mode + +Configuration: +[platform_opts.h] + #define CONFIG_EXAMPLE_GET_BEACON_FRAME 1 + +Execution: +Call example_get_beacon_frame() to create get beacon frame thread. +It can collect the beacon of AP in the air. + diff --git a/USDK/component/common/example/googlenest/example.html b/USDK/component/common/example/googlenest/example.html new file mode 100644 index 0000000..858f0d4 --- /dev/null +++ b/USDK/component/common/example/googlenest/example.html @@ -0,0 +1,38 @@ + + + + + + + +

Realtek Google Nest API example

+
+ + +

Data To Device

+ +

Input the value of RGB to change the state of light:

+

Red +Green +Blue + +

+ + + + + diff --git a/USDK/component/common/example/googlenest/example_google.c b/USDK/component/common/example/googlenest/example_google.c new file mode 100644 index 0000000..66d3877 --- /dev/null +++ b/USDK/component/common/example/googlenest/example_google.c @@ -0,0 +1,185 @@ +#include "cmsis_os.h" +#include "diag.h" +#include "wifi_conf.h" +#include "wifi_ind.h" +#include "google/google_nest.h" + + +#include +#include "cJSON.h" + +osThreadId google_thread_id; +#define malloc pvPortMalloc +#define free vPortFree + +void google_data_retrieve(char *response_buf); + +void google_data_retrieve(char *response_buf) { + //printf("\r\n\r\n\r\nResponse_buf:\r\n%s\r\n", response_buf); + char *event = NULL; + char *delims = "\n"; + char *data = NULL, *backup = NULL; + char *info = NULL; + cJSON_Hooks memoryHook; + + event = strtok_r(response_buf, delims, &backup); + data = strtok_r( NULL, delims, &backup ); + + if (!strncmp(data, "data: ", strlen("data: "))){ + info = data + strlen("data: "); + if(info != NULL){ + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + + cJSON *infoJSObject, *pathJSObject, *dataJSObject; + cJSON *redJSObject, *greenJSObject, *blueJSObject; + char *red, *green, *blue; + + + if((infoJSObject = cJSON_Parse(info)) != NULL) { + pathJSObject = cJSON_GetObjectItem(infoJSObject, "path"); + dataJSObject = cJSON_GetObjectItem(infoJSObject, "data"); + if(dataJSObject != NULL) { + + redJSObject = cJSON_GetObjectItem(dataJSObject, "Red"); + greenJSObject = cJSON_GetObjectItem(dataJSObject, "Green"); + blueJSObject = cJSON_GetObjectItem(dataJSObject, "Blue"); + + if(redJSObject) + red = redJSObject->valuestring; + + if(greenJSObject) + green = greenJSObject->valuestring; + + if(blueJSObject) + blue = blueJSObject->valuestring; + + printf("\n\rThe latest RGB information: RGB(%s, %s, %s)\n\r", red, green, blue); + + cJSON_Delete(dataJSObject); + } + cJSON_Delete(infoJSObject); + } + else + printf("\r\nCannot parse the message to JSON!\r\n"); + + } + else + printf("\r\n This is the keep alive message or cannot get the information!\r\n"); + } + else + printf("\r\nData structure may wrong!\r\n"); +} + + +void gn_todevice_start(void) { + + googlenest_context googlenest; + char *googlenest_host = HOST_ADDR; + char *googlenest_uri = "light.json"; + + printf("\r\nStart connecting to Google Nest Server...\r\n"); + memset(&googlenest, 0, sizeof(googlenest_context)); + +reconnect: + if(gn_connect(&googlenest, googlenest_host, GN_PORT) == 0) { + printf("\r\n Connection is OK!\r\n"); + + google_retrieve_data_hook_callback(google_data_retrieve); + if(gn_stream(&googlenest, googlenest_uri) != 0){ + printf("\r\n Connection is fail! \r\n Start Reconnecting...\r\n"); + goto reconnect; + } + + gn_close(&googlenest); + + } + else{ + printf("\r\n Connection is fail! \r\n\r\n\r\n\r\nStart Reconnecting...\r\n"); + goto reconnect; + } + +} + +void gn_fromdevice_start(void) { + googlenest_context googlenest; + char *googlenest_uri = "MotionSensor.json"; + cJSON_Hooks memoryHook; + int j = 0; + + memoryHook.malloc_fn = malloc; + memoryHook.free_fn = free; + cJSON_InitHooks(&memoryHook); + printf("\r\nStart connecting to Google Nest Server!\r\n"); + + while(1) { + memset(&googlenest, 0, sizeof(googlenest_context)); + if(gn_connect(&googlenest, HOST_ADDR, GN_PORT) == 0) { + cJSON *MSJSObject; + char *data; + + if((MSJSObject = cJSON_CreateObject()) != NULL) { + cJSON_AddItemToObject(MSJSObject, "MotionSenser", cJSON_CreateNumber(j++)); + data = cJSON_Print(MSJSObject); + cJSON_Delete(MSJSObject); + } + + if(gn_put(&googlenest, googlenest_uri, data) == 0) + printf("\n\rUpdate the Motion Sensor's data to %d\n\r", (j-1)); + free(data); + gn_close(&googlenest); + } + else{ + printf("\n\rConnection failed!\n\r"); + break; + } + + vTaskDelay(5 * configTICK_RATE_HZ); + } +} + +void gn_fromdevice_task(void *arg) { + int i; + + printf("\n\r\n\r\n\r\n\r<<<<<>>>>>>\n\r\n\r\n\r\n\r"); + for (i = 0; i<120; i++) + vTaskDelay(1000 / portTICK_PERIOD_MS); + + gn_fromdevice_start(); +} + +void gn_todevice_task(void *arg) { + int i; + + printf("\n\r\n\r\n\r\n\r<<<<<>>>>>>\n\r\n\r\n\r\n\r"); + for (i = 0; i<120; i++) + vTaskDelay(1000 / portTICK_PERIOD_MS); + + gn_todevice_start(); +} + +void example_google(char *type) { + + + if(strcmp(type, "FromDevice") == 0){ + osThreadDef_t google_thread; + google_thread.instances = 1; + google_thread.name = "google thread"; + google_thread.stacksize = 4096; + google_thread.pthread = (os_pthread)gn_fromdevice_task; + google_thread.tpriority = tskIDLE_PRIORITY+6; + google_thread_id = osThreadCreate(&google_thread, NULL); + } + else if(strcmp(type, "ToDevice") == 0){ + osThreadDef_t google_thread; + google_thread.instances = 1; + google_thread.name = "google thread"; + google_thread.stacksize = 4096; + google_thread.pthread = (os_pthread)gn_todevice_task; + google_thread.tpriority = tskIDLE_PRIORITY+6; + google_thread_id = osThreadCreate(&google_thread, NULL); + } + +} + diff --git a/USDK/component/common/example/googlenest/example_google.h b/USDK/component/common/example/googlenest/example_google.h new file mode 100644 index 0000000..8de92d0 --- /dev/null +++ b/USDK/component/common/example/googlenest/example_google.h @@ -0,0 +1,10 @@ +#ifndef GOOGLE_THREAD_H +#define GOOGLE_THREAD_H + +#define HOST_ADDR "your_firebase_address.firebaseio.com" +#define GN_PORT 443 + +void example_google(char *type); + + +#endif diff --git a/USDK/component/common/example/mcast/example_mcast.c b/USDK/component/common/example/mcast/example_mcast.c new file mode 100644 index 0000000..b18dae8 --- /dev/null +++ b/USDK/component/common/example/mcast/example_mcast.c @@ -0,0 +1,98 @@ +#include "FreeRTOS.h" +#include "task.h" +#include + +#include +#include +#include +extern struct netif xnetif[]; + +static void example_mcast_thread(void *param) +{ +#if LWIP_IGMP + int err = 0; + int socket = -1; + char *group_ip = "224.0.0.251"; + uint16_t port = 5353; + + // Set NETIF_FLAG_IGMP flag for netif which should process IGMP messages + xnetif[0].flags |= NETIF_FLAG_IGMP; + + if((socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("ERROR: socket - AF_INET, SOCK_DGRAM\n"); + err = -1; + } + + // Add multicast group membership on this interface + if(err == 0) { + struct ip_mreq imr; + imr.imr_multiaddr.s_addr = inet_addr(group_ip); + imr.imr_interface.s_addr = INADDR_ANY; + err = setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)); + if(err < 0) printf("ERROR: setsockopt - IP_ADD_MEMBERSHIP\n"); + } + + // Specify outgoing interface too + if(err == 0) { + struct in_addr intfAddr; + intfAddr.s_addr = INADDR_ANY; + err = setsockopt(socket, IPPROTO_IP, IP_MULTICAST_IF, &intfAddr, sizeof(struct in_addr)); + if(err < 0) printf("ERROR: setsockopt - IP_MULTICAST_IF\n"); + } + + // And start listening for packets + if(err == 0) { + struct sockaddr_in bindAddr; + bindAddr.sin_family = AF_INET; + bindAddr.sin_port = htons(port); + bindAddr.sin_addr.s_addr = INADDR_ANY; + err = bind(socket, (struct sockaddr *) &bindAddr, sizeof(bindAddr)); + if(err < 0) printf("ERROR: bind\n"); + } + + if(err == 0) { + unsigned char packet[1024]; + + while(1) { + // Receive multicast + int packetLen; + struct sockaddr from; + struct sockaddr_in *from_sin = (struct sockaddr_in*) &from; + socklen_t fromLen = sizeof(from); + + if((packetLen = recvfrom(socket, &packet, sizeof(packet), 0, &from, &fromLen)) >= 0) { + uint8_t *ip = (uint8_t *) &from_sin->sin_addr.s_addr; + uint16_t from_port = ntohs(from_sin->sin_port); + printf("recvfrom - %d bytes from %d.%d.%d.%d:%d\n", packetLen, ip[0], ip[1], ip[2], ip[3], from_port); + } + + // Send multicast + if(packetLen > 0) { + int sendLen; + struct sockaddr to; + struct sockaddr_in *to_sin = (struct sockaddr_in*) &to; + to_sin->sin_family = AF_INET; + to_sin->sin_port = htons(port); + to_sin->sin_addr.s_addr = inet_addr(group_ip); + + if((sendLen = sendto(socket, packet, packetLen, 0, &to, sizeof(struct sockaddr))) < 0) + printf("ERROR: sendto %s\n", group_ip); + else + printf("sendto - %d bytes to %s:%d\n", sendLen, group_ip, port); + } + } + } + else if(socket != -1) { + close(socket); + } +#else + printf("\nSHOULD ENABLE LWIP_IGMP\n"); +#endif + vTaskDelete(NULL); +} + +void example_mcast(void) +{ + if(xTaskCreate(example_mcast_thread, ((const char*)"example_mcast_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/USDK/component/common/example/mcast/example_mcast.h b/USDK/component/common/example/mcast/example_mcast.h new file mode 100644 index 0000000..7be6823 --- /dev/null +++ b/USDK/component/common/example/mcast/example_mcast.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_MCAST_H +#define EXAMPLE_MCAST_H + +void example_mcast(void); + +#endif /* EXAMPLE_MCAST_H */ diff --git a/USDK/component/common/example/mcast/readme.txt b/USDK/component/common/example/mcast/readme.txt new file mode 100644 index 0000000..1a6409d --- /dev/null +++ b/USDK/component/common/example/mcast/readme.txt @@ -0,0 +1,17 @@ +LWIP MULTICAST EXAMPLE + +Description: +Join multicast group of 224.0.0.251 and listen on port 5353. +Send packet with the content of received packet to multicast group of 224.0.0.251. + +Configuration: +[lwipopts.h] + #define LWIP_UDP 1 + #define LWIP_IGMP 1 +[platform_opts.h] + #define CONFIG_EXAMPLE_MCAST 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A multicast example thread will be started automatically when booting. + diff --git a/USDK/component/common/example/mdns/example_mdns.c b/USDK/component/common/example/mdns/example_mdns.c new file mode 100644 index 0000000..3af2b36 --- /dev/null +++ b/USDK/component/common/example/mdns/example_mdns.c @@ -0,0 +1,55 @@ +#include "FreeRTOS.h" +#include "task.h" +#include + +#include + +#include +#include +extern struct netif xnetif[]; + +static void example_mdns_thread(void *param) +{ + DNSServiceRef dnsServiceRef = NULL; + TXTRecordRef txtRecord; + unsigned char txt_buf[100]; // use fixed buffer for text record to prevent malloc/free + + // Delay to wait for IP by DHCP + vTaskDelay(10000); + + printf("\nmDNS Init\n"); + if(mDNSResponderInit() == 0) { + printf("mDNS Register service\n"); + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content"), "text1_content"); + TXTRecordSetValue(&txtRecord, "text2", strlen("text2_content"), "text2_content"); + dnsServiceRef = mDNSRegisterService("ameba", "_service1._tcp", "local", 5000, &txtRecord); + TXTRecordDeallocate(&txtRecord); + printf("wait for 30s ... \n"); + vTaskDelay(30*1000); + + printf("mDNS Update service\n"); + TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf); + TXTRecordSetValue(&txtRecord, "text1", strlen("text1_content_new"), "text1_content_new"); + mDNSUpdateService(dnsServiceRef, &txtRecord, 0); + TXTRecordDeallocate(&txtRecord); + printf("wait for 30s ... \n"); + vTaskDelay(30*1000); + + if(dnsServiceRef) + mDNSDeregisterService(dnsServiceRef); + + // deregister service before mdns deinit is not necessary + // mDNS deinit will also deregister all services + printf("mDNS Deinit\n"); + mDNSResponderDeinit(); + } + + vTaskDelete(NULL); +} + +void example_mdns(void) +{ + if(xTaskCreate(example_mdns_thread, ((const char*)"example_mdns_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/USDK/component/common/example/mdns/example_mdns.h b/USDK/component/common/example/mdns/example_mdns.h new file mode 100644 index 0000000..39c4914 --- /dev/null +++ b/USDK/component/common/example/mdns/example_mdns.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_MDNS_H +#define EXAMPLE_MDNS_H + +void example_mdns(void); + +#endif /* EXAMPLE_MDNS_H */ diff --git a/USDK/component/common/example/socket_select/example_socket_select.c b/USDK/component/common/example/socket_select/example_socket_select.c new file mode 100644 index 0000000..403ccd1 --- /dev/null +++ b/USDK/component/common/example/socket_select/example_socket_select.c @@ -0,0 +1,106 @@ +#include "FreeRTOS.h" +#include "task.h" +#include +#include + +#if LWIP_SOCKET + +#define MAX_SOCKETS 10 +#define SELECT_TIMEOUT 10 +#define SERVER_PORT 5000 +#define LISTEN_QLEN 2 + +static void example_socket_select_thread(void *param) +{ + struct sockaddr_in server_addr; + int server_fd = -1; + int socket_used[10]; + + memset(socket_used, 0, sizeof(socket_used)); + + if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { + socket_used[server_fd] = 1; + } + else { + printf("socket error\n"); + goto exit; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(SERVER_PORT); + server_addr.sin_addr.s_addr = INADDR_ANY; + + if(bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) != 0) { + printf("bind error\n"); + goto exit; + } + + if(listen(server_fd, LISTEN_QLEN) != 0) { + printf("listen error\n"); + goto exit; + } + + while(1) { + int socket_fd; + unsigned char buf[512]; + fd_set read_fds; + struct timeval timeout; + + FD_ZERO(&read_fds); + timeout.tv_sec = SELECT_TIMEOUT; + timeout.tv_usec = 0; + + for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++) + if(socket_used[socket_fd]) + FD_SET(socket_fd, &read_fds); + + if(select(MAX_SOCKETS, &read_fds, NULL, NULL, &timeout)) { + for(socket_fd = 0; socket_fd < MAX_SOCKETS; socket_fd ++) { + if(socket_used[socket_fd] && FD_ISSET(socket_fd, &read_fds)) { + if(socket_fd == server_fd) { + struct sockaddr_in client_addr; + unsigned int client_addr_size = sizeof(client_addr); + int fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_addr_size); + + if(fd >= 0) { + printf("accept socket fd(%d)\n", fd); + socket_used[fd] = 1; + } + else { + printf("accept error\n"); + } + } + else { + int read_size = read(socket_fd, buf, sizeof(buf)); + + if(read_size > 0) { + write(socket_fd, buf, read_size); + } + else { + printf("socket fd(%d) disconnected\n", socket_fd); + socket_used[socket_fd] = 0; + close(socket_fd); + } + } + } + } + } + else { + printf("TCP server: no data in %d seconds\n", SELECT_TIMEOUT); + } + } + +exit: + if(server_fd >= 0) + close(server_fd); + + vTaskDelete(NULL); +} + +void example_socket_select(void) +{ + if(xTaskCreate(example_socket_select_thread, ((const char*)"example_socket_select_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} + +#endif // LWIP_SOCKET diff --git a/USDK/component/common/example/socket_select/example_socket_select.h b/USDK/component/common/example/socket_select/example_socket_select.h new file mode 100644 index 0000000..f42594f --- /dev/null +++ b/USDK/component/common/example/socket_select/example_socket_select.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_SOCKET_SELECT_H +#define EXAMPLE_SOCKET_SELECT_H + +void example_socket_select(void); + +#endif /* EXAMPLE_SOCKET_SELECT_H */ diff --git a/USDK/component/common/example/socket_select/readme.txt b/USDK/component/common/example/socket_select/readme.txt new file mode 100644 index 0000000..6618e4b --- /dev/null +++ b/USDK/component/common/example/socket_select/readme.txt @@ -0,0 +1,13 @@ +LWIP SOCKET SELECT EXAMPLE + +Description: +TCP server listens on port 5000 and handle socket by select(). + +Configuration: +[platform_opts.h] + #define CONFIG_EXAMPLE_SOCKET_SELECT 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A socket select example thread will be started automatically when booting. + diff --git a/USDK/component/common/example/ssl_download/example_ssl_download.c b/USDK/component/common/example/ssl_download/example_ssl_download.c new file mode 100644 index 0000000..746d12a --- /dev/null +++ b/USDK/component/common/example/ssl_download/example_ssl_download.c @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include +#include +#include + +#define SERVER_HOST "192.168.13.27" +#define SERVER_PORT 443 +#define RESOURCE "/dummy100k.bin" + +static unsigned int arc4random(void) +{ + unsigned int res = xTaskGetTickCount(); + static unsigned int seed = 0xDEADB00B; + + seed = ((seed & 0x007F00FF) << 7) ^ + ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits + (res << 13) ^ (res >> 9); // using the clock too! + + return seed; +} + +static void get_random_bytes(void *buf, size_t len) +{ + unsigned int ranbuf; + unsigned int *lp; + int i, count; + count = len / sizeof(unsigned int); + lp = (unsigned int *) buf; + + for(i = 0; i < count; i ++) { + lp[i] = arc4random(); + len -= sizeof(unsigned int); + } + + if(len > 0) { + ranbuf = arc4random(); + memcpy(&lp[i], &ranbuf, len); + } +} + +static int my_random(void *p_rng, unsigned char *output, size_t output_len) +{ + get_random_bytes(output, output_len); + return 0; +} + +static void example_ssl_download_thread(void *param) +{ + int server_fd = -1, ret; + struct sockaddr_in server_addr; + ssl_context ssl; + + // Delay to wait for IP by DHCP + vTaskDelay(10000); + printf("\nExample: SSL download\n"); + + memory_set_own(pvPortMalloc, vPortFree); + memset(&ssl, 0, sizeof(ssl_context)); + + if((ret = net_connect(&server_fd, SERVER_HOST, SERVER_PORT)) != 0) { + printf("ERROR: net_connect ret(%d)\n", ret); + goto exit; + } + + if((ret = ssl_init(&ssl)) != 0) { + printf("ERRPR: ssl_init ret(%d)\n", ret); + goto exit; + } + + ssl_set_endpoint(&ssl, SSL_IS_CLIENT); + ssl_set_authmode(&ssl, SSL_VERIFY_NONE); + ssl_set_rng(&ssl, my_random, NULL); + ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd); + + if((ret = ssl_handshake(&ssl)) != 0) { + printf("ERROR: ssl_handshake ret(-0x%x)", -ret); + goto exit; + } + else { + unsigned char buf[2048]; + int read_size = 0, resource_size = 0, content_len = 0, header_removed = 0; + + printf("SSL ciphersuite %s\n", ssl_get_ciphersuite(&ssl)); + sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", RESOURCE, SERVER_HOST); + ssl_write(&ssl, buf, strlen(buf)); + + while((read_size = ssl_read(&ssl, buf, sizeof(buf))) > 0) { + if(header_removed == 0) { + char *header = strstr(buf, "\r\n\r\n"); + + if(header) { + char *body, *content_len_pos; + + body = header + strlen("\r\n\r\n"); + *(body - 2) = 0; + header_removed = 1; + printf("\nHTTP Header: %s\n", buf); + read_size = read_size - ((unsigned char *) body - buf); + + content_len_pos = strstr(buf, "Content-Length: "); + if(content_len_pos) { + content_len_pos += strlen("Content-Length: "); + *(strstr(content_len_pos, "\r\n")) = 0; + content_len = atoi(content_len_pos); + } + } + else { + printf("ERROR: HTTP header\n"); + goto exit; + } + } + + printf("read resource %d bytes\n", read_size); + resource_size += read_size; + } + + printf("final read size = %d bytes\n", read_size); + printf("http content-length = %d bytes, download resource size = %d bytes\n", content_len, resource_size); + } + +exit: + if(server_fd != -1) + net_close(server_fd); + + ssl_free(&ssl); + vTaskDelete(NULL); +} + +void example_ssl_download(void) +{ + if(xTaskCreate(example_ssl_download_thread, ((const char*)"example_ssl_download_thread"), 2048, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} diff --git a/USDK/component/common/example/ssl_download/example_ssl_download.h b/USDK/component/common/example/ssl_download/example_ssl_download.h new file mode 100644 index 0000000..d7748ac --- /dev/null +++ b/USDK/component/common/example/ssl_download/example_ssl_download.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_SSL_DOWNLOAD_H +#define EXAMPLE_SSL_DOWNLOAD_H + +void example_ssl_download(void); + +#endif /* EXAMPLE_SSL_DOWNLOAD_H */ diff --git a/USDK/component/common/example/ssl_download/readme.txt b/USDK/component/common/example/ssl_download/readme.txt new file mode 100644 index 0000000..e82c5b2 --- /dev/null +++ b/USDK/component/common/example/ssl_download/readme.txt @@ -0,0 +1,16 @@ +SSL DOWNLOAD EXAMPLE + +Description: +Download file from Web server via https. + +Configuration: +Modify SSL_MAX_CONTENT_LEN in SSL config and configTOTAL_HEAP_SIZE in freertos config for large size file +Modify SERVER_HOST, SERVER_PORT and RESOURCE in example_ssl_download.c based on your SSL server + +[platform_opts.h] + #define CONFIG_EXAMPLE_SSL_DOWNLOAD 1 + +Execution: +Can make automatical Wi-Fi connection when booting by using wlan fast connect example. +A ssl download example thread will be started automatically when booting. + diff --git a/USDK/component/common/example/uart_atcmd/example_uart_atcmd.c b/USDK/component/common/example/uart_atcmd/example_uart_atcmd.c new file mode 100644 index 0000000..5c1fa71 --- /dev/null +++ b/USDK/component/common/example/uart_atcmd/example_uart_atcmd.c @@ -0,0 +1,612 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#include "platform_opts.h" +#include "FreeRTOS.h" +#include "task.h" +#include "platform/platform_stdlib.h" +#include "semphr.h" +#include "device.h" +#include "serial_api.h" +#include "at_cmd/log_service.h" +#include "uart_atcmd/example_uart_atcmd.h" +#include "flash_api.h" +#include "device_lock.h" +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "freertos_pmu.h" +#endif +#include "osdep_api.h" +#include "osdep_service.h" +#include "serial_ex_api.h" +#include "at_cmd/atcmd_wifi.h" +#include "at_cmd/atcmd_lwip.h" +#include "pinmap.h" + +#ifdef USE_FLASH_EEP +#include "flash_eep.h" +#endif + +#if CONFIG_EXAMPLE_UART_ATCMD + +typedef int (*init_done_ptr)(void); +extern init_done_ptr p_wlan_init_done_callback; +extern char log_buf[LOG_SERVICE_BUFLEN]; +extern xSemaphoreHandle log_rx_interrupt_sema; +extern void serial_rx_fifo_level(serial_t *obj, SerialFifoLevel FifoLv); +extern int atcmd_wifi_restore_from_flash(void); +extern int atcmd_lwip_restore_from_flash(void); + +serial_t at_cmd_sobj; +char at_string[ATSTRING_LEN]; +//xSemaphoreHandle at_printf_sema; +_Sema uart_at_dma_tx_sema; +unsigned char gAT_Echo = 1; // default echo on + +#define UART_AT_MAX_DELAY_TIME_MS 20 + +#define UART_AT_DATA UART_SETTING_SECTOR +#define BACKUP_SECTOR FLASH_SYSTEM_DATA_ADDR-0x1000 + +#define UART_AT_USE_DMA_TX 0 + +void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len){ +#ifdef USE_FLASH_EEP + if(id == AT_PARTITION_UART || id == AT_PARTITION_LWIP || id == AT_PARTITION_WIFI) { + if(ops == AT_PARTITION_READ) flash_read_cfg(data, id, len); + else if (ops == AT_PARTITION_WRITE) flash_write_cfg(data, id, len); + else if (ops == AT_PARTITION_ERASE) flash_write_cfg(data, id, 0); + } +#else + flash_t flash; + int size, offset, i; + u32 read_data; + + switch(id){ + case AT_PARTITION_UART: + size = UART_CONF_DATA_SIZE; + offset = UART_CONF_DATA_OFFSET; + break; + case AT_PARTITION_WIFI: + size = WIFI_CONF_DATA_SIZE; + offset = WIFI_CONF_DATA_OFFSET; + break; + case AT_PARTITION_LWIP: + size = LWIP_CONF_DATA_SIZE; + offset = LWIP_CONF_DATA_OFFSET; + break; + case AT_PARTITION_ALL: + size = 0x1000; + offset = 0; + break; + default: + printf("partition id is invalid!\r\n"); + return; + } + + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(id == AT_PARTITION_ALL && ops == AT_PARTITION_ERASE){ + flash_erase_sector(&flash, UART_SETTING_SECTOR); + goto exit; + } + + if(ops == AT_PARTITION_READ){ + flash_stream_read(&flash, UART_SETTING_SECTOR+offset, len, data); + goto exit; + } + + //erase BACKUP_SECTOR + flash_erase_sector(&flash, UART_SETTING_BACKUP_SECTOR); + + if(ops == AT_PARTITION_WRITE){ + // backup new data + flash_stream_write(&flash, UART_SETTING_BACKUP_SECTOR+offset, len, data); + } + + //backup front data to backup sector + for(i = 0; i < offset; i += sizeof(read_data)){ + flash_read_word(&flash, UART_SETTING_SECTOR + i, &read_data); + flash_write_word(&flash, UART_SETTING_BACKUP_SECTOR + i,read_data); + } + + //backup rear data + for(i = (offset + size); i < 0x1000; i += sizeof(read_data)){ + flash_read_word(&flash, UART_SETTING_SECTOR + i, &read_data); + flash_write_word(&flash, UART_SETTING_BACKUP_SECTOR + i,read_data); + } + + //erase UART_SETTING_SECTOR + flash_erase_sector(&flash, UART_SETTING_SECTOR); + + //retore data to UART_SETTING_SECTOR from UART_SETTING_BACKUP_SECTOR + for(i = 0; i < 0x1000; i+= sizeof(read_data)){ + flash_read_word(&flash, UART_SETTING_BACKUP_SECTOR + i, &read_data); + flash_write_word(&flash, UART_SETTING_SECTOR + i,read_data); + } + + //erase BACKUP_SECTOR + flash_erase_sector(&flash, UART_SETTING_BACKUP_SECTOR); + +exit: + device_mutex_unlock(RT_DEV_LOCK_FLASH); + return; +#endif +} + +int read_uart_atcmd_setting_from_system_data(UART_LOG_CONF* uartconf) +{ +// flash_t flash; + UART_LOG_CONF conf; + bool load_default = _TRUE; + +// device_mutex_lock(RT_DEV_LOCK_FLASH); +// flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), (u8 *)&conf); + atcmd_update_partition_info(AT_PARTITION_UART, AT_PARTITION_READ, (u8 *)&conf, sizeof(UART_LOG_CONF)); + do{ + if(conf.FlowControl != AUTOFLOW_DISABLE && conf.FlowControl != AUTOFLOW_ENABLE) + break; + + if(conf.DataBits != 5 + && conf.DataBits != 6 + && conf.DataBits != 7 + && conf.DataBits != 8) //5, 6, 7, 8 + break; + + if(conf.Parity != ParityNone && conf.Parity != ParityOdd && conf.Parity != ParityEven) + break; + + if(conf.StopBits != 1 && conf.StopBits != 2) + break; + + load_default = _FALSE; + }while(0); + + if(load_default == _TRUE){ + // load default setting + uartconf->BaudRate = DEFAULT_BAUDRATE; + uartconf->DataBits = 8; + uartconf->Parity = ParityNone; + uartconf->StopBits = 1; + uartconf->FlowControl = AUTOFLOW_DISABLE; + } + else{ + uartconf->BaudRate = conf.BaudRate; + uartconf->DataBits = conf.DataBits; + uartconf->Parity = conf.Parity; + uartconf->StopBits = conf.StopBits; + uartconf->FlowControl = conf.FlowControl; + } +// device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("\r\nAT_UART_CONF: %d,%d,%d,%d,%d\r\n", + uartconf->BaudRate, + uartconf->DataBits, + uartconf->StopBits, + uartconf->Parity, + uartconf->FlowControl); + + return 0; +} + +int write_uart_atcmd_setting_to_system_data(UART_LOG_CONF* uartconf) +{ +#if 0 + flash_t flash; + + u8 data1[sizeof(UART_LOG_CONF)]; + u8 data2[sizeof(UART_LOG_CONF)]; + + u32 data,i; + + memset(data2, 0xFF, sizeof(UART_LOG_CONF)); + + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), data1); + + if(memcmp(data1,data2,sizeof(UART_LOG_CONF)) == 0){ + flash_stream_write(&flash, UART_AT_DATA, sizeof(UART_LOG_CONF),(u8*)uartconf); + }else{ + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + + // backup log uart configuration + flash_stream_write(&flash, BACKUP_SECTOR, sizeof(UART_LOG_CONF),(u8*)uartconf); + + //backup system data to backup sector + for(i = sizeof(UART_LOG_CONF); i < 0x1000; i+= 4){ + flash_read_word(&flash, UART_AT_DATA + i, &data); + flash_write_word(&flash, BACKUP_SECTOR + i,data); + } + //erase system data + flash_erase_sector(&flash, UART_AT_DATA); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, BACKUP_SECTOR + i, &data); + flash_write_word(&flash, UART_AT_DATA + i,data); + } + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#else + atcmd_update_partition_info(AT_PARTITION_UART, AT_PARTITION_WRITE, (u8 *)uartconf, sizeof(UART_LOG_CONF)); +#endif + return 0; +} + +int reset_uart_atcmd_setting(){ +#if 0 + flash_t flash; + + u8 data1[sizeof(UART_LOG_CONF)]; + u8 data2[sizeof(UART_LOG_CONF)]; + + u32 data,i; + + memset(data2, 0xFF, sizeof(UART_LOG_CONF)); + + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, UART_AT_DATA,sizeof(UART_LOG_CONF), data1); + + if(memcmp(data1,data2,sizeof(UART_LOG_CONF)) == 0){ + ; + }else{ + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + + // erase uart configuration + flash_stream_write(&flash, BACKUP_SECTOR, sizeof(UART_LOG_CONF),(u8*)data2); + //backup system data to backup sector + for(i = sizeof(UART_LOG_CONF); i < 0x1000; i+= 4){ + flash_read_word(&flash, UART_AT_DATA + i, &data); + flash_write_word(&flash, BACKUP_SECTOR + i,data); + } + //erase system data + flash_erase_sector(&flash, UART_AT_DATA); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, BACKUP_SECTOR + i, &data); + flash_write_word(&flash, UART_AT_DATA + i,data); + } + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#else +#ifdef USE_FLASH_EEP + flash_write_cfg(NULL, AT_PARTITION_UART, 0); + flash_write_cfg(NULL, AT_PARTITION_WIFI, 0); + flash_write_cfg(NULL, AT_PARTITION_LWIP, 0); +#else + atcmd_update_partition_info(AT_PARTITION_ALL, AT_PARTITION_ERASE, NULL, 0); +#endif +#endif + return 0; +} + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "gpio_irq_api.h" +#define UART_AT_RX_WAKE UART_RX +void gpio_uart_at_rx_irq_callback (uint32_t id, gpio_irq_event event) +{ + /* WAKELOCK_LOGUART is also handled in log service. + * It is release after a complete command is sent. + **/ + //acquire_wakelock(WAKELOCK_LOGUART); +} + +void uart_at_rx_wakeup() +{ + gpio_irq_t gpio_rx_wake; +#ifdef RTL8711AM +#if (UART_AT_RX_WAKE!=PA_0)||(UART_AT_RX_WAKE!=PE_3) +#error "Set pin rx_wakeup!" +#endif +#endif + gpio_irq_init(&gpio_rx_wake, UART_AT_RX_WAKE, gpio_uart_at_rx_irq_callback, 0); + gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_rx_wake); +} +#endif + +void uart_atcmd_reinit(UART_LOG_CONF* uartconf){ + serial_baud(&at_cmd_sobj,uartconf->BaudRate); + serial_format(&at_cmd_sobj, uartconf->DataBits, (SerialParity)uartconf->Parity, uartconf->StopBits); + + // set flow control, only support RTS and CTS concurrent mode + // rxflow and tx flow is fixed by hardware +#define rxflow UART_RTS +#define txflow UART_CTS + if(uartconf->FlowControl){ + pin_mode(txflow, PullDown); //init CTS in low + serial_set_flow_control(&at_cmd_sobj, FlowControlRTSCTS, rxflow, txflow); + } + else + serial_set_flow_control(&at_cmd_sobj, FlowControlNone, rxflow, txflow); +} + +void uart_at_send_string(char *str) +{ + unsigned int i=0; + while (str[i] != '\0') { + serial_putc(&at_cmd_sobj, str[i]); + i++; + } +} + +#if UART_AT_USE_DMA_TX +static void uart_at_send_buf_done(uint32_t id) +{ + //serial_t *sobj = (serial_t *)id; + + RtlUpSemaFromISR(&uart_at_dma_tx_sema); +} +#endif + +void uart_at_send_buf(u8 *buf, u32 len) +{ + unsigned char *st_p=buf; + if(!len || (!buf)){ + return; + } +#if UART_AT_USE_DMA_TX + int ret; + while(RtlDownSema(&uart_at_dma_tx_sema) == pdTRUE){ + ret = serial_send_stream_dma(&at_cmd_sobj, st_p, len); + if(ret != HAL_OK){ + RtlUpSema(&uart_at_dma_tx_sema); + return; + }else{ + return; + } + } +#else + while(len){ + serial_putc(&at_cmd_sobj, *st_p); + st_p++; + len--; + } +#endif +} +/* +void uart_at_lock(void) +{ + RtlDownSema(&at_printf_sema); +} + +void uart_at_unlock(void) +{ + RtlUpSema(&at_printf_sema); +} + +void uart_at_lock_init(){ + RtlInitSema(&at_printf_sema, 1); +} +*/ +void uart_irq(uint32_t id, SerialIrq event) +{ + serial_t *sobj = (serial_t *)id; + unsigned char rc=0; + static unsigned char temp_buf[LOG_SERVICE_BUFLEN] = "\0"; + static unsigned int buf_count = 0; + static unsigned char combo_key = 0; + static u32 last_tickcnt = 0; //to check if any data lost + static bool is_data_cmd = _FALSE; // to mark if it's a data command + static u32 data_sz = 0, data_cmd_sz =0; // command will send to log handler until "data_cmd_sz" characters are received + + if(event == RxIrq) { + rc = serial_getc(sobj); + + if(atcmd_lwip_is_tt_mode()){ + log_buf[atcmd_lwip_tt_datasize++] = rc; + atcmd_lwip_tt_lasttickcnt = xTaskGetTickCountFromISR(); + if(atcmd_lwip_tt_datasize == 1) + rtw_up_sema_from_isr((_Sema *)&atcmd_lwip_tt_sema); + return; + } + + if(buf_count == 4){ + // if this is a data command with hex data, then '\n' should not be treated + // as the end of command + if(strncmp(temp_buf, "ATPT", C_NUM_AT_CMD)==0){ + is_data_cmd = _TRUE; + } + } + if(buf_count > C_NUM_AT_CMD && is_data_cmd == _TRUE){ + if(data_cmd_sz == 0){ + if(data_sz == 0){ + if(rc == ','){ + //first delimeter, ATxx=[sz],.... + char str[10]={0}; + char size_pos = C_NUM_AT_CMD + C_NUM_AT_CMD_DLT; + memcpy(str, &temp_buf[size_pos], buf_count-size_pos); + data_sz = atoi(str); //get data size + } + }else{ + if(rc == ':'){ //data will start after this delimeter ':' + strncpy(log_buf, (char *)temp_buf, buf_count); + memset(temp_buf,'\0',buf_count); + last_tickcnt = xTaskGetTickCountFromISR(); + data_cmd_sz = buf_count + 1 + data_sz; + } + } + } + + if(data_cmd_sz){ + if((!gAT_Echo) && (rtw_systime_to_ms(xTaskGetTickCountFromISR() - last_tickcnt) > UART_AT_MAX_DELAY_TIME_MS)){ + uart_at_send_string("\r\nERROR:data timeout\r\n\n# "); + memset(log_buf, 0, buf_count); + is_data_cmd = _FALSE; + data_sz = 0; + data_cmd_sz = 0; + buf_count=0; + last_tickcnt = 0; + return; + } + last_tickcnt = xTaskGetTickCountFromISR(); + log_buf[buf_count++]=rc; + if(gAT_Echo == 1){ + serial_putc(sobj, rc); + } + if(buf_count >= data_cmd_sz){ + log_buf[data_cmd_sz - data_sz - 1] = '\0'; //for log service handler parse to get command parameter, replace ":" with "\0" + is_data_cmd = _FALSE; + data_sz = 0; + data_cmd_sz = 0; + buf_count=0; + last_tickcnt = 0; + rtw_up_sema_from_isr((_Sema *)&log_rx_interrupt_sema); + } + return; + } + } + + if (rc == KEY_ESC) { + combo_key = 1; + } + else if (combo_key == 1){ + if (rc == KEY_LBRKT) { + combo_key = 2; + } + else{ + combo_key = 0; + } + } + else if (combo_key == 2){ + //if ((rc=='A')|| rc=='B'){//up and down + //} + combo_key=0; + } + else if(rc == KEY_ENTER){ + if(buf_count>0){ + memset(log_buf,'\0',LOG_SERVICE_BUFLEN); + strncpy(log_buf,(char *)&temp_buf[0],buf_count); + rtw_up_sema_from_isr((_Sema *)&log_rx_interrupt_sema); + memset(temp_buf,'\0',buf_count); + is_data_cmd = _FALSE; + data_sz = 0; + data_cmd_sz = 0; + buf_count=0; + last_tickcnt = 0; + }else{ + uart_at_send_string(STR_END_OF_ATCMD_RET); + } + } + else if(rc == KEY_BS){ + if(buf_count>0){ + buf_count--; + temp_buf[buf_count] = '\0'; + if(gAT_Echo == 1){ + serial_putc(sobj, rc); + serial_putc(sobj, ' '); + serial_putc(sobj, rc); + } + } + } + else{ + // skip characters until "A" + if((buf_count == 0) && (rc != 'A')){ + if(gAT_Echo == 1){ + uart_at_send_string("\r\nERROR:command should start with 'A'"STR_END_OF_ATCMD_RET); + } + return; + } + if(buf_count < (LOG_SERVICE_BUFLEN - 1)){ + temp_buf[buf_count] = rc; + buf_count++; + if(gAT_Echo == 1){ + serial_putc(sobj, rc); + } + } + else if(buf_count == (LOG_SERVICE_BUFLEN - 1)){ + temp_buf[buf_count] = '\0'; + if(gAT_Echo == 1){ + uart_at_send_string("\r\nERROR:exceed size limit"STR_END_OF_ATCMD_RET); + } + } + } + } +} + +void uart_atcmd_main(void) +{ + UART_LOG_CONF uartconf; + + read_uart_atcmd_setting_from_system_data(&uartconf); + serial_init(&at_cmd_sobj, UART_TX, UART_RX); + serial_baud(&at_cmd_sobj,uartconf.BaudRate); + serial_format(&at_cmd_sobj, uartconf.DataBits, (SerialParity)uartconf.Parity, uartconf.StopBits); + serial_rx_fifo_level(&at_cmd_sobj, FifoLvHalf); + // set flow control, only support RTS and CTS concurrent mode + // rxflow and tx flow is fixed by hardware + #define rxflow UART_RTS + #define txflow UART_CTS + if(uartconf.FlowControl){ + pin_mode(txflow, PullDown); //init CTS in low + serial_set_flow_control(&at_cmd_sobj, FlowControlRTSCTS, rxflow, txflow); + } + else + serial_set_flow_control(&at_cmd_sobj, FlowControlNone, rxflow, txflow); + + /*uart_at_lock_init();*/ + +#if UART_AT_USE_DMA_TX + RtlInitSema(&uart_at_dma_tx_sema, 1); +#endif + +#if UART_AT_USE_DMA_TX + serial_send_comp_handler(&at_cmd_sobj, (void*)uart_at_send_buf_done, (uint32_t)&at_cmd_sobj); +#endif + + serial_irq_handler(&at_cmd_sobj, uart_irq, (uint32_t)&at_cmd_sobj); + serial_irq_set(&at_cmd_sobj, RxIrq, 1); + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + uart_at_rx_wakeup(); +#endif +} + +static void uart_atcmd_thread(void *param) +{ + p_wlan_init_done_callback = NULL; +#if CONFIG_DEBUG_LOG > 3 + ConfigDebugErr = -1; + ConfigDebugInfo = ~_DBG_SPI_FLASH_; + ConfigDebugWarn = -1; + CfgSysDebugErr = -1; + CfgSysDebugInfo = -1; + CfgSysDebugWarn = -1; +#endif + atcmd_wifi_restore_from_flash(); + atcmd_lwip_restore_from_flash(); + vTaskDelay(20); //rtw_msleep_os(20); + uart_atcmd_main(); + at_printf("\r\nAT COMMAND READY"); + if(atcmd_lwip_is_tt_mode()) + at_printf(STR_END_OF_ATDATA_RET); + else + at_printf(STR_END_OF_ATCMD_RET); + _AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, STR_END_OF_ATCMD_RET); + vTaskDelete(NULL); +} + +int uart_atcmd_module_init(void){ +#if CONFIG_DEBUG_LOG > 3 + printf("Time at start %d ms.\n", xTaskGetTickCount()); +#endif + if(xTaskCreate(uart_atcmd_thread, ((const char*)"uart_atcmd_thread"), 1024, NULL, tskIDLE_PRIORITY + 1 , NULL) != pdPASS) // tskIDLE_PRIORITY + 1 + printf("\n\r%s xTaskCreate(uart_atcmd_thread) failed", __FUNCTION__); + return 0; +} + +void example_uart_atcmd(void) +{ + //if(xTaskCreate(uart_atcmd_thread, ((const char*)"uart_atcmd_thread"), 1024, NULL, tskIDLE_PRIORITY + 1 , NULL) != pdPASS) + // printf("\n\r%s xTaskCreate(uart_atcmd_thread) failed", __FUNCTION__); + p_wlan_init_done_callback = uart_atcmd_module_init; + return; +} +#endif diff --git a/USDK/component/common/example/uart_atcmd/example_uart_atcmd.h b/USDK/component/common/example/uart_atcmd/example_uart_atcmd.h new file mode 100644 index 0000000..2320f72 --- /dev/null +++ b/USDK/component/common/example/uart_atcmd/example_uart_atcmd.h @@ -0,0 +1,99 @@ +#ifndef __EXAMPLE_UART_ATCMD_H__ +#define __EXAMPLE_UART_ATCMD_H__ + +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#if CONFIG_EXAMPLE_UART_ATCMD +#include "FreeRTOS.h" +#include "semphr.h" +#include "osdep_api.h" + + +#if defined(RTL8710AF) +// RTL8710AF +#define UART_TX PA_4 // PC_3 +#define UART_RX PA_0 // PC_0 +#define UART_RTS PA_2 // PC_2 +#define UART_CTS PA_1 // PC_1 + +#elif 0 // defined(RTL8711AM) +// RTL8711AM +#define UART_TX PA_7 +#define UART_RX PA_6 // no Interrupt! +#define UART_RTS PA_3 +#define UART_CTS PA_5 + +#elif 0 // else +// RTL8711AM + RTL8710AF +#define UART_TX PC_3 +#define UART_RX PC_0 // no Interrupt! +#define UART_RTS PC_2 +#define UART_CTS PC_1 + +#elif defined(RTL8711AM) +// RTL8711AM + RTL8710AF +#define UART_TX PE_0 +#define UART_RX PE_3 +#define UART_RTS PE_1 +#define UART_CTS PE_2 + +#endif + +#define KEY_ENTER 0xd +#define KEY_BS 0x8 +#define KEY_ESC 0x1B +#define KEY_LBRKT 0x5B + +void uart_at_lock(void); +void uart_at_unlock(void); +void uart_at_send_string(char *str); +void uart_at_send_buf(u8 *buf, u32 len); +void example_uart_atcmd(void); + +#include "at_cmd/atcmd_wifi.h" + +void uart_atcmd_reinit(UART_LOG_CONF* uartconf); +int write_uart_atcmd_setting_to_system_data(UART_LOG_CONF* uartconf); + +extern u8 key_2char2num(u8 hch, u8 lch); +static void at_hex2str(const u8 *start, u32 size, u8 *out, u32 out_size) +{ + int index, index2; + u8 *buf, *line; + + if(!start ||(size==0)||(!out)||(out_size==0)) + return; + + buf = (u8*)start; + line = (u8*)out; + for (index = 0, index2=0; (index < size)&&(index2=0; i--) + { + rtp_uninit_payload(stream_ctx, &rtp_payload[i]); + } + goto exit; + } + } + + if(uvc_set_param(stream_ctx, UVC_FORMAT_MJPEG, 640, 480, 30)<0) + goto exit; + + if(uvc_stream_on(stream_ctx)<0) + goto exit; + + /*do buffer queue & dequeue inside the loop*/ + payload_queue.flush_err = 0; + while(!(payload_queue.flush_err)) + { + memset(&buf, 0, sizeof(struct uvc_buf_context)); + ret = uvc_dqbuf(stream_ctx, &buf); + if(buf.index < 0) + continue;//empty buffer retrieved + if((uvc_buf_check(&buf)<0)||(ret < 0)){ + RTSP_ERROR("\n\rbuffer error!"); + ret = -ENOENT; + goto exit; + } + rtp_payload[buf.index].index = buf.index; + if(rtp_fill_payload(stream_ctx, &rtp_payload[buf.index], buf.data, buf.len) < 0) + goto exit; + + /*add rtp_payload into payload queue*/ + RtlDownMutex(&payload_queue.wait_mutex); + list_add_tail(&rtp_payload[buf.index].rtp_list, &payload_queue.wait_queue); + RtlUpMutex(&payload_queue.wait_mutex); + RtlUpSema(&payload_queue.wait_sema); + + //check if any rtp payload is queued in done_queue + while(RtlDownSemaWithTimeout(&payload_queue.done_sema, 5)==0) + { + if(payload_queue.flush_err) + goto exit; + } + if(!list_empty(&payload_queue.done_queue)) + { + RtlDownMutex(&payload_queue.done_mutex); + payload = list_first_entry(&payload_queue.done_queue, struct rtp_object, rtp_list); + if(payload == NULL) + { + RtlUpMutex(&payload_queue.done_mutex); + continue; + } + list_del_init(&payload->rtp_list); + RtlUpMutex(&payload_queue.done_mutex); + + buf.index = payload->index; + buf.data = payload->data; + buf.len = payload->len; + + ret = uvc_qbuf(stream_ctx, &buf); + if (ret < 0){ + RTSP_ERROR("\n\rread_frame mmap method enqueue buffer failed"); + ret = -ENOENT; + goto exit; + } + } + } + +exit: + uvc_stream_off(stream_ctx); + uvc_stream_free(stream_ctx); + + for(i = 0; i < VIDEO_MAX_FRAME; i++) + { + rtp_uninit_payload(stream_ctx, &rtp_payload[i]); + } + + //free payload_queue memory + INIT_LIST_HEAD(&payload_queue.wait_queue); + INIT_LIST_HEAD(&payload_queue.done_queue); + RtlMutexFree(&payload_queue.wait_mutex); + RtlMutexFree(&payload_queue.done_mutex); + RtlFreeSema(&payload_queue.wait_sema); + RtlFreeSema(&payload_queue.done_sema); + + printf("\n\rstream free success, delete task..."); + vTaskDelete(NULL); +} + + + +int uvc_rtp_init(struct rtsp_context *rtsp_ctx); +void uvc_rtsp_handle(void *param) +{ + struct stream_context *stream_ctx = (struct stream_context *)param; + struct rtsp_context *rtsp_ctx; + u8 *request_header; //buffer to hold rtsp request + struct sockaddr_in server_addr, client_addr; + int client_socket; + socklen_t client_addr_len = sizeof(struct sockaddr_in); + + fd_set read_fds; + struct timeval timeout; + int ok; + rtsp_ctx = malloc(sizeof(struct rtsp_context)); + if(rtsp_ctx == NULL) + { + RTSP_ERROR("\n\rrtsp context is NULL"); + goto exit; + } + request_header = malloc(512); + if(request_header == NULL) + { + RTSP_ERROR("\n\rallocate request header buffer failed"); + goto exit; + } + // Delay to wait for IP by DHCP + vTaskDelay(500); + /*init rtsp context to unicast udp mode*/ + if(rtsp_context_init(rtsp_ctx) < 0) + goto exit; + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = *(uint32_t *)(rtsp_ctx->connect_ctx.server_ip)/*htonl(INADDR_ANY)*/; + server_addr.sin_port = htons(rtsp_ctx->connect_ctx.port); + + if(bind(rtsp_ctx->connect_ctx.socket_id, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + RTSP_ERROR("\n\rCannot bind stream socket"); + goto exit; + } + listen(rtsp_ctx->connect_ctx.socket_id, 1); + printf("\n\rrtsp context initialized!"); + + stream_ctx->protoCtx = (void *)rtsp_ctx; + rtsp_ctx->stream_ctx = (void *)stream_ctx; + + /*start rtp task*/ + uvc_rtp_init(rtsp_ctx); + + + while(stream_ctx->allowStream) + { + FD_ZERO(&read_fds); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + FD_SET(rtsp_ctx->connect_ctx.socket_id, &read_fds); + if(select(1, &read_fds, NULL, NULL, &timeout)) + { + client_socket = accept(rtsp_ctx->connect_ctx.socket_id,(struct sockaddr *)&client_addr, &client_addr_len); + if(client_socket < 0) + { + RTSP_ERROR("client_socket error:%d\r\n", client_socket); + close(client_socket); + continue; + } + *(rtsp_ctx->connect_ctx.remote_ip + 3) = (unsigned char) (client_addr.sin_addr.s_addr >> 24); + *(rtsp_ctx->connect_ctx.remote_ip + 2) = (unsigned char) (client_addr.sin_addr.s_addr >> 16); + *(rtsp_ctx->connect_ctx.remote_ip + 1) = (unsigned char) (client_addr.sin_addr.s_addr >> 8); + *(rtsp_ctx->connect_ctx.remote_ip) = (unsigned char) (client_addr.sin_addr.s_addr ); + + while(stream_ctx->allowStream) + { + + + read(client_socket, request_header, 512); + rtsp_readheader(request_header); + if(*request_header == 0) + { + + //Do I need to send error response to client? + continue; + } + + + rtsp_getparam(rtsp_ctx, request_header); + switch(rtsp_ctx->rtsp_cmd) + { + + case(CMD_OPTIONS): + RTSP_PRINTF("\n\rReceive options command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_options(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend OPTIONS response failed!"); + goto exit; + } + break; + + + + case(CMD_DESCRIBE): + RTSP_PRINTF("\n\rReceive describe command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_describe(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend DESCRIBE response failed!"); + goto exit; + } + break; + + + + case(CMD_SETUP): + RTSP_PRINTF("\n\rReceive setup command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + //fill transport parameter + rtsp_cmd_setup(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend SETUP response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_INIT) + { + + rtsp_ctx->state = RTSP_READY; + RTSP_PRINTF("\n\rstate changed from RTSP_INIT to RTSP_READY"); + }; + break; + + + case(CMD_TEARDOWN): + RTSP_PRINTF("\n\rReceive teardown command!"); + rtsp_ctx->state = RTSP_INIT; + rtsp_cmd_teardown(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend TEARDOWN response failed!"); + goto exit; + } + + + + + RTSP_PRINTF("\n\rstreaming teardown, state changed back to RTSP_INIT"); + /*have to wait until rtp server reinit*/ + vTaskDelay(1000); + goto out; + break; + + + case(CMD_PLAY): + RTSP_PRINTF("\n\rReceive play command!"); + if(rtsp_ctx->state == RTSP_PLAYING) + break; + + rtsp_cmd_play(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend PLAY response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_READY) + { + + rtsp_ctx->state = RTSP_PLAYING; + RTSP_PRINTF("\n\rstate changed from RTSP_READY to RTSP_PLAYING"); + rtsp_ctx->is_rtp_start = 1; + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + break; + + + + + case(CMD_PAUSE): + RTSP_PRINTF("\n\rReceive pause command!"); + rtsp_cmd_pause(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend PAUSE response failed!"); + goto exit; + } + + + if(rtsp_ctx->state == RTSP_PLAYING) + { + + rtsp_ctx->state = RTSP_READY; + RTSP_PRINTF("\n\rstate changed from RTSP_PLAYING to RTSP_READY"); + } + break; + default: + + + + RTSP_ERROR("\n\rReceive unrecognized command!"); + rtsp_cmd_error(rtsp_ctx); + ok = write(client_socket, rtsp_ctx->response, strlen(rtsp_ctx->response)); + if (ok <= 0) + { + + + RTSP_ERROR("\n\rsend ERROR response failed!"); + goto exit; + } + rtsp_ctx->state = RTSP_INIT; + } + if((rtsp_ctx->is_rtp_start == 0) && (rtsp_ctx->state == RTSP_PLAYING)) + { + + + rtsp_ctx->state = RTSP_INIT; + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + + + } +out: + rtsp_ctx->state = RTSP_INIT; + close(client_socket); + } + + } +exit: + if((rtsp_ctx->is_rtp_start) == 1){ + RtlUpSema(&rtsp_ctx->start_rtp_sema); + } + printf("\n\rrtsp -> Available heap 0x%x\n", xPortGetFreeHeapSize()); + close(client_socket); + close(rtsp_ctx->connect_ctx.socket_id); + if(request_header != NULL) + free(request_header); + /*wait until rtp task being destroyed*/ + while((rtsp_ctx->is_rtp_start)) + { + vTaskDelay(100); + } + rtsp_context_free(rtsp_ctx); + if(rtsp_ctx != NULL) + free(rtsp_ctx); + RTSP_ERROR("\n\rkill rtsp server thread!"); + //printf("Available heap 0x%x\n", xPortGetFreeHeapSize()); + //thread must be killed after server socket is terminated + vTaskDelete(NULL); + +} + + +void uvc_rtp_udp_init(struct stream_context *stream_ctx) +{ + + struct rtsp_context *rtsp_ctx = (struct rtsp_context *)stream_ctx->protoCtx; + struct uvc_buf_context buf; + struct rtp_object *payload; + struct sockaddr_in rtp_addr; + int rtp_socket; + int i, ret; + socklen_t addrlen = sizeof(struct sockaddr_in); + int rtp_port; + /* varibles for recording statistic use*/ + unsigned int cnt, total, total_time, time1, time2, time3; + cnt = total = total_time = time1 = time2 = time3 = 0; + /*init rtp socket*/ + rtp_socket = socket(AF_INET, SOCK_DGRAM, 0); + rtp_port = rtsp_ctx->transport.serverport_min; + memset(&rtp_addr, 0, addrlen); + rtp_addr.sin_family = AF_INET; + rtp_addr.sin_addr.s_addr = *(uint32_t *)(rtsp_ctx->connect_ctx.server_ip); + rtp_addr.sin_port = htons((u16)rtp_port); + if (bind(rtp_socket,(struct sockaddr *)&rtp_addr, addrlen)<0) { + RTSP_ERROR("bind failed\r\n"); + goto exit; + } + + +restart: + while((stream_ctx->isProcess)&&(rtsp_ctx->state == RTSP_PLAYING)) + { + if(RtlDownSemaWithTimeout(&payload_queue.wait_sema, 5)==0) + continue; + time1 = time3; + time2 = xTaskGetTickCount(); + /*send rtp payload*/ + if(!list_empty(&payload_queue.wait_queue)) + { + RtlDownMutex(&payload_queue.wait_mutex); + payload = list_first_entry(&payload_queue.wait_queue, struct rtp_object, rtp_list); + if(payload == NULL) + { + RtlUpMutex(&payload_queue.wait_mutex); + continue; + } + list_del_init(&payload->rtp_list); + RtlUpMutex(&payload_queue.wait_mutex); + + if(rtsp_ctx->state == RTSP_PLAYING) + { + + payload->connect_ctx.socket_id = rtp_socket; + payload->connect_ctx.port = (u16)rtsp_ctx->transport.clientport_min; + payload->connect_ctx.server_ip = rtsp_ctx->connect_ctx.server_ip; + payload->connect_ctx.remote_ip = rtsp_ctx->connect_ctx.remote_ip; + + ret = rtp_udp_send(stream_ctx, payload); + } + + //dequeue the this buffer from payload_queue + RtlDownMutex(&payload_queue.done_mutex); + list_add_tail(&payload->rtp_list, &payload_queue.done_queue); + RtlUpMutex(&payload_queue.done_mutex); + RtlUpSema(&payload_queue.done_sema); + + time3 = xTaskGetTickCount(); + cnt ++; + total += payload->len; + total_time += (time3-time1); + if(cnt == 100) + { + /* print statistics info */ + /*1.average frame size(kB) T:2.time waited for next frame sending start(ms)-3.udp sending time(ms) 4.frame rate(fps)*/ + printf("\n\r%dkB T:%d-%d %dfps", (total/102400), (time2 - time1), (time3 - time2), (100000/total_time)); + cnt = 0; + total = 0; + total_time = 0; + } + } + + } + mdelay(1000); + if(rtsp_ctx->state == RTSP_READY) + { + goto restart; + } + +exit: + close(rtp_socket); +} + +void uvc_rtp_tcp_init(struct stream_context *stream_ctx) +{ +} + +void uvc_rtp_multi_init(struct stream_context *stream_ctx) +{ +} + +void uvc_rtp_handle(void *param) +{ + struct stream_context *stream_ctx = (struct stream_context *)param; + struct rtsp_context *rtsp_ctx = (struct rtsp_context *)stream_ctx->protoCtx; + + /*go down when rtsp state change to playing*/ + while(1) + { + RtlDownSema(&rtsp_ctx->start_rtp_sema); + /*check rtp cast mode*/ + if(rtsp_ctx->state == RTSP_PLAYING) + { + printf("\n\rrtp start..."); + switch(rtsp_ctx->transport.castMode) + { + case(UNICAST_UDP_MODE): + uvc_rtp_udp_init(stream_ctx); + break; + case(MULTICAST_MODE): + uvc_rtp_tcp_init(stream_ctx); + break; + case(UNICAST_TCP_MODE): + uvc_rtp_multi_init(stream_ctx); + break; + default: + RTSP_ERROR("\r\n unknown streaming mode! Go back to RTSP_INIT state\n"); + rtsp_ctx->is_rtp_start = 0; + break; + } + }else{ + + break; + } + printf("\n\rrtp stop..."); + } + rtsp_ctx->is_rtp_start = 0; + RTSP_ERROR("\n\rkill rtp server thread!"); + //printf("Available heap 0x%x\n", xPortGetFreeHeapSize()); + vTaskDelete(NULL); +} + + +int uvc_rtp_init(struct rtsp_context *rtsp_ctx) +{ + struct stream_context *stream_ctx = (struct stream_context *)rtsp_ctx->stream_ctx; + + if(xTaskCreate(uvc_rtp_handle, ((const signed char*)"uvc_rtp_handle"), 2048, (void *)stream_ctx, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + RTSP_ERROR("\r\n uvc_rtp_handle: Create Task Error\n"); + return -1; + } + return 0; +} + +void uvc_task_init(void * param) +{ + +/*entry to start uvc streaming -- dequeue uvc buffer*/ + if(xTaskCreate(uvc_entry_handle, ((const signed char*)"uvc_entry_handle"), 1024, param, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + UVC_ERROR("\r\n uvc_entry_handle: Create Task Error\n"); + } + +/*entry to start rtsp server*/ +#if UVC_RTSP_EN + if(xTaskCreate(uvc_rtsp_handle, ((const signed char*)"uvc_rtsp_handle"), 4096, param, tskIDLE_PRIORITY + 2, NULL) != pdPASS) { + RTSP_ERROR("\r\n uvc_rtsp_handle: Create Task Error\n"); + } +#endif +} + + +/************************************************************end of rtsp/rtp with motion-jpeg************************************************/ diff --git a/USDK/component/common/example/uvc/example_uvc.h b/USDK/component/common/example/uvc/example_uvc.h new file mode 100644 index 0000000..12c2742 --- /dev/null +++ b/USDK/component/common/example/uvc/example_uvc.h @@ -0,0 +1,25 @@ +#ifndef EXAMPLE_UVC_H +#define EXAMPLE_UVC_H + +#include +#include "platform_opts.h" +#include "dlist.h" +#include "osdep_api.h" + +#define UVC_RTSP_EN 1 + +//example structure to handle rtp_object operation in queue +struct rtp_payload_queue +{ + struct list_head wait_queue; + _Mutex wait_mutex; + struct list_head done_queue; + _Mutex done_mutex; + _Sema wait_sema; //up it whenever a rtp payload queue in wait_queue + _Sema done_sema; //up it whenever a rtp payload queue in done_queue + int flush_err; +}; + +void example_uvc(void); + +#endif /* EXAMPLE_UVC_H */ \ No newline at end of file diff --git a/USDK/component/common/example/uvc/readme.txt b/USDK/component/common/example/uvc/readme.txt new file mode 100644 index 0000000..98298c4 --- /dev/null +++ b/USDK/component/common/example/uvc/readme.txt @@ -0,0 +1,8 @@ + +THis is an example for USB Video Capture specifically for motion-jpeg capturing. + +Please MAKE SURE to reserve enough heap size for UVC by raising configTOTAL_HEAP_SIZE in freeRTOSconfig.h & turning off some functions (e.g. WPS, JDSMART, ATcmd for internal and system) since image frame storing could consume quite large memory space. + +TO switch on UVC example, make sure CONFIG_USB_EN is enabled (in platform_autoconf.h) & set CONFIG_EXAMPLE_UVC to 1 (in platform_opts.h). + +TO combine uvc with rtsp server, make sure wlan module is enabled & set UVC_WLAN_TRANSFER to 1 (in example_uvc.h). \ No newline at end of file diff --git a/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.c b/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.c new file mode 100644 index 0000000..0db5390 --- /dev/null +++ b/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.c @@ -0,0 +1,226 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ + + /** @file + + This example demonstrate how to implement wifi fast reconnection +**/ +#include +#if defined(CONFIG_EXAMPLE_WLAN_FAST_CONNECT) && CONFIG_EXAMPLE_WLAN_FAST_CONNECT +#include + + +#include "task.h" +#include +#include +#include "flash_api.h" +#include +#ifdef USE_FLASH_EEP +#include "flash_eep.h" +#include "feep_config.h" +#endif + +write_reconnect_ptr p_write_reconnect_ptr; + +extern void fATW0(void *arg); +extern void fATW1(void *arg); +extern void fATW2(void *arg); +extern void fATWC(void *arg); + +/* +* Usage: +* wifi connection indication trigger this function to save current +* wifi profile in flash +* +* Condition: +* CONFIG_EXAMPLE_WLAN_FAST_CONNECT flag is set +*/ + +int wlan_write_reconnect_data_to_flash(u8 *data, uint32_t len) +{ + if(data == NULL || len < sizeof(struct wlan_fast_reconnect)) return -1; + DBG_8195A("WiFi connected at start %d ms\n", xTaskGetTickCount()); +#ifdef USE_FLASH_EEP + flash_write_cfg(data, FEEP_ID_WIFI_CFG, sizeof(struct wlan_fast_reconnect)); +#else + struct wlan_fast_reconnect read_data = {0}; + flash_t flash; + if(!data) return -1; + flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (u8 *) &read_data); + + //wirte it to flash if different content: SSID, Passphrase, Channel, Security type + if(memcmp(data, (u8 *) &read_data, sizeof(struct wlan_fast_reconnect)) != 0) { + DBG_8195A(" %s():not the same ssid/passphrase/channel, write new profile to flash\n", __func__); + flash_erase_sector(&flash, FAST_RECONNECT_DATA); + flash_stream_write(&flash, FAST_RECONNECT_DATA, len, (uint8_t *) data); + } +#endif + return 0; +} + +/* +* Usage: +* After wifi init done, waln driver call this function to check whether +* auto-connect is required. +* +* This function read previous saved wlan profile in flash and execute connection. +* +* Condition: +* CONFIG_EXAMPLE_WLAN_FAST_CONNECT flag is set +*/ +//scan_buf_arg scan_buf; + +int wlan_init_done_callback() +{ + flash_t flash; + struct wlan_fast_reconnect *data; + uint32_t channel; + uint8_t pscan_config; + char key_id[2] = {0}; +// wifi_disable_powersave(); +#if CONFIG_AUTO_RECONNECT + //setup reconnection flag +// u8 mode; +// if(wifi_get_autoreconnect(&mode) > 0 && mode != 1) + wifi_set_autoreconnect(1); // (not work if lib_wlan_mp.a ?) +#endif + DBG_8195A("WiFi Init after %d ms\n", xTaskGetTickCount()); + data = (struct wlan_fast_reconnect *)rtw_zmalloc(sizeof(struct wlan_fast_reconnect)); + if(data) { +#ifdef USE_FLASH_EEP + if (flash_read_cfg(data, FEEP_ID_WIFI_CFG, sizeof(struct wlan_fast_reconnect)) == sizeof(struct wlan_fast_reconnect)) { +#else + flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (uint8_t *)data); + if(*((uint32_t *) data) != ~0x0) { +#endif +#if 1 // not use AT +#if 0 + //set partial scan for entering to listen beacon quickly + channel = data->channel & 0xFF; + pscan_config = PSCAN_ENABLE |PSCAN_FAST_SURVEY; // PSCAN_SIMPLE_CONFIG | + if(wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1) < 0) + printf("Wifi set partial scan channel fail!\n"); +// rtw_network_info_t *wifi; +// SC_connect_to_candidate_AP +// SC_parse_scan_result_and_connect(); + if (wifi_connect( + NULL, + 0, + data->psk_essid, + data->security_type, + data->psk_passphrase, + RTW_SECURITY_OPEN, + NULL) == RTW_SUCCESS) { +#else + //set partial scan for entering to listen beacon quickly + channel = data->channel & 0xFF; + pscan_config = PSCAN_ENABLE |PSCAN_FAST_SURVEY; // PSCAN_SIMPLE_CONFIG | + if(wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1) < 0) + printf("Wifi set partial scan channel fail!\n"); +// channel = data->channel & 0xFF; + wifi_set_channel(1); //channel); +// wifi_set_channel_plan(channel); +// pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY; // PSCAN_SIMPLE_CONFIG | +// wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1); +// DiagPrintf("\nScan end at start %d ms.\n", xTaskGetTickCount()); +// u8 bssid[ETH_ALEN] = { 0x1a,0xfe,0x34,0x99,0xad,0x1d }; + u8 bssid[ETH_ALEN] = { 0xbc,0xae,0xc5,0xeb,0x09,0x90 }; + +// if (wifi_connect(data->psk_essid, data->security_type, data->psk_passphrase, strlen(data->psk_essid), strlen(data->psk_passphrase), RTW_SECURITY_OPEN, NULL) == RTW_SUCCESS) { + if (wifi_connect( + bssid, + 1, + data->psk_essid, + data->security_type, + data->psk_passphrase, + data->channel>>28, + NULL) == RTW_SUCCESS) { +#endif +// DBG_8195A("WiFi connected at start %dms\n", xTaskGetTickCount()); +#if CONFIG_LWIP_LAYER +#ifdef USE_FLASH_EEP + dhcp_cfg *p = (dhcp_cfg *)&data; + p->mode = 3; + extern struct netif xnetif[NET_IF_NUM]; + struct netif * pnetif = &xnetif[0]; + if(flash_read_cfg(p, FEEP_ID_DHCP_CFG, sizeof(dhcp_cfg)) > 1) { + rtl_printf("Read dhcp_config: mode = %d, ip:%p, msk:%p, gw:%p\n", p->mode, p->ip, p->mask, p->gw); + if(p->mode == 2) { + netif_set_addr(pnetif, (ip_addr_t *)&p->ip, (ip_addr_t *)&p->mask, (ip_addr_t *)&p->gw); + dhcps_init(pnetif); + } + else if(p->mode) LwIP_DHCP(0, DHCP_START); + } + else LwIP_DHCP(0, DHCP_START); + if(p->mode == 3 && pnetif->ip_addr.addr != 0) { + p->mode = 2; + p->ip = pnetif->ip_addr.addr; + p->gw = pnetif->gw.addr; + p->mask = pnetif->netmask.addr; + flash_write_cfg(p, FEEP_ID_DHCP_CFG, sizeof(dhcp_cfg)); + rtl_printf("Write dhcp_config: mode = %d, ip:%p, msk:%p, gw:%p\n", p->mode, p->ip, p->mask, p->gw); + } +#else + LwIP_DHCP(0, DHCP_START); +#endif //#if USE_FLASH_EEP +#endif //#if CONFIG_LWIP_LAYER +#if CONFIG_WLAN_CONNECT_CB + connect_start(); +#endif + } +#else +// flash_read_cfg(psk_essid, 0x5731, sizeof(psk_essid)); + memcpy(psk_essid, data->psk_essid, sizeof(data->psk_essid)); +// flash_read_cfg(psk_passphrase, 0x5732, sizeof(psk_passphrase)); + memcpy(psk_passphrase, data->psk_passphrase, sizeof(data->psk_passphrase)); +// flash_read_cfg(wpa_global_PSK, 0x5733, sizeof(wpa_global_PSK)); + memcpy(wpa_global_PSK, data->wpa_global_PSK, sizeof(data->wpa_global_PSK)); + //set partial scan for entering to listen beacon quickly + pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY; + channel = data->channel & 0xFF; + wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1); + //set wifi connect + switch(data->security_type){ + case RTW_SECURITY_OPEN: + fATW0((char*)psk_essid); + break; + case RTW_SECURITY_WEP_PSK: + fATW0((char*)psk_essid); + fATW1((char*)psk_passphrase); + sprintf(key_id,"%d",(char) (data->channel>>28)); + fATW2(key_id); + break; + case RTW_SECURITY_WPA_TKIP_PSK: + case RTW_SECURITY_WPA2_AES_PSK: + fATW0((char*)psk_essid); + fATW1((char*)psk_passphrase); + break; + default: + break; + } + fATWC(NULL); +#endif // use AT + } + rtw_mfree(data); + } + + return 0; +} + + +void example_wlan_fast_connect() +{ + // Call back from wlan driver after wlan init done + p_wlan_init_done_callback = wlan_init_done_callback; + + // Call back from application layer after wifi_connection success + p_write_reconnect_ptr = wlan_write_reconnect_data_to_flash; + +} + +#endif // defined(CONFIG_EXAMPLE_WLAN_FAST_CONNECT) && CONFIG_EXAMPLE_WLAN_FAST_CONNECT + diff --git a/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.h b/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.h new file mode 100644 index 0000000..b7efbed --- /dev/null +++ b/USDK/component/common/example/wlan_fast_connect/example_wlan_fast_connect.h @@ -0,0 +1,50 @@ +#ifndef __EXAMPLE_FAST_RECONNECTION_H__ +#define __EXAMPLE_FAST_RECONNECTION_H__ + + +/****************************************************************************** + * + * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#include "FreeRTOS.h" +#include +#include "main.h" + +#define IW_PASSPHRASE_MAX_SIZE 64 +//#define FAST_RECONNECT_DATA (0x80000 - 0x1000) +#define NDIS_802_11_LENGTH_SSID 32 +#define A_SHA_DIGEST_LEN 20 + + +struct wlan_fast_reconnect { + unsigned char psk_essid[NDIS_802_11_LENGTH_SSID + 4]; + unsigned char psk_passphrase[IW_PASSPHRASE_MAX_SIZE + 1]; + unsigned char wpa_global_PSK[A_SHA_DIGEST_LEN * 2]; + uint32_t channel; + uint32_t security_type; +#if ATCMD_VER == ATVER_2 + uint8_t enable; +#endif +}; + + + +typedef int (*wlan_init_done_ptr)(void); +typedef int (*write_reconnect_ptr)(uint8_t *data, uint32_t len); + + +//Variable +extern unsigned char psk_essid[NET_IF_NUM][NDIS_802_11_LENGTH_SSID+4]; +extern unsigned char psk_passphrase[NET_IF_NUM][IW_PASSPHRASE_MAX_SIZE + 1]; +extern unsigned char wpa_global_PSK[NET_IF_NUM][A_SHA_DIGEST_LEN * 2]; +extern unsigned char psk_passphrase64[IW_PASSPHRASE_MAX_SIZE + 1]; + +//Function +extern wlan_init_done_ptr p_wlan_init_done_callback; +extern write_reconnect_ptr p_write_reconnect_ptr; + +void example_wlan_fast_connect(void); + +#endif //#ifndef __EXAMPLE_FAST_RECONNECTION_H__ diff --git a/USDK/component/common/example/xml/example_xml.c b/USDK/component/common/example/xml/example_xml.c new file mode 100644 index 0000000..cf4abe5 --- /dev/null +++ b/USDK/component/common/example/xml/example_xml.c @@ -0,0 +1,111 @@ +#include "FreeRTOS.h" +#include "task.h" +#include +#include "xml.h" + +static void example_xml_thread(void *param) +{ + /* Create XML document + * + * on + * + * 255 + * 255 + * 255 + * + * + */ + struct xml_node *light_node, *power_node, *color_node, *red_node, *green_node, *blue_node; + + // Creates element with (prefix, tag name, namespace uri), add element and text node as child + light_node = xml_new_element("Home", "Light", "http://www.home.com"); + power_node = xml_new_element(NULL, "Power", NULL); + xml_add_child(power_node, xml_new_text("on")); + color_node = xml_new_element(NULL, "Color", NULL); + red_node = xml_new_element(NULL, "Red", NULL); + xml_add_child(red_node, xml_new_text("255")); + green_node = xml_new_element(NULL, "Green", NULL); + xml_add_child(green_node, xml_new_text("255")); + blue_node = xml_new_element(NULL, "Blue", NULL); + xml_add_child(blue_node, xml_new_text("255")); + xml_add_child(light_node, power_node); + xml_add_child(light_node, color_node); + xml_add_child(color_node, red_node); + xml_add_child(color_node, green_node); + xml_add_child(color_node, blue_node); + + // Add or modify attributes + xml_set_attribute(light_node, "xmlns", "http://www.device.com"); + xml_set_attribute(light_node, "fw_ver", "1.0.0"); + + // Dump XML document to memory buffer, equal to xml_dump_tree_ex(node, NULL, 0, 0); + char *dump_buf = xml_dump_tree(light_node); + printf("\n%s\n", dump_buf); + // Free dump buffer + xml_free(dump_buf); + // Dump XML document to memory buffer with prolog, new line, aligment + dump_buf = xml_dump_tree_ex(light_node, "", 1, 4); + printf("\n%s\n", dump_buf); + xml_free(dump_buf); + + // Delete XML tree to free memory + xml_delete_tree(light_node); + + /* Parse XML document */ + char *doc = "\ + \ + \ + \ + \ + auto\ + 25.5\ + \ + "; + + // Parse document buffer to XML tree. Prolog will be dropped + struct xml_node *root = xml_parse(doc, strlen(doc)); + + if(root) { + dump_buf = xml_dump_tree_ex(root, NULL, 1, 4); + printf("\n%s\n", dump_buf); + xml_free(dump_buf); + + // Search by XPath, prefix and name in path should be matched + struct xml_node_set *set = xml_find_path(root, "/Home:Sensor/Thermostat/Temperature"); + + if(set->count) { + printf("\nFind %d element by %s\n", set->count, "/Home:Sensor/Thermostat/Temperature"); + + // Get XML tree search result 0 + struct xml_node *temperature_node = set->node[0]; + + if(xml_is_text(temperature_node->child)) { + // Get text + printf("Temperature[0] is %s\n", temperature_node->child->text); + } + + // Get attribute + char *unit = xml_get_attribute(temperature_node, "unit"); + printf("Unit is \"%s\"\n", unit); + // Free attribute search result + xml_free(unit); + } + + // Delete XML tree search result to free memory + xml_delete_set(set); + + xml_delete_tree(root); + } + else { + printf("Xml parse failed\n"); + } + + vTaskDelete(NULL); +} + +void example_xml(void) +{ + if(xTaskCreate(example_xml_thread, ((const char*)"example_xml_thread"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__); +} + diff --git a/USDK/component/common/example/xml/example_xml.h b/USDK/component/common/example/xml/example_xml.h new file mode 100644 index 0000000..1dbcf5f --- /dev/null +++ b/USDK/component/common/example/xml/example_xml.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_XML_H +#define EXAMPLE_XML_H + +void example_xml(void); + +#endif /* EXAMPLE_XML_H */ diff --git a/USDK/component/common/example/xml/readme.txt b/USDK/component/common/example/xml/readme.txt new file mode 100644 index 0000000..9fb461c --- /dev/null +++ b/USDK/component/common/example/xml/readme.txt @@ -0,0 +1,13 @@ +XML EXAMPLE + +Description: +The creation of a light XML document is used as the example of XML document generation. +The processing of a sensor XML document is used as the example of XML document parsing. + +Configuration: +[platform_opts.h] + #define CONFIG_EXAMPLE_XML 1 + +Execution: +An XML example thread will be started automatically when booting. + diff --git a/USDK/component/common/file_system/fatfs/disk_if/inc/atadrive.h b/USDK/component/common/file_system/fatfs/disk_if/inc/atadrive.h new file mode 100644 index 0000000..715ae8c --- /dev/null +++ b/USDK/component/common/file_system/fatfs/disk_if/inc/atadrive.h @@ -0,0 +1,7 @@ +#ifndef _ATADRIVE_H_ +#define _ATADRIVE_H_ + +#include "fatfs_ext/inc/ff_driver.h" + +extern ll_diskio_drv ATA_disk_Driver; +#endif diff --git a/USDK/component/common/file_system/fatfs/disk_if/inc/sdcard.h b/USDK/component/common/file_system/fatfs/disk_if/inc/sdcard.h new file mode 100644 index 0000000..a9ed1d8 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/disk_if/inc/sdcard.h @@ -0,0 +1,6 @@ +#ifndef _SDCARD_H_ +#define _SDCARD_H_ +#include "fatfs_ext/inc/ff_driver.h" + +extern ll_diskio_drv SD_disk_Driver; +#endif diff --git a/USDK/component/common/file_system/fatfs/disk_if/inc/usbdisk.h b/USDK/component/common/file_system/fatfs/disk_if/inc/usbdisk.h new file mode 100644 index 0000000..023616b --- /dev/null +++ b/USDK/component/common/file_system/fatfs/disk_if/inc/usbdisk.h @@ -0,0 +1,8 @@ +#ifndef _USBDISK_H_ +#define _USBDISK_H_ + +#include "fatfs_ext/inc/ff_driver.h" + +extern ll_diskio_drv USB_disk_Driver; +#endif + diff --git a/USDK/component/common/file_system/fatfs/disk_if/src/sdcard.c b/USDK/component/common/file_system/fatfs/disk_if/src/sdcard.c new file mode 100644 index 0000000..f7ee687 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/disk_if/src/sdcard.c @@ -0,0 +1,133 @@ +/* + * Routines to associate SD card driver with FatFs + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "integer.h" +#include + +#if FATFS_DISK_SD + +#include "sd.h" // sd card driver with sdio interface + +#define SD_BLOCK_SIZE 512 + +static int interpret_sd_result(SD_RESULT result){ + int ret = 0; + if(result == SD_OK) + ret = 0; + else if(result == SD_NODISK) + ret = STA_NODISK; + else if(result == SD_INITERR) + ret = STA_NOINIT; + else if(result == SD_PROTECTED) + ret = STA_PROTECT; + return ret; +} + +DSTATUS SD_disk_status(void){ + SD_RESULT res; + res = SD_Status(); + return interpret_sd_result(res);; +} + +DSTATUS SD_disk_initialize(void){ + SD_RESULT res; + res = SD_Init(); + return interpret_sd_result(res); +} + +/* Read sector(s) --------------------------------------------*/ +DRESULT SD_disk_read(BYTE *buff, DWORD sector, UINT count){ + SD_RESULT res; + + res = SD_ReadBlocks(sector, buff, count); + + //__rtl_memDump_v1_00(buff, 512*count, "MMC_disk_read:"); + + return interpret_sd_result(res); +} + +/* Write sector(s) --------------------------------------------*/ +#if _USE_WRITE == 1 +DRESULT SD_disk_write(const BYTE *buff, DWORD sector, UINT count){ + SD_RESULT res; + res = SD_WriteBlocks(sector, buff, count); + + return interpret_sd_result(res); +} +#endif + +/* Write sector(s) --------------------------------------------*/ +#if _USE_IOCTL == 1 +DRESULT SD_disk_ioctl (BYTE cmd, void* buff){ + DRESULT res = RES_ERROR; + SD_RESULT result; + DWORD last_blk_addr, block_size; + + switch(cmd){ + /* Generic command (used by FatFs) */ + + /* Make sure that no pending write process in the physical drive */ + case CTRL_SYNC: /* Flush disk cache (for write functions) */ + result = SD_WaitReady(); + res = interpret_sd_result(result); + break; + case GET_SECTOR_COUNT: /* Get media size (for only f_mkfs()) */ + result = SD_GetCapacity((unsigned long*) buff); + res = interpret_sd_result(result); + break; + /* for case _MAX_SS != _MIN_SS */ + case GET_SECTOR_SIZE: /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ + //*(DWORD*)buff = 1024;//2048;//4096; + res = RES_OK; + break; + case GET_BLOCK_SIZE: /* Get erase block size (for only f_mkfs()) */ + *(DWORD*)buff = SD_BLOCK_SIZE; + res = RES_OK; + break; + case CTRL_ERASE_SECTOR:/* Force erased a block of sectors (for only _USE_ERASE) */ + res = RES_OK; + break; + + /* MMC/SDC specific ioctl command */ + + case MMC_GET_TYPE: /* Get card type */ + res = RES_OK; + break; + case MMC_GET_CSD: /* Get CSD */ + res = RES_OK; + break; + case MMC_GET_CID: /* Get CID */ + res = RES_OK; + break; + case MMC_GET_OCR: /* Get OCR */ + res = RES_OK; + break; + case MMC_GET_SDSTAT:/* Get SD status */ + res = RES_OK; + break; + default: + res = RES_PARERR; + break; + } + return res; +} +#endif + +ll_diskio_drv SD_disk_Driver ={ + .disk_initialize = SD_disk_initialize, + .disk_status = SD_disk_status, + .disk_read = SD_disk_read, +#if _USE_WRITE == 1 + .disk_write = SD_disk_write, +#endif +#if _USE_IOCTL == 1 + .disk_ioctl = SD_disk_ioctl, +#endif + .TAG = "SD" +}; +#endif diff --git a/USDK/component/common/file_system/fatfs/disk_if/src/usbdisk.c b/USDK/component/common/file_system/fatfs/disk_if/src/usbdisk.c new file mode 100644 index 0000000..016b32c --- /dev/null +++ b/USDK/component/common/file_system/fatfs/disk_if/src/usbdisk.c @@ -0,0 +1,122 @@ +/* + * Routines to associate usb mass storage driver with FatFs + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "integer.h" +#include + +#if FATFS_DISK_USB +#include "us_intf.h" + +DSTATUS USB_disk_status(void){ + MSC_RESULT res; + if(USB_STORAGE_READY){ + res = us_getStatus(); + if(res == MSC_W_PROTECT) + return STA_PROTECT; + else + return 0; // every thing is ok + } + return STA_NOINIT; +} + +DSTATUS USB_disk_initialize(void){ + MSC_RESULT res; + + if(USB_STORAGE_READY) + return 0; + + res = us_init(); + + if(res == MSC_OK) + return 0; + else + return STA_NOINIT; +} + +/* Read sector(s) --------------------------------------------*/ +DRESULT USB_disk_read(BYTE *buff, DWORD sector, UINT count){ + if(!USB_STORAGE_READY) + return RES_NOTRDY; + + if(us_read_blocks(buff, sector, count) == MSC_OK) + return RES_OK; + else + return RES_ERROR; +} + +/* Write sector(s) --------------------------------------------*/ +#if _USE_WRITE == 1 +DRESULT USB_disk_write(const BYTE *buff, DWORD sector, UINT count){ + if(!USB_STORAGE_READY) + return RES_NOTRDY; + + if(us_write_blocks(buff, sector, count) == MSC_OK) + return RES_OK; + else + return RES_ERROR; +} +#endif + +/* Write sector(s) --------------------------------------------*/ +#if _USE_IOCTL == 1 +DRESULT USB_disk_ioctl (BYTE cmd, void* buff){ + DRESULT res = RES_ERROR; + DWORD last_blk_addr, block_size; + + if(!USB_STORAGE_READY) + return RES_NOTRDY; + + switch(cmd){ + /* Generic command (used by FatFs) */ + + case CTRL_SYNC: /* Flush disk cache (for write functions) */ + res = RES_OK; + break; + case GET_SECTOR_COUNT: /* Get media size (for only f_mkfs()) */ + if(us_getcap(&last_blk_addr, &block_size) == MSC_OK){ + *(DWORD*)buff = last_blk_addr + 1; + res = RES_OK; + }else + res = RES_ERROR; + break; + case GET_SECTOR_SIZE: /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ + if(us_getcap(&last_blk_addr, &block_size) == MSC_OK){ + *(DWORD*)buff = block_size; + res = RES_OK; + }else + res = RES_ERROR; + break; + case GET_BLOCK_SIZE: /* Get erase block size (for only f_mkfs()) */ + *(DWORD*)buff = 512; + res = RES_OK; + break; + case CTRL_ERASE_SECTOR:/* Force erased a block of sectors (for only _USE_ERASE) */ + res = RES_OK; + break; + default: + res = RES_PARERR; + break; + } + return res; +} +#endif + +ll_diskio_drv USB_disk_Driver ={ + .disk_initialize = USB_disk_initialize, + .disk_status = USB_disk_status, + .disk_read = USB_disk_read, +#if _USE_WRITE == 1 + .disk_write = USB_disk_write, +#endif +#if _USE_IOCTL == 1 + .disk_ioctl = USB_disk_ioctl, +#endif + .TAG = "USB" +}; + +#endif diff --git a/USDK/component/common/file_system/fatfs/fatfs_ext/inc/ff_driver.h b/USDK/component/common/file_system/fatfs/fatfs_ext/inc/ff_driver.h new file mode 100644 index 0000000..4c5ed6b --- /dev/null +++ b/USDK/component/common/file_system/fatfs/fatfs_ext/inc/ff_driver.h @@ -0,0 +1,34 @@ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FF_DRIVER_H +#define __FF_DRIVER_H + +/* Includes ------------------------------------------------------------------*/ +#include "diskio.h" +#include "ff.h" +#include "platform_opts.h" + +typedef struct{ + DSTATUS (*disk_initialize) (void); /*!< Initialize Disk Drive */ + DSTATUS (*disk_status) (void); /*!< Get Disk Status */ + DRESULT (*disk_read) (BYTE*, DWORD, UINT); /*!< Read Sector(s) */ +#if _USE_WRITE == 1 + DRESULT (*disk_write) (const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */ +#endif /* _USE_WRITE == 1 */ +#if _USE_IOCTL == 1 + DRESULT (*disk_ioctl) (BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */ +#endif /* _USE_IOCTL == 1 */ + unsigned char* TAG; + unsigned char drv_num; +}ll_diskio_drv; + +typedef struct{ + ll_diskio_drv *drv[_VOLUMES]; + unsigned int nbr; +}ff_disk_drv; +extern ff_disk_drv disk; + +int FATFS_RegisterDiskDriver(ll_diskio_drv *disk_drv); +int FATFS_UnRegisterDiskDriver(unsigned char drv_num); +int FATFS_getDrivernum(unsigned char* TAG); + +#endif diff --git a/USDK/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c b/USDK/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c new file mode 100644 index 0000000..f18e832 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c @@ -0,0 +1,57 @@ +#include + +#include "rtl_lib.h" +#define strcmp(s1, s2) rtl_strcmp((const char *)s1, (const char *)s2) + +ff_disk_drv disk = {0}; + +// return drv_num assigned +int FATFS_RegisterDiskDriver(ll_diskio_drv *drv){ + unsigned char drv_num = -1; + + if(disk.nbr < _VOLUMES) + { + drv->drv_num = disk.nbr; // record driver number for a specific disk + disk.drv[disk.nbr] = drv; + disk.nbr++; + drv_num = drv->drv_num; + } + return drv_num; +} + +int FATFS_UnRegisterDiskDriver(unsigned char drv_num){ + int index; + + if(disk.nbr >= 1) + { + for(index=0;indexdrv_num == drv_num){ + disk.drv[index] = 0; + disk.nbr--; + return 0; + } + } + return -1; // fail + } + return -1; // no disk driver registered +} + + +/** + * @brief Gets number of linked drivers to the FatFs module. + * @param None + * @retval Number of attached drivers. + */ +int FATFS_getDrivernum(unsigned char* TAG) +{ + ll_diskio_drv *drv; + int index; + + for(index=0;indexTAG, TAG)){ + return drv->drv_num; + } + } + return -1; +} diff --git a/USDK/component/common/file_system/fatfs/r0.10c/Makefile b/USDK/component/common/file_system/fatfs/r0.10c/Makefile new file mode 100644 index 0000000..31bd89d --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/Makefile @@ -0,0 +1,29 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = + + +#*****************************************************************************# +# Dependency # +#*****************************************************************************# +-include $(OBJS:.o=.d) + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS + make -C src all + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/include/diskio.h b/USDK/component/common/file_system/fatfs/r0.10c/include/diskio.h new file mode 100644 index 0000000..4d72b91 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/include/diskio.h @@ -0,0 +1,80 @@ +/*-----------------------------------------------------------------------/ +/ Low level disk interface modlue include file (C)ChaN, 2013 / +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +#define _USE_WRITE 1 /* 1: Enable disk_write function */ +#define _USE_IOCTL 1 /* 1: Enable disk_ioctl fucntion */ + +#include "integer.h" + + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (used by FatFs) */ +#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */ +#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */ +#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */ + +/* Generic command (not used by FatFs) */ +#define CTRL_POWER 5 /* Get/Set power status */ +#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/file_system/fatfs/r0.10c/include/ff.h b/USDK/component/common/file_system/fatfs/r0.10c/include/ff.h new file mode 100644 index 0000000..a93d9a2 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/include/ff.h @@ -0,0 +1,342 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module include file R0.10b (C)ChaN, 2014 +/----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2014, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/----------------------------------------------------------------------------*/ + +#ifndef _FATFS +#define _FATFS 8051 /* Revision ID */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "integer.h" /* Basic integer types */ +#include "ffconf.h" /* FatFs configuration options */ + +#if _FATFS != _FFCONF +#error Wrong configuration file (ffconf.h). +#endif + + + +/* Definitions of volume management */ + +#if _MULTI_PARTITION /* Multiple partition configuration */ +typedef struct { + BYTE pd; /* Physical drive number */ + BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ +} PARTITION; +extern PARTITION VolToPart[]; /* Volume - Partition resolution table */ +#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */ +#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */ + +#else /* Single partition configuration */ +#define LD2PD(vol) (BYTE)(vol) /* Each logical drive is bound to the same physical drive number */ +#define LD2PT(vol) 0 /* Find first valid partition or in SFD */ + +#endif + + + +/* Type of path name strings on FatFs API */ + +#if _LFN_UNICODE /* Unicode string */ +#if !_USE_LFN +#error _LFN_UNICODE must be 0 at non-LFN cfg. +#endif +#ifndef _INC_TCHAR +typedef WCHAR TCHAR; +#define _T(x) L ## x +#define _TEXT(x) L ## x +#endif + +#else /* ANSI/OEM string */ +#ifndef _INC_TCHAR +typedef char TCHAR; +#define _T(x) x +#define _TEXT(x) x +#endif + +#endif + + + +/* File system object structure (FATFS) */ + +typedef struct { + BYTE fs_type; /* FAT sub-type (0:Not mounted) */ + BYTE drv; /* Physical drive number */ + BYTE csize; /* Sectors per cluster (1,2,4...128) */ + BYTE n_fats; /* Number of FAT copies (1 or 2) */ + BYTE wflag; /* win[] flag (b0:dirty) */ + BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ + WORD id; /* File system mount ID */ + WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ +#if _MAX_SS != _MIN_SS + WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */ +#endif +#if _FS_REENTRANT + _SYNC_t sobj; /* Identifier of sync object */ +#endif +#if !_FS_READONLY + DWORD last_clust; /* Last allocated cluster */ + DWORD free_clust; /* Number of free clusters */ +#endif +#if _FS_RPATH + DWORD cdir; /* Current directory start cluster (0:root) */ +#endif + DWORD n_fatent; /* Number of FAT entries, = number of clusters + 2 */ + DWORD fsize; /* Sectors per FAT */ + DWORD volbase; /* Volume start sector */ + DWORD fatbase; /* FAT start sector */ + DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */ + DWORD database; /* Data start sector */ + DWORD winsect; /* Current sector appearing in the win[] */ + BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ +} FATFS; + + + +/* File object structure (FIL) */ + +typedef struct { + FATFS* fs; /* Pointer to the related file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + BYTE flag; /* Status flags */ + BYTE err; /* Abort flag (error code) */ + DWORD fptr; /* File read/write pointer (Zeroed on file open) */ + DWORD fsize; /* File size */ + DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */ + DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */ + DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */ +#if !_FS_READONLY + DWORD dir_sect; /* Sector number containing the directory entry */ + BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */ +#endif +#if _USE_FASTSEEK + DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */ +#endif +#if _FS_LOCK + UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ +#endif +#if !_FS_TINY + BYTE buf[_MAX_SS]; /* File private data read/write window */ +#endif +} FIL; + + + +/* Directory object structure (DIR) */ + +typedef struct { + FATFS* fs; /* Pointer to the owner file system object (**do not change order**) */ + WORD id; /* Owner file system mount ID (**do not change order**) */ + WORD index; /* Current read/write index number */ + DWORD sclust; /* Table start cluster (0:Root dir) */ + DWORD clust; /* Current cluster */ + DWORD sect; /* Current sector */ + BYTE* dir; /* Pointer to the current SFN entry in the win[] */ + BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */ +#if _FS_LOCK + UINT lockid; /* File lock ID (index of file semaphore table Files[]) */ +#endif +#if _USE_LFN + WCHAR* lfn; /* Pointer to the LFN working buffer */ + WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */ +#endif +} DIR; + + + +/* File status structure (FILINFO) */ + +typedef struct { + DWORD fsize; /* File size */ + WORD fdate; /* Last modified date */ + WORD ftime; /* Last modified time */ + BYTE fattrib; /* Attribute */ + TCHAR fname[13]; /* Short file name (8.3 format) */ +#if _USE_LFN + TCHAR* lfname; /* Pointer to the LFN buffer */ + UINT lfsize; /* Size of LFN buffer in TCHAR */ +#endif +} FILINFO; + + + +/* File function return code (FRESULT) */ + +typedef enum { + FR_OK = 0, /* (0) Succeeded */ + FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ + FR_INT_ERR, /* (2) Assertion failed */ + FR_NOT_READY, /* (3) The physical drive cannot work */ + FR_NO_FILE, /* (4) Could not find the file */ + FR_NO_PATH, /* (5) Could not find the path */ + FR_INVALID_NAME, /* (6) The path name format is invalid */ + FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ + FR_EXIST, /* (8) Access denied due to prohibited access */ + FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ + FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ + FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ + FR_NOT_ENABLED, /* (12) The volume has no work area */ + FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ + FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */ + FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ + FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ + FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ + FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */ + FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ +} FRESULT; + + + +/*--------------------------------------------------------------*/ +/* FatFs module application interface */ + +FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ +FRESULT f_close (FIL* fp); /* Close an open file object */ +FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from a file */ +FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to a file */ +FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ +FRESULT f_lseek (FIL* fp, DWORD ofs); /* Move file pointer of a file object */ +FRESULT f_truncate (FIL* fp); /* Truncate file */ +FRESULT f_sync (FIL* fp); /* Flush cached data of a writing file */ +FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ +FRESULT f_closedir (DIR* dp); /* Close an open directory */ +FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ +FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ +FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ +FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ +FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ +FRESULT f_chmod (const TCHAR* path, BYTE value, BYTE mask); /* Change attribute of the file/dir */ +FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change times-tamp of the file/dir */ +FRESULT f_chdir (const TCHAR* path); /* Change current directory */ +FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ +FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ +FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ +FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ +FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ +FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ +FRESULT f_mkfs (const TCHAR* path, BYTE sfd, UINT au); /* Create a file system on the volume */ +FRESULT f_fdisk (BYTE pdrv, const DWORD szt[], void* work); /* Divide a physical drive into some partitions */ +int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ +int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ +int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ +TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ + +#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0) +#define f_error(fp) ((fp)->err) +#define f_tell(fp) ((fp)->fptr) +#define f_size(fp) ((fp)->fsize) + +#ifndef EOF +#define EOF (-1) +#endif + + + + +/*--------------------------------------------------------------*/ +/* Additional user defined functions */ + +/* RTC function */ +#if !_FS_READONLY +DWORD get_fattime (void); +#endif + +/* Unicode support functions */ +#if _USE_LFN /* Unicode - OEM code conversion */ +WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */ +WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */ +#if _USE_LFN == 3 /* Memory functions */ +void* ff_memalloc (UINT msize); /* Allocate memory block */ +void ff_memfree (void* mblock); /* Free memory block */ +#endif +#endif + +/* Sync functions */ +#if _FS_REENTRANT +int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */ +int ff_req_grant (_SYNC_t sobj); /* Lock sync object */ +void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */ +int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */ +#endif + + + + +/*--------------------------------------------------------------*/ +/* Flags and offset address */ + + +/* File access control and file status flags (FIL.flag) */ + +#define FA_READ 0x01 +#define FA_OPEN_EXISTING 0x00 + +#if !_FS_READONLY +#define FA_WRITE 0x02 +#define FA_CREATE_NEW 0x04 +#define FA_CREATE_ALWAYS 0x08 +#define FA_OPEN_ALWAYS 0x10 +#define FA__WRITTEN 0x20 +#define FA__DIRTY 0x40 +#endif + + +/* FAT sub type (FATFS.fs_type) */ + +#define FS_FAT12 1 +#define FS_FAT16 2 +#define FS_FAT32 3 + + +/* File attribute bits for directory entry */ + +#define AM_RDO 0x01 /* Read only */ +#define AM_HID 0x02 /* Hidden */ +#define AM_SYS 0x04 /* System */ +#define AM_VOL 0x08 /* Volume label */ +#define AM_LFN 0x0F /* LFN entry */ +#define AM_DIR 0x10 /* Directory */ +#define AM_ARC 0x20 /* Archive */ +#define AM_MASK 0x3F /* Mask of defined bits */ + + +/* Fast seek feature */ +#define CREATE_LINKMAP 0xFFFFFFFF + + + +/*--------------------------------*/ +/* Multi-byte word access macros */ + +#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val) +#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val) +#else /* Use byte-by-byte access to the FAT structure */ +#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr)) +#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr)) +#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8) +#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _FATFS */ diff --git a/USDK/component/common/file_system/fatfs/r0.10c/include/ffconf.h b/USDK/component/common/file_system/fatfs/r0.10c/include/ffconf.h new file mode 100644 index 0000000..85f3005 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/include/ffconf.h @@ -0,0 +1,228 @@ +/*---------------------------------------------------------------------------/ +/ FatFs - FAT file system module configuration file R0.10b (C)ChaN, 2014 +/---------------------------------------------------------------------------*/ + +#ifndef _FFCONF +#define _FFCONF 8051 /* Revision ID */ + + +/*---------------------------------------------------------------------------/ +/ Functions and Buffer Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_TINY 0 /* 0:Normal or 1:Tiny */ +/* When _FS_TINY is set to 1, it reduces memory consumption _MAX_SS bytes each +/ file object. For file data transfer, FatFs uses the common sector buffer in +/ the file system object (FATFS) instead of private sector buffer eliminated +/ from the file object (FIL). */ + + +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ +/* Setting _FS_READONLY to 1 defines read only configuration. This removes +/ writing functions, f_write(), f_sync(), f_unlink(), f_mkdir(), f_chmod(), +/ f_rename(), f_truncate() and useless f_getfree(). */ + + +#define _FS_MINIMIZE 0 /* 0 to 3 */ +/* The _FS_MINIMIZE option defines minimization level to remove API functions. +/ +/ 0: All basic functions are enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), +/ f_truncate() and f_rename() function are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define _USE_STRFUNC 0 /* 0:Disable or 1-2:Enable */ +/* To enable string functions, set _USE_STRFUNC to 1 or 2. */ + + +#define _USE_MKFS 0 /* 0:Disable or 1:Enable */ +/* To enable f_mkfs() function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ + + +#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */ +/* To enable fast seek feature, set _USE_FASTSEEK to 1. */ + + +#define _USE_LABEL 1 /* 0:Disable or 1:Enable */ +/* To enable volume label functions, set _USE_LAVEL to 1 */ + + +#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */ +/* To enable f_forward() function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define _CODE_PAGE 866 // 437 +/* The _CODE_PAGE specifies the OEM code page to be used on the target system. +/ Incorrect setting of the code page can cause a file open failure. +/ +/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows) +/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows) +/ 949 - Korean (DBCS, OEM, Windows) +/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) +/ 1250 - Central Europe (Windows) +/ 1251 - Cyrillic (Windows) +/ 1252 - Latin 1 (Windows) +/ 1253 - Greek (Windows) +/ 1254 - Turkish (Windows) +/ 1255 - Hebrew (Windows) +/ 1256 - Arabic (Windows) +/ 1257 - Baltic (Windows) +/ 1258 - Vietnam (OEM, Windows) +/ 437 - U.S. (OEM) +/ 720 - Arabic (OEM) +/ 737 - Greek (OEM) +/ 775 - Baltic (OEM) +/ 850 - Multilingual Latin 1 (OEM) +/ 858 - Multilingual Latin 1 + Euro (OEM) +/ 852 - Latin 2 (OEM) +/ 855 - Cyrillic (OEM) +/ 866 - Russian (OEM) +/ 857 - Turkish (OEM) +/ 862 - Hebrew (OEM) +/ 874 - Thai (OEM, Windows) +/ 1 - ASCII (Valid for only non-LFN configuration) */ + + +#define _USE_LFN 1 /* 0 to 3 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +/* The _USE_LFN option switches the LFN feature. +/ +/ 0: Disable LFN feature. _MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ When enable LFN feature, Unicode handling functions ff_convert() and ff_wtoupper() +/ function must be added to the project. +/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. When use stack for the +/ working buffer, take care on stack overflow. When use heap memory for the working +/ buffer, memory management functions, ff_memalloc() and ff_memfree(), must be added +/ to the project. */ + + +#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +/* To switch the character encoding on the FatFs API (TCHAR) to Unicode, enable LFN +/ feature and set _LFN_UNICODE to 1. This option affects behavior of string I/O +/ functions. This option must be 0 when LFN feature is not enabled. */ + + +#define _STRF_ENCODE 3 /* 0:ANSI/OEM, 1:UTF-16LE, 2:UTF-16BE, 3:UTF-8 */ +/* When Unicode API is enabled by _LFN_UNICODE option, this option selects the character +/ encoding on the file to be read/written via string I/O functions, f_gets(), f_putc(), +/ f_puts and f_printf(). This option has no effect when _LFN_UNICODE == 0. Note that +/ FatFs supports only BMP. */ + + +#define _FS_RPATH 0 /* 0 to 2 */ +/* The _FS_RPATH option configures relative path feature. +/ +/ 0: Disable relative path feature and remove related functions. +/ 1: Enable relative path. f_chdrive() and f_chdir() function are available. +/ 2: f_getcwd() function is available in addition to 1. +/ +/ Note that output of the f_readdir() fnction is affected by this option. */ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define _VOLUMES 1 +/* Number of volumes (logical drives) to be used. */ + + +#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */ +#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3" +/* When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive +/ number in the path name. _VOLUME_STRS defines the drive ID strings for each logical +/ drives. Number of items must be equal to _VOLUMES. Valid characters for the drive ID +/ strings are: 0-9 and A-Z. */ + + +#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Enable multiple partition */ +/* By default(0), each logical drive number is bound to the same physical drive number +/ and only a FAT volume found on the physical drive is mounted. When it is set to 1, +/ each logical drive number is bound to arbitrary drive/partition listed in VolToPart[]. +*/ + + +#define _MIN_SS 512 +#define _MAX_SS 512 +/* These options configure the range of sector size to be supported. (512, 1024, 2048 or +/ 4096) Always set both 512 for most systems, all memory card and harddisk. But a larger +/ value may be required for on-board flash memory and some type of optical media. +/ When _MAX_SS is larger than _MIN_SS, FatFs is configured to variable sector size and +/ GET_SECTOR_SIZE command must be implemented to the disk_ioctl() function. */ + + +#define _USE_ERASE 0 /* 0:Disable or 1:Enable */ +/* To enable sector erase feature, set _USE_ERASE to 1. Also CTRL_ERASE_SECTOR command +/ should be added to the disk_ioctl() function. */ + + +#define _FS_NOFSINFO 0 /* 0 to 3 */ +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this option +/ and f_getfree() function at first time after volume mount will force a full FAT scan. +/ Bit 1 controls the last allocated cluster number as bit 0. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define _FS_LOCK 0 /* 0:Disable or >=1:Enable */ +/* To enable file lock control feature, set _FS_LOCK to non-zero value. +/ The value defines how many files/sub-directories can be opened simultaneously +/ with file lock control. This feature uses bss _FS_LOCK * 12 bytes. */ + + +#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time tick */ +#define _SYNC_t HANDLE /* O/S dependent sync object type. e.g. HANDLE, OS_EVENT*, ID, SemaphoreHandle_t and etc.. */ +/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs module. +/ +/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function must be added to the project. +*/ + + +#define _WORD_ACCESS 0 /* 0 or 1 */ +/* The _WORD_ACCESS option is an only platform dependent option. It defines +/ which access method is used to the word data on the FAT volume. +/ +/ 0: Byte-by-byte access. Always compatible with all platforms. +/ 1: Word access. Do not choose this unless under both the following conditions. +/ +/ * Address misaligned memory access is always allowed for ALL instructions. +/ * Byte order on the memory is little-endian. +/ +/ If it is the case, _WORD_ACCESS can also be set to 1 to improve performance and +/ reduce code size. Following table shows an example of some processor types. +/ +/ ARM7TDMI 0 ColdFire 0 V850E 0 +/ Cortex-M3 0 Z80 0/1 V850ES 0/1 +/ Cortex-M0 0 RX600(LE) 0/1 TLCS-870 0/1 +/ AVR 0/1 RX600(BE) 0 TLCS-900 0/1 +/ AVR32 0 RL78 0 R32C 0 +/ PIC18 0/1 SH-2 0 M16C 0/1 +/ PIC24 0 H8S 0 MSP430 0 +/ PIC32 0 H8/300H 0 x86 0/1 +*/ + + +#endif /* _FFCONF */ diff --git a/USDK/component/common/file_system/fatfs/r0.10c/include/integer.h b/USDK/component/common/file_system/fatfs/r0.10c/include/integer.h new file mode 100644 index 0000000..048da92 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/include/integer.h @@ -0,0 +1,34 @@ +/*-------------------------------------------*/ +/* Integer type definitions for FatFs module */ +/*-------------------------------------------*/ + +#ifndef _FF_INTEGER +#define _FF_INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include + +#else /* Embedded platform */ + +/* This type MUST be 8 bit */ +typedef unsigned char BYTE; + +/* These types MUST be 16 bit */ +typedef short SHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types MUST be 16 bit or 32 bit */ +typedef int INT; +#undef UINT +typedef unsigned int UINT; + +/* These types MUST be 32 bit */ +typedef long LONG; +typedef unsigned long DWORD; + +#endif + +#endif diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/Makefile b/USDK/component/common/file_system/fatfs/r0.10c/src/Makefile new file mode 100644 index 0000000..cce4b19 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/Makefile @@ -0,0 +1,32 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +RT_USB_OTG_DIR = $(HWLIBDIR)/usb_otg/realtek/v3_0 + +MODULE_IFLAGS = -I$(RT_USB_OTG_DIR)/include/umsc +MODULE_IFLAGS += -I../include + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = ff.o diskio.o ff_driver.o + + +#*****************************************************************************# +# Dependency # +#*****************************************************************************# +-include $(OBJS:.o=.d) + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS COPY_RAM_OBJS + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/diskio.c b/USDK/component/common/file_system/fatfs/r0.10c/src/diskio.c new file mode 100644 index 0000000..0249fcc --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/diskio.c @@ -0,0 +1,142 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */ +/*-----------------------------------------------------------------------*/ +/* If a working storage control module is available, it should be */ +/* attached to the FatFs via a glue function rather than modifying it. */ +/* This is an example of glue functions to attach various exsisting */ +/* storage control modules to the FatFs module with a defined API. */ +/*-----------------------------------------------------------------------*/ + +#include "diskio.h" /* FatFs lower layer API */ +#include "fatfs_ext/inc/ff_driver.h" +/*-----------------------------------------------------------------------*/ +/* Get Drive Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status ( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS stat = STA_NODISK; + + if (disk.nbr <= 0 || pdrv < 0 || pdrv >= disk.nbr) + return stat; + + stat = disk.drv[pdrv]->disk_status(); + + return stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize ( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS stat = STA_NOINIT; + + if (disk.nbr <= 0 || pdrv < 0 || pdrv >= disk.nbr) + return stat; + + stat = disk.drv[pdrv]->disk_initialize(); + + return stat; +} + + + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read ( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to read */ +) +{ + DRESULT res = RES_PARERR; + + if (pdrv < 0 || pdrv >= disk.nbr || buff == (void*)0 || count <= 0) + return RES_PARERR; // Return if the parameter is invalid + + if(disk.nbr <= 0) + return RES_NOTRDY; + + res = disk.drv[pdrv]->disk_read(buff, sector, count); + + return res; +} + + + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ +#if _USE_WRITE +DRESULT disk_write ( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Sector address in LBA */ + UINT count /* Number of sectors to write */ +) +{ + DRESULT res = RES_PARERR; + int index = 0; + + if (pdrv < 0 || pdrv >= disk.nbr || buff == (void*)0 || count <= 0) + return RES_PARERR; // Return if the parameter is invalid + + if(disk.nbr <= 0) + return RES_NOTRDY; + + res = disk.drv[pdrv]->disk_write(buff, sector, count); + + return res; +} +#endif + + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +#if _USE_IOCTL +DRESULT disk_ioctl ( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res = RES_PARERR; + + if (pdrv < 0 || pdrv >= disk.nbr) + return RES_PARERR; // Return if the parameter is invalid + + if(disk.nbr <= 0) + return RES_NOTRDY; + + res = disk.drv[pdrv]->disk_ioctl(cmd, buff); + + return res; +} +#endif + +DWORD get_fattime (void) +{ + DWORD time_abs; + + time_abs = ((DWORD)(2016 - 1980) << 25) /* Fixed to Feb. 2, 2016 */ + | ((DWORD)2 << 21) + | ((DWORD)2 << 16) + | ((DWORD)0 << 11) + | ((DWORD)0 << 5) + | ((DWORD)0 >> 1); + + return time_abs; +} diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/ff.c b/USDK/component/common/file_system/fatfs/r0.10c/src/ff.c new file mode 100644 index 0000000..7096067 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/ff.c @@ -0,0 +1,4595 @@ +/*----------------------------------------------------------------------------/ +/ FatFs - FAT file system module R0.10b (C)ChaN, 2014 +/-----------------------------------------------------------------------------/ +/ FatFs module is a generic FAT file system module for small embedded systems. +/ This is a free software that opened for education, research and commercial +/ developments under license policy of following terms. +/ +/ Copyright (C) 2014, ChaN, all right reserved. +/ +/ * The FatFs module is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-----------------------------------------------------------------------------/ +/ Feb 26,'06 R0.00 Prototype. +/ +/ Apr 29,'06 R0.01 First stable version. +/ +/ Jun 01,'06 R0.02 Added FAT12 support. +/ Removed unbuffered mode. +/ Fixed a problem on small (<32M) partition. +/ Jun 10,'06 R0.02a Added a configuration option (_FS_MINIMUM). +/ +/ Sep 22,'06 R0.03 Added f_rename(). +/ Changed option _FS_MINIMUM to _FS_MINIMIZE. +/ Dec 11,'06 R0.03a Improved cluster scan algorithm to write files fast. +/ Fixed f_mkdir() creates incorrect directory on FAT32. +/ +/ Feb 04,'07 R0.04 Supported multiple drive system. +/ Changed some interfaces for multiple drive system. +/ Changed f_mountdrv() to f_mount(). +/ Added f_mkfs(). +/ Apr 01,'07 R0.04a Supported multiple partitions on a physical drive. +/ Added a capability of extending file size to f_lseek(). +/ Added minimization level 3. +/ Fixed an endian sensitive code in f_mkfs(). +/ May 05,'07 R0.04b Added a configuration option _USE_NTFLAG. +/ Added FSINFO support. +/ Fixed DBCS name can result FR_INVALID_NAME. +/ Fixed short seek (<= csize) collapses the file object. +/ +/ Aug 25,'07 R0.05 Changed arguments of f_read(), f_write() and f_mkfs(). +/ Fixed f_mkfs() on FAT32 creates incorrect FSINFO. +/ Fixed f_mkdir() on FAT32 creates incorrect directory. +/ Feb 03,'08 R0.05a Added f_truncate() and f_utime(). +/ Fixed off by one error at FAT sub-type determination. +/ Fixed btr in f_read() can be mistruncated. +/ Fixed cached sector is not flushed when create and close without write. +/ +/ Apr 01,'08 R0.06 Added fputc(), fputs(), fprintf() and fgets(). +/ Improved performance of f_lseek() on moving to the same or following cluster. +/ +/ Apr 01,'09 R0.07 Merged Tiny-FatFs as a configuration option. (_FS_TINY) +/ Added long file name feature. +/ Added multiple code page feature. +/ Added re-entrancy for multitask operation. +/ Added auto cluster size selection to f_mkfs(). +/ Added rewind option to f_readdir(). +/ Changed result code of critical errors. +/ Renamed string functions to avoid name collision. +/ Apr 14,'09 R0.07a Separated out OS dependent code on reentrant cfg. +/ Added multiple sector size feature. +/ Jun 21,'09 R0.07c Fixed f_unlink() can return FR_OK on error. +/ Fixed wrong cache control in f_lseek(). +/ Added relative path feature. +/ Added f_chdir() and f_chdrive(). +/ Added proper case conversion to extended character. +/ Nov 03,'09 R0.07e Separated out configuration options from ff.h to ffconf.h. +/ Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH. +/ Fixed name matching error on the 13 character boundary. +/ Added a configuration option, _LFN_UNICODE. +/ Changed f_readdir() to return the SFN with always upper case on non-LFN cfg. +/ +/ May 15,'10 R0.08 Added a memory configuration option. (_USE_LFN = 3) +/ Added file lock feature. (_FS_SHARE) +/ Added fast seek feature. (_USE_FASTSEEK) +/ Changed some types on the API, XCHAR->TCHAR. +/ Changed .fname in the FILINFO structure on Unicode cfg. +/ String functions support UTF-8 encoding files on Unicode cfg. +/ Aug 16,'10 R0.08a Added f_getcwd(). +/ Added sector erase feature. (_USE_ERASE) +/ Moved file lock semaphore table from fs object to the bss. +/ Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'. +/ Fixed f_mkfs() creates wrong FAT32 volume. +/ Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write(). +/ f_lseek() reports required table size on creating CLMP. +/ Extended format syntax of f_printf(). +/ Ignores duplicated directory separators in given path name. +/ +/ Sep 06,'11 R0.09 f_mkfs() supports multiple partition to complete the multiple partition feature. +/ Added f_fdisk(). +/ Aug 27,'12 R0.09a Changed f_open() and f_opendir() reject null object pointer to avoid crash. +/ Changed option name _FS_SHARE to _FS_LOCK. +/ Fixed assertion failure due to OS/2 EA on FAT12/16 volume. +/ Jan 24,'13 R0.09b Added f_setlabel() and f_getlabel(). +/ +/ Oct 02,'13 R0.10 Added selection of character encoding on the file. (_STRF_ENCODE) +/ Added f_closedir(). +/ Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO) +/ Added forced mount feature with changes of f_mount(). +/ Improved behavior of volume auto detection. +/ Improved write throughput of f_puts() and f_printf(). +/ Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write(). +/ Fixed f_write() can be truncated when the file size is close to 4GB. +/ Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect error code. +/ Jan 15,'14 R0.10a Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID) +/ Added a configuration option of minimum sector size. (_MIN_SS) +/ 2nd argument of f_rename() can have a drive number and it will be ignored. +/ Fixed f_mount() with forced mount fails when drive number is >= 1. +/ Fixed f_close() invalidates the file object without volume lock. +/ Fixed f_closedir() returns but the volume lock is left acquired. +/ Fixed creation of an entry with LFN fails on too many SFN collisions. +/ May 19,'14 R0.10b Fixed a hard error in the disk I/O layer can collapse the directory entry. +/ Fixed LFN entry is not deleted on delete/rename an object with lossy converted SFN. +/---------------------------------------------------------------------------*/ + +#include "ff.h" /* Declarations of FatFs API */ +#include "diskio.h" /* Declarations of disk I/O functions */ + + + + +/*-------------------------------------------------------------------------- + + Module Private Definitions + +---------------------------------------------------------------------------*/ + +#if _FATFS != 8051 /* Revision ID */ +#error Wrong include file (ff.h). +#endif + + +/* Reentrancy related */ +#if _FS_REENTRANT +#if _USE_LFN == 1 +#error Static LFN work area cannot be used at thread-safe configuration. +#endif +#define ENTER_FF(fs) { if (!lock_fs(fs)) return FR_TIMEOUT; } +#define LEAVE_FF(fs, res) { unlock_fs(fs, res); return res; } +#else +#define ENTER_FF(fs) +#define LEAVE_FF(fs, res) return res +#endif + +#define ABORT(fs, res) { fp->err = (BYTE)(res); LEAVE_FF(fs, res); } + + +/* Definitions of sector size */ +#if (_MAX_SS < _MIN_SS) || (_MAX_SS != 512 && _MAX_SS != 1024 && _MAX_SS != 2048 && _MAX_SS != 4096) || (_MIN_SS != 512 && _MIN_SS != 1024 && _MIN_SS != 2048 && _MIN_SS != 4096) +#error Wrong sector size configuration. +#endif +#if _MAX_SS == _MIN_SS +#define SS(fs) ((UINT)_MAX_SS) /* Fixed sector size */ +#else +#define SS(fs) ((fs)->ssize) /* Variable sector size */ +#endif + + +/* File access control feature */ +#if _FS_LOCK +#if _FS_READONLY +#error _FS_LOCK must be 0 at read-only cfg. +#endif +typedef struct { + FATFS *fs; /* Object ID 1, volume (NULL:blank entry) */ + DWORD clu; /* Object ID 2, directory (0:root) */ + WORD idx; /* Object ID 3, directory index */ + WORD ctr; /* Object open counter, 0:none, 0x01..0xFF:read mode open count, 0x100:write mode */ +} FILESEM; +#endif + + + +/* DBCS code ranges and SBCS extend character conversion table */ + +#if _CODE_PAGE == 932 /* Japanese Shift-JIS */ +#define _DF1S 0x81 /* DBC 1st byte range 1 start */ +#define _DF1E 0x9F /* DBC 1st byte range 1 end */ +#define _DF2S 0xE0 /* DBC 1st byte range 2 start */ +#define _DF2E 0xFC /* DBC 1st byte range 2 end */ +#define _DS1S 0x40 /* DBC 2nd byte range 1 start */ +#define _DS1E 0x7E /* DBC 2nd byte range 1 end */ +#define _DS2S 0x80 /* DBC 2nd byte range 2 start */ +#define _DS2E 0xFC /* DBC 2nd byte range 2 end */ + +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0x80 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 949 /* Korean */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x41 +#define _DS1E 0x5A +#define _DS2S 0x61 +#define _DS2E 0x7A +#define _DS3S 0x81 +#define _DS3E 0xFE + +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#define _DF1S 0x81 +#define _DF1E 0xFE +#define _DS1S 0x40 +#define _DS1E 0x7E +#define _DS2S 0xA1 +#define _DS2E 0xFE + +#elif _CODE_PAGE == 437 /* U.S. (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 720 /* Arabic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 737 /* Greek (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \ + 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 775 /* Baltic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF} + +#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \ + 0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \ + 0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 857 /* Turkish (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \ + 0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 862 /* Hebrew (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 866 /* Russian (OEM) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \ + 0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF} + +#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1253 /* Greek (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \ + 0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF} + +#elif _CODE_PAGE == 1254 /* Turkish (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F} + +#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1256 /* Arabic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF} + +#elif _CODE_PAGE == 1257 /* Baltic (Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \ + 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF} + +#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */ +#define _DF1S 0 +#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \ + 0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F} + +#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */ +#if _USE_LFN +#error Cannot use LFN feature without valid code page. +#endif +#define _DF1S 0 + +#else +#error Unknown code page + +#endif + + +/* Character code support macros */ +#define IsUpper(c) (((c)>='A')&&((c)<='Z')) +#define IsLower(c) (((c)>='a')&&((c)<='z')) +#define IsDigit(c) (((c)>='0')&&((c)<='9')) + +#if _DF1S /* Code page is DBCS */ + +#ifdef _DF2S /* Two 1st byte areas */ +#define IsDBCS1(c) (((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) || ((BYTE)(c) >= _DF2S && (BYTE)(c) <= _DF2E)) +#else /* One 1st byte area */ +#define IsDBCS1(c) ((BYTE)(c) >= _DF1S && (BYTE)(c) <= _DF1E) +#endif + +#ifdef _DS3S /* Three 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E) || ((BYTE)(c) >= _DS3S && (BYTE)(c) <= _DS3E)) +#else /* Two 2nd byte areas */ +#define IsDBCS2(c) (((BYTE)(c) >= _DS1S && (BYTE)(c) <= _DS1E) || ((BYTE)(c) >= _DS2S && (BYTE)(c) <= _DS2E)) +#endif + +#else /* Code page is SBCS */ + +#define IsDBCS1(c) 0 +#define IsDBCS2(c) 0 + +#endif /* _DF1S */ + + +/* Name status flags */ +#define NS 11 /* Index of name status byte in fn[] */ +#define NS_LOSS 0x01 /* Out of 8.3 format */ +#define NS_LFN 0x02 /* Force to create LFN entry */ +#define NS_LAST 0x04 /* Last segment */ +#define NS_BODY 0x08 /* Lower case flag (body) */ +#define NS_EXT 0x10 /* Lower case flag (ext) */ +#define NS_DOT 0x20 /* Dot entry */ + + +/* FAT sub-type boundaries */ +#define MIN_FAT16 4086U /* Minimum number of clusters for FAT16 */ +#define MIN_FAT32 65526U /* Minimum number of clusters for FAT32 */ + + +/* FatFs refers the members in the FAT structures as byte array instead of +/ structure member because the structure is not binary compatible between +/ different platforms */ + +#define BS_jmpBoot 0 /* Jump instruction (3) */ +#define BS_OEMName 3 /* OEM name (8) */ +#define BPB_BytsPerSec 11 /* Sector size [byte] (2) */ +#define BPB_SecPerClus 13 /* Cluster size [sector] (1) */ +#define BPB_RsvdSecCnt 14 /* Size of reserved area [sector] (2) */ +#define BPB_NumFATs 16 /* Number of FAT copies (1) */ +#define BPB_RootEntCnt 17 /* Number of root directory entries for FAT12/16 (2) */ +#define BPB_TotSec16 19 /* Volume size [sector] (2) */ +#define BPB_Media 21 /* Media descriptor (1) */ +#define BPB_FATSz16 22 /* FAT size [sector] (2) */ +#define BPB_SecPerTrk 24 /* Track size [sector] (2) */ +#define BPB_NumHeads 26 /* Number of heads (2) */ +#define BPB_HiddSec 28 /* Number of special hidden sectors (4) */ +#define BPB_TotSec32 32 /* Volume size [sector] (4) */ +#define BS_DrvNum 36 /* Physical drive number (2) */ +#define BS_BootSig 38 /* Extended boot signature (1) */ +#define BS_VolID 39 /* Volume serial number (4) */ +#define BS_VolLab 43 /* Volume label (8) */ +#define BS_FilSysType 54 /* File system type (1) */ +#define BPB_FATSz32 36 /* FAT size [sector] (4) */ +#define BPB_ExtFlags 40 /* Extended flags (2) */ +#define BPB_FSVer 42 /* File system version (2) */ +#define BPB_RootClus 44 /* Root directory first cluster (4) */ +#define BPB_FSInfo 48 /* Offset of FSINFO sector (2) */ +#define BPB_BkBootSec 50 /* Offset of backup boot sector (2) */ +#define BS_DrvNum32 64 /* Physical drive number (2) */ +#define BS_BootSig32 66 /* Extended boot signature (1) */ +#define BS_VolID32 67 /* Volume serial number (4) */ +#define BS_VolLab32 71 /* Volume label (8) */ +#define BS_FilSysType32 82 /* File system type (1) */ +#define FSI_LeadSig 0 /* FSI: Leading signature (4) */ +#define FSI_StrucSig 484 /* FSI: Structure signature (4) */ +#define FSI_Free_Count 488 /* FSI: Number of free clusters (4) */ +#define FSI_Nxt_Free 492 /* FSI: Last allocated cluster (4) */ +#define MBR_Table 446 /* MBR: Partition table offset (2) */ +#define SZ_PTE 16 /* MBR: Size of a partition table entry */ +#define BS_55AA 510 /* Signature word (2) */ + +#define DIR_Name 0 /* Short file name (11) */ +#define DIR_Attr 11 /* Attribute (1) */ +#define DIR_NTres 12 /* NT flag (1) */ +#define DIR_CrtTimeTenth 13 /* Created time sub-second (1) */ +#define DIR_CrtTime 14 /* Created time (2) */ +#define DIR_CrtDate 16 /* Created date (2) */ +#define DIR_LstAccDate 18 /* Last accessed date (2) */ +#define DIR_FstClusHI 20 /* Higher 16-bit of first cluster (2) */ +#define DIR_WrtTime 22 /* Modified time (2) */ +#define DIR_WrtDate 24 /* Modified date (2) */ +#define DIR_FstClusLO 26 /* Lower 16-bit of first cluster (2) */ +#define DIR_FileSize 28 /* File size (4) */ +#define LDIR_Ord 0 /* LFN entry order and LLE flag (1) */ +#define LDIR_Attr 11 /* LFN attribute (1) */ +#define LDIR_Type 12 /* LFN type (1) */ +#define LDIR_Chksum 13 /* Sum of corresponding SFN entry */ +#define LDIR_FstClusLO 26 /* Filled by zero (0) */ +#define SZ_DIR 32 /* Size of a directory entry */ +#define LLE 0x40 /* Last long entry flag in LDIR_Ord */ +#define DDE 0xE5 /* Deleted directory entry mark in DIR_Name[0] */ +#define NDDE 0x05 /* Replacement of the character collides with DDE */ + + + + +/*------------------------------------------------------------*/ +/* Module private work area */ +/*------------------------------------------------------------*/ +/* Note that uninitialized variables with static duration are +/ guaranteed zero/null as initial value. If not, either the +/ linker or start-up routine is out of ANSI-C standard. +*/ + +#if _VOLUMES >= 1 || _VOLUMES <= 10 +static +FATFS *FatFs[_VOLUMES]; /* Pointer to the file system objects (logical drives) */ +#else +#error Number of volumes must be 1 to 10. +#endif + +static +WORD Fsid; /* File system mount ID */ + +#if _FS_RPATH && _VOLUMES >= 2 +static +BYTE CurrVol; /* Current drive */ +#endif + +#if _FS_LOCK +static +FILESEM Files[_FS_LOCK]; /* Open object lock semaphores */ +#endif + +#if _USE_LFN == 0 /* No LFN feature */ +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) (dobj).fn = sfn +#define FREE_BUF() + +#elif _USE_LFN == 1 /* LFN feature with static working buffer */ +static +WCHAR LfnBuf[_MAX_LFN+1]; +#define DEF_NAMEBUF BYTE sfn[12] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = LfnBuf; } +#define FREE_BUF() + +#elif _USE_LFN == 2 /* LFN feature with dynamic working buffer on the stack */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR lbuf[_MAX_LFN+1] +#define INIT_BUF(dobj) { (dobj).fn = sfn; (dobj).lfn = lbuf; } +#define FREE_BUF() + +#elif _USE_LFN == 3 /* LFN feature with dynamic working buffer on the heap */ +#define DEF_NAMEBUF BYTE sfn[12]; WCHAR *lfn +#define INIT_BUF(dobj) { lfn = ff_memalloc((_MAX_LFN + 1) * 2); \ + if (!lfn) LEAVE_FF((dobj).fs, FR_NOT_ENOUGH_CORE); \ + (dobj).lfn = lfn; (dobj).fn = sfn; } +#define FREE_BUF() ff_memfree(lfn) + +#else +#error Wrong LFN configuration. +#endif + + +#ifdef _EXCVT +static +const BYTE ExCvt[] = _EXCVT; /* Upper conversion table for extended characters */ +#endif + + + + + + +/*-------------------------------------------------------------------------- + + Module Private Functions + +---------------------------------------------------------------------------*/ + + +/*-----------------------------------------------------------------------*/ +/* String functions */ +/*-----------------------------------------------------------------------*/ + +#if 0 + +/* Copy memory to memory */ +static +void mem_cpy (void* dst, const void* src, UINT cnt) { + BYTE *d = (BYTE*)dst; + const BYTE *s = (const BYTE*)src; + +#if _WORD_ACCESS == 1 + while (cnt >= sizeof (int)) { + *(int*)d = *(int*)s; + d += sizeof (int); s += sizeof (int); + cnt -= sizeof (int); + } +#endif + while (cnt--) + *d++ = *s++; +} + +/* Fill memory */ +static +void mem_set (void* dst, int val, UINT cnt) { + BYTE *d = (BYTE*)dst; + + while (cnt--) + *d++ = (BYTE)val; +} + +/* Compare memory to memory */ +static +int mem_cmp (const void* dst, const void* src, UINT cnt) { + const BYTE *d = (const BYTE *)dst, *s = (const BYTE *)src; + int r = 0; + + while (cnt-- && (r = *d++ - *s++) == 0) ; + return r; +} +#else +#define mem_cpy memcpy +#define mem_set memset +#define mem_cmp memcmp +#endif + +/* Check if chr is contained in the string */ +static +int chk_chr (const char* str, int chr) { + while (*str && *str != chr) str++; + return *str; +} + + + +/*-----------------------------------------------------------------------*/ +/* Request/Release grant to access the volume */ +/*-----------------------------------------------------------------------*/ +#if _FS_REENTRANT +static +int lock_fs ( + FATFS* fs /* File system object */ +) +{ + return ff_req_grant(fs->sobj); +} + + +static +void unlock_fs ( + FATFS* fs, /* File system object */ + FRESULT res /* Result code to be returned */ +) +{ + if (fs && + res != FR_NOT_ENABLED && + res != FR_INVALID_DRIVE && + res != FR_INVALID_OBJECT && + res != FR_TIMEOUT) { + ff_rel_grant(fs->sobj); + } +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* File lock control functions */ +/*-----------------------------------------------------------------------*/ +#if _FS_LOCK + +static +FRESULT chk_lock ( /* Check if the file can be accessed */ + DIR* dp, /* Directory object pointing the file to be checked */ + int acc /* Desired access type (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i, be; + + /* Search file semaphore table */ + for (i = be = 0; i < _FS_LOCK; i++) { + if (Files[i].fs) { /* Existing entry */ + if (Files[i].fs == dp->fs && /* Check if the object matched with an open object */ + Files[i].clu == dp->sclust && + Files[i].idx == dp->index) break; + } else { /* Blank entry */ + be = 1; + } + } + if (i == _FS_LOCK) /* The object is not opened */ + return (be || acc == 2) ? FR_OK : FR_TOO_MANY_OPEN_FILES; /* Is there a blank entry for new object? */ + + /* The object has been opened. Reject any open against writing file and all write mode open */ + return (acc || Files[i].ctr == 0x100) ? FR_LOCKED : FR_OK; +} + + +static +int enq_lock (void) /* Check if an entry is available for a new object */ +{ + UINT i; + + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + return (i == _FS_LOCK) ? 0 : 1; +} + + +static +UINT inc_lock ( /* Increment object open counter and returns its index (0:Internal error) */ + DIR* dp, /* Directory object pointing the file to register or increment */ + int acc /* Desired access (0:Read, 1:Write, 2:Delete/Rename) */ +) +{ + UINT i; + + + for (i = 0; i < _FS_LOCK; i++) { /* Find the object */ + if (Files[i].fs == dp->fs && + Files[i].clu == dp->sclust && + Files[i].idx == dp->index) break; + } + + if (i == _FS_LOCK) { /* Not opened. Register it as new. */ + for (i = 0; i < _FS_LOCK && Files[i].fs; i++) ; + if (i == _FS_LOCK) return 0; /* No free entry to register (int err) */ + Files[i].fs = dp->fs; + Files[i].clu = dp->sclust; + Files[i].idx = dp->index; + Files[i].ctr = 0; + } + + if (acc && Files[i].ctr) return 0; /* Access violation (int err) */ + + Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */ + + return i + 1; +} + + +static +FRESULT dec_lock ( /* Decrement object open counter */ + UINT i /* Semaphore index (1..) */ +) +{ + WORD n; + FRESULT res; + + + if (--i < _FS_LOCK) { /* Shift index number origin from 0 */ + n = Files[i].ctr; + if (n == 0x100) n = 0; /* If write mode open, delete the entry */ + if (n) n--; /* Decrement read mode open count */ + Files[i].ctr = n; + if (!n) Files[i].fs = 0; /* Delete the entry if open count gets zero */ + res = FR_OK; + } else { + res = FR_INT_ERR; /* Invalid index nunber */ + } + return res; +} + + +static +void clear_lock ( /* Clear lock entries of the volume */ + FATFS *fs +) +{ + UINT i; + + for (i = 0; i < _FS_LOCK; i++) { + if (Files[i].fs == fs) Files[i].fs = 0; + } +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Move/Flush disk access window in the file system object */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync_window ( + FATFS* fs /* File system object */ +) +{ + DWORD wsect; + UINT nf; + + + if (fs->wflag) { /* Write back the sector if it is dirty */ + wsect = fs->winsect; /* Current sector number */ + if (disk_write(fs->drv, fs->win, wsect, 1)) + return FR_DISK_ERR; + fs->wflag = 0; + if (wsect - fs->fatbase < fs->fsize) { /* Is it in the FAT area? */ + for (nf = fs->n_fats; nf >= 2; nf--) { /* Reflect the change to all FAT copies */ + wsect += fs->fsize; + disk_write(fs->drv, fs->win, wsect, 1); + } + } + } + return FR_OK; +} +#endif + + +static +FRESULT move_window ( + FATFS* fs, /* File system object */ + DWORD sector /* Sector number to make appearance in the fs->win[] */ +) +{ + if (sector != fs->winsect) { /* Changed current window */ +#if !_FS_READONLY + if (sync_window(fs) != FR_OK) + return FR_DISK_ERR; +#endif + if (disk_read(fs->drv, fs->win, sector, 1)) + return FR_DISK_ERR; + fs->winsect = sector; + } + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Synchronize file system and strage device */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT sync_fs ( /* FR_OK: successful, FR_DISK_ERR: failed */ + FATFS* fs /* File system object */ +) +{ + FRESULT res; + + + res = sync_window(fs); + if (res == FR_OK) { + /* Update FSINFO sector if needed */ + if (fs->fs_type == FS_FAT32 && fs->fsi_flag == 1) { + /* Create FSINFO structure */ + mem_set(fs->win, 0, SS(fs)); + ST_WORD(fs->win+BS_55AA, 0xAA55); + ST_DWORD(fs->win+FSI_LeadSig, 0x41615252); + ST_DWORD(fs->win+FSI_StrucSig, 0x61417272); + ST_DWORD(fs->win+FSI_Free_Count, fs->free_clust); + ST_DWORD(fs->win+FSI_Nxt_Free, fs->last_clust); + /* Write it into the FSINFO sector */ + fs->winsect = fs->volbase + 1; + disk_write(fs->drv, fs->win, fs->winsect, 1); + fs->fsi_flag = 0; + } + /* Make sure that no pending write process in the physical drive */ + if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK) + res = FR_DISK_ERR; + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Get sector# from cluster# */ +/*-----------------------------------------------------------------------*/ + + +DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to be converted */ +) +{ + clst -= 2; + if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */ + return clst * fs->csize + fs->database; +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Read value of a FAT entry */ +/*-----------------------------------------------------------------------*/ + + +DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to get the link information */ +) +{ + UINT wc, bc; + BYTE *p; + + + if (clst < 2 || clst >= fs->n_fatent) /* Check range */ + return 1; + + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc = fs->win[bc % SS(fs)]; bc++; + if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break; + wc |= fs->win[bc % SS(fs)] << 8; + return clst & 1 ? wc >> 4 : (wc & 0xFFF); + + case FS_FAT16 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break; + p = &fs->win[clst * 2 % SS(fs)]; + return LD_WORD(p); + + case FS_FAT32 : + if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break; + p = &fs->win[clst * 4 % SS(fs)]; + return LD_DWORD(p) & 0x0FFFFFFF; + + default: + return 1; + } + + return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */ +} + + + + +/*-----------------------------------------------------------------------*/ +/* FAT access - Change value of a FAT entry */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY + +FRESULT put_fat ( + FATFS* fs, /* File system object */ + DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */ + DWORD val /* New value to mark the cluster */ +) +{ + UINT bc; + BYTE *p; + FRESULT res; + + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + switch (fs->fs_type) { + case FS_FAT12 : + bc = (UINT)clst; bc += bc / 2; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val; + bc++; + fs->wflag = 1; + res = move_window(fs, fs->fatbase + (bc / SS(fs))); + if (res != FR_OK) break; + p = &fs->win[bc % SS(fs)]; + *p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F)); + break; + + case FS_FAT16 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2))); + if (res != FR_OK) break; + p = &fs->win[clst * 2 % SS(fs)]; + ST_WORD(p, (WORD)val); + break; + + case FS_FAT32 : + res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4))); + if (res != FR_OK) break; + p = &fs->win[clst * 4 % SS(fs)]; + val |= LD_DWORD(p) & 0xF0000000; + ST_DWORD(p, val); + break; + + default : + res = FR_INT_ERR; + } + fs->wflag = 1; + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Remove a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT remove_chain ( + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to remove a chain from */ +) +{ + FRESULT res; + DWORD nxt; +#if _USE_ERASE + DWORD scl = clst, ecl = clst, rt[2]; +#endif + + if (clst < 2 || clst >= fs->n_fatent) { /* Check range */ + res = FR_INT_ERR; + + } else { + res = FR_OK; + while (clst < fs->n_fatent) { /* Not a last link? */ + nxt = get_fat(fs, clst); /* Get cluster status */ + if (nxt == 0) break; /* Empty cluster? */ + if (nxt == 1) { res = FR_INT_ERR; break; } /* Internal error? */ + if (nxt == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } /* Disk error? */ + res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */ + if (res != FR_OK) break; + if (fs->free_clust != 0xFFFFFFFF) { /* Update FSINFO */ + fs->free_clust++; + fs->fsi_flag |= 1; + } +#if _USE_ERASE + if (ecl + 1 == nxt) { /* Is next cluster contiguous? */ + ecl = nxt; + } else { /* End of contiguous clusters */ + rt[0] = clust2sect(fs, scl); /* Start sector */ + rt[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */ + disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, rt); /* Erase the block */ + scl = ecl = nxt; + } +#endif + clst = nxt; /* Next cluster */ + } + } + + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Stretch or Create a cluster chain */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +DWORD create_chain ( /* 0:No free cluster, 1:Internal error, 0xFFFFFFFF:Disk error, >=2:New cluster# */ + FATFS* fs, /* File system object */ + DWORD clst /* Cluster# to stretch. 0 means create a new chain. */ +) +{ + DWORD cs, ncl, scl; + FRESULT res; + + + if (clst == 0) { /* Create a new chain */ + scl = fs->last_clust; /* Get suggested start point */ + if (!scl || scl >= fs->n_fatent) scl = 1; + } + else { /* Stretch the current chain */ + cs = get_fat(fs, clst); /* Check the cluster status */ + if (cs < 2) return 1; /* Invalid value */ + if (cs == 0xFFFFFFFF) return cs; /* A disk error occurred */ + if (cs < fs->n_fatent) return cs; /* It is already followed by next cluster */ + scl = clst; + } + + ncl = scl; /* Start cluster */ + for (;;) { + ncl++; /* Next cluster */ + if (ncl >= fs->n_fatent) { /* Check wrap around */ + ncl = 2; + if (ncl > scl) return 0; /* No free cluster */ + } + cs = get_fat(fs, ncl); /* Get the cluster status */ + if (cs == 0) break; /* Found a free cluster */ + if (cs == 0xFFFFFFFF || cs == 1)/* An error occurred */ + return cs; + if (ncl == scl) return 0; /* No free cluster */ + } + + res = put_fat(fs, ncl, 0x0FFFFFFF); /* Mark the new cluster "last link" */ + if (res == FR_OK && clst != 0) { + res = put_fat(fs, clst, ncl); /* Link it to the previous one if needed */ + } + if (res == FR_OK) { + fs->last_clust = ncl; /* Update FSINFO */ + if (fs->free_clust != 0xFFFFFFFF) { + fs->free_clust--; + fs->fsi_flag |= 1; + } + } else { + ncl = (res == FR_DISK_ERR) ? 0xFFFFFFFF : 1; + } + + return ncl; /* Return new cluster number or error code */ +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* FAT handling - Convert offset into cluster with link map table */ +/*-----------------------------------------------------------------------*/ + +#if _USE_FASTSEEK +static +DWORD clmt_clust ( /* <2:Error, >=2:Cluster number */ + FIL* fp, /* Pointer to the file object */ + DWORD ofs /* File offset to be converted to cluster# */ +) +{ + DWORD cl, ncl, *tbl; + + + tbl = fp->cltbl + 1; /* Top of CLMT */ + cl = ofs / SS(fp->fs) / fp->fs->csize; /* Cluster order from top of the file */ + for (;;) { + ncl = *tbl++; /* Number of cluters in the fragment */ + if (!ncl) return 0; /* End of table? (error) */ + if (cl < ncl) break; /* In this fragment? */ + cl -= ncl; tbl++; /* Next fragment */ + } + return cl + *tbl; /* Return the cluster number */ +} +#endif /* _USE_FASTSEEK */ + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Set directory index */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_sdi ( + DIR* dp, /* Pointer to directory object */ + UINT idx /* Index of directory table */ +) +{ + DWORD clst, sect; + UINT ic; + + + dp->index = (WORD)idx; /* Current index */ + clst = dp->sclust; /* Table start cluster (0:root) */ + if (clst == 1 || clst >= dp->fs->n_fatent) /* Check start cluster range */ + return FR_INT_ERR; + if (!clst && dp->fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */ + clst = dp->fs->dirbase; + + if (clst == 0) { /* Static table (root-directory in FAT12/16) */ + if (idx >= dp->fs->n_rootdir) /* Is index out of range? */ + return FR_INT_ERR; + sect = dp->fs->dirbase; + } + else { /* Dynamic table (root-directory in FAT32 or sub-directory) */ + ic = SS(dp->fs) / SZ_DIR * dp->fs->csize; /* Entries per cluster */ + while (idx >= ic) { /* Follow cluster chain */ + clst = get_fat(dp->fs, clst); /* Get next cluster */ + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; /* Disk error */ + if (clst < 2 || clst >= dp->fs->n_fatent) /* Reached to end of table or internal error */ + return FR_INT_ERR; + idx -= ic; + } + sect = clust2sect(dp->fs, clst); + } + dp->clust = clst; /* Current cluster# */ + if (!sect) return FR_INT_ERR; + dp->sect = sect + idx / (SS(dp->fs) / SZ_DIR); /* Sector# of the directory entry */ + dp->dir = dp->fs->win + (idx % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Ptr to the entry in the sector */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Move directory table index next */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table, FR_DENIED:Could not stretch */ + DIR* dp, /* Pointer to the directory object */ + int stretch /* 0: Do not stretch table, 1: Stretch table if needed */ +) +{ + DWORD clst; + UINT i; + + + i = dp->index + 1; + if (!(i & 0xFFFF) || !dp->sect) /* Report EOT when index has reached 65535 */ + return FR_NO_FILE; + + if (!(i % (SS(dp->fs) / SZ_DIR))) { /* Sector changed? */ + dp->sect++; /* Next sector */ + + if (!dp->clust) { /* Static table */ + if (i >= dp->fs->n_rootdir) /* Report EOT if it reached end of static table */ + return FR_NO_FILE; + } + else { /* Dynamic table */ + if (((i / (SS(dp->fs) / SZ_DIR)) & (dp->fs->csize - 1)) == 0) { /* Cluster changed? */ + clst = get_fat(dp->fs, dp->clust); /* Get next cluster */ + if (clst <= 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + if (clst >= dp->fs->n_fatent) { /* If it reached end of dynamic table, */ +#if !_FS_READONLY + UINT c; + if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT */ + clst = create_chain(dp->fs, dp->clust); /* Stretch cluster chain */ + if (clst == 0) return FR_DENIED; /* No free cluster */ + if (clst == 1) return FR_INT_ERR; + if (clst == 0xFFFFFFFF) return FR_DISK_ERR; + /* Clean-up stretched table */ + if (sync_window(dp->fs)) return FR_DISK_ERR;/* Flush disk access window */ + mem_set(dp->fs->win, 0, SS(dp->fs)); /* Clear window buffer */ + dp->fs->winsect = clust2sect(dp->fs, clst); /* Cluster start sector */ + for (c = 0; c < dp->fs->csize; c++) { /* Fill the new cluster with 0 */ + dp->fs->wflag = 1; + if (sync_window(dp->fs)) return FR_DISK_ERR; + dp->fs->winsect++; + } + dp->fs->winsect -= c; /* Rewind window offset */ +#else + if (!stretch) return FR_NO_FILE; /* If do not stretch, report EOT (this is to suppress warning) */ + return FR_NO_FILE; /* Report EOT */ +#endif + } + dp->clust = clst; /* Initialize data for new cluster */ + dp->sect = clust2sect(dp->fs, clst); + } + } + } + + dp->index = (WORD)i; /* Current index */ + dp->dir = dp->fs->win + (i % (SS(dp->fs) / SZ_DIR)) * SZ_DIR; /* Current entry in the window */ + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Reserve directory entry */ +/*-----------------------------------------------------------------------*/ + +#if !_FS_READONLY +static +FRESULT dir_alloc ( + DIR* dp, /* Pointer to the directory object */ + UINT nent /* Number of contiguous entries to allocate (1-21) */ +) +{ + FRESULT res; + UINT n; + + + res = dir_sdi(dp, 0); + if (res == FR_OK) { + n = 0; + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + if (dp->dir[0] == DDE || dp->dir[0] == 0) { /* Is it a blank entry? */ + if (++n == nent) break; /* A block of contiguous entries is found */ + } else { + n = 0; /* Not a blank entry. Restart to search */ + } + res = dir_next(dp, 1); /* Next entry with table stretch enabled */ + } while (res == FR_OK); + } + if (res == FR_NO_FILE) res = FR_DENIED; /* No directory entry to allocate */ + return res; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Load/Store start cluster number */ +/*-----------------------------------------------------------------------*/ + +static +DWORD ld_clust ( + FATFS* fs, /* Pointer to the fs object */ + BYTE* dir /* Pointer to the directory entry */ +) +{ + DWORD cl; + + cl = LD_WORD(dir+DIR_FstClusLO); + if (fs->fs_type == FS_FAT32) + cl |= (DWORD)LD_WORD(dir+DIR_FstClusHI) << 16; + + return cl; +} + + +#if !_FS_READONLY +static +void st_clust ( + BYTE* dir, /* Pointer to the directory entry */ + DWORD cl /* Value to be set */ +) +{ + ST_WORD(dir+DIR_FstClusLO, cl); + ST_WORD(dir+DIR_FstClusHI, cl >> 16); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* LFN handling - Test/Pick/Fit an LFN segment from/to directory entry */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +const BYTE LfnOfs[] = {1,3,5,7,9,14,16,18,20,22,24,28,30}; /* Offset of LFN characters in the directory entry */ + + +static +int cmp_lfn ( /* 1:Matched, 0:Not matched */ + WCHAR* lfnbuf, /* Pointer to the LFN to be compared */ + BYTE* dir /* Pointer to the directory entry containing a part of LFN */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & ~LLE) - 1) * 13; /* Get offset in the LFN buffer */ + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last character has not been processed */ + wc = ff_wtoupper(uc); /* Convert it to upper case */ + if (i >= _MAX_LFN || wc != ff_wtoupper(lfnbuf[i++])) /* Compare it */ + return 0; /* Not matched */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Repeat until all characters in the entry are checked */ + + if ((dir[LDIR_Ord] & LLE) && wc && lfnbuf[i]) /* Last segment matched but different length */ + return 0; + + return 1; /* The part of LFN matched */ +} + + + +static +int pick_lfn ( /* 1:Succeeded, 0:Buffer overflow */ + WCHAR* lfnbuf, /* Pointer to the Unicode-LFN buffer */ + BYTE* dir /* Pointer to the directory entry */ +) +{ + UINT i, s; + WCHAR wc, uc; + + + i = ((dir[LDIR_Ord] & 0x3F) - 1) * 13; /* Offset in the LFN buffer */ + + s = 0; wc = 1; + do { + uc = LD_WORD(dir+LfnOfs[s]); /* Pick an LFN character from the entry */ + if (wc) { /* Last character has not been processed */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i++] = wc = uc; /* Store it */ + } else { + if (uc != 0xFFFF) return 0; /* Check filler */ + } + } while (++s < 13); /* Read all character in the entry */ + + if (dir[LDIR_Ord] & LLE) { /* Put terminator if it is the last LFN part */ + if (i >= _MAX_LFN) return 0; /* Buffer overflow? */ + lfnbuf[i] = 0; + } + + return 1; +} + + +#if !_FS_READONLY +static +void fit_lfn ( + const WCHAR* lfnbuf, /* Pointer to the LFN buffer */ + BYTE* dir, /* Pointer to the directory entry */ + BYTE ord, /* LFN order (1-20) */ + BYTE sum /* SFN sum */ +) +{ + UINT i, s; + WCHAR wc; + + + dir[LDIR_Chksum] = sum; /* Set check sum */ + dir[LDIR_Attr] = AM_LFN; /* Set attribute. LFN entry */ + dir[LDIR_Type] = 0; + ST_WORD(dir+LDIR_FstClusLO, 0); + + i = (ord - 1) * 13; /* Get offset in the LFN buffer */ + s = wc = 0; + do { + if (wc != 0xFFFF) wc = lfnbuf[i++]; /* Get an effective character */ + ST_WORD(dir+LfnOfs[s], wc); /* Put it */ + if (!wc) wc = 0xFFFF; /* Padding characters following last character */ + } while (++s < 13); + if (wc == 0xFFFF || !lfnbuf[i]) ord |= LLE; /* Bottom LFN part is the start of LFN sequence */ + dir[LDIR_Ord] = ord; /* Set the LFN order */ +} + +#endif +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Create numbered name */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +void gen_numname ( + BYTE* dst, /* Pointer to the buffer to store numbered SFN */ + const BYTE* src, /* Pointer to SFN */ + const WCHAR* lfn, /* Pointer to LFN */ + UINT seq /* Sequence number */ +) +{ + BYTE ns[8], c; + UINT i, j; + + + mem_cpy(dst, src, 11); + + if (seq > 5) { /* On many collisions, generate a hash number instead of sequential number */ + WCHAR wc; + DWORD sr = seq; + + while (*lfn) { /* Create a CRC */ + wc = *lfn++; + for (i = 0; i < 16; i++) { + sr = (sr << 1) + (wc & 1); + wc >>= 1; + if (sr & 0x10000) sr ^= 0x11021; + } + } + seq = (UINT)sr; + } + + /* itoa (hexdecimal) */ + i = 7; + do { + c = (seq % 16) + '0'; + if (c > '9') c += 7; + ns[i--] = c; + seq /= 16; + } while (seq); + ns[i] = '~'; + + /* Append the number */ + for (j = 0; j < i && dst[j] != ' '; j++) { + if (IsDBCS1(dst[j])) { + if (j == i - 1) break; + j++; + } + } + do { + dst[j++] = (i < 8) ? ns[i++] : ' '; + } while (j < 8); +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Calculate sum of an SFN */ +/*-----------------------------------------------------------------------*/ +#if _USE_LFN +static +BYTE sum_sfn ( + const BYTE* dir /* Pointer to the SFN entry */ +) +{ + BYTE sum = 0; + UINT n = 11; + + do sum = (sum >> 1) + (sum << 7) + *dir++; while (--n); + return sum; +} +#endif + + + + +/*-----------------------------------------------------------------------*/ +/* Directory handling - Find an object in the directory */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT dir_find ( + DIR* dp /* Pointer to the directory object linked to the file name */ +) +{ + FRESULT res; + BYTE c, *dir; +#if _USE_LFN + BYTE a, ord, sum; +#endif + + res = dir_sdi(dp, 0); /* Rewind directory object */ + if (res != FR_OK) return res; + +#if _USE_LFN + ord = sum = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */ +#endif + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + dir = dp->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ +#if _USE_LFN /* LFN configuration */ + a = dir[DIR_Attr] & AM_MASK; + if (c == DDE || ((a & AM_VOL) && a != AM_LFN)) { /* An entry without valid data */ + ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (dp->lfn) { + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; /* LFN start order */ + dp->lfn_idx = dp->index; /* Start index of LFN */ + } + /* Check validity of the LFN entry and compare it with given name */ + ord = (c == ord && sum == dir[LDIR_Chksum] && cmp_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF; + } + } else { /* An SFN entry is found */ + if (!ord && sum == sum_sfn(dir)) break; /* LFN matched? */ + if (!(dp->fn[NS] & NS_LOSS) && !mem_cmp(dir, dp->fn, 11)) break; /* SFN matched? */ + ord = 0xFF; dp->lfn_idx = 0xFFFF; /* Reset LFN sequence */ + } + } +#else /* Non LFN configuration */ + if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dp->fn, 11)) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 +static +FRESULT dir_read ( + DIR* dp, /* Pointer to the directory object */ + int vol /* Filtered by 0:file/directory or 1:volume label */ +) +{ + FRESULT res; + BYTE a, c, *dir; +#if _USE_LFN + BYTE ord = 0xFF, sum = 0xFF; +#endif + + res = FR_NO_FILE; + while (dp->sect) { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + dir = dp->dir; /* Ptr to the directory entry of current index */ + c = dir[DIR_Name]; + if (c == 0) { res = FR_NO_FILE; break; } /* Reached to end of table */ + a = dir[DIR_Attr] & AM_MASK; +#if _USE_LFN /* LFN configuration */ + if (c == DDE || (!_FS_RPATH && c == '.') || (int)(a == AM_VOL) != vol) { /* An entry without valid data */ + ord = 0xFF; + } else { + if (a == AM_LFN) { /* An LFN entry is found */ + if (c & LLE) { /* Is it start of LFN sequence? */ + sum = dir[LDIR_Chksum]; + c &= ~LLE; ord = c; + dp->lfn_idx = dp->index; + } + /* Check LFN validity and capture it */ + ord = (c == ord && sum == dir[LDIR_Chksum] && pick_lfn(dp->lfn, dir)) ? ord - 1 : 0xFF; + } else { /* An SFN entry is found */ + if (ord || sum != sum_sfn(dir)) /* Is there a valid LFN? */ + dp->lfn_idx = 0xFFFF; /* It has no LFN. */ + break; + } + } +#else /* Non LFN configuration */ + if (c != DDE && (_FS_RPATH || c != '.') && a != AM_LFN && (int)(a == AM_VOL) == vol) /* Is it a valid entry? */ + break; +#endif + res = dir_next(dp, 0); /* Next entry */ + if (res != FR_OK) break; + } + + if (res != FR_OK) dp->sect = 0; + + return res; +} +#endif /* _FS_MINIMIZE <= 1 || _USE_LABEL || _FS_RPATH >= 2 */ + + + + +/*-----------------------------------------------------------------------*/ +/* Register an object to the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY +static +FRESULT dir_register ( /* FR_OK:Successful, FR_DENIED:No free entry or too many SFN collision, FR_DISK_ERR:Disk error */ + DIR* dp /* Target directory with object name to be created */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + UINT n, nent; + BYTE sn[12], *fn, sum; + WCHAR *lfn; + + + fn = dp->fn; lfn = dp->lfn; + mem_cpy(sn, fn, 12); + + if (_FS_RPATH && (sn[NS] & NS_DOT)) /* Cannot create dot entry */ + return FR_INVALID_NAME; + + if (sn[NS] & NS_LOSS) { /* When LFN is out of 8.3 format, generate a numbered name */ + fn[NS] = 0; dp->lfn = 0; /* Find only SFN */ + for (n = 1; n < 100; n++) { + gen_numname(fn, sn, lfn, n); /* Generate a numbered name */ + res = dir_find(dp); /* Check if the name collides with existing SFN */ + if (res != FR_OK) break; + } + if (n == 100) return FR_DENIED; /* Abort if too many collisions */ + if (res != FR_NO_FILE) return res; /* Abort if the result is other than 'not collided' */ + fn[NS] = sn[NS]; dp->lfn = lfn; + } + + if (sn[NS] & NS_LFN) { /* When LFN is to be created, allocate entries for an SFN + LFNs. */ + for (n = 0; lfn[n]; n++) ; + nent = (n + 25) / 13; + } else { /* Otherwise allocate an entry for an SFN */ + nent = 1; + } + res = dir_alloc(dp, nent); /* Allocate entries */ + + if (res == FR_OK && --nent) { /* Set LFN entry if needed */ + res = dir_sdi(dp, dp->index - nent); + if (res == FR_OK) { + sum = sum_sfn(dp->fn); /* Sum value of the SFN tied to the LFN */ + do { /* Store LFN entries in bottom first */ + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + fit_lfn(dp->lfn, dp->dir, (BYTE)nent, sum); + dp->fs->wflag = 1; + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK && --nent); + } + } +#else /* Non LFN configuration */ + res = dir_alloc(dp, 1); /* Allocate an entry for SFN */ +#endif + + if (res == FR_OK) { /* Set SFN entry */ + res = move_window(dp->fs, dp->sect); + if (res == FR_OK) { + mem_set(dp->dir, 0, SZ_DIR); /* Clean the entry */ + mem_cpy(dp->dir, dp->fn, 11); /* Put SFN */ +#if _USE_LFN + dp->dir[DIR_NTres] = dp->fn[NS] & (NS_BODY | NS_EXT); /* Put NT flag */ +#endif + dp->fs->wflag = 1; + } + } + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Remove an object from the directory */ +/*-----------------------------------------------------------------------*/ +#if !_FS_READONLY && !_FS_MINIMIZE +static +FRESULT dir_remove ( /* FR_OK: Successful, FR_DISK_ERR: A disk error */ + DIR* dp /* Directory object pointing the entry to be removed */ +) +{ + FRESULT res; +#if _USE_LFN /* LFN configuration */ + UINT i; + + i = dp->index; /* SFN index */ + res = dir_sdi(dp, (dp->lfn_idx == 0xFFFF) ? i : dp->lfn_idx); /* Goto the SFN or top of the LFN entries */ + if (res == FR_OK) { + do { + res = move_window(dp->fs, dp->sect); + if (res != FR_OK) break; + mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */ + *dp->dir = DDE; + dp->fs->wflag = 1; + if (dp->index >= i) break; /* When reached SFN, all entries of the object has been deleted. */ + res = dir_next(dp, 0); /* Next entry */ + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR; + } + +#else /* Non LFN configuration */ + res = dir_sdi(dp, dp->index); + if (res == FR_OK) { + res = move_window(dp->fs, dp->sect); + if (res == FR_OK) { + mem_set(dp->dir, 0, SZ_DIR); /* Clear and mark the entry "deleted" */ + *dp->dir = DDE; + dp->fs->wflag = 1; + } + } +#endif + + return res; +} +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Get file information from directory entry */ +/*-----------------------------------------------------------------------*/ +#if _FS_MINIMIZE <= 1 || _FS_RPATH >= 2 +static +void get_fileinfo ( /* No return code */ + DIR* dp, /* Pointer to the directory object */ + FILINFO* fno /* Pointer to the file information to be filled */ +) +{ + UINT i; + TCHAR *p, c; + + + p = fno->fname; + if (dp->sect) { /* Get SFN */ + BYTE *dir = dp->dir; + + i = 0; + while (i < 11) { /* Copy name body and extension */ + c = (TCHAR)dir[i++]; + if (c == ' ') continue; /* Skip padding spaces */ + if (c == NDDE) c = (TCHAR)DDE; /* Restore replaced DDE character */ + if (i == 9) *p++ = '.'; /* Insert a . if extension is exist */ +#if _USE_LFN + if (IsUpper(c) && (dir[DIR_NTres] & (i >= 9 ? NS_EXT : NS_BODY))) + c += 0x20; /* To lower */ +#if _LFN_UNICODE + if (IsDBCS1(c) && i != 8 && i != 11 && IsDBCS2(dir[i])) + c = c << 8 | dir[i++]; + c = ff_convert(c, 1); /* OEM -> Unicode */ + if (!c) c = '?'; +#endif +#endif + *p++ = c; + } + fno->fattrib = dir[DIR_Attr]; /* Attribute */ + fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */ + fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */ + fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */ + } + *p = 0; /* Terminate SFN string by a \0 */ + +#if _USE_LFN + if (fno->lfname) { + WCHAR w, *lfn; + + i = 0; p = fno->lfname; + if (dp->sect && fno->lfsize && dp->lfn_idx != 0xFFFF) { /* Get LFN if available */ + lfn = dp->lfn; + while ((w = *lfn++) != 0) { /* Get an LFN character */ +#if !_LFN_UNICODE + w = ff_convert(w, 0); /* Unicode -> OEM */ + if (!w) { i = 0; break; } /* No LFN if it could not be converted */ + if (_DF1S && w >= 0x100) /* Put 1st byte if it is a DBC (always false on SBCS cfg) */ + p[i++] = (TCHAR)(w >> 8); +#endif + if (i >= fno->lfsize - 1) { i = 0; break; } /* No LFN if buffer overflow */ + p[i++] = (TCHAR)w; + } + } + p[i] = 0; /* Terminate LFN string by a \0 */ + } +#endif +} +#endif /* _FS_MINIMIZE <= 1 || _FS_RPATH >= 2*/ + + + + +/*-----------------------------------------------------------------------*/ +/* Pick a segment and create the object name in directory form */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT create_name ( + DIR* dp, /* Pointer to the directory object */ + const TCHAR** path /* Pointer to pointer to the segment in the path string */ +) +{ +#if _USE_LFN /* LFN configuration */ + BYTE b, cf; + WCHAR w, *lfn; + UINT i, ni, si, di; + const TCHAR *p; + + /* Create LFN in Unicode */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + lfn = dp->lfn; + si = di = 0; + for (;;) { + w = p[si++]; /* Get a character */ + if (w < ' ' || w == '/' || w == '\\') break; /* Break on end of segment */ + if (di >= _MAX_LFN) /* Reject too long name */ + return FR_INVALID_NAME; +#if !_LFN_UNICODE + w &= 0xFF; +#if _DF1E // modified for remove compile warning + if (IsDBCS1(w)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + b = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(b)) + return FR_INVALID_NAME; /* Reject invalid sequence */ + w = (w << 8) + b; /* Create a DBC */ + } +#endif + w = ff_convert(w, 1); /* Convert ANSI/OEM to Unicode */ + if (!w) return FR_INVALID_NAME; /* Reject invalid code */ +#endif + if (w < 0x80 && chk_chr("\"*:<>\?|\x7F", w)) /* Reject illegal characters for LFN */ + return FR_INVALID_NAME; + lfn[di++] = w; /* Store the Unicode character */ + } + *path = &p[si]; /* Return pointer to the next segment */ + cf = (w < ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ +#if _FS_RPATH + if ((di == 1 && lfn[di-1] == '.') || /* Is this a dot entry? */ + (di == 2 && lfn[di-1] == '.' && lfn[di-2] == '.')) { + lfn[di] = 0; + for (i = 0; i < 11; i++) + dp->fn[i] = (i < di) ? '.' : ' '; + dp->fn[i] = cf | NS_DOT; /* This is a dot entry */ + return FR_OK; + } +#endif + while (di) { /* Strip trailing spaces and dots */ + w = lfn[di-1]; + if (w != ' ' && w != '.') break; + di--; + } + if (!di) return FR_INVALID_NAME; /* Reject nul string */ + + lfn[di] = 0; /* LFN is created */ + + /* Create SFN in directory form */ + mem_set(dp->fn, ' ', 11); + for (si = 0; lfn[si] == ' ' || lfn[si] == '.'; si++) ; /* Strip leading spaces and dots */ + if (si) cf |= NS_LOSS | NS_LFN; + while (di && lfn[di - 1] != '.') di--; /* Find extension (di<=si: no extension) */ + + b = i = 0; ni = 8; + for (;;) { + w = lfn[si++]; /* Get an LFN character */ + if (!w) break; /* Break on end of the LFN */ + if (w == ' ' || (w == '.' && si != di)) { /* Remove spaces and dots */ + cf |= NS_LOSS | NS_LFN; continue; + } + + if (i >= ni || si == di) { /* Extension or end of SFN */ + if (ni == 11) { /* Long extension */ + cf |= NS_LOSS | NS_LFN; break; + } + if (si != di) cf |= NS_LOSS | NS_LFN; /* Out of 8.3 format */ + if (si > di) break; /* No extension */ + si = di; i = 8; ni = 11; /* Enter extension section */ + b <<= 2; continue; + } + + if (w >= 0x80) { /* Non ASCII character */ +#ifdef _EXCVT + w = ff_convert(w, 0); /* Unicode -> OEM code */ + if (w) w = ExCvt[w - 0x80]; /* Convert extended character to upper (SBCS) */ +#else + w = ff_convert(ff_wtoupper(w), 0); /* Upper converted Unicode -> OEM code */ +#endif + cf |= NS_LFN; /* Force create LFN entry */ + } + + if (_DF1S && w >= 0x100) { /* Double byte character (always false on SBCS cfg) */ + if (i >= ni - 1) { + cf |= NS_LOSS | NS_LFN; i = ni; continue; + } + dp->fn[i++] = (BYTE)(w >> 8); + } else { /* Single byte character */ + if (!w || chk_chr("+,;=[]", w)) { /* Replace illegal characters for SFN */ + w = '_'; cf |= NS_LOSS | NS_LFN;/* Lossy conversion */ + } else { + if (IsUpper(w)) { /* ASCII large capital */ + b |= 2; + } else { + if (IsLower(w)) { /* ASCII small capital */ + b |= 1; w -= 0x20; + } + } + } + } + dp->fn[i++] = (BYTE)w; + } + + if (dp->fn[0] == DDE) dp->fn[0] = NDDE; /* If the first character collides with deleted mark, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x0C) == 0x0C || (b & 0x03) == 0x03) /* Create LFN entry when there are composite capitals */ + cf |= NS_LFN; + if (!(cf & NS_LFN)) { /* When LFN is in 8.3 format without extended character, NT flags are created */ + if ((b & 0x03) == 0x01) cf |= NS_EXT; /* NT flag (Extension has only small capital) */ + if ((b & 0x0C) == 0x04) cf |= NS_BODY; /* NT flag (Filename has only small capital) */ + } + + dp->fn[NS] = cf; /* SFN is created */ + + return FR_OK; + + +#else /* Non-LFN configuration */ + BYTE b, c, d, *sfn; + UINT ni, si, i; + const char *p; + + /* Create file name in directory form */ + for (p = *path; *p == '/' || *p == '\\'; p++) ; /* Strip duplicated separator */ + sfn = dp->fn; + mem_set(sfn, ' ', 11); + si = i = b = 0; ni = 8; +#if _FS_RPATH + if (p[si] == '.') { /* Is this a dot entry? */ + for (;;) { + c = (BYTE)p[si++]; + if (c != '.' || si >= 3) break; + sfn[i++] = c; + } + if (c != '/' && c != '\\' && c > ' ') return FR_INVALID_NAME; + *path = &p[si]; /* Return pointer to the next segment */ + sfn[NS] = (c <= ' ') ? NS_LAST | NS_DOT : NS_DOT; /* Set last segment flag if end of path */ + return FR_OK; + } +#endif + for (;;) { + c = (BYTE)p[si++]; + if (c <= ' ' || c == '/' || c == '\\') break; /* Break on end of segment */ + if (c == '.' || i >= ni) { + if (ni != 8 || c != '.') return FR_INVALID_NAME; + i = 8; ni = 11; + b <<= 2; continue; + } + if (c >= 0x80) { /* Extended character? */ + b |= 3; /* Eliminate NT flag */ +#ifdef _EXCVT + c = ExCvt[c - 0x80]; /* To upper extended characters (SBCS cfg) */ +#else +#if !_DF1S + return FR_INVALID_NAME; /* Reject extended characters (ASCII cfg) */ +#endif +#endif + } + if (IsDBCS1(c)) { /* Check if it is a DBC 1st byte (always false on SBCS cfg) */ + d = (BYTE)p[si++]; /* Get 2nd byte */ + if (!IsDBCS2(d) || i >= ni - 1) /* Reject invalid DBC */ + return FR_INVALID_NAME; + sfn[i++] = c; + sfn[i++] = d; + } else { /* Single byte code */ + if (chk_chr("\"*+,:;<=>\?[]|\x7F", c)) /* Reject illegal chrs for SFN */ + return FR_INVALID_NAME; + if (IsUpper(c)) { /* ASCII large capital? */ + b |= 2; + } else { + if (IsLower(c)) { /* ASCII small capital? */ + b |= 1; c -= 0x20; + } + } + sfn[i++] = c; + } + } + *path = &p[si]; /* Return pointer to the next segment */ + c = (c <= ' ') ? NS_LAST : 0; /* Set last segment flag if end of path */ + + if (!i) return FR_INVALID_NAME; /* Reject nul string */ + if (sfn[0] == DDE) sfn[0] = NDDE; /* When first character collides with DDE, replace it with 0x05 */ + + if (ni == 8) b <<= 2; + if ((b & 0x03) == 0x01) c |= NS_EXT; /* NT flag (Name extension has only small capital) */ + if ((b & 0x0C) == 0x04) c |= NS_BODY; /* NT flag (Name body has only small capital) */ + + sfn[NS] = c; /* Store NT flag, File name is created */ + + return FR_OK; +#endif +} + + + + +/*-----------------------------------------------------------------------*/ +/* Follow a file path */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */ + DIR* dp, /* Directory object to return last directory and found object */ + const TCHAR* path /* Full-path string to find a file or directory */ +) +{ + FRESULT res; + BYTE *dir, ns; + + +#if _FS_RPATH + if (*path == '/' || *path == '\\') { /* There is a heading separator */ + path++; dp->sclust = 0; /* Strip it and start from the root directory */ + } else { /* No heading separator */ + dp->sclust = dp->fs->cdir; /* Start from the current directory */ + } +#else + if (*path == '/' || *path == '\\') /* Strip heading separator if exist */ + path++; + dp->sclust = 0; /* Always start from the root directory */ +#endif + + if ((UINT)*path < ' ') { /* Null path name is the origin directory itself */ + res = dir_sdi(dp, 0); + dp->dir = 0; + } else { /* Follow path */ + for (;;) { + res = create_name(dp, &path); /* Get a segment name of the path */ + if (res != FR_OK) break; + + res = dir_find(dp); /* Find an object with the sagment name */ + ns = dp->fn[NS]; + if (res != FR_OK) { /* Failed to find the object */ + if (res == FR_NO_FILE) { /* Object is not found */ + if (_FS_RPATH && (ns & NS_DOT)) { /* If dot entry is not exist, */ + dp->sclust = 0; dp->dir = 0; /* it is the root directory and stay there */ + if (!(ns & NS_LAST)) continue; /* Continue to follow if not last segment */ + res = FR_OK; /* Ended at the root directroy. Function completed. */ + } else { /* Could not find the object */ + if (!(ns & NS_LAST)) res = FR_NO_PATH; /* Adjust error code if not last segment */ + } + } + break; + } + if (ns & NS_LAST) break; /* Last segment matched. Function completed. */ + dir = dp->dir; /* Follow the sub-directory */ + if (!(dir[DIR_Attr] & AM_DIR)) { /* It is not a sub-directory and cannot follow */ + res = FR_NO_PATH; break; + } + dp->sclust = ld_clust(dp->fs, dir); + } + } + + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Get logical drive number from path name */ +/*-----------------------------------------------------------------------*/ + +static +int get_ldnumber ( /* Returns logical drive number (-1:invalid drive) */ + const TCHAR** path /* Pointer to pointer to the path name */ +) +{ + const TCHAR *tp, *tt; + UINT i; + int vol = -1; + + + if (*path) { /* If the pointer is not a null */ + for (tt = *path; (UINT)*tt >= (_USE_LFN ? ' ' : '!') && *tt != ':'; tt++) ; /* Find ':' in the path */ + if (*tt == ':') { /* If a ':' is exist in the path name */ + tp = *path; + i = *tp++ - '0'; + if (i < 10 && tp == tt) { /* Is there a numeric drive id? */ + if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */ + vol = (int)i; + *path = ++tt; + } + } else { /* No numeric drive number */ +#if _STR_VOLUME_ID /* Find string drive id */ + static const char* const str[] = {_VOLUME_STRS}; + const char *sp; + char c; + TCHAR tc; + + i = 0; tt++; + do { + sp = str[i]; tp = *path; + do { /* Compare a string drive id with path name */ + c = *sp++; tc = *tp++; + if (IsLower(tc)) tc -= 0x20; + } while (c && (TCHAR)c == tc); + } while ((c || tp != tt) && ++i < _VOLUMES); /* Repeat for each id until pattern match */ + if (i < _VOLUMES) { /* If a drive id is found, get the value and strip it */ + vol = (int)i; + *path = tt; + } +#endif + } + return vol; + } +#if _FS_RPATH && _VOLUMES >= 2 + vol = CurrVol; /* Current drive */ +#else + vol = 0; /* Drive 0 */ +#endif + } + return vol; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Load a sector and check if it is an FAT boot sector */ +/*-----------------------------------------------------------------------*/ + +static +BYTE check_fs ( /* 0:FAT boor sector, 1:Valid boor sector but not FAT, 2:Not a boot sector, 3:Disk error */ + FATFS* fs, /* File system object */ + DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */ +) +{ + fs->wflag = 0; fs->winsect = 0xFFFFFFFF; /* Invaidate window */ + if (move_window(fs, sect) != FR_OK) /* Load boot record */ + return 3; + + if (LD_WORD(&fs->win[BS_55AA]) != 0xAA55) /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */ + return 2; + + if ((LD_DWORD(&fs->win[BS_FilSysType]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + if ((LD_DWORD(&fs->win[BS_FilSysType32]) & 0xFFFFFF) == 0x544146) /* Check "FAT" string */ + return 0; + + return 1; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Find logical drive and check if the volume is mounted */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT find_volume ( /* FR_OK(0): successful, !=0: any error occurred */ + FATFS** rfs, /* Pointer to pointer to the found file system object */ + const TCHAR** path, /* Pointer to pointer to the path name (drive number) */ + BYTE wmode /* !=0: Check write protection for write access */ +) +{ + BYTE fmt; + int vol; + DSTATUS stat; + DWORD bsect, fasize, tsect, sysect, nclst, szbfat; + WORD nrsv; + FATFS *fs; + + + /* Get logical drive number from the path name */ + *rfs = 0; + vol = get_ldnumber(path); + if (vol < 0) return FR_INVALID_DRIVE; + + /* Check if the file system object is valid or not */ + fs = FatFs[vol]; /* Get pointer to the file system object */ + if (!fs) return FR_NOT_ENABLED; /* Is the file system object available? */ + + ENTER_FF(fs); /* Lock the volume */ + *rfs = fs; /* Return pointer to the file system object */ + + if (fs->fs_type) { /* If the volume has been mounted */ + stat = disk_status(fs->drv); + if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check write protection if needed */ + return FR_WRITE_PROTECTED; + return FR_OK; /* The file system object is valid */ + } + } + + /* The file system object is not valid. */ + /* Following code attempts to mount the volume. (analyze BPB and initialize the fs object) */ + + fs->fs_type = 0; /* Clear the file system object */ + fs->drv = LD2PD(vol); /* Bind the logical drive and a physical drive */ + stat = disk_initialize(fs->drv); /* Initialize the physical drive */ + if (stat & STA_NOINIT) /* Check if the initialization succeeded */ + return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */ + if (!_FS_READONLY && wmode && (stat & STA_PROTECT)) /* Check disk write protection if needed */ + return FR_WRITE_PROTECTED; +#if _MAX_SS != _MIN_SS /* Get sector size (multiple sector size cfg only) */ + if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK + || SS(fs) < _MIN_SS || SS(fs) > _MAX_SS) return FR_DISK_ERR; +#endif + /* Find an FAT partition on the drive. Supports only generic partitioning, FDISK and SFD. */ + bsect = 0; + fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT boot sector as SFD */ + if (fmt == 1 || (!fmt && (LD2PT(vol)))) { /* Not an FAT boot sector or forced partition number */ + UINT i; + DWORD br[4]; + + for (i = 0; i < 4; i++) { /* Get partition offset */ + BYTE *pt = fs->win+MBR_Table + i * SZ_PTE; + br[i] = pt[4] ? LD_DWORD(&pt[8]) : 0; + } + i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */ + if (i) i--; + do { /* Find an FAT volume */ + bsect = br[i]; + fmt = bsect ? check_fs(fs, bsect) : 2; /* Check the partition */ + } while (!LD2PT(vol) && fmt && ++i < 4); + } + if (fmt == 3) return FR_DISK_ERR; /* An error occured in the disk I/O layer */ + if (fmt) return FR_NO_FILESYSTEM; /* No FAT volume is found */ + + /* An FAT volume is found. Following code initializes the file system object */ + + if (LD_WORD(fs->win+BPB_BytsPerSec) != SS(fs)) /* (BPB_BytsPerSec must be equal to the physical sector size) */ + return FR_NO_FILESYSTEM; + + fasize = LD_WORD(fs->win+BPB_FATSz16); /* Number of sectors per FAT */ + if (!fasize) fasize = LD_DWORD(fs->win+BPB_FATSz32); + fs->fsize = fasize; + + fs->n_fats = fs->win[BPB_NumFATs]; /* Number of FAT copies */ + if (fs->n_fats != 1 && fs->n_fats != 2) /* (Must be 1 or 2) */ + return FR_NO_FILESYSTEM; + fasize *= fs->n_fats; /* Number of sectors for FAT area */ + + fs->csize = fs->win[BPB_SecPerClus]; /* Number of sectors per cluster */ + if (!fs->csize || (fs->csize & (fs->csize - 1))) /* (Must be power of 2) */ + return FR_NO_FILESYSTEM; + + fs->n_rootdir = LD_WORD(fs->win+BPB_RootEntCnt); /* Number of root directory entries */ + if (fs->n_rootdir % (SS(fs) / SZ_DIR)) /* (Must be sector aligned) */ + return FR_NO_FILESYSTEM; + + tsect = LD_WORD(fs->win+BPB_TotSec16); /* Number of sectors on the volume */ + if (!tsect) tsect = LD_DWORD(fs->win+BPB_TotSec32); + + nrsv = LD_WORD(fs->win+BPB_RsvdSecCnt); /* Number of reserved sectors */ + if (!nrsv) return FR_NO_FILESYSTEM; /* (Must not be 0) */ + + /* Determine the FAT sub type */ + sysect = nrsv + fasize + fs->n_rootdir / (SS(fs) / SZ_DIR); /* RSV+FAT+DIR */ + if (tsect < sysect) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + nclst = (tsect - sysect) / fs->csize; /* Number of clusters */ + if (!nclst) return FR_NO_FILESYSTEM; /* (Invalid volume size) */ + fmt = FS_FAT12; + if (nclst >= MIN_FAT16) fmt = FS_FAT16; + if (nclst >= MIN_FAT32) fmt = FS_FAT32; + + /* Boundaries and Limits */ + fs->n_fatent = nclst + 2; /* Number of FAT entries */ + fs->volbase = bsect; /* Volume start sector */ + fs->fatbase = bsect + nrsv; /* FAT start sector */ + fs->database = bsect + sysect; /* Data start sector */ + if (fmt == FS_FAT32) { + if (fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must be 0) */ + fs->dirbase = LD_DWORD(fs->win+BPB_RootClus); /* Root directory start cluster */ + szbfat = fs->n_fatent * 4; /* (Needed FAT size) */ + } else { + if (!fs->n_rootdir) return FR_NO_FILESYSTEM; /* (BPB_RootEntCnt must not be 0) */ + fs->dirbase = fs->fatbase + fasize; /* Root directory start sector */ + szbfat = (fmt == FS_FAT16) ? /* (Needed FAT size) */ + fs->n_fatent * 2 : fs->n_fatent * 3 / 2 + (fs->n_fatent & 1); + } + if (fs->fsize < (szbfat + (SS(fs) - 1)) / SS(fs)) /* (BPB_FATSz must not be less than needed) */ + return FR_NO_FILESYSTEM; + +#if !_FS_READONLY + /* Initialize cluster allocation information */ + fs->last_clust = fs->free_clust = 0xFFFFFFFF; + + /* Get fsinfo if available */ + fs->fsi_flag = 0x80; +#if (_FS_NOFSINFO & 3) != 3 + if (fmt == FS_FAT32 /* Enable FSINFO only if FAT32 and BPB_FSInfo is 1 */ + && LD_WORD(fs->win+BPB_FSInfo) == 1 + && move_window(fs, bsect + 1) == FR_OK) + { + fs->fsi_flag = 0; + if (LD_WORD(fs->win+BS_55AA) == 0xAA55 /* Load FSINFO data if available */ + && LD_DWORD(fs->win+FSI_LeadSig) == 0x41615252 + && LD_DWORD(fs->win+FSI_StrucSig) == 0x61417272) + { +#if (_FS_NOFSINFO & 1) == 0 + fs->free_clust = LD_DWORD(fs->win+FSI_Free_Count); +#endif +#if (_FS_NOFSINFO & 2) == 0 + fs->last_clust = LD_DWORD(fs->win+FSI_Nxt_Free); +#endif + } + } +#endif +#endif + fs->fs_type = fmt; /* FAT sub-type */ + fs->id = ++Fsid; /* File system mount ID */ +#if _FS_RPATH + fs->cdir = 0; /* Set current directory to root */ +#endif +#if _FS_LOCK /* Clear file lock semaphores */ + clear_lock(fs); +#endif + + return FR_OK; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Check if the file/directory object is valid or not */ +/*-----------------------------------------------------------------------*/ + +static +FRESULT validate ( /* FR_OK(0): The object is valid, !=0: Invalid */ + void* obj /* Pointer to the object FIL/DIR to check validity */ +) +{ + FIL *fil = (FIL*)obj; /* Assuming offset of .fs and .id in the FIL/DIR structure is identical */ + + + if (!fil || !fil->fs || !fil->fs->fs_type || fil->fs->id != fil->id) + return FR_INVALID_OBJECT; + + ENTER_FF(fil->fs); /* Lock file system */ + + if (disk_status(fil->fs->drv) & STA_NOINIT) + return FR_NOT_READY; + + return FR_OK; +} + + + + +/*-------------------------------------------------------------------------- + + Public Functions + +--------------------------------------------------------------------------*/ + + + +/*-----------------------------------------------------------------------*/ +/* Mount/Unmount a Logical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mount ( + FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/ + const TCHAR* path, /* Logical drive number to be mounted/unmounted */ + BYTE opt /* 0:Do not mount (delayed mount), 1:Mount immediately */ +) +{ + FATFS *cfs; + int vol; + FRESULT res; + const TCHAR *rp = path; + + + vol = get_ldnumber(&rp); + if (vol < 0) return FR_INVALID_DRIVE; + cfs = FatFs[vol]; /* Pointer to fs object */ + + if (cfs) { +#if _FS_LOCK + clear_lock(cfs); +#endif +#if _FS_REENTRANT /* Discard sync object of the current volume */ + if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR; +#endif + cfs->fs_type = 0; /* Clear old fs object */ + } + + if (fs) { + fs->fs_type = 0; /* Clear new fs object */ +#if _FS_REENTRANT /* Create sync object for the new volume */ + if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR; +#endif + } + FatFs[vol] = fs; /* Register new fs object */ + + if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */ + + res = find_volume(&fs, &path, 0); /* Force mounted the volume */ + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Open or Create a File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_open ( + FIL* fp, /* Pointer to the blank file object */ + const TCHAR* path, /* Pointer to the file name */ + BYTE mode /* Access mode and file open mode flags */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + if (!fp) return FR_INVALID_OBJECT; + fp->fs = 0; /* Clear file object */ + + /* Get logical drive number */ +#if !_FS_READONLY + mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW; + res = find_volume(&dj.fs, &path, (BYTE)(mode & ~FA_READ)); +#else + mode &= FA_READ; + res = find_volume(&dj.fs, &path, 0); +#endif + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + dir = dj.dir; +#if !_FS_READONLY /* R/W configuration */ + if (res == FR_OK) { + if (!dir) /* Default directory itself */ + res = FR_INVALID_NAME; +#if _FS_LOCK + else + res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0); +#endif + } + /* Create or Open a file */ + if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) { + DWORD dw, cl; + + if (res != FR_OK) { /* No file, create new */ + if (res == FR_NO_FILE) /* There is no file to open, create a new entry */ +#if _FS_LOCK + res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES; +#else + res = dir_register(&dj); +#endif + mode |= FA_CREATE_ALWAYS; /* File is created */ + dir = dj.dir; /* New entry */ + } + else { /* Any object is already existing */ + if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */ + res = FR_DENIED; + } else { + if (mode & FA_CREATE_NEW) /* Cannot create as new file */ + res = FR_EXIST; + } + } + if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */ + dw = get_fattime(); /* Created time */ + ST_DWORD(dir+DIR_CrtTime, dw); + dir[DIR_Attr] = 0; /* Reset attribute */ + ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */ + cl = ld_clust(dj.fs, dir); /* Get start cluster */ + st_clust(dir, 0); /* cluster = 0 */ + dj.fs->wflag = 1; + if (cl) { /* Remove the cluster chain if exist */ + dw = dj.fs->winsect; + res = remove_chain(dj.fs, cl); + if (res == FR_OK) { + dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */ + res = move_window(dj.fs, dw); + } + } + } + } + else { /* Open an existing file */ + if (res == FR_OK) { /* Follow succeeded */ + if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */ + res = FR_NO_FILE; + } else { + if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */ + res = FR_DENIED; + } + } + } + if (res == FR_OK) { + if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */ + mode |= FA__WRITTEN; + fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */ + fp->dir_ptr = dir; +#if _FS_LOCK + fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0); + if (!fp->lockid) res = FR_INT_ERR; +#endif + } + +#else /* R/O configuration */ + if (res == FR_OK) { /* Follow succeeded */ + dir = dj.dir; + if (!dir) { /* Current directory itself */ + res = FR_INVALID_NAME; + } else { + if (dir[DIR_Attr] & AM_DIR) /* It is a directory */ + res = FR_NO_FILE; + } + } +#endif + FREE_BUF(); + + if (res == FR_OK) { + fp->flag = mode; /* File access mode */ + fp->err = 0; /* Clear error flag */ + fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */ + fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */ + fp->fptr = 0; /* File pointer */ + fp->dsect = 0; +#if _USE_FASTSEEK + fp->cltbl = 0; /* Normal seek mode */ +#endif + fp->fs = dj.fs; /* Validate file object */ + fp->id = fp->fs->id; + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_read ( + FIL* fp, /* Pointer to the file object */ + void* buff, /* Pointer to data buffer */ + UINT btr, /* Number of bytes to read */ + UINT* br /* Pointer to number of bytes read */ +) +{ + FRESULT res; + DWORD clst, sect, remain; + UINT rcnt, cc; + BYTE csect, *rbuff = (BYTE*)buff; + + *br = 0; /* Clear read byte counter */ + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + remain = fp->fsize - fp->fptr; + if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */ + + for ( ; btr; /* Repeat until all data read */ + rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */ + } + if (clst < 2) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Read maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_read(fp->fs->drv, rbuff, sect, cc)) + ABORT(fp->fs, FR_DISK_ERR); +#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */ +#if _FS_TINY + if (fp->fs->wflag && fp->fs->winsect - sect < cc) + mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs)); +#else + if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc) + mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs)); +#endif +#endif + rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if !_FS_TINY + if (fp->dsect != sect) { /* Load data sector if not in cache */ +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, sect, 1)) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */ + if (rcnt > btr) rcnt = btr; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#else + mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */ +#endif + } + + LEAVE_FF(fp->fs, FR_OK); +} + + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Write File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_write ( + FIL* fp, /* Pointer to the file object */ + const void *buff, /* Pointer to the data to be written */ + UINT btw, /* Number of bytes to write */ + UINT* bw /* Pointer to number of bytes written */ +) +{ + FRESULT res; + DWORD clst, sect; + UINT wcnt, cc; + const BYTE *wbuff = (const BYTE*)buff; + BYTE csect; + + *bw = 0; /* Clear write byte counter */ + +// rtl_printf("f_write(%p, %p, %d) = %d\n", fp, buff, btw); + + res = validate(fp); /* Check validity */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + if (fp->fptr + btw < fp->fptr) btw = 0; /* File size cannot reach 4GB */ + + for ( ; btw; /* Repeat until all data written */ + wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) { + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if (!csect) { /* On the cluster boundary? */ + if (fp->fptr == 0) { /* On the top of the file? */ + clst = fp->sclust; /* Follow from the origin */ + if (clst == 0) /* When no cluster is allocated, */ + clst = create_chain(fp->fs, 0); /* Create a new cluster chain */ + } else { /* Middle or end of the file */ +#if _USE_FASTSEEK + if (fp->cltbl) + clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */ + else +#endif + clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */ + } + if (clst == 0) break; /* Could not allocate a new cluster (disk full) */ + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + if (fp->sclust == 0) fp->sclust = clst; /* Set start cluster if the first write */ + } +#if _FS_TINY + if (fp->fs->winsect == fp->dsect && sync_window(fp->fs)) /* Write-back sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#else + if (fp->flag & FA__DIRTY) { /* Write-back sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + sect = clust2sect(fp->fs, fp->clust); /* Get current sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */ + if (cc) { /* Write maximum contiguous sectors directly */ + if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */ + cc = fp->fs->csize - csect; + if (disk_write(fp->fs->drv, wbuff, sect, cc)) + ABORT(fp->fs, FR_DISK_ERR); +#if _FS_MINIMIZE <= 2 +#if _FS_TINY + if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->fs->wflag = 0; + } +#else + if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */ + mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs)); + fp->flag &= ~FA__DIRTY; + } +#endif +#endif + wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */ + continue; + } +#if _FS_TINY + if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */ + if (sync_window(fp->fs)) ABORT(fp->fs, FR_DISK_ERR); + fp->fs->winsect = sect; + } +#else + if (fp->dsect != sect) { /* Fill sector cache with file data */ + if (fp->fptr < fp->fsize && + disk_read(fp->fs->drv, fp->buf, sect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + } +#endif + fp->dsect = sect; + } + wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */ + if (wcnt > btw) wcnt = btw; +#if _FS_TINY + if (move_window(fp->fs, fp->dsect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->fs->wflag = 1; +#else + mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */ + fp->flag |= FA__DIRTY; +#endif + } + + if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */ + fp->flag |= FA__WRITTEN; /* Set file change flag */ + + LEAVE_FF(fp->fs, FR_OK); +} + + +/*-----------------------------------------------------------------------*/ +/* Synchronize the File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_sync ( + FIL* fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD tm; + BYTE *dir; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ + /* Write-back dirty buffer */ +#if !_FS_TINY + if (fp->flag & FA__DIRTY) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + LEAVE_FF(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + /* Update the directory entry */ + res = move_window(fp->fs, fp->dir_sect); + if (res == FR_OK) { + dir = fp->dir_ptr; + dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ + ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */ + st_clust(dir, fp->sclust); /* Update start cluster */ + tm = get_fattime(); /* Update updated time */ + ST_DWORD(dir+DIR_WrtTime, tm); + ST_WORD(dir+DIR_LstAccDate, 0); + fp->flag &= ~FA__WRITTEN; + fp->fs->wflag = 1; + res = sync_fs(fp->fs); + } + } + } + + LEAVE_FF(fp->fs, res); +} + +#endif /* !_FS_READONLY */ + + + + +/*-----------------------------------------------------------------------*/ +/* Close File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_close ( + FIL *fp /* Pointer to the file object to be closed */ +) +{ + FRESULT res; + + +#if !_FS_READONLY + res = f_sync(fp); /* Flush cached data */ + if (res == FR_OK) +#endif + { + res = validate(fp); /* Lock volume */ + if (res == FR_OK) { +#if _FS_REENTRANT + FATFS *fs = fp->fs; +#endif +#if _FS_LOCK + res = dec_lock(fp->lockid); /* Decrement file open counter */ + if (res == FR_OK) +#endif + fp->fs = 0; /* Invalidate file object */ +#if _FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + } + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Current Directory or Current Drive, Get Current Directory */ +/*-----------------------------------------------------------------------*/ + +#if _FS_RPATH >= 1 +#if _VOLUMES >= 2 +FRESULT f_chdrive ( + const TCHAR* path /* Drive number */ +) +{ + int vol; + + + vol = get_ldnumber(&path); + if (vol < 0) return FR_INVALID_DRIVE; + + CurrVol = (BYTE)vol; + + return FR_OK; +} +#endif + + +FRESULT f_chdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the path */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (!dj.dir) { + dj.fs->cdir = dj.sclust; /* Start directory itself */ + } else { + if (dj.dir[DIR_Attr] & AM_DIR) /* Reached to the directory */ + dj.fs->cdir = ld_clust(dj.fs, dj.dir); + else + res = FR_NO_PATH; /* Reached but a file */ + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + + LEAVE_FF(dj.fs, res); +} + + +#if _FS_RPATH >= 2 +FRESULT f_getcwd ( + TCHAR* buff, /* Pointer to the directory path */ + UINT len /* Size of path */ +) +{ + FRESULT res; + DIR dj; + UINT i, n; + DWORD ccl; + TCHAR *tp; + FILINFO fno; + DEF_NAMEBUF; + + + *buff = 0; + /* Get logical drive number */ + res = find_volume(&dj.fs, (const TCHAR**)&buff, 0); /* Get current volume */ + if (res == FR_OK) { + INIT_BUF(dj); + i = len; /* Bottom of buffer (directory stack base) */ + dj.sclust = dj.fs->cdir; /* Start to follow upper directory from current directory */ + while ((ccl = dj.sclust) != 0) { /* Repeat while current directory is a sub-directory */ + res = dir_sdi(&dj, 1); /* Get parent directory */ + if (res != FR_OK) break; + res = dir_read(&dj, 0); + if (res != FR_OK) break; + dj.sclust = ld_clust(dj.fs, dj.dir); /* Goto parent directory */ + res = dir_sdi(&dj, 0); + if (res != FR_OK) break; + do { /* Find the entry links to the child directory */ + res = dir_read(&dj, 0); + if (res != FR_OK) break; + if (ccl == ld_clust(dj.fs, dj.dir)) break; /* Found the entry */ + res = dir_next(&dj, 0); + } while (res == FR_OK); + if (res == FR_NO_FILE) res = FR_INT_ERR;/* It cannot be 'not found'. */ + if (res != FR_OK) break; +#if _USE_LFN + fno.lfname = buff; + fno.lfsize = i; +#endif + get_fileinfo(&dj, &fno); /* Get the directory name and push it to the buffer */ + tp = fno.fname; +#if _USE_LFN + if (*buff) tp = buff; +#endif + for (n = 0; tp[n]; n++) ; + if (i < n + 3) { + res = FR_NOT_ENOUGH_CORE; break; + } + while (n) buff[--i] = tp[--n]; + buff[--i] = '/'; + } + tp = buff; + if (res == FR_OK) { +#if _VOLUMES >= 2 + *tp++ = '0' + CurrVol; /* Put drive number */ + *tp++ = ':'; +#endif + if (i == len) { /* Root-directory */ + *tp++ = '/'; + } else { /* Sub-directroy */ + do /* Add stacked path str */ + *tp++ = buff[i++]; + while (i < len); + } + } + *tp = 0; + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} +#endif /* _FS_RPATH >= 2 */ +#endif /* _FS_RPATH >= 1 */ + + + +#if _FS_MINIMIZE <= 2 +/*-----------------------------------------------------------------------*/ +/* Seek File R/W Pointer */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_lseek ( + FIL* fp, /* Pointer to the file object */ + DWORD ofs /* File pointer from top of file */ +) +{ + FRESULT res; + + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + +#if _USE_FASTSEEK + if (fp->cltbl) { /* Fast seek */ + DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl; + + if (ofs == CREATE_LINKMAP) { /* Create CLMT */ + tbl = fp->cltbl; + tlen = *tbl++; ulen = 2; /* Given table size and required table size */ + cl = fp->sclust; /* Top of the chain */ + if (cl) { + do { + /* Get a fragment */ + tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */ + do { + pcl = cl; ncl++; + cl = get_fat(fp->fs, cl); + if (cl <= 1) ABORT(fp->fs, FR_INT_ERR); + if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + } while (cl == pcl + 1); + if (ulen <= tlen) { /* Store the length and top of the fragment */ + *tbl++ = ncl; *tbl++ = tcl; + } + } while (cl < fp->fs->n_fatent); /* Repeat until end of chain */ + } + *fp->cltbl = ulen; /* Number of items used */ + if (ulen <= tlen) + *tbl = 0; /* Terminate table */ + else + res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */ + + } else { /* Fast seek */ + if (ofs > fp->fsize) /* Clip offset at the file size */ + ofs = fp->fsize; + fp->fptr = ofs; /* Set file pointer */ + if (ofs) { + fp->clust = clmt_clust(fp, ofs - 1); + dsc = clust2sect(fp->fs, fp->clust); + if (!dsc) ABORT(fp->fs, FR_INT_ERR); + dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1); + if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, dsc, 1)) /* Load current sector */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = dsc; + } + } + } + } else +#endif + + /* Normal Seek */ + { + DWORD clst, bcs, nsect, ifptr; + + if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */ +#if !_FS_READONLY + && !(fp->flag & FA_WRITE) +#endif + ) ofs = fp->fsize; + + ifptr = fp->fptr; + fp->fptr = nsect = 0; + if (ofs) { + bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */ + if (ifptr > 0 && + (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */ + fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */ + ofs -= fp->fptr; + clst = fp->clust; + } else { /* When seek to back cluster, */ + clst = fp->sclust; /* start from the first cluster */ +#if !_FS_READONLY + if (clst == 0) { /* If no cluster chain, create a new chain */ + clst = create_chain(fp->fs, 0); + if (clst == 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->sclust = clst; + } +#endif + fp->clust = clst; + } + if (clst != 0) { + while (ofs > bcs) { /* Cluster following loop */ +#if !_FS_READONLY + if (fp->flag & FA_WRITE) { /* Check if in write mode or not */ + clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */ + if (clst == 0) { /* When disk gets full, clip file size */ + ofs = bcs; break; + } + } else +#endif + clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */ + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR); + fp->clust = clst; + fp->fptr += bcs; + ofs -= bcs; + } + fp->fptr += ofs; + if (ofs % SS(fp->fs)) { + nsect = clust2sect(fp->fs, clst); /* Current sector */ + if (!nsect) ABORT(fp->fs, FR_INT_ERR); + nsect += ofs / SS(fp->fs); + } + } + } + if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */ +#if !_FS_TINY +#if !_FS_READONLY + if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */ + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + ABORT(fp->fs, FR_DISK_ERR); + fp->flag &= ~FA__DIRTY; + } +#endif + if (disk_read(fp->fs->drv, fp->buf, nsect, 1)) /* Fill sector cache */ + ABORT(fp->fs, FR_DISK_ERR); +#endif + fp->dsect = nsect; + } +#if !_FS_READONLY + if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */ + fp->fsize = fp->fptr; + fp->flag |= FA__WRITTEN; + } +#endif + } + + LEAVE_FF(fp->fs, res); +} + + + +#if _FS_MINIMIZE <= 1 +/*-----------------------------------------------------------------------*/ +/* Create a Directory Object */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_opendir ( + DIR* dp, /* Pointer to directory object to create */ + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + FATFS* fs; + DEF_NAMEBUF; + + + if (!dp) return FR_INVALID_OBJECT; + + /* Get logical drive number */ + res = find_volume(&fs, &path, 0); + if (res == FR_OK) { + dp->fs = fs; + INIT_BUF(*dp); + res = follow_path(dp, path); /* Follow the path to the directory */ + FREE_BUF(); + if (res == FR_OK) { /* Follow completed */ + if (dp->dir) { /* It is not the origin directory itself */ + if (dp->dir[DIR_Attr] & AM_DIR) /* The object is a sub directory */ + dp->sclust = ld_clust(fs, dp->dir); + else /* The object is a file */ + res = FR_NO_PATH; + } + if (res == FR_OK) { + dp->id = fs->id; + res = dir_sdi(dp, 0); /* Rewind directory */ +#if _FS_LOCK + if (res == FR_OK) { + if (dp->sclust) { + dp->lockid = inc_lock(dp, 0); /* Lock the sub directory */ + if (!dp->lockid) + res = FR_TOO_MANY_OPEN_FILES; + } else { + dp->lockid = 0; /* Root directory need not to be locked */ + } + } +#endif + } + } + if (res == FR_NO_FILE) res = FR_NO_PATH; + } + if (res != FR_OK) dp->fs = 0; /* Invalidate the directory object if function faild */ + + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Close Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_closedir ( + DIR *dp /* Pointer to the directory object to be closed */ +) +{ + FRESULT res; + + + res = validate(dp); + if (res == FR_OK) { +#if _FS_REENTRANT + FATFS *fs = dp->fs; +#endif +#if _FS_LOCK + if (dp->lockid) /* Decrement sub-directory open counter */ + res = dec_lock(dp->lockid); + if (res == FR_OK) +#endif + dp->fs = 0; /* Invalidate directory object */ +#if _FS_REENTRANT + unlock_fs(fs, FR_OK); /* Unlock volume */ +#endif + } + return res; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Read Directory Entries in Sequence */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_readdir ( + DIR* dp, /* Pointer to the open directory object */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DEF_NAMEBUF; + + + res = validate(dp); /* Check validity of the object */ + if (res == FR_OK) { + if (!fno) { + res = dir_sdi(dp, 0); /* Rewind the directory object */ + } else { + INIT_BUF(*dp); + res = dir_read(dp, 0); /* Read an item */ + if (res == FR_NO_FILE) { /* Reached end of directory */ + dp->sect = 0; + res = FR_OK; + } + if (res == FR_OK) { /* A valid entry is found */ + get_fileinfo(dp, fno); /* Get the object information */ + res = dir_next(dp, 0); /* Increment index for next */ + if (res == FR_NO_FILE) { + dp->sect = 0; + res = FR_OK; + } + } + FREE_BUF(); + } + } + + LEAVE_FF(dp->fs, res); +} + + + +#if _FS_MINIMIZE == 0 +/*-----------------------------------------------------------------------*/ +/* Get File Status */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_stat ( + const TCHAR* path, /* Pointer to the file path */ + FILINFO* fno /* Pointer to file information to return */ +) +{ + FRESULT res; + DIR dj; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) { /* Follow completed */ + if (dj.dir) { /* Found an object */ + if (fno) get_fileinfo(&dj, fno); + } else { /* It is root directory */ + res = FR_INVALID_NAME; + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Get Number of Free Clusters */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getfree ( + const TCHAR* path, /* Path name of the logical drive number */ + DWORD* nclst, /* Pointer to a variable to return number of free clusters */ + FATFS** fatfs /* Pointer to return pointer to corresponding file system object */ +) +{ + FRESULT res; + FATFS *fs; + DWORD n, clst, sect, stat; + UINT i; + BYTE fat, *p; + + + /* Get logical drive number */ + res = find_volume(fatfs, &path, 0); + fs = *fatfs; + if (res == FR_OK) { + /* If free_clust is valid, return it without full cluster scan */ + if (fs->free_clust <= fs->n_fatent - 2) { + *nclst = fs->free_clust; + } else { + /* Get number of free clusters */ + fat = fs->fs_type; + n = 0; + if (fat == FS_FAT12) { + clst = 2; + do { + stat = get_fat(fs, clst); + if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; } + if (stat == 1) { res = FR_INT_ERR; break; } + if (stat == 0) n++; + } while (++clst < fs->n_fatent); + } else { + clst = fs->n_fatent; + sect = fs->fatbase; + i = 0; p = 0; + do { + if (!i) { + res = move_window(fs, sect++); + if (res != FR_OK) break; + p = fs->win; + i = SS(fs); + } + if (fat == FS_FAT16) { + if (LD_WORD(p) == 0) n++; + p += 2; i -= 2; + } else { + if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++; + p += 4; i -= 4; + } + } while (--clst); + } + fs->free_clust = n; + fs->fsi_flag |= 1; + *nclst = n; + } + } + LEAVE_FF(fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Truncate File */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_truncate ( + FIL* fp /* Pointer to the file object */ +) +{ + FRESULT res; + DWORD ncl; + + + res = validate(fp); /* Check validity of the object */ + if (res == FR_OK) { + if (fp->err) { /* Check error */ + res = (FRESULT)fp->err; + } else { + if (!(fp->flag & FA_WRITE)) /* Check access mode */ + res = FR_DENIED; + } + } + if (res == FR_OK) { + if (fp->fsize > fp->fptr) { + fp->fsize = fp->fptr; /* Set file size to current R/W point */ + fp->flag |= FA__WRITTEN; + if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */ + res = remove_chain(fp->fs, fp->sclust); + fp->sclust = 0; + } else { /* When truncate a part of the file, remove remaining clusters */ + ncl = get_fat(fp->fs, fp->clust); + res = FR_OK; + if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (ncl == 1) res = FR_INT_ERR; + if (res == FR_OK && ncl < fp->fs->n_fatent) { + res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF); + if (res == FR_OK) res = remove_chain(fp->fs, ncl); + } + } +#if !_FS_TINY + if (res == FR_OK && (fp->flag & FA__DIRTY)) { + if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1)) + res = FR_DISK_ERR; + else + fp->flag &= ~FA__DIRTY; + } +#endif + } + if (res != FR_OK) fp->err = (FRESULT)res; + } + + LEAVE_FF(fp->fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Delete a File or Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_unlink ( + const TCHAR* path /* Pointer to the file or directory path */ +) +{ + FRESULT res; + DIR dj, sdj; + BYTE *dir; + DWORD dclst; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; /* Cannot remove dot entry */ +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */ +#endif + if (res == FR_OK) { /* The object is accessible */ + dir = dj.dir; + if (!dir) { + res = FR_INVALID_NAME; /* Cannot remove the start directory */ + } else { + if (dir[DIR_Attr] & AM_RDO) + res = FR_DENIED; /* Cannot remove R/O object */ + } + dclst = ld_clust(dj.fs, dir); + if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */ + if (dclst < 2) { + res = FR_INT_ERR; + } else { + mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-directory is empty or not */ + sdj.sclust = dclst; + res = dir_sdi(&sdj, 2); /* Exclude dot entries */ + if (res == FR_OK) { + res = dir_read(&sdj, 0); /* Read an item */ + if (res == FR_OK /* Not empty directory */ +#if _FS_RPATH + || dclst == dj.fs->cdir /* Current directory */ +#endif + ) res = FR_DENIED; + if (res == FR_NO_FILE) res = FR_OK; /* Empty */ + } + } + } + if (res == FR_OK) { + res = dir_remove(&dj); /* Remove the directory entry */ + if (res == FR_OK) { + if (dclst) /* Remove the cluster chain if exist */ + res = remove_chain(dj.fs, dclst); + if (res == FR_OK) res = sync_fs(dj.fs); + } + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Create a Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_mkdir ( + const TCHAR* path /* Pointer to the directory path */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir, n; + DWORD dsc, dcl, pcl, tm = get_fattime(); + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */ + if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_NO_FILE) { /* Can create a new directory */ + dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */ + res = FR_OK; + if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */ + if (dcl == 1) res = FR_INT_ERR; + if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR; + if (res == FR_OK) /* Flush FAT */ + res = sync_window(dj.fs); + if (res == FR_OK) { /* Initialize the new directory table */ + dsc = clust2sect(dj.fs, dcl); + dir = dj.fs->win; + mem_set(dir, 0, SS(dj.fs)); + mem_set(dir+DIR_Name, ' ', 11); /* Create "." entry */ + dir[DIR_Name] = '.'; + dir[DIR_Attr] = AM_DIR; + ST_DWORD(dir+DIR_WrtTime, tm); + st_clust(dir, dcl); + mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */ + dir[SZ_DIR+1] = '.'; pcl = dj.sclust; + if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase) + pcl = 0; + st_clust(dir+SZ_DIR, pcl); + for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */ + dj.fs->winsect = dsc++; + dj.fs->wflag = 1; + res = sync_window(dj.fs); + if (res != FR_OK) break; + mem_set(dir, 0, SS(dj.fs)); + } + } + if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */ + if (res != FR_OK) { + remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */ + } else { + dir = dj.dir; + dir[DIR_Attr] = AM_DIR; /* Attribute */ + ST_DWORD(dir+DIR_WrtTime, tm); /* Created time */ + st_clust(dir, dcl); /* Table start cluster */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + FREE_BUF(); + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Attribute */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_chmod ( + const TCHAR* path, /* Pointer to the file path */ + BYTE value, /* Attribute bits */ + BYTE mask /* Attribute mask to change */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Is it a root directory? */ + res = FR_INVALID_NAME; + } else { /* File or sub directory */ + mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */ + dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */ + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Change Timestamp */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_utime ( + const TCHAR* path, /* Pointer to the file/directory name */ + const FILINFO* fno /* Pointer to the time stamp to be set */ +) +{ + FRESULT res; + DIR dj; + BYTE *dir; + DEF_NAMEBUF; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 1); + if (res == FR_OK) { + INIT_BUF(dj); + res = follow_path(&dj, path); /* Follow the file path */ + FREE_BUF(); + if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; + if (res == FR_OK) { + dir = dj.dir; + if (!dir) { /* Root directory */ + res = FR_INVALID_NAME; + } else { /* File or sub-directory */ + ST_WORD(dir+DIR_WrtTime, fno->ftime); + ST_WORD(dir+DIR_WrtDate, fno->fdate); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + + LEAVE_FF(dj.fs, res); +} + + + + +/*-----------------------------------------------------------------------*/ +/* Rename File/Directory */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_rename ( + const TCHAR* path_old, /* Pointer to the object to be renamed */ + const TCHAR* path_new /* Pointer to the new name */ +) +{ + FRESULT res; + DIR djo, djn; + BYTE buf[21], *dir; + DWORD dw; + DEF_NAMEBUF; + + + /* Get logical drive number of the source object */ + res = find_volume(&djo.fs, &path_old, 1); + if (res == FR_OK) { + djn.fs = djo.fs; + INIT_BUF(djo); + res = follow_path(&djo, path_old); /* Check old object */ + if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT)) + res = FR_INVALID_NAME; +#if _FS_LOCK + if (res == FR_OK) res = chk_lock(&djo, 2); +#endif + if (res == FR_OK) { /* Old object is found */ + if (!djo.dir) { /* Is root dir? */ + res = FR_NO_FILE; + } else { + mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except name */ + mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */ + if (get_ldnumber(&path_new) >= 0) /* Snip drive number off and ignore it */ + res = follow_path(&djn, path_new); /* and check if new object is exist */ + else + res = FR_INVALID_DRIVE; + if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */ + if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */ +/* Start critical section that any interruption can cause a cross-link */ + res = dir_register(&djn); /* Register the new entry */ + if (res == FR_OK) { + dir = djn.dir; /* Copy object information except name */ + mem_cpy(dir+13, buf+2, 19); + dir[DIR_Attr] = buf[0] | AM_ARC; + djo.fs->wflag = 1; + if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */ + dw = clust2sect(djo.fs, ld_clust(djo.fs, dir)); + if (!dw) { + res = FR_INT_ERR; + } else { + res = move_window(djo.fs, dw); + dir = djo.fs->win+SZ_DIR; /* .. entry */ + if (res == FR_OK && dir[1] == '.') { + dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust; + st_clust(dir, dw); + djo.fs->wflag = 1; + } + } + } + if (res == FR_OK) { + res = dir_remove(&djo); /* Remove old entry */ + if (res == FR_OK) + res = sync_fs(djo.fs); + } + } +/* End critical section */ + } + } + } + FREE_BUF(); + } + + LEAVE_FF(djo.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _FS_MINIMIZE == 0 */ +#endif /* _FS_MINIMIZE <= 1 */ +#endif /* _FS_MINIMIZE <= 2 */ + + + +#if _USE_LABEL +/*-----------------------------------------------------------------------*/ +/* Get volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_getlabel ( + const TCHAR* path, /* Path name of the logical drive number */ + TCHAR* label, /* Pointer to a buffer to return the volume label */ + DWORD* vsn /* Pointer to a variable to return the volume serial number */ +) +{ + FRESULT res; + DIR dj; + UINT i, j; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &path, 0); + + /* Get volume label */ + if (res == FR_OK && label) { + dj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is exist */ +#if _USE_LFN && _LFN_UNICODE + WCHAR w; + i = j = 0; + do { + w = (i < 11) ? dj.dir[i++] : ' '; + if (IsDBCS1(w) && i < 11 && IsDBCS2(dj.dir[i])) + w = w << 8 | dj.dir[i++]; + label[j++] = ff_convert(w, 1); /* OEM -> Unicode */ + } while (j < 11); +#else + mem_cpy(label, dj.dir, 11); +#endif + j = 11; + do { + label[j] = 0; + if (!j) break; + } while (label[--j] == ' '); + } + if (res == FR_NO_FILE) { /* No label, return nul string */ + label[0] = 0; + res = FR_OK; + } + } + } + + /* Get volume serial number */ + if (res == FR_OK && vsn) { + res = move_window(dj.fs, dj.fs->volbase); + if (res == FR_OK) { + i = dj.fs->fs_type == FS_FAT32 ? BS_VolID32 : BS_VolID; + *vsn = LD_DWORD(&dj.fs->win[i]); + } + } + + LEAVE_FF(dj.fs, res); +} + + + +#if !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Set volume label */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_setlabel ( + const TCHAR* label /* Pointer to the volume label to set */ +) +{ + FRESULT res; + DIR dj; + BYTE vn[11]; + UINT i, j, sl; + WCHAR w; + DWORD tm; + + + /* Get logical drive number */ + res = find_volume(&dj.fs, &label, 1); + if (res) LEAVE_FF(dj.fs, res); + + /* Create a volume label in directory form */ + vn[0] = 0; + for (sl = 0; label[sl]; sl++) ; /* Get name length */ + for ( ; sl && label[sl-1] == ' '; sl--) ; /* Remove trailing spaces */ + if (sl) { /* Create volume label in directory form */ + i = j = 0; + do { +#if _USE_LFN && _LFN_UNICODE + w = ff_convert(ff_wtoupper(label[i++]), 0); +#else + w = (BYTE)label[i++]; + if (IsDBCS1(w)) + w = (j < 10 && i < sl && IsDBCS2(label[i])) ? w << 8 | (BYTE)label[i++] : 0; +#if _USE_LFN + w = ff_convert(ff_wtoupper(ff_convert(w, 1)), 0); +#else + if (IsLower(w)) w -= 0x20; /* To upper ASCII characters */ +#ifdef _EXCVT + if (w >= 0x80) w = ExCvt[w - 0x80]; /* To upper extended characters (SBCS cfg) */ +#else + if (!_DF1S && w >= 0x80) w = 0; /* Reject extended characters (ASCII cfg) */ +#endif +#endif +#endif + if (!w || chk_chr("\"*+,.:;<=>\?[]|\x7F", w) || j >= (UINT)((w >= 0x100) ? 10 : 11)) /* Reject invalid characters for volume label */ + LEAVE_FF(dj.fs, FR_INVALID_NAME); + if (w >= 0x100) vn[j++] = (BYTE)(w >> 8); + vn[j++] = (BYTE)w; + } while (i < sl); + while (j < 11) vn[j++] = ' '; + } + + /* Set volume label */ + dj.sclust = 0; /* Open root directory */ + res = dir_sdi(&dj, 0); + if (res == FR_OK) { + res = dir_read(&dj, 1); /* Get an entry with AM_VOL */ + if (res == FR_OK) { /* A volume label is found */ + if (vn[0]) { + mem_cpy(dj.dir, vn, 11); /* Change the volume label name */ + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + } else { + dj.dir[0] = DDE; /* Remove the volume label */ + } + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } else { /* No volume label is found or error */ + if (res == FR_NO_FILE) { + res = FR_OK; + if (vn[0]) { /* Create volume label as new */ + res = dir_alloc(&dj, 1); /* Allocate an entry for volume label */ + if (res == FR_OK) { + mem_set(dj.dir, 0, SZ_DIR); /* Set volume label */ + mem_cpy(dj.dir, vn, 11); + dj.dir[DIR_Attr] = AM_VOL; + tm = get_fattime(); + ST_DWORD(dj.dir+DIR_WrtTime, tm); + dj.fs->wflag = 1; + res = sync_fs(dj.fs); + } + } + } + } + } + + LEAVE_FF(dj.fs, res); +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_LABEL */ + + + +/*-----------------------------------------------------------------------*/ +/* Forward data to the stream directly (available on only tiny cfg) */ +/*-----------------------------------------------------------------------*/ +#if _USE_FORWARD && _FS_TINY + +FRESULT f_forward ( + FIL* fp, /* Pointer to the file object */ + UINT (*func)(const BYTE*,UINT), /* Pointer to the streaming function */ + UINT btf, /* Number of bytes to forward */ + UINT* bf /* Pointer to number of bytes forwarded */ +) +{ + FRESULT res; + DWORD remain, clst, sect; + UINT rcnt; + BYTE csect; + + + *bf = 0; /* Clear transfer byte counter */ + + res = validate(fp); /* Check validity of the object */ + if (res != FR_OK) LEAVE_FF(fp->fs, res); + if (fp->err) /* Check error */ + LEAVE_FF(fp->fs, (FRESULT)fp->err); + if (!(fp->flag & FA_READ)) /* Check access mode */ + LEAVE_FF(fp->fs, FR_DENIED); + + remain = fp->fsize - fp->fptr; + if (btf > remain) btf = (UINT)remain; /* Truncate btf by remaining bytes */ + + for ( ; btf && (*func)(0, 0); /* Repeat until all data transferred or stream becomes busy */ + fp->fptr += rcnt, *bf += rcnt, btf -= rcnt) { + csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */ + if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */ + if (!csect) { /* On the cluster boundary? */ + clst = (fp->fptr == 0) ? /* On the top of the file? */ + fp->sclust : get_fat(fp->fs, fp->clust); + if (clst <= 1) ABORT(fp->fs, FR_INT_ERR); + if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR); + fp->clust = clst; /* Update current cluster */ + } + } + sect = clust2sect(fp->fs, fp->clust); /* Get current data sector */ + if (!sect) ABORT(fp->fs, FR_INT_ERR); + sect += csect; + if (move_window(fp->fs, sect)) /* Move sector window */ + ABORT(fp->fs, FR_DISK_ERR); + fp->dsect = sect; + rcnt = SS(fp->fs) - (WORD)(fp->fptr % SS(fp->fs)); /* Forward data from sector window */ + if (rcnt > btf) rcnt = btf; + rcnt = (*func)(&fp->fs->win[(WORD)fp->fptr % SS(fp->fs)], rcnt); + if (!rcnt) ABORT(fp->fs, FR_INT_ERR); + } + + LEAVE_FF(fp->fs, FR_OK); +} +#endif /* _USE_FORWARD */ + + + +#if _USE_MKFS && !_FS_READONLY +/*-----------------------------------------------------------------------*/ +/* Create File System on the Drive */ +/*-----------------------------------------------------------------------*/ +#define N_ROOTDIR 512 /* Number of root directory entries for FAT12/16 */ +#define N_FATS 1 /* Number of FAT copies (1 or 2) */ + + +FRESULT f_mkfs ( + const TCHAR* path, /* Logical drive number */ + BYTE sfd, /* Partitioning rule 0:FDISK, 1:SFD */ + UINT au /* Allocation unit [bytes] */ +) +{ + static const WORD vst[] = { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 0}; + static const WORD cst[] = {32768, 16384, 8192, 4096, 2048, 16384, 8192, 4096, 2048, 1024, 512}; + int vol; + BYTE fmt, md, sys, *tbl, pdrv, part; + DWORD n_clst, vs, n, wsect; + UINT i; + DWORD b_vol, b_fat, b_dir, b_data; /* LBA */ + DWORD n_vol, n_rsv, n_fat, n_dir; /* Size */ + FATFS *fs; + DSTATUS stat; + + + /* Check mounted drive and clear work area */ + vol = get_ldnumber(&path); + if (vol < 0) return FR_INVALID_DRIVE; + if (sfd > 1) return FR_INVALID_PARAMETER; + if (au & (au - 1)) return FR_INVALID_PARAMETER; + fs = FatFs[vol]; + if (!fs) return FR_NOT_ENABLED; + fs->fs_type = 0; + pdrv = LD2PD(vol); /* Physical drive */ + part = LD2PT(vol); /* Partition (0:auto detect, 1-4:get from partition table)*/ + + /* Get disk statics */ + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; +#if _MAX_SS != _MIN_SS /* Get disk sector size */ + if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) > _MAX_SS || SS(fs) < _MIN_SS) + return FR_DISK_ERR; +#endif + if (_MULTI_PARTITION && part) { + /* Get partition information from partition table in the MBR */ + if (disk_read(pdrv, fs->win, 0, 1)) return FR_DISK_ERR; + if (LD_WORD(fs->win+BS_55AA) != 0xAA55) return FR_MKFS_ABORTED; + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + if (!tbl[4]) return FR_MKFS_ABORTED; /* No partition? */ + b_vol = LD_DWORD(tbl+8); /* Volume start sector */ + n_vol = LD_DWORD(tbl+12); /* Volume size */ + } else { + /* Create a partition in this function */ + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128) + return FR_DISK_ERR; + b_vol = (sfd) ? 0 : 63; /* Volume start sector */ + n_vol -= b_vol; /* Volume size */ + } + + if (!au) { /* AU auto selection */ + vs = n_vol / (2000 / (SS(fs) / 512)); + for (i = 0; vs < vst[i]; i++) ; + au = cst[i]; + } + au /= SS(fs); /* Number of sectors per cluster */ + if (au == 0) au = 1; + if (au > 128) au = 128; + + /* Pre-compute number of clusters and FAT sub-type */ + n_clst = n_vol / au; + fmt = FS_FAT12; + if (n_clst >= MIN_FAT16) fmt = FS_FAT16; + if (n_clst >= MIN_FAT32) fmt = FS_FAT32; + + /* Determine offset and size of FAT structure */ + if (fmt == FS_FAT32) { + n_fat = ((n_clst * 4) + 8 + SS(fs) - 1) / SS(fs); + n_rsv = 32; + n_dir = 0; + } else { + n_fat = (fmt == FS_FAT12) ? (n_clst * 3 + 1) / 2 + 3 : (n_clst * 2) + 4; + n_fat = (n_fat + SS(fs) - 1) / SS(fs); + n_rsv = 1; + n_dir = (DWORD)N_ROOTDIR * SZ_DIR / SS(fs); + } + b_fat = b_vol + n_rsv; /* FAT area start sector */ + b_dir = b_fat + n_fat * N_FATS; /* Directory area start sector */ + b_data = b_dir + n_dir; /* Data area start sector */ + if (n_vol < b_data + au - b_vol) return FR_MKFS_ABORTED; /* Too small volume */ + + /* Align data start sector to erase block boundary (for flash memory media) */ + if (disk_ioctl(pdrv, GET_BLOCK_SIZE, &n) != RES_OK || !n || n > 32768) n = 1; + n = (b_data + n - 1) & ~(n - 1); /* Next nearest erase block from current data start */ + n = (n - b_data) / N_FATS; + if (fmt == FS_FAT32) { /* FAT32: Move FAT offset */ + n_rsv += n; + b_fat += n; + } else { /* FAT12/16: Expand FAT size */ + n_fat += n; + } + + /* Determine number of clusters and final check of validity of the FAT sub-type */ + n_clst = (n_vol - n_rsv - n_fat * N_FATS - n_dir) / au; + if ( (fmt == FS_FAT16 && n_clst < MIN_FAT16) + || (fmt == FS_FAT32 && n_clst < MIN_FAT32)) + return FR_MKFS_ABORTED; + + /* Determine system ID in the partition table */ + if (fmt == FS_FAT32) { + sys = 0x0C; /* FAT32X */ + } else { + if (fmt == FS_FAT12 && n_vol < 0x10000) { + sys = 0x01; /* FAT12(<65536) */ + } else { + sys = (n_vol < 0x10000) ? 0x04 : 0x06; /* FAT16(<65536) : FAT12/16(>=65536) */ + } + } + + if (_MULTI_PARTITION && part) { + /* Update system ID in the partition table */ + tbl = &fs->win[MBR_Table + (part - 1) * SZ_PTE]; + tbl[4] = sys; + if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to teh MBR */ + return FR_DISK_ERR; + md = 0xF8; + } else { + if (sfd) { /* No partition table (SFD) */ + md = 0xF0; + } else { /* Create partition table (FDISK) */ + mem_set(fs->win, 0, SS(fs)); + tbl = fs->win+MBR_Table; /* Create partition table for single partition in the drive */ + tbl[1] = 1; /* Partition start head */ + tbl[2] = 1; /* Partition start sector */ + tbl[3] = 0; /* Partition start cylinder */ + tbl[4] = sys; /* System type */ + tbl[5] = 254; /* Partition end head */ + n = (b_vol + n_vol) / 63 / 255; + tbl[6] = (BYTE)(n >> 2 | 63); /* Partition end sector */ + tbl[7] = (BYTE)n; /* End cylinder */ + ST_DWORD(tbl+8, 63); /* Partition start in LBA */ + ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */ + ST_WORD(fs->win+BS_55AA, 0xAA55); /* MBR signature */ + if (disk_write(pdrv, fs->win, 0, 1)) /* Write it to the MBR */ + return FR_DISK_ERR; + md = 0xF8; + } + } + + /* Create BPB in the VBR */ + tbl = fs->win; /* Clear sector */ + mem_set(tbl, 0, SS(fs)); + mem_cpy(tbl, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code, OEM name */ + i = SS(fs); /* Sector size */ + ST_WORD(tbl+BPB_BytsPerSec, i); + tbl[BPB_SecPerClus] = (BYTE)au; /* Sectors per cluster */ + ST_WORD(tbl+BPB_RsvdSecCnt, n_rsv); /* Reserved sectors */ + tbl[BPB_NumFATs] = N_FATS; /* Number of FATs */ + i = (fmt == FS_FAT32) ? 0 : N_ROOTDIR; /* Number of root directory entries */ + ST_WORD(tbl+BPB_RootEntCnt, i); + if (n_vol < 0x10000) { /* Number of total sectors */ + ST_WORD(tbl+BPB_TotSec16, n_vol); + } else { + ST_DWORD(tbl+BPB_TotSec32, n_vol); + } + tbl[BPB_Media] = md; /* Media descriptor */ + ST_WORD(tbl+BPB_SecPerTrk, 63); /* Number of sectors per track */ + ST_WORD(tbl+BPB_NumHeads, 255); /* Number of heads */ + ST_DWORD(tbl+BPB_HiddSec, b_vol); /* Hidden sectors */ + n = get_fattime(); /* Use current time as VSN */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+BS_VolID32, n); /* VSN */ + ST_DWORD(tbl+BPB_FATSz32, n_fat); /* Number of sectors per FAT */ + ST_DWORD(tbl+BPB_RootClus, 2); /* Root directory start cluster (2) */ + ST_WORD(tbl+BPB_FSInfo, 1); /* FSINFO record offset (VBR+1) */ + ST_WORD(tbl+BPB_BkBootSec, 6); /* Backup boot record offset (VBR+6) */ + tbl[BS_DrvNum32] = 0x80; /* Drive number */ + tbl[BS_BootSig32] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab32, "NO NAME " "FAT32 ", 19); /* Volume label, FAT signature */ + } else { + ST_DWORD(tbl+BS_VolID, n); /* VSN */ + ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */ + tbl[BS_DrvNum] = 0x80; /* Drive number */ + tbl[BS_BootSig] = 0x29; /* Extended boot signature */ + mem_cpy(tbl+BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */ + } + ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */ + if (disk_write(pdrv, tbl, b_vol, 1)) /* Write it to the VBR sector */ + return FR_DISK_ERR; + if (fmt == FS_FAT32) /* Write backup VBR if needed (VBR+6) */ + disk_write(pdrv, tbl, b_vol + 6, 1); + + /* Initialize FAT area */ + wsect = b_fat; + for (i = 0; i < N_FATS; i++) { /* Initialize each FAT copy */ + mem_set(tbl, 0, SS(fs)); /* 1st sector of the FAT */ + n = md; /* Media descriptor byte */ + if (fmt != FS_FAT32) { + n |= (fmt == FS_FAT12) ? 0x00FFFF00 : 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT12/16) */ + } else { + n |= 0xFFFFFF00; + ST_DWORD(tbl+0, n); /* Reserve cluster #0-1 (FAT32) */ + ST_DWORD(tbl+4, 0xFFFFFFFF); + ST_DWORD(tbl+8, 0x0FFFFFFF); /* Reserve cluster #2 for root directory */ + } + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + mem_set(tbl, 0, SS(fs)); /* Fill following FAT entries with zero */ + for (n = 1; n < n_fat; n++) { /* This loop may take a time on FAT32 volume due to many single sector writes */ + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + } + } + + /* Initialize root directory */ + i = (fmt == FS_FAT32) ? au : (UINT)n_dir; + do { + if (disk_write(pdrv, tbl, wsect++, 1)) + return FR_DISK_ERR; + } while (--i); + +#if _USE_ERASE /* Erase data area if needed */ + { + DWORD eb[2]; + + eb[0] = wsect; eb[1] = wsect + (n_clst - ((fmt == FS_FAT32) ? 1 : 0)) * au - 1; + disk_ioctl(pdrv, CTRL_ERASE_SECTOR, eb); + } +#endif + + /* Create FSINFO if needed */ + if (fmt == FS_FAT32) { + ST_DWORD(tbl+FSI_LeadSig, 0x41615252); + ST_DWORD(tbl+FSI_StrucSig, 0x61417272); + ST_DWORD(tbl+FSI_Free_Count, n_clst - 1); /* Number of free clusters */ + ST_DWORD(tbl+FSI_Nxt_Free, 2); /* Last allocated cluster# */ + ST_WORD(tbl+BS_55AA, 0xAA55); + disk_write(pdrv, tbl, b_vol + 1, 1); /* Write original (VBR+1) */ + disk_write(pdrv, tbl, b_vol + 7, 1); /* Write backup (VBR+7) */ + } + + return (disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR; +} + + + +#if _MULTI_PARTITION +/*-----------------------------------------------------------------------*/ +/* Divide Physical Drive */ +/*-----------------------------------------------------------------------*/ + +FRESULT f_fdisk ( + BYTE pdrv, /* Physical drive number */ + const DWORD szt[], /* Pointer to the size table for each partitions */ + void* work /* Pointer to the working buffer */ +) +{ + UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl; + BYTE s_hd, e_hd, *p, *buf = (BYTE*)work; + DSTATUS stat; + DWORD sz_disk, sz_part, s_part; + + + stat = disk_initialize(pdrv); + if (stat & STA_NOINIT) return FR_NOT_READY; + if (stat & STA_PROTECT) return FR_WRITE_PROTECTED; + if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR; + + /* Determine CHS in the table regardless of the drive geometry */ + for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ; + if (n == 256) n--; + e_hd = n - 1; + sz_cyl = 63 * n; + tot_cyl = sz_disk / sz_cyl; + + /* Create partition table */ + mem_set(buf, 0, _MAX_SS); + p = buf + MBR_Table; b_cyl = 0; + for (i = 0; i < 4; i++, p += SZ_PTE) { + p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl; + if (!p_cyl) continue; + s_part = (DWORD)sz_cyl * b_cyl; + sz_part = (DWORD)sz_cyl * p_cyl; + if (i == 0) { /* Exclude first track of cylinder 0 */ + s_hd = 1; + s_part += 63; sz_part -= 63; + } else { + s_hd = 0; + } + e_cyl = b_cyl + p_cyl - 1; + if (e_cyl >= tot_cyl) return FR_INVALID_PARAMETER; + + /* Set partition table */ + p[1] = s_hd; /* Start head */ + p[2] = (BYTE)((b_cyl >> 2) + 1); /* Start sector */ + p[3] = (BYTE)b_cyl; /* Start cylinder */ + p[4] = 0x06; /* System type (temporary setting) */ + p[5] = e_hd; /* End head */ + p[6] = (BYTE)((e_cyl >> 2) + 63); /* End sector */ + p[7] = (BYTE)e_cyl; /* End cylinder */ + ST_DWORD(p + 8, s_part); /* Start sector in LBA */ + ST_DWORD(p + 12, sz_part); /* Partition size */ + + /* Next partition */ + b_cyl += p_cyl; + } + ST_WORD(p, 0xAA55); + + /* Write it to the MBR */ + return (disk_write(pdrv, buf, 0, 1) || disk_ioctl(pdrv, CTRL_SYNC, 0)) ? FR_DISK_ERR : FR_OK; +} + + +#endif /* _MULTI_PARTITION */ +#endif /* _USE_MKFS && !_FS_READONLY */ + + + + +#if _USE_STRFUNC +/*-----------------------------------------------------------------------*/ +/* Get a string from the file */ +/*-----------------------------------------------------------------------*/ + +TCHAR* f_gets ( + TCHAR* buff, /* Pointer to the string buffer to read */ + int len, /* Size of string buffer (characters) */ + FIL* fp /* Pointer to the file object */ +) +{ + int n = 0; + TCHAR c, *p = buff; + BYTE s[2]; + UINT rc; + + + while (n < len - 1) { /* Read characters until buffer gets filled */ +#if _USE_LFN && _LFN_UNICODE +#if _STRF_ENCODE == 3 /* Read a character in UTF-8 */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; + if (c >= 0x80) { + if (c < 0xC0) continue; /* Skip stray trailer */ + if (c < 0xE0) { /* Two-byte sequence */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = (c & 0x1F) << 6 | (s[0] & 0x3F); + if (c < 0x80) c = '?'; + } else { + if (c < 0xF0) { /* Three-byte sequence */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = c << 12 | (s[0] & 0x3F) << 6 | (s[1] & 0x3F); + if (c < 0x800) c = '?'; + } else { /* Reject four-byte sequence */ + c = '?'; + } + } + } +#elif _STRF_ENCODE == 2 /* Read a character in UTF-16BE */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = s[1] + (s[0] << 8); +#elif _STRF_ENCODE == 1 /* Read a character in UTF-16LE */ + f_read(fp, s, 2, &rc); + if (rc != 2) break; + c = s[0] + (s[1] << 8); +#else /* Read a character in ANSI/OEM */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; + if (IsDBCS1(c)) { + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = (c << 8) + s[0]; + } + c = ff_convert(c, 1); /* OEM -> Unicode */ + if (!c) c = '?'; +#endif +#else /* Read a character without conversion */ + f_read(fp, s, 1, &rc); + if (rc != 1) break; + c = s[0]; +#endif + if (_USE_STRFUNC == 2 && c == '\r') continue; /* Strip '\r' */ + *p++ = c; + n++; + if (c == '\n') break; /* Break on EOL */ + } + *p = 0; + return n ? buff : 0; /* When no data read (eof or error), return with error. */ +} + + + +#if !_FS_READONLY +#include +/*-----------------------------------------------------------------------*/ +/* Put a character to the file */ +/*-----------------------------------------------------------------------*/ + +typedef struct { + FIL* fp; + int idx, nchr; + BYTE buf[64]; +} putbuff; + + +static +void putc_bfd ( + putbuff* pb, + TCHAR c +) +{ + UINT bw; + int i; + + + if (_USE_STRFUNC == 2 && c == '\n') /* LF -> CRLF conversion */ + putc_bfd(pb, '\r'); + + i = pb->idx; /* Buffer write index (-1:error) */ + if (i < 0) return; + +#if _USE_LFN && _LFN_UNICODE +#if _STRF_ENCODE == 3 /* Write a character in UTF-8 */ + if (c < 0x80) { /* 7-bit */ + pb->buf[i++] = (BYTE)c; + } else { + if (c < 0x800) { /* 11-bit */ + pb->buf[i++] = (BYTE)(0xC0 | c >> 6); + } else { /* 16-bit */ + pb->buf[i++] = (BYTE)(0xE0 | c >> 12); + pb->buf[i++] = (BYTE)(0x80 | (c >> 6 & 0x3F)); + } + pb->buf[i++] = (BYTE)(0x80 | (c & 0x3F)); + } +#elif _STRF_ENCODE == 2 /* Write a character in UTF-16BE */ + pb->buf[i++] = (BYTE)(c >> 8); + pb->buf[i++] = (BYTE)c; +#elif _STRF_ENCODE == 1 /* Write a character in UTF-16LE */ + pb->buf[i++] = (BYTE)c; + pb->buf[i++] = (BYTE)(c >> 8); +#else /* Write a character in ANSI/OEM */ + c = ff_convert(c, 0); /* Unicode -> OEM */ + if (!c) c = '?'; + if (c >= 0x100) + pb->buf[i++] = (BYTE)(c >> 8); + pb->buf[i++] = (BYTE)c; +#endif +#else /* Write a character without conversion */ + pb->buf[i++] = (BYTE)c; +#endif + + if (i >= (int)(sizeof pb->buf) - 3) { /* Write buffered characters to the file */ + f_write(pb->fp, pb->buf, (UINT)i, &bw); + i = (bw == (UINT)i) ? 0 : -1; + } + pb->idx = i; + pb->nchr++; +} + + + +int f_putc ( + TCHAR c, /* A character to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + UINT nw; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + putc_bfd(&pb, c); /* Put a character */ + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_puts ( + const TCHAR* str, /* Pointer to the string to be output */ + FIL* fp /* Pointer to the file object */ +) +{ + putbuff pb; + UINT nw; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + while (*str) /* Put the string */ + putc_bfd(&pb, *str++); + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + + + + +/*-----------------------------------------------------------------------*/ +/* Put a formatted string to the file */ +/*-----------------------------------------------------------------------*/ + +int f_printf ( + FIL* fp, /* Pointer to the file object */ + const TCHAR* fmt, /* Pointer to the format string */ + ... /* Optional arguments... */ +) +{ + va_list arp; + BYTE f, r; + UINT nw, i, j, w; + DWORD v; + TCHAR c, d, s[16], *p; + putbuff pb; + + + pb.fp = fp; /* Initialize output buffer */ + pb.nchr = pb.idx = 0; + + va_start(arp, fmt); + + for (;;) { + c = *fmt++; + if (c == 0) break; /* End of string */ + if (c != '%') { /* Non escape character */ + putc_bfd(&pb, c); + continue; + } + w = f = 0; + c = *fmt++; + if (c == '0') { /* Flag: '0' padding */ + f = 1; c = *fmt++; + } else { + if (c == '-') { /* Flag: left justified */ + f = 2; c = *fmt++; + } + } + while (IsDigit(c)) { /* Precision */ + w = w * 10 + c - '0'; + c = *fmt++; + } + if (c == 'l' || c == 'L') { /* Prefix: Size is long int */ + f |= 4; c = *fmt++; + } + if (!c) break; + d = c; + if (IsLower(d)) d -= 0x20; + switch (d) { /* Type is... */ + case 'S' : /* String */ + p = va_arg(arp, TCHAR*); + for (j = 0; p[j]; j++) ; + if (!(f & 2)) { + while (j++ < w) putc_bfd(&pb, ' '); + } + while (*p) putc_bfd(&pb, *p++); + while (j++ < w) putc_bfd(&pb, ' '); + continue; + case 'C' : /* Character */ + putc_bfd(&pb, (TCHAR)va_arg(arp, int)); continue; + case 'B' : /* Binary */ + r = 2; break; + case 'O' : /* Octal */ + r = 8; break; + case 'D' : /* Signed decimal */ + case 'U' : /* Unsigned decimal */ + r = 10; break; + case 'X' : /* Hexdecimal */ + r = 16; break; + default: /* Unknown type (pass-through) */ + putc_bfd(&pb, c); continue; + } + + /* Get an argument and put it in numeral */ + v = (f & 4) ? (DWORD)va_arg(arp, long) : ((d == 'D') ? (DWORD)(long)va_arg(arp, int) : (DWORD)va_arg(arp, unsigned int)); + if (d == 'D' && (v & 0x80000000)) { + v = 0 - v; + f |= 8; + } + i = 0; + do { + d = (TCHAR)(v % r); v /= r; + if (d > 9) d += (c == 'x') ? 0x27 : 0x07; + s[i++] = d + '0'; + } while (v && i < sizeof s / sizeof s[0]); + if (f & 8) s[i++] = '-'; + j = i; d = (f & 1) ? '0' : ' '; + while (!(f & 2) && j++ < w) putc_bfd(&pb, d); + do putc_bfd(&pb, s[--i]); while (i); + while (j++ < w) putc_bfd(&pb, d); + } + + va_end(arp); + + if ( pb.idx >= 0 /* Flush buffered characters to the file */ + && f_write(pb.fp, pb.buf, (UINT)pb.idx, &nw) == FR_OK + && (UINT)pb.idx == nw) return pb.nchr; + return EOF; +} + +#endif /* !_FS_READONLY */ +#endif /* _USE_STRFUNC */ diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc932.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc932.c new file mode 100644 index 0000000..9a8d035 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc932.c @@ -0,0 +1,3829 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */ +/* CP932 (Japanese Shift-JIS) */ +/*------------------------------------------------------------------------*/ + +#include "ff.h" + +#define _TINY_TABLE 0 + +#if !_USE_LFN || _CODE_PAGE != 932 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2sjis[] = { +/* Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, Unicode - Sjis, */ + 0x00A7, 0x8198, 0x00A8, 0x814E, 0x00B0, 0x818B, 0x00B1, 0x817D, + 0x00B4, 0x814C, 0x00B6, 0x81F7, 0x00D7, 0x817E, 0x00F7, 0x8180, + 0x0391, 0x839F, 0x0392, 0x83A0, 0x0393, 0x83A1, 0x0394, 0x83A2, + 0x0395, 0x83A3, 0x0396, 0x83A4, 0x0397, 0x83A5, 0x0398, 0x83A6, + 0x0399, 0x83A7, 0x039A, 0x83A8, 0x039B, 0x83A9, 0x039C, 0x83AA, + 0x039D, 0x83AB, 0x039E, 0x83AC, 0x039F, 0x83AD, 0x03A0, 0x83AE, + 0x03A1, 0x83AF, 0x03A3, 0x83B0, 0x03A4, 0x83B1, 0x03A5, 0x83B2, + 0x03A6, 0x83B3, 0x03A7, 0x83B4, 0x03A8, 0x83B5, 0x03A9, 0x83B6, + 0x03B1, 0x83BF, 0x03B2, 0x83C0, 0x03B3, 0x83C1, 0x03B4, 0x83C2, + 0x03B5, 0x83C3, 0x03B6, 0x83C4, 0x03B7, 0x83C5, 0x03B8, 0x83C6, + 0x03B9, 0x83C7, 0x03BA, 0x83C8, 0x03BB, 0x83C9, 0x03BC, 0x83CA, + 0x03BD, 0x83CB, 0x03BE, 0x83CC, 0x03BF, 0x83CD, 0x03C0, 0x83CE, + 0x03C1, 0x83CF, 0x03C3, 0x83D0, 0x03C4, 0x83D1, 0x03C5, 0x83D2, + 0x03C6, 0x83D3, 0x03C7, 0x83D4, 0x03C8, 0x83D5, 0x03C9, 0x83D6, + 0x0401, 0x8446, 0x0410, 0x8440, 0x0411, 0x8441, 0x0412, 0x8442, + 0x0413, 0x8443, 0x0414, 0x8444, 0x0415, 0x8445, 0x0416, 0x8447, + 0x0417, 0x8448, 0x0418, 0x8449, 0x0419, 0x844A, 0x041A, 0x844B, + 0x041B, 0x844C, 0x041C, 0x844D, 0x041D, 0x844E, 0x041E, 0x844F, + 0x041F, 0x8450, 0x0420, 0x8451, 0x0421, 0x8452, 0x0422, 0x8453, + 0x0423, 0x8454, 0x0424, 0x8455, 0x0425, 0x8456, 0x0426, 0x8457, + 0x0427, 0x8458, 0x0428, 0x8459, 0x0429, 0x845A, 0x042A, 0x845B, + 0x042B, 0x845C, 0x042C, 0x845D, 0x042D, 0x845E, 0x042E, 0x845F, + 0x042F, 0x8460, 0x0430, 0x8470, 0x0431, 0x8471, 0x0432, 0x8472, + 0x0433, 0x8473, 0x0434, 0x8474, 0x0435, 0x8475, 0x0436, 0x8477, + 0x0437, 0x8478, 0x0438, 0x8479, 0x0439, 0x847A, 0x043A, 0x847B, + 0x043B, 0x847C, 0x043C, 0x847D, 0x043D, 0x847E, 0x043E, 0x8480, + 0x043F, 0x8481, 0x0440, 0x8482, 0x0441, 0x8483, 0x0442, 0x8484, + 0x0443, 0x8485, 0x0444, 0x8486, 0x0445, 0x8487, 0x0446, 0x8488, + 0x0447, 0x8489, 0x0448, 0x848A, 0x0449, 0x848B, 0x044A, 0x848C, + 0x044B, 0x848D, 0x044C, 0x848E, 0x044D, 0x848F, 0x044E, 0x8490, + 0x044F, 0x8491, 0x0451, 0x8476, 0x2010, 0x815D, 0x2015, 0x815C, + 0x2018, 0x8165, 0x2019, 0x8166, 0x201C, 0x8167, 0x201D, 0x8168, + 0x2020, 0x81F5, 0x2021, 0x81F6, 0x2025, 0x8164, 0x2026, 0x8163, + 0x2030, 0x81F1, 0x2032, 0x818C, 0x2033, 0x818D, 0x203B, 0x81A6, + 0x2103, 0x818E, 0x2116, 0x8782, 0x2121, 0x8784, 0x212B, 0x81F0, + 0x2160, 0x8754, 0x2161, 0x8755, 0x2162, 0x8756, 0x2163, 0x8757, + 0x2164, 0x8758, 0x2165, 0x8759, 0x2166, 0x875A, 0x2167, 0x875B, + 0x2168, 0x875C, 0x2169, 0x875D, 0x2170, 0xFA40, 0x2171, 0xFA41, + 0x2172, 0xFA42, 0x2173, 0xFA43, 0x2174, 0xFA44, 0x2175, 0xFA45, + 0x2176, 0xFA46, 0x2177, 0xFA47, 0x2178, 0xFA48, 0x2179, 0xFA49, + 0x2190, 0x81A9, 0x2191, 0x81AA, 0x2192, 0x81A8, 0x2193, 0x81AB, + 0x21D2, 0x81CB, 0x21D4, 0x81CC, 0x2200, 0x81CD, 0x2202, 0x81DD, + 0x2203, 0x81CE, 0x2207, 0x81DE, 0x2208, 0x81B8, 0x220B, 0x81B9, + 0x2211, 0x8794, 0x221A, 0x81E3, 0x221D, 0x81E5, 0x221E, 0x8187, + 0x221F, 0x8798, 0x2220, 0x81DA, 0x2225, 0x8161, 0x2227, 0x81C8, + 0x2228, 0x81C9, 0x2229, 0x81BF, 0x222A, 0x81BE, 0x222B, 0x81E7, + 0x222C, 0x81E8, 0x222E, 0x8793, 0x2234, 0x8188, 0x2235, 0x81E6, + 0x223D, 0x81E4, 0x2252, 0x81E0, 0x2260, 0x8182, 0x2261, 0x81DF, + 0x2266, 0x8185, 0x2267, 0x8186, 0x226A, 0x81E1, 0x226B, 0x81E2, + 0x2282, 0x81BC, 0x2283, 0x81BD, 0x2286, 0x81BA, 0x2287, 0x81BB, + 0x22A5, 0x81DB, 0x22BF, 0x8799, 0x2312, 0x81DC, 0x2460, 0x8740, + 0x2461, 0x8741, 0x2462, 0x8742, 0x2463, 0x8743, 0x2464, 0x8744, + 0x2465, 0x8745, 0x2466, 0x8746, 0x2467, 0x8747, 0x2468, 0x8748, + 0x2469, 0x8749, 0x246A, 0x874A, 0x246B, 0x874B, 0x246C, 0x874C, + 0x246D, 0x874D, 0x246E, 0x874E, 0x246F, 0x874F, 0x2470, 0x8750, + 0x2471, 0x8751, 0x2472, 0x8752, 0x2473, 0x8753, 0x2500, 0x849F, + 0x2501, 0x84AA, 0x2502, 0x84A0, 0x2503, 0x84AB, 0x250C, 0x84A1, + 0x250F, 0x84AC, 0x2510, 0x84A2, 0x2513, 0x84AD, 0x2514, 0x84A4, + 0x2517, 0x84AF, 0x2518, 0x84A3, 0x251B, 0x84AE, 0x251C, 0x84A5, + 0x251D, 0x84BA, 0x2520, 0x84B5, 0x2523, 0x84B0, 0x2524, 0x84A7, + 0x2525, 0x84BC, 0x2528, 0x84B7, 0x252B, 0x84B2, 0x252C, 0x84A6, + 0x252F, 0x84B6, 0x2530, 0x84BB, 0x2533, 0x84B1, 0x2534, 0x84A8, + 0x2537, 0x84B8, 0x2538, 0x84BD, 0x253B, 0x84B3, 0x253C, 0x84A9, + 0x253F, 0x84B9, 0x2542, 0x84BE, 0x254B, 0x84B4, 0x25A0, 0x81A1, + 0x25A1, 0x81A0, 0x25B2, 0x81A3, 0x25B3, 0x81A2, 0x25BC, 0x81A5, + 0x25BD, 0x81A4, 0x25C6, 0x819F, 0x25C7, 0x819E, 0x25CB, 0x819B, + 0x25CE, 0x819D, 0x25CF, 0x819C, 0x25EF, 0x81FC, 0x2605, 0x819A, + 0x2606, 0x8199, 0x2640, 0x818A, 0x2642, 0x8189, 0x266A, 0x81F4, + 0x266D, 0x81F3, 0x266F, 0x81F2, 0x3000, 0x8140, 0x3001, 0x8141, + 0x3002, 0x8142, 0x3003, 0x8156, 0x3005, 0x8158, 0x3006, 0x8159, + 0x3007, 0x815A, 0x3008, 0x8171, 0x3009, 0x8172, 0x300A, 0x8173, + 0x300B, 0x8174, 0x300C, 0x8175, 0x300D, 0x8176, 0x300E, 0x8177, + 0x300F, 0x8178, 0x3010, 0x8179, 0x3011, 0x817A, 0x3012, 0x81A7, + 0x3013, 0x81AC, 0x3014, 0x816B, 0x3015, 0x816C, 0x301D, 0x8780, + 0x301F, 0x8781, 0x3041, 0x829F, 0x3042, 0x82A0, 0x3043, 0x82A1, + 0x3044, 0x82A2, 0x3045, 0x82A3, 0x3046, 0x82A4, 0x3047, 0x82A5, + 0x3048, 0x82A6, 0x3049, 0x82A7, 0x304A, 0x82A8, 0x304B, 0x82A9, + 0x304C, 0x82AA, 0x304D, 0x82AB, 0x304E, 0x82AC, 0x304F, 0x82AD, + 0x3050, 0x82AE, 0x3051, 0x82AF, 0x3052, 0x82B0, 0x3053, 0x82B1, + 0x3054, 0x82B2, 0x3055, 0x82B3, 0x3056, 0x82B4, 0x3057, 0x82B5, + 0x3058, 0x82B6, 0x3059, 0x82B7, 0x305A, 0x82B8, 0x305B, 0x82B9, + 0x305C, 0x82BA, 0x305D, 0x82BB, 0x305E, 0x82BC, 0x305F, 0x82BD, + 0x3060, 0x82BE, 0x3061, 0x82BF, 0x3062, 0x82C0, 0x3063, 0x82C1, + 0x3064, 0x82C2, 0x3065, 0x82C3, 0x3066, 0x82C4, 0x3067, 0x82C5, + 0x3068, 0x82C6, 0x3069, 0x82C7, 0x306A, 0x82C8, 0x306B, 0x82C9, + 0x306C, 0x82CA, 0x306D, 0x82CB, 0x306E, 0x82CC, 0x306F, 0x82CD, + 0x3070, 0x82CE, 0x3071, 0x82CF, 0x3072, 0x82D0, 0x3073, 0x82D1, + 0x3074, 0x82D2, 0x3075, 0x82D3, 0x3076, 0x82D4, 0x3077, 0x82D5, + 0x3078, 0x82D6, 0x3079, 0x82D7, 0x307A, 0x82D8, 0x307B, 0x82D9, + 0x307C, 0x82DA, 0x307D, 0x82DB, 0x307E, 0x82DC, 0x307F, 0x82DD, + 0x3080, 0x82DE, 0x3081, 0x82DF, 0x3082, 0x82E0, 0x3083, 0x82E1, + 0x3084, 0x82E2, 0x3085, 0x82E3, 0x3086, 0x82E4, 0x3087, 0x82E5, + 0x3088, 0x82E6, 0x3089, 0x82E7, 0x308A, 0x82E8, 0x308B, 0x82E9, + 0x308C, 0x82EA, 0x308D, 0x82EB, 0x308E, 0x82EC, 0x308F, 0x82ED, + 0x3090, 0x82EE, 0x3091, 0x82EF, 0x3092, 0x82F0, 0x3093, 0x82F1, + 0x309B, 0x814A, 0x309C, 0x814B, 0x309D, 0x8154, 0x309E, 0x8155, + 0x30A1, 0x8340, 0x30A2, 0x8341, 0x30A3, 0x8342, 0x30A4, 0x8343, + 0x30A5, 0x8344, 0x30A6, 0x8345, 0x30A7, 0x8346, 0x30A8, 0x8347, + 0x30A9, 0x8348, 0x30AA, 0x8349, 0x30AB, 0x834A, 0x30AC, 0x834B, + 0x30AD, 0x834C, 0x30AE, 0x834D, 0x30AF, 0x834E, 0x30B0, 0x834F, + 0x30B1, 0x8350, 0x30B2, 0x8351, 0x30B3, 0x8352, 0x30B4, 0x8353, + 0x30B5, 0x8354, 0x30B6, 0x8355, 0x30B7, 0x8356, 0x30B8, 0x8357, + 0x30B9, 0x8358, 0x30BA, 0x8359, 0x30BB, 0x835A, 0x30BC, 0x835B, + 0x30BD, 0x835C, 0x30BE, 0x835D, 0x30BF, 0x835E, 0x30C0, 0x835F, + 0x30C1, 0x8360, 0x30C2, 0x8361, 0x30C3, 0x8362, 0x30C4, 0x8363, + 0x30C5, 0x8364, 0x30C6, 0x8365, 0x30C7, 0x8366, 0x30C8, 0x8367, + 0x30C9, 0x8368, 0x30CA, 0x8369, 0x30CB, 0x836A, 0x30CC, 0x836B, + 0x30CD, 0x836C, 0x30CE, 0x836D, 0x30CF, 0x836E, 0x30D0, 0x836F, + 0x30D1, 0x8370, 0x30D2, 0x8371, 0x30D3, 0x8372, 0x30D4, 0x8373, + 0x30D5, 0x8374, 0x30D6, 0x8375, 0x30D7, 0x8376, 0x30D8, 0x8377, + 0x30D9, 0x8378, 0x30DA, 0x8379, 0x30DB, 0x837A, 0x30DC, 0x837B, + 0x30DD, 0x837C, 0x30DE, 0x837D, 0x30DF, 0x837E, 0x30E0, 0x8380, + 0x30E1, 0x8381, 0x30E2, 0x8382, 0x30E3, 0x8383, 0x30E4, 0x8384, + 0x30E5, 0x8385, 0x30E6, 0x8386, 0x30E7, 0x8387, 0x30E8, 0x8388, + 0x30E9, 0x8389, 0x30EA, 0x838A, 0x30EB, 0x838B, 0x30EC, 0x838C, + 0x30ED, 0x838D, 0x30EE, 0x838E, 0x30EF, 0x838F, 0x30F0, 0x8390, + 0x30F1, 0x8391, 0x30F2, 0x8392, 0x30F3, 0x8393, 0x30F4, 0x8394, + 0x30F5, 0x8395, 0x30F6, 0x8396, 0x30FB, 0x8145, 0x30FC, 0x815B, + 0x30FD, 0x8152, 0x30FE, 0x8153, 0x3231, 0x878A, 0x3232, 0x878B, + 0x3239, 0x878C, 0x32A4, 0x8785, 0x32A5, 0x8786, 0x32A6, 0x8787, + 0x32A7, 0x8788, 0x32A8, 0x8789, 0x3303, 0x8765, 0x330D, 0x8769, + 0x3314, 0x8760, 0x3318, 0x8763, 0x3322, 0x8761, 0x3323, 0x876B, + 0x3326, 0x876A, 0x3327, 0x8764, 0x332B, 0x876C, 0x3336, 0x8766, + 0x333B, 0x876E, 0x3349, 0x875F, 0x334A, 0x876D, 0x334D, 0x8762, + 0x3351, 0x8767, 0x3357, 0x8768, 0x337B, 0x877E, 0x337C, 0x878F, + 0x337D, 0x878E, 0x337E, 0x878D, 0x338E, 0x8772, 0x338F, 0x8773, + 0x339C, 0x876F, 0x339D, 0x8770, 0x339E, 0x8771, 0x33A1, 0x8775, + 0x33C4, 0x8774, 0x33CD, 0x8783, 0x4E00, 0x88EA, 0x4E01, 0x929A, + 0x4E03, 0x8EB5, 0x4E07, 0x969C, 0x4E08, 0x8FE4, 0x4E09, 0x8E4F, + 0x4E0A, 0x8FE3, 0x4E0B, 0x89BA, 0x4E0D, 0x9573, 0x4E0E, 0x975E, + 0x4E10, 0x98A0, 0x4E11, 0x894E, 0x4E14, 0x8A8E, 0x4E15, 0x98A1, + 0x4E16, 0x90A2, 0x4E17, 0x99C0, 0x4E18, 0x8B75, 0x4E19, 0x95B8, + 0x4E1E, 0x8FE5, 0x4E21, 0x97BC, 0x4E26, 0x95C0, 0x4E28, 0xFA68, + 0x4E2A, 0x98A2, 0x4E2D, 0x9286, 0x4E31, 0x98A3, 0x4E32, 0x8BF8, + 0x4E36, 0x98A4, 0x4E38, 0x8ADB, 0x4E39, 0x924F, 0x4E3B, 0x8EE5, + 0x4E3C, 0x98A5, 0x4E3F, 0x98A6, 0x4E42, 0x98A7, 0x4E43, 0x9454, + 0x4E45, 0x8B76, 0x4E4B, 0x9456, 0x4E4D, 0x93E1, 0x4E4E, 0x8CC1, + 0x4E4F, 0x9652, 0x4E55, 0xE568, 0x4E56, 0x98A8, 0x4E57, 0x8FE6, + 0x4E58, 0x98A9, 0x4E59, 0x89B3, 0x4E5D, 0x8BE3, 0x4E5E, 0x8CEE, + 0x4E5F, 0x96E7, 0x4E62, 0x9BA4, 0x4E71, 0x9790, 0x4E73, 0x93FB, + 0x4E7E, 0x8AA3, 0x4E80, 0x8B54, 0x4E82, 0x98AA, 0x4E85, 0x98AB, + 0x4E86, 0x97B9, 0x4E88, 0x975C, 0x4E89, 0x9188, 0x4E8A, 0x98AD, + 0x4E8B, 0x8E96, 0x4E8C, 0x93F1, 0x4E8E, 0x98B0, 0x4E91, 0x895D, + 0x4E92, 0x8CDD, 0x4E94, 0x8CDC, 0x4E95, 0x88E4, 0x4E98, 0x986A, + 0x4E99, 0x9869, 0x4E9B, 0x8DB1, 0x4E9C, 0x889F, 0x4E9E, 0x98B1, + 0x4E9F, 0x98B2, 0x4EA0, 0x98B3, 0x4EA1, 0x9653, 0x4EA2, 0x98B4, + 0x4EA4, 0x8CF0, 0x4EA5, 0x88E5, 0x4EA6, 0x9692, 0x4EA8, 0x8B9C, + 0x4EAB, 0x8B9D, 0x4EAC, 0x8B9E, 0x4EAD, 0x92E0, 0x4EAE, 0x97BA, + 0x4EB0, 0x98B5, 0x4EB3, 0x98B6, 0x4EB6, 0x98B7, 0x4EBA, 0x906C, + 0x4EC0, 0x8F59, 0x4EC1, 0x906D, 0x4EC2, 0x98BC, 0x4EC4, 0x98BA, + 0x4EC6, 0x98BB, 0x4EC7, 0x8B77, 0x4ECA, 0x8DA1, 0x4ECB, 0x89EE, + 0x4ECD, 0x98B9, 0x4ECE, 0x98B8, 0x4ECF, 0x95A7, 0x4ED4, 0x8E65, + 0x4ED5, 0x8E64, 0x4ED6, 0x91BC, 0x4ED7, 0x98BD, 0x4ED8, 0x9574, + 0x4ED9, 0x90E5, 0x4EDD, 0x8157, 0x4EDE, 0x98BE, 0x4EDF, 0x98C0, + 0x4EE1, 0xFA69, 0x4EE3, 0x91E3, 0x4EE4, 0x97DF, 0x4EE5, 0x88C8, + 0x4EED, 0x98BF, 0x4EEE, 0x89BC, 0x4EF0, 0x8BC2, 0x4EF2, 0x9287, + 0x4EF6, 0x8C8F, 0x4EF7, 0x98C1, 0x4EFB, 0x9443, 0x4EFC, 0xFA6A, + 0x4F00, 0xFA6B, 0x4F01, 0x8AE9, 0x4F03, 0xFA6C, 0x4F09, 0x98C2, + 0x4F0A, 0x88C9, 0x4F0D, 0x8CDE, 0x4F0E, 0x8AEA, 0x4F0F, 0x959A, + 0x4F10, 0x94B0, 0x4F11, 0x8B78, 0x4F1A, 0x89EF, 0x4F1C, 0x98E5, + 0x4F1D, 0x9360, 0x4F2F, 0x948C, 0x4F30, 0x98C4, 0x4F34, 0x94BA, + 0x4F36, 0x97E0, 0x4F38, 0x904C, 0x4F39, 0xFA6D, 0x4F3A, 0x8E66, + 0x4F3C, 0x8E97, 0x4F3D, 0x89BE, 0x4F43, 0x92CF, 0x4F46, 0x9241, + 0x4F47, 0x98C8, 0x4F4D, 0x88CA, 0x4F4E, 0x92E1, 0x4F4F, 0x8F5A, + 0x4F50, 0x8DB2, 0x4F51, 0x9743, 0x4F53, 0x91CC, 0x4F55, 0x89BD, + 0x4F56, 0xFA6E, 0x4F57, 0x98C7, 0x4F59, 0x975D, 0x4F5A, 0x98C3, + 0x4F5B, 0x98C5, 0x4F5C, 0x8DEC, 0x4F5D, 0x98C6, 0x4F5E, 0x9B43, + 0x4F69, 0x98CE, 0x4F6F, 0x98D1, 0x4F70, 0x98CF, 0x4F73, 0x89C0, + 0x4F75, 0x95B9, 0x4F76, 0x98C9, 0x4F7B, 0x98CD, 0x4F7C, 0x8CF1, + 0x4F7F, 0x8E67, 0x4F83, 0x8AA4, 0x4F86, 0x98D2, 0x4F88, 0x98CA, + 0x4F8A, 0xFA70, 0x4F8B, 0x97E1, 0x4F8D, 0x8E98, 0x4F8F, 0x98CB, + 0x4F91, 0x98D0, 0x4F92, 0xFA6F, 0x4F94, 0xFA72, 0x4F96, 0x98D3, + 0x4F98, 0x98CC, 0x4F9A, 0xFA71, 0x4F9B, 0x8B9F, 0x4F9D, 0x88CB, + 0x4FA0, 0x8BA0, 0x4FA1, 0x89BF, 0x4FAB, 0x9B44, 0x4FAD, 0x9699, + 0x4FAE, 0x958E, 0x4FAF, 0x8CF2, 0x4FB5, 0x904E, 0x4FB6, 0x97B5, + 0x4FBF, 0x95D6, 0x4FC2, 0x8C57, 0x4FC3, 0x91A3, 0x4FC4, 0x89E2, + 0x4FC9, 0xFA61, 0x4FCA, 0x8F72, 0x4FCD, 0xFA73, 0x4FCE, 0x98D7, + 0x4FD0, 0x98DC, 0x4FD1, 0x98DA, 0x4FD4, 0x98D5, 0x4FD7, 0x91AD, + 0x4FD8, 0x98D8, 0x4FDA, 0x98DB, 0x4FDB, 0x98D9, 0x4FDD, 0x95DB, + 0x4FDF, 0x98D6, 0x4FE1, 0x904D, 0x4FE3, 0x9693, 0x4FE4, 0x98DD, + 0x4FE5, 0x98DE, 0x4FEE, 0x8F43, 0x4FEF, 0x98EB, 0x4FF3, 0x946F, + 0x4FF5, 0x9555, 0x4FF6, 0x98E6, 0x4FF8, 0x95EE, 0x4FFA, 0x89B4, + 0x4FFE, 0x98EA, 0x4FFF, 0xFA76, 0x5005, 0x98E4, 0x5006, 0x98ED, + 0x5009, 0x9171, 0x500B, 0x8CC2, 0x500D, 0x947B, 0x500F, 0xE0C5, + 0x5011, 0x98EC, 0x5012, 0x937C, 0x5014, 0x98E1, 0x5016, 0x8CF4, + 0x5019, 0x8CF3, 0x501A, 0x98DF, 0x501E, 0xFA77, 0x501F, 0x8ED8, + 0x5021, 0x98E7, 0x5022, 0xFA75, 0x5023, 0x95ED, 0x5024, 0x926C, + 0x5025, 0x98E3, 0x5026, 0x8C91, 0x5028, 0x98E0, 0x5029, 0x98E8, + 0x502A, 0x98E2, 0x502B, 0x97CF, 0x502C, 0x98E9, 0x502D, 0x9860, + 0x5036, 0x8BE4, 0x5039, 0x8C90, 0x5040, 0xFA74, 0x5042, 0xFA7A, + 0x5043, 0x98EE, 0x5046, 0xFA78, 0x5047, 0x98EF, 0x5048, 0x98F3, + 0x5049, 0x88CC, 0x504F, 0x95CE, 0x5050, 0x98F2, 0x5055, 0x98F1, + 0x5056, 0x98F5, 0x505A, 0x98F4, 0x505C, 0x92E2, 0x5065, 0x8C92, + 0x506C, 0x98F6, 0x5070, 0xFA79, 0x5072, 0x8EC3, 0x5074, 0x91A4, + 0x5075, 0x92E3, 0x5076, 0x8BF4, 0x5078, 0x98F7, 0x507D, 0x8B55, + 0x5080, 0x98F8, 0x5085, 0x98FA, 0x508D, 0x9654, 0x5091, 0x8C86, + 0x5094, 0xFA7B, 0x5098, 0x8E50, 0x5099, 0x94F5, 0x509A, 0x98F9, + 0x50AC, 0x8DC3, 0x50AD, 0x9762, 0x50B2, 0x98FC, 0x50B3, 0x9942, + 0x50B4, 0x98FB, 0x50B5, 0x8DC2, 0x50B7, 0x8F9D, 0x50BE, 0x8C58, + 0x50C2, 0x9943, 0x50C5, 0x8BCD, 0x50C9, 0x9940, 0x50CA, 0x9941, + 0x50CD, 0x93AD, 0x50CF, 0x919C, 0x50D1, 0x8BA1, 0x50D5, 0x966C, + 0x50D6, 0x9944, 0x50D8, 0xFA7D, 0x50DA, 0x97BB, 0x50DE, 0x9945, + 0x50E3, 0x9948, 0x50E5, 0x9946, 0x50E7, 0x916D, 0x50ED, 0x9947, + 0x50EE, 0x9949, 0x50F4, 0xFA7C, 0x50F5, 0x994B, 0x50F9, 0x994A, + 0x50FB, 0x95C6, 0x5100, 0x8B56, 0x5101, 0x994D, 0x5102, 0x994E, + 0x5104, 0x89AD, 0x5109, 0x994C, 0x5112, 0x8EF2, 0x5114, 0x9951, + 0x5115, 0x9950, 0x5116, 0x994F, 0x5118, 0x98D4, 0x511A, 0x9952, + 0x511F, 0x8F9E, 0x5121, 0x9953, 0x512A, 0x9744, 0x5132, 0x96D7, + 0x5137, 0x9955, 0x513A, 0x9954, 0x513B, 0x9957, 0x513C, 0x9956, + 0x513F, 0x9958, 0x5140, 0x9959, 0x5141, 0x88F2, 0x5143, 0x8CB3, + 0x5144, 0x8C5A, 0x5145, 0x8F5B, 0x5146, 0x929B, 0x5147, 0x8BA2, + 0x5148, 0x90E6, 0x5149, 0x8CF5, 0x514A, 0xFA7E, 0x514B, 0x8D8E, + 0x514C, 0x995B, 0x514D, 0x96C6, 0x514E, 0x9365, 0x5150, 0x8E99, + 0x5152, 0x995A, 0x5154, 0x995C, 0x515A, 0x937D, 0x515C, 0x8A95, + 0x5162, 0x995D, 0x5164, 0xFA80, 0x5165, 0x93FC, 0x5168, 0x9153, + 0x5169, 0x995F, 0x516A, 0x9960, 0x516B, 0x94AA, 0x516C, 0x8CF6, + 0x516D, 0x985A, 0x516E, 0x9961, 0x5171, 0x8BA4, 0x5175, 0x95BA, + 0x5176, 0x91B4, 0x5177, 0x8BEF, 0x5178, 0x9354, 0x517C, 0x8C93, + 0x5180, 0x9962, 0x5182, 0x9963, 0x5185, 0x93E0, 0x5186, 0x897E, + 0x5189, 0x9966, 0x518A, 0x8DFB, 0x518C, 0x9965, 0x518D, 0x8DC4, + 0x518F, 0x9967, 0x5190, 0xE3EC, 0x5191, 0x9968, 0x5192, 0x9660, + 0x5193, 0x9969, 0x5195, 0x996A, 0x5196, 0x996B, 0x5197, 0x8FE7, + 0x5199, 0x8ECA, 0x519D, 0xFA81, 0x51A0, 0x8AA5, 0x51A2, 0x996E, + 0x51A4, 0x996C, 0x51A5, 0x96BB, 0x51A6, 0x996D, 0x51A8, 0x9579, + 0x51A9, 0x996F, 0x51AA, 0x9970, 0x51AB, 0x9971, 0x51AC, 0x937E, + 0x51B0, 0x9975, 0x51B1, 0x9973, 0x51B2, 0x9974, 0x51B3, 0x9972, + 0x51B4, 0x8DE1, 0x51B5, 0x9976, 0x51B6, 0x96E8, 0x51B7, 0x97E2, + 0x51BD, 0x9977, 0x51BE, 0xFA82, 0x51C4, 0x90A6, 0x51C5, 0x9978, + 0x51C6, 0x8F79, 0x51C9, 0x9979, 0x51CB, 0x929C, 0x51CC, 0x97BD, + 0x51CD, 0x9380, 0x51D6, 0x99C3, 0x51DB, 0x997A, 0x51DC, 0xEAA3, + 0x51DD, 0x8BC3, 0x51E0, 0x997B, 0x51E1, 0x967D, 0x51E6, 0x8F88, + 0x51E7, 0x91FA, 0x51E9, 0x997D, 0x51EA, 0x93E2, 0x51EC, 0xFA83, + 0x51ED, 0x997E, 0x51F0, 0x9980, 0x51F1, 0x8A4D, 0x51F5, 0x9981, + 0x51F6, 0x8BA5, 0x51F8, 0x93CA, 0x51F9, 0x899A, 0x51FA, 0x8F6F, + 0x51FD, 0x949F, 0x51FE, 0x9982, 0x5200, 0x9381, 0x5203, 0x906E, + 0x5204, 0x9983, 0x5206, 0x95AA, 0x5207, 0x90D8, 0x5208, 0x8AA0, + 0x520A, 0x8AA7, 0x520B, 0x9984, 0x520E, 0x9986, 0x5211, 0x8C59, + 0x5214, 0x9985, 0x5215, 0xFA84, 0x5217, 0x97F1, 0x521D, 0x8F89, + 0x5224, 0x94BB, 0x5225, 0x95CA, 0x5227, 0x9987, 0x5229, 0x9798, + 0x522A, 0x9988, 0x522E, 0x9989, 0x5230, 0x939E, 0x5233, 0x998A, + 0x5236, 0x90A7, 0x5237, 0x8DFC, 0x5238, 0x8C94, 0x5239, 0x998B, + 0x523A, 0x8E68, 0x523B, 0x8D8F, 0x5243, 0x92E4, 0x5244, 0x998D, + 0x5247, 0x91A5, 0x524A, 0x8DED, 0x524B, 0x998E, 0x524C, 0x998F, + 0x524D, 0x914F, 0x524F, 0x998C, 0x5254, 0x9991, 0x5256, 0x9655, + 0x525B, 0x8D84, 0x525E, 0x9990, 0x5263, 0x8C95, 0x5264, 0x8DDC, + 0x5265, 0x948D, 0x5269, 0x9994, 0x526A, 0x9992, 0x526F, 0x959B, + 0x5270, 0x8FE8, 0x5271, 0x999B, 0x5272, 0x8A84, 0x5273, 0x9995, + 0x5274, 0x9993, 0x5275, 0x916E, 0x527D, 0x9997, 0x527F, 0x9996, + 0x5283, 0x8A63, 0x5287, 0x8C80, 0x5288, 0x999C, 0x5289, 0x97AB, + 0x528D, 0x9998, 0x5291, 0x999D, 0x5292, 0x999A, 0x5294, 0x9999, + 0x529B, 0x97CD, 0x529C, 0xFA85, 0x529F, 0x8CF7, 0x52A0, 0x89C1, + 0x52A3, 0x97F2, 0x52A6, 0xFA86, 0x52A9, 0x8F95, 0x52AA, 0x9377, + 0x52AB, 0x8D85, 0x52AC, 0x99A0, 0x52AD, 0x99A1, 0x52AF, 0xFB77, + 0x52B1, 0x97E3, 0x52B4, 0x984A, 0x52B5, 0x99A3, 0x52B9, 0x8CF8, + 0x52BC, 0x99A2, 0x52BE, 0x8A4E, 0x52C0, 0xFA87, 0x52C1, 0x99A4, + 0x52C3, 0x9675, 0x52C5, 0x92BA, 0x52C7, 0x9745, 0x52C9, 0x95D7, + 0x52CD, 0x99A5, 0x52D2, 0xE8D3, 0x52D5, 0x93AE, 0x52D7, 0x99A6, + 0x52D8, 0x8AA8, 0x52D9, 0x96B1, 0x52DB, 0xFA88, 0x52DD, 0x8F9F, + 0x52DE, 0x99A7, 0x52DF, 0x95E5, 0x52E0, 0x99AB, 0x52E2, 0x90A8, + 0x52E3, 0x99A8, 0x52E4, 0x8BCE, 0x52E6, 0x99A9, 0x52E7, 0x8AA9, + 0x52F2, 0x8C4D, 0x52F3, 0x99AC, 0x52F5, 0x99AD, 0x52F8, 0x99AE, + 0x52F9, 0x99AF, 0x52FA, 0x8ED9, 0x52FE, 0x8CF9, 0x52FF, 0x96DC, + 0x5300, 0xFA89, 0x5301, 0x96E6, 0x5302, 0x93F5, 0x5305, 0x95EF, + 0x5306, 0x99B0, 0x5307, 0xFA8A, 0x5308, 0x99B1, 0x530D, 0x99B3, + 0x530F, 0x99B5, 0x5310, 0x99B4, 0x5315, 0x99B6, 0x5316, 0x89BB, + 0x5317, 0x966B, 0x5319, 0x8DFA, 0x531A, 0x99B7, 0x531D, 0x9178, + 0x5320, 0x8FA0, 0x5321, 0x8BA7, 0x5323, 0x99B8, 0x5324, 0xFA8B, + 0x532A, 0x94D9, 0x532F, 0x99B9, 0x5331, 0x99BA, 0x5333, 0x99BB, + 0x5338, 0x99BC, 0x5339, 0x9543, 0x533A, 0x8BE6, 0x533B, 0x88E3, + 0x533F, 0x93BD, 0x5340, 0x99BD, 0x5341, 0x8F5C, 0x5343, 0x90E7, + 0x5345, 0x99BF, 0x5346, 0x99BE, 0x5347, 0x8FA1, 0x5348, 0x8CDF, + 0x5349, 0x99C1, 0x534A, 0x94BC, 0x534D, 0x99C2, 0x5351, 0x94DA, + 0x5352, 0x91B2, 0x5353, 0x91EC, 0x5354, 0x8BA6, 0x5357, 0x93EC, + 0x5358, 0x9250, 0x535A, 0x948E, 0x535C, 0x966D, 0x535E, 0x99C4, + 0x5360, 0x90E8, 0x5366, 0x8C54, 0x5369, 0x99C5, 0x536E, 0x99C6, + 0x536F, 0x894B, 0x5370, 0x88F3, 0x5371, 0x8AEB, 0x5372, 0xFA8C, + 0x5373, 0x91A6, 0x5374, 0x8B70, 0x5375, 0x9791, 0x5377, 0x99C9, + 0x5378, 0x89B5, 0x537B, 0x99C8, 0x537F, 0x8BA8, 0x5382, 0x99CA, + 0x5384, 0x96EF, 0x5393, 0xFA8D, 0x5396, 0x99CB, 0x5398, 0x97D0, + 0x539A, 0x8CFA, 0x539F, 0x8CB4, 0x53A0, 0x99CC, 0x53A5, 0x99CE, + 0x53A6, 0x99CD, 0x53A8, 0x907E, 0x53A9, 0x8958, 0x53AD, 0x897D, + 0x53AE, 0x99CF, 0x53B0, 0x99D0, 0x53B2, 0xFA8E, 0x53B3, 0x8CB5, + 0x53B6, 0x99D1, 0x53BB, 0x8B8E, 0x53C2, 0x8E51, 0x53C3, 0x99D2, + 0x53C8, 0x9694, 0x53C9, 0x8DB3, 0x53CA, 0x8B79, 0x53CB, 0x9746, + 0x53CC, 0x916F, 0x53CD, 0x94BD, 0x53CE, 0x8EFB, 0x53D4, 0x8F66, + 0x53D6, 0x8EE6, 0x53D7, 0x8EF3, 0x53D9, 0x8F96, 0x53DB, 0x94BE, + 0x53DD, 0xFA8F, 0x53DF, 0x99D5, 0x53E1, 0x8962, 0x53E2, 0x9170, + 0x53E3, 0x8CFB, 0x53E4, 0x8CC3, 0x53E5, 0x8BE5, 0x53E8, 0x99D9, + 0x53E9, 0x9240, 0x53EA, 0x91FC, 0x53EB, 0x8BA9, 0x53EC, 0x8FA2, + 0x53ED, 0x99DA, 0x53EE, 0x99D8, 0x53EF, 0x89C2, 0x53F0, 0x91E4, + 0x53F1, 0x8EB6, 0x53F2, 0x8E6A, 0x53F3, 0x8945, 0x53F6, 0x8A90, + 0x53F7, 0x8D86, 0x53F8, 0x8E69, 0x53FA, 0x99DB, 0x5401, 0x99DC, + 0x5403, 0x8B68, 0x5404, 0x8A65, 0x5408, 0x8D87, 0x5409, 0x8B67, + 0x540A, 0x92DD, 0x540B, 0x8944, 0x540C, 0x93AF, 0x540D, 0x96BC, + 0x540E, 0x8D40, 0x540F, 0x9799, 0x5410, 0x9366, 0x5411, 0x8CFC, + 0x541B, 0x8C4E, 0x541D, 0x99E5, 0x541F, 0x8BE1, 0x5420, 0x9669, + 0x5426, 0x94DB, 0x5429, 0x99E4, 0x542B, 0x8ADC, 0x542C, 0x99DF, + 0x542D, 0x99E0, 0x542E, 0x99E2, 0x5436, 0x99E3, 0x5438, 0x8B7A, + 0x5439, 0x9081, 0x543B, 0x95AB, 0x543C, 0x99E1, 0x543D, 0x99DD, + 0x543E, 0x8CE1, 0x5440, 0x99DE, 0x5442, 0x9843, 0x5446, 0x95F0, + 0x5448, 0x92E6, 0x5449, 0x8CE0, 0x544A, 0x8D90, 0x544E, 0x99E6, + 0x5451, 0x93DB, 0x545F, 0x99EA, 0x5468, 0x8EFC, 0x546A, 0x8EF4, + 0x5470, 0x99ED, 0x5471, 0x99EB, 0x5473, 0x96A1, 0x5475, 0x99E8, + 0x5476, 0x99F1, 0x5477, 0x99EC, 0x547B, 0x99EF, 0x547C, 0x8CC4, + 0x547D, 0x96BD, 0x5480, 0x99F0, 0x5484, 0x99F2, 0x5486, 0x99F4, + 0x548A, 0xFA92, 0x548B, 0x8DEE, 0x548C, 0x9861, 0x548E, 0x99E9, + 0x548F, 0x99E7, 0x5490, 0x99F3, 0x5492, 0x99EE, 0x549C, 0xFA91, + 0x54A2, 0x99F6, 0x54A4, 0x9A42, 0x54A5, 0x99F8, 0x54A8, 0x99FC, + 0x54A9, 0xFA93, 0x54AB, 0x9A40, 0x54AC, 0x99F9, 0x54AF, 0x9A5D, + 0x54B2, 0x8DE7, 0x54B3, 0x8A50, 0x54B8, 0x99F7, 0x54BC, 0x9A44, + 0x54BD, 0x88F4, 0x54BE, 0x9A43, 0x54C0, 0x88A3, 0x54C1, 0x9569, + 0x54C2, 0x9A41, 0x54C4, 0x99FA, 0x54C7, 0x99F5, 0x54C8, 0x99FB, + 0x54C9, 0x8DC6, 0x54D8, 0x9A45, 0x54E1, 0x88F5, 0x54E2, 0x9A4E, + 0x54E5, 0x9A46, 0x54E6, 0x9A47, 0x54E8, 0x8FA3, 0x54E9, 0x9689, + 0x54ED, 0x9A4C, 0x54EE, 0x9A4B, 0x54F2, 0x934E, 0x54FA, 0x9A4D, + 0x54FD, 0x9A4A, 0x54FF, 0xFA94, 0x5504, 0x8953, 0x5506, 0x8DB4, + 0x5507, 0x904F, 0x550F, 0x9A48, 0x5510, 0x9382, 0x5514, 0x9A49, + 0x5516, 0x88A0, 0x552E, 0x9A53, 0x552F, 0x9742, 0x5531, 0x8FA5, + 0x5533, 0x9A59, 0x5538, 0x9A58, 0x5539, 0x9A4F, 0x553E, 0x91C1, + 0x5540, 0x9A50, 0x5544, 0x91ED, 0x5545, 0x9A55, 0x5546, 0x8FA4, + 0x554C, 0x9A52, 0x554F, 0x96E2, 0x5553, 0x8C5B, 0x5556, 0x9A56, + 0x5557, 0x9A57, 0x555C, 0x9A54, 0x555D, 0x9A5A, 0x5563, 0x9A51, + 0x557B, 0x9A60, 0x557C, 0x9A65, 0x557E, 0x9A61, 0x5580, 0x9A5C, + 0x5583, 0x9A66, 0x5584, 0x9150, 0x5586, 0xFA95, 0x5587, 0x9A68, + 0x5589, 0x8D41, 0x558A, 0x9A5E, 0x558B, 0x929D, 0x5598, 0x9A62, + 0x5599, 0x9A5B, 0x559A, 0x8AAB, 0x559C, 0x8AEC, 0x559D, 0x8A85, + 0x559E, 0x9A63, 0x559F, 0x9A5F, 0x55A7, 0x8C96, 0x55A8, 0x9A69, + 0x55A9, 0x9A67, 0x55AA, 0x9172, 0x55AB, 0x8B69, 0x55AC, 0x8BAA, + 0x55AE, 0x9A64, 0x55B0, 0x8BF2, 0x55B6, 0x8963, 0x55C4, 0x9A6D, + 0x55C5, 0x9A6B, 0x55C7, 0x9AA5, 0x55D4, 0x9A70, 0x55DA, 0x9A6A, + 0x55DC, 0x9A6E, 0x55DF, 0x9A6C, 0x55E3, 0x8E6B, 0x55E4, 0x9A6F, + 0x55F7, 0x9A72, 0x55F9, 0x9A77, 0x55FD, 0x9A75, 0x55FE, 0x9A74, + 0x5606, 0x9251, 0x5609, 0x89C3, 0x5614, 0x9A71, 0x5616, 0x9A73, + 0x5617, 0x8FA6, 0x5618, 0x8952, 0x561B, 0x9A76, 0x5629, 0x89DC, + 0x562F, 0x9A82, 0x5631, 0x8FFA, 0x5632, 0x9A7D, 0x5634, 0x9A7B, + 0x5636, 0x9A7C, 0x5638, 0x9A7E, 0x5642, 0x895C, 0x564C, 0x9158, + 0x564E, 0x9A78, 0x5650, 0x9A79, 0x565B, 0x8A9A, 0x5664, 0x9A81, + 0x5668, 0x8AED, 0x566A, 0x9A84, 0x566B, 0x9A80, 0x566C, 0x9A83, + 0x5674, 0x95AC, 0x5678, 0x93D3, 0x567A, 0x94B6, 0x5680, 0x9A86, + 0x5686, 0x9A85, 0x5687, 0x8A64, 0x568A, 0x9A87, 0x568F, 0x9A8A, + 0x5694, 0x9A89, 0x56A0, 0x9A88, 0x56A2, 0x9458, 0x56A5, 0x9A8B, + 0x56AE, 0x9A8C, 0x56B4, 0x9A8E, 0x56B6, 0x9A8D, 0x56BC, 0x9A90, + 0x56C0, 0x9A93, 0x56C1, 0x9A91, 0x56C2, 0x9A8F, 0x56C3, 0x9A92, + 0x56C8, 0x9A94, 0x56CE, 0x9A95, 0x56D1, 0x9A96, 0x56D3, 0x9A97, + 0x56D7, 0x9A98, 0x56D8, 0x9964, 0x56DA, 0x8EFA, 0x56DB, 0x8E6C, + 0x56DE, 0x89F1, 0x56E0, 0x88F6, 0x56E3, 0x9263, 0x56EE, 0x9A99, + 0x56F0, 0x8DA2, 0x56F2, 0x88CD, 0x56F3, 0x907D, 0x56F9, 0x9A9A, + 0x56FA, 0x8CC5, 0x56FD, 0x8D91, 0x56FF, 0x9A9C, 0x5700, 0x9A9B, + 0x5703, 0x95DE, 0x5704, 0x9A9D, 0x5708, 0x9A9F, 0x5709, 0x9A9E, + 0x570B, 0x9AA0, 0x570D, 0x9AA1, 0x570F, 0x8C97, 0x5712, 0x8980, + 0x5713, 0x9AA2, 0x5716, 0x9AA4, 0x5718, 0x9AA3, 0x571C, 0x9AA6, + 0x571F, 0x9379, 0x5726, 0x9AA7, 0x5727, 0x88B3, 0x5728, 0x8DDD, + 0x572D, 0x8C5C, 0x5730, 0x926E, 0x5737, 0x9AA8, 0x5738, 0x9AA9, + 0x573B, 0x9AAB, 0x5740, 0x9AAC, 0x5742, 0x8DE2, 0x5747, 0x8BCF, + 0x574A, 0x9656, 0x574E, 0x9AAA, 0x574F, 0x9AAD, 0x5750, 0x8DBF, + 0x5751, 0x8D42, 0x5759, 0xFA96, 0x5761, 0x9AB1, 0x5764, 0x8DA3, + 0x5765, 0xFA97, 0x5766, 0x9252, 0x5769, 0x9AAE, 0x576A, 0x92D8, + 0x577F, 0x9AB2, 0x5782, 0x9082, 0x5788, 0x9AB0, 0x5789, 0x9AB3, + 0x578B, 0x8C5E, 0x5793, 0x9AB4, 0x57A0, 0x9AB5, 0x57A2, 0x8D43, + 0x57A3, 0x8A5F, 0x57A4, 0x9AB7, 0x57AA, 0x9AB8, 0x57AC, 0xFA98, + 0x57B0, 0x9AB9, 0x57B3, 0x9AB6, 0x57C0, 0x9AAF, 0x57C3, 0x9ABA, + 0x57C6, 0x9ABB, 0x57C7, 0xFA9A, 0x57C8, 0xFA99, 0x57CB, 0x9684, + 0x57CE, 0x8FE9, 0x57D2, 0x9ABD, 0x57D3, 0x9ABE, 0x57D4, 0x9ABC, + 0x57D6, 0x9AC0, 0x57DC, 0x9457, 0x57DF, 0x88E6, 0x57E0, 0x9575, + 0x57E3, 0x9AC1, 0x57F4, 0x8FFB, 0x57F7, 0x8EB7, 0x57F9, 0x947C, + 0x57FA, 0x8AEE, 0x57FC, 0x8DE9, 0x5800, 0x9678, 0x5802, 0x93B0, + 0x5805, 0x8C98, 0x5806, 0x91CD, 0x580A, 0x9ABF, 0x580B, 0x9AC2, + 0x5815, 0x91C2, 0x5819, 0x9AC3, 0x581D, 0x9AC4, 0x5821, 0x9AC6, + 0x5824, 0x92E7, 0x582A, 0x8AAC, 0x582F, 0xEA9F, 0x5830, 0x8981, + 0x5831, 0x95F1, 0x5834, 0x8FEA, 0x5835, 0x9367, 0x583A, 0x8DE4, + 0x583D, 0x9ACC, 0x5840, 0x95BB, 0x5841, 0x97DB, 0x584A, 0x89F2, + 0x584B, 0x9AC8, 0x5851, 0x9159, 0x5852, 0x9ACB, 0x5854, 0x9383, + 0x5857, 0x9368, 0x5858, 0x9384, 0x5859, 0x94B7, 0x585A, 0x92CB, + 0x585E, 0x8DC7, 0x5862, 0x9AC7, 0x5869, 0x8996, 0x586B, 0x9355, + 0x5870, 0x9AC9, 0x5872, 0x9AC5, 0x5875, 0x906F, 0x5879, 0x9ACD, + 0x587E, 0x8F6D, 0x5883, 0x8BAB, 0x5885, 0x9ACE, 0x5893, 0x95E6, + 0x5897, 0x919D, 0x589C, 0x92C4, 0x589E, 0xFA9D, 0x589F, 0x9AD0, + 0x58A8, 0x966E, 0x58AB, 0x9AD1, 0x58AE, 0x9AD6, 0x58B2, 0xFA9E, + 0x58B3, 0x95AD, 0x58B8, 0x9AD5, 0x58B9, 0x9ACF, 0x58BA, 0x9AD2, + 0x58BB, 0x9AD4, 0x58BE, 0x8DA4, 0x58C1, 0x95C7, 0x58C5, 0x9AD7, + 0x58C7, 0x9264, 0x58CA, 0x89F3, 0x58CC, 0x8FEB, 0x58D1, 0x9AD9, + 0x58D3, 0x9AD8, 0x58D5, 0x8D88, 0x58D7, 0x9ADA, 0x58D8, 0x9ADC, + 0x58D9, 0x9ADB, 0x58DC, 0x9ADE, 0x58DE, 0x9AD3, 0x58DF, 0x9AE0, + 0x58E4, 0x9ADF, 0x58E5, 0x9ADD, 0x58EB, 0x8E6D, 0x58EC, 0x9070, + 0x58EE, 0x9173, 0x58EF, 0x9AE1, 0x58F0, 0x90BA, 0x58F1, 0x88EB, + 0x58F2, 0x9484, 0x58F7, 0x92D9, 0x58F9, 0x9AE3, 0x58FA, 0x9AE2, + 0x58FB, 0x9AE4, 0x58FC, 0x9AE5, 0x58FD, 0x9AE6, 0x5902, 0x9AE7, + 0x5909, 0x95CF, 0x590A, 0x9AE8, 0x590B, 0xFA9F, 0x590F, 0x89C4, + 0x5910, 0x9AE9, 0x5915, 0x975B, 0x5916, 0x8A4F, 0x5918, 0x99C7, + 0x5919, 0x8F67, 0x591A, 0x91BD, 0x591B, 0x9AEA, 0x591C, 0x96E9, + 0x5922, 0x96B2, 0x5925, 0x9AEC, 0x5927, 0x91E5, 0x5929, 0x9356, + 0x592A, 0x91BE, 0x592B, 0x9576, 0x592C, 0x9AED, 0x592D, 0x9AEE, + 0x592E, 0x899B, 0x5931, 0x8EB8, 0x5932, 0x9AEF, 0x5937, 0x88CE, + 0x5938, 0x9AF0, 0x593E, 0x9AF1, 0x5944, 0x8982, 0x5947, 0x8AEF, + 0x5948, 0x93DE, 0x5949, 0x95F2, 0x594E, 0x9AF5, 0x594F, 0x9174, + 0x5950, 0x9AF4, 0x5951, 0x8C5F, 0x5953, 0xFAA0, 0x5954, 0x967A, + 0x5955, 0x9AF3, 0x5957, 0x9385, 0x5958, 0x9AF7, 0x595A, 0x9AF6, + 0x595B, 0xFAA1, 0x595D, 0xFAA2, 0x5960, 0x9AF9, 0x5962, 0x9AF8, + 0x5963, 0xFAA3, 0x5965, 0x899C, 0x5967, 0x9AFA, 0x5968, 0x8FA7, + 0x5969, 0x9AFC, 0x596A, 0x9244, 0x596C, 0x9AFB, 0x596E, 0x95B1, + 0x5973, 0x8F97, 0x5974, 0x937A, 0x5978, 0x9B40, 0x597D, 0x8D44, + 0x5981, 0x9B41, 0x5982, 0x9440, 0x5983, 0x94DC, 0x5984, 0x96CF, + 0x598A, 0x9444, 0x598D, 0x9B4A, 0x5993, 0x8B57, 0x5996, 0x9764, + 0x5999, 0x96AD, 0x599B, 0x9BAA, 0x599D, 0x9B42, 0x59A3, 0x9B45, + 0x59A4, 0xFAA4, 0x59A5, 0x91C3, 0x59A8, 0x9657, 0x59AC, 0x9369, + 0x59B2, 0x9B46, 0x59B9, 0x9685, 0x59BA, 0xFAA5, 0x59BB, 0x8DC8, + 0x59BE, 0x8FA8, 0x59C6, 0x9B47, 0x59C9, 0x8E6F, 0x59CB, 0x8E6E, + 0x59D0, 0x88B7, 0x59D1, 0x8CC6, 0x59D3, 0x90A9, 0x59D4, 0x88CF, + 0x59D9, 0x9B4B, 0x59DA, 0x9B4C, 0x59DC, 0x9B49, 0x59E5, 0x8957, + 0x59E6, 0x8AAD, 0x59E8, 0x9B48, 0x59EA, 0x96C3, 0x59EB, 0x9550, + 0x59F6, 0x88A6, 0x59FB, 0x88F7, 0x59FF, 0x8E70, 0x5A01, 0x88D0, + 0x5A03, 0x88A1, 0x5A09, 0x9B51, 0x5A11, 0x9B4F, 0x5A18, 0x96BA, + 0x5A1A, 0x9B52, 0x5A1C, 0x9B50, 0x5A1F, 0x9B4E, 0x5A20, 0x9050, + 0x5A25, 0x9B4D, 0x5A29, 0x95D8, 0x5A2F, 0x8CE2, 0x5A35, 0x9B56, + 0x5A36, 0x9B57, 0x5A3C, 0x8FA9, 0x5A40, 0x9B53, 0x5A41, 0x984B, + 0x5A46, 0x946B, 0x5A49, 0x9B55, 0x5A5A, 0x8DA5, 0x5A62, 0x9B58, + 0x5A66, 0x9577, 0x5A6A, 0x9B59, 0x5A6C, 0x9B54, 0x5A7F, 0x96B9, + 0x5A92, 0x947D, 0x5A9A, 0x9B5A, 0x5A9B, 0x9551, 0x5ABC, 0x9B5B, + 0x5ABD, 0x9B5F, 0x5ABE, 0x9B5C, 0x5AC1, 0x89C5, 0x5AC2, 0x9B5E, + 0x5AC9, 0x8EB9, 0x5ACB, 0x9B5D, 0x5ACC, 0x8C99, 0x5AD0, 0x9B6B, + 0x5AD6, 0x9B64, 0x5AD7, 0x9B61, 0x5AE1, 0x9284, 0x5AE3, 0x9B60, + 0x5AE6, 0x9B62, 0x5AE9, 0x9B63, 0x5AFA, 0x9B65, 0x5AFB, 0x9B66, + 0x5B09, 0x8AF0, 0x5B0B, 0x9B68, 0x5B0C, 0x9B67, 0x5B16, 0x9B69, + 0x5B22, 0x8FEC, 0x5B2A, 0x9B6C, 0x5B2C, 0x92DA, 0x5B30, 0x8964, + 0x5B32, 0x9B6A, 0x5B36, 0x9B6D, 0x5B3E, 0x9B6E, 0x5B40, 0x9B71, + 0x5B43, 0x9B6F, 0x5B45, 0x9B70, 0x5B50, 0x8E71, 0x5B51, 0x9B72, + 0x5B54, 0x8D45, 0x5B55, 0x9B73, 0x5B56, 0xFAA6, 0x5B57, 0x8E9A, + 0x5B58, 0x91B6, 0x5B5A, 0x9B74, 0x5B5B, 0x9B75, 0x5B5C, 0x8E79, + 0x5B5D, 0x8D46, 0x5B5F, 0x96D0, 0x5B63, 0x8B47, 0x5B64, 0x8CC7, + 0x5B65, 0x9B76, 0x5B66, 0x8A77, 0x5B69, 0x9B77, 0x5B6B, 0x91B7, + 0x5B70, 0x9B78, 0x5B71, 0x9BA1, 0x5B73, 0x9B79, 0x5B75, 0x9B7A, + 0x5B78, 0x9B7B, 0x5B7A, 0x9B7D, 0x5B80, 0x9B7E, 0x5B83, 0x9B80, + 0x5B85, 0x91EE, 0x5B87, 0x8946, 0x5B88, 0x8EE7, 0x5B89, 0x88C0, + 0x5B8B, 0x9176, 0x5B8C, 0x8AAE, 0x5B8D, 0x8EB3, 0x5B8F, 0x8D47, + 0x5B95, 0x9386, 0x5B97, 0x8F40, 0x5B98, 0x8AAF, 0x5B99, 0x9288, + 0x5B9A, 0x92E8, 0x5B9B, 0x88B6, 0x5B9C, 0x8B58, 0x5B9D, 0x95F3, + 0x5B9F, 0x8EC0, 0x5BA2, 0x8B71, 0x5BA3, 0x90E9, 0x5BA4, 0x8EBA, + 0x5BA5, 0x9747, 0x5BA6, 0x9B81, 0x5BAE, 0x8B7B, 0x5BB0, 0x8DC9, + 0x5BB3, 0x8A51, 0x5BB4, 0x8983, 0x5BB5, 0x8FAA, 0x5BB6, 0x89C6, + 0x5BB8, 0x9B82, 0x5BB9, 0x9765, 0x5BBF, 0x8F68, 0x5BC0, 0xFAA7, + 0x5BC2, 0x8EE2, 0x5BC3, 0x9B83, 0x5BC4, 0x8AF1, 0x5BC5, 0x93D0, + 0x5BC6, 0x96A7, 0x5BC7, 0x9B84, 0x5BC9, 0x9B85, 0x5BCC, 0x9578, + 0x5BD0, 0x9B87, 0x5BD2, 0x8AA6, 0x5BD3, 0x8BF5, 0x5BD4, 0x9B86, + 0x5BD8, 0xFAA9, 0x5BDB, 0x8AB0, 0x5BDD, 0x9051, 0x5BDE, 0x9B8B, + 0x5BDF, 0x8E40, 0x5BE1, 0x89C7, 0x5BE2, 0x9B8A, 0x5BE4, 0x9B88, + 0x5BE5, 0x9B8C, 0x5BE6, 0x9B89, 0x5BE7, 0x944A, 0x5BE8, 0x9ECB, + 0x5BE9, 0x9052, 0x5BEB, 0x9B8D, 0x5BEC, 0xFAAA, 0x5BEE, 0x97BE, + 0x5BF0, 0x9B8E, 0x5BF3, 0x9B90, 0x5BF5, 0x929E, 0x5BF6, 0x9B8F, + 0x5BF8, 0x90A1, 0x5BFA, 0x8E9B, 0x5BFE, 0x91CE, 0x5BFF, 0x8EF5, + 0x5C01, 0x9595, 0x5C02, 0x90EA, 0x5C04, 0x8ECB, 0x5C05, 0x9B91, + 0x5C06, 0x8FAB, 0x5C07, 0x9B92, 0x5C08, 0x9B93, 0x5C09, 0x88D1, + 0x5C0A, 0x91B8, 0x5C0B, 0x9071, 0x5C0D, 0x9B94, 0x5C0E, 0x93B1, + 0x5C0F, 0x8FAC, 0x5C11, 0x8FAD, 0x5C13, 0x9B95, 0x5C16, 0x90EB, + 0x5C1A, 0x8FAE, 0x5C1E, 0xFAAB, 0x5C20, 0x9B96, 0x5C22, 0x9B97, + 0x5C24, 0x96DE, 0x5C28, 0x9B98, 0x5C2D, 0x8BC4, 0x5C31, 0x8F41, + 0x5C38, 0x9B99, 0x5C39, 0x9B9A, 0x5C3A, 0x8EDA, 0x5C3B, 0x904B, + 0x5C3C, 0x93F2, 0x5C3D, 0x9073, 0x5C3E, 0x94F6, 0x5C3F, 0x9441, + 0x5C40, 0x8BC7, 0x5C41, 0x9B9B, 0x5C45, 0x8B8F, 0x5C46, 0x9B9C, + 0x5C48, 0x8BFC, 0x5C4A, 0x93CD, 0x5C4B, 0x89AE, 0x5C4D, 0x8E72, + 0x5C4E, 0x9B9D, 0x5C4F, 0x9BA0, 0x5C50, 0x9B9F, 0x5C51, 0x8BFB, + 0x5C53, 0x9B9E, 0x5C55, 0x9357, 0x5C5E, 0x91AE, 0x5C60, 0x936A, + 0x5C61, 0x8EC6, 0x5C64, 0x9177, 0x5C65, 0x979A, 0x5C6C, 0x9BA2, + 0x5C6E, 0x9BA3, 0x5C6F, 0x93D4, 0x5C71, 0x8E52, 0x5C76, 0x9BA5, + 0x5C79, 0x9BA6, 0x5C8C, 0x9BA7, 0x5C90, 0x8AF2, 0x5C91, 0x9BA8, + 0x5C94, 0x9BA9, 0x5CA1, 0x89AA, 0x5CA6, 0xFAAC, 0x5CA8, 0x915A, + 0x5CA9, 0x8AE2, 0x5CAB, 0x9BAB, 0x5CAC, 0x96A6, 0x5CB1, 0x91D0, + 0x5CB3, 0x8A78, 0x5CB6, 0x9BAD, 0x5CB7, 0x9BAF, 0x5CB8, 0x8ADD, + 0x5CBA, 0xFAAD, 0x5CBB, 0x9BAC, 0x5CBC, 0x9BAE, 0x5CBE, 0x9BB1, + 0x5CC5, 0x9BB0, 0x5CC7, 0x9BB2, 0x5CD9, 0x9BB3, 0x5CE0, 0x93BB, + 0x5CE1, 0x8BAC, 0x5CE8, 0x89E3, 0x5CE9, 0x9BB4, 0x5CEA, 0x9BB9, + 0x5CED, 0x9BB7, 0x5CEF, 0x95F5, 0x5CF0, 0x95F4, 0x5CF5, 0xFAAE, + 0x5CF6, 0x9387, 0x5CFA, 0x9BB6, 0x5CFB, 0x8F73, 0x5CFD, 0x9BB5, + 0x5D07, 0x9092, 0x5D0B, 0x9BBA, 0x5D0E, 0x8DE8, 0x5D11, 0x9BC0, + 0x5D14, 0x9BC1, 0x5D15, 0x9BBB, 0x5D16, 0x8A52, 0x5D17, 0x9BBC, + 0x5D18, 0x9BC5, 0x5D19, 0x9BC4, 0x5D1A, 0x9BC3, 0x5D1B, 0x9BBF, + 0x5D1F, 0x9BBE, 0x5D22, 0x9BC2, 0x5D27, 0xFAAF, 0x5D29, 0x95F6, + 0x5D42, 0xFAB2, 0x5D4B, 0x9BC9, 0x5D4C, 0x9BC6, 0x5D4E, 0x9BC8, + 0x5D50, 0x9792, 0x5D52, 0x9BC7, 0x5D53, 0xFAB0, 0x5D5C, 0x9BBD, + 0x5D69, 0x9093, 0x5D6C, 0x9BCA, 0x5D6D, 0xFAB3, 0x5D6F, 0x8DB5, + 0x5D73, 0x9BCB, 0x5D76, 0x9BCC, 0x5D82, 0x9BCF, 0x5D84, 0x9BCE, + 0x5D87, 0x9BCD, 0x5D8B, 0x9388, 0x5D8C, 0x9BB8, 0x5D90, 0x9BD5, + 0x5D9D, 0x9BD1, 0x5DA2, 0x9BD0, 0x5DAC, 0x9BD2, 0x5DAE, 0x9BD3, + 0x5DB7, 0x9BD6, 0x5DB8, 0xFAB4, 0x5DB9, 0xFAB5, 0x5DBA, 0x97E4, + 0x5DBC, 0x9BD7, 0x5DBD, 0x9BD4, 0x5DC9, 0x9BD8, 0x5DCC, 0x8ADE, + 0x5DCD, 0x9BD9, 0x5DD0, 0xFAB6, 0x5DD2, 0x9BDB, 0x5DD3, 0x9BDA, + 0x5DD6, 0x9BDC, 0x5DDB, 0x9BDD, 0x5DDD, 0x90EC, 0x5DDE, 0x8F42, + 0x5DE1, 0x8F84, 0x5DE3, 0x9183, 0x5DE5, 0x8D48, 0x5DE6, 0x8DB6, + 0x5DE7, 0x8D49, 0x5DE8, 0x8B90, 0x5DEB, 0x9BDE, 0x5DEE, 0x8DB7, + 0x5DF1, 0x8CC8, 0x5DF2, 0x9BDF, 0x5DF3, 0x96A4, 0x5DF4, 0x9462, + 0x5DF5, 0x9BE0, 0x5DF7, 0x8D4A, 0x5DFB, 0x8AAA, 0x5DFD, 0x9246, + 0x5DFE, 0x8BD0, 0x5E02, 0x8E73, 0x5E03, 0x957A, 0x5E06, 0x94BF, + 0x5E0B, 0x9BE1, 0x5E0C, 0x8AF3, 0x5E11, 0x9BE4, 0x5E16, 0x929F, + 0x5E19, 0x9BE3, 0x5E1A, 0x9BE2, 0x5E1B, 0x9BE5, 0x5E1D, 0x92E9, + 0x5E25, 0x9083, 0x5E2B, 0x8E74, 0x5E2D, 0x90C8, 0x5E2F, 0x91D1, + 0x5E30, 0x8B41, 0x5E33, 0x92A0, 0x5E36, 0x9BE6, 0x5E37, 0x9BE7, + 0x5E38, 0x8FED, 0x5E3D, 0x9658, 0x5E40, 0x9BEA, 0x5E43, 0x9BE9, + 0x5E44, 0x9BE8, 0x5E45, 0x959D, 0x5E47, 0x9BF1, 0x5E4C, 0x9679, + 0x5E4E, 0x9BEB, 0x5E54, 0x9BED, 0x5E55, 0x968B, 0x5E57, 0x9BEC, + 0x5E5F, 0x9BEE, 0x5E61, 0x94A6, 0x5E62, 0x9BEF, 0x5E63, 0x95BC, + 0x5E64, 0x9BF0, 0x5E72, 0x8AB1, 0x5E73, 0x95BD, 0x5E74, 0x944E, + 0x5E75, 0x9BF2, 0x5E76, 0x9BF3, 0x5E78, 0x8D4B, 0x5E79, 0x8AB2, + 0x5E7A, 0x9BF4, 0x5E7B, 0x8CB6, 0x5E7C, 0x9763, 0x5E7D, 0x9748, + 0x5E7E, 0x8AF4, 0x5E7F, 0x9BF6, 0x5E81, 0x92A1, 0x5E83, 0x8D4C, + 0x5E84, 0x8FAF, 0x5E87, 0x94DD, 0x5E8A, 0x8FB0, 0x5E8F, 0x8F98, + 0x5E95, 0x92EA, 0x5E96, 0x95F7, 0x5E97, 0x9358, 0x5E9A, 0x8D4D, + 0x5E9C, 0x957B, 0x5EA0, 0x9BF7, 0x5EA6, 0x9378, 0x5EA7, 0x8DC0, + 0x5EAB, 0x8CC9, 0x5EAD, 0x92EB, 0x5EB5, 0x88C1, 0x5EB6, 0x8F8E, + 0x5EB7, 0x8D4E, 0x5EB8, 0x9766, 0x5EC1, 0x9BF8, 0x5EC2, 0x9BF9, + 0x5EC3, 0x9470, 0x5EC8, 0x9BFA, 0x5EC9, 0x97F5, 0x5ECA, 0x984C, + 0x5ECF, 0x9BFC, 0x5ED0, 0x9BFB, 0x5ED3, 0x8A66, 0x5ED6, 0x9C40, + 0x5EDA, 0x9C43, 0x5EDB, 0x9C44, 0x5EDD, 0x9C42, 0x5EDF, 0x955F, + 0x5EE0, 0x8FB1, 0x5EE1, 0x9C46, 0x5EE2, 0x9C45, 0x5EE3, 0x9C41, + 0x5EE8, 0x9C47, 0x5EE9, 0x9C48, 0x5EEC, 0x9C49, 0x5EF0, 0x9C4C, + 0x5EF1, 0x9C4A, 0x5EF3, 0x9C4B, 0x5EF4, 0x9C4D, 0x5EF6, 0x8984, + 0x5EF7, 0x92EC, 0x5EF8, 0x9C4E, 0x5EFA, 0x8C9A, 0x5EFB, 0x89F4, + 0x5EFC, 0x9455, 0x5EFE, 0x9C4F, 0x5EFF, 0x93F9, 0x5F01, 0x95D9, + 0x5F03, 0x9C50, 0x5F04, 0x984D, 0x5F09, 0x9C51, 0x5F0A, 0x95BE, + 0x5F0B, 0x9C54, 0x5F0C, 0x989F, 0x5F0D, 0x98AF, 0x5F0F, 0x8EAE, + 0x5F10, 0x93F3, 0x5F11, 0x9C55, 0x5F13, 0x8B7C, 0x5F14, 0x92A2, + 0x5F15, 0x88F8, 0x5F16, 0x9C56, 0x5F17, 0x95A4, 0x5F18, 0x8D4F, + 0x5F1B, 0x926F, 0x5F1F, 0x92ED, 0x5F21, 0xFAB7, 0x5F25, 0x96ED, + 0x5F26, 0x8CB7, 0x5F27, 0x8CCA, 0x5F29, 0x9C57, 0x5F2D, 0x9C58, + 0x5F2F, 0x9C5E, 0x5F31, 0x8EE3, 0x5F34, 0xFAB8, 0x5F35, 0x92A3, + 0x5F37, 0x8BAD, 0x5F38, 0x9C59, 0x5F3C, 0x954A, 0x5F3E, 0x9265, + 0x5F41, 0x9C5A, 0x5F45, 0xFA67, 0x5F48, 0x9C5B, 0x5F4A, 0x8BAE, + 0x5F4C, 0x9C5C, 0x5F4E, 0x9C5D, 0x5F51, 0x9C5F, 0x5F53, 0x9396, + 0x5F56, 0x9C60, 0x5F57, 0x9C61, 0x5F59, 0x9C62, 0x5F5C, 0x9C53, + 0x5F5D, 0x9C52, 0x5F61, 0x9C63, 0x5F62, 0x8C60, 0x5F66, 0x9546, + 0x5F67, 0xFAB9, 0x5F69, 0x8DCA, 0x5F6A, 0x9556, 0x5F6B, 0x92A4, + 0x5F6C, 0x956A, 0x5F6D, 0x9C64, 0x5F70, 0x8FB2, 0x5F71, 0x8965, + 0x5F73, 0x9C65, 0x5F77, 0x9C66, 0x5F79, 0x96F0, 0x5F7C, 0x94DE, + 0x5F7F, 0x9C69, 0x5F80, 0x899D, 0x5F81, 0x90AA, 0x5F82, 0x9C68, + 0x5F83, 0x9C67, 0x5F84, 0x8C61, 0x5F85, 0x91D2, 0x5F87, 0x9C6D, + 0x5F88, 0x9C6B, 0x5F8A, 0x9C6A, 0x5F8B, 0x97A5, 0x5F8C, 0x8CE3, + 0x5F90, 0x8F99, 0x5F91, 0x9C6C, 0x5F92, 0x936B, 0x5F93, 0x8F5D, + 0x5F97, 0x93BE, 0x5F98, 0x9C70, 0x5F99, 0x9C6F, 0x5F9E, 0x9C6E, + 0x5FA0, 0x9C71, 0x5FA1, 0x8CE4, 0x5FA8, 0x9C72, 0x5FA9, 0x959C, + 0x5FAA, 0x8F7A, 0x5FAD, 0x9C73, 0x5FAE, 0x94F7, 0x5FB3, 0x93BF, + 0x5FB4, 0x92A5, 0x5FB7, 0xFABA, 0x5FB9, 0x934F, 0x5FBC, 0x9C74, + 0x5FBD, 0x8B4A, 0x5FC3, 0x9053, 0x5FC5, 0x954B, 0x5FCC, 0x8AF5, + 0x5FCD, 0x9445, 0x5FD6, 0x9C75, 0x5FD7, 0x8E75, 0x5FD8, 0x9659, + 0x5FD9, 0x965A, 0x5FDC, 0x899E, 0x5FDD, 0x9C7A, 0x5FDE, 0xFABB, + 0x5FE0, 0x9289, 0x5FE4, 0x9C77, 0x5FEB, 0x89F5, 0x5FF0, 0x9CAB, + 0x5FF1, 0x9C79, 0x5FF5, 0x944F, 0x5FF8, 0x9C78, 0x5FFB, 0x9C76, + 0x5FFD, 0x8D9A, 0x5FFF, 0x9C7C, 0x600E, 0x9C83, 0x600F, 0x9C89, + 0x6010, 0x9C81, 0x6012, 0x937B, 0x6015, 0x9C86, 0x6016, 0x957C, + 0x6019, 0x9C80, 0x601B, 0x9C85, 0x601C, 0x97E5, 0x601D, 0x8E76, + 0x6020, 0x91D3, 0x6021, 0x9C7D, 0x6025, 0x8B7D, 0x6026, 0x9C88, + 0x6027, 0x90AB, 0x6028, 0x8985, 0x6029, 0x9C82, 0x602A, 0x89F6, + 0x602B, 0x9C87, 0x602F, 0x8BAF, 0x6031, 0x9C84, 0x603A, 0x9C8A, + 0x6041, 0x9C8C, 0x6042, 0x9C96, 0x6043, 0x9C94, 0x6046, 0x9C91, + 0x604A, 0x9C90, 0x604B, 0x97F6, 0x604D, 0x9C92, 0x6050, 0x8BB0, + 0x6052, 0x8D50, 0x6055, 0x8F9A, 0x6059, 0x9C99, 0x605A, 0x9C8B, + 0x605D, 0xFABC, 0x605F, 0x9C8F, 0x6060, 0x9C7E, 0x6062, 0x89F8, + 0x6063, 0x9C93, 0x6064, 0x9C95, 0x6065, 0x9270, 0x6068, 0x8DA6, + 0x6069, 0x89B6, 0x606A, 0x9C8D, 0x606B, 0x9C98, 0x606C, 0x9C97, + 0x606D, 0x8BB1, 0x606F, 0x91A7, 0x6070, 0x8A86, 0x6075, 0x8C62, + 0x6077, 0x9C8E, 0x6081, 0x9C9A, 0x6083, 0x9C9D, 0x6084, 0x9C9F, + 0x6085, 0xFABD, 0x6089, 0x8EBB, 0x608A, 0xFABE, 0x608B, 0x9CA5, + 0x608C, 0x92EE, 0x608D, 0x9C9B, 0x6092, 0x9CA3, 0x6094, 0x89F7, + 0x6096, 0x9CA1, 0x6097, 0x9CA2, 0x609A, 0x9C9E, 0x609B, 0x9CA0, + 0x609F, 0x8CE5, 0x60A0, 0x9749, 0x60A3, 0x8AB3, 0x60A6, 0x8978, + 0x60A7, 0x9CA4, 0x60A9, 0x9459, 0x60AA, 0x88AB, 0x60B2, 0x94DF, + 0x60B3, 0x9C7B, 0x60B4, 0x9CAA, 0x60B5, 0x9CAE, 0x60B6, 0x96E3, + 0x60B8, 0x9CA7, 0x60BC, 0x9389, 0x60BD, 0x9CAC, 0x60C5, 0x8FEE, + 0x60C6, 0x9CAD, 0x60C7, 0x93D5, 0x60D1, 0x9866, 0x60D3, 0x9CA9, + 0x60D5, 0xFAC0, 0x60D8, 0x9CAF, 0x60DA, 0x8D9B, 0x60DC, 0x90C9, + 0x60DE, 0xFABF, 0x60DF, 0x88D2, 0x60E0, 0x9CA8, 0x60E1, 0x9CA6, + 0x60E3, 0x9179, 0x60E7, 0x9C9C, 0x60E8, 0x8E53, 0x60F0, 0x91C4, + 0x60F1, 0x9CBB, 0x60F2, 0xFAC2, 0x60F3, 0x917A, 0x60F4, 0x9CB6, + 0x60F6, 0x9CB3, 0x60F7, 0x9CB4, 0x60F9, 0x8EE4, 0x60FA, 0x9CB7, + 0x60FB, 0x9CBA, 0x6100, 0x9CB5, 0x6101, 0x8F44, 0x6103, 0x9CB8, + 0x6106, 0x9CB2, 0x6108, 0x96FA, 0x6109, 0x96F9, 0x610D, 0x9CBC, + 0x610E, 0x9CBD, 0x610F, 0x88D3, 0x6111, 0xFAC3, 0x6115, 0x9CB1, + 0x611A, 0x8BF0, 0x611B, 0x88A4, 0x611F, 0x8AB4, 0x6120, 0xFAC1, + 0x6121, 0x9CB9, 0x6127, 0x9CC1, 0x6128, 0x9CC0, 0x612C, 0x9CC5, + 0x6130, 0xFAC5, 0x6134, 0x9CC6, 0x6137, 0xFAC4, 0x613C, 0x9CC4, + 0x613D, 0x9CC7, 0x613E, 0x9CBF, 0x613F, 0x9CC3, 0x6142, 0x9CC8, + 0x6144, 0x9CC9, 0x6147, 0x9CBE, 0x6148, 0x8E9C, 0x614A, 0x9CC2, + 0x614B, 0x91D4, 0x614C, 0x8D51, 0x614D, 0x9CB0, 0x614E, 0x9054, + 0x6153, 0x9CD6, 0x6155, 0x95E7, 0x6158, 0x9CCC, 0x6159, 0x9CCD, + 0x615A, 0x9CCE, 0x615D, 0x9CD5, 0x615F, 0x9CD4, 0x6162, 0x969D, + 0x6163, 0x8AB5, 0x6165, 0x9CD2, 0x6167, 0x8C64, 0x6168, 0x8A53, + 0x616B, 0x9CCF, 0x616E, 0x97B6, 0x616F, 0x9CD1, 0x6170, 0x88D4, + 0x6171, 0x9CD3, 0x6173, 0x9CCA, 0x6174, 0x9CD0, 0x6175, 0x9CD7, + 0x6176, 0x8C63, 0x6177, 0x9CCB, 0x617E, 0x977C, 0x6182, 0x974A, + 0x6187, 0x9CDA, 0x618A, 0x9CDE, 0x618E, 0x919E, 0x6190, 0x97F7, + 0x6191, 0x9CDF, 0x6194, 0x9CDC, 0x6196, 0x9CD9, 0x6198, 0xFAC6, + 0x6199, 0x9CD8, 0x619A, 0x9CDD, 0x61A4, 0x95AE, 0x61A7, 0x93B2, + 0x61A9, 0x8C65, 0x61AB, 0x9CE0, 0x61AC, 0x9CDB, 0x61AE, 0x9CE1, + 0x61B2, 0x8C9B, 0x61B6, 0x89AF, 0x61BA, 0x9CE9, 0x61BE, 0x8AB6, + 0x61C3, 0x9CE7, 0x61C6, 0x9CE8, 0x61C7, 0x8DA7, 0x61C8, 0x9CE6, + 0x61C9, 0x9CE4, 0x61CA, 0x9CE3, 0x61CB, 0x9CEA, 0x61CC, 0x9CE2, + 0x61CD, 0x9CEC, 0x61D0, 0x89F9, 0x61E3, 0x9CEE, 0x61E6, 0x9CED, + 0x61F2, 0x92A6, 0x61F4, 0x9CF1, 0x61F6, 0x9CEF, 0x61F7, 0x9CE5, + 0x61F8, 0x8C9C, 0x61FA, 0x9CF0, 0x61FC, 0x9CF4, 0x61FD, 0x9CF3, + 0x61FE, 0x9CF5, 0x61FF, 0x9CF2, 0x6200, 0x9CF6, 0x6208, 0x9CF7, + 0x6209, 0x9CF8, 0x620A, 0x95E8, 0x620C, 0x9CFA, 0x620D, 0x9CF9, + 0x620E, 0x8F5E, 0x6210, 0x90AC, 0x6211, 0x89E4, 0x6212, 0x89FA, + 0x6213, 0xFAC7, 0x6214, 0x9CFB, 0x6216, 0x88BD, 0x621A, 0x90CA, + 0x621B, 0x9CFC, 0x621D, 0xE6C1, 0x621E, 0x9D40, 0x621F, 0x8C81, + 0x6221, 0x9D41, 0x6226, 0x90ED, 0x622A, 0x9D42, 0x622E, 0x9D43, + 0x622F, 0x8B59, 0x6230, 0x9D44, 0x6232, 0x9D45, 0x6233, 0x9D46, + 0x6234, 0x91D5, 0x6238, 0x8CCB, 0x623B, 0x96DF, 0x623F, 0x965B, + 0x6240, 0x8F8A, 0x6241, 0x9D47, 0x6247, 0x90EE, 0x6248, 0xE7BB, + 0x6249, 0x94E0, 0x624B, 0x8EE8, 0x624D, 0x8DCB, 0x624E, 0x9D48, + 0x6253, 0x91C5, 0x6255, 0x95A5, 0x6258, 0x91EF, 0x625B, 0x9D4B, + 0x625E, 0x9D49, 0x6260, 0x9D4C, 0x6263, 0x9D4A, 0x6268, 0x9D4D, + 0x626E, 0x95AF, 0x6271, 0x88B5, 0x6276, 0x957D, 0x6279, 0x94E1, + 0x627C, 0x9D4E, 0x627E, 0x9D51, 0x627F, 0x8FB3, 0x6280, 0x8B5A, + 0x6282, 0x9D4F, 0x6283, 0x9D56, 0x6284, 0x8FB4, 0x6289, 0x9D50, + 0x628A, 0x9463, 0x6291, 0x977D, 0x6292, 0x9D52, 0x6293, 0x9D53, + 0x6294, 0x9D57, 0x6295, 0x938A, 0x6296, 0x9D54, 0x6297, 0x8D52, + 0x6298, 0x90DC, 0x629B, 0x9D65, 0x629C, 0x94B2, 0x629E, 0x91F0, + 0x62A6, 0xFAC8, 0x62AB, 0x94E2, 0x62AC, 0x9DAB, 0x62B1, 0x95F8, + 0x62B5, 0x92EF, 0x62B9, 0x9695, 0x62BB, 0x9D5A, 0x62BC, 0x899F, + 0x62BD, 0x928A, 0x62C2, 0x9D63, 0x62C5, 0x9253, 0x62C6, 0x9D5D, + 0x62C7, 0x9D64, 0x62C8, 0x9D5F, 0x62C9, 0x9D66, 0x62CA, 0x9D62, + 0x62CC, 0x9D61, 0x62CD, 0x948F, 0x62CF, 0x9D5B, 0x62D0, 0x89FB, + 0x62D1, 0x9D59, 0x62D2, 0x8B91, 0x62D3, 0x91F1, 0x62D4, 0x9D55, + 0x62D7, 0x9D58, 0x62D8, 0x8D53, 0x62D9, 0x90D9, 0x62DB, 0x8FB5, + 0x62DC, 0x9D60, 0x62DD, 0x9471, 0x62E0, 0x8B92, 0x62E1, 0x8A67, + 0x62EC, 0x8A87, 0x62ED, 0x9040, 0x62EE, 0x9D68, 0x62EF, 0x9D6D, + 0x62F1, 0x9D69, 0x62F3, 0x8C9D, 0x62F5, 0x9D6E, 0x62F6, 0x8E41, + 0x62F7, 0x8D89, 0x62FE, 0x8F45, 0x62FF, 0x9D5C, 0x6301, 0x8E9D, + 0x6302, 0x9D6B, 0x6307, 0x8E77, 0x6308, 0x9D6C, 0x6309, 0x88C2, + 0x630C, 0x9D67, 0x6311, 0x92A7, 0x6319, 0x8B93, 0x631F, 0x8BB2, + 0x6327, 0x9D6A, 0x6328, 0x88A5, 0x632B, 0x8DC1, 0x632F, 0x9055, + 0x633A, 0x92F0, 0x633D, 0x94D2, 0x633E, 0x9D70, 0x633F, 0x917D, + 0x6349, 0x91A8, 0x634C, 0x8E4A, 0x634D, 0x9D71, 0x634F, 0x9D73, + 0x6350, 0x9D6F, 0x6355, 0x95DF, 0x6357, 0x92BB, 0x635C, 0x917B, + 0x6367, 0x95F9, 0x6368, 0x8ECC, 0x6369, 0x9D80, 0x636B, 0x9D7E, + 0x636E, 0x9098, 0x6372, 0x8C9E, 0x6376, 0x9D78, 0x6377, 0x8FB7, + 0x637A, 0x93E6, 0x637B, 0x9450, 0x6380, 0x9D76, 0x6383, 0x917C, + 0x6388, 0x8EF6, 0x6389, 0x9D7B, 0x638C, 0x8FB6, 0x638E, 0x9D75, + 0x638F, 0x9D7A, 0x6392, 0x9472, 0x6396, 0x9D74, 0x6398, 0x8C40, + 0x639B, 0x8A7C, 0x639F, 0x9D7C, 0x63A0, 0x97A9, 0x63A1, 0x8DCC, + 0x63A2, 0x9254, 0x63A3, 0x9D79, 0x63A5, 0x90DA, 0x63A7, 0x8D54, + 0x63A8, 0x9084, 0x63A9, 0x8986, 0x63AA, 0x915B, 0x63AB, 0x9D77, + 0x63AC, 0x8B64, 0x63B2, 0x8C66, 0x63B4, 0x92CD, 0x63B5, 0x9D7D, + 0x63BB, 0x917E, 0x63BE, 0x9D81, 0x63C0, 0x9D83, 0x63C3, 0x91B5, + 0x63C4, 0x9D89, 0x63C6, 0x9D84, 0x63C9, 0x9D86, 0x63CF, 0x9560, + 0x63D0, 0x92F1, 0x63D2, 0x9D87, 0x63D6, 0x974B, 0x63DA, 0x9767, + 0x63DB, 0x8AB7, 0x63E1, 0x88AC, 0x63E3, 0x9D85, 0x63E9, 0x9D82, + 0x63EE, 0x8AF6, 0x63F4, 0x8987, 0x63F5, 0xFAC9, 0x63F6, 0x9D88, + 0x63FA, 0x9768, 0x6406, 0x9D8C, 0x640D, 0x91B9, 0x640F, 0x9D93, + 0x6413, 0x9D8D, 0x6416, 0x9D8A, 0x6417, 0x9D91, 0x641C, 0x9D72, + 0x6426, 0x9D8E, 0x6428, 0x9D92, 0x642C, 0x94C0, 0x642D, 0x938B, + 0x6434, 0x9D8B, 0x6436, 0x9D8F, 0x643A, 0x8C67, 0x643E, 0x8DEF, + 0x6442, 0x90DB, 0x644E, 0x9D97, 0x6458, 0x9345, 0x6460, 0xFACA, + 0x6467, 0x9D94, 0x6469, 0x9680, 0x646F, 0x9D95, 0x6476, 0x9D96, + 0x6478, 0x96CC, 0x647A, 0x90A0, 0x6483, 0x8C82, 0x6488, 0x9D9D, + 0x6492, 0x8E54, 0x6493, 0x9D9A, 0x6495, 0x9D99, 0x649A, 0x9451, + 0x649D, 0xFACB, 0x649E, 0x93B3, 0x64A4, 0x9350, 0x64A5, 0x9D9B, + 0x64A9, 0x9D9C, 0x64AB, 0x958F, 0x64AD, 0x9464, 0x64AE, 0x8E42, + 0x64B0, 0x90EF, 0x64B2, 0x966F, 0x64B9, 0x8A68, 0x64BB, 0x9DA3, + 0x64BC, 0x9D9E, 0x64C1, 0x9769, 0x64C2, 0x9DA5, 0x64C5, 0x9DA1, + 0x64C7, 0x9DA2, 0x64CD, 0x9180, 0x64CE, 0xFACC, 0x64D2, 0x9DA0, + 0x64D4, 0x9D5E, 0x64D8, 0x9DA4, 0x64DA, 0x9D9F, 0x64E0, 0x9DA9, + 0x64E1, 0x9DAA, 0x64E2, 0x9346, 0x64E3, 0x9DAC, 0x64E6, 0x8E43, + 0x64E7, 0x9DA7, 0x64EC, 0x8B5B, 0x64EF, 0x9DAD, 0x64F1, 0x9DA6, + 0x64F2, 0x9DB1, 0x64F4, 0x9DB0, 0x64F6, 0x9DAF, 0x64FA, 0x9DB2, + 0x64FD, 0x9DB4, 0x64FE, 0x8FEF, 0x6500, 0x9DB3, 0x6505, 0x9DB7, + 0x6518, 0x9DB5, 0x651C, 0x9DB6, 0x651D, 0x9D90, 0x6523, 0x9DB9, + 0x6524, 0x9DB8, 0x652A, 0x9D98, 0x652B, 0x9DBA, 0x652C, 0x9DAE, + 0x652F, 0x8E78, 0x6534, 0x9DBB, 0x6535, 0x9DBC, 0x6536, 0x9DBE, + 0x6537, 0x9DBD, 0x6538, 0x9DBF, 0x6539, 0x89FC, 0x653B, 0x8D55, + 0x653E, 0x95FA, 0x653F, 0x90AD, 0x6545, 0x8CCC, 0x6548, 0x9DC1, + 0x654D, 0x9DC4, 0x654E, 0xFACD, 0x654F, 0x9571, 0x6551, 0x8B7E, + 0x6555, 0x9DC3, 0x6556, 0x9DC2, 0x6557, 0x9473, 0x6558, 0x9DC5, + 0x6559, 0x8BB3, 0x655D, 0x9DC7, 0x655E, 0x9DC6, 0x6562, 0x8AB8, + 0x6563, 0x8E55, 0x6566, 0x93D6, 0x656C, 0x8C68, 0x6570, 0x9094, + 0x6572, 0x9DC8, 0x6574, 0x90AE, 0x6575, 0x9347, 0x6577, 0x957E, + 0x6578, 0x9DC9, 0x6582, 0x9DCA, 0x6583, 0x9DCB, 0x6587, 0x95B6, + 0x6588, 0x9B7C, 0x6589, 0x90C4, 0x658C, 0x956B, 0x658E, 0x8DD6, + 0x6590, 0x94E3, 0x6591, 0x94C1, 0x6597, 0x936C, 0x6599, 0x97BF, + 0x659B, 0x9DCD, 0x659C, 0x8ECE, 0x659F, 0x9DCE, 0x65A1, 0x88B4, + 0x65A4, 0x8BD2, 0x65A5, 0x90CB, 0x65A7, 0x9580, 0x65AB, 0x9DCF, + 0x65AC, 0x8E61, 0x65AD, 0x9266, 0x65AF, 0x8E7A, 0x65B0, 0x9056, + 0x65B7, 0x9DD0, 0x65B9, 0x95FB, 0x65BC, 0x8997, 0x65BD, 0x8E7B, + 0x65C1, 0x9DD3, 0x65C3, 0x9DD1, 0x65C4, 0x9DD4, 0x65C5, 0x97B7, + 0x65C6, 0x9DD2, 0x65CB, 0x90F9, 0x65CC, 0x9DD5, 0x65CF, 0x91B0, + 0x65D2, 0x9DD6, 0x65D7, 0x8AF8, 0x65D9, 0x9DD8, 0x65DB, 0x9DD7, + 0x65E0, 0x9DD9, 0x65E1, 0x9DDA, 0x65E2, 0x8AF9, 0x65E5, 0x93FA, + 0x65E6, 0x9255, 0x65E7, 0x8B8C, 0x65E8, 0x8E7C, 0x65E9, 0x9181, + 0x65EC, 0x8F7B, 0x65ED, 0x88AE, 0x65F1, 0x9DDB, 0x65FA, 0x89A0, + 0x65FB, 0x9DDF, 0x6600, 0xFACE, 0x6602, 0x8D56, 0x6603, 0x9DDE, + 0x6606, 0x8DA9, 0x6607, 0x8FB8, 0x6609, 0xFAD1, 0x660A, 0x9DDD, + 0x660C, 0x8FB9, 0x660E, 0x96BE, 0x660F, 0x8DA8, 0x6613, 0x88D5, + 0x6614, 0x90CC, 0x6615, 0xFACF, 0x661C, 0x9DE4, 0x661E, 0xFAD3, + 0x661F, 0x90AF, 0x6620, 0x8966, 0x6624, 0xFAD4, 0x6625, 0x8F74, + 0x6627, 0x9686, 0x6628, 0x8DF0, 0x662D, 0x8FBA, 0x662E, 0xFAD2, + 0x662F, 0x90A5, 0x6631, 0xFA63, 0x6634, 0x9DE3, 0x6635, 0x9DE1, + 0x6636, 0x9DE2, 0x663B, 0xFAD0, 0x663C, 0x928B, 0x663F, 0x9E45, + 0x6641, 0x9DE8, 0x6642, 0x8E9E, 0x6643, 0x8D57, 0x6644, 0x9DE6, + 0x6649, 0x9DE7, 0x664B, 0x9057, 0x664F, 0x9DE5, 0x6652, 0x8E4E, + 0x6657, 0xFAD6, 0x6659, 0xFAD7, 0x665D, 0x9DEA, 0x665E, 0x9DE9, + 0x665F, 0x9DEE, 0x6662, 0x9DEF, 0x6664, 0x9DEB, 0x6665, 0xFAD5, + 0x6666, 0x8A41, 0x6667, 0x9DEC, 0x6668, 0x9DED, 0x6669, 0x94D3, + 0x666E, 0x9581, 0x666F, 0x8C69, 0x6670, 0x9DF0, 0x6673, 0xFAD9, + 0x6674, 0x90B0, 0x6676, 0x8FBB, 0x667A, 0x9271, 0x6681, 0x8BC5, + 0x6683, 0x9DF1, 0x6684, 0x9DF5, 0x6687, 0x89C9, 0x6688, 0x9DF2, + 0x6689, 0x9DF4, 0x668E, 0x9DF3, 0x6691, 0x8F8B, 0x6696, 0x9267, + 0x6697, 0x88C3, 0x6698, 0x9DF6, 0x6699, 0xFADA, 0x669D, 0x9DF7, + 0x66A0, 0xFADB, 0x66A2, 0x92A8, 0x66A6, 0x97EF, 0x66AB, 0x8E62, + 0x66AE, 0x95E9, 0x66B2, 0xFADC, 0x66B4, 0x965C, 0x66B8, 0x9E41, + 0x66B9, 0x9DF9, 0x66BC, 0x9DFC, 0x66BE, 0x9DFB, 0x66BF, 0xFADD, + 0x66C1, 0x9DF8, 0x66C4, 0x9E40, 0x66C7, 0x93DC, 0x66C9, 0x9DFA, + 0x66D6, 0x9E42, 0x66D9, 0x8F8C, 0x66DA, 0x9E43, 0x66DC, 0x976A, + 0x66DD, 0x9498, 0x66E0, 0x9E44, 0x66E6, 0x9E46, 0x66E9, 0x9E47, + 0x66F0, 0x9E48, 0x66F2, 0x8BC8, 0x66F3, 0x8967, 0x66F4, 0x8D58, + 0x66F5, 0x9E49, 0x66F7, 0x9E4A, 0x66F8, 0x8F91, 0x66F9, 0x9182, + 0x66FA, 0xFADE, 0x66FB, 0xFA66, 0x66FC, 0x99D6, 0x66FD, 0x915D, + 0x66FE, 0x915C, 0x66FF, 0x91D6, 0x6700, 0x8DC5, 0x6703, 0x98F0, + 0x6708, 0x8C8E, 0x6709, 0x974C, 0x670B, 0x95FC, 0x670D, 0x959E, + 0x670E, 0xFADF, 0x670F, 0x9E4B, 0x6714, 0x8DF1, 0x6715, 0x92BD, + 0x6716, 0x9E4C, 0x6717, 0x984E, 0x671B, 0x965D, 0x671D, 0x92A9, + 0x671E, 0x9E4D, 0x671F, 0x8AFA, 0x6726, 0x9E4E, 0x6727, 0x9E4F, + 0x6728, 0x96D8, 0x672A, 0x96A2, 0x672B, 0x9696, 0x672C, 0x967B, + 0x672D, 0x8E44, 0x672E, 0x9E51, 0x6731, 0x8EE9, 0x6734, 0x9670, + 0x6736, 0x9E53, 0x6737, 0x9E56, 0x6738, 0x9E55, 0x673A, 0x8AF7, + 0x673D, 0x8B80, 0x673F, 0x9E52, 0x6741, 0x9E54, 0x6746, 0x9E57, + 0x6749, 0x9099, 0x674E, 0x979B, 0x674F, 0x88C7, 0x6750, 0x8DDE, + 0x6751, 0x91BA, 0x6753, 0x8EDB, 0x6756, 0x8FF1, 0x6759, 0x9E5A, + 0x675C, 0x936D, 0x675E, 0x9E58, 0x675F, 0x91A9, 0x6760, 0x9E59, + 0x6761, 0x8FF0, 0x6762, 0x96DB, 0x6763, 0x9E5B, 0x6764, 0x9E5C, + 0x6765, 0x9788, 0x6766, 0xFAE1, 0x676A, 0x9E61, 0x676D, 0x8D59, + 0x676F, 0x9474, 0x6770, 0x9E5E, 0x6771, 0x938C, 0x6772, 0x9DDC, + 0x6773, 0x9DE0, 0x6775, 0x8B6E, 0x6777, 0x9466, 0x677C, 0x9E60, + 0x677E, 0x8FBC, 0x677F, 0x94C2, 0x6785, 0x9E66, 0x6787, 0x94F8, + 0x6789, 0x9E5D, 0x678B, 0x9E63, 0x678C, 0x9E62, 0x6790, 0x90CD, + 0x6795, 0x968D, 0x6797, 0x97D1, 0x679A, 0x9687, 0x679C, 0x89CA, + 0x679D, 0x8E7D, 0x67A0, 0x9867, 0x67A1, 0x9E65, 0x67A2, 0x9095, + 0x67A6, 0x9E64, 0x67A9, 0x9E5F, 0x67AF, 0x8CCD, 0x67B3, 0x9E6B, + 0x67B4, 0x9E69, 0x67B6, 0x89CB, 0x67B7, 0x9E67, 0x67B8, 0x9E6D, + 0x67B9, 0x9E73, 0x67BB, 0xFAE2, 0x67C0, 0xFAE4, 0x67C1, 0x91C6, + 0x67C4, 0x95BF, 0x67C6, 0x9E75, 0x67CA, 0x9541, 0x67CE, 0x9E74, + 0x67CF, 0x9490, 0x67D0, 0x965E, 0x67D1, 0x8AB9, 0x67D3, 0x90F5, + 0x67D4, 0x8F5F, 0x67D8, 0x92D1, 0x67DA, 0x974D, 0x67DD, 0x9E70, + 0x67DE, 0x9E6F, 0x67E2, 0x9E71, 0x67E4, 0x9E6E, 0x67E7, 0x9E76, + 0x67E9, 0x9E6C, 0x67EC, 0x9E6A, 0x67EE, 0x9E72, 0x67EF, 0x9E68, + 0x67F1, 0x928C, 0x67F3, 0x96F6, 0x67F4, 0x8EC4, 0x67F5, 0x8DF2, + 0x67FB, 0x8DB8, 0x67FE, 0x968F, 0x67FF, 0x8A60, 0x6801, 0xFAE5, + 0x6802, 0x92CC, 0x6803, 0x93C8, 0x6804, 0x8968, 0x6813, 0x90F0, + 0x6816, 0x90B2, 0x6817, 0x8C49, 0x681E, 0x9E78, 0x6821, 0x8D5A, + 0x6822, 0x8A9C, 0x6829, 0x9E7A, 0x682A, 0x8A94, 0x682B, 0x9E81, + 0x6832, 0x9E7D, 0x6834, 0x90F1, 0x6838, 0x8A6A, 0x6839, 0x8DAA, + 0x683C, 0x8A69, 0x683D, 0x8DCD, 0x6840, 0x9E7B, 0x6841, 0x8C85, + 0x6842, 0x8C6A, 0x6843, 0x938D, 0x6844, 0xFAE6, 0x6846, 0x9E79, + 0x6848, 0x88C4, 0x684D, 0x9E7C, 0x684E, 0x9E7E, 0x6850, 0x8BCB, + 0x6851, 0x8C4B, 0x6852, 0xFAE3, 0x6853, 0x8ABA, 0x6854, 0x8B6A, + 0x6859, 0x9E82, 0x685C, 0x8DF7, 0x685D, 0x9691, 0x685F, 0x8E56, + 0x6863, 0x9E83, 0x6867, 0x954F, 0x6874, 0x9E8F, 0x6876, 0x89B1, + 0x6877, 0x9E84, 0x687E, 0x9E95, 0x687F, 0x9E85, 0x6881, 0x97C0, + 0x6883, 0x9E8C, 0x6885, 0x947E, 0x688D, 0x9E94, 0x688F, 0x9E87, + 0x6893, 0x88B2, 0x6894, 0x9E89, 0x6897, 0x8D5B, 0x689B, 0x9E8B, + 0x689D, 0x9E8A, 0x689F, 0x9E86, 0x68A0, 0x9E91, 0x68A2, 0x8FBD, + 0x68A6, 0x9AEB, 0x68A7, 0x8CE6, 0x68A8, 0x979C, 0x68AD, 0x9E88, + 0x68AF, 0x92F2, 0x68B0, 0x8A42, 0x68B1, 0x8DAB, 0x68B3, 0x9E80, + 0x68B5, 0x9E90, 0x68B6, 0x8A81, 0x68B9, 0x9E8E, 0x68BA, 0x9E92, + 0x68BC, 0x938E, 0x68C4, 0x8AFC, 0x68C6, 0x9EB0, 0x68C8, 0xFA64, + 0x68C9, 0x96C7, 0x68CA, 0x9E97, 0x68CB, 0x8AFB, 0x68CD, 0x9E9E, + 0x68CF, 0xFAE7, 0x68D2, 0x965F, 0x68D4, 0x9E9F, 0x68D5, 0x9EA1, + 0x68D7, 0x9EA5, 0x68D8, 0x9E99, 0x68DA, 0x9249, 0x68DF, 0x938F, + 0x68E0, 0x9EA9, 0x68E1, 0x9E9C, 0x68E3, 0x9EA6, 0x68E7, 0x9EA0, + 0x68EE, 0x9058, 0x68EF, 0x9EAA, 0x68F2, 0x90B1, 0x68F9, 0x9EA8, + 0x68FA, 0x8ABB, 0x6900, 0x986F, 0x6901, 0x9E96, 0x6904, 0x9EA4, + 0x6905, 0x88D6, 0x6908, 0x9E98, 0x690B, 0x96B8, 0x690C, 0x9E9D, + 0x690D, 0x9041, 0x690E, 0x92C5, 0x690F, 0x9E93, 0x6912, 0x9EA3, + 0x6919, 0x909A, 0x691A, 0x9EAD, 0x691B, 0x8A91, 0x691C, 0x8C9F, + 0x6921, 0x9EAF, 0x6922, 0x9E9A, 0x6923, 0x9EAE, 0x6925, 0x9EA7, + 0x6926, 0x9E9B, 0x6928, 0x9EAB, 0x692A, 0x9EAC, 0x6930, 0x9EBD, + 0x6934, 0x93CC, 0x6936, 0x9EA2, 0x6939, 0x9EB9, 0x693D, 0x9EBB, + 0x693F, 0x92D6, 0x694A, 0x976B, 0x6953, 0x9596, 0x6954, 0x9EB6, + 0x6955, 0x91C8, 0x6959, 0x9EBC, 0x695A, 0x915E, 0x695C, 0x9EB3, + 0x695D, 0x9EC0, 0x695E, 0x9EBF, 0x6960, 0x93ED, 0x6961, 0x9EBE, + 0x6962, 0x93E8, 0x6968, 0xFAE9, 0x696A, 0x9EC2, 0x696B, 0x9EB5, + 0x696D, 0x8BC6, 0x696E, 0x9EB8, 0x696F, 0x8F7C, 0x6973, 0x9480, + 0x6974, 0x9EBA, 0x6975, 0x8BC9, 0x6977, 0x9EB2, 0x6978, 0x9EB4, + 0x6979, 0x9EB1, 0x697C, 0x984F, 0x697D, 0x8A79, 0x697E, 0x9EB7, + 0x6981, 0x9EC1, 0x6982, 0x8A54, 0x698A, 0x8DE5, 0x698E, 0x897C, + 0x6991, 0x9ED2, 0x6994, 0x9850, 0x6995, 0x9ED5, 0x6998, 0xFAEB, + 0x699B, 0x9059, 0x699C, 0x9ED4, 0x69A0, 0x9ED3, 0x69A7, 0x9ED0, + 0x69AE, 0x9EC4, 0x69B1, 0x9EE1, 0x69B2, 0x9EC3, 0x69B4, 0x9ED6, + 0x69BB, 0x9ECE, 0x69BE, 0x9EC9, 0x69BF, 0x9EC6, 0x69C1, 0x9EC7, + 0x69C3, 0x9ECF, 0x69C7, 0xEAA0, 0x69CA, 0x9ECC, 0x69CB, 0x8D5C, + 0x69CC, 0x92C6, 0x69CD, 0x9184, 0x69CE, 0x9ECA, 0x69D0, 0x9EC5, + 0x69D3, 0x9EC8, 0x69D8, 0x976C, 0x69D9, 0x968A, 0x69DD, 0x9ECD, + 0x69DE, 0x9ED7, 0x69E2, 0xFAEC, 0x69E7, 0x9EDF, 0x69E8, 0x9ED8, + 0x69EB, 0x9EE5, 0x69ED, 0x9EE3, 0x69F2, 0x9EDE, 0x69F9, 0x9EDD, + 0x69FB, 0x92CE, 0x69FD, 0x9185, 0x69FF, 0x9EDB, 0x6A02, 0x9ED9, + 0x6A05, 0x9EE0, 0x6A0A, 0x9EE6, 0x6A0B, 0x94F3, 0x6A0C, 0x9EEC, + 0x6A12, 0x9EE7, 0x6A13, 0x9EEA, 0x6A14, 0x9EE4, 0x6A17, 0x9294, + 0x6A19, 0x9557, 0x6A1B, 0x9EDA, 0x6A1E, 0x9EE2, 0x6A1F, 0x8FBE, + 0x6A21, 0x96CD, 0x6A22, 0x9EF6, 0x6A23, 0x9EE9, 0x6A29, 0x8CA0, + 0x6A2A, 0x89A1, 0x6A2B, 0x8A7E, 0x6A2E, 0x9ED1, 0x6A30, 0xFAED, + 0x6A35, 0x8FBF, 0x6A36, 0x9EEE, 0x6A38, 0x9EF5, 0x6A39, 0x8EF7, + 0x6A3A, 0x8A92, 0x6A3D, 0x924D, 0x6A44, 0x9EEB, 0x6A46, 0xFAEF, + 0x6A47, 0x9EF0, 0x6A48, 0x9EF4, 0x6A4B, 0x8BB4, 0x6A58, 0x8B6B, + 0x6A59, 0x9EF2, 0x6A5F, 0x8B40, 0x6A61, 0x93C9, 0x6A62, 0x9EF1, + 0x6A66, 0x9EF3, 0x6A6B, 0xFAEE, 0x6A72, 0x9EED, 0x6A73, 0xFAF0, + 0x6A78, 0x9EEF, 0x6A7E, 0xFAF1, 0x6A7F, 0x8A80, 0x6A80, 0x9268, + 0x6A84, 0x9EFA, 0x6A8D, 0x9EF8, 0x6A8E, 0x8CE7, 0x6A90, 0x9EF7, + 0x6A97, 0x9F40, 0x6A9C, 0x9E77, 0x6AA0, 0x9EF9, 0x6AA2, 0x9EFB, + 0x6AA3, 0x9EFC, 0x6AAA, 0x9F4B, 0x6AAC, 0x9F47, 0x6AAE, 0x9E8D, + 0x6AB3, 0x9F46, 0x6AB8, 0x9F45, 0x6ABB, 0x9F42, 0x6AC1, 0x9EE8, + 0x6AC2, 0x9F44, 0x6AC3, 0x9F43, 0x6AD1, 0x9F49, 0x6AD3, 0x9845, + 0x6ADA, 0x9F4C, 0x6ADB, 0x8BF9, 0x6ADE, 0x9F48, 0x6ADF, 0x9F4A, + 0x6AE2, 0xFAF2, 0x6AE4, 0xFAF3, 0x6AE8, 0x94A5, 0x6AEA, 0x9F4D, + 0x6AFA, 0x9F51, 0x6AFB, 0x9F4E, 0x6B04, 0x9793, 0x6B05, 0x9F4F, + 0x6B0A, 0x9EDC, 0x6B12, 0x9F52, 0x6B16, 0x9F53, 0x6B1D, 0x8954, + 0x6B1F, 0x9F55, 0x6B20, 0x8C87, 0x6B21, 0x8E9F, 0x6B23, 0x8BD3, + 0x6B27, 0x89A2, 0x6B32, 0x977E, 0x6B37, 0x9F57, 0x6B38, 0x9F56, + 0x6B39, 0x9F59, 0x6B3A, 0x8B5C, 0x6B3D, 0x8BD4, 0x6B3E, 0x8ABC, + 0x6B43, 0x9F5C, 0x6B47, 0x9F5B, 0x6B49, 0x9F5D, 0x6B4C, 0x89CC, + 0x6B4E, 0x9256, 0x6B50, 0x9F5E, 0x6B53, 0x8ABD, 0x6B54, 0x9F60, + 0x6B59, 0x9F5F, 0x6B5B, 0x9F61, 0x6B5F, 0x9F62, 0x6B61, 0x9F63, + 0x6B62, 0x8E7E, 0x6B63, 0x90B3, 0x6B64, 0x8D9F, 0x6B66, 0x9590, + 0x6B69, 0x95E0, 0x6B6A, 0x9863, 0x6B6F, 0x8E95, 0x6B73, 0x8DCE, + 0x6B74, 0x97F0, 0x6B78, 0x9F64, 0x6B79, 0x9F65, 0x6B7B, 0x8E80, + 0x6B7F, 0x9F66, 0x6B80, 0x9F67, 0x6B83, 0x9F69, 0x6B84, 0x9F68, + 0x6B86, 0x9677, 0x6B89, 0x8F7D, 0x6B8A, 0x8EEA, 0x6B8B, 0x8E63, + 0x6B8D, 0x9F6A, 0x6B95, 0x9F6C, 0x6B96, 0x9042, 0x6B98, 0x9F6B, + 0x6B9E, 0x9F6D, 0x6BA4, 0x9F6E, 0x6BAA, 0x9F6F, 0x6BAB, 0x9F70, + 0x6BAF, 0x9F71, 0x6BB1, 0x9F73, 0x6BB2, 0x9F72, 0x6BB3, 0x9F74, + 0x6BB4, 0x89A3, 0x6BB5, 0x9269, 0x6BB7, 0x9F75, 0x6BBA, 0x8E45, + 0x6BBB, 0x8A6B, 0x6BBC, 0x9F76, 0x6BBF, 0x9361, 0x6BC0, 0x9ACA, + 0x6BC5, 0x8B42, 0x6BC6, 0x9F77, 0x6BCB, 0x9F78, 0x6BCD, 0x95EA, + 0x6BCE, 0x9688, 0x6BD2, 0x93C5, 0x6BD3, 0x9F79, 0x6BD4, 0x94E4, + 0x6BD6, 0xFAF4, 0x6BD8, 0x94F9, 0x6BDB, 0x96D1, 0x6BDF, 0x9F7A, + 0x6BEB, 0x9F7C, 0x6BEC, 0x9F7B, 0x6BEF, 0x9F7E, 0x6BF3, 0x9F7D, + 0x6C08, 0x9F81, 0x6C0F, 0x8E81, 0x6C11, 0x96AF, 0x6C13, 0x9F82, + 0x6C14, 0x9F83, 0x6C17, 0x8B43, 0x6C1B, 0x9F84, 0x6C23, 0x9F86, + 0x6C24, 0x9F85, 0x6C34, 0x9085, 0x6C37, 0x9558, 0x6C38, 0x8969, + 0x6C3E, 0x94C3, 0x6C3F, 0xFAF5, 0x6C40, 0x92F3, 0x6C41, 0x8F60, + 0x6C42, 0x8B81, 0x6C4E, 0x94C4, 0x6C50, 0x8EAC, 0x6C55, 0x9F88, + 0x6C57, 0x8ABE, 0x6C5A, 0x8998, 0x6C5C, 0xFAF6, 0x6C5D, 0x93F0, + 0x6C5E, 0x9F87, 0x6C5F, 0x8D5D, 0x6C60, 0x9272, 0x6C62, 0x9F89, + 0x6C68, 0x9F91, 0x6C6A, 0x9F8A, 0x6C6F, 0xFAF8, 0x6C70, 0x91BF, + 0x6C72, 0x8B82, 0x6C73, 0x9F92, 0x6C7A, 0x8C88, 0x6C7D, 0x8B44, + 0x6C7E, 0x9F90, 0x6C81, 0x9F8E, 0x6C82, 0x9F8B, 0x6C83, 0x9780, + 0x6C86, 0xFAF7, 0x6C88, 0x92BE, 0x6C8C, 0x93D7, 0x6C8D, 0x9F8C, + 0x6C90, 0x9F94, 0x6C92, 0x9F93, 0x6C93, 0x8C42, 0x6C96, 0x89AB, + 0x6C99, 0x8DB9, 0x6C9A, 0x9F8D, 0x6C9B, 0x9F8F, 0x6CA1, 0x9676, + 0x6CA2, 0x91F2, 0x6CAB, 0x9697, 0x6CAE, 0x9F9C, 0x6CB1, 0x9F9D, + 0x6CB3, 0x89CD, 0x6CB8, 0x95A6, 0x6CB9, 0x96FB, 0x6CBA, 0x9F9F, + 0x6CBB, 0x8EA1, 0x6CBC, 0x8FC0, 0x6CBD, 0x9F98, 0x6CBE, 0x9F9E, + 0x6CBF, 0x8988, 0x6CC1, 0x8BB5, 0x6CC4, 0x9F95, 0x6CC5, 0x9F9A, + 0x6CC9, 0x90F2, 0x6CCA, 0x9491, 0x6CCC, 0x94E5, 0x6CD3, 0x9F97, + 0x6CD5, 0x9640, 0x6CD7, 0x9F99, 0x6CD9, 0x9FA2, 0x6CDA, 0xFAF9, + 0x6CDB, 0x9FA0, 0x6CDD, 0x9F9B, 0x6CE1, 0x9641, 0x6CE2, 0x9467, + 0x6CE3, 0x8B83, 0x6CE5, 0x9344, 0x6CE8, 0x928D, 0x6CEA, 0x9FA3, + 0x6CEF, 0x9FA1, 0x6CF0, 0x91D7, 0x6CF1, 0x9F96, 0x6CF3, 0x896A, + 0x6D04, 0xFAFA, 0x6D0B, 0x976D, 0x6D0C, 0x9FAE, 0x6D12, 0x9FAD, + 0x6D17, 0x90F4, 0x6D19, 0x9FAA, 0x6D1B, 0x978C, 0x6D1E, 0x93B4, + 0x6D1F, 0x9FA4, 0x6D25, 0x92C3, 0x6D29, 0x896B, 0x6D2A, 0x8D5E, + 0x6D2B, 0x9FA7, 0x6D32, 0x8F46, 0x6D33, 0x9FAC, 0x6D35, 0x9FAB, + 0x6D36, 0x9FA6, 0x6D38, 0x9FA9, 0x6D3B, 0x8A88, 0x6D3D, 0x9FA8, + 0x6D3E, 0x9468, 0x6D41, 0x97AC, 0x6D44, 0x8FF2, 0x6D45, 0x90F3, + 0x6D59, 0x9FB4, 0x6D5A, 0x9FB2, 0x6D5C, 0x956C, 0x6D63, 0x9FAF, + 0x6D64, 0x9FB1, 0x6D66, 0x8959, 0x6D69, 0x8D5F, 0x6D6A, 0x9851, + 0x6D6C, 0x8A5C, 0x6D6E, 0x9582, 0x6D6F, 0xFAFC, 0x6D74, 0x9781, + 0x6D77, 0x8A43, 0x6D78, 0x905A, 0x6D79, 0x9FB3, 0x6D85, 0x9FB8, + 0x6D87, 0xFAFB, 0x6D88, 0x8FC1, 0x6D8C, 0x974F, 0x6D8E, 0x9FB5, + 0x6D93, 0x9FB0, 0x6D95, 0x9FB6, 0x6D96, 0xFB40, 0x6D99, 0x97DC, + 0x6D9B, 0x9393, 0x6D9C, 0x93C0, 0x6DAC, 0xFB41, 0x6DAF, 0x8A55, + 0x6DB2, 0x8974, 0x6DB5, 0x9FBC, 0x6DB8, 0x9FBF, 0x6DBC, 0x97C1, + 0x6DC0, 0x9784, 0x6DC5, 0x9FC6, 0x6DC6, 0x9FC0, 0x6DC7, 0x9FBD, + 0x6DCB, 0x97D2, 0x6DCC, 0x9FC3, 0x6DCF, 0xFB42, 0x6DD1, 0x8F69, + 0x6DD2, 0x9FC5, 0x6DD5, 0x9FCA, 0x6DD8, 0x9391, 0x6DD9, 0x9FC8, + 0x6DDE, 0x9FC2, 0x6DE1, 0x9257, 0x6DE4, 0x9FC9, 0x6DE6, 0x9FBE, + 0x6DE8, 0x9FC4, 0x6DEA, 0x9FCB, 0x6DEB, 0x88FA, 0x6DEC, 0x9FC1, + 0x6DEE, 0x9FCC, 0x6DF1, 0x905B, 0x6DF2, 0xFB44, 0x6DF3, 0x8F7E, + 0x6DF5, 0x95A3, 0x6DF7, 0x8DAC, 0x6DF8, 0xFB43, 0x6DF9, 0x9FB9, + 0x6DFA, 0x9FC7, 0x6DFB, 0x9359, 0x6DFC, 0xFB45, 0x6E05, 0x90B4, + 0x6E07, 0x8A89, 0x6E08, 0x8DCF, 0x6E09, 0x8FC2, 0x6E0A, 0x9FBB, + 0x6E0B, 0x8F61, 0x6E13, 0x8C6B, 0x6E15, 0x9FBA, 0x6E19, 0x9FD0, + 0x6E1A, 0x8F8D, 0x6E1B, 0x8CB8, 0x6E1D, 0x9FDF, 0x6E1F, 0x9FD9, + 0x6E20, 0x8B94, 0x6E21, 0x936E, 0x6E23, 0x9FD4, 0x6E24, 0x9FDD, + 0x6E25, 0x88AD, 0x6E26, 0x8951, 0x6E27, 0xFB48, 0x6E29, 0x89B7, + 0x6E2B, 0x9FD6, 0x6E2C, 0x91AA, 0x6E2D, 0x9FCD, 0x6E2E, 0x9FCF, + 0x6E2F, 0x8D60, 0x6E38, 0x9FE0, 0x6E39, 0xFB46, 0x6E3A, 0x9FDB, + 0x6E3C, 0xFB49, 0x6E3E, 0x9FD3, 0x6E43, 0x9FDA, 0x6E4A, 0x96A9, + 0x6E4D, 0x9FD8, 0x6E4E, 0x9FDC, 0x6E56, 0x8CCE, 0x6E58, 0x8FC3, + 0x6E5B, 0x9258, 0x6E5C, 0xFB47, 0x6E5F, 0x9FD2, 0x6E67, 0x974E, + 0x6E6B, 0x9FD5, 0x6E6E, 0x9FCE, 0x6E6F, 0x9392, 0x6E72, 0x9FD1, + 0x6E76, 0x9FD7, 0x6E7E, 0x9870, 0x6E7F, 0x8EBC, 0x6E80, 0x969E, + 0x6E82, 0x9FE1, 0x6E8C, 0x94AC, 0x6E8F, 0x9FED, 0x6E90, 0x8CB9, + 0x6E96, 0x8F80, 0x6E98, 0x9FE3, 0x6E9C, 0x97AD, 0x6E9D, 0x8D61, + 0x6E9F, 0x9FF0, 0x6EA2, 0x88EC, 0x6EA5, 0x9FEE, 0x6EAA, 0x9FE2, + 0x6EAF, 0x9FE8, 0x6EB2, 0x9FEA, 0x6EB6, 0x976E, 0x6EB7, 0x9FE5, + 0x6EBA, 0x934D, 0x6EBD, 0x9FE7, 0x6EBF, 0xFB4A, 0x6EC2, 0x9FEF, + 0x6EC4, 0x9FE9, 0x6EC5, 0x96C5, 0x6EC9, 0x9FE4, 0x6ECB, 0x8EA0, + 0x6ECC, 0x9FFC, 0x6ED1, 0x8A8A, 0x6ED3, 0x9FE6, 0x6ED4, 0x9FEB, + 0x6ED5, 0x9FEC, 0x6EDD, 0x91EA, 0x6EDE, 0x91D8, 0x6EEC, 0x9FF4, + 0x6EEF, 0x9FFA, 0x6EF2, 0x9FF8, 0x6EF4, 0x9348, 0x6EF7, 0xE042, + 0x6EF8, 0x9FF5, 0x6EFE, 0x9FF6, 0x6EFF, 0x9FDE, 0x6F01, 0x8B99, + 0x6F02, 0x9559, 0x6F06, 0x8EBD, 0x6F09, 0x8D97, 0x6F0F, 0x9852, + 0x6F11, 0x9FF2, 0x6F13, 0xE041, 0x6F14, 0x8989, 0x6F15, 0x9186, + 0x6F20, 0x9499, 0x6F22, 0x8ABF, 0x6F23, 0x97F8, 0x6F2B, 0x969F, + 0x6F2C, 0x92D0, 0x6F31, 0x9FF9, 0x6F32, 0x9FFB, 0x6F38, 0x9151, + 0x6F3E, 0xE040, 0x6F3F, 0x9FF7, 0x6F41, 0x9FF1, 0x6F45, 0x8AC1, + 0x6F54, 0x8C89, 0x6F58, 0xE04E, 0x6F5B, 0xE049, 0x6F5C, 0x90F6, + 0x6F5F, 0x8A83, 0x6F64, 0x8F81, 0x6F66, 0xE052, 0x6F6D, 0xE04B, + 0x6F6E, 0x92AA, 0x6F6F, 0xE048, 0x6F70, 0x92D7, 0x6F74, 0xE06B, + 0x6F78, 0xE045, 0x6F7A, 0xE044, 0x6F7C, 0xE04D, 0x6F80, 0xE047, + 0x6F81, 0xE046, 0x6F82, 0xE04C, 0x6F84, 0x909F, 0x6F86, 0xE043, + 0x6F88, 0xFB4B, 0x6F8E, 0xE04F, 0x6F91, 0xE050, 0x6F97, 0x8AC0, + 0x6FA1, 0xE055, 0x6FA3, 0xE054, 0x6FA4, 0xE056, 0x6FAA, 0xE059, + 0x6FB1, 0x9362, 0x6FB3, 0xE053, 0x6FB5, 0xFB4C, 0x6FB9, 0xE057, + 0x6FC0, 0x8C83, 0x6FC1, 0x91F7, 0x6FC2, 0xE051, 0x6FC3, 0x945A, + 0x6FC6, 0xE058, 0x6FD4, 0xE05D, 0x6FD5, 0xE05B, 0x6FD8, 0xE05E, + 0x6FDB, 0xE061, 0x6FDF, 0xE05A, 0x6FE0, 0x8D8A, 0x6FE1, 0x9447, + 0x6FE4, 0x9FB7, 0x6FEB, 0x9794, 0x6FEC, 0xE05C, 0x6FEE, 0xE060, + 0x6FEF, 0x91F3, 0x6FF1, 0xE05F, 0x6FF3, 0xE04A, 0x6FF5, 0xFB4D, + 0x6FF6, 0xE889, 0x6FFA, 0xE064, 0x6FFE, 0xE068, 0x7001, 0xE066, + 0x7005, 0xFB4E, 0x7007, 0xFB4F, 0x7009, 0xE062, 0x700B, 0xE063, + 0x700F, 0xE067, 0x7011, 0xE065, 0x7015, 0x956D, 0x7018, 0xE06D, + 0x701A, 0xE06A, 0x701B, 0xE069, 0x701D, 0xE06C, 0x701E, 0x93D2, + 0x701F, 0xE06E, 0x7026, 0x9295, 0x7027, 0x91EB, 0x7028, 0xFB50, + 0x702C, 0x90A3, 0x7030, 0xE06F, 0x7032, 0xE071, 0x703E, 0xE070, + 0x704C, 0x9FF3, 0x7051, 0xE072, 0x7058, 0x93E5, 0x7063, 0xE073, + 0x706B, 0x89CE, 0x706F, 0x9394, 0x7070, 0x8A44, 0x7078, 0x8B84, + 0x707C, 0x8EDC, 0x707D, 0x8DD0, 0x7085, 0xFB51, 0x7089, 0x9846, + 0x708A, 0x9086, 0x708E, 0x898A, 0x7092, 0xE075, 0x7099, 0xE074, + 0x70AB, 0xFB52, 0x70AC, 0xE078, 0x70AD, 0x9259, 0x70AE, 0xE07B, + 0x70AF, 0xE076, 0x70B3, 0xE07A, 0x70B8, 0xE079, 0x70B9, 0x935F, + 0x70BA, 0x88D7, 0x70BB, 0xFA62, 0x70C8, 0x97F3, 0x70CB, 0xE07D, + 0x70CF, 0x8947, 0x70D9, 0xE080, 0x70DD, 0xE07E, 0x70DF, 0xE07C, + 0x70F1, 0xE077, 0x70F9, 0x9642, 0x70FD, 0xE082, 0x7104, 0xFB54, + 0x7109, 0xE081, 0x710F, 0xFB53, 0x7114, 0x898B, 0x7119, 0xE084, + 0x711A, 0x95B0, 0x711C, 0xE083, 0x7121, 0x96B3, 0x7126, 0x8FC5, + 0x7136, 0x9152, 0x713C, 0x8FC4, 0x7146, 0xFB56, 0x7147, 0xFB57, + 0x7149, 0x97F9, 0x714C, 0xE08A, 0x714E, 0x90F7, 0x7155, 0xE086, + 0x7156, 0xE08B, 0x7159, 0x898C, 0x715C, 0xFB55, 0x7162, 0xE089, + 0x7164, 0x9481, 0x7165, 0xE085, 0x7166, 0xE088, 0x7167, 0x8FC6, + 0x7169, 0x94CF, 0x716C, 0xE08C, 0x716E, 0x8ECF, 0x717D, 0x90F8, + 0x7184, 0xE08F, 0x7188, 0xE087, 0x718A, 0x8C46, 0x718F, 0xE08D, + 0x7194, 0x976F, 0x7195, 0xE090, 0x7199, 0xEAA4, 0x719F, 0x8F6E, + 0x71A8, 0xE091, 0x71AC, 0xE092, 0x71B1, 0x944D, 0x71B9, 0xE094, + 0x71BE, 0xE095, 0x71C1, 0xFB59, 0x71C3, 0x9452, 0x71C8, 0x9395, + 0x71C9, 0xE097, 0x71CE, 0xE099, 0x71D0, 0x97D3, 0x71D2, 0xE096, + 0x71D4, 0xE098, 0x71D5, 0x898D, 0x71D7, 0xE093, 0x71DF, 0x9A7A, + 0x71E0, 0xE09A, 0x71E5, 0x9187, 0x71E6, 0x8E57, 0x71E7, 0xE09C, + 0x71EC, 0xE09B, 0x71ED, 0x9043, 0x71EE, 0x99D7, 0x71F5, 0xE09D, + 0x71F9, 0xE09F, 0x71FB, 0xE08E, 0x71FC, 0xE09E, 0x71FE, 0xFB5A, + 0x71FF, 0xE0A0, 0x7206, 0x949A, 0x720D, 0xE0A1, 0x7210, 0xE0A2, + 0x721B, 0xE0A3, 0x7228, 0xE0A4, 0x722A, 0x92DC, 0x722C, 0xE0A6, + 0x722D, 0xE0A5, 0x7230, 0xE0A7, 0x7232, 0xE0A8, 0x7235, 0x8EDD, + 0x7236, 0x9583, 0x723A, 0x96EA, 0x723B, 0xE0A9, 0x723C, 0xE0AA, + 0x723D, 0x9175, 0x723E, 0x8EA2, 0x723F, 0xE0AB, 0x7240, 0xE0AC, + 0x7246, 0xE0AD, 0x7247, 0x95D0, 0x7248, 0x94C5, 0x724B, 0xE0AE, + 0x724C, 0x9476, 0x7252, 0x92AB, 0x7258, 0xE0AF, 0x7259, 0x89E5, + 0x725B, 0x8B8D, 0x725D, 0x96C4, 0x725F, 0x96B4, 0x7261, 0x89B2, + 0x7262, 0x9853, 0x7267, 0x9671, 0x7269, 0x95A8, 0x7272, 0x90B5, + 0x7274, 0xE0B0, 0x7279, 0x93C1, 0x727D, 0x8CA1, 0x727E, 0xE0B1, + 0x7280, 0x8DD2, 0x7281, 0xE0B3, 0x7282, 0xE0B2, 0x7287, 0xE0B4, + 0x7292, 0xE0B5, 0x7296, 0xE0B6, 0x72A0, 0x8B5D, 0x72A2, 0xE0B7, + 0x72A7, 0xE0B8, 0x72AC, 0x8CA2, 0x72AF, 0x94C6, 0x72B1, 0xFB5B, + 0x72B2, 0xE0BA, 0x72B6, 0x8FF3, 0x72B9, 0xE0B9, 0x72BE, 0xFB5C, + 0x72C2, 0x8BB6, 0x72C3, 0xE0BB, 0x72C4, 0xE0BD, 0x72C6, 0xE0BC, + 0x72CE, 0xE0BE, 0x72D0, 0x8CCF, 0x72D2, 0xE0BF, 0x72D7, 0x8BE7, + 0x72D9, 0x915F, 0x72DB, 0x8D9D, 0x72E0, 0xE0C1, 0x72E1, 0xE0C2, + 0x72E2, 0xE0C0, 0x72E9, 0x8EEB, 0x72EC, 0x93C6, 0x72ED, 0x8BB7, + 0x72F7, 0xE0C4, 0x72F8, 0x924B, 0x72F9, 0xE0C3, 0x72FC, 0x9854, + 0x72FD, 0x9482, 0x730A, 0xE0C7, 0x7316, 0xE0C9, 0x7317, 0xE0C6, + 0x731B, 0x96D2, 0x731C, 0xE0C8, 0x731D, 0xE0CA, 0x731F, 0x97C2, + 0x7324, 0xFB5D, 0x7325, 0xE0CE, 0x7329, 0xE0CD, 0x732A, 0x9296, + 0x732B, 0x944C, 0x732E, 0x8CA3, 0x732F, 0xE0CC, 0x7334, 0xE0CB, + 0x7336, 0x9750, 0x7337, 0x9751, 0x733E, 0xE0CF, 0x733F, 0x898E, + 0x7344, 0x8D96, 0x7345, 0x8E82, 0x734E, 0xE0D0, 0x734F, 0xE0D1, + 0x7357, 0xE0D3, 0x7363, 0x8F62, 0x7368, 0xE0D5, 0x736A, 0xE0D4, + 0x7370, 0xE0D6, 0x7372, 0x8A6C, 0x7375, 0xE0D8, 0x7377, 0xFB5F, + 0x7378, 0xE0D7, 0x737A, 0xE0DA, 0x737B, 0xE0D9, 0x7384, 0x8CBA, + 0x7387, 0x97A6, 0x7389, 0x8BCA, 0x738B, 0x89A4, 0x7396, 0x8BE8, + 0x73A9, 0x8ADF, 0x73B2, 0x97E6, 0x73B3, 0xE0DC, 0x73BB, 0xE0DE, + 0x73BD, 0xFB60, 0x73C0, 0xE0DF, 0x73C2, 0x89CF, 0x73C8, 0xE0DB, + 0x73C9, 0xFB61, 0x73CA, 0x8E58, 0x73CD, 0x92BF, 0x73CE, 0xE0DD, + 0x73D2, 0xFB64, 0x73D6, 0xFB62, 0x73DE, 0xE0E2, 0x73E0, 0x8EEC, + 0x73E3, 0xFB63, 0x73E5, 0xE0E0, 0x73EA, 0x8C5D, 0x73ED, 0x94C7, + 0x73EE, 0xE0E1, 0x73F1, 0xE0FC, 0x73F5, 0xFB66, 0x73F8, 0xE0E7, + 0x73FE, 0x8CBB, 0x7403, 0x8B85, 0x7405, 0xE0E4, 0x7406, 0x979D, + 0x7407, 0xFB65, 0x7409, 0x97AE, 0x7422, 0x91F4, 0x7425, 0xE0E6, + 0x7426, 0xFB67, 0x7429, 0xFB69, 0x742A, 0xFB68, 0x742E, 0xFB6A, + 0x7432, 0xE0E8, 0x7433, 0x97D4, 0x7434, 0x8BD5, 0x7435, 0x94FA, + 0x7436, 0x9469, 0x743A, 0xE0E9, 0x743F, 0xE0EB, 0x7441, 0xE0EE, + 0x7455, 0xE0EA, 0x7459, 0xE0ED, 0x745A, 0x8CE8, 0x745B, 0x896C, + 0x745C, 0xE0EF, 0x745E, 0x9090, 0x745F, 0xE0EC, 0x7460, 0x97DA, + 0x7462, 0xFB6B, 0x7463, 0xE0F2, 0x7464, 0xEAA2, 0x7469, 0xE0F0, + 0x746A, 0xE0F3, 0x746F, 0xE0E5, 0x7470, 0xE0F1, 0x7473, 0x8DBA, + 0x7476, 0xE0F4, 0x747E, 0xE0F5, 0x7483, 0x979E, 0x7489, 0xFB6C, + 0x748B, 0xE0F6, 0x749E, 0xE0F7, 0x749F, 0xFB6D, 0x74A2, 0xE0E3, + 0x74A7, 0xE0F8, 0x74B0, 0x8AC2, 0x74BD, 0x8EA3, 0x74CA, 0xE0F9, + 0x74CF, 0xE0FA, 0x74D4, 0xE0FB, 0x74DC, 0x895A, 0x74E0, 0xE140, + 0x74E2, 0x955A, 0x74E3, 0xE141, 0x74E6, 0x8AA2, 0x74E7, 0xE142, + 0x74E9, 0xE143, 0x74EE, 0xE144, 0x74F0, 0xE146, 0x74F1, 0xE147, + 0x74F2, 0xE145, 0x74F6, 0x9572, 0x74F7, 0xE149, 0x74F8, 0xE148, + 0x7501, 0xFB6E, 0x7503, 0xE14B, 0x7504, 0xE14A, 0x7505, 0xE14C, + 0x750C, 0xE14D, 0x750D, 0xE14F, 0x750E, 0xE14E, 0x7511, 0x8D99, + 0x7513, 0xE151, 0x7515, 0xE150, 0x7518, 0x8AC3, 0x751A, 0x9072, + 0x751C, 0x935B, 0x751E, 0xE152, 0x751F, 0x90B6, 0x7523, 0x8E59, + 0x7525, 0x8999, 0x7526, 0xE153, 0x7528, 0x9770, 0x752B, 0x95E1, + 0x752C, 0xE154, 0x752F, 0xFAA8, 0x7530, 0x9363, 0x7531, 0x9752, + 0x7532, 0x8D62, 0x7533, 0x905C, 0x7537, 0x926A, 0x7538, 0x99B2, + 0x753A, 0x92AC, 0x753B, 0x89E6, 0x753C, 0xE155, 0x7544, 0xE156, + 0x7546, 0xE15B, 0x7549, 0xE159, 0x754A, 0xE158, 0x754B, 0x9DC0, + 0x754C, 0x8A45, 0x754D, 0xE157, 0x754F, 0x88D8, 0x7551, 0x94A8, + 0x7554, 0x94C8, 0x7559, 0x97AF, 0x755A, 0xE15C, 0x755B, 0xE15A, + 0x755C, 0x927B, 0x755D, 0x90A4, 0x7560, 0x94A9, 0x7562, 0x954C, + 0x7564, 0xE15E, 0x7565, 0x97AA, 0x7566, 0x8C6C, 0x7567, 0xE15F, + 0x7569, 0xE15D, 0x756A, 0x94D4, 0x756B, 0xE160, 0x756D, 0xE161, + 0x756F, 0xFB6F, 0x7570, 0x88D9, 0x7573, 0x8FF4, 0x7574, 0xE166, + 0x7576, 0xE163, 0x7577, 0x93EB, 0x7578, 0xE162, 0x757F, 0x8B45, + 0x7582, 0xE169, 0x7586, 0xE164, 0x7587, 0xE165, 0x7589, 0xE168, + 0x758A, 0xE167, 0x758B, 0x9544, 0x758E, 0x9161, 0x758F, 0x9160, + 0x7591, 0x8B5E, 0x7594, 0xE16A, 0x759A, 0xE16B, 0x759D, 0xE16C, + 0x75A3, 0xE16E, 0x75A5, 0xE16D, 0x75AB, 0x8975, 0x75B1, 0xE176, + 0x75B2, 0x94E6, 0x75B3, 0xE170, 0x75B5, 0xE172, 0x75B8, 0xE174, + 0x75B9, 0x905D, 0x75BC, 0xE175, 0x75BD, 0xE173, 0x75BE, 0x8EBE, + 0x75C2, 0xE16F, 0x75C3, 0xE171, 0x75C5, 0x9561, 0x75C7, 0x8FC7, + 0x75CA, 0xE178, 0x75CD, 0xE177, 0x75D2, 0xE179, 0x75D4, 0x8EA4, + 0x75D5, 0x8DAD, 0x75D8, 0x9397, 0x75D9, 0xE17A, 0x75DB, 0x92C9, + 0x75DE, 0xE17C, 0x75E2, 0x979F, 0x75E3, 0xE17B, 0x75E9, 0x9189, + 0x75F0, 0xE182, 0x75F2, 0xE184, 0x75F3, 0xE185, 0x75F4, 0x9273, + 0x75FA, 0xE183, 0x75FC, 0xE180, 0x75FE, 0xE17D, 0x75FF, 0xE17E, + 0x7601, 0xE181, 0x7609, 0xE188, 0x760B, 0xE186, 0x760D, 0xE187, + 0x761F, 0xE189, 0x7620, 0xE18B, 0x7621, 0xE18C, 0x7622, 0xE18D, + 0x7624, 0xE18E, 0x7627, 0xE18A, 0x7630, 0xE190, 0x7634, 0xE18F, + 0x763B, 0xE191, 0x7642, 0x97C3, 0x7646, 0xE194, 0x7647, 0xE192, + 0x7648, 0xE193, 0x764C, 0x8AE0, 0x7652, 0x96FC, 0x7656, 0x95C8, + 0x7658, 0xE196, 0x765C, 0xE195, 0x7661, 0xE197, 0x7662, 0xE198, + 0x7667, 0xE19C, 0x7668, 0xE199, 0x7669, 0xE19A, 0x766A, 0xE19B, + 0x766C, 0xE19D, 0x7670, 0xE19E, 0x7672, 0xE19F, 0x7676, 0xE1A0, + 0x7678, 0xE1A1, 0x767A, 0x94AD, 0x767B, 0x936F, 0x767C, 0xE1A2, + 0x767D, 0x9492, 0x767E, 0x9553, 0x7680, 0xE1A3, 0x7682, 0xFB70, + 0x7683, 0xE1A4, 0x7684, 0x9349, 0x7686, 0x8A46, 0x7687, 0x8D63, + 0x7688, 0xE1A5, 0x768B, 0xE1A6, 0x768E, 0xE1A7, 0x7690, 0x8E48, + 0x7693, 0xE1A9, 0x7696, 0xE1A8, 0x7699, 0xE1AA, 0x769A, 0xE1AB, + 0x769B, 0xFB73, 0x769C, 0xFB71, 0x769E, 0xFB72, 0x76A6, 0xFB74, + 0x76AE, 0x94E7, 0x76B0, 0xE1AC, 0x76B4, 0xE1AD, 0x76B7, 0xEA89, + 0x76B8, 0xE1AE, 0x76B9, 0xE1AF, 0x76BA, 0xE1B0, 0x76BF, 0x8E4D, + 0x76C2, 0xE1B1, 0x76C3, 0x9475, 0x76C6, 0x967E, 0x76C8, 0x896D, + 0x76CA, 0x8976, 0x76CD, 0xE1B2, 0x76D2, 0xE1B4, 0x76D6, 0xE1B3, + 0x76D7, 0x9390, 0x76DB, 0x90B7, 0x76DC, 0x9F58, 0x76DE, 0xE1B5, + 0x76DF, 0x96BF, 0x76E1, 0xE1B6, 0x76E3, 0x8AC4, 0x76E4, 0x94D5, + 0x76E5, 0xE1B7, 0x76E7, 0xE1B8, 0x76EA, 0xE1B9, 0x76EE, 0x96DA, + 0x76F2, 0x96D3, 0x76F4, 0x92BC, 0x76F8, 0x918A, 0x76FB, 0xE1BB, + 0x76FE, 0x8F82, 0x7701, 0x8FC8, 0x7704, 0xE1BE, 0x7707, 0xE1BD, + 0x7708, 0xE1BC, 0x7709, 0x94FB, 0x770B, 0x8AC5, 0x770C, 0x8CA7, + 0x771B, 0xE1C4, 0x771E, 0xE1C1, 0x771F, 0x905E, 0x7720, 0x96B0, + 0x7724, 0xE1C0, 0x7725, 0xE1C2, 0x7726, 0xE1C3, 0x7729, 0xE1BF, + 0x7737, 0xE1C5, 0x7738, 0xE1C6, 0x773A, 0x92AD, 0x773C, 0x8AE1, + 0x7740, 0x9285, 0x7746, 0xFB76, 0x7747, 0xE1C7, 0x775A, 0xE1C8, + 0x775B, 0xE1CB, 0x7761, 0x9087, 0x7763, 0x93C2, 0x7765, 0xE1CC, + 0x7766, 0x9672, 0x7768, 0xE1C9, 0x776B, 0xE1CA, 0x7779, 0xE1CF, + 0x777E, 0xE1CE, 0x777F, 0xE1CD, 0x778B, 0xE1D1, 0x778E, 0xE1D0, + 0x7791, 0xE1D2, 0x779E, 0xE1D4, 0x77A0, 0xE1D3, 0x77A5, 0x95CB, + 0x77AC, 0x8F75, 0x77AD, 0x97C4, 0x77B0, 0xE1D5, 0x77B3, 0x93B5, + 0x77B6, 0xE1D6, 0x77B9, 0xE1D7, 0x77BB, 0xE1DB, 0x77BC, 0xE1D9, + 0x77BD, 0xE1DA, 0x77BF, 0xE1D8, 0x77C7, 0xE1DC, 0x77CD, 0xE1DD, + 0x77D7, 0xE1DE, 0x77DA, 0xE1DF, 0x77DB, 0x96B5, 0x77DC, 0xE1E0, + 0x77E2, 0x96EE, 0x77E3, 0xE1E1, 0x77E5, 0x926D, 0x77E7, 0x948A, + 0x77E9, 0x8BE9, 0x77ED, 0x925A, 0x77EE, 0xE1E2, 0x77EF, 0x8BB8, + 0x77F3, 0x90CE, 0x77FC, 0xE1E3, 0x7802, 0x8DBB, 0x780C, 0xE1E4, + 0x7812, 0xE1E5, 0x7814, 0x8CA4, 0x7815, 0x8DD3, 0x7820, 0xE1E7, + 0x7821, 0xFB78, 0x7825, 0x9375, 0x7826, 0x8DD4, 0x7827, 0x8B6D, + 0x7832, 0x9643, 0x7834, 0x946A, 0x783A, 0x9376, 0x783F, 0x8D7B, + 0x7845, 0xE1E9, 0x784E, 0xFB79, 0x785D, 0x8FC9, 0x7864, 0xFB7A, + 0x786B, 0x97B0, 0x786C, 0x8D64, 0x786F, 0x8CA5, 0x7872, 0x94A1, + 0x7874, 0xE1EB, 0x787A, 0xFB7B, 0x787C, 0xE1ED, 0x7881, 0x8CE9, + 0x7886, 0xE1EC, 0x7887, 0x92F4, 0x788C, 0xE1EF, 0x788D, 0x8A56, + 0x788E, 0xE1EA, 0x7891, 0x94E8, 0x7893, 0x894F, 0x7895, 0x8DEA, + 0x7897, 0x9871, 0x789A, 0xE1EE, 0x78A3, 0xE1F0, 0x78A7, 0x95C9, + 0x78A9, 0x90D7, 0x78AA, 0xE1F2, 0x78AF, 0xE1F3, 0x78B5, 0xE1F1, + 0x78BA, 0x8A6D, 0x78BC, 0xE1F9, 0x78BE, 0xE1F8, 0x78C1, 0x8EA5, + 0x78C5, 0xE1FA, 0x78C6, 0xE1F5, 0x78CA, 0xE1FB, 0x78CB, 0xE1F6, + 0x78D0, 0x94D6, 0x78D1, 0xE1F4, 0x78D4, 0xE1F7, 0x78DA, 0xE241, + 0x78E7, 0xE240, 0x78E8, 0x9681, 0x78EC, 0xE1FC, 0x78EF, 0x88E9, + 0x78F4, 0xE243, 0x78FD, 0xE242, 0x7901, 0x8FCA, 0x7907, 0xE244, + 0x790E, 0x9162, 0x7911, 0xE246, 0x7912, 0xE245, 0x7919, 0xE247, + 0x7926, 0xE1E6, 0x792A, 0xE1E8, 0x792B, 0xE249, 0x792C, 0xE248, + 0x7930, 0xFB7C, 0x793A, 0x8EA6, 0x793C, 0x97E7, 0x793E, 0x8ED0, + 0x7940, 0xE24A, 0x7941, 0x8C56, 0x7947, 0x8B5F, 0x7948, 0x8B46, + 0x7949, 0x8E83, 0x7950, 0x9753, 0x7953, 0xE250, 0x7955, 0xE24F, + 0x7956, 0x9163, 0x7957, 0xE24C, 0x795A, 0xE24E, 0x795D, 0x8F6A, + 0x795E, 0x905F, 0x795F, 0xE24D, 0x7960, 0xE24B, 0x7962, 0x9449, + 0x7965, 0x8FCB, 0x7968, 0x955B, 0x796D, 0x8DD5, 0x7977, 0x9398, + 0x797A, 0xE251, 0x797F, 0xE252, 0x7980, 0xE268, 0x7981, 0x8BD6, + 0x7984, 0x985C, 0x7985, 0x9154, 0x798A, 0xE253, 0x798D, 0x89D0, + 0x798E, 0x92F5, 0x798F, 0x959F, 0x7994, 0xFB81, 0x799B, 0xFB83, + 0x799D, 0xE254, 0x79A6, 0x8B9A, 0x79A7, 0xE255, 0x79AA, 0xE257, + 0x79AE, 0xE258, 0x79B0, 0x9448, 0x79B3, 0xE259, 0x79B9, 0xE25A, + 0x79BA, 0xE25B, 0x79BD, 0x8BD7, 0x79BE, 0x89D1, 0x79BF, 0x93C3, + 0x79C0, 0x8F47, 0x79C1, 0x8E84, 0x79C9, 0xE25C, 0x79CB, 0x8F48, + 0x79D1, 0x89C8, 0x79D2, 0x9562, 0x79D5, 0xE25D, 0x79D8, 0x94E9, + 0x79DF, 0x9164, 0x79E1, 0xE260, 0x79E3, 0xE261, 0x79E4, 0x9489, + 0x79E6, 0x9060, 0x79E7, 0xE25E, 0x79E9, 0x9281, 0x79EC, 0xE25F, + 0x79F0, 0x8FCC, 0x79FB, 0x88DA, 0x7A00, 0x8B48, 0x7A08, 0xE262, + 0x7A0B, 0x92F6, 0x7A0D, 0xE263, 0x7A0E, 0x90C5, 0x7A14, 0x96AB, + 0x7A17, 0x9542, 0x7A18, 0xE264, 0x7A19, 0xE265, 0x7A1A, 0x9274, + 0x7A1C, 0x97C5, 0x7A1F, 0xE267, 0x7A20, 0xE266, 0x7A2E, 0x8EED, + 0x7A31, 0xE269, 0x7A32, 0x88EE, 0x7A37, 0xE26C, 0x7A3B, 0xE26A, + 0x7A3C, 0x89D2, 0x7A3D, 0x8C6D, 0x7A3E, 0xE26B, 0x7A3F, 0x8D65, + 0x7A40, 0x8D92, 0x7A42, 0x95E4, 0x7A43, 0xE26D, 0x7A46, 0x9673, + 0x7A49, 0xE26F, 0x7A4D, 0x90CF, 0x7A4E, 0x896E, 0x7A4F, 0x89B8, + 0x7A50, 0x88AA, 0x7A57, 0xE26E, 0x7A61, 0xE270, 0x7A62, 0xE271, + 0x7A63, 0x8FF5, 0x7A69, 0xE272, 0x7A6B, 0x8A6E, 0x7A70, 0xE274, + 0x7A74, 0x8C8A, 0x7A76, 0x8B86, 0x7A79, 0xE275, 0x7A7A, 0x8BF3, + 0x7A7D, 0xE276, 0x7A7F, 0x90FA, 0x7A81, 0x93CB, 0x7A83, 0x90DE, + 0x7A84, 0x8DF3, 0x7A88, 0xE277, 0x7A92, 0x9282, 0x7A93, 0x918B, + 0x7A95, 0xE279, 0x7A96, 0xE27B, 0x7A97, 0xE278, 0x7A98, 0xE27A, + 0x7A9F, 0x8C41, 0x7AA9, 0xE27C, 0x7AAA, 0x8C45, 0x7AAE, 0x8B87, + 0x7AAF, 0x9771, 0x7AB0, 0xE27E, 0x7AB6, 0xE280, 0x7ABA, 0x894D, + 0x7ABF, 0xE283, 0x7AC3, 0x8A96, 0x7AC4, 0xE282, 0x7AC5, 0xE281, + 0x7AC7, 0xE285, 0x7AC8, 0xE27D, 0x7ACA, 0xE286, 0x7ACB, 0x97A7, + 0x7ACD, 0xE287, 0x7ACF, 0xE288, 0x7AD1, 0xFB84, 0x7AD2, 0x9AF2, + 0x7AD3, 0xE28A, 0x7AD5, 0xE289, 0x7AD9, 0xE28B, 0x7ADA, 0xE28C, + 0x7ADC, 0x97B3, 0x7ADD, 0xE28D, 0x7ADF, 0xE8ED, 0x7AE0, 0x8FCD, + 0x7AE1, 0xE28E, 0x7AE2, 0xE28F, 0x7AE3, 0x8F76, 0x7AE5, 0x93B6, + 0x7AE6, 0xE290, 0x7AE7, 0xFB85, 0x7AEA, 0x9247, 0x7AEB, 0xFB87, + 0x7AED, 0xE291, 0x7AEF, 0x925B, 0x7AF0, 0xE292, 0x7AF6, 0x8BA3, + 0x7AF8, 0x995E, 0x7AF9, 0x927C, 0x7AFA, 0x8EB1, 0x7AFF, 0x8AC6, + 0x7B02, 0xE293, 0x7B04, 0xE2A0, 0x7B06, 0xE296, 0x7B08, 0x8B88, + 0x7B0A, 0xE295, 0x7B0B, 0xE2A2, 0x7B0F, 0xE294, 0x7B11, 0x8FCE, + 0x7B18, 0xE298, 0x7B19, 0xE299, 0x7B1B, 0x934A, 0x7B1E, 0xE29A, + 0x7B20, 0x8A7D, 0x7B25, 0x9079, 0x7B26, 0x9584, 0x7B28, 0xE29C, + 0x7B2C, 0x91E6, 0x7B33, 0xE297, 0x7B35, 0xE29B, 0x7B36, 0xE29D, + 0x7B39, 0x8DF9, 0x7B45, 0xE2A4, 0x7B46, 0x954D, 0x7B48, 0x94A4, + 0x7B49, 0x9399, 0x7B4B, 0x8BD8, 0x7B4C, 0xE2A3, 0x7B4D, 0xE2A1, + 0x7B4F, 0x94B3, 0x7B50, 0xE29E, 0x7B51, 0x927D, 0x7B52, 0x939B, + 0x7B54, 0x939A, 0x7B56, 0x8DF4, 0x7B5D, 0xE2B6, 0x7B65, 0xE2A6, + 0x7B67, 0xE2A8, 0x7B6C, 0xE2AB, 0x7B6E, 0xE2AC, 0x7B70, 0xE2A9, + 0x7B71, 0xE2AA, 0x7B74, 0xE2A7, 0x7B75, 0xE2A5, 0x7B7A, 0xE29F, + 0x7B86, 0x95CD, 0x7B87, 0x89D3, 0x7B8B, 0xE2B3, 0x7B8D, 0xE2B0, + 0x7B8F, 0xE2B5, 0x7B92, 0xE2B4, 0x7B94, 0x9493, 0x7B95, 0x96A5, + 0x7B97, 0x8E5A, 0x7B98, 0xE2AE, 0x7B99, 0xE2B7, 0x7B9A, 0xE2B2, + 0x7B9C, 0xE2B1, 0x7B9D, 0xE2AD, 0x7B9E, 0xFB88, 0x7B9F, 0xE2AF, + 0x7BA1, 0x8AC7, 0x7BAA, 0x925C, 0x7BAD, 0x90FB, 0x7BB1, 0x94A0, + 0x7BB4, 0xE2BC, 0x7BB8, 0x94A2, 0x7BC0, 0x90DF, 0x7BC1, 0xE2B9, + 0x7BC4, 0x94CD, 0x7BC6, 0xE2BD, 0x7BC7, 0x95D1, 0x7BC9, 0x927A, + 0x7BCB, 0xE2B8, 0x7BCC, 0xE2BA, 0x7BCF, 0xE2BB, 0x7BDD, 0xE2BE, + 0x7BE0, 0x8EC2, 0x7BE4, 0x93C4, 0x7BE5, 0xE2C3, 0x7BE6, 0xE2C2, + 0x7BE9, 0xE2BF, 0x7BED, 0x9855, 0x7BF3, 0xE2C8, 0x7BF6, 0xE2CC, + 0x7BF7, 0xE2C9, 0x7C00, 0xE2C5, 0x7C07, 0xE2C6, 0x7C0D, 0xE2CB, + 0x7C11, 0xE2C0, 0x7C12, 0x99D3, 0x7C13, 0xE2C7, 0x7C14, 0xE2C1, + 0x7C17, 0xE2CA, 0x7C1F, 0xE2D0, 0x7C21, 0x8AC8, 0x7C23, 0xE2CD, + 0x7C27, 0xE2CE, 0x7C2A, 0xE2CF, 0x7C2B, 0xE2D2, 0x7C37, 0xE2D1, + 0x7C38, 0x94F4, 0x7C3D, 0xE2D3, 0x7C3E, 0x97FA, 0x7C3F, 0x95EB, + 0x7C40, 0xE2D8, 0x7C43, 0xE2D5, 0x7C4C, 0xE2D4, 0x7C4D, 0x90D0, + 0x7C4F, 0xE2D7, 0x7C50, 0xE2D9, 0x7C54, 0xE2D6, 0x7C56, 0xE2DD, + 0x7C58, 0xE2DA, 0x7C5F, 0xE2DB, 0x7C60, 0xE2C4, 0x7C64, 0xE2DC, + 0x7C65, 0xE2DE, 0x7C6C, 0xE2DF, 0x7C73, 0x95C4, 0x7C75, 0xE2E0, + 0x7C7E, 0x96E0, 0x7C81, 0x8BCC, 0x7C82, 0x8C48, 0x7C83, 0xE2E1, + 0x7C89, 0x95B2, 0x7C8B, 0x9088, 0x7C8D, 0x96AE, 0x7C90, 0xE2E2, + 0x7C92, 0x97B1, 0x7C95, 0x9494, 0x7C97, 0x9165, 0x7C98, 0x9453, + 0x7C9B, 0x8F6C, 0x7C9F, 0x88BE, 0x7CA1, 0xE2E7, 0x7CA2, 0xE2E5, + 0x7CA4, 0xE2E3, 0x7CA5, 0x8A9F, 0x7CA7, 0x8FCF, 0x7CA8, 0xE2E8, + 0x7CAB, 0xE2E6, 0x7CAD, 0xE2E4, 0x7CAE, 0xE2EC, 0x7CB1, 0xE2EB, + 0x7CB2, 0xE2EA, 0x7CB3, 0xE2E9, 0x7CB9, 0xE2ED, 0x7CBD, 0xE2EE, + 0x7CBE, 0x90B8, 0x7CC0, 0xE2EF, 0x7CC2, 0xE2F1, 0x7CC5, 0xE2F0, + 0x7CCA, 0x8CD0, 0x7CCE, 0x9157, 0x7CD2, 0xE2F3, 0x7CD6, 0x939C, + 0x7CD8, 0xE2F2, 0x7CDC, 0xE2F4, 0x7CDE, 0x95B3, 0x7CDF, 0x918C, + 0x7CE0, 0x8D66, 0x7CE2, 0xE2F5, 0x7CE7, 0x97C6, 0x7CEF, 0xE2F7, + 0x7CF2, 0xE2F8, 0x7CF4, 0xE2F9, 0x7CF6, 0xE2FA, 0x7CF8, 0x8E85, + 0x7CFA, 0xE2FB, 0x7CFB, 0x8C6E, 0x7CFE, 0x8B8A, 0x7D00, 0x8B49, + 0x7D02, 0xE340, 0x7D04, 0x96F1, 0x7D05, 0x8D67, 0x7D06, 0xE2FC, + 0x7D0A, 0xE343, 0x7D0B, 0x96E4, 0x7D0D, 0x945B, 0x7D10, 0x9552, + 0x7D14, 0x8F83, 0x7D15, 0xE342, 0x7D17, 0x8ED1, 0x7D18, 0x8D68, + 0x7D19, 0x8E86, 0x7D1A, 0x8B89, 0x7D1B, 0x95B4, 0x7D1C, 0xE341, + 0x7D20, 0x9166, 0x7D21, 0x9661, 0x7D22, 0x8DF5, 0x7D2B, 0x8E87, + 0x7D2C, 0x92DB, 0x7D2E, 0xE346, 0x7D2F, 0x97DD, 0x7D30, 0x8DD7, + 0x7D32, 0xE347, 0x7D33, 0x9061, 0x7D35, 0xE349, 0x7D39, 0x8FD0, + 0x7D3A, 0x8DAE, 0x7D3F, 0xE348, 0x7D42, 0x8F49, 0x7D43, 0x8CBC, + 0x7D44, 0x9167, 0x7D45, 0xE344, 0x7D46, 0xE34A, 0x7D48, 0xFB8A, + 0x7D4B, 0xE345, 0x7D4C, 0x8C6F, 0x7D4E, 0xE34D, 0x7D4F, 0xE351, + 0x7D50, 0x8C8B, 0x7D56, 0xE34C, 0x7D5B, 0xE355, 0x7D5C, 0xFB8B, + 0x7D5E, 0x8D69, 0x7D61, 0x978D, 0x7D62, 0x88BA, 0x7D63, 0xE352, + 0x7D66, 0x8B8B, 0x7D68, 0xE34F, 0x7D6E, 0xE350, 0x7D71, 0x939D, + 0x7D72, 0xE34E, 0x7D73, 0xE34B, 0x7D75, 0x8A47, 0x7D76, 0x90E2, + 0x7D79, 0x8CA6, 0x7D7D, 0xE357, 0x7D89, 0xE354, 0x7D8F, 0xE356, + 0x7D93, 0xE353, 0x7D99, 0x8C70, 0x7D9A, 0x91B1, 0x7D9B, 0xE358, + 0x7D9C, 0x918E, 0x7D9F, 0xE365, 0x7DA0, 0xFB8D, 0x7DA2, 0xE361, + 0x7DA3, 0xE35B, 0x7DAB, 0xE35F, 0x7DAC, 0x8EF8, 0x7DAD, 0x88DB, + 0x7DAE, 0xE35A, 0x7DAF, 0xE362, 0x7DB0, 0xE366, 0x7DB1, 0x8D6A, + 0x7DB2, 0x96D4, 0x7DB4, 0x92D4, 0x7DB5, 0xE35C, 0x7DB7, 0xFB8C, + 0x7DB8, 0xE364, 0x7DBA, 0xE359, 0x7DBB, 0x925D, 0x7DBD, 0xE35E, + 0x7DBE, 0x88BB, 0x7DBF, 0x96C8, 0x7DC7, 0xE35D, 0x7DCA, 0x8BD9, + 0x7DCB, 0x94EA, 0x7DCF, 0x918D, 0x7DD1, 0x97CE, 0x7DD2, 0x8F8F, + 0x7DD5, 0xE38E, 0x7DD6, 0xFB8E, 0x7DD8, 0xE367, 0x7DDA, 0x90FC, + 0x7DDC, 0xE363, 0x7DDD, 0xE368, 0x7DDE, 0xE36A, 0x7DE0, 0x92F7, + 0x7DE1, 0xE36D, 0x7DE4, 0xE369, 0x7DE8, 0x95D2, 0x7DE9, 0x8AC9, + 0x7DEC, 0x96C9, 0x7DEF, 0x88DC, 0x7DF2, 0xE36C, 0x7DF4, 0x97FB, + 0x7DFB, 0xE36B, 0x7E01, 0x898F, 0x7E04, 0x93EA, 0x7E05, 0xE36E, + 0x7E09, 0xE375, 0x7E0A, 0xE36F, 0x7E0B, 0xE376, 0x7E12, 0xE372, + 0x7E1B, 0x949B, 0x7E1E, 0x8EC8, 0x7E1F, 0xE374, 0x7E21, 0xE371, + 0x7E22, 0xE377, 0x7E23, 0xE370, 0x7E26, 0x8F63, 0x7E2B, 0x9644, + 0x7E2E, 0x8F6B, 0x7E31, 0xE373, 0x7E32, 0xE380, 0x7E35, 0xE37B, + 0x7E37, 0xE37E, 0x7E39, 0xE37C, 0x7E3A, 0xE381, 0x7E3B, 0xE37A, + 0x7E3D, 0xE360, 0x7E3E, 0x90D1, 0x7E41, 0x94C9, 0x7E43, 0xE37D, + 0x7E46, 0xE378, 0x7E4A, 0x9140, 0x7E4B, 0x8C71, 0x7E4D, 0x8F4A, + 0x7E52, 0xFB8F, 0x7E54, 0x9044, 0x7E55, 0x9155, 0x7E56, 0xE384, + 0x7E59, 0xE386, 0x7E5A, 0xE387, 0x7E5D, 0xE383, 0x7E5E, 0xE385, + 0x7E66, 0xE379, 0x7E67, 0xE382, 0x7E69, 0xE38A, 0x7E6A, 0xE389, + 0x7E6D, 0x969A, 0x7E70, 0x8C4A, 0x7E79, 0xE388, 0x7E7B, 0xE38C, + 0x7E7C, 0xE38B, 0x7E7D, 0xE38F, 0x7E7F, 0xE391, 0x7E82, 0x8E5B, + 0x7E83, 0xE38D, 0x7E88, 0xE392, 0x7E89, 0xE393, 0x7E8A, 0xFA5C, + 0x7E8C, 0xE394, 0x7E8E, 0xE39A, 0x7E8F, 0x935A, 0x7E90, 0xE396, + 0x7E92, 0xE395, 0x7E93, 0xE397, 0x7E94, 0xE398, 0x7E96, 0xE399, + 0x7E9B, 0xE39B, 0x7E9C, 0xE39C, 0x7F36, 0x8ACA, 0x7F38, 0xE39D, + 0x7F3A, 0xE39E, 0x7F45, 0xE39F, 0x7F47, 0xFB90, 0x7F4C, 0xE3A0, + 0x7F4D, 0xE3A1, 0x7F4E, 0xE3A2, 0x7F50, 0xE3A3, 0x7F51, 0xE3A4, + 0x7F54, 0xE3A6, 0x7F55, 0xE3A5, 0x7F58, 0xE3A7, 0x7F5F, 0xE3A8, + 0x7F60, 0xE3A9, 0x7F67, 0xE3AC, 0x7F68, 0xE3AA, 0x7F69, 0xE3AB, + 0x7F6A, 0x8DDF, 0x7F6B, 0x8C72, 0x7F6E, 0x9275, 0x7F70, 0x94B1, + 0x7F72, 0x8F90, 0x7F75, 0x946C, 0x7F77, 0x94EB, 0x7F78, 0xE3AD, + 0x7F79, 0x9CEB, 0x7F82, 0xE3AE, 0x7F83, 0xE3B0, 0x7F85, 0x9785, + 0x7F86, 0xE3AF, 0x7F87, 0xE3B2, 0x7F88, 0xE3B1, 0x7F8A, 0x9772, + 0x7F8C, 0xE3B3, 0x7F8E, 0x94FC, 0x7F94, 0xE3B4, 0x7F9A, 0xE3B7, + 0x7F9D, 0xE3B6, 0x7F9E, 0xE3B5, 0x7FA1, 0xFB91, 0x7FA3, 0xE3B8, + 0x7FA4, 0x8C51, 0x7FA8, 0x9141, 0x7FA9, 0x8B60, 0x7FAE, 0xE3BC, + 0x7FAF, 0xE3B9, 0x7FB2, 0xE3BA, 0x7FB6, 0xE3BD, 0x7FB8, 0xE3BE, + 0x7FB9, 0xE3BB, 0x7FBD, 0x8948, 0x7FC1, 0x89A5, 0x7FC5, 0xE3C0, + 0x7FC6, 0xE3C1, 0x7FCA, 0xE3C2, 0x7FCC, 0x9782, 0x7FD2, 0x8F4B, + 0x7FD4, 0xE3C4, 0x7FD5, 0xE3C3, 0x7FE0, 0x9089, 0x7FE1, 0xE3C5, + 0x7FE6, 0xE3C6, 0x7FE9, 0xE3C7, 0x7FEB, 0x8AE3, 0x7FF0, 0x8ACB, + 0x7FF3, 0xE3C8, 0x7FF9, 0xE3C9, 0x7FFB, 0x967C, 0x7FFC, 0x9783, + 0x8000, 0x9773, 0x8001, 0x9856, 0x8003, 0x8D6C, 0x8004, 0xE3CC, + 0x8005, 0x8ED2, 0x8006, 0xE3CB, 0x800B, 0xE3CD, 0x800C, 0x8EA7, + 0x8010, 0x91CF, 0x8012, 0xE3CE, 0x8015, 0x8D6B, 0x8017, 0x96D5, + 0x8018, 0xE3CF, 0x8019, 0xE3D0, 0x801C, 0xE3D1, 0x8021, 0xE3D2, + 0x8028, 0xE3D3, 0x8033, 0x8EA8, 0x8036, 0x96EB, 0x803B, 0xE3D5, + 0x803D, 0x925E, 0x803F, 0xE3D4, 0x8046, 0xE3D7, 0x804A, 0xE3D6, + 0x8052, 0xE3D8, 0x8056, 0x90B9, 0x8058, 0xE3D9, 0x805A, 0xE3DA, + 0x805E, 0x95B7, 0x805F, 0xE3DB, 0x8061, 0x918F, 0x8062, 0xE3DC, + 0x8068, 0xE3DD, 0x806F, 0x97FC, 0x8070, 0xE3E0, 0x8072, 0xE3DF, + 0x8073, 0xE3DE, 0x8074, 0x92AE, 0x8076, 0xE3E1, 0x8077, 0x9045, + 0x8079, 0xE3E2, 0x807D, 0xE3E3, 0x807E, 0x9857, 0x807F, 0xE3E4, + 0x8084, 0xE3E5, 0x8085, 0xE3E7, 0x8086, 0xE3E6, 0x8087, 0x94A3, + 0x8089, 0x93F7, 0x808B, 0x985D, 0x808C, 0x94A7, 0x8093, 0xE3E9, + 0x8096, 0x8FD1, 0x8098, 0x9549, 0x809A, 0xE3EA, 0x809B, 0xE3E8, + 0x809D, 0x8ACC, 0x80A1, 0x8CD2, 0x80A2, 0x8E88, 0x80A5, 0x94EC, + 0x80A9, 0x8CA8, 0x80AA, 0x9662, 0x80AC, 0xE3ED, 0x80AD, 0xE3EB, + 0x80AF, 0x8D6D, 0x80B1, 0x8D6E, 0x80B2, 0x88E7, 0x80B4, 0x8DE6, + 0x80BA, 0x9478, 0x80C3, 0x88DD, 0x80C4, 0xE3F2, 0x80C6, 0x925F, + 0x80CC, 0x9477, 0x80CE, 0x91D9, 0x80D6, 0xE3F4, 0x80D9, 0xE3F0, + 0x80DA, 0xE3F3, 0x80DB, 0xE3EE, 0x80DD, 0xE3F1, 0x80DE, 0x9645, + 0x80E1, 0x8CD3, 0x80E4, 0x88FB, 0x80E5, 0xE3EF, 0x80EF, 0xE3F6, + 0x80F1, 0xE3F7, 0x80F4, 0x93B7, 0x80F8, 0x8BB9, 0x80FC, 0xE445, + 0x80FD, 0x945C, 0x8102, 0x8E89, 0x8105, 0x8BBA, 0x8106, 0x90C6, + 0x8107, 0x9865, 0x8108, 0x96AC, 0x8109, 0xE3F5, 0x810A, 0x90D2, + 0x811A, 0x8B72, 0x811B, 0xE3F8, 0x8123, 0xE3FA, 0x8129, 0xE3F9, + 0x812F, 0xE3FB, 0x8131, 0x9245, 0x8133, 0x945D, 0x8139, 0x92AF, + 0x813E, 0xE442, 0x8146, 0xE441, 0x814B, 0xE3FC, 0x814E, 0x9074, + 0x8150, 0x9585, 0x8151, 0xE444, 0x8153, 0xE443, 0x8154, 0x8D6F, + 0x8155, 0x9872, 0x815F, 0xE454, 0x8165, 0xE448, 0x8166, 0xE449, + 0x816B, 0x8EEE, 0x816E, 0xE447, 0x8170, 0x8D98, 0x8171, 0xE446, + 0x8174, 0xE44A, 0x8178, 0x92B0, 0x8179, 0x95A0, 0x817A, 0x9142, + 0x817F, 0x91DA, 0x8180, 0xE44E, 0x8182, 0xE44F, 0x8183, 0xE44B, + 0x8188, 0xE44C, 0x818A, 0xE44D, 0x818F, 0x8D70, 0x8193, 0xE455, + 0x8195, 0xE451, 0x819A, 0x9586, 0x819C, 0x968C, 0x819D, 0x9547, + 0x81A0, 0xE450, 0x81A3, 0xE453, 0x81A4, 0xE452, 0x81A8, 0x9663, + 0x81A9, 0xE456, 0x81B0, 0xE457, 0x81B3, 0x9156, 0x81B5, 0xE458, + 0x81B8, 0xE45A, 0x81BA, 0xE45E, 0x81BD, 0xE45B, 0x81BE, 0xE459, + 0x81BF, 0x945E, 0x81C0, 0xE45C, 0x81C2, 0xE45D, 0x81C6, 0x89B0, + 0x81C8, 0xE464, 0x81C9, 0xE45F, 0x81CD, 0xE460, 0x81D1, 0xE461, + 0x81D3, 0x919F, 0x81D8, 0xE463, 0x81D9, 0xE462, 0x81DA, 0xE465, + 0x81DF, 0xE466, 0x81E0, 0xE467, 0x81E3, 0x9062, 0x81E5, 0x89E7, + 0x81E7, 0xE468, 0x81E8, 0x97D5, 0x81EA, 0x8EA9, 0x81ED, 0x8F4C, + 0x81F3, 0x8E8A, 0x81F4, 0x9276, 0x81FA, 0xE469, 0x81FB, 0xE46A, + 0x81FC, 0x8950, 0x81FE, 0xE46B, 0x8201, 0xE46C, 0x8202, 0xE46D, + 0x8205, 0xE46E, 0x8207, 0xE46F, 0x8208, 0x8BBB, 0x8209, 0x9DA8, + 0x820A, 0xE470, 0x820C, 0x90E3, 0x820D, 0xE471, 0x820E, 0x8EC9, + 0x8210, 0xE472, 0x8212, 0x98AE, 0x8216, 0xE473, 0x8217, 0x95DC, + 0x8218, 0x8ADA, 0x821B, 0x9143, 0x821C, 0x8F77, 0x821E, 0x9591, + 0x821F, 0x8F4D, 0x8229, 0xE474, 0x822A, 0x8D71, 0x822B, 0xE475, + 0x822C, 0x94CA, 0x822E, 0xE484, 0x8233, 0xE477, 0x8235, 0x91C7, + 0x8236, 0x9495, 0x8237, 0x8CBD, 0x8238, 0xE476, 0x8239, 0x9144, + 0x8240, 0xE478, 0x8247, 0x92F8, 0x8258, 0xE47A, 0x8259, 0xE479, + 0x825A, 0xE47C, 0x825D, 0xE47B, 0x825F, 0xE47D, 0x8262, 0xE480, + 0x8264, 0xE47E, 0x8266, 0x8ACD, 0x8268, 0xE481, 0x826A, 0xE482, + 0x826B, 0xE483, 0x826E, 0x8DAF, 0x826F, 0x97C7, 0x8271, 0xE485, + 0x8272, 0x9046, 0x8276, 0x8990, 0x8277, 0xE486, 0x8278, 0xE487, + 0x827E, 0xE488, 0x828B, 0x88F0, 0x828D, 0xE489, 0x8292, 0xE48A, + 0x8299, 0x9587, 0x829D, 0x8EC5, 0x829F, 0xE48C, 0x82A5, 0x8A48, + 0x82A6, 0x88B0, 0x82AB, 0xE48B, 0x82AC, 0xE48E, 0x82AD, 0x946D, + 0x82AF, 0x9063, 0x82B1, 0x89D4, 0x82B3, 0x9646, 0x82B8, 0x8C7C, + 0x82B9, 0x8BDA, 0x82BB, 0xE48D, 0x82BD, 0x89E8, 0x82C5, 0x8AA1, + 0x82D1, 0x8991, 0x82D2, 0xE492, 0x82D3, 0x97E8, 0x82D4, 0x91DB, + 0x82D7, 0x9563, 0x82D9, 0xE49E, 0x82DB, 0x89D5, 0x82DC, 0xE49C, + 0x82DE, 0xE49A, 0x82DF, 0xE491, 0x82E1, 0xE48F, 0x82E3, 0xE490, + 0x82E5, 0x8EE1, 0x82E6, 0x8BEA, 0x82E7, 0x9297, 0x82EB, 0x93CF, + 0x82F1, 0x8970, 0x82F3, 0xE494, 0x82F4, 0xE493, 0x82F9, 0xE499, + 0x82FA, 0xE495, 0x82FB, 0xE498, 0x8301, 0xFB93, 0x8302, 0x96CE, + 0x8303, 0xE497, 0x8304, 0x89D6, 0x8305, 0x8A9D, 0x8306, 0xE49B, + 0x8309, 0xE49D, 0x830E, 0x8C73, 0x8316, 0xE4A1, 0x8317, 0xE4AA, + 0x8318, 0xE4AB, 0x831C, 0x88A9, 0x8323, 0xE4B2, 0x8328, 0x88EF, + 0x832B, 0xE4A9, 0x832F, 0xE4A8, 0x8331, 0xE4A3, 0x8332, 0xE4A2, + 0x8334, 0xE4A0, 0x8335, 0xE49F, 0x8336, 0x9283, 0x8338, 0x91F9, + 0x8339, 0xE4A5, 0x8340, 0xE4A4, 0x8345, 0xE4A7, 0x8349, 0x9190, + 0x834A, 0x8C74, 0x834F, 0x8960, 0x8350, 0xE4A6, 0x8352, 0x8D72, + 0x8358, 0x9191, 0x8362, 0xFB94, 0x8373, 0xE4B8, 0x8375, 0xE4B9, + 0x8377, 0x89D7, 0x837B, 0x89AC, 0x837C, 0xE4B6, 0x837F, 0xFB95, + 0x8385, 0xE4AC, 0x8387, 0xE4B4, 0x8389, 0xE4BB, 0x838A, 0xE4B5, + 0x838E, 0xE4B3, 0x8393, 0xE496, 0x8396, 0xE4B1, 0x839A, 0xE4AD, + 0x839E, 0x8ACE, 0x839F, 0xE4AF, 0x83A0, 0xE4BA, 0x83A2, 0xE4B0, + 0x83A8, 0xE4BC, 0x83AA, 0xE4AE, 0x83AB, 0x949C, 0x83B1, 0x9789, + 0x83B5, 0xE4B7, 0x83BD, 0xE4CD, 0x83C1, 0xE4C5, 0x83C5, 0x909B, + 0x83C7, 0xFB96, 0x83CA, 0x8B65, 0x83CC, 0x8BDB, 0x83CE, 0xE4C0, + 0x83D3, 0x89D9, 0x83D6, 0x8FD2, 0x83D8, 0xE4C3, 0x83DC, 0x8DD8, + 0x83DF, 0x9370, 0x83E0, 0xE4C8, 0x83E9, 0x95EC, 0x83EB, 0xE4BF, + 0x83EF, 0x89D8, 0x83F0, 0x8CD4, 0x83F1, 0x9548, 0x83F2, 0xE4C9, + 0x83F4, 0xE4BD, 0x83F6, 0xFB97, 0x83F7, 0xE4C6, 0x83FB, 0xE4D0, + 0x83FD, 0xE4C1, 0x8403, 0xE4C2, 0x8404, 0x93B8, 0x8407, 0xE4C7, + 0x840B, 0xE4C4, 0x840C, 0x9647, 0x840D, 0xE4CA, 0x840E, 0x88DE, + 0x8413, 0xE4BE, 0x8420, 0xE4CC, 0x8422, 0xE4CB, 0x8429, 0x948B, + 0x842A, 0xE4D2, 0x842C, 0xE4DD, 0x8431, 0x8A9E, 0x8435, 0xE4E0, + 0x8438, 0xE4CE, 0x843C, 0xE4D3, 0x843D, 0x978E, 0x8446, 0xE4DC, + 0x8448, 0xFB98, 0x8449, 0x9774, 0x844E, 0x97A8, 0x8457, 0x9298, + 0x845B, 0x8A8B, 0x8461, 0x9592, 0x8462, 0xE4E2, 0x8463, 0x939F, + 0x8466, 0x88AF, 0x8469, 0xE4DB, 0x846B, 0xE4D7, 0x846C, 0x9192, + 0x846D, 0xE4D1, 0x846E, 0xE4D9, 0x846F, 0xE4DE, 0x8471, 0x944B, + 0x8475, 0x88A8, 0x8477, 0xE4D6, 0x8479, 0xE4DF, 0x847A, 0x9598, + 0x8482, 0xE4DA, 0x8484, 0xE4D5, 0x848B, 0x8FD3, 0x8490, 0x8F4E, + 0x8494, 0x8EAA, 0x8499, 0x96D6, 0x849C, 0x9566, 0x849F, 0xE4E5, + 0x84A1, 0xE4EE, 0x84AD, 0xE4D8, 0x84B2, 0x8A97, 0x84B4, 0xFB99, + 0x84B8, 0x8FF6, 0x84B9, 0xE4E3, 0x84BB, 0xE4E8, 0x84BC, 0x9193, + 0x84BF, 0xE4E4, 0x84C1, 0xE4EB, 0x84C4, 0x927E, 0x84C6, 0xE4EC, + 0x84C9, 0x9775, 0x84CA, 0xE4E1, 0x84CB, 0x8A57, 0x84CD, 0xE4E7, + 0x84D0, 0xE4EA, 0x84D1, 0x96AA, 0x84D6, 0xE4ED, 0x84D9, 0xE4E6, + 0x84DA, 0xE4E9, 0x84DC, 0xFA60, 0x84EC, 0x9648, 0x84EE, 0x9840, + 0x84F4, 0xE4F1, 0x84FC, 0xE4F8, 0x84FF, 0xE4F0, 0x8500, 0x8EC1, + 0x8506, 0xE4CF, 0x8511, 0x95CC, 0x8513, 0x96A0, 0x8514, 0xE4F7, + 0x8515, 0xE4F6, 0x8517, 0xE4F2, 0x8518, 0xE4F3, 0x851A, 0x8955, + 0x851F, 0xE4F5, 0x8521, 0xE4EF, 0x8526, 0x92D3, 0x852C, 0xE4F4, + 0x852D, 0x88FC, 0x8535, 0x91A0, 0x853D, 0x95C1, 0x8540, 0xE4F9, + 0x8541, 0xE540, 0x8543, 0x94D7, 0x8548, 0xE4FC, 0x8549, 0x8FD4, + 0x854A, 0x8EC7, 0x854B, 0xE542, 0x854E, 0x8BBC, 0x8553, 0xFB9A, + 0x8555, 0xE543, 0x8557, 0x9599, 0x8558, 0xE4FB, 0x8559, 0xFB9B, + 0x855A, 0xE4D4, 0x8563, 0xE4FA, 0x8568, 0x986E, 0x8569, 0x93A0, + 0x856A, 0x9593, 0x856B, 0xFB9C, 0x856D, 0xE54A, 0x8577, 0xE550, + 0x857E, 0xE551, 0x8580, 0xE544, 0x8584, 0x9496, 0x8587, 0xE54E, + 0x8588, 0xE546, 0x858A, 0xE548, 0x8590, 0xE552, 0x8591, 0xE547, + 0x8594, 0xE54B, 0x8597, 0x8992, 0x8599, 0x93E3, 0x859B, 0xE54C, + 0x859C, 0xE54F, 0x85A4, 0xE545, 0x85A6, 0x9145, 0x85A8, 0xE549, + 0x85A9, 0x8E46, 0x85AA, 0x9064, 0x85AB, 0x8C4F, 0x85AC, 0x96F2, + 0x85AE, 0x96F7, 0x85AF, 0x8F92, 0x85B0, 0xFB9E, 0x85B9, 0xE556, + 0x85BA, 0xE554, 0x85C1, 0x986D, 0x85C9, 0xE553, 0x85CD, 0x9795, + 0x85CF, 0xE555, 0x85D0, 0xE557, 0x85D5, 0xE558, 0x85DC, 0xE55B, + 0x85DD, 0xE559, 0x85E4, 0x93A1, 0x85E5, 0xE55A, 0x85E9, 0x94CB, + 0x85EA, 0xE54D, 0x85F7, 0x8F93, 0x85F9, 0xE55C, 0x85FA, 0xE561, + 0x85FB, 0x9194, 0x85FE, 0xE560, 0x8602, 0xE541, 0x8606, 0xE562, + 0x8607, 0x9168, 0x860A, 0xE55D, 0x860B, 0xE55F, 0x8613, 0xE55E, + 0x8616, 0x9F50, 0x8617, 0x9F41, 0x861A, 0xE564, 0x8622, 0xE563, + 0x862D, 0x9796, 0x862F, 0xE1BA, 0x8630, 0xE565, 0x863F, 0xE566, + 0x864D, 0xE567, 0x864E, 0x8CD5, 0x8650, 0x8B73, 0x8654, 0xE569, + 0x8655, 0x997C, 0x865A, 0x8B95, 0x865C, 0x97B8, 0x865E, 0x8BF1, + 0x865F, 0xE56A, 0x8667, 0xE56B, 0x866B, 0x928E, 0x8671, 0xE56C, + 0x8679, 0x93F8, 0x867B, 0x88B8, 0x868A, 0x89E1, 0x868B, 0xE571, + 0x868C, 0xE572, 0x8693, 0xE56D, 0x8695, 0x8E5C, 0x86A3, 0xE56E, + 0x86A4, 0x9461, 0x86A9, 0xE56F, 0x86AA, 0xE570, 0x86AB, 0xE57A, + 0x86AF, 0xE574, 0x86B0, 0xE577, 0x86B6, 0xE573, 0x86C4, 0xE575, + 0x86C6, 0xE576, 0x86C7, 0x8ED6, 0x86C9, 0xE578, 0x86CB, 0x9260, + 0x86CD, 0x8C75, 0x86CE, 0x8A61, 0x86D4, 0xE57B, 0x86D9, 0x8A5E, + 0x86DB, 0xE581, 0x86DE, 0xE57C, 0x86DF, 0xE580, 0x86E4, 0x94B8, + 0x86E9, 0xE57D, 0x86EC, 0xE57E, 0x86ED, 0x9567, 0x86EE, 0x94D8, + 0x86EF, 0xE582, 0x86F8, 0x91FB, 0x86F9, 0xE58C, 0x86FB, 0xE588, + 0x86FE, 0x89E9, 0x8700, 0xE586, 0x8702, 0x9649, 0x8703, 0xE587, + 0x8706, 0xE584, 0x8708, 0xE585, 0x8709, 0xE58A, 0x870A, 0xE58D, + 0x870D, 0xE58B, 0x8711, 0xE589, 0x8712, 0xE583, 0x8718, 0x9277, + 0x871A, 0xE594, 0x871C, 0x96A8, 0x8725, 0xE592, 0x8729, 0xE593, + 0x8734, 0xE58E, 0x8737, 0xE590, 0x873B, 0xE591, 0x873F, 0xE58F, + 0x8749, 0x90E4, 0x874B, 0x9858, 0x874C, 0xE598, 0x874E, 0xE599, + 0x8753, 0xE59F, 0x8755, 0x9049, 0x8757, 0xE59B, 0x8759, 0xE59E, + 0x875F, 0xE596, 0x8760, 0xE595, 0x8763, 0xE5A0, 0x8766, 0x89DA, + 0x8768, 0xE59C, 0x876A, 0xE5A1, 0x876E, 0xE59D, 0x8774, 0xE59A, + 0x8776, 0x92B1, 0x8778, 0xE597, 0x877F, 0x9488, 0x8782, 0xE5A5, + 0x878D, 0x975A, 0x879F, 0xE5A4, 0x87A2, 0xE5A3, 0x87AB, 0xE5AC, + 0x87AF, 0xE5A6, 0x87B3, 0xE5AE, 0x87BA, 0x9786, 0x87BB, 0xE5B1, + 0x87BD, 0xE5A8, 0x87C0, 0xE5A9, 0x87C4, 0xE5AD, 0x87C6, 0xE5B0, + 0x87C7, 0xE5AF, 0x87CB, 0xE5A7, 0x87D0, 0xE5AA, 0x87D2, 0xE5BB, + 0x87E0, 0xE5B4, 0x87EF, 0xE5B2, 0x87F2, 0xE5B3, 0x87F6, 0xE5B8, + 0x87F7, 0xE5B9, 0x87F9, 0x8A49, 0x87FB, 0x8B61, 0x87FE, 0xE5B7, + 0x8805, 0xE5A2, 0x8807, 0xFBA1, 0x880D, 0xE5B6, 0x880E, 0xE5BA, + 0x880F, 0xE5B5, 0x8811, 0xE5BC, 0x8815, 0xE5BE, 0x8816, 0xE5BD, + 0x8821, 0xE5C0, 0x8822, 0xE5BF, 0x8823, 0xE579, 0x8827, 0xE5C4, + 0x8831, 0xE5C1, 0x8836, 0xE5C2, 0x8839, 0xE5C3, 0x883B, 0xE5C5, + 0x8840, 0x8C8C, 0x8842, 0xE5C7, 0x8844, 0xE5C6, 0x8846, 0x8F4F, + 0x884C, 0x8D73, 0x884D, 0x9FA5, 0x8852, 0xE5C8, 0x8853, 0x8F70, + 0x8857, 0x8A58, 0x8859, 0xE5C9, 0x885B, 0x8971, 0x885D, 0x8FD5, + 0x885E, 0xE5CA, 0x8861, 0x8D74, 0x8862, 0xE5CB, 0x8863, 0x88DF, + 0x8868, 0x955C, 0x886B, 0xE5CC, 0x8870, 0x908A, 0x8872, 0xE5D3, + 0x8875, 0xE5D0, 0x8877, 0x928F, 0x887D, 0xE5D1, 0x887E, 0xE5CE, + 0x887F, 0x8BDC, 0x8881, 0xE5CD, 0x8882, 0xE5D4, 0x8888, 0x8C55, + 0x888B, 0x91DC, 0x888D, 0xE5DA, 0x8892, 0xE5D6, 0x8896, 0x91B3, + 0x8897, 0xE5D5, 0x8899, 0xE5D8, 0x889E, 0xE5CF, 0x88A2, 0xE5D9, + 0x88A4, 0xE5DB, 0x88AB, 0x94ED, 0x88AE, 0xE5D7, 0x88B0, 0xE5DC, + 0x88B1, 0xE5DE, 0x88B4, 0x8CD1, 0x88B5, 0xE5D2, 0x88B7, 0x88BF, + 0x88BF, 0xE5DD, 0x88C1, 0x8DD9, 0x88C2, 0x97F4, 0x88C3, 0xE5DF, + 0x88C4, 0xE5E0, 0x88C5, 0x9195, 0x88CF, 0x97A0, 0x88D4, 0xE5E1, + 0x88D5, 0x9754, 0x88D8, 0xE5E2, 0x88D9, 0xE5E3, 0x88DC, 0x95E2, + 0x88DD, 0xE5E4, 0x88DF, 0x8DBE, 0x88E1, 0x97A1, 0x88E8, 0xE5E9, + 0x88F2, 0xE5EA, 0x88F3, 0x8FD6, 0x88F4, 0xE5E8, 0x88F5, 0xFBA2, + 0x88F8, 0x9787, 0x88F9, 0xE5E5, 0x88FC, 0xE5E7, 0x88FD, 0x90BB, + 0x88FE, 0x909E, 0x8902, 0xE5E6, 0x8904, 0xE5EB, 0x8907, 0x95A1, + 0x890A, 0xE5ED, 0x890C, 0xE5EC, 0x8910, 0x8A8C, 0x8912, 0x964A, + 0x8913, 0xE5EE, 0x891C, 0xFA5D, 0x891D, 0xE5FA, 0x891E, 0xE5F0, + 0x8925, 0xE5F1, 0x892A, 0xE5F2, 0x892B, 0xE5F3, 0x8936, 0xE5F7, + 0x8938, 0xE5F8, 0x893B, 0xE5F6, 0x8941, 0xE5F4, 0x8943, 0xE5EF, + 0x8944, 0xE5F5, 0x894C, 0xE5F9, 0x894D, 0xE8B5, 0x8956, 0x89A6, + 0x895E, 0xE5FC, 0x895F, 0x8BDD, 0x8960, 0xE5FB, 0x8964, 0xE641, + 0x8966, 0xE640, 0x896A, 0xE643, 0x896D, 0xE642, 0x896F, 0xE644, + 0x8972, 0x8F50, 0x8974, 0xE645, 0x8977, 0xE646, 0x897E, 0xE647, + 0x897F, 0x90BC, 0x8981, 0x9776, 0x8983, 0xE648, 0x8986, 0x95A2, + 0x8987, 0x9465, 0x8988, 0xE649, 0x898A, 0xE64A, 0x898B, 0x8CA9, + 0x898F, 0x8B4B, 0x8993, 0xE64B, 0x8996, 0x8E8B, 0x8997, 0x9460, + 0x8998, 0xE64C, 0x899A, 0x8A6F, 0x89A1, 0xE64D, 0x89A6, 0xE64F, + 0x89A7, 0x9797, 0x89A9, 0xE64E, 0x89AA, 0x9065, 0x89AC, 0xE650, + 0x89AF, 0xE651, 0x89B2, 0xE652, 0x89B3, 0x8ACF, 0x89BA, 0xE653, + 0x89BD, 0xE654, 0x89BF, 0xE655, 0x89C0, 0xE656, 0x89D2, 0x8A70, + 0x89DA, 0xE657, 0x89DC, 0xE658, 0x89DD, 0xE659, 0x89E3, 0x89F0, + 0x89E6, 0x9047, 0x89E7, 0xE65A, 0x89F4, 0xE65B, 0x89F8, 0xE65C, + 0x8A00, 0x8CBE, 0x8A02, 0x92F9, 0x8A03, 0xE65D, 0x8A08, 0x8C76, + 0x8A0A, 0x9075, 0x8A0C, 0xE660, 0x8A0E, 0x93A2, 0x8A10, 0xE65F, + 0x8A12, 0xFBA3, 0x8A13, 0x8C50, 0x8A16, 0xE65E, 0x8A17, 0x91F5, + 0x8A18, 0x8B4C, 0x8A1B, 0xE661, 0x8A1D, 0xE662, 0x8A1F, 0x8FD7, + 0x8A23, 0x8C8D, 0x8A25, 0xE663, 0x8A2A, 0x964B, 0x8A2D, 0x90DD, + 0x8A31, 0x8B96, 0x8A33, 0x96F3, 0x8A34, 0x9169, 0x8A36, 0xE664, + 0x8A37, 0xFBA4, 0x8A3A, 0x9066, 0x8A3B, 0x9290, 0x8A3C, 0x8FD8, + 0x8A41, 0xE665, 0x8A46, 0xE668, 0x8A48, 0xE669, 0x8A50, 0x8DBC, + 0x8A51, 0x91C0, 0x8A52, 0xE667, 0x8A54, 0x8FD9, 0x8A55, 0x955D, + 0x8A5B, 0xE666, 0x8A5E, 0x8E8C, 0x8A60, 0x8972, 0x8A62, 0xE66D, + 0x8A63, 0x8C77, 0x8A66, 0x8E8E, 0x8A69, 0x8E8D, 0x8A6B, 0x986C, + 0x8A6C, 0xE66C, 0x8A6D, 0xE66B, 0x8A6E, 0x9146, 0x8A70, 0x8B6C, + 0x8A71, 0x9862, 0x8A72, 0x8A59, 0x8A73, 0x8FDA, 0x8A79, 0xFBA5, + 0x8A7C, 0xE66A, 0x8A82, 0xE66F, 0x8A84, 0xE670, 0x8A85, 0xE66E, + 0x8A87, 0x8CD6, 0x8A89, 0x975F, 0x8A8C, 0x8E8F, 0x8A8D, 0x9446, + 0x8A91, 0xE673, 0x8A93, 0x90BE, 0x8A95, 0x9261, 0x8A98, 0x9755, + 0x8A9A, 0xE676, 0x8A9E, 0x8CEA, 0x8AA0, 0x90BD, 0x8AA1, 0xE672, + 0x8AA3, 0xE677, 0x8AA4, 0x8CEB, 0x8AA5, 0xE674, 0x8AA6, 0xE675, + 0x8AA7, 0xFBA6, 0x8AA8, 0xE671, 0x8AAC, 0x90E0, 0x8AAD, 0x93C7, + 0x8AB0, 0x924E, 0x8AB2, 0x89DB, 0x8AB9, 0x94EE, 0x8ABC, 0x8B62, + 0x8ABE, 0xFBA7, 0x8ABF, 0x92B2, 0x8AC2, 0xE67A, 0x8AC4, 0xE678, + 0x8AC7, 0x926B, 0x8ACB, 0x90BF, 0x8ACC, 0x8AD0, 0x8ACD, 0xE679, + 0x8ACF, 0x907A, 0x8AD2, 0x97C8, 0x8AD6, 0x985F, 0x8ADA, 0xE67B, + 0x8ADB, 0xE687, 0x8ADC, 0x92B3, 0x8ADE, 0xE686, 0x8ADF, 0xFBA8, + 0x8AE0, 0xE683, 0x8AE1, 0xE68B, 0x8AE2, 0xE684, 0x8AE4, 0xE680, + 0x8AE6, 0x92FA, 0x8AE7, 0xE67E, 0x8AEB, 0xE67C, 0x8AED, 0x9740, + 0x8AEE, 0x8E90, 0x8AF1, 0xE681, 0x8AF3, 0xE67D, 0x8AF6, 0xFBAA, + 0x8AF7, 0xE685, 0x8AF8, 0x8F94, 0x8AFA, 0x8CBF, 0x8AFE, 0x91F8, + 0x8B00, 0x9664, 0x8B01, 0x8979, 0x8B02, 0x88E0, 0x8B04, 0x93A3, + 0x8B07, 0xE689, 0x8B0C, 0xE688, 0x8B0E, 0x93E4, 0x8B10, 0xE68D, + 0x8B14, 0xE682, 0x8B16, 0xE68C, 0x8B17, 0xE68E, 0x8B19, 0x8CAA, + 0x8B1A, 0xE68A, 0x8B1B, 0x8D75, 0x8B1D, 0x8ED3, 0x8B20, 0xE68F, + 0x8B21, 0x9777, 0x8B26, 0xE692, 0x8B28, 0xE695, 0x8B2B, 0xE693, + 0x8B2C, 0x9554, 0x8B33, 0xE690, 0x8B39, 0x8BDE, 0x8B3E, 0xE694, + 0x8B41, 0xE696, 0x8B49, 0xE69A, 0x8B4C, 0xE697, 0x8B4E, 0xE699, + 0x8B4F, 0xE698, 0x8B53, 0xFBAB, 0x8B56, 0xE69B, 0x8B58, 0x8EAF, + 0x8B5A, 0xE69D, 0x8B5B, 0xE69C, 0x8B5C, 0x9588, 0x8B5F, 0xE69F, + 0x8B66, 0x8C78, 0x8B6B, 0xE69E, 0x8B6C, 0xE6A0, 0x8B6F, 0xE6A1, + 0x8B70, 0x8B63, 0x8B71, 0xE3BF, 0x8B72, 0x8FF7, 0x8B74, 0xE6A2, + 0x8B77, 0x8CEC, 0x8B7D, 0xE6A3, 0x8B7F, 0xFBAC, 0x8B80, 0xE6A4, + 0x8B83, 0x8E5D, 0x8B8A, 0x9DCC, 0x8B8C, 0xE6A5, 0x8B8E, 0xE6A6, + 0x8B90, 0x8F51, 0x8B92, 0xE6A7, 0x8B93, 0xE6A8, 0x8B96, 0xE6A9, + 0x8B99, 0xE6AA, 0x8B9A, 0xE6AB, 0x8C37, 0x924A, 0x8C3A, 0xE6AC, + 0x8C3F, 0xE6AE, 0x8C41, 0xE6AD, 0x8C46, 0x93A4, 0x8C48, 0xE6AF, + 0x8C4A, 0x964C, 0x8C4C, 0xE6B0, 0x8C4E, 0xE6B1, 0x8C50, 0xE6B2, + 0x8C55, 0xE6B3, 0x8C5A, 0x93D8, 0x8C61, 0x8FDB, 0x8C62, 0xE6B4, + 0x8C6A, 0x8D8B, 0x8C6B, 0x98AC, 0x8C6C, 0xE6B5, 0x8C78, 0xE6B6, + 0x8C79, 0x955E, 0x8C7A, 0xE6B7, 0x8C7C, 0xE6BF, 0x8C82, 0xE6B8, + 0x8C85, 0xE6BA, 0x8C89, 0xE6B9, 0x8C8A, 0xE6BB, 0x8C8C, 0x9665, + 0x8C8D, 0xE6BC, 0x8C8E, 0xE6BD, 0x8C94, 0xE6BE, 0x8C98, 0xE6C0, + 0x8C9D, 0x8A4C, 0x8C9E, 0x92E5, 0x8CA0, 0x9589, 0x8CA1, 0x8DE0, + 0x8CA2, 0x8D76, 0x8CA7, 0x956E, 0x8CA8, 0x89DD, 0x8CA9, 0x94CC, + 0x8CAA, 0xE6C3, 0x8CAB, 0x8AD1, 0x8CAC, 0x90D3, 0x8CAD, 0xE6C2, + 0x8CAE, 0xE6C7, 0x8CAF, 0x9299, 0x8CB0, 0x96E1, 0x8CB2, 0xE6C5, + 0x8CB3, 0xE6C6, 0x8CB4, 0x8B4D, 0x8CB6, 0xE6C8, 0x8CB7, 0x9483, + 0x8CB8, 0x91DD, 0x8CBB, 0x94EF, 0x8CBC, 0x935C, 0x8CBD, 0xE6C4, + 0x8CBF, 0x9666, 0x8CC0, 0x89EA, 0x8CC1, 0xE6CA, 0x8CC2, 0x9847, + 0x8CC3, 0x92C0, 0x8CC4, 0x9864, 0x8CC7, 0x8E91, 0x8CC8, 0xE6C9, + 0x8CCA, 0x91AF, 0x8CCD, 0xE6DA, 0x8CCE, 0x9147, 0x8CD1, 0x93F6, + 0x8CD3, 0x956F, 0x8CDA, 0xE6CD, 0x8CDB, 0x8E5E, 0x8CDC, 0x8E92, + 0x8CDE, 0x8FDC, 0x8CE0, 0x9485, 0x8CE2, 0x8CAB, 0x8CE3, 0xE6CC, + 0x8CE4, 0xE6CB, 0x8CE6, 0x958A, 0x8CEA, 0x8EBF, 0x8CED, 0x9371, + 0x8CF0, 0xFBAD, 0x8CF4, 0xFBAE, 0x8CFA, 0xE6CF, 0x8CFB, 0xE6D0, + 0x8CFC, 0x8D77, 0x8CFD, 0xE6CE, 0x8D04, 0xE6D1, 0x8D05, 0xE6D2, + 0x8D07, 0xE6D4, 0x8D08, 0x91A1, 0x8D0A, 0xE6D3, 0x8D0B, 0x8AE4, + 0x8D0D, 0xE6D6, 0x8D0F, 0xE6D5, 0x8D10, 0xE6D7, 0x8D12, 0xFBAF, + 0x8D13, 0xE6D9, 0x8D14, 0xE6DB, 0x8D16, 0xE6DC, 0x8D64, 0x90D4, + 0x8D66, 0x8ECD, 0x8D67, 0xE6DD, 0x8D6B, 0x8A71, 0x8D6D, 0xE6DE, + 0x8D70, 0x9196, 0x8D71, 0xE6DF, 0x8D73, 0xE6E0, 0x8D74, 0x958B, + 0x8D76, 0xFBB0, 0x8D77, 0x8B4E, 0x8D81, 0xE6E1, 0x8D85, 0x92B4, + 0x8D8A, 0x897A, 0x8D99, 0xE6E2, 0x8DA3, 0x8EEF, 0x8DA8, 0x9096, + 0x8DB3, 0x91AB, 0x8DBA, 0xE6E5, 0x8DBE, 0xE6E4, 0x8DC2, 0xE6E3, + 0x8DCB, 0xE6EB, 0x8DCC, 0xE6E9, 0x8DCF, 0xE6E6, 0x8DD6, 0xE6E8, + 0x8DDA, 0xE6E7, 0x8DDB, 0xE6EA, 0x8DDD, 0x8B97, 0x8DDF, 0xE6EE, + 0x8DE1, 0x90D5, 0x8DE3, 0xE6EF, 0x8DE8, 0x8CD7, 0x8DEA, 0xE6EC, + 0x8DEB, 0xE6ED, 0x8DEF, 0x9848, 0x8DF3, 0x92B5, 0x8DF5, 0x9148, + 0x8DFC, 0xE6F0, 0x8DFF, 0xE6F3, 0x8E08, 0xE6F1, 0x8E09, 0xE6F2, + 0x8E0A, 0x9778, 0x8E0F, 0x93A5, 0x8E10, 0xE6F6, 0x8E1D, 0xE6F4, + 0x8E1E, 0xE6F5, 0x8E1F, 0xE6F7, 0x8E2A, 0xE748, 0x8E30, 0xE6FA, + 0x8E34, 0xE6FB, 0x8E35, 0xE6F9, 0x8E42, 0xE6F8, 0x8E44, 0x92FB, + 0x8E47, 0xE740, 0x8E48, 0xE744, 0x8E49, 0xE741, 0x8E4A, 0xE6FC, + 0x8E4C, 0xE742, 0x8E50, 0xE743, 0x8E55, 0xE74A, 0x8E59, 0xE745, + 0x8E5F, 0x90D6, 0x8E60, 0xE747, 0x8E63, 0xE749, 0x8E64, 0xE746, + 0x8E72, 0xE74C, 0x8E74, 0x8F52, 0x8E76, 0xE74B, 0x8E7C, 0xE74D, + 0x8E81, 0xE74E, 0x8E84, 0xE751, 0x8E85, 0xE750, 0x8E87, 0xE74F, + 0x8E8A, 0xE753, 0x8E8B, 0xE752, 0x8E8D, 0x96F4, 0x8E91, 0xE755, + 0x8E93, 0xE754, 0x8E94, 0xE756, 0x8E99, 0xE757, 0x8EA1, 0xE759, + 0x8EAA, 0xE758, 0x8EAB, 0x9067, 0x8EAC, 0xE75A, 0x8EAF, 0x8BEB, + 0x8EB0, 0xE75B, 0x8EB1, 0xE75D, 0x8EBE, 0xE75E, 0x8EC5, 0xE75F, + 0x8EC6, 0xE75C, 0x8EC8, 0xE760, 0x8ECA, 0x8ED4, 0x8ECB, 0xE761, + 0x8ECC, 0x8B4F, 0x8ECD, 0x8C52, 0x8ECF, 0xFBB2, 0x8ED2, 0x8CAC, + 0x8EDB, 0xE762, 0x8EDF, 0x93EE, 0x8EE2, 0x935D, 0x8EE3, 0xE763, + 0x8EEB, 0xE766, 0x8EF8, 0x8EB2, 0x8EFB, 0xE765, 0x8EFC, 0xE764, + 0x8EFD, 0x8C79, 0x8EFE, 0xE767, 0x8F03, 0x8A72, 0x8F05, 0xE769, + 0x8F09, 0x8DDA, 0x8F0A, 0xE768, 0x8F0C, 0xE771, 0x8F12, 0xE76B, + 0x8F13, 0xE76D, 0x8F14, 0x95E3, 0x8F15, 0xE76A, 0x8F19, 0xE76C, + 0x8F1B, 0xE770, 0x8F1C, 0xE76E, 0x8F1D, 0x8B50, 0x8F1F, 0xE76F, + 0x8F26, 0xE772, 0x8F29, 0x9479, 0x8F2A, 0x97D6, 0x8F2F, 0x8F53, + 0x8F33, 0xE773, 0x8F38, 0x9741, 0x8F39, 0xE775, 0x8F3B, 0xE774, + 0x8F3E, 0xE778, 0x8F3F, 0x9760, 0x8F42, 0xE777, 0x8F44, 0x8A8D, + 0x8F45, 0xE776, 0x8F46, 0xE77B, 0x8F49, 0xE77A, 0x8F4C, 0xE779, + 0x8F4D, 0x9351, 0x8F4E, 0xE77C, 0x8F57, 0xE77D, 0x8F5C, 0xE77E, + 0x8F5F, 0x8D8C, 0x8F61, 0x8C44, 0x8F62, 0xE780, 0x8F63, 0xE781, + 0x8F64, 0xE782, 0x8F9B, 0x9068, 0x8F9C, 0xE783, 0x8F9E, 0x8EAB, + 0x8F9F, 0xE784, 0x8FA3, 0xE785, 0x8FA7, 0x999F, 0x8FA8, 0x999E, + 0x8FAD, 0xE786, 0x8FAE, 0xE390, 0x8FAF, 0xE787, 0x8FB0, 0x9243, + 0x8FB1, 0x904A, 0x8FB2, 0x945F, 0x8FB7, 0xE788, 0x8FBA, 0x95D3, + 0x8FBB, 0x92D2, 0x8FBC, 0x8D9E, 0x8FBF, 0x9248, 0x8FC2, 0x8949, + 0x8FC4, 0x9698, 0x8FC5, 0x9076, 0x8FCE, 0x8C7D, 0x8FD1, 0x8BDF, + 0x8FD4, 0x95D4, 0x8FDA, 0xE789, 0x8FE2, 0xE78B, 0x8FE5, 0xE78A, + 0x8FE6, 0x89DE, 0x8FE9, 0x93F4, 0x8FEA, 0xE78C, 0x8FEB, 0x9497, + 0x8FED, 0x9352, 0x8FEF, 0xE78D, 0x8FF0, 0x8F71, 0x8FF4, 0xE78F, + 0x8FF7, 0x96C0, 0x8FF8, 0xE79E, 0x8FF9, 0xE791, 0x8FFA, 0xE792, + 0x8FFD, 0x92C7, 0x9000, 0x91DE, 0x9001, 0x9197, 0x9003, 0x93A6, + 0x9005, 0xE790, 0x9006, 0x8B74, 0x900B, 0xE799, 0x900D, 0xE796, + 0x900E, 0xE7A3, 0x900F, 0x93A7, 0x9010, 0x9280, 0x9011, 0xE793, + 0x9013, 0x92FC, 0x9014, 0x9372, 0x9015, 0xE794, 0x9016, 0xE798, + 0x9017, 0x9080, 0x9019, 0x9487, 0x901A, 0x92CA, 0x901D, 0x90C0, + 0x901E, 0xE797, 0x901F, 0x91AC, 0x9020, 0x91A2, 0x9021, 0xE795, + 0x9022, 0x88A7, 0x9023, 0x9841, 0x9027, 0xE79A, 0x902E, 0x91DF, + 0x9031, 0x8F54, 0x9032, 0x9069, 0x9035, 0xE79C, 0x9036, 0xE79B, + 0x9038, 0x88ED, 0x9039, 0xE79D, 0x903C, 0x954E, 0x903E, 0xE7A5, + 0x9041, 0x93D9, 0x9042, 0x908B, 0x9045, 0x9278, 0x9047, 0x8BF6, + 0x9049, 0xE7A4, 0x904A, 0x9756, 0x904B, 0x895E, 0x904D, 0x95D5, + 0x904E, 0x89DF, 0x904F, 0xE79F, 0x9050, 0xE7A0, 0x9051, 0xE7A1, + 0x9052, 0xE7A2, 0x9053, 0x93B9, 0x9054, 0x9242, 0x9055, 0x88E1, + 0x9056, 0xE7A6, 0x9058, 0xE7A7, 0x9059, 0xEAA1, 0x905C, 0x91BB, + 0x905E, 0xE7A8, 0x9060, 0x8993, 0x9061, 0x916B, 0x9063, 0x8CAD, + 0x9065, 0x9779, 0x9067, 0xFBB5, 0x9068, 0xE7A9, 0x9069, 0x934B, + 0x906D, 0x9198, 0x906E, 0x8ED5, 0x906F, 0xE7AA, 0x9072, 0xE7AD, + 0x9075, 0x8F85, 0x9076, 0xE7AB, 0x9077, 0x914A, 0x9078, 0x9149, + 0x907A, 0x88E2, 0x907C, 0x97C9, 0x907D, 0xE7AF, 0x907F, 0x94F0, + 0x9080, 0xE7B1, 0x9081, 0xE7B0, 0x9082, 0xE7AE, 0x9083, 0xE284, + 0x9084, 0x8AD2, 0x9087, 0xE78E, 0x9089, 0xE7B3, 0x908A, 0xE7B2, + 0x908F, 0xE7B4, 0x9091, 0x9757, 0x90A3, 0x93DF, 0x90A6, 0x964D, + 0x90A8, 0xE7B5, 0x90AA, 0x8ED7, 0x90AF, 0xE7B6, 0x90B1, 0xE7B7, + 0x90B5, 0xE7B8, 0x90B8, 0x9340, 0x90C1, 0x88E8, 0x90CA, 0x8D78, + 0x90CE, 0x9859, 0x90DB, 0xE7BC, 0x90DE, 0xFBB6, 0x90E1, 0x8C53, + 0x90E2, 0xE7B9, 0x90E4, 0xE7BA, 0x90E8, 0x9594, 0x90ED, 0x8A73, + 0x90F5, 0x9758, 0x90F7, 0x8BBD, 0x90FD, 0x9373, 0x9102, 0xE7BD, + 0x9112, 0xE7BE, 0x9115, 0xFBB8, 0x9119, 0xE7BF, 0x9127, 0xFBB9, + 0x912D, 0x9341, 0x9130, 0xE7C1, 0x9132, 0xE7C0, 0x9149, 0x93D1, + 0x914A, 0xE7C2, 0x914B, 0x8F55, 0x914C, 0x8EDE, 0x914D, 0x947A, + 0x914E, 0x9291, 0x9152, 0x8EF0, 0x9154, 0x908C, 0x9156, 0xE7C3, + 0x9158, 0xE7C4, 0x9162, 0x907C, 0x9163, 0xE7C5, 0x9165, 0xE7C6, + 0x9169, 0xE7C7, 0x916A, 0x978F, 0x916C, 0x8F56, 0x9172, 0xE7C9, + 0x9173, 0xE7C8, 0x9175, 0x8D79, 0x9177, 0x8D93, 0x9178, 0x8E5F, + 0x9182, 0xE7CC, 0x9187, 0x8F86, 0x9189, 0xE7CB, 0x918B, 0xE7CA, + 0x918D, 0x91E7, 0x9190, 0x8CED, 0x9192, 0x90C1, 0x9197, 0x94AE, + 0x919C, 0x8F58, 0x91A2, 0xE7CD, 0x91A4, 0x8FDD, 0x91AA, 0xE7D0, + 0x91AB, 0xE7CE, 0x91AF, 0xE7CF, 0x91B4, 0xE7D2, 0x91B5, 0xE7D1, + 0x91B8, 0x8FF8, 0x91BA, 0xE7D3, 0x91C0, 0xE7D4, 0x91C1, 0xE7D5, + 0x91C6, 0x94CE, 0x91C7, 0x8DD1, 0x91C8, 0x8EDF, 0x91C9, 0xE7D6, + 0x91CB, 0xE7D7, 0x91CC, 0x97A2, 0x91CD, 0x8F64, 0x91CE, 0x96EC, + 0x91CF, 0x97CA, 0x91D0, 0xE7D8, 0x91D1, 0x8BE0, 0x91D6, 0xE7D9, + 0x91D7, 0xFBBB, 0x91D8, 0x9342, 0x91DA, 0xFBBA, 0x91DB, 0xE7DC, + 0x91DC, 0x8A98, 0x91DD, 0x906A, 0x91DE, 0xFBBC, 0x91DF, 0xE7DA, + 0x91E1, 0xE7DB, 0x91E3, 0x92DE, 0x91E4, 0xFBBF, 0x91E5, 0xFBC0, + 0x91E6, 0x9674, 0x91E7, 0x8BFA, 0x91ED, 0xFBBD, 0x91EE, 0xFBBE, + 0x91F5, 0xE7DE, 0x91F6, 0xE7DF, 0x91FC, 0xE7DD, 0x91FF, 0xE7E1, + 0x9206, 0xFBC1, 0x920A, 0xFBC3, 0x920D, 0x93DD, 0x920E, 0x8A62, + 0x9210, 0xFBC2, 0x9211, 0xE7E5, 0x9214, 0xE7E2, 0x9215, 0xE7E4, + 0x921E, 0xE7E0, 0x9229, 0xE86E, 0x922C, 0xE7E3, 0x9234, 0x97E9, + 0x9237, 0x8CD8, 0x9239, 0xFBCA, 0x923A, 0xFBC4, 0x923C, 0xFBC6, + 0x923F, 0xE7ED, 0x9240, 0xFBC5, 0x9244, 0x9353, 0x9245, 0xE7E8, + 0x9248, 0xE7EB, 0x9249, 0xE7E9, 0x924B, 0xE7EE, 0x924E, 0xFBC7, + 0x9250, 0xE7EF, 0x9251, 0xFBC9, 0x9257, 0xE7E7, 0x9259, 0xFBC8, + 0x925A, 0xE7F4, 0x925B, 0x8994, 0x925E, 0xE7E6, 0x9262, 0x94AB, + 0x9264, 0xE7EA, 0x9266, 0x8FDE, 0x9267, 0xFBCB, 0x9271, 0x8D7A, + 0x9277, 0xFBCD, 0x9278, 0xFBCE, 0x927E, 0x9667, 0x9280, 0x8BE2, + 0x9283, 0x8F65, 0x9285, 0x93BA, 0x9288, 0xFA5F, 0x9291, 0x914C, + 0x9293, 0xE7F2, 0x9295, 0xE7EC, 0x9296, 0xE7F1, 0x9298, 0x96C1, + 0x929A, 0x92B6, 0x929B, 0xE7F3, 0x929C, 0xE7F0, 0x92A7, 0xFBCC, + 0x92AD, 0x914B, 0x92B7, 0xE7F7, 0x92B9, 0xE7F6, 0x92CF, 0xE7F5, + 0x92D0, 0xFBD2, 0x92D2, 0x964E, 0x92D3, 0xFBD6, 0x92D5, 0xFBD4, + 0x92D7, 0xFBD0, 0x92D9, 0xFBD1, 0x92E0, 0xFBD5, 0x92E4, 0x8F9B, + 0x92E7, 0xFBCF, 0x92E9, 0xE7F8, 0x92EA, 0x95DD, 0x92ED, 0x8973, + 0x92F2, 0x9565, 0x92F3, 0x9292, 0x92F8, 0x8B98, 0x92F9, 0xFA65, + 0x92FA, 0xE7FA, 0x92FB, 0xFBD9, 0x92FC, 0x8D7C, 0x92FF, 0xFBDC, + 0x9302, 0xFBDE, 0x9306, 0x8E4B, 0x930F, 0xE7F9, 0x9310, 0x908D, + 0x9318, 0x908E, 0x9319, 0xE840, 0x931A, 0xE842, 0x931D, 0xFBDD, + 0x931E, 0xFBDB, 0x9320, 0x8FF9, 0x9321, 0xFBD8, 0x9322, 0xE841, + 0x9323, 0xE843, 0x9325, 0xFBD7, 0x9326, 0x8BD1, 0x9328, 0x9564, + 0x932B, 0x8EE0, 0x932C, 0x9842, 0x932E, 0xE7FC, 0x932F, 0x8DF6, + 0x9332, 0x985E, 0x9335, 0xE845, 0x933A, 0xE844, 0x933B, 0xE846, + 0x9344, 0xE7FB, 0x9348, 0xFA5E, 0x934B, 0x93E7, 0x934D, 0x9374, + 0x9354, 0x92D5, 0x9356, 0xE84B, 0x9357, 0xFBE0, 0x935B, 0x9262, + 0x935C, 0xE847, 0x9360, 0xE848, 0x936C, 0x8C4C, 0x936E, 0xE84A, + 0x9370, 0xFBDF, 0x9375, 0x8CAE, 0x937C, 0xE849, 0x937E, 0x8FDF, + 0x938C, 0x8A99, 0x9394, 0xE84F, 0x9396, 0x8DBD, 0x9397, 0x9199, + 0x939A, 0x92C8, 0x93A4, 0xFBE1, 0x93A7, 0x8A5A, 0x93AC, 0xE84D, + 0x93AD, 0xE84E, 0x93AE, 0x92C1, 0x93B0, 0xE84C, 0x93B9, 0xE850, + 0x93C3, 0xE856, 0x93C6, 0xFBE2, 0x93C8, 0xE859, 0x93D0, 0xE858, + 0x93D1, 0x934C, 0x93D6, 0xE851, 0x93D7, 0xE852, 0x93D8, 0xE855, + 0x93DD, 0xE857, 0x93DE, 0xFBE3, 0x93E1, 0x8BBE, 0x93E4, 0xE85A, + 0x93E5, 0xE854, 0x93E8, 0xE853, 0x93F8, 0xFBE4, 0x9403, 0xE85E, + 0x9407, 0xE85F, 0x9410, 0xE860, 0x9413, 0xE85D, 0x9414, 0xE85C, + 0x9418, 0x8FE0, 0x9419, 0x93A8, 0x941A, 0xE85B, 0x9421, 0xE864, + 0x942B, 0xE862, 0x9431, 0xFBE5, 0x9435, 0xE863, 0x9436, 0xE861, + 0x9438, 0x91F6, 0x943A, 0xE865, 0x9441, 0xE866, 0x9444, 0xE868, + 0x9445, 0xFBE6, 0x9448, 0xFBE7, 0x9451, 0x8AD3, 0x9452, 0xE867, + 0x9453, 0x96F8, 0x945A, 0xE873, 0x945B, 0xE869, 0x945E, 0xE86C, + 0x9460, 0xE86A, 0x9462, 0xE86B, 0x946A, 0xE86D, 0x9470, 0xE86F, + 0x9475, 0xE870, 0x9477, 0xE871, 0x947C, 0xE874, 0x947D, 0xE872, + 0x947E, 0xE875, 0x947F, 0xE877, 0x9481, 0xE876, 0x9577, 0x92B7, + 0x9580, 0x96E5, 0x9582, 0xE878, 0x9583, 0x914D, 0x9587, 0xE879, + 0x9589, 0x95C2, 0x958A, 0xE87A, 0x958B, 0x8A4A, 0x958F, 0x895B, + 0x9591, 0x8AD5, 0x9592, 0xFBE8, 0x9593, 0x8AD4, 0x9594, 0xE87B, + 0x9596, 0xE87C, 0x9598, 0xE87D, 0x9599, 0xE87E, 0x95A0, 0xE880, + 0x95A2, 0x8AD6, 0x95A3, 0x8A74, 0x95A4, 0x8D7D, 0x95A5, 0x94B4, + 0x95A7, 0xE882, 0x95A8, 0xE881, 0x95AD, 0xE883, 0x95B2, 0x897B, + 0x95B9, 0xE886, 0x95BB, 0xE885, 0x95BC, 0xE884, 0x95BE, 0xE887, + 0x95C3, 0xE88A, 0x95C7, 0x88C5, 0x95CA, 0xE888, 0x95CC, 0xE88C, + 0x95CD, 0xE88B, 0x95D4, 0xE88E, 0x95D5, 0xE88D, 0x95D6, 0xE88F, + 0x95D8, 0x93AC, 0x95DC, 0xE890, 0x95E1, 0xE891, 0x95E2, 0xE893, + 0x95E5, 0xE892, 0x961C, 0x958C, 0x9621, 0xE894, 0x9628, 0xE895, + 0x962A, 0x8DE3, 0x962E, 0xE896, 0x962F, 0xE897, 0x9632, 0x9668, + 0x963B, 0x916A, 0x963F, 0x88A2, 0x9640, 0x91C9, 0x9642, 0xE898, + 0x9644, 0x958D, 0x964B, 0xE89B, 0x964C, 0xE899, 0x964D, 0x8D7E, + 0x964F, 0xE89A, 0x9650, 0x8CC0, 0x965B, 0x95C3, 0x965C, 0xE89D, + 0x965D, 0xE89F, 0x965E, 0xE89E, 0x965F, 0xE8A0, 0x9662, 0x8940, + 0x9663, 0x9077, 0x9664, 0x8F9C, 0x9665, 0x8AD7, 0x9666, 0xE8A1, + 0x966A, 0x9486, 0x966C, 0xE8A3, 0x9670, 0x8941, 0x9672, 0xE8A2, + 0x9673, 0x92C2, 0x9675, 0x97CB, 0x9676, 0x93A9, 0x9677, 0xE89C, + 0x9678, 0x97A4, 0x967A, 0x8CAF, 0x967D, 0x977A, 0x9685, 0x8BF7, + 0x9686, 0x97B2, 0x9688, 0x8C47, 0x968A, 0x91E0, 0x968B, 0xE440, + 0x968D, 0xE8A4, 0x968E, 0x8A4B, 0x968F, 0x908F, 0x9694, 0x8A75, + 0x9695, 0xE8A6, 0x9697, 0xE8A7, 0x9698, 0xE8A5, 0x9699, 0x8C84, + 0x969B, 0x8DDB, 0x969C, 0x8FE1, 0x969D, 0xFBEB, 0x96A0, 0x8942, + 0x96A3, 0x97D7, 0x96A7, 0xE8A9, 0x96A8, 0xE7AC, 0x96AA, 0xE8A8, + 0x96AF, 0xFBEC, 0x96B0, 0xE8AC, 0x96B1, 0xE8AA, 0x96B2, 0xE8AB, + 0x96B4, 0xE8AD, 0x96B6, 0xE8AE, 0x96B7, 0x97EA, 0x96B8, 0xE8AF, + 0x96B9, 0xE8B0, 0x96BB, 0x90C7, 0x96BC, 0x94B9, 0x96C0, 0x909D, + 0x96C1, 0x8AE5, 0x96C4, 0x9759, 0x96C5, 0x89EB, 0x96C6, 0x8F57, + 0x96C7, 0x8CD9, 0x96C9, 0xE8B3, 0x96CB, 0xE8B2, 0x96CC, 0x8E93, + 0x96CD, 0xE8B4, 0x96CE, 0xE8B1, 0x96D1, 0x8E47, 0x96D5, 0xE8B8, + 0x96D6, 0xE5AB, 0x96D9, 0x99D4, 0x96DB, 0x9097, 0x96DC, 0xE8B6, + 0x96E2, 0x97A3, 0x96E3, 0x93EF, 0x96E8, 0x894A, 0x96EA, 0x90E1, + 0x96EB, 0x8EB4, 0x96F0, 0x95B5, 0x96F2, 0x895F, 0x96F6, 0x97EB, + 0x96F7, 0x978B, 0x96F9, 0xE8B9, 0x96FB, 0x9364, 0x9700, 0x8EF9, + 0x9704, 0xE8BA, 0x9706, 0xE8BB, 0x9707, 0x906B, 0x9708, 0xE8BC, + 0x970A, 0x97EC, 0x970D, 0xE8B7, 0x970E, 0xE8BE, 0x970F, 0xE8C0, + 0x9711, 0xE8BF, 0x9713, 0xE8BD, 0x9716, 0xE8C1, 0x9719, 0xE8C2, + 0x971C, 0x919A, 0x971E, 0x89E0, 0x9724, 0xE8C3, 0x9727, 0x96B6, + 0x972A, 0xE8C4, 0x9730, 0xE8C5, 0x9732, 0x9849, 0x9733, 0xFBED, + 0x9738, 0x9E50, 0x9739, 0xE8C6, 0x973B, 0xFBEE, 0x973D, 0xE8C7, + 0x973E, 0xE8C8, 0x9742, 0xE8CC, 0x9743, 0xFBEF, 0x9744, 0xE8C9, + 0x9746, 0xE8CA, 0x9748, 0xE8CB, 0x9749, 0xE8CD, 0x974D, 0xFBF0, + 0x974F, 0xFBF1, 0x9751, 0xFBF2, 0x9752, 0x90C2, 0x9755, 0xFBF3, + 0x9756, 0x96F5, 0x9759, 0x90C3, 0x975C, 0xE8CE, 0x975E, 0x94F1, + 0x9760, 0xE8CF, 0x9761, 0xEA72, 0x9762, 0x96CA, 0x9764, 0xE8D0, + 0x9766, 0xE8D1, 0x9768, 0xE8D2, 0x9769, 0x8A76, 0x976B, 0xE8D4, + 0x976D, 0x9078, 0x9771, 0xE8D5, 0x9774, 0x8C43, 0x9779, 0xE8D6, + 0x977A, 0xE8DA, 0x977C, 0xE8D8, 0x9781, 0xE8D9, 0x9784, 0x8A93, + 0x9785, 0xE8D7, 0x9786, 0xE8DB, 0x978B, 0xE8DC, 0x978D, 0x88C6, + 0x978F, 0xE8DD, 0x9790, 0xE8DE, 0x9798, 0x8FE2, 0x979C, 0xE8DF, + 0x97A0, 0x8B66, 0x97A3, 0xE8E2, 0x97A6, 0xE8E1, 0x97A8, 0xE8E0, + 0x97AB, 0xE691, 0x97AD, 0x95DA, 0x97B3, 0xE8E3, 0x97B4, 0xE8E4, + 0x97C3, 0xE8E5, 0x97C6, 0xE8E6, 0x97C8, 0xE8E7, 0x97CB, 0xE8E8, + 0x97D3, 0x8AD8, 0x97DC, 0xE8E9, 0x97ED, 0xE8EA, 0x97EE, 0x9442, + 0x97F2, 0xE8EC, 0x97F3, 0x89B9, 0x97F5, 0xE8EF, 0x97F6, 0xE8EE, + 0x97FB, 0x8943, 0x97FF, 0x8BBF, 0x9801, 0x95C5, 0x9802, 0x92B8, + 0x9803, 0x8DA0, 0x9805, 0x8D80, 0x9806, 0x8F87, 0x9808, 0x907B, + 0x980C, 0xE8F1, 0x980F, 0xE8F0, 0x9810, 0x9761, 0x9811, 0x8AE6, + 0x9812, 0x94D0, 0x9813, 0x93DA, 0x9817, 0x909C, 0x9818, 0x97CC, + 0x981A, 0x8C7A, 0x9821, 0xE8F4, 0x9824, 0xE8F3, 0x982C, 0x966A, + 0x982D, 0x93AA, 0x9834, 0x896F, 0x9837, 0xE8F5, 0x9838, 0xE8F2, + 0x983B, 0x9570, 0x983C, 0x978A, 0x983D, 0xE8F6, 0x9846, 0xE8F7, + 0x984B, 0xE8F9, 0x984C, 0x91E8, 0x984D, 0x8A7A, 0x984E, 0x8A7B, + 0x984F, 0xE8F8, 0x9854, 0x8AE7, 0x9855, 0x8CB0, 0x9857, 0xFBF4, + 0x9858, 0x8AE8, 0x985B, 0x935E, 0x985E, 0x97DE, 0x9865, 0xFBF5, + 0x9867, 0x8CDA, 0x986B, 0xE8FA, 0x986F, 0xE8FB, 0x9870, 0xE8FC, + 0x9871, 0xE940, 0x9873, 0xE942, 0x9874, 0xE941, 0x98A8, 0x9597, + 0x98AA, 0xE943, 0x98AF, 0xE944, 0x98B1, 0xE945, 0x98B6, 0xE946, + 0x98C3, 0xE948, 0x98C4, 0xE947, 0x98C6, 0xE949, 0x98DB, 0x94F2, + 0x98DC, 0xE3CA, 0x98DF, 0x9048, 0x98E2, 0x8B51, 0x98E9, 0xE94A, + 0x98EB, 0xE94B, 0x98ED, 0x99AA, 0x98EE, 0x9F5A, 0x98EF, 0x94D1, + 0x98F2, 0x88F9, 0x98F4, 0x88B9, 0x98FC, 0x8E94, 0x98FD, 0x964F, + 0x98FE, 0x8FFC, 0x9903, 0xE94C, 0x9905, 0x96DD, 0x9909, 0xE94D, + 0x990A, 0x977B, 0x990C, 0x8961, 0x9910, 0x8E60, 0x9912, 0xE94E, + 0x9913, 0x89EC, 0x9914, 0xE94F, 0x9918, 0xE950, 0x991D, 0xE952, + 0x991E, 0xE953, 0x9920, 0xE955, 0x9921, 0xE951, 0x9924, 0xE954, + 0x9927, 0xFBF8, 0x9928, 0x8AD9, 0x992C, 0xE956, 0x992E, 0xE957, + 0x993D, 0xE958, 0x993E, 0xE959, 0x9942, 0xE95A, 0x9945, 0xE95C, + 0x9949, 0xE95B, 0x994B, 0xE95E, 0x994C, 0xE961, 0x9950, 0xE95D, + 0x9951, 0xE95F, 0x9952, 0xE960, 0x9955, 0xE962, 0x9957, 0x8BC0, + 0x9996, 0x8EF1, 0x9997, 0xE963, 0x9998, 0xE964, 0x9999, 0x8D81, + 0x999E, 0xFBFA, 0x99A5, 0xE965, 0x99A8, 0x8A5D, 0x99AC, 0x946E, + 0x99AD, 0xE966, 0x99AE, 0xE967, 0x99B3, 0x9279, 0x99B4, 0x93E9, + 0x99BC, 0xE968, 0x99C1, 0x949D, 0x99C4, 0x91CA, 0x99C5, 0x8977, + 0x99C6, 0x8BEC, 0x99C8, 0x8BED, 0x99D0, 0x9293, 0x99D1, 0xE96D, + 0x99D2, 0x8BEE, 0x99D5, 0x89ED, 0x99D8, 0xE96C, 0x99DB, 0xE96A, + 0x99DD, 0xE96B, 0x99DF, 0xE969, 0x99E2, 0xE977, 0x99ED, 0xE96E, + 0x99EE, 0xE96F, 0x99F1, 0xE970, 0x99F2, 0xE971, 0x99F8, 0xE973, + 0x99FB, 0xE972, 0x99FF, 0x8F78, 0x9A01, 0xE974, 0x9A05, 0xE976, + 0x9A0E, 0x8B52, 0x9A0F, 0xE975, 0x9A12, 0x919B, 0x9A13, 0x8CB1, + 0x9A19, 0xE978, 0x9A28, 0x91CB, 0x9A2B, 0xE979, 0x9A30, 0x93AB, + 0x9A37, 0xE97A, 0x9A3E, 0xE980, 0x9A40, 0xE97D, 0x9A42, 0xE97C, + 0x9A43, 0xE97E, 0x9A45, 0xE97B, 0x9A4D, 0xE982, 0x9A4E, 0xFBFB, + 0x9A55, 0xE981, 0x9A57, 0xE984, 0x9A5A, 0x8BC1, 0x9A5B, 0xE983, + 0x9A5F, 0xE985, 0x9A62, 0xE986, 0x9A64, 0xE988, 0x9A65, 0xE987, + 0x9A69, 0xE989, 0x9A6A, 0xE98B, 0x9A6B, 0xE98A, 0x9AA8, 0x8D9C, + 0x9AAD, 0xE98C, 0x9AB0, 0xE98D, 0x9AB8, 0x8A5B, 0x9ABC, 0xE98E, + 0x9AC0, 0xE98F, 0x9AC4, 0x9091, 0x9ACF, 0xE990, 0x9AD1, 0xE991, + 0x9AD3, 0xE992, 0x9AD4, 0xE993, 0x9AD8, 0x8D82, 0x9AD9, 0xFBFC, + 0x9ADC, 0xFC40, 0x9ADE, 0xE994, 0x9ADF, 0xE995, 0x9AE2, 0xE996, + 0x9AE3, 0xE997, 0x9AE6, 0xE998, 0x9AEA, 0x94AF, 0x9AEB, 0xE99A, + 0x9AED, 0x9545, 0x9AEE, 0xE99B, 0x9AEF, 0xE999, 0x9AF1, 0xE99D, + 0x9AF4, 0xE99C, 0x9AF7, 0xE99E, 0x9AFB, 0xE99F, 0x9B06, 0xE9A0, + 0x9B18, 0xE9A1, 0x9B1A, 0xE9A2, 0x9B1F, 0xE9A3, 0x9B22, 0xE9A4, + 0x9B23, 0xE9A5, 0x9B25, 0xE9A6, 0x9B27, 0xE9A7, 0x9B28, 0xE9A8, + 0x9B29, 0xE9A9, 0x9B2A, 0xE9AA, 0x9B2E, 0xE9AB, 0x9B2F, 0xE9AC, + 0x9B31, 0x9F54, 0x9B32, 0xE9AD, 0x9B3B, 0xE2F6, 0x9B3C, 0x8B53, + 0x9B41, 0x8A40, 0x9B42, 0x8DB0, 0x9B43, 0xE9AF, 0x9B44, 0xE9AE, + 0x9B45, 0x96A3, 0x9B4D, 0xE9B1, 0x9B4E, 0xE9B2, 0x9B4F, 0xE9B0, + 0x9B51, 0xE9B3, 0x9B54, 0x9682, 0x9B58, 0xE9B4, 0x9B5A, 0x8B9B, + 0x9B6F, 0x9844, 0x9B72, 0xFC42, 0x9B74, 0xE9B5, 0x9B75, 0xFC41, + 0x9B83, 0xE9B7, 0x9B8E, 0x88BC, 0x9B8F, 0xFC43, 0x9B91, 0xE9B8, + 0x9B92, 0x95A9, 0x9B93, 0xE9B6, 0x9B96, 0xE9B9, 0x9B97, 0xE9BA, + 0x9B9F, 0xE9BB, 0x9BA0, 0xE9BC, 0x9BA8, 0xE9BD, 0x9BAA, 0x968E, + 0x9BAB, 0x8E4C, 0x9BAD, 0x8DF8, 0x9BAE, 0x914E, 0x9BB1, 0xFC44, + 0x9BB4, 0xE9BE, 0x9BB9, 0xE9C1, 0x9BBB, 0xFC45, 0x9BC0, 0xE9BF, + 0x9BC6, 0xE9C2, 0x9BC9, 0x8CEF, 0x9BCA, 0xE9C0, 0x9BCF, 0xE9C3, + 0x9BD1, 0xE9C4, 0x9BD2, 0xE9C5, 0x9BD4, 0xE9C9, 0x9BD6, 0x8E49, + 0x9BDB, 0x91E2, 0x9BE1, 0xE9CA, 0x9BE2, 0xE9C7, 0x9BE3, 0xE9C6, + 0x9BE4, 0xE9C8, 0x9BE8, 0x8C7E, 0x9BF0, 0xE9CE, 0x9BF1, 0xE9CD, + 0x9BF2, 0xE9CC, 0x9BF5, 0x88B1, 0x9C00, 0xFC46, 0x9C04, 0xE9D8, + 0x9C06, 0xE9D4, 0x9C08, 0xE9D5, 0x9C09, 0xE9D1, 0x9C0A, 0xE9D7, + 0x9C0C, 0xE9D3, 0x9C0D, 0x8A82, 0x9C10, 0x986B, 0x9C12, 0xE9D6, + 0x9C13, 0xE9D2, 0x9C14, 0xE9D0, 0x9C15, 0xE9CF, 0x9C1B, 0xE9DA, + 0x9C21, 0xE9DD, 0x9C24, 0xE9DC, 0x9C25, 0xE9DB, 0x9C2D, 0x9568, + 0x9C2E, 0xE9D9, 0x9C2F, 0x88F1, 0x9C30, 0xE9DE, 0x9C32, 0xE9E0, + 0x9C39, 0x8A8F, 0x9C3A, 0xE9CB, 0x9C3B, 0x8956, 0x9C3E, 0xE9E2, + 0x9C46, 0xE9E1, 0x9C47, 0xE9DF, 0x9C48, 0x924C, 0x9C52, 0x9690, + 0x9C57, 0x97D8, 0x9C5A, 0xE9E3, 0x9C60, 0xE9E4, 0x9C67, 0xE9E5, + 0x9C76, 0xE9E6, 0x9C78, 0xE9E7, 0x9CE5, 0x92B9, 0x9CE7, 0xE9E8, + 0x9CE9, 0x94B5, 0x9CEB, 0xE9ED, 0x9CEC, 0xE9E9, 0x9CF0, 0xE9EA, + 0x9CF3, 0x9650, 0x9CF4, 0x96C2, 0x9CF6, 0x93CE, 0x9D03, 0xE9EE, + 0x9D06, 0xE9EF, 0x9D07, 0x93BC, 0x9D08, 0xE9EC, 0x9D09, 0xE9EB, + 0x9D0E, 0x89A8, 0x9D12, 0xE9F7, 0x9D15, 0xE9F6, 0x9D1B, 0x8995, + 0x9D1F, 0xE9F4, 0x9D23, 0xE9F3, 0x9D26, 0xE9F1, 0x9D28, 0x8A9B, + 0x9D2A, 0xE9F0, 0x9D2B, 0x8EB0, 0x9D2C, 0x89A7, 0x9D3B, 0x8D83, + 0x9D3E, 0xE9FA, 0x9D3F, 0xE9F9, 0x9D41, 0xE9F8, 0x9D44, 0xE9F5, + 0x9D46, 0xE9FB, 0x9D48, 0xE9FC, 0x9D50, 0xEA44, 0x9D51, 0xEA43, + 0x9D59, 0xEA45, 0x9D5C, 0x894C, 0x9D5D, 0xEA40, 0x9D5E, 0xEA41, + 0x9D60, 0x8D94, 0x9D61, 0x96B7, 0x9D64, 0xEA42, 0x9D6B, 0xFC48, + 0x9D6C, 0x9651, 0x9D6F, 0xEA4A, 0x9D70, 0xFC47, 0x9D72, 0xEA46, + 0x9D7A, 0xEA4B, 0x9D87, 0xEA48, 0x9D89, 0xEA47, 0x9D8F, 0x8C7B, + 0x9D9A, 0xEA4C, 0x9DA4, 0xEA4D, 0x9DA9, 0xEA4E, 0x9DAB, 0xEA49, + 0x9DAF, 0xE9F2, 0x9DB2, 0xEA4F, 0x9DB4, 0x92DF, 0x9DB8, 0xEA53, + 0x9DBA, 0xEA54, 0x9DBB, 0xEA52, 0x9DC1, 0xEA51, 0x9DC2, 0xEA57, + 0x9DC4, 0xEA50, 0x9DC6, 0xEA55, 0x9DCF, 0xEA56, 0x9DD3, 0xEA59, + 0x9DD9, 0xEA58, 0x9DE6, 0xEA5B, 0x9DED, 0xEA5C, 0x9DEF, 0xEA5D, + 0x9DF2, 0x9868, 0x9DF8, 0xEA5A, 0x9DF9, 0x91E9, 0x9DFA, 0x8DEB, + 0x9DFD, 0xEA5E, 0x9E19, 0xFC4A, 0x9E1A, 0xEA5F, 0x9E1B, 0xEA60, + 0x9E1E, 0xEA61, 0x9E75, 0xEA62, 0x9E78, 0x8CB2, 0x9E79, 0xEA63, + 0x9E7D, 0xEA64, 0x9E7F, 0x8EAD, 0x9E81, 0xEA65, 0x9E88, 0xEA66, + 0x9E8B, 0xEA67, 0x9E8C, 0xEA68, 0x9E91, 0xEA6B, 0x9E92, 0xEA69, + 0x9E93, 0x985B, 0x9E95, 0xEA6A, 0x9E97, 0x97ED, 0x9E9D, 0xEA6C, + 0x9E9F, 0x97D9, 0x9EA5, 0xEA6D, 0x9EA6, 0x949E, 0x9EA9, 0xEA6E, + 0x9EAA, 0xEA70, 0x9EAD, 0xEA71, 0x9EB8, 0xEA6F, 0x9EB9, 0x8D8D, + 0x9EBA, 0x96CB, 0x9EBB, 0x9683, 0x9EBC, 0x9BF5, 0x9EBE, 0x9F80, + 0x9EBF, 0x969B, 0x9EC4, 0x89A9, 0x9ECC, 0xEA73, 0x9ECD, 0x8B6F, + 0x9ECE, 0xEA74, 0x9ECF, 0xEA75, 0x9ED0, 0xEA76, 0x9ED1, 0xFC4B, + 0x9ED2, 0x8D95, 0x9ED4, 0xEA77, 0x9ED8, 0xE0D2, 0x9ED9, 0x96D9, + 0x9EDB, 0x91E1, 0x9EDC, 0xEA78, 0x9EDD, 0xEA7A, 0x9EDE, 0xEA79, + 0x9EE0, 0xEA7B, 0x9EE5, 0xEA7C, 0x9EE8, 0xEA7D, 0x9EEF, 0xEA7E, + 0x9EF4, 0xEA80, 0x9EF6, 0xEA81, 0x9EF7, 0xEA82, 0x9EF9, 0xEA83, + 0x9EFB, 0xEA84, 0x9EFC, 0xEA85, 0x9EFD, 0xEA86, 0x9F07, 0xEA87, + 0x9F08, 0xEA88, 0x9F0E, 0x9343, 0x9F13, 0x8CDB, 0x9F15, 0xEA8A, + 0x9F20, 0x916C, 0x9F21, 0xEA8B, 0x9F2C, 0xEA8C, 0x9F3B, 0x9540, + 0x9F3E, 0xEA8D, 0x9F4A, 0xEA8E, 0x9F4B, 0xE256, 0x9F4E, 0xE6D8, + 0x9F4F, 0xE8EB, 0x9F52, 0xEA8F, 0x9F54, 0xEA90, 0x9F5F, 0xEA92, + 0x9F60, 0xEA93, 0x9F61, 0xEA94, 0x9F62, 0x97EE, 0x9F63, 0xEA91, + 0x9F66, 0xEA95, 0x9F67, 0xEA96, 0x9F6A, 0xEA98, 0x9F6C, 0xEA97, + 0x9F72, 0xEA9A, 0x9F76, 0xEA9B, 0x9F77, 0xEA99, 0x9F8D, 0x97B4, + 0x9F95, 0xEA9C, 0x9F9C, 0xEA9D, 0x9F9D, 0xE273, 0x9FA0, 0xEA9E, + 0xF929, 0xFAE0, 0xF9DC, 0xFBE9, 0xFA0E, 0xFA90, 0xFA0F, 0xFA9B, + 0xFA10, 0xFA9C, 0xFA11, 0xFAB1, 0xFA12, 0xFAD8, 0xFA13, 0xFAE8, + 0xFA14, 0xFAEA, 0xFA15, 0xFB58, 0xFA16, 0xFB5E, 0xFA17, 0xFB75, + 0xFA18, 0xFB7D, 0xFA19, 0xFB7E, 0xFA1A, 0xFB80, 0xFA1B, 0xFB82, + 0xFA1C, 0xFB86, 0xFA1D, 0xFB89, 0xFA1E, 0xFB92, 0xFA1F, 0xFB9D, + 0xFA20, 0xFB9F, 0xFA21, 0xFBA0, 0xFA22, 0xFBA9, 0xFA23, 0xFBB1, + 0xFA24, 0xFBB3, 0xFA25, 0xFBB4, 0xFA26, 0xFBB7, 0xFA27, 0xFBD3, + 0xFA28, 0xFBDA, 0xFA29, 0xFBEA, 0xFA2A, 0xFBF6, 0xFA2B, 0xFBF7, + 0xFA2C, 0xFBF9, 0xFA2D, 0xFC49, 0xFF01, 0x8149, 0xFF02, 0xFA57, + 0xFF03, 0x8194, 0xFF04, 0x8190, 0xFF05, 0x8193, 0xFF06, 0x8195, + 0xFF07, 0xFA56, 0xFF08, 0x8169, 0xFF09, 0x816A, 0xFF0A, 0x8196, + 0xFF0B, 0x817B, 0xFF0C, 0x8143, 0xFF0D, 0x817C, 0xFF0E, 0x8144, + 0xFF0F, 0x815E, 0xFF10, 0x824F, 0xFF11, 0x8250, 0xFF12, 0x8251, + 0xFF13, 0x8252, 0xFF14, 0x8253, 0xFF15, 0x8254, 0xFF16, 0x8255, + 0xFF17, 0x8256, 0xFF18, 0x8257, 0xFF19, 0x8258, 0xFF1A, 0x8146, + 0xFF1B, 0x8147, 0xFF1C, 0x8183, 0xFF1D, 0x8181, 0xFF1E, 0x8184, + 0xFF1F, 0x8148, 0xFF20, 0x8197, 0xFF21, 0x8260, 0xFF22, 0x8261, + 0xFF23, 0x8262, 0xFF24, 0x8263, 0xFF25, 0x8264, 0xFF26, 0x8265, + 0xFF27, 0x8266, 0xFF28, 0x8267, 0xFF29, 0x8268, 0xFF2A, 0x8269, + 0xFF2B, 0x826A, 0xFF2C, 0x826B, 0xFF2D, 0x826C, 0xFF2E, 0x826D, + 0xFF2F, 0x826E, 0xFF30, 0x826F, 0xFF31, 0x8270, 0xFF32, 0x8271, + 0xFF33, 0x8272, 0xFF34, 0x8273, 0xFF35, 0x8274, 0xFF36, 0x8275, + 0xFF37, 0x8276, 0xFF38, 0x8277, 0xFF39, 0x8278, 0xFF3A, 0x8279, + 0xFF3B, 0x816D, 0xFF3C, 0x815F, 0xFF3D, 0x816E, 0xFF3E, 0x814F, + 0xFF3F, 0x8151, 0xFF40, 0x814D, 0xFF41, 0x8281, 0xFF42, 0x8282, + 0xFF43, 0x8283, 0xFF44, 0x8284, 0xFF45, 0x8285, 0xFF46, 0x8286, + 0xFF47, 0x8287, 0xFF48, 0x8288, 0xFF49, 0x8289, 0xFF4A, 0x828A, + 0xFF4B, 0x828B, 0xFF4C, 0x828C, 0xFF4D, 0x828D, 0xFF4E, 0x828E, + 0xFF4F, 0x828F, 0xFF50, 0x8290, 0xFF51, 0x8291, 0xFF52, 0x8292, + 0xFF53, 0x8293, 0xFF54, 0x8294, 0xFF55, 0x8295, 0xFF56, 0x8296, + 0xFF57, 0x8297, 0xFF58, 0x8298, 0xFF59, 0x8299, 0xFF5A, 0x829A, + 0xFF5B, 0x816F, 0xFF5C, 0x8162, 0xFF5D, 0x8170, 0xFF5E, 0x8160, + 0xFF61, 0x00A1, 0xFF62, 0x00A2, 0xFF63, 0x00A3, 0xFF64, 0x00A4, + 0xFF65, 0x00A5, 0xFF66, 0x00A6, 0xFF67, 0x00A7, 0xFF68, 0x00A8, + 0xFF69, 0x00A9, 0xFF6A, 0x00AA, 0xFF6B, 0x00AB, 0xFF6C, 0x00AC, + 0xFF6D, 0x00AD, 0xFF6E, 0x00AE, 0xFF6F, 0x00AF, 0xFF70, 0x00B0, + 0xFF71, 0x00B1, 0xFF72, 0x00B2, 0xFF73, 0x00B3, 0xFF74, 0x00B4, + 0xFF75, 0x00B5, 0xFF76, 0x00B6, 0xFF77, 0x00B7, 0xFF78, 0x00B8, + 0xFF79, 0x00B9, 0xFF7A, 0x00BA, 0xFF7B, 0x00BB, 0xFF7C, 0x00BC, + 0xFF7D, 0x00BD, 0xFF7E, 0x00BE, 0xFF7F, 0x00BF, 0xFF80, 0x00C0, + 0xFF81, 0x00C1, 0xFF82, 0x00C2, 0xFF83, 0x00C3, 0xFF84, 0x00C4, + 0xFF85, 0x00C5, 0xFF86, 0x00C6, 0xFF87, 0x00C7, 0xFF88, 0x00C8, + 0xFF89, 0x00C9, 0xFF8A, 0x00CA, 0xFF8B, 0x00CB, 0xFF8C, 0x00CC, + 0xFF8D, 0x00CD, 0xFF8E, 0x00CE, 0xFF8F, 0x00CF, 0xFF90, 0x00D0, + 0xFF91, 0x00D1, 0xFF92, 0x00D2, 0xFF93, 0x00D3, 0xFF94, 0x00D4, + 0xFF95, 0x00D5, 0xFF96, 0x00D6, 0xFF97, 0x00D7, 0xFF98, 0x00D8, + 0xFF99, 0x00D9, 0xFF9A, 0x00DA, 0xFF9B, 0x00DB, 0xFF9C, 0x00DC, + 0xFF9D, 0x00DD, 0xFF9E, 0x00DE, 0xFF9F, 0x00DF, 0xFFE0, 0x8191, + 0xFFE1, 0x8192, 0xFFE2, 0x81CA, 0xFFE3, 0x8150, 0xFFE4, 0xFA55, + 0xFFE5, 0x818F, 0, 0 +}; + +#if !_TINY_TABLE +static +const WCHAR sjis2uni[] = { +/* SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, SJIS - Unicode, */ + 0x00A1, 0xFF61, 0x00A2, 0xFF62, 0x00A3, 0xFF63, 0x00A4, 0xFF64, + 0x00A5, 0xFF65, 0x00A6, 0xFF66, 0x00A7, 0xFF67, 0x00A8, 0xFF68, + 0x00A9, 0xFF69, 0x00AA, 0xFF6A, 0x00AB, 0xFF6B, 0x00AC, 0xFF6C, + 0x00AD, 0xFF6D, 0x00AE, 0xFF6E, 0x00AF, 0xFF6F, 0x00B0, 0xFF70, + 0x00B1, 0xFF71, 0x00B2, 0xFF72, 0x00B3, 0xFF73, 0x00B4, 0xFF74, + 0x00B5, 0xFF75, 0x00B6, 0xFF76, 0x00B7, 0xFF77, 0x00B8, 0xFF78, + 0x00B9, 0xFF79, 0x00BA, 0xFF7A, 0x00BB, 0xFF7B, 0x00BC, 0xFF7C, + 0x00BD, 0xFF7D, 0x00BE, 0xFF7E, 0x00BF, 0xFF7F, 0x00C0, 0xFF80, + 0x00C1, 0xFF81, 0x00C2, 0xFF82, 0x00C3, 0xFF83, 0x00C4, 0xFF84, + 0x00C5, 0xFF85, 0x00C6, 0xFF86, 0x00C7, 0xFF87, 0x00C8, 0xFF88, + 0x00C9, 0xFF89, 0x00CA, 0xFF8A, 0x00CB, 0xFF8B, 0x00CC, 0xFF8C, + 0x00CD, 0xFF8D, 0x00CE, 0xFF8E, 0x00CF, 0xFF8F, 0x00D0, 0xFF90, + 0x00D1, 0xFF91, 0x00D2, 0xFF92, 0x00D3, 0xFF93, 0x00D4, 0xFF94, + 0x00D5, 0xFF95, 0x00D6, 0xFF96, 0x00D7, 0xFF97, 0x00D8, 0xFF98, + 0x00D9, 0xFF99, 0x00DA, 0xFF9A, 0x00DB, 0xFF9B, 0x00DC, 0xFF9C, + 0x00DD, 0xFF9D, 0x00DE, 0xFF9E, 0x00DF, 0xFF9F, 0x8140, 0x3000, + 0x8141, 0x3001, 0x8142, 0x3002, 0x8143, 0xFF0C, 0x8144, 0xFF0E, + 0x8145, 0x30FB, 0x8146, 0xFF1A, 0x8147, 0xFF1B, 0x8148, 0xFF1F, + 0x8149, 0xFF01, 0x814A, 0x309B, 0x814B, 0x309C, 0x814C, 0x00B4, + 0x814D, 0xFF40, 0x814E, 0x00A8, 0x814F, 0xFF3E, 0x8150, 0xFFE3, + 0x8151, 0xFF3F, 0x8152, 0x30FD, 0x8153, 0x30FE, 0x8154, 0x309D, + 0x8155, 0x309E, 0x8156, 0x3003, 0x8157, 0x4EDD, 0x8158, 0x3005, + 0x8159, 0x3006, 0x815A, 0x3007, 0x815B, 0x30FC, 0x815C, 0x2015, + 0x815D, 0x2010, 0x815E, 0xFF0F, 0x815F, 0xFF3C, 0x8160, 0xFF5E, + 0x8161, 0x2225, 0x8162, 0xFF5C, 0x8163, 0x2026, 0x8164, 0x2025, + 0x8165, 0x2018, 0x8166, 0x2019, 0x8167, 0x201C, 0x8168, 0x201D, + 0x8169, 0xFF08, 0x816A, 0xFF09, 0x816B, 0x3014, 0x816C, 0x3015, + 0x816D, 0xFF3B, 0x816E, 0xFF3D, 0x816F, 0xFF5B, 0x8170, 0xFF5D, + 0x8171, 0x3008, 0x8172, 0x3009, 0x8173, 0x300A, 0x8174, 0x300B, + 0x8175, 0x300C, 0x8176, 0x300D, 0x8177, 0x300E, 0x8178, 0x300F, + 0x8179, 0x3010, 0x817A, 0x3011, 0x817B, 0xFF0B, 0x817C, 0xFF0D, + 0x817D, 0x00B1, 0x817E, 0x00D7, 0x8180, 0x00F7, 0x8181, 0xFF1D, + 0x8182, 0x2260, 0x8183, 0xFF1C, 0x8184, 0xFF1E, 0x8185, 0x2266, + 0x8186, 0x2267, 0x8187, 0x221E, 0x8188, 0x2234, 0x8189, 0x2642, + 0x818A, 0x2640, 0x818B, 0x00B0, 0x818C, 0x2032, 0x818D, 0x2033, + 0x818E, 0x2103, 0x818F, 0xFFE5, 0x8190, 0xFF04, 0x8191, 0xFFE0, + 0x8192, 0xFFE1, 0x8193, 0xFF05, 0x8194, 0xFF03, 0x8195, 0xFF06, + 0x8196, 0xFF0A, 0x8197, 0xFF20, 0x8198, 0x00A7, 0x8199, 0x2606, + 0x819A, 0x2605, 0x819B, 0x25CB, 0x819C, 0x25CF, 0x819D, 0x25CE, + 0x819E, 0x25C7, 0x819F, 0x25C6, 0x81A0, 0x25A1, 0x81A1, 0x25A0, + 0x81A2, 0x25B3, 0x81A3, 0x25B2, 0x81A4, 0x25BD, 0x81A5, 0x25BC, + 0x81A6, 0x203B, 0x81A7, 0x3012, 0x81A8, 0x2192, 0x81A9, 0x2190, + 0x81AA, 0x2191, 0x81AB, 0x2193, 0x81AC, 0x3013, 0x81B8, 0x2208, + 0x81B9, 0x220B, 0x81BA, 0x2286, 0x81BB, 0x2287, 0x81BC, 0x2282, + 0x81BD, 0x2283, 0x81BE, 0x222A, 0x81BF, 0x2229, 0x81C8, 0x2227, + 0x81C9, 0x2228, 0x81CA, 0xFFE2, 0x81CB, 0x21D2, 0x81CC, 0x21D4, + 0x81CD, 0x2200, 0x81CE, 0x2203, 0x81DA, 0x2220, 0x81DB, 0x22A5, + 0x81DC, 0x2312, 0x81DD, 0x2202, 0x81DE, 0x2207, 0x81DF, 0x2261, + 0x81E0, 0x2252, 0x81E1, 0x226A, 0x81E2, 0x226B, 0x81E3, 0x221A, + 0x81E4, 0x223D, 0x81E5, 0x221D, 0x81E6, 0x2235, 0x81E7, 0x222B, + 0x81E8, 0x222C, 0x81F0, 0x212B, 0x81F1, 0x2030, 0x81F2, 0x266F, + 0x81F3, 0x266D, 0x81F4, 0x266A, 0x81F5, 0x2020, 0x81F6, 0x2021, + 0x81F7, 0x00B6, 0x81FC, 0x25EF, 0x824F, 0xFF10, 0x8250, 0xFF11, + 0x8251, 0xFF12, 0x8252, 0xFF13, 0x8253, 0xFF14, 0x8254, 0xFF15, + 0x8255, 0xFF16, 0x8256, 0xFF17, 0x8257, 0xFF18, 0x8258, 0xFF19, + 0x8260, 0xFF21, 0x8261, 0xFF22, 0x8262, 0xFF23, 0x8263, 0xFF24, + 0x8264, 0xFF25, 0x8265, 0xFF26, 0x8266, 0xFF27, 0x8267, 0xFF28, + 0x8268, 0xFF29, 0x8269, 0xFF2A, 0x826A, 0xFF2B, 0x826B, 0xFF2C, + 0x826C, 0xFF2D, 0x826D, 0xFF2E, 0x826E, 0xFF2F, 0x826F, 0xFF30, + 0x8270, 0xFF31, 0x8271, 0xFF32, 0x8272, 0xFF33, 0x8273, 0xFF34, + 0x8274, 0xFF35, 0x8275, 0xFF36, 0x8276, 0xFF37, 0x8277, 0xFF38, + 0x8278, 0xFF39, 0x8279, 0xFF3A, 0x8281, 0xFF41, 0x8282, 0xFF42, + 0x8283, 0xFF43, 0x8284, 0xFF44, 0x8285, 0xFF45, 0x8286, 0xFF46, + 0x8287, 0xFF47, 0x8288, 0xFF48, 0x8289, 0xFF49, 0x828A, 0xFF4A, + 0x828B, 0xFF4B, 0x828C, 0xFF4C, 0x828D, 0xFF4D, 0x828E, 0xFF4E, + 0x828F, 0xFF4F, 0x8290, 0xFF50, 0x8291, 0xFF51, 0x8292, 0xFF52, + 0x8293, 0xFF53, 0x8294, 0xFF54, 0x8295, 0xFF55, 0x8296, 0xFF56, + 0x8297, 0xFF57, 0x8298, 0xFF58, 0x8299, 0xFF59, 0x829A, 0xFF5A, + 0x829F, 0x3041, 0x82A0, 0x3042, 0x82A1, 0x3043, 0x82A2, 0x3044, + 0x82A3, 0x3045, 0x82A4, 0x3046, 0x82A5, 0x3047, 0x82A6, 0x3048, + 0x82A7, 0x3049, 0x82A8, 0x304A, 0x82A9, 0x304B, 0x82AA, 0x304C, + 0x82AB, 0x304D, 0x82AC, 0x304E, 0x82AD, 0x304F, 0x82AE, 0x3050, + 0x82AF, 0x3051, 0x82B0, 0x3052, 0x82B1, 0x3053, 0x82B2, 0x3054, + 0x82B3, 0x3055, 0x82B4, 0x3056, 0x82B5, 0x3057, 0x82B6, 0x3058, + 0x82B7, 0x3059, 0x82B8, 0x305A, 0x82B9, 0x305B, 0x82BA, 0x305C, + 0x82BB, 0x305D, 0x82BC, 0x305E, 0x82BD, 0x305F, 0x82BE, 0x3060, + 0x82BF, 0x3061, 0x82C0, 0x3062, 0x82C1, 0x3063, 0x82C2, 0x3064, + 0x82C3, 0x3065, 0x82C4, 0x3066, 0x82C5, 0x3067, 0x82C6, 0x3068, + 0x82C7, 0x3069, 0x82C8, 0x306A, 0x82C9, 0x306B, 0x82CA, 0x306C, + 0x82CB, 0x306D, 0x82CC, 0x306E, 0x82CD, 0x306F, 0x82CE, 0x3070, + 0x82CF, 0x3071, 0x82D0, 0x3072, 0x82D1, 0x3073, 0x82D2, 0x3074, + 0x82D3, 0x3075, 0x82D4, 0x3076, 0x82D5, 0x3077, 0x82D6, 0x3078, + 0x82D7, 0x3079, 0x82D8, 0x307A, 0x82D9, 0x307B, 0x82DA, 0x307C, + 0x82DB, 0x307D, 0x82DC, 0x307E, 0x82DD, 0x307F, 0x82DE, 0x3080, + 0x82DF, 0x3081, 0x82E0, 0x3082, 0x82E1, 0x3083, 0x82E2, 0x3084, + 0x82E3, 0x3085, 0x82E4, 0x3086, 0x82E5, 0x3087, 0x82E6, 0x3088, + 0x82E7, 0x3089, 0x82E8, 0x308A, 0x82E9, 0x308B, 0x82EA, 0x308C, + 0x82EB, 0x308D, 0x82EC, 0x308E, 0x82ED, 0x308F, 0x82EE, 0x3090, + 0x82EF, 0x3091, 0x82F0, 0x3092, 0x82F1, 0x3093, 0x8340, 0x30A1, + 0x8341, 0x30A2, 0x8342, 0x30A3, 0x8343, 0x30A4, 0x8344, 0x30A5, + 0x8345, 0x30A6, 0x8346, 0x30A7, 0x8347, 0x30A8, 0x8348, 0x30A9, + 0x8349, 0x30AA, 0x834A, 0x30AB, 0x834B, 0x30AC, 0x834C, 0x30AD, + 0x834D, 0x30AE, 0x834E, 0x30AF, 0x834F, 0x30B0, 0x8350, 0x30B1, + 0x8351, 0x30B2, 0x8352, 0x30B3, 0x8353, 0x30B4, 0x8354, 0x30B5, + 0x8355, 0x30B6, 0x8356, 0x30B7, 0x8357, 0x30B8, 0x8358, 0x30B9, + 0x8359, 0x30BA, 0x835A, 0x30BB, 0x835B, 0x30BC, 0x835C, 0x30BD, + 0x835D, 0x30BE, 0x835E, 0x30BF, 0x835F, 0x30C0, 0x8360, 0x30C1, + 0x8361, 0x30C2, 0x8362, 0x30C3, 0x8363, 0x30C4, 0x8364, 0x30C5, + 0x8365, 0x30C6, 0x8366, 0x30C7, 0x8367, 0x30C8, 0x8368, 0x30C9, + 0x8369, 0x30CA, 0x836A, 0x30CB, 0x836B, 0x30CC, 0x836C, 0x30CD, + 0x836D, 0x30CE, 0x836E, 0x30CF, 0x836F, 0x30D0, 0x8370, 0x30D1, + 0x8371, 0x30D2, 0x8372, 0x30D3, 0x8373, 0x30D4, 0x8374, 0x30D5, + 0x8375, 0x30D6, 0x8376, 0x30D7, 0x8377, 0x30D8, 0x8378, 0x30D9, + 0x8379, 0x30DA, 0x837A, 0x30DB, 0x837B, 0x30DC, 0x837C, 0x30DD, + 0x837D, 0x30DE, 0x837E, 0x30DF, 0x8380, 0x30E0, 0x8381, 0x30E1, + 0x8382, 0x30E2, 0x8383, 0x30E3, 0x8384, 0x30E4, 0x8385, 0x30E5, + 0x8386, 0x30E6, 0x8387, 0x30E7, 0x8388, 0x30E8, 0x8389, 0x30E9, + 0x838A, 0x30EA, 0x838B, 0x30EB, 0x838C, 0x30EC, 0x838D, 0x30ED, + 0x838E, 0x30EE, 0x838F, 0x30EF, 0x8390, 0x30F0, 0x8391, 0x30F1, + 0x8392, 0x30F2, 0x8393, 0x30F3, 0x8394, 0x30F4, 0x8395, 0x30F5, + 0x8396, 0x30F6, 0x839F, 0x0391, 0x83A0, 0x0392, 0x83A1, 0x0393, + 0x83A2, 0x0394, 0x83A3, 0x0395, 0x83A4, 0x0396, 0x83A5, 0x0397, + 0x83A6, 0x0398, 0x83A7, 0x0399, 0x83A8, 0x039A, 0x83A9, 0x039B, + 0x83AA, 0x039C, 0x83AB, 0x039D, 0x83AC, 0x039E, 0x83AD, 0x039F, + 0x83AE, 0x03A0, 0x83AF, 0x03A1, 0x83B0, 0x03A3, 0x83B1, 0x03A4, + 0x83B2, 0x03A5, 0x83B3, 0x03A6, 0x83B4, 0x03A7, 0x83B5, 0x03A8, + 0x83B6, 0x03A9, 0x83BF, 0x03B1, 0x83C0, 0x03B2, 0x83C1, 0x03B3, + 0x83C2, 0x03B4, 0x83C3, 0x03B5, 0x83C4, 0x03B6, 0x83C5, 0x03B7, + 0x83C6, 0x03B8, 0x83C7, 0x03B9, 0x83C8, 0x03BA, 0x83C9, 0x03BB, + 0x83CA, 0x03BC, 0x83CB, 0x03BD, 0x83CC, 0x03BE, 0x83CD, 0x03BF, + 0x83CE, 0x03C0, 0x83CF, 0x03C1, 0x83D0, 0x03C3, 0x83D1, 0x03C4, + 0x83D2, 0x03C5, 0x83D3, 0x03C6, 0x83D4, 0x03C7, 0x83D5, 0x03C8, + 0x83D6, 0x03C9, 0x8440, 0x0410, 0x8441, 0x0411, 0x8442, 0x0412, + 0x8443, 0x0413, 0x8444, 0x0414, 0x8445, 0x0415, 0x8446, 0x0401, + 0x8447, 0x0416, 0x8448, 0x0417, 0x8449, 0x0418, 0x844A, 0x0419, + 0x844B, 0x041A, 0x844C, 0x041B, 0x844D, 0x041C, 0x844E, 0x041D, + 0x844F, 0x041E, 0x8450, 0x041F, 0x8451, 0x0420, 0x8452, 0x0421, + 0x8453, 0x0422, 0x8454, 0x0423, 0x8455, 0x0424, 0x8456, 0x0425, + 0x8457, 0x0426, 0x8458, 0x0427, 0x8459, 0x0428, 0x845A, 0x0429, + 0x845B, 0x042A, 0x845C, 0x042B, 0x845D, 0x042C, 0x845E, 0x042D, + 0x845F, 0x042E, 0x8460, 0x042F, 0x8470, 0x0430, 0x8471, 0x0431, + 0x8472, 0x0432, 0x8473, 0x0433, 0x8474, 0x0434, 0x8475, 0x0435, + 0x8476, 0x0451, 0x8477, 0x0436, 0x8478, 0x0437, 0x8479, 0x0438, + 0x847A, 0x0439, 0x847B, 0x043A, 0x847C, 0x043B, 0x847D, 0x043C, + 0x847E, 0x043D, 0x8480, 0x043E, 0x8481, 0x043F, 0x8482, 0x0440, + 0x8483, 0x0441, 0x8484, 0x0442, 0x8485, 0x0443, 0x8486, 0x0444, + 0x8487, 0x0445, 0x8488, 0x0446, 0x8489, 0x0447, 0x848A, 0x0448, + 0x848B, 0x0449, 0x848C, 0x044A, 0x848D, 0x044B, 0x848E, 0x044C, + 0x848F, 0x044D, 0x8490, 0x044E, 0x8491, 0x044F, 0x849F, 0x2500, + 0x84A0, 0x2502, 0x84A1, 0x250C, 0x84A2, 0x2510, 0x84A3, 0x2518, + 0x84A4, 0x2514, 0x84A5, 0x251C, 0x84A6, 0x252C, 0x84A7, 0x2524, + 0x84A8, 0x2534, 0x84A9, 0x253C, 0x84AA, 0x2501, 0x84AB, 0x2503, + 0x84AC, 0x250F, 0x84AD, 0x2513, 0x84AE, 0x251B, 0x84AF, 0x2517, + 0x84B0, 0x2523, 0x84B1, 0x2533, 0x84B2, 0x252B, 0x84B3, 0x253B, + 0x84B4, 0x254B, 0x84B5, 0x2520, 0x84B6, 0x252F, 0x84B7, 0x2528, + 0x84B8, 0x2537, 0x84B9, 0x253F, 0x84BA, 0x251D, 0x84BB, 0x2530, + 0x84BC, 0x2525, 0x84BD, 0x2538, 0x84BE, 0x2542, 0x8740, 0x2460, + 0x8741, 0x2461, 0x8742, 0x2462, 0x8743, 0x2463, 0x8744, 0x2464, + 0x8745, 0x2465, 0x8746, 0x2466, 0x8747, 0x2467, 0x8748, 0x2468, + 0x8749, 0x2469, 0x874A, 0x246A, 0x874B, 0x246B, 0x874C, 0x246C, + 0x874D, 0x246D, 0x874E, 0x246E, 0x874F, 0x246F, 0x8750, 0x2470, + 0x8751, 0x2471, 0x8752, 0x2472, 0x8753, 0x2473, 0x8754, 0x2160, + 0x8755, 0x2161, 0x8756, 0x2162, 0x8757, 0x2163, 0x8758, 0x2164, + 0x8759, 0x2165, 0x875A, 0x2166, 0x875B, 0x2167, 0x875C, 0x2168, + 0x875D, 0x2169, 0x875F, 0x3349, 0x8760, 0x3314, 0x8761, 0x3322, + 0x8762, 0x334D, 0x8763, 0x3318, 0x8764, 0x3327, 0x8765, 0x3303, + 0x8766, 0x3336, 0x8767, 0x3351, 0x8768, 0x3357, 0x8769, 0x330D, + 0x876A, 0x3326, 0x876B, 0x3323, 0x876C, 0x332B, 0x876D, 0x334A, + 0x876E, 0x333B, 0x876F, 0x339C, 0x8770, 0x339D, 0x8771, 0x339E, + 0x8772, 0x338E, 0x8773, 0x338F, 0x8774, 0x33C4, 0x8775, 0x33A1, + 0x877E, 0x337B, 0x8780, 0x301D, 0x8781, 0x301F, 0x8782, 0x2116, + 0x8783, 0x33CD, 0x8784, 0x2121, 0x8785, 0x32A4, 0x8786, 0x32A5, + 0x8787, 0x32A6, 0x8788, 0x32A7, 0x8789, 0x32A8, 0x878A, 0x3231, + 0x878B, 0x3232, 0x878C, 0x3239, 0x878D, 0x337E, 0x878E, 0x337D, + 0x878F, 0x337C, 0x8793, 0x222E, 0x8794, 0x2211, 0x8798, 0x221F, + 0x8799, 0x22BF, 0x889F, 0x4E9C, 0x88A0, 0x5516, 0x88A1, 0x5A03, + 0x88A2, 0x963F, 0x88A3, 0x54C0, 0x88A4, 0x611B, 0x88A5, 0x6328, + 0x88A6, 0x59F6, 0x88A7, 0x9022, 0x88A8, 0x8475, 0x88A9, 0x831C, + 0x88AA, 0x7A50, 0x88AB, 0x60AA, 0x88AC, 0x63E1, 0x88AD, 0x6E25, + 0x88AE, 0x65ED, 0x88AF, 0x8466, 0x88B0, 0x82A6, 0x88B1, 0x9BF5, + 0x88B2, 0x6893, 0x88B3, 0x5727, 0x88B4, 0x65A1, 0x88B5, 0x6271, + 0x88B6, 0x5B9B, 0x88B7, 0x59D0, 0x88B8, 0x867B, 0x88B9, 0x98F4, + 0x88BA, 0x7D62, 0x88BB, 0x7DBE, 0x88BC, 0x9B8E, 0x88BD, 0x6216, + 0x88BE, 0x7C9F, 0x88BF, 0x88B7, 0x88C0, 0x5B89, 0x88C1, 0x5EB5, + 0x88C2, 0x6309, 0x88C3, 0x6697, 0x88C4, 0x6848, 0x88C5, 0x95C7, + 0x88C6, 0x978D, 0x88C7, 0x674F, 0x88C8, 0x4EE5, 0x88C9, 0x4F0A, + 0x88CA, 0x4F4D, 0x88CB, 0x4F9D, 0x88CC, 0x5049, 0x88CD, 0x56F2, + 0x88CE, 0x5937, 0x88CF, 0x59D4, 0x88D0, 0x5A01, 0x88D1, 0x5C09, + 0x88D2, 0x60DF, 0x88D3, 0x610F, 0x88D4, 0x6170, 0x88D5, 0x6613, + 0x88D6, 0x6905, 0x88D7, 0x70BA, 0x88D8, 0x754F, 0x88D9, 0x7570, + 0x88DA, 0x79FB, 0x88DB, 0x7DAD, 0x88DC, 0x7DEF, 0x88DD, 0x80C3, + 0x88DE, 0x840E, 0x88DF, 0x8863, 0x88E0, 0x8B02, 0x88E1, 0x9055, + 0x88E2, 0x907A, 0x88E3, 0x533B, 0x88E4, 0x4E95, 0x88E5, 0x4EA5, + 0x88E6, 0x57DF, 0x88E7, 0x80B2, 0x88E8, 0x90C1, 0x88E9, 0x78EF, + 0x88EA, 0x4E00, 0x88EB, 0x58F1, 0x88EC, 0x6EA2, 0x88ED, 0x9038, + 0x88EE, 0x7A32, 0x88EF, 0x8328, 0x88F0, 0x828B, 0x88F1, 0x9C2F, + 0x88F2, 0x5141, 0x88F3, 0x5370, 0x88F4, 0x54BD, 0x88F5, 0x54E1, + 0x88F6, 0x56E0, 0x88F7, 0x59FB, 0x88F8, 0x5F15, 0x88F9, 0x98F2, + 0x88FA, 0x6DEB, 0x88FB, 0x80E4, 0x88FC, 0x852D, 0x8940, 0x9662, + 0x8941, 0x9670, 0x8942, 0x96A0, 0x8943, 0x97FB, 0x8944, 0x540B, + 0x8945, 0x53F3, 0x8946, 0x5B87, 0x8947, 0x70CF, 0x8948, 0x7FBD, + 0x8949, 0x8FC2, 0x894A, 0x96E8, 0x894B, 0x536F, 0x894C, 0x9D5C, + 0x894D, 0x7ABA, 0x894E, 0x4E11, 0x894F, 0x7893, 0x8950, 0x81FC, + 0x8951, 0x6E26, 0x8952, 0x5618, 0x8953, 0x5504, 0x8954, 0x6B1D, + 0x8955, 0x851A, 0x8956, 0x9C3B, 0x8957, 0x59E5, 0x8958, 0x53A9, + 0x8959, 0x6D66, 0x895A, 0x74DC, 0x895B, 0x958F, 0x895C, 0x5642, + 0x895D, 0x4E91, 0x895E, 0x904B, 0x895F, 0x96F2, 0x8960, 0x834F, + 0x8961, 0x990C, 0x8962, 0x53E1, 0x8963, 0x55B6, 0x8964, 0x5B30, + 0x8965, 0x5F71, 0x8966, 0x6620, 0x8967, 0x66F3, 0x8968, 0x6804, + 0x8969, 0x6C38, 0x896A, 0x6CF3, 0x896B, 0x6D29, 0x896C, 0x745B, + 0x896D, 0x76C8, 0x896E, 0x7A4E, 0x896F, 0x9834, 0x8970, 0x82F1, + 0x8971, 0x885B, 0x8972, 0x8A60, 0x8973, 0x92ED, 0x8974, 0x6DB2, + 0x8975, 0x75AB, 0x8976, 0x76CA, 0x8977, 0x99C5, 0x8978, 0x60A6, + 0x8979, 0x8B01, 0x897A, 0x8D8A, 0x897B, 0x95B2, 0x897C, 0x698E, + 0x897D, 0x53AD, 0x897E, 0x5186, 0x8980, 0x5712, 0x8981, 0x5830, + 0x8982, 0x5944, 0x8983, 0x5BB4, 0x8984, 0x5EF6, 0x8985, 0x6028, + 0x8986, 0x63A9, 0x8987, 0x63F4, 0x8988, 0x6CBF, 0x8989, 0x6F14, + 0x898A, 0x708E, 0x898B, 0x7114, 0x898C, 0x7159, 0x898D, 0x71D5, + 0x898E, 0x733F, 0x898F, 0x7E01, 0x8990, 0x8276, 0x8991, 0x82D1, + 0x8992, 0x8597, 0x8993, 0x9060, 0x8994, 0x925B, 0x8995, 0x9D1B, + 0x8996, 0x5869, 0x8997, 0x65BC, 0x8998, 0x6C5A, 0x8999, 0x7525, + 0x899A, 0x51F9, 0x899B, 0x592E, 0x899C, 0x5965, 0x899D, 0x5F80, + 0x899E, 0x5FDC, 0x899F, 0x62BC, 0x89A0, 0x65FA, 0x89A1, 0x6A2A, + 0x89A2, 0x6B27, 0x89A3, 0x6BB4, 0x89A4, 0x738B, 0x89A5, 0x7FC1, + 0x89A6, 0x8956, 0x89A7, 0x9D2C, 0x89A8, 0x9D0E, 0x89A9, 0x9EC4, + 0x89AA, 0x5CA1, 0x89AB, 0x6C96, 0x89AC, 0x837B, 0x89AD, 0x5104, + 0x89AE, 0x5C4B, 0x89AF, 0x61B6, 0x89B0, 0x81C6, 0x89B1, 0x6876, + 0x89B2, 0x7261, 0x89B3, 0x4E59, 0x89B4, 0x4FFA, 0x89B5, 0x5378, + 0x89B6, 0x6069, 0x89B7, 0x6E29, 0x89B8, 0x7A4F, 0x89B9, 0x97F3, + 0x89BA, 0x4E0B, 0x89BB, 0x5316, 0x89BC, 0x4EEE, 0x89BD, 0x4F55, + 0x89BE, 0x4F3D, 0x89BF, 0x4FA1, 0x89C0, 0x4F73, 0x89C1, 0x52A0, + 0x89C2, 0x53EF, 0x89C3, 0x5609, 0x89C4, 0x590F, 0x89C5, 0x5AC1, + 0x89C6, 0x5BB6, 0x89C7, 0x5BE1, 0x89C8, 0x79D1, 0x89C9, 0x6687, + 0x89CA, 0x679C, 0x89CB, 0x67B6, 0x89CC, 0x6B4C, 0x89CD, 0x6CB3, + 0x89CE, 0x706B, 0x89CF, 0x73C2, 0x89D0, 0x798D, 0x89D1, 0x79BE, + 0x89D2, 0x7A3C, 0x89D3, 0x7B87, 0x89D4, 0x82B1, 0x89D5, 0x82DB, + 0x89D6, 0x8304, 0x89D7, 0x8377, 0x89D8, 0x83EF, 0x89D9, 0x83D3, + 0x89DA, 0x8766, 0x89DB, 0x8AB2, 0x89DC, 0x5629, 0x89DD, 0x8CA8, + 0x89DE, 0x8FE6, 0x89DF, 0x904E, 0x89E0, 0x971E, 0x89E1, 0x868A, + 0x89E2, 0x4FC4, 0x89E3, 0x5CE8, 0x89E4, 0x6211, 0x89E5, 0x7259, + 0x89E6, 0x753B, 0x89E7, 0x81E5, 0x89E8, 0x82BD, 0x89E9, 0x86FE, + 0x89EA, 0x8CC0, 0x89EB, 0x96C5, 0x89EC, 0x9913, 0x89ED, 0x99D5, + 0x89EE, 0x4ECB, 0x89EF, 0x4F1A, 0x89F0, 0x89E3, 0x89F1, 0x56DE, + 0x89F2, 0x584A, 0x89F3, 0x58CA, 0x89F4, 0x5EFB, 0x89F5, 0x5FEB, + 0x89F6, 0x602A, 0x89F7, 0x6094, 0x89F8, 0x6062, 0x89F9, 0x61D0, + 0x89FA, 0x6212, 0x89FB, 0x62D0, 0x89FC, 0x6539, 0x8A40, 0x9B41, + 0x8A41, 0x6666, 0x8A42, 0x68B0, 0x8A43, 0x6D77, 0x8A44, 0x7070, + 0x8A45, 0x754C, 0x8A46, 0x7686, 0x8A47, 0x7D75, 0x8A48, 0x82A5, + 0x8A49, 0x87F9, 0x8A4A, 0x958B, 0x8A4B, 0x968E, 0x8A4C, 0x8C9D, + 0x8A4D, 0x51F1, 0x8A4E, 0x52BE, 0x8A4F, 0x5916, 0x8A50, 0x54B3, + 0x8A51, 0x5BB3, 0x8A52, 0x5D16, 0x8A53, 0x6168, 0x8A54, 0x6982, + 0x8A55, 0x6DAF, 0x8A56, 0x788D, 0x8A57, 0x84CB, 0x8A58, 0x8857, + 0x8A59, 0x8A72, 0x8A5A, 0x93A7, 0x8A5B, 0x9AB8, 0x8A5C, 0x6D6C, + 0x8A5D, 0x99A8, 0x8A5E, 0x86D9, 0x8A5F, 0x57A3, 0x8A60, 0x67FF, + 0x8A61, 0x86CE, 0x8A62, 0x920E, 0x8A63, 0x5283, 0x8A64, 0x5687, + 0x8A65, 0x5404, 0x8A66, 0x5ED3, 0x8A67, 0x62E1, 0x8A68, 0x64B9, + 0x8A69, 0x683C, 0x8A6A, 0x6838, 0x8A6B, 0x6BBB, 0x8A6C, 0x7372, + 0x8A6D, 0x78BA, 0x8A6E, 0x7A6B, 0x8A6F, 0x899A, 0x8A70, 0x89D2, + 0x8A71, 0x8D6B, 0x8A72, 0x8F03, 0x8A73, 0x90ED, 0x8A74, 0x95A3, + 0x8A75, 0x9694, 0x8A76, 0x9769, 0x8A77, 0x5B66, 0x8A78, 0x5CB3, + 0x8A79, 0x697D, 0x8A7A, 0x984D, 0x8A7B, 0x984E, 0x8A7C, 0x639B, + 0x8A7D, 0x7B20, 0x8A7E, 0x6A2B, 0x8A80, 0x6A7F, 0x8A81, 0x68B6, + 0x8A82, 0x9C0D, 0x8A83, 0x6F5F, 0x8A84, 0x5272, 0x8A85, 0x559D, + 0x8A86, 0x6070, 0x8A87, 0x62EC, 0x8A88, 0x6D3B, 0x8A89, 0x6E07, + 0x8A8A, 0x6ED1, 0x8A8B, 0x845B, 0x8A8C, 0x8910, 0x8A8D, 0x8F44, + 0x8A8E, 0x4E14, 0x8A8F, 0x9C39, 0x8A90, 0x53F6, 0x8A91, 0x691B, + 0x8A92, 0x6A3A, 0x8A93, 0x9784, 0x8A94, 0x682A, 0x8A95, 0x515C, + 0x8A96, 0x7AC3, 0x8A97, 0x84B2, 0x8A98, 0x91DC, 0x8A99, 0x938C, + 0x8A9A, 0x565B, 0x8A9B, 0x9D28, 0x8A9C, 0x6822, 0x8A9D, 0x8305, + 0x8A9E, 0x8431, 0x8A9F, 0x7CA5, 0x8AA0, 0x5208, 0x8AA1, 0x82C5, + 0x8AA2, 0x74E6, 0x8AA3, 0x4E7E, 0x8AA4, 0x4F83, 0x8AA5, 0x51A0, + 0x8AA6, 0x5BD2, 0x8AA7, 0x520A, 0x8AA8, 0x52D8, 0x8AA9, 0x52E7, + 0x8AAA, 0x5DFB, 0x8AAB, 0x559A, 0x8AAC, 0x582A, 0x8AAD, 0x59E6, + 0x8AAE, 0x5B8C, 0x8AAF, 0x5B98, 0x8AB0, 0x5BDB, 0x8AB1, 0x5E72, + 0x8AB2, 0x5E79, 0x8AB3, 0x60A3, 0x8AB4, 0x611F, 0x8AB5, 0x6163, + 0x8AB6, 0x61BE, 0x8AB7, 0x63DB, 0x8AB8, 0x6562, 0x8AB9, 0x67D1, + 0x8ABA, 0x6853, 0x8ABB, 0x68FA, 0x8ABC, 0x6B3E, 0x8ABD, 0x6B53, + 0x8ABE, 0x6C57, 0x8ABF, 0x6F22, 0x8AC0, 0x6F97, 0x8AC1, 0x6F45, + 0x8AC2, 0x74B0, 0x8AC3, 0x7518, 0x8AC4, 0x76E3, 0x8AC5, 0x770B, + 0x8AC6, 0x7AFF, 0x8AC7, 0x7BA1, 0x8AC8, 0x7C21, 0x8AC9, 0x7DE9, + 0x8ACA, 0x7F36, 0x8ACB, 0x7FF0, 0x8ACC, 0x809D, 0x8ACD, 0x8266, + 0x8ACE, 0x839E, 0x8ACF, 0x89B3, 0x8AD0, 0x8ACC, 0x8AD1, 0x8CAB, + 0x8AD2, 0x9084, 0x8AD3, 0x9451, 0x8AD4, 0x9593, 0x8AD5, 0x9591, + 0x8AD6, 0x95A2, 0x8AD7, 0x9665, 0x8AD8, 0x97D3, 0x8AD9, 0x9928, + 0x8ADA, 0x8218, 0x8ADB, 0x4E38, 0x8ADC, 0x542B, 0x8ADD, 0x5CB8, + 0x8ADE, 0x5DCC, 0x8ADF, 0x73A9, 0x8AE0, 0x764C, 0x8AE1, 0x773C, + 0x8AE2, 0x5CA9, 0x8AE3, 0x7FEB, 0x8AE4, 0x8D0B, 0x8AE5, 0x96C1, + 0x8AE6, 0x9811, 0x8AE7, 0x9854, 0x8AE8, 0x9858, 0x8AE9, 0x4F01, + 0x8AEA, 0x4F0E, 0x8AEB, 0x5371, 0x8AEC, 0x559C, 0x8AED, 0x5668, + 0x8AEE, 0x57FA, 0x8AEF, 0x5947, 0x8AF0, 0x5B09, 0x8AF1, 0x5BC4, + 0x8AF2, 0x5C90, 0x8AF3, 0x5E0C, 0x8AF4, 0x5E7E, 0x8AF5, 0x5FCC, + 0x8AF6, 0x63EE, 0x8AF7, 0x673A, 0x8AF8, 0x65D7, 0x8AF9, 0x65E2, + 0x8AFA, 0x671F, 0x8AFB, 0x68CB, 0x8AFC, 0x68C4, 0x8B40, 0x6A5F, + 0x8B41, 0x5E30, 0x8B42, 0x6BC5, 0x8B43, 0x6C17, 0x8B44, 0x6C7D, + 0x8B45, 0x757F, 0x8B46, 0x7948, 0x8B47, 0x5B63, 0x8B48, 0x7A00, + 0x8B49, 0x7D00, 0x8B4A, 0x5FBD, 0x8B4B, 0x898F, 0x8B4C, 0x8A18, + 0x8B4D, 0x8CB4, 0x8B4E, 0x8D77, 0x8B4F, 0x8ECC, 0x8B50, 0x8F1D, + 0x8B51, 0x98E2, 0x8B52, 0x9A0E, 0x8B53, 0x9B3C, 0x8B54, 0x4E80, + 0x8B55, 0x507D, 0x8B56, 0x5100, 0x8B57, 0x5993, 0x8B58, 0x5B9C, + 0x8B59, 0x622F, 0x8B5A, 0x6280, 0x8B5B, 0x64EC, 0x8B5C, 0x6B3A, + 0x8B5D, 0x72A0, 0x8B5E, 0x7591, 0x8B5F, 0x7947, 0x8B60, 0x7FA9, + 0x8B61, 0x87FB, 0x8B62, 0x8ABC, 0x8B63, 0x8B70, 0x8B64, 0x63AC, + 0x8B65, 0x83CA, 0x8B66, 0x97A0, 0x8B67, 0x5409, 0x8B68, 0x5403, + 0x8B69, 0x55AB, 0x8B6A, 0x6854, 0x8B6B, 0x6A58, 0x8B6C, 0x8A70, + 0x8B6D, 0x7827, 0x8B6E, 0x6775, 0x8B6F, 0x9ECD, 0x8B70, 0x5374, + 0x8B71, 0x5BA2, 0x8B72, 0x811A, 0x8B73, 0x8650, 0x8B74, 0x9006, + 0x8B75, 0x4E18, 0x8B76, 0x4E45, 0x8B77, 0x4EC7, 0x8B78, 0x4F11, + 0x8B79, 0x53CA, 0x8B7A, 0x5438, 0x8B7B, 0x5BAE, 0x8B7C, 0x5F13, + 0x8B7D, 0x6025, 0x8B7E, 0x6551, 0x8B80, 0x673D, 0x8B81, 0x6C42, + 0x8B82, 0x6C72, 0x8B83, 0x6CE3, 0x8B84, 0x7078, 0x8B85, 0x7403, + 0x8B86, 0x7A76, 0x8B87, 0x7AAE, 0x8B88, 0x7B08, 0x8B89, 0x7D1A, + 0x8B8A, 0x7CFE, 0x8B8B, 0x7D66, 0x8B8C, 0x65E7, 0x8B8D, 0x725B, + 0x8B8E, 0x53BB, 0x8B8F, 0x5C45, 0x8B90, 0x5DE8, 0x8B91, 0x62D2, + 0x8B92, 0x62E0, 0x8B93, 0x6319, 0x8B94, 0x6E20, 0x8B95, 0x865A, + 0x8B96, 0x8A31, 0x8B97, 0x8DDD, 0x8B98, 0x92F8, 0x8B99, 0x6F01, + 0x8B9A, 0x79A6, 0x8B9B, 0x9B5A, 0x8B9C, 0x4EA8, 0x8B9D, 0x4EAB, + 0x8B9E, 0x4EAC, 0x8B9F, 0x4F9B, 0x8BA0, 0x4FA0, 0x8BA1, 0x50D1, + 0x8BA2, 0x5147, 0x8BA3, 0x7AF6, 0x8BA4, 0x5171, 0x8BA5, 0x51F6, + 0x8BA6, 0x5354, 0x8BA7, 0x5321, 0x8BA8, 0x537F, 0x8BA9, 0x53EB, + 0x8BAA, 0x55AC, 0x8BAB, 0x5883, 0x8BAC, 0x5CE1, 0x8BAD, 0x5F37, + 0x8BAE, 0x5F4A, 0x8BAF, 0x602F, 0x8BB0, 0x6050, 0x8BB1, 0x606D, + 0x8BB2, 0x631F, 0x8BB3, 0x6559, 0x8BB4, 0x6A4B, 0x8BB5, 0x6CC1, + 0x8BB6, 0x72C2, 0x8BB7, 0x72ED, 0x8BB8, 0x77EF, 0x8BB9, 0x80F8, + 0x8BBA, 0x8105, 0x8BBB, 0x8208, 0x8BBC, 0x854E, 0x8BBD, 0x90F7, + 0x8BBE, 0x93E1, 0x8BBF, 0x97FF, 0x8BC0, 0x9957, 0x8BC1, 0x9A5A, + 0x8BC2, 0x4EF0, 0x8BC3, 0x51DD, 0x8BC4, 0x5C2D, 0x8BC5, 0x6681, + 0x8BC6, 0x696D, 0x8BC7, 0x5C40, 0x8BC8, 0x66F2, 0x8BC9, 0x6975, + 0x8BCA, 0x7389, 0x8BCB, 0x6850, 0x8BCC, 0x7C81, 0x8BCD, 0x50C5, + 0x8BCE, 0x52E4, 0x8BCF, 0x5747, 0x8BD0, 0x5DFE, 0x8BD1, 0x9326, + 0x8BD2, 0x65A4, 0x8BD3, 0x6B23, 0x8BD4, 0x6B3D, 0x8BD5, 0x7434, + 0x8BD6, 0x7981, 0x8BD7, 0x79BD, 0x8BD8, 0x7B4B, 0x8BD9, 0x7DCA, + 0x8BDA, 0x82B9, 0x8BDB, 0x83CC, 0x8BDC, 0x887F, 0x8BDD, 0x895F, + 0x8BDE, 0x8B39, 0x8BDF, 0x8FD1, 0x8BE0, 0x91D1, 0x8BE1, 0x541F, + 0x8BE2, 0x9280, 0x8BE3, 0x4E5D, 0x8BE4, 0x5036, 0x8BE5, 0x53E5, + 0x8BE6, 0x533A, 0x8BE7, 0x72D7, 0x8BE8, 0x7396, 0x8BE9, 0x77E9, + 0x8BEA, 0x82E6, 0x8BEB, 0x8EAF, 0x8BEC, 0x99C6, 0x8BED, 0x99C8, + 0x8BEE, 0x99D2, 0x8BEF, 0x5177, 0x8BF0, 0x611A, 0x8BF1, 0x865E, + 0x8BF2, 0x55B0, 0x8BF3, 0x7A7A, 0x8BF4, 0x5076, 0x8BF5, 0x5BD3, + 0x8BF6, 0x9047, 0x8BF7, 0x9685, 0x8BF8, 0x4E32, 0x8BF9, 0x6ADB, + 0x8BFA, 0x91E7, 0x8BFB, 0x5C51, 0x8BFC, 0x5C48, 0x8C40, 0x6398, + 0x8C41, 0x7A9F, 0x8C42, 0x6C93, 0x8C43, 0x9774, 0x8C44, 0x8F61, + 0x8C45, 0x7AAA, 0x8C46, 0x718A, 0x8C47, 0x9688, 0x8C48, 0x7C82, + 0x8C49, 0x6817, 0x8C4A, 0x7E70, 0x8C4B, 0x6851, 0x8C4C, 0x936C, + 0x8C4D, 0x52F2, 0x8C4E, 0x541B, 0x8C4F, 0x85AB, 0x8C50, 0x8A13, + 0x8C51, 0x7FA4, 0x8C52, 0x8ECD, 0x8C53, 0x90E1, 0x8C54, 0x5366, + 0x8C55, 0x8888, 0x8C56, 0x7941, 0x8C57, 0x4FC2, 0x8C58, 0x50BE, + 0x8C59, 0x5211, 0x8C5A, 0x5144, 0x8C5B, 0x5553, 0x8C5C, 0x572D, + 0x8C5D, 0x73EA, 0x8C5E, 0x578B, 0x8C5F, 0x5951, 0x8C60, 0x5F62, + 0x8C61, 0x5F84, 0x8C62, 0x6075, 0x8C63, 0x6176, 0x8C64, 0x6167, + 0x8C65, 0x61A9, 0x8C66, 0x63B2, 0x8C67, 0x643A, 0x8C68, 0x656C, + 0x8C69, 0x666F, 0x8C6A, 0x6842, 0x8C6B, 0x6E13, 0x8C6C, 0x7566, + 0x8C6D, 0x7A3D, 0x8C6E, 0x7CFB, 0x8C6F, 0x7D4C, 0x8C70, 0x7D99, + 0x8C71, 0x7E4B, 0x8C72, 0x7F6B, 0x8C73, 0x830E, 0x8C74, 0x834A, + 0x8C75, 0x86CD, 0x8C76, 0x8A08, 0x8C77, 0x8A63, 0x8C78, 0x8B66, + 0x8C79, 0x8EFD, 0x8C7A, 0x981A, 0x8C7B, 0x9D8F, 0x8C7C, 0x82B8, + 0x8C7D, 0x8FCE, 0x8C7E, 0x9BE8, 0x8C80, 0x5287, 0x8C81, 0x621F, + 0x8C82, 0x6483, 0x8C83, 0x6FC0, 0x8C84, 0x9699, 0x8C85, 0x6841, + 0x8C86, 0x5091, 0x8C87, 0x6B20, 0x8C88, 0x6C7A, 0x8C89, 0x6F54, + 0x8C8A, 0x7A74, 0x8C8B, 0x7D50, 0x8C8C, 0x8840, 0x8C8D, 0x8A23, + 0x8C8E, 0x6708, 0x8C8F, 0x4EF6, 0x8C90, 0x5039, 0x8C91, 0x5026, + 0x8C92, 0x5065, 0x8C93, 0x517C, 0x8C94, 0x5238, 0x8C95, 0x5263, + 0x8C96, 0x55A7, 0x8C97, 0x570F, 0x8C98, 0x5805, 0x8C99, 0x5ACC, + 0x8C9A, 0x5EFA, 0x8C9B, 0x61B2, 0x8C9C, 0x61F8, 0x8C9D, 0x62F3, + 0x8C9E, 0x6372, 0x8C9F, 0x691C, 0x8CA0, 0x6A29, 0x8CA1, 0x727D, + 0x8CA2, 0x72AC, 0x8CA3, 0x732E, 0x8CA4, 0x7814, 0x8CA5, 0x786F, + 0x8CA6, 0x7D79, 0x8CA7, 0x770C, 0x8CA8, 0x80A9, 0x8CA9, 0x898B, + 0x8CAA, 0x8B19, 0x8CAB, 0x8CE2, 0x8CAC, 0x8ED2, 0x8CAD, 0x9063, + 0x8CAE, 0x9375, 0x8CAF, 0x967A, 0x8CB0, 0x9855, 0x8CB1, 0x9A13, + 0x8CB2, 0x9E78, 0x8CB3, 0x5143, 0x8CB4, 0x539F, 0x8CB5, 0x53B3, + 0x8CB6, 0x5E7B, 0x8CB7, 0x5F26, 0x8CB8, 0x6E1B, 0x8CB9, 0x6E90, + 0x8CBA, 0x7384, 0x8CBB, 0x73FE, 0x8CBC, 0x7D43, 0x8CBD, 0x8237, + 0x8CBE, 0x8A00, 0x8CBF, 0x8AFA, 0x8CC0, 0x9650, 0x8CC1, 0x4E4E, + 0x8CC2, 0x500B, 0x8CC3, 0x53E4, 0x8CC4, 0x547C, 0x8CC5, 0x56FA, + 0x8CC6, 0x59D1, 0x8CC7, 0x5B64, 0x8CC8, 0x5DF1, 0x8CC9, 0x5EAB, + 0x8CCA, 0x5F27, 0x8CCB, 0x6238, 0x8CCC, 0x6545, 0x8CCD, 0x67AF, + 0x8CCE, 0x6E56, 0x8CCF, 0x72D0, 0x8CD0, 0x7CCA, 0x8CD1, 0x88B4, + 0x8CD2, 0x80A1, 0x8CD3, 0x80E1, 0x8CD4, 0x83F0, 0x8CD5, 0x864E, + 0x8CD6, 0x8A87, 0x8CD7, 0x8DE8, 0x8CD8, 0x9237, 0x8CD9, 0x96C7, + 0x8CDA, 0x9867, 0x8CDB, 0x9F13, 0x8CDC, 0x4E94, 0x8CDD, 0x4E92, + 0x8CDE, 0x4F0D, 0x8CDF, 0x5348, 0x8CE0, 0x5449, 0x8CE1, 0x543E, + 0x8CE2, 0x5A2F, 0x8CE3, 0x5F8C, 0x8CE4, 0x5FA1, 0x8CE5, 0x609F, + 0x8CE6, 0x68A7, 0x8CE7, 0x6A8E, 0x8CE8, 0x745A, 0x8CE9, 0x7881, + 0x8CEA, 0x8A9E, 0x8CEB, 0x8AA4, 0x8CEC, 0x8B77, 0x8CED, 0x9190, + 0x8CEE, 0x4E5E, 0x8CEF, 0x9BC9, 0x8CF0, 0x4EA4, 0x8CF1, 0x4F7C, + 0x8CF2, 0x4FAF, 0x8CF3, 0x5019, 0x8CF4, 0x5016, 0x8CF5, 0x5149, + 0x8CF6, 0x516C, 0x8CF7, 0x529F, 0x8CF8, 0x52B9, 0x8CF9, 0x52FE, + 0x8CFA, 0x539A, 0x8CFB, 0x53E3, 0x8CFC, 0x5411, 0x8D40, 0x540E, + 0x8D41, 0x5589, 0x8D42, 0x5751, 0x8D43, 0x57A2, 0x8D44, 0x597D, + 0x8D45, 0x5B54, 0x8D46, 0x5B5D, 0x8D47, 0x5B8F, 0x8D48, 0x5DE5, + 0x8D49, 0x5DE7, 0x8D4A, 0x5DF7, 0x8D4B, 0x5E78, 0x8D4C, 0x5E83, + 0x8D4D, 0x5E9A, 0x8D4E, 0x5EB7, 0x8D4F, 0x5F18, 0x8D50, 0x6052, + 0x8D51, 0x614C, 0x8D52, 0x6297, 0x8D53, 0x62D8, 0x8D54, 0x63A7, + 0x8D55, 0x653B, 0x8D56, 0x6602, 0x8D57, 0x6643, 0x8D58, 0x66F4, + 0x8D59, 0x676D, 0x8D5A, 0x6821, 0x8D5B, 0x6897, 0x8D5C, 0x69CB, + 0x8D5D, 0x6C5F, 0x8D5E, 0x6D2A, 0x8D5F, 0x6D69, 0x8D60, 0x6E2F, + 0x8D61, 0x6E9D, 0x8D62, 0x7532, 0x8D63, 0x7687, 0x8D64, 0x786C, + 0x8D65, 0x7A3F, 0x8D66, 0x7CE0, 0x8D67, 0x7D05, 0x8D68, 0x7D18, + 0x8D69, 0x7D5E, 0x8D6A, 0x7DB1, 0x8D6B, 0x8015, 0x8D6C, 0x8003, + 0x8D6D, 0x80AF, 0x8D6E, 0x80B1, 0x8D6F, 0x8154, 0x8D70, 0x818F, + 0x8D71, 0x822A, 0x8D72, 0x8352, 0x8D73, 0x884C, 0x8D74, 0x8861, + 0x8D75, 0x8B1B, 0x8D76, 0x8CA2, 0x8D77, 0x8CFC, 0x8D78, 0x90CA, + 0x8D79, 0x9175, 0x8D7A, 0x9271, 0x8D7B, 0x783F, 0x8D7C, 0x92FC, + 0x8D7D, 0x95A4, 0x8D7E, 0x964D, 0x8D80, 0x9805, 0x8D81, 0x9999, + 0x8D82, 0x9AD8, 0x8D83, 0x9D3B, 0x8D84, 0x525B, 0x8D85, 0x52AB, + 0x8D86, 0x53F7, 0x8D87, 0x5408, 0x8D88, 0x58D5, 0x8D89, 0x62F7, + 0x8D8A, 0x6FE0, 0x8D8B, 0x8C6A, 0x8D8C, 0x8F5F, 0x8D8D, 0x9EB9, + 0x8D8E, 0x514B, 0x8D8F, 0x523B, 0x8D90, 0x544A, 0x8D91, 0x56FD, + 0x8D92, 0x7A40, 0x8D93, 0x9177, 0x8D94, 0x9D60, 0x8D95, 0x9ED2, + 0x8D96, 0x7344, 0x8D97, 0x6F09, 0x8D98, 0x8170, 0x8D99, 0x7511, + 0x8D9A, 0x5FFD, 0x8D9B, 0x60DA, 0x8D9C, 0x9AA8, 0x8D9D, 0x72DB, + 0x8D9E, 0x8FBC, 0x8D9F, 0x6B64, 0x8DA0, 0x9803, 0x8DA1, 0x4ECA, + 0x8DA2, 0x56F0, 0x8DA3, 0x5764, 0x8DA4, 0x58BE, 0x8DA5, 0x5A5A, + 0x8DA6, 0x6068, 0x8DA7, 0x61C7, 0x8DA8, 0x660F, 0x8DA9, 0x6606, + 0x8DAA, 0x6839, 0x8DAB, 0x68B1, 0x8DAC, 0x6DF7, 0x8DAD, 0x75D5, + 0x8DAE, 0x7D3A, 0x8DAF, 0x826E, 0x8DB0, 0x9B42, 0x8DB1, 0x4E9B, + 0x8DB2, 0x4F50, 0x8DB3, 0x53C9, 0x8DB4, 0x5506, 0x8DB5, 0x5D6F, + 0x8DB6, 0x5DE6, 0x8DB7, 0x5DEE, 0x8DB8, 0x67FB, 0x8DB9, 0x6C99, + 0x8DBA, 0x7473, 0x8DBB, 0x7802, 0x8DBC, 0x8A50, 0x8DBD, 0x9396, + 0x8DBE, 0x88DF, 0x8DBF, 0x5750, 0x8DC0, 0x5EA7, 0x8DC1, 0x632B, + 0x8DC2, 0x50B5, 0x8DC3, 0x50AC, 0x8DC4, 0x518D, 0x8DC5, 0x6700, + 0x8DC6, 0x54C9, 0x8DC7, 0x585E, 0x8DC8, 0x59BB, 0x8DC9, 0x5BB0, + 0x8DCA, 0x5F69, 0x8DCB, 0x624D, 0x8DCC, 0x63A1, 0x8DCD, 0x683D, + 0x8DCE, 0x6B73, 0x8DCF, 0x6E08, 0x8DD0, 0x707D, 0x8DD1, 0x91C7, + 0x8DD2, 0x7280, 0x8DD3, 0x7815, 0x8DD4, 0x7826, 0x8DD5, 0x796D, + 0x8DD6, 0x658E, 0x8DD7, 0x7D30, 0x8DD8, 0x83DC, 0x8DD9, 0x88C1, + 0x8DDA, 0x8F09, 0x8DDB, 0x969B, 0x8DDC, 0x5264, 0x8DDD, 0x5728, + 0x8DDE, 0x6750, 0x8DDF, 0x7F6A, 0x8DE0, 0x8CA1, 0x8DE1, 0x51B4, + 0x8DE2, 0x5742, 0x8DE3, 0x962A, 0x8DE4, 0x583A, 0x8DE5, 0x698A, + 0x8DE6, 0x80B4, 0x8DE7, 0x54B2, 0x8DE8, 0x5D0E, 0x8DE9, 0x57FC, + 0x8DEA, 0x7895, 0x8DEB, 0x9DFA, 0x8DEC, 0x4F5C, 0x8DED, 0x524A, + 0x8DEE, 0x548B, 0x8DEF, 0x643E, 0x8DF0, 0x6628, 0x8DF1, 0x6714, + 0x8DF2, 0x67F5, 0x8DF3, 0x7A84, 0x8DF4, 0x7B56, 0x8DF5, 0x7D22, + 0x8DF6, 0x932F, 0x8DF7, 0x685C, 0x8DF8, 0x9BAD, 0x8DF9, 0x7B39, + 0x8DFA, 0x5319, 0x8DFB, 0x518A, 0x8DFC, 0x5237, 0x8E40, 0x5BDF, + 0x8E41, 0x62F6, 0x8E42, 0x64AE, 0x8E43, 0x64E6, 0x8E44, 0x672D, + 0x8E45, 0x6BBA, 0x8E46, 0x85A9, 0x8E47, 0x96D1, 0x8E48, 0x7690, + 0x8E49, 0x9BD6, 0x8E4A, 0x634C, 0x8E4B, 0x9306, 0x8E4C, 0x9BAB, + 0x8E4D, 0x76BF, 0x8E4E, 0x6652, 0x8E4F, 0x4E09, 0x8E50, 0x5098, + 0x8E51, 0x53C2, 0x8E52, 0x5C71, 0x8E53, 0x60E8, 0x8E54, 0x6492, + 0x8E55, 0x6563, 0x8E56, 0x685F, 0x8E57, 0x71E6, 0x8E58, 0x73CA, + 0x8E59, 0x7523, 0x8E5A, 0x7B97, 0x8E5B, 0x7E82, 0x8E5C, 0x8695, + 0x8E5D, 0x8B83, 0x8E5E, 0x8CDB, 0x8E5F, 0x9178, 0x8E60, 0x9910, + 0x8E61, 0x65AC, 0x8E62, 0x66AB, 0x8E63, 0x6B8B, 0x8E64, 0x4ED5, + 0x8E65, 0x4ED4, 0x8E66, 0x4F3A, 0x8E67, 0x4F7F, 0x8E68, 0x523A, + 0x8E69, 0x53F8, 0x8E6A, 0x53F2, 0x8E6B, 0x55E3, 0x8E6C, 0x56DB, + 0x8E6D, 0x58EB, 0x8E6E, 0x59CB, 0x8E6F, 0x59C9, 0x8E70, 0x59FF, + 0x8E71, 0x5B50, 0x8E72, 0x5C4D, 0x8E73, 0x5E02, 0x8E74, 0x5E2B, + 0x8E75, 0x5FD7, 0x8E76, 0x601D, 0x8E77, 0x6307, 0x8E78, 0x652F, + 0x8E79, 0x5B5C, 0x8E7A, 0x65AF, 0x8E7B, 0x65BD, 0x8E7C, 0x65E8, + 0x8E7D, 0x679D, 0x8E7E, 0x6B62, 0x8E80, 0x6B7B, 0x8E81, 0x6C0F, + 0x8E82, 0x7345, 0x8E83, 0x7949, 0x8E84, 0x79C1, 0x8E85, 0x7CF8, + 0x8E86, 0x7D19, 0x8E87, 0x7D2B, 0x8E88, 0x80A2, 0x8E89, 0x8102, + 0x8E8A, 0x81F3, 0x8E8B, 0x8996, 0x8E8C, 0x8A5E, 0x8E8D, 0x8A69, + 0x8E8E, 0x8A66, 0x8E8F, 0x8A8C, 0x8E90, 0x8AEE, 0x8E91, 0x8CC7, + 0x8E92, 0x8CDC, 0x8E93, 0x96CC, 0x8E94, 0x98FC, 0x8E95, 0x6B6F, + 0x8E96, 0x4E8B, 0x8E97, 0x4F3C, 0x8E98, 0x4F8D, 0x8E99, 0x5150, + 0x8E9A, 0x5B57, 0x8E9B, 0x5BFA, 0x8E9C, 0x6148, 0x8E9D, 0x6301, + 0x8E9E, 0x6642, 0x8E9F, 0x6B21, 0x8EA0, 0x6ECB, 0x8EA1, 0x6CBB, + 0x8EA2, 0x723E, 0x8EA3, 0x74BD, 0x8EA4, 0x75D4, 0x8EA5, 0x78C1, + 0x8EA6, 0x793A, 0x8EA7, 0x800C, 0x8EA8, 0x8033, 0x8EA9, 0x81EA, + 0x8EAA, 0x8494, 0x8EAB, 0x8F9E, 0x8EAC, 0x6C50, 0x8EAD, 0x9E7F, + 0x8EAE, 0x5F0F, 0x8EAF, 0x8B58, 0x8EB0, 0x9D2B, 0x8EB1, 0x7AFA, + 0x8EB2, 0x8EF8, 0x8EB3, 0x5B8D, 0x8EB4, 0x96EB, 0x8EB5, 0x4E03, + 0x8EB6, 0x53F1, 0x8EB7, 0x57F7, 0x8EB8, 0x5931, 0x8EB9, 0x5AC9, + 0x8EBA, 0x5BA4, 0x8EBB, 0x6089, 0x8EBC, 0x6E7F, 0x8EBD, 0x6F06, + 0x8EBE, 0x75BE, 0x8EBF, 0x8CEA, 0x8EC0, 0x5B9F, 0x8EC1, 0x8500, + 0x8EC2, 0x7BE0, 0x8EC3, 0x5072, 0x8EC4, 0x67F4, 0x8EC5, 0x829D, + 0x8EC6, 0x5C61, 0x8EC7, 0x854A, 0x8EC8, 0x7E1E, 0x8EC9, 0x820E, + 0x8ECA, 0x5199, 0x8ECB, 0x5C04, 0x8ECC, 0x6368, 0x8ECD, 0x8D66, + 0x8ECE, 0x659C, 0x8ECF, 0x716E, 0x8ED0, 0x793E, 0x8ED1, 0x7D17, + 0x8ED2, 0x8005, 0x8ED3, 0x8B1D, 0x8ED4, 0x8ECA, 0x8ED5, 0x906E, + 0x8ED6, 0x86C7, 0x8ED7, 0x90AA, 0x8ED8, 0x501F, 0x8ED9, 0x52FA, + 0x8EDA, 0x5C3A, 0x8EDB, 0x6753, 0x8EDC, 0x707C, 0x8EDD, 0x7235, + 0x8EDE, 0x914C, 0x8EDF, 0x91C8, 0x8EE0, 0x932B, 0x8EE1, 0x82E5, + 0x8EE2, 0x5BC2, 0x8EE3, 0x5F31, 0x8EE4, 0x60F9, 0x8EE5, 0x4E3B, + 0x8EE6, 0x53D6, 0x8EE7, 0x5B88, 0x8EE8, 0x624B, 0x8EE9, 0x6731, + 0x8EEA, 0x6B8A, 0x8EEB, 0x72E9, 0x8EEC, 0x73E0, 0x8EED, 0x7A2E, + 0x8EEE, 0x816B, 0x8EEF, 0x8DA3, 0x8EF0, 0x9152, 0x8EF1, 0x9996, + 0x8EF2, 0x5112, 0x8EF3, 0x53D7, 0x8EF4, 0x546A, 0x8EF5, 0x5BFF, + 0x8EF6, 0x6388, 0x8EF7, 0x6A39, 0x8EF8, 0x7DAC, 0x8EF9, 0x9700, + 0x8EFA, 0x56DA, 0x8EFB, 0x53CE, 0x8EFC, 0x5468, 0x8F40, 0x5B97, + 0x8F41, 0x5C31, 0x8F42, 0x5DDE, 0x8F43, 0x4FEE, 0x8F44, 0x6101, + 0x8F45, 0x62FE, 0x8F46, 0x6D32, 0x8F47, 0x79C0, 0x8F48, 0x79CB, + 0x8F49, 0x7D42, 0x8F4A, 0x7E4D, 0x8F4B, 0x7FD2, 0x8F4C, 0x81ED, + 0x8F4D, 0x821F, 0x8F4E, 0x8490, 0x8F4F, 0x8846, 0x8F50, 0x8972, + 0x8F51, 0x8B90, 0x8F52, 0x8E74, 0x8F53, 0x8F2F, 0x8F54, 0x9031, + 0x8F55, 0x914B, 0x8F56, 0x916C, 0x8F57, 0x96C6, 0x8F58, 0x919C, + 0x8F59, 0x4EC0, 0x8F5A, 0x4F4F, 0x8F5B, 0x5145, 0x8F5C, 0x5341, + 0x8F5D, 0x5F93, 0x8F5E, 0x620E, 0x8F5F, 0x67D4, 0x8F60, 0x6C41, + 0x8F61, 0x6E0B, 0x8F62, 0x7363, 0x8F63, 0x7E26, 0x8F64, 0x91CD, + 0x8F65, 0x9283, 0x8F66, 0x53D4, 0x8F67, 0x5919, 0x8F68, 0x5BBF, + 0x8F69, 0x6DD1, 0x8F6A, 0x795D, 0x8F6B, 0x7E2E, 0x8F6C, 0x7C9B, + 0x8F6D, 0x587E, 0x8F6E, 0x719F, 0x8F6F, 0x51FA, 0x8F70, 0x8853, + 0x8F71, 0x8FF0, 0x8F72, 0x4FCA, 0x8F73, 0x5CFB, 0x8F74, 0x6625, + 0x8F75, 0x77AC, 0x8F76, 0x7AE3, 0x8F77, 0x821C, 0x8F78, 0x99FF, + 0x8F79, 0x51C6, 0x8F7A, 0x5FAA, 0x8F7B, 0x65EC, 0x8F7C, 0x696F, + 0x8F7D, 0x6B89, 0x8F7E, 0x6DF3, 0x8F80, 0x6E96, 0x8F81, 0x6F64, + 0x8F82, 0x76FE, 0x8F83, 0x7D14, 0x8F84, 0x5DE1, 0x8F85, 0x9075, + 0x8F86, 0x9187, 0x8F87, 0x9806, 0x8F88, 0x51E6, 0x8F89, 0x521D, + 0x8F8A, 0x6240, 0x8F8B, 0x6691, 0x8F8C, 0x66D9, 0x8F8D, 0x6E1A, + 0x8F8E, 0x5EB6, 0x8F8F, 0x7DD2, 0x8F90, 0x7F72, 0x8F91, 0x66F8, + 0x8F92, 0x85AF, 0x8F93, 0x85F7, 0x8F94, 0x8AF8, 0x8F95, 0x52A9, + 0x8F96, 0x53D9, 0x8F97, 0x5973, 0x8F98, 0x5E8F, 0x8F99, 0x5F90, + 0x8F9A, 0x6055, 0x8F9B, 0x92E4, 0x8F9C, 0x9664, 0x8F9D, 0x50B7, + 0x8F9E, 0x511F, 0x8F9F, 0x52DD, 0x8FA0, 0x5320, 0x8FA1, 0x5347, + 0x8FA2, 0x53EC, 0x8FA3, 0x54E8, 0x8FA4, 0x5546, 0x8FA5, 0x5531, + 0x8FA6, 0x5617, 0x8FA7, 0x5968, 0x8FA8, 0x59BE, 0x8FA9, 0x5A3C, + 0x8FAA, 0x5BB5, 0x8FAB, 0x5C06, 0x8FAC, 0x5C0F, 0x8FAD, 0x5C11, + 0x8FAE, 0x5C1A, 0x8FAF, 0x5E84, 0x8FB0, 0x5E8A, 0x8FB1, 0x5EE0, + 0x8FB2, 0x5F70, 0x8FB3, 0x627F, 0x8FB4, 0x6284, 0x8FB5, 0x62DB, + 0x8FB6, 0x638C, 0x8FB7, 0x6377, 0x8FB8, 0x6607, 0x8FB9, 0x660C, + 0x8FBA, 0x662D, 0x8FBB, 0x6676, 0x8FBC, 0x677E, 0x8FBD, 0x68A2, + 0x8FBE, 0x6A1F, 0x8FBF, 0x6A35, 0x8FC0, 0x6CBC, 0x8FC1, 0x6D88, + 0x8FC2, 0x6E09, 0x8FC3, 0x6E58, 0x8FC4, 0x713C, 0x8FC5, 0x7126, + 0x8FC6, 0x7167, 0x8FC7, 0x75C7, 0x8FC8, 0x7701, 0x8FC9, 0x785D, + 0x8FCA, 0x7901, 0x8FCB, 0x7965, 0x8FCC, 0x79F0, 0x8FCD, 0x7AE0, + 0x8FCE, 0x7B11, 0x8FCF, 0x7CA7, 0x8FD0, 0x7D39, 0x8FD1, 0x8096, + 0x8FD2, 0x83D6, 0x8FD3, 0x848B, 0x8FD4, 0x8549, 0x8FD5, 0x885D, + 0x8FD6, 0x88F3, 0x8FD7, 0x8A1F, 0x8FD8, 0x8A3C, 0x8FD9, 0x8A54, + 0x8FDA, 0x8A73, 0x8FDB, 0x8C61, 0x8FDC, 0x8CDE, 0x8FDD, 0x91A4, + 0x8FDE, 0x9266, 0x8FDF, 0x937E, 0x8FE0, 0x9418, 0x8FE1, 0x969C, + 0x8FE2, 0x9798, 0x8FE3, 0x4E0A, 0x8FE4, 0x4E08, 0x8FE5, 0x4E1E, + 0x8FE6, 0x4E57, 0x8FE7, 0x5197, 0x8FE8, 0x5270, 0x8FE9, 0x57CE, + 0x8FEA, 0x5834, 0x8FEB, 0x58CC, 0x8FEC, 0x5B22, 0x8FED, 0x5E38, + 0x8FEE, 0x60C5, 0x8FEF, 0x64FE, 0x8FF0, 0x6761, 0x8FF1, 0x6756, + 0x8FF2, 0x6D44, 0x8FF3, 0x72B6, 0x8FF4, 0x7573, 0x8FF5, 0x7A63, + 0x8FF6, 0x84B8, 0x8FF7, 0x8B72, 0x8FF8, 0x91B8, 0x8FF9, 0x9320, + 0x8FFA, 0x5631, 0x8FFB, 0x57F4, 0x8FFC, 0x98FE, 0x9040, 0x62ED, + 0x9041, 0x690D, 0x9042, 0x6B96, 0x9043, 0x71ED, 0x9044, 0x7E54, + 0x9045, 0x8077, 0x9046, 0x8272, 0x9047, 0x89E6, 0x9048, 0x98DF, + 0x9049, 0x8755, 0x904A, 0x8FB1, 0x904B, 0x5C3B, 0x904C, 0x4F38, + 0x904D, 0x4FE1, 0x904E, 0x4FB5, 0x904F, 0x5507, 0x9050, 0x5A20, + 0x9051, 0x5BDD, 0x9052, 0x5BE9, 0x9053, 0x5FC3, 0x9054, 0x614E, + 0x9055, 0x632F, 0x9056, 0x65B0, 0x9057, 0x664B, 0x9058, 0x68EE, + 0x9059, 0x699B, 0x905A, 0x6D78, 0x905B, 0x6DF1, 0x905C, 0x7533, + 0x905D, 0x75B9, 0x905E, 0x771F, 0x905F, 0x795E, 0x9060, 0x79E6, + 0x9061, 0x7D33, 0x9062, 0x81E3, 0x9063, 0x82AF, 0x9064, 0x85AA, + 0x9065, 0x89AA, 0x9066, 0x8A3A, 0x9067, 0x8EAB, 0x9068, 0x8F9B, + 0x9069, 0x9032, 0x906A, 0x91DD, 0x906B, 0x9707, 0x906C, 0x4EBA, + 0x906D, 0x4EC1, 0x906E, 0x5203, 0x906F, 0x5875, 0x9070, 0x58EC, + 0x9071, 0x5C0B, 0x9072, 0x751A, 0x9073, 0x5C3D, 0x9074, 0x814E, + 0x9075, 0x8A0A, 0x9076, 0x8FC5, 0x9077, 0x9663, 0x9078, 0x976D, + 0x9079, 0x7B25, 0x907A, 0x8ACF, 0x907B, 0x9808, 0x907C, 0x9162, + 0x907D, 0x56F3, 0x907E, 0x53A8, 0x9080, 0x9017, 0x9081, 0x5439, + 0x9082, 0x5782, 0x9083, 0x5E25, 0x9084, 0x63A8, 0x9085, 0x6C34, + 0x9086, 0x708A, 0x9087, 0x7761, 0x9088, 0x7C8B, 0x9089, 0x7FE0, + 0x908A, 0x8870, 0x908B, 0x9042, 0x908C, 0x9154, 0x908D, 0x9310, + 0x908E, 0x9318, 0x908F, 0x968F, 0x9090, 0x745E, 0x9091, 0x9AC4, + 0x9092, 0x5D07, 0x9093, 0x5D69, 0x9094, 0x6570, 0x9095, 0x67A2, + 0x9096, 0x8DA8, 0x9097, 0x96DB, 0x9098, 0x636E, 0x9099, 0x6749, + 0x909A, 0x6919, 0x909B, 0x83C5, 0x909C, 0x9817, 0x909D, 0x96C0, + 0x909E, 0x88FE, 0x909F, 0x6F84, 0x90A0, 0x647A, 0x90A1, 0x5BF8, + 0x90A2, 0x4E16, 0x90A3, 0x702C, 0x90A4, 0x755D, 0x90A5, 0x662F, + 0x90A6, 0x51C4, 0x90A7, 0x5236, 0x90A8, 0x52E2, 0x90A9, 0x59D3, + 0x90AA, 0x5F81, 0x90AB, 0x6027, 0x90AC, 0x6210, 0x90AD, 0x653F, + 0x90AE, 0x6574, 0x90AF, 0x661F, 0x90B0, 0x6674, 0x90B1, 0x68F2, + 0x90B2, 0x6816, 0x90B3, 0x6B63, 0x90B4, 0x6E05, 0x90B5, 0x7272, + 0x90B6, 0x751F, 0x90B7, 0x76DB, 0x90B8, 0x7CBE, 0x90B9, 0x8056, + 0x90BA, 0x58F0, 0x90BB, 0x88FD, 0x90BC, 0x897F, 0x90BD, 0x8AA0, + 0x90BE, 0x8A93, 0x90BF, 0x8ACB, 0x90C0, 0x901D, 0x90C1, 0x9192, + 0x90C2, 0x9752, 0x90C3, 0x9759, 0x90C4, 0x6589, 0x90C5, 0x7A0E, + 0x90C6, 0x8106, 0x90C7, 0x96BB, 0x90C8, 0x5E2D, 0x90C9, 0x60DC, + 0x90CA, 0x621A, 0x90CB, 0x65A5, 0x90CC, 0x6614, 0x90CD, 0x6790, + 0x90CE, 0x77F3, 0x90CF, 0x7A4D, 0x90D0, 0x7C4D, 0x90D1, 0x7E3E, + 0x90D2, 0x810A, 0x90D3, 0x8CAC, 0x90D4, 0x8D64, 0x90D5, 0x8DE1, + 0x90D6, 0x8E5F, 0x90D7, 0x78A9, 0x90D8, 0x5207, 0x90D9, 0x62D9, + 0x90DA, 0x63A5, 0x90DB, 0x6442, 0x90DC, 0x6298, 0x90DD, 0x8A2D, + 0x90DE, 0x7A83, 0x90DF, 0x7BC0, 0x90E0, 0x8AAC, 0x90E1, 0x96EA, + 0x90E2, 0x7D76, 0x90E3, 0x820C, 0x90E4, 0x8749, 0x90E5, 0x4ED9, + 0x90E6, 0x5148, 0x90E7, 0x5343, 0x90E8, 0x5360, 0x90E9, 0x5BA3, + 0x90EA, 0x5C02, 0x90EB, 0x5C16, 0x90EC, 0x5DDD, 0x90ED, 0x6226, + 0x90EE, 0x6247, 0x90EF, 0x64B0, 0x90F0, 0x6813, 0x90F1, 0x6834, + 0x90F2, 0x6CC9, 0x90F3, 0x6D45, 0x90F4, 0x6D17, 0x90F5, 0x67D3, + 0x90F6, 0x6F5C, 0x90F7, 0x714E, 0x90F8, 0x717D, 0x90F9, 0x65CB, + 0x90FA, 0x7A7F, 0x90FB, 0x7BAD, 0x90FC, 0x7DDA, 0x9140, 0x7E4A, + 0x9141, 0x7FA8, 0x9142, 0x817A, 0x9143, 0x821B, 0x9144, 0x8239, + 0x9145, 0x85A6, 0x9146, 0x8A6E, 0x9147, 0x8CCE, 0x9148, 0x8DF5, + 0x9149, 0x9078, 0x914A, 0x9077, 0x914B, 0x92AD, 0x914C, 0x9291, + 0x914D, 0x9583, 0x914E, 0x9BAE, 0x914F, 0x524D, 0x9150, 0x5584, + 0x9151, 0x6F38, 0x9152, 0x7136, 0x9153, 0x5168, 0x9154, 0x7985, + 0x9155, 0x7E55, 0x9156, 0x81B3, 0x9157, 0x7CCE, 0x9158, 0x564C, + 0x9159, 0x5851, 0x915A, 0x5CA8, 0x915B, 0x63AA, 0x915C, 0x66FE, + 0x915D, 0x66FD, 0x915E, 0x695A, 0x915F, 0x72D9, 0x9160, 0x758F, + 0x9161, 0x758E, 0x9162, 0x790E, 0x9163, 0x7956, 0x9164, 0x79DF, + 0x9165, 0x7C97, 0x9166, 0x7D20, 0x9167, 0x7D44, 0x9168, 0x8607, + 0x9169, 0x8A34, 0x916A, 0x963B, 0x916B, 0x9061, 0x916C, 0x9F20, + 0x916D, 0x50E7, 0x916E, 0x5275, 0x916F, 0x53CC, 0x9170, 0x53E2, + 0x9171, 0x5009, 0x9172, 0x55AA, 0x9173, 0x58EE, 0x9174, 0x594F, + 0x9175, 0x723D, 0x9176, 0x5B8B, 0x9177, 0x5C64, 0x9178, 0x531D, + 0x9179, 0x60E3, 0x917A, 0x60F3, 0x917B, 0x635C, 0x917C, 0x6383, + 0x917D, 0x633F, 0x917E, 0x63BB, 0x9180, 0x64CD, 0x9181, 0x65E9, + 0x9182, 0x66F9, 0x9183, 0x5DE3, 0x9184, 0x69CD, 0x9185, 0x69FD, + 0x9186, 0x6F15, 0x9187, 0x71E5, 0x9188, 0x4E89, 0x9189, 0x75E9, + 0x918A, 0x76F8, 0x918B, 0x7A93, 0x918C, 0x7CDF, 0x918D, 0x7DCF, + 0x918E, 0x7D9C, 0x918F, 0x8061, 0x9190, 0x8349, 0x9191, 0x8358, + 0x9192, 0x846C, 0x9193, 0x84BC, 0x9194, 0x85FB, 0x9195, 0x88C5, + 0x9196, 0x8D70, 0x9197, 0x9001, 0x9198, 0x906D, 0x9199, 0x9397, + 0x919A, 0x971C, 0x919B, 0x9A12, 0x919C, 0x50CF, 0x919D, 0x5897, + 0x919E, 0x618E, 0x919F, 0x81D3, 0x91A0, 0x8535, 0x91A1, 0x8D08, + 0x91A2, 0x9020, 0x91A3, 0x4FC3, 0x91A4, 0x5074, 0x91A5, 0x5247, + 0x91A6, 0x5373, 0x91A7, 0x606F, 0x91A8, 0x6349, 0x91A9, 0x675F, + 0x91AA, 0x6E2C, 0x91AB, 0x8DB3, 0x91AC, 0x901F, 0x91AD, 0x4FD7, + 0x91AE, 0x5C5E, 0x91AF, 0x8CCA, 0x91B0, 0x65CF, 0x91B1, 0x7D9A, + 0x91B2, 0x5352, 0x91B3, 0x8896, 0x91B4, 0x5176, 0x91B5, 0x63C3, + 0x91B6, 0x5B58, 0x91B7, 0x5B6B, 0x91B8, 0x5C0A, 0x91B9, 0x640D, + 0x91BA, 0x6751, 0x91BB, 0x905C, 0x91BC, 0x4ED6, 0x91BD, 0x591A, + 0x91BE, 0x592A, 0x91BF, 0x6C70, 0x91C0, 0x8A51, 0x91C1, 0x553E, + 0x91C2, 0x5815, 0x91C3, 0x59A5, 0x91C4, 0x60F0, 0x91C5, 0x6253, + 0x91C6, 0x67C1, 0x91C7, 0x8235, 0x91C8, 0x6955, 0x91C9, 0x9640, + 0x91CA, 0x99C4, 0x91CB, 0x9A28, 0x91CC, 0x4F53, 0x91CD, 0x5806, + 0x91CE, 0x5BFE, 0x91CF, 0x8010, 0x91D0, 0x5CB1, 0x91D1, 0x5E2F, + 0x91D2, 0x5F85, 0x91D3, 0x6020, 0x91D4, 0x614B, 0x91D5, 0x6234, + 0x91D6, 0x66FF, 0x91D7, 0x6CF0, 0x91D8, 0x6EDE, 0x91D9, 0x80CE, + 0x91DA, 0x817F, 0x91DB, 0x82D4, 0x91DC, 0x888B, 0x91DD, 0x8CB8, + 0x91DE, 0x9000, 0x91DF, 0x902E, 0x91E0, 0x968A, 0x91E1, 0x9EDB, + 0x91E2, 0x9BDB, 0x91E3, 0x4EE3, 0x91E4, 0x53F0, 0x91E5, 0x5927, + 0x91E6, 0x7B2C, 0x91E7, 0x918D, 0x91E8, 0x984C, 0x91E9, 0x9DF9, + 0x91EA, 0x6EDD, 0x91EB, 0x7027, 0x91EC, 0x5353, 0x91ED, 0x5544, + 0x91EE, 0x5B85, 0x91EF, 0x6258, 0x91F0, 0x629E, 0x91F1, 0x62D3, + 0x91F2, 0x6CA2, 0x91F3, 0x6FEF, 0x91F4, 0x7422, 0x91F5, 0x8A17, + 0x91F6, 0x9438, 0x91F7, 0x6FC1, 0x91F8, 0x8AFE, 0x91F9, 0x8338, + 0x91FA, 0x51E7, 0x91FB, 0x86F8, 0x91FC, 0x53EA, 0x9240, 0x53E9, + 0x9241, 0x4F46, 0x9242, 0x9054, 0x9243, 0x8FB0, 0x9244, 0x596A, + 0x9245, 0x8131, 0x9246, 0x5DFD, 0x9247, 0x7AEA, 0x9248, 0x8FBF, + 0x9249, 0x68DA, 0x924A, 0x8C37, 0x924B, 0x72F8, 0x924C, 0x9C48, + 0x924D, 0x6A3D, 0x924E, 0x8AB0, 0x924F, 0x4E39, 0x9250, 0x5358, + 0x9251, 0x5606, 0x9252, 0x5766, 0x9253, 0x62C5, 0x9254, 0x63A2, + 0x9255, 0x65E6, 0x9256, 0x6B4E, 0x9257, 0x6DE1, 0x9258, 0x6E5B, + 0x9259, 0x70AD, 0x925A, 0x77ED, 0x925B, 0x7AEF, 0x925C, 0x7BAA, + 0x925D, 0x7DBB, 0x925E, 0x803D, 0x925F, 0x80C6, 0x9260, 0x86CB, + 0x9261, 0x8A95, 0x9262, 0x935B, 0x9263, 0x56E3, 0x9264, 0x58C7, + 0x9265, 0x5F3E, 0x9266, 0x65AD, 0x9267, 0x6696, 0x9268, 0x6A80, + 0x9269, 0x6BB5, 0x926A, 0x7537, 0x926B, 0x8AC7, 0x926C, 0x5024, + 0x926D, 0x77E5, 0x926E, 0x5730, 0x926F, 0x5F1B, 0x9270, 0x6065, + 0x9271, 0x667A, 0x9272, 0x6C60, 0x9273, 0x75F4, 0x9274, 0x7A1A, + 0x9275, 0x7F6E, 0x9276, 0x81F4, 0x9277, 0x8718, 0x9278, 0x9045, + 0x9279, 0x99B3, 0x927A, 0x7BC9, 0x927B, 0x755C, 0x927C, 0x7AF9, + 0x927D, 0x7B51, 0x927E, 0x84C4, 0x9280, 0x9010, 0x9281, 0x79E9, + 0x9282, 0x7A92, 0x9283, 0x8336, 0x9284, 0x5AE1, 0x9285, 0x7740, + 0x9286, 0x4E2D, 0x9287, 0x4EF2, 0x9288, 0x5B99, 0x9289, 0x5FE0, + 0x928A, 0x62BD, 0x928B, 0x663C, 0x928C, 0x67F1, 0x928D, 0x6CE8, + 0x928E, 0x866B, 0x928F, 0x8877, 0x9290, 0x8A3B, 0x9291, 0x914E, + 0x9292, 0x92F3, 0x9293, 0x99D0, 0x9294, 0x6A17, 0x9295, 0x7026, + 0x9296, 0x732A, 0x9297, 0x82E7, 0x9298, 0x8457, 0x9299, 0x8CAF, + 0x929A, 0x4E01, 0x929B, 0x5146, 0x929C, 0x51CB, 0x929D, 0x558B, + 0x929E, 0x5BF5, 0x929F, 0x5E16, 0x92A0, 0x5E33, 0x92A1, 0x5E81, + 0x92A2, 0x5F14, 0x92A3, 0x5F35, 0x92A4, 0x5F6B, 0x92A5, 0x5FB4, + 0x92A6, 0x61F2, 0x92A7, 0x6311, 0x92A8, 0x66A2, 0x92A9, 0x671D, + 0x92AA, 0x6F6E, 0x92AB, 0x7252, 0x92AC, 0x753A, 0x92AD, 0x773A, + 0x92AE, 0x8074, 0x92AF, 0x8139, 0x92B0, 0x8178, 0x92B1, 0x8776, + 0x92B2, 0x8ABF, 0x92B3, 0x8ADC, 0x92B4, 0x8D85, 0x92B5, 0x8DF3, + 0x92B6, 0x929A, 0x92B7, 0x9577, 0x92B8, 0x9802, 0x92B9, 0x9CE5, + 0x92BA, 0x52C5, 0x92BB, 0x6357, 0x92BC, 0x76F4, 0x92BD, 0x6715, + 0x92BE, 0x6C88, 0x92BF, 0x73CD, 0x92C0, 0x8CC3, 0x92C1, 0x93AE, + 0x92C2, 0x9673, 0x92C3, 0x6D25, 0x92C4, 0x589C, 0x92C5, 0x690E, + 0x92C6, 0x69CC, 0x92C7, 0x8FFD, 0x92C8, 0x939A, 0x92C9, 0x75DB, + 0x92CA, 0x901A, 0x92CB, 0x585A, 0x92CC, 0x6802, 0x92CD, 0x63B4, + 0x92CE, 0x69FB, 0x92CF, 0x4F43, 0x92D0, 0x6F2C, 0x92D1, 0x67D8, + 0x92D2, 0x8FBB, 0x92D3, 0x8526, 0x92D4, 0x7DB4, 0x92D5, 0x9354, + 0x92D6, 0x693F, 0x92D7, 0x6F70, 0x92D8, 0x576A, 0x92D9, 0x58F7, + 0x92DA, 0x5B2C, 0x92DB, 0x7D2C, 0x92DC, 0x722A, 0x92DD, 0x540A, + 0x92DE, 0x91E3, 0x92DF, 0x9DB4, 0x92E0, 0x4EAD, 0x92E1, 0x4F4E, + 0x92E2, 0x505C, 0x92E3, 0x5075, 0x92E4, 0x5243, 0x92E5, 0x8C9E, + 0x92E6, 0x5448, 0x92E7, 0x5824, 0x92E8, 0x5B9A, 0x92E9, 0x5E1D, + 0x92EA, 0x5E95, 0x92EB, 0x5EAD, 0x92EC, 0x5EF7, 0x92ED, 0x5F1F, + 0x92EE, 0x608C, 0x92EF, 0x62B5, 0x92F0, 0x633A, 0x92F1, 0x63D0, + 0x92F2, 0x68AF, 0x92F3, 0x6C40, 0x92F4, 0x7887, 0x92F5, 0x798E, + 0x92F6, 0x7A0B, 0x92F7, 0x7DE0, 0x92F8, 0x8247, 0x92F9, 0x8A02, + 0x92FA, 0x8AE6, 0x92FB, 0x8E44, 0x92FC, 0x9013, 0x9340, 0x90B8, + 0x9341, 0x912D, 0x9342, 0x91D8, 0x9343, 0x9F0E, 0x9344, 0x6CE5, + 0x9345, 0x6458, 0x9346, 0x64E2, 0x9347, 0x6575, 0x9348, 0x6EF4, + 0x9349, 0x7684, 0x934A, 0x7B1B, 0x934B, 0x9069, 0x934C, 0x93D1, + 0x934D, 0x6EBA, 0x934E, 0x54F2, 0x934F, 0x5FB9, 0x9350, 0x64A4, + 0x9351, 0x8F4D, 0x9352, 0x8FED, 0x9353, 0x9244, 0x9354, 0x5178, + 0x9355, 0x586B, 0x9356, 0x5929, 0x9357, 0x5C55, 0x9358, 0x5E97, + 0x9359, 0x6DFB, 0x935A, 0x7E8F, 0x935B, 0x751C, 0x935C, 0x8CBC, + 0x935D, 0x8EE2, 0x935E, 0x985B, 0x935F, 0x70B9, 0x9360, 0x4F1D, + 0x9361, 0x6BBF, 0x9362, 0x6FB1, 0x9363, 0x7530, 0x9364, 0x96FB, + 0x9365, 0x514E, 0x9366, 0x5410, 0x9367, 0x5835, 0x9368, 0x5857, + 0x9369, 0x59AC, 0x936A, 0x5C60, 0x936B, 0x5F92, 0x936C, 0x6597, + 0x936D, 0x675C, 0x936E, 0x6E21, 0x936F, 0x767B, 0x9370, 0x83DF, + 0x9371, 0x8CED, 0x9372, 0x9014, 0x9373, 0x90FD, 0x9374, 0x934D, + 0x9375, 0x7825, 0x9376, 0x783A, 0x9377, 0x52AA, 0x9378, 0x5EA6, + 0x9379, 0x571F, 0x937A, 0x5974, 0x937B, 0x6012, 0x937C, 0x5012, + 0x937D, 0x515A, 0x937E, 0x51AC, 0x9380, 0x51CD, 0x9381, 0x5200, + 0x9382, 0x5510, 0x9383, 0x5854, 0x9384, 0x5858, 0x9385, 0x5957, + 0x9386, 0x5B95, 0x9387, 0x5CF6, 0x9388, 0x5D8B, 0x9389, 0x60BC, + 0x938A, 0x6295, 0x938B, 0x642D, 0x938C, 0x6771, 0x938D, 0x6843, + 0x938E, 0x68BC, 0x938F, 0x68DF, 0x9390, 0x76D7, 0x9391, 0x6DD8, + 0x9392, 0x6E6F, 0x9393, 0x6D9B, 0x9394, 0x706F, 0x9395, 0x71C8, + 0x9396, 0x5F53, 0x9397, 0x75D8, 0x9398, 0x7977, 0x9399, 0x7B49, + 0x939A, 0x7B54, 0x939B, 0x7B52, 0x939C, 0x7CD6, 0x939D, 0x7D71, + 0x939E, 0x5230, 0x939F, 0x8463, 0x93A0, 0x8569, 0x93A1, 0x85E4, + 0x93A2, 0x8A0E, 0x93A3, 0x8B04, 0x93A4, 0x8C46, 0x93A5, 0x8E0F, + 0x93A6, 0x9003, 0x93A7, 0x900F, 0x93A8, 0x9419, 0x93A9, 0x9676, + 0x93AA, 0x982D, 0x93AB, 0x9A30, 0x93AC, 0x95D8, 0x93AD, 0x50CD, + 0x93AE, 0x52D5, 0x93AF, 0x540C, 0x93B0, 0x5802, 0x93B1, 0x5C0E, + 0x93B2, 0x61A7, 0x93B3, 0x649E, 0x93B4, 0x6D1E, 0x93B5, 0x77B3, + 0x93B6, 0x7AE5, 0x93B7, 0x80F4, 0x93B8, 0x8404, 0x93B9, 0x9053, + 0x93BA, 0x9285, 0x93BB, 0x5CE0, 0x93BC, 0x9D07, 0x93BD, 0x533F, + 0x93BE, 0x5F97, 0x93BF, 0x5FB3, 0x93C0, 0x6D9C, 0x93C1, 0x7279, + 0x93C2, 0x7763, 0x93C3, 0x79BF, 0x93C4, 0x7BE4, 0x93C5, 0x6BD2, + 0x93C6, 0x72EC, 0x93C7, 0x8AAD, 0x93C8, 0x6803, 0x93C9, 0x6A61, + 0x93CA, 0x51F8, 0x93CB, 0x7A81, 0x93CC, 0x6934, 0x93CD, 0x5C4A, + 0x93CE, 0x9CF6, 0x93CF, 0x82EB, 0x93D0, 0x5BC5, 0x93D1, 0x9149, + 0x93D2, 0x701E, 0x93D3, 0x5678, 0x93D4, 0x5C6F, 0x93D5, 0x60C7, + 0x93D6, 0x6566, 0x93D7, 0x6C8C, 0x93D8, 0x8C5A, 0x93D9, 0x9041, + 0x93DA, 0x9813, 0x93DB, 0x5451, 0x93DC, 0x66C7, 0x93DD, 0x920D, + 0x93DE, 0x5948, 0x93DF, 0x90A3, 0x93E0, 0x5185, 0x93E1, 0x4E4D, + 0x93E2, 0x51EA, 0x93E3, 0x8599, 0x93E4, 0x8B0E, 0x93E5, 0x7058, + 0x93E6, 0x637A, 0x93E7, 0x934B, 0x93E8, 0x6962, 0x93E9, 0x99B4, + 0x93EA, 0x7E04, 0x93EB, 0x7577, 0x93EC, 0x5357, 0x93ED, 0x6960, + 0x93EE, 0x8EDF, 0x93EF, 0x96E3, 0x93F0, 0x6C5D, 0x93F1, 0x4E8C, + 0x93F2, 0x5C3C, 0x93F3, 0x5F10, 0x93F4, 0x8FE9, 0x93F5, 0x5302, + 0x93F6, 0x8CD1, 0x93F7, 0x8089, 0x93F8, 0x8679, 0x93F9, 0x5EFF, + 0x93FA, 0x65E5, 0x93FB, 0x4E73, 0x93FC, 0x5165, 0x9440, 0x5982, + 0x9441, 0x5C3F, 0x9442, 0x97EE, 0x9443, 0x4EFB, 0x9444, 0x598A, + 0x9445, 0x5FCD, 0x9446, 0x8A8D, 0x9447, 0x6FE1, 0x9448, 0x79B0, + 0x9449, 0x7962, 0x944A, 0x5BE7, 0x944B, 0x8471, 0x944C, 0x732B, + 0x944D, 0x71B1, 0x944E, 0x5E74, 0x944F, 0x5FF5, 0x9450, 0x637B, + 0x9451, 0x649A, 0x9452, 0x71C3, 0x9453, 0x7C98, 0x9454, 0x4E43, + 0x9455, 0x5EFC, 0x9456, 0x4E4B, 0x9457, 0x57DC, 0x9458, 0x56A2, + 0x9459, 0x60A9, 0x945A, 0x6FC3, 0x945B, 0x7D0D, 0x945C, 0x80FD, + 0x945D, 0x8133, 0x945E, 0x81BF, 0x945F, 0x8FB2, 0x9460, 0x8997, + 0x9461, 0x86A4, 0x9462, 0x5DF4, 0x9463, 0x628A, 0x9464, 0x64AD, + 0x9465, 0x8987, 0x9466, 0x6777, 0x9467, 0x6CE2, 0x9468, 0x6D3E, + 0x9469, 0x7436, 0x946A, 0x7834, 0x946B, 0x5A46, 0x946C, 0x7F75, + 0x946D, 0x82AD, 0x946E, 0x99AC, 0x946F, 0x4FF3, 0x9470, 0x5EC3, + 0x9471, 0x62DD, 0x9472, 0x6392, 0x9473, 0x6557, 0x9474, 0x676F, + 0x9475, 0x76C3, 0x9476, 0x724C, 0x9477, 0x80CC, 0x9478, 0x80BA, + 0x9479, 0x8F29, 0x947A, 0x914D, 0x947B, 0x500D, 0x947C, 0x57F9, + 0x947D, 0x5A92, 0x947E, 0x6885, 0x9480, 0x6973, 0x9481, 0x7164, + 0x9482, 0x72FD, 0x9483, 0x8CB7, 0x9484, 0x58F2, 0x9485, 0x8CE0, + 0x9486, 0x966A, 0x9487, 0x9019, 0x9488, 0x877F, 0x9489, 0x79E4, + 0x948A, 0x77E7, 0x948B, 0x8429, 0x948C, 0x4F2F, 0x948D, 0x5265, + 0x948E, 0x535A, 0x948F, 0x62CD, 0x9490, 0x67CF, 0x9491, 0x6CCA, + 0x9492, 0x767D, 0x9493, 0x7B94, 0x9494, 0x7C95, 0x9495, 0x8236, + 0x9496, 0x8584, 0x9497, 0x8FEB, 0x9498, 0x66DD, 0x9499, 0x6F20, + 0x949A, 0x7206, 0x949B, 0x7E1B, 0x949C, 0x83AB, 0x949D, 0x99C1, + 0x949E, 0x9EA6, 0x949F, 0x51FD, 0x94A0, 0x7BB1, 0x94A1, 0x7872, + 0x94A2, 0x7BB8, 0x94A3, 0x8087, 0x94A4, 0x7B48, 0x94A5, 0x6AE8, + 0x94A6, 0x5E61, 0x94A7, 0x808C, 0x94A8, 0x7551, 0x94A9, 0x7560, + 0x94AA, 0x516B, 0x94AB, 0x9262, 0x94AC, 0x6E8C, 0x94AD, 0x767A, + 0x94AE, 0x9197, 0x94AF, 0x9AEA, 0x94B0, 0x4F10, 0x94B1, 0x7F70, + 0x94B2, 0x629C, 0x94B3, 0x7B4F, 0x94B4, 0x95A5, 0x94B5, 0x9CE9, + 0x94B6, 0x567A, 0x94B7, 0x5859, 0x94B8, 0x86E4, 0x94B9, 0x96BC, + 0x94BA, 0x4F34, 0x94BB, 0x5224, 0x94BC, 0x534A, 0x94BD, 0x53CD, + 0x94BE, 0x53DB, 0x94BF, 0x5E06, 0x94C0, 0x642C, 0x94C1, 0x6591, + 0x94C2, 0x677F, 0x94C3, 0x6C3E, 0x94C4, 0x6C4E, 0x94C5, 0x7248, + 0x94C6, 0x72AF, 0x94C7, 0x73ED, 0x94C8, 0x7554, 0x94C9, 0x7E41, + 0x94CA, 0x822C, 0x94CB, 0x85E9, 0x94CC, 0x8CA9, 0x94CD, 0x7BC4, + 0x94CE, 0x91C6, 0x94CF, 0x7169, 0x94D0, 0x9812, 0x94D1, 0x98EF, + 0x94D2, 0x633D, 0x94D3, 0x6669, 0x94D4, 0x756A, 0x94D5, 0x76E4, + 0x94D6, 0x78D0, 0x94D7, 0x8543, 0x94D8, 0x86EE, 0x94D9, 0x532A, + 0x94DA, 0x5351, 0x94DB, 0x5426, 0x94DC, 0x5983, 0x94DD, 0x5E87, + 0x94DE, 0x5F7C, 0x94DF, 0x60B2, 0x94E0, 0x6249, 0x94E1, 0x6279, + 0x94E2, 0x62AB, 0x94E3, 0x6590, 0x94E4, 0x6BD4, 0x94E5, 0x6CCC, + 0x94E6, 0x75B2, 0x94E7, 0x76AE, 0x94E8, 0x7891, 0x94E9, 0x79D8, + 0x94EA, 0x7DCB, 0x94EB, 0x7F77, 0x94EC, 0x80A5, 0x94ED, 0x88AB, + 0x94EE, 0x8AB9, 0x94EF, 0x8CBB, 0x94F0, 0x907F, 0x94F1, 0x975E, + 0x94F2, 0x98DB, 0x94F3, 0x6A0B, 0x94F4, 0x7C38, 0x94F5, 0x5099, + 0x94F6, 0x5C3E, 0x94F7, 0x5FAE, 0x94F8, 0x6787, 0x94F9, 0x6BD8, + 0x94FA, 0x7435, 0x94FB, 0x7709, 0x94FC, 0x7F8E, 0x9540, 0x9F3B, + 0x9541, 0x67CA, 0x9542, 0x7A17, 0x9543, 0x5339, 0x9544, 0x758B, + 0x9545, 0x9AED, 0x9546, 0x5F66, 0x9547, 0x819D, 0x9548, 0x83F1, + 0x9549, 0x8098, 0x954A, 0x5F3C, 0x954B, 0x5FC5, 0x954C, 0x7562, + 0x954D, 0x7B46, 0x954E, 0x903C, 0x954F, 0x6867, 0x9550, 0x59EB, + 0x9551, 0x5A9B, 0x9552, 0x7D10, 0x9553, 0x767E, 0x9554, 0x8B2C, + 0x9555, 0x4FF5, 0x9556, 0x5F6A, 0x9557, 0x6A19, 0x9558, 0x6C37, + 0x9559, 0x6F02, 0x955A, 0x74E2, 0x955B, 0x7968, 0x955C, 0x8868, + 0x955D, 0x8A55, 0x955E, 0x8C79, 0x955F, 0x5EDF, 0x9560, 0x63CF, + 0x9561, 0x75C5, 0x9562, 0x79D2, 0x9563, 0x82D7, 0x9564, 0x9328, + 0x9565, 0x92F2, 0x9566, 0x849C, 0x9567, 0x86ED, 0x9568, 0x9C2D, + 0x9569, 0x54C1, 0x956A, 0x5F6C, 0x956B, 0x658C, 0x956C, 0x6D5C, + 0x956D, 0x7015, 0x956E, 0x8CA7, 0x956F, 0x8CD3, 0x9570, 0x983B, + 0x9571, 0x654F, 0x9572, 0x74F6, 0x9573, 0x4E0D, 0x9574, 0x4ED8, + 0x9575, 0x57E0, 0x9576, 0x592B, 0x9577, 0x5A66, 0x9578, 0x5BCC, + 0x9579, 0x51A8, 0x957A, 0x5E03, 0x957B, 0x5E9C, 0x957C, 0x6016, + 0x957D, 0x6276, 0x957E, 0x6577, 0x9580, 0x65A7, 0x9581, 0x666E, + 0x9582, 0x6D6E, 0x9583, 0x7236, 0x9584, 0x7B26, 0x9585, 0x8150, + 0x9586, 0x819A, 0x9587, 0x8299, 0x9588, 0x8B5C, 0x9589, 0x8CA0, + 0x958A, 0x8CE6, 0x958B, 0x8D74, 0x958C, 0x961C, 0x958D, 0x9644, + 0x958E, 0x4FAE, 0x958F, 0x64AB, 0x9590, 0x6B66, 0x9591, 0x821E, + 0x9592, 0x8461, 0x9593, 0x856A, 0x9594, 0x90E8, 0x9595, 0x5C01, + 0x9596, 0x6953, 0x9597, 0x98A8, 0x9598, 0x847A, 0x9599, 0x8557, + 0x959A, 0x4F0F, 0x959B, 0x526F, 0x959C, 0x5FA9, 0x959D, 0x5E45, + 0x959E, 0x670D, 0x959F, 0x798F, 0x95A0, 0x8179, 0x95A1, 0x8907, + 0x95A2, 0x8986, 0x95A3, 0x6DF5, 0x95A4, 0x5F17, 0x95A5, 0x6255, + 0x95A6, 0x6CB8, 0x95A7, 0x4ECF, 0x95A8, 0x7269, 0x95A9, 0x9B92, + 0x95AA, 0x5206, 0x95AB, 0x543B, 0x95AC, 0x5674, 0x95AD, 0x58B3, + 0x95AE, 0x61A4, 0x95AF, 0x626E, 0x95B0, 0x711A, 0x95B1, 0x596E, + 0x95B2, 0x7C89, 0x95B3, 0x7CDE, 0x95B4, 0x7D1B, 0x95B5, 0x96F0, + 0x95B6, 0x6587, 0x95B7, 0x805E, 0x95B8, 0x4E19, 0x95B9, 0x4F75, + 0x95BA, 0x5175, 0x95BB, 0x5840, 0x95BC, 0x5E63, 0x95BD, 0x5E73, + 0x95BE, 0x5F0A, 0x95BF, 0x67C4, 0x95C0, 0x4E26, 0x95C1, 0x853D, + 0x95C2, 0x9589, 0x95C3, 0x965B, 0x95C4, 0x7C73, 0x95C5, 0x9801, + 0x95C6, 0x50FB, 0x95C7, 0x58C1, 0x95C8, 0x7656, 0x95C9, 0x78A7, + 0x95CA, 0x5225, 0x95CB, 0x77A5, 0x95CC, 0x8511, 0x95CD, 0x7B86, + 0x95CE, 0x504F, 0x95CF, 0x5909, 0x95D0, 0x7247, 0x95D1, 0x7BC7, + 0x95D2, 0x7DE8, 0x95D3, 0x8FBA, 0x95D4, 0x8FD4, 0x95D5, 0x904D, + 0x95D6, 0x4FBF, 0x95D7, 0x52C9, 0x95D8, 0x5A29, 0x95D9, 0x5F01, + 0x95DA, 0x97AD, 0x95DB, 0x4FDD, 0x95DC, 0x8217, 0x95DD, 0x92EA, + 0x95DE, 0x5703, 0x95DF, 0x6355, 0x95E0, 0x6B69, 0x95E1, 0x752B, + 0x95E2, 0x88DC, 0x95E3, 0x8F14, 0x95E4, 0x7A42, 0x95E5, 0x52DF, + 0x95E6, 0x5893, 0x95E7, 0x6155, 0x95E8, 0x620A, 0x95E9, 0x66AE, + 0x95EA, 0x6BCD, 0x95EB, 0x7C3F, 0x95EC, 0x83E9, 0x95ED, 0x5023, + 0x95EE, 0x4FF8, 0x95EF, 0x5305, 0x95F0, 0x5446, 0x95F1, 0x5831, + 0x95F2, 0x5949, 0x95F3, 0x5B9D, 0x95F4, 0x5CF0, 0x95F5, 0x5CEF, + 0x95F6, 0x5D29, 0x95F7, 0x5E96, 0x95F8, 0x62B1, 0x95F9, 0x6367, + 0x95FA, 0x653E, 0x95FB, 0x65B9, 0x95FC, 0x670B, 0x9640, 0x6CD5, + 0x9641, 0x6CE1, 0x9642, 0x70F9, 0x9643, 0x7832, 0x9644, 0x7E2B, + 0x9645, 0x80DE, 0x9646, 0x82B3, 0x9647, 0x840C, 0x9648, 0x84EC, + 0x9649, 0x8702, 0x964A, 0x8912, 0x964B, 0x8A2A, 0x964C, 0x8C4A, + 0x964D, 0x90A6, 0x964E, 0x92D2, 0x964F, 0x98FD, 0x9650, 0x9CF3, + 0x9651, 0x9D6C, 0x9652, 0x4E4F, 0x9653, 0x4EA1, 0x9654, 0x508D, + 0x9655, 0x5256, 0x9656, 0x574A, 0x9657, 0x59A8, 0x9658, 0x5E3D, + 0x9659, 0x5FD8, 0x965A, 0x5FD9, 0x965B, 0x623F, 0x965C, 0x66B4, + 0x965D, 0x671B, 0x965E, 0x67D0, 0x965F, 0x68D2, 0x9660, 0x5192, + 0x9661, 0x7D21, 0x9662, 0x80AA, 0x9663, 0x81A8, 0x9664, 0x8B00, + 0x9665, 0x8C8C, 0x9666, 0x8CBF, 0x9667, 0x927E, 0x9668, 0x9632, + 0x9669, 0x5420, 0x966A, 0x982C, 0x966B, 0x5317, 0x966C, 0x50D5, + 0x966D, 0x535C, 0x966E, 0x58A8, 0x966F, 0x64B2, 0x9670, 0x6734, + 0x9671, 0x7267, 0x9672, 0x7766, 0x9673, 0x7A46, 0x9674, 0x91E6, + 0x9675, 0x52C3, 0x9676, 0x6CA1, 0x9677, 0x6B86, 0x9678, 0x5800, + 0x9679, 0x5E4C, 0x967A, 0x5954, 0x967B, 0x672C, 0x967C, 0x7FFB, + 0x967D, 0x51E1, 0x967E, 0x76C6, 0x9680, 0x6469, 0x9681, 0x78E8, + 0x9682, 0x9B54, 0x9683, 0x9EBB, 0x9684, 0x57CB, 0x9685, 0x59B9, + 0x9686, 0x6627, 0x9687, 0x679A, 0x9688, 0x6BCE, 0x9689, 0x54E9, + 0x968A, 0x69D9, 0x968B, 0x5E55, 0x968C, 0x819C, 0x968D, 0x6795, + 0x968E, 0x9BAA, 0x968F, 0x67FE, 0x9690, 0x9C52, 0x9691, 0x685D, + 0x9692, 0x4EA6, 0x9693, 0x4FE3, 0x9694, 0x53C8, 0x9695, 0x62B9, + 0x9696, 0x672B, 0x9697, 0x6CAB, 0x9698, 0x8FC4, 0x9699, 0x4FAD, + 0x969A, 0x7E6D, 0x969B, 0x9EBF, 0x969C, 0x4E07, 0x969D, 0x6162, + 0x969E, 0x6E80, 0x969F, 0x6F2B, 0x96A0, 0x8513, 0x96A1, 0x5473, + 0x96A2, 0x672A, 0x96A3, 0x9B45, 0x96A4, 0x5DF3, 0x96A5, 0x7B95, + 0x96A6, 0x5CAC, 0x96A7, 0x5BC6, 0x96A8, 0x871C, 0x96A9, 0x6E4A, + 0x96AA, 0x84D1, 0x96AB, 0x7A14, 0x96AC, 0x8108, 0x96AD, 0x5999, + 0x96AE, 0x7C8D, 0x96AF, 0x6C11, 0x96B0, 0x7720, 0x96B1, 0x52D9, + 0x96B2, 0x5922, 0x96B3, 0x7121, 0x96B4, 0x725F, 0x96B5, 0x77DB, + 0x96B6, 0x9727, 0x96B7, 0x9D61, 0x96B8, 0x690B, 0x96B9, 0x5A7F, + 0x96BA, 0x5A18, 0x96BB, 0x51A5, 0x96BC, 0x540D, 0x96BD, 0x547D, + 0x96BE, 0x660E, 0x96BF, 0x76DF, 0x96C0, 0x8FF7, 0x96C1, 0x9298, + 0x96C2, 0x9CF4, 0x96C3, 0x59EA, 0x96C4, 0x725D, 0x96C5, 0x6EC5, + 0x96C6, 0x514D, 0x96C7, 0x68C9, 0x96C8, 0x7DBF, 0x96C9, 0x7DEC, + 0x96CA, 0x9762, 0x96CB, 0x9EBA, 0x96CC, 0x6478, 0x96CD, 0x6A21, + 0x96CE, 0x8302, 0x96CF, 0x5984, 0x96D0, 0x5B5F, 0x96D1, 0x6BDB, + 0x96D2, 0x731B, 0x96D3, 0x76F2, 0x96D4, 0x7DB2, 0x96D5, 0x8017, + 0x96D6, 0x8499, 0x96D7, 0x5132, 0x96D8, 0x6728, 0x96D9, 0x9ED9, + 0x96DA, 0x76EE, 0x96DB, 0x6762, 0x96DC, 0x52FF, 0x96DD, 0x9905, + 0x96DE, 0x5C24, 0x96DF, 0x623B, 0x96E0, 0x7C7E, 0x96E1, 0x8CB0, + 0x96E2, 0x554F, 0x96E3, 0x60B6, 0x96E4, 0x7D0B, 0x96E5, 0x9580, + 0x96E6, 0x5301, 0x96E7, 0x4E5F, 0x96E8, 0x51B6, 0x96E9, 0x591C, + 0x96EA, 0x723A, 0x96EB, 0x8036, 0x96EC, 0x91CE, 0x96ED, 0x5F25, + 0x96EE, 0x77E2, 0x96EF, 0x5384, 0x96F0, 0x5F79, 0x96F1, 0x7D04, + 0x96F2, 0x85AC, 0x96F3, 0x8A33, 0x96F4, 0x8E8D, 0x96F5, 0x9756, + 0x96F6, 0x67F3, 0x96F7, 0x85AE, 0x96F8, 0x9453, 0x96F9, 0x6109, + 0x96FA, 0x6108, 0x96FB, 0x6CB9, 0x96FC, 0x7652, 0x9740, 0x8AED, + 0x9741, 0x8F38, 0x9742, 0x552F, 0x9743, 0x4F51, 0x9744, 0x512A, + 0x9745, 0x52C7, 0x9746, 0x53CB, 0x9747, 0x5BA5, 0x9748, 0x5E7D, + 0x9749, 0x60A0, 0x974A, 0x6182, 0x974B, 0x63D6, 0x974C, 0x6709, + 0x974D, 0x67DA, 0x974E, 0x6E67, 0x974F, 0x6D8C, 0x9750, 0x7336, + 0x9751, 0x7337, 0x9752, 0x7531, 0x9753, 0x7950, 0x9754, 0x88D5, + 0x9755, 0x8A98, 0x9756, 0x904A, 0x9757, 0x9091, 0x9758, 0x90F5, + 0x9759, 0x96C4, 0x975A, 0x878D, 0x975B, 0x5915, 0x975C, 0x4E88, + 0x975D, 0x4F59, 0x975E, 0x4E0E, 0x975F, 0x8A89, 0x9760, 0x8F3F, + 0x9761, 0x9810, 0x9762, 0x50AD, 0x9763, 0x5E7C, 0x9764, 0x5996, + 0x9765, 0x5BB9, 0x9766, 0x5EB8, 0x9767, 0x63DA, 0x9768, 0x63FA, + 0x9769, 0x64C1, 0x976A, 0x66DC, 0x976B, 0x694A, 0x976C, 0x69D8, + 0x976D, 0x6D0B, 0x976E, 0x6EB6, 0x976F, 0x7194, 0x9770, 0x7528, + 0x9771, 0x7AAF, 0x9772, 0x7F8A, 0x9773, 0x8000, 0x9774, 0x8449, + 0x9775, 0x84C9, 0x9776, 0x8981, 0x9777, 0x8B21, 0x9778, 0x8E0A, + 0x9779, 0x9065, 0x977A, 0x967D, 0x977B, 0x990A, 0x977C, 0x617E, + 0x977D, 0x6291, 0x977E, 0x6B32, 0x9780, 0x6C83, 0x9781, 0x6D74, + 0x9782, 0x7FCC, 0x9783, 0x7FFC, 0x9784, 0x6DC0, 0x9785, 0x7F85, + 0x9786, 0x87BA, 0x9787, 0x88F8, 0x9788, 0x6765, 0x9789, 0x83B1, + 0x978A, 0x983C, 0x978B, 0x96F7, 0x978C, 0x6D1B, 0x978D, 0x7D61, + 0x978E, 0x843D, 0x978F, 0x916A, 0x9790, 0x4E71, 0x9791, 0x5375, + 0x9792, 0x5D50, 0x9793, 0x6B04, 0x9794, 0x6FEB, 0x9795, 0x85CD, + 0x9796, 0x862D, 0x9797, 0x89A7, 0x9798, 0x5229, 0x9799, 0x540F, + 0x979A, 0x5C65, 0x979B, 0x674E, 0x979C, 0x68A8, 0x979D, 0x7406, + 0x979E, 0x7483, 0x979F, 0x75E2, 0x97A0, 0x88CF, 0x97A1, 0x88E1, + 0x97A2, 0x91CC, 0x97A3, 0x96E2, 0x97A4, 0x9678, 0x97A5, 0x5F8B, + 0x97A6, 0x7387, 0x97A7, 0x7ACB, 0x97A8, 0x844E, 0x97A9, 0x63A0, + 0x97AA, 0x7565, 0x97AB, 0x5289, 0x97AC, 0x6D41, 0x97AD, 0x6E9C, + 0x97AE, 0x7409, 0x97AF, 0x7559, 0x97B0, 0x786B, 0x97B1, 0x7C92, + 0x97B2, 0x9686, 0x97B3, 0x7ADC, 0x97B4, 0x9F8D, 0x97B5, 0x4FB6, + 0x97B6, 0x616E, 0x97B7, 0x65C5, 0x97B8, 0x865C, 0x97B9, 0x4E86, + 0x97BA, 0x4EAE, 0x97BB, 0x50DA, 0x97BC, 0x4E21, 0x97BD, 0x51CC, + 0x97BE, 0x5BEE, 0x97BF, 0x6599, 0x97C0, 0x6881, 0x97C1, 0x6DBC, + 0x97C2, 0x731F, 0x97C3, 0x7642, 0x97C4, 0x77AD, 0x97C5, 0x7A1C, + 0x97C6, 0x7CE7, 0x97C7, 0x826F, 0x97C8, 0x8AD2, 0x97C9, 0x907C, + 0x97CA, 0x91CF, 0x97CB, 0x9675, 0x97CC, 0x9818, 0x97CD, 0x529B, + 0x97CE, 0x7DD1, 0x97CF, 0x502B, 0x97D0, 0x5398, 0x97D1, 0x6797, + 0x97D2, 0x6DCB, 0x97D3, 0x71D0, 0x97D4, 0x7433, 0x97D5, 0x81E8, + 0x97D6, 0x8F2A, 0x97D7, 0x96A3, 0x97D8, 0x9C57, 0x97D9, 0x9E9F, + 0x97DA, 0x7460, 0x97DB, 0x5841, 0x97DC, 0x6D99, 0x97DD, 0x7D2F, + 0x97DE, 0x985E, 0x97DF, 0x4EE4, 0x97E0, 0x4F36, 0x97E1, 0x4F8B, + 0x97E2, 0x51B7, 0x97E3, 0x52B1, 0x97E4, 0x5DBA, 0x97E5, 0x601C, + 0x97E6, 0x73B2, 0x97E7, 0x793C, 0x97E8, 0x82D3, 0x97E9, 0x9234, + 0x97EA, 0x96B7, 0x97EB, 0x96F6, 0x97EC, 0x970A, 0x97ED, 0x9E97, + 0x97EE, 0x9F62, 0x97EF, 0x66A6, 0x97F0, 0x6B74, 0x97F1, 0x5217, + 0x97F2, 0x52A3, 0x97F3, 0x70C8, 0x97F4, 0x88C2, 0x97F5, 0x5EC9, + 0x97F6, 0x604B, 0x97F7, 0x6190, 0x97F8, 0x6F23, 0x97F9, 0x7149, + 0x97FA, 0x7C3E, 0x97FB, 0x7DF4, 0x97FC, 0x806F, 0x9840, 0x84EE, + 0x9841, 0x9023, 0x9842, 0x932C, 0x9843, 0x5442, 0x9844, 0x9B6F, + 0x9845, 0x6AD3, 0x9846, 0x7089, 0x9847, 0x8CC2, 0x9848, 0x8DEF, + 0x9849, 0x9732, 0x984A, 0x52B4, 0x984B, 0x5A41, 0x984C, 0x5ECA, + 0x984D, 0x5F04, 0x984E, 0x6717, 0x984F, 0x697C, 0x9850, 0x6994, + 0x9851, 0x6D6A, 0x9852, 0x6F0F, 0x9853, 0x7262, 0x9854, 0x72FC, + 0x9855, 0x7BED, 0x9856, 0x8001, 0x9857, 0x807E, 0x9858, 0x874B, + 0x9859, 0x90CE, 0x985A, 0x516D, 0x985B, 0x9E93, 0x985C, 0x7984, + 0x985D, 0x808B, 0x985E, 0x9332, 0x985F, 0x8AD6, 0x9860, 0x502D, + 0x9861, 0x548C, 0x9862, 0x8A71, 0x9863, 0x6B6A, 0x9864, 0x8CC4, + 0x9865, 0x8107, 0x9866, 0x60D1, 0x9867, 0x67A0, 0x9868, 0x9DF2, + 0x9869, 0x4E99, 0x986A, 0x4E98, 0x986B, 0x9C10, 0x986C, 0x8A6B, + 0x986D, 0x85C1, 0x986E, 0x8568, 0x986F, 0x6900, 0x9870, 0x6E7E, + 0x9871, 0x7897, 0x9872, 0x8155, 0x989F, 0x5F0C, 0x98A0, 0x4E10, + 0x98A1, 0x4E15, 0x98A2, 0x4E2A, 0x98A3, 0x4E31, 0x98A4, 0x4E36, + 0x98A5, 0x4E3C, 0x98A6, 0x4E3F, 0x98A7, 0x4E42, 0x98A8, 0x4E56, + 0x98A9, 0x4E58, 0x98AA, 0x4E82, 0x98AB, 0x4E85, 0x98AC, 0x8C6B, + 0x98AD, 0x4E8A, 0x98AE, 0x8212, 0x98AF, 0x5F0D, 0x98B0, 0x4E8E, + 0x98B1, 0x4E9E, 0x98B2, 0x4E9F, 0x98B3, 0x4EA0, 0x98B4, 0x4EA2, + 0x98B5, 0x4EB0, 0x98B6, 0x4EB3, 0x98B7, 0x4EB6, 0x98B8, 0x4ECE, + 0x98B9, 0x4ECD, 0x98BA, 0x4EC4, 0x98BB, 0x4EC6, 0x98BC, 0x4EC2, + 0x98BD, 0x4ED7, 0x98BE, 0x4EDE, 0x98BF, 0x4EED, 0x98C0, 0x4EDF, + 0x98C1, 0x4EF7, 0x98C2, 0x4F09, 0x98C3, 0x4F5A, 0x98C4, 0x4F30, + 0x98C5, 0x4F5B, 0x98C6, 0x4F5D, 0x98C7, 0x4F57, 0x98C8, 0x4F47, + 0x98C9, 0x4F76, 0x98CA, 0x4F88, 0x98CB, 0x4F8F, 0x98CC, 0x4F98, + 0x98CD, 0x4F7B, 0x98CE, 0x4F69, 0x98CF, 0x4F70, 0x98D0, 0x4F91, + 0x98D1, 0x4F6F, 0x98D2, 0x4F86, 0x98D3, 0x4F96, 0x98D4, 0x5118, + 0x98D5, 0x4FD4, 0x98D6, 0x4FDF, 0x98D7, 0x4FCE, 0x98D8, 0x4FD8, + 0x98D9, 0x4FDB, 0x98DA, 0x4FD1, 0x98DB, 0x4FDA, 0x98DC, 0x4FD0, + 0x98DD, 0x4FE4, 0x98DE, 0x4FE5, 0x98DF, 0x501A, 0x98E0, 0x5028, + 0x98E1, 0x5014, 0x98E2, 0x502A, 0x98E3, 0x5025, 0x98E4, 0x5005, + 0x98E5, 0x4F1C, 0x98E6, 0x4FF6, 0x98E7, 0x5021, 0x98E8, 0x5029, + 0x98E9, 0x502C, 0x98EA, 0x4FFE, 0x98EB, 0x4FEF, 0x98EC, 0x5011, + 0x98ED, 0x5006, 0x98EE, 0x5043, 0x98EF, 0x5047, 0x98F0, 0x6703, + 0x98F1, 0x5055, 0x98F2, 0x5050, 0x98F3, 0x5048, 0x98F4, 0x505A, + 0x98F5, 0x5056, 0x98F6, 0x506C, 0x98F7, 0x5078, 0x98F8, 0x5080, + 0x98F9, 0x509A, 0x98FA, 0x5085, 0x98FB, 0x50B4, 0x98FC, 0x50B2, + 0x9940, 0x50C9, 0x9941, 0x50CA, 0x9942, 0x50B3, 0x9943, 0x50C2, + 0x9944, 0x50D6, 0x9945, 0x50DE, 0x9946, 0x50E5, 0x9947, 0x50ED, + 0x9948, 0x50E3, 0x9949, 0x50EE, 0x994A, 0x50F9, 0x994B, 0x50F5, + 0x994C, 0x5109, 0x994D, 0x5101, 0x994E, 0x5102, 0x994F, 0x5116, + 0x9950, 0x5115, 0x9951, 0x5114, 0x9952, 0x511A, 0x9953, 0x5121, + 0x9954, 0x513A, 0x9955, 0x5137, 0x9956, 0x513C, 0x9957, 0x513B, + 0x9958, 0x513F, 0x9959, 0x5140, 0x995A, 0x5152, 0x995B, 0x514C, + 0x995C, 0x5154, 0x995D, 0x5162, 0x995E, 0x7AF8, 0x995F, 0x5169, + 0x9960, 0x516A, 0x9961, 0x516E, 0x9962, 0x5180, 0x9963, 0x5182, + 0x9964, 0x56D8, 0x9965, 0x518C, 0x9966, 0x5189, 0x9967, 0x518F, + 0x9968, 0x5191, 0x9969, 0x5193, 0x996A, 0x5195, 0x996B, 0x5196, + 0x996C, 0x51A4, 0x996D, 0x51A6, 0x996E, 0x51A2, 0x996F, 0x51A9, + 0x9970, 0x51AA, 0x9971, 0x51AB, 0x9972, 0x51B3, 0x9973, 0x51B1, + 0x9974, 0x51B2, 0x9975, 0x51B0, 0x9976, 0x51B5, 0x9977, 0x51BD, + 0x9978, 0x51C5, 0x9979, 0x51C9, 0x997A, 0x51DB, 0x997B, 0x51E0, + 0x997C, 0x8655, 0x997D, 0x51E9, 0x997E, 0x51ED, 0x9980, 0x51F0, + 0x9981, 0x51F5, 0x9982, 0x51FE, 0x9983, 0x5204, 0x9984, 0x520B, + 0x9985, 0x5214, 0x9986, 0x520E, 0x9987, 0x5227, 0x9988, 0x522A, + 0x9989, 0x522E, 0x998A, 0x5233, 0x998B, 0x5239, 0x998C, 0x524F, + 0x998D, 0x5244, 0x998E, 0x524B, 0x998F, 0x524C, 0x9990, 0x525E, + 0x9991, 0x5254, 0x9992, 0x526A, 0x9993, 0x5274, 0x9994, 0x5269, + 0x9995, 0x5273, 0x9996, 0x527F, 0x9997, 0x527D, 0x9998, 0x528D, + 0x9999, 0x5294, 0x999A, 0x5292, 0x999B, 0x5271, 0x999C, 0x5288, + 0x999D, 0x5291, 0x999E, 0x8FA8, 0x999F, 0x8FA7, 0x99A0, 0x52AC, + 0x99A1, 0x52AD, 0x99A2, 0x52BC, 0x99A3, 0x52B5, 0x99A4, 0x52C1, + 0x99A5, 0x52CD, 0x99A6, 0x52D7, 0x99A7, 0x52DE, 0x99A8, 0x52E3, + 0x99A9, 0x52E6, 0x99AA, 0x98ED, 0x99AB, 0x52E0, 0x99AC, 0x52F3, + 0x99AD, 0x52F5, 0x99AE, 0x52F8, 0x99AF, 0x52F9, 0x99B0, 0x5306, + 0x99B1, 0x5308, 0x99B2, 0x7538, 0x99B3, 0x530D, 0x99B4, 0x5310, + 0x99B5, 0x530F, 0x99B6, 0x5315, 0x99B7, 0x531A, 0x99B8, 0x5323, + 0x99B9, 0x532F, 0x99BA, 0x5331, 0x99BB, 0x5333, 0x99BC, 0x5338, + 0x99BD, 0x5340, 0x99BE, 0x5346, 0x99BF, 0x5345, 0x99C0, 0x4E17, + 0x99C1, 0x5349, 0x99C2, 0x534D, 0x99C3, 0x51D6, 0x99C4, 0x535E, + 0x99C5, 0x5369, 0x99C6, 0x536E, 0x99C7, 0x5918, 0x99C8, 0x537B, + 0x99C9, 0x5377, 0x99CA, 0x5382, 0x99CB, 0x5396, 0x99CC, 0x53A0, + 0x99CD, 0x53A6, 0x99CE, 0x53A5, 0x99CF, 0x53AE, 0x99D0, 0x53B0, + 0x99D1, 0x53B6, 0x99D2, 0x53C3, 0x99D3, 0x7C12, 0x99D4, 0x96D9, + 0x99D5, 0x53DF, 0x99D6, 0x66FC, 0x99D7, 0x71EE, 0x99D8, 0x53EE, + 0x99D9, 0x53E8, 0x99DA, 0x53ED, 0x99DB, 0x53FA, 0x99DC, 0x5401, + 0x99DD, 0x543D, 0x99DE, 0x5440, 0x99DF, 0x542C, 0x99E0, 0x542D, + 0x99E1, 0x543C, 0x99E2, 0x542E, 0x99E3, 0x5436, 0x99E4, 0x5429, + 0x99E5, 0x541D, 0x99E6, 0x544E, 0x99E7, 0x548F, 0x99E8, 0x5475, + 0x99E9, 0x548E, 0x99EA, 0x545F, 0x99EB, 0x5471, 0x99EC, 0x5477, + 0x99ED, 0x5470, 0x99EE, 0x5492, 0x99EF, 0x547B, 0x99F0, 0x5480, + 0x99F1, 0x5476, 0x99F2, 0x5484, 0x99F3, 0x5490, 0x99F4, 0x5486, + 0x99F5, 0x54C7, 0x99F6, 0x54A2, 0x99F7, 0x54B8, 0x99F8, 0x54A5, + 0x99F9, 0x54AC, 0x99FA, 0x54C4, 0x99FB, 0x54C8, 0x99FC, 0x54A8, + 0x9A40, 0x54AB, 0x9A41, 0x54C2, 0x9A42, 0x54A4, 0x9A43, 0x54BE, + 0x9A44, 0x54BC, 0x9A45, 0x54D8, 0x9A46, 0x54E5, 0x9A47, 0x54E6, + 0x9A48, 0x550F, 0x9A49, 0x5514, 0x9A4A, 0x54FD, 0x9A4B, 0x54EE, + 0x9A4C, 0x54ED, 0x9A4D, 0x54FA, 0x9A4E, 0x54E2, 0x9A4F, 0x5539, + 0x9A50, 0x5540, 0x9A51, 0x5563, 0x9A52, 0x554C, 0x9A53, 0x552E, + 0x9A54, 0x555C, 0x9A55, 0x5545, 0x9A56, 0x5556, 0x9A57, 0x5557, + 0x9A58, 0x5538, 0x9A59, 0x5533, 0x9A5A, 0x555D, 0x9A5B, 0x5599, + 0x9A5C, 0x5580, 0x9A5D, 0x54AF, 0x9A5E, 0x558A, 0x9A5F, 0x559F, + 0x9A60, 0x557B, 0x9A61, 0x557E, 0x9A62, 0x5598, 0x9A63, 0x559E, + 0x9A64, 0x55AE, 0x9A65, 0x557C, 0x9A66, 0x5583, 0x9A67, 0x55A9, + 0x9A68, 0x5587, 0x9A69, 0x55A8, 0x9A6A, 0x55DA, 0x9A6B, 0x55C5, + 0x9A6C, 0x55DF, 0x9A6D, 0x55C4, 0x9A6E, 0x55DC, 0x9A6F, 0x55E4, + 0x9A70, 0x55D4, 0x9A71, 0x5614, 0x9A72, 0x55F7, 0x9A73, 0x5616, + 0x9A74, 0x55FE, 0x9A75, 0x55FD, 0x9A76, 0x561B, 0x9A77, 0x55F9, + 0x9A78, 0x564E, 0x9A79, 0x5650, 0x9A7A, 0x71DF, 0x9A7B, 0x5634, + 0x9A7C, 0x5636, 0x9A7D, 0x5632, 0x9A7E, 0x5638, 0x9A80, 0x566B, + 0x9A81, 0x5664, 0x9A82, 0x562F, 0x9A83, 0x566C, 0x9A84, 0x566A, + 0x9A85, 0x5686, 0x9A86, 0x5680, 0x9A87, 0x568A, 0x9A88, 0x56A0, + 0x9A89, 0x5694, 0x9A8A, 0x568F, 0x9A8B, 0x56A5, 0x9A8C, 0x56AE, + 0x9A8D, 0x56B6, 0x9A8E, 0x56B4, 0x9A8F, 0x56C2, 0x9A90, 0x56BC, + 0x9A91, 0x56C1, 0x9A92, 0x56C3, 0x9A93, 0x56C0, 0x9A94, 0x56C8, + 0x9A95, 0x56CE, 0x9A96, 0x56D1, 0x9A97, 0x56D3, 0x9A98, 0x56D7, + 0x9A99, 0x56EE, 0x9A9A, 0x56F9, 0x9A9B, 0x5700, 0x9A9C, 0x56FF, + 0x9A9D, 0x5704, 0x9A9E, 0x5709, 0x9A9F, 0x5708, 0x9AA0, 0x570B, + 0x9AA1, 0x570D, 0x9AA2, 0x5713, 0x9AA3, 0x5718, 0x9AA4, 0x5716, + 0x9AA5, 0x55C7, 0x9AA6, 0x571C, 0x9AA7, 0x5726, 0x9AA8, 0x5737, + 0x9AA9, 0x5738, 0x9AAA, 0x574E, 0x9AAB, 0x573B, 0x9AAC, 0x5740, + 0x9AAD, 0x574F, 0x9AAE, 0x5769, 0x9AAF, 0x57C0, 0x9AB0, 0x5788, + 0x9AB1, 0x5761, 0x9AB2, 0x577F, 0x9AB3, 0x5789, 0x9AB4, 0x5793, + 0x9AB5, 0x57A0, 0x9AB6, 0x57B3, 0x9AB7, 0x57A4, 0x9AB8, 0x57AA, + 0x9AB9, 0x57B0, 0x9ABA, 0x57C3, 0x9ABB, 0x57C6, 0x9ABC, 0x57D4, + 0x9ABD, 0x57D2, 0x9ABE, 0x57D3, 0x9ABF, 0x580A, 0x9AC0, 0x57D6, + 0x9AC1, 0x57E3, 0x9AC2, 0x580B, 0x9AC3, 0x5819, 0x9AC4, 0x581D, + 0x9AC5, 0x5872, 0x9AC6, 0x5821, 0x9AC7, 0x5862, 0x9AC8, 0x584B, + 0x9AC9, 0x5870, 0x9ACA, 0x6BC0, 0x9ACB, 0x5852, 0x9ACC, 0x583D, + 0x9ACD, 0x5879, 0x9ACE, 0x5885, 0x9ACF, 0x58B9, 0x9AD0, 0x589F, + 0x9AD1, 0x58AB, 0x9AD2, 0x58BA, 0x9AD3, 0x58DE, 0x9AD4, 0x58BB, + 0x9AD5, 0x58B8, 0x9AD6, 0x58AE, 0x9AD7, 0x58C5, 0x9AD8, 0x58D3, + 0x9AD9, 0x58D1, 0x9ADA, 0x58D7, 0x9ADB, 0x58D9, 0x9ADC, 0x58D8, + 0x9ADD, 0x58E5, 0x9ADE, 0x58DC, 0x9ADF, 0x58E4, 0x9AE0, 0x58DF, + 0x9AE1, 0x58EF, 0x9AE2, 0x58FA, 0x9AE3, 0x58F9, 0x9AE4, 0x58FB, + 0x9AE5, 0x58FC, 0x9AE6, 0x58FD, 0x9AE7, 0x5902, 0x9AE8, 0x590A, + 0x9AE9, 0x5910, 0x9AEA, 0x591B, 0x9AEB, 0x68A6, 0x9AEC, 0x5925, + 0x9AED, 0x592C, 0x9AEE, 0x592D, 0x9AEF, 0x5932, 0x9AF0, 0x5938, + 0x9AF1, 0x593E, 0x9AF2, 0x7AD2, 0x9AF3, 0x5955, 0x9AF4, 0x5950, + 0x9AF5, 0x594E, 0x9AF6, 0x595A, 0x9AF7, 0x5958, 0x9AF8, 0x5962, + 0x9AF9, 0x5960, 0x9AFA, 0x5967, 0x9AFB, 0x596C, 0x9AFC, 0x5969, + 0x9B40, 0x5978, 0x9B41, 0x5981, 0x9B42, 0x599D, 0x9B43, 0x4F5E, + 0x9B44, 0x4FAB, 0x9B45, 0x59A3, 0x9B46, 0x59B2, 0x9B47, 0x59C6, + 0x9B48, 0x59E8, 0x9B49, 0x59DC, 0x9B4A, 0x598D, 0x9B4B, 0x59D9, + 0x9B4C, 0x59DA, 0x9B4D, 0x5A25, 0x9B4E, 0x5A1F, 0x9B4F, 0x5A11, + 0x9B50, 0x5A1C, 0x9B51, 0x5A09, 0x9B52, 0x5A1A, 0x9B53, 0x5A40, + 0x9B54, 0x5A6C, 0x9B55, 0x5A49, 0x9B56, 0x5A35, 0x9B57, 0x5A36, + 0x9B58, 0x5A62, 0x9B59, 0x5A6A, 0x9B5A, 0x5A9A, 0x9B5B, 0x5ABC, + 0x9B5C, 0x5ABE, 0x9B5D, 0x5ACB, 0x9B5E, 0x5AC2, 0x9B5F, 0x5ABD, + 0x9B60, 0x5AE3, 0x9B61, 0x5AD7, 0x9B62, 0x5AE6, 0x9B63, 0x5AE9, + 0x9B64, 0x5AD6, 0x9B65, 0x5AFA, 0x9B66, 0x5AFB, 0x9B67, 0x5B0C, + 0x9B68, 0x5B0B, 0x9B69, 0x5B16, 0x9B6A, 0x5B32, 0x9B6B, 0x5AD0, + 0x9B6C, 0x5B2A, 0x9B6D, 0x5B36, 0x9B6E, 0x5B3E, 0x9B6F, 0x5B43, + 0x9B70, 0x5B45, 0x9B71, 0x5B40, 0x9B72, 0x5B51, 0x9B73, 0x5B55, + 0x9B74, 0x5B5A, 0x9B75, 0x5B5B, 0x9B76, 0x5B65, 0x9B77, 0x5B69, + 0x9B78, 0x5B70, 0x9B79, 0x5B73, 0x9B7A, 0x5B75, 0x9B7B, 0x5B78, + 0x9B7C, 0x6588, 0x9B7D, 0x5B7A, 0x9B7E, 0x5B80, 0x9B80, 0x5B83, + 0x9B81, 0x5BA6, 0x9B82, 0x5BB8, 0x9B83, 0x5BC3, 0x9B84, 0x5BC7, + 0x9B85, 0x5BC9, 0x9B86, 0x5BD4, 0x9B87, 0x5BD0, 0x9B88, 0x5BE4, + 0x9B89, 0x5BE6, 0x9B8A, 0x5BE2, 0x9B8B, 0x5BDE, 0x9B8C, 0x5BE5, + 0x9B8D, 0x5BEB, 0x9B8E, 0x5BF0, 0x9B8F, 0x5BF6, 0x9B90, 0x5BF3, + 0x9B91, 0x5C05, 0x9B92, 0x5C07, 0x9B93, 0x5C08, 0x9B94, 0x5C0D, + 0x9B95, 0x5C13, 0x9B96, 0x5C20, 0x9B97, 0x5C22, 0x9B98, 0x5C28, + 0x9B99, 0x5C38, 0x9B9A, 0x5C39, 0x9B9B, 0x5C41, 0x9B9C, 0x5C46, + 0x9B9D, 0x5C4E, 0x9B9E, 0x5C53, 0x9B9F, 0x5C50, 0x9BA0, 0x5C4F, + 0x9BA1, 0x5B71, 0x9BA2, 0x5C6C, 0x9BA3, 0x5C6E, 0x9BA4, 0x4E62, + 0x9BA5, 0x5C76, 0x9BA6, 0x5C79, 0x9BA7, 0x5C8C, 0x9BA8, 0x5C91, + 0x9BA9, 0x5C94, 0x9BAA, 0x599B, 0x9BAB, 0x5CAB, 0x9BAC, 0x5CBB, + 0x9BAD, 0x5CB6, 0x9BAE, 0x5CBC, 0x9BAF, 0x5CB7, 0x9BB0, 0x5CC5, + 0x9BB1, 0x5CBE, 0x9BB2, 0x5CC7, 0x9BB3, 0x5CD9, 0x9BB4, 0x5CE9, + 0x9BB5, 0x5CFD, 0x9BB6, 0x5CFA, 0x9BB7, 0x5CED, 0x9BB8, 0x5D8C, + 0x9BB9, 0x5CEA, 0x9BBA, 0x5D0B, 0x9BBB, 0x5D15, 0x9BBC, 0x5D17, + 0x9BBD, 0x5D5C, 0x9BBE, 0x5D1F, 0x9BBF, 0x5D1B, 0x9BC0, 0x5D11, + 0x9BC1, 0x5D14, 0x9BC2, 0x5D22, 0x9BC3, 0x5D1A, 0x9BC4, 0x5D19, + 0x9BC5, 0x5D18, 0x9BC6, 0x5D4C, 0x9BC7, 0x5D52, 0x9BC8, 0x5D4E, + 0x9BC9, 0x5D4B, 0x9BCA, 0x5D6C, 0x9BCB, 0x5D73, 0x9BCC, 0x5D76, + 0x9BCD, 0x5D87, 0x9BCE, 0x5D84, 0x9BCF, 0x5D82, 0x9BD0, 0x5DA2, + 0x9BD1, 0x5D9D, 0x9BD2, 0x5DAC, 0x9BD3, 0x5DAE, 0x9BD4, 0x5DBD, + 0x9BD5, 0x5D90, 0x9BD6, 0x5DB7, 0x9BD7, 0x5DBC, 0x9BD8, 0x5DC9, + 0x9BD9, 0x5DCD, 0x9BDA, 0x5DD3, 0x9BDB, 0x5DD2, 0x9BDC, 0x5DD6, + 0x9BDD, 0x5DDB, 0x9BDE, 0x5DEB, 0x9BDF, 0x5DF2, 0x9BE0, 0x5DF5, + 0x9BE1, 0x5E0B, 0x9BE2, 0x5E1A, 0x9BE3, 0x5E19, 0x9BE4, 0x5E11, + 0x9BE5, 0x5E1B, 0x9BE6, 0x5E36, 0x9BE7, 0x5E37, 0x9BE8, 0x5E44, + 0x9BE9, 0x5E43, 0x9BEA, 0x5E40, 0x9BEB, 0x5E4E, 0x9BEC, 0x5E57, + 0x9BED, 0x5E54, 0x9BEE, 0x5E5F, 0x9BEF, 0x5E62, 0x9BF0, 0x5E64, + 0x9BF1, 0x5E47, 0x9BF2, 0x5E75, 0x9BF3, 0x5E76, 0x9BF4, 0x5E7A, + 0x9BF5, 0x9EBC, 0x9BF6, 0x5E7F, 0x9BF7, 0x5EA0, 0x9BF8, 0x5EC1, + 0x9BF9, 0x5EC2, 0x9BFA, 0x5EC8, 0x9BFB, 0x5ED0, 0x9BFC, 0x5ECF, + 0x9C40, 0x5ED6, 0x9C41, 0x5EE3, 0x9C42, 0x5EDD, 0x9C43, 0x5EDA, + 0x9C44, 0x5EDB, 0x9C45, 0x5EE2, 0x9C46, 0x5EE1, 0x9C47, 0x5EE8, + 0x9C48, 0x5EE9, 0x9C49, 0x5EEC, 0x9C4A, 0x5EF1, 0x9C4B, 0x5EF3, + 0x9C4C, 0x5EF0, 0x9C4D, 0x5EF4, 0x9C4E, 0x5EF8, 0x9C4F, 0x5EFE, + 0x9C50, 0x5F03, 0x9C51, 0x5F09, 0x9C52, 0x5F5D, 0x9C53, 0x5F5C, + 0x9C54, 0x5F0B, 0x9C55, 0x5F11, 0x9C56, 0x5F16, 0x9C57, 0x5F29, + 0x9C58, 0x5F2D, 0x9C59, 0x5F38, 0x9C5A, 0x5F41, 0x9C5B, 0x5F48, + 0x9C5C, 0x5F4C, 0x9C5D, 0x5F4E, 0x9C5E, 0x5F2F, 0x9C5F, 0x5F51, + 0x9C60, 0x5F56, 0x9C61, 0x5F57, 0x9C62, 0x5F59, 0x9C63, 0x5F61, + 0x9C64, 0x5F6D, 0x9C65, 0x5F73, 0x9C66, 0x5F77, 0x9C67, 0x5F83, + 0x9C68, 0x5F82, 0x9C69, 0x5F7F, 0x9C6A, 0x5F8A, 0x9C6B, 0x5F88, + 0x9C6C, 0x5F91, 0x9C6D, 0x5F87, 0x9C6E, 0x5F9E, 0x9C6F, 0x5F99, + 0x9C70, 0x5F98, 0x9C71, 0x5FA0, 0x9C72, 0x5FA8, 0x9C73, 0x5FAD, + 0x9C74, 0x5FBC, 0x9C75, 0x5FD6, 0x9C76, 0x5FFB, 0x9C77, 0x5FE4, + 0x9C78, 0x5FF8, 0x9C79, 0x5FF1, 0x9C7A, 0x5FDD, 0x9C7B, 0x60B3, + 0x9C7C, 0x5FFF, 0x9C7D, 0x6021, 0x9C7E, 0x6060, 0x9C80, 0x6019, + 0x9C81, 0x6010, 0x9C82, 0x6029, 0x9C83, 0x600E, 0x9C84, 0x6031, + 0x9C85, 0x601B, 0x9C86, 0x6015, 0x9C87, 0x602B, 0x9C88, 0x6026, + 0x9C89, 0x600F, 0x9C8A, 0x603A, 0x9C8B, 0x605A, 0x9C8C, 0x6041, + 0x9C8D, 0x606A, 0x9C8E, 0x6077, 0x9C8F, 0x605F, 0x9C90, 0x604A, + 0x9C91, 0x6046, 0x9C92, 0x604D, 0x9C93, 0x6063, 0x9C94, 0x6043, + 0x9C95, 0x6064, 0x9C96, 0x6042, 0x9C97, 0x606C, 0x9C98, 0x606B, + 0x9C99, 0x6059, 0x9C9A, 0x6081, 0x9C9B, 0x608D, 0x9C9C, 0x60E7, + 0x9C9D, 0x6083, 0x9C9E, 0x609A, 0x9C9F, 0x6084, 0x9CA0, 0x609B, + 0x9CA1, 0x6096, 0x9CA2, 0x6097, 0x9CA3, 0x6092, 0x9CA4, 0x60A7, + 0x9CA5, 0x608B, 0x9CA6, 0x60E1, 0x9CA7, 0x60B8, 0x9CA8, 0x60E0, + 0x9CA9, 0x60D3, 0x9CAA, 0x60B4, 0x9CAB, 0x5FF0, 0x9CAC, 0x60BD, + 0x9CAD, 0x60C6, 0x9CAE, 0x60B5, 0x9CAF, 0x60D8, 0x9CB0, 0x614D, + 0x9CB1, 0x6115, 0x9CB2, 0x6106, 0x9CB3, 0x60F6, 0x9CB4, 0x60F7, + 0x9CB5, 0x6100, 0x9CB6, 0x60F4, 0x9CB7, 0x60FA, 0x9CB8, 0x6103, + 0x9CB9, 0x6121, 0x9CBA, 0x60FB, 0x9CBB, 0x60F1, 0x9CBC, 0x610D, + 0x9CBD, 0x610E, 0x9CBE, 0x6147, 0x9CBF, 0x613E, 0x9CC0, 0x6128, + 0x9CC1, 0x6127, 0x9CC2, 0x614A, 0x9CC3, 0x613F, 0x9CC4, 0x613C, + 0x9CC5, 0x612C, 0x9CC6, 0x6134, 0x9CC7, 0x613D, 0x9CC8, 0x6142, + 0x9CC9, 0x6144, 0x9CCA, 0x6173, 0x9CCB, 0x6177, 0x9CCC, 0x6158, + 0x9CCD, 0x6159, 0x9CCE, 0x615A, 0x9CCF, 0x616B, 0x9CD0, 0x6174, + 0x9CD1, 0x616F, 0x9CD2, 0x6165, 0x9CD3, 0x6171, 0x9CD4, 0x615F, + 0x9CD5, 0x615D, 0x9CD6, 0x6153, 0x9CD7, 0x6175, 0x9CD8, 0x6199, + 0x9CD9, 0x6196, 0x9CDA, 0x6187, 0x9CDB, 0x61AC, 0x9CDC, 0x6194, + 0x9CDD, 0x619A, 0x9CDE, 0x618A, 0x9CDF, 0x6191, 0x9CE0, 0x61AB, + 0x9CE1, 0x61AE, 0x9CE2, 0x61CC, 0x9CE3, 0x61CA, 0x9CE4, 0x61C9, + 0x9CE5, 0x61F7, 0x9CE6, 0x61C8, 0x9CE7, 0x61C3, 0x9CE8, 0x61C6, + 0x9CE9, 0x61BA, 0x9CEA, 0x61CB, 0x9CEB, 0x7F79, 0x9CEC, 0x61CD, + 0x9CED, 0x61E6, 0x9CEE, 0x61E3, 0x9CEF, 0x61F6, 0x9CF0, 0x61FA, + 0x9CF1, 0x61F4, 0x9CF2, 0x61FF, 0x9CF3, 0x61FD, 0x9CF4, 0x61FC, + 0x9CF5, 0x61FE, 0x9CF6, 0x6200, 0x9CF7, 0x6208, 0x9CF8, 0x6209, + 0x9CF9, 0x620D, 0x9CFA, 0x620C, 0x9CFB, 0x6214, 0x9CFC, 0x621B, + 0x9D40, 0x621E, 0x9D41, 0x6221, 0x9D42, 0x622A, 0x9D43, 0x622E, + 0x9D44, 0x6230, 0x9D45, 0x6232, 0x9D46, 0x6233, 0x9D47, 0x6241, + 0x9D48, 0x624E, 0x9D49, 0x625E, 0x9D4A, 0x6263, 0x9D4B, 0x625B, + 0x9D4C, 0x6260, 0x9D4D, 0x6268, 0x9D4E, 0x627C, 0x9D4F, 0x6282, + 0x9D50, 0x6289, 0x9D51, 0x627E, 0x9D52, 0x6292, 0x9D53, 0x6293, + 0x9D54, 0x6296, 0x9D55, 0x62D4, 0x9D56, 0x6283, 0x9D57, 0x6294, + 0x9D58, 0x62D7, 0x9D59, 0x62D1, 0x9D5A, 0x62BB, 0x9D5B, 0x62CF, + 0x9D5C, 0x62FF, 0x9D5D, 0x62C6, 0x9D5E, 0x64D4, 0x9D5F, 0x62C8, + 0x9D60, 0x62DC, 0x9D61, 0x62CC, 0x9D62, 0x62CA, 0x9D63, 0x62C2, + 0x9D64, 0x62C7, 0x9D65, 0x629B, 0x9D66, 0x62C9, 0x9D67, 0x630C, + 0x9D68, 0x62EE, 0x9D69, 0x62F1, 0x9D6A, 0x6327, 0x9D6B, 0x6302, + 0x9D6C, 0x6308, 0x9D6D, 0x62EF, 0x9D6E, 0x62F5, 0x9D6F, 0x6350, + 0x9D70, 0x633E, 0x9D71, 0x634D, 0x9D72, 0x641C, 0x9D73, 0x634F, + 0x9D74, 0x6396, 0x9D75, 0x638E, 0x9D76, 0x6380, 0x9D77, 0x63AB, + 0x9D78, 0x6376, 0x9D79, 0x63A3, 0x9D7A, 0x638F, 0x9D7B, 0x6389, + 0x9D7C, 0x639F, 0x9D7D, 0x63B5, 0x9D7E, 0x636B, 0x9D80, 0x6369, + 0x9D81, 0x63BE, 0x9D82, 0x63E9, 0x9D83, 0x63C0, 0x9D84, 0x63C6, + 0x9D85, 0x63E3, 0x9D86, 0x63C9, 0x9D87, 0x63D2, 0x9D88, 0x63F6, + 0x9D89, 0x63C4, 0x9D8A, 0x6416, 0x9D8B, 0x6434, 0x9D8C, 0x6406, + 0x9D8D, 0x6413, 0x9D8E, 0x6426, 0x9D8F, 0x6436, 0x9D90, 0x651D, + 0x9D91, 0x6417, 0x9D92, 0x6428, 0x9D93, 0x640F, 0x9D94, 0x6467, + 0x9D95, 0x646F, 0x9D96, 0x6476, 0x9D97, 0x644E, 0x9D98, 0x652A, + 0x9D99, 0x6495, 0x9D9A, 0x6493, 0x9D9B, 0x64A5, 0x9D9C, 0x64A9, + 0x9D9D, 0x6488, 0x9D9E, 0x64BC, 0x9D9F, 0x64DA, 0x9DA0, 0x64D2, + 0x9DA1, 0x64C5, 0x9DA2, 0x64C7, 0x9DA3, 0x64BB, 0x9DA4, 0x64D8, + 0x9DA5, 0x64C2, 0x9DA6, 0x64F1, 0x9DA7, 0x64E7, 0x9DA8, 0x8209, + 0x9DA9, 0x64E0, 0x9DAA, 0x64E1, 0x9DAB, 0x62AC, 0x9DAC, 0x64E3, + 0x9DAD, 0x64EF, 0x9DAE, 0x652C, 0x9DAF, 0x64F6, 0x9DB0, 0x64F4, + 0x9DB1, 0x64F2, 0x9DB2, 0x64FA, 0x9DB3, 0x6500, 0x9DB4, 0x64FD, + 0x9DB5, 0x6518, 0x9DB6, 0x651C, 0x9DB7, 0x6505, 0x9DB8, 0x6524, + 0x9DB9, 0x6523, 0x9DBA, 0x652B, 0x9DBB, 0x6534, 0x9DBC, 0x6535, + 0x9DBD, 0x6537, 0x9DBE, 0x6536, 0x9DBF, 0x6538, 0x9DC0, 0x754B, + 0x9DC1, 0x6548, 0x9DC2, 0x6556, 0x9DC3, 0x6555, 0x9DC4, 0x654D, + 0x9DC5, 0x6558, 0x9DC6, 0x655E, 0x9DC7, 0x655D, 0x9DC8, 0x6572, + 0x9DC9, 0x6578, 0x9DCA, 0x6582, 0x9DCB, 0x6583, 0x9DCC, 0x8B8A, + 0x9DCD, 0x659B, 0x9DCE, 0x659F, 0x9DCF, 0x65AB, 0x9DD0, 0x65B7, + 0x9DD1, 0x65C3, 0x9DD2, 0x65C6, 0x9DD3, 0x65C1, 0x9DD4, 0x65C4, + 0x9DD5, 0x65CC, 0x9DD6, 0x65D2, 0x9DD7, 0x65DB, 0x9DD8, 0x65D9, + 0x9DD9, 0x65E0, 0x9DDA, 0x65E1, 0x9DDB, 0x65F1, 0x9DDC, 0x6772, + 0x9DDD, 0x660A, 0x9DDE, 0x6603, 0x9DDF, 0x65FB, 0x9DE0, 0x6773, + 0x9DE1, 0x6635, 0x9DE2, 0x6636, 0x9DE3, 0x6634, 0x9DE4, 0x661C, + 0x9DE5, 0x664F, 0x9DE6, 0x6644, 0x9DE7, 0x6649, 0x9DE8, 0x6641, + 0x9DE9, 0x665E, 0x9DEA, 0x665D, 0x9DEB, 0x6664, 0x9DEC, 0x6667, + 0x9DED, 0x6668, 0x9DEE, 0x665F, 0x9DEF, 0x6662, 0x9DF0, 0x6670, + 0x9DF1, 0x6683, 0x9DF2, 0x6688, 0x9DF3, 0x668E, 0x9DF4, 0x6689, + 0x9DF5, 0x6684, 0x9DF6, 0x6698, 0x9DF7, 0x669D, 0x9DF8, 0x66C1, + 0x9DF9, 0x66B9, 0x9DFA, 0x66C9, 0x9DFB, 0x66BE, 0x9DFC, 0x66BC, + 0x9E40, 0x66C4, 0x9E41, 0x66B8, 0x9E42, 0x66D6, 0x9E43, 0x66DA, + 0x9E44, 0x66E0, 0x9E45, 0x663F, 0x9E46, 0x66E6, 0x9E47, 0x66E9, + 0x9E48, 0x66F0, 0x9E49, 0x66F5, 0x9E4A, 0x66F7, 0x9E4B, 0x670F, + 0x9E4C, 0x6716, 0x9E4D, 0x671E, 0x9E4E, 0x6726, 0x9E4F, 0x6727, + 0x9E50, 0x9738, 0x9E51, 0x672E, 0x9E52, 0x673F, 0x9E53, 0x6736, + 0x9E54, 0x6741, 0x9E55, 0x6738, 0x9E56, 0x6737, 0x9E57, 0x6746, + 0x9E58, 0x675E, 0x9E59, 0x6760, 0x9E5A, 0x6759, 0x9E5B, 0x6763, + 0x9E5C, 0x6764, 0x9E5D, 0x6789, 0x9E5E, 0x6770, 0x9E5F, 0x67A9, + 0x9E60, 0x677C, 0x9E61, 0x676A, 0x9E62, 0x678C, 0x9E63, 0x678B, + 0x9E64, 0x67A6, 0x9E65, 0x67A1, 0x9E66, 0x6785, 0x9E67, 0x67B7, + 0x9E68, 0x67EF, 0x9E69, 0x67B4, 0x9E6A, 0x67EC, 0x9E6B, 0x67B3, + 0x9E6C, 0x67E9, 0x9E6D, 0x67B8, 0x9E6E, 0x67E4, 0x9E6F, 0x67DE, + 0x9E70, 0x67DD, 0x9E71, 0x67E2, 0x9E72, 0x67EE, 0x9E73, 0x67B9, + 0x9E74, 0x67CE, 0x9E75, 0x67C6, 0x9E76, 0x67E7, 0x9E77, 0x6A9C, + 0x9E78, 0x681E, 0x9E79, 0x6846, 0x9E7A, 0x6829, 0x9E7B, 0x6840, + 0x9E7C, 0x684D, 0x9E7D, 0x6832, 0x9E7E, 0x684E, 0x9E80, 0x68B3, + 0x9E81, 0x682B, 0x9E82, 0x6859, 0x9E83, 0x6863, 0x9E84, 0x6877, + 0x9E85, 0x687F, 0x9E86, 0x689F, 0x9E87, 0x688F, 0x9E88, 0x68AD, + 0x9E89, 0x6894, 0x9E8A, 0x689D, 0x9E8B, 0x689B, 0x9E8C, 0x6883, + 0x9E8D, 0x6AAE, 0x9E8E, 0x68B9, 0x9E8F, 0x6874, 0x9E90, 0x68B5, + 0x9E91, 0x68A0, 0x9E92, 0x68BA, 0x9E93, 0x690F, 0x9E94, 0x688D, + 0x9E95, 0x687E, 0x9E96, 0x6901, 0x9E97, 0x68CA, 0x9E98, 0x6908, + 0x9E99, 0x68D8, 0x9E9A, 0x6922, 0x9E9B, 0x6926, 0x9E9C, 0x68E1, + 0x9E9D, 0x690C, 0x9E9E, 0x68CD, 0x9E9F, 0x68D4, 0x9EA0, 0x68E7, + 0x9EA1, 0x68D5, 0x9EA2, 0x6936, 0x9EA3, 0x6912, 0x9EA4, 0x6904, + 0x9EA5, 0x68D7, 0x9EA6, 0x68E3, 0x9EA7, 0x6925, 0x9EA8, 0x68F9, + 0x9EA9, 0x68E0, 0x9EAA, 0x68EF, 0x9EAB, 0x6928, 0x9EAC, 0x692A, + 0x9EAD, 0x691A, 0x9EAE, 0x6923, 0x9EAF, 0x6921, 0x9EB0, 0x68C6, + 0x9EB1, 0x6979, 0x9EB2, 0x6977, 0x9EB3, 0x695C, 0x9EB4, 0x6978, + 0x9EB5, 0x696B, 0x9EB6, 0x6954, 0x9EB7, 0x697E, 0x9EB8, 0x696E, + 0x9EB9, 0x6939, 0x9EBA, 0x6974, 0x9EBB, 0x693D, 0x9EBC, 0x6959, + 0x9EBD, 0x6930, 0x9EBE, 0x6961, 0x9EBF, 0x695E, 0x9EC0, 0x695D, + 0x9EC1, 0x6981, 0x9EC2, 0x696A, 0x9EC3, 0x69B2, 0x9EC4, 0x69AE, + 0x9EC5, 0x69D0, 0x9EC6, 0x69BF, 0x9EC7, 0x69C1, 0x9EC8, 0x69D3, + 0x9EC9, 0x69BE, 0x9ECA, 0x69CE, 0x9ECB, 0x5BE8, 0x9ECC, 0x69CA, + 0x9ECD, 0x69DD, 0x9ECE, 0x69BB, 0x9ECF, 0x69C3, 0x9ED0, 0x69A7, + 0x9ED1, 0x6A2E, 0x9ED2, 0x6991, 0x9ED3, 0x69A0, 0x9ED4, 0x699C, + 0x9ED5, 0x6995, 0x9ED6, 0x69B4, 0x9ED7, 0x69DE, 0x9ED8, 0x69E8, + 0x9ED9, 0x6A02, 0x9EDA, 0x6A1B, 0x9EDB, 0x69FF, 0x9EDC, 0x6B0A, + 0x9EDD, 0x69F9, 0x9EDE, 0x69F2, 0x9EDF, 0x69E7, 0x9EE0, 0x6A05, + 0x9EE1, 0x69B1, 0x9EE2, 0x6A1E, 0x9EE3, 0x69ED, 0x9EE4, 0x6A14, + 0x9EE5, 0x69EB, 0x9EE6, 0x6A0A, 0x9EE7, 0x6A12, 0x9EE8, 0x6AC1, + 0x9EE9, 0x6A23, 0x9EEA, 0x6A13, 0x9EEB, 0x6A44, 0x9EEC, 0x6A0C, + 0x9EED, 0x6A72, 0x9EEE, 0x6A36, 0x9EEF, 0x6A78, 0x9EF0, 0x6A47, + 0x9EF1, 0x6A62, 0x9EF2, 0x6A59, 0x9EF3, 0x6A66, 0x9EF4, 0x6A48, + 0x9EF5, 0x6A38, 0x9EF6, 0x6A22, 0x9EF7, 0x6A90, 0x9EF8, 0x6A8D, + 0x9EF9, 0x6AA0, 0x9EFA, 0x6A84, 0x9EFB, 0x6AA2, 0x9EFC, 0x6AA3, + 0x9F40, 0x6A97, 0x9F41, 0x8617, 0x9F42, 0x6ABB, 0x9F43, 0x6AC3, + 0x9F44, 0x6AC2, 0x9F45, 0x6AB8, 0x9F46, 0x6AB3, 0x9F47, 0x6AAC, + 0x9F48, 0x6ADE, 0x9F49, 0x6AD1, 0x9F4A, 0x6ADF, 0x9F4B, 0x6AAA, + 0x9F4C, 0x6ADA, 0x9F4D, 0x6AEA, 0x9F4E, 0x6AFB, 0x9F4F, 0x6B05, + 0x9F50, 0x8616, 0x9F51, 0x6AFA, 0x9F52, 0x6B12, 0x9F53, 0x6B16, + 0x9F54, 0x9B31, 0x9F55, 0x6B1F, 0x9F56, 0x6B38, 0x9F57, 0x6B37, + 0x9F58, 0x76DC, 0x9F59, 0x6B39, 0x9F5A, 0x98EE, 0x9F5B, 0x6B47, + 0x9F5C, 0x6B43, 0x9F5D, 0x6B49, 0x9F5E, 0x6B50, 0x9F5F, 0x6B59, + 0x9F60, 0x6B54, 0x9F61, 0x6B5B, 0x9F62, 0x6B5F, 0x9F63, 0x6B61, + 0x9F64, 0x6B78, 0x9F65, 0x6B79, 0x9F66, 0x6B7F, 0x9F67, 0x6B80, + 0x9F68, 0x6B84, 0x9F69, 0x6B83, 0x9F6A, 0x6B8D, 0x9F6B, 0x6B98, + 0x9F6C, 0x6B95, 0x9F6D, 0x6B9E, 0x9F6E, 0x6BA4, 0x9F6F, 0x6BAA, + 0x9F70, 0x6BAB, 0x9F71, 0x6BAF, 0x9F72, 0x6BB2, 0x9F73, 0x6BB1, + 0x9F74, 0x6BB3, 0x9F75, 0x6BB7, 0x9F76, 0x6BBC, 0x9F77, 0x6BC6, + 0x9F78, 0x6BCB, 0x9F79, 0x6BD3, 0x9F7A, 0x6BDF, 0x9F7B, 0x6BEC, + 0x9F7C, 0x6BEB, 0x9F7D, 0x6BF3, 0x9F7E, 0x6BEF, 0x9F80, 0x9EBE, + 0x9F81, 0x6C08, 0x9F82, 0x6C13, 0x9F83, 0x6C14, 0x9F84, 0x6C1B, + 0x9F85, 0x6C24, 0x9F86, 0x6C23, 0x9F87, 0x6C5E, 0x9F88, 0x6C55, + 0x9F89, 0x6C62, 0x9F8A, 0x6C6A, 0x9F8B, 0x6C82, 0x9F8C, 0x6C8D, + 0x9F8D, 0x6C9A, 0x9F8E, 0x6C81, 0x9F8F, 0x6C9B, 0x9F90, 0x6C7E, + 0x9F91, 0x6C68, 0x9F92, 0x6C73, 0x9F93, 0x6C92, 0x9F94, 0x6C90, + 0x9F95, 0x6CC4, 0x9F96, 0x6CF1, 0x9F97, 0x6CD3, 0x9F98, 0x6CBD, + 0x9F99, 0x6CD7, 0x9F9A, 0x6CC5, 0x9F9B, 0x6CDD, 0x9F9C, 0x6CAE, + 0x9F9D, 0x6CB1, 0x9F9E, 0x6CBE, 0x9F9F, 0x6CBA, 0x9FA0, 0x6CDB, + 0x9FA1, 0x6CEF, 0x9FA2, 0x6CD9, 0x9FA3, 0x6CEA, 0x9FA4, 0x6D1F, + 0x9FA5, 0x884D, 0x9FA6, 0x6D36, 0x9FA7, 0x6D2B, 0x9FA8, 0x6D3D, + 0x9FA9, 0x6D38, 0x9FAA, 0x6D19, 0x9FAB, 0x6D35, 0x9FAC, 0x6D33, + 0x9FAD, 0x6D12, 0x9FAE, 0x6D0C, 0x9FAF, 0x6D63, 0x9FB0, 0x6D93, + 0x9FB1, 0x6D64, 0x9FB2, 0x6D5A, 0x9FB3, 0x6D79, 0x9FB4, 0x6D59, + 0x9FB5, 0x6D8E, 0x9FB6, 0x6D95, 0x9FB7, 0x6FE4, 0x9FB8, 0x6D85, + 0x9FB9, 0x6DF9, 0x9FBA, 0x6E15, 0x9FBB, 0x6E0A, 0x9FBC, 0x6DB5, + 0x9FBD, 0x6DC7, 0x9FBE, 0x6DE6, 0x9FBF, 0x6DB8, 0x9FC0, 0x6DC6, + 0x9FC1, 0x6DEC, 0x9FC2, 0x6DDE, 0x9FC3, 0x6DCC, 0x9FC4, 0x6DE8, + 0x9FC5, 0x6DD2, 0x9FC6, 0x6DC5, 0x9FC7, 0x6DFA, 0x9FC8, 0x6DD9, + 0x9FC9, 0x6DE4, 0x9FCA, 0x6DD5, 0x9FCB, 0x6DEA, 0x9FCC, 0x6DEE, + 0x9FCD, 0x6E2D, 0x9FCE, 0x6E6E, 0x9FCF, 0x6E2E, 0x9FD0, 0x6E19, + 0x9FD1, 0x6E72, 0x9FD2, 0x6E5F, 0x9FD3, 0x6E3E, 0x9FD4, 0x6E23, + 0x9FD5, 0x6E6B, 0x9FD6, 0x6E2B, 0x9FD7, 0x6E76, 0x9FD8, 0x6E4D, + 0x9FD9, 0x6E1F, 0x9FDA, 0x6E43, 0x9FDB, 0x6E3A, 0x9FDC, 0x6E4E, + 0x9FDD, 0x6E24, 0x9FDE, 0x6EFF, 0x9FDF, 0x6E1D, 0x9FE0, 0x6E38, + 0x9FE1, 0x6E82, 0x9FE2, 0x6EAA, 0x9FE3, 0x6E98, 0x9FE4, 0x6EC9, + 0x9FE5, 0x6EB7, 0x9FE6, 0x6ED3, 0x9FE7, 0x6EBD, 0x9FE8, 0x6EAF, + 0x9FE9, 0x6EC4, 0x9FEA, 0x6EB2, 0x9FEB, 0x6ED4, 0x9FEC, 0x6ED5, + 0x9FED, 0x6E8F, 0x9FEE, 0x6EA5, 0x9FEF, 0x6EC2, 0x9FF0, 0x6E9F, + 0x9FF1, 0x6F41, 0x9FF2, 0x6F11, 0x9FF3, 0x704C, 0x9FF4, 0x6EEC, + 0x9FF5, 0x6EF8, 0x9FF6, 0x6EFE, 0x9FF7, 0x6F3F, 0x9FF8, 0x6EF2, + 0x9FF9, 0x6F31, 0x9FFA, 0x6EEF, 0x9FFB, 0x6F32, 0x9FFC, 0x6ECC, + 0xE040, 0x6F3E, 0xE041, 0x6F13, 0xE042, 0x6EF7, 0xE043, 0x6F86, + 0xE044, 0x6F7A, 0xE045, 0x6F78, 0xE046, 0x6F81, 0xE047, 0x6F80, + 0xE048, 0x6F6F, 0xE049, 0x6F5B, 0xE04A, 0x6FF3, 0xE04B, 0x6F6D, + 0xE04C, 0x6F82, 0xE04D, 0x6F7C, 0xE04E, 0x6F58, 0xE04F, 0x6F8E, + 0xE050, 0x6F91, 0xE051, 0x6FC2, 0xE052, 0x6F66, 0xE053, 0x6FB3, + 0xE054, 0x6FA3, 0xE055, 0x6FA1, 0xE056, 0x6FA4, 0xE057, 0x6FB9, + 0xE058, 0x6FC6, 0xE059, 0x6FAA, 0xE05A, 0x6FDF, 0xE05B, 0x6FD5, + 0xE05C, 0x6FEC, 0xE05D, 0x6FD4, 0xE05E, 0x6FD8, 0xE05F, 0x6FF1, + 0xE060, 0x6FEE, 0xE061, 0x6FDB, 0xE062, 0x7009, 0xE063, 0x700B, + 0xE064, 0x6FFA, 0xE065, 0x7011, 0xE066, 0x7001, 0xE067, 0x700F, + 0xE068, 0x6FFE, 0xE069, 0x701B, 0xE06A, 0x701A, 0xE06B, 0x6F74, + 0xE06C, 0x701D, 0xE06D, 0x7018, 0xE06E, 0x701F, 0xE06F, 0x7030, + 0xE070, 0x703E, 0xE071, 0x7032, 0xE072, 0x7051, 0xE073, 0x7063, + 0xE074, 0x7099, 0xE075, 0x7092, 0xE076, 0x70AF, 0xE077, 0x70F1, + 0xE078, 0x70AC, 0xE079, 0x70B8, 0xE07A, 0x70B3, 0xE07B, 0x70AE, + 0xE07C, 0x70DF, 0xE07D, 0x70CB, 0xE07E, 0x70DD, 0xE080, 0x70D9, + 0xE081, 0x7109, 0xE082, 0x70FD, 0xE083, 0x711C, 0xE084, 0x7119, + 0xE085, 0x7165, 0xE086, 0x7155, 0xE087, 0x7188, 0xE088, 0x7166, + 0xE089, 0x7162, 0xE08A, 0x714C, 0xE08B, 0x7156, 0xE08C, 0x716C, + 0xE08D, 0x718F, 0xE08E, 0x71FB, 0xE08F, 0x7184, 0xE090, 0x7195, + 0xE091, 0x71A8, 0xE092, 0x71AC, 0xE093, 0x71D7, 0xE094, 0x71B9, + 0xE095, 0x71BE, 0xE096, 0x71D2, 0xE097, 0x71C9, 0xE098, 0x71D4, + 0xE099, 0x71CE, 0xE09A, 0x71E0, 0xE09B, 0x71EC, 0xE09C, 0x71E7, + 0xE09D, 0x71F5, 0xE09E, 0x71FC, 0xE09F, 0x71F9, 0xE0A0, 0x71FF, + 0xE0A1, 0x720D, 0xE0A2, 0x7210, 0xE0A3, 0x721B, 0xE0A4, 0x7228, + 0xE0A5, 0x722D, 0xE0A6, 0x722C, 0xE0A7, 0x7230, 0xE0A8, 0x7232, + 0xE0A9, 0x723B, 0xE0AA, 0x723C, 0xE0AB, 0x723F, 0xE0AC, 0x7240, + 0xE0AD, 0x7246, 0xE0AE, 0x724B, 0xE0AF, 0x7258, 0xE0B0, 0x7274, + 0xE0B1, 0x727E, 0xE0B2, 0x7282, 0xE0B3, 0x7281, 0xE0B4, 0x7287, + 0xE0B5, 0x7292, 0xE0B6, 0x7296, 0xE0B7, 0x72A2, 0xE0B8, 0x72A7, + 0xE0B9, 0x72B9, 0xE0BA, 0x72B2, 0xE0BB, 0x72C3, 0xE0BC, 0x72C6, + 0xE0BD, 0x72C4, 0xE0BE, 0x72CE, 0xE0BF, 0x72D2, 0xE0C0, 0x72E2, + 0xE0C1, 0x72E0, 0xE0C2, 0x72E1, 0xE0C3, 0x72F9, 0xE0C4, 0x72F7, + 0xE0C5, 0x500F, 0xE0C6, 0x7317, 0xE0C7, 0x730A, 0xE0C8, 0x731C, + 0xE0C9, 0x7316, 0xE0CA, 0x731D, 0xE0CB, 0x7334, 0xE0CC, 0x732F, + 0xE0CD, 0x7329, 0xE0CE, 0x7325, 0xE0CF, 0x733E, 0xE0D0, 0x734E, + 0xE0D1, 0x734F, 0xE0D2, 0x9ED8, 0xE0D3, 0x7357, 0xE0D4, 0x736A, + 0xE0D5, 0x7368, 0xE0D6, 0x7370, 0xE0D7, 0x7378, 0xE0D8, 0x7375, + 0xE0D9, 0x737B, 0xE0DA, 0x737A, 0xE0DB, 0x73C8, 0xE0DC, 0x73B3, + 0xE0DD, 0x73CE, 0xE0DE, 0x73BB, 0xE0DF, 0x73C0, 0xE0E0, 0x73E5, + 0xE0E1, 0x73EE, 0xE0E2, 0x73DE, 0xE0E3, 0x74A2, 0xE0E4, 0x7405, + 0xE0E5, 0x746F, 0xE0E6, 0x7425, 0xE0E7, 0x73F8, 0xE0E8, 0x7432, + 0xE0E9, 0x743A, 0xE0EA, 0x7455, 0xE0EB, 0x743F, 0xE0EC, 0x745F, + 0xE0ED, 0x7459, 0xE0EE, 0x7441, 0xE0EF, 0x745C, 0xE0F0, 0x7469, + 0xE0F1, 0x7470, 0xE0F2, 0x7463, 0xE0F3, 0x746A, 0xE0F4, 0x7476, + 0xE0F5, 0x747E, 0xE0F6, 0x748B, 0xE0F7, 0x749E, 0xE0F8, 0x74A7, + 0xE0F9, 0x74CA, 0xE0FA, 0x74CF, 0xE0FB, 0x74D4, 0xE0FC, 0x73F1, + 0xE140, 0x74E0, 0xE141, 0x74E3, 0xE142, 0x74E7, 0xE143, 0x74E9, + 0xE144, 0x74EE, 0xE145, 0x74F2, 0xE146, 0x74F0, 0xE147, 0x74F1, + 0xE148, 0x74F8, 0xE149, 0x74F7, 0xE14A, 0x7504, 0xE14B, 0x7503, + 0xE14C, 0x7505, 0xE14D, 0x750C, 0xE14E, 0x750E, 0xE14F, 0x750D, + 0xE150, 0x7515, 0xE151, 0x7513, 0xE152, 0x751E, 0xE153, 0x7526, + 0xE154, 0x752C, 0xE155, 0x753C, 0xE156, 0x7544, 0xE157, 0x754D, + 0xE158, 0x754A, 0xE159, 0x7549, 0xE15A, 0x755B, 0xE15B, 0x7546, + 0xE15C, 0x755A, 0xE15D, 0x7569, 0xE15E, 0x7564, 0xE15F, 0x7567, + 0xE160, 0x756B, 0xE161, 0x756D, 0xE162, 0x7578, 0xE163, 0x7576, + 0xE164, 0x7586, 0xE165, 0x7587, 0xE166, 0x7574, 0xE167, 0x758A, + 0xE168, 0x7589, 0xE169, 0x7582, 0xE16A, 0x7594, 0xE16B, 0x759A, + 0xE16C, 0x759D, 0xE16D, 0x75A5, 0xE16E, 0x75A3, 0xE16F, 0x75C2, + 0xE170, 0x75B3, 0xE171, 0x75C3, 0xE172, 0x75B5, 0xE173, 0x75BD, + 0xE174, 0x75B8, 0xE175, 0x75BC, 0xE176, 0x75B1, 0xE177, 0x75CD, + 0xE178, 0x75CA, 0xE179, 0x75D2, 0xE17A, 0x75D9, 0xE17B, 0x75E3, + 0xE17C, 0x75DE, 0xE17D, 0x75FE, 0xE17E, 0x75FF, 0xE180, 0x75FC, + 0xE181, 0x7601, 0xE182, 0x75F0, 0xE183, 0x75FA, 0xE184, 0x75F2, + 0xE185, 0x75F3, 0xE186, 0x760B, 0xE187, 0x760D, 0xE188, 0x7609, + 0xE189, 0x761F, 0xE18A, 0x7627, 0xE18B, 0x7620, 0xE18C, 0x7621, + 0xE18D, 0x7622, 0xE18E, 0x7624, 0xE18F, 0x7634, 0xE190, 0x7630, + 0xE191, 0x763B, 0xE192, 0x7647, 0xE193, 0x7648, 0xE194, 0x7646, + 0xE195, 0x765C, 0xE196, 0x7658, 0xE197, 0x7661, 0xE198, 0x7662, + 0xE199, 0x7668, 0xE19A, 0x7669, 0xE19B, 0x766A, 0xE19C, 0x7667, + 0xE19D, 0x766C, 0xE19E, 0x7670, 0xE19F, 0x7672, 0xE1A0, 0x7676, + 0xE1A1, 0x7678, 0xE1A2, 0x767C, 0xE1A3, 0x7680, 0xE1A4, 0x7683, + 0xE1A5, 0x7688, 0xE1A6, 0x768B, 0xE1A7, 0x768E, 0xE1A8, 0x7696, + 0xE1A9, 0x7693, 0xE1AA, 0x7699, 0xE1AB, 0x769A, 0xE1AC, 0x76B0, + 0xE1AD, 0x76B4, 0xE1AE, 0x76B8, 0xE1AF, 0x76B9, 0xE1B0, 0x76BA, + 0xE1B1, 0x76C2, 0xE1B2, 0x76CD, 0xE1B3, 0x76D6, 0xE1B4, 0x76D2, + 0xE1B5, 0x76DE, 0xE1B6, 0x76E1, 0xE1B7, 0x76E5, 0xE1B8, 0x76E7, + 0xE1B9, 0x76EA, 0xE1BA, 0x862F, 0xE1BB, 0x76FB, 0xE1BC, 0x7708, + 0xE1BD, 0x7707, 0xE1BE, 0x7704, 0xE1BF, 0x7729, 0xE1C0, 0x7724, + 0xE1C1, 0x771E, 0xE1C2, 0x7725, 0xE1C3, 0x7726, 0xE1C4, 0x771B, + 0xE1C5, 0x7737, 0xE1C6, 0x7738, 0xE1C7, 0x7747, 0xE1C8, 0x775A, + 0xE1C9, 0x7768, 0xE1CA, 0x776B, 0xE1CB, 0x775B, 0xE1CC, 0x7765, + 0xE1CD, 0x777F, 0xE1CE, 0x777E, 0xE1CF, 0x7779, 0xE1D0, 0x778E, + 0xE1D1, 0x778B, 0xE1D2, 0x7791, 0xE1D3, 0x77A0, 0xE1D4, 0x779E, + 0xE1D5, 0x77B0, 0xE1D6, 0x77B6, 0xE1D7, 0x77B9, 0xE1D8, 0x77BF, + 0xE1D9, 0x77BC, 0xE1DA, 0x77BD, 0xE1DB, 0x77BB, 0xE1DC, 0x77C7, + 0xE1DD, 0x77CD, 0xE1DE, 0x77D7, 0xE1DF, 0x77DA, 0xE1E0, 0x77DC, + 0xE1E1, 0x77E3, 0xE1E2, 0x77EE, 0xE1E3, 0x77FC, 0xE1E4, 0x780C, + 0xE1E5, 0x7812, 0xE1E6, 0x7926, 0xE1E7, 0x7820, 0xE1E8, 0x792A, + 0xE1E9, 0x7845, 0xE1EA, 0x788E, 0xE1EB, 0x7874, 0xE1EC, 0x7886, + 0xE1ED, 0x787C, 0xE1EE, 0x789A, 0xE1EF, 0x788C, 0xE1F0, 0x78A3, + 0xE1F1, 0x78B5, 0xE1F2, 0x78AA, 0xE1F3, 0x78AF, 0xE1F4, 0x78D1, + 0xE1F5, 0x78C6, 0xE1F6, 0x78CB, 0xE1F7, 0x78D4, 0xE1F8, 0x78BE, + 0xE1F9, 0x78BC, 0xE1FA, 0x78C5, 0xE1FB, 0x78CA, 0xE1FC, 0x78EC, + 0xE240, 0x78E7, 0xE241, 0x78DA, 0xE242, 0x78FD, 0xE243, 0x78F4, + 0xE244, 0x7907, 0xE245, 0x7912, 0xE246, 0x7911, 0xE247, 0x7919, + 0xE248, 0x792C, 0xE249, 0x792B, 0xE24A, 0x7940, 0xE24B, 0x7960, + 0xE24C, 0x7957, 0xE24D, 0x795F, 0xE24E, 0x795A, 0xE24F, 0x7955, + 0xE250, 0x7953, 0xE251, 0x797A, 0xE252, 0x797F, 0xE253, 0x798A, + 0xE254, 0x799D, 0xE255, 0x79A7, 0xE256, 0x9F4B, 0xE257, 0x79AA, + 0xE258, 0x79AE, 0xE259, 0x79B3, 0xE25A, 0x79B9, 0xE25B, 0x79BA, + 0xE25C, 0x79C9, 0xE25D, 0x79D5, 0xE25E, 0x79E7, 0xE25F, 0x79EC, + 0xE260, 0x79E1, 0xE261, 0x79E3, 0xE262, 0x7A08, 0xE263, 0x7A0D, + 0xE264, 0x7A18, 0xE265, 0x7A19, 0xE266, 0x7A20, 0xE267, 0x7A1F, + 0xE268, 0x7980, 0xE269, 0x7A31, 0xE26A, 0x7A3B, 0xE26B, 0x7A3E, + 0xE26C, 0x7A37, 0xE26D, 0x7A43, 0xE26E, 0x7A57, 0xE26F, 0x7A49, + 0xE270, 0x7A61, 0xE271, 0x7A62, 0xE272, 0x7A69, 0xE273, 0x9F9D, + 0xE274, 0x7A70, 0xE275, 0x7A79, 0xE276, 0x7A7D, 0xE277, 0x7A88, + 0xE278, 0x7A97, 0xE279, 0x7A95, 0xE27A, 0x7A98, 0xE27B, 0x7A96, + 0xE27C, 0x7AA9, 0xE27D, 0x7AC8, 0xE27E, 0x7AB0, 0xE280, 0x7AB6, + 0xE281, 0x7AC5, 0xE282, 0x7AC4, 0xE283, 0x7ABF, 0xE284, 0x9083, + 0xE285, 0x7AC7, 0xE286, 0x7ACA, 0xE287, 0x7ACD, 0xE288, 0x7ACF, + 0xE289, 0x7AD5, 0xE28A, 0x7AD3, 0xE28B, 0x7AD9, 0xE28C, 0x7ADA, + 0xE28D, 0x7ADD, 0xE28E, 0x7AE1, 0xE28F, 0x7AE2, 0xE290, 0x7AE6, + 0xE291, 0x7AED, 0xE292, 0x7AF0, 0xE293, 0x7B02, 0xE294, 0x7B0F, + 0xE295, 0x7B0A, 0xE296, 0x7B06, 0xE297, 0x7B33, 0xE298, 0x7B18, + 0xE299, 0x7B19, 0xE29A, 0x7B1E, 0xE29B, 0x7B35, 0xE29C, 0x7B28, + 0xE29D, 0x7B36, 0xE29E, 0x7B50, 0xE29F, 0x7B7A, 0xE2A0, 0x7B04, + 0xE2A1, 0x7B4D, 0xE2A2, 0x7B0B, 0xE2A3, 0x7B4C, 0xE2A4, 0x7B45, + 0xE2A5, 0x7B75, 0xE2A6, 0x7B65, 0xE2A7, 0x7B74, 0xE2A8, 0x7B67, + 0xE2A9, 0x7B70, 0xE2AA, 0x7B71, 0xE2AB, 0x7B6C, 0xE2AC, 0x7B6E, + 0xE2AD, 0x7B9D, 0xE2AE, 0x7B98, 0xE2AF, 0x7B9F, 0xE2B0, 0x7B8D, + 0xE2B1, 0x7B9C, 0xE2B2, 0x7B9A, 0xE2B3, 0x7B8B, 0xE2B4, 0x7B92, + 0xE2B5, 0x7B8F, 0xE2B6, 0x7B5D, 0xE2B7, 0x7B99, 0xE2B8, 0x7BCB, + 0xE2B9, 0x7BC1, 0xE2BA, 0x7BCC, 0xE2BB, 0x7BCF, 0xE2BC, 0x7BB4, + 0xE2BD, 0x7BC6, 0xE2BE, 0x7BDD, 0xE2BF, 0x7BE9, 0xE2C0, 0x7C11, + 0xE2C1, 0x7C14, 0xE2C2, 0x7BE6, 0xE2C3, 0x7BE5, 0xE2C4, 0x7C60, + 0xE2C5, 0x7C00, 0xE2C6, 0x7C07, 0xE2C7, 0x7C13, 0xE2C8, 0x7BF3, + 0xE2C9, 0x7BF7, 0xE2CA, 0x7C17, 0xE2CB, 0x7C0D, 0xE2CC, 0x7BF6, + 0xE2CD, 0x7C23, 0xE2CE, 0x7C27, 0xE2CF, 0x7C2A, 0xE2D0, 0x7C1F, + 0xE2D1, 0x7C37, 0xE2D2, 0x7C2B, 0xE2D3, 0x7C3D, 0xE2D4, 0x7C4C, + 0xE2D5, 0x7C43, 0xE2D6, 0x7C54, 0xE2D7, 0x7C4F, 0xE2D8, 0x7C40, + 0xE2D9, 0x7C50, 0xE2DA, 0x7C58, 0xE2DB, 0x7C5F, 0xE2DC, 0x7C64, + 0xE2DD, 0x7C56, 0xE2DE, 0x7C65, 0xE2DF, 0x7C6C, 0xE2E0, 0x7C75, + 0xE2E1, 0x7C83, 0xE2E2, 0x7C90, 0xE2E3, 0x7CA4, 0xE2E4, 0x7CAD, + 0xE2E5, 0x7CA2, 0xE2E6, 0x7CAB, 0xE2E7, 0x7CA1, 0xE2E8, 0x7CA8, + 0xE2E9, 0x7CB3, 0xE2EA, 0x7CB2, 0xE2EB, 0x7CB1, 0xE2EC, 0x7CAE, + 0xE2ED, 0x7CB9, 0xE2EE, 0x7CBD, 0xE2EF, 0x7CC0, 0xE2F0, 0x7CC5, + 0xE2F1, 0x7CC2, 0xE2F2, 0x7CD8, 0xE2F3, 0x7CD2, 0xE2F4, 0x7CDC, + 0xE2F5, 0x7CE2, 0xE2F6, 0x9B3B, 0xE2F7, 0x7CEF, 0xE2F8, 0x7CF2, + 0xE2F9, 0x7CF4, 0xE2FA, 0x7CF6, 0xE2FB, 0x7CFA, 0xE2FC, 0x7D06, + 0xE340, 0x7D02, 0xE341, 0x7D1C, 0xE342, 0x7D15, 0xE343, 0x7D0A, + 0xE344, 0x7D45, 0xE345, 0x7D4B, 0xE346, 0x7D2E, 0xE347, 0x7D32, + 0xE348, 0x7D3F, 0xE349, 0x7D35, 0xE34A, 0x7D46, 0xE34B, 0x7D73, + 0xE34C, 0x7D56, 0xE34D, 0x7D4E, 0xE34E, 0x7D72, 0xE34F, 0x7D68, + 0xE350, 0x7D6E, 0xE351, 0x7D4F, 0xE352, 0x7D63, 0xE353, 0x7D93, + 0xE354, 0x7D89, 0xE355, 0x7D5B, 0xE356, 0x7D8F, 0xE357, 0x7D7D, + 0xE358, 0x7D9B, 0xE359, 0x7DBA, 0xE35A, 0x7DAE, 0xE35B, 0x7DA3, + 0xE35C, 0x7DB5, 0xE35D, 0x7DC7, 0xE35E, 0x7DBD, 0xE35F, 0x7DAB, + 0xE360, 0x7E3D, 0xE361, 0x7DA2, 0xE362, 0x7DAF, 0xE363, 0x7DDC, + 0xE364, 0x7DB8, 0xE365, 0x7D9F, 0xE366, 0x7DB0, 0xE367, 0x7DD8, + 0xE368, 0x7DDD, 0xE369, 0x7DE4, 0xE36A, 0x7DDE, 0xE36B, 0x7DFB, + 0xE36C, 0x7DF2, 0xE36D, 0x7DE1, 0xE36E, 0x7E05, 0xE36F, 0x7E0A, + 0xE370, 0x7E23, 0xE371, 0x7E21, 0xE372, 0x7E12, 0xE373, 0x7E31, + 0xE374, 0x7E1F, 0xE375, 0x7E09, 0xE376, 0x7E0B, 0xE377, 0x7E22, + 0xE378, 0x7E46, 0xE379, 0x7E66, 0xE37A, 0x7E3B, 0xE37B, 0x7E35, + 0xE37C, 0x7E39, 0xE37D, 0x7E43, 0xE37E, 0x7E37, 0xE380, 0x7E32, + 0xE381, 0x7E3A, 0xE382, 0x7E67, 0xE383, 0x7E5D, 0xE384, 0x7E56, + 0xE385, 0x7E5E, 0xE386, 0x7E59, 0xE387, 0x7E5A, 0xE388, 0x7E79, + 0xE389, 0x7E6A, 0xE38A, 0x7E69, 0xE38B, 0x7E7C, 0xE38C, 0x7E7B, + 0xE38D, 0x7E83, 0xE38E, 0x7DD5, 0xE38F, 0x7E7D, 0xE390, 0x8FAE, + 0xE391, 0x7E7F, 0xE392, 0x7E88, 0xE393, 0x7E89, 0xE394, 0x7E8C, + 0xE395, 0x7E92, 0xE396, 0x7E90, 0xE397, 0x7E93, 0xE398, 0x7E94, + 0xE399, 0x7E96, 0xE39A, 0x7E8E, 0xE39B, 0x7E9B, 0xE39C, 0x7E9C, + 0xE39D, 0x7F38, 0xE39E, 0x7F3A, 0xE39F, 0x7F45, 0xE3A0, 0x7F4C, + 0xE3A1, 0x7F4D, 0xE3A2, 0x7F4E, 0xE3A3, 0x7F50, 0xE3A4, 0x7F51, + 0xE3A5, 0x7F55, 0xE3A6, 0x7F54, 0xE3A7, 0x7F58, 0xE3A8, 0x7F5F, + 0xE3A9, 0x7F60, 0xE3AA, 0x7F68, 0xE3AB, 0x7F69, 0xE3AC, 0x7F67, + 0xE3AD, 0x7F78, 0xE3AE, 0x7F82, 0xE3AF, 0x7F86, 0xE3B0, 0x7F83, + 0xE3B1, 0x7F88, 0xE3B2, 0x7F87, 0xE3B3, 0x7F8C, 0xE3B4, 0x7F94, + 0xE3B5, 0x7F9E, 0xE3B6, 0x7F9D, 0xE3B7, 0x7F9A, 0xE3B8, 0x7FA3, + 0xE3B9, 0x7FAF, 0xE3BA, 0x7FB2, 0xE3BB, 0x7FB9, 0xE3BC, 0x7FAE, + 0xE3BD, 0x7FB6, 0xE3BE, 0x7FB8, 0xE3BF, 0x8B71, 0xE3C0, 0x7FC5, + 0xE3C1, 0x7FC6, 0xE3C2, 0x7FCA, 0xE3C3, 0x7FD5, 0xE3C4, 0x7FD4, + 0xE3C5, 0x7FE1, 0xE3C6, 0x7FE6, 0xE3C7, 0x7FE9, 0xE3C8, 0x7FF3, + 0xE3C9, 0x7FF9, 0xE3CA, 0x98DC, 0xE3CB, 0x8006, 0xE3CC, 0x8004, + 0xE3CD, 0x800B, 0xE3CE, 0x8012, 0xE3CF, 0x8018, 0xE3D0, 0x8019, + 0xE3D1, 0x801C, 0xE3D2, 0x8021, 0xE3D3, 0x8028, 0xE3D4, 0x803F, + 0xE3D5, 0x803B, 0xE3D6, 0x804A, 0xE3D7, 0x8046, 0xE3D8, 0x8052, + 0xE3D9, 0x8058, 0xE3DA, 0x805A, 0xE3DB, 0x805F, 0xE3DC, 0x8062, + 0xE3DD, 0x8068, 0xE3DE, 0x8073, 0xE3DF, 0x8072, 0xE3E0, 0x8070, + 0xE3E1, 0x8076, 0xE3E2, 0x8079, 0xE3E3, 0x807D, 0xE3E4, 0x807F, + 0xE3E5, 0x8084, 0xE3E6, 0x8086, 0xE3E7, 0x8085, 0xE3E8, 0x809B, + 0xE3E9, 0x8093, 0xE3EA, 0x809A, 0xE3EB, 0x80AD, 0xE3EC, 0x5190, + 0xE3ED, 0x80AC, 0xE3EE, 0x80DB, 0xE3EF, 0x80E5, 0xE3F0, 0x80D9, + 0xE3F1, 0x80DD, 0xE3F2, 0x80C4, 0xE3F3, 0x80DA, 0xE3F4, 0x80D6, + 0xE3F5, 0x8109, 0xE3F6, 0x80EF, 0xE3F7, 0x80F1, 0xE3F8, 0x811B, + 0xE3F9, 0x8129, 0xE3FA, 0x8123, 0xE3FB, 0x812F, 0xE3FC, 0x814B, + 0xE440, 0x968B, 0xE441, 0x8146, 0xE442, 0x813E, 0xE443, 0x8153, + 0xE444, 0x8151, 0xE445, 0x80FC, 0xE446, 0x8171, 0xE447, 0x816E, + 0xE448, 0x8165, 0xE449, 0x8166, 0xE44A, 0x8174, 0xE44B, 0x8183, + 0xE44C, 0x8188, 0xE44D, 0x818A, 0xE44E, 0x8180, 0xE44F, 0x8182, + 0xE450, 0x81A0, 0xE451, 0x8195, 0xE452, 0x81A4, 0xE453, 0x81A3, + 0xE454, 0x815F, 0xE455, 0x8193, 0xE456, 0x81A9, 0xE457, 0x81B0, + 0xE458, 0x81B5, 0xE459, 0x81BE, 0xE45A, 0x81B8, 0xE45B, 0x81BD, + 0xE45C, 0x81C0, 0xE45D, 0x81C2, 0xE45E, 0x81BA, 0xE45F, 0x81C9, + 0xE460, 0x81CD, 0xE461, 0x81D1, 0xE462, 0x81D9, 0xE463, 0x81D8, + 0xE464, 0x81C8, 0xE465, 0x81DA, 0xE466, 0x81DF, 0xE467, 0x81E0, + 0xE468, 0x81E7, 0xE469, 0x81FA, 0xE46A, 0x81FB, 0xE46B, 0x81FE, + 0xE46C, 0x8201, 0xE46D, 0x8202, 0xE46E, 0x8205, 0xE46F, 0x8207, + 0xE470, 0x820A, 0xE471, 0x820D, 0xE472, 0x8210, 0xE473, 0x8216, + 0xE474, 0x8229, 0xE475, 0x822B, 0xE476, 0x8238, 0xE477, 0x8233, + 0xE478, 0x8240, 0xE479, 0x8259, 0xE47A, 0x8258, 0xE47B, 0x825D, + 0xE47C, 0x825A, 0xE47D, 0x825F, 0xE47E, 0x8264, 0xE480, 0x8262, + 0xE481, 0x8268, 0xE482, 0x826A, 0xE483, 0x826B, 0xE484, 0x822E, + 0xE485, 0x8271, 0xE486, 0x8277, 0xE487, 0x8278, 0xE488, 0x827E, + 0xE489, 0x828D, 0xE48A, 0x8292, 0xE48B, 0x82AB, 0xE48C, 0x829F, + 0xE48D, 0x82BB, 0xE48E, 0x82AC, 0xE48F, 0x82E1, 0xE490, 0x82E3, + 0xE491, 0x82DF, 0xE492, 0x82D2, 0xE493, 0x82F4, 0xE494, 0x82F3, + 0xE495, 0x82FA, 0xE496, 0x8393, 0xE497, 0x8303, 0xE498, 0x82FB, + 0xE499, 0x82F9, 0xE49A, 0x82DE, 0xE49B, 0x8306, 0xE49C, 0x82DC, + 0xE49D, 0x8309, 0xE49E, 0x82D9, 0xE49F, 0x8335, 0xE4A0, 0x8334, + 0xE4A1, 0x8316, 0xE4A2, 0x8332, 0xE4A3, 0x8331, 0xE4A4, 0x8340, + 0xE4A5, 0x8339, 0xE4A6, 0x8350, 0xE4A7, 0x8345, 0xE4A8, 0x832F, + 0xE4A9, 0x832B, 0xE4AA, 0x8317, 0xE4AB, 0x8318, 0xE4AC, 0x8385, + 0xE4AD, 0x839A, 0xE4AE, 0x83AA, 0xE4AF, 0x839F, 0xE4B0, 0x83A2, + 0xE4B1, 0x8396, 0xE4B2, 0x8323, 0xE4B3, 0x838E, 0xE4B4, 0x8387, + 0xE4B5, 0x838A, 0xE4B6, 0x837C, 0xE4B7, 0x83B5, 0xE4B8, 0x8373, + 0xE4B9, 0x8375, 0xE4BA, 0x83A0, 0xE4BB, 0x8389, 0xE4BC, 0x83A8, + 0xE4BD, 0x83F4, 0xE4BE, 0x8413, 0xE4BF, 0x83EB, 0xE4C0, 0x83CE, + 0xE4C1, 0x83FD, 0xE4C2, 0x8403, 0xE4C3, 0x83D8, 0xE4C4, 0x840B, + 0xE4C5, 0x83C1, 0xE4C6, 0x83F7, 0xE4C7, 0x8407, 0xE4C8, 0x83E0, + 0xE4C9, 0x83F2, 0xE4CA, 0x840D, 0xE4CB, 0x8422, 0xE4CC, 0x8420, + 0xE4CD, 0x83BD, 0xE4CE, 0x8438, 0xE4CF, 0x8506, 0xE4D0, 0x83FB, + 0xE4D1, 0x846D, 0xE4D2, 0x842A, 0xE4D3, 0x843C, 0xE4D4, 0x855A, + 0xE4D5, 0x8484, 0xE4D6, 0x8477, 0xE4D7, 0x846B, 0xE4D8, 0x84AD, + 0xE4D9, 0x846E, 0xE4DA, 0x8482, 0xE4DB, 0x8469, 0xE4DC, 0x8446, + 0xE4DD, 0x842C, 0xE4DE, 0x846F, 0xE4DF, 0x8479, 0xE4E0, 0x8435, + 0xE4E1, 0x84CA, 0xE4E2, 0x8462, 0xE4E3, 0x84B9, 0xE4E4, 0x84BF, + 0xE4E5, 0x849F, 0xE4E6, 0x84D9, 0xE4E7, 0x84CD, 0xE4E8, 0x84BB, + 0xE4E9, 0x84DA, 0xE4EA, 0x84D0, 0xE4EB, 0x84C1, 0xE4EC, 0x84C6, + 0xE4ED, 0x84D6, 0xE4EE, 0x84A1, 0xE4EF, 0x8521, 0xE4F0, 0x84FF, + 0xE4F1, 0x84F4, 0xE4F2, 0x8517, 0xE4F3, 0x8518, 0xE4F4, 0x852C, + 0xE4F5, 0x851F, 0xE4F6, 0x8515, 0xE4F7, 0x8514, 0xE4F8, 0x84FC, + 0xE4F9, 0x8540, 0xE4FA, 0x8563, 0xE4FB, 0x8558, 0xE4FC, 0x8548, + 0xE540, 0x8541, 0xE541, 0x8602, 0xE542, 0x854B, 0xE543, 0x8555, + 0xE544, 0x8580, 0xE545, 0x85A4, 0xE546, 0x8588, 0xE547, 0x8591, + 0xE548, 0x858A, 0xE549, 0x85A8, 0xE54A, 0x856D, 0xE54B, 0x8594, + 0xE54C, 0x859B, 0xE54D, 0x85EA, 0xE54E, 0x8587, 0xE54F, 0x859C, + 0xE550, 0x8577, 0xE551, 0x857E, 0xE552, 0x8590, 0xE553, 0x85C9, + 0xE554, 0x85BA, 0xE555, 0x85CF, 0xE556, 0x85B9, 0xE557, 0x85D0, + 0xE558, 0x85D5, 0xE559, 0x85DD, 0xE55A, 0x85E5, 0xE55B, 0x85DC, + 0xE55C, 0x85F9, 0xE55D, 0x860A, 0xE55E, 0x8613, 0xE55F, 0x860B, + 0xE560, 0x85FE, 0xE561, 0x85FA, 0xE562, 0x8606, 0xE563, 0x8622, + 0xE564, 0x861A, 0xE565, 0x8630, 0xE566, 0x863F, 0xE567, 0x864D, + 0xE568, 0x4E55, 0xE569, 0x8654, 0xE56A, 0x865F, 0xE56B, 0x8667, + 0xE56C, 0x8671, 0xE56D, 0x8693, 0xE56E, 0x86A3, 0xE56F, 0x86A9, + 0xE570, 0x86AA, 0xE571, 0x868B, 0xE572, 0x868C, 0xE573, 0x86B6, + 0xE574, 0x86AF, 0xE575, 0x86C4, 0xE576, 0x86C6, 0xE577, 0x86B0, + 0xE578, 0x86C9, 0xE579, 0x8823, 0xE57A, 0x86AB, 0xE57B, 0x86D4, + 0xE57C, 0x86DE, 0xE57D, 0x86E9, 0xE57E, 0x86EC, 0xE580, 0x86DF, + 0xE581, 0x86DB, 0xE582, 0x86EF, 0xE583, 0x8712, 0xE584, 0x8706, + 0xE585, 0x8708, 0xE586, 0x8700, 0xE587, 0x8703, 0xE588, 0x86FB, + 0xE589, 0x8711, 0xE58A, 0x8709, 0xE58B, 0x870D, 0xE58C, 0x86F9, + 0xE58D, 0x870A, 0xE58E, 0x8734, 0xE58F, 0x873F, 0xE590, 0x8737, + 0xE591, 0x873B, 0xE592, 0x8725, 0xE593, 0x8729, 0xE594, 0x871A, + 0xE595, 0x8760, 0xE596, 0x875F, 0xE597, 0x8778, 0xE598, 0x874C, + 0xE599, 0x874E, 0xE59A, 0x8774, 0xE59B, 0x8757, 0xE59C, 0x8768, + 0xE59D, 0x876E, 0xE59E, 0x8759, 0xE59F, 0x8753, 0xE5A0, 0x8763, + 0xE5A1, 0x876A, 0xE5A2, 0x8805, 0xE5A3, 0x87A2, 0xE5A4, 0x879F, + 0xE5A5, 0x8782, 0xE5A6, 0x87AF, 0xE5A7, 0x87CB, 0xE5A8, 0x87BD, + 0xE5A9, 0x87C0, 0xE5AA, 0x87D0, 0xE5AB, 0x96D6, 0xE5AC, 0x87AB, + 0xE5AD, 0x87C4, 0xE5AE, 0x87B3, 0xE5AF, 0x87C7, 0xE5B0, 0x87C6, + 0xE5B1, 0x87BB, 0xE5B2, 0x87EF, 0xE5B3, 0x87F2, 0xE5B4, 0x87E0, + 0xE5B5, 0x880F, 0xE5B6, 0x880D, 0xE5B7, 0x87FE, 0xE5B8, 0x87F6, + 0xE5B9, 0x87F7, 0xE5BA, 0x880E, 0xE5BB, 0x87D2, 0xE5BC, 0x8811, + 0xE5BD, 0x8816, 0xE5BE, 0x8815, 0xE5BF, 0x8822, 0xE5C0, 0x8821, + 0xE5C1, 0x8831, 0xE5C2, 0x8836, 0xE5C3, 0x8839, 0xE5C4, 0x8827, + 0xE5C5, 0x883B, 0xE5C6, 0x8844, 0xE5C7, 0x8842, 0xE5C8, 0x8852, + 0xE5C9, 0x8859, 0xE5CA, 0x885E, 0xE5CB, 0x8862, 0xE5CC, 0x886B, + 0xE5CD, 0x8881, 0xE5CE, 0x887E, 0xE5CF, 0x889E, 0xE5D0, 0x8875, + 0xE5D1, 0x887D, 0xE5D2, 0x88B5, 0xE5D3, 0x8872, 0xE5D4, 0x8882, + 0xE5D5, 0x8897, 0xE5D6, 0x8892, 0xE5D7, 0x88AE, 0xE5D8, 0x8899, + 0xE5D9, 0x88A2, 0xE5DA, 0x888D, 0xE5DB, 0x88A4, 0xE5DC, 0x88B0, + 0xE5DD, 0x88BF, 0xE5DE, 0x88B1, 0xE5DF, 0x88C3, 0xE5E0, 0x88C4, + 0xE5E1, 0x88D4, 0xE5E2, 0x88D8, 0xE5E3, 0x88D9, 0xE5E4, 0x88DD, + 0xE5E5, 0x88F9, 0xE5E6, 0x8902, 0xE5E7, 0x88FC, 0xE5E8, 0x88F4, + 0xE5E9, 0x88E8, 0xE5EA, 0x88F2, 0xE5EB, 0x8904, 0xE5EC, 0x890C, + 0xE5ED, 0x890A, 0xE5EE, 0x8913, 0xE5EF, 0x8943, 0xE5F0, 0x891E, + 0xE5F1, 0x8925, 0xE5F2, 0x892A, 0xE5F3, 0x892B, 0xE5F4, 0x8941, + 0xE5F5, 0x8944, 0xE5F6, 0x893B, 0xE5F7, 0x8936, 0xE5F8, 0x8938, + 0xE5F9, 0x894C, 0xE5FA, 0x891D, 0xE5FB, 0x8960, 0xE5FC, 0x895E, + 0xE640, 0x8966, 0xE641, 0x8964, 0xE642, 0x896D, 0xE643, 0x896A, + 0xE644, 0x896F, 0xE645, 0x8974, 0xE646, 0x8977, 0xE647, 0x897E, + 0xE648, 0x8983, 0xE649, 0x8988, 0xE64A, 0x898A, 0xE64B, 0x8993, + 0xE64C, 0x8998, 0xE64D, 0x89A1, 0xE64E, 0x89A9, 0xE64F, 0x89A6, + 0xE650, 0x89AC, 0xE651, 0x89AF, 0xE652, 0x89B2, 0xE653, 0x89BA, + 0xE654, 0x89BD, 0xE655, 0x89BF, 0xE656, 0x89C0, 0xE657, 0x89DA, + 0xE658, 0x89DC, 0xE659, 0x89DD, 0xE65A, 0x89E7, 0xE65B, 0x89F4, + 0xE65C, 0x89F8, 0xE65D, 0x8A03, 0xE65E, 0x8A16, 0xE65F, 0x8A10, + 0xE660, 0x8A0C, 0xE661, 0x8A1B, 0xE662, 0x8A1D, 0xE663, 0x8A25, + 0xE664, 0x8A36, 0xE665, 0x8A41, 0xE666, 0x8A5B, 0xE667, 0x8A52, + 0xE668, 0x8A46, 0xE669, 0x8A48, 0xE66A, 0x8A7C, 0xE66B, 0x8A6D, + 0xE66C, 0x8A6C, 0xE66D, 0x8A62, 0xE66E, 0x8A85, 0xE66F, 0x8A82, + 0xE670, 0x8A84, 0xE671, 0x8AA8, 0xE672, 0x8AA1, 0xE673, 0x8A91, + 0xE674, 0x8AA5, 0xE675, 0x8AA6, 0xE676, 0x8A9A, 0xE677, 0x8AA3, + 0xE678, 0x8AC4, 0xE679, 0x8ACD, 0xE67A, 0x8AC2, 0xE67B, 0x8ADA, + 0xE67C, 0x8AEB, 0xE67D, 0x8AF3, 0xE67E, 0x8AE7, 0xE680, 0x8AE4, + 0xE681, 0x8AF1, 0xE682, 0x8B14, 0xE683, 0x8AE0, 0xE684, 0x8AE2, + 0xE685, 0x8AF7, 0xE686, 0x8ADE, 0xE687, 0x8ADB, 0xE688, 0x8B0C, + 0xE689, 0x8B07, 0xE68A, 0x8B1A, 0xE68B, 0x8AE1, 0xE68C, 0x8B16, + 0xE68D, 0x8B10, 0xE68E, 0x8B17, 0xE68F, 0x8B20, 0xE690, 0x8B33, + 0xE691, 0x97AB, 0xE692, 0x8B26, 0xE693, 0x8B2B, 0xE694, 0x8B3E, + 0xE695, 0x8B28, 0xE696, 0x8B41, 0xE697, 0x8B4C, 0xE698, 0x8B4F, + 0xE699, 0x8B4E, 0xE69A, 0x8B49, 0xE69B, 0x8B56, 0xE69C, 0x8B5B, + 0xE69D, 0x8B5A, 0xE69E, 0x8B6B, 0xE69F, 0x8B5F, 0xE6A0, 0x8B6C, + 0xE6A1, 0x8B6F, 0xE6A2, 0x8B74, 0xE6A3, 0x8B7D, 0xE6A4, 0x8B80, + 0xE6A5, 0x8B8C, 0xE6A6, 0x8B8E, 0xE6A7, 0x8B92, 0xE6A8, 0x8B93, + 0xE6A9, 0x8B96, 0xE6AA, 0x8B99, 0xE6AB, 0x8B9A, 0xE6AC, 0x8C3A, + 0xE6AD, 0x8C41, 0xE6AE, 0x8C3F, 0xE6AF, 0x8C48, 0xE6B0, 0x8C4C, + 0xE6B1, 0x8C4E, 0xE6B2, 0x8C50, 0xE6B3, 0x8C55, 0xE6B4, 0x8C62, + 0xE6B5, 0x8C6C, 0xE6B6, 0x8C78, 0xE6B7, 0x8C7A, 0xE6B8, 0x8C82, + 0xE6B9, 0x8C89, 0xE6BA, 0x8C85, 0xE6BB, 0x8C8A, 0xE6BC, 0x8C8D, + 0xE6BD, 0x8C8E, 0xE6BE, 0x8C94, 0xE6BF, 0x8C7C, 0xE6C0, 0x8C98, + 0xE6C1, 0x621D, 0xE6C2, 0x8CAD, 0xE6C3, 0x8CAA, 0xE6C4, 0x8CBD, + 0xE6C5, 0x8CB2, 0xE6C6, 0x8CB3, 0xE6C7, 0x8CAE, 0xE6C8, 0x8CB6, + 0xE6C9, 0x8CC8, 0xE6CA, 0x8CC1, 0xE6CB, 0x8CE4, 0xE6CC, 0x8CE3, + 0xE6CD, 0x8CDA, 0xE6CE, 0x8CFD, 0xE6CF, 0x8CFA, 0xE6D0, 0x8CFB, + 0xE6D1, 0x8D04, 0xE6D2, 0x8D05, 0xE6D3, 0x8D0A, 0xE6D4, 0x8D07, + 0xE6D5, 0x8D0F, 0xE6D6, 0x8D0D, 0xE6D7, 0x8D10, 0xE6D8, 0x9F4E, + 0xE6D9, 0x8D13, 0xE6DA, 0x8CCD, 0xE6DB, 0x8D14, 0xE6DC, 0x8D16, + 0xE6DD, 0x8D67, 0xE6DE, 0x8D6D, 0xE6DF, 0x8D71, 0xE6E0, 0x8D73, + 0xE6E1, 0x8D81, 0xE6E2, 0x8D99, 0xE6E3, 0x8DC2, 0xE6E4, 0x8DBE, + 0xE6E5, 0x8DBA, 0xE6E6, 0x8DCF, 0xE6E7, 0x8DDA, 0xE6E8, 0x8DD6, + 0xE6E9, 0x8DCC, 0xE6EA, 0x8DDB, 0xE6EB, 0x8DCB, 0xE6EC, 0x8DEA, + 0xE6ED, 0x8DEB, 0xE6EE, 0x8DDF, 0xE6EF, 0x8DE3, 0xE6F0, 0x8DFC, + 0xE6F1, 0x8E08, 0xE6F2, 0x8E09, 0xE6F3, 0x8DFF, 0xE6F4, 0x8E1D, + 0xE6F5, 0x8E1E, 0xE6F6, 0x8E10, 0xE6F7, 0x8E1F, 0xE6F8, 0x8E42, + 0xE6F9, 0x8E35, 0xE6FA, 0x8E30, 0xE6FB, 0x8E34, 0xE6FC, 0x8E4A, + 0xE740, 0x8E47, 0xE741, 0x8E49, 0xE742, 0x8E4C, 0xE743, 0x8E50, + 0xE744, 0x8E48, 0xE745, 0x8E59, 0xE746, 0x8E64, 0xE747, 0x8E60, + 0xE748, 0x8E2A, 0xE749, 0x8E63, 0xE74A, 0x8E55, 0xE74B, 0x8E76, + 0xE74C, 0x8E72, 0xE74D, 0x8E7C, 0xE74E, 0x8E81, 0xE74F, 0x8E87, + 0xE750, 0x8E85, 0xE751, 0x8E84, 0xE752, 0x8E8B, 0xE753, 0x8E8A, + 0xE754, 0x8E93, 0xE755, 0x8E91, 0xE756, 0x8E94, 0xE757, 0x8E99, + 0xE758, 0x8EAA, 0xE759, 0x8EA1, 0xE75A, 0x8EAC, 0xE75B, 0x8EB0, + 0xE75C, 0x8EC6, 0xE75D, 0x8EB1, 0xE75E, 0x8EBE, 0xE75F, 0x8EC5, + 0xE760, 0x8EC8, 0xE761, 0x8ECB, 0xE762, 0x8EDB, 0xE763, 0x8EE3, + 0xE764, 0x8EFC, 0xE765, 0x8EFB, 0xE766, 0x8EEB, 0xE767, 0x8EFE, + 0xE768, 0x8F0A, 0xE769, 0x8F05, 0xE76A, 0x8F15, 0xE76B, 0x8F12, + 0xE76C, 0x8F19, 0xE76D, 0x8F13, 0xE76E, 0x8F1C, 0xE76F, 0x8F1F, + 0xE770, 0x8F1B, 0xE771, 0x8F0C, 0xE772, 0x8F26, 0xE773, 0x8F33, + 0xE774, 0x8F3B, 0xE775, 0x8F39, 0xE776, 0x8F45, 0xE777, 0x8F42, + 0xE778, 0x8F3E, 0xE779, 0x8F4C, 0xE77A, 0x8F49, 0xE77B, 0x8F46, + 0xE77C, 0x8F4E, 0xE77D, 0x8F57, 0xE77E, 0x8F5C, 0xE780, 0x8F62, + 0xE781, 0x8F63, 0xE782, 0x8F64, 0xE783, 0x8F9C, 0xE784, 0x8F9F, + 0xE785, 0x8FA3, 0xE786, 0x8FAD, 0xE787, 0x8FAF, 0xE788, 0x8FB7, + 0xE789, 0x8FDA, 0xE78A, 0x8FE5, 0xE78B, 0x8FE2, 0xE78C, 0x8FEA, + 0xE78D, 0x8FEF, 0xE78E, 0x9087, 0xE78F, 0x8FF4, 0xE790, 0x9005, + 0xE791, 0x8FF9, 0xE792, 0x8FFA, 0xE793, 0x9011, 0xE794, 0x9015, + 0xE795, 0x9021, 0xE796, 0x900D, 0xE797, 0x901E, 0xE798, 0x9016, + 0xE799, 0x900B, 0xE79A, 0x9027, 0xE79B, 0x9036, 0xE79C, 0x9035, + 0xE79D, 0x9039, 0xE79E, 0x8FF8, 0xE79F, 0x904F, 0xE7A0, 0x9050, + 0xE7A1, 0x9051, 0xE7A2, 0x9052, 0xE7A3, 0x900E, 0xE7A4, 0x9049, + 0xE7A5, 0x903E, 0xE7A6, 0x9056, 0xE7A7, 0x9058, 0xE7A8, 0x905E, + 0xE7A9, 0x9068, 0xE7AA, 0x906F, 0xE7AB, 0x9076, 0xE7AC, 0x96A8, + 0xE7AD, 0x9072, 0xE7AE, 0x9082, 0xE7AF, 0x907D, 0xE7B0, 0x9081, + 0xE7B1, 0x9080, 0xE7B2, 0x908A, 0xE7B3, 0x9089, 0xE7B4, 0x908F, + 0xE7B5, 0x90A8, 0xE7B6, 0x90AF, 0xE7B7, 0x90B1, 0xE7B8, 0x90B5, + 0xE7B9, 0x90E2, 0xE7BA, 0x90E4, 0xE7BB, 0x6248, 0xE7BC, 0x90DB, + 0xE7BD, 0x9102, 0xE7BE, 0x9112, 0xE7BF, 0x9119, 0xE7C0, 0x9132, + 0xE7C1, 0x9130, 0xE7C2, 0x914A, 0xE7C3, 0x9156, 0xE7C4, 0x9158, + 0xE7C5, 0x9163, 0xE7C6, 0x9165, 0xE7C7, 0x9169, 0xE7C8, 0x9173, + 0xE7C9, 0x9172, 0xE7CA, 0x918B, 0xE7CB, 0x9189, 0xE7CC, 0x9182, + 0xE7CD, 0x91A2, 0xE7CE, 0x91AB, 0xE7CF, 0x91AF, 0xE7D0, 0x91AA, + 0xE7D1, 0x91B5, 0xE7D2, 0x91B4, 0xE7D3, 0x91BA, 0xE7D4, 0x91C0, + 0xE7D5, 0x91C1, 0xE7D6, 0x91C9, 0xE7D7, 0x91CB, 0xE7D8, 0x91D0, + 0xE7D9, 0x91D6, 0xE7DA, 0x91DF, 0xE7DB, 0x91E1, 0xE7DC, 0x91DB, + 0xE7DD, 0x91FC, 0xE7DE, 0x91F5, 0xE7DF, 0x91F6, 0xE7E0, 0x921E, + 0xE7E1, 0x91FF, 0xE7E2, 0x9214, 0xE7E3, 0x922C, 0xE7E4, 0x9215, + 0xE7E5, 0x9211, 0xE7E6, 0x925E, 0xE7E7, 0x9257, 0xE7E8, 0x9245, + 0xE7E9, 0x9249, 0xE7EA, 0x9264, 0xE7EB, 0x9248, 0xE7EC, 0x9295, + 0xE7ED, 0x923F, 0xE7EE, 0x924B, 0xE7EF, 0x9250, 0xE7F0, 0x929C, + 0xE7F1, 0x9296, 0xE7F2, 0x9293, 0xE7F3, 0x929B, 0xE7F4, 0x925A, + 0xE7F5, 0x92CF, 0xE7F6, 0x92B9, 0xE7F7, 0x92B7, 0xE7F8, 0x92E9, + 0xE7F9, 0x930F, 0xE7FA, 0x92FA, 0xE7FB, 0x9344, 0xE7FC, 0x932E, + 0xE840, 0x9319, 0xE841, 0x9322, 0xE842, 0x931A, 0xE843, 0x9323, + 0xE844, 0x933A, 0xE845, 0x9335, 0xE846, 0x933B, 0xE847, 0x935C, + 0xE848, 0x9360, 0xE849, 0x937C, 0xE84A, 0x936E, 0xE84B, 0x9356, + 0xE84C, 0x93B0, 0xE84D, 0x93AC, 0xE84E, 0x93AD, 0xE84F, 0x9394, + 0xE850, 0x93B9, 0xE851, 0x93D6, 0xE852, 0x93D7, 0xE853, 0x93E8, + 0xE854, 0x93E5, 0xE855, 0x93D8, 0xE856, 0x93C3, 0xE857, 0x93DD, + 0xE858, 0x93D0, 0xE859, 0x93C8, 0xE85A, 0x93E4, 0xE85B, 0x941A, + 0xE85C, 0x9414, 0xE85D, 0x9413, 0xE85E, 0x9403, 0xE85F, 0x9407, + 0xE860, 0x9410, 0xE861, 0x9436, 0xE862, 0x942B, 0xE863, 0x9435, + 0xE864, 0x9421, 0xE865, 0x943A, 0xE866, 0x9441, 0xE867, 0x9452, + 0xE868, 0x9444, 0xE869, 0x945B, 0xE86A, 0x9460, 0xE86B, 0x9462, + 0xE86C, 0x945E, 0xE86D, 0x946A, 0xE86E, 0x9229, 0xE86F, 0x9470, + 0xE870, 0x9475, 0xE871, 0x9477, 0xE872, 0x947D, 0xE873, 0x945A, + 0xE874, 0x947C, 0xE875, 0x947E, 0xE876, 0x9481, 0xE877, 0x947F, + 0xE878, 0x9582, 0xE879, 0x9587, 0xE87A, 0x958A, 0xE87B, 0x9594, + 0xE87C, 0x9596, 0xE87D, 0x9598, 0xE87E, 0x9599, 0xE880, 0x95A0, + 0xE881, 0x95A8, 0xE882, 0x95A7, 0xE883, 0x95AD, 0xE884, 0x95BC, + 0xE885, 0x95BB, 0xE886, 0x95B9, 0xE887, 0x95BE, 0xE888, 0x95CA, + 0xE889, 0x6FF6, 0xE88A, 0x95C3, 0xE88B, 0x95CD, 0xE88C, 0x95CC, + 0xE88D, 0x95D5, 0xE88E, 0x95D4, 0xE88F, 0x95D6, 0xE890, 0x95DC, + 0xE891, 0x95E1, 0xE892, 0x95E5, 0xE893, 0x95E2, 0xE894, 0x9621, + 0xE895, 0x9628, 0xE896, 0x962E, 0xE897, 0x962F, 0xE898, 0x9642, + 0xE899, 0x964C, 0xE89A, 0x964F, 0xE89B, 0x964B, 0xE89C, 0x9677, + 0xE89D, 0x965C, 0xE89E, 0x965E, 0xE89F, 0x965D, 0xE8A0, 0x965F, + 0xE8A1, 0x9666, 0xE8A2, 0x9672, 0xE8A3, 0x966C, 0xE8A4, 0x968D, + 0xE8A5, 0x9698, 0xE8A6, 0x9695, 0xE8A7, 0x9697, 0xE8A8, 0x96AA, + 0xE8A9, 0x96A7, 0xE8AA, 0x96B1, 0xE8AB, 0x96B2, 0xE8AC, 0x96B0, + 0xE8AD, 0x96B4, 0xE8AE, 0x96B6, 0xE8AF, 0x96B8, 0xE8B0, 0x96B9, + 0xE8B1, 0x96CE, 0xE8B2, 0x96CB, 0xE8B3, 0x96C9, 0xE8B4, 0x96CD, + 0xE8B5, 0x894D, 0xE8B6, 0x96DC, 0xE8B7, 0x970D, 0xE8B8, 0x96D5, + 0xE8B9, 0x96F9, 0xE8BA, 0x9704, 0xE8BB, 0x9706, 0xE8BC, 0x9708, + 0xE8BD, 0x9713, 0xE8BE, 0x970E, 0xE8BF, 0x9711, 0xE8C0, 0x970F, + 0xE8C1, 0x9716, 0xE8C2, 0x9719, 0xE8C3, 0x9724, 0xE8C4, 0x972A, + 0xE8C5, 0x9730, 0xE8C6, 0x9739, 0xE8C7, 0x973D, 0xE8C8, 0x973E, + 0xE8C9, 0x9744, 0xE8CA, 0x9746, 0xE8CB, 0x9748, 0xE8CC, 0x9742, + 0xE8CD, 0x9749, 0xE8CE, 0x975C, 0xE8CF, 0x9760, 0xE8D0, 0x9764, + 0xE8D1, 0x9766, 0xE8D2, 0x9768, 0xE8D3, 0x52D2, 0xE8D4, 0x976B, + 0xE8D5, 0x9771, 0xE8D6, 0x9779, 0xE8D7, 0x9785, 0xE8D8, 0x977C, + 0xE8D9, 0x9781, 0xE8DA, 0x977A, 0xE8DB, 0x9786, 0xE8DC, 0x978B, + 0xE8DD, 0x978F, 0xE8DE, 0x9790, 0xE8DF, 0x979C, 0xE8E0, 0x97A8, + 0xE8E1, 0x97A6, 0xE8E2, 0x97A3, 0xE8E3, 0x97B3, 0xE8E4, 0x97B4, + 0xE8E5, 0x97C3, 0xE8E6, 0x97C6, 0xE8E7, 0x97C8, 0xE8E8, 0x97CB, + 0xE8E9, 0x97DC, 0xE8EA, 0x97ED, 0xE8EB, 0x9F4F, 0xE8EC, 0x97F2, + 0xE8ED, 0x7ADF, 0xE8EE, 0x97F6, 0xE8EF, 0x97F5, 0xE8F0, 0x980F, + 0xE8F1, 0x980C, 0xE8F2, 0x9838, 0xE8F3, 0x9824, 0xE8F4, 0x9821, + 0xE8F5, 0x9837, 0xE8F6, 0x983D, 0xE8F7, 0x9846, 0xE8F8, 0x984F, + 0xE8F9, 0x984B, 0xE8FA, 0x986B, 0xE8FB, 0x986F, 0xE8FC, 0x9870, + 0xE940, 0x9871, 0xE941, 0x9874, 0xE942, 0x9873, 0xE943, 0x98AA, + 0xE944, 0x98AF, 0xE945, 0x98B1, 0xE946, 0x98B6, 0xE947, 0x98C4, + 0xE948, 0x98C3, 0xE949, 0x98C6, 0xE94A, 0x98E9, 0xE94B, 0x98EB, + 0xE94C, 0x9903, 0xE94D, 0x9909, 0xE94E, 0x9912, 0xE94F, 0x9914, + 0xE950, 0x9918, 0xE951, 0x9921, 0xE952, 0x991D, 0xE953, 0x991E, + 0xE954, 0x9924, 0xE955, 0x9920, 0xE956, 0x992C, 0xE957, 0x992E, + 0xE958, 0x993D, 0xE959, 0x993E, 0xE95A, 0x9942, 0xE95B, 0x9949, + 0xE95C, 0x9945, 0xE95D, 0x9950, 0xE95E, 0x994B, 0xE95F, 0x9951, + 0xE960, 0x9952, 0xE961, 0x994C, 0xE962, 0x9955, 0xE963, 0x9997, + 0xE964, 0x9998, 0xE965, 0x99A5, 0xE966, 0x99AD, 0xE967, 0x99AE, + 0xE968, 0x99BC, 0xE969, 0x99DF, 0xE96A, 0x99DB, 0xE96B, 0x99DD, + 0xE96C, 0x99D8, 0xE96D, 0x99D1, 0xE96E, 0x99ED, 0xE96F, 0x99EE, + 0xE970, 0x99F1, 0xE971, 0x99F2, 0xE972, 0x99FB, 0xE973, 0x99F8, + 0xE974, 0x9A01, 0xE975, 0x9A0F, 0xE976, 0x9A05, 0xE977, 0x99E2, + 0xE978, 0x9A19, 0xE979, 0x9A2B, 0xE97A, 0x9A37, 0xE97B, 0x9A45, + 0xE97C, 0x9A42, 0xE97D, 0x9A40, 0xE97E, 0x9A43, 0xE980, 0x9A3E, + 0xE981, 0x9A55, 0xE982, 0x9A4D, 0xE983, 0x9A5B, 0xE984, 0x9A57, + 0xE985, 0x9A5F, 0xE986, 0x9A62, 0xE987, 0x9A65, 0xE988, 0x9A64, + 0xE989, 0x9A69, 0xE98A, 0x9A6B, 0xE98B, 0x9A6A, 0xE98C, 0x9AAD, + 0xE98D, 0x9AB0, 0xE98E, 0x9ABC, 0xE98F, 0x9AC0, 0xE990, 0x9ACF, + 0xE991, 0x9AD1, 0xE992, 0x9AD3, 0xE993, 0x9AD4, 0xE994, 0x9ADE, + 0xE995, 0x9ADF, 0xE996, 0x9AE2, 0xE997, 0x9AE3, 0xE998, 0x9AE6, + 0xE999, 0x9AEF, 0xE99A, 0x9AEB, 0xE99B, 0x9AEE, 0xE99C, 0x9AF4, + 0xE99D, 0x9AF1, 0xE99E, 0x9AF7, 0xE99F, 0x9AFB, 0xE9A0, 0x9B06, + 0xE9A1, 0x9B18, 0xE9A2, 0x9B1A, 0xE9A3, 0x9B1F, 0xE9A4, 0x9B22, + 0xE9A5, 0x9B23, 0xE9A6, 0x9B25, 0xE9A7, 0x9B27, 0xE9A8, 0x9B28, + 0xE9A9, 0x9B29, 0xE9AA, 0x9B2A, 0xE9AB, 0x9B2E, 0xE9AC, 0x9B2F, + 0xE9AD, 0x9B32, 0xE9AE, 0x9B44, 0xE9AF, 0x9B43, 0xE9B0, 0x9B4F, + 0xE9B1, 0x9B4D, 0xE9B2, 0x9B4E, 0xE9B3, 0x9B51, 0xE9B4, 0x9B58, + 0xE9B5, 0x9B74, 0xE9B6, 0x9B93, 0xE9B7, 0x9B83, 0xE9B8, 0x9B91, + 0xE9B9, 0x9B96, 0xE9BA, 0x9B97, 0xE9BB, 0x9B9F, 0xE9BC, 0x9BA0, + 0xE9BD, 0x9BA8, 0xE9BE, 0x9BB4, 0xE9BF, 0x9BC0, 0xE9C0, 0x9BCA, + 0xE9C1, 0x9BB9, 0xE9C2, 0x9BC6, 0xE9C3, 0x9BCF, 0xE9C4, 0x9BD1, + 0xE9C5, 0x9BD2, 0xE9C6, 0x9BE3, 0xE9C7, 0x9BE2, 0xE9C8, 0x9BE4, + 0xE9C9, 0x9BD4, 0xE9CA, 0x9BE1, 0xE9CB, 0x9C3A, 0xE9CC, 0x9BF2, + 0xE9CD, 0x9BF1, 0xE9CE, 0x9BF0, 0xE9CF, 0x9C15, 0xE9D0, 0x9C14, + 0xE9D1, 0x9C09, 0xE9D2, 0x9C13, 0xE9D3, 0x9C0C, 0xE9D4, 0x9C06, + 0xE9D5, 0x9C08, 0xE9D6, 0x9C12, 0xE9D7, 0x9C0A, 0xE9D8, 0x9C04, + 0xE9D9, 0x9C2E, 0xE9DA, 0x9C1B, 0xE9DB, 0x9C25, 0xE9DC, 0x9C24, + 0xE9DD, 0x9C21, 0xE9DE, 0x9C30, 0xE9DF, 0x9C47, 0xE9E0, 0x9C32, + 0xE9E1, 0x9C46, 0xE9E2, 0x9C3E, 0xE9E3, 0x9C5A, 0xE9E4, 0x9C60, + 0xE9E5, 0x9C67, 0xE9E6, 0x9C76, 0xE9E7, 0x9C78, 0xE9E8, 0x9CE7, + 0xE9E9, 0x9CEC, 0xE9EA, 0x9CF0, 0xE9EB, 0x9D09, 0xE9EC, 0x9D08, + 0xE9ED, 0x9CEB, 0xE9EE, 0x9D03, 0xE9EF, 0x9D06, 0xE9F0, 0x9D2A, + 0xE9F1, 0x9D26, 0xE9F2, 0x9DAF, 0xE9F3, 0x9D23, 0xE9F4, 0x9D1F, + 0xE9F5, 0x9D44, 0xE9F6, 0x9D15, 0xE9F7, 0x9D12, 0xE9F8, 0x9D41, + 0xE9F9, 0x9D3F, 0xE9FA, 0x9D3E, 0xE9FB, 0x9D46, 0xE9FC, 0x9D48, + 0xEA40, 0x9D5D, 0xEA41, 0x9D5E, 0xEA42, 0x9D64, 0xEA43, 0x9D51, + 0xEA44, 0x9D50, 0xEA45, 0x9D59, 0xEA46, 0x9D72, 0xEA47, 0x9D89, + 0xEA48, 0x9D87, 0xEA49, 0x9DAB, 0xEA4A, 0x9D6F, 0xEA4B, 0x9D7A, + 0xEA4C, 0x9D9A, 0xEA4D, 0x9DA4, 0xEA4E, 0x9DA9, 0xEA4F, 0x9DB2, + 0xEA50, 0x9DC4, 0xEA51, 0x9DC1, 0xEA52, 0x9DBB, 0xEA53, 0x9DB8, + 0xEA54, 0x9DBA, 0xEA55, 0x9DC6, 0xEA56, 0x9DCF, 0xEA57, 0x9DC2, + 0xEA58, 0x9DD9, 0xEA59, 0x9DD3, 0xEA5A, 0x9DF8, 0xEA5B, 0x9DE6, + 0xEA5C, 0x9DED, 0xEA5D, 0x9DEF, 0xEA5E, 0x9DFD, 0xEA5F, 0x9E1A, + 0xEA60, 0x9E1B, 0xEA61, 0x9E1E, 0xEA62, 0x9E75, 0xEA63, 0x9E79, + 0xEA64, 0x9E7D, 0xEA65, 0x9E81, 0xEA66, 0x9E88, 0xEA67, 0x9E8B, + 0xEA68, 0x9E8C, 0xEA69, 0x9E92, 0xEA6A, 0x9E95, 0xEA6B, 0x9E91, + 0xEA6C, 0x9E9D, 0xEA6D, 0x9EA5, 0xEA6E, 0x9EA9, 0xEA6F, 0x9EB8, + 0xEA70, 0x9EAA, 0xEA71, 0x9EAD, 0xEA72, 0x9761, 0xEA73, 0x9ECC, + 0xEA74, 0x9ECE, 0xEA75, 0x9ECF, 0xEA76, 0x9ED0, 0xEA77, 0x9ED4, + 0xEA78, 0x9EDC, 0xEA79, 0x9EDE, 0xEA7A, 0x9EDD, 0xEA7B, 0x9EE0, + 0xEA7C, 0x9EE5, 0xEA7D, 0x9EE8, 0xEA7E, 0x9EEF, 0xEA80, 0x9EF4, + 0xEA81, 0x9EF6, 0xEA82, 0x9EF7, 0xEA83, 0x9EF9, 0xEA84, 0x9EFB, + 0xEA85, 0x9EFC, 0xEA86, 0x9EFD, 0xEA87, 0x9F07, 0xEA88, 0x9F08, + 0xEA89, 0x76B7, 0xEA8A, 0x9F15, 0xEA8B, 0x9F21, 0xEA8C, 0x9F2C, + 0xEA8D, 0x9F3E, 0xEA8E, 0x9F4A, 0xEA8F, 0x9F52, 0xEA90, 0x9F54, + 0xEA91, 0x9F63, 0xEA92, 0x9F5F, 0xEA93, 0x9F60, 0xEA94, 0x9F61, + 0xEA95, 0x9F66, 0xEA96, 0x9F67, 0xEA97, 0x9F6C, 0xEA98, 0x9F6A, + 0xEA99, 0x9F77, 0xEA9A, 0x9F72, 0xEA9B, 0x9F76, 0xEA9C, 0x9F95, + 0xEA9D, 0x9F9C, 0xEA9E, 0x9FA0, 0xEA9F, 0x582F, 0xEAA0, 0x69C7, + 0xEAA1, 0x9059, 0xEAA2, 0x7464, 0xEAA3, 0x51DC, 0xEAA4, 0x7199, + 0xFA40, 0x2170, 0xFA41, 0x2171, 0xFA42, 0x2172, 0xFA43, 0x2173, + 0xFA44, 0x2174, 0xFA45, 0x2175, 0xFA46, 0x2176, 0xFA47, 0x2177, + 0xFA48, 0x2178, 0xFA49, 0x2179, 0xFA55, 0xFFE4, 0xFA56, 0xFF07, + 0xFA57, 0xFF02, 0xFA5C, 0x7E8A, 0xFA5D, 0x891C, 0xFA5E, 0x9348, + 0xFA5F, 0x9288, 0xFA60, 0x84DC, 0xFA61, 0x4FC9, 0xFA62, 0x70BB, + 0xFA63, 0x6631, 0xFA64, 0x68C8, 0xFA65, 0x92F9, 0xFA66, 0x66FB, + 0xFA67, 0x5F45, 0xFA68, 0x4E28, 0xFA69, 0x4EE1, 0xFA6A, 0x4EFC, + 0xFA6B, 0x4F00, 0xFA6C, 0x4F03, 0xFA6D, 0x4F39, 0xFA6E, 0x4F56, + 0xFA6F, 0x4F92, 0xFA70, 0x4F8A, 0xFA71, 0x4F9A, 0xFA72, 0x4F94, + 0xFA73, 0x4FCD, 0xFA74, 0x5040, 0xFA75, 0x5022, 0xFA76, 0x4FFF, + 0xFA77, 0x501E, 0xFA78, 0x5046, 0xFA79, 0x5070, 0xFA7A, 0x5042, + 0xFA7B, 0x5094, 0xFA7C, 0x50F4, 0xFA7D, 0x50D8, 0xFA7E, 0x514A, + 0xFA80, 0x5164, 0xFA81, 0x519D, 0xFA82, 0x51BE, 0xFA83, 0x51EC, + 0xFA84, 0x5215, 0xFA85, 0x529C, 0xFA86, 0x52A6, 0xFA87, 0x52C0, + 0xFA88, 0x52DB, 0xFA89, 0x5300, 0xFA8A, 0x5307, 0xFA8B, 0x5324, + 0xFA8C, 0x5372, 0xFA8D, 0x5393, 0xFA8E, 0x53B2, 0xFA8F, 0x53DD, + 0xFA90, 0xFA0E, 0xFA91, 0x549C, 0xFA92, 0x548A, 0xFA93, 0x54A9, + 0xFA94, 0x54FF, 0xFA95, 0x5586, 0xFA96, 0x5759, 0xFA97, 0x5765, + 0xFA98, 0x57AC, 0xFA99, 0x57C8, 0xFA9A, 0x57C7, 0xFA9B, 0xFA0F, + 0xFA9C, 0xFA10, 0xFA9D, 0x589E, 0xFA9E, 0x58B2, 0xFA9F, 0x590B, + 0xFAA0, 0x5953, 0xFAA1, 0x595B, 0xFAA2, 0x595D, 0xFAA3, 0x5963, + 0xFAA4, 0x59A4, 0xFAA5, 0x59BA, 0xFAA6, 0x5B56, 0xFAA7, 0x5BC0, + 0xFAA8, 0x752F, 0xFAA9, 0x5BD8, 0xFAAA, 0x5BEC, 0xFAAB, 0x5C1E, + 0xFAAC, 0x5CA6, 0xFAAD, 0x5CBA, 0xFAAE, 0x5CF5, 0xFAAF, 0x5D27, + 0xFAB0, 0x5D53, 0xFAB1, 0xFA11, 0xFAB2, 0x5D42, 0xFAB3, 0x5D6D, + 0xFAB4, 0x5DB8, 0xFAB5, 0x5DB9, 0xFAB6, 0x5DD0, 0xFAB7, 0x5F21, + 0xFAB8, 0x5F34, 0xFAB9, 0x5F67, 0xFABA, 0x5FB7, 0xFABB, 0x5FDE, + 0xFABC, 0x605D, 0xFABD, 0x6085, 0xFABE, 0x608A, 0xFABF, 0x60DE, + 0xFAC0, 0x60D5, 0xFAC1, 0x6120, 0xFAC2, 0x60F2, 0xFAC3, 0x6111, + 0xFAC4, 0x6137, 0xFAC5, 0x6130, 0xFAC6, 0x6198, 0xFAC7, 0x6213, + 0xFAC8, 0x62A6, 0xFAC9, 0x63F5, 0xFACA, 0x6460, 0xFACB, 0x649D, + 0xFACC, 0x64CE, 0xFACD, 0x654E, 0xFACE, 0x6600, 0xFACF, 0x6615, + 0xFAD0, 0x663B, 0xFAD1, 0x6609, 0xFAD2, 0x662E, 0xFAD3, 0x661E, + 0xFAD4, 0x6624, 0xFAD5, 0x6665, 0xFAD6, 0x6657, 0xFAD7, 0x6659, + 0xFAD8, 0xFA12, 0xFAD9, 0x6673, 0xFADA, 0x6699, 0xFADB, 0x66A0, + 0xFADC, 0x66B2, 0xFADD, 0x66BF, 0xFADE, 0x66FA, 0xFADF, 0x670E, + 0xFAE0, 0xF929, 0xFAE1, 0x6766, 0xFAE2, 0x67BB, 0xFAE3, 0x6852, + 0xFAE4, 0x67C0, 0xFAE5, 0x6801, 0xFAE6, 0x6844, 0xFAE7, 0x68CF, + 0xFAE8, 0xFA13, 0xFAE9, 0x6968, 0xFAEA, 0xFA14, 0xFAEB, 0x6998, + 0xFAEC, 0x69E2, 0xFAED, 0x6A30, 0xFAEE, 0x6A6B, 0xFAEF, 0x6A46, + 0xFAF0, 0x6A73, 0xFAF1, 0x6A7E, 0xFAF2, 0x6AE2, 0xFAF3, 0x6AE4, + 0xFAF4, 0x6BD6, 0xFAF5, 0x6C3F, 0xFAF6, 0x6C5C, 0xFAF7, 0x6C86, + 0xFAF8, 0x6C6F, 0xFAF9, 0x6CDA, 0xFAFA, 0x6D04, 0xFAFB, 0x6D87, + 0xFAFC, 0x6D6F, 0xFB40, 0x6D96, 0xFB41, 0x6DAC, 0xFB42, 0x6DCF, + 0xFB43, 0x6DF8, 0xFB44, 0x6DF2, 0xFB45, 0x6DFC, 0xFB46, 0x6E39, + 0xFB47, 0x6E5C, 0xFB48, 0x6E27, 0xFB49, 0x6E3C, 0xFB4A, 0x6EBF, + 0xFB4B, 0x6F88, 0xFB4C, 0x6FB5, 0xFB4D, 0x6FF5, 0xFB4E, 0x7005, + 0xFB4F, 0x7007, 0xFB50, 0x7028, 0xFB51, 0x7085, 0xFB52, 0x70AB, + 0xFB53, 0x710F, 0xFB54, 0x7104, 0xFB55, 0x715C, 0xFB56, 0x7146, + 0xFB57, 0x7147, 0xFB58, 0xFA15, 0xFB59, 0x71C1, 0xFB5A, 0x71FE, + 0xFB5B, 0x72B1, 0xFB5C, 0x72BE, 0xFB5D, 0x7324, 0xFB5E, 0xFA16, + 0xFB5F, 0x7377, 0xFB60, 0x73BD, 0xFB61, 0x73C9, 0xFB62, 0x73D6, + 0xFB63, 0x73E3, 0xFB64, 0x73D2, 0xFB65, 0x7407, 0xFB66, 0x73F5, + 0xFB67, 0x7426, 0xFB68, 0x742A, 0xFB69, 0x7429, 0xFB6A, 0x742E, + 0xFB6B, 0x7462, 0xFB6C, 0x7489, 0xFB6D, 0x749F, 0xFB6E, 0x7501, + 0xFB6F, 0x756F, 0xFB70, 0x7682, 0xFB71, 0x769C, 0xFB72, 0x769E, + 0xFB73, 0x769B, 0xFB74, 0x76A6, 0xFB75, 0xFA17, 0xFB76, 0x7746, + 0xFB77, 0x52AF, 0xFB78, 0x7821, 0xFB79, 0x784E, 0xFB7A, 0x7864, + 0xFB7B, 0x787A, 0xFB7C, 0x7930, 0xFB7D, 0xFA18, 0xFB7E, 0xFA19, + 0xFB80, 0xFA1A, 0xFB81, 0x7994, 0xFB82, 0xFA1B, 0xFB83, 0x799B, + 0xFB84, 0x7AD1, 0xFB85, 0x7AE7, 0xFB86, 0xFA1C, 0xFB87, 0x7AEB, + 0xFB88, 0x7B9E, 0xFB89, 0xFA1D, 0xFB8A, 0x7D48, 0xFB8B, 0x7D5C, + 0xFB8C, 0x7DB7, 0xFB8D, 0x7DA0, 0xFB8E, 0x7DD6, 0xFB8F, 0x7E52, + 0xFB90, 0x7F47, 0xFB91, 0x7FA1, 0xFB92, 0xFA1E, 0xFB93, 0x8301, + 0xFB94, 0x8362, 0xFB95, 0x837F, 0xFB96, 0x83C7, 0xFB97, 0x83F6, + 0xFB98, 0x8448, 0xFB99, 0x84B4, 0xFB9A, 0x8553, 0xFB9B, 0x8559, + 0xFB9C, 0x856B, 0xFB9D, 0xFA1F, 0xFB9E, 0x85B0, 0xFB9F, 0xFA20, + 0xFBA0, 0xFA21, 0xFBA1, 0x8807, 0xFBA2, 0x88F5, 0xFBA3, 0x8A12, + 0xFBA4, 0x8A37, 0xFBA5, 0x8A79, 0xFBA6, 0x8AA7, 0xFBA7, 0x8ABE, + 0xFBA8, 0x8ADF, 0xFBA9, 0xFA22, 0xFBAA, 0x8AF6, 0xFBAB, 0x8B53, + 0xFBAC, 0x8B7F, 0xFBAD, 0x8CF0, 0xFBAE, 0x8CF4, 0xFBAF, 0x8D12, + 0xFBB0, 0x8D76, 0xFBB1, 0xFA23, 0xFBB2, 0x8ECF, 0xFBB3, 0xFA24, + 0xFBB4, 0xFA25, 0xFBB5, 0x9067, 0xFBB6, 0x90DE, 0xFBB7, 0xFA26, + 0xFBB8, 0x9115, 0xFBB9, 0x9127, 0xFBBA, 0x91DA, 0xFBBB, 0x91D7, + 0xFBBC, 0x91DE, 0xFBBD, 0x91ED, 0xFBBE, 0x91EE, 0xFBBF, 0x91E4, + 0xFBC0, 0x91E5, 0xFBC1, 0x9206, 0xFBC2, 0x9210, 0xFBC3, 0x920A, + 0xFBC4, 0x923A, 0xFBC5, 0x9240, 0xFBC6, 0x923C, 0xFBC7, 0x924E, + 0xFBC8, 0x9259, 0xFBC9, 0x9251, 0xFBCA, 0x9239, 0xFBCB, 0x9267, + 0xFBCC, 0x92A7, 0xFBCD, 0x9277, 0xFBCE, 0x9278, 0xFBCF, 0x92E7, + 0xFBD0, 0x92D7, 0xFBD1, 0x92D9, 0xFBD2, 0x92D0, 0xFBD3, 0xFA27, + 0xFBD4, 0x92D5, 0xFBD5, 0x92E0, 0xFBD6, 0x92D3, 0xFBD7, 0x9325, + 0xFBD8, 0x9321, 0xFBD9, 0x92FB, 0xFBDA, 0xFA28, 0xFBDB, 0x931E, + 0xFBDC, 0x92FF, 0xFBDD, 0x931D, 0xFBDE, 0x9302, 0xFBDF, 0x9370, + 0xFBE0, 0x9357, 0xFBE1, 0x93A4, 0xFBE2, 0x93C6, 0xFBE3, 0x93DE, + 0xFBE4, 0x93F8, 0xFBE5, 0x9431, 0xFBE6, 0x9445, 0xFBE7, 0x9448, + 0xFBE8, 0x9592, 0xFBE9, 0xF9DC, 0xFBEA, 0xFA29, 0xFBEB, 0x969D, + 0xFBEC, 0x96AF, 0xFBED, 0x9733, 0xFBEE, 0x973B, 0xFBEF, 0x9743, + 0xFBF0, 0x974D, 0xFBF1, 0x974F, 0xFBF2, 0x9751, 0xFBF3, 0x9755, + 0xFBF4, 0x9857, 0xFBF5, 0x9865, 0xFBF6, 0xFA2A, 0xFBF7, 0xFA2B, + 0xFBF8, 0x9927, 0xFBF9, 0xFA2C, 0xFBFA, 0x999E, 0xFBFB, 0x9A4E, + 0xFBFC, 0x9AD9, 0xFC40, 0x9ADC, 0xFC41, 0x9B75, 0xFC42, 0x9B72, + 0xFC43, 0x9B8F, 0xFC44, 0x9BB1, 0xFC45, 0x9BBB, 0xFC46, 0x9C00, + 0xFC47, 0x9D70, 0xFC48, 0x9D6B, 0xFC49, 0xFA2D, 0xFC4A, 0x9E19, + 0xFC4B, 0x9ED1, 0, 0 +}; +#endif + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (chr <= 0x80) { /* ASCII */ + c = chr; + } else { +#if !_TINY_TABLE + if (dir) { /* OEM code to unicode */ + p = sjis2uni; + hi = sizeof sjis2uni / 4 - 1; + } else { /* Unicode to OEM code */ + p = uni2sjis; + hi = sizeof uni2sjis / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (chr == p[i * 2]) break; + if (chr > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; +#else + if (dir) { /* OEM code to unicode (Incremental search)*/ + p = &uni2sjis[1]; + do { + c = *p; + p += 2; + } while (c && c != chr); + p -= 3; + c = *p; + } else { /* Unicode to OEM code */ + li = 0; hi = sizeof uni2sjis / 4 - 1; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (chr == uni2sjis[i * 2]) break; + if (chr > uni2sjis[i * 2]) + li = i; + else + hi = i; + } + c = n ? uni2sjis[i * 2 + 1] : 0; + } +#endif + } + + return c; +} + + + +WCHAR ff_wtoupper ( + WCHAR chr /* Unicode character to be upper converted */ +) +{ + static const WCHAR lower[] = { /* Lower case characters to be converted */ + /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, + /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E, + /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217, + /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB, + /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9, + /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586, + /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9, + /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A + }; + static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D, + 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216, + 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8, + 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556, + 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A + }; + UINT i, n, hi, li; + + + if (chr < 0x80) { /* ASCII characters (acceleration) */ + if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20; + + } else { /* Extended characters */ + n = 12; li = 0; hi = sizeof lower / sizeof lower[0]; + do { + i = li + (hi - li) / 2; + if (chr == lower[i]) break; + if (chr > lower[i]) li = i; else hi = i; + } while (--n); + if (n) chr = upper[i]; + } + + return chr; +} + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc936.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc936.c new file mode 100644 index 0000000..1a3da5d --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc936.c @@ -0,0 +1,11004 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */ +/* CP936 (Simplified Chinese GBK) */ +/*------------------------------------------------------------------------*/ + +#include "ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 936 +#error This file is not needed in current configuration. Remove from the project. +#endif + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A4, 0xA1E8, 0x00A7, 0xA1EC, 0x00A8, 0xA1A7, 0x00B0, 0xA1E3, + 0x00B1, 0xA1C0, 0x00B7, 0xA1A4, 0x00D7, 0xA1C1, 0x00E0, 0xA8A4, + 0x00E1, 0xA8A2, 0x00E8, 0xA8A8, 0x00E9, 0xA8A6, 0x00EA, 0xA8BA, + 0x00EC, 0xA8AC, 0x00ED, 0xA8AA, 0x00F2, 0xA8B0, 0x00F3, 0xA8AE, + 0x00F7, 0xA1C2, 0x00F9, 0xA8B4, 0x00FA, 0xA8B2, 0x00FC, 0xA8B9, + 0x0101, 0xA8A1, 0x0113, 0xA8A5, 0x011B, 0xA8A7, 0x012B, 0xA8A9, + 0x0144, 0xA8BD, 0x0148, 0xA8BE, 0x014D, 0xA8AD, 0x016B, 0xA8B1, + 0x01CE, 0xA8A3, 0x01D0, 0xA8AB, 0x01D2, 0xA8AF, 0x01D4, 0xA8B3, + 0x01D6, 0xA8B5, 0x01D8, 0xA8B6, 0x01DA, 0xA8B7, 0x01DC, 0xA8B8, + 0x0251, 0xA8BB, 0x0261, 0xA8C0, 0x02C7, 0xA1A6, 0x02C9, 0xA1A5, + 0x02CA, 0xA840, 0x02CB, 0xA841, 0x02D9, 0xA842, 0x0391, 0xA6A1, + 0x0392, 0xA6A2, 0x0393, 0xA6A3, 0x0394, 0xA6A4, 0x0395, 0xA6A5, + 0x0396, 0xA6A6, 0x0397, 0xA6A7, 0x0398, 0xA6A8, 0x0399, 0xA6A9, + 0x039A, 0xA6AA, 0x039B, 0xA6AB, 0x039C, 0xA6AC, 0x039D, 0xA6AD, + 0x039E, 0xA6AE, 0x039F, 0xA6AF, 0x03A0, 0xA6B0, 0x03A1, 0xA6B1, + 0x03A3, 0xA6B2, 0x03A4, 0xA6B3, 0x03A5, 0xA6B4, 0x03A6, 0xA6B5, + 0x03A7, 0xA6B6, 0x03A8, 0xA6B7, 0x03A9, 0xA6B8, 0x03B1, 0xA6C1, + 0x03B2, 0xA6C2, 0x03B3, 0xA6C3, 0x03B4, 0xA6C4, 0x03B5, 0xA6C5, + 0x03B6, 0xA6C6, 0x03B7, 0xA6C7, 0x03B8, 0xA6C8, 0x03B9, 0xA6C9, + 0x03BA, 0xA6CA, 0x03BB, 0xA6CB, 0x03BC, 0xA6CC, 0x03BD, 0xA6CD, + 0x03BE, 0xA6CE, 0x03BF, 0xA6CF, 0x03C0, 0xA6D0, 0x03C1, 0xA6D1, + 0x03C3, 0xA6D2, 0x03C4, 0xA6D3, 0x03C5, 0xA6D4, 0x03C6, 0xA6D5, + 0x03C7, 0xA6D6, 0x03C8, 0xA6D7, 0x03C9, 0xA6D8, 0x0401, 0xA7A7, + 0x0410, 0xA7A1, 0x0411, 0xA7A2, 0x0412, 0xA7A3, 0x0413, 0xA7A4, + 0x0414, 0xA7A5, 0x0415, 0xA7A6, 0x0416, 0xA7A8, 0x0417, 0xA7A9, + 0x0418, 0xA7AA, 0x0419, 0xA7AB, 0x041A, 0xA7AC, 0x041B, 0xA7AD, + 0x041C, 0xA7AE, 0x041D, 0xA7AF, 0x041E, 0xA7B0, 0x041F, 0xA7B1, + 0x0420, 0xA7B2, 0x0421, 0xA7B3, 0x0422, 0xA7B4, 0x0423, 0xA7B5, + 0x0424, 0xA7B6, 0x0425, 0xA7B7, 0x0426, 0xA7B8, 0x0427, 0xA7B9, + 0x0428, 0xA7BA, 0x0429, 0xA7BB, 0x042A, 0xA7BC, 0x042B, 0xA7BD, + 0x042C, 0xA7BE, 0x042D, 0xA7BF, 0x042E, 0xA7C0, 0x042F, 0xA7C1, + 0x0430, 0xA7D1, 0x0431, 0xA7D2, 0x0432, 0xA7D3, 0x0433, 0xA7D4, + 0x0434, 0xA7D5, 0x0435, 0xA7D6, 0x0436, 0xA7D8, 0x0437, 0xA7D9, + 0x0438, 0xA7DA, 0x0439, 0xA7DB, 0x043A, 0xA7DC, 0x043B, 0xA7DD, + 0x043C, 0xA7DE, 0x043D, 0xA7DF, 0x043E, 0xA7E0, 0x043F, 0xA7E1, + 0x0440, 0xA7E2, 0x0441, 0xA7E3, 0x0442, 0xA7E4, 0x0443, 0xA7E5, + 0x0444, 0xA7E6, 0x0445, 0xA7E7, 0x0446, 0xA7E8, 0x0447, 0xA7E9, + 0x0448, 0xA7EA, 0x0449, 0xA7EB, 0x044A, 0xA7EC, 0x044B, 0xA7ED, + 0x044C, 0xA7EE, 0x044D, 0xA7EF, 0x044E, 0xA7F0, 0x044F, 0xA7F1, + 0x0451, 0xA7D7, 0x2010, 0xA95C, 0x2013, 0xA843, 0x2014, 0xA1AA, + 0x2015, 0xA844, 0x2016, 0xA1AC, 0x2018, 0xA1AE, 0x2019, 0xA1AF, + 0x201C, 0xA1B0, 0x201D, 0xA1B1, 0x2025, 0xA845, 0x2026, 0xA1AD, + 0x2030, 0xA1EB, 0x2032, 0xA1E4, 0x2033, 0xA1E5, 0x2035, 0xA846, + 0x203B, 0xA1F9, 0x20AC, 0x0080, 0x2103, 0xA1E6, 0x2105, 0xA847, + 0x2109, 0xA848, 0x2116, 0xA1ED, 0x2121, 0xA959, 0x2160, 0xA2F1, + 0x2161, 0xA2F2, 0x2162, 0xA2F3, 0x2163, 0xA2F4, 0x2164, 0xA2F5, + 0x2165, 0xA2F6, 0x2166, 0xA2F7, 0x2167, 0xA2F8, 0x2168, 0xA2F9, + 0x2169, 0xA2FA, 0x216A, 0xA2FB, 0x216B, 0xA2FC, 0x2170, 0xA2A1, + 0x2171, 0xA2A2, 0x2172, 0xA2A3, 0x2173, 0xA2A4, 0x2174, 0xA2A5, + 0x2175, 0xA2A6, 0x2176, 0xA2A7, 0x2177, 0xA2A8, 0x2178, 0xA2A9, + 0x2179, 0xA2AA, 0x2190, 0xA1FB, 0x2191, 0xA1FC, 0x2192, 0xA1FA, + 0x2193, 0xA1FD, 0x2196, 0xA849, 0x2197, 0xA84A, 0x2198, 0xA84B, + 0x2199, 0xA84C, 0x2208, 0xA1CA, 0x220F, 0xA1C7, 0x2211, 0xA1C6, + 0x2215, 0xA84D, 0x221A, 0xA1CC, 0x221D, 0xA1D8, 0x221E, 0xA1DE, + 0x221F, 0xA84E, 0x2220, 0xA1CF, 0x2223, 0xA84F, 0x2225, 0xA1CE, + 0x2227, 0xA1C4, 0x2228, 0xA1C5, 0x2229, 0xA1C9, 0x222A, 0xA1C8, + 0x222B, 0xA1D2, 0x222E, 0xA1D3, 0x2234, 0xA1E0, 0x2235, 0xA1DF, + 0x2236, 0xA1C3, 0x2237, 0xA1CB, 0x223D, 0xA1D7, 0x2248, 0xA1D6, + 0x224C, 0xA1D5, 0x2252, 0xA850, 0x2260, 0xA1D9, 0x2261, 0xA1D4, + 0x2264, 0xA1DC, 0x2265, 0xA1DD, 0x2266, 0xA851, 0x2267, 0xA852, + 0x226E, 0xA1DA, 0x226F, 0xA1DB, 0x2295, 0xA892, 0x2299, 0xA1D1, + 0x22A5, 0xA1CD, 0x22BF, 0xA853, 0x2312, 0xA1D0, 0x2460, 0xA2D9, + 0x2461, 0xA2DA, 0x2462, 0xA2DB, 0x2463, 0xA2DC, 0x2464, 0xA2DD, + 0x2465, 0xA2DE, 0x2466, 0xA2DF, 0x2467, 0xA2E0, 0x2468, 0xA2E1, + 0x2469, 0xA2E2, 0x2474, 0xA2C5, 0x2475, 0xA2C6, 0x2476, 0xA2C7, + 0x2477, 0xA2C8, 0x2478, 0xA2C9, 0x2479, 0xA2CA, 0x247A, 0xA2CB, + 0x247B, 0xA2CC, 0x247C, 0xA2CD, 0x247D, 0xA2CE, 0x247E, 0xA2CF, + 0x247F, 0xA2D0, 0x2480, 0xA2D1, 0x2481, 0xA2D2, 0x2482, 0xA2D3, + 0x2483, 0xA2D4, 0x2484, 0xA2D5, 0x2485, 0xA2D6, 0x2486, 0xA2D7, + 0x2487, 0xA2D8, 0x2488, 0xA2B1, 0x2489, 0xA2B2, 0x248A, 0xA2B3, + 0x248B, 0xA2B4, 0x248C, 0xA2B5, 0x248D, 0xA2B6, 0x248E, 0xA2B7, + 0x248F, 0xA2B8, 0x2490, 0xA2B9, 0x2491, 0xA2BA, 0x2492, 0xA2BB, + 0x2493, 0xA2BC, 0x2494, 0xA2BD, 0x2495, 0xA2BE, 0x2496, 0xA2BF, + 0x2497, 0xA2C0, 0x2498, 0xA2C1, 0x2499, 0xA2C2, 0x249A, 0xA2C3, + 0x249B, 0xA2C4, 0x2500, 0xA9A4, 0x2501, 0xA9A5, 0x2502, 0xA9A6, + 0x2503, 0xA9A7, 0x2504, 0xA9A8, 0x2505, 0xA9A9, 0x2506, 0xA9AA, + 0x2507, 0xA9AB, 0x2508, 0xA9AC, 0x2509, 0xA9AD, 0x250A, 0xA9AE, + 0x250B, 0xA9AF, 0x250C, 0xA9B0, 0x250D, 0xA9B1, 0x250E, 0xA9B2, + 0x250F, 0xA9B3, 0x2510, 0xA9B4, 0x2511, 0xA9B5, 0x2512, 0xA9B6, + 0x2513, 0xA9B7, 0x2514, 0xA9B8, 0x2515, 0xA9B9, 0x2516, 0xA9BA, + 0x2517, 0xA9BB, 0x2518, 0xA9BC, 0x2519, 0xA9BD, 0x251A, 0xA9BE, + 0x251B, 0xA9BF, 0x251C, 0xA9C0, 0x251D, 0xA9C1, 0x251E, 0xA9C2, + 0x251F, 0xA9C3, 0x2520, 0xA9C4, 0x2521, 0xA9C5, 0x2522, 0xA9C6, + 0x2523, 0xA9C7, 0x2524, 0xA9C8, 0x2525, 0xA9C9, 0x2526, 0xA9CA, + 0x2527, 0xA9CB, 0x2528, 0xA9CC, 0x2529, 0xA9CD, 0x252A, 0xA9CE, + 0x252B, 0xA9CF, 0x252C, 0xA9D0, 0x252D, 0xA9D1, 0x252E, 0xA9D2, + 0x252F, 0xA9D3, 0x2530, 0xA9D4, 0x2531, 0xA9D5, 0x2532, 0xA9D6, + 0x2533, 0xA9D7, 0x2534, 0xA9D8, 0x2535, 0xA9D9, 0x2536, 0xA9DA, + 0x2537, 0xA9DB, 0x2538, 0xA9DC, 0x2539, 0xA9DD, 0x253A, 0xA9DE, + 0x253B, 0xA9DF, 0x253C, 0xA9E0, 0x253D, 0xA9E1, 0x253E, 0xA9E2, + 0x253F, 0xA9E3, 0x2540, 0xA9E4, 0x2541, 0xA9E5, 0x2542, 0xA9E6, + 0x2543, 0xA9E7, 0x2544, 0xA9E8, 0x2545, 0xA9E9, 0x2546, 0xA9EA, + 0x2547, 0xA9EB, 0x2548, 0xA9EC, 0x2549, 0xA9ED, 0x254A, 0xA9EE, + 0x254B, 0xA9EF, 0x2550, 0xA854, 0x2551, 0xA855, 0x2552, 0xA856, + 0x2553, 0xA857, 0x2554, 0xA858, 0x2555, 0xA859, 0x2556, 0xA85A, + 0x2557, 0xA85B, 0x2558, 0xA85C, 0x2559, 0xA85D, 0x255A, 0xA85E, + 0x255B, 0xA85F, 0x255C, 0xA860, 0x255D, 0xA861, 0x255E, 0xA862, + 0x255F, 0xA863, 0x2560, 0xA864, 0x2561, 0xA865, 0x2562, 0xA866, + 0x2563, 0xA867, 0x2564, 0xA868, 0x2565, 0xA869, 0x2566, 0xA86A, + 0x2567, 0xA86B, 0x2568, 0xA86C, 0x2569, 0xA86D, 0x256A, 0xA86E, + 0x256B, 0xA86F, 0x256C, 0xA870, 0x256D, 0xA871, 0x256E, 0xA872, + 0x256F, 0xA873, 0x2570, 0xA874, 0x2571, 0xA875, 0x2572, 0xA876, + 0x2573, 0xA877, 0x2581, 0xA878, 0x2582, 0xA879, 0x2583, 0xA87A, + 0x2584, 0xA87B, 0x2585, 0xA87C, 0x2586, 0xA87D, 0x2587, 0xA87E, + 0x2588, 0xA880, 0x2589, 0xA881, 0x258A, 0xA882, 0x258B, 0xA883, + 0x258C, 0xA884, 0x258D, 0xA885, 0x258E, 0xA886, 0x258F, 0xA887, + 0x2593, 0xA888, 0x2594, 0xA889, 0x2595, 0xA88A, 0x25A0, 0xA1F6, + 0x25A1, 0xA1F5, 0x25B2, 0xA1F8, 0x25B3, 0xA1F7, 0x25BC, 0xA88B, + 0x25BD, 0xA88C, 0x25C6, 0xA1F4, 0x25C7, 0xA1F3, 0x25CB, 0xA1F0, + 0x25CE, 0xA1F2, 0x25CF, 0xA1F1, 0x25E2, 0xA88D, 0x25E3, 0xA88E, + 0x25E4, 0xA88F, 0x25E5, 0xA890, 0x2605, 0xA1EF, 0x2606, 0xA1EE, + 0x2609, 0xA891, 0x2640, 0xA1E2, 0x2642, 0xA1E1, 0x3000, 0xA1A1, + 0x3001, 0xA1A2, 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3005, 0xA1A9, + 0x3006, 0xA965, 0x3007, 0xA996, 0x3008, 0xA1B4, 0x3009, 0xA1B5, + 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, + 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BE, 0x3011, 0xA1BF, + 0x3012, 0xA893, 0x3013, 0xA1FE, 0x3014, 0xA1B2, 0x3015, 0xA1B3, + 0x3016, 0xA1BC, 0x3017, 0xA1BD, 0x301D, 0xA894, 0x301E, 0xA895, + 0x3021, 0xA940, 0x3022, 0xA941, 0x3023, 0xA942, 0x3024, 0xA943, + 0x3025, 0xA944, 0x3026, 0xA945, 0x3027, 0xA946, 0x3028, 0xA947, + 0x3029, 0xA948, 0x3041, 0xA4A1, 0x3042, 0xA4A2, 0x3043, 0xA4A3, + 0x3044, 0xA4A4, 0x3045, 0xA4A5, 0x3046, 0xA4A6, 0x3047, 0xA4A7, + 0x3048, 0xA4A8, 0x3049, 0xA4A9, 0x304A, 0xA4AA, 0x304B, 0xA4AB, + 0x304C, 0xA4AC, 0x304D, 0xA4AD, 0x304E, 0xA4AE, 0x304F, 0xA4AF, + 0x3050, 0xA4B0, 0x3051, 0xA4B1, 0x3052, 0xA4B2, 0x3053, 0xA4B3, + 0x3054, 0xA4B4, 0x3055, 0xA4B5, 0x3056, 0xA4B6, 0x3057, 0xA4B7, + 0x3058, 0xA4B8, 0x3059, 0xA4B9, 0x305A, 0xA4BA, 0x305B, 0xA4BB, + 0x305C, 0xA4BC, 0x305D, 0xA4BD, 0x305E, 0xA4BE, 0x305F, 0xA4BF, + 0x3060, 0xA4C0, 0x3061, 0xA4C1, 0x3062, 0xA4C2, 0x3063, 0xA4C3, + 0x3064, 0xA4C4, 0x3065, 0xA4C5, 0x3066, 0xA4C6, 0x3067, 0xA4C7, + 0x3068, 0xA4C8, 0x3069, 0xA4C9, 0x306A, 0xA4CA, 0x306B, 0xA4CB, + 0x306C, 0xA4CC, 0x306D, 0xA4CD, 0x306E, 0xA4CE, 0x306F, 0xA4CF, + 0x3070, 0xA4D0, 0x3071, 0xA4D1, 0x3072, 0xA4D2, 0x3073, 0xA4D3, + 0x3074, 0xA4D4, 0x3075, 0xA4D5, 0x3076, 0xA4D6, 0x3077, 0xA4D7, + 0x3078, 0xA4D8, 0x3079, 0xA4D9, 0x307A, 0xA4DA, 0x307B, 0xA4DB, + 0x307C, 0xA4DC, 0x307D, 0xA4DD, 0x307E, 0xA4DE, 0x307F, 0xA4DF, + 0x3080, 0xA4E0, 0x3081, 0xA4E1, 0x3082, 0xA4E2, 0x3083, 0xA4E3, + 0x3084, 0xA4E4, 0x3085, 0xA4E5, 0x3086, 0xA4E6, 0x3087, 0xA4E7, + 0x3088, 0xA4E8, 0x3089, 0xA4E9, 0x308A, 0xA4EA, 0x308B, 0xA4EB, + 0x308C, 0xA4EC, 0x308D, 0xA4ED, 0x308E, 0xA4EE, 0x308F, 0xA4EF, + 0x3090, 0xA4F0, 0x3091, 0xA4F1, 0x3092, 0xA4F2, 0x3093, 0xA4F3, + 0x309B, 0xA961, 0x309C, 0xA962, 0x309D, 0xA966, 0x309E, 0xA967, + 0x30A1, 0xA5A1, 0x30A2, 0xA5A2, 0x30A3, 0xA5A3, 0x30A4, 0xA5A4, + 0x30A5, 0xA5A5, 0x30A6, 0xA5A6, 0x30A7, 0xA5A7, 0x30A8, 0xA5A8, + 0x30A9, 0xA5A9, 0x30AA, 0xA5AA, 0x30AB, 0xA5AB, 0x30AC, 0xA5AC, + 0x30AD, 0xA5AD, 0x30AE, 0xA5AE, 0x30AF, 0xA5AF, 0x30B0, 0xA5B0, + 0x30B1, 0xA5B1, 0x30B2, 0xA5B2, 0x30B3, 0xA5B3, 0x30B4, 0xA5B4, + 0x30B5, 0xA5B5, 0x30B6, 0xA5B6, 0x30B7, 0xA5B7, 0x30B8, 0xA5B8, + 0x30B9, 0xA5B9, 0x30BA, 0xA5BA, 0x30BB, 0xA5BB, 0x30BC, 0xA5BC, + 0x30BD, 0xA5BD, 0x30BE, 0xA5BE, 0x30BF, 0xA5BF, 0x30C0, 0xA5C0, + 0x30C1, 0xA5C1, 0x30C2, 0xA5C2, 0x30C3, 0xA5C3, 0x30C4, 0xA5C4, + 0x30C5, 0xA5C5, 0x30C6, 0xA5C6, 0x30C7, 0xA5C7, 0x30C8, 0xA5C8, + 0x30C9, 0xA5C9, 0x30CA, 0xA5CA, 0x30CB, 0xA5CB, 0x30CC, 0xA5CC, + 0x30CD, 0xA5CD, 0x30CE, 0xA5CE, 0x30CF, 0xA5CF, 0x30D0, 0xA5D0, + 0x30D1, 0xA5D1, 0x30D2, 0xA5D2, 0x30D3, 0xA5D3, 0x30D4, 0xA5D4, + 0x30D5, 0xA5D5, 0x30D6, 0xA5D6, 0x30D7, 0xA5D7, 0x30D8, 0xA5D8, + 0x30D9, 0xA5D9, 0x30DA, 0xA5DA, 0x30DB, 0xA5DB, 0x30DC, 0xA5DC, + 0x30DD, 0xA5DD, 0x30DE, 0xA5DE, 0x30DF, 0xA5DF, 0x30E0, 0xA5E0, + 0x30E1, 0xA5E1, 0x30E2, 0xA5E2, 0x30E3, 0xA5E3, 0x30E4, 0xA5E4, + 0x30E5, 0xA5E5, 0x30E6, 0xA5E6, 0x30E7, 0xA5E7, 0x30E8, 0xA5E8, + 0x30E9, 0xA5E9, 0x30EA, 0xA5EA, 0x30EB, 0xA5EB, 0x30EC, 0xA5EC, + 0x30ED, 0xA5ED, 0x30EE, 0xA5EE, 0x30EF, 0xA5EF, 0x30F0, 0xA5F0, + 0x30F1, 0xA5F1, 0x30F2, 0xA5F2, 0x30F3, 0xA5F3, 0x30F4, 0xA5F4, + 0x30F5, 0xA5F5, 0x30F6, 0xA5F6, 0x30FC, 0xA960, 0x30FD, 0xA963, + 0x30FE, 0xA964, 0x3105, 0xA8C5, 0x3106, 0xA8C6, 0x3107, 0xA8C7, + 0x3108, 0xA8C8, 0x3109, 0xA8C9, 0x310A, 0xA8CA, 0x310B, 0xA8CB, + 0x310C, 0xA8CC, 0x310D, 0xA8CD, 0x310E, 0xA8CE, 0x310F, 0xA8CF, + 0x3110, 0xA8D0, 0x3111, 0xA8D1, 0x3112, 0xA8D2, 0x3113, 0xA8D3, + 0x3114, 0xA8D4, 0x3115, 0xA8D5, 0x3116, 0xA8D6, 0x3117, 0xA8D7, + 0x3118, 0xA8D8, 0x3119, 0xA8D9, 0x311A, 0xA8DA, 0x311B, 0xA8DB, + 0x311C, 0xA8DC, 0x311D, 0xA8DD, 0x311E, 0xA8DE, 0x311F, 0xA8DF, + 0x3120, 0xA8E0, 0x3121, 0xA8E1, 0x3122, 0xA8E2, 0x3123, 0xA8E3, + 0x3124, 0xA8E4, 0x3125, 0xA8E5, 0x3126, 0xA8E6, 0x3127, 0xA8E7, + 0x3128, 0xA8E8, 0x3129, 0xA8E9, 0x3220, 0xA2E5, 0x3221, 0xA2E6, + 0x3222, 0xA2E7, 0x3223, 0xA2E8, 0x3224, 0xA2E9, 0x3225, 0xA2EA, + 0x3226, 0xA2EB, 0x3227, 0xA2EC, 0x3228, 0xA2ED, 0x3229, 0xA2EE, + 0x3231, 0xA95A, 0x32A3, 0xA949, 0x338E, 0xA94A, 0x338F, 0xA94B, + 0x339C, 0xA94C, 0x339D, 0xA94D, 0x339E, 0xA94E, 0x33A1, 0xA94F, + 0x33C4, 0xA950, 0x33CE, 0xA951, 0x33D1, 0xA952, 0x33D2, 0xA953, + 0x33D5, 0xA954, 0x4E00, 0xD2BB, 0x4E01, 0xB6A1, 0x4E02, 0x8140, + 0x4E03, 0xC6DF, 0x4E04, 0x8141, 0x4E05, 0x8142, 0x4E06, 0x8143, + 0x4E07, 0xCDF2, 0x4E08, 0xD5C9, 0x4E09, 0xC8FD, 0x4E0A, 0xC9CF, + 0x4E0B, 0xCFC2, 0x4E0C, 0xD8A2, 0x4E0D, 0xB2BB, 0x4E0E, 0xD3EB, + 0x4E0F, 0x8144, 0x4E10, 0xD8A4, 0x4E11, 0xB3F3, 0x4E12, 0x8145, + 0x4E13, 0xD7A8, 0x4E14, 0xC7D2, 0x4E15, 0xD8A7, 0x4E16, 0xCAC0, + 0x4E17, 0x8146, 0x4E18, 0xC7F0, 0x4E19, 0xB1FB, 0x4E1A, 0xD2B5, + 0x4E1B, 0xB4D4, 0x4E1C, 0xB6AB, 0x4E1D, 0xCBBF, 0x4E1E, 0xD8A9, + 0x4E1F, 0x8147, 0x4E20, 0x8148, 0x4E21, 0x8149, 0x4E22, 0xB6AA, + 0x4E23, 0x814A, 0x4E24, 0xC1BD, 0x4E25, 0xD1CF, 0x4E26, 0x814B, + 0x4E27, 0xC9A5, 0x4E28, 0xD8AD, 0x4E29, 0x814C, 0x4E2A, 0xB8F6, + 0x4E2B, 0xD1BE, 0x4E2C, 0xE3DC, 0x4E2D, 0xD6D0, 0x4E2E, 0x814D, + 0x4E2F, 0x814E, 0x4E30, 0xB7E1, 0x4E31, 0x814F, 0x4E32, 0xB4AE, + 0x4E33, 0x8150, 0x4E34, 0xC1D9, 0x4E35, 0x8151, 0x4E36, 0xD8BC, + 0x4E37, 0x8152, 0x4E38, 0xCDE8, 0x4E39, 0xB5A4, 0x4E3A, 0xCEAA, + 0x4E3B, 0xD6F7, 0x4E3C, 0x8153, 0x4E3D, 0xC0F6, 0x4E3E, 0xBED9, + 0x4E3F, 0xD8AF, 0x4E40, 0x8154, 0x4E41, 0x8155, 0x4E42, 0x8156, + 0x4E43, 0xC4CB, 0x4E44, 0x8157, 0x4E45, 0xBEC3, 0x4E46, 0x8158, + 0x4E47, 0xD8B1, 0x4E48, 0xC3B4, 0x4E49, 0xD2E5, 0x4E4A, 0x8159, + 0x4E4B, 0xD6AE, 0x4E4C, 0xCEDA, 0x4E4D, 0xD5A7, 0x4E4E, 0xBAF5, + 0x4E4F, 0xB7A6, 0x4E50, 0xC0D6, 0x4E51, 0x815A, 0x4E52, 0xC6B9, + 0x4E53, 0xC5D2, 0x4E54, 0xC7C7, 0x4E55, 0x815B, 0x4E56, 0xB9D4, + 0x4E57, 0x815C, 0x4E58, 0xB3CB, 0x4E59, 0xD2D2, 0x4E5A, 0x815D, + 0x4E5B, 0x815E, 0x4E5C, 0xD8BF, 0x4E5D, 0xBEC5, 0x4E5E, 0xC6F2, + 0x4E5F, 0xD2B2, 0x4E60, 0xCFB0, 0x4E61, 0xCFE7, 0x4E62, 0x815F, + 0x4E63, 0x8160, 0x4E64, 0x8161, 0x4E65, 0x8162, 0x4E66, 0xCAE9, + 0x4E67, 0x8163, 0x4E68, 0x8164, 0x4E69, 0xD8C0, 0x4E6A, 0x8165, + 0x4E6B, 0x8166, 0x4E6C, 0x8167, 0x4E6D, 0x8168, 0x4E6E, 0x8169, + 0x4E6F, 0x816A, 0x4E70, 0xC2F2, 0x4E71, 0xC2D2, 0x4E72, 0x816B, + 0x4E73, 0xC8E9, 0x4E74, 0x816C, 0x4E75, 0x816D, 0x4E76, 0x816E, + 0x4E77, 0x816F, 0x4E78, 0x8170, 0x4E79, 0x8171, 0x4E7A, 0x8172, + 0x4E7B, 0x8173, 0x4E7C, 0x8174, 0x4E7D, 0x8175, 0x4E7E, 0xC7AC, + 0x4E7F, 0x8176, 0x4E80, 0x8177, 0x4E81, 0x8178, 0x4E82, 0x8179, + 0x4E83, 0x817A, 0x4E84, 0x817B, 0x4E85, 0x817C, 0x4E86, 0xC1CB, + 0x4E87, 0x817D, 0x4E88, 0xD3E8, 0x4E89, 0xD5F9, 0x4E8A, 0x817E, + 0x4E8B, 0xCAC2, 0x4E8C, 0xB6FE, 0x4E8D, 0xD8A1, 0x4E8E, 0xD3DA, + 0x4E8F, 0xBFF7, 0x4E90, 0x8180, 0x4E91, 0xD4C6, 0x4E92, 0xBBA5, + 0x4E93, 0xD8C1, 0x4E94, 0xCEE5, 0x4E95, 0xBEAE, 0x4E96, 0x8181, + 0x4E97, 0x8182, 0x4E98, 0xD8A8, 0x4E99, 0x8183, 0x4E9A, 0xD1C7, + 0x4E9B, 0xD0A9, 0x4E9C, 0x8184, 0x4E9D, 0x8185, 0x4E9E, 0x8186, + 0x4E9F, 0xD8BD, 0x4EA0, 0xD9EF, 0x4EA1, 0xCDF6, 0x4EA2, 0xBFBA, + 0x4EA3, 0x8187, 0x4EA4, 0xBDBB, 0x4EA5, 0xBAA5, 0x4EA6, 0xD2E0, + 0x4EA7, 0xB2FA, 0x4EA8, 0xBAE0, 0x4EA9, 0xC4B6, 0x4EAA, 0x8188, + 0x4EAB, 0xCFED, 0x4EAC, 0xBEA9, 0x4EAD, 0xCDA4, 0x4EAE, 0xC1C1, + 0x4EAF, 0x8189, 0x4EB0, 0x818A, 0x4EB1, 0x818B, 0x4EB2, 0xC7D7, + 0x4EB3, 0xD9F1, 0x4EB4, 0x818C, 0x4EB5, 0xD9F4, 0x4EB6, 0x818D, + 0x4EB7, 0x818E, 0x4EB8, 0x818F, 0x4EB9, 0x8190, 0x4EBA, 0xC8CB, + 0x4EBB, 0xD8E9, 0x4EBC, 0x8191, 0x4EBD, 0x8192, 0x4EBE, 0x8193, + 0x4EBF, 0xD2DA, 0x4EC0, 0xCAB2, 0x4EC1, 0xC8CA, 0x4EC2, 0xD8EC, + 0x4EC3, 0xD8EA, 0x4EC4, 0xD8C6, 0x4EC5, 0xBDF6, 0x4EC6, 0xC6CD, + 0x4EC7, 0xB3F0, 0x4EC8, 0x8194, 0x4EC9, 0xD8EB, 0x4ECA, 0xBDF1, + 0x4ECB, 0xBDE9, 0x4ECC, 0x8195, 0x4ECD, 0xC8D4, 0x4ECE, 0xB4D3, + 0x4ECF, 0x8196, 0x4ED0, 0x8197, 0x4ED1, 0xC2D8, 0x4ED2, 0x8198, + 0x4ED3, 0xB2D6, 0x4ED4, 0xD7D0, 0x4ED5, 0xCACB, 0x4ED6, 0xCBFB, + 0x4ED7, 0xD5CC, 0x4ED8, 0xB8B6, 0x4ED9, 0xCFC9, 0x4EDA, 0x8199, + 0x4EDB, 0x819A, 0x4EDC, 0x819B, 0x4EDD, 0xD9DA, 0x4EDE, 0xD8F0, + 0x4EDF, 0xC7AA, 0x4EE0, 0x819C, 0x4EE1, 0xD8EE, 0x4EE2, 0x819D, + 0x4EE3, 0xB4FA, 0x4EE4, 0xC1EE, 0x4EE5, 0xD2D4, 0x4EE6, 0x819E, + 0x4EE7, 0x819F, 0x4EE8, 0xD8ED, 0x4EE9, 0x81A0, 0x4EEA, 0xD2C7, + 0x4EEB, 0xD8EF, 0x4EEC, 0xC3C7, 0x4EED, 0x81A1, 0x4EEE, 0x81A2, + 0x4EEF, 0x81A3, 0x4EF0, 0xD1F6, 0x4EF1, 0x81A4, 0x4EF2, 0xD6D9, + 0x4EF3, 0xD8F2, 0x4EF4, 0x81A5, 0x4EF5, 0xD8F5, 0x4EF6, 0xBCFE, + 0x4EF7, 0xBCDB, 0x4EF8, 0x81A6, 0x4EF9, 0x81A7, 0x4EFA, 0x81A8, + 0x4EFB, 0xC8CE, 0x4EFC, 0x81A9, 0x4EFD, 0xB7DD, 0x4EFE, 0x81AA, + 0x4EFF, 0xB7C2, 0x4F00, 0x81AB, 0x4F01, 0xC6F3, 0x4F02, 0x81AC, + 0x4F03, 0x81AD, 0x4F04, 0x81AE, 0x4F05, 0x81AF, 0x4F06, 0x81B0, + 0x4F07, 0x81B1, 0x4F08, 0x81B2, 0x4F09, 0xD8F8, 0x4F0A, 0xD2C1, + 0x4F0B, 0x81B3, 0x4F0C, 0x81B4, 0x4F0D, 0xCEE9, 0x4F0E, 0xBCBF, + 0x4F0F, 0xB7FC, 0x4F10, 0xB7A5, 0x4F11, 0xD0DD, 0x4F12, 0x81B5, + 0x4F13, 0x81B6, 0x4F14, 0x81B7, 0x4F15, 0x81B8, 0x4F16, 0x81B9, + 0x4F17, 0xD6DA, 0x4F18, 0xD3C5, 0x4F19, 0xBBEF, 0x4F1A, 0xBBE1, + 0x4F1B, 0xD8F1, 0x4F1C, 0x81BA, 0x4F1D, 0x81BB, 0x4F1E, 0xC9A1, + 0x4F1F, 0xCEB0, 0x4F20, 0xB4AB, 0x4F21, 0x81BC, 0x4F22, 0xD8F3, + 0x4F23, 0x81BD, 0x4F24, 0xC9CB, 0x4F25, 0xD8F6, 0x4F26, 0xC2D7, + 0x4F27, 0xD8F7, 0x4F28, 0x81BE, 0x4F29, 0x81BF, 0x4F2A, 0xCEB1, + 0x4F2B, 0xD8F9, 0x4F2C, 0x81C0, 0x4F2D, 0x81C1, 0x4F2E, 0x81C2, + 0x4F2F, 0xB2AE, 0x4F30, 0xB9C0, 0x4F31, 0x81C3, 0x4F32, 0xD9A3, + 0x4F33, 0x81C4, 0x4F34, 0xB0E9, 0x4F35, 0x81C5, 0x4F36, 0xC1E6, + 0x4F37, 0x81C6, 0x4F38, 0xC9EC, 0x4F39, 0x81C7, 0x4F3A, 0xCBC5, + 0x4F3B, 0x81C8, 0x4F3C, 0xCBC6, 0x4F3D, 0xD9A4, 0x4F3E, 0x81C9, + 0x4F3F, 0x81CA, 0x4F40, 0x81CB, 0x4F41, 0x81CC, 0x4F42, 0x81CD, + 0x4F43, 0xB5E8, 0x4F44, 0x81CE, 0x4F45, 0x81CF, 0x4F46, 0xB5AB, + 0x4F47, 0x81D0, 0x4F48, 0x81D1, 0x4F49, 0x81D2, 0x4F4A, 0x81D3, + 0x4F4B, 0x81D4, 0x4F4C, 0x81D5, 0x4F4D, 0xCEBB, 0x4F4E, 0xB5CD, + 0x4F4F, 0xD7A1, 0x4F50, 0xD7F4, 0x4F51, 0xD3D3, 0x4F52, 0x81D6, + 0x4F53, 0xCCE5, 0x4F54, 0x81D7, 0x4F55, 0xBACE, 0x4F56, 0x81D8, + 0x4F57, 0xD9A2, 0x4F58, 0xD9DC, 0x4F59, 0xD3E0, 0x4F5A, 0xD8FD, + 0x4F5B, 0xB7F0, 0x4F5C, 0xD7F7, 0x4F5D, 0xD8FE, 0x4F5E, 0xD8FA, + 0x4F5F, 0xD9A1, 0x4F60, 0xC4E3, 0x4F61, 0x81D9, 0x4F62, 0x81DA, + 0x4F63, 0xD3B6, 0x4F64, 0xD8F4, 0x4F65, 0xD9DD, 0x4F66, 0x81DB, + 0x4F67, 0xD8FB, 0x4F68, 0x81DC, 0x4F69, 0xC5E5, 0x4F6A, 0x81DD, + 0x4F6B, 0x81DE, 0x4F6C, 0xC0D0, 0x4F6D, 0x81DF, 0x4F6E, 0x81E0, + 0x4F6F, 0xD1F0, 0x4F70, 0xB0DB, 0x4F71, 0x81E1, 0x4F72, 0x81E2, + 0x4F73, 0xBCD1, 0x4F74, 0xD9A6, 0x4F75, 0x81E3, 0x4F76, 0xD9A5, + 0x4F77, 0x81E4, 0x4F78, 0x81E5, 0x4F79, 0x81E6, 0x4F7A, 0x81E7, + 0x4F7B, 0xD9AC, 0x4F7C, 0xD9AE, 0x4F7D, 0x81E8, 0x4F7E, 0xD9AB, + 0x4F7F, 0xCAB9, 0x4F80, 0x81E9, 0x4F81, 0x81EA, 0x4F82, 0x81EB, + 0x4F83, 0xD9A9, 0x4F84, 0xD6B6, 0x4F85, 0x81EC, 0x4F86, 0x81ED, + 0x4F87, 0x81EE, 0x4F88, 0xB3DE, 0x4F89, 0xD9A8, 0x4F8A, 0x81EF, + 0x4F8B, 0xC0FD, 0x4F8C, 0x81F0, 0x4F8D, 0xCACC, 0x4F8E, 0x81F1, + 0x4F8F, 0xD9AA, 0x4F90, 0x81F2, 0x4F91, 0xD9A7, 0x4F92, 0x81F3, + 0x4F93, 0x81F4, 0x4F94, 0xD9B0, 0x4F95, 0x81F5, 0x4F96, 0x81F6, + 0x4F97, 0xB6B1, 0x4F98, 0x81F7, 0x4F99, 0x81F8, 0x4F9A, 0x81F9, + 0x4F9B, 0xB9A9, 0x4F9C, 0x81FA, 0x4F9D, 0xD2C0, 0x4F9E, 0x81FB, + 0x4F9F, 0x81FC, 0x4FA0, 0xCFC0, 0x4FA1, 0x81FD, 0x4FA2, 0x81FE, + 0x4FA3, 0xC2C2, 0x4FA4, 0x8240, 0x4FA5, 0xBDC4, 0x4FA6, 0xD5EC, + 0x4FA7, 0xB2E0, 0x4FA8, 0xC7C8, 0x4FA9, 0xBFEB, 0x4FAA, 0xD9AD, + 0x4FAB, 0x8241, 0x4FAC, 0xD9AF, 0x4FAD, 0x8242, 0x4FAE, 0xCEEA, + 0x4FAF, 0xBAEE, 0x4FB0, 0x8243, 0x4FB1, 0x8244, 0x4FB2, 0x8245, + 0x4FB3, 0x8246, 0x4FB4, 0x8247, 0x4FB5, 0xC7D6, 0x4FB6, 0x8248, + 0x4FB7, 0x8249, 0x4FB8, 0x824A, 0x4FB9, 0x824B, 0x4FBA, 0x824C, + 0x4FBB, 0x824D, 0x4FBC, 0x824E, 0x4FBD, 0x824F, 0x4FBE, 0x8250, + 0x4FBF, 0xB1E3, 0x4FC0, 0x8251, 0x4FC1, 0x8252, 0x4FC2, 0x8253, + 0x4FC3, 0xB4D9, 0x4FC4, 0xB6ED, 0x4FC5, 0xD9B4, 0x4FC6, 0x8254, + 0x4FC7, 0x8255, 0x4FC8, 0x8256, 0x4FC9, 0x8257, 0x4FCA, 0xBFA1, + 0x4FCB, 0x8258, 0x4FCC, 0x8259, 0x4FCD, 0x825A, 0x4FCE, 0xD9DE, + 0x4FCF, 0xC7CE, 0x4FD0, 0xC0FE, 0x4FD1, 0xD9B8, 0x4FD2, 0x825B, + 0x4FD3, 0x825C, 0x4FD4, 0x825D, 0x4FD5, 0x825E, 0x4FD6, 0x825F, + 0x4FD7, 0xCBD7, 0x4FD8, 0xB7FD, 0x4FD9, 0x8260, 0x4FDA, 0xD9B5, + 0x4FDB, 0x8261, 0x4FDC, 0xD9B7, 0x4FDD, 0xB1A3, 0x4FDE, 0xD3E1, + 0x4FDF, 0xD9B9, 0x4FE0, 0x8262, 0x4FE1, 0xD0C5, 0x4FE2, 0x8263, + 0x4FE3, 0xD9B6, 0x4FE4, 0x8264, 0x4FE5, 0x8265, 0x4FE6, 0xD9B1, + 0x4FE7, 0x8266, 0x4FE8, 0xD9B2, 0x4FE9, 0xC1A9, 0x4FEA, 0xD9B3, + 0x4FEB, 0x8267, 0x4FEC, 0x8268, 0x4FED, 0xBCF3, 0x4FEE, 0xD0DE, + 0x4FEF, 0xB8A9, 0x4FF0, 0x8269, 0x4FF1, 0xBEE3, 0x4FF2, 0x826A, + 0x4FF3, 0xD9BD, 0x4FF4, 0x826B, 0x4FF5, 0x826C, 0x4FF6, 0x826D, + 0x4FF7, 0x826E, 0x4FF8, 0xD9BA, 0x4FF9, 0x826F, 0x4FFA, 0xB0B3, + 0x4FFB, 0x8270, 0x4FFC, 0x8271, 0x4FFD, 0x8272, 0x4FFE, 0xD9C2, + 0x4FFF, 0x8273, 0x5000, 0x8274, 0x5001, 0x8275, 0x5002, 0x8276, + 0x5003, 0x8277, 0x5004, 0x8278, 0x5005, 0x8279, 0x5006, 0x827A, + 0x5007, 0x827B, 0x5008, 0x827C, 0x5009, 0x827D, 0x500A, 0x827E, + 0x500B, 0x8280, 0x500C, 0xD9C4, 0x500D, 0xB1B6, 0x500E, 0x8281, + 0x500F, 0xD9BF, 0x5010, 0x8282, 0x5011, 0x8283, 0x5012, 0xB5B9, + 0x5013, 0x8284, 0x5014, 0xBEF3, 0x5015, 0x8285, 0x5016, 0x8286, + 0x5017, 0x8287, 0x5018, 0xCCC8, 0x5019, 0xBAF2, 0x501A, 0xD2D0, + 0x501B, 0x8288, 0x501C, 0xD9C3, 0x501D, 0x8289, 0x501E, 0x828A, + 0x501F, 0xBDE8, 0x5020, 0x828B, 0x5021, 0xB3AB, 0x5022, 0x828C, + 0x5023, 0x828D, 0x5024, 0x828E, 0x5025, 0xD9C5, 0x5026, 0xBEEB, + 0x5027, 0x828F, 0x5028, 0xD9C6, 0x5029, 0xD9BB, 0x502A, 0xC4DF, + 0x502B, 0x8290, 0x502C, 0xD9BE, 0x502D, 0xD9C1, 0x502E, 0xD9C0, + 0x502F, 0x8291, 0x5030, 0x8292, 0x5031, 0x8293, 0x5032, 0x8294, + 0x5033, 0x8295, 0x5034, 0x8296, 0x5035, 0x8297, 0x5036, 0x8298, + 0x5037, 0x8299, 0x5038, 0x829A, 0x5039, 0x829B, 0x503A, 0xD5AE, + 0x503B, 0x829C, 0x503C, 0xD6B5, 0x503D, 0x829D, 0x503E, 0xC7E3, + 0x503F, 0x829E, 0x5040, 0x829F, 0x5041, 0x82A0, 0x5042, 0x82A1, + 0x5043, 0xD9C8, 0x5044, 0x82A2, 0x5045, 0x82A3, 0x5046, 0x82A4, + 0x5047, 0xBCD9, 0x5048, 0xD9CA, 0x5049, 0x82A5, 0x504A, 0x82A6, + 0x504B, 0x82A7, 0x504C, 0xD9BC, 0x504D, 0x82A8, 0x504E, 0xD9CB, + 0x504F, 0xC6AB, 0x5050, 0x82A9, 0x5051, 0x82AA, 0x5052, 0x82AB, + 0x5053, 0x82AC, 0x5054, 0x82AD, 0x5055, 0xD9C9, 0x5056, 0x82AE, + 0x5057, 0x82AF, 0x5058, 0x82B0, 0x5059, 0x82B1, 0x505A, 0xD7F6, + 0x505B, 0x82B2, 0x505C, 0xCDA3, 0x505D, 0x82B3, 0x505E, 0x82B4, + 0x505F, 0x82B5, 0x5060, 0x82B6, 0x5061, 0x82B7, 0x5062, 0x82B8, + 0x5063, 0x82B9, 0x5064, 0x82BA, 0x5065, 0xBDA1, 0x5066, 0x82BB, + 0x5067, 0x82BC, 0x5068, 0x82BD, 0x5069, 0x82BE, 0x506A, 0x82BF, + 0x506B, 0x82C0, 0x506C, 0xD9CC, 0x506D, 0x82C1, 0x506E, 0x82C2, + 0x506F, 0x82C3, 0x5070, 0x82C4, 0x5071, 0x82C5, 0x5072, 0x82C6, + 0x5073, 0x82C7, 0x5074, 0x82C8, 0x5075, 0x82C9, 0x5076, 0xC5BC, + 0x5077, 0xCDB5, 0x5078, 0x82CA, 0x5079, 0x82CB, 0x507A, 0x82CC, + 0x507B, 0xD9CD, 0x507C, 0x82CD, 0x507D, 0x82CE, 0x507E, 0xD9C7, + 0x507F, 0xB3A5, 0x5080, 0xBFFE, 0x5081, 0x82CF, 0x5082, 0x82D0, + 0x5083, 0x82D1, 0x5084, 0x82D2, 0x5085, 0xB8B5, 0x5086, 0x82D3, + 0x5087, 0x82D4, 0x5088, 0xC0FC, 0x5089, 0x82D5, 0x508A, 0x82D6, + 0x508B, 0x82D7, 0x508C, 0x82D8, 0x508D, 0xB0F8, 0x508E, 0x82D9, + 0x508F, 0x82DA, 0x5090, 0x82DB, 0x5091, 0x82DC, 0x5092, 0x82DD, + 0x5093, 0x82DE, 0x5094, 0x82DF, 0x5095, 0x82E0, 0x5096, 0x82E1, + 0x5097, 0x82E2, 0x5098, 0x82E3, 0x5099, 0x82E4, 0x509A, 0x82E5, + 0x509B, 0x82E6, 0x509C, 0x82E7, 0x509D, 0x82E8, 0x509E, 0x82E9, + 0x509F, 0x82EA, 0x50A0, 0x82EB, 0x50A1, 0x82EC, 0x50A2, 0x82ED, + 0x50A3, 0xB4F6, 0x50A4, 0x82EE, 0x50A5, 0xD9CE, 0x50A6, 0x82EF, + 0x50A7, 0xD9CF, 0x50A8, 0xB4A2, 0x50A9, 0xD9D0, 0x50AA, 0x82F0, + 0x50AB, 0x82F1, 0x50AC, 0xB4DF, 0x50AD, 0x82F2, 0x50AE, 0x82F3, + 0x50AF, 0x82F4, 0x50B0, 0x82F5, 0x50B1, 0x82F6, 0x50B2, 0xB0C1, + 0x50B3, 0x82F7, 0x50B4, 0x82F8, 0x50B5, 0x82F9, 0x50B6, 0x82FA, + 0x50B7, 0x82FB, 0x50B8, 0x82FC, 0x50B9, 0x82FD, 0x50BA, 0xD9D1, + 0x50BB, 0xC9B5, 0x50BC, 0x82FE, 0x50BD, 0x8340, 0x50BE, 0x8341, + 0x50BF, 0x8342, 0x50C0, 0x8343, 0x50C1, 0x8344, 0x50C2, 0x8345, + 0x50C3, 0x8346, 0x50C4, 0x8347, 0x50C5, 0x8348, 0x50C6, 0x8349, + 0x50C7, 0x834A, 0x50C8, 0x834B, 0x50C9, 0x834C, 0x50CA, 0x834D, + 0x50CB, 0x834E, 0x50CC, 0x834F, 0x50CD, 0x8350, 0x50CE, 0x8351, + 0x50CF, 0xCFF1, 0x50D0, 0x8352, 0x50D1, 0x8353, 0x50D2, 0x8354, + 0x50D3, 0x8355, 0x50D4, 0x8356, 0x50D5, 0x8357, 0x50D6, 0xD9D2, + 0x50D7, 0x8358, 0x50D8, 0x8359, 0x50D9, 0x835A, 0x50DA, 0xC1C5, + 0x50DB, 0x835B, 0x50DC, 0x835C, 0x50DD, 0x835D, 0x50DE, 0x835E, + 0x50DF, 0x835F, 0x50E0, 0x8360, 0x50E1, 0x8361, 0x50E2, 0x8362, + 0x50E3, 0x8363, 0x50E4, 0x8364, 0x50E5, 0x8365, 0x50E6, 0xD9D6, + 0x50E7, 0xC9AE, 0x50E8, 0x8366, 0x50E9, 0x8367, 0x50EA, 0x8368, + 0x50EB, 0x8369, 0x50EC, 0xD9D5, 0x50ED, 0xD9D4, 0x50EE, 0xD9D7, + 0x50EF, 0x836A, 0x50F0, 0x836B, 0x50F1, 0x836C, 0x50F2, 0x836D, + 0x50F3, 0xCBDB, 0x50F4, 0x836E, 0x50F5, 0xBDA9, 0x50F6, 0x836F, + 0x50F7, 0x8370, 0x50F8, 0x8371, 0x50F9, 0x8372, 0x50FA, 0x8373, + 0x50FB, 0xC6A7, 0x50FC, 0x8374, 0x50FD, 0x8375, 0x50FE, 0x8376, + 0x50FF, 0x8377, 0x5100, 0x8378, 0x5101, 0x8379, 0x5102, 0x837A, + 0x5103, 0x837B, 0x5104, 0x837C, 0x5105, 0x837D, 0x5106, 0xD9D3, + 0x5107, 0xD9D8, 0x5108, 0x837E, 0x5109, 0x8380, 0x510A, 0x8381, + 0x510B, 0xD9D9, 0x510C, 0x8382, 0x510D, 0x8383, 0x510E, 0x8384, + 0x510F, 0x8385, 0x5110, 0x8386, 0x5111, 0x8387, 0x5112, 0xC8E5, + 0x5113, 0x8388, 0x5114, 0x8389, 0x5115, 0x838A, 0x5116, 0x838B, + 0x5117, 0x838C, 0x5118, 0x838D, 0x5119, 0x838E, 0x511A, 0x838F, + 0x511B, 0x8390, 0x511C, 0x8391, 0x511D, 0x8392, 0x511E, 0x8393, + 0x511F, 0x8394, 0x5120, 0x8395, 0x5121, 0xC0DC, 0x5122, 0x8396, + 0x5123, 0x8397, 0x5124, 0x8398, 0x5125, 0x8399, 0x5126, 0x839A, + 0x5127, 0x839B, 0x5128, 0x839C, 0x5129, 0x839D, 0x512A, 0x839E, + 0x512B, 0x839F, 0x512C, 0x83A0, 0x512D, 0x83A1, 0x512E, 0x83A2, + 0x512F, 0x83A3, 0x5130, 0x83A4, 0x5131, 0x83A5, 0x5132, 0x83A6, + 0x5133, 0x83A7, 0x5134, 0x83A8, 0x5135, 0x83A9, 0x5136, 0x83AA, + 0x5137, 0x83AB, 0x5138, 0x83AC, 0x5139, 0x83AD, 0x513A, 0x83AE, + 0x513B, 0x83AF, 0x513C, 0x83B0, 0x513D, 0x83B1, 0x513E, 0x83B2, + 0x513F, 0xB6F9, 0x5140, 0xD8A3, 0x5141, 0xD4CA, 0x5142, 0x83B3, + 0x5143, 0xD4AA, 0x5144, 0xD0D6, 0x5145, 0xB3E4, 0x5146, 0xD5D7, + 0x5147, 0x83B4, 0x5148, 0xCFC8, 0x5149, 0xB9E2, 0x514A, 0x83B5, + 0x514B, 0xBFCB, 0x514C, 0x83B6, 0x514D, 0xC3E2, 0x514E, 0x83B7, + 0x514F, 0x83B8, 0x5150, 0x83B9, 0x5151, 0xB6D2, 0x5152, 0x83BA, + 0x5153, 0x83BB, 0x5154, 0xCDC3, 0x5155, 0xD9EE, 0x5156, 0xD9F0, + 0x5157, 0x83BC, 0x5158, 0x83BD, 0x5159, 0x83BE, 0x515A, 0xB5B3, + 0x515B, 0x83BF, 0x515C, 0xB6B5, 0x515D, 0x83C0, 0x515E, 0x83C1, + 0x515F, 0x83C2, 0x5160, 0x83C3, 0x5161, 0x83C4, 0x5162, 0xBEA4, + 0x5163, 0x83C5, 0x5164, 0x83C6, 0x5165, 0xC8EB, 0x5166, 0x83C7, + 0x5167, 0x83C8, 0x5168, 0xC8AB, 0x5169, 0x83C9, 0x516A, 0x83CA, + 0x516B, 0xB0CB, 0x516C, 0xB9AB, 0x516D, 0xC1F9, 0x516E, 0xD9E2, + 0x516F, 0x83CB, 0x5170, 0xC0BC, 0x5171, 0xB9B2, 0x5172, 0x83CC, + 0x5173, 0xB9D8, 0x5174, 0xD0CB, 0x5175, 0xB1F8, 0x5176, 0xC6E4, + 0x5177, 0xBEDF, 0x5178, 0xB5E4, 0x5179, 0xD7C8, 0x517A, 0x83CD, + 0x517B, 0xD1F8, 0x517C, 0xBCE6, 0x517D, 0xCADE, 0x517E, 0x83CE, + 0x517F, 0x83CF, 0x5180, 0xBCBD, 0x5181, 0xD9E6, 0x5182, 0xD8E7, + 0x5183, 0x83D0, 0x5184, 0x83D1, 0x5185, 0xC4DA, 0x5186, 0x83D2, + 0x5187, 0x83D3, 0x5188, 0xB8D4, 0x5189, 0xC8BD, 0x518A, 0x83D4, + 0x518B, 0x83D5, 0x518C, 0xB2E1, 0x518D, 0xD4D9, 0x518E, 0x83D6, + 0x518F, 0x83D7, 0x5190, 0x83D8, 0x5191, 0x83D9, 0x5192, 0xC3B0, + 0x5193, 0x83DA, 0x5194, 0x83DB, 0x5195, 0xC3E1, 0x5196, 0xDAA2, + 0x5197, 0xC8DF, 0x5198, 0x83DC, 0x5199, 0xD0B4, 0x519A, 0x83DD, + 0x519B, 0xBEFC, 0x519C, 0xC5A9, 0x519D, 0x83DE, 0x519E, 0x83DF, + 0x519F, 0x83E0, 0x51A0, 0xB9DA, 0x51A1, 0x83E1, 0x51A2, 0xDAA3, + 0x51A3, 0x83E2, 0x51A4, 0xD4A9, 0x51A5, 0xDAA4, 0x51A6, 0x83E3, + 0x51A7, 0x83E4, 0x51A8, 0x83E5, 0x51A9, 0x83E6, 0x51AA, 0x83E7, + 0x51AB, 0xD9FB, 0x51AC, 0xB6AC, 0x51AD, 0x83E8, 0x51AE, 0x83E9, + 0x51AF, 0xB7EB, 0x51B0, 0xB1F9, 0x51B1, 0xD9FC, 0x51B2, 0xB3E5, + 0x51B3, 0xBEF6, 0x51B4, 0x83EA, 0x51B5, 0xBFF6, 0x51B6, 0xD2B1, + 0x51B7, 0xC0E4, 0x51B8, 0x83EB, 0x51B9, 0x83EC, 0x51BA, 0x83ED, + 0x51BB, 0xB6B3, 0x51BC, 0xD9FE, 0x51BD, 0xD9FD, 0x51BE, 0x83EE, + 0x51BF, 0x83EF, 0x51C0, 0xBEBB, 0x51C1, 0x83F0, 0x51C2, 0x83F1, + 0x51C3, 0x83F2, 0x51C4, 0xC6E0, 0x51C5, 0x83F3, 0x51C6, 0xD7BC, + 0x51C7, 0xDAA1, 0x51C8, 0x83F4, 0x51C9, 0xC1B9, 0x51CA, 0x83F5, + 0x51CB, 0xB5F2, 0x51CC, 0xC1E8, 0x51CD, 0x83F6, 0x51CE, 0x83F7, + 0x51CF, 0xBCF5, 0x51D0, 0x83F8, 0x51D1, 0xB4D5, 0x51D2, 0x83F9, + 0x51D3, 0x83FA, 0x51D4, 0x83FB, 0x51D5, 0x83FC, 0x51D6, 0x83FD, + 0x51D7, 0x83FE, 0x51D8, 0x8440, 0x51D9, 0x8441, 0x51DA, 0x8442, + 0x51DB, 0xC1DD, 0x51DC, 0x8443, 0x51DD, 0xC4FD, 0x51DE, 0x8444, + 0x51DF, 0x8445, 0x51E0, 0xBCB8, 0x51E1, 0xB7B2, 0x51E2, 0x8446, + 0x51E3, 0x8447, 0x51E4, 0xB7EF, 0x51E5, 0x8448, 0x51E6, 0x8449, + 0x51E7, 0x844A, 0x51E8, 0x844B, 0x51E9, 0x844C, 0x51EA, 0x844D, + 0x51EB, 0xD9EC, 0x51EC, 0x844E, 0x51ED, 0xC6BE, 0x51EE, 0x844F, + 0x51EF, 0xBFAD, 0x51F0, 0xBBCB, 0x51F1, 0x8450, 0x51F2, 0x8451, + 0x51F3, 0xB5CA, 0x51F4, 0x8452, 0x51F5, 0xDBC9, 0x51F6, 0xD0D7, + 0x51F7, 0x8453, 0x51F8, 0xCDB9, 0x51F9, 0xB0BC, 0x51FA, 0xB3F6, + 0x51FB, 0xBBF7, 0x51FC, 0xDBCA, 0x51FD, 0xBAAF, 0x51FE, 0x8454, + 0x51FF, 0xD4E4, 0x5200, 0xB5B6, 0x5201, 0xB5F3, 0x5202, 0xD8D6, + 0x5203, 0xC8D0, 0x5204, 0x8455, 0x5205, 0x8456, 0x5206, 0xB7D6, + 0x5207, 0xC7D0, 0x5208, 0xD8D7, 0x5209, 0x8457, 0x520A, 0xBFAF, + 0x520B, 0x8458, 0x520C, 0x8459, 0x520D, 0xDBBB, 0x520E, 0xD8D8, + 0x520F, 0x845A, 0x5210, 0x845B, 0x5211, 0xD0CC, 0x5212, 0xBBAE, + 0x5213, 0x845C, 0x5214, 0x845D, 0x5215, 0x845E, 0x5216, 0xEBBE, + 0x5217, 0xC1D0, 0x5218, 0xC1F5, 0x5219, 0xD4F2, 0x521A, 0xB8D5, + 0x521B, 0xB4B4, 0x521C, 0x845F, 0x521D, 0xB3F5, 0x521E, 0x8460, + 0x521F, 0x8461, 0x5220, 0xC9BE, 0x5221, 0x8462, 0x5222, 0x8463, + 0x5223, 0x8464, 0x5224, 0xC5D0, 0x5225, 0x8465, 0x5226, 0x8466, + 0x5227, 0x8467, 0x5228, 0xC5D9, 0x5229, 0xC0FB, 0x522A, 0x8468, + 0x522B, 0xB1F0, 0x522C, 0x8469, 0x522D, 0xD8D9, 0x522E, 0xB9CE, + 0x522F, 0x846A, 0x5230, 0xB5BD, 0x5231, 0x846B, 0x5232, 0x846C, + 0x5233, 0xD8DA, 0x5234, 0x846D, 0x5235, 0x846E, 0x5236, 0xD6C6, + 0x5237, 0xCBA2, 0x5238, 0xC8AF, 0x5239, 0xC9B2, 0x523A, 0xB4CC, + 0x523B, 0xBFCC, 0x523C, 0x846F, 0x523D, 0xB9F4, 0x523E, 0x8470, + 0x523F, 0xD8DB, 0x5240, 0xD8DC, 0x5241, 0xB6E7, 0x5242, 0xBCC1, + 0x5243, 0xCCEA, 0x5244, 0x8471, 0x5245, 0x8472, 0x5246, 0x8473, + 0x5247, 0x8474, 0x5248, 0x8475, 0x5249, 0x8476, 0x524A, 0xCFF7, + 0x524B, 0x8477, 0x524C, 0xD8DD, 0x524D, 0xC7B0, 0x524E, 0x8478, + 0x524F, 0x8479, 0x5250, 0xB9D0, 0x5251, 0xBDA3, 0x5252, 0x847A, + 0x5253, 0x847B, 0x5254, 0xCCDE, 0x5255, 0x847C, 0x5256, 0xC6CA, + 0x5257, 0x847D, 0x5258, 0x847E, 0x5259, 0x8480, 0x525A, 0x8481, + 0x525B, 0x8482, 0x525C, 0xD8E0, 0x525D, 0x8483, 0x525E, 0xD8DE, + 0x525F, 0x8484, 0x5260, 0x8485, 0x5261, 0xD8DF, 0x5262, 0x8486, + 0x5263, 0x8487, 0x5264, 0x8488, 0x5265, 0xB0FE, 0x5266, 0x8489, + 0x5267, 0xBEE7, 0x5268, 0x848A, 0x5269, 0xCAA3, 0x526A, 0xBCF4, + 0x526B, 0x848B, 0x526C, 0x848C, 0x526D, 0x848D, 0x526E, 0x848E, + 0x526F, 0xB8B1, 0x5270, 0x848F, 0x5271, 0x8490, 0x5272, 0xB8EE, + 0x5273, 0x8491, 0x5274, 0x8492, 0x5275, 0x8493, 0x5276, 0x8494, + 0x5277, 0x8495, 0x5278, 0x8496, 0x5279, 0x8497, 0x527A, 0x8498, + 0x527B, 0x8499, 0x527C, 0x849A, 0x527D, 0xD8E2, 0x527E, 0x849B, + 0x527F, 0xBDCB, 0x5280, 0x849C, 0x5281, 0xD8E4, 0x5282, 0xD8E3, + 0x5283, 0x849D, 0x5284, 0x849E, 0x5285, 0x849F, 0x5286, 0x84A0, + 0x5287, 0x84A1, 0x5288, 0xC5FC, 0x5289, 0x84A2, 0x528A, 0x84A3, + 0x528B, 0x84A4, 0x528C, 0x84A5, 0x528D, 0x84A6, 0x528E, 0x84A7, + 0x528F, 0x84A8, 0x5290, 0xD8E5, 0x5291, 0x84A9, 0x5292, 0x84AA, + 0x5293, 0xD8E6, 0x5294, 0x84AB, 0x5295, 0x84AC, 0x5296, 0x84AD, + 0x5297, 0x84AE, 0x5298, 0x84AF, 0x5299, 0x84B0, 0x529A, 0x84B1, + 0x529B, 0xC1A6, 0x529C, 0x84B2, 0x529D, 0xC8B0, 0x529E, 0xB0EC, + 0x529F, 0xB9A6, 0x52A0, 0xBCD3, 0x52A1, 0xCEF1, 0x52A2, 0xDBBD, + 0x52A3, 0xC1D3, 0x52A4, 0x84B3, 0x52A5, 0x84B4, 0x52A6, 0x84B5, + 0x52A7, 0x84B6, 0x52A8, 0xB6AF, 0x52A9, 0xD6FA, 0x52AA, 0xC5AC, + 0x52AB, 0xBDD9, 0x52AC, 0xDBBE, 0x52AD, 0xDBBF, 0x52AE, 0x84B7, + 0x52AF, 0x84B8, 0x52B0, 0x84B9, 0x52B1, 0xC0F8, 0x52B2, 0xBEA2, + 0x52B3, 0xC0CD, 0x52B4, 0x84BA, 0x52B5, 0x84BB, 0x52B6, 0x84BC, + 0x52B7, 0x84BD, 0x52B8, 0x84BE, 0x52B9, 0x84BF, 0x52BA, 0x84C0, + 0x52BB, 0x84C1, 0x52BC, 0x84C2, 0x52BD, 0x84C3, 0x52BE, 0xDBC0, + 0x52BF, 0xCAC6, 0x52C0, 0x84C4, 0x52C1, 0x84C5, 0x52C2, 0x84C6, + 0x52C3, 0xB2AA, 0x52C4, 0x84C7, 0x52C5, 0x84C8, 0x52C6, 0x84C9, + 0x52C7, 0xD3C2, 0x52C8, 0x84CA, 0x52C9, 0xC3E3, 0x52CA, 0x84CB, + 0x52CB, 0xD1AB, 0x52CC, 0x84CC, 0x52CD, 0x84CD, 0x52CE, 0x84CE, + 0x52CF, 0x84CF, 0x52D0, 0xDBC2, 0x52D1, 0x84D0, 0x52D2, 0xC0D5, + 0x52D3, 0x84D1, 0x52D4, 0x84D2, 0x52D5, 0x84D3, 0x52D6, 0xDBC3, + 0x52D7, 0x84D4, 0x52D8, 0xBFB1, 0x52D9, 0x84D5, 0x52DA, 0x84D6, + 0x52DB, 0x84D7, 0x52DC, 0x84D8, 0x52DD, 0x84D9, 0x52DE, 0x84DA, + 0x52DF, 0xC4BC, 0x52E0, 0x84DB, 0x52E1, 0x84DC, 0x52E2, 0x84DD, + 0x52E3, 0x84DE, 0x52E4, 0xC7DA, 0x52E5, 0x84DF, 0x52E6, 0x84E0, + 0x52E7, 0x84E1, 0x52E8, 0x84E2, 0x52E9, 0x84E3, 0x52EA, 0x84E4, + 0x52EB, 0x84E5, 0x52EC, 0x84E6, 0x52ED, 0x84E7, 0x52EE, 0x84E8, + 0x52EF, 0x84E9, 0x52F0, 0xDBC4, 0x52F1, 0x84EA, 0x52F2, 0x84EB, + 0x52F3, 0x84EC, 0x52F4, 0x84ED, 0x52F5, 0x84EE, 0x52F6, 0x84EF, + 0x52F7, 0x84F0, 0x52F8, 0x84F1, 0x52F9, 0xD9E8, 0x52FA, 0xC9D7, + 0x52FB, 0x84F2, 0x52FC, 0x84F3, 0x52FD, 0x84F4, 0x52FE, 0xB9B4, + 0x52FF, 0xCEF0, 0x5300, 0xD4C8, 0x5301, 0x84F5, 0x5302, 0x84F6, + 0x5303, 0x84F7, 0x5304, 0x84F8, 0x5305, 0xB0FC, 0x5306, 0xB4D2, + 0x5307, 0x84F9, 0x5308, 0xD0D9, 0x5309, 0x84FA, 0x530A, 0x84FB, + 0x530B, 0x84FC, 0x530C, 0x84FD, 0x530D, 0xD9E9, 0x530E, 0x84FE, + 0x530F, 0xDECB, 0x5310, 0xD9EB, 0x5311, 0x8540, 0x5312, 0x8541, + 0x5313, 0x8542, 0x5314, 0x8543, 0x5315, 0xD8B0, 0x5316, 0xBBAF, + 0x5317, 0xB1B1, 0x5318, 0x8544, 0x5319, 0xB3D7, 0x531A, 0xD8CE, + 0x531B, 0x8545, 0x531C, 0x8546, 0x531D, 0xD4D1, 0x531E, 0x8547, + 0x531F, 0x8548, 0x5320, 0xBDB3, 0x5321, 0xBFEF, 0x5322, 0x8549, + 0x5323, 0xCFBB, 0x5324, 0x854A, 0x5325, 0x854B, 0x5326, 0xD8D0, + 0x5327, 0x854C, 0x5328, 0x854D, 0x5329, 0x854E, 0x532A, 0xB7CB, + 0x532B, 0x854F, 0x532C, 0x8550, 0x532D, 0x8551, 0x532E, 0xD8D1, + 0x532F, 0x8552, 0x5330, 0x8553, 0x5331, 0x8554, 0x5332, 0x8555, + 0x5333, 0x8556, 0x5334, 0x8557, 0x5335, 0x8558, 0x5336, 0x8559, + 0x5337, 0x855A, 0x5338, 0x855B, 0x5339, 0xC6A5, 0x533A, 0xC7F8, + 0x533B, 0xD2BD, 0x533C, 0x855C, 0x533D, 0x855D, 0x533E, 0xD8D2, + 0x533F, 0xC4E4, 0x5340, 0x855E, 0x5341, 0xCAAE, 0x5342, 0x855F, + 0x5343, 0xC7A7, 0x5344, 0x8560, 0x5345, 0xD8A6, 0x5346, 0x8561, + 0x5347, 0xC9FD, 0x5348, 0xCEE7, 0x5349, 0xBBDC, 0x534A, 0xB0EB, + 0x534B, 0x8562, 0x534C, 0x8563, 0x534D, 0x8564, 0x534E, 0xBBAA, + 0x534F, 0xD0AD, 0x5350, 0x8565, 0x5351, 0xB1B0, 0x5352, 0xD7E4, + 0x5353, 0xD7BF, 0x5354, 0x8566, 0x5355, 0xB5A5, 0x5356, 0xC2F4, + 0x5357, 0xC4CF, 0x5358, 0x8567, 0x5359, 0x8568, 0x535A, 0xB2A9, + 0x535B, 0x8569, 0x535C, 0xB2B7, 0x535D, 0x856A, 0x535E, 0xB1E5, + 0x535F, 0xDFB2, 0x5360, 0xD5BC, 0x5361, 0xBFA8, 0x5362, 0xC2AC, + 0x5363, 0xD8D5, 0x5364, 0xC2B1, 0x5365, 0x856B, 0x5366, 0xD8D4, + 0x5367, 0xCED4, 0x5368, 0x856C, 0x5369, 0xDAE0, 0x536A, 0x856D, + 0x536B, 0xCEC0, 0x536C, 0x856E, 0x536D, 0x856F, 0x536E, 0xD8B4, + 0x536F, 0xC3AE, 0x5370, 0xD3A1, 0x5371, 0xCEA3, 0x5372, 0x8570, + 0x5373, 0xBCB4, 0x5374, 0xC8B4, 0x5375, 0xC2D1, 0x5376, 0x8571, + 0x5377, 0xBEED, 0x5378, 0xD0B6, 0x5379, 0x8572, 0x537A, 0xDAE1, + 0x537B, 0x8573, 0x537C, 0x8574, 0x537D, 0x8575, 0x537E, 0x8576, + 0x537F, 0xC7E4, 0x5380, 0x8577, 0x5381, 0x8578, 0x5382, 0xB3A7, + 0x5383, 0x8579, 0x5384, 0xB6F2, 0x5385, 0xCCFC, 0x5386, 0xC0FA, + 0x5387, 0x857A, 0x5388, 0x857B, 0x5389, 0xC0F7, 0x538A, 0x857C, + 0x538B, 0xD1B9, 0x538C, 0xD1E1, 0x538D, 0xD8C7, 0x538E, 0x857D, + 0x538F, 0x857E, 0x5390, 0x8580, 0x5391, 0x8581, 0x5392, 0x8582, + 0x5393, 0x8583, 0x5394, 0x8584, 0x5395, 0xB2DE, 0x5396, 0x8585, + 0x5397, 0x8586, 0x5398, 0xC0E5, 0x5399, 0x8587, 0x539A, 0xBAF1, + 0x539B, 0x8588, 0x539C, 0x8589, 0x539D, 0xD8C8, 0x539E, 0x858A, + 0x539F, 0xD4AD, 0x53A0, 0x858B, 0x53A1, 0x858C, 0x53A2, 0xCFE1, + 0x53A3, 0xD8C9, 0x53A4, 0x858D, 0x53A5, 0xD8CA, 0x53A6, 0xCFC3, + 0x53A7, 0x858E, 0x53A8, 0xB3F8, 0x53A9, 0xBEC7, 0x53AA, 0x858F, + 0x53AB, 0x8590, 0x53AC, 0x8591, 0x53AD, 0x8592, 0x53AE, 0xD8CB, + 0x53AF, 0x8593, 0x53B0, 0x8594, 0x53B1, 0x8595, 0x53B2, 0x8596, + 0x53B3, 0x8597, 0x53B4, 0x8598, 0x53B5, 0x8599, 0x53B6, 0xDBCC, + 0x53B7, 0x859A, 0x53B8, 0x859B, 0x53B9, 0x859C, 0x53BA, 0x859D, + 0x53BB, 0xC8A5, 0x53BC, 0x859E, 0x53BD, 0x859F, 0x53BE, 0x85A0, + 0x53BF, 0xCFD8, 0x53C0, 0x85A1, 0x53C1, 0xC8FE, 0x53C2, 0xB2CE, + 0x53C3, 0x85A2, 0x53C4, 0x85A3, 0x53C5, 0x85A4, 0x53C6, 0x85A5, + 0x53C7, 0x85A6, 0x53C8, 0xD3D6, 0x53C9, 0xB2E6, 0x53CA, 0xBCB0, + 0x53CB, 0xD3D1, 0x53CC, 0xCBAB, 0x53CD, 0xB7B4, 0x53CE, 0x85A7, + 0x53CF, 0x85A8, 0x53D0, 0x85A9, 0x53D1, 0xB7A2, 0x53D2, 0x85AA, + 0x53D3, 0x85AB, 0x53D4, 0xCAE5, 0x53D5, 0x85AC, 0x53D6, 0xC8A1, + 0x53D7, 0xCADC, 0x53D8, 0xB1E4, 0x53D9, 0xD0F0, 0x53DA, 0x85AD, + 0x53DB, 0xC5D1, 0x53DC, 0x85AE, 0x53DD, 0x85AF, 0x53DE, 0x85B0, + 0x53DF, 0xDBC5, 0x53E0, 0xB5FE, 0x53E1, 0x85B1, 0x53E2, 0x85B2, + 0x53E3, 0xBFDA, 0x53E4, 0xB9C5, 0x53E5, 0xBEE4, 0x53E6, 0xC1ED, + 0x53E7, 0x85B3, 0x53E8, 0xDFB6, 0x53E9, 0xDFB5, 0x53EA, 0xD6BB, + 0x53EB, 0xBDD0, 0x53EC, 0xD5D9, 0x53ED, 0xB0C8, 0x53EE, 0xB6A3, + 0x53EF, 0xBFC9, 0x53F0, 0xCCA8, 0x53F1, 0xDFB3, 0x53F2, 0xCAB7, + 0x53F3, 0xD3D2, 0x53F4, 0x85B4, 0x53F5, 0xD8CF, 0x53F6, 0xD2B6, + 0x53F7, 0xBAC5, 0x53F8, 0xCBBE, 0x53F9, 0xCCBE, 0x53FA, 0x85B5, + 0x53FB, 0xDFB7, 0x53FC, 0xB5F0, 0x53FD, 0xDFB4, 0x53FE, 0x85B6, + 0x53FF, 0x85B7, 0x5400, 0x85B8, 0x5401, 0xD3F5, 0x5402, 0x85B9, + 0x5403, 0xB3D4, 0x5404, 0xB8F7, 0x5405, 0x85BA, 0x5406, 0xDFBA, + 0x5407, 0x85BB, 0x5408, 0xBACF, 0x5409, 0xBCAA, 0x540A, 0xB5F5, + 0x540B, 0x85BC, 0x540C, 0xCDAC, 0x540D, 0xC3FB, 0x540E, 0xBAF3, + 0x540F, 0xC0F4, 0x5410, 0xCDC2, 0x5411, 0xCFF2, 0x5412, 0xDFB8, + 0x5413, 0xCFC5, 0x5414, 0x85BD, 0x5415, 0xC2C0, 0x5416, 0xDFB9, + 0x5417, 0xC2F0, 0x5418, 0x85BE, 0x5419, 0x85BF, 0x541A, 0x85C0, + 0x541B, 0xBEFD, 0x541C, 0x85C1, 0x541D, 0xC1DF, 0x541E, 0xCDCC, + 0x541F, 0xD2F7, 0x5420, 0xB7CD, 0x5421, 0xDFC1, 0x5422, 0x85C2, + 0x5423, 0xDFC4, 0x5424, 0x85C3, 0x5425, 0x85C4, 0x5426, 0xB7F1, + 0x5427, 0xB0C9, 0x5428, 0xB6D6, 0x5429, 0xB7D4, 0x542A, 0x85C5, + 0x542B, 0xBAAC, 0x542C, 0xCCFD, 0x542D, 0xBFD4, 0x542E, 0xCBB1, + 0x542F, 0xC6F4, 0x5430, 0x85C6, 0x5431, 0xD6A8, 0x5432, 0xDFC5, + 0x5433, 0x85C7, 0x5434, 0xCEE2, 0x5435, 0xB3B3, 0x5436, 0x85C8, + 0x5437, 0x85C9, 0x5438, 0xCEFC, 0x5439, 0xB4B5, 0x543A, 0x85CA, + 0x543B, 0xCEC7, 0x543C, 0xBAF0, 0x543D, 0x85CB, 0x543E, 0xCEE1, + 0x543F, 0x85CC, 0x5440, 0xD1BD, 0x5441, 0x85CD, 0x5442, 0x85CE, + 0x5443, 0xDFC0, 0x5444, 0x85CF, 0x5445, 0x85D0, 0x5446, 0xB4F4, + 0x5447, 0x85D1, 0x5448, 0xB3CA, 0x5449, 0x85D2, 0x544A, 0xB8E6, + 0x544B, 0xDFBB, 0x544C, 0x85D3, 0x544D, 0x85D4, 0x544E, 0x85D5, + 0x544F, 0x85D6, 0x5450, 0xC4C5, 0x5451, 0x85D7, 0x5452, 0xDFBC, + 0x5453, 0xDFBD, 0x5454, 0xDFBE, 0x5455, 0xC5BB, 0x5456, 0xDFBF, + 0x5457, 0xDFC2, 0x5458, 0xD4B1, 0x5459, 0xDFC3, 0x545A, 0x85D8, + 0x545B, 0xC7BA, 0x545C, 0xCED8, 0x545D, 0x85D9, 0x545E, 0x85DA, + 0x545F, 0x85DB, 0x5460, 0x85DC, 0x5461, 0x85DD, 0x5462, 0xC4D8, + 0x5463, 0x85DE, 0x5464, 0xDFCA, 0x5465, 0x85DF, 0x5466, 0xDFCF, + 0x5467, 0x85E0, 0x5468, 0xD6DC, 0x5469, 0x85E1, 0x546A, 0x85E2, + 0x546B, 0x85E3, 0x546C, 0x85E4, 0x546D, 0x85E5, 0x546E, 0x85E6, + 0x546F, 0x85E7, 0x5470, 0x85E8, 0x5471, 0xDFC9, 0x5472, 0xDFDA, + 0x5473, 0xCEB6, 0x5474, 0x85E9, 0x5475, 0xBAC7, 0x5476, 0xDFCE, + 0x5477, 0xDFC8, 0x5478, 0xC5DE, 0x5479, 0x85EA, 0x547A, 0x85EB, + 0x547B, 0xC9EB, 0x547C, 0xBAF4, 0x547D, 0xC3FC, 0x547E, 0x85EC, + 0x547F, 0x85ED, 0x5480, 0xBED7, 0x5481, 0x85EE, 0x5482, 0xDFC6, + 0x5483, 0x85EF, 0x5484, 0xDFCD, 0x5485, 0x85F0, 0x5486, 0xC5D8, + 0x5487, 0x85F1, 0x5488, 0x85F2, 0x5489, 0x85F3, 0x548A, 0x85F4, + 0x548B, 0xD5A6, 0x548C, 0xBACD, 0x548D, 0x85F5, 0x548E, 0xBECC, + 0x548F, 0xD3BD, 0x5490, 0xB8C0, 0x5491, 0x85F6, 0x5492, 0xD6E4, + 0x5493, 0x85F7, 0x5494, 0xDFC7, 0x5495, 0xB9BE, 0x5496, 0xBFA7, + 0x5497, 0x85F8, 0x5498, 0x85F9, 0x5499, 0xC1FC, 0x549A, 0xDFCB, + 0x549B, 0xDFCC, 0x549C, 0x85FA, 0x549D, 0xDFD0, 0x549E, 0x85FB, + 0x549F, 0x85FC, 0x54A0, 0x85FD, 0x54A1, 0x85FE, 0x54A2, 0x8640, + 0x54A3, 0xDFDB, 0x54A4, 0xDFE5, 0x54A5, 0x8641, 0x54A6, 0xDFD7, + 0x54A7, 0xDFD6, 0x54A8, 0xD7C9, 0x54A9, 0xDFE3, 0x54AA, 0xDFE4, + 0x54AB, 0xE5EB, 0x54AC, 0xD2A7, 0x54AD, 0xDFD2, 0x54AE, 0x8642, + 0x54AF, 0xBFA9, 0x54B0, 0x8643, 0x54B1, 0xD4DB, 0x54B2, 0x8644, + 0x54B3, 0xBFC8, 0x54B4, 0xDFD4, 0x54B5, 0x8645, 0x54B6, 0x8646, + 0x54B7, 0x8647, 0x54B8, 0xCFCC, 0x54B9, 0x8648, 0x54BA, 0x8649, + 0x54BB, 0xDFDD, 0x54BC, 0x864A, 0x54BD, 0xD1CA, 0x54BE, 0x864B, + 0x54BF, 0xDFDE, 0x54C0, 0xB0A7, 0x54C1, 0xC6B7, 0x54C2, 0xDFD3, + 0x54C3, 0x864C, 0x54C4, 0xBAE5, 0x54C5, 0x864D, 0x54C6, 0xB6DF, + 0x54C7, 0xCDDB, 0x54C8, 0xB9FE, 0x54C9, 0xD4D5, 0x54CA, 0x864E, + 0x54CB, 0x864F, 0x54CC, 0xDFDF, 0x54CD, 0xCFEC, 0x54CE, 0xB0A5, + 0x54CF, 0xDFE7, 0x54D0, 0xDFD1, 0x54D1, 0xD1C6, 0x54D2, 0xDFD5, + 0x54D3, 0xDFD8, 0x54D4, 0xDFD9, 0x54D5, 0xDFDC, 0x54D6, 0x8650, + 0x54D7, 0xBBA9, 0x54D8, 0x8651, 0x54D9, 0xDFE0, 0x54DA, 0xDFE1, + 0x54DB, 0x8652, 0x54DC, 0xDFE2, 0x54DD, 0xDFE6, 0x54DE, 0xDFE8, + 0x54DF, 0xD3B4, 0x54E0, 0x8653, 0x54E1, 0x8654, 0x54E2, 0x8655, + 0x54E3, 0x8656, 0x54E4, 0x8657, 0x54E5, 0xB8E7, 0x54E6, 0xC5B6, + 0x54E7, 0xDFEA, 0x54E8, 0xC9DA, 0x54E9, 0xC1A8, 0x54EA, 0xC4C4, + 0x54EB, 0x8658, 0x54EC, 0x8659, 0x54ED, 0xBFDE, 0x54EE, 0xCFF8, + 0x54EF, 0x865A, 0x54F0, 0x865B, 0x54F1, 0x865C, 0x54F2, 0xD5DC, + 0x54F3, 0xDFEE, 0x54F4, 0x865D, 0x54F5, 0x865E, 0x54F6, 0x865F, + 0x54F7, 0x8660, 0x54F8, 0x8661, 0x54F9, 0x8662, 0x54FA, 0xB2B8, + 0x54FB, 0x8663, 0x54FC, 0xBADF, 0x54FD, 0xDFEC, 0x54FE, 0x8664, + 0x54FF, 0xDBC1, 0x5500, 0x8665, 0x5501, 0xD1E4, 0x5502, 0x8666, + 0x5503, 0x8667, 0x5504, 0x8668, 0x5505, 0x8669, 0x5506, 0xCBF4, + 0x5507, 0xB4BD, 0x5508, 0x866A, 0x5509, 0xB0A6, 0x550A, 0x866B, + 0x550B, 0x866C, 0x550C, 0x866D, 0x550D, 0x866E, 0x550E, 0x866F, + 0x550F, 0xDFF1, 0x5510, 0xCCC6, 0x5511, 0xDFF2, 0x5512, 0x8670, + 0x5513, 0x8671, 0x5514, 0xDFED, 0x5515, 0x8672, 0x5516, 0x8673, + 0x5517, 0x8674, 0x5518, 0x8675, 0x5519, 0x8676, 0x551A, 0x8677, + 0x551B, 0xDFE9, 0x551C, 0x8678, 0x551D, 0x8679, 0x551E, 0x867A, + 0x551F, 0x867B, 0x5520, 0xDFEB, 0x5521, 0x867C, 0x5522, 0xDFEF, + 0x5523, 0xDFF0, 0x5524, 0xBBBD, 0x5525, 0x867D, 0x5526, 0x867E, + 0x5527, 0xDFF3, 0x5528, 0x8680, 0x5529, 0x8681, 0x552A, 0xDFF4, + 0x552B, 0x8682, 0x552C, 0xBBA3, 0x552D, 0x8683, 0x552E, 0xCADB, + 0x552F, 0xCEA8, 0x5530, 0xE0A7, 0x5531, 0xB3AA, 0x5532, 0x8684, + 0x5533, 0xE0A6, 0x5534, 0x8685, 0x5535, 0x8686, 0x5536, 0x8687, + 0x5537, 0xE0A1, 0x5538, 0x8688, 0x5539, 0x8689, 0x553A, 0x868A, + 0x553B, 0x868B, 0x553C, 0xDFFE, 0x553D, 0x868C, 0x553E, 0xCDD9, + 0x553F, 0xDFFC, 0x5540, 0x868D, 0x5541, 0xDFFA, 0x5542, 0x868E, + 0x5543, 0xBFD0, 0x5544, 0xD7C4, 0x5545, 0x868F, 0x5546, 0xC9CC, + 0x5547, 0x8690, 0x5548, 0x8691, 0x5549, 0xDFF8, 0x554A, 0xB0A1, + 0x554B, 0x8692, 0x554C, 0x8693, 0x554D, 0x8694, 0x554E, 0x8695, + 0x554F, 0x8696, 0x5550, 0xDFFD, 0x5551, 0x8697, 0x5552, 0x8698, + 0x5553, 0x8699, 0x5554, 0x869A, 0x5555, 0xDFFB, 0x5556, 0xE0A2, + 0x5557, 0x869B, 0x5558, 0x869C, 0x5559, 0x869D, 0x555A, 0x869E, + 0x555B, 0x869F, 0x555C, 0xE0A8, 0x555D, 0x86A0, 0x555E, 0x86A1, + 0x555F, 0x86A2, 0x5560, 0x86A3, 0x5561, 0xB7C8, 0x5562, 0x86A4, + 0x5563, 0x86A5, 0x5564, 0xC6A1, 0x5565, 0xC9B6, 0x5566, 0xC0B2, + 0x5567, 0xDFF5, 0x5568, 0x86A6, 0x5569, 0x86A7, 0x556A, 0xC5BE, + 0x556B, 0x86A8, 0x556C, 0xD8C4, 0x556D, 0xDFF9, 0x556E, 0xC4F6, + 0x556F, 0x86A9, 0x5570, 0x86AA, 0x5571, 0x86AB, 0x5572, 0x86AC, + 0x5573, 0x86AD, 0x5574, 0x86AE, 0x5575, 0xE0A3, 0x5576, 0xE0A4, + 0x5577, 0xE0A5, 0x5578, 0xD0A5, 0x5579, 0x86AF, 0x557A, 0x86B0, + 0x557B, 0xE0B4, 0x557C, 0xCCE4, 0x557D, 0x86B1, 0x557E, 0xE0B1, + 0x557F, 0x86B2, 0x5580, 0xBFA6, 0x5581, 0xE0AF, 0x5582, 0xCEB9, + 0x5583, 0xE0AB, 0x5584, 0xC9C6, 0x5585, 0x86B3, 0x5586, 0x86B4, + 0x5587, 0xC0AE, 0x5588, 0xE0AE, 0x5589, 0xBAED, 0x558A, 0xBAB0, + 0x558B, 0xE0A9, 0x558C, 0x86B5, 0x558D, 0x86B6, 0x558E, 0x86B7, + 0x558F, 0xDFF6, 0x5590, 0x86B8, 0x5591, 0xE0B3, 0x5592, 0x86B9, + 0x5593, 0x86BA, 0x5594, 0xE0B8, 0x5595, 0x86BB, 0x5596, 0x86BC, + 0x5597, 0x86BD, 0x5598, 0xB4AD, 0x5599, 0xE0B9, 0x559A, 0x86BE, + 0x559B, 0x86BF, 0x559C, 0xCFB2, 0x559D, 0xBAC8, 0x559E, 0x86C0, + 0x559F, 0xE0B0, 0x55A0, 0x86C1, 0x55A1, 0x86C2, 0x55A2, 0x86C3, + 0x55A3, 0x86C4, 0x55A4, 0x86C5, 0x55A5, 0x86C6, 0x55A6, 0x86C7, + 0x55A7, 0xD0FA, 0x55A8, 0x86C8, 0x55A9, 0x86C9, 0x55AA, 0x86CA, + 0x55AB, 0x86CB, 0x55AC, 0x86CC, 0x55AD, 0x86CD, 0x55AE, 0x86CE, + 0x55AF, 0x86CF, 0x55B0, 0x86D0, 0x55B1, 0xE0AC, 0x55B2, 0x86D1, + 0x55B3, 0xD4FB, 0x55B4, 0x86D2, 0x55B5, 0xDFF7, 0x55B6, 0x86D3, + 0x55B7, 0xC5E7, 0x55B8, 0x86D4, 0x55B9, 0xE0AD, 0x55BA, 0x86D5, + 0x55BB, 0xD3F7, 0x55BC, 0x86D6, 0x55BD, 0xE0B6, 0x55BE, 0xE0B7, + 0x55BF, 0x86D7, 0x55C0, 0x86D8, 0x55C1, 0x86D9, 0x55C2, 0x86DA, + 0x55C3, 0x86DB, 0x55C4, 0xE0C4, 0x55C5, 0xD0E1, 0x55C6, 0x86DC, + 0x55C7, 0x86DD, 0x55C8, 0x86DE, 0x55C9, 0xE0BC, 0x55CA, 0x86DF, + 0x55CB, 0x86E0, 0x55CC, 0xE0C9, 0x55CD, 0xE0CA, 0x55CE, 0x86E1, + 0x55CF, 0x86E2, 0x55D0, 0x86E3, 0x55D1, 0xE0BE, 0x55D2, 0xE0AA, + 0x55D3, 0xC9A4, 0x55D4, 0xE0C1, 0x55D5, 0x86E4, 0x55D6, 0xE0B2, + 0x55D7, 0x86E5, 0x55D8, 0x86E6, 0x55D9, 0x86E7, 0x55DA, 0x86E8, + 0x55DB, 0x86E9, 0x55DC, 0xCAC8, 0x55DD, 0xE0C3, 0x55DE, 0x86EA, + 0x55DF, 0xE0B5, 0x55E0, 0x86EB, 0x55E1, 0xCECB, 0x55E2, 0x86EC, + 0x55E3, 0xCBC3, 0x55E4, 0xE0CD, 0x55E5, 0xE0C6, 0x55E6, 0xE0C2, + 0x55E7, 0x86ED, 0x55E8, 0xE0CB, 0x55E9, 0x86EE, 0x55EA, 0xE0BA, + 0x55EB, 0xE0BF, 0x55EC, 0xE0C0, 0x55ED, 0x86EF, 0x55EE, 0x86F0, + 0x55EF, 0xE0C5, 0x55F0, 0x86F1, 0x55F1, 0x86F2, 0x55F2, 0xE0C7, + 0x55F3, 0xE0C8, 0x55F4, 0x86F3, 0x55F5, 0xE0CC, 0x55F6, 0x86F4, + 0x55F7, 0xE0BB, 0x55F8, 0x86F5, 0x55F9, 0x86F6, 0x55FA, 0x86F7, + 0x55FB, 0x86F8, 0x55FC, 0x86F9, 0x55FD, 0xCBD4, 0x55FE, 0xE0D5, + 0x55FF, 0x86FA, 0x5600, 0xE0D6, 0x5601, 0xE0D2, 0x5602, 0x86FB, + 0x5603, 0x86FC, 0x5604, 0x86FD, 0x5605, 0x86FE, 0x5606, 0x8740, + 0x5607, 0x8741, 0x5608, 0xE0D0, 0x5609, 0xBCCE, 0x560A, 0x8742, + 0x560B, 0x8743, 0x560C, 0xE0D1, 0x560D, 0x8744, 0x560E, 0xB8C2, + 0x560F, 0xD8C5, 0x5610, 0x8745, 0x5611, 0x8746, 0x5612, 0x8747, + 0x5613, 0x8748, 0x5614, 0x8749, 0x5615, 0x874A, 0x5616, 0x874B, + 0x5617, 0x874C, 0x5618, 0xD0EA, 0x5619, 0x874D, 0x561A, 0x874E, + 0x561B, 0xC2EF, 0x561C, 0x874F, 0x561D, 0x8750, 0x561E, 0xE0CF, + 0x561F, 0xE0BD, 0x5620, 0x8751, 0x5621, 0x8752, 0x5622, 0x8753, + 0x5623, 0xE0D4, 0x5624, 0xE0D3, 0x5625, 0x8754, 0x5626, 0x8755, + 0x5627, 0xE0D7, 0x5628, 0x8756, 0x5629, 0x8757, 0x562A, 0x8758, + 0x562B, 0x8759, 0x562C, 0xE0DC, 0x562D, 0xE0D8, 0x562E, 0x875A, + 0x562F, 0x875B, 0x5630, 0x875C, 0x5631, 0xD6F6, 0x5632, 0xB3B0, + 0x5633, 0x875D, 0x5634, 0xD7EC, 0x5635, 0x875E, 0x5636, 0xCBBB, + 0x5637, 0x875F, 0x5638, 0x8760, 0x5639, 0xE0DA, 0x563A, 0x8761, + 0x563B, 0xCEFB, 0x563C, 0x8762, 0x563D, 0x8763, 0x563E, 0x8764, + 0x563F, 0xBAD9, 0x5640, 0x8765, 0x5641, 0x8766, 0x5642, 0x8767, + 0x5643, 0x8768, 0x5644, 0x8769, 0x5645, 0x876A, 0x5646, 0x876B, + 0x5647, 0x876C, 0x5648, 0x876D, 0x5649, 0x876E, 0x564A, 0x876F, + 0x564B, 0x8770, 0x564C, 0xE0E1, 0x564D, 0xE0DD, 0x564E, 0xD2AD, + 0x564F, 0x8771, 0x5650, 0x8772, 0x5651, 0x8773, 0x5652, 0x8774, + 0x5653, 0x8775, 0x5654, 0xE0E2, 0x5655, 0x8776, 0x5656, 0x8777, + 0x5657, 0xE0DB, 0x5658, 0xE0D9, 0x5659, 0xE0DF, 0x565A, 0x8778, + 0x565B, 0x8779, 0x565C, 0xE0E0, 0x565D, 0x877A, 0x565E, 0x877B, + 0x565F, 0x877C, 0x5660, 0x877D, 0x5661, 0x877E, 0x5662, 0xE0DE, + 0x5663, 0x8780, 0x5664, 0xE0E4, 0x5665, 0x8781, 0x5666, 0x8782, + 0x5667, 0x8783, 0x5668, 0xC6F7, 0x5669, 0xD8AC, 0x566A, 0xD4EB, + 0x566B, 0xE0E6, 0x566C, 0xCAC9, 0x566D, 0x8784, 0x566E, 0x8785, + 0x566F, 0x8786, 0x5670, 0x8787, 0x5671, 0xE0E5, 0x5672, 0x8788, + 0x5673, 0x8789, 0x5674, 0x878A, 0x5675, 0x878B, 0x5676, 0xB8C1, + 0x5677, 0x878C, 0x5678, 0x878D, 0x5679, 0x878E, 0x567A, 0x878F, + 0x567B, 0xE0E7, 0x567C, 0xE0E8, 0x567D, 0x8790, 0x567E, 0x8791, + 0x567F, 0x8792, 0x5680, 0x8793, 0x5681, 0x8794, 0x5682, 0x8795, + 0x5683, 0x8796, 0x5684, 0x8797, 0x5685, 0xE0E9, 0x5686, 0xE0E3, + 0x5687, 0x8798, 0x5688, 0x8799, 0x5689, 0x879A, 0x568A, 0x879B, + 0x568B, 0x879C, 0x568C, 0x879D, 0x568D, 0x879E, 0x568E, 0xBABF, + 0x568F, 0xCCE7, 0x5690, 0x879F, 0x5691, 0x87A0, 0x5692, 0x87A1, + 0x5693, 0xE0EA, 0x5694, 0x87A2, 0x5695, 0x87A3, 0x5696, 0x87A4, + 0x5697, 0x87A5, 0x5698, 0x87A6, 0x5699, 0x87A7, 0x569A, 0x87A8, + 0x569B, 0x87A9, 0x569C, 0x87AA, 0x569D, 0x87AB, 0x569E, 0x87AC, + 0x569F, 0x87AD, 0x56A0, 0x87AE, 0x56A1, 0x87AF, 0x56A2, 0x87B0, + 0x56A3, 0xCFF9, 0x56A4, 0x87B1, 0x56A5, 0x87B2, 0x56A6, 0x87B3, + 0x56A7, 0x87B4, 0x56A8, 0x87B5, 0x56A9, 0x87B6, 0x56AA, 0x87B7, + 0x56AB, 0x87B8, 0x56AC, 0x87B9, 0x56AD, 0x87BA, 0x56AE, 0x87BB, + 0x56AF, 0xE0EB, 0x56B0, 0x87BC, 0x56B1, 0x87BD, 0x56B2, 0x87BE, + 0x56B3, 0x87BF, 0x56B4, 0x87C0, 0x56B5, 0x87C1, 0x56B6, 0x87C2, + 0x56B7, 0xC8C2, 0x56B8, 0x87C3, 0x56B9, 0x87C4, 0x56BA, 0x87C5, + 0x56BB, 0x87C6, 0x56BC, 0xBDC0, 0x56BD, 0x87C7, 0x56BE, 0x87C8, + 0x56BF, 0x87C9, 0x56C0, 0x87CA, 0x56C1, 0x87CB, 0x56C2, 0x87CC, + 0x56C3, 0x87CD, 0x56C4, 0x87CE, 0x56C5, 0x87CF, 0x56C6, 0x87D0, + 0x56C7, 0x87D1, 0x56C8, 0x87D2, 0x56C9, 0x87D3, 0x56CA, 0xC4D2, + 0x56CB, 0x87D4, 0x56CC, 0x87D5, 0x56CD, 0x87D6, 0x56CE, 0x87D7, + 0x56CF, 0x87D8, 0x56D0, 0x87D9, 0x56D1, 0x87DA, 0x56D2, 0x87DB, + 0x56D3, 0x87DC, 0x56D4, 0xE0EC, 0x56D5, 0x87DD, 0x56D6, 0x87DE, + 0x56D7, 0xE0ED, 0x56D8, 0x87DF, 0x56D9, 0x87E0, 0x56DA, 0xC7F4, + 0x56DB, 0xCBC4, 0x56DC, 0x87E1, 0x56DD, 0xE0EE, 0x56DE, 0xBBD8, + 0x56DF, 0xD8B6, 0x56E0, 0xD2F2, 0x56E1, 0xE0EF, 0x56E2, 0xCDC5, + 0x56E3, 0x87E2, 0x56E4, 0xB6DA, 0x56E5, 0x87E3, 0x56E6, 0x87E4, + 0x56E7, 0x87E5, 0x56E8, 0x87E6, 0x56E9, 0x87E7, 0x56EA, 0x87E8, + 0x56EB, 0xE0F1, 0x56EC, 0x87E9, 0x56ED, 0xD4B0, 0x56EE, 0x87EA, + 0x56EF, 0x87EB, 0x56F0, 0xC0A7, 0x56F1, 0xB4D1, 0x56F2, 0x87EC, + 0x56F3, 0x87ED, 0x56F4, 0xCEA7, 0x56F5, 0xE0F0, 0x56F6, 0x87EE, + 0x56F7, 0x87EF, 0x56F8, 0x87F0, 0x56F9, 0xE0F2, 0x56FA, 0xB9CC, + 0x56FB, 0x87F1, 0x56FC, 0x87F2, 0x56FD, 0xB9FA, 0x56FE, 0xCDBC, + 0x56FF, 0xE0F3, 0x5700, 0x87F3, 0x5701, 0x87F4, 0x5702, 0x87F5, + 0x5703, 0xC6D4, 0x5704, 0xE0F4, 0x5705, 0x87F6, 0x5706, 0xD4B2, + 0x5707, 0x87F7, 0x5708, 0xC8A6, 0x5709, 0xE0F6, 0x570A, 0xE0F5, + 0x570B, 0x87F8, 0x570C, 0x87F9, 0x570D, 0x87FA, 0x570E, 0x87FB, + 0x570F, 0x87FC, 0x5710, 0x87FD, 0x5711, 0x87FE, 0x5712, 0x8840, + 0x5713, 0x8841, 0x5714, 0x8842, 0x5715, 0x8843, 0x5716, 0x8844, + 0x5717, 0x8845, 0x5718, 0x8846, 0x5719, 0x8847, 0x571A, 0x8848, + 0x571B, 0x8849, 0x571C, 0xE0F7, 0x571D, 0x884A, 0x571E, 0x884B, + 0x571F, 0xCDC1, 0x5720, 0x884C, 0x5721, 0x884D, 0x5722, 0x884E, + 0x5723, 0xCAA5, 0x5724, 0x884F, 0x5725, 0x8850, 0x5726, 0x8851, + 0x5727, 0x8852, 0x5728, 0xD4DA, 0x5729, 0xDBD7, 0x572A, 0xDBD9, + 0x572B, 0x8853, 0x572C, 0xDBD8, 0x572D, 0xB9E7, 0x572E, 0xDBDC, + 0x572F, 0xDBDD, 0x5730, 0xB5D8, 0x5731, 0x8854, 0x5732, 0x8855, + 0x5733, 0xDBDA, 0x5734, 0x8856, 0x5735, 0x8857, 0x5736, 0x8858, + 0x5737, 0x8859, 0x5738, 0x885A, 0x5739, 0xDBDB, 0x573A, 0xB3A1, + 0x573B, 0xDBDF, 0x573C, 0x885B, 0x573D, 0x885C, 0x573E, 0xBBF8, + 0x573F, 0x885D, 0x5740, 0xD6B7, 0x5741, 0x885E, 0x5742, 0xDBE0, + 0x5743, 0x885F, 0x5744, 0x8860, 0x5745, 0x8861, 0x5746, 0x8862, + 0x5747, 0xBEF9, 0x5748, 0x8863, 0x5749, 0x8864, 0x574A, 0xB7BB, + 0x574B, 0x8865, 0x574C, 0xDBD0, 0x574D, 0xCCAE, 0x574E, 0xBFB2, + 0x574F, 0xBBB5, 0x5750, 0xD7F8, 0x5751, 0xBFD3, 0x5752, 0x8866, + 0x5753, 0x8867, 0x5754, 0x8868, 0x5755, 0x8869, 0x5756, 0x886A, + 0x5757, 0xBFE9, 0x5758, 0x886B, 0x5759, 0x886C, 0x575A, 0xBCE1, + 0x575B, 0xCCB3, 0x575C, 0xDBDE, 0x575D, 0xB0D3, 0x575E, 0xCEEB, + 0x575F, 0xB7D8, 0x5760, 0xD7B9, 0x5761, 0xC6C2, 0x5762, 0x886D, + 0x5763, 0x886E, 0x5764, 0xC0A4, 0x5765, 0x886F, 0x5766, 0xCCB9, + 0x5767, 0x8870, 0x5768, 0xDBE7, 0x5769, 0xDBE1, 0x576A, 0xC6BA, + 0x576B, 0xDBE3, 0x576C, 0x8871, 0x576D, 0xDBE8, 0x576E, 0x8872, + 0x576F, 0xC5F7, 0x5770, 0x8873, 0x5771, 0x8874, 0x5772, 0x8875, + 0x5773, 0xDBEA, 0x5774, 0x8876, 0x5775, 0x8877, 0x5776, 0xDBE9, + 0x5777, 0xBFC0, 0x5778, 0x8878, 0x5779, 0x8879, 0x577A, 0x887A, + 0x577B, 0xDBE6, 0x577C, 0xDBE5, 0x577D, 0x887B, 0x577E, 0x887C, + 0x577F, 0x887D, 0x5780, 0x887E, 0x5781, 0x8880, 0x5782, 0xB4B9, + 0x5783, 0xC0AC, 0x5784, 0xC2A2, 0x5785, 0xDBE2, 0x5786, 0xDBE4, + 0x5787, 0x8881, 0x5788, 0x8882, 0x5789, 0x8883, 0x578A, 0x8884, + 0x578B, 0xD0CD, 0x578C, 0xDBED, 0x578D, 0x8885, 0x578E, 0x8886, + 0x578F, 0x8887, 0x5790, 0x8888, 0x5791, 0x8889, 0x5792, 0xC0DD, + 0x5793, 0xDBF2, 0x5794, 0x888A, 0x5795, 0x888B, 0x5796, 0x888C, + 0x5797, 0x888D, 0x5798, 0x888E, 0x5799, 0x888F, 0x579A, 0x8890, + 0x579B, 0xB6E2, 0x579C, 0x8891, 0x579D, 0x8892, 0x579E, 0x8893, + 0x579F, 0x8894, 0x57A0, 0xDBF3, 0x57A1, 0xDBD2, 0x57A2, 0xB9B8, + 0x57A3, 0xD4AB, 0x57A4, 0xDBEC, 0x57A5, 0x8895, 0x57A6, 0xBFD1, + 0x57A7, 0xDBF0, 0x57A8, 0x8896, 0x57A9, 0xDBD1, 0x57AA, 0x8897, + 0x57AB, 0xB5E6, 0x57AC, 0x8898, 0x57AD, 0xDBEB, 0x57AE, 0xBFE5, + 0x57AF, 0x8899, 0x57B0, 0x889A, 0x57B1, 0x889B, 0x57B2, 0xDBEE, + 0x57B3, 0x889C, 0x57B4, 0xDBF1, 0x57B5, 0x889D, 0x57B6, 0x889E, + 0x57B7, 0x889F, 0x57B8, 0xDBF9, 0x57B9, 0x88A0, 0x57BA, 0x88A1, + 0x57BB, 0x88A2, 0x57BC, 0x88A3, 0x57BD, 0x88A4, 0x57BE, 0x88A5, + 0x57BF, 0x88A6, 0x57C0, 0x88A7, 0x57C1, 0x88A8, 0x57C2, 0xB9A1, + 0x57C3, 0xB0A3, 0x57C4, 0x88A9, 0x57C5, 0x88AA, 0x57C6, 0x88AB, + 0x57C7, 0x88AC, 0x57C8, 0x88AD, 0x57C9, 0x88AE, 0x57CA, 0x88AF, + 0x57CB, 0xC2F1, 0x57CC, 0x88B0, 0x57CD, 0x88B1, 0x57CE, 0xB3C7, + 0x57CF, 0xDBEF, 0x57D0, 0x88B2, 0x57D1, 0x88B3, 0x57D2, 0xDBF8, + 0x57D3, 0x88B4, 0x57D4, 0xC6D2, 0x57D5, 0xDBF4, 0x57D6, 0x88B5, + 0x57D7, 0x88B6, 0x57D8, 0xDBF5, 0x57D9, 0xDBF7, 0x57DA, 0xDBF6, + 0x57DB, 0x88B7, 0x57DC, 0x88B8, 0x57DD, 0xDBFE, 0x57DE, 0x88B9, + 0x57DF, 0xD3F2, 0x57E0, 0xB2BA, 0x57E1, 0x88BA, 0x57E2, 0x88BB, + 0x57E3, 0x88BC, 0x57E4, 0xDBFD, 0x57E5, 0x88BD, 0x57E6, 0x88BE, + 0x57E7, 0x88BF, 0x57E8, 0x88C0, 0x57E9, 0x88C1, 0x57EA, 0x88C2, + 0x57EB, 0x88C3, 0x57EC, 0x88C4, 0x57ED, 0xDCA4, 0x57EE, 0x88C5, + 0x57EF, 0xDBFB, 0x57F0, 0x88C6, 0x57F1, 0x88C7, 0x57F2, 0x88C8, + 0x57F3, 0x88C9, 0x57F4, 0xDBFA, 0x57F5, 0x88CA, 0x57F6, 0x88CB, + 0x57F7, 0x88CC, 0x57F8, 0xDBFC, 0x57F9, 0xC5E0, 0x57FA, 0xBBF9, + 0x57FB, 0x88CD, 0x57FC, 0x88CE, 0x57FD, 0xDCA3, 0x57FE, 0x88CF, + 0x57FF, 0x88D0, 0x5800, 0xDCA5, 0x5801, 0x88D1, 0x5802, 0xCCC3, + 0x5803, 0x88D2, 0x5804, 0x88D3, 0x5805, 0x88D4, 0x5806, 0xB6D1, + 0x5807, 0xDDC0, 0x5808, 0x88D5, 0x5809, 0x88D6, 0x580A, 0x88D7, + 0x580B, 0xDCA1, 0x580C, 0x88D8, 0x580D, 0xDCA2, 0x580E, 0x88D9, + 0x580F, 0x88DA, 0x5810, 0x88DB, 0x5811, 0xC7B5, 0x5812, 0x88DC, + 0x5813, 0x88DD, 0x5814, 0x88DE, 0x5815, 0xB6E9, 0x5816, 0x88DF, + 0x5817, 0x88E0, 0x5818, 0x88E1, 0x5819, 0xDCA7, 0x581A, 0x88E2, + 0x581B, 0x88E3, 0x581C, 0x88E4, 0x581D, 0x88E5, 0x581E, 0xDCA6, + 0x581F, 0x88E6, 0x5820, 0xDCA9, 0x5821, 0xB1A4, 0x5822, 0x88E7, + 0x5823, 0x88E8, 0x5824, 0xB5CC, 0x5825, 0x88E9, 0x5826, 0x88EA, + 0x5827, 0x88EB, 0x5828, 0x88EC, 0x5829, 0x88ED, 0x582A, 0xBFB0, + 0x582B, 0x88EE, 0x582C, 0x88EF, 0x582D, 0x88F0, 0x582E, 0x88F1, + 0x582F, 0x88F2, 0x5830, 0xD1DF, 0x5831, 0x88F3, 0x5832, 0x88F4, + 0x5833, 0x88F5, 0x5834, 0x88F6, 0x5835, 0xB6C2, 0x5836, 0x88F7, + 0x5837, 0x88F8, 0x5838, 0x88F9, 0x5839, 0x88FA, 0x583A, 0x88FB, + 0x583B, 0x88FC, 0x583C, 0x88FD, 0x583D, 0x88FE, 0x583E, 0x8940, + 0x583F, 0x8941, 0x5840, 0x8942, 0x5841, 0x8943, 0x5842, 0x8944, + 0x5843, 0x8945, 0x5844, 0xDCA8, 0x5845, 0x8946, 0x5846, 0x8947, + 0x5847, 0x8948, 0x5848, 0x8949, 0x5849, 0x894A, 0x584A, 0x894B, + 0x584B, 0x894C, 0x584C, 0xCBFA, 0x584D, 0xEBF3, 0x584E, 0x894D, + 0x584F, 0x894E, 0x5850, 0x894F, 0x5851, 0xCBDC, 0x5852, 0x8950, + 0x5853, 0x8951, 0x5854, 0xCBFE, 0x5855, 0x8952, 0x5856, 0x8953, + 0x5857, 0x8954, 0x5858, 0xCCC1, 0x5859, 0x8955, 0x585A, 0x8956, + 0x585B, 0x8957, 0x585C, 0x8958, 0x585D, 0x8959, 0x585E, 0xC8FB, + 0x585F, 0x895A, 0x5860, 0x895B, 0x5861, 0x895C, 0x5862, 0x895D, + 0x5863, 0x895E, 0x5864, 0x895F, 0x5865, 0xDCAA, 0x5866, 0x8960, + 0x5867, 0x8961, 0x5868, 0x8962, 0x5869, 0x8963, 0x586A, 0x8964, + 0x586B, 0xCCEE, 0x586C, 0xDCAB, 0x586D, 0x8965, 0x586E, 0x8966, + 0x586F, 0x8967, 0x5870, 0x8968, 0x5871, 0x8969, 0x5872, 0x896A, + 0x5873, 0x896B, 0x5874, 0x896C, 0x5875, 0x896D, 0x5876, 0x896E, + 0x5877, 0x896F, 0x5878, 0x8970, 0x5879, 0x8971, 0x587A, 0x8972, + 0x587B, 0x8973, 0x587C, 0x8974, 0x587D, 0x8975, 0x587E, 0xDBD3, + 0x587F, 0x8976, 0x5880, 0xDCAF, 0x5881, 0xDCAC, 0x5882, 0x8977, + 0x5883, 0xBEB3, 0x5884, 0x8978, 0x5885, 0xCAFB, 0x5886, 0x8979, + 0x5887, 0x897A, 0x5888, 0x897B, 0x5889, 0xDCAD, 0x588A, 0x897C, + 0x588B, 0x897D, 0x588C, 0x897E, 0x588D, 0x8980, 0x588E, 0x8981, + 0x588F, 0x8982, 0x5890, 0x8983, 0x5891, 0x8984, 0x5892, 0xC9CA, + 0x5893, 0xC4B9, 0x5894, 0x8985, 0x5895, 0x8986, 0x5896, 0x8987, + 0x5897, 0x8988, 0x5898, 0x8989, 0x5899, 0xC7BD, 0x589A, 0xDCAE, + 0x589B, 0x898A, 0x589C, 0x898B, 0x589D, 0x898C, 0x589E, 0xD4F6, + 0x589F, 0xD0E6, 0x58A0, 0x898D, 0x58A1, 0x898E, 0x58A2, 0x898F, + 0x58A3, 0x8990, 0x58A4, 0x8991, 0x58A5, 0x8992, 0x58A6, 0x8993, + 0x58A7, 0x8994, 0x58A8, 0xC4AB, 0x58A9, 0xB6D5, 0x58AA, 0x8995, + 0x58AB, 0x8996, 0x58AC, 0x8997, 0x58AD, 0x8998, 0x58AE, 0x8999, + 0x58AF, 0x899A, 0x58B0, 0x899B, 0x58B1, 0x899C, 0x58B2, 0x899D, + 0x58B3, 0x899E, 0x58B4, 0x899F, 0x58B5, 0x89A0, 0x58B6, 0x89A1, + 0x58B7, 0x89A2, 0x58B8, 0x89A3, 0x58B9, 0x89A4, 0x58BA, 0x89A5, + 0x58BB, 0x89A6, 0x58BC, 0xDBD4, 0x58BD, 0x89A7, 0x58BE, 0x89A8, + 0x58BF, 0x89A9, 0x58C0, 0x89AA, 0x58C1, 0xB1DA, 0x58C2, 0x89AB, + 0x58C3, 0x89AC, 0x58C4, 0x89AD, 0x58C5, 0xDBD5, 0x58C6, 0x89AE, + 0x58C7, 0x89AF, 0x58C8, 0x89B0, 0x58C9, 0x89B1, 0x58CA, 0x89B2, + 0x58CB, 0x89B3, 0x58CC, 0x89B4, 0x58CD, 0x89B5, 0x58CE, 0x89B6, + 0x58CF, 0x89B7, 0x58D0, 0x89B8, 0x58D1, 0xDBD6, 0x58D2, 0x89B9, + 0x58D3, 0x89BA, 0x58D4, 0x89BB, 0x58D5, 0xBABE, 0x58D6, 0x89BC, + 0x58D7, 0x89BD, 0x58D8, 0x89BE, 0x58D9, 0x89BF, 0x58DA, 0x89C0, + 0x58DB, 0x89C1, 0x58DC, 0x89C2, 0x58DD, 0x89C3, 0x58DE, 0x89C4, + 0x58DF, 0x89C5, 0x58E0, 0x89C6, 0x58E1, 0x89C7, 0x58E2, 0x89C8, + 0x58E3, 0x89C9, 0x58E4, 0xC8C0, 0x58E5, 0x89CA, 0x58E6, 0x89CB, + 0x58E7, 0x89CC, 0x58E8, 0x89CD, 0x58E9, 0x89CE, 0x58EA, 0x89CF, + 0x58EB, 0xCABF, 0x58EC, 0xC8C9, 0x58ED, 0x89D0, 0x58EE, 0xD7B3, + 0x58EF, 0x89D1, 0x58F0, 0xC9F9, 0x58F1, 0x89D2, 0x58F2, 0x89D3, + 0x58F3, 0xBFC7, 0x58F4, 0x89D4, 0x58F5, 0x89D5, 0x58F6, 0xBAF8, + 0x58F7, 0x89D6, 0x58F8, 0x89D7, 0x58F9, 0xD2BC, 0x58FA, 0x89D8, + 0x58FB, 0x89D9, 0x58FC, 0x89DA, 0x58FD, 0x89DB, 0x58FE, 0x89DC, + 0x58FF, 0x89DD, 0x5900, 0x89DE, 0x5901, 0x89DF, 0x5902, 0xE2BA, + 0x5903, 0x89E0, 0x5904, 0xB4A6, 0x5905, 0x89E1, 0x5906, 0x89E2, + 0x5907, 0xB1B8, 0x5908, 0x89E3, 0x5909, 0x89E4, 0x590A, 0x89E5, + 0x590B, 0x89E6, 0x590C, 0x89E7, 0x590D, 0xB8B4, 0x590E, 0x89E8, + 0x590F, 0xCFC4, 0x5910, 0x89E9, 0x5911, 0x89EA, 0x5912, 0x89EB, + 0x5913, 0x89EC, 0x5914, 0xD9E7, 0x5915, 0xCFA6, 0x5916, 0xCDE2, + 0x5917, 0x89ED, 0x5918, 0x89EE, 0x5919, 0xD9ED, 0x591A, 0xB6E0, + 0x591B, 0x89EF, 0x591C, 0xD2B9, 0x591D, 0x89F0, 0x591E, 0x89F1, + 0x591F, 0xB9BB, 0x5920, 0x89F2, 0x5921, 0x89F3, 0x5922, 0x89F4, + 0x5923, 0x89F5, 0x5924, 0xE2B9, 0x5925, 0xE2B7, 0x5926, 0x89F6, + 0x5927, 0xB4F3, 0x5928, 0x89F7, 0x5929, 0xCCEC, 0x592A, 0xCCAB, + 0x592B, 0xB7F2, 0x592C, 0x89F8, 0x592D, 0xD8B2, 0x592E, 0xD1EB, + 0x592F, 0xBABB, 0x5930, 0x89F9, 0x5931, 0xCAA7, 0x5932, 0x89FA, + 0x5933, 0x89FB, 0x5934, 0xCDB7, 0x5935, 0x89FC, 0x5936, 0x89FD, + 0x5937, 0xD2C4, 0x5938, 0xBFE4, 0x5939, 0xBCD0, 0x593A, 0xB6E1, + 0x593B, 0x89FE, 0x593C, 0xDEC5, 0x593D, 0x8A40, 0x593E, 0x8A41, + 0x593F, 0x8A42, 0x5940, 0x8A43, 0x5941, 0xDEC6, 0x5942, 0xDBBC, + 0x5943, 0x8A44, 0x5944, 0xD1D9, 0x5945, 0x8A45, 0x5946, 0x8A46, + 0x5947, 0xC6E6, 0x5948, 0xC4CE, 0x5949, 0xB7EE, 0x594A, 0x8A47, + 0x594B, 0xB7DC, 0x594C, 0x8A48, 0x594D, 0x8A49, 0x594E, 0xBFFC, + 0x594F, 0xD7E0, 0x5950, 0x8A4A, 0x5951, 0xC6F5, 0x5952, 0x8A4B, + 0x5953, 0x8A4C, 0x5954, 0xB1BC, 0x5955, 0xDEC8, 0x5956, 0xBDB1, + 0x5957, 0xCCD7, 0x5958, 0xDECA, 0x5959, 0x8A4D, 0x595A, 0xDEC9, + 0x595B, 0x8A4E, 0x595C, 0x8A4F, 0x595D, 0x8A50, 0x595E, 0x8A51, + 0x595F, 0x8A52, 0x5960, 0xB5EC, 0x5961, 0x8A53, 0x5962, 0xC9DD, + 0x5963, 0x8A54, 0x5964, 0x8A55, 0x5965, 0xB0C2, 0x5966, 0x8A56, + 0x5967, 0x8A57, 0x5968, 0x8A58, 0x5969, 0x8A59, 0x596A, 0x8A5A, + 0x596B, 0x8A5B, 0x596C, 0x8A5C, 0x596D, 0x8A5D, 0x596E, 0x8A5E, + 0x596F, 0x8A5F, 0x5970, 0x8A60, 0x5971, 0x8A61, 0x5972, 0x8A62, + 0x5973, 0xC5AE, 0x5974, 0xC5AB, 0x5975, 0x8A63, 0x5976, 0xC4CC, + 0x5977, 0x8A64, 0x5978, 0xBCE9, 0x5979, 0xCBFD, 0x597A, 0x8A65, + 0x597B, 0x8A66, 0x597C, 0x8A67, 0x597D, 0xBAC3, 0x597E, 0x8A68, + 0x597F, 0x8A69, 0x5980, 0x8A6A, 0x5981, 0xE5F9, 0x5982, 0xC8E7, + 0x5983, 0xE5FA, 0x5984, 0xCDFD, 0x5985, 0x8A6B, 0x5986, 0xD7B1, + 0x5987, 0xB8BE, 0x5988, 0xC2E8, 0x5989, 0x8A6C, 0x598A, 0xC8D1, + 0x598B, 0x8A6D, 0x598C, 0x8A6E, 0x598D, 0xE5FB, 0x598E, 0x8A6F, + 0x598F, 0x8A70, 0x5990, 0x8A71, 0x5991, 0x8A72, 0x5992, 0xB6CA, + 0x5993, 0xBCCB, 0x5994, 0x8A73, 0x5995, 0x8A74, 0x5996, 0xD1FD, + 0x5997, 0xE6A1, 0x5998, 0x8A75, 0x5999, 0xC3EE, 0x599A, 0x8A76, + 0x599B, 0x8A77, 0x599C, 0x8A78, 0x599D, 0x8A79, 0x599E, 0xE6A4, + 0x599F, 0x8A7A, 0x59A0, 0x8A7B, 0x59A1, 0x8A7C, 0x59A2, 0x8A7D, + 0x59A3, 0xE5FE, 0x59A4, 0xE6A5, 0x59A5, 0xCDD7, 0x59A6, 0x8A7E, + 0x59A7, 0x8A80, 0x59A8, 0xB7C1, 0x59A9, 0xE5FC, 0x59AA, 0xE5FD, + 0x59AB, 0xE6A3, 0x59AC, 0x8A81, 0x59AD, 0x8A82, 0x59AE, 0xC4DD, + 0x59AF, 0xE6A8, 0x59B0, 0x8A83, 0x59B1, 0x8A84, 0x59B2, 0xE6A7, + 0x59B3, 0x8A85, 0x59B4, 0x8A86, 0x59B5, 0x8A87, 0x59B6, 0x8A88, + 0x59B7, 0x8A89, 0x59B8, 0x8A8A, 0x59B9, 0xC3C3, 0x59BA, 0x8A8B, + 0x59BB, 0xC6DE, 0x59BC, 0x8A8C, 0x59BD, 0x8A8D, 0x59BE, 0xE6AA, + 0x59BF, 0x8A8E, 0x59C0, 0x8A8F, 0x59C1, 0x8A90, 0x59C2, 0x8A91, + 0x59C3, 0x8A92, 0x59C4, 0x8A93, 0x59C5, 0x8A94, 0x59C6, 0xC4B7, + 0x59C7, 0x8A95, 0x59C8, 0x8A96, 0x59C9, 0x8A97, 0x59CA, 0xE6A2, + 0x59CB, 0xCABC, 0x59CC, 0x8A98, 0x59CD, 0x8A99, 0x59CE, 0x8A9A, + 0x59CF, 0x8A9B, 0x59D0, 0xBDE3, 0x59D1, 0xB9C3, 0x59D2, 0xE6A6, + 0x59D3, 0xD0D5, 0x59D4, 0xCEAF, 0x59D5, 0x8A9C, 0x59D6, 0x8A9D, + 0x59D7, 0xE6A9, 0x59D8, 0xE6B0, 0x59D9, 0x8A9E, 0x59DA, 0xD2A6, + 0x59DB, 0x8A9F, 0x59DC, 0xBDAA, 0x59DD, 0xE6AD, 0x59DE, 0x8AA0, + 0x59DF, 0x8AA1, 0x59E0, 0x8AA2, 0x59E1, 0x8AA3, 0x59E2, 0x8AA4, + 0x59E3, 0xE6AF, 0x59E4, 0x8AA5, 0x59E5, 0xC0D1, 0x59E6, 0x8AA6, + 0x59E7, 0x8AA7, 0x59E8, 0xD2CC, 0x59E9, 0x8AA8, 0x59EA, 0x8AA9, + 0x59EB, 0x8AAA, 0x59EC, 0xBCA7, 0x59ED, 0x8AAB, 0x59EE, 0x8AAC, + 0x59EF, 0x8AAD, 0x59F0, 0x8AAE, 0x59F1, 0x8AAF, 0x59F2, 0x8AB0, + 0x59F3, 0x8AB1, 0x59F4, 0x8AB2, 0x59F5, 0x8AB3, 0x59F6, 0x8AB4, + 0x59F7, 0x8AB5, 0x59F8, 0x8AB6, 0x59F9, 0xE6B1, 0x59FA, 0x8AB7, + 0x59FB, 0xD2F6, 0x59FC, 0x8AB8, 0x59FD, 0x8AB9, 0x59FE, 0x8ABA, + 0x59FF, 0xD7CB, 0x5A00, 0x8ABB, 0x5A01, 0xCDFE, 0x5A02, 0x8ABC, + 0x5A03, 0xCDDE, 0x5A04, 0xC2A6, 0x5A05, 0xE6AB, 0x5A06, 0xE6AC, + 0x5A07, 0xBDBF, 0x5A08, 0xE6AE, 0x5A09, 0xE6B3, 0x5A0A, 0x8ABD, + 0x5A0B, 0x8ABE, 0x5A0C, 0xE6B2, 0x5A0D, 0x8ABF, 0x5A0E, 0x8AC0, + 0x5A0F, 0x8AC1, 0x5A10, 0x8AC2, 0x5A11, 0xE6B6, 0x5A12, 0x8AC3, + 0x5A13, 0xE6B8, 0x5A14, 0x8AC4, 0x5A15, 0x8AC5, 0x5A16, 0x8AC6, + 0x5A17, 0x8AC7, 0x5A18, 0xC4EF, 0x5A19, 0x8AC8, 0x5A1A, 0x8AC9, + 0x5A1B, 0x8ACA, 0x5A1C, 0xC4C8, 0x5A1D, 0x8ACB, 0x5A1E, 0x8ACC, + 0x5A1F, 0xBEEA, 0x5A20, 0xC9EF, 0x5A21, 0x8ACD, 0x5A22, 0x8ACE, + 0x5A23, 0xE6B7, 0x5A24, 0x8ACF, 0x5A25, 0xB6F0, 0x5A26, 0x8AD0, + 0x5A27, 0x8AD1, 0x5A28, 0x8AD2, 0x5A29, 0xC3E4, 0x5A2A, 0x8AD3, + 0x5A2B, 0x8AD4, 0x5A2C, 0x8AD5, 0x5A2D, 0x8AD6, 0x5A2E, 0x8AD7, + 0x5A2F, 0x8AD8, 0x5A30, 0x8AD9, 0x5A31, 0xD3E9, 0x5A32, 0xE6B4, + 0x5A33, 0x8ADA, 0x5A34, 0xE6B5, 0x5A35, 0x8ADB, 0x5A36, 0xC8A2, + 0x5A37, 0x8ADC, 0x5A38, 0x8ADD, 0x5A39, 0x8ADE, 0x5A3A, 0x8ADF, + 0x5A3B, 0x8AE0, 0x5A3C, 0xE6BD, 0x5A3D, 0x8AE1, 0x5A3E, 0x8AE2, + 0x5A3F, 0x8AE3, 0x5A40, 0xE6B9, 0x5A41, 0x8AE4, 0x5A42, 0x8AE5, + 0x5A43, 0x8AE6, 0x5A44, 0x8AE7, 0x5A45, 0x8AE8, 0x5A46, 0xC6C5, + 0x5A47, 0x8AE9, 0x5A48, 0x8AEA, 0x5A49, 0xCDF1, 0x5A4A, 0xE6BB, + 0x5A4B, 0x8AEB, 0x5A4C, 0x8AEC, 0x5A4D, 0x8AED, 0x5A4E, 0x8AEE, + 0x5A4F, 0x8AEF, 0x5A50, 0x8AF0, 0x5A51, 0x8AF1, 0x5A52, 0x8AF2, + 0x5A53, 0x8AF3, 0x5A54, 0x8AF4, 0x5A55, 0xE6BC, 0x5A56, 0x8AF5, + 0x5A57, 0x8AF6, 0x5A58, 0x8AF7, 0x5A59, 0x8AF8, 0x5A5A, 0xBBE9, + 0x5A5B, 0x8AF9, 0x5A5C, 0x8AFA, 0x5A5D, 0x8AFB, 0x5A5E, 0x8AFC, + 0x5A5F, 0x8AFD, 0x5A60, 0x8AFE, 0x5A61, 0x8B40, 0x5A62, 0xE6BE, + 0x5A63, 0x8B41, 0x5A64, 0x8B42, 0x5A65, 0x8B43, 0x5A66, 0x8B44, + 0x5A67, 0xE6BA, 0x5A68, 0x8B45, 0x5A69, 0x8B46, 0x5A6A, 0xC0B7, + 0x5A6B, 0x8B47, 0x5A6C, 0x8B48, 0x5A6D, 0x8B49, 0x5A6E, 0x8B4A, + 0x5A6F, 0x8B4B, 0x5A70, 0x8B4C, 0x5A71, 0x8B4D, 0x5A72, 0x8B4E, + 0x5A73, 0x8B4F, 0x5A74, 0xD3A4, 0x5A75, 0xE6BF, 0x5A76, 0xC9F4, + 0x5A77, 0xE6C3, 0x5A78, 0x8B50, 0x5A79, 0x8B51, 0x5A7A, 0xE6C4, + 0x5A7B, 0x8B52, 0x5A7C, 0x8B53, 0x5A7D, 0x8B54, 0x5A7E, 0x8B55, + 0x5A7F, 0xD0F6, 0x5A80, 0x8B56, 0x5A81, 0x8B57, 0x5A82, 0x8B58, + 0x5A83, 0x8B59, 0x5A84, 0x8B5A, 0x5A85, 0x8B5B, 0x5A86, 0x8B5C, + 0x5A87, 0x8B5D, 0x5A88, 0x8B5E, 0x5A89, 0x8B5F, 0x5A8A, 0x8B60, + 0x5A8B, 0x8B61, 0x5A8C, 0x8B62, 0x5A8D, 0x8B63, 0x5A8E, 0x8B64, + 0x5A8F, 0x8B65, 0x5A90, 0x8B66, 0x5A91, 0x8B67, 0x5A92, 0xC3BD, + 0x5A93, 0x8B68, 0x5A94, 0x8B69, 0x5A95, 0x8B6A, 0x5A96, 0x8B6B, + 0x5A97, 0x8B6C, 0x5A98, 0x8B6D, 0x5A99, 0x8B6E, 0x5A9A, 0xC3C4, + 0x5A9B, 0xE6C2, 0x5A9C, 0x8B6F, 0x5A9D, 0x8B70, 0x5A9E, 0x8B71, + 0x5A9F, 0x8B72, 0x5AA0, 0x8B73, 0x5AA1, 0x8B74, 0x5AA2, 0x8B75, + 0x5AA3, 0x8B76, 0x5AA4, 0x8B77, 0x5AA5, 0x8B78, 0x5AA6, 0x8B79, + 0x5AA7, 0x8B7A, 0x5AA8, 0x8B7B, 0x5AA9, 0x8B7C, 0x5AAA, 0xE6C1, + 0x5AAB, 0x8B7D, 0x5AAC, 0x8B7E, 0x5AAD, 0x8B80, 0x5AAE, 0x8B81, + 0x5AAF, 0x8B82, 0x5AB0, 0x8B83, 0x5AB1, 0x8B84, 0x5AB2, 0xE6C7, + 0x5AB3, 0xCFB1, 0x5AB4, 0x8B85, 0x5AB5, 0xEBF4, 0x5AB6, 0x8B86, + 0x5AB7, 0x8B87, 0x5AB8, 0xE6CA, 0x5AB9, 0x8B88, 0x5ABA, 0x8B89, + 0x5ABB, 0x8B8A, 0x5ABC, 0x8B8B, 0x5ABD, 0x8B8C, 0x5ABE, 0xE6C5, + 0x5ABF, 0x8B8D, 0x5AC0, 0x8B8E, 0x5AC1, 0xBCDE, 0x5AC2, 0xC9A9, + 0x5AC3, 0x8B8F, 0x5AC4, 0x8B90, 0x5AC5, 0x8B91, 0x5AC6, 0x8B92, + 0x5AC7, 0x8B93, 0x5AC8, 0x8B94, 0x5AC9, 0xBCB5, 0x5ACA, 0x8B95, + 0x5ACB, 0x8B96, 0x5ACC, 0xCFD3, 0x5ACD, 0x8B97, 0x5ACE, 0x8B98, + 0x5ACF, 0x8B99, 0x5AD0, 0x8B9A, 0x5AD1, 0x8B9B, 0x5AD2, 0xE6C8, + 0x5AD3, 0x8B9C, 0x5AD4, 0xE6C9, 0x5AD5, 0x8B9D, 0x5AD6, 0xE6CE, + 0x5AD7, 0x8B9E, 0x5AD8, 0xE6D0, 0x5AD9, 0x8B9F, 0x5ADA, 0x8BA0, + 0x5ADB, 0x8BA1, 0x5ADC, 0xE6D1, 0x5ADD, 0x8BA2, 0x5ADE, 0x8BA3, + 0x5ADF, 0x8BA4, 0x5AE0, 0xE6CB, 0x5AE1, 0xB5D5, 0x5AE2, 0x8BA5, + 0x5AE3, 0xE6CC, 0x5AE4, 0x8BA6, 0x5AE5, 0x8BA7, 0x5AE6, 0xE6CF, + 0x5AE7, 0x8BA8, 0x5AE8, 0x8BA9, 0x5AE9, 0xC4DB, 0x5AEA, 0x8BAA, + 0x5AEB, 0xE6C6, 0x5AEC, 0x8BAB, 0x5AED, 0x8BAC, 0x5AEE, 0x8BAD, + 0x5AEF, 0x8BAE, 0x5AF0, 0x8BAF, 0x5AF1, 0xE6CD, 0x5AF2, 0x8BB0, + 0x5AF3, 0x8BB1, 0x5AF4, 0x8BB2, 0x5AF5, 0x8BB3, 0x5AF6, 0x8BB4, + 0x5AF7, 0x8BB5, 0x5AF8, 0x8BB6, 0x5AF9, 0x8BB7, 0x5AFA, 0x8BB8, + 0x5AFB, 0x8BB9, 0x5AFC, 0x8BBA, 0x5AFD, 0x8BBB, 0x5AFE, 0x8BBC, + 0x5AFF, 0x8BBD, 0x5B00, 0x8BBE, 0x5B01, 0x8BBF, 0x5B02, 0x8BC0, + 0x5B03, 0x8BC1, 0x5B04, 0x8BC2, 0x5B05, 0x8BC3, 0x5B06, 0x8BC4, + 0x5B07, 0x8BC5, 0x5B08, 0x8BC6, 0x5B09, 0xE6D2, 0x5B0A, 0x8BC7, + 0x5B0B, 0x8BC8, 0x5B0C, 0x8BC9, 0x5B0D, 0x8BCA, 0x5B0E, 0x8BCB, + 0x5B0F, 0x8BCC, 0x5B10, 0x8BCD, 0x5B11, 0x8BCE, 0x5B12, 0x8BCF, + 0x5B13, 0x8BD0, 0x5B14, 0x8BD1, 0x5B15, 0x8BD2, 0x5B16, 0xE6D4, + 0x5B17, 0xE6D3, 0x5B18, 0x8BD3, 0x5B19, 0x8BD4, 0x5B1A, 0x8BD5, + 0x5B1B, 0x8BD6, 0x5B1C, 0x8BD7, 0x5B1D, 0x8BD8, 0x5B1E, 0x8BD9, + 0x5B1F, 0x8BDA, 0x5B20, 0x8BDB, 0x5B21, 0x8BDC, 0x5B22, 0x8BDD, + 0x5B23, 0x8BDE, 0x5B24, 0x8BDF, 0x5B25, 0x8BE0, 0x5B26, 0x8BE1, + 0x5B27, 0x8BE2, 0x5B28, 0x8BE3, 0x5B29, 0x8BE4, 0x5B2A, 0x8BE5, + 0x5B2B, 0x8BE6, 0x5B2C, 0x8BE7, 0x5B2D, 0x8BE8, 0x5B2E, 0x8BE9, + 0x5B2F, 0x8BEA, 0x5B30, 0x8BEB, 0x5B31, 0x8BEC, 0x5B32, 0xE6D5, + 0x5B33, 0x8BED, 0x5B34, 0xD9F8, 0x5B35, 0x8BEE, 0x5B36, 0x8BEF, + 0x5B37, 0xE6D6, 0x5B38, 0x8BF0, 0x5B39, 0x8BF1, 0x5B3A, 0x8BF2, + 0x5B3B, 0x8BF3, 0x5B3C, 0x8BF4, 0x5B3D, 0x8BF5, 0x5B3E, 0x8BF6, + 0x5B3F, 0x8BF7, 0x5B40, 0xE6D7, 0x5B41, 0x8BF8, 0x5B42, 0x8BF9, + 0x5B43, 0x8BFA, 0x5B44, 0x8BFB, 0x5B45, 0x8BFC, 0x5B46, 0x8BFD, + 0x5B47, 0x8BFE, 0x5B48, 0x8C40, 0x5B49, 0x8C41, 0x5B4A, 0x8C42, + 0x5B4B, 0x8C43, 0x5B4C, 0x8C44, 0x5B4D, 0x8C45, 0x5B4E, 0x8C46, + 0x5B4F, 0x8C47, 0x5B50, 0xD7D3, 0x5B51, 0xE6DD, 0x5B52, 0x8C48, + 0x5B53, 0xE6DE, 0x5B54, 0xBFD7, 0x5B55, 0xD4D0, 0x5B56, 0x8C49, + 0x5B57, 0xD7D6, 0x5B58, 0xB4E6, 0x5B59, 0xCBEF, 0x5B5A, 0xE6DA, + 0x5B5B, 0xD8C3, 0x5B5C, 0xD7CE, 0x5B5D, 0xD0A2, 0x5B5E, 0x8C4A, + 0x5B5F, 0xC3CF, 0x5B60, 0x8C4B, 0x5B61, 0x8C4C, 0x5B62, 0xE6DF, + 0x5B63, 0xBCBE, 0x5B64, 0xB9C2, 0x5B65, 0xE6DB, 0x5B66, 0xD1A7, + 0x5B67, 0x8C4D, 0x5B68, 0x8C4E, 0x5B69, 0xBAA2, 0x5B6A, 0xC2CF, + 0x5B6B, 0x8C4F, 0x5B6C, 0xD8AB, 0x5B6D, 0x8C50, 0x5B6E, 0x8C51, + 0x5B6F, 0x8C52, 0x5B70, 0xCAEB, 0x5B71, 0xE5EE, 0x5B72, 0x8C53, + 0x5B73, 0xE6DC, 0x5B74, 0x8C54, 0x5B75, 0xB7F5, 0x5B76, 0x8C55, + 0x5B77, 0x8C56, 0x5B78, 0x8C57, 0x5B79, 0x8C58, 0x5B7A, 0xC8E6, + 0x5B7B, 0x8C59, 0x5B7C, 0x8C5A, 0x5B7D, 0xC4F5, 0x5B7E, 0x8C5B, + 0x5B7F, 0x8C5C, 0x5B80, 0xE5B2, 0x5B81, 0xC4FE, 0x5B82, 0x8C5D, + 0x5B83, 0xCBFC, 0x5B84, 0xE5B3, 0x5B85, 0xD5AC, 0x5B86, 0x8C5E, + 0x5B87, 0xD3EE, 0x5B88, 0xCAD8, 0x5B89, 0xB0B2, 0x5B8A, 0x8C5F, + 0x5B8B, 0xCBCE, 0x5B8C, 0xCDEA, 0x5B8D, 0x8C60, 0x5B8E, 0x8C61, + 0x5B8F, 0xBAEA, 0x5B90, 0x8C62, 0x5B91, 0x8C63, 0x5B92, 0x8C64, + 0x5B93, 0xE5B5, 0x5B94, 0x8C65, 0x5B95, 0xE5B4, 0x5B96, 0x8C66, + 0x5B97, 0xD7DA, 0x5B98, 0xB9D9, 0x5B99, 0xD6E6, 0x5B9A, 0xB6A8, + 0x5B9B, 0xCDF0, 0x5B9C, 0xD2CB, 0x5B9D, 0xB1A6, 0x5B9E, 0xCAB5, + 0x5B9F, 0x8C67, 0x5BA0, 0xB3E8, 0x5BA1, 0xC9F3, 0x5BA2, 0xBFCD, + 0x5BA3, 0xD0FB, 0x5BA4, 0xCAD2, 0x5BA5, 0xE5B6, 0x5BA6, 0xBBC2, + 0x5BA7, 0x8C68, 0x5BA8, 0x8C69, 0x5BA9, 0x8C6A, 0x5BAA, 0xCFDC, + 0x5BAB, 0xB9AC, 0x5BAC, 0x8C6B, 0x5BAD, 0x8C6C, 0x5BAE, 0x8C6D, + 0x5BAF, 0x8C6E, 0x5BB0, 0xD4D7, 0x5BB1, 0x8C6F, 0x5BB2, 0x8C70, + 0x5BB3, 0xBAA6, 0x5BB4, 0xD1E7, 0x5BB5, 0xCFFC, 0x5BB6, 0xBCD2, + 0x5BB7, 0x8C71, 0x5BB8, 0xE5B7, 0x5BB9, 0xC8DD, 0x5BBA, 0x8C72, + 0x5BBB, 0x8C73, 0x5BBC, 0x8C74, 0x5BBD, 0xBFED, 0x5BBE, 0xB1F6, + 0x5BBF, 0xCBDE, 0x5BC0, 0x8C75, 0x5BC1, 0x8C76, 0x5BC2, 0xBCC5, + 0x5BC3, 0x8C77, 0x5BC4, 0xBCC4, 0x5BC5, 0xD2FA, 0x5BC6, 0xC3DC, + 0x5BC7, 0xBFDC, 0x5BC8, 0x8C78, 0x5BC9, 0x8C79, 0x5BCA, 0x8C7A, + 0x5BCB, 0x8C7B, 0x5BCC, 0xB8BB, 0x5BCD, 0x8C7C, 0x5BCE, 0x8C7D, + 0x5BCF, 0x8C7E, 0x5BD0, 0xC3C2, 0x5BD1, 0x8C80, 0x5BD2, 0xBAAE, + 0x5BD3, 0xD4A2, 0x5BD4, 0x8C81, 0x5BD5, 0x8C82, 0x5BD6, 0x8C83, + 0x5BD7, 0x8C84, 0x5BD8, 0x8C85, 0x5BD9, 0x8C86, 0x5BDA, 0x8C87, + 0x5BDB, 0x8C88, 0x5BDC, 0x8C89, 0x5BDD, 0xC7DE, 0x5BDE, 0xC4AF, + 0x5BDF, 0xB2EC, 0x5BE0, 0x8C8A, 0x5BE1, 0xB9D1, 0x5BE2, 0x8C8B, + 0x5BE3, 0x8C8C, 0x5BE4, 0xE5BB, 0x5BE5, 0xC1C8, 0x5BE6, 0x8C8D, + 0x5BE7, 0x8C8E, 0x5BE8, 0xD5AF, 0x5BE9, 0x8C8F, 0x5BEA, 0x8C90, + 0x5BEB, 0x8C91, 0x5BEC, 0x8C92, 0x5BED, 0x8C93, 0x5BEE, 0xE5BC, + 0x5BEF, 0x8C94, 0x5BF0, 0xE5BE, 0x5BF1, 0x8C95, 0x5BF2, 0x8C96, + 0x5BF3, 0x8C97, 0x5BF4, 0x8C98, 0x5BF5, 0x8C99, 0x5BF6, 0x8C9A, + 0x5BF7, 0x8C9B, 0x5BF8, 0xB4E7, 0x5BF9, 0xB6D4, 0x5BFA, 0xCBC2, + 0x5BFB, 0xD1B0, 0x5BFC, 0xB5BC, 0x5BFD, 0x8C9C, 0x5BFE, 0x8C9D, + 0x5BFF, 0xCAD9, 0x5C00, 0x8C9E, 0x5C01, 0xB7E2, 0x5C02, 0x8C9F, + 0x5C03, 0x8CA0, 0x5C04, 0xC9E4, 0x5C05, 0x8CA1, 0x5C06, 0xBDAB, + 0x5C07, 0x8CA2, 0x5C08, 0x8CA3, 0x5C09, 0xCEBE, 0x5C0A, 0xD7F0, + 0x5C0B, 0x8CA4, 0x5C0C, 0x8CA5, 0x5C0D, 0x8CA6, 0x5C0E, 0x8CA7, + 0x5C0F, 0xD0A1, 0x5C10, 0x8CA8, 0x5C11, 0xC9D9, 0x5C12, 0x8CA9, + 0x5C13, 0x8CAA, 0x5C14, 0xB6FB, 0x5C15, 0xE6D8, 0x5C16, 0xBCE2, + 0x5C17, 0x8CAB, 0x5C18, 0xB3BE, 0x5C19, 0x8CAC, 0x5C1A, 0xC9D0, + 0x5C1B, 0x8CAD, 0x5C1C, 0xE6D9, 0x5C1D, 0xB3A2, 0x5C1E, 0x8CAE, + 0x5C1F, 0x8CAF, 0x5C20, 0x8CB0, 0x5C21, 0x8CB1, 0x5C22, 0xDECC, + 0x5C23, 0x8CB2, 0x5C24, 0xD3C8, 0x5C25, 0xDECD, 0x5C26, 0x8CB3, + 0x5C27, 0xD2A2, 0x5C28, 0x8CB4, 0x5C29, 0x8CB5, 0x5C2A, 0x8CB6, + 0x5C2B, 0x8CB7, 0x5C2C, 0xDECE, 0x5C2D, 0x8CB8, 0x5C2E, 0x8CB9, + 0x5C2F, 0x8CBA, 0x5C30, 0x8CBB, 0x5C31, 0xBECD, 0x5C32, 0x8CBC, + 0x5C33, 0x8CBD, 0x5C34, 0xDECF, 0x5C35, 0x8CBE, 0x5C36, 0x8CBF, + 0x5C37, 0x8CC0, 0x5C38, 0xCAAC, 0x5C39, 0xD2FC, 0x5C3A, 0xB3DF, + 0x5C3B, 0xE5EA, 0x5C3C, 0xC4E1, 0x5C3D, 0xBEA1, 0x5C3E, 0xCEB2, + 0x5C3F, 0xC4F2, 0x5C40, 0xBED6, 0x5C41, 0xC6A8, 0x5C42, 0xB2E3, + 0x5C43, 0x8CC1, 0x5C44, 0x8CC2, 0x5C45, 0xBED3, 0x5C46, 0x8CC3, + 0x5C47, 0x8CC4, 0x5C48, 0xC7FC, 0x5C49, 0xCCEB, 0x5C4A, 0xBDEC, + 0x5C4B, 0xCEDD, 0x5C4C, 0x8CC5, 0x5C4D, 0x8CC6, 0x5C4E, 0xCABA, + 0x5C4F, 0xC6C1, 0x5C50, 0xE5EC, 0x5C51, 0xD0BC, 0x5C52, 0x8CC7, + 0x5C53, 0x8CC8, 0x5C54, 0x8CC9, 0x5C55, 0xD5B9, 0x5C56, 0x8CCA, + 0x5C57, 0x8CCB, 0x5C58, 0x8CCC, 0x5C59, 0xE5ED, 0x5C5A, 0x8CCD, + 0x5C5B, 0x8CCE, 0x5C5C, 0x8CCF, 0x5C5D, 0x8CD0, 0x5C5E, 0xCAF4, + 0x5C5F, 0x8CD1, 0x5C60, 0xCDC0, 0x5C61, 0xC2C5, 0x5C62, 0x8CD2, + 0x5C63, 0xE5EF, 0x5C64, 0x8CD3, 0x5C65, 0xC2C4, 0x5C66, 0xE5F0, + 0x5C67, 0x8CD4, 0x5C68, 0x8CD5, 0x5C69, 0x8CD6, 0x5C6A, 0x8CD7, + 0x5C6B, 0x8CD8, 0x5C6C, 0x8CD9, 0x5C6D, 0x8CDA, 0x5C6E, 0xE5F8, + 0x5C6F, 0xCDCD, 0x5C70, 0x8CDB, 0x5C71, 0xC9BD, 0x5C72, 0x8CDC, + 0x5C73, 0x8CDD, 0x5C74, 0x8CDE, 0x5C75, 0x8CDF, 0x5C76, 0x8CE0, + 0x5C77, 0x8CE1, 0x5C78, 0x8CE2, 0x5C79, 0xD2D9, 0x5C7A, 0xE1A8, + 0x5C7B, 0x8CE3, 0x5C7C, 0x8CE4, 0x5C7D, 0x8CE5, 0x5C7E, 0x8CE6, + 0x5C7F, 0xD3EC, 0x5C80, 0x8CE7, 0x5C81, 0xCBEA, 0x5C82, 0xC6F1, + 0x5C83, 0x8CE8, 0x5C84, 0x8CE9, 0x5C85, 0x8CEA, 0x5C86, 0x8CEB, + 0x5C87, 0x8CEC, 0x5C88, 0xE1AC, 0x5C89, 0x8CED, 0x5C8A, 0x8CEE, + 0x5C8B, 0x8CEF, 0x5C8C, 0xE1A7, 0x5C8D, 0xE1A9, 0x5C8E, 0x8CF0, + 0x5C8F, 0x8CF1, 0x5C90, 0xE1AA, 0x5C91, 0xE1AF, 0x5C92, 0x8CF2, + 0x5C93, 0x8CF3, 0x5C94, 0xB2ED, 0x5C95, 0x8CF4, 0x5C96, 0xE1AB, + 0x5C97, 0xB8DA, 0x5C98, 0xE1AD, 0x5C99, 0xE1AE, 0x5C9A, 0xE1B0, + 0x5C9B, 0xB5BA, 0x5C9C, 0xE1B1, 0x5C9D, 0x8CF5, 0x5C9E, 0x8CF6, + 0x5C9F, 0x8CF7, 0x5CA0, 0x8CF8, 0x5CA1, 0x8CF9, 0x5CA2, 0xE1B3, + 0x5CA3, 0xE1B8, 0x5CA4, 0x8CFA, 0x5CA5, 0x8CFB, 0x5CA6, 0x8CFC, + 0x5CA7, 0x8CFD, 0x5CA8, 0x8CFE, 0x5CA9, 0xD1D2, 0x5CAA, 0x8D40, + 0x5CAB, 0xE1B6, 0x5CAC, 0xE1B5, 0x5CAD, 0xC1EB, 0x5CAE, 0x8D41, + 0x5CAF, 0x8D42, 0x5CB0, 0x8D43, 0x5CB1, 0xE1B7, 0x5CB2, 0x8D44, + 0x5CB3, 0xD4C0, 0x5CB4, 0x8D45, 0x5CB5, 0xE1B2, 0x5CB6, 0x8D46, + 0x5CB7, 0xE1BA, 0x5CB8, 0xB0B6, 0x5CB9, 0x8D47, 0x5CBA, 0x8D48, + 0x5CBB, 0x8D49, 0x5CBC, 0x8D4A, 0x5CBD, 0xE1B4, 0x5CBE, 0x8D4B, + 0x5CBF, 0xBFF9, 0x5CC0, 0x8D4C, 0x5CC1, 0xE1B9, 0x5CC2, 0x8D4D, + 0x5CC3, 0x8D4E, 0x5CC4, 0xE1BB, 0x5CC5, 0x8D4F, 0x5CC6, 0x8D50, + 0x5CC7, 0x8D51, 0x5CC8, 0x8D52, 0x5CC9, 0x8D53, 0x5CCA, 0x8D54, + 0x5CCB, 0xE1BE, 0x5CCC, 0x8D55, 0x5CCD, 0x8D56, 0x5CCE, 0x8D57, + 0x5CCF, 0x8D58, 0x5CD0, 0x8D59, 0x5CD1, 0x8D5A, 0x5CD2, 0xE1BC, + 0x5CD3, 0x8D5B, 0x5CD4, 0x8D5C, 0x5CD5, 0x8D5D, 0x5CD6, 0x8D5E, + 0x5CD7, 0x8D5F, 0x5CD8, 0x8D60, 0x5CD9, 0xD6C5, 0x5CDA, 0x8D61, + 0x5CDB, 0x8D62, 0x5CDC, 0x8D63, 0x5CDD, 0x8D64, 0x5CDE, 0x8D65, + 0x5CDF, 0x8D66, 0x5CE0, 0x8D67, 0x5CE1, 0xCFBF, 0x5CE2, 0x8D68, + 0x5CE3, 0x8D69, 0x5CE4, 0xE1BD, 0x5CE5, 0xE1BF, 0x5CE6, 0xC2CD, + 0x5CE7, 0x8D6A, 0x5CE8, 0xB6EB, 0x5CE9, 0x8D6B, 0x5CEA, 0xD3F8, + 0x5CEB, 0x8D6C, 0x5CEC, 0x8D6D, 0x5CED, 0xC7CD, 0x5CEE, 0x8D6E, + 0x5CEF, 0x8D6F, 0x5CF0, 0xB7E5, 0x5CF1, 0x8D70, 0x5CF2, 0x8D71, + 0x5CF3, 0x8D72, 0x5CF4, 0x8D73, 0x5CF5, 0x8D74, 0x5CF6, 0x8D75, + 0x5CF7, 0x8D76, 0x5CF8, 0x8D77, 0x5CF9, 0x8D78, 0x5CFA, 0x8D79, + 0x5CFB, 0xBEFE, 0x5CFC, 0x8D7A, 0x5CFD, 0x8D7B, 0x5CFE, 0x8D7C, + 0x5CFF, 0x8D7D, 0x5D00, 0x8D7E, 0x5D01, 0x8D80, 0x5D02, 0xE1C0, + 0x5D03, 0xE1C1, 0x5D04, 0x8D81, 0x5D05, 0x8D82, 0x5D06, 0xE1C7, + 0x5D07, 0xB3E7, 0x5D08, 0x8D83, 0x5D09, 0x8D84, 0x5D0A, 0x8D85, + 0x5D0B, 0x8D86, 0x5D0C, 0x8D87, 0x5D0D, 0x8D88, 0x5D0E, 0xC6E9, + 0x5D0F, 0x8D89, 0x5D10, 0x8D8A, 0x5D11, 0x8D8B, 0x5D12, 0x8D8C, + 0x5D13, 0x8D8D, 0x5D14, 0xB4DE, 0x5D15, 0x8D8E, 0x5D16, 0xD1C2, + 0x5D17, 0x8D8F, 0x5D18, 0x8D90, 0x5D19, 0x8D91, 0x5D1A, 0x8D92, + 0x5D1B, 0xE1C8, 0x5D1C, 0x8D93, 0x5D1D, 0x8D94, 0x5D1E, 0xE1C6, + 0x5D1F, 0x8D95, 0x5D20, 0x8D96, 0x5D21, 0x8D97, 0x5D22, 0x8D98, + 0x5D23, 0x8D99, 0x5D24, 0xE1C5, 0x5D25, 0x8D9A, 0x5D26, 0xE1C3, + 0x5D27, 0xE1C2, 0x5D28, 0x8D9B, 0x5D29, 0xB1C0, 0x5D2A, 0x8D9C, + 0x5D2B, 0x8D9D, 0x5D2C, 0x8D9E, 0x5D2D, 0xD5B8, 0x5D2E, 0xE1C4, + 0x5D2F, 0x8D9F, 0x5D30, 0x8DA0, 0x5D31, 0x8DA1, 0x5D32, 0x8DA2, + 0x5D33, 0x8DA3, 0x5D34, 0xE1CB, 0x5D35, 0x8DA4, 0x5D36, 0x8DA5, + 0x5D37, 0x8DA6, 0x5D38, 0x8DA7, 0x5D39, 0x8DA8, 0x5D3A, 0x8DA9, + 0x5D3B, 0x8DAA, 0x5D3C, 0x8DAB, 0x5D3D, 0xE1CC, 0x5D3E, 0xE1CA, + 0x5D3F, 0x8DAC, 0x5D40, 0x8DAD, 0x5D41, 0x8DAE, 0x5D42, 0x8DAF, + 0x5D43, 0x8DB0, 0x5D44, 0x8DB1, 0x5D45, 0x8DB2, 0x5D46, 0x8DB3, + 0x5D47, 0xEFFA, 0x5D48, 0x8DB4, 0x5D49, 0x8DB5, 0x5D4A, 0xE1D3, + 0x5D4B, 0xE1D2, 0x5D4C, 0xC7B6, 0x5D4D, 0x8DB6, 0x5D4E, 0x8DB7, + 0x5D4F, 0x8DB8, 0x5D50, 0x8DB9, 0x5D51, 0x8DBA, 0x5D52, 0x8DBB, + 0x5D53, 0x8DBC, 0x5D54, 0x8DBD, 0x5D55, 0x8DBE, 0x5D56, 0x8DBF, + 0x5D57, 0x8DC0, 0x5D58, 0xE1C9, 0x5D59, 0x8DC1, 0x5D5A, 0x8DC2, + 0x5D5B, 0xE1CE, 0x5D5C, 0x8DC3, 0x5D5D, 0xE1D0, 0x5D5E, 0x8DC4, + 0x5D5F, 0x8DC5, 0x5D60, 0x8DC6, 0x5D61, 0x8DC7, 0x5D62, 0x8DC8, + 0x5D63, 0x8DC9, 0x5D64, 0x8DCA, 0x5D65, 0x8DCB, 0x5D66, 0x8DCC, + 0x5D67, 0x8DCD, 0x5D68, 0x8DCE, 0x5D69, 0xE1D4, 0x5D6A, 0x8DCF, + 0x5D6B, 0xE1D1, 0x5D6C, 0xE1CD, 0x5D6D, 0x8DD0, 0x5D6E, 0x8DD1, + 0x5D6F, 0xE1CF, 0x5D70, 0x8DD2, 0x5D71, 0x8DD3, 0x5D72, 0x8DD4, + 0x5D73, 0x8DD5, 0x5D74, 0xE1D5, 0x5D75, 0x8DD6, 0x5D76, 0x8DD7, + 0x5D77, 0x8DD8, 0x5D78, 0x8DD9, 0x5D79, 0x8DDA, 0x5D7A, 0x8DDB, + 0x5D7B, 0x8DDC, 0x5D7C, 0x8DDD, 0x5D7D, 0x8DDE, 0x5D7E, 0x8DDF, + 0x5D7F, 0x8DE0, 0x5D80, 0x8DE1, 0x5D81, 0x8DE2, 0x5D82, 0xE1D6, + 0x5D83, 0x8DE3, 0x5D84, 0x8DE4, 0x5D85, 0x8DE5, 0x5D86, 0x8DE6, + 0x5D87, 0x8DE7, 0x5D88, 0x8DE8, 0x5D89, 0x8DE9, 0x5D8A, 0x8DEA, + 0x5D8B, 0x8DEB, 0x5D8C, 0x8DEC, 0x5D8D, 0x8DED, 0x5D8E, 0x8DEE, + 0x5D8F, 0x8DEF, 0x5D90, 0x8DF0, 0x5D91, 0x8DF1, 0x5D92, 0x8DF2, + 0x5D93, 0x8DF3, 0x5D94, 0x8DF4, 0x5D95, 0x8DF5, 0x5D96, 0x8DF6, + 0x5D97, 0x8DF7, 0x5D98, 0x8DF8, 0x5D99, 0xE1D7, 0x5D9A, 0x8DF9, + 0x5D9B, 0x8DFA, 0x5D9C, 0x8DFB, 0x5D9D, 0xE1D8, 0x5D9E, 0x8DFC, + 0x5D9F, 0x8DFD, 0x5DA0, 0x8DFE, 0x5DA1, 0x8E40, 0x5DA2, 0x8E41, + 0x5DA3, 0x8E42, 0x5DA4, 0x8E43, 0x5DA5, 0x8E44, 0x5DA6, 0x8E45, + 0x5DA7, 0x8E46, 0x5DA8, 0x8E47, 0x5DA9, 0x8E48, 0x5DAA, 0x8E49, + 0x5DAB, 0x8E4A, 0x5DAC, 0x8E4B, 0x5DAD, 0x8E4C, 0x5DAE, 0x8E4D, + 0x5DAF, 0x8E4E, 0x5DB0, 0x8E4F, 0x5DB1, 0x8E50, 0x5DB2, 0x8E51, + 0x5DB3, 0x8E52, 0x5DB4, 0x8E53, 0x5DB5, 0x8E54, 0x5DB6, 0x8E55, + 0x5DB7, 0xE1DA, 0x5DB8, 0x8E56, 0x5DB9, 0x8E57, 0x5DBA, 0x8E58, + 0x5DBB, 0x8E59, 0x5DBC, 0x8E5A, 0x5DBD, 0x8E5B, 0x5DBE, 0x8E5C, + 0x5DBF, 0x8E5D, 0x5DC0, 0x8E5E, 0x5DC1, 0x8E5F, 0x5DC2, 0x8E60, + 0x5DC3, 0x8E61, 0x5DC4, 0x8E62, 0x5DC5, 0xE1DB, 0x5DC6, 0x8E63, + 0x5DC7, 0x8E64, 0x5DC8, 0x8E65, 0x5DC9, 0x8E66, 0x5DCA, 0x8E67, + 0x5DCB, 0x8E68, 0x5DCC, 0x8E69, 0x5DCD, 0xCEA1, 0x5DCE, 0x8E6A, + 0x5DCF, 0x8E6B, 0x5DD0, 0x8E6C, 0x5DD1, 0x8E6D, 0x5DD2, 0x8E6E, + 0x5DD3, 0x8E6F, 0x5DD4, 0x8E70, 0x5DD5, 0x8E71, 0x5DD6, 0x8E72, + 0x5DD7, 0x8E73, 0x5DD8, 0x8E74, 0x5DD9, 0x8E75, 0x5DDA, 0x8E76, + 0x5DDB, 0xE7DD, 0x5DDC, 0x8E77, 0x5DDD, 0xB4A8, 0x5DDE, 0xD6DD, + 0x5DDF, 0x8E78, 0x5DE0, 0x8E79, 0x5DE1, 0xD1B2, 0x5DE2, 0xB3B2, + 0x5DE3, 0x8E7A, 0x5DE4, 0x8E7B, 0x5DE5, 0xB9A4, 0x5DE6, 0xD7F3, + 0x5DE7, 0xC7C9, 0x5DE8, 0xBEDE, 0x5DE9, 0xB9AE, 0x5DEA, 0x8E7C, + 0x5DEB, 0xCED7, 0x5DEC, 0x8E7D, 0x5DED, 0x8E7E, 0x5DEE, 0xB2EE, + 0x5DEF, 0xDBCF, 0x5DF0, 0x8E80, 0x5DF1, 0xBCBA, 0x5DF2, 0xD2D1, + 0x5DF3, 0xCBC8, 0x5DF4, 0xB0CD, 0x5DF5, 0x8E81, 0x5DF6, 0x8E82, + 0x5DF7, 0xCFEF, 0x5DF8, 0x8E83, 0x5DF9, 0x8E84, 0x5DFA, 0x8E85, + 0x5DFB, 0x8E86, 0x5DFC, 0x8E87, 0x5DFD, 0xD9E3, 0x5DFE, 0xBDED, + 0x5DFF, 0x8E88, 0x5E00, 0x8E89, 0x5E01, 0xB1D2, 0x5E02, 0xCAD0, + 0x5E03, 0xB2BC, 0x5E04, 0x8E8A, 0x5E05, 0xCBA7, 0x5E06, 0xB7AB, + 0x5E07, 0x8E8B, 0x5E08, 0xCAA6, 0x5E09, 0x8E8C, 0x5E0A, 0x8E8D, + 0x5E0B, 0x8E8E, 0x5E0C, 0xCFA3, 0x5E0D, 0x8E8F, 0x5E0E, 0x8E90, + 0x5E0F, 0xE0F8, 0x5E10, 0xD5CA, 0x5E11, 0xE0FB, 0x5E12, 0x8E91, + 0x5E13, 0x8E92, 0x5E14, 0xE0FA, 0x5E15, 0xC5C1, 0x5E16, 0xCCFB, + 0x5E17, 0x8E93, 0x5E18, 0xC1B1, 0x5E19, 0xE0F9, 0x5E1A, 0xD6E3, + 0x5E1B, 0xB2AF, 0x5E1C, 0xD6C4, 0x5E1D, 0xB5DB, 0x5E1E, 0x8E94, + 0x5E1F, 0x8E95, 0x5E20, 0x8E96, 0x5E21, 0x8E97, 0x5E22, 0x8E98, + 0x5E23, 0x8E99, 0x5E24, 0x8E9A, 0x5E25, 0x8E9B, 0x5E26, 0xB4F8, + 0x5E27, 0xD6A1, 0x5E28, 0x8E9C, 0x5E29, 0x8E9D, 0x5E2A, 0x8E9E, + 0x5E2B, 0x8E9F, 0x5E2C, 0x8EA0, 0x5E2D, 0xCFAF, 0x5E2E, 0xB0EF, + 0x5E2F, 0x8EA1, 0x5E30, 0x8EA2, 0x5E31, 0xE0FC, 0x5E32, 0x8EA3, + 0x5E33, 0x8EA4, 0x5E34, 0x8EA5, 0x5E35, 0x8EA6, 0x5E36, 0x8EA7, + 0x5E37, 0xE1A1, 0x5E38, 0xB3A3, 0x5E39, 0x8EA8, 0x5E3A, 0x8EA9, + 0x5E3B, 0xE0FD, 0x5E3C, 0xE0FE, 0x5E3D, 0xC3B1, 0x5E3E, 0x8EAA, + 0x5E3F, 0x8EAB, 0x5E40, 0x8EAC, 0x5E41, 0x8EAD, 0x5E42, 0xC3DD, + 0x5E43, 0x8EAE, 0x5E44, 0xE1A2, 0x5E45, 0xB7F9, 0x5E46, 0x8EAF, + 0x5E47, 0x8EB0, 0x5E48, 0x8EB1, 0x5E49, 0x8EB2, 0x5E4A, 0x8EB3, + 0x5E4B, 0x8EB4, 0x5E4C, 0xBBCF, 0x5E4D, 0x8EB5, 0x5E4E, 0x8EB6, + 0x5E4F, 0x8EB7, 0x5E50, 0x8EB8, 0x5E51, 0x8EB9, 0x5E52, 0x8EBA, + 0x5E53, 0x8EBB, 0x5E54, 0xE1A3, 0x5E55, 0xC4BB, 0x5E56, 0x8EBC, + 0x5E57, 0x8EBD, 0x5E58, 0x8EBE, 0x5E59, 0x8EBF, 0x5E5A, 0x8EC0, + 0x5E5B, 0xE1A4, 0x5E5C, 0x8EC1, 0x5E5D, 0x8EC2, 0x5E5E, 0xE1A5, + 0x5E5F, 0x8EC3, 0x5E60, 0x8EC4, 0x5E61, 0xE1A6, 0x5E62, 0xB4B1, + 0x5E63, 0x8EC5, 0x5E64, 0x8EC6, 0x5E65, 0x8EC7, 0x5E66, 0x8EC8, + 0x5E67, 0x8EC9, 0x5E68, 0x8ECA, 0x5E69, 0x8ECB, 0x5E6A, 0x8ECC, + 0x5E6B, 0x8ECD, 0x5E6C, 0x8ECE, 0x5E6D, 0x8ECF, 0x5E6E, 0x8ED0, + 0x5E6F, 0x8ED1, 0x5E70, 0x8ED2, 0x5E71, 0x8ED3, 0x5E72, 0xB8C9, + 0x5E73, 0xC6BD, 0x5E74, 0xC4EA, 0x5E75, 0x8ED4, 0x5E76, 0xB2A2, + 0x5E77, 0x8ED5, 0x5E78, 0xD0D2, 0x5E79, 0x8ED6, 0x5E7A, 0xE7DB, + 0x5E7B, 0xBBC3, 0x5E7C, 0xD3D7, 0x5E7D, 0xD3C4, 0x5E7E, 0x8ED7, + 0x5E7F, 0xB9E3, 0x5E80, 0xE2CF, 0x5E81, 0x8ED8, 0x5E82, 0x8ED9, + 0x5E83, 0x8EDA, 0x5E84, 0xD7AF, 0x5E85, 0x8EDB, 0x5E86, 0xC7EC, + 0x5E87, 0xB1D3, 0x5E88, 0x8EDC, 0x5E89, 0x8EDD, 0x5E8A, 0xB4B2, + 0x5E8B, 0xE2D1, 0x5E8C, 0x8EDE, 0x5E8D, 0x8EDF, 0x5E8E, 0x8EE0, + 0x5E8F, 0xD0F2, 0x5E90, 0xC2AE, 0x5E91, 0xE2D0, 0x5E92, 0x8EE1, + 0x5E93, 0xBFE2, 0x5E94, 0xD3A6, 0x5E95, 0xB5D7, 0x5E96, 0xE2D2, + 0x5E97, 0xB5EA, 0x5E98, 0x8EE2, 0x5E99, 0xC3ED, 0x5E9A, 0xB8FD, + 0x5E9B, 0x8EE3, 0x5E9C, 0xB8AE, 0x5E9D, 0x8EE4, 0x5E9E, 0xC5D3, + 0x5E9F, 0xB7CF, 0x5EA0, 0xE2D4, 0x5EA1, 0x8EE5, 0x5EA2, 0x8EE6, + 0x5EA3, 0x8EE7, 0x5EA4, 0x8EE8, 0x5EA5, 0xE2D3, 0x5EA6, 0xB6C8, + 0x5EA7, 0xD7F9, 0x5EA8, 0x8EE9, 0x5EA9, 0x8EEA, 0x5EAA, 0x8EEB, + 0x5EAB, 0x8EEC, 0x5EAC, 0x8EED, 0x5EAD, 0xCDA5, 0x5EAE, 0x8EEE, + 0x5EAF, 0x8EEF, 0x5EB0, 0x8EF0, 0x5EB1, 0x8EF1, 0x5EB2, 0x8EF2, + 0x5EB3, 0xE2D8, 0x5EB4, 0x8EF3, 0x5EB5, 0xE2D6, 0x5EB6, 0xCAFC, + 0x5EB7, 0xBFB5, 0x5EB8, 0xD3B9, 0x5EB9, 0xE2D5, 0x5EBA, 0x8EF4, + 0x5EBB, 0x8EF5, 0x5EBC, 0x8EF6, 0x5EBD, 0x8EF7, 0x5EBE, 0xE2D7, + 0x5EBF, 0x8EF8, 0x5EC0, 0x8EF9, 0x5EC1, 0x8EFA, 0x5EC2, 0x8EFB, + 0x5EC3, 0x8EFC, 0x5EC4, 0x8EFD, 0x5EC5, 0x8EFE, 0x5EC6, 0x8F40, + 0x5EC7, 0x8F41, 0x5EC8, 0x8F42, 0x5EC9, 0xC1AE, 0x5ECA, 0xC0C8, + 0x5ECB, 0x8F43, 0x5ECC, 0x8F44, 0x5ECD, 0x8F45, 0x5ECE, 0x8F46, + 0x5ECF, 0x8F47, 0x5ED0, 0x8F48, 0x5ED1, 0xE2DB, 0x5ED2, 0xE2DA, + 0x5ED3, 0xC0AA, 0x5ED4, 0x8F49, 0x5ED5, 0x8F4A, 0x5ED6, 0xC1CE, + 0x5ED7, 0x8F4B, 0x5ED8, 0x8F4C, 0x5ED9, 0x8F4D, 0x5EDA, 0x8F4E, + 0x5EDB, 0xE2DC, 0x5EDC, 0x8F4F, 0x5EDD, 0x8F50, 0x5EDE, 0x8F51, + 0x5EDF, 0x8F52, 0x5EE0, 0x8F53, 0x5EE1, 0x8F54, 0x5EE2, 0x8F55, + 0x5EE3, 0x8F56, 0x5EE4, 0x8F57, 0x5EE5, 0x8F58, 0x5EE6, 0x8F59, + 0x5EE7, 0x8F5A, 0x5EE8, 0xE2DD, 0x5EE9, 0x8F5B, 0x5EEA, 0xE2DE, + 0x5EEB, 0x8F5C, 0x5EEC, 0x8F5D, 0x5EED, 0x8F5E, 0x5EEE, 0x8F5F, + 0x5EEF, 0x8F60, 0x5EF0, 0x8F61, 0x5EF1, 0x8F62, 0x5EF2, 0x8F63, + 0x5EF3, 0x8F64, 0x5EF4, 0xDBC8, 0x5EF5, 0x8F65, 0x5EF6, 0xD1D3, + 0x5EF7, 0xCDA2, 0x5EF8, 0x8F66, 0x5EF9, 0x8F67, 0x5EFA, 0xBDA8, + 0x5EFB, 0x8F68, 0x5EFC, 0x8F69, 0x5EFD, 0x8F6A, 0x5EFE, 0xDEC3, + 0x5EFF, 0xD8A5, 0x5F00, 0xBFAA, 0x5F01, 0xDBCD, 0x5F02, 0xD2EC, + 0x5F03, 0xC6FA, 0x5F04, 0xC5AA, 0x5F05, 0x8F6B, 0x5F06, 0x8F6C, + 0x5F07, 0x8F6D, 0x5F08, 0xDEC4, 0x5F09, 0x8F6E, 0x5F0A, 0xB1D7, + 0x5F0B, 0xDFAE, 0x5F0C, 0x8F6F, 0x5F0D, 0x8F70, 0x5F0E, 0x8F71, + 0x5F0F, 0xCABD, 0x5F10, 0x8F72, 0x5F11, 0xDFB1, 0x5F12, 0x8F73, + 0x5F13, 0xB9AD, 0x5F14, 0x8F74, 0x5F15, 0xD2FD, 0x5F16, 0x8F75, + 0x5F17, 0xB8A5, 0x5F18, 0xBAEB, 0x5F19, 0x8F76, 0x5F1A, 0x8F77, + 0x5F1B, 0xB3DA, 0x5F1C, 0x8F78, 0x5F1D, 0x8F79, 0x5F1E, 0x8F7A, + 0x5F1F, 0xB5DC, 0x5F20, 0xD5C5, 0x5F21, 0x8F7B, 0x5F22, 0x8F7C, + 0x5F23, 0x8F7D, 0x5F24, 0x8F7E, 0x5F25, 0xC3D6, 0x5F26, 0xCFD2, + 0x5F27, 0xBBA1, 0x5F28, 0x8F80, 0x5F29, 0xE5F3, 0x5F2A, 0xE5F2, + 0x5F2B, 0x8F81, 0x5F2C, 0x8F82, 0x5F2D, 0xE5F4, 0x5F2E, 0x8F83, + 0x5F2F, 0xCDE4, 0x5F30, 0x8F84, 0x5F31, 0xC8F5, 0x5F32, 0x8F85, + 0x5F33, 0x8F86, 0x5F34, 0x8F87, 0x5F35, 0x8F88, 0x5F36, 0x8F89, + 0x5F37, 0x8F8A, 0x5F38, 0x8F8B, 0x5F39, 0xB5AF, 0x5F3A, 0xC7BF, + 0x5F3B, 0x8F8C, 0x5F3C, 0xE5F6, 0x5F3D, 0x8F8D, 0x5F3E, 0x8F8E, + 0x5F3F, 0x8F8F, 0x5F40, 0xECB0, 0x5F41, 0x8F90, 0x5F42, 0x8F91, + 0x5F43, 0x8F92, 0x5F44, 0x8F93, 0x5F45, 0x8F94, 0x5F46, 0x8F95, + 0x5F47, 0x8F96, 0x5F48, 0x8F97, 0x5F49, 0x8F98, 0x5F4A, 0x8F99, + 0x5F4B, 0x8F9A, 0x5F4C, 0x8F9B, 0x5F4D, 0x8F9C, 0x5F4E, 0x8F9D, + 0x5F4F, 0x8F9E, 0x5F50, 0xE5E6, 0x5F51, 0x8F9F, 0x5F52, 0xB9E9, + 0x5F53, 0xB5B1, 0x5F54, 0x8FA0, 0x5F55, 0xC2BC, 0x5F56, 0xE5E8, + 0x5F57, 0xE5E7, 0x5F58, 0xE5E9, 0x5F59, 0x8FA1, 0x5F5A, 0x8FA2, + 0x5F5B, 0x8FA3, 0x5F5C, 0x8FA4, 0x5F5D, 0xD2CD, 0x5F5E, 0x8FA5, + 0x5F5F, 0x8FA6, 0x5F60, 0x8FA7, 0x5F61, 0xE1EA, 0x5F62, 0xD0CE, + 0x5F63, 0x8FA8, 0x5F64, 0xCDAE, 0x5F65, 0x8FA9, 0x5F66, 0xD1E5, + 0x5F67, 0x8FAA, 0x5F68, 0x8FAB, 0x5F69, 0xB2CA, 0x5F6A, 0xB1EB, + 0x5F6B, 0x8FAC, 0x5F6C, 0xB1F2, 0x5F6D, 0xC5ED, 0x5F6E, 0x8FAD, + 0x5F6F, 0x8FAE, 0x5F70, 0xD5C3, 0x5F71, 0xD3B0, 0x5F72, 0x8FAF, + 0x5F73, 0xE1DC, 0x5F74, 0x8FB0, 0x5F75, 0x8FB1, 0x5F76, 0x8FB2, + 0x5F77, 0xE1DD, 0x5F78, 0x8FB3, 0x5F79, 0xD2DB, 0x5F7A, 0x8FB4, + 0x5F7B, 0xB3B9, 0x5F7C, 0xB1CB, 0x5F7D, 0x8FB5, 0x5F7E, 0x8FB6, + 0x5F7F, 0x8FB7, 0x5F80, 0xCDF9, 0x5F81, 0xD5F7, 0x5F82, 0xE1DE, + 0x5F83, 0x8FB8, 0x5F84, 0xBEB6, 0x5F85, 0xB4FD, 0x5F86, 0x8FB9, + 0x5F87, 0xE1DF, 0x5F88, 0xBADC, 0x5F89, 0xE1E0, 0x5F8A, 0xBBB2, + 0x5F8B, 0xC2C9, 0x5F8C, 0xE1E1, 0x5F8D, 0x8FBA, 0x5F8E, 0x8FBB, + 0x5F8F, 0x8FBC, 0x5F90, 0xD0EC, 0x5F91, 0x8FBD, 0x5F92, 0xCDBD, + 0x5F93, 0x8FBE, 0x5F94, 0x8FBF, 0x5F95, 0xE1E2, 0x5F96, 0x8FC0, + 0x5F97, 0xB5C3, 0x5F98, 0xC5C7, 0x5F99, 0xE1E3, 0x5F9A, 0x8FC1, + 0x5F9B, 0x8FC2, 0x5F9C, 0xE1E4, 0x5F9D, 0x8FC3, 0x5F9E, 0x8FC4, + 0x5F9F, 0x8FC5, 0x5FA0, 0x8FC6, 0x5FA1, 0xD3F9, 0x5FA2, 0x8FC7, + 0x5FA3, 0x8FC8, 0x5FA4, 0x8FC9, 0x5FA5, 0x8FCA, 0x5FA6, 0x8FCB, + 0x5FA7, 0x8FCC, 0x5FA8, 0xE1E5, 0x5FA9, 0x8FCD, 0x5FAA, 0xD1AD, + 0x5FAB, 0x8FCE, 0x5FAC, 0x8FCF, 0x5FAD, 0xE1E6, 0x5FAE, 0xCEA2, + 0x5FAF, 0x8FD0, 0x5FB0, 0x8FD1, 0x5FB1, 0x8FD2, 0x5FB2, 0x8FD3, + 0x5FB3, 0x8FD4, 0x5FB4, 0x8FD5, 0x5FB5, 0xE1E7, 0x5FB6, 0x8FD6, + 0x5FB7, 0xB5C2, 0x5FB8, 0x8FD7, 0x5FB9, 0x8FD8, 0x5FBA, 0x8FD9, + 0x5FBB, 0x8FDA, 0x5FBC, 0xE1E8, 0x5FBD, 0xBBD5, 0x5FBE, 0x8FDB, + 0x5FBF, 0x8FDC, 0x5FC0, 0x8FDD, 0x5FC1, 0x8FDE, 0x5FC2, 0x8FDF, + 0x5FC3, 0xD0C4, 0x5FC4, 0xE2E0, 0x5FC5, 0xB1D8, 0x5FC6, 0xD2E4, + 0x5FC7, 0x8FE0, 0x5FC8, 0x8FE1, 0x5FC9, 0xE2E1, 0x5FCA, 0x8FE2, + 0x5FCB, 0x8FE3, 0x5FCC, 0xBCC9, 0x5FCD, 0xC8CC, 0x5FCE, 0x8FE4, + 0x5FCF, 0xE2E3, 0x5FD0, 0xECFE, 0x5FD1, 0xECFD, 0x5FD2, 0xDFAF, + 0x5FD3, 0x8FE5, 0x5FD4, 0x8FE6, 0x5FD5, 0x8FE7, 0x5FD6, 0xE2E2, + 0x5FD7, 0xD6BE, 0x5FD8, 0xCDFC, 0x5FD9, 0xC3A6, 0x5FDA, 0x8FE8, + 0x5FDB, 0x8FE9, 0x5FDC, 0x8FEA, 0x5FDD, 0xE3C3, 0x5FDE, 0x8FEB, + 0x5FDF, 0x8FEC, 0x5FE0, 0xD6D2, 0x5FE1, 0xE2E7, 0x5FE2, 0x8FED, + 0x5FE3, 0x8FEE, 0x5FE4, 0xE2E8, 0x5FE5, 0x8FEF, 0x5FE6, 0x8FF0, + 0x5FE7, 0xD3C7, 0x5FE8, 0x8FF1, 0x5FE9, 0x8FF2, 0x5FEA, 0xE2EC, + 0x5FEB, 0xBFEC, 0x5FEC, 0x8FF3, 0x5FED, 0xE2ED, 0x5FEE, 0xE2E5, + 0x5FEF, 0x8FF4, 0x5FF0, 0x8FF5, 0x5FF1, 0xB3C0, 0x5FF2, 0x8FF6, + 0x5FF3, 0x8FF7, 0x5FF4, 0x8FF8, 0x5FF5, 0xC4EE, 0x5FF6, 0x8FF9, + 0x5FF7, 0x8FFA, 0x5FF8, 0xE2EE, 0x5FF9, 0x8FFB, 0x5FFA, 0x8FFC, + 0x5FFB, 0xD0C3, 0x5FFC, 0x8FFD, 0x5FFD, 0xBAF6, 0x5FFE, 0xE2E9, + 0x5FFF, 0xB7DE, 0x6000, 0xBBB3, 0x6001, 0xCCAC, 0x6002, 0xCBCB, + 0x6003, 0xE2E4, 0x6004, 0xE2E6, 0x6005, 0xE2EA, 0x6006, 0xE2EB, + 0x6007, 0x8FFE, 0x6008, 0x9040, 0x6009, 0x9041, 0x600A, 0xE2F7, + 0x600B, 0x9042, 0x600C, 0x9043, 0x600D, 0xE2F4, 0x600E, 0xD4F5, + 0x600F, 0xE2F3, 0x6010, 0x9044, 0x6011, 0x9045, 0x6012, 0xC5AD, + 0x6013, 0x9046, 0x6014, 0xD5FA, 0x6015, 0xC5C2, 0x6016, 0xB2C0, + 0x6017, 0x9047, 0x6018, 0x9048, 0x6019, 0xE2EF, 0x601A, 0x9049, + 0x601B, 0xE2F2, 0x601C, 0xC1AF, 0x601D, 0xCBBC, 0x601E, 0x904A, + 0x601F, 0x904B, 0x6020, 0xB5A1, 0x6021, 0xE2F9, 0x6022, 0x904C, + 0x6023, 0x904D, 0x6024, 0x904E, 0x6025, 0xBCB1, 0x6026, 0xE2F1, + 0x6027, 0xD0D4, 0x6028, 0xD4B9, 0x6029, 0xE2F5, 0x602A, 0xB9D6, + 0x602B, 0xE2F6, 0x602C, 0x904F, 0x602D, 0x9050, 0x602E, 0x9051, + 0x602F, 0xC7D3, 0x6030, 0x9052, 0x6031, 0x9053, 0x6032, 0x9054, + 0x6033, 0x9055, 0x6034, 0x9056, 0x6035, 0xE2F0, 0x6036, 0x9057, + 0x6037, 0x9058, 0x6038, 0x9059, 0x6039, 0x905A, 0x603A, 0x905B, + 0x603B, 0xD7DC, 0x603C, 0xEDA1, 0x603D, 0x905C, 0x603E, 0x905D, + 0x603F, 0xE2F8, 0x6040, 0x905E, 0x6041, 0xEDA5, 0x6042, 0xE2FE, + 0x6043, 0xCAD1, 0x6044, 0x905F, 0x6045, 0x9060, 0x6046, 0x9061, + 0x6047, 0x9062, 0x6048, 0x9063, 0x6049, 0x9064, 0x604A, 0x9065, + 0x604B, 0xC1B5, 0x604C, 0x9066, 0x604D, 0xBBD0, 0x604E, 0x9067, + 0x604F, 0x9068, 0x6050, 0xBFD6, 0x6051, 0x9069, 0x6052, 0xBAE3, + 0x6053, 0x906A, 0x6054, 0x906B, 0x6055, 0xCBA1, 0x6056, 0x906C, + 0x6057, 0x906D, 0x6058, 0x906E, 0x6059, 0xEDA6, 0x605A, 0xEDA3, + 0x605B, 0x906F, 0x605C, 0x9070, 0x605D, 0xEDA2, 0x605E, 0x9071, + 0x605F, 0x9072, 0x6060, 0x9073, 0x6061, 0x9074, 0x6062, 0xBBD6, + 0x6063, 0xEDA7, 0x6064, 0xD0F4, 0x6065, 0x9075, 0x6066, 0x9076, + 0x6067, 0xEDA4, 0x6068, 0xBADE, 0x6069, 0xB6F7, 0x606A, 0xE3A1, + 0x606B, 0xB6B2, 0x606C, 0xCCF1, 0x606D, 0xB9A7, 0x606E, 0x9077, + 0x606F, 0xCFA2, 0x6070, 0xC7A1, 0x6071, 0x9078, 0x6072, 0x9079, + 0x6073, 0xBFD2, 0x6074, 0x907A, 0x6075, 0x907B, 0x6076, 0xB6F1, + 0x6077, 0x907C, 0x6078, 0xE2FA, 0x6079, 0xE2FB, 0x607A, 0xE2FD, + 0x607B, 0xE2FC, 0x607C, 0xC4D5, 0x607D, 0xE3A2, 0x607E, 0x907D, + 0x607F, 0xD3C1, 0x6080, 0x907E, 0x6081, 0x9080, 0x6082, 0x9081, + 0x6083, 0xE3A7, 0x6084, 0xC7C4, 0x6085, 0x9082, 0x6086, 0x9083, + 0x6087, 0x9084, 0x6088, 0x9085, 0x6089, 0xCFA4, 0x608A, 0x9086, + 0x608B, 0x9087, 0x608C, 0xE3A9, 0x608D, 0xBAB7, 0x608E, 0x9088, + 0x608F, 0x9089, 0x6090, 0x908A, 0x6091, 0x908B, 0x6092, 0xE3A8, + 0x6093, 0x908C, 0x6094, 0xBBDA, 0x6095, 0x908D, 0x6096, 0xE3A3, + 0x6097, 0x908E, 0x6098, 0x908F, 0x6099, 0x9090, 0x609A, 0xE3A4, + 0x609B, 0xE3AA, 0x609C, 0x9091, 0x609D, 0xE3A6, 0x609E, 0x9092, + 0x609F, 0xCEF2, 0x60A0, 0xD3C6, 0x60A1, 0x9093, 0x60A2, 0x9094, + 0x60A3, 0xBBBC, 0x60A4, 0x9095, 0x60A5, 0x9096, 0x60A6, 0xD4C3, + 0x60A7, 0x9097, 0x60A8, 0xC4FA, 0x60A9, 0x9098, 0x60AA, 0x9099, + 0x60AB, 0xEDA8, 0x60AC, 0xD0FC, 0x60AD, 0xE3A5, 0x60AE, 0x909A, + 0x60AF, 0xC3F5, 0x60B0, 0x909B, 0x60B1, 0xE3AD, 0x60B2, 0xB1AF, + 0x60B3, 0x909C, 0x60B4, 0xE3B2, 0x60B5, 0x909D, 0x60B6, 0x909E, + 0x60B7, 0x909F, 0x60B8, 0xBCC2, 0x60B9, 0x90A0, 0x60BA, 0x90A1, + 0x60BB, 0xE3AC, 0x60BC, 0xB5BF, 0x60BD, 0x90A2, 0x60BE, 0x90A3, + 0x60BF, 0x90A4, 0x60C0, 0x90A5, 0x60C1, 0x90A6, 0x60C2, 0x90A7, + 0x60C3, 0x90A8, 0x60C4, 0x90A9, 0x60C5, 0xC7E9, 0x60C6, 0xE3B0, + 0x60C7, 0x90AA, 0x60C8, 0x90AB, 0x60C9, 0x90AC, 0x60CA, 0xBEAA, + 0x60CB, 0xCDEF, 0x60CC, 0x90AD, 0x60CD, 0x90AE, 0x60CE, 0x90AF, + 0x60CF, 0x90B0, 0x60D0, 0x90B1, 0x60D1, 0xBBF3, 0x60D2, 0x90B2, + 0x60D3, 0x90B3, 0x60D4, 0x90B4, 0x60D5, 0xCCE8, 0x60D6, 0x90B5, + 0x60D7, 0x90B6, 0x60D8, 0xE3AF, 0x60D9, 0x90B7, 0x60DA, 0xE3B1, + 0x60DB, 0x90B8, 0x60DC, 0xCFA7, 0x60DD, 0xE3AE, 0x60DE, 0x90B9, + 0x60DF, 0xCEA9, 0x60E0, 0xBBDD, 0x60E1, 0x90BA, 0x60E2, 0x90BB, + 0x60E3, 0x90BC, 0x60E4, 0x90BD, 0x60E5, 0x90BE, 0x60E6, 0xB5EB, + 0x60E7, 0xBEE5, 0x60E8, 0xB2D2, 0x60E9, 0xB3CD, 0x60EA, 0x90BF, + 0x60EB, 0xB1B9, 0x60EC, 0xE3AB, 0x60ED, 0xB2D1, 0x60EE, 0xB5AC, + 0x60EF, 0xB9DF, 0x60F0, 0xB6E8, 0x60F1, 0x90C0, 0x60F2, 0x90C1, + 0x60F3, 0xCFEB, 0x60F4, 0xE3B7, 0x60F5, 0x90C2, 0x60F6, 0xBBCC, + 0x60F7, 0x90C3, 0x60F8, 0x90C4, 0x60F9, 0xC8C7, 0x60FA, 0xD0CA, + 0x60FB, 0x90C5, 0x60FC, 0x90C6, 0x60FD, 0x90C7, 0x60FE, 0x90C8, + 0x60FF, 0x90C9, 0x6100, 0xE3B8, 0x6101, 0xB3EE, 0x6102, 0x90CA, + 0x6103, 0x90CB, 0x6104, 0x90CC, 0x6105, 0x90CD, 0x6106, 0xEDA9, + 0x6107, 0x90CE, 0x6108, 0xD3FA, 0x6109, 0xD3E4, 0x610A, 0x90CF, + 0x610B, 0x90D0, 0x610C, 0x90D1, 0x610D, 0xEDAA, 0x610E, 0xE3B9, + 0x610F, 0xD2E2, 0x6110, 0x90D2, 0x6111, 0x90D3, 0x6112, 0x90D4, + 0x6113, 0x90D5, 0x6114, 0x90D6, 0x6115, 0xE3B5, 0x6116, 0x90D7, + 0x6117, 0x90D8, 0x6118, 0x90D9, 0x6119, 0x90DA, 0x611A, 0xD3DE, + 0x611B, 0x90DB, 0x611C, 0x90DC, 0x611D, 0x90DD, 0x611E, 0x90DE, + 0x611F, 0xB8D0, 0x6120, 0xE3B3, 0x6121, 0x90DF, 0x6122, 0x90E0, + 0x6123, 0xE3B6, 0x6124, 0xB7DF, 0x6125, 0x90E1, 0x6126, 0xE3B4, + 0x6127, 0xC0A2, 0x6128, 0x90E2, 0x6129, 0x90E3, 0x612A, 0x90E4, + 0x612B, 0xE3BA, 0x612C, 0x90E5, 0x612D, 0x90E6, 0x612E, 0x90E7, + 0x612F, 0x90E8, 0x6130, 0x90E9, 0x6131, 0x90EA, 0x6132, 0x90EB, + 0x6133, 0x90EC, 0x6134, 0x90ED, 0x6135, 0x90EE, 0x6136, 0x90EF, + 0x6137, 0x90F0, 0x6138, 0x90F1, 0x6139, 0x90F2, 0x613A, 0x90F3, + 0x613B, 0x90F4, 0x613C, 0x90F5, 0x613D, 0x90F6, 0x613E, 0x90F7, + 0x613F, 0xD4B8, 0x6140, 0x90F8, 0x6141, 0x90F9, 0x6142, 0x90FA, + 0x6143, 0x90FB, 0x6144, 0x90FC, 0x6145, 0x90FD, 0x6146, 0x90FE, + 0x6147, 0x9140, 0x6148, 0xB4C8, 0x6149, 0x9141, 0x614A, 0xE3BB, + 0x614B, 0x9142, 0x614C, 0xBBC5, 0x614D, 0x9143, 0x614E, 0xC9F7, + 0x614F, 0x9144, 0x6150, 0x9145, 0x6151, 0xC9E5, 0x6152, 0x9146, + 0x6153, 0x9147, 0x6154, 0x9148, 0x6155, 0xC4BD, 0x6156, 0x9149, + 0x6157, 0x914A, 0x6158, 0x914B, 0x6159, 0x914C, 0x615A, 0x914D, + 0x615B, 0x914E, 0x615C, 0x914F, 0x615D, 0xEDAB, 0x615E, 0x9150, + 0x615F, 0x9151, 0x6160, 0x9152, 0x6161, 0x9153, 0x6162, 0xC2FD, + 0x6163, 0x9154, 0x6164, 0x9155, 0x6165, 0x9156, 0x6166, 0x9157, + 0x6167, 0xBBDB, 0x6168, 0xBFAE, 0x6169, 0x9158, 0x616A, 0x9159, + 0x616B, 0x915A, 0x616C, 0x915B, 0x616D, 0x915C, 0x616E, 0x915D, + 0x616F, 0x915E, 0x6170, 0xCEBF, 0x6171, 0x915F, 0x6172, 0x9160, + 0x6173, 0x9161, 0x6174, 0x9162, 0x6175, 0xE3BC, 0x6176, 0x9163, + 0x6177, 0xBFB6, 0x6178, 0x9164, 0x6179, 0x9165, 0x617A, 0x9166, + 0x617B, 0x9167, 0x617C, 0x9168, 0x617D, 0x9169, 0x617E, 0x916A, + 0x617F, 0x916B, 0x6180, 0x916C, 0x6181, 0x916D, 0x6182, 0x916E, + 0x6183, 0x916F, 0x6184, 0x9170, 0x6185, 0x9171, 0x6186, 0x9172, + 0x6187, 0x9173, 0x6188, 0x9174, 0x6189, 0x9175, 0x618A, 0x9176, + 0x618B, 0xB1EF, 0x618C, 0x9177, 0x618D, 0x9178, 0x618E, 0xD4F7, + 0x618F, 0x9179, 0x6190, 0x917A, 0x6191, 0x917B, 0x6192, 0x917C, + 0x6193, 0x917D, 0x6194, 0xE3BE, 0x6195, 0x917E, 0x6196, 0x9180, + 0x6197, 0x9181, 0x6198, 0x9182, 0x6199, 0x9183, 0x619A, 0x9184, + 0x619B, 0x9185, 0x619C, 0x9186, 0x619D, 0xEDAD, 0x619E, 0x9187, + 0x619F, 0x9188, 0x61A0, 0x9189, 0x61A1, 0x918A, 0x61A2, 0x918B, + 0x61A3, 0x918C, 0x61A4, 0x918D, 0x61A5, 0x918E, 0x61A6, 0x918F, + 0x61A7, 0xE3BF, 0x61A8, 0xBAA9, 0x61A9, 0xEDAC, 0x61AA, 0x9190, + 0x61AB, 0x9191, 0x61AC, 0xE3BD, 0x61AD, 0x9192, 0x61AE, 0x9193, + 0x61AF, 0x9194, 0x61B0, 0x9195, 0x61B1, 0x9196, 0x61B2, 0x9197, + 0x61B3, 0x9198, 0x61B4, 0x9199, 0x61B5, 0x919A, 0x61B6, 0x919B, + 0x61B7, 0xE3C0, 0x61B8, 0x919C, 0x61B9, 0x919D, 0x61BA, 0x919E, + 0x61BB, 0x919F, 0x61BC, 0x91A0, 0x61BD, 0x91A1, 0x61BE, 0xBAB6, + 0x61BF, 0x91A2, 0x61C0, 0x91A3, 0x61C1, 0x91A4, 0x61C2, 0xB6AE, + 0x61C3, 0x91A5, 0x61C4, 0x91A6, 0x61C5, 0x91A7, 0x61C6, 0x91A8, + 0x61C7, 0x91A9, 0x61C8, 0xD0B8, 0x61C9, 0x91AA, 0x61CA, 0xB0C3, + 0x61CB, 0xEDAE, 0x61CC, 0x91AB, 0x61CD, 0x91AC, 0x61CE, 0x91AD, + 0x61CF, 0x91AE, 0x61D0, 0x91AF, 0x61D1, 0xEDAF, 0x61D2, 0xC0C1, + 0x61D3, 0x91B0, 0x61D4, 0xE3C1, 0x61D5, 0x91B1, 0x61D6, 0x91B2, + 0x61D7, 0x91B3, 0x61D8, 0x91B4, 0x61D9, 0x91B5, 0x61DA, 0x91B6, + 0x61DB, 0x91B7, 0x61DC, 0x91B8, 0x61DD, 0x91B9, 0x61DE, 0x91BA, + 0x61DF, 0x91BB, 0x61E0, 0x91BC, 0x61E1, 0x91BD, 0x61E2, 0x91BE, + 0x61E3, 0x91BF, 0x61E4, 0x91C0, 0x61E5, 0x91C1, 0x61E6, 0xC5B3, + 0x61E7, 0x91C2, 0x61E8, 0x91C3, 0x61E9, 0x91C4, 0x61EA, 0x91C5, + 0x61EB, 0x91C6, 0x61EC, 0x91C7, 0x61ED, 0x91C8, 0x61EE, 0x91C9, + 0x61EF, 0x91CA, 0x61F0, 0x91CB, 0x61F1, 0x91CC, 0x61F2, 0x91CD, + 0x61F3, 0x91CE, 0x61F4, 0x91CF, 0x61F5, 0xE3C2, 0x61F6, 0x91D0, + 0x61F7, 0x91D1, 0x61F8, 0x91D2, 0x61F9, 0x91D3, 0x61FA, 0x91D4, + 0x61FB, 0x91D5, 0x61FC, 0x91D6, 0x61FD, 0x91D7, 0x61FE, 0x91D8, + 0x61FF, 0xDCB2, 0x6200, 0x91D9, 0x6201, 0x91DA, 0x6202, 0x91DB, + 0x6203, 0x91DC, 0x6204, 0x91DD, 0x6205, 0x91DE, 0x6206, 0xEDB0, + 0x6207, 0x91DF, 0x6208, 0xB8EA, 0x6209, 0x91E0, 0x620A, 0xCEEC, + 0x620B, 0xEAA7, 0x620C, 0xD0E7, 0x620D, 0xCAF9, 0x620E, 0xC8D6, + 0x620F, 0xCFB7, 0x6210, 0xB3C9, 0x6211, 0xCED2, 0x6212, 0xBDE4, + 0x6213, 0x91E1, 0x6214, 0x91E2, 0x6215, 0xE3DE, 0x6216, 0xBBF2, + 0x6217, 0xEAA8, 0x6218, 0xD5BD, 0x6219, 0x91E3, 0x621A, 0xC6DD, + 0x621B, 0xEAA9, 0x621C, 0x91E4, 0x621D, 0x91E5, 0x621E, 0x91E6, + 0x621F, 0xEAAA, 0x6220, 0x91E7, 0x6221, 0xEAAC, 0x6222, 0xEAAB, + 0x6223, 0x91E8, 0x6224, 0xEAAE, 0x6225, 0xEAAD, 0x6226, 0x91E9, + 0x6227, 0x91EA, 0x6228, 0x91EB, 0x6229, 0x91EC, 0x622A, 0xBDD8, + 0x622B, 0x91ED, 0x622C, 0xEAAF, 0x622D, 0x91EE, 0x622E, 0xC2BE, + 0x622F, 0x91EF, 0x6230, 0x91F0, 0x6231, 0x91F1, 0x6232, 0x91F2, + 0x6233, 0xB4C1, 0x6234, 0xB4F7, 0x6235, 0x91F3, 0x6236, 0x91F4, + 0x6237, 0xBBA7, 0x6238, 0x91F5, 0x6239, 0x91F6, 0x623A, 0x91F7, + 0x623B, 0x91F8, 0x623C, 0x91F9, 0x623D, 0xECE6, 0x623E, 0xECE5, + 0x623F, 0xB7BF, 0x6240, 0xCBF9, 0x6241, 0xB1E2, 0x6242, 0x91FA, + 0x6243, 0xECE7, 0x6244, 0x91FB, 0x6245, 0x91FC, 0x6246, 0x91FD, + 0x6247, 0xC9C8, 0x6248, 0xECE8, 0x6249, 0xECE9, 0x624A, 0x91FE, + 0x624B, 0xCAD6, 0x624C, 0xDED0, 0x624D, 0xB2C5, 0x624E, 0xD4FA, + 0x624F, 0x9240, 0x6250, 0x9241, 0x6251, 0xC6CB, 0x6252, 0xB0C7, + 0x6253, 0xB4F2, 0x6254, 0xC8D3, 0x6255, 0x9242, 0x6256, 0x9243, + 0x6257, 0x9244, 0x6258, 0xCDD0, 0x6259, 0x9245, 0x625A, 0x9246, + 0x625B, 0xBFB8, 0x625C, 0x9247, 0x625D, 0x9248, 0x625E, 0x9249, + 0x625F, 0x924A, 0x6260, 0x924B, 0x6261, 0x924C, 0x6262, 0x924D, + 0x6263, 0xBFDB, 0x6264, 0x924E, 0x6265, 0x924F, 0x6266, 0xC7A4, + 0x6267, 0xD6B4, 0x6268, 0x9250, 0x6269, 0xC0A9, 0x626A, 0xDED1, + 0x626B, 0xC9A8, 0x626C, 0xD1EF, 0x626D, 0xC5A4, 0x626E, 0xB0E7, + 0x626F, 0xB3B6, 0x6270, 0xC8C5, 0x6271, 0x9251, 0x6272, 0x9252, + 0x6273, 0xB0E2, 0x6274, 0x9253, 0x6275, 0x9254, 0x6276, 0xB7F6, + 0x6277, 0x9255, 0x6278, 0x9256, 0x6279, 0xC5FA, 0x627A, 0x9257, + 0x627B, 0x9258, 0x627C, 0xB6F3, 0x627D, 0x9259, 0x627E, 0xD5D2, + 0x627F, 0xB3D0, 0x6280, 0xBCBC, 0x6281, 0x925A, 0x6282, 0x925B, + 0x6283, 0x925C, 0x6284, 0xB3AD, 0x6285, 0x925D, 0x6286, 0x925E, + 0x6287, 0x925F, 0x6288, 0x9260, 0x6289, 0xBEF1, 0x628A, 0xB0D1, + 0x628B, 0x9261, 0x628C, 0x9262, 0x628D, 0x9263, 0x628E, 0x9264, + 0x628F, 0x9265, 0x6290, 0x9266, 0x6291, 0xD2D6, 0x6292, 0xCAE3, + 0x6293, 0xD7A5, 0x6294, 0x9267, 0x6295, 0xCDB6, 0x6296, 0xB6B6, + 0x6297, 0xBFB9, 0x6298, 0xD5DB, 0x6299, 0x9268, 0x629A, 0xB8A7, + 0x629B, 0xC5D7, 0x629C, 0x9269, 0x629D, 0x926A, 0x629E, 0x926B, + 0x629F, 0xDED2, 0x62A0, 0xBFD9, 0x62A1, 0xC2D5, 0x62A2, 0xC7C0, + 0x62A3, 0x926C, 0x62A4, 0xBBA4, 0x62A5, 0xB1A8, 0x62A6, 0x926D, + 0x62A7, 0x926E, 0x62A8, 0xC5EA, 0x62A9, 0x926F, 0x62AA, 0x9270, + 0x62AB, 0xC5FB, 0x62AC, 0xCCA7, 0x62AD, 0x9271, 0x62AE, 0x9272, + 0x62AF, 0x9273, 0x62B0, 0x9274, 0x62B1, 0xB1A7, 0x62B2, 0x9275, + 0x62B3, 0x9276, 0x62B4, 0x9277, 0x62B5, 0xB5D6, 0x62B6, 0x9278, + 0x62B7, 0x9279, 0x62B8, 0x927A, 0x62B9, 0xC4A8, 0x62BA, 0x927B, + 0x62BB, 0xDED3, 0x62BC, 0xD1BA, 0x62BD, 0xB3E9, 0x62BE, 0x927C, + 0x62BF, 0xC3F2, 0x62C0, 0x927D, 0x62C1, 0x927E, 0x62C2, 0xB7F7, + 0x62C3, 0x9280, 0x62C4, 0xD6F4, 0x62C5, 0xB5A3, 0x62C6, 0xB2F0, + 0x62C7, 0xC4B4, 0x62C8, 0xC4E9, 0x62C9, 0xC0AD, 0x62CA, 0xDED4, + 0x62CB, 0x9281, 0x62CC, 0xB0E8, 0x62CD, 0xC5C4, 0x62CE, 0xC1E0, + 0x62CF, 0x9282, 0x62D0, 0xB9D5, 0x62D1, 0x9283, 0x62D2, 0xBEDC, + 0x62D3, 0xCDD8, 0x62D4, 0xB0CE, 0x62D5, 0x9284, 0x62D6, 0xCDCF, + 0x62D7, 0xDED6, 0x62D8, 0xBED0, 0x62D9, 0xD7BE, 0x62DA, 0xDED5, + 0x62DB, 0xD5D0, 0x62DC, 0xB0DD, 0x62DD, 0x9285, 0x62DE, 0x9286, + 0x62DF, 0xC4E2, 0x62E0, 0x9287, 0x62E1, 0x9288, 0x62E2, 0xC2A3, + 0x62E3, 0xBCF0, 0x62E4, 0x9289, 0x62E5, 0xD3B5, 0x62E6, 0xC0B9, + 0x62E7, 0xC5A1, 0x62E8, 0xB2A6, 0x62E9, 0xD4F1, 0x62EA, 0x928A, + 0x62EB, 0x928B, 0x62EC, 0xC0A8, 0x62ED, 0xCAC3, 0x62EE, 0xDED7, + 0x62EF, 0xD5FC, 0x62F0, 0x928C, 0x62F1, 0xB9B0, 0x62F2, 0x928D, + 0x62F3, 0xC8AD, 0x62F4, 0xCBA9, 0x62F5, 0x928E, 0x62F6, 0xDED9, + 0x62F7, 0xBFBD, 0x62F8, 0x928F, 0x62F9, 0x9290, 0x62FA, 0x9291, + 0x62FB, 0x9292, 0x62FC, 0xC6B4, 0x62FD, 0xD7A7, 0x62FE, 0xCAB0, + 0x62FF, 0xC4C3, 0x6300, 0x9293, 0x6301, 0xB3D6, 0x6302, 0xB9D2, + 0x6303, 0x9294, 0x6304, 0x9295, 0x6305, 0x9296, 0x6306, 0x9297, + 0x6307, 0xD6B8, 0x6308, 0xEAFC, 0x6309, 0xB0B4, 0x630A, 0x9298, + 0x630B, 0x9299, 0x630C, 0x929A, 0x630D, 0x929B, 0x630E, 0xBFE6, + 0x630F, 0x929C, 0x6310, 0x929D, 0x6311, 0xCCF4, 0x6312, 0x929E, + 0x6313, 0x929F, 0x6314, 0x92A0, 0x6315, 0x92A1, 0x6316, 0xCDDA, + 0x6317, 0x92A2, 0x6318, 0x92A3, 0x6319, 0x92A4, 0x631A, 0xD6BF, + 0x631B, 0xC2CE, 0x631C, 0x92A5, 0x631D, 0xCECE, 0x631E, 0xCCA2, + 0x631F, 0xD0AE, 0x6320, 0xC4D3, 0x6321, 0xB5B2, 0x6322, 0xDED8, + 0x6323, 0xD5F5, 0x6324, 0xBCB7, 0x6325, 0xBBD3, 0x6326, 0x92A6, + 0x6327, 0x92A7, 0x6328, 0xB0A4, 0x6329, 0x92A8, 0x632A, 0xC5B2, + 0x632B, 0xB4EC, 0x632C, 0x92A9, 0x632D, 0x92AA, 0x632E, 0x92AB, + 0x632F, 0xD5F1, 0x6330, 0x92AC, 0x6331, 0x92AD, 0x6332, 0xEAFD, + 0x6333, 0x92AE, 0x6334, 0x92AF, 0x6335, 0x92B0, 0x6336, 0x92B1, + 0x6337, 0x92B2, 0x6338, 0x92B3, 0x6339, 0xDEDA, 0x633A, 0xCDA6, + 0x633B, 0x92B4, 0x633C, 0x92B5, 0x633D, 0xCDEC, 0x633E, 0x92B6, + 0x633F, 0x92B7, 0x6340, 0x92B8, 0x6341, 0x92B9, 0x6342, 0xCEE6, + 0x6343, 0xDEDC, 0x6344, 0x92BA, 0x6345, 0xCDB1, 0x6346, 0xC0A6, + 0x6347, 0x92BB, 0x6348, 0x92BC, 0x6349, 0xD7BD, 0x634A, 0x92BD, + 0x634B, 0xDEDB, 0x634C, 0xB0C6, 0x634D, 0xBAB4, 0x634E, 0xC9D3, + 0x634F, 0xC4F3, 0x6350, 0xBEE8, 0x6351, 0x92BE, 0x6352, 0x92BF, + 0x6353, 0x92C0, 0x6354, 0x92C1, 0x6355, 0xB2B6, 0x6356, 0x92C2, + 0x6357, 0x92C3, 0x6358, 0x92C4, 0x6359, 0x92C5, 0x635A, 0x92C6, + 0x635B, 0x92C7, 0x635C, 0x92C8, 0x635D, 0x92C9, 0x635E, 0xC0CC, + 0x635F, 0xCBF0, 0x6360, 0x92CA, 0x6361, 0xBCF1, 0x6362, 0xBBBB, + 0x6363, 0xB5B7, 0x6364, 0x92CB, 0x6365, 0x92CC, 0x6366, 0x92CD, + 0x6367, 0xC5F5, 0x6368, 0x92CE, 0x6369, 0xDEE6, 0x636A, 0x92CF, + 0x636B, 0x92D0, 0x636C, 0x92D1, 0x636D, 0xDEE3, 0x636E, 0xBEDD, + 0x636F, 0x92D2, 0x6370, 0x92D3, 0x6371, 0xDEDF, 0x6372, 0x92D4, + 0x6373, 0x92D5, 0x6374, 0x92D6, 0x6375, 0x92D7, 0x6376, 0xB4B7, + 0x6377, 0xBDDD, 0x6378, 0x92D8, 0x6379, 0x92D9, 0x637A, 0xDEE0, + 0x637B, 0xC4ED, 0x637C, 0x92DA, 0x637D, 0x92DB, 0x637E, 0x92DC, + 0x637F, 0x92DD, 0x6380, 0xCFC6, 0x6381, 0x92DE, 0x6382, 0xB5E0, + 0x6383, 0x92DF, 0x6384, 0x92E0, 0x6385, 0x92E1, 0x6386, 0x92E2, + 0x6387, 0xB6DE, 0x6388, 0xCADA, 0x6389, 0xB5F4, 0x638A, 0xDEE5, + 0x638B, 0x92E3, 0x638C, 0xD5C6, 0x638D, 0x92E4, 0x638E, 0xDEE1, + 0x638F, 0xCCCD, 0x6390, 0xC6FE, 0x6391, 0x92E5, 0x6392, 0xC5C5, + 0x6393, 0x92E6, 0x6394, 0x92E7, 0x6395, 0x92E8, 0x6396, 0xD2B4, + 0x6397, 0x92E9, 0x6398, 0xBEF2, 0x6399, 0x92EA, 0x639A, 0x92EB, + 0x639B, 0x92EC, 0x639C, 0x92ED, 0x639D, 0x92EE, 0x639E, 0x92EF, + 0x639F, 0x92F0, 0x63A0, 0xC2D3, 0x63A1, 0x92F1, 0x63A2, 0xCCBD, + 0x63A3, 0xB3B8, 0x63A4, 0x92F2, 0x63A5, 0xBDD3, 0x63A6, 0x92F3, + 0x63A7, 0xBFD8, 0x63A8, 0xCDC6, 0x63A9, 0xD1DA, 0x63AA, 0xB4EB, + 0x63AB, 0x92F4, 0x63AC, 0xDEE4, 0x63AD, 0xDEDD, 0x63AE, 0xDEE7, + 0x63AF, 0x92F5, 0x63B0, 0xEAFE, 0x63B1, 0x92F6, 0x63B2, 0x92F7, + 0x63B3, 0xC2B0, 0x63B4, 0xDEE2, 0x63B5, 0x92F8, 0x63B6, 0x92F9, + 0x63B7, 0xD6C0, 0x63B8, 0xB5A7, 0x63B9, 0x92FA, 0x63BA, 0xB2F4, + 0x63BB, 0x92FB, 0x63BC, 0xDEE8, 0x63BD, 0x92FC, 0x63BE, 0xDEF2, + 0x63BF, 0x92FD, 0x63C0, 0x92FE, 0x63C1, 0x9340, 0x63C2, 0x9341, + 0x63C3, 0x9342, 0x63C4, 0xDEED, 0x63C5, 0x9343, 0x63C6, 0xDEF1, + 0x63C7, 0x9344, 0x63C8, 0x9345, 0x63C9, 0xC8E0, 0x63CA, 0x9346, + 0x63CB, 0x9347, 0x63CC, 0x9348, 0x63CD, 0xD7E1, 0x63CE, 0xDEEF, + 0x63CF, 0xC3E8, 0x63D0, 0xCCE1, 0x63D1, 0x9349, 0x63D2, 0xB2E5, + 0x63D3, 0x934A, 0x63D4, 0x934B, 0x63D5, 0x934C, 0x63D6, 0xD2BE, + 0x63D7, 0x934D, 0x63D8, 0x934E, 0x63D9, 0x934F, 0x63DA, 0x9350, + 0x63DB, 0x9351, 0x63DC, 0x9352, 0x63DD, 0x9353, 0x63DE, 0xDEEE, + 0x63DF, 0x9354, 0x63E0, 0xDEEB, 0x63E1, 0xCED5, 0x63E2, 0x9355, + 0x63E3, 0xB4A7, 0x63E4, 0x9356, 0x63E5, 0x9357, 0x63E6, 0x9358, + 0x63E7, 0x9359, 0x63E8, 0x935A, 0x63E9, 0xBFAB, 0x63EA, 0xBEBE, + 0x63EB, 0x935B, 0x63EC, 0x935C, 0x63ED, 0xBDD2, 0x63EE, 0x935D, + 0x63EF, 0x935E, 0x63F0, 0x935F, 0x63F1, 0x9360, 0x63F2, 0xDEE9, + 0x63F3, 0x9361, 0x63F4, 0xD4AE, 0x63F5, 0x9362, 0x63F6, 0xDEDE, + 0x63F7, 0x9363, 0x63F8, 0xDEEA, 0x63F9, 0x9364, 0x63FA, 0x9365, + 0x63FB, 0x9366, 0x63FC, 0x9367, 0x63FD, 0xC0BF, 0x63FE, 0x9368, + 0x63FF, 0xDEEC, 0x6400, 0xB2F3, 0x6401, 0xB8E9, 0x6402, 0xC2A7, + 0x6403, 0x9369, 0x6404, 0x936A, 0x6405, 0xBDC1, 0x6406, 0x936B, + 0x6407, 0x936C, 0x6408, 0x936D, 0x6409, 0x936E, 0x640A, 0x936F, + 0x640B, 0xDEF5, 0x640C, 0xDEF8, 0x640D, 0x9370, 0x640E, 0x9371, + 0x640F, 0xB2AB, 0x6410, 0xB4A4, 0x6411, 0x9372, 0x6412, 0x9373, + 0x6413, 0xB4EA, 0x6414, 0xC9A6, 0x6415, 0x9374, 0x6416, 0x9375, + 0x6417, 0x9376, 0x6418, 0x9377, 0x6419, 0x9378, 0x641A, 0x9379, + 0x641B, 0xDEF6, 0x641C, 0xCBD1, 0x641D, 0x937A, 0x641E, 0xB8E3, + 0x641F, 0x937B, 0x6420, 0xDEF7, 0x6421, 0xDEFA, 0x6422, 0x937C, + 0x6423, 0x937D, 0x6424, 0x937E, 0x6425, 0x9380, 0x6426, 0xDEF9, + 0x6427, 0x9381, 0x6428, 0x9382, 0x6429, 0x9383, 0x642A, 0xCCC2, + 0x642B, 0x9384, 0x642C, 0xB0E1, 0x642D, 0xB4EE, 0x642E, 0x9385, + 0x642F, 0x9386, 0x6430, 0x9387, 0x6431, 0x9388, 0x6432, 0x9389, + 0x6433, 0x938A, 0x6434, 0xE5BA, 0x6435, 0x938B, 0x6436, 0x938C, + 0x6437, 0x938D, 0x6438, 0x938E, 0x6439, 0x938F, 0x643A, 0xD0AF, + 0x643B, 0x9390, 0x643C, 0x9391, 0x643D, 0xB2EB, 0x643E, 0x9392, + 0x643F, 0xEBA1, 0x6440, 0x9393, 0x6441, 0xDEF4, 0x6442, 0x9394, + 0x6443, 0x9395, 0x6444, 0xC9E3, 0x6445, 0xDEF3, 0x6446, 0xB0DA, + 0x6447, 0xD2A1, 0x6448, 0xB1F7, 0x6449, 0x9396, 0x644A, 0xCCAF, + 0x644B, 0x9397, 0x644C, 0x9398, 0x644D, 0x9399, 0x644E, 0x939A, + 0x644F, 0x939B, 0x6450, 0x939C, 0x6451, 0x939D, 0x6452, 0xDEF0, + 0x6453, 0x939E, 0x6454, 0xCBA4, 0x6455, 0x939F, 0x6456, 0x93A0, + 0x6457, 0x93A1, 0x6458, 0xD5AA, 0x6459, 0x93A2, 0x645A, 0x93A3, + 0x645B, 0x93A4, 0x645C, 0x93A5, 0x645D, 0x93A6, 0x645E, 0xDEFB, + 0x645F, 0x93A7, 0x6460, 0x93A8, 0x6461, 0x93A9, 0x6462, 0x93AA, + 0x6463, 0x93AB, 0x6464, 0x93AC, 0x6465, 0x93AD, 0x6466, 0x93AE, + 0x6467, 0xB4DD, 0x6468, 0x93AF, 0x6469, 0xC4A6, 0x646A, 0x93B0, + 0x646B, 0x93B1, 0x646C, 0x93B2, 0x646D, 0xDEFD, 0x646E, 0x93B3, + 0x646F, 0x93B4, 0x6470, 0x93B5, 0x6471, 0x93B6, 0x6472, 0x93B7, + 0x6473, 0x93B8, 0x6474, 0x93B9, 0x6475, 0x93BA, 0x6476, 0x93BB, + 0x6477, 0x93BC, 0x6478, 0xC3FE, 0x6479, 0xC4A1, 0x647A, 0xDFA1, + 0x647B, 0x93BD, 0x647C, 0x93BE, 0x647D, 0x93BF, 0x647E, 0x93C0, + 0x647F, 0x93C1, 0x6480, 0x93C2, 0x6481, 0x93C3, 0x6482, 0xC1CC, + 0x6483, 0x93C4, 0x6484, 0xDEFC, 0x6485, 0xBEEF, 0x6486, 0x93C5, + 0x6487, 0xC6B2, 0x6488, 0x93C6, 0x6489, 0x93C7, 0x648A, 0x93C8, + 0x648B, 0x93C9, 0x648C, 0x93CA, 0x648D, 0x93CB, 0x648E, 0x93CC, + 0x648F, 0x93CD, 0x6490, 0x93CE, 0x6491, 0xB3C5, 0x6492, 0xC8F6, + 0x6493, 0x93CF, 0x6494, 0x93D0, 0x6495, 0xCBBA, 0x6496, 0xDEFE, + 0x6497, 0x93D1, 0x6498, 0x93D2, 0x6499, 0xDFA4, 0x649A, 0x93D3, + 0x649B, 0x93D4, 0x649C, 0x93D5, 0x649D, 0x93D6, 0x649E, 0xD7B2, + 0x649F, 0x93D7, 0x64A0, 0x93D8, 0x64A1, 0x93D9, 0x64A2, 0x93DA, + 0x64A3, 0x93DB, 0x64A4, 0xB3B7, 0x64A5, 0x93DC, 0x64A6, 0x93DD, + 0x64A7, 0x93DE, 0x64A8, 0x93DF, 0x64A9, 0xC1C3, 0x64AA, 0x93E0, + 0x64AB, 0x93E1, 0x64AC, 0xC7CB, 0x64AD, 0xB2A5, 0x64AE, 0xB4E9, + 0x64AF, 0x93E2, 0x64B0, 0xD7AB, 0x64B1, 0x93E3, 0x64B2, 0x93E4, + 0x64B3, 0x93E5, 0x64B4, 0x93E6, 0x64B5, 0xC4EC, 0x64B6, 0x93E7, + 0x64B7, 0xDFA2, 0x64B8, 0xDFA3, 0x64B9, 0x93E8, 0x64BA, 0xDFA5, + 0x64BB, 0x93E9, 0x64BC, 0xBAB3, 0x64BD, 0x93EA, 0x64BE, 0x93EB, + 0x64BF, 0x93EC, 0x64C0, 0xDFA6, 0x64C1, 0x93ED, 0x64C2, 0xC0DE, + 0x64C3, 0x93EE, 0x64C4, 0x93EF, 0x64C5, 0xC9C3, 0x64C6, 0x93F0, + 0x64C7, 0x93F1, 0x64C8, 0x93F2, 0x64C9, 0x93F3, 0x64CA, 0x93F4, + 0x64CB, 0x93F5, 0x64CC, 0x93F6, 0x64CD, 0xB2D9, 0x64CE, 0xC7E6, + 0x64CF, 0x93F7, 0x64D0, 0xDFA7, 0x64D1, 0x93F8, 0x64D2, 0xC7DC, + 0x64D3, 0x93F9, 0x64D4, 0x93FA, 0x64D5, 0x93FB, 0x64D6, 0x93FC, + 0x64D7, 0xDFA8, 0x64D8, 0xEBA2, 0x64D9, 0x93FD, 0x64DA, 0x93FE, + 0x64DB, 0x9440, 0x64DC, 0x9441, 0x64DD, 0x9442, 0x64DE, 0xCBD3, + 0x64DF, 0x9443, 0x64E0, 0x9444, 0x64E1, 0x9445, 0x64E2, 0xDFAA, + 0x64E3, 0x9446, 0x64E4, 0xDFA9, 0x64E5, 0x9447, 0x64E6, 0xB2C1, + 0x64E7, 0x9448, 0x64E8, 0x9449, 0x64E9, 0x944A, 0x64EA, 0x944B, + 0x64EB, 0x944C, 0x64EC, 0x944D, 0x64ED, 0x944E, 0x64EE, 0x944F, + 0x64EF, 0x9450, 0x64F0, 0x9451, 0x64F1, 0x9452, 0x64F2, 0x9453, + 0x64F3, 0x9454, 0x64F4, 0x9455, 0x64F5, 0x9456, 0x64F6, 0x9457, + 0x64F7, 0x9458, 0x64F8, 0x9459, 0x64F9, 0x945A, 0x64FA, 0x945B, + 0x64FB, 0x945C, 0x64FC, 0x945D, 0x64FD, 0x945E, 0x64FE, 0x945F, + 0x64FF, 0x9460, 0x6500, 0xC5CA, 0x6501, 0x9461, 0x6502, 0x9462, + 0x6503, 0x9463, 0x6504, 0x9464, 0x6505, 0x9465, 0x6506, 0x9466, + 0x6507, 0x9467, 0x6508, 0x9468, 0x6509, 0xDFAB, 0x650A, 0x9469, + 0x650B, 0x946A, 0x650C, 0x946B, 0x650D, 0x946C, 0x650E, 0x946D, + 0x650F, 0x946E, 0x6510, 0x946F, 0x6511, 0x9470, 0x6512, 0xD4DC, + 0x6513, 0x9471, 0x6514, 0x9472, 0x6515, 0x9473, 0x6516, 0x9474, + 0x6517, 0x9475, 0x6518, 0xC8C1, 0x6519, 0x9476, 0x651A, 0x9477, + 0x651B, 0x9478, 0x651C, 0x9479, 0x651D, 0x947A, 0x651E, 0x947B, + 0x651F, 0x947C, 0x6520, 0x947D, 0x6521, 0x947E, 0x6522, 0x9480, + 0x6523, 0x9481, 0x6524, 0x9482, 0x6525, 0xDFAC, 0x6526, 0x9483, + 0x6527, 0x9484, 0x6528, 0x9485, 0x6529, 0x9486, 0x652A, 0x9487, + 0x652B, 0xBEF0, 0x652C, 0x9488, 0x652D, 0x9489, 0x652E, 0xDFAD, + 0x652F, 0xD6A7, 0x6530, 0x948A, 0x6531, 0x948B, 0x6532, 0x948C, + 0x6533, 0x948D, 0x6534, 0xEAB7, 0x6535, 0xEBB6, 0x6536, 0xCAD5, + 0x6537, 0x948E, 0x6538, 0xD8FC, 0x6539, 0xB8C4, 0x653A, 0x948F, + 0x653B, 0xB9A5, 0x653C, 0x9490, 0x653D, 0x9491, 0x653E, 0xB7C5, + 0x653F, 0xD5FE, 0x6540, 0x9492, 0x6541, 0x9493, 0x6542, 0x9494, + 0x6543, 0x9495, 0x6544, 0x9496, 0x6545, 0xB9CA, 0x6546, 0x9497, + 0x6547, 0x9498, 0x6548, 0xD0A7, 0x6549, 0xF4CD, 0x654A, 0x9499, + 0x654B, 0x949A, 0x654C, 0xB5D0, 0x654D, 0x949B, 0x654E, 0x949C, + 0x654F, 0xC3F4, 0x6550, 0x949D, 0x6551, 0xBEC8, 0x6552, 0x949E, + 0x6553, 0x949F, 0x6554, 0x94A0, 0x6555, 0xEBB7, 0x6556, 0xB0BD, + 0x6557, 0x94A1, 0x6558, 0x94A2, 0x6559, 0xBDCC, 0x655A, 0x94A3, + 0x655B, 0xC1B2, 0x655C, 0x94A4, 0x655D, 0xB1D6, 0x655E, 0xB3A8, + 0x655F, 0x94A5, 0x6560, 0x94A6, 0x6561, 0x94A7, 0x6562, 0xB8D2, + 0x6563, 0xC9A2, 0x6564, 0x94A8, 0x6565, 0x94A9, 0x6566, 0xB6D8, + 0x6567, 0x94AA, 0x6568, 0x94AB, 0x6569, 0x94AC, 0x656A, 0x94AD, + 0x656B, 0xEBB8, 0x656C, 0xBEB4, 0x656D, 0x94AE, 0x656E, 0x94AF, + 0x656F, 0x94B0, 0x6570, 0xCAFD, 0x6571, 0x94B1, 0x6572, 0xC7C3, + 0x6573, 0x94B2, 0x6574, 0xD5FB, 0x6575, 0x94B3, 0x6576, 0x94B4, + 0x6577, 0xB7F3, 0x6578, 0x94B5, 0x6579, 0x94B6, 0x657A, 0x94B7, + 0x657B, 0x94B8, 0x657C, 0x94B9, 0x657D, 0x94BA, 0x657E, 0x94BB, + 0x657F, 0x94BC, 0x6580, 0x94BD, 0x6581, 0x94BE, 0x6582, 0x94BF, + 0x6583, 0x94C0, 0x6584, 0x94C1, 0x6585, 0x94C2, 0x6586, 0x94C3, + 0x6587, 0xCEC4, 0x6588, 0x94C4, 0x6589, 0x94C5, 0x658A, 0x94C6, + 0x658B, 0xD5AB, 0x658C, 0xB1F3, 0x658D, 0x94C7, 0x658E, 0x94C8, + 0x658F, 0x94C9, 0x6590, 0xECB3, 0x6591, 0xB0DF, 0x6592, 0x94CA, + 0x6593, 0xECB5, 0x6594, 0x94CB, 0x6595, 0x94CC, 0x6596, 0x94CD, + 0x6597, 0xB6B7, 0x6598, 0x94CE, 0x6599, 0xC1CF, 0x659A, 0x94CF, + 0x659B, 0xF5FA, 0x659C, 0xD0B1, 0x659D, 0x94D0, 0x659E, 0x94D1, + 0x659F, 0xD5E5, 0x65A0, 0x94D2, 0x65A1, 0xCED3, 0x65A2, 0x94D3, + 0x65A3, 0x94D4, 0x65A4, 0xBDEF, 0x65A5, 0xB3E2, 0x65A6, 0x94D5, + 0x65A7, 0xB8AB, 0x65A8, 0x94D6, 0x65A9, 0xD5B6, 0x65AA, 0x94D7, + 0x65AB, 0xEDBD, 0x65AC, 0x94D8, 0x65AD, 0xB6CF, 0x65AE, 0x94D9, + 0x65AF, 0xCBB9, 0x65B0, 0xD0C2, 0x65B1, 0x94DA, 0x65B2, 0x94DB, + 0x65B3, 0x94DC, 0x65B4, 0x94DD, 0x65B5, 0x94DE, 0x65B6, 0x94DF, + 0x65B7, 0x94E0, 0x65B8, 0x94E1, 0x65B9, 0xB7BD, 0x65BA, 0x94E2, + 0x65BB, 0x94E3, 0x65BC, 0xECB6, 0x65BD, 0xCAA9, 0x65BE, 0x94E4, + 0x65BF, 0x94E5, 0x65C0, 0x94E6, 0x65C1, 0xC5D4, 0x65C2, 0x94E7, + 0x65C3, 0xECB9, 0x65C4, 0xECB8, 0x65C5, 0xC2C3, 0x65C6, 0xECB7, + 0x65C7, 0x94E8, 0x65C8, 0x94E9, 0x65C9, 0x94EA, 0x65CA, 0x94EB, + 0x65CB, 0xD0FD, 0x65CC, 0xECBA, 0x65CD, 0x94EC, 0x65CE, 0xECBB, + 0x65CF, 0xD7E5, 0x65D0, 0x94ED, 0x65D1, 0x94EE, 0x65D2, 0xECBC, + 0x65D3, 0x94EF, 0x65D4, 0x94F0, 0x65D5, 0x94F1, 0x65D6, 0xECBD, + 0x65D7, 0xC6EC, 0x65D8, 0x94F2, 0x65D9, 0x94F3, 0x65DA, 0x94F4, + 0x65DB, 0x94F5, 0x65DC, 0x94F6, 0x65DD, 0x94F7, 0x65DE, 0x94F8, + 0x65DF, 0x94F9, 0x65E0, 0xCEDE, 0x65E1, 0x94FA, 0x65E2, 0xBCC8, + 0x65E3, 0x94FB, 0x65E4, 0x94FC, 0x65E5, 0xC8D5, 0x65E6, 0xB5A9, + 0x65E7, 0xBEC9, 0x65E8, 0xD6BC, 0x65E9, 0xD4E7, 0x65EA, 0x94FD, + 0x65EB, 0x94FE, 0x65EC, 0xD1AE, 0x65ED, 0xD0F1, 0x65EE, 0xEAB8, + 0x65EF, 0xEAB9, 0x65F0, 0xEABA, 0x65F1, 0xBAB5, 0x65F2, 0x9540, + 0x65F3, 0x9541, 0x65F4, 0x9542, 0x65F5, 0x9543, 0x65F6, 0xCAB1, + 0x65F7, 0xBFF5, 0x65F8, 0x9544, 0x65F9, 0x9545, 0x65FA, 0xCDFA, + 0x65FB, 0x9546, 0x65FC, 0x9547, 0x65FD, 0x9548, 0x65FE, 0x9549, + 0x65FF, 0x954A, 0x6600, 0xEAC0, 0x6601, 0x954B, 0x6602, 0xB0BA, + 0x6603, 0xEABE, 0x6604, 0x954C, 0x6605, 0x954D, 0x6606, 0xC0A5, + 0x6607, 0x954E, 0x6608, 0x954F, 0x6609, 0x9550, 0x660A, 0xEABB, + 0x660B, 0x9551, 0x660C, 0xB2FD, 0x660D, 0x9552, 0x660E, 0xC3F7, + 0x660F, 0xBBE8, 0x6610, 0x9553, 0x6611, 0x9554, 0x6612, 0x9555, + 0x6613, 0xD2D7, 0x6614, 0xCEF4, 0x6615, 0xEABF, 0x6616, 0x9556, + 0x6617, 0x9557, 0x6618, 0x9558, 0x6619, 0xEABC, 0x661A, 0x9559, + 0x661B, 0x955A, 0x661C, 0x955B, 0x661D, 0xEAC3, 0x661E, 0x955C, + 0x661F, 0xD0C7, 0x6620, 0xD3B3, 0x6621, 0x955D, 0x6622, 0x955E, + 0x6623, 0x955F, 0x6624, 0x9560, 0x6625, 0xB4BA, 0x6626, 0x9561, + 0x6627, 0xC3C1, 0x6628, 0xD7F2, 0x6629, 0x9562, 0x662A, 0x9563, + 0x662B, 0x9564, 0x662C, 0x9565, 0x662D, 0xD5D1, 0x662E, 0x9566, + 0x662F, 0xCAC7, 0x6630, 0x9567, 0x6631, 0xEAC5, 0x6632, 0x9568, + 0x6633, 0x9569, 0x6634, 0xEAC4, 0x6635, 0xEAC7, 0x6636, 0xEAC6, + 0x6637, 0x956A, 0x6638, 0x956B, 0x6639, 0x956C, 0x663A, 0x956D, + 0x663B, 0x956E, 0x663C, 0xD6E7, 0x663D, 0x956F, 0x663E, 0xCFD4, + 0x663F, 0x9570, 0x6640, 0x9571, 0x6641, 0xEACB, 0x6642, 0x9572, + 0x6643, 0xBBCE, 0x6644, 0x9573, 0x6645, 0x9574, 0x6646, 0x9575, + 0x6647, 0x9576, 0x6648, 0x9577, 0x6649, 0x9578, 0x664A, 0x9579, + 0x664B, 0xBDFA, 0x664C, 0xC9CE, 0x664D, 0x957A, 0x664E, 0x957B, + 0x664F, 0xEACC, 0x6650, 0x957C, 0x6651, 0x957D, 0x6652, 0xC9B9, + 0x6653, 0xCFFE, 0x6654, 0xEACA, 0x6655, 0xD4CE, 0x6656, 0xEACD, + 0x6657, 0xEACF, 0x6658, 0x957E, 0x6659, 0x9580, 0x665A, 0xCDED, + 0x665B, 0x9581, 0x665C, 0x9582, 0x665D, 0x9583, 0x665E, 0x9584, + 0x665F, 0xEAC9, 0x6660, 0x9585, 0x6661, 0xEACE, 0x6662, 0x9586, + 0x6663, 0x9587, 0x6664, 0xCEEE, 0x6665, 0x9588, 0x6666, 0xBBDE, + 0x6667, 0x9589, 0x6668, 0xB3BF, 0x6669, 0x958A, 0x666A, 0x958B, + 0x666B, 0x958C, 0x666C, 0x958D, 0x666D, 0x958E, 0x666E, 0xC6D5, + 0x666F, 0xBEB0, 0x6670, 0xCEFA, 0x6671, 0x958F, 0x6672, 0x9590, + 0x6673, 0x9591, 0x6674, 0xC7E7, 0x6675, 0x9592, 0x6676, 0xBEA7, + 0x6677, 0xEAD0, 0x6678, 0x9593, 0x6679, 0x9594, 0x667A, 0xD6C7, + 0x667B, 0x9595, 0x667C, 0x9596, 0x667D, 0x9597, 0x667E, 0xC1C0, + 0x667F, 0x9598, 0x6680, 0x9599, 0x6681, 0x959A, 0x6682, 0xD4DD, + 0x6683, 0x959B, 0x6684, 0xEAD1, 0x6685, 0x959C, 0x6686, 0x959D, + 0x6687, 0xCFBE, 0x6688, 0x959E, 0x6689, 0x959F, 0x668A, 0x95A0, + 0x668B, 0x95A1, 0x668C, 0xEAD2, 0x668D, 0x95A2, 0x668E, 0x95A3, + 0x668F, 0x95A4, 0x6690, 0x95A5, 0x6691, 0xCAEE, 0x6692, 0x95A6, + 0x6693, 0x95A7, 0x6694, 0x95A8, 0x6695, 0x95A9, 0x6696, 0xC5AF, + 0x6697, 0xB0B5, 0x6698, 0x95AA, 0x6699, 0x95AB, 0x669A, 0x95AC, + 0x669B, 0x95AD, 0x669C, 0x95AE, 0x669D, 0xEAD4, 0x669E, 0x95AF, + 0x669F, 0x95B0, 0x66A0, 0x95B1, 0x66A1, 0x95B2, 0x66A2, 0x95B3, + 0x66A3, 0x95B4, 0x66A4, 0x95B5, 0x66A5, 0x95B6, 0x66A6, 0x95B7, + 0x66A7, 0xEAD3, 0x66A8, 0xF4DF, 0x66A9, 0x95B8, 0x66AA, 0x95B9, + 0x66AB, 0x95BA, 0x66AC, 0x95BB, 0x66AD, 0x95BC, 0x66AE, 0xC4BA, + 0x66AF, 0x95BD, 0x66B0, 0x95BE, 0x66B1, 0x95BF, 0x66B2, 0x95C0, + 0x66B3, 0x95C1, 0x66B4, 0xB1A9, 0x66B5, 0x95C2, 0x66B6, 0x95C3, + 0x66B7, 0x95C4, 0x66B8, 0x95C5, 0x66B9, 0xE5DF, 0x66BA, 0x95C6, + 0x66BB, 0x95C7, 0x66BC, 0x95C8, 0x66BD, 0x95C9, 0x66BE, 0xEAD5, + 0x66BF, 0x95CA, 0x66C0, 0x95CB, 0x66C1, 0x95CC, 0x66C2, 0x95CD, + 0x66C3, 0x95CE, 0x66C4, 0x95CF, 0x66C5, 0x95D0, 0x66C6, 0x95D1, + 0x66C7, 0x95D2, 0x66C8, 0x95D3, 0x66C9, 0x95D4, 0x66CA, 0x95D5, + 0x66CB, 0x95D6, 0x66CC, 0x95D7, 0x66CD, 0x95D8, 0x66CE, 0x95D9, + 0x66CF, 0x95DA, 0x66D0, 0x95DB, 0x66D1, 0x95DC, 0x66D2, 0x95DD, + 0x66D3, 0x95DE, 0x66D4, 0x95DF, 0x66D5, 0x95E0, 0x66D6, 0x95E1, + 0x66D7, 0x95E2, 0x66D8, 0x95E3, 0x66D9, 0xCAEF, 0x66DA, 0x95E4, + 0x66DB, 0xEAD6, 0x66DC, 0xEAD7, 0x66DD, 0xC6D8, 0x66DE, 0x95E5, + 0x66DF, 0x95E6, 0x66E0, 0x95E7, 0x66E1, 0x95E8, 0x66E2, 0x95E9, + 0x66E3, 0x95EA, 0x66E4, 0x95EB, 0x66E5, 0x95EC, 0x66E6, 0xEAD8, + 0x66E7, 0x95ED, 0x66E8, 0x95EE, 0x66E9, 0xEAD9, 0x66EA, 0x95EF, + 0x66EB, 0x95F0, 0x66EC, 0x95F1, 0x66ED, 0x95F2, 0x66EE, 0x95F3, + 0x66EF, 0x95F4, 0x66F0, 0xD4BB, 0x66F1, 0x95F5, 0x66F2, 0xC7FA, + 0x66F3, 0xD2B7, 0x66F4, 0xB8FC, 0x66F5, 0x95F6, 0x66F6, 0x95F7, + 0x66F7, 0xEAC2, 0x66F8, 0x95F8, 0x66F9, 0xB2DC, 0x66FA, 0x95F9, + 0x66FB, 0x95FA, 0x66FC, 0xC2FC, 0x66FD, 0x95FB, 0x66FE, 0xD4F8, + 0x66FF, 0xCCE6, 0x6700, 0xD7EE, 0x6701, 0x95FC, 0x6702, 0x95FD, + 0x6703, 0x95FE, 0x6704, 0x9640, 0x6705, 0x9641, 0x6706, 0x9642, + 0x6707, 0x9643, 0x6708, 0xD4C2, 0x6709, 0xD3D0, 0x670A, 0xEBC3, + 0x670B, 0xC5F3, 0x670C, 0x9644, 0x670D, 0xB7FE, 0x670E, 0x9645, + 0x670F, 0x9646, 0x6710, 0xEBD4, 0x6711, 0x9647, 0x6712, 0x9648, + 0x6713, 0x9649, 0x6714, 0xCBB7, 0x6715, 0xEBDE, 0x6716, 0x964A, + 0x6717, 0xC0CA, 0x6718, 0x964B, 0x6719, 0x964C, 0x671A, 0x964D, + 0x671B, 0xCDFB, 0x671C, 0x964E, 0x671D, 0xB3AF, 0x671E, 0x964F, + 0x671F, 0xC6DA, 0x6720, 0x9650, 0x6721, 0x9651, 0x6722, 0x9652, + 0x6723, 0x9653, 0x6724, 0x9654, 0x6725, 0x9655, 0x6726, 0xEBFC, + 0x6727, 0x9656, 0x6728, 0xC4BE, 0x6729, 0x9657, 0x672A, 0xCEB4, + 0x672B, 0xC4A9, 0x672C, 0xB1BE, 0x672D, 0xD4FD, 0x672E, 0x9658, + 0x672F, 0xCAF5, 0x6730, 0x9659, 0x6731, 0xD6EC, 0x6732, 0x965A, + 0x6733, 0x965B, 0x6734, 0xC6D3, 0x6735, 0xB6E4, 0x6736, 0x965C, + 0x6737, 0x965D, 0x6738, 0x965E, 0x6739, 0x965F, 0x673A, 0xBBFA, + 0x673B, 0x9660, 0x673C, 0x9661, 0x673D, 0xD0E0, 0x673E, 0x9662, + 0x673F, 0x9663, 0x6740, 0xC9B1, 0x6741, 0x9664, 0x6742, 0xD4D3, + 0x6743, 0xC8A8, 0x6744, 0x9665, 0x6745, 0x9666, 0x6746, 0xB8CB, + 0x6747, 0x9667, 0x6748, 0xE8BE, 0x6749, 0xC9BC, 0x674A, 0x9668, + 0x674B, 0x9669, 0x674C, 0xE8BB, 0x674D, 0x966A, 0x674E, 0xC0EE, + 0x674F, 0xD0D3, 0x6750, 0xB2C4, 0x6751, 0xB4E5, 0x6752, 0x966B, + 0x6753, 0xE8BC, 0x6754, 0x966C, 0x6755, 0x966D, 0x6756, 0xD5C8, + 0x6757, 0x966E, 0x6758, 0x966F, 0x6759, 0x9670, 0x675A, 0x9671, + 0x675B, 0x9672, 0x675C, 0xB6C5, 0x675D, 0x9673, 0x675E, 0xE8BD, + 0x675F, 0xCAF8, 0x6760, 0xB8DC, 0x6761, 0xCCF5, 0x6762, 0x9674, + 0x6763, 0x9675, 0x6764, 0x9676, 0x6765, 0xC0B4, 0x6766, 0x9677, + 0x6767, 0x9678, 0x6768, 0xD1EE, 0x6769, 0xE8BF, 0x676A, 0xE8C2, + 0x676B, 0x9679, 0x676C, 0x967A, 0x676D, 0xBABC, 0x676E, 0x967B, + 0x676F, 0xB1AD, 0x6770, 0xBDDC, 0x6771, 0x967C, 0x6772, 0xEABD, + 0x6773, 0xE8C3, 0x6774, 0x967D, 0x6775, 0xE8C6, 0x6776, 0x967E, + 0x6777, 0xE8CB, 0x6778, 0x9680, 0x6779, 0x9681, 0x677A, 0x9682, + 0x677B, 0x9683, 0x677C, 0xE8CC, 0x677D, 0x9684, 0x677E, 0xCBC9, + 0x677F, 0xB0E5, 0x6780, 0x9685, 0x6781, 0xBCAB, 0x6782, 0x9686, + 0x6783, 0x9687, 0x6784, 0xB9B9, 0x6785, 0x9688, 0x6786, 0x9689, + 0x6787, 0xE8C1, 0x6788, 0x968A, 0x6789, 0xCDF7, 0x678A, 0x968B, + 0x678B, 0xE8CA, 0x678C, 0x968C, 0x678D, 0x968D, 0x678E, 0x968E, + 0x678F, 0x968F, 0x6790, 0xCEF6, 0x6791, 0x9690, 0x6792, 0x9691, + 0x6793, 0x9692, 0x6794, 0x9693, 0x6795, 0xD5ED, 0x6796, 0x9694, + 0x6797, 0xC1D6, 0x6798, 0xE8C4, 0x6799, 0x9695, 0x679A, 0xC3B6, + 0x679B, 0x9696, 0x679C, 0xB9FB, 0x679D, 0xD6A6, 0x679E, 0xE8C8, + 0x679F, 0x9697, 0x67A0, 0x9698, 0x67A1, 0x9699, 0x67A2, 0xCAE0, + 0x67A3, 0xD4E6, 0x67A4, 0x969A, 0x67A5, 0xE8C0, 0x67A6, 0x969B, + 0x67A7, 0xE8C5, 0x67A8, 0xE8C7, 0x67A9, 0x969C, 0x67AA, 0xC7B9, + 0x67AB, 0xB7E3, 0x67AC, 0x969D, 0x67AD, 0xE8C9, 0x67AE, 0x969E, + 0x67AF, 0xBFDD, 0x67B0, 0xE8D2, 0x67B1, 0x969F, 0x67B2, 0x96A0, + 0x67B3, 0xE8D7, 0x67B4, 0x96A1, 0x67B5, 0xE8D5, 0x67B6, 0xBCDC, + 0x67B7, 0xBCCF, 0x67B8, 0xE8DB, 0x67B9, 0x96A2, 0x67BA, 0x96A3, + 0x67BB, 0x96A4, 0x67BC, 0x96A5, 0x67BD, 0x96A6, 0x67BE, 0x96A7, + 0x67BF, 0x96A8, 0x67C0, 0x96A9, 0x67C1, 0xE8DE, 0x67C2, 0x96AA, + 0x67C3, 0xE8DA, 0x67C4, 0xB1FA, 0x67C5, 0x96AB, 0x67C6, 0x96AC, + 0x67C7, 0x96AD, 0x67C8, 0x96AE, 0x67C9, 0x96AF, 0x67CA, 0x96B0, + 0x67CB, 0x96B1, 0x67CC, 0x96B2, 0x67CD, 0x96B3, 0x67CE, 0x96B4, + 0x67CF, 0xB0D8, 0x67D0, 0xC4B3, 0x67D1, 0xB8CC, 0x67D2, 0xC6E2, + 0x67D3, 0xC8BE, 0x67D4, 0xC8E1, 0x67D5, 0x96B5, 0x67D6, 0x96B6, + 0x67D7, 0x96B7, 0x67D8, 0xE8CF, 0x67D9, 0xE8D4, 0x67DA, 0xE8D6, + 0x67DB, 0x96B8, 0x67DC, 0xB9F1, 0x67DD, 0xE8D8, 0x67DE, 0xD7F5, + 0x67DF, 0x96B9, 0x67E0, 0xC4FB, 0x67E1, 0x96BA, 0x67E2, 0xE8DC, + 0x67E3, 0x96BB, 0x67E4, 0x96BC, 0x67E5, 0xB2E9, 0x67E6, 0x96BD, + 0x67E7, 0x96BE, 0x67E8, 0x96BF, 0x67E9, 0xE8D1, 0x67EA, 0x96C0, + 0x67EB, 0x96C1, 0x67EC, 0xBCED, 0x67ED, 0x96C2, 0x67EE, 0x96C3, + 0x67EF, 0xBFC2, 0x67F0, 0xE8CD, 0x67F1, 0xD6F9, 0x67F2, 0x96C4, + 0x67F3, 0xC1F8, 0x67F4, 0xB2F1, 0x67F5, 0x96C5, 0x67F6, 0x96C6, + 0x67F7, 0x96C7, 0x67F8, 0x96C8, 0x67F9, 0x96C9, 0x67FA, 0x96CA, + 0x67FB, 0x96CB, 0x67FC, 0x96CC, 0x67FD, 0xE8DF, 0x67FE, 0x96CD, + 0x67FF, 0xCAC1, 0x6800, 0xE8D9, 0x6801, 0x96CE, 0x6802, 0x96CF, + 0x6803, 0x96D0, 0x6804, 0x96D1, 0x6805, 0xD5A4, 0x6806, 0x96D2, + 0x6807, 0xB1EA, 0x6808, 0xD5BB, 0x6809, 0xE8CE, 0x680A, 0xE8D0, + 0x680B, 0xB6B0, 0x680C, 0xE8D3, 0x680D, 0x96D3, 0x680E, 0xE8DD, + 0x680F, 0xC0B8, 0x6810, 0x96D4, 0x6811, 0xCAF7, 0x6812, 0x96D5, + 0x6813, 0xCBA8, 0x6814, 0x96D6, 0x6815, 0x96D7, 0x6816, 0xC6DC, + 0x6817, 0xC0F5, 0x6818, 0x96D8, 0x6819, 0x96D9, 0x681A, 0x96DA, + 0x681B, 0x96DB, 0x681C, 0x96DC, 0x681D, 0xE8E9, 0x681E, 0x96DD, + 0x681F, 0x96DE, 0x6820, 0x96DF, 0x6821, 0xD0A3, 0x6822, 0x96E0, + 0x6823, 0x96E1, 0x6824, 0x96E2, 0x6825, 0x96E3, 0x6826, 0x96E4, + 0x6827, 0x96E5, 0x6828, 0x96E6, 0x6829, 0xE8F2, 0x682A, 0xD6EA, + 0x682B, 0x96E7, 0x682C, 0x96E8, 0x682D, 0x96E9, 0x682E, 0x96EA, + 0x682F, 0x96EB, 0x6830, 0x96EC, 0x6831, 0x96ED, 0x6832, 0xE8E0, + 0x6833, 0xE8E1, 0x6834, 0x96EE, 0x6835, 0x96EF, 0x6836, 0x96F0, + 0x6837, 0xD1F9, 0x6838, 0xBACB, 0x6839, 0xB8F9, 0x683A, 0x96F1, + 0x683B, 0x96F2, 0x683C, 0xB8F1, 0x683D, 0xD4D4, 0x683E, 0xE8EF, + 0x683F, 0x96F3, 0x6840, 0xE8EE, 0x6841, 0xE8EC, 0x6842, 0xB9F0, + 0x6843, 0xCCD2, 0x6844, 0xE8E6, 0x6845, 0xCEA6, 0x6846, 0xBFF2, + 0x6847, 0x96F4, 0x6848, 0xB0B8, 0x6849, 0xE8F1, 0x684A, 0xE8F0, + 0x684B, 0x96F5, 0x684C, 0xD7C0, 0x684D, 0x96F6, 0x684E, 0xE8E4, + 0x684F, 0x96F7, 0x6850, 0xCDA9, 0x6851, 0xC9A3, 0x6852, 0x96F8, + 0x6853, 0xBBB8, 0x6854, 0xBDDB, 0x6855, 0xE8EA, 0x6856, 0x96F9, + 0x6857, 0x96FA, 0x6858, 0x96FB, 0x6859, 0x96FC, 0x685A, 0x96FD, + 0x685B, 0x96FE, 0x685C, 0x9740, 0x685D, 0x9741, 0x685E, 0x9742, + 0x685F, 0x9743, 0x6860, 0xE8E2, 0x6861, 0xE8E3, 0x6862, 0xE8E5, + 0x6863, 0xB5B5, 0x6864, 0xE8E7, 0x6865, 0xC7C5, 0x6866, 0xE8EB, + 0x6867, 0xE8ED, 0x6868, 0xBDB0, 0x6869, 0xD7AE, 0x686A, 0x9744, + 0x686B, 0xE8F8, 0x686C, 0x9745, 0x686D, 0x9746, 0x686E, 0x9747, + 0x686F, 0x9748, 0x6870, 0x9749, 0x6871, 0x974A, 0x6872, 0x974B, + 0x6873, 0x974C, 0x6874, 0xE8F5, 0x6875, 0x974D, 0x6876, 0xCDB0, + 0x6877, 0xE8F6, 0x6878, 0x974E, 0x6879, 0x974F, 0x687A, 0x9750, + 0x687B, 0x9751, 0x687C, 0x9752, 0x687D, 0x9753, 0x687E, 0x9754, + 0x687F, 0x9755, 0x6880, 0x9756, 0x6881, 0xC1BA, 0x6882, 0x9757, + 0x6883, 0xE8E8, 0x6884, 0x9758, 0x6885, 0xC3B7, 0x6886, 0xB0F0, + 0x6887, 0x9759, 0x6888, 0x975A, 0x6889, 0x975B, 0x688A, 0x975C, + 0x688B, 0x975D, 0x688C, 0x975E, 0x688D, 0x975F, 0x688E, 0x9760, + 0x688F, 0xE8F4, 0x6890, 0x9761, 0x6891, 0x9762, 0x6892, 0x9763, + 0x6893, 0xE8F7, 0x6894, 0x9764, 0x6895, 0x9765, 0x6896, 0x9766, + 0x6897, 0xB9A3, 0x6898, 0x9767, 0x6899, 0x9768, 0x689A, 0x9769, + 0x689B, 0x976A, 0x689C, 0x976B, 0x689D, 0x976C, 0x689E, 0x976D, + 0x689F, 0x976E, 0x68A0, 0x976F, 0x68A1, 0x9770, 0x68A2, 0xC9D2, + 0x68A3, 0x9771, 0x68A4, 0x9772, 0x68A5, 0x9773, 0x68A6, 0xC3CE, + 0x68A7, 0xCEE0, 0x68A8, 0xC0E6, 0x68A9, 0x9774, 0x68AA, 0x9775, + 0x68AB, 0x9776, 0x68AC, 0x9777, 0x68AD, 0xCBF3, 0x68AE, 0x9778, + 0x68AF, 0xCCDD, 0x68B0, 0xD0B5, 0x68B1, 0x9779, 0x68B2, 0x977A, + 0x68B3, 0xCAE1, 0x68B4, 0x977B, 0x68B5, 0xE8F3, 0x68B6, 0x977C, + 0x68B7, 0x977D, 0x68B8, 0x977E, 0x68B9, 0x9780, 0x68BA, 0x9781, + 0x68BB, 0x9782, 0x68BC, 0x9783, 0x68BD, 0x9784, 0x68BE, 0x9785, + 0x68BF, 0x9786, 0x68C0, 0xBCEC, 0x68C1, 0x9787, 0x68C2, 0xE8F9, + 0x68C3, 0x9788, 0x68C4, 0x9789, 0x68C5, 0x978A, 0x68C6, 0x978B, + 0x68C7, 0x978C, 0x68C8, 0x978D, 0x68C9, 0xC3DE, 0x68CA, 0x978E, + 0x68CB, 0xC6E5, 0x68CC, 0x978F, 0x68CD, 0xB9F7, 0x68CE, 0x9790, + 0x68CF, 0x9791, 0x68D0, 0x9792, 0x68D1, 0x9793, 0x68D2, 0xB0F4, + 0x68D3, 0x9794, 0x68D4, 0x9795, 0x68D5, 0xD7D8, 0x68D6, 0x9796, + 0x68D7, 0x9797, 0x68D8, 0xBCAC, 0x68D9, 0x9798, 0x68DA, 0xC5EF, + 0x68DB, 0x9799, 0x68DC, 0x979A, 0x68DD, 0x979B, 0x68DE, 0x979C, + 0x68DF, 0x979D, 0x68E0, 0xCCC4, 0x68E1, 0x979E, 0x68E2, 0x979F, + 0x68E3, 0xE9A6, 0x68E4, 0x97A0, 0x68E5, 0x97A1, 0x68E6, 0x97A2, + 0x68E7, 0x97A3, 0x68E8, 0x97A4, 0x68E9, 0x97A5, 0x68EA, 0x97A6, + 0x68EB, 0x97A7, 0x68EC, 0x97A8, 0x68ED, 0x97A9, 0x68EE, 0xC9AD, + 0x68EF, 0x97AA, 0x68F0, 0xE9A2, 0x68F1, 0xC0E2, 0x68F2, 0x97AB, + 0x68F3, 0x97AC, 0x68F4, 0x97AD, 0x68F5, 0xBFC3, 0x68F6, 0x97AE, + 0x68F7, 0x97AF, 0x68F8, 0x97B0, 0x68F9, 0xE8FE, 0x68FA, 0xB9D7, + 0x68FB, 0x97B1, 0x68FC, 0xE8FB, 0x68FD, 0x97B2, 0x68FE, 0x97B3, + 0x68FF, 0x97B4, 0x6900, 0x97B5, 0x6901, 0xE9A4, 0x6902, 0x97B6, + 0x6903, 0x97B7, 0x6904, 0x97B8, 0x6905, 0xD2CE, 0x6906, 0x97B9, + 0x6907, 0x97BA, 0x6908, 0x97BB, 0x6909, 0x97BC, 0x690A, 0x97BD, + 0x690B, 0xE9A3, 0x690C, 0x97BE, 0x690D, 0xD6B2, 0x690E, 0xD7B5, + 0x690F, 0x97BF, 0x6910, 0xE9A7, 0x6911, 0x97C0, 0x6912, 0xBDB7, + 0x6913, 0x97C1, 0x6914, 0x97C2, 0x6915, 0x97C3, 0x6916, 0x97C4, + 0x6917, 0x97C5, 0x6918, 0x97C6, 0x6919, 0x97C7, 0x691A, 0x97C8, + 0x691B, 0x97C9, 0x691C, 0x97CA, 0x691D, 0x97CB, 0x691E, 0x97CC, + 0x691F, 0xE8FC, 0x6920, 0xE8FD, 0x6921, 0x97CD, 0x6922, 0x97CE, + 0x6923, 0x97CF, 0x6924, 0xE9A1, 0x6925, 0x97D0, 0x6926, 0x97D1, + 0x6927, 0x97D2, 0x6928, 0x97D3, 0x6929, 0x97D4, 0x692A, 0x97D5, + 0x692B, 0x97D6, 0x692C, 0x97D7, 0x692D, 0xCDD6, 0x692E, 0x97D8, + 0x692F, 0x97D9, 0x6930, 0xD2AC, 0x6931, 0x97DA, 0x6932, 0x97DB, + 0x6933, 0x97DC, 0x6934, 0xE9B2, 0x6935, 0x97DD, 0x6936, 0x97DE, + 0x6937, 0x97DF, 0x6938, 0x97E0, 0x6939, 0xE9A9, 0x693A, 0x97E1, + 0x693B, 0x97E2, 0x693C, 0x97E3, 0x693D, 0xB4AA, 0x693E, 0x97E4, + 0x693F, 0xB4BB, 0x6940, 0x97E5, 0x6941, 0x97E6, 0x6942, 0xE9AB, + 0x6943, 0x97E7, 0x6944, 0x97E8, 0x6945, 0x97E9, 0x6946, 0x97EA, + 0x6947, 0x97EB, 0x6948, 0x97EC, 0x6949, 0x97ED, 0x694A, 0x97EE, + 0x694B, 0x97EF, 0x694C, 0x97F0, 0x694D, 0x97F1, 0x694E, 0x97F2, + 0x694F, 0x97F3, 0x6950, 0x97F4, 0x6951, 0x97F5, 0x6952, 0x97F6, + 0x6953, 0x97F7, 0x6954, 0xD0A8, 0x6955, 0x97F8, 0x6956, 0x97F9, + 0x6957, 0xE9A5, 0x6958, 0x97FA, 0x6959, 0x97FB, 0x695A, 0xB3FE, + 0x695B, 0x97FC, 0x695C, 0x97FD, 0x695D, 0xE9AC, 0x695E, 0xC0E3, + 0x695F, 0x97FE, 0x6960, 0xE9AA, 0x6961, 0x9840, 0x6962, 0x9841, + 0x6963, 0xE9B9, 0x6964, 0x9842, 0x6965, 0x9843, 0x6966, 0xE9B8, + 0x6967, 0x9844, 0x6968, 0x9845, 0x6969, 0x9846, 0x696A, 0x9847, + 0x696B, 0xE9AE, 0x696C, 0x9848, 0x696D, 0x9849, 0x696E, 0xE8FA, + 0x696F, 0x984A, 0x6970, 0x984B, 0x6971, 0xE9A8, 0x6972, 0x984C, + 0x6973, 0x984D, 0x6974, 0x984E, 0x6975, 0x984F, 0x6976, 0x9850, + 0x6977, 0xBFAC, 0x6978, 0xE9B1, 0x6979, 0xE9BA, 0x697A, 0x9851, + 0x697B, 0x9852, 0x697C, 0xC2A5, 0x697D, 0x9853, 0x697E, 0x9854, + 0x697F, 0x9855, 0x6980, 0xE9AF, 0x6981, 0x9856, 0x6982, 0xB8C5, + 0x6983, 0x9857, 0x6984, 0xE9AD, 0x6985, 0x9858, 0x6986, 0xD3DC, + 0x6987, 0xE9B4, 0x6988, 0xE9B5, 0x6989, 0xE9B7, 0x698A, 0x9859, + 0x698B, 0x985A, 0x698C, 0x985B, 0x698D, 0xE9C7, 0x698E, 0x985C, + 0x698F, 0x985D, 0x6990, 0x985E, 0x6991, 0x985F, 0x6992, 0x9860, + 0x6993, 0x9861, 0x6994, 0xC0C6, 0x6995, 0xE9C5, 0x6996, 0x9862, + 0x6997, 0x9863, 0x6998, 0xE9B0, 0x6999, 0x9864, 0x699A, 0x9865, + 0x699B, 0xE9BB, 0x699C, 0xB0F1, 0x699D, 0x9866, 0x699E, 0x9867, + 0x699F, 0x9868, 0x69A0, 0x9869, 0x69A1, 0x986A, 0x69A2, 0x986B, + 0x69A3, 0x986C, 0x69A4, 0x986D, 0x69A5, 0x986E, 0x69A6, 0x986F, + 0x69A7, 0xE9BC, 0x69A8, 0xD5A5, 0x69A9, 0x9870, 0x69AA, 0x9871, + 0x69AB, 0xE9BE, 0x69AC, 0x9872, 0x69AD, 0xE9BF, 0x69AE, 0x9873, + 0x69AF, 0x9874, 0x69B0, 0x9875, 0x69B1, 0xE9C1, 0x69B2, 0x9876, + 0x69B3, 0x9877, 0x69B4, 0xC1F1, 0x69B5, 0x9878, 0x69B6, 0x9879, + 0x69B7, 0xC8B6, 0x69B8, 0x987A, 0x69B9, 0x987B, 0x69BA, 0x987C, + 0x69BB, 0xE9BD, 0x69BC, 0x987D, 0x69BD, 0x987E, 0x69BE, 0x9880, + 0x69BF, 0x9881, 0x69C0, 0x9882, 0x69C1, 0xE9C2, 0x69C2, 0x9883, + 0x69C3, 0x9884, 0x69C4, 0x9885, 0x69C5, 0x9886, 0x69C6, 0x9887, + 0x69C7, 0x9888, 0x69C8, 0x9889, 0x69C9, 0x988A, 0x69CA, 0xE9C3, + 0x69CB, 0x988B, 0x69CC, 0xE9B3, 0x69CD, 0x988C, 0x69CE, 0xE9B6, + 0x69CF, 0x988D, 0x69D0, 0xBBB1, 0x69D1, 0x988E, 0x69D2, 0x988F, + 0x69D3, 0x9890, 0x69D4, 0xE9C0, 0x69D5, 0x9891, 0x69D6, 0x9892, + 0x69D7, 0x9893, 0x69D8, 0x9894, 0x69D9, 0x9895, 0x69DA, 0x9896, + 0x69DB, 0xBCF7, 0x69DC, 0x9897, 0x69DD, 0x9898, 0x69DE, 0x9899, + 0x69DF, 0xE9C4, 0x69E0, 0xE9C6, 0x69E1, 0x989A, 0x69E2, 0x989B, + 0x69E3, 0x989C, 0x69E4, 0x989D, 0x69E5, 0x989E, 0x69E6, 0x989F, + 0x69E7, 0x98A0, 0x69E8, 0x98A1, 0x69E9, 0x98A2, 0x69EA, 0x98A3, + 0x69EB, 0x98A4, 0x69EC, 0x98A5, 0x69ED, 0xE9CA, 0x69EE, 0x98A6, + 0x69EF, 0x98A7, 0x69F0, 0x98A8, 0x69F1, 0x98A9, 0x69F2, 0xE9CE, + 0x69F3, 0x98AA, 0x69F4, 0x98AB, 0x69F5, 0x98AC, 0x69F6, 0x98AD, + 0x69F7, 0x98AE, 0x69F8, 0x98AF, 0x69F9, 0x98B0, 0x69FA, 0x98B1, + 0x69FB, 0x98B2, 0x69FC, 0x98B3, 0x69FD, 0xB2DB, 0x69FE, 0x98B4, + 0x69FF, 0xE9C8, 0x6A00, 0x98B5, 0x6A01, 0x98B6, 0x6A02, 0x98B7, + 0x6A03, 0x98B8, 0x6A04, 0x98B9, 0x6A05, 0x98BA, 0x6A06, 0x98BB, + 0x6A07, 0x98BC, 0x6A08, 0x98BD, 0x6A09, 0x98BE, 0x6A0A, 0xB7AE, + 0x6A0B, 0x98BF, 0x6A0C, 0x98C0, 0x6A0D, 0x98C1, 0x6A0E, 0x98C2, + 0x6A0F, 0x98C3, 0x6A10, 0x98C4, 0x6A11, 0x98C5, 0x6A12, 0x98C6, + 0x6A13, 0x98C7, 0x6A14, 0x98C8, 0x6A15, 0x98C9, 0x6A16, 0x98CA, + 0x6A17, 0xE9CB, 0x6A18, 0xE9CC, 0x6A19, 0x98CB, 0x6A1A, 0x98CC, + 0x6A1B, 0x98CD, 0x6A1C, 0x98CE, 0x6A1D, 0x98CF, 0x6A1E, 0x98D0, + 0x6A1F, 0xD5C1, 0x6A20, 0x98D1, 0x6A21, 0xC4A3, 0x6A22, 0x98D2, + 0x6A23, 0x98D3, 0x6A24, 0x98D4, 0x6A25, 0x98D5, 0x6A26, 0x98D6, + 0x6A27, 0x98D7, 0x6A28, 0xE9D8, 0x6A29, 0x98D8, 0x6A2A, 0xBAE1, + 0x6A2B, 0x98D9, 0x6A2C, 0x98DA, 0x6A2D, 0x98DB, 0x6A2E, 0x98DC, + 0x6A2F, 0xE9C9, 0x6A30, 0x98DD, 0x6A31, 0xD3A3, 0x6A32, 0x98DE, + 0x6A33, 0x98DF, 0x6A34, 0x98E0, 0x6A35, 0xE9D4, 0x6A36, 0x98E1, + 0x6A37, 0x98E2, 0x6A38, 0x98E3, 0x6A39, 0x98E4, 0x6A3A, 0x98E5, + 0x6A3B, 0x98E6, 0x6A3C, 0x98E7, 0x6A3D, 0xE9D7, 0x6A3E, 0xE9D0, + 0x6A3F, 0x98E8, 0x6A40, 0x98E9, 0x6A41, 0x98EA, 0x6A42, 0x98EB, + 0x6A43, 0x98EC, 0x6A44, 0xE9CF, 0x6A45, 0x98ED, 0x6A46, 0x98EE, + 0x6A47, 0xC7C1, 0x6A48, 0x98EF, 0x6A49, 0x98F0, 0x6A4A, 0x98F1, + 0x6A4B, 0x98F2, 0x6A4C, 0x98F3, 0x6A4D, 0x98F4, 0x6A4E, 0x98F5, + 0x6A4F, 0x98F6, 0x6A50, 0xE9D2, 0x6A51, 0x98F7, 0x6A52, 0x98F8, + 0x6A53, 0x98F9, 0x6A54, 0x98FA, 0x6A55, 0x98FB, 0x6A56, 0x98FC, + 0x6A57, 0x98FD, 0x6A58, 0xE9D9, 0x6A59, 0xB3C8, 0x6A5A, 0x98FE, + 0x6A5B, 0xE9D3, 0x6A5C, 0x9940, 0x6A5D, 0x9941, 0x6A5E, 0x9942, + 0x6A5F, 0x9943, 0x6A60, 0x9944, 0x6A61, 0xCFF0, 0x6A62, 0x9945, + 0x6A63, 0x9946, 0x6A64, 0x9947, 0x6A65, 0xE9CD, 0x6A66, 0x9948, + 0x6A67, 0x9949, 0x6A68, 0x994A, 0x6A69, 0x994B, 0x6A6A, 0x994C, + 0x6A6B, 0x994D, 0x6A6C, 0x994E, 0x6A6D, 0x994F, 0x6A6E, 0x9950, + 0x6A6F, 0x9951, 0x6A70, 0x9952, 0x6A71, 0xB3F7, 0x6A72, 0x9953, + 0x6A73, 0x9954, 0x6A74, 0x9955, 0x6A75, 0x9956, 0x6A76, 0x9957, + 0x6A77, 0x9958, 0x6A78, 0x9959, 0x6A79, 0xE9D6, 0x6A7A, 0x995A, + 0x6A7B, 0x995B, 0x6A7C, 0xE9DA, 0x6A7D, 0x995C, 0x6A7E, 0x995D, + 0x6A7F, 0x995E, 0x6A80, 0xCCB4, 0x6A81, 0x995F, 0x6A82, 0x9960, + 0x6A83, 0x9961, 0x6A84, 0xCFAD, 0x6A85, 0x9962, 0x6A86, 0x9963, + 0x6A87, 0x9964, 0x6A88, 0x9965, 0x6A89, 0x9966, 0x6A8A, 0x9967, + 0x6A8B, 0x9968, 0x6A8C, 0x9969, 0x6A8D, 0x996A, 0x6A8E, 0xE9D5, + 0x6A8F, 0x996B, 0x6A90, 0xE9DC, 0x6A91, 0xE9DB, 0x6A92, 0x996C, + 0x6A93, 0x996D, 0x6A94, 0x996E, 0x6A95, 0x996F, 0x6A96, 0x9970, + 0x6A97, 0xE9DE, 0x6A98, 0x9971, 0x6A99, 0x9972, 0x6A9A, 0x9973, + 0x6A9B, 0x9974, 0x6A9C, 0x9975, 0x6A9D, 0x9976, 0x6A9E, 0x9977, + 0x6A9F, 0x9978, 0x6AA0, 0xE9D1, 0x6AA1, 0x9979, 0x6AA2, 0x997A, + 0x6AA3, 0x997B, 0x6AA4, 0x997C, 0x6AA5, 0x997D, 0x6AA6, 0x997E, + 0x6AA7, 0x9980, 0x6AA8, 0x9981, 0x6AA9, 0xE9DD, 0x6AAA, 0x9982, + 0x6AAB, 0xE9DF, 0x6AAC, 0xC3CA, 0x6AAD, 0x9983, 0x6AAE, 0x9984, + 0x6AAF, 0x9985, 0x6AB0, 0x9986, 0x6AB1, 0x9987, 0x6AB2, 0x9988, + 0x6AB3, 0x9989, 0x6AB4, 0x998A, 0x6AB5, 0x998B, 0x6AB6, 0x998C, + 0x6AB7, 0x998D, 0x6AB8, 0x998E, 0x6AB9, 0x998F, 0x6ABA, 0x9990, + 0x6ABB, 0x9991, 0x6ABC, 0x9992, 0x6ABD, 0x9993, 0x6ABE, 0x9994, + 0x6ABF, 0x9995, 0x6AC0, 0x9996, 0x6AC1, 0x9997, 0x6AC2, 0x9998, + 0x6AC3, 0x9999, 0x6AC4, 0x999A, 0x6AC5, 0x999B, 0x6AC6, 0x999C, + 0x6AC7, 0x999D, 0x6AC8, 0x999E, 0x6AC9, 0x999F, 0x6ACA, 0x99A0, + 0x6ACB, 0x99A1, 0x6ACC, 0x99A2, 0x6ACD, 0x99A3, 0x6ACE, 0x99A4, + 0x6ACF, 0x99A5, 0x6AD0, 0x99A6, 0x6AD1, 0x99A7, 0x6AD2, 0x99A8, + 0x6AD3, 0x99A9, 0x6AD4, 0x99AA, 0x6AD5, 0x99AB, 0x6AD6, 0x99AC, + 0x6AD7, 0x99AD, 0x6AD8, 0x99AE, 0x6AD9, 0x99AF, 0x6ADA, 0x99B0, + 0x6ADB, 0x99B1, 0x6ADC, 0x99B2, 0x6ADD, 0x99B3, 0x6ADE, 0x99B4, + 0x6ADF, 0x99B5, 0x6AE0, 0x99B6, 0x6AE1, 0x99B7, 0x6AE2, 0x99B8, + 0x6AE3, 0x99B9, 0x6AE4, 0x99BA, 0x6AE5, 0x99BB, 0x6AE6, 0x99BC, + 0x6AE7, 0x99BD, 0x6AE8, 0x99BE, 0x6AE9, 0x99BF, 0x6AEA, 0x99C0, + 0x6AEB, 0x99C1, 0x6AEC, 0x99C2, 0x6AED, 0x99C3, 0x6AEE, 0x99C4, + 0x6AEF, 0x99C5, 0x6AF0, 0x99C6, 0x6AF1, 0x99C7, 0x6AF2, 0x99C8, + 0x6AF3, 0x99C9, 0x6AF4, 0x99CA, 0x6AF5, 0x99CB, 0x6AF6, 0x99CC, + 0x6AF7, 0x99CD, 0x6AF8, 0x99CE, 0x6AF9, 0x99CF, 0x6AFA, 0x99D0, + 0x6AFB, 0x99D1, 0x6AFC, 0x99D2, 0x6AFD, 0x99D3, 0x6AFE, 0x99D4, + 0x6AFF, 0x99D5, 0x6B00, 0x99D6, 0x6B01, 0x99D7, 0x6B02, 0x99D8, + 0x6B03, 0x99D9, 0x6B04, 0x99DA, 0x6B05, 0x99DB, 0x6B06, 0x99DC, + 0x6B07, 0x99DD, 0x6B08, 0x99DE, 0x6B09, 0x99DF, 0x6B0A, 0x99E0, + 0x6B0B, 0x99E1, 0x6B0C, 0x99E2, 0x6B0D, 0x99E3, 0x6B0E, 0x99E4, + 0x6B0F, 0x99E5, 0x6B10, 0x99E6, 0x6B11, 0x99E7, 0x6B12, 0x99E8, + 0x6B13, 0x99E9, 0x6B14, 0x99EA, 0x6B15, 0x99EB, 0x6B16, 0x99EC, + 0x6B17, 0x99ED, 0x6B18, 0x99EE, 0x6B19, 0x99EF, 0x6B1A, 0x99F0, + 0x6B1B, 0x99F1, 0x6B1C, 0x99F2, 0x6B1D, 0x99F3, 0x6B1E, 0x99F4, + 0x6B1F, 0x99F5, 0x6B20, 0xC7B7, 0x6B21, 0xB4CE, 0x6B22, 0xBBB6, + 0x6B23, 0xD0C0, 0x6B24, 0xECA3, 0x6B25, 0x99F6, 0x6B26, 0x99F7, + 0x6B27, 0xC5B7, 0x6B28, 0x99F8, 0x6B29, 0x99F9, 0x6B2A, 0x99FA, + 0x6B2B, 0x99FB, 0x6B2C, 0x99FC, 0x6B2D, 0x99FD, 0x6B2E, 0x99FE, + 0x6B2F, 0x9A40, 0x6B30, 0x9A41, 0x6B31, 0x9A42, 0x6B32, 0xD3FB, + 0x6B33, 0x9A43, 0x6B34, 0x9A44, 0x6B35, 0x9A45, 0x6B36, 0x9A46, + 0x6B37, 0xECA4, 0x6B38, 0x9A47, 0x6B39, 0xECA5, 0x6B3A, 0xC6DB, + 0x6B3B, 0x9A48, 0x6B3C, 0x9A49, 0x6B3D, 0x9A4A, 0x6B3E, 0xBFEE, + 0x6B3F, 0x9A4B, 0x6B40, 0x9A4C, 0x6B41, 0x9A4D, 0x6B42, 0x9A4E, + 0x6B43, 0xECA6, 0x6B44, 0x9A4F, 0x6B45, 0x9A50, 0x6B46, 0xECA7, + 0x6B47, 0xD0AA, 0x6B48, 0x9A51, 0x6B49, 0xC7B8, 0x6B4A, 0x9A52, + 0x6B4B, 0x9A53, 0x6B4C, 0xB8E8, 0x6B4D, 0x9A54, 0x6B4E, 0x9A55, + 0x6B4F, 0x9A56, 0x6B50, 0x9A57, 0x6B51, 0x9A58, 0x6B52, 0x9A59, + 0x6B53, 0x9A5A, 0x6B54, 0x9A5B, 0x6B55, 0x9A5C, 0x6B56, 0x9A5D, + 0x6B57, 0x9A5E, 0x6B58, 0x9A5F, 0x6B59, 0xECA8, 0x6B5A, 0x9A60, + 0x6B5B, 0x9A61, 0x6B5C, 0x9A62, 0x6B5D, 0x9A63, 0x6B5E, 0x9A64, + 0x6B5F, 0x9A65, 0x6B60, 0x9A66, 0x6B61, 0x9A67, 0x6B62, 0xD6B9, + 0x6B63, 0xD5FD, 0x6B64, 0xB4CB, 0x6B65, 0xB2BD, 0x6B66, 0xCEE4, + 0x6B67, 0xC6E7, 0x6B68, 0x9A68, 0x6B69, 0x9A69, 0x6B6A, 0xCDE1, + 0x6B6B, 0x9A6A, 0x6B6C, 0x9A6B, 0x6B6D, 0x9A6C, 0x6B6E, 0x9A6D, + 0x6B6F, 0x9A6E, 0x6B70, 0x9A6F, 0x6B71, 0x9A70, 0x6B72, 0x9A71, + 0x6B73, 0x9A72, 0x6B74, 0x9A73, 0x6B75, 0x9A74, 0x6B76, 0x9A75, + 0x6B77, 0x9A76, 0x6B78, 0x9A77, 0x6B79, 0xB4F5, 0x6B7A, 0x9A78, + 0x6B7B, 0xCBC0, 0x6B7C, 0xBCDF, 0x6B7D, 0x9A79, 0x6B7E, 0x9A7A, + 0x6B7F, 0x9A7B, 0x6B80, 0x9A7C, 0x6B81, 0xE9E2, 0x6B82, 0xE9E3, + 0x6B83, 0xD1EA, 0x6B84, 0xE9E5, 0x6B85, 0x9A7D, 0x6B86, 0xB4F9, + 0x6B87, 0xE9E4, 0x6B88, 0x9A7E, 0x6B89, 0xD1B3, 0x6B8A, 0xCAE2, + 0x6B8B, 0xB2D0, 0x6B8C, 0x9A80, 0x6B8D, 0xE9E8, 0x6B8E, 0x9A81, + 0x6B8F, 0x9A82, 0x6B90, 0x9A83, 0x6B91, 0x9A84, 0x6B92, 0xE9E6, + 0x6B93, 0xE9E7, 0x6B94, 0x9A85, 0x6B95, 0x9A86, 0x6B96, 0xD6B3, + 0x6B97, 0x9A87, 0x6B98, 0x9A88, 0x6B99, 0x9A89, 0x6B9A, 0xE9E9, + 0x6B9B, 0xE9EA, 0x6B9C, 0x9A8A, 0x6B9D, 0x9A8B, 0x6B9E, 0x9A8C, + 0x6B9F, 0x9A8D, 0x6BA0, 0x9A8E, 0x6BA1, 0xE9EB, 0x6BA2, 0x9A8F, + 0x6BA3, 0x9A90, 0x6BA4, 0x9A91, 0x6BA5, 0x9A92, 0x6BA6, 0x9A93, + 0x6BA7, 0x9A94, 0x6BA8, 0x9A95, 0x6BA9, 0x9A96, 0x6BAA, 0xE9EC, + 0x6BAB, 0x9A97, 0x6BAC, 0x9A98, 0x6BAD, 0x9A99, 0x6BAE, 0x9A9A, + 0x6BAF, 0x9A9B, 0x6BB0, 0x9A9C, 0x6BB1, 0x9A9D, 0x6BB2, 0x9A9E, + 0x6BB3, 0xECAF, 0x6BB4, 0xC5B9, 0x6BB5, 0xB6CE, 0x6BB6, 0x9A9F, + 0x6BB7, 0xD2F3, 0x6BB8, 0x9AA0, 0x6BB9, 0x9AA1, 0x6BBA, 0x9AA2, + 0x6BBB, 0x9AA3, 0x6BBC, 0x9AA4, 0x6BBD, 0x9AA5, 0x6BBE, 0x9AA6, + 0x6BBF, 0xB5EE, 0x6BC0, 0x9AA7, 0x6BC1, 0xBBD9, 0x6BC2, 0xECB1, + 0x6BC3, 0x9AA8, 0x6BC4, 0x9AA9, 0x6BC5, 0xD2E3, 0x6BC6, 0x9AAA, + 0x6BC7, 0x9AAB, 0x6BC8, 0x9AAC, 0x6BC9, 0x9AAD, 0x6BCA, 0x9AAE, + 0x6BCB, 0xCEE3, 0x6BCC, 0x9AAF, 0x6BCD, 0xC4B8, 0x6BCE, 0x9AB0, + 0x6BCF, 0xC3BF, 0x6BD0, 0x9AB1, 0x6BD1, 0x9AB2, 0x6BD2, 0xB6BE, + 0x6BD3, 0xD8B9, 0x6BD4, 0xB1C8, 0x6BD5, 0xB1CF, 0x6BD6, 0xB1D1, + 0x6BD7, 0xC5FE, 0x6BD8, 0x9AB3, 0x6BD9, 0xB1D0, 0x6BDA, 0x9AB4, + 0x6BDB, 0xC3AB, 0x6BDC, 0x9AB5, 0x6BDD, 0x9AB6, 0x6BDE, 0x9AB7, + 0x6BDF, 0x9AB8, 0x6BE0, 0x9AB9, 0x6BE1, 0xD5B1, 0x6BE2, 0x9ABA, + 0x6BE3, 0x9ABB, 0x6BE4, 0x9ABC, 0x6BE5, 0x9ABD, 0x6BE6, 0x9ABE, + 0x6BE7, 0x9ABF, 0x6BE8, 0x9AC0, 0x6BE9, 0x9AC1, 0x6BEA, 0xEBA4, + 0x6BEB, 0xBAC1, 0x6BEC, 0x9AC2, 0x6BED, 0x9AC3, 0x6BEE, 0x9AC4, + 0x6BEF, 0xCCBA, 0x6BF0, 0x9AC5, 0x6BF1, 0x9AC6, 0x6BF2, 0x9AC7, + 0x6BF3, 0xEBA5, 0x6BF4, 0x9AC8, 0x6BF5, 0xEBA7, 0x6BF6, 0x9AC9, + 0x6BF7, 0x9ACA, 0x6BF8, 0x9ACB, 0x6BF9, 0xEBA8, 0x6BFA, 0x9ACC, + 0x6BFB, 0x9ACD, 0x6BFC, 0x9ACE, 0x6BFD, 0xEBA6, 0x6BFE, 0x9ACF, + 0x6BFF, 0x9AD0, 0x6C00, 0x9AD1, 0x6C01, 0x9AD2, 0x6C02, 0x9AD3, + 0x6C03, 0x9AD4, 0x6C04, 0x9AD5, 0x6C05, 0xEBA9, 0x6C06, 0xEBAB, + 0x6C07, 0xEBAA, 0x6C08, 0x9AD6, 0x6C09, 0x9AD7, 0x6C0A, 0x9AD8, + 0x6C0B, 0x9AD9, 0x6C0C, 0x9ADA, 0x6C0D, 0xEBAC, 0x6C0E, 0x9ADB, + 0x6C0F, 0xCACF, 0x6C10, 0xD8B5, 0x6C11, 0xC3F1, 0x6C12, 0x9ADC, + 0x6C13, 0xC3A5, 0x6C14, 0xC6F8, 0x6C15, 0xEBAD, 0x6C16, 0xC4CA, + 0x6C17, 0x9ADD, 0x6C18, 0xEBAE, 0x6C19, 0xEBAF, 0x6C1A, 0xEBB0, + 0x6C1B, 0xB7D5, 0x6C1C, 0x9ADE, 0x6C1D, 0x9ADF, 0x6C1E, 0x9AE0, + 0x6C1F, 0xB7FA, 0x6C20, 0x9AE1, 0x6C21, 0xEBB1, 0x6C22, 0xC7E2, + 0x6C23, 0x9AE2, 0x6C24, 0xEBB3, 0x6C25, 0x9AE3, 0x6C26, 0xBAA4, + 0x6C27, 0xD1F5, 0x6C28, 0xB0B1, 0x6C29, 0xEBB2, 0x6C2A, 0xEBB4, + 0x6C2B, 0x9AE4, 0x6C2C, 0x9AE5, 0x6C2D, 0x9AE6, 0x6C2E, 0xB5AA, + 0x6C2F, 0xC2C8, 0x6C30, 0xC7E8, 0x6C31, 0x9AE7, 0x6C32, 0xEBB5, + 0x6C33, 0x9AE8, 0x6C34, 0xCBAE, 0x6C35, 0xE3DF, 0x6C36, 0x9AE9, + 0x6C37, 0x9AEA, 0x6C38, 0xD3C0, 0x6C39, 0x9AEB, 0x6C3A, 0x9AEC, + 0x6C3B, 0x9AED, 0x6C3C, 0x9AEE, 0x6C3D, 0xD9DB, 0x6C3E, 0x9AEF, + 0x6C3F, 0x9AF0, 0x6C40, 0xCDA1, 0x6C41, 0xD6AD, 0x6C42, 0xC7F3, + 0x6C43, 0x9AF1, 0x6C44, 0x9AF2, 0x6C45, 0x9AF3, 0x6C46, 0xD9E0, + 0x6C47, 0xBBE3, 0x6C48, 0x9AF4, 0x6C49, 0xBABA, 0x6C4A, 0xE3E2, + 0x6C4B, 0x9AF5, 0x6C4C, 0x9AF6, 0x6C4D, 0x9AF7, 0x6C4E, 0x9AF8, + 0x6C4F, 0x9AF9, 0x6C50, 0xCFAB, 0x6C51, 0x9AFA, 0x6C52, 0x9AFB, + 0x6C53, 0x9AFC, 0x6C54, 0xE3E0, 0x6C55, 0xC9C7, 0x6C56, 0x9AFD, + 0x6C57, 0xBAB9, 0x6C58, 0x9AFE, 0x6C59, 0x9B40, 0x6C5A, 0x9B41, + 0x6C5B, 0xD1B4, 0x6C5C, 0xE3E1, 0x6C5D, 0xC8EA, 0x6C5E, 0xB9AF, + 0x6C5F, 0xBDAD, 0x6C60, 0xB3D8, 0x6C61, 0xCEDB, 0x6C62, 0x9B42, + 0x6C63, 0x9B43, 0x6C64, 0xCCC0, 0x6C65, 0x9B44, 0x6C66, 0x9B45, + 0x6C67, 0x9B46, 0x6C68, 0xE3E8, 0x6C69, 0xE3E9, 0x6C6A, 0xCDF4, + 0x6C6B, 0x9B47, 0x6C6C, 0x9B48, 0x6C6D, 0x9B49, 0x6C6E, 0x9B4A, + 0x6C6F, 0x9B4B, 0x6C70, 0xCCAD, 0x6C71, 0x9B4C, 0x6C72, 0xBCB3, + 0x6C73, 0x9B4D, 0x6C74, 0xE3EA, 0x6C75, 0x9B4E, 0x6C76, 0xE3EB, + 0x6C77, 0x9B4F, 0x6C78, 0x9B50, 0x6C79, 0xD0DA, 0x6C7A, 0x9B51, + 0x6C7B, 0x9B52, 0x6C7C, 0x9B53, 0x6C7D, 0xC6FB, 0x6C7E, 0xB7DA, + 0x6C7F, 0x9B54, 0x6C80, 0x9B55, 0x6C81, 0xC7DF, 0x6C82, 0xD2CA, + 0x6C83, 0xCED6, 0x6C84, 0x9B56, 0x6C85, 0xE3E4, 0x6C86, 0xE3EC, + 0x6C87, 0x9B57, 0x6C88, 0xC9F2, 0x6C89, 0xB3C1, 0x6C8A, 0x9B58, + 0x6C8B, 0x9B59, 0x6C8C, 0xE3E7, 0x6C8D, 0x9B5A, 0x6C8E, 0x9B5B, + 0x6C8F, 0xC6E3, 0x6C90, 0xE3E5, 0x6C91, 0x9B5C, 0x6C92, 0x9B5D, + 0x6C93, 0xEDB3, 0x6C94, 0xE3E6, 0x6C95, 0x9B5E, 0x6C96, 0x9B5F, + 0x6C97, 0x9B60, 0x6C98, 0x9B61, 0x6C99, 0xC9B3, 0x6C9A, 0x9B62, + 0x6C9B, 0xC5E6, 0x6C9C, 0x9B63, 0x6C9D, 0x9B64, 0x6C9E, 0x9B65, + 0x6C9F, 0xB9B5, 0x6CA0, 0x9B66, 0x6CA1, 0xC3BB, 0x6CA2, 0x9B67, + 0x6CA3, 0xE3E3, 0x6CA4, 0xC5BD, 0x6CA5, 0xC1A4, 0x6CA6, 0xC2D9, + 0x6CA7, 0xB2D7, 0x6CA8, 0x9B68, 0x6CA9, 0xE3ED, 0x6CAA, 0xBBA6, + 0x6CAB, 0xC4AD, 0x6CAC, 0x9B69, 0x6CAD, 0xE3F0, 0x6CAE, 0xBEDA, + 0x6CAF, 0x9B6A, 0x6CB0, 0x9B6B, 0x6CB1, 0xE3FB, 0x6CB2, 0xE3F5, + 0x6CB3, 0xBAD3, 0x6CB4, 0x9B6C, 0x6CB5, 0x9B6D, 0x6CB6, 0x9B6E, + 0x6CB7, 0x9B6F, 0x6CB8, 0xB7D0, 0x6CB9, 0xD3CD, 0x6CBA, 0x9B70, + 0x6CBB, 0xD6CE, 0x6CBC, 0xD5D3, 0x6CBD, 0xB9C1, 0x6CBE, 0xD5B4, + 0x6CBF, 0xD1D8, 0x6CC0, 0x9B71, 0x6CC1, 0x9B72, 0x6CC2, 0x9B73, + 0x6CC3, 0x9B74, 0x6CC4, 0xD0B9, 0x6CC5, 0xC7F6, 0x6CC6, 0x9B75, + 0x6CC7, 0x9B76, 0x6CC8, 0x9B77, 0x6CC9, 0xC8AA, 0x6CCA, 0xB2B4, + 0x6CCB, 0x9B78, 0x6CCC, 0xC3DA, 0x6CCD, 0x9B79, 0x6CCE, 0x9B7A, + 0x6CCF, 0x9B7B, 0x6CD0, 0xE3EE, 0x6CD1, 0x9B7C, 0x6CD2, 0x9B7D, + 0x6CD3, 0xE3FC, 0x6CD4, 0xE3EF, 0x6CD5, 0xB7A8, 0x6CD6, 0xE3F7, + 0x6CD7, 0xE3F4, 0x6CD8, 0x9B7E, 0x6CD9, 0x9B80, 0x6CDA, 0x9B81, + 0x6CDB, 0xB7BA, 0x6CDC, 0x9B82, 0x6CDD, 0x9B83, 0x6CDE, 0xC5A2, + 0x6CDF, 0x9B84, 0x6CE0, 0xE3F6, 0x6CE1, 0xC5DD, 0x6CE2, 0xB2A8, + 0x6CE3, 0xC6FC, 0x6CE4, 0x9B85, 0x6CE5, 0xC4E0, 0x6CE6, 0x9B86, + 0x6CE7, 0x9B87, 0x6CE8, 0xD7A2, 0x6CE9, 0x9B88, 0x6CEA, 0xC0E1, + 0x6CEB, 0xE3F9, 0x6CEC, 0x9B89, 0x6CED, 0x9B8A, 0x6CEE, 0xE3FA, + 0x6CEF, 0xE3FD, 0x6CF0, 0xCCA9, 0x6CF1, 0xE3F3, 0x6CF2, 0x9B8B, + 0x6CF3, 0xD3BE, 0x6CF4, 0x9B8C, 0x6CF5, 0xB1C3, 0x6CF6, 0xEDB4, + 0x6CF7, 0xE3F1, 0x6CF8, 0xE3F2, 0x6CF9, 0x9B8D, 0x6CFA, 0xE3F8, + 0x6CFB, 0xD0BA, 0x6CFC, 0xC6C3, 0x6CFD, 0xD4F3, 0x6CFE, 0xE3FE, + 0x6CFF, 0x9B8E, 0x6D00, 0x9B8F, 0x6D01, 0xBDE0, 0x6D02, 0x9B90, + 0x6D03, 0x9B91, 0x6D04, 0xE4A7, 0x6D05, 0x9B92, 0x6D06, 0x9B93, + 0x6D07, 0xE4A6, 0x6D08, 0x9B94, 0x6D09, 0x9B95, 0x6D0A, 0x9B96, + 0x6D0B, 0xD1F3, 0x6D0C, 0xE4A3, 0x6D0D, 0x9B97, 0x6D0E, 0xE4A9, + 0x6D0F, 0x9B98, 0x6D10, 0x9B99, 0x6D11, 0x9B9A, 0x6D12, 0xC8F7, + 0x6D13, 0x9B9B, 0x6D14, 0x9B9C, 0x6D15, 0x9B9D, 0x6D16, 0x9B9E, + 0x6D17, 0xCFB4, 0x6D18, 0x9B9F, 0x6D19, 0xE4A8, 0x6D1A, 0xE4AE, + 0x6D1B, 0xC2E5, 0x6D1C, 0x9BA0, 0x6D1D, 0x9BA1, 0x6D1E, 0xB6B4, + 0x6D1F, 0x9BA2, 0x6D20, 0x9BA3, 0x6D21, 0x9BA4, 0x6D22, 0x9BA5, + 0x6D23, 0x9BA6, 0x6D24, 0x9BA7, 0x6D25, 0xBDF2, 0x6D26, 0x9BA8, + 0x6D27, 0xE4A2, 0x6D28, 0x9BA9, 0x6D29, 0x9BAA, 0x6D2A, 0xBAE9, + 0x6D2B, 0xE4AA, 0x6D2C, 0x9BAB, 0x6D2D, 0x9BAC, 0x6D2E, 0xE4AC, + 0x6D2F, 0x9BAD, 0x6D30, 0x9BAE, 0x6D31, 0xB6FD, 0x6D32, 0xD6DE, + 0x6D33, 0xE4B2, 0x6D34, 0x9BAF, 0x6D35, 0xE4AD, 0x6D36, 0x9BB0, + 0x6D37, 0x9BB1, 0x6D38, 0x9BB2, 0x6D39, 0xE4A1, 0x6D3A, 0x9BB3, + 0x6D3B, 0xBBEE, 0x6D3C, 0xCDDD, 0x6D3D, 0xC7A2, 0x6D3E, 0xC5C9, + 0x6D3F, 0x9BB4, 0x6D40, 0x9BB5, 0x6D41, 0xC1F7, 0x6D42, 0x9BB6, + 0x6D43, 0xE4A4, 0x6D44, 0x9BB7, 0x6D45, 0xC7B3, 0x6D46, 0xBDAC, + 0x6D47, 0xBDBD, 0x6D48, 0xE4A5, 0x6D49, 0x9BB8, 0x6D4A, 0xD7C7, + 0x6D4B, 0xB2E2, 0x6D4C, 0x9BB9, 0x6D4D, 0xE4AB, 0x6D4E, 0xBCC3, + 0x6D4F, 0xE4AF, 0x6D50, 0x9BBA, 0x6D51, 0xBBEB, 0x6D52, 0xE4B0, + 0x6D53, 0xC5A8, 0x6D54, 0xE4B1, 0x6D55, 0x9BBB, 0x6D56, 0x9BBC, + 0x6D57, 0x9BBD, 0x6D58, 0x9BBE, 0x6D59, 0xD5E3, 0x6D5A, 0xBFA3, + 0x6D5B, 0x9BBF, 0x6D5C, 0xE4BA, 0x6D5D, 0x9BC0, 0x6D5E, 0xE4B7, + 0x6D5F, 0x9BC1, 0x6D60, 0xE4BB, 0x6D61, 0x9BC2, 0x6D62, 0x9BC3, + 0x6D63, 0xE4BD, 0x6D64, 0x9BC4, 0x6D65, 0x9BC5, 0x6D66, 0xC6D6, + 0x6D67, 0x9BC6, 0x6D68, 0x9BC7, 0x6D69, 0xBAC6, 0x6D6A, 0xC0CB, + 0x6D6B, 0x9BC8, 0x6D6C, 0x9BC9, 0x6D6D, 0x9BCA, 0x6D6E, 0xB8A1, + 0x6D6F, 0xE4B4, 0x6D70, 0x9BCB, 0x6D71, 0x9BCC, 0x6D72, 0x9BCD, + 0x6D73, 0x9BCE, 0x6D74, 0xD4A1, 0x6D75, 0x9BCF, 0x6D76, 0x9BD0, + 0x6D77, 0xBAA3, 0x6D78, 0xBDFE, 0x6D79, 0x9BD1, 0x6D7A, 0x9BD2, + 0x6D7B, 0x9BD3, 0x6D7C, 0xE4BC, 0x6D7D, 0x9BD4, 0x6D7E, 0x9BD5, + 0x6D7F, 0x9BD6, 0x6D80, 0x9BD7, 0x6D81, 0x9BD8, 0x6D82, 0xCDBF, + 0x6D83, 0x9BD9, 0x6D84, 0x9BDA, 0x6D85, 0xC4F9, 0x6D86, 0x9BDB, + 0x6D87, 0x9BDC, 0x6D88, 0xCFFB, 0x6D89, 0xC9E6, 0x6D8A, 0x9BDD, + 0x6D8B, 0x9BDE, 0x6D8C, 0xD3BF, 0x6D8D, 0x9BDF, 0x6D8E, 0xCFD1, + 0x6D8F, 0x9BE0, 0x6D90, 0x9BE1, 0x6D91, 0xE4B3, 0x6D92, 0x9BE2, + 0x6D93, 0xE4B8, 0x6D94, 0xE4B9, 0x6D95, 0xCCE9, 0x6D96, 0x9BE3, + 0x6D97, 0x9BE4, 0x6D98, 0x9BE5, 0x6D99, 0x9BE6, 0x6D9A, 0x9BE7, + 0x6D9B, 0xCCCE, 0x6D9C, 0x9BE8, 0x6D9D, 0xC0D4, 0x6D9E, 0xE4B5, + 0x6D9F, 0xC1B0, 0x6DA0, 0xE4B6, 0x6DA1, 0xCED0, 0x6DA2, 0x9BE9, + 0x6DA3, 0xBBC1, 0x6DA4, 0xB5D3, 0x6DA5, 0x9BEA, 0x6DA6, 0xC8F3, + 0x6DA7, 0xBDA7, 0x6DA8, 0xD5C7, 0x6DA9, 0xC9AC, 0x6DAA, 0xB8A2, + 0x6DAB, 0xE4CA, 0x6DAC, 0x9BEB, 0x6DAD, 0x9BEC, 0x6DAE, 0xE4CC, + 0x6DAF, 0xD1C4, 0x6DB0, 0x9BED, 0x6DB1, 0x9BEE, 0x6DB2, 0xD2BA, + 0x6DB3, 0x9BEF, 0x6DB4, 0x9BF0, 0x6DB5, 0xBAAD, 0x6DB6, 0x9BF1, + 0x6DB7, 0x9BF2, 0x6DB8, 0xBAD4, 0x6DB9, 0x9BF3, 0x6DBA, 0x9BF4, + 0x6DBB, 0x9BF5, 0x6DBC, 0x9BF6, 0x6DBD, 0x9BF7, 0x6DBE, 0x9BF8, + 0x6DBF, 0xE4C3, 0x6DC0, 0xB5ED, 0x6DC1, 0x9BF9, 0x6DC2, 0x9BFA, + 0x6DC3, 0x9BFB, 0x6DC4, 0xD7CD, 0x6DC5, 0xE4C0, 0x6DC6, 0xCFFD, + 0x6DC7, 0xE4BF, 0x6DC8, 0x9BFC, 0x6DC9, 0x9BFD, 0x6DCA, 0x9BFE, + 0x6DCB, 0xC1DC, 0x6DCC, 0xCCCA, 0x6DCD, 0x9C40, 0x6DCE, 0x9C41, + 0x6DCF, 0x9C42, 0x6DD0, 0x9C43, 0x6DD1, 0xCAE7, 0x6DD2, 0x9C44, + 0x6DD3, 0x9C45, 0x6DD4, 0x9C46, 0x6DD5, 0x9C47, 0x6DD6, 0xC4D7, + 0x6DD7, 0x9C48, 0x6DD8, 0xCCD4, 0x6DD9, 0xE4C8, 0x6DDA, 0x9C49, + 0x6DDB, 0x9C4A, 0x6DDC, 0x9C4B, 0x6DDD, 0xE4C7, 0x6DDE, 0xE4C1, + 0x6DDF, 0x9C4C, 0x6DE0, 0xE4C4, 0x6DE1, 0xB5AD, 0x6DE2, 0x9C4D, + 0x6DE3, 0x9C4E, 0x6DE4, 0xD3D9, 0x6DE5, 0x9C4F, 0x6DE6, 0xE4C6, + 0x6DE7, 0x9C50, 0x6DE8, 0x9C51, 0x6DE9, 0x9C52, 0x6DEA, 0x9C53, + 0x6DEB, 0xD2F9, 0x6DEC, 0xB4E3, 0x6DED, 0x9C54, 0x6DEE, 0xBBB4, + 0x6DEF, 0x9C55, 0x6DF0, 0x9C56, 0x6DF1, 0xC9EE, 0x6DF2, 0x9C57, + 0x6DF3, 0xB4BE, 0x6DF4, 0x9C58, 0x6DF5, 0x9C59, 0x6DF6, 0x9C5A, + 0x6DF7, 0xBBEC, 0x6DF8, 0x9C5B, 0x6DF9, 0xD1CD, 0x6DFA, 0x9C5C, + 0x6DFB, 0xCCED, 0x6DFC, 0xEDB5, 0x6DFD, 0x9C5D, 0x6DFE, 0x9C5E, + 0x6DFF, 0x9C5F, 0x6E00, 0x9C60, 0x6E01, 0x9C61, 0x6E02, 0x9C62, + 0x6E03, 0x9C63, 0x6E04, 0x9C64, 0x6E05, 0xC7E5, 0x6E06, 0x9C65, + 0x6E07, 0x9C66, 0x6E08, 0x9C67, 0x6E09, 0x9C68, 0x6E0A, 0xD4A8, + 0x6E0B, 0x9C69, 0x6E0C, 0xE4CB, 0x6E0D, 0xD7D5, 0x6E0E, 0xE4C2, + 0x6E0F, 0x9C6A, 0x6E10, 0xBDA5, 0x6E11, 0xE4C5, 0x6E12, 0x9C6B, + 0x6E13, 0x9C6C, 0x6E14, 0xD3E6, 0x6E15, 0x9C6D, 0x6E16, 0xE4C9, + 0x6E17, 0xC9F8, 0x6E18, 0x9C6E, 0x6E19, 0x9C6F, 0x6E1A, 0xE4BE, + 0x6E1B, 0x9C70, 0x6E1C, 0x9C71, 0x6E1D, 0xD3E5, 0x6E1E, 0x9C72, + 0x6E1F, 0x9C73, 0x6E20, 0xC7FE, 0x6E21, 0xB6C9, 0x6E22, 0x9C74, + 0x6E23, 0xD4FC, 0x6E24, 0xB2B3, 0x6E25, 0xE4D7, 0x6E26, 0x9C75, + 0x6E27, 0x9C76, 0x6E28, 0x9C77, 0x6E29, 0xCEC2, 0x6E2A, 0x9C78, + 0x6E2B, 0xE4CD, 0x6E2C, 0x9C79, 0x6E2D, 0xCEBC, 0x6E2E, 0x9C7A, + 0x6E2F, 0xB8DB, 0x6E30, 0x9C7B, 0x6E31, 0x9C7C, 0x6E32, 0xE4D6, + 0x6E33, 0x9C7D, 0x6E34, 0xBFCA, 0x6E35, 0x9C7E, 0x6E36, 0x9C80, + 0x6E37, 0x9C81, 0x6E38, 0xD3CE, 0x6E39, 0x9C82, 0x6E3A, 0xC3EC, + 0x6E3B, 0x9C83, 0x6E3C, 0x9C84, 0x6E3D, 0x9C85, 0x6E3E, 0x9C86, + 0x6E3F, 0x9C87, 0x6E40, 0x9C88, 0x6E41, 0x9C89, 0x6E42, 0x9C8A, + 0x6E43, 0xC5C8, 0x6E44, 0xE4D8, 0x6E45, 0x9C8B, 0x6E46, 0x9C8C, + 0x6E47, 0x9C8D, 0x6E48, 0x9C8E, 0x6E49, 0x9C8F, 0x6E4A, 0x9C90, + 0x6E4B, 0x9C91, 0x6E4C, 0x9C92, 0x6E4D, 0xCDC4, 0x6E4E, 0xE4CF, + 0x6E4F, 0x9C93, 0x6E50, 0x9C94, 0x6E51, 0x9C95, 0x6E52, 0x9C96, + 0x6E53, 0xE4D4, 0x6E54, 0xE4D5, 0x6E55, 0x9C97, 0x6E56, 0xBAFE, + 0x6E57, 0x9C98, 0x6E58, 0xCFE6, 0x6E59, 0x9C99, 0x6E5A, 0x9C9A, + 0x6E5B, 0xD5BF, 0x6E5C, 0x9C9B, 0x6E5D, 0x9C9C, 0x6E5E, 0x9C9D, + 0x6E5F, 0xE4D2, 0x6E60, 0x9C9E, 0x6E61, 0x9C9F, 0x6E62, 0x9CA0, + 0x6E63, 0x9CA1, 0x6E64, 0x9CA2, 0x6E65, 0x9CA3, 0x6E66, 0x9CA4, + 0x6E67, 0x9CA5, 0x6E68, 0x9CA6, 0x6E69, 0x9CA7, 0x6E6A, 0x9CA8, + 0x6E6B, 0xE4D0, 0x6E6C, 0x9CA9, 0x6E6D, 0x9CAA, 0x6E6E, 0xE4CE, + 0x6E6F, 0x9CAB, 0x6E70, 0x9CAC, 0x6E71, 0x9CAD, 0x6E72, 0x9CAE, + 0x6E73, 0x9CAF, 0x6E74, 0x9CB0, 0x6E75, 0x9CB1, 0x6E76, 0x9CB2, + 0x6E77, 0x9CB3, 0x6E78, 0x9CB4, 0x6E79, 0x9CB5, 0x6E7A, 0x9CB6, + 0x6E7B, 0x9CB7, 0x6E7C, 0x9CB8, 0x6E7D, 0x9CB9, 0x6E7E, 0xCDE5, + 0x6E7F, 0xCAAA, 0x6E80, 0x9CBA, 0x6E81, 0x9CBB, 0x6E82, 0x9CBC, + 0x6E83, 0xC0A3, 0x6E84, 0x9CBD, 0x6E85, 0xBDA6, 0x6E86, 0xE4D3, + 0x6E87, 0x9CBE, 0x6E88, 0x9CBF, 0x6E89, 0xB8C8, 0x6E8A, 0x9CC0, + 0x6E8B, 0x9CC1, 0x6E8C, 0x9CC2, 0x6E8D, 0x9CC3, 0x6E8E, 0x9CC4, + 0x6E8F, 0xE4E7, 0x6E90, 0xD4B4, 0x6E91, 0x9CC5, 0x6E92, 0x9CC6, + 0x6E93, 0x9CC7, 0x6E94, 0x9CC8, 0x6E95, 0x9CC9, 0x6E96, 0x9CCA, + 0x6E97, 0x9CCB, 0x6E98, 0xE4DB, 0x6E99, 0x9CCC, 0x6E9A, 0x9CCD, + 0x6E9B, 0x9CCE, 0x6E9C, 0xC1EF, 0x6E9D, 0x9CCF, 0x6E9E, 0x9CD0, + 0x6E9F, 0xE4E9, 0x6EA0, 0x9CD1, 0x6EA1, 0x9CD2, 0x6EA2, 0xD2E7, + 0x6EA3, 0x9CD3, 0x6EA4, 0x9CD4, 0x6EA5, 0xE4DF, 0x6EA6, 0x9CD5, + 0x6EA7, 0xE4E0, 0x6EA8, 0x9CD6, 0x6EA9, 0x9CD7, 0x6EAA, 0xCFAA, + 0x6EAB, 0x9CD8, 0x6EAC, 0x9CD9, 0x6EAD, 0x9CDA, 0x6EAE, 0x9CDB, + 0x6EAF, 0xCBDD, 0x6EB0, 0x9CDC, 0x6EB1, 0xE4DA, 0x6EB2, 0xE4D1, + 0x6EB3, 0x9CDD, 0x6EB4, 0xE4E5, 0x6EB5, 0x9CDE, 0x6EB6, 0xC8DC, + 0x6EB7, 0xE4E3, 0x6EB8, 0x9CDF, 0x6EB9, 0x9CE0, 0x6EBA, 0xC4E7, + 0x6EBB, 0xE4E2, 0x6EBC, 0x9CE1, 0x6EBD, 0xE4E1, 0x6EBE, 0x9CE2, + 0x6EBF, 0x9CE3, 0x6EC0, 0x9CE4, 0x6EC1, 0xB3FC, 0x6EC2, 0xE4E8, + 0x6EC3, 0x9CE5, 0x6EC4, 0x9CE6, 0x6EC5, 0x9CE7, 0x6EC6, 0x9CE8, + 0x6EC7, 0xB5E1, 0x6EC8, 0x9CE9, 0x6EC9, 0x9CEA, 0x6ECA, 0x9CEB, + 0x6ECB, 0xD7CC, 0x6ECC, 0x9CEC, 0x6ECD, 0x9CED, 0x6ECE, 0x9CEE, + 0x6ECF, 0xE4E6, 0x6ED0, 0x9CEF, 0x6ED1, 0xBBAC, 0x6ED2, 0x9CF0, + 0x6ED3, 0xD7D2, 0x6ED4, 0xCCCF, 0x6ED5, 0xEBF8, 0x6ED6, 0x9CF1, + 0x6ED7, 0xE4E4, 0x6ED8, 0x9CF2, 0x6ED9, 0x9CF3, 0x6EDA, 0xB9F6, + 0x6EDB, 0x9CF4, 0x6EDC, 0x9CF5, 0x6EDD, 0x9CF6, 0x6EDE, 0xD6CD, + 0x6EDF, 0xE4D9, 0x6EE0, 0xE4DC, 0x6EE1, 0xC2FA, 0x6EE2, 0xE4DE, + 0x6EE3, 0x9CF7, 0x6EE4, 0xC2CB, 0x6EE5, 0xC0C4, 0x6EE6, 0xC2D0, + 0x6EE7, 0x9CF8, 0x6EE8, 0xB1F5, 0x6EE9, 0xCCB2, 0x6EEA, 0x9CF9, + 0x6EEB, 0x9CFA, 0x6EEC, 0x9CFB, 0x6EED, 0x9CFC, 0x6EEE, 0x9CFD, + 0x6EEF, 0x9CFE, 0x6EF0, 0x9D40, 0x6EF1, 0x9D41, 0x6EF2, 0x9D42, + 0x6EF3, 0x9D43, 0x6EF4, 0xB5CE, 0x6EF5, 0x9D44, 0x6EF6, 0x9D45, + 0x6EF7, 0x9D46, 0x6EF8, 0x9D47, 0x6EF9, 0xE4EF, 0x6EFA, 0x9D48, + 0x6EFB, 0x9D49, 0x6EFC, 0x9D4A, 0x6EFD, 0x9D4B, 0x6EFE, 0x9D4C, + 0x6EFF, 0x9D4D, 0x6F00, 0x9D4E, 0x6F01, 0x9D4F, 0x6F02, 0xC6AF, + 0x6F03, 0x9D50, 0x6F04, 0x9D51, 0x6F05, 0x9D52, 0x6F06, 0xC6E1, + 0x6F07, 0x9D53, 0x6F08, 0x9D54, 0x6F09, 0xE4F5, 0x6F0A, 0x9D55, + 0x6F0B, 0x9D56, 0x6F0C, 0x9D57, 0x6F0D, 0x9D58, 0x6F0E, 0x9D59, + 0x6F0F, 0xC2A9, 0x6F10, 0x9D5A, 0x6F11, 0x9D5B, 0x6F12, 0x9D5C, + 0x6F13, 0xC0EC, 0x6F14, 0xD1DD, 0x6F15, 0xE4EE, 0x6F16, 0x9D5D, + 0x6F17, 0x9D5E, 0x6F18, 0x9D5F, 0x6F19, 0x9D60, 0x6F1A, 0x9D61, + 0x6F1B, 0x9D62, 0x6F1C, 0x9D63, 0x6F1D, 0x9D64, 0x6F1E, 0x9D65, + 0x6F1F, 0x9D66, 0x6F20, 0xC4AE, 0x6F21, 0x9D67, 0x6F22, 0x9D68, + 0x6F23, 0x9D69, 0x6F24, 0xE4ED, 0x6F25, 0x9D6A, 0x6F26, 0x9D6B, + 0x6F27, 0x9D6C, 0x6F28, 0x9D6D, 0x6F29, 0xE4F6, 0x6F2A, 0xE4F4, + 0x6F2B, 0xC2FE, 0x6F2C, 0x9D6E, 0x6F2D, 0xE4DD, 0x6F2E, 0x9D6F, + 0x6F2F, 0xE4F0, 0x6F30, 0x9D70, 0x6F31, 0xCAFE, 0x6F32, 0x9D71, + 0x6F33, 0xD5C4, 0x6F34, 0x9D72, 0x6F35, 0x9D73, 0x6F36, 0xE4F1, + 0x6F37, 0x9D74, 0x6F38, 0x9D75, 0x6F39, 0x9D76, 0x6F3A, 0x9D77, + 0x6F3B, 0x9D78, 0x6F3C, 0x9D79, 0x6F3D, 0x9D7A, 0x6F3E, 0xD1FA, + 0x6F3F, 0x9D7B, 0x6F40, 0x9D7C, 0x6F41, 0x9D7D, 0x6F42, 0x9D7E, + 0x6F43, 0x9D80, 0x6F44, 0x9D81, 0x6F45, 0x9D82, 0x6F46, 0xE4EB, + 0x6F47, 0xE4EC, 0x6F48, 0x9D83, 0x6F49, 0x9D84, 0x6F4A, 0x9D85, + 0x6F4B, 0xE4F2, 0x6F4C, 0x9D86, 0x6F4D, 0xCEAB, 0x6F4E, 0x9D87, + 0x6F4F, 0x9D88, 0x6F50, 0x9D89, 0x6F51, 0x9D8A, 0x6F52, 0x9D8B, + 0x6F53, 0x9D8C, 0x6F54, 0x9D8D, 0x6F55, 0x9D8E, 0x6F56, 0x9D8F, + 0x6F57, 0x9D90, 0x6F58, 0xC5CB, 0x6F59, 0x9D91, 0x6F5A, 0x9D92, + 0x6F5B, 0x9D93, 0x6F5C, 0xC7B1, 0x6F5D, 0x9D94, 0x6F5E, 0xC2BA, + 0x6F5F, 0x9D95, 0x6F60, 0x9D96, 0x6F61, 0x9D97, 0x6F62, 0xE4EA, + 0x6F63, 0x9D98, 0x6F64, 0x9D99, 0x6F65, 0x9D9A, 0x6F66, 0xC1CA, + 0x6F67, 0x9D9B, 0x6F68, 0x9D9C, 0x6F69, 0x9D9D, 0x6F6A, 0x9D9E, + 0x6F6B, 0x9D9F, 0x6F6C, 0x9DA0, 0x6F6D, 0xCCB6, 0x6F6E, 0xB3B1, + 0x6F6F, 0x9DA1, 0x6F70, 0x9DA2, 0x6F71, 0x9DA3, 0x6F72, 0xE4FB, + 0x6F73, 0x9DA4, 0x6F74, 0xE4F3, 0x6F75, 0x9DA5, 0x6F76, 0x9DA6, + 0x6F77, 0x9DA7, 0x6F78, 0xE4FA, 0x6F79, 0x9DA8, 0x6F7A, 0xE4FD, + 0x6F7B, 0x9DA9, 0x6F7C, 0xE4FC, 0x6F7D, 0x9DAA, 0x6F7E, 0x9DAB, + 0x6F7F, 0x9DAC, 0x6F80, 0x9DAD, 0x6F81, 0x9DAE, 0x6F82, 0x9DAF, + 0x6F83, 0x9DB0, 0x6F84, 0xB3CE, 0x6F85, 0x9DB1, 0x6F86, 0x9DB2, + 0x6F87, 0x9DB3, 0x6F88, 0xB3BA, 0x6F89, 0xE4F7, 0x6F8A, 0x9DB4, + 0x6F8B, 0x9DB5, 0x6F8C, 0xE4F9, 0x6F8D, 0xE4F8, 0x6F8E, 0xC5EC, + 0x6F8F, 0x9DB6, 0x6F90, 0x9DB7, 0x6F91, 0x9DB8, 0x6F92, 0x9DB9, + 0x6F93, 0x9DBA, 0x6F94, 0x9DBB, 0x6F95, 0x9DBC, 0x6F96, 0x9DBD, + 0x6F97, 0x9DBE, 0x6F98, 0x9DBF, 0x6F99, 0x9DC0, 0x6F9A, 0x9DC1, + 0x6F9B, 0x9DC2, 0x6F9C, 0xC0BD, 0x6F9D, 0x9DC3, 0x6F9E, 0x9DC4, + 0x6F9F, 0x9DC5, 0x6FA0, 0x9DC6, 0x6FA1, 0xD4E8, 0x6FA2, 0x9DC7, + 0x6FA3, 0x9DC8, 0x6FA4, 0x9DC9, 0x6FA5, 0x9DCA, 0x6FA6, 0x9DCB, + 0x6FA7, 0xE5A2, 0x6FA8, 0x9DCC, 0x6FA9, 0x9DCD, 0x6FAA, 0x9DCE, + 0x6FAB, 0x9DCF, 0x6FAC, 0x9DD0, 0x6FAD, 0x9DD1, 0x6FAE, 0x9DD2, + 0x6FAF, 0x9DD3, 0x6FB0, 0x9DD4, 0x6FB1, 0x9DD5, 0x6FB2, 0x9DD6, + 0x6FB3, 0xB0C4, 0x6FB4, 0x9DD7, 0x6FB5, 0x9DD8, 0x6FB6, 0xE5A4, + 0x6FB7, 0x9DD9, 0x6FB8, 0x9DDA, 0x6FB9, 0xE5A3, 0x6FBA, 0x9DDB, + 0x6FBB, 0x9DDC, 0x6FBC, 0x9DDD, 0x6FBD, 0x9DDE, 0x6FBE, 0x9DDF, + 0x6FBF, 0x9DE0, 0x6FC0, 0xBCA4, 0x6FC1, 0x9DE1, 0x6FC2, 0xE5A5, + 0x6FC3, 0x9DE2, 0x6FC4, 0x9DE3, 0x6FC5, 0x9DE4, 0x6FC6, 0x9DE5, + 0x6FC7, 0x9DE6, 0x6FC8, 0x9DE7, 0x6FC9, 0xE5A1, 0x6FCA, 0x9DE8, + 0x6FCB, 0x9DE9, 0x6FCC, 0x9DEA, 0x6FCD, 0x9DEB, 0x6FCE, 0x9DEC, + 0x6FCF, 0x9DED, 0x6FD0, 0x9DEE, 0x6FD1, 0xE4FE, 0x6FD2, 0xB1F4, + 0x6FD3, 0x9DEF, 0x6FD4, 0x9DF0, 0x6FD5, 0x9DF1, 0x6FD6, 0x9DF2, + 0x6FD7, 0x9DF3, 0x6FD8, 0x9DF4, 0x6FD9, 0x9DF5, 0x6FDA, 0x9DF6, + 0x6FDB, 0x9DF7, 0x6FDC, 0x9DF8, 0x6FDD, 0x9DF9, 0x6FDE, 0xE5A8, + 0x6FDF, 0x9DFA, 0x6FE0, 0xE5A9, 0x6FE1, 0xE5A6, 0x6FE2, 0x9DFB, + 0x6FE3, 0x9DFC, 0x6FE4, 0x9DFD, 0x6FE5, 0x9DFE, 0x6FE6, 0x9E40, + 0x6FE7, 0x9E41, 0x6FE8, 0x9E42, 0x6FE9, 0x9E43, 0x6FEA, 0x9E44, + 0x6FEB, 0x9E45, 0x6FEC, 0x9E46, 0x6FED, 0x9E47, 0x6FEE, 0xE5A7, + 0x6FEF, 0xE5AA, 0x6FF0, 0x9E48, 0x6FF1, 0x9E49, 0x6FF2, 0x9E4A, + 0x6FF3, 0x9E4B, 0x6FF4, 0x9E4C, 0x6FF5, 0x9E4D, 0x6FF6, 0x9E4E, + 0x6FF7, 0x9E4F, 0x6FF8, 0x9E50, 0x6FF9, 0x9E51, 0x6FFA, 0x9E52, + 0x6FFB, 0x9E53, 0x6FFC, 0x9E54, 0x6FFD, 0x9E55, 0x6FFE, 0x9E56, + 0x6FFF, 0x9E57, 0x7000, 0x9E58, 0x7001, 0x9E59, 0x7002, 0x9E5A, + 0x7003, 0x9E5B, 0x7004, 0x9E5C, 0x7005, 0x9E5D, 0x7006, 0x9E5E, + 0x7007, 0x9E5F, 0x7008, 0x9E60, 0x7009, 0x9E61, 0x700A, 0x9E62, + 0x700B, 0x9E63, 0x700C, 0x9E64, 0x700D, 0x9E65, 0x700E, 0x9E66, + 0x700F, 0x9E67, 0x7010, 0x9E68, 0x7011, 0xC6D9, 0x7012, 0x9E69, + 0x7013, 0x9E6A, 0x7014, 0x9E6B, 0x7015, 0x9E6C, 0x7016, 0x9E6D, + 0x7017, 0x9E6E, 0x7018, 0x9E6F, 0x7019, 0x9E70, 0x701A, 0xE5AB, + 0x701B, 0xE5AD, 0x701C, 0x9E71, 0x701D, 0x9E72, 0x701E, 0x9E73, + 0x701F, 0x9E74, 0x7020, 0x9E75, 0x7021, 0x9E76, 0x7022, 0x9E77, + 0x7023, 0xE5AC, 0x7024, 0x9E78, 0x7025, 0x9E79, 0x7026, 0x9E7A, + 0x7027, 0x9E7B, 0x7028, 0x9E7C, 0x7029, 0x9E7D, 0x702A, 0x9E7E, + 0x702B, 0x9E80, 0x702C, 0x9E81, 0x702D, 0x9E82, 0x702E, 0x9E83, + 0x702F, 0x9E84, 0x7030, 0x9E85, 0x7031, 0x9E86, 0x7032, 0x9E87, + 0x7033, 0x9E88, 0x7034, 0x9E89, 0x7035, 0xE5AF, 0x7036, 0x9E8A, + 0x7037, 0x9E8B, 0x7038, 0x9E8C, 0x7039, 0xE5AE, 0x703A, 0x9E8D, + 0x703B, 0x9E8E, 0x703C, 0x9E8F, 0x703D, 0x9E90, 0x703E, 0x9E91, + 0x703F, 0x9E92, 0x7040, 0x9E93, 0x7041, 0x9E94, 0x7042, 0x9E95, + 0x7043, 0x9E96, 0x7044, 0x9E97, 0x7045, 0x9E98, 0x7046, 0x9E99, + 0x7047, 0x9E9A, 0x7048, 0x9E9B, 0x7049, 0x9E9C, 0x704A, 0x9E9D, + 0x704B, 0x9E9E, 0x704C, 0xB9E0, 0x704D, 0x9E9F, 0x704E, 0x9EA0, + 0x704F, 0xE5B0, 0x7050, 0x9EA1, 0x7051, 0x9EA2, 0x7052, 0x9EA3, + 0x7053, 0x9EA4, 0x7054, 0x9EA5, 0x7055, 0x9EA6, 0x7056, 0x9EA7, + 0x7057, 0x9EA8, 0x7058, 0x9EA9, 0x7059, 0x9EAA, 0x705A, 0x9EAB, + 0x705B, 0x9EAC, 0x705C, 0x9EAD, 0x705D, 0x9EAE, 0x705E, 0xE5B1, + 0x705F, 0x9EAF, 0x7060, 0x9EB0, 0x7061, 0x9EB1, 0x7062, 0x9EB2, + 0x7063, 0x9EB3, 0x7064, 0x9EB4, 0x7065, 0x9EB5, 0x7066, 0x9EB6, + 0x7067, 0x9EB7, 0x7068, 0x9EB8, 0x7069, 0x9EB9, 0x706A, 0x9EBA, + 0x706B, 0xBBF0, 0x706C, 0xECE1, 0x706D, 0xC3F0, 0x706E, 0x9EBB, + 0x706F, 0xB5C6, 0x7070, 0xBBD2, 0x7071, 0x9EBC, 0x7072, 0x9EBD, + 0x7073, 0x9EBE, 0x7074, 0x9EBF, 0x7075, 0xC1E9, 0x7076, 0xD4EE, + 0x7077, 0x9EC0, 0x7078, 0xBEC4, 0x7079, 0x9EC1, 0x707A, 0x9EC2, + 0x707B, 0x9EC3, 0x707C, 0xD7C6, 0x707D, 0x9EC4, 0x707E, 0xD4D6, + 0x707F, 0xB2D3, 0x7080, 0xECBE, 0x7081, 0x9EC5, 0x7082, 0x9EC6, + 0x7083, 0x9EC7, 0x7084, 0x9EC8, 0x7085, 0xEAC1, 0x7086, 0x9EC9, + 0x7087, 0x9ECA, 0x7088, 0x9ECB, 0x7089, 0xC2AF, 0x708A, 0xB4B6, + 0x708B, 0x9ECC, 0x708C, 0x9ECD, 0x708D, 0x9ECE, 0x708E, 0xD1D7, + 0x708F, 0x9ECF, 0x7090, 0x9ED0, 0x7091, 0x9ED1, 0x7092, 0xB3B4, + 0x7093, 0x9ED2, 0x7094, 0xC8B2, 0x7095, 0xBFBB, 0x7096, 0xECC0, + 0x7097, 0x9ED3, 0x7098, 0x9ED4, 0x7099, 0xD6CB, 0x709A, 0x9ED5, + 0x709B, 0x9ED6, 0x709C, 0xECBF, 0x709D, 0xECC1, 0x709E, 0x9ED7, + 0x709F, 0x9ED8, 0x70A0, 0x9ED9, 0x70A1, 0x9EDA, 0x70A2, 0x9EDB, + 0x70A3, 0x9EDC, 0x70A4, 0x9EDD, 0x70A5, 0x9EDE, 0x70A6, 0x9EDF, + 0x70A7, 0x9EE0, 0x70A8, 0x9EE1, 0x70A9, 0x9EE2, 0x70AA, 0x9EE3, + 0x70AB, 0xECC5, 0x70AC, 0xBEE6, 0x70AD, 0xCCBF, 0x70AE, 0xC5DA, + 0x70AF, 0xBEBC, 0x70B0, 0x9EE4, 0x70B1, 0xECC6, 0x70B2, 0x9EE5, + 0x70B3, 0xB1FE, 0x70B4, 0x9EE6, 0x70B5, 0x9EE7, 0x70B6, 0x9EE8, + 0x70B7, 0xECC4, 0x70B8, 0xD5A8, 0x70B9, 0xB5E3, 0x70BA, 0x9EE9, + 0x70BB, 0xECC2, 0x70BC, 0xC1B6, 0x70BD, 0xB3E3, 0x70BE, 0x9EEA, + 0x70BF, 0x9EEB, 0x70C0, 0xECC3, 0x70C1, 0xCBB8, 0x70C2, 0xC0C3, + 0x70C3, 0xCCFE, 0x70C4, 0x9EEC, 0x70C5, 0x9EED, 0x70C6, 0x9EEE, + 0x70C7, 0x9EEF, 0x70C8, 0xC1D2, 0x70C9, 0x9EF0, 0x70CA, 0xECC8, + 0x70CB, 0x9EF1, 0x70CC, 0x9EF2, 0x70CD, 0x9EF3, 0x70CE, 0x9EF4, + 0x70CF, 0x9EF5, 0x70D0, 0x9EF6, 0x70D1, 0x9EF7, 0x70D2, 0x9EF8, + 0x70D3, 0x9EF9, 0x70D4, 0x9EFA, 0x70D5, 0x9EFB, 0x70D6, 0x9EFC, + 0x70D7, 0x9EFD, 0x70D8, 0xBAE6, 0x70D9, 0xC0D3, 0x70DA, 0x9EFE, + 0x70DB, 0xD6F2, 0x70DC, 0x9F40, 0x70DD, 0x9F41, 0x70DE, 0x9F42, + 0x70DF, 0xD1CC, 0x70E0, 0x9F43, 0x70E1, 0x9F44, 0x70E2, 0x9F45, + 0x70E3, 0x9F46, 0x70E4, 0xBFBE, 0x70E5, 0x9F47, 0x70E6, 0xB7B3, + 0x70E7, 0xC9D5, 0x70E8, 0xECC7, 0x70E9, 0xBBE2, 0x70EA, 0x9F48, + 0x70EB, 0xCCCC, 0x70EC, 0xBDFD, 0x70ED, 0xC8C8, 0x70EE, 0x9F49, + 0x70EF, 0xCFA9, 0x70F0, 0x9F4A, 0x70F1, 0x9F4B, 0x70F2, 0x9F4C, + 0x70F3, 0x9F4D, 0x70F4, 0x9F4E, 0x70F5, 0x9F4F, 0x70F6, 0x9F50, + 0x70F7, 0xCDE9, 0x70F8, 0x9F51, 0x70F9, 0xC5EB, 0x70FA, 0x9F52, + 0x70FB, 0x9F53, 0x70FC, 0x9F54, 0x70FD, 0xB7E9, 0x70FE, 0x9F55, + 0x70FF, 0x9F56, 0x7100, 0x9F57, 0x7101, 0x9F58, 0x7102, 0x9F59, + 0x7103, 0x9F5A, 0x7104, 0x9F5B, 0x7105, 0x9F5C, 0x7106, 0x9F5D, + 0x7107, 0x9F5E, 0x7108, 0x9F5F, 0x7109, 0xD1C9, 0x710A, 0xBAB8, + 0x710B, 0x9F60, 0x710C, 0x9F61, 0x710D, 0x9F62, 0x710E, 0x9F63, + 0x710F, 0x9F64, 0x7110, 0xECC9, 0x7111, 0x9F65, 0x7112, 0x9F66, + 0x7113, 0xECCA, 0x7114, 0x9F67, 0x7115, 0xBBC0, 0x7116, 0xECCB, + 0x7117, 0x9F68, 0x7118, 0xECE2, 0x7119, 0xB1BA, 0x711A, 0xB7D9, + 0x711B, 0x9F69, 0x711C, 0x9F6A, 0x711D, 0x9F6B, 0x711E, 0x9F6C, + 0x711F, 0x9F6D, 0x7120, 0x9F6E, 0x7121, 0x9F6F, 0x7122, 0x9F70, + 0x7123, 0x9F71, 0x7124, 0x9F72, 0x7125, 0x9F73, 0x7126, 0xBDB9, + 0x7127, 0x9F74, 0x7128, 0x9F75, 0x7129, 0x9F76, 0x712A, 0x9F77, + 0x712B, 0x9F78, 0x712C, 0x9F79, 0x712D, 0x9F7A, 0x712E, 0x9F7B, + 0x712F, 0xECCC, 0x7130, 0xD1E6, 0x7131, 0xECCD, 0x7132, 0x9F7C, + 0x7133, 0x9F7D, 0x7134, 0x9F7E, 0x7135, 0x9F80, 0x7136, 0xC8BB, + 0x7137, 0x9F81, 0x7138, 0x9F82, 0x7139, 0x9F83, 0x713A, 0x9F84, + 0x713B, 0x9F85, 0x713C, 0x9F86, 0x713D, 0x9F87, 0x713E, 0x9F88, + 0x713F, 0x9F89, 0x7140, 0x9F8A, 0x7141, 0x9F8B, 0x7142, 0x9F8C, + 0x7143, 0x9F8D, 0x7144, 0x9F8E, 0x7145, 0xECD1, 0x7146, 0x9F8F, + 0x7147, 0x9F90, 0x7148, 0x9F91, 0x7149, 0x9F92, 0x714A, 0xECD3, + 0x714B, 0x9F93, 0x714C, 0xBBCD, 0x714D, 0x9F94, 0x714E, 0xBCE5, + 0x714F, 0x9F95, 0x7150, 0x9F96, 0x7151, 0x9F97, 0x7152, 0x9F98, + 0x7153, 0x9F99, 0x7154, 0x9F9A, 0x7155, 0x9F9B, 0x7156, 0x9F9C, + 0x7157, 0x9F9D, 0x7158, 0x9F9E, 0x7159, 0x9F9F, 0x715A, 0x9FA0, + 0x715B, 0x9FA1, 0x715C, 0xECCF, 0x715D, 0x9FA2, 0x715E, 0xC9B7, + 0x715F, 0x9FA3, 0x7160, 0x9FA4, 0x7161, 0x9FA5, 0x7162, 0x9FA6, + 0x7163, 0x9FA7, 0x7164, 0xC3BA, 0x7165, 0x9FA8, 0x7166, 0xECE3, + 0x7167, 0xD5D5, 0x7168, 0xECD0, 0x7169, 0x9FA9, 0x716A, 0x9FAA, + 0x716B, 0x9FAB, 0x716C, 0x9FAC, 0x716D, 0x9FAD, 0x716E, 0xD6F3, + 0x716F, 0x9FAE, 0x7170, 0x9FAF, 0x7171, 0x9FB0, 0x7172, 0xECD2, + 0x7173, 0xECCE, 0x7174, 0x9FB1, 0x7175, 0x9FB2, 0x7176, 0x9FB3, + 0x7177, 0x9FB4, 0x7178, 0xECD4, 0x7179, 0x9FB5, 0x717A, 0xECD5, + 0x717B, 0x9FB6, 0x717C, 0x9FB7, 0x717D, 0xC9BF, 0x717E, 0x9FB8, + 0x717F, 0x9FB9, 0x7180, 0x9FBA, 0x7181, 0x9FBB, 0x7182, 0x9FBC, + 0x7183, 0x9FBD, 0x7184, 0xCFA8, 0x7185, 0x9FBE, 0x7186, 0x9FBF, + 0x7187, 0x9FC0, 0x7188, 0x9FC1, 0x7189, 0x9FC2, 0x718A, 0xD0DC, + 0x718B, 0x9FC3, 0x718C, 0x9FC4, 0x718D, 0x9FC5, 0x718E, 0x9FC6, + 0x718F, 0xD1AC, 0x7190, 0x9FC7, 0x7191, 0x9FC8, 0x7192, 0x9FC9, + 0x7193, 0x9FCA, 0x7194, 0xC8DB, 0x7195, 0x9FCB, 0x7196, 0x9FCC, + 0x7197, 0x9FCD, 0x7198, 0xECD6, 0x7199, 0xCEF5, 0x719A, 0x9FCE, + 0x719B, 0x9FCF, 0x719C, 0x9FD0, 0x719D, 0x9FD1, 0x719E, 0x9FD2, + 0x719F, 0xCAEC, 0x71A0, 0xECDA, 0x71A1, 0x9FD3, 0x71A2, 0x9FD4, + 0x71A3, 0x9FD5, 0x71A4, 0x9FD6, 0x71A5, 0x9FD7, 0x71A6, 0x9FD8, + 0x71A7, 0x9FD9, 0x71A8, 0xECD9, 0x71A9, 0x9FDA, 0x71AA, 0x9FDB, + 0x71AB, 0x9FDC, 0x71AC, 0xB0BE, 0x71AD, 0x9FDD, 0x71AE, 0x9FDE, + 0x71AF, 0x9FDF, 0x71B0, 0x9FE0, 0x71B1, 0x9FE1, 0x71B2, 0x9FE2, + 0x71B3, 0xECD7, 0x71B4, 0x9FE3, 0x71B5, 0xECD8, 0x71B6, 0x9FE4, + 0x71B7, 0x9FE5, 0x71B8, 0x9FE6, 0x71B9, 0xECE4, 0x71BA, 0x9FE7, + 0x71BB, 0x9FE8, 0x71BC, 0x9FE9, 0x71BD, 0x9FEA, 0x71BE, 0x9FEB, + 0x71BF, 0x9FEC, 0x71C0, 0x9FED, 0x71C1, 0x9FEE, 0x71C2, 0x9FEF, + 0x71C3, 0xC8BC, 0x71C4, 0x9FF0, 0x71C5, 0x9FF1, 0x71C6, 0x9FF2, + 0x71C7, 0x9FF3, 0x71C8, 0x9FF4, 0x71C9, 0x9FF5, 0x71CA, 0x9FF6, + 0x71CB, 0x9FF7, 0x71CC, 0x9FF8, 0x71CD, 0x9FF9, 0x71CE, 0xC1C7, + 0x71CF, 0x9FFA, 0x71D0, 0x9FFB, 0x71D1, 0x9FFC, 0x71D2, 0x9FFD, + 0x71D3, 0x9FFE, 0x71D4, 0xECDC, 0x71D5, 0xD1E0, 0x71D6, 0xA040, + 0x71D7, 0xA041, 0x71D8, 0xA042, 0x71D9, 0xA043, 0x71DA, 0xA044, + 0x71DB, 0xA045, 0x71DC, 0xA046, 0x71DD, 0xA047, 0x71DE, 0xA048, + 0x71DF, 0xA049, 0x71E0, 0xECDB, 0x71E1, 0xA04A, 0x71E2, 0xA04B, + 0x71E3, 0xA04C, 0x71E4, 0xA04D, 0x71E5, 0xD4EF, 0x71E6, 0xA04E, + 0x71E7, 0xECDD, 0x71E8, 0xA04F, 0x71E9, 0xA050, 0x71EA, 0xA051, + 0x71EB, 0xA052, 0x71EC, 0xA053, 0x71ED, 0xA054, 0x71EE, 0xDBC6, + 0x71EF, 0xA055, 0x71F0, 0xA056, 0x71F1, 0xA057, 0x71F2, 0xA058, + 0x71F3, 0xA059, 0x71F4, 0xA05A, 0x71F5, 0xA05B, 0x71F6, 0xA05C, + 0x71F7, 0xA05D, 0x71F8, 0xA05E, 0x71F9, 0xECDE, 0x71FA, 0xA05F, + 0x71FB, 0xA060, 0x71FC, 0xA061, 0x71FD, 0xA062, 0x71FE, 0xA063, + 0x71FF, 0xA064, 0x7200, 0xA065, 0x7201, 0xA066, 0x7202, 0xA067, + 0x7203, 0xA068, 0x7204, 0xA069, 0x7205, 0xA06A, 0x7206, 0xB1AC, + 0x7207, 0xA06B, 0x7208, 0xA06C, 0x7209, 0xA06D, 0x720A, 0xA06E, + 0x720B, 0xA06F, 0x720C, 0xA070, 0x720D, 0xA071, 0x720E, 0xA072, + 0x720F, 0xA073, 0x7210, 0xA074, 0x7211, 0xA075, 0x7212, 0xA076, + 0x7213, 0xA077, 0x7214, 0xA078, 0x7215, 0xA079, 0x7216, 0xA07A, + 0x7217, 0xA07B, 0x7218, 0xA07C, 0x7219, 0xA07D, 0x721A, 0xA07E, + 0x721B, 0xA080, 0x721C, 0xA081, 0x721D, 0xECDF, 0x721E, 0xA082, + 0x721F, 0xA083, 0x7220, 0xA084, 0x7221, 0xA085, 0x7222, 0xA086, + 0x7223, 0xA087, 0x7224, 0xA088, 0x7225, 0xA089, 0x7226, 0xA08A, + 0x7227, 0xA08B, 0x7228, 0xECE0, 0x7229, 0xA08C, 0x722A, 0xD7A6, + 0x722B, 0xA08D, 0x722C, 0xC5C0, 0x722D, 0xA08E, 0x722E, 0xA08F, + 0x722F, 0xA090, 0x7230, 0xEBBC, 0x7231, 0xB0AE, 0x7232, 0xA091, + 0x7233, 0xA092, 0x7234, 0xA093, 0x7235, 0xBEF4, 0x7236, 0xB8B8, + 0x7237, 0xD2AF, 0x7238, 0xB0D6, 0x7239, 0xB5F9, 0x723A, 0xA094, + 0x723B, 0xD8B3, 0x723C, 0xA095, 0x723D, 0xCBAC, 0x723E, 0xA096, + 0x723F, 0xE3DD, 0x7240, 0xA097, 0x7241, 0xA098, 0x7242, 0xA099, + 0x7243, 0xA09A, 0x7244, 0xA09B, 0x7245, 0xA09C, 0x7246, 0xA09D, + 0x7247, 0xC6AC, 0x7248, 0xB0E6, 0x7249, 0xA09E, 0x724A, 0xA09F, + 0x724B, 0xA0A0, 0x724C, 0xC5C6, 0x724D, 0xEBB9, 0x724E, 0xA0A1, + 0x724F, 0xA0A2, 0x7250, 0xA0A3, 0x7251, 0xA0A4, 0x7252, 0xEBBA, + 0x7253, 0xA0A5, 0x7254, 0xA0A6, 0x7255, 0xA0A7, 0x7256, 0xEBBB, + 0x7257, 0xA0A8, 0x7258, 0xA0A9, 0x7259, 0xD1C0, 0x725A, 0xA0AA, + 0x725B, 0xC5A3, 0x725C, 0xA0AB, 0x725D, 0xEAF2, 0x725E, 0xA0AC, + 0x725F, 0xC4B2, 0x7260, 0xA0AD, 0x7261, 0xC4B5, 0x7262, 0xC0CE, + 0x7263, 0xA0AE, 0x7264, 0xA0AF, 0x7265, 0xA0B0, 0x7266, 0xEAF3, + 0x7267, 0xC4C1, 0x7268, 0xA0B1, 0x7269, 0xCEEF, 0x726A, 0xA0B2, + 0x726B, 0xA0B3, 0x726C, 0xA0B4, 0x726D, 0xA0B5, 0x726E, 0xEAF0, + 0x726F, 0xEAF4, 0x7270, 0xA0B6, 0x7271, 0xA0B7, 0x7272, 0xC9FC, + 0x7273, 0xA0B8, 0x7274, 0xA0B9, 0x7275, 0xC7A3, 0x7276, 0xA0BA, + 0x7277, 0xA0BB, 0x7278, 0xA0BC, 0x7279, 0xCCD8, 0x727A, 0xCEFE, + 0x727B, 0xA0BD, 0x727C, 0xA0BE, 0x727D, 0xA0BF, 0x727E, 0xEAF5, + 0x727F, 0xEAF6, 0x7280, 0xCFAC, 0x7281, 0xC0E7, 0x7282, 0xA0C0, + 0x7283, 0xA0C1, 0x7284, 0xEAF7, 0x7285, 0xA0C2, 0x7286, 0xA0C3, + 0x7287, 0xA0C4, 0x7288, 0xA0C5, 0x7289, 0xA0C6, 0x728A, 0xB6BF, + 0x728B, 0xEAF8, 0x728C, 0xA0C7, 0x728D, 0xEAF9, 0x728E, 0xA0C8, + 0x728F, 0xEAFA, 0x7290, 0xA0C9, 0x7291, 0xA0CA, 0x7292, 0xEAFB, + 0x7293, 0xA0CB, 0x7294, 0xA0CC, 0x7295, 0xA0CD, 0x7296, 0xA0CE, + 0x7297, 0xA0CF, 0x7298, 0xA0D0, 0x7299, 0xA0D1, 0x729A, 0xA0D2, + 0x729B, 0xA0D3, 0x729C, 0xA0D4, 0x729D, 0xA0D5, 0x729E, 0xA0D6, + 0x729F, 0xEAF1, 0x72A0, 0xA0D7, 0x72A1, 0xA0D8, 0x72A2, 0xA0D9, + 0x72A3, 0xA0DA, 0x72A4, 0xA0DB, 0x72A5, 0xA0DC, 0x72A6, 0xA0DD, + 0x72A7, 0xA0DE, 0x72A8, 0xA0DF, 0x72A9, 0xA0E0, 0x72AA, 0xA0E1, + 0x72AB, 0xA0E2, 0x72AC, 0xC8AE, 0x72AD, 0xE1EB, 0x72AE, 0xA0E3, + 0x72AF, 0xB7B8, 0x72B0, 0xE1EC, 0x72B1, 0xA0E4, 0x72B2, 0xA0E5, + 0x72B3, 0xA0E6, 0x72B4, 0xE1ED, 0x72B5, 0xA0E7, 0x72B6, 0xD7B4, + 0x72B7, 0xE1EE, 0x72B8, 0xE1EF, 0x72B9, 0xD3CC, 0x72BA, 0xA0E8, + 0x72BB, 0xA0E9, 0x72BC, 0xA0EA, 0x72BD, 0xA0EB, 0x72BE, 0xA0EC, + 0x72BF, 0xA0ED, 0x72C0, 0xA0EE, 0x72C1, 0xE1F1, 0x72C2, 0xBFF1, + 0x72C3, 0xE1F0, 0x72C4, 0xB5D2, 0x72C5, 0xA0EF, 0x72C6, 0xA0F0, + 0x72C7, 0xA0F1, 0x72C8, 0xB1B7, 0x72C9, 0xA0F2, 0x72CA, 0xA0F3, + 0x72CB, 0xA0F4, 0x72CC, 0xA0F5, 0x72CD, 0xE1F3, 0x72CE, 0xE1F2, + 0x72CF, 0xA0F6, 0x72D0, 0xBAFC, 0x72D1, 0xA0F7, 0x72D2, 0xE1F4, + 0x72D3, 0xA0F8, 0x72D4, 0xA0F9, 0x72D5, 0xA0FA, 0x72D6, 0xA0FB, + 0x72D7, 0xB9B7, 0x72D8, 0xA0FC, 0x72D9, 0xBED1, 0x72DA, 0xA0FD, + 0x72DB, 0xA0FE, 0x72DC, 0xAA40, 0x72DD, 0xAA41, 0x72DE, 0xC4FC, + 0x72DF, 0xAA42, 0x72E0, 0xBADD, 0x72E1, 0xBDC6, 0x72E2, 0xAA43, + 0x72E3, 0xAA44, 0x72E4, 0xAA45, 0x72E5, 0xAA46, 0x72E6, 0xAA47, + 0x72E7, 0xAA48, 0x72E8, 0xE1F5, 0x72E9, 0xE1F7, 0x72EA, 0xAA49, + 0x72EB, 0xAA4A, 0x72EC, 0xB6C0, 0x72ED, 0xCFC1, 0x72EE, 0xCAA8, + 0x72EF, 0xE1F6, 0x72F0, 0xD5F8, 0x72F1, 0xD3FC, 0x72F2, 0xE1F8, + 0x72F3, 0xE1FC, 0x72F4, 0xE1F9, 0x72F5, 0xAA4B, 0x72F6, 0xAA4C, + 0x72F7, 0xE1FA, 0x72F8, 0xC0EA, 0x72F9, 0xAA4D, 0x72FA, 0xE1FE, + 0x72FB, 0xE2A1, 0x72FC, 0xC0C7, 0x72FD, 0xAA4E, 0x72FE, 0xAA4F, + 0x72FF, 0xAA50, 0x7300, 0xAA51, 0x7301, 0xE1FB, 0x7302, 0xAA52, + 0x7303, 0xE1FD, 0x7304, 0xAA53, 0x7305, 0xAA54, 0x7306, 0xAA55, + 0x7307, 0xAA56, 0x7308, 0xAA57, 0x7309, 0xAA58, 0x730A, 0xE2A5, + 0x730B, 0xAA59, 0x730C, 0xAA5A, 0x730D, 0xAA5B, 0x730E, 0xC1D4, + 0x730F, 0xAA5C, 0x7310, 0xAA5D, 0x7311, 0xAA5E, 0x7312, 0xAA5F, + 0x7313, 0xE2A3, 0x7314, 0xAA60, 0x7315, 0xE2A8, 0x7316, 0xB2FE, + 0x7317, 0xE2A2, 0x7318, 0xAA61, 0x7319, 0xAA62, 0x731A, 0xAA63, + 0x731B, 0xC3CD, 0x731C, 0xB2C2, 0x731D, 0xE2A7, 0x731E, 0xE2A6, + 0x731F, 0xAA64, 0x7320, 0xAA65, 0x7321, 0xE2A4, 0x7322, 0xE2A9, + 0x7323, 0xAA66, 0x7324, 0xAA67, 0x7325, 0xE2AB, 0x7326, 0xAA68, + 0x7327, 0xAA69, 0x7328, 0xAA6A, 0x7329, 0xD0C9, 0x732A, 0xD6ED, + 0x732B, 0xC3A8, 0x732C, 0xE2AC, 0x732D, 0xAA6B, 0x732E, 0xCFD7, + 0x732F, 0xAA6C, 0x7330, 0xAA6D, 0x7331, 0xE2AE, 0x7332, 0xAA6E, + 0x7333, 0xAA6F, 0x7334, 0xBAEF, 0x7335, 0xAA70, 0x7336, 0xAA71, + 0x7337, 0xE9E0, 0x7338, 0xE2AD, 0x7339, 0xE2AA, 0x733A, 0xAA72, + 0x733B, 0xAA73, 0x733C, 0xAA74, 0x733D, 0xAA75, 0x733E, 0xBBAB, + 0x733F, 0xD4B3, 0x7340, 0xAA76, 0x7341, 0xAA77, 0x7342, 0xAA78, + 0x7343, 0xAA79, 0x7344, 0xAA7A, 0x7345, 0xAA7B, 0x7346, 0xAA7C, + 0x7347, 0xAA7D, 0x7348, 0xAA7E, 0x7349, 0xAA80, 0x734A, 0xAA81, + 0x734B, 0xAA82, 0x734C, 0xAA83, 0x734D, 0xE2B0, 0x734E, 0xAA84, + 0x734F, 0xAA85, 0x7350, 0xE2AF, 0x7351, 0xAA86, 0x7352, 0xE9E1, + 0x7353, 0xAA87, 0x7354, 0xAA88, 0x7355, 0xAA89, 0x7356, 0xAA8A, + 0x7357, 0xE2B1, 0x7358, 0xAA8B, 0x7359, 0xAA8C, 0x735A, 0xAA8D, + 0x735B, 0xAA8E, 0x735C, 0xAA8F, 0x735D, 0xAA90, 0x735E, 0xAA91, + 0x735F, 0xAA92, 0x7360, 0xE2B2, 0x7361, 0xAA93, 0x7362, 0xAA94, + 0x7363, 0xAA95, 0x7364, 0xAA96, 0x7365, 0xAA97, 0x7366, 0xAA98, + 0x7367, 0xAA99, 0x7368, 0xAA9A, 0x7369, 0xAA9B, 0x736A, 0xAA9C, + 0x736B, 0xAA9D, 0x736C, 0xE2B3, 0x736D, 0xCCA1, 0x736E, 0xAA9E, + 0x736F, 0xE2B4, 0x7370, 0xAA9F, 0x7371, 0xAAA0, 0x7372, 0xAB40, + 0x7373, 0xAB41, 0x7374, 0xAB42, 0x7375, 0xAB43, 0x7376, 0xAB44, + 0x7377, 0xAB45, 0x7378, 0xAB46, 0x7379, 0xAB47, 0x737A, 0xAB48, + 0x737B, 0xAB49, 0x737C, 0xAB4A, 0x737D, 0xAB4B, 0x737E, 0xE2B5, + 0x737F, 0xAB4C, 0x7380, 0xAB4D, 0x7381, 0xAB4E, 0x7382, 0xAB4F, + 0x7383, 0xAB50, 0x7384, 0xD0FE, 0x7385, 0xAB51, 0x7386, 0xAB52, + 0x7387, 0xC2CA, 0x7388, 0xAB53, 0x7389, 0xD3F1, 0x738A, 0xAB54, + 0x738B, 0xCDF5, 0x738C, 0xAB55, 0x738D, 0xAB56, 0x738E, 0xE7E0, + 0x738F, 0xAB57, 0x7390, 0xAB58, 0x7391, 0xE7E1, 0x7392, 0xAB59, + 0x7393, 0xAB5A, 0x7394, 0xAB5B, 0x7395, 0xAB5C, 0x7396, 0xBEC1, + 0x7397, 0xAB5D, 0x7398, 0xAB5E, 0x7399, 0xAB5F, 0x739A, 0xAB60, + 0x739B, 0xC2EA, 0x739C, 0xAB61, 0x739D, 0xAB62, 0x739E, 0xAB63, + 0x739F, 0xE7E4, 0x73A0, 0xAB64, 0x73A1, 0xAB65, 0x73A2, 0xE7E3, + 0x73A3, 0xAB66, 0x73A4, 0xAB67, 0x73A5, 0xAB68, 0x73A6, 0xAB69, + 0x73A7, 0xAB6A, 0x73A8, 0xAB6B, 0x73A9, 0xCDE6, 0x73AA, 0xAB6C, + 0x73AB, 0xC3B5, 0x73AC, 0xAB6D, 0x73AD, 0xAB6E, 0x73AE, 0xE7E2, + 0x73AF, 0xBBB7, 0x73B0, 0xCFD6, 0x73B1, 0xAB6F, 0x73B2, 0xC1E1, + 0x73B3, 0xE7E9, 0x73B4, 0xAB70, 0x73B5, 0xAB71, 0x73B6, 0xAB72, + 0x73B7, 0xE7E8, 0x73B8, 0xAB73, 0x73B9, 0xAB74, 0x73BA, 0xE7F4, + 0x73BB, 0xB2A3, 0x73BC, 0xAB75, 0x73BD, 0xAB76, 0x73BE, 0xAB77, + 0x73BF, 0xAB78, 0x73C0, 0xE7EA, 0x73C1, 0xAB79, 0x73C2, 0xE7E6, + 0x73C3, 0xAB7A, 0x73C4, 0xAB7B, 0x73C5, 0xAB7C, 0x73C6, 0xAB7D, + 0x73C7, 0xAB7E, 0x73C8, 0xE7EC, 0x73C9, 0xE7EB, 0x73CA, 0xC9BA, + 0x73CB, 0xAB80, 0x73CC, 0xAB81, 0x73CD, 0xD5E4, 0x73CE, 0xAB82, + 0x73CF, 0xE7E5, 0x73D0, 0xB7A9, 0x73D1, 0xE7E7, 0x73D2, 0xAB83, + 0x73D3, 0xAB84, 0x73D4, 0xAB85, 0x73D5, 0xAB86, 0x73D6, 0xAB87, + 0x73D7, 0xAB88, 0x73D8, 0xAB89, 0x73D9, 0xE7EE, 0x73DA, 0xAB8A, + 0x73DB, 0xAB8B, 0x73DC, 0xAB8C, 0x73DD, 0xAB8D, 0x73DE, 0xE7F3, + 0x73DF, 0xAB8E, 0x73E0, 0xD6E9, 0x73E1, 0xAB8F, 0x73E2, 0xAB90, + 0x73E3, 0xAB91, 0x73E4, 0xAB92, 0x73E5, 0xE7ED, 0x73E6, 0xAB93, + 0x73E7, 0xE7F2, 0x73E8, 0xAB94, 0x73E9, 0xE7F1, 0x73EA, 0xAB95, + 0x73EB, 0xAB96, 0x73EC, 0xAB97, 0x73ED, 0xB0E0, 0x73EE, 0xAB98, + 0x73EF, 0xAB99, 0x73F0, 0xAB9A, 0x73F1, 0xAB9B, 0x73F2, 0xE7F5, + 0x73F3, 0xAB9C, 0x73F4, 0xAB9D, 0x73F5, 0xAB9E, 0x73F6, 0xAB9F, + 0x73F7, 0xABA0, 0x73F8, 0xAC40, 0x73F9, 0xAC41, 0x73FA, 0xAC42, + 0x73FB, 0xAC43, 0x73FC, 0xAC44, 0x73FD, 0xAC45, 0x73FE, 0xAC46, + 0x73FF, 0xAC47, 0x7400, 0xAC48, 0x7401, 0xAC49, 0x7402, 0xAC4A, + 0x7403, 0xC7F2, 0x7404, 0xAC4B, 0x7405, 0xC0C5, 0x7406, 0xC0ED, + 0x7407, 0xAC4C, 0x7408, 0xAC4D, 0x7409, 0xC1F0, 0x740A, 0xE7F0, + 0x740B, 0xAC4E, 0x740C, 0xAC4F, 0x740D, 0xAC50, 0x740E, 0xAC51, + 0x740F, 0xE7F6, 0x7410, 0xCBF6, 0x7411, 0xAC52, 0x7412, 0xAC53, + 0x7413, 0xAC54, 0x7414, 0xAC55, 0x7415, 0xAC56, 0x7416, 0xAC57, + 0x7417, 0xAC58, 0x7418, 0xAC59, 0x7419, 0xAC5A, 0x741A, 0xE8A2, + 0x741B, 0xE8A1, 0x741C, 0xAC5B, 0x741D, 0xAC5C, 0x741E, 0xAC5D, + 0x741F, 0xAC5E, 0x7420, 0xAC5F, 0x7421, 0xAC60, 0x7422, 0xD7C1, + 0x7423, 0xAC61, 0x7424, 0xAC62, 0x7425, 0xE7FA, 0x7426, 0xE7F9, + 0x7427, 0xAC63, 0x7428, 0xE7FB, 0x7429, 0xAC64, 0x742A, 0xE7F7, + 0x742B, 0xAC65, 0x742C, 0xE7FE, 0x742D, 0xAC66, 0x742E, 0xE7FD, + 0x742F, 0xAC67, 0x7430, 0xE7FC, 0x7431, 0xAC68, 0x7432, 0xAC69, + 0x7433, 0xC1D5, 0x7434, 0xC7D9, 0x7435, 0xC5FD, 0x7436, 0xC5C3, + 0x7437, 0xAC6A, 0x7438, 0xAC6B, 0x7439, 0xAC6C, 0x743A, 0xAC6D, + 0x743B, 0xAC6E, 0x743C, 0xC7ED, 0x743D, 0xAC6F, 0x743E, 0xAC70, + 0x743F, 0xAC71, 0x7440, 0xAC72, 0x7441, 0xE8A3, 0x7442, 0xAC73, + 0x7443, 0xAC74, 0x7444, 0xAC75, 0x7445, 0xAC76, 0x7446, 0xAC77, + 0x7447, 0xAC78, 0x7448, 0xAC79, 0x7449, 0xAC7A, 0x744A, 0xAC7B, + 0x744B, 0xAC7C, 0x744C, 0xAC7D, 0x744D, 0xAC7E, 0x744E, 0xAC80, + 0x744F, 0xAC81, 0x7450, 0xAC82, 0x7451, 0xAC83, 0x7452, 0xAC84, + 0x7453, 0xAC85, 0x7454, 0xAC86, 0x7455, 0xE8A6, 0x7456, 0xAC87, + 0x7457, 0xE8A5, 0x7458, 0xAC88, 0x7459, 0xE8A7, 0x745A, 0xBAF7, + 0x745B, 0xE7F8, 0x745C, 0xE8A4, 0x745D, 0xAC89, 0x745E, 0xC8F0, + 0x745F, 0xC9AA, 0x7460, 0xAC8A, 0x7461, 0xAC8B, 0x7462, 0xAC8C, + 0x7463, 0xAC8D, 0x7464, 0xAC8E, 0x7465, 0xAC8F, 0x7466, 0xAC90, + 0x7467, 0xAC91, 0x7468, 0xAC92, 0x7469, 0xAC93, 0x746A, 0xAC94, + 0x746B, 0xAC95, 0x746C, 0xAC96, 0x746D, 0xE8A9, 0x746E, 0xAC97, + 0x746F, 0xAC98, 0x7470, 0xB9E5, 0x7471, 0xAC99, 0x7472, 0xAC9A, + 0x7473, 0xAC9B, 0x7474, 0xAC9C, 0x7475, 0xAC9D, 0x7476, 0xD1FE, + 0x7477, 0xE8A8, 0x7478, 0xAC9E, 0x7479, 0xAC9F, 0x747A, 0xACA0, + 0x747B, 0xAD40, 0x747C, 0xAD41, 0x747D, 0xAD42, 0x747E, 0xE8AA, + 0x747F, 0xAD43, 0x7480, 0xE8AD, 0x7481, 0xE8AE, 0x7482, 0xAD44, + 0x7483, 0xC1A7, 0x7484, 0xAD45, 0x7485, 0xAD46, 0x7486, 0xAD47, + 0x7487, 0xE8AF, 0x7488, 0xAD48, 0x7489, 0xAD49, 0x748A, 0xAD4A, + 0x748B, 0xE8B0, 0x748C, 0xAD4B, 0x748D, 0xAD4C, 0x748E, 0xE8AC, + 0x748F, 0xAD4D, 0x7490, 0xE8B4, 0x7491, 0xAD4E, 0x7492, 0xAD4F, + 0x7493, 0xAD50, 0x7494, 0xAD51, 0x7495, 0xAD52, 0x7496, 0xAD53, + 0x7497, 0xAD54, 0x7498, 0xAD55, 0x7499, 0xAD56, 0x749A, 0xAD57, + 0x749B, 0xAD58, 0x749C, 0xE8AB, 0x749D, 0xAD59, 0x749E, 0xE8B1, + 0x749F, 0xAD5A, 0x74A0, 0xAD5B, 0x74A1, 0xAD5C, 0x74A2, 0xAD5D, + 0x74A3, 0xAD5E, 0x74A4, 0xAD5F, 0x74A5, 0xAD60, 0x74A6, 0xAD61, + 0x74A7, 0xE8B5, 0x74A8, 0xE8B2, 0x74A9, 0xE8B3, 0x74AA, 0xAD62, + 0x74AB, 0xAD63, 0x74AC, 0xAD64, 0x74AD, 0xAD65, 0x74AE, 0xAD66, + 0x74AF, 0xAD67, 0x74B0, 0xAD68, 0x74B1, 0xAD69, 0x74B2, 0xAD6A, + 0x74B3, 0xAD6B, 0x74B4, 0xAD6C, 0x74B5, 0xAD6D, 0x74B6, 0xAD6E, + 0x74B7, 0xAD6F, 0x74B8, 0xAD70, 0x74B9, 0xAD71, 0x74BA, 0xE8B7, + 0x74BB, 0xAD72, 0x74BC, 0xAD73, 0x74BD, 0xAD74, 0x74BE, 0xAD75, + 0x74BF, 0xAD76, 0x74C0, 0xAD77, 0x74C1, 0xAD78, 0x74C2, 0xAD79, + 0x74C3, 0xAD7A, 0x74C4, 0xAD7B, 0x74C5, 0xAD7C, 0x74C6, 0xAD7D, + 0x74C7, 0xAD7E, 0x74C8, 0xAD80, 0x74C9, 0xAD81, 0x74CA, 0xAD82, + 0x74CB, 0xAD83, 0x74CC, 0xAD84, 0x74CD, 0xAD85, 0x74CE, 0xAD86, + 0x74CF, 0xAD87, 0x74D0, 0xAD88, 0x74D1, 0xAD89, 0x74D2, 0xE8B6, + 0x74D3, 0xAD8A, 0x74D4, 0xAD8B, 0x74D5, 0xAD8C, 0x74D6, 0xAD8D, + 0x74D7, 0xAD8E, 0x74D8, 0xAD8F, 0x74D9, 0xAD90, 0x74DA, 0xAD91, + 0x74DB, 0xAD92, 0x74DC, 0xB9CF, 0x74DD, 0xAD93, 0x74DE, 0xF0AC, + 0x74DF, 0xAD94, 0x74E0, 0xF0AD, 0x74E1, 0xAD95, 0x74E2, 0xC6B0, + 0x74E3, 0xB0EA, 0x74E4, 0xC8BF, 0x74E5, 0xAD96, 0x74E6, 0xCDDF, + 0x74E7, 0xAD97, 0x74E8, 0xAD98, 0x74E9, 0xAD99, 0x74EA, 0xAD9A, + 0x74EB, 0xAD9B, 0x74EC, 0xAD9C, 0x74ED, 0xAD9D, 0x74EE, 0xCECD, + 0x74EF, 0xEAB1, 0x74F0, 0xAD9E, 0x74F1, 0xAD9F, 0x74F2, 0xADA0, + 0x74F3, 0xAE40, 0x74F4, 0xEAB2, 0x74F5, 0xAE41, 0x74F6, 0xC6BF, + 0x74F7, 0xB4C9, 0x74F8, 0xAE42, 0x74F9, 0xAE43, 0x74FA, 0xAE44, + 0x74FB, 0xAE45, 0x74FC, 0xAE46, 0x74FD, 0xAE47, 0x74FE, 0xAE48, + 0x74FF, 0xEAB3, 0x7500, 0xAE49, 0x7501, 0xAE4A, 0x7502, 0xAE4B, + 0x7503, 0xAE4C, 0x7504, 0xD5E7, 0x7505, 0xAE4D, 0x7506, 0xAE4E, + 0x7507, 0xAE4F, 0x7508, 0xAE50, 0x7509, 0xAE51, 0x750A, 0xAE52, + 0x750B, 0xAE53, 0x750C, 0xAE54, 0x750D, 0xDDF9, 0x750E, 0xAE55, + 0x750F, 0xEAB4, 0x7510, 0xAE56, 0x7511, 0xEAB5, 0x7512, 0xAE57, + 0x7513, 0xEAB6, 0x7514, 0xAE58, 0x7515, 0xAE59, 0x7516, 0xAE5A, + 0x7517, 0xAE5B, 0x7518, 0xB8CA, 0x7519, 0xDFB0, 0x751A, 0xC9F5, + 0x751B, 0xAE5C, 0x751C, 0xCCF0, 0x751D, 0xAE5D, 0x751E, 0xAE5E, + 0x751F, 0xC9FA, 0x7520, 0xAE5F, 0x7521, 0xAE60, 0x7522, 0xAE61, + 0x7523, 0xAE62, 0x7524, 0xAE63, 0x7525, 0xC9FB, 0x7526, 0xAE64, + 0x7527, 0xAE65, 0x7528, 0xD3C3, 0x7529, 0xCBA6, 0x752A, 0xAE66, + 0x752B, 0xB8A6, 0x752C, 0xF0AE, 0x752D, 0xB1C2, 0x752E, 0xAE67, + 0x752F, 0xE5B8, 0x7530, 0xCCEF, 0x7531, 0xD3C9, 0x7532, 0xBCD7, + 0x7533, 0xC9EA, 0x7534, 0xAE68, 0x7535, 0xB5E7, 0x7536, 0xAE69, + 0x7537, 0xC4D0, 0x7538, 0xB5E9, 0x7539, 0xAE6A, 0x753A, 0xEEAE, + 0x753B, 0xBBAD, 0x753C, 0xAE6B, 0x753D, 0xAE6C, 0x753E, 0xE7DE, + 0x753F, 0xAE6D, 0x7540, 0xEEAF, 0x7541, 0xAE6E, 0x7542, 0xAE6F, + 0x7543, 0xAE70, 0x7544, 0xAE71, 0x7545, 0xB3A9, 0x7546, 0xAE72, + 0x7547, 0xAE73, 0x7548, 0xEEB2, 0x7549, 0xAE74, 0x754A, 0xAE75, + 0x754B, 0xEEB1, 0x754C, 0xBDE7, 0x754D, 0xAE76, 0x754E, 0xEEB0, + 0x754F, 0xCEB7, 0x7550, 0xAE77, 0x7551, 0xAE78, 0x7552, 0xAE79, + 0x7553, 0xAE7A, 0x7554, 0xC5CF, 0x7555, 0xAE7B, 0x7556, 0xAE7C, + 0x7557, 0xAE7D, 0x7558, 0xAE7E, 0x7559, 0xC1F4, 0x755A, 0xDBCE, + 0x755B, 0xEEB3, 0x755C, 0xD0F3, 0x755D, 0xAE80, 0x755E, 0xAE81, + 0x755F, 0xAE82, 0x7560, 0xAE83, 0x7561, 0xAE84, 0x7562, 0xAE85, + 0x7563, 0xAE86, 0x7564, 0xAE87, 0x7565, 0xC2D4, 0x7566, 0xC6E8, + 0x7567, 0xAE88, 0x7568, 0xAE89, 0x7569, 0xAE8A, 0x756A, 0xB7AC, + 0x756B, 0xAE8B, 0x756C, 0xAE8C, 0x756D, 0xAE8D, 0x756E, 0xAE8E, + 0x756F, 0xAE8F, 0x7570, 0xAE90, 0x7571, 0xAE91, 0x7572, 0xEEB4, + 0x7573, 0xAE92, 0x7574, 0xB3EB, 0x7575, 0xAE93, 0x7576, 0xAE94, + 0x7577, 0xAE95, 0x7578, 0xBBFB, 0x7579, 0xEEB5, 0x757A, 0xAE96, + 0x757B, 0xAE97, 0x757C, 0xAE98, 0x757D, 0xAE99, 0x757E, 0xAE9A, + 0x757F, 0xE7DC, 0x7580, 0xAE9B, 0x7581, 0xAE9C, 0x7582, 0xAE9D, + 0x7583, 0xEEB6, 0x7584, 0xAE9E, 0x7585, 0xAE9F, 0x7586, 0xBDAE, + 0x7587, 0xAEA0, 0x7588, 0xAF40, 0x7589, 0xAF41, 0x758A, 0xAF42, + 0x758B, 0xF1E2, 0x758C, 0xAF43, 0x758D, 0xAF44, 0x758E, 0xAF45, + 0x758F, 0xCAE8, 0x7590, 0xAF46, 0x7591, 0xD2C9, 0x7592, 0xF0DA, + 0x7593, 0xAF47, 0x7594, 0xF0DB, 0x7595, 0xAF48, 0x7596, 0xF0DC, + 0x7597, 0xC1C6, 0x7598, 0xAF49, 0x7599, 0xB8ED, 0x759A, 0xBECE, + 0x759B, 0xAF4A, 0x759C, 0xAF4B, 0x759D, 0xF0DE, 0x759E, 0xAF4C, + 0x759F, 0xC5B1, 0x75A0, 0xF0DD, 0x75A1, 0xD1F1, 0x75A2, 0xAF4D, + 0x75A3, 0xF0E0, 0x75A4, 0xB0CC, 0x75A5, 0xBDEA, 0x75A6, 0xAF4E, + 0x75A7, 0xAF4F, 0x75A8, 0xAF50, 0x75A9, 0xAF51, 0x75AA, 0xAF52, + 0x75AB, 0xD2DF, 0x75AC, 0xF0DF, 0x75AD, 0xAF53, 0x75AE, 0xB4AF, + 0x75AF, 0xB7E8, 0x75B0, 0xF0E6, 0x75B1, 0xF0E5, 0x75B2, 0xC6A3, + 0x75B3, 0xF0E1, 0x75B4, 0xF0E2, 0x75B5, 0xB4C3, 0x75B6, 0xAF54, + 0x75B7, 0xAF55, 0x75B8, 0xF0E3, 0x75B9, 0xD5EE, 0x75BA, 0xAF56, + 0x75BB, 0xAF57, 0x75BC, 0xCCDB, 0x75BD, 0xBED2, 0x75BE, 0xBCB2, + 0x75BF, 0xAF58, 0x75C0, 0xAF59, 0x75C1, 0xAF5A, 0x75C2, 0xF0E8, + 0x75C3, 0xF0E7, 0x75C4, 0xF0E4, 0x75C5, 0xB2A1, 0x75C6, 0xAF5B, + 0x75C7, 0xD6A2, 0x75C8, 0xD3B8, 0x75C9, 0xBEB7, 0x75CA, 0xC8AC, + 0x75CB, 0xAF5C, 0x75CC, 0xAF5D, 0x75CD, 0xF0EA, 0x75CE, 0xAF5E, + 0x75CF, 0xAF5F, 0x75D0, 0xAF60, 0x75D1, 0xAF61, 0x75D2, 0xD1F7, + 0x75D3, 0xAF62, 0x75D4, 0xD6CC, 0x75D5, 0xBADB, 0x75D6, 0xF0E9, + 0x75D7, 0xAF63, 0x75D8, 0xB6BB, 0x75D9, 0xAF64, 0x75DA, 0xAF65, + 0x75DB, 0xCDB4, 0x75DC, 0xAF66, 0x75DD, 0xAF67, 0x75DE, 0xC6A6, + 0x75DF, 0xAF68, 0x75E0, 0xAF69, 0x75E1, 0xAF6A, 0x75E2, 0xC1A1, + 0x75E3, 0xF0EB, 0x75E4, 0xF0EE, 0x75E5, 0xAF6B, 0x75E6, 0xF0ED, + 0x75E7, 0xF0F0, 0x75E8, 0xF0EC, 0x75E9, 0xAF6C, 0x75EA, 0xBBBE, + 0x75EB, 0xF0EF, 0x75EC, 0xAF6D, 0x75ED, 0xAF6E, 0x75EE, 0xAF6F, + 0x75EF, 0xAF70, 0x75F0, 0xCCB5, 0x75F1, 0xF0F2, 0x75F2, 0xAF71, + 0x75F3, 0xAF72, 0x75F4, 0xB3D5, 0x75F5, 0xAF73, 0x75F6, 0xAF74, + 0x75F7, 0xAF75, 0x75F8, 0xAF76, 0x75F9, 0xB1D4, 0x75FA, 0xAF77, + 0x75FB, 0xAF78, 0x75FC, 0xF0F3, 0x75FD, 0xAF79, 0x75FE, 0xAF7A, + 0x75FF, 0xF0F4, 0x7600, 0xF0F6, 0x7601, 0xB4E1, 0x7602, 0xAF7B, + 0x7603, 0xF0F1, 0x7604, 0xAF7C, 0x7605, 0xF0F7, 0x7606, 0xAF7D, + 0x7607, 0xAF7E, 0x7608, 0xAF80, 0x7609, 0xAF81, 0x760A, 0xF0FA, + 0x760B, 0xAF82, 0x760C, 0xF0F8, 0x760D, 0xAF83, 0x760E, 0xAF84, + 0x760F, 0xAF85, 0x7610, 0xF0F5, 0x7611, 0xAF86, 0x7612, 0xAF87, + 0x7613, 0xAF88, 0x7614, 0xAF89, 0x7615, 0xF0FD, 0x7616, 0xAF8A, + 0x7617, 0xF0F9, 0x7618, 0xF0FC, 0x7619, 0xF0FE, 0x761A, 0xAF8B, + 0x761B, 0xF1A1, 0x761C, 0xAF8C, 0x761D, 0xAF8D, 0x761E, 0xAF8E, + 0x761F, 0xCEC1, 0x7620, 0xF1A4, 0x7621, 0xAF8F, 0x7622, 0xF1A3, + 0x7623, 0xAF90, 0x7624, 0xC1F6, 0x7625, 0xF0FB, 0x7626, 0xCADD, + 0x7627, 0xAF91, 0x7628, 0xAF92, 0x7629, 0xB4F1, 0x762A, 0xB1F1, + 0x762B, 0xCCB1, 0x762C, 0xAF93, 0x762D, 0xF1A6, 0x762E, 0xAF94, + 0x762F, 0xAF95, 0x7630, 0xF1A7, 0x7631, 0xAF96, 0x7632, 0xAF97, + 0x7633, 0xF1AC, 0x7634, 0xD5CE, 0x7635, 0xF1A9, 0x7636, 0xAF98, + 0x7637, 0xAF99, 0x7638, 0xC8B3, 0x7639, 0xAF9A, 0x763A, 0xAF9B, + 0x763B, 0xAF9C, 0x763C, 0xF1A2, 0x763D, 0xAF9D, 0x763E, 0xF1AB, + 0x763F, 0xF1A8, 0x7640, 0xF1A5, 0x7641, 0xAF9E, 0x7642, 0xAF9F, + 0x7643, 0xF1AA, 0x7644, 0xAFA0, 0x7645, 0xB040, 0x7646, 0xB041, + 0x7647, 0xB042, 0x7648, 0xB043, 0x7649, 0xB044, 0x764A, 0xB045, + 0x764B, 0xB046, 0x764C, 0xB0A9, 0x764D, 0xF1AD, 0x764E, 0xB047, + 0x764F, 0xB048, 0x7650, 0xB049, 0x7651, 0xB04A, 0x7652, 0xB04B, + 0x7653, 0xB04C, 0x7654, 0xF1AF, 0x7655, 0xB04D, 0x7656, 0xF1B1, + 0x7657, 0xB04E, 0x7658, 0xB04F, 0x7659, 0xB050, 0x765A, 0xB051, + 0x765B, 0xB052, 0x765C, 0xF1B0, 0x765D, 0xB053, 0x765E, 0xF1AE, + 0x765F, 0xB054, 0x7660, 0xB055, 0x7661, 0xB056, 0x7662, 0xB057, + 0x7663, 0xD1A2, 0x7664, 0xB058, 0x7665, 0xB059, 0x7666, 0xB05A, + 0x7667, 0xB05B, 0x7668, 0xB05C, 0x7669, 0xB05D, 0x766A, 0xB05E, + 0x766B, 0xF1B2, 0x766C, 0xB05F, 0x766D, 0xB060, 0x766E, 0xB061, + 0x766F, 0xF1B3, 0x7670, 0xB062, 0x7671, 0xB063, 0x7672, 0xB064, + 0x7673, 0xB065, 0x7674, 0xB066, 0x7675, 0xB067, 0x7676, 0xB068, + 0x7677, 0xB069, 0x7678, 0xB9EF, 0x7679, 0xB06A, 0x767A, 0xB06B, + 0x767B, 0xB5C7, 0x767C, 0xB06C, 0x767D, 0xB0D7, 0x767E, 0xB0D9, + 0x767F, 0xB06D, 0x7680, 0xB06E, 0x7681, 0xB06F, 0x7682, 0xD4ED, + 0x7683, 0xB070, 0x7684, 0xB5C4, 0x7685, 0xB071, 0x7686, 0xBDD4, + 0x7687, 0xBBCA, 0x7688, 0xF0A7, 0x7689, 0xB072, 0x768A, 0xB073, + 0x768B, 0xB8DE, 0x768C, 0xB074, 0x768D, 0xB075, 0x768E, 0xF0A8, + 0x768F, 0xB076, 0x7690, 0xB077, 0x7691, 0xB0A8, 0x7692, 0xB078, + 0x7693, 0xF0A9, 0x7694, 0xB079, 0x7695, 0xB07A, 0x7696, 0xCDEE, + 0x7697, 0xB07B, 0x7698, 0xB07C, 0x7699, 0xF0AA, 0x769A, 0xB07D, + 0x769B, 0xB07E, 0x769C, 0xB080, 0x769D, 0xB081, 0x769E, 0xB082, + 0x769F, 0xB083, 0x76A0, 0xB084, 0x76A1, 0xB085, 0x76A2, 0xB086, + 0x76A3, 0xB087, 0x76A4, 0xF0AB, 0x76A5, 0xB088, 0x76A6, 0xB089, + 0x76A7, 0xB08A, 0x76A8, 0xB08B, 0x76A9, 0xB08C, 0x76AA, 0xB08D, + 0x76AB, 0xB08E, 0x76AC, 0xB08F, 0x76AD, 0xB090, 0x76AE, 0xC6A4, + 0x76AF, 0xB091, 0x76B0, 0xB092, 0x76B1, 0xD6E5, 0x76B2, 0xF1E4, + 0x76B3, 0xB093, 0x76B4, 0xF1E5, 0x76B5, 0xB094, 0x76B6, 0xB095, + 0x76B7, 0xB096, 0x76B8, 0xB097, 0x76B9, 0xB098, 0x76BA, 0xB099, + 0x76BB, 0xB09A, 0x76BC, 0xB09B, 0x76BD, 0xB09C, 0x76BE, 0xB09D, + 0x76BF, 0xC3F3, 0x76C0, 0xB09E, 0x76C1, 0xB09F, 0x76C2, 0xD3DB, + 0x76C3, 0xB0A0, 0x76C4, 0xB140, 0x76C5, 0xD6D1, 0x76C6, 0xC5E8, + 0x76C7, 0xB141, 0x76C8, 0xD3AF, 0x76C9, 0xB142, 0x76CA, 0xD2E6, + 0x76CB, 0xB143, 0x76CC, 0xB144, 0x76CD, 0xEEC1, 0x76CE, 0xB0BB, + 0x76CF, 0xD5B5, 0x76D0, 0xD1CE, 0x76D1, 0xBCE0, 0x76D2, 0xBAD0, + 0x76D3, 0xB145, 0x76D4, 0xBFF8, 0x76D5, 0xB146, 0x76D6, 0xB8C7, + 0x76D7, 0xB5C1, 0x76D8, 0xC5CC, 0x76D9, 0xB147, 0x76DA, 0xB148, + 0x76DB, 0xCAA2, 0x76DC, 0xB149, 0x76DD, 0xB14A, 0x76DE, 0xB14B, + 0x76DF, 0xC3CB, 0x76E0, 0xB14C, 0x76E1, 0xB14D, 0x76E2, 0xB14E, + 0x76E3, 0xB14F, 0x76E4, 0xB150, 0x76E5, 0xEEC2, 0x76E6, 0xB151, + 0x76E7, 0xB152, 0x76E8, 0xB153, 0x76E9, 0xB154, 0x76EA, 0xB155, + 0x76EB, 0xB156, 0x76EC, 0xB157, 0x76ED, 0xB158, 0x76EE, 0xC4BF, + 0x76EF, 0xB6A2, 0x76F0, 0xB159, 0x76F1, 0xEDEC, 0x76F2, 0xC3A4, + 0x76F3, 0xB15A, 0x76F4, 0xD6B1, 0x76F5, 0xB15B, 0x76F6, 0xB15C, + 0x76F7, 0xB15D, 0x76F8, 0xCFE0, 0x76F9, 0xEDEF, 0x76FA, 0xB15E, + 0x76FB, 0xB15F, 0x76FC, 0xC5CE, 0x76FD, 0xB160, 0x76FE, 0xB6DC, + 0x76FF, 0xB161, 0x7700, 0xB162, 0x7701, 0xCAA1, 0x7702, 0xB163, + 0x7703, 0xB164, 0x7704, 0xEDED, 0x7705, 0xB165, 0x7706, 0xB166, + 0x7707, 0xEDF0, 0x7708, 0xEDF1, 0x7709, 0xC3BC, 0x770A, 0xB167, + 0x770B, 0xBFB4, 0x770C, 0xB168, 0x770D, 0xEDEE, 0x770E, 0xB169, + 0x770F, 0xB16A, 0x7710, 0xB16B, 0x7711, 0xB16C, 0x7712, 0xB16D, + 0x7713, 0xB16E, 0x7714, 0xB16F, 0x7715, 0xB170, 0x7716, 0xB171, + 0x7717, 0xB172, 0x7718, 0xB173, 0x7719, 0xEDF4, 0x771A, 0xEDF2, + 0x771B, 0xB174, 0x771C, 0xB175, 0x771D, 0xB176, 0x771E, 0xB177, + 0x771F, 0xD5E6, 0x7720, 0xC3DF, 0x7721, 0xB178, 0x7722, 0xEDF3, + 0x7723, 0xB179, 0x7724, 0xB17A, 0x7725, 0xB17B, 0x7726, 0xEDF6, + 0x7727, 0xB17C, 0x7728, 0xD5A3, 0x7729, 0xD1A3, 0x772A, 0xB17D, + 0x772B, 0xB17E, 0x772C, 0xB180, 0x772D, 0xEDF5, 0x772E, 0xB181, + 0x772F, 0xC3D0, 0x7730, 0xB182, 0x7731, 0xB183, 0x7732, 0xB184, + 0x7733, 0xB185, 0x7734, 0xB186, 0x7735, 0xEDF7, 0x7736, 0xBFF4, + 0x7737, 0xBEEC, 0x7738, 0xEDF8, 0x7739, 0xB187, 0x773A, 0xCCF7, + 0x773B, 0xB188, 0x773C, 0xD1DB, 0x773D, 0xB189, 0x773E, 0xB18A, + 0x773F, 0xB18B, 0x7740, 0xD7C5, 0x7741, 0xD5F6, 0x7742, 0xB18C, + 0x7743, 0xEDFC, 0x7744, 0xB18D, 0x7745, 0xB18E, 0x7746, 0xB18F, + 0x7747, 0xEDFB, 0x7748, 0xB190, 0x7749, 0xB191, 0x774A, 0xB192, + 0x774B, 0xB193, 0x774C, 0xB194, 0x774D, 0xB195, 0x774E, 0xB196, + 0x774F, 0xB197, 0x7750, 0xEDF9, 0x7751, 0xEDFA, 0x7752, 0xB198, + 0x7753, 0xB199, 0x7754, 0xB19A, 0x7755, 0xB19B, 0x7756, 0xB19C, + 0x7757, 0xB19D, 0x7758, 0xB19E, 0x7759, 0xB19F, 0x775A, 0xEDFD, + 0x775B, 0xBEA6, 0x775C, 0xB1A0, 0x775D, 0xB240, 0x775E, 0xB241, + 0x775F, 0xB242, 0x7760, 0xB243, 0x7761, 0xCBAF, 0x7762, 0xEEA1, + 0x7763, 0xB6BD, 0x7764, 0xB244, 0x7765, 0xEEA2, 0x7766, 0xC4C0, + 0x7767, 0xB245, 0x7768, 0xEDFE, 0x7769, 0xB246, 0x776A, 0xB247, + 0x776B, 0xBDDE, 0x776C, 0xB2C7, 0x776D, 0xB248, 0x776E, 0xB249, + 0x776F, 0xB24A, 0x7770, 0xB24B, 0x7771, 0xB24C, 0x7772, 0xB24D, + 0x7773, 0xB24E, 0x7774, 0xB24F, 0x7775, 0xB250, 0x7776, 0xB251, + 0x7777, 0xB252, 0x7778, 0xB253, 0x7779, 0xB6C3, 0x777A, 0xB254, + 0x777B, 0xB255, 0x777C, 0xB256, 0x777D, 0xEEA5, 0x777E, 0xD8BA, + 0x777F, 0xEEA3, 0x7780, 0xEEA6, 0x7781, 0xB257, 0x7782, 0xB258, + 0x7783, 0xB259, 0x7784, 0xC3E9, 0x7785, 0xB3F2, 0x7786, 0xB25A, + 0x7787, 0xB25B, 0x7788, 0xB25C, 0x7789, 0xB25D, 0x778A, 0xB25E, + 0x778B, 0xB25F, 0x778C, 0xEEA7, 0x778D, 0xEEA4, 0x778E, 0xCFB9, + 0x778F, 0xB260, 0x7790, 0xB261, 0x7791, 0xEEA8, 0x7792, 0xC2F7, + 0x7793, 0xB262, 0x7794, 0xB263, 0x7795, 0xB264, 0x7796, 0xB265, + 0x7797, 0xB266, 0x7798, 0xB267, 0x7799, 0xB268, 0x779A, 0xB269, + 0x779B, 0xB26A, 0x779C, 0xB26B, 0x779D, 0xB26C, 0x779E, 0xB26D, + 0x779F, 0xEEA9, 0x77A0, 0xEEAA, 0x77A1, 0xB26E, 0x77A2, 0xDEAB, + 0x77A3, 0xB26F, 0x77A4, 0xB270, 0x77A5, 0xC6B3, 0x77A6, 0xB271, + 0x77A7, 0xC7C6, 0x77A8, 0xB272, 0x77A9, 0xD6F5, 0x77AA, 0xB5C9, + 0x77AB, 0xB273, 0x77AC, 0xCBB2, 0x77AD, 0xB274, 0x77AE, 0xB275, + 0x77AF, 0xB276, 0x77B0, 0xEEAB, 0x77B1, 0xB277, 0x77B2, 0xB278, + 0x77B3, 0xCDAB, 0x77B4, 0xB279, 0x77B5, 0xEEAC, 0x77B6, 0xB27A, + 0x77B7, 0xB27B, 0x77B8, 0xB27C, 0x77B9, 0xB27D, 0x77BA, 0xB27E, + 0x77BB, 0xD5B0, 0x77BC, 0xB280, 0x77BD, 0xEEAD, 0x77BE, 0xB281, + 0x77BF, 0xF6C4, 0x77C0, 0xB282, 0x77C1, 0xB283, 0x77C2, 0xB284, + 0x77C3, 0xB285, 0x77C4, 0xB286, 0x77C5, 0xB287, 0x77C6, 0xB288, + 0x77C7, 0xB289, 0x77C8, 0xB28A, 0x77C9, 0xB28B, 0x77CA, 0xB28C, + 0x77CB, 0xB28D, 0x77CC, 0xB28E, 0x77CD, 0xDBC7, 0x77CE, 0xB28F, + 0x77CF, 0xB290, 0x77D0, 0xB291, 0x77D1, 0xB292, 0x77D2, 0xB293, + 0x77D3, 0xB294, 0x77D4, 0xB295, 0x77D5, 0xB296, 0x77D6, 0xB297, + 0x77D7, 0xB4A3, 0x77D8, 0xB298, 0x77D9, 0xB299, 0x77DA, 0xB29A, + 0x77DB, 0xC3AC, 0x77DC, 0xF1E6, 0x77DD, 0xB29B, 0x77DE, 0xB29C, + 0x77DF, 0xB29D, 0x77E0, 0xB29E, 0x77E1, 0xB29F, 0x77E2, 0xCAB8, + 0x77E3, 0xD2D3, 0x77E4, 0xB2A0, 0x77E5, 0xD6AA, 0x77E6, 0xB340, + 0x77E7, 0xEFF2, 0x77E8, 0xB341, 0x77E9, 0xBED8, 0x77EA, 0xB342, + 0x77EB, 0xBDC3, 0x77EC, 0xEFF3, 0x77ED, 0xB6CC, 0x77EE, 0xB0AB, + 0x77EF, 0xB343, 0x77F0, 0xB344, 0x77F1, 0xB345, 0x77F2, 0xB346, + 0x77F3, 0xCAAF, 0x77F4, 0xB347, 0x77F5, 0xB348, 0x77F6, 0xEDB6, + 0x77F7, 0xB349, 0x77F8, 0xEDB7, 0x77F9, 0xB34A, 0x77FA, 0xB34B, + 0x77FB, 0xB34C, 0x77FC, 0xB34D, 0x77FD, 0xCEF9, 0x77FE, 0xB7AF, + 0x77FF, 0xBFF3, 0x7800, 0xEDB8, 0x7801, 0xC2EB, 0x7802, 0xC9B0, + 0x7803, 0xB34E, 0x7804, 0xB34F, 0x7805, 0xB350, 0x7806, 0xB351, + 0x7807, 0xB352, 0x7808, 0xB353, 0x7809, 0xEDB9, 0x780A, 0xB354, + 0x780B, 0xB355, 0x780C, 0xC6F6, 0x780D, 0xBFB3, 0x780E, 0xB356, + 0x780F, 0xB357, 0x7810, 0xB358, 0x7811, 0xEDBC, 0x7812, 0xC5F8, + 0x7813, 0xB359, 0x7814, 0xD1D0, 0x7815, 0xB35A, 0x7816, 0xD7A9, + 0x7817, 0xEDBA, 0x7818, 0xEDBB, 0x7819, 0xB35B, 0x781A, 0xD1E2, + 0x781B, 0xB35C, 0x781C, 0xEDBF, 0x781D, 0xEDC0, 0x781E, 0xB35D, + 0x781F, 0xEDC4, 0x7820, 0xB35E, 0x7821, 0xB35F, 0x7822, 0xB360, + 0x7823, 0xEDC8, 0x7824, 0xB361, 0x7825, 0xEDC6, 0x7826, 0xEDCE, + 0x7827, 0xD5E8, 0x7828, 0xB362, 0x7829, 0xEDC9, 0x782A, 0xB363, + 0x782B, 0xB364, 0x782C, 0xEDC7, 0x782D, 0xEDBE, 0x782E, 0xB365, + 0x782F, 0xB366, 0x7830, 0xC5E9, 0x7831, 0xB367, 0x7832, 0xB368, + 0x7833, 0xB369, 0x7834, 0xC6C6, 0x7835, 0xB36A, 0x7836, 0xB36B, + 0x7837, 0xC9E9, 0x7838, 0xD4D2, 0x7839, 0xEDC1, 0x783A, 0xEDC2, + 0x783B, 0xEDC3, 0x783C, 0xEDC5, 0x783D, 0xB36C, 0x783E, 0xC0F9, + 0x783F, 0xB36D, 0x7840, 0xB4A1, 0x7841, 0xB36E, 0x7842, 0xB36F, + 0x7843, 0xB370, 0x7844, 0xB371, 0x7845, 0xB9E8, 0x7846, 0xB372, + 0x7847, 0xEDD0, 0x7848, 0xB373, 0x7849, 0xB374, 0x784A, 0xB375, + 0x784B, 0xB376, 0x784C, 0xEDD1, 0x784D, 0xB377, 0x784E, 0xEDCA, + 0x784F, 0xB378, 0x7850, 0xEDCF, 0x7851, 0xB379, 0x7852, 0xCEF8, + 0x7853, 0xB37A, 0x7854, 0xB37B, 0x7855, 0xCBB6, 0x7856, 0xEDCC, + 0x7857, 0xEDCD, 0x7858, 0xB37C, 0x7859, 0xB37D, 0x785A, 0xB37E, + 0x785B, 0xB380, 0x785C, 0xB381, 0x785D, 0xCFF5, 0x785E, 0xB382, + 0x785F, 0xB383, 0x7860, 0xB384, 0x7861, 0xB385, 0x7862, 0xB386, + 0x7863, 0xB387, 0x7864, 0xB388, 0x7865, 0xB389, 0x7866, 0xB38A, + 0x7867, 0xB38B, 0x7868, 0xB38C, 0x7869, 0xB38D, 0x786A, 0xEDD2, + 0x786B, 0xC1F2, 0x786C, 0xD3B2, 0x786D, 0xEDCB, 0x786E, 0xC8B7, + 0x786F, 0xB38E, 0x7870, 0xB38F, 0x7871, 0xB390, 0x7872, 0xB391, + 0x7873, 0xB392, 0x7874, 0xB393, 0x7875, 0xB394, 0x7876, 0xB395, + 0x7877, 0xBCEF, 0x7878, 0xB396, 0x7879, 0xB397, 0x787A, 0xB398, + 0x787B, 0xB399, 0x787C, 0xC5F0, 0x787D, 0xB39A, 0x787E, 0xB39B, + 0x787F, 0xB39C, 0x7880, 0xB39D, 0x7881, 0xB39E, 0x7882, 0xB39F, + 0x7883, 0xB3A0, 0x7884, 0xB440, 0x7885, 0xB441, 0x7886, 0xB442, + 0x7887, 0xEDD6, 0x7888, 0xB443, 0x7889, 0xB5EF, 0x788A, 0xB444, + 0x788B, 0xB445, 0x788C, 0xC2B5, 0x788D, 0xB0AD, 0x788E, 0xCBE9, + 0x788F, 0xB446, 0x7890, 0xB447, 0x7891, 0xB1AE, 0x7892, 0xB448, + 0x7893, 0xEDD4, 0x7894, 0xB449, 0x7895, 0xB44A, 0x7896, 0xB44B, + 0x7897, 0xCDEB, 0x7898, 0xB5E2, 0x7899, 0xB44C, 0x789A, 0xEDD5, + 0x789B, 0xEDD3, 0x789C, 0xEDD7, 0x789D, 0xB44D, 0x789E, 0xB44E, + 0x789F, 0xB5FA, 0x78A0, 0xB44F, 0x78A1, 0xEDD8, 0x78A2, 0xB450, + 0x78A3, 0xEDD9, 0x78A4, 0xB451, 0x78A5, 0xEDDC, 0x78A6, 0xB452, + 0x78A7, 0xB1CC, 0x78A8, 0xB453, 0x78A9, 0xB454, 0x78AA, 0xB455, + 0x78AB, 0xB456, 0x78AC, 0xB457, 0x78AD, 0xB458, 0x78AE, 0xB459, + 0x78AF, 0xB45A, 0x78B0, 0xC5F6, 0x78B1, 0xBCEE, 0x78B2, 0xEDDA, + 0x78B3, 0xCCBC, 0x78B4, 0xB2EA, 0x78B5, 0xB45B, 0x78B6, 0xB45C, + 0x78B7, 0xB45D, 0x78B8, 0xB45E, 0x78B9, 0xEDDB, 0x78BA, 0xB45F, + 0x78BB, 0xB460, 0x78BC, 0xB461, 0x78BD, 0xB462, 0x78BE, 0xC4EB, + 0x78BF, 0xB463, 0x78C0, 0xB464, 0x78C1, 0xB4C5, 0x78C2, 0xB465, + 0x78C3, 0xB466, 0x78C4, 0xB467, 0x78C5, 0xB0F5, 0x78C6, 0xB468, + 0x78C7, 0xB469, 0x78C8, 0xB46A, 0x78C9, 0xEDDF, 0x78CA, 0xC0DA, + 0x78CB, 0xB4E8, 0x78CC, 0xB46B, 0x78CD, 0xB46C, 0x78CE, 0xB46D, + 0x78CF, 0xB46E, 0x78D0, 0xC5CD, 0x78D1, 0xB46F, 0x78D2, 0xB470, + 0x78D3, 0xB471, 0x78D4, 0xEDDD, 0x78D5, 0xBFC4, 0x78D6, 0xB472, + 0x78D7, 0xB473, 0x78D8, 0xB474, 0x78D9, 0xEDDE, 0x78DA, 0xB475, + 0x78DB, 0xB476, 0x78DC, 0xB477, 0x78DD, 0xB478, 0x78DE, 0xB479, + 0x78DF, 0xB47A, 0x78E0, 0xB47B, 0x78E1, 0xB47C, 0x78E2, 0xB47D, + 0x78E3, 0xB47E, 0x78E4, 0xB480, 0x78E5, 0xB481, 0x78E6, 0xB482, + 0x78E7, 0xB483, 0x78E8, 0xC4A5, 0x78E9, 0xB484, 0x78EA, 0xB485, + 0x78EB, 0xB486, 0x78EC, 0xEDE0, 0x78ED, 0xB487, 0x78EE, 0xB488, + 0x78EF, 0xB489, 0x78F0, 0xB48A, 0x78F1, 0xB48B, 0x78F2, 0xEDE1, + 0x78F3, 0xB48C, 0x78F4, 0xEDE3, 0x78F5, 0xB48D, 0x78F6, 0xB48E, + 0x78F7, 0xC1D7, 0x78F8, 0xB48F, 0x78F9, 0xB490, 0x78FA, 0xBBC7, + 0x78FB, 0xB491, 0x78FC, 0xB492, 0x78FD, 0xB493, 0x78FE, 0xB494, + 0x78FF, 0xB495, 0x7900, 0xB496, 0x7901, 0xBDB8, 0x7902, 0xB497, + 0x7903, 0xB498, 0x7904, 0xB499, 0x7905, 0xEDE2, 0x7906, 0xB49A, + 0x7907, 0xB49B, 0x7908, 0xB49C, 0x7909, 0xB49D, 0x790A, 0xB49E, + 0x790B, 0xB49F, 0x790C, 0xB4A0, 0x790D, 0xB540, 0x790E, 0xB541, + 0x790F, 0xB542, 0x7910, 0xB543, 0x7911, 0xB544, 0x7912, 0xB545, + 0x7913, 0xEDE4, 0x7914, 0xB546, 0x7915, 0xB547, 0x7916, 0xB548, + 0x7917, 0xB549, 0x7918, 0xB54A, 0x7919, 0xB54B, 0x791A, 0xB54C, + 0x791B, 0xB54D, 0x791C, 0xB54E, 0x791D, 0xB54F, 0x791E, 0xEDE6, + 0x791F, 0xB550, 0x7920, 0xB551, 0x7921, 0xB552, 0x7922, 0xB553, + 0x7923, 0xB554, 0x7924, 0xEDE5, 0x7925, 0xB555, 0x7926, 0xB556, + 0x7927, 0xB557, 0x7928, 0xB558, 0x7929, 0xB559, 0x792A, 0xB55A, + 0x792B, 0xB55B, 0x792C, 0xB55C, 0x792D, 0xB55D, 0x792E, 0xB55E, + 0x792F, 0xB55F, 0x7930, 0xB560, 0x7931, 0xB561, 0x7932, 0xB562, + 0x7933, 0xB563, 0x7934, 0xEDE7, 0x7935, 0xB564, 0x7936, 0xB565, + 0x7937, 0xB566, 0x7938, 0xB567, 0x7939, 0xB568, 0x793A, 0xCABE, + 0x793B, 0xECEA, 0x793C, 0xC0F1, 0x793D, 0xB569, 0x793E, 0xC9E7, + 0x793F, 0xB56A, 0x7940, 0xECEB, 0x7941, 0xC6EE, 0x7942, 0xB56B, + 0x7943, 0xB56C, 0x7944, 0xB56D, 0x7945, 0xB56E, 0x7946, 0xECEC, + 0x7947, 0xB56F, 0x7948, 0xC6ED, 0x7949, 0xECED, 0x794A, 0xB570, + 0x794B, 0xB571, 0x794C, 0xB572, 0x794D, 0xB573, 0x794E, 0xB574, + 0x794F, 0xB575, 0x7950, 0xB576, 0x7951, 0xB577, 0x7952, 0xB578, + 0x7953, 0xECF0, 0x7954, 0xB579, 0x7955, 0xB57A, 0x7956, 0xD7E6, + 0x7957, 0xECF3, 0x7958, 0xB57B, 0x7959, 0xB57C, 0x795A, 0xECF1, + 0x795B, 0xECEE, 0x795C, 0xECEF, 0x795D, 0xD7A3, 0x795E, 0xC9F1, + 0x795F, 0xCBEE, 0x7960, 0xECF4, 0x7961, 0xB57D, 0x7962, 0xECF2, + 0x7963, 0xB57E, 0x7964, 0xB580, 0x7965, 0xCFE9, 0x7966, 0xB581, + 0x7967, 0xECF6, 0x7968, 0xC6B1, 0x7969, 0xB582, 0x796A, 0xB583, + 0x796B, 0xB584, 0x796C, 0xB585, 0x796D, 0xBCC0, 0x796E, 0xB586, + 0x796F, 0xECF5, 0x7970, 0xB587, 0x7971, 0xB588, 0x7972, 0xB589, + 0x7973, 0xB58A, 0x7974, 0xB58B, 0x7975, 0xB58C, 0x7976, 0xB58D, + 0x7977, 0xB5BB, 0x7978, 0xBBF6, 0x7979, 0xB58E, 0x797A, 0xECF7, + 0x797B, 0xB58F, 0x797C, 0xB590, 0x797D, 0xB591, 0x797E, 0xB592, + 0x797F, 0xB593, 0x7980, 0xD9F7, 0x7981, 0xBDFB, 0x7982, 0xB594, + 0x7983, 0xB595, 0x7984, 0xC2BB, 0x7985, 0xECF8, 0x7986, 0xB596, + 0x7987, 0xB597, 0x7988, 0xB598, 0x7989, 0xB599, 0x798A, 0xECF9, + 0x798B, 0xB59A, 0x798C, 0xB59B, 0x798D, 0xB59C, 0x798E, 0xB59D, + 0x798F, 0xB8A3, 0x7990, 0xB59E, 0x7991, 0xB59F, 0x7992, 0xB5A0, + 0x7993, 0xB640, 0x7994, 0xB641, 0x7995, 0xB642, 0x7996, 0xB643, + 0x7997, 0xB644, 0x7998, 0xB645, 0x7999, 0xB646, 0x799A, 0xECFA, + 0x799B, 0xB647, 0x799C, 0xB648, 0x799D, 0xB649, 0x799E, 0xB64A, + 0x799F, 0xB64B, 0x79A0, 0xB64C, 0x79A1, 0xB64D, 0x79A2, 0xB64E, + 0x79A3, 0xB64F, 0x79A4, 0xB650, 0x79A5, 0xB651, 0x79A6, 0xB652, + 0x79A7, 0xECFB, 0x79A8, 0xB653, 0x79A9, 0xB654, 0x79AA, 0xB655, + 0x79AB, 0xB656, 0x79AC, 0xB657, 0x79AD, 0xB658, 0x79AE, 0xB659, + 0x79AF, 0xB65A, 0x79B0, 0xB65B, 0x79B1, 0xB65C, 0x79B2, 0xB65D, + 0x79B3, 0xECFC, 0x79B4, 0xB65E, 0x79B5, 0xB65F, 0x79B6, 0xB660, + 0x79B7, 0xB661, 0x79B8, 0xB662, 0x79B9, 0xD3ED, 0x79BA, 0xD8AE, + 0x79BB, 0xC0EB, 0x79BC, 0xB663, 0x79BD, 0xC7DD, 0x79BE, 0xBACC, + 0x79BF, 0xB664, 0x79C0, 0xD0E3, 0x79C1, 0xCBBD, 0x79C2, 0xB665, + 0x79C3, 0xCDBA, 0x79C4, 0xB666, 0x79C5, 0xB667, 0x79C6, 0xB8D1, + 0x79C7, 0xB668, 0x79C8, 0xB669, 0x79C9, 0xB1FC, 0x79CA, 0xB66A, + 0x79CB, 0xC7EF, 0x79CC, 0xB66B, 0x79CD, 0xD6D6, 0x79CE, 0xB66C, + 0x79CF, 0xB66D, 0x79D0, 0xB66E, 0x79D1, 0xBFC6, 0x79D2, 0xC3EB, + 0x79D3, 0xB66F, 0x79D4, 0xB670, 0x79D5, 0xEFF5, 0x79D6, 0xB671, + 0x79D7, 0xB672, 0x79D8, 0xC3D8, 0x79D9, 0xB673, 0x79DA, 0xB674, + 0x79DB, 0xB675, 0x79DC, 0xB676, 0x79DD, 0xB677, 0x79DE, 0xB678, + 0x79DF, 0xD7E2, 0x79E0, 0xB679, 0x79E1, 0xB67A, 0x79E2, 0xB67B, + 0x79E3, 0xEFF7, 0x79E4, 0xB3D3, 0x79E5, 0xB67C, 0x79E6, 0xC7D8, + 0x79E7, 0xD1ED, 0x79E8, 0xB67D, 0x79E9, 0xD6C8, 0x79EA, 0xB67E, + 0x79EB, 0xEFF8, 0x79EC, 0xB680, 0x79ED, 0xEFF6, 0x79EE, 0xB681, + 0x79EF, 0xBBFD, 0x79F0, 0xB3C6, 0x79F1, 0xB682, 0x79F2, 0xB683, + 0x79F3, 0xB684, 0x79F4, 0xB685, 0x79F5, 0xB686, 0x79F6, 0xB687, + 0x79F7, 0xB688, 0x79F8, 0xBDD5, 0x79F9, 0xB689, 0x79FA, 0xB68A, + 0x79FB, 0xD2C6, 0x79FC, 0xB68B, 0x79FD, 0xBBE0, 0x79FE, 0xB68C, + 0x79FF, 0xB68D, 0x7A00, 0xCFA1, 0x7A01, 0xB68E, 0x7A02, 0xEFFC, + 0x7A03, 0xEFFB, 0x7A04, 0xB68F, 0x7A05, 0xB690, 0x7A06, 0xEFF9, + 0x7A07, 0xB691, 0x7A08, 0xB692, 0x7A09, 0xB693, 0x7A0A, 0xB694, + 0x7A0B, 0xB3CC, 0x7A0C, 0xB695, 0x7A0D, 0xC9D4, 0x7A0E, 0xCBB0, + 0x7A0F, 0xB696, 0x7A10, 0xB697, 0x7A11, 0xB698, 0x7A12, 0xB699, + 0x7A13, 0xB69A, 0x7A14, 0xEFFE, 0x7A15, 0xB69B, 0x7A16, 0xB69C, + 0x7A17, 0xB0DE, 0x7A18, 0xB69D, 0x7A19, 0xB69E, 0x7A1A, 0xD6C9, + 0x7A1B, 0xB69F, 0x7A1C, 0xB6A0, 0x7A1D, 0xB740, 0x7A1E, 0xEFFD, + 0x7A1F, 0xB741, 0x7A20, 0xB3ED, 0x7A21, 0xB742, 0x7A22, 0xB743, + 0x7A23, 0xF6D5, 0x7A24, 0xB744, 0x7A25, 0xB745, 0x7A26, 0xB746, + 0x7A27, 0xB747, 0x7A28, 0xB748, 0x7A29, 0xB749, 0x7A2A, 0xB74A, + 0x7A2B, 0xB74B, 0x7A2C, 0xB74C, 0x7A2D, 0xB74D, 0x7A2E, 0xB74E, + 0x7A2F, 0xB74F, 0x7A30, 0xB750, 0x7A31, 0xB751, 0x7A32, 0xB752, + 0x7A33, 0xCEC8, 0x7A34, 0xB753, 0x7A35, 0xB754, 0x7A36, 0xB755, + 0x7A37, 0xF0A2, 0x7A38, 0xB756, 0x7A39, 0xF0A1, 0x7A3A, 0xB757, + 0x7A3B, 0xB5BE, 0x7A3C, 0xBCDA, 0x7A3D, 0xBBFC, 0x7A3E, 0xB758, + 0x7A3F, 0xB8E5, 0x7A40, 0xB759, 0x7A41, 0xB75A, 0x7A42, 0xB75B, + 0x7A43, 0xB75C, 0x7A44, 0xB75D, 0x7A45, 0xB75E, 0x7A46, 0xC4C2, + 0x7A47, 0xB75F, 0x7A48, 0xB760, 0x7A49, 0xB761, 0x7A4A, 0xB762, + 0x7A4B, 0xB763, 0x7A4C, 0xB764, 0x7A4D, 0xB765, 0x7A4E, 0xB766, + 0x7A4F, 0xB767, 0x7A50, 0xB768, 0x7A51, 0xF0A3, 0x7A52, 0xB769, + 0x7A53, 0xB76A, 0x7A54, 0xB76B, 0x7A55, 0xB76C, 0x7A56, 0xB76D, + 0x7A57, 0xCBEB, 0x7A58, 0xB76E, 0x7A59, 0xB76F, 0x7A5A, 0xB770, + 0x7A5B, 0xB771, 0x7A5C, 0xB772, 0x7A5D, 0xB773, 0x7A5E, 0xB774, + 0x7A5F, 0xB775, 0x7A60, 0xB776, 0x7A61, 0xB777, 0x7A62, 0xB778, + 0x7A63, 0xB779, 0x7A64, 0xB77A, 0x7A65, 0xB77B, 0x7A66, 0xB77C, + 0x7A67, 0xB77D, 0x7A68, 0xB77E, 0x7A69, 0xB780, 0x7A6A, 0xB781, + 0x7A6B, 0xB782, 0x7A6C, 0xB783, 0x7A6D, 0xB784, 0x7A6E, 0xB785, + 0x7A6F, 0xB786, 0x7A70, 0xF0A6, 0x7A71, 0xB787, 0x7A72, 0xB788, + 0x7A73, 0xB789, 0x7A74, 0xD1A8, 0x7A75, 0xB78A, 0x7A76, 0xBEBF, + 0x7A77, 0xC7EE, 0x7A78, 0xF1B6, 0x7A79, 0xF1B7, 0x7A7A, 0xBFD5, + 0x7A7B, 0xB78B, 0x7A7C, 0xB78C, 0x7A7D, 0xB78D, 0x7A7E, 0xB78E, + 0x7A7F, 0xB4A9, 0x7A80, 0xF1B8, 0x7A81, 0xCDBB, 0x7A82, 0xB78F, + 0x7A83, 0xC7D4, 0x7A84, 0xD5AD, 0x7A85, 0xB790, 0x7A86, 0xF1B9, + 0x7A87, 0xB791, 0x7A88, 0xF1BA, 0x7A89, 0xB792, 0x7A8A, 0xB793, + 0x7A8B, 0xB794, 0x7A8C, 0xB795, 0x7A8D, 0xC7CF, 0x7A8E, 0xB796, + 0x7A8F, 0xB797, 0x7A90, 0xB798, 0x7A91, 0xD2A4, 0x7A92, 0xD6CF, + 0x7A93, 0xB799, 0x7A94, 0xB79A, 0x7A95, 0xF1BB, 0x7A96, 0xBDD1, + 0x7A97, 0xB4B0, 0x7A98, 0xBEBD, 0x7A99, 0xB79B, 0x7A9A, 0xB79C, + 0x7A9B, 0xB79D, 0x7A9C, 0xB4DC, 0x7A9D, 0xCED1, 0x7A9E, 0xB79E, + 0x7A9F, 0xBFDF, 0x7AA0, 0xF1BD, 0x7AA1, 0xB79F, 0x7AA2, 0xB7A0, + 0x7AA3, 0xB840, 0x7AA4, 0xB841, 0x7AA5, 0xBFFA, 0x7AA6, 0xF1BC, + 0x7AA7, 0xB842, 0x7AA8, 0xF1BF, 0x7AA9, 0xB843, 0x7AAA, 0xB844, + 0x7AAB, 0xB845, 0x7AAC, 0xF1BE, 0x7AAD, 0xF1C0, 0x7AAE, 0xB846, + 0x7AAF, 0xB847, 0x7AB0, 0xB848, 0x7AB1, 0xB849, 0x7AB2, 0xB84A, + 0x7AB3, 0xF1C1, 0x7AB4, 0xB84B, 0x7AB5, 0xB84C, 0x7AB6, 0xB84D, + 0x7AB7, 0xB84E, 0x7AB8, 0xB84F, 0x7AB9, 0xB850, 0x7ABA, 0xB851, + 0x7ABB, 0xB852, 0x7ABC, 0xB853, 0x7ABD, 0xB854, 0x7ABE, 0xB855, + 0x7ABF, 0xC1FE, 0x7AC0, 0xB856, 0x7AC1, 0xB857, 0x7AC2, 0xB858, + 0x7AC3, 0xB859, 0x7AC4, 0xB85A, 0x7AC5, 0xB85B, 0x7AC6, 0xB85C, + 0x7AC7, 0xB85D, 0x7AC8, 0xB85E, 0x7AC9, 0xB85F, 0x7ACA, 0xB860, + 0x7ACB, 0xC1A2, 0x7ACC, 0xB861, 0x7ACD, 0xB862, 0x7ACE, 0xB863, + 0x7ACF, 0xB864, 0x7AD0, 0xB865, 0x7AD1, 0xB866, 0x7AD2, 0xB867, + 0x7AD3, 0xB868, 0x7AD4, 0xB869, 0x7AD5, 0xB86A, 0x7AD6, 0xCAFA, + 0x7AD7, 0xB86B, 0x7AD8, 0xB86C, 0x7AD9, 0xD5BE, 0x7ADA, 0xB86D, + 0x7ADB, 0xB86E, 0x7ADC, 0xB86F, 0x7ADD, 0xB870, 0x7ADE, 0xBEBA, + 0x7ADF, 0xBEB9, 0x7AE0, 0xD5C2, 0x7AE1, 0xB871, 0x7AE2, 0xB872, + 0x7AE3, 0xBFA2, 0x7AE4, 0xB873, 0x7AE5, 0xCDAF, 0x7AE6, 0xF1B5, + 0x7AE7, 0xB874, 0x7AE8, 0xB875, 0x7AE9, 0xB876, 0x7AEA, 0xB877, + 0x7AEB, 0xB878, 0x7AEC, 0xB879, 0x7AED, 0xBDDF, 0x7AEE, 0xB87A, + 0x7AEF, 0xB6CB, 0x7AF0, 0xB87B, 0x7AF1, 0xB87C, 0x7AF2, 0xB87D, + 0x7AF3, 0xB87E, 0x7AF4, 0xB880, 0x7AF5, 0xB881, 0x7AF6, 0xB882, + 0x7AF7, 0xB883, 0x7AF8, 0xB884, 0x7AF9, 0xD6F1, 0x7AFA, 0xF3C3, + 0x7AFB, 0xB885, 0x7AFC, 0xB886, 0x7AFD, 0xF3C4, 0x7AFE, 0xB887, + 0x7AFF, 0xB8CD, 0x7B00, 0xB888, 0x7B01, 0xB889, 0x7B02, 0xB88A, + 0x7B03, 0xF3C6, 0x7B04, 0xF3C7, 0x7B05, 0xB88B, 0x7B06, 0xB0CA, + 0x7B07, 0xB88C, 0x7B08, 0xF3C5, 0x7B09, 0xB88D, 0x7B0A, 0xF3C9, + 0x7B0B, 0xCBF1, 0x7B0C, 0xB88E, 0x7B0D, 0xB88F, 0x7B0E, 0xB890, + 0x7B0F, 0xF3CB, 0x7B10, 0xB891, 0x7B11, 0xD0A6, 0x7B12, 0xB892, + 0x7B13, 0xB893, 0x7B14, 0xB1CA, 0x7B15, 0xF3C8, 0x7B16, 0xB894, + 0x7B17, 0xB895, 0x7B18, 0xB896, 0x7B19, 0xF3CF, 0x7B1A, 0xB897, + 0x7B1B, 0xB5D1, 0x7B1C, 0xB898, 0x7B1D, 0xB899, 0x7B1E, 0xF3D7, + 0x7B1F, 0xB89A, 0x7B20, 0xF3D2, 0x7B21, 0xB89B, 0x7B22, 0xB89C, + 0x7B23, 0xB89D, 0x7B24, 0xF3D4, 0x7B25, 0xF3D3, 0x7B26, 0xB7FB, + 0x7B27, 0xB89E, 0x7B28, 0xB1BF, 0x7B29, 0xB89F, 0x7B2A, 0xF3CE, + 0x7B2B, 0xF3CA, 0x7B2C, 0xB5DA, 0x7B2D, 0xB8A0, 0x7B2E, 0xF3D0, + 0x7B2F, 0xB940, 0x7B30, 0xB941, 0x7B31, 0xF3D1, 0x7B32, 0xB942, + 0x7B33, 0xF3D5, 0x7B34, 0xB943, 0x7B35, 0xB944, 0x7B36, 0xB945, + 0x7B37, 0xB946, 0x7B38, 0xF3CD, 0x7B39, 0xB947, 0x7B3A, 0xBCE3, + 0x7B3B, 0xB948, 0x7B3C, 0xC1FD, 0x7B3D, 0xB949, 0x7B3E, 0xF3D6, + 0x7B3F, 0xB94A, 0x7B40, 0xB94B, 0x7B41, 0xB94C, 0x7B42, 0xB94D, + 0x7B43, 0xB94E, 0x7B44, 0xB94F, 0x7B45, 0xF3DA, 0x7B46, 0xB950, + 0x7B47, 0xF3CC, 0x7B48, 0xB951, 0x7B49, 0xB5C8, 0x7B4A, 0xB952, + 0x7B4B, 0xBDEE, 0x7B4C, 0xF3DC, 0x7B4D, 0xB953, 0x7B4E, 0xB954, + 0x7B4F, 0xB7A4, 0x7B50, 0xBFF0, 0x7B51, 0xD6FE, 0x7B52, 0xCDB2, + 0x7B53, 0xB955, 0x7B54, 0xB4F0, 0x7B55, 0xB956, 0x7B56, 0xB2DF, + 0x7B57, 0xB957, 0x7B58, 0xF3D8, 0x7B59, 0xB958, 0x7B5A, 0xF3D9, + 0x7B5B, 0xC9B8, 0x7B5C, 0xB959, 0x7B5D, 0xF3DD, 0x7B5E, 0xB95A, + 0x7B5F, 0xB95B, 0x7B60, 0xF3DE, 0x7B61, 0xB95C, 0x7B62, 0xF3E1, + 0x7B63, 0xB95D, 0x7B64, 0xB95E, 0x7B65, 0xB95F, 0x7B66, 0xB960, + 0x7B67, 0xB961, 0x7B68, 0xB962, 0x7B69, 0xB963, 0x7B6A, 0xB964, + 0x7B6B, 0xB965, 0x7B6C, 0xB966, 0x7B6D, 0xB967, 0x7B6E, 0xF3DF, + 0x7B6F, 0xB968, 0x7B70, 0xB969, 0x7B71, 0xF3E3, 0x7B72, 0xF3E2, + 0x7B73, 0xB96A, 0x7B74, 0xB96B, 0x7B75, 0xF3DB, 0x7B76, 0xB96C, + 0x7B77, 0xBFEA, 0x7B78, 0xB96D, 0x7B79, 0xB3EF, 0x7B7A, 0xB96E, + 0x7B7B, 0xF3E0, 0x7B7C, 0xB96F, 0x7B7D, 0xB970, 0x7B7E, 0xC7A9, + 0x7B7F, 0xB971, 0x7B80, 0xBCF2, 0x7B81, 0xB972, 0x7B82, 0xB973, + 0x7B83, 0xB974, 0x7B84, 0xB975, 0x7B85, 0xF3EB, 0x7B86, 0xB976, + 0x7B87, 0xB977, 0x7B88, 0xB978, 0x7B89, 0xB979, 0x7B8A, 0xB97A, + 0x7B8B, 0xB97B, 0x7B8C, 0xB97C, 0x7B8D, 0xB9BF, 0x7B8E, 0xB97D, + 0x7B8F, 0xB97E, 0x7B90, 0xF3E4, 0x7B91, 0xB980, 0x7B92, 0xB981, + 0x7B93, 0xB982, 0x7B94, 0xB2AD, 0x7B95, 0xBBFE, 0x7B96, 0xB983, + 0x7B97, 0xCBE3, 0x7B98, 0xB984, 0x7B99, 0xB985, 0x7B9A, 0xB986, + 0x7B9B, 0xB987, 0x7B9C, 0xF3ED, 0x7B9D, 0xF3E9, 0x7B9E, 0xB988, + 0x7B9F, 0xB989, 0x7BA0, 0xB98A, 0x7BA1, 0xB9DC, 0x7BA2, 0xF3EE, + 0x7BA3, 0xB98B, 0x7BA4, 0xB98C, 0x7BA5, 0xB98D, 0x7BA6, 0xF3E5, + 0x7BA7, 0xF3E6, 0x7BA8, 0xF3EA, 0x7BA9, 0xC2E1, 0x7BAA, 0xF3EC, + 0x7BAB, 0xF3EF, 0x7BAC, 0xF3E8, 0x7BAD, 0xBCFD, 0x7BAE, 0xB98E, + 0x7BAF, 0xB98F, 0x7BB0, 0xB990, 0x7BB1, 0xCFE4, 0x7BB2, 0xB991, + 0x7BB3, 0xB992, 0x7BB4, 0xF3F0, 0x7BB5, 0xB993, 0x7BB6, 0xB994, + 0x7BB7, 0xB995, 0x7BB8, 0xF3E7, 0x7BB9, 0xB996, 0x7BBA, 0xB997, + 0x7BBB, 0xB998, 0x7BBC, 0xB999, 0x7BBD, 0xB99A, 0x7BBE, 0xB99B, + 0x7BBF, 0xB99C, 0x7BC0, 0xB99D, 0x7BC1, 0xF3F2, 0x7BC2, 0xB99E, + 0x7BC3, 0xB99F, 0x7BC4, 0xB9A0, 0x7BC5, 0xBA40, 0x7BC6, 0xD7AD, + 0x7BC7, 0xC6AA, 0x7BC8, 0xBA41, 0x7BC9, 0xBA42, 0x7BCA, 0xBA43, + 0x7BCB, 0xBA44, 0x7BCC, 0xF3F3, 0x7BCD, 0xBA45, 0x7BCE, 0xBA46, + 0x7BCF, 0xBA47, 0x7BD0, 0xBA48, 0x7BD1, 0xF3F1, 0x7BD2, 0xBA49, + 0x7BD3, 0xC2A8, 0x7BD4, 0xBA4A, 0x7BD5, 0xBA4B, 0x7BD6, 0xBA4C, + 0x7BD7, 0xBA4D, 0x7BD8, 0xBA4E, 0x7BD9, 0xB8DD, 0x7BDA, 0xF3F5, + 0x7BDB, 0xBA4F, 0x7BDC, 0xBA50, 0x7BDD, 0xF3F4, 0x7BDE, 0xBA51, + 0x7BDF, 0xBA52, 0x7BE0, 0xBA53, 0x7BE1, 0xB4DB, 0x7BE2, 0xBA54, + 0x7BE3, 0xBA55, 0x7BE4, 0xBA56, 0x7BE5, 0xF3F6, 0x7BE6, 0xF3F7, + 0x7BE7, 0xBA57, 0x7BE8, 0xBA58, 0x7BE9, 0xBA59, 0x7BEA, 0xF3F8, + 0x7BEB, 0xBA5A, 0x7BEC, 0xBA5B, 0x7BED, 0xBA5C, 0x7BEE, 0xC0BA, + 0x7BEF, 0xBA5D, 0x7BF0, 0xBA5E, 0x7BF1, 0xC0E9, 0x7BF2, 0xBA5F, + 0x7BF3, 0xBA60, 0x7BF4, 0xBA61, 0x7BF5, 0xBA62, 0x7BF6, 0xBA63, + 0x7BF7, 0xC5F1, 0x7BF8, 0xBA64, 0x7BF9, 0xBA65, 0x7BFA, 0xBA66, + 0x7BFB, 0xBA67, 0x7BFC, 0xF3FB, 0x7BFD, 0xBA68, 0x7BFE, 0xF3FA, + 0x7BFF, 0xBA69, 0x7C00, 0xBA6A, 0x7C01, 0xBA6B, 0x7C02, 0xBA6C, + 0x7C03, 0xBA6D, 0x7C04, 0xBA6E, 0x7C05, 0xBA6F, 0x7C06, 0xBA70, + 0x7C07, 0xB4D8, 0x7C08, 0xBA71, 0x7C09, 0xBA72, 0x7C0A, 0xBA73, + 0x7C0B, 0xF3FE, 0x7C0C, 0xF3F9, 0x7C0D, 0xBA74, 0x7C0E, 0xBA75, + 0x7C0F, 0xF3FC, 0x7C10, 0xBA76, 0x7C11, 0xBA77, 0x7C12, 0xBA78, + 0x7C13, 0xBA79, 0x7C14, 0xBA7A, 0x7C15, 0xBA7B, 0x7C16, 0xF3FD, + 0x7C17, 0xBA7C, 0x7C18, 0xBA7D, 0x7C19, 0xBA7E, 0x7C1A, 0xBA80, + 0x7C1B, 0xBA81, 0x7C1C, 0xBA82, 0x7C1D, 0xBA83, 0x7C1E, 0xBA84, + 0x7C1F, 0xF4A1, 0x7C20, 0xBA85, 0x7C21, 0xBA86, 0x7C22, 0xBA87, + 0x7C23, 0xBA88, 0x7C24, 0xBA89, 0x7C25, 0xBA8A, 0x7C26, 0xF4A3, + 0x7C27, 0xBBC9, 0x7C28, 0xBA8B, 0x7C29, 0xBA8C, 0x7C2A, 0xF4A2, + 0x7C2B, 0xBA8D, 0x7C2C, 0xBA8E, 0x7C2D, 0xBA8F, 0x7C2E, 0xBA90, + 0x7C2F, 0xBA91, 0x7C30, 0xBA92, 0x7C31, 0xBA93, 0x7C32, 0xBA94, + 0x7C33, 0xBA95, 0x7C34, 0xBA96, 0x7C35, 0xBA97, 0x7C36, 0xBA98, + 0x7C37, 0xBA99, 0x7C38, 0xF4A4, 0x7C39, 0xBA9A, 0x7C3A, 0xBA9B, + 0x7C3B, 0xBA9C, 0x7C3C, 0xBA9D, 0x7C3D, 0xBA9E, 0x7C3E, 0xBA9F, + 0x7C3F, 0xB2BE, 0x7C40, 0xF4A6, 0x7C41, 0xF4A5, 0x7C42, 0xBAA0, + 0x7C43, 0xBB40, 0x7C44, 0xBB41, 0x7C45, 0xBB42, 0x7C46, 0xBB43, + 0x7C47, 0xBB44, 0x7C48, 0xBB45, 0x7C49, 0xBB46, 0x7C4A, 0xBB47, + 0x7C4B, 0xBB48, 0x7C4C, 0xBB49, 0x7C4D, 0xBCAE, 0x7C4E, 0xBB4A, + 0x7C4F, 0xBB4B, 0x7C50, 0xBB4C, 0x7C51, 0xBB4D, 0x7C52, 0xBB4E, + 0x7C53, 0xBB4F, 0x7C54, 0xBB50, 0x7C55, 0xBB51, 0x7C56, 0xBB52, + 0x7C57, 0xBB53, 0x7C58, 0xBB54, 0x7C59, 0xBB55, 0x7C5A, 0xBB56, + 0x7C5B, 0xBB57, 0x7C5C, 0xBB58, 0x7C5D, 0xBB59, 0x7C5E, 0xBB5A, + 0x7C5F, 0xBB5B, 0x7C60, 0xBB5C, 0x7C61, 0xBB5D, 0x7C62, 0xBB5E, + 0x7C63, 0xBB5F, 0x7C64, 0xBB60, 0x7C65, 0xBB61, 0x7C66, 0xBB62, + 0x7C67, 0xBB63, 0x7C68, 0xBB64, 0x7C69, 0xBB65, 0x7C6A, 0xBB66, + 0x7C6B, 0xBB67, 0x7C6C, 0xBB68, 0x7C6D, 0xBB69, 0x7C6E, 0xBB6A, + 0x7C6F, 0xBB6B, 0x7C70, 0xBB6C, 0x7C71, 0xBB6D, 0x7C72, 0xBB6E, + 0x7C73, 0xC3D7, 0x7C74, 0xD9E1, 0x7C75, 0xBB6F, 0x7C76, 0xBB70, + 0x7C77, 0xBB71, 0x7C78, 0xBB72, 0x7C79, 0xBB73, 0x7C7A, 0xBB74, + 0x7C7B, 0xC0E0, 0x7C7C, 0xF4CC, 0x7C7D, 0xD7D1, 0x7C7E, 0xBB75, + 0x7C7F, 0xBB76, 0x7C80, 0xBB77, 0x7C81, 0xBB78, 0x7C82, 0xBB79, + 0x7C83, 0xBB7A, 0x7C84, 0xBB7B, 0x7C85, 0xBB7C, 0x7C86, 0xBB7D, + 0x7C87, 0xBB7E, 0x7C88, 0xBB80, 0x7C89, 0xB7DB, 0x7C8A, 0xBB81, + 0x7C8B, 0xBB82, 0x7C8C, 0xBB83, 0x7C8D, 0xBB84, 0x7C8E, 0xBB85, + 0x7C8F, 0xBB86, 0x7C90, 0xBB87, 0x7C91, 0xF4CE, 0x7C92, 0xC1A3, + 0x7C93, 0xBB88, 0x7C94, 0xBB89, 0x7C95, 0xC6C9, 0x7C96, 0xBB8A, + 0x7C97, 0xB4D6, 0x7C98, 0xD5B3, 0x7C99, 0xBB8B, 0x7C9A, 0xBB8C, + 0x7C9B, 0xBB8D, 0x7C9C, 0xF4D0, 0x7C9D, 0xF4CF, 0x7C9E, 0xF4D1, + 0x7C9F, 0xCBDA, 0x7CA0, 0xBB8E, 0x7CA1, 0xBB8F, 0x7CA2, 0xF4D2, + 0x7CA3, 0xBB90, 0x7CA4, 0xD4C1, 0x7CA5, 0xD6E0, 0x7CA6, 0xBB91, + 0x7CA7, 0xBB92, 0x7CA8, 0xBB93, 0x7CA9, 0xBB94, 0x7CAA, 0xB7E0, + 0x7CAB, 0xBB95, 0x7CAC, 0xBB96, 0x7CAD, 0xBB97, 0x7CAE, 0xC1B8, + 0x7CAF, 0xBB98, 0x7CB0, 0xBB99, 0x7CB1, 0xC1BB, 0x7CB2, 0xF4D3, + 0x7CB3, 0xBEAC, 0x7CB4, 0xBB9A, 0x7CB5, 0xBB9B, 0x7CB6, 0xBB9C, + 0x7CB7, 0xBB9D, 0x7CB8, 0xBB9E, 0x7CB9, 0xB4E2, 0x7CBA, 0xBB9F, + 0x7CBB, 0xBBA0, 0x7CBC, 0xF4D4, 0x7CBD, 0xF4D5, 0x7CBE, 0xBEAB, + 0x7CBF, 0xBC40, 0x7CC0, 0xBC41, 0x7CC1, 0xF4D6, 0x7CC2, 0xBC42, + 0x7CC3, 0xBC43, 0x7CC4, 0xBC44, 0x7CC5, 0xF4DB, 0x7CC6, 0xBC45, + 0x7CC7, 0xF4D7, 0x7CC8, 0xF4DA, 0x7CC9, 0xBC46, 0x7CCA, 0xBAFD, + 0x7CCB, 0xBC47, 0x7CCC, 0xF4D8, 0x7CCD, 0xF4D9, 0x7CCE, 0xBC48, + 0x7CCF, 0xBC49, 0x7CD0, 0xBC4A, 0x7CD1, 0xBC4B, 0x7CD2, 0xBC4C, + 0x7CD3, 0xBC4D, 0x7CD4, 0xBC4E, 0x7CD5, 0xB8E2, 0x7CD6, 0xCCC7, + 0x7CD7, 0xF4DC, 0x7CD8, 0xBC4F, 0x7CD9, 0xB2DA, 0x7CDA, 0xBC50, + 0x7CDB, 0xBC51, 0x7CDC, 0xC3D3, 0x7CDD, 0xBC52, 0x7CDE, 0xBC53, + 0x7CDF, 0xD4E3, 0x7CE0, 0xBFB7, 0x7CE1, 0xBC54, 0x7CE2, 0xBC55, + 0x7CE3, 0xBC56, 0x7CE4, 0xBC57, 0x7CE5, 0xBC58, 0x7CE6, 0xBC59, + 0x7CE7, 0xBC5A, 0x7CE8, 0xF4DD, 0x7CE9, 0xBC5B, 0x7CEA, 0xBC5C, + 0x7CEB, 0xBC5D, 0x7CEC, 0xBC5E, 0x7CED, 0xBC5F, 0x7CEE, 0xBC60, + 0x7CEF, 0xC5B4, 0x7CF0, 0xBC61, 0x7CF1, 0xBC62, 0x7CF2, 0xBC63, + 0x7CF3, 0xBC64, 0x7CF4, 0xBC65, 0x7CF5, 0xBC66, 0x7CF6, 0xBC67, + 0x7CF7, 0xBC68, 0x7CF8, 0xF4E9, 0x7CF9, 0xBC69, 0x7CFA, 0xBC6A, + 0x7CFB, 0xCFB5, 0x7CFC, 0xBC6B, 0x7CFD, 0xBC6C, 0x7CFE, 0xBC6D, + 0x7CFF, 0xBC6E, 0x7D00, 0xBC6F, 0x7D01, 0xBC70, 0x7D02, 0xBC71, + 0x7D03, 0xBC72, 0x7D04, 0xBC73, 0x7D05, 0xBC74, 0x7D06, 0xBC75, + 0x7D07, 0xBC76, 0x7D08, 0xBC77, 0x7D09, 0xBC78, 0x7D0A, 0xCEC9, + 0x7D0B, 0xBC79, 0x7D0C, 0xBC7A, 0x7D0D, 0xBC7B, 0x7D0E, 0xBC7C, + 0x7D0F, 0xBC7D, 0x7D10, 0xBC7E, 0x7D11, 0xBC80, 0x7D12, 0xBC81, + 0x7D13, 0xBC82, 0x7D14, 0xBC83, 0x7D15, 0xBC84, 0x7D16, 0xBC85, + 0x7D17, 0xBC86, 0x7D18, 0xBC87, 0x7D19, 0xBC88, 0x7D1A, 0xBC89, + 0x7D1B, 0xBC8A, 0x7D1C, 0xBC8B, 0x7D1D, 0xBC8C, 0x7D1E, 0xBC8D, + 0x7D1F, 0xBC8E, 0x7D20, 0xCBD8, 0x7D21, 0xBC8F, 0x7D22, 0xCBF7, + 0x7D23, 0xBC90, 0x7D24, 0xBC91, 0x7D25, 0xBC92, 0x7D26, 0xBC93, + 0x7D27, 0xBDF4, 0x7D28, 0xBC94, 0x7D29, 0xBC95, 0x7D2A, 0xBC96, + 0x7D2B, 0xD7CF, 0x7D2C, 0xBC97, 0x7D2D, 0xBC98, 0x7D2E, 0xBC99, + 0x7D2F, 0xC0DB, 0x7D30, 0xBC9A, 0x7D31, 0xBC9B, 0x7D32, 0xBC9C, + 0x7D33, 0xBC9D, 0x7D34, 0xBC9E, 0x7D35, 0xBC9F, 0x7D36, 0xBCA0, + 0x7D37, 0xBD40, 0x7D38, 0xBD41, 0x7D39, 0xBD42, 0x7D3A, 0xBD43, + 0x7D3B, 0xBD44, 0x7D3C, 0xBD45, 0x7D3D, 0xBD46, 0x7D3E, 0xBD47, + 0x7D3F, 0xBD48, 0x7D40, 0xBD49, 0x7D41, 0xBD4A, 0x7D42, 0xBD4B, + 0x7D43, 0xBD4C, 0x7D44, 0xBD4D, 0x7D45, 0xBD4E, 0x7D46, 0xBD4F, + 0x7D47, 0xBD50, 0x7D48, 0xBD51, 0x7D49, 0xBD52, 0x7D4A, 0xBD53, + 0x7D4B, 0xBD54, 0x7D4C, 0xBD55, 0x7D4D, 0xBD56, 0x7D4E, 0xBD57, + 0x7D4F, 0xBD58, 0x7D50, 0xBD59, 0x7D51, 0xBD5A, 0x7D52, 0xBD5B, + 0x7D53, 0xBD5C, 0x7D54, 0xBD5D, 0x7D55, 0xBD5E, 0x7D56, 0xBD5F, + 0x7D57, 0xBD60, 0x7D58, 0xBD61, 0x7D59, 0xBD62, 0x7D5A, 0xBD63, + 0x7D5B, 0xBD64, 0x7D5C, 0xBD65, 0x7D5D, 0xBD66, 0x7D5E, 0xBD67, + 0x7D5F, 0xBD68, 0x7D60, 0xBD69, 0x7D61, 0xBD6A, 0x7D62, 0xBD6B, + 0x7D63, 0xBD6C, 0x7D64, 0xBD6D, 0x7D65, 0xBD6E, 0x7D66, 0xBD6F, + 0x7D67, 0xBD70, 0x7D68, 0xBD71, 0x7D69, 0xBD72, 0x7D6A, 0xBD73, + 0x7D6B, 0xBD74, 0x7D6C, 0xBD75, 0x7D6D, 0xBD76, 0x7D6E, 0xD0F5, + 0x7D6F, 0xBD77, 0x7D70, 0xBD78, 0x7D71, 0xBD79, 0x7D72, 0xBD7A, + 0x7D73, 0xBD7B, 0x7D74, 0xBD7C, 0x7D75, 0xBD7D, 0x7D76, 0xBD7E, + 0x7D77, 0xF4EA, 0x7D78, 0xBD80, 0x7D79, 0xBD81, 0x7D7A, 0xBD82, + 0x7D7B, 0xBD83, 0x7D7C, 0xBD84, 0x7D7D, 0xBD85, 0x7D7E, 0xBD86, + 0x7D7F, 0xBD87, 0x7D80, 0xBD88, 0x7D81, 0xBD89, 0x7D82, 0xBD8A, + 0x7D83, 0xBD8B, 0x7D84, 0xBD8C, 0x7D85, 0xBD8D, 0x7D86, 0xBD8E, + 0x7D87, 0xBD8F, 0x7D88, 0xBD90, 0x7D89, 0xBD91, 0x7D8A, 0xBD92, + 0x7D8B, 0xBD93, 0x7D8C, 0xBD94, 0x7D8D, 0xBD95, 0x7D8E, 0xBD96, + 0x7D8F, 0xBD97, 0x7D90, 0xBD98, 0x7D91, 0xBD99, 0x7D92, 0xBD9A, + 0x7D93, 0xBD9B, 0x7D94, 0xBD9C, 0x7D95, 0xBD9D, 0x7D96, 0xBD9E, + 0x7D97, 0xBD9F, 0x7D98, 0xBDA0, 0x7D99, 0xBE40, 0x7D9A, 0xBE41, + 0x7D9B, 0xBE42, 0x7D9C, 0xBE43, 0x7D9D, 0xBE44, 0x7D9E, 0xBE45, + 0x7D9F, 0xBE46, 0x7DA0, 0xBE47, 0x7DA1, 0xBE48, 0x7DA2, 0xBE49, + 0x7DA3, 0xBE4A, 0x7DA4, 0xBE4B, 0x7DA5, 0xBE4C, 0x7DA6, 0xF4EB, + 0x7DA7, 0xBE4D, 0x7DA8, 0xBE4E, 0x7DA9, 0xBE4F, 0x7DAA, 0xBE50, + 0x7DAB, 0xBE51, 0x7DAC, 0xBE52, 0x7DAD, 0xBE53, 0x7DAE, 0xF4EC, + 0x7DAF, 0xBE54, 0x7DB0, 0xBE55, 0x7DB1, 0xBE56, 0x7DB2, 0xBE57, + 0x7DB3, 0xBE58, 0x7DB4, 0xBE59, 0x7DB5, 0xBE5A, 0x7DB6, 0xBE5B, + 0x7DB7, 0xBE5C, 0x7DB8, 0xBE5D, 0x7DB9, 0xBE5E, 0x7DBA, 0xBE5F, + 0x7DBB, 0xBE60, 0x7DBC, 0xBE61, 0x7DBD, 0xBE62, 0x7DBE, 0xBE63, + 0x7DBF, 0xBE64, 0x7DC0, 0xBE65, 0x7DC1, 0xBE66, 0x7DC2, 0xBE67, + 0x7DC3, 0xBE68, 0x7DC4, 0xBE69, 0x7DC5, 0xBE6A, 0x7DC6, 0xBE6B, + 0x7DC7, 0xBE6C, 0x7DC8, 0xBE6D, 0x7DC9, 0xBE6E, 0x7DCA, 0xBE6F, + 0x7DCB, 0xBE70, 0x7DCC, 0xBE71, 0x7DCD, 0xBE72, 0x7DCE, 0xBE73, + 0x7DCF, 0xBE74, 0x7DD0, 0xBE75, 0x7DD1, 0xBE76, 0x7DD2, 0xBE77, + 0x7DD3, 0xBE78, 0x7DD4, 0xBE79, 0x7DD5, 0xBE7A, 0x7DD6, 0xBE7B, + 0x7DD7, 0xBE7C, 0x7DD8, 0xBE7D, 0x7DD9, 0xBE7E, 0x7DDA, 0xBE80, + 0x7DDB, 0xBE81, 0x7DDC, 0xBE82, 0x7DDD, 0xBE83, 0x7DDE, 0xBE84, + 0x7DDF, 0xBE85, 0x7DE0, 0xBE86, 0x7DE1, 0xBE87, 0x7DE2, 0xBE88, + 0x7DE3, 0xBE89, 0x7DE4, 0xBE8A, 0x7DE5, 0xBE8B, 0x7DE6, 0xBE8C, + 0x7DE7, 0xBE8D, 0x7DE8, 0xBE8E, 0x7DE9, 0xBE8F, 0x7DEA, 0xBE90, + 0x7DEB, 0xBE91, 0x7DEC, 0xBE92, 0x7DED, 0xBE93, 0x7DEE, 0xBE94, + 0x7DEF, 0xBE95, 0x7DF0, 0xBE96, 0x7DF1, 0xBE97, 0x7DF2, 0xBE98, + 0x7DF3, 0xBE99, 0x7DF4, 0xBE9A, 0x7DF5, 0xBE9B, 0x7DF6, 0xBE9C, + 0x7DF7, 0xBE9D, 0x7DF8, 0xBE9E, 0x7DF9, 0xBE9F, 0x7DFA, 0xBEA0, + 0x7DFB, 0xBF40, 0x7DFC, 0xBF41, 0x7DFD, 0xBF42, 0x7DFE, 0xBF43, + 0x7DFF, 0xBF44, 0x7E00, 0xBF45, 0x7E01, 0xBF46, 0x7E02, 0xBF47, + 0x7E03, 0xBF48, 0x7E04, 0xBF49, 0x7E05, 0xBF4A, 0x7E06, 0xBF4B, + 0x7E07, 0xBF4C, 0x7E08, 0xBF4D, 0x7E09, 0xBF4E, 0x7E0A, 0xBF4F, + 0x7E0B, 0xBF50, 0x7E0C, 0xBF51, 0x7E0D, 0xBF52, 0x7E0E, 0xBF53, + 0x7E0F, 0xBF54, 0x7E10, 0xBF55, 0x7E11, 0xBF56, 0x7E12, 0xBF57, + 0x7E13, 0xBF58, 0x7E14, 0xBF59, 0x7E15, 0xBF5A, 0x7E16, 0xBF5B, + 0x7E17, 0xBF5C, 0x7E18, 0xBF5D, 0x7E19, 0xBF5E, 0x7E1A, 0xBF5F, + 0x7E1B, 0xBF60, 0x7E1C, 0xBF61, 0x7E1D, 0xBF62, 0x7E1E, 0xBF63, + 0x7E1F, 0xBF64, 0x7E20, 0xBF65, 0x7E21, 0xBF66, 0x7E22, 0xBF67, + 0x7E23, 0xBF68, 0x7E24, 0xBF69, 0x7E25, 0xBF6A, 0x7E26, 0xBF6B, + 0x7E27, 0xBF6C, 0x7E28, 0xBF6D, 0x7E29, 0xBF6E, 0x7E2A, 0xBF6F, + 0x7E2B, 0xBF70, 0x7E2C, 0xBF71, 0x7E2D, 0xBF72, 0x7E2E, 0xBF73, + 0x7E2F, 0xBF74, 0x7E30, 0xBF75, 0x7E31, 0xBF76, 0x7E32, 0xBF77, + 0x7E33, 0xBF78, 0x7E34, 0xBF79, 0x7E35, 0xBF7A, 0x7E36, 0xBF7B, + 0x7E37, 0xBF7C, 0x7E38, 0xBF7D, 0x7E39, 0xBF7E, 0x7E3A, 0xBF80, + 0x7E3B, 0xF7E3, 0x7E3C, 0xBF81, 0x7E3D, 0xBF82, 0x7E3E, 0xBF83, + 0x7E3F, 0xBF84, 0x7E40, 0xBF85, 0x7E41, 0xB7B1, 0x7E42, 0xBF86, + 0x7E43, 0xBF87, 0x7E44, 0xBF88, 0x7E45, 0xBF89, 0x7E46, 0xBF8A, + 0x7E47, 0xF4ED, 0x7E48, 0xBF8B, 0x7E49, 0xBF8C, 0x7E4A, 0xBF8D, + 0x7E4B, 0xBF8E, 0x7E4C, 0xBF8F, 0x7E4D, 0xBF90, 0x7E4E, 0xBF91, + 0x7E4F, 0xBF92, 0x7E50, 0xBF93, 0x7E51, 0xBF94, 0x7E52, 0xBF95, + 0x7E53, 0xBF96, 0x7E54, 0xBF97, 0x7E55, 0xBF98, 0x7E56, 0xBF99, + 0x7E57, 0xBF9A, 0x7E58, 0xBF9B, 0x7E59, 0xBF9C, 0x7E5A, 0xBF9D, + 0x7E5B, 0xBF9E, 0x7E5C, 0xBF9F, 0x7E5D, 0xBFA0, 0x7E5E, 0xC040, + 0x7E5F, 0xC041, 0x7E60, 0xC042, 0x7E61, 0xC043, 0x7E62, 0xC044, + 0x7E63, 0xC045, 0x7E64, 0xC046, 0x7E65, 0xC047, 0x7E66, 0xC048, + 0x7E67, 0xC049, 0x7E68, 0xC04A, 0x7E69, 0xC04B, 0x7E6A, 0xC04C, + 0x7E6B, 0xC04D, 0x7E6C, 0xC04E, 0x7E6D, 0xC04F, 0x7E6E, 0xC050, + 0x7E6F, 0xC051, 0x7E70, 0xC052, 0x7E71, 0xC053, 0x7E72, 0xC054, + 0x7E73, 0xC055, 0x7E74, 0xC056, 0x7E75, 0xC057, 0x7E76, 0xC058, + 0x7E77, 0xC059, 0x7E78, 0xC05A, 0x7E79, 0xC05B, 0x7E7A, 0xC05C, + 0x7E7B, 0xC05D, 0x7E7C, 0xC05E, 0x7E7D, 0xC05F, 0x7E7E, 0xC060, + 0x7E7F, 0xC061, 0x7E80, 0xC062, 0x7E81, 0xC063, 0x7E82, 0xD7EB, + 0x7E83, 0xC064, 0x7E84, 0xC065, 0x7E85, 0xC066, 0x7E86, 0xC067, + 0x7E87, 0xC068, 0x7E88, 0xC069, 0x7E89, 0xC06A, 0x7E8A, 0xC06B, + 0x7E8B, 0xC06C, 0x7E8C, 0xC06D, 0x7E8D, 0xC06E, 0x7E8E, 0xC06F, + 0x7E8F, 0xC070, 0x7E90, 0xC071, 0x7E91, 0xC072, 0x7E92, 0xC073, + 0x7E93, 0xC074, 0x7E94, 0xC075, 0x7E95, 0xC076, 0x7E96, 0xC077, + 0x7E97, 0xC078, 0x7E98, 0xC079, 0x7E99, 0xC07A, 0x7E9A, 0xC07B, + 0x7E9B, 0xF4EE, 0x7E9C, 0xC07C, 0x7E9D, 0xC07D, 0x7E9E, 0xC07E, + 0x7E9F, 0xE6F9, 0x7EA0, 0xBEC0, 0x7EA1, 0xE6FA, 0x7EA2, 0xBAEC, + 0x7EA3, 0xE6FB, 0x7EA4, 0xCFCB, 0x7EA5, 0xE6FC, 0x7EA6, 0xD4BC, + 0x7EA7, 0xBCB6, 0x7EA8, 0xE6FD, 0x7EA9, 0xE6FE, 0x7EAA, 0xBCCD, + 0x7EAB, 0xC8D2, 0x7EAC, 0xCEB3, 0x7EAD, 0xE7A1, 0x7EAE, 0xC080, + 0x7EAF, 0xB4BF, 0x7EB0, 0xE7A2, 0x7EB1, 0xC9B4, 0x7EB2, 0xB8D9, + 0x7EB3, 0xC4C9, 0x7EB4, 0xC081, 0x7EB5, 0xD7DD, 0x7EB6, 0xC2DA, + 0x7EB7, 0xB7D7, 0x7EB8, 0xD6BD, 0x7EB9, 0xCEC6, 0x7EBA, 0xB7C4, + 0x7EBB, 0xC082, 0x7EBC, 0xC083, 0x7EBD, 0xC5A6, 0x7EBE, 0xE7A3, + 0x7EBF, 0xCFDF, 0x7EC0, 0xE7A4, 0x7EC1, 0xE7A5, 0x7EC2, 0xE7A6, + 0x7EC3, 0xC1B7, 0x7EC4, 0xD7E9, 0x7EC5, 0xC9F0, 0x7EC6, 0xCFB8, + 0x7EC7, 0xD6AF, 0x7EC8, 0xD6D5, 0x7EC9, 0xE7A7, 0x7ECA, 0xB0ED, + 0x7ECB, 0xE7A8, 0x7ECC, 0xE7A9, 0x7ECD, 0xC9DC, 0x7ECE, 0xD2EF, + 0x7ECF, 0xBEAD, 0x7ED0, 0xE7AA, 0x7ED1, 0xB0F3, 0x7ED2, 0xC8DE, + 0x7ED3, 0xBDE1, 0x7ED4, 0xE7AB, 0x7ED5, 0xC8C6, 0x7ED6, 0xC084, + 0x7ED7, 0xE7AC, 0x7ED8, 0xBBE6, 0x7ED9, 0xB8F8, 0x7EDA, 0xD1A4, + 0x7EDB, 0xE7AD, 0x7EDC, 0xC2E7, 0x7EDD, 0xBEF8, 0x7EDE, 0xBDCA, + 0x7EDF, 0xCDB3, 0x7EE0, 0xE7AE, 0x7EE1, 0xE7AF, 0x7EE2, 0xBEEE, + 0x7EE3, 0xD0E5, 0x7EE4, 0xC085, 0x7EE5, 0xCBE7, 0x7EE6, 0xCCD0, + 0x7EE7, 0xBCCC, 0x7EE8, 0xE7B0, 0x7EE9, 0xBCA8, 0x7EEA, 0xD0F7, + 0x7EEB, 0xE7B1, 0x7EEC, 0xC086, 0x7EED, 0xD0F8, 0x7EEE, 0xE7B2, + 0x7EEF, 0xE7B3, 0x7EF0, 0xB4C2, 0x7EF1, 0xE7B4, 0x7EF2, 0xE7B5, + 0x7EF3, 0xC9FE, 0x7EF4, 0xCEAC, 0x7EF5, 0xC3E0, 0x7EF6, 0xE7B7, + 0x7EF7, 0xB1C1, 0x7EF8, 0xB3F1, 0x7EF9, 0xC087, 0x7EFA, 0xE7B8, + 0x7EFB, 0xE7B9, 0x7EFC, 0xD7DB, 0x7EFD, 0xD5C0, 0x7EFE, 0xE7BA, + 0x7EFF, 0xC2CC, 0x7F00, 0xD7BA, 0x7F01, 0xE7BB, 0x7F02, 0xE7BC, + 0x7F03, 0xE7BD, 0x7F04, 0xBCEA, 0x7F05, 0xC3E5, 0x7F06, 0xC0C2, + 0x7F07, 0xE7BE, 0x7F08, 0xE7BF, 0x7F09, 0xBCA9, 0x7F0A, 0xC088, + 0x7F0B, 0xE7C0, 0x7F0C, 0xE7C1, 0x7F0D, 0xE7B6, 0x7F0E, 0xB6D0, + 0x7F0F, 0xE7C2, 0x7F10, 0xC089, 0x7F11, 0xE7C3, 0x7F12, 0xE7C4, + 0x7F13, 0xBBBA, 0x7F14, 0xB5DE, 0x7F15, 0xC2C6, 0x7F16, 0xB1E0, + 0x7F17, 0xE7C5, 0x7F18, 0xD4B5, 0x7F19, 0xE7C6, 0x7F1A, 0xB8BF, + 0x7F1B, 0xE7C8, 0x7F1C, 0xE7C7, 0x7F1D, 0xB7EC, 0x7F1E, 0xC08A, + 0x7F1F, 0xE7C9, 0x7F20, 0xB2F8, 0x7F21, 0xE7CA, 0x7F22, 0xE7CB, + 0x7F23, 0xE7CC, 0x7F24, 0xE7CD, 0x7F25, 0xE7CE, 0x7F26, 0xE7CF, + 0x7F27, 0xE7D0, 0x7F28, 0xD3A7, 0x7F29, 0xCBF5, 0x7F2A, 0xE7D1, + 0x7F2B, 0xE7D2, 0x7F2C, 0xE7D3, 0x7F2D, 0xE7D4, 0x7F2E, 0xC9C9, + 0x7F2F, 0xE7D5, 0x7F30, 0xE7D6, 0x7F31, 0xE7D7, 0x7F32, 0xE7D8, + 0x7F33, 0xE7D9, 0x7F34, 0xBDC9, 0x7F35, 0xE7DA, 0x7F36, 0xF3BE, + 0x7F37, 0xC08B, 0x7F38, 0xB8D7, 0x7F39, 0xC08C, 0x7F3A, 0xC8B1, + 0x7F3B, 0xC08D, 0x7F3C, 0xC08E, 0x7F3D, 0xC08F, 0x7F3E, 0xC090, + 0x7F3F, 0xC091, 0x7F40, 0xC092, 0x7F41, 0xC093, 0x7F42, 0xF3BF, + 0x7F43, 0xC094, 0x7F44, 0xF3C0, 0x7F45, 0xF3C1, 0x7F46, 0xC095, + 0x7F47, 0xC096, 0x7F48, 0xC097, 0x7F49, 0xC098, 0x7F4A, 0xC099, + 0x7F4B, 0xC09A, 0x7F4C, 0xC09B, 0x7F4D, 0xC09C, 0x7F4E, 0xC09D, + 0x7F4F, 0xC09E, 0x7F50, 0xB9DE, 0x7F51, 0xCDF8, 0x7F52, 0xC09F, + 0x7F53, 0xC0A0, 0x7F54, 0xD8E8, 0x7F55, 0xBAB1, 0x7F56, 0xC140, + 0x7F57, 0xC2DE, 0x7F58, 0xEEB7, 0x7F59, 0xC141, 0x7F5A, 0xB7A3, + 0x7F5B, 0xC142, 0x7F5C, 0xC143, 0x7F5D, 0xC144, 0x7F5E, 0xC145, + 0x7F5F, 0xEEB9, 0x7F60, 0xC146, 0x7F61, 0xEEB8, 0x7F62, 0xB0D5, + 0x7F63, 0xC147, 0x7F64, 0xC148, 0x7F65, 0xC149, 0x7F66, 0xC14A, + 0x7F67, 0xC14B, 0x7F68, 0xEEBB, 0x7F69, 0xD5D6, 0x7F6A, 0xD7EF, + 0x7F6B, 0xC14C, 0x7F6C, 0xC14D, 0x7F6D, 0xC14E, 0x7F6E, 0xD6C3, + 0x7F6F, 0xC14F, 0x7F70, 0xC150, 0x7F71, 0xEEBD, 0x7F72, 0xCAF0, + 0x7F73, 0xC151, 0x7F74, 0xEEBC, 0x7F75, 0xC152, 0x7F76, 0xC153, + 0x7F77, 0xC154, 0x7F78, 0xC155, 0x7F79, 0xEEBE, 0x7F7A, 0xC156, + 0x7F7B, 0xC157, 0x7F7C, 0xC158, 0x7F7D, 0xC159, 0x7F7E, 0xEEC0, + 0x7F7F, 0xC15A, 0x7F80, 0xC15B, 0x7F81, 0xEEBF, 0x7F82, 0xC15C, + 0x7F83, 0xC15D, 0x7F84, 0xC15E, 0x7F85, 0xC15F, 0x7F86, 0xC160, + 0x7F87, 0xC161, 0x7F88, 0xC162, 0x7F89, 0xC163, 0x7F8A, 0xD1F2, + 0x7F8B, 0xC164, 0x7F8C, 0xC7BC, 0x7F8D, 0xC165, 0x7F8E, 0xC3C0, + 0x7F8F, 0xC166, 0x7F90, 0xC167, 0x7F91, 0xC168, 0x7F92, 0xC169, + 0x7F93, 0xC16A, 0x7F94, 0xB8E1, 0x7F95, 0xC16B, 0x7F96, 0xC16C, + 0x7F97, 0xC16D, 0x7F98, 0xC16E, 0x7F99, 0xC16F, 0x7F9A, 0xC1E7, + 0x7F9B, 0xC170, 0x7F9C, 0xC171, 0x7F9D, 0xF4C6, 0x7F9E, 0xD0DF, + 0x7F9F, 0xF4C7, 0x7FA0, 0xC172, 0x7FA1, 0xCFDB, 0x7FA2, 0xC173, + 0x7FA3, 0xC174, 0x7FA4, 0xC8BA, 0x7FA5, 0xC175, 0x7FA6, 0xC176, + 0x7FA7, 0xF4C8, 0x7FA8, 0xC177, 0x7FA9, 0xC178, 0x7FAA, 0xC179, + 0x7FAB, 0xC17A, 0x7FAC, 0xC17B, 0x7FAD, 0xC17C, 0x7FAE, 0xC17D, + 0x7FAF, 0xF4C9, 0x7FB0, 0xF4CA, 0x7FB1, 0xC17E, 0x7FB2, 0xF4CB, + 0x7FB3, 0xC180, 0x7FB4, 0xC181, 0x7FB5, 0xC182, 0x7FB6, 0xC183, + 0x7FB7, 0xC184, 0x7FB8, 0xD9FA, 0x7FB9, 0xB8FE, 0x7FBA, 0xC185, + 0x7FBB, 0xC186, 0x7FBC, 0xE5F1, 0x7FBD, 0xD3F0, 0x7FBE, 0xC187, + 0x7FBF, 0xF4E0, 0x7FC0, 0xC188, 0x7FC1, 0xCECC, 0x7FC2, 0xC189, + 0x7FC3, 0xC18A, 0x7FC4, 0xC18B, 0x7FC5, 0xB3E1, 0x7FC6, 0xC18C, + 0x7FC7, 0xC18D, 0x7FC8, 0xC18E, 0x7FC9, 0xC18F, 0x7FCA, 0xF1B4, + 0x7FCB, 0xC190, 0x7FCC, 0xD2EE, 0x7FCD, 0xC191, 0x7FCE, 0xF4E1, + 0x7FCF, 0xC192, 0x7FD0, 0xC193, 0x7FD1, 0xC194, 0x7FD2, 0xC195, + 0x7FD3, 0xC196, 0x7FD4, 0xCFE8, 0x7FD5, 0xF4E2, 0x7FD6, 0xC197, + 0x7FD7, 0xC198, 0x7FD8, 0xC7CC, 0x7FD9, 0xC199, 0x7FDA, 0xC19A, + 0x7FDB, 0xC19B, 0x7FDC, 0xC19C, 0x7FDD, 0xC19D, 0x7FDE, 0xC19E, + 0x7FDF, 0xB5D4, 0x7FE0, 0xB4E4, 0x7FE1, 0xF4E4, 0x7FE2, 0xC19F, + 0x7FE3, 0xC1A0, 0x7FE4, 0xC240, 0x7FE5, 0xF4E3, 0x7FE6, 0xF4E5, + 0x7FE7, 0xC241, 0x7FE8, 0xC242, 0x7FE9, 0xF4E6, 0x7FEA, 0xC243, + 0x7FEB, 0xC244, 0x7FEC, 0xC245, 0x7FED, 0xC246, 0x7FEE, 0xF4E7, + 0x7FEF, 0xC247, 0x7FF0, 0xBAB2, 0x7FF1, 0xB0BF, 0x7FF2, 0xC248, + 0x7FF3, 0xF4E8, 0x7FF4, 0xC249, 0x7FF5, 0xC24A, 0x7FF6, 0xC24B, + 0x7FF7, 0xC24C, 0x7FF8, 0xC24D, 0x7FF9, 0xC24E, 0x7FFA, 0xC24F, + 0x7FFB, 0xB7AD, 0x7FFC, 0xD2ED, 0x7FFD, 0xC250, 0x7FFE, 0xC251, + 0x7FFF, 0xC252, 0x8000, 0xD2AB, 0x8001, 0xC0CF, 0x8002, 0xC253, + 0x8003, 0xBFBC, 0x8004, 0xEBA3, 0x8005, 0xD5DF, 0x8006, 0xEAC8, + 0x8007, 0xC254, 0x8008, 0xC255, 0x8009, 0xC256, 0x800A, 0xC257, + 0x800B, 0xF1F3, 0x800C, 0xB6F8, 0x800D, 0xCBA3, 0x800E, 0xC258, + 0x800F, 0xC259, 0x8010, 0xC4CD, 0x8011, 0xC25A, 0x8012, 0xF1E7, + 0x8013, 0xC25B, 0x8014, 0xF1E8, 0x8015, 0xB8FB, 0x8016, 0xF1E9, + 0x8017, 0xBAC4, 0x8018, 0xD4C5, 0x8019, 0xB0D2, 0x801A, 0xC25C, + 0x801B, 0xC25D, 0x801C, 0xF1EA, 0x801D, 0xC25E, 0x801E, 0xC25F, + 0x801F, 0xC260, 0x8020, 0xF1EB, 0x8021, 0xC261, 0x8022, 0xF1EC, + 0x8023, 0xC262, 0x8024, 0xC263, 0x8025, 0xF1ED, 0x8026, 0xF1EE, + 0x8027, 0xF1EF, 0x8028, 0xF1F1, 0x8029, 0xF1F0, 0x802A, 0xC5D5, + 0x802B, 0xC264, 0x802C, 0xC265, 0x802D, 0xC266, 0x802E, 0xC267, + 0x802F, 0xC268, 0x8030, 0xC269, 0x8031, 0xF1F2, 0x8032, 0xC26A, + 0x8033, 0xB6FA, 0x8034, 0xC26B, 0x8035, 0xF1F4, 0x8036, 0xD2AE, + 0x8037, 0xDEC7, 0x8038, 0xCBCA, 0x8039, 0xC26C, 0x803A, 0xC26D, + 0x803B, 0xB3DC, 0x803C, 0xC26E, 0x803D, 0xB5A2, 0x803E, 0xC26F, + 0x803F, 0xB9A2, 0x8040, 0xC270, 0x8041, 0xC271, 0x8042, 0xC4F4, + 0x8043, 0xF1F5, 0x8044, 0xC272, 0x8045, 0xC273, 0x8046, 0xF1F6, + 0x8047, 0xC274, 0x8048, 0xC275, 0x8049, 0xC276, 0x804A, 0xC1C4, + 0x804B, 0xC1FB, 0x804C, 0xD6B0, 0x804D, 0xF1F7, 0x804E, 0xC277, + 0x804F, 0xC278, 0x8050, 0xC279, 0x8051, 0xC27A, 0x8052, 0xF1F8, + 0x8053, 0xC27B, 0x8054, 0xC1AA, 0x8055, 0xC27C, 0x8056, 0xC27D, + 0x8057, 0xC27E, 0x8058, 0xC6B8, 0x8059, 0xC280, 0x805A, 0xBEDB, + 0x805B, 0xC281, 0x805C, 0xC282, 0x805D, 0xC283, 0x805E, 0xC284, + 0x805F, 0xC285, 0x8060, 0xC286, 0x8061, 0xC287, 0x8062, 0xC288, + 0x8063, 0xC289, 0x8064, 0xC28A, 0x8065, 0xC28B, 0x8066, 0xC28C, + 0x8067, 0xC28D, 0x8068, 0xC28E, 0x8069, 0xF1F9, 0x806A, 0xB4CF, + 0x806B, 0xC28F, 0x806C, 0xC290, 0x806D, 0xC291, 0x806E, 0xC292, + 0x806F, 0xC293, 0x8070, 0xC294, 0x8071, 0xF1FA, 0x8072, 0xC295, + 0x8073, 0xC296, 0x8074, 0xC297, 0x8075, 0xC298, 0x8076, 0xC299, + 0x8077, 0xC29A, 0x8078, 0xC29B, 0x8079, 0xC29C, 0x807A, 0xC29D, + 0x807B, 0xC29E, 0x807C, 0xC29F, 0x807D, 0xC2A0, 0x807E, 0xC340, + 0x807F, 0xEDB2, 0x8080, 0xEDB1, 0x8081, 0xC341, 0x8082, 0xC342, + 0x8083, 0xCBE0, 0x8084, 0xD2DE, 0x8085, 0xC343, 0x8086, 0xCBC1, + 0x8087, 0xD5D8, 0x8088, 0xC344, 0x8089, 0xC8E2, 0x808A, 0xC345, + 0x808B, 0xC0DF, 0x808C, 0xBCA1, 0x808D, 0xC346, 0x808E, 0xC347, + 0x808F, 0xC348, 0x8090, 0xC349, 0x8091, 0xC34A, 0x8092, 0xC34B, + 0x8093, 0xEBC1, 0x8094, 0xC34C, 0x8095, 0xC34D, 0x8096, 0xD0A4, + 0x8097, 0xC34E, 0x8098, 0xD6E2, 0x8099, 0xC34F, 0x809A, 0xB6C7, + 0x809B, 0xB8D8, 0x809C, 0xEBC0, 0x809D, 0xB8CE, 0x809E, 0xC350, + 0x809F, 0xEBBF, 0x80A0, 0xB3A6, 0x80A1, 0xB9C9, 0x80A2, 0xD6AB, + 0x80A3, 0xC351, 0x80A4, 0xB7F4, 0x80A5, 0xB7CA, 0x80A6, 0xC352, + 0x80A7, 0xC353, 0x80A8, 0xC354, 0x80A9, 0xBCE7, 0x80AA, 0xB7BE, + 0x80AB, 0xEBC6, 0x80AC, 0xC355, 0x80AD, 0xEBC7, 0x80AE, 0xB0B9, + 0x80AF, 0xBFCF, 0x80B0, 0xC356, 0x80B1, 0xEBC5, 0x80B2, 0xD3FD, + 0x80B3, 0xC357, 0x80B4, 0xEBC8, 0x80B5, 0xC358, 0x80B6, 0xC359, + 0x80B7, 0xEBC9, 0x80B8, 0xC35A, 0x80B9, 0xC35B, 0x80BA, 0xB7CE, + 0x80BB, 0xC35C, 0x80BC, 0xEBC2, 0x80BD, 0xEBC4, 0x80BE, 0xC9F6, + 0x80BF, 0xD6D7, 0x80C0, 0xD5CD, 0x80C1, 0xD0B2, 0x80C2, 0xEBCF, + 0x80C3, 0xCEB8, 0x80C4, 0xEBD0, 0x80C5, 0xC35D, 0x80C6, 0xB5A8, + 0x80C7, 0xC35E, 0x80C8, 0xC35F, 0x80C9, 0xC360, 0x80CA, 0xC361, + 0x80CB, 0xC362, 0x80CC, 0xB1B3, 0x80CD, 0xEBD2, 0x80CE, 0xCCA5, + 0x80CF, 0xC363, 0x80D0, 0xC364, 0x80D1, 0xC365, 0x80D2, 0xC366, + 0x80D3, 0xC367, 0x80D4, 0xC368, 0x80D5, 0xC369, 0x80D6, 0xC5D6, + 0x80D7, 0xEBD3, 0x80D8, 0xC36A, 0x80D9, 0xEBD1, 0x80DA, 0xC5DF, + 0x80DB, 0xEBCE, 0x80DC, 0xCAA4, 0x80DD, 0xEBD5, 0x80DE, 0xB0FB, + 0x80DF, 0xC36B, 0x80E0, 0xC36C, 0x80E1, 0xBAFA, 0x80E2, 0xC36D, + 0x80E3, 0xC36E, 0x80E4, 0xD8B7, 0x80E5, 0xF1E3, 0x80E6, 0xC36F, + 0x80E7, 0xEBCA, 0x80E8, 0xEBCB, 0x80E9, 0xEBCC, 0x80EA, 0xEBCD, + 0x80EB, 0xEBD6, 0x80EC, 0xE6C0, 0x80ED, 0xEBD9, 0x80EE, 0xC370, + 0x80EF, 0xBFE8, 0x80F0, 0xD2C8, 0x80F1, 0xEBD7, 0x80F2, 0xEBDC, + 0x80F3, 0xB8EC, 0x80F4, 0xEBD8, 0x80F5, 0xC371, 0x80F6, 0xBDBA, + 0x80F7, 0xC372, 0x80F8, 0xD0D8, 0x80F9, 0xC373, 0x80FA, 0xB0B7, + 0x80FB, 0xC374, 0x80FC, 0xEBDD, 0x80FD, 0xC4DC, 0x80FE, 0xC375, + 0x80FF, 0xC376, 0x8100, 0xC377, 0x8101, 0xC378, 0x8102, 0xD6AC, + 0x8103, 0xC379, 0x8104, 0xC37A, 0x8105, 0xC37B, 0x8106, 0xB4E0, + 0x8107, 0xC37C, 0x8108, 0xC37D, 0x8109, 0xC2F6, 0x810A, 0xBCB9, + 0x810B, 0xC37E, 0x810C, 0xC380, 0x810D, 0xEBDA, 0x810E, 0xEBDB, + 0x810F, 0xD4E0, 0x8110, 0xC6EA, 0x8111, 0xC4D4, 0x8112, 0xEBDF, + 0x8113, 0xC5A7, 0x8114, 0xD9F5, 0x8115, 0xC381, 0x8116, 0xB2B1, + 0x8117, 0xC382, 0x8118, 0xEBE4, 0x8119, 0xC383, 0x811A, 0xBDC5, + 0x811B, 0xC384, 0x811C, 0xC385, 0x811D, 0xC386, 0x811E, 0xEBE2, + 0x811F, 0xC387, 0x8120, 0xC388, 0x8121, 0xC389, 0x8122, 0xC38A, + 0x8123, 0xC38B, 0x8124, 0xC38C, 0x8125, 0xC38D, 0x8126, 0xC38E, + 0x8127, 0xC38F, 0x8128, 0xC390, 0x8129, 0xC391, 0x812A, 0xC392, + 0x812B, 0xC393, 0x812C, 0xEBE3, 0x812D, 0xC394, 0x812E, 0xC395, + 0x812F, 0xB8AC, 0x8130, 0xC396, 0x8131, 0xCDD1, 0x8132, 0xEBE5, + 0x8133, 0xC397, 0x8134, 0xC398, 0x8135, 0xC399, 0x8136, 0xEBE1, + 0x8137, 0xC39A, 0x8138, 0xC1B3, 0x8139, 0xC39B, 0x813A, 0xC39C, + 0x813B, 0xC39D, 0x813C, 0xC39E, 0x813D, 0xC39F, 0x813E, 0xC6A2, + 0x813F, 0xC3A0, 0x8140, 0xC440, 0x8141, 0xC441, 0x8142, 0xC442, + 0x8143, 0xC443, 0x8144, 0xC444, 0x8145, 0xC445, 0x8146, 0xCCF3, + 0x8147, 0xC446, 0x8148, 0xEBE6, 0x8149, 0xC447, 0x814A, 0xC0B0, + 0x814B, 0xD2B8, 0x814C, 0xEBE7, 0x814D, 0xC448, 0x814E, 0xC449, + 0x814F, 0xC44A, 0x8150, 0xB8AF, 0x8151, 0xB8AD, 0x8152, 0xC44B, + 0x8153, 0xEBE8, 0x8154, 0xC7BB, 0x8155, 0xCDF3, 0x8156, 0xC44C, + 0x8157, 0xC44D, 0x8158, 0xC44E, 0x8159, 0xEBEA, 0x815A, 0xEBEB, + 0x815B, 0xC44F, 0x815C, 0xC450, 0x815D, 0xC451, 0x815E, 0xC452, + 0x815F, 0xC453, 0x8160, 0xEBED, 0x8161, 0xC454, 0x8162, 0xC455, + 0x8163, 0xC456, 0x8164, 0xC457, 0x8165, 0xD0C8, 0x8166, 0xC458, + 0x8167, 0xEBF2, 0x8168, 0xC459, 0x8169, 0xEBEE, 0x816A, 0xC45A, + 0x816B, 0xC45B, 0x816C, 0xC45C, 0x816D, 0xEBF1, 0x816E, 0xC8F9, + 0x816F, 0xC45D, 0x8170, 0xD1FC, 0x8171, 0xEBEC, 0x8172, 0xC45E, + 0x8173, 0xC45F, 0x8174, 0xEBE9, 0x8175, 0xC460, 0x8176, 0xC461, + 0x8177, 0xC462, 0x8178, 0xC463, 0x8179, 0xB8B9, 0x817A, 0xCFD9, + 0x817B, 0xC4E5, 0x817C, 0xEBEF, 0x817D, 0xEBF0, 0x817E, 0xCCDA, + 0x817F, 0xCDC8, 0x8180, 0xB0F2, 0x8181, 0xC464, 0x8182, 0xEBF6, + 0x8183, 0xC465, 0x8184, 0xC466, 0x8185, 0xC467, 0x8186, 0xC468, + 0x8187, 0xC469, 0x8188, 0xEBF5, 0x8189, 0xC46A, 0x818A, 0xB2B2, + 0x818B, 0xC46B, 0x818C, 0xC46C, 0x818D, 0xC46D, 0x818E, 0xC46E, + 0x818F, 0xB8E0, 0x8190, 0xC46F, 0x8191, 0xEBF7, 0x8192, 0xC470, + 0x8193, 0xC471, 0x8194, 0xC472, 0x8195, 0xC473, 0x8196, 0xC474, + 0x8197, 0xC475, 0x8198, 0xB1EC, 0x8199, 0xC476, 0x819A, 0xC477, + 0x819B, 0xCCC5, 0x819C, 0xC4A4, 0x819D, 0xCFA5, 0x819E, 0xC478, + 0x819F, 0xC479, 0x81A0, 0xC47A, 0x81A1, 0xC47B, 0x81A2, 0xC47C, + 0x81A3, 0xEBF9, 0x81A4, 0xC47D, 0x81A5, 0xC47E, 0x81A6, 0xECA2, + 0x81A7, 0xC480, 0x81A8, 0xC5F2, 0x81A9, 0xC481, 0x81AA, 0xEBFA, + 0x81AB, 0xC482, 0x81AC, 0xC483, 0x81AD, 0xC484, 0x81AE, 0xC485, + 0x81AF, 0xC486, 0x81B0, 0xC487, 0x81B1, 0xC488, 0x81B2, 0xC489, + 0x81B3, 0xC9C5, 0x81B4, 0xC48A, 0x81B5, 0xC48B, 0x81B6, 0xC48C, + 0x81B7, 0xC48D, 0x81B8, 0xC48E, 0x81B9, 0xC48F, 0x81BA, 0xE2DF, + 0x81BB, 0xEBFE, 0x81BC, 0xC490, 0x81BD, 0xC491, 0x81BE, 0xC492, + 0x81BF, 0xC493, 0x81C0, 0xCDCE, 0x81C1, 0xECA1, 0x81C2, 0xB1DB, + 0x81C3, 0xD3B7, 0x81C4, 0xC494, 0x81C5, 0xC495, 0x81C6, 0xD2DC, + 0x81C7, 0xC496, 0x81C8, 0xC497, 0x81C9, 0xC498, 0x81CA, 0xEBFD, + 0x81CB, 0xC499, 0x81CC, 0xEBFB, 0x81CD, 0xC49A, 0x81CE, 0xC49B, + 0x81CF, 0xC49C, 0x81D0, 0xC49D, 0x81D1, 0xC49E, 0x81D2, 0xC49F, + 0x81D3, 0xC4A0, 0x81D4, 0xC540, 0x81D5, 0xC541, 0x81D6, 0xC542, + 0x81D7, 0xC543, 0x81D8, 0xC544, 0x81D9, 0xC545, 0x81DA, 0xC546, + 0x81DB, 0xC547, 0x81DC, 0xC548, 0x81DD, 0xC549, 0x81DE, 0xC54A, + 0x81DF, 0xC54B, 0x81E0, 0xC54C, 0x81E1, 0xC54D, 0x81E2, 0xC54E, + 0x81E3, 0xB3BC, 0x81E4, 0xC54F, 0x81E5, 0xC550, 0x81E6, 0xC551, + 0x81E7, 0xEAB0, 0x81E8, 0xC552, 0x81E9, 0xC553, 0x81EA, 0xD7D4, + 0x81EB, 0xC554, 0x81EC, 0xF4AB, 0x81ED, 0xB3F4, 0x81EE, 0xC555, + 0x81EF, 0xC556, 0x81F0, 0xC557, 0x81F1, 0xC558, 0x81F2, 0xC559, + 0x81F3, 0xD6C1, 0x81F4, 0xD6C2, 0x81F5, 0xC55A, 0x81F6, 0xC55B, + 0x81F7, 0xC55C, 0x81F8, 0xC55D, 0x81F9, 0xC55E, 0x81FA, 0xC55F, + 0x81FB, 0xD5E9, 0x81FC, 0xBECA, 0x81FD, 0xC560, 0x81FE, 0xF4A7, + 0x81FF, 0xC561, 0x8200, 0xD2A8, 0x8201, 0xF4A8, 0x8202, 0xF4A9, + 0x8203, 0xC562, 0x8204, 0xF4AA, 0x8205, 0xBECB, 0x8206, 0xD3DF, + 0x8207, 0xC563, 0x8208, 0xC564, 0x8209, 0xC565, 0x820A, 0xC566, + 0x820B, 0xC567, 0x820C, 0xC9E0, 0x820D, 0xC9E1, 0x820E, 0xC568, + 0x820F, 0xC569, 0x8210, 0xF3C2, 0x8211, 0xC56A, 0x8212, 0xCAE6, + 0x8213, 0xC56B, 0x8214, 0xCCF2, 0x8215, 0xC56C, 0x8216, 0xC56D, + 0x8217, 0xC56E, 0x8218, 0xC56F, 0x8219, 0xC570, 0x821A, 0xC571, + 0x821B, 0xE2B6, 0x821C, 0xCBB4, 0x821D, 0xC572, 0x821E, 0xCEE8, + 0x821F, 0xD6DB, 0x8220, 0xC573, 0x8221, 0xF4AD, 0x8222, 0xF4AE, + 0x8223, 0xF4AF, 0x8224, 0xC574, 0x8225, 0xC575, 0x8226, 0xC576, + 0x8227, 0xC577, 0x8228, 0xF4B2, 0x8229, 0xC578, 0x822A, 0xBABD, + 0x822B, 0xF4B3, 0x822C, 0xB0E3, 0x822D, 0xF4B0, 0x822E, 0xC579, + 0x822F, 0xF4B1, 0x8230, 0xBDA2, 0x8231, 0xB2D5, 0x8232, 0xC57A, + 0x8233, 0xF4B6, 0x8234, 0xF4B7, 0x8235, 0xB6E6, 0x8236, 0xB2B0, + 0x8237, 0xCFCF, 0x8238, 0xF4B4, 0x8239, 0xB4AC, 0x823A, 0xC57B, + 0x823B, 0xF4B5, 0x823C, 0xC57C, 0x823D, 0xC57D, 0x823E, 0xF4B8, + 0x823F, 0xC57E, 0x8240, 0xC580, 0x8241, 0xC581, 0x8242, 0xC582, + 0x8243, 0xC583, 0x8244, 0xF4B9, 0x8245, 0xC584, 0x8246, 0xC585, + 0x8247, 0xCDA7, 0x8248, 0xC586, 0x8249, 0xF4BA, 0x824A, 0xC587, + 0x824B, 0xF4BB, 0x824C, 0xC588, 0x824D, 0xC589, 0x824E, 0xC58A, + 0x824F, 0xF4BC, 0x8250, 0xC58B, 0x8251, 0xC58C, 0x8252, 0xC58D, + 0x8253, 0xC58E, 0x8254, 0xC58F, 0x8255, 0xC590, 0x8256, 0xC591, + 0x8257, 0xC592, 0x8258, 0xCBD2, 0x8259, 0xC593, 0x825A, 0xF4BD, + 0x825B, 0xC594, 0x825C, 0xC595, 0x825D, 0xC596, 0x825E, 0xC597, + 0x825F, 0xF4BE, 0x8260, 0xC598, 0x8261, 0xC599, 0x8262, 0xC59A, + 0x8263, 0xC59B, 0x8264, 0xC59C, 0x8265, 0xC59D, 0x8266, 0xC59E, + 0x8267, 0xC59F, 0x8268, 0xF4BF, 0x8269, 0xC5A0, 0x826A, 0xC640, + 0x826B, 0xC641, 0x826C, 0xC642, 0x826D, 0xC643, 0x826E, 0xF4DE, + 0x826F, 0xC1BC, 0x8270, 0xBCE8, 0x8271, 0xC644, 0x8272, 0xC9AB, + 0x8273, 0xD1DE, 0x8274, 0xE5F5, 0x8275, 0xC645, 0x8276, 0xC646, + 0x8277, 0xC647, 0x8278, 0xC648, 0x8279, 0xDCB3, 0x827A, 0xD2D5, + 0x827B, 0xC649, 0x827C, 0xC64A, 0x827D, 0xDCB4, 0x827E, 0xB0AC, + 0x827F, 0xDCB5, 0x8280, 0xC64B, 0x8281, 0xC64C, 0x8282, 0xBDDA, + 0x8283, 0xC64D, 0x8284, 0xDCB9, 0x8285, 0xC64E, 0x8286, 0xC64F, + 0x8287, 0xC650, 0x8288, 0xD8C2, 0x8289, 0xC651, 0x828A, 0xDCB7, + 0x828B, 0xD3F3, 0x828C, 0xC652, 0x828D, 0xC9D6, 0x828E, 0xDCBA, + 0x828F, 0xDCB6, 0x8290, 0xC653, 0x8291, 0xDCBB, 0x8292, 0xC3A2, + 0x8293, 0xC654, 0x8294, 0xC655, 0x8295, 0xC656, 0x8296, 0xC657, + 0x8297, 0xDCBC, 0x8298, 0xDCC5, 0x8299, 0xDCBD, 0x829A, 0xC658, + 0x829B, 0xC659, 0x829C, 0xCEDF, 0x829D, 0xD6A5, 0x829E, 0xC65A, + 0x829F, 0xDCCF, 0x82A0, 0xC65B, 0x82A1, 0xDCCD, 0x82A2, 0xC65C, + 0x82A3, 0xC65D, 0x82A4, 0xDCD2, 0x82A5, 0xBDE6, 0x82A6, 0xC2AB, + 0x82A7, 0xC65E, 0x82A8, 0xDCB8, 0x82A9, 0xDCCB, 0x82AA, 0xDCCE, + 0x82AB, 0xDCBE, 0x82AC, 0xB7D2, 0x82AD, 0xB0C5, 0x82AE, 0xDCC7, + 0x82AF, 0xD0BE, 0x82B0, 0xDCC1, 0x82B1, 0xBBA8, 0x82B2, 0xC65F, + 0x82B3, 0xB7BC, 0x82B4, 0xDCCC, 0x82B5, 0xC660, 0x82B6, 0xC661, + 0x82B7, 0xDCC6, 0x82B8, 0xDCBF, 0x82B9, 0xC7DB, 0x82BA, 0xC662, + 0x82BB, 0xC663, 0x82BC, 0xC664, 0x82BD, 0xD1BF, 0x82BE, 0xDCC0, + 0x82BF, 0xC665, 0x82C0, 0xC666, 0x82C1, 0xDCCA, 0x82C2, 0xC667, + 0x82C3, 0xC668, 0x82C4, 0xDCD0, 0x82C5, 0xC669, 0x82C6, 0xC66A, + 0x82C7, 0xCEAD, 0x82C8, 0xDCC2, 0x82C9, 0xC66B, 0x82CA, 0xDCC3, + 0x82CB, 0xDCC8, 0x82CC, 0xDCC9, 0x82CD, 0xB2D4, 0x82CE, 0xDCD1, + 0x82CF, 0xCBD5, 0x82D0, 0xC66C, 0x82D1, 0xD4B7, 0x82D2, 0xDCDB, + 0x82D3, 0xDCDF, 0x82D4, 0xCCA6, 0x82D5, 0xDCE6, 0x82D6, 0xC66D, + 0x82D7, 0xC3E7, 0x82D8, 0xDCDC, 0x82D9, 0xC66E, 0x82DA, 0xC66F, + 0x82DB, 0xBFC1, 0x82DC, 0xDCD9, 0x82DD, 0xC670, 0x82DE, 0xB0FA, + 0x82DF, 0xB9B6, 0x82E0, 0xDCE5, 0x82E1, 0xDCD3, 0x82E2, 0xC671, + 0x82E3, 0xDCC4, 0x82E4, 0xDCD6, 0x82E5, 0xC8F4, 0x82E6, 0xBFE0, + 0x82E7, 0xC672, 0x82E8, 0xC673, 0x82E9, 0xC674, 0x82EA, 0xC675, + 0x82EB, 0xC9BB, 0x82EC, 0xC676, 0x82ED, 0xC677, 0x82EE, 0xC678, + 0x82EF, 0xB1BD, 0x82F0, 0xC679, 0x82F1, 0xD3A2, 0x82F2, 0xC67A, + 0x82F3, 0xC67B, 0x82F4, 0xDCDA, 0x82F5, 0xC67C, 0x82F6, 0xC67D, + 0x82F7, 0xDCD5, 0x82F8, 0xC67E, 0x82F9, 0xC6BB, 0x82FA, 0xC680, + 0x82FB, 0xDCDE, 0x82FC, 0xC681, 0x82FD, 0xC682, 0x82FE, 0xC683, + 0x82FF, 0xC684, 0x8300, 0xC685, 0x8301, 0xD7C2, 0x8302, 0xC3AF, + 0x8303, 0xB7B6, 0x8304, 0xC7D1, 0x8305, 0xC3A9, 0x8306, 0xDCE2, + 0x8307, 0xDCD8, 0x8308, 0xDCEB, 0x8309, 0xDCD4, 0x830A, 0xC686, + 0x830B, 0xC687, 0x830C, 0xDCDD, 0x830D, 0xC688, 0x830E, 0xBEA5, + 0x830F, 0xDCD7, 0x8310, 0xC689, 0x8311, 0xDCE0, 0x8312, 0xC68A, + 0x8313, 0xC68B, 0x8314, 0xDCE3, 0x8315, 0xDCE4, 0x8316, 0xC68C, + 0x8317, 0xDCF8, 0x8318, 0xC68D, 0x8319, 0xC68E, 0x831A, 0xDCE1, + 0x831B, 0xDDA2, 0x831C, 0xDCE7, 0x831D, 0xC68F, 0x831E, 0xC690, + 0x831F, 0xC691, 0x8320, 0xC692, 0x8321, 0xC693, 0x8322, 0xC694, + 0x8323, 0xC695, 0x8324, 0xC696, 0x8325, 0xC697, 0x8326, 0xC698, + 0x8327, 0xBCEB, 0x8328, 0xB4C4, 0x8329, 0xC699, 0x832A, 0xC69A, + 0x832B, 0xC3A3, 0x832C, 0xB2E7, 0x832D, 0xDCFA, 0x832E, 0xC69B, + 0x832F, 0xDCF2, 0x8330, 0xC69C, 0x8331, 0xDCEF, 0x8332, 0xC69D, + 0x8333, 0xDCFC, 0x8334, 0xDCEE, 0x8335, 0xD2F0, 0x8336, 0xB2E8, + 0x8337, 0xC69E, 0x8338, 0xC8D7, 0x8339, 0xC8E3, 0x833A, 0xDCFB, + 0x833B, 0xC69F, 0x833C, 0xDCED, 0x833D, 0xC6A0, 0x833E, 0xC740, + 0x833F, 0xC741, 0x8340, 0xDCF7, 0x8341, 0xC742, 0x8342, 0xC743, + 0x8343, 0xDCF5, 0x8344, 0xC744, 0x8345, 0xC745, 0x8346, 0xBEA3, + 0x8347, 0xDCF4, 0x8348, 0xC746, 0x8349, 0xB2DD, 0x834A, 0xC747, + 0x834B, 0xC748, 0x834C, 0xC749, 0x834D, 0xC74A, 0x834E, 0xC74B, + 0x834F, 0xDCF3, 0x8350, 0xBCF6, 0x8351, 0xDCE8, 0x8352, 0xBBC4, + 0x8353, 0xC74C, 0x8354, 0xC0F3, 0x8355, 0xC74D, 0x8356, 0xC74E, + 0x8357, 0xC74F, 0x8358, 0xC750, 0x8359, 0xC751, 0x835A, 0xBCD4, + 0x835B, 0xDCE9, 0x835C, 0xDCEA, 0x835D, 0xC752, 0x835E, 0xDCF1, + 0x835F, 0xDCF6, 0x8360, 0xDCF9, 0x8361, 0xB5B4, 0x8362, 0xC753, + 0x8363, 0xC8D9, 0x8364, 0xBBE7, 0x8365, 0xDCFE, 0x8366, 0xDCFD, + 0x8367, 0xD3AB, 0x8368, 0xDDA1, 0x8369, 0xDDA3, 0x836A, 0xDDA5, + 0x836B, 0xD2F1, 0x836C, 0xDDA4, 0x836D, 0xDDA6, 0x836E, 0xDDA7, + 0x836F, 0xD2A9, 0x8370, 0xC754, 0x8371, 0xC755, 0x8372, 0xC756, + 0x8373, 0xC757, 0x8374, 0xC758, 0x8375, 0xC759, 0x8376, 0xC75A, + 0x8377, 0xBAC9, 0x8378, 0xDDA9, 0x8379, 0xC75B, 0x837A, 0xC75C, + 0x837B, 0xDDB6, 0x837C, 0xDDB1, 0x837D, 0xDDB4, 0x837E, 0xC75D, + 0x837F, 0xC75E, 0x8380, 0xC75F, 0x8381, 0xC760, 0x8382, 0xC761, + 0x8383, 0xC762, 0x8384, 0xC763, 0x8385, 0xDDB0, 0x8386, 0xC6CE, + 0x8387, 0xC764, 0x8388, 0xC765, 0x8389, 0xC0F2, 0x838A, 0xC766, + 0x838B, 0xC767, 0x838C, 0xC768, 0x838D, 0xC769, 0x838E, 0xC9AF, + 0x838F, 0xC76A, 0x8390, 0xC76B, 0x8391, 0xC76C, 0x8392, 0xDCEC, + 0x8393, 0xDDAE, 0x8394, 0xC76D, 0x8395, 0xC76E, 0x8396, 0xC76F, + 0x8397, 0xC770, 0x8398, 0xDDB7, 0x8399, 0xC771, 0x839A, 0xC772, + 0x839B, 0xDCF0, 0x839C, 0xDDAF, 0x839D, 0xC773, 0x839E, 0xDDB8, + 0x839F, 0xC774, 0x83A0, 0xDDAC, 0x83A1, 0xC775, 0x83A2, 0xC776, + 0x83A3, 0xC777, 0x83A4, 0xC778, 0x83A5, 0xC779, 0x83A6, 0xC77A, + 0x83A7, 0xC77B, 0x83A8, 0xDDB9, 0x83A9, 0xDDB3, 0x83AA, 0xDDAD, + 0x83AB, 0xC4AA, 0x83AC, 0xC77C, 0x83AD, 0xC77D, 0x83AE, 0xC77E, + 0x83AF, 0xC780, 0x83B0, 0xDDA8, 0x83B1, 0xC0B3, 0x83B2, 0xC1AB, + 0x83B3, 0xDDAA, 0x83B4, 0xDDAB, 0x83B5, 0xC781, 0x83B6, 0xDDB2, + 0x83B7, 0xBBF1, 0x83B8, 0xDDB5, 0x83B9, 0xD3A8, 0x83BA, 0xDDBA, + 0x83BB, 0xC782, 0x83BC, 0xDDBB, 0x83BD, 0xC3A7, 0x83BE, 0xC783, + 0x83BF, 0xC784, 0x83C0, 0xDDD2, 0x83C1, 0xDDBC, 0x83C2, 0xC785, + 0x83C3, 0xC786, 0x83C4, 0xC787, 0x83C5, 0xDDD1, 0x83C6, 0xC788, + 0x83C7, 0xB9BD, 0x83C8, 0xC789, 0x83C9, 0xC78A, 0x83CA, 0xBED5, + 0x83CB, 0xC78B, 0x83CC, 0xBEFA, 0x83CD, 0xC78C, 0x83CE, 0xC78D, + 0x83CF, 0xBACA, 0x83D0, 0xC78E, 0x83D1, 0xC78F, 0x83D2, 0xC790, + 0x83D3, 0xC791, 0x83D4, 0xDDCA, 0x83D5, 0xC792, 0x83D6, 0xDDC5, + 0x83D7, 0xC793, 0x83D8, 0xDDBF, 0x83D9, 0xC794, 0x83DA, 0xC795, + 0x83DB, 0xC796, 0x83DC, 0xB2CB, 0x83DD, 0xDDC3, 0x83DE, 0xC797, + 0x83DF, 0xDDCB, 0x83E0, 0xB2A4, 0x83E1, 0xDDD5, 0x83E2, 0xC798, + 0x83E3, 0xC799, 0x83E4, 0xC79A, 0x83E5, 0xDDBE, 0x83E6, 0xC79B, + 0x83E7, 0xC79C, 0x83E8, 0xC79D, 0x83E9, 0xC6D0, 0x83EA, 0xDDD0, + 0x83EB, 0xC79E, 0x83EC, 0xC79F, 0x83ED, 0xC7A0, 0x83EE, 0xC840, + 0x83EF, 0xC841, 0x83F0, 0xDDD4, 0x83F1, 0xC1E2, 0x83F2, 0xB7C6, + 0x83F3, 0xC842, 0x83F4, 0xC843, 0x83F5, 0xC844, 0x83F6, 0xC845, + 0x83F7, 0xC846, 0x83F8, 0xDDCE, 0x83F9, 0xDDCF, 0x83FA, 0xC847, + 0x83FB, 0xC848, 0x83FC, 0xC849, 0x83FD, 0xDDC4, 0x83FE, 0xC84A, + 0x83FF, 0xC84B, 0x8400, 0xC84C, 0x8401, 0xDDBD, 0x8402, 0xC84D, + 0x8403, 0xDDCD, 0x8404, 0xCCD1, 0x8405, 0xC84E, 0x8406, 0xDDC9, + 0x8407, 0xC84F, 0x8408, 0xC850, 0x8409, 0xC851, 0x840A, 0xC852, + 0x840B, 0xDDC2, 0x840C, 0xC3C8, 0x840D, 0xC6BC, 0x840E, 0xCEAE, + 0x840F, 0xDDCC, 0x8410, 0xC853, 0x8411, 0xDDC8, 0x8412, 0xC854, + 0x8413, 0xC855, 0x8414, 0xC856, 0x8415, 0xC857, 0x8416, 0xC858, + 0x8417, 0xC859, 0x8418, 0xDDC1, 0x8419, 0xC85A, 0x841A, 0xC85B, + 0x841B, 0xC85C, 0x841C, 0xDDC6, 0x841D, 0xC2DC, 0x841E, 0xC85D, + 0x841F, 0xC85E, 0x8420, 0xC85F, 0x8421, 0xC860, 0x8422, 0xC861, + 0x8423, 0xC862, 0x8424, 0xD3A9, 0x8425, 0xD3AA, 0x8426, 0xDDD3, + 0x8427, 0xCFF4, 0x8428, 0xC8F8, 0x8429, 0xC863, 0x842A, 0xC864, + 0x842B, 0xC865, 0x842C, 0xC866, 0x842D, 0xC867, 0x842E, 0xC868, + 0x842F, 0xC869, 0x8430, 0xC86A, 0x8431, 0xDDE6, 0x8432, 0xC86B, + 0x8433, 0xC86C, 0x8434, 0xC86D, 0x8435, 0xC86E, 0x8436, 0xC86F, + 0x8437, 0xC870, 0x8438, 0xDDC7, 0x8439, 0xC871, 0x843A, 0xC872, + 0x843B, 0xC873, 0x843C, 0xDDE0, 0x843D, 0xC2E4, 0x843E, 0xC874, + 0x843F, 0xC875, 0x8440, 0xC876, 0x8441, 0xC877, 0x8442, 0xC878, + 0x8443, 0xC879, 0x8444, 0xC87A, 0x8445, 0xC87B, 0x8446, 0xDDE1, + 0x8447, 0xC87C, 0x8448, 0xC87D, 0x8449, 0xC87E, 0x844A, 0xC880, + 0x844B, 0xC881, 0x844C, 0xC882, 0x844D, 0xC883, 0x844E, 0xC884, + 0x844F, 0xC885, 0x8450, 0xC886, 0x8451, 0xDDD7, 0x8452, 0xC887, + 0x8453, 0xC888, 0x8454, 0xC889, 0x8455, 0xC88A, 0x8456, 0xC88B, + 0x8457, 0xD6F8, 0x8458, 0xC88C, 0x8459, 0xDDD9, 0x845A, 0xDDD8, + 0x845B, 0xB8F0, 0x845C, 0xDDD6, 0x845D, 0xC88D, 0x845E, 0xC88E, + 0x845F, 0xC88F, 0x8460, 0xC890, 0x8461, 0xC6CF, 0x8462, 0xC891, + 0x8463, 0xB6AD, 0x8464, 0xC892, 0x8465, 0xC893, 0x8466, 0xC894, + 0x8467, 0xC895, 0x8468, 0xC896, 0x8469, 0xDDE2, 0x846A, 0xC897, + 0x846B, 0xBAF9, 0x846C, 0xD4E1, 0x846D, 0xDDE7, 0x846E, 0xC898, + 0x846F, 0xC899, 0x8470, 0xC89A, 0x8471, 0xB4D0, 0x8472, 0xC89B, + 0x8473, 0xDDDA, 0x8474, 0xC89C, 0x8475, 0xBFFB, 0x8476, 0xDDE3, + 0x8477, 0xC89D, 0x8478, 0xDDDF, 0x8479, 0xC89E, 0x847A, 0xDDDD, + 0x847B, 0xC89F, 0x847C, 0xC8A0, 0x847D, 0xC940, 0x847E, 0xC941, + 0x847F, 0xC942, 0x8480, 0xC943, 0x8481, 0xC944, 0x8482, 0xB5D9, + 0x8483, 0xC945, 0x8484, 0xC946, 0x8485, 0xC947, 0x8486, 0xC948, + 0x8487, 0xDDDB, 0x8488, 0xDDDC, 0x8489, 0xDDDE, 0x848A, 0xC949, + 0x848B, 0xBDAF, 0x848C, 0xDDE4, 0x848D, 0xC94A, 0x848E, 0xDDE5, + 0x848F, 0xC94B, 0x8490, 0xC94C, 0x8491, 0xC94D, 0x8492, 0xC94E, + 0x8493, 0xC94F, 0x8494, 0xC950, 0x8495, 0xC951, 0x8496, 0xC952, + 0x8497, 0xDDF5, 0x8498, 0xC953, 0x8499, 0xC3C9, 0x849A, 0xC954, + 0x849B, 0xC955, 0x849C, 0xCBE2, 0x849D, 0xC956, 0x849E, 0xC957, + 0x849F, 0xC958, 0x84A0, 0xC959, 0x84A1, 0xDDF2, 0x84A2, 0xC95A, + 0x84A3, 0xC95B, 0x84A4, 0xC95C, 0x84A5, 0xC95D, 0x84A6, 0xC95E, + 0x84A7, 0xC95F, 0x84A8, 0xC960, 0x84A9, 0xC961, 0x84AA, 0xC962, + 0x84AB, 0xC963, 0x84AC, 0xC964, 0x84AD, 0xC965, 0x84AE, 0xC966, + 0x84AF, 0xD8E1, 0x84B0, 0xC967, 0x84B1, 0xC968, 0x84B2, 0xC6D1, + 0x84B3, 0xC969, 0x84B4, 0xDDF4, 0x84B5, 0xC96A, 0x84B6, 0xC96B, + 0x84B7, 0xC96C, 0x84B8, 0xD5F4, 0x84B9, 0xDDF3, 0x84BA, 0xDDF0, + 0x84BB, 0xC96D, 0x84BC, 0xC96E, 0x84BD, 0xDDEC, 0x84BE, 0xC96F, + 0x84BF, 0xDDEF, 0x84C0, 0xC970, 0x84C1, 0xDDE8, 0x84C2, 0xC971, + 0x84C3, 0xC972, 0x84C4, 0xD0EE, 0x84C5, 0xC973, 0x84C6, 0xC974, + 0x84C7, 0xC975, 0x84C8, 0xC976, 0x84C9, 0xC8D8, 0x84CA, 0xDDEE, + 0x84CB, 0xC977, 0x84CC, 0xC978, 0x84CD, 0xDDE9, 0x84CE, 0xC979, + 0x84CF, 0xC97A, 0x84D0, 0xDDEA, 0x84D1, 0xCBF2, 0x84D2, 0xC97B, + 0x84D3, 0xDDED, 0x84D4, 0xC97C, 0x84D5, 0xC97D, 0x84D6, 0xB1CD, + 0x84D7, 0xC97E, 0x84D8, 0xC980, 0x84D9, 0xC981, 0x84DA, 0xC982, + 0x84DB, 0xC983, 0x84DC, 0xC984, 0x84DD, 0xC0B6, 0x84DE, 0xC985, + 0x84DF, 0xBCBB, 0x84E0, 0xDDF1, 0x84E1, 0xC986, 0x84E2, 0xC987, + 0x84E3, 0xDDF7, 0x84E4, 0xC988, 0x84E5, 0xDDF6, 0x84E6, 0xDDEB, + 0x84E7, 0xC989, 0x84E8, 0xC98A, 0x84E9, 0xC98B, 0x84EA, 0xC98C, + 0x84EB, 0xC98D, 0x84EC, 0xC5EE, 0x84ED, 0xC98E, 0x84EE, 0xC98F, + 0x84EF, 0xC990, 0x84F0, 0xDDFB, 0x84F1, 0xC991, 0x84F2, 0xC992, + 0x84F3, 0xC993, 0x84F4, 0xC994, 0x84F5, 0xC995, 0x84F6, 0xC996, + 0x84F7, 0xC997, 0x84F8, 0xC998, 0x84F9, 0xC999, 0x84FA, 0xC99A, + 0x84FB, 0xC99B, 0x84FC, 0xDEA4, 0x84FD, 0xC99C, 0x84FE, 0xC99D, + 0x84FF, 0xDEA3, 0x8500, 0xC99E, 0x8501, 0xC99F, 0x8502, 0xC9A0, + 0x8503, 0xCA40, 0x8504, 0xCA41, 0x8505, 0xCA42, 0x8506, 0xCA43, + 0x8507, 0xCA44, 0x8508, 0xCA45, 0x8509, 0xCA46, 0x850A, 0xCA47, + 0x850B, 0xCA48, 0x850C, 0xDDF8, 0x850D, 0xCA49, 0x850E, 0xCA4A, + 0x850F, 0xCA4B, 0x8510, 0xCA4C, 0x8511, 0xC3EF, 0x8512, 0xCA4D, + 0x8513, 0xC2FB, 0x8514, 0xCA4E, 0x8515, 0xCA4F, 0x8516, 0xCA50, + 0x8517, 0xD5E1, 0x8518, 0xCA51, 0x8519, 0xCA52, 0x851A, 0xCEB5, + 0x851B, 0xCA53, 0x851C, 0xCA54, 0x851D, 0xCA55, 0x851E, 0xCA56, + 0x851F, 0xDDFD, 0x8520, 0xCA57, 0x8521, 0xB2CC, 0x8522, 0xCA58, + 0x8523, 0xCA59, 0x8524, 0xCA5A, 0x8525, 0xCA5B, 0x8526, 0xCA5C, + 0x8527, 0xCA5D, 0x8528, 0xCA5E, 0x8529, 0xCA5F, 0x852A, 0xCA60, + 0x852B, 0xC4E8, 0x852C, 0xCADF, 0x852D, 0xCA61, 0x852E, 0xCA62, + 0x852F, 0xCA63, 0x8530, 0xCA64, 0x8531, 0xCA65, 0x8532, 0xCA66, + 0x8533, 0xCA67, 0x8534, 0xCA68, 0x8535, 0xCA69, 0x8536, 0xCA6A, + 0x8537, 0xC7BE, 0x8538, 0xDDFA, 0x8539, 0xDDFC, 0x853A, 0xDDFE, + 0x853B, 0xDEA2, 0x853C, 0xB0AA, 0x853D, 0xB1CE, 0x853E, 0xCA6B, + 0x853F, 0xCA6C, 0x8540, 0xCA6D, 0x8541, 0xCA6E, 0x8542, 0xCA6F, + 0x8543, 0xDEAC, 0x8544, 0xCA70, 0x8545, 0xCA71, 0x8546, 0xCA72, + 0x8547, 0xCA73, 0x8548, 0xDEA6, 0x8549, 0xBDB6, 0x854A, 0xC8EF, + 0x854B, 0xCA74, 0x854C, 0xCA75, 0x854D, 0xCA76, 0x854E, 0xCA77, + 0x854F, 0xCA78, 0x8550, 0xCA79, 0x8551, 0xCA7A, 0x8552, 0xCA7B, + 0x8553, 0xCA7C, 0x8554, 0xCA7D, 0x8555, 0xCA7E, 0x8556, 0xDEA1, + 0x8557, 0xCA80, 0x8558, 0xCA81, 0x8559, 0xDEA5, 0x855A, 0xCA82, + 0x855B, 0xCA83, 0x855C, 0xCA84, 0x855D, 0xCA85, 0x855E, 0xDEA9, + 0x855F, 0xCA86, 0x8560, 0xCA87, 0x8561, 0xCA88, 0x8562, 0xCA89, + 0x8563, 0xCA8A, 0x8564, 0xDEA8, 0x8565, 0xCA8B, 0x8566, 0xCA8C, + 0x8567, 0xCA8D, 0x8568, 0xDEA7, 0x8569, 0xCA8E, 0x856A, 0xCA8F, + 0x856B, 0xCA90, 0x856C, 0xCA91, 0x856D, 0xCA92, 0x856E, 0xCA93, + 0x856F, 0xCA94, 0x8570, 0xCA95, 0x8571, 0xCA96, 0x8572, 0xDEAD, + 0x8573, 0xCA97, 0x8574, 0xD4CC, 0x8575, 0xCA98, 0x8576, 0xCA99, + 0x8577, 0xCA9A, 0x8578, 0xCA9B, 0x8579, 0xDEB3, 0x857A, 0xDEAA, + 0x857B, 0xDEAE, 0x857C, 0xCA9C, 0x857D, 0xCA9D, 0x857E, 0xC0D9, + 0x857F, 0xCA9E, 0x8580, 0xCA9F, 0x8581, 0xCAA0, 0x8582, 0xCB40, + 0x8583, 0xCB41, 0x8584, 0xB1A1, 0x8585, 0xDEB6, 0x8586, 0xCB42, + 0x8587, 0xDEB1, 0x8588, 0xCB43, 0x8589, 0xCB44, 0x858A, 0xCB45, + 0x858B, 0xCB46, 0x858C, 0xCB47, 0x858D, 0xCB48, 0x858E, 0xCB49, + 0x858F, 0xDEB2, 0x8590, 0xCB4A, 0x8591, 0xCB4B, 0x8592, 0xCB4C, + 0x8593, 0xCB4D, 0x8594, 0xCB4E, 0x8595, 0xCB4F, 0x8596, 0xCB50, + 0x8597, 0xCB51, 0x8598, 0xCB52, 0x8599, 0xCB53, 0x859A, 0xCB54, + 0x859B, 0xD1A6, 0x859C, 0xDEB5, 0x859D, 0xCB55, 0x859E, 0xCB56, + 0x859F, 0xCB57, 0x85A0, 0xCB58, 0x85A1, 0xCB59, 0x85A2, 0xCB5A, + 0x85A3, 0xCB5B, 0x85A4, 0xDEAF, 0x85A5, 0xCB5C, 0x85A6, 0xCB5D, + 0x85A7, 0xCB5E, 0x85A8, 0xDEB0, 0x85A9, 0xCB5F, 0x85AA, 0xD0BD, + 0x85AB, 0xCB60, 0x85AC, 0xCB61, 0x85AD, 0xCB62, 0x85AE, 0xDEB4, + 0x85AF, 0xCAED, 0x85B0, 0xDEB9, 0x85B1, 0xCB63, 0x85B2, 0xCB64, + 0x85B3, 0xCB65, 0x85B4, 0xCB66, 0x85B5, 0xCB67, 0x85B6, 0xCB68, + 0x85B7, 0xDEB8, 0x85B8, 0xCB69, 0x85B9, 0xDEB7, 0x85BA, 0xCB6A, + 0x85BB, 0xCB6B, 0x85BC, 0xCB6C, 0x85BD, 0xCB6D, 0x85BE, 0xCB6E, + 0x85BF, 0xCB6F, 0x85C0, 0xCB70, 0x85C1, 0xDEBB, 0x85C2, 0xCB71, + 0x85C3, 0xCB72, 0x85C4, 0xCB73, 0x85C5, 0xCB74, 0x85C6, 0xCB75, + 0x85C7, 0xCB76, 0x85C8, 0xCB77, 0x85C9, 0xBDE5, 0x85CA, 0xCB78, + 0x85CB, 0xCB79, 0x85CC, 0xCB7A, 0x85CD, 0xCB7B, 0x85CE, 0xCB7C, + 0x85CF, 0xB2D8, 0x85D0, 0xC3EA, 0x85D1, 0xCB7D, 0x85D2, 0xCB7E, + 0x85D3, 0xDEBA, 0x85D4, 0xCB80, 0x85D5, 0xC5BA, 0x85D6, 0xCB81, + 0x85D7, 0xCB82, 0x85D8, 0xCB83, 0x85D9, 0xCB84, 0x85DA, 0xCB85, + 0x85DB, 0xCB86, 0x85DC, 0xDEBC, 0x85DD, 0xCB87, 0x85DE, 0xCB88, + 0x85DF, 0xCB89, 0x85E0, 0xCB8A, 0x85E1, 0xCB8B, 0x85E2, 0xCB8C, + 0x85E3, 0xCB8D, 0x85E4, 0xCCD9, 0x85E5, 0xCB8E, 0x85E6, 0xCB8F, + 0x85E7, 0xCB90, 0x85E8, 0xCB91, 0x85E9, 0xB7AA, 0x85EA, 0xCB92, + 0x85EB, 0xCB93, 0x85EC, 0xCB94, 0x85ED, 0xCB95, 0x85EE, 0xCB96, + 0x85EF, 0xCB97, 0x85F0, 0xCB98, 0x85F1, 0xCB99, 0x85F2, 0xCB9A, + 0x85F3, 0xCB9B, 0x85F4, 0xCB9C, 0x85F5, 0xCB9D, 0x85F6, 0xCB9E, + 0x85F7, 0xCB9F, 0x85F8, 0xCBA0, 0x85F9, 0xCC40, 0x85FA, 0xCC41, + 0x85FB, 0xD4E5, 0x85FC, 0xCC42, 0x85FD, 0xCC43, 0x85FE, 0xCC44, + 0x85FF, 0xDEBD, 0x8600, 0xCC45, 0x8601, 0xCC46, 0x8602, 0xCC47, + 0x8603, 0xCC48, 0x8604, 0xCC49, 0x8605, 0xDEBF, 0x8606, 0xCC4A, + 0x8607, 0xCC4B, 0x8608, 0xCC4C, 0x8609, 0xCC4D, 0x860A, 0xCC4E, + 0x860B, 0xCC4F, 0x860C, 0xCC50, 0x860D, 0xCC51, 0x860E, 0xCC52, + 0x860F, 0xCC53, 0x8610, 0xCC54, 0x8611, 0xC4A2, 0x8612, 0xCC55, + 0x8613, 0xCC56, 0x8614, 0xCC57, 0x8615, 0xCC58, 0x8616, 0xDEC1, + 0x8617, 0xCC59, 0x8618, 0xCC5A, 0x8619, 0xCC5B, 0x861A, 0xCC5C, + 0x861B, 0xCC5D, 0x861C, 0xCC5E, 0x861D, 0xCC5F, 0x861E, 0xCC60, + 0x861F, 0xCC61, 0x8620, 0xCC62, 0x8621, 0xCC63, 0x8622, 0xCC64, + 0x8623, 0xCC65, 0x8624, 0xCC66, 0x8625, 0xCC67, 0x8626, 0xCC68, + 0x8627, 0xDEBE, 0x8628, 0xCC69, 0x8629, 0xDEC0, 0x862A, 0xCC6A, + 0x862B, 0xCC6B, 0x862C, 0xCC6C, 0x862D, 0xCC6D, 0x862E, 0xCC6E, + 0x862F, 0xCC6F, 0x8630, 0xCC70, 0x8631, 0xCC71, 0x8632, 0xCC72, + 0x8633, 0xCC73, 0x8634, 0xCC74, 0x8635, 0xCC75, 0x8636, 0xCC76, + 0x8637, 0xCC77, 0x8638, 0xD5BA, 0x8639, 0xCC78, 0x863A, 0xCC79, + 0x863B, 0xCC7A, 0x863C, 0xDEC2, 0x863D, 0xCC7B, 0x863E, 0xCC7C, + 0x863F, 0xCC7D, 0x8640, 0xCC7E, 0x8641, 0xCC80, 0x8642, 0xCC81, + 0x8643, 0xCC82, 0x8644, 0xCC83, 0x8645, 0xCC84, 0x8646, 0xCC85, + 0x8647, 0xCC86, 0x8648, 0xCC87, 0x8649, 0xCC88, 0x864A, 0xCC89, + 0x864B, 0xCC8A, 0x864C, 0xCC8B, 0x864D, 0xF2AE, 0x864E, 0xBBA2, + 0x864F, 0xC2B2, 0x8650, 0xC5B0, 0x8651, 0xC2C7, 0x8652, 0xCC8C, + 0x8653, 0xCC8D, 0x8654, 0xF2AF, 0x8655, 0xCC8E, 0x8656, 0xCC8F, + 0x8657, 0xCC90, 0x8658, 0xCC91, 0x8659, 0xCC92, 0x865A, 0xD0E9, + 0x865B, 0xCC93, 0x865C, 0xCC94, 0x865D, 0xCC95, 0x865E, 0xD3DD, + 0x865F, 0xCC96, 0x8660, 0xCC97, 0x8661, 0xCC98, 0x8662, 0xEBBD, + 0x8663, 0xCC99, 0x8664, 0xCC9A, 0x8665, 0xCC9B, 0x8666, 0xCC9C, + 0x8667, 0xCC9D, 0x8668, 0xCC9E, 0x8669, 0xCC9F, 0x866A, 0xCCA0, + 0x866B, 0xB3E6, 0x866C, 0xF2B0, 0x866D, 0xCD40, 0x866E, 0xF2B1, + 0x866F, 0xCD41, 0x8670, 0xCD42, 0x8671, 0xCAAD, 0x8672, 0xCD43, + 0x8673, 0xCD44, 0x8674, 0xCD45, 0x8675, 0xCD46, 0x8676, 0xCD47, + 0x8677, 0xCD48, 0x8678, 0xCD49, 0x8679, 0xBAE7, 0x867A, 0xF2B3, + 0x867B, 0xF2B5, 0x867C, 0xF2B4, 0x867D, 0xCBE4, 0x867E, 0xCFBA, + 0x867F, 0xF2B2, 0x8680, 0xCAB4, 0x8681, 0xD2CF, 0x8682, 0xC2EC, + 0x8683, 0xCD4A, 0x8684, 0xCD4B, 0x8685, 0xCD4C, 0x8686, 0xCD4D, + 0x8687, 0xCD4E, 0x8688, 0xCD4F, 0x8689, 0xCD50, 0x868A, 0xCEC3, + 0x868B, 0xF2B8, 0x868C, 0xB0F6, 0x868D, 0xF2B7, 0x868E, 0xCD51, + 0x868F, 0xCD52, 0x8690, 0xCD53, 0x8691, 0xCD54, 0x8692, 0xCD55, + 0x8693, 0xF2BE, 0x8694, 0xCD56, 0x8695, 0xB2CF, 0x8696, 0xCD57, + 0x8697, 0xCD58, 0x8698, 0xCD59, 0x8699, 0xCD5A, 0x869A, 0xCD5B, + 0x869B, 0xCD5C, 0x869C, 0xD1C1, 0x869D, 0xF2BA, 0x869E, 0xCD5D, + 0x869F, 0xCD5E, 0x86A0, 0xCD5F, 0x86A1, 0xCD60, 0x86A2, 0xCD61, + 0x86A3, 0xF2BC, 0x86A4, 0xD4E9, 0x86A5, 0xCD62, 0x86A6, 0xCD63, + 0x86A7, 0xF2BB, 0x86A8, 0xF2B6, 0x86A9, 0xF2BF, 0x86AA, 0xF2BD, + 0x86AB, 0xCD64, 0x86AC, 0xF2B9, 0x86AD, 0xCD65, 0x86AE, 0xCD66, + 0x86AF, 0xF2C7, 0x86B0, 0xF2C4, 0x86B1, 0xF2C6, 0x86B2, 0xCD67, + 0x86B3, 0xCD68, 0x86B4, 0xF2CA, 0x86B5, 0xF2C2, 0x86B6, 0xF2C0, + 0x86B7, 0xCD69, 0x86B8, 0xCD6A, 0x86B9, 0xCD6B, 0x86BA, 0xF2C5, + 0x86BB, 0xCD6C, 0x86BC, 0xCD6D, 0x86BD, 0xCD6E, 0x86BE, 0xCD6F, + 0x86BF, 0xCD70, 0x86C0, 0xD6FB, 0x86C1, 0xCD71, 0x86C2, 0xCD72, + 0x86C3, 0xCD73, 0x86C4, 0xF2C1, 0x86C5, 0xCD74, 0x86C6, 0xC7F9, + 0x86C7, 0xC9DF, 0x86C8, 0xCD75, 0x86C9, 0xF2C8, 0x86CA, 0xB9C6, + 0x86CB, 0xB5B0, 0x86CC, 0xCD76, 0x86CD, 0xCD77, 0x86CE, 0xF2C3, + 0x86CF, 0xF2C9, 0x86D0, 0xF2D0, 0x86D1, 0xF2D6, 0x86D2, 0xCD78, + 0x86D3, 0xCD79, 0x86D4, 0xBBD7, 0x86D5, 0xCD7A, 0x86D6, 0xCD7B, + 0x86D7, 0xCD7C, 0x86D8, 0xF2D5, 0x86D9, 0xCDDC, 0x86DA, 0xCD7D, + 0x86DB, 0xD6EB, 0x86DC, 0xCD7E, 0x86DD, 0xCD80, 0x86DE, 0xF2D2, + 0x86DF, 0xF2D4, 0x86E0, 0xCD81, 0x86E1, 0xCD82, 0x86E2, 0xCD83, + 0x86E3, 0xCD84, 0x86E4, 0xB8F2, 0x86E5, 0xCD85, 0x86E6, 0xCD86, + 0x86E7, 0xCD87, 0x86E8, 0xCD88, 0x86E9, 0xF2CB, 0x86EA, 0xCD89, + 0x86EB, 0xCD8A, 0x86EC, 0xCD8B, 0x86ED, 0xF2CE, 0x86EE, 0xC2F9, + 0x86EF, 0xCD8C, 0x86F0, 0xD5DD, 0x86F1, 0xF2CC, 0x86F2, 0xF2CD, + 0x86F3, 0xF2CF, 0x86F4, 0xF2D3, 0x86F5, 0xCD8D, 0x86F6, 0xCD8E, + 0x86F7, 0xCD8F, 0x86F8, 0xF2D9, 0x86F9, 0xD3BC, 0x86FA, 0xCD90, + 0x86FB, 0xCD91, 0x86FC, 0xCD92, 0x86FD, 0xCD93, 0x86FE, 0xB6EA, + 0x86FF, 0xCD94, 0x8700, 0xCAF1, 0x8701, 0xCD95, 0x8702, 0xB7E4, + 0x8703, 0xF2D7, 0x8704, 0xCD96, 0x8705, 0xCD97, 0x8706, 0xCD98, + 0x8707, 0xF2D8, 0x8708, 0xF2DA, 0x8709, 0xF2DD, 0x870A, 0xF2DB, + 0x870B, 0xCD99, 0x870C, 0xCD9A, 0x870D, 0xF2DC, 0x870E, 0xCD9B, + 0x870F, 0xCD9C, 0x8710, 0xCD9D, 0x8711, 0xCD9E, 0x8712, 0xD1D1, + 0x8713, 0xF2D1, 0x8714, 0xCD9F, 0x8715, 0xCDC9, 0x8716, 0xCDA0, + 0x8717, 0xCECF, 0x8718, 0xD6A9, 0x8719, 0xCE40, 0x871A, 0xF2E3, + 0x871B, 0xCE41, 0x871C, 0xC3DB, 0x871D, 0xCE42, 0x871E, 0xF2E0, + 0x871F, 0xCE43, 0x8720, 0xCE44, 0x8721, 0xC0AF, 0x8722, 0xF2EC, + 0x8723, 0xF2DE, 0x8724, 0xCE45, 0x8725, 0xF2E1, 0x8726, 0xCE46, + 0x8727, 0xCE47, 0x8728, 0xCE48, 0x8729, 0xF2E8, 0x872A, 0xCE49, + 0x872B, 0xCE4A, 0x872C, 0xCE4B, 0x872D, 0xCE4C, 0x872E, 0xF2E2, + 0x872F, 0xCE4D, 0x8730, 0xCE4E, 0x8731, 0xF2E7, 0x8732, 0xCE4F, + 0x8733, 0xCE50, 0x8734, 0xF2E6, 0x8735, 0xCE51, 0x8736, 0xCE52, + 0x8737, 0xF2E9, 0x8738, 0xCE53, 0x8739, 0xCE54, 0x873A, 0xCE55, + 0x873B, 0xF2DF, 0x873C, 0xCE56, 0x873D, 0xCE57, 0x873E, 0xF2E4, + 0x873F, 0xF2EA, 0x8740, 0xCE58, 0x8741, 0xCE59, 0x8742, 0xCE5A, + 0x8743, 0xCE5B, 0x8744, 0xCE5C, 0x8745, 0xCE5D, 0x8746, 0xCE5E, + 0x8747, 0xD3AC, 0x8748, 0xF2E5, 0x8749, 0xB2F5, 0x874A, 0xCE5F, + 0x874B, 0xCE60, 0x874C, 0xF2F2, 0x874D, 0xCE61, 0x874E, 0xD0AB, + 0x874F, 0xCE62, 0x8750, 0xCE63, 0x8751, 0xCE64, 0x8752, 0xCE65, + 0x8753, 0xF2F5, 0x8754, 0xCE66, 0x8755, 0xCE67, 0x8756, 0xCE68, + 0x8757, 0xBBC8, 0x8758, 0xCE69, 0x8759, 0xF2F9, 0x875A, 0xCE6A, + 0x875B, 0xCE6B, 0x875C, 0xCE6C, 0x875D, 0xCE6D, 0x875E, 0xCE6E, + 0x875F, 0xCE6F, 0x8760, 0xF2F0, 0x8761, 0xCE70, 0x8762, 0xCE71, + 0x8763, 0xF2F6, 0x8764, 0xF2F8, 0x8765, 0xF2FA, 0x8766, 0xCE72, + 0x8767, 0xCE73, 0x8768, 0xCE74, 0x8769, 0xCE75, 0x876A, 0xCE76, + 0x876B, 0xCE77, 0x876C, 0xCE78, 0x876D, 0xCE79, 0x876E, 0xF2F3, + 0x876F, 0xCE7A, 0x8770, 0xF2F1, 0x8771, 0xCE7B, 0x8772, 0xCE7C, + 0x8773, 0xCE7D, 0x8774, 0xBAFB, 0x8775, 0xCE7E, 0x8776, 0xB5FB, + 0x8777, 0xCE80, 0x8778, 0xCE81, 0x8779, 0xCE82, 0x877A, 0xCE83, + 0x877B, 0xF2EF, 0x877C, 0xF2F7, 0x877D, 0xF2ED, 0x877E, 0xF2EE, + 0x877F, 0xCE84, 0x8780, 0xCE85, 0x8781, 0xCE86, 0x8782, 0xF2EB, + 0x8783, 0xF3A6, 0x8784, 0xCE87, 0x8785, 0xF3A3, 0x8786, 0xCE88, + 0x8787, 0xCE89, 0x8788, 0xF3A2, 0x8789, 0xCE8A, 0x878A, 0xCE8B, + 0x878B, 0xF2F4, 0x878C, 0xCE8C, 0x878D, 0xC8DA, 0x878E, 0xCE8D, + 0x878F, 0xCE8E, 0x8790, 0xCE8F, 0x8791, 0xCE90, 0x8792, 0xCE91, + 0x8793, 0xF2FB, 0x8794, 0xCE92, 0x8795, 0xCE93, 0x8796, 0xCE94, + 0x8797, 0xF3A5, 0x8798, 0xCE95, 0x8799, 0xCE96, 0x879A, 0xCE97, + 0x879B, 0xCE98, 0x879C, 0xCE99, 0x879D, 0xCE9A, 0x879E, 0xCE9B, + 0x879F, 0xC3F8, 0x87A0, 0xCE9C, 0x87A1, 0xCE9D, 0x87A2, 0xCE9E, + 0x87A3, 0xCE9F, 0x87A4, 0xCEA0, 0x87A5, 0xCF40, 0x87A6, 0xCF41, + 0x87A7, 0xCF42, 0x87A8, 0xF2FD, 0x87A9, 0xCF43, 0x87AA, 0xCF44, + 0x87AB, 0xF3A7, 0x87AC, 0xF3A9, 0x87AD, 0xF3A4, 0x87AE, 0xCF45, + 0x87AF, 0xF2FC, 0x87B0, 0xCF46, 0x87B1, 0xCF47, 0x87B2, 0xCF48, + 0x87B3, 0xF3AB, 0x87B4, 0xCF49, 0x87B5, 0xF3AA, 0x87B6, 0xCF4A, + 0x87B7, 0xCF4B, 0x87B8, 0xCF4C, 0x87B9, 0xCF4D, 0x87BA, 0xC2DD, + 0x87BB, 0xCF4E, 0x87BC, 0xCF4F, 0x87BD, 0xF3AE, 0x87BE, 0xCF50, + 0x87BF, 0xCF51, 0x87C0, 0xF3B0, 0x87C1, 0xCF52, 0x87C2, 0xCF53, + 0x87C3, 0xCF54, 0x87C4, 0xCF55, 0x87C5, 0xCF56, 0x87C6, 0xF3A1, + 0x87C7, 0xCF57, 0x87C8, 0xCF58, 0x87C9, 0xCF59, 0x87CA, 0xF3B1, + 0x87CB, 0xF3AC, 0x87CC, 0xCF5A, 0x87CD, 0xCF5B, 0x87CE, 0xCF5C, + 0x87CF, 0xCF5D, 0x87D0, 0xCF5E, 0x87D1, 0xF3AF, 0x87D2, 0xF2FE, + 0x87D3, 0xF3AD, 0x87D4, 0xCF5F, 0x87D5, 0xCF60, 0x87D6, 0xCF61, + 0x87D7, 0xCF62, 0x87D8, 0xCF63, 0x87D9, 0xCF64, 0x87DA, 0xCF65, + 0x87DB, 0xF3B2, 0x87DC, 0xCF66, 0x87DD, 0xCF67, 0x87DE, 0xCF68, + 0x87DF, 0xCF69, 0x87E0, 0xF3B4, 0x87E1, 0xCF6A, 0x87E2, 0xCF6B, + 0x87E3, 0xCF6C, 0x87E4, 0xCF6D, 0x87E5, 0xF3A8, 0x87E6, 0xCF6E, + 0x87E7, 0xCF6F, 0x87E8, 0xCF70, 0x87E9, 0xCF71, 0x87EA, 0xF3B3, + 0x87EB, 0xCF72, 0x87EC, 0xCF73, 0x87ED, 0xCF74, 0x87EE, 0xF3B5, + 0x87EF, 0xCF75, 0x87F0, 0xCF76, 0x87F1, 0xCF77, 0x87F2, 0xCF78, + 0x87F3, 0xCF79, 0x87F4, 0xCF7A, 0x87F5, 0xCF7B, 0x87F6, 0xCF7C, + 0x87F7, 0xCF7D, 0x87F8, 0xCF7E, 0x87F9, 0xD0B7, 0x87FA, 0xCF80, + 0x87FB, 0xCF81, 0x87FC, 0xCF82, 0x87FD, 0xCF83, 0x87FE, 0xF3B8, + 0x87FF, 0xCF84, 0x8800, 0xCF85, 0x8801, 0xCF86, 0x8802, 0xCF87, + 0x8803, 0xD9F9, 0x8804, 0xCF88, 0x8805, 0xCF89, 0x8806, 0xCF8A, + 0x8807, 0xCF8B, 0x8808, 0xCF8C, 0x8809, 0xCF8D, 0x880A, 0xF3B9, + 0x880B, 0xCF8E, 0x880C, 0xCF8F, 0x880D, 0xCF90, 0x880E, 0xCF91, + 0x880F, 0xCF92, 0x8810, 0xCF93, 0x8811, 0xCF94, 0x8812, 0xCF95, + 0x8813, 0xF3B7, 0x8814, 0xCF96, 0x8815, 0xC8E4, 0x8816, 0xF3B6, + 0x8817, 0xCF97, 0x8818, 0xCF98, 0x8819, 0xCF99, 0x881A, 0xCF9A, + 0x881B, 0xF3BA, 0x881C, 0xCF9B, 0x881D, 0xCF9C, 0x881E, 0xCF9D, + 0x881F, 0xCF9E, 0x8820, 0xCF9F, 0x8821, 0xF3BB, 0x8822, 0xB4C0, + 0x8823, 0xCFA0, 0x8824, 0xD040, 0x8825, 0xD041, 0x8826, 0xD042, + 0x8827, 0xD043, 0x8828, 0xD044, 0x8829, 0xD045, 0x882A, 0xD046, + 0x882B, 0xD047, 0x882C, 0xD048, 0x882D, 0xD049, 0x882E, 0xD04A, + 0x882F, 0xD04B, 0x8830, 0xD04C, 0x8831, 0xD04D, 0x8832, 0xEEC3, + 0x8833, 0xD04E, 0x8834, 0xD04F, 0x8835, 0xD050, 0x8836, 0xD051, + 0x8837, 0xD052, 0x8838, 0xD053, 0x8839, 0xF3BC, 0x883A, 0xD054, + 0x883B, 0xD055, 0x883C, 0xF3BD, 0x883D, 0xD056, 0x883E, 0xD057, + 0x883F, 0xD058, 0x8840, 0xD1AA, 0x8841, 0xD059, 0x8842, 0xD05A, + 0x8843, 0xD05B, 0x8844, 0xF4AC, 0x8845, 0xD0C6, 0x8846, 0xD05C, + 0x8847, 0xD05D, 0x8848, 0xD05E, 0x8849, 0xD05F, 0x884A, 0xD060, + 0x884B, 0xD061, 0x884C, 0xD0D0, 0x884D, 0xD1DC, 0x884E, 0xD062, + 0x884F, 0xD063, 0x8850, 0xD064, 0x8851, 0xD065, 0x8852, 0xD066, + 0x8853, 0xD067, 0x8854, 0xCFCE, 0x8855, 0xD068, 0x8856, 0xD069, + 0x8857, 0xBDD6, 0x8858, 0xD06A, 0x8859, 0xD1C3, 0x885A, 0xD06B, + 0x885B, 0xD06C, 0x885C, 0xD06D, 0x885D, 0xD06E, 0x885E, 0xD06F, + 0x885F, 0xD070, 0x8860, 0xD071, 0x8861, 0xBAE2, 0x8862, 0xE1E9, + 0x8863, 0xD2C2, 0x8864, 0xF1C2, 0x8865, 0xB2B9, 0x8866, 0xD072, + 0x8867, 0xD073, 0x8868, 0xB1ED, 0x8869, 0xF1C3, 0x886A, 0xD074, + 0x886B, 0xC9C0, 0x886C, 0xB3C4, 0x886D, 0xD075, 0x886E, 0xD9F2, + 0x886F, 0xD076, 0x8870, 0xCBA5, 0x8871, 0xD077, 0x8872, 0xF1C4, + 0x8873, 0xD078, 0x8874, 0xD079, 0x8875, 0xD07A, 0x8876, 0xD07B, + 0x8877, 0xD6D4, 0x8878, 0xD07C, 0x8879, 0xD07D, 0x887A, 0xD07E, + 0x887B, 0xD080, 0x887C, 0xD081, 0x887D, 0xF1C5, 0x887E, 0xF4C0, + 0x887F, 0xF1C6, 0x8880, 0xD082, 0x8881, 0xD4AC, 0x8882, 0xF1C7, + 0x8883, 0xD083, 0x8884, 0xB0C0, 0x8885, 0xF4C1, 0x8886, 0xD084, + 0x8887, 0xD085, 0x8888, 0xF4C2, 0x8889, 0xD086, 0x888A, 0xD087, + 0x888B, 0xB4FC, 0x888C, 0xD088, 0x888D, 0xC5DB, 0x888E, 0xD089, + 0x888F, 0xD08A, 0x8890, 0xD08B, 0x8891, 0xD08C, 0x8892, 0xCCBB, + 0x8893, 0xD08D, 0x8894, 0xD08E, 0x8895, 0xD08F, 0x8896, 0xD0E4, + 0x8897, 0xD090, 0x8898, 0xD091, 0x8899, 0xD092, 0x889A, 0xD093, + 0x889B, 0xD094, 0x889C, 0xCDE0, 0x889D, 0xD095, 0x889E, 0xD096, + 0x889F, 0xD097, 0x88A0, 0xD098, 0x88A1, 0xD099, 0x88A2, 0xF1C8, + 0x88A3, 0xD09A, 0x88A4, 0xD9F3, 0x88A5, 0xD09B, 0x88A6, 0xD09C, + 0x88A7, 0xD09D, 0x88A8, 0xD09E, 0x88A9, 0xD09F, 0x88AA, 0xD0A0, + 0x88AB, 0xB1BB, 0x88AC, 0xD140, 0x88AD, 0xCFAE, 0x88AE, 0xD141, + 0x88AF, 0xD142, 0x88B0, 0xD143, 0x88B1, 0xB8A4, 0x88B2, 0xD144, + 0x88B3, 0xD145, 0x88B4, 0xD146, 0x88B5, 0xD147, 0x88B6, 0xD148, + 0x88B7, 0xF1CA, 0x88B8, 0xD149, 0x88B9, 0xD14A, 0x88BA, 0xD14B, + 0x88BB, 0xD14C, 0x88BC, 0xF1CB, 0x88BD, 0xD14D, 0x88BE, 0xD14E, + 0x88BF, 0xD14F, 0x88C0, 0xD150, 0x88C1, 0xB2C3, 0x88C2, 0xC1D1, + 0x88C3, 0xD151, 0x88C4, 0xD152, 0x88C5, 0xD7B0, 0x88C6, 0xF1C9, + 0x88C7, 0xD153, 0x88C8, 0xD154, 0x88C9, 0xF1CC, 0x88CA, 0xD155, + 0x88CB, 0xD156, 0x88CC, 0xD157, 0x88CD, 0xD158, 0x88CE, 0xF1CE, + 0x88CF, 0xD159, 0x88D0, 0xD15A, 0x88D1, 0xD15B, 0x88D2, 0xD9F6, + 0x88D3, 0xD15C, 0x88D4, 0xD2E1, 0x88D5, 0xD4A3, 0x88D6, 0xD15D, + 0x88D7, 0xD15E, 0x88D8, 0xF4C3, 0x88D9, 0xC8B9, 0x88DA, 0xD15F, + 0x88DB, 0xD160, 0x88DC, 0xD161, 0x88DD, 0xD162, 0x88DE, 0xD163, + 0x88DF, 0xF4C4, 0x88E0, 0xD164, 0x88E1, 0xD165, 0x88E2, 0xF1CD, + 0x88E3, 0xF1CF, 0x88E4, 0xBFE3, 0x88E5, 0xF1D0, 0x88E6, 0xD166, + 0x88E7, 0xD167, 0x88E8, 0xF1D4, 0x88E9, 0xD168, 0x88EA, 0xD169, + 0x88EB, 0xD16A, 0x88EC, 0xD16B, 0x88ED, 0xD16C, 0x88EE, 0xD16D, + 0x88EF, 0xD16E, 0x88F0, 0xF1D6, 0x88F1, 0xF1D1, 0x88F2, 0xD16F, + 0x88F3, 0xC9D1, 0x88F4, 0xC5E1, 0x88F5, 0xD170, 0x88F6, 0xD171, + 0x88F7, 0xD172, 0x88F8, 0xC2E3, 0x88F9, 0xB9FC, 0x88FA, 0xD173, + 0x88FB, 0xD174, 0x88FC, 0xF1D3, 0x88FD, 0xD175, 0x88FE, 0xF1D5, + 0x88FF, 0xD176, 0x8900, 0xD177, 0x8901, 0xD178, 0x8902, 0xB9D3, + 0x8903, 0xD179, 0x8904, 0xD17A, 0x8905, 0xD17B, 0x8906, 0xD17C, + 0x8907, 0xD17D, 0x8908, 0xD17E, 0x8909, 0xD180, 0x890A, 0xF1DB, + 0x890B, 0xD181, 0x890C, 0xD182, 0x890D, 0xD183, 0x890E, 0xD184, + 0x890F, 0xD185, 0x8910, 0xBAD6, 0x8911, 0xD186, 0x8912, 0xB0FD, + 0x8913, 0xF1D9, 0x8914, 0xD187, 0x8915, 0xD188, 0x8916, 0xD189, + 0x8917, 0xD18A, 0x8918, 0xD18B, 0x8919, 0xF1D8, 0x891A, 0xF1D2, + 0x891B, 0xF1DA, 0x891C, 0xD18C, 0x891D, 0xD18D, 0x891E, 0xD18E, + 0x891F, 0xD18F, 0x8920, 0xD190, 0x8921, 0xF1D7, 0x8922, 0xD191, + 0x8923, 0xD192, 0x8924, 0xD193, 0x8925, 0xC8EC, 0x8926, 0xD194, + 0x8927, 0xD195, 0x8928, 0xD196, 0x8929, 0xD197, 0x892A, 0xCDCA, + 0x892B, 0xF1DD, 0x892C, 0xD198, 0x892D, 0xD199, 0x892E, 0xD19A, + 0x892F, 0xD19B, 0x8930, 0xE5BD, 0x8931, 0xD19C, 0x8932, 0xD19D, + 0x8933, 0xD19E, 0x8934, 0xF1DC, 0x8935, 0xD19F, 0x8936, 0xF1DE, + 0x8937, 0xD1A0, 0x8938, 0xD240, 0x8939, 0xD241, 0x893A, 0xD242, + 0x893B, 0xD243, 0x893C, 0xD244, 0x893D, 0xD245, 0x893E, 0xD246, + 0x893F, 0xD247, 0x8940, 0xD248, 0x8941, 0xF1DF, 0x8942, 0xD249, + 0x8943, 0xD24A, 0x8944, 0xCFE5, 0x8945, 0xD24B, 0x8946, 0xD24C, + 0x8947, 0xD24D, 0x8948, 0xD24E, 0x8949, 0xD24F, 0x894A, 0xD250, + 0x894B, 0xD251, 0x894C, 0xD252, 0x894D, 0xD253, 0x894E, 0xD254, + 0x894F, 0xD255, 0x8950, 0xD256, 0x8951, 0xD257, 0x8952, 0xD258, + 0x8953, 0xD259, 0x8954, 0xD25A, 0x8955, 0xD25B, 0x8956, 0xD25C, + 0x8957, 0xD25D, 0x8958, 0xD25E, 0x8959, 0xD25F, 0x895A, 0xD260, + 0x895B, 0xD261, 0x895C, 0xD262, 0x895D, 0xD263, 0x895E, 0xF4C5, + 0x895F, 0xBDF3, 0x8960, 0xD264, 0x8961, 0xD265, 0x8962, 0xD266, + 0x8963, 0xD267, 0x8964, 0xD268, 0x8965, 0xD269, 0x8966, 0xF1E0, + 0x8967, 0xD26A, 0x8968, 0xD26B, 0x8969, 0xD26C, 0x896A, 0xD26D, + 0x896B, 0xD26E, 0x896C, 0xD26F, 0x896D, 0xD270, 0x896E, 0xD271, + 0x896F, 0xD272, 0x8970, 0xD273, 0x8971, 0xD274, 0x8972, 0xD275, + 0x8973, 0xD276, 0x8974, 0xD277, 0x8975, 0xD278, 0x8976, 0xD279, + 0x8977, 0xD27A, 0x8978, 0xD27B, 0x8979, 0xD27C, 0x897A, 0xD27D, + 0x897B, 0xF1E1, 0x897C, 0xD27E, 0x897D, 0xD280, 0x897E, 0xD281, + 0x897F, 0xCEF7, 0x8980, 0xD282, 0x8981, 0xD2AA, 0x8982, 0xD283, + 0x8983, 0xF1FB, 0x8984, 0xD284, 0x8985, 0xD285, 0x8986, 0xB8B2, + 0x8987, 0xD286, 0x8988, 0xD287, 0x8989, 0xD288, 0x898A, 0xD289, + 0x898B, 0xD28A, 0x898C, 0xD28B, 0x898D, 0xD28C, 0x898E, 0xD28D, + 0x898F, 0xD28E, 0x8990, 0xD28F, 0x8991, 0xD290, 0x8992, 0xD291, + 0x8993, 0xD292, 0x8994, 0xD293, 0x8995, 0xD294, 0x8996, 0xD295, + 0x8997, 0xD296, 0x8998, 0xD297, 0x8999, 0xD298, 0x899A, 0xD299, + 0x899B, 0xD29A, 0x899C, 0xD29B, 0x899D, 0xD29C, 0x899E, 0xD29D, + 0x899F, 0xD29E, 0x89A0, 0xD29F, 0x89A1, 0xD2A0, 0x89A2, 0xD340, + 0x89A3, 0xD341, 0x89A4, 0xD342, 0x89A5, 0xD343, 0x89A6, 0xD344, + 0x89A7, 0xD345, 0x89A8, 0xD346, 0x89A9, 0xD347, 0x89AA, 0xD348, + 0x89AB, 0xD349, 0x89AC, 0xD34A, 0x89AD, 0xD34B, 0x89AE, 0xD34C, + 0x89AF, 0xD34D, 0x89B0, 0xD34E, 0x89B1, 0xD34F, 0x89B2, 0xD350, + 0x89B3, 0xD351, 0x89B4, 0xD352, 0x89B5, 0xD353, 0x89B6, 0xD354, + 0x89B7, 0xD355, 0x89B8, 0xD356, 0x89B9, 0xD357, 0x89BA, 0xD358, + 0x89BB, 0xD359, 0x89BC, 0xD35A, 0x89BD, 0xD35B, 0x89BE, 0xD35C, + 0x89BF, 0xD35D, 0x89C0, 0xD35E, 0x89C1, 0xBCFB, 0x89C2, 0xB9DB, + 0x89C3, 0xD35F, 0x89C4, 0xB9E6, 0x89C5, 0xC3D9, 0x89C6, 0xCAD3, + 0x89C7, 0xEAE8, 0x89C8, 0xC0C0, 0x89C9, 0xBEF5, 0x89CA, 0xEAE9, + 0x89CB, 0xEAEA, 0x89CC, 0xEAEB, 0x89CD, 0xD360, 0x89CE, 0xEAEC, + 0x89CF, 0xEAED, 0x89D0, 0xEAEE, 0x89D1, 0xEAEF, 0x89D2, 0xBDC7, + 0x89D3, 0xD361, 0x89D4, 0xD362, 0x89D5, 0xD363, 0x89D6, 0xF5FB, + 0x89D7, 0xD364, 0x89D8, 0xD365, 0x89D9, 0xD366, 0x89DA, 0xF5FD, + 0x89DB, 0xD367, 0x89DC, 0xF5FE, 0x89DD, 0xD368, 0x89DE, 0xF5FC, + 0x89DF, 0xD369, 0x89E0, 0xD36A, 0x89E1, 0xD36B, 0x89E2, 0xD36C, + 0x89E3, 0xBDE2, 0x89E4, 0xD36D, 0x89E5, 0xF6A1, 0x89E6, 0xB4A5, + 0x89E7, 0xD36E, 0x89E8, 0xD36F, 0x89E9, 0xD370, 0x89EA, 0xD371, + 0x89EB, 0xF6A2, 0x89EC, 0xD372, 0x89ED, 0xD373, 0x89EE, 0xD374, + 0x89EF, 0xF6A3, 0x89F0, 0xD375, 0x89F1, 0xD376, 0x89F2, 0xD377, + 0x89F3, 0xECB2, 0x89F4, 0xD378, 0x89F5, 0xD379, 0x89F6, 0xD37A, + 0x89F7, 0xD37B, 0x89F8, 0xD37C, 0x89F9, 0xD37D, 0x89FA, 0xD37E, + 0x89FB, 0xD380, 0x89FC, 0xD381, 0x89FD, 0xD382, 0x89FE, 0xD383, + 0x89FF, 0xD384, 0x8A00, 0xD1D4, 0x8A01, 0xD385, 0x8A02, 0xD386, + 0x8A03, 0xD387, 0x8A04, 0xD388, 0x8A05, 0xD389, 0x8A06, 0xD38A, + 0x8A07, 0xD9EA, 0x8A08, 0xD38B, 0x8A09, 0xD38C, 0x8A0A, 0xD38D, + 0x8A0B, 0xD38E, 0x8A0C, 0xD38F, 0x8A0D, 0xD390, 0x8A0E, 0xD391, + 0x8A0F, 0xD392, 0x8A10, 0xD393, 0x8A11, 0xD394, 0x8A12, 0xD395, + 0x8A13, 0xD396, 0x8A14, 0xD397, 0x8A15, 0xD398, 0x8A16, 0xD399, + 0x8A17, 0xD39A, 0x8A18, 0xD39B, 0x8A19, 0xD39C, 0x8A1A, 0xD39D, + 0x8A1B, 0xD39E, 0x8A1C, 0xD39F, 0x8A1D, 0xD3A0, 0x8A1E, 0xD440, + 0x8A1F, 0xD441, 0x8A20, 0xD442, 0x8A21, 0xD443, 0x8A22, 0xD444, + 0x8A23, 0xD445, 0x8A24, 0xD446, 0x8A25, 0xD447, 0x8A26, 0xD448, + 0x8A27, 0xD449, 0x8A28, 0xD44A, 0x8A29, 0xD44B, 0x8A2A, 0xD44C, + 0x8A2B, 0xD44D, 0x8A2C, 0xD44E, 0x8A2D, 0xD44F, 0x8A2E, 0xD450, + 0x8A2F, 0xD451, 0x8A30, 0xD452, 0x8A31, 0xD453, 0x8A32, 0xD454, + 0x8A33, 0xD455, 0x8A34, 0xD456, 0x8A35, 0xD457, 0x8A36, 0xD458, + 0x8A37, 0xD459, 0x8A38, 0xD45A, 0x8A39, 0xD45B, 0x8A3A, 0xD45C, + 0x8A3B, 0xD45D, 0x8A3C, 0xD45E, 0x8A3D, 0xD45F, 0x8A3E, 0xF6A4, + 0x8A3F, 0xD460, 0x8A40, 0xD461, 0x8A41, 0xD462, 0x8A42, 0xD463, + 0x8A43, 0xD464, 0x8A44, 0xD465, 0x8A45, 0xD466, 0x8A46, 0xD467, + 0x8A47, 0xD468, 0x8A48, 0xEEBA, 0x8A49, 0xD469, 0x8A4A, 0xD46A, + 0x8A4B, 0xD46B, 0x8A4C, 0xD46C, 0x8A4D, 0xD46D, 0x8A4E, 0xD46E, + 0x8A4F, 0xD46F, 0x8A50, 0xD470, 0x8A51, 0xD471, 0x8A52, 0xD472, + 0x8A53, 0xD473, 0x8A54, 0xD474, 0x8A55, 0xD475, 0x8A56, 0xD476, + 0x8A57, 0xD477, 0x8A58, 0xD478, 0x8A59, 0xD479, 0x8A5A, 0xD47A, + 0x8A5B, 0xD47B, 0x8A5C, 0xD47C, 0x8A5D, 0xD47D, 0x8A5E, 0xD47E, + 0x8A5F, 0xD480, 0x8A60, 0xD481, 0x8A61, 0xD482, 0x8A62, 0xD483, + 0x8A63, 0xD484, 0x8A64, 0xD485, 0x8A65, 0xD486, 0x8A66, 0xD487, + 0x8A67, 0xD488, 0x8A68, 0xD489, 0x8A69, 0xD48A, 0x8A6A, 0xD48B, + 0x8A6B, 0xD48C, 0x8A6C, 0xD48D, 0x8A6D, 0xD48E, 0x8A6E, 0xD48F, + 0x8A6F, 0xD490, 0x8A70, 0xD491, 0x8A71, 0xD492, 0x8A72, 0xD493, + 0x8A73, 0xD494, 0x8A74, 0xD495, 0x8A75, 0xD496, 0x8A76, 0xD497, + 0x8A77, 0xD498, 0x8A78, 0xD499, 0x8A79, 0xD5B2, 0x8A7A, 0xD49A, + 0x8A7B, 0xD49B, 0x8A7C, 0xD49C, 0x8A7D, 0xD49D, 0x8A7E, 0xD49E, + 0x8A7F, 0xD49F, 0x8A80, 0xD4A0, 0x8A81, 0xD540, 0x8A82, 0xD541, + 0x8A83, 0xD542, 0x8A84, 0xD543, 0x8A85, 0xD544, 0x8A86, 0xD545, + 0x8A87, 0xD546, 0x8A88, 0xD547, 0x8A89, 0xD3FE, 0x8A8A, 0xCCDC, + 0x8A8B, 0xD548, 0x8A8C, 0xD549, 0x8A8D, 0xD54A, 0x8A8E, 0xD54B, + 0x8A8F, 0xD54C, 0x8A90, 0xD54D, 0x8A91, 0xD54E, 0x8A92, 0xD54F, + 0x8A93, 0xCAC4, 0x8A94, 0xD550, 0x8A95, 0xD551, 0x8A96, 0xD552, + 0x8A97, 0xD553, 0x8A98, 0xD554, 0x8A99, 0xD555, 0x8A9A, 0xD556, + 0x8A9B, 0xD557, 0x8A9C, 0xD558, 0x8A9D, 0xD559, 0x8A9E, 0xD55A, + 0x8A9F, 0xD55B, 0x8AA0, 0xD55C, 0x8AA1, 0xD55D, 0x8AA2, 0xD55E, + 0x8AA3, 0xD55F, 0x8AA4, 0xD560, 0x8AA5, 0xD561, 0x8AA6, 0xD562, + 0x8AA7, 0xD563, 0x8AA8, 0xD564, 0x8AA9, 0xD565, 0x8AAA, 0xD566, + 0x8AAB, 0xD567, 0x8AAC, 0xD568, 0x8AAD, 0xD569, 0x8AAE, 0xD56A, + 0x8AAF, 0xD56B, 0x8AB0, 0xD56C, 0x8AB1, 0xD56D, 0x8AB2, 0xD56E, + 0x8AB3, 0xD56F, 0x8AB4, 0xD570, 0x8AB5, 0xD571, 0x8AB6, 0xD572, + 0x8AB7, 0xD573, 0x8AB8, 0xD574, 0x8AB9, 0xD575, 0x8ABA, 0xD576, + 0x8ABB, 0xD577, 0x8ABC, 0xD578, 0x8ABD, 0xD579, 0x8ABE, 0xD57A, + 0x8ABF, 0xD57B, 0x8AC0, 0xD57C, 0x8AC1, 0xD57D, 0x8AC2, 0xD57E, + 0x8AC3, 0xD580, 0x8AC4, 0xD581, 0x8AC5, 0xD582, 0x8AC6, 0xD583, + 0x8AC7, 0xD584, 0x8AC8, 0xD585, 0x8AC9, 0xD586, 0x8ACA, 0xD587, + 0x8ACB, 0xD588, 0x8ACC, 0xD589, 0x8ACD, 0xD58A, 0x8ACE, 0xD58B, + 0x8ACF, 0xD58C, 0x8AD0, 0xD58D, 0x8AD1, 0xD58E, 0x8AD2, 0xD58F, + 0x8AD3, 0xD590, 0x8AD4, 0xD591, 0x8AD5, 0xD592, 0x8AD6, 0xD593, + 0x8AD7, 0xD594, 0x8AD8, 0xD595, 0x8AD9, 0xD596, 0x8ADA, 0xD597, + 0x8ADB, 0xD598, 0x8ADC, 0xD599, 0x8ADD, 0xD59A, 0x8ADE, 0xD59B, + 0x8ADF, 0xD59C, 0x8AE0, 0xD59D, 0x8AE1, 0xD59E, 0x8AE2, 0xD59F, + 0x8AE3, 0xD5A0, 0x8AE4, 0xD640, 0x8AE5, 0xD641, 0x8AE6, 0xD642, + 0x8AE7, 0xD643, 0x8AE8, 0xD644, 0x8AE9, 0xD645, 0x8AEA, 0xD646, + 0x8AEB, 0xD647, 0x8AEC, 0xD648, 0x8AED, 0xD649, 0x8AEE, 0xD64A, + 0x8AEF, 0xD64B, 0x8AF0, 0xD64C, 0x8AF1, 0xD64D, 0x8AF2, 0xD64E, + 0x8AF3, 0xD64F, 0x8AF4, 0xD650, 0x8AF5, 0xD651, 0x8AF6, 0xD652, + 0x8AF7, 0xD653, 0x8AF8, 0xD654, 0x8AF9, 0xD655, 0x8AFA, 0xD656, + 0x8AFB, 0xD657, 0x8AFC, 0xD658, 0x8AFD, 0xD659, 0x8AFE, 0xD65A, + 0x8AFF, 0xD65B, 0x8B00, 0xD65C, 0x8B01, 0xD65D, 0x8B02, 0xD65E, + 0x8B03, 0xD65F, 0x8B04, 0xD660, 0x8B05, 0xD661, 0x8B06, 0xD662, + 0x8B07, 0xE5C0, 0x8B08, 0xD663, 0x8B09, 0xD664, 0x8B0A, 0xD665, + 0x8B0B, 0xD666, 0x8B0C, 0xD667, 0x8B0D, 0xD668, 0x8B0E, 0xD669, + 0x8B0F, 0xD66A, 0x8B10, 0xD66B, 0x8B11, 0xD66C, 0x8B12, 0xD66D, + 0x8B13, 0xD66E, 0x8B14, 0xD66F, 0x8B15, 0xD670, 0x8B16, 0xD671, + 0x8B17, 0xD672, 0x8B18, 0xD673, 0x8B19, 0xD674, 0x8B1A, 0xD675, + 0x8B1B, 0xD676, 0x8B1C, 0xD677, 0x8B1D, 0xD678, 0x8B1E, 0xD679, + 0x8B1F, 0xD67A, 0x8B20, 0xD67B, 0x8B21, 0xD67C, 0x8B22, 0xD67D, + 0x8B23, 0xD67E, 0x8B24, 0xD680, 0x8B25, 0xD681, 0x8B26, 0xF6A5, + 0x8B27, 0xD682, 0x8B28, 0xD683, 0x8B29, 0xD684, 0x8B2A, 0xD685, + 0x8B2B, 0xD686, 0x8B2C, 0xD687, 0x8B2D, 0xD688, 0x8B2E, 0xD689, + 0x8B2F, 0xD68A, 0x8B30, 0xD68B, 0x8B31, 0xD68C, 0x8B32, 0xD68D, + 0x8B33, 0xD68E, 0x8B34, 0xD68F, 0x8B35, 0xD690, 0x8B36, 0xD691, + 0x8B37, 0xD692, 0x8B38, 0xD693, 0x8B39, 0xD694, 0x8B3A, 0xD695, + 0x8B3B, 0xD696, 0x8B3C, 0xD697, 0x8B3D, 0xD698, 0x8B3E, 0xD699, + 0x8B3F, 0xD69A, 0x8B40, 0xD69B, 0x8B41, 0xD69C, 0x8B42, 0xD69D, + 0x8B43, 0xD69E, 0x8B44, 0xD69F, 0x8B45, 0xD6A0, 0x8B46, 0xD740, + 0x8B47, 0xD741, 0x8B48, 0xD742, 0x8B49, 0xD743, 0x8B4A, 0xD744, + 0x8B4B, 0xD745, 0x8B4C, 0xD746, 0x8B4D, 0xD747, 0x8B4E, 0xD748, + 0x8B4F, 0xD749, 0x8B50, 0xD74A, 0x8B51, 0xD74B, 0x8B52, 0xD74C, + 0x8B53, 0xD74D, 0x8B54, 0xD74E, 0x8B55, 0xD74F, 0x8B56, 0xD750, + 0x8B57, 0xD751, 0x8B58, 0xD752, 0x8B59, 0xD753, 0x8B5A, 0xD754, + 0x8B5B, 0xD755, 0x8B5C, 0xD756, 0x8B5D, 0xD757, 0x8B5E, 0xD758, + 0x8B5F, 0xD759, 0x8B60, 0xD75A, 0x8B61, 0xD75B, 0x8B62, 0xD75C, + 0x8B63, 0xD75D, 0x8B64, 0xD75E, 0x8B65, 0xD75F, 0x8B66, 0xBEAF, + 0x8B67, 0xD760, 0x8B68, 0xD761, 0x8B69, 0xD762, 0x8B6A, 0xD763, + 0x8B6B, 0xD764, 0x8B6C, 0xC6A9, 0x8B6D, 0xD765, 0x8B6E, 0xD766, + 0x8B6F, 0xD767, 0x8B70, 0xD768, 0x8B71, 0xD769, 0x8B72, 0xD76A, + 0x8B73, 0xD76B, 0x8B74, 0xD76C, 0x8B75, 0xD76D, 0x8B76, 0xD76E, + 0x8B77, 0xD76F, 0x8B78, 0xD770, 0x8B79, 0xD771, 0x8B7A, 0xD772, + 0x8B7B, 0xD773, 0x8B7C, 0xD774, 0x8B7D, 0xD775, 0x8B7E, 0xD776, + 0x8B7F, 0xD777, 0x8B80, 0xD778, 0x8B81, 0xD779, 0x8B82, 0xD77A, + 0x8B83, 0xD77B, 0x8B84, 0xD77C, 0x8B85, 0xD77D, 0x8B86, 0xD77E, + 0x8B87, 0xD780, 0x8B88, 0xD781, 0x8B89, 0xD782, 0x8B8A, 0xD783, + 0x8B8B, 0xD784, 0x8B8C, 0xD785, 0x8B8D, 0xD786, 0x8B8E, 0xD787, + 0x8B8F, 0xD788, 0x8B90, 0xD789, 0x8B91, 0xD78A, 0x8B92, 0xD78B, + 0x8B93, 0xD78C, 0x8B94, 0xD78D, 0x8B95, 0xD78E, 0x8B96, 0xD78F, + 0x8B97, 0xD790, 0x8B98, 0xD791, 0x8B99, 0xD792, 0x8B9A, 0xD793, + 0x8B9B, 0xD794, 0x8B9C, 0xD795, 0x8B9D, 0xD796, 0x8B9E, 0xD797, + 0x8B9F, 0xD798, 0x8BA0, 0xDAA5, 0x8BA1, 0xBCC6, 0x8BA2, 0xB6A9, + 0x8BA3, 0xB8BC, 0x8BA4, 0xC8CF, 0x8BA5, 0xBCA5, 0x8BA6, 0xDAA6, + 0x8BA7, 0xDAA7, 0x8BA8, 0xCCD6, 0x8BA9, 0xC8C3, 0x8BAA, 0xDAA8, + 0x8BAB, 0xC6FD, 0x8BAC, 0xD799, 0x8BAD, 0xD1B5, 0x8BAE, 0xD2E9, + 0x8BAF, 0xD1B6, 0x8BB0, 0xBCC7, 0x8BB1, 0xD79A, 0x8BB2, 0xBDB2, + 0x8BB3, 0xBBE4, 0x8BB4, 0xDAA9, 0x8BB5, 0xDAAA, 0x8BB6, 0xD1C8, + 0x8BB7, 0xDAAB, 0x8BB8, 0xD0ED, 0x8BB9, 0xB6EF, 0x8BBA, 0xC2DB, + 0x8BBB, 0xD79B, 0x8BBC, 0xCBCF, 0x8BBD, 0xB7ED, 0x8BBE, 0xC9E8, + 0x8BBF, 0xB7C3, 0x8BC0, 0xBEF7, 0x8BC1, 0xD6A4, 0x8BC2, 0xDAAC, + 0x8BC3, 0xDAAD, 0x8BC4, 0xC6C0, 0x8BC5, 0xD7E7, 0x8BC6, 0xCAB6, + 0x8BC7, 0xD79C, 0x8BC8, 0xD5A9, 0x8BC9, 0xCBDF, 0x8BCA, 0xD5EF, + 0x8BCB, 0xDAAE, 0x8BCC, 0xD6DF, 0x8BCD, 0xB4CA, 0x8BCE, 0xDAB0, + 0x8BCF, 0xDAAF, 0x8BD0, 0xD79D, 0x8BD1, 0xD2EB, 0x8BD2, 0xDAB1, + 0x8BD3, 0xDAB2, 0x8BD4, 0xDAB3, 0x8BD5, 0xCAD4, 0x8BD6, 0xDAB4, + 0x8BD7, 0xCAAB, 0x8BD8, 0xDAB5, 0x8BD9, 0xDAB6, 0x8BDA, 0xB3CF, + 0x8BDB, 0xD6EF, 0x8BDC, 0xDAB7, 0x8BDD, 0xBBB0, 0x8BDE, 0xB5AE, + 0x8BDF, 0xDAB8, 0x8BE0, 0xDAB9, 0x8BE1, 0xB9EE, 0x8BE2, 0xD1AF, + 0x8BE3, 0xD2E8, 0x8BE4, 0xDABA, 0x8BE5, 0xB8C3, 0x8BE6, 0xCFEA, + 0x8BE7, 0xB2EF, 0x8BE8, 0xDABB, 0x8BE9, 0xDABC, 0x8BEA, 0xD79E, + 0x8BEB, 0xBDEB, 0x8BEC, 0xCEDC, 0x8BED, 0xD3EF, 0x8BEE, 0xDABD, + 0x8BEF, 0xCEF3, 0x8BF0, 0xDABE, 0x8BF1, 0xD3D5, 0x8BF2, 0xBBE5, + 0x8BF3, 0xDABF, 0x8BF4, 0xCBB5, 0x8BF5, 0xCBD0, 0x8BF6, 0xDAC0, + 0x8BF7, 0xC7EB, 0x8BF8, 0xD6EE, 0x8BF9, 0xDAC1, 0x8BFA, 0xC5B5, + 0x8BFB, 0xB6C1, 0x8BFC, 0xDAC2, 0x8BFD, 0xB7CC, 0x8BFE, 0xBFCE, + 0x8BFF, 0xDAC3, 0x8C00, 0xDAC4, 0x8C01, 0xCBAD, 0x8C02, 0xDAC5, + 0x8C03, 0xB5F7, 0x8C04, 0xDAC6, 0x8C05, 0xC1C2, 0x8C06, 0xD7BB, + 0x8C07, 0xDAC7, 0x8C08, 0xCCB8, 0x8C09, 0xD79F, 0x8C0A, 0xD2EA, + 0x8C0B, 0xC4B1, 0x8C0C, 0xDAC8, 0x8C0D, 0xB5FD, 0x8C0E, 0xBBD1, + 0x8C0F, 0xDAC9, 0x8C10, 0xD0B3, 0x8C11, 0xDACA, 0x8C12, 0xDACB, + 0x8C13, 0xCEBD, 0x8C14, 0xDACC, 0x8C15, 0xDACD, 0x8C16, 0xDACE, + 0x8C17, 0xB2F7, 0x8C18, 0xDAD1, 0x8C19, 0xDACF, 0x8C1A, 0xD1E8, + 0x8C1B, 0xDAD0, 0x8C1C, 0xC3D5, 0x8C1D, 0xDAD2, 0x8C1E, 0xD7A0, + 0x8C1F, 0xDAD3, 0x8C20, 0xDAD4, 0x8C21, 0xDAD5, 0x8C22, 0xD0BB, + 0x8C23, 0xD2A5, 0x8C24, 0xB0F9, 0x8C25, 0xDAD6, 0x8C26, 0xC7AB, + 0x8C27, 0xDAD7, 0x8C28, 0xBDF7, 0x8C29, 0xC3A1, 0x8C2A, 0xDAD8, + 0x8C2B, 0xDAD9, 0x8C2C, 0xC3FD, 0x8C2D, 0xCCB7, 0x8C2E, 0xDADA, + 0x8C2F, 0xDADB, 0x8C30, 0xC0BE, 0x8C31, 0xC6D7, 0x8C32, 0xDADC, + 0x8C33, 0xDADD, 0x8C34, 0xC7B4, 0x8C35, 0xDADE, 0x8C36, 0xDADF, + 0x8C37, 0xB9C8, 0x8C38, 0xD840, 0x8C39, 0xD841, 0x8C3A, 0xD842, + 0x8C3B, 0xD843, 0x8C3C, 0xD844, 0x8C3D, 0xD845, 0x8C3E, 0xD846, + 0x8C3F, 0xD847, 0x8C40, 0xD848, 0x8C41, 0xBBED, 0x8C42, 0xD849, + 0x8C43, 0xD84A, 0x8C44, 0xD84B, 0x8C45, 0xD84C, 0x8C46, 0xB6B9, + 0x8C47, 0xF4F8, 0x8C48, 0xD84D, 0x8C49, 0xF4F9, 0x8C4A, 0xD84E, + 0x8C4B, 0xD84F, 0x8C4C, 0xCDE3, 0x8C4D, 0xD850, 0x8C4E, 0xD851, + 0x8C4F, 0xD852, 0x8C50, 0xD853, 0x8C51, 0xD854, 0x8C52, 0xD855, + 0x8C53, 0xD856, 0x8C54, 0xD857, 0x8C55, 0xF5B9, 0x8C56, 0xD858, + 0x8C57, 0xD859, 0x8C58, 0xD85A, 0x8C59, 0xD85B, 0x8C5A, 0xEBE0, + 0x8C5B, 0xD85C, 0x8C5C, 0xD85D, 0x8C5D, 0xD85E, 0x8C5E, 0xD85F, + 0x8C5F, 0xD860, 0x8C60, 0xD861, 0x8C61, 0xCFF3, 0x8C62, 0xBBBF, + 0x8C63, 0xD862, 0x8C64, 0xD863, 0x8C65, 0xD864, 0x8C66, 0xD865, + 0x8C67, 0xD866, 0x8C68, 0xD867, 0x8C69, 0xD868, 0x8C6A, 0xBAC0, + 0x8C6B, 0xD4A5, 0x8C6C, 0xD869, 0x8C6D, 0xD86A, 0x8C6E, 0xD86B, + 0x8C6F, 0xD86C, 0x8C70, 0xD86D, 0x8C71, 0xD86E, 0x8C72, 0xD86F, + 0x8C73, 0xE1D9, 0x8C74, 0xD870, 0x8C75, 0xD871, 0x8C76, 0xD872, + 0x8C77, 0xD873, 0x8C78, 0xF5F4, 0x8C79, 0xB1AA, 0x8C7A, 0xB2F2, + 0x8C7B, 0xD874, 0x8C7C, 0xD875, 0x8C7D, 0xD876, 0x8C7E, 0xD877, + 0x8C7F, 0xD878, 0x8C80, 0xD879, 0x8C81, 0xD87A, 0x8C82, 0xF5F5, + 0x8C83, 0xD87B, 0x8C84, 0xD87C, 0x8C85, 0xF5F7, 0x8C86, 0xD87D, + 0x8C87, 0xD87E, 0x8C88, 0xD880, 0x8C89, 0xBAD1, 0x8C8A, 0xF5F6, + 0x8C8B, 0xD881, 0x8C8C, 0xC3B2, 0x8C8D, 0xD882, 0x8C8E, 0xD883, + 0x8C8F, 0xD884, 0x8C90, 0xD885, 0x8C91, 0xD886, 0x8C92, 0xD887, + 0x8C93, 0xD888, 0x8C94, 0xF5F9, 0x8C95, 0xD889, 0x8C96, 0xD88A, + 0x8C97, 0xD88B, 0x8C98, 0xF5F8, 0x8C99, 0xD88C, 0x8C9A, 0xD88D, + 0x8C9B, 0xD88E, 0x8C9C, 0xD88F, 0x8C9D, 0xD890, 0x8C9E, 0xD891, + 0x8C9F, 0xD892, 0x8CA0, 0xD893, 0x8CA1, 0xD894, 0x8CA2, 0xD895, + 0x8CA3, 0xD896, 0x8CA4, 0xD897, 0x8CA5, 0xD898, 0x8CA6, 0xD899, + 0x8CA7, 0xD89A, 0x8CA8, 0xD89B, 0x8CA9, 0xD89C, 0x8CAA, 0xD89D, + 0x8CAB, 0xD89E, 0x8CAC, 0xD89F, 0x8CAD, 0xD8A0, 0x8CAE, 0xD940, + 0x8CAF, 0xD941, 0x8CB0, 0xD942, 0x8CB1, 0xD943, 0x8CB2, 0xD944, + 0x8CB3, 0xD945, 0x8CB4, 0xD946, 0x8CB5, 0xD947, 0x8CB6, 0xD948, + 0x8CB7, 0xD949, 0x8CB8, 0xD94A, 0x8CB9, 0xD94B, 0x8CBA, 0xD94C, + 0x8CBB, 0xD94D, 0x8CBC, 0xD94E, 0x8CBD, 0xD94F, 0x8CBE, 0xD950, + 0x8CBF, 0xD951, 0x8CC0, 0xD952, 0x8CC1, 0xD953, 0x8CC2, 0xD954, + 0x8CC3, 0xD955, 0x8CC4, 0xD956, 0x8CC5, 0xD957, 0x8CC6, 0xD958, + 0x8CC7, 0xD959, 0x8CC8, 0xD95A, 0x8CC9, 0xD95B, 0x8CCA, 0xD95C, + 0x8CCB, 0xD95D, 0x8CCC, 0xD95E, 0x8CCD, 0xD95F, 0x8CCE, 0xD960, + 0x8CCF, 0xD961, 0x8CD0, 0xD962, 0x8CD1, 0xD963, 0x8CD2, 0xD964, + 0x8CD3, 0xD965, 0x8CD4, 0xD966, 0x8CD5, 0xD967, 0x8CD6, 0xD968, + 0x8CD7, 0xD969, 0x8CD8, 0xD96A, 0x8CD9, 0xD96B, 0x8CDA, 0xD96C, + 0x8CDB, 0xD96D, 0x8CDC, 0xD96E, 0x8CDD, 0xD96F, 0x8CDE, 0xD970, + 0x8CDF, 0xD971, 0x8CE0, 0xD972, 0x8CE1, 0xD973, 0x8CE2, 0xD974, + 0x8CE3, 0xD975, 0x8CE4, 0xD976, 0x8CE5, 0xD977, 0x8CE6, 0xD978, + 0x8CE7, 0xD979, 0x8CE8, 0xD97A, 0x8CE9, 0xD97B, 0x8CEA, 0xD97C, + 0x8CEB, 0xD97D, 0x8CEC, 0xD97E, 0x8CED, 0xD980, 0x8CEE, 0xD981, + 0x8CEF, 0xD982, 0x8CF0, 0xD983, 0x8CF1, 0xD984, 0x8CF2, 0xD985, + 0x8CF3, 0xD986, 0x8CF4, 0xD987, 0x8CF5, 0xD988, 0x8CF6, 0xD989, + 0x8CF7, 0xD98A, 0x8CF8, 0xD98B, 0x8CF9, 0xD98C, 0x8CFA, 0xD98D, + 0x8CFB, 0xD98E, 0x8CFC, 0xD98F, 0x8CFD, 0xD990, 0x8CFE, 0xD991, + 0x8CFF, 0xD992, 0x8D00, 0xD993, 0x8D01, 0xD994, 0x8D02, 0xD995, + 0x8D03, 0xD996, 0x8D04, 0xD997, 0x8D05, 0xD998, 0x8D06, 0xD999, + 0x8D07, 0xD99A, 0x8D08, 0xD99B, 0x8D09, 0xD99C, 0x8D0A, 0xD99D, + 0x8D0B, 0xD99E, 0x8D0C, 0xD99F, 0x8D0D, 0xD9A0, 0x8D0E, 0xDA40, + 0x8D0F, 0xDA41, 0x8D10, 0xDA42, 0x8D11, 0xDA43, 0x8D12, 0xDA44, + 0x8D13, 0xDA45, 0x8D14, 0xDA46, 0x8D15, 0xDA47, 0x8D16, 0xDA48, + 0x8D17, 0xDA49, 0x8D18, 0xDA4A, 0x8D19, 0xDA4B, 0x8D1A, 0xDA4C, + 0x8D1B, 0xDA4D, 0x8D1C, 0xDA4E, 0x8D1D, 0xB1B4, 0x8D1E, 0xD5EA, + 0x8D1F, 0xB8BA, 0x8D20, 0xDA4F, 0x8D21, 0xB9B1, 0x8D22, 0xB2C6, + 0x8D23, 0xD4F0, 0x8D24, 0xCFCD, 0x8D25, 0xB0DC, 0x8D26, 0xD5CB, + 0x8D27, 0xBBF5, 0x8D28, 0xD6CA, 0x8D29, 0xB7B7, 0x8D2A, 0xCCB0, + 0x8D2B, 0xC6B6, 0x8D2C, 0xB1E1, 0x8D2D, 0xB9BA, 0x8D2E, 0xD6FC, + 0x8D2F, 0xB9E1, 0x8D30, 0xB7A1, 0x8D31, 0xBCFA, 0x8D32, 0xEADA, + 0x8D33, 0xEADB, 0x8D34, 0xCCF9, 0x8D35, 0xB9F3, 0x8D36, 0xEADC, + 0x8D37, 0xB4FB, 0x8D38, 0xC3B3, 0x8D39, 0xB7D1, 0x8D3A, 0xBAD8, + 0x8D3B, 0xEADD, 0x8D3C, 0xD4F4, 0x8D3D, 0xEADE, 0x8D3E, 0xBCD6, + 0x8D3F, 0xBBDF, 0x8D40, 0xEADF, 0x8D41, 0xC1DE, 0x8D42, 0xC2B8, + 0x8D43, 0xD4DF, 0x8D44, 0xD7CA, 0x8D45, 0xEAE0, 0x8D46, 0xEAE1, + 0x8D47, 0xEAE4, 0x8D48, 0xEAE2, 0x8D49, 0xEAE3, 0x8D4A, 0xC9DE, + 0x8D4B, 0xB8B3, 0x8D4C, 0xB6C4, 0x8D4D, 0xEAE5, 0x8D4E, 0xCAEA, + 0x8D4F, 0xC9CD, 0x8D50, 0xB4CD, 0x8D51, 0xDA50, 0x8D52, 0xDA51, + 0x8D53, 0xE2D9, 0x8D54, 0xC5E2, 0x8D55, 0xEAE6, 0x8D56, 0xC0B5, + 0x8D57, 0xDA52, 0x8D58, 0xD7B8, 0x8D59, 0xEAE7, 0x8D5A, 0xD7AC, + 0x8D5B, 0xC8FC, 0x8D5C, 0xD8D3, 0x8D5D, 0xD8CD, 0x8D5E, 0xD4DE, + 0x8D5F, 0xDA53, 0x8D60, 0xD4F9, 0x8D61, 0xC9C4, 0x8D62, 0xD3AE, + 0x8D63, 0xB8D3, 0x8D64, 0xB3E0, 0x8D65, 0xDA54, 0x8D66, 0xC9E2, + 0x8D67, 0xF4F6, 0x8D68, 0xDA55, 0x8D69, 0xDA56, 0x8D6A, 0xDA57, + 0x8D6B, 0xBAD5, 0x8D6C, 0xDA58, 0x8D6D, 0xF4F7, 0x8D6E, 0xDA59, + 0x8D6F, 0xDA5A, 0x8D70, 0xD7DF, 0x8D71, 0xDA5B, 0x8D72, 0xDA5C, + 0x8D73, 0xF4F1, 0x8D74, 0xB8B0, 0x8D75, 0xD5D4, 0x8D76, 0xB8CF, + 0x8D77, 0xC6F0, 0x8D78, 0xDA5D, 0x8D79, 0xDA5E, 0x8D7A, 0xDA5F, + 0x8D7B, 0xDA60, 0x8D7C, 0xDA61, 0x8D7D, 0xDA62, 0x8D7E, 0xDA63, + 0x8D7F, 0xDA64, 0x8D80, 0xDA65, 0x8D81, 0xB3C3, 0x8D82, 0xDA66, + 0x8D83, 0xDA67, 0x8D84, 0xF4F2, 0x8D85, 0xB3AC, 0x8D86, 0xDA68, + 0x8D87, 0xDA69, 0x8D88, 0xDA6A, 0x8D89, 0xDA6B, 0x8D8A, 0xD4BD, + 0x8D8B, 0xC7F7, 0x8D8C, 0xDA6C, 0x8D8D, 0xDA6D, 0x8D8E, 0xDA6E, + 0x8D8F, 0xDA6F, 0x8D90, 0xDA70, 0x8D91, 0xF4F4, 0x8D92, 0xDA71, + 0x8D93, 0xDA72, 0x8D94, 0xF4F3, 0x8D95, 0xDA73, 0x8D96, 0xDA74, + 0x8D97, 0xDA75, 0x8D98, 0xDA76, 0x8D99, 0xDA77, 0x8D9A, 0xDA78, + 0x8D9B, 0xDA79, 0x8D9C, 0xDA7A, 0x8D9D, 0xDA7B, 0x8D9E, 0xDA7C, + 0x8D9F, 0xCCCB, 0x8DA0, 0xDA7D, 0x8DA1, 0xDA7E, 0x8DA2, 0xDA80, + 0x8DA3, 0xC8A4, 0x8DA4, 0xDA81, 0x8DA5, 0xDA82, 0x8DA6, 0xDA83, + 0x8DA7, 0xDA84, 0x8DA8, 0xDA85, 0x8DA9, 0xDA86, 0x8DAA, 0xDA87, + 0x8DAB, 0xDA88, 0x8DAC, 0xDA89, 0x8DAD, 0xDA8A, 0x8DAE, 0xDA8B, + 0x8DAF, 0xDA8C, 0x8DB0, 0xDA8D, 0x8DB1, 0xF4F5, 0x8DB2, 0xDA8E, + 0x8DB3, 0xD7E3, 0x8DB4, 0xC5BF, 0x8DB5, 0xF5C0, 0x8DB6, 0xDA8F, + 0x8DB7, 0xDA90, 0x8DB8, 0xF5BB, 0x8DB9, 0xDA91, 0x8DBA, 0xF5C3, + 0x8DBB, 0xDA92, 0x8DBC, 0xF5C2, 0x8DBD, 0xDA93, 0x8DBE, 0xD6BA, + 0x8DBF, 0xF5C1, 0x8DC0, 0xDA94, 0x8DC1, 0xDA95, 0x8DC2, 0xDA96, + 0x8DC3, 0xD4BE, 0x8DC4, 0xF5C4, 0x8DC5, 0xDA97, 0x8DC6, 0xF5CC, + 0x8DC7, 0xDA98, 0x8DC8, 0xDA99, 0x8DC9, 0xDA9A, 0x8DCA, 0xDA9B, + 0x8DCB, 0xB0CF, 0x8DCC, 0xB5F8, 0x8DCD, 0xDA9C, 0x8DCE, 0xF5C9, + 0x8DCF, 0xF5CA, 0x8DD0, 0xDA9D, 0x8DD1, 0xC5DC, 0x8DD2, 0xDA9E, + 0x8DD3, 0xDA9F, 0x8DD4, 0xDAA0, 0x8DD5, 0xDB40, 0x8DD6, 0xF5C5, + 0x8DD7, 0xF5C6, 0x8DD8, 0xDB41, 0x8DD9, 0xDB42, 0x8DDA, 0xF5C7, + 0x8DDB, 0xF5CB, 0x8DDC, 0xDB43, 0x8DDD, 0xBEE0, 0x8DDE, 0xF5C8, + 0x8DDF, 0xB8FA, 0x8DE0, 0xDB44, 0x8DE1, 0xDB45, 0x8DE2, 0xDB46, + 0x8DE3, 0xF5D0, 0x8DE4, 0xF5D3, 0x8DE5, 0xDB47, 0x8DE6, 0xDB48, + 0x8DE7, 0xDB49, 0x8DE8, 0xBFE7, 0x8DE9, 0xDB4A, 0x8DEA, 0xB9F2, + 0x8DEB, 0xF5BC, 0x8DEC, 0xF5CD, 0x8DED, 0xDB4B, 0x8DEE, 0xDB4C, + 0x8DEF, 0xC2B7, 0x8DF0, 0xDB4D, 0x8DF1, 0xDB4E, 0x8DF2, 0xDB4F, + 0x8DF3, 0xCCF8, 0x8DF4, 0xDB50, 0x8DF5, 0xBCF9, 0x8DF6, 0xDB51, + 0x8DF7, 0xF5CE, 0x8DF8, 0xF5CF, 0x8DF9, 0xF5D1, 0x8DFA, 0xB6E5, + 0x8DFB, 0xF5D2, 0x8DFC, 0xDB52, 0x8DFD, 0xF5D5, 0x8DFE, 0xDB53, + 0x8DFF, 0xDB54, 0x8E00, 0xDB55, 0x8E01, 0xDB56, 0x8E02, 0xDB57, + 0x8E03, 0xDB58, 0x8E04, 0xDB59, 0x8E05, 0xF5BD, 0x8E06, 0xDB5A, + 0x8E07, 0xDB5B, 0x8E08, 0xDB5C, 0x8E09, 0xF5D4, 0x8E0A, 0xD3BB, + 0x8E0B, 0xDB5D, 0x8E0C, 0xB3EC, 0x8E0D, 0xDB5E, 0x8E0E, 0xDB5F, + 0x8E0F, 0xCCA4, 0x8E10, 0xDB60, 0x8E11, 0xDB61, 0x8E12, 0xDB62, + 0x8E13, 0xDB63, 0x8E14, 0xF5D6, 0x8E15, 0xDB64, 0x8E16, 0xDB65, + 0x8E17, 0xDB66, 0x8E18, 0xDB67, 0x8E19, 0xDB68, 0x8E1A, 0xDB69, + 0x8E1B, 0xDB6A, 0x8E1C, 0xDB6B, 0x8E1D, 0xF5D7, 0x8E1E, 0xBEE1, + 0x8E1F, 0xF5D8, 0x8E20, 0xDB6C, 0x8E21, 0xDB6D, 0x8E22, 0xCCDF, + 0x8E23, 0xF5DB, 0x8E24, 0xDB6E, 0x8E25, 0xDB6F, 0x8E26, 0xDB70, + 0x8E27, 0xDB71, 0x8E28, 0xDB72, 0x8E29, 0xB2C8, 0x8E2A, 0xD7D9, + 0x8E2B, 0xDB73, 0x8E2C, 0xF5D9, 0x8E2D, 0xDB74, 0x8E2E, 0xF5DA, + 0x8E2F, 0xF5DC, 0x8E30, 0xDB75, 0x8E31, 0xF5E2, 0x8E32, 0xDB76, + 0x8E33, 0xDB77, 0x8E34, 0xDB78, 0x8E35, 0xF5E0, 0x8E36, 0xDB79, + 0x8E37, 0xDB7A, 0x8E38, 0xDB7B, 0x8E39, 0xF5DF, 0x8E3A, 0xF5DD, + 0x8E3B, 0xDB7C, 0x8E3C, 0xDB7D, 0x8E3D, 0xF5E1, 0x8E3E, 0xDB7E, + 0x8E3F, 0xDB80, 0x8E40, 0xF5DE, 0x8E41, 0xF5E4, 0x8E42, 0xF5E5, + 0x8E43, 0xDB81, 0x8E44, 0xCCE3, 0x8E45, 0xDB82, 0x8E46, 0xDB83, + 0x8E47, 0xE5BF, 0x8E48, 0xB5B8, 0x8E49, 0xF5E3, 0x8E4A, 0xF5E8, + 0x8E4B, 0xCCA3, 0x8E4C, 0xDB84, 0x8E4D, 0xDB85, 0x8E4E, 0xDB86, + 0x8E4F, 0xDB87, 0x8E50, 0xDB88, 0x8E51, 0xF5E6, 0x8E52, 0xF5E7, + 0x8E53, 0xDB89, 0x8E54, 0xDB8A, 0x8E55, 0xDB8B, 0x8E56, 0xDB8C, + 0x8E57, 0xDB8D, 0x8E58, 0xDB8E, 0x8E59, 0xF5BE, 0x8E5A, 0xDB8F, + 0x8E5B, 0xDB90, 0x8E5C, 0xDB91, 0x8E5D, 0xDB92, 0x8E5E, 0xDB93, + 0x8E5F, 0xDB94, 0x8E60, 0xDB95, 0x8E61, 0xDB96, 0x8E62, 0xDB97, + 0x8E63, 0xDB98, 0x8E64, 0xDB99, 0x8E65, 0xDB9A, 0x8E66, 0xB1C4, + 0x8E67, 0xDB9B, 0x8E68, 0xDB9C, 0x8E69, 0xF5BF, 0x8E6A, 0xDB9D, + 0x8E6B, 0xDB9E, 0x8E6C, 0xB5C5, 0x8E6D, 0xB2E4, 0x8E6E, 0xDB9F, + 0x8E6F, 0xF5EC, 0x8E70, 0xF5E9, 0x8E71, 0xDBA0, 0x8E72, 0xB6D7, + 0x8E73, 0xDC40, 0x8E74, 0xF5ED, 0x8E75, 0xDC41, 0x8E76, 0xF5EA, + 0x8E77, 0xDC42, 0x8E78, 0xDC43, 0x8E79, 0xDC44, 0x8E7A, 0xDC45, + 0x8E7B, 0xDC46, 0x8E7C, 0xF5EB, 0x8E7D, 0xDC47, 0x8E7E, 0xDC48, + 0x8E7F, 0xB4DA, 0x8E80, 0xDC49, 0x8E81, 0xD4EA, 0x8E82, 0xDC4A, + 0x8E83, 0xDC4B, 0x8E84, 0xDC4C, 0x8E85, 0xF5EE, 0x8E86, 0xDC4D, + 0x8E87, 0xB3F9, 0x8E88, 0xDC4E, 0x8E89, 0xDC4F, 0x8E8A, 0xDC50, + 0x8E8B, 0xDC51, 0x8E8C, 0xDC52, 0x8E8D, 0xDC53, 0x8E8E, 0xDC54, + 0x8E8F, 0xF5EF, 0x8E90, 0xF5F1, 0x8E91, 0xDC55, 0x8E92, 0xDC56, + 0x8E93, 0xDC57, 0x8E94, 0xF5F0, 0x8E95, 0xDC58, 0x8E96, 0xDC59, + 0x8E97, 0xDC5A, 0x8E98, 0xDC5B, 0x8E99, 0xDC5C, 0x8E9A, 0xDC5D, + 0x8E9B, 0xDC5E, 0x8E9C, 0xF5F2, 0x8E9D, 0xDC5F, 0x8E9E, 0xF5F3, + 0x8E9F, 0xDC60, 0x8EA0, 0xDC61, 0x8EA1, 0xDC62, 0x8EA2, 0xDC63, + 0x8EA3, 0xDC64, 0x8EA4, 0xDC65, 0x8EA5, 0xDC66, 0x8EA6, 0xDC67, + 0x8EA7, 0xDC68, 0x8EA8, 0xDC69, 0x8EA9, 0xDC6A, 0x8EAA, 0xDC6B, + 0x8EAB, 0xC9ED, 0x8EAC, 0xB9AA, 0x8EAD, 0xDC6C, 0x8EAE, 0xDC6D, + 0x8EAF, 0xC7FB, 0x8EB0, 0xDC6E, 0x8EB1, 0xDC6F, 0x8EB2, 0xB6E3, + 0x8EB3, 0xDC70, 0x8EB4, 0xDC71, 0x8EB5, 0xDC72, 0x8EB6, 0xDC73, + 0x8EB7, 0xDC74, 0x8EB8, 0xDC75, 0x8EB9, 0xDC76, 0x8EBA, 0xCCC9, + 0x8EBB, 0xDC77, 0x8EBC, 0xDC78, 0x8EBD, 0xDC79, 0x8EBE, 0xDC7A, + 0x8EBF, 0xDC7B, 0x8EC0, 0xDC7C, 0x8EC1, 0xDC7D, 0x8EC2, 0xDC7E, + 0x8EC3, 0xDC80, 0x8EC4, 0xDC81, 0x8EC5, 0xDC82, 0x8EC6, 0xDC83, + 0x8EC7, 0xDC84, 0x8EC8, 0xDC85, 0x8EC9, 0xDC86, 0x8ECA, 0xDC87, + 0x8ECB, 0xDC88, 0x8ECC, 0xDC89, 0x8ECD, 0xDC8A, 0x8ECE, 0xEAA6, + 0x8ECF, 0xDC8B, 0x8ED0, 0xDC8C, 0x8ED1, 0xDC8D, 0x8ED2, 0xDC8E, + 0x8ED3, 0xDC8F, 0x8ED4, 0xDC90, 0x8ED5, 0xDC91, 0x8ED6, 0xDC92, + 0x8ED7, 0xDC93, 0x8ED8, 0xDC94, 0x8ED9, 0xDC95, 0x8EDA, 0xDC96, + 0x8EDB, 0xDC97, 0x8EDC, 0xDC98, 0x8EDD, 0xDC99, 0x8EDE, 0xDC9A, + 0x8EDF, 0xDC9B, 0x8EE0, 0xDC9C, 0x8EE1, 0xDC9D, 0x8EE2, 0xDC9E, + 0x8EE3, 0xDC9F, 0x8EE4, 0xDCA0, 0x8EE5, 0xDD40, 0x8EE6, 0xDD41, + 0x8EE7, 0xDD42, 0x8EE8, 0xDD43, 0x8EE9, 0xDD44, 0x8EEA, 0xDD45, + 0x8EEB, 0xDD46, 0x8EEC, 0xDD47, 0x8EED, 0xDD48, 0x8EEE, 0xDD49, + 0x8EEF, 0xDD4A, 0x8EF0, 0xDD4B, 0x8EF1, 0xDD4C, 0x8EF2, 0xDD4D, + 0x8EF3, 0xDD4E, 0x8EF4, 0xDD4F, 0x8EF5, 0xDD50, 0x8EF6, 0xDD51, + 0x8EF7, 0xDD52, 0x8EF8, 0xDD53, 0x8EF9, 0xDD54, 0x8EFA, 0xDD55, + 0x8EFB, 0xDD56, 0x8EFC, 0xDD57, 0x8EFD, 0xDD58, 0x8EFE, 0xDD59, + 0x8EFF, 0xDD5A, 0x8F00, 0xDD5B, 0x8F01, 0xDD5C, 0x8F02, 0xDD5D, + 0x8F03, 0xDD5E, 0x8F04, 0xDD5F, 0x8F05, 0xDD60, 0x8F06, 0xDD61, + 0x8F07, 0xDD62, 0x8F08, 0xDD63, 0x8F09, 0xDD64, 0x8F0A, 0xDD65, + 0x8F0B, 0xDD66, 0x8F0C, 0xDD67, 0x8F0D, 0xDD68, 0x8F0E, 0xDD69, + 0x8F0F, 0xDD6A, 0x8F10, 0xDD6B, 0x8F11, 0xDD6C, 0x8F12, 0xDD6D, + 0x8F13, 0xDD6E, 0x8F14, 0xDD6F, 0x8F15, 0xDD70, 0x8F16, 0xDD71, + 0x8F17, 0xDD72, 0x8F18, 0xDD73, 0x8F19, 0xDD74, 0x8F1A, 0xDD75, + 0x8F1B, 0xDD76, 0x8F1C, 0xDD77, 0x8F1D, 0xDD78, 0x8F1E, 0xDD79, + 0x8F1F, 0xDD7A, 0x8F20, 0xDD7B, 0x8F21, 0xDD7C, 0x8F22, 0xDD7D, + 0x8F23, 0xDD7E, 0x8F24, 0xDD80, 0x8F25, 0xDD81, 0x8F26, 0xDD82, + 0x8F27, 0xDD83, 0x8F28, 0xDD84, 0x8F29, 0xDD85, 0x8F2A, 0xDD86, + 0x8F2B, 0xDD87, 0x8F2C, 0xDD88, 0x8F2D, 0xDD89, 0x8F2E, 0xDD8A, + 0x8F2F, 0xDD8B, 0x8F30, 0xDD8C, 0x8F31, 0xDD8D, 0x8F32, 0xDD8E, + 0x8F33, 0xDD8F, 0x8F34, 0xDD90, 0x8F35, 0xDD91, 0x8F36, 0xDD92, + 0x8F37, 0xDD93, 0x8F38, 0xDD94, 0x8F39, 0xDD95, 0x8F3A, 0xDD96, + 0x8F3B, 0xDD97, 0x8F3C, 0xDD98, 0x8F3D, 0xDD99, 0x8F3E, 0xDD9A, + 0x8F3F, 0xDD9B, 0x8F40, 0xDD9C, 0x8F41, 0xDD9D, 0x8F42, 0xDD9E, + 0x8F43, 0xDD9F, 0x8F44, 0xDDA0, 0x8F45, 0xDE40, 0x8F46, 0xDE41, + 0x8F47, 0xDE42, 0x8F48, 0xDE43, 0x8F49, 0xDE44, 0x8F4A, 0xDE45, + 0x8F4B, 0xDE46, 0x8F4C, 0xDE47, 0x8F4D, 0xDE48, 0x8F4E, 0xDE49, + 0x8F4F, 0xDE4A, 0x8F50, 0xDE4B, 0x8F51, 0xDE4C, 0x8F52, 0xDE4D, + 0x8F53, 0xDE4E, 0x8F54, 0xDE4F, 0x8F55, 0xDE50, 0x8F56, 0xDE51, + 0x8F57, 0xDE52, 0x8F58, 0xDE53, 0x8F59, 0xDE54, 0x8F5A, 0xDE55, + 0x8F5B, 0xDE56, 0x8F5C, 0xDE57, 0x8F5D, 0xDE58, 0x8F5E, 0xDE59, + 0x8F5F, 0xDE5A, 0x8F60, 0xDE5B, 0x8F61, 0xDE5C, 0x8F62, 0xDE5D, + 0x8F63, 0xDE5E, 0x8F64, 0xDE5F, 0x8F65, 0xDE60, 0x8F66, 0xB3B5, + 0x8F67, 0xD4FE, 0x8F68, 0xB9EC, 0x8F69, 0xD0F9, 0x8F6A, 0xDE61, + 0x8F6B, 0xE9ED, 0x8F6C, 0xD7AA, 0x8F6D, 0xE9EE, 0x8F6E, 0xC2D6, + 0x8F6F, 0xC8ED, 0x8F70, 0xBAE4, 0x8F71, 0xE9EF, 0x8F72, 0xE9F0, + 0x8F73, 0xE9F1, 0x8F74, 0xD6E1, 0x8F75, 0xE9F2, 0x8F76, 0xE9F3, + 0x8F77, 0xE9F5, 0x8F78, 0xE9F4, 0x8F79, 0xE9F6, 0x8F7A, 0xE9F7, + 0x8F7B, 0xC7E1, 0x8F7C, 0xE9F8, 0x8F7D, 0xD4D8, 0x8F7E, 0xE9F9, + 0x8F7F, 0xBDCE, 0x8F80, 0xDE62, 0x8F81, 0xE9FA, 0x8F82, 0xE9FB, + 0x8F83, 0xBDCF, 0x8F84, 0xE9FC, 0x8F85, 0xB8A8, 0x8F86, 0xC1BE, + 0x8F87, 0xE9FD, 0x8F88, 0xB1B2, 0x8F89, 0xBBD4, 0x8F8A, 0xB9F5, + 0x8F8B, 0xE9FE, 0x8F8C, 0xDE63, 0x8F8D, 0xEAA1, 0x8F8E, 0xEAA2, + 0x8F8F, 0xEAA3, 0x8F90, 0xB7F8, 0x8F91, 0xBCAD, 0x8F92, 0xDE64, + 0x8F93, 0xCAE4, 0x8F94, 0xE0CE, 0x8F95, 0xD4AF, 0x8F96, 0xCFBD, + 0x8F97, 0xD5B7, 0x8F98, 0xEAA4, 0x8F99, 0xD5DE, 0x8F9A, 0xEAA5, + 0x8F9B, 0xD0C1, 0x8F9C, 0xB9BC, 0x8F9D, 0xDE65, 0x8F9E, 0xB4C7, + 0x8F9F, 0xB1D9, 0x8FA0, 0xDE66, 0x8FA1, 0xDE67, 0x8FA2, 0xDE68, + 0x8FA3, 0xC0B1, 0x8FA4, 0xDE69, 0x8FA5, 0xDE6A, 0x8FA6, 0xDE6B, + 0x8FA7, 0xDE6C, 0x8FA8, 0xB1E6, 0x8FA9, 0xB1E7, 0x8FAA, 0xDE6D, + 0x8FAB, 0xB1E8, 0x8FAC, 0xDE6E, 0x8FAD, 0xDE6F, 0x8FAE, 0xDE70, + 0x8FAF, 0xDE71, 0x8FB0, 0xB3BD, 0x8FB1, 0xC8E8, 0x8FB2, 0xDE72, + 0x8FB3, 0xDE73, 0x8FB4, 0xDE74, 0x8FB5, 0xDE75, 0x8FB6, 0xE5C1, + 0x8FB7, 0xDE76, 0x8FB8, 0xDE77, 0x8FB9, 0xB1DF, 0x8FBA, 0xDE78, + 0x8FBB, 0xDE79, 0x8FBC, 0xDE7A, 0x8FBD, 0xC1C9, 0x8FBE, 0xB4EF, + 0x8FBF, 0xDE7B, 0x8FC0, 0xDE7C, 0x8FC1, 0xC7A8, 0x8FC2, 0xD3D8, + 0x8FC3, 0xDE7D, 0x8FC4, 0xC6F9, 0x8FC5, 0xD1B8, 0x8FC6, 0xDE7E, + 0x8FC7, 0xB9FD, 0x8FC8, 0xC2F5, 0x8FC9, 0xDE80, 0x8FCA, 0xDE81, + 0x8FCB, 0xDE82, 0x8FCC, 0xDE83, 0x8FCD, 0xDE84, 0x8FCE, 0xD3AD, + 0x8FCF, 0xDE85, 0x8FD0, 0xD4CB, 0x8FD1, 0xBDFC, 0x8FD2, 0xDE86, + 0x8FD3, 0xE5C2, 0x8FD4, 0xB7B5, 0x8FD5, 0xE5C3, 0x8FD6, 0xDE87, + 0x8FD7, 0xDE88, 0x8FD8, 0xBBB9, 0x8FD9, 0xD5E2, 0x8FDA, 0xDE89, + 0x8FDB, 0xBDF8, 0x8FDC, 0xD4B6, 0x8FDD, 0xCEA5, 0x8FDE, 0xC1AC, + 0x8FDF, 0xB3D9, 0x8FE0, 0xDE8A, 0x8FE1, 0xDE8B, 0x8FE2, 0xCCF6, + 0x8FE3, 0xDE8C, 0x8FE4, 0xE5C6, 0x8FE5, 0xE5C4, 0x8FE6, 0xE5C8, + 0x8FE7, 0xDE8D, 0x8FE8, 0xE5CA, 0x8FE9, 0xE5C7, 0x8FEA, 0xB5CF, + 0x8FEB, 0xC6C8, 0x8FEC, 0xDE8E, 0x8FED, 0xB5FC, 0x8FEE, 0xE5C5, + 0x8FEF, 0xDE8F, 0x8FF0, 0xCAF6, 0x8FF1, 0xDE90, 0x8FF2, 0xDE91, + 0x8FF3, 0xE5C9, 0x8FF4, 0xDE92, 0x8FF5, 0xDE93, 0x8FF6, 0xDE94, + 0x8FF7, 0xC3D4, 0x8FF8, 0xB1C5, 0x8FF9, 0xBCA3, 0x8FFA, 0xDE95, + 0x8FFB, 0xDE96, 0x8FFC, 0xDE97, 0x8FFD, 0xD7B7, 0x8FFE, 0xDE98, + 0x8FFF, 0xDE99, 0x9000, 0xCDCB, 0x9001, 0xCBCD, 0x9002, 0xCACA, + 0x9003, 0xCCD3, 0x9004, 0xE5CC, 0x9005, 0xE5CB, 0x9006, 0xC4E6, + 0x9007, 0xDE9A, 0x9008, 0xDE9B, 0x9009, 0xD1A1, 0x900A, 0xD1B7, + 0x900B, 0xE5CD, 0x900C, 0xDE9C, 0x900D, 0xE5D0, 0x900E, 0xDE9D, + 0x900F, 0xCDB8, 0x9010, 0xD6F0, 0x9011, 0xE5CF, 0x9012, 0xB5DD, + 0x9013, 0xDE9E, 0x9014, 0xCDBE, 0x9015, 0xDE9F, 0x9016, 0xE5D1, + 0x9017, 0xB6BA, 0x9018, 0xDEA0, 0x9019, 0xDF40, 0x901A, 0xCDA8, + 0x901B, 0xB9E4, 0x901C, 0xDF41, 0x901D, 0xCAC5, 0x901E, 0xB3D1, + 0x901F, 0xCBD9, 0x9020, 0xD4EC, 0x9021, 0xE5D2, 0x9022, 0xB7EA, + 0x9023, 0xDF42, 0x9024, 0xDF43, 0x9025, 0xDF44, 0x9026, 0xE5CE, + 0x9027, 0xDF45, 0x9028, 0xDF46, 0x9029, 0xDF47, 0x902A, 0xDF48, + 0x902B, 0xDF49, 0x902C, 0xDF4A, 0x902D, 0xE5D5, 0x902E, 0xB4FE, + 0x902F, 0xE5D6, 0x9030, 0xDF4B, 0x9031, 0xDF4C, 0x9032, 0xDF4D, + 0x9033, 0xDF4E, 0x9034, 0xDF4F, 0x9035, 0xE5D3, 0x9036, 0xE5D4, + 0x9037, 0xDF50, 0x9038, 0xD2DD, 0x9039, 0xDF51, 0x903A, 0xDF52, + 0x903B, 0xC2DF, 0x903C, 0xB1C6, 0x903D, 0xDF53, 0x903E, 0xD3E2, + 0x903F, 0xDF54, 0x9040, 0xDF55, 0x9041, 0xB6DD, 0x9042, 0xCBEC, + 0x9043, 0xDF56, 0x9044, 0xE5D7, 0x9045, 0xDF57, 0x9046, 0xDF58, + 0x9047, 0xD3F6, 0x9048, 0xDF59, 0x9049, 0xDF5A, 0x904A, 0xDF5B, + 0x904B, 0xDF5C, 0x904C, 0xDF5D, 0x904D, 0xB1E9, 0x904E, 0xDF5E, + 0x904F, 0xB6F4, 0x9050, 0xE5DA, 0x9051, 0xE5D8, 0x9052, 0xE5D9, + 0x9053, 0xB5C0, 0x9054, 0xDF5F, 0x9055, 0xDF60, 0x9056, 0xDF61, + 0x9057, 0xD2C5, 0x9058, 0xE5DC, 0x9059, 0xDF62, 0x905A, 0xDF63, + 0x905B, 0xE5DE, 0x905C, 0xDF64, 0x905D, 0xDF65, 0x905E, 0xDF66, + 0x905F, 0xDF67, 0x9060, 0xDF68, 0x9061, 0xDF69, 0x9062, 0xE5DD, + 0x9063, 0xC7B2, 0x9064, 0xDF6A, 0x9065, 0xD2A3, 0x9066, 0xDF6B, + 0x9067, 0xDF6C, 0x9068, 0xE5DB, 0x9069, 0xDF6D, 0x906A, 0xDF6E, + 0x906B, 0xDF6F, 0x906C, 0xDF70, 0x906D, 0xD4E2, 0x906E, 0xD5DA, + 0x906F, 0xDF71, 0x9070, 0xDF72, 0x9071, 0xDF73, 0x9072, 0xDF74, + 0x9073, 0xDF75, 0x9074, 0xE5E0, 0x9075, 0xD7F1, 0x9076, 0xDF76, + 0x9077, 0xDF77, 0x9078, 0xDF78, 0x9079, 0xDF79, 0x907A, 0xDF7A, + 0x907B, 0xDF7B, 0x907C, 0xDF7C, 0x907D, 0xE5E1, 0x907E, 0xDF7D, + 0x907F, 0xB1DC, 0x9080, 0xD1FB, 0x9081, 0xDF7E, 0x9082, 0xE5E2, + 0x9083, 0xE5E4, 0x9084, 0xDF80, 0x9085, 0xDF81, 0x9086, 0xDF82, + 0x9087, 0xDF83, 0x9088, 0xE5E3, 0x9089, 0xDF84, 0x908A, 0xDF85, + 0x908B, 0xE5E5, 0x908C, 0xDF86, 0x908D, 0xDF87, 0x908E, 0xDF88, + 0x908F, 0xDF89, 0x9090, 0xDF8A, 0x9091, 0xD2D8, 0x9092, 0xDF8B, + 0x9093, 0xB5CB, 0x9094, 0xDF8C, 0x9095, 0xE7DF, 0x9096, 0xDF8D, + 0x9097, 0xDAF5, 0x9098, 0xDF8E, 0x9099, 0xDAF8, 0x909A, 0xDF8F, + 0x909B, 0xDAF6, 0x909C, 0xDF90, 0x909D, 0xDAF7, 0x909E, 0xDF91, + 0x909F, 0xDF92, 0x90A0, 0xDF93, 0x90A1, 0xDAFA, 0x90A2, 0xD0CF, + 0x90A3, 0xC4C7, 0x90A4, 0xDF94, 0x90A5, 0xDF95, 0x90A6, 0xB0EE, + 0x90A7, 0xDF96, 0x90A8, 0xDF97, 0x90A9, 0xDF98, 0x90AA, 0xD0B0, + 0x90AB, 0xDF99, 0x90AC, 0xDAF9, 0x90AD, 0xDF9A, 0x90AE, 0xD3CA, + 0x90AF, 0xBAAA, 0x90B0, 0xDBA2, 0x90B1, 0xC7F1, 0x90B2, 0xDF9B, + 0x90B3, 0xDAFC, 0x90B4, 0xDAFB, 0x90B5, 0xC9DB, 0x90B6, 0xDAFD, + 0x90B7, 0xDF9C, 0x90B8, 0xDBA1, 0x90B9, 0xD7DE, 0x90BA, 0xDAFE, + 0x90BB, 0xC1DA, 0x90BC, 0xDF9D, 0x90BD, 0xDF9E, 0x90BE, 0xDBA5, + 0x90BF, 0xDF9F, 0x90C0, 0xDFA0, 0x90C1, 0xD3F4, 0x90C2, 0xE040, + 0x90C3, 0xE041, 0x90C4, 0xDBA7, 0x90C5, 0xDBA4, 0x90C6, 0xE042, + 0x90C7, 0xDBA8, 0x90C8, 0xE043, 0x90C9, 0xE044, 0x90CA, 0xBDBC, + 0x90CB, 0xE045, 0x90CC, 0xE046, 0x90CD, 0xE047, 0x90CE, 0xC0C9, + 0x90CF, 0xDBA3, 0x90D0, 0xDBA6, 0x90D1, 0xD6A3, 0x90D2, 0xE048, + 0x90D3, 0xDBA9, 0x90D4, 0xE049, 0x90D5, 0xE04A, 0x90D6, 0xE04B, + 0x90D7, 0xDBAD, 0x90D8, 0xE04C, 0x90D9, 0xE04D, 0x90DA, 0xE04E, + 0x90DB, 0xDBAE, 0x90DC, 0xDBAC, 0x90DD, 0xBAC2, 0x90DE, 0xE04F, + 0x90DF, 0xE050, 0x90E0, 0xE051, 0x90E1, 0xBFA4, 0x90E2, 0xDBAB, + 0x90E3, 0xE052, 0x90E4, 0xE053, 0x90E5, 0xE054, 0x90E6, 0xDBAA, + 0x90E7, 0xD4C7, 0x90E8, 0xB2BF, 0x90E9, 0xE055, 0x90EA, 0xE056, + 0x90EB, 0xDBAF, 0x90EC, 0xE057, 0x90ED, 0xB9F9, 0x90EE, 0xE058, + 0x90EF, 0xDBB0, 0x90F0, 0xE059, 0x90F1, 0xE05A, 0x90F2, 0xE05B, + 0x90F3, 0xE05C, 0x90F4, 0xB3BB, 0x90F5, 0xE05D, 0x90F6, 0xE05E, + 0x90F7, 0xE05F, 0x90F8, 0xB5A6, 0x90F9, 0xE060, 0x90FA, 0xE061, + 0x90FB, 0xE062, 0x90FC, 0xE063, 0x90FD, 0xB6BC, 0x90FE, 0xDBB1, + 0x90FF, 0xE064, 0x9100, 0xE065, 0x9101, 0xE066, 0x9102, 0xB6F5, + 0x9103, 0xE067, 0x9104, 0xDBB2, 0x9105, 0xE068, 0x9106, 0xE069, + 0x9107, 0xE06A, 0x9108, 0xE06B, 0x9109, 0xE06C, 0x910A, 0xE06D, + 0x910B, 0xE06E, 0x910C, 0xE06F, 0x910D, 0xE070, 0x910E, 0xE071, + 0x910F, 0xE072, 0x9110, 0xE073, 0x9111, 0xE074, 0x9112, 0xE075, + 0x9113, 0xE076, 0x9114, 0xE077, 0x9115, 0xE078, 0x9116, 0xE079, + 0x9117, 0xE07A, 0x9118, 0xE07B, 0x9119, 0xB1C9, 0x911A, 0xE07C, + 0x911B, 0xE07D, 0x911C, 0xE07E, 0x911D, 0xE080, 0x911E, 0xDBB4, + 0x911F, 0xE081, 0x9120, 0xE082, 0x9121, 0xE083, 0x9122, 0xDBB3, + 0x9123, 0xDBB5, 0x9124, 0xE084, 0x9125, 0xE085, 0x9126, 0xE086, + 0x9127, 0xE087, 0x9128, 0xE088, 0x9129, 0xE089, 0x912A, 0xE08A, + 0x912B, 0xE08B, 0x912C, 0xE08C, 0x912D, 0xE08D, 0x912E, 0xE08E, + 0x912F, 0xDBB7, 0x9130, 0xE08F, 0x9131, 0xDBB6, 0x9132, 0xE090, + 0x9133, 0xE091, 0x9134, 0xE092, 0x9135, 0xE093, 0x9136, 0xE094, + 0x9137, 0xE095, 0x9138, 0xE096, 0x9139, 0xDBB8, 0x913A, 0xE097, + 0x913B, 0xE098, 0x913C, 0xE099, 0x913D, 0xE09A, 0x913E, 0xE09B, + 0x913F, 0xE09C, 0x9140, 0xE09D, 0x9141, 0xE09E, 0x9142, 0xE09F, + 0x9143, 0xDBB9, 0x9144, 0xE0A0, 0x9145, 0xE140, 0x9146, 0xDBBA, + 0x9147, 0xE141, 0x9148, 0xE142, 0x9149, 0xD3CF, 0x914A, 0xF4FA, + 0x914B, 0xC7F5, 0x914C, 0xD7C3, 0x914D, 0xC5E4, 0x914E, 0xF4FC, + 0x914F, 0xF4FD, 0x9150, 0xF4FB, 0x9151, 0xE143, 0x9152, 0xBEC6, + 0x9153, 0xE144, 0x9154, 0xE145, 0x9155, 0xE146, 0x9156, 0xE147, + 0x9157, 0xD0EF, 0x9158, 0xE148, 0x9159, 0xE149, 0x915A, 0xB7D3, + 0x915B, 0xE14A, 0x915C, 0xE14B, 0x915D, 0xD4CD, 0x915E, 0xCCAA, + 0x915F, 0xE14C, 0x9160, 0xE14D, 0x9161, 0xF5A2, 0x9162, 0xF5A1, + 0x9163, 0xBAA8, 0x9164, 0xF4FE, 0x9165, 0xCBD6, 0x9166, 0xE14E, + 0x9167, 0xE14F, 0x9168, 0xE150, 0x9169, 0xF5A4, 0x916A, 0xC0D2, + 0x916B, 0xE151, 0x916C, 0xB3EA, 0x916D, 0xE152, 0x916E, 0xCDAA, + 0x916F, 0xF5A5, 0x9170, 0xF5A3, 0x9171, 0xBDB4, 0x9172, 0xF5A8, + 0x9173, 0xE153, 0x9174, 0xF5A9, 0x9175, 0xBDCD, 0x9176, 0xC3B8, + 0x9177, 0xBFE1, 0x9178, 0xCBE1, 0x9179, 0xF5AA, 0x917A, 0xE154, + 0x917B, 0xE155, 0x917C, 0xE156, 0x917D, 0xF5A6, 0x917E, 0xF5A7, + 0x917F, 0xC4F0, 0x9180, 0xE157, 0x9181, 0xE158, 0x9182, 0xE159, + 0x9183, 0xE15A, 0x9184, 0xE15B, 0x9185, 0xF5AC, 0x9186, 0xE15C, + 0x9187, 0xB4BC, 0x9188, 0xE15D, 0x9189, 0xD7ED, 0x918A, 0xE15E, + 0x918B, 0xB4D7, 0x918C, 0xF5AB, 0x918D, 0xF5AE, 0x918E, 0xE15F, + 0x918F, 0xE160, 0x9190, 0xF5AD, 0x9191, 0xF5AF, 0x9192, 0xD0D1, + 0x9193, 0xE161, 0x9194, 0xE162, 0x9195, 0xE163, 0x9196, 0xE164, + 0x9197, 0xE165, 0x9198, 0xE166, 0x9199, 0xE167, 0x919A, 0xC3D1, + 0x919B, 0xC8A9, 0x919C, 0xE168, 0x919D, 0xE169, 0x919E, 0xE16A, + 0x919F, 0xE16B, 0x91A0, 0xE16C, 0x91A1, 0xE16D, 0x91A2, 0xF5B0, + 0x91A3, 0xF5B1, 0x91A4, 0xE16E, 0x91A5, 0xE16F, 0x91A6, 0xE170, + 0x91A7, 0xE171, 0x91A8, 0xE172, 0x91A9, 0xE173, 0x91AA, 0xF5B2, + 0x91AB, 0xE174, 0x91AC, 0xE175, 0x91AD, 0xF5B3, 0x91AE, 0xF5B4, + 0x91AF, 0xF5B5, 0x91B0, 0xE176, 0x91B1, 0xE177, 0x91B2, 0xE178, + 0x91B3, 0xE179, 0x91B4, 0xF5B7, 0x91B5, 0xF5B6, 0x91B6, 0xE17A, + 0x91B7, 0xE17B, 0x91B8, 0xE17C, 0x91B9, 0xE17D, 0x91BA, 0xF5B8, + 0x91BB, 0xE17E, 0x91BC, 0xE180, 0x91BD, 0xE181, 0x91BE, 0xE182, + 0x91BF, 0xE183, 0x91C0, 0xE184, 0x91C1, 0xE185, 0x91C2, 0xE186, + 0x91C3, 0xE187, 0x91C4, 0xE188, 0x91C5, 0xE189, 0x91C6, 0xE18A, + 0x91C7, 0xB2C9, 0x91C8, 0xE18B, 0x91C9, 0xD3D4, 0x91CA, 0xCACD, + 0x91CB, 0xE18C, 0x91CC, 0xC0EF, 0x91CD, 0xD6D8, 0x91CE, 0xD2B0, + 0x91CF, 0xC1BF, 0x91D0, 0xE18D, 0x91D1, 0xBDF0, 0x91D2, 0xE18E, + 0x91D3, 0xE18F, 0x91D4, 0xE190, 0x91D5, 0xE191, 0x91D6, 0xE192, + 0x91D7, 0xE193, 0x91D8, 0xE194, 0x91D9, 0xE195, 0x91DA, 0xE196, + 0x91DB, 0xE197, 0x91DC, 0xB8AA, 0x91DD, 0xE198, 0x91DE, 0xE199, + 0x91DF, 0xE19A, 0x91E0, 0xE19B, 0x91E1, 0xE19C, 0x91E2, 0xE19D, + 0x91E3, 0xE19E, 0x91E4, 0xE19F, 0x91E5, 0xE1A0, 0x91E6, 0xE240, + 0x91E7, 0xE241, 0x91E8, 0xE242, 0x91E9, 0xE243, 0x91EA, 0xE244, + 0x91EB, 0xE245, 0x91EC, 0xE246, 0x91ED, 0xE247, 0x91EE, 0xE248, + 0x91EF, 0xE249, 0x91F0, 0xE24A, 0x91F1, 0xE24B, 0x91F2, 0xE24C, + 0x91F3, 0xE24D, 0x91F4, 0xE24E, 0x91F5, 0xE24F, 0x91F6, 0xE250, + 0x91F7, 0xE251, 0x91F8, 0xE252, 0x91F9, 0xE253, 0x91FA, 0xE254, + 0x91FB, 0xE255, 0x91FC, 0xE256, 0x91FD, 0xE257, 0x91FE, 0xE258, + 0x91FF, 0xE259, 0x9200, 0xE25A, 0x9201, 0xE25B, 0x9202, 0xE25C, + 0x9203, 0xE25D, 0x9204, 0xE25E, 0x9205, 0xE25F, 0x9206, 0xE260, + 0x9207, 0xE261, 0x9208, 0xE262, 0x9209, 0xE263, 0x920A, 0xE264, + 0x920B, 0xE265, 0x920C, 0xE266, 0x920D, 0xE267, 0x920E, 0xE268, + 0x920F, 0xE269, 0x9210, 0xE26A, 0x9211, 0xE26B, 0x9212, 0xE26C, + 0x9213, 0xE26D, 0x9214, 0xE26E, 0x9215, 0xE26F, 0x9216, 0xE270, + 0x9217, 0xE271, 0x9218, 0xE272, 0x9219, 0xE273, 0x921A, 0xE274, + 0x921B, 0xE275, 0x921C, 0xE276, 0x921D, 0xE277, 0x921E, 0xE278, + 0x921F, 0xE279, 0x9220, 0xE27A, 0x9221, 0xE27B, 0x9222, 0xE27C, + 0x9223, 0xE27D, 0x9224, 0xE27E, 0x9225, 0xE280, 0x9226, 0xE281, + 0x9227, 0xE282, 0x9228, 0xE283, 0x9229, 0xE284, 0x922A, 0xE285, + 0x922B, 0xE286, 0x922C, 0xE287, 0x922D, 0xE288, 0x922E, 0xE289, + 0x922F, 0xE28A, 0x9230, 0xE28B, 0x9231, 0xE28C, 0x9232, 0xE28D, + 0x9233, 0xE28E, 0x9234, 0xE28F, 0x9235, 0xE290, 0x9236, 0xE291, + 0x9237, 0xE292, 0x9238, 0xE293, 0x9239, 0xE294, 0x923A, 0xE295, + 0x923B, 0xE296, 0x923C, 0xE297, 0x923D, 0xE298, 0x923E, 0xE299, + 0x923F, 0xE29A, 0x9240, 0xE29B, 0x9241, 0xE29C, 0x9242, 0xE29D, + 0x9243, 0xE29E, 0x9244, 0xE29F, 0x9245, 0xE2A0, 0x9246, 0xE340, + 0x9247, 0xE341, 0x9248, 0xE342, 0x9249, 0xE343, 0x924A, 0xE344, + 0x924B, 0xE345, 0x924C, 0xE346, 0x924D, 0xE347, 0x924E, 0xE348, + 0x924F, 0xE349, 0x9250, 0xE34A, 0x9251, 0xE34B, 0x9252, 0xE34C, + 0x9253, 0xE34D, 0x9254, 0xE34E, 0x9255, 0xE34F, 0x9256, 0xE350, + 0x9257, 0xE351, 0x9258, 0xE352, 0x9259, 0xE353, 0x925A, 0xE354, + 0x925B, 0xE355, 0x925C, 0xE356, 0x925D, 0xE357, 0x925E, 0xE358, + 0x925F, 0xE359, 0x9260, 0xE35A, 0x9261, 0xE35B, 0x9262, 0xE35C, + 0x9263, 0xE35D, 0x9264, 0xE35E, 0x9265, 0xE35F, 0x9266, 0xE360, + 0x9267, 0xE361, 0x9268, 0xE362, 0x9269, 0xE363, 0x926A, 0xE364, + 0x926B, 0xE365, 0x926C, 0xE366, 0x926D, 0xE367, 0x926E, 0xE368, + 0x926F, 0xE369, 0x9270, 0xE36A, 0x9271, 0xE36B, 0x9272, 0xE36C, + 0x9273, 0xE36D, 0x9274, 0xBCF8, 0x9275, 0xE36E, 0x9276, 0xE36F, + 0x9277, 0xE370, 0x9278, 0xE371, 0x9279, 0xE372, 0x927A, 0xE373, + 0x927B, 0xE374, 0x927C, 0xE375, 0x927D, 0xE376, 0x927E, 0xE377, + 0x927F, 0xE378, 0x9280, 0xE379, 0x9281, 0xE37A, 0x9282, 0xE37B, + 0x9283, 0xE37C, 0x9284, 0xE37D, 0x9285, 0xE37E, 0x9286, 0xE380, + 0x9287, 0xE381, 0x9288, 0xE382, 0x9289, 0xE383, 0x928A, 0xE384, + 0x928B, 0xE385, 0x928C, 0xE386, 0x928D, 0xE387, 0x928E, 0xF6C6, + 0x928F, 0xE388, 0x9290, 0xE389, 0x9291, 0xE38A, 0x9292, 0xE38B, + 0x9293, 0xE38C, 0x9294, 0xE38D, 0x9295, 0xE38E, 0x9296, 0xE38F, + 0x9297, 0xE390, 0x9298, 0xE391, 0x9299, 0xE392, 0x929A, 0xE393, + 0x929B, 0xE394, 0x929C, 0xE395, 0x929D, 0xE396, 0x929E, 0xE397, + 0x929F, 0xE398, 0x92A0, 0xE399, 0x92A1, 0xE39A, 0x92A2, 0xE39B, + 0x92A3, 0xE39C, 0x92A4, 0xE39D, 0x92A5, 0xE39E, 0x92A6, 0xE39F, + 0x92A7, 0xE3A0, 0x92A8, 0xE440, 0x92A9, 0xE441, 0x92AA, 0xE442, + 0x92AB, 0xE443, 0x92AC, 0xE444, 0x92AD, 0xE445, 0x92AE, 0xF6C7, + 0x92AF, 0xE446, 0x92B0, 0xE447, 0x92B1, 0xE448, 0x92B2, 0xE449, + 0x92B3, 0xE44A, 0x92B4, 0xE44B, 0x92B5, 0xE44C, 0x92B6, 0xE44D, + 0x92B7, 0xE44E, 0x92B8, 0xE44F, 0x92B9, 0xE450, 0x92BA, 0xE451, + 0x92BB, 0xE452, 0x92BC, 0xE453, 0x92BD, 0xE454, 0x92BE, 0xE455, + 0x92BF, 0xE456, 0x92C0, 0xE457, 0x92C1, 0xE458, 0x92C2, 0xE459, + 0x92C3, 0xE45A, 0x92C4, 0xE45B, 0x92C5, 0xE45C, 0x92C6, 0xE45D, + 0x92C7, 0xE45E, 0x92C8, 0xF6C8, 0x92C9, 0xE45F, 0x92CA, 0xE460, + 0x92CB, 0xE461, 0x92CC, 0xE462, 0x92CD, 0xE463, 0x92CE, 0xE464, + 0x92CF, 0xE465, 0x92D0, 0xE466, 0x92D1, 0xE467, 0x92D2, 0xE468, + 0x92D3, 0xE469, 0x92D4, 0xE46A, 0x92D5, 0xE46B, 0x92D6, 0xE46C, + 0x92D7, 0xE46D, 0x92D8, 0xE46E, 0x92D9, 0xE46F, 0x92DA, 0xE470, + 0x92DB, 0xE471, 0x92DC, 0xE472, 0x92DD, 0xE473, 0x92DE, 0xE474, + 0x92DF, 0xE475, 0x92E0, 0xE476, 0x92E1, 0xE477, 0x92E2, 0xE478, + 0x92E3, 0xE479, 0x92E4, 0xE47A, 0x92E5, 0xE47B, 0x92E6, 0xE47C, + 0x92E7, 0xE47D, 0x92E8, 0xE47E, 0x92E9, 0xE480, 0x92EA, 0xE481, + 0x92EB, 0xE482, 0x92EC, 0xE483, 0x92ED, 0xE484, 0x92EE, 0xE485, + 0x92EF, 0xE486, 0x92F0, 0xE487, 0x92F1, 0xE488, 0x92F2, 0xE489, + 0x92F3, 0xE48A, 0x92F4, 0xE48B, 0x92F5, 0xE48C, 0x92F6, 0xE48D, + 0x92F7, 0xE48E, 0x92F8, 0xE48F, 0x92F9, 0xE490, 0x92FA, 0xE491, + 0x92FB, 0xE492, 0x92FC, 0xE493, 0x92FD, 0xE494, 0x92FE, 0xE495, + 0x92FF, 0xE496, 0x9300, 0xE497, 0x9301, 0xE498, 0x9302, 0xE499, + 0x9303, 0xE49A, 0x9304, 0xE49B, 0x9305, 0xE49C, 0x9306, 0xE49D, + 0x9307, 0xE49E, 0x9308, 0xE49F, 0x9309, 0xE4A0, 0x930A, 0xE540, + 0x930B, 0xE541, 0x930C, 0xE542, 0x930D, 0xE543, 0x930E, 0xE544, + 0x930F, 0xE545, 0x9310, 0xE546, 0x9311, 0xE547, 0x9312, 0xE548, + 0x9313, 0xE549, 0x9314, 0xE54A, 0x9315, 0xE54B, 0x9316, 0xE54C, + 0x9317, 0xE54D, 0x9318, 0xE54E, 0x9319, 0xE54F, 0x931A, 0xE550, + 0x931B, 0xE551, 0x931C, 0xE552, 0x931D, 0xE553, 0x931E, 0xE554, + 0x931F, 0xE555, 0x9320, 0xE556, 0x9321, 0xE557, 0x9322, 0xE558, + 0x9323, 0xE559, 0x9324, 0xE55A, 0x9325, 0xE55B, 0x9326, 0xE55C, + 0x9327, 0xE55D, 0x9328, 0xE55E, 0x9329, 0xE55F, 0x932A, 0xE560, + 0x932B, 0xE561, 0x932C, 0xE562, 0x932D, 0xE563, 0x932E, 0xE564, + 0x932F, 0xE565, 0x9330, 0xE566, 0x9331, 0xE567, 0x9332, 0xE568, + 0x9333, 0xE569, 0x9334, 0xE56A, 0x9335, 0xE56B, 0x9336, 0xE56C, + 0x9337, 0xE56D, 0x9338, 0xE56E, 0x9339, 0xE56F, 0x933A, 0xE570, + 0x933B, 0xE571, 0x933C, 0xE572, 0x933D, 0xE573, 0x933E, 0xF6C9, + 0x933F, 0xE574, 0x9340, 0xE575, 0x9341, 0xE576, 0x9342, 0xE577, + 0x9343, 0xE578, 0x9344, 0xE579, 0x9345, 0xE57A, 0x9346, 0xE57B, + 0x9347, 0xE57C, 0x9348, 0xE57D, 0x9349, 0xE57E, 0x934A, 0xE580, + 0x934B, 0xE581, 0x934C, 0xE582, 0x934D, 0xE583, 0x934E, 0xE584, + 0x934F, 0xE585, 0x9350, 0xE586, 0x9351, 0xE587, 0x9352, 0xE588, + 0x9353, 0xE589, 0x9354, 0xE58A, 0x9355, 0xE58B, 0x9356, 0xE58C, + 0x9357, 0xE58D, 0x9358, 0xE58E, 0x9359, 0xE58F, 0x935A, 0xE590, + 0x935B, 0xE591, 0x935C, 0xE592, 0x935D, 0xE593, 0x935E, 0xE594, + 0x935F, 0xE595, 0x9360, 0xE596, 0x9361, 0xE597, 0x9362, 0xE598, + 0x9363, 0xE599, 0x9364, 0xE59A, 0x9365, 0xE59B, 0x9366, 0xE59C, + 0x9367, 0xE59D, 0x9368, 0xE59E, 0x9369, 0xE59F, 0x936A, 0xF6CA, + 0x936B, 0xE5A0, 0x936C, 0xE640, 0x936D, 0xE641, 0x936E, 0xE642, + 0x936F, 0xE643, 0x9370, 0xE644, 0x9371, 0xE645, 0x9372, 0xE646, + 0x9373, 0xE647, 0x9374, 0xE648, 0x9375, 0xE649, 0x9376, 0xE64A, + 0x9377, 0xE64B, 0x9378, 0xE64C, 0x9379, 0xE64D, 0x937A, 0xE64E, + 0x937B, 0xE64F, 0x937C, 0xE650, 0x937D, 0xE651, 0x937E, 0xE652, + 0x937F, 0xE653, 0x9380, 0xE654, 0x9381, 0xE655, 0x9382, 0xE656, + 0x9383, 0xE657, 0x9384, 0xE658, 0x9385, 0xE659, 0x9386, 0xE65A, + 0x9387, 0xE65B, 0x9388, 0xE65C, 0x9389, 0xE65D, 0x938A, 0xE65E, + 0x938B, 0xE65F, 0x938C, 0xE660, 0x938D, 0xE661, 0x938E, 0xE662, + 0x938F, 0xF6CC, 0x9390, 0xE663, 0x9391, 0xE664, 0x9392, 0xE665, + 0x9393, 0xE666, 0x9394, 0xE667, 0x9395, 0xE668, 0x9396, 0xE669, + 0x9397, 0xE66A, 0x9398, 0xE66B, 0x9399, 0xE66C, 0x939A, 0xE66D, + 0x939B, 0xE66E, 0x939C, 0xE66F, 0x939D, 0xE670, 0x939E, 0xE671, + 0x939F, 0xE672, 0x93A0, 0xE673, 0x93A1, 0xE674, 0x93A2, 0xE675, + 0x93A3, 0xE676, 0x93A4, 0xE677, 0x93A5, 0xE678, 0x93A6, 0xE679, + 0x93A7, 0xE67A, 0x93A8, 0xE67B, 0x93A9, 0xE67C, 0x93AA, 0xE67D, + 0x93AB, 0xE67E, 0x93AC, 0xE680, 0x93AD, 0xE681, 0x93AE, 0xE682, + 0x93AF, 0xE683, 0x93B0, 0xE684, 0x93B1, 0xE685, 0x93B2, 0xE686, + 0x93B3, 0xE687, 0x93B4, 0xE688, 0x93B5, 0xE689, 0x93B6, 0xE68A, + 0x93B7, 0xE68B, 0x93B8, 0xE68C, 0x93B9, 0xE68D, 0x93BA, 0xE68E, + 0x93BB, 0xE68F, 0x93BC, 0xE690, 0x93BD, 0xE691, 0x93BE, 0xE692, + 0x93BF, 0xE693, 0x93C0, 0xE694, 0x93C1, 0xE695, 0x93C2, 0xE696, + 0x93C3, 0xE697, 0x93C4, 0xE698, 0x93C5, 0xE699, 0x93C6, 0xE69A, + 0x93C7, 0xE69B, 0x93C8, 0xE69C, 0x93C9, 0xE69D, 0x93CA, 0xF6CB, + 0x93CB, 0xE69E, 0x93CC, 0xE69F, 0x93CD, 0xE6A0, 0x93CE, 0xE740, + 0x93CF, 0xE741, 0x93D0, 0xE742, 0x93D1, 0xE743, 0x93D2, 0xE744, + 0x93D3, 0xE745, 0x93D4, 0xE746, 0x93D5, 0xE747, 0x93D6, 0xF7E9, + 0x93D7, 0xE748, 0x93D8, 0xE749, 0x93D9, 0xE74A, 0x93DA, 0xE74B, + 0x93DB, 0xE74C, 0x93DC, 0xE74D, 0x93DD, 0xE74E, 0x93DE, 0xE74F, + 0x93DF, 0xE750, 0x93E0, 0xE751, 0x93E1, 0xE752, 0x93E2, 0xE753, + 0x93E3, 0xE754, 0x93E4, 0xE755, 0x93E5, 0xE756, 0x93E6, 0xE757, + 0x93E7, 0xE758, 0x93E8, 0xE759, 0x93E9, 0xE75A, 0x93EA, 0xE75B, + 0x93EB, 0xE75C, 0x93EC, 0xE75D, 0x93ED, 0xE75E, 0x93EE, 0xE75F, + 0x93EF, 0xE760, 0x93F0, 0xE761, 0x93F1, 0xE762, 0x93F2, 0xE763, + 0x93F3, 0xE764, 0x93F4, 0xE765, 0x93F5, 0xE766, 0x93F6, 0xE767, + 0x93F7, 0xE768, 0x93F8, 0xE769, 0x93F9, 0xE76A, 0x93FA, 0xE76B, + 0x93FB, 0xE76C, 0x93FC, 0xE76D, 0x93FD, 0xE76E, 0x93FE, 0xE76F, + 0x93FF, 0xE770, 0x9400, 0xE771, 0x9401, 0xE772, 0x9402, 0xE773, + 0x9403, 0xE774, 0x9404, 0xE775, 0x9405, 0xE776, 0x9406, 0xE777, + 0x9407, 0xE778, 0x9408, 0xE779, 0x9409, 0xE77A, 0x940A, 0xE77B, + 0x940B, 0xE77C, 0x940C, 0xE77D, 0x940D, 0xE77E, 0x940E, 0xE780, + 0x940F, 0xE781, 0x9410, 0xE782, 0x9411, 0xE783, 0x9412, 0xE784, + 0x9413, 0xE785, 0x9414, 0xE786, 0x9415, 0xE787, 0x9416, 0xE788, + 0x9417, 0xE789, 0x9418, 0xE78A, 0x9419, 0xE78B, 0x941A, 0xE78C, + 0x941B, 0xE78D, 0x941C, 0xE78E, 0x941D, 0xE78F, 0x941E, 0xE790, + 0x941F, 0xE791, 0x9420, 0xE792, 0x9421, 0xE793, 0x9422, 0xE794, + 0x9423, 0xE795, 0x9424, 0xE796, 0x9425, 0xE797, 0x9426, 0xE798, + 0x9427, 0xE799, 0x9428, 0xE79A, 0x9429, 0xE79B, 0x942A, 0xE79C, + 0x942B, 0xE79D, 0x942C, 0xE79E, 0x942D, 0xE79F, 0x942E, 0xE7A0, + 0x942F, 0xE840, 0x9430, 0xE841, 0x9431, 0xE842, 0x9432, 0xE843, + 0x9433, 0xE844, 0x9434, 0xE845, 0x9435, 0xE846, 0x9436, 0xE847, + 0x9437, 0xE848, 0x9438, 0xE849, 0x9439, 0xE84A, 0x943A, 0xE84B, + 0x943B, 0xE84C, 0x943C, 0xE84D, 0x943D, 0xE84E, 0x943E, 0xF6CD, + 0x943F, 0xE84F, 0x9440, 0xE850, 0x9441, 0xE851, 0x9442, 0xE852, + 0x9443, 0xE853, 0x9444, 0xE854, 0x9445, 0xE855, 0x9446, 0xE856, + 0x9447, 0xE857, 0x9448, 0xE858, 0x9449, 0xE859, 0x944A, 0xE85A, + 0x944B, 0xE85B, 0x944C, 0xE85C, 0x944D, 0xE85D, 0x944E, 0xE85E, + 0x944F, 0xE85F, 0x9450, 0xE860, 0x9451, 0xE861, 0x9452, 0xE862, + 0x9453, 0xE863, 0x9454, 0xE864, 0x9455, 0xE865, 0x9456, 0xE866, + 0x9457, 0xE867, 0x9458, 0xE868, 0x9459, 0xE869, 0x945A, 0xE86A, + 0x945B, 0xE86B, 0x945C, 0xE86C, 0x945D, 0xE86D, 0x945E, 0xE86E, + 0x945F, 0xE86F, 0x9460, 0xE870, 0x9461, 0xE871, 0x9462, 0xE872, + 0x9463, 0xE873, 0x9464, 0xE874, 0x9465, 0xE875, 0x9466, 0xE876, + 0x9467, 0xE877, 0x9468, 0xE878, 0x9469, 0xE879, 0x946A, 0xE87A, + 0x946B, 0xF6CE, 0x946C, 0xE87B, 0x946D, 0xE87C, 0x946E, 0xE87D, + 0x946F, 0xE87E, 0x9470, 0xE880, 0x9471, 0xE881, 0x9472, 0xE882, + 0x9473, 0xE883, 0x9474, 0xE884, 0x9475, 0xE885, 0x9476, 0xE886, + 0x9477, 0xE887, 0x9478, 0xE888, 0x9479, 0xE889, 0x947A, 0xE88A, + 0x947B, 0xE88B, 0x947C, 0xE88C, 0x947D, 0xE88D, 0x947E, 0xE88E, + 0x947F, 0xE88F, 0x9480, 0xE890, 0x9481, 0xE891, 0x9482, 0xE892, + 0x9483, 0xE893, 0x9484, 0xE894, 0x9485, 0xEEC4, 0x9486, 0xEEC5, + 0x9487, 0xEEC6, 0x9488, 0xD5EB, 0x9489, 0xB6A4, 0x948A, 0xEEC8, + 0x948B, 0xEEC7, 0x948C, 0xEEC9, 0x948D, 0xEECA, 0x948E, 0xC7A5, + 0x948F, 0xEECB, 0x9490, 0xEECC, 0x9491, 0xE895, 0x9492, 0xB7B0, + 0x9493, 0xB5F6, 0x9494, 0xEECD, 0x9495, 0xEECF, 0x9496, 0xE896, + 0x9497, 0xEECE, 0x9498, 0xE897, 0x9499, 0xB8C6, 0x949A, 0xEED0, + 0x949B, 0xEED1, 0x949C, 0xEED2, 0x949D, 0xB6DB, 0x949E, 0xB3AE, + 0x949F, 0xD6D3, 0x94A0, 0xC4C6, 0x94A1, 0xB1B5, 0x94A2, 0xB8D6, + 0x94A3, 0xEED3, 0x94A4, 0xEED4, 0x94A5, 0xD4BF, 0x94A6, 0xC7D5, + 0x94A7, 0xBEFB, 0x94A8, 0xCED9, 0x94A9, 0xB9B3, 0x94AA, 0xEED6, + 0x94AB, 0xEED5, 0x94AC, 0xEED8, 0x94AD, 0xEED7, 0x94AE, 0xC5A5, + 0x94AF, 0xEED9, 0x94B0, 0xEEDA, 0x94B1, 0xC7AE, 0x94B2, 0xEEDB, + 0x94B3, 0xC7AF, 0x94B4, 0xEEDC, 0x94B5, 0xB2A7, 0x94B6, 0xEEDD, + 0x94B7, 0xEEDE, 0x94B8, 0xEEDF, 0x94B9, 0xEEE0, 0x94BA, 0xEEE1, + 0x94BB, 0xD7EA, 0x94BC, 0xEEE2, 0x94BD, 0xEEE3, 0x94BE, 0xBCD8, + 0x94BF, 0xEEE4, 0x94C0, 0xD3CB, 0x94C1, 0xCCFA, 0x94C2, 0xB2AC, + 0x94C3, 0xC1E5, 0x94C4, 0xEEE5, 0x94C5, 0xC7A6, 0x94C6, 0xC3AD, + 0x94C7, 0xE898, 0x94C8, 0xEEE6, 0x94C9, 0xEEE7, 0x94CA, 0xEEE8, + 0x94CB, 0xEEE9, 0x94CC, 0xEEEA, 0x94CD, 0xEEEB, 0x94CE, 0xEEEC, + 0x94CF, 0xE899, 0x94D0, 0xEEED, 0x94D1, 0xEEEE, 0x94D2, 0xEEEF, + 0x94D3, 0xE89A, 0x94D4, 0xE89B, 0x94D5, 0xEEF0, 0x94D6, 0xEEF1, + 0x94D7, 0xEEF2, 0x94D8, 0xEEF4, 0x94D9, 0xEEF3, 0x94DA, 0xE89C, + 0x94DB, 0xEEF5, 0x94DC, 0xCDAD, 0x94DD, 0xC2C1, 0x94DE, 0xEEF6, + 0x94DF, 0xEEF7, 0x94E0, 0xEEF8, 0x94E1, 0xD5A1, 0x94E2, 0xEEF9, + 0x94E3, 0xCFB3, 0x94E4, 0xEEFA, 0x94E5, 0xEEFB, 0x94E6, 0xE89D, + 0x94E7, 0xEEFC, 0x94E8, 0xEEFD, 0x94E9, 0xEFA1, 0x94EA, 0xEEFE, + 0x94EB, 0xEFA2, 0x94EC, 0xB8F5, 0x94ED, 0xC3FA, 0x94EE, 0xEFA3, + 0x94EF, 0xEFA4, 0x94F0, 0xBDC2, 0x94F1, 0xD2BF, 0x94F2, 0xB2F9, + 0x94F3, 0xEFA5, 0x94F4, 0xEFA6, 0x94F5, 0xEFA7, 0x94F6, 0xD2F8, + 0x94F7, 0xEFA8, 0x94F8, 0xD6FD, 0x94F9, 0xEFA9, 0x94FA, 0xC6CC, + 0x94FB, 0xE89E, 0x94FC, 0xEFAA, 0x94FD, 0xEFAB, 0x94FE, 0xC1B4, + 0x94FF, 0xEFAC, 0x9500, 0xCFFA, 0x9501, 0xCBF8, 0x9502, 0xEFAE, + 0x9503, 0xEFAD, 0x9504, 0xB3FA, 0x9505, 0xB9F8, 0x9506, 0xEFAF, + 0x9507, 0xEFB0, 0x9508, 0xD0E2, 0x9509, 0xEFB1, 0x950A, 0xEFB2, + 0x950B, 0xB7E6, 0x950C, 0xD0BF, 0x950D, 0xEFB3, 0x950E, 0xEFB4, + 0x950F, 0xEFB5, 0x9510, 0xC8F1, 0x9511, 0xCCE0, 0x9512, 0xEFB6, + 0x9513, 0xEFB7, 0x9514, 0xEFB8, 0x9515, 0xEFB9, 0x9516, 0xEFBA, + 0x9517, 0xD5E0, 0x9518, 0xEFBB, 0x9519, 0xB4ED, 0x951A, 0xC3AA, + 0x951B, 0xEFBC, 0x951C, 0xE89F, 0x951D, 0xEFBD, 0x951E, 0xEFBE, + 0x951F, 0xEFBF, 0x9520, 0xE8A0, 0x9521, 0xCEFD, 0x9522, 0xEFC0, + 0x9523, 0xC2E0, 0x9524, 0xB4B8, 0x9525, 0xD7B6, 0x9526, 0xBDF5, + 0x9527, 0xE940, 0x9528, 0xCFC7, 0x9529, 0xEFC3, 0x952A, 0xEFC1, + 0x952B, 0xEFC2, 0x952C, 0xEFC4, 0x952D, 0xB6A7, 0x952E, 0xBCFC, + 0x952F, 0xBEE2, 0x9530, 0xC3CC, 0x9531, 0xEFC5, 0x9532, 0xEFC6, + 0x9533, 0xE941, 0x9534, 0xEFC7, 0x9535, 0xEFCF, 0x9536, 0xEFC8, + 0x9537, 0xEFC9, 0x9538, 0xEFCA, 0x9539, 0xC7C2, 0x953A, 0xEFF1, + 0x953B, 0xB6CD, 0x953C, 0xEFCB, 0x953D, 0xE942, 0x953E, 0xEFCC, + 0x953F, 0xEFCD, 0x9540, 0xB6C6, 0x9541, 0xC3BE, 0x9542, 0xEFCE, + 0x9543, 0xE943, 0x9544, 0xEFD0, 0x9545, 0xEFD1, 0x9546, 0xEFD2, + 0x9547, 0xD5F2, 0x9548, 0xE944, 0x9549, 0xEFD3, 0x954A, 0xC4F7, + 0x954B, 0xE945, 0x954C, 0xEFD4, 0x954D, 0xC4F8, 0x954E, 0xEFD5, + 0x954F, 0xEFD6, 0x9550, 0xB8E4, 0x9551, 0xB0F7, 0x9552, 0xEFD7, + 0x9553, 0xEFD8, 0x9554, 0xEFD9, 0x9555, 0xE946, 0x9556, 0xEFDA, + 0x9557, 0xEFDB, 0x9558, 0xEFDC, 0x9559, 0xEFDD, 0x955A, 0xE947, + 0x955B, 0xEFDE, 0x955C, 0xBEB5, 0x955D, 0xEFE1, 0x955E, 0xEFDF, + 0x955F, 0xEFE0, 0x9560, 0xE948, 0x9561, 0xEFE2, 0x9562, 0xEFE3, + 0x9563, 0xC1CD, 0x9564, 0xEFE4, 0x9565, 0xEFE5, 0x9566, 0xEFE6, + 0x9567, 0xEFE7, 0x9568, 0xEFE8, 0x9569, 0xEFE9, 0x956A, 0xEFEA, + 0x956B, 0xEFEB, 0x956C, 0xEFEC, 0x956D, 0xC0D8, 0x956E, 0xE949, + 0x956F, 0xEFED, 0x9570, 0xC1AD, 0x9571, 0xEFEE, 0x9572, 0xEFEF, + 0x9573, 0xEFF0, 0x9574, 0xE94A, 0x9575, 0xE94B, 0x9576, 0xCFE2, + 0x9577, 0xE94C, 0x9578, 0xE94D, 0x9579, 0xE94E, 0x957A, 0xE94F, + 0x957B, 0xE950, 0x957C, 0xE951, 0x957D, 0xE952, 0x957E, 0xE953, + 0x957F, 0xB3A4, 0x9580, 0xE954, 0x9581, 0xE955, 0x9582, 0xE956, + 0x9583, 0xE957, 0x9584, 0xE958, 0x9585, 0xE959, 0x9586, 0xE95A, + 0x9587, 0xE95B, 0x9588, 0xE95C, 0x9589, 0xE95D, 0x958A, 0xE95E, + 0x958B, 0xE95F, 0x958C, 0xE960, 0x958D, 0xE961, 0x958E, 0xE962, + 0x958F, 0xE963, 0x9590, 0xE964, 0x9591, 0xE965, 0x9592, 0xE966, + 0x9593, 0xE967, 0x9594, 0xE968, 0x9595, 0xE969, 0x9596, 0xE96A, + 0x9597, 0xE96B, 0x9598, 0xE96C, 0x9599, 0xE96D, 0x959A, 0xE96E, + 0x959B, 0xE96F, 0x959C, 0xE970, 0x959D, 0xE971, 0x959E, 0xE972, + 0x959F, 0xE973, 0x95A0, 0xE974, 0x95A1, 0xE975, 0x95A2, 0xE976, + 0x95A3, 0xE977, 0x95A4, 0xE978, 0x95A5, 0xE979, 0x95A6, 0xE97A, + 0x95A7, 0xE97B, 0x95A8, 0xE97C, 0x95A9, 0xE97D, 0x95AA, 0xE97E, + 0x95AB, 0xE980, 0x95AC, 0xE981, 0x95AD, 0xE982, 0x95AE, 0xE983, + 0x95AF, 0xE984, 0x95B0, 0xE985, 0x95B1, 0xE986, 0x95B2, 0xE987, + 0x95B3, 0xE988, 0x95B4, 0xE989, 0x95B5, 0xE98A, 0x95B6, 0xE98B, + 0x95B7, 0xE98C, 0x95B8, 0xE98D, 0x95B9, 0xE98E, 0x95BA, 0xE98F, + 0x95BB, 0xE990, 0x95BC, 0xE991, 0x95BD, 0xE992, 0x95BE, 0xE993, + 0x95BF, 0xE994, 0x95C0, 0xE995, 0x95C1, 0xE996, 0x95C2, 0xE997, + 0x95C3, 0xE998, 0x95C4, 0xE999, 0x95C5, 0xE99A, 0x95C6, 0xE99B, + 0x95C7, 0xE99C, 0x95C8, 0xE99D, 0x95C9, 0xE99E, 0x95CA, 0xE99F, + 0x95CB, 0xE9A0, 0x95CC, 0xEA40, 0x95CD, 0xEA41, 0x95CE, 0xEA42, + 0x95CF, 0xEA43, 0x95D0, 0xEA44, 0x95D1, 0xEA45, 0x95D2, 0xEA46, + 0x95D3, 0xEA47, 0x95D4, 0xEA48, 0x95D5, 0xEA49, 0x95D6, 0xEA4A, + 0x95D7, 0xEA4B, 0x95D8, 0xEA4C, 0x95D9, 0xEA4D, 0x95DA, 0xEA4E, + 0x95DB, 0xEA4F, 0x95DC, 0xEA50, 0x95DD, 0xEA51, 0x95DE, 0xEA52, + 0x95DF, 0xEA53, 0x95E0, 0xEA54, 0x95E1, 0xEA55, 0x95E2, 0xEA56, + 0x95E3, 0xEA57, 0x95E4, 0xEA58, 0x95E5, 0xEA59, 0x95E6, 0xEA5A, + 0x95E7, 0xEA5B, 0x95E8, 0xC3C5, 0x95E9, 0xE3C5, 0x95EA, 0xC9C1, + 0x95EB, 0xE3C6, 0x95EC, 0xEA5C, 0x95ED, 0xB1D5, 0x95EE, 0xCECA, + 0x95EF, 0xB4B3, 0x95F0, 0xC8F2, 0x95F1, 0xE3C7, 0x95F2, 0xCFD0, + 0x95F3, 0xE3C8, 0x95F4, 0xBCE4, 0x95F5, 0xE3C9, 0x95F6, 0xE3CA, + 0x95F7, 0xC3C6, 0x95F8, 0xD5A2, 0x95F9, 0xC4D6, 0x95FA, 0xB9EB, + 0x95FB, 0xCEC5, 0x95FC, 0xE3CB, 0x95FD, 0xC3F6, 0x95FE, 0xE3CC, + 0x95FF, 0xEA5D, 0x9600, 0xB7A7, 0x9601, 0xB8F3, 0x9602, 0xBAD2, + 0x9603, 0xE3CD, 0x9604, 0xE3CE, 0x9605, 0xD4C4, 0x9606, 0xE3CF, + 0x9607, 0xEA5E, 0x9608, 0xE3D0, 0x9609, 0xD1CB, 0x960A, 0xE3D1, + 0x960B, 0xE3D2, 0x960C, 0xE3D3, 0x960D, 0xE3D4, 0x960E, 0xD1D6, + 0x960F, 0xE3D5, 0x9610, 0xB2FB, 0x9611, 0xC0BB, 0x9612, 0xE3D6, + 0x9613, 0xEA5F, 0x9614, 0xC0AB, 0x9615, 0xE3D7, 0x9616, 0xE3D8, + 0x9617, 0xE3D9, 0x9618, 0xEA60, 0x9619, 0xE3DA, 0x961A, 0xE3DB, + 0x961B, 0xEA61, 0x961C, 0xB8B7, 0x961D, 0xDAE2, 0x961E, 0xEA62, + 0x961F, 0xB6D3, 0x9620, 0xEA63, 0x9621, 0xDAE4, 0x9622, 0xDAE3, + 0x9623, 0xEA64, 0x9624, 0xEA65, 0x9625, 0xEA66, 0x9626, 0xEA67, + 0x9627, 0xEA68, 0x9628, 0xEA69, 0x9629, 0xEA6A, 0x962A, 0xDAE6, + 0x962B, 0xEA6B, 0x962C, 0xEA6C, 0x962D, 0xEA6D, 0x962E, 0xC8EE, + 0x962F, 0xEA6E, 0x9630, 0xEA6F, 0x9631, 0xDAE5, 0x9632, 0xB7C0, + 0x9633, 0xD1F4, 0x9634, 0xD2F5, 0x9635, 0xD5F3, 0x9636, 0xBDD7, + 0x9637, 0xEA70, 0x9638, 0xEA71, 0x9639, 0xEA72, 0x963A, 0xEA73, + 0x963B, 0xD7E8, 0x963C, 0xDAE8, 0x963D, 0xDAE7, 0x963E, 0xEA74, + 0x963F, 0xB0A2, 0x9640, 0xCDD3, 0x9641, 0xEA75, 0x9642, 0xDAE9, + 0x9643, 0xEA76, 0x9644, 0xB8BD, 0x9645, 0xBCCA, 0x9646, 0xC2BD, + 0x9647, 0xC2A4, 0x9648, 0xB3C2, 0x9649, 0xDAEA, 0x964A, 0xEA77, + 0x964B, 0xC2AA, 0x964C, 0xC4B0, 0x964D, 0xBDB5, 0x964E, 0xEA78, + 0x964F, 0xEA79, 0x9650, 0xCFDE, 0x9651, 0xEA7A, 0x9652, 0xEA7B, + 0x9653, 0xEA7C, 0x9654, 0xDAEB, 0x9655, 0xC9C2, 0x9656, 0xEA7D, + 0x9657, 0xEA7E, 0x9658, 0xEA80, 0x9659, 0xEA81, 0x965A, 0xEA82, + 0x965B, 0xB1DD, 0x965C, 0xEA83, 0x965D, 0xEA84, 0x965E, 0xEA85, + 0x965F, 0xDAEC, 0x9660, 0xEA86, 0x9661, 0xB6B8, 0x9662, 0xD4BA, + 0x9663, 0xEA87, 0x9664, 0xB3FD, 0x9665, 0xEA88, 0x9666, 0xEA89, + 0x9667, 0xDAED, 0x9668, 0xD4C9, 0x9669, 0xCFD5, 0x966A, 0xC5E3, + 0x966B, 0xEA8A, 0x966C, 0xDAEE, 0x966D, 0xEA8B, 0x966E, 0xEA8C, + 0x966F, 0xEA8D, 0x9670, 0xEA8E, 0x9671, 0xEA8F, 0x9672, 0xDAEF, + 0x9673, 0xEA90, 0x9674, 0xDAF0, 0x9675, 0xC1EA, 0x9676, 0xCCD5, + 0x9677, 0xCFDD, 0x9678, 0xEA91, 0x9679, 0xEA92, 0x967A, 0xEA93, + 0x967B, 0xEA94, 0x967C, 0xEA95, 0x967D, 0xEA96, 0x967E, 0xEA97, + 0x967F, 0xEA98, 0x9680, 0xEA99, 0x9681, 0xEA9A, 0x9682, 0xEA9B, + 0x9683, 0xEA9C, 0x9684, 0xEA9D, 0x9685, 0xD3E7, 0x9686, 0xC2A1, + 0x9687, 0xEA9E, 0x9688, 0xDAF1, 0x9689, 0xEA9F, 0x968A, 0xEAA0, + 0x968B, 0xCBE5, 0x968C, 0xEB40, 0x968D, 0xDAF2, 0x968E, 0xEB41, + 0x968F, 0xCBE6, 0x9690, 0xD2FE, 0x9691, 0xEB42, 0x9692, 0xEB43, + 0x9693, 0xEB44, 0x9694, 0xB8F4, 0x9695, 0xEB45, 0x9696, 0xEB46, + 0x9697, 0xDAF3, 0x9698, 0xB0AF, 0x9699, 0xCFB6, 0x969A, 0xEB47, + 0x969B, 0xEB48, 0x969C, 0xD5CF, 0x969D, 0xEB49, 0x969E, 0xEB4A, + 0x969F, 0xEB4B, 0x96A0, 0xEB4C, 0x96A1, 0xEB4D, 0x96A2, 0xEB4E, + 0x96A3, 0xEB4F, 0x96A4, 0xEB50, 0x96A5, 0xEB51, 0x96A6, 0xEB52, + 0x96A7, 0xCBED, 0x96A8, 0xEB53, 0x96A9, 0xEB54, 0x96AA, 0xEB55, + 0x96AB, 0xEB56, 0x96AC, 0xEB57, 0x96AD, 0xEB58, 0x96AE, 0xEB59, + 0x96AF, 0xEB5A, 0x96B0, 0xDAF4, 0x96B1, 0xEB5B, 0x96B2, 0xEB5C, + 0x96B3, 0xE3C4, 0x96B4, 0xEB5D, 0x96B5, 0xEB5E, 0x96B6, 0xC1A5, + 0x96B7, 0xEB5F, 0x96B8, 0xEB60, 0x96B9, 0xF6BF, 0x96BA, 0xEB61, + 0x96BB, 0xEB62, 0x96BC, 0xF6C0, 0x96BD, 0xF6C1, 0x96BE, 0xC4D1, + 0x96BF, 0xEB63, 0x96C0, 0xC8B8, 0x96C1, 0xD1E3, 0x96C2, 0xEB64, + 0x96C3, 0xEB65, 0x96C4, 0xD0DB, 0x96C5, 0xD1C5, 0x96C6, 0xBCAF, + 0x96C7, 0xB9CD, 0x96C8, 0xEB66, 0x96C9, 0xEFF4, 0x96CA, 0xEB67, + 0x96CB, 0xEB68, 0x96CC, 0xB4C6, 0x96CD, 0xD3BA, 0x96CE, 0xF6C2, + 0x96CF, 0xB3FB, 0x96D0, 0xEB69, 0x96D1, 0xEB6A, 0x96D2, 0xF6C3, + 0x96D3, 0xEB6B, 0x96D4, 0xEB6C, 0x96D5, 0xB5F1, 0x96D6, 0xEB6D, + 0x96D7, 0xEB6E, 0x96D8, 0xEB6F, 0x96D9, 0xEB70, 0x96DA, 0xEB71, + 0x96DB, 0xEB72, 0x96DC, 0xEB73, 0x96DD, 0xEB74, 0x96DE, 0xEB75, + 0x96DF, 0xEB76, 0x96E0, 0xF6C5, 0x96E1, 0xEB77, 0x96E2, 0xEB78, + 0x96E3, 0xEB79, 0x96E4, 0xEB7A, 0x96E5, 0xEB7B, 0x96E6, 0xEB7C, + 0x96E7, 0xEB7D, 0x96E8, 0xD3EA, 0x96E9, 0xF6A7, 0x96EA, 0xD1A9, + 0x96EB, 0xEB7E, 0x96EC, 0xEB80, 0x96ED, 0xEB81, 0x96EE, 0xEB82, + 0x96EF, 0xF6A9, 0x96F0, 0xEB83, 0x96F1, 0xEB84, 0x96F2, 0xEB85, + 0x96F3, 0xF6A8, 0x96F4, 0xEB86, 0x96F5, 0xEB87, 0x96F6, 0xC1E3, + 0x96F7, 0xC0D7, 0x96F8, 0xEB88, 0x96F9, 0xB1A2, 0x96FA, 0xEB89, + 0x96FB, 0xEB8A, 0x96FC, 0xEB8B, 0x96FD, 0xEB8C, 0x96FE, 0xCEED, + 0x96FF, 0xEB8D, 0x9700, 0xD0E8, 0x9701, 0xF6AB, 0x9702, 0xEB8E, + 0x9703, 0xEB8F, 0x9704, 0xCFF6, 0x9705, 0xEB90, 0x9706, 0xF6AA, + 0x9707, 0xD5F0, 0x9708, 0xF6AC, 0x9709, 0xC3B9, 0x970A, 0xEB91, + 0x970B, 0xEB92, 0x970C, 0xEB93, 0x970D, 0xBBF4, 0x970E, 0xF6AE, + 0x970F, 0xF6AD, 0x9710, 0xEB94, 0x9711, 0xEB95, 0x9712, 0xEB96, + 0x9713, 0xC4DE, 0x9714, 0xEB97, 0x9715, 0xEB98, 0x9716, 0xC1D8, + 0x9717, 0xEB99, 0x9718, 0xEB9A, 0x9719, 0xEB9B, 0x971A, 0xEB9C, + 0x971B, 0xEB9D, 0x971C, 0xCBAA, 0x971D, 0xEB9E, 0x971E, 0xCFBC, + 0x971F, 0xEB9F, 0x9720, 0xEBA0, 0x9721, 0xEC40, 0x9722, 0xEC41, + 0x9723, 0xEC42, 0x9724, 0xEC43, 0x9725, 0xEC44, 0x9726, 0xEC45, + 0x9727, 0xEC46, 0x9728, 0xEC47, 0x9729, 0xEC48, 0x972A, 0xF6AF, + 0x972B, 0xEC49, 0x972C, 0xEC4A, 0x972D, 0xF6B0, 0x972E, 0xEC4B, + 0x972F, 0xEC4C, 0x9730, 0xF6B1, 0x9731, 0xEC4D, 0x9732, 0xC2B6, + 0x9733, 0xEC4E, 0x9734, 0xEC4F, 0x9735, 0xEC50, 0x9736, 0xEC51, + 0x9737, 0xEC52, 0x9738, 0xB0D4, 0x9739, 0xC5F9, 0x973A, 0xEC53, + 0x973B, 0xEC54, 0x973C, 0xEC55, 0x973D, 0xEC56, 0x973E, 0xF6B2, + 0x973F, 0xEC57, 0x9740, 0xEC58, 0x9741, 0xEC59, 0x9742, 0xEC5A, + 0x9743, 0xEC5B, 0x9744, 0xEC5C, 0x9745, 0xEC5D, 0x9746, 0xEC5E, + 0x9747, 0xEC5F, 0x9748, 0xEC60, 0x9749, 0xEC61, 0x974A, 0xEC62, + 0x974B, 0xEC63, 0x974C, 0xEC64, 0x974D, 0xEC65, 0x974E, 0xEC66, + 0x974F, 0xEC67, 0x9750, 0xEC68, 0x9751, 0xEC69, 0x9752, 0xC7E0, + 0x9753, 0xF6A6, 0x9754, 0xEC6A, 0x9755, 0xEC6B, 0x9756, 0xBEB8, + 0x9757, 0xEC6C, 0x9758, 0xEC6D, 0x9759, 0xBEB2, 0x975A, 0xEC6E, + 0x975B, 0xB5E5, 0x975C, 0xEC6F, 0x975D, 0xEC70, 0x975E, 0xB7C7, + 0x975F, 0xEC71, 0x9760, 0xBFBF, 0x9761, 0xC3D2, 0x9762, 0xC3E6, + 0x9763, 0xEC72, 0x9764, 0xEC73, 0x9765, 0xD8CC, 0x9766, 0xEC74, + 0x9767, 0xEC75, 0x9768, 0xEC76, 0x9769, 0xB8EF, 0x976A, 0xEC77, + 0x976B, 0xEC78, 0x976C, 0xEC79, 0x976D, 0xEC7A, 0x976E, 0xEC7B, + 0x976F, 0xEC7C, 0x9770, 0xEC7D, 0x9771, 0xEC7E, 0x9772, 0xEC80, + 0x9773, 0xBDF9, 0x9774, 0xD1A5, 0x9775, 0xEC81, 0x9776, 0xB0D0, + 0x9777, 0xEC82, 0x9778, 0xEC83, 0x9779, 0xEC84, 0x977A, 0xEC85, + 0x977B, 0xEC86, 0x977C, 0xF7B0, 0x977D, 0xEC87, 0x977E, 0xEC88, + 0x977F, 0xEC89, 0x9780, 0xEC8A, 0x9781, 0xEC8B, 0x9782, 0xEC8C, + 0x9783, 0xEC8D, 0x9784, 0xEC8E, 0x9785, 0xF7B1, 0x9786, 0xEC8F, + 0x9787, 0xEC90, 0x9788, 0xEC91, 0x9789, 0xEC92, 0x978A, 0xEC93, + 0x978B, 0xD0AC, 0x978C, 0xEC94, 0x978D, 0xB0B0, 0x978E, 0xEC95, + 0x978F, 0xEC96, 0x9790, 0xEC97, 0x9791, 0xF7B2, 0x9792, 0xF7B3, + 0x9793, 0xEC98, 0x9794, 0xF7B4, 0x9795, 0xEC99, 0x9796, 0xEC9A, + 0x9797, 0xEC9B, 0x9798, 0xC7CA, 0x9799, 0xEC9C, 0x979A, 0xEC9D, + 0x979B, 0xEC9E, 0x979C, 0xEC9F, 0x979D, 0xECA0, 0x979E, 0xED40, + 0x979F, 0xED41, 0x97A0, 0xBECF, 0x97A1, 0xED42, 0x97A2, 0xED43, + 0x97A3, 0xF7B7, 0x97A4, 0xED44, 0x97A5, 0xED45, 0x97A6, 0xED46, + 0x97A7, 0xED47, 0x97A8, 0xED48, 0x97A9, 0xED49, 0x97AA, 0xED4A, + 0x97AB, 0xF7B6, 0x97AC, 0xED4B, 0x97AD, 0xB1DE, 0x97AE, 0xED4C, + 0x97AF, 0xF7B5, 0x97B0, 0xED4D, 0x97B1, 0xED4E, 0x97B2, 0xF7B8, + 0x97B3, 0xED4F, 0x97B4, 0xF7B9, 0x97B5, 0xED50, 0x97B6, 0xED51, + 0x97B7, 0xED52, 0x97B8, 0xED53, 0x97B9, 0xED54, 0x97BA, 0xED55, + 0x97BB, 0xED56, 0x97BC, 0xED57, 0x97BD, 0xED58, 0x97BE, 0xED59, + 0x97BF, 0xED5A, 0x97C0, 0xED5B, 0x97C1, 0xED5C, 0x97C2, 0xED5D, + 0x97C3, 0xED5E, 0x97C4, 0xED5F, 0x97C5, 0xED60, 0x97C6, 0xED61, + 0x97C7, 0xED62, 0x97C8, 0xED63, 0x97C9, 0xED64, 0x97CA, 0xED65, + 0x97CB, 0xED66, 0x97CC, 0xED67, 0x97CD, 0xED68, 0x97CE, 0xED69, + 0x97CF, 0xED6A, 0x97D0, 0xED6B, 0x97D1, 0xED6C, 0x97D2, 0xED6D, + 0x97D3, 0xED6E, 0x97D4, 0xED6F, 0x97D5, 0xED70, 0x97D6, 0xED71, + 0x97D7, 0xED72, 0x97D8, 0xED73, 0x97D9, 0xED74, 0x97DA, 0xED75, + 0x97DB, 0xED76, 0x97DC, 0xED77, 0x97DD, 0xED78, 0x97DE, 0xED79, + 0x97DF, 0xED7A, 0x97E0, 0xED7B, 0x97E1, 0xED7C, 0x97E2, 0xED7D, + 0x97E3, 0xED7E, 0x97E4, 0xED80, 0x97E5, 0xED81, 0x97E6, 0xCEA4, + 0x97E7, 0xC8CD, 0x97E8, 0xED82, 0x97E9, 0xBAAB, 0x97EA, 0xE8B8, + 0x97EB, 0xE8B9, 0x97EC, 0xE8BA, 0x97ED, 0xBEC2, 0x97EE, 0xED83, + 0x97EF, 0xED84, 0x97F0, 0xED85, 0x97F1, 0xED86, 0x97F2, 0xED87, + 0x97F3, 0xD2F4, 0x97F4, 0xED88, 0x97F5, 0xD4CF, 0x97F6, 0xC9D8, + 0x97F7, 0xED89, 0x97F8, 0xED8A, 0x97F9, 0xED8B, 0x97FA, 0xED8C, + 0x97FB, 0xED8D, 0x97FC, 0xED8E, 0x97FD, 0xED8F, 0x97FE, 0xED90, + 0x97FF, 0xED91, 0x9800, 0xED92, 0x9801, 0xED93, 0x9802, 0xED94, + 0x9803, 0xED95, 0x9804, 0xED96, 0x9805, 0xED97, 0x9806, 0xED98, + 0x9807, 0xED99, 0x9808, 0xED9A, 0x9809, 0xED9B, 0x980A, 0xED9C, + 0x980B, 0xED9D, 0x980C, 0xED9E, 0x980D, 0xED9F, 0x980E, 0xEDA0, + 0x980F, 0xEE40, 0x9810, 0xEE41, 0x9811, 0xEE42, 0x9812, 0xEE43, + 0x9813, 0xEE44, 0x9814, 0xEE45, 0x9815, 0xEE46, 0x9816, 0xEE47, + 0x9817, 0xEE48, 0x9818, 0xEE49, 0x9819, 0xEE4A, 0x981A, 0xEE4B, + 0x981B, 0xEE4C, 0x981C, 0xEE4D, 0x981D, 0xEE4E, 0x981E, 0xEE4F, + 0x981F, 0xEE50, 0x9820, 0xEE51, 0x9821, 0xEE52, 0x9822, 0xEE53, + 0x9823, 0xEE54, 0x9824, 0xEE55, 0x9825, 0xEE56, 0x9826, 0xEE57, + 0x9827, 0xEE58, 0x9828, 0xEE59, 0x9829, 0xEE5A, 0x982A, 0xEE5B, + 0x982B, 0xEE5C, 0x982C, 0xEE5D, 0x982D, 0xEE5E, 0x982E, 0xEE5F, + 0x982F, 0xEE60, 0x9830, 0xEE61, 0x9831, 0xEE62, 0x9832, 0xEE63, + 0x9833, 0xEE64, 0x9834, 0xEE65, 0x9835, 0xEE66, 0x9836, 0xEE67, + 0x9837, 0xEE68, 0x9838, 0xEE69, 0x9839, 0xEE6A, 0x983A, 0xEE6B, + 0x983B, 0xEE6C, 0x983C, 0xEE6D, 0x983D, 0xEE6E, 0x983E, 0xEE6F, + 0x983F, 0xEE70, 0x9840, 0xEE71, 0x9841, 0xEE72, 0x9842, 0xEE73, + 0x9843, 0xEE74, 0x9844, 0xEE75, 0x9845, 0xEE76, 0x9846, 0xEE77, + 0x9847, 0xEE78, 0x9848, 0xEE79, 0x9849, 0xEE7A, 0x984A, 0xEE7B, + 0x984B, 0xEE7C, 0x984C, 0xEE7D, 0x984D, 0xEE7E, 0x984E, 0xEE80, + 0x984F, 0xEE81, 0x9850, 0xEE82, 0x9851, 0xEE83, 0x9852, 0xEE84, + 0x9853, 0xEE85, 0x9854, 0xEE86, 0x9855, 0xEE87, 0x9856, 0xEE88, + 0x9857, 0xEE89, 0x9858, 0xEE8A, 0x9859, 0xEE8B, 0x985A, 0xEE8C, + 0x985B, 0xEE8D, 0x985C, 0xEE8E, 0x985D, 0xEE8F, 0x985E, 0xEE90, + 0x985F, 0xEE91, 0x9860, 0xEE92, 0x9861, 0xEE93, 0x9862, 0xEE94, + 0x9863, 0xEE95, 0x9864, 0xEE96, 0x9865, 0xEE97, 0x9866, 0xEE98, + 0x9867, 0xEE99, 0x9868, 0xEE9A, 0x9869, 0xEE9B, 0x986A, 0xEE9C, + 0x986B, 0xEE9D, 0x986C, 0xEE9E, 0x986D, 0xEE9F, 0x986E, 0xEEA0, + 0x986F, 0xEF40, 0x9870, 0xEF41, 0x9871, 0xEF42, 0x9872, 0xEF43, + 0x9873, 0xEF44, 0x9874, 0xEF45, 0x9875, 0xD2B3, 0x9876, 0xB6A5, + 0x9877, 0xC7EA, 0x9878, 0xF1FC, 0x9879, 0xCFEE, 0x987A, 0xCBB3, + 0x987B, 0xD0EB, 0x987C, 0xE7EF, 0x987D, 0xCDE7, 0x987E, 0xB9CB, + 0x987F, 0xB6D9, 0x9880, 0xF1FD, 0x9881, 0xB0E4, 0x9882, 0xCBCC, + 0x9883, 0xF1FE, 0x9884, 0xD4A4, 0x9885, 0xC2AD, 0x9886, 0xC1EC, + 0x9887, 0xC6C4, 0x9888, 0xBEB1, 0x9889, 0xF2A1, 0x988A, 0xBCD5, + 0x988B, 0xEF46, 0x988C, 0xF2A2, 0x988D, 0xF2A3, 0x988E, 0xEF47, + 0x988F, 0xF2A4, 0x9890, 0xD2C3, 0x9891, 0xC6B5, 0x9892, 0xEF48, + 0x9893, 0xCDC7, 0x9894, 0xF2A5, 0x9895, 0xEF49, 0x9896, 0xD3B1, + 0x9897, 0xBFC5, 0x9898, 0xCCE2, 0x9899, 0xEF4A, 0x989A, 0xF2A6, + 0x989B, 0xF2A7, 0x989C, 0xD1D5, 0x989D, 0xB6EE, 0x989E, 0xF2A8, + 0x989F, 0xF2A9, 0x98A0, 0xB5DF, 0x98A1, 0xF2AA, 0x98A2, 0xF2AB, + 0x98A3, 0xEF4B, 0x98A4, 0xB2FC, 0x98A5, 0xF2AC, 0x98A6, 0xF2AD, + 0x98A7, 0xC8A7, 0x98A8, 0xEF4C, 0x98A9, 0xEF4D, 0x98AA, 0xEF4E, + 0x98AB, 0xEF4F, 0x98AC, 0xEF50, 0x98AD, 0xEF51, 0x98AE, 0xEF52, + 0x98AF, 0xEF53, 0x98B0, 0xEF54, 0x98B1, 0xEF55, 0x98B2, 0xEF56, + 0x98B3, 0xEF57, 0x98B4, 0xEF58, 0x98B5, 0xEF59, 0x98B6, 0xEF5A, + 0x98B7, 0xEF5B, 0x98B8, 0xEF5C, 0x98B9, 0xEF5D, 0x98BA, 0xEF5E, + 0x98BB, 0xEF5F, 0x98BC, 0xEF60, 0x98BD, 0xEF61, 0x98BE, 0xEF62, + 0x98BF, 0xEF63, 0x98C0, 0xEF64, 0x98C1, 0xEF65, 0x98C2, 0xEF66, + 0x98C3, 0xEF67, 0x98C4, 0xEF68, 0x98C5, 0xEF69, 0x98C6, 0xEF6A, + 0x98C7, 0xEF6B, 0x98C8, 0xEF6C, 0x98C9, 0xEF6D, 0x98CA, 0xEF6E, + 0x98CB, 0xEF6F, 0x98CC, 0xEF70, 0x98CD, 0xEF71, 0x98CE, 0xB7E7, + 0x98CF, 0xEF72, 0x98D0, 0xEF73, 0x98D1, 0xECA9, 0x98D2, 0xECAA, + 0x98D3, 0xECAB, 0x98D4, 0xEF74, 0x98D5, 0xECAC, 0x98D6, 0xEF75, + 0x98D7, 0xEF76, 0x98D8, 0xC6AE, 0x98D9, 0xECAD, 0x98DA, 0xECAE, + 0x98DB, 0xEF77, 0x98DC, 0xEF78, 0x98DD, 0xEF79, 0x98DE, 0xB7C9, + 0x98DF, 0xCAB3, 0x98E0, 0xEF7A, 0x98E1, 0xEF7B, 0x98E2, 0xEF7C, + 0x98E3, 0xEF7D, 0x98E4, 0xEF7E, 0x98E5, 0xEF80, 0x98E6, 0xEF81, + 0x98E7, 0xE2B8, 0x98E8, 0xF7CF, 0x98E9, 0xEF82, 0x98EA, 0xEF83, + 0x98EB, 0xEF84, 0x98EC, 0xEF85, 0x98ED, 0xEF86, 0x98EE, 0xEF87, + 0x98EF, 0xEF88, 0x98F0, 0xEF89, 0x98F1, 0xEF8A, 0x98F2, 0xEF8B, + 0x98F3, 0xEF8C, 0x98F4, 0xEF8D, 0x98F5, 0xEF8E, 0x98F6, 0xEF8F, + 0x98F7, 0xEF90, 0x98F8, 0xEF91, 0x98F9, 0xEF92, 0x98FA, 0xEF93, + 0x98FB, 0xEF94, 0x98FC, 0xEF95, 0x98FD, 0xEF96, 0x98FE, 0xEF97, + 0x98FF, 0xEF98, 0x9900, 0xEF99, 0x9901, 0xEF9A, 0x9902, 0xEF9B, + 0x9903, 0xEF9C, 0x9904, 0xEF9D, 0x9905, 0xEF9E, 0x9906, 0xEF9F, + 0x9907, 0xEFA0, 0x9908, 0xF040, 0x9909, 0xF041, 0x990A, 0xF042, + 0x990B, 0xF043, 0x990C, 0xF044, 0x990D, 0xF7D0, 0x990E, 0xF045, + 0x990F, 0xF046, 0x9910, 0xB2CD, 0x9911, 0xF047, 0x9912, 0xF048, + 0x9913, 0xF049, 0x9914, 0xF04A, 0x9915, 0xF04B, 0x9916, 0xF04C, + 0x9917, 0xF04D, 0x9918, 0xF04E, 0x9919, 0xF04F, 0x991A, 0xF050, + 0x991B, 0xF051, 0x991C, 0xF052, 0x991D, 0xF053, 0x991E, 0xF054, + 0x991F, 0xF055, 0x9920, 0xF056, 0x9921, 0xF057, 0x9922, 0xF058, + 0x9923, 0xF059, 0x9924, 0xF05A, 0x9925, 0xF05B, 0x9926, 0xF05C, + 0x9927, 0xF05D, 0x9928, 0xF05E, 0x9929, 0xF05F, 0x992A, 0xF060, + 0x992B, 0xF061, 0x992C, 0xF062, 0x992D, 0xF063, 0x992E, 0xF7D1, + 0x992F, 0xF064, 0x9930, 0xF065, 0x9931, 0xF066, 0x9932, 0xF067, + 0x9933, 0xF068, 0x9934, 0xF069, 0x9935, 0xF06A, 0x9936, 0xF06B, + 0x9937, 0xF06C, 0x9938, 0xF06D, 0x9939, 0xF06E, 0x993A, 0xF06F, + 0x993B, 0xF070, 0x993C, 0xF071, 0x993D, 0xF072, 0x993E, 0xF073, + 0x993F, 0xF074, 0x9940, 0xF075, 0x9941, 0xF076, 0x9942, 0xF077, + 0x9943, 0xF078, 0x9944, 0xF079, 0x9945, 0xF07A, 0x9946, 0xF07B, + 0x9947, 0xF07C, 0x9948, 0xF07D, 0x9949, 0xF07E, 0x994A, 0xF080, + 0x994B, 0xF081, 0x994C, 0xF082, 0x994D, 0xF083, 0x994E, 0xF084, + 0x994F, 0xF085, 0x9950, 0xF086, 0x9951, 0xF087, 0x9952, 0xF088, + 0x9953, 0xF089, 0x9954, 0xF7D3, 0x9955, 0xF7D2, 0x9956, 0xF08A, + 0x9957, 0xF08B, 0x9958, 0xF08C, 0x9959, 0xF08D, 0x995A, 0xF08E, + 0x995B, 0xF08F, 0x995C, 0xF090, 0x995D, 0xF091, 0x995E, 0xF092, + 0x995F, 0xF093, 0x9960, 0xF094, 0x9961, 0xF095, 0x9962, 0xF096, + 0x9963, 0xE2BB, 0x9964, 0xF097, 0x9965, 0xBCA2, 0x9966, 0xF098, + 0x9967, 0xE2BC, 0x9968, 0xE2BD, 0x9969, 0xE2BE, 0x996A, 0xE2BF, + 0x996B, 0xE2C0, 0x996C, 0xE2C1, 0x996D, 0xB7B9, 0x996E, 0xD2FB, + 0x996F, 0xBDA4, 0x9970, 0xCACE, 0x9971, 0xB1A5, 0x9972, 0xCBC7, + 0x9973, 0xF099, 0x9974, 0xE2C2, 0x9975, 0xB6FC, 0x9976, 0xC8C4, + 0x9977, 0xE2C3, 0x9978, 0xF09A, 0x9979, 0xF09B, 0x997A, 0xBDC8, + 0x997B, 0xF09C, 0x997C, 0xB1FD, 0x997D, 0xE2C4, 0x997E, 0xF09D, + 0x997F, 0xB6F6, 0x9980, 0xE2C5, 0x9981, 0xC4D9, 0x9982, 0xF09E, + 0x9983, 0xF09F, 0x9984, 0xE2C6, 0x9985, 0xCFDA, 0x9986, 0xB9DD, + 0x9987, 0xE2C7, 0x9988, 0xC0A1, 0x9989, 0xF0A0, 0x998A, 0xE2C8, + 0x998B, 0xB2F6, 0x998C, 0xF140, 0x998D, 0xE2C9, 0x998E, 0xF141, + 0x998F, 0xC1F3, 0x9990, 0xE2CA, 0x9991, 0xE2CB, 0x9992, 0xC2F8, + 0x9993, 0xE2CC, 0x9994, 0xE2CD, 0x9995, 0xE2CE, 0x9996, 0xCAD7, + 0x9997, 0xD8B8, 0x9998, 0xD9E5, 0x9999, 0xCFE3, 0x999A, 0xF142, + 0x999B, 0xF143, 0x999C, 0xF144, 0x999D, 0xF145, 0x999E, 0xF146, + 0x999F, 0xF147, 0x99A0, 0xF148, 0x99A1, 0xF149, 0x99A2, 0xF14A, + 0x99A3, 0xF14B, 0x99A4, 0xF14C, 0x99A5, 0xF0A5, 0x99A6, 0xF14D, + 0x99A7, 0xF14E, 0x99A8, 0xDCB0, 0x99A9, 0xF14F, 0x99AA, 0xF150, + 0x99AB, 0xF151, 0x99AC, 0xF152, 0x99AD, 0xF153, 0x99AE, 0xF154, + 0x99AF, 0xF155, 0x99B0, 0xF156, 0x99B1, 0xF157, 0x99B2, 0xF158, + 0x99B3, 0xF159, 0x99B4, 0xF15A, 0x99B5, 0xF15B, 0x99B6, 0xF15C, + 0x99B7, 0xF15D, 0x99B8, 0xF15E, 0x99B9, 0xF15F, 0x99BA, 0xF160, + 0x99BB, 0xF161, 0x99BC, 0xF162, 0x99BD, 0xF163, 0x99BE, 0xF164, + 0x99BF, 0xF165, 0x99C0, 0xF166, 0x99C1, 0xF167, 0x99C2, 0xF168, + 0x99C3, 0xF169, 0x99C4, 0xF16A, 0x99C5, 0xF16B, 0x99C6, 0xF16C, + 0x99C7, 0xF16D, 0x99C8, 0xF16E, 0x99C9, 0xF16F, 0x99CA, 0xF170, + 0x99CB, 0xF171, 0x99CC, 0xF172, 0x99CD, 0xF173, 0x99CE, 0xF174, + 0x99CF, 0xF175, 0x99D0, 0xF176, 0x99D1, 0xF177, 0x99D2, 0xF178, + 0x99D3, 0xF179, 0x99D4, 0xF17A, 0x99D5, 0xF17B, 0x99D6, 0xF17C, + 0x99D7, 0xF17D, 0x99D8, 0xF17E, 0x99D9, 0xF180, 0x99DA, 0xF181, + 0x99DB, 0xF182, 0x99DC, 0xF183, 0x99DD, 0xF184, 0x99DE, 0xF185, + 0x99DF, 0xF186, 0x99E0, 0xF187, 0x99E1, 0xF188, 0x99E2, 0xF189, + 0x99E3, 0xF18A, 0x99E4, 0xF18B, 0x99E5, 0xF18C, 0x99E6, 0xF18D, + 0x99E7, 0xF18E, 0x99E8, 0xF18F, 0x99E9, 0xF190, 0x99EA, 0xF191, + 0x99EB, 0xF192, 0x99EC, 0xF193, 0x99ED, 0xF194, 0x99EE, 0xF195, + 0x99EF, 0xF196, 0x99F0, 0xF197, 0x99F1, 0xF198, 0x99F2, 0xF199, + 0x99F3, 0xF19A, 0x99F4, 0xF19B, 0x99F5, 0xF19C, 0x99F6, 0xF19D, + 0x99F7, 0xF19E, 0x99F8, 0xF19F, 0x99F9, 0xF1A0, 0x99FA, 0xF240, + 0x99FB, 0xF241, 0x99FC, 0xF242, 0x99FD, 0xF243, 0x99FE, 0xF244, + 0x99FF, 0xF245, 0x9A00, 0xF246, 0x9A01, 0xF247, 0x9A02, 0xF248, + 0x9A03, 0xF249, 0x9A04, 0xF24A, 0x9A05, 0xF24B, 0x9A06, 0xF24C, + 0x9A07, 0xF24D, 0x9A08, 0xF24E, 0x9A09, 0xF24F, 0x9A0A, 0xF250, + 0x9A0B, 0xF251, 0x9A0C, 0xF252, 0x9A0D, 0xF253, 0x9A0E, 0xF254, + 0x9A0F, 0xF255, 0x9A10, 0xF256, 0x9A11, 0xF257, 0x9A12, 0xF258, + 0x9A13, 0xF259, 0x9A14, 0xF25A, 0x9A15, 0xF25B, 0x9A16, 0xF25C, + 0x9A17, 0xF25D, 0x9A18, 0xF25E, 0x9A19, 0xF25F, 0x9A1A, 0xF260, + 0x9A1B, 0xF261, 0x9A1C, 0xF262, 0x9A1D, 0xF263, 0x9A1E, 0xF264, + 0x9A1F, 0xF265, 0x9A20, 0xF266, 0x9A21, 0xF267, 0x9A22, 0xF268, + 0x9A23, 0xF269, 0x9A24, 0xF26A, 0x9A25, 0xF26B, 0x9A26, 0xF26C, + 0x9A27, 0xF26D, 0x9A28, 0xF26E, 0x9A29, 0xF26F, 0x9A2A, 0xF270, + 0x9A2B, 0xF271, 0x9A2C, 0xF272, 0x9A2D, 0xF273, 0x9A2E, 0xF274, + 0x9A2F, 0xF275, 0x9A30, 0xF276, 0x9A31, 0xF277, 0x9A32, 0xF278, + 0x9A33, 0xF279, 0x9A34, 0xF27A, 0x9A35, 0xF27B, 0x9A36, 0xF27C, + 0x9A37, 0xF27D, 0x9A38, 0xF27E, 0x9A39, 0xF280, 0x9A3A, 0xF281, + 0x9A3B, 0xF282, 0x9A3C, 0xF283, 0x9A3D, 0xF284, 0x9A3E, 0xF285, + 0x9A3F, 0xF286, 0x9A40, 0xF287, 0x9A41, 0xF288, 0x9A42, 0xF289, + 0x9A43, 0xF28A, 0x9A44, 0xF28B, 0x9A45, 0xF28C, 0x9A46, 0xF28D, + 0x9A47, 0xF28E, 0x9A48, 0xF28F, 0x9A49, 0xF290, 0x9A4A, 0xF291, + 0x9A4B, 0xF292, 0x9A4C, 0xF293, 0x9A4D, 0xF294, 0x9A4E, 0xF295, + 0x9A4F, 0xF296, 0x9A50, 0xF297, 0x9A51, 0xF298, 0x9A52, 0xF299, + 0x9A53, 0xF29A, 0x9A54, 0xF29B, 0x9A55, 0xF29C, 0x9A56, 0xF29D, + 0x9A57, 0xF29E, 0x9A58, 0xF29F, 0x9A59, 0xF2A0, 0x9A5A, 0xF340, + 0x9A5B, 0xF341, 0x9A5C, 0xF342, 0x9A5D, 0xF343, 0x9A5E, 0xF344, + 0x9A5F, 0xF345, 0x9A60, 0xF346, 0x9A61, 0xF347, 0x9A62, 0xF348, + 0x9A63, 0xF349, 0x9A64, 0xF34A, 0x9A65, 0xF34B, 0x9A66, 0xF34C, + 0x9A67, 0xF34D, 0x9A68, 0xF34E, 0x9A69, 0xF34F, 0x9A6A, 0xF350, + 0x9A6B, 0xF351, 0x9A6C, 0xC2ED, 0x9A6D, 0xD4A6, 0x9A6E, 0xCDD4, + 0x9A6F, 0xD1B1, 0x9A70, 0xB3DB, 0x9A71, 0xC7FD, 0x9A72, 0xF352, + 0x9A73, 0xB2B5, 0x9A74, 0xC2BF, 0x9A75, 0xE6E0, 0x9A76, 0xCABB, + 0x9A77, 0xE6E1, 0x9A78, 0xE6E2, 0x9A79, 0xBED4, 0x9A7A, 0xE6E3, + 0x9A7B, 0xD7A4, 0x9A7C, 0xCDD5, 0x9A7D, 0xE6E5, 0x9A7E, 0xBCDD, + 0x9A7F, 0xE6E4, 0x9A80, 0xE6E6, 0x9A81, 0xE6E7, 0x9A82, 0xC2EE, + 0x9A83, 0xF353, 0x9A84, 0xBDBE, 0x9A85, 0xE6E8, 0x9A86, 0xC2E6, + 0x9A87, 0xBAA7, 0x9A88, 0xE6E9, 0x9A89, 0xF354, 0x9A8A, 0xE6EA, + 0x9A8B, 0xB3D2, 0x9A8C, 0xD1E9, 0x9A8D, 0xF355, 0x9A8E, 0xF356, + 0x9A8F, 0xBFA5, 0x9A90, 0xE6EB, 0x9A91, 0xC6EF, 0x9A92, 0xE6EC, + 0x9A93, 0xE6ED, 0x9A94, 0xF357, 0x9A95, 0xF358, 0x9A96, 0xE6EE, + 0x9A97, 0xC6AD, 0x9A98, 0xE6EF, 0x9A99, 0xF359, 0x9A9A, 0xC9A7, + 0x9A9B, 0xE6F0, 0x9A9C, 0xE6F1, 0x9A9D, 0xE6F2, 0x9A9E, 0xE5B9, + 0x9A9F, 0xE6F3, 0x9AA0, 0xE6F4, 0x9AA1, 0xC2E2, 0x9AA2, 0xE6F5, + 0x9AA3, 0xE6F6, 0x9AA4, 0xD6E8, 0x9AA5, 0xE6F7, 0x9AA6, 0xF35A, + 0x9AA7, 0xE6F8, 0x9AA8, 0xB9C7, 0x9AA9, 0xF35B, 0x9AAA, 0xF35C, + 0x9AAB, 0xF35D, 0x9AAC, 0xF35E, 0x9AAD, 0xF35F, 0x9AAE, 0xF360, + 0x9AAF, 0xF361, 0x9AB0, 0xF7BB, 0x9AB1, 0xF7BA, 0x9AB2, 0xF362, + 0x9AB3, 0xF363, 0x9AB4, 0xF364, 0x9AB5, 0xF365, 0x9AB6, 0xF7BE, + 0x9AB7, 0xF7BC, 0x9AB8, 0xBAA1, 0x9AB9, 0xF366, 0x9ABA, 0xF7BF, + 0x9ABB, 0xF367, 0x9ABC, 0xF7C0, 0x9ABD, 0xF368, 0x9ABE, 0xF369, + 0x9ABF, 0xF36A, 0x9AC0, 0xF7C2, 0x9AC1, 0xF7C1, 0x9AC2, 0xF7C4, + 0x9AC3, 0xF36B, 0x9AC4, 0xF36C, 0x9AC5, 0xF7C3, 0x9AC6, 0xF36D, + 0x9AC7, 0xF36E, 0x9AC8, 0xF36F, 0x9AC9, 0xF370, 0x9ACA, 0xF371, + 0x9ACB, 0xF7C5, 0x9ACC, 0xF7C6, 0x9ACD, 0xF372, 0x9ACE, 0xF373, + 0x9ACF, 0xF374, 0x9AD0, 0xF375, 0x9AD1, 0xF7C7, 0x9AD2, 0xF376, + 0x9AD3, 0xCBE8, 0x9AD4, 0xF377, 0x9AD5, 0xF378, 0x9AD6, 0xF379, + 0x9AD7, 0xF37A, 0x9AD8, 0xB8DF, 0x9AD9, 0xF37B, 0x9ADA, 0xF37C, + 0x9ADB, 0xF37D, 0x9ADC, 0xF37E, 0x9ADD, 0xF380, 0x9ADE, 0xF381, + 0x9ADF, 0xF7D4, 0x9AE0, 0xF382, 0x9AE1, 0xF7D5, 0x9AE2, 0xF383, + 0x9AE3, 0xF384, 0x9AE4, 0xF385, 0x9AE5, 0xF386, 0x9AE6, 0xF7D6, + 0x9AE7, 0xF387, 0x9AE8, 0xF388, 0x9AE9, 0xF389, 0x9AEA, 0xF38A, + 0x9AEB, 0xF7D8, 0x9AEC, 0xF38B, 0x9AED, 0xF7DA, 0x9AEE, 0xF38C, + 0x9AEF, 0xF7D7, 0x9AF0, 0xF38D, 0x9AF1, 0xF38E, 0x9AF2, 0xF38F, + 0x9AF3, 0xF390, 0x9AF4, 0xF391, 0x9AF5, 0xF392, 0x9AF6, 0xF393, + 0x9AF7, 0xF394, 0x9AF8, 0xF395, 0x9AF9, 0xF7DB, 0x9AFA, 0xF396, + 0x9AFB, 0xF7D9, 0x9AFC, 0xF397, 0x9AFD, 0xF398, 0x9AFE, 0xF399, + 0x9AFF, 0xF39A, 0x9B00, 0xF39B, 0x9B01, 0xF39C, 0x9B02, 0xF39D, + 0x9B03, 0xD7D7, 0x9B04, 0xF39E, 0x9B05, 0xF39F, 0x9B06, 0xF3A0, + 0x9B07, 0xF440, 0x9B08, 0xF7DC, 0x9B09, 0xF441, 0x9B0A, 0xF442, + 0x9B0B, 0xF443, 0x9B0C, 0xF444, 0x9B0D, 0xF445, 0x9B0E, 0xF446, + 0x9B0F, 0xF7DD, 0x9B10, 0xF447, 0x9B11, 0xF448, 0x9B12, 0xF449, + 0x9B13, 0xF7DE, 0x9B14, 0xF44A, 0x9B15, 0xF44B, 0x9B16, 0xF44C, + 0x9B17, 0xF44D, 0x9B18, 0xF44E, 0x9B19, 0xF44F, 0x9B1A, 0xF450, + 0x9B1B, 0xF451, 0x9B1C, 0xF452, 0x9B1D, 0xF453, 0x9B1E, 0xF454, + 0x9B1F, 0xF7DF, 0x9B20, 0xF455, 0x9B21, 0xF456, 0x9B22, 0xF457, + 0x9B23, 0xF7E0, 0x9B24, 0xF458, 0x9B25, 0xF459, 0x9B26, 0xF45A, + 0x9B27, 0xF45B, 0x9B28, 0xF45C, 0x9B29, 0xF45D, 0x9B2A, 0xF45E, + 0x9B2B, 0xF45F, 0x9B2C, 0xF460, 0x9B2D, 0xF461, 0x9B2E, 0xF462, + 0x9B2F, 0xDBCB, 0x9B30, 0xF463, 0x9B31, 0xF464, 0x9B32, 0xD8AA, + 0x9B33, 0xF465, 0x9B34, 0xF466, 0x9B35, 0xF467, 0x9B36, 0xF468, + 0x9B37, 0xF469, 0x9B38, 0xF46A, 0x9B39, 0xF46B, 0x9B3A, 0xF46C, + 0x9B3B, 0xE5F7, 0x9B3C, 0xB9ED, 0x9B3D, 0xF46D, 0x9B3E, 0xF46E, + 0x9B3F, 0xF46F, 0x9B40, 0xF470, 0x9B41, 0xBFFD, 0x9B42, 0xBBEA, + 0x9B43, 0xF7C9, 0x9B44, 0xC6C7, 0x9B45, 0xF7C8, 0x9B46, 0xF471, + 0x9B47, 0xF7CA, 0x9B48, 0xF7CC, 0x9B49, 0xF7CB, 0x9B4A, 0xF472, + 0x9B4B, 0xF473, 0x9B4C, 0xF474, 0x9B4D, 0xF7CD, 0x9B4E, 0xF475, + 0x9B4F, 0xCEBA, 0x9B50, 0xF476, 0x9B51, 0xF7CE, 0x9B52, 0xF477, + 0x9B53, 0xF478, 0x9B54, 0xC4A7, 0x9B55, 0xF479, 0x9B56, 0xF47A, + 0x9B57, 0xF47B, 0x9B58, 0xF47C, 0x9B59, 0xF47D, 0x9B5A, 0xF47E, + 0x9B5B, 0xF480, 0x9B5C, 0xF481, 0x9B5D, 0xF482, 0x9B5E, 0xF483, + 0x9B5F, 0xF484, 0x9B60, 0xF485, 0x9B61, 0xF486, 0x9B62, 0xF487, + 0x9B63, 0xF488, 0x9B64, 0xF489, 0x9B65, 0xF48A, 0x9B66, 0xF48B, + 0x9B67, 0xF48C, 0x9B68, 0xF48D, 0x9B69, 0xF48E, 0x9B6A, 0xF48F, + 0x9B6B, 0xF490, 0x9B6C, 0xF491, 0x9B6D, 0xF492, 0x9B6E, 0xF493, + 0x9B6F, 0xF494, 0x9B70, 0xF495, 0x9B71, 0xF496, 0x9B72, 0xF497, + 0x9B73, 0xF498, 0x9B74, 0xF499, 0x9B75, 0xF49A, 0x9B76, 0xF49B, + 0x9B77, 0xF49C, 0x9B78, 0xF49D, 0x9B79, 0xF49E, 0x9B7A, 0xF49F, + 0x9B7B, 0xF4A0, 0x9B7C, 0xF540, 0x9B7D, 0xF541, 0x9B7E, 0xF542, + 0x9B7F, 0xF543, 0x9B80, 0xF544, 0x9B81, 0xF545, 0x9B82, 0xF546, + 0x9B83, 0xF547, 0x9B84, 0xF548, 0x9B85, 0xF549, 0x9B86, 0xF54A, + 0x9B87, 0xF54B, 0x9B88, 0xF54C, 0x9B89, 0xF54D, 0x9B8A, 0xF54E, + 0x9B8B, 0xF54F, 0x9B8C, 0xF550, 0x9B8D, 0xF551, 0x9B8E, 0xF552, + 0x9B8F, 0xF553, 0x9B90, 0xF554, 0x9B91, 0xF555, 0x9B92, 0xF556, + 0x9B93, 0xF557, 0x9B94, 0xF558, 0x9B95, 0xF559, 0x9B96, 0xF55A, + 0x9B97, 0xF55B, 0x9B98, 0xF55C, 0x9B99, 0xF55D, 0x9B9A, 0xF55E, + 0x9B9B, 0xF55F, 0x9B9C, 0xF560, 0x9B9D, 0xF561, 0x9B9E, 0xF562, + 0x9B9F, 0xF563, 0x9BA0, 0xF564, 0x9BA1, 0xF565, 0x9BA2, 0xF566, + 0x9BA3, 0xF567, 0x9BA4, 0xF568, 0x9BA5, 0xF569, 0x9BA6, 0xF56A, + 0x9BA7, 0xF56B, 0x9BA8, 0xF56C, 0x9BA9, 0xF56D, 0x9BAA, 0xF56E, + 0x9BAB, 0xF56F, 0x9BAC, 0xF570, 0x9BAD, 0xF571, 0x9BAE, 0xF572, + 0x9BAF, 0xF573, 0x9BB0, 0xF574, 0x9BB1, 0xF575, 0x9BB2, 0xF576, + 0x9BB3, 0xF577, 0x9BB4, 0xF578, 0x9BB5, 0xF579, 0x9BB6, 0xF57A, + 0x9BB7, 0xF57B, 0x9BB8, 0xF57C, 0x9BB9, 0xF57D, 0x9BBA, 0xF57E, + 0x9BBB, 0xF580, 0x9BBC, 0xF581, 0x9BBD, 0xF582, 0x9BBE, 0xF583, + 0x9BBF, 0xF584, 0x9BC0, 0xF585, 0x9BC1, 0xF586, 0x9BC2, 0xF587, + 0x9BC3, 0xF588, 0x9BC4, 0xF589, 0x9BC5, 0xF58A, 0x9BC6, 0xF58B, + 0x9BC7, 0xF58C, 0x9BC8, 0xF58D, 0x9BC9, 0xF58E, 0x9BCA, 0xF58F, + 0x9BCB, 0xF590, 0x9BCC, 0xF591, 0x9BCD, 0xF592, 0x9BCE, 0xF593, + 0x9BCF, 0xF594, 0x9BD0, 0xF595, 0x9BD1, 0xF596, 0x9BD2, 0xF597, + 0x9BD3, 0xF598, 0x9BD4, 0xF599, 0x9BD5, 0xF59A, 0x9BD6, 0xF59B, + 0x9BD7, 0xF59C, 0x9BD8, 0xF59D, 0x9BD9, 0xF59E, 0x9BDA, 0xF59F, + 0x9BDB, 0xF5A0, 0x9BDC, 0xF640, 0x9BDD, 0xF641, 0x9BDE, 0xF642, + 0x9BDF, 0xF643, 0x9BE0, 0xF644, 0x9BE1, 0xF645, 0x9BE2, 0xF646, + 0x9BE3, 0xF647, 0x9BE4, 0xF648, 0x9BE5, 0xF649, 0x9BE6, 0xF64A, + 0x9BE7, 0xF64B, 0x9BE8, 0xF64C, 0x9BE9, 0xF64D, 0x9BEA, 0xF64E, + 0x9BEB, 0xF64F, 0x9BEC, 0xF650, 0x9BED, 0xF651, 0x9BEE, 0xF652, + 0x9BEF, 0xF653, 0x9BF0, 0xF654, 0x9BF1, 0xF655, 0x9BF2, 0xF656, + 0x9BF3, 0xF657, 0x9BF4, 0xF658, 0x9BF5, 0xF659, 0x9BF6, 0xF65A, + 0x9BF7, 0xF65B, 0x9BF8, 0xF65C, 0x9BF9, 0xF65D, 0x9BFA, 0xF65E, + 0x9BFB, 0xF65F, 0x9BFC, 0xF660, 0x9BFD, 0xF661, 0x9BFE, 0xF662, + 0x9BFF, 0xF663, 0x9C00, 0xF664, 0x9C01, 0xF665, 0x9C02, 0xF666, + 0x9C03, 0xF667, 0x9C04, 0xF668, 0x9C05, 0xF669, 0x9C06, 0xF66A, + 0x9C07, 0xF66B, 0x9C08, 0xF66C, 0x9C09, 0xF66D, 0x9C0A, 0xF66E, + 0x9C0B, 0xF66F, 0x9C0C, 0xF670, 0x9C0D, 0xF671, 0x9C0E, 0xF672, + 0x9C0F, 0xF673, 0x9C10, 0xF674, 0x9C11, 0xF675, 0x9C12, 0xF676, + 0x9C13, 0xF677, 0x9C14, 0xF678, 0x9C15, 0xF679, 0x9C16, 0xF67A, + 0x9C17, 0xF67B, 0x9C18, 0xF67C, 0x9C19, 0xF67D, 0x9C1A, 0xF67E, + 0x9C1B, 0xF680, 0x9C1C, 0xF681, 0x9C1D, 0xF682, 0x9C1E, 0xF683, + 0x9C1F, 0xF684, 0x9C20, 0xF685, 0x9C21, 0xF686, 0x9C22, 0xF687, + 0x9C23, 0xF688, 0x9C24, 0xF689, 0x9C25, 0xF68A, 0x9C26, 0xF68B, + 0x9C27, 0xF68C, 0x9C28, 0xF68D, 0x9C29, 0xF68E, 0x9C2A, 0xF68F, + 0x9C2B, 0xF690, 0x9C2C, 0xF691, 0x9C2D, 0xF692, 0x9C2E, 0xF693, + 0x9C2F, 0xF694, 0x9C30, 0xF695, 0x9C31, 0xF696, 0x9C32, 0xF697, + 0x9C33, 0xF698, 0x9C34, 0xF699, 0x9C35, 0xF69A, 0x9C36, 0xF69B, + 0x9C37, 0xF69C, 0x9C38, 0xF69D, 0x9C39, 0xF69E, 0x9C3A, 0xF69F, + 0x9C3B, 0xF6A0, 0x9C3C, 0xF740, 0x9C3D, 0xF741, 0x9C3E, 0xF742, + 0x9C3F, 0xF743, 0x9C40, 0xF744, 0x9C41, 0xF745, 0x9C42, 0xF746, + 0x9C43, 0xF747, 0x9C44, 0xF748, 0x9C45, 0xF749, 0x9C46, 0xF74A, + 0x9C47, 0xF74B, 0x9C48, 0xF74C, 0x9C49, 0xF74D, 0x9C4A, 0xF74E, + 0x9C4B, 0xF74F, 0x9C4C, 0xF750, 0x9C4D, 0xF751, 0x9C4E, 0xF752, + 0x9C4F, 0xF753, 0x9C50, 0xF754, 0x9C51, 0xF755, 0x9C52, 0xF756, + 0x9C53, 0xF757, 0x9C54, 0xF758, 0x9C55, 0xF759, 0x9C56, 0xF75A, + 0x9C57, 0xF75B, 0x9C58, 0xF75C, 0x9C59, 0xF75D, 0x9C5A, 0xF75E, + 0x9C5B, 0xF75F, 0x9C5C, 0xF760, 0x9C5D, 0xF761, 0x9C5E, 0xF762, + 0x9C5F, 0xF763, 0x9C60, 0xF764, 0x9C61, 0xF765, 0x9C62, 0xF766, + 0x9C63, 0xF767, 0x9C64, 0xF768, 0x9C65, 0xF769, 0x9C66, 0xF76A, + 0x9C67, 0xF76B, 0x9C68, 0xF76C, 0x9C69, 0xF76D, 0x9C6A, 0xF76E, + 0x9C6B, 0xF76F, 0x9C6C, 0xF770, 0x9C6D, 0xF771, 0x9C6E, 0xF772, + 0x9C6F, 0xF773, 0x9C70, 0xF774, 0x9C71, 0xF775, 0x9C72, 0xF776, + 0x9C73, 0xF777, 0x9C74, 0xF778, 0x9C75, 0xF779, 0x9C76, 0xF77A, + 0x9C77, 0xF77B, 0x9C78, 0xF77C, 0x9C79, 0xF77D, 0x9C7A, 0xF77E, + 0x9C7B, 0xF780, 0x9C7C, 0xD3E3, 0x9C7D, 0xF781, 0x9C7E, 0xF782, + 0x9C7F, 0xF6CF, 0x9C80, 0xF783, 0x9C81, 0xC2B3, 0x9C82, 0xF6D0, + 0x9C83, 0xF784, 0x9C84, 0xF785, 0x9C85, 0xF6D1, 0x9C86, 0xF6D2, + 0x9C87, 0xF6D3, 0x9C88, 0xF6D4, 0x9C89, 0xF786, 0x9C8A, 0xF787, + 0x9C8B, 0xF6D6, 0x9C8C, 0xF788, 0x9C8D, 0xB1AB, 0x9C8E, 0xF6D7, + 0x9C8F, 0xF789, 0x9C90, 0xF6D8, 0x9C91, 0xF6D9, 0x9C92, 0xF6DA, + 0x9C93, 0xF78A, 0x9C94, 0xF6DB, 0x9C95, 0xF6DC, 0x9C96, 0xF78B, + 0x9C97, 0xF78C, 0x9C98, 0xF78D, 0x9C99, 0xF78E, 0x9C9A, 0xF6DD, + 0x9C9B, 0xF6DE, 0x9C9C, 0xCFCA, 0x9C9D, 0xF78F, 0x9C9E, 0xF6DF, + 0x9C9F, 0xF6E0, 0x9CA0, 0xF6E1, 0x9CA1, 0xF6E2, 0x9CA2, 0xF6E3, + 0x9CA3, 0xF6E4, 0x9CA4, 0xC0F0, 0x9CA5, 0xF6E5, 0x9CA6, 0xF6E6, + 0x9CA7, 0xF6E7, 0x9CA8, 0xF6E8, 0x9CA9, 0xF6E9, 0x9CAA, 0xF790, + 0x9CAB, 0xF6EA, 0x9CAC, 0xF791, 0x9CAD, 0xF6EB, 0x9CAE, 0xF6EC, + 0x9CAF, 0xF792, 0x9CB0, 0xF6ED, 0x9CB1, 0xF6EE, 0x9CB2, 0xF6EF, + 0x9CB3, 0xF6F0, 0x9CB4, 0xF6F1, 0x9CB5, 0xF6F2, 0x9CB6, 0xF6F3, + 0x9CB7, 0xF6F4, 0x9CB8, 0xBEA8, 0x9CB9, 0xF793, 0x9CBA, 0xF6F5, + 0x9CBB, 0xF6F6, 0x9CBC, 0xF6F7, 0x9CBD, 0xF6F8, 0x9CBE, 0xF794, + 0x9CBF, 0xF795, 0x9CC0, 0xF796, 0x9CC1, 0xF797, 0x9CC2, 0xF798, + 0x9CC3, 0xC8FA, 0x9CC4, 0xF6F9, 0x9CC5, 0xF6FA, 0x9CC6, 0xF6FB, + 0x9CC7, 0xF6FC, 0x9CC8, 0xF799, 0x9CC9, 0xF79A, 0x9CCA, 0xF6FD, + 0x9CCB, 0xF6FE, 0x9CCC, 0xF7A1, 0x9CCD, 0xF7A2, 0x9CCE, 0xF7A3, + 0x9CCF, 0xF7A4, 0x9CD0, 0xF7A5, 0x9CD1, 0xF79B, 0x9CD2, 0xF79C, + 0x9CD3, 0xF7A6, 0x9CD4, 0xF7A7, 0x9CD5, 0xF7A8, 0x9CD6, 0xB1EE, + 0x9CD7, 0xF7A9, 0x9CD8, 0xF7AA, 0x9CD9, 0xF7AB, 0x9CDA, 0xF79D, + 0x9CDB, 0xF79E, 0x9CDC, 0xF7AC, 0x9CDD, 0xF7AD, 0x9CDE, 0xC1DB, + 0x9CDF, 0xF7AE, 0x9CE0, 0xF79F, 0x9CE1, 0xF7A0, 0x9CE2, 0xF7AF, + 0x9CE3, 0xF840, 0x9CE4, 0xF841, 0x9CE5, 0xF842, 0x9CE6, 0xF843, + 0x9CE7, 0xF844, 0x9CE8, 0xF845, 0x9CE9, 0xF846, 0x9CEA, 0xF847, + 0x9CEB, 0xF848, 0x9CEC, 0xF849, 0x9CED, 0xF84A, 0x9CEE, 0xF84B, + 0x9CEF, 0xF84C, 0x9CF0, 0xF84D, 0x9CF1, 0xF84E, 0x9CF2, 0xF84F, + 0x9CF3, 0xF850, 0x9CF4, 0xF851, 0x9CF5, 0xF852, 0x9CF6, 0xF853, + 0x9CF7, 0xF854, 0x9CF8, 0xF855, 0x9CF9, 0xF856, 0x9CFA, 0xF857, + 0x9CFB, 0xF858, 0x9CFC, 0xF859, 0x9CFD, 0xF85A, 0x9CFE, 0xF85B, + 0x9CFF, 0xF85C, 0x9D00, 0xF85D, 0x9D01, 0xF85E, 0x9D02, 0xF85F, + 0x9D03, 0xF860, 0x9D04, 0xF861, 0x9D05, 0xF862, 0x9D06, 0xF863, + 0x9D07, 0xF864, 0x9D08, 0xF865, 0x9D09, 0xF866, 0x9D0A, 0xF867, + 0x9D0B, 0xF868, 0x9D0C, 0xF869, 0x9D0D, 0xF86A, 0x9D0E, 0xF86B, + 0x9D0F, 0xF86C, 0x9D10, 0xF86D, 0x9D11, 0xF86E, 0x9D12, 0xF86F, + 0x9D13, 0xF870, 0x9D14, 0xF871, 0x9D15, 0xF872, 0x9D16, 0xF873, + 0x9D17, 0xF874, 0x9D18, 0xF875, 0x9D19, 0xF876, 0x9D1A, 0xF877, + 0x9D1B, 0xF878, 0x9D1C, 0xF879, 0x9D1D, 0xF87A, 0x9D1E, 0xF87B, + 0x9D1F, 0xF87C, 0x9D20, 0xF87D, 0x9D21, 0xF87E, 0x9D22, 0xF880, + 0x9D23, 0xF881, 0x9D24, 0xF882, 0x9D25, 0xF883, 0x9D26, 0xF884, + 0x9D27, 0xF885, 0x9D28, 0xF886, 0x9D29, 0xF887, 0x9D2A, 0xF888, + 0x9D2B, 0xF889, 0x9D2C, 0xF88A, 0x9D2D, 0xF88B, 0x9D2E, 0xF88C, + 0x9D2F, 0xF88D, 0x9D30, 0xF88E, 0x9D31, 0xF88F, 0x9D32, 0xF890, + 0x9D33, 0xF891, 0x9D34, 0xF892, 0x9D35, 0xF893, 0x9D36, 0xF894, + 0x9D37, 0xF895, 0x9D38, 0xF896, 0x9D39, 0xF897, 0x9D3A, 0xF898, + 0x9D3B, 0xF899, 0x9D3C, 0xF89A, 0x9D3D, 0xF89B, 0x9D3E, 0xF89C, + 0x9D3F, 0xF89D, 0x9D40, 0xF89E, 0x9D41, 0xF89F, 0x9D42, 0xF8A0, + 0x9D43, 0xF940, 0x9D44, 0xF941, 0x9D45, 0xF942, 0x9D46, 0xF943, + 0x9D47, 0xF944, 0x9D48, 0xF945, 0x9D49, 0xF946, 0x9D4A, 0xF947, + 0x9D4B, 0xF948, 0x9D4C, 0xF949, 0x9D4D, 0xF94A, 0x9D4E, 0xF94B, + 0x9D4F, 0xF94C, 0x9D50, 0xF94D, 0x9D51, 0xF94E, 0x9D52, 0xF94F, + 0x9D53, 0xF950, 0x9D54, 0xF951, 0x9D55, 0xF952, 0x9D56, 0xF953, + 0x9D57, 0xF954, 0x9D58, 0xF955, 0x9D59, 0xF956, 0x9D5A, 0xF957, + 0x9D5B, 0xF958, 0x9D5C, 0xF959, 0x9D5D, 0xF95A, 0x9D5E, 0xF95B, + 0x9D5F, 0xF95C, 0x9D60, 0xF95D, 0x9D61, 0xF95E, 0x9D62, 0xF95F, + 0x9D63, 0xF960, 0x9D64, 0xF961, 0x9D65, 0xF962, 0x9D66, 0xF963, + 0x9D67, 0xF964, 0x9D68, 0xF965, 0x9D69, 0xF966, 0x9D6A, 0xF967, + 0x9D6B, 0xF968, 0x9D6C, 0xF969, 0x9D6D, 0xF96A, 0x9D6E, 0xF96B, + 0x9D6F, 0xF96C, 0x9D70, 0xF96D, 0x9D71, 0xF96E, 0x9D72, 0xF96F, + 0x9D73, 0xF970, 0x9D74, 0xF971, 0x9D75, 0xF972, 0x9D76, 0xF973, + 0x9D77, 0xF974, 0x9D78, 0xF975, 0x9D79, 0xF976, 0x9D7A, 0xF977, + 0x9D7B, 0xF978, 0x9D7C, 0xF979, 0x9D7D, 0xF97A, 0x9D7E, 0xF97B, + 0x9D7F, 0xF97C, 0x9D80, 0xF97D, 0x9D81, 0xF97E, 0x9D82, 0xF980, + 0x9D83, 0xF981, 0x9D84, 0xF982, 0x9D85, 0xF983, 0x9D86, 0xF984, + 0x9D87, 0xF985, 0x9D88, 0xF986, 0x9D89, 0xF987, 0x9D8A, 0xF988, + 0x9D8B, 0xF989, 0x9D8C, 0xF98A, 0x9D8D, 0xF98B, 0x9D8E, 0xF98C, + 0x9D8F, 0xF98D, 0x9D90, 0xF98E, 0x9D91, 0xF98F, 0x9D92, 0xF990, + 0x9D93, 0xF991, 0x9D94, 0xF992, 0x9D95, 0xF993, 0x9D96, 0xF994, + 0x9D97, 0xF995, 0x9D98, 0xF996, 0x9D99, 0xF997, 0x9D9A, 0xF998, + 0x9D9B, 0xF999, 0x9D9C, 0xF99A, 0x9D9D, 0xF99B, 0x9D9E, 0xF99C, + 0x9D9F, 0xF99D, 0x9DA0, 0xF99E, 0x9DA1, 0xF99F, 0x9DA2, 0xF9A0, + 0x9DA3, 0xFA40, 0x9DA4, 0xFA41, 0x9DA5, 0xFA42, 0x9DA6, 0xFA43, + 0x9DA7, 0xFA44, 0x9DA8, 0xFA45, 0x9DA9, 0xFA46, 0x9DAA, 0xFA47, + 0x9DAB, 0xFA48, 0x9DAC, 0xFA49, 0x9DAD, 0xFA4A, 0x9DAE, 0xFA4B, + 0x9DAF, 0xFA4C, 0x9DB0, 0xFA4D, 0x9DB1, 0xFA4E, 0x9DB2, 0xFA4F, + 0x9DB3, 0xFA50, 0x9DB4, 0xFA51, 0x9DB5, 0xFA52, 0x9DB6, 0xFA53, + 0x9DB7, 0xFA54, 0x9DB8, 0xFA55, 0x9DB9, 0xFA56, 0x9DBA, 0xFA57, + 0x9DBB, 0xFA58, 0x9DBC, 0xFA59, 0x9DBD, 0xFA5A, 0x9DBE, 0xFA5B, + 0x9DBF, 0xFA5C, 0x9DC0, 0xFA5D, 0x9DC1, 0xFA5E, 0x9DC2, 0xFA5F, + 0x9DC3, 0xFA60, 0x9DC4, 0xFA61, 0x9DC5, 0xFA62, 0x9DC6, 0xFA63, + 0x9DC7, 0xFA64, 0x9DC8, 0xFA65, 0x9DC9, 0xFA66, 0x9DCA, 0xFA67, + 0x9DCB, 0xFA68, 0x9DCC, 0xFA69, 0x9DCD, 0xFA6A, 0x9DCE, 0xFA6B, + 0x9DCF, 0xFA6C, 0x9DD0, 0xFA6D, 0x9DD1, 0xFA6E, 0x9DD2, 0xFA6F, + 0x9DD3, 0xFA70, 0x9DD4, 0xFA71, 0x9DD5, 0xFA72, 0x9DD6, 0xFA73, + 0x9DD7, 0xFA74, 0x9DD8, 0xFA75, 0x9DD9, 0xFA76, 0x9DDA, 0xFA77, + 0x9DDB, 0xFA78, 0x9DDC, 0xFA79, 0x9DDD, 0xFA7A, 0x9DDE, 0xFA7B, + 0x9DDF, 0xFA7C, 0x9DE0, 0xFA7D, 0x9DE1, 0xFA7E, 0x9DE2, 0xFA80, + 0x9DE3, 0xFA81, 0x9DE4, 0xFA82, 0x9DE5, 0xFA83, 0x9DE6, 0xFA84, + 0x9DE7, 0xFA85, 0x9DE8, 0xFA86, 0x9DE9, 0xFA87, 0x9DEA, 0xFA88, + 0x9DEB, 0xFA89, 0x9DEC, 0xFA8A, 0x9DED, 0xFA8B, 0x9DEE, 0xFA8C, + 0x9DEF, 0xFA8D, 0x9DF0, 0xFA8E, 0x9DF1, 0xFA8F, 0x9DF2, 0xFA90, + 0x9DF3, 0xFA91, 0x9DF4, 0xFA92, 0x9DF5, 0xFA93, 0x9DF6, 0xFA94, + 0x9DF7, 0xFA95, 0x9DF8, 0xFA96, 0x9DF9, 0xFA97, 0x9DFA, 0xFA98, + 0x9DFB, 0xFA99, 0x9DFC, 0xFA9A, 0x9DFD, 0xFA9B, 0x9DFE, 0xFA9C, + 0x9DFF, 0xFA9D, 0x9E00, 0xFA9E, 0x9E01, 0xFA9F, 0x9E02, 0xFAA0, + 0x9E03, 0xFB40, 0x9E04, 0xFB41, 0x9E05, 0xFB42, 0x9E06, 0xFB43, + 0x9E07, 0xFB44, 0x9E08, 0xFB45, 0x9E09, 0xFB46, 0x9E0A, 0xFB47, + 0x9E0B, 0xFB48, 0x9E0C, 0xFB49, 0x9E0D, 0xFB4A, 0x9E0E, 0xFB4B, + 0x9E0F, 0xFB4C, 0x9E10, 0xFB4D, 0x9E11, 0xFB4E, 0x9E12, 0xFB4F, + 0x9E13, 0xFB50, 0x9E14, 0xFB51, 0x9E15, 0xFB52, 0x9E16, 0xFB53, + 0x9E17, 0xFB54, 0x9E18, 0xFB55, 0x9E19, 0xFB56, 0x9E1A, 0xFB57, + 0x9E1B, 0xFB58, 0x9E1C, 0xFB59, 0x9E1D, 0xFB5A, 0x9E1E, 0xFB5B, + 0x9E1F, 0xC4F1, 0x9E20, 0xF0AF, 0x9E21, 0xBCA6, 0x9E22, 0xF0B0, + 0x9E23, 0xC3F9, 0x9E24, 0xFB5C, 0x9E25, 0xC5B8, 0x9E26, 0xD1BB, + 0x9E27, 0xFB5D, 0x9E28, 0xF0B1, 0x9E29, 0xF0B2, 0x9E2A, 0xF0B3, + 0x9E2B, 0xF0B4, 0x9E2C, 0xF0B5, 0x9E2D, 0xD1BC, 0x9E2E, 0xFB5E, + 0x9E2F, 0xD1EC, 0x9E30, 0xFB5F, 0x9E31, 0xF0B7, 0x9E32, 0xF0B6, + 0x9E33, 0xD4A7, 0x9E34, 0xFB60, 0x9E35, 0xCDD2, 0x9E36, 0xF0B8, + 0x9E37, 0xF0BA, 0x9E38, 0xF0B9, 0x9E39, 0xF0BB, 0x9E3A, 0xF0BC, + 0x9E3B, 0xFB61, 0x9E3C, 0xFB62, 0x9E3D, 0xB8EB, 0x9E3E, 0xF0BD, + 0x9E3F, 0xBAE8, 0x9E40, 0xFB63, 0x9E41, 0xF0BE, 0x9E42, 0xF0BF, + 0x9E43, 0xBEE9, 0x9E44, 0xF0C0, 0x9E45, 0xB6EC, 0x9E46, 0xF0C1, + 0x9E47, 0xF0C2, 0x9E48, 0xF0C3, 0x9E49, 0xF0C4, 0x9E4A, 0xC8B5, + 0x9E4B, 0xF0C5, 0x9E4C, 0xF0C6, 0x9E4D, 0xFB64, 0x9E4E, 0xF0C7, + 0x9E4F, 0xC5F4, 0x9E50, 0xFB65, 0x9E51, 0xF0C8, 0x9E52, 0xFB66, + 0x9E53, 0xFB67, 0x9E54, 0xFB68, 0x9E55, 0xF0C9, 0x9E56, 0xFB69, + 0x9E57, 0xF0CA, 0x9E58, 0xF7BD, 0x9E59, 0xFB6A, 0x9E5A, 0xF0CB, + 0x9E5B, 0xF0CC, 0x9E5C, 0xF0CD, 0x9E5D, 0xFB6B, 0x9E5E, 0xF0CE, + 0x9E5F, 0xFB6C, 0x9E60, 0xFB6D, 0x9E61, 0xFB6E, 0x9E62, 0xFB6F, + 0x9E63, 0xF0CF, 0x9E64, 0xBAD7, 0x9E65, 0xFB70, 0x9E66, 0xF0D0, + 0x9E67, 0xF0D1, 0x9E68, 0xF0D2, 0x9E69, 0xF0D3, 0x9E6A, 0xF0D4, + 0x9E6B, 0xF0D5, 0x9E6C, 0xF0D6, 0x9E6D, 0xF0D8, 0x9E6E, 0xFB71, + 0x9E6F, 0xFB72, 0x9E70, 0xD3A5, 0x9E71, 0xF0D7, 0x9E72, 0xFB73, + 0x9E73, 0xF0D9, 0x9E74, 0xFB74, 0x9E75, 0xFB75, 0x9E76, 0xFB76, + 0x9E77, 0xFB77, 0x9E78, 0xFB78, 0x9E79, 0xFB79, 0x9E7A, 0xFB7A, + 0x9E7B, 0xFB7B, 0x9E7C, 0xFB7C, 0x9E7D, 0xFB7D, 0x9E7E, 0xF5BA, + 0x9E7F, 0xC2B9, 0x9E80, 0xFB7E, 0x9E81, 0xFB80, 0x9E82, 0xF7E4, + 0x9E83, 0xFB81, 0x9E84, 0xFB82, 0x9E85, 0xFB83, 0x9E86, 0xFB84, + 0x9E87, 0xF7E5, 0x9E88, 0xF7E6, 0x9E89, 0xFB85, 0x9E8A, 0xFB86, + 0x9E8B, 0xF7E7, 0x9E8C, 0xFB87, 0x9E8D, 0xFB88, 0x9E8E, 0xFB89, + 0x9E8F, 0xFB8A, 0x9E90, 0xFB8B, 0x9E91, 0xFB8C, 0x9E92, 0xF7E8, + 0x9E93, 0xC2B4, 0x9E94, 0xFB8D, 0x9E95, 0xFB8E, 0x9E96, 0xFB8F, + 0x9E97, 0xFB90, 0x9E98, 0xFB91, 0x9E99, 0xFB92, 0x9E9A, 0xFB93, + 0x9E9B, 0xFB94, 0x9E9C, 0xFB95, 0x9E9D, 0xF7EA, 0x9E9E, 0xFB96, + 0x9E9F, 0xF7EB, 0x9EA0, 0xFB97, 0x9EA1, 0xFB98, 0x9EA2, 0xFB99, + 0x9EA3, 0xFB9A, 0x9EA4, 0xFB9B, 0x9EA5, 0xFB9C, 0x9EA6, 0xC2F3, + 0x9EA7, 0xFB9D, 0x9EA8, 0xFB9E, 0x9EA9, 0xFB9F, 0x9EAA, 0xFBA0, + 0x9EAB, 0xFC40, 0x9EAC, 0xFC41, 0x9EAD, 0xFC42, 0x9EAE, 0xFC43, + 0x9EAF, 0xFC44, 0x9EB0, 0xFC45, 0x9EB1, 0xFC46, 0x9EB2, 0xFC47, + 0x9EB3, 0xFC48, 0x9EB4, 0xF4F0, 0x9EB5, 0xFC49, 0x9EB6, 0xFC4A, + 0x9EB7, 0xFC4B, 0x9EB8, 0xF4EF, 0x9EB9, 0xFC4C, 0x9EBA, 0xFC4D, + 0x9EBB, 0xC2E9, 0x9EBC, 0xFC4E, 0x9EBD, 0xF7E1, 0x9EBE, 0xF7E2, + 0x9EBF, 0xFC4F, 0x9EC0, 0xFC50, 0x9EC1, 0xFC51, 0x9EC2, 0xFC52, + 0x9EC3, 0xFC53, 0x9EC4, 0xBBC6, 0x9EC5, 0xFC54, 0x9EC6, 0xFC55, + 0x9EC7, 0xFC56, 0x9EC8, 0xFC57, 0x9EC9, 0xD9E4, 0x9ECA, 0xFC58, + 0x9ECB, 0xFC59, 0x9ECC, 0xFC5A, 0x9ECD, 0xCAF2, 0x9ECE, 0xC0E8, + 0x9ECF, 0xF0A4, 0x9ED0, 0xFC5B, 0x9ED1, 0xBADA, 0x9ED2, 0xFC5C, + 0x9ED3, 0xFC5D, 0x9ED4, 0xC7AD, 0x9ED5, 0xFC5E, 0x9ED6, 0xFC5F, + 0x9ED7, 0xFC60, 0x9ED8, 0xC4AC, 0x9ED9, 0xFC61, 0x9EDA, 0xFC62, + 0x9EDB, 0xF7EC, 0x9EDC, 0xF7ED, 0x9EDD, 0xF7EE, 0x9EDE, 0xFC63, + 0x9EDF, 0xF7F0, 0x9EE0, 0xF7EF, 0x9EE1, 0xFC64, 0x9EE2, 0xF7F1, + 0x9EE3, 0xFC65, 0x9EE4, 0xFC66, 0x9EE5, 0xF7F4, 0x9EE6, 0xFC67, + 0x9EE7, 0xF7F3, 0x9EE8, 0xFC68, 0x9EE9, 0xF7F2, 0x9EEA, 0xF7F5, + 0x9EEB, 0xFC69, 0x9EEC, 0xFC6A, 0x9EED, 0xFC6B, 0x9EEE, 0xFC6C, + 0x9EEF, 0xF7F6, 0x9EF0, 0xFC6D, 0x9EF1, 0xFC6E, 0x9EF2, 0xFC6F, + 0x9EF3, 0xFC70, 0x9EF4, 0xFC71, 0x9EF5, 0xFC72, 0x9EF6, 0xFC73, + 0x9EF7, 0xFC74, 0x9EF8, 0xFC75, 0x9EF9, 0xEDE9, 0x9EFA, 0xFC76, + 0x9EFB, 0xEDEA, 0x9EFC, 0xEDEB, 0x9EFD, 0xFC77, 0x9EFE, 0xF6BC, + 0x9EFF, 0xFC78, 0x9F00, 0xFC79, 0x9F01, 0xFC7A, 0x9F02, 0xFC7B, + 0x9F03, 0xFC7C, 0x9F04, 0xFC7D, 0x9F05, 0xFC7E, 0x9F06, 0xFC80, + 0x9F07, 0xFC81, 0x9F08, 0xFC82, 0x9F09, 0xFC83, 0x9F0A, 0xFC84, + 0x9F0B, 0xF6BD, 0x9F0C, 0xFC85, 0x9F0D, 0xF6BE, 0x9F0E, 0xB6A6, + 0x9F0F, 0xFC86, 0x9F10, 0xD8BE, 0x9F11, 0xFC87, 0x9F12, 0xFC88, + 0x9F13, 0xB9C4, 0x9F14, 0xFC89, 0x9F15, 0xFC8A, 0x9F16, 0xFC8B, + 0x9F17, 0xD8BB, 0x9F18, 0xFC8C, 0x9F19, 0xDCB1, 0x9F1A, 0xFC8D, + 0x9F1B, 0xFC8E, 0x9F1C, 0xFC8F, 0x9F1D, 0xFC90, 0x9F1E, 0xFC91, + 0x9F1F, 0xFC92, 0x9F20, 0xCAF3, 0x9F21, 0xFC93, 0x9F22, 0xF7F7, + 0x9F23, 0xFC94, 0x9F24, 0xFC95, 0x9F25, 0xFC96, 0x9F26, 0xFC97, + 0x9F27, 0xFC98, 0x9F28, 0xFC99, 0x9F29, 0xFC9A, 0x9F2A, 0xFC9B, + 0x9F2B, 0xFC9C, 0x9F2C, 0xF7F8, 0x9F2D, 0xFC9D, 0x9F2E, 0xFC9E, + 0x9F2F, 0xF7F9, 0x9F30, 0xFC9F, 0x9F31, 0xFCA0, 0x9F32, 0xFD40, + 0x9F33, 0xFD41, 0x9F34, 0xFD42, 0x9F35, 0xFD43, 0x9F36, 0xFD44, + 0x9F37, 0xF7FB, 0x9F38, 0xFD45, 0x9F39, 0xF7FA, 0x9F3A, 0xFD46, + 0x9F3B, 0xB1C7, 0x9F3C, 0xFD47, 0x9F3D, 0xF7FC, 0x9F3E, 0xF7FD, + 0x9F3F, 0xFD48, 0x9F40, 0xFD49, 0x9F41, 0xFD4A, 0x9F42, 0xFD4B, + 0x9F43, 0xFD4C, 0x9F44, 0xF7FE, 0x9F45, 0xFD4D, 0x9F46, 0xFD4E, + 0x9F47, 0xFD4F, 0x9F48, 0xFD50, 0x9F49, 0xFD51, 0x9F4A, 0xFD52, + 0x9F4B, 0xFD53, 0x9F4C, 0xFD54, 0x9F4D, 0xFD55, 0x9F4E, 0xFD56, + 0x9F4F, 0xFD57, 0x9F50, 0xC6EB, 0x9F51, 0xECB4, 0x9F52, 0xFD58, + 0x9F53, 0xFD59, 0x9F54, 0xFD5A, 0x9F55, 0xFD5B, 0x9F56, 0xFD5C, + 0x9F57, 0xFD5D, 0x9F58, 0xFD5E, 0x9F59, 0xFD5F, 0x9F5A, 0xFD60, + 0x9F5B, 0xFD61, 0x9F5C, 0xFD62, 0x9F5D, 0xFD63, 0x9F5E, 0xFD64, + 0x9F5F, 0xFD65, 0x9F60, 0xFD66, 0x9F61, 0xFD67, 0x9F62, 0xFD68, + 0x9F63, 0xFD69, 0x9F64, 0xFD6A, 0x9F65, 0xFD6B, 0x9F66, 0xFD6C, + 0x9F67, 0xFD6D, 0x9F68, 0xFD6E, 0x9F69, 0xFD6F, 0x9F6A, 0xFD70, + 0x9F6B, 0xFD71, 0x9F6C, 0xFD72, 0x9F6D, 0xFD73, 0x9F6E, 0xFD74, + 0x9F6F, 0xFD75, 0x9F70, 0xFD76, 0x9F71, 0xFD77, 0x9F72, 0xFD78, + 0x9F73, 0xFD79, 0x9F74, 0xFD7A, 0x9F75, 0xFD7B, 0x9F76, 0xFD7C, + 0x9F77, 0xFD7D, 0x9F78, 0xFD7E, 0x9F79, 0xFD80, 0x9F7A, 0xFD81, + 0x9F7B, 0xFD82, 0x9F7C, 0xFD83, 0x9F7D, 0xFD84, 0x9F7E, 0xFD85, + 0x9F7F, 0xB3DD, 0x9F80, 0xF6B3, 0x9F81, 0xFD86, 0x9F82, 0xFD87, + 0x9F83, 0xF6B4, 0x9F84, 0xC1E4, 0x9F85, 0xF6B5, 0x9F86, 0xF6B6, + 0x9F87, 0xF6B7, 0x9F88, 0xF6B8, 0x9F89, 0xF6B9, 0x9F8A, 0xF6BA, + 0x9F8B, 0xC8A3, 0x9F8C, 0xF6BB, 0x9F8D, 0xFD88, 0x9F8E, 0xFD89, + 0x9F8F, 0xFD8A, 0x9F90, 0xFD8B, 0x9F91, 0xFD8C, 0x9F92, 0xFD8D, + 0x9F93, 0xFD8E, 0x9F94, 0xFD8F, 0x9F95, 0xFD90, 0x9F96, 0xFD91, + 0x9F97, 0xFD92, 0x9F98, 0xFD93, 0x9F99, 0xC1FA, 0x9F9A, 0xB9A8, + 0x9F9B, 0xEDE8, 0x9F9C, 0xFD94, 0x9F9D, 0xFD95, 0x9F9E, 0xFD96, + 0x9F9F, 0xB9EA, 0x9FA0, 0xD9DF, 0x9FA1, 0xFD97, 0x9FA2, 0xFD98, + 0x9FA3, 0xFD99, 0x9FA4, 0xFD9A, 0x9FA5, 0xFD9B, 0xF92C, 0xFD9C, + 0xF979, 0xFD9D, 0xF995, 0xFD9E, 0xF9E7, 0xFD9F, 0xF9F1, 0xFDA0, + 0xFA0C, 0xFE40, 0xFA0D, 0xFE41, 0xFA0E, 0xFE42, 0xFA0F, 0xFE43, + 0xFA11, 0xFE44, 0xFA13, 0xFE45, 0xFA14, 0xFE46, 0xFA18, 0xFE47, + 0xFA1F, 0xFE48, 0xFA20, 0xFE49, 0xFA21, 0xFE4A, 0xFA23, 0xFE4B, + 0xFA24, 0xFE4C, 0xFA27, 0xFE4D, 0xFA28, 0xFE4E, 0xFA29, 0xFE4F, + 0xFE30, 0xA955, 0xFE31, 0xA6F2, 0xFE33, 0xA6F4, 0xFE34, 0xA6F5, + 0xFE35, 0xA6E0, 0xFE36, 0xA6E1, 0xFE37, 0xA6F0, 0xFE38, 0xA6F1, + 0xFE39, 0xA6E2, 0xFE3A, 0xA6E3, 0xFE3B, 0xA6EE, 0xFE3C, 0xA6EF, + 0xFE3D, 0xA6E6, 0xFE3E, 0xA6E7, 0xFE3F, 0xA6E4, 0xFE40, 0xA6E5, + 0xFE41, 0xA6E8, 0xFE42, 0xA6E9, 0xFE43, 0xA6EA, 0xFE44, 0xA6EB, + 0xFE49, 0xA968, 0xFE4A, 0xA969, 0xFE4B, 0xA96A, 0xFE4C, 0xA96B, + 0xFE4D, 0xA96C, 0xFE4E, 0xA96D, 0xFE4F, 0xA96E, 0xFE50, 0xA96F, + 0xFE51, 0xA970, 0xFE52, 0xA971, 0xFE54, 0xA972, 0xFE55, 0xA973, + 0xFE56, 0xA974, 0xFE57, 0xA975, 0xFE59, 0xA976, 0xFE5A, 0xA977, + 0xFE5B, 0xA978, 0xFE5C, 0xA979, 0xFE5D, 0xA97A, 0xFE5E, 0xA97B, + 0xFE5F, 0xA97C, 0xFE60, 0xA97D, 0xFE61, 0xA97E, 0xFE62, 0xA980, + 0xFE63, 0xA981, 0xFE64, 0xA982, 0xFE65, 0xA983, 0xFE66, 0xA984, + 0xFE68, 0xA985, 0xFE69, 0xA986, 0xFE6A, 0xA987, 0xFE6B, 0xA988, + 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA1E7, + 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA3DC, + 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, 0xFF5E, 0xA1AB, 0xFFE0, 0xA1E9, 0xFFE1, 0xA1EA, + 0xFFE2, 0xA956, 0xFFE3, 0xA3FE, 0xFFE4, 0xA957, 0xFFE5, 0xA3A4, + 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0x0080, 0x20AC, 0x8140, 0x4E02, 0x8141, 0x4E04, 0x8142, 0x4E05, + 0x8143, 0x4E06, 0x8144, 0x4E0F, 0x8145, 0x4E12, 0x8146, 0x4E17, + 0x8147, 0x4E1F, 0x8148, 0x4E20, 0x8149, 0x4E21, 0x814A, 0x4E23, + 0x814B, 0x4E26, 0x814C, 0x4E29, 0x814D, 0x4E2E, 0x814E, 0x4E2F, + 0x814F, 0x4E31, 0x8150, 0x4E33, 0x8151, 0x4E35, 0x8152, 0x4E37, + 0x8153, 0x4E3C, 0x8154, 0x4E40, 0x8155, 0x4E41, 0x8156, 0x4E42, + 0x8157, 0x4E44, 0x8158, 0x4E46, 0x8159, 0x4E4A, 0x815A, 0x4E51, + 0x815B, 0x4E55, 0x815C, 0x4E57, 0x815D, 0x4E5A, 0x815E, 0x4E5B, + 0x815F, 0x4E62, 0x8160, 0x4E63, 0x8161, 0x4E64, 0x8162, 0x4E65, + 0x8163, 0x4E67, 0x8164, 0x4E68, 0x8165, 0x4E6A, 0x8166, 0x4E6B, + 0x8167, 0x4E6C, 0x8168, 0x4E6D, 0x8169, 0x4E6E, 0x816A, 0x4E6F, + 0x816B, 0x4E72, 0x816C, 0x4E74, 0x816D, 0x4E75, 0x816E, 0x4E76, + 0x816F, 0x4E77, 0x8170, 0x4E78, 0x8171, 0x4E79, 0x8172, 0x4E7A, + 0x8173, 0x4E7B, 0x8174, 0x4E7C, 0x8175, 0x4E7D, 0x8176, 0x4E7F, + 0x8177, 0x4E80, 0x8178, 0x4E81, 0x8179, 0x4E82, 0x817A, 0x4E83, + 0x817B, 0x4E84, 0x817C, 0x4E85, 0x817D, 0x4E87, 0x817E, 0x4E8A, + 0x8180, 0x4E90, 0x8181, 0x4E96, 0x8182, 0x4E97, 0x8183, 0x4E99, + 0x8184, 0x4E9C, 0x8185, 0x4E9D, 0x8186, 0x4E9E, 0x8187, 0x4EA3, + 0x8188, 0x4EAA, 0x8189, 0x4EAF, 0x818A, 0x4EB0, 0x818B, 0x4EB1, + 0x818C, 0x4EB4, 0x818D, 0x4EB6, 0x818E, 0x4EB7, 0x818F, 0x4EB8, + 0x8190, 0x4EB9, 0x8191, 0x4EBC, 0x8192, 0x4EBD, 0x8193, 0x4EBE, + 0x8194, 0x4EC8, 0x8195, 0x4ECC, 0x8196, 0x4ECF, 0x8197, 0x4ED0, + 0x8198, 0x4ED2, 0x8199, 0x4EDA, 0x819A, 0x4EDB, 0x819B, 0x4EDC, + 0x819C, 0x4EE0, 0x819D, 0x4EE2, 0x819E, 0x4EE6, 0x819F, 0x4EE7, + 0x81A0, 0x4EE9, 0x81A1, 0x4EED, 0x81A2, 0x4EEE, 0x81A3, 0x4EEF, + 0x81A4, 0x4EF1, 0x81A5, 0x4EF4, 0x81A6, 0x4EF8, 0x81A7, 0x4EF9, + 0x81A8, 0x4EFA, 0x81A9, 0x4EFC, 0x81AA, 0x4EFE, 0x81AB, 0x4F00, + 0x81AC, 0x4F02, 0x81AD, 0x4F03, 0x81AE, 0x4F04, 0x81AF, 0x4F05, + 0x81B0, 0x4F06, 0x81B1, 0x4F07, 0x81B2, 0x4F08, 0x81B3, 0x4F0B, + 0x81B4, 0x4F0C, 0x81B5, 0x4F12, 0x81B6, 0x4F13, 0x81B7, 0x4F14, + 0x81B8, 0x4F15, 0x81B9, 0x4F16, 0x81BA, 0x4F1C, 0x81BB, 0x4F1D, + 0x81BC, 0x4F21, 0x81BD, 0x4F23, 0x81BE, 0x4F28, 0x81BF, 0x4F29, + 0x81C0, 0x4F2C, 0x81C1, 0x4F2D, 0x81C2, 0x4F2E, 0x81C3, 0x4F31, + 0x81C4, 0x4F33, 0x81C5, 0x4F35, 0x81C6, 0x4F37, 0x81C7, 0x4F39, + 0x81C8, 0x4F3B, 0x81C9, 0x4F3E, 0x81CA, 0x4F3F, 0x81CB, 0x4F40, + 0x81CC, 0x4F41, 0x81CD, 0x4F42, 0x81CE, 0x4F44, 0x81CF, 0x4F45, + 0x81D0, 0x4F47, 0x81D1, 0x4F48, 0x81D2, 0x4F49, 0x81D3, 0x4F4A, + 0x81D4, 0x4F4B, 0x81D5, 0x4F4C, 0x81D6, 0x4F52, 0x81D7, 0x4F54, + 0x81D8, 0x4F56, 0x81D9, 0x4F61, 0x81DA, 0x4F62, 0x81DB, 0x4F66, + 0x81DC, 0x4F68, 0x81DD, 0x4F6A, 0x81DE, 0x4F6B, 0x81DF, 0x4F6D, + 0x81E0, 0x4F6E, 0x81E1, 0x4F71, 0x81E2, 0x4F72, 0x81E3, 0x4F75, + 0x81E4, 0x4F77, 0x81E5, 0x4F78, 0x81E6, 0x4F79, 0x81E7, 0x4F7A, + 0x81E8, 0x4F7D, 0x81E9, 0x4F80, 0x81EA, 0x4F81, 0x81EB, 0x4F82, + 0x81EC, 0x4F85, 0x81ED, 0x4F86, 0x81EE, 0x4F87, 0x81EF, 0x4F8A, + 0x81F0, 0x4F8C, 0x81F1, 0x4F8E, 0x81F2, 0x4F90, 0x81F3, 0x4F92, + 0x81F4, 0x4F93, 0x81F5, 0x4F95, 0x81F6, 0x4F96, 0x81F7, 0x4F98, + 0x81F8, 0x4F99, 0x81F9, 0x4F9A, 0x81FA, 0x4F9C, 0x81FB, 0x4F9E, + 0x81FC, 0x4F9F, 0x81FD, 0x4FA1, 0x81FE, 0x4FA2, 0x8240, 0x4FA4, + 0x8241, 0x4FAB, 0x8242, 0x4FAD, 0x8243, 0x4FB0, 0x8244, 0x4FB1, + 0x8245, 0x4FB2, 0x8246, 0x4FB3, 0x8247, 0x4FB4, 0x8248, 0x4FB6, + 0x8249, 0x4FB7, 0x824A, 0x4FB8, 0x824B, 0x4FB9, 0x824C, 0x4FBA, + 0x824D, 0x4FBB, 0x824E, 0x4FBC, 0x824F, 0x4FBD, 0x8250, 0x4FBE, + 0x8251, 0x4FC0, 0x8252, 0x4FC1, 0x8253, 0x4FC2, 0x8254, 0x4FC6, + 0x8255, 0x4FC7, 0x8256, 0x4FC8, 0x8257, 0x4FC9, 0x8258, 0x4FCB, + 0x8259, 0x4FCC, 0x825A, 0x4FCD, 0x825B, 0x4FD2, 0x825C, 0x4FD3, + 0x825D, 0x4FD4, 0x825E, 0x4FD5, 0x825F, 0x4FD6, 0x8260, 0x4FD9, + 0x8261, 0x4FDB, 0x8262, 0x4FE0, 0x8263, 0x4FE2, 0x8264, 0x4FE4, + 0x8265, 0x4FE5, 0x8266, 0x4FE7, 0x8267, 0x4FEB, 0x8268, 0x4FEC, + 0x8269, 0x4FF0, 0x826A, 0x4FF2, 0x826B, 0x4FF4, 0x826C, 0x4FF5, + 0x826D, 0x4FF6, 0x826E, 0x4FF7, 0x826F, 0x4FF9, 0x8270, 0x4FFB, + 0x8271, 0x4FFC, 0x8272, 0x4FFD, 0x8273, 0x4FFF, 0x8274, 0x5000, + 0x8275, 0x5001, 0x8276, 0x5002, 0x8277, 0x5003, 0x8278, 0x5004, + 0x8279, 0x5005, 0x827A, 0x5006, 0x827B, 0x5007, 0x827C, 0x5008, + 0x827D, 0x5009, 0x827E, 0x500A, 0x8280, 0x500B, 0x8281, 0x500E, + 0x8282, 0x5010, 0x8283, 0x5011, 0x8284, 0x5013, 0x8285, 0x5015, + 0x8286, 0x5016, 0x8287, 0x5017, 0x8288, 0x501B, 0x8289, 0x501D, + 0x828A, 0x501E, 0x828B, 0x5020, 0x828C, 0x5022, 0x828D, 0x5023, + 0x828E, 0x5024, 0x828F, 0x5027, 0x8290, 0x502B, 0x8291, 0x502F, + 0x8292, 0x5030, 0x8293, 0x5031, 0x8294, 0x5032, 0x8295, 0x5033, + 0x8296, 0x5034, 0x8297, 0x5035, 0x8298, 0x5036, 0x8299, 0x5037, + 0x829A, 0x5038, 0x829B, 0x5039, 0x829C, 0x503B, 0x829D, 0x503D, + 0x829E, 0x503F, 0x829F, 0x5040, 0x82A0, 0x5041, 0x82A1, 0x5042, + 0x82A2, 0x5044, 0x82A3, 0x5045, 0x82A4, 0x5046, 0x82A5, 0x5049, + 0x82A6, 0x504A, 0x82A7, 0x504B, 0x82A8, 0x504D, 0x82A9, 0x5050, + 0x82AA, 0x5051, 0x82AB, 0x5052, 0x82AC, 0x5053, 0x82AD, 0x5054, + 0x82AE, 0x5056, 0x82AF, 0x5057, 0x82B0, 0x5058, 0x82B1, 0x5059, + 0x82B2, 0x505B, 0x82B3, 0x505D, 0x82B4, 0x505E, 0x82B5, 0x505F, + 0x82B6, 0x5060, 0x82B7, 0x5061, 0x82B8, 0x5062, 0x82B9, 0x5063, + 0x82BA, 0x5064, 0x82BB, 0x5066, 0x82BC, 0x5067, 0x82BD, 0x5068, + 0x82BE, 0x5069, 0x82BF, 0x506A, 0x82C0, 0x506B, 0x82C1, 0x506D, + 0x82C2, 0x506E, 0x82C3, 0x506F, 0x82C4, 0x5070, 0x82C5, 0x5071, + 0x82C6, 0x5072, 0x82C7, 0x5073, 0x82C8, 0x5074, 0x82C9, 0x5075, + 0x82CA, 0x5078, 0x82CB, 0x5079, 0x82CC, 0x507A, 0x82CD, 0x507C, + 0x82CE, 0x507D, 0x82CF, 0x5081, 0x82D0, 0x5082, 0x82D1, 0x5083, + 0x82D2, 0x5084, 0x82D3, 0x5086, 0x82D4, 0x5087, 0x82D5, 0x5089, + 0x82D6, 0x508A, 0x82D7, 0x508B, 0x82D8, 0x508C, 0x82D9, 0x508E, + 0x82DA, 0x508F, 0x82DB, 0x5090, 0x82DC, 0x5091, 0x82DD, 0x5092, + 0x82DE, 0x5093, 0x82DF, 0x5094, 0x82E0, 0x5095, 0x82E1, 0x5096, + 0x82E2, 0x5097, 0x82E3, 0x5098, 0x82E4, 0x5099, 0x82E5, 0x509A, + 0x82E6, 0x509B, 0x82E7, 0x509C, 0x82E8, 0x509D, 0x82E9, 0x509E, + 0x82EA, 0x509F, 0x82EB, 0x50A0, 0x82EC, 0x50A1, 0x82ED, 0x50A2, + 0x82EE, 0x50A4, 0x82EF, 0x50A6, 0x82F0, 0x50AA, 0x82F1, 0x50AB, + 0x82F2, 0x50AD, 0x82F3, 0x50AE, 0x82F4, 0x50AF, 0x82F5, 0x50B0, + 0x82F6, 0x50B1, 0x82F7, 0x50B3, 0x82F8, 0x50B4, 0x82F9, 0x50B5, + 0x82FA, 0x50B6, 0x82FB, 0x50B7, 0x82FC, 0x50B8, 0x82FD, 0x50B9, + 0x82FE, 0x50BC, 0x8340, 0x50BD, 0x8341, 0x50BE, 0x8342, 0x50BF, + 0x8343, 0x50C0, 0x8344, 0x50C1, 0x8345, 0x50C2, 0x8346, 0x50C3, + 0x8347, 0x50C4, 0x8348, 0x50C5, 0x8349, 0x50C6, 0x834A, 0x50C7, + 0x834B, 0x50C8, 0x834C, 0x50C9, 0x834D, 0x50CA, 0x834E, 0x50CB, + 0x834F, 0x50CC, 0x8350, 0x50CD, 0x8351, 0x50CE, 0x8352, 0x50D0, + 0x8353, 0x50D1, 0x8354, 0x50D2, 0x8355, 0x50D3, 0x8356, 0x50D4, + 0x8357, 0x50D5, 0x8358, 0x50D7, 0x8359, 0x50D8, 0x835A, 0x50D9, + 0x835B, 0x50DB, 0x835C, 0x50DC, 0x835D, 0x50DD, 0x835E, 0x50DE, + 0x835F, 0x50DF, 0x8360, 0x50E0, 0x8361, 0x50E1, 0x8362, 0x50E2, + 0x8363, 0x50E3, 0x8364, 0x50E4, 0x8365, 0x50E5, 0x8366, 0x50E8, + 0x8367, 0x50E9, 0x8368, 0x50EA, 0x8369, 0x50EB, 0x836A, 0x50EF, + 0x836B, 0x50F0, 0x836C, 0x50F1, 0x836D, 0x50F2, 0x836E, 0x50F4, + 0x836F, 0x50F6, 0x8370, 0x50F7, 0x8371, 0x50F8, 0x8372, 0x50F9, + 0x8373, 0x50FA, 0x8374, 0x50FC, 0x8375, 0x50FD, 0x8376, 0x50FE, + 0x8377, 0x50FF, 0x8378, 0x5100, 0x8379, 0x5101, 0x837A, 0x5102, + 0x837B, 0x5103, 0x837C, 0x5104, 0x837D, 0x5105, 0x837E, 0x5108, + 0x8380, 0x5109, 0x8381, 0x510A, 0x8382, 0x510C, 0x8383, 0x510D, + 0x8384, 0x510E, 0x8385, 0x510F, 0x8386, 0x5110, 0x8387, 0x5111, + 0x8388, 0x5113, 0x8389, 0x5114, 0x838A, 0x5115, 0x838B, 0x5116, + 0x838C, 0x5117, 0x838D, 0x5118, 0x838E, 0x5119, 0x838F, 0x511A, + 0x8390, 0x511B, 0x8391, 0x511C, 0x8392, 0x511D, 0x8393, 0x511E, + 0x8394, 0x511F, 0x8395, 0x5120, 0x8396, 0x5122, 0x8397, 0x5123, + 0x8398, 0x5124, 0x8399, 0x5125, 0x839A, 0x5126, 0x839B, 0x5127, + 0x839C, 0x5128, 0x839D, 0x5129, 0x839E, 0x512A, 0x839F, 0x512B, + 0x83A0, 0x512C, 0x83A1, 0x512D, 0x83A2, 0x512E, 0x83A3, 0x512F, + 0x83A4, 0x5130, 0x83A5, 0x5131, 0x83A6, 0x5132, 0x83A7, 0x5133, + 0x83A8, 0x5134, 0x83A9, 0x5135, 0x83AA, 0x5136, 0x83AB, 0x5137, + 0x83AC, 0x5138, 0x83AD, 0x5139, 0x83AE, 0x513A, 0x83AF, 0x513B, + 0x83B0, 0x513C, 0x83B1, 0x513D, 0x83B2, 0x513E, 0x83B3, 0x5142, + 0x83B4, 0x5147, 0x83B5, 0x514A, 0x83B6, 0x514C, 0x83B7, 0x514E, + 0x83B8, 0x514F, 0x83B9, 0x5150, 0x83BA, 0x5152, 0x83BB, 0x5153, + 0x83BC, 0x5157, 0x83BD, 0x5158, 0x83BE, 0x5159, 0x83BF, 0x515B, + 0x83C0, 0x515D, 0x83C1, 0x515E, 0x83C2, 0x515F, 0x83C3, 0x5160, + 0x83C4, 0x5161, 0x83C5, 0x5163, 0x83C6, 0x5164, 0x83C7, 0x5166, + 0x83C8, 0x5167, 0x83C9, 0x5169, 0x83CA, 0x516A, 0x83CB, 0x516F, + 0x83CC, 0x5172, 0x83CD, 0x517A, 0x83CE, 0x517E, 0x83CF, 0x517F, + 0x83D0, 0x5183, 0x83D1, 0x5184, 0x83D2, 0x5186, 0x83D3, 0x5187, + 0x83D4, 0x518A, 0x83D5, 0x518B, 0x83D6, 0x518E, 0x83D7, 0x518F, + 0x83D8, 0x5190, 0x83D9, 0x5191, 0x83DA, 0x5193, 0x83DB, 0x5194, + 0x83DC, 0x5198, 0x83DD, 0x519A, 0x83DE, 0x519D, 0x83DF, 0x519E, + 0x83E0, 0x519F, 0x83E1, 0x51A1, 0x83E2, 0x51A3, 0x83E3, 0x51A6, + 0x83E4, 0x51A7, 0x83E5, 0x51A8, 0x83E6, 0x51A9, 0x83E7, 0x51AA, + 0x83E8, 0x51AD, 0x83E9, 0x51AE, 0x83EA, 0x51B4, 0x83EB, 0x51B8, + 0x83EC, 0x51B9, 0x83ED, 0x51BA, 0x83EE, 0x51BE, 0x83EF, 0x51BF, + 0x83F0, 0x51C1, 0x83F1, 0x51C2, 0x83F2, 0x51C3, 0x83F3, 0x51C5, + 0x83F4, 0x51C8, 0x83F5, 0x51CA, 0x83F6, 0x51CD, 0x83F7, 0x51CE, + 0x83F8, 0x51D0, 0x83F9, 0x51D2, 0x83FA, 0x51D3, 0x83FB, 0x51D4, + 0x83FC, 0x51D5, 0x83FD, 0x51D6, 0x83FE, 0x51D7, 0x8440, 0x51D8, + 0x8441, 0x51D9, 0x8442, 0x51DA, 0x8443, 0x51DC, 0x8444, 0x51DE, + 0x8445, 0x51DF, 0x8446, 0x51E2, 0x8447, 0x51E3, 0x8448, 0x51E5, + 0x8449, 0x51E6, 0x844A, 0x51E7, 0x844B, 0x51E8, 0x844C, 0x51E9, + 0x844D, 0x51EA, 0x844E, 0x51EC, 0x844F, 0x51EE, 0x8450, 0x51F1, + 0x8451, 0x51F2, 0x8452, 0x51F4, 0x8453, 0x51F7, 0x8454, 0x51FE, + 0x8455, 0x5204, 0x8456, 0x5205, 0x8457, 0x5209, 0x8458, 0x520B, + 0x8459, 0x520C, 0x845A, 0x520F, 0x845B, 0x5210, 0x845C, 0x5213, + 0x845D, 0x5214, 0x845E, 0x5215, 0x845F, 0x521C, 0x8460, 0x521E, + 0x8461, 0x521F, 0x8462, 0x5221, 0x8463, 0x5222, 0x8464, 0x5223, + 0x8465, 0x5225, 0x8466, 0x5226, 0x8467, 0x5227, 0x8468, 0x522A, + 0x8469, 0x522C, 0x846A, 0x522F, 0x846B, 0x5231, 0x846C, 0x5232, + 0x846D, 0x5234, 0x846E, 0x5235, 0x846F, 0x523C, 0x8470, 0x523E, + 0x8471, 0x5244, 0x8472, 0x5245, 0x8473, 0x5246, 0x8474, 0x5247, + 0x8475, 0x5248, 0x8476, 0x5249, 0x8477, 0x524B, 0x8478, 0x524E, + 0x8479, 0x524F, 0x847A, 0x5252, 0x847B, 0x5253, 0x847C, 0x5255, + 0x847D, 0x5257, 0x847E, 0x5258, 0x8480, 0x5259, 0x8481, 0x525A, + 0x8482, 0x525B, 0x8483, 0x525D, 0x8484, 0x525F, 0x8485, 0x5260, + 0x8486, 0x5262, 0x8487, 0x5263, 0x8488, 0x5264, 0x8489, 0x5266, + 0x848A, 0x5268, 0x848B, 0x526B, 0x848C, 0x526C, 0x848D, 0x526D, + 0x848E, 0x526E, 0x848F, 0x5270, 0x8490, 0x5271, 0x8491, 0x5273, + 0x8492, 0x5274, 0x8493, 0x5275, 0x8494, 0x5276, 0x8495, 0x5277, + 0x8496, 0x5278, 0x8497, 0x5279, 0x8498, 0x527A, 0x8499, 0x527B, + 0x849A, 0x527C, 0x849B, 0x527E, 0x849C, 0x5280, 0x849D, 0x5283, + 0x849E, 0x5284, 0x849F, 0x5285, 0x84A0, 0x5286, 0x84A1, 0x5287, + 0x84A2, 0x5289, 0x84A3, 0x528A, 0x84A4, 0x528B, 0x84A5, 0x528C, + 0x84A6, 0x528D, 0x84A7, 0x528E, 0x84A8, 0x528F, 0x84A9, 0x5291, + 0x84AA, 0x5292, 0x84AB, 0x5294, 0x84AC, 0x5295, 0x84AD, 0x5296, + 0x84AE, 0x5297, 0x84AF, 0x5298, 0x84B0, 0x5299, 0x84B1, 0x529A, + 0x84B2, 0x529C, 0x84B3, 0x52A4, 0x84B4, 0x52A5, 0x84B5, 0x52A6, + 0x84B6, 0x52A7, 0x84B7, 0x52AE, 0x84B8, 0x52AF, 0x84B9, 0x52B0, + 0x84BA, 0x52B4, 0x84BB, 0x52B5, 0x84BC, 0x52B6, 0x84BD, 0x52B7, + 0x84BE, 0x52B8, 0x84BF, 0x52B9, 0x84C0, 0x52BA, 0x84C1, 0x52BB, + 0x84C2, 0x52BC, 0x84C3, 0x52BD, 0x84C4, 0x52C0, 0x84C5, 0x52C1, + 0x84C6, 0x52C2, 0x84C7, 0x52C4, 0x84C8, 0x52C5, 0x84C9, 0x52C6, + 0x84CA, 0x52C8, 0x84CB, 0x52CA, 0x84CC, 0x52CC, 0x84CD, 0x52CD, + 0x84CE, 0x52CE, 0x84CF, 0x52CF, 0x84D0, 0x52D1, 0x84D1, 0x52D3, + 0x84D2, 0x52D4, 0x84D3, 0x52D5, 0x84D4, 0x52D7, 0x84D5, 0x52D9, + 0x84D6, 0x52DA, 0x84D7, 0x52DB, 0x84D8, 0x52DC, 0x84D9, 0x52DD, + 0x84DA, 0x52DE, 0x84DB, 0x52E0, 0x84DC, 0x52E1, 0x84DD, 0x52E2, + 0x84DE, 0x52E3, 0x84DF, 0x52E5, 0x84E0, 0x52E6, 0x84E1, 0x52E7, + 0x84E2, 0x52E8, 0x84E3, 0x52E9, 0x84E4, 0x52EA, 0x84E5, 0x52EB, + 0x84E6, 0x52EC, 0x84E7, 0x52ED, 0x84E8, 0x52EE, 0x84E9, 0x52EF, + 0x84EA, 0x52F1, 0x84EB, 0x52F2, 0x84EC, 0x52F3, 0x84ED, 0x52F4, + 0x84EE, 0x52F5, 0x84EF, 0x52F6, 0x84F0, 0x52F7, 0x84F1, 0x52F8, + 0x84F2, 0x52FB, 0x84F3, 0x52FC, 0x84F4, 0x52FD, 0x84F5, 0x5301, + 0x84F6, 0x5302, 0x84F7, 0x5303, 0x84F8, 0x5304, 0x84F9, 0x5307, + 0x84FA, 0x5309, 0x84FB, 0x530A, 0x84FC, 0x530B, 0x84FD, 0x530C, + 0x84FE, 0x530E, 0x8540, 0x5311, 0x8541, 0x5312, 0x8542, 0x5313, + 0x8543, 0x5314, 0x8544, 0x5318, 0x8545, 0x531B, 0x8546, 0x531C, + 0x8547, 0x531E, 0x8548, 0x531F, 0x8549, 0x5322, 0x854A, 0x5324, + 0x854B, 0x5325, 0x854C, 0x5327, 0x854D, 0x5328, 0x854E, 0x5329, + 0x854F, 0x532B, 0x8550, 0x532C, 0x8551, 0x532D, 0x8552, 0x532F, + 0x8553, 0x5330, 0x8554, 0x5331, 0x8555, 0x5332, 0x8556, 0x5333, + 0x8557, 0x5334, 0x8558, 0x5335, 0x8559, 0x5336, 0x855A, 0x5337, + 0x855B, 0x5338, 0x855C, 0x533C, 0x855D, 0x533D, 0x855E, 0x5340, + 0x855F, 0x5342, 0x8560, 0x5344, 0x8561, 0x5346, 0x8562, 0x534B, + 0x8563, 0x534C, 0x8564, 0x534D, 0x8565, 0x5350, 0x8566, 0x5354, + 0x8567, 0x5358, 0x8568, 0x5359, 0x8569, 0x535B, 0x856A, 0x535D, + 0x856B, 0x5365, 0x856C, 0x5368, 0x856D, 0x536A, 0x856E, 0x536C, + 0x856F, 0x536D, 0x8570, 0x5372, 0x8571, 0x5376, 0x8572, 0x5379, + 0x8573, 0x537B, 0x8574, 0x537C, 0x8575, 0x537D, 0x8576, 0x537E, + 0x8577, 0x5380, 0x8578, 0x5381, 0x8579, 0x5383, 0x857A, 0x5387, + 0x857B, 0x5388, 0x857C, 0x538A, 0x857D, 0x538E, 0x857E, 0x538F, + 0x8580, 0x5390, 0x8581, 0x5391, 0x8582, 0x5392, 0x8583, 0x5393, + 0x8584, 0x5394, 0x8585, 0x5396, 0x8586, 0x5397, 0x8587, 0x5399, + 0x8588, 0x539B, 0x8589, 0x539C, 0x858A, 0x539E, 0x858B, 0x53A0, + 0x858C, 0x53A1, 0x858D, 0x53A4, 0x858E, 0x53A7, 0x858F, 0x53AA, + 0x8590, 0x53AB, 0x8591, 0x53AC, 0x8592, 0x53AD, 0x8593, 0x53AF, + 0x8594, 0x53B0, 0x8595, 0x53B1, 0x8596, 0x53B2, 0x8597, 0x53B3, + 0x8598, 0x53B4, 0x8599, 0x53B5, 0x859A, 0x53B7, 0x859B, 0x53B8, + 0x859C, 0x53B9, 0x859D, 0x53BA, 0x859E, 0x53BC, 0x859F, 0x53BD, + 0x85A0, 0x53BE, 0x85A1, 0x53C0, 0x85A2, 0x53C3, 0x85A3, 0x53C4, + 0x85A4, 0x53C5, 0x85A5, 0x53C6, 0x85A6, 0x53C7, 0x85A7, 0x53CE, + 0x85A8, 0x53CF, 0x85A9, 0x53D0, 0x85AA, 0x53D2, 0x85AB, 0x53D3, + 0x85AC, 0x53D5, 0x85AD, 0x53DA, 0x85AE, 0x53DC, 0x85AF, 0x53DD, + 0x85B0, 0x53DE, 0x85B1, 0x53E1, 0x85B2, 0x53E2, 0x85B3, 0x53E7, + 0x85B4, 0x53F4, 0x85B5, 0x53FA, 0x85B6, 0x53FE, 0x85B7, 0x53FF, + 0x85B8, 0x5400, 0x85B9, 0x5402, 0x85BA, 0x5405, 0x85BB, 0x5407, + 0x85BC, 0x540B, 0x85BD, 0x5414, 0x85BE, 0x5418, 0x85BF, 0x5419, + 0x85C0, 0x541A, 0x85C1, 0x541C, 0x85C2, 0x5422, 0x85C3, 0x5424, + 0x85C4, 0x5425, 0x85C5, 0x542A, 0x85C6, 0x5430, 0x85C7, 0x5433, + 0x85C8, 0x5436, 0x85C9, 0x5437, 0x85CA, 0x543A, 0x85CB, 0x543D, + 0x85CC, 0x543F, 0x85CD, 0x5441, 0x85CE, 0x5442, 0x85CF, 0x5444, + 0x85D0, 0x5445, 0x85D1, 0x5447, 0x85D2, 0x5449, 0x85D3, 0x544C, + 0x85D4, 0x544D, 0x85D5, 0x544E, 0x85D6, 0x544F, 0x85D7, 0x5451, + 0x85D8, 0x545A, 0x85D9, 0x545D, 0x85DA, 0x545E, 0x85DB, 0x545F, + 0x85DC, 0x5460, 0x85DD, 0x5461, 0x85DE, 0x5463, 0x85DF, 0x5465, + 0x85E0, 0x5467, 0x85E1, 0x5469, 0x85E2, 0x546A, 0x85E3, 0x546B, + 0x85E4, 0x546C, 0x85E5, 0x546D, 0x85E6, 0x546E, 0x85E7, 0x546F, + 0x85E8, 0x5470, 0x85E9, 0x5474, 0x85EA, 0x5479, 0x85EB, 0x547A, + 0x85EC, 0x547E, 0x85ED, 0x547F, 0x85EE, 0x5481, 0x85EF, 0x5483, + 0x85F0, 0x5485, 0x85F1, 0x5487, 0x85F2, 0x5488, 0x85F3, 0x5489, + 0x85F4, 0x548A, 0x85F5, 0x548D, 0x85F6, 0x5491, 0x85F7, 0x5493, + 0x85F8, 0x5497, 0x85F9, 0x5498, 0x85FA, 0x549C, 0x85FB, 0x549E, + 0x85FC, 0x549F, 0x85FD, 0x54A0, 0x85FE, 0x54A1, 0x8640, 0x54A2, + 0x8641, 0x54A5, 0x8642, 0x54AE, 0x8643, 0x54B0, 0x8644, 0x54B2, + 0x8645, 0x54B5, 0x8646, 0x54B6, 0x8647, 0x54B7, 0x8648, 0x54B9, + 0x8649, 0x54BA, 0x864A, 0x54BC, 0x864B, 0x54BE, 0x864C, 0x54C3, + 0x864D, 0x54C5, 0x864E, 0x54CA, 0x864F, 0x54CB, 0x8650, 0x54D6, + 0x8651, 0x54D8, 0x8652, 0x54DB, 0x8653, 0x54E0, 0x8654, 0x54E1, + 0x8655, 0x54E2, 0x8656, 0x54E3, 0x8657, 0x54E4, 0x8658, 0x54EB, + 0x8659, 0x54EC, 0x865A, 0x54EF, 0x865B, 0x54F0, 0x865C, 0x54F1, + 0x865D, 0x54F4, 0x865E, 0x54F5, 0x865F, 0x54F6, 0x8660, 0x54F7, + 0x8661, 0x54F8, 0x8662, 0x54F9, 0x8663, 0x54FB, 0x8664, 0x54FE, + 0x8665, 0x5500, 0x8666, 0x5502, 0x8667, 0x5503, 0x8668, 0x5504, + 0x8669, 0x5505, 0x866A, 0x5508, 0x866B, 0x550A, 0x866C, 0x550B, + 0x866D, 0x550C, 0x866E, 0x550D, 0x866F, 0x550E, 0x8670, 0x5512, + 0x8671, 0x5513, 0x8672, 0x5515, 0x8673, 0x5516, 0x8674, 0x5517, + 0x8675, 0x5518, 0x8676, 0x5519, 0x8677, 0x551A, 0x8678, 0x551C, + 0x8679, 0x551D, 0x867A, 0x551E, 0x867B, 0x551F, 0x867C, 0x5521, + 0x867D, 0x5525, 0x867E, 0x5526, 0x8680, 0x5528, 0x8681, 0x5529, + 0x8682, 0x552B, 0x8683, 0x552D, 0x8684, 0x5532, 0x8685, 0x5534, + 0x8686, 0x5535, 0x8687, 0x5536, 0x8688, 0x5538, 0x8689, 0x5539, + 0x868A, 0x553A, 0x868B, 0x553B, 0x868C, 0x553D, 0x868D, 0x5540, + 0x868E, 0x5542, 0x868F, 0x5545, 0x8690, 0x5547, 0x8691, 0x5548, + 0x8692, 0x554B, 0x8693, 0x554C, 0x8694, 0x554D, 0x8695, 0x554E, + 0x8696, 0x554F, 0x8697, 0x5551, 0x8698, 0x5552, 0x8699, 0x5553, + 0x869A, 0x5554, 0x869B, 0x5557, 0x869C, 0x5558, 0x869D, 0x5559, + 0x869E, 0x555A, 0x869F, 0x555B, 0x86A0, 0x555D, 0x86A1, 0x555E, + 0x86A2, 0x555F, 0x86A3, 0x5560, 0x86A4, 0x5562, 0x86A5, 0x5563, + 0x86A6, 0x5568, 0x86A7, 0x5569, 0x86A8, 0x556B, 0x86A9, 0x556F, + 0x86AA, 0x5570, 0x86AB, 0x5571, 0x86AC, 0x5572, 0x86AD, 0x5573, + 0x86AE, 0x5574, 0x86AF, 0x5579, 0x86B0, 0x557A, 0x86B1, 0x557D, + 0x86B2, 0x557F, 0x86B3, 0x5585, 0x86B4, 0x5586, 0x86B5, 0x558C, + 0x86B6, 0x558D, 0x86B7, 0x558E, 0x86B8, 0x5590, 0x86B9, 0x5592, + 0x86BA, 0x5593, 0x86BB, 0x5595, 0x86BC, 0x5596, 0x86BD, 0x5597, + 0x86BE, 0x559A, 0x86BF, 0x559B, 0x86C0, 0x559E, 0x86C1, 0x55A0, + 0x86C2, 0x55A1, 0x86C3, 0x55A2, 0x86C4, 0x55A3, 0x86C5, 0x55A4, + 0x86C6, 0x55A5, 0x86C7, 0x55A6, 0x86C8, 0x55A8, 0x86C9, 0x55A9, + 0x86CA, 0x55AA, 0x86CB, 0x55AB, 0x86CC, 0x55AC, 0x86CD, 0x55AD, + 0x86CE, 0x55AE, 0x86CF, 0x55AF, 0x86D0, 0x55B0, 0x86D1, 0x55B2, + 0x86D2, 0x55B4, 0x86D3, 0x55B6, 0x86D4, 0x55B8, 0x86D5, 0x55BA, + 0x86D6, 0x55BC, 0x86D7, 0x55BF, 0x86D8, 0x55C0, 0x86D9, 0x55C1, + 0x86DA, 0x55C2, 0x86DB, 0x55C3, 0x86DC, 0x55C6, 0x86DD, 0x55C7, + 0x86DE, 0x55C8, 0x86DF, 0x55CA, 0x86E0, 0x55CB, 0x86E1, 0x55CE, + 0x86E2, 0x55CF, 0x86E3, 0x55D0, 0x86E4, 0x55D5, 0x86E5, 0x55D7, + 0x86E6, 0x55D8, 0x86E7, 0x55D9, 0x86E8, 0x55DA, 0x86E9, 0x55DB, + 0x86EA, 0x55DE, 0x86EB, 0x55E0, 0x86EC, 0x55E2, 0x86ED, 0x55E7, + 0x86EE, 0x55E9, 0x86EF, 0x55ED, 0x86F0, 0x55EE, 0x86F1, 0x55F0, + 0x86F2, 0x55F1, 0x86F3, 0x55F4, 0x86F4, 0x55F6, 0x86F5, 0x55F8, + 0x86F6, 0x55F9, 0x86F7, 0x55FA, 0x86F8, 0x55FB, 0x86F9, 0x55FC, + 0x86FA, 0x55FF, 0x86FB, 0x5602, 0x86FC, 0x5603, 0x86FD, 0x5604, + 0x86FE, 0x5605, 0x8740, 0x5606, 0x8741, 0x5607, 0x8742, 0x560A, + 0x8743, 0x560B, 0x8744, 0x560D, 0x8745, 0x5610, 0x8746, 0x5611, + 0x8747, 0x5612, 0x8748, 0x5613, 0x8749, 0x5614, 0x874A, 0x5615, + 0x874B, 0x5616, 0x874C, 0x5617, 0x874D, 0x5619, 0x874E, 0x561A, + 0x874F, 0x561C, 0x8750, 0x561D, 0x8751, 0x5620, 0x8752, 0x5621, + 0x8753, 0x5622, 0x8754, 0x5625, 0x8755, 0x5626, 0x8756, 0x5628, + 0x8757, 0x5629, 0x8758, 0x562A, 0x8759, 0x562B, 0x875A, 0x562E, + 0x875B, 0x562F, 0x875C, 0x5630, 0x875D, 0x5633, 0x875E, 0x5635, + 0x875F, 0x5637, 0x8760, 0x5638, 0x8761, 0x563A, 0x8762, 0x563C, + 0x8763, 0x563D, 0x8764, 0x563E, 0x8765, 0x5640, 0x8766, 0x5641, + 0x8767, 0x5642, 0x8768, 0x5643, 0x8769, 0x5644, 0x876A, 0x5645, + 0x876B, 0x5646, 0x876C, 0x5647, 0x876D, 0x5648, 0x876E, 0x5649, + 0x876F, 0x564A, 0x8770, 0x564B, 0x8771, 0x564F, 0x8772, 0x5650, + 0x8773, 0x5651, 0x8774, 0x5652, 0x8775, 0x5653, 0x8776, 0x5655, + 0x8777, 0x5656, 0x8778, 0x565A, 0x8779, 0x565B, 0x877A, 0x565D, + 0x877B, 0x565E, 0x877C, 0x565F, 0x877D, 0x5660, 0x877E, 0x5661, + 0x8780, 0x5663, 0x8781, 0x5665, 0x8782, 0x5666, 0x8783, 0x5667, + 0x8784, 0x566D, 0x8785, 0x566E, 0x8786, 0x566F, 0x8787, 0x5670, + 0x8788, 0x5672, 0x8789, 0x5673, 0x878A, 0x5674, 0x878B, 0x5675, + 0x878C, 0x5677, 0x878D, 0x5678, 0x878E, 0x5679, 0x878F, 0x567A, + 0x8790, 0x567D, 0x8791, 0x567E, 0x8792, 0x567F, 0x8793, 0x5680, + 0x8794, 0x5681, 0x8795, 0x5682, 0x8796, 0x5683, 0x8797, 0x5684, + 0x8798, 0x5687, 0x8799, 0x5688, 0x879A, 0x5689, 0x879B, 0x568A, + 0x879C, 0x568B, 0x879D, 0x568C, 0x879E, 0x568D, 0x879F, 0x5690, + 0x87A0, 0x5691, 0x87A1, 0x5692, 0x87A2, 0x5694, 0x87A3, 0x5695, + 0x87A4, 0x5696, 0x87A5, 0x5697, 0x87A6, 0x5698, 0x87A7, 0x5699, + 0x87A8, 0x569A, 0x87A9, 0x569B, 0x87AA, 0x569C, 0x87AB, 0x569D, + 0x87AC, 0x569E, 0x87AD, 0x569F, 0x87AE, 0x56A0, 0x87AF, 0x56A1, + 0x87B0, 0x56A2, 0x87B1, 0x56A4, 0x87B2, 0x56A5, 0x87B3, 0x56A6, + 0x87B4, 0x56A7, 0x87B5, 0x56A8, 0x87B6, 0x56A9, 0x87B7, 0x56AA, + 0x87B8, 0x56AB, 0x87B9, 0x56AC, 0x87BA, 0x56AD, 0x87BB, 0x56AE, + 0x87BC, 0x56B0, 0x87BD, 0x56B1, 0x87BE, 0x56B2, 0x87BF, 0x56B3, + 0x87C0, 0x56B4, 0x87C1, 0x56B5, 0x87C2, 0x56B6, 0x87C3, 0x56B8, + 0x87C4, 0x56B9, 0x87C5, 0x56BA, 0x87C6, 0x56BB, 0x87C7, 0x56BD, + 0x87C8, 0x56BE, 0x87C9, 0x56BF, 0x87CA, 0x56C0, 0x87CB, 0x56C1, + 0x87CC, 0x56C2, 0x87CD, 0x56C3, 0x87CE, 0x56C4, 0x87CF, 0x56C5, + 0x87D0, 0x56C6, 0x87D1, 0x56C7, 0x87D2, 0x56C8, 0x87D3, 0x56C9, + 0x87D4, 0x56CB, 0x87D5, 0x56CC, 0x87D6, 0x56CD, 0x87D7, 0x56CE, + 0x87D8, 0x56CF, 0x87D9, 0x56D0, 0x87DA, 0x56D1, 0x87DB, 0x56D2, + 0x87DC, 0x56D3, 0x87DD, 0x56D5, 0x87DE, 0x56D6, 0x87DF, 0x56D8, + 0x87E0, 0x56D9, 0x87E1, 0x56DC, 0x87E2, 0x56E3, 0x87E3, 0x56E5, + 0x87E4, 0x56E6, 0x87E5, 0x56E7, 0x87E6, 0x56E8, 0x87E7, 0x56E9, + 0x87E8, 0x56EA, 0x87E9, 0x56EC, 0x87EA, 0x56EE, 0x87EB, 0x56EF, + 0x87EC, 0x56F2, 0x87ED, 0x56F3, 0x87EE, 0x56F6, 0x87EF, 0x56F7, + 0x87F0, 0x56F8, 0x87F1, 0x56FB, 0x87F2, 0x56FC, 0x87F3, 0x5700, + 0x87F4, 0x5701, 0x87F5, 0x5702, 0x87F6, 0x5705, 0x87F7, 0x5707, + 0x87F8, 0x570B, 0x87F9, 0x570C, 0x87FA, 0x570D, 0x87FB, 0x570E, + 0x87FC, 0x570F, 0x87FD, 0x5710, 0x87FE, 0x5711, 0x8840, 0x5712, + 0x8841, 0x5713, 0x8842, 0x5714, 0x8843, 0x5715, 0x8844, 0x5716, + 0x8845, 0x5717, 0x8846, 0x5718, 0x8847, 0x5719, 0x8848, 0x571A, + 0x8849, 0x571B, 0x884A, 0x571D, 0x884B, 0x571E, 0x884C, 0x5720, + 0x884D, 0x5721, 0x884E, 0x5722, 0x884F, 0x5724, 0x8850, 0x5725, + 0x8851, 0x5726, 0x8852, 0x5727, 0x8853, 0x572B, 0x8854, 0x5731, + 0x8855, 0x5732, 0x8856, 0x5734, 0x8857, 0x5735, 0x8858, 0x5736, + 0x8859, 0x5737, 0x885A, 0x5738, 0x885B, 0x573C, 0x885C, 0x573D, + 0x885D, 0x573F, 0x885E, 0x5741, 0x885F, 0x5743, 0x8860, 0x5744, + 0x8861, 0x5745, 0x8862, 0x5746, 0x8863, 0x5748, 0x8864, 0x5749, + 0x8865, 0x574B, 0x8866, 0x5752, 0x8867, 0x5753, 0x8868, 0x5754, + 0x8869, 0x5755, 0x886A, 0x5756, 0x886B, 0x5758, 0x886C, 0x5759, + 0x886D, 0x5762, 0x886E, 0x5763, 0x886F, 0x5765, 0x8870, 0x5767, + 0x8871, 0x576C, 0x8872, 0x576E, 0x8873, 0x5770, 0x8874, 0x5771, + 0x8875, 0x5772, 0x8876, 0x5774, 0x8877, 0x5775, 0x8878, 0x5778, + 0x8879, 0x5779, 0x887A, 0x577A, 0x887B, 0x577D, 0x887C, 0x577E, + 0x887D, 0x577F, 0x887E, 0x5780, 0x8880, 0x5781, 0x8881, 0x5787, + 0x8882, 0x5788, 0x8883, 0x5789, 0x8884, 0x578A, 0x8885, 0x578D, + 0x8886, 0x578E, 0x8887, 0x578F, 0x8888, 0x5790, 0x8889, 0x5791, + 0x888A, 0x5794, 0x888B, 0x5795, 0x888C, 0x5796, 0x888D, 0x5797, + 0x888E, 0x5798, 0x888F, 0x5799, 0x8890, 0x579A, 0x8891, 0x579C, + 0x8892, 0x579D, 0x8893, 0x579E, 0x8894, 0x579F, 0x8895, 0x57A5, + 0x8896, 0x57A8, 0x8897, 0x57AA, 0x8898, 0x57AC, 0x8899, 0x57AF, + 0x889A, 0x57B0, 0x889B, 0x57B1, 0x889C, 0x57B3, 0x889D, 0x57B5, + 0x889E, 0x57B6, 0x889F, 0x57B7, 0x88A0, 0x57B9, 0x88A1, 0x57BA, + 0x88A2, 0x57BB, 0x88A3, 0x57BC, 0x88A4, 0x57BD, 0x88A5, 0x57BE, + 0x88A6, 0x57BF, 0x88A7, 0x57C0, 0x88A8, 0x57C1, 0x88A9, 0x57C4, + 0x88AA, 0x57C5, 0x88AB, 0x57C6, 0x88AC, 0x57C7, 0x88AD, 0x57C8, + 0x88AE, 0x57C9, 0x88AF, 0x57CA, 0x88B0, 0x57CC, 0x88B1, 0x57CD, + 0x88B2, 0x57D0, 0x88B3, 0x57D1, 0x88B4, 0x57D3, 0x88B5, 0x57D6, + 0x88B6, 0x57D7, 0x88B7, 0x57DB, 0x88B8, 0x57DC, 0x88B9, 0x57DE, + 0x88BA, 0x57E1, 0x88BB, 0x57E2, 0x88BC, 0x57E3, 0x88BD, 0x57E5, + 0x88BE, 0x57E6, 0x88BF, 0x57E7, 0x88C0, 0x57E8, 0x88C1, 0x57E9, + 0x88C2, 0x57EA, 0x88C3, 0x57EB, 0x88C4, 0x57EC, 0x88C5, 0x57EE, + 0x88C6, 0x57F0, 0x88C7, 0x57F1, 0x88C8, 0x57F2, 0x88C9, 0x57F3, + 0x88CA, 0x57F5, 0x88CB, 0x57F6, 0x88CC, 0x57F7, 0x88CD, 0x57FB, + 0x88CE, 0x57FC, 0x88CF, 0x57FE, 0x88D0, 0x57FF, 0x88D1, 0x5801, + 0x88D2, 0x5803, 0x88D3, 0x5804, 0x88D4, 0x5805, 0x88D5, 0x5808, + 0x88D6, 0x5809, 0x88D7, 0x580A, 0x88D8, 0x580C, 0x88D9, 0x580E, + 0x88DA, 0x580F, 0x88DB, 0x5810, 0x88DC, 0x5812, 0x88DD, 0x5813, + 0x88DE, 0x5814, 0x88DF, 0x5816, 0x88E0, 0x5817, 0x88E1, 0x5818, + 0x88E2, 0x581A, 0x88E3, 0x581B, 0x88E4, 0x581C, 0x88E5, 0x581D, + 0x88E6, 0x581F, 0x88E7, 0x5822, 0x88E8, 0x5823, 0x88E9, 0x5825, + 0x88EA, 0x5826, 0x88EB, 0x5827, 0x88EC, 0x5828, 0x88ED, 0x5829, + 0x88EE, 0x582B, 0x88EF, 0x582C, 0x88F0, 0x582D, 0x88F1, 0x582E, + 0x88F2, 0x582F, 0x88F3, 0x5831, 0x88F4, 0x5832, 0x88F5, 0x5833, + 0x88F6, 0x5834, 0x88F7, 0x5836, 0x88F8, 0x5837, 0x88F9, 0x5838, + 0x88FA, 0x5839, 0x88FB, 0x583A, 0x88FC, 0x583B, 0x88FD, 0x583C, + 0x88FE, 0x583D, 0x8940, 0x583E, 0x8941, 0x583F, 0x8942, 0x5840, + 0x8943, 0x5841, 0x8944, 0x5842, 0x8945, 0x5843, 0x8946, 0x5845, + 0x8947, 0x5846, 0x8948, 0x5847, 0x8949, 0x5848, 0x894A, 0x5849, + 0x894B, 0x584A, 0x894C, 0x584B, 0x894D, 0x584E, 0x894E, 0x584F, + 0x894F, 0x5850, 0x8950, 0x5852, 0x8951, 0x5853, 0x8952, 0x5855, + 0x8953, 0x5856, 0x8954, 0x5857, 0x8955, 0x5859, 0x8956, 0x585A, + 0x8957, 0x585B, 0x8958, 0x585C, 0x8959, 0x585D, 0x895A, 0x585F, + 0x895B, 0x5860, 0x895C, 0x5861, 0x895D, 0x5862, 0x895E, 0x5863, + 0x895F, 0x5864, 0x8960, 0x5866, 0x8961, 0x5867, 0x8962, 0x5868, + 0x8963, 0x5869, 0x8964, 0x586A, 0x8965, 0x586D, 0x8966, 0x586E, + 0x8967, 0x586F, 0x8968, 0x5870, 0x8969, 0x5871, 0x896A, 0x5872, + 0x896B, 0x5873, 0x896C, 0x5874, 0x896D, 0x5875, 0x896E, 0x5876, + 0x896F, 0x5877, 0x8970, 0x5878, 0x8971, 0x5879, 0x8972, 0x587A, + 0x8973, 0x587B, 0x8974, 0x587C, 0x8975, 0x587D, 0x8976, 0x587F, + 0x8977, 0x5882, 0x8978, 0x5884, 0x8979, 0x5886, 0x897A, 0x5887, + 0x897B, 0x5888, 0x897C, 0x588A, 0x897D, 0x588B, 0x897E, 0x588C, + 0x8980, 0x588D, 0x8981, 0x588E, 0x8982, 0x588F, 0x8983, 0x5890, + 0x8984, 0x5891, 0x8985, 0x5894, 0x8986, 0x5895, 0x8987, 0x5896, + 0x8988, 0x5897, 0x8989, 0x5898, 0x898A, 0x589B, 0x898B, 0x589C, + 0x898C, 0x589D, 0x898D, 0x58A0, 0x898E, 0x58A1, 0x898F, 0x58A2, + 0x8990, 0x58A3, 0x8991, 0x58A4, 0x8992, 0x58A5, 0x8993, 0x58A6, + 0x8994, 0x58A7, 0x8995, 0x58AA, 0x8996, 0x58AB, 0x8997, 0x58AC, + 0x8998, 0x58AD, 0x8999, 0x58AE, 0x899A, 0x58AF, 0x899B, 0x58B0, + 0x899C, 0x58B1, 0x899D, 0x58B2, 0x899E, 0x58B3, 0x899F, 0x58B4, + 0x89A0, 0x58B5, 0x89A1, 0x58B6, 0x89A2, 0x58B7, 0x89A3, 0x58B8, + 0x89A4, 0x58B9, 0x89A5, 0x58BA, 0x89A6, 0x58BB, 0x89A7, 0x58BD, + 0x89A8, 0x58BE, 0x89A9, 0x58BF, 0x89AA, 0x58C0, 0x89AB, 0x58C2, + 0x89AC, 0x58C3, 0x89AD, 0x58C4, 0x89AE, 0x58C6, 0x89AF, 0x58C7, + 0x89B0, 0x58C8, 0x89B1, 0x58C9, 0x89B2, 0x58CA, 0x89B3, 0x58CB, + 0x89B4, 0x58CC, 0x89B5, 0x58CD, 0x89B6, 0x58CE, 0x89B7, 0x58CF, + 0x89B8, 0x58D0, 0x89B9, 0x58D2, 0x89BA, 0x58D3, 0x89BB, 0x58D4, + 0x89BC, 0x58D6, 0x89BD, 0x58D7, 0x89BE, 0x58D8, 0x89BF, 0x58D9, + 0x89C0, 0x58DA, 0x89C1, 0x58DB, 0x89C2, 0x58DC, 0x89C3, 0x58DD, + 0x89C4, 0x58DE, 0x89C5, 0x58DF, 0x89C6, 0x58E0, 0x89C7, 0x58E1, + 0x89C8, 0x58E2, 0x89C9, 0x58E3, 0x89CA, 0x58E5, 0x89CB, 0x58E6, + 0x89CC, 0x58E7, 0x89CD, 0x58E8, 0x89CE, 0x58E9, 0x89CF, 0x58EA, + 0x89D0, 0x58ED, 0x89D1, 0x58EF, 0x89D2, 0x58F1, 0x89D3, 0x58F2, + 0x89D4, 0x58F4, 0x89D5, 0x58F5, 0x89D6, 0x58F7, 0x89D7, 0x58F8, + 0x89D8, 0x58FA, 0x89D9, 0x58FB, 0x89DA, 0x58FC, 0x89DB, 0x58FD, + 0x89DC, 0x58FE, 0x89DD, 0x58FF, 0x89DE, 0x5900, 0x89DF, 0x5901, + 0x89E0, 0x5903, 0x89E1, 0x5905, 0x89E2, 0x5906, 0x89E3, 0x5908, + 0x89E4, 0x5909, 0x89E5, 0x590A, 0x89E6, 0x590B, 0x89E7, 0x590C, + 0x89E8, 0x590E, 0x89E9, 0x5910, 0x89EA, 0x5911, 0x89EB, 0x5912, + 0x89EC, 0x5913, 0x89ED, 0x5917, 0x89EE, 0x5918, 0x89EF, 0x591B, + 0x89F0, 0x591D, 0x89F1, 0x591E, 0x89F2, 0x5920, 0x89F3, 0x5921, + 0x89F4, 0x5922, 0x89F5, 0x5923, 0x89F6, 0x5926, 0x89F7, 0x5928, + 0x89F8, 0x592C, 0x89F9, 0x5930, 0x89FA, 0x5932, 0x89FB, 0x5933, + 0x89FC, 0x5935, 0x89FD, 0x5936, 0x89FE, 0x593B, 0x8A40, 0x593D, + 0x8A41, 0x593E, 0x8A42, 0x593F, 0x8A43, 0x5940, 0x8A44, 0x5943, + 0x8A45, 0x5945, 0x8A46, 0x5946, 0x8A47, 0x594A, 0x8A48, 0x594C, + 0x8A49, 0x594D, 0x8A4A, 0x5950, 0x8A4B, 0x5952, 0x8A4C, 0x5953, + 0x8A4D, 0x5959, 0x8A4E, 0x595B, 0x8A4F, 0x595C, 0x8A50, 0x595D, + 0x8A51, 0x595E, 0x8A52, 0x595F, 0x8A53, 0x5961, 0x8A54, 0x5963, + 0x8A55, 0x5964, 0x8A56, 0x5966, 0x8A57, 0x5967, 0x8A58, 0x5968, + 0x8A59, 0x5969, 0x8A5A, 0x596A, 0x8A5B, 0x596B, 0x8A5C, 0x596C, + 0x8A5D, 0x596D, 0x8A5E, 0x596E, 0x8A5F, 0x596F, 0x8A60, 0x5970, + 0x8A61, 0x5971, 0x8A62, 0x5972, 0x8A63, 0x5975, 0x8A64, 0x5977, + 0x8A65, 0x597A, 0x8A66, 0x597B, 0x8A67, 0x597C, 0x8A68, 0x597E, + 0x8A69, 0x597F, 0x8A6A, 0x5980, 0x8A6B, 0x5985, 0x8A6C, 0x5989, + 0x8A6D, 0x598B, 0x8A6E, 0x598C, 0x8A6F, 0x598E, 0x8A70, 0x598F, + 0x8A71, 0x5990, 0x8A72, 0x5991, 0x8A73, 0x5994, 0x8A74, 0x5995, + 0x8A75, 0x5998, 0x8A76, 0x599A, 0x8A77, 0x599B, 0x8A78, 0x599C, + 0x8A79, 0x599D, 0x8A7A, 0x599F, 0x8A7B, 0x59A0, 0x8A7C, 0x59A1, + 0x8A7D, 0x59A2, 0x8A7E, 0x59A6, 0x8A80, 0x59A7, 0x8A81, 0x59AC, + 0x8A82, 0x59AD, 0x8A83, 0x59B0, 0x8A84, 0x59B1, 0x8A85, 0x59B3, + 0x8A86, 0x59B4, 0x8A87, 0x59B5, 0x8A88, 0x59B6, 0x8A89, 0x59B7, + 0x8A8A, 0x59B8, 0x8A8B, 0x59BA, 0x8A8C, 0x59BC, 0x8A8D, 0x59BD, + 0x8A8E, 0x59BF, 0x8A8F, 0x59C0, 0x8A90, 0x59C1, 0x8A91, 0x59C2, + 0x8A92, 0x59C3, 0x8A93, 0x59C4, 0x8A94, 0x59C5, 0x8A95, 0x59C7, + 0x8A96, 0x59C8, 0x8A97, 0x59C9, 0x8A98, 0x59CC, 0x8A99, 0x59CD, + 0x8A9A, 0x59CE, 0x8A9B, 0x59CF, 0x8A9C, 0x59D5, 0x8A9D, 0x59D6, + 0x8A9E, 0x59D9, 0x8A9F, 0x59DB, 0x8AA0, 0x59DE, 0x8AA1, 0x59DF, + 0x8AA2, 0x59E0, 0x8AA3, 0x59E1, 0x8AA4, 0x59E2, 0x8AA5, 0x59E4, + 0x8AA6, 0x59E6, 0x8AA7, 0x59E7, 0x8AA8, 0x59E9, 0x8AA9, 0x59EA, + 0x8AAA, 0x59EB, 0x8AAB, 0x59ED, 0x8AAC, 0x59EE, 0x8AAD, 0x59EF, + 0x8AAE, 0x59F0, 0x8AAF, 0x59F1, 0x8AB0, 0x59F2, 0x8AB1, 0x59F3, + 0x8AB2, 0x59F4, 0x8AB3, 0x59F5, 0x8AB4, 0x59F6, 0x8AB5, 0x59F7, + 0x8AB6, 0x59F8, 0x8AB7, 0x59FA, 0x8AB8, 0x59FC, 0x8AB9, 0x59FD, + 0x8ABA, 0x59FE, 0x8ABB, 0x5A00, 0x8ABC, 0x5A02, 0x8ABD, 0x5A0A, + 0x8ABE, 0x5A0B, 0x8ABF, 0x5A0D, 0x8AC0, 0x5A0E, 0x8AC1, 0x5A0F, + 0x8AC2, 0x5A10, 0x8AC3, 0x5A12, 0x8AC4, 0x5A14, 0x8AC5, 0x5A15, + 0x8AC6, 0x5A16, 0x8AC7, 0x5A17, 0x8AC8, 0x5A19, 0x8AC9, 0x5A1A, + 0x8ACA, 0x5A1B, 0x8ACB, 0x5A1D, 0x8ACC, 0x5A1E, 0x8ACD, 0x5A21, + 0x8ACE, 0x5A22, 0x8ACF, 0x5A24, 0x8AD0, 0x5A26, 0x8AD1, 0x5A27, + 0x8AD2, 0x5A28, 0x8AD3, 0x5A2A, 0x8AD4, 0x5A2B, 0x8AD5, 0x5A2C, + 0x8AD6, 0x5A2D, 0x8AD7, 0x5A2E, 0x8AD8, 0x5A2F, 0x8AD9, 0x5A30, + 0x8ADA, 0x5A33, 0x8ADB, 0x5A35, 0x8ADC, 0x5A37, 0x8ADD, 0x5A38, + 0x8ADE, 0x5A39, 0x8ADF, 0x5A3A, 0x8AE0, 0x5A3B, 0x8AE1, 0x5A3D, + 0x8AE2, 0x5A3E, 0x8AE3, 0x5A3F, 0x8AE4, 0x5A41, 0x8AE5, 0x5A42, + 0x8AE6, 0x5A43, 0x8AE7, 0x5A44, 0x8AE8, 0x5A45, 0x8AE9, 0x5A47, + 0x8AEA, 0x5A48, 0x8AEB, 0x5A4B, 0x8AEC, 0x5A4C, 0x8AED, 0x5A4D, + 0x8AEE, 0x5A4E, 0x8AEF, 0x5A4F, 0x8AF0, 0x5A50, 0x8AF1, 0x5A51, + 0x8AF2, 0x5A52, 0x8AF3, 0x5A53, 0x8AF4, 0x5A54, 0x8AF5, 0x5A56, + 0x8AF6, 0x5A57, 0x8AF7, 0x5A58, 0x8AF8, 0x5A59, 0x8AF9, 0x5A5B, + 0x8AFA, 0x5A5C, 0x8AFB, 0x5A5D, 0x8AFC, 0x5A5E, 0x8AFD, 0x5A5F, + 0x8AFE, 0x5A60, 0x8B40, 0x5A61, 0x8B41, 0x5A63, 0x8B42, 0x5A64, + 0x8B43, 0x5A65, 0x8B44, 0x5A66, 0x8B45, 0x5A68, 0x8B46, 0x5A69, + 0x8B47, 0x5A6B, 0x8B48, 0x5A6C, 0x8B49, 0x5A6D, 0x8B4A, 0x5A6E, + 0x8B4B, 0x5A6F, 0x8B4C, 0x5A70, 0x8B4D, 0x5A71, 0x8B4E, 0x5A72, + 0x8B4F, 0x5A73, 0x8B50, 0x5A78, 0x8B51, 0x5A79, 0x8B52, 0x5A7B, + 0x8B53, 0x5A7C, 0x8B54, 0x5A7D, 0x8B55, 0x5A7E, 0x8B56, 0x5A80, + 0x8B57, 0x5A81, 0x8B58, 0x5A82, 0x8B59, 0x5A83, 0x8B5A, 0x5A84, + 0x8B5B, 0x5A85, 0x8B5C, 0x5A86, 0x8B5D, 0x5A87, 0x8B5E, 0x5A88, + 0x8B5F, 0x5A89, 0x8B60, 0x5A8A, 0x8B61, 0x5A8B, 0x8B62, 0x5A8C, + 0x8B63, 0x5A8D, 0x8B64, 0x5A8E, 0x8B65, 0x5A8F, 0x8B66, 0x5A90, + 0x8B67, 0x5A91, 0x8B68, 0x5A93, 0x8B69, 0x5A94, 0x8B6A, 0x5A95, + 0x8B6B, 0x5A96, 0x8B6C, 0x5A97, 0x8B6D, 0x5A98, 0x8B6E, 0x5A99, + 0x8B6F, 0x5A9C, 0x8B70, 0x5A9D, 0x8B71, 0x5A9E, 0x8B72, 0x5A9F, + 0x8B73, 0x5AA0, 0x8B74, 0x5AA1, 0x8B75, 0x5AA2, 0x8B76, 0x5AA3, + 0x8B77, 0x5AA4, 0x8B78, 0x5AA5, 0x8B79, 0x5AA6, 0x8B7A, 0x5AA7, + 0x8B7B, 0x5AA8, 0x8B7C, 0x5AA9, 0x8B7D, 0x5AAB, 0x8B7E, 0x5AAC, + 0x8B80, 0x5AAD, 0x8B81, 0x5AAE, 0x8B82, 0x5AAF, 0x8B83, 0x5AB0, + 0x8B84, 0x5AB1, 0x8B85, 0x5AB4, 0x8B86, 0x5AB6, 0x8B87, 0x5AB7, + 0x8B88, 0x5AB9, 0x8B89, 0x5ABA, 0x8B8A, 0x5ABB, 0x8B8B, 0x5ABC, + 0x8B8C, 0x5ABD, 0x8B8D, 0x5ABF, 0x8B8E, 0x5AC0, 0x8B8F, 0x5AC3, + 0x8B90, 0x5AC4, 0x8B91, 0x5AC5, 0x8B92, 0x5AC6, 0x8B93, 0x5AC7, + 0x8B94, 0x5AC8, 0x8B95, 0x5ACA, 0x8B96, 0x5ACB, 0x8B97, 0x5ACD, + 0x8B98, 0x5ACE, 0x8B99, 0x5ACF, 0x8B9A, 0x5AD0, 0x8B9B, 0x5AD1, + 0x8B9C, 0x5AD3, 0x8B9D, 0x5AD5, 0x8B9E, 0x5AD7, 0x8B9F, 0x5AD9, + 0x8BA0, 0x5ADA, 0x8BA1, 0x5ADB, 0x8BA2, 0x5ADD, 0x8BA3, 0x5ADE, + 0x8BA4, 0x5ADF, 0x8BA5, 0x5AE2, 0x8BA6, 0x5AE4, 0x8BA7, 0x5AE5, + 0x8BA8, 0x5AE7, 0x8BA9, 0x5AE8, 0x8BAA, 0x5AEA, 0x8BAB, 0x5AEC, + 0x8BAC, 0x5AED, 0x8BAD, 0x5AEE, 0x8BAE, 0x5AEF, 0x8BAF, 0x5AF0, + 0x8BB0, 0x5AF2, 0x8BB1, 0x5AF3, 0x8BB2, 0x5AF4, 0x8BB3, 0x5AF5, + 0x8BB4, 0x5AF6, 0x8BB5, 0x5AF7, 0x8BB6, 0x5AF8, 0x8BB7, 0x5AF9, + 0x8BB8, 0x5AFA, 0x8BB9, 0x5AFB, 0x8BBA, 0x5AFC, 0x8BBB, 0x5AFD, + 0x8BBC, 0x5AFE, 0x8BBD, 0x5AFF, 0x8BBE, 0x5B00, 0x8BBF, 0x5B01, + 0x8BC0, 0x5B02, 0x8BC1, 0x5B03, 0x8BC2, 0x5B04, 0x8BC3, 0x5B05, + 0x8BC4, 0x5B06, 0x8BC5, 0x5B07, 0x8BC6, 0x5B08, 0x8BC7, 0x5B0A, + 0x8BC8, 0x5B0B, 0x8BC9, 0x5B0C, 0x8BCA, 0x5B0D, 0x8BCB, 0x5B0E, + 0x8BCC, 0x5B0F, 0x8BCD, 0x5B10, 0x8BCE, 0x5B11, 0x8BCF, 0x5B12, + 0x8BD0, 0x5B13, 0x8BD1, 0x5B14, 0x8BD2, 0x5B15, 0x8BD3, 0x5B18, + 0x8BD4, 0x5B19, 0x8BD5, 0x5B1A, 0x8BD6, 0x5B1B, 0x8BD7, 0x5B1C, + 0x8BD8, 0x5B1D, 0x8BD9, 0x5B1E, 0x8BDA, 0x5B1F, 0x8BDB, 0x5B20, + 0x8BDC, 0x5B21, 0x8BDD, 0x5B22, 0x8BDE, 0x5B23, 0x8BDF, 0x5B24, + 0x8BE0, 0x5B25, 0x8BE1, 0x5B26, 0x8BE2, 0x5B27, 0x8BE3, 0x5B28, + 0x8BE4, 0x5B29, 0x8BE5, 0x5B2A, 0x8BE6, 0x5B2B, 0x8BE7, 0x5B2C, + 0x8BE8, 0x5B2D, 0x8BE9, 0x5B2E, 0x8BEA, 0x5B2F, 0x8BEB, 0x5B30, + 0x8BEC, 0x5B31, 0x8BED, 0x5B33, 0x8BEE, 0x5B35, 0x8BEF, 0x5B36, + 0x8BF0, 0x5B38, 0x8BF1, 0x5B39, 0x8BF2, 0x5B3A, 0x8BF3, 0x5B3B, + 0x8BF4, 0x5B3C, 0x8BF5, 0x5B3D, 0x8BF6, 0x5B3E, 0x8BF7, 0x5B3F, + 0x8BF8, 0x5B41, 0x8BF9, 0x5B42, 0x8BFA, 0x5B43, 0x8BFB, 0x5B44, + 0x8BFC, 0x5B45, 0x8BFD, 0x5B46, 0x8BFE, 0x5B47, 0x8C40, 0x5B48, + 0x8C41, 0x5B49, 0x8C42, 0x5B4A, 0x8C43, 0x5B4B, 0x8C44, 0x5B4C, + 0x8C45, 0x5B4D, 0x8C46, 0x5B4E, 0x8C47, 0x5B4F, 0x8C48, 0x5B52, + 0x8C49, 0x5B56, 0x8C4A, 0x5B5E, 0x8C4B, 0x5B60, 0x8C4C, 0x5B61, + 0x8C4D, 0x5B67, 0x8C4E, 0x5B68, 0x8C4F, 0x5B6B, 0x8C50, 0x5B6D, + 0x8C51, 0x5B6E, 0x8C52, 0x5B6F, 0x8C53, 0x5B72, 0x8C54, 0x5B74, + 0x8C55, 0x5B76, 0x8C56, 0x5B77, 0x8C57, 0x5B78, 0x8C58, 0x5B79, + 0x8C59, 0x5B7B, 0x8C5A, 0x5B7C, 0x8C5B, 0x5B7E, 0x8C5C, 0x5B7F, + 0x8C5D, 0x5B82, 0x8C5E, 0x5B86, 0x8C5F, 0x5B8A, 0x8C60, 0x5B8D, + 0x8C61, 0x5B8E, 0x8C62, 0x5B90, 0x8C63, 0x5B91, 0x8C64, 0x5B92, + 0x8C65, 0x5B94, 0x8C66, 0x5B96, 0x8C67, 0x5B9F, 0x8C68, 0x5BA7, + 0x8C69, 0x5BA8, 0x8C6A, 0x5BA9, 0x8C6B, 0x5BAC, 0x8C6C, 0x5BAD, + 0x8C6D, 0x5BAE, 0x8C6E, 0x5BAF, 0x8C6F, 0x5BB1, 0x8C70, 0x5BB2, + 0x8C71, 0x5BB7, 0x8C72, 0x5BBA, 0x8C73, 0x5BBB, 0x8C74, 0x5BBC, + 0x8C75, 0x5BC0, 0x8C76, 0x5BC1, 0x8C77, 0x5BC3, 0x8C78, 0x5BC8, + 0x8C79, 0x5BC9, 0x8C7A, 0x5BCA, 0x8C7B, 0x5BCB, 0x8C7C, 0x5BCD, + 0x8C7D, 0x5BCE, 0x8C7E, 0x5BCF, 0x8C80, 0x5BD1, 0x8C81, 0x5BD4, + 0x8C82, 0x5BD5, 0x8C83, 0x5BD6, 0x8C84, 0x5BD7, 0x8C85, 0x5BD8, + 0x8C86, 0x5BD9, 0x8C87, 0x5BDA, 0x8C88, 0x5BDB, 0x8C89, 0x5BDC, + 0x8C8A, 0x5BE0, 0x8C8B, 0x5BE2, 0x8C8C, 0x5BE3, 0x8C8D, 0x5BE6, + 0x8C8E, 0x5BE7, 0x8C8F, 0x5BE9, 0x8C90, 0x5BEA, 0x8C91, 0x5BEB, + 0x8C92, 0x5BEC, 0x8C93, 0x5BED, 0x8C94, 0x5BEF, 0x8C95, 0x5BF1, + 0x8C96, 0x5BF2, 0x8C97, 0x5BF3, 0x8C98, 0x5BF4, 0x8C99, 0x5BF5, + 0x8C9A, 0x5BF6, 0x8C9B, 0x5BF7, 0x8C9C, 0x5BFD, 0x8C9D, 0x5BFE, + 0x8C9E, 0x5C00, 0x8C9F, 0x5C02, 0x8CA0, 0x5C03, 0x8CA1, 0x5C05, + 0x8CA2, 0x5C07, 0x8CA3, 0x5C08, 0x8CA4, 0x5C0B, 0x8CA5, 0x5C0C, + 0x8CA6, 0x5C0D, 0x8CA7, 0x5C0E, 0x8CA8, 0x5C10, 0x8CA9, 0x5C12, + 0x8CAA, 0x5C13, 0x8CAB, 0x5C17, 0x8CAC, 0x5C19, 0x8CAD, 0x5C1B, + 0x8CAE, 0x5C1E, 0x8CAF, 0x5C1F, 0x8CB0, 0x5C20, 0x8CB1, 0x5C21, + 0x8CB2, 0x5C23, 0x8CB3, 0x5C26, 0x8CB4, 0x5C28, 0x8CB5, 0x5C29, + 0x8CB6, 0x5C2A, 0x8CB7, 0x5C2B, 0x8CB8, 0x5C2D, 0x8CB9, 0x5C2E, + 0x8CBA, 0x5C2F, 0x8CBB, 0x5C30, 0x8CBC, 0x5C32, 0x8CBD, 0x5C33, + 0x8CBE, 0x5C35, 0x8CBF, 0x5C36, 0x8CC0, 0x5C37, 0x8CC1, 0x5C43, + 0x8CC2, 0x5C44, 0x8CC3, 0x5C46, 0x8CC4, 0x5C47, 0x8CC5, 0x5C4C, + 0x8CC6, 0x5C4D, 0x8CC7, 0x5C52, 0x8CC8, 0x5C53, 0x8CC9, 0x5C54, + 0x8CCA, 0x5C56, 0x8CCB, 0x5C57, 0x8CCC, 0x5C58, 0x8CCD, 0x5C5A, + 0x8CCE, 0x5C5B, 0x8CCF, 0x5C5C, 0x8CD0, 0x5C5D, 0x8CD1, 0x5C5F, + 0x8CD2, 0x5C62, 0x8CD3, 0x5C64, 0x8CD4, 0x5C67, 0x8CD5, 0x5C68, + 0x8CD6, 0x5C69, 0x8CD7, 0x5C6A, 0x8CD8, 0x5C6B, 0x8CD9, 0x5C6C, + 0x8CDA, 0x5C6D, 0x8CDB, 0x5C70, 0x8CDC, 0x5C72, 0x8CDD, 0x5C73, + 0x8CDE, 0x5C74, 0x8CDF, 0x5C75, 0x8CE0, 0x5C76, 0x8CE1, 0x5C77, + 0x8CE2, 0x5C78, 0x8CE3, 0x5C7B, 0x8CE4, 0x5C7C, 0x8CE5, 0x5C7D, + 0x8CE6, 0x5C7E, 0x8CE7, 0x5C80, 0x8CE8, 0x5C83, 0x8CE9, 0x5C84, + 0x8CEA, 0x5C85, 0x8CEB, 0x5C86, 0x8CEC, 0x5C87, 0x8CED, 0x5C89, + 0x8CEE, 0x5C8A, 0x8CEF, 0x5C8B, 0x8CF0, 0x5C8E, 0x8CF1, 0x5C8F, + 0x8CF2, 0x5C92, 0x8CF3, 0x5C93, 0x8CF4, 0x5C95, 0x8CF5, 0x5C9D, + 0x8CF6, 0x5C9E, 0x8CF7, 0x5C9F, 0x8CF8, 0x5CA0, 0x8CF9, 0x5CA1, + 0x8CFA, 0x5CA4, 0x8CFB, 0x5CA5, 0x8CFC, 0x5CA6, 0x8CFD, 0x5CA7, + 0x8CFE, 0x5CA8, 0x8D40, 0x5CAA, 0x8D41, 0x5CAE, 0x8D42, 0x5CAF, + 0x8D43, 0x5CB0, 0x8D44, 0x5CB2, 0x8D45, 0x5CB4, 0x8D46, 0x5CB6, + 0x8D47, 0x5CB9, 0x8D48, 0x5CBA, 0x8D49, 0x5CBB, 0x8D4A, 0x5CBC, + 0x8D4B, 0x5CBE, 0x8D4C, 0x5CC0, 0x8D4D, 0x5CC2, 0x8D4E, 0x5CC3, + 0x8D4F, 0x5CC5, 0x8D50, 0x5CC6, 0x8D51, 0x5CC7, 0x8D52, 0x5CC8, + 0x8D53, 0x5CC9, 0x8D54, 0x5CCA, 0x8D55, 0x5CCC, 0x8D56, 0x5CCD, + 0x8D57, 0x5CCE, 0x8D58, 0x5CCF, 0x8D59, 0x5CD0, 0x8D5A, 0x5CD1, + 0x8D5B, 0x5CD3, 0x8D5C, 0x5CD4, 0x8D5D, 0x5CD5, 0x8D5E, 0x5CD6, + 0x8D5F, 0x5CD7, 0x8D60, 0x5CD8, 0x8D61, 0x5CDA, 0x8D62, 0x5CDB, + 0x8D63, 0x5CDC, 0x8D64, 0x5CDD, 0x8D65, 0x5CDE, 0x8D66, 0x5CDF, + 0x8D67, 0x5CE0, 0x8D68, 0x5CE2, 0x8D69, 0x5CE3, 0x8D6A, 0x5CE7, + 0x8D6B, 0x5CE9, 0x8D6C, 0x5CEB, 0x8D6D, 0x5CEC, 0x8D6E, 0x5CEE, + 0x8D6F, 0x5CEF, 0x8D70, 0x5CF1, 0x8D71, 0x5CF2, 0x8D72, 0x5CF3, + 0x8D73, 0x5CF4, 0x8D74, 0x5CF5, 0x8D75, 0x5CF6, 0x8D76, 0x5CF7, + 0x8D77, 0x5CF8, 0x8D78, 0x5CF9, 0x8D79, 0x5CFA, 0x8D7A, 0x5CFC, + 0x8D7B, 0x5CFD, 0x8D7C, 0x5CFE, 0x8D7D, 0x5CFF, 0x8D7E, 0x5D00, + 0x8D80, 0x5D01, 0x8D81, 0x5D04, 0x8D82, 0x5D05, 0x8D83, 0x5D08, + 0x8D84, 0x5D09, 0x8D85, 0x5D0A, 0x8D86, 0x5D0B, 0x8D87, 0x5D0C, + 0x8D88, 0x5D0D, 0x8D89, 0x5D0F, 0x8D8A, 0x5D10, 0x8D8B, 0x5D11, + 0x8D8C, 0x5D12, 0x8D8D, 0x5D13, 0x8D8E, 0x5D15, 0x8D8F, 0x5D17, + 0x8D90, 0x5D18, 0x8D91, 0x5D19, 0x8D92, 0x5D1A, 0x8D93, 0x5D1C, + 0x8D94, 0x5D1D, 0x8D95, 0x5D1F, 0x8D96, 0x5D20, 0x8D97, 0x5D21, + 0x8D98, 0x5D22, 0x8D99, 0x5D23, 0x8D9A, 0x5D25, 0x8D9B, 0x5D28, + 0x8D9C, 0x5D2A, 0x8D9D, 0x5D2B, 0x8D9E, 0x5D2C, 0x8D9F, 0x5D2F, + 0x8DA0, 0x5D30, 0x8DA1, 0x5D31, 0x8DA2, 0x5D32, 0x8DA3, 0x5D33, + 0x8DA4, 0x5D35, 0x8DA5, 0x5D36, 0x8DA6, 0x5D37, 0x8DA7, 0x5D38, + 0x8DA8, 0x5D39, 0x8DA9, 0x5D3A, 0x8DAA, 0x5D3B, 0x8DAB, 0x5D3C, + 0x8DAC, 0x5D3F, 0x8DAD, 0x5D40, 0x8DAE, 0x5D41, 0x8DAF, 0x5D42, + 0x8DB0, 0x5D43, 0x8DB1, 0x5D44, 0x8DB2, 0x5D45, 0x8DB3, 0x5D46, + 0x8DB4, 0x5D48, 0x8DB5, 0x5D49, 0x8DB6, 0x5D4D, 0x8DB7, 0x5D4E, + 0x8DB8, 0x5D4F, 0x8DB9, 0x5D50, 0x8DBA, 0x5D51, 0x8DBB, 0x5D52, + 0x8DBC, 0x5D53, 0x8DBD, 0x5D54, 0x8DBE, 0x5D55, 0x8DBF, 0x5D56, + 0x8DC0, 0x5D57, 0x8DC1, 0x5D59, 0x8DC2, 0x5D5A, 0x8DC3, 0x5D5C, + 0x8DC4, 0x5D5E, 0x8DC5, 0x5D5F, 0x8DC6, 0x5D60, 0x8DC7, 0x5D61, + 0x8DC8, 0x5D62, 0x8DC9, 0x5D63, 0x8DCA, 0x5D64, 0x8DCB, 0x5D65, + 0x8DCC, 0x5D66, 0x8DCD, 0x5D67, 0x8DCE, 0x5D68, 0x8DCF, 0x5D6A, + 0x8DD0, 0x5D6D, 0x8DD1, 0x5D6E, 0x8DD2, 0x5D70, 0x8DD3, 0x5D71, + 0x8DD4, 0x5D72, 0x8DD5, 0x5D73, 0x8DD6, 0x5D75, 0x8DD7, 0x5D76, + 0x8DD8, 0x5D77, 0x8DD9, 0x5D78, 0x8DDA, 0x5D79, 0x8DDB, 0x5D7A, + 0x8DDC, 0x5D7B, 0x8DDD, 0x5D7C, 0x8DDE, 0x5D7D, 0x8DDF, 0x5D7E, + 0x8DE0, 0x5D7F, 0x8DE1, 0x5D80, 0x8DE2, 0x5D81, 0x8DE3, 0x5D83, + 0x8DE4, 0x5D84, 0x8DE5, 0x5D85, 0x8DE6, 0x5D86, 0x8DE7, 0x5D87, + 0x8DE8, 0x5D88, 0x8DE9, 0x5D89, 0x8DEA, 0x5D8A, 0x8DEB, 0x5D8B, + 0x8DEC, 0x5D8C, 0x8DED, 0x5D8D, 0x8DEE, 0x5D8E, 0x8DEF, 0x5D8F, + 0x8DF0, 0x5D90, 0x8DF1, 0x5D91, 0x8DF2, 0x5D92, 0x8DF3, 0x5D93, + 0x8DF4, 0x5D94, 0x8DF5, 0x5D95, 0x8DF6, 0x5D96, 0x8DF7, 0x5D97, + 0x8DF8, 0x5D98, 0x8DF9, 0x5D9A, 0x8DFA, 0x5D9B, 0x8DFB, 0x5D9C, + 0x8DFC, 0x5D9E, 0x8DFD, 0x5D9F, 0x8DFE, 0x5DA0, 0x8E40, 0x5DA1, + 0x8E41, 0x5DA2, 0x8E42, 0x5DA3, 0x8E43, 0x5DA4, 0x8E44, 0x5DA5, + 0x8E45, 0x5DA6, 0x8E46, 0x5DA7, 0x8E47, 0x5DA8, 0x8E48, 0x5DA9, + 0x8E49, 0x5DAA, 0x8E4A, 0x5DAB, 0x8E4B, 0x5DAC, 0x8E4C, 0x5DAD, + 0x8E4D, 0x5DAE, 0x8E4E, 0x5DAF, 0x8E4F, 0x5DB0, 0x8E50, 0x5DB1, + 0x8E51, 0x5DB2, 0x8E52, 0x5DB3, 0x8E53, 0x5DB4, 0x8E54, 0x5DB5, + 0x8E55, 0x5DB6, 0x8E56, 0x5DB8, 0x8E57, 0x5DB9, 0x8E58, 0x5DBA, + 0x8E59, 0x5DBB, 0x8E5A, 0x5DBC, 0x8E5B, 0x5DBD, 0x8E5C, 0x5DBE, + 0x8E5D, 0x5DBF, 0x8E5E, 0x5DC0, 0x8E5F, 0x5DC1, 0x8E60, 0x5DC2, + 0x8E61, 0x5DC3, 0x8E62, 0x5DC4, 0x8E63, 0x5DC6, 0x8E64, 0x5DC7, + 0x8E65, 0x5DC8, 0x8E66, 0x5DC9, 0x8E67, 0x5DCA, 0x8E68, 0x5DCB, + 0x8E69, 0x5DCC, 0x8E6A, 0x5DCE, 0x8E6B, 0x5DCF, 0x8E6C, 0x5DD0, + 0x8E6D, 0x5DD1, 0x8E6E, 0x5DD2, 0x8E6F, 0x5DD3, 0x8E70, 0x5DD4, + 0x8E71, 0x5DD5, 0x8E72, 0x5DD6, 0x8E73, 0x5DD7, 0x8E74, 0x5DD8, + 0x8E75, 0x5DD9, 0x8E76, 0x5DDA, 0x8E77, 0x5DDC, 0x8E78, 0x5DDF, + 0x8E79, 0x5DE0, 0x8E7A, 0x5DE3, 0x8E7B, 0x5DE4, 0x8E7C, 0x5DEA, + 0x8E7D, 0x5DEC, 0x8E7E, 0x5DED, 0x8E80, 0x5DF0, 0x8E81, 0x5DF5, + 0x8E82, 0x5DF6, 0x8E83, 0x5DF8, 0x8E84, 0x5DF9, 0x8E85, 0x5DFA, + 0x8E86, 0x5DFB, 0x8E87, 0x5DFC, 0x8E88, 0x5DFF, 0x8E89, 0x5E00, + 0x8E8A, 0x5E04, 0x8E8B, 0x5E07, 0x8E8C, 0x5E09, 0x8E8D, 0x5E0A, + 0x8E8E, 0x5E0B, 0x8E8F, 0x5E0D, 0x8E90, 0x5E0E, 0x8E91, 0x5E12, + 0x8E92, 0x5E13, 0x8E93, 0x5E17, 0x8E94, 0x5E1E, 0x8E95, 0x5E1F, + 0x8E96, 0x5E20, 0x8E97, 0x5E21, 0x8E98, 0x5E22, 0x8E99, 0x5E23, + 0x8E9A, 0x5E24, 0x8E9B, 0x5E25, 0x8E9C, 0x5E28, 0x8E9D, 0x5E29, + 0x8E9E, 0x5E2A, 0x8E9F, 0x5E2B, 0x8EA0, 0x5E2C, 0x8EA1, 0x5E2F, + 0x8EA2, 0x5E30, 0x8EA3, 0x5E32, 0x8EA4, 0x5E33, 0x8EA5, 0x5E34, + 0x8EA6, 0x5E35, 0x8EA7, 0x5E36, 0x8EA8, 0x5E39, 0x8EA9, 0x5E3A, + 0x8EAA, 0x5E3E, 0x8EAB, 0x5E3F, 0x8EAC, 0x5E40, 0x8EAD, 0x5E41, + 0x8EAE, 0x5E43, 0x8EAF, 0x5E46, 0x8EB0, 0x5E47, 0x8EB1, 0x5E48, + 0x8EB2, 0x5E49, 0x8EB3, 0x5E4A, 0x8EB4, 0x5E4B, 0x8EB5, 0x5E4D, + 0x8EB6, 0x5E4E, 0x8EB7, 0x5E4F, 0x8EB8, 0x5E50, 0x8EB9, 0x5E51, + 0x8EBA, 0x5E52, 0x8EBB, 0x5E53, 0x8EBC, 0x5E56, 0x8EBD, 0x5E57, + 0x8EBE, 0x5E58, 0x8EBF, 0x5E59, 0x8EC0, 0x5E5A, 0x8EC1, 0x5E5C, + 0x8EC2, 0x5E5D, 0x8EC3, 0x5E5F, 0x8EC4, 0x5E60, 0x8EC5, 0x5E63, + 0x8EC6, 0x5E64, 0x8EC7, 0x5E65, 0x8EC8, 0x5E66, 0x8EC9, 0x5E67, + 0x8ECA, 0x5E68, 0x8ECB, 0x5E69, 0x8ECC, 0x5E6A, 0x8ECD, 0x5E6B, + 0x8ECE, 0x5E6C, 0x8ECF, 0x5E6D, 0x8ED0, 0x5E6E, 0x8ED1, 0x5E6F, + 0x8ED2, 0x5E70, 0x8ED3, 0x5E71, 0x8ED4, 0x5E75, 0x8ED5, 0x5E77, + 0x8ED6, 0x5E79, 0x8ED7, 0x5E7E, 0x8ED8, 0x5E81, 0x8ED9, 0x5E82, + 0x8EDA, 0x5E83, 0x8EDB, 0x5E85, 0x8EDC, 0x5E88, 0x8EDD, 0x5E89, + 0x8EDE, 0x5E8C, 0x8EDF, 0x5E8D, 0x8EE0, 0x5E8E, 0x8EE1, 0x5E92, + 0x8EE2, 0x5E98, 0x8EE3, 0x5E9B, 0x8EE4, 0x5E9D, 0x8EE5, 0x5EA1, + 0x8EE6, 0x5EA2, 0x8EE7, 0x5EA3, 0x8EE8, 0x5EA4, 0x8EE9, 0x5EA8, + 0x8EEA, 0x5EA9, 0x8EEB, 0x5EAA, 0x8EEC, 0x5EAB, 0x8EED, 0x5EAC, + 0x8EEE, 0x5EAE, 0x8EEF, 0x5EAF, 0x8EF0, 0x5EB0, 0x8EF1, 0x5EB1, + 0x8EF2, 0x5EB2, 0x8EF3, 0x5EB4, 0x8EF4, 0x5EBA, 0x8EF5, 0x5EBB, + 0x8EF6, 0x5EBC, 0x8EF7, 0x5EBD, 0x8EF8, 0x5EBF, 0x8EF9, 0x5EC0, + 0x8EFA, 0x5EC1, 0x8EFB, 0x5EC2, 0x8EFC, 0x5EC3, 0x8EFD, 0x5EC4, + 0x8EFE, 0x5EC5, 0x8F40, 0x5EC6, 0x8F41, 0x5EC7, 0x8F42, 0x5EC8, + 0x8F43, 0x5ECB, 0x8F44, 0x5ECC, 0x8F45, 0x5ECD, 0x8F46, 0x5ECE, + 0x8F47, 0x5ECF, 0x8F48, 0x5ED0, 0x8F49, 0x5ED4, 0x8F4A, 0x5ED5, + 0x8F4B, 0x5ED7, 0x8F4C, 0x5ED8, 0x8F4D, 0x5ED9, 0x8F4E, 0x5EDA, + 0x8F4F, 0x5EDC, 0x8F50, 0x5EDD, 0x8F51, 0x5EDE, 0x8F52, 0x5EDF, + 0x8F53, 0x5EE0, 0x8F54, 0x5EE1, 0x8F55, 0x5EE2, 0x8F56, 0x5EE3, + 0x8F57, 0x5EE4, 0x8F58, 0x5EE5, 0x8F59, 0x5EE6, 0x8F5A, 0x5EE7, + 0x8F5B, 0x5EE9, 0x8F5C, 0x5EEB, 0x8F5D, 0x5EEC, 0x8F5E, 0x5EED, + 0x8F5F, 0x5EEE, 0x8F60, 0x5EEF, 0x8F61, 0x5EF0, 0x8F62, 0x5EF1, + 0x8F63, 0x5EF2, 0x8F64, 0x5EF3, 0x8F65, 0x5EF5, 0x8F66, 0x5EF8, + 0x8F67, 0x5EF9, 0x8F68, 0x5EFB, 0x8F69, 0x5EFC, 0x8F6A, 0x5EFD, + 0x8F6B, 0x5F05, 0x8F6C, 0x5F06, 0x8F6D, 0x5F07, 0x8F6E, 0x5F09, + 0x8F6F, 0x5F0C, 0x8F70, 0x5F0D, 0x8F71, 0x5F0E, 0x8F72, 0x5F10, + 0x8F73, 0x5F12, 0x8F74, 0x5F14, 0x8F75, 0x5F16, 0x8F76, 0x5F19, + 0x8F77, 0x5F1A, 0x8F78, 0x5F1C, 0x8F79, 0x5F1D, 0x8F7A, 0x5F1E, + 0x8F7B, 0x5F21, 0x8F7C, 0x5F22, 0x8F7D, 0x5F23, 0x8F7E, 0x5F24, + 0x8F80, 0x5F28, 0x8F81, 0x5F2B, 0x8F82, 0x5F2C, 0x8F83, 0x5F2E, + 0x8F84, 0x5F30, 0x8F85, 0x5F32, 0x8F86, 0x5F33, 0x8F87, 0x5F34, + 0x8F88, 0x5F35, 0x8F89, 0x5F36, 0x8F8A, 0x5F37, 0x8F8B, 0x5F38, + 0x8F8C, 0x5F3B, 0x8F8D, 0x5F3D, 0x8F8E, 0x5F3E, 0x8F8F, 0x5F3F, + 0x8F90, 0x5F41, 0x8F91, 0x5F42, 0x8F92, 0x5F43, 0x8F93, 0x5F44, + 0x8F94, 0x5F45, 0x8F95, 0x5F46, 0x8F96, 0x5F47, 0x8F97, 0x5F48, + 0x8F98, 0x5F49, 0x8F99, 0x5F4A, 0x8F9A, 0x5F4B, 0x8F9B, 0x5F4C, + 0x8F9C, 0x5F4D, 0x8F9D, 0x5F4E, 0x8F9E, 0x5F4F, 0x8F9F, 0x5F51, + 0x8FA0, 0x5F54, 0x8FA1, 0x5F59, 0x8FA2, 0x5F5A, 0x8FA3, 0x5F5B, + 0x8FA4, 0x5F5C, 0x8FA5, 0x5F5E, 0x8FA6, 0x5F5F, 0x8FA7, 0x5F60, + 0x8FA8, 0x5F63, 0x8FA9, 0x5F65, 0x8FAA, 0x5F67, 0x8FAB, 0x5F68, + 0x8FAC, 0x5F6B, 0x8FAD, 0x5F6E, 0x8FAE, 0x5F6F, 0x8FAF, 0x5F72, + 0x8FB0, 0x5F74, 0x8FB1, 0x5F75, 0x8FB2, 0x5F76, 0x8FB3, 0x5F78, + 0x8FB4, 0x5F7A, 0x8FB5, 0x5F7D, 0x8FB6, 0x5F7E, 0x8FB7, 0x5F7F, + 0x8FB8, 0x5F83, 0x8FB9, 0x5F86, 0x8FBA, 0x5F8D, 0x8FBB, 0x5F8E, + 0x8FBC, 0x5F8F, 0x8FBD, 0x5F91, 0x8FBE, 0x5F93, 0x8FBF, 0x5F94, + 0x8FC0, 0x5F96, 0x8FC1, 0x5F9A, 0x8FC2, 0x5F9B, 0x8FC3, 0x5F9D, + 0x8FC4, 0x5F9E, 0x8FC5, 0x5F9F, 0x8FC6, 0x5FA0, 0x8FC7, 0x5FA2, + 0x8FC8, 0x5FA3, 0x8FC9, 0x5FA4, 0x8FCA, 0x5FA5, 0x8FCB, 0x5FA6, + 0x8FCC, 0x5FA7, 0x8FCD, 0x5FA9, 0x8FCE, 0x5FAB, 0x8FCF, 0x5FAC, + 0x8FD0, 0x5FAF, 0x8FD1, 0x5FB0, 0x8FD2, 0x5FB1, 0x8FD3, 0x5FB2, + 0x8FD4, 0x5FB3, 0x8FD5, 0x5FB4, 0x8FD6, 0x5FB6, 0x8FD7, 0x5FB8, + 0x8FD8, 0x5FB9, 0x8FD9, 0x5FBA, 0x8FDA, 0x5FBB, 0x8FDB, 0x5FBE, + 0x8FDC, 0x5FBF, 0x8FDD, 0x5FC0, 0x8FDE, 0x5FC1, 0x8FDF, 0x5FC2, + 0x8FE0, 0x5FC7, 0x8FE1, 0x5FC8, 0x8FE2, 0x5FCA, 0x8FE3, 0x5FCB, + 0x8FE4, 0x5FCE, 0x8FE5, 0x5FD3, 0x8FE6, 0x5FD4, 0x8FE7, 0x5FD5, + 0x8FE8, 0x5FDA, 0x8FE9, 0x5FDB, 0x8FEA, 0x5FDC, 0x8FEB, 0x5FDE, + 0x8FEC, 0x5FDF, 0x8FED, 0x5FE2, 0x8FEE, 0x5FE3, 0x8FEF, 0x5FE5, + 0x8FF0, 0x5FE6, 0x8FF1, 0x5FE8, 0x8FF2, 0x5FE9, 0x8FF3, 0x5FEC, + 0x8FF4, 0x5FEF, 0x8FF5, 0x5FF0, 0x8FF6, 0x5FF2, 0x8FF7, 0x5FF3, + 0x8FF8, 0x5FF4, 0x8FF9, 0x5FF6, 0x8FFA, 0x5FF7, 0x8FFB, 0x5FF9, + 0x8FFC, 0x5FFA, 0x8FFD, 0x5FFC, 0x8FFE, 0x6007, 0x9040, 0x6008, + 0x9041, 0x6009, 0x9042, 0x600B, 0x9043, 0x600C, 0x9044, 0x6010, + 0x9045, 0x6011, 0x9046, 0x6013, 0x9047, 0x6017, 0x9048, 0x6018, + 0x9049, 0x601A, 0x904A, 0x601E, 0x904B, 0x601F, 0x904C, 0x6022, + 0x904D, 0x6023, 0x904E, 0x6024, 0x904F, 0x602C, 0x9050, 0x602D, + 0x9051, 0x602E, 0x9052, 0x6030, 0x9053, 0x6031, 0x9054, 0x6032, + 0x9055, 0x6033, 0x9056, 0x6034, 0x9057, 0x6036, 0x9058, 0x6037, + 0x9059, 0x6038, 0x905A, 0x6039, 0x905B, 0x603A, 0x905C, 0x603D, + 0x905D, 0x603E, 0x905E, 0x6040, 0x905F, 0x6044, 0x9060, 0x6045, + 0x9061, 0x6046, 0x9062, 0x6047, 0x9063, 0x6048, 0x9064, 0x6049, + 0x9065, 0x604A, 0x9066, 0x604C, 0x9067, 0x604E, 0x9068, 0x604F, + 0x9069, 0x6051, 0x906A, 0x6053, 0x906B, 0x6054, 0x906C, 0x6056, + 0x906D, 0x6057, 0x906E, 0x6058, 0x906F, 0x605B, 0x9070, 0x605C, + 0x9071, 0x605E, 0x9072, 0x605F, 0x9073, 0x6060, 0x9074, 0x6061, + 0x9075, 0x6065, 0x9076, 0x6066, 0x9077, 0x606E, 0x9078, 0x6071, + 0x9079, 0x6072, 0x907A, 0x6074, 0x907B, 0x6075, 0x907C, 0x6077, + 0x907D, 0x607E, 0x907E, 0x6080, 0x9080, 0x6081, 0x9081, 0x6082, + 0x9082, 0x6085, 0x9083, 0x6086, 0x9084, 0x6087, 0x9085, 0x6088, + 0x9086, 0x608A, 0x9087, 0x608B, 0x9088, 0x608E, 0x9089, 0x608F, + 0x908A, 0x6090, 0x908B, 0x6091, 0x908C, 0x6093, 0x908D, 0x6095, + 0x908E, 0x6097, 0x908F, 0x6098, 0x9090, 0x6099, 0x9091, 0x609C, + 0x9092, 0x609E, 0x9093, 0x60A1, 0x9094, 0x60A2, 0x9095, 0x60A4, + 0x9096, 0x60A5, 0x9097, 0x60A7, 0x9098, 0x60A9, 0x9099, 0x60AA, + 0x909A, 0x60AE, 0x909B, 0x60B0, 0x909C, 0x60B3, 0x909D, 0x60B5, + 0x909E, 0x60B6, 0x909F, 0x60B7, 0x90A0, 0x60B9, 0x90A1, 0x60BA, + 0x90A2, 0x60BD, 0x90A3, 0x60BE, 0x90A4, 0x60BF, 0x90A5, 0x60C0, + 0x90A6, 0x60C1, 0x90A7, 0x60C2, 0x90A8, 0x60C3, 0x90A9, 0x60C4, + 0x90AA, 0x60C7, 0x90AB, 0x60C8, 0x90AC, 0x60C9, 0x90AD, 0x60CC, + 0x90AE, 0x60CD, 0x90AF, 0x60CE, 0x90B0, 0x60CF, 0x90B1, 0x60D0, + 0x90B2, 0x60D2, 0x90B3, 0x60D3, 0x90B4, 0x60D4, 0x90B5, 0x60D6, + 0x90B6, 0x60D7, 0x90B7, 0x60D9, 0x90B8, 0x60DB, 0x90B9, 0x60DE, + 0x90BA, 0x60E1, 0x90BB, 0x60E2, 0x90BC, 0x60E3, 0x90BD, 0x60E4, + 0x90BE, 0x60E5, 0x90BF, 0x60EA, 0x90C0, 0x60F1, 0x90C1, 0x60F2, + 0x90C2, 0x60F5, 0x90C3, 0x60F7, 0x90C4, 0x60F8, 0x90C5, 0x60FB, + 0x90C6, 0x60FC, 0x90C7, 0x60FD, 0x90C8, 0x60FE, 0x90C9, 0x60FF, + 0x90CA, 0x6102, 0x90CB, 0x6103, 0x90CC, 0x6104, 0x90CD, 0x6105, + 0x90CE, 0x6107, 0x90CF, 0x610A, 0x90D0, 0x610B, 0x90D1, 0x610C, + 0x90D2, 0x6110, 0x90D3, 0x6111, 0x90D4, 0x6112, 0x90D5, 0x6113, + 0x90D6, 0x6114, 0x90D7, 0x6116, 0x90D8, 0x6117, 0x90D9, 0x6118, + 0x90DA, 0x6119, 0x90DB, 0x611B, 0x90DC, 0x611C, 0x90DD, 0x611D, + 0x90DE, 0x611E, 0x90DF, 0x6121, 0x90E0, 0x6122, 0x90E1, 0x6125, + 0x90E2, 0x6128, 0x90E3, 0x6129, 0x90E4, 0x612A, 0x90E5, 0x612C, + 0x90E6, 0x612D, 0x90E7, 0x612E, 0x90E8, 0x612F, 0x90E9, 0x6130, + 0x90EA, 0x6131, 0x90EB, 0x6132, 0x90EC, 0x6133, 0x90ED, 0x6134, + 0x90EE, 0x6135, 0x90EF, 0x6136, 0x90F0, 0x6137, 0x90F1, 0x6138, + 0x90F2, 0x6139, 0x90F3, 0x613A, 0x90F4, 0x613B, 0x90F5, 0x613C, + 0x90F6, 0x613D, 0x90F7, 0x613E, 0x90F8, 0x6140, 0x90F9, 0x6141, + 0x90FA, 0x6142, 0x90FB, 0x6143, 0x90FC, 0x6144, 0x90FD, 0x6145, + 0x90FE, 0x6146, 0x9140, 0x6147, 0x9141, 0x6149, 0x9142, 0x614B, + 0x9143, 0x614D, 0x9144, 0x614F, 0x9145, 0x6150, 0x9146, 0x6152, + 0x9147, 0x6153, 0x9148, 0x6154, 0x9149, 0x6156, 0x914A, 0x6157, + 0x914B, 0x6158, 0x914C, 0x6159, 0x914D, 0x615A, 0x914E, 0x615B, + 0x914F, 0x615C, 0x9150, 0x615E, 0x9151, 0x615F, 0x9152, 0x6160, + 0x9153, 0x6161, 0x9154, 0x6163, 0x9155, 0x6164, 0x9156, 0x6165, + 0x9157, 0x6166, 0x9158, 0x6169, 0x9159, 0x616A, 0x915A, 0x616B, + 0x915B, 0x616C, 0x915C, 0x616D, 0x915D, 0x616E, 0x915E, 0x616F, + 0x915F, 0x6171, 0x9160, 0x6172, 0x9161, 0x6173, 0x9162, 0x6174, + 0x9163, 0x6176, 0x9164, 0x6178, 0x9165, 0x6179, 0x9166, 0x617A, + 0x9167, 0x617B, 0x9168, 0x617C, 0x9169, 0x617D, 0x916A, 0x617E, + 0x916B, 0x617F, 0x916C, 0x6180, 0x916D, 0x6181, 0x916E, 0x6182, + 0x916F, 0x6183, 0x9170, 0x6184, 0x9171, 0x6185, 0x9172, 0x6186, + 0x9173, 0x6187, 0x9174, 0x6188, 0x9175, 0x6189, 0x9176, 0x618A, + 0x9177, 0x618C, 0x9178, 0x618D, 0x9179, 0x618F, 0x917A, 0x6190, + 0x917B, 0x6191, 0x917C, 0x6192, 0x917D, 0x6193, 0x917E, 0x6195, + 0x9180, 0x6196, 0x9181, 0x6197, 0x9182, 0x6198, 0x9183, 0x6199, + 0x9184, 0x619A, 0x9185, 0x619B, 0x9186, 0x619C, 0x9187, 0x619E, + 0x9188, 0x619F, 0x9189, 0x61A0, 0x918A, 0x61A1, 0x918B, 0x61A2, + 0x918C, 0x61A3, 0x918D, 0x61A4, 0x918E, 0x61A5, 0x918F, 0x61A6, + 0x9190, 0x61AA, 0x9191, 0x61AB, 0x9192, 0x61AD, 0x9193, 0x61AE, + 0x9194, 0x61AF, 0x9195, 0x61B0, 0x9196, 0x61B1, 0x9197, 0x61B2, + 0x9198, 0x61B3, 0x9199, 0x61B4, 0x919A, 0x61B5, 0x919B, 0x61B6, + 0x919C, 0x61B8, 0x919D, 0x61B9, 0x919E, 0x61BA, 0x919F, 0x61BB, + 0x91A0, 0x61BC, 0x91A1, 0x61BD, 0x91A2, 0x61BF, 0x91A3, 0x61C0, + 0x91A4, 0x61C1, 0x91A5, 0x61C3, 0x91A6, 0x61C4, 0x91A7, 0x61C5, + 0x91A8, 0x61C6, 0x91A9, 0x61C7, 0x91AA, 0x61C9, 0x91AB, 0x61CC, + 0x91AC, 0x61CD, 0x91AD, 0x61CE, 0x91AE, 0x61CF, 0x91AF, 0x61D0, + 0x91B0, 0x61D3, 0x91B1, 0x61D5, 0x91B2, 0x61D6, 0x91B3, 0x61D7, + 0x91B4, 0x61D8, 0x91B5, 0x61D9, 0x91B6, 0x61DA, 0x91B7, 0x61DB, + 0x91B8, 0x61DC, 0x91B9, 0x61DD, 0x91BA, 0x61DE, 0x91BB, 0x61DF, + 0x91BC, 0x61E0, 0x91BD, 0x61E1, 0x91BE, 0x61E2, 0x91BF, 0x61E3, + 0x91C0, 0x61E4, 0x91C1, 0x61E5, 0x91C2, 0x61E7, 0x91C3, 0x61E8, + 0x91C4, 0x61E9, 0x91C5, 0x61EA, 0x91C6, 0x61EB, 0x91C7, 0x61EC, + 0x91C8, 0x61ED, 0x91C9, 0x61EE, 0x91CA, 0x61EF, 0x91CB, 0x61F0, + 0x91CC, 0x61F1, 0x91CD, 0x61F2, 0x91CE, 0x61F3, 0x91CF, 0x61F4, + 0x91D0, 0x61F6, 0x91D1, 0x61F7, 0x91D2, 0x61F8, 0x91D3, 0x61F9, + 0x91D4, 0x61FA, 0x91D5, 0x61FB, 0x91D6, 0x61FC, 0x91D7, 0x61FD, + 0x91D8, 0x61FE, 0x91D9, 0x6200, 0x91DA, 0x6201, 0x91DB, 0x6202, + 0x91DC, 0x6203, 0x91DD, 0x6204, 0x91DE, 0x6205, 0x91DF, 0x6207, + 0x91E0, 0x6209, 0x91E1, 0x6213, 0x91E2, 0x6214, 0x91E3, 0x6219, + 0x91E4, 0x621C, 0x91E5, 0x621D, 0x91E6, 0x621E, 0x91E7, 0x6220, + 0x91E8, 0x6223, 0x91E9, 0x6226, 0x91EA, 0x6227, 0x91EB, 0x6228, + 0x91EC, 0x6229, 0x91ED, 0x622B, 0x91EE, 0x622D, 0x91EF, 0x622F, + 0x91F0, 0x6230, 0x91F1, 0x6231, 0x91F2, 0x6232, 0x91F3, 0x6235, + 0x91F4, 0x6236, 0x91F5, 0x6238, 0x91F6, 0x6239, 0x91F7, 0x623A, + 0x91F8, 0x623B, 0x91F9, 0x623C, 0x91FA, 0x6242, 0x91FB, 0x6244, + 0x91FC, 0x6245, 0x91FD, 0x6246, 0x91FE, 0x624A, 0x9240, 0x624F, + 0x9241, 0x6250, 0x9242, 0x6255, 0x9243, 0x6256, 0x9244, 0x6257, + 0x9245, 0x6259, 0x9246, 0x625A, 0x9247, 0x625C, 0x9248, 0x625D, + 0x9249, 0x625E, 0x924A, 0x625F, 0x924B, 0x6260, 0x924C, 0x6261, + 0x924D, 0x6262, 0x924E, 0x6264, 0x924F, 0x6265, 0x9250, 0x6268, + 0x9251, 0x6271, 0x9252, 0x6272, 0x9253, 0x6274, 0x9254, 0x6275, + 0x9255, 0x6277, 0x9256, 0x6278, 0x9257, 0x627A, 0x9258, 0x627B, + 0x9259, 0x627D, 0x925A, 0x6281, 0x925B, 0x6282, 0x925C, 0x6283, + 0x925D, 0x6285, 0x925E, 0x6286, 0x925F, 0x6287, 0x9260, 0x6288, + 0x9261, 0x628B, 0x9262, 0x628C, 0x9263, 0x628D, 0x9264, 0x628E, + 0x9265, 0x628F, 0x9266, 0x6290, 0x9267, 0x6294, 0x9268, 0x6299, + 0x9269, 0x629C, 0x926A, 0x629D, 0x926B, 0x629E, 0x926C, 0x62A3, + 0x926D, 0x62A6, 0x926E, 0x62A7, 0x926F, 0x62A9, 0x9270, 0x62AA, + 0x9271, 0x62AD, 0x9272, 0x62AE, 0x9273, 0x62AF, 0x9274, 0x62B0, + 0x9275, 0x62B2, 0x9276, 0x62B3, 0x9277, 0x62B4, 0x9278, 0x62B6, + 0x9279, 0x62B7, 0x927A, 0x62B8, 0x927B, 0x62BA, 0x927C, 0x62BE, + 0x927D, 0x62C0, 0x927E, 0x62C1, 0x9280, 0x62C3, 0x9281, 0x62CB, + 0x9282, 0x62CF, 0x9283, 0x62D1, 0x9284, 0x62D5, 0x9285, 0x62DD, + 0x9286, 0x62DE, 0x9287, 0x62E0, 0x9288, 0x62E1, 0x9289, 0x62E4, + 0x928A, 0x62EA, 0x928B, 0x62EB, 0x928C, 0x62F0, 0x928D, 0x62F2, + 0x928E, 0x62F5, 0x928F, 0x62F8, 0x9290, 0x62F9, 0x9291, 0x62FA, + 0x9292, 0x62FB, 0x9293, 0x6300, 0x9294, 0x6303, 0x9295, 0x6304, + 0x9296, 0x6305, 0x9297, 0x6306, 0x9298, 0x630A, 0x9299, 0x630B, + 0x929A, 0x630C, 0x929B, 0x630D, 0x929C, 0x630F, 0x929D, 0x6310, + 0x929E, 0x6312, 0x929F, 0x6313, 0x92A0, 0x6314, 0x92A1, 0x6315, + 0x92A2, 0x6317, 0x92A3, 0x6318, 0x92A4, 0x6319, 0x92A5, 0x631C, + 0x92A6, 0x6326, 0x92A7, 0x6327, 0x92A8, 0x6329, 0x92A9, 0x632C, + 0x92AA, 0x632D, 0x92AB, 0x632E, 0x92AC, 0x6330, 0x92AD, 0x6331, + 0x92AE, 0x6333, 0x92AF, 0x6334, 0x92B0, 0x6335, 0x92B1, 0x6336, + 0x92B2, 0x6337, 0x92B3, 0x6338, 0x92B4, 0x633B, 0x92B5, 0x633C, + 0x92B6, 0x633E, 0x92B7, 0x633F, 0x92B8, 0x6340, 0x92B9, 0x6341, + 0x92BA, 0x6344, 0x92BB, 0x6347, 0x92BC, 0x6348, 0x92BD, 0x634A, + 0x92BE, 0x6351, 0x92BF, 0x6352, 0x92C0, 0x6353, 0x92C1, 0x6354, + 0x92C2, 0x6356, 0x92C3, 0x6357, 0x92C4, 0x6358, 0x92C5, 0x6359, + 0x92C6, 0x635A, 0x92C7, 0x635B, 0x92C8, 0x635C, 0x92C9, 0x635D, + 0x92CA, 0x6360, 0x92CB, 0x6364, 0x92CC, 0x6365, 0x92CD, 0x6366, + 0x92CE, 0x6368, 0x92CF, 0x636A, 0x92D0, 0x636B, 0x92D1, 0x636C, + 0x92D2, 0x636F, 0x92D3, 0x6370, 0x92D4, 0x6372, 0x92D5, 0x6373, + 0x92D6, 0x6374, 0x92D7, 0x6375, 0x92D8, 0x6378, 0x92D9, 0x6379, + 0x92DA, 0x637C, 0x92DB, 0x637D, 0x92DC, 0x637E, 0x92DD, 0x637F, + 0x92DE, 0x6381, 0x92DF, 0x6383, 0x92E0, 0x6384, 0x92E1, 0x6385, + 0x92E2, 0x6386, 0x92E3, 0x638B, 0x92E4, 0x638D, 0x92E5, 0x6391, + 0x92E6, 0x6393, 0x92E7, 0x6394, 0x92E8, 0x6395, 0x92E9, 0x6397, + 0x92EA, 0x6399, 0x92EB, 0x639A, 0x92EC, 0x639B, 0x92ED, 0x639C, + 0x92EE, 0x639D, 0x92EF, 0x639E, 0x92F0, 0x639F, 0x92F1, 0x63A1, + 0x92F2, 0x63A4, 0x92F3, 0x63A6, 0x92F4, 0x63AB, 0x92F5, 0x63AF, + 0x92F6, 0x63B1, 0x92F7, 0x63B2, 0x92F8, 0x63B5, 0x92F9, 0x63B6, + 0x92FA, 0x63B9, 0x92FB, 0x63BB, 0x92FC, 0x63BD, 0x92FD, 0x63BF, + 0x92FE, 0x63C0, 0x9340, 0x63C1, 0x9341, 0x63C2, 0x9342, 0x63C3, + 0x9343, 0x63C5, 0x9344, 0x63C7, 0x9345, 0x63C8, 0x9346, 0x63CA, + 0x9347, 0x63CB, 0x9348, 0x63CC, 0x9349, 0x63D1, 0x934A, 0x63D3, + 0x934B, 0x63D4, 0x934C, 0x63D5, 0x934D, 0x63D7, 0x934E, 0x63D8, + 0x934F, 0x63D9, 0x9350, 0x63DA, 0x9351, 0x63DB, 0x9352, 0x63DC, + 0x9353, 0x63DD, 0x9354, 0x63DF, 0x9355, 0x63E2, 0x9356, 0x63E4, + 0x9357, 0x63E5, 0x9358, 0x63E6, 0x9359, 0x63E7, 0x935A, 0x63E8, + 0x935B, 0x63EB, 0x935C, 0x63EC, 0x935D, 0x63EE, 0x935E, 0x63EF, + 0x935F, 0x63F0, 0x9360, 0x63F1, 0x9361, 0x63F3, 0x9362, 0x63F5, + 0x9363, 0x63F7, 0x9364, 0x63F9, 0x9365, 0x63FA, 0x9366, 0x63FB, + 0x9367, 0x63FC, 0x9368, 0x63FE, 0x9369, 0x6403, 0x936A, 0x6404, + 0x936B, 0x6406, 0x936C, 0x6407, 0x936D, 0x6408, 0x936E, 0x6409, + 0x936F, 0x640A, 0x9370, 0x640D, 0x9371, 0x640E, 0x9372, 0x6411, + 0x9373, 0x6412, 0x9374, 0x6415, 0x9375, 0x6416, 0x9376, 0x6417, + 0x9377, 0x6418, 0x9378, 0x6419, 0x9379, 0x641A, 0x937A, 0x641D, + 0x937B, 0x641F, 0x937C, 0x6422, 0x937D, 0x6423, 0x937E, 0x6424, + 0x9380, 0x6425, 0x9381, 0x6427, 0x9382, 0x6428, 0x9383, 0x6429, + 0x9384, 0x642B, 0x9385, 0x642E, 0x9386, 0x642F, 0x9387, 0x6430, + 0x9388, 0x6431, 0x9389, 0x6432, 0x938A, 0x6433, 0x938B, 0x6435, + 0x938C, 0x6436, 0x938D, 0x6437, 0x938E, 0x6438, 0x938F, 0x6439, + 0x9390, 0x643B, 0x9391, 0x643C, 0x9392, 0x643E, 0x9393, 0x6440, + 0x9394, 0x6442, 0x9395, 0x6443, 0x9396, 0x6449, 0x9397, 0x644B, + 0x9398, 0x644C, 0x9399, 0x644D, 0x939A, 0x644E, 0x939B, 0x644F, + 0x939C, 0x6450, 0x939D, 0x6451, 0x939E, 0x6453, 0x939F, 0x6455, + 0x93A0, 0x6456, 0x93A1, 0x6457, 0x93A2, 0x6459, 0x93A3, 0x645A, + 0x93A4, 0x645B, 0x93A5, 0x645C, 0x93A6, 0x645D, 0x93A7, 0x645F, + 0x93A8, 0x6460, 0x93A9, 0x6461, 0x93AA, 0x6462, 0x93AB, 0x6463, + 0x93AC, 0x6464, 0x93AD, 0x6465, 0x93AE, 0x6466, 0x93AF, 0x6468, + 0x93B0, 0x646A, 0x93B1, 0x646B, 0x93B2, 0x646C, 0x93B3, 0x646E, + 0x93B4, 0x646F, 0x93B5, 0x6470, 0x93B6, 0x6471, 0x93B7, 0x6472, + 0x93B8, 0x6473, 0x93B9, 0x6474, 0x93BA, 0x6475, 0x93BB, 0x6476, + 0x93BC, 0x6477, 0x93BD, 0x647B, 0x93BE, 0x647C, 0x93BF, 0x647D, + 0x93C0, 0x647E, 0x93C1, 0x647F, 0x93C2, 0x6480, 0x93C3, 0x6481, + 0x93C4, 0x6483, 0x93C5, 0x6486, 0x93C6, 0x6488, 0x93C7, 0x6489, + 0x93C8, 0x648A, 0x93C9, 0x648B, 0x93CA, 0x648C, 0x93CB, 0x648D, + 0x93CC, 0x648E, 0x93CD, 0x648F, 0x93CE, 0x6490, 0x93CF, 0x6493, + 0x93D0, 0x6494, 0x93D1, 0x6497, 0x93D2, 0x6498, 0x93D3, 0x649A, + 0x93D4, 0x649B, 0x93D5, 0x649C, 0x93D6, 0x649D, 0x93D7, 0x649F, + 0x93D8, 0x64A0, 0x93D9, 0x64A1, 0x93DA, 0x64A2, 0x93DB, 0x64A3, + 0x93DC, 0x64A5, 0x93DD, 0x64A6, 0x93DE, 0x64A7, 0x93DF, 0x64A8, + 0x93E0, 0x64AA, 0x93E1, 0x64AB, 0x93E2, 0x64AF, 0x93E3, 0x64B1, + 0x93E4, 0x64B2, 0x93E5, 0x64B3, 0x93E6, 0x64B4, 0x93E7, 0x64B6, + 0x93E8, 0x64B9, 0x93E9, 0x64BB, 0x93EA, 0x64BD, 0x93EB, 0x64BE, + 0x93EC, 0x64BF, 0x93ED, 0x64C1, 0x93EE, 0x64C3, 0x93EF, 0x64C4, + 0x93F0, 0x64C6, 0x93F1, 0x64C7, 0x93F2, 0x64C8, 0x93F3, 0x64C9, + 0x93F4, 0x64CA, 0x93F5, 0x64CB, 0x93F6, 0x64CC, 0x93F7, 0x64CF, + 0x93F8, 0x64D1, 0x93F9, 0x64D3, 0x93FA, 0x64D4, 0x93FB, 0x64D5, + 0x93FC, 0x64D6, 0x93FD, 0x64D9, 0x93FE, 0x64DA, 0x9440, 0x64DB, + 0x9441, 0x64DC, 0x9442, 0x64DD, 0x9443, 0x64DF, 0x9444, 0x64E0, + 0x9445, 0x64E1, 0x9446, 0x64E3, 0x9447, 0x64E5, 0x9448, 0x64E7, + 0x9449, 0x64E8, 0x944A, 0x64E9, 0x944B, 0x64EA, 0x944C, 0x64EB, + 0x944D, 0x64EC, 0x944E, 0x64ED, 0x944F, 0x64EE, 0x9450, 0x64EF, + 0x9451, 0x64F0, 0x9452, 0x64F1, 0x9453, 0x64F2, 0x9454, 0x64F3, + 0x9455, 0x64F4, 0x9456, 0x64F5, 0x9457, 0x64F6, 0x9458, 0x64F7, + 0x9459, 0x64F8, 0x945A, 0x64F9, 0x945B, 0x64FA, 0x945C, 0x64FB, + 0x945D, 0x64FC, 0x945E, 0x64FD, 0x945F, 0x64FE, 0x9460, 0x64FF, + 0x9461, 0x6501, 0x9462, 0x6502, 0x9463, 0x6503, 0x9464, 0x6504, + 0x9465, 0x6505, 0x9466, 0x6506, 0x9467, 0x6507, 0x9468, 0x6508, + 0x9469, 0x650A, 0x946A, 0x650B, 0x946B, 0x650C, 0x946C, 0x650D, + 0x946D, 0x650E, 0x946E, 0x650F, 0x946F, 0x6510, 0x9470, 0x6511, + 0x9471, 0x6513, 0x9472, 0x6514, 0x9473, 0x6515, 0x9474, 0x6516, + 0x9475, 0x6517, 0x9476, 0x6519, 0x9477, 0x651A, 0x9478, 0x651B, + 0x9479, 0x651C, 0x947A, 0x651D, 0x947B, 0x651E, 0x947C, 0x651F, + 0x947D, 0x6520, 0x947E, 0x6521, 0x9480, 0x6522, 0x9481, 0x6523, + 0x9482, 0x6524, 0x9483, 0x6526, 0x9484, 0x6527, 0x9485, 0x6528, + 0x9486, 0x6529, 0x9487, 0x652A, 0x9488, 0x652C, 0x9489, 0x652D, + 0x948A, 0x6530, 0x948B, 0x6531, 0x948C, 0x6532, 0x948D, 0x6533, + 0x948E, 0x6537, 0x948F, 0x653A, 0x9490, 0x653C, 0x9491, 0x653D, + 0x9492, 0x6540, 0x9493, 0x6541, 0x9494, 0x6542, 0x9495, 0x6543, + 0x9496, 0x6544, 0x9497, 0x6546, 0x9498, 0x6547, 0x9499, 0x654A, + 0x949A, 0x654B, 0x949B, 0x654D, 0x949C, 0x654E, 0x949D, 0x6550, + 0x949E, 0x6552, 0x949F, 0x6553, 0x94A0, 0x6554, 0x94A1, 0x6557, + 0x94A2, 0x6558, 0x94A3, 0x655A, 0x94A4, 0x655C, 0x94A5, 0x655F, + 0x94A6, 0x6560, 0x94A7, 0x6561, 0x94A8, 0x6564, 0x94A9, 0x6565, + 0x94AA, 0x6567, 0x94AB, 0x6568, 0x94AC, 0x6569, 0x94AD, 0x656A, + 0x94AE, 0x656D, 0x94AF, 0x656E, 0x94B0, 0x656F, 0x94B1, 0x6571, + 0x94B2, 0x6573, 0x94B3, 0x6575, 0x94B4, 0x6576, 0x94B5, 0x6578, + 0x94B6, 0x6579, 0x94B7, 0x657A, 0x94B8, 0x657B, 0x94B9, 0x657C, + 0x94BA, 0x657D, 0x94BB, 0x657E, 0x94BC, 0x657F, 0x94BD, 0x6580, + 0x94BE, 0x6581, 0x94BF, 0x6582, 0x94C0, 0x6583, 0x94C1, 0x6584, + 0x94C2, 0x6585, 0x94C3, 0x6586, 0x94C4, 0x6588, 0x94C5, 0x6589, + 0x94C6, 0x658A, 0x94C7, 0x658D, 0x94C8, 0x658E, 0x94C9, 0x658F, + 0x94CA, 0x6592, 0x94CB, 0x6594, 0x94CC, 0x6595, 0x94CD, 0x6596, + 0x94CE, 0x6598, 0x94CF, 0x659A, 0x94D0, 0x659D, 0x94D1, 0x659E, + 0x94D2, 0x65A0, 0x94D3, 0x65A2, 0x94D4, 0x65A3, 0x94D5, 0x65A6, + 0x94D6, 0x65A8, 0x94D7, 0x65AA, 0x94D8, 0x65AC, 0x94D9, 0x65AE, + 0x94DA, 0x65B1, 0x94DB, 0x65B2, 0x94DC, 0x65B3, 0x94DD, 0x65B4, + 0x94DE, 0x65B5, 0x94DF, 0x65B6, 0x94E0, 0x65B7, 0x94E1, 0x65B8, + 0x94E2, 0x65BA, 0x94E3, 0x65BB, 0x94E4, 0x65BE, 0x94E5, 0x65BF, + 0x94E6, 0x65C0, 0x94E7, 0x65C2, 0x94E8, 0x65C7, 0x94E9, 0x65C8, + 0x94EA, 0x65C9, 0x94EB, 0x65CA, 0x94EC, 0x65CD, 0x94ED, 0x65D0, + 0x94EE, 0x65D1, 0x94EF, 0x65D3, 0x94F0, 0x65D4, 0x94F1, 0x65D5, + 0x94F2, 0x65D8, 0x94F3, 0x65D9, 0x94F4, 0x65DA, 0x94F5, 0x65DB, + 0x94F6, 0x65DC, 0x94F7, 0x65DD, 0x94F8, 0x65DE, 0x94F9, 0x65DF, + 0x94FA, 0x65E1, 0x94FB, 0x65E3, 0x94FC, 0x65E4, 0x94FD, 0x65EA, + 0x94FE, 0x65EB, 0x9540, 0x65F2, 0x9541, 0x65F3, 0x9542, 0x65F4, + 0x9543, 0x65F5, 0x9544, 0x65F8, 0x9545, 0x65F9, 0x9546, 0x65FB, + 0x9547, 0x65FC, 0x9548, 0x65FD, 0x9549, 0x65FE, 0x954A, 0x65FF, + 0x954B, 0x6601, 0x954C, 0x6604, 0x954D, 0x6605, 0x954E, 0x6607, + 0x954F, 0x6608, 0x9550, 0x6609, 0x9551, 0x660B, 0x9552, 0x660D, + 0x9553, 0x6610, 0x9554, 0x6611, 0x9555, 0x6612, 0x9556, 0x6616, + 0x9557, 0x6617, 0x9558, 0x6618, 0x9559, 0x661A, 0x955A, 0x661B, + 0x955B, 0x661C, 0x955C, 0x661E, 0x955D, 0x6621, 0x955E, 0x6622, + 0x955F, 0x6623, 0x9560, 0x6624, 0x9561, 0x6626, 0x9562, 0x6629, + 0x9563, 0x662A, 0x9564, 0x662B, 0x9565, 0x662C, 0x9566, 0x662E, + 0x9567, 0x6630, 0x9568, 0x6632, 0x9569, 0x6633, 0x956A, 0x6637, + 0x956B, 0x6638, 0x956C, 0x6639, 0x956D, 0x663A, 0x956E, 0x663B, + 0x956F, 0x663D, 0x9570, 0x663F, 0x9571, 0x6640, 0x9572, 0x6642, + 0x9573, 0x6644, 0x9574, 0x6645, 0x9575, 0x6646, 0x9576, 0x6647, + 0x9577, 0x6648, 0x9578, 0x6649, 0x9579, 0x664A, 0x957A, 0x664D, + 0x957B, 0x664E, 0x957C, 0x6650, 0x957D, 0x6651, 0x957E, 0x6658, + 0x9580, 0x6659, 0x9581, 0x665B, 0x9582, 0x665C, 0x9583, 0x665D, + 0x9584, 0x665E, 0x9585, 0x6660, 0x9586, 0x6662, 0x9587, 0x6663, + 0x9588, 0x6665, 0x9589, 0x6667, 0x958A, 0x6669, 0x958B, 0x666A, + 0x958C, 0x666B, 0x958D, 0x666C, 0x958E, 0x666D, 0x958F, 0x6671, + 0x9590, 0x6672, 0x9591, 0x6673, 0x9592, 0x6675, 0x9593, 0x6678, + 0x9594, 0x6679, 0x9595, 0x667B, 0x9596, 0x667C, 0x9597, 0x667D, + 0x9598, 0x667F, 0x9599, 0x6680, 0x959A, 0x6681, 0x959B, 0x6683, + 0x959C, 0x6685, 0x959D, 0x6686, 0x959E, 0x6688, 0x959F, 0x6689, + 0x95A0, 0x668A, 0x95A1, 0x668B, 0x95A2, 0x668D, 0x95A3, 0x668E, + 0x95A4, 0x668F, 0x95A5, 0x6690, 0x95A6, 0x6692, 0x95A7, 0x6693, + 0x95A8, 0x6694, 0x95A9, 0x6695, 0x95AA, 0x6698, 0x95AB, 0x6699, + 0x95AC, 0x669A, 0x95AD, 0x669B, 0x95AE, 0x669C, 0x95AF, 0x669E, + 0x95B0, 0x669F, 0x95B1, 0x66A0, 0x95B2, 0x66A1, 0x95B3, 0x66A2, + 0x95B4, 0x66A3, 0x95B5, 0x66A4, 0x95B6, 0x66A5, 0x95B7, 0x66A6, + 0x95B8, 0x66A9, 0x95B9, 0x66AA, 0x95BA, 0x66AB, 0x95BB, 0x66AC, + 0x95BC, 0x66AD, 0x95BD, 0x66AF, 0x95BE, 0x66B0, 0x95BF, 0x66B1, + 0x95C0, 0x66B2, 0x95C1, 0x66B3, 0x95C2, 0x66B5, 0x95C3, 0x66B6, + 0x95C4, 0x66B7, 0x95C5, 0x66B8, 0x95C6, 0x66BA, 0x95C7, 0x66BB, + 0x95C8, 0x66BC, 0x95C9, 0x66BD, 0x95CA, 0x66BF, 0x95CB, 0x66C0, + 0x95CC, 0x66C1, 0x95CD, 0x66C2, 0x95CE, 0x66C3, 0x95CF, 0x66C4, + 0x95D0, 0x66C5, 0x95D1, 0x66C6, 0x95D2, 0x66C7, 0x95D3, 0x66C8, + 0x95D4, 0x66C9, 0x95D5, 0x66CA, 0x95D6, 0x66CB, 0x95D7, 0x66CC, + 0x95D8, 0x66CD, 0x95D9, 0x66CE, 0x95DA, 0x66CF, 0x95DB, 0x66D0, + 0x95DC, 0x66D1, 0x95DD, 0x66D2, 0x95DE, 0x66D3, 0x95DF, 0x66D4, + 0x95E0, 0x66D5, 0x95E1, 0x66D6, 0x95E2, 0x66D7, 0x95E3, 0x66D8, + 0x95E4, 0x66DA, 0x95E5, 0x66DE, 0x95E6, 0x66DF, 0x95E7, 0x66E0, + 0x95E8, 0x66E1, 0x95E9, 0x66E2, 0x95EA, 0x66E3, 0x95EB, 0x66E4, + 0x95EC, 0x66E5, 0x95ED, 0x66E7, 0x95EE, 0x66E8, 0x95EF, 0x66EA, + 0x95F0, 0x66EB, 0x95F1, 0x66EC, 0x95F2, 0x66ED, 0x95F3, 0x66EE, + 0x95F4, 0x66EF, 0x95F5, 0x66F1, 0x95F6, 0x66F5, 0x95F7, 0x66F6, + 0x95F8, 0x66F8, 0x95F9, 0x66FA, 0x95FA, 0x66FB, 0x95FB, 0x66FD, + 0x95FC, 0x6701, 0x95FD, 0x6702, 0x95FE, 0x6703, 0x9640, 0x6704, + 0x9641, 0x6705, 0x9642, 0x6706, 0x9643, 0x6707, 0x9644, 0x670C, + 0x9645, 0x670E, 0x9646, 0x670F, 0x9647, 0x6711, 0x9648, 0x6712, + 0x9649, 0x6713, 0x964A, 0x6716, 0x964B, 0x6718, 0x964C, 0x6719, + 0x964D, 0x671A, 0x964E, 0x671C, 0x964F, 0x671E, 0x9650, 0x6720, + 0x9651, 0x6721, 0x9652, 0x6722, 0x9653, 0x6723, 0x9654, 0x6724, + 0x9655, 0x6725, 0x9656, 0x6727, 0x9657, 0x6729, 0x9658, 0x672E, + 0x9659, 0x6730, 0x965A, 0x6732, 0x965B, 0x6733, 0x965C, 0x6736, + 0x965D, 0x6737, 0x965E, 0x6738, 0x965F, 0x6739, 0x9660, 0x673B, + 0x9661, 0x673C, 0x9662, 0x673E, 0x9663, 0x673F, 0x9664, 0x6741, + 0x9665, 0x6744, 0x9666, 0x6745, 0x9667, 0x6747, 0x9668, 0x674A, + 0x9669, 0x674B, 0x966A, 0x674D, 0x966B, 0x6752, 0x966C, 0x6754, + 0x966D, 0x6755, 0x966E, 0x6757, 0x966F, 0x6758, 0x9670, 0x6759, + 0x9671, 0x675A, 0x9672, 0x675B, 0x9673, 0x675D, 0x9674, 0x6762, + 0x9675, 0x6763, 0x9676, 0x6764, 0x9677, 0x6766, 0x9678, 0x6767, + 0x9679, 0x676B, 0x967A, 0x676C, 0x967B, 0x676E, 0x967C, 0x6771, + 0x967D, 0x6774, 0x967E, 0x6776, 0x9680, 0x6778, 0x9681, 0x6779, + 0x9682, 0x677A, 0x9683, 0x677B, 0x9684, 0x677D, 0x9685, 0x6780, + 0x9686, 0x6782, 0x9687, 0x6783, 0x9688, 0x6785, 0x9689, 0x6786, + 0x968A, 0x6788, 0x968B, 0x678A, 0x968C, 0x678C, 0x968D, 0x678D, + 0x968E, 0x678E, 0x968F, 0x678F, 0x9690, 0x6791, 0x9691, 0x6792, + 0x9692, 0x6793, 0x9693, 0x6794, 0x9694, 0x6796, 0x9695, 0x6799, + 0x9696, 0x679B, 0x9697, 0x679F, 0x9698, 0x67A0, 0x9699, 0x67A1, + 0x969A, 0x67A4, 0x969B, 0x67A6, 0x969C, 0x67A9, 0x969D, 0x67AC, + 0x969E, 0x67AE, 0x969F, 0x67B1, 0x96A0, 0x67B2, 0x96A1, 0x67B4, + 0x96A2, 0x67B9, 0x96A3, 0x67BA, 0x96A4, 0x67BB, 0x96A5, 0x67BC, + 0x96A6, 0x67BD, 0x96A7, 0x67BE, 0x96A8, 0x67BF, 0x96A9, 0x67C0, + 0x96AA, 0x67C2, 0x96AB, 0x67C5, 0x96AC, 0x67C6, 0x96AD, 0x67C7, + 0x96AE, 0x67C8, 0x96AF, 0x67C9, 0x96B0, 0x67CA, 0x96B1, 0x67CB, + 0x96B2, 0x67CC, 0x96B3, 0x67CD, 0x96B4, 0x67CE, 0x96B5, 0x67D5, + 0x96B6, 0x67D6, 0x96B7, 0x67D7, 0x96B8, 0x67DB, 0x96B9, 0x67DF, + 0x96BA, 0x67E1, 0x96BB, 0x67E3, 0x96BC, 0x67E4, 0x96BD, 0x67E6, + 0x96BE, 0x67E7, 0x96BF, 0x67E8, 0x96C0, 0x67EA, 0x96C1, 0x67EB, + 0x96C2, 0x67ED, 0x96C3, 0x67EE, 0x96C4, 0x67F2, 0x96C5, 0x67F5, + 0x96C6, 0x67F6, 0x96C7, 0x67F7, 0x96C8, 0x67F8, 0x96C9, 0x67F9, + 0x96CA, 0x67FA, 0x96CB, 0x67FB, 0x96CC, 0x67FC, 0x96CD, 0x67FE, + 0x96CE, 0x6801, 0x96CF, 0x6802, 0x96D0, 0x6803, 0x96D1, 0x6804, + 0x96D2, 0x6806, 0x96D3, 0x680D, 0x96D4, 0x6810, 0x96D5, 0x6812, + 0x96D6, 0x6814, 0x96D7, 0x6815, 0x96D8, 0x6818, 0x96D9, 0x6819, + 0x96DA, 0x681A, 0x96DB, 0x681B, 0x96DC, 0x681C, 0x96DD, 0x681E, + 0x96DE, 0x681F, 0x96DF, 0x6820, 0x96E0, 0x6822, 0x96E1, 0x6823, + 0x96E2, 0x6824, 0x96E3, 0x6825, 0x96E4, 0x6826, 0x96E5, 0x6827, + 0x96E6, 0x6828, 0x96E7, 0x682B, 0x96E8, 0x682C, 0x96E9, 0x682D, + 0x96EA, 0x682E, 0x96EB, 0x682F, 0x96EC, 0x6830, 0x96ED, 0x6831, + 0x96EE, 0x6834, 0x96EF, 0x6835, 0x96F0, 0x6836, 0x96F1, 0x683A, + 0x96F2, 0x683B, 0x96F3, 0x683F, 0x96F4, 0x6847, 0x96F5, 0x684B, + 0x96F6, 0x684D, 0x96F7, 0x684F, 0x96F8, 0x6852, 0x96F9, 0x6856, + 0x96FA, 0x6857, 0x96FB, 0x6858, 0x96FC, 0x6859, 0x96FD, 0x685A, + 0x96FE, 0x685B, 0x9740, 0x685C, 0x9741, 0x685D, 0x9742, 0x685E, + 0x9743, 0x685F, 0x9744, 0x686A, 0x9745, 0x686C, 0x9746, 0x686D, + 0x9747, 0x686E, 0x9748, 0x686F, 0x9749, 0x6870, 0x974A, 0x6871, + 0x974B, 0x6872, 0x974C, 0x6873, 0x974D, 0x6875, 0x974E, 0x6878, + 0x974F, 0x6879, 0x9750, 0x687A, 0x9751, 0x687B, 0x9752, 0x687C, + 0x9753, 0x687D, 0x9754, 0x687E, 0x9755, 0x687F, 0x9756, 0x6880, + 0x9757, 0x6882, 0x9758, 0x6884, 0x9759, 0x6887, 0x975A, 0x6888, + 0x975B, 0x6889, 0x975C, 0x688A, 0x975D, 0x688B, 0x975E, 0x688C, + 0x975F, 0x688D, 0x9760, 0x688E, 0x9761, 0x6890, 0x9762, 0x6891, + 0x9763, 0x6892, 0x9764, 0x6894, 0x9765, 0x6895, 0x9766, 0x6896, + 0x9767, 0x6898, 0x9768, 0x6899, 0x9769, 0x689A, 0x976A, 0x689B, + 0x976B, 0x689C, 0x976C, 0x689D, 0x976D, 0x689E, 0x976E, 0x689F, + 0x976F, 0x68A0, 0x9770, 0x68A1, 0x9771, 0x68A3, 0x9772, 0x68A4, + 0x9773, 0x68A5, 0x9774, 0x68A9, 0x9775, 0x68AA, 0x9776, 0x68AB, + 0x9777, 0x68AC, 0x9778, 0x68AE, 0x9779, 0x68B1, 0x977A, 0x68B2, + 0x977B, 0x68B4, 0x977C, 0x68B6, 0x977D, 0x68B7, 0x977E, 0x68B8, + 0x9780, 0x68B9, 0x9781, 0x68BA, 0x9782, 0x68BB, 0x9783, 0x68BC, + 0x9784, 0x68BD, 0x9785, 0x68BE, 0x9786, 0x68BF, 0x9787, 0x68C1, + 0x9788, 0x68C3, 0x9789, 0x68C4, 0x978A, 0x68C5, 0x978B, 0x68C6, + 0x978C, 0x68C7, 0x978D, 0x68C8, 0x978E, 0x68CA, 0x978F, 0x68CC, + 0x9790, 0x68CE, 0x9791, 0x68CF, 0x9792, 0x68D0, 0x9793, 0x68D1, + 0x9794, 0x68D3, 0x9795, 0x68D4, 0x9796, 0x68D6, 0x9797, 0x68D7, + 0x9798, 0x68D9, 0x9799, 0x68DB, 0x979A, 0x68DC, 0x979B, 0x68DD, + 0x979C, 0x68DE, 0x979D, 0x68DF, 0x979E, 0x68E1, 0x979F, 0x68E2, + 0x97A0, 0x68E4, 0x97A1, 0x68E5, 0x97A2, 0x68E6, 0x97A3, 0x68E7, + 0x97A4, 0x68E8, 0x97A5, 0x68E9, 0x97A6, 0x68EA, 0x97A7, 0x68EB, + 0x97A8, 0x68EC, 0x97A9, 0x68ED, 0x97AA, 0x68EF, 0x97AB, 0x68F2, + 0x97AC, 0x68F3, 0x97AD, 0x68F4, 0x97AE, 0x68F6, 0x97AF, 0x68F7, + 0x97B0, 0x68F8, 0x97B1, 0x68FB, 0x97B2, 0x68FD, 0x97B3, 0x68FE, + 0x97B4, 0x68FF, 0x97B5, 0x6900, 0x97B6, 0x6902, 0x97B7, 0x6903, + 0x97B8, 0x6904, 0x97B9, 0x6906, 0x97BA, 0x6907, 0x97BB, 0x6908, + 0x97BC, 0x6909, 0x97BD, 0x690A, 0x97BE, 0x690C, 0x97BF, 0x690F, + 0x97C0, 0x6911, 0x97C1, 0x6913, 0x97C2, 0x6914, 0x97C3, 0x6915, + 0x97C4, 0x6916, 0x97C5, 0x6917, 0x97C6, 0x6918, 0x97C7, 0x6919, + 0x97C8, 0x691A, 0x97C9, 0x691B, 0x97CA, 0x691C, 0x97CB, 0x691D, + 0x97CC, 0x691E, 0x97CD, 0x6921, 0x97CE, 0x6922, 0x97CF, 0x6923, + 0x97D0, 0x6925, 0x97D1, 0x6926, 0x97D2, 0x6927, 0x97D3, 0x6928, + 0x97D4, 0x6929, 0x97D5, 0x692A, 0x97D6, 0x692B, 0x97D7, 0x692C, + 0x97D8, 0x692E, 0x97D9, 0x692F, 0x97DA, 0x6931, 0x97DB, 0x6932, + 0x97DC, 0x6933, 0x97DD, 0x6935, 0x97DE, 0x6936, 0x97DF, 0x6937, + 0x97E0, 0x6938, 0x97E1, 0x693A, 0x97E2, 0x693B, 0x97E3, 0x693C, + 0x97E4, 0x693E, 0x97E5, 0x6940, 0x97E6, 0x6941, 0x97E7, 0x6943, + 0x97E8, 0x6944, 0x97E9, 0x6945, 0x97EA, 0x6946, 0x97EB, 0x6947, + 0x97EC, 0x6948, 0x97ED, 0x6949, 0x97EE, 0x694A, 0x97EF, 0x694B, + 0x97F0, 0x694C, 0x97F1, 0x694D, 0x97F2, 0x694E, 0x97F3, 0x694F, + 0x97F4, 0x6950, 0x97F5, 0x6951, 0x97F6, 0x6952, 0x97F7, 0x6953, + 0x97F8, 0x6955, 0x97F9, 0x6956, 0x97FA, 0x6958, 0x97FB, 0x6959, + 0x97FC, 0x695B, 0x97FD, 0x695C, 0x97FE, 0x695F, 0x9840, 0x6961, + 0x9841, 0x6962, 0x9842, 0x6964, 0x9843, 0x6965, 0x9844, 0x6967, + 0x9845, 0x6968, 0x9846, 0x6969, 0x9847, 0x696A, 0x9848, 0x696C, + 0x9849, 0x696D, 0x984A, 0x696F, 0x984B, 0x6970, 0x984C, 0x6972, + 0x984D, 0x6973, 0x984E, 0x6974, 0x984F, 0x6975, 0x9850, 0x6976, + 0x9851, 0x697A, 0x9852, 0x697B, 0x9853, 0x697D, 0x9854, 0x697E, + 0x9855, 0x697F, 0x9856, 0x6981, 0x9857, 0x6983, 0x9858, 0x6985, + 0x9859, 0x698A, 0x985A, 0x698B, 0x985B, 0x698C, 0x985C, 0x698E, + 0x985D, 0x698F, 0x985E, 0x6990, 0x985F, 0x6991, 0x9860, 0x6992, + 0x9861, 0x6993, 0x9862, 0x6996, 0x9863, 0x6997, 0x9864, 0x6999, + 0x9865, 0x699A, 0x9866, 0x699D, 0x9867, 0x699E, 0x9868, 0x699F, + 0x9869, 0x69A0, 0x986A, 0x69A1, 0x986B, 0x69A2, 0x986C, 0x69A3, + 0x986D, 0x69A4, 0x986E, 0x69A5, 0x986F, 0x69A6, 0x9870, 0x69A9, + 0x9871, 0x69AA, 0x9872, 0x69AC, 0x9873, 0x69AE, 0x9874, 0x69AF, + 0x9875, 0x69B0, 0x9876, 0x69B2, 0x9877, 0x69B3, 0x9878, 0x69B5, + 0x9879, 0x69B6, 0x987A, 0x69B8, 0x987B, 0x69B9, 0x987C, 0x69BA, + 0x987D, 0x69BC, 0x987E, 0x69BD, 0x9880, 0x69BE, 0x9881, 0x69BF, + 0x9882, 0x69C0, 0x9883, 0x69C2, 0x9884, 0x69C3, 0x9885, 0x69C4, + 0x9886, 0x69C5, 0x9887, 0x69C6, 0x9888, 0x69C7, 0x9889, 0x69C8, + 0x988A, 0x69C9, 0x988B, 0x69CB, 0x988C, 0x69CD, 0x988D, 0x69CF, + 0x988E, 0x69D1, 0x988F, 0x69D2, 0x9890, 0x69D3, 0x9891, 0x69D5, + 0x9892, 0x69D6, 0x9893, 0x69D7, 0x9894, 0x69D8, 0x9895, 0x69D9, + 0x9896, 0x69DA, 0x9897, 0x69DC, 0x9898, 0x69DD, 0x9899, 0x69DE, + 0x989A, 0x69E1, 0x989B, 0x69E2, 0x989C, 0x69E3, 0x989D, 0x69E4, + 0x989E, 0x69E5, 0x989F, 0x69E6, 0x98A0, 0x69E7, 0x98A1, 0x69E8, + 0x98A2, 0x69E9, 0x98A3, 0x69EA, 0x98A4, 0x69EB, 0x98A5, 0x69EC, + 0x98A6, 0x69EE, 0x98A7, 0x69EF, 0x98A8, 0x69F0, 0x98A9, 0x69F1, + 0x98AA, 0x69F3, 0x98AB, 0x69F4, 0x98AC, 0x69F5, 0x98AD, 0x69F6, + 0x98AE, 0x69F7, 0x98AF, 0x69F8, 0x98B0, 0x69F9, 0x98B1, 0x69FA, + 0x98B2, 0x69FB, 0x98B3, 0x69FC, 0x98B4, 0x69FE, 0x98B5, 0x6A00, + 0x98B6, 0x6A01, 0x98B7, 0x6A02, 0x98B8, 0x6A03, 0x98B9, 0x6A04, + 0x98BA, 0x6A05, 0x98BB, 0x6A06, 0x98BC, 0x6A07, 0x98BD, 0x6A08, + 0x98BE, 0x6A09, 0x98BF, 0x6A0B, 0x98C0, 0x6A0C, 0x98C1, 0x6A0D, + 0x98C2, 0x6A0E, 0x98C3, 0x6A0F, 0x98C4, 0x6A10, 0x98C5, 0x6A11, + 0x98C6, 0x6A12, 0x98C7, 0x6A13, 0x98C8, 0x6A14, 0x98C9, 0x6A15, + 0x98CA, 0x6A16, 0x98CB, 0x6A19, 0x98CC, 0x6A1A, 0x98CD, 0x6A1B, + 0x98CE, 0x6A1C, 0x98CF, 0x6A1D, 0x98D0, 0x6A1E, 0x98D1, 0x6A20, + 0x98D2, 0x6A22, 0x98D3, 0x6A23, 0x98D4, 0x6A24, 0x98D5, 0x6A25, + 0x98D6, 0x6A26, 0x98D7, 0x6A27, 0x98D8, 0x6A29, 0x98D9, 0x6A2B, + 0x98DA, 0x6A2C, 0x98DB, 0x6A2D, 0x98DC, 0x6A2E, 0x98DD, 0x6A30, + 0x98DE, 0x6A32, 0x98DF, 0x6A33, 0x98E0, 0x6A34, 0x98E1, 0x6A36, + 0x98E2, 0x6A37, 0x98E3, 0x6A38, 0x98E4, 0x6A39, 0x98E5, 0x6A3A, + 0x98E6, 0x6A3B, 0x98E7, 0x6A3C, 0x98E8, 0x6A3F, 0x98E9, 0x6A40, + 0x98EA, 0x6A41, 0x98EB, 0x6A42, 0x98EC, 0x6A43, 0x98ED, 0x6A45, + 0x98EE, 0x6A46, 0x98EF, 0x6A48, 0x98F0, 0x6A49, 0x98F1, 0x6A4A, + 0x98F2, 0x6A4B, 0x98F3, 0x6A4C, 0x98F4, 0x6A4D, 0x98F5, 0x6A4E, + 0x98F6, 0x6A4F, 0x98F7, 0x6A51, 0x98F8, 0x6A52, 0x98F9, 0x6A53, + 0x98FA, 0x6A54, 0x98FB, 0x6A55, 0x98FC, 0x6A56, 0x98FD, 0x6A57, + 0x98FE, 0x6A5A, 0x9940, 0x6A5C, 0x9941, 0x6A5D, 0x9942, 0x6A5E, + 0x9943, 0x6A5F, 0x9944, 0x6A60, 0x9945, 0x6A62, 0x9946, 0x6A63, + 0x9947, 0x6A64, 0x9948, 0x6A66, 0x9949, 0x6A67, 0x994A, 0x6A68, + 0x994B, 0x6A69, 0x994C, 0x6A6A, 0x994D, 0x6A6B, 0x994E, 0x6A6C, + 0x994F, 0x6A6D, 0x9950, 0x6A6E, 0x9951, 0x6A6F, 0x9952, 0x6A70, + 0x9953, 0x6A72, 0x9954, 0x6A73, 0x9955, 0x6A74, 0x9956, 0x6A75, + 0x9957, 0x6A76, 0x9958, 0x6A77, 0x9959, 0x6A78, 0x995A, 0x6A7A, + 0x995B, 0x6A7B, 0x995C, 0x6A7D, 0x995D, 0x6A7E, 0x995E, 0x6A7F, + 0x995F, 0x6A81, 0x9960, 0x6A82, 0x9961, 0x6A83, 0x9962, 0x6A85, + 0x9963, 0x6A86, 0x9964, 0x6A87, 0x9965, 0x6A88, 0x9966, 0x6A89, + 0x9967, 0x6A8A, 0x9968, 0x6A8B, 0x9969, 0x6A8C, 0x996A, 0x6A8D, + 0x996B, 0x6A8F, 0x996C, 0x6A92, 0x996D, 0x6A93, 0x996E, 0x6A94, + 0x996F, 0x6A95, 0x9970, 0x6A96, 0x9971, 0x6A98, 0x9972, 0x6A99, + 0x9973, 0x6A9A, 0x9974, 0x6A9B, 0x9975, 0x6A9C, 0x9976, 0x6A9D, + 0x9977, 0x6A9E, 0x9978, 0x6A9F, 0x9979, 0x6AA1, 0x997A, 0x6AA2, + 0x997B, 0x6AA3, 0x997C, 0x6AA4, 0x997D, 0x6AA5, 0x997E, 0x6AA6, + 0x9980, 0x6AA7, 0x9981, 0x6AA8, 0x9982, 0x6AAA, 0x9983, 0x6AAD, + 0x9984, 0x6AAE, 0x9985, 0x6AAF, 0x9986, 0x6AB0, 0x9987, 0x6AB1, + 0x9988, 0x6AB2, 0x9989, 0x6AB3, 0x998A, 0x6AB4, 0x998B, 0x6AB5, + 0x998C, 0x6AB6, 0x998D, 0x6AB7, 0x998E, 0x6AB8, 0x998F, 0x6AB9, + 0x9990, 0x6ABA, 0x9991, 0x6ABB, 0x9992, 0x6ABC, 0x9993, 0x6ABD, + 0x9994, 0x6ABE, 0x9995, 0x6ABF, 0x9996, 0x6AC0, 0x9997, 0x6AC1, + 0x9998, 0x6AC2, 0x9999, 0x6AC3, 0x999A, 0x6AC4, 0x999B, 0x6AC5, + 0x999C, 0x6AC6, 0x999D, 0x6AC7, 0x999E, 0x6AC8, 0x999F, 0x6AC9, + 0x99A0, 0x6ACA, 0x99A1, 0x6ACB, 0x99A2, 0x6ACC, 0x99A3, 0x6ACD, + 0x99A4, 0x6ACE, 0x99A5, 0x6ACF, 0x99A6, 0x6AD0, 0x99A7, 0x6AD1, + 0x99A8, 0x6AD2, 0x99A9, 0x6AD3, 0x99AA, 0x6AD4, 0x99AB, 0x6AD5, + 0x99AC, 0x6AD6, 0x99AD, 0x6AD7, 0x99AE, 0x6AD8, 0x99AF, 0x6AD9, + 0x99B0, 0x6ADA, 0x99B1, 0x6ADB, 0x99B2, 0x6ADC, 0x99B3, 0x6ADD, + 0x99B4, 0x6ADE, 0x99B5, 0x6ADF, 0x99B6, 0x6AE0, 0x99B7, 0x6AE1, + 0x99B8, 0x6AE2, 0x99B9, 0x6AE3, 0x99BA, 0x6AE4, 0x99BB, 0x6AE5, + 0x99BC, 0x6AE6, 0x99BD, 0x6AE7, 0x99BE, 0x6AE8, 0x99BF, 0x6AE9, + 0x99C0, 0x6AEA, 0x99C1, 0x6AEB, 0x99C2, 0x6AEC, 0x99C3, 0x6AED, + 0x99C4, 0x6AEE, 0x99C5, 0x6AEF, 0x99C6, 0x6AF0, 0x99C7, 0x6AF1, + 0x99C8, 0x6AF2, 0x99C9, 0x6AF3, 0x99CA, 0x6AF4, 0x99CB, 0x6AF5, + 0x99CC, 0x6AF6, 0x99CD, 0x6AF7, 0x99CE, 0x6AF8, 0x99CF, 0x6AF9, + 0x99D0, 0x6AFA, 0x99D1, 0x6AFB, 0x99D2, 0x6AFC, 0x99D3, 0x6AFD, + 0x99D4, 0x6AFE, 0x99D5, 0x6AFF, 0x99D6, 0x6B00, 0x99D7, 0x6B01, + 0x99D8, 0x6B02, 0x99D9, 0x6B03, 0x99DA, 0x6B04, 0x99DB, 0x6B05, + 0x99DC, 0x6B06, 0x99DD, 0x6B07, 0x99DE, 0x6B08, 0x99DF, 0x6B09, + 0x99E0, 0x6B0A, 0x99E1, 0x6B0B, 0x99E2, 0x6B0C, 0x99E3, 0x6B0D, + 0x99E4, 0x6B0E, 0x99E5, 0x6B0F, 0x99E6, 0x6B10, 0x99E7, 0x6B11, + 0x99E8, 0x6B12, 0x99E9, 0x6B13, 0x99EA, 0x6B14, 0x99EB, 0x6B15, + 0x99EC, 0x6B16, 0x99ED, 0x6B17, 0x99EE, 0x6B18, 0x99EF, 0x6B19, + 0x99F0, 0x6B1A, 0x99F1, 0x6B1B, 0x99F2, 0x6B1C, 0x99F3, 0x6B1D, + 0x99F4, 0x6B1E, 0x99F5, 0x6B1F, 0x99F6, 0x6B25, 0x99F7, 0x6B26, + 0x99F8, 0x6B28, 0x99F9, 0x6B29, 0x99FA, 0x6B2A, 0x99FB, 0x6B2B, + 0x99FC, 0x6B2C, 0x99FD, 0x6B2D, 0x99FE, 0x6B2E, 0x9A40, 0x6B2F, + 0x9A41, 0x6B30, 0x9A42, 0x6B31, 0x9A43, 0x6B33, 0x9A44, 0x6B34, + 0x9A45, 0x6B35, 0x9A46, 0x6B36, 0x9A47, 0x6B38, 0x9A48, 0x6B3B, + 0x9A49, 0x6B3C, 0x9A4A, 0x6B3D, 0x9A4B, 0x6B3F, 0x9A4C, 0x6B40, + 0x9A4D, 0x6B41, 0x9A4E, 0x6B42, 0x9A4F, 0x6B44, 0x9A50, 0x6B45, + 0x9A51, 0x6B48, 0x9A52, 0x6B4A, 0x9A53, 0x6B4B, 0x9A54, 0x6B4D, + 0x9A55, 0x6B4E, 0x9A56, 0x6B4F, 0x9A57, 0x6B50, 0x9A58, 0x6B51, + 0x9A59, 0x6B52, 0x9A5A, 0x6B53, 0x9A5B, 0x6B54, 0x9A5C, 0x6B55, + 0x9A5D, 0x6B56, 0x9A5E, 0x6B57, 0x9A5F, 0x6B58, 0x9A60, 0x6B5A, + 0x9A61, 0x6B5B, 0x9A62, 0x6B5C, 0x9A63, 0x6B5D, 0x9A64, 0x6B5E, + 0x9A65, 0x6B5F, 0x9A66, 0x6B60, 0x9A67, 0x6B61, 0x9A68, 0x6B68, + 0x9A69, 0x6B69, 0x9A6A, 0x6B6B, 0x9A6B, 0x6B6C, 0x9A6C, 0x6B6D, + 0x9A6D, 0x6B6E, 0x9A6E, 0x6B6F, 0x9A6F, 0x6B70, 0x9A70, 0x6B71, + 0x9A71, 0x6B72, 0x9A72, 0x6B73, 0x9A73, 0x6B74, 0x9A74, 0x6B75, + 0x9A75, 0x6B76, 0x9A76, 0x6B77, 0x9A77, 0x6B78, 0x9A78, 0x6B7A, + 0x9A79, 0x6B7D, 0x9A7A, 0x6B7E, 0x9A7B, 0x6B7F, 0x9A7C, 0x6B80, + 0x9A7D, 0x6B85, 0x9A7E, 0x6B88, 0x9A80, 0x6B8C, 0x9A81, 0x6B8E, + 0x9A82, 0x6B8F, 0x9A83, 0x6B90, 0x9A84, 0x6B91, 0x9A85, 0x6B94, + 0x9A86, 0x6B95, 0x9A87, 0x6B97, 0x9A88, 0x6B98, 0x9A89, 0x6B99, + 0x9A8A, 0x6B9C, 0x9A8B, 0x6B9D, 0x9A8C, 0x6B9E, 0x9A8D, 0x6B9F, + 0x9A8E, 0x6BA0, 0x9A8F, 0x6BA2, 0x9A90, 0x6BA3, 0x9A91, 0x6BA4, + 0x9A92, 0x6BA5, 0x9A93, 0x6BA6, 0x9A94, 0x6BA7, 0x9A95, 0x6BA8, + 0x9A96, 0x6BA9, 0x9A97, 0x6BAB, 0x9A98, 0x6BAC, 0x9A99, 0x6BAD, + 0x9A9A, 0x6BAE, 0x9A9B, 0x6BAF, 0x9A9C, 0x6BB0, 0x9A9D, 0x6BB1, + 0x9A9E, 0x6BB2, 0x9A9F, 0x6BB6, 0x9AA0, 0x6BB8, 0x9AA1, 0x6BB9, + 0x9AA2, 0x6BBA, 0x9AA3, 0x6BBB, 0x9AA4, 0x6BBC, 0x9AA5, 0x6BBD, + 0x9AA6, 0x6BBE, 0x9AA7, 0x6BC0, 0x9AA8, 0x6BC3, 0x9AA9, 0x6BC4, + 0x9AAA, 0x6BC6, 0x9AAB, 0x6BC7, 0x9AAC, 0x6BC8, 0x9AAD, 0x6BC9, + 0x9AAE, 0x6BCA, 0x9AAF, 0x6BCC, 0x9AB0, 0x6BCE, 0x9AB1, 0x6BD0, + 0x9AB2, 0x6BD1, 0x9AB3, 0x6BD8, 0x9AB4, 0x6BDA, 0x9AB5, 0x6BDC, + 0x9AB6, 0x6BDD, 0x9AB7, 0x6BDE, 0x9AB8, 0x6BDF, 0x9AB9, 0x6BE0, + 0x9ABA, 0x6BE2, 0x9ABB, 0x6BE3, 0x9ABC, 0x6BE4, 0x9ABD, 0x6BE5, + 0x9ABE, 0x6BE6, 0x9ABF, 0x6BE7, 0x9AC0, 0x6BE8, 0x9AC1, 0x6BE9, + 0x9AC2, 0x6BEC, 0x9AC3, 0x6BED, 0x9AC4, 0x6BEE, 0x9AC5, 0x6BF0, + 0x9AC6, 0x6BF1, 0x9AC7, 0x6BF2, 0x9AC8, 0x6BF4, 0x9AC9, 0x6BF6, + 0x9ACA, 0x6BF7, 0x9ACB, 0x6BF8, 0x9ACC, 0x6BFA, 0x9ACD, 0x6BFB, + 0x9ACE, 0x6BFC, 0x9ACF, 0x6BFE, 0x9AD0, 0x6BFF, 0x9AD1, 0x6C00, + 0x9AD2, 0x6C01, 0x9AD3, 0x6C02, 0x9AD4, 0x6C03, 0x9AD5, 0x6C04, + 0x9AD6, 0x6C08, 0x9AD7, 0x6C09, 0x9AD8, 0x6C0A, 0x9AD9, 0x6C0B, + 0x9ADA, 0x6C0C, 0x9ADB, 0x6C0E, 0x9ADC, 0x6C12, 0x9ADD, 0x6C17, + 0x9ADE, 0x6C1C, 0x9ADF, 0x6C1D, 0x9AE0, 0x6C1E, 0x9AE1, 0x6C20, + 0x9AE2, 0x6C23, 0x9AE3, 0x6C25, 0x9AE4, 0x6C2B, 0x9AE5, 0x6C2C, + 0x9AE6, 0x6C2D, 0x9AE7, 0x6C31, 0x9AE8, 0x6C33, 0x9AE9, 0x6C36, + 0x9AEA, 0x6C37, 0x9AEB, 0x6C39, 0x9AEC, 0x6C3A, 0x9AED, 0x6C3B, + 0x9AEE, 0x6C3C, 0x9AEF, 0x6C3E, 0x9AF0, 0x6C3F, 0x9AF1, 0x6C43, + 0x9AF2, 0x6C44, 0x9AF3, 0x6C45, 0x9AF4, 0x6C48, 0x9AF5, 0x6C4B, + 0x9AF6, 0x6C4C, 0x9AF7, 0x6C4D, 0x9AF8, 0x6C4E, 0x9AF9, 0x6C4F, + 0x9AFA, 0x6C51, 0x9AFB, 0x6C52, 0x9AFC, 0x6C53, 0x9AFD, 0x6C56, + 0x9AFE, 0x6C58, 0x9B40, 0x6C59, 0x9B41, 0x6C5A, 0x9B42, 0x6C62, + 0x9B43, 0x6C63, 0x9B44, 0x6C65, 0x9B45, 0x6C66, 0x9B46, 0x6C67, + 0x9B47, 0x6C6B, 0x9B48, 0x6C6C, 0x9B49, 0x6C6D, 0x9B4A, 0x6C6E, + 0x9B4B, 0x6C6F, 0x9B4C, 0x6C71, 0x9B4D, 0x6C73, 0x9B4E, 0x6C75, + 0x9B4F, 0x6C77, 0x9B50, 0x6C78, 0x9B51, 0x6C7A, 0x9B52, 0x6C7B, + 0x9B53, 0x6C7C, 0x9B54, 0x6C7F, 0x9B55, 0x6C80, 0x9B56, 0x6C84, + 0x9B57, 0x6C87, 0x9B58, 0x6C8A, 0x9B59, 0x6C8B, 0x9B5A, 0x6C8D, + 0x9B5B, 0x6C8E, 0x9B5C, 0x6C91, 0x9B5D, 0x6C92, 0x9B5E, 0x6C95, + 0x9B5F, 0x6C96, 0x9B60, 0x6C97, 0x9B61, 0x6C98, 0x9B62, 0x6C9A, + 0x9B63, 0x6C9C, 0x9B64, 0x6C9D, 0x9B65, 0x6C9E, 0x9B66, 0x6CA0, + 0x9B67, 0x6CA2, 0x9B68, 0x6CA8, 0x9B69, 0x6CAC, 0x9B6A, 0x6CAF, + 0x9B6B, 0x6CB0, 0x9B6C, 0x6CB4, 0x9B6D, 0x6CB5, 0x9B6E, 0x6CB6, + 0x9B6F, 0x6CB7, 0x9B70, 0x6CBA, 0x9B71, 0x6CC0, 0x9B72, 0x6CC1, + 0x9B73, 0x6CC2, 0x9B74, 0x6CC3, 0x9B75, 0x6CC6, 0x9B76, 0x6CC7, + 0x9B77, 0x6CC8, 0x9B78, 0x6CCB, 0x9B79, 0x6CCD, 0x9B7A, 0x6CCE, + 0x9B7B, 0x6CCF, 0x9B7C, 0x6CD1, 0x9B7D, 0x6CD2, 0x9B7E, 0x6CD8, + 0x9B80, 0x6CD9, 0x9B81, 0x6CDA, 0x9B82, 0x6CDC, 0x9B83, 0x6CDD, + 0x9B84, 0x6CDF, 0x9B85, 0x6CE4, 0x9B86, 0x6CE6, 0x9B87, 0x6CE7, + 0x9B88, 0x6CE9, 0x9B89, 0x6CEC, 0x9B8A, 0x6CED, 0x9B8B, 0x6CF2, + 0x9B8C, 0x6CF4, 0x9B8D, 0x6CF9, 0x9B8E, 0x6CFF, 0x9B8F, 0x6D00, + 0x9B90, 0x6D02, 0x9B91, 0x6D03, 0x9B92, 0x6D05, 0x9B93, 0x6D06, + 0x9B94, 0x6D08, 0x9B95, 0x6D09, 0x9B96, 0x6D0A, 0x9B97, 0x6D0D, + 0x9B98, 0x6D0F, 0x9B99, 0x6D10, 0x9B9A, 0x6D11, 0x9B9B, 0x6D13, + 0x9B9C, 0x6D14, 0x9B9D, 0x6D15, 0x9B9E, 0x6D16, 0x9B9F, 0x6D18, + 0x9BA0, 0x6D1C, 0x9BA1, 0x6D1D, 0x9BA2, 0x6D1F, 0x9BA3, 0x6D20, + 0x9BA4, 0x6D21, 0x9BA5, 0x6D22, 0x9BA6, 0x6D23, 0x9BA7, 0x6D24, + 0x9BA8, 0x6D26, 0x9BA9, 0x6D28, 0x9BAA, 0x6D29, 0x9BAB, 0x6D2C, + 0x9BAC, 0x6D2D, 0x9BAD, 0x6D2F, 0x9BAE, 0x6D30, 0x9BAF, 0x6D34, + 0x9BB0, 0x6D36, 0x9BB1, 0x6D37, 0x9BB2, 0x6D38, 0x9BB3, 0x6D3A, + 0x9BB4, 0x6D3F, 0x9BB5, 0x6D40, 0x9BB6, 0x6D42, 0x9BB7, 0x6D44, + 0x9BB8, 0x6D49, 0x9BB9, 0x6D4C, 0x9BBA, 0x6D50, 0x9BBB, 0x6D55, + 0x9BBC, 0x6D56, 0x9BBD, 0x6D57, 0x9BBE, 0x6D58, 0x9BBF, 0x6D5B, + 0x9BC0, 0x6D5D, 0x9BC1, 0x6D5F, 0x9BC2, 0x6D61, 0x9BC3, 0x6D62, + 0x9BC4, 0x6D64, 0x9BC5, 0x6D65, 0x9BC6, 0x6D67, 0x9BC7, 0x6D68, + 0x9BC8, 0x6D6B, 0x9BC9, 0x6D6C, 0x9BCA, 0x6D6D, 0x9BCB, 0x6D70, + 0x9BCC, 0x6D71, 0x9BCD, 0x6D72, 0x9BCE, 0x6D73, 0x9BCF, 0x6D75, + 0x9BD0, 0x6D76, 0x9BD1, 0x6D79, 0x9BD2, 0x6D7A, 0x9BD3, 0x6D7B, + 0x9BD4, 0x6D7D, 0x9BD5, 0x6D7E, 0x9BD6, 0x6D7F, 0x9BD7, 0x6D80, + 0x9BD8, 0x6D81, 0x9BD9, 0x6D83, 0x9BDA, 0x6D84, 0x9BDB, 0x6D86, + 0x9BDC, 0x6D87, 0x9BDD, 0x6D8A, 0x9BDE, 0x6D8B, 0x9BDF, 0x6D8D, + 0x9BE0, 0x6D8F, 0x9BE1, 0x6D90, 0x9BE2, 0x6D92, 0x9BE3, 0x6D96, + 0x9BE4, 0x6D97, 0x9BE5, 0x6D98, 0x9BE6, 0x6D99, 0x9BE7, 0x6D9A, + 0x9BE8, 0x6D9C, 0x9BE9, 0x6DA2, 0x9BEA, 0x6DA5, 0x9BEB, 0x6DAC, + 0x9BEC, 0x6DAD, 0x9BED, 0x6DB0, 0x9BEE, 0x6DB1, 0x9BEF, 0x6DB3, + 0x9BF0, 0x6DB4, 0x9BF1, 0x6DB6, 0x9BF2, 0x6DB7, 0x9BF3, 0x6DB9, + 0x9BF4, 0x6DBA, 0x9BF5, 0x6DBB, 0x9BF6, 0x6DBC, 0x9BF7, 0x6DBD, + 0x9BF8, 0x6DBE, 0x9BF9, 0x6DC1, 0x9BFA, 0x6DC2, 0x9BFB, 0x6DC3, + 0x9BFC, 0x6DC8, 0x9BFD, 0x6DC9, 0x9BFE, 0x6DCA, 0x9C40, 0x6DCD, + 0x9C41, 0x6DCE, 0x9C42, 0x6DCF, 0x9C43, 0x6DD0, 0x9C44, 0x6DD2, + 0x9C45, 0x6DD3, 0x9C46, 0x6DD4, 0x9C47, 0x6DD5, 0x9C48, 0x6DD7, + 0x9C49, 0x6DDA, 0x9C4A, 0x6DDB, 0x9C4B, 0x6DDC, 0x9C4C, 0x6DDF, + 0x9C4D, 0x6DE2, 0x9C4E, 0x6DE3, 0x9C4F, 0x6DE5, 0x9C50, 0x6DE7, + 0x9C51, 0x6DE8, 0x9C52, 0x6DE9, 0x9C53, 0x6DEA, 0x9C54, 0x6DED, + 0x9C55, 0x6DEF, 0x9C56, 0x6DF0, 0x9C57, 0x6DF2, 0x9C58, 0x6DF4, + 0x9C59, 0x6DF5, 0x9C5A, 0x6DF6, 0x9C5B, 0x6DF8, 0x9C5C, 0x6DFA, + 0x9C5D, 0x6DFD, 0x9C5E, 0x6DFE, 0x9C5F, 0x6DFF, 0x9C60, 0x6E00, + 0x9C61, 0x6E01, 0x9C62, 0x6E02, 0x9C63, 0x6E03, 0x9C64, 0x6E04, + 0x9C65, 0x6E06, 0x9C66, 0x6E07, 0x9C67, 0x6E08, 0x9C68, 0x6E09, + 0x9C69, 0x6E0B, 0x9C6A, 0x6E0F, 0x9C6B, 0x6E12, 0x9C6C, 0x6E13, + 0x9C6D, 0x6E15, 0x9C6E, 0x6E18, 0x9C6F, 0x6E19, 0x9C70, 0x6E1B, + 0x9C71, 0x6E1C, 0x9C72, 0x6E1E, 0x9C73, 0x6E1F, 0x9C74, 0x6E22, + 0x9C75, 0x6E26, 0x9C76, 0x6E27, 0x9C77, 0x6E28, 0x9C78, 0x6E2A, + 0x9C79, 0x6E2C, 0x9C7A, 0x6E2E, 0x9C7B, 0x6E30, 0x9C7C, 0x6E31, + 0x9C7D, 0x6E33, 0x9C7E, 0x6E35, 0x9C80, 0x6E36, 0x9C81, 0x6E37, + 0x9C82, 0x6E39, 0x9C83, 0x6E3B, 0x9C84, 0x6E3C, 0x9C85, 0x6E3D, + 0x9C86, 0x6E3E, 0x9C87, 0x6E3F, 0x9C88, 0x6E40, 0x9C89, 0x6E41, + 0x9C8A, 0x6E42, 0x9C8B, 0x6E45, 0x9C8C, 0x6E46, 0x9C8D, 0x6E47, + 0x9C8E, 0x6E48, 0x9C8F, 0x6E49, 0x9C90, 0x6E4A, 0x9C91, 0x6E4B, + 0x9C92, 0x6E4C, 0x9C93, 0x6E4F, 0x9C94, 0x6E50, 0x9C95, 0x6E51, + 0x9C96, 0x6E52, 0x9C97, 0x6E55, 0x9C98, 0x6E57, 0x9C99, 0x6E59, + 0x9C9A, 0x6E5A, 0x9C9B, 0x6E5C, 0x9C9C, 0x6E5D, 0x9C9D, 0x6E5E, + 0x9C9E, 0x6E60, 0x9C9F, 0x6E61, 0x9CA0, 0x6E62, 0x9CA1, 0x6E63, + 0x9CA2, 0x6E64, 0x9CA3, 0x6E65, 0x9CA4, 0x6E66, 0x9CA5, 0x6E67, + 0x9CA6, 0x6E68, 0x9CA7, 0x6E69, 0x9CA8, 0x6E6A, 0x9CA9, 0x6E6C, + 0x9CAA, 0x6E6D, 0x9CAB, 0x6E6F, 0x9CAC, 0x6E70, 0x9CAD, 0x6E71, + 0x9CAE, 0x6E72, 0x9CAF, 0x6E73, 0x9CB0, 0x6E74, 0x9CB1, 0x6E75, + 0x9CB2, 0x6E76, 0x9CB3, 0x6E77, 0x9CB4, 0x6E78, 0x9CB5, 0x6E79, + 0x9CB6, 0x6E7A, 0x9CB7, 0x6E7B, 0x9CB8, 0x6E7C, 0x9CB9, 0x6E7D, + 0x9CBA, 0x6E80, 0x9CBB, 0x6E81, 0x9CBC, 0x6E82, 0x9CBD, 0x6E84, + 0x9CBE, 0x6E87, 0x9CBF, 0x6E88, 0x9CC0, 0x6E8A, 0x9CC1, 0x6E8B, + 0x9CC2, 0x6E8C, 0x9CC3, 0x6E8D, 0x9CC4, 0x6E8E, 0x9CC5, 0x6E91, + 0x9CC6, 0x6E92, 0x9CC7, 0x6E93, 0x9CC8, 0x6E94, 0x9CC9, 0x6E95, + 0x9CCA, 0x6E96, 0x9CCB, 0x6E97, 0x9CCC, 0x6E99, 0x9CCD, 0x6E9A, + 0x9CCE, 0x6E9B, 0x9CCF, 0x6E9D, 0x9CD0, 0x6E9E, 0x9CD1, 0x6EA0, + 0x9CD2, 0x6EA1, 0x9CD3, 0x6EA3, 0x9CD4, 0x6EA4, 0x9CD5, 0x6EA6, + 0x9CD6, 0x6EA8, 0x9CD7, 0x6EA9, 0x9CD8, 0x6EAB, 0x9CD9, 0x6EAC, + 0x9CDA, 0x6EAD, 0x9CDB, 0x6EAE, 0x9CDC, 0x6EB0, 0x9CDD, 0x6EB3, + 0x9CDE, 0x6EB5, 0x9CDF, 0x6EB8, 0x9CE0, 0x6EB9, 0x9CE1, 0x6EBC, + 0x9CE2, 0x6EBE, 0x9CE3, 0x6EBF, 0x9CE4, 0x6EC0, 0x9CE5, 0x6EC3, + 0x9CE6, 0x6EC4, 0x9CE7, 0x6EC5, 0x9CE8, 0x6EC6, 0x9CE9, 0x6EC8, + 0x9CEA, 0x6EC9, 0x9CEB, 0x6ECA, 0x9CEC, 0x6ECC, 0x9CED, 0x6ECD, + 0x9CEE, 0x6ECE, 0x9CEF, 0x6ED0, 0x9CF0, 0x6ED2, 0x9CF1, 0x6ED6, + 0x9CF2, 0x6ED8, 0x9CF3, 0x6ED9, 0x9CF4, 0x6EDB, 0x9CF5, 0x6EDC, + 0x9CF6, 0x6EDD, 0x9CF7, 0x6EE3, 0x9CF8, 0x6EE7, 0x9CF9, 0x6EEA, + 0x9CFA, 0x6EEB, 0x9CFB, 0x6EEC, 0x9CFC, 0x6EED, 0x9CFD, 0x6EEE, + 0x9CFE, 0x6EEF, 0x9D40, 0x6EF0, 0x9D41, 0x6EF1, 0x9D42, 0x6EF2, + 0x9D43, 0x6EF3, 0x9D44, 0x6EF5, 0x9D45, 0x6EF6, 0x9D46, 0x6EF7, + 0x9D47, 0x6EF8, 0x9D48, 0x6EFA, 0x9D49, 0x6EFB, 0x9D4A, 0x6EFC, + 0x9D4B, 0x6EFD, 0x9D4C, 0x6EFE, 0x9D4D, 0x6EFF, 0x9D4E, 0x6F00, + 0x9D4F, 0x6F01, 0x9D50, 0x6F03, 0x9D51, 0x6F04, 0x9D52, 0x6F05, + 0x9D53, 0x6F07, 0x9D54, 0x6F08, 0x9D55, 0x6F0A, 0x9D56, 0x6F0B, + 0x9D57, 0x6F0C, 0x9D58, 0x6F0D, 0x9D59, 0x6F0E, 0x9D5A, 0x6F10, + 0x9D5B, 0x6F11, 0x9D5C, 0x6F12, 0x9D5D, 0x6F16, 0x9D5E, 0x6F17, + 0x9D5F, 0x6F18, 0x9D60, 0x6F19, 0x9D61, 0x6F1A, 0x9D62, 0x6F1B, + 0x9D63, 0x6F1C, 0x9D64, 0x6F1D, 0x9D65, 0x6F1E, 0x9D66, 0x6F1F, + 0x9D67, 0x6F21, 0x9D68, 0x6F22, 0x9D69, 0x6F23, 0x9D6A, 0x6F25, + 0x9D6B, 0x6F26, 0x9D6C, 0x6F27, 0x9D6D, 0x6F28, 0x9D6E, 0x6F2C, + 0x9D6F, 0x6F2E, 0x9D70, 0x6F30, 0x9D71, 0x6F32, 0x9D72, 0x6F34, + 0x9D73, 0x6F35, 0x9D74, 0x6F37, 0x9D75, 0x6F38, 0x9D76, 0x6F39, + 0x9D77, 0x6F3A, 0x9D78, 0x6F3B, 0x9D79, 0x6F3C, 0x9D7A, 0x6F3D, + 0x9D7B, 0x6F3F, 0x9D7C, 0x6F40, 0x9D7D, 0x6F41, 0x9D7E, 0x6F42, + 0x9D80, 0x6F43, 0x9D81, 0x6F44, 0x9D82, 0x6F45, 0x9D83, 0x6F48, + 0x9D84, 0x6F49, 0x9D85, 0x6F4A, 0x9D86, 0x6F4C, 0x9D87, 0x6F4E, + 0x9D88, 0x6F4F, 0x9D89, 0x6F50, 0x9D8A, 0x6F51, 0x9D8B, 0x6F52, + 0x9D8C, 0x6F53, 0x9D8D, 0x6F54, 0x9D8E, 0x6F55, 0x9D8F, 0x6F56, + 0x9D90, 0x6F57, 0x9D91, 0x6F59, 0x9D92, 0x6F5A, 0x9D93, 0x6F5B, + 0x9D94, 0x6F5D, 0x9D95, 0x6F5F, 0x9D96, 0x6F60, 0x9D97, 0x6F61, + 0x9D98, 0x6F63, 0x9D99, 0x6F64, 0x9D9A, 0x6F65, 0x9D9B, 0x6F67, + 0x9D9C, 0x6F68, 0x9D9D, 0x6F69, 0x9D9E, 0x6F6A, 0x9D9F, 0x6F6B, + 0x9DA0, 0x6F6C, 0x9DA1, 0x6F6F, 0x9DA2, 0x6F70, 0x9DA3, 0x6F71, + 0x9DA4, 0x6F73, 0x9DA5, 0x6F75, 0x9DA6, 0x6F76, 0x9DA7, 0x6F77, + 0x9DA8, 0x6F79, 0x9DA9, 0x6F7B, 0x9DAA, 0x6F7D, 0x9DAB, 0x6F7E, + 0x9DAC, 0x6F7F, 0x9DAD, 0x6F80, 0x9DAE, 0x6F81, 0x9DAF, 0x6F82, + 0x9DB0, 0x6F83, 0x9DB1, 0x6F85, 0x9DB2, 0x6F86, 0x9DB3, 0x6F87, + 0x9DB4, 0x6F8A, 0x9DB5, 0x6F8B, 0x9DB6, 0x6F8F, 0x9DB7, 0x6F90, + 0x9DB8, 0x6F91, 0x9DB9, 0x6F92, 0x9DBA, 0x6F93, 0x9DBB, 0x6F94, + 0x9DBC, 0x6F95, 0x9DBD, 0x6F96, 0x9DBE, 0x6F97, 0x9DBF, 0x6F98, + 0x9DC0, 0x6F99, 0x9DC1, 0x6F9A, 0x9DC2, 0x6F9B, 0x9DC3, 0x6F9D, + 0x9DC4, 0x6F9E, 0x9DC5, 0x6F9F, 0x9DC6, 0x6FA0, 0x9DC7, 0x6FA2, + 0x9DC8, 0x6FA3, 0x9DC9, 0x6FA4, 0x9DCA, 0x6FA5, 0x9DCB, 0x6FA6, + 0x9DCC, 0x6FA8, 0x9DCD, 0x6FA9, 0x9DCE, 0x6FAA, 0x9DCF, 0x6FAB, + 0x9DD0, 0x6FAC, 0x9DD1, 0x6FAD, 0x9DD2, 0x6FAE, 0x9DD3, 0x6FAF, + 0x9DD4, 0x6FB0, 0x9DD5, 0x6FB1, 0x9DD6, 0x6FB2, 0x9DD7, 0x6FB4, + 0x9DD8, 0x6FB5, 0x9DD9, 0x6FB7, 0x9DDA, 0x6FB8, 0x9DDB, 0x6FBA, + 0x9DDC, 0x6FBB, 0x9DDD, 0x6FBC, 0x9DDE, 0x6FBD, 0x9DDF, 0x6FBE, + 0x9DE0, 0x6FBF, 0x9DE1, 0x6FC1, 0x9DE2, 0x6FC3, 0x9DE3, 0x6FC4, + 0x9DE4, 0x6FC5, 0x9DE5, 0x6FC6, 0x9DE6, 0x6FC7, 0x9DE7, 0x6FC8, + 0x9DE8, 0x6FCA, 0x9DE9, 0x6FCB, 0x9DEA, 0x6FCC, 0x9DEB, 0x6FCD, + 0x9DEC, 0x6FCE, 0x9DED, 0x6FCF, 0x9DEE, 0x6FD0, 0x9DEF, 0x6FD3, + 0x9DF0, 0x6FD4, 0x9DF1, 0x6FD5, 0x9DF2, 0x6FD6, 0x9DF3, 0x6FD7, + 0x9DF4, 0x6FD8, 0x9DF5, 0x6FD9, 0x9DF6, 0x6FDA, 0x9DF7, 0x6FDB, + 0x9DF8, 0x6FDC, 0x9DF9, 0x6FDD, 0x9DFA, 0x6FDF, 0x9DFB, 0x6FE2, + 0x9DFC, 0x6FE3, 0x9DFD, 0x6FE4, 0x9DFE, 0x6FE5, 0x9E40, 0x6FE6, + 0x9E41, 0x6FE7, 0x9E42, 0x6FE8, 0x9E43, 0x6FE9, 0x9E44, 0x6FEA, + 0x9E45, 0x6FEB, 0x9E46, 0x6FEC, 0x9E47, 0x6FED, 0x9E48, 0x6FF0, + 0x9E49, 0x6FF1, 0x9E4A, 0x6FF2, 0x9E4B, 0x6FF3, 0x9E4C, 0x6FF4, + 0x9E4D, 0x6FF5, 0x9E4E, 0x6FF6, 0x9E4F, 0x6FF7, 0x9E50, 0x6FF8, + 0x9E51, 0x6FF9, 0x9E52, 0x6FFA, 0x9E53, 0x6FFB, 0x9E54, 0x6FFC, + 0x9E55, 0x6FFD, 0x9E56, 0x6FFE, 0x9E57, 0x6FFF, 0x9E58, 0x7000, + 0x9E59, 0x7001, 0x9E5A, 0x7002, 0x9E5B, 0x7003, 0x9E5C, 0x7004, + 0x9E5D, 0x7005, 0x9E5E, 0x7006, 0x9E5F, 0x7007, 0x9E60, 0x7008, + 0x9E61, 0x7009, 0x9E62, 0x700A, 0x9E63, 0x700B, 0x9E64, 0x700C, + 0x9E65, 0x700D, 0x9E66, 0x700E, 0x9E67, 0x700F, 0x9E68, 0x7010, + 0x9E69, 0x7012, 0x9E6A, 0x7013, 0x9E6B, 0x7014, 0x9E6C, 0x7015, + 0x9E6D, 0x7016, 0x9E6E, 0x7017, 0x9E6F, 0x7018, 0x9E70, 0x7019, + 0x9E71, 0x701C, 0x9E72, 0x701D, 0x9E73, 0x701E, 0x9E74, 0x701F, + 0x9E75, 0x7020, 0x9E76, 0x7021, 0x9E77, 0x7022, 0x9E78, 0x7024, + 0x9E79, 0x7025, 0x9E7A, 0x7026, 0x9E7B, 0x7027, 0x9E7C, 0x7028, + 0x9E7D, 0x7029, 0x9E7E, 0x702A, 0x9E80, 0x702B, 0x9E81, 0x702C, + 0x9E82, 0x702D, 0x9E83, 0x702E, 0x9E84, 0x702F, 0x9E85, 0x7030, + 0x9E86, 0x7031, 0x9E87, 0x7032, 0x9E88, 0x7033, 0x9E89, 0x7034, + 0x9E8A, 0x7036, 0x9E8B, 0x7037, 0x9E8C, 0x7038, 0x9E8D, 0x703A, + 0x9E8E, 0x703B, 0x9E8F, 0x703C, 0x9E90, 0x703D, 0x9E91, 0x703E, + 0x9E92, 0x703F, 0x9E93, 0x7040, 0x9E94, 0x7041, 0x9E95, 0x7042, + 0x9E96, 0x7043, 0x9E97, 0x7044, 0x9E98, 0x7045, 0x9E99, 0x7046, + 0x9E9A, 0x7047, 0x9E9B, 0x7048, 0x9E9C, 0x7049, 0x9E9D, 0x704A, + 0x9E9E, 0x704B, 0x9E9F, 0x704D, 0x9EA0, 0x704E, 0x9EA1, 0x7050, + 0x9EA2, 0x7051, 0x9EA3, 0x7052, 0x9EA4, 0x7053, 0x9EA5, 0x7054, + 0x9EA6, 0x7055, 0x9EA7, 0x7056, 0x9EA8, 0x7057, 0x9EA9, 0x7058, + 0x9EAA, 0x7059, 0x9EAB, 0x705A, 0x9EAC, 0x705B, 0x9EAD, 0x705C, + 0x9EAE, 0x705D, 0x9EAF, 0x705F, 0x9EB0, 0x7060, 0x9EB1, 0x7061, + 0x9EB2, 0x7062, 0x9EB3, 0x7063, 0x9EB4, 0x7064, 0x9EB5, 0x7065, + 0x9EB6, 0x7066, 0x9EB7, 0x7067, 0x9EB8, 0x7068, 0x9EB9, 0x7069, + 0x9EBA, 0x706A, 0x9EBB, 0x706E, 0x9EBC, 0x7071, 0x9EBD, 0x7072, + 0x9EBE, 0x7073, 0x9EBF, 0x7074, 0x9EC0, 0x7077, 0x9EC1, 0x7079, + 0x9EC2, 0x707A, 0x9EC3, 0x707B, 0x9EC4, 0x707D, 0x9EC5, 0x7081, + 0x9EC6, 0x7082, 0x9EC7, 0x7083, 0x9EC8, 0x7084, 0x9EC9, 0x7086, + 0x9ECA, 0x7087, 0x9ECB, 0x7088, 0x9ECC, 0x708B, 0x9ECD, 0x708C, + 0x9ECE, 0x708D, 0x9ECF, 0x708F, 0x9ED0, 0x7090, 0x9ED1, 0x7091, + 0x9ED2, 0x7093, 0x9ED3, 0x7097, 0x9ED4, 0x7098, 0x9ED5, 0x709A, + 0x9ED6, 0x709B, 0x9ED7, 0x709E, 0x9ED8, 0x709F, 0x9ED9, 0x70A0, + 0x9EDA, 0x70A1, 0x9EDB, 0x70A2, 0x9EDC, 0x70A3, 0x9EDD, 0x70A4, + 0x9EDE, 0x70A5, 0x9EDF, 0x70A6, 0x9EE0, 0x70A7, 0x9EE1, 0x70A8, + 0x9EE2, 0x70A9, 0x9EE3, 0x70AA, 0x9EE4, 0x70B0, 0x9EE5, 0x70B2, + 0x9EE6, 0x70B4, 0x9EE7, 0x70B5, 0x9EE8, 0x70B6, 0x9EE9, 0x70BA, + 0x9EEA, 0x70BE, 0x9EEB, 0x70BF, 0x9EEC, 0x70C4, 0x9EED, 0x70C5, + 0x9EEE, 0x70C6, 0x9EEF, 0x70C7, 0x9EF0, 0x70C9, 0x9EF1, 0x70CB, + 0x9EF2, 0x70CC, 0x9EF3, 0x70CD, 0x9EF4, 0x70CE, 0x9EF5, 0x70CF, + 0x9EF6, 0x70D0, 0x9EF7, 0x70D1, 0x9EF8, 0x70D2, 0x9EF9, 0x70D3, + 0x9EFA, 0x70D4, 0x9EFB, 0x70D5, 0x9EFC, 0x70D6, 0x9EFD, 0x70D7, + 0x9EFE, 0x70DA, 0x9F40, 0x70DC, 0x9F41, 0x70DD, 0x9F42, 0x70DE, + 0x9F43, 0x70E0, 0x9F44, 0x70E1, 0x9F45, 0x70E2, 0x9F46, 0x70E3, + 0x9F47, 0x70E5, 0x9F48, 0x70EA, 0x9F49, 0x70EE, 0x9F4A, 0x70F0, + 0x9F4B, 0x70F1, 0x9F4C, 0x70F2, 0x9F4D, 0x70F3, 0x9F4E, 0x70F4, + 0x9F4F, 0x70F5, 0x9F50, 0x70F6, 0x9F51, 0x70F8, 0x9F52, 0x70FA, + 0x9F53, 0x70FB, 0x9F54, 0x70FC, 0x9F55, 0x70FE, 0x9F56, 0x70FF, + 0x9F57, 0x7100, 0x9F58, 0x7101, 0x9F59, 0x7102, 0x9F5A, 0x7103, + 0x9F5B, 0x7104, 0x9F5C, 0x7105, 0x9F5D, 0x7106, 0x9F5E, 0x7107, + 0x9F5F, 0x7108, 0x9F60, 0x710B, 0x9F61, 0x710C, 0x9F62, 0x710D, + 0x9F63, 0x710E, 0x9F64, 0x710F, 0x9F65, 0x7111, 0x9F66, 0x7112, + 0x9F67, 0x7114, 0x9F68, 0x7117, 0x9F69, 0x711B, 0x9F6A, 0x711C, + 0x9F6B, 0x711D, 0x9F6C, 0x711E, 0x9F6D, 0x711F, 0x9F6E, 0x7120, + 0x9F6F, 0x7121, 0x9F70, 0x7122, 0x9F71, 0x7123, 0x9F72, 0x7124, + 0x9F73, 0x7125, 0x9F74, 0x7127, 0x9F75, 0x7128, 0x9F76, 0x7129, + 0x9F77, 0x712A, 0x9F78, 0x712B, 0x9F79, 0x712C, 0x9F7A, 0x712D, + 0x9F7B, 0x712E, 0x9F7C, 0x7132, 0x9F7D, 0x7133, 0x9F7E, 0x7134, + 0x9F80, 0x7135, 0x9F81, 0x7137, 0x9F82, 0x7138, 0x9F83, 0x7139, + 0x9F84, 0x713A, 0x9F85, 0x713B, 0x9F86, 0x713C, 0x9F87, 0x713D, + 0x9F88, 0x713E, 0x9F89, 0x713F, 0x9F8A, 0x7140, 0x9F8B, 0x7141, + 0x9F8C, 0x7142, 0x9F8D, 0x7143, 0x9F8E, 0x7144, 0x9F8F, 0x7146, + 0x9F90, 0x7147, 0x9F91, 0x7148, 0x9F92, 0x7149, 0x9F93, 0x714B, + 0x9F94, 0x714D, 0x9F95, 0x714F, 0x9F96, 0x7150, 0x9F97, 0x7151, + 0x9F98, 0x7152, 0x9F99, 0x7153, 0x9F9A, 0x7154, 0x9F9B, 0x7155, + 0x9F9C, 0x7156, 0x9F9D, 0x7157, 0x9F9E, 0x7158, 0x9F9F, 0x7159, + 0x9FA0, 0x715A, 0x9FA1, 0x715B, 0x9FA2, 0x715D, 0x9FA3, 0x715F, + 0x9FA4, 0x7160, 0x9FA5, 0x7161, 0x9FA6, 0x7162, 0x9FA7, 0x7163, + 0x9FA8, 0x7165, 0x9FA9, 0x7169, 0x9FAA, 0x716A, 0x9FAB, 0x716B, + 0x9FAC, 0x716C, 0x9FAD, 0x716D, 0x9FAE, 0x716F, 0x9FAF, 0x7170, + 0x9FB0, 0x7171, 0x9FB1, 0x7174, 0x9FB2, 0x7175, 0x9FB3, 0x7176, + 0x9FB4, 0x7177, 0x9FB5, 0x7179, 0x9FB6, 0x717B, 0x9FB7, 0x717C, + 0x9FB8, 0x717E, 0x9FB9, 0x717F, 0x9FBA, 0x7180, 0x9FBB, 0x7181, + 0x9FBC, 0x7182, 0x9FBD, 0x7183, 0x9FBE, 0x7185, 0x9FBF, 0x7186, + 0x9FC0, 0x7187, 0x9FC1, 0x7188, 0x9FC2, 0x7189, 0x9FC3, 0x718B, + 0x9FC4, 0x718C, 0x9FC5, 0x718D, 0x9FC6, 0x718E, 0x9FC7, 0x7190, + 0x9FC8, 0x7191, 0x9FC9, 0x7192, 0x9FCA, 0x7193, 0x9FCB, 0x7195, + 0x9FCC, 0x7196, 0x9FCD, 0x7197, 0x9FCE, 0x719A, 0x9FCF, 0x719B, + 0x9FD0, 0x719C, 0x9FD1, 0x719D, 0x9FD2, 0x719E, 0x9FD3, 0x71A1, + 0x9FD4, 0x71A2, 0x9FD5, 0x71A3, 0x9FD6, 0x71A4, 0x9FD7, 0x71A5, + 0x9FD8, 0x71A6, 0x9FD9, 0x71A7, 0x9FDA, 0x71A9, 0x9FDB, 0x71AA, + 0x9FDC, 0x71AB, 0x9FDD, 0x71AD, 0x9FDE, 0x71AE, 0x9FDF, 0x71AF, + 0x9FE0, 0x71B0, 0x9FE1, 0x71B1, 0x9FE2, 0x71B2, 0x9FE3, 0x71B4, + 0x9FE4, 0x71B6, 0x9FE5, 0x71B7, 0x9FE6, 0x71B8, 0x9FE7, 0x71BA, + 0x9FE8, 0x71BB, 0x9FE9, 0x71BC, 0x9FEA, 0x71BD, 0x9FEB, 0x71BE, + 0x9FEC, 0x71BF, 0x9FED, 0x71C0, 0x9FEE, 0x71C1, 0x9FEF, 0x71C2, + 0x9FF0, 0x71C4, 0x9FF1, 0x71C5, 0x9FF2, 0x71C6, 0x9FF3, 0x71C7, + 0x9FF4, 0x71C8, 0x9FF5, 0x71C9, 0x9FF6, 0x71CA, 0x9FF7, 0x71CB, + 0x9FF8, 0x71CC, 0x9FF9, 0x71CD, 0x9FFA, 0x71CF, 0x9FFB, 0x71D0, + 0x9FFC, 0x71D1, 0x9FFD, 0x71D2, 0x9FFE, 0x71D3, 0xA040, 0x71D6, + 0xA041, 0x71D7, 0xA042, 0x71D8, 0xA043, 0x71D9, 0xA044, 0x71DA, + 0xA045, 0x71DB, 0xA046, 0x71DC, 0xA047, 0x71DD, 0xA048, 0x71DE, + 0xA049, 0x71DF, 0xA04A, 0x71E1, 0xA04B, 0x71E2, 0xA04C, 0x71E3, + 0xA04D, 0x71E4, 0xA04E, 0x71E6, 0xA04F, 0x71E8, 0xA050, 0x71E9, + 0xA051, 0x71EA, 0xA052, 0x71EB, 0xA053, 0x71EC, 0xA054, 0x71ED, + 0xA055, 0x71EF, 0xA056, 0x71F0, 0xA057, 0x71F1, 0xA058, 0x71F2, + 0xA059, 0x71F3, 0xA05A, 0x71F4, 0xA05B, 0x71F5, 0xA05C, 0x71F6, + 0xA05D, 0x71F7, 0xA05E, 0x71F8, 0xA05F, 0x71FA, 0xA060, 0x71FB, + 0xA061, 0x71FC, 0xA062, 0x71FD, 0xA063, 0x71FE, 0xA064, 0x71FF, + 0xA065, 0x7200, 0xA066, 0x7201, 0xA067, 0x7202, 0xA068, 0x7203, + 0xA069, 0x7204, 0xA06A, 0x7205, 0xA06B, 0x7207, 0xA06C, 0x7208, + 0xA06D, 0x7209, 0xA06E, 0x720A, 0xA06F, 0x720B, 0xA070, 0x720C, + 0xA071, 0x720D, 0xA072, 0x720E, 0xA073, 0x720F, 0xA074, 0x7210, + 0xA075, 0x7211, 0xA076, 0x7212, 0xA077, 0x7213, 0xA078, 0x7214, + 0xA079, 0x7215, 0xA07A, 0x7216, 0xA07B, 0x7217, 0xA07C, 0x7218, + 0xA07D, 0x7219, 0xA07E, 0x721A, 0xA080, 0x721B, 0xA081, 0x721C, + 0xA082, 0x721E, 0xA083, 0x721F, 0xA084, 0x7220, 0xA085, 0x7221, + 0xA086, 0x7222, 0xA087, 0x7223, 0xA088, 0x7224, 0xA089, 0x7225, + 0xA08A, 0x7226, 0xA08B, 0x7227, 0xA08C, 0x7229, 0xA08D, 0x722B, + 0xA08E, 0x722D, 0xA08F, 0x722E, 0xA090, 0x722F, 0xA091, 0x7232, + 0xA092, 0x7233, 0xA093, 0x7234, 0xA094, 0x723A, 0xA095, 0x723C, + 0xA096, 0x723E, 0xA097, 0x7240, 0xA098, 0x7241, 0xA099, 0x7242, + 0xA09A, 0x7243, 0xA09B, 0x7244, 0xA09C, 0x7245, 0xA09D, 0x7246, + 0xA09E, 0x7249, 0xA09F, 0x724A, 0xA0A0, 0x724B, 0xA0A1, 0x724E, + 0xA0A2, 0x724F, 0xA0A3, 0x7250, 0xA0A4, 0x7251, 0xA0A5, 0x7253, + 0xA0A6, 0x7254, 0xA0A7, 0x7255, 0xA0A8, 0x7257, 0xA0A9, 0x7258, + 0xA0AA, 0x725A, 0xA0AB, 0x725C, 0xA0AC, 0x725E, 0xA0AD, 0x7260, + 0xA0AE, 0x7263, 0xA0AF, 0x7264, 0xA0B0, 0x7265, 0xA0B1, 0x7268, + 0xA0B2, 0x726A, 0xA0B3, 0x726B, 0xA0B4, 0x726C, 0xA0B5, 0x726D, + 0xA0B6, 0x7270, 0xA0B7, 0x7271, 0xA0B8, 0x7273, 0xA0B9, 0x7274, + 0xA0BA, 0x7276, 0xA0BB, 0x7277, 0xA0BC, 0x7278, 0xA0BD, 0x727B, + 0xA0BE, 0x727C, 0xA0BF, 0x727D, 0xA0C0, 0x7282, 0xA0C1, 0x7283, + 0xA0C2, 0x7285, 0xA0C3, 0x7286, 0xA0C4, 0x7287, 0xA0C5, 0x7288, + 0xA0C6, 0x7289, 0xA0C7, 0x728C, 0xA0C8, 0x728E, 0xA0C9, 0x7290, + 0xA0CA, 0x7291, 0xA0CB, 0x7293, 0xA0CC, 0x7294, 0xA0CD, 0x7295, + 0xA0CE, 0x7296, 0xA0CF, 0x7297, 0xA0D0, 0x7298, 0xA0D1, 0x7299, + 0xA0D2, 0x729A, 0xA0D3, 0x729B, 0xA0D4, 0x729C, 0xA0D5, 0x729D, + 0xA0D6, 0x729E, 0xA0D7, 0x72A0, 0xA0D8, 0x72A1, 0xA0D9, 0x72A2, + 0xA0DA, 0x72A3, 0xA0DB, 0x72A4, 0xA0DC, 0x72A5, 0xA0DD, 0x72A6, + 0xA0DE, 0x72A7, 0xA0DF, 0x72A8, 0xA0E0, 0x72A9, 0xA0E1, 0x72AA, + 0xA0E2, 0x72AB, 0xA0E3, 0x72AE, 0xA0E4, 0x72B1, 0xA0E5, 0x72B2, + 0xA0E6, 0x72B3, 0xA0E7, 0x72B5, 0xA0E8, 0x72BA, 0xA0E9, 0x72BB, + 0xA0EA, 0x72BC, 0xA0EB, 0x72BD, 0xA0EC, 0x72BE, 0xA0ED, 0x72BF, + 0xA0EE, 0x72C0, 0xA0EF, 0x72C5, 0xA0F0, 0x72C6, 0xA0F1, 0x72C7, + 0xA0F2, 0x72C9, 0xA0F3, 0x72CA, 0xA0F4, 0x72CB, 0xA0F5, 0x72CC, + 0xA0F6, 0x72CF, 0xA0F7, 0x72D1, 0xA0F8, 0x72D3, 0xA0F9, 0x72D4, + 0xA0FA, 0x72D5, 0xA0FB, 0x72D6, 0xA0FC, 0x72D8, 0xA0FD, 0x72DA, + 0xA0FE, 0x72DB, 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, + 0xA1A4, 0x00B7, 0xA1A5, 0x02C9, 0xA1A6, 0x02C7, 0xA1A7, 0x00A8, + 0xA1A8, 0x3003, 0xA1A9, 0x3005, 0xA1AA, 0x2014, 0xA1AB, 0xFF5E, + 0xA1AC, 0x2016, 0xA1AD, 0x2026, 0xA1AE, 0x2018, 0xA1AF, 0x2019, + 0xA1B0, 0x201C, 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, + 0xA1B4, 0x3008, 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, + 0xA1B8, 0x300C, 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, + 0xA1BC, 0x3016, 0xA1BD, 0x3017, 0xA1BE, 0x3010, 0xA1BF, 0x3011, + 0xA1C0, 0x00B1, 0xA1C1, 0x00D7, 0xA1C2, 0x00F7, 0xA1C3, 0x2236, + 0xA1C4, 0x2227, 0xA1C5, 0x2228, 0xA1C6, 0x2211, 0xA1C7, 0x220F, + 0xA1C8, 0x222A, 0xA1C9, 0x2229, 0xA1CA, 0x2208, 0xA1CB, 0x2237, + 0xA1CC, 0x221A, 0xA1CD, 0x22A5, 0xA1CE, 0x2225, 0xA1CF, 0x2220, + 0xA1D0, 0x2312, 0xA1D1, 0x2299, 0xA1D2, 0x222B, 0xA1D3, 0x222E, + 0xA1D4, 0x2261, 0xA1D5, 0x224C, 0xA1D6, 0x2248, 0xA1D7, 0x223D, + 0xA1D8, 0x221D, 0xA1D9, 0x2260, 0xA1DA, 0x226E, 0xA1DB, 0x226F, + 0xA1DC, 0x2264, 0xA1DD, 0x2265, 0xA1DE, 0x221E, 0xA1DF, 0x2235, + 0xA1E0, 0x2234, 0xA1E1, 0x2642, 0xA1E2, 0x2640, 0xA1E3, 0x00B0, + 0xA1E4, 0x2032, 0xA1E5, 0x2033, 0xA1E6, 0x2103, 0xA1E7, 0xFF04, + 0xA1E8, 0x00A4, 0xA1E9, 0xFFE0, 0xA1EA, 0xFFE1, 0xA1EB, 0x2030, + 0xA1EC, 0x00A7, 0xA1ED, 0x2116, 0xA1EE, 0x2606, 0xA1EF, 0x2605, + 0xA1F0, 0x25CB, 0xA1F1, 0x25CF, 0xA1F2, 0x25CE, 0xA1F3, 0x25C7, + 0xA1F4, 0x25C6, 0xA1F5, 0x25A1, 0xA1F6, 0x25A0, 0xA1F7, 0x25B3, + 0xA1F8, 0x25B2, 0xA1F9, 0x203B, 0xA1FA, 0x2192, 0xA1FB, 0x2190, + 0xA1FC, 0x2191, 0xA1FD, 0x2193, 0xA1FE, 0x3013, 0xA2A1, 0x2170, + 0xA2A2, 0x2171, 0xA2A3, 0x2172, 0xA2A4, 0x2173, 0xA2A5, 0x2174, + 0xA2A6, 0x2175, 0xA2A7, 0x2176, 0xA2A8, 0x2177, 0xA2A9, 0x2178, + 0xA2AA, 0x2179, 0xA2B1, 0x2488, 0xA2B2, 0x2489, 0xA2B3, 0x248A, + 0xA2B4, 0x248B, 0xA2B5, 0x248C, 0xA2B6, 0x248D, 0xA2B7, 0x248E, + 0xA2B8, 0x248F, 0xA2B9, 0x2490, 0xA2BA, 0x2491, 0xA2BB, 0x2492, + 0xA2BC, 0x2493, 0xA2BD, 0x2494, 0xA2BE, 0x2495, 0xA2BF, 0x2496, + 0xA2C0, 0x2497, 0xA2C1, 0x2498, 0xA2C2, 0x2499, 0xA2C3, 0x249A, + 0xA2C4, 0x249B, 0xA2C5, 0x2474, 0xA2C6, 0x2475, 0xA2C7, 0x2476, + 0xA2C8, 0x2477, 0xA2C9, 0x2478, 0xA2CA, 0x2479, 0xA2CB, 0x247A, + 0xA2CC, 0x247B, 0xA2CD, 0x247C, 0xA2CE, 0x247D, 0xA2CF, 0x247E, + 0xA2D0, 0x247F, 0xA2D1, 0x2480, 0xA2D2, 0x2481, 0xA2D3, 0x2482, + 0xA2D4, 0x2483, 0xA2D5, 0x2484, 0xA2D6, 0x2485, 0xA2D7, 0x2486, + 0xA2D8, 0x2487, 0xA2D9, 0x2460, 0xA2DA, 0x2461, 0xA2DB, 0x2462, + 0xA2DC, 0x2463, 0xA2DD, 0x2464, 0xA2DE, 0x2465, 0xA2DF, 0x2466, + 0xA2E0, 0x2467, 0xA2E1, 0x2468, 0xA2E2, 0x2469, 0xA2E5, 0x3220, + 0xA2E6, 0x3221, 0xA2E7, 0x3222, 0xA2E8, 0x3223, 0xA2E9, 0x3224, + 0xA2EA, 0x3225, 0xA2EB, 0x3226, 0xA2EC, 0x3227, 0xA2ED, 0x3228, + 0xA2EE, 0x3229, 0xA2F1, 0x2160, 0xA2F2, 0x2161, 0xA2F3, 0x2162, + 0xA2F4, 0x2163, 0xA2F5, 0x2164, 0xA2F6, 0x2165, 0xA2F7, 0x2166, + 0xA2F8, 0x2167, 0xA2F9, 0x2168, 0xA2FA, 0x2169, 0xA2FB, 0x216A, + 0xA2FC, 0x216B, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, + 0xA3A4, 0xFFE5, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, + 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, + 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, + 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, + 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, + 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, + 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, + 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, + 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, + 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, + 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, + 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, + 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, + 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, + 0xA3DC, 0xFF3C, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, + 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, + 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, + 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, + 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, + 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, + 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, + 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, + 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA4A1, 0x3041, + 0xA4A2, 0x3042, 0xA4A3, 0x3043, 0xA4A4, 0x3044, 0xA4A5, 0x3045, + 0xA4A6, 0x3046, 0xA4A7, 0x3047, 0xA4A8, 0x3048, 0xA4A9, 0x3049, + 0xA4AA, 0x304A, 0xA4AB, 0x304B, 0xA4AC, 0x304C, 0xA4AD, 0x304D, + 0xA4AE, 0x304E, 0xA4AF, 0x304F, 0xA4B0, 0x3050, 0xA4B1, 0x3051, + 0xA4B2, 0x3052, 0xA4B3, 0x3053, 0xA4B4, 0x3054, 0xA4B5, 0x3055, + 0xA4B6, 0x3056, 0xA4B7, 0x3057, 0xA4B8, 0x3058, 0xA4B9, 0x3059, + 0xA4BA, 0x305A, 0xA4BB, 0x305B, 0xA4BC, 0x305C, 0xA4BD, 0x305D, + 0xA4BE, 0x305E, 0xA4BF, 0x305F, 0xA4C0, 0x3060, 0xA4C1, 0x3061, + 0xA4C2, 0x3062, 0xA4C3, 0x3063, 0xA4C4, 0x3064, 0xA4C5, 0x3065, + 0xA4C6, 0x3066, 0xA4C7, 0x3067, 0xA4C8, 0x3068, 0xA4C9, 0x3069, + 0xA4CA, 0x306A, 0xA4CB, 0x306B, 0xA4CC, 0x306C, 0xA4CD, 0x306D, + 0xA4CE, 0x306E, 0xA4CF, 0x306F, 0xA4D0, 0x3070, 0xA4D1, 0x3071, + 0xA4D2, 0x3072, 0xA4D3, 0x3073, 0xA4D4, 0x3074, 0xA4D5, 0x3075, + 0xA4D6, 0x3076, 0xA4D7, 0x3077, 0xA4D8, 0x3078, 0xA4D9, 0x3079, + 0xA4DA, 0x307A, 0xA4DB, 0x307B, 0xA4DC, 0x307C, 0xA4DD, 0x307D, + 0xA4DE, 0x307E, 0xA4DF, 0x307F, 0xA4E0, 0x3080, 0xA4E1, 0x3081, + 0xA4E2, 0x3082, 0xA4E3, 0x3083, 0xA4E4, 0x3084, 0xA4E5, 0x3085, + 0xA4E6, 0x3086, 0xA4E7, 0x3087, 0xA4E8, 0x3088, 0xA4E9, 0x3089, + 0xA4EA, 0x308A, 0xA4EB, 0x308B, 0xA4EC, 0x308C, 0xA4ED, 0x308D, + 0xA4EE, 0x308E, 0xA4EF, 0x308F, 0xA4F0, 0x3090, 0xA4F1, 0x3091, + 0xA4F2, 0x3092, 0xA4F3, 0x3093, 0xA5A1, 0x30A1, 0xA5A2, 0x30A2, + 0xA5A3, 0x30A3, 0xA5A4, 0x30A4, 0xA5A5, 0x30A5, 0xA5A6, 0x30A6, + 0xA5A7, 0x30A7, 0xA5A8, 0x30A8, 0xA5A9, 0x30A9, 0xA5AA, 0x30AA, + 0xA5AB, 0x30AB, 0xA5AC, 0x30AC, 0xA5AD, 0x30AD, 0xA5AE, 0x30AE, + 0xA5AF, 0x30AF, 0xA5B0, 0x30B0, 0xA5B1, 0x30B1, 0xA5B2, 0x30B2, + 0xA5B3, 0x30B3, 0xA5B4, 0x30B4, 0xA5B5, 0x30B5, 0xA5B6, 0x30B6, + 0xA5B7, 0x30B7, 0xA5B8, 0x30B8, 0xA5B9, 0x30B9, 0xA5BA, 0x30BA, + 0xA5BB, 0x30BB, 0xA5BC, 0x30BC, 0xA5BD, 0x30BD, 0xA5BE, 0x30BE, + 0xA5BF, 0x30BF, 0xA5C0, 0x30C0, 0xA5C1, 0x30C1, 0xA5C2, 0x30C2, + 0xA5C3, 0x30C3, 0xA5C4, 0x30C4, 0xA5C5, 0x30C5, 0xA5C6, 0x30C6, + 0xA5C7, 0x30C7, 0xA5C8, 0x30C8, 0xA5C9, 0x30C9, 0xA5CA, 0x30CA, + 0xA5CB, 0x30CB, 0xA5CC, 0x30CC, 0xA5CD, 0x30CD, 0xA5CE, 0x30CE, + 0xA5CF, 0x30CF, 0xA5D0, 0x30D0, 0xA5D1, 0x30D1, 0xA5D2, 0x30D2, + 0xA5D3, 0x30D3, 0xA5D4, 0x30D4, 0xA5D5, 0x30D5, 0xA5D6, 0x30D6, + 0xA5D7, 0x30D7, 0xA5D8, 0x30D8, 0xA5D9, 0x30D9, 0xA5DA, 0x30DA, + 0xA5DB, 0x30DB, 0xA5DC, 0x30DC, 0xA5DD, 0x30DD, 0xA5DE, 0x30DE, + 0xA5DF, 0x30DF, 0xA5E0, 0x30E0, 0xA5E1, 0x30E1, 0xA5E2, 0x30E2, + 0xA5E3, 0x30E3, 0xA5E4, 0x30E4, 0xA5E5, 0x30E5, 0xA5E6, 0x30E6, + 0xA5E7, 0x30E7, 0xA5E8, 0x30E8, 0xA5E9, 0x30E9, 0xA5EA, 0x30EA, + 0xA5EB, 0x30EB, 0xA5EC, 0x30EC, 0xA5ED, 0x30ED, 0xA5EE, 0x30EE, + 0xA5EF, 0x30EF, 0xA5F0, 0x30F0, 0xA5F1, 0x30F1, 0xA5F2, 0x30F2, + 0xA5F3, 0x30F3, 0xA5F4, 0x30F4, 0xA5F5, 0x30F5, 0xA5F6, 0x30F6, + 0xA6A1, 0x0391, 0xA6A2, 0x0392, 0xA6A3, 0x0393, 0xA6A4, 0x0394, + 0xA6A5, 0x0395, 0xA6A6, 0x0396, 0xA6A7, 0x0397, 0xA6A8, 0x0398, + 0xA6A9, 0x0399, 0xA6AA, 0x039A, 0xA6AB, 0x039B, 0xA6AC, 0x039C, + 0xA6AD, 0x039D, 0xA6AE, 0x039E, 0xA6AF, 0x039F, 0xA6B0, 0x03A0, + 0xA6B1, 0x03A1, 0xA6B2, 0x03A3, 0xA6B3, 0x03A4, 0xA6B4, 0x03A5, + 0xA6B5, 0x03A6, 0xA6B6, 0x03A7, 0xA6B7, 0x03A8, 0xA6B8, 0x03A9, + 0xA6C1, 0x03B1, 0xA6C2, 0x03B2, 0xA6C3, 0x03B3, 0xA6C4, 0x03B4, + 0xA6C5, 0x03B5, 0xA6C6, 0x03B6, 0xA6C7, 0x03B7, 0xA6C8, 0x03B8, + 0xA6C9, 0x03B9, 0xA6CA, 0x03BA, 0xA6CB, 0x03BB, 0xA6CC, 0x03BC, + 0xA6CD, 0x03BD, 0xA6CE, 0x03BE, 0xA6CF, 0x03BF, 0xA6D0, 0x03C0, + 0xA6D1, 0x03C1, 0xA6D2, 0x03C3, 0xA6D3, 0x03C4, 0xA6D4, 0x03C5, + 0xA6D5, 0x03C6, 0xA6D6, 0x03C7, 0xA6D7, 0x03C8, 0xA6D8, 0x03C9, + 0xA6E0, 0xFE35, 0xA6E1, 0xFE36, 0xA6E2, 0xFE39, 0xA6E3, 0xFE3A, + 0xA6E4, 0xFE3F, 0xA6E5, 0xFE40, 0xA6E6, 0xFE3D, 0xA6E7, 0xFE3E, + 0xA6E8, 0xFE41, 0xA6E9, 0xFE42, 0xA6EA, 0xFE43, 0xA6EB, 0xFE44, + 0xA6EE, 0xFE3B, 0xA6EF, 0xFE3C, 0xA6F0, 0xFE37, 0xA6F1, 0xFE38, + 0xA6F2, 0xFE31, 0xA6F4, 0xFE33, 0xA6F5, 0xFE34, 0xA7A1, 0x0410, + 0xA7A2, 0x0411, 0xA7A3, 0x0412, 0xA7A4, 0x0413, 0xA7A5, 0x0414, + 0xA7A6, 0x0415, 0xA7A7, 0x0401, 0xA7A8, 0x0416, 0xA7A9, 0x0417, + 0xA7AA, 0x0418, 0xA7AB, 0x0419, 0xA7AC, 0x041A, 0xA7AD, 0x041B, + 0xA7AE, 0x041C, 0xA7AF, 0x041D, 0xA7B0, 0x041E, 0xA7B1, 0x041F, + 0xA7B2, 0x0420, 0xA7B3, 0x0421, 0xA7B4, 0x0422, 0xA7B5, 0x0423, + 0xA7B6, 0x0424, 0xA7B7, 0x0425, 0xA7B8, 0x0426, 0xA7B9, 0x0427, + 0xA7BA, 0x0428, 0xA7BB, 0x0429, 0xA7BC, 0x042A, 0xA7BD, 0x042B, + 0xA7BE, 0x042C, 0xA7BF, 0x042D, 0xA7C0, 0x042E, 0xA7C1, 0x042F, + 0xA7D1, 0x0430, 0xA7D2, 0x0431, 0xA7D3, 0x0432, 0xA7D4, 0x0433, + 0xA7D5, 0x0434, 0xA7D6, 0x0435, 0xA7D7, 0x0451, 0xA7D8, 0x0436, + 0xA7D9, 0x0437, 0xA7DA, 0x0438, 0xA7DB, 0x0439, 0xA7DC, 0x043A, + 0xA7DD, 0x043B, 0xA7DE, 0x043C, 0xA7DF, 0x043D, 0xA7E0, 0x043E, + 0xA7E1, 0x043F, 0xA7E2, 0x0440, 0xA7E3, 0x0441, 0xA7E4, 0x0442, + 0xA7E5, 0x0443, 0xA7E6, 0x0444, 0xA7E7, 0x0445, 0xA7E8, 0x0446, + 0xA7E9, 0x0447, 0xA7EA, 0x0448, 0xA7EB, 0x0449, 0xA7EC, 0x044A, + 0xA7ED, 0x044B, 0xA7EE, 0x044C, 0xA7EF, 0x044D, 0xA7F0, 0x044E, + 0xA7F1, 0x044F, 0xA840, 0x02CA, 0xA841, 0x02CB, 0xA842, 0x02D9, + 0xA843, 0x2013, 0xA844, 0x2015, 0xA845, 0x2025, 0xA846, 0x2035, + 0xA847, 0x2105, 0xA848, 0x2109, 0xA849, 0x2196, 0xA84A, 0x2197, + 0xA84B, 0x2198, 0xA84C, 0x2199, 0xA84D, 0x2215, 0xA84E, 0x221F, + 0xA84F, 0x2223, 0xA850, 0x2252, 0xA851, 0x2266, 0xA852, 0x2267, + 0xA853, 0x22BF, 0xA854, 0x2550, 0xA855, 0x2551, 0xA856, 0x2552, + 0xA857, 0x2553, 0xA858, 0x2554, 0xA859, 0x2555, 0xA85A, 0x2556, + 0xA85B, 0x2557, 0xA85C, 0x2558, 0xA85D, 0x2559, 0xA85E, 0x255A, + 0xA85F, 0x255B, 0xA860, 0x255C, 0xA861, 0x255D, 0xA862, 0x255E, + 0xA863, 0x255F, 0xA864, 0x2560, 0xA865, 0x2561, 0xA866, 0x2562, + 0xA867, 0x2563, 0xA868, 0x2564, 0xA869, 0x2565, 0xA86A, 0x2566, + 0xA86B, 0x2567, 0xA86C, 0x2568, 0xA86D, 0x2569, 0xA86E, 0x256A, + 0xA86F, 0x256B, 0xA870, 0x256C, 0xA871, 0x256D, 0xA872, 0x256E, + 0xA873, 0x256F, 0xA874, 0x2570, 0xA875, 0x2571, 0xA876, 0x2572, + 0xA877, 0x2573, 0xA878, 0x2581, 0xA879, 0x2582, 0xA87A, 0x2583, + 0xA87B, 0x2584, 0xA87C, 0x2585, 0xA87D, 0x2586, 0xA87E, 0x2587, + 0xA880, 0x2588, 0xA881, 0x2589, 0xA882, 0x258A, 0xA883, 0x258B, + 0xA884, 0x258C, 0xA885, 0x258D, 0xA886, 0x258E, 0xA887, 0x258F, + 0xA888, 0x2593, 0xA889, 0x2594, 0xA88A, 0x2595, 0xA88B, 0x25BC, + 0xA88C, 0x25BD, 0xA88D, 0x25E2, 0xA88E, 0x25E3, 0xA88F, 0x25E4, + 0xA890, 0x25E5, 0xA891, 0x2609, 0xA892, 0x2295, 0xA893, 0x3012, + 0xA894, 0x301D, 0xA895, 0x301E, 0xA8A1, 0x0101, 0xA8A2, 0x00E1, + 0xA8A3, 0x01CE, 0xA8A4, 0x00E0, 0xA8A5, 0x0113, 0xA8A6, 0x00E9, + 0xA8A7, 0x011B, 0xA8A8, 0x00E8, 0xA8A9, 0x012B, 0xA8AA, 0x00ED, + 0xA8AB, 0x01D0, 0xA8AC, 0x00EC, 0xA8AD, 0x014D, 0xA8AE, 0x00F3, + 0xA8AF, 0x01D2, 0xA8B0, 0x00F2, 0xA8B1, 0x016B, 0xA8B2, 0x00FA, + 0xA8B3, 0x01D4, 0xA8B4, 0x00F9, 0xA8B5, 0x01D6, 0xA8B6, 0x01D8, + 0xA8B7, 0x01DA, 0xA8B8, 0x01DC, 0xA8B9, 0x00FC, 0xA8BA, 0x00EA, + 0xA8BB, 0x0251, 0xA8BD, 0x0144, 0xA8BE, 0x0148, 0xA8C0, 0x0261, + 0xA8C5, 0x3105, 0xA8C6, 0x3106, 0xA8C7, 0x3107, 0xA8C8, 0x3108, + 0xA8C9, 0x3109, 0xA8CA, 0x310A, 0xA8CB, 0x310B, 0xA8CC, 0x310C, + 0xA8CD, 0x310D, 0xA8CE, 0x310E, 0xA8CF, 0x310F, 0xA8D0, 0x3110, + 0xA8D1, 0x3111, 0xA8D2, 0x3112, 0xA8D3, 0x3113, 0xA8D4, 0x3114, + 0xA8D5, 0x3115, 0xA8D6, 0x3116, 0xA8D7, 0x3117, 0xA8D8, 0x3118, + 0xA8D9, 0x3119, 0xA8DA, 0x311A, 0xA8DB, 0x311B, 0xA8DC, 0x311C, + 0xA8DD, 0x311D, 0xA8DE, 0x311E, 0xA8DF, 0x311F, 0xA8E0, 0x3120, + 0xA8E1, 0x3121, 0xA8E2, 0x3122, 0xA8E3, 0x3123, 0xA8E4, 0x3124, + 0xA8E5, 0x3125, 0xA8E6, 0x3126, 0xA8E7, 0x3127, 0xA8E8, 0x3128, + 0xA8E9, 0x3129, 0xA940, 0x3021, 0xA941, 0x3022, 0xA942, 0x3023, + 0xA943, 0x3024, 0xA944, 0x3025, 0xA945, 0x3026, 0xA946, 0x3027, + 0xA947, 0x3028, 0xA948, 0x3029, 0xA949, 0x32A3, 0xA94A, 0x338E, + 0xA94B, 0x338F, 0xA94C, 0x339C, 0xA94D, 0x339D, 0xA94E, 0x339E, + 0xA94F, 0x33A1, 0xA950, 0x33C4, 0xA951, 0x33CE, 0xA952, 0x33D1, + 0xA953, 0x33D2, 0xA954, 0x33D5, 0xA955, 0xFE30, 0xA956, 0xFFE2, + 0xA957, 0xFFE4, 0xA959, 0x2121, 0xA95A, 0x3231, 0xA95C, 0x2010, + 0xA960, 0x30FC, 0xA961, 0x309B, 0xA962, 0x309C, 0xA963, 0x30FD, + 0xA964, 0x30FE, 0xA965, 0x3006, 0xA966, 0x309D, 0xA967, 0x309E, + 0xA968, 0xFE49, 0xA969, 0xFE4A, 0xA96A, 0xFE4B, 0xA96B, 0xFE4C, + 0xA96C, 0xFE4D, 0xA96D, 0xFE4E, 0xA96E, 0xFE4F, 0xA96F, 0xFE50, + 0xA970, 0xFE51, 0xA971, 0xFE52, 0xA972, 0xFE54, 0xA973, 0xFE55, + 0xA974, 0xFE56, 0xA975, 0xFE57, 0xA976, 0xFE59, 0xA977, 0xFE5A, + 0xA978, 0xFE5B, 0xA979, 0xFE5C, 0xA97A, 0xFE5D, 0xA97B, 0xFE5E, + 0xA97C, 0xFE5F, 0xA97D, 0xFE60, 0xA97E, 0xFE61, 0xA980, 0xFE62, + 0xA981, 0xFE63, 0xA982, 0xFE64, 0xA983, 0xFE65, 0xA984, 0xFE66, + 0xA985, 0xFE68, 0xA986, 0xFE69, 0xA987, 0xFE6A, 0xA988, 0xFE6B, + 0xA996, 0x3007, 0xA9A4, 0x2500, 0xA9A5, 0x2501, 0xA9A6, 0x2502, + 0xA9A7, 0x2503, 0xA9A8, 0x2504, 0xA9A9, 0x2505, 0xA9AA, 0x2506, + 0xA9AB, 0x2507, 0xA9AC, 0x2508, 0xA9AD, 0x2509, 0xA9AE, 0x250A, + 0xA9AF, 0x250B, 0xA9B0, 0x250C, 0xA9B1, 0x250D, 0xA9B2, 0x250E, + 0xA9B3, 0x250F, 0xA9B4, 0x2510, 0xA9B5, 0x2511, 0xA9B6, 0x2512, + 0xA9B7, 0x2513, 0xA9B8, 0x2514, 0xA9B9, 0x2515, 0xA9BA, 0x2516, + 0xA9BB, 0x2517, 0xA9BC, 0x2518, 0xA9BD, 0x2519, 0xA9BE, 0x251A, + 0xA9BF, 0x251B, 0xA9C0, 0x251C, 0xA9C1, 0x251D, 0xA9C2, 0x251E, + 0xA9C3, 0x251F, 0xA9C4, 0x2520, 0xA9C5, 0x2521, 0xA9C6, 0x2522, + 0xA9C7, 0x2523, 0xA9C8, 0x2524, 0xA9C9, 0x2525, 0xA9CA, 0x2526, + 0xA9CB, 0x2527, 0xA9CC, 0x2528, 0xA9CD, 0x2529, 0xA9CE, 0x252A, + 0xA9CF, 0x252B, 0xA9D0, 0x252C, 0xA9D1, 0x252D, 0xA9D2, 0x252E, + 0xA9D3, 0x252F, 0xA9D4, 0x2530, 0xA9D5, 0x2531, 0xA9D6, 0x2532, + 0xA9D7, 0x2533, 0xA9D8, 0x2534, 0xA9D9, 0x2535, 0xA9DA, 0x2536, + 0xA9DB, 0x2537, 0xA9DC, 0x2538, 0xA9DD, 0x2539, 0xA9DE, 0x253A, + 0xA9DF, 0x253B, 0xA9E0, 0x253C, 0xA9E1, 0x253D, 0xA9E2, 0x253E, + 0xA9E3, 0x253F, 0xA9E4, 0x2540, 0xA9E5, 0x2541, 0xA9E6, 0x2542, + 0xA9E7, 0x2543, 0xA9E8, 0x2544, 0xA9E9, 0x2545, 0xA9EA, 0x2546, + 0xA9EB, 0x2547, 0xA9EC, 0x2548, 0xA9ED, 0x2549, 0xA9EE, 0x254A, + 0xA9EF, 0x254B, 0xAA40, 0x72DC, 0xAA41, 0x72DD, 0xAA42, 0x72DF, + 0xAA43, 0x72E2, 0xAA44, 0x72E3, 0xAA45, 0x72E4, 0xAA46, 0x72E5, + 0xAA47, 0x72E6, 0xAA48, 0x72E7, 0xAA49, 0x72EA, 0xAA4A, 0x72EB, + 0xAA4B, 0x72F5, 0xAA4C, 0x72F6, 0xAA4D, 0x72F9, 0xAA4E, 0x72FD, + 0xAA4F, 0x72FE, 0xAA50, 0x72FF, 0xAA51, 0x7300, 0xAA52, 0x7302, + 0xAA53, 0x7304, 0xAA54, 0x7305, 0xAA55, 0x7306, 0xAA56, 0x7307, + 0xAA57, 0x7308, 0xAA58, 0x7309, 0xAA59, 0x730B, 0xAA5A, 0x730C, + 0xAA5B, 0x730D, 0xAA5C, 0x730F, 0xAA5D, 0x7310, 0xAA5E, 0x7311, + 0xAA5F, 0x7312, 0xAA60, 0x7314, 0xAA61, 0x7318, 0xAA62, 0x7319, + 0xAA63, 0x731A, 0xAA64, 0x731F, 0xAA65, 0x7320, 0xAA66, 0x7323, + 0xAA67, 0x7324, 0xAA68, 0x7326, 0xAA69, 0x7327, 0xAA6A, 0x7328, + 0xAA6B, 0x732D, 0xAA6C, 0x732F, 0xAA6D, 0x7330, 0xAA6E, 0x7332, + 0xAA6F, 0x7333, 0xAA70, 0x7335, 0xAA71, 0x7336, 0xAA72, 0x733A, + 0xAA73, 0x733B, 0xAA74, 0x733C, 0xAA75, 0x733D, 0xAA76, 0x7340, + 0xAA77, 0x7341, 0xAA78, 0x7342, 0xAA79, 0x7343, 0xAA7A, 0x7344, + 0xAA7B, 0x7345, 0xAA7C, 0x7346, 0xAA7D, 0x7347, 0xAA7E, 0x7348, + 0xAA80, 0x7349, 0xAA81, 0x734A, 0xAA82, 0x734B, 0xAA83, 0x734C, + 0xAA84, 0x734E, 0xAA85, 0x734F, 0xAA86, 0x7351, 0xAA87, 0x7353, + 0xAA88, 0x7354, 0xAA89, 0x7355, 0xAA8A, 0x7356, 0xAA8B, 0x7358, + 0xAA8C, 0x7359, 0xAA8D, 0x735A, 0xAA8E, 0x735B, 0xAA8F, 0x735C, + 0xAA90, 0x735D, 0xAA91, 0x735E, 0xAA92, 0x735F, 0xAA93, 0x7361, + 0xAA94, 0x7362, 0xAA95, 0x7363, 0xAA96, 0x7364, 0xAA97, 0x7365, + 0xAA98, 0x7366, 0xAA99, 0x7367, 0xAA9A, 0x7368, 0xAA9B, 0x7369, + 0xAA9C, 0x736A, 0xAA9D, 0x736B, 0xAA9E, 0x736E, 0xAA9F, 0x7370, + 0xAAA0, 0x7371, 0xAB40, 0x7372, 0xAB41, 0x7373, 0xAB42, 0x7374, + 0xAB43, 0x7375, 0xAB44, 0x7376, 0xAB45, 0x7377, 0xAB46, 0x7378, + 0xAB47, 0x7379, 0xAB48, 0x737A, 0xAB49, 0x737B, 0xAB4A, 0x737C, + 0xAB4B, 0x737D, 0xAB4C, 0x737F, 0xAB4D, 0x7380, 0xAB4E, 0x7381, + 0xAB4F, 0x7382, 0xAB50, 0x7383, 0xAB51, 0x7385, 0xAB52, 0x7386, + 0xAB53, 0x7388, 0xAB54, 0x738A, 0xAB55, 0x738C, 0xAB56, 0x738D, + 0xAB57, 0x738F, 0xAB58, 0x7390, 0xAB59, 0x7392, 0xAB5A, 0x7393, + 0xAB5B, 0x7394, 0xAB5C, 0x7395, 0xAB5D, 0x7397, 0xAB5E, 0x7398, + 0xAB5F, 0x7399, 0xAB60, 0x739A, 0xAB61, 0x739C, 0xAB62, 0x739D, + 0xAB63, 0x739E, 0xAB64, 0x73A0, 0xAB65, 0x73A1, 0xAB66, 0x73A3, + 0xAB67, 0x73A4, 0xAB68, 0x73A5, 0xAB69, 0x73A6, 0xAB6A, 0x73A7, + 0xAB6B, 0x73A8, 0xAB6C, 0x73AA, 0xAB6D, 0x73AC, 0xAB6E, 0x73AD, + 0xAB6F, 0x73B1, 0xAB70, 0x73B4, 0xAB71, 0x73B5, 0xAB72, 0x73B6, + 0xAB73, 0x73B8, 0xAB74, 0x73B9, 0xAB75, 0x73BC, 0xAB76, 0x73BD, + 0xAB77, 0x73BE, 0xAB78, 0x73BF, 0xAB79, 0x73C1, 0xAB7A, 0x73C3, + 0xAB7B, 0x73C4, 0xAB7C, 0x73C5, 0xAB7D, 0x73C6, 0xAB7E, 0x73C7, + 0xAB80, 0x73CB, 0xAB81, 0x73CC, 0xAB82, 0x73CE, 0xAB83, 0x73D2, + 0xAB84, 0x73D3, 0xAB85, 0x73D4, 0xAB86, 0x73D5, 0xAB87, 0x73D6, + 0xAB88, 0x73D7, 0xAB89, 0x73D8, 0xAB8A, 0x73DA, 0xAB8B, 0x73DB, + 0xAB8C, 0x73DC, 0xAB8D, 0x73DD, 0xAB8E, 0x73DF, 0xAB8F, 0x73E1, + 0xAB90, 0x73E2, 0xAB91, 0x73E3, 0xAB92, 0x73E4, 0xAB93, 0x73E6, + 0xAB94, 0x73E8, 0xAB95, 0x73EA, 0xAB96, 0x73EB, 0xAB97, 0x73EC, + 0xAB98, 0x73EE, 0xAB99, 0x73EF, 0xAB9A, 0x73F0, 0xAB9B, 0x73F1, + 0xAB9C, 0x73F3, 0xAB9D, 0x73F4, 0xAB9E, 0x73F5, 0xAB9F, 0x73F6, + 0xABA0, 0x73F7, 0xAC40, 0x73F8, 0xAC41, 0x73F9, 0xAC42, 0x73FA, + 0xAC43, 0x73FB, 0xAC44, 0x73FC, 0xAC45, 0x73FD, 0xAC46, 0x73FE, + 0xAC47, 0x73FF, 0xAC48, 0x7400, 0xAC49, 0x7401, 0xAC4A, 0x7402, + 0xAC4B, 0x7404, 0xAC4C, 0x7407, 0xAC4D, 0x7408, 0xAC4E, 0x740B, + 0xAC4F, 0x740C, 0xAC50, 0x740D, 0xAC51, 0x740E, 0xAC52, 0x7411, + 0xAC53, 0x7412, 0xAC54, 0x7413, 0xAC55, 0x7414, 0xAC56, 0x7415, + 0xAC57, 0x7416, 0xAC58, 0x7417, 0xAC59, 0x7418, 0xAC5A, 0x7419, + 0xAC5B, 0x741C, 0xAC5C, 0x741D, 0xAC5D, 0x741E, 0xAC5E, 0x741F, + 0xAC5F, 0x7420, 0xAC60, 0x7421, 0xAC61, 0x7423, 0xAC62, 0x7424, + 0xAC63, 0x7427, 0xAC64, 0x7429, 0xAC65, 0x742B, 0xAC66, 0x742D, + 0xAC67, 0x742F, 0xAC68, 0x7431, 0xAC69, 0x7432, 0xAC6A, 0x7437, + 0xAC6B, 0x7438, 0xAC6C, 0x7439, 0xAC6D, 0x743A, 0xAC6E, 0x743B, + 0xAC6F, 0x743D, 0xAC70, 0x743E, 0xAC71, 0x743F, 0xAC72, 0x7440, + 0xAC73, 0x7442, 0xAC74, 0x7443, 0xAC75, 0x7444, 0xAC76, 0x7445, + 0xAC77, 0x7446, 0xAC78, 0x7447, 0xAC79, 0x7448, 0xAC7A, 0x7449, + 0xAC7B, 0x744A, 0xAC7C, 0x744B, 0xAC7D, 0x744C, 0xAC7E, 0x744D, + 0xAC80, 0x744E, 0xAC81, 0x744F, 0xAC82, 0x7450, 0xAC83, 0x7451, + 0xAC84, 0x7452, 0xAC85, 0x7453, 0xAC86, 0x7454, 0xAC87, 0x7456, + 0xAC88, 0x7458, 0xAC89, 0x745D, 0xAC8A, 0x7460, 0xAC8B, 0x7461, + 0xAC8C, 0x7462, 0xAC8D, 0x7463, 0xAC8E, 0x7464, 0xAC8F, 0x7465, + 0xAC90, 0x7466, 0xAC91, 0x7467, 0xAC92, 0x7468, 0xAC93, 0x7469, + 0xAC94, 0x746A, 0xAC95, 0x746B, 0xAC96, 0x746C, 0xAC97, 0x746E, + 0xAC98, 0x746F, 0xAC99, 0x7471, 0xAC9A, 0x7472, 0xAC9B, 0x7473, + 0xAC9C, 0x7474, 0xAC9D, 0x7475, 0xAC9E, 0x7478, 0xAC9F, 0x7479, + 0xACA0, 0x747A, 0xAD40, 0x747B, 0xAD41, 0x747C, 0xAD42, 0x747D, + 0xAD43, 0x747F, 0xAD44, 0x7482, 0xAD45, 0x7484, 0xAD46, 0x7485, + 0xAD47, 0x7486, 0xAD48, 0x7488, 0xAD49, 0x7489, 0xAD4A, 0x748A, + 0xAD4B, 0x748C, 0xAD4C, 0x748D, 0xAD4D, 0x748F, 0xAD4E, 0x7491, + 0xAD4F, 0x7492, 0xAD50, 0x7493, 0xAD51, 0x7494, 0xAD52, 0x7495, + 0xAD53, 0x7496, 0xAD54, 0x7497, 0xAD55, 0x7498, 0xAD56, 0x7499, + 0xAD57, 0x749A, 0xAD58, 0x749B, 0xAD59, 0x749D, 0xAD5A, 0x749F, + 0xAD5B, 0x74A0, 0xAD5C, 0x74A1, 0xAD5D, 0x74A2, 0xAD5E, 0x74A3, + 0xAD5F, 0x74A4, 0xAD60, 0x74A5, 0xAD61, 0x74A6, 0xAD62, 0x74AA, + 0xAD63, 0x74AB, 0xAD64, 0x74AC, 0xAD65, 0x74AD, 0xAD66, 0x74AE, + 0xAD67, 0x74AF, 0xAD68, 0x74B0, 0xAD69, 0x74B1, 0xAD6A, 0x74B2, + 0xAD6B, 0x74B3, 0xAD6C, 0x74B4, 0xAD6D, 0x74B5, 0xAD6E, 0x74B6, + 0xAD6F, 0x74B7, 0xAD70, 0x74B8, 0xAD71, 0x74B9, 0xAD72, 0x74BB, + 0xAD73, 0x74BC, 0xAD74, 0x74BD, 0xAD75, 0x74BE, 0xAD76, 0x74BF, + 0xAD77, 0x74C0, 0xAD78, 0x74C1, 0xAD79, 0x74C2, 0xAD7A, 0x74C3, + 0xAD7B, 0x74C4, 0xAD7C, 0x74C5, 0xAD7D, 0x74C6, 0xAD7E, 0x74C7, + 0xAD80, 0x74C8, 0xAD81, 0x74C9, 0xAD82, 0x74CA, 0xAD83, 0x74CB, + 0xAD84, 0x74CC, 0xAD85, 0x74CD, 0xAD86, 0x74CE, 0xAD87, 0x74CF, + 0xAD88, 0x74D0, 0xAD89, 0x74D1, 0xAD8A, 0x74D3, 0xAD8B, 0x74D4, + 0xAD8C, 0x74D5, 0xAD8D, 0x74D6, 0xAD8E, 0x74D7, 0xAD8F, 0x74D8, + 0xAD90, 0x74D9, 0xAD91, 0x74DA, 0xAD92, 0x74DB, 0xAD93, 0x74DD, + 0xAD94, 0x74DF, 0xAD95, 0x74E1, 0xAD96, 0x74E5, 0xAD97, 0x74E7, + 0xAD98, 0x74E8, 0xAD99, 0x74E9, 0xAD9A, 0x74EA, 0xAD9B, 0x74EB, + 0xAD9C, 0x74EC, 0xAD9D, 0x74ED, 0xAD9E, 0x74F0, 0xAD9F, 0x74F1, + 0xADA0, 0x74F2, 0xAE40, 0x74F3, 0xAE41, 0x74F5, 0xAE42, 0x74F8, + 0xAE43, 0x74F9, 0xAE44, 0x74FA, 0xAE45, 0x74FB, 0xAE46, 0x74FC, + 0xAE47, 0x74FD, 0xAE48, 0x74FE, 0xAE49, 0x7500, 0xAE4A, 0x7501, + 0xAE4B, 0x7502, 0xAE4C, 0x7503, 0xAE4D, 0x7505, 0xAE4E, 0x7506, + 0xAE4F, 0x7507, 0xAE50, 0x7508, 0xAE51, 0x7509, 0xAE52, 0x750A, + 0xAE53, 0x750B, 0xAE54, 0x750C, 0xAE55, 0x750E, 0xAE56, 0x7510, + 0xAE57, 0x7512, 0xAE58, 0x7514, 0xAE59, 0x7515, 0xAE5A, 0x7516, + 0xAE5B, 0x7517, 0xAE5C, 0x751B, 0xAE5D, 0x751D, 0xAE5E, 0x751E, + 0xAE5F, 0x7520, 0xAE60, 0x7521, 0xAE61, 0x7522, 0xAE62, 0x7523, + 0xAE63, 0x7524, 0xAE64, 0x7526, 0xAE65, 0x7527, 0xAE66, 0x752A, + 0xAE67, 0x752E, 0xAE68, 0x7534, 0xAE69, 0x7536, 0xAE6A, 0x7539, + 0xAE6B, 0x753C, 0xAE6C, 0x753D, 0xAE6D, 0x753F, 0xAE6E, 0x7541, + 0xAE6F, 0x7542, 0xAE70, 0x7543, 0xAE71, 0x7544, 0xAE72, 0x7546, + 0xAE73, 0x7547, 0xAE74, 0x7549, 0xAE75, 0x754A, 0xAE76, 0x754D, + 0xAE77, 0x7550, 0xAE78, 0x7551, 0xAE79, 0x7552, 0xAE7A, 0x7553, + 0xAE7B, 0x7555, 0xAE7C, 0x7556, 0xAE7D, 0x7557, 0xAE7E, 0x7558, + 0xAE80, 0x755D, 0xAE81, 0x755E, 0xAE82, 0x755F, 0xAE83, 0x7560, + 0xAE84, 0x7561, 0xAE85, 0x7562, 0xAE86, 0x7563, 0xAE87, 0x7564, + 0xAE88, 0x7567, 0xAE89, 0x7568, 0xAE8A, 0x7569, 0xAE8B, 0x756B, + 0xAE8C, 0x756C, 0xAE8D, 0x756D, 0xAE8E, 0x756E, 0xAE8F, 0x756F, + 0xAE90, 0x7570, 0xAE91, 0x7571, 0xAE92, 0x7573, 0xAE93, 0x7575, + 0xAE94, 0x7576, 0xAE95, 0x7577, 0xAE96, 0x757A, 0xAE97, 0x757B, + 0xAE98, 0x757C, 0xAE99, 0x757D, 0xAE9A, 0x757E, 0xAE9B, 0x7580, + 0xAE9C, 0x7581, 0xAE9D, 0x7582, 0xAE9E, 0x7584, 0xAE9F, 0x7585, + 0xAEA0, 0x7587, 0xAF40, 0x7588, 0xAF41, 0x7589, 0xAF42, 0x758A, + 0xAF43, 0x758C, 0xAF44, 0x758D, 0xAF45, 0x758E, 0xAF46, 0x7590, + 0xAF47, 0x7593, 0xAF48, 0x7595, 0xAF49, 0x7598, 0xAF4A, 0x759B, + 0xAF4B, 0x759C, 0xAF4C, 0x759E, 0xAF4D, 0x75A2, 0xAF4E, 0x75A6, + 0xAF4F, 0x75A7, 0xAF50, 0x75A8, 0xAF51, 0x75A9, 0xAF52, 0x75AA, + 0xAF53, 0x75AD, 0xAF54, 0x75B6, 0xAF55, 0x75B7, 0xAF56, 0x75BA, + 0xAF57, 0x75BB, 0xAF58, 0x75BF, 0xAF59, 0x75C0, 0xAF5A, 0x75C1, + 0xAF5B, 0x75C6, 0xAF5C, 0x75CB, 0xAF5D, 0x75CC, 0xAF5E, 0x75CE, + 0xAF5F, 0x75CF, 0xAF60, 0x75D0, 0xAF61, 0x75D1, 0xAF62, 0x75D3, + 0xAF63, 0x75D7, 0xAF64, 0x75D9, 0xAF65, 0x75DA, 0xAF66, 0x75DC, + 0xAF67, 0x75DD, 0xAF68, 0x75DF, 0xAF69, 0x75E0, 0xAF6A, 0x75E1, + 0xAF6B, 0x75E5, 0xAF6C, 0x75E9, 0xAF6D, 0x75EC, 0xAF6E, 0x75ED, + 0xAF6F, 0x75EE, 0xAF70, 0x75EF, 0xAF71, 0x75F2, 0xAF72, 0x75F3, + 0xAF73, 0x75F5, 0xAF74, 0x75F6, 0xAF75, 0x75F7, 0xAF76, 0x75F8, + 0xAF77, 0x75FA, 0xAF78, 0x75FB, 0xAF79, 0x75FD, 0xAF7A, 0x75FE, + 0xAF7B, 0x7602, 0xAF7C, 0x7604, 0xAF7D, 0x7606, 0xAF7E, 0x7607, + 0xAF80, 0x7608, 0xAF81, 0x7609, 0xAF82, 0x760B, 0xAF83, 0x760D, + 0xAF84, 0x760E, 0xAF85, 0x760F, 0xAF86, 0x7611, 0xAF87, 0x7612, + 0xAF88, 0x7613, 0xAF89, 0x7614, 0xAF8A, 0x7616, 0xAF8B, 0x761A, + 0xAF8C, 0x761C, 0xAF8D, 0x761D, 0xAF8E, 0x761E, 0xAF8F, 0x7621, + 0xAF90, 0x7623, 0xAF91, 0x7627, 0xAF92, 0x7628, 0xAF93, 0x762C, + 0xAF94, 0x762E, 0xAF95, 0x762F, 0xAF96, 0x7631, 0xAF97, 0x7632, + 0xAF98, 0x7636, 0xAF99, 0x7637, 0xAF9A, 0x7639, 0xAF9B, 0x763A, + 0xAF9C, 0x763B, 0xAF9D, 0x763D, 0xAF9E, 0x7641, 0xAF9F, 0x7642, + 0xAFA0, 0x7644, 0xB040, 0x7645, 0xB041, 0x7646, 0xB042, 0x7647, + 0xB043, 0x7648, 0xB044, 0x7649, 0xB045, 0x764A, 0xB046, 0x764B, + 0xB047, 0x764E, 0xB048, 0x764F, 0xB049, 0x7650, 0xB04A, 0x7651, + 0xB04B, 0x7652, 0xB04C, 0x7653, 0xB04D, 0x7655, 0xB04E, 0x7657, + 0xB04F, 0x7658, 0xB050, 0x7659, 0xB051, 0x765A, 0xB052, 0x765B, + 0xB053, 0x765D, 0xB054, 0x765F, 0xB055, 0x7660, 0xB056, 0x7661, + 0xB057, 0x7662, 0xB058, 0x7664, 0xB059, 0x7665, 0xB05A, 0x7666, + 0xB05B, 0x7667, 0xB05C, 0x7668, 0xB05D, 0x7669, 0xB05E, 0x766A, + 0xB05F, 0x766C, 0xB060, 0x766D, 0xB061, 0x766E, 0xB062, 0x7670, + 0xB063, 0x7671, 0xB064, 0x7672, 0xB065, 0x7673, 0xB066, 0x7674, + 0xB067, 0x7675, 0xB068, 0x7676, 0xB069, 0x7677, 0xB06A, 0x7679, + 0xB06B, 0x767A, 0xB06C, 0x767C, 0xB06D, 0x767F, 0xB06E, 0x7680, + 0xB06F, 0x7681, 0xB070, 0x7683, 0xB071, 0x7685, 0xB072, 0x7689, + 0xB073, 0x768A, 0xB074, 0x768C, 0xB075, 0x768D, 0xB076, 0x768F, + 0xB077, 0x7690, 0xB078, 0x7692, 0xB079, 0x7694, 0xB07A, 0x7695, + 0xB07B, 0x7697, 0xB07C, 0x7698, 0xB07D, 0x769A, 0xB07E, 0x769B, + 0xB080, 0x769C, 0xB081, 0x769D, 0xB082, 0x769E, 0xB083, 0x769F, + 0xB084, 0x76A0, 0xB085, 0x76A1, 0xB086, 0x76A2, 0xB087, 0x76A3, + 0xB088, 0x76A5, 0xB089, 0x76A6, 0xB08A, 0x76A7, 0xB08B, 0x76A8, + 0xB08C, 0x76A9, 0xB08D, 0x76AA, 0xB08E, 0x76AB, 0xB08F, 0x76AC, + 0xB090, 0x76AD, 0xB091, 0x76AF, 0xB092, 0x76B0, 0xB093, 0x76B3, + 0xB094, 0x76B5, 0xB095, 0x76B6, 0xB096, 0x76B7, 0xB097, 0x76B8, + 0xB098, 0x76B9, 0xB099, 0x76BA, 0xB09A, 0x76BB, 0xB09B, 0x76BC, + 0xB09C, 0x76BD, 0xB09D, 0x76BE, 0xB09E, 0x76C0, 0xB09F, 0x76C1, + 0xB0A0, 0x76C3, 0xB0A1, 0x554A, 0xB0A2, 0x963F, 0xB0A3, 0x57C3, + 0xB0A4, 0x6328, 0xB0A5, 0x54CE, 0xB0A6, 0x5509, 0xB0A7, 0x54C0, + 0xB0A8, 0x7691, 0xB0A9, 0x764C, 0xB0AA, 0x853C, 0xB0AB, 0x77EE, + 0xB0AC, 0x827E, 0xB0AD, 0x788D, 0xB0AE, 0x7231, 0xB0AF, 0x9698, + 0xB0B0, 0x978D, 0xB0B1, 0x6C28, 0xB0B2, 0x5B89, 0xB0B3, 0x4FFA, + 0xB0B4, 0x6309, 0xB0B5, 0x6697, 0xB0B6, 0x5CB8, 0xB0B7, 0x80FA, + 0xB0B8, 0x6848, 0xB0B9, 0x80AE, 0xB0BA, 0x6602, 0xB0BB, 0x76CE, + 0xB0BC, 0x51F9, 0xB0BD, 0x6556, 0xB0BE, 0x71AC, 0xB0BF, 0x7FF1, + 0xB0C0, 0x8884, 0xB0C1, 0x50B2, 0xB0C2, 0x5965, 0xB0C3, 0x61CA, + 0xB0C4, 0x6FB3, 0xB0C5, 0x82AD, 0xB0C6, 0x634C, 0xB0C7, 0x6252, + 0xB0C8, 0x53ED, 0xB0C9, 0x5427, 0xB0CA, 0x7B06, 0xB0CB, 0x516B, + 0xB0CC, 0x75A4, 0xB0CD, 0x5DF4, 0xB0CE, 0x62D4, 0xB0CF, 0x8DCB, + 0xB0D0, 0x9776, 0xB0D1, 0x628A, 0xB0D2, 0x8019, 0xB0D3, 0x575D, + 0xB0D4, 0x9738, 0xB0D5, 0x7F62, 0xB0D6, 0x7238, 0xB0D7, 0x767D, + 0xB0D8, 0x67CF, 0xB0D9, 0x767E, 0xB0DA, 0x6446, 0xB0DB, 0x4F70, + 0xB0DC, 0x8D25, 0xB0DD, 0x62DC, 0xB0DE, 0x7A17, 0xB0DF, 0x6591, + 0xB0E0, 0x73ED, 0xB0E1, 0x642C, 0xB0E2, 0x6273, 0xB0E3, 0x822C, + 0xB0E4, 0x9881, 0xB0E5, 0x677F, 0xB0E6, 0x7248, 0xB0E7, 0x626E, + 0xB0E8, 0x62CC, 0xB0E9, 0x4F34, 0xB0EA, 0x74E3, 0xB0EB, 0x534A, + 0xB0EC, 0x529E, 0xB0ED, 0x7ECA, 0xB0EE, 0x90A6, 0xB0EF, 0x5E2E, + 0xB0F0, 0x6886, 0xB0F1, 0x699C, 0xB0F2, 0x8180, 0xB0F3, 0x7ED1, + 0xB0F4, 0x68D2, 0xB0F5, 0x78C5, 0xB0F6, 0x868C, 0xB0F7, 0x9551, + 0xB0F8, 0x508D, 0xB0F9, 0x8C24, 0xB0FA, 0x82DE, 0xB0FB, 0x80DE, + 0xB0FC, 0x5305, 0xB0FD, 0x8912, 0xB0FE, 0x5265, 0xB140, 0x76C4, + 0xB141, 0x76C7, 0xB142, 0x76C9, 0xB143, 0x76CB, 0xB144, 0x76CC, + 0xB145, 0x76D3, 0xB146, 0x76D5, 0xB147, 0x76D9, 0xB148, 0x76DA, + 0xB149, 0x76DC, 0xB14A, 0x76DD, 0xB14B, 0x76DE, 0xB14C, 0x76E0, + 0xB14D, 0x76E1, 0xB14E, 0x76E2, 0xB14F, 0x76E3, 0xB150, 0x76E4, + 0xB151, 0x76E6, 0xB152, 0x76E7, 0xB153, 0x76E8, 0xB154, 0x76E9, + 0xB155, 0x76EA, 0xB156, 0x76EB, 0xB157, 0x76EC, 0xB158, 0x76ED, + 0xB159, 0x76F0, 0xB15A, 0x76F3, 0xB15B, 0x76F5, 0xB15C, 0x76F6, + 0xB15D, 0x76F7, 0xB15E, 0x76FA, 0xB15F, 0x76FB, 0xB160, 0x76FD, + 0xB161, 0x76FF, 0xB162, 0x7700, 0xB163, 0x7702, 0xB164, 0x7703, + 0xB165, 0x7705, 0xB166, 0x7706, 0xB167, 0x770A, 0xB168, 0x770C, + 0xB169, 0x770E, 0xB16A, 0x770F, 0xB16B, 0x7710, 0xB16C, 0x7711, + 0xB16D, 0x7712, 0xB16E, 0x7713, 0xB16F, 0x7714, 0xB170, 0x7715, + 0xB171, 0x7716, 0xB172, 0x7717, 0xB173, 0x7718, 0xB174, 0x771B, + 0xB175, 0x771C, 0xB176, 0x771D, 0xB177, 0x771E, 0xB178, 0x7721, + 0xB179, 0x7723, 0xB17A, 0x7724, 0xB17B, 0x7725, 0xB17C, 0x7727, + 0xB17D, 0x772A, 0xB17E, 0x772B, 0xB180, 0x772C, 0xB181, 0x772E, + 0xB182, 0x7730, 0xB183, 0x7731, 0xB184, 0x7732, 0xB185, 0x7733, + 0xB186, 0x7734, 0xB187, 0x7739, 0xB188, 0x773B, 0xB189, 0x773D, + 0xB18A, 0x773E, 0xB18B, 0x773F, 0xB18C, 0x7742, 0xB18D, 0x7744, + 0xB18E, 0x7745, 0xB18F, 0x7746, 0xB190, 0x7748, 0xB191, 0x7749, + 0xB192, 0x774A, 0xB193, 0x774B, 0xB194, 0x774C, 0xB195, 0x774D, + 0xB196, 0x774E, 0xB197, 0x774F, 0xB198, 0x7752, 0xB199, 0x7753, + 0xB19A, 0x7754, 0xB19B, 0x7755, 0xB19C, 0x7756, 0xB19D, 0x7757, + 0xB19E, 0x7758, 0xB19F, 0x7759, 0xB1A0, 0x775C, 0xB1A1, 0x8584, + 0xB1A2, 0x96F9, 0xB1A3, 0x4FDD, 0xB1A4, 0x5821, 0xB1A5, 0x9971, + 0xB1A6, 0x5B9D, 0xB1A7, 0x62B1, 0xB1A8, 0x62A5, 0xB1A9, 0x66B4, + 0xB1AA, 0x8C79, 0xB1AB, 0x9C8D, 0xB1AC, 0x7206, 0xB1AD, 0x676F, + 0xB1AE, 0x7891, 0xB1AF, 0x60B2, 0xB1B0, 0x5351, 0xB1B1, 0x5317, + 0xB1B2, 0x8F88, 0xB1B3, 0x80CC, 0xB1B4, 0x8D1D, 0xB1B5, 0x94A1, + 0xB1B6, 0x500D, 0xB1B7, 0x72C8, 0xB1B8, 0x5907, 0xB1B9, 0x60EB, + 0xB1BA, 0x7119, 0xB1BB, 0x88AB, 0xB1BC, 0x5954, 0xB1BD, 0x82EF, + 0xB1BE, 0x672C, 0xB1BF, 0x7B28, 0xB1C0, 0x5D29, 0xB1C1, 0x7EF7, + 0xB1C2, 0x752D, 0xB1C3, 0x6CF5, 0xB1C4, 0x8E66, 0xB1C5, 0x8FF8, + 0xB1C6, 0x903C, 0xB1C7, 0x9F3B, 0xB1C8, 0x6BD4, 0xB1C9, 0x9119, + 0xB1CA, 0x7B14, 0xB1CB, 0x5F7C, 0xB1CC, 0x78A7, 0xB1CD, 0x84D6, + 0xB1CE, 0x853D, 0xB1CF, 0x6BD5, 0xB1D0, 0x6BD9, 0xB1D1, 0x6BD6, + 0xB1D2, 0x5E01, 0xB1D3, 0x5E87, 0xB1D4, 0x75F9, 0xB1D5, 0x95ED, + 0xB1D6, 0x655D, 0xB1D7, 0x5F0A, 0xB1D8, 0x5FC5, 0xB1D9, 0x8F9F, + 0xB1DA, 0x58C1, 0xB1DB, 0x81C2, 0xB1DC, 0x907F, 0xB1DD, 0x965B, + 0xB1DE, 0x97AD, 0xB1DF, 0x8FB9, 0xB1E0, 0x7F16, 0xB1E1, 0x8D2C, + 0xB1E2, 0x6241, 0xB1E3, 0x4FBF, 0xB1E4, 0x53D8, 0xB1E5, 0x535E, + 0xB1E6, 0x8FA8, 0xB1E7, 0x8FA9, 0xB1E8, 0x8FAB, 0xB1E9, 0x904D, + 0xB1EA, 0x6807, 0xB1EB, 0x5F6A, 0xB1EC, 0x8198, 0xB1ED, 0x8868, + 0xB1EE, 0x9CD6, 0xB1EF, 0x618B, 0xB1F0, 0x522B, 0xB1F1, 0x762A, + 0xB1F2, 0x5F6C, 0xB1F3, 0x658C, 0xB1F4, 0x6FD2, 0xB1F5, 0x6EE8, + 0xB1F6, 0x5BBE, 0xB1F7, 0x6448, 0xB1F8, 0x5175, 0xB1F9, 0x51B0, + 0xB1FA, 0x67C4, 0xB1FB, 0x4E19, 0xB1FC, 0x79C9, 0xB1FD, 0x997C, + 0xB1FE, 0x70B3, 0xB240, 0x775D, 0xB241, 0x775E, 0xB242, 0x775F, + 0xB243, 0x7760, 0xB244, 0x7764, 0xB245, 0x7767, 0xB246, 0x7769, + 0xB247, 0x776A, 0xB248, 0x776D, 0xB249, 0x776E, 0xB24A, 0x776F, + 0xB24B, 0x7770, 0xB24C, 0x7771, 0xB24D, 0x7772, 0xB24E, 0x7773, + 0xB24F, 0x7774, 0xB250, 0x7775, 0xB251, 0x7776, 0xB252, 0x7777, + 0xB253, 0x7778, 0xB254, 0x777A, 0xB255, 0x777B, 0xB256, 0x777C, + 0xB257, 0x7781, 0xB258, 0x7782, 0xB259, 0x7783, 0xB25A, 0x7786, + 0xB25B, 0x7787, 0xB25C, 0x7788, 0xB25D, 0x7789, 0xB25E, 0x778A, + 0xB25F, 0x778B, 0xB260, 0x778F, 0xB261, 0x7790, 0xB262, 0x7793, + 0xB263, 0x7794, 0xB264, 0x7795, 0xB265, 0x7796, 0xB266, 0x7797, + 0xB267, 0x7798, 0xB268, 0x7799, 0xB269, 0x779A, 0xB26A, 0x779B, + 0xB26B, 0x779C, 0xB26C, 0x779D, 0xB26D, 0x779E, 0xB26E, 0x77A1, + 0xB26F, 0x77A3, 0xB270, 0x77A4, 0xB271, 0x77A6, 0xB272, 0x77A8, + 0xB273, 0x77AB, 0xB274, 0x77AD, 0xB275, 0x77AE, 0xB276, 0x77AF, + 0xB277, 0x77B1, 0xB278, 0x77B2, 0xB279, 0x77B4, 0xB27A, 0x77B6, + 0xB27B, 0x77B7, 0xB27C, 0x77B8, 0xB27D, 0x77B9, 0xB27E, 0x77BA, + 0xB280, 0x77BC, 0xB281, 0x77BE, 0xB282, 0x77C0, 0xB283, 0x77C1, + 0xB284, 0x77C2, 0xB285, 0x77C3, 0xB286, 0x77C4, 0xB287, 0x77C5, + 0xB288, 0x77C6, 0xB289, 0x77C7, 0xB28A, 0x77C8, 0xB28B, 0x77C9, + 0xB28C, 0x77CA, 0xB28D, 0x77CB, 0xB28E, 0x77CC, 0xB28F, 0x77CE, + 0xB290, 0x77CF, 0xB291, 0x77D0, 0xB292, 0x77D1, 0xB293, 0x77D2, + 0xB294, 0x77D3, 0xB295, 0x77D4, 0xB296, 0x77D5, 0xB297, 0x77D6, + 0xB298, 0x77D8, 0xB299, 0x77D9, 0xB29A, 0x77DA, 0xB29B, 0x77DD, + 0xB29C, 0x77DE, 0xB29D, 0x77DF, 0xB29E, 0x77E0, 0xB29F, 0x77E1, + 0xB2A0, 0x77E4, 0xB2A1, 0x75C5, 0xB2A2, 0x5E76, 0xB2A3, 0x73BB, + 0xB2A4, 0x83E0, 0xB2A5, 0x64AD, 0xB2A6, 0x62E8, 0xB2A7, 0x94B5, + 0xB2A8, 0x6CE2, 0xB2A9, 0x535A, 0xB2AA, 0x52C3, 0xB2AB, 0x640F, + 0xB2AC, 0x94C2, 0xB2AD, 0x7B94, 0xB2AE, 0x4F2F, 0xB2AF, 0x5E1B, + 0xB2B0, 0x8236, 0xB2B1, 0x8116, 0xB2B2, 0x818A, 0xB2B3, 0x6E24, + 0xB2B4, 0x6CCA, 0xB2B5, 0x9A73, 0xB2B6, 0x6355, 0xB2B7, 0x535C, + 0xB2B8, 0x54FA, 0xB2B9, 0x8865, 0xB2BA, 0x57E0, 0xB2BB, 0x4E0D, + 0xB2BC, 0x5E03, 0xB2BD, 0x6B65, 0xB2BE, 0x7C3F, 0xB2BF, 0x90E8, + 0xB2C0, 0x6016, 0xB2C1, 0x64E6, 0xB2C2, 0x731C, 0xB2C3, 0x88C1, + 0xB2C4, 0x6750, 0xB2C5, 0x624D, 0xB2C6, 0x8D22, 0xB2C7, 0x776C, + 0xB2C8, 0x8E29, 0xB2C9, 0x91C7, 0xB2CA, 0x5F69, 0xB2CB, 0x83DC, + 0xB2CC, 0x8521, 0xB2CD, 0x9910, 0xB2CE, 0x53C2, 0xB2CF, 0x8695, + 0xB2D0, 0x6B8B, 0xB2D1, 0x60ED, 0xB2D2, 0x60E8, 0xB2D3, 0x707F, + 0xB2D4, 0x82CD, 0xB2D5, 0x8231, 0xB2D6, 0x4ED3, 0xB2D7, 0x6CA7, + 0xB2D8, 0x85CF, 0xB2D9, 0x64CD, 0xB2DA, 0x7CD9, 0xB2DB, 0x69FD, + 0xB2DC, 0x66F9, 0xB2DD, 0x8349, 0xB2DE, 0x5395, 0xB2DF, 0x7B56, + 0xB2E0, 0x4FA7, 0xB2E1, 0x518C, 0xB2E2, 0x6D4B, 0xB2E3, 0x5C42, + 0xB2E4, 0x8E6D, 0xB2E5, 0x63D2, 0xB2E6, 0x53C9, 0xB2E7, 0x832C, + 0xB2E8, 0x8336, 0xB2E9, 0x67E5, 0xB2EA, 0x78B4, 0xB2EB, 0x643D, + 0xB2EC, 0x5BDF, 0xB2ED, 0x5C94, 0xB2EE, 0x5DEE, 0xB2EF, 0x8BE7, + 0xB2F0, 0x62C6, 0xB2F1, 0x67F4, 0xB2F2, 0x8C7A, 0xB2F3, 0x6400, + 0xB2F4, 0x63BA, 0xB2F5, 0x8749, 0xB2F6, 0x998B, 0xB2F7, 0x8C17, + 0xB2F8, 0x7F20, 0xB2F9, 0x94F2, 0xB2FA, 0x4EA7, 0xB2FB, 0x9610, + 0xB2FC, 0x98A4, 0xB2FD, 0x660C, 0xB2FE, 0x7316, 0xB340, 0x77E6, + 0xB341, 0x77E8, 0xB342, 0x77EA, 0xB343, 0x77EF, 0xB344, 0x77F0, + 0xB345, 0x77F1, 0xB346, 0x77F2, 0xB347, 0x77F4, 0xB348, 0x77F5, + 0xB349, 0x77F7, 0xB34A, 0x77F9, 0xB34B, 0x77FA, 0xB34C, 0x77FB, + 0xB34D, 0x77FC, 0xB34E, 0x7803, 0xB34F, 0x7804, 0xB350, 0x7805, + 0xB351, 0x7806, 0xB352, 0x7807, 0xB353, 0x7808, 0xB354, 0x780A, + 0xB355, 0x780B, 0xB356, 0x780E, 0xB357, 0x780F, 0xB358, 0x7810, + 0xB359, 0x7813, 0xB35A, 0x7815, 0xB35B, 0x7819, 0xB35C, 0x781B, + 0xB35D, 0x781E, 0xB35E, 0x7820, 0xB35F, 0x7821, 0xB360, 0x7822, + 0xB361, 0x7824, 0xB362, 0x7828, 0xB363, 0x782A, 0xB364, 0x782B, + 0xB365, 0x782E, 0xB366, 0x782F, 0xB367, 0x7831, 0xB368, 0x7832, + 0xB369, 0x7833, 0xB36A, 0x7835, 0xB36B, 0x7836, 0xB36C, 0x783D, + 0xB36D, 0x783F, 0xB36E, 0x7841, 0xB36F, 0x7842, 0xB370, 0x7843, + 0xB371, 0x7844, 0xB372, 0x7846, 0xB373, 0x7848, 0xB374, 0x7849, + 0xB375, 0x784A, 0xB376, 0x784B, 0xB377, 0x784D, 0xB378, 0x784F, + 0xB379, 0x7851, 0xB37A, 0x7853, 0xB37B, 0x7854, 0xB37C, 0x7858, + 0xB37D, 0x7859, 0xB37E, 0x785A, 0xB380, 0x785B, 0xB381, 0x785C, + 0xB382, 0x785E, 0xB383, 0x785F, 0xB384, 0x7860, 0xB385, 0x7861, + 0xB386, 0x7862, 0xB387, 0x7863, 0xB388, 0x7864, 0xB389, 0x7865, + 0xB38A, 0x7866, 0xB38B, 0x7867, 0xB38C, 0x7868, 0xB38D, 0x7869, + 0xB38E, 0x786F, 0xB38F, 0x7870, 0xB390, 0x7871, 0xB391, 0x7872, + 0xB392, 0x7873, 0xB393, 0x7874, 0xB394, 0x7875, 0xB395, 0x7876, + 0xB396, 0x7878, 0xB397, 0x7879, 0xB398, 0x787A, 0xB399, 0x787B, + 0xB39A, 0x787D, 0xB39B, 0x787E, 0xB39C, 0x787F, 0xB39D, 0x7880, + 0xB39E, 0x7881, 0xB39F, 0x7882, 0xB3A0, 0x7883, 0xB3A1, 0x573A, + 0xB3A2, 0x5C1D, 0xB3A3, 0x5E38, 0xB3A4, 0x957F, 0xB3A5, 0x507F, + 0xB3A6, 0x80A0, 0xB3A7, 0x5382, 0xB3A8, 0x655E, 0xB3A9, 0x7545, + 0xB3AA, 0x5531, 0xB3AB, 0x5021, 0xB3AC, 0x8D85, 0xB3AD, 0x6284, + 0xB3AE, 0x949E, 0xB3AF, 0x671D, 0xB3B0, 0x5632, 0xB3B1, 0x6F6E, + 0xB3B2, 0x5DE2, 0xB3B3, 0x5435, 0xB3B4, 0x7092, 0xB3B5, 0x8F66, + 0xB3B6, 0x626F, 0xB3B7, 0x64A4, 0xB3B8, 0x63A3, 0xB3B9, 0x5F7B, + 0xB3BA, 0x6F88, 0xB3BB, 0x90F4, 0xB3BC, 0x81E3, 0xB3BD, 0x8FB0, + 0xB3BE, 0x5C18, 0xB3BF, 0x6668, 0xB3C0, 0x5FF1, 0xB3C1, 0x6C89, + 0xB3C2, 0x9648, 0xB3C3, 0x8D81, 0xB3C4, 0x886C, 0xB3C5, 0x6491, + 0xB3C6, 0x79F0, 0xB3C7, 0x57CE, 0xB3C8, 0x6A59, 0xB3C9, 0x6210, + 0xB3CA, 0x5448, 0xB3CB, 0x4E58, 0xB3CC, 0x7A0B, 0xB3CD, 0x60E9, + 0xB3CE, 0x6F84, 0xB3CF, 0x8BDA, 0xB3D0, 0x627F, 0xB3D1, 0x901E, + 0xB3D2, 0x9A8B, 0xB3D3, 0x79E4, 0xB3D4, 0x5403, 0xB3D5, 0x75F4, + 0xB3D6, 0x6301, 0xB3D7, 0x5319, 0xB3D8, 0x6C60, 0xB3D9, 0x8FDF, + 0xB3DA, 0x5F1B, 0xB3DB, 0x9A70, 0xB3DC, 0x803B, 0xB3DD, 0x9F7F, + 0xB3DE, 0x4F88, 0xB3DF, 0x5C3A, 0xB3E0, 0x8D64, 0xB3E1, 0x7FC5, + 0xB3E2, 0x65A5, 0xB3E3, 0x70BD, 0xB3E4, 0x5145, 0xB3E5, 0x51B2, + 0xB3E6, 0x866B, 0xB3E7, 0x5D07, 0xB3E8, 0x5BA0, 0xB3E9, 0x62BD, + 0xB3EA, 0x916C, 0xB3EB, 0x7574, 0xB3EC, 0x8E0C, 0xB3ED, 0x7A20, + 0xB3EE, 0x6101, 0xB3EF, 0x7B79, 0xB3F0, 0x4EC7, 0xB3F1, 0x7EF8, + 0xB3F2, 0x7785, 0xB3F3, 0x4E11, 0xB3F4, 0x81ED, 0xB3F5, 0x521D, + 0xB3F6, 0x51FA, 0xB3F7, 0x6A71, 0xB3F8, 0x53A8, 0xB3F9, 0x8E87, + 0xB3FA, 0x9504, 0xB3FB, 0x96CF, 0xB3FC, 0x6EC1, 0xB3FD, 0x9664, + 0xB3FE, 0x695A, 0xB440, 0x7884, 0xB441, 0x7885, 0xB442, 0x7886, + 0xB443, 0x7888, 0xB444, 0x788A, 0xB445, 0x788B, 0xB446, 0x788F, + 0xB447, 0x7890, 0xB448, 0x7892, 0xB449, 0x7894, 0xB44A, 0x7895, + 0xB44B, 0x7896, 0xB44C, 0x7899, 0xB44D, 0x789D, 0xB44E, 0x789E, + 0xB44F, 0x78A0, 0xB450, 0x78A2, 0xB451, 0x78A4, 0xB452, 0x78A6, + 0xB453, 0x78A8, 0xB454, 0x78A9, 0xB455, 0x78AA, 0xB456, 0x78AB, + 0xB457, 0x78AC, 0xB458, 0x78AD, 0xB459, 0x78AE, 0xB45A, 0x78AF, + 0xB45B, 0x78B5, 0xB45C, 0x78B6, 0xB45D, 0x78B7, 0xB45E, 0x78B8, + 0xB45F, 0x78BA, 0xB460, 0x78BB, 0xB461, 0x78BC, 0xB462, 0x78BD, + 0xB463, 0x78BF, 0xB464, 0x78C0, 0xB465, 0x78C2, 0xB466, 0x78C3, + 0xB467, 0x78C4, 0xB468, 0x78C6, 0xB469, 0x78C7, 0xB46A, 0x78C8, + 0xB46B, 0x78CC, 0xB46C, 0x78CD, 0xB46D, 0x78CE, 0xB46E, 0x78CF, + 0xB46F, 0x78D1, 0xB470, 0x78D2, 0xB471, 0x78D3, 0xB472, 0x78D6, + 0xB473, 0x78D7, 0xB474, 0x78D8, 0xB475, 0x78DA, 0xB476, 0x78DB, + 0xB477, 0x78DC, 0xB478, 0x78DD, 0xB479, 0x78DE, 0xB47A, 0x78DF, + 0xB47B, 0x78E0, 0xB47C, 0x78E1, 0xB47D, 0x78E2, 0xB47E, 0x78E3, + 0xB480, 0x78E4, 0xB481, 0x78E5, 0xB482, 0x78E6, 0xB483, 0x78E7, + 0xB484, 0x78E9, 0xB485, 0x78EA, 0xB486, 0x78EB, 0xB487, 0x78ED, + 0xB488, 0x78EE, 0xB489, 0x78EF, 0xB48A, 0x78F0, 0xB48B, 0x78F1, + 0xB48C, 0x78F3, 0xB48D, 0x78F5, 0xB48E, 0x78F6, 0xB48F, 0x78F8, + 0xB490, 0x78F9, 0xB491, 0x78FB, 0xB492, 0x78FC, 0xB493, 0x78FD, + 0xB494, 0x78FE, 0xB495, 0x78FF, 0xB496, 0x7900, 0xB497, 0x7902, + 0xB498, 0x7903, 0xB499, 0x7904, 0xB49A, 0x7906, 0xB49B, 0x7907, + 0xB49C, 0x7908, 0xB49D, 0x7909, 0xB49E, 0x790A, 0xB49F, 0x790B, + 0xB4A0, 0x790C, 0xB4A1, 0x7840, 0xB4A2, 0x50A8, 0xB4A3, 0x77D7, + 0xB4A4, 0x6410, 0xB4A5, 0x89E6, 0xB4A6, 0x5904, 0xB4A7, 0x63E3, + 0xB4A8, 0x5DDD, 0xB4A9, 0x7A7F, 0xB4AA, 0x693D, 0xB4AB, 0x4F20, + 0xB4AC, 0x8239, 0xB4AD, 0x5598, 0xB4AE, 0x4E32, 0xB4AF, 0x75AE, + 0xB4B0, 0x7A97, 0xB4B1, 0x5E62, 0xB4B2, 0x5E8A, 0xB4B3, 0x95EF, + 0xB4B4, 0x521B, 0xB4B5, 0x5439, 0xB4B6, 0x708A, 0xB4B7, 0x6376, + 0xB4B8, 0x9524, 0xB4B9, 0x5782, 0xB4BA, 0x6625, 0xB4BB, 0x693F, + 0xB4BC, 0x9187, 0xB4BD, 0x5507, 0xB4BE, 0x6DF3, 0xB4BF, 0x7EAF, + 0xB4C0, 0x8822, 0xB4C1, 0x6233, 0xB4C2, 0x7EF0, 0xB4C3, 0x75B5, + 0xB4C4, 0x8328, 0xB4C5, 0x78C1, 0xB4C6, 0x96CC, 0xB4C7, 0x8F9E, + 0xB4C8, 0x6148, 0xB4C9, 0x74F7, 0xB4CA, 0x8BCD, 0xB4CB, 0x6B64, + 0xB4CC, 0x523A, 0xB4CD, 0x8D50, 0xB4CE, 0x6B21, 0xB4CF, 0x806A, + 0xB4D0, 0x8471, 0xB4D1, 0x56F1, 0xB4D2, 0x5306, 0xB4D3, 0x4ECE, + 0xB4D4, 0x4E1B, 0xB4D5, 0x51D1, 0xB4D6, 0x7C97, 0xB4D7, 0x918B, + 0xB4D8, 0x7C07, 0xB4D9, 0x4FC3, 0xB4DA, 0x8E7F, 0xB4DB, 0x7BE1, + 0xB4DC, 0x7A9C, 0xB4DD, 0x6467, 0xB4DE, 0x5D14, 0xB4DF, 0x50AC, + 0xB4E0, 0x8106, 0xB4E1, 0x7601, 0xB4E2, 0x7CB9, 0xB4E3, 0x6DEC, + 0xB4E4, 0x7FE0, 0xB4E5, 0x6751, 0xB4E6, 0x5B58, 0xB4E7, 0x5BF8, + 0xB4E8, 0x78CB, 0xB4E9, 0x64AE, 0xB4EA, 0x6413, 0xB4EB, 0x63AA, + 0xB4EC, 0x632B, 0xB4ED, 0x9519, 0xB4EE, 0x642D, 0xB4EF, 0x8FBE, + 0xB4F0, 0x7B54, 0xB4F1, 0x7629, 0xB4F2, 0x6253, 0xB4F3, 0x5927, + 0xB4F4, 0x5446, 0xB4F5, 0x6B79, 0xB4F6, 0x50A3, 0xB4F7, 0x6234, + 0xB4F8, 0x5E26, 0xB4F9, 0x6B86, 0xB4FA, 0x4EE3, 0xB4FB, 0x8D37, + 0xB4FC, 0x888B, 0xB4FD, 0x5F85, 0xB4FE, 0x902E, 0xB540, 0x790D, + 0xB541, 0x790E, 0xB542, 0x790F, 0xB543, 0x7910, 0xB544, 0x7911, + 0xB545, 0x7912, 0xB546, 0x7914, 0xB547, 0x7915, 0xB548, 0x7916, + 0xB549, 0x7917, 0xB54A, 0x7918, 0xB54B, 0x7919, 0xB54C, 0x791A, + 0xB54D, 0x791B, 0xB54E, 0x791C, 0xB54F, 0x791D, 0xB550, 0x791F, + 0xB551, 0x7920, 0xB552, 0x7921, 0xB553, 0x7922, 0xB554, 0x7923, + 0xB555, 0x7925, 0xB556, 0x7926, 0xB557, 0x7927, 0xB558, 0x7928, + 0xB559, 0x7929, 0xB55A, 0x792A, 0xB55B, 0x792B, 0xB55C, 0x792C, + 0xB55D, 0x792D, 0xB55E, 0x792E, 0xB55F, 0x792F, 0xB560, 0x7930, + 0xB561, 0x7931, 0xB562, 0x7932, 0xB563, 0x7933, 0xB564, 0x7935, + 0xB565, 0x7936, 0xB566, 0x7937, 0xB567, 0x7938, 0xB568, 0x7939, + 0xB569, 0x793D, 0xB56A, 0x793F, 0xB56B, 0x7942, 0xB56C, 0x7943, + 0xB56D, 0x7944, 0xB56E, 0x7945, 0xB56F, 0x7947, 0xB570, 0x794A, + 0xB571, 0x794B, 0xB572, 0x794C, 0xB573, 0x794D, 0xB574, 0x794E, + 0xB575, 0x794F, 0xB576, 0x7950, 0xB577, 0x7951, 0xB578, 0x7952, + 0xB579, 0x7954, 0xB57A, 0x7955, 0xB57B, 0x7958, 0xB57C, 0x7959, + 0xB57D, 0x7961, 0xB57E, 0x7963, 0xB580, 0x7964, 0xB581, 0x7966, + 0xB582, 0x7969, 0xB583, 0x796A, 0xB584, 0x796B, 0xB585, 0x796C, + 0xB586, 0x796E, 0xB587, 0x7970, 0xB588, 0x7971, 0xB589, 0x7972, + 0xB58A, 0x7973, 0xB58B, 0x7974, 0xB58C, 0x7975, 0xB58D, 0x7976, + 0xB58E, 0x7979, 0xB58F, 0x797B, 0xB590, 0x797C, 0xB591, 0x797D, + 0xB592, 0x797E, 0xB593, 0x797F, 0xB594, 0x7982, 0xB595, 0x7983, + 0xB596, 0x7986, 0xB597, 0x7987, 0xB598, 0x7988, 0xB599, 0x7989, + 0xB59A, 0x798B, 0xB59B, 0x798C, 0xB59C, 0x798D, 0xB59D, 0x798E, + 0xB59E, 0x7990, 0xB59F, 0x7991, 0xB5A0, 0x7992, 0xB5A1, 0x6020, + 0xB5A2, 0x803D, 0xB5A3, 0x62C5, 0xB5A4, 0x4E39, 0xB5A5, 0x5355, + 0xB5A6, 0x90F8, 0xB5A7, 0x63B8, 0xB5A8, 0x80C6, 0xB5A9, 0x65E6, + 0xB5AA, 0x6C2E, 0xB5AB, 0x4F46, 0xB5AC, 0x60EE, 0xB5AD, 0x6DE1, + 0xB5AE, 0x8BDE, 0xB5AF, 0x5F39, 0xB5B0, 0x86CB, 0xB5B1, 0x5F53, + 0xB5B2, 0x6321, 0xB5B3, 0x515A, 0xB5B4, 0x8361, 0xB5B5, 0x6863, + 0xB5B6, 0x5200, 0xB5B7, 0x6363, 0xB5B8, 0x8E48, 0xB5B9, 0x5012, + 0xB5BA, 0x5C9B, 0xB5BB, 0x7977, 0xB5BC, 0x5BFC, 0xB5BD, 0x5230, + 0xB5BE, 0x7A3B, 0xB5BF, 0x60BC, 0xB5C0, 0x9053, 0xB5C1, 0x76D7, + 0xB5C2, 0x5FB7, 0xB5C3, 0x5F97, 0xB5C4, 0x7684, 0xB5C5, 0x8E6C, + 0xB5C6, 0x706F, 0xB5C7, 0x767B, 0xB5C8, 0x7B49, 0xB5C9, 0x77AA, + 0xB5CA, 0x51F3, 0xB5CB, 0x9093, 0xB5CC, 0x5824, 0xB5CD, 0x4F4E, + 0xB5CE, 0x6EF4, 0xB5CF, 0x8FEA, 0xB5D0, 0x654C, 0xB5D1, 0x7B1B, + 0xB5D2, 0x72C4, 0xB5D3, 0x6DA4, 0xB5D4, 0x7FDF, 0xB5D5, 0x5AE1, + 0xB5D6, 0x62B5, 0xB5D7, 0x5E95, 0xB5D8, 0x5730, 0xB5D9, 0x8482, + 0xB5DA, 0x7B2C, 0xB5DB, 0x5E1D, 0xB5DC, 0x5F1F, 0xB5DD, 0x9012, + 0xB5DE, 0x7F14, 0xB5DF, 0x98A0, 0xB5E0, 0x6382, 0xB5E1, 0x6EC7, + 0xB5E2, 0x7898, 0xB5E3, 0x70B9, 0xB5E4, 0x5178, 0xB5E5, 0x975B, + 0xB5E6, 0x57AB, 0xB5E7, 0x7535, 0xB5E8, 0x4F43, 0xB5E9, 0x7538, + 0xB5EA, 0x5E97, 0xB5EB, 0x60E6, 0xB5EC, 0x5960, 0xB5ED, 0x6DC0, + 0xB5EE, 0x6BBF, 0xB5EF, 0x7889, 0xB5F0, 0x53FC, 0xB5F1, 0x96D5, + 0xB5F2, 0x51CB, 0xB5F3, 0x5201, 0xB5F4, 0x6389, 0xB5F5, 0x540A, + 0xB5F6, 0x9493, 0xB5F7, 0x8C03, 0xB5F8, 0x8DCC, 0xB5F9, 0x7239, + 0xB5FA, 0x789F, 0xB5FB, 0x8776, 0xB5FC, 0x8FED, 0xB5FD, 0x8C0D, + 0xB5FE, 0x53E0, 0xB640, 0x7993, 0xB641, 0x7994, 0xB642, 0x7995, + 0xB643, 0x7996, 0xB644, 0x7997, 0xB645, 0x7998, 0xB646, 0x7999, + 0xB647, 0x799B, 0xB648, 0x799C, 0xB649, 0x799D, 0xB64A, 0x799E, + 0xB64B, 0x799F, 0xB64C, 0x79A0, 0xB64D, 0x79A1, 0xB64E, 0x79A2, + 0xB64F, 0x79A3, 0xB650, 0x79A4, 0xB651, 0x79A5, 0xB652, 0x79A6, + 0xB653, 0x79A8, 0xB654, 0x79A9, 0xB655, 0x79AA, 0xB656, 0x79AB, + 0xB657, 0x79AC, 0xB658, 0x79AD, 0xB659, 0x79AE, 0xB65A, 0x79AF, + 0xB65B, 0x79B0, 0xB65C, 0x79B1, 0xB65D, 0x79B2, 0xB65E, 0x79B4, + 0xB65F, 0x79B5, 0xB660, 0x79B6, 0xB661, 0x79B7, 0xB662, 0x79B8, + 0xB663, 0x79BC, 0xB664, 0x79BF, 0xB665, 0x79C2, 0xB666, 0x79C4, + 0xB667, 0x79C5, 0xB668, 0x79C7, 0xB669, 0x79C8, 0xB66A, 0x79CA, + 0xB66B, 0x79CC, 0xB66C, 0x79CE, 0xB66D, 0x79CF, 0xB66E, 0x79D0, + 0xB66F, 0x79D3, 0xB670, 0x79D4, 0xB671, 0x79D6, 0xB672, 0x79D7, + 0xB673, 0x79D9, 0xB674, 0x79DA, 0xB675, 0x79DB, 0xB676, 0x79DC, + 0xB677, 0x79DD, 0xB678, 0x79DE, 0xB679, 0x79E0, 0xB67A, 0x79E1, + 0xB67B, 0x79E2, 0xB67C, 0x79E5, 0xB67D, 0x79E8, 0xB67E, 0x79EA, + 0xB680, 0x79EC, 0xB681, 0x79EE, 0xB682, 0x79F1, 0xB683, 0x79F2, + 0xB684, 0x79F3, 0xB685, 0x79F4, 0xB686, 0x79F5, 0xB687, 0x79F6, + 0xB688, 0x79F7, 0xB689, 0x79F9, 0xB68A, 0x79FA, 0xB68B, 0x79FC, + 0xB68C, 0x79FE, 0xB68D, 0x79FF, 0xB68E, 0x7A01, 0xB68F, 0x7A04, + 0xB690, 0x7A05, 0xB691, 0x7A07, 0xB692, 0x7A08, 0xB693, 0x7A09, + 0xB694, 0x7A0A, 0xB695, 0x7A0C, 0xB696, 0x7A0F, 0xB697, 0x7A10, + 0xB698, 0x7A11, 0xB699, 0x7A12, 0xB69A, 0x7A13, 0xB69B, 0x7A15, + 0xB69C, 0x7A16, 0xB69D, 0x7A18, 0xB69E, 0x7A19, 0xB69F, 0x7A1B, + 0xB6A0, 0x7A1C, 0xB6A1, 0x4E01, 0xB6A2, 0x76EF, 0xB6A3, 0x53EE, + 0xB6A4, 0x9489, 0xB6A5, 0x9876, 0xB6A6, 0x9F0E, 0xB6A7, 0x952D, + 0xB6A8, 0x5B9A, 0xB6A9, 0x8BA2, 0xB6AA, 0x4E22, 0xB6AB, 0x4E1C, + 0xB6AC, 0x51AC, 0xB6AD, 0x8463, 0xB6AE, 0x61C2, 0xB6AF, 0x52A8, + 0xB6B0, 0x680B, 0xB6B1, 0x4F97, 0xB6B2, 0x606B, 0xB6B3, 0x51BB, + 0xB6B4, 0x6D1E, 0xB6B5, 0x515C, 0xB6B6, 0x6296, 0xB6B7, 0x6597, + 0xB6B8, 0x9661, 0xB6B9, 0x8C46, 0xB6BA, 0x9017, 0xB6BB, 0x75D8, + 0xB6BC, 0x90FD, 0xB6BD, 0x7763, 0xB6BE, 0x6BD2, 0xB6BF, 0x728A, + 0xB6C0, 0x72EC, 0xB6C1, 0x8BFB, 0xB6C2, 0x5835, 0xB6C3, 0x7779, + 0xB6C4, 0x8D4C, 0xB6C5, 0x675C, 0xB6C6, 0x9540, 0xB6C7, 0x809A, + 0xB6C8, 0x5EA6, 0xB6C9, 0x6E21, 0xB6CA, 0x5992, 0xB6CB, 0x7AEF, + 0xB6CC, 0x77ED, 0xB6CD, 0x953B, 0xB6CE, 0x6BB5, 0xB6CF, 0x65AD, + 0xB6D0, 0x7F0E, 0xB6D1, 0x5806, 0xB6D2, 0x5151, 0xB6D3, 0x961F, + 0xB6D4, 0x5BF9, 0xB6D5, 0x58A9, 0xB6D6, 0x5428, 0xB6D7, 0x8E72, + 0xB6D8, 0x6566, 0xB6D9, 0x987F, 0xB6DA, 0x56E4, 0xB6DB, 0x949D, + 0xB6DC, 0x76FE, 0xB6DD, 0x9041, 0xB6DE, 0x6387, 0xB6DF, 0x54C6, + 0xB6E0, 0x591A, 0xB6E1, 0x593A, 0xB6E2, 0x579B, 0xB6E3, 0x8EB2, + 0xB6E4, 0x6735, 0xB6E5, 0x8DFA, 0xB6E6, 0x8235, 0xB6E7, 0x5241, + 0xB6E8, 0x60F0, 0xB6E9, 0x5815, 0xB6EA, 0x86FE, 0xB6EB, 0x5CE8, + 0xB6EC, 0x9E45, 0xB6ED, 0x4FC4, 0xB6EE, 0x989D, 0xB6EF, 0x8BB9, + 0xB6F0, 0x5A25, 0xB6F1, 0x6076, 0xB6F2, 0x5384, 0xB6F3, 0x627C, + 0xB6F4, 0x904F, 0xB6F5, 0x9102, 0xB6F6, 0x997F, 0xB6F7, 0x6069, + 0xB6F8, 0x800C, 0xB6F9, 0x513F, 0xB6FA, 0x8033, 0xB6FB, 0x5C14, + 0xB6FC, 0x9975, 0xB6FD, 0x6D31, 0xB6FE, 0x4E8C, 0xB740, 0x7A1D, + 0xB741, 0x7A1F, 0xB742, 0x7A21, 0xB743, 0x7A22, 0xB744, 0x7A24, + 0xB745, 0x7A25, 0xB746, 0x7A26, 0xB747, 0x7A27, 0xB748, 0x7A28, + 0xB749, 0x7A29, 0xB74A, 0x7A2A, 0xB74B, 0x7A2B, 0xB74C, 0x7A2C, + 0xB74D, 0x7A2D, 0xB74E, 0x7A2E, 0xB74F, 0x7A2F, 0xB750, 0x7A30, + 0xB751, 0x7A31, 0xB752, 0x7A32, 0xB753, 0x7A34, 0xB754, 0x7A35, + 0xB755, 0x7A36, 0xB756, 0x7A38, 0xB757, 0x7A3A, 0xB758, 0x7A3E, + 0xB759, 0x7A40, 0xB75A, 0x7A41, 0xB75B, 0x7A42, 0xB75C, 0x7A43, + 0xB75D, 0x7A44, 0xB75E, 0x7A45, 0xB75F, 0x7A47, 0xB760, 0x7A48, + 0xB761, 0x7A49, 0xB762, 0x7A4A, 0xB763, 0x7A4B, 0xB764, 0x7A4C, + 0xB765, 0x7A4D, 0xB766, 0x7A4E, 0xB767, 0x7A4F, 0xB768, 0x7A50, + 0xB769, 0x7A52, 0xB76A, 0x7A53, 0xB76B, 0x7A54, 0xB76C, 0x7A55, + 0xB76D, 0x7A56, 0xB76E, 0x7A58, 0xB76F, 0x7A59, 0xB770, 0x7A5A, + 0xB771, 0x7A5B, 0xB772, 0x7A5C, 0xB773, 0x7A5D, 0xB774, 0x7A5E, + 0xB775, 0x7A5F, 0xB776, 0x7A60, 0xB777, 0x7A61, 0xB778, 0x7A62, + 0xB779, 0x7A63, 0xB77A, 0x7A64, 0xB77B, 0x7A65, 0xB77C, 0x7A66, + 0xB77D, 0x7A67, 0xB77E, 0x7A68, 0xB780, 0x7A69, 0xB781, 0x7A6A, + 0xB782, 0x7A6B, 0xB783, 0x7A6C, 0xB784, 0x7A6D, 0xB785, 0x7A6E, + 0xB786, 0x7A6F, 0xB787, 0x7A71, 0xB788, 0x7A72, 0xB789, 0x7A73, + 0xB78A, 0x7A75, 0xB78B, 0x7A7B, 0xB78C, 0x7A7C, 0xB78D, 0x7A7D, + 0xB78E, 0x7A7E, 0xB78F, 0x7A82, 0xB790, 0x7A85, 0xB791, 0x7A87, + 0xB792, 0x7A89, 0xB793, 0x7A8A, 0xB794, 0x7A8B, 0xB795, 0x7A8C, + 0xB796, 0x7A8E, 0xB797, 0x7A8F, 0xB798, 0x7A90, 0xB799, 0x7A93, + 0xB79A, 0x7A94, 0xB79B, 0x7A99, 0xB79C, 0x7A9A, 0xB79D, 0x7A9B, + 0xB79E, 0x7A9E, 0xB79F, 0x7AA1, 0xB7A0, 0x7AA2, 0xB7A1, 0x8D30, + 0xB7A2, 0x53D1, 0xB7A3, 0x7F5A, 0xB7A4, 0x7B4F, 0xB7A5, 0x4F10, + 0xB7A6, 0x4E4F, 0xB7A7, 0x9600, 0xB7A8, 0x6CD5, 0xB7A9, 0x73D0, + 0xB7AA, 0x85E9, 0xB7AB, 0x5E06, 0xB7AC, 0x756A, 0xB7AD, 0x7FFB, + 0xB7AE, 0x6A0A, 0xB7AF, 0x77FE, 0xB7B0, 0x9492, 0xB7B1, 0x7E41, + 0xB7B2, 0x51E1, 0xB7B3, 0x70E6, 0xB7B4, 0x53CD, 0xB7B5, 0x8FD4, + 0xB7B6, 0x8303, 0xB7B7, 0x8D29, 0xB7B8, 0x72AF, 0xB7B9, 0x996D, + 0xB7BA, 0x6CDB, 0xB7BB, 0x574A, 0xB7BC, 0x82B3, 0xB7BD, 0x65B9, + 0xB7BE, 0x80AA, 0xB7BF, 0x623F, 0xB7C0, 0x9632, 0xB7C1, 0x59A8, + 0xB7C2, 0x4EFF, 0xB7C3, 0x8BBF, 0xB7C4, 0x7EBA, 0xB7C5, 0x653E, + 0xB7C6, 0x83F2, 0xB7C7, 0x975E, 0xB7C8, 0x5561, 0xB7C9, 0x98DE, + 0xB7CA, 0x80A5, 0xB7CB, 0x532A, 0xB7CC, 0x8BFD, 0xB7CD, 0x5420, + 0xB7CE, 0x80BA, 0xB7CF, 0x5E9F, 0xB7D0, 0x6CB8, 0xB7D1, 0x8D39, + 0xB7D2, 0x82AC, 0xB7D3, 0x915A, 0xB7D4, 0x5429, 0xB7D5, 0x6C1B, + 0xB7D6, 0x5206, 0xB7D7, 0x7EB7, 0xB7D8, 0x575F, 0xB7D9, 0x711A, + 0xB7DA, 0x6C7E, 0xB7DB, 0x7C89, 0xB7DC, 0x594B, 0xB7DD, 0x4EFD, + 0xB7DE, 0x5FFF, 0xB7DF, 0x6124, 0xB7E0, 0x7CAA, 0xB7E1, 0x4E30, + 0xB7E2, 0x5C01, 0xB7E3, 0x67AB, 0xB7E4, 0x8702, 0xB7E5, 0x5CF0, + 0xB7E6, 0x950B, 0xB7E7, 0x98CE, 0xB7E8, 0x75AF, 0xB7E9, 0x70FD, + 0xB7EA, 0x9022, 0xB7EB, 0x51AF, 0xB7EC, 0x7F1D, 0xB7ED, 0x8BBD, + 0xB7EE, 0x5949, 0xB7EF, 0x51E4, 0xB7F0, 0x4F5B, 0xB7F1, 0x5426, + 0xB7F2, 0x592B, 0xB7F3, 0x6577, 0xB7F4, 0x80A4, 0xB7F5, 0x5B75, + 0xB7F6, 0x6276, 0xB7F7, 0x62C2, 0xB7F8, 0x8F90, 0xB7F9, 0x5E45, + 0xB7FA, 0x6C1F, 0xB7FB, 0x7B26, 0xB7FC, 0x4F0F, 0xB7FD, 0x4FD8, + 0xB7FE, 0x670D, 0xB840, 0x7AA3, 0xB841, 0x7AA4, 0xB842, 0x7AA7, + 0xB843, 0x7AA9, 0xB844, 0x7AAA, 0xB845, 0x7AAB, 0xB846, 0x7AAE, + 0xB847, 0x7AAF, 0xB848, 0x7AB0, 0xB849, 0x7AB1, 0xB84A, 0x7AB2, + 0xB84B, 0x7AB4, 0xB84C, 0x7AB5, 0xB84D, 0x7AB6, 0xB84E, 0x7AB7, + 0xB84F, 0x7AB8, 0xB850, 0x7AB9, 0xB851, 0x7ABA, 0xB852, 0x7ABB, + 0xB853, 0x7ABC, 0xB854, 0x7ABD, 0xB855, 0x7ABE, 0xB856, 0x7AC0, + 0xB857, 0x7AC1, 0xB858, 0x7AC2, 0xB859, 0x7AC3, 0xB85A, 0x7AC4, + 0xB85B, 0x7AC5, 0xB85C, 0x7AC6, 0xB85D, 0x7AC7, 0xB85E, 0x7AC8, + 0xB85F, 0x7AC9, 0xB860, 0x7ACA, 0xB861, 0x7ACC, 0xB862, 0x7ACD, + 0xB863, 0x7ACE, 0xB864, 0x7ACF, 0xB865, 0x7AD0, 0xB866, 0x7AD1, + 0xB867, 0x7AD2, 0xB868, 0x7AD3, 0xB869, 0x7AD4, 0xB86A, 0x7AD5, + 0xB86B, 0x7AD7, 0xB86C, 0x7AD8, 0xB86D, 0x7ADA, 0xB86E, 0x7ADB, + 0xB86F, 0x7ADC, 0xB870, 0x7ADD, 0xB871, 0x7AE1, 0xB872, 0x7AE2, + 0xB873, 0x7AE4, 0xB874, 0x7AE7, 0xB875, 0x7AE8, 0xB876, 0x7AE9, + 0xB877, 0x7AEA, 0xB878, 0x7AEB, 0xB879, 0x7AEC, 0xB87A, 0x7AEE, + 0xB87B, 0x7AF0, 0xB87C, 0x7AF1, 0xB87D, 0x7AF2, 0xB87E, 0x7AF3, + 0xB880, 0x7AF4, 0xB881, 0x7AF5, 0xB882, 0x7AF6, 0xB883, 0x7AF7, + 0xB884, 0x7AF8, 0xB885, 0x7AFB, 0xB886, 0x7AFC, 0xB887, 0x7AFE, + 0xB888, 0x7B00, 0xB889, 0x7B01, 0xB88A, 0x7B02, 0xB88B, 0x7B05, + 0xB88C, 0x7B07, 0xB88D, 0x7B09, 0xB88E, 0x7B0C, 0xB88F, 0x7B0D, + 0xB890, 0x7B0E, 0xB891, 0x7B10, 0xB892, 0x7B12, 0xB893, 0x7B13, + 0xB894, 0x7B16, 0xB895, 0x7B17, 0xB896, 0x7B18, 0xB897, 0x7B1A, + 0xB898, 0x7B1C, 0xB899, 0x7B1D, 0xB89A, 0x7B1F, 0xB89B, 0x7B21, + 0xB89C, 0x7B22, 0xB89D, 0x7B23, 0xB89E, 0x7B27, 0xB89F, 0x7B29, + 0xB8A0, 0x7B2D, 0xB8A1, 0x6D6E, 0xB8A2, 0x6DAA, 0xB8A3, 0x798F, + 0xB8A4, 0x88B1, 0xB8A5, 0x5F17, 0xB8A6, 0x752B, 0xB8A7, 0x629A, + 0xB8A8, 0x8F85, 0xB8A9, 0x4FEF, 0xB8AA, 0x91DC, 0xB8AB, 0x65A7, + 0xB8AC, 0x812F, 0xB8AD, 0x8151, 0xB8AE, 0x5E9C, 0xB8AF, 0x8150, + 0xB8B0, 0x8D74, 0xB8B1, 0x526F, 0xB8B2, 0x8986, 0xB8B3, 0x8D4B, + 0xB8B4, 0x590D, 0xB8B5, 0x5085, 0xB8B6, 0x4ED8, 0xB8B7, 0x961C, + 0xB8B8, 0x7236, 0xB8B9, 0x8179, 0xB8BA, 0x8D1F, 0xB8BB, 0x5BCC, + 0xB8BC, 0x8BA3, 0xB8BD, 0x9644, 0xB8BE, 0x5987, 0xB8BF, 0x7F1A, + 0xB8C0, 0x5490, 0xB8C1, 0x5676, 0xB8C2, 0x560E, 0xB8C3, 0x8BE5, + 0xB8C4, 0x6539, 0xB8C5, 0x6982, 0xB8C6, 0x9499, 0xB8C7, 0x76D6, + 0xB8C8, 0x6E89, 0xB8C9, 0x5E72, 0xB8CA, 0x7518, 0xB8CB, 0x6746, + 0xB8CC, 0x67D1, 0xB8CD, 0x7AFF, 0xB8CE, 0x809D, 0xB8CF, 0x8D76, + 0xB8D0, 0x611F, 0xB8D1, 0x79C6, 0xB8D2, 0x6562, 0xB8D3, 0x8D63, + 0xB8D4, 0x5188, 0xB8D5, 0x521A, 0xB8D6, 0x94A2, 0xB8D7, 0x7F38, + 0xB8D8, 0x809B, 0xB8D9, 0x7EB2, 0xB8DA, 0x5C97, 0xB8DB, 0x6E2F, + 0xB8DC, 0x6760, 0xB8DD, 0x7BD9, 0xB8DE, 0x768B, 0xB8DF, 0x9AD8, + 0xB8E0, 0x818F, 0xB8E1, 0x7F94, 0xB8E2, 0x7CD5, 0xB8E3, 0x641E, + 0xB8E4, 0x9550, 0xB8E5, 0x7A3F, 0xB8E6, 0x544A, 0xB8E7, 0x54E5, + 0xB8E8, 0x6B4C, 0xB8E9, 0x6401, 0xB8EA, 0x6208, 0xB8EB, 0x9E3D, + 0xB8EC, 0x80F3, 0xB8ED, 0x7599, 0xB8EE, 0x5272, 0xB8EF, 0x9769, + 0xB8F0, 0x845B, 0xB8F1, 0x683C, 0xB8F2, 0x86E4, 0xB8F3, 0x9601, + 0xB8F4, 0x9694, 0xB8F5, 0x94EC, 0xB8F6, 0x4E2A, 0xB8F7, 0x5404, + 0xB8F8, 0x7ED9, 0xB8F9, 0x6839, 0xB8FA, 0x8DDF, 0xB8FB, 0x8015, + 0xB8FC, 0x66F4, 0xB8FD, 0x5E9A, 0xB8FE, 0x7FB9, 0xB940, 0x7B2F, + 0xB941, 0x7B30, 0xB942, 0x7B32, 0xB943, 0x7B34, 0xB944, 0x7B35, + 0xB945, 0x7B36, 0xB946, 0x7B37, 0xB947, 0x7B39, 0xB948, 0x7B3B, + 0xB949, 0x7B3D, 0xB94A, 0x7B3F, 0xB94B, 0x7B40, 0xB94C, 0x7B41, + 0xB94D, 0x7B42, 0xB94E, 0x7B43, 0xB94F, 0x7B44, 0xB950, 0x7B46, + 0xB951, 0x7B48, 0xB952, 0x7B4A, 0xB953, 0x7B4D, 0xB954, 0x7B4E, + 0xB955, 0x7B53, 0xB956, 0x7B55, 0xB957, 0x7B57, 0xB958, 0x7B59, + 0xB959, 0x7B5C, 0xB95A, 0x7B5E, 0xB95B, 0x7B5F, 0xB95C, 0x7B61, + 0xB95D, 0x7B63, 0xB95E, 0x7B64, 0xB95F, 0x7B65, 0xB960, 0x7B66, + 0xB961, 0x7B67, 0xB962, 0x7B68, 0xB963, 0x7B69, 0xB964, 0x7B6A, + 0xB965, 0x7B6B, 0xB966, 0x7B6C, 0xB967, 0x7B6D, 0xB968, 0x7B6F, + 0xB969, 0x7B70, 0xB96A, 0x7B73, 0xB96B, 0x7B74, 0xB96C, 0x7B76, + 0xB96D, 0x7B78, 0xB96E, 0x7B7A, 0xB96F, 0x7B7C, 0xB970, 0x7B7D, + 0xB971, 0x7B7F, 0xB972, 0x7B81, 0xB973, 0x7B82, 0xB974, 0x7B83, + 0xB975, 0x7B84, 0xB976, 0x7B86, 0xB977, 0x7B87, 0xB978, 0x7B88, + 0xB979, 0x7B89, 0xB97A, 0x7B8A, 0xB97B, 0x7B8B, 0xB97C, 0x7B8C, + 0xB97D, 0x7B8E, 0xB97E, 0x7B8F, 0xB980, 0x7B91, 0xB981, 0x7B92, + 0xB982, 0x7B93, 0xB983, 0x7B96, 0xB984, 0x7B98, 0xB985, 0x7B99, + 0xB986, 0x7B9A, 0xB987, 0x7B9B, 0xB988, 0x7B9E, 0xB989, 0x7B9F, + 0xB98A, 0x7BA0, 0xB98B, 0x7BA3, 0xB98C, 0x7BA4, 0xB98D, 0x7BA5, + 0xB98E, 0x7BAE, 0xB98F, 0x7BAF, 0xB990, 0x7BB0, 0xB991, 0x7BB2, + 0xB992, 0x7BB3, 0xB993, 0x7BB5, 0xB994, 0x7BB6, 0xB995, 0x7BB7, + 0xB996, 0x7BB9, 0xB997, 0x7BBA, 0xB998, 0x7BBB, 0xB999, 0x7BBC, + 0xB99A, 0x7BBD, 0xB99B, 0x7BBE, 0xB99C, 0x7BBF, 0xB99D, 0x7BC0, + 0xB99E, 0x7BC2, 0xB99F, 0x7BC3, 0xB9A0, 0x7BC4, 0xB9A1, 0x57C2, + 0xB9A2, 0x803F, 0xB9A3, 0x6897, 0xB9A4, 0x5DE5, 0xB9A5, 0x653B, + 0xB9A6, 0x529F, 0xB9A7, 0x606D, 0xB9A8, 0x9F9A, 0xB9A9, 0x4F9B, + 0xB9AA, 0x8EAC, 0xB9AB, 0x516C, 0xB9AC, 0x5BAB, 0xB9AD, 0x5F13, + 0xB9AE, 0x5DE9, 0xB9AF, 0x6C5E, 0xB9B0, 0x62F1, 0xB9B1, 0x8D21, + 0xB9B2, 0x5171, 0xB9B3, 0x94A9, 0xB9B4, 0x52FE, 0xB9B5, 0x6C9F, + 0xB9B6, 0x82DF, 0xB9B7, 0x72D7, 0xB9B8, 0x57A2, 0xB9B9, 0x6784, + 0xB9BA, 0x8D2D, 0xB9BB, 0x591F, 0xB9BC, 0x8F9C, 0xB9BD, 0x83C7, + 0xB9BE, 0x5495, 0xB9BF, 0x7B8D, 0xB9C0, 0x4F30, 0xB9C1, 0x6CBD, + 0xB9C2, 0x5B64, 0xB9C3, 0x59D1, 0xB9C4, 0x9F13, 0xB9C5, 0x53E4, + 0xB9C6, 0x86CA, 0xB9C7, 0x9AA8, 0xB9C8, 0x8C37, 0xB9C9, 0x80A1, + 0xB9CA, 0x6545, 0xB9CB, 0x987E, 0xB9CC, 0x56FA, 0xB9CD, 0x96C7, + 0xB9CE, 0x522E, 0xB9CF, 0x74DC, 0xB9D0, 0x5250, 0xB9D1, 0x5BE1, + 0xB9D2, 0x6302, 0xB9D3, 0x8902, 0xB9D4, 0x4E56, 0xB9D5, 0x62D0, + 0xB9D6, 0x602A, 0xB9D7, 0x68FA, 0xB9D8, 0x5173, 0xB9D9, 0x5B98, + 0xB9DA, 0x51A0, 0xB9DB, 0x89C2, 0xB9DC, 0x7BA1, 0xB9DD, 0x9986, + 0xB9DE, 0x7F50, 0xB9DF, 0x60EF, 0xB9E0, 0x704C, 0xB9E1, 0x8D2F, + 0xB9E2, 0x5149, 0xB9E3, 0x5E7F, 0xB9E4, 0x901B, 0xB9E5, 0x7470, + 0xB9E6, 0x89C4, 0xB9E7, 0x572D, 0xB9E8, 0x7845, 0xB9E9, 0x5F52, + 0xB9EA, 0x9F9F, 0xB9EB, 0x95FA, 0xB9EC, 0x8F68, 0xB9ED, 0x9B3C, + 0xB9EE, 0x8BE1, 0xB9EF, 0x7678, 0xB9F0, 0x6842, 0xB9F1, 0x67DC, + 0xB9F2, 0x8DEA, 0xB9F3, 0x8D35, 0xB9F4, 0x523D, 0xB9F5, 0x8F8A, + 0xB9F6, 0x6EDA, 0xB9F7, 0x68CD, 0xB9F8, 0x9505, 0xB9F9, 0x90ED, + 0xB9FA, 0x56FD, 0xB9FB, 0x679C, 0xB9FC, 0x88F9, 0xB9FD, 0x8FC7, + 0xB9FE, 0x54C8, 0xBA40, 0x7BC5, 0xBA41, 0x7BC8, 0xBA42, 0x7BC9, + 0xBA43, 0x7BCA, 0xBA44, 0x7BCB, 0xBA45, 0x7BCD, 0xBA46, 0x7BCE, + 0xBA47, 0x7BCF, 0xBA48, 0x7BD0, 0xBA49, 0x7BD2, 0xBA4A, 0x7BD4, + 0xBA4B, 0x7BD5, 0xBA4C, 0x7BD6, 0xBA4D, 0x7BD7, 0xBA4E, 0x7BD8, + 0xBA4F, 0x7BDB, 0xBA50, 0x7BDC, 0xBA51, 0x7BDE, 0xBA52, 0x7BDF, + 0xBA53, 0x7BE0, 0xBA54, 0x7BE2, 0xBA55, 0x7BE3, 0xBA56, 0x7BE4, + 0xBA57, 0x7BE7, 0xBA58, 0x7BE8, 0xBA59, 0x7BE9, 0xBA5A, 0x7BEB, + 0xBA5B, 0x7BEC, 0xBA5C, 0x7BED, 0xBA5D, 0x7BEF, 0xBA5E, 0x7BF0, + 0xBA5F, 0x7BF2, 0xBA60, 0x7BF3, 0xBA61, 0x7BF4, 0xBA62, 0x7BF5, + 0xBA63, 0x7BF6, 0xBA64, 0x7BF8, 0xBA65, 0x7BF9, 0xBA66, 0x7BFA, + 0xBA67, 0x7BFB, 0xBA68, 0x7BFD, 0xBA69, 0x7BFF, 0xBA6A, 0x7C00, + 0xBA6B, 0x7C01, 0xBA6C, 0x7C02, 0xBA6D, 0x7C03, 0xBA6E, 0x7C04, + 0xBA6F, 0x7C05, 0xBA70, 0x7C06, 0xBA71, 0x7C08, 0xBA72, 0x7C09, + 0xBA73, 0x7C0A, 0xBA74, 0x7C0D, 0xBA75, 0x7C0E, 0xBA76, 0x7C10, + 0xBA77, 0x7C11, 0xBA78, 0x7C12, 0xBA79, 0x7C13, 0xBA7A, 0x7C14, + 0xBA7B, 0x7C15, 0xBA7C, 0x7C17, 0xBA7D, 0x7C18, 0xBA7E, 0x7C19, + 0xBA80, 0x7C1A, 0xBA81, 0x7C1B, 0xBA82, 0x7C1C, 0xBA83, 0x7C1D, + 0xBA84, 0x7C1E, 0xBA85, 0x7C20, 0xBA86, 0x7C21, 0xBA87, 0x7C22, + 0xBA88, 0x7C23, 0xBA89, 0x7C24, 0xBA8A, 0x7C25, 0xBA8B, 0x7C28, + 0xBA8C, 0x7C29, 0xBA8D, 0x7C2B, 0xBA8E, 0x7C2C, 0xBA8F, 0x7C2D, + 0xBA90, 0x7C2E, 0xBA91, 0x7C2F, 0xBA92, 0x7C30, 0xBA93, 0x7C31, + 0xBA94, 0x7C32, 0xBA95, 0x7C33, 0xBA96, 0x7C34, 0xBA97, 0x7C35, + 0xBA98, 0x7C36, 0xBA99, 0x7C37, 0xBA9A, 0x7C39, 0xBA9B, 0x7C3A, + 0xBA9C, 0x7C3B, 0xBA9D, 0x7C3C, 0xBA9E, 0x7C3D, 0xBA9F, 0x7C3E, + 0xBAA0, 0x7C42, 0xBAA1, 0x9AB8, 0xBAA2, 0x5B69, 0xBAA3, 0x6D77, + 0xBAA4, 0x6C26, 0xBAA5, 0x4EA5, 0xBAA6, 0x5BB3, 0xBAA7, 0x9A87, + 0xBAA8, 0x9163, 0xBAA9, 0x61A8, 0xBAAA, 0x90AF, 0xBAAB, 0x97E9, + 0xBAAC, 0x542B, 0xBAAD, 0x6DB5, 0xBAAE, 0x5BD2, 0xBAAF, 0x51FD, + 0xBAB0, 0x558A, 0xBAB1, 0x7F55, 0xBAB2, 0x7FF0, 0xBAB3, 0x64BC, + 0xBAB4, 0x634D, 0xBAB5, 0x65F1, 0xBAB6, 0x61BE, 0xBAB7, 0x608D, + 0xBAB8, 0x710A, 0xBAB9, 0x6C57, 0xBABA, 0x6C49, 0xBABB, 0x592F, + 0xBABC, 0x676D, 0xBABD, 0x822A, 0xBABE, 0x58D5, 0xBABF, 0x568E, + 0xBAC0, 0x8C6A, 0xBAC1, 0x6BEB, 0xBAC2, 0x90DD, 0xBAC3, 0x597D, + 0xBAC4, 0x8017, 0xBAC5, 0x53F7, 0xBAC6, 0x6D69, 0xBAC7, 0x5475, + 0xBAC8, 0x559D, 0xBAC9, 0x8377, 0xBACA, 0x83CF, 0xBACB, 0x6838, + 0xBACC, 0x79BE, 0xBACD, 0x548C, 0xBACE, 0x4F55, 0xBACF, 0x5408, + 0xBAD0, 0x76D2, 0xBAD1, 0x8C89, 0xBAD2, 0x9602, 0xBAD3, 0x6CB3, + 0xBAD4, 0x6DB8, 0xBAD5, 0x8D6B, 0xBAD6, 0x8910, 0xBAD7, 0x9E64, + 0xBAD8, 0x8D3A, 0xBAD9, 0x563F, 0xBADA, 0x9ED1, 0xBADB, 0x75D5, + 0xBADC, 0x5F88, 0xBADD, 0x72E0, 0xBADE, 0x6068, 0xBADF, 0x54FC, + 0xBAE0, 0x4EA8, 0xBAE1, 0x6A2A, 0xBAE2, 0x8861, 0xBAE3, 0x6052, + 0xBAE4, 0x8F70, 0xBAE5, 0x54C4, 0xBAE6, 0x70D8, 0xBAE7, 0x8679, + 0xBAE8, 0x9E3F, 0xBAE9, 0x6D2A, 0xBAEA, 0x5B8F, 0xBAEB, 0x5F18, + 0xBAEC, 0x7EA2, 0xBAED, 0x5589, 0xBAEE, 0x4FAF, 0xBAEF, 0x7334, + 0xBAF0, 0x543C, 0xBAF1, 0x539A, 0xBAF2, 0x5019, 0xBAF3, 0x540E, + 0xBAF4, 0x547C, 0xBAF5, 0x4E4E, 0xBAF6, 0x5FFD, 0xBAF7, 0x745A, + 0xBAF8, 0x58F6, 0xBAF9, 0x846B, 0xBAFA, 0x80E1, 0xBAFB, 0x8774, + 0xBAFC, 0x72D0, 0xBAFD, 0x7CCA, 0xBAFE, 0x6E56, 0xBB40, 0x7C43, + 0xBB41, 0x7C44, 0xBB42, 0x7C45, 0xBB43, 0x7C46, 0xBB44, 0x7C47, + 0xBB45, 0x7C48, 0xBB46, 0x7C49, 0xBB47, 0x7C4A, 0xBB48, 0x7C4B, + 0xBB49, 0x7C4C, 0xBB4A, 0x7C4E, 0xBB4B, 0x7C4F, 0xBB4C, 0x7C50, + 0xBB4D, 0x7C51, 0xBB4E, 0x7C52, 0xBB4F, 0x7C53, 0xBB50, 0x7C54, + 0xBB51, 0x7C55, 0xBB52, 0x7C56, 0xBB53, 0x7C57, 0xBB54, 0x7C58, + 0xBB55, 0x7C59, 0xBB56, 0x7C5A, 0xBB57, 0x7C5B, 0xBB58, 0x7C5C, + 0xBB59, 0x7C5D, 0xBB5A, 0x7C5E, 0xBB5B, 0x7C5F, 0xBB5C, 0x7C60, + 0xBB5D, 0x7C61, 0xBB5E, 0x7C62, 0xBB5F, 0x7C63, 0xBB60, 0x7C64, + 0xBB61, 0x7C65, 0xBB62, 0x7C66, 0xBB63, 0x7C67, 0xBB64, 0x7C68, + 0xBB65, 0x7C69, 0xBB66, 0x7C6A, 0xBB67, 0x7C6B, 0xBB68, 0x7C6C, + 0xBB69, 0x7C6D, 0xBB6A, 0x7C6E, 0xBB6B, 0x7C6F, 0xBB6C, 0x7C70, + 0xBB6D, 0x7C71, 0xBB6E, 0x7C72, 0xBB6F, 0x7C75, 0xBB70, 0x7C76, + 0xBB71, 0x7C77, 0xBB72, 0x7C78, 0xBB73, 0x7C79, 0xBB74, 0x7C7A, + 0xBB75, 0x7C7E, 0xBB76, 0x7C7F, 0xBB77, 0x7C80, 0xBB78, 0x7C81, + 0xBB79, 0x7C82, 0xBB7A, 0x7C83, 0xBB7B, 0x7C84, 0xBB7C, 0x7C85, + 0xBB7D, 0x7C86, 0xBB7E, 0x7C87, 0xBB80, 0x7C88, 0xBB81, 0x7C8A, + 0xBB82, 0x7C8B, 0xBB83, 0x7C8C, 0xBB84, 0x7C8D, 0xBB85, 0x7C8E, + 0xBB86, 0x7C8F, 0xBB87, 0x7C90, 0xBB88, 0x7C93, 0xBB89, 0x7C94, + 0xBB8A, 0x7C96, 0xBB8B, 0x7C99, 0xBB8C, 0x7C9A, 0xBB8D, 0x7C9B, + 0xBB8E, 0x7CA0, 0xBB8F, 0x7CA1, 0xBB90, 0x7CA3, 0xBB91, 0x7CA6, + 0xBB92, 0x7CA7, 0xBB93, 0x7CA8, 0xBB94, 0x7CA9, 0xBB95, 0x7CAB, + 0xBB96, 0x7CAC, 0xBB97, 0x7CAD, 0xBB98, 0x7CAF, 0xBB99, 0x7CB0, + 0xBB9A, 0x7CB4, 0xBB9B, 0x7CB5, 0xBB9C, 0x7CB6, 0xBB9D, 0x7CB7, + 0xBB9E, 0x7CB8, 0xBB9F, 0x7CBA, 0xBBA0, 0x7CBB, 0xBBA1, 0x5F27, + 0xBBA2, 0x864E, 0xBBA3, 0x552C, 0xBBA4, 0x62A4, 0xBBA5, 0x4E92, + 0xBBA6, 0x6CAA, 0xBBA7, 0x6237, 0xBBA8, 0x82B1, 0xBBA9, 0x54D7, + 0xBBAA, 0x534E, 0xBBAB, 0x733E, 0xBBAC, 0x6ED1, 0xBBAD, 0x753B, + 0xBBAE, 0x5212, 0xBBAF, 0x5316, 0xBBB0, 0x8BDD, 0xBBB1, 0x69D0, + 0xBBB2, 0x5F8A, 0xBBB3, 0x6000, 0xBBB4, 0x6DEE, 0xBBB5, 0x574F, + 0xBBB6, 0x6B22, 0xBBB7, 0x73AF, 0xBBB8, 0x6853, 0xBBB9, 0x8FD8, + 0xBBBA, 0x7F13, 0xBBBB, 0x6362, 0xBBBC, 0x60A3, 0xBBBD, 0x5524, + 0xBBBE, 0x75EA, 0xBBBF, 0x8C62, 0xBBC0, 0x7115, 0xBBC1, 0x6DA3, + 0xBBC2, 0x5BA6, 0xBBC3, 0x5E7B, 0xBBC4, 0x8352, 0xBBC5, 0x614C, + 0xBBC6, 0x9EC4, 0xBBC7, 0x78FA, 0xBBC8, 0x8757, 0xBBC9, 0x7C27, + 0xBBCA, 0x7687, 0xBBCB, 0x51F0, 0xBBCC, 0x60F6, 0xBBCD, 0x714C, + 0xBBCE, 0x6643, 0xBBCF, 0x5E4C, 0xBBD0, 0x604D, 0xBBD1, 0x8C0E, + 0xBBD2, 0x7070, 0xBBD3, 0x6325, 0xBBD4, 0x8F89, 0xBBD5, 0x5FBD, + 0xBBD6, 0x6062, 0xBBD7, 0x86D4, 0xBBD8, 0x56DE, 0xBBD9, 0x6BC1, + 0xBBDA, 0x6094, 0xBBDB, 0x6167, 0xBBDC, 0x5349, 0xBBDD, 0x60E0, + 0xBBDE, 0x6666, 0xBBDF, 0x8D3F, 0xBBE0, 0x79FD, 0xBBE1, 0x4F1A, + 0xBBE2, 0x70E9, 0xBBE3, 0x6C47, 0xBBE4, 0x8BB3, 0xBBE5, 0x8BF2, + 0xBBE6, 0x7ED8, 0xBBE7, 0x8364, 0xBBE8, 0x660F, 0xBBE9, 0x5A5A, + 0xBBEA, 0x9B42, 0xBBEB, 0x6D51, 0xBBEC, 0x6DF7, 0xBBED, 0x8C41, + 0xBBEE, 0x6D3B, 0xBBEF, 0x4F19, 0xBBF0, 0x706B, 0xBBF1, 0x83B7, + 0xBBF2, 0x6216, 0xBBF3, 0x60D1, 0xBBF4, 0x970D, 0xBBF5, 0x8D27, + 0xBBF6, 0x7978, 0xBBF7, 0x51FB, 0xBBF8, 0x573E, 0xBBF9, 0x57FA, + 0xBBFA, 0x673A, 0xBBFB, 0x7578, 0xBBFC, 0x7A3D, 0xBBFD, 0x79EF, + 0xBBFE, 0x7B95, 0xBC40, 0x7CBF, 0xBC41, 0x7CC0, 0xBC42, 0x7CC2, + 0xBC43, 0x7CC3, 0xBC44, 0x7CC4, 0xBC45, 0x7CC6, 0xBC46, 0x7CC9, + 0xBC47, 0x7CCB, 0xBC48, 0x7CCE, 0xBC49, 0x7CCF, 0xBC4A, 0x7CD0, + 0xBC4B, 0x7CD1, 0xBC4C, 0x7CD2, 0xBC4D, 0x7CD3, 0xBC4E, 0x7CD4, + 0xBC4F, 0x7CD8, 0xBC50, 0x7CDA, 0xBC51, 0x7CDB, 0xBC52, 0x7CDD, + 0xBC53, 0x7CDE, 0xBC54, 0x7CE1, 0xBC55, 0x7CE2, 0xBC56, 0x7CE3, + 0xBC57, 0x7CE4, 0xBC58, 0x7CE5, 0xBC59, 0x7CE6, 0xBC5A, 0x7CE7, + 0xBC5B, 0x7CE9, 0xBC5C, 0x7CEA, 0xBC5D, 0x7CEB, 0xBC5E, 0x7CEC, + 0xBC5F, 0x7CED, 0xBC60, 0x7CEE, 0xBC61, 0x7CF0, 0xBC62, 0x7CF1, + 0xBC63, 0x7CF2, 0xBC64, 0x7CF3, 0xBC65, 0x7CF4, 0xBC66, 0x7CF5, + 0xBC67, 0x7CF6, 0xBC68, 0x7CF7, 0xBC69, 0x7CF9, 0xBC6A, 0x7CFA, + 0xBC6B, 0x7CFC, 0xBC6C, 0x7CFD, 0xBC6D, 0x7CFE, 0xBC6E, 0x7CFF, + 0xBC6F, 0x7D00, 0xBC70, 0x7D01, 0xBC71, 0x7D02, 0xBC72, 0x7D03, + 0xBC73, 0x7D04, 0xBC74, 0x7D05, 0xBC75, 0x7D06, 0xBC76, 0x7D07, + 0xBC77, 0x7D08, 0xBC78, 0x7D09, 0xBC79, 0x7D0B, 0xBC7A, 0x7D0C, + 0xBC7B, 0x7D0D, 0xBC7C, 0x7D0E, 0xBC7D, 0x7D0F, 0xBC7E, 0x7D10, + 0xBC80, 0x7D11, 0xBC81, 0x7D12, 0xBC82, 0x7D13, 0xBC83, 0x7D14, + 0xBC84, 0x7D15, 0xBC85, 0x7D16, 0xBC86, 0x7D17, 0xBC87, 0x7D18, + 0xBC88, 0x7D19, 0xBC89, 0x7D1A, 0xBC8A, 0x7D1B, 0xBC8B, 0x7D1C, + 0xBC8C, 0x7D1D, 0xBC8D, 0x7D1E, 0xBC8E, 0x7D1F, 0xBC8F, 0x7D21, + 0xBC90, 0x7D23, 0xBC91, 0x7D24, 0xBC92, 0x7D25, 0xBC93, 0x7D26, + 0xBC94, 0x7D28, 0xBC95, 0x7D29, 0xBC96, 0x7D2A, 0xBC97, 0x7D2C, + 0xBC98, 0x7D2D, 0xBC99, 0x7D2E, 0xBC9A, 0x7D30, 0xBC9B, 0x7D31, + 0xBC9C, 0x7D32, 0xBC9D, 0x7D33, 0xBC9E, 0x7D34, 0xBC9F, 0x7D35, + 0xBCA0, 0x7D36, 0xBCA1, 0x808C, 0xBCA2, 0x9965, 0xBCA3, 0x8FF9, + 0xBCA4, 0x6FC0, 0xBCA5, 0x8BA5, 0xBCA6, 0x9E21, 0xBCA7, 0x59EC, + 0xBCA8, 0x7EE9, 0xBCA9, 0x7F09, 0xBCAA, 0x5409, 0xBCAB, 0x6781, + 0xBCAC, 0x68D8, 0xBCAD, 0x8F91, 0xBCAE, 0x7C4D, 0xBCAF, 0x96C6, + 0xBCB0, 0x53CA, 0xBCB1, 0x6025, 0xBCB2, 0x75BE, 0xBCB3, 0x6C72, + 0xBCB4, 0x5373, 0xBCB5, 0x5AC9, 0xBCB6, 0x7EA7, 0xBCB7, 0x6324, + 0xBCB8, 0x51E0, 0xBCB9, 0x810A, 0xBCBA, 0x5DF1, 0xBCBB, 0x84DF, + 0xBCBC, 0x6280, 0xBCBD, 0x5180, 0xBCBE, 0x5B63, 0xBCBF, 0x4F0E, + 0xBCC0, 0x796D, 0xBCC1, 0x5242, 0xBCC2, 0x60B8, 0xBCC3, 0x6D4E, + 0xBCC4, 0x5BC4, 0xBCC5, 0x5BC2, 0xBCC6, 0x8BA1, 0xBCC7, 0x8BB0, + 0xBCC8, 0x65E2, 0xBCC9, 0x5FCC, 0xBCCA, 0x9645, 0xBCCB, 0x5993, + 0xBCCC, 0x7EE7, 0xBCCD, 0x7EAA, 0xBCCE, 0x5609, 0xBCCF, 0x67B7, + 0xBCD0, 0x5939, 0xBCD1, 0x4F73, 0xBCD2, 0x5BB6, 0xBCD3, 0x52A0, + 0xBCD4, 0x835A, 0xBCD5, 0x988A, 0xBCD6, 0x8D3E, 0xBCD7, 0x7532, + 0xBCD8, 0x94BE, 0xBCD9, 0x5047, 0xBCDA, 0x7A3C, 0xBCDB, 0x4EF7, + 0xBCDC, 0x67B6, 0xBCDD, 0x9A7E, 0xBCDE, 0x5AC1, 0xBCDF, 0x6B7C, + 0xBCE0, 0x76D1, 0xBCE1, 0x575A, 0xBCE2, 0x5C16, 0xBCE3, 0x7B3A, + 0xBCE4, 0x95F4, 0xBCE5, 0x714E, 0xBCE6, 0x517C, 0xBCE7, 0x80A9, + 0xBCE8, 0x8270, 0xBCE9, 0x5978, 0xBCEA, 0x7F04, 0xBCEB, 0x8327, + 0xBCEC, 0x68C0, 0xBCED, 0x67EC, 0xBCEE, 0x78B1, 0xBCEF, 0x7877, + 0xBCF0, 0x62E3, 0xBCF1, 0x6361, 0xBCF2, 0x7B80, 0xBCF3, 0x4FED, + 0xBCF4, 0x526A, 0xBCF5, 0x51CF, 0xBCF6, 0x8350, 0xBCF7, 0x69DB, + 0xBCF8, 0x9274, 0xBCF9, 0x8DF5, 0xBCFA, 0x8D31, 0xBCFB, 0x89C1, + 0xBCFC, 0x952E, 0xBCFD, 0x7BAD, 0xBCFE, 0x4EF6, 0xBD40, 0x7D37, + 0xBD41, 0x7D38, 0xBD42, 0x7D39, 0xBD43, 0x7D3A, 0xBD44, 0x7D3B, + 0xBD45, 0x7D3C, 0xBD46, 0x7D3D, 0xBD47, 0x7D3E, 0xBD48, 0x7D3F, + 0xBD49, 0x7D40, 0xBD4A, 0x7D41, 0xBD4B, 0x7D42, 0xBD4C, 0x7D43, + 0xBD4D, 0x7D44, 0xBD4E, 0x7D45, 0xBD4F, 0x7D46, 0xBD50, 0x7D47, + 0xBD51, 0x7D48, 0xBD52, 0x7D49, 0xBD53, 0x7D4A, 0xBD54, 0x7D4B, + 0xBD55, 0x7D4C, 0xBD56, 0x7D4D, 0xBD57, 0x7D4E, 0xBD58, 0x7D4F, + 0xBD59, 0x7D50, 0xBD5A, 0x7D51, 0xBD5B, 0x7D52, 0xBD5C, 0x7D53, + 0xBD5D, 0x7D54, 0xBD5E, 0x7D55, 0xBD5F, 0x7D56, 0xBD60, 0x7D57, + 0xBD61, 0x7D58, 0xBD62, 0x7D59, 0xBD63, 0x7D5A, 0xBD64, 0x7D5B, + 0xBD65, 0x7D5C, 0xBD66, 0x7D5D, 0xBD67, 0x7D5E, 0xBD68, 0x7D5F, + 0xBD69, 0x7D60, 0xBD6A, 0x7D61, 0xBD6B, 0x7D62, 0xBD6C, 0x7D63, + 0xBD6D, 0x7D64, 0xBD6E, 0x7D65, 0xBD6F, 0x7D66, 0xBD70, 0x7D67, + 0xBD71, 0x7D68, 0xBD72, 0x7D69, 0xBD73, 0x7D6A, 0xBD74, 0x7D6B, + 0xBD75, 0x7D6C, 0xBD76, 0x7D6D, 0xBD77, 0x7D6F, 0xBD78, 0x7D70, + 0xBD79, 0x7D71, 0xBD7A, 0x7D72, 0xBD7B, 0x7D73, 0xBD7C, 0x7D74, + 0xBD7D, 0x7D75, 0xBD7E, 0x7D76, 0xBD80, 0x7D78, 0xBD81, 0x7D79, + 0xBD82, 0x7D7A, 0xBD83, 0x7D7B, 0xBD84, 0x7D7C, 0xBD85, 0x7D7D, + 0xBD86, 0x7D7E, 0xBD87, 0x7D7F, 0xBD88, 0x7D80, 0xBD89, 0x7D81, + 0xBD8A, 0x7D82, 0xBD8B, 0x7D83, 0xBD8C, 0x7D84, 0xBD8D, 0x7D85, + 0xBD8E, 0x7D86, 0xBD8F, 0x7D87, 0xBD90, 0x7D88, 0xBD91, 0x7D89, + 0xBD92, 0x7D8A, 0xBD93, 0x7D8B, 0xBD94, 0x7D8C, 0xBD95, 0x7D8D, + 0xBD96, 0x7D8E, 0xBD97, 0x7D8F, 0xBD98, 0x7D90, 0xBD99, 0x7D91, + 0xBD9A, 0x7D92, 0xBD9B, 0x7D93, 0xBD9C, 0x7D94, 0xBD9D, 0x7D95, + 0xBD9E, 0x7D96, 0xBD9F, 0x7D97, 0xBDA0, 0x7D98, 0xBDA1, 0x5065, + 0xBDA2, 0x8230, 0xBDA3, 0x5251, 0xBDA4, 0x996F, 0xBDA5, 0x6E10, + 0xBDA6, 0x6E85, 0xBDA7, 0x6DA7, 0xBDA8, 0x5EFA, 0xBDA9, 0x50F5, + 0xBDAA, 0x59DC, 0xBDAB, 0x5C06, 0xBDAC, 0x6D46, 0xBDAD, 0x6C5F, + 0xBDAE, 0x7586, 0xBDAF, 0x848B, 0xBDB0, 0x6868, 0xBDB1, 0x5956, + 0xBDB2, 0x8BB2, 0xBDB3, 0x5320, 0xBDB4, 0x9171, 0xBDB5, 0x964D, + 0xBDB6, 0x8549, 0xBDB7, 0x6912, 0xBDB8, 0x7901, 0xBDB9, 0x7126, + 0xBDBA, 0x80F6, 0xBDBB, 0x4EA4, 0xBDBC, 0x90CA, 0xBDBD, 0x6D47, + 0xBDBE, 0x9A84, 0xBDBF, 0x5A07, 0xBDC0, 0x56BC, 0xBDC1, 0x6405, + 0xBDC2, 0x94F0, 0xBDC3, 0x77EB, 0xBDC4, 0x4FA5, 0xBDC5, 0x811A, + 0xBDC6, 0x72E1, 0xBDC7, 0x89D2, 0xBDC8, 0x997A, 0xBDC9, 0x7F34, + 0xBDCA, 0x7EDE, 0xBDCB, 0x527F, 0xBDCC, 0x6559, 0xBDCD, 0x9175, + 0xBDCE, 0x8F7F, 0xBDCF, 0x8F83, 0xBDD0, 0x53EB, 0xBDD1, 0x7A96, + 0xBDD2, 0x63ED, 0xBDD3, 0x63A5, 0xBDD4, 0x7686, 0xBDD5, 0x79F8, + 0xBDD6, 0x8857, 0xBDD7, 0x9636, 0xBDD8, 0x622A, 0xBDD9, 0x52AB, + 0xBDDA, 0x8282, 0xBDDB, 0x6854, 0xBDDC, 0x6770, 0xBDDD, 0x6377, + 0xBDDE, 0x776B, 0xBDDF, 0x7AED, 0xBDE0, 0x6D01, 0xBDE1, 0x7ED3, + 0xBDE2, 0x89E3, 0xBDE3, 0x59D0, 0xBDE4, 0x6212, 0xBDE5, 0x85C9, + 0xBDE6, 0x82A5, 0xBDE7, 0x754C, 0xBDE8, 0x501F, 0xBDE9, 0x4ECB, + 0xBDEA, 0x75A5, 0xBDEB, 0x8BEB, 0xBDEC, 0x5C4A, 0xBDED, 0x5DFE, + 0xBDEE, 0x7B4B, 0xBDEF, 0x65A4, 0xBDF0, 0x91D1, 0xBDF1, 0x4ECA, + 0xBDF2, 0x6D25, 0xBDF3, 0x895F, 0xBDF4, 0x7D27, 0xBDF5, 0x9526, + 0xBDF6, 0x4EC5, 0xBDF7, 0x8C28, 0xBDF8, 0x8FDB, 0xBDF9, 0x9773, + 0xBDFA, 0x664B, 0xBDFB, 0x7981, 0xBDFC, 0x8FD1, 0xBDFD, 0x70EC, + 0xBDFE, 0x6D78, 0xBE40, 0x7D99, 0xBE41, 0x7D9A, 0xBE42, 0x7D9B, + 0xBE43, 0x7D9C, 0xBE44, 0x7D9D, 0xBE45, 0x7D9E, 0xBE46, 0x7D9F, + 0xBE47, 0x7DA0, 0xBE48, 0x7DA1, 0xBE49, 0x7DA2, 0xBE4A, 0x7DA3, + 0xBE4B, 0x7DA4, 0xBE4C, 0x7DA5, 0xBE4D, 0x7DA7, 0xBE4E, 0x7DA8, + 0xBE4F, 0x7DA9, 0xBE50, 0x7DAA, 0xBE51, 0x7DAB, 0xBE52, 0x7DAC, + 0xBE53, 0x7DAD, 0xBE54, 0x7DAF, 0xBE55, 0x7DB0, 0xBE56, 0x7DB1, + 0xBE57, 0x7DB2, 0xBE58, 0x7DB3, 0xBE59, 0x7DB4, 0xBE5A, 0x7DB5, + 0xBE5B, 0x7DB6, 0xBE5C, 0x7DB7, 0xBE5D, 0x7DB8, 0xBE5E, 0x7DB9, + 0xBE5F, 0x7DBA, 0xBE60, 0x7DBB, 0xBE61, 0x7DBC, 0xBE62, 0x7DBD, + 0xBE63, 0x7DBE, 0xBE64, 0x7DBF, 0xBE65, 0x7DC0, 0xBE66, 0x7DC1, + 0xBE67, 0x7DC2, 0xBE68, 0x7DC3, 0xBE69, 0x7DC4, 0xBE6A, 0x7DC5, + 0xBE6B, 0x7DC6, 0xBE6C, 0x7DC7, 0xBE6D, 0x7DC8, 0xBE6E, 0x7DC9, + 0xBE6F, 0x7DCA, 0xBE70, 0x7DCB, 0xBE71, 0x7DCC, 0xBE72, 0x7DCD, + 0xBE73, 0x7DCE, 0xBE74, 0x7DCF, 0xBE75, 0x7DD0, 0xBE76, 0x7DD1, + 0xBE77, 0x7DD2, 0xBE78, 0x7DD3, 0xBE79, 0x7DD4, 0xBE7A, 0x7DD5, + 0xBE7B, 0x7DD6, 0xBE7C, 0x7DD7, 0xBE7D, 0x7DD8, 0xBE7E, 0x7DD9, + 0xBE80, 0x7DDA, 0xBE81, 0x7DDB, 0xBE82, 0x7DDC, 0xBE83, 0x7DDD, + 0xBE84, 0x7DDE, 0xBE85, 0x7DDF, 0xBE86, 0x7DE0, 0xBE87, 0x7DE1, + 0xBE88, 0x7DE2, 0xBE89, 0x7DE3, 0xBE8A, 0x7DE4, 0xBE8B, 0x7DE5, + 0xBE8C, 0x7DE6, 0xBE8D, 0x7DE7, 0xBE8E, 0x7DE8, 0xBE8F, 0x7DE9, + 0xBE90, 0x7DEA, 0xBE91, 0x7DEB, 0xBE92, 0x7DEC, 0xBE93, 0x7DED, + 0xBE94, 0x7DEE, 0xBE95, 0x7DEF, 0xBE96, 0x7DF0, 0xBE97, 0x7DF1, + 0xBE98, 0x7DF2, 0xBE99, 0x7DF3, 0xBE9A, 0x7DF4, 0xBE9B, 0x7DF5, + 0xBE9C, 0x7DF6, 0xBE9D, 0x7DF7, 0xBE9E, 0x7DF8, 0xBE9F, 0x7DF9, + 0xBEA0, 0x7DFA, 0xBEA1, 0x5C3D, 0xBEA2, 0x52B2, 0xBEA3, 0x8346, + 0xBEA4, 0x5162, 0xBEA5, 0x830E, 0xBEA6, 0x775B, 0xBEA7, 0x6676, + 0xBEA8, 0x9CB8, 0xBEA9, 0x4EAC, 0xBEAA, 0x60CA, 0xBEAB, 0x7CBE, + 0xBEAC, 0x7CB3, 0xBEAD, 0x7ECF, 0xBEAE, 0x4E95, 0xBEAF, 0x8B66, + 0xBEB0, 0x666F, 0xBEB1, 0x9888, 0xBEB2, 0x9759, 0xBEB3, 0x5883, + 0xBEB4, 0x656C, 0xBEB5, 0x955C, 0xBEB6, 0x5F84, 0xBEB7, 0x75C9, + 0xBEB8, 0x9756, 0xBEB9, 0x7ADF, 0xBEBA, 0x7ADE, 0xBEBB, 0x51C0, + 0xBEBC, 0x70AF, 0xBEBD, 0x7A98, 0xBEBE, 0x63EA, 0xBEBF, 0x7A76, + 0xBEC0, 0x7EA0, 0xBEC1, 0x7396, 0xBEC2, 0x97ED, 0xBEC3, 0x4E45, + 0xBEC4, 0x7078, 0xBEC5, 0x4E5D, 0xBEC6, 0x9152, 0xBEC7, 0x53A9, + 0xBEC8, 0x6551, 0xBEC9, 0x65E7, 0xBECA, 0x81FC, 0xBECB, 0x8205, + 0xBECC, 0x548E, 0xBECD, 0x5C31, 0xBECE, 0x759A, 0xBECF, 0x97A0, + 0xBED0, 0x62D8, 0xBED1, 0x72D9, 0xBED2, 0x75BD, 0xBED3, 0x5C45, + 0xBED4, 0x9A79, 0xBED5, 0x83CA, 0xBED6, 0x5C40, 0xBED7, 0x5480, + 0xBED8, 0x77E9, 0xBED9, 0x4E3E, 0xBEDA, 0x6CAE, 0xBEDB, 0x805A, + 0xBEDC, 0x62D2, 0xBEDD, 0x636E, 0xBEDE, 0x5DE8, 0xBEDF, 0x5177, + 0xBEE0, 0x8DDD, 0xBEE1, 0x8E1E, 0xBEE2, 0x952F, 0xBEE3, 0x4FF1, + 0xBEE4, 0x53E5, 0xBEE5, 0x60E7, 0xBEE6, 0x70AC, 0xBEE7, 0x5267, + 0xBEE8, 0x6350, 0xBEE9, 0x9E43, 0xBEEA, 0x5A1F, 0xBEEB, 0x5026, + 0xBEEC, 0x7737, 0xBEED, 0x5377, 0xBEEE, 0x7EE2, 0xBEEF, 0x6485, + 0xBEF0, 0x652B, 0xBEF1, 0x6289, 0xBEF2, 0x6398, 0xBEF3, 0x5014, + 0xBEF4, 0x7235, 0xBEF5, 0x89C9, 0xBEF6, 0x51B3, 0xBEF7, 0x8BC0, + 0xBEF8, 0x7EDD, 0xBEF9, 0x5747, 0xBEFA, 0x83CC, 0xBEFB, 0x94A7, + 0xBEFC, 0x519B, 0xBEFD, 0x541B, 0xBEFE, 0x5CFB, 0xBF40, 0x7DFB, + 0xBF41, 0x7DFC, 0xBF42, 0x7DFD, 0xBF43, 0x7DFE, 0xBF44, 0x7DFF, + 0xBF45, 0x7E00, 0xBF46, 0x7E01, 0xBF47, 0x7E02, 0xBF48, 0x7E03, + 0xBF49, 0x7E04, 0xBF4A, 0x7E05, 0xBF4B, 0x7E06, 0xBF4C, 0x7E07, + 0xBF4D, 0x7E08, 0xBF4E, 0x7E09, 0xBF4F, 0x7E0A, 0xBF50, 0x7E0B, + 0xBF51, 0x7E0C, 0xBF52, 0x7E0D, 0xBF53, 0x7E0E, 0xBF54, 0x7E0F, + 0xBF55, 0x7E10, 0xBF56, 0x7E11, 0xBF57, 0x7E12, 0xBF58, 0x7E13, + 0xBF59, 0x7E14, 0xBF5A, 0x7E15, 0xBF5B, 0x7E16, 0xBF5C, 0x7E17, + 0xBF5D, 0x7E18, 0xBF5E, 0x7E19, 0xBF5F, 0x7E1A, 0xBF60, 0x7E1B, + 0xBF61, 0x7E1C, 0xBF62, 0x7E1D, 0xBF63, 0x7E1E, 0xBF64, 0x7E1F, + 0xBF65, 0x7E20, 0xBF66, 0x7E21, 0xBF67, 0x7E22, 0xBF68, 0x7E23, + 0xBF69, 0x7E24, 0xBF6A, 0x7E25, 0xBF6B, 0x7E26, 0xBF6C, 0x7E27, + 0xBF6D, 0x7E28, 0xBF6E, 0x7E29, 0xBF6F, 0x7E2A, 0xBF70, 0x7E2B, + 0xBF71, 0x7E2C, 0xBF72, 0x7E2D, 0xBF73, 0x7E2E, 0xBF74, 0x7E2F, + 0xBF75, 0x7E30, 0xBF76, 0x7E31, 0xBF77, 0x7E32, 0xBF78, 0x7E33, + 0xBF79, 0x7E34, 0xBF7A, 0x7E35, 0xBF7B, 0x7E36, 0xBF7C, 0x7E37, + 0xBF7D, 0x7E38, 0xBF7E, 0x7E39, 0xBF80, 0x7E3A, 0xBF81, 0x7E3C, + 0xBF82, 0x7E3D, 0xBF83, 0x7E3E, 0xBF84, 0x7E3F, 0xBF85, 0x7E40, + 0xBF86, 0x7E42, 0xBF87, 0x7E43, 0xBF88, 0x7E44, 0xBF89, 0x7E45, + 0xBF8A, 0x7E46, 0xBF8B, 0x7E48, 0xBF8C, 0x7E49, 0xBF8D, 0x7E4A, + 0xBF8E, 0x7E4B, 0xBF8F, 0x7E4C, 0xBF90, 0x7E4D, 0xBF91, 0x7E4E, + 0xBF92, 0x7E4F, 0xBF93, 0x7E50, 0xBF94, 0x7E51, 0xBF95, 0x7E52, + 0xBF96, 0x7E53, 0xBF97, 0x7E54, 0xBF98, 0x7E55, 0xBF99, 0x7E56, + 0xBF9A, 0x7E57, 0xBF9B, 0x7E58, 0xBF9C, 0x7E59, 0xBF9D, 0x7E5A, + 0xBF9E, 0x7E5B, 0xBF9F, 0x7E5C, 0xBFA0, 0x7E5D, 0xBFA1, 0x4FCA, + 0xBFA2, 0x7AE3, 0xBFA3, 0x6D5A, 0xBFA4, 0x90E1, 0xBFA5, 0x9A8F, + 0xBFA6, 0x5580, 0xBFA7, 0x5496, 0xBFA8, 0x5361, 0xBFA9, 0x54AF, + 0xBFAA, 0x5F00, 0xBFAB, 0x63E9, 0xBFAC, 0x6977, 0xBFAD, 0x51EF, + 0xBFAE, 0x6168, 0xBFAF, 0x520A, 0xBFB0, 0x582A, 0xBFB1, 0x52D8, + 0xBFB2, 0x574E, 0xBFB3, 0x780D, 0xBFB4, 0x770B, 0xBFB5, 0x5EB7, + 0xBFB6, 0x6177, 0xBFB7, 0x7CE0, 0xBFB8, 0x625B, 0xBFB9, 0x6297, + 0xBFBA, 0x4EA2, 0xBFBB, 0x7095, 0xBFBC, 0x8003, 0xBFBD, 0x62F7, + 0xBFBE, 0x70E4, 0xBFBF, 0x9760, 0xBFC0, 0x5777, 0xBFC1, 0x82DB, + 0xBFC2, 0x67EF, 0xBFC3, 0x68F5, 0xBFC4, 0x78D5, 0xBFC5, 0x9897, + 0xBFC6, 0x79D1, 0xBFC7, 0x58F3, 0xBFC8, 0x54B3, 0xBFC9, 0x53EF, + 0xBFCA, 0x6E34, 0xBFCB, 0x514B, 0xBFCC, 0x523B, 0xBFCD, 0x5BA2, + 0xBFCE, 0x8BFE, 0xBFCF, 0x80AF, 0xBFD0, 0x5543, 0xBFD1, 0x57A6, + 0xBFD2, 0x6073, 0xBFD3, 0x5751, 0xBFD4, 0x542D, 0xBFD5, 0x7A7A, + 0xBFD6, 0x6050, 0xBFD7, 0x5B54, 0xBFD8, 0x63A7, 0xBFD9, 0x62A0, + 0xBFDA, 0x53E3, 0xBFDB, 0x6263, 0xBFDC, 0x5BC7, 0xBFDD, 0x67AF, + 0xBFDE, 0x54ED, 0xBFDF, 0x7A9F, 0xBFE0, 0x82E6, 0xBFE1, 0x9177, + 0xBFE2, 0x5E93, 0xBFE3, 0x88E4, 0xBFE4, 0x5938, 0xBFE5, 0x57AE, + 0xBFE6, 0x630E, 0xBFE7, 0x8DE8, 0xBFE8, 0x80EF, 0xBFE9, 0x5757, + 0xBFEA, 0x7B77, 0xBFEB, 0x4FA9, 0xBFEC, 0x5FEB, 0xBFED, 0x5BBD, + 0xBFEE, 0x6B3E, 0xBFEF, 0x5321, 0xBFF0, 0x7B50, 0xBFF1, 0x72C2, + 0xBFF2, 0x6846, 0xBFF3, 0x77FF, 0xBFF4, 0x7736, 0xBFF5, 0x65F7, + 0xBFF6, 0x51B5, 0xBFF7, 0x4E8F, 0xBFF8, 0x76D4, 0xBFF9, 0x5CBF, + 0xBFFA, 0x7AA5, 0xBFFB, 0x8475, 0xBFFC, 0x594E, 0xBFFD, 0x9B41, + 0xBFFE, 0x5080, 0xC040, 0x7E5E, 0xC041, 0x7E5F, 0xC042, 0x7E60, + 0xC043, 0x7E61, 0xC044, 0x7E62, 0xC045, 0x7E63, 0xC046, 0x7E64, + 0xC047, 0x7E65, 0xC048, 0x7E66, 0xC049, 0x7E67, 0xC04A, 0x7E68, + 0xC04B, 0x7E69, 0xC04C, 0x7E6A, 0xC04D, 0x7E6B, 0xC04E, 0x7E6C, + 0xC04F, 0x7E6D, 0xC050, 0x7E6E, 0xC051, 0x7E6F, 0xC052, 0x7E70, + 0xC053, 0x7E71, 0xC054, 0x7E72, 0xC055, 0x7E73, 0xC056, 0x7E74, + 0xC057, 0x7E75, 0xC058, 0x7E76, 0xC059, 0x7E77, 0xC05A, 0x7E78, + 0xC05B, 0x7E79, 0xC05C, 0x7E7A, 0xC05D, 0x7E7B, 0xC05E, 0x7E7C, + 0xC05F, 0x7E7D, 0xC060, 0x7E7E, 0xC061, 0x7E7F, 0xC062, 0x7E80, + 0xC063, 0x7E81, 0xC064, 0x7E83, 0xC065, 0x7E84, 0xC066, 0x7E85, + 0xC067, 0x7E86, 0xC068, 0x7E87, 0xC069, 0x7E88, 0xC06A, 0x7E89, + 0xC06B, 0x7E8A, 0xC06C, 0x7E8B, 0xC06D, 0x7E8C, 0xC06E, 0x7E8D, + 0xC06F, 0x7E8E, 0xC070, 0x7E8F, 0xC071, 0x7E90, 0xC072, 0x7E91, + 0xC073, 0x7E92, 0xC074, 0x7E93, 0xC075, 0x7E94, 0xC076, 0x7E95, + 0xC077, 0x7E96, 0xC078, 0x7E97, 0xC079, 0x7E98, 0xC07A, 0x7E99, + 0xC07B, 0x7E9A, 0xC07C, 0x7E9C, 0xC07D, 0x7E9D, 0xC07E, 0x7E9E, + 0xC080, 0x7EAE, 0xC081, 0x7EB4, 0xC082, 0x7EBB, 0xC083, 0x7EBC, + 0xC084, 0x7ED6, 0xC085, 0x7EE4, 0xC086, 0x7EEC, 0xC087, 0x7EF9, + 0xC088, 0x7F0A, 0xC089, 0x7F10, 0xC08A, 0x7F1E, 0xC08B, 0x7F37, + 0xC08C, 0x7F39, 0xC08D, 0x7F3B, 0xC08E, 0x7F3C, 0xC08F, 0x7F3D, + 0xC090, 0x7F3E, 0xC091, 0x7F3F, 0xC092, 0x7F40, 0xC093, 0x7F41, + 0xC094, 0x7F43, 0xC095, 0x7F46, 0xC096, 0x7F47, 0xC097, 0x7F48, + 0xC098, 0x7F49, 0xC099, 0x7F4A, 0xC09A, 0x7F4B, 0xC09B, 0x7F4C, + 0xC09C, 0x7F4D, 0xC09D, 0x7F4E, 0xC09E, 0x7F4F, 0xC09F, 0x7F52, + 0xC0A0, 0x7F53, 0xC0A1, 0x9988, 0xC0A2, 0x6127, 0xC0A3, 0x6E83, + 0xC0A4, 0x5764, 0xC0A5, 0x6606, 0xC0A6, 0x6346, 0xC0A7, 0x56F0, + 0xC0A8, 0x62EC, 0xC0A9, 0x6269, 0xC0AA, 0x5ED3, 0xC0AB, 0x9614, + 0xC0AC, 0x5783, 0xC0AD, 0x62C9, 0xC0AE, 0x5587, 0xC0AF, 0x8721, + 0xC0B0, 0x814A, 0xC0B1, 0x8FA3, 0xC0B2, 0x5566, 0xC0B3, 0x83B1, + 0xC0B4, 0x6765, 0xC0B5, 0x8D56, 0xC0B6, 0x84DD, 0xC0B7, 0x5A6A, + 0xC0B8, 0x680F, 0xC0B9, 0x62E6, 0xC0BA, 0x7BEE, 0xC0BB, 0x9611, + 0xC0BC, 0x5170, 0xC0BD, 0x6F9C, 0xC0BE, 0x8C30, 0xC0BF, 0x63FD, + 0xC0C0, 0x89C8, 0xC0C1, 0x61D2, 0xC0C2, 0x7F06, 0xC0C3, 0x70C2, + 0xC0C4, 0x6EE5, 0xC0C5, 0x7405, 0xC0C6, 0x6994, 0xC0C7, 0x72FC, + 0xC0C8, 0x5ECA, 0xC0C9, 0x90CE, 0xC0CA, 0x6717, 0xC0CB, 0x6D6A, + 0xC0CC, 0x635E, 0xC0CD, 0x52B3, 0xC0CE, 0x7262, 0xC0CF, 0x8001, + 0xC0D0, 0x4F6C, 0xC0D1, 0x59E5, 0xC0D2, 0x916A, 0xC0D3, 0x70D9, + 0xC0D4, 0x6D9D, 0xC0D5, 0x52D2, 0xC0D6, 0x4E50, 0xC0D7, 0x96F7, + 0xC0D8, 0x956D, 0xC0D9, 0x857E, 0xC0DA, 0x78CA, 0xC0DB, 0x7D2F, + 0xC0DC, 0x5121, 0xC0DD, 0x5792, 0xC0DE, 0x64C2, 0xC0DF, 0x808B, + 0xC0E0, 0x7C7B, 0xC0E1, 0x6CEA, 0xC0E2, 0x68F1, 0xC0E3, 0x695E, + 0xC0E4, 0x51B7, 0xC0E5, 0x5398, 0xC0E6, 0x68A8, 0xC0E7, 0x7281, + 0xC0E8, 0x9ECE, 0xC0E9, 0x7BF1, 0xC0EA, 0x72F8, 0xC0EB, 0x79BB, + 0xC0EC, 0x6F13, 0xC0ED, 0x7406, 0xC0EE, 0x674E, 0xC0EF, 0x91CC, + 0xC0F0, 0x9CA4, 0xC0F1, 0x793C, 0xC0F2, 0x8389, 0xC0F3, 0x8354, + 0xC0F4, 0x540F, 0xC0F5, 0x6817, 0xC0F6, 0x4E3D, 0xC0F7, 0x5389, + 0xC0F8, 0x52B1, 0xC0F9, 0x783E, 0xC0FA, 0x5386, 0xC0FB, 0x5229, + 0xC0FC, 0x5088, 0xC0FD, 0x4F8B, 0xC0FE, 0x4FD0, 0xC140, 0x7F56, + 0xC141, 0x7F59, 0xC142, 0x7F5B, 0xC143, 0x7F5C, 0xC144, 0x7F5D, + 0xC145, 0x7F5E, 0xC146, 0x7F60, 0xC147, 0x7F63, 0xC148, 0x7F64, + 0xC149, 0x7F65, 0xC14A, 0x7F66, 0xC14B, 0x7F67, 0xC14C, 0x7F6B, + 0xC14D, 0x7F6C, 0xC14E, 0x7F6D, 0xC14F, 0x7F6F, 0xC150, 0x7F70, + 0xC151, 0x7F73, 0xC152, 0x7F75, 0xC153, 0x7F76, 0xC154, 0x7F77, + 0xC155, 0x7F78, 0xC156, 0x7F7A, 0xC157, 0x7F7B, 0xC158, 0x7F7C, + 0xC159, 0x7F7D, 0xC15A, 0x7F7F, 0xC15B, 0x7F80, 0xC15C, 0x7F82, + 0xC15D, 0x7F83, 0xC15E, 0x7F84, 0xC15F, 0x7F85, 0xC160, 0x7F86, + 0xC161, 0x7F87, 0xC162, 0x7F88, 0xC163, 0x7F89, 0xC164, 0x7F8B, + 0xC165, 0x7F8D, 0xC166, 0x7F8F, 0xC167, 0x7F90, 0xC168, 0x7F91, + 0xC169, 0x7F92, 0xC16A, 0x7F93, 0xC16B, 0x7F95, 0xC16C, 0x7F96, + 0xC16D, 0x7F97, 0xC16E, 0x7F98, 0xC16F, 0x7F99, 0xC170, 0x7F9B, + 0xC171, 0x7F9C, 0xC172, 0x7FA0, 0xC173, 0x7FA2, 0xC174, 0x7FA3, + 0xC175, 0x7FA5, 0xC176, 0x7FA6, 0xC177, 0x7FA8, 0xC178, 0x7FA9, + 0xC179, 0x7FAA, 0xC17A, 0x7FAB, 0xC17B, 0x7FAC, 0xC17C, 0x7FAD, + 0xC17D, 0x7FAE, 0xC17E, 0x7FB1, 0xC180, 0x7FB3, 0xC181, 0x7FB4, + 0xC182, 0x7FB5, 0xC183, 0x7FB6, 0xC184, 0x7FB7, 0xC185, 0x7FBA, + 0xC186, 0x7FBB, 0xC187, 0x7FBE, 0xC188, 0x7FC0, 0xC189, 0x7FC2, + 0xC18A, 0x7FC3, 0xC18B, 0x7FC4, 0xC18C, 0x7FC6, 0xC18D, 0x7FC7, + 0xC18E, 0x7FC8, 0xC18F, 0x7FC9, 0xC190, 0x7FCB, 0xC191, 0x7FCD, + 0xC192, 0x7FCF, 0xC193, 0x7FD0, 0xC194, 0x7FD1, 0xC195, 0x7FD2, + 0xC196, 0x7FD3, 0xC197, 0x7FD6, 0xC198, 0x7FD7, 0xC199, 0x7FD9, + 0xC19A, 0x7FDA, 0xC19B, 0x7FDB, 0xC19C, 0x7FDC, 0xC19D, 0x7FDD, + 0xC19E, 0x7FDE, 0xC19F, 0x7FE2, 0xC1A0, 0x7FE3, 0xC1A1, 0x75E2, + 0xC1A2, 0x7ACB, 0xC1A3, 0x7C92, 0xC1A4, 0x6CA5, 0xC1A5, 0x96B6, + 0xC1A6, 0x529B, 0xC1A7, 0x7483, 0xC1A8, 0x54E9, 0xC1A9, 0x4FE9, + 0xC1AA, 0x8054, 0xC1AB, 0x83B2, 0xC1AC, 0x8FDE, 0xC1AD, 0x9570, + 0xC1AE, 0x5EC9, 0xC1AF, 0x601C, 0xC1B0, 0x6D9F, 0xC1B1, 0x5E18, + 0xC1B2, 0x655B, 0xC1B3, 0x8138, 0xC1B4, 0x94FE, 0xC1B5, 0x604B, + 0xC1B6, 0x70BC, 0xC1B7, 0x7EC3, 0xC1B8, 0x7CAE, 0xC1B9, 0x51C9, + 0xC1BA, 0x6881, 0xC1BB, 0x7CB1, 0xC1BC, 0x826F, 0xC1BD, 0x4E24, + 0xC1BE, 0x8F86, 0xC1BF, 0x91CF, 0xC1C0, 0x667E, 0xC1C1, 0x4EAE, + 0xC1C2, 0x8C05, 0xC1C3, 0x64A9, 0xC1C4, 0x804A, 0xC1C5, 0x50DA, + 0xC1C6, 0x7597, 0xC1C7, 0x71CE, 0xC1C8, 0x5BE5, 0xC1C9, 0x8FBD, + 0xC1CA, 0x6F66, 0xC1CB, 0x4E86, 0xC1CC, 0x6482, 0xC1CD, 0x9563, + 0xC1CE, 0x5ED6, 0xC1CF, 0x6599, 0xC1D0, 0x5217, 0xC1D1, 0x88C2, + 0xC1D2, 0x70C8, 0xC1D3, 0x52A3, 0xC1D4, 0x730E, 0xC1D5, 0x7433, + 0xC1D6, 0x6797, 0xC1D7, 0x78F7, 0xC1D8, 0x9716, 0xC1D9, 0x4E34, + 0xC1DA, 0x90BB, 0xC1DB, 0x9CDE, 0xC1DC, 0x6DCB, 0xC1DD, 0x51DB, + 0xC1DE, 0x8D41, 0xC1DF, 0x541D, 0xC1E0, 0x62CE, 0xC1E1, 0x73B2, + 0xC1E2, 0x83F1, 0xC1E3, 0x96F6, 0xC1E4, 0x9F84, 0xC1E5, 0x94C3, + 0xC1E6, 0x4F36, 0xC1E7, 0x7F9A, 0xC1E8, 0x51CC, 0xC1E9, 0x7075, + 0xC1EA, 0x9675, 0xC1EB, 0x5CAD, 0xC1EC, 0x9886, 0xC1ED, 0x53E6, + 0xC1EE, 0x4EE4, 0xC1EF, 0x6E9C, 0xC1F0, 0x7409, 0xC1F1, 0x69B4, + 0xC1F2, 0x786B, 0xC1F3, 0x998F, 0xC1F4, 0x7559, 0xC1F5, 0x5218, + 0xC1F6, 0x7624, 0xC1F7, 0x6D41, 0xC1F8, 0x67F3, 0xC1F9, 0x516D, + 0xC1FA, 0x9F99, 0xC1FB, 0x804B, 0xC1FC, 0x5499, 0xC1FD, 0x7B3C, + 0xC1FE, 0x7ABF, 0xC240, 0x7FE4, 0xC241, 0x7FE7, 0xC242, 0x7FE8, + 0xC243, 0x7FEA, 0xC244, 0x7FEB, 0xC245, 0x7FEC, 0xC246, 0x7FED, + 0xC247, 0x7FEF, 0xC248, 0x7FF2, 0xC249, 0x7FF4, 0xC24A, 0x7FF5, + 0xC24B, 0x7FF6, 0xC24C, 0x7FF7, 0xC24D, 0x7FF8, 0xC24E, 0x7FF9, + 0xC24F, 0x7FFA, 0xC250, 0x7FFD, 0xC251, 0x7FFE, 0xC252, 0x7FFF, + 0xC253, 0x8002, 0xC254, 0x8007, 0xC255, 0x8008, 0xC256, 0x8009, + 0xC257, 0x800A, 0xC258, 0x800E, 0xC259, 0x800F, 0xC25A, 0x8011, + 0xC25B, 0x8013, 0xC25C, 0x801A, 0xC25D, 0x801B, 0xC25E, 0x801D, + 0xC25F, 0x801E, 0xC260, 0x801F, 0xC261, 0x8021, 0xC262, 0x8023, + 0xC263, 0x8024, 0xC264, 0x802B, 0xC265, 0x802C, 0xC266, 0x802D, + 0xC267, 0x802E, 0xC268, 0x802F, 0xC269, 0x8030, 0xC26A, 0x8032, + 0xC26B, 0x8034, 0xC26C, 0x8039, 0xC26D, 0x803A, 0xC26E, 0x803C, + 0xC26F, 0x803E, 0xC270, 0x8040, 0xC271, 0x8041, 0xC272, 0x8044, + 0xC273, 0x8045, 0xC274, 0x8047, 0xC275, 0x8048, 0xC276, 0x8049, + 0xC277, 0x804E, 0xC278, 0x804F, 0xC279, 0x8050, 0xC27A, 0x8051, + 0xC27B, 0x8053, 0xC27C, 0x8055, 0xC27D, 0x8056, 0xC27E, 0x8057, + 0xC280, 0x8059, 0xC281, 0x805B, 0xC282, 0x805C, 0xC283, 0x805D, + 0xC284, 0x805E, 0xC285, 0x805F, 0xC286, 0x8060, 0xC287, 0x8061, + 0xC288, 0x8062, 0xC289, 0x8063, 0xC28A, 0x8064, 0xC28B, 0x8065, + 0xC28C, 0x8066, 0xC28D, 0x8067, 0xC28E, 0x8068, 0xC28F, 0x806B, + 0xC290, 0x806C, 0xC291, 0x806D, 0xC292, 0x806E, 0xC293, 0x806F, + 0xC294, 0x8070, 0xC295, 0x8072, 0xC296, 0x8073, 0xC297, 0x8074, + 0xC298, 0x8075, 0xC299, 0x8076, 0xC29A, 0x8077, 0xC29B, 0x8078, + 0xC29C, 0x8079, 0xC29D, 0x807A, 0xC29E, 0x807B, 0xC29F, 0x807C, + 0xC2A0, 0x807D, 0xC2A1, 0x9686, 0xC2A2, 0x5784, 0xC2A3, 0x62E2, + 0xC2A4, 0x9647, 0xC2A5, 0x697C, 0xC2A6, 0x5A04, 0xC2A7, 0x6402, + 0xC2A8, 0x7BD3, 0xC2A9, 0x6F0F, 0xC2AA, 0x964B, 0xC2AB, 0x82A6, + 0xC2AC, 0x5362, 0xC2AD, 0x9885, 0xC2AE, 0x5E90, 0xC2AF, 0x7089, + 0xC2B0, 0x63B3, 0xC2B1, 0x5364, 0xC2B2, 0x864F, 0xC2B3, 0x9C81, + 0xC2B4, 0x9E93, 0xC2B5, 0x788C, 0xC2B6, 0x9732, 0xC2B7, 0x8DEF, + 0xC2B8, 0x8D42, 0xC2B9, 0x9E7F, 0xC2BA, 0x6F5E, 0xC2BB, 0x7984, + 0xC2BC, 0x5F55, 0xC2BD, 0x9646, 0xC2BE, 0x622E, 0xC2BF, 0x9A74, + 0xC2C0, 0x5415, 0xC2C1, 0x94DD, 0xC2C2, 0x4FA3, 0xC2C3, 0x65C5, + 0xC2C4, 0x5C65, 0xC2C5, 0x5C61, 0xC2C6, 0x7F15, 0xC2C7, 0x8651, + 0xC2C8, 0x6C2F, 0xC2C9, 0x5F8B, 0xC2CA, 0x7387, 0xC2CB, 0x6EE4, + 0xC2CC, 0x7EFF, 0xC2CD, 0x5CE6, 0xC2CE, 0x631B, 0xC2CF, 0x5B6A, + 0xC2D0, 0x6EE6, 0xC2D1, 0x5375, 0xC2D2, 0x4E71, 0xC2D3, 0x63A0, + 0xC2D4, 0x7565, 0xC2D5, 0x62A1, 0xC2D6, 0x8F6E, 0xC2D7, 0x4F26, + 0xC2D8, 0x4ED1, 0xC2D9, 0x6CA6, 0xC2DA, 0x7EB6, 0xC2DB, 0x8BBA, + 0xC2DC, 0x841D, 0xC2DD, 0x87BA, 0xC2DE, 0x7F57, 0xC2DF, 0x903B, + 0xC2E0, 0x9523, 0xC2E1, 0x7BA9, 0xC2E2, 0x9AA1, 0xC2E3, 0x88F8, + 0xC2E4, 0x843D, 0xC2E5, 0x6D1B, 0xC2E6, 0x9A86, 0xC2E7, 0x7EDC, + 0xC2E8, 0x5988, 0xC2E9, 0x9EBB, 0xC2EA, 0x739B, 0xC2EB, 0x7801, + 0xC2EC, 0x8682, 0xC2ED, 0x9A6C, 0xC2EE, 0x9A82, 0xC2EF, 0x561B, + 0xC2F0, 0x5417, 0xC2F1, 0x57CB, 0xC2F2, 0x4E70, 0xC2F3, 0x9EA6, + 0xC2F4, 0x5356, 0xC2F5, 0x8FC8, 0xC2F6, 0x8109, 0xC2F7, 0x7792, + 0xC2F8, 0x9992, 0xC2F9, 0x86EE, 0xC2FA, 0x6EE1, 0xC2FB, 0x8513, + 0xC2FC, 0x66FC, 0xC2FD, 0x6162, 0xC2FE, 0x6F2B, 0xC340, 0x807E, + 0xC341, 0x8081, 0xC342, 0x8082, 0xC343, 0x8085, 0xC344, 0x8088, + 0xC345, 0x808A, 0xC346, 0x808D, 0xC347, 0x808E, 0xC348, 0x808F, + 0xC349, 0x8090, 0xC34A, 0x8091, 0xC34B, 0x8092, 0xC34C, 0x8094, + 0xC34D, 0x8095, 0xC34E, 0x8097, 0xC34F, 0x8099, 0xC350, 0x809E, + 0xC351, 0x80A3, 0xC352, 0x80A6, 0xC353, 0x80A7, 0xC354, 0x80A8, + 0xC355, 0x80AC, 0xC356, 0x80B0, 0xC357, 0x80B3, 0xC358, 0x80B5, + 0xC359, 0x80B6, 0xC35A, 0x80B8, 0xC35B, 0x80B9, 0xC35C, 0x80BB, + 0xC35D, 0x80C5, 0xC35E, 0x80C7, 0xC35F, 0x80C8, 0xC360, 0x80C9, + 0xC361, 0x80CA, 0xC362, 0x80CB, 0xC363, 0x80CF, 0xC364, 0x80D0, + 0xC365, 0x80D1, 0xC366, 0x80D2, 0xC367, 0x80D3, 0xC368, 0x80D4, + 0xC369, 0x80D5, 0xC36A, 0x80D8, 0xC36B, 0x80DF, 0xC36C, 0x80E0, + 0xC36D, 0x80E2, 0xC36E, 0x80E3, 0xC36F, 0x80E6, 0xC370, 0x80EE, + 0xC371, 0x80F5, 0xC372, 0x80F7, 0xC373, 0x80F9, 0xC374, 0x80FB, + 0xC375, 0x80FE, 0xC376, 0x80FF, 0xC377, 0x8100, 0xC378, 0x8101, + 0xC379, 0x8103, 0xC37A, 0x8104, 0xC37B, 0x8105, 0xC37C, 0x8107, + 0xC37D, 0x8108, 0xC37E, 0x810B, 0xC380, 0x810C, 0xC381, 0x8115, + 0xC382, 0x8117, 0xC383, 0x8119, 0xC384, 0x811B, 0xC385, 0x811C, + 0xC386, 0x811D, 0xC387, 0x811F, 0xC388, 0x8120, 0xC389, 0x8121, + 0xC38A, 0x8122, 0xC38B, 0x8123, 0xC38C, 0x8124, 0xC38D, 0x8125, + 0xC38E, 0x8126, 0xC38F, 0x8127, 0xC390, 0x8128, 0xC391, 0x8129, + 0xC392, 0x812A, 0xC393, 0x812B, 0xC394, 0x812D, 0xC395, 0x812E, + 0xC396, 0x8130, 0xC397, 0x8133, 0xC398, 0x8134, 0xC399, 0x8135, + 0xC39A, 0x8137, 0xC39B, 0x8139, 0xC39C, 0x813A, 0xC39D, 0x813B, + 0xC39E, 0x813C, 0xC39F, 0x813D, 0xC3A0, 0x813F, 0xC3A1, 0x8C29, + 0xC3A2, 0x8292, 0xC3A3, 0x832B, 0xC3A4, 0x76F2, 0xC3A5, 0x6C13, + 0xC3A6, 0x5FD9, 0xC3A7, 0x83BD, 0xC3A8, 0x732B, 0xC3A9, 0x8305, + 0xC3AA, 0x951A, 0xC3AB, 0x6BDB, 0xC3AC, 0x77DB, 0xC3AD, 0x94C6, + 0xC3AE, 0x536F, 0xC3AF, 0x8302, 0xC3B0, 0x5192, 0xC3B1, 0x5E3D, + 0xC3B2, 0x8C8C, 0xC3B3, 0x8D38, 0xC3B4, 0x4E48, 0xC3B5, 0x73AB, + 0xC3B6, 0x679A, 0xC3B7, 0x6885, 0xC3B8, 0x9176, 0xC3B9, 0x9709, + 0xC3BA, 0x7164, 0xC3BB, 0x6CA1, 0xC3BC, 0x7709, 0xC3BD, 0x5A92, + 0xC3BE, 0x9541, 0xC3BF, 0x6BCF, 0xC3C0, 0x7F8E, 0xC3C1, 0x6627, + 0xC3C2, 0x5BD0, 0xC3C3, 0x59B9, 0xC3C4, 0x5A9A, 0xC3C5, 0x95E8, + 0xC3C6, 0x95F7, 0xC3C7, 0x4EEC, 0xC3C8, 0x840C, 0xC3C9, 0x8499, + 0xC3CA, 0x6AAC, 0xC3CB, 0x76DF, 0xC3CC, 0x9530, 0xC3CD, 0x731B, + 0xC3CE, 0x68A6, 0xC3CF, 0x5B5F, 0xC3D0, 0x772F, 0xC3D1, 0x919A, + 0xC3D2, 0x9761, 0xC3D3, 0x7CDC, 0xC3D4, 0x8FF7, 0xC3D5, 0x8C1C, + 0xC3D6, 0x5F25, 0xC3D7, 0x7C73, 0xC3D8, 0x79D8, 0xC3D9, 0x89C5, + 0xC3DA, 0x6CCC, 0xC3DB, 0x871C, 0xC3DC, 0x5BC6, 0xC3DD, 0x5E42, + 0xC3DE, 0x68C9, 0xC3DF, 0x7720, 0xC3E0, 0x7EF5, 0xC3E1, 0x5195, + 0xC3E2, 0x514D, 0xC3E3, 0x52C9, 0xC3E4, 0x5A29, 0xC3E5, 0x7F05, + 0xC3E6, 0x9762, 0xC3E7, 0x82D7, 0xC3E8, 0x63CF, 0xC3E9, 0x7784, + 0xC3EA, 0x85D0, 0xC3EB, 0x79D2, 0xC3EC, 0x6E3A, 0xC3ED, 0x5E99, + 0xC3EE, 0x5999, 0xC3EF, 0x8511, 0xC3F0, 0x706D, 0xC3F1, 0x6C11, + 0xC3F2, 0x62BF, 0xC3F3, 0x76BF, 0xC3F4, 0x654F, 0xC3F5, 0x60AF, + 0xC3F6, 0x95FD, 0xC3F7, 0x660E, 0xC3F8, 0x879F, 0xC3F9, 0x9E23, + 0xC3FA, 0x94ED, 0xC3FB, 0x540D, 0xC3FC, 0x547D, 0xC3FD, 0x8C2C, + 0xC3FE, 0x6478, 0xC440, 0x8140, 0xC441, 0x8141, 0xC442, 0x8142, + 0xC443, 0x8143, 0xC444, 0x8144, 0xC445, 0x8145, 0xC446, 0x8147, + 0xC447, 0x8149, 0xC448, 0x814D, 0xC449, 0x814E, 0xC44A, 0x814F, + 0xC44B, 0x8152, 0xC44C, 0x8156, 0xC44D, 0x8157, 0xC44E, 0x8158, + 0xC44F, 0x815B, 0xC450, 0x815C, 0xC451, 0x815D, 0xC452, 0x815E, + 0xC453, 0x815F, 0xC454, 0x8161, 0xC455, 0x8162, 0xC456, 0x8163, + 0xC457, 0x8164, 0xC458, 0x8166, 0xC459, 0x8168, 0xC45A, 0x816A, + 0xC45B, 0x816B, 0xC45C, 0x816C, 0xC45D, 0x816F, 0xC45E, 0x8172, + 0xC45F, 0x8173, 0xC460, 0x8175, 0xC461, 0x8176, 0xC462, 0x8177, + 0xC463, 0x8178, 0xC464, 0x8181, 0xC465, 0x8183, 0xC466, 0x8184, + 0xC467, 0x8185, 0xC468, 0x8186, 0xC469, 0x8187, 0xC46A, 0x8189, + 0xC46B, 0x818B, 0xC46C, 0x818C, 0xC46D, 0x818D, 0xC46E, 0x818E, + 0xC46F, 0x8190, 0xC470, 0x8192, 0xC471, 0x8193, 0xC472, 0x8194, + 0xC473, 0x8195, 0xC474, 0x8196, 0xC475, 0x8197, 0xC476, 0x8199, + 0xC477, 0x819A, 0xC478, 0x819E, 0xC479, 0x819F, 0xC47A, 0x81A0, + 0xC47B, 0x81A1, 0xC47C, 0x81A2, 0xC47D, 0x81A4, 0xC47E, 0x81A5, + 0xC480, 0x81A7, 0xC481, 0x81A9, 0xC482, 0x81AB, 0xC483, 0x81AC, + 0xC484, 0x81AD, 0xC485, 0x81AE, 0xC486, 0x81AF, 0xC487, 0x81B0, + 0xC488, 0x81B1, 0xC489, 0x81B2, 0xC48A, 0x81B4, 0xC48B, 0x81B5, + 0xC48C, 0x81B6, 0xC48D, 0x81B7, 0xC48E, 0x81B8, 0xC48F, 0x81B9, + 0xC490, 0x81BC, 0xC491, 0x81BD, 0xC492, 0x81BE, 0xC493, 0x81BF, + 0xC494, 0x81C4, 0xC495, 0x81C5, 0xC496, 0x81C7, 0xC497, 0x81C8, + 0xC498, 0x81C9, 0xC499, 0x81CB, 0xC49A, 0x81CD, 0xC49B, 0x81CE, + 0xC49C, 0x81CF, 0xC49D, 0x81D0, 0xC49E, 0x81D1, 0xC49F, 0x81D2, + 0xC4A0, 0x81D3, 0xC4A1, 0x6479, 0xC4A2, 0x8611, 0xC4A3, 0x6A21, + 0xC4A4, 0x819C, 0xC4A5, 0x78E8, 0xC4A6, 0x6469, 0xC4A7, 0x9B54, + 0xC4A8, 0x62B9, 0xC4A9, 0x672B, 0xC4AA, 0x83AB, 0xC4AB, 0x58A8, + 0xC4AC, 0x9ED8, 0xC4AD, 0x6CAB, 0xC4AE, 0x6F20, 0xC4AF, 0x5BDE, + 0xC4B0, 0x964C, 0xC4B1, 0x8C0B, 0xC4B2, 0x725F, 0xC4B3, 0x67D0, + 0xC4B4, 0x62C7, 0xC4B5, 0x7261, 0xC4B6, 0x4EA9, 0xC4B7, 0x59C6, + 0xC4B8, 0x6BCD, 0xC4B9, 0x5893, 0xC4BA, 0x66AE, 0xC4BB, 0x5E55, + 0xC4BC, 0x52DF, 0xC4BD, 0x6155, 0xC4BE, 0x6728, 0xC4BF, 0x76EE, + 0xC4C0, 0x7766, 0xC4C1, 0x7267, 0xC4C2, 0x7A46, 0xC4C3, 0x62FF, + 0xC4C4, 0x54EA, 0xC4C5, 0x5450, 0xC4C6, 0x94A0, 0xC4C7, 0x90A3, + 0xC4C8, 0x5A1C, 0xC4C9, 0x7EB3, 0xC4CA, 0x6C16, 0xC4CB, 0x4E43, + 0xC4CC, 0x5976, 0xC4CD, 0x8010, 0xC4CE, 0x5948, 0xC4CF, 0x5357, + 0xC4D0, 0x7537, 0xC4D1, 0x96BE, 0xC4D2, 0x56CA, 0xC4D3, 0x6320, + 0xC4D4, 0x8111, 0xC4D5, 0x607C, 0xC4D6, 0x95F9, 0xC4D7, 0x6DD6, + 0xC4D8, 0x5462, 0xC4D9, 0x9981, 0xC4DA, 0x5185, 0xC4DB, 0x5AE9, + 0xC4DC, 0x80FD, 0xC4DD, 0x59AE, 0xC4DE, 0x9713, 0xC4DF, 0x502A, + 0xC4E0, 0x6CE5, 0xC4E1, 0x5C3C, 0xC4E2, 0x62DF, 0xC4E3, 0x4F60, + 0xC4E4, 0x533F, 0xC4E5, 0x817B, 0xC4E6, 0x9006, 0xC4E7, 0x6EBA, + 0xC4E8, 0x852B, 0xC4E9, 0x62C8, 0xC4EA, 0x5E74, 0xC4EB, 0x78BE, + 0xC4EC, 0x64B5, 0xC4ED, 0x637B, 0xC4EE, 0x5FF5, 0xC4EF, 0x5A18, + 0xC4F0, 0x917F, 0xC4F1, 0x9E1F, 0xC4F2, 0x5C3F, 0xC4F3, 0x634F, + 0xC4F4, 0x8042, 0xC4F5, 0x5B7D, 0xC4F6, 0x556E, 0xC4F7, 0x954A, + 0xC4F8, 0x954D, 0xC4F9, 0x6D85, 0xC4FA, 0x60A8, 0xC4FB, 0x67E0, + 0xC4FC, 0x72DE, 0xC4FD, 0x51DD, 0xC4FE, 0x5B81, 0xC540, 0x81D4, + 0xC541, 0x81D5, 0xC542, 0x81D6, 0xC543, 0x81D7, 0xC544, 0x81D8, + 0xC545, 0x81D9, 0xC546, 0x81DA, 0xC547, 0x81DB, 0xC548, 0x81DC, + 0xC549, 0x81DD, 0xC54A, 0x81DE, 0xC54B, 0x81DF, 0xC54C, 0x81E0, + 0xC54D, 0x81E1, 0xC54E, 0x81E2, 0xC54F, 0x81E4, 0xC550, 0x81E5, + 0xC551, 0x81E6, 0xC552, 0x81E8, 0xC553, 0x81E9, 0xC554, 0x81EB, + 0xC555, 0x81EE, 0xC556, 0x81EF, 0xC557, 0x81F0, 0xC558, 0x81F1, + 0xC559, 0x81F2, 0xC55A, 0x81F5, 0xC55B, 0x81F6, 0xC55C, 0x81F7, + 0xC55D, 0x81F8, 0xC55E, 0x81F9, 0xC55F, 0x81FA, 0xC560, 0x81FD, + 0xC561, 0x81FF, 0xC562, 0x8203, 0xC563, 0x8207, 0xC564, 0x8208, + 0xC565, 0x8209, 0xC566, 0x820A, 0xC567, 0x820B, 0xC568, 0x820E, + 0xC569, 0x820F, 0xC56A, 0x8211, 0xC56B, 0x8213, 0xC56C, 0x8215, + 0xC56D, 0x8216, 0xC56E, 0x8217, 0xC56F, 0x8218, 0xC570, 0x8219, + 0xC571, 0x821A, 0xC572, 0x821D, 0xC573, 0x8220, 0xC574, 0x8224, + 0xC575, 0x8225, 0xC576, 0x8226, 0xC577, 0x8227, 0xC578, 0x8229, + 0xC579, 0x822E, 0xC57A, 0x8232, 0xC57B, 0x823A, 0xC57C, 0x823C, + 0xC57D, 0x823D, 0xC57E, 0x823F, 0xC580, 0x8240, 0xC581, 0x8241, + 0xC582, 0x8242, 0xC583, 0x8243, 0xC584, 0x8245, 0xC585, 0x8246, + 0xC586, 0x8248, 0xC587, 0x824A, 0xC588, 0x824C, 0xC589, 0x824D, + 0xC58A, 0x824E, 0xC58B, 0x8250, 0xC58C, 0x8251, 0xC58D, 0x8252, + 0xC58E, 0x8253, 0xC58F, 0x8254, 0xC590, 0x8255, 0xC591, 0x8256, + 0xC592, 0x8257, 0xC593, 0x8259, 0xC594, 0x825B, 0xC595, 0x825C, + 0xC596, 0x825D, 0xC597, 0x825E, 0xC598, 0x8260, 0xC599, 0x8261, + 0xC59A, 0x8262, 0xC59B, 0x8263, 0xC59C, 0x8264, 0xC59D, 0x8265, + 0xC59E, 0x8266, 0xC59F, 0x8267, 0xC5A0, 0x8269, 0xC5A1, 0x62E7, + 0xC5A2, 0x6CDE, 0xC5A3, 0x725B, 0xC5A4, 0x626D, 0xC5A5, 0x94AE, + 0xC5A6, 0x7EBD, 0xC5A7, 0x8113, 0xC5A8, 0x6D53, 0xC5A9, 0x519C, + 0xC5AA, 0x5F04, 0xC5AB, 0x5974, 0xC5AC, 0x52AA, 0xC5AD, 0x6012, + 0xC5AE, 0x5973, 0xC5AF, 0x6696, 0xC5B0, 0x8650, 0xC5B1, 0x759F, + 0xC5B2, 0x632A, 0xC5B3, 0x61E6, 0xC5B4, 0x7CEF, 0xC5B5, 0x8BFA, + 0xC5B6, 0x54E6, 0xC5B7, 0x6B27, 0xC5B8, 0x9E25, 0xC5B9, 0x6BB4, + 0xC5BA, 0x85D5, 0xC5BB, 0x5455, 0xC5BC, 0x5076, 0xC5BD, 0x6CA4, + 0xC5BE, 0x556A, 0xC5BF, 0x8DB4, 0xC5C0, 0x722C, 0xC5C1, 0x5E15, + 0xC5C2, 0x6015, 0xC5C3, 0x7436, 0xC5C4, 0x62CD, 0xC5C5, 0x6392, + 0xC5C6, 0x724C, 0xC5C7, 0x5F98, 0xC5C8, 0x6E43, 0xC5C9, 0x6D3E, + 0xC5CA, 0x6500, 0xC5CB, 0x6F58, 0xC5CC, 0x76D8, 0xC5CD, 0x78D0, + 0xC5CE, 0x76FC, 0xC5CF, 0x7554, 0xC5D0, 0x5224, 0xC5D1, 0x53DB, + 0xC5D2, 0x4E53, 0xC5D3, 0x5E9E, 0xC5D4, 0x65C1, 0xC5D5, 0x802A, + 0xC5D6, 0x80D6, 0xC5D7, 0x629B, 0xC5D8, 0x5486, 0xC5D9, 0x5228, + 0xC5DA, 0x70AE, 0xC5DB, 0x888D, 0xC5DC, 0x8DD1, 0xC5DD, 0x6CE1, + 0xC5DE, 0x5478, 0xC5DF, 0x80DA, 0xC5E0, 0x57F9, 0xC5E1, 0x88F4, + 0xC5E2, 0x8D54, 0xC5E3, 0x966A, 0xC5E4, 0x914D, 0xC5E5, 0x4F69, + 0xC5E6, 0x6C9B, 0xC5E7, 0x55B7, 0xC5E8, 0x76C6, 0xC5E9, 0x7830, + 0xC5EA, 0x62A8, 0xC5EB, 0x70F9, 0xC5EC, 0x6F8E, 0xC5ED, 0x5F6D, + 0xC5EE, 0x84EC, 0xC5EF, 0x68DA, 0xC5F0, 0x787C, 0xC5F1, 0x7BF7, + 0xC5F2, 0x81A8, 0xC5F3, 0x670B, 0xC5F4, 0x9E4F, 0xC5F5, 0x6367, + 0xC5F6, 0x78B0, 0xC5F7, 0x576F, 0xC5F8, 0x7812, 0xC5F9, 0x9739, + 0xC5FA, 0x6279, 0xC5FB, 0x62AB, 0xC5FC, 0x5288, 0xC5FD, 0x7435, + 0xC5FE, 0x6BD7, 0xC640, 0x826A, 0xC641, 0x826B, 0xC642, 0x826C, + 0xC643, 0x826D, 0xC644, 0x8271, 0xC645, 0x8275, 0xC646, 0x8276, + 0xC647, 0x8277, 0xC648, 0x8278, 0xC649, 0x827B, 0xC64A, 0x827C, + 0xC64B, 0x8280, 0xC64C, 0x8281, 0xC64D, 0x8283, 0xC64E, 0x8285, + 0xC64F, 0x8286, 0xC650, 0x8287, 0xC651, 0x8289, 0xC652, 0x828C, + 0xC653, 0x8290, 0xC654, 0x8293, 0xC655, 0x8294, 0xC656, 0x8295, + 0xC657, 0x8296, 0xC658, 0x829A, 0xC659, 0x829B, 0xC65A, 0x829E, + 0xC65B, 0x82A0, 0xC65C, 0x82A2, 0xC65D, 0x82A3, 0xC65E, 0x82A7, + 0xC65F, 0x82B2, 0xC660, 0x82B5, 0xC661, 0x82B6, 0xC662, 0x82BA, + 0xC663, 0x82BB, 0xC664, 0x82BC, 0xC665, 0x82BF, 0xC666, 0x82C0, + 0xC667, 0x82C2, 0xC668, 0x82C3, 0xC669, 0x82C5, 0xC66A, 0x82C6, + 0xC66B, 0x82C9, 0xC66C, 0x82D0, 0xC66D, 0x82D6, 0xC66E, 0x82D9, + 0xC66F, 0x82DA, 0xC670, 0x82DD, 0xC671, 0x82E2, 0xC672, 0x82E7, + 0xC673, 0x82E8, 0xC674, 0x82E9, 0xC675, 0x82EA, 0xC676, 0x82EC, + 0xC677, 0x82ED, 0xC678, 0x82EE, 0xC679, 0x82F0, 0xC67A, 0x82F2, + 0xC67B, 0x82F3, 0xC67C, 0x82F5, 0xC67D, 0x82F6, 0xC67E, 0x82F8, + 0xC680, 0x82FA, 0xC681, 0x82FC, 0xC682, 0x82FD, 0xC683, 0x82FE, + 0xC684, 0x82FF, 0xC685, 0x8300, 0xC686, 0x830A, 0xC687, 0x830B, + 0xC688, 0x830D, 0xC689, 0x8310, 0xC68A, 0x8312, 0xC68B, 0x8313, + 0xC68C, 0x8316, 0xC68D, 0x8318, 0xC68E, 0x8319, 0xC68F, 0x831D, + 0xC690, 0x831E, 0xC691, 0x831F, 0xC692, 0x8320, 0xC693, 0x8321, + 0xC694, 0x8322, 0xC695, 0x8323, 0xC696, 0x8324, 0xC697, 0x8325, + 0xC698, 0x8326, 0xC699, 0x8329, 0xC69A, 0x832A, 0xC69B, 0x832E, + 0xC69C, 0x8330, 0xC69D, 0x8332, 0xC69E, 0x8337, 0xC69F, 0x833B, + 0xC6A0, 0x833D, 0xC6A1, 0x5564, 0xC6A2, 0x813E, 0xC6A3, 0x75B2, + 0xC6A4, 0x76AE, 0xC6A5, 0x5339, 0xC6A6, 0x75DE, 0xC6A7, 0x50FB, + 0xC6A8, 0x5C41, 0xC6A9, 0x8B6C, 0xC6AA, 0x7BC7, 0xC6AB, 0x504F, + 0xC6AC, 0x7247, 0xC6AD, 0x9A97, 0xC6AE, 0x98D8, 0xC6AF, 0x6F02, + 0xC6B0, 0x74E2, 0xC6B1, 0x7968, 0xC6B2, 0x6487, 0xC6B3, 0x77A5, + 0xC6B4, 0x62FC, 0xC6B5, 0x9891, 0xC6B6, 0x8D2B, 0xC6B7, 0x54C1, + 0xC6B8, 0x8058, 0xC6B9, 0x4E52, 0xC6BA, 0x576A, 0xC6BB, 0x82F9, + 0xC6BC, 0x840D, 0xC6BD, 0x5E73, 0xC6BE, 0x51ED, 0xC6BF, 0x74F6, + 0xC6C0, 0x8BC4, 0xC6C1, 0x5C4F, 0xC6C2, 0x5761, 0xC6C3, 0x6CFC, + 0xC6C4, 0x9887, 0xC6C5, 0x5A46, 0xC6C6, 0x7834, 0xC6C7, 0x9B44, + 0xC6C8, 0x8FEB, 0xC6C9, 0x7C95, 0xC6CA, 0x5256, 0xC6CB, 0x6251, + 0xC6CC, 0x94FA, 0xC6CD, 0x4EC6, 0xC6CE, 0x8386, 0xC6CF, 0x8461, + 0xC6D0, 0x83E9, 0xC6D1, 0x84B2, 0xC6D2, 0x57D4, 0xC6D3, 0x6734, + 0xC6D4, 0x5703, 0xC6D5, 0x666E, 0xC6D6, 0x6D66, 0xC6D7, 0x8C31, + 0xC6D8, 0x66DD, 0xC6D9, 0x7011, 0xC6DA, 0x671F, 0xC6DB, 0x6B3A, + 0xC6DC, 0x6816, 0xC6DD, 0x621A, 0xC6DE, 0x59BB, 0xC6DF, 0x4E03, + 0xC6E0, 0x51C4, 0xC6E1, 0x6F06, 0xC6E2, 0x67D2, 0xC6E3, 0x6C8F, + 0xC6E4, 0x5176, 0xC6E5, 0x68CB, 0xC6E6, 0x5947, 0xC6E7, 0x6B67, + 0xC6E8, 0x7566, 0xC6E9, 0x5D0E, 0xC6EA, 0x8110, 0xC6EB, 0x9F50, + 0xC6EC, 0x65D7, 0xC6ED, 0x7948, 0xC6EE, 0x7941, 0xC6EF, 0x9A91, + 0xC6F0, 0x8D77, 0xC6F1, 0x5C82, 0xC6F2, 0x4E5E, 0xC6F3, 0x4F01, + 0xC6F4, 0x542F, 0xC6F5, 0x5951, 0xC6F6, 0x780C, 0xC6F7, 0x5668, + 0xC6F8, 0x6C14, 0xC6F9, 0x8FC4, 0xC6FA, 0x5F03, 0xC6FB, 0x6C7D, + 0xC6FC, 0x6CE3, 0xC6FD, 0x8BAB, 0xC6FE, 0x6390, 0xC740, 0x833E, + 0xC741, 0x833F, 0xC742, 0x8341, 0xC743, 0x8342, 0xC744, 0x8344, + 0xC745, 0x8345, 0xC746, 0x8348, 0xC747, 0x834A, 0xC748, 0x834B, + 0xC749, 0x834C, 0xC74A, 0x834D, 0xC74B, 0x834E, 0xC74C, 0x8353, + 0xC74D, 0x8355, 0xC74E, 0x8356, 0xC74F, 0x8357, 0xC750, 0x8358, + 0xC751, 0x8359, 0xC752, 0x835D, 0xC753, 0x8362, 0xC754, 0x8370, + 0xC755, 0x8371, 0xC756, 0x8372, 0xC757, 0x8373, 0xC758, 0x8374, + 0xC759, 0x8375, 0xC75A, 0x8376, 0xC75B, 0x8379, 0xC75C, 0x837A, + 0xC75D, 0x837E, 0xC75E, 0x837F, 0xC75F, 0x8380, 0xC760, 0x8381, + 0xC761, 0x8382, 0xC762, 0x8383, 0xC763, 0x8384, 0xC764, 0x8387, + 0xC765, 0x8388, 0xC766, 0x838A, 0xC767, 0x838B, 0xC768, 0x838C, + 0xC769, 0x838D, 0xC76A, 0x838F, 0xC76B, 0x8390, 0xC76C, 0x8391, + 0xC76D, 0x8394, 0xC76E, 0x8395, 0xC76F, 0x8396, 0xC770, 0x8397, + 0xC771, 0x8399, 0xC772, 0x839A, 0xC773, 0x839D, 0xC774, 0x839F, + 0xC775, 0x83A1, 0xC776, 0x83A2, 0xC777, 0x83A3, 0xC778, 0x83A4, + 0xC779, 0x83A5, 0xC77A, 0x83A6, 0xC77B, 0x83A7, 0xC77C, 0x83AC, + 0xC77D, 0x83AD, 0xC77E, 0x83AE, 0xC780, 0x83AF, 0xC781, 0x83B5, + 0xC782, 0x83BB, 0xC783, 0x83BE, 0xC784, 0x83BF, 0xC785, 0x83C2, + 0xC786, 0x83C3, 0xC787, 0x83C4, 0xC788, 0x83C6, 0xC789, 0x83C8, + 0xC78A, 0x83C9, 0xC78B, 0x83CB, 0xC78C, 0x83CD, 0xC78D, 0x83CE, + 0xC78E, 0x83D0, 0xC78F, 0x83D1, 0xC790, 0x83D2, 0xC791, 0x83D3, + 0xC792, 0x83D5, 0xC793, 0x83D7, 0xC794, 0x83D9, 0xC795, 0x83DA, + 0xC796, 0x83DB, 0xC797, 0x83DE, 0xC798, 0x83E2, 0xC799, 0x83E3, + 0xC79A, 0x83E4, 0xC79B, 0x83E6, 0xC79C, 0x83E7, 0xC79D, 0x83E8, + 0xC79E, 0x83EB, 0xC79F, 0x83EC, 0xC7A0, 0x83ED, 0xC7A1, 0x6070, + 0xC7A2, 0x6D3D, 0xC7A3, 0x7275, 0xC7A4, 0x6266, 0xC7A5, 0x948E, + 0xC7A6, 0x94C5, 0xC7A7, 0x5343, 0xC7A8, 0x8FC1, 0xC7A9, 0x7B7E, + 0xC7AA, 0x4EDF, 0xC7AB, 0x8C26, 0xC7AC, 0x4E7E, 0xC7AD, 0x9ED4, + 0xC7AE, 0x94B1, 0xC7AF, 0x94B3, 0xC7B0, 0x524D, 0xC7B1, 0x6F5C, + 0xC7B2, 0x9063, 0xC7B3, 0x6D45, 0xC7B4, 0x8C34, 0xC7B5, 0x5811, + 0xC7B6, 0x5D4C, 0xC7B7, 0x6B20, 0xC7B8, 0x6B49, 0xC7B9, 0x67AA, + 0xC7BA, 0x545B, 0xC7BB, 0x8154, 0xC7BC, 0x7F8C, 0xC7BD, 0x5899, + 0xC7BE, 0x8537, 0xC7BF, 0x5F3A, 0xC7C0, 0x62A2, 0xC7C1, 0x6A47, + 0xC7C2, 0x9539, 0xC7C3, 0x6572, 0xC7C4, 0x6084, 0xC7C5, 0x6865, + 0xC7C6, 0x77A7, 0xC7C7, 0x4E54, 0xC7C8, 0x4FA8, 0xC7C9, 0x5DE7, + 0xC7CA, 0x9798, 0xC7CB, 0x64AC, 0xC7CC, 0x7FD8, 0xC7CD, 0x5CED, + 0xC7CE, 0x4FCF, 0xC7CF, 0x7A8D, 0xC7D0, 0x5207, 0xC7D1, 0x8304, + 0xC7D2, 0x4E14, 0xC7D3, 0x602F, 0xC7D4, 0x7A83, 0xC7D5, 0x94A6, + 0xC7D6, 0x4FB5, 0xC7D7, 0x4EB2, 0xC7D8, 0x79E6, 0xC7D9, 0x7434, + 0xC7DA, 0x52E4, 0xC7DB, 0x82B9, 0xC7DC, 0x64D2, 0xC7DD, 0x79BD, + 0xC7DE, 0x5BDD, 0xC7DF, 0x6C81, 0xC7E0, 0x9752, 0xC7E1, 0x8F7B, + 0xC7E2, 0x6C22, 0xC7E3, 0x503E, 0xC7E4, 0x537F, 0xC7E5, 0x6E05, + 0xC7E6, 0x64CE, 0xC7E7, 0x6674, 0xC7E8, 0x6C30, 0xC7E9, 0x60C5, + 0xC7EA, 0x9877, 0xC7EB, 0x8BF7, 0xC7EC, 0x5E86, 0xC7ED, 0x743C, + 0xC7EE, 0x7A77, 0xC7EF, 0x79CB, 0xC7F0, 0x4E18, 0xC7F1, 0x90B1, + 0xC7F2, 0x7403, 0xC7F3, 0x6C42, 0xC7F4, 0x56DA, 0xC7F5, 0x914B, + 0xC7F6, 0x6CC5, 0xC7F7, 0x8D8B, 0xC7F8, 0x533A, 0xC7F9, 0x86C6, + 0xC7FA, 0x66F2, 0xC7FB, 0x8EAF, 0xC7FC, 0x5C48, 0xC7FD, 0x9A71, + 0xC7FE, 0x6E20, 0xC840, 0x83EE, 0xC841, 0x83EF, 0xC842, 0x83F3, + 0xC843, 0x83F4, 0xC844, 0x83F5, 0xC845, 0x83F6, 0xC846, 0x83F7, + 0xC847, 0x83FA, 0xC848, 0x83FB, 0xC849, 0x83FC, 0xC84A, 0x83FE, + 0xC84B, 0x83FF, 0xC84C, 0x8400, 0xC84D, 0x8402, 0xC84E, 0x8405, + 0xC84F, 0x8407, 0xC850, 0x8408, 0xC851, 0x8409, 0xC852, 0x840A, + 0xC853, 0x8410, 0xC854, 0x8412, 0xC855, 0x8413, 0xC856, 0x8414, + 0xC857, 0x8415, 0xC858, 0x8416, 0xC859, 0x8417, 0xC85A, 0x8419, + 0xC85B, 0x841A, 0xC85C, 0x841B, 0xC85D, 0x841E, 0xC85E, 0x841F, + 0xC85F, 0x8420, 0xC860, 0x8421, 0xC861, 0x8422, 0xC862, 0x8423, + 0xC863, 0x8429, 0xC864, 0x842A, 0xC865, 0x842B, 0xC866, 0x842C, + 0xC867, 0x842D, 0xC868, 0x842E, 0xC869, 0x842F, 0xC86A, 0x8430, + 0xC86B, 0x8432, 0xC86C, 0x8433, 0xC86D, 0x8434, 0xC86E, 0x8435, + 0xC86F, 0x8436, 0xC870, 0x8437, 0xC871, 0x8439, 0xC872, 0x843A, + 0xC873, 0x843B, 0xC874, 0x843E, 0xC875, 0x843F, 0xC876, 0x8440, + 0xC877, 0x8441, 0xC878, 0x8442, 0xC879, 0x8443, 0xC87A, 0x8444, + 0xC87B, 0x8445, 0xC87C, 0x8447, 0xC87D, 0x8448, 0xC87E, 0x8449, + 0xC880, 0x844A, 0xC881, 0x844B, 0xC882, 0x844C, 0xC883, 0x844D, + 0xC884, 0x844E, 0xC885, 0x844F, 0xC886, 0x8450, 0xC887, 0x8452, + 0xC888, 0x8453, 0xC889, 0x8454, 0xC88A, 0x8455, 0xC88B, 0x8456, + 0xC88C, 0x8458, 0xC88D, 0x845D, 0xC88E, 0x845E, 0xC88F, 0x845F, + 0xC890, 0x8460, 0xC891, 0x8462, 0xC892, 0x8464, 0xC893, 0x8465, + 0xC894, 0x8466, 0xC895, 0x8467, 0xC896, 0x8468, 0xC897, 0x846A, + 0xC898, 0x846E, 0xC899, 0x846F, 0xC89A, 0x8470, 0xC89B, 0x8472, + 0xC89C, 0x8474, 0xC89D, 0x8477, 0xC89E, 0x8479, 0xC89F, 0x847B, + 0xC8A0, 0x847C, 0xC8A1, 0x53D6, 0xC8A2, 0x5A36, 0xC8A3, 0x9F8B, + 0xC8A4, 0x8DA3, 0xC8A5, 0x53BB, 0xC8A6, 0x5708, 0xC8A7, 0x98A7, + 0xC8A8, 0x6743, 0xC8A9, 0x919B, 0xC8AA, 0x6CC9, 0xC8AB, 0x5168, + 0xC8AC, 0x75CA, 0xC8AD, 0x62F3, 0xC8AE, 0x72AC, 0xC8AF, 0x5238, + 0xC8B0, 0x529D, 0xC8B1, 0x7F3A, 0xC8B2, 0x7094, 0xC8B3, 0x7638, + 0xC8B4, 0x5374, 0xC8B5, 0x9E4A, 0xC8B6, 0x69B7, 0xC8B7, 0x786E, + 0xC8B8, 0x96C0, 0xC8B9, 0x88D9, 0xC8BA, 0x7FA4, 0xC8BB, 0x7136, + 0xC8BC, 0x71C3, 0xC8BD, 0x5189, 0xC8BE, 0x67D3, 0xC8BF, 0x74E4, + 0xC8C0, 0x58E4, 0xC8C1, 0x6518, 0xC8C2, 0x56B7, 0xC8C3, 0x8BA9, + 0xC8C4, 0x9976, 0xC8C5, 0x6270, 0xC8C6, 0x7ED5, 0xC8C7, 0x60F9, + 0xC8C8, 0x70ED, 0xC8C9, 0x58EC, 0xC8CA, 0x4EC1, 0xC8CB, 0x4EBA, + 0xC8CC, 0x5FCD, 0xC8CD, 0x97E7, 0xC8CE, 0x4EFB, 0xC8CF, 0x8BA4, + 0xC8D0, 0x5203, 0xC8D1, 0x598A, 0xC8D2, 0x7EAB, 0xC8D3, 0x6254, + 0xC8D4, 0x4ECD, 0xC8D5, 0x65E5, 0xC8D6, 0x620E, 0xC8D7, 0x8338, + 0xC8D8, 0x84C9, 0xC8D9, 0x8363, 0xC8DA, 0x878D, 0xC8DB, 0x7194, + 0xC8DC, 0x6EB6, 0xC8DD, 0x5BB9, 0xC8DE, 0x7ED2, 0xC8DF, 0x5197, + 0xC8E0, 0x63C9, 0xC8E1, 0x67D4, 0xC8E2, 0x8089, 0xC8E3, 0x8339, + 0xC8E4, 0x8815, 0xC8E5, 0x5112, 0xC8E6, 0x5B7A, 0xC8E7, 0x5982, + 0xC8E8, 0x8FB1, 0xC8E9, 0x4E73, 0xC8EA, 0x6C5D, 0xC8EB, 0x5165, + 0xC8EC, 0x8925, 0xC8ED, 0x8F6F, 0xC8EE, 0x962E, 0xC8EF, 0x854A, + 0xC8F0, 0x745E, 0xC8F1, 0x9510, 0xC8F2, 0x95F0, 0xC8F3, 0x6DA6, + 0xC8F4, 0x82E5, 0xC8F5, 0x5F31, 0xC8F6, 0x6492, 0xC8F7, 0x6D12, + 0xC8F8, 0x8428, 0xC8F9, 0x816E, 0xC8FA, 0x9CC3, 0xC8FB, 0x585E, + 0xC8FC, 0x8D5B, 0xC8FD, 0x4E09, 0xC8FE, 0x53C1, 0xC940, 0x847D, + 0xC941, 0x847E, 0xC942, 0x847F, 0xC943, 0x8480, 0xC944, 0x8481, + 0xC945, 0x8483, 0xC946, 0x8484, 0xC947, 0x8485, 0xC948, 0x8486, + 0xC949, 0x848A, 0xC94A, 0x848D, 0xC94B, 0x848F, 0xC94C, 0x8490, + 0xC94D, 0x8491, 0xC94E, 0x8492, 0xC94F, 0x8493, 0xC950, 0x8494, + 0xC951, 0x8495, 0xC952, 0x8496, 0xC953, 0x8498, 0xC954, 0x849A, + 0xC955, 0x849B, 0xC956, 0x849D, 0xC957, 0x849E, 0xC958, 0x849F, + 0xC959, 0x84A0, 0xC95A, 0x84A2, 0xC95B, 0x84A3, 0xC95C, 0x84A4, + 0xC95D, 0x84A5, 0xC95E, 0x84A6, 0xC95F, 0x84A7, 0xC960, 0x84A8, + 0xC961, 0x84A9, 0xC962, 0x84AA, 0xC963, 0x84AB, 0xC964, 0x84AC, + 0xC965, 0x84AD, 0xC966, 0x84AE, 0xC967, 0x84B0, 0xC968, 0x84B1, + 0xC969, 0x84B3, 0xC96A, 0x84B5, 0xC96B, 0x84B6, 0xC96C, 0x84B7, + 0xC96D, 0x84BB, 0xC96E, 0x84BC, 0xC96F, 0x84BE, 0xC970, 0x84C0, + 0xC971, 0x84C2, 0xC972, 0x84C3, 0xC973, 0x84C5, 0xC974, 0x84C6, + 0xC975, 0x84C7, 0xC976, 0x84C8, 0xC977, 0x84CB, 0xC978, 0x84CC, + 0xC979, 0x84CE, 0xC97A, 0x84CF, 0xC97B, 0x84D2, 0xC97C, 0x84D4, + 0xC97D, 0x84D5, 0xC97E, 0x84D7, 0xC980, 0x84D8, 0xC981, 0x84D9, + 0xC982, 0x84DA, 0xC983, 0x84DB, 0xC984, 0x84DC, 0xC985, 0x84DE, + 0xC986, 0x84E1, 0xC987, 0x84E2, 0xC988, 0x84E4, 0xC989, 0x84E7, + 0xC98A, 0x84E8, 0xC98B, 0x84E9, 0xC98C, 0x84EA, 0xC98D, 0x84EB, + 0xC98E, 0x84ED, 0xC98F, 0x84EE, 0xC990, 0x84EF, 0xC991, 0x84F1, + 0xC992, 0x84F2, 0xC993, 0x84F3, 0xC994, 0x84F4, 0xC995, 0x84F5, + 0xC996, 0x84F6, 0xC997, 0x84F7, 0xC998, 0x84F8, 0xC999, 0x84F9, + 0xC99A, 0x84FA, 0xC99B, 0x84FB, 0xC99C, 0x84FD, 0xC99D, 0x84FE, + 0xC99E, 0x8500, 0xC99F, 0x8501, 0xC9A0, 0x8502, 0xC9A1, 0x4F1E, + 0xC9A2, 0x6563, 0xC9A3, 0x6851, 0xC9A4, 0x55D3, 0xC9A5, 0x4E27, + 0xC9A6, 0x6414, 0xC9A7, 0x9A9A, 0xC9A8, 0x626B, 0xC9A9, 0x5AC2, + 0xC9AA, 0x745F, 0xC9AB, 0x8272, 0xC9AC, 0x6DA9, 0xC9AD, 0x68EE, + 0xC9AE, 0x50E7, 0xC9AF, 0x838E, 0xC9B0, 0x7802, 0xC9B1, 0x6740, + 0xC9B2, 0x5239, 0xC9B3, 0x6C99, 0xC9B4, 0x7EB1, 0xC9B5, 0x50BB, + 0xC9B6, 0x5565, 0xC9B7, 0x715E, 0xC9B8, 0x7B5B, 0xC9B9, 0x6652, + 0xC9BA, 0x73CA, 0xC9BB, 0x82EB, 0xC9BC, 0x6749, 0xC9BD, 0x5C71, + 0xC9BE, 0x5220, 0xC9BF, 0x717D, 0xC9C0, 0x886B, 0xC9C1, 0x95EA, + 0xC9C2, 0x9655, 0xC9C3, 0x64C5, 0xC9C4, 0x8D61, 0xC9C5, 0x81B3, + 0xC9C6, 0x5584, 0xC9C7, 0x6C55, 0xC9C8, 0x6247, 0xC9C9, 0x7F2E, + 0xC9CA, 0x5892, 0xC9CB, 0x4F24, 0xC9CC, 0x5546, 0xC9CD, 0x8D4F, + 0xC9CE, 0x664C, 0xC9CF, 0x4E0A, 0xC9D0, 0x5C1A, 0xC9D1, 0x88F3, + 0xC9D2, 0x68A2, 0xC9D3, 0x634E, 0xC9D4, 0x7A0D, 0xC9D5, 0x70E7, + 0xC9D6, 0x828D, 0xC9D7, 0x52FA, 0xC9D8, 0x97F6, 0xC9D9, 0x5C11, + 0xC9DA, 0x54E8, 0xC9DB, 0x90B5, 0xC9DC, 0x7ECD, 0xC9DD, 0x5962, + 0xC9DE, 0x8D4A, 0xC9DF, 0x86C7, 0xC9E0, 0x820C, 0xC9E1, 0x820D, + 0xC9E2, 0x8D66, 0xC9E3, 0x6444, 0xC9E4, 0x5C04, 0xC9E5, 0x6151, + 0xC9E6, 0x6D89, 0xC9E7, 0x793E, 0xC9E8, 0x8BBE, 0xC9E9, 0x7837, + 0xC9EA, 0x7533, 0xC9EB, 0x547B, 0xC9EC, 0x4F38, 0xC9ED, 0x8EAB, + 0xC9EE, 0x6DF1, 0xC9EF, 0x5A20, 0xC9F0, 0x7EC5, 0xC9F1, 0x795E, + 0xC9F2, 0x6C88, 0xC9F3, 0x5BA1, 0xC9F4, 0x5A76, 0xC9F5, 0x751A, + 0xC9F6, 0x80BE, 0xC9F7, 0x614E, 0xC9F8, 0x6E17, 0xC9F9, 0x58F0, + 0xC9FA, 0x751F, 0xC9FB, 0x7525, 0xC9FC, 0x7272, 0xC9FD, 0x5347, + 0xC9FE, 0x7EF3, 0xCA40, 0x8503, 0xCA41, 0x8504, 0xCA42, 0x8505, + 0xCA43, 0x8506, 0xCA44, 0x8507, 0xCA45, 0x8508, 0xCA46, 0x8509, + 0xCA47, 0x850A, 0xCA48, 0x850B, 0xCA49, 0x850D, 0xCA4A, 0x850E, + 0xCA4B, 0x850F, 0xCA4C, 0x8510, 0xCA4D, 0x8512, 0xCA4E, 0x8514, + 0xCA4F, 0x8515, 0xCA50, 0x8516, 0xCA51, 0x8518, 0xCA52, 0x8519, + 0xCA53, 0x851B, 0xCA54, 0x851C, 0xCA55, 0x851D, 0xCA56, 0x851E, + 0xCA57, 0x8520, 0xCA58, 0x8522, 0xCA59, 0x8523, 0xCA5A, 0x8524, + 0xCA5B, 0x8525, 0xCA5C, 0x8526, 0xCA5D, 0x8527, 0xCA5E, 0x8528, + 0xCA5F, 0x8529, 0xCA60, 0x852A, 0xCA61, 0x852D, 0xCA62, 0x852E, + 0xCA63, 0x852F, 0xCA64, 0x8530, 0xCA65, 0x8531, 0xCA66, 0x8532, + 0xCA67, 0x8533, 0xCA68, 0x8534, 0xCA69, 0x8535, 0xCA6A, 0x8536, + 0xCA6B, 0x853E, 0xCA6C, 0x853F, 0xCA6D, 0x8540, 0xCA6E, 0x8541, + 0xCA6F, 0x8542, 0xCA70, 0x8544, 0xCA71, 0x8545, 0xCA72, 0x8546, + 0xCA73, 0x8547, 0xCA74, 0x854B, 0xCA75, 0x854C, 0xCA76, 0x854D, + 0xCA77, 0x854E, 0xCA78, 0x854F, 0xCA79, 0x8550, 0xCA7A, 0x8551, + 0xCA7B, 0x8552, 0xCA7C, 0x8553, 0xCA7D, 0x8554, 0xCA7E, 0x8555, + 0xCA80, 0x8557, 0xCA81, 0x8558, 0xCA82, 0x855A, 0xCA83, 0x855B, + 0xCA84, 0x855C, 0xCA85, 0x855D, 0xCA86, 0x855F, 0xCA87, 0x8560, + 0xCA88, 0x8561, 0xCA89, 0x8562, 0xCA8A, 0x8563, 0xCA8B, 0x8565, + 0xCA8C, 0x8566, 0xCA8D, 0x8567, 0xCA8E, 0x8569, 0xCA8F, 0x856A, + 0xCA90, 0x856B, 0xCA91, 0x856C, 0xCA92, 0x856D, 0xCA93, 0x856E, + 0xCA94, 0x856F, 0xCA95, 0x8570, 0xCA96, 0x8571, 0xCA97, 0x8573, + 0xCA98, 0x8575, 0xCA99, 0x8576, 0xCA9A, 0x8577, 0xCA9B, 0x8578, + 0xCA9C, 0x857C, 0xCA9D, 0x857D, 0xCA9E, 0x857F, 0xCA9F, 0x8580, + 0xCAA0, 0x8581, 0xCAA1, 0x7701, 0xCAA2, 0x76DB, 0xCAA3, 0x5269, + 0xCAA4, 0x80DC, 0xCAA5, 0x5723, 0xCAA6, 0x5E08, 0xCAA7, 0x5931, + 0xCAA8, 0x72EE, 0xCAA9, 0x65BD, 0xCAAA, 0x6E7F, 0xCAAB, 0x8BD7, + 0xCAAC, 0x5C38, 0xCAAD, 0x8671, 0xCAAE, 0x5341, 0xCAAF, 0x77F3, + 0xCAB0, 0x62FE, 0xCAB1, 0x65F6, 0xCAB2, 0x4EC0, 0xCAB3, 0x98DF, + 0xCAB4, 0x8680, 0xCAB5, 0x5B9E, 0xCAB6, 0x8BC6, 0xCAB7, 0x53F2, + 0xCAB8, 0x77E2, 0xCAB9, 0x4F7F, 0xCABA, 0x5C4E, 0xCABB, 0x9A76, + 0xCABC, 0x59CB, 0xCABD, 0x5F0F, 0xCABE, 0x793A, 0xCABF, 0x58EB, + 0xCAC0, 0x4E16, 0xCAC1, 0x67FF, 0xCAC2, 0x4E8B, 0xCAC3, 0x62ED, + 0xCAC4, 0x8A93, 0xCAC5, 0x901D, 0xCAC6, 0x52BF, 0xCAC7, 0x662F, + 0xCAC8, 0x55DC, 0xCAC9, 0x566C, 0xCACA, 0x9002, 0xCACB, 0x4ED5, + 0xCACC, 0x4F8D, 0xCACD, 0x91CA, 0xCACE, 0x9970, 0xCACF, 0x6C0F, + 0xCAD0, 0x5E02, 0xCAD1, 0x6043, 0xCAD2, 0x5BA4, 0xCAD3, 0x89C6, + 0xCAD4, 0x8BD5, 0xCAD5, 0x6536, 0xCAD6, 0x624B, 0xCAD7, 0x9996, + 0xCAD8, 0x5B88, 0xCAD9, 0x5BFF, 0xCADA, 0x6388, 0xCADB, 0x552E, + 0xCADC, 0x53D7, 0xCADD, 0x7626, 0xCADE, 0x517D, 0xCADF, 0x852C, + 0xCAE0, 0x67A2, 0xCAE1, 0x68B3, 0xCAE2, 0x6B8A, 0xCAE3, 0x6292, + 0xCAE4, 0x8F93, 0xCAE5, 0x53D4, 0xCAE6, 0x8212, 0xCAE7, 0x6DD1, + 0xCAE8, 0x758F, 0xCAE9, 0x4E66, 0xCAEA, 0x8D4E, 0xCAEB, 0x5B70, + 0xCAEC, 0x719F, 0xCAED, 0x85AF, 0xCAEE, 0x6691, 0xCAEF, 0x66D9, + 0xCAF0, 0x7F72, 0xCAF1, 0x8700, 0xCAF2, 0x9ECD, 0xCAF3, 0x9F20, + 0xCAF4, 0x5C5E, 0xCAF5, 0x672F, 0xCAF6, 0x8FF0, 0xCAF7, 0x6811, + 0xCAF8, 0x675F, 0xCAF9, 0x620D, 0xCAFA, 0x7AD6, 0xCAFB, 0x5885, + 0xCAFC, 0x5EB6, 0xCAFD, 0x6570, 0xCAFE, 0x6F31, 0xCB40, 0x8582, + 0xCB41, 0x8583, 0xCB42, 0x8586, 0xCB43, 0x8588, 0xCB44, 0x8589, + 0xCB45, 0x858A, 0xCB46, 0x858B, 0xCB47, 0x858C, 0xCB48, 0x858D, + 0xCB49, 0x858E, 0xCB4A, 0x8590, 0xCB4B, 0x8591, 0xCB4C, 0x8592, + 0xCB4D, 0x8593, 0xCB4E, 0x8594, 0xCB4F, 0x8595, 0xCB50, 0x8596, + 0xCB51, 0x8597, 0xCB52, 0x8598, 0xCB53, 0x8599, 0xCB54, 0x859A, + 0xCB55, 0x859D, 0xCB56, 0x859E, 0xCB57, 0x859F, 0xCB58, 0x85A0, + 0xCB59, 0x85A1, 0xCB5A, 0x85A2, 0xCB5B, 0x85A3, 0xCB5C, 0x85A5, + 0xCB5D, 0x85A6, 0xCB5E, 0x85A7, 0xCB5F, 0x85A9, 0xCB60, 0x85AB, + 0xCB61, 0x85AC, 0xCB62, 0x85AD, 0xCB63, 0x85B1, 0xCB64, 0x85B2, + 0xCB65, 0x85B3, 0xCB66, 0x85B4, 0xCB67, 0x85B5, 0xCB68, 0x85B6, + 0xCB69, 0x85B8, 0xCB6A, 0x85BA, 0xCB6B, 0x85BB, 0xCB6C, 0x85BC, + 0xCB6D, 0x85BD, 0xCB6E, 0x85BE, 0xCB6F, 0x85BF, 0xCB70, 0x85C0, + 0xCB71, 0x85C2, 0xCB72, 0x85C3, 0xCB73, 0x85C4, 0xCB74, 0x85C5, + 0xCB75, 0x85C6, 0xCB76, 0x85C7, 0xCB77, 0x85C8, 0xCB78, 0x85CA, + 0xCB79, 0x85CB, 0xCB7A, 0x85CC, 0xCB7B, 0x85CD, 0xCB7C, 0x85CE, + 0xCB7D, 0x85D1, 0xCB7E, 0x85D2, 0xCB80, 0x85D4, 0xCB81, 0x85D6, + 0xCB82, 0x85D7, 0xCB83, 0x85D8, 0xCB84, 0x85D9, 0xCB85, 0x85DA, + 0xCB86, 0x85DB, 0xCB87, 0x85DD, 0xCB88, 0x85DE, 0xCB89, 0x85DF, + 0xCB8A, 0x85E0, 0xCB8B, 0x85E1, 0xCB8C, 0x85E2, 0xCB8D, 0x85E3, + 0xCB8E, 0x85E5, 0xCB8F, 0x85E6, 0xCB90, 0x85E7, 0xCB91, 0x85E8, + 0xCB92, 0x85EA, 0xCB93, 0x85EB, 0xCB94, 0x85EC, 0xCB95, 0x85ED, + 0xCB96, 0x85EE, 0xCB97, 0x85EF, 0xCB98, 0x85F0, 0xCB99, 0x85F1, + 0xCB9A, 0x85F2, 0xCB9B, 0x85F3, 0xCB9C, 0x85F4, 0xCB9D, 0x85F5, + 0xCB9E, 0x85F6, 0xCB9F, 0x85F7, 0xCBA0, 0x85F8, 0xCBA1, 0x6055, + 0xCBA2, 0x5237, 0xCBA3, 0x800D, 0xCBA4, 0x6454, 0xCBA5, 0x8870, + 0xCBA6, 0x7529, 0xCBA7, 0x5E05, 0xCBA8, 0x6813, 0xCBA9, 0x62F4, + 0xCBAA, 0x971C, 0xCBAB, 0x53CC, 0xCBAC, 0x723D, 0xCBAD, 0x8C01, + 0xCBAE, 0x6C34, 0xCBAF, 0x7761, 0xCBB0, 0x7A0E, 0xCBB1, 0x542E, + 0xCBB2, 0x77AC, 0xCBB3, 0x987A, 0xCBB4, 0x821C, 0xCBB5, 0x8BF4, + 0xCBB6, 0x7855, 0xCBB7, 0x6714, 0xCBB8, 0x70C1, 0xCBB9, 0x65AF, + 0xCBBA, 0x6495, 0xCBBB, 0x5636, 0xCBBC, 0x601D, 0xCBBD, 0x79C1, + 0xCBBE, 0x53F8, 0xCBBF, 0x4E1D, 0xCBC0, 0x6B7B, 0xCBC1, 0x8086, + 0xCBC2, 0x5BFA, 0xCBC3, 0x55E3, 0xCBC4, 0x56DB, 0xCBC5, 0x4F3A, + 0xCBC6, 0x4F3C, 0xCBC7, 0x9972, 0xCBC8, 0x5DF3, 0xCBC9, 0x677E, + 0xCBCA, 0x8038, 0xCBCB, 0x6002, 0xCBCC, 0x9882, 0xCBCD, 0x9001, + 0xCBCE, 0x5B8B, 0xCBCF, 0x8BBC, 0xCBD0, 0x8BF5, 0xCBD1, 0x641C, + 0xCBD2, 0x8258, 0xCBD3, 0x64DE, 0xCBD4, 0x55FD, 0xCBD5, 0x82CF, + 0xCBD6, 0x9165, 0xCBD7, 0x4FD7, 0xCBD8, 0x7D20, 0xCBD9, 0x901F, + 0xCBDA, 0x7C9F, 0xCBDB, 0x50F3, 0xCBDC, 0x5851, 0xCBDD, 0x6EAF, + 0xCBDE, 0x5BBF, 0xCBDF, 0x8BC9, 0xCBE0, 0x8083, 0xCBE1, 0x9178, + 0xCBE2, 0x849C, 0xCBE3, 0x7B97, 0xCBE4, 0x867D, 0xCBE5, 0x968B, + 0xCBE6, 0x968F, 0xCBE7, 0x7EE5, 0xCBE8, 0x9AD3, 0xCBE9, 0x788E, + 0xCBEA, 0x5C81, 0xCBEB, 0x7A57, 0xCBEC, 0x9042, 0xCBED, 0x96A7, + 0xCBEE, 0x795F, 0xCBEF, 0x5B59, 0xCBF0, 0x635F, 0xCBF1, 0x7B0B, + 0xCBF2, 0x84D1, 0xCBF3, 0x68AD, 0xCBF4, 0x5506, 0xCBF5, 0x7F29, + 0xCBF6, 0x7410, 0xCBF7, 0x7D22, 0xCBF8, 0x9501, 0xCBF9, 0x6240, + 0xCBFA, 0x584C, 0xCBFB, 0x4ED6, 0xCBFC, 0x5B83, 0xCBFD, 0x5979, + 0xCBFE, 0x5854, 0xCC40, 0x85F9, 0xCC41, 0x85FA, 0xCC42, 0x85FC, + 0xCC43, 0x85FD, 0xCC44, 0x85FE, 0xCC45, 0x8600, 0xCC46, 0x8601, + 0xCC47, 0x8602, 0xCC48, 0x8603, 0xCC49, 0x8604, 0xCC4A, 0x8606, + 0xCC4B, 0x8607, 0xCC4C, 0x8608, 0xCC4D, 0x8609, 0xCC4E, 0x860A, + 0xCC4F, 0x860B, 0xCC50, 0x860C, 0xCC51, 0x860D, 0xCC52, 0x860E, + 0xCC53, 0x860F, 0xCC54, 0x8610, 0xCC55, 0x8612, 0xCC56, 0x8613, + 0xCC57, 0x8614, 0xCC58, 0x8615, 0xCC59, 0x8617, 0xCC5A, 0x8618, + 0xCC5B, 0x8619, 0xCC5C, 0x861A, 0xCC5D, 0x861B, 0xCC5E, 0x861C, + 0xCC5F, 0x861D, 0xCC60, 0x861E, 0xCC61, 0x861F, 0xCC62, 0x8620, + 0xCC63, 0x8621, 0xCC64, 0x8622, 0xCC65, 0x8623, 0xCC66, 0x8624, + 0xCC67, 0x8625, 0xCC68, 0x8626, 0xCC69, 0x8628, 0xCC6A, 0x862A, + 0xCC6B, 0x862B, 0xCC6C, 0x862C, 0xCC6D, 0x862D, 0xCC6E, 0x862E, + 0xCC6F, 0x862F, 0xCC70, 0x8630, 0xCC71, 0x8631, 0xCC72, 0x8632, + 0xCC73, 0x8633, 0xCC74, 0x8634, 0xCC75, 0x8635, 0xCC76, 0x8636, + 0xCC77, 0x8637, 0xCC78, 0x8639, 0xCC79, 0x863A, 0xCC7A, 0x863B, + 0xCC7B, 0x863D, 0xCC7C, 0x863E, 0xCC7D, 0x863F, 0xCC7E, 0x8640, + 0xCC80, 0x8641, 0xCC81, 0x8642, 0xCC82, 0x8643, 0xCC83, 0x8644, + 0xCC84, 0x8645, 0xCC85, 0x8646, 0xCC86, 0x8647, 0xCC87, 0x8648, + 0xCC88, 0x8649, 0xCC89, 0x864A, 0xCC8A, 0x864B, 0xCC8B, 0x864C, + 0xCC8C, 0x8652, 0xCC8D, 0x8653, 0xCC8E, 0x8655, 0xCC8F, 0x8656, + 0xCC90, 0x8657, 0xCC91, 0x8658, 0xCC92, 0x8659, 0xCC93, 0x865B, + 0xCC94, 0x865C, 0xCC95, 0x865D, 0xCC96, 0x865F, 0xCC97, 0x8660, + 0xCC98, 0x8661, 0xCC99, 0x8663, 0xCC9A, 0x8664, 0xCC9B, 0x8665, + 0xCC9C, 0x8666, 0xCC9D, 0x8667, 0xCC9E, 0x8668, 0xCC9F, 0x8669, + 0xCCA0, 0x866A, 0xCCA1, 0x736D, 0xCCA2, 0x631E, 0xCCA3, 0x8E4B, + 0xCCA4, 0x8E0F, 0xCCA5, 0x80CE, 0xCCA6, 0x82D4, 0xCCA7, 0x62AC, + 0xCCA8, 0x53F0, 0xCCA9, 0x6CF0, 0xCCAA, 0x915E, 0xCCAB, 0x592A, + 0xCCAC, 0x6001, 0xCCAD, 0x6C70, 0xCCAE, 0x574D, 0xCCAF, 0x644A, + 0xCCB0, 0x8D2A, 0xCCB1, 0x762B, 0xCCB2, 0x6EE9, 0xCCB3, 0x575B, + 0xCCB4, 0x6A80, 0xCCB5, 0x75F0, 0xCCB6, 0x6F6D, 0xCCB7, 0x8C2D, + 0xCCB8, 0x8C08, 0xCCB9, 0x5766, 0xCCBA, 0x6BEF, 0xCCBB, 0x8892, + 0xCCBC, 0x78B3, 0xCCBD, 0x63A2, 0xCCBE, 0x53F9, 0xCCBF, 0x70AD, + 0xCCC0, 0x6C64, 0xCCC1, 0x5858, 0xCCC2, 0x642A, 0xCCC3, 0x5802, + 0xCCC4, 0x68E0, 0xCCC5, 0x819B, 0xCCC6, 0x5510, 0xCCC7, 0x7CD6, + 0xCCC8, 0x5018, 0xCCC9, 0x8EBA, 0xCCCA, 0x6DCC, 0xCCCB, 0x8D9F, + 0xCCCC, 0x70EB, 0xCCCD, 0x638F, 0xCCCE, 0x6D9B, 0xCCCF, 0x6ED4, + 0xCCD0, 0x7EE6, 0xCCD1, 0x8404, 0xCCD2, 0x6843, 0xCCD3, 0x9003, + 0xCCD4, 0x6DD8, 0xCCD5, 0x9676, 0xCCD6, 0x8BA8, 0xCCD7, 0x5957, + 0xCCD8, 0x7279, 0xCCD9, 0x85E4, 0xCCDA, 0x817E, 0xCCDB, 0x75BC, + 0xCCDC, 0x8A8A, 0xCCDD, 0x68AF, 0xCCDE, 0x5254, 0xCCDF, 0x8E22, + 0xCCE0, 0x9511, 0xCCE1, 0x63D0, 0xCCE2, 0x9898, 0xCCE3, 0x8E44, + 0xCCE4, 0x557C, 0xCCE5, 0x4F53, 0xCCE6, 0x66FF, 0xCCE7, 0x568F, + 0xCCE8, 0x60D5, 0xCCE9, 0x6D95, 0xCCEA, 0x5243, 0xCCEB, 0x5C49, + 0xCCEC, 0x5929, 0xCCED, 0x6DFB, 0xCCEE, 0x586B, 0xCCEF, 0x7530, + 0xCCF0, 0x751C, 0xCCF1, 0x606C, 0xCCF2, 0x8214, 0xCCF3, 0x8146, + 0xCCF4, 0x6311, 0xCCF5, 0x6761, 0xCCF6, 0x8FE2, 0xCCF7, 0x773A, + 0xCCF8, 0x8DF3, 0xCCF9, 0x8D34, 0xCCFA, 0x94C1, 0xCCFB, 0x5E16, + 0xCCFC, 0x5385, 0xCCFD, 0x542C, 0xCCFE, 0x70C3, 0xCD40, 0x866D, + 0xCD41, 0x866F, 0xCD42, 0x8670, 0xCD43, 0x8672, 0xCD44, 0x8673, + 0xCD45, 0x8674, 0xCD46, 0x8675, 0xCD47, 0x8676, 0xCD48, 0x8677, + 0xCD49, 0x8678, 0xCD4A, 0x8683, 0xCD4B, 0x8684, 0xCD4C, 0x8685, + 0xCD4D, 0x8686, 0xCD4E, 0x8687, 0xCD4F, 0x8688, 0xCD50, 0x8689, + 0xCD51, 0x868E, 0xCD52, 0x868F, 0xCD53, 0x8690, 0xCD54, 0x8691, + 0xCD55, 0x8692, 0xCD56, 0x8694, 0xCD57, 0x8696, 0xCD58, 0x8697, + 0xCD59, 0x8698, 0xCD5A, 0x8699, 0xCD5B, 0x869A, 0xCD5C, 0x869B, + 0xCD5D, 0x869E, 0xCD5E, 0x869F, 0xCD5F, 0x86A0, 0xCD60, 0x86A1, + 0xCD61, 0x86A2, 0xCD62, 0x86A5, 0xCD63, 0x86A6, 0xCD64, 0x86AB, + 0xCD65, 0x86AD, 0xCD66, 0x86AE, 0xCD67, 0x86B2, 0xCD68, 0x86B3, + 0xCD69, 0x86B7, 0xCD6A, 0x86B8, 0xCD6B, 0x86B9, 0xCD6C, 0x86BB, + 0xCD6D, 0x86BC, 0xCD6E, 0x86BD, 0xCD6F, 0x86BE, 0xCD70, 0x86BF, + 0xCD71, 0x86C1, 0xCD72, 0x86C2, 0xCD73, 0x86C3, 0xCD74, 0x86C5, + 0xCD75, 0x86C8, 0xCD76, 0x86CC, 0xCD77, 0x86CD, 0xCD78, 0x86D2, + 0xCD79, 0x86D3, 0xCD7A, 0x86D5, 0xCD7B, 0x86D6, 0xCD7C, 0x86D7, + 0xCD7D, 0x86DA, 0xCD7E, 0x86DC, 0xCD80, 0x86DD, 0xCD81, 0x86E0, + 0xCD82, 0x86E1, 0xCD83, 0x86E2, 0xCD84, 0x86E3, 0xCD85, 0x86E5, + 0xCD86, 0x86E6, 0xCD87, 0x86E7, 0xCD88, 0x86E8, 0xCD89, 0x86EA, + 0xCD8A, 0x86EB, 0xCD8B, 0x86EC, 0xCD8C, 0x86EF, 0xCD8D, 0x86F5, + 0xCD8E, 0x86F6, 0xCD8F, 0x86F7, 0xCD90, 0x86FA, 0xCD91, 0x86FB, + 0xCD92, 0x86FC, 0xCD93, 0x86FD, 0xCD94, 0x86FF, 0xCD95, 0x8701, + 0xCD96, 0x8704, 0xCD97, 0x8705, 0xCD98, 0x8706, 0xCD99, 0x870B, + 0xCD9A, 0x870C, 0xCD9B, 0x870E, 0xCD9C, 0x870F, 0xCD9D, 0x8710, + 0xCD9E, 0x8711, 0xCD9F, 0x8714, 0xCDA0, 0x8716, 0xCDA1, 0x6C40, + 0xCDA2, 0x5EF7, 0xCDA3, 0x505C, 0xCDA4, 0x4EAD, 0xCDA5, 0x5EAD, + 0xCDA6, 0x633A, 0xCDA7, 0x8247, 0xCDA8, 0x901A, 0xCDA9, 0x6850, + 0xCDAA, 0x916E, 0xCDAB, 0x77B3, 0xCDAC, 0x540C, 0xCDAD, 0x94DC, + 0xCDAE, 0x5F64, 0xCDAF, 0x7AE5, 0xCDB0, 0x6876, 0xCDB1, 0x6345, + 0xCDB2, 0x7B52, 0xCDB3, 0x7EDF, 0xCDB4, 0x75DB, 0xCDB5, 0x5077, + 0xCDB6, 0x6295, 0xCDB7, 0x5934, 0xCDB8, 0x900F, 0xCDB9, 0x51F8, + 0xCDBA, 0x79C3, 0xCDBB, 0x7A81, 0xCDBC, 0x56FE, 0xCDBD, 0x5F92, + 0xCDBE, 0x9014, 0xCDBF, 0x6D82, 0xCDC0, 0x5C60, 0xCDC1, 0x571F, + 0xCDC2, 0x5410, 0xCDC3, 0x5154, 0xCDC4, 0x6E4D, 0xCDC5, 0x56E2, + 0xCDC6, 0x63A8, 0xCDC7, 0x9893, 0xCDC8, 0x817F, 0xCDC9, 0x8715, + 0xCDCA, 0x892A, 0xCDCB, 0x9000, 0xCDCC, 0x541E, 0xCDCD, 0x5C6F, + 0xCDCE, 0x81C0, 0xCDCF, 0x62D6, 0xCDD0, 0x6258, 0xCDD1, 0x8131, + 0xCDD2, 0x9E35, 0xCDD3, 0x9640, 0xCDD4, 0x9A6E, 0xCDD5, 0x9A7C, + 0xCDD6, 0x692D, 0xCDD7, 0x59A5, 0xCDD8, 0x62D3, 0xCDD9, 0x553E, + 0xCDDA, 0x6316, 0xCDDB, 0x54C7, 0xCDDC, 0x86D9, 0xCDDD, 0x6D3C, + 0xCDDE, 0x5A03, 0xCDDF, 0x74E6, 0xCDE0, 0x889C, 0xCDE1, 0x6B6A, + 0xCDE2, 0x5916, 0xCDE3, 0x8C4C, 0xCDE4, 0x5F2F, 0xCDE5, 0x6E7E, + 0xCDE6, 0x73A9, 0xCDE7, 0x987D, 0xCDE8, 0x4E38, 0xCDE9, 0x70F7, + 0xCDEA, 0x5B8C, 0xCDEB, 0x7897, 0xCDEC, 0x633D, 0xCDED, 0x665A, + 0xCDEE, 0x7696, 0xCDEF, 0x60CB, 0xCDF0, 0x5B9B, 0xCDF1, 0x5A49, + 0xCDF2, 0x4E07, 0xCDF3, 0x8155, 0xCDF4, 0x6C6A, 0xCDF5, 0x738B, + 0xCDF6, 0x4EA1, 0xCDF7, 0x6789, 0xCDF8, 0x7F51, 0xCDF9, 0x5F80, + 0xCDFA, 0x65FA, 0xCDFB, 0x671B, 0xCDFC, 0x5FD8, 0xCDFD, 0x5984, + 0xCDFE, 0x5A01, 0xCE40, 0x8719, 0xCE41, 0x871B, 0xCE42, 0x871D, + 0xCE43, 0x871F, 0xCE44, 0x8720, 0xCE45, 0x8724, 0xCE46, 0x8726, + 0xCE47, 0x8727, 0xCE48, 0x8728, 0xCE49, 0x872A, 0xCE4A, 0x872B, + 0xCE4B, 0x872C, 0xCE4C, 0x872D, 0xCE4D, 0x872F, 0xCE4E, 0x8730, + 0xCE4F, 0x8732, 0xCE50, 0x8733, 0xCE51, 0x8735, 0xCE52, 0x8736, + 0xCE53, 0x8738, 0xCE54, 0x8739, 0xCE55, 0x873A, 0xCE56, 0x873C, + 0xCE57, 0x873D, 0xCE58, 0x8740, 0xCE59, 0x8741, 0xCE5A, 0x8742, + 0xCE5B, 0x8743, 0xCE5C, 0x8744, 0xCE5D, 0x8745, 0xCE5E, 0x8746, + 0xCE5F, 0x874A, 0xCE60, 0x874B, 0xCE61, 0x874D, 0xCE62, 0x874F, + 0xCE63, 0x8750, 0xCE64, 0x8751, 0xCE65, 0x8752, 0xCE66, 0x8754, + 0xCE67, 0x8755, 0xCE68, 0x8756, 0xCE69, 0x8758, 0xCE6A, 0x875A, + 0xCE6B, 0x875B, 0xCE6C, 0x875C, 0xCE6D, 0x875D, 0xCE6E, 0x875E, + 0xCE6F, 0x875F, 0xCE70, 0x8761, 0xCE71, 0x8762, 0xCE72, 0x8766, + 0xCE73, 0x8767, 0xCE74, 0x8768, 0xCE75, 0x8769, 0xCE76, 0x876A, + 0xCE77, 0x876B, 0xCE78, 0x876C, 0xCE79, 0x876D, 0xCE7A, 0x876F, + 0xCE7B, 0x8771, 0xCE7C, 0x8772, 0xCE7D, 0x8773, 0xCE7E, 0x8775, + 0xCE80, 0x8777, 0xCE81, 0x8778, 0xCE82, 0x8779, 0xCE83, 0x877A, + 0xCE84, 0x877F, 0xCE85, 0x8780, 0xCE86, 0x8781, 0xCE87, 0x8784, + 0xCE88, 0x8786, 0xCE89, 0x8787, 0xCE8A, 0x8789, 0xCE8B, 0x878A, + 0xCE8C, 0x878C, 0xCE8D, 0x878E, 0xCE8E, 0x878F, 0xCE8F, 0x8790, + 0xCE90, 0x8791, 0xCE91, 0x8792, 0xCE92, 0x8794, 0xCE93, 0x8795, + 0xCE94, 0x8796, 0xCE95, 0x8798, 0xCE96, 0x8799, 0xCE97, 0x879A, + 0xCE98, 0x879B, 0xCE99, 0x879C, 0xCE9A, 0x879D, 0xCE9B, 0x879E, + 0xCE9C, 0x87A0, 0xCE9D, 0x87A1, 0xCE9E, 0x87A2, 0xCE9F, 0x87A3, + 0xCEA0, 0x87A4, 0xCEA1, 0x5DCD, 0xCEA2, 0x5FAE, 0xCEA3, 0x5371, + 0xCEA4, 0x97E6, 0xCEA5, 0x8FDD, 0xCEA6, 0x6845, 0xCEA7, 0x56F4, + 0xCEA8, 0x552F, 0xCEA9, 0x60DF, 0xCEAA, 0x4E3A, 0xCEAB, 0x6F4D, + 0xCEAC, 0x7EF4, 0xCEAD, 0x82C7, 0xCEAE, 0x840E, 0xCEAF, 0x59D4, + 0xCEB0, 0x4F1F, 0xCEB1, 0x4F2A, 0xCEB2, 0x5C3E, 0xCEB3, 0x7EAC, + 0xCEB4, 0x672A, 0xCEB5, 0x851A, 0xCEB6, 0x5473, 0xCEB7, 0x754F, + 0xCEB8, 0x80C3, 0xCEB9, 0x5582, 0xCEBA, 0x9B4F, 0xCEBB, 0x4F4D, + 0xCEBC, 0x6E2D, 0xCEBD, 0x8C13, 0xCEBE, 0x5C09, 0xCEBF, 0x6170, + 0xCEC0, 0x536B, 0xCEC1, 0x761F, 0xCEC2, 0x6E29, 0xCEC3, 0x868A, + 0xCEC4, 0x6587, 0xCEC5, 0x95FB, 0xCEC6, 0x7EB9, 0xCEC7, 0x543B, + 0xCEC8, 0x7A33, 0xCEC9, 0x7D0A, 0xCECA, 0x95EE, 0xCECB, 0x55E1, + 0xCECC, 0x7FC1, 0xCECD, 0x74EE, 0xCECE, 0x631D, 0xCECF, 0x8717, + 0xCED0, 0x6DA1, 0xCED1, 0x7A9D, 0xCED2, 0x6211, 0xCED3, 0x65A1, + 0xCED4, 0x5367, 0xCED5, 0x63E1, 0xCED6, 0x6C83, 0xCED7, 0x5DEB, + 0xCED8, 0x545C, 0xCED9, 0x94A8, 0xCEDA, 0x4E4C, 0xCEDB, 0x6C61, + 0xCEDC, 0x8BEC, 0xCEDD, 0x5C4B, 0xCEDE, 0x65E0, 0xCEDF, 0x829C, + 0xCEE0, 0x68A7, 0xCEE1, 0x543E, 0xCEE2, 0x5434, 0xCEE3, 0x6BCB, + 0xCEE4, 0x6B66, 0xCEE5, 0x4E94, 0xCEE6, 0x6342, 0xCEE7, 0x5348, + 0xCEE8, 0x821E, 0xCEE9, 0x4F0D, 0xCEEA, 0x4FAE, 0xCEEB, 0x575E, + 0xCEEC, 0x620A, 0xCEED, 0x96FE, 0xCEEE, 0x6664, 0xCEEF, 0x7269, + 0xCEF0, 0x52FF, 0xCEF1, 0x52A1, 0xCEF2, 0x609F, 0xCEF3, 0x8BEF, + 0xCEF4, 0x6614, 0xCEF5, 0x7199, 0xCEF6, 0x6790, 0xCEF7, 0x897F, + 0xCEF8, 0x7852, 0xCEF9, 0x77FD, 0xCEFA, 0x6670, 0xCEFB, 0x563B, + 0xCEFC, 0x5438, 0xCEFD, 0x9521, 0xCEFE, 0x727A, 0xCF40, 0x87A5, + 0xCF41, 0x87A6, 0xCF42, 0x87A7, 0xCF43, 0x87A9, 0xCF44, 0x87AA, + 0xCF45, 0x87AE, 0xCF46, 0x87B0, 0xCF47, 0x87B1, 0xCF48, 0x87B2, + 0xCF49, 0x87B4, 0xCF4A, 0x87B6, 0xCF4B, 0x87B7, 0xCF4C, 0x87B8, + 0xCF4D, 0x87B9, 0xCF4E, 0x87BB, 0xCF4F, 0x87BC, 0xCF50, 0x87BE, + 0xCF51, 0x87BF, 0xCF52, 0x87C1, 0xCF53, 0x87C2, 0xCF54, 0x87C3, + 0xCF55, 0x87C4, 0xCF56, 0x87C5, 0xCF57, 0x87C7, 0xCF58, 0x87C8, + 0xCF59, 0x87C9, 0xCF5A, 0x87CC, 0xCF5B, 0x87CD, 0xCF5C, 0x87CE, + 0xCF5D, 0x87CF, 0xCF5E, 0x87D0, 0xCF5F, 0x87D4, 0xCF60, 0x87D5, + 0xCF61, 0x87D6, 0xCF62, 0x87D7, 0xCF63, 0x87D8, 0xCF64, 0x87D9, + 0xCF65, 0x87DA, 0xCF66, 0x87DC, 0xCF67, 0x87DD, 0xCF68, 0x87DE, + 0xCF69, 0x87DF, 0xCF6A, 0x87E1, 0xCF6B, 0x87E2, 0xCF6C, 0x87E3, + 0xCF6D, 0x87E4, 0xCF6E, 0x87E6, 0xCF6F, 0x87E7, 0xCF70, 0x87E8, + 0xCF71, 0x87E9, 0xCF72, 0x87EB, 0xCF73, 0x87EC, 0xCF74, 0x87ED, + 0xCF75, 0x87EF, 0xCF76, 0x87F0, 0xCF77, 0x87F1, 0xCF78, 0x87F2, + 0xCF79, 0x87F3, 0xCF7A, 0x87F4, 0xCF7B, 0x87F5, 0xCF7C, 0x87F6, + 0xCF7D, 0x87F7, 0xCF7E, 0x87F8, 0xCF80, 0x87FA, 0xCF81, 0x87FB, + 0xCF82, 0x87FC, 0xCF83, 0x87FD, 0xCF84, 0x87FF, 0xCF85, 0x8800, + 0xCF86, 0x8801, 0xCF87, 0x8802, 0xCF88, 0x8804, 0xCF89, 0x8805, + 0xCF8A, 0x8806, 0xCF8B, 0x8807, 0xCF8C, 0x8808, 0xCF8D, 0x8809, + 0xCF8E, 0x880B, 0xCF8F, 0x880C, 0xCF90, 0x880D, 0xCF91, 0x880E, + 0xCF92, 0x880F, 0xCF93, 0x8810, 0xCF94, 0x8811, 0xCF95, 0x8812, + 0xCF96, 0x8814, 0xCF97, 0x8817, 0xCF98, 0x8818, 0xCF99, 0x8819, + 0xCF9A, 0x881A, 0xCF9B, 0x881C, 0xCF9C, 0x881D, 0xCF9D, 0x881E, + 0xCF9E, 0x881F, 0xCF9F, 0x8820, 0xCFA0, 0x8823, 0xCFA1, 0x7A00, + 0xCFA2, 0x606F, 0xCFA3, 0x5E0C, 0xCFA4, 0x6089, 0xCFA5, 0x819D, + 0xCFA6, 0x5915, 0xCFA7, 0x60DC, 0xCFA8, 0x7184, 0xCFA9, 0x70EF, + 0xCFAA, 0x6EAA, 0xCFAB, 0x6C50, 0xCFAC, 0x7280, 0xCFAD, 0x6A84, + 0xCFAE, 0x88AD, 0xCFAF, 0x5E2D, 0xCFB0, 0x4E60, 0xCFB1, 0x5AB3, + 0xCFB2, 0x559C, 0xCFB3, 0x94E3, 0xCFB4, 0x6D17, 0xCFB5, 0x7CFB, + 0xCFB6, 0x9699, 0xCFB7, 0x620F, 0xCFB8, 0x7EC6, 0xCFB9, 0x778E, + 0xCFBA, 0x867E, 0xCFBB, 0x5323, 0xCFBC, 0x971E, 0xCFBD, 0x8F96, + 0xCFBE, 0x6687, 0xCFBF, 0x5CE1, 0xCFC0, 0x4FA0, 0xCFC1, 0x72ED, + 0xCFC2, 0x4E0B, 0xCFC3, 0x53A6, 0xCFC4, 0x590F, 0xCFC5, 0x5413, + 0xCFC6, 0x6380, 0xCFC7, 0x9528, 0xCFC8, 0x5148, 0xCFC9, 0x4ED9, + 0xCFCA, 0x9C9C, 0xCFCB, 0x7EA4, 0xCFCC, 0x54B8, 0xCFCD, 0x8D24, + 0xCFCE, 0x8854, 0xCFCF, 0x8237, 0xCFD0, 0x95F2, 0xCFD1, 0x6D8E, + 0xCFD2, 0x5F26, 0xCFD3, 0x5ACC, 0xCFD4, 0x663E, 0xCFD5, 0x9669, + 0xCFD6, 0x73B0, 0xCFD7, 0x732E, 0xCFD8, 0x53BF, 0xCFD9, 0x817A, + 0xCFDA, 0x9985, 0xCFDB, 0x7FA1, 0xCFDC, 0x5BAA, 0xCFDD, 0x9677, + 0xCFDE, 0x9650, 0xCFDF, 0x7EBF, 0xCFE0, 0x76F8, 0xCFE1, 0x53A2, + 0xCFE2, 0x9576, 0xCFE3, 0x9999, 0xCFE4, 0x7BB1, 0xCFE5, 0x8944, + 0xCFE6, 0x6E58, 0xCFE7, 0x4E61, 0xCFE8, 0x7FD4, 0xCFE9, 0x7965, + 0xCFEA, 0x8BE6, 0xCFEB, 0x60F3, 0xCFEC, 0x54CD, 0xCFED, 0x4EAB, + 0xCFEE, 0x9879, 0xCFEF, 0x5DF7, 0xCFF0, 0x6A61, 0xCFF1, 0x50CF, + 0xCFF2, 0x5411, 0xCFF3, 0x8C61, 0xCFF4, 0x8427, 0xCFF5, 0x785D, + 0xCFF6, 0x9704, 0xCFF7, 0x524A, 0xCFF8, 0x54EE, 0xCFF9, 0x56A3, + 0xCFFA, 0x9500, 0xCFFB, 0x6D88, 0xCFFC, 0x5BB5, 0xCFFD, 0x6DC6, + 0xCFFE, 0x6653, 0xD040, 0x8824, 0xD041, 0x8825, 0xD042, 0x8826, + 0xD043, 0x8827, 0xD044, 0x8828, 0xD045, 0x8829, 0xD046, 0x882A, + 0xD047, 0x882B, 0xD048, 0x882C, 0xD049, 0x882D, 0xD04A, 0x882E, + 0xD04B, 0x882F, 0xD04C, 0x8830, 0xD04D, 0x8831, 0xD04E, 0x8833, + 0xD04F, 0x8834, 0xD050, 0x8835, 0xD051, 0x8836, 0xD052, 0x8837, + 0xD053, 0x8838, 0xD054, 0x883A, 0xD055, 0x883B, 0xD056, 0x883D, + 0xD057, 0x883E, 0xD058, 0x883F, 0xD059, 0x8841, 0xD05A, 0x8842, + 0xD05B, 0x8843, 0xD05C, 0x8846, 0xD05D, 0x8847, 0xD05E, 0x8848, + 0xD05F, 0x8849, 0xD060, 0x884A, 0xD061, 0x884B, 0xD062, 0x884E, + 0xD063, 0x884F, 0xD064, 0x8850, 0xD065, 0x8851, 0xD066, 0x8852, + 0xD067, 0x8853, 0xD068, 0x8855, 0xD069, 0x8856, 0xD06A, 0x8858, + 0xD06B, 0x885A, 0xD06C, 0x885B, 0xD06D, 0x885C, 0xD06E, 0x885D, + 0xD06F, 0x885E, 0xD070, 0x885F, 0xD071, 0x8860, 0xD072, 0x8866, + 0xD073, 0x8867, 0xD074, 0x886A, 0xD075, 0x886D, 0xD076, 0x886F, + 0xD077, 0x8871, 0xD078, 0x8873, 0xD079, 0x8874, 0xD07A, 0x8875, + 0xD07B, 0x8876, 0xD07C, 0x8878, 0xD07D, 0x8879, 0xD07E, 0x887A, + 0xD080, 0x887B, 0xD081, 0x887C, 0xD082, 0x8880, 0xD083, 0x8883, + 0xD084, 0x8886, 0xD085, 0x8887, 0xD086, 0x8889, 0xD087, 0x888A, + 0xD088, 0x888C, 0xD089, 0x888E, 0xD08A, 0x888F, 0xD08B, 0x8890, + 0xD08C, 0x8891, 0xD08D, 0x8893, 0xD08E, 0x8894, 0xD08F, 0x8895, + 0xD090, 0x8897, 0xD091, 0x8898, 0xD092, 0x8899, 0xD093, 0x889A, + 0xD094, 0x889B, 0xD095, 0x889D, 0xD096, 0x889E, 0xD097, 0x889F, + 0xD098, 0x88A0, 0xD099, 0x88A1, 0xD09A, 0x88A3, 0xD09B, 0x88A5, + 0xD09C, 0x88A6, 0xD09D, 0x88A7, 0xD09E, 0x88A8, 0xD09F, 0x88A9, + 0xD0A0, 0x88AA, 0xD0A1, 0x5C0F, 0xD0A2, 0x5B5D, 0xD0A3, 0x6821, + 0xD0A4, 0x8096, 0xD0A5, 0x5578, 0xD0A6, 0x7B11, 0xD0A7, 0x6548, + 0xD0A8, 0x6954, 0xD0A9, 0x4E9B, 0xD0AA, 0x6B47, 0xD0AB, 0x874E, + 0xD0AC, 0x978B, 0xD0AD, 0x534F, 0xD0AE, 0x631F, 0xD0AF, 0x643A, + 0xD0B0, 0x90AA, 0xD0B1, 0x659C, 0xD0B2, 0x80C1, 0xD0B3, 0x8C10, + 0xD0B4, 0x5199, 0xD0B5, 0x68B0, 0xD0B6, 0x5378, 0xD0B7, 0x87F9, + 0xD0B8, 0x61C8, 0xD0B9, 0x6CC4, 0xD0BA, 0x6CFB, 0xD0BB, 0x8C22, + 0xD0BC, 0x5C51, 0xD0BD, 0x85AA, 0xD0BE, 0x82AF, 0xD0BF, 0x950C, + 0xD0C0, 0x6B23, 0xD0C1, 0x8F9B, 0xD0C2, 0x65B0, 0xD0C3, 0x5FFB, + 0xD0C4, 0x5FC3, 0xD0C5, 0x4FE1, 0xD0C6, 0x8845, 0xD0C7, 0x661F, + 0xD0C8, 0x8165, 0xD0C9, 0x7329, 0xD0CA, 0x60FA, 0xD0CB, 0x5174, + 0xD0CC, 0x5211, 0xD0CD, 0x578B, 0xD0CE, 0x5F62, 0xD0CF, 0x90A2, + 0xD0D0, 0x884C, 0xD0D1, 0x9192, 0xD0D2, 0x5E78, 0xD0D3, 0x674F, + 0xD0D4, 0x6027, 0xD0D5, 0x59D3, 0xD0D6, 0x5144, 0xD0D7, 0x51F6, + 0xD0D8, 0x80F8, 0xD0D9, 0x5308, 0xD0DA, 0x6C79, 0xD0DB, 0x96C4, + 0xD0DC, 0x718A, 0xD0DD, 0x4F11, 0xD0DE, 0x4FEE, 0xD0DF, 0x7F9E, + 0xD0E0, 0x673D, 0xD0E1, 0x55C5, 0xD0E2, 0x9508, 0xD0E3, 0x79C0, + 0xD0E4, 0x8896, 0xD0E5, 0x7EE3, 0xD0E6, 0x589F, 0xD0E7, 0x620C, + 0xD0E8, 0x9700, 0xD0E9, 0x865A, 0xD0EA, 0x5618, 0xD0EB, 0x987B, + 0xD0EC, 0x5F90, 0xD0ED, 0x8BB8, 0xD0EE, 0x84C4, 0xD0EF, 0x9157, + 0xD0F0, 0x53D9, 0xD0F1, 0x65ED, 0xD0F2, 0x5E8F, 0xD0F3, 0x755C, + 0xD0F4, 0x6064, 0xD0F5, 0x7D6E, 0xD0F6, 0x5A7F, 0xD0F7, 0x7EEA, + 0xD0F8, 0x7EED, 0xD0F9, 0x8F69, 0xD0FA, 0x55A7, 0xD0FB, 0x5BA3, + 0xD0FC, 0x60AC, 0xD0FD, 0x65CB, 0xD0FE, 0x7384, 0xD140, 0x88AC, + 0xD141, 0x88AE, 0xD142, 0x88AF, 0xD143, 0x88B0, 0xD144, 0x88B2, + 0xD145, 0x88B3, 0xD146, 0x88B4, 0xD147, 0x88B5, 0xD148, 0x88B6, + 0xD149, 0x88B8, 0xD14A, 0x88B9, 0xD14B, 0x88BA, 0xD14C, 0x88BB, + 0xD14D, 0x88BD, 0xD14E, 0x88BE, 0xD14F, 0x88BF, 0xD150, 0x88C0, + 0xD151, 0x88C3, 0xD152, 0x88C4, 0xD153, 0x88C7, 0xD154, 0x88C8, + 0xD155, 0x88CA, 0xD156, 0x88CB, 0xD157, 0x88CC, 0xD158, 0x88CD, + 0xD159, 0x88CF, 0xD15A, 0x88D0, 0xD15B, 0x88D1, 0xD15C, 0x88D3, + 0xD15D, 0x88D6, 0xD15E, 0x88D7, 0xD15F, 0x88DA, 0xD160, 0x88DB, + 0xD161, 0x88DC, 0xD162, 0x88DD, 0xD163, 0x88DE, 0xD164, 0x88E0, + 0xD165, 0x88E1, 0xD166, 0x88E6, 0xD167, 0x88E7, 0xD168, 0x88E9, + 0xD169, 0x88EA, 0xD16A, 0x88EB, 0xD16B, 0x88EC, 0xD16C, 0x88ED, + 0xD16D, 0x88EE, 0xD16E, 0x88EF, 0xD16F, 0x88F2, 0xD170, 0x88F5, + 0xD171, 0x88F6, 0xD172, 0x88F7, 0xD173, 0x88FA, 0xD174, 0x88FB, + 0xD175, 0x88FD, 0xD176, 0x88FF, 0xD177, 0x8900, 0xD178, 0x8901, + 0xD179, 0x8903, 0xD17A, 0x8904, 0xD17B, 0x8905, 0xD17C, 0x8906, + 0xD17D, 0x8907, 0xD17E, 0x8908, 0xD180, 0x8909, 0xD181, 0x890B, + 0xD182, 0x890C, 0xD183, 0x890D, 0xD184, 0x890E, 0xD185, 0x890F, + 0xD186, 0x8911, 0xD187, 0x8914, 0xD188, 0x8915, 0xD189, 0x8916, + 0xD18A, 0x8917, 0xD18B, 0x8918, 0xD18C, 0x891C, 0xD18D, 0x891D, + 0xD18E, 0x891E, 0xD18F, 0x891F, 0xD190, 0x8920, 0xD191, 0x8922, + 0xD192, 0x8923, 0xD193, 0x8924, 0xD194, 0x8926, 0xD195, 0x8927, + 0xD196, 0x8928, 0xD197, 0x8929, 0xD198, 0x892C, 0xD199, 0x892D, + 0xD19A, 0x892E, 0xD19B, 0x892F, 0xD19C, 0x8931, 0xD19D, 0x8932, + 0xD19E, 0x8933, 0xD19F, 0x8935, 0xD1A0, 0x8937, 0xD1A1, 0x9009, + 0xD1A2, 0x7663, 0xD1A3, 0x7729, 0xD1A4, 0x7EDA, 0xD1A5, 0x9774, + 0xD1A6, 0x859B, 0xD1A7, 0x5B66, 0xD1A8, 0x7A74, 0xD1A9, 0x96EA, + 0xD1AA, 0x8840, 0xD1AB, 0x52CB, 0xD1AC, 0x718F, 0xD1AD, 0x5FAA, + 0xD1AE, 0x65EC, 0xD1AF, 0x8BE2, 0xD1B0, 0x5BFB, 0xD1B1, 0x9A6F, + 0xD1B2, 0x5DE1, 0xD1B3, 0x6B89, 0xD1B4, 0x6C5B, 0xD1B5, 0x8BAD, + 0xD1B6, 0x8BAF, 0xD1B7, 0x900A, 0xD1B8, 0x8FC5, 0xD1B9, 0x538B, + 0xD1BA, 0x62BC, 0xD1BB, 0x9E26, 0xD1BC, 0x9E2D, 0xD1BD, 0x5440, + 0xD1BE, 0x4E2B, 0xD1BF, 0x82BD, 0xD1C0, 0x7259, 0xD1C1, 0x869C, + 0xD1C2, 0x5D16, 0xD1C3, 0x8859, 0xD1C4, 0x6DAF, 0xD1C5, 0x96C5, + 0xD1C6, 0x54D1, 0xD1C7, 0x4E9A, 0xD1C8, 0x8BB6, 0xD1C9, 0x7109, + 0xD1CA, 0x54BD, 0xD1CB, 0x9609, 0xD1CC, 0x70DF, 0xD1CD, 0x6DF9, + 0xD1CE, 0x76D0, 0xD1CF, 0x4E25, 0xD1D0, 0x7814, 0xD1D1, 0x8712, + 0xD1D2, 0x5CA9, 0xD1D3, 0x5EF6, 0xD1D4, 0x8A00, 0xD1D5, 0x989C, + 0xD1D6, 0x960E, 0xD1D7, 0x708E, 0xD1D8, 0x6CBF, 0xD1D9, 0x5944, + 0xD1DA, 0x63A9, 0xD1DB, 0x773C, 0xD1DC, 0x884D, 0xD1DD, 0x6F14, + 0xD1DE, 0x8273, 0xD1DF, 0x5830, 0xD1E0, 0x71D5, 0xD1E1, 0x538C, + 0xD1E2, 0x781A, 0xD1E3, 0x96C1, 0xD1E4, 0x5501, 0xD1E5, 0x5F66, + 0xD1E6, 0x7130, 0xD1E7, 0x5BB4, 0xD1E8, 0x8C1A, 0xD1E9, 0x9A8C, + 0xD1EA, 0x6B83, 0xD1EB, 0x592E, 0xD1EC, 0x9E2F, 0xD1ED, 0x79E7, + 0xD1EE, 0x6768, 0xD1EF, 0x626C, 0xD1F0, 0x4F6F, 0xD1F1, 0x75A1, + 0xD1F2, 0x7F8A, 0xD1F3, 0x6D0B, 0xD1F4, 0x9633, 0xD1F5, 0x6C27, + 0xD1F6, 0x4EF0, 0xD1F7, 0x75D2, 0xD1F8, 0x517B, 0xD1F9, 0x6837, + 0xD1FA, 0x6F3E, 0xD1FB, 0x9080, 0xD1FC, 0x8170, 0xD1FD, 0x5996, + 0xD1FE, 0x7476, 0xD240, 0x8938, 0xD241, 0x8939, 0xD242, 0x893A, + 0xD243, 0x893B, 0xD244, 0x893C, 0xD245, 0x893D, 0xD246, 0x893E, + 0xD247, 0x893F, 0xD248, 0x8940, 0xD249, 0x8942, 0xD24A, 0x8943, + 0xD24B, 0x8945, 0xD24C, 0x8946, 0xD24D, 0x8947, 0xD24E, 0x8948, + 0xD24F, 0x8949, 0xD250, 0x894A, 0xD251, 0x894B, 0xD252, 0x894C, + 0xD253, 0x894D, 0xD254, 0x894E, 0xD255, 0x894F, 0xD256, 0x8950, + 0xD257, 0x8951, 0xD258, 0x8952, 0xD259, 0x8953, 0xD25A, 0x8954, + 0xD25B, 0x8955, 0xD25C, 0x8956, 0xD25D, 0x8957, 0xD25E, 0x8958, + 0xD25F, 0x8959, 0xD260, 0x895A, 0xD261, 0x895B, 0xD262, 0x895C, + 0xD263, 0x895D, 0xD264, 0x8960, 0xD265, 0x8961, 0xD266, 0x8962, + 0xD267, 0x8963, 0xD268, 0x8964, 0xD269, 0x8965, 0xD26A, 0x8967, + 0xD26B, 0x8968, 0xD26C, 0x8969, 0xD26D, 0x896A, 0xD26E, 0x896B, + 0xD26F, 0x896C, 0xD270, 0x896D, 0xD271, 0x896E, 0xD272, 0x896F, + 0xD273, 0x8970, 0xD274, 0x8971, 0xD275, 0x8972, 0xD276, 0x8973, + 0xD277, 0x8974, 0xD278, 0x8975, 0xD279, 0x8976, 0xD27A, 0x8977, + 0xD27B, 0x8978, 0xD27C, 0x8979, 0xD27D, 0x897A, 0xD27E, 0x897C, + 0xD280, 0x897D, 0xD281, 0x897E, 0xD282, 0x8980, 0xD283, 0x8982, + 0xD284, 0x8984, 0xD285, 0x8985, 0xD286, 0x8987, 0xD287, 0x8988, + 0xD288, 0x8989, 0xD289, 0x898A, 0xD28A, 0x898B, 0xD28B, 0x898C, + 0xD28C, 0x898D, 0xD28D, 0x898E, 0xD28E, 0x898F, 0xD28F, 0x8990, + 0xD290, 0x8991, 0xD291, 0x8992, 0xD292, 0x8993, 0xD293, 0x8994, + 0xD294, 0x8995, 0xD295, 0x8996, 0xD296, 0x8997, 0xD297, 0x8998, + 0xD298, 0x8999, 0xD299, 0x899A, 0xD29A, 0x899B, 0xD29B, 0x899C, + 0xD29C, 0x899D, 0xD29D, 0x899E, 0xD29E, 0x899F, 0xD29F, 0x89A0, + 0xD2A0, 0x89A1, 0xD2A1, 0x6447, 0xD2A2, 0x5C27, 0xD2A3, 0x9065, + 0xD2A4, 0x7A91, 0xD2A5, 0x8C23, 0xD2A6, 0x59DA, 0xD2A7, 0x54AC, + 0xD2A8, 0x8200, 0xD2A9, 0x836F, 0xD2AA, 0x8981, 0xD2AB, 0x8000, + 0xD2AC, 0x6930, 0xD2AD, 0x564E, 0xD2AE, 0x8036, 0xD2AF, 0x7237, + 0xD2B0, 0x91CE, 0xD2B1, 0x51B6, 0xD2B2, 0x4E5F, 0xD2B3, 0x9875, + 0xD2B4, 0x6396, 0xD2B5, 0x4E1A, 0xD2B6, 0x53F6, 0xD2B7, 0x66F3, + 0xD2B8, 0x814B, 0xD2B9, 0x591C, 0xD2BA, 0x6DB2, 0xD2BB, 0x4E00, + 0xD2BC, 0x58F9, 0xD2BD, 0x533B, 0xD2BE, 0x63D6, 0xD2BF, 0x94F1, + 0xD2C0, 0x4F9D, 0xD2C1, 0x4F0A, 0xD2C2, 0x8863, 0xD2C3, 0x9890, + 0xD2C4, 0x5937, 0xD2C5, 0x9057, 0xD2C6, 0x79FB, 0xD2C7, 0x4EEA, + 0xD2C8, 0x80F0, 0xD2C9, 0x7591, 0xD2CA, 0x6C82, 0xD2CB, 0x5B9C, + 0xD2CC, 0x59E8, 0xD2CD, 0x5F5D, 0xD2CE, 0x6905, 0xD2CF, 0x8681, + 0xD2D0, 0x501A, 0xD2D1, 0x5DF2, 0xD2D2, 0x4E59, 0xD2D3, 0x77E3, + 0xD2D4, 0x4EE5, 0xD2D5, 0x827A, 0xD2D6, 0x6291, 0xD2D7, 0x6613, + 0xD2D8, 0x9091, 0xD2D9, 0x5C79, 0xD2DA, 0x4EBF, 0xD2DB, 0x5F79, + 0xD2DC, 0x81C6, 0xD2DD, 0x9038, 0xD2DE, 0x8084, 0xD2DF, 0x75AB, + 0xD2E0, 0x4EA6, 0xD2E1, 0x88D4, 0xD2E2, 0x610F, 0xD2E3, 0x6BC5, + 0xD2E4, 0x5FC6, 0xD2E5, 0x4E49, 0xD2E6, 0x76CA, 0xD2E7, 0x6EA2, + 0xD2E8, 0x8BE3, 0xD2E9, 0x8BAE, 0xD2EA, 0x8C0A, 0xD2EB, 0x8BD1, + 0xD2EC, 0x5F02, 0xD2ED, 0x7FFC, 0xD2EE, 0x7FCC, 0xD2EF, 0x7ECE, + 0xD2F0, 0x8335, 0xD2F1, 0x836B, 0xD2F2, 0x56E0, 0xD2F3, 0x6BB7, + 0xD2F4, 0x97F3, 0xD2F5, 0x9634, 0xD2F6, 0x59FB, 0xD2F7, 0x541F, + 0xD2F8, 0x94F6, 0xD2F9, 0x6DEB, 0xD2FA, 0x5BC5, 0xD2FB, 0x996E, + 0xD2FC, 0x5C39, 0xD2FD, 0x5F15, 0xD2FE, 0x9690, 0xD340, 0x89A2, + 0xD341, 0x89A3, 0xD342, 0x89A4, 0xD343, 0x89A5, 0xD344, 0x89A6, + 0xD345, 0x89A7, 0xD346, 0x89A8, 0xD347, 0x89A9, 0xD348, 0x89AA, + 0xD349, 0x89AB, 0xD34A, 0x89AC, 0xD34B, 0x89AD, 0xD34C, 0x89AE, + 0xD34D, 0x89AF, 0xD34E, 0x89B0, 0xD34F, 0x89B1, 0xD350, 0x89B2, + 0xD351, 0x89B3, 0xD352, 0x89B4, 0xD353, 0x89B5, 0xD354, 0x89B6, + 0xD355, 0x89B7, 0xD356, 0x89B8, 0xD357, 0x89B9, 0xD358, 0x89BA, + 0xD359, 0x89BB, 0xD35A, 0x89BC, 0xD35B, 0x89BD, 0xD35C, 0x89BE, + 0xD35D, 0x89BF, 0xD35E, 0x89C0, 0xD35F, 0x89C3, 0xD360, 0x89CD, + 0xD361, 0x89D3, 0xD362, 0x89D4, 0xD363, 0x89D5, 0xD364, 0x89D7, + 0xD365, 0x89D8, 0xD366, 0x89D9, 0xD367, 0x89DB, 0xD368, 0x89DD, + 0xD369, 0x89DF, 0xD36A, 0x89E0, 0xD36B, 0x89E1, 0xD36C, 0x89E2, + 0xD36D, 0x89E4, 0xD36E, 0x89E7, 0xD36F, 0x89E8, 0xD370, 0x89E9, + 0xD371, 0x89EA, 0xD372, 0x89EC, 0xD373, 0x89ED, 0xD374, 0x89EE, + 0xD375, 0x89F0, 0xD376, 0x89F1, 0xD377, 0x89F2, 0xD378, 0x89F4, + 0xD379, 0x89F5, 0xD37A, 0x89F6, 0xD37B, 0x89F7, 0xD37C, 0x89F8, + 0xD37D, 0x89F9, 0xD37E, 0x89FA, 0xD380, 0x89FB, 0xD381, 0x89FC, + 0xD382, 0x89FD, 0xD383, 0x89FE, 0xD384, 0x89FF, 0xD385, 0x8A01, + 0xD386, 0x8A02, 0xD387, 0x8A03, 0xD388, 0x8A04, 0xD389, 0x8A05, + 0xD38A, 0x8A06, 0xD38B, 0x8A08, 0xD38C, 0x8A09, 0xD38D, 0x8A0A, + 0xD38E, 0x8A0B, 0xD38F, 0x8A0C, 0xD390, 0x8A0D, 0xD391, 0x8A0E, + 0xD392, 0x8A0F, 0xD393, 0x8A10, 0xD394, 0x8A11, 0xD395, 0x8A12, + 0xD396, 0x8A13, 0xD397, 0x8A14, 0xD398, 0x8A15, 0xD399, 0x8A16, + 0xD39A, 0x8A17, 0xD39B, 0x8A18, 0xD39C, 0x8A19, 0xD39D, 0x8A1A, + 0xD39E, 0x8A1B, 0xD39F, 0x8A1C, 0xD3A0, 0x8A1D, 0xD3A1, 0x5370, + 0xD3A2, 0x82F1, 0xD3A3, 0x6A31, 0xD3A4, 0x5A74, 0xD3A5, 0x9E70, + 0xD3A6, 0x5E94, 0xD3A7, 0x7F28, 0xD3A8, 0x83B9, 0xD3A9, 0x8424, + 0xD3AA, 0x8425, 0xD3AB, 0x8367, 0xD3AC, 0x8747, 0xD3AD, 0x8FCE, + 0xD3AE, 0x8D62, 0xD3AF, 0x76C8, 0xD3B0, 0x5F71, 0xD3B1, 0x9896, + 0xD3B2, 0x786C, 0xD3B3, 0x6620, 0xD3B4, 0x54DF, 0xD3B5, 0x62E5, + 0xD3B6, 0x4F63, 0xD3B7, 0x81C3, 0xD3B8, 0x75C8, 0xD3B9, 0x5EB8, + 0xD3BA, 0x96CD, 0xD3BB, 0x8E0A, 0xD3BC, 0x86F9, 0xD3BD, 0x548F, + 0xD3BE, 0x6CF3, 0xD3BF, 0x6D8C, 0xD3C0, 0x6C38, 0xD3C1, 0x607F, + 0xD3C2, 0x52C7, 0xD3C3, 0x7528, 0xD3C4, 0x5E7D, 0xD3C5, 0x4F18, + 0xD3C6, 0x60A0, 0xD3C7, 0x5FE7, 0xD3C8, 0x5C24, 0xD3C9, 0x7531, + 0xD3CA, 0x90AE, 0xD3CB, 0x94C0, 0xD3CC, 0x72B9, 0xD3CD, 0x6CB9, + 0xD3CE, 0x6E38, 0xD3CF, 0x9149, 0xD3D0, 0x6709, 0xD3D1, 0x53CB, + 0xD3D2, 0x53F3, 0xD3D3, 0x4F51, 0xD3D4, 0x91C9, 0xD3D5, 0x8BF1, + 0xD3D6, 0x53C8, 0xD3D7, 0x5E7C, 0xD3D8, 0x8FC2, 0xD3D9, 0x6DE4, + 0xD3DA, 0x4E8E, 0xD3DB, 0x76C2, 0xD3DC, 0x6986, 0xD3DD, 0x865E, + 0xD3DE, 0x611A, 0xD3DF, 0x8206, 0xD3E0, 0x4F59, 0xD3E1, 0x4FDE, + 0xD3E2, 0x903E, 0xD3E3, 0x9C7C, 0xD3E4, 0x6109, 0xD3E5, 0x6E1D, + 0xD3E6, 0x6E14, 0xD3E7, 0x9685, 0xD3E8, 0x4E88, 0xD3E9, 0x5A31, + 0xD3EA, 0x96E8, 0xD3EB, 0x4E0E, 0xD3EC, 0x5C7F, 0xD3ED, 0x79B9, + 0xD3EE, 0x5B87, 0xD3EF, 0x8BED, 0xD3F0, 0x7FBD, 0xD3F1, 0x7389, + 0xD3F2, 0x57DF, 0xD3F3, 0x828B, 0xD3F4, 0x90C1, 0xD3F5, 0x5401, + 0xD3F6, 0x9047, 0xD3F7, 0x55BB, 0xD3F8, 0x5CEA, 0xD3F9, 0x5FA1, + 0xD3FA, 0x6108, 0xD3FB, 0x6B32, 0xD3FC, 0x72F1, 0xD3FD, 0x80B2, + 0xD3FE, 0x8A89, 0xD440, 0x8A1E, 0xD441, 0x8A1F, 0xD442, 0x8A20, + 0xD443, 0x8A21, 0xD444, 0x8A22, 0xD445, 0x8A23, 0xD446, 0x8A24, + 0xD447, 0x8A25, 0xD448, 0x8A26, 0xD449, 0x8A27, 0xD44A, 0x8A28, + 0xD44B, 0x8A29, 0xD44C, 0x8A2A, 0xD44D, 0x8A2B, 0xD44E, 0x8A2C, + 0xD44F, 0x8A2D, 0xD450, 0x8A2E, 0xD451, 0x8A2F, 0xD452, 0x8A30, + 0xD453, 0x8A31, 0xD454, 0x8A32, 0xD455, 0x8A33, 0xD456, 0x8A34, + 0xD457, 0x8A35, 0xD458, 0x8A36, 0xD459, 0x8A37, 0xD45A, 0x8A38, + 0xD45B, 0x8A39, 0xD45C, 0x8A3A, 0xD45D, 0x8A3B, 0xD45E, 0x8A3C, + 0xD45F, 0x8A3D, 0xD460, 0x8A3F, 0xD461, 0x8A40, 0xD462, 0x8A41, + 0xD463, 0x8A42, 0xD464, 0x8A43, 0xD465, 0x8A44, 0xD466, 0x8A45, + 0xD467, 0x8A46, 0xD468, 0x8A47, 0xD469, 0x8A49, 0xD46A, 0x8A4A, + 0xD46B, 0x8A4B, 0xD46C, 0x8A4C, 0xD46D, 0x8A4D, 0xD46E, 0x8A4E, + 0xD46F, 0x8A4F, 0xD470, 0x8A50, 0xD471, 0x8A51, 0xD472, 0x8A52, + 0xD473, 0x8A53, 0xD474, 0x8A54, 0xD475, 0x8A55, 0xD476, 0x8A56, + 0xD477, 0x8A57, 0xD478, 0x8A58, 0xD479, 0x8A59, 0xD47A, 0x8A5A, + 0xD47B, 0x8A5B, 0xD47C, 0x8A5C, 0xD47D, 0x8A5D, 0xD47E, 0x8A5E, + 0xD480, 0x8A5F, 0xD481, 0x8A60, 0xD482, 0x8A61, 0xD483, 0x8A62, + 0xD484, 0x8A63, 0xD485, 0x8A64, 0xD486, 0x8A65, 0xD487, 0x8A66, + 0xD488, 0x8A67, 0xD489, 0x8A68, 0xD48A, 0x8A69, 0xD48B, 0x8A6A, + 0xD48C, 0x8A6B, 0xD48D, 0x8A6C, 0xD48E, 0x8A6D, 0xD48F, 0x8A6E, + 0xD490, 0x8A6F, 0xD491, 0x8A70, 0xD492, 0x8A71, 0xD493, 0x8A72, + 0xD494, 0x8A73, 0xD495, 0x8A74, 0xD496, 0x8A75, 0xD497, 0x8A76, + 0xD498, 0x8A77, 0xD499, 0x8A78, 0xD49A, 0x8A7A, 0xD49B, 0x8A7B, + 0xD49C, 0x8A7C, 0xD49D, 0x8A7D, 0xD49E, 0x8A7E, 0xD49F, 0x8A7F, + 0xD4A0, 0x8A80, 0xD4A1, 0x6D74, 0xD4A2, 0x5BD3, 0xD4A3, 0x88D5, + 0xD4A4, 0x9884, 0xD4A5, 0x8C6B, 0xD4A6, 0x9A6D, 0xD4A7, 0x9E33, + 0xD4A8, 0x6E0A, 0xD4A9, 0x51A4, 0xD4AA, 0x5143, 0xD4AB, 0x57A3, + 0xD4AC, 0x8881, 0xD4AD, 0x539F, 0xD4AE, 0x63F4, 0xD4AF, 0x8F95, + 0xD4B0, 0x56ED, 0xD4B1, 0x5458, 0xD4B2, 0x5706, 0xD4B3, 0x733F, + 0xD4B4, 0x6E90, 0xD4B5, 0x7F18, 0xD4B6, 0x8FDC, 0xD4B7, 0x82D1, + 0xD4B8, 0x613F, 0xD4B9, 0x6028, 0xD4BA, 0x9662, 0xD4BB, 0x66F0, + 0xD4BC, 0x7EA6, 0xD4BD, 0x8D8A, 0xD4BE, 0x8DC3, 0xD4BF, 0x94A5, + 0xD4C0, 0x5CB3, 0xD4C1, 0x7CA4, 0xD4C2, 0x6708, 0xD4C3, 0x60A6, + 0xD4C4, 0x9605, 0xD4C5, 0x8018, 0xD4C6, 0x4E91, 0xD4C7, 0x90E7, + 0xD4C8, 0x5300, 0xD4C9, 0x9668, 0xD4CA, 0x5141, 0xD4CB, 0x8FD0, + 0xD4CC, 0x8574, 0xD4CD, 0x915D, 0xD4CE, 0x6655, 0xD4CF, 0x97F5, + 0xD4D0, 0x5B55, 0xD4D1, 0x531D, 0xD4D2, 0x7838, 0xD4D3, 0x6742, + 0xD4D4, 0x683D, 0xD4D5, 0x54C9, 0xD4D6, 0x707E, 0xD4D7, 0x5BB0, + 0xD4D8, 0x8F7D, 0xD4D9, 0x518D, 0xD4DA, 0x5728, 0xD4DB, 0x54B1, + 0xD4DC, 0x6512, 0xD4DD, 0x6682, 0xD4DE, 0x8D5E, 0xD4DF, 0x8D43, + 0xD4E0, 0x810F, 0xD4E1, 0x846C, 0xD4E2, 0x906D, 0xD4E3, 0x7CDF, + 0xD4E4, 0x51FF, 0xD4E5, 0x85FB, 0xD4E6, 0x67A3, 0xD4E7, 0x65E9, + 0xD4E8, 0x6FA1, 0xD4E9, 0x86A4, 0xD4EA, 0x8E81, 0xD4EB, 0x566A, + 0xD4EC, 0x9020, 0xD4ED, 0x7682, 0xD4EE, 0x7076, 0xD4EF, 0x71E5, + 0xD4F0, 0x8D23, 0xD4F1, 0x62E9, 0xD4F2, 0x5219, 0xD4F3, 0x6CFD, + 0xD4F4, 0x8D3C, 0xD4F5, 0x600E, 0xD4F6, 0x589E, 0xD4F7, 0x618E, + 0xD4F8, 0x66FE, 0xD4F9, 0x8D60, 0xD4FA, 0x624E, 0xD4FB, 0x55B3, + 0xD4FC, 0x6E23, 0xD4FD, 0x672D, 0xD4FE, 0x8F67, 0xD540, 0x8A81, + 0xD541, 0x8A82, 0xD542, 0x8A83, 0xD543, 0x8A84, 0xD544, 0x8A85, + 0xD545, 0x8A86, 0xD546, 0x8A87, 0xD547, 0x8A88, 0xD548, 0x8A8B, + 0xD549, 0x8A8C, 0xD54A, 0x8A8D, 0xD54B, 0x8A8E, 0xD54C, 0x8A8F, + 0xD54D, 0x8A90, 0xD54E, 0x8A91, 0xD54F, 0x8A92, 0xD550, 0x8A94, + 0xD551, 0x8A95, 0xD552, 0x8A96, 0xD553, 0x8A97, 0xD554, 0x8A98, + 0xD555, 0x8A99, 0xD556, 0x8A9A, 0xD557, 0x8A9B, 0xD558, 0x8A9C, + 0xD559, 0x8A9D, 0xD55A, 0x8A9E, 0xD55B, 0x8A9F, 0xD55C, 0x8AA0, + 0xD55D, 0x8AA1, 0xD55E, 0x8AA2, 0xD55F, 0x8AA3, 0xD560, 0x8AA4, + 0xD561, 0x8AA5, 0xD562, 0x8AA6, 0xD563, 0x8AA7, 0xD564, 0x8AA8, + 0xD565, 0x8AA9, 0xD566, 0x8AAA, 0xD567, 0x8AAB, 0xD568, 0x8AAC, + 0xD569, 0x8AAD, 0xD56A, 0x8AAE, 0xD56B, 0x8AAF, 0xD56C, 0x8AB0, + 0xD56D, 0x8AB1, 0xD56E, 0x8AB2, 0xD56F, 0x8AB3, 0xD570, 0x8AB4, + 0xD571, 0x8AB5, 0xD572, 0x8AB6, 0xD573, 0x8AB7, 0xD574, 0x8AB8, + 0xD575, 0x8AB9, 0xD576, 0x8ABA, 0xD577, 0x8ABB, 0xD578, 0x8ABC, + 0xD579, 0x8ABD, 0xD57A, 0x8ABE, 0xD57B, 0x8ABF, 0xD57C, 0x8AC0, + 0xD57D, 0x8AC1, 0xD57E, 0x8AC2, 0xD580, 0x8AC3, 0xD581, 0x8AC4, + 0xD582, 0x8AC5, 0xD583, 0x8AC6, 0xD584, 0x8AC7, 0xD585, 0x8AC8, + 0xD586, 0x8AC9, 0xD587, 0x8ACA, 0xD588, 0x8ACB, 0xD589, 0x8ACC, + 0xD58A, 0x8ACD, 0xD58B, 0x8ACE, 0xD58C, 0x8ACF, 0xD58D, 0x8AD0, + 0xD58E, 0x8AD1, 0xD58F, 0x8AD2, 0xD590, 0x8AD3, 0xD591, 0x8AD4, + 0xD592, 0x8AD5, 0xD593, 0x8AD6, 0xD594, 0x8AD7, 0xD595, 0x8AD8, + 0xD596, 0x8AD9, 0xD597, 0x8ADA, 0xD598, 0x8ADB, 0xD599, 0x8ADC, + 0xD59A, 0x8ADD, 0xD59B, 0x8ADE, 0xD59C, 0x8ADF, 0xD59D, 0x8AE0, + 0xD59E, 0x8AE1, 0xD59F, 0x8AE2, 0xD5A0, 0x8AE3, 0xD5A1, 0x94E1, + 0xD5A2, 0x95F8, 0xD5A3, 0x7728, 0xD5A4, 0x6805, 0xD5A5, 0x69A8, + 0xD5A6, 0x548B, 0xD5A7, 0x4E4D, 0xD5A8, 0x70B8, 0xD5A9, 0x8BC8, + 0xD5AA, 0x6458, 0xD5AB, 0x658B, 0xD5AC, 0x5B85, 0xD5AD, 0x7A84, + 0xD5AE, 0x503A, 0xD5AF, 0x5BE8, 0xD5B0, 0x77BB, 0xD5B1, 0x6BE1, + 0xD5B2, 0x8A79, 0xD5B3, 0x7C98, 0xD5B4, 0x6CBE, 0xD5B5, 0x76CF, + 0xD5B6, 0x65A9, 0xD5B7, 0x8F97, 0xD5B8, 0x5D2D, 0xD5B9, 0x5C55, + 0xD5BA, 0x8638, 0xD5BB, 0x6808, 0xD5BC, 0x5360, 0xD5BD, 0x6218, + 0xD5BE, 0x7AD9, 0xD5BF, 0x6E5B, 0xD5C0, 0x7EFD, 0xD5C1, 0x6A1F, + 0xD5C2, 0x7AE0, 0xD5C3, 0x5F70, 0xD5C4, 0x6F33, 0xD5C5, 0x5F20, + 0xD5C6, 0x638C, 0xD5C7, 0x6DA8, 0xD5C8, 0x6756, 0xD5C9, 0x4E08, + 0xD5CA, 0x5E10, 0xD5CB, 0x8D26, 0xD5CC, 0x4ED7, 0xD5CD, 0x80C0, + 0xD5CE, 0x7634, 0xD5CF, 0x969C, 0xD5D0, 0x62DB, 0xD5D1, 0x662D, + 0xD5D2, 0x627E, 0xD5D3, 0x6CBC, 0xD5D4, 0x8D75, 0xD5D5, 0x7167, + 0xD5D6, 0x7F69, 0xD5D7, 0x5146, 0xD5D8, 0x8087, 0xD5D9, 0x53EC, + 0xD5DA, 0x906E, 0xD5DB, 0x6298, 0xD5DC, 0x54F2, 0xD5DD, 0x86F0, + 0xD5DE, 0x8F99, 0xD5DF, 0x8005, 0xD5E0, 0x9517, 0xD5E1, 0x8517, + 0xD5E2, 0x8FD9, 0xD5E3, 0x6D59, 0xD5E4, 0x73CD, 0xD5E5, 0x659F, + 0xD5E6, 0x771F, 0xD5E7, 0x7504, 0xD5E8, 0x7827, 0xD5E9, 0x81FB, + 0xD5EA, 0x8D1E, 0xD5EB, 0x9488, 0xD5EC, 0x4FA6, 0xD5ED, 0x6795, + 0xD5EE, 0x75B9, 0xD5EF, 0x8BCA, 0xD5F0, 0x9707, 0xD5F1, 0x632F, + 0xD5F2, 0x9547, 0xD5F3, 0x9635, 0xD5F4, 0x84B8, 0xD5F5, 0x6323, + 0xD5F6, 0x7741, 0xD5F7, 0x5F81, 0xD5F8, 0x72F0, 0xD5F9, 0x4E89, + 0xD5FA, 0x6014, 0xD5FB, 0x6574, 0xD5FC, 0x62EF, 0xD5FD, 0x6B63, + 0xD5FE, 0x653F, 0xD640, 0x8AE4, 0xD641, 0x8AE5, 0xD642, 0x8AE6, + 0xD643, 0x8AE7, 0xD644, 0x8AE8, 0xD645, 0x8AE9, 0xD646, 0x8AEA, + 0xD647, 0x8AEB, 0xD648, 0x8AEC, 0xD649, 0x8AED, 0xD64A, 0x8AEE, + 0xD64B, 0x8AEF, 0xD64C, 0x8AF0, 0xD64D, 0x8AF1, 0xD64E, 0x8AF2, + 0xD64F, 0x8AF3, 0xD650, 0x8AF4, 0xD651, 0x8AF5, 0xD652, 0x8AF6, + 0xD653, 0x8AF7, 0xD654, 0x8AF8, 0xD655, 0x8AF9, 0xD656, 0x8AFA, + 0xD657, 0x8AFB, 0xD658, 0x8AFC, 0xD659, 0x8AFD, 0xD65A, 0x8AFE, + 0xD65B, 0x8AFF, 0xD65C, 0x8B00, 0xD65D, 0x8B01, 0xD65E, 0x8B02, + 0xD65F, 0x8B03, 0xD660, 0x8B04, 0xD661, 0x8B05, 0xD662, 0x8B06, + 0xD663, 0x8B08, 0xD664, 0x8B09, 0xD665, 0x8B0A, 0xD666, 0x8B0B, + 0xD667, 0x8B0C, 0xD668, 0x8B0D, 0xD669, 0x8B0E, 0xD66A, 0x8B0F, + 0xD66B, 0x8B10, 0xD66C, 0x8B11, 0xD66D, 0x8B12, 0xD66E, 0x8B13, + 0xD66F, 0x8B14, 0xD670, 0x8B15, 0xD671, 0x8B16, 0xD672, 0x8B17, + 0xD673, 0x8B18, 0xD674, 0x8B19, 0xD675, 0x8B1A, 0xD676, 0x8B1B, + 0xD677, 0x8B1C, 0xD678, 0x8B1D, 0xD679, 0x8B1E, 0xD67A, 0x8B1F, + 0xD67B, 0x8B20, 0xD67C, 0x8B21, 0xD67D, 0x8B22, 0xD67E, 0x8B23, + 0xD680, 0x8B24, 0xD681, 0x8B25, 0xD682, 0x8B27, 0xD683, 0x8B28, + 0xD684, 0x8B29, 0xD685, 0x8B2A, 0xD686, 0x8B2B, 0xD687, 0x8B2C, + 0xD688, 0x8B2D, 0xD689, 0x8B2E, 0xD68A, 0x8B2F, 0xD68B, 0x8B30, + 0xD68C, 0x8B31, 0xD68D, 0x8B32, 0xD68E, 0x8B33, 0xD68F, 0x8B34, + 0xD690, 0x8B35, 0xD691, 0x8B36, 0xD692, 0x8B37, 0xD693, 0x8B38, + 0xD694, 0x8B39, 0xD695, 0x8B3A, 0xD696, 0x8B3B, 0xD697, 0x8B3C, + 0xD698, 0x8B3D, 0xD699, 0x8B3E, 0xD69A, 0x8B3F, 0xD69B, 0x8B40, + 0xD69C, 0x8B41, 0xD69D, 0x8B42, 0xD69E, 0x8B43, 0xD69F, 0x8B44, + 0xD6A0, 0x8B45, 0xD6A1, 0x5E27, 0xD6A2, 0x75C7, 0xD6A3, 0x90D1, + 0xD6A4, 0x8BC1, 0xD6A5, 0x829D, 0xD6A6, 0x679D, 0xD6A7, 0x652F, + 0xD6A8, 0x5431, 0xD6A9, 0x8718, 0xD6AA, 0x77E5, 0xD6AB, 0x80A2, + 0xD6AC, 0x8102, 0xD6AD, 0x6C41, 0xD6AE, 0x4E4B, 0xD6AF, 0x7EC7, + 0xD6B0, 0x804C, 0xD6B1, 0x76F4, 0xD6B2, 0x690D, 0xD6B3, 0x6B96, + 0xD6B4, 0x6267, 0xD6B5, 0x503C, 0xD6B6, 0x4F84, 0xD6B7, 0x5740, + 0xD6B8, 0x6307, 0xD6B9, 0x6B62, 0xD6BA, 0x8DBE, 0xD6BB, 0x53EA, + 0xD6BC, 0x65E8, 0xD6BD, 0x7EB8, 0xD6BE, 0x5FD7, 0xD6BF, 0x631A, + 0xD6C0, 0x63B7, 0xD6C1, 0x81F3, 0xD6C2, 0x81F4, 0xD6C3, 0x7F6E, + 0xD6C4, 0x5E1C, 0xD6C5, 0x5CD9, 0xD6C6, 0x5236, 0xD6C7, 0x667A, + 0xD6C8, 0x79E9, 0xD6C9, 0x7A1A, 0xD6CA, 0x8D28, 0xD6CB, 0x7099, + 0xD6CC, 0x75D4, 0xD6CD, 0x6EDE, 0xD6CE, 0x6CBB, 0xD6CF, 0x7A92, + 0xD6D0, 0x4E2D, 0xD6D1, 0x76C5, 0xD6D2, 0x5FE0, 0xD6D3, 0x949F, + 0xD6D4, 0x8877, 0xD6D5, 0x7EC8, 0xD6D6, 0x79CD, 0xD6D7, 0x80BF, + 0xD6D8, 0x91CD, 0xD6D9, 0x4EF2, 0xD6DA, 0x4F17, 0xD6DB, 0x821F, + 0xD6DC, 0x5468, 0xD6DD, 0x5DDE, 0xD6DE, 0x6D32, 0xD6DF, 0x8BCC, + 0xD6E0, 0x7CA5, 0xD6E1, 0x8F74, 0xD6E2, 0x8098, 0xD6E3, 0x5E1A, + 0xD6E4, 0x5492, 0xD6E5, 0x76B1, 0xD6E6, 0x5B99, 0xD6E7, 0x663C, + 0xD6E8, 0x9AA4, 0xD6E9, 0x73E0, 0xD6EA, 0x682A, 0xD6EB, 0x86DB, + 0xD6EC, 0x6731, 0xD6ED, 0x732A, 0xD6EE, 0x8BF8, 0xD6EF, 0x8BDB, + 0xD6F0, 0x9010, 0xD6F1, 0x7AF9, 0xD6F2, 0x70DB, 0xD6F3, 0x716E, + 0xD6F4, 0x62C4, 0xD6F5, 0x77A9, 0xD6F6, 0x5631, 0xD6F7, 0x4E3B, + 0xD6F8, 0x8457, 0xD6F9, 0x67F1, 0xD6FA, 0x52A9, 0xD6FB, 0x86C0, + 0xD6FC, 0x8D2E, 0xD6FD, 0x94F8, 0xD6FE, 0x7B51, 0xD740, 0x8B46, + 0xD741, 0x8B47, 0xD742, 0x8B48, 0xD743, 0x8B49, 0xD744, 0x8B4A, + 0xD745, 0x8B4B, 0xD746, 0x8B4C, 0xD747, 0x8B4D, 0xD748, 0x8B4E, + 0xD749, 0x8B4F, 0xD74A, 0x8B50, 0xD74B, 0x8B51, 0xD74C, 0x8B52, + 0xD74D, 0x8B53, 0xD74E, 0x8B54, 0xD74F, 0x8B55, 0xD750, 0x8B56, + 0xD751, 0x8B57, 0xD752, 0x8B58, 0xD753, 0x8B59, 0xD754, 0x8B5A, + 0xD755, 0x8B5B, 0xD756, 0x8B5C, 0xD757, 0x8B5D, 0xD758, 0x8B5E, + 0xD759, 0x8B5F, 0xD75A, 0x8B60, 0xD75B, 0x8B61, 0xD75C, 0x8B62, + 0xD75D, 0x8B63, 0xD75E, 0x8B64, 0xD75F, 0x8B65, 0xD760, 0x8B67, + 0xD761, 0x8B68, 0xD762, 0x8B69, 0xD763, 0x8B6A, 0xD764, 0x8B6B, + 0xD765, 0x8B6D, 0xD766, 0x8B6E, 0xD767, 0x8B6F, 0xD768, 0x8B70, + 0xD769, 0x8B71, 0xD76A, 0x8B72, 0xD76B, 0x8B73, 0xD76C, 0x8B74, + 0xD76D, 0x8B75, 0xD76E, 0x8B76, 0xD76F, 0x8B77, 0xD770, 0x8B78, + 0xD771, 0x8B79, 0xD772, 0x8B7A, 0xD773, 0x8B7B, 0xD774, 0x8B7C, + 0xD775, 0x8B7D, 0xD776, 0x8B7E, 0xD777, 0x8B7F, 0xD778, 0x8B80, + 0xD779, 0x8B81, 0xD77A, 0x8B82, 0xD77B, 0x8B83, 0xD77C, 0x8B84, + 0xD77D, 0x8B85, 0xD77E, 0x8B86, 0xD780, 0x8B87, 0xD781, 0x8B88, + 0xD782, 0x8B89, 0xD783, 0x8B8A, 0xD784, 0x8B8B, 0xD785, 0x8B8C, + 0xD786, 0x8B8D, 0xD787, 0x8B8E, 0xD788, 0x8B8F, 0xD789, 0x8B90, + 0xD78A, 0x8B91, 0xD78B, 0x8B92, 0xD78C, 0x8B93, 0xD78D, 0x8B94, + 0xD78E, 0x8B95, 0xD78F, 0x8B96, 0xD790, 0x8B97, 0xD791, 0x8B98, + 0xD792, 0x8B99, 0xD793, 0x8B9A, 0xD794, 0x8B9B, 0xD795, 0x8B9C, + 0xD796, 0x8B9D, 0xD797, 0x8B9E, 0xD798, 0x8B9F, 0xD799, 0x8BAC, + 0xD79A, 0x8BB1, 0xD79B, 0x8BBB, 0xD79C, 0x8BC7, 0xD79D, 0x8BD0, + 0xD79E, 0x8BEA, 0xD79F, 0x8C09, 0xD7A0, 0x8C1E, 0xD7A1, 0x4F4F, + 0xD7A2, 0x6CE8, 0xD7A3, 0x795D, 0xD7A4, 0x9A7B, 0xD7A5, 0x6293, + 0xD7A6, 0x722A, 0xD7A7, 0x62FD, 0xD7A8, 0x4E13, 0xD7A9, 0x7816, + 0xD7AA, 0x8F6C, 0xD7AB, 0x64B0, 0xD7AC, 0x8D5A, 0xD7AD, 0x7BC6, + 0xD7AE, 0x6869, 0xD7AF, 0x5E84, 0xD7B0, 0x88C5, 0xD7B1, 0x5986, + 0xD7B2, 0x649E, 0xD7B3, 0x58EE, 0xD7B4, 0x72B6, 0xD7B5, 0x690E, + 0xD7B6, 0x9525, 0xD7B7, 0x8FFD, 0xD7B8, 0x8D58, 0xD7B9, 0x5760, + 0xD7BA, 0x7F00, 0xD7BB, 0x8C06, 0xD7BC, 0x51C6, 0xD7BD, 0x6349, + 0xD7BE, 0x62D9, 0xD7BF, 0x5353, 0xD7C0, 0x684C, 0xD7C1, 0x7422, + 0xD7C2, 0x8301, 0xD7C3, 0x914C, 0xD7C4, 0x5544, 0xD7C5, 0x7740, + 0xD7C6, 0x707C, 0xD7C7, 0x6D4A, 0xD7C8, 0x5179, 0xD7C9, 0x54A8, + 0xD7CA, 0x8D44, 0xD7CB, 0x59FF, 0xD7CC, 0x6ECB, 0xD7CD, 0x6DC4, + 0xD7CE, 0x5B5C, 0xD7CF, 0x7D2B, 0xD7D0, 0x4ED4, 0xD7D1, 0x7C7D, + 0xD7D2, 0x6ED3, 0xD7D3, 0x5B50, 0xD7D4, 0x81EA, 0xD7D5, 0x6E0D, + 0xD7D6, 0x5B57, 0xD7D7, 0x9B03, 0xD7D8, 0x68D5, 0xD7D9, 0x8E2A, + 0xD7DA, 0x5B97, 0xD7DB, 0x7EFC, 0xD7DC, 0x603B, 0xD7DD, 0x7EB5, + 0xD7DE, 0x90B9, 0xD7DF, 0x8D70, 0xD7E0, 0x594F, 0xD7E1, 0x63CD, + 0xD7E2, 0x79DF, 0xD7E3, 0x8DB3, 0xD7E4, 0x5352, 0xD7E5, 0x65CF, + 0xD7E6, 0x7956, 0xD7E7, 0x8BC5, 0xD7E8, 0x963B, 0xD7E9, 0x7EC4, + 0xD7EA, 0x94BB, 0xD7EB, 0x7E82, 0xD7EC, 0x5634, 0xD7ED, 0x9189, + 0xD7EE, 0x6700, 0xD7EF, 0x7F6A, 0xD7F0, 0x5C0A, 0xD7F1, 0x9075, + 0xD7F2, 0x6628, 0xD7F3, 0x5DE6, 0xD7F4, 0x4F50, 0xD7F5, 0x67DE, + 0xD7F6, 0x505A, 0xD7F7, 0x4F5C, 0xD7F8, 0x5750, 0xD7F9, 0x5EA7, + 0xD840, 0x8C38, 0xD841, 0x8C39, 0xD842, 0x8C3A, 0xD843, 0x8C3B, + 0xD844, 0x8C3C, 0xD845, 0x8C3D, 0xD846, 0x8C3E, 0xD847, 0x8C3F, + 0xD848, 0x8C40, 0xD849, 0x8C42, 0xD84A, 0x8C43, 0xD84B, 0x8C44, + 0xD84C, 0x8C45, 0xD84D, 0x8C48, 0xD84E, 0x8C4A, 0xD84F, 0x8C4B, + 0xD850, 0x8C4D, 0xD851, 0x8C4E, 0xD852, 0x8C4F, 0xD853, 0x8C50, + 0xD854, 0x8C51, 0xD855, 0x8C52, 0xD856, 0x8C53, 0xD857, 0x8C54, + 0xD858, 0x8C56, 0xD859, 0x8C57, 0xD85A, 0x8C58, 0xD85B, 0x8C59, + 0xD85C, 0x8C5B, 0xD85D, 0x8C5C, 0xD85E, 0x8C5D, 0xD85F, 0x8C5E, + 0xD860, 0x8C5F, 0xD861, 0x8C60, 0xD862, 0x8C63, 0xD863, 0x8C64, + 0xD864, 0x8C65, 0xD865, 0x8C66, 0xD866, 0x8C67, 0xD867, 0x8C68, + 0xD868, 0x8C69, 0xD869, 0x8C6C, 0xD86A, 0x8C6D, 0xD86B, 0x8C6E, + 0xD86C, 0x8C6F, 0xD86D, 0x8C70, 0xD86E, 0x8C71, 0xD86F, 0x8C72, + 0xD870, 0x8C74, 0xD871, 0x8C75, 0xD872, 0x8C76, 0xD873, 0x8C77, + 0xD874, 0x8C7B, 0xD875, 0x8C7C, 0xD876, 0x8C7D, 0xD877, 0x8C7E, + 0xD878, 0x8C7F, 0xD879, 0x8C80, 0xD87A, 0x8C81, 0xD87B, 0x8C83, + 0xD87C, 0x8C84, 0xD87D, 0x8C86, 0xD87E, 0x8C87, 0xD880, 0x8C88, + 0xD881, 0x8C8B, 0xD882, 0x8C8D, 0xD883, 0x8C8E, 0xD884, 0x8C8F, + 0xD885, 0x8C90, 0xD886, 0x8C91, 0xD887, 0x8C92, 0xD888, 0x8C93, + 0xD889, 0x8C95, 0xD88A, 0x8C96, 0xD88B, 0x8C97, 0xD88C, 0x8C99, + 0xD88D, 0x8C9A, 0xD88E, 0x8C9B, 0xD88F, 0x8C9C, 0xD890, 0x8C9D, + 0xD891, 0x8C9E, 0xD892, 0x8C9F, 0xD893, 0x8CA0, 0xD894, 0x8CA1, + 0xD895, 0x8CA2, 0xD896, 0x8CA3, 0xD897, 0x8CA4, 0xD898, 0x8CA5, + 0xD899, 0x8CA6, 0xD89A, 0x8CA7, 0xD89B, 0x8CA8, 0xD89C, 0x8CA9, + 0xD89D, 0x8CAA, 0xD89E, 0x8CAB, 0xD89F, 0x8CAC, 0xD8A0, 0x8CAD, + 0xD8A1, 0x4E8D, 0xD8A2, 0x4E0C, 0xD8A3, 0x5140, 0xD8A4, 0x4E10, + 0xD8A5, 0x5EFF, 0xD8A6, 0x5345, 0xD8A7, 0x4E15, 0xD8A8, 0x4E98, + 0xD8A9, 0x4E1E, 0xD8AA, 0x9B32, 0xD8AB, 0x5B6C, 0xD8AC, 0x5669, + 0xD8AD, 0x4E28, 0xD8AE, 0x79BA, 0xD8AF, 0x4E3F, 0xD8B0, 0x5315, + 0xD8B1, 0x4E47, 0xD8B2, 0x592D, 0xD8B3, 0x723B, 0xD8B4, 0x536E, + 0xD8B5, 0x6C10, 0xD8B6, 0x56DF, 0xD8B7, 0x80E4, 0xD8B8, 0x9997, + 0xD8B9, 0x6BD3, 0xD8BA, 0x777E, 0xD8BB, 0x9F17, 0xD8BC, 0x4E36, + 0xD8BD, 0x4E9F, 0xD8BE, 0x9F10, 0xD8BF, 0x4E5C, 0xD8C0, 0x4E69, + 0xD8C1, 0x4E93, 0xD8C2, 0x8288, 0xD8C3, 0x5B5B, 0xD8C4, 0x556C, + 0xD8C5, 0x560F, 0xD8C6, 0x4EC4, 0xD8C7, 0x538D, 0xD8C8, 0x539D, + 0xD8C9, 0x53A3, 0xD8CA, 0x53A5, 0xD8CB, 0x53AE, 0xD8CC, 0x9765, + 0xD8CD, 0x8D5D, 0xD8CE, 0x531A, 0xD8CF, 0x53F5, 0xD8D0, 0x5326, + 0xD8D1, 0x532E, 0xD8D2, 0x533E, 0xD8D3, 0x8D5C, 0xD8D4, 0x5366, + 0xD8D5, 0x5363, 0xD8D6, 0x5202, 0xD8D7, 0x5208, 0xD8D8, 0x520E, + 0xD8D9, 0x522D, 0xD8DA, 0x5233, 0xD8DB, 0x523F, 0xD8DC, 0x5240, + 0xD8DD, 0x524C, 0xD8DE, 0x525E, 0xD8DF, 0x5261, 0xD8E0, 0x525C, + 0xD8E1, 0x84AF, 0xD8E2, 0x527D, 0xD8E3, 0x5282, 0xD8E4, 0x5281, + 0xD8E5, 0x5290, 0xD8E6, 0x5293, 0xD8E7, 0x5182, 0xD8E8, 0x7F54, + 0xD8E9, 0x4EBB, 0xD8EA, 0x4EC3, 0xD8EB, 0x4EC9, 0xD8EC, 0x4EC2, + 0xD8ED, 0x4EE8, 0xD8EE, 0x4EE1, 0xD8EF, 0x4EEB, 0xD8F0, 0x4EDE, + 0xD8F1, 0x4F1B, 0xD8F2, 0x4EF3, 0xD8F3, 0x4F22, 0xD8F4, 0x4F64, + 0xD8F5, 0x4EF5, 0xD8F6, 0x4F25, 0xD8F7, 0x4F27, 0xD8F8, 0x4F09, + 0xD8F9, 0x4F2B, 0xD8FA, 0x4F5E, 0xD8FB, 0x4F67, 0xD8FC, 0x6538, + 0xD8FD, 0x4F5A, 0xD8FE, 0x4F5D, 0xD940, 0x8CAE, 0xD941, 0x8CAF, + 0xD942, 0x8CB0, 0xD943, 0x8CB1, 0xD944, 0x8CB2, 0xD945, 0x8CB3, + 0xD946, 0x8CB4, 0xD947, 0x8CB5, 0xD948, 0x8CB6, 0xD949, 0x8CB7, + 0xD94A, 0x8CB8, 0xD94B, 0x8CB9, 0xD94C, 0x8CBA, 0xD94D, 0x8CBB, + 0xD94E, 0x8CBC, 0xD94F, 0x8CBD, 0xD950, 0x8CBE, 0xD951, 0x8CBF, + 0xD952, 0x8CC0, 0xD953, 0x8CC1, 0xD954, 0x8CC2, 0xD955, 0x8CC3, + 0xD956, 0x8CC4, 0xD957, 0x8CC5, 0xD958, 0x8CC6, 0xD959, 0x8CC7, + 0xD95A, 0x8CC8, 0xD95B, 0x8CC9, 0xD95C, 0x8CCA, 0xD95D, 0x8CCB, + 0xD95E, 0x8CCC, 0xD95F, 0x8CCD, 0xD960, 0x8CCE, 0xD961, 0x8CCF, + 0xD962, 0x8CD0, 0xD963, 0x8CD1, 0xD964, 0x8CD2, 0xD965, 0x8CD3, + 0xD966, 0x8CD4, 0xD967, 0x8CD5, 0xD968, 0x8CD6, 0xD969, 0x8CD7, + 0xD96A, 0x8CD8, 0xD96B, 0x8CD9, 0xD96C, 0x8CDA, 0xD96D, 0x8CDB, + 0xD96E, 0x8CDC, 0xD96F, 0x8CDD, 0xD970, 0x8CDE, 0xD971, 0x8CDF, + 0xD972, 0x8CE0, 0xD973, 0x8CE1, 0xD974, 0x8CE2, 0xD975, 0x8CE3, + 0xD976, 0x8CE4, 0xD977, 0x8CE5, 0xD978, 0x8CE6, 0xD979, 0x8CE7, + 0xD97A, 0x8CE8, 0xD97B, 0x8CE9, 0xD97C, 0x8CEA, 0xD97D, 0x8CEB, + 0xD97E, 0x8CEC, 0xD980, 0x8CED, 0xD981, 0x8CEE, 0xD982, 0x8CEF, + 0xD983, 0x8CF0, 0xD984, 0x8CF1, 0xD985, 0x8CF2, 0xD986, 0x8CF3, + 0xD987, 0x8CF4, 0xD988, 0x8CF5, 0xD989, 0x8CF6, 0xD98A, 0x8CF7, + 0xD98B, 0x8CF8, 0xD98C, 0x8CF9, 0xD98D, 0x8CFA, 0xD98E, 0x8CFB, + 0xD98F, 0x8CFC, 0xD990, 0x8CFD, 0xD991, 0x8CFE, 0xD992, 0x8CFF, + 0xD993, 0x8D00, 0xD994, 0x8D01, 0xD995, 0x8D02, 0xD996, 0x8D03, + 0xD997, 0x8D04, 0xD998, 0x8D05, 0xD999, 0x8D06, 0xD99A, 0x8D07, + 0xD99B, 0x8D08, 0xD99C, 0x8D09, 0xD99D, 0x8D0A, 0xD99E, 0x8D0B, + 0xD99F, 0x8D0C, 0xD9A0, 0x8D0D, 0xD9A1, 0x4F5F, 0xD9A2, 0x4F57, + 0xD9A3, 0x4F32, 0xD9A4, 0x4F3D, 0xD9A5, 0x4F76, 0xD9A6, 0x4F74, + 0xD9A7, 0x4F91, 0xD9A8, 0x4F89, 0xD9A9, 0x4F83, 0xD9AA, 0x4F8F, + 0xD9AB, 0x4F7E, 0xD9AC, 0x4F7B, 0xD9AD, 0x4FAA, 0xD9AE, 0x4F7C, + 0xD9AF, 0x4FAC, 0xD9B0, 0x4F94, 0xD9B1, 0x4FE6, 0xD9B2, 0x4FE8, + 0xD9B3, 0x4FEA, 0xD9B4, 0x4FC5, 0xD9B5, 0x4FDA, 0xD9B6, 0x4FE3, + 0xD9B7, 0x4FDC, 0xD9B8, 0x4FD1, 0xD9B9, 0x4FDF, 0xD9BA, 0x4FF8, + 0xD9BB, 0x5029, 0xD9BC, 0x504C, 0xD9BD, 0x4FF3, 0xD9BE, 0x502C, + 0xD9BF, 0x500F, 0xD9C0, 0x502E, 0xD9C1, 0x502D, 0xD9C2, 0x4FFE, + 0xD9C3, 0x501C, 0xD9C4, 0x500C, 0xD9C5, 0x5025, 0xD9C6, 0x5028, + 0xD9C7, 0x507E, 0xD9C8, 0x5043, 0xD9C9, 0x5055, 0xD9CA, 0x5048, + 0xD9CB, 0x504E, 0xD9CC, 0x506C, 0xD9CD, 0x507B, 0xD9CE, 0x50A5, + 0xD9CF, 0x50A7, 0xD9D0, 0x50A9, 0xD9D1, 0x50BA, 0xD9D2, 0x50D6, + 0xD9D3, 0x5106, 0xD9D4, 0x50ED, 0xD9D5, 0x50EC, 0xD9D6, 0x50E6, + 0xD9D7, 0x50EE, 0xD9D8, 0x5107, 0xD9D9, 0x510B, 0xD9DA, 0x4EDD, + 0xD9DB, 0x6C3D, 0xD9DC, 0x4F58, 0xD9DD, 0x4F65, 0xD9DE, 0x4FCE, + 0xD9DF, 0x9FA0, 0xD9E0, 0x6C46, 0xD9E1, 0x7C74, 0xD9E2, 0x516E, + 0xD9E3, 0x5DFD, 0xD9E4, 0x9EC9, 0xD9E5, 0x9998, 0xD9E6, 0x5181, + 0xD9E7, 0x5914, 0xD9E8, 0x52F9, 0xD9E9, 0x530D, 0xD9EA, 0x8A07, + 0xD9EB, 0x5310, 0xD9EC, 0x51EB, 0xD9ED, 0x5919, 0xD9EE, 0x5155, + 0xD9EF, 0x4EA0, 0xD9F0, 0x5156, 0xD9F1, 0x4EB3, 0xD9F2, 0x886E, + 0xD9F3, 0x88A4, 0xD9F4, 0x4EB5, 0xD9F5, 0x8114, 0xD9F6, 0x88D2, + 0xD9F7, 0x7980, 0xD9F8, 0x5B34, 0xD9F9, 0x8803, 0xD9FA, 0x7FB8, + 0xD9FB, 0x51AB, 0xD9FC, 0x51B1, 0xD9FD, 0x51BD, 0xD9FE, 0x51BC, + 0xDA40, 0x8D0E, 0xDA41, 0x8D0F, 0xDA42, 0x8D10, 0xDA43, 0x8D11, + 0xDA44, 0x8D12, 0xDA45, 0x8D13, 0xDA46, 0x8D14, 0xDA47, 0x8D15, + 0xDA48, 0x8D16, 0xDA49, 0x8D17, 0xDA4A, 0x8D18, 0xDA4B, 0x8D19, + 0xDA4C, 0x8D1A, 0xDA4D, 0x8D1B, 0xDA4E, 0x8D1C, 0xDA4F, 0x8D20, + 0xDA50, 0x8D51, 0xDA51, 0x8D52, 0xDA52, 0x8D57, 0xDA53, 0x8D5F, + 0xDA54, 0x8D65, 0xDA55, 0x8D68, 0xDA56, 0x8D69, 0xDA57, 0x8D6A, + 0xDA58, 0x8D6C, 0xDA59, 0x8D6E, 0xDA5A, 0x8D6F, 0xDA5B, 0x8D71, + 0xDA5C, 0x8D72, 0xDA5D, 0x8D78, 0xDA5E, 0x8D79, 0xDA5F, 0x8D7A, + 0xDA60, 0x8D7B, 0xDA61, 0x8D7C, 0xDA62, 0x8D7D, 0xDA63, 0x8D7E, + 0xDA64, 0x8D7F, 0xDA65, 0x8D80, 0xDA66, 0x8D82, 0xDA67, 0x8D83, + 0xDA68, 0x8D86, 0xDA69, 0x8D87, 0xDA6A, 0x8D88, 0xDA6B, 0x8D89, + 0xDA6C, 0x8D8C, 0xDA6D, 0x8D8D, 0xDA6E, 0x8D8E, 0xDA6F, 0x8D8F, + 0xDA70, 0x8D90, 0xDA71, 0x8D92, 0xDA72, 0x8D93, 0xDA73, 0x8D95, + 0xDA74, 0x8D96, 0xDA75, 0x8D97, 0xDA76, 0x8D98, 0xDA77, 0x8D99, + 0xDA78, 0x8D9A, 0xDA79, 0x8D9B, 0xDA7A, 0x8D9C, 0xDA7B, 0x8D9D, + 0xDA7C, 0x8D9E, 0xDA7D, 0x8DA0, 0xDA7E, 0x8DA1, 0xDA80, 0x8DA2, + 0xDA81, 0x8DA4, 0xDA82, 0x8DA5, 0xDA83, 0x8DA6, 0xDA84, 0x8DA7, + 0xDA85, 0x8DA8, 0xDA86, 0x8DA9, 0xDA87, 0x8DAA, 0xDA88, 0x8DAB, + 0xDA89, 0x8DAC, 0xDA8A, 0x8DAD, 0xDA8B, 0x8DAE, 0xDA8C, 0x8DAF, + 0xDA8D, 0x8DB0, 0xDA8E, 0x8DB2, 0xDA8F, 0x8DB6, 0xDA90, 0x8DB7, + 0xDA91, 0x8DB9, 0xDA92, 0x8DBB, 0xDA93, 0x8DBD, 0xDA94, 0x8DC0, + 0xDA95, 0x8DC1, 0xDA96, 0x8DC2, 0xDA97, 0x8DC5, 0xDA98, 0x8DC7, + 0xDA99, 0x8DC8, 0xDA9A, 0x8DC9, 0xDA9B, 0x8DCA, 0xDA9C, 0x8DCD, + 0xDA9D, 0x8DD0, 0xDA9E, 0x8DD2, 0xDA9F, 0x8DD3, 0xDAA0, 0x8DD4, + 0xDAA1, 0x51C7, 0xDAA2, 0x5196, 0xDAA3, 0x51A2, 0xDAA4, 0x51A5, + 0xDAA5, 0x8BA0, 0xDAA6, 0x8BA6, 0xDAA7, 0x8BA7, 0xDAA8, 0x8BAA, + 0xDAA9, 0x8BB4, 0xDAAA, 0x8BB5, 0xDAAB, 0x8BB7, 0xDAAC, 0x8BC2, + 0xDAAD, 0x8BC3, 0xDAAE, 0x8BCB, 0xDAAF, 0x8BCF, 0xDAB0, 0x8BCE, + 0xDAB1, 0x8BD2, 0xDAB2, 0x8BD3, 0xDAB3, 0x8BD4, 0xDAB4, 0x8BD6, + 0xDAB5, 0x8BD8, 0xDAB6, 0x8BD9, 0xDAB7, 0x8BDC, 0xDAB8, 0x8BDF, + 0xDAB9, 0x8BE0, 0xDABA, 0x8BE4, 0xDABB, 0x8BE8, 0xDABC, 0x8BE9, + 0xDABD, 0x8BEE, 0xDABE, 0x8BF0, 0xDABF, 0x8BF3, 0xDAC0, 0x8BF6, + 0xDAC1, 0x8BF9, 0xDAC2, 0x8BFC, 0xDAC3, 0x8BFF, 0xDAC4, 0x8C00, + 0xDAC5, 0x8C02, 0xDAC6, 0x8C04, 0xDAC7, 0x8C07, 0xDAC8, 0x8C0C, + 0xDAC9, 0x8C0F, 0xDACA, 0x8C11, 0xDACB, 0x8C12, 0xDACC, 0x8C14, + 0xDACD, 0x8C15, 0xDACE, 0x8C16, 0xDACF, 0x8C19, 0xDAD0, 0x8C1B, + 0xDAD1, 0x8C18, 0xDAD2, 0x8C1D, 0xDAD3, 0x8C1F, 0xDAD4, 0x8C20, + 0xDAD5, 0x8C21, 0xDAD6, 0x8C25, 0xDAD7, 0x8C27, 0xDAD8, 0x8C2A, + 0xDAD9, 0x8C2B, 0xDADA, 0x8C2E, 0xDADB, 0x8C2F, 0xDADC, 0x8C32, + 0xDADD, 0x8C33, 0xDADE, 0x8C35, 0xDADF, 0x8C36, 0xDAE0, 0x5369, + 0xDAE1, 0x537A, 0xDAE2, 0x961D, 0xDAE3, 0x9622, 0xDAE4, 0x9621, + 0xDAE5, 0x9631, 0xDAE6, 0x962A, 0xDAE7, 0x963D, 0xDAE8, 0x963C, + 0xDAE9, 0x9642, 0xDAEA, 0x9649, 0xDAEB, 0x9654, 0xDAEC, 0x965F, + 0xDAED, 0x9667, 0xDAEE, 0x966C, 0xDAEF, 0x9672, 0xDAF0, 0x9674, + 0xDAF1, 0x9688, 0xDAF2, 0x968D, 0xDAF3, 0x9697, 0xDAF4, 0x96B0, + 0xDAF5, 0x9097, 0xDAF6, 0x909B, 0xDAF7, 0x909D, 0xDAF8, 0x9099, + 0xDAF9, 0x90AC, 0xDAFA, 0x90A1, 0xDAFB, 0x90B4, 0xDAFC, 0x90B3, + 0xDAFD, 0x90B6, 0xDAFE, 0x90BA, 0xDB40, 0x8DD5, 0xDB41, 0x8DD8, + 0xDB42, 0x8DD9, 0xDB43, 0x8DDC, 0xDB44, 0x8DE0, 0xDB45, 0x8DE1, + 0xDB46, 0x8DE2, 0xDB47, 0x8DE5, 0xDB48, 0x8DE6, 0xDB49, 0x8DE7, + 0xDB4A, 0x8DE9, 0xDB4B, 0x8DED, 0xDB4C, 0x8DEE, 0xDB4D, 0x8DF0, + 0xDB4E, 0x8DF1, 0xDB4F, 0x8DF2, 0xDB50, 0x8DF4, 0xDB51, 0x8DF6, + 0xDB52, 0x8DFC, 0xDB53, 0x8DFE, 0xDB54, 0x8DFF, 0xDB55, 0x8E00, + 0xDB56, 0x8E01, 0xDB57, 0x8E02, 0xDB58, 0x8E03, 0xDB59, 0x8E04, + 0xDB5A, 0x8E06, 0xDB5B, 0x8E07, 0xDB5C, 0x8E08, 0xDB5D, 0x8E0B, + 0xDB5E, 0x8E0D, 0xDB5F, 0x8E0E, 0xDB60, 0x8E10, 0xDB61, 0x8E11, + 0xDB62, 0x8E12, 0xDB63, 0x8E13, 0xDB64, 0x8E15, 0xDB65, 0x8E16, + 0xDB66, 0x8E17, 0xDB67, 0x8E18, 0xDB68, 0x8E19, 0xDB69, 0x8E1A, + 0xDB6A, 0x8E1B, 0xDB6B, 0x8E1C, 0xDB6C, 0x8E20, 0xDB6D, 0x8E21, + 0xDB6E, 0x8E24, 0xDB6F, 0x8E25, 0xDB70, 0x8E26, 0xDB71, 0x8E27, + 0xDB72, 0x8E28, 0xDB73, 0x8E2B, 0xDB74, 0x8E2D, 0xDB75, 0x8E30, + 0xDB76, 0x8E32, 0xDB77, 0x8E33, 0xDB78, 0x8E34, 0xDB79, 0x8E36, + 0xDB7A, 0x8E37, 0xDB7B, 0x8E38, 0xDB7C, 0x8E3B, 0xDB7D, 0x8E3C, + 0xDB7E, 0x8E3E, 0xDB80, 0x8E3F, 0xDB81, 0x8E43, 0xDB82, 0x8E45, + 0xDB83, 0x8E46, 0xDB84, 0x8E4C, 0xDB85, 0x8E4D, 0xDB86, 0x8E4E, + 0xDB87, 0x8E4F, 0xDB88, 0x8E50, 0xDB89, 0x8E53, 0xDB8A, 0x8E54, + 0xDB8B, 0x8E55, 0xDB8C, 0x8E56, 0xDB8D, 0x8E57, 0xDB8E, 0x8E58, + 0xDB8F, 0x8E5A, 0xDB90, 0x8E5B, 0xDB91, 0x8E5C, 0xDB92, 0x8E5D, + 0xDB93, 0x8E5E, 0xDB94, 0x8E5F, 0xDB95, 0x8E60, 0xDB96, 0x8E61, + 0xDB97, 0x8E62, 0xDB98, 0x8E63, 0xDB99, 0x8E64, 0xDB9A, 0x8E65, + 0xDB9B, 0x8E67, 0xDB9C, 0x8E68, 0xDB9D, 0x8E6A, 0xDB9E, 0x8E6B, + 0xDB9F, 0x8E6E, 0xDBA0, 0x8E71, 0xDBA1, 0x90B8, 0xDBA2, 0x90B0, + 0xDBA3, 0x90CF, 0xDBA4, 0x90C5, 0xDBA5, 0x90BE, 0xDBA6, 0x90D0, + 0xDBA7, 0x90C4, 0xDBA8, 0x90C7, 0xDBA9, 0x90D3, 0xDBAA, 0x90E6, + 0xDBAB, 0x90E2, 0xDBAC, 0x90DC, 0xDBAD, 0x90D7, 0xDBAE, 0x90DB, + 0xDBAF, 0x90EB, 0xDBB0, 0x90EF, 0xDBB1, 0x90FE, 0xDBB2, 0x9104, + 0xDBB3, 0x9122, 0xDBB4, 0x911E, 0xDBB5, 0x9123, 0xDBB6, 0x9131, + 0xDBB7, 0x912F, 0xDBB8, 0x9139, 0xDBB9, 0x9143, 0xDBBA, 0x9146, + 0xDBBB, 0x520D, 0xDBBC, 0x5942, 0xDBBD, 0x52A2, 0xDBBE, 0x52AC, + 0xDBBF, 0x52AD, 0xDBC0, 0x52BE, 0xDBC1, 0x54FF, 0xDBC2, 0x52D0, + 0xDBC3, 0x52D6, 0xDBC4, 0x52F0, 0xDBC5, 0x53DF, 0xDBC6, 0x71EE, + 0xDBC7, 0x77CD, 0xDBC8, 0x5EF4, 0xDBC9, 0x51F5, 0xDBCA, 0x51FC, + 0xDBCB, 0x9B2F, 0xDBCC, 0x53B6, 0xDBCD, 0x5F01, 0xDBCE, 0x755A, + 0xDBCF, 0x5DEF, 0xDBD0, 0x574C, 0xDBD1, 0x57A9, 0xDBD2, 0x57A1, + 0xDBD3, 0x587E, 0xDBD4, 0x58BC, 0xDBD5, 0x58C5, 0xDBD6, 0x58D1, + 0xDBD7, 0x5729, 0xDBD8, 0x572C, 0xDBD9, 0x572A, 0xDBDA, 0x5733, + 0xDBDB, 0x5739, 0xDBDC, 0x572E, 0xDBDD, 0x572F, 0xDBDE, 0x575C, + 0xDBDF, 0x573B, 0xDBE0, 0x5742, 0xDBE1, 0x5769, 0xDBE2, 0x5785, + 0xDBE3, 0x576B, 0xDBE4, 0x5786, 0xDBE5, 0x577C, 0xDBE6, 0x577B, + 0xDBE7, 0x5768, 0xDBE8, 0x576D, 0xDBE9, 0x5776, 0xDBEA, 0x5773, + 0xDBEB, 0x57AD, 0xDBEC, 0x57A4, 0xDBED, 0x578C, 0xDBEE, 0x57B2, + 0xDBEF, 0x57CF, 0xDBF0, 0x57A7, 0xDBF1, 0x57B4, 0xDBF2, 0x5793, + 0xDBF3, 0x57A0, 0xDBF4, 0x57D5, 0xDBF5, 0x57D8, 0xDBF6, 0x57DA, + 0xDBF7, 0x57D9, 0xDBF8, 0x57D2, 0xDBF9, 0x57B8, 0xDBFA, 0x57F4, + 0xDBFB, 0x57EF, 0xDBFC, 0x57F8, 0xDBFD, 0x57E4, 0xDBFE, 0x57DD, + 0xDC40, 0x8E73, 0xDC41, 0x8E75, 0xDC42, 0x8E77, 0xDC43, 0x8E78, + 0xDC44, 0x8E79, 0xDC45, 0x8E7A, 0xDC46, 0x8E7B, 0xDC47, 0x8E7D, + 0xDC48, 0x8E7E, 0xDC49, 0x8E80, 0xDC4A, 0x8E82, 0xDC4B, 0x8E83, + 0xDC4C, 0x8E84, 0xDC4D, 0x8E86, 0xDC4E, 0x8E88, 0xDC4F, 0x8E89, + 0xDC50, 0x8E8A, 0xDC51, 0x8E8B, 0xDC52, 0x8E8C, 0xDC53, 0x8E8D, + 0xDC54, 0x8E8E, 0xDC55, 0x8E91, 0xDC56, 0x8E92, 0xDC57, 0x8E93, + 0xDC58, 0x8E95, 0xDC59, 0x8E96, 0xDC5A, 0x8E97, 0xDC5B, 0x8E98, + 0xDC5C, 0x8E99, 0xDC5D, 0x8E9A, 0xDC5E, 0x8E9B, 0xDC5F, 0x8E9D, + 0xDC60, 0x8E9F, 0xDC61, 0x8EA0, 0xDC62, 0x8EA1, 0xDC63, 0x8EA2, + 0xDC64, 0x8EA3, 0xDC65, 0x8EA4, 0xDC66, 0x8EA5, 0xDC67, 0x8EA6, + 0xDC68, 0x8EA7, 0xDC69, 0x8EA8, 0xDC6A, 0x8EA9, 0xDC6B, 0x8EAA, + 0xDC6C, 0x8EAD, 0xDC6D, 0x8EAE, 0xDC6E, 0x8EB0, 0xDC6F, 0x8EB1, + 0xDC70, 0x8EB3, 0xDC71, 0x8EB4, 0xDC72, 0x8EB5, 0xDC73, 0x8EB6, + 0xDC74, 0x8EB7, 0xDC75, 0x8EB8, 0xDC76, 0x8EB9, 0xDC77, 0x8EBB, + 0xDC78, 0x8EBC, 0xDC79, 0x8EBD, 0xDC7A, 0x8EBE, 0xDC7B, 0x8EBF, + 0xDC7C, 0x8EC0, 0xDC7D, 0x8EC1, 0xDC7E, 0x8EC2, 0xDC80, 0x8EC3, + 0xDC81, 0x8EC4, 0xDC82, 0x8EC5, 0xDC83, 0x8EC6, 0xDC84, 0x8EC7, + 0xDC85, 0x8EC8, 0xDC86, 0x8EC9, 0xDC87, 0x8ECA, 0xDC88, 0x8ECB, + 0xDC89, 0x8ECC, 0xDC8A, 0x8ECD, 0xDC8B, 0x8ECF, 0xDC8C, 0x8ED0, + 0xDC8D, 0x8ED1, 0xDC8E, 0x8ED2, 0xDC8F, 0x8ED3, 0xDC90, 0x8ED4, + 0xDC91, 0x8ED5, 0xDC92, 0x8ED6, 0xDC93, 0x8ED7, 0xDC94, 0x8ED8, + 0xDC95, 0x8ED9, 0xDC96, 0x8EDA, 0xDC97, 0x8EDB, 0xDC98, 0x8EDC, + 0xDC99, 0x8EDD, 0xDC9A, 0x8EDE, 0xDC9B, 0x8EDF, 0xDC9C, 0x8EE0, + 0xDC9D, 0x8EE1, 0xDC9E, 0x8EE2, 0xDC9F, 0x8EE3, 0xDCA0, 0x8EE4, + 0xDCA1, 0x580B, 0xDCA2, 0x580D, 0xDCA3, 0x57FD, 0xDCA4, 0x57ED, + 0xDCA5, 0x5800, 0xDCA6, 0x581E, 0xDCA7, 0x5819, 0xDCA8, 0x5844, + 0xDCA9, 0x5820, 0xDCAA, 0x5865, 0xDCAB, 0x586C, 0xDCAC, 0x5881, + 0xDCAD, 0x5889, 0xDCAE, 0x589A, 0xDCAF, 0x5880, 0xDCB0, 0x99A8, + 0xDCB1, 0x9F19, 0xDCB2, 0x61FF, 0xDCB3, 0x8279, 0xDCB4, 0x827D, + 0xDCB5, 0x827F, 0xDCB6, 0x828F, 0xDCB7, 0x828A, 0xDCB8, 0x82A8, + 0xDCB9, 0x8284, 0xDCBA, 0x828E, 0xDCBB, 0x8291, 0xDCBC, 0x8297, + 0xDCBD, 0x8299, 0xDCBE, 0x82AB, 0xDCBF, 0x82B8, 0xDCC0, 0x82BE, + 0xDCC1, 0x82B0, 0xDCC2, 0x82C8, 0xDCC3, 0x82CA, 0xDCC4, 0x82E3, + 0xDCC5, 0x8298, 0xDCC6, 0x82B7, 0xDCC7, 0x82AE, 0xDCC8, 0x82CB, + 0xDCC9, 0x82CC, 0xDCCA, 0x82C1, 0xDCCB, 0x82A9, 0xDCCC, 0x82B4, + 0xDCCD, 0x82A1, 0xDCCE, 0x82AA, 0xDCCF, 0x829F, 0xDCD0, 0x82C4, + 0xDCD1, 0x82CE, 0xDCD2, 0x82A4, 0xDCD3, 0x82E1, 0xDCD4, 0x8309, + 0xDCD5, 0x82F7, 0xDCD6, 0x82E4, 0xDCD7, 0x830F, 0xDCD8, 0x8307, + 0xDCD9, 0x82DC, 0xDCDA, 0x82F4, 0xDCDB, 0x82D2, 0xDCDC, 0x82D8, + 0xDCDD, 0x830C, 0xDCDE, 0x82FB, 0xDCDF, 0x82D3, 0xDCE0, 0x8311, + 0xDCE1, 0x831A, 0xDCE2, 0x8306, 0xDCE3, 0x8314, 0xDCE4, 0x8315, + 0xDCE5, 0x82E0, 0xDCE6, 0x82D5, 0xDCE7, 0x831C, 0xDCE8, 0x8351, + 0xDCE9, 0x835B, 0xDCEA, 0x835C, 0xDCEB, 0x8308, 0xDCEC, 0x8392, + 0xDCED, 0x833C, 0xDCEE, 0x8334, 0xDCEF, 0x8331, 0xDCF0, 0x839B, + 0xDCF1, 0x835E, 0xDCF2, 0x832F, 0xDCF3, 0x834F, 0xDCF4, 0x8347, + 0xDCF5, 0x8343, 0xDCF6, 0x835F, 0xDCF7, 0x8340, 0xDCF8, 0x8317, + 0xDCF9, 0x8360, 0xDCFA, 0x832D, 0xDCFB, 0x833A, 0xDCFC, 0x8333, + 0xDCFD, 0x8366, 0xDCFE, 0x8365, 0xDD40, 0x8EE5, 0xDD41, 0x8EE6, + 0xDD42, 0x8EE7, 0xDD43, 0x8EE8, 0xDD44, 0x8EE9, 0xDD45, 0x8EEA, + 0xDD46, 0x8EEB, 0xDD47, 0x8EEC, 0xDD48, 0x8EED, 0xDD49, 0x8EEE, + 0xDD4A, 0x8EEF, 0xDD4B, 0x8EF0, 0xDD4C, 0x8EF1, 0xDD4D, 0x8EF2, + 0xDD4E, 0x8EF3, 0xDD4F, 0x8EF4, 0xDD50, 0x8EF5, 0xDD51, 0x8EF6, + 0xDD52, 0x8EF7, 0xDD53, 0x8EF8, 0xDD54, 0x8EF9, 0xDD55, 0x8EFA, + 0xDD56, 0x8EFB, 0xDD57, 0x8EFC, 0xDD58, 0x8EFD, 0xDD59, 0x8EFE, + 0xDD5A, 0x8EFF, 0xDD5B, 0x8F00, 0xDD5C, 0x8F01, 0xDD5D, 0x8F02, + 0xDD5E, 0x8F03, 0xDD5F, 0x8F04, 0xDD60, 0x8F05, 0xDD61, 0x8F06, + 0xDD62, 0x8F07, 0xDD63, 0x8F08, 0xDD64, 0x8F09, 0xDD65, 0x8F0A, + 0xDD66, 0x8F0B, 0xDD67, 0x8F0C, 0xDD68, 0x8F0D, 0xDD69, 0x8F0E, + 0xDD6A, 0x8F0F, 0xDD6B, 0x8F10, 0xDD6C, 0x8F11, 0xDD6D, 0x8F12, + 0xDD6E, 0x8F13, 0xDD6F, 0x8F14, 0xDD70, 0x8F15, 0xDD71, 0x8F16, + 0xDD72, 0x8F17, 0xDD73, 0x8F18, 0xDD74, 0x8F19, 0xDD75, 0x8F1A, + 0xDD76, 0x8F1B, 0xDD77, 0x8F1C, 0xDD78, 0x8F1D, 0xDD79, 0x8F1E, + 0xDD7A, 0x8F1F, 0xDD7B, 0x8F20, 0xDD7C, 0x8F21, 0xDD7D, 0x8F22, + 0xDD7E, 0x8F23, 0xDD80, 0x8F24, 0xDD81, 0x8F25, 0xDD82, 0x8F26, + 0xDD83, 0x8F27, 0xDD84, 0x8F28, 0xDD85, 0x8F29, 0xDD86, 0x8F2A, + 0xDD87, 0x8F2B, 0xDD88, 0x8F2C, 0xDD89, 0x8F2D, 0xDD8A, 0x8F2E, + 0xDD8B, 0x8F2F, 0xDD8C, 0x8F30, 0xDD8D, 0x8F31, 0xDD8E, 0x8F32, + 0xDD8F, 0x8F33, 0xDD90, 0x8F34, 0xDD91, 0x8F35, 0xDD92, 0x8F36, + 0xDD93, 0x8F37, 0xDD94, 0x8F38, 0xDD95, 0x8F39, 0xDD96, 0x8F3A, + 0xDD97, 0x8F3B, 0xDD98, 0x8F3C, 0xDD99, 0x8F3D, 0xDD9A, 0x8F3E, + 0xDD9B, 0x8F3F, 0xDD9C, 0x8F40, 0xDD9D, 0x8F41, 0xDD9E, 0x8F42, + 0xDD9F, 0x8F43, 0xDDA0, 0x8F44, 0xDDA1, 0x8368, 0xDDA2, 0x831B, + 0xDDA3, 0x8369, 0xDDA4, 0x836C, 0xDDA5, 0x836A, 0xDDA6, 0x836D, + 0xDDA7, 0x836E, 0xDDA8, 0x83B0, 0xDDA9, 0x8378, 0xDDAA, 0x83B3, + 0xDDAB, 0x83B4, 0xDDAC, 0x83A0, 0xDDAD, 0x83AA, 0xDDAE, 0x8393, + 0xDDAF, 0x839C, 0xDDB0, 0x8385, 0xDDB1, 0x837C, 0xDDB2, 0x83B6, + 0xDDB3, 0x83A9, 0xDDB4, 0x837D, 0xDDB5, 0x83B8, 0xDDB6, 0x837B, + 0xDDB7, 0x8398, 0xDDB8, 0x839E, 0xDDB9, 0x83A8, 0xDDBA, 0x83BA, + 0xDDBB, 0x83BC, 0xDDBC, 0x83C1, 0xDDBD, 0x8401, 0xDDBE, 0x83E5, + 0xDDBF, 0x83D8, 0xDDC0, 0x5807, 0xDDC1, 0x8418, 0xDDC2, 0x840B, + 0xDDC3, 0x83DD, 0xDDC4, 0x83FD, 0xDDC5, 0x83D6, 0xDDC6, 0x841C, + 0xDDC7, 0x8438, 0xDDC8, 0x8411, 0xDDC9, 0x8406, 0xDDCA, 0x83D4, + 0xDDCB, 0x83DF, 0xDDCC, 0x840F, 0xDDCD, 0x8403, 0xDDCE, 0x83F8, + 0xDDCF, 0x83F9, 0xDDD0, 0x83EA, 0xDDD1, 0x83C5, 0xDDD2, 0x83C0, + 0xDDD3, 0x8426, 0xDDD4, 0x83F0, 0xDDD5, 0x83E1, 0xDDD6, 0x845C, + 0xDDD7, 0x8451, 0xDDD8, 0x845A, 0xDDD9, 0x8459, 0xDDDA, 0x8473, + 0xDDDB, 0x8487, 0xDDDC, 0x8488, 0xDDDD, 0x847A, 0xDDDE, 0x8489, + 0xDDDF, 0x8478, 0xDDE0, 0x843C, 0xDDE1, 0x8446, 0xDDE2, 0x8469, + 0xDDE3, 0x8476, 0xDDE4, 0x848C, 0xDDE5, 0x848E, 0xDDE6, 0x8431, + 0xDDE7, 0x846D, 0xDDE8, 0x84C1, 0xDDE9, 0x84CD, 0xDDEA, 0x84D0, + 0xDDEB, 0x84E6, 0xDDEC, 0x84BD, 0xDDED, 0x84D3, 0xDDEE, 0x84CA, + 0xDDEF, 0x84BF, 0xDDF0, 0x84BA, 0xDDF1, 0x84E0, 0xDDF2, 0x84A1, + 0xDDF3, 0x84B9, 0xDDF4, 0x84B4, 0xDDF5, 0x8497, 0xDDF6, 0x84E5, + 0xDDF7, 0x84E3, 0xDDF8, 0x850C, 0xDDF9, 0x750D, 0xDDFA, 0x8538, + 0xDDFB, 0x84F0, 0xDDFC, 0x8539, 0xDDFD, 0x851F, 0xDDFE, 0x853A, + 0xDE40, 0x8F45, 0xDE41, 0x8F46, 0xDE42, 0x8F47, 0xDE43, 0x8F48, + 0xDE44, 0x8F49, 0xDE45, 0x8F4A, 0xDE46, 0x8F4B, 0xDE47, 0x8F4C, + 0xDE48, 0x8F4D, 0xDE49, 0x8F4E, 0xDE4A, 0x8F4F, 0xDE4B, 0x8F50, + 0xDE4C, 0x8F51, 0xDE4D, 0x8F52, 0xDE4E, 0x8F53, 0xDE4F, 0x8F54, + 0xDE50, 0x8F55, 0xDE51, 0x8F56, 0xDE52, 0x8F57, 0xDE53, 0x8F58, + 0xDE54, 0x8F59, 0xDE55, 0x8F5A, 0xDE56, 0x8F5B, 0xDE57, 0x8F5C, + 0xDE58, 0x8F5D, 0xDE59, 0x8F5E, 0xDE5A, 0x8F5F, 0xDE5B, 0x8F60, + 0xDE5C, 0x8F61, 0xDE5D, 0x8F62, 0xDE5E, 0x8F63, 0xDE5F, 0x8F64, + 0xDE60, 0x8F65, 0xDE61, 0x8F6A, 0xDE62, 0x8F80, 0xDE63, 0x8F8C, + 0xDE64, 0x8F92, 0xDE65, 0x8F9D, 0xDE66, 0x8FA0, 0xDE67, 0x8FA1, + 0xDE68, 0x8FA2, 0xDE69, 0x8FA4, 0xDE6A, 0x8FA5, 0xDE6B, 0x8FA6, + 0xDE6C, 0x8FA7, 0xDE6D, 0x8FAA, 0xDE6E, 0x8FAC, 0xDE6F, 0x8FAD, + 0xDE70, 0x8FAE, 0xDE71, 0x8FAF, 0xDE72, 0x8FB2, 0xDE73, 0x8FB3, + 0xDE74, 0x8FB4, 0xDE75, 0x8FB5, 0xDE76, 0x8FB7, 0xDE77, 0x8FB8, + 0xDE78, 0x8FBA, 0xDE79, 0x8FBB, 0xDE7A, 0x8FBC, 0xDE7B, 0x8FBF, + 0xDE7C, 0x8FC0, 0xDE7D, 0x8FC3, 0xDE7E, 0x8FC6, 0xDE80, 0x8FC9, + 0xDE81, 0x8FCA, 0xDE82, 0x8FCB, 0xDE83, 0x8FCC, 0xDE84, 0x8FCD, + 0xDE85, 0x8FCF, 0xDE86, 0x8FD2, 0xDE87, 0x8FD6, 0xDE88, 0x8FD7, + 0xDE89, 0x8FDA, 0xDE8A, 0x8FE0, 0xDE8B, 0x8FE1, 0xDE8C, 0x8FE3, + 0xDE8D, 0x8FE7, 0xDE8E, 0x8FEC, 0xDE8F, 0x8FEF, 0xDE90, 0x8FF1, + 0xDE91, 0x8FF2, 0xDE92, 0x8FF4, 0xDE93, 0x8FF5, 0xDE94, 0x8FF6, + 0xDE95, 0x8FFA, 0xDE96, 0x8FFB, 0xDE97, 0x8FFC, 0xDE98, 0x8FFE, + 0xDE99, 0x8FFF, 0xDE9A, 0x9007, 0xDE9B, 0x9008, 0xDE9C, 0x900C, + 0xDE9D, 0x900E, 0xDE9E, 0x9013, 0xDE9F, 0x9015, 0xDEA0, 0x9018, + 0xDEA1, 0x8556, 0xDEA2, 0x853B, 0xDEA3, 0x84FF, 0xDEA4, 0x84FC, + 0xDEA5, 0x8559, 0xDEA6, 0x8548, 0xDEA7, 0x8568, 0xDEA8, 0x8564, + 0xDEA9, 0x855E, 0xDEAA, 0x857A, 0xDEAB, 0x77A2, 0xDEAC, 0x8543, + 0xDEAD, 0x8572, 0xDEAE, 0x857B, 0xDEAF, 0x85A4, 0xDEB0, 0x85A8, + 0xDEB1, 0x8587, 0xDEB2, 0x858F, 0xDEB3, 0x8579, 0xDEB4, 0x85AE, + 0xDEB5, 0x859C, 0xDEB6, 0x8585, 0xDEB7, 0x85B9, 0xDEB8, 0x85B7, + 0xDEB9, 0x85B0, 0xDEBA, 0x85D3, 0xDEBB, 0x85C1, 0xDEBC, 0x85DC, + 0xDEBD, 0x85FF, 0xDEBE, 0x8627, 0xDEBF, 0x8605, 0xDEC0, 0x8629, + 0xDEC1, 0x8616, 0xDEC2, 0x863C, 0xDEC3, 0x5EFE, 0xDEC4, 0x5F08, + 0xDEC5, 0x593C, 0xDEC6, 0x5941, 0xDEC7, 0x8037, 0xDEC8, 0x5955, + 0xDEC9, 0x595A, 0xDECA, 0x5958, 0xDECB, 0x530F, 0xDECC, 0x5C22, + 0xDECD, 0x5C25, 0xDECE, 0x5C2C, 0xDECF, 0x5C34, 0xDED0, 0x624C, + 0xDED1, 0x626A, 0xDED2, 0x629F, 0xDED3, 0x62BB, 0xDED4, 0x62CA, + 0xDED5, 0x62DA, 0xDED6, 0x62D7, 0xDED7, 0x62EE, 0xDED8, 0x6322, + 0xDED9, 0x62F6, 0xDEDA, 0x6339, 0xDEDB, 0x634B, 0xDEDC, 0x6343, + 0xDEDD, 0x63AD, 0xDEDE, 0x63F6, 0xDEDF, 0x6371, 0xDEE0, 0x637A, + 0xDEE1, 0x638E, 0xDEE2, 0x63B4, 0xDEE3, 0x636D, 0xDEE4, 0x63AC, + 0xDEE5, 0x638A, 0xDEE6, 0x6369, 0xDEE7, 0x63AE, 0xDEE8, 0x63BC, + 0xDEE9, 0x63F2, 0xDEEA, 0x63F8, 0xDEEB, 0x63E0, 0xDEEC, 0x63FF, + 0xDEED, 0x63C4, 0xDEEE, 0x63DE, 0xDEEF, 0x63CE, 0xDEF0, 0x6452, + 0xDEF1, 0x63C6, 0xDEF2, 0x63BE, 0xDEF3, 0x6445, 0xDEF4, 0x6441, + 0xDEF5, 0x640B, 0xDEF6, 0x641B, 0xDEF7, 0x6420, 0xDEF8, 0x640C, + 0xDEF9, 0x6426, 0xDEFA, 0x6421, 0xDEFB, 0x645E, 0xDEFC, 0x6484, + 0xDEFD, 0x646D, 0xDEFE, 0x6496, 0xDF40, 0x9019, 0xDF41, 0x901C, + 0xDF42, 0x9023, 0xDF43, 0x9024, 0xDF44, 0x9025, 0xDF45, 0x9027, + 0xDF46, 0x9028, 0xDF47, 0x9029, 0xDF48, 0x902A, 0xDF49, 0x902B, + 0xDF4A, 0x902C, 0xDF4B, 0x9030, 0xDF4C, 0x9031, 0xDF4D, 0x9032, + 0xDF4E, 0x9033, 0xDF4F, 0x9034, 0xDF50, 0x9037, 0xDF51, 0x9039, + 0xDF52, 0x903A, 0xDF53, 0x903D, 0xDF54, 0x903F, 0xDF55, 0x9040, + 0xDF56, 0x9043, 0xDF57, 0x9045, 0xDF58, 0x9046, 0xDF59, 0x9048, + 0xDF5A, 0x9049, 0xDF5B, 0x904A, 0xDF5C, 0x904B, 0xDF5D, 0x904C, + 0xDF5E, 0x904E, 0xDF5F, 0x9054, 0xDF60, 0x9055, 0xDF61, 0x9056, + 0xDF62, 0x9059, 0xDF63, 0x905A, 0xDF64, 0x905C, 0xDF65, 0x905D, + 0xDF66, 0x905E, 0xDF67, 0x905F, 0xDF68, 0x9060, 0xDF69, 0x9061, + 0xDF6A, 0x9064, 0xDF6B, 0x9066, 0xDF6C, 0x9067, 0xDF6D, 0x9069, + 0xDF6E, 0x906A, 0xDF6F, 0x906B, 0xDF70, 0x906C, 0xDF71, 0x906F, + 0xDF72, 0x9070, 0xDF73, 0x9071, 0xDF74, 0x9072, 0xDF75, 0x9073, + 0xDF76, 0x9076, 0xDF77, 0x9077, 0xDF78, 0x9078, 0xDF79, 0x9079, + 0xDF7A, 0x907A, 0xDF7B, 0x907B, 0xDF7C, 0x907C, 0xDF7D, 0x907E, + 0xDF7E, 0x9081, 0xDF80, 0x9084, 0xDF81, 0x9085, 0xDF82, 0x9086, + 0xDF83, 0x9087, 0xDF84, 0x9089, 0xDF85, 0x908A, 0xDF86, 0x908C, + 0xDF87, 0x908D, 0xDF88, 0x908E, 0xDF89, 0x908F, 0xDF8A, 0x9090, + 0xDF8B, 0x9092, 0xDF8C, 0x9094, 0xDF8D, 0x9096, 0xDF8E, 0x9098, + 0xDF8F, 0x909A, 0xDF90, 0x909C, 0xDF91, 0x909E, 0xDF92, 0x909F, + 0xDF93, 0x90A0, 0xDF94, 0x90A4, 0xDF95, 0x90A5, 0xDF96, 0x90A7, + 0xDF97, 0x90A8, 0xDF98, 0x90A9, 0xDF99, 0x90AB, 0xDF9A, 0x90AD, + 0xDF9B, 0x90B2, 0xDF9C, 0x90B7, 0xDF9D, 0x90BC, 0xDF9E, 0x90BD, + 0xDF9F, 0x90BF, 0xDFA0, 0x90C0, 0xDFA1, 0x647A, 0xDFA2, 0x64B7, + 0xDFA3, 0x64B8, 0xDFA4, 0x6499, 0xDFA5, 0x64BA, 0xDFA6, 0x64C0, + 0xDFA7, 0x64D0, 0xDFA8, 0x64D7, 0xDFA9, 0x64E4, 0xDFAA, 0x64E2, + 0xDFAB, 0x6509, 0xDFAC, 0x6525, 0xDFAD, 0x652E, 0xDFAE, 0x5F0B, + 0xDFAF, 0x5FD2, 0xDFB0, 0x7519, 0xDFB1, 0x5F11, 0xDFB2, 0x535F, + 0xDFB3, 0x53F1, 0xDFB4, 0x53FD, 0xDFB5, 0x53E9, 0xDFB6, 0x53E8, + 0xDFB7, 0x53FB, 0xDFB8, 0x5412, 0xDFB9, 0x5416, 0xDFBA, 0x5406, + 0xDFBB, 0x544B, 0xDFBC, 0x5452, 0xDFBD, 0x5453, 0xDFBE, 0x5454, + 0xDFBF, 0x5456, 0xDFC0, 0x5443, 0xDFC1, 0x5421, 0xDFC2, 0x5457, + 0xDFC3, 0x5459, 0xDFC4, 0x5423, 0xDFC5, 0x5432, 0xDFC6, 0x5482, + 0xDFC7, 0x5494, 0xDFC8, 0x5477, 0xDFC9, 0x5471, 0xDFCA, 0x5464, + 0xDFCB, 0x549A, 0xDFCC, 0x549B, 0xDFCD, 0x5484, 0xDFCE, 0x5476, + 0xDFCF, 0x5466, 0xDFD0, 0x549D, 0xDFD1, 0x54D0, 0xDFD2, 0x54AD, + 0xDFD3, 0x54C2, 0xDFD4, 0x54B4, 0xDFD5, 0x54D2, 0xDFD6, 0x54A7, + 0xDFD7, 0x54A6, 0xDFD8, 0x54D3, 0xDFD9, 0x54D4, 0xDFDA, 0x5472, + 0xDFDB, 0x54A3, 0xDFDC, 0x54D5, 0xDFDD, 0x54BB, 0xDFDE, 0x54BF, + 0xDFDF, 0x54CC, 0xDFE0, 0x54D9, 0xDFE1, 0x54DA, 0xDFE2, 0x54DC, + 0xDFE3, 0x54A9, 0xDFE4, 0x54AA, 0xDFE5, 0x54A4, 0xDFE6, 0x54DD, + 0xDFE7, 0x54CF, 0xDFE8, 0x54DE, 0xDFE9, 0x551B, 0xDFEA, 0x54E7, + 0xDFEB, 0x5520, 0xDFEC, 0x54FD, 0xDFED, 0x5514, 0xDFEE, 0x54F3, + 0xDFEF, 0x5522, 0xDFF0, 0x5523, 0xDFF1, 0x550F, 0xDFF2, 0x5511, + 0xDFF3, 0x5527, 0xDFF4, 0x552A, 0xDFF5, 0x5567, 0xDFF6, 0x558F, + 0xDFF7, 0x55B5, 0xDFF8, 0x5549, 0xDFF9, 0x556D, 0xDFFA, 0x5541, + 0xDFFB, 0x5555, 0xDFFC, 0x553F, 0xDFFD, 0x5550, 0xDFFE, 0x553C, + 0xE040, 0x90C2, 0xE041, 0x90C3, 0xE042, 0x90C6, 0xE043, 0x90C8, + 0xE044, 0x90C9, 0xE045, 0x90CB, 0xE046, 0x90CC, 0xE047, 0x90CD, + 0xE048, 0x90D2, 0xE049, 0x90D4, 0xE04A, 0x90D5, 0xE04B, 0x90D6, + 0xE04C, 0x90D8, 0xE04D, 0x90D9, 0xE04E, 0x90DA, 0xE04F, 0x90DE, + 0xE050, 0x90DF, 0xE051, 0x90E0, 0xE052, 0x90E3, 0xE053, 0x90E4, + 0xE054, 0x90E5, 0xE055, 0x90E9, 0xE056, 0x90EA, 0xE057, 0x90EC, + 0xE058, 0x90EE, 0xE059, 0x90F0, 0xE05A, 0x90F1, 0xE05B, 0x90F2, + 0xE05C, 0x90F3, 0xE05D, 0x90F5, 0xE05E, 0x90F6, 0xE05F, 0x90F7, + 0xE060, 0x90F9, 0xE061, 0x90FA, 0xE062, 0x90FB, 0xE063, 0x90FC, + 0xE064, 0x90FF, 0xE065, 0x9100, 0xE066, 0x9101, 0xE067, 0x9103, + 0xE068, 0x9105, 0xE069, 0x9106, 0xE06A, 0x9107, 0xE06B, 0x9108, + 0xE06C, 0x9109, 0xE06D, 0x910A, 0xE06E, 0x910B, 0xE06F, 0x910C, + 0xE070, 0x910D, 0xE071, 0x910E, 0xE072, 0x910F, 0xE073, 0x9110, + 0xE074, 0x9111, 0xE075, 0x9112, 0xE076, 0x9113, 0xE077, 0x9114, + 0xE078, 0x9115, 0xE079, 0x9116, 0xE07A, 0x9117, 0xE07B, 0x9118, + 0xE07C, 0x911A, 0xE07D, 0x911B, 0xE07E, 0x911C, 0xE080, 0x911D, + 0xE081, 0x911F, 0xE082, 0x9120, 0xE083, 0x9121, 0xE084, 0x9124, + 0xE085, 0x9125, 0xE086, 0x9126, 0xE087, 0x9127, 0xE088, 0x9128, + 0xE089, 0x9129, 0xE08A, 0x912A, 0xE08B, 0x912B, 0xE08C, 0x912C, + 0xE08D, 0x912D, 0xE08E, 0x912E, 0xE08F, 0x9130, 0xE090, 0x9132, + 0xE091, 0x9133, 0xE092, 0x9134, 0xE093, 0x9135, 0xE094, 0x9136, + 0xE095, 0x9137, 0xE096, 0x9138, 0xE097, 0x913A, 0xE098, 0x913B, + 0xE099, 0x913C, 0xE09A, 0x913D, 0xE09B, 0x913E, 0xE09C, 0x913F, + 0xE09D, 0x9140, 0xE09E, 0x9141, 0xE09F, 0x9142, 0xE0A0, 0x9144, + 0xE0A1, 0x5537, 0xE0A2, 0x5556, 0xE0A3, 0x5575, 0xE0A4, 0x5576, + 0xE0A5, 0x5577, 0xE0A6, 0x5533, 0xE0A7, 0x5530, 0xE0A8, 0x555C, + 0xE0A9, 0x558B, 0xE0AA, 0x55D2, 0xE0AB, 0x5583, 0xE0AC, 0x55B1, + 0xE0AD, 0x55B9, 0xE0AE, 0x5588, 0xE0AF, 0x5581, 0xE0B0, 0x559F, + 0xE0B1, 0x557E, 0xE0B2, 0x55D6, 0xE0B3, 0x5591, 0xE0B4, 0x557B, + 0xE0B5, 0x55DF, 0xE0B6, 0x55BD, 0xE0B7, 0x55BE, 0xE0B8, 0x5594, + 0xE0B9, 0x5599, 0xE0BA, 0x55EA, 0xE0BB, 0x55F7, 0xE0BC, 0x55C9, + 0xE0BD, 0x561F, 0xE0BE, 0x55D1, 0xE0BF, 0x55EB, 0xE0C0, 0x55EC, + 0xE0C1, 0x55D4, 0xE0C2, 0x55E6, 0xE0C3, 0x55DD, 0xE0C4, 0x55C4, + 0xE0C5, 0x55EF, 0xE0C6, 0x55E5, 0xE0C7, 0x55F2, 0xE0C8, 0x55F3, + 0xE0C9, 0x55CC, 0xE0CA, 0x55CD, 0xE0CB, 0x55E8, 0xE0CC, 0x55F5, + 0xE0CD, 0x55E4, 0xE0CE, 0x8F94, 0xE0CF, 0x561E, 0xE0D0, 0x5608, + 0xE0D1, 0x560C, 0xE0D2, 0x5601, 0xE0D3, 0x5624, 0xE0D4, 0x5623, + 0xE0D5, 0x55FE, 0xE0D6, 0x5600, 0xE0D7, 0x5627, 0xE0D8, 0x562D, + 0xE0D9, 0x5658, 0xE0DA, 0x5639, 0xE0DB, 0x5657, 0xE0DC, 0x562C, + 0xE0DD, 0x564D, 0xE0DE, 0x5662, 0xE0DF, 0x5659, 0xE0E0, 0x565C, + 0xE0E1, 0x564C, 0xE0E2, 0x5654, 0xE0E3, 0x5686, 0xE0E4, 0x5664, + 0xE0E5, 0x5671, 0xE0E6, 0x566B, 0xE0E7, 0x567B, 0xE0E8, 0x567C, + 0xE0E9, 0x5685, 0xE0EA, 0x5693, 0xE0EB, 0x56AF, 0xE0EC, 0x56D4, + 0xE0ED, 0x56D7, 0xE0EE, 0x56DD, 0xE0EF, 0x56E1, 0xE0F0, 0x56F5, + 0xE0F1, 0x56EB, 0xE0F2, 0x56F9, 0xE0F3, 0x56FF, 0xE0F4, 0x5704, + 0xE0F5, 0x570A, 0xE0F6, 0x5709, 0xE0F7, 0x571C, 0xE0F8, 0x5E0F, + 0xE0F9, 0x5E19, 0xE0FA, 0x5E14, 0xE0FB, 0x5E11, 0xE0FC, 0x5E31, + 0xE0FD, 0x5E3B, 0xE0FE, 0x5E3C, 0xE140, 0x9145, 0xE141, 0x9147, + 0xE142, 0x9148, 0xE143, 0x9151, 0xE144, 0x9153, 0xE145, 0x9154, + 0xE146, 0x9155, 0xE147, 0x9156, 0xE148, 0x9158, 0xE149, 0x9159, + 0xE14A, 0x915B, 0xE14B, 0x915C, 0xE14C, 0x915F, 0xE14D, 0x9160, + 0xE14E, 0x9166, 0xE14F, 0x9167, 0xE150, 0x9168, 0xE151, 0x916B, + 0xE152, 0x916D, 0xE153, 0x9173, 0xE154, 0x917A, 0xE155, 0x917B, + 0xE156, 0x917C, 0xE157, 0x9180, 0xE158, 0x9181, 0xE159, 0x9182, + 0xE15A, 0x9183, 0xE15B, 0x9184, 0xE15C, 0x9186, 0xE15D, 0x9188, + 0xE15E, 0x918A, 0xE15F, 0x918E, 0xE160, 0x918F, 0xE161, 0x9193, + 0xE162, 0x9194, 0xE163, 0x9195, 0xE164, 0x9196, 0xE165, 0x9197, + 0xE166, 0x9198, 0xE167, 0x9199, 0xE168, 0x919C, 0xE169, 0x919D, + 0xE16A, 0x919E, 0xE16B, 0x919F, 0xE16C, 0x91A0, 0xE16D, 0x91A1, + 0xE16E, 0x91A4, 0xE16F, 0x91A5, 0xE170, 0x91A6, 0xE171, 0x91A7, + 0xE172, 0x91A8, 0xE173, 0x91A9, 0xE174, 0x91AB, 0xE175, 0x91AC, + 0xE176, 0x91B0, 0xE177, 0x91B1, 0xE178, 0x91B2, 0xE179, 0x91B3, + 0xE17A, 0x91B6, 0xE17B, 0x91B7, 0xE17C, 0x91B8, 0xE17D, 0x91B9, + 0xE17E, 0x91BB, 0xE180, 0x91BC, 0xE181, 0x91BD, 0xE182, 0x91BE, + 0xE183, 0x91BF, 0xE184, 0x91C0, 0xE185, 0x91C1, 0xE186, 0x91C2, + 0xE187, 0x91C3, 0xE188, 0x91C4, 0xE189, 0x91C5, 0xE18A, 0x91C6, + 0xE18B, 0x91C8, 0xE18C, 0x91CB, 0xE18D, 0x91D0, 0xE18E, 0x91D2, + 0xE18F, 0x91D3, 0xE190, 0x91D4, 0xE191, 0x91D5, 0xE192, 0x91D6, + 0xE193, 0x91D7, 0xE194, 0x91D8, 0xE195, 0x91D9, 0xE196, 0x91DA, + 0xE197, 0x91DB, 0xE198, 0x91DD, 0xE199, 0x91DE, 0xE19A, 0x91DF, + 0xE19B, 0x91E0, 0xE19C, 0x91E1, 0xE19D, 0x91E2, 0xE19E, 0x91E3, + 0xE19F, 0x91E4, 0xE1A0, 0x91E5, 0xE1A1, 0x5E37, 0xE1A2, 0x5E44, + 0xE1A3, 0x5E54, 0xE1A4, 0x5E5B, 0xE1A5, 0x5E5E, 0xE1A6, 0x5E61, + 0xE1A7, 0x5C8C, 0xE1A8, 0x5C7A, 0xE1A9, 0x5C8D, 0xE1AA, 0x5C90, + 0xE1AB, 0x5C96, 0xE1AC, 0x5C88, 0xE1AD, 0x5C98, 0xE1AE, 0x5C99, + 0xE1AF, 0x5C91, 0xE1B0, 0x5C9A, 0xE1B1, 0x5C9C, 0xE1B2, 0x5CB5, + 0xE1B3, 0x5CA2, 0xE1B4, 0x5CBD, 0xE1B5, 0x5CAC, 0xE1B6, 0x5CAB, + 0xE1B7, 0x5CB1, 0xE1B8, 0x5CA3, 0xE1B9, 0x5CC1, 0xE1BA, 0x5CB7, + 0xE1BB, 0x5CC4, 0xE1BC, 0x5CD2, 0xE1BD, 0x5CE4, 0xE1BE, 0x5CCB, + 0xE1BF, 0x5CE5, 0xE1C0, 0x5D02, 0xE1C1, 0x5D03, 0xE1C2, 0x5D27, + 0xE1C3, 0x5D26, 0xE1C4, 0x5D2E, 0xE1C5, 0x5D24, 0xE1C6, 0x5D1E, + 0xE1C7, 0x5D06, 0xE1C8, 0x5D1B, 0xE1C9, 0x5D58, 0xE1CA, 0x5D3E, + 0xE1CB, 0x5D34, 0xE1CC, 0x5D3D, 0xE1CD, 0x5D6C, 0xE1CE, 0x5D5B, + 0xE1CF, 0x5D6F, 0xE1D0, 0x5D5D, 0xE1D1, 0x5D6B, 0xE1D2, 0x5D4B, + 0xE1D3, 0x5D4A, 0xE1D4, 0x5D69, 0xE1D5, 0x5D74, 0xE1D6, 0x5D82, + 0xE1D7, 0x5D99, 0xE1D8, 0x5D9D, 0xE1D9, 0x8C73, 0xE1DA, 0x5DB7, + 0xE1DB, 0x5DC5, 0xE1DC, 0x5F73, 0xE1DD, 0x5F77, 0xE1DE, 0x5F82, + 0xE1DF, 0x5F87, 0xE1E0, 0x5F89, 0xE1E1, 0x5F8C, 0xE1E2, 0x5F95, + 0xE1E3, 0x5F99, 0xE1E4, 0x5F9C, 0xE1E5, 0x5FA8, 0xE1E6, 0x5FAD, + 0xE1E7, 0x5FB5, 0xE1E8, 0x5FBC, 0xE1E9, 0x8862, 0xE1EA, 0x5F61, + 0xE1EB, 0x72AD, 0xE1EC, 0x72B0, 0xE1ED, 0x72B4, 0xE1EE, 0x72B7, + 0xE1EF, 0x72B8, 0xE1F0, 0x72C3, 0xE1F1, 0x72C1, 0xE1F2, 0x72CE, + 0xE1F3, 0x72CD, 0xE1F4, 0x72D2, 0xE1F5, 0x72E8, 0xE1F6, 0x72EF, + 0xE1F7, 0x72E9, 0xE1F8, 0x72F2, 0xE1F9, 0x72F4, 0xE1FA, 0x72F7, + 0xE1FB, 0x7301, 0xE1FC, 0x72F3, 0xE1FD, 0x7303, 0xE1FE, 0x72FA, + 0xE240, 0x91E6, 0xE241, 0x91E7, 0xE242, 0x91E8, 0xE243, 0x91E9, + 0xE244, 0x91EA, 0xE245, 0x91EB, 0xE246, 0x91EC, 0xE247, 0x91ED, + 0xE248, 0x91EE, 0xE249, 0x91EF, 0xE24A, 0x91F0, 0xE24B, 0x91F1, + 0xE24C, 0x91F2, 0xE24D, 0x91F3, 0xE24E, 0x91F4, 0xE24F, 0x91F5, + 0xE250, 0x91F6, 0xE251, 0x91F7, 0xE252, 0x91F8, 0xE253, 0x91F9, + 0xE254, 0x91FA, 0xE255, 0x91FB, 0xE256, 0x91FC, 0xE257, 0x91FD, + 0xE258, 0x91FE, 0xE259, 0x91FF, 0xE25A, 0x9200, 0xE25B, 0x9201, + 0xE25C, 0x9202, 0xE25D, 0x9203, 0xE25E, 0x9204, 0xE25F, 0x9205, + 0xE260, 0x9206, 0xE261, 0x9207, 0xE262, 0x9208, 0xE263, 0x9209, + 0xE264, 0x920A, 0xE265, 0x920B, 0xE266, 0x920C, 0xE267, 0x920D, + 0xE268, 0x920E, 0xE269, 0x920F, 0xE26A, 0x9210, 0xE26B, 0x9211, + 0xE26C, 0x9212, 0xE26D, 0x9213, 0xE26E, 0x9214, 0xE26F, 0x9215, + 0xE270, 0x9216, 0xE271, 0x9217, 0xE272, 0x9218, 0xE273, 0x9219, + 0xE274, 0x921A, 0xE275, 0x921B, 0xE276, 0x921C, 0xE277, 0x921D, + 0xE278, 0x921E, 0xE279, 0x921F, 0xE27A, 0x9220, 0xE27B, 0x9221, + 0xE27C, 0x9222, 0xE27D, 0x9223, 0xE27E, 0x9224, 0xE280, 0x9225, + 0xE281, 0x9226, 0xE282, 0x9227, 0xE283, 0x9228, 0xE284, 0x9229, + 0xE285, 0x922A, 0xE286, 0x922B, 0xE287, 0x922C, 0xE288, 0x922D, + 0xE289, 0x922E, 0xE28A, 0x922F, 0xE28B, 0x9230, 0xE28C, 0x9231, + 0xE28D, 0x9232, 0xE28E, 0x9233, 0xE28F, 0x9234, 0xE290, 0x9235, + 0xE291, 0x9236, 0xE292, 0x9237, 0xE293, 0x9238, 0xE294, 0x9239, + 0xE295, 0x923A, 0xE296, 0x923B, 0xE297, 0x923C, 0xE298, 0x923D, + 0xE299, 0x923E, 0xE29A, 0x923F, 0xE29B, 0x9240, 0xE29C, 0x9241, + 0xE29D, 0x9242, 0xE29E, 0x9243, 0xE29F, 0x9244, 0xE2A0, 0x9245, + 0xE2A1, 0x72FB, 0xE2A2, 0x7317, 0xE2A3, 0x7313, 0xE2A4, 0x7321, + 0xE2A5, 0x730A, 0xE2A6, 0x731E, 0xE2A7, 0x731D, 0xE2A8, 0x7315, + 0xE2A9, 0x7322, 0xE2AA, 0x7339, 0xE2AB, 0x7325, 0xE2AC, 0x732C, + 0xE2AD, 0x7338, 0xE2AE, 0x7331, 0xE2AF, 0x7350, 0xE2B0, 0x734D, + 0xE2B1, 0x7357, 0xE2B2, 0x7360, 0xE2B3, 0x736C, 0xE2B4, 0x736F, + 0xE2B5, 0x737E, 0xE2B6, 0x821B, 0xE2B7, 0x5925, 0xE2B8, 0x98E7, + 0xE2B9, 0x5924, 0xE2BA, 0x5902, 0xE2BB, 0x9963, 0xE2BC, 0x9967, + 0xE2BD, 0x9968, 0xE2BE, 0x9969, 0xE2BF, 0x996A, 0xE2C0, 0x996B, + 0xE2C1, 0x996C, 0xE2C2, 0x9974, 0xE2C3, 0x9977, 0xE2C4, 0x997D, + 0xE2C5, 0x9980, 0xE2C6, 0x9984, 0xE2C7, 0x9987, 0xE2C8, 0x998A, + 0xE2C9, 0x998D, 0xE2CA, 0x9990, 0xE2CB, 0x9991, 0xE2CC, 0x9993, + 0xE2CD, 0x9994, 0xE2CE, 0x9995, 0xE2CF, 0x5E80, 0xE2D0, 0x5E91, + 0xE2D1, 0x5E8B, 0xE2D2, 0x5E96, 0xE2D3, 0x5EA5, 0xE2D4, 0x5EA0, + 0xE2D5, 0x5EB9, 0xE2D6, 0x5EB5, 0xE2D7, 0x5EBE, 0xE2D8, 0x5EB3, + 0xE2D9, 0x8D53, 0xE2DA, 0x5ED2, 0xE2DB, 0x5ED1, 0xE2DC, 0x5EDB, + 0xE2DD, 0x5EE8, 0xE2DE, 0x5EEA, 0xE2DF, 0x81BA, 0xE2E0, 0x5FC4, + 0xE2E1, 0x5FC9, 0xE2E2, 0x5FD6, 0xE2E3, 0x5FCF, 0xE2E4, 0x6003, + 0xE2E5, 0x5FEE, 0xE2E6, 0x6004, 0xE2E7, 0x5FE1, 0xE2E8, 0x5FE4, + 0xE2E9, 0x5FFE, 0xE2EA, 0x6005, 0xE2EB, 0x6006, 0xE2EC, 0x5FEA, + 0xE2ED, 0x5FED, 0xE2EE, 0x5FF8, 0xE2EF, 0x6019, 0xE2F0, 0x6035, + 0xE2F1, 0x6026, 0xE2F2, 0x601B, 0xE2F3, 0x600F, 0xE2F4, 0x600D, + 0xE2F5, 0x6029, 0xE2F6, 0x602B, 0xE2F7, 0x600A, 0xE2F8, 0x603F, + 0xE2F9, 0x6021, 0xE2FA, 0x6078, 0xE2FB, 0x6079, 0xE2FC, 0x607B, + 0xE2FD, 0x607A, 0xE2FE, 0x6042, 0xE340, 0x9246, 0xE341, 0x9247, + 0xE342, 0x9248, 0xE343, 0x9249, 0xE344, 0x924A, 0xE345, 0x924B, + 0xE346, 0x924C, 0xE347, 0x924D, 0xE348, 0x924E, 0xE349, 0x924F, + 0xE34A, 0x9250, 0xE34B, 0x9251, 0xE34C, 0x9252, 0xE34D, 0x9253, + 0xE34E, 0x9254, 0xE34F, 0x9255, 0xE350, 0x9256, 0xE351, 0x9257, + 0xE352, 0x9258, 0xE353, 0x9259, 0xE354, 0x925A, 0xE355, 0x925B, + 0xE356, 0x925C, 0xE357, 0x925D, 0xE358, 0x925E, 0xE359, 0x925F, + 0xE35A, 0x9260, 0xE35B, 0x9261, 0xE35C, 0x9262, 0xE35D, 0x9263, + 0xE35E, 0x9264, 0xE35F, 0x9265, 0xE360, 0x9266, 0xE361, 0x9267, + 0xE362, 0x9268, 0xE363, 0x9269, 0xE364, 0x926A, 0xE365, 0x926B, + 0xE366, 0x926C, 0xE367, 0x926D, 0xE368, 0x926E, 0xE369, 0x926F, + 0xE36A, 0x9270, 0xE36B, 0x9271, 0xE36C, 0x9272, 0xE36D, 0x9273, + 0xE36E, 0x9275, 0xE36F, 0x9276, 0xE370, 0x9277, 0xE371, 0x9278, + 0xE372, 0x9279, 0xE373, 0x927A, 0xE374, 0x927B, 0xE375, 0x927C, + 0xE376, 0x927D, 0xE377, 0x927E, 0xE378, 0x927F, 0xE379, 0x9280, + 0xE37A, 0x9281, 0xE37B, 0x9282, 0xE37C, 0x9283, 0xE37D, 0x9284, + 0xE37E, 0x9285, 0xE380, 0x9286, 0xE381, 0x9287, 0xE382, 0x9288, + 0xE383, 0x9289, 0xE384, 0x928A, 0xE385, 0x928B, 0xE386, 0x928C, + 0xE387, 0x928D, 0xE388, 0x928F, 0xE389, 0x9290, 0xE38A, 0x9291, + 0xE38B, 0x9292, 0xE38C, 0x9293, 0xE38D, 0x9294, 0xE38E, 0x9295, + 0xE38F, 0x9296, 0xE390, 0x9297, 0xE391, 0x9298, 0xE392, 0x9299, + 0xE393, 0x929A, 0xE394, 0x929B, 0xE395, 0x929C, 0xE396, 0x929D, + 0xE397, 0x929E, 0xE398, 0x929F, 0xE399, 0x92A0, 0xE39A, 0x92A1, + 0xE39B, 0x92A2, 0xE39C, 0x92A3, 0xE39D, 0x92A4, 0xE39E, 0x92A5, + 0xE39F, 0x92A6, 0xE3A0, 0x92A7, 0xE3A1, 0x606A, 0xE3A2, 0x607D, + 0xE3A3, 0x6096, 0xE3A4, 0x609A, 0xE3A5, 0x60AD, 0xE3A6, 0x609D, + 0xE3A7, 0x6083, 0xE3A8, 0x6092, 0xE3A9, 0x608C, 0xE3AA, 0x609B, + 0xE3AB, 0x60EC, 0xE3AC, 0x60BB, 0xE3AD, 0x60B1, 0xE3AE, 0x60DD, + 0xE3AF, 0x60D8, 0xE3B0, 0x60C6, 0xE3B1, 0x60DA, 0xE3B2, 0x60B4, + 0xE3B3, 0x6120, 0xE3B4, 0x6126, 0xE3B5, 0x6115, 0xE3B6, 0x6123, + 0xE3B7, 0x60F4, 0xE3B8, 0x6100, 0xE3B9, 0x610E, 0xE3BA, 0x612B, + 0xE3BB, 0x614A, 0xE3BC, 0x6175, 0xE3BD, 0x61AC, 0xE3BE, 0x6194, + 0xE3BF, 0x61A7, 0xE3C0, 0x61B7, 0xE3C1, 0x61D4, 0xE3C2, 0x61F5, + 0xE3C3, 0x5FDD, 0xE3C4, 0x96B3, 0xE3C5, 0x95E9, 0xE3C6, 0x95EB, + 0xE3C7, 0x95F1, 0xE3C8, 0x95F3, 0xE3C9, 0x95F5, 0xE3CA, 0x95F6, + 0xE3CB, 0x95FC, 0xE3CC, 0x95FE, 0xE3CD, 0x9603, 0xE3CE, 0x9604, + 0xE3CF, 0x9606, 0xE3D0, 0x9608, 0xE3D1, 0x960A, 0xE3D2, 0x960B, + 0xE3D3, 0x960C, 0xE3D4, 0x960D, 0xE3D5, 0x960F, 0xE3D6, 0x9612, + 0xE3D7, 0x9615, 0xE3D8, 0x9616, 0xE3D9, 0x9617, 0xE3DA, 0x9619, + 0xE3DB, 0x961A, 0xE3DC, 0x4E2C, 0xE3DD, 0x723F, 0xE3DE, 0x6215, + 0xE3DF, 0x6C35, 0xE3E0, 0x6C54, 0xE3E1, 0x6C5C, 0xE3E2, 0x6C4A, + 0xE3E3, 0x6CA3, 0xE3E4, 0x6C85, 0xE3E5, 0x6C90, 0xE3E6, 0x6C94, + 0xE3E7, 0x6C8C, 0xE3E8, 0x6C68, 0xE3E9, 0x6C69, 0xE3EA, 0x6C74, + 0xE3EB, 0x6C76, 0xE3EC, 0x6C86, 0xE3ED, 0x6CA9, 0xE3EE, 0x6CD0, + 0xE3EF, 0x6CD4, 0xE3F0, 0x6CAD, 0xE3F1, 0x6CF7, 0xE3F2, 0x6CF8, + 0xE3F3, 0x6CF1, 0xE3F4, 0x6CD7, 0xE3F5, 0x6CB2, 0xE3F6, 0x6CE0, + 0xE3F7, 0x6CD6, 0xE3F8, 0x6CFA, 0xE3F9, 0x6CEB, 0xE3FA, 0x6CEE, + 0xE3FB, 0x6CB1, 0xE3FC, 0x6CD3, 0xE3FD, 0x6CEF, 0xE3FE, 0x6CFE, + 0xE440, 0x92A8, 0xE441, 0x92A9, 0xE442, 0x92AA, 0xE443, 0x92AB, + 0xE444, 0x92AC, 0xE445, 0x92AD, 0xE446, 0x92AF, 0xE447, 0x92B0, + 0xE448, 0x92B1, 0xE449, 0x92B2, 0xE44A, 0x92B3, 0xE44B, 0x92B4, + 0xE44C, 0x92B5, 0xE44D, 0x92B6, 0xE44E, 0x92B7, 0xE44F, 0x92B8, + 0xE450, 0x92B9, 0xE451, 0x92BA, 0xE452, 0x92BB, 0xE453, 0x92BC, + 0xE454, 0x92BD, 0xE455, 0x92BE, 0xE456, 0x92BF, 0xE457, 0x92C0, + 0xE458, 0x92C1, 0xE459, 0x92C2, 0xE45A, 0x92C3, 0xE45B, 0x92C4, + 0xE45C, 0x92C5, 0xE45D, 0x92C6, 0xE45E, 0x92C7, 0xE45F, 0x92C9, + 0xE460, 0x92CA, 0xE461, 0x92CB, 0xE462, 0x92CC, 0xE463, 0x92CD, + 0xE464, 0x92CE, 0xE465, 0x92CF, 0xE466, 0x92D0, 0xE467, 0x92D1, + 0xE468, 0x92D2, 0xE469, 0x92D3, 0xE46A, 0x92D4, 0xE46B, 0x92D5, + 0xE46C, 0x92D6, 0xE46D, 0x92D7, 0xE46E, 0x92D8, 0xE46F, 0x92D9, + 0xE470, 0x92DA, 0xE471, 0x92DB, 0xE472, 0x92DC, 0xE473, 0x92DD, + 0xE474, 0x92DE, 0xE475, 0x92DF, 0xE476, 0x92E0, 0xE477, 0x92E1, + 0xE478, 0x92E2, 0xE479, 0x92E3, 0xE47A, 0x92E4, 0xE47B, 0x92E5, + 0xE47C, 0x92E6, 0xE47D, 0x92E7, 0xE47E, 0x92E8, 0xE480, 0x92E9, + 0xE481, 0x92EA, 0xE482, 0x92EB, 0xE483, 0x92EC, 0xE484, 0x92ED, + 0xE485, 0x92EE, 0xE486, 0x92EF, 0xE487, 0x92F0, 0xE488, 0x92F1, + 0xE489, 0x92F2, 0xE48A, 0x92F3, 0xE48B, 0x92F4, 0xE48C, 0x92F5, + 0xE48D, 0x92F6, 0xE48E, 0x92F7, 0xE48F, 0x92F8, 0xE490, 0x92F9, + 0xE491, 0x92FA, 0xE492, 0x92FB, 0xE493, 0x92FC, 0xE494, 0x92FD, + 0xE495, 0x92FE, 0xE496, 0x92FF, 0xE497, 0x9300, 0xE498, 0x9301, + 0xE499, 0x9302, 0xE49A, 0x9303, 0xE49B, 0x9304, 0xE49C, 0x9305, + 0xE49D, 0x9306, 0xE49E, 0x9307, 0xE49F, 0x9308, 0xE4A0, 0x9309, + 0xE4A1, 0x6D39, 0xE4A2, 0x6D27, 0xE4A3, 0x6D0C, 0xE4A4, 0x6D43, + 0xE4A5, 0x6D48, 0xE4A6, 0x6D07, 0xE4A7, 0x6D04, 0xE4A8, 0x6D19, + 0xE4A9, 0x6D0E, 0xE4AA, 0x6D2B, 0xE4AB, 0x6D4D, 0xE4AC, 0x6D2E, + 0xE4AD, 0x6D35, 0xE4AE, 0x6D1A, 0xE4AF, 0x6D4F, 0xE4B0, 0x6D52, + 0xE4B1, 0x6D54, 0xE4B2, 0x6D33, 0xE4B3, 0x6D91, 0xE4B4, 0x6D6F, + 0xE4B5, 0x6D9E, 0xE4B6, 0x6DA0, 0xE4B7, 0x6D5E, 0xE4B8, 0x6D93, + 0xE4B9, 0x6D94, 0xE4BA, 0x6D5C, 0xE4BB, 0x6D60, 0xE4BC, 0x6D7C, + 0xE4BD, 0x6D63, 0xE4BE, 0x6E1A, 0xE4BF, 0x6DC7, 0xE4C0, 0x6DC5, + 0xE4C1, 0x6DDE, 0xE4C2, 0x6E0E, 0xE4C3, 0x6DBF, 0xE4C4, 0x6DE0, + 0xE4C5, 0x6E11, 0xE4C6, 0x6DE6, 0xE4C7, 0x6DDD, 0xE4C8, 0x6DD9, + 0xE4C9, 0x6E16, 0xE4CA, 0x6DAB, 0xE4CB, 0x6E0C, 0xE4CC, 0x6DAE, + 0xE4CD, 0x6E2B, 0xE4CE, 0x6E6E, 0xE4CF, 0x6E4E, 0xE4D0, 0x6E6B, + 0xE4D1, 0x6EB2, 0xE4D2, 0x6E5F, 0xE4D3, 0x6E86, 0xE4D4, 0x6E53, + 0xE4D5, 0x6E54, 0xE4D6, 0x6E32, 0xE4D7, 0x6E25, 0xE4D8, 0x6E44, + 0xE4D9, 0x6EDF, 0xE4DA, 0x6EB1, 0xE4DB, 0x6E98, 0xE4DC, 0x6EE0, + 0xE4DD, 0x6F2D, 0xE4DE, 0x6EE2, 0xE4DF, 0x6EA5, 0xE4E0, 0x6EA7, + 0xE4E1, 0x6EBD, 0xE4E2, 0x6EBB, 0xE4E3, 0x6EB7, 0xE4E4, 0x6ED7, + 0xE4E5, 0x6EB4, 0xE4E6, 0x6ECF, 0xE4E7, 0x6E8F, 0xE4E8, 0x6EC2, + 0xE4E9, 0x6E9F, 0xE4EA, 0x6F62, 0xE4EB, 0x6F46, 0xE4EC, 0x6F47, + 0xE4ED, 0x6F24, 0xE4EE, 0x6F15, 0xE4EF, 0x6EF9, 0xE4F0, 0x6F2F, + 0xE4F1, 0x6F36, 0xE4F2, 0x6F4B, 0xE4F3, 0x6F74, 0xE4F4, 0x6F2A, + 0xE4F5, 0x6F09, 0xE4F6, 0x6F29, 0xE4F7, 0x6F89, 0xE4F8, 0x6F8D, + 0xE4F9, 0x6F8C, 0xE4FA, 0x6F78, 0xE4FB, 0x6F72, 0xE4FC, 0x6F7C, + 0xE4FD, 0x6F7A, 0xE4FE, 0x6FD1, 0xE540, 0x930A, 0xE541, 0x930B, + 0xE542, 0x930C, 0xE543, 0x930D, 0xE544, 0x930E, 0xE545, 0x930F, + 0xE546, 0x9310, 0xE547, 0x9311, 0xE548, 0x9312, 0xE549, 0x9313, + 0xE54A, 0x9314, 0xE54B, 0x9315, 0xE54C, 0x9316, 0xE54D, 0x9317, + 0xE54E, 0x9318, 0xE54F, 0x9319, 0xE550, 0x931A, 0xE551, 0x931B, + 0xE552, 0x931C, 0xE553, 0x931D, 0xE554, 0x931E, 0xE555, 0x931F, + 0xE556, 0x9320, 0xE557, 0x9321, 0xE558, 0x9322, 0xE559, 0x9323, + 0xE55A, 0x9324, 0xE55B, 0x9325, 0xE55C, 0x9326, 0xE55D, 0x9327, + 0xE55E, 0x9328, 0xE55F, 0x9329, 0xE560, 0x932A, 0xE561, 0x932B, + 0xE562, 0x932C, 0xE563, 0x932D, 0xE564, 0x932E, 0xE565, 0x932F, + 0xE566, 0x9330, 0xE567, 0x9331, 0xE568, 0x9332, 0xE569, 0x9333, + 0xE56A, 0x9334, 0xE56B, 0x9335, 0xE56C, 0x9336, 0xE56D, 0x9337, + 0xE56E, 0x9338, 0xE56F, 0x9339, 0xE570, 0x933A, 0xE571, 0x933B, + 0xE572, 0x933C, 0xE573, 0x933D, 0xE574, 0x933F, 0xE575, 0x9340, + 0xE576, 0x9341, 0xE577, 0x9342, 0xE578, 0x9343, 0xE579, 0x9344, + 0xE57A, 0x9345, 0xE57B, 0x9346, 0xE57C, 0x9347, 0xE57D, 0x9348, + 0xE57E, 0x9349, 0xE580, 0x934A, 0xE581, 0x934B, 0xE582, 0x934C, + 0xE583, 0x934D, 0xE584, 0x934E, 0xE585, 0x934F, 0xE586, 0x9350, + 0xE587, 0x9351, 0xE588, 0x9352, 0xE589, 0x9353, 0xE58A, 0x9354, + 0xE58B, 0x9355, 0xE58C, 0x9356, 0xE58D, 0x9357, 0xE58E, 0x9358, + 0xE58F, 0x9359, 0xE590, 0x935A, 0xE591, 0x935B, 0xE592, 0x935C, + 0xE593, 0x935D, 0xE594, 0x935E, 0xE595, 0x935F, 0xE596, 0x9360, + 0xE597, 0x9361, 0xE598, 0x9362, 0xE599, 0x9363, 0xE59A, 0x9364, + 0xE59B, 0x9365, 0xE59C, 0x9366, 0xE59D, 0x9367, 0xE59E, 0x9368, + 0xE59F, 0x9369, 0xE5A0, 0x936B, 0xE5A1, 0x6FC9, 0xE5A2, 0x6FA7, + 0xE5A3, 0x6FB9, 0xE5A4, 0x6FB6, 0xE5A5, 0x6FC2, 0xE5A6, 0x6FE1, + 0xE5A7, 0x6FEE, 0xE5A8, 0x6FDE, 0xE5A9, 0x6FE0, 0xE5AA, 0x6FEF, + 0xE5AB, 0x701A, 0xE5AC, 0x7023, 0xE5AD, 0x701B, 0xE5AE, 0x7039, + 0xE5AF, 0x7035, 0xE5B0, 0x704F, 0xE5B1, 0x705E, 0xE5B2, 0x5B80, + 0xE5B3, 0x5B84, 0xE5B4, 0x5B95, 0xE5B5, 0x5B93, 0xE5B6, 0x5BA5, + 0xE5B7, 0x5BB8, 0xE5B8, 0x752F, 0xE5B9, 0x9A9E, 0xE5BA, 0x6434, + 0xE5BB, 0x5BE4, 0xE5BC, 0x5BEE, 0xE5BD, 0x8930, 0xE5BE, 0x5BF0, + 0xE5BF, 0x8E47, 0xE5C0, 0x8B07, 0xE5C1, 0x8FB6, 0xE5C2, 0x8FD3, + 0xE5C3, 0x8FD5, 0xE5C4, 0x8FE5, 0xE5C5, 0x8FEE, 0xE5C6, 0x8FE4, + 0xE5C7, 0x8FE9, 0xE5C8, 0x8FE6, 0xE5C9, 0x8FF3, 0xE5CA, 0x8FE8, + 0xE5CB, 0x9005, 0xE5CC, 0x9004, 0xE5CD, 0x900B, 0xE5CE, 0x9026, + 0xE5CF, 0x9011, 0xE5D0, 0x900D, 0xE5D1, 0x9016, 0xE5D2, 0x9021, + 0xE5D3, 0x9035, 0xE5D4, 0x9036, 0xE5D5, 0x902D, 0xE5D6, 0x902F, + 0xE5D7, 0x9044, 0xE5D8, 0x9051, 0xE5D9, 0x9052, 0xE5DA, 0x9050, + 0xE5DB, 0x9068, 0xE5DC, 0x9058, 0xE5DD, 0x9062, 0xE5DE, 0x905B, + 0xE5DF, 0x66B9, 0xE5E0, 0x9074, 0xE5E1, 0x907D, 0xE5E2, 0x9082, + 0xE5E3, 0x9088, 0xE5E4, 0x9083, 0xE5E5, 0x908B, 0xE5E6, 0x5F50, + 0xE5E7, 0x5F57, 0xE5E8, 0x5F56, 0xE5E9, 0x5F58, 0xE5EA, 0x5C3B, + 0xE5EB, 0x54AB, 0xE5EC, 0x5C50, 0xE5ED, 0x5C59, 0xE5EE, 0x5B71, + 0xE5EF, 0x5C63, 0xE5F0, 0x5C66, 0xE5F1, 0x7FBC, 0xE5F2, 0x5F2A, + 0xE5F3, 0x5F29, 0xE5F4, 0x5F2D, 0xE5F5, 0x8274, 0xE5F6, 0x5F3C, + 0xE5F7, 0x9B3B, 0xE5F8, 0x5C6E, 0xE5F9, 0x5981, 0xE5FA, 0x5983, + 0xE5FB, 0x598D, 0xE5FC, 0x59A9, 0xE5FD, 0x59AA, 0xE5FE, 0x59A3, + 0xE640, 0x936C, 0xE641, 0x936D, 0xE642, 0x936E, 0xE643, 0x936F, + 0xE644, 0x9370, 0xE645, 0x9371, 0xE646, 0x9372, 0xE647, 0x9373, + 0xE648, 0x9374, 0xE649, 0x9375, 0xE64A, 0x9376, 0xE64B, 0x9377, + 0xE64C, 0x9378, 0xE64D, 0x9379, 0xE64E, 0x937A, 0xE64F, 0x937B, + 0xE650, 0x937C, 0xE651, 0x937D, 0xE652, 0x937E, 0xE653, 0x937F, + 0xE654, 0x9380, 0xE655, 0x9381, 0xE656, 0x9382, 0xE657, 0x9383, + 0xE658, 0x9384, 0xE659, 0x9385, 0xE65A, 0x9386, 0xE65B, 0x9387, + 0xE65C, 0x9388, 0xE65D, 0x9389, 0xE65E, 0x938A, 0xE65F, 0x938B, + 0xE660, 0x938C, 0xE661, 0x938D, 0xE662, 0x938E, 0xE663, 0x9390, + 0xE664, 0x9391, 0xE665, 0x9392, 0xE666, 0x9393, 0xE667, 0x9394, + 0xE668, 0x9395, 0xE669, 0x9396, 0xE66A, 0x9397, 0xE66B, 0x9398, + 0xE66C, 0x9399, 0xE66D, 0x939A, 0xE66E, 0x939B, 0xE66F, 0x939C, + 0xE670, 0x939D, 0xE671, 0x939E, 0xE672, 0x939F, 0xE673, 0x93A0, + 0xE674, 0x93A1, 0xE675, 0x93A2, 0xE676, 0x93A3, 0xE677, 0x93A4, + 0xE678, 0x93A5, 0xE679, 0x93A6, 0xE67A, 0x93A7, 0xE67B, 0x93A8, + 0xE67C, 0x93A9, 0xE67D, 0x93AA, 0xE67E, 0x93AB, 0xE680, 0x93AC, + 0xE681, 0x93AD, 0xE682, 0x93AE, 0xE683, 0x93AF, 0xE684, 0x93B0, + 0xE685, 0x93B1, 0xE686, 0x93B2, 0xE687, 0x93B3, 0xE688, 0x93B4, + 0xE689, 0x93B5, 0xE68A, 0x93B6, 0xE68B, 0x93B7, 0xE68C, 0x93B8, + 0xE68D, 0x93B9, 0xE68E, 0x93BA, 0xE68F, 0x93BB, 0xE690, 0x93BC, + 0xE691, 0x93BD, 0xE692, 0x93BE, 0xE693, 0x93BF, 0xE694, 0x93C0, + 0xE695, 0x93C1, 0xE696, 0x93C2, 0xE697, 0x93C3, 0xE698, 0x93C4, + 0xE699, 0x93C5, 0xE69A, 0x93C6, 0xE69B, 0x93C7, 0xE69C, 0x93C8, + 0xE69D, 0x93C9, 0xE69E, 0x93CB, 0xE69F, 0x93CC, 0xE6A0, 0x93CD, + 0xE6A1, 0x5997, 0xE6A2, 0x59CA, 0xE6A3, 0x59AB, 0xE6A4, 0x599E, + 0xE6A5, 0x59A4, 0xE6A6, 0x59D2, 0xE6A7, 0x59B2, 0xE6A8, 0x59AF, + 0xE6A9, 0x59D7, 0xE6AA, 0x59BE, 0xE6AB, 0x5A05, 0xE6AC, 0x5A06, + 0xE6AD, 0x59DD, 0xE6AE, 0x5A08, 0xE6AF, 0x59E3, 0xE6B0, 0x59D8, + 0xE6B1, 0x59F9, 0xE6B2, 0x5A0C, 0xE6B3, 0x5A09, 0xE6B4, 0x5A32, + 0xE6B5, 0x5A34, 0xE6B6, 0x5A11, 0xE6B7, 0x5A23, 0xE6B8, 0x5A13, + 0xE6B9, 0x5A40, 0xE6BA, 0x5A67, 0xE6BB, 0x5A4A, 0xE6BC, 0x5A55, + 0xE6BD, 0x5A3C, 0xE6BE, 0x5A62, 0xE6BF, 0x5A75, 0xE6C0, 0x80EC, + 0xE6C1, 0x5AAA, 0xE6C2, 0x5A9B, 0xE6C3, 0x5A77, 0xE6C4, 0x5A7A, + 0xE6C5, 0x5ABE, 0xE6C6, 0x5AEB, 0xE6C7, 0x5AB2, 0xE6C8, 0x5AD2, + 0xE6C9, 0x5AD4, 0xE6CA, 0x5AB8, 0xE6CB, 0x5AE0, 0xE6CC, 0x5AE3, + 0xE6CD, 0x5AF1, 0xE6CE, 0x5AD6, 0xE6CF, 0x5AE6, 0xE6D0, 0x5AD8, + 0xE6D1, 0x5ADC, 0xE6D2, 0x5B09, 0xE6D3, 0x5B17, 0xE6D4, 0x5B16, + 0xE6D5, 0x5B32, 0xE6D6, 0x5B37, 0xE6D7, 0x5B40, 0xE6D8, 0x5C15, + 0xE6D9, 0x5C1C, 0xE6DA, 0x5B5A, 0xE6DB, 0x5B65, 0xE6DC, 0x5B73, + 0xE6DD, 0x5B51, 0xE6DE, 0x5B53, 0xE6DF, 0x5B62, 0xE6E0, 0x9A75, + 0xE6E1, 0x9A77, 0xE6E2, 0x9A78, 0xE6E3, 0x9A7A, 0xE6E4, 0x9A7F, + 0xE6E5, 0x9A7D, 0xE6E6, 0x9A80, 0xE6E7, 0x9A81, 0xE6E8, 0x9A85, + 0xE6E9, 0x9A88, 0xE6EA, 0x9A8A, 0xE6EB, 0x9A90, 0xE6EC, 0x9A92, + 0xE6ED, 0x9A93, 0xE6EE, 0x9A96, 0xE6EF, 0x9A98, 0xE6F0, 0x9A9B, + 0xE6F1, 0x9A9C, 0xE6F2, 0x9A9D, 0xE6F3, 0x9A9F, 0xE6F4, 0x9AA0, + 0xE6F5, 0x9AA2, 0xE6F6, 0x9AA3, 0xE6F7, 0x9AA5, 0xE6F8, 0x9AA7, + 0xE6F9, 0x7E9F, 0xE6FA, 0x7EA1, 0xE6FB, 0x7EA3, 0xE6FC, 0x7EA5, + 0xE6FD, 0x7EA8, 0xE6FE, 0x7EA9, 0xE740, 0x93CE, 0xE741, 0x93CF, + 0xE742, 0x93D0, 0xE743, 0x93D1, 0xE744, 0x93D2, 0xE745, 0x93D3, + 0xE746, 0x93D4, 0xE747, 0x93D5, 0xE748, 0x93D7, 0xE749, 0x93D8, + 0xE74A, 0x93D9, 0xE74B, 0x93DA, 0xE74C, 0x93DB, 0xE74D, 0x93DC, + 0xE74E, 0x93DD, 0xE74F, 0x93DE, 0xE750, 0x93DF, 0xE751, 0x93E0, + 0xE752, 0x93E1, 0xE753, 0x93E2, 0xE754, 0x93E3, 0xE755, 0x93E4, + 0xE756, 0x93E5, 0xE757, 0x93E6, 0xE758, 0x93E7, 0xE759, 0x93E8, + 0xE75A, 0x93E9, 0xE75B, 0x93EA, 0xE75C, 0x93EB, 0xE75D, 0x93EC, + 0xE75E, 0x93ED, 0xE75F, 0x93EE, 0xE760, 0x93EF, 0xE761, 0x93F0, + 0xE762, 0x93F1, 0xE763, 0x93F2, 0xE764, 0x93F3, 0xE765, 0x93F4, + 0xE766, 0x93F5, 0xE767, 0x93F6, 0xE768, 0x93F7, 0xE769, 0x93F8, + 0xE76A, 0x93F9, 0xE76B, 0x93FA, 0xE76C, 0x93FB, 0xE76D, 0x93FC, + 0xE76E, 0x93FD, 0xE76F, 0x93FE, 0xE770, 0x93FF, 0xE771, 0x9400, + 0xE772, 0x9401, 0xE773, 0x9402, 0xE774, 0x9403, 0xE775, 0x9404, + 0xE776, 0x9405, 0xE777, 0x9406, 0xE778, 0x9407, 0xE779, 0x9408, + 0xE77A, 0x9409, 0xE77B, 0x940A, 0xE77C, 0x940B, 0xE77D, 0x940C, + 0xE77E, 0x940D, 0xE780, 0x940E, 0xE781, 0x940F, 0xE782, 0x9410, + 0xE783, 0x9411, 0xE784, 0x9412, 0xE785, 0x9413, 0xE786, 0x9414, + 0xE787, 0x9415, 0xE788, 0x9416, 0xE789, 0x9417, 0xE78A, 0x9418, + 0xE78B, 0x9419, 0xE78C, 0x941A, 0xE78D, 0x941B, 0xE78E, 0x941C, + 0xE78F, 0x941D, 0xE790, 0x941E, 0xE791, 0x941F, 0xE792, 0x9420, + 0xE793, 0x9421, 0xE794, 0x9422, 0xE795, 0x9423, 0xE796, 0x9424, + 0xE797, 0x9425, 0xE798, 0x9426, 0xE799, 0x9427, 0xE79A, 0x9428, + 0xE79B, 0x9429, 0xE79C, 0x942A, 0xE79D, 0x942B, 0xE79E, 0x942C, + 0xE79F, 0x942D, 0xE7A0, 0x942E, 0xE7A1, 0x7EAD, 0xE7A2, 0x7EB0, + 0xE7A3, 0x7EBE, 0xE7A4, 0x7EC0, 0xE7A5, 0x7EC1, 0xE7A6, 0x7EC2, + 0xE7A7, 0x7EC9, 0xE7A8, 0x7ECB, 0xE7A9, 0x7ECC, 0xE7AA, 0x7ED0, + 0xE7AB, 0x7ED4, 0xE7AC, 0x7ED7, 0xE7AD, 0x7EDB, 0xE7AE, 0x7EE0, + 0xE7AF, 0x7EE1, 0xE7B0, 0x7EE8, 0xE7B1, 0x7EEB, 0xE7B2, 0x7EEE, + 0xE7B3, 0x7EEF, 0xE7B4, 0x7EF1, 0xE7B5, 0x7EF2, 0xE7B6, 0x7F0D, + 0xE7B7, 0x7EF6, 0xE7B8, 0x7EFA, 0xE7B9, 0x7EFB, 0xE7BA, 0x7EFE, + 0xE7BB, 0x7F01, 0xE7BC, 0x7F02, 0xE7BD, 0x7F03, 0xE7BE, 0x7F07, + 0xE7BF, 0x7F08, 0xE7C0, 0x7F0B, 0xE7C1, 0x7F0C, 0xE7C2, 0x7F0F, + 0xE7C3, 0x7F11, 0xE7C4, 0x7F12, 0xE7C5, 0x7F17, 0xE7C6, 0x7F19, + 0xE7C7, 0x7F1C, 0xE7C8, 0x7F1B, 0xE7C9, 0x7F1F, 0xE7CA, 0x7F21, + 0xE7CB, 0x7F22, 0xE7CC, 0x7F23, 0xE7CD, 0x7F24, 0xE7CE, 0x7F25, + 0xE7CF, 0x7F26, 0xE7D0, 0x7F27, 0xE7D1, 0x7F2A, 0xE7D2, 0x7F2B, + 0xE7D3, 0x7F2C, 0xE7D4, 0x7F2D, 0xE7D5, 0x7F2F, 0xE7D6, 0x7F30, + 0xE7D7, 0x7F31, 0xE7D8, 0x7F32, 0xE7D9, 0x7F33, 0xE7DA, 0x7F35, + 0xE7DB, 0x5E7A, 0xE7DC, 0x757F, 0xE7DD, 0x5DDB, 0xE7DE, 0x753E, + 0xE7DF, 0x9095, 0xE7E0, 0x738E, 0xE7E1, 0x7391, 0xE7E2, 0x73AE, + 0xE7E3, 0x73A2, 0xE7E4, 0x739F, 0xE7E5, 0x73CF, 0xE7E6, 0x73C2, + 0xE7E7, 0x73D1, 0xE7E8, 0x73B7, 0xE7E9, 0x73B3, 0xE7EA, 0x73C0, + 0xE7EB, 0x73C9, 0xE7EC, 0x73C8, 0xE7ED, 0x73E5, 0xE7EE, 0x73D9, + 0xE7EF, 0x987C, 0xE7F0, 0x740A, 0xE7F1, 0x73E9, 0xE7F2, 0x73E7, + 0xE7F3, 0x73DE, 0xE7F4, 0x73BA, 0xE7F5, 0x73F2, 0xE7F6, 0x740F, + 0xE7F7, 0x742A, 0xE7F8, 0x745B, 0xE7F9, 0x7426, 0xE7FA, 0x7425, + 0xE7FB, 0x7428, 0xE7FC, 0x7430, 0xE7FD, 0x742E, 0xE7FE, 0x742C, + 0xE840, 0x942F, 0xE841, 0x9430, 0xE842, 0x9431, 0xE843, 0x9432, + 0xE844, 0x9433, 0xE845, 0x9434, 0xE846, 0x9435, 0xE847, 0x9436, + 0xE848, 0x9437, 0xE849, 0x9438, 0xE84A, 0x9439, 0xE84B, 0x943A, + 0xE84C, 0x943B, 0xE84D, 0x943C, 0xE84E, 0x943D, 0xE84F, 0x943F, + 0xE850, 0x9440, 0xE851, 0x9441, 0xE852, 0x9442, 0xE853, 0x9443, + 0xE854, 0x9444, 0xE855, 0x9445, 0xE856, 0x9446, 0xE857, 0x9447, + 0xE858, 0x9448, 0xE859, 0x9449, 0xE85A, 0x944A, 0xE85B, 0x944B, + 0xE85C, 0x944C, 0xE85D, 0x944D, 0xE85E, 0x944E, 0xE85F, 0x944F, + 0xE860, 0x9450, 0xE861, 0x9451, 0xE862, 0x9452, 0xE863, 0x9453, + 0xE864, 0x9454, 0xE865, 0x9455, 0xE866, 0x9456, 0xE867, 0x9457, + 0xE868, 0x9458, 0xE869, 0x9459, 0xE86A, 0x945A, 0xE86B, 0x945B, + 0xE86C, 0x945C, 0xE86D, 0x945D, 0xE86E, 0x945E, 0xE86F, 0x945F, + 0xE870, 0x9460, 0xE871, 0x9461, 0xE872, 0x9462, 0xE873, 0x9463, + 0xE874, 0x9464, 0xE875, 0x9465, 0xE876, 0x9466, 0xE877, 0x9467, + 0xE878, 0x9468, 0xE879, 0x9469, 0xE87A, 0x946A, 0xE87B, 0x946C, + 0xE87C, 0x946D, 0xE87D, 0x946E, 0xE87E, 0x946F, 0xE880, 0x9470, + 0xE881, 0x9471, 0xE882, 0x9472, 0xE883, 0x9473, 0xE884, 0x9474, + 0xE885, 0x9475, 0xE886, 0x9476, 0xE887, 0x9477, 0xE888, 0x9478, + 0xE889, 0x9479, 0xE88A, 0x947A, 0xE88B, 0x947B, 0xE88C, 0x947C, + 0xE88D, 0x947D, 0xE88E, 0x947E, 0xE88F, 0x947F, 0xE890, 0x9480, + 0xE891, 0x9481, 0xE892, 0x9482, 0xE893, 0x9483, 0xE894, 0x9484, + 0xE895, 0x9491, 0xE896, 0x9496, 0xE897, 0x9498, 0xE898, 0x94C7, + 0xE899, 0x94CF, 0xE89A, 0x94D3, 0xE89B, 0x94D4, 0xE89C, 0x94DA, + 0xE89D, 0x94E6, 0xE89E, 0x94FB, 0xE89F, 0x951C, 0xE8A0, 0x9520, + 0xE8A1, 0x741B, 0xE8A2, 0x741A, 0xE8A3, 0x7441, 0xE8A4, 0x745C, + 0xE8A5, 0x7457, 0xE8A6, 0x7455, 0xE8A7, 0x7459, 0xE8A8, 0x7477, + 0xE8A9, 0x746D, 0xE8AA, 0x747E, 0xE8AB, 0x749C, 0xE8AC, 0x748E, + 0xE8AD, 0x7480, 0xE8AE, 0x7481, 0xE8AF, 0x7487, 0xE8B0, 0x748B, + 0xE8B1, 0x749E, 0xE8B2, 0x74A8, 0xE8B3, 0x74A9, 0xE8B4, 0x7490, + 0xE8B5, 0x74A7, 0xE8B6, 0x74D2, 0xE8B7, 0x74BA, 0xE8B8, 0x97EA, + 0xE8B9, 0x97EB, 0xE8BA, 0x97EC, 0xE8BB, 0x674C, 0xE8BC, 0x6753, + 0xE8BD, 0x675E, 0xE8BE, 0x6748, 0xE8BF, 0x6769, 0xE8C0, 0x67A5, + 0xE8C1, 0x6787, 0xE8C2, 0x676A, 0xE8C3, 0x6773, 0xE8C4, 0x6798, + 0xE8C5, 0x67A7, 0xE8C6, 0x6775, 0xE8C7, 0x67A8, 0xE8C8, 0x679E, + 0xE8C9, 0x67AD, 0xE8CA, 0x678B, 0xE8CB, 0x6777, 0xE8CC, 0x677C, + 0xE8CD, 0x67F0, 0xE8CE, 0x6809, 0xE8CF, 0x67D8, 0xE8D0, 0x680A, + 0xE8D1, 0x67E9, 0xE8D2, 0x67B0, 0xE8D3, 0x680C, 0xE8D4, 0x67D9, + 0xE8D5, 0x67B5, 0xE8D6, 0x67DA, 0xE8D7, 0x67B3, 0xE8D8, 0x67DD, + 0xE8D9, 0x6800, 0xE8DA, 0x67C3, 0xE8DB, 0x67B8, 0xE8DC, 0x67E2, + 0xE8DD, 0x680E, 0xE8DE, 0x67C1, 0xE8DF, 0x67FD, 0xE8E0, 0x6832, + 0xE8E1, 0x6833, 0xE8E2, 0x6860, 0xE8E3, 0x6861, 0xE8E4, 0x684E, + 0xE8E5, 0x6862, 0xE8E6, 0x6844, 0xE8E7, 0x6864, 0xE8E8, 0x6883, + 0xE8E9, 0x681D, 0xE8EA, 0x6855, 0xE8EB, 0x6866, 0xE8EC, 0x6841, + 0xE8ED, 0x6867, 0xE8EE, 0x6840, 0xE8EF, 0x683E, 0xE8F0, 0x684A, + 0xE8F1, 0x6849, 0xE8F2, 0x6829, 0xE8F3, 0x68B5, 0xE8F4, 0x688F, + 0xE8F5, 0x6874, 0xE8F6, 0x6877, 0xE8F7, 0x6893, 0xE8F8, 0x686B, + 0xE8F9, 0x68C2, 0xE8FA, 0x696E, 0xE8FB, 0x68FC, 0xE8FC, 0x691F, + 0xE8FD, 0x6920, 0xE8FE, 0x68F9, 0xE940, 0x9527, 0xE941, 0x9533, + 0xE942, 0x953D, 0xE943, 0x9543, 0xE944, 0x9548, 0xE945, 0x954B, + 0xE946, 0x9555, 0xE947, 0x955A, 0xE948, 0x9560, 0xE949, 0x956E, + 0xE94A, 0x9574, 0xE94B, 0x9575, 0xE94C, 0x9577, 0xE94D, 0x9578, + 0xE94E, 0x9579, 0xE94F, 0x957A, 0xE950, 0x957B, 0xE951, 0x957C, + 0xE952, 0x957D, 0xE953, 0x957E, 0xE954, 0x9580, 0xE955, 0x9581, + 0xE956, 0x9582, 0xE957, 0x9583, 0xE958, 0x9584, 0xE959, 0x9585, + 0xE95A, 0x9586, 0xE95B, 0x9587, 0xE95C, 0x9588, 0xE95D, 0x9589, + 0xE95E, 0x958A, 0xE95F, 0x958B, 0xE960, 0x958C, 0xE961, 0x958D, + 0xE962, 0x958E, 0xE963, 0x958F, 0xE964, 0x9590, 0xE965, 0x9591, + 0xE966, 0x9592, 0xE967, 0x9593, 0xE968, 0x9594, 0xE969, 0x9595, + 0xE96A, 0x9596, 0xE96B, 0x9597, 0xE96C, 0x9598, 0xE96D, 0x9599, + 0xE96E, 0x959A, 0xE96F, 0x959B, 0xE970, 0x959C, 0xE971, 0x959D, + 0xE972, 0x959E, 0xE973, 0x959F, 0xE974, 0x95A0, 0xE975, 0x95A1, + 0xE976, 0x95A2, 0xE977, 0x95A3, 0xE978, 0x95A4, 0xE979, 0x95A5, + 0xE97A, 0x95A6, 0xE97B, 0x95A7, 0xE97C, 0x95A8, 0xE97D, 0x95A9, + 0xE97E, 0x95AA, 0xE980, 0x95AB, 0xE981, 0x95AC, 0xE982, 0x95AD, + 0xE983, 0x95AE, 0xE984, 0x95AF, 0xE985, 0x95B0, 0xE986, 0x95B1, + 0xE987, 0x95B2, 0xE988, 0x95B3, 0xE989, 0x95B4, 0xE98A, 0x95B5, + 0xE98B, 0x95B6, 0xE98C, 0x95B7, 0xE98D, 0x95B8, 0xE98E, 0x95B9, + 0xE98F, 0x95BA, 0xE990, 0x95BB, 0xE991, 0x95BC, 0xE992, 0x95BD, + 0xE993, 0x95BE, 0xE994, 0x95BF, 0xE995, 0x95C0, 0xE996, 0x95C1, + 0xE997, 0x95C2, 0xE998, 0x95C3, 0xE999, 0x95C4, 0xE99A, 0x95C5, + 0xE99B, 0x95C6, 0xE99C, 0x95C7, 0xE99D, 0x95C8, 0xE99E, 0x95C9, + 0xE99F, 0x95CA, 0xE9A0, 0x95CB, 0xE9A1, 0x6924, 0xE9A2, 0x68F0, + 0xE9A3, 0x690B, 0xE9A4, 0x6901, 0xE9A5, 0x6957, 0xE9A6, 0x68E3, + 0xE9A7, 0x6910, 0xE9A8, 0x6971, 0xE9A9, 0x6939, 0xE9AA, 0x6960, + 0xE9AB, 0x6942, 0xE9AC, 0x695D, 0xE9AD, 0x6984, 0xE9AE, 0x696B, + 0xE9AF, 0x6980, 0xE9B0, 0x6998, 0xE9B1, 0x6978, 0xE9B2, 0x6934, + 0xE9B3, 0x69CC, 0xE9B4, 0x6987, 0xE9B5, 0x6988, 0xE9B6, 0x69CE, + 0xE9B7, 0x6989, 0xE9B8, 0x6966, 0xE9B9, 0x6963, 0xE9BA, 0x6979, + 0xE9BB, 0x699B, 0xE9BC, 0x69A7, 0xE9BD, 0x69BB, 0xE9BE, 0x69AB, + 0xE9BF, 0x69AD, 0xE9C0, 0x69D4, 0xE9C1, 0x69B1, 0xE9C2, 0x69C1, + 0xE9C3, 0x69CA, 0xE9C4, 0x69DF, 0xE9C5, 0x6995, 0xE9C6, 0x69E0, + 0xE9C7, 0x698D, 0xE9C8, 0x69FF, 0xE9C9, 0x6A2F, 0xE9CA, 0x69ED, + 0xE9CB, 0x6A17, 0xE9CC, 0x6A18, 0xE9CD, 0x6A65, 0xE9CE, 0x69F2, + 0xE9CF, 0x6A44, 0xE9D0, 0x6A3E, 0xE9D1, 0x6AA0, 0xE9D2, 0x6A50, + 0xE9D3, 0x6A5B, 0xE9D4, 0x6A35, 0xE9D5, 0x6A8E, 0xE9D6, 0x6A79, + 0xE9D7, 0x6A3D, 0xE9D8, 0x6A28, 0xE9D9, 0x6A58, 0xE9DA, 0x6A7C, + 0xE9DB, 0x6A91, 0xE9DC, 0x6A90, 0xE9DD, 0x6AA9, 0xE9DE, 0x6A97, + 0xE9DF, 0x6AAB, 0xE9E0, 0x7337, 0xE9E1, 0x7352, 0xE9E2, 0x6B81, + 0xE9E3, 0x6B82, 0xE9E4, 0x6B87, 0xE9E5, 0x6B84, 0xE9E6, 0x6B92, + 0xE9E7, 0x6B93, 0xE9E8, 0x6B8D, 0xE9E9, 0x6B9A, 0xE9EA, 0x6B9B, + 0xE9EB, 0x6BA1, 0xE9EC, 0x6BAA, 0xE9ED, 0x8F6B, 0xE9EE, 0x8F6D, + 0xE9EF, 0x8F71, 0xE9F0, 0x8F72, 0xE9F1, 0x8F73, 0xE9F2, 0x8F75, + 0xE9F3, 0x8F76, 0xE9F4, 0x8F78, 0xE9F5, 0x8F77, 0xE9F6, 0x8F79, + 0xE9F7, 0x8F7A, 0xE9F8, 0x8F7C, 0xE9F9, 0x8F7E, 0xE9FA, 0x8F81, + 0xE9FB, 0x8F82, 0xE9FC, 0x8F84, 0xE9FD, 0x8F87, 0xE9FE, 0x8F8B, + 0xEA40, 0x95CC, 0xEA41, 0x95CD, 0xEA42, 0x95CE, 0xEA43, 0x95CF, + 0xEA44, 0x95D0, 0xEA45, 0x95D1, 0xEA46, 0x95D2, 0xEA47, 0x95D3, + 0xEA48, 0x95D4, 0xEA49, 0x95D5, 0xEA4A, 0x95D6, 0xEA4B, 0x95D7, + 0xEA4C, 0x95D8, 0xEA4D, 0x95D9, 0xEA4E, 0x95DA, 0xEA4F, 0x95DB, + 0xEA50, 0x95DC, 0xEA51, 0x95DD, 0xEA52, 0x95DE, 0xEA53, 0x95DF, + 0xEA54, 0x95E0, 0xEA55, 0x95E1, 0xEA56, 0x95E2, 0xEA57, 0x95E3, + 0xEA58, 0x95E4, 0xEA59, 0x95E5, 0xEA5A, 0x95E6, 0xEA5B, 0x95E7, + 0xEA5C, 0x95EC, 0xEA5D, 0x95FF, 0xEA5E, 0x9607, 0xEA5F, 0x9613, + 0xEA60, 0x9618, 0xEA61, 0x961B, 0xEA62, 0x961E, 0xEA63, 0x9620, + 0xEA64, 0x9623, 0xEA65, 0x9624, 0xEA66, 0x9625, 0xEA67, 0x9626, + 0xEA68, 0x9627, 0xEA69, 0x9628, 0xEA6A, 0x9629, 0xEA6B, 0x962B, + 0xEA6C, 0x962C, 0xEA6D, 0x962D, 0xEA6E, 0x962F, 0xEA6F, 0x9630, + 0xEA70, 0x9637, 0xEA71, 0x9638, 0xEA72, 0x9639, 0xEA73, 0x963A, + 0xEA74, 0x963E, 0xEA75, 0x9641, 0xEA76, 0x9643, 0xEA77, 0x964A, + 0xEA78, 0x964E, 0xEA79, 0x964F, 0xEA7A, 0x9651, 0xEA7B, 0x9652, + 0xEA7C, 0x9653, 0xEA7D, 0x9656, 0xEA7E, 0x9657, 0xEA80, 0x9658, + 0xEA81, 0x9659, 0xEA82, 0x965A, 0xEA83, 0x965C, 0xEA84, 0x965D, + 0xEA85, 0x965E, 0xEA86, 0x9660, 0xEA87, 0x9663, 0xEA88, 0x9665, + 0xEA89, 0x9666, 0xEA8A, 0x966B, 0xEA8B, 0x966D, 0xEA8C, 0x966E, + 0xEA8D, 0x966F, 0xEA8E, 0x9670, 0xEA8F, 0x9671, 0xEA90, 0x9673, + 0xEA91, 0x9678, 0xEA92, 0x9679, 0xEA93, 0x967A, 0xEA94, 0x967B, + 0xEA95, 0x967C, 0xEA96, 0x967D, 0xEA97, 0x967E, 0xEA98, 0x967F, + 0xEA99, 0x9680, 0xEA9A, 0x9681, 0xEA9B, 0x9682, 0xEA9C, 0x9683, + 0xEA9D, 0x9684, 0xEA9E, 0x9687, 0xEA9F, 0x9689, 0xEAA0, 0x968A, + 0xEAA1, 0x8F8D, 0xEAA2, 0x8F8E, 0xEAA3, 0x8F8F, 0xEAA4, 0x8F98, + 0xEAA5, 0x8F9A, 0xEAA6, 0x8ECE, 0xEAA7, 0x620B, 0xEAA8, 0x6217, + 0xEAA9, 0x621B, 0xEAAA, 0x621F, 0xEAAB, 0x6222, 0xEAAC, 0x6221, + 0xEAAD, 0x6225, 0xEAAE, 0x6224, 0xEAAF, 0x622C, 0xEAB0, 0x81E7, + 0xEAB1, 0x74EF, 0xEAB2, 0x74F4, 0xEAB3, 0x74FF, 0xEAB4, 0x750F, + 0xEAB5, 0x7511, 0xEAB6, 0x7513, 0xEAB7, 0x6534, 0xEAB8, 0x65EE, + 0xEAB9, 0x65EF, 0xEABA, 0x65F0, 0xEABB, 0x660A, 0xEABC, 0x6619, + 0xEABD, 0x6772, 0xEABE, 0x6603, 0xEABF, 0x6615, 0xEAC0, 0x6600, + 0xEAC1, 0x7085, 0xEAC2, 0x66F7, 0xEAC3, 0x661D, 0xEAC4, 0x6634, + 0xEAC5, 0x6631, 0xEAC6, 0x6636, 0xEAC7, 0x6635, 0xEAC8, 0x8006, + 0xEAC9, 0x665F, 0xEACA, 0x6654, 0xEACB, 0x6641, 0xEACC, 0x664F, + 0xEACD, 0x6656, 0xEACE, 0x6661, 0xEACF, 0x6657, 0xEAD0, 0x6677, + 0xEAD1, 0x6684, 0xEAD2, 0x668C, 0xEAD3, 0x66A7, 0xEAD4, 0x669D, + 0xEAD5, 0x66BE, 0xEAD6, 0x66DB, 0xEAD7, 0x66DC, 0xEAD8, 0x66E6, + 0xEAD9, 0x66E9, 0xEADA, 0x8D32, 0xEADB, 0x8D33, 0xEADC, 0x8D36, + 0xEADD, 0x8D3B, 0xEADE, 0x8D3D, 0xEADF, 0x8D40, 0xEAE0, 0x8D45, + 0xEAE1, 0x8D46, 0xEAE2, 0x8D48, 0xEAE3, 0x8D49, 0xEAE4, 0x8D47, + 0xEAE5, 0x8D4D, 0xEAE6, 0x8D55, 0xEAE7, 0x8D59, 0xEAE8, 0x89C7, + 0xEAE9, 0x89CA, 0xEAEA, 0x89CB, 0xEAEB, 0x89CC, 0xEAEC, 0x89CE, + 0xEAED, 0x89CF, 0xEAEE, 0x89D0, 0xEAEF, 0x89D1, 0xEAF0, 0x726E, + 0xEAF1, 0x729F, 0xEAF2, 0x725D, 0xEAF3, 0x7266, 0xEAF4, 0x726F, + 0xEAF5, 0x727E, 0xEAF6, 0x727F, 0xEAF7, 0x7284, 0xEAF8, 0x728B, + 0xEAF9, 0x728D, 0xEAFA, 0x728F, 0xEAFB, 0x7292, 0xEAFC, 0x6308, + 0xEAFD, 0x6332, 0xEAFE, 0x63B0, 0xEB40, 0x968C, 0xEB41, 0x968E, + 0xEB42, 0x9691, 0xEB43, 0x9692, 0xEB44, 0x9693, 0xEB45, 0x9695, + 0xEB46, 0x9696, 0xEB47, 0x969A, 0xEB48, 0x969B, 0xEB49, 0x969D, + 0xEB4A, 0x969E, 0xEB4B, 0x969F, 0xEB4C, 0x96A0, 0xEB4D, 0x96A1, + 0xEB4E, 0x96A2, 0xEB4F, 0x96A3, 0xEB50, 0x96A4, 0xEB51, 0x96A5, + 0xEB52, 0x96A6, 0xEB53, 0x96A8, 0xEB54, 0x96A9, 0xEB55, 0x96AA, + 0xEB56, 0x96AB, 0xEB57, 0x96AC, 0xEB58, 0x96AD, 0xEB59, 0x96AE, + 0xEB5A, 0x96AF, 0xEB5B, 0x96B1, 0xEB5C, 0x96B2, 0xEB5D, 0x96B4, + 0xEB5E, 0x96B5, 0xEB5F, 0x96B7, 0xEB60, 0x96B8, 0xEB61, 0x96BA, + 0xEB62, 0x96BB, 0xEB63, 0x96BF, 0xEB64, 0x96C2, 0xEB65, 0x96C3, + 0xEB66, 0x96C8, 0xEB67, 0x96CA, 0xEB68, 0x96CB, 0xEB69, 0x96D0, + 0xEB6A, 0x96D1, 0xEB6B, 0x96D3, 0xEB6C, 0x96D4, 0xEB6D, 0x96D6, + 0xEB6E, 0x96D7, 0xEB6F, 0x96D8, 0xEB70, 0x96D9, 0xEB71, 0x96DA, + 0xEB72, 0x96DB, 0xEB73, 0x96DC, 0xEB74, 0x96DD, 0xEB75, 0x96DE, + 0xEB76, 0x96DF, 0xEB77, 0x96E1, 0xEB78, 0x96E2, 0xEB79, 0x96E3, + 0xEB7A, 0x96E4, 0xEB7B, 0x96E5, 0xEB7C, 0x96E6, 0xEB7D, 0x96E7, + 0xEB7E, 0x96EB, 0xEB80, 0x96EC, 0xEB81, 0x96ED, 0xEB82, 0x96EE, + 0xEB83, 0x96F0, 0xEB84, 0x96F1, 0xEB85, 0x96F2, 0xEB86, 0x96F4, + 0xEB87, 0x96F5, 0xEB88, 0x96F8, 0xEB89, 0x96FA, 0xEB8A, 0x96FB, + 0xEB8B, 0x96FC, 0xEB8C, 0x96FD, 0xEB8D, 0x96FF, 0xEB8E, 0x9702, + 0xEB8F, 0x9703, 0xEB90, 0x9705, 0xEB91, 0x970A, 0xEB92, 0x970B, + 0xEB93, 0x970C, 0xEB94, 0x9710, 0xEB95, 0x9711, 0xEB96, 0x9712, + 0xEB97, 0x9714, 0xEB98, 0x9715, 0xEB99, 0x9717, 0xEB9A, 0x9718, + 0xEB9B, 0x9719, 0xEB9C, 0x971A, 0xEB9D, 0x971B, 0xEB9E, 0x971D, + 0xEB9F, 0x971F, 0xEBA0, 0x9720, 0xEBA1, 0x643F, 0xEBA2, 0x64D8, + 0xEBA3, 0x8004, 0xEBA4, 0x6BEA, 0xEBA5, 0x6BF3, 0xEBA6, 0x6BFD, + 0xEBA7, 0x6BF5, 0xEBA8, 0x6BF9, 0xEBA9, 0x6C05, 0xEBAA, 0x6C07, + 0xEBAB, 0x6C06, 0xEBAC, 0x6C0D, 0xEBAD, 0x6C15, 0xEBAE, 0x6C18, + 0xEBAF, 0x6C19, 0xEBB0, 0x6C1A, 0xEBB1, 0x6C21, 0xEBB2, 0x6C29, + 0xEBB3, 0x6C24, 0xEBB4, 0x6C2A, 0xEBB5, 0x6C32, 0xEBB6, 0x6535, + 0xEBB7, 0x6555, 0xEBB8, 0x656B, 0xEBB9, 0x724D, 0xEBBA, 0x7252, + 0xEBBB, 0x7256, 0xEBBC, 0x7230, 0xEBBD, 0x8662, 0xEBBE, 0x5216, + 0xEBBF, 0x809F, 0xEBC0, 0x809C, 0xEBC1, 0x8093, 0xEBC2, 0x80BC, + 0xEBC3, 0x670A, 0xEBC4, 0x80BD, 0xEBC5, 0x80B1, 0xEBC6, 0x80AB, + 0xEBC7, 0x80AD, 0xEBC8, 0x80B4, 0xEBC9, 0x80B7, 0xEBCA, 0x80E7, + 0xEBCB, 0x80E8, 0xEBCC, 0x80E9, 0xEBCD, 0x80EA, 0xEBCE, 0x80DB, + 0xEBCF, 0x80C2, 0xEBD0, 0x80C4, 0xEBD1, 0x80D9, 0xEBD2, 0x80CD, + 0xEBD3, 0x80D7, 0xEBD4, 0x6710, 0xEBD5, 0x80DD, 0xEBD6, 0x80EB, + 0xEBD7, 0x80F1, 0xEBD8, 0x80F4, 0xEBD9, 0x80ED, 0xEBDA, 0x810D, + 0xEBDB, 0x810E, 0xEBDC, 0x80F2, 0xEBDD, 0x80FC, 0xEBDE, 0x6715, + 0xEBDF, 0x8112, 0xEBE0, 0x8C5A, 0xEBE1, 0x8136, 0xEBE2, 0x811E, + 0xEBE3, 0x812C, 0xEBE4, 0x8118, 0xEBE5, 0x8132, 0xEBE6, 0x8148, + 0xEBE7, 0x814C, 0xEBE8, 0x8153, 0xEBE9, 0x8174, 0xEBEA, 0x8159, + 0xEBEB, 0x815A, 0xEBEC, 0x8171, 0xEBED, 0x8160, 0xEBEE, 0x8169, + 0xEBEF, 0x817C, 0xEBF0, 0x817D, 0xEBF1, 0x816D, 0xEBF2, 0x8167, + 0xEBF3, 0x584D, 0xEBF4, 0x5AB5, 0xEBF5, 0x8188, 0xEBF6, 0x8182, + 0xEBF7, 0x8191, 0xEBF8, 0x6ED5, 0xEBF9, 0x81A3, 0xEBFA, 0x81AA, + 0xEBFB, 0x81CC, 0xEBFC, 0x6726, 0xEBFD, 0x81CA, 0xEBFE, 0x81BB, + 0xEC40, 0x9721, 0xEC41, 0x9722, 0xEC42, 0x9723, 0xEC43, 0x9724, + 0xEC44, 0x9725, 0xEC45, 0x9726, 0xEC46, 0x9727, 0xEC47, 0x9728, + 0xEC48, 0x9729, 0xEC49, 0x972B, 0xEC4A, 0x972C, 0xEC4B, 0x972E, + 0xEC4C, 0x972F, 0xEC4D, 0x9731, 0xEC4E, 0x9733, 0xEC4F, 0x9734, + 0xEC50, 0x9735, 0xEC51, 0x9736, 0xEC52, 0x9737, 0xEC53, 0x973A, + 0xEC54, 0x973B, 0xEC55, 0x973C, 0xEC56, 0x973D, 0xEC57, 0x973F, + 0xEC58, 0x9740, 0xEC59, 0x9741, 0xEC5A, 0x9742, 0xEC5B, 0x9743, + 0xEC5C, 0x9744, 0xEC5D, 0x9745, 0xEC5E, 0x9746, 0xEC5F, 0x9747, + 0xEC60, 0x9748, 0xEC61, 0x9749, 0xEC62, 0x974A, 0xEC63, 0x974B, + 0xEC64, 0x974C, 0xEC65, 0x974D, 0xEC66, 0x974E, 0xEC67, 0x974F, + 0xEC68, 0x9750, 0xEC69, 0x9751, 0xEC6A, 0x9754, 0xEC6B, 0x9755, + 0xEC6C, 0x9757, 0xEC6D, 0x9758, 0xEC6E, 0x975A, 0xEC6F, 0x975C, + 0xEC70, 0x975D, 0xEC71, 0x975F, 0xEC72, 0x9763, 0xEC73, 0x9764, + 0xEC74, 0x9766, 0xEC75, 0x9767, 0xEC76, 0x9768, 0xEC77, 0x976A, + 0xEC78, 0x976B, 0xEC79, 0x976C, 0xEC7A, 0x976D, 0xEC7B, 0x976E, + 0xEC7C, 0x976F, 0xEC7D, 0x9770, 0xEC7E, 0x9771, 0xEC80, 0x9772, + 0xEC81, 0x9775, 0xEC82, 0x9777, 0xEC83, 0x9778, 0xEC84, 0x9779, + 0xEC85, 0x977A, 0xEC86, 0x977B, 0xEC87, 0x977D, 0xEC88, 0x977E, + 0xEC89, 0x977F, 0xEC8A, 0x9780, 0xEC8B, 0x9781, 0xEC8C, 0x9782, + 0xEC8D, 0x9783, 0xEC8E, 0x9784, 0xEC8F, 0x9786, 0xEC90, 0x9787, + 0xEC91, 0x9788, 0xEC92, 0x9789, 0xEC93, 0x978A, 0xEC94, 0x978C, + 0xEC95, 0x978E, 0xEC96, 0x978F, 0xEC97, 0x9790, 0xEC98, 0x9793, + 0xEC99, 0x9795, 0xEC9A, 0x9796, 0xEC9B, 0x9797, 0xEC9C, 0x9799, + 0xEC9D, 0x979A, 0xEC9E, 0x979B, 0xEC9F, 0x979C, 0xECA0, 0x979D, + 0xECA1, 0x81C1, 0xECA2, 0x81A6, 0xECA3, 0x6B24, 0xECA4, 0x6B37, + 0xECA5, 0x6B39, 0xECA6, 0x6B43, 0xECA7, 0x6B46, 0xECA8, 0x6B59, + 0xECA9, 0x98D1, 0xECAA, 0x98D2, 0xECAB, 0x98D3, 0xECAC, 0x98D5, + 0xECAD, 0x98D9, 0xECAE, 0x98DA, 0xECAF, 0x6BB3, 0xECB0, 0x5F40, + 0xECB1, 0x6BC2, 0xECB2, 0x89F3, 0xECB3, 0x6590, 0xECB4, 0x9F51, + 0xECB5, 0x6593, 0xECB6, 0x65BC, 0xECB7, 0x65C6, 0xECB8, 0x65C4, + 0xECB9, 0x65C3, 0xECBA, 0x65CC, 0xECBB, 0x65CE, 0xECBC, 0x65D2, + 0xECBD, 0x65D6, 0xECBE, 0x7080, 0xECBF, 0x709C, 0xECC0, 0x7096, + 0xECC1, 0x709D, 0xECC2, 0x70BB, 0xECC3, 0x70C0, 0xECC4, 0x70B7, + 0xECC5, 0x70AB, 0xECC6, 0x70B1, 0xECC7, 0x70E8, 0xECC8, 0x70CA, + 0xECC9, 0x7110, 0xECCA, 0x7113, 0xECCB, 0x7116, 0xECCC, 0x712F, + 0xECCD, 0x7131, 0xECCE, 0x7173, 0xECCF, 0x715C, 0xECD0, 0x7168, + 0xECD1, 0x7145, 0xECD2, 0x7172, 0xECD3, 0x714A, 0xECD4, 0x7178, + 0xECD5, 0x717A, 0xECD6, 0x7198, 0xECD7, 0x71B3, 0xECD8, 0x71B5, + 0xECD9, 0x71A8, 0xECDA, 0x71A0, 0xECDB, 0x71E0, 0xECDC, 0x71D4, + 0xECDD, 0x71E7, 0xECDE, 0x71F9, 0xECDF, 0x721D, 0xECE0, 0x7228, + 0xECE1, 0x706C, 0xECE2, 0x7118, 0xECE3, 0x7166, 0xECE4, 0x71B9, + 0xECE5, 0x623E, 0xECE6, 0x623D, 0xECE7, 0x6243, 0xECE8, 0x6248, + 0xECE9, 0x6249, 0xECEA, 0x793B, 0xECEB, 0x7940, 0xECEC, 0x7946, + 0xECED, 0x7949, 0xECEE, 0x795B, 0xECEF, 0x795C, 0xECF0, 0x7953, + 0xECF1, 0x795A, 0xECF2, 0x7962, 0xECF3, 0x7957, 0xECF4, 0x7960, + 0xECF5, 0x796F, 0xECF6, 0x7967, 0xECF7, 0x797A, 0xECF8, 0x7985, + 0xECF9, 0x798A, 0xECFA, 0x799A, 0xECFB, 0x79A7, 0xECFC, 0x79B3, + 0xECFD, 0x5FD1, 0xECFE, 0x5FD0, 0xED40, 0x979E, 0xED41, 0x979F, + 0xED42, 0x97A1, 0xED43, 0x97A2, 0xED44, 0x97A4, 0xED45, 0x97A5, + 0xED46, 0x97A6, 0xED47, 0x97A7, 0xED48, 0x97A8, 0xED49, 0x97A9, + 0xED4A, 0x97AA, 0xED4B, 0x97AC, 0xED4C, 0x97AE, 0xED4D, 0x97B0, + 0xED4E, 0x97B1, 0xED4F, 0x97B3, 0xED50, 0x97B5, 0xED51, 0x97B6, + 0xED52, 0x97B7, 0xED53, 0x97B8, 0xED54, 0x97B9, 0xED55, 0x97BA, + 0xED56, 0x97BB, 0xED57, 0x97BC, 0xED58, 0x97BD, 0xED59, 0x97BE, + 0xED5A, 0x97BF, 0xED5B, 0x97C0, 0xED5C, 0x97C1, 0xED5D, 0x97C2, + 0xED5E, 0x97C3, 0xED5F, 0x97C4, 0xED60, 0x97C5, 0xED61, 0x97C6, + 0xED62, 0x97C7, 0xED63, 0x97C8, 0xED64, 0x97C9, 0xED65, 0x97CA, + 0xED66, 0x97CB, 0xED67, 0x97CC, 0xED68, 0x97CD, 0xED69, 0x97CE, + 0xED6A, 0x97CF, 0xED6B, 0x97D0, 0xED6C, 0x97D1, 0xED6D, 0x97D2, + 0xED6E, 0x97D3, 0xED6F, 0x97D4, 0xED70, 0x97D5, 0xED71, 0x97D6, + 0xED72, 0x97D7, 0xED73, 0x97D8, 0xED74, 0x97D9, 0xED75, 0x97DA, + 0xED76, 0x97DB, 0xED77, 0x97DC, 0xED78, 0x97DD, 0xED79, 0x97DE, + 0xED7A, 0x97DF, 0xED7B, 0x97E0, 0xED7C, 0x97E1, 0xED7D, 0x97E2, + 0xED7E, 0x97E3, 0xED80, 0x97E4, 0xED81, 0x97E5, 0xED82, 0x97E8, + 0xED83, 0x97EE, 0xED84, 0x97EF, 0xED85, 0x97F0, 0xED86, 0x97F1, + 0xED87, 0x97F2, 0xED88, 0x97F4, 0xED89, 0x97F7, 0xED8A, 0x97F8, + 0xED8B, 0x97F9, 0xED8C, 0x97FA, 0xED8D, 0x97FB, 0xED8E, 0x97FC, + 0xED8F, 0x97FD, 0xED90, 0x97FE, 0xED91, 0x97FF, 0xED92, 0x9800, + 0xED93, 0x9801, 0xED94, 0x9802, 0xED95, 0x9803, 0xED96, 0x9804, + 0xED97, 0x9805, 0xED98, 0x9806, 0xED99, 0x9807, 0xED9A, 0x9808, + 0xED9B, 0x9809, 0xED9C, 0x980A, 0xED9D, 0x980B, 0xED9E, 0x980C, + 0xED9F, 0x980D, 0xEDA0, 0x980E, 0xEDA1, 0x603C, 0xEDA2, 0x605D, + 0xEDA3, 0x605A, 0xEDA4, 0x6067, 0xEDA5, 0x6041, 0xEDA6, 0x6059, + 0xEDA7, 0x6063, 0xEDA8, 0x60AB, 0xEDA9, 0x6106, 0xEDAA, 0x610D, + 0xEDAB, 0x615D, 0xEDAC, 0x61A9, 0xEDAD, 0x619D, 0xEDAE, 0x61CB, + 0xEDAF, 0x61D1, 0xEDB0, 0x6206, 0xEDB1, 0x8080, 0xEDB2, 0x807F, + 0xEDB3, 0x6C93, 0xEDB4, 0x6CF6, 0xEDB5, 0x6DFC, 0xEDB6, 0x77F6, + 0xEDB7, 0x77F8, 0xEDB8, 0x7800, 0xEDB9, 0x7809, 0xEDBA, 0x7817, + 0xEDBB, 0x7818, 0xEDBC, 0x7811, 0xEDBD, 0x65AB, 0xEDBE, 0x782D, + 0xEDBF, 0x781C, 0xEDC0, 0x781D, 0xEDC1, 0x7839, 0xEDC2, 0x783A, + 0xEDC3, 0x783B, 0xEDC4, 0x781F, 0xEDC5, 0x783C, 0xEDC6, 0x7825, + 0xEDC7, 0x782C, 0xEDC8, 0x7823, 0xEDC9, 0x7829, 0xEDCA, 0x784E, + 0xEDCB, 0x786D, 0xEDCC, 0x7856, 0xEDCD, 0x7857, 0xEDCE, 0x7826, + 0xEDCF, 0x7850, 0xEDD0, 0x7847, 0xEDD1, 0x784C, 0xEDD2, 0x786A, + 0xEDD3, 0x789B, 0xEDD4, 0x7893, 0xEDD5, 0x789A, 0xEDD6, 0x7887, + 0xEDD7, 0x789C, 0xEDD8, 0x78A1, 0xEDD9, 0x78A3, 0xEDDA, 0x78B2, + 0xEDDB, 0x78B9, 0xEDDC, 0x78A5, 0xEDDD, 0x78D4, 0xEDDE, 0x78D9, + 0xEDDF, 0x78C9, 0xEDE0, 0x78EC, 0xEDE1, 0x78F2, 0xEDE2, 0x7905, + 0xEDE3, 0x78F4, 0xEDE4, 0x7913, 0xEDE5, 0x7924, 0xEDE6, 0x791E, + 0xEDE7, 0x7934, 0xEDE8, 0x9F9B, 0xEDE9, 0x9EF9, 0xEDEA, 0x9EFB, + 0xEDEB, 0x9EFC, 0xEDEC, 0x76F1, 0xEDED, 0x7704, 0xEDEE, 0x770D, + 0xEDEF, 0x76F9, 0xEDF0, 0x7707, 0xEDF1, 0x7708, 0xEDF2, 0x771A, + 0xEDF3, 0x7722, 0xEDF4, 0x7719, 0xEDF5, 0x772D, 0xEDF6, 0x7726, + 0xEDF7, 0x7735, 0xEDF8, 0x7738, 0xEDF9, 0x7750, 0xEDFA, 0x7751, + 0xEDFB, 0x7747, 0xEDFC, 0x7743, 0xEDFD, 0x775A, 0xEDFE, 0x7768, + 0xEE40, 0x980F, 0xEE41, 0x9810, 0xEE42, 0x9811, 0xEE43, 0x9812, + 0xEE44, 0x9813, 0xEE45, 0x9814, 0xEE46, 0x9815, 0xEE47, 0x9816, + 0xEE48, 0x9817, 0xEE49, 0x9818, 0xEE4A, 0x9819, 0xEE4B, 0x981A, + 0xEE4C, 0x981B, 0xEE4D, 0x981C, 0xEE4E, 0x981D, 0xEE4F, 0x981E, + 0xEE50, 0x981F, 0xEE51, 0x9820, 0xEE52, 0x9821, 0xEE53, 0x9822, + 0xEE54, 0x9823, 0xEE55, 0x9824, 0xEE56, 0x9825, 0xEE57, 0x9826, + 0xEE58, 0x9827, 0xEE59, 0x9828, 0xEE5A, 0x9829, 0xEE5B, 0x982A, + 0xEE5C, 0x982B, 0xEE5D, 0x982C, 0xEE5E, 0x982D, 0xEE5F, 0x982E, + 0xEE60, 0x982F, 0xEE61, 0x9830, 0xEE62, 0x9831, 0xEE63, 0x9832, + 0xEE64, 0x9833, 0xEE65, 0x9834, 0xEE66, 0x9835, 0xEE67, 0x9836, + 0xEE68, 0x9837, 0xEE69, 0x9838, 0xEE6A, 0x9839, 0xEE6B, 0x983A, + 0xEE6C, 0x983B, 0xEE6D, 0x983C, 0xEE6E, 0x983D, 0xEE6F, 0x983E, + 0xEE70, 0x983F, 0xEE71, 0x9840, 0xEE72, 0x9841, 0xEE73, 0x9842, + 0xEE74, 0x9843, 0xEE75, 0x9844, 0xEE76, 0x9845, 0xEE77, 0x9846, + 0xEE78, 0x9847, 0xEE79, 0x9848, 0xEE7A, 0x9849, 0xEE7B, 0x984A, + 0xEE7C, 0x984B, 0xEE7D, 0x984C, 0xEE7E, 0x984D, 0xEE80, 0x984E, + 0xEE81, 0x984F, 0xEE82, 0x9850, 0xEE83, 0x9851, 0xEE84, 0x9852, + 0xEE85, 0x9853, 0xEE86, 0x9854, 0xEE87, 0x9855, 0xEE88, 0x9856, + 0xEE89, 0x9857, 0xEE8A, 0x9858, 0xEE8B, 0x9859, 0xEE8C, 0x985A, + 0xEE8D, 0x985B, 0xEE8E, 0x985C, 0xEE8F, 0x985D, 0xEE90, 0x985E, + 0xEE91, 0x985F, 0xEE92, 0x9860, 0xEE93, 0x9861, 0xEE94, 0x9862, + 0xEE95, 0x9863, 0xEE96, 0x9864, 0xEE97, 0x9865, 0xEE98, 0x9866, + 0xEE99, 0x9867, 0xEE9A, 0x9868, 0xEE9B, 0x9869, 0xEE9C, 0x986A, + 0xEE9D, 0x986B, 0xEE9E, 0x986C, 0xEE9F, 0x986D, 0xEEA0, 0x986E, + 0xEEA1, 0x7762, 0xEEA2, 0x7765, 0xEEA3, 0x777F, 0xEEA4, 0x778D, + 0xEEA5, 0x777D, 0xEEA6, 0x7780, 0xEEA7, 0x778C, 0xEEA8, 0x7791, + 0xEEA9, 0x779F, 0xEEAA, 0x77A0, 0xEEAB, 0x77B0, 0xEEAC, 0x77B5, + 0xEEAD, 0x77BD, 0xEEAE, 0x753A, 0xEEAF, 0x7540, 0xEEB0, 0x754E, + 0xEEB1, 0x754B, 0xEEB2, 0x7548, 0xEEB3, 0x755B, 0xEEB4, 0x7572, + 0xEEB5, 0x7579, 0xEEB6, 0x7583, 0xEEB7, 0x7F58, 0xEEB8, 0x7F61, + 0xEEB9, 0x7F5F, 0xEEBA, 0x8A48, 0xEEBB, 0x7F68, 0xEEBC, 0x7F74, + 0xEEBD, 0x7F71, 0xEEBE, 0x7F79, 0xEEBF, 0x7F81, 0xEEC0, 0x7F7E, + 0xEEC1, 0x76CD, 0xEEC2, 0x76E5, 0xEEC3, 0x8832, 0xEEC4, 0x9485, + 0xEEC5, 0x9486, 0xEEC6, 0x9487, 0xEEC7, 0x948B, 0xEEC8, 0x948A, + 0xEEC9, 0x948C, 0xEECA, 0x948D, 0xEECB, 0x948F, 0xEECC, 0x9490, + 0xEECD, 0x9494, 0xEECE, 0x9497, 0xEECF, 0x9495, 0xEED0, 0x949A, + 0xEED1, 0x949B, 0xEED2, 0x949C, 0xEED3, 0x94A3, 0xEED4, 0x94A4, + 0xEED5, 0x94AB, 0xEED6, 0x94AA, 0xEED7, 0x94AD, 0xEED8, 0x94AC, + 0xEED9, 0x94AF, 0xEEDA, 0x94B0, 0xEEDB, 0x94B2, 0xEEDC, 0x94B4, + 0xEEDD, 0x94B6, 0xEEDE, 0x94B7, 0xEEDF, 0x94B8, 0xEEE0, 0x94B9, + 0xEEE1, 0x94BA, 0xEEE2, 0x94BC, 0xEEE3, 0x94BD, 0xEEE4, 0x94BF, + 0xEEE5, 0x94C4, 0xEEE6, 0x94C8, 0xEEE7, 0x94C9, 0xEEE8, 0x94CA, + 0xEEE9, 0x94CB, 0xEEEA, 0x94CC, 0xEEEB, 0x94CD, 0xEEEC, 0x94CE, + 0xEEED, 0x94D0, 0xEEEE, 0x94D1, 0xEEEF, 0x94D2, 0xEEF0, 0x94D5, + 0xEEF1, 0x94D6, 0xEEF2, 0x94D7, 0xEEF3, 0x94D9, 0xEEF4, 0x94D8, + 0xEEF5, 0x94DB, 0xEEF6, 0x94DE, 0xEEF7, 0x94DF, 0xEEF8, 0x94E0, + 0xEEF9, 0x94E2, 0xEEFA, 0x94E4, 0xEEFB, 0x94E5, 0xEEFC, 0x94E7, + 0xEEFD, 0x94E8, 0xEEFE, 0x94EA, 0xEF40, 0x986F, 0xEF41, 0x9870, + 0xEF42, 0x9871, 0xEF43, 0x9872, 0xEF44, 0x9873, 0xEF45, 0x9874, + 0xEF46, 0x988B, 0xEF47, 0x988E, 0xEF48, 0x9892, 0xEF49, 0x9895, + 0xEF4A, 0x9899, 0xEF4B, 0x98A3, 0xEF4C, 0x98A8, 0xEF4D, 0x98A9, + 0xEF4E, 0x98AA, 0xEF4F, 0x98AB, 0xEF50, 0x98AC, 0xEF51, 0x98AD, + 0xEF52, 0x98AE, 0xEF53, 0x98AF, 0xEF54, 0x98B0, 0xEF55, 0x98B1, + 0xEF56, 0x98B2, 0xEF57, 0x98B3, 0xEF58, 0x98B4, 0xEF59, 0x98B5, + 0xEF5A, 0x98B6, 0xEF5B, 0x98B7, 0xEF5C, 0x98B8, 0xEF5D, 0x98B9, + 0xEF5E, 0x98BA, 0xEF5F, 0x98BB, 0xEF60, 0x98BC, 0xEF61, 0x98BD, + 0xEF62, 0x98BE, 0xEF63, 0x98BF, 0xEF64, 0x98C0, 0xEF65, 0x98C1, + 0xEF66, 0x98C2, 0xEF67, 0x98C3, 0xEF68, 0x98C4, 0xEF69, 0x98C5, + 0xEF6A, 0x98C6, 0xEF6B, 0x98C7, 0xEF6C, 0x98C8, 0xEF6D, 0x98C9, + 0xEF6E, 0x98CA, 0xEF6F, 0x98CB, 0xEF70, 0x98CC, 0xEF71, 0x98CD, + 0xEF72, 0x98CF, 0xEF73, 0x98D0, 0xEF74, 0x98D4, 0xEF75, 0x98D6, + 0xEF76, 0x98D7, 0xEF77, 0x98DB, 0xEF78, 0x98DC, 0xEF79, 0x98DD, + 0xEF7A, 0x98E0, 0xEF7B, 0x98E1, 0xEF7C, 0x98E2, 0xEF7D, 0x98E3, + 0xEF7E, 0x98E4, 0xEF80, 0x98E5, 0xEF81, 0x98E6, 0xEF82, 0x98E9, + 0xEF83, 0x98EA, 0xEF84, 0x98EB, 0xEF85, 0x98EC, 0xEF86, 0x98ED, + 0xEF87, 0x98EE, 0xEF88, 0x98EF, 0xEF89, 0x98F0, 0xEF8A, 0x98F1, + 0xEF8B, 0x98F2, 0xEF8C, 0x98F3, 0xEF8D, 0x98F4, 0xEF8E, 0x98F5, + 0xEF8F, 0x98F6, 0xEF90, 0x98F7, 0xEF91, 0x98F8, 0xEF92, 0x98F9, + 0xEF93, 0x98FA, 0xEF94, 0x98FB, 0xEF95, 0x98FC, 0xEF96, 0x98FD, + 0xEF97, 0x98FE, 0xEF98, 0x98FF, 0xEF99, 0x9900, 0xEF9A, 0x9901, + 0xEF9B, 0x9902, 0xEF9C, 0x9903, 0xEF9D, 0x9904, 0xEF9E, 0x9905, + 0xEF9F, 0x9906, 0xEFA0, 0x9907, 0xEFA1, 0x94E9, 0xEFA2, 0x94EB, + 0xEFA3, 0x94EE, 0xEFA4, 0x94EF, 0xEFA5, 0x94F3, 0xEFA6, 0x94F4, + 0xEFA7, 0x94F5, 0xEFA8, 0x94F7, 0xEFA9, 0x94F9, 0xEFAA, 0x94FC, + 0xEFAB, 0x94FD, 0xEFAC, 0x94FF, 0xEFAD, 0x9503, 0xEFAE, 0x9502, + 0xEFAF, 0x9506, 0xEFB0, 0x9507, 0xEFB1, 0x9509, 0xEFB2, 0x950A, + 0xEFB3, 0x950D, 0xEFB4, 0x950E, 0xEFB5, 0x950F, 0xEFB6, 0x9512, + 0xEFB7, 0x9513, 0xEFB8, 0x9514, 0xEFB9, 0x9515, 0xEFBA, 0x9516, + 0xEFBB, 0x9518, 0xEFBC, 0x951B, 0xEFBD, 0x951D, 0xEFBE, 0x951E, + 0xEFBF, 0x951F, 0xEFC0, 0x9522, 0xEFC1, 0x952A, 0xEFC2, 0x952B, + 0xEFC3, 0x9529, 0xEFC4, 0x952C, 0xEFC5, 0x9531, 0xEFC6, 0x9532, + 0xEFC7, 0x9534, 0xEFC8, 0x9536, 0xEFC9, 0x9537, 0xEFCA, 0x9538, + 0xEFCB, 0x953C, 0xEFCC, 0x953E, 0xEFCD, 0x953F, 0xEFCE, 0x9542, + 0xEFCF, 0x9535, 0xEFD0, 0x9544, 0xEFD1, 0x9545, 0xEFD2, 0x9546, + 0xEFD3, 0x9549, 0xEFD4, 0x954C, 0xEFD5, 0x954E, 0xEFD6, 0x954F, + 0xEFD7, 0x9552, 0xEFD8, 0x9553, 0xEFD9, 0x9554, 0xEFDA, 0x9556, + 0xEFDB, 0x9557, 0xEFDC, 0x9558, 0xEFDD, 0x9559, 0xEFDE, 0x955B, + 0xEFDF, 0x955E, 0xEFE0, 0x955F, 0xEFE1, 0x955D, 0xEFE2, 0x9561, + 0xEFE3, 0x9562, 0xEFE4, 0x9564, 0xEFE5, 0x9565, 0xEFE6, 0x9566, + 0xEFE7, 0x9567, 0xEFE8, 0x9568, 0xEFE9, 0x9569, 0xEFEA, 0x956A, + 0xEFEB, 0x956B, 0xEFEC, 0x956C, 0xEFED, 0x956F, 0xEFEE, 0x9571, + 0xEFEF, 0x9572, 0xEFF0, 0x9573, 0xEFF1, 0x953A, 0xEFF2, 0x77E7, + 0xEFF3, 0x77EC, 0xEFF4, 0x96C9, 0xEFF5, 0x79D5, 0xEFF6, 0x79ED, + 0xEFF7, 0x79E3, 0xEFF8, 0x79EB, 0xEFF9, 0x7A06, 0xEFFA, 0x5D47, + 0xEFFB, 0x7A03, 0xEFFC, 0x7A02, 0xEFFD, 0x7A1E, 0xEFFE, 0x7A14, + 0xF040, 0x9908, 0xF041, 0x9909, 0xF042, 0x990A, 0xF043, 0x990B, + 0xF044, 0x990C, 0xF045, 0x990E, 0xF046, 0x990F, 0xF047, 0x9911, + 0xF048, 0x9912, 0xF049, 0x9913, 0xF04A, 0x9914, 0xF04B, 0x9915, + 0xF04C, 0x9916, 0xF04D, 0x9917, 0xF04E, 0x9918, 0xF04F, 0x9919, + 0xF050, 0x991A, 0xF051, 0x991B, 0xF052, 0x991C, 0xF053, 0x991D, + 0xF054, 0x991E, 0xF055, 0x991F, 0xF056, 0x9920, 0xF057, 0x9921, + 0xF058, 0x9922, 0xF059, 0x9923, 0xF05A, 0x9924, 0xF05B, 0x9925, + 0xF05C, 0x9926, 0xF05D, 0x9927, 0xF05E, 0x9928, 0xF05F, 0x9929, + 0xF060, 0x992A, 0xF061, 0x992B, 0xF062, 0x992C, 0xF063, 0x992D, + 0xF064, 0x992F, 0xF065, 0x9930, 0xF066, 0x9931, 0xF067, 0x9932, + 0xF068, 0x9933, 0xF069, 0x9934, 0xF06A, 0x9935, 0xF06B, 0x9936, + 0xF06C, 0x9937, 0xF06D, 0x9938, 0xF06E, 0x9939, 0xF06F, 0x993A, + 0xF070, 0x993B, 0xF071, 0x993C, 0xF072, 0x993D, 0xF073, 0x993E, + 0xF074, 0x993F, 0xF075, 0x9940, 0xF076, 0x9941, 0xF077, 0x9942, + 0xF078, 0x9943, 0xF079, 0x9944, 0xF07A, 0x9945, 0xF07B, 0x9946, + 0xF07C, 0x9947, 0xF07D, 0x9948, 0xF07E, 0x9949, 0xF080, 0x994A, + 0xF081, 0x994B, 0xF082, 0x994C, 0xF083, 0x994D, 0xF084, 0x994E, + 0xF085, 0x994F, 0xF086, 0x9950, 0xF087, 0x9951, 0xF088, 0x9952, + 0xF089, 0x9953, 0xF08A, 0x9956, 0xF08B, 0x9957, 0xF08C, 0x9958, + 0xF08D, 0x9959, 0xF08E, 0x995A, 0xF08F, 0x995B, 0xF090, 0x995C, + 0xF091, 0x995D, 0xF092, 0x995E, 0xF093, 0x995F, 0xF094, 0x9960, + 0xF095, 0x9961, 0xF096, 0x9962, 0xF097, 0x9964, 0xF098, 0x9966, + 0xF099, 0x9973, 0xF09A, 0x9978, 0xF09B, 0x9979, 0xF09C, 0x997B, + 0xF09D, 0x997E, 0xF09E, 0x9982, 0xF09F, 0x9983, 0xF0A0, 0x9989, + 0xF0A1, 0x7A39, 0xF0A2, 0x7A37, 0xF0A3, 0x7A51, 0xF0A4, 0x9ECF, + 0xF0A5, 0x99A5, 0xF0A6, 0x7A70, 0xF0A7, 0x7688, 0xF0A8, 0x768E, + 0xF0A9, 0x7693, 0xF0AA, 0x7699, 0xF0AB, 0x76A4, 0xF0AC, 0x74DE, + 0xF0AD, 0x74E0, 0xF0AE, 0x752C, 0xF0AF, 0x9E20, 0xF0B0, 0x9E22, + 0xF0B1, 0x9E28, 0xF0B2, 0x9E29, 0xF0B3, 0x9E2A, 0xF0B4, 0x9E2B, + 0xF0B5, 0x9E2C, 0xF0B6, 0x9E32, 0xF0B7, 0x9E31, 0xF0B8, 0x9E36, + 0xF0B9, 0x9E38, 0xF0BA, 0x9E37, 0xF0BB, 0x9E39, 0xF0BC, 0x9E3A, + 0xF0BD, 0x9E3E, 0xF0BE, 0x9E41, 0xF0BF, 0x9E42, 0xF0C0, 0x9E44, + 0xF0C1, 0x9E46, 0xF0C2, 0x9E47, 0xF0C3, 0x9E48, 0xF0C4, 0x9E49, + 0xF0C5, 0x9E4B, 0xF0C6, 0x9E4C, 0xF0C7, 0x9E4E, 0xF0C8, 0x9E51, + 0xF0C9, 0x9E55, 0xF0CA, 0x9E57, 0xF0CB, 0x9E5A, 0xF0CC, 0x9E5B, + 0xF0CD, 0x9E5C, 0xF0CE, 0x9E5E, 0xF0CF, 0x9E63, 0xF0D0, 0x9E66, + 0xF0D1, 0x9E67, 0xF0D2, 0x9E68, 0xF0D3, 0x9E69, 0xF0D4, 0x9E6A, + 0xF0D5, 0x9E6B, 0xF0D6, 0x9E6C, 0xF0D7, 0x9E71, 0xF0D8, 0x9E6D, + 0xF0D9, 0x9E73, 0xF0DA, 0x7592, 0xF0DB, 0x7594, 0xF0DC, 0x7596, + 0xF0DD, 0x75A0, 0xF0DE, 0x759D, 0xF0DF, 0x75AC, 0xF0E0, 0x75A3, + 0xF0E1, 0x75B3, 0xF0E2, 0x75B4, 0xF0E3, 0x75B8, 0xF0E4, 0x75C4, + 0xF0E5, 0x75B1, 0xF0E6, 0x75B0, 0xF0E7, 0x75C3, 0xF0E8, 0x75C2, + 0xF0E9, 0x75D6, 0xF0EA, 0x75CD, 0xF0EB, 0x75E3, 0xF0EC, 0x75E8, + 0xF0ED, 0x75E6, 0xF0EE, 0x75E4, 0xF0EF, 0x75EB, 0xF0F0, 0x75E7, + 0xF0F1, 0x7603, 0xF0F2, 0x75F1, 0xF0F3, 0x75FC, 0xF0F4, 0x75FF, + 0xF0F5, 0x7610, 0xF0F6, 0x7600, 0xF0F7, 0x7605, 0xF0F8, 0x760C, + 0xF0F9, 0x7617, 0xF0FA, 0x760A, 0xF0FB, 0x7625, 0xF0FC, 0x7618, + 0xF0FD, 0x7615, 0xF0FE, 0x7619, 0xF140, 0x998C, 0xF141, 0x998E, + 0xF142, 0x999A, 0xF143, 0x999B, 0xF144, 0x999C, 0xF145, 0x999D, + 0xF146, 0x999E, 0xF147, 0x999F, 0xF148, 0x99A0, 0xF149, 0x99A1, + 0xF14A, 0x99A2, 0xF14B, 0x99A3, 0xF14C, 0x99A4, 0xF14D, 0x99A6, + 0xF14E, 0x99A7, 0xF14F, 0x99A9, 0xF150, 0x99AA, 0xF151, 0x99AB, + 0xF152, 0x99AC, 0xF153, 0x99AD, 0xF154, 0x99AE, 0xF155, 0x99AF, + 0xF156, 0x99B0, 0xF157, 0x99B1, 0xF158, 0x99B2, 0xF159, 0x99B3, + 0xF15A, 0x99B4, 0xF15B, 0x99B5, 0xF15C, 0x99B6, 0xF15D, 0x99B7, + 0xF15E, 0x99B8, 0xF15F, 0x99B9, 0xF160, 0x99BA, 0xF161, 0x99BB, + 0xF162, 0x99BC, 0xF163, 0x99BD, 0xF164, 0x99BE, 0xF165, 0x99BF, + 0xF166, 0x99C0, 0xF167, 0x99C1, 0xF168, 0x99C2, 0xF169, 0x99C3, + 0xF16A, 0x99C4, 0xF16B, 0x99C5, 0xF16C, 0x99C6, 0xF16D, 0x99C7, + 0xF16E, 0x99C8, 0xF16F, 0x99C9, 0xF170, 0x99CA, 0xF171, 0x99CB, + 0xF172, 0x99CC, 0xF173, 0x99CD, 0xF174, 0x99CE, 0xF175, 0x99CF, + 0xF176, 0x99D0, 0xF177, 0x99D1, 0xF178, 0x99D2, 0xF179, 0x99D3, + 0xF17A, 0x99D4, 0xF17B, 0x99D5, 0xF17C, 0x99D6, 0xF17D, 0x99D7, + 0xF17E, 0x99D8, 0xF180, 0x99D9, 0xF181, 0x99DA, 0xF182, 0x99DB, + 0xF183, 0x99DC, 0xF184, 0x99DD, 0xF185, 0x99DE, 0xF186, 0x99DF, + 0xF187, 0x99E0, 0xF188, 0x99E1, 0xF189, 0x99E2, 0xF18A, 0x99E3, + 0xF18B, 0x99E4, 0xF18C, 0x99E5, 0xF18D, 0x99E6, 0xF18E, 0x99E7, + 0xF18F, 0x99E8, 0xF190, 0x99E9, 0xF191, 0x99EA, 0xF192, 0x99EB, + 0xF193, 0x99EC, 0xF194, 0x99ED, 0xF195, 0x99EE, 0xF196, 0x99EF, + 0xF197, 0x99F0, 0xF198, 0x99F1, 0xF199, 0x99F2, 0xF19A, 0x99F3, + 0xF19B, 0x99F4, 0xF19C, 0x99F5, 0xF19D, 0x99F6, 0xF19E, 0x99F7, + 0xF19F, 0x99F8, 0xF1A0, 0x99F9, 0xF1A1, 0x761B, 0xF1A2, 0x763C, + 0xF1A3, 0x7622, 0xF1A4, 0x7620, 0xF1A5, 0x7640, 0xF1A6, 0x762D, + 0xF1A7, 0x7630, 0xF1A8, 0x763F, 0xF1A9, 0x7635, 0xF1AA, 0x7643, + 0xF1AB, 0x763E, 0xF1AC, 0x7633, 0xF1AD, 0x764D, 0xF1AE, 0x765E, + 0xF1AF, 0x7654, 0xF1B0, 0x765C, 0xF1B1, 0x7656, 0xF1B2, 0x766B, + 0xF1B3, 0x766F, 0xF1B4, 0x7FCA, 0xF1B5, 0x7AE6, 0xF1B6, 0x7A78, + 0xF1B7, 0x7A79, 0xF1B8, 0x7A80, 0xF1B9, 0x7A86, 0xF1BA, 0x7A88, + 0xF1BB, 0x7A95, 0xF1BC, 0x7AA6, 0xF1BD, 0x7AA0, 0xF1BE, 0x7AAC, + 0xF1BF, 0x7AA8, 0xF1C0, 0x7AAD, 0xF1C1, 0x7AB3, 0xF1C2, 0x8864, + 0xF1C3, 0x8869, 0xF1C4, 0x8872, 0xF1C5, 0x887D, 0xF1C6, 0x887F, + 0xF1C7, 0x8882, 0xF1C8, 0x88A2, 0xF1C9, 0x88C6, 0xF1CA, 0x88B7, + 0xF1CB, 0x88BC, 0xF1CC, 0x88C9, 0xF1CD, 0x88E2, 0xF1CE, 0x88CE, + 0xF1CF, 0x88E3, 0xF1D0, 0x88E5, 0xF1D1, 0x88F1, 0xF1D2, 0x891A, + 0xF1D3, 0x88FC, 0xF1D4, 0x88E8, 0xF1D5, 0x88FE, 0xF1D6, 0x88F0, + 0xF1D7, 0x8921, 0xF1D8, 0x8919, 0xF1D9, 0x8913, 0xF1DA, 0x891B, + 0xF1DB, 0x890A, 0xF1DC, 0x8934, 0xF1DD, 0x892B, 0xF1DE, 0x8936, + 0xF1DF, 0x8941, 0xF1E0, 0x8966, 0xF1E1, 0x897B, 0xF1E2, 0x758B, + 0xF1E3, 0x80E5, 0xF1E4, 0x76B2, 0xF1E5, 0x76B4, 0xF1E6, 0x77DC, + 0xF1E7, 0x8012, 0xF1E8, 0x8014, 0xF1E9, 0x8016, 0xF1EA, 0x801C, + 0xF1EB, 0x8020, 0xF1EC, 0x8022, 0xF1ED, 0x8025, 0xF1EE, 0x8026, + 0xF1EF, 0x8027, 0xF1F0, 0x8029, 0xF1F1, 0x8028, 0xF1F2, 0x8031, + 0xF1F3, 0x800B, 0xF1F4, 0x8035, 0xF1F5, 0x8043, 0xF1F6, 0x8046, + 0xF1F7, 0x804D, 0xF1F8, 0x8052, 0xF1F9, 0x8069, 0xF1FA, 0x8071, + 0xF1FB, 0x8983, 0xF1FC, 0x9878, 0xF1FD, 0x9880, 0xF1FE, 0x9883, + 0xF240, 0x99FA, 0xF241, 0x99FB, 0xF242, 0x99FC, 0xF243, 0x99FD, + 0xF244, 0x99FE, 0xF245, 0x99FF, 0xF246, 0x9A00, 0xF247, 0x9A01, + 0xF248, 0x9A02, 0xF249, 0x9A03, 0xF24A, 0x9A04, 0xF24B, 0x9A05, + 0xF24C, 0x9A06, 0xF24D, 0x9A07, 0xF24E, 0x9A08, 0xF24F, 0x9A09, + 0xF250, 0x9A0A, 0xF251, 0x9A0B, 0xF252, 0x9A0C, 0xF253, 0x9A0D, + 0xF254, 0x9A0E, 0xF255, 0x9A0F, 0xF256, 0x9A10, 0xF257, 0x9A11, + 0xF258, 0x9A12, 0xF259, 0x9A13, 0xF25A, 0x9A14, 0xF25B, 0x9A15, + 0xF25C, 0x9A16, 0xF25D, 0x9A17, 0xF25E, 0x9A18, 0xF25F, 0x9A19, + 0xF260, 0x9A1A, 0xF261, 0x9A1B, 0xF262, 0x9A1C, 0xF263, 0x9A1D, + 0xF264, 0x9A1E, 0xF265, 0x9A1F, 0xF266, 0x9A20, 0xF267, 0x9A21, + 0xF268, 0x9A22, 0xF269, 0x9A23, 0xF26A, 0x9A24, 0xF26B, 0x9A25, + 0xF26C, 0x9A26, 0xF26D, 0x9A27, 0xF26E, 0x9A28, 0xF26F, 0x9A29, + 0xF270, 0x9A2A, 0xF271, 0x9A2B, 0xF272, 0x9A2C, 0xF273, 0x9A2D, + 0xF274, 0x9A2E, 0xF275, 0x9A2F, 0xF276, 0x9A30, 0xF277, 0x9A31, + 0xF278, 0x9A32, 0xF279, 0x9A33, 0xF27A, 0x9A34, 0xF27B, 0x9A35, + 0xF27C, 0x9A36, 0xF27D, 0x9A37, 0xF27E, 0x9A38, 0xF280, 0x9A39, + 0xF281, 0x9A3A, 0xF282, 0x9A3B, 0xF283, 0x9A3C, 0xF284, 0x9A3D, + 0xF285, 0x9A3E, 0xF286, 0x9A3F, 0xF287, 0x9A40, 0xF288, 0x9A41, + 0xF289, 0x9A42, 0xF28A, 0x9A43, 0xF28B, 0x9A44, 0xF28C, 0x9A45, + 0xF28D, 0x9A46, 0xF28E, 0x9A47, 0xF28F, 0x9A48, 0xF290, 0x9A49, + 0xF291, 0x9A4A, 0xF292, 0x9A4B, 0xF293, 0x9A4C, 0xF294, 0x9A4D, + 0xF295, 0x9A4E, 0xF296, 0x9A4F, 0xF297, 0x9A50, 0xF298, 0x9A51, + 0xF299, 0x9A52, 0xF29A, 0x9A53, 0xF29B, 0x9A54, 0xF29C, 0x9A55, + 0xF29D, 0x9A56, 0xF29E, 0x9A57, 0xF29F, 0x9A58, 0xF2A0, 0x9A59, + 0xF2A1, 0x9889, 0xF2A2, 0x988C, 0xF2A3, 0x988D, 0xF2A4, 0x988F, + 0xF2A5, 0x9894, 0xF2A6, 0x989A, 0xF2A7, 0x989B, 0xF2A8, 0x989E, + 0xF2A9, 0x989F, 0xF2AA, 0x98A1, 0xF2AB, 0x98A2, 0xF2AC, 0x98A5, + 0xF2AD, 0x98A6, 0xF2AE, 0x864D, 0xF2AF, 0x8654, 0xF2B0, 0x866C, + 0xF2B1, 0x866E, 0xF2B2, 0x867F, 0xF2B3, 0x867A, 0xF2B4, 0x867C, + 0xF2B5, 0x867B, 0xF2B6, 0x86A8, 0xF2B7, 0x868D, 0xF2B8, 0x868B, + 0xF2B9, 0x86AC, 0xF2BA, 0x869D, 0xF2BB, 0x86A7, 0xF2BC, 0x86A3, + 0xF2BD, 0x86AA, 0xF2BE, 0x8693, 0xF2BF, 0x86A9, 0xF2C0, 0x86B6, + 0xF2C1, 0x86C4, 0xF2C2, 0x86B5, 0xF2C3, 0x86CE, 0xF2C4, 0x86B0, + 0xF2C5, 0x86BA, 0xF2C6, 0x86B1, 0xF2C7, 0x86AF, 0xF2C8, 0x86C9, + 0xF2C9, 0x86CF, 0xF2CA, 0x86B4, 0xF2CB, 0x86E9, 0xF2CC, 0x86F1, + 0xF2CD, 0x86F2, 0xF2CE, 0x86ED, 0xF2CF, 0x86F3, 0xF2D0, 0x86D0, + 0xF2D1, 0x8713, 0xF2D2, 0x86DE, 0xF2D3, 0x86F4, 0xF2D4, 0x86DF, + 0xF2D5, 0x86D8, 0xF2D6, 0x86D1, 0xF2D7, 0x8703, 0xF2D8, 0x8707, + 0xF2D9, 0x86F8, 0xF2DA, 0x8708, 0xF2DB, 0x870A, 0xF2DC, 0x870D, + 0xF2DD, 0x8709, 0xF2DE, 0x8723, 0xF2DF, 0x873B, 0xF2E0, 0x871E, + 0xF2E1, 0x8725, 0xF2E2, 0x872E, 0xF2E3, 0x871A, 0xF2E4, 0x873E, + 0xF2E5, 0x8748, 0xF2E6, 0x8734, 0xF2E7, 0x8731, 0xF2E8, 0x8729, + 0xF2E9, 0x8737, 0xF2EA, 0x873F, 0xF2EB, 0x8782, 0xF2EC, 0x8722, + 0xF2ED, 0x877D, 0xF2EE, 0x877E, 0xF2EF, 0x877B, 0xF2F0, 0x8760, + 0xF2F1, 0x8770, 0xF2F2, 0x874C, 0xF2F3, 0x876E, 0xF2F4, 0x878B, + 0xF2F5, 0x8753, 0xF2F6, 0x8763, 0xF2F7, 0x877C, 0xF2F8, 0x8764, + 0xF2F9, 0x8759, 0xF2FA, 0x8765, 0xF2FB, 0x8793, 0xF2FC, 0x87AF, + 0xF2FD, 0x87A8, 0xF2FE, 0x87D2, 0xF340, 0x9A5A, 0xF341, 0x9A5B, + 0xF342, 0x9A5C, 0xF343, 0x9A5D, 0xF344, 0x9A5E, 0xF345, 0x9A5F, + 0xF346, 0x9A60, 0xF347, 0x9A61, 0xF348, 0x9A62, 0xF349, 0x9A63, + 0xF34A, 0x9A64, 0xF34B, 0x9A65, 0xF34C, 0x9A66, 0xF34D, 0x9A67, + 0xF34E, 0x9A68, 0xF34F, 0x9A69, 0xF350, 0x9A6A, 0xF351, 0x9A6B, + 0xF352, 0x9A72, 0xF353, 0x9A83, 0xF354, 0x9A89, 0xF355, 0x9A8D, + 0xF356, 0x9A8E, 0xF357, 0x9A94, 0xF358, 0x9A95, 0xF359, 0x9A99, + 0xF35A, 0x9AA6, 0xF35B, 0x9AA9, 0xF35C, 0x9AAA, 0xF35D, 0x9AAB, + 0xF35E, 0x9AAC, 0xF35F, 0x9AAD, 0xF360, 0x9AAE, 0xF361, 0x9AAF, + 0xF362, 0x9AB2, 0xF363, 0x9AB3, 0xF364, 0x9AB4, 0xF365, 0x9AB5, + 0xF366, 0x9AB9, 0xF367, 0x9ABB, 0xF368, 0x9ABD, 0xF369, 0x9ABE, + 0xF36A, 0x9ABF, 0xF36B, 0x9AC3, 0xF36C, 0x9AC4, 0xF36D, 0x9AC6, + 0xF36E, 0x9AC7, 0xF36F, 0x9AC8, 0xF370, 0x9AC9, 0xF371, 0x9ACA, + 0xF372, 0x9ACD, 0xF373, 0x9ACE, 0xF374, 0x9ACF, 0xF375, 0x9AD0, + 0xF376, 0x9AD2, 0xF377, 0x9AD4, 0xF378, 0x9AD5, 0xF379, 0x9AD6, + 0xF37A, 0x9AD7, 0xF37B, 0x9AD9, 0xF37C, 0x9ADA, 0xF37D, 0x9ADB, + 0xF37E, 0x9ADC, 0xF380, 0x9ADD, 0xF381, 0x9ADE, 0xF382, 0x9AE0, + 0xF383, 0x9AE2, 0xF384, 0x9AE3, 0xF385, 0x9AE4, 0xF386, 0x9AE5, + 0xF387, 0x9AE7, 0xF388, 0x9AE8, 0xF389, 0x9AE9, 0xF38A, 0x9AEA, + 0xF38B, 0x9AEC, 0xF38C, 0x9AEE, 0xF38D, 0x9AF0, 0xF38E, 0x9AF1, + 0xF38F, 0x9AF2, 0xF390, 0x9AF3, 0xF391, 0x9AF4, 0xF392, 0x9AF5, + 0xF393, 0x9AF6, 0xF394, 0x9AF7, 0xF395, 0x9AF8, 0xF396, 0x9AFA, + 0xF397, 0x9AFC, 0xF398, 0x9AFD, 0xF399, 0x9AFE, 0xF39A, 0x9AFF, + 0xF39B, 0x9B00, 0xF39C, 0x9B01, 0xF39D, 0x9B02, 0xF39E, 0x9B04, + 0xF39F, 0x9B05, 0xF3A0, 0x9B06, 0xF3A1, 0x87C6, 0xF3A2, 0x8788, + 0xF3A3, 0x8785, 0xF3A4, 0x87AD, 0xF3A5, 0x8797, 0xF3A6, 0x8783, + 0xF3A7, 0x87AB, 0xF3A8, 0x87E5, 0xF3A9, 0x87AC, 0xF3AA, 0x87B5, + 0xF3AB, 0x87B3, 0xF3AC, 0x87CB, 0xF3AD, 0x87D3, 0xF3AE, 0x87BD, + 0xF3AF, 0x87D1, 0xF3B0, 0x87C0, 0xF3B1, 0x87CA, 0xF3B2, 0x87DB, + 0xF3B3, 0x87EA, 0xF3B4, 0x87E0, 0xF3B5, 0x87EE, 0xF3B6, 0x8816, + 0xF3B7, 0x8813, 0xF3B8, 0x87FE, 0xF3B9, 0x880A, 0xF3BA, 0x881B, + 0xF3BB, 0x8821, 0xF3BC, 0x8839, 0xF3BD, 0x883C, 0xF3BE, 0x7F36, + 0xF3BF, 0x7F42, 0xF3C0, 0x7F44, 0xF3C1, 0x7F45, 0xF3C2, 0x8210, + 0xF3C3, 0x7AFA, 0xF3C4, 0x7AFD, 0xF3C5, 0x7B08, 0xF3C6, 0x7B03, + 0xF3C7, 0x7B04, 0xF3C8, 0x7B15, 0xF3C9, 0x7B0A, 0xF3CA, 0x7B2B, + 0xF3CB, 0x7B0F, 0xF3CC, 0x7B47, 0xF3CD, 0x7B38, 0xF3CE, 0x7B2A, + 0xF3CF, 0x7B19, 0xF3D0, 0x7B2E, 0xF3D1, 0x7B31, 0xF3D2, 0x7B20, + 0xF3D3, 0x7B25, 0xF3D4, 0x7B24, 0xF3D5, 0x7B33, 0xF3D6, 0x7B3E, + 0xF3D7, 0x7B1E, 0xF3D8, 0x7B58, 0xF3D9, 0x7B5A, 0xF3DA, 0x7B45, + 0xF3DB, 0x7B75, 0xF3DC, 0x7B4C, 0xF3DD, 0x7B5D, 0xF3DE, 0x7B60, + 0xF3DF, 0x7B6E, 0xF3E0, 0x7B7B, 0xF3E1, 0x7B62, 0xF3E2, 0x7B72, + 0xF3E3, 0x7B71, 0xF3E4, 0x7B90, 0xF3E5, 0x7BA6, 0xF3E6, 0x7BA7, + 0xF3E7, 0x7BB8, 0xF3E8, 0x7BAC, 0xF3E9, 0x7B9D, 0xF3EA, 0x7BA8, + 0xF3EB, 0x7B85, 0xF3EC, 0x7BAA, 0xF3ED, 0x7B9C, 0xF3EE, 0x7BA2, + 0xF3EF, 0x7BAB, 0xF3F0, 0x7BB4, 0xF3F1, 0x7BD1, 0xF3F2, 0x7BC1, + 0xF3F3, 0x7BCC, 0xF3F4, 0x7BDD, 0xF3F5, 0x7BDA, 0xF3F6, 0x7BE5, + 0xF3F7, 0x7BE6, 0xF3F8, 0x7BEA, 0xF3F9, 0x7C0C, 0xF3FA, 0x7BFE, + 0xF3FB, 0x7BFC, 0xF3FC, 0x7C0F, 0xF3FD, 0x7C16, 0xF3FE, 0x7C0B, + 0xF440, 0x9B07, 0xF441, 0x9B09, 0xF442, 0x9B0A, 0xF443, 0x9B0B, + 0xF444, 0x9B0C, 0xF445, 0x9B0D, 0xF446, 0x9B0E, 0xF447, 0x9B10, + 0xF448, 0x9B11, 0xF449, 0x9B12, 0xF44A, 0x9B14, 0xF44B, 0x9B15, + 0xF44C, 0x9B16, 0xF44D, 0x9B17, 0xF44E, 0x9B18, 0xF44F, 0x9B19, + 0xF450, 0x9B1A, 0xF451, 0x9B1B, 0xF452, 0x9B1C, 0xF453, 0x9B1D, + 0xF454, 0x9B1E, 0xF455, 0x9B20, 0xF456, 0x9B21, 0xF457, 0x9B22, + 0xF458, 0x9B24, 0xF459, 0x9B25, 0xF45A, 0x9B26, 0xF45B, 0x9B27, + 0xF45C, 0x9B28, 0xF45D, 0x9B29, 0xF45E, 0x9B2A, 0xF45F, 0x9B2B, + 0xF460, 0x9B2C, 0xF461, 0x9B2D, 0xF462, 0x9B2E, 0xF463, 0x9B30, + 0xF464, 0x9B31, 0xF465, 0x9B33, 0xF466, 0x9B34, 0xF467, 0x9B35, + 0xF468, 0x9B36, 0xF469, 0x9B37, 0xF46A, 0x9B38, 0xF46B, 0x9B39, + 0xF46C, 0x9B3A, 0xF46D, 0x9B3D, 0xF46E, 0x9B3E, 0xF46F, 0x9B3F, + 0xF470, 0x9B40, 0xF471, 0x9B46, 0xF472, 0x9B4A, 0xF473, 0x9B4B, + 0xF474, 0x9B4C, 0xF475, 0x9B4E, 0xF476, 0x9B50, 0xF477, 0x9B52, + 0xF478, 0x9B53, 0xF479, 0x9B55, 0xF47A, 0x9B56, 0xF47B, 0x9B57, + 0xF47C, 0x9B58, 0xF47D, 0x9B59, 0xF47E, 0x9B5A, 0xF480, 0x9B5B, + 0xF481, 0x9B5C, 0xF482, 0x9B5D, 0xF483, 0x9B5E, 0xF484, 0x9B5F, + 0xF485, 0x9B60, 0xF486, 0x9B61, 0xF487, 0x9B62, 0xF488, 0x9B63, + 0xF489, 0x9B64, 0xF48A, 0x9B65, 0xF48B, 0x9B66, 0xF48C, 0x9B67, + 0xF48D, 0x9B68, 0xF48E, 0x9B69, 0xF48F, 0x9B6A, 0xF490, 0x9B6B, + 0xF491, 0x9B6C, 0xF492, 0x9B6D, 0xF493, 0x9B6E, 0xF494, 0x9B6F, + 0xF495, 0x9B70, 0xF496, 0x9B71, 0xF497, 0x9B72, 0xF498, 0x9B73, + 0xF499, 0x9B74, 0xF49A, 0x9B75, 0xF49B, 0x9B76, 0xF49C, 0x9B77, + 0xF49D, 0x9B78, 0xF49E, 0x9B79, 0xF49F, 0x9B7A, 0xF4A0, 0x9B7B, + 0xF4A1, 0x7C1F, 0xF4A2, 0x7C2A, 0xF4A3, 0x7C26, 0xF4A4, 0x7C38, + 0xF4A5, 0x7C41, 0xF4A6, 0x7C40, 0xF4A7, 0x81FE, 0xF4A8, 0x8201, + 0xF4A9, 0x8202, 0xF4AA, 0x8204, 0xF4AB, 0x81EC, 0xF4AC, 0x8844, + 0xF4AD, 0x8221, 0xF4AE, 0x8222, 0xF4AF, 0x8223, 0xF4B0, 0x822D, + 0xF4B1, 0x822F, 0xF4B2, 0x8228, 0xF4B3, 0x822B, 0xF4B4, 0x8238, + 0xF4B5, 0x823B, 0xF4B6, 0x8233, 0xF4B7, 0x8234, 0xF4B8, 0x823E, + 0xF4B9, 0x8244, 0xF4BA, 0x8249, 0xF4BB, 0x824B, 0xF4BC, 0x824F, + 0xF4BD, 0x825A, 0xF4BE, 0x825F, 0xF4BF, 0x8268, 0xF4C0, 0x887E, + 0xF4C1, 0x8885, 0xF4C2, 0x8888, 0xF4C3, 0x88D8, 0xF4C4, 0x88DF, + 0xF4C5, 0x895E, 0xF4C6, 0x7F9D, 0xF4C7, 0x7F9F, 0xF4C8, 0x7FA7, + 0xF4C9, 0x7FAF, 0xF4CA, 0x7FB0, 0xF4CB, 0x7FB2, 0xF4CC, 0x7C7C, + 0xF4CD, 0x6549, 0xF4CE, 0x7C91, 0xF4CF, 0x7C9D, 0xF4D0, 0x7C9C, + 0xF4D1, 0x7C9E, 0xF4D2, 0x7CA2, 0xF4D3, 0x7CB2, 0xF4D4, 0x7CBC, + 0xF4D5, 0x7CBD, 0xF4D6, 0x7CC1, 0xF4D7, 0x7CC7, 0xF4D8, 0x7CCC, + 0xF4D9, 0x7CCD, 0xF4DA, 0x7CC8, 0xF4DB, 0x7CC5, 0xF4DC, 0x7CD7, + 0xF4DD, 0x7CE8, 0xF4DE, 0x826E, 0xF4DF, 0x66A8, 0xF4E0, 0x7FBF, + 0xF4E1, 0x7FCE, 0xF4E2, 0x7FD5, 0xF4E3, 0x7FE5, 0xF4E4, 0x7FE1, + 0xF4E5, 0x7FE6, 0xF4E6, 0x7FE9, 0xF4E7, 0x7FEE, 0xF4E8, 0x7FF3, + 0xF4E9, 0x7CF8, 0xF4EA, 0x7D77, 0xF4EB, 0x7DA6, 0xF4EC, 0x7DAE, + 0xF4ED, 0x7E47, 0xF4EE, 0x7E9B, 0xF4EF, 0x9EB8, 0xF4F0, 0x9EB4, + 0xF4F1, 0x8D73, 0xF4F2, 0x8D84, 0xF4F3, 0x8D94, 0xF4F4, 0x8D91, + 0xF4F5, 0x8DB1, 0xF4F6, 0x8D67, 0xF4F7, 0x8D6D, 0xF4F8, 0x8C47, + 0xF4F9, 0x8C49, 0xF4FA, 0x914A, 0xF4FB, 0x9150, 0xF4FC, 0x914E, + 0xF4FD, 0x914F, 0xF4FE, 0x9164, 0xF540, 0x9B7C, 0xF541, 0x9B7D, + 0xF542, 0x9B7E, 0xF543, 0x9B7F, 0xF544, 0x9B80, 0xF545, 0x9B81, + 0xF546, 0x9B82, 0xF547, 0x9B83, 0xF548, 0x9B84, 0xF549, 0x9B85, + 0xF54A, 0x9B86, 0xF54B, 0x9B87, 0xF54C, 0x9B88, 0xF54D, 0x9B89, + 0xF54E, 0x9B8A, 0xF54F, 0x9B8B, 0xF550, 0x9B8C, 0xF551, 0x9B8D, + 0xF552, 0x9B8E, 0xF553, 0x9B8F, 0xF554, 0x9B90, 0xF555, 0x9B91, + 0xF556, 0x9B92, 0xF557, 0x9B93, 0xF558, 0x9B94, 0xF559, 0x9B95, + 0xF55A, 0x9B96, 0xF55B, 0x9B97, 0xF55C, 0x9B98, 0xF55D, 0x9B99, + 0xF55E, 0x9B9A, 0xF55F, 0x9B9B, 0xF560, 0x9B9C, 0xF561, 0x9B9D, + 0xF562, 0x9B9E, 0xF563, 0x9B9F, 0xF564, 0x9BA0, 0xF565, 0x9BA1, + 0xF566, 0x9BA2, 0xF567, 0x9BA3, 0xF568, 0x9BA4, 0xF569, 0x9BA5, + 0xF56A, 0x9BA6, 0xF56B, 0x9BA7, 0xF56C, 0x9BA8, 0xF56D, 0x9BA9, + 0xF56E, 0x9BAA, 0xF56F, 0x9BAB, 0xF570, 0x9BAC, 0xF571, 0x9BAD, + 0xF572, 0x9BAE, 0xF573, 0x9BAF, 0xF574, 0x9BB0, 0xF575, 0x9BB1, + 0xF576, 0x9BB2, 0xF577, 0x9BB3, 0xF578, 0x9BB4, 0xF579, 0x9BB5, + 0xF57A, 0x9BB6, 0xF57B, 0x9BB7, 0xF57C, 0x9BB8, 0xF57D, 0x9BB9, + 0xF57E, 0x9BBA, 0xF580, 0x9BBB, 0xF581, 0x9BBC, 0xF582, 0x9BBD, + 0xF583, 0x9BBE, 0xF584, 0x9BBF, 0xF585, 0x9BC0, 0xF586, 0x9BC1, + 0xF587, 0x9BC2, 0xF588, 0x9BC3, 0xF589, 0x9BC4, 0xF58A, 0x9BC5, + 0xF58B, 0x9BC6, 0xF58C, 0x9BC7, 0xF58D, 0x9BC8, 0xF58E, 0x9BC9, + 0xF58F, 0x9BCA, 0xF590, 0x9BCB, 0xF591, 0x9BCC, 0xF592, 0x9BCD, + 0xF593, 0x9BCE, 0xF594, 0x9BCF, 0xF595, 0x9BD0, 0xF596, 0x9BD1, + 0xF597, 0x9BD2, 0xF598, 0x9BD3, 0xF599, 0x9BD4, 0xF59A, 0x9BD5, + 0xF59B, 0x9BD6, 0xF59C, 0x9BD7, 0xF59D, 0x9BD8, 0xF59E, 0x9BD9, + 0xF59F, 0x9BDA, 0xF5A0, 0x9BDB, 0xF5A1, 0x9162, 0xF5A2, 0x9161, + 0xF5A3, 0x9170, 0xF5A4, 0x9169, 0xF5A5, 0x916F, 0xF5A6, 0x917D, + 0xF5A7, 0x917E, 0xF5A8, 0x9172, 0xF5A9, 0x9174, 0xF5AA, 0x9179, + 0xF5AB, 0x918C, 0xF5AC, 0x9185, 0xF5AD, 0x9190, 0xF5AE, 0x918D, + 0xF5AF, 0x9191, 0xF5B0, 0x91A2, 0xF5B1, 0x91A3, 0xF5B2, 0x91AA, + 0xF5B3, 0x91AD, 0xF5B4, 0x91AE, 0xF5B5, 0x91AF, 0xF5B6, 0x91B5, + 0xF5B7, 0x91B4, 0xF5B8, 0x91BA, 0xF5B9, 0x8C55, 0xF5BA, 0x9E7E, + 0xF5BB, 0x8DB8, 0xF5BC, 0x8DEB, 0xF5BD, 0x8E05, 0xF5BE, 0x8E59, + 0xF5BF, 0x8E69, 0xF5C0, 0x8DB5, 0xF5C1, 0x8DBF, 0xF5C2, 0x8DBC, + 0xF5C3, 0x8DBA, 0xF5C4, 0x8DC4, 0xF5C5, 0x8DD6, 0xF5C6, 0x8DD7, + 0xF5C7, 0x8DDA, 0xF5C8, 0x8DDE, 0xF5C9, 0x8DCE, 0xF5CA, 0x8DCF, + 0xF5CB, 0x8DDB, 0xF5CC, 0x8DC6, 0xF5CD, 0x8DEC, 0xF5CE, 0x8DF7, + 0xF5CF, 0x8DF8, 0xF5D0, 0x8DE3, 0xF5D1, 0x8DF9, 0xF5D2, 0x8DFB, + 0xF5D3, 0x8DE4, 0xF5D4, 0x8E09, 0xF5D5, 0x8DFD, 0xF5D6, 0x8E14, + 0xF5D7, 0x8E1D, 0xF5D8, 0x8E1F, 0xF5D9, 0x8E2C, 0xF5DA, 0x8E2E, + 0xF5DB, 0x8E23, 0xF5DC, 0x8E2F, 0xF5DD, 0x8E3A, 0xF5DE, 0x8E40, + 0xF5DF, 0x8E39, 0xF5E0, 0x8E35, 0xF5E1, 0x8E3D, 0xF5E2, 0x8E31, + 0xF5E3, 0x8E49, 0xF5E4, 0x8E41, 0xF5E5, 0x8E42, 0xF5E6, 0x8E51, + 0xF5E7, 0x8E52, 0xF5E8, 0x8E4A, 0xF5E9, 0x8E70, 0xF5EA, 0x8E76, + 0xF5EB, 0x8E7C, 0xF5EC, 0x8E6F, 0xF5ED, 0x8E74, 0xF5EE, 0x8E85, + 0xF5EF, 0x8E8F, 0xF5F0, 0x8E94, 0xF5F1, 0x8E90, 0xF5F2, 0x8E9C, + 0xF5F3, 0x8E9E, 0xF5F4, 0x8C78, 0xF5F5, 0x8C82, 0xF5F6, 0x8C8A, + 0xF5F7, 0x8C85, 0xF5F8, 0x8C98, 0xF5F9, 0x8C94, 0xF5FA, 0x659B, + 0xF5FB, 0x89D6, 0xF5FC, 0x89DE, 0xF5FD, 0x89DA, 0xF5FE, 0x89DC, + 0xF640, 0x9BDC, 0xF641, 0x9BDD, 0xF642, 0x9BDE, 0xF643, 0x9BDF, + 0xF644, 0x9BE0, 0xF645, 0x9BE1, 0xF646, 0x9BE2, 0xF647, 0x9BE3, + 0xF648, 0x9BE4, 0xF649, 0x9BE5, 0xF64A, 0x9BE6, 0xF64B, 0x9BE7, + 0xF64C, 0x9BE8, 0xF64D, 0x9BE9, 0xF64E, 0x9BEA, 0xF64F, 0x9BEB, + 0xF650, 0x9BEC, 0xF651, 0x9BED, 0xF652, 0x9BEE, 0xF653, 0x9BEF, + 0xF654, 0x9BF0, 0xF655, 0x9BF1, 0xF656, 0x9BF2, 0xF657, 0x9BF3, + 0xF658, 0x9BF4, 0xF659, 0x9BF5, 0xF65A, 0x9BF6, 0xF65B, 0x9BF7, + 0xF65C, 0x9BF8, 0xF65D, 0x9BF9, 0xF65E, 0x9BFA, 0xF65F, 0x9BFB, + 0xF660, 0x9BFC, 0xF661, 0x9BFD, 0xF662, 0x9BFE, 0xF663, 0x9BFF, + 0xF664, 0x9C00, 0xF665, 0x9C01, 0xF666, 0x9C02, 0xF667, 0x9C03, + 0xF668, 0x9C04, 0xF669, 0x9C05, 0xF66A, 0x9C06, 0xF66B, 0x9C07, + 0xF66C, 0x9C08, 0xF66D, 0x9C09, 0xF66E, 0x9C0A, 0xF66F, 0x9C0B, + 0xF670, 0x9C0C, 0xF671, 0x9C0D, 0xF672, 0x9C0E, 0xF673, 0x9C0F, + 0xF674, 0x9C10, 0xF675, 0x9C11, 0xF676, 0x9C12, 0xF677, 0x9C13, + 0xF678, 0x9C14, 0xF679, 0x9C15, 0xF67A, 0x9C16, 0xF67B, 0x9C17, + 0xF67C, 0x9C18, 0xF67D, 0x9C19, 0xF67E, 0x9C1A, 0xF680, 0x9C1B, + 0xF681, 0x9C1C, 0xF682, 0x9C1D, 0xF683, 0x9C1E, 0xF684, 0x9C1F, + 0xF685, 0x9C20, 0xF686, 0x9C21, 0xF687, 0x9C22, 0xF688, 0x9C23, + 0xF689, 0x9C24, 0xF68A, 0x9C25, 0xF68B, 0x9C26, 0xF68C, 0x9C27, + 0xF68D, 0x9C28, 0xF68E, 0x9C29, 0xF68F, 0x9C2A, 0xF690, 0x9C2B, + 0xF691, 0x9C2C, 0xF692, 0x9C2D, 0xF693, 0x9C2E, 0xF694, 0x9C2F, + 0xF695, 0x9C30, 0xF696, 0x9C31, 0xF697, 0x9C32, 0xF698, 0x9C33, + 0xF699, 0x9C34, 0xF69A, 0x9C35, 0xF69B, 0x9C36, 0xF69C, 0x9C37, + 0xF69D, 0x9C38, 0xF69E, 0x9C39, 0xF69F, 0x9C3A, 0xF6A0, 0x9C3B, + 0xF6A1, 0x89E5, 0xF6A2, 0x89EB, 0xF6A3, 0x89EF, 0xF6A4, 0x8A3E, + 0xF6A5, 0x8B26, 0xF6A6, 0x9753, 0xF6A7, 0x96E9, 0xF6A8, 0x96F3, + 0xF6A9, 0x96EF, 0xF6AA, 0x9706, 0xF6AB, 0x9701, 0xF6AC, 0x9708, + 0xF6AD, 0x970F, 0xF6AE, 0x970E, 0xF6AF, 0x972A, 0xF6B0, 0x972D, + 0xF6B1, 0x9730, 0xF6B2, 0x973E, 0xF6B3, 0x9F80, 0xF6B4, 0x9F83, + 0xF6B5, 0x9F85, 0xF6B6, 0x9F86, 0xF6B7, 0x9F87, 0xF6B8, 0x9F88, + 0xF6B9, 0x9F89, 0xF6BA, 0x9F8A, 0xF6BB, 0x9F8C, 0xF6BC, 0x9EFE, + 0xF6BD, 0x9F0B, 0xF6BE, 0x9F0D, 0xF6BF, 0x96B9, 0xF6C0, 0x96BC, + 0xF6C1, 0x96BD, 0xF6C2, 0x96CE, 0xF6C3, 0x96D2, 0xF6C4, 0x77BF, + 0xF6C5, 0x96E0, 0xF6C6, 0x928E, 0xF6C7, 0x92AE, 0xF6C8, 0x92C8, + 0xF6C9, 0x933E, 0xF6CA, 0x936A, 0xF6CB, 0x93CA, 0xF6CC, 0x938F, + 0xF6CD, 0x943E, 0xF6CE, 0x946B, 0xF6CF, 0x9C7F, 0xF6D0, 0x9C82, + 0xF6D1, 0x9C85, 0xF6D2, 0x9C86, 0xF6D3, 0x9C87, 0xF6D4, 0x9C88, + 0xF6D5, 0x7A23, 0xF6D6, 0x9C8B, 0xF6D7, 0x9C8E, 0xF6D8, 0x9C90, + 0xF6D9, 0x9C91, 0xF6DA, 0x9C92, 0xF6DB, 0x9C94, 0xF6DC, 0x9C95, + 0xF6DD, 0x9C9A, 0xF6DE, 0x9C9B, 0xF6DF, 0x9C9E, 0xF6E0, 0x9C9F, + 0xF6E1, 0x9CA0, 0xF6E2, 0x9CA1, 0xF6E3, 0x9CA2, 0xF6E4, 0x9CA3, + 0xF6E5, 0x9CA5, 0xF6E6, 0x9CA6, 0xF6E7, 0x9CA7, 0xF6E8, 0x9CA8, + 0xF6E9, 0x9CA9, 0xF6EA, 0x9CAB, 0xF6EB, 0x9CAD, 0xF6EC, 0x9CAE, + 0xF6ED, 0x9CB0, 0xF6EE, 0x9CB1, 0xF6EF, 0x9CB2, 0xF6F0, 0x9CB3, + 0xF6F1, 0x9CB4, 0xF6F2, 0x9CB5, 0xF6F3, 0x9CB6, 0xF6F4, 0x9CB7, + 0xF6F5, 0x9CBA, 0xF6F6, 0x9CBB, 0xF6F7, 0x9CBC, 0xF6F8, 0x9CBD, + 0xF6F9, 0x9CC4, 0xF6FA, 0x9CC5, 0xF6FB, 0x9CC6, 0xF6FC, 0x9CC7, + 0xF6FD, 0x9CCA, 0xF6FE, 0x9CCB, 0xF740, 0x9C3C, 0xF741, 0x9C3D, + 0xF742, 0x9C3E, 0xF743, 0x9C3F, 0xF744, 0x9C40, 0xF745, 0x9C41, + 0xF746, 0x9C42, 0xF747, 0x9C43, 0xF748, 0x9C44, 0xF749, 0x9C45, + 0xF74A, 0x9C46, 0xF74B, 0x9C47, 0xF74C, 0x9C48, 0xF74D, 0x9C49, + 0xF74E, 0x9C4A, 0xF74F, 0x9C4B, 0xF750, 0x9C4C, 0xF751, 0x9C4D, + 0xF752, 0x9C4E, 0xF753, 0x9C4F, 0xF754, 0x9C50, 0xF755, 0x9C51, + 0xF756, 0x9C52, 0xF757, 0x9C53, 0xF758, 0x9C54, 0xF759, 0x9C55, + 0xF75A, 0x9C56, 0xF75B, 0x9C57, 0xF75C, 0x9C58, 0xF75D, 0x9C59, + 0xF75E, 0x9C5A, 0xF75F, 0x9C5B, 0xF760, 0x9C5C, 0xF761, 0x9C5D, + 0xF762, 0x9C5E, 0xF763, 0x9C5F, 0xF764, 0x9C60, 0xF765, 0x9C61, + 0xF766, 0x9C62, 0xF767, 0x9C63, 0xF768, 0x9C64, 0xF769, 0x9C65, + 0xF76A, 0x9C66, 0xF76B, 0x9C67, 0xF76C, 0x9C68, 0xF76D, 0x9C69, + 0xF76E, 0x9C6A, 0xF76F, 0x9C6B, 0xF770, 0x9C6C, 0xF771, 0x9C6D, + 0xF772, 0x9C6E, 0xF773, 0x9C6F, 0xF774, 0x9C70, 0xF775, 0x9C71, + 0xF776, 0x9C72, 0xF777, 0x9C73, 0xF778, 0x9C74, 0xF779, 0x9C75, + 0xF77A, 0x9C76, 0xF77B, 0x9C77, 0xF77C, 0x9C78, 0xF77D, 0x9C79, + 0xF77E, 0x9C7A, 0xF780, 0x9C7B, 0xF781, 0x9C7D, 0xF782, 0x9C7E, + 0xF783, 0x9C80, 0xF784, 0x9C83, 0xF785, 0x9C84, 0xF786, 0x9C89, + 0xF787, 0x9C8A, 0xF788, 0x9C8C, 0xF789, 0x9C8F, 0xF78A, 0x9C93, + 0xF78B, 0x9C96, 0xF78C, 0x9C97, 0xF78D, 0x9C98, 0xF78E, 0x9C99, + 0xF78F, 0x9C9D, 0xF790, 0x9CAA, 0xF791, 0x9CAC, 0xF792, 0x9CAF, + 0xF793, 0x9CB9, 0xF794, 0x9CBE, 0xF795, 0x9CBF, 0xF796, 0x9CC0, + 0xF797, 0x9CC1, 0xF798, 0x9CC2, 0xF799, 0x9CC8, 0xF79A, 0x9CC9, + 0xF79B, 0x9CD1, 0xF79C, 0x9CD2, 0xF79D, 0x9CDA, 0xF79E, 0x9CDB, + 0xF79F, 0x9CE0, 0xF7A0, 0x9CE1, 0xF7A1, 0x9CCC, 0xF7A2, 0x9CCD, + 0xF7A3, 0x9CCE, 0xF7A4, 0x9CCF, 0xF7A5, 0x9CD0, 0xF7A6, 0x9CD3, + 0xF7A7, 0x9CD4, 0xF7A8, 0x9CD5, 0xF7A9, 0x9CD7, 0xF7AA, 0x9CD8, + 0xF7AB, 0x9CD9, 0xF7AC, 0x9CDC, 0xF7AD, 0x9CDD, 0xF7AE, 0x9CDF, + 0xF7AF, 0x9CE2, 0xF7B0, 0x977C, 0xF7B1, 0x9785, 0xF7B2, 0x9791, + 0xF7B3, 0x9792, 0xF7B4, 0x9794, 0xF7B5, 0x97AF, 0xF7B6, 0x97AB, + 0xF7B7, 0x97A3, 0xF7B8, 0x97B2, 0xF7B9, 0x97B4, 0xF7BA, 0x9AB1, + 0xF7BB, 0x9AB0, 0xF7BC, 0x9AB7, 0xF7BD, 0x9E58, 0xF7BE, 0x9AB6, + 0xF7BF, 0x9ABA, 0xF7C0, 0x9ABC, 0xF7C1, 0x9AC1, 0xF7C2, 0x9AC0, + 0xF7C3, 0x9AC5, 0xF7C4, 0x9AC2, 0xF7C5, 0x9ACB, 0xF7C6, 0x9ACC, + 0xF7C7, 0x9AD1, 0xF7C8, 0x9B45, 0xF7C9, 0x9B43, 0xF7CA, 0x9B47, + 0xF7CB, 0x9B49, 0xF7CC, 0x9B48, 0xF7CD, 0x9B4D, 0xF7CE, 0x9B51, + 0xF7CF, 0x98E8, 0xF7D0, 0x990D, 0xF7D1, 0x992E, 0xF7D2, 0x9955, + 0xF7D3, 0x9954, 0xF7D4, 0x9ADF, 0xF7D5, 0x9AE1, 0xF7D6, 0x9AE6, + 0xF7D7, 0x9AEF, 0xF7D8, 0x9AEB, 0xF7D9, 0x9AFB, 0xF7DA, 0x9AED, + 0xF7DB, 0x9AF9, 0xF7DC, 0x9B08, 0xF7DD, 0x9B0F, 0xF7DE, 0x9B13, + 0xF7DF, 0x9B1F, 0xF7E0, 0x9B23, 0xF7E1, 0x9EBD, 0xF7E2, 0x9EBE, + 0xF7E3, 0x7E3B, 0xF7E4, 0x9E82, 0xF7E5, 0x9E87, 0xF7E6, 0x9E88, + 0xF7E7, 0x9E8B, 0xF7E8, 0x9E92, 0xF7E9, 0x93D6, 0xF7EA, 0x9E9D, + 0xF7EB, 0x9E9F, 0xF7EC, 0x9EDB, 0xF7ED, 0x9EDC, 0xF7EE, 0x9EDD, + 0xF7EF, 0x9EE0, 0xF7F0, 0x9EDF, 0xF7F1, 0x9EE2, 0xF7F2, 0x9EE9, + 0xF7F3, 0x9EE7, 0xF7F4, 0x9EE5, 0xF7F5, 0x9EEA, 0xF7F6, 0x9EEF, + 0xF7F7, 0x9F22, 0xF7F8, 0x9F2C, 0xF7F9, 0x9F2F, 0xF7FA, 0x9F39, + 0xF7FB, 0x9F37, 0xF7FC, 0x9F3D, 0xF7FD, 0x9F3E, 0xF7FE, 0x9F44, + 0xF840, 0x9CE3, 0xF841, 0x9CE4, 0xF842, 0x9CE5, 0xF843, 0x9CE6, + 0xF844, 0x9CE7, 0xF845, 0x9CE8, 0xF846, 0x9CE9, 0xF847, 0x9CEA, + 0xF848, 0x9CEB, 0xF849, 0x9CEC, 0xF84A, 0x9CED, 0xF84B, 0x9CEE, + 0xF84C, 0x9CEF, 0xF84D, 0x9CF0, 0xF84E, 0x9CF1, 0xF84F, 0x9CF2, + 0xF850, 0x9CF3, 0xF851, 0x9CF4, 0xF852, 0x9CF5, 0xF853, 0x9CF6, + 0xF854, 0x9CF7, 0xF855, 0x9CF8, 0xF856, 0x9CF9, 0xF857, 0x9CFA, + 0xF858, 0x9CFB, 0xF859, 0x9CFC, 0xF85A, 0x9CFD, 0xF85B, 0x9CFE, + 0xF85C, 0x9CFF, 0xF85D, 0x9D00, 0xF85E, 0x9D01, 0xF85F, 0x9D02, + 0xF860, 0x9D03, 0xF861, 0x9D04, 0xF862, 0x9D05, 0xF863, 0x9D06, + 0xF864, 0x9D07, 0xF865, 0x9D08, 0xF866, 0x9D09, 0xF867, 0x9D0A, + 0xF868, 0x9D0B, 0xF869, 0x9D0C, 0xF86A, 0x9D0D, 0xF86B, 0x9D0E, + 0xF86C, 0x9D0F, 0xF86D, 0x9D10, 0xF86E, 0x9D11, 0xF86F, 0x9D12, + 0xF870, 0x9D13, 0xF871, 0x9D14, 0xF872, 0x9D15, 0xF873, 0x9D16, + 0xF874, 0x9D17, 0xF875, 0x9D18, 0xF876, 0x9D19, 0xF877, 0x9D1A, + 0xF878, 0x9D1B, 0xF879, 0x9D1C, 0xF87A, 0x9D1D, 0xF87B, 0x9D1E, + 0xF87C, 0x9D1F, 0xF87D, 0x9D20, 0xF87E, 0x9D21, 0xF880, 0x9D22, + 0xF881, 0x9D23, 0xF882, 0x9D24, 0xF883, 0x9D25, 0xF884, 0x9D26, + 0xF885, 0x9D27, 0xF886, 0x9D28, 0xF887, 0x9D29, 0xF888, 0x9D2A, + 0xF889, 0x9D2B, 0xF88A, 0x9D2C, 0xF88B, 0x9D2D, 0xF88C, 0x9D2E, + 0xF88D, 0x9D2F, 0xF88E, 0x9D30, 0xF88F, 0x9D31, 0xF890, 0x9D32, + 0xF891, 0x9D33, 0xF892, 0x9D34, 0xF893, 0x9D35, 0xF894, 0x9D36, + 0xF895, 0x9D37, 0xF896, 0x9D38, 0xF897, 0x9D39, 0xF898, 0x9D3A, + 0xF899, 0x9D3B, 0xF89A, 0x9D3C, 0xF89B, 0x9D3D, 0xF89C, 0x9D3E, + 0xF89D, 0x9D3F, 0xF89E, 0x9D40, 0xF89F, 0x9D41, 0xF8A0, 0x9D42, + 0xF940, 0x9D43, 0xF941, 0x9D44, 0xF942, 0x9D45, 0xF943, 0x9D46, + 0xF944, 0x9D47, 0xF945, 0x9D48, 0xF946, 0x9D49, 0xF947, 0x9D4A, + 0xF948, 0x9D4B, 0xF949, 0x9D4C, 0xF94A, 0x9D4D, 0xF94B, 0x9D4E, + 0xF94C, 0x9D4F, 0xF94D, 0x9D50, 0xF94E, 0x9D51, 0xF94F, 0x9D52, + 0xF950, 0x9D53, 0xF951, 0x9D54, 0xF952, 0x9D55, 0xF953, 0x9D56, + 0xF954, 0x9D57, 0xF955, 0x9D58, 0xF956, 0x9D59, 0xF957, 0x9D5A, + 0xF958, 0x9D5B, 0xF959, 0x9D5C, 0xF95A, 0x9D5D, 0xF95B, 0x9D5E, + 0xF95C, 0x9D5F, 0xF95D, 0x9D60, 0xF95E, 0x9D61, 0xF95F, 0x9D62, + 0xF960, 0x9D63, 0xF961, 0x9D64, 0xF962, 0x9D65, 0xF963, 0x9D66, + 0xF964, 0x9D67, 0xF965, 0x9D68, 0xF966, 0x9D69, 0xF967, 0x9D6A, + 0xF968, 0x9D6B, 0xF969, 0x9D6C, 0xF96A, 0x9D6D, 0xF96B, 0x9D6E, + 0xF96C, 0x9D6F, 0xF96D, 0x9D70, 0xF96E, 0x9D71, 0xF96F, 0x9D72, + 0xF970, 0x9D73, 0xF971, 0x9D74, 0xF972, 0x9D75, 0xF973, 0x9D76, + 0xF974, 0x9D77, 0xF975, 0x9D78, 0xF976, 0x9D79, 0xF977, 0x9D7A, + 0xF978, 0x9D7B, 0xF979, 0x9D7C, 0xF97A, 0x9D7D, 0xF97B, 0x9D7E, + 0xF97C, 0x9D7F, 0xF97D, 0x9D80, 0xF97E, 0x9D81, 0xF980, 0x9D82, + 0xF981, 0x9D83, 0xF982, 0x9D84, 0xF983, 0x9D85, 0xF984, 0x9D86, + 0xF985, 0x9D87, 0xF986, 0x9D88, 0xF987, 0x9D89, 0xF988, 0x9D8A, + 0xF989, 0x9D8B, 0xF98A, 0x9D8C, 0xF98B, 0x9D8D, 0xF98C, 0x9D8E, + 0xF98D, 0x9D8F, 0xF98E, 0x9D90, 0xF98F, 0x9D91, 0xF990, 0x9D92, + 0xF991, 0x9D93, 0xF992, 0x9D94, 0xF993, 0x9D95, 0xF994, 0x9D96, + 0xF995, 0x9D97, 0xF996, 0x9D98, 0xF997, 0x9D99, 0xF998, 0x9D9A, + 0xF999, 0x9D9B, 0xF99A, 0x9D9C, 0xF99B, 0x9D9D, 0xF99C, 0x9D9E, + 0xF99D, 0x9D9F, 0xF99E, 0x9DA0, 0xF99F, 0x9DA1, 0xF9A0, 0x9DA2, + 0xFA40, 0x9DA3, 0xFA41, 0x9DA4, 0xFA42, 0x9DA5, 0xFA43, 0x9DA6, + 0xFA44, 0x9DA7, 0xFA45, 0x9DA8, 0xFA46, 0x9DA9, 0xFA47, 0x9DAA, + 0xFA48, 0x9DAB, 0xFA49, 0x9DAC, 0xFA4A, 0x9DAD, 0xFA4B, 0x9DAE, + 0xFA4C, 0x9DAF, 0xFA4D, 0x9DB0, 0xFA4E, 0x9DB1, 0xFA4F, 0x9DB2, + 0xFA50, 0x9DB3, 0xFA51, 0x9DB4, 0xFA52, 0x9DB5, 0xFA53, 0x9DB6, + 0xFA54, 0x9DB7, 0xFA55, 0x9DB8, 0xFA56, 0x9DB9, 0xFA57, 0x9DBA, + 0xFA58, 0x9DBB, 0xFA59, 0x9DBC, 0xFA5A, 0x9DBD, 0xFA5B, 0x9DBE, + 0xFA5C, 0x9DBF, 0xFA5D, 0x9DC0, 0xFA5E, 0x9DC1, 0xFA5F, 0x9DC2, + 0xFA60, 0x9DC3, 0xFA61, 0x9DC4, 0xFA62, 0x9DC5, 0xFA63, 0x9DC6, + 0xFA64, 0x9DC7, 0xFA65, 0x9DC8, 0xFA66, 0x9DC9, 0xFA67, 0x9DCA, + 0xFA68, 0x9DCB, 0xFA69, 0x9DCC, 0xFA6A, 0x9DCD, 0xFA6B, 0x9DCE, + 0xFA6C, 0x9DCF, 0xFA6D, 0x9DD0, 0xFA6E, 0x9DD1, 0xFA6F, 0x9DD2, + 0xFA70, 0x9DD3, 0xFA71, 0x9DD4, 0xFA72, 0x9DD5, 0xFA73, 0x9DD6, + 0xFA74, 0x9DD7, 0xFA75, 0x9DD8, 0xFA76, 0x9DD9, 0xFA77, 0x9DDA, + 0xFA78, 0x9DDB, 0xFA79, 0x9DDC, 0xFA7A, 0x9DDD, 0xFA7B, 0x9DDE, + 0xFA7C, 0x9DDF, 0xFA7D, 0x9DE0, 0xFA7E, 0x9DE1, 0xFA80, 0x9DE2, + 0xFA81, 0x9DE3, 0xFA82, 0x9DE4, 0xFA83, 0x9DE5, 0xFA84, 0x9DE6, + 0xFA85, 0x9DE7, 0xFA86, 0x9DE8, 0xFA87, 0x9DE9, 0xFA88, 0x9DEA, + 0xFA89, 0x9DEB, 0xFA8A, 0x9DEC, 0xFA8B, 0x9DED, 0xFA8C, 0x9DEE, + 0xFA8D, 0x9DEF, 0xFA8E, 0x9DF0, 0xFA8F, 0x9DF1, 0xFA90, 0x9DF2, + 0xFA91, 0x9DF3, 0xFA92, 0x9DF4, 0xFA93, 0x9DF5, 0xFA94, 0x9DF6, + 0xFA95, 0x9DF7, 0xFA96, 0x9DF8, 0xFA97, 0x9DF9, 0xFA98, 0x9DFA, + 0xFA99, 0x9DFB, 0xFA9A, 0x9DFC, 0xFA9B, 0x9DFD, 0xFA9C, 0x9DFE, + 0xFA9D, 0x9DFF, 0xFA9E, 0x9E00, 0xFA9F, 0x9E01, 0xFAA0, 0x9E02, + 0xFB40, 0x9E03, 0xFB41, 0x9E04, 0xFB42, 0x9E05, 0xFB43, 0x9E06, + 0xFB44, 0x9E07, 0xFB45, 0x9E08, 0xFB46, 0x9E09, 0xFB47, 0x9E0A, + 0xFB48, 0x9E0B, 0xFB49, 0x9E0C, 0xFB4A, 0x9E0D, 0xFB4B, 0x9E0E, + 0xFB4C, 0x9E0F, 0xFB4D, 0x9E10, 0xFB4E, 0x9E11, 0xFB4F, 0x9E12, + 0xFB50, 0x9E13, 0xFB51, 0x9E14, 0xFB52, 0x9E15, 0xFB53, 0x9E16, + 0xFB54, 0x9E17, 0xFB55, 0x9E18, 0xFB56, 0x9E19, 0xFB57, 0x9E1A, + 0xFB58, 0x9E1B, 0xFB59, 0x9E1C, 0xFB5A, 0x9E1D, 0xFB5B, 0x9E1E, + 0xFB5C, 0x9E24, 0xFB5D, 0x9E27, 0xFB5E, 0x9E2E, 0xFB5F, 0x9E30, + 0xFB60, 0x9E34, 0xFB61, 0x9E3B, 0xFB62, 0x9E3C, 0xFB63, 0x9E40, + 0xFB64, 0x9E4D, 0xFB65, 0x9E50, 0xFB66, 0x9E52, 0xFB67, 0x9E53, + 0xFB68, 0x9E54, 0xFB69, 0x9E56, 0xFB6A, 0x9E59, 0xFB6B, 0x9E5D, + 0xFB6C, 0x9E5F, 0xFB6D, 0x9E60, 0xFB6E, 0x9E61, 0xFB6F, 0x9E62, + 0xFB70, 0x9E65, 0xFB71, 0x9E6E, 0xFB72, 0x9E6F, 0xFB73, 0x9E72, + 0xFB74, 0x9E74, 0xFB75, 0x9E75, 0xFB76, 0x9E76, 0xFB77, 0x9E77, + 0xFB78, 0x9E78, 0xFB79, 0x9E79, 0xFB7A, 0x9E7A, 0xFB7B, 0x9E7B, + 0xFB7C, 0x9E7C, 0xFB7D, 0x9E7D, 0xFB7E, 0x9E80, 0xFB80, 0x9E81, + 0xFB81, 0x9E83, 0xFB82, 0x9E84, 0xFB83, 0x9E85, 0xFB84, 0x9E86, + 0xFB85, 0x9E89, 0xFB86, 0x9E8A, 0xFB87, 0x9E8C, 0xFB88, 0x9E8D, + 0xFB89, 0x9E8E, 0xFB8A, 0x9E8F, 0xFB8B, 0x9E90, 0xFB8C, 0x9E91, + 0xFB8D, 0x9E94, 0xFB8E, 0x9E95, 0xFB8F, 0x9E96, 0xFB90, 0x9E97, + 0xFB91, 0x9E98, 0xFB92, 0x9E99, 0xFB93, 0x9E9A, 0xFB94, 0x9E9B, + 0xFB95, 0x9E9C, 0xFB96, 0x9E9E, 0xFB97, 0x9EA0, 0xFB98, 0x9EA1, + 0xFB99, 0x9EA2, 0xFB9A, 0x9EA3, 0xFB9B, 0x9EA4, 0xFB9C, 0x9EA5, + 0xFB9D, 0x9EA7, 0xFB9E, 0x9EA8, 0xFB9F, 0x9EA9, 0xFBA0, 0x9EAA, + 0xFC40, 0x9EAB, 0xFC41, 0x9EAC, 0xFC42, 0x9EAD, 0xFC43, 0x9EAE, + 0xFC44, 0x9EAF, 0xFC45, 0x9EB0, 0xFC46, 0x9EB1, 0xFC47, 0x9EB2, + 0xFC48, 0x9EB3, 0xFC49, 0x9EB5, 0xFC4A, 0x9EB6, 0xFC4B, 0x9EB7, + 0xFC4C, 0x9EB9, 0xFC4D, 0x9EBA, 0xFC4E, 0x9EBC, 0xFC4F, 0x9EBF, + 0xFC50, 0x9EC0, 0xFC51, 0x9EC1, 0xFC52, 0x9EC2, 0xFC53, 0x9EC3, + 0xFC54, 0x9EC5, 0xFC55, 0x9EC6, 0xFC56, 0x9EC7, 0xFC57, 0x9EC8, + 0xFC58, 0x9ECA, 0xFC59, 0x9ECB, 0xFC5A, 0x9ECC, 0xFC5B, 0x9ED0, + 0xFC5C, 0x9ED2, 0xFC5D, 0x9ED3, 0xFC5E, 0x9ED5, 0xFC5F, 0x9ED6, + 0xFC60, 0x9ED7, 0xFC61, 0x9ED9, 0xFC62, 0x9EDA, 0xFC63, 0x9EDE, + 0xFC64, 0x9EE1, 0xFC65, 0x9EE3, 0xFC66, 0x9EE4, 0xFC67, 0x9EE6, + 0xFC68, 0x9EE8, 0xFC69, 0x9EEB, 0xFC6A, 0x9EEC, 0xFC6B, 0x9EED, + 0xFC6C, 0x9EEE, 0xFC6D, 0x9EF0, 0xFC6E, 0x9EF1, 0xFC6F, 0x9EF2, + 0xFC70, 0x9EF3, 0xFC71, 0x9EF4, 0xFC72, 0x9EF5, 0xFC73, 0x9EF6, + 0xFC74, 0x9EF7, 0xFC75, 0x9EF8, 0xFC76, 0x9EFA, 0xFC77, 0x9EFD, + 0xFC78, 0x9EFF, 0xFC79, 0x9F00, 0xFC7A, 0x9F01, 0xFC7B, 0x9F02, + 0xFC7C, 0x9F03, 0xFC7D, 0x9F04, 0xFC7E, 0x9F05, 0xFC80, 0x9F06, + 0xFC81, 0x9F07, 0xFC82, 0x9F08, 0xFC83, 0x9F09, 0xFC84, 0x9F0A, + 0xFC85, 0x9F0C, 0xFC86, 0x9F0F, 0xFC87, 0x9F11, 0xFC88, 0x9F12, + 0xFC89, 0x9F14, 0xFC8A, 0x9F15, 0xFC8B, 0x9F16, 0xFC8C, 0x9F18, + 0xFC8D, 0x9F1A, 0xFC8E, 0x9F1B, 0xFC8F, 0x9F1C, 0xFC90, 0x9F1D, + 0xFC91, 0x9F1E, 0xFC92, 0x9F1F, 0xFC93, 0x9F21, 0xFC94, 0x9F23, + 0xFC95, 0x9F24, 0xFC96, 0x9F25, 0xFC97, 0x9F26, 0xFC98, 0x9F27, + 0xFC99, 0x9F28, 0xFC9A, 0x9F29, 0xFC9B, 0x9F2A, 0xFC9C, 0x9F2B, + 0xFC9D, 0x9F2D, 0xFC9E, 0x9F2E, 0xFC9F, 0x9F30, 0xFCA0, 0x9F31, + 0xFD40, 0x9F32, 0xFD41, 0x9F33, 0xFD42, 0x9F34, 0xFD43, 0x9F35, + 0xFD44, 0x9F36, 0xFD45, 0x9F38, 0xFD46, 0x9F3A, 0xFD47, 0x9F3C, + 0xFD48, 0x9F3F, 0xFD49, 0x9F40, 0xFD4A, 0x9F41, 0xFD4B, 0x9F42, + 0xFD4C, 0x9F43, 0xFD4D, 0x9F45, 0xFD4E, 0x9F46, 0xFD4F, 0x9F47, + 0xFD50, 0x9F48, 0xFD51, 0x9F49, 0xFD52, 0x9F4A, 0xFD53, 0x9F4B, + 0xFD54, 0x9F4C, 0xFD55, 0x9F4D, 0xFD56, 0x9F4E, 0xFD57, 0x9F4F, + 0xFD58, 0x9F52, 0xFD59, 0x9F53, 0xFD5A, 0x9F54, 0xFD5B, 0x9F55, + 0xFD5C, 0x9F56, 0xFD5D, 0x9F57, 0xFD5E, 0x9F58, 0xFD5F, 0x9F59, + 0xFD60, 0x9F5A, 0xFD61, 0x9F5B, 0xFD62, 0x9F5C, 0xFD63, 0x9F5D, + 0xFD64, 0x9F5E, 0xFD65, 0x9F5F, 0xFD66, 0x9F60, 0xFD67, 0x9F61, + 0xFD68, 0x9F62, 0xFD69, 0x9F63, 0xFD6A, 0x9F64, 0xFD6B, 0x9F65, + 0xFD6C, 0x9F66, 0xFD6D, 0x9F67, 0xFD6E, 0x9F68, 0xFD6F, 0x9F69, + 0xFD70, 0x9F6A, 0xFD71, 0x9F6B, 0xFD72, 0x9F6C, 0xFD73, 0x9F6D, + 0xFD74, 0x9F6E, 0xFD75, 0x9F6F, 0xFD76, 0x9F70, 0xFD77, 0x9F71, + 0xFD78, 0x9F72, 0xFD79, 0x9F73, 0xFD7A, 0x9F74, 0xFD7B, 0x9F75, + 0xFD7C, 0x9F76, 0xFD7D, 0x9F77, 0xFD7E, 0x9F78, 0xFD80, 0x9F79, + 0xFD81, 0x9F7A, 0xFD82, 0x9F7B, 0xFD83, 0x9F7C, 0xFD84, 0x9F7D, + 0xFD85, 0x9F7E, 0xFD86, 0x9F81, 0xFD87, 0x9F82, 0xFD88, 0x9F8D, + 0xFD89, 0x9F8E, 0xFD8A, 0x9F8F, 0xFD8B, 0x9F90, 0xFD8C, 0x9F91, + 0xFD8D, 0x9F92, 0xFD8E, 0x9F93, 0xFD8F, 0x9F94, 0xFD90, 0x9F95, + 0xFD91, 0x9F96, 0xFD92, 0x9F97, 0xFD93, 0x9F98, 0xFD94, 0x9F9C, + 0xFD95, 0x9F9D, 0xFD96, 0x9F9E, 0xFD97, 0x9FA1, 0xFD98, 0x9FA2, + 0xFD99, 0x9FA3, 0xFD9A, 0x9FA4, 0xFD9B, 0x9FA5, 0xFD9C, 0xF92C, + 0xFD9D, 0xF979, 0xFD9E, 0xF995, 0xFD9F, 0xF9E7, 0xFDA0, 0xF9F1, + 0xFE40, 0xFA0C, 0xFE41, 0xFA0D, 0xFE42, 0xFA0E, 0xFE43, 0xFA0F, + 0xFE44, 0xFA11, 0xFE45, 0xFA13, 0xFE46, 0xFA14, 0xFE47, 0xFA18, + 0xFE48, 0xFA1F, 0xFE49, 0xFA20, 0xFE4A, 0xFA21, 0xFE4B, 0xFA23, + 0xFE4C, 0xFA24, 0xFE4D, 0xFA27, 0xFE4E, 0xFA28, 0xFE4F, 0xFA29, + 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (chr < 0x80) { /* ASCII */ + c = chr; + } else { + if (dir) { /* OEM code to unicode */ + p = oem2uni; + hi = sizeof oem2uni / 4 - 1; + } else { /* Unicode to OEM code */ + p = uni2oem; + hi = sizeof uni2oem / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (chr == p[i * 2]) break; + if (chr > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + +WCHAR ff_wtoupper ( + WCHAR chr /* Unicode character to be upper converted */ +) +{ + static const WCHAR lower[] = { /* Lower case characters to be converted */ + /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, + /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E, + /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217, + /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB, + /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9, + /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586, + /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9, + /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A + }; + static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D, + 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216, + 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8, + 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556, + 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A + }; + UINT i, n, hi, li; + + + if (chr < 0x80) { /* ASCII characters (acceleration) */ + if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20; + + } else { /* Extended characters */ + n = 12; li = 0; hi = sizeof lower / sizeof lower[0]; + do { + i = li + (hi - li) / 2; + if (chr == lower[i]) break; + if (chr > lower[i]) li = i; else hi = i; + } while (--n); + if (n) chr = upper[i]; + } + + return chr; +} + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc949.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc949.c new file mode 100644 index 0000000..0d94566 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc949.c @@ -0,0 +1,8634 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */ +/* CP949 (Korean EUC-KR) */ +/*------------------------------------------------------------------------*/ + +#include "ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 949 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A1, 0xA2AE, 0x00A4, 0xA2B4, 0x00A7, 0xA1D7, 0x00A8, 0xA1A7, + 0x00AA, 0xA8A3, 0x00AD, 0xA1A9, 0x00AE, 0xA2E7, 0x00B0, 0xA1C6, + 0x00B1, 0xA1BE, 0x00B2, 0xA9F7, 0x00B3, 0xA9F8, 0x00B4, 0xA2A5, + 0x00B6, 0xA2D2, 0x00B7, 0xA1A4, 0x00B8, 0xA2AC, 0x00B9, 0xA9F6, + 0x00BA, 0xA8AC, 0x00BC, 0xA8F9, 0x00BD, 0xA8F6, 0x00BE, 0xA8FA, + 0x00BF, 0xA2AF, 0x00C6, 0xA8A1, 0x00D0, 0xA8A2, 0x00D7, 0xA1BF, + 0x00D8, 0xA8AA, 0x00DE, 0xA8AD, 0x00DF, 0xA9AC, 0x00E6, 0xA9A1, + 0x00F0, 0xA9A3, 0x00F7, 0xA1C0, 0x00F8, 0xA9AA, 0x00FE, 0xA9AD, + 0x0111, 0xA9A2, 0x0126, 0xA8A4, 0x0127, 0xA9A4, 0x0131, 0xA9A5, + 0x0132, 0xA8A6, 0x0133, 0xA9A6, 0x0138, 0xA9A7, 0x013F, 0xA8A8, + 0x0140, 0xA9A8, 0x0141, 0xA8A9, 0x0142, 0xA9A9, 0x0149, 0xA9B0, + 0x014A, 0xA8AF, 0x014B, 0xA9AF, 0x0152, 0xA8AB, 0x0153, 0xA9AB, + 0x0166, 0xA8AE, 0x0167, 0xA9AE, 0x02C7, 0xA2A7, 0x02D0, 0xA2B0, + 0x02D8, 0xA2A8, 0x02D9, 0xA2AB, 0x02DA, 0xA2AA, 0x02DB, 0xA2AD, + 0x02DD, 0xA2A9, 0x0391, 0xA5C1, 0x0392, 0xA5C2, 0x0393, 0xA5C3, + 0x0394, 0xA5C4, 0x0395, 0xA5C5, 0x0396, 0xA5C6, 0x0397, 0xA5C7, + 0x0398, 0xA5C8, 0x0399, 0xA5C9, 0x039A, 0xA5CA, 0x039B, 0xA5CB, + 0x039C, 0xA5CC, 0x039D, 0xA5CD, 0x039E, 0xA5CE, 0x039F, 0xA5CF, + 0x03A0, 0xA5D0, 0x03A1, 0xA5D1, 0x03A3, 0xA5D2, 0x03A4, 0xA5D3, + 0x03A5, 0xA5D4, 0x03A6, 0xA5D5, 0x03A7, 0xA5D6, 0x03A8, 0xA5D7, + 0x03A9, 0xA5D8, 0x03B1, 0xA5E1, 0x03B2, 0xA5E2, 0x03B3, 0xA5E3, + 0x03B4, 0xA5E4, 0x03B5, 0xA5E5, 0x03B6, 0xA5E6, 0x03B7, 0xA5E7, + 0x03B8, 0xA5E8, 0x03B9, 0xA5E9, 0x03BA, 0xA5EA, 0x03BB, 0xA5EB, + 0x03BC, 0xA5EC, 0x03BD, 0xA5ED, 0x03BE, 0xA5EE, 0x03BF, 0xA5EF, + 0x03C0, 0xA5F0, 0x03C1, 0xA5F1, 0x03C3, 0xA5F2, 0x03C4, 0xA5F3, + 0x03C5, 0xA5F4, 0x03C6, 0xA5F5, 0x03C7, 0xA5F6, 0x03C8, 0xA5F7, + 0x03C9, 0xA5F8, 0x0401, 0xACA7, 0x0410, 0xACA1, 0x0411, 0xACA2, + 0x0412, 0xACA3, 0x0413, 0xACA4, 0x0414, 0xACA5, 0x0415, 0xACA6, + 0x0416, 0xACA8, 0x0417, 0xACA9, 0x0418, 0xACAA, 0x0419, 0xACAB, + 0x041A, 0xACAC, 0x041B, 0xACAD, 0x041C, 0xACAE, 0x041D, 0xACAF, + 0x041E, 0xACB0, 0x041F, 0xACB1, 0x0420, 0xACB2, 0x0421, 0xACB3, + 0x0422, 0xACB4, 0x0423, 0xACB5, 0x0424, 0xACB6, 0x0425, 0xACB7, + 0x0426, 0xACB8, 0x0427, 0xACB9, 0x0428, 0xACBA, 0x0429, 0xACBB, + 0x042A, 0xACBC, 0x042B, 0xACBD, 0x042C, 0xACBE, 0x042D, 0xACBF, + 0x042E, 0xACC0, 0x042F, 0xACC1, 0x0430, 0xACD1, 0x0431, 0xACD2, + 0x0432, 0xACD3, 0x0433, 0xACD4, 0x0434, 0xACD5, 0x0435, 0xACD6, + 0x0436, 0xACD8, 0x0437, 0xACD9, 0x0438, 0xACDA, 0x0439, 0xACDB, + 0x043A, 0xACDC, 0x043B, 0xACDD, 0x043C, 0xACDE, 0x043D, 0xACDF, + 0x043E, 0xACE0, 0x043F, 0xACE1, 0x0440, 0xACE2, 0x0441, 0xACE3, + 0x0442, 0xACE4, 0x0443, 0xACE5, 0x0444, 0xACE6, 0x0445, 0xACE7, + 0x0446, 0xACE8, 0x0447, 0xACE9, 0x0448, 0xACEA, 0x0449, 0xACEB, + 0x044A, 0xACEC, 0x044B, 0xACED, 0x044C, 0xACEE, 0x044D, 0xACEF, + 0x044E, 0xACF0, 0x044F, 0xACF1, 0x0451, 0xACD7, 0x2015, 0xA1AA, + 0x2018, 0xA1AE, 0x2019, 0xA1AF, 0x201C, 0xA1B0, 0x201D, 0xA1B1, + 0x2020, 0xA2D3, 0x2021, 0xA2D4, 0x2025, 0xA1A5, 0x2026, 0xA1A6, + 0x2030, 0xA2B6, 0x2032, 0xA1C7, 0x2033, 0xA1C8, 0x203B, 0xA1D8, + 0x2074, 0xA9F9, 0x207F, 0xA9FA, 0x2081, 0xA9FB, 0x2082, 0xA9FC, + 0x2083, 0xA9FD, 0x2084, 0xA9FE, 0x20AC, 0xA2E6, 0x2103, 0xA1C9, + 0x2109, 0xA2B5, 0x2113, 0xA7A4, 0x2116, 0xA2E0, 0x2121, 0xA2E5, + 0x2122, 0xA2E2, 0x2126, 0xA7D9, 0x212B, 0xA1CA, 0x2153, 0xA8F7, + 0x2154, 0xA8F8, 0x215B, 0xA8FB, 0x215C, 0xA8FC, 0x215D, 0xA8FD, + 0x215E, 0xA8FE, 0x2160, 0xA5B0, 0x2161, 0xA5B1, 0x2162, 0xA5B2, + 0x2163, 0xA5B3, 0x2164, 0xA5B4, 0x2165, 0xA5B5, 0x2166, 0xA5B6, + 0x2167, 0xA5B7, 0x2168, 0xA5B8, 0x2169, 0xA5B9, 0x2170, 0xA5A1, + 0x2171, 0xA5A2, 0x2172, 0xA5A3, 0x2173, 0xA5A4, 0x2174, 0xA5A5, + 0x2175, 0xA5A6, 0x2176, 0xA5A7, 0x2177, 0xA5A8, 0x2178, 0xA5A9, + 0x2179, 0xA5AA, 0x2190, 0xA1E7, 0x2191, 0xA1E8, 0x2192, 0xA1E6, + 0x2193, 0xA1E9, 0x2194, 0xA1EA, 0x2195, 0xA2D5, 0x2196, 0xA2D8, + 0x2197, 0xA2D6, 0x2198, 0xA2D9, 0x2199, 0xA2D7, 0x21D2, 0xA2A1, + 0x21D4, 0xA2A2, 0x2200, 0xA2A3, 0x2202, 0xA1D3, 0x2203, 0xA2A4, + 0x2207, 0xA1D4, 0x2208, 0xA1F4, 0x220B, 0xA1F5, 0x220F, 0xA2B3, + 0x2211, 0xA2B2, 0x221A, 0xA1EE, 0x221D, 0xA1F0, 0x221E, 0xA1C4, + 0x2220, 0xA1D0, 0x2225, 0xA1AB, 0x2227, 0xA1FC, 0x2228, 0xA1FD, + 0x2229, 0xA1FB, 0x222A, 0xA1FA, 0x222B, 0xA1F2, 0x222C, 0xA1F3, + 0x222E, 0xA2B1, 0x2234, 0xA1C5, 0x2235, 0xA1F1, 0x223C, 0xA1AD, + 0x223D, 0xA1EF, 0x2252, 0xA1D6, 0x2260, 0xA1C1, 0x2261, 0xA1D5, + 0x2264, 0xA1C2, 0x2265, 0xA1C3, 0x226A, 0xA1EC, 0x226B, 0xA1ED, + 0x2282, 0xA1F8, 0x2283, 0xA1F9, 0x2286, 0xA1F6, 0x2287, 0xA1F7, + 0x2299, 0xA2C1, 0x22A5, 0xA1D1, 0x2312, 0xA1D2, 0x2460, 0xA8E7, + 0x2461, 0xA8E8, 0x2462, 0xA8E9, 0x2463, 0xA8EA, 0x2464, 0xA8EB, + 0x2465, 0xA8EC, 0x2466, 0xA8ED, 0x2467, 0xA8EE, 0x2468, 0xA8EF, + 0x2469, 0xA8F0, 0x246A, 0xA8F1, 0x246B, 0xA8F2, 0x246C, 0xA8F3, + 0x246D, 0xA8F4, 0x246E, 0xA8F5, 0x2474, 0xA9E7, 0x2475, 0xA9E8, + 0x2476, 0xA9E9, 0x2477, 0xA9EA, 0x2478, 0xA9EB, 0x2479, 0xA9EC, + 0x247A, 0xA9ED, 0x247B, 0xA9EE, 0x247C, 0xA9EF, 0x247D, 0xA9F0, + 0x247E, 0xA9F1, 0x247F, 0xA9F2, 0x2480, 0xA9F3, 0x2481, 0xA9F4, + 0x2482, 0xA9F5, 0x249C, 0xA9CD, 0x249D, 0xA9CE, 0x249E, 0xA9CF, + 0x249F, 0xA9D0, 0x24A0, 0xA9D1, 0x24A1, 0xA9D2, 0x24A2, 0xA9D3, + 0x24A3, 0xA9D4, 0x24A4, 0xA9D5, 0x24A5, 0xA9D6, 0x24A6, 0xA9D7, + 0x24A7, 0xA9D8, 0x24A8, 0xA9D9, 0x24A9, 0xA9DA, 0x24AA, 0xA9DB, + 0x24AB, 0xA9DC, 0x24AC, 0xA9DD, 0x24AD, 0xA9DE, 0x24AE, 0xA9DF, + 0x24AF, 0xA9E0, 0x24B0, 0xA9E1, 0x24B1, 0xA9E2, 0x24B2, 0xA9E3, + 0x24B3, 0xA9E4, 0x24B4, 0xA9E5, 0x24B5, 0xA9E6, 0x24D0, 0xA8CD, + 0x24D1, 0xA8CE, 0x24D2, 0xA8CF, 0x24D3, 0xA8D0, 0x24D4, 0xA8D1, + 0x24D5, 0xA8D2, 0x24D6, 0xA8D3, 0x24D7, 0xA8D4, 0x24D8, 0xA8D5, + 0x24D9, 0xA8D6, 0x24DA, 0xA8D7, 0x24DB, 0xA8D8, 0x24DC, 0xA8D9, + 0x24DD, 0xA8DA, 0x24DE, 0xA8DB, 0x24DF, 0xA8DC, 0x24E0, 0xA8DD, + 0x24E1, 0xA8DE, 0x24E2, 0xA8DF, 0x24E3, 0xA8E0, 0x24E4, 0xA8E1, + 0x24E5, 0xA8E2, 0x24E6, 0xA8E3, 0x24E7, 0xA8E4, 0x24E8, 0xA8E5, + 0x24E9, 0xA8E6, 0x2500, 0xA6A1, 0x2501, 0xA6AC, 0x2502, 0xA6A2, + 0x2503, 0xA6AD, 0x250C, 0xA6A3, 0x250D, 0xA6C8, 0x250E, 0xA6C7, + 0x250F, 0xA6AE, 0x2510, 0xA6A4, 0x2511, 0xA6C2, 0x2512, 0xA6C1, + 0x2513, 0xA6AF, 0x2514, 0xA6A6, 0x2515, 0xA6C6, 0x2516, 0xA6C5, + 0x2517, 0xA6B1, 0x2518, 0xA6A5, 0x2519, 0xA6C4, 0x251A, 0xA6C3, + 0x251B, 0xA6B0, 0x251C, 0xA6A7, 0x251D, 0xA6BC, 0x251E, 0xA6C9, + 0x251F, 0xA6CA, 0x2520, 0xA6B7, 0x2521, 0xA6CB, 0x2522, 0xA6CC, + 0x2523, 0xA6B2, 0x2524, 0xA6A9, 0x2525, 0xA6BE, 0x2526, 0xA6CD, + 0x2527, 0xA6CE, 0x2528, 0xA6B9, 0x2529, 0xA6CF, 0x252A, 0xA6D0, + 0x252B, 0xA6B4, 0x252C, 0xA6A8, 0x252D, 0xA6D1, 0x252E, 0xA6D2, + 0x252F, 0xA6B8, 0x2530, 0xA6BD, 0x2531, 0xA6D3, 0x2532, 0xA6D4, + 0x2533, 0xA6B3, 0x2534, 0xA6AA, 0x2535, 0xA6D5, 0x2536, 0xA6D6, + 0x2537, 0xA6BA, 0x2538, 0xA6BF, 0x2539, 0xA6D7, 0x253A, 0xA6D8, + 0x253B, 0xA6B5, 0x253C, 0xA6AB, 0x253D, 0xA6D9, 0x253E, 0xA6DA, + 0x253F, 0xA6BB, 0x2540, 0xA6DB, 0x2541, 0xA6DC, 0x2542, 0xA6C0, + 0x2543, 0xA6DD, 0x2544, 0xA6DE, 0x2545, 0xA6DF, 0x2546, 0xA6E0, + 0x2547, 0xA6E1, 0x2548, 0xA6E2, 0x2549, 0xA6E3, 0x254A, 0xA6E4, + 0x254B, 0xA6B6, 0x2592, 0xA2C6, 0x25A0, 0xA1E1, 0x25A1, 0xA1E0, + 0x25A3, 0xA2C3, 0x25A4, 0xA2C7, 0x25A5, 0xA2C8, 0x25A6, 0xA2CB, + 0x25A7, 0xA2CA, 0x25A8, 0xA2C9, 0x25A9, 0xA2CC, 0x25B2, 0xA1E3, + 0x25B3, 0xA1E2, 0x25B6, 0xA2BA, 0x25B7, 0xA2B9, 0x25BC, 0xA1E5, + 0x25BD, 0xA1E4, 0x25C0, 0xA2B8, 0x25C1, 0xA2B7, 0x25C6, 0xA1DF, + 0x25C7, 0xA1DE, 0x25C8, 0xA2C2, 0x25CB, 0xA1DB, 0x25CE, 0xA1DD, + 0x25CF, 0xA1DC, 0x25D0, 0xA2C4, 0x25D1, 0xA2C5, 0x2605, 0xA1DA, + 0x2606, 0xA1D9, 0x260E, 0xA2CF, 0x260F, 0xA2CE, 0x261C, 0xA2D0, + 0x261E, 0xA2D1, 0x2640, 0xA1CF, 0x2642, 0xA1CE, 0x2660, 0xA2BC, + 0x2661, 0xA2BD, 0x2663, 0xA2C0, 0x2664, 0xA2BB, 0x2665, 0xA2BE, + 0x2667, 0xA2BF, 0x2668, 0xA2CD, 0x2669, 0xA2DB, 0x266A, 0xA2DC, + 0x266C, 0xA2DD, 0x266D, 0xA2DA, 0x3000, 0xA1A1, 0x3001, 0xA1A2, + 0x3002, 0xA1A3, 0x3003, 0xA1A8, 0x3008, 0xA1B4, 0x3009, 0xA1B5, + 0x300A, 0xA1B6, 0x300B, 0xA1B7, 0x300C, 0xA1B8, 0x300D, 0xA1B9, + 0x300E, 0xA1BA, 0x300F, 0xA1BB, 0x3010, 0xA1BC, 0x3011, 0xA1BD, + 0x3013, 0xA1EB, 0x3014, 0xA1B2, 0x3015, 0xA1B3, 0x3041, 0xAAA1, + 0x3042, 0xAAA2, 0x3043, 0xAAA3, 0x3044, 0xAAA4, 0x3045, 0xAAA5, + 0x3046, 0xAAA6, 0x3047, 0xAAA7, 0x3048, 0xAAA8, 0x3049, 0xAAA9, + 0x304A, 0xAAAA, 0x304B, 0xAAAB, 0x304C, 0xAAAC, 0x304D, 0xAAAD, + 0x304E, 0xAAAE, 0x304F, 0xAAAF, 0x3050, 0xAAB0, 0x3051, 0xAAB1, + 0x3052, 0xAAB2, 0x3053, 0xAAB3, 0x3054, 0xAAB4, 0x3055, 0xAAB5, + 0x3056, 0xAAB6, 0x3057, 0xAAB7, 0x3058, 0xAAB8, 0x3059, 0xAAB9, + 0x305A, 0xAABA, 0x305B, 0xAABB, 0x305C, 0xAABC, 0x305D, 0xAABD, + 0x305E, 0xAABE, 0x305F, 0xAABF, 0x3060, 0xAAC0, 0x3061, 0xAAC1, + 0x3062, 0xAAC2, 0x3063, 0xAAC3, 0x3064, 0xAAC4, 0x3065, 0xAAC5, + 0x3066, 0xAAC6, 0x3067, 0xAAC7, 0x3068, 0xAAC8, 0x3069, 0xAAC9, + 0x306A, 0xAACA, 0x306B, 0xAACB, 0x306C, 0xAACC, 0x306D, 0xAACD, + 0x306E, 0xAACE, 0x306F, 0xAACF, 0x3070, 0xAAD0, 0x3071, 0xAAD1, + 0x3072, 0xAAD2, 0x3073, 0xAAD3, 0x3074, 0xAAD4, 0x3075, 0xAAD5, + 0x3076, 0xAAD6, 0x3077, 0xAAD7, 0x3078, 0xAAD8, 0x3079, 0xAAD9, + 0x307A, 0xAADA, 0x307B, 0xAADB, 0x307C, 0xAADC, 0x307D, 0xAADD, + 0x307E, 0xAADE, 0x307F, 0xAADF, 0x3080, 0xAAE0, 0x3081, 0xAAE1, + 0x3082, 0xAAE2, 0x3083, 0xAAE3, 0x3084, 0xAAE4, 0x3085, 0xAAE5, + 0x3086, 0xAAE6, 0x3087, 0xAAE7, 0x3088, 0xAAE8, 0x3089, 0xAAE9, + 0x308A, 0xAAEA, 0x308B, 0xAAEB, 0x308C, 0xAAEC, 0x308D, 0xAAED, + 0x308E, 0xAAEE, 0x308F, 0xAAEF, 0x3090, 0xAAF0, 0x3091, 0xAAF1, + 0x3092, 0xAAF2, 0x3093, 0xAAF3, 0x30A1, 0xABA1, 0x30A2, 0xABA2, + 0x30A3, 0xABA3, 0x30A4, 0xABA4, 0x30A5, 0xABA5, 0x30A6, 0xABA6, + 0x30A7, 0xABA7, 0x30A8, 0xABA8, 0x30A9, 0xABA9, 0x30AA, 0xABAA, + 0x30AB, 0xABAB, 0x30AC, 0xABAC, 0x30AD, 0xABAD, 0x30AE, 0xABAE, + 0x30AF, 0xABAF, 0x30B0, 0xABB0, 0x30B1, 0xABB1, 0x30B2, 0xABB2, + 0x30B3, 0xABB3, 0x30B4, 0xABB4, 0x30B5, 0xABB5, 0x30B6, 0xABB6, + 0x30B7, 0xABB7, 0x30B8, 0xABB8, 0x30B9, 0xABB9, 0x30BA, 0xABBA, + 0x30BB, 0xABBB, 0x30BC, 0xABBC, 0x30BD, 0xABBD, 0x30BE, 0xABBE, + 0x30BF, 0xABBF, 0x30C0, 0xABC0, 0x30C1, 0xABC1, 0x30C2, 0xABC2, + 0x30C3, 0xABC3, 0x30C4, 0xABC4, 0x30C5, 0xABC5, 0x30C6, 0xABC6, + 0x30C7, 0xABC7, 0x30C8, 0xABC8, 0x30C9, 0xABC9, 0x30CA, 0xABCA, + 0x30CB, 0xABCB, 0x30CC, 0xABCC, 0x30CD, 0xABCD, 0x30CE, 0xABCE, + 0x30CF, 0xABCF, 0x30D0, 0xABD0, 0x30D1, 0xABD1, 0x30D2, 0xABD2, + 0x30D3, 0xABD3, 0x30D4, 0xABD4, 0x30D5, 0xABD5, 0x30D6, 0xABD6, + 0x30D7, 0xABD7, 0x30D8, 0xABD8, 0x30D9, 0xABD9, 0x30DA, 0xABDA, + 0x30DB, 0xABDB, 0x30DC, 0xABDC, 0x30DD, 0xABDD, 0x30DE, 0xABDE, + 0x30DF, 0xABDF, 0x30E0, 0xABE0, 0x30E1, 0xABE1, 0x30E2, 0xABE2, + 0x30E3, 0xABE3, 0x30E4, 0xABE4, 0x30E5, 0xABE5, 0x30E6, 0xABE6, + 0x30E7, 0xABE7, 0x30E8, 0xABE8, 0x30E9, 0xABE9, 0x30EA, 0xABEA, + 0x30EB, 0xABEB, 0x30EC, 0xABEC, 0x30ED, 0xABED, 0x30EE, 0xABEE, + 0x30EF, 0xABEF, 0x30F0, 0xABF0, 0x30F1, 0xABF1, 0x30F2, 0xABF2, + 0x30F3, 0xABF3, 0x30F4, 0xABF4, 0x30F5, 0xABF5, 0x30F6, 0xABF6, + 0x3131, 0xA4A1, 0x3132, 0xA4A2, 0x3133, 0xA4A3, 0x3134, 0xA4A4, + 0x3135, 0xA4A5, 0x3136, 0xA4A6, 0x3137, 0xA4A7, 0x3138, 0xA4A8, + 0x3139, 0xA4A9, 0x313A, 0xA4AA, 0x313B, 0xA4AB, 0x313C, 0xA4AC, + 0x313D, 0xA4AD, 0x313E, 0xA4AE, 0x313F, 0xA4AF, 0x3140, 0xA4B0, + 0x3141, 0xA4B1, 0x3142, 0xA4B2, 0x3143, 0xA4B3, 0x3144, 0xA4B4, + 0x3145, 0xA4B5, 0x3146, 0xA4B6, 0x3147, 0xA4B7, 0x3148, 0xA4B8, + 0x3149, 0xA4B9, 0x314A, 0xA4BA, 0x314B, 0xA4BB, 0x314C, 0xA4BC, + 0x314D, 0xA4BD, 0x314E, 0xA4BE, 0x314F, 0xA4BF, 0x3150, 0xA4C0, + 0x3151, 0xA4C1, 0x3152, 0xA4C2, 0x3153, 0xA4C3, 0x3154, 0xA4C4, + 0x3155, 0xA4C5, 0x3156, 0xA4C6, 0x3157, 0xA4C7, 0x3158, 0xA4C8, + 0x3159, 0xA4C9, 0x315A, 0xA4CA, 0x315B, 0xA4CB, 0x315C, 0xA4CC, + 0x315D, 0xA4CD, 0x315E, 0xA4CE, 0x315F, 0xA4CF, 0x3160, 0xA4D0, + 0x3161, 0xA4D1, 0x3162, 0xA4D2, 0x3163, 0xA4D3, 0x3164, 0xA4D4, + 0x3165, 0xA4D5, 0x3166, 0xA4D6, 0x3167, 0xA4D7, 0x3168, 0xA4D8, + 0x3169, 0xA4D9, 0x316A, 0xA4DA, 0x316B, 0xA4DB, 0x316C, 0xA4DC, + 0x316D, 0xA4DD, 0x316E, 0xA4DE, 0x316F, 0xA4DF, 0x3170, 0xA4E0, + 0x3171, 0xA4E1, 0x3172, 0xA4E2, 0x3173, 0xA4E3, 0x3174, 0xA4E4, + 0x3175, 0xA4E5, 0x3176, 0xA4E6, 0x3177, 0xA4E7, 0x3178, 0xA4E8, + 0x3179, 0xA4E9, 0x317A, 0xA4EA, 0x317B, 0xA4EB, 0x317C, 0xA4EC, + 0x317D, 0xA4ED, 0x317E, 0xA4EE, 0x317F, 0xA4EF, 0x3180, 0xA4F0, + 0x3181, 0xA4F1, 0x3182, 0xA4F2, 0x3183, 0xA4F3, 0x3184, 0xA4F4, + 0x3185, 0xA4F5, 0x3186, 0xA4F6, 0x3187, 0xA4F7, 0x3188, 0xA4F8, + 0x3189, 0xA4F9, 0x318A, 0xA4FA, 0x318B, 0xA4FB, 0x318C, 0xA4FC, + 0x318D, 0xA4FD, 0x318E, 0xA4FE, 0x3200, 0xA9B1, 0x3201, 0xA9B2, + 0x3202, 0xA9B3, 0x3203, 0xA9B4, 0x3204, 0xA9B5, 0x3205, 0xA9B6, + 0x3206, 0xA9B7, 0x3207, 0xA9B8, 0x3208, 0xA9B9, 0x3209, 0xA9BA, + 0x320A, 0xA9BB, 0x320B, 0xA9BC, 0x320C, 0xA9BD, 0x320D, 0xA9BE, + 0x320E, 0xA9BF, 0x320F, 0xA9C0, 0x3210, 0xA9C1, 0x3211, 0xA9C2, + 0x3212, 0xA9C3, 0x3213, 0xA9C4, 0x3214, 0xA9C5, 0x3215, 0xA9C6, + 0x3216, 0xA9C7, 0x3217, 0xA9C8, 0x3218, 0xA9C9, 0x3219, 0xA9CA, + 0x321A, 0xA9CB, 0x321B, 0xA9CC, 0x321C, 0xA2DF, 0x3260, 0xA8B1, + 0x3261, 0xA8B2, 0x3262, 0xA8B3, 0x3263, 0xA8B4, 0x3264, 0xA8B5, + 0x3265, 0xA8B6, 0x3266, 0xA8B7, 0x3267, 0xA8B8, 0x3268, 0xA8B9, + 0x3269, 0xA8BA, 0x326A, 0xA8BB, 0x326B, 0xA8BC, 0x326C, 0xA8BD, + 0x326D, 0xA8BE, 0x326E, 0xA8BF, 0x326F, 0xA8C0, 0x3270, 0xA8C1, + 0x3271, 0xA8C2, 0x3272, 0xA8C3, 0x3273, 0xA8C4, 0x3274, 0xA8C5, + 0x3275, 0xA8C6, 0x3276, 0xA8C7, 0x3277, 0xA8C8, 0x3278, 0xA8C9, + 0x3279, 0xA8CA, 0x327A, 0xA8CB, 0x327B, 0xA8CC, 0x327F, 0xA2DE, + 0x3380, 0xA7C9, 0x3381, 0xA7CA, 0x3382, 0xA7CB, 0x3383, 0xA7CC, + 0x3384, 0xA7CD, 0x3388, 0xA7BA, 0x3389, 0xA7BB, 0x338A, 0xA7DC, + 0x338B, 0xA7DD, 0x338C, 0xA7DE, 0x338D, 0xA7B6, 0x338E, 0xA7B7, + 0x338F, 0xA7B8, 0x3390, 0xA7D4, 0x3391, 0xA7D5, 0x3392, 0xA7D6, + 0x3393, 0xA7D7, 0x3394, 0xA7D8, 0x3395, 0xA7A1, 0x3396, 0xA7A2, + 0x3397, 0xA7A3, 0x3398, 0xA7A5, 0x3399, 0xA7AB, 0x339A, 0xA7AC, + 0x339B, 0xA7AD, 0x339C, 0xA7AE, 0x339D, 0xA7AF, 0x339E, 0xA7B0, + 0x339F, 0xA7B1, 0x33A0, 0xA7B2, 0x33A1, 0xA7B3, 0x33A2, 0xA7B4, + 0x33A3, 0xA7A7, 0x33A4, 0xA7A8, 0x33A5, 0xA7A9, 0x33A6, 0xA7AA, + 0x33A7, 0xA7BD, 0x33A8, 0xA7BE, 0x33A9, 0xA7E5, 0x33AA, 0xA7E6, + 0x33AB, 0xA7E7, 0x33AC, 0xA7E8, 0x33AD, 0xA7E1, 0x33AE, 0xA7E2, + 0x33AF, 0xA7E3, 0x33B0, 0xA7BF, 0x33B1, 0xA7C0, 0x33B2, 0xA7C1, + 0x33B3, 0xA7C2, 0x33B4, 0xA7C3, 0x33B5, 0xA7C4, 0x33B6, 0xA7C5, + 0x33B7, 0xA7C6, 0x33B8, 0xA7C7, 0x33B9, 0xA7C8, 0x33BA, 0xA7CE, + 0x33BB, 0xA7CF, 0x33BC, 0xA7D0, 0x33BD, 0xA7D1, 0x33BE, 0xA7D2, + 0x33BF, 0xA7D3, 0x33C0, 0xA7DA, 0x33C1, 0xA7DB, 0x33C2, 0xA2E3, + 0x33C3, 0xA7EC, 0x33C4, 0xA7A6, 0x33C5, 0xA7E0, 0x33C6, 0xA7EF, + 0x33C7, 0xA2E1, 0x33C8, 0xA7BC, 0x33C9, 0xA7ED, 0x33CA, 0xA7B5, + 0x33CF, 0xA7B9, 0x33D0, 0xA7EA, 0x33D3, 0xA7EB, 0x33D6, 0xA7DF, + 0x33D8, 0xA2E4, 0x33DB, 0xA7E4, 0x33DC, 0xA7EE, 0x33DD, 0xA7E9, + 0x4E00, 0xECE9, 0x4E01, 0xEFCB, 0x4E03, 0xF6D2, 0x4E07, 0xD8B2, + 0x4E08, 0xEDDB, 0x4E09, 0xDFB2, 0x4E0A, 0xDFBE, 0x4E0B, 0xF9BB, + 0x4E0D, 0xDCF4, 0x4E11, 0xF5E4, 0x4E14, 0xF3A6, 0x4E15, 0xDDE0, + 0x4E16, 0xE1A6, 0x4E18, 0xCEF8, 0x4E19, 0xDCB0, 0x4E1E, 0xE3AA, + 0x4E2D, 0xF1E9, 0x4E32, 0xCDFA, 0x4E38, 0xFCAF, 0x4E39, 0xD3A1, + 0x4E3B, 0xF1AB, 0x4E42, 0xE7D1, 0x4E43, 0xD2AC, 0x4E45, 0xCEF9, + 0x4E4B, 0xF1FD, 0x4E4D, 0xDEBF, 0x4E4E, 0xFBBA, 0x4E4F, 0xF9B9, + 0x4E56, 0xCED2, 0x4E58, 0xE3AB, 0x4E59, 0xEBE0, 0x4E5D, 0xCEFA, + 0x4E5E, 0xCBF7, 0x4E5F, 0xE5A5, 0x4E6B, 0xCAE1, 0x4E6D, 0xD4CC, + 0x4E73, 0xEAE1, 0x4E76, 0xDCE3, 0x4E77, 0xDFAD, 0x4E7E, 0xCBEB, + 0x4E82, 0xD5AF, 0x4E86, 0xD6F5, 0x4E88, 0xE5F8, 0x4E8B, 0xDEC0, + 0x4E8C, 0xECA3, 0x4E8E, 0xE9CD, 0x4E90, 0xEAA7, 0x4E91, 0xE9F6, + 0x4E92, 0xFBBB, 0x4E94, 0xE7E9, 0x4E95, 0xEFCC, 0x4E98, 0xD0E6, + 0x4E9B, 0xDEC1, 0x4E9E, 0xE4AC, 0x4EA1, 0xD8CC, 0x4EA2, 0xF9F1, + 0x4EA4, 0xCEDF, 0x4EA5, 0xFAA4, 0x4EA6, 0xE6B2, 0x4EA8, 0xFAFB, + 0x4EAB, 0xFABD, 0x4EAC, 0xCCC8, 0x4EAD, 0xEFCD, 0x4EAE, 0xD5D5, + 0x4EB6, 0xD3A2, 0x4EBA, 0xECD1, 0x4EC0, 0xE4A7, 0x4EC1, 0xECD2, + 0x4EC4, 0xF6B1, 0x4EC7, 0xCEFB, 0x4ECA, 0xD0D1, 0x4ECB, 0xCBBF, + 0x4ECD, 0xEDA4, 0x4ED4, 0xEDA8, 0x4ED5, 0xDEC2, 0x4ED6, 0xF6E2, + 0x4ED7, 0xEDDC, 0x4ED8, 0xDCF5, 0x4ED9, 0xE0B9, 0x4EDD, 0xD4CE, + 0x4EDF, 0xF4B5, 0x4EE3, 0xD3DB, 0x4EE4, 0xD6B5, 0x4EE5, 0xECA4, + 0x4EF0, 0xE4E6, 0x4EF2, 0xF1EA, 0x4EF6, 0xCBEC, 0x4EF7, 0xCBC0, + 0x4EFB, 0xECF2, 0x4F01, 0xD0EA, 0x4F09, 0xF9F2, 0x4F0A, 0xECA5, + 0x4F0B, 0xD0DF, 0x4F0D, 0xE7EA, 0x4F0E, 0xD0EB, 0x4F0F, 0xDCD1, + 0x4F10, 0xDBE9, 0x4F11, 0xFDCC, 0x4F2F, 0xDBD7, 0x4F34, 0xDAE1, + 0x4F36, 0xD6B6, 0x4F38, 0xE3DF, 0x4F3A, 0xDEC3, 0x4F3C, 0xDEC4, + 0x4F3D, 0xCAA1, 0x4F43, 0xEEEC, 0x4F46, 0xD3A3, 0x4F47, 0xEEB7, + 0x4F48, 0xF8CF, 0x4F4D, 0xEAC8, 0x4F4E, 0xEEB8, 0x4F4F, 0xF1AC, + 0x4F50, 0xF1A5, 0x4F51, 0xE9CE, 0x4F55, 0xF9BC, 0x4F59, 0xE5F9, + 0x4F5A, 0xECEA, 0x4F5B, 0xDDD6, 0x4F5C, 0xEDC2, 0x4F69, 0xF8A5, + 0x4F6F, 0xE5BA, 0x4F70, 0xDBD8, 0x4F73, 0xCAA2, 0x4F76, 0xD1CD, + 0x4F7A, 0xEEED, 0x4F7E, 0xECEB, 0x4F7F, 0xDEC5, 0x4F81, 0xE3E0, + 0x4F83, 0xCAC9, 0x4F84, 0xF2E9, 0x4F86, 0xD5CE, 0x4F88, 0xF6B6, + 0x4F8A, 0xCEC2, 0x4F8B, 0xD6C7, 0x4F8D, 0xE3B4, 0x4F8F, 0xF1AD, + 0x4F91, 0xEAE2, 0x4F96, 0xD7C2, 0x4F98, 0xF3A7, 0x4F9B, 0xCDEA, + 0x4F9D, 0xEBEE, 0x4FAE, 0xD9B2, 0x4FAF, 0xFDA5, 0x4FB5, 0xF6D5, + 0x4FB6, 0xD5E2, 0x4FBF, 0xF8B5, 0x4FC2, 0xCCF5, 0x4FC3, 0xF5B5, + 0x4FC4, 0xE4AD, 0x4FC9, 0xE7EB, 0x4FCA, 0xF1D5, 0x4FCE, 0xF0BB, + 0x4FD1, 0xE9B5, 0x4FD3, 0xCCC9, 0x4FD4, 0xFAD5, 0x4FD7, 0xE1D4, + 0x4FDA, 0xD7D6, 0x4FDD, 0xDCC1, 0x4FDF, 0xDEC6, 0x4FE0, 0xFAEF, + 0x4FE1, 0xE3E1, 0x4FEE, 0xE1F3, 0x4FEF, 0xDCF6, 0x4FF1, 0xCEFC, + 0x4FF3, 0xDBC4, 0x4FF5, 0xF8F1, 0x4FF8, 0xDCE4, 0x4FFA, 0xE5EF, + 0x5002, 0xDCB1, 0x5006, 0xD5D6, 0x5009, 0xF3DA, 0x500B, 0xCBC1, + 0x500D, 0xDBC3, 0x5011, 0xD9FA, 0x5012, 0xD3EE, 0x5016, 0xFAB8, + 0x5019, 0xFDA6, 0x501A, 0xEBEF, 0x501C, 0xF4A6, 0x501E, 0xCCCA, + 0x501F, 0xF3A8, 0x5021, 0xF3DB, 0x5023, 0xDBA7, 0x5024, 0xF6B7, + 0x5026, 0xCFE6, 0x5027, 0xF0F2, 0x5028, 0xCBDA, 0x502A, 0xE7D2, + 0x502B, 0xD7C3, 0x502C, 0xF6F0, 0x502D, 0xE8DE, 0x503B, 0xE5A6, + 0x5043, 0xE5E7, 0x5047, 0xCAA3, 0x5048, 0xCCA7, 0x5049, 0xEAC9, + 0x504F, 0xF8B6, 0x5055, 0xFAA5, 0x505A, 0xF1AE, 0x505C, 0xEFCE, + 0x5065, 0xCBED, 0x5074, 0xF6B0, 0x5075, 0xEFCF, 0x5076, 0xE9CF, + 0x5078, 0xF7DE, 0x5080, 0xCED3, 0x5085, 0xDCF7, 0x508D, 0xDBA8, + 0x5091, 0xCBF8, 0x5098, 0xDFA1, 0x5099, 0xDDE1, 0x50AC, 0xF5CA, + 0x50AD, 0xE9B6, 0x50B2, 0xE7EC, 0x50B3, 0xEEEE, 0x50B5, 0xF3F0, + 0x50B7, 0xDFBF, 0x50BE, 0xCCCB, 0x50C5, 0xD0C1, 0x50C9, 0xF4D2, + 0x50CA, 0xE0BA, 0x50CF, 0xDFC0, 0x50D1, 0xCEE0, 0x50D5, 0xDCD2, + 0x50D6, 0xFDEA, 0x50DA, 0xD6F6, 0x50DE, 0xEACA, 0x50E5, 0xE8E9, + 0x50E7, 0xE3AC, 0x50ED, 0xF3D0, 0x50F9, 0xCAA4, 0x50FB, 0xDBF8, + 0x50FF, 0xDEC7, 0x5100, 0xEBF0, 0x5101, 0xF1D6, 0x5104, 0xE5E2, + 0x5106, 0xCCCC, 0x5109, 0xCBFB, 0x5112, 0xEAE3, 0x511F, 0xDFC1, + 0x5121, 0xD6ED, 0x512A, 0xE9D0, 0x5132, 0xEEB9, 0x5137, 0xD5E3, + 0x513A, 0xD1D3, 0x513C, 0xE5F0, 0x5140, 0xE8B4, 0x5141, 0xEBC3, + 0x5143, 0xEAAA, 0x5144, 0xFAFC, 0x5145, 0xF5F6, 0x5146, 0xF0BC, + 0x5147, 0xFDD4, 0x5148, 0xE0BB, 0x5149, 0xCEC3, 0x514B, 0xD0BA, + 0x514C, 0xF7BA, 0x514D, 0xD8F3, 0x514E, 0xF7CD, 0x5152, 0xE4AE, + 0x515C, 0xD4DF, 0x5162, 0xD0E7, 0x5165, 0xECFD, 0x5167, 0xD2AE, + 0x5168, 0xEEEF, 0x5169, 0xD5D7, 0x516A, 0xEAE4, 0x516B, 0xF8A2, + 0x516C, 0xCDEB, 0x516D, 0xD7BF, 0x516E, 0xFBB1, 0x5171, 0xCDEC, + 0x5175, 0xDCB2, 0x5176, 0xD0EC, 0x5177, 0xCEFD, 0x5178, 0xEEF0, + 0x517C, 0xCCC2, 0x5180, 0xD0ED, 0x5186, 0xE5F7, 0x518A, 0xF3FC, + 0x518D, 0xEEA2, 0x5192, 0xD9B3, 0x5195, 0xD8F4, 0x5197, 0xE9B7, + 0x51A0, 0xCEAE, 0x51A5, 0xD9A2, 0x51AA, 0xD8F1, 0x51AC, 0xD4CF, + 0x51B6, 0xE5A7, 0x51B7, 0xD5D2, 0x51BD, 0xD6A9, 0x51C4, 0xF4A2, + 0x51C6, 0xF1D7, 0x51C9, 0xD5D8, 0x51CB, 0xF0BD, 0x51CC, 0xD7D0, + 0x51CD, 0xD4D0, 0x51DC, 0xD7CF, 0x51DD, 0xEBEA, 0x51DE, 0xFDEB, + 0x51E1, 0xDBED, 0x51F0, 0xFCC5, 0x51F1, 0xCBC2, 0x51F6, 0xFDD5, + 0x51F8, 0xF4C8, 0x51F9, 0xE8EA, 0x51FA, 0xF5F3, 0x51FD, 0xF9DE, + 0x5200, 0xD3EF, 0x5203, 0xECD3, 0x5206, 0xDDC2, 0x5207, 0xEFB7, + 0x5208, 0xE7D4, 0x520A, 0xCACA, 0x520E, 0xD9FB, 0x5211, 0xFAFD, + 0x5217, 0xD6AA, 0x521D, 0xF4F8, 0x5224, 0xF7F7, 0x5225, 0xDCAC, + 0x5229, 0xD7D7, 0x522A, 0xDFA2, 0x522E, 0xCEBE, 0x5230, 0xD3F0, + 0x5236, 0xF0A4, 0x5237, 0xE1EC, 0x5238, 0xCFE7, 0x5239, 0xF3CB, + 0x523A, 0xEDA9, 0x523B, 0xCABE, 0x5243, 0xF4EF, 0x5247, 0xF6CE, + 0x524A, 0xDEFB, 0x524B, 0xD0BB, 0x524C, 0xD5B7, 0x524D, 0xEEF1, + 0x5254, 0xF4A8, 0x5256, 0xDCF8, 0x525B, 0xCBA7, 0x525D, 0xDACE, + 0x5261, 0xE0E6, 0x5269, 0xEDA5, 0x526A, 0xEEF2, 0x526F, 0xDCF9, + 0x5272, 0xF9DC, 0x5275, 0xF3DC, 0x527D, 0xF8F2, 0x527F, 0xF4F9, + 0x5283, 0xFCF1, 0x5287, 0xD0BC, 0x5288, 0xDBF9, 0x5289, 0xD7B1, + 0x528D, 0xCBFC, 0x5291, 0xF0A5, 0x5292, 0xCBFD, 0x529B, 0xD5F4, + 0x529F, 0xCDED, 0x52A0, 0xCAA5, 0x52A3, 0xD6AB, 0x52A4, 0xD0C2, + 0x52A9, 0xF0BE, 0x52AA, 0xD2BD, 0x52AB, 0xCCA4, 0x52BE, 0xFAB6, + 0x52C1, 0xCCCD, 0x52C3, 0xDAFA, 0x52C5, 0xF6CF, 0x52C7, 0xE9B8, + 0x52C9, 0xD8F5, 0x52CD, 0xCCCE, 0x52D2, 0xD7CD, 0x52D5, 0xD4D1, + 0x52D6, 0xE9ED, 0x52D8, 0xCAEB, 0x52D9, 0xD9E2, 0x52DB, 0xFDB2, + 0x52DD, 0xE3AD, 0x52DE, 0xD6CC, 0x52DF, 0xD9B4, 0x52E2, 0xE1A7, + 0x52E3, 0xEED3, 0x52E4, 0xD0C3, 0x52F3, 0xFDB3, 0x52F5, 0xD5E4, + 0x52F8, 0xCFE8, 0x52FA, 0xEDC3, 0x52FB, 0xD0B2, 0x52FE, 0xCEFE, + 0x52FF, 0xDAA8, 0x5305, 0xF8D0, 0x5308, 0xFDD6, 0x530D, 0xF8D1, + 0x530F, 0xF8D2, 0x5310, 0xDCD3, 0x5315, 0xDDE2, 0x5316, 0xFBF9, + 0x5317, 0xDDC1, 0x5319, 0xE3B5, 0x5320, 0xEDDD, 0x5321, 0xCEC4, + 0x5323, 0xCBA1, 0x532A, 0xDDE3, 0x532F, 0xFCDD, 0x5339, 0xF9AF, + 0x533F, 0xD2FB, 0x5340, 0xCFA1, 0x5341, 0xE4A8, 0x5343, 0xF4B6, + 0x5344, 0xECFE, 0x5347, 0xE3AE, 0x5348, 0xE7ED, 0x5349, 0xFDC1, + 0x534A, 0xDAE2, 0x534D, 0xD8B3, 0x5351, 0xDDE4, 0x5352, 0xF0EF, + 0x5353, 0xF6F1, 0x5354, 0xFAF0, 0x5357, 0xD1F5, 0x535A, 0xDACF, + 0x535C, 0xDCD4, 0x535E, 0xDCA6, 0x5360, 0xEFBF, 0x5366, 0xCECF, + 0x5368, 0xE0D9, 0x536F, 0xD9D6, 0x5370, 0xECD4, 0x5371, 0xEACB, + 0x5374, 0xCABF, 0x5375, 0xD5B0, 0x5377, 0xCFE9, 0x537D, 0xF1ED, + 0x537F, 0xCCCF, 0x5384, 0xE4F8, 0x5393, 0xE4ED, 0x5398, 0xD7D8, + 0x539A, 0xFDA7, 0x539F, 0xEAAB, 0x53A0, 0xF6B2, 0x53A5, 0xCFF0, + 0x53A6, 0xF9BD, 0x53AD, 0xE6F4, 0x53BB, 0xCBDB, 0x53C3, 0xF3D1, + 0x53C8, 0xE9D1, 0x53C9, 0xF3A9, 0x53CA, 0xD0E0, 0x53CB, 0xE9D2, + 0x53CD, 0xDAE3, 0x53D4, 0xE2D2, 0x53D6, 0xF6A2, 0x53D7, 0xE1F4, + 0x53DB, 0xDAE4, 0x53E1, 0xE7D5, 0x53E2, 0xF5BF, 0x53E3, 0xCFA2, + 0x53E4, 0xCDAF, 0x53E5, 0xCFA3, 0x53E9, 0xCDB0, 0x53EA, 0xF1FE, + 0x53EB, 0xD0A3, 0x53EC, 0xE1AF, 0x53ED, 0xF8A3, 0x53EF, 0xCAA6, + 0x53F0, 0xF7BB, 0x53F1, 0xF2EA, 0x53F2, 0xDEC8, 0x53F3, 0xE9D3, + 0x53F8, 0xDEC9, 0x5403, 0xFDDE, 0x5404, 0xCAC0, 0x5408, 0xF9EA, + 0x5409, 0xD1CE, 0x540A, 0xEED4, 0x540C, 0xD4D2, 0x540D, 0xD9A3, + 0x540E, 0xFDA8, 0x540F, 0xD7D9, 0x5410, 0xF7CE, 0x5411, 0xFABE, + 0x541B, 0xCFD6, 0x541D, 0xD7F0, 0x541F, 0xEBE1, 0x5420, 0xF8C5, + 0x5426, 0xDCFA, 0x5429, 0xDDC3, 0x542B, 0xF9DF, 0x5433, 0xE7EF, + 0x5438, 0xFDE5, 0x5439, 0xF6A3, 0x543B, 0xD9FC, 0x543C, 0xFDA9, + 0x543E, 0xE7EE, 0x5442, 0xD5E5, 0x5448, 0xEFD0, 0x544A, 0xCDB1, + 0x5451, 0xF7A2, 0x5468, 0xF1B2, 0x546A, 0xF1B1, 0x5471, 0xCDB2, + 0x5473, 0xDAAB, 0x5475, 0xCAA7, 0x547B, 0xE3E2, 0x547C, 0xFBBC, + 0x547D, 0xD9A4, 0x5480, 0xEEBA, 0x5486, 0xF8D3, 0x548C, 0xFBFA, + 0x548E, 0xCFA4, 0x5490, 0xDCFB, 0x54A4, 0xF6E3, 0x54A8, 0xEDAA, + 0x54AB, 0xF2A1, 0x54AC, 0xCEE1, 0x54B3, 0xFAA6, 0x54B8, 0xF9E0, + 0x54BD, 0xECD6, 0x54C0, 0xE4EE, 0x54C1, 0xF9A1, 0x54C4, 0xFBEF, + 0x54C8, 0xF9EB, 0x54C9, 0xEEA3, 0x54E1, 0xEAAC, 0x54E5, 0xCAA8, + 0x54E8, 0xF4FA, 0x54ED, 0xCDD6, 0x54EE, 0xFCF6, 0x54F2, 0xF4C9, + 0x54FA, 0xF8D4, 0x5504, 0xF8A6, 0x5506, 0xDECA, 0x5507, 0xF2C6, + 0x550E, 0xD7DA, 0x5510, 0xD3D0, 0x551C, 0xD8C5, 0x552F, 0xEAE6, + 0x5531, 0xF3DD, 0x5535, 0xE4DA, 0x553E, 0xF6E4, 0x5544, 0xF6F2, + 0x5546, 0xDFC2, 0x554F, 0xD9FD, 0x5553, 0xCCF6, 0x5556, 0xD3BA, + 0x555E, 0xE4AF, 0x5563, 0xF9E1, 0x557C, 0xF0A6, 0x5580, 0xCBD3, + 0x5584, 0xE0BC, 0x5586, 0xF4CA, 0x5587, 0xD4FA, 0x5589, 0xFDAA, + 0x558A, 0xF9E2, 0x5598, 0xF4B7, 0x5599, 0xFDC2, 0x559A, 0xFCB0, + 0x559C, 0xFDEC, 0x559D, 0xCAE2, 0x55A7, 0xFDBD, 0x55A9, 0xEAE7, + 0x55AA, 0xDFC3, 0x55AB, 0xD1D2, 0x55AC, 0xCEE2, 0x55AE, 0xD3A4, + 0x55C5, 0xFDAB, 0x55C7, 0xDFE0, 0x55D4, 0xF2C7, 0x55DA, 0xE7F0, + 0x55DC, 0xD0EE, 0x55DF, 0xF3AA, 0x55E3, 0xDECB, 0x55E4, 0xF6B8, + 0x55FD, 0xE1F5, 0x55FE, 0xF1B3, 0x5606, 0xF7A3, 0x5609, 0xCAA9, + 0x5614, 0xCFA5, 0x5617, 0xDFC4, 0x562F, 0xE1B0, 0x5632, 0xF0BF, + 0x5634, 0xF6A4, 0x5636, 0xE3B6, 0x5653, 0xFAC6, 0x5668, 0xD0EF, + 0x566B, 0xFDED, 0x5674, 0xDDC4, 0x5686, 0xFCF7, 0x56A5, 0xE6BF, + 0x56AC, 0xDEAD, 0x56AE, 0xFABF, 0x56B4, 0xE5F1, 0x56BC, 0xEDC4, + 0x56CA, 0xD2A5, 0x56CD, 0xFDEE, 0x56D1, 0xF5B6, 0x56DA, 0xE1F6, + 0x56DB, 0xDECC, 0x56DE, 0xFCDE, 0x56E0, 0xECD7, 0x56F0, 0xCDDD, + 0x56F9, 0xD6B7, 0x56FA, 0xCDB3, 0x5703, 0xF8D5, 0x5704, 0xE5D8, + 0x5708, 0xCFEA, 0x570B, 0xCFD0, 0x570D, 0xEACC, 0x5712, 0xEAAE, + 0x5713, 0xEAAD, 0x5716, 0xD3F1, 0x5718, 0xD3A5, 0x571F, 0xF7CF, + 0x5728, 0xEEA4, 0x572D, 0xD0A4, 0x5730, 0xF2A2, 0x573B, 0xD0F0, + 0x5740, 0xF2A3, 0x5742, 0xF7F8, 0x5747, 0xD0B3, 0x574A, 0xDBA9, + 0x574D, 0xD3BB, 0x574E, 0xCAEC, 0x5750, 0xF1A6, 0x5751, 0xCBD5, + 0x5761, 0xF7E7, 0x5764, 0xCDDE, 0x5766, 0xF7A4, 0x576A, 0xF8C0, + 0x576E, 0xD3DD, 0x5770, 0xCCD0, 0x5775, 0xCFA6, 0x577C, 0xF6F3, + 0x5782, 0xE1F7, 0x5788, 0xD3DC, 0x578B, 0xFAFE, 0x5793, 0xFAA7, + 0x57A0, 0xEBD9, 0x57A2, 0xCFA7, 0x57A3, 0xEAAF, 0x57C3, 0xE4EF, + 0x57C7, 0xE9B9, 0x57C8, 0xF1D8, 0x57CB, 0xD8D8, 0x57CE, 0xE0F2, + 0x57DF, 0xE6B4, 0x57E0, 0xDCFC, 0x57F0, 0xF3F1, 0x57F4, 0xE3D0, + 0x57F7, 0xF2FB, 0x57F9, 0xDBC6, 0x57FA, 0xD0F1, 0x57FC, 0xD0F2, + 0x5800, 0xCFDC, 0x5802, 0xD3D1, 0x5805, 0xCCB1, 0x5806, 0xF7D8, + 0x5808, 0xCBA8, 0x5809, 0xEBBC, 0x580A, 0xE4BE, 0x581E, 0xF4DC, + 0x5821, 0xDCC2, 0x5824, 0xF0A7, 0x5827, 0xE6C0, 0x582A, 0xCAED, + 0x582F, 0xE8EB, 0x5830, 0xE5E8, 0x5831, 0xDCC3, 0x5834, 0xEDDE, + 0x5835, 0xD3F2, 0x583A, 0xCCF7, 0x584A, 0xCED4, 0x584B, 0xE7AB, + 0x584F, 0xCBC3, 0x5851, 0xE1B1, 0x5854, 0xF7B2, 0x5857, 0xD3F3, + 0x5858, 0xD3D2, 0x585A, 0xF5C0, 0x585E, 0xDFDD, 0x5861, 0xEEF3, + 0x5862, 0xE7F1, 0x5864, 0xFDB4, 0x5875, 0xF2C8, 0x5879, 0xF3D2, + 0x587C, 0xEEF4, 0x587E, 0xE2D3, 0x5883, 0xCCD1, 0x5885, 0xDFEA, + 0x5889, 0xE9BA, 0x5893, 0xD9D7, 0x589C, 0xF5CD, 0x589E, 0xF1F2, + 0x589F, 0xFAC7, 0x58A8, 0xD9F8, 0x58A9, 0xD4C2, 0x58AE, 0xF6E5, + 0x58B3, 0xDDC5, 0x58BA, 0xE7F2, 0x58BB, 0xEDDF, 0x58BE, 0xCACB, + 0x58C1, 0xDBFA, 0x58C5, 0xE8B5, 0x58C7, 0xD3A6, 0x58CE, 0xFDB5, + 0x58D1, 0xF9C9, 0x58D3, 0xE4E2, 0x58D5, 0xFBBD, 0x58D8, 0xD7A4, + 0x58D9, 0xCEC5, 0x58DE, 0xCED5, 0x58DF, 0xD6E6, 0x58E4, 0xE5BD, + 0x58EB, 0xDECD, 0x58EC, 0xECF3, 0x58EF, 0xEDE0, 0x58F9, 0xECEC, + 0x58FA, 0xFBBE, 0x58FB, 0xDFEB, 0x58FD, 0xE1F8, 0x590F, 0xF9BE, + 0x5914, 0xD0F3, 0x5915, 0xE0AA, 0x5916, 0xE8E2, 0x5919, 0xE2D4, + 0x591A, 0xD2FD, 0x591C, 0xE5A8, 0x5922, 0xD9D3, 0x5927, 0xD3DE, + 0x5929, 0xF4B8, 0x592A, 0xF7BC, 0x592B, 0xDCFD, 0x592D, 0xE8EC, + 0x592E, 0xE4E7, 0x5931, 0xE3F7, 0x5937, 0xECA8, 0x593E, 0xFAF1, + 0x5944, 0xE5F2, 0x5947, 0xD0F4, 0x5948, 0xD2AF, 0x5949, 0xDCE5, + 0x594E, 0xD0A5, 0x594F, 0xF1B4, 0x5950, 0xFCB1, 0x5951, 0xCCF8, + 0x5954, 0xDDC6, 0x5955, 0xFAD1, 0x5957, 0xF7DF, 0x595A, 0xFAA8, + 0x5960, 0xEEF5, 0x5962, 0xDECE, 0x5967, 0xE7F3, 0x596A, 0xF7AC, + 0x596B, 0xEBC4, 0x596C, 0xEDE1, 0x596D, 0xE0AB, 0x596E, 0xDDC7, + 0x5973, 0xD2B3, 0x5974, 0xD2BF, 0x5978, 0xCACC, 0x597D, 0xFBBF, + 0x5982, 0xE5FD, 0x5983, 0xDDE5, 0x5984, 0xD8CD, 0x598A, 0xECF4, + 0x5993, 0xD0F5, 0x5996, 0xE8ED, 0x5997, 0xD0D2, 0x5999, 0xD9D8, + 0x59A5, 0xF6E6, 0x59A8, 0xDBAA, 0x59AC, 0xF7E0, 0x59B9, 0xD8D9, + 0x59BB, 0xF4A3, 0x59BE, 0xF4DD, 0x59C3, 0xEFD1, 0x59C6, 0xD9B5, + 0x59C9, 0xEDAB, 0x59CB, 0xE3B7, 0x59D0, 0xEEBB, 0x59D1, 0xCDB4, + 0x59D3, 0xE0F3, 0x59D4, 0xEACD, 0x59D9, 0xECF5, 0x59DA, 0xE8EE, + 0x59DC, 0xCBA9, 0x59DD, 0xF1AF, 0x59E6, 0xCACD, 0x59E8, 0xECA9, + 0x59EA, 0xF2EB, 0x59EC, 0xFDEF, 0x59EE, 0xF9F3, 0x59F8, 0xE6C1, + 0x59FB, 0xECD8, 0x59FF, 0xEDAC, 0x5A01, 0xEACE, 0x5A03, 0xE8DF, + 0x5A11, 0xDECF, 0x5A18, 0xD2A6, 0x5A1B, 0xE7F4, 0x5A1C, 0xD1D6, + 0x5A1F, 0xE6C2, 0x5A20, 0xE3E3, 0x5A25, 0xE4B0, 0x5A29, 0xD8B4, + 0x5A36, 0xF6A5, 0x5A3C, 0xF3DE, 0x5A41, 0xD7A5, 0x5A46, 0xF7E8, + 0x5A49, 0xE8C6, 0x5A5A, 0xFBE6, 0x5A62, 0xDDE6, 0x5A66, 0xDCFE, + 0x5A92, 0xD8DA, 0x5A9A, 0xDAAC, 0x5A9B, 0xEAB0, 0x5AA4, 0xE3B8, + 0x5AC1, 0xCAAA, 0x5AC2, 0xE1F9, 0x5AC4, 0xEAB1, 0x5AC9, 0xF2EC, + 0x5ACC, 0xFAEE, 0x5AE1, 0xEED5, 0x5AE6, 0xF9F4, 0x5AE9, 0xD2EC, + 0x5B05, 0xFBFB, 0x5B09, 0xFDF0, 0x5B0B, 0xE0BD, 0x5B0C, 0xCEE3, + 0x5B16, 0xF8C6, 0x5B2A, 0xDEAE, 0x5B40, 0xDFC5, 0x5B43, 0xE5BE, + 0x5B50, 0xEDAD, 0x5B51, 0xFAEA, 0x5B54, 0xCDEE, 0x5B55, 0xEDA6, + 0x5B57, 0xEDAE, 0x5B58, 0xF0ED, 0x5B5A, 0xDDA1, 0x5B5C, 0xEDAF, + 0x5B5D, 0xFCF8, 0x5B5F, 0xD8EB, 0x5B63, 0xCCF9, 0x5B64, 0xCDB5, + 0x5B69, 0xFAA9, 0x5B6B, 0xE1DD, 0x5B70, 0xE2D5, 0x5B71, 0xEDCF, + 0x5B75, 0xDDA2, 0x5B78, 0xF9CA, 0x5B7A, 0xEAE8, 0x5B7C, 0xE5ED, + 0x5B85, 0xD3EB, 0x5B87, 0xE9D4, 0x5B88, 0xE1FA, 0x5B89, 0xE4CC, + 0x5B8B, 0xE1E4, 0x5B8C, 0xE8C7, 0x5B8F, 0xCEDB, 0x5B93, 0xDCD5, + 0x5B95, 0xF7B5, 0x5B96, 0xFCF3, 0x5B97, 0xF0F3, 0x5B98, 0xCEAF, + 0x5B99, 0xF1B5, 0x5B9A, 0xEFD2, 0x5B9B, 0xE8C8, 0x5B9C, 0xEBF1, + 0x5BA2, 0xCBD4, 0x5BA3, 0xE0BE, 0x5BA4, 0xE3F8, 0x5BA5, 0xEAE9, + 0x5BA6, 0xFCB2, 0x5BAC, 0xE0F4, 0x5BAE, 0xCFE0, 0x5BB0, 0xEEA5, + 0x5BB3, 0xFAAA, 0x5BB4, 0xE6C3, 0x5BB5, 0xE1B2, 0x5BB6, 0xCAAB, + 0x5BB8, 0xE3E4, 0x5BB9, 0xE9BB, 0x5BBF, 0xE2D6, 0x5BC0, 0xF3F2, + 0x5BC2, 0xEED6, 0x5BC3, 0xEAB2, 0x5BC4, 0xD0F6, 0x5BC5, 0xECD9, + 0x5BC6, 0xDACB, 0x5BC7, 0xCFA8, 0x5BCC, 0xDDA3, 0x5BD0, 0xD8DB, + 0x5BD2, 0xF9CE, 0x5BD3, 0xE9D5, 0x5BD4, 0xE3D1, 0x5BD7, 0xD2BC, + 0x5BDE, 0xD8AC, 0x5BDF, 0xF3CC, 0x5BE1, 0xCDFB, 0x5BE2, 0xF6D6, + 0x5BE4, 0xE7F5, 0x5BE5, 0xE8EF, 0x5BE6, 0xE3F9, 0x5BE7, 0xD2BB, + 0x5BE8, 0xF3F3, 0x5BE9, 0xE3FB, 0x5BEB, 0xDED0, 0x5BEC, 0xCEB0, + 0x5BEE, 0xD6F7, 0x5BEF, 0xF1D9, 0x5BF5, 0xF5C1, 0x5BF6, 0xDCC4, + 0x5BF8, 0xF5BB, 0x5BFA, 0xDED1, 0x5C01, 0xDCE6, 0x5C04, 0xDED2, + 0x5C07, 0xEDE2, 0x5C08, 0xEEF6, 0x5C09, 0xEACF, 0x5C0A, 0xF0EE, + 0x5C0B, 0xE3FC, 0x5C0D, 0xD3DF, 0x5C0E, 0xD3F4, 0x5C0F, 0xE1B3, + 0x5C11, 0xE1B4, 0x5C16, 0xF4D3, 0x5C19, 0xDFC6, 0x5C24, 0xE9D6, + 0x5C28, 0xDBAB, 0x5C31, 0xF6A6, 0x5C38, 0xE3B9, 0x5C39, 0xEBC5, + 0x5C3A, 0xF4A9, 0x5C3B, 0xCDB6, 0x5C3C, 0xD2F9, 0x5C3E, 0xDAAD, + 0x5C3F, 0xD2E3, 0x5C40, 0xCFD1, 0x5C45, 0xCBDC, 0x5C46, 0xCCFA, + 0x5C48, 0xCFDD, 0x5C4B, 0xE8A9, 0x5C4D, 0xE3BB, 0x5C4E, 0xE3BA, + 0x5C51, 0xE0DA, 0x5C55, 0xEEF7, 0x5C5B, 0xDCB3, 0x5C60, 0xD3F5, + 0x5C62, 0xD7A6, 0x5C64, 0xF6B5, 0x5C65, 0xD7DB, 0x5C6C, 0xE1D5, + 0x5C6F, 0xD4EA, 0x5C71, 0xDFA3, 0x5C79, 0xFDDF, 0x5C90, 0xD0F7, + 0x5C91, 0xEDD4, 0x5CA1, 0xCBAA, 0x5CA9, 0xE4DB, 0x5CAB, 0xE1FB, + 0x5CAC, 0xCBA2, 0x5CB1, 0xD3E0, 0x5CB3, 0xE4BF, 0x5CB5, 0xFBC0, + 0x5CB7, 0xDABE, 0x5CB8, 0xE4CD, 0x5CBA, 0xD6B9, 0x5CBE, 0xEFC0, + 0x5CC0, 0xE1FC, 0x5CD9, 0xF6B9, 0x5CE0, 0xDFC7, 0x5CE8, 0xE4B1, + 0x5CEF, 0xDCE7, 0x5CF0, 0xDCE8, 0x5CF4, 0xFAD6, 0x5CF6, 0xD3F6, + 0x5CFB, 0xF1DA, 0x5CFD, 0xFAF2, 0x5D07, 0xE2FD, 0x5D0D, 0xD5CF, + 0x5D0E, 0xD0F8, 0x5D11, 0xCDDF, 0x5D14, 0xF5CB, 0x5D16, 0xE4F0, + 0x5D17, 0xCBAB, 0x5D19, 0xD7C4, 0x5D27, 0xE2FE, 0x5D29, 0xDDDA, + 0x5D4B, 0xDAAE, 0x5D4C, 0xCAEE, 0x5D50, 0xD5B9, 0x5D69, 0xE3A1, + 0x5D6C, 0xE8E3, 0x5D6F, 0xF3AB, 0x5D87, 0xCFA9, 0x5D8B, 0xD3F7, + 0x5D9D, 0xD4F1, 0x5DA0, 0xCEE4, 0x5DA2, 0xE8F2, 0x5DAA, 0xE5F5, + 0x5DB8, 0xE7AE, 0x5DBA, 0xD6BA, 0x5DBC, 0xDFEC, 0x5DBD, 0xE4C0, + 0x5DCD, 0xE8E4, 0x5DD2, 0xD8B5, 0x5DD6, 0xE4DC, 0x5DDD, 0xF4B9, + 0x5DDE, 0xF1B6, 0x5DE1, 0xE2DE, 0x5DE2, 0xE1B5, 0x5DE5, 0xCDEF, + 0x5DE6, 0xF1A7, 0x5DE7, 0xCEE5, 0x5DE8, 0xCBDD, 0x5DEB, 0xD9E3, + 0x5DEE, 0xF3AC, 0x5DF1, 0xD0F9, 0x5DF2, 0xECAB, 0x5DF3, 0xDED3, + 0x5DF4, 0xF7E9, 0x5DF7, 0xF9F5, 0x5DFD, 0xE1DE, 0x5DFE, 0xCBEE, + 0x5E02, 0xE3BC, 0x5E03, 0xF8D6, 0x5E06, 0xDBEE, 0x5E0C, 0xFDF1, + 0x5E11, 0xF7B6, 0x5E16, 0xF4DE, 0x5E19, 0xF2ED, 0x5E1B, 0xDBD9, + 0x5E1D, 0xF0A8, 0x5E25, 0xE1FD, 0x5E2B, 0xDED4, 0x5E2D, 0xE0AC, + 0x5E33, 0xEDE3, 0x5E36, 0xD3E1, 0x5E38, 0xDFC8, 0x5E3D, 0xD9B6, + 0x5E3F, 0xFDAC, 0x5E40, 0xEFD3, 0x5E44, 0xE4C1, 0x5E45, 0xF8EB, + 0x5E47, 0xDBAC, 0x5E4C, 0xFCC6, 0x5E55, 0xD8AD, 0x5E5F, 0xF6BA, + 0x5E61, 0xDBDF, 0x5E62, 0xD3D3, 0x5E63, 0xF8C7, 0x5E72, 0xCACE, + 0x5E73, 0xF8C1, 0x5E74, 0xD2B4, 0x5E77, 0xDCB4, 0x5E78, 0xFAB9, + 0x5E79, 0xCACF, 0x5E7B, 0xFCB3, 0x5E7C, 0xEAEA, 0x5E7D, 0xEAEB, + 0x5E7E, 0xD0FA, 0x5E84, 0xEDE4, 0x5E87, 0xDDE7, 0x5E8A, 0xDFC9, + 0x5E8F, 0xDFED, 0x5E95, 0xEEBC, 0x5E97, 0xEFC1, 0x5E9A, 0xCCD2, + 0x5E9C, 0xDDA4, 0x5EA0, 0xDFCA, 0x5EA6, 0xD3F8, 0x5EA7, 0xF1A8, + 0x5EAB, 0xCDB7, 0x5EAD, 0xEFD4, 0x5EB5, 0xE4DD, 0x5EB6, 0xDFEE, + 0x5EB7, 0xCBAC, 0x5EB8, 0xE9BC, 0x5EBE, 0xEAEC, 0x5EC2, 0xDFCB, + 0x5EC8, 0xF9BF, 0x5EC9, 0xD6AF, 0x5ECA, 0xD5C6, 0x5ED0, 0xCFAA, + 0x5ED3, 0xCEA9, 0x5ED6, 0xD6F8, 0x5EDA, 0xF1B7, 0x5EDB, 0xEEF8, + 0x5EDF, 0xD9D9, 0x5EE0, 0xF3DF, 0x5EE2, 0xF8C8, 0x5EE3, 0xCEC6, + 0x5EEC, 0xD5E6, 0x5EF3, 0xF4E6, 0x5EF6, 0xE6C5, 0x5EF7, 0xEFD5, + 0x5EFA, 0xCBEF, 0x5EFB, 0xFCDF, 0x5F01, 0xDCA7, 0x5F04, 0xD6E7, + 0x5F0A, 0xF8C9, 0x5F0F, 0xE3D2, 0x5F11, 0xE3BD, 0x5F13, 0xCFE1, + 0x5F14, 0xF0C0, 0x5F15, 0xECDA, 0x5F17, 0xDDD7, 0x5F18, 0xFBF0, + 0x5F1B, 0xECAC, 0x5F1F, 0xF0A9, 0x5F26, 0xFAD7, 0x5F27, 0xFBC1, + 0x5F29, 0xD2C0, 0x5F31, 0xE5B0, 0x5F35, 0xEDE5, 0x5F3A, 0xCBAD, + 0x5F3C, 0xF9B0, 0x5F48, 0xF7A5, 0x5F4A, 0xCBAE, 0x5F4C, 0xDAAF, + 0x5F4E, 0xD8B6, 0x5F56, 0xD3A7, 0x5F57, 0xFBB2, 0x5F59, 0xFDC4, + 0x5F5B, 0xECAD, 0x5F62, 0xFBA1, 0x5F66, 0xE5E9, 0x5F67, 0xE9EE, + 0x5F69, 0xF3F4, 0x5F6A, 0xF8F3, 0x5F6B, 0xF0C1, 0x5F6C, 0xDEAF, + 0x5F6D, 0xF8B0, 0x5F70, 0xF3E0, 0x5F71, 0xE7AF, 0x5F77, 0xDBAD, + 0x5F79, 0xE6B5, 0x5F7C, 0xF9A8, 0x5F7F, 0xDDD8, 0x5F80, 0xE8D9, + 0x5F81, 0xEFD6, 0x5F85, 0xD3E2, 0x5F87, 0xE2DF, 0x5F8A, 0xFCE0, + 0x5F8B, 0xD7C8, 0x5F8C, 0xFDAD, 0x5F90, 0xDFEF, 0x5F91, 0xCCD3, + 0x5F92, 0xD3F9, 0x5F97, 0xD4F0, 0x5F98, 0xDBC7, 0x5F99, 0xDED5, + 0x5F9E, 0xF0F4, 0x5FA0, 0xD5D0, 0x5FA1, 0xE5D9, 0x5FA8, 0xFCC7, + 0x5FA9, 0xDCD6, 0x5FAA, 0xE2E0, 0x5FAE, 0xDAB0, 0x5FB5, 0xF3A3, + 0x5FB7, 0xD3EC, 0x5FB9, 0xF4CB, 0x5FBD, 0xFDC5, 0x5FC3, 0xE3FD, + 0x5FC5, 0xF9B1, 0x5FCC, 0xD0FB, 0x5FCD, 0xECDB, 0x5FD6, 0xF5BC, + 0x5FD7, 0xF2A4, 0x5FD8, 0xD8CE, 0x5FD9, 0xD8CF, 0x5FE0, 0xF5F7, + 0x5FEB, 0xF6E1, 0x5FF5, 0xD2B7, 0x5FFD, 0xFBEC, 0x5FFF, 0xDDC8, + 0x600F, 0xE4E8, 0x6012, 0xD2C1, 0x6016, 0xF8D7, 0x601C, 0xD6BB, + 0x601D, 0xDED6, 0x6020, 0xF7BD, 0x6021, 0xECAE, 0x6025, 0xD0E1, + 0x6027, 0xE0F5, 0x6028, 0xEAB3, 0x602A, 0xCED6, 0x602F, 0xCCA5, + 0x6041, 0xECF6, 0x6042, 0xE2E1, 0x6043, 0xE3BE, 0x604D, 0xFCC8, + 0x6050, 0xCDF0, 0x6052, 0xF9F6, 0x6055, 0xDFF0, 0x6059, 0xE5BF, + 0x605D, 0xCEBF, 0x6062, 0xFCE1, 0x6063, 0xEDB0, 0x6064, 0xFDD1, + 0x6065, 0xF6BB, 0x6068, 0xF9CF, 0x6069, 0xEBDA, 0x606A, 0xCAC1, + 0x606C, 0xD2B8, 0x606D, 0xCDF1, 0x606F, 0xE3D3, 0x6070, 0xFDE6, + 0x6085, 0xE6ED, 0x6089, 0xE3FA, 0x608C, 0xF0AA, 0x608D, 0xF9D0, + 0x6094, 0xFCE2, 0x6096, 0xF8A7, 0x609A, 0xE1E5, 0x609B, 0xEEF9, + 0x609F, 0xE7F6, 0x60A0, 0xEAED, 0x60A3, 0xFCB4, 0x60A4, 0xF5C2, + 0x60A7, 0xD7DC, 0x60B0, 0xF0F5, 0x60B2, 0xDDE8, 0x60B3, 0xD3ED, + 0x60B4, 0xF5FC, 0x60B6, 0xDABF, 0x60B8, 0xCCFB, 0x60BC, 0xD3FA, + 0x60BD, 0xF4A4, 0x60C5, 0xEFD7, 0x60C7, 0xD4C3, 0x60D1, 0xFBE3, + 0x60DA, 0xFBED, 0x60DC, 0xE0AD, 0x60DF, 0xEAEE, 0x60E0, 0xFBB3, + 0x60E1, 0xE4C2, 0x60F0, 0xF6E7, 0x60F1, 0xD2DD, 0x60F3, 0xDFCC, + 0x60F6, 0xFCC9, 0x60F9, 0xE5A9, 0x60FA, 0xE0F6, 0x60FB, 0xF6B3, + 0x6101, 0xE1FE, 0x6106, 0xCBF0, 0x6108, 0xEAEF, 0x6109, 0xEAF0, + 0x610D, 0xDAC0, 0x610E, 0xF8B4, 0x610F, 0xEBF2, 0x6115, 0xE4C3, + 0x611A, 0xE9D7, 0x611B, 0xE4F1, 0x611F, 0xCAEF, 0x6127, 0xCED7, + 0x6130, 0xFCCA, 0x6134, 0xF3E1, 0x6137, 0xCBC4, 0x613C, 0xE3E5, + 0x613E, 0xCBC5, 0x613F, 0xEAB4, 0x6142, 0xE9BD, 0x6144, 0xD7C9, + 0x6147, 0xEBDB, 0x6148, 0xEDB1, 0x614A, 0xCCC3, 0x614B, 0xF7BE, + 0x614C, 0xFCCB, 0x6153, 0xF8F4, 0x6155, 0xD9B7, 0x6158, 0xF3D3, + 0x6159, 0xF3D4, 0x615D, 0xF7E4, 0x615F, 0xF7D1, 0x6162, 0xD8B7, + 0x6163, 0xCEB1, 0x6164, 0xCAC2, 0x6167, 0xFBB4, 0x6168, 0xCBC6, + 0x616B, 0xF0F6, 0x616E, 0xD5E7, 0x6170, 0xEAD0, 0x6176, 0xCCD4, + 0x6177, 0xCBAF, 0x617D, 0xF4AA, 0x617E, 0xE9AF, 0x6181, 0xF5C3, + 0x6182, 0xE9D8, 0x618A, 0xDDE9, 0x618E, 0xF1F3, 0x6190, 0xD5FB, + 0x6191, 0xDEBB, 0x6194, 0xF4FB, 0x6198, 0xFDF3, 0x6199, 0xFDF2, + 0x619A, 0xF7A6, 0x61A4, 0xDDC9, 0x61A7, 0xD4D3, 0x61A9, 0xCCA8, + 0x61AB, 0xDAC1, 0x61AC, 0xCCD5, 0x61AE, 0xD9E4, 0x61B2, 0xFACA, + 0x61B6, 0xE5E3, 0x61BA, 0xD3BC, 0x61BE, 0xCAF0, 0x61C3, 0xD0C4, + 0x61C7, 0xCAD0, 0x61C8, 0xFAAB, 0x61C9, 0xEBEB, 0x61CA, 0xE7F8, + 0x61CB, 0xD9E5, 0x61E6, 0xD1D7, 0x61F2, 0xF3A4, 0x61F6, 0xD4FB, + 0x61F7, 0xFCE3, 0x61F8, 0xFAD8, 0x61FA, 0xF3D5, 0x61FC, 0xCFAB, + 0x61FF, 0xEBF3, 0x6200, 0xD5FC, 0x6207, 0xD3D4, 0x6208, 0xCDFC, + 0x620A, 0xD9E6, 0x620C, 0xE2F9, 0x620D, 0xE2A1, 0x620E, 0xEBD4, + 0x6210, 0xE0F7, 0x6211, 0xE4B2, 0x6212, 0xCCFC, 0x6216, 0xFBE4, + 0x621A, 0xF4AB, 0x621F, 0xD0BD, 0x6221, 0xCAF1, 0x622A, 0xEFB8, + 0x622E, 0xD7C0, 0x6230, 0xEEFA, 0x6231, 0xFDF4, 0x6234, 0xD3E3, + 0x6236, 0xFBC2, 0x623E, 0xD5E8, 0x623F, 0xDBAE, 0x6240, 0xE1B6, + 0x6241, 0xF8B7, 0x6247, 0xE0BF, 0x6248, 0xFBC3, 0x6249, 0xDDEA, + 0x624B, 0xE2A2, 0x624D, 0xEEA6, 0x6253, 0xF6E8, 0x6258, 0xF6F5, + 0x626E, 0xDDCA, 0x6271, 0xD0E2, 0x6276, 0xDDA6, 0x6279, 0xDDEB, + 0x627C, 0xE4F9, 0x627F, 0xE3AF, 0x6280, 0xD0FC, 0x6284, 0xF4FC, + 0x6289, 0xCCBC, 0x628A, 0xF7EA, 0x6291, 0xE5E4, 0x6292, 0xDFF1, + 0x6295, 0xF7E1, 0x6297, 0xF9F7, 0x6298, 0xEFB9, 0x629B, 0xF8D8, + 0x62AB, 0xF9A9, 0x62B1, 0xF8D9, 0x62B5, 0xEEBD, 0x62B9, 0xD8C6, + 0x62BC, 0xE4E3, 0x62BD, 0xF5CE, 0x62C2, 0xDDD9, 0x62C7, 0xD9E7, + 0x62C8, 0xD2B9, 0x62C9, 0xD5C3, 0x62CC, 0xDAE5, 0x62CD, 0xDAD0, + 0x62CF, 0xD1D9, 0x62D0, 0xCED8, 0x62D2, 0xCBDE, 0x62D3, 0xF4AC, + 0x62D4, 0xDAFB, 0x62D6, 0xF6E9, 0x62D7, 0xE8F3, 0x62D8, 0xCFAC, + 0x62D9, 0xF0F0, 0x62DB, 0xF4FD, 0x62DC, 0xDBC8, 0x62EC, 0xCEC0, + 0x62ED, 0xE3D4, 0x62EE, 0xD1CF, 0x62EF, 0xF1F5, 0x62F1, 0xCDF2, + 0x62F3, 0xCFEB, 0x62F7, 0xCDB8, 0x62FE, 0xE3A6, 0x62FF, 0xD1DA, + 0x6301, 0xF2A5, 0x6307, 0xF2A6, 0x6309, 0xE4CE, 0x6311, 0xD3FB, + 0x632B, 0xF1A9, 0x632F, 0xF2C9, 0x633A, 0xEFD8, 0x633B, 0xE6C9, + 0x633D, 0xD8B8, 0x633E, 0xFAF3, 0x6349, 0xF3B5, 0x634C, 0xF8A4, + 0x634F, 0xD1F3, 0x6350, 0xE6C8, 0x6355, 0xF8DA, 0x6367, 0xDCE9, + 0x6368, 0xDED7, 0x636E, 0xCBDF, 0x6372, 0xCFEC, 0x6377, 0xF4DF, + 0x637A, 0xD1F4, 0x637B, 0xD2BA, 0x637F, 0xDFF2, 0x6383, 0xE1B7, + 0x6388, 0xE2A3, 0x6389, 0xD3FC, 0x638C, 0xEDE6, 0x6392, 0xDBC9, + 0x6396, 0xE4FA, 0x6398, 0xCFDE, 0x639B, 0xCED0, 0x63A0, 0xD5D3, + 0x63A1, 0xF3F5, 0x63A2, 0xF7AE, 0x63A5, 0xEFC8, 0x63A7, 0xCDF3, + 0x63A8, 0xF5CF, 0x63A9, 0xE5F3, 0x63AA, 0xF0C2, 0x63C0, 0xCAD1, + 0x63C4, 0xEAF1, 0x63C6, 0xD0A6, 0x63CF, 0xD9DA, 0x63D0, 0xF0AB, + 0x63D6, 0xEBE7, 0x63DA, 0xE5C0, 0x63DB, 0xFCB5, 0x63E1, 0xE4C4, + 0x63ED, 0xCCA9, 0x63EE, 0xFDC6, 0x63F4, 0xEAB5, 0x63F6, 0xE5AA, + 0x63F7, 0xDFBA, 0x640D, 0xE1DF, 0x640F, 0xDAD1, 0x6414, 0xE1B8, + 0x6416, 0xE8F4, 0x6417, 0xD3FD, 0x641C, 0xE2A4, 0x6422, 0xF2CA, + 0x642C, 0xDAE6, 0x642D, 0xF7B3, 0x643A, 0xFDCD, 0x643E, 0xF3B6, + 0x6458, 0xEED7, 0x6460, 0xF5C4, 0x6469, 0xD8A4, 0x646F, 0xF2A7, + 0x6478, 0xD9B8, 0x6479, 0xD9B9, 0x647A, 0xEFC9, 0x6488, 0xD6CE, + 0x6491, 0xF7CB, 0x6492, 0xDFAE, 0x6493, 0xE8F5, 0x649A, 0xD2B5, + 0x649E, 0xD3D5, 0x64A4, 0xF4CC, 0x64A5, 0xDAFC, 0x64AB, 0xD9E8, + 0x64AD, 0xF7EB, 0x64AE, 0xF5C9, 0x64B0, 0xF3BC, 0x64B2, 0xDAD2, + 0x64BB, 0xD3B5, 0x64C1, 0xE8B6, 0x64C4, 0xD6CF, 0x64C5, 0xF4BA, + 0x64C7, 0xF7C9, 0x64CA, 0xCCAA, 0x64CD, 0xF0C3, 0x64CE, 0xCCD6, + 0x64D2, 0xD0D3, 0x64D4, 0xD3BD, 0x64D8, 0xDBFB, 0x64DA, 0xCBE0, + 0x64E1, 0xD3E4, 0x64E2, 0xF6F7, 0x64E5, 0xD5BA, 0x64E6, 0xF3CD, + 0x64E7, 0xCBE1, 0x64EC, 0xEBF4, 0x64F2, 0xF4AD, 0x64F4, 0xFCAA, + 0x64FA, 0xF7EC, 0x64FE, 0xE8F6, 0x6500, 0xDAE7, 0x6504, 0xF7CC, + 0x6518, 0xE5C1, 0x651D, 0xE0EE, 0x6523, 0xD5FD, 0x652A, 0xCEE6, + 0x652B, 0xFCAB, 0x652C, 0xD5BB, 0x652F, 0xF2A8, 0x6536, 0xE2A5, + 0x6537, 0xCDB9, 0x6538, 0xEAF2, 0x6539, 0xCBC7, 0x653B, 0xCDF4, + 0x653E, 0xDBAF, 0x653F, 0xEFD9, 0x6545, 0xCDBA, 0x6548, 0xFCF9, + 0x654D, 0xDFF3, 0x654E, 0xCEE7, 0x654F, 0xDAC2, 0x6551, 0xCFAD, + 0x6556, 0xE7F9, 0x6557, 0xF8A8, 0x655E, 0xF3E2, 0x6562, 0xCAF2, + 0x6563, 0xDFA4, 0x6566, 0xD4C4, 0x656C, 0xCCD7, 0x656D, 0xE5C2, + 0x6572, 0xCDBB, 0x6574, 0xEFDA, 0x6575, 0xEED8, 0x6577, 0xDDA7, + 0x6578, 0xE2A6, 0x657E, 0xE0C0, 0x6582, 0xD6B0, 0x6583, 0xF8CA, + 0x6585, 0xFCFA, 0x6587, 0xD9FE, 0x658C, 0xDEB0, 0x6590, 0xDDEC, + 0x6591, 0xDAE8, 0x6597, 0xD4E0, 0x6599, 0xD6F9, 0x659B, 0xCDD7, + 0x659C, 0xDED8, 0x659F, 0xF2F8, 0x65A1, 0xE4D6, 0x65A4, 0xD0C5, + 0x65A5, 0xF4AE, 0x65A7, 0xDDA8, 0x65AB, 0xEDC5, 0x65AC, 0xF3D6, + 0x65AF, 0xDED9, 0x65B0, 0xE3E6, 0x65B7, 0xD3A8, 0x65B9, 0xDBB0, + 0x65BC, 0xE5DA, 0x65BD, 0xE3BF, 0x65C1, 0xDBB1, 0x65C5, 0xD5E9, + 0x65CB, 0xE0C1, 0x65CC, 0xEFDB, 0x65CF, 0xF0E9, 0x65D2, 0xD7B2, + 0x65D7, 0xD0FD, 0x65E0, 0xD9E9, 0x65E3, 0xD0FE, 0x65E5, 0xECED, + 0x65E6, 0xD3A9, 0x65E8, 0xF2A9, 0x65E9, 0xF0C4, 0x65EC, 0xE2E2, + 0x65ED, 0xE9EF, 0x65F1, 0xF9D1, 0x65F4, 0xE9D9, 0x65FA, 0xE8DA, + 0x65FB, 0xDAC3, 0x65FC, 0xDAC4, 0x65FD, 0xD4C5, 0x65FF, 0xE7FA, + 0x6606, 0xCDE0, 0x6607, 0xE3B0, 0x6609, 0xDBB2, 0x660A, 0xFBC4, + 0x660C, 0xF3E3, 0x660E, 0xD9A5, 0x660F, 0xFBE7, 0x6610, 0xDDCB, + 0x6611, 0xD0D4, 0x6613, 0xE6B6, 0x6614, 0xE0AE, 0x6615, 0xFDDA, + 0x661E, 0xDCB5, 0x661F, 0xE0F8, 0x6620, 0xE7B1, 0x6625, 0xF5F0, + 0x6627, 0xD8DC, 0x6628, 0xEDC6, 0x662D, 0xE1B9, 0x662F, 0xE3C0, + 0x6630, 0xF9C0, 0x6631, 0xE9F0, 0x6634, 0xD9DB, 0x6636, 0xF3E4, + 0x663A, 0xDCB6, 0x663B, 0xE4E9, 0x6641, 0xF0C5, 0x6642, 0xE3C1, + 0x6643, 0xFCCC, 0x6644, 0xFCCD, 0x6649, 0xF2CB, 0x664B, 0xF2CC, + 0x664F, 0xE4CF, 0x6659, 0xF1DB, 0x665B, 0xFAD9, 0x665D, 0xF1B8, + 0x665E, 0xFDF5, 0x665F, 0xE0F9, 0x6664, 0xE7FB, 0x6665, 0xFCB7, + 0x6666, 0xFCE4, 0x6667, 0xFBC5, 0x6668, 0xE3E7, 0x6669, 0xD8B9, + 0x666B, 0xF6F8, 0x666E, 0xDCC5, 0x666F, 0xCCD8, 0x6673, 0xE0AF, + 0x6674, 0xF4E7, 0x6676, 0xEFDC, 0x6677, 0xCFFC, 0x6678, 0xEFDD, + 0x667A, 0xF2AA, 0x6684, 0xFDBE, 0x6687, 0xCAAC, 0x6688, 0xFDBB, + 0x6689, 0xFDC7, 0x668E, 0xE7B2, 0x6690, 0xEAD1, 0x6691, 0xDFF4, + 0x6696, 0xD1EC, 0x6697, 0xE4DE, 0x6698, 0xE5C3, 0x669D, 0xD9A6, + 0x66A0, 0xCDBC, 0x66A2, 0xF3E5, 0x66AB, 0xEDD5, 0x66AE, 0xD9BA, + 0x66B2, 0xEDE7, 0x66B3, 0xFBB5, 0x66B4, 0xF8EC, 0x66B9, 0xE0E7, + 0x66BB, 0xCCD9, 0x66BE, 0xD4C6, 0x66C4, 0xE7A5, 0x66C6, 0xD5F5, + 0x66C7, 0xD3BE, 0x66C9, 0xFCFB, 0x66D6, 0xE4F2, 0x66D9, 0xDFF5, + 0x66DC, 0xE8F8, 0x66DD, 0xF8ED, 0x66E0, 0xCEC7, 0x66E6, 0xFDF6, + 0x66F0, 0xE8D8, 0x66F2, 0xCDD8, 0x66F3, 0xE7D6, 0x66F4, 0xCCDA, + 0x66F7, 0xCAE3, 0x66F8, 0xDFF6, 0x66F9, 0xF0C7, 0x66FA, 0xF0C6, + 0x66FC, 0xD8BA, 0x66FE, 0xF1F4, 0x66FF, 0xF4F0, 0x6700, 0xF5CC, + 0x6703, 0xFCE5, 0x6708, 0xEAC5, 0x6709, 0xEAF3, 0x670B, 0xDDDB, + 0x670D, 0xDCD7, 0x6714, 0xDEFD, 0x6715, 0xF2F9, 0x6717, 0xD5C7, + 0x671B, 0xD8D0, 0x671D, 0xF0C8, 0x671E, 0xD1A1, 0x671F, 0xD1A2, + 0x6726, 0xD9D4, 0x6727, 0xD6E8, 0x6728, 0xD9CA, 0x672A, 0xDAB1, + 0x672B, 0xD8C7, 0x672C, 0xDCE2, 0x672D, 0xF3CE, 0x672E, 0xF5F4, + 0x6731, 0xF1B9, 0x6734, 0xDAD3, 0x6736, 0xF6EA, 0x673A, 0xCFF5, + 0x673D, 0xFDAE, 0x6746, 0xCAD2, 0x6749, 0xDFB4, 0x674E, 0xD7DD, + 0x674F, 0xFABA, 0x6750, 0xEEA7, 0x6751, 0xF5BD, 0x6753, 0xF8F5, + 0x6756, 0xEDE8, 0x675C, 0xD4E1, 0x675E, 0xD1A3, 0x675F, 0xE1D6, + 0x676D, 0xF9F8, 0x676F, 0xDBCA, 0x6770, 0xCBF9, 0x6771, 0xD4D4, + 0x6773, 0xD9DC, 0x6775, 0xEEBE, 0x6777, 0xF7ED, 0x677B, 0xD2EE, + 0x677E, 0xE1E6, 0x677F, 0xF7F9, 0x6787, 0xDDED, 0x6789, 0xE8DB, + 0x678B, 0xDBB3, 0x678F, 0xD1F7, 0x6790, 0xE0B0, 0x6793, 0xD4E2, + 0x6795, 0xF6D7, 0x6797, 0xD7F9, 0x679A, 0xD8DD, 0x679C, 0xCDFD, + 0x679D, 0xF2AB, 0x67AF, 0xCDBD, 0x67B0, 0xF8C2, 0x67B3, 0xF2AC, + 0x67B6, 0xCAAD, 0x67B7, 0xCAAE, 0x67B8, 0xCFAE, 0x67BE, 0xE3C2, + 0x67C4, 0xDCB7, 0x67CF, 0xDBDA, 0x67D0, 0xD9BB, 0x67D1, 0xCAF3, + 0x67D2, 0xF6D3, 0x67D3, 0xE6F8, 0x67D4, 0xEAF5, 0x67DA, 0xEAF6, + 0x67DD, 0xF6F9, 0x67E9, 0xCFAF, 0x67EC, 0xCAD3, 0x67EF, 0xCAAF, + 0x67F0, 0xD2B0, 0x67F1, 0xF1BA, 0x67F3, 0xD7B3, 0x67F4, 0xE3C3, + 0x67F5, 0xF3FD, 0x67F6, 0xDEDA, 0x67FB, 0xDEDB, 0x67FE, 0xEFDE, + 0x6812, 0xE2E3, 0x6813, 0xEEFB, 0x6816, 0xDFF7, 0x6817, 0xD7CA, + 0x6821, 0xCEE8, 0x6822, 0xDBDB, 0x682A, 0xF1BB, 0x682F, 0xE9F1, + 0x6838, 0xFAB7, 0x6839, 0xD0C6, 0x683C, 0xCCAB, 0x683D, 0xEEA8, + 0x6840, 0xCBFA, 0x6841, 0xF9F9, 0x6842, 0xCCFD, 0x6843, 0xD3FE, + 0x6848, 0xE4D0, 0x684E, 0xF2EE, 0x6850, 0xD4D5, 0x6851, 0xDFCD, + 0x6853, 0xFCB8, 0x6854, 0xD1D0, 0x686D, 0xF2CD, 0x6876, 0xF7D2, + 0x687F, 0xCAD4, 0x6881, 0xD5D9, 0x6885, 0xD8DE, 0x688F, 0xCDD9, + 0x6893, 0xEEA9, 0x6894, 0xF6BC, 0x6897, 0xCCDB, 0x689D, 0xF0C9, + 0x689F, 0xFCFC, 0x68A1, 0xE8C9, 0x68A2, 0xF4FE, 0x68A7, 0xE7FC, + 0x68A8, 0xD7DE, 0x68AD, 0xDEDC, 0x68AF, 0xF0AC, 0x68B0, 0xCCFE, + 0x68B1, 0xCDE1, 0x68B3, 0xE1BA, 0x68B5, 0xDBEF, 0x68B6, 0xDAB2, + 0x68C4, 0xD1A5, 0x68C5, 0xDCB8, 0x68C9, 0xD8F6, 0x68CB, 0xD1A4, + 0x68CD, 0xCDE2, 0x68D2, 0xDCEA, 0x68D5, 0xF0F7, 0x68D7, 0xF0CA, + 0x68D8, 0xD0BE, 0x68DA, 0xDDDC, 0x68DF, 0xD4D6, 0x68E0, 0xD3D6, + 0x68E7, 0xEDD0, 0x68E8, 0xCDA1, 0x68EE, 0xDFB5, 0x68F2, 0xDFF8, + 0x68F9, 0xD4A1, 0x68FA, 0xCEB2, 0x6900, 0xE8CA, 0x6905, 0xEBF5, + 0x690D, 0xE3D5, 0x690E, 0xF5D0, 0x6912, 0xF5A1, 0x6927, 0xD9A7, + 0x6930, 0xE5AB, 0x693D, 0xE6CB, 0x693F, 0xF5F1, 0x694A, 0xE5C5, + 0x6953, 0xF9A3, 0x6954, 0xE0DB, 0x6955, 0xF6EB, 0x6957, 0xCBF1, + 0x6959, 0xD9EA, 0x695A, 0xF5A2, 0x695E, 0xD7D1, 0x6960, 0xD1F8, + 0x6961, 0xEAF8, 0x6962, 0xEAF9, 0x6963, 0xDAB3, 0x6968, 0xEFDF, + 0x696B, 0xF1EF, 0x696D, 0xE5F6, 0x696E, 0xEEBF, 0x696F, 0xE2E4, + 0x6975, 0xD0BF, 0x6977, 0xFAAC, 0x6978, 0xF5D1, 0x6979, 0xE7B3, + 0x6995, 0xE9BE, 0x699B, 0xF2CE, 0x699C, 0xDBB4, 0x69A5, 0xFCCE, + 0x69A7, 0xDDEE, 0x69AE, 0xE7B4, 0x69B4, 0xD7B4, 0x69BB, 0xF7B4, + 0x69C1, 0xCDBE, 0x69C3, 0xDAE9, 0x69CB, 0xCFB0, 0x69CC, 0xF7D9, + 0x69CD, 0xF3E6, 0x69D0, 0xCED9, 0x69E8, 0xCEAA, 0x69EA, 0xCBC8, + 0x69FB, 0xD0A7, 0x69FD, 0xF0CB, 0x69FF, 0xD0C7, 0x6A02, 0xE4C5, + 0x6A0A, 0xDBE0, 0x6A11, 0xD5DA, 0x6A13, 0xD7A7, 0x6A17, 0xEEC0, + 0x6A19, 0xF8F6, 0x6A1E, 0xF5D2, 0x6A1F, 0xEDE9, 0x6A21, 0xD9BC, + 0x6A23, 0xE5C6, 0x6A35, 0xF5A3, 0x6A38, 0xDAD4, 0x6A39, 0xE2A7, + 0x6A3A, 0xFBFC, 0x6A3D, 0xF1DC, 0x6A44, 0xCAF4, 0x6A48, 0xE8FA, + 0x6A4B, 0xCEE9, 0x6A52, 0xE9F8, 0x6A53, 0xE2E5, 0x6A58, 0xD0B9, + 0x6A59, 0xD4F2, 0x6A5F, 0xD1A6, 0x6A61, 0xDFCE, 0x6A6B, 0xFCF4, + 0x6A80, 0xD3AA, 0x6A84, 0xCCAC, 0x6A89, 0xEFE0, 0x6A8D, 0xE5E5, + 0x6A8E, 0xD0D5, 0x6A97, 0xDBFC, 0x6A9C, 0xFCE6, 0x6AA2, 0xCBFE, + 0x6AA3, 0xEDEA, 0x6AB3, 0xDEB1, 0x6ABB, 0xF9E3, 0x6AC2, 0xD4A2, + 0x6AC3, 0xCFF6, 0x6AD3, 0xD6D0, 0x6ADA, 0xD5EA, 0x6ADB, 0xF1EE, + 0x6AF6, 0xFACB, 0x6AFB, 0xE5A1, 0x6B04, 0xD5B1, 0x6B0A, 0xCFED, + 0x6B0C, 0xEDEB, 0x6B12, 0xD5B2, 0x6B16, 0xD5BC, 0x6B20, 0xFDE2, + 0x6B21, 0xF3AD, 0x6B23, 0xFDDB, 0x6B32, 0xE9B0, 0x6B3A, 0xD1A7, + 0x6B3D, 0xFDE3, 0x6B3E, 0xCEB3, 0x6B46, 0xFDE4, 0x6B47, 0xFACE, + 0x6B4C, 0xCAB0, 0x6B4E, 0xF7A7, 0x6B50, 0xCFB1, 0x6B5F, 0xE6A2, + 0x6B61, 0xFCB6, 0x6B62, 0xF2AD, 0x6B63, 0xEFE1, 0x6B64, 0xF3AE, + 0x6B65, 0xDCC6, 0x6B66, 0xD9EB, 0x6B6A, 0xE8E0, 0x6B72, 0xE1A8, + 0x6B77, 0xD5F6, 0x6B78, 0xCFFD, 0x6B7B, 0xDEDD, 0x6B7F, 0xD9D1, + 0x6B83, 0xE4EA, 0x6B84, 0xF2CF, 0x6B86, 0xF7BF, 0x6B89, 0xE2E6, + 0x6B8A, 0xE2A8, 0x6B96, 0xE3D6, 0x6B98, 0xEDD1, 0x6B9E, 0xE9F9, + 0x6BAE, 0xD6B1, 0x6BAF, 0xDEB2, 0x6BB2, 0xE0E8, 0x6BB5, 0xD3AB, + 0x6BB7, 0xEBDC, 0x6BBA, 0xDFAF, 0x6BBC, 0xCAC3, 0x6BBF, 0xEEFC, + 0x6BC1, 0xFDC3, 0x6BC5, 0xEBF6, 0x6BC6, 0xCFB2, 0x6BCB, 0xD9EC, + 0x6BCD, 0xD9BD, 0x6BCF, 0xD8DF, 0x6BD2, 0xD4B8, 0x6BD3, 0xEBBE, + 0x6BD4, 0xDDEF, 0x6BD6, 0xDDF0, 0x6BD7, 0xDDF1, 0x6BD8, 0xDDF2, + 0x6BDB, 0xD9BE, 0x6BEB, 0xFBC6, 0x6BEC, 0xCFB3, 0x6C08, 0xEEFD, + 0x6C0F, 0xE4AB, 0x6C11, 0xDAC5, 0x6C13, 0xD8EC, 0x6C23, 0xD1A8, + 0x6C34, 0xE2A9, 0x6C37, 0xDEBC, 0x6C38, 0xE7B5, 0x6C3E, 0xDBF0, + 0x6C40, 0xEFE2, 0x6C41, 0xF1F0, 0x6C42, 0xCFB4, 0x6C4E, 0xDBF1, + 0x6C50, 0xE0B1, 0x6C55, 0xDFA5, 0x6C57, 0xF9D2, 0x6C5A, 0xE7FD, + 0x6C5D, 0xE6A3, 0x6C5E, 0xFBF1, 0x6C5F, 0xCBB0, 0x6C60, 0xF2AE, + 0x6C68, 0xCDE7, 0x6C6A, 0xE8DC, 0x6C6D, 0xE7D7, 0x6C70, 0xF7C0, + 0x6C72, 0xD0E3, 0x6C76, 0xDAA1, 0x6C7A, 0xCCBD, 0x6C7D, 0xD1A9, + 0x6C7E, 0xDDCC, 0x6C81, 0xE3FE, 0x6C82, 0xD1AA, 0x6C83, 0xE8AA, + 0x6C85, 0xEAB6, 0x6C86, 0xF9FA, 0x6C87, 0xE6CC, 0x6C88, 0xF6D8, + 0x6C8C, 0xD4C7, 0x6C90, 0xD9CB, 0x6C92, 0xD9D2, 0x6C93, 0xD3CB, + 0x6C94, 0xD8F7, 0x6C95, 0xDAA9, 0x6C96, 0xF5F8, 0x6C99, 0xDEDE, + 0x6C9A, 0xF2AF, 0x6C9B, 0xF8A9, 0x6CAB, 0xD8C8, 0x6CAE, 0xEEC1, + 0x6CB3, 0xF9C1, 0x6CB8, 0xDDF3, 0x6CB9, 0xEAFA, 0x6CBB, 0xF6BD, + 0x6CBC, 0xE1BB, 0x6CBD, 0xCDBF, 0x6CBE, 0xF4D4, 0x6CBF, 0xE6CD, + 0x6CC1, 0xFCCF, 0x6CC2, 0xFBA2, 0x6CC4, 0xE0DC, 0x6CC9, 0xF4BB, + 0x6CCA, 0xDAD5, 0x6CCC, 0xF9B2, 0x6CD3, 0xFBF2, 0x6CD5, 0xDBF6, + 0x6CD7, 0xDEDF, 0x6CDB, 0xDBF2, 0x6CE1, 0xF8DC, 0x6CE2, 0xF7EE, + 0x6CE3, 0xEBE8, 0x6CE5, 0xD2FA, 0x6CE8, 0xF1BC, 0x6CEB, 0xFADA, + 0x6CEE, 0xDAEA, 0x6CEF, 0xDAC6, 0x6CF0, 0xF7C1, 0x6CF3, 0xE7B6, + 0x6D0B, 0xE5C7, 0x6D0C, 0xD6AC, 0x6D11, 0xDCC7, 0x6D17, 0xE1A9, + 0x6D19, 0xE2AA, 0x6D1B, 0xD5A6, 0x6D1E, 0xD4D7, 0x6D25, 0xF2D0, + 0x6D27, 0xEAFB, 0x6D29, 0xE0DD, 0x6D2A, 0xFBF3, 0x6D32, 0xF1BD, + 0x6D35, 0xE2E7, 0x6D36, 0xFDD7, 0x6D38, 0xCEC8, 0x6D39, 0xEAB7, + 0x6D3B, 0xFCC0, 0x6D3D, 0xFDE7, 0x6D3E, 0xF7EF, 0x6D41, 0xD7B5, + 0x6D59, 0xEFBA, 0x6D5A, 0xF1DD, 0x6D5C, 0xDEB3, 0x6D63, 0xE8CB, + 0x6D66, 0xF8DD, 0x6D69, 0xFBC7, 0x6D6A, 0xD5C8, 0x6D6C, 0xD7DF, + 0x6D6E, 0xDDA9, 0x6D74, 0xE9B1, 0x6D77, 0xFAAD, 0x6D78, 0xF6D9, + 0x6D79, 0xFAF4, 0x6D7F, 0xF8AA, 0x6D85, 0xE6EE, 0x6D87, 0xCCDC, + 0x6D88, 0xE1BC, 0x6D89, 0xE0EF, 0x6D8C, 0xE9BF, 0x6D8D, 0xFCFD, + 0x6D8E, 0xE6CE, 0x6D91, 0xE1D7, 0x6D93, 0xE6CF, 0x6D95, 0xF4F1, + 0x6DAF, 0xE4F3, 0x6DB2, 0xE4FB, 0x6DB5, 0xF9E4, 0x6DC0, 0xEFE3, + 0x6DC3, 0xCFEE, 0x6DC4, 0xF6BE, 0x6DC5, 0xE0B2, 0x6DC6, 0xFCFE, + 0x6DC7, 0xD1AB, 0x6DCB, 0xD7FA, 0x6DCF, 0xFBC8, 0x6DD1, 0xE2D7, + 0x6DD8, 0xD4A3, 0x6DD9, 0xF0F8, 0x6DDA, 0xD7A8, 0x6DDE, 0xE1E7, + 0x6DE1, 0xD3BF, 0x6DE8, 0xEFE4, 0x6DEA, 0xD7C5, 0x6DEB, 0xEBE2, + 0x6DEE, 0xFCE7, 0x6DF1, 0xE4A2, 0x6DF3, 0xE2E8, 0x6DF5, 0xE6D0, + 0x6DF7, 0xFBE8, 0x6DF8, 0xF4E8, 0x6DF9, 0xE5F4, 0x6DFA, 0xF4BC, + 0x6DFB, 0xF4D5, 0x6E17, 0xDFB6, 0x6E19, 0xFCB9, 0x6E1A, 0xEEC2, + 0x6E1B, 0xCAF5, 0x6E1F, 0xEFE5, 0x6E20, 0xCBE2, 0x6E21, 0xD4A4, + 0x6E23, 0xDEE0, 0x6E24, 0xDAFD, 0x6E25, 0xE4C6, 0x6E26, 0xE8BE, + 0x6E2B, 0xE0DE, 0x6E2C, 0xF6B4, 0x6E2D, 0xEAD2, 0x6E2F, 0xF9FB, + 0x6E32, 0xE0C2, 0x6E34, 0xCAE4, 0x6E36, 0xE7B7, 0x6E38, 0xEAFD, + 0x6E3A, 0xD9DD, 0x6E3C, 0xDAB4, 0x6E3D, 0xEEAA, 0x6E3E, 0xFBE9, + 0x6E43, 0xDBCB, 0x6E44, 0xDAB5, 0x6E4A, 0xF1BE, 0x6E4D, 0xD3AC, + 0x6E56, 0xFBC9, 0x6E58, 0xDFCF, 0x6E5B, 0xD3C0, 0x6E5C, 0xE3D7, + 0x6E5E, 0xEFE6, 0x6E5F, 0xFCD0, 0x6E67, 0xE9C0, 0x6E6B, 0xF5D3, + 0x6E6E, 0xECDC, 0x6E6F, 0xF7B7, 0x6E72, 0xEAB8, 0x6E73, 0xD1F9, + 0x6E7A, 0xDCC8, 0x6E90, 0xEAB9, 0x6E96, 0xF1DE, 0x6E9C, 0xD7B6, + 0x6E9D, 0xCFB5, 0x6E9F, 0xD9A8, 0x6EA2, 0xECEE, 0x6EA5, 0xDDAA, + 0x6EAA, 0xCDA2, 0x6EAB, 0xE8AE, 0x6EAF, 0xE1BD, 0x6EB1, 0xF2D1, + 0x6EB6, 0xE9C1, 0x6EBA, 0xD2FC, 0x6EC2, 0xDBB5, 0x6EC4, 0xF3E7, + 0x6EC5, 0xD8FE, 0x6EC9, 0xFCD1, 0x6ECB, 0xEDB2, 0x6ECC, 0xF4AF, + 0x6ECE, 0xFBA3, 0x6ED1, 0xFCC1, 0x6ED3, 0xEEAB, 0x6ED4, 0xD4A5, + 0x6EEF, 0xF4F2, 0x6EF4, 0xEED9, 0x6EF8, 0xFBCA, 0x6EFE, 0xCDE3, + 0x6EFF, 0xD8BB, 0x6F01, 0xE5DB, 0x6F02, 0xF8F7, 0x6F06, 0xF6D4, + 0x6F0F, 0xD7A9, 0x6F11, 0xCBC9, 0x6F14, 0xE6D1, 0x6F15, 0xF0CC, + 0x6F20, 0xD8AE, 0x6F22, 0xF9D3, 0x6F23, 0xD5FE, 0x6F2B, 0xD8BC, + 0x6F2C, 0xF2B0, 0x6F31, 0xE2AB, 0x6F32, 0xF3E8, 0x6F38, 0xEFC2, + 0x6F3F, 0xEDEC, 0x6F41, 0xE7B8, 0x6F51, 0xDAFE, 0x6F54, 0xCCBE, + 0x6F57, 0xF2FC, 0x6F58, 0xDAEB, 0x6F5A, 0xE2D8, 0x6F5B, 0xEDD6, + 0x6F5E, 0xD6D1, 0x6F5F, 0xE0B3, 0x6F62, 0xFCD2, 0x6F64, 0xEBC8, + 0x6F6D, 0xD3C1, 0x6F6E, 0xF0CD, 0x6F70, 0xCFF7, 0x6F7A, 0xEDD2, + 0x6F7C, 0xD4D8, 0x6F7D, 0xDCC9, 0x6F7E, 0xD7F1, 0x6F81, 0xDFBB, + 0x6F84, 0xF3A5, 0x6F88, 0xF4CD, 0x6F8D, 0xF1BF, 0x6F8E, 0xF8B1, + 0x6F90, 0xE9FA, 0x6F94, 0xFBCB, 0x6F97, 0xCAD5, 0x6FA3, 0xF9D4, + 0x6FA4, 0xF7CA, 0x6FA7, 0xD6C8, 0x6FAE, 0xFCE8, 0x6FAF, 0xF3BD, + 0x6FB1, 0xEEFE, 0x6FB3, 0xE7FE, 0x6FB9, 0xD3C2, 0x6FBE, 0xD3B6, + 0x6FC0, 0xCCAD, 0x6FC1, 0xF6FA, 0x6FC2, 0xD6B2, 0x6FC3, 0xD2D8, + 0x6FCA, 0xE7D8, 0x6FD5, 0xE3A5, 0x6FDA, 0xE7B9, 0x6FDF, 0xF0AD, + 0x6FE0, 0xFBCC, 0x6FE1, 0xEBA1, 0x6FE4, 0xD4A6, 0x6FE9, 0xFBCD, + 0x6FEB, 0xD5BD, 0x6FEC, 0xF1DF, 0x6FEF, 0xF6FB, 0x6FF1, 0xDEB4, + 0x6FFE, 0xD5EB, 0x7001, 0xE5C8, 0x7005, 0xFBA4, 0x7006, 0xD4B9, + 0x7009, 0xDEE1, 0x700B, 0xE4A3, 0x700F, 0xD7B7, 0x7011, 0xF8EE, + 0x7015, 0xDEB5, 0x7018, 0xD6D2, 0x701A, 0xF9D5, 0x701B, 0xE7BA, + 0x701C, 0xEBD5, 0x701D, 0xD5F7, 0x701E, 0xEFE7, 0x701F, 0xE1BE, + 0x7023, 0xFAAE, 0x7027, 0xD6E9, 0x7028, 0xD6EE, 0x702F, 0xE7BB, + 0x7037, 0xECCB, 0x703E, 0xD5B3, 0x704C, 0xCEB4, 0x7050, 0xFBA5, + 0x7051, 0xE1EE, 0x7058, 0xF7A8, 0x705D, 0xFBCE, 0x7063, 0xD8BD, + 0x706B, 0xFBFD, 0x7070, 0xFCE9, 0x7078, 0xCFB6, 0x707C, 0xEDC7, + 0x707D, 0xEEAC, 0x7085, 0xCCDD, 0x708A, 0xF6A7, 0x708E, 0xE6FA, + 0x7092, 0xF5A4, 0x7098, 0xFDDC, 0x7099, 0xEDB3, 0x709A, 0xCEC9, + 0x70A1, 0xEFE8, 0x70A4, 0xE1BF, 0x70AB, 0xFADB, 0x70AC, 0xCBE3, + 0x70AD, 0xF7A9, 0x70AF, 0xFBA6, 0x70B3, 0xDCB9, 0x70B7, 0xF1C0, + 0x70B8, 0xEDC8, 0x70B9, 0xEFC3, 0x70C8, 0xD6AD, 0x70CB, 0xFDCE, + 0x70CF, 0xE8A1, 0x70D8, 0xFBF4, 0x70D9, 0xD5A7, 0x70DD, 0xF1F6, + 0x70DF, 0xE6D3, 0x70F1, 0xCCDE, 0x70F9, 0xF8B2, 0x70FD, 0xDCEB, + 0x7104, 0xFDB6, 0x7109, 0xE5EA, 0x710C, 0xF1E0, 0x7119, 0xDBCC, + 0x711A, 0xDDCD, 0x711E, 0xD4C8, 0x7121, 0xD9ED, 0x7126, 0xF5A5, + 0x7130, 0xE6FB, 0x7136, 0xE6D4, 0x7147, 0xFDC8, 0x7149, 0xD6A1, + 0x714A, 0xFDBF, 0x714C, 0xFCD3, 0x714E, 0xEFA1, 0x7150, 0xE7BC, + 0x7156, 0xD1EE, 0x7159, 0xE6D5, 0x715C, 0xE9F2, 0x715E, 0xDFB0, + 0x7164, 0xD8E0, 0x7165, 0xFCBA, 0x7166, 0xFDAF, 0x7167, 0xF0CE, + 0x7169, 0xDBE1, 0x716C, 0xE5C9, 0x716E, 0xEDB4, 0x717D, 0xE0C3, + 0x7184, 0xE3D8, 0x7189, 0xE9FB, 0x718A, 0xEAA8, 0x718F, 0xFDB7, + 0x7192, 0xFBA7, 0x7194, 0xE9C2, 0x7199, 0xFDF7, 0x719F, 0xE2D9, + 0x71A2, 0xDCEC, 0x71AC, 0xE8A2, 0x71B1, 0xE6F0, 0x71B9, 0xFDF8, + 0x71BA, 0xFDF9, 0x71BE, 0xF6BF, 0x71C1, 0xE7A7, 0x71C3, 0xE6D7, + 0x71C8, 0xD4F3, 0x71C9, 0xD4C9, 0x71CE, 0xD6FA, 0x71D0, 0xD7F2, + 0x71D2, 0xE1C0, 0x71D4, 0xDBE2, 0x71D5, 0xE6D8, 0x71DF, 0xE7BD, + 0x71E5, 0xF0CF, 0x71E6, 0xF3BE, 0x71E7, 0xE2AC, 0x71ED, 0xF5B7, + 0x71EE, 0xE0F0, 0x71FB, 0xFDB8, 0x71FC, 0xE3E8, 0x71FE, 0xD4A7, + 0x71FF, 0xE8FC, 0x7200, 0xFAD2, 0x7206, 0xF8EF, 0x7210, 0xD6D3, + 0x721B, 0xD5B4, 0x722A, 0xF0D0, 0x722C, 0xF7F0, 0x722D, 0xEEB3, + 0x7230, 0xEABA, 0x7232, 0xEAD3, 0x7235, 0xEDC9, 0x7236, 0xDDAB, + 0x723A, 0xE5AC, 0x723B, 0xFDA1, 0x723D, 0xDFD0, 0x723E, 0xECB3, + 0x7240, 0xDFD1, 0x7246, 0xEDED, 0x7247, 0xF8B8, 0x7248, 0xF7FA, + 0x724C, 0xF8AB, 0x7252, 0xF4E0, 0x7258, 0xD4BA, 0x7259, 0xE4B3, + 0x725B, 0xE9DA, 0x725D, 0xDEB6, 0x725F, 0xD9BF, 0x7261, 0xD9C0, + 0x7262, 0xD6EF, 0x7267, 0xD9CC, 0x7269, 0xDAAA, 0x7272, 0xDFE5, + 0x7279, 0xF7E5, 0x727D, 0xCCB2, 0x7280, 0xDFF9, 0x7281, 0xD7E0, + 0x72A2, 0xD4BB, 0x72A7, 0xFDFA, 0x72AC, 0xCCB3, 0x72AF, 0xDBF3, + 0x72C0, 0xDFD2, 0x72C2, 0xCECA, 0x72C4, 0xEEDA, 0x72CE, 0xE4E4, + 0x72D0, 0xFBCF, 0x72D7, 0xCFB7, 0x72D9, 0xEEC3, 0x72E1, 0xCEEA, + 0x72E9, 0xE2AD, 0x72F8, 0xD7E1, 0x72F9, 0xFAF5, 0x72FC, 0xD5C9, + 0x72FD, 0xF8AC, 0x730A, 0xE7D9, 0x7316, 0xF3E9, 0x731B, 0xD8ED, + 0x731C, 0xE3C4, 0x731D, 0xF0F1, 0x7325, 0xE8E5, 0x7329, 0xE0FA, + 0x732A, 0xEEC4, 0x732B, 0xD9DE, 0x7336, 0xEBA2, 0x7337, 0xEBA3, + 0x733E, 0xFCC2, 0x733F, 0xEABB, 0x7344, 0xE8AB, 0x7345, 0xDEE2, + 0x7350, 0xEDEF, 0x7352, 0xE8A3, 0x7357, 0xCFF1, 0x7368, 0xD4BC, + 0x736A, 0xFCEA, 0x7370, 0xE7BE, 0x7372, 0xFCF2, 0x7375, 0xD6B4, + 0x7378, 0xE2AE, 0x737A, 0xD3B7, 0x737B, 0xFACC, 0x7384, 0xFADC, + 0x7386, 0xEDB5, 0x7387, 0xE1E3, 0x7389, 0xE8AC, 0x738B, 0xE8DD, + 0x738E, 0xEFE9, 0x7394, 0xF4BD, 0x7396, 0xCFB8, 0x7397, 0xE9DB, + 0x7398, 0xD1AC, 0x739F, 0xDAC7, 0x73A7, 0xEBC9, 0x73A9, 0xE8CC, + 0x73AD, 0xDEB7, 0x73B2, 0xD6BC, 0x73B3, 0xD3E5, 0x73B9, 0xFADD, + 0x73C0, 0xDAD6, 0x73C2, 0xCAB1, 0x73C9, 0xDAC8, 0x73CA, 0xDFA6, + 0x73CC, 0xF9B3, 0x73CD, 0xF2D2, 0x73CF, 0xCAC4, 0x73D6, 0xCECB, + 0x73D9, 0xCDF5, 0x73DD, 0xFDB0, 0x73DE, 0xD5A8, 0x73E0, 0xF1C1, + 0x73E3, 0xE2E9, 0x73E4, 0xDCCA, 0x73E5, 0xECB4, 0x73E6, 0xFAC0, + 0x73E9, 0xFBA8, 0x73EA, 0xD0A8, 0x73ED, 0xDAEC, 0x73F7, 0xD9EE, + 0x73F9, 0xE0FB, 0x73FD, 0xEFEA, 0x73FE, 0xFADE, 0x7401, 0xE0C4, + 0x7403, 0xCFB9, 0x7405, 0xD5CA, 0x7406, 0xD7E2, 0x7407, 0xE2AF, + 0x7409, 0xD7B8, 0x7413, 0xE8CD, 0x741B, 0xF6DA, 0x7420, 0xEFA2, + 0x7421, 0xE2DA, 0x7422, 0xF6FC, 0x7425, 0xFBD0, 0x7426, 0xD1AD, + 0x7428, 0xCDE4, 0x742A, 0xD1AE, 0x742B, 0xDCED, 0x742C, 0xE8CE, + 0x742E, 0xF0F9, 0x742F, 0xCEB5, 0x7430, 0xE6FC, 0x7433, 0xD7FB, + 0x7434, 0xD0D6, 0x7435, 0xDDF5, 0x7436, 0xF7F1, 0x7438, 0xF6FD, + 0x743A, 0xDBF7, 0x743F, 0xFBEA, 0x7440, 0xE9DC, 0x7441, 0xD9C1, + 0x7443, 0xF5F2, 0x7444, 0xE0C5, 0x744B, 0xEAD4, 0x7455, 0xF9C2, + 0x7457, 0xEABC, 0x7459, 0xD2C5, 0x745A, 0xFBD1, 0x745B, 0xE7C0, + 0x745C, 0xEBA5, 0x745E, 0xDFFA, 0x745F, 0xE3A2, 0x7460, 0xD7B9, + 0x7462, 0xE9C3, 0x7464, 0xE8FD, 0x7465, 0xE8AF, 0x7468, 0xF2D3, + 0x7469, 0xFBA9, 0x746A, 0xD8A5, 0x746F, 0xD5CB, 0x747E, 0xD0C8, + 0x7482, 0xD1AF, 0x7483, 0xD7E3, 0x7487, 0xE0C6, 0x7489, 0xD6A2, + 0x748B, 0xEDF0, 0x7498, 0xD7F3, 0x749C, 0xFCD4, 0x749E, 0xDAD7, + 0x749F, 0xCCDF, 0x74A1, 0xF2D4, 0x74A3, 0xD1B0, 0x74A5, 0xCCE0, + 0x74A7, 0xDBFD, 0x74A8, 0xF3BF, 0x74AA, 0xF0D1, 0x74B0, 0xFCBB, + 0x74B2, 0xE2B0, 0x74B5, 0xE6A5, 0x74B9, 0xE2DB, 0x74BD, 0xDFDE, + 0x74BF, 0xE0C7, 0x74C6, 0xF2EF, 0x74CA, 0xCCE1, 0x74CF, 0xD6EA, + 0x74D4, 0xE7C2, 0x74D8, 0xCEB6, 0x74DA, 0xF3C0, 0x74DC, 0xCDFE, + 0x74E0, 0xFBD2, 0x74E2, 0xF8F8, 0x74E3, 0xF7FB, 0x74E6, 0xE8BF, + 0x74EE, 0xE8B7, 0x74F7, 0xEDB6, 0x7501, 0xDCBA, 0x7504, 0xCCB4, + 0x7511, 0xF1F7, 0x7515, 0xE8B8, 0x7518, 0xCAF6, 0x751A, 0xE4A4, + 0x751B, 0xF4D6, 0x751F, 0xDFE6, 0x7523, 0xDFA7, 0x7525, 0xDFE7, + 0x7526, 0xE1C1, 0x7528, 0xE9C4, 0x752B, 0xDCCB, 0x752C, 0xE9C5, + 0x7530, 0xEFA3, 0x7531, 0xEBA6, 0x7532, 0xCBA3, 0x7533, 0xE3E9, + 0x7537, 0xD1FB, 0x7538, 0xEFA4, 0x753A, 0xEFEB, 0x7547, 0xD0B4, + 0x754C, 0xCDA3, 0x754F, 0xE8E6, 0x7551, 0xEFA5, 0x7553, 0xD3CC, + 0x7554, 0xDAED, 0x7559, 0xD7BA, 0x755B, 0xF2D5, 0x755C, 0xF5E5, + 0x755D, 0xD9EF, 0x7562, 0xF9B4, 0x7565, 0xD5D4, 0x7566, 0xFDCF, + 0x756A, 0xDBE3, 0x756F, 0xF1E1, 0x7570, 0xECB6, 0x7575, 0xFBFE, + 0x7576, 0xD3D7, 0x7578, 0xD1B1, 0x757A, 0xCBB1, 0x757F, 0xD1B2, + 0x7586, 0xCBB2, 0x7587, 0xF1C2, 0x758A, 0xF4E1, 0x758B, 0xF9B5, + 0x758E, 0xE1C3, 0x758F, 0xE1C2, 0x7591, 0xEBF7, 0x759D, 0xDFA8, + 0x75A5, 0xCBCA, 0x75AB, 0xE6B9, 0x75B1, 0xF8DE, 0x75B2, 0xF9AA, + 0x75B3, 0xCAF7, 0x75B5, 0xEDB7, 0x75B8, 0xD3B8, 0x75B9, 0xF2D6, + 0x75BC, 0xD4D9, 0x75BD, 0xEEC5, 0x75BE, 0xF2F0, 0x75C2, 0xCAB2, + 0x75C5, 0xDCBB, 0x75C7, 0xF1F8, 0x75CD, 0xECB7, 0x75D2, 0xE5CA, + 0x75D4, 0xF6C0, 0x75D5, 0xFDDD, 0x75D8, 0xD4E3, 0x75D9, 0xCCE2, + 0x75DB, 0xF7D4, 0x75E2, 0xD7E5, 0x75F0, 0xD3C3, 0x75F2, 0xD8A6, + 0x75F4, 0xF6C1, 0x75FA, 0xDDF6, 0x75FC, 0xCDC0, 0x7600, 0xE5DC, + 0x760D, 0xE5CB, 0x7619, 0xE1C4, 0x761F, 0xE8B0, 0x7620, 0xF4B0, + 0x7621, 0xF3EA, 0x7622, 0xDAEE, 0x7624, 0xD7BB, 0x7626, 0xE2B1, + 0x763B, 0xD7AA, 0x7642, 0xD6FB, 0x764C, 0xE4DF, 0x764E, 0xCAD6, + 0x7652, 0xEBA8, 0x7656, 0xDBFE, 0x7661, 0xF6C2, 0x7664, 0xEFBB, + 0x7669, 0xD4FD, 0x766C, 0xE0C8, 0x7670, 0xE8B9, 0x7672, 0xEFA6, + 0x7678, 0xCDA4, 0x767B, 0xD4F4, 0x767C, 0xDBA1, 0x767D, 0xDBDC, + 0x767E, 0xDBDD, 0x7684, 0xEEDC, 0x7686, 0xCBCB, 0x7687, 0xFCD5, + 0x768E, 0xCEEB, 0x7690, 0xCDC1, 0x7693, 0xFBD3, 0x76AE, 0xF9AB, + 0x76BA, 0xF5D4, 0x76BF, 0xD9A9, 0x76C2, 0xE9DD, 0x76C3, 0xDBCD, + 0x76C6, 0xDDCE, 0x76C8, 0xE7C3, 0x76CA, 0xECCC, 0x76D2, 0xF9EC, + 0x76D6, 0xCBCC, 0x76DB, 0xE0FC, 0x76DC, 0xD4A8, 0x76DE, 0xEDD3, + 0x76DF, 0xD8EF, 0x76E1, 0xF2D7, 0x76E3, 0xCAF8, 0x76E4, 0xDAEF, + 0x76E7, 0xD6D4, 0x76EE, 0xD9CD, 0x76F2, 0xD8EE, 0x76F4, 0xF2C1, + 0x76F8, 0xDFD3, 0x76FC, 0xDAF0, 0x76FE, 0xE2EA, 0x7701, 0xE0FD, + 0x7704, 0xD8F8, 0x7708, 0xF7AF, 0x7709, 0xDAB6, 0x770B, 0xCAD7, + 0x771E, 0xF2D8, 0x7720, 0xD8F9, 0x7729, 0xFADF, 0x7737, 0xCFEF, + 0x7738, 0xD9C2, 0x773A, 0xF0D2, 0x773C, 0xE4D1, 0x7740, 0xF3B7, + 0x774D, 0xFAE0, 0x775B, 0xEFEC, 0x7761, 0xE2B2, 0x7763, 0xD4BD, + 0x7766, 0xD9CE, 0x776B, 0xF4E2, 0x7779, 0xD4A9, 0x777E, 0xCDC2, + 0x777F, 0xE7DA, 0x778B, 0xF2D9, 0x7791, 0xD9AA, 0x779E, 0xD8BE, + 0x77A5, 0xDCAD, 0x77AC, 0xE2EB, 0x77AD, 0xD6FC, 0x77B0, 0xCAF9, + 0x77B3, 0xD4DA, 0x77BB, 0xF4D7, 0x77BC, 0xCCA1, 0x77BF, 0xCFBA, + 0x77D7, 0xF5B8, 0x77DB, 0xD9C3, 0x77DC, 0xD0E8, 0x77E2, 0xE3C5, + 0x77E3, 0xEBF8, 0x77E5, 0xF2B1, 0x77E9, 0xCFBB, 0x77ED, 0xD3AD, + 0x77EE, 0xE8E1, 0x77EF, 0xCEEC, 0x77F3, 0xE0B4, 0x7802, 0xDEE3, + 0x7812, 0xDDF7, 0x7825, 0xF2B2, 0x7826, 0xF3F6, 0x7827, 0xF6DB, + 0x782C, 0xD7FE, 0x7832, 0xF8DF, 0x7834, 0xF7F2, 0x7845, 0xD0A9, + 0x784F, 0xE6DA, 0x785D, 0xF5A6, 0x786B, 0xD7BC, 0x786C, 0xCCE3, + 0x786F, 0xE6DB, 0x787C, 0xDDDD, 0x7881, 0xD1B3, 0x7887, 0xEFED, + 0x788C, 0xD6DE, 0x788D, 0xE4F4, 0x788E, 0xE1EF, 0x7891, 0xDDF8, + 0x7897, 0xE8CF, 0x78A3, 0xCAE5, 0x78A7, 0xDCA1, 0x78A9, 0xE0B5, + 0x78BA, 0xFCAC, 0x78BB, 0xFCAD, 0x78BC, 0xD8A7, 0x78C1, 0xEDB8, + 0x78C5, 0xDBB6, 0x78CA, 0xD6F0, 0x78CB, 0xF3AF, 0x78CE, 0xCDA5, + 0x78D0, 0xDAF1, 0x78E8, 0xD8A8, 0x78EC, 0xCCE4, 0x78EF, 0xD1B4, + 0x78F5, 0xCAD8, 0x78FB, 0xDAF2, 0x7901, 0xF5A7, 0x790E, 0xF5A8, + 0x7916, 0xE6A6, 0x792A, 0xD5EC, 0x792B, 0xD5F8, 0x792C, 0xDAF3, + 0x793A, 0xE3C6, 0x793E, 0xDEE4, 0x7940, 0xDEE5, 0x7941, 0xD1B5, + 0x7947, 0xD1B6, 0x7948, 0xD1B7, 0x7949, 0xF2B3, 0x7950, 0xE9DE, + 0x7956, 0xF0D3, 0x7957, 0xF2B4, 0x795A, 0xF0D4, 0x795B, 0xCBE4, + 0x795C, 0xFBD4, 0x795D, 0xF5E6, 0x795E, 0xE3EA, 0x7960, 0xDEE6, + 0x7965, 0xDFD4, 0x7968, 0xF8F9, 0x796D, 0xF0AE, 0x797A, 0xD1B8, + 0x797F, 0xD6DF, 0x7981, 0xD0D7, 0x798D, 0xFCA1, 0x798E, 0xEFEE, + 0x798F, 0xDCD8, 0x7991, 0xE9DF, 0x79A6, 0xE5DD, 0x79A7, 0xFDFB, + 0x79AA, 0xE0C9, 0x79AE, 0xD6C9, 0x79B1, 0xD4AA, 0x79B3, 0xE5CC, + 0x79B9, 0xE9E0, 0x79BD, 0xD0D8, 0x79BE, 0xFCA2, 0x79BF, 0xD4BE, + 0x79C0, 0xE2B3, 0x79C1, 0xDEE7, 0x79C9, 0xDCBC, 0x79CA, 0xD2B6, + 0x79CB, 0xF5D5, 0x79D1, 0xCEA1, 0x79D2, 0xF5A9, 0x79D5, 0xDDF9, + 0x79D8, 0xDDFA, 0x79DF, 0xF0D5, 0x79E4, 0xF6DF, 0x79E6, 0xF2DA, + 0x79E7, 0xE4EB, 0x79E9, 0xF2F1, 0x79FB, 0xECB9, 0x7A00, 0xFDFC, + 0x7A05, 0xE1AA, 0x7A08, 0xCAD9, 0x7A0B, 0xEFEF, 0x7A0D, 0xF5AA, + 0x7A14, 0xECF9, 0x7A17, 0xF8AD, 0x7A19, 0xF2C2, 0x7A1A, 0xF6C3, + 0x7A1C, 0xD7D2, 0x7A1F, 0xF9A2, 0x7A20, 0xF0D6, 0x7A2E, 0xF0FA, + 0x7A31, 0xF6E0, 0x7A36, 0xE9F3, 0x7A37, 0xF2C3, 0x7A3B, 0xD4AB, + 0x7A3C, 0xCAB3, 0x7A3D, 0xCDA6, 0x7A3F, 0xCDC3, 0x7A40, 0xCDDA, + 0x7A46, 0xD9CF, 0x7A49, 0xF6C4, 0x7A4D, 0xEEDD, 0x7A4E, 0xE7C4, + 0x7A57, 0xE2B4, 0x7A61, 0xDFE2, 0x7A62, 0xE7DB, 0x7A69, 0xE8B1, + 0x7A6B, 0xFCAE, 0x7A70, 0xE5CD, 0x7A74, 0xFAEB, 0x7A76, 0xCFBC, + 0x7A79, 0xCFE2, 0x7A7A, 0xCDF6, 0x7A7D, 0xEFF0, 0x7A7F, 0xF4BE, + 0x7A81, 0xD4CD, 0x7A84, 0xF3B8, 0x7A88, 0xE9A1, 0x7A92, 0xF2F2, + 0x7A93, 0xF3EB, 0x7A95, 0xF0D7, 0x7A98, 0xCFD7, 0x7A9F, 0xCFDF, + 0x7AA9, 0xE8C0, 0x7AAA, 0xE8C1, 0x7AAE, 0xCFE3, 0x7AAF, 0xE9A2, + 0x7ABA, 0xD0AA, 0x7AC4, 0xF3C1, 0x7AC5, 0xD0AB, 0x7AC7, 0xD4E4, + 0x7ACA, 0xEFBC, 0x7ACB, 0xD8A1, 0x7AD7, 0xD9DF, 0x7AD9, 0xF3D7, + 0x7ADD, 0xDCBD, 0x7ADF, 0xCCE5, 0x7AE0, 0xEDF1, 0x7AE3, 0xF1E2, + 0x7AE5, 0xD4DB, 0x7AEA, 0xE2B5, 0x7AED, 0xCAE6, 0x7AEF, 0xD3AE, + 0x7AF6, 0xCCE6, 0x7AF9, 0xF1D3, 0x7AFA, 0xF5E7, 0x7AFF, 0xCADA, + 0x7B0F, 0xFBEE, 0x7B11, 0xE1C5, 0x7B19, 0xDFE9, 0x7B1B, 0xEEDE, + 0x7B1E, 0xF7C2, 0x7B20, 0xD8A2, 0x7B26, 0xDDAC, 0x7B2C, 0xF0AF, + 0x7B2D, 0xD6BD, 0x7B39, 0xE1AB, 0x7B46, 0xF9B6, 0x7B49, 0xD4F5, + 0x7B4B, 0xD0C9, 0x7B4C, 0xEFA7, 0x7B4D, 0xE2EC, 0x7B4F, 0xDBEA, + 0x7B50, 0xCECC, 0x7B51, 0xF5E8, 0x7B52, 0xF7D5, 0x7B54, 0xD3CD, + 0x7B56, 0xF3FE, 0x7B60, 0xD0B5, 0x7B6C, 0xE0FE, 0x7B6E, 0xDFFB, + 0x7B75, 0xE6DD, 0x7B7D, 0xE8A4, 0x7B87, 0xCBCD, 0x7B8B, 0xEFA8, + 0x7B8F, 0xEEB4, 0x7B94, 0xDAD8, 0x7B95, 0xD1B9, 0x7B97, 0xDFA9, + 0x7B9A, 0xF3B0, 0x7B9D, 0xCCC4, 0x7BA1, 0xCEB7, 0x7BAD, 0xEFA9, + 0x7BB1, 0xDFD5, 0x7BB4, 0xEDD7, 0x7BB8, 0xEEC6, 0x7BC0, 0xEFBD, + 0x7BC1, 0xFCD6, 0x7BC4, 0xDBF4, 0x7BC6, 0xEFAA, 0x7BC7, 0xF8B9, + 0x7BC9, 0xF5E9, 0x7BD2, 0xE3D9, 0x7BE0, 0xE1C6, 0x7BE4, 0xD4BF, + 0x7BE9, 0xDEE8, 0x7C07, 0xF0EA, 0x7C12, 0xF3C2, 0x7C1E, 0xD3AF, + 0x7C21, 0xCADB, 0x7C27, 0xFCD7, 0x7C2A, 0xEDD8, 0x7C2B, 0xE1C7, + 0x7C3D, 0xF4D8, 0x7C3E, 0xD6B3, 0x7C3F, 0xDDAD, 0x7C43, 0xD5BE, + 0x7C4C, 0xF1C3, 0x7C4D, 0xEEDF, 0x7C60, 0xD6EB, 0x7C64, 0xF4D9, + 0x7C6C, 0xD7E6, 0x7C73, 0xDAB7, 0x7C83, 0xDDFB, 0x7C89, 0xDDCF, + 0x7C92, 0xD8A3, 0x7C95, 0xDAD9, 0x7C97, 0xF0D8, 0x7C98, 0xEFC4, + 0x7C9F, 0xE1D8, 0x7CA5, 0xF1D4, 0x7CA7, 0xEDF2, 0x7CAE, 0xD5DB, + 0x7CB1, 0xD5DC, 0x7CB2, 0xF3C4, 0x7CB3, 0xCBD7, 0x7CB9, 0xE2B6, + 0x7CBE, 0xEFF1, 0x7CCA, 0xFBD5, 0x7CD6, 0xD3D8, 0x7CDE, 0xDDD0, + 0x7CDF, 0xF0D9, 0x7CE0, 0xCBB3, 0x7CE7, 0xD5DD, 0x7CFB, 0xCDA7, + 0x7CFE, 0xD0AC, 0x7D00, 0xD1BA, 0x7D02, 0xF1C4, 0x7D04, 0xE5B3, + 0x7D05, 0xFBF5, 0x7D06, 0xE9E1, 0x7D07, 0xFDE0, 0x7D08, 0xFCBC, + 0x7D0A, 0xDAA2, 0x7D0B, 0xDAA3, 0x7D0D, 0xD2A1, 0x7D10, 0xD2EF, + 0x7D14, 0xE2ED, 0x7D17, 0xDEE9, 0x7D18, 0xCEDC, 0x7D19, 0xF2B5, + 0x7D1A, 0xD0E4, 0x7D1B, 0xDDD1, 0x7D20, 0xE1C8, 0x7D21, 0xDBB7, + 0x7D22, 0xDFE3, 0x7D2B, 0xEDB9, 0x7D2C, 0xF1C5, 0x7D2E, 0xF3CF, + 0x7D2F, 0xD7AB, 0x7D30, 0xE1AC, 0x7D33, 0xE3EB, 0x7D35, 0xEEC7, + 0x7D39, 0xE1C9, 0x7D3A, 0xCAFA, 0x7D42, 0xF0FB, 0x7D43, 0xFAE1, + 0x7D44, 0xF0DA, 0x7D45, 0xCCE7, 0x7D46, 0xDAF4, 0x7D50, 0xCCBF, + 0x7D5E, 0xCEED, 0x7D61, 0xD5A9, 0x7D62, 0xFAE2, 0x7D66, 0xD0E5, + 0x7D68, 0xEBD6, 0x7D6A, 0xECDF, 0x7D6E, 0xDFFC, 0x7D71, 0xF7D6, + 0x7D72, 0xDEEA, 0x7D73, 0xCBB4, 0x7D76, 0xEFBE, 0x7D79, 0xCCB5, + 0x7D7F, 0xCFBD, 0x7D8E, 0xEFF2, 0x7D8F, 0xE2B7, 0x7D93, 0xCCE8, + 0x7D9C, 0xF0FC, 0x7DA0, 0xD6E0, 0x7DA2, 0xF1C6, 0x7DAC, 0xE2B8, + 0x7DAD, 0xEBAB, 0x7DB1, 0xCBB5, 0x7DB2, 0xD8D1, 0x7DB4, 0xF4CE, + 0x7DB5, 0xF3F7, 0x7DB8, 0xD7C6, 0x7DBA, 0xD1BB, 0x7DBB, 0xF7AA, + 0x7DBD, 0xEDCA, 0x7DBE, 0xD7D3, 0x7DBF, 0xD8FA, 0x7DC7, 0xF6C5, + 0x7DCA, 0xD1CC, 0x7DCB, 0xDDFC, 0x7DD6, 0xDFFD, 0x7DD8, 0xF9E5, + 0x7DDA, 0xE0CA, 0x7DDD, 0xF2FD, 0x7DDE, 0xD3B0, 0x7DE0, 0xF4F3, + 0x7DE1, 0xDAC9, 0x7DE3, 0xE6DE, 0x7DE8, 0xF8BA, 0x7DE9, 0xE8D0, + 0x7DEC, 0xD8FB, 0x7DEF, 0xEAD5, 0x7DF4, 0xD6A3, 0x7DFB, 0xF6C6, + 0x7E09, 0xF2DB, 0x7E0A, 0xE4FC, 0x7E15, 0xE8B2, 0x7E1B, 0xDADA, + 0x7E1D, 0xF2DC, 0x7E1E, 0xFBD6, 0x7E1F, 0xE9B2, 0x7E21, 0xEEAD, + 0x7E23, 0xFAE3, 0x7E2B, 0xDCEE, 0x7E2E, 0xF5EA, 0x7E2F, 0xE6E0, + 0x7E31, 0xF0FD, 0x7E37, 0xD7AC, 0x7E3D, 0xF5C5, 0x7E3E, 0xEEE0, + 0x7E41, 0xDBE5, 0x7E43, 0xDDDE, 0x7E46, 0xD9F0, 0x7E47, 0xE9A3, + 0x7E52, 0xF1F9, 0x7E54, 0xF2C4, 0x7E55, 0xE0CB, 0x7E5E, 0xE9A4, + 0x7E61, 0xE2B9, 0x7E69, 0xE3B1, 0x7E6A, 0xFCEB, 0x7E6B, 0xCDA8, + 0x7E6D, 0xCCB6, 0x7E70, 0xF0DB, 0x7E79, 0xE6BA, 0x7E7C, 0xCDA9, + 0x7E82, 0xF3C3, 0x7E8C, 0xE1D9, 0x7E8F, 0xEFAB, 0x7E93, 0xE7C5, + 0x7E96, 0xE0E9, 0x7E98, 0xF3C5, 0x7E9B, 0xD4C0, 0x7E9C, 0xD5BF, + 0x7F36, 0xDDAE, 0x7F38, 0xF9FC, 0x7F3A, 0xCCC0, 0x7F4C, 0xE5A2, + 0x7F50, 0xCEB8, 0x7F54, 0xD8D2, 0x7F55, 0xF9D6, 0x7F6A, 0xF1AA, + 0x7F6B, 0xCED1, 0x7F6E, 0xF6C7, 0x7F70, 0xDBEB, 0x7F72, 0xDFFE, + 0x7F75, 0xD8E1, 0x7F77, 0xF7F3, 0x7F79, 0xD7E7, 0x7F85, 0xD4FE, + 0x7F88, 0xD1BC, 0x7F8A, 0xE5CF, 0x7F8C, 0xCBB6, 0x7F8E, 0xDAB8, + 0x7F94, 0xCDC4, 0x7F9A, 0xD6BE, 0x7F9E, 0xE2BA, 0x7FA4, 0xCFD8, + 0x7FA8, 0xE0CC, 0x7FA9, 0xEBF9, 0x7FB2, 0xFDFD, 0x7FB8, 0xD7E8, + 0x7FB9, 0xCBD8, 0x7FBD, 0xE9E2, 0x7FC1, 0xE8BA, 0x7FC5, 0xE3C7, + 0x7FCA, 0xECCD, 0x7FCC, 0xECCE, 0x7FCE, 0xD6BF, 0x7FD2, 0xE3A7, + 0x7FD4, 0xDFD6, 0x7FD5, 0xFDE8, 0x7FDF, 0xEEE1, 0x7FE0, 0xF6A8, + 0x7FE1, 0xDDFD, 0x7FE9, 0xF8BB, 0x7FEB, 0xE8D1, 0x7FF0, 0xF9D7, + 0x7FF9, 0xCEEE, 0x7FFC, 0xECCF, 0x8000, 0xE9A5, 0x8001, 0xD6D5, + 0x8003, 0xCDC5, 0x8005, 0xEDBA, 0x8006, 0xD1BD, 0x8009, 0xCFBE, + 0x800C, 0xECBB, 0x8010, 0xD2B1, 0x8015, 0xCCE9, 0x8017, 0xD9C4, + 0x8018, 0xE9FC, 0x802D, 0xD1BE, 0x8033, 0xECBC, 0x8036, 0xE5AD, + 0x803D, 0xF7B0, 0x803F, 0xCCEA, 0x8043, 0xD3C4, 0x8046, 0xD6C0, + 0x804A, 0xD6FD, 0x8056, 0xE1A1, 0x8058, 0xDEBD, 0x805A, 0xF6A9, + 0x805E, 0xDAA4, 0x806F, 0xD6A4, 0x8070, 0xF5C6, 0x8072, 0xE1A2, + 0x8073, 0xE9C6, 0x8077, 0xF2C5, 0x807D, 0xF4E9, 0x807E, 0xD6EC, + 0x807F, 0xEBD3, 0x8084, 0xECBD, 0x8085, 0xE2DC, 0x8086, 0xDEEB, + 0x8087, 0xF0DC, 0x8089, 0xEBBF, 0x808B, 0xD7CE, 0x808C, 0xD1BF, + 0x8096, 0xF5AB, 0x809B, 0xF9FD, 0x809D, 0xCADC, 0x80A1, 0xCDC6, + 0x80A2, 0xF2B6, 0x80A5, 0xDDFE, 0x80A9, 0xCCB7, 0x80AA, 0xDBB8, + 0x80AF, 0xD0E9, 0x80B1, 0xCEDD, 0x80B2, 0xEBC0, 0x80B4, 0xFDA2, + 0x80BA, 0xF8CB, 0x80C3, 0xEAD6, 0x80C4, 0xF1B0, 0x80CC, 0xDBCE, + 0x80CE, 0xF7C3, 0x80DA, 0xDBCF, 0x80DB, 0xCBA4, 0x80DE, 0xF8E0, + 0x80E1, 0xFBD7, 0x80E4, 0xEBCA, 0x80E5, 0xE0A1, 0x80F1, 0xCECD, + 0x80F4, 0xD4DC, 0x80F8, 0xFDD8, 0x80FD, 0xD2F6, 0x8102, 0xF2B7, + 0x8105, 0xFAF6, 0x8106, 0xF6AA, 0x8107, 0xFAF7, 0x8108, 0xD8E6, + 0x810A, 0xF4B1, 0x8118, 0xE8D2, 0x811A, 0xCAC5, 0x811B, 0xCCEB, + 0x8123, 0xE2EE, 0x8129, 0xE2BB, 0x812B, 0xF7AD, 0x812F, 0xF8E1, + 0x8139, 0xF3EC, 0x813E, 0xDEA1, 0x814B, 0xE4FD, 0x814E, 0xE3EC, + 0x8150, 0xDDAF, 0x8151, 0xDDB0, 0x8154, 0xCBB7, 0x8155, 0xE8D3, + 0x8165, 0xE1A3, 0x8166, 0xD2E0, 0x816B, 0xF0FE, 0x8170, 0xE9A6, + 0x8171, 0xCBF2, 0x8178, 0xEDF3, 0x8179, 0xDCD9, 0x817A, 0xE0CD, + 0x817F, 0xF7DA, 0x8180, 0xDBB9, 0x8188, 0xCCAE, 0x818A, 0xDADB, + 0x818F, 0xCDC7, 0x819A, 0xDDB1, 0x819C, 0xD8AF, 0x819D, 0xE3A3, + 0x81A0, 0xCEEF, 0x81A3, 0xF2F3, 0x81A8, 0xF8B3, 0x81B3, 0xE0CE, + 0x81B5, 0xF5FD, 0x81BA, 0xEBEC, 0x81BD, 0xD3C5, 0x81BE, 0xFCEC, + 0x81BF, 0xD2DB, 0x81C0, 0xD4EB, 0x81C2, 0xDEA2, 0x81C6, 0xE5E6, + 0x81CD, 0xF0B0, 0x81D8, 0xD5C4, 0x81DF, 0xEDF4, 0x81E3, 0xE3ED, + 0x81E5, 0xE8C2, 0x81E7, 0xEDF5, 0x81E8, 0xD7FC, 0x81EA, 0xEDBB, + 0x81ED, 0xF6AB, 0x81F3, 0xF2B8, 0x81F4, 0xF6C8, 0x81FA, 0xD3E6, + 0x81FB, 0xF2DD, 0x81FC, 0xCFBF, 0x81FE, 0xEBAC, 0x8205, 0xCFC0, + 0x8207, 0xE6A8, 0x8208, 0xFDE9, 0x820A, 0xCFC1, 0x820C, 0xE0DF, + 0x820D, 0xDEEC, 0x8212, 0xE0A2, 0x821B, 0xF4BF, 0x821C, 0xE2EF, + 0x821E, 0xD9F1, 0x821F, 0xF1C7, 0x8221, 0xCBB8, 0x822A, 0xF9FE, + 0x822B, 0xDBBA, 0x822C, 0xDAF5, 0x8235, 0xF6EC, 0x8236, 0xDADC, + 0x8237, 0xFAE4, 0x8239, 0xE0CF, 0x8240, 0xDDB2, 0x8245, 0xE6A9, + 0x8247, 0xEFF3, 0x8259, 0xF3ED, 0x8264, 0xEBFA, 0x8266, 0xF9E6, + 0x826E, 0xCADD, 0x826F, 0xD5DE, 0x8271, 0xCADE, 0x8272, 0xDFE4, + 0x8276, 0xE6FD, 0x8278, 0xF5AC, 0x827E, 0xE4F5, 0x828B, 0xE9E3, + 0x828D, 0xEDCB, 0x828E, 0xCFE4, 0x8292, 0xD8D3, 0x8299, 0xDDB3, + 0x829A, 0xD4EC, 0x829D, 0xF2B9, 0x829F, 0xDFB7, 0x82A5, 0xCBCE, + 0x82A6, 0xFBD8, 0x82A9, 0xD0D9, 0x82AC, 0xDDD2, 0x82AD, 0xF7F4, + 0x82AE, 0xE7DC, 0x82AF, 0xE4A5, 0x82B1, 0xFCA3, 0x82B3, 0xDBBB, + 0x82B7, 0xF2BA, 0x82B8, 0xE9FD, 0x82B9, 0xD0CA, 0x82BB, 0xF5D6, + 0x82BC, 0xD9C5, 0x82BD, 0xE4B4, 0x82BF, 0xEDA7, 0x82D1, 0xEABD, + 0x82D2, 0xE6FE, 0x82D4, 0xF7C4, 0x82D5, 0xF5AD, 0x82D7, 0xD9E0, + 0x82DB, 0xCAB4, 0x82DE, 0xF8E2, 0x82DF, 0xCFC2, 0x82E1, 0xECBE, + 0x82E5, 0xE5B4, 0x82E6, 0xCDC8, 0x82E7, 0xEEC8, 0x82F1, 0xE7C8, + 0x82FD, 0xCDC9, 0x82FE, 0xF9B7, 0x8301, 0xF1E8, 0x8302, 0xD9F2, + 0x8303, 0xDBF5, 0x8304, 0xCAB5, 0x8305, 0xD9C6, 0x8309, 0xD8C9, + 0x8317, 0xD9AB, 0x8328, 0xEDBC, 0x832B, 0xD8D4, 0x832F, 0xDCDA, + 0x8331, 0xE2BC, 0x8334, 0xFCED, 0x8335, 0xECE0, 0x8336, 0xD2FE, + 0x8338, 0xE9C7, 0x8339, 0xE6AA, 0x8340, 0xE2F0, 0x8347, 0xFABB, + 0x8349, 0xF5AE, 0x834A, 0xFBAA, 0x834F, 0xECFB, 0x8351, 0xECBF, + 0x8352, 0xFCD8, 0x8373, 0xD4E5, 0x8377, 0xF9C3, 0x837B, 0xEEE2, + 0x8389, 0xD7E9, 0x838A, 0xEDF6, 0x838E, 0xDEED, 0x8396, 0xCCEC, + 0x8398, 0xE3EE, 0x839E, 0xE8D4, 0x83A2, 0xFAF8, 0x83A9, 0xDDB4, + 0x83AA, 0xE4B5, 0x83AB, 0xD8B0, 0x83BD, 0xD8D5, 0x83C1, 0xF4EA, + 0x83C5, 0xCEB9, 0x83C9, 0xD6E1, 0x83CA, 0xCFD2, 0x83CC, 0xD0B6, + 0x83D3, 0xCEA2, 0x83D6, 0xF3EE, 0x83DC, 0xF3F8, 0x83E9, 0xDCCC, + 0x83EB, 0xD0CB, 0x83EF, 0xFCA4, 0x83F0, 0xCDCA, 0x83F1, 0xD7D4, + 0x83F2, 0xDEA3, 0x83F4, 0xE4E0, 0x83F9, 0xEEC9, 0x83FD, 0xE2DD, + 0x8403, 0xF5FE, 0x8404, 0xD4AC, 0x840A, 0xD5D1, 0x840C, 0xD8F0, + 0x840D, 0xF8C3, 0x840E, 0xEAD7, 0x8429, 0xF5D7, 0x842C, 0xD8BF, + 0x8431, 0xFDC0, 0x8438, 0xEBAD, 0x843D, 0xD5AA, 0x8449, 0xE7A8, + 0x8457, 0xEECA, 0x845B, 0xCAE7, 0x8461, 0xF8E3, 0x8463, 0xD4DD, + 0x8466, 0xEAD8, 0x846B, 0xFBD9, 0x846C, 0xEDF7, 0x846F, 0xE5B5, + 0x8475, 0xD0AD, 0x847A, 0xF1F1, 0x8490, 0xE2BD, 0x8494, 0xE3C8, + 0x8499, 0xD9D5, 0x849C, 0xDFAA, 0x84A1, 0xDBBC, 0x84B2, 0xF8E4, + 0x84B8, 0xF1FA, 0x84BB, 0xE5B6, 0x84BC, 0xF3EF, 0x84BF, 0xFBDA, + 0x84C0, 0xE1E0, 0x84C2, 0xD9AC, 0x84C4, 0xF5EB, 0x84C6, 0xE0B6, + 0x84C9, 0xE9C8, 0x84CB, 0xCBCF, 0x84CD, 0xE3C9, 0x84D1, 0xDEEE, + 0x84DA, 0xE2BE, 0x84EC, 0xDCEF, 0x84EE, 0xD6A5, 0x84F4, 0xE2F1, + 0x84FC, 0xD6FE, 0x8511, 0xD9A1, 0x8513, 0xD8C0, 0x8514, 0xDCDB, + 0x8517, 0xEDBD, 0x8518, 0xDFB8, 0x851A, 0xEAA5, 0x851E, 0xD7AD, + 0x8521, 0xF3F9, 0x8523, 0xEDF8, 0x8525, 0xF5C7, 0x852C, 0xE1CA, + 0x852D, 0xEBE3, 0x852F, 0xF2DE, 0x853D, 0xF8CC, 0x853F, 0xEAD9, + 0x8541, 0xD3C6, 0x8543, 0xDBE6, 0x8549, 0xF5AF, 0x854E, 0xCEF0, + 0x8553, 0xE9FE, 0x8559, 0xFBB6, 0x8563, 0xE2F2, 0x8568, 0xCFF2, + 0x8569, 0xF7B9, 0x856A, 0xD9F3, 0x856D, 0xE1CB, 0x8584, 0xDADD, + 0x8587, 0xDAB9, 0x858F, 0xEBFB, 0x8591, 0xCBB9, 0x8594, 0xEDF9, + 0x859B, 0xE0E0, 0x85A6, 0xF4C0, 0x85A8, 0xFDBC, 0x85A9, 0xDFB1, + 0x85AA, 0xE3EF, 0x85AF, 0xE0A3, 0x85B0, 0xFDB9, 0x85BA, 0xF0B1, + 0x85C1, 0xCDCB, 0x85C9, 0xEDBE, 0x85CD, 0xD5C0, 0x85CE, 0xE3F0, + 0x85CF, 0xEDFA, 0x85D5, 0xE9E4, 0x85DC, 0xD5ED, 0x85DD, 0xE7DD, + 0x85E4, 0xD4F6, 0x85E5, 0xE5B7, 0x85E9, 0xDBE7, 0x85EA, 0xE2BF, + 0x85F7, 0xEECB, 0x85FA, 0xD7F4, 0x85FB, 0xF0DD, 0x85FF, 0xCEAB, + 0x8602, 0xE7DE, 0x8606, 0xD6D6, 0x8607, 0xE1CC, 0x860A, 0xE8B3, + 0x8616, 0xE5EE, 0x8617, 0xDCA2, 0x861A, 0xE0D0, 0x862D, 0xD5B5, + 0x863F, 0xD5A1, 0x864E, 0xFBDB, 0x8650, 0xF9CB, 0x8654, 0xCBF3, + 0x8655, 0xF4A5, 0x865B, 0xFAC8, 0x865C, 0xD6D7, 0x865E, 0xE9E5, + 0x865F, 0xFBDC, 0x8667, 0xFDD0, 0x8679, 0xFBF6, 0x868A, 0xDAA5, + 0x868C, 0xDBBD, 0x8693, 0xECE2, 0x86A3, 0xCDF7, 0x86A4, 0xF0DE, + 0x86A9, 0xF6C9, 0x86C7, 0xDEEF, 0x86CB, 0xD3B1, 0x86D4, 0xFCEE, + 0x86D9, 0xE8C3, 0x86DB, 0xF1C8, 0x86DF, 0xCEF1, 0x86E4, 0xF9ED, + 0x86ED, 0xF2F4, 0x86FE, 0xE4B6, 0x8700, 0xF5B9, 0x8702, 0xDCF0, + 0x8703, 0xE3F1, 0x8708, 0xE8A5, 0x8718, 0xF2BB, 0x871A, 0xDEA4, + 0x871C, 0xDACC, 0x874E, 0xCAE9, 0x8755, 0xE3DA, 0x8757, 0xFCD9, + 0x875F, 0xEADA, 0x8766, 0xF9C4, 0x8768, 0xE3A4, 0x8774, 0xFBDD, + 0x8776, 0xEFCA, 0x8778, 0xE8C4, 0x8782, 0xD5CC, 0x878D, 0xEBD7, + 0x879F, 0xD9AD, 0x87A2, 0xFBAB, 0x87B3, 0xD3D9, 0x87BA, 0xD5A2, + 0x87C4, 0xF6DE, 0x87E0, 0xDAF6, 0x87EC, 0xE0D1, 0x87EF, 0xE9A8, + 0x87F2, 0xF5F9, 0x87F9, 0xFAAF, 0x87FB, 0xEBFC, 0x87FE, 0xE0EA, + 0x8805, 0xE3B2, 0x881F, 0xD5C5, 0x8822, 0xF1E3, 0x8823, 0xD5EE, + 0x8831, 0xCDCC, 0x8836, 0xEDD9, 0x883B, 0xD8C1, 0x8840, 0xFAEC, + 0x8846, 0xF1EB, 0x884C, 0xFABC, 0x884D, 0xE6E2, 0x8852, 0xFAE5, + 0x8853, 0xE2FA, 0x8857, 0xCAB6, 0x8859, 0xE4B7, 0x885B, 0xEADB, + 0x885D, 0xF5FA, 0x8861, 0xFBAC, 0x8862, 0xCFC3, 0x8863, 0xEBFD, + 0x8868, 0xF8FA, 0x886B, 0xDFB9, 0x8870, 0xE1F1, 0x8872, 0xD2A4, + 0x8877, 0xF5FB, 0x887E, 0xD0DA, 0x887F, 0xD0DB, 0x8881, 0xEABE, + 0x8882, 0xD9B1, 0x8888, 0xCAB7, 0x888B, 0xD3E7, 0x888D, 0xF8E5, + 0x8892, 0xD3B2, 0x8896, 0xE2C0, 0x8897, 0xF2DF, 0x889E, 0xCDE5, + 0x88AB, 0xF9AC, 0x88B4, 0xCDCD, 0x88C1, 0xEEAE, 0x88C2, 0xD6AE, + 0x88CF, 0xD7EA, 0x88D4, 0xE7E0, 0x88D5, 0xEBAE, 0x88D9, 0xCFD9, + 0x88DC, 0xDCCD, 0x88DD, 0xEDFB, 0x88DF, 0xDEF0, 0x88E1, 0xD7EB, + 0x88E8, 0xDEA5, 0x88F3, 0xDFD7, 0x88F4, 0xDBD0, 0x88F5, 0xDBD1, + 0x88F8, 0xD5A3, 0x88FD, 0xF0B2, 0x8907, 0xDCDC, 0x8910, 0xCAE8, + 0x8912, 0xF8E6, 0x8913, 0xDCCE, 0x8918, 0xEADC, 0x8919, 0xDBD2, + 0x8925, 0xE9B3, 0x892A, 0xF7DB, 0x8936, 0xE3A8, 0x8938, 0xD7AE, + 0x893B, 0xE0E1, 0x8941, 0xCBBA, 0x8944, 0xE5D1, 0x895F, 0xD0DC, + 0x8964, 0xD5C1, 0x896A, 0xD8CA, 0x8972, 0xE3A9, 0x897F, 0xE0A4, + 0x8981, 0xE9A9, 0x8983, 0xD3C7, 0x8986, 0xDCDD, 0x8987, 0xF8AE, + 0x898B, 0xCCB8, 0x898F, 0xD0AE, 0x8993, 0xD8F2, 0x8996, 0xE3CA, + 0x89A1, 0xCCAF, 0x89A9, 0xD4AD, 0x89AA, 0xF6D1, 0x89B2, 0xD0CC, + 0x89BA, 0xCAC6, 0x89BD, 0xD5C2, 0x89C0, 0xCEBA, 0x89D2, 0xCAC7, + 0x89E3, 0xFAB0, 0x89F4, 0xDFD8, 0x89F8, 0xF5BA, 0x8A00, 0xE5EB, + 0x8A02, 0xEFF4, 0x8A03, 0xDDB5, 0x8A08, 0xCDAA, 0x8A0A, 0xE3F2, + 0x8A0C, 0xFBF7, 0x8A0E, 0xF7D0, 0x8A13, 0xFDBA, 0x8A16, 0xFDE1, + 0x8A17, 0xF6FE, 0x8A18, 0xD1C0, 0x8A1B, 0xE8C5, 0x8A1D, 0xE4B8, + 0x8A1F, 0xE1E8, 0x8A23, 0xCCC1, 0x8A25, 0xD2ED, 0x8A2A, 0xDBBE, + 0x8A2D, 0xE0E2, 0x8A31, 0xFAC9, 0x8A34, 0xE1CD, 0x8A36, 0xCAB8, + 0x8A3A, 0xF2E0, 0x8A3B, 0xF1C9, 0x8A50, 0xDEF1, 0x8A54, 0xF0DF, + 0x8A55, 0xF8C4, 0x8A5B, 0xEECC, 0x8A5E, 0xDEF2, 0x8A60, 0xE7C9, + 0x8A62, 0xE2F3, 0x8A63, 0xE7E1, 0x8A66, 0xE3CB, 0x8A69, 0xE3CC, + 0x8A6D, 0xCFF8, 0x8A6E, 0xEFAC, 0x8A70, 0xFDFE, 0x8A71, 0xFCA5, + 0x8A72, 0xFAB1, 0x8A73, 0xDFD9, 0x8A75, 0xE0D2, 0x8A79, 0xF4DA, + 0x8A85, 0xF1CA, 0x8A87, 0xCEA3, 0x8A8C, 0xF2BC, 0x8A8D, 0xECE3, + 0x8A93, 0xE0A5, 0x8A95, 0xF7AB, 0x8A98, 0xEBAF, 0x8A9E, 0xE5DE, + 0x8AA0, 0xE1A4, 0x8AA1, 0xCDAB, 0x8AA3, 0xD9F4, 0x8AA4, 0xE8A6, + 0x8AA5, 0xCDCE, 0x8AA6, 0xE1E9, 0x8AA8, 0xFCEF, 0x8AAA, 0xE0E3, + 0x8AB0, 0xE2C1, 0x8AB2, 0xCEA4, 0x8AB9, 0xDEA6, 0x8ABC, 0xEBFE, + 0x8ABE, 0xEBDD, 0x8ABF, 0xF0E0, 0x8AC2, 0xF4DB, 0x8AC4, 0xE2F4, + 0x8AC7, 0xD3C8, 0x8ACB, 0xF4EB, 0x8ACD, 0xEEB5, 0x8ACF, 0xF5D8, + 0x8AD2, 0xD5DF, 0x8AD6, 0xD6E5, 0x8ADB, 0xEBB0, 0x8ADC, 0xF4E3, + 0x8AE1, 0xE3CD, 0x8AE6, 0xF4F4, 0x8AE7, 0xFAB2, 0x8AEA, 0xEFF5, + 0x8AEB, 0xCADF, 0x8AED, 0xEBB1, 0x8AEE, 0xEDBF, 0x8AF1, 0xFDC9, + 0x8AF6, 0xE4A6, 0x8AF7, 0xF9A4, 0x8AF8, 0xF0B3, 0x8AFA, 0xE5EC, + 0x8AFE, 0xD1E7, 0x8B00, 0xD9C7, 0x8B01, 0xE4D7, 0x8B02, 0xEADD, + 0x8B04, 0xD4F7, 0x8B0E, 0xDABA, 0x8B10, 0xDACD, 0x8B14, 0xF9CC, + 0x8B16, 0xE1DA, 0x8B17, 0xDBBF, 0x8B19, 0xCCC5, 0x8B1A, 0xECD0, + 0x8B1B, 0xCBBB, 0x8B1D, 0xDEF3, 0x8B20, 0xE9AA, 0x8B28, 0xD9C8, + 0x8B2B, 0xEEE3, 0x8B2C, 0xD7BD, 0x8B33, 0xCFC4, 0x8B39, 0xD0CD, + 0x8B41, 0xFCA6, 0x8B49, 0xF1FB, 0x8B4E, 0xFDD2, 0x8B4F, 0xD1C1, + 0x8B58, 0xE3DB, 0x8B5A, 0xD3C9, 0x8B5C, 0xDCCF, 0x8B66, 0xCCED, + 0x8B6C, 0xDEA7, 0x8B6F, 0xE6BB, 0x8B70, 0xECA1, 0x8B74, 0xCCB9, + 0x8B77, 0xFBDE, 0x8B7D, 0xE7E2, 0x8B80, 0xD4C1, 0x8B8A, 0xDCA8, + 0x8B90, 0xE2C2, 0x8B92, 0xF3D8, 0x8B93, 0xE5D3, 0x8B96, 0xF3D9, + 0x8B9A, 0xF3C6, 0x8C37, 0xCDDB, 0x8C3F, 0xCDAC, 0x8C41, 0xFCC3, + 0x8C46, 0xD4E7, 0x8C48, 0xD1C2, 0x8C4A, 0xF9A5, 0x8C4C, 0xE8D5, + 0x8C55, 0xE3CE, 0x8C5A, 0xD4CA, 0x8C61, 0xDFDA, 0x8C6A, 0xFBDF, + 0x8C6B, 0xE7E3, 0x8C79, 0xF8FB, 0x8C7A, 0xE3CF, 0x8C82, 0xF5B0, + 0x8C8A, 0xD8E7, 0x8C8C, 0xD9C9, 0x8C9D, 0xF8AF, 0x8C9E, 0xEFF6, + 0x8CA0, 0xDDB6, 0x8CA1, 0xEEAF, 0x8CA2, 0xCDF8, 0x8CA7, 0xDEB8, + 0x8CA8, 0xFCA7, 0x8CA9, 0xF7FC, 0x8CAA, 0xF7B1, 0x8CAB, 0xCEBB, + 0x8CAC, 0xF4A1, 0x8CAF, 0xEECD, 0x8CB0, 0xE1AE, 0x8CB3, 0xECC3, + 0x8CB4, 0xCFFE, 0x8CB6, 0xF8BF, 0x8CB7, 0xD8E2, 0x8CB8, 0xD3E8, + 0x8CBB, 0xDEA8, 0x8CBC, 0xF4E4, 0x8CBD, 0xECC2, 0x8CBF, 0xD9F5, + 0x8CC0, 0xF9C5, 0x8CC1, 0xDDD3, 0x8CC2, 0xD6F1, 0x8CC3, 0xECFC, + 0x8CC4, 0xFCF0, 0x8CC7, 0xEDC0, 0x8CC8, 0xCAB9, 0x8CCA, 0xEEE4, + 0x8CD1, 0xF2E1, 0x8CD3, 0xDEB9, 0x8CDA, 0xD6F2, 0x8CDC, 0xDEF4, + 0x8CDE, 0xDFDB, 0x8CE0, 0xDBD3, 0x8CE2, 0xFAE7, 0x8CE3, 0xD8E3, + 0x8CE4, 0xF4C1, 0x8CE6, 0xDDB7, 0x8CEA, 0xF2F5, 0x8CED, 0xD4AE, + 0x8CF4, 0xD6F3, 0x8CFB, 0xDDB8, 0x8CFC, 0xCFC5, 0x8CFD, 0xDFDF, + 0x8D04, 0xF2BE, 0x8D05, 0xF6A1, 0x8D07, 0xEBCB, 0x8D08, 0xF1FC, + 0x8D0A, 0xF3C7, 0x8D0D, 0xE0EB, 0x8D13, 0xEDFC, 0x8D16, 0xE1DB, + 0x8D64, 0xEEE5, 0x8D66, 0xDEF5, 0x8D6B, 0xFAD3, 0x8D70, 0xF1CB, + 0x8D73, 0xD0AF, 0x8D74, 0xDDB9, 0x8D77, 0xD1C3, 0x8D85, 0xF5B1, + 0x8D8A, 0xEAC6, 0x8D99, 0xF0E1, 0x8DA3, 0xF6AC, 0x8DA8, 0xF5D9, + 0x8DB3, 0xF0EB, 0x8DBA, 0xDDBA, 0x8DBE, 0xF2BF, 0x8DC6, 0xF7C5, + 0x8DCB, 0xDBA2, 0x8DCC, 0xF2F6, 0x8DCF, 0xCABA, 0x8DDB, 0xF7F5, + 0x8DDD, 0xCBE5, 0x8DE1, 0xEEE6, 0x8DE3, 0xE0D3, 0x8DE8, 0xCEA5, + 0x8DEF, 0xD6D8, 0x8DF3, 0xD4AF, 0x8E0A, 0xE9C9, 0x8E0F, 0xD3CE, + 0x8E10, 0xF4C2, 0x8E1E, 0xCBE6, 0x8E2A, 0xF1A1, 0x8E30, 0xEBB2, + 0x8E35, 0xF1A2, 0x8E42, 0xEBB3, 0x8E44, 0xF0B4, 0x8E47, 0xCBF4, + 0x8E48, 0xD4B0, 0x8E49, 0xF3B2, 0x8E4A, 0xFBB7, 0x8E59, 0xF5EC, + 0x8E5F, 0xEEE7, 0x8E60, 0xF4B2, 0x8E74, 0xF5ED, 0x8E76, 0xCFF3, + 0x8E81, 0xF0E2, 0x8E87, 0xEECE, 0x8E8A, 0xF1CC, 0x8E8D, 0xE5B8, + 0x8EAA, 0xD7F5, 0x8EAB, 0xE3F3, 0x8EAC, 0xCFE5, 0x8EC0, 0xCFC6, + 0x8ECA, 0xF3B3, 0x8ECB, 0xE4D8, 0x8ECC, 0xCFF9, 0x8ECD, 0xCFDA, + 0x8ED2, 0xFACD, 0x8EDF, 0xE6E3, 0x8EEB, 0xF2E2, 0x8EF8, 0xF5EE, + 0x8EFB, 0xCABB, 0x8EFE, 0xE3DC, 0x8F03, 0xCEF2, 0x8F05, 0xD6D9, + 0x8F09, 0xEEB0, 0x8F12, 0xF4E5, 0x8F13, 0xD8C2, 0x8F14, 0xDCD0, + 0x8F15, 0xCCEE, 0x8F1B, 0xD5E0, 0x8F1C, 0xF6CA, 0x8F1D, 0xFDCA, + 0x8F1E, 0xD8D6, 0x8F1F, 0xF4CF, 0x8F26, 0xD6A6, 0x8F27, 0xDCBE, + 0x8F29, 0xDBD4, 0x8F2A, 0xD7C7, 0x8F2F, 0xF2FE, 0x8F33, 0xF1CD, + 0x8F38, 0xE2C3, 0x8F39, 0xDCDE, 0x8F3B, 0xDCDF, 0x8F3E, 0xEFAD, + 0x8F3F, 0xE6AB, 0x8F44, 0xF9DD, 0x8F45, 0xEABF, 0x8F49, 0xEFAE, + 0x8F4D, 0xF4D0, 0x8F4E, 0xCEF3, 0x8F5D, 0xE6AC, 0x8F5F, 0xCEDE, + 0x8F62, 0xD5F9, 0x8F9B, 0xE3F4, 0x8F9C, 0xCDD0, 0x8FA3, 0xD5B8, + 0x8FA6, 0xF7FD, 0x8FA8, 0xDCA9, 0x8FAD, 0xDEF6, 0x8FAF, 0xDCAA, + 0x8FB0, 0xF2E3, 0x8FB1, 0xE9B4, 0x8FB2, 0xD2DC, 0x8FC2, 0xE9E6, + 0x8FC5, 0xE3F6, 0x8FCE, 0xE7CA, 0x8FD1, 0xD0CE, 0x8FD4, 0xDAF7, + 0x8FE6, 0xCABC, 0x8FEA, 0xEEE8, 0x8FEB, 0xDADE, 0x8FED, 0xF2F7, + 0x8FF0, 0xE2FB, 0x8FF2, 0xCCA6, 0x8FF7, 0xDABB, 0x8FF9, 0xEEE9, + 0x8FFD, 0xF5DA, 0x9000, 0xF7DC, 0x9001, 0xE1EA, 0x9002, 0xCEC1, + 0x9003, 0xD4B1, 0x9005, 0xFDB1, 0x9006, 0xE6BD, 0x9008, 0xFBAD, + 0x900B, 0xF8E7, 0x900D, 0xE1CE, 0x900F, 0xF7E2, 0x9010, 0xF5EF, + 0x9011, 0xCFC7, 0x9014, 0xD4B2, 0x9015, 0xCCEF, 0x9017, 0xD4E8, + 0x9019, 0xEECF, 0x901A, 0xF7D7, 0x901D, 0xE0A6, 0x901E, 0xD6C1, + 0x901F, 0xE1DC, 0x9020, 0xF0E3, 0x9021, 0xF1E4, 0x9022, 0xDCF1, + 0x9023, 0xD6A7, 0x902E, 0xF4F5, 0x9031, 0xF1CE, 0x9032, 0xF2E4, + 0x9035, 0xD0B0, 0x9038, 0xECEF, 0x903C, 0xF9BA, 0x903E, 0xEBB5, + 0x9041, 0xD4ED, 0x9042, 0xE2C4, 0x9047, 0xE9E7, 0x904A, 0xEBB4, + 0x904B, 0xEAA1, 0x904D, 0xF8BC, 0x904E, 0xCEA6, 0x9050, 0xF9C6, + 0x9051, 0xFCDA, 0x9053, 0xD4B3, 0x9054, 0xD3B9, 0x9055, 0xEADE, + 0x9059, 0xE9AB, 0x905C, 0xE1E1, 0x905D, 0xD3CF, 0x905E, 0xF4F6, + 0x9060, 0xEAC0, 0x9061, 0xE1CF, 0x9063, 0xCCBA, 0x9069, 0xEEEA, + 0x906D, 0xF0E4, 0x906E, 0xF3B4, 0x906F, 0xD4EE, 0x9072, 0xF2C0, + 0x9075, 0xF1E5, 0x9077, 0xF4C3, 0x9078, 0xE0D4, 0x907A, 0xEBB6, + 0x907C, 0xD7A1, 0x907D, 0xCBE8, 0x907F, 0xF9AD, 0x9080, 0xE9AD, + 0x9081, 0xD8E4, 0x9082, 0xFAB3, 0x9083, 0xE2C5, 0x9084, 0xFCBD, + 0x9087, 0xECC4, 0x9088, 0xD8B1, 0x908A, 0xDCAB, 0x908F, 0xD5A4, + 0x9091, 0xEBE9, 0x9095, 0xE8BB, 0x9099, 0xD8D7, 0x90A2, 0xFBAE, + 0x90A3, 0xD1E1, 0x90A6, 0xDBC0, 0x90A8, 0xF5BE, 0x90AA, 0xDEF7, + 0x90AF, 0xCAFB, 0x90B0, 0xF7C6, 0x90B1, 0xCFC8, 0x90B5, 0xE1D0, + 0x90B8, 0xEED0, 0x90C1, 0xE9F4, 0x90CA, 0xCEF4, 0x90DE, 0xD5CD, + 0x90E1, 0xCFDB, 0x90E8, 0xDDBB, 0x90ED, 0xCEAC, 0x90F5, 0xE9E8, + 0x90FD, 0xD4B4, 0x9102, 0xE4C7, 0x9112, 0xF5DB, 0x9115, 0xFAC1, + 0x9119, 0xDEA9, 0x9127, 0xD4F8, 0x912D, 0xEFF7, 0x9132, 0xD3B3, + 0x9149, 0xEBB7, 0x914A, 0xEFF8, 0x914B, 0xF5DC, 0x914C, 0xEDCC, + 0x914D, 0xDBD5, 0x914E, 0xF1CF, 0x9152, 0xF1D0, 0x9162, 0xF5B2, + 0x9169, 0xD9AE, 0x916A, 0xD5AC, 0x916C, 0xE2C6, 0x9175, 0xFDA3, + 0x9177, 0xFBE5, 0x9178, 0xDFAB, 0x9187, 0xE2F5, 0x9189, 0xF6AD, + 0x918B, 0xF5B3, 0x918D, 0xF0B5, 0x9192, 0xE1A5, 0x919C, 0xF5DD, + 0x91AB, 0xECA2, 0x91AC, 0xEDFD, 0x91AE, 0xF5B4, 0x91AF, 0xFBB8, + 0x91B1, 0xDBA3, 0x91B4, 0xD6CA, 0x91B5, 0xCBD9, 0x91C0, 0xE5D4, + 0x91C7, 0xF3FA, 0x91C9, 0xEBB8, 0x91CB, 0xE0B7, 0x91CC, 0xD7EC, + 0x91CD, 0xF1EC, 0x91CE, 0xE5AF, 0x91CF, 0xD5E1, 0x91D0, 0xD7ED, + 0x91D1, 0xD1D1, 0x91D7, 0xE1F2, 0x91D8, 0xEFF9, 0x91DC, 0xDDBC, + 0x91DD, 0xF6DC, 0x91E3, 0xF0E5, 0x91E7, 0xF4C4, 0x91EA, 0xE9E9, + 0x91F5, 0xF3FB, 0x920D, 0xD4EF, 0x9210, 0xCCA2, 0x9211, 0xF7FE, + 0x9212, 0xDFBC, 0x9217, 0xEBCD, 0x921E, 0xD0B7, 0x9234, 0xD6C2, + 0x923A, 0xE8AD, 0x923F, 0xEFAF, 0x9240, 0xCBA5, 0x9245, 0xCBE9, + 0x9249, 0xFAE8, 0x9257, 0xCCC6, 0x925B, 0xE6E7, 0x925E, 0xEAC7, + 0x9262, 0xDBA4, 0x9264, 0xCFC9, 0x9265, 0xE2FC, 0x9266, 0xEFFA, + 0x9280, 0xEBDE, 0x9283, 0xF5C8, 0x9285, 0xD4DE, 0x9291, 0xE0D5, + 0x9293, 0xEFB0, 0x9296, 0xE2C7, 0x9298, 0xD9AF, 0x929C, 0xF9E7, + 0x92B3, 0xE7E5, 0x92B6, 0xCFCA, 0x92B7, 0xE1D1, 0x92B9, 0xE2C8, + 0x92CC, 0xEFFB, 0x92CF, 0xFAF9, 0x92D2, 0xDCF2, 0x92E4, 0xE0A7, + 0x92EA, 0xF8E8, 0x92F8, 0xCBEA, 0x92FC, 0xCBBC, 0x9304, 0xD6E2, + 0x9310, 0xF5DE, 0x9318, 0xF5DF, 0x931A, 0xEEB6, 0x931E, 0xE2F6, + 0x931F, 0xD3CA, 0x9320, 0xEFFC, 0x9321, 0xD1C4, 0x9322, 0xEFB1, + 0x9324, 0xD1C5, 0x9326, 0xD0DE, 0x9328, 0xD9E1, 0x932B, 0xE0B8, + 0x932E, 0xCDD1, 0x932F, 0xF3B9, 0x9348, 0xE7CC, 0x934A, 0xD6A8, + 0x934B, 0xCEA7, 0x934D, 0xD4B5, 0x9354, 0xE4C8, 0x935B, 0xD3B4, + 0x936E, 0xEBB9, 0x9375, 0xCBF5, 0x937C, 0xF6DD, 0x937E, 0xF1A3, + 0x938C, 0xCCC7, 0x9394, 0xE9CA, 0x9396, 0xE1F0, 0x939A, 0xF5E0, + 0x93A3, 0xFBAF, 0x93A7, 0xCBD1, 0x93AC, 0xFBE0, 0x93AD, 0xF2E5, + 0x93B0, 0xECF0, 0x93C3, 0xF0EC, 0x93D1, 0xEEEB, 0x93DE, 0xE9CB, + 0x93E1, 0xCCF0, 0x93E4, 0xD7AF, 0x93F6, 0xF3A1, 0x9404, 0xFCF5, + 0x9418, 0xF1A4, 0x9425, 0xE0D6, 0x942B, 0xEFB2, 0x9435, 0xF4D1, + 0x9438, 0xF7A1, 0x9444, 0xF1D1, 0x9451, 0xCAFC, 0x9452, 0xCAFD, + 0x945B, 0xCECE, 0x947D, 0xF3C8, 0x947F, 0xF3BA, 0x9577, 0xEDFE, + 0x9580, 0xDAA6, 0x9583, 0xE0EC, 0x9589, 0xF8CD, 0x958B, 0xCBD2, + 0x958F, 0xEBCE, 0x9591, 0xF9D8, 0x9592, 0xF9D9, 0x9593, 0xCAE0, + 0x9594, 0xDACA, 0x9598, 0xCBA6, 0x95A3, 0xCAC8, 0x95A4, 0xF9EE, + 0x95A5, 0xDBEC, 0x95A8, 0xD0B1, 0x95AD, 0xD5EF, 0x95B1, 0xE6F3, + 0x95BB, 0xE7A2, 0x95BC, 0xE4D9, 0x95C7, 0xE4E1, 0x95CA, 0xFCC4, + 0x95D4, 0xF9EF, 0x95D5, 0xCFF4, 0x95D6, 0xF7E6, 0x95DC, 0xCEBC, + 0x95E1, 0xF4C5, 0x95E2, 0xDCA3, 0x961C, 0xDDBD, 0x9621, 0xF4C6, + 0x962A, 0xF8A1, 0x962E, 0xE8D6, 0x9632, 0xDBC1, 0x963B, 0xF0E6, + 0x963F, 0xE4B9, 0x9640, 0xF6ED, 0x9642, 0xF9AE, 0x9644, 0xDDBE, + 0x964B, 0xD7B0, 0x964C, 0xD8E8, 0x964D, 0xCBBD, 0x9650, 0xF9DA, + 0x965B, 0xF8CE, 0x965C, 0xF9F0, 0x965D, 0xE0ED, 0x965E, 0xE3B3, + 0x965F, 0xF4B3, 0x9662, 0xEAC2, 0x9663, 0xF2E6, 0x9664, 0xF0B6, + 0x966A, 0xDBD6, 0x9670, 0xEBE4, 0x9673, 0xF2E7, 0x9675, 0xD7D5, + 0x9676, 0xD4B6, 0x9677, 0xF9E8, 0x9678, 0xD7C1, 0x967D, 0xE5D5, + 0x9685, 0xE9EA, 0x9686, 0xD7CC, 0x968A, 0xD3E9, 0x968B, 0xE2C9, + 0x968D, 0xFCDB, 0x968E, 0xCDAD, 0x9694, 0xCCB0, 0x9695, 0xEAA2, + 0x9698, 0xE4F6, 0x9699, 0xD0C0, 0x969B, 0xF0B7, 0x969C, 0xEEA1, + 0x96A3, 0xD7F6, 0x96A7, 0xE2CA, 0x96A8, 0xE2CB, 0x96AA, 0xFACF, + 0x96B1, 0xEBDF, 0x96B7, 0xD6CB, 0x96BB, 0xF4B4, 0x96C0, 0xEDCD, + 0x96C1, 0xE4D2, 0x96C4, 0xEAA9, 0x96C5, 0xE4BA, 0x96C6, 0xF3A2, + 0x96C7, 0xCDD2, 0x96C9, 0xF6CB, 0x96CB, 0xF1E6, 0x96CC, 0xEDC1, + 0x96CD, 0xE8BC, 0x96CE, 0xEED1, 0x96D5, 0xF0E7, 0x96D6, 0xE2CC, + 0x96D9, 0xE4AA, 0x96DB, 0xF5E1, 0x96DC, 0xEDDA, 0x96E2, 0xD7EE, + 0x96E3, 0xD1F1, 0x96E8, 0xE9EB, 0x96E9, 0xE9EC, 0x96EA, 0xE0E4, + 0x96EF, 0xDAA7, 0x96F0, 0xDDD4, 0x96F2, 0xEAA3, 0x96F6, 0xD6C3, + 0x96F7, 0xD6F4, 0x96F9, 0xDADF, 0x96FB, 0xEFB3, 0x9700, 0xE2CD, + 0x9706, 0xEFFD, 0x9707, 0xF2E8, 0x9711, 0xEFC5, 0x9713, 0xE7E7, + 0x9716, 0xD7FD, 0x9719, 0xE7CE, 0x971C, 0xDFDC, 0x971E, 0xF9C7, + 0x9727, 0xD9F6, 0x9730, 0xDFAC, 0x9732, 0xD6DA, 0x9739, 0xDCA4, + 0x973D, 0xF0B8, 0x9742, 0xD5FA, 0x9744, 0xE4F7, 0x9748, 0xD6C4, + 0x9751, 0xF4EC, 0x9756, 0xEFFE, 0x975C, 0xF0A1, 0x975E, 0xDEAA, + 0x9761, 0xDABC, 0x9762, 0xD8FC, 0x9769, 0xFAD4, 0x976D, 0xECE5, + 0x9774, 0xFCA8, 0x9777, 0xECE6, 0x977A, 0xD8CB, 0x978B, 0xFBB9, + 0x978D, 0xE4D3, 0x978F, 0xCDF9, 0x97A0, 0xCFD3, 0x97A8, 0xCAEA, + 0x97AB, 0xCFD4, 0x97AD, 0xF8BD, 0x97C6, 0xF4C7, 0x97CB, 0xEADF, + 0x97D3, 0xF9DB, 0x97DC, 0xD4B7, 0x97F3, 0xEBE5, 0x97F6, 0xE1D2, + 0x97FB, 0xEAA4, 0x97FF, 0xFAC2, 0x9800, 0xFBE1, 0x9801, 0xFAED, + 0x9802, 0xF0A2, 0x9803, 0xCCF1, 0x9805, 0xFAA3, 0x9806, 0xE2F7, + 0x9808, 0xE2CE, 0x980A, 0xE9F5, 0x980C, 0xE1EB, 0x9810, 0xE7E8, + 0x9811, 0xE8D7, 0x9812, 0xDAF8, 0x9813, 0xD4CB, 0x9817, 0xF7F6, + 0x9818, 0xD6C5, 0x982D, 0xD4E9, 0x9830, 0xFAFA, 0x9838, 0xCCF2, + 0x9839, 0xF7DD, 0x983B, 0xDEBA, 0x9846, 0xCEA8, 0x984C, 0xF0B9, + 0x984D, 0xE4FE, 0x984E, 0xE4C9, 0x9854, 0xE4D4, 0x9858, 0xEAC3, + 0x985A, 0xEFB4, 0x985E, 0xD7BE, 0x9865, 0xFBE2, 0x9867, 0xCDD3, + 0x986B, 0xEFB5, 0x986F, 0xFAE9, 0x98A8, 0xF9A6, 0x98AF, 0xDFBD, + 0x98B1, 0xF7C7, 0x98C4, 0xF8FD, 0x98C7, 0xF8FC, 0x98DB, 0xDEAB, + 0x98DC, 0xDBE8, 0x98DF, 0xE3DD, 0x98E1, 0xE1E2, 0x98E2, 0xD1C6, + 0x98ED, 0xF6D0, 0x98EE, 0xEBE6, 0x98EF, 0xDAF9, 0x98F4, 0xECC7, + 0x98FC, 0xDEF8, 0x98FD, 0xF8E9, 0x98FE, 0xE3DE, 0x9903, 0xCEF5, + 0x9909, 0xFAC3, 0x990A, 0xE5D7, 0x990C, 0xECC8, 0x9910, 0xF3C9, + 0x9913, 0xE4BB, 0x9918, 0xE6AE, 0x991E, 0xEFB6, 0x9920, 0xDCBF, + 0x9928, 0xCEBD, 0x9945, 0xD8C3, 0x9949, 0xD0CF, 0x994B, 0xCFFA, + 0x994C, 0xF3CA, 0x994D, 0xE0D7, 0x9951, 0xD1C7, 0x9952, 0xE9AE, + 0x9954, 0xE8BD, 0x9957, 0xFAC4, 0x9996, 0xE2CF, 0x9999, 0xFAC5, + 0x999D, 0xF9B8, 0x99A5, 0xDCE0, 0x99A8, 0xFBB0, 0x99AC, 0xD8A9, + 0x99AD, 0xE5DF, 0x99AE, 0xF9A7, 0x99B1, 0xF6EE, 0x99B3, 0xF6CC, + 0x99B4, 0xE2F8, 0x99B9, 0xECF1, 0x99C1, 0xDAE0, 0x99D0, 0xF1D2, + 0x99D1, 0xD2CC, 0x99D2, 0xCFCB, 0x99D5, 0xCABD, 0x99D9, 0xDDBF, + 0x99DD, 0xF6EF, 0x99DF, 0xDEF9, 0x99ED, 0xFAB4, 0x99F1, 0xD5AD, + 0x99FF, 0xF1E7, 0x9A01, 0xDEBE, 0x9A08, 0xDCC0, 0x9A0E, 0xD1C8, + 0x9A0F, 0xD1C9, 0x9A19, 0xF8BE, 0x9A2B, 0xCBF6, 0x9A30, 0xD4F9, + 0x9A36, 0xF5E2, 0x9A37, 0xE1D3, 0x9A40, 0xD8E9, 0x9A43, 0xF8FE, + 0x9A45, 0xCFCC, 0x9A4D, 0xFDA4, 0x9A55, 0xCEF6, 0x9A57, 0xFAD0, + 0x9A5A, 0xCCF3, 0x9A5B, 0xE6BE, 0x9A5F, 0xF6AE, 0x9A62, 0xD5F0, + 0x9A65, 0xD1CA, 0x9A69, 0xFCBE, 0x9A6A, 0xD5F1, 0x9AA8, 0xCDE9, + 0x9AB8, 0xFAB5, 0x9AD3, 0xE2D0, 0x9AD4, 0xF4F7, 0x9AD8, 0xCDD4, + 0x9AE5, 0xE7A3, 0x9AEE, 0xDBA5, 0x9B1A, 0xE2D1, 0x9B27, 0xD7A2, + 0x9B2A, 0xF7E3, 0x9B31, 0xEAA6, 0x9B3C, 0xD0A1, 0x9B41, 0xCEDA, + 0x9B42, 0xFBEB, 0x9B43, 0xDBA6, 0x9B44, 0xDBDE, 0x9B45, 0xD8E5, + 0x9B4F, 0xEAE0, 0x9B54, 0xD8AA, 0x9B5A, 0xE5E0, 0x9B6F, 0xD6DB, + 0x9B8E, 0xEFC6, 0x9B91, 0xF8EA, 0x9B9F, 0xE4D5, 0x9BAB, 0xCEF7, + 0x9BAE, 0xE0D8, 0x9BC9, 0xD7EF, 0x9BD6, 0xF4ED, 0x9BE4, 0xCDE6, + 0x9BE8, 0xCCF4, 0x9C0D, 0xF5E3, 0x9C10, 0xE4CA, 0x9C12, 0xDCE1, + 0x9C15, 0xF9C8, 0x9C25, 0xFCBF, 0x9C32, 0xE8A7, 0x9C3B, 0xD8C4, + 0x9C47, 0xCBBE, 0x9C49, 0xDCAE, 0x9C57, 0xD7F7, 0x9CE5, 0xF0E8, + 0x9CE7, 0xDDC0, 0x9CE9, 0xCFCD, 0x9CF3, 0xDCF3, 0x9CF4, 0xD9B0, + 0x9CF6, 0xE6E9, 0x9D09, 0xE4BC, 0x9D1B, 0xEAC4, 0x9D26, 0xE4EC, + 0x9D28, 0xE4E5, 0x9D3B, 0xFBF8, 0x9D51, 0xCCBB, 0x9D5D, 0xE4BD, + 0x9D60, 0xCDDC, 0x9D61, 0xD9F7, 0x9D6C, 0xDDDF, 0x9D72, 0xEDCE, + 0x9DA9, 0xD9D0, 0x9DAF, 0xE5A3, 0x9DB4, 0xF9CD, 0x9DC4, 0xCDAE, + 0x9DD7, 0xCFCE, 0x9DF2, 0xF6AF, 0x9DF8, 0xFDD3, 0x9DF9, 0xEBED, + 0x9DFA, 0xD6DC, 0x9E1A, 0xE5A4, 0x9E1E, 0xD5B6, 0x9E75, 0xD6DD, + 0x9E79, 0xF9E9, 0x9E7D, 0xE7A4, 0x9E7F, 0xD6E3, 0x9E92, 0xD1CB, + 0x9E93, 0xD6E4, 0x9E97, 0xD5F2, 0x9E9D, 0xDEFA, 0x9E9F, 0xD7F8, + 0x9EA5, 0xD8EA, 0x9EB4, 0xCFD5, 0x9EB5, 0xD8FD, 0x9EBB, 0xD8AB, + 0x9EBE, 0xFDCB, 0x9EC3, 0xFCDC, 0x9ECD, 0xE0A8, 0x9ECE, 0xD5F3, + 0x9ED1, 0xFDD9, 0x9ED4, 0xCCA3, 0x9ED8, 0xD9F9, 0x9EDB, 0xD3EA, + 0x9EDC, 0xF5F5, 0x9EDE, 0xEFC7, 0x9EE8, 0xD3DA, 0x9EF4, 0xDABD, + 0x9F07, 0xE8A8, 0x9F08, 0xDCAF, 0x9F0E, 0xF0A3, 0x9F13, 0xCDD5, + 0x9F20, 0xE0A9, 0x9F3B, 0xDEAC, 0x9F4A, 0xF0BA, 0x9F4B, 0xEEB1, + 0x9F4E, 0xEEB2, 0x9F52, 0xF6CD, 0x9F5F, 0xEED2, 0x9F61, 0xD6C6, + 0x9F67, 0xE0E5, 0x9F6A, 0xF3BB, 0x9F6C, 0xE5E1, 0x9F77, 0xE4CB, + 0x9F8D, 0xD7A3, 0x9F90, 0xDBC2, 0x9F95, 0xCAFE, 0x9F9C, 0xCFCF, + 0xAC00, 0xB0A1, 0xAC01, 0xB0A2, 0xAC02, 0x8141, 0xAC03, 0x8142, + 0xAC04, 0xB0A3, 0xAC05, 0x8143, 0xAC06, 0x8144, 0xAC07, 0xB0A4, + 0xAC08, 0xB0A5, 0xAC09, 0xB0A6, 0xAC0A, 0xB0A7, 0xAC0B, 0x8145, + 0xAC0C, 0x8146, 0xAC0D, 0x8147, 0xAC0E, 0x8148, 0xAC0F, 0x8149, + 0xAC10, 0xB0A8, 0xAC11, 0xB0A9, 0xAC12, 0xB0AA, 0xAC13, 0xB0AB, + 0xAC14, 0xB0AC, 0xAC15, 0xB0AD, 0xAC16, 0xB0AE, 0xAC17, 0xB0AF, + 0xAC18, 0x814A, 0xAC19, 0xB0B0, 0xAC1A, 0xB0B1, 0xAC1B, 0xB0B2, + 0xAC1C, 0xB0B3, 0xAC1D, 0xB0B4, 0xAC1E, 0x814B, 0xAC1F, 0x814C, + 0xAC20, 0xB0B5, 0xAC21, 0x814D, 0xAC22, 0x814E, 0xAC23, 0x814F, + 0xAC24, 0xB0B6, 0xAC25, 0x8150, 0xAC26, 0x8151, 0xAC27, 0x8152, + 0xAC28, 0x8153, 0xAC29, 0x8154, 0xAC2A, 0x8155, 0xAC2B, 0x8156, + 0xAC2C, 0xB0B7, 0xAC2D, 0xB0B8, 0xAC2E, 0x8157, 0xAC2F, 0xB0B9, + 0xAC30, 0xB0BA, 0xAC31, 0xB0BB, 0xAC32, 0x8158, 0xAC33, 0x8159, + 0xAC34, 0x815A, 0xAC35, 0x8161, 0xAC36, 0x8162, 0xAC37, 0x8163, + 0xAC38, 0xB0BC, 0xAC39, 0xB0BD, 0xAC3A, 0x8164, 0xAC3B, 0x8165, + 0xAC3C, 0xB0BE, 0xAC3D, 0x8166, 0xAC3E, 0x8167, 0xAC3F, 0x8168, + 0xAC40, 0xB0BF, 0xAC41, 0x8169, 0xAC42, 0x816A, 0xAC43, 0x816B, + 0xAC44, 0x816C, 0xAC45, 0x816D, 0xAC46, 0x816E, 0xAC47, 0x816F, + 0xAC48, 0x8170, 0xAC49, 0x8171, 0xAC4A, 0x8172, 0xAC4B, 0xB0C0, + 0xAC4C, 0x8173, 0xAC4D, 0xB0C1, 0xAC4E, 0x8174, 0xAC4F, 0x8175, + 0xAC50, 0x8176, 0xAC51, 0x8177, 0xAC52, 0x8178, 0xAC53, 0x8179, + 0xAC54, 0xB0C2, 0xAC55, 0x817A, 0xAC56, 0x8181, 0xAC57, 0x8182, + 0xAC58, 0xB0C3, 0xAC59, 0x8183, 0xAC5A, 0x8184, 0xAC5B, 0x8185, + 0xAC5C, 0xB0C4, 0xAC5D, 0x8186, 0xAC5E, 0x8187, 0xAC5F, 0x8188, + 0xAC60, 0x8189, 0xAC61, 0x818A, 0xAC62, 0x818B, 0xAC63, 0x818C, + 0xAC64, 0x818D, 0xAC65, 0x818E, 0xAC66, 0x818F, 0xAC67, 0x8190, + 0xAC68, 0x8191, 0xAC69, 0x8192, 0xAC6A, 0x8193, 0xAC6B, 0x8194, + 0xAC6C, 0x8195, 0xAC6D, 0x8196, 0xAC6E, 0x8197, 0xAC6F, 0x8198, + 0xAC70, 0xB0C5, 0xAC71, 0xB0C6, 0xAC72, 0x8199, 0xAC73, 0x819A, + 0xAC74, 0xB0C7, 0xAC75, 0x819B, 0xAC76, 0x819C, 0xAC77, 0xB0C8, + 0xAC78, 0xB0C9, 0xAC79, 0x819D, 0xAC7A, 0xB0CA, 0xAC7B, 0x819E, + 0xAC7C, 0x819F, 0xAC7D, 0x81A0, 0xAC7E, 0x81A1, 0xAC7F, 0x81A2, + 0xAC80, 0xB0CB, 0xAC81, 0xB0CC, 0xAC82, 0x81A3, 0xAC83, 0xB0CD, + 0xAC84, 0xB0CE, 0xAC85, 0xB0CF, 0xAC86, 0xB0D0, 0xAC87, 0x81A4, + 0xAC88, 0x81A5, 0xAC89, 0xB0D1, 0xAC8A, 0xB0D2, 0xAC8B, 0xB0D3, + 0xAC8C, 0xB0D4, 0xAC8D, 0x81A6, 0xAC8E, 0x81A7, 0xAC8F, 0x81A8, + 0xAC90, 0xB0D5, 0xAC91, 0x81A9, 0xAC92, 0x81AA, 0xAC93, 0x81AB, + 0xAC94, 0xB0D6, 0xAC95, 0x81AC, 0xAC96, 0x81AD, 0xAC97, 0x81AE, + 0xAC98, 0x81AF, 0xAC99, 0x81B0, 0xAC9A, 0x81B1, 0xAC9B, 0x81B2, + 0xAC9C, 0xB0D7, 0xAC9D, 0xB0D8, 0xAC9E, 0x81B3, 0xAC9F, 0xB0D9, + 0xACA0, 0xB0DA, 0xACA1, 0xB0DB, 0xACA2, 0x81B4, 0xACA3, 0x81B5, + 0xACA4, 0x81B6, 0xACA5, 0x81B7, 0xACA6, 0x81B8, 0xACA7, 0x81B9, + 0xACA8, 0xB0DC, 0xACA9, 0xB0DD, 0xACAA, 0xB0DE, 0xACAB, 0x81BA, + 0xACAC, 0xB0DF, 0xACAD, 0x81BB, 0xACAE, 0x81BC, 0xACAF, 0xB0E0, + 0xACB0, 0xB0E1, 0xACB1, 0x81BD, 0xACB2, 0x81BE, 0xACB3, 0x81BF, + 0xACB4, 0x81C0, 0xACB5, 0x81C1, 0xACB6, 0x81C2, 0xACB7, 0x81C3, + 0xACB8, 0xB0E2, 0xACB9, 0xB0E3, 0xACBA, 0x81C4, 0xACBB, 0xB0E4, + 0xACBC, 0xB0E5, 0xACBD, 0xB0E6, 0xACBE, 0x81C5, 0xACBF, 0x81C6, + 0xACC0, 0x81C7, 0xACC1, 0xB0E7, 0xACC2, 0x81C8, 0xACC3, 0x81C9, + 0xACC4, 0xB0E8, 0xACC5, 0x81CA, 0xACC6, 0x81CB, 0xACC7, 0x81CC, + 0xACC8, 0xB0E9, 0xACC9, 0x81CD, 0xACCA, 0x81CE, 0xACCB, 0x81CF, + 0xACCC, 0xB0EA, 0xACCD, 0x81D0, 0xACCE, 0x81D1, 0xACCF, 0x81D2, + 0xACD0, 0x81D3, 0xACD1, 0x81D4, 0xACD2, 0x81D5, 0xACD3, 0x81D6, + 0xACD4, 0x81D7, 0xACD5, 0xB0EB, 0xACD6, 0x81D8, 0xACD7, 0xB0EC, + 0xACD8, 0x81D9, 0xACD9, 0x81DA, 0xACDA, 0x81DB, 0xACDB, 0x81DC, + 0xACDC, 0x81DD, 0xACDD, 0x81DE, 0xACDE, 0x81DF, 0xACDF, 0x81E0, + 0xACE0, 0xB0ED, 0xACE1, 0xB0EE, 0xACE2, 0x81E1, 0xACE3, 0x81E2, + 0xACE4, 0xB0EF, 0xACE5, 0x81E3, 0xACE6, 0x81E4, 0xACE7, 0xB0F0, + 0xACE8, 0xB0F1, 0xACE9, 0x81E5, 0xACEA, 0xB0F2, 0xACEB, 0x81E6, + 0xACEC, 0xB0F3, 0xACED, 0x81E7, 0xACEE, 0x81E8, 0xACEF, 0xB0F4, + 0xACF0, 0xB0F5, 0xACF1, 0xB0F6, 0xACF2, 0x81E9, 0xACF3, 0xB0F7, + 0xACF4, 0x81EA, 0xACF5, 0xB0F8, 0xACF6, 0xB0F9, 0xACF7, 0x81EB, + 0xACF8, 0x81EC, 0xACF9, 0x81ED, 0xACFA, 0x81EE, 0xACFB, 0x81EF, + 0xACFC, 0xB0FA, 0xACFD, 0xB0FB, 0xACFE, 0x81F0, 0xACFF, 0x81F1, + 0xAD00, 0xB0FC, 0xAD01, 0x81F2, 0xAD02, 0x81F3, 0xAD03, 0x81F4, + 0xAD04, 0xB0FD, 0xAD05, 0x81F5, 0xAD06, 0xB0FE, 0xAD07, 0x81F6, + 0xAD08, 0x81F7, 0xAD09, 0x81F8, 0xAD0A, 0x81F9, 0xAD0B, 0x81FA, + 0xAD0C, 0xB1A1, 0xAD0D, 0xB1A2, 0xAD0E, 0x81FB, 0xAD0F, 0xB1A3, + 0xAD10, 0x81FC, 0xAD11, 0xB1A4, 0xAD12, 0x81FD, 0xAD13, 0x81FE, + 0xAD14, 0x8241, 0xAD15, 0x8242, 0xAD16, 0x8243, 0xAD17, 0x8244, + 0xAD18, 0xB1A5, 0xAD19, 0x8245, 0xAD1A, 0x8246, 0xAD1B, 0x8247, + 0xAD1C, 0xB1A6, 0xAD1D, 0x8248, 0xAD1E, 0x8249, 0xAD1F, 0x824A, + 0xAD20, 0xB1A7, 0xAD21, 0x824B, 0xAD22, 0x824C, 0xAD23, 0x824D, + 0xAD24, 0x824E, 0xAD25, 0x824F, 0xAD26, 0x8250, 0xAD27, 0x8251, + 0xAD28, 0x8252, 0xAD29, 0xB1A8, 0xAD2A, 0x8253, 0xAD2B, 0x8254, + 0xAD2C, 0xB1A9, 0xAD2D, 0xB1AA, 0xAD2E, 0x8255, 0xAD2F, 0x8256, + 0xAD30, 0x8257, 0xAD31, 0x8258, 0xAD32, 0x8259, 0xAD33, 0x825A, + 0xAD34, 0xB1AB, 0xAD35, 0xB1AC, 0xAD36, 0x8261, 0xAD37, 0x8262, + 0xAD38, 0xB1AD, 0xAD39, 0x8263, 0xAD3A, 0x8264, 0xAD3B, 0x8265, + 0xAD3C, 0xB1AE, 0xAD3D, 0x8266, 0xAD3E, 0x8267, 0xAD3F, 0x8268, + 0xAD40, 0x8269, 0xAD41, 0x826A, 0xAD42, 0x826B, 0xAD43, 0x826C, + 0xAD44, 0xB1AF, 0xAD45, 0xB1B0, 0xAD46, 0x826D, 0xAD47, 0xB1B1, + 0xAD48, 0x826E, 0xAD49, 0xB1B2, 0xAD4A, 0x826F, 0xAD4B, 0x8270, + 0xAD4C, 0x8271, 0xAD4D, 0x8272, 0xAD4E, 0x8273, 0xAD4F, 0x8274, + 0xAD50, 0xB1B3, 0xAD51, 0x8275, 0xAD52, 0x8276, 0xAD53, 0x8277, + 0xAD54, 0xB1B4, 0xAD55, 0x8278, 0xAD56, 0x8279, 0xAD57, 0x827A, + 0xAD58, 0xB1B5, 0xAD59, 0x8281, 0xAD5A, 0x8282, 0xAD5B, 0x8283, + 0xAD5C, 0x8284, 0xAD5D, 0x8285, 0xAD5E, 0x8286, 0xAD5F, 0x8287, + 0xAD60, 0x8288, 0xAD61, 0xB1B6, 0xAD62, 0x8289, 0xAD63, 0xB1B7, + 0xAD64, 0x828A, 0xAD65, 0x828B, 0xAD66, 0x828C, 0xAD67, 0x828D, + 0xAD68, 0x828E, 0xAD69, 0x828F, 0xAD6A, 0x8290, 0xAD6B, 0x8291, + 0xAD6C, 0xB1B8, 0xAD6D, 0xB1B9, 0xAD6E, 0x8292, 0xAD6F, 0x8293, + 0xAD70, 0xB1BA, 0xAD71, 0x8294, 0xAD72, 0x8295, 0xAD73, 0xB1BB, + 0xAD74, 0xB1BC, 0xAD75, 0xB1BD, 0xAD76, 0xB1BE, 0xAD77, 0x8296, + 0xAD78, 0x8297, 0xAD79, 0x8298, 0xAD7A, 0x8299, 0xAD7B, 0xB1BF, + 0xAD7C, 0xB1C0, 0xAD7D, 0xB1C1, 0xAD7E, 0x829A, 0xAD7F, 0xB1C2, + 0xAD80, 0x829B, 0xAD81, 0xB1C3, 0xAD82, 0xB1C4, 0xAD83, 0x829C, + 0xAD84, 0x829D, 0xAD85, 0x829E, 0xAD86, 0x829F, 0xAD87, 0x82A0, + 0xAD88, 0xB1C5, 0xAD89, 0xB1C6, 0xAD8A, 0x82A1, 0xAD8B, 0x82A2, + 0xAD8C, 0xB1C7, 0xAD8D, 0x82A3, 0xAD8E, 0x82A4, 0xAD8F, 0x82A5, + 0xAD90, 0xB1C8, 0xAD91, 0x82A6, 0xAD92, 0x82A7, 0xAD93, 0x82A8, + 0xAD94, 0x82A9, 0xAD95, 0x82AA, 0xAD96, 0x82AB, 0xAD97, 0x82AC, + 0xAD98, 0x82AD, 0xAD99, 0x82AE, 0xAD9A, 0x82AF, 0xAD9B, 0x82B0, + 0xAD9C, 0xB1C9, 0xAD9D, 0xB1CA, 0xAD9E, 0x82B1, 0xAD9F, 0x82B2, + 0xADA0, 0x82B3, 0xADA1, 0x82B4, 0xADA2, 0x82B5, 0xADA3, 0x82B6, + 0xADA4, 0xB1CB, 0xADA5, 0x82B7, 0xADA6, 0x82B8, 0xADA7, 0x82B9, + 0xADA8, 0x82BA, 0xADA9, 0x82BB, 0xADAA, 0x82BC, 0xADAB, 0x82BD, + 0xADAC, 0x82BE, 0xADAD, 0x82BF, 0xADAE, 0x82C0, 0xADAF, 0x82C1, + 0xADB0, 0x82C2, 0xADB1, 0x82C3, 0xADB2, 0x82C4, 0xADB3, 0x82C5, + 0xADB4, 0x82C6, 0xADB5, 0x82C7, 0xADB6, 0x82C8, 0xADB7, 0xB1CC, + 0xADB8, 0x82C9, 0xADB9, 0x82CA, 0xADBA, 0x82CB, 0xADBB, 0x82CC, + 0xADBC, 0x82CD, 0xADBD, 0x82CE, 0xADBE, 0x82CF, 0xADBF, 0x82D0, + 0xADC0, 0xB1CD, 0xADC1, 0xB1CE, 0xADC2, 0x82D1, 0xADC3, 0x82D2, + 0xADC4, 0xB1CF, 0xADC5, 0x82D3, 0xADC6, 0x82D4, 0xADC7, 0x82D5, + 0xADC8, 0xB1D0, 0xADC9, 0x82D6, 0xADCA, 0x82D7, 0xADCB, 0x82D8, + 0xADCC, 0x82D9, 0xADCD, 0x82DA, 0xADCE, 0x82DB, 0xADCF, 0x82DC, + 0xADD0, 0xB1D1, 0xADD1, 0xB1D2, 0xADD2, 0x82DD, 0xADD3, 0xB1D3, + 0xADD4, 0x82DE, 0xADD5, 0x82DF, 0xADD6, 0x82E0, 0xADD7, 0x82E1, + 0xADD8, 0x82E2, 0xADD9, 0x82E3, 0xADDA, 0x82E4, 0xADDB, 0x82E5, + 0xADDC, 0xB1D4, 0xADDD, 0x82E6, 0xADDE, 0x82E7, 0xADDF, 0x82E8, + 0xADE0, 0xB1D5, 0xADE1, 0x82E9, 0xADE2, 0x82EA, 0xADE3, 0x82EB, + 0xADE4, 0xB1D6, 0xADE5, 0x82EC, 0xADE6, 0x82ED, 0xADE7, 0x82EE, + 0xADE8, 0x82EF, 0xADE9, 0x82F0, 0xADEA, 0x82F1, 0xADEB, 0x82F2, + 0xADEC, 0x82F3, 0xADED, 0x82F4, 0xADEE, 0x82F5, 0xADEF, 0x82F6, + 0xADF0, 0x82F7, 0xADF1, 0x82F8, 0xADF2, 0x82F9, 0xADF3, 0x82FA, + 0xADF4, 0x82FB, 0xADF5, 0x82FC, 0xADF6, 0x82FD, 0xADF7, 0x82FE, + 0xADF8, 0xB1D7, 0xADF9, 0xB1D8, 0xADFA, 0x8341, 0xADFB, 0x8342, + 0xADFC, 0xB1D9, 0xADFD, 0x8343, 0xADFE, 0x8344, 0xADFF, 0xB1DA, + 0xAE00, 0xB1DB, 0xAE01, 0xB1DC, 0xAE02, 0x8345, 0xAE03, 0x8346, + 0xAE04, 0x8347, 0xAE05, 0x8348, 0xAE06, 0x8349, 0xAE07, 0x834A, + 0xAE08, 0xB1DD, 0xAE09, 0xB1DE, 0xAE0A, 0x834B, 0xAE0B, 0xB1DF, + 0xAE0C, 0x834C, 0xAE0D, 0xB1E0, 0xAE0E, 0x834D, 0xAE0F, 0x834E, + 0xAE10, 0x834F, 0xAE11, 0x8350, 0xAE12, 0x8351, 0xAE13, 0x8352, + 0xAE14, 0xB1E1, 0xAE15, 0x8353, 0xAE16, 0x8354, 0xAE17, 0x8355, + 0xAE18, 0x8356, 0xAE19, 0x8357, 0xAE1A, 0x8358, 0xAE1B, 0x8359, + 0xAE1C, 0x835A, 0xAE1D, 0x8361, 0xAE1E, 0x8362, 0xAE1F, 0x8363, + 0xAE20, 0x8364, 0xAE21, 0x8365, 0xAE22, 0x8366, 0xAE23, 0x8367, + 0xAE24, 0x8368, 0xAE25, 0x8369, 0xAE26, 0x836A, 0xAE27, 0x836B, + 0xAE28, 0x836C, 0xAE29, 0x836D, 0xAE2A, 0x836E, 0xAE2B, 0x836F, + 0xAE2C, 0x8370, 0xAE2D, 0x8371, 0xAE2E, 0x8372, 0xAE2F, 0x8373, + 0xAE30, 0xB1E2, 0xAE31, 0xB1E3, 0xAE32, 0x8374, 0xAE33, 0x8375, + 0xAE34, 0xB1E4, 0xAE35, 0x8376, 0xAE36, 0x8377, 0xAE37, 0xB1E5, + 0xAE38, 0xB1E6, 0xAE39, 0x8378, 0xAE3A, 0xB1E7, 0xAE3B, 0x8379, + 0xAE3C, 0x837A, 0xAE3D, 0x8381, 0xAE3E, 0x8382, 0xAE3F, 0x8383, + 0xAE40, 0xB1E8, 0xAE41, 0xB1E9, 0xAE42, 0x8384, 0xAE43, 0xB1EA, + 0xAE44, 0x8385, 0xAE45, 0xB1EB, 0xAE46, 0xB1EC, 0xAE47, 0x8386, + 0xAE48, 0x8387, 0xAE49, 0x8388, 0xAE4A, 0xB1ED, 0xAE4B, 0x8389, + 0xAE4C, 0xB1EE, 0xAE4D, 0xB1EF, 0xAE4E, 0xB1F0, 0xAE4F, 0x838A, + 0xAE50, 0xB1F1, 0xAE51, 0x838B, 0xAE52, 0x838C, 0xAE53, 0x838D, + 0xAE54, 0xB1F2, 0xAE55, 0x838E, 0xAE56, 0xB1F3, 0xAE57, 0x838F, + 0xAE58, 0x8390, 0xAE59, 0x8391, 0xAE5A, 0x8392, 0xAE5B, 0x8393, + 0xAE5C, 0xB1F4, 0xAE5D, 0xB1F5, 0xAE5E, 0x8394, 0xAE5F, 0xB1F6, + 0xAE60, 0xB1F7, 0xAE61, 0xB1F8, 0xAE62, 0x8395, 0xAE63, 0x8396, + 0xAE64, 0x8397, 0xAE65, 0xB1F9, 0xAE66, 0x8398, 0xAE67, 0x8399, + 0xAE68, 0xB1FA, 0xAE69, 0xB1FB, 0xAE6A, 0x839A, 0xAE6B, 0x839B, + 0xAE6C, 0xB1FC, 0xAE6D, 0x839C, 0xAE6E, 0x839D, 0xAE6F, 0x839E, + 0xAE70, 0xB1FD, 0xAE71, 0x839F, 0xAE72, 0x83A0, 0xAE73, 0x83A1, + 0xAE74, 0x83A2, 0xAE75, 0x83A3, 0xAE76, 0x83A4, 0xAE77, 0x83A5, + 0xAE78, 0xB1FE, 0xAE79, 0xB2A1, 0xAE7A, 0x83A6, 0xAE7B, 0xB2A2, + 0xAE7C, 0xB2A3, 0xAE7D, 0xB2A4, 0xAE7E, 0x83A7, 0xAE7F, 0x83A8, + 0xAE80, 0x83A9, 0xAE81, 0x83AA, 0xAE82, 0x83AB, 0xAE83, 0x83AC, + 0xAE84, 0xB2A5, 0xAE85, 0xB2A6, 0xAE86, 0x83AD, 0xAE87, 0x83AE, + 0xAE88, 0x83AF, 0xAE89, 0x83B0, 0xAE8A, 0x83B1, 0xAE8B, 0x83B2, + 0xAE8C, 0xB2A7, 0xAE8D, 0x83B3, 0xAE8E, 0x83B4, 0xAE8F, 0x83B5, + 0xAE90, 0x83B6, 0xAE91, 0x83B7, 0xAE92, 0x83B8, 0xAE93, 0x83B9, + 0xAE94, 0x83BA, 0xAE95, 0x83BB, 0xAE96, 0x83BC, 0xAE97, 0x83BD, + 0xAE98, 0x83BE, 0xAE99, 0x83BF, 0xAE9A, 0x83C0, 0xAE9B, 0x83C1, + 0xAE9C, 0x83C2, 0xAE9D, 0x83C3, 0xAE9E, 0x83C4, 0xAE9F, 0x83C5, + 0xAEA0, 0x83C6, 0xAEA1, 0x83C7, 0xAEA2, 0x83C8, 0xAEA3, 0x83C9, + 0xAEA4, 0x83CA, 0xAEA5, 0x83CB, 0xAEA6, 0x83CC, 0xAEA7, 0x83CD, + 0xAEA8, 0x83CE, 0xAEA9, 0x83CF, 0xAEAA, 0x83D0, 0xAEAB, 0x83D1, + 0xAEAC, 0x83D2, 0xAEAD, 0x83D3, 0xAEAE, 0x83D4, 0xAEAF, 0x83D5, + 0xAEB0, 0x83D6, 0xAEB1, 0x83D7, 0xAEB2, 0x83D8, 0xAEB3, 0x83D9, + 0xAEB4, 0x83DA, 0xAEB5, 0x83DB, 0xAEB6, 0x83DC, 0xAEB7, 0x83DD, + 0xAEB8, 0x83DE, 0xAEB9, 0x83DF, 0xAEBA, 0x83E0, 0xAEBB, 0x83E1, + 0xAEBC, 0xB2A8, 0xAEBD, 0xB2A9, 0xAEBE, 0xB2AA, 0xAEBF, 0x83E2, + 0xAEC0, 0xB2AB, 0xAEC1, 0x83E3, 0xAEC2, 0x83E4, 0xAEC3, 0x83E5, + 0xAEC4, 0xB2AC, 0xAEC5, 0x83E6, 0xAEC6, 0x83E7, 0xAEC7, 0x83E8, + 0xAEC8, 0x83E9, 0xAEC9, 0x83EA, 0xAECA, 0x83EB, 0xAECB, 0x83EC, + 0xAECC, 0xB2AD, 0xAECD, 0xB2AE, 0xAECE, 0x83ED, 0xAECF, 0xB2AF, + 0xAED0, 0xB2B0, 0xAED1, 0xB2B1, 0xAED2, 0x83EE, 0xAED3, 0x83EF, + 0xAED4, 0x83F0, 0xAED5, 0x83F1, 0xAED6, 0x83F2, 0xAED7, 0x83F3, + 0xAED8, 0xB2B2, 0xAED9, 0xB2B3, 0xAEDA, 0x83F4, 0xAEDB, 0x83F5, + 0xAEDC, 0xB2B4, 0xAEDD, 0x83F6, 0xAEDE, 0x83F7, 0xAEDF, 0x83F8, + 0xAEE0, 0x83F9, 0xAEE1, 0x83FA, 0xAEE2, 0x83FB, 0xAEE3, 0x83FC, + 0xAEE4, 0x83FD, 0xAEE5, 0x83FE, 0xAEE6, 0x8441, 0xAEE7, 0x8442, + 0xAEE8, 0xB2B5, 0xAEE9, 0x8443, 0xAEEA, 0x8444, 0xAEEB, 0xB2B6, + 0xAEEC, 0x8445, 0xAEED, 0xB2B7, 0xAEEE, 0x8446, 0xAEEF, 0x8447, + 0xAEF0, 0x8448, 0xAEF1, 0x8449, 0xAEF2, 0x844A, 0xAEF3, 0x844B, + 0xAEF4, 0xB2B8, 0xAEF5, 0x844C, 0xAEF6, 0x844D, 0xAEF7, 0x844E, + 0xAEF8, 0xB2B9, 0xAEF9, 0x844F, 0xAEFA, 0x8450, 0xAEFB, 0x8451, + 0xAEFC, 0xB2BA, 0xAEFD, 0x8452, 0xAEFE, 0x8453, 0xAEFF, 0x8454, + 0xAF00, 0x8455, 0xAF01, 0x8456, 0xAF02, 0x8457, 0xAF03, 0x8458, + 0xAF04, 0x8459, 0xAF05, 0x845A, 0xAF06, 0x8461, 0xAF07, 0xB2BB, + 0xAF08, 0xB2BC, 0xAF09, 0x8462, 0xAF0A, 0x8463, 0xAF0B, 0x8464, + 0xAF0C, 0x8465, 0xAF0D, 0xB2BD, 0xAF0E, 0x8466, 0xAF0F, 0x8467, + 0xAF10, 0xB2BE, 0xAF11, 0x8468, 0xAF12, 0x8469, 0xAF13, 0x846A, + 0xAF14, 0x846B, 0xAF15, 0x846C, 0xAF16, 0x846D, 0xAF17, 0x846E, + 0xAF18, 0x846F, 0xAF19, 0x8470, 0xAF1A, 0x8471, 0xAF1B, 0x8472, + 0xAF1C, 0x8473, 0xAF1D, 0x8474, 0xAF1E, 0x8475, 0xAF1F, 0x8476, + 0xAF20, 0x8477, 0xAF21, 0x8478, 0xAF22, 0x8479, 0xAF23, 0x847A, + 0xAF24, 0x8481, 0xAF25, 0x8482, 0xAF26, 0x8483, 0xAF27, 0x8484, + 0xAF28, 0x8485, 0xAF29, 0x8486, 0xAF2A, 0x8487, 0xAF2B, 0x8488, + 0xAF2C, 0xB2BF, 0xAF2D, 0xB2C0, 0xAF2E, 0x8489, 0xAF2F, 0x848A, + 0xAF30, 0xB2C1, 0xAF31, 0x848B, 0xAF32, 0xB2C2, 0xAF33, 0x848C, + 0xAF34, 0xB2C3, 0xAF35, 0x848D, 0xAF36, 0x848E, 0xAF37, 0x848F, + 0xAF38, 0x8490, 0xAF39, 0x8491, 0xAF3A, 0x8492, 0xAF3B, 0x8493, + 0xAF3C, 0xB2C4, 0xAF3D, 0xB2C5, 0xAF3E, 0x8494, 0xAF3F, 0xB2C6, + 0xAF40, 0x8495, 0xAF41, 0xB2C7, 0xAF42, 0xB2C8, 0xAF43, 0xB2C9, + 0xAF44, 0x8496, 0xAF45, 0x8497, 0xAF46, 0x8498, 0xAF47, 0x8499, + 0xAF48, 0xB2CA, 0xAF49, 0xB2CB, 0xAF4A, 0x849A, 0xAF4B, 0x849B, + 0xAF4C, 0x849C, 0xAF4D, 0x849D, 0xAF4E, 0x849E, 0xAF4F, 0x849F, + 0xAF50, 0xB2CC, 0xAF51, 0x84A0, 0xAF52, 0x84A1, 0xAF53, 0x84A2, + 0xAF54, 0x84A3, 0xAF55, 0x84A4, 0xAF56, 0x84A5, 0xAF57, 0x84A6, + 0xAF58, 0x84A7, 0xAF59, 0x84A8, 0xAF5A, 0x84A9, 0xAF5B, 0x84AA, + 0xAF5C, 0xB2CD, 0xAF5D, 0xB2CE, 0xAF5E, 0x84AB, 0xAF5F, 0x84AC, + 0xAF60, 0x84AD, 0xAF61, 0x84AE, 0xAF62, 0x84AF, 0xAF63, 0x84B0, + 0xAF64, 0xB2CF, 0xAF65, 0xB2D0, 0xAF66, 0x84B1, 0xAF67, 0x84B2, + 0xAF68, 0x84B3, 0xAF69, 0x84B4, 0xAF6A, 0x84B5, 0xAF6B, 0x84B6, + 0xAF6C, 0x84B7, 0xAF6D, 0x84B8, 0xAF6E, 0x84B9, 0xAF6F, 0x84BA, + 0xAF70, 0x84BB, 0xAF71, 0x84BC, 0xAF72, 0x84BD, 0xAF73, 0x84BE, + 0xAF74, 0x84BF, 0xAF75, 0x84C0, 0xAF76, 0x84C1, 0xAF77, 0x84C2, + 0xAF78, 0x84C3, 0xAF79, 0xB2D1, 0xAF7A, 0x84C4, 0xAF7B, 0x84C5, + 0xAF7C, 0x84C6, 0xAF7D, 0x84C7, 0xAF7E, 0x84C8, 0xAF7F, 0x84C9, + 0xAF80, 0xB2D2, 0xAF81, 0x84CA, 0xAF82, 0x84CB, 0xAF83, 0x84CC, + 0xAF84, 0xB2D3, 0xAF85, 0x84CD, 0xAF86, 0x84CE, 0xAF87, 0x84CF, + 0xAF88, 0xB2D4, 0xAF89, 0x84D0, 0xAF8A, 0x84D1, 0xAF8B, 0x84D2, + 0xAF8C, 0x84D3, 0xAF8D, 0x84D4, 0xAF8E, 0x84D5, 0xAF8F, 0x84D6, + 0xAF90, 0xB2D5, 0xAF91, 0xB2D6, 0xAF92, 0x84D7, 0xAF93, 0x84D8, + 0xAF94, 0x84D9, 0xAF95, 0xB2D7, 0xAF96, 0x84DA, 0xAF97, 0x84DB, + 0xAF98, 0x84DC, 0xAF99, 0x84DD, 0xAF9A, 0x84DE, 0xAF9B, 0x84DF, + 0xAF9C, 0xB2D8, 0xAF9D, 0x84E0, 0xAF9E, 0x84E1, 0xAF9F, 0x84E2, + 0xAFA0, 0x84E3, 0xAFA1, 0x84E4, 0xAFA2, 0x84E5, 0xAFA3, 0x84E6, + 0xAFA4, 0x84E7, 0xAFA5, 0x84E8, 0xAFA6, 0x84E9, 0xAFA7, 0x84EA, + 0xAFA8, 0x84EB, 0xAFA9, 0x84EC, 0xAFAA, 0x84ED, 0xAFAB, 0x84EE, + 0xAFAC, 0x84EF, 0xAFAD, 0x84F0, 0xAFAE, 0x84F1, 0xAFAF, 0x84F2, + 0xAFB0, 0x84F3, 0xAFB1, 0x84F4, 0xAFB2, 0x84F5, 0xAFB3, 0x84F6, + 0xAFB4, 0x84F7, 0xAFB5, 0x84F8, 0xAFB6, 0x84F9, 0xAFB7, 0x84FA, + 0xAFB8, 0xB2D9, 0xAFB9, 0xB2DA, 0xAFBA, 0x84FB, 0xAFBB, 0x84FC, + 0xAFBC, 0xB2DB, 0xAFBD, 0x84FD, 0xAFBE, 0x84FE, 0xAFBF, 0x8541, + 0xAFC0, 0xB2DC, 0xAFC1, 0x8542, 0xAFC2, 0x8543, 0xAFC3, 0x8544, + 0xAFC4, 0x8545, 0xAFC5, 0x8546, 0xAFC6, 0x8547, 0xAFC7, 0xB2DD, + 0xAFC8, 0xB2DE, 0xAFC9, 0xB2DF, 0xAFCA, 0x8548, 0xAFCB, 0xB2E0, + 0xAFCC, 0x8549, 0xAFCD, 0xB2E1, 0xAFCE, 0xB2E2, 0xAFCF, 0x854A, + 0xAFD0, 0x854B, 0xAFD1, 0x854C, 0xAFD2, 0x854D, 0xAFD3, 0x854E, + 0xAFD4, 0xB2E3, 0xAFD5, 0x854F, 0xAFD6, 0x8550, 0xAFD7, 0x8551, + 0xAFD8, 0x8552, 0xAFD9, 0x8553, 0xAFDA, 0x8554, 0xAFDB, 0x8555, + 0xAFDC, 0xB2E4, 0xAFDD, 0x8556, 0xAFDE, 0x8557, 0xAFDF, 0x8558, + 0xAFE0, 0x8559, 0xAFE1, 0x855A, 0xAFE2, 0x8561, 0xAFE3, 0x8562, + 0xAFE4, 0x8563, 0xAFE5, 0x8564, 0xAFE6, 0x8565, 0xAFE7, 0x8566, + 0xAFE8, 0xB2E5, 0xAFE9, 0xB2E6, 0xAFEA, 0x8567, 0xAFEB, 0x8568, + 0xAFEC, 0x8569, 0xAFED, 0x856A, 0xAFEE, 0x856B, 0xAFEF, 0x856C, + 0xAFF0, 0xB2E7, 0xAFF1, 0xB2E8, 0xAFF2, 0x856D, 0xAFF3, 0x856E, + 0xAFF4, 0xB2E9, 0xAFF5, 0x856F, 0xAFF6, 0x8570, 0xAFF7, 0x8571, + 0xAFF8, 0xB2EA, 0xAFF9, 0x8572, 0xAFFA, 0x8573, 0xAFFB, 0x8574, + 0xAFFC, 0x8575, 0xAFFD, 0x8576, 0xAFFE, 0x8577, 0xAFFF, 0x8578, + 0xB000, 0xB2EB, 0xB001, 0xB2EC, 0xB002, 0x8579, 0xB003, 0x857A, + 0xB004, 0xB2ED, 0xB005, 0x8581, 0xB006, 0x8582, 0xB007, 0x8583, + 0xB008, 0x8584, 0xB009, 0x8585, 0xB00A, 0x8586, 0xB00B, 0x8587, + 0xB00C, 0xB2EE, 0xB00D, 0x8588, 0xB00E, 0x8589, 0xB00F, 0x858A, + 0xB010, 0xB2EF, 0xB011, 0x858B, 0xB012, 0x858C, 0xB013, 0x858D, + 0xB014, 0xB2F0, 0xB015, 0x858E, 0xB016, 0x858F, 0xB017, 0x8590, + 0xB018, 0x8591, 0xB019, 0x8592, 0xB01A, 0x8593, 0xB01B, 0x8594, + 0xB01C, 0xB2F1, 0xB01D, 0xB2F2, 0xB01E, 0x8595, 0xB01F, 0x8596, + 0xB020, 0x8597, 0xB021, 0x8598, 0xB022, 0x8599, 0xB023, 0x859A, + 0xB024, 0x859B, 0xB025, 0x859C, 0xB026, 0x859D, 0xB027, 0x859E, + 0xB028, 0xB2F3, 0xB029, 0x859F, 0xB02A, 0x85A0, 0xB02B, 0x85A1, + 0xB02C, 0x85A2, 0xB02D, 0x85A3, 0xB02E, 0x85A4, 0xB02F, 0x85A5, + 0xB030, 0x85A6, 0xB031, 0x85A7, 0xB032, 0x85A8, 0xB033, 0x85A9, + 0xB034, 0x85AA, 0xB035, 0x85AB, 0xB036, 0x85AC, 0xB037, 0x85AD, + 0xB038, 0x85AE, 0xB039, 0x85AF, 0xB03A, 0x85B0, 0xB03B, 0x85B1, + 0xB03C, 0x85B2, 0xB03D, 0x85B3, 0xB03E, 0x85B4, 0xB03F, 0x85B5, + 0xB040, 0x85B6, 0xB041, 0x85B7, 0xB042, 0x85B8, 0xB043, 0x85B9, + 0xB044, 0xB2F4, 0xB045, 0xB2F5, 0xB046, 0x85BA, 0xB047, 0x85BB, + 0xB048, 0xB2F6, 0xB049, 0x85BC, 0xB04A, 0xB2F7, 0xB04B, 0x85BD, + 0xB04C, 0xB2F8, 0xB04D, 0x85BE, 0xB04E, 0xB2F9, 0xB04F, 0x85BF, + 0xB050, 0x85C0, 0xB051, 0x85C1, 0xB052, 0x85C2, 0xB053, 0xB2FA, + 0xB054, 0xB2FB, 0xB055, 0xB2FC, 0xB056, 0x85C3, 0xB057, 0xB2FD, + 0xB058, 0x85C4, 0xB059, 0xB2FE, 0xB05A, 0x85C5, 0xB05B, 0x85C6, + 0xB05C, 0x85C7, 0xB05D, 0xB3A1, 0xB05E, 0x85C8, 0xB05F, 0x85C9, + 0xB060, 0x85CA, 0xB061, 0x85CB, 0xB062, 0x85CC, 0xB063, 0x85CD, + 0xB064, 0x85CE, 0xB065, 0x85CF, 0xB066, 0x85D0, 0xB067, 0x85D1, + 0xB068, 0x85D2, 0xB069, 0x85D3, 0xB06A, 0x85D4, 0xB06B, 0x85D5, + 0xB06C, 0x85D6, 0xB06D, 0x85D7, 0xB06E, 0x85D8, 0xB06F, 0x85D9, + 0xB070, 0x85DA, 0xB071, 0x85DB, 0xB072, 0x85DC, 0xB073, 0x85DD, + 0xB074, 0x85DE, 0xB075, 0x85DF, 0xB076, 0x85E0, 0xB077, 0x85E1, + 0xB078, 0x85E2, 0xB079, 0x85E3, 0xB07A, 0x85E4, 0xB07B, 0x85E5, + 0xB07C, 0xB3A2, 0xB07D, 0xB3A3, 0xB07E, 0x85E6, 0xB07F, 0x85E7, + 0xB080, 0xB3A4, 0xB081, 0x85E8, 0xB082, 0x85E9, 0xB083, 0x85EA, + 0xB084, 0xB3A5, 0xB085, 0x85EB, 0xB086, 0x85EC, 0xB087, 0x85ED, + 0xB088, 0x85EE, 0xB089, 0x85EF, 0xB08A, 0x85F0, 0xB08B, 0x85F1, + 0xB08C, 0xB3A6, 0xB08D, 0xB3A7, 0xB08E, 0x85F2, 0xB08F, 0xB3A8, + 0xB090, 0x85F3, 0xB091, 0xB3A9, 0xB092, 0x85F4, 0xB093, 0x85F5, + 0xB094, 0x85F6, 0xB095, 0x85F7, 0xB096, 0x85F8, 0xB097, 0x85F9, + 0xB098, 0xB3AA, 0xB099, 0xB3AB, 0xB09A, 0xB3AC, 0xB09B, 0x85FA, + 0xB09C, 0xB3AD, 0xB09D, 0x85FB, 0xB09E, 0x85FC, 0xB09F, 0xB3AE, + 0xB0A0, 0xB3AF, 0xB0A1, 0xB3B0, 0xB0A2, 0xB3B1, 0xB0A3, 0x85FD, + 0xB0A4, 0x85FE, 0xB0A5, 0x8641, 0xB0A6, 0x8642, 0xB0A7, 0x8643, + 0xB0A8, 0xB3B2, 0xB0A9, 0xB3B3, 0xB0AA, 0x8644, 0xB0AB, 0xB3B4, + 0xB0AC, 0xB3B5, 0xB0AD, 0xB3B6, 0xB0AE, 0xB3B7, 0xB0AF, 0xB3B8, + 0xB0B0, 0x8645, 0xB0B1, 0xB3B9, 0xB0B2, 0x8646, 0xB0B3, 0xB3BA, + 0xB0B4, 0xB3BB, 0xB0B5, 0xB3BC, 0xB0B6, 0x8647, 0xB0B7, 0x8648, + 0xB0B8, 0xB3BD, 0xB0B9, 0x8649, 0xB0BA, 0x864A, 0xB0BB, 0x864B, + 0xB0BC, 0xB3BE, 0xB0BD, 0x864C, 0xB0BE, 0x864D, 0xB0BF, 0x864E, + 0xB0C0, 0x864F, 0xB0C1, 0x8650, 0xB0C2, 0x8651, 0xB0C3, 0x8652, + 0xB0C4, 0xB3BF, 0xB0C5, 0xB3C0, 0xB0C6, 0x8653, 0xB0C7, 0xB3C1, + 0xB0C8, 0xB3C2, 0xB0C9, 0xB3C3, 0xB0CA, 0x8654, 0xB0CB, 0x8655, + 0xB0CC, 0x8656, 0xB0CD, 0x8657, 0xB0CE, 0x8658, 0xB0CF, 0x8659, + 0xB0D0, 0xB3C4, 0xB0D1, 0xB3C5, 0xB0D2, 0x865A, 0xB0D3, 0x8661, + 0xB0D4, 0xB3C6, 0xB0D5, 0x8662, 0xB0D6, 0x8663, 0xB0D7, 0x8664, + 0xB0D8, 0xB3C7, 0xB0D9, 0x8665, 0xB0DA, 0x8666, 0xB0DB, 0x8667, + 0xB0DC, 0x8668, 0xB0DD, 0x8669, 0xB0DE, 0x866A, 0xB0DF, 0x866B, + 0xB0E0, 0xB3C8, 0xB0E1, 0x866C, 0xB0E2, 0x866D, 0xB0E3, 0x866E, + 0xB0E4, 0x866F, 0xB0E5, 0xB3C9, 0xB0E6, 0x8670, 0xB0E7, 0x8671, + 0xB0E8, 0x8672, 0xB0E9, 0x8673, 0xB0EA, 0x8674, 0xB0EB, 0x8675, + 0xB0EC, 0x8676, 0xB0ED, 0x8677, 0xB0EE, 0x8678, 0xB0EF, 0x8679, + 0xB0F0, 0x867A, 0xB0F1, 0x8681, 0xB0F2, 0x8682, 0xB0F3, 0x8683, + 0xB0F4, 0x8684, 0xB0F5, 0x8685, 0xB0F6, 0x8686, 0xB0F7, 0x8687, + 0xB0F8, 0x8688, 0xB0F9, 0x8689, 0xB0FA, 0x868A, 0xB0FB, 0x868B, + 0xB0FC, 0x868C, 0xB0FD, 0x868D, 0xB0FE, 0x868E, 0xB0FF, 0x868F, + 0xB100, 0x8690, 0xB101, 0x8691, 0xB102, 0x8692, 0xB103, 0x8693, + 0xB104, 0x8694, 0xB105, 0x8695, 0xB106, 0x8696, 0xB107, 0x8697, + 0xB108, 0xB3CA, 0xB109, 0xB3CB, 0xB10A, 0x8698, 0xB10B, 0xB3CC, + 0xB10C, 0xB3CD, 0xB10D, 0x8699, 0xB10E, 0x869A, 0xB10F, 0x869B, + 0xB110, 0xB3CE, 0xB111, 0x869C, 0xB112, 0xB3CF, 0xB113, 0xB3D0, + 0xB114, 0x869D, 0xB115, 0x869E, 0xB116, 0x869F, 0xB117, 0x86A0, + 0xB118, 0xB3D1, 0xB119, 0xB3D2, 0xB11A, 0x86A1, 0xB11B, 0xB3D3, + 0xB11C, 0xB3D4, 0xB11D, 0xB3D5, 0xB11E, 0x86A2, 0xB11F, 0x86A3, + 0xB120, 0x86A4, 0xB121, 0x86A5, 0xB122, 0x86A6, 0xB123, 0xB3D6, + 0xB124, 0xB3D7, 0xB125, 0xB3D8, 0xB126, 0x86A7, 0xB127, 0x86A8, + 0xB128, 0xB3D9, 0xB129, 0x86A9, 0xB12A, 0x86AA, 0xB12B, 0x86AB, + 0xB12C, 0xB3DA, 0xB12D, 0x86AC, 0xB12E, 0x86AD, 0xB12F, 0x86AE, + 0xB130, 0x86AF, 0xB131, 0x86B0, 0xB132, 0x86B1, 0xB133, 0x86B2, + 0xB134, 0xB3DB, 0xB135, 0xB3DC, 0xB136, 0x86B3, 0xB137, 0xB3DD, + 0xB138, 0xB3DE, 0xB139, 0xB3DF, 0xB13A, 0x86B4, 0xB13B, 0x86B5, + 0xB13C, 0x86B6, 0xB13D, 0x86B7, 0xB13E, 0x86B8, 0xB13F, 0x86B9, + 0xB140, 0xB3E0, 0xB141, 0xB3E1, 0xB142, 0x86BA, 0xB143, 0x86BB, + 0xB144, 0xB3E2, 0xB145, 0x86BC, 0xB146, 0x86BD, 0xB147, 0x86BE, + 0xB148, 0xB3E3, 0xB149, 0x86BF, 0xB14A, 0x86C0, 0xB14B, 0x86C1, + 0xB14C, 0x86C2, 0xB14D, 0x86C3, 0xB14E, 0x86C4, 0xB14F, 0x86C5, + 0xB150, 0xB3E4, 0xB151, 0xB3E5, 0xB152, 0x86C6, 0xB153, 0x86C7, + 0xB154, 0xB3E6, 0xB155, 0xB3E7, 0xB156, 0x86C8, 0xB157, 0x86C9, + 0xB158, 0xB3E8, 0xB159, 0x86CA, 0xB15A, 0x86CB, 0xB15B, 0x86CC, + 0xB15C, 0xB3E9, 0xB15D, 0x86CD, 0xB15E, 0x86CE, 0xB15F, 0x86CF, + 0xB160, 0xB3EA, 0xB161, 0x86D0, 0xB162, 0x86D1, 0xB163, 0x86D2, + 0xB164, 0x86D3, 0xB165, 0x86D4, 0xB166, 0x86D5, 0xB167, 0x86D6, + 0xB168, 0x86D7, 0xB169, 0x86D8, 0xB16A, 0x86D9, 0xB16B, 0x86DA, + 0xB16C, 0x86DB, 0xB16D, 0x86DC, 0xB16E, 0x86DD, 0xB16F, 0x86DE, + 0xB170, 0x86DF, 0xB171, 0x86E0, 0xB172, 0x86E1, 0xB173, 0x86E2, + 0xB174, 0x86E3, 0xB175, 0x86E4, 0xB176, 0x86E5, 0xB177, 0x86E6, + 0xB178, 0xB3EB, 0xB179, 0xB3EC, 0xB17A, 0x86E7, 0xB17B, 0x86E8, + 0xB17C, 0xB3ED, 0xB17D, 0x86E9, 0xB17E, 0x86EA, 0xB17F, 0x86EB, + 0xB180, 0xB3EE, 0xB181, 0x86EC, 0xB182, 0xB3EF, 0xB183, 0x86ED, + 0xB184, 0x86EE, 0xB185, 0x86EF, 0xB186, 0x86F0, 0xB187, 0x86F1, + 0xB188, 0xB3F0, 0xB189, 0xB3F1, 0xB18A, 0x86F2, 0xB18B, 0xB3F2, + 0xB18C, 0x86F3, 0xB18D, 0xB3F3, 0xB18E, 0x86F4, 0xB18F, 0x86F5, + 0xB190, 0x86F6, 0xB191, 0x86F7, 0xB192, 0xB3F4, 0xB193, 0xB3F5, + 0xB194, 0xB3F6, 0xB195, 0x86F8, 0xB196, 0x86F9, 0xB197, 0x86FA, + 0xB198, 0xB3F7, 0xB199, 0x86FB, 0xB19A, 0x86FC, 0xB19B, 0x86FD, + 0xB19C, 0xB3F8, 0xB19D, 0x86FE, 0xB19E, 0x8741, 0xB19F, 0x8742, + 0xB1A0, 0x8743, 0xB1A1, 0x8744, 0xB1A2, 0x8745, 0xB1A3, 0x8746, + 0xB1A4, 0x8747, 0xB1A5, 0x8748, 0xB1A6, 0x8749, 0xB1A7, 0x874A, + 0xB1A8, 0xB3F9, 0xB1A9, 0x874B, 0xB1AA, 0x874C, 0xB1AB, 0x874D, + 0xB1AC, 0x874E, 0xB1AD, 0x874F, 0xB1AE, 0x8750, 0xB1AF, 0x8751, + 0xB1B0, 0x8752, 0xB1B1, 0x8753, 0xB1B2, 0x8754, 0xB1B3, 0x8755, + 0xB1B4, 0x8756, 0xB1B5, 0x8757, 0xB1B6, 0x8758, 0xB1B7, 0x8759, + 0xB1B8, 0x875A, 0xB1B9, 0x8761, 0xB1BA, 0x8762, 0xB1BB, 0x8763, + 0xB1BC, 0x8764, 0xB1BD, 0x8765, 0xB1BE, 0x8766, 0xB1BF, 0x8767, + 0xB1C0, 0x8768, 0xB1C1, 0x8769, 0xB1C2, 0x876A, 0xB1C3, 0x876B, + 0xB1C4, 0x876C, 0xB1C5, 0x876D, 0xB1C6, 0x876E, 0xB1C7, 0x876F, + 0xB1C8, 0x8770, 0xB1C9, 0x8771, 0xB1CA, 0x8772, 0xB1CB, 0x8773, + 0xB1CC, 0xB3FA, 0xB1CD, 0x8774, 0xB1CE, 0x8775, 0xB1CF, 0x8776, + 0xB1D0, 0xB3FB, 0xB1D1, 0x8777, 0xB1D2, 0x8778, 0xB1D3, 0x8779, + 0xB1D4, 0xB3FC, 0xB1D5, 0x877A, 0xB1D6, 0x8781, 0xB1D7, 0x8782, + 0xB1D8, 0x8783, 0xB1D9, 0x8784, 0xB1DA, 0x8785, 0xB1DB, 0x8786, + 0xB1DC, 0xB3FD, 0xB1DD, 0xB3FE, 0xB1DE, 0x8787, 0xB1DF, 0xB4A1, + 0xB1E0, 0x8788, 0xB1E1, 0x8789, 0xB1E2, 0x878A, 0xB1E3, 0x878B, + 0xB1E4, 0x878C, 0xB1E5, 0x878D, 0xB1E6, 0x878E, 0xB1E7, 0x878F, + 0xB1E8, 0xB4A2, 0xB1E9, 0xB4A3, 0xB1EA, 0x8790, 0xB1EB, 0x8791, + 0xB1EC, 0xB4A4, 0xB1ED, 0x8792, 0xB1EE, 0x8793, 0xB1EF, 0x8794, + 0xB1F0, 0xB4A5, 0xB1F1, 0x8795, 0xB1F2, 0x8796, 0xB1F3, 0x8797, + 0xB1F4, 0x8798, 0xB1F5, 0x8799, 0xB1F6, 0x879A, 0xB1F7, 0x879B, + 0xB1F8, 0x879C, 0xB1F9, 0xB4A6, 0xB1FA, 0x879D, 0xB1FB, 0xB4A7, + 0xB1FC, 0x879E, 0xB1FD, 0xB4A8, 0xB1FE, 0x879F, 0xB1FF, 0x87A0, + 0xB200, 0x87A1, 0xB201, 0x87A2, 0xB202, 0x87A3, 0xB203, 0x87A4, + 0xB204, 0xB4A9, 0xB205, 0xB4AA, 0xB206, 0x87A5, 0xB207, 0x87A6, + 0xB208, 0xB4AB, 0xB209, 0x87A7, 0xB20A, 0x87A8, 0xB20B, 0xB4AC, + 0xB20C, 0xB4AD, 0xB20D, 0x87A9, 0xB20E, 0x87AA, 0xB20F, 0x87AB, + 0xB210, 0x87AC, 0xB211, 0x87AD, 0xB212, 0x87AE, 0xB213, 0x87AF, + 0xB214, 0xB4AE, 0xB215, 0xB4AF, 0xB216, 0x87B0, 0xB217, 0xB4B0, + 0xB218, 0x87B1, 0xB219, 0xB4B1, 0xB21A, 0x87B2, 0xB21B, 0x87B3, + 0xB21C, 0x87B4, 0xB21D, 0x87B5, 0xB21E, 0x87B6, 0xB21F, 0x87B7, + 0xB220, 0xB4B2, 0xB221, 0x87B8, 0xB222, 0x87B9, 0xB223, 0x87BA, + 0xB224, 0x87BB, 0xB225, 0x87BC, 0xB226, 0x87BD, 0xB227, 0x87BE, + 0xB228, 0x87BF, 0xB229, 0x87C0, 0xB22A, 0x87C1, 0xB22B, 0x87C2, + 0xB22C, 0x87C3, 0xB22D, 0x87C4, 0xB22E, 0x87C5, 0xB22F, 0x87C6, + 0xB230, 0x87C7, 0xB231, 0x87C8, 0xB232, 0x87C9, 0xB233, 0x87CA, + 0xB234, 0xB4B3, 0xB235, 0x87CB, 0xB236, 0x87CC, 0xB237, 0x87CD, + 0xB238, 0x87CE, 0xB239, 0x87CF, 0xB23A, 0x87D0, 0xB23B, 0x87D1, + 0xB23C, 0xB4B4, 0xB23D, 0x87D2, 0xB23E, 0x87D3, 0xB23F, 0x87D4, + 0xB240, 0x87D5, 0xB241, 0x87D6, 0xB242, 0x87D7, 0xB243, 0x87D8, + 0xB244, 0x87D9, 0xB245, 0x87DA, 0xB246, 0x87DB, 0xB247, 0x87DC, + 0xB248, 0x87DD, 0xB249, 0x87DE, 0xB24A, 0x87DF, 0xB24B, 0x87E0, + 0xB24C, 0x87E1, 0xB24D, 0x87E2, 0xB24E, 0x87E3, 0xB24F, 0x87E4, + 0xB250, 0x87E5, 0xB251, 0x87E6, 0xB252, 0x87E7, 0xB253, 0x87E8, + 0xB254, 0x87E9, 0xB255, 0x87EA, 0xB256, 0x87EB, 0xB257, 0x87EC, + 0xB258, 0xB4B5, 0xB259, 0x87ED, 0xB25A, 0x87EE, 0xB25B, 0x87EF, + 0xB25C, 0xB4B6, 0xB25D, 0x87F0, 0xB25E, 0x87F1, 0xB25F, 0x87F2, + 0xB260, 0xB4B7, 0xB261, 0x87F3, 0xB262, 0x87F4, 0xB263, 0x87F5, + 0xB264, 0x87F6, 0xB265, 0x87F7, 0xB266, 0x87F8, 0xB267, 0x87F9, + 0xB268, 0xB4B8, 0xB269, 0xB4B9, 0xB26A, 0x87FA, 0xB26B, 0x87FB, + 0xB26C, 0x87FC, 0xB26D, 0x87FD, 0xB26E, 0x87FE, 0xB26F, 0x8841, + 0xB270, 0x8842, 0xB271, 0x8843, 0xB272, 0x8844, 0xB273, 0x8845, + 0xB274, 0xB4BA, 0xB275, 0xB4BB, 0xB276, 0x8846, 0xB277, 0x8847, + 0xB278, 0x8848, 0xB279, 0x8849, 0xB27A, 0x884A, 0xB27B, 0x884B, + 0xB27C, 0xB4BC, 0xB27D, 0x884C, 0xB27E, 0x884D, 0xB27F, 0x884E, + 0xB280, 0x884F, 0xB281, 0x8850, 0xB282, 0x8851, 0xB283, 0x8852, + 0xB284, 0xB4BD, 0xB285, 0xB4BE, 0xB286, 0x8853, 0xB287, 0x8854, + 0xB288, 0x8855, 0xB289, 0xB4BF, 0xB28A, 0x8856, 0xB28B, 0x8857, + 0xB28C, 0x8858, 0xB28D, 0x8859, 0xB28E, 0x885A, 0xB28F, 0x8861, + 0xB290, 0xB4C0, 0xB291, 0xB4C1, 0xB292, 0x8862, 0xB293, 0x8863, + 0xB294, 0xB4C2, 0xB295, 0x8864, 0xB296, 0x8865, 0xB297, 0x8866, + 0xB298, 0xB4C3, 0xB299, 0xB4C4, 0xB29A, 0xB4C5, 0xB29B, 0x8867, + 0xB29C, 0x8868, 0xB29D, 0x8869, 0xB29E, 0x886A, 0xB29F, 0x886B, + 0xB2A0, 0xB4C6, 0xB2A1, 0xB4C7, 0xB2A2, 0x886C, 0xB2A3, 0xB4C8, + 0xB2A4, 0x886D, 0xB2A5, 0xB4C9, 0xB2A6, 0xB4CA, 0xB2A7, 0x886E, + 0xB2A8, 0x886F, 0xB2A9, 0x8870, 0xB2AA, 0xB4CB, 0xB2AB, 0x8871, + 0xB2AC, 0xB4CC, 0xB2AD, 0x8872, 0xB2AE, 0x8873, 0xB2AF, 0x8874, + 0xB2B0, 0xB4CD, 0xB2B1, 0x8875, 0xB2B2, 0x8876, 0xB2B3, 0x8877, + 0xB2B4, 0xB4CE, 0xB2B5, 0x8878, 0xB2B6, 0x8879, 0xB2B7, 0x887A, + 0xB2B8, 0x8881, 0xB2B9, 0x8882, 0xB2BA, 0x8883, 0xB2BB, 0x8884, + 0xB2BC, 0x8885, 0xB2BD, 0x8886, 0xB2BE, 0x8887, 0xB2BF, 0x8888, + 0xB2C0, 0x8889, 0xB2C1, 0x888A, 0xB2C2, 0x888B, 0xB2C3, 0x888C, + 0xB2C4, 0x888D, 0xB2C5, 0x888E, 0xB2C6, 0x888F, 0xB2C7, 0x8890, + 0xB2C8, 0xB4CF, 0xB2C9, 0xB4D0, 0xB2CA, 0x8891, 0xB2CB, 0x8892, + 0xB2CC, 0xB4D1, 0xB2CD, 0x8893, 0xB2CE, 0x8894, 0xB2CF, 0x8895, + 0xB2D0, 0xB4D2, 0xB2D1, 0x8896, 0xB2D2, 0xB4D3, 0xB2D3, 0x8897, + 0xB2D4, 0x8898, 0xB2D5, 0x8899, 0xB2D6, 0x889A, 0xB2D7, 0x889B, + 0xB2D8, 0xB4D4, 0xB2D9, 0xB4D5, 0xB2DA, 0x889C, 0xB2DB, 0xB4D6, + 0xB2DC, 0x889D, 0xB2DD, 0xB4D7, 0xB2DE, 0x889E, 0xB2DF, 0x889F, + 0xB2E0, 0x88A0, 0xB2E1, 0x88A1, 0xB2E2, 0xB4D8, 0xB2E3, 0x88A2, + 0xB2E4, 0xB4D9, 0xB2E5, 0xB4DA, 0xB2E6, 0xB4DB, 0xB2E7, 0x88A3, + 0xB2E8, 0xB4DC, 0xB2E9, 0x88A4, 0xB2EA, 0x88A5, 0xB2EB, 0xB4DD, + 0xB2EC, 0xB4DE, 0xB2ED, 0xB4DF, 0xB2EE, 0xB4E0, 0xB2EF, 0xB4E1, + 0xB2F0, 0x88A6, 0xB2F1, 0x88A7, 0xB2F2, 0x88A8, 0xB2F3, 0xB4E2, + 0xB2F4, 0xB4E3, 0xB2F5, 0xB4E4, 0xB2F6, 0x88A9, 0xB2F7, 0xB4E5, + 0xB2F8, 0xB4E6, 0xB2F9, 0xB4E7, 0xB2FA, 0xB4E8, 0xB2FB, 0xB4E9, + 0xB2FC, 0x88AA, 0xB2FD, 0x88AB, 0xB2FE, 0x88AC, 0xB2FF, 0xB4EA, + 0xB300, 0xB4EB, 0xB301, 0xB4EC, 0xB302, 0x88AD, 0xB303, 0x88AE, + 0xB304, 0xB4ED, 0xB305, 0x88AF, 0xB306, 0x88B0, 0xB307, 0x88B1, + 0xB308, 0xB4EE, 0xB309, 0x88B2, 0xB30A, 0x88B3, 0xB30B, 0x88B4, + 0xB30C, 0x88B5, 0xB30D, 0x88B6, 0xB30E, 0x88B7, 0xB30F, 0x88B8, + 0xB310, 0xB4EF, 0xB311, 0xB4F0, 0xB312, 0x88B9, 0xB313, 0xB4F1, + 0xB314, 0xB4F2, 0xB315, 0xB4F3, 0xB316, 0x88BA, 0xB317, 0x88BB, + 0xB318, 0x88BC, 0xB319, 0x88BD, 0xB31A, 0x88BE, 0xB31B, 0x88BF, + 0xB31C, 0xB4F4, 0xB31D, 0x88C0, 0xB31E, 0x88C1, 0xB31F, 0x88C2, + 0xB320, 0x88C3, 0xB321, 0x88C4, 0xB322, 0x88C5, 0xB323, 0x88C6, + 0xB324, 0x88C7, 0xB325, 0x88C8, 0xB326, 0x88C9, 0xB327, 0x88CA, + 0xB328, 0x88CB, 0xB329, 0x88CC, 0xB32A, 0x88CD, 0xB32B, 0x88CE, + 0xB32C, 0x88CF, 0xB32D, 0x88D0, 0xB32E, 0x88D1, 0xB32F, 0x88D2, + 0xB330, 0x88D3, 0xB331, 0x88D4, 0xB332, 0x88D5, 0xB333, 0x88D6, + 0xB334, 0x88D7, 0xB335, 0x88D8, 0xB336, 0x88D9, 0xB337, 0x88DA, + 0xB338, 0x88DB, 0xB339, 0x88DC, 0xB33A, 0x88DD, 0xB33B, 0x88DE, + 0xB33C, 0x88DF, 0xB33D, 0x88E0, 0xB33E, 0x88E1, 0xB33F, 0x88E2, + 0xB340, 0x88E3, 0xB341, 0x88E4, 0xB342, 0x88E5, 0xB343, 0x88E6, + 0xB344, 0x88E7, 0xB345, 0x88E8, 0xB346, 0x88E9, 0xB347, 0x88EA, + 0xB348, 0x88EB, 0xB349, 0x88EC, 0xB34A, 0x88ED, 0xB34B, 0x88EE, + 0xB34C, 0x88EF, 0xB34D, 0x88F0, 0xB34E, 0x88F1, 0xB34F, 0x88F2, + 0xB350, 0x88F3, 0xB351, 0x88F4, 0xB352, 0x88F5, 0xB353, 0x88F6, + 0xB354, 0xB4F5, 0xB355, 0xB4F6, 0xB356, 0xB4F7, 0xB357, 0x88F7, + 0xB358, 0xB4F8, 0xB359, 0x88F8, 0xB35A, 0x88F9, 0xB35B, 0xB4F9, + 0xB35C, 0xB4FA, 0xB35D, 0x88FA, 0xB35E, 0xB4FB, 0xB35F, 0xB4FC, + 0xB360, 0x88FB, 0xB361, 0x88FC, 0xB362, 0x88FD, 0xB363, 0x88FE, + 0xB364, 0xB4FD, 0xB365, 0xB4FE, 0xB366, 0x8941, 0xB367, 0xB5A1, + 0xB368, 0x8942, 0xB369, 0xB5A2, 0xB36A, 0x8943, 0xB36B, 0xB5A3, + 0xB36C, 0x8944, 0xB36D, 0x8945, 0xB36E, 0xB5A4, 0xB36F, 0x8946, + 0xB370, 0xB5A5, 0xB371, 0xB5A6, 0xB372, 0x8947, 0xB373, 0x8948, + 0xB374, 0xB5A7, 0xB375, 0x8949, 0xB376, 0x894A, 0xB377, 0x894B, + 0xB378, 0xB5A8, 0xB379, 0x894C, 0xB37A, 0x894D, 0xB37B, 0x894E, + 0xB37C, 0x894F, 0xB37D, 0x8950, 0xB37E, 0x8951, 0xB37F, 0x8952, + 0xB380, 0xB5A9, 0xB381, 0xB5AA, 0xB382, 0x8953, 0xB383, 0xB5AB, + 0xB384, 0xB5AC, 0xB385, 0xB5AD, 0xB386, 0x8954, 0xB387, 0x8955, + 0xB388, 0x8956, 0xB389, 0x8957, 0xB38A, 0x8958, 0xB38B, 0x8959, + 0xB38C, 0xB5AE, 0xB38D, 0x895A, 0xB38E, 0x8961, 0xB38F, 0x8962, + 0xB390, 0xB5AF, 0xB391, 0x8963, 0xB392, 0x8964, 0xB393, 0x8965, + 0xB394, 0xB5B0, 0xB395, 0x8966, 0xB396, 0x8967, 0xB397, 0x8968, + 0xB398, 0x8969, 0xB399, 0x896A, 0xB39A, 0x896B, 0xB39B, 0x896C, + 0xB39C, 0x896D, 0xB39D, 0x896E, 0xB39E, 0x896F, 0xB39F, 0x8970, + 0xB3A0, 0xB5B1, 0xB3A1, 0xB5B2, 0xB3A2, 0x8971, 0xB3A3, 0x8972, + 0xB3A4, 0x8973, 0xB3A5, 0x8974, 0xB3A6, 0x8975, 0xB3A7, 0x8976, + 0xB3A8, 0xB5B3, 0xB3A9, 0x8977, 0xB3AA, 0x8978, 0xB3AB, 0x8979, + 0xB3AC, 0xB5B4, 0xB3AD, 0x897A, 0xB3AE, 0x8981, 0xB3AF, 0x8982, + 0xB3B0, 0x8983, 0xB3B1, 0x8984, 0xB3B2, 0x8985, 0xB3B3, 0x8986, + 0xB3B4, 0x8987, 0xB3B5, 0x8988, 0xB3B6, 0x8989, 0xB3B7, 0x898A, + 0xB3B8, 0x898B, 0xB3B9, 0x898C, 0xB3BA, 0x898D, 0xB3BB, 0x898E, + 0xB3BC, 0x898F, 0xB3BD, 0x8990, 0xB3BE, 0x8991, 0xB3BF, 0x8992, + 0xB3C0, 0x8993, 0xB3C1, 0x8994, 0xB3C2, 0x8995, 0xB3C3, 0x8996, + 0xB3C4, 0xB5B5, 0xB3C5, 0xB5B6, 0xB3C6, 0x8997, 0xB3C7, 0x8998, + 0xB3C8, 0xB5B7, 0xB3C9, 0x8999, 0xB3CA, 0x899A, 0xB3CB, 0xB5B8, + 0xB3CC, 0xB5B9, 0xB3CD, 0x899B, 0xB3CE, 0xB5BA, 0xB3CF, 0x899C, + 0xB3D0, 0xB5BB, 0xB3D1, 0x899D, 0xB3D2, 0x899E, 0xB3D3, 0x899F, + 0xB3D4, 0xB5BC, 0xB3D5, 0xB5BD, 0xB3D6, 0x89A0, 0xB3D7, 0xB5BE, + 0xB3D8, 0x89A1, 0xB3D9, 0xB5BF, 0xB3DA, 0x89A2, 0xB3DB, 0xB5C0, + 0xB3DC, 0x89A3, 0xB3DD, 0xB5C1, 0xB3DE, 0x89A4, 0xB3DF, 0x89A5, + 0xB3E0, 0xB5C2, 0xB3E1, 0x89A6, 0xB3E2, 0x89A7, 0xB3E3, 0x89A8, + 0xB3E4, 0xB5C3, 0xB3E5, 0x89A9, 0xB3E6, 0x89AA, 0xB3E7, 0x89AB, + 0xB3E8, 0xB5C4, 0xB3E9, 0x89AC, 0xB3EA, 0x89AD, 0xB3EB, 0x89AE, + 0xB3EC, 0x89AF, 0xB3ED, 0x89B0, 0xB3EE, 0x89B1, 0xB3EF, 0x89B2, + 0xB3F0, 0x89B3, 0xB3F1, 0x89B4, 0xB3F2, 0x89B5, 0xB3F3, 0x89B6, + 0xB3F4, 0x89B7, 0xB3F5, 0x89B8, 0xB3F6, 0x89B9, 0xB3F7, 0x89BA, + 0xB3F8, 0x89BB, 0xB3F9, 0x89BC, 0xB3FA, 0x89BD, 0xB3FB, 0x89BE, + 0xB3FC, 0xB5C5, 0xB3FD, 0x89BF, 0xB3FE, 0x89C0, 0xB3FF, 0x89C1, + 0xB400, 0x89C2, 0xB401, 0x89C3, 0xB402, 0x89C4, 0xB403, 0x89C5, + 0xB404, 0x89C6, 0xB405, 0x89C7, 0xB406, 0x89C8, 0xB407, 0x89C9, + 0xB408, 0x89CA, 0xB409, 0x89CB, 0xB40A, 0x89CC, 0xB40B, 0x89CD, + 0xB40C, 0x89CE, 0xB40D, 0x89CF, 0xB40E, 0x89D0, 0xB40F, 0x89D1, + 0xB410, 0xB5C6, 0xB411, 0x89D2, 0xB412, 0x89D3, 0xB413, 0x89D4, + 0xB414, 0x89D5, 0xB415, 0x89D6, 0xB416, 0x89D7, 0xB417, 0x89D8, + 0xB418, 0xB5C7, 0xB419, 0x89D9, 0xB41A, 0x89DA, 0xB41B, 0x89DB, + 0xB41C, 0xB5C8, 0xB41D, 0x89DC, 0xB41E, 0x89DD, 0xB41F, 0x89DE, + 0xB420, 0xB5C9, 0xB421, 0x89DF, 0xB422, 0x89E0, 0xB423, 0x89E1, + 0xB424, 0x89E2, 0xB425, 0x89E3, 0xB426, 0x89E4, 0xB427, 0x89E5, + 0xB428, 0xB5CA, 0xB429, 0xB5CB, 0xB42A, 0x89E6, 0xB42B, 0xB5CC, + 0xB42C, 0x89E7, 0xB42D, 0x89E8, 0xB42E, 0x89E9, 0xB42F, 0x89EA, + 0xB430, 0x89EB, 0xB431, 0x89EC, 0xB432, 0x89ED, 0xB433, 0x89EE, + 0xB434, 0xB5CD, 0xB435, 0x89EF, 0xB436, 0x89F0, 0xB437, 0x89F1, + 0xB438, 0x89F2, 0xB439, 0x89F3, 0xB43A, 0x89F4, 0xB43B, 0x89F5, + 0xB43C, 0x89F6, 0xB43D, 0x89F7, 0xB43E, 0x89F8, 0xB43F, 0x89F9, + 0xB440, 0x89FA, 0xB441, 0x89FB, 0xB442, 0x89FC, 0xB443, 0x89FD, + 0xB444, 0x89FE, 0xB445, 0x8A41, 0xB446, 0x8A42, 0xB447, 0x8A43, + 0xB448, 0x8A44, 0xB449, 0x8A45, 0xB44A, 0x8A46, 0xB44B, 0x8A47, + 0xB44C, 0x8A48, 0xB44D, 0x8A49, 0xB44E, 0x8A4A, 0xB44F, 0x8A4B, + 0xB450, 0xB5CE, 0xB451, 0xB5CF, 0xB452, 0x8A4C, 0xB453, 0x8A4D, + 0xB454, 0xB5D0, 0xB455, 0x8A4E, 0xB456, 0x8A4F, 0xB457, 0x8A50, + 0xB458, 0xB5D1, 0xB459, 0x8A51, 0xB45A, 0x8A52, 0xB45B, 0x8A53, + 0xB45C, 0x8A54, 0xB45D, 0x8A55, 0xB45E, 0x8A56, 0xB45F, 0x8A57, + 0xB460, 0xB5D2, 0xB461, 0xB5D3, 0xB462, 0x8A58, 0xB463, 0xB5D4, + 0xB464, 0x8A59, 0xB465, 0xB5D5, 0xB466, 0x8A5A, 0xB467, 0x8A61, + 0xB468, 0x8A62, 0xB469, 0x8A63, 0xB46A, 0x8A64, 0xB46B, 0x8A65, + 0xB46C, 0xB5D6, 0xB46D, 0x8A66, 0xB46E, 0x8A67, 0xB46F, 0x8A68, + 0xB470, 0x8A69, 0xB471, 0x8A6A, 0xB472, 0x8A6B, 0xB473, 0x8A6C, + 0xB474, 0x8A6D, 0xB475, 0x8A6E, 0xB476, 0x8A6F, 0xB477, 0x8A70, + 0xB478, 0x8A71, 0xB479, 0x8A72, 0xB47A, 0x8A73, 0xB47B, 0x8A74, + 0xB47C, 0x8A75, 0xB47D, 0x8A76, 0xB47E, 0x8A77, 0xB47F, 0x8A78, + 0xB480, 0xB5D7, 0xB481, 0x8A79, 0xB482, 0x8A7A, 0xB483, 0x8A81, + 0xB484, 0x8A82, 0xB485, 0x8A83, 0xB486, 0x8A84, 0xB487, 0x8A85, + 0xB488, 0xB5D8, 0xB489, 0x8A86, 0xB48A, 0x8A87, 0xB48B, 0x8A88, + 0xB48C, 0x8A89, 0xB48D, 0x8A8A, 0xB48E, 0x8A8B, 0xB48F, 0x8A8C, + 0xB490, 0x8A8D, 0xB491, 0x8A8E, 0xB492, 0x8A8F, 0xB493, 0x8A90, + 0xB494, 0x8A91, 0xB495, 0x8A92, 0xB496, 0x8A93, 0xB497, 0x8A94, + 0xB498, 0x8A95, 0xB499, 0x8A96, 0xB49A, 0x8A97, 0xB49B, 0x8A98, + 0xB49C, 0x8A99, 0xB49D, 0xB5D9, 0xB49E, 0x8A9A, 0xB49F, 0x8A9B, + 0xB4A0, 0x8A9C, 0xB4A1, 0x8A9D, 0xB4A2, 0x8A9E, 0xB4A3, 0x8A9F, + 0xB4A4, 0xB5DA, 0xB4A5, 0x8AA0, 0xB4A6, 0x8AA1, 0xB4A7, 0x8AA2, + 0xB4A8, 0xB5DB, 0xB4A9, 0x8AA3, 0xB4AA, 0x8AA4, 0xB4AB, 0x8AA5, + 0xB4AC, 0xB5DC, 0xB4AD, 0x8AA6, 0xB4AE, 0x8AA7, 0xB4AF, 0x8AA8, + 0xB4B0, 0x8AA9, 0xB4B1, 0x8AAA, 0xB4B2, 0x8AAB, 0xB4B3, 0x8AAC, + 0xB4B4, 0x8AAD, 0xB4B5, 0xB5DD, 0xB4B6, 0x8AAE, 0xB4B7, 0xB5DE, + 0xB4B8, 0x8AAF, 0xB4B9, 0xB5DF, 0xB4BA, 0x8AB0, 0xB4BB, 0x8AB1, + 0xB4BC, 0x8AB2, 0xB4BD, 0x8AB3, 0xB4BE, 0x8AB4, 0xB4BF, 0x8AB5, + 0xB4C0, 0xB5E0, 0xB4C1, 0x8AB6, 0xB4C2, 0x8AB7, 0xB4C3, 0x8AB8, + 0xB4C4, 0xB5E1, 0xB4C5, 0x8AB9, 0xB4C6, 0x8ABA, 0xB4C7, 0x8ABB, + 0xB4C8, 0xB5E2, 0xB4C9, 0x8ABC, 0xB4CA, 0x8ABD, 0xB4CB, 0x8ABE, + 0xB4CC, 0x8ABF, 0xB4CD, 0x8AC0, 0xB4CE, 0x8AC1, 0xB4CF, 0x8AC2, + 0xB4D0, 0xB5E3, 0xB4D1, 0x8AC3, 0xB4D2, 0x8AC4, 0xB4D3, 0x8AC5, + 0xB4D4, 0x8AC6, 0xB4D5, 0xB5E4, 0xB4D6, 0x8AC7, 0xB4D7, 0x8AC8, + 0xB4D8, 0x8AC9, 0xB4D9, 0x8ACA, 0xB4DA, 0x8ACB, 0xB4DB, 0x8ACC, + 0xB4DC, 0xB5E5, 0xB4DD, 0xB5E6, 0xB4DE, 0x8ACD, 0xB4DF, 0x8ACE, + 0xB4E0, 0xB5E7, 0xB4E1, 0x8ACF, 0xB4E2, 0x8AD0, 0xB4E3, 0xB5E8, + 0xB4E4, 0xB5E9, 0xB4E5, 0x8AD1, 0xB4E6, 0xB5EA, 0xB4E7, 0x8AD2, + 0xB4E8, 0x8AD3, 0xB4E9, 0x8AD4, 0xB4EA, 0x8AD5, 0xB4EB, 0x8AD6, + 0xB4EC, 0xB5EB, 0xB4ED, 0xB5EC, 0xB4EE, 0x8AD7, 0xB4EF, 0xB5ED, + 0xB4F0, 0x8AD8, 0xB4F1, 0xB5EE, 0xB4F2, 0x8AD9, 0xB4F3, 0x8ADA, + 0xB4F4, 0x8ADB, 0xB4F5, 0x8ADC, 0xB4F6, 0x8ADD, 0xB4F7, 0x8ADE, + 0xB4F8, 0xB5EF, 0xB4F9, 0x8ADF, 0xB4FA, 0x8AE0, 0xB4FB, 0x8AE1, + 0xB4FC, 0x8AE2, 0xB4FD, 0x8AE3, 0xB4FE, 0x8AE4, 0xB4FF, 0x8AE5, + 0xB500, 0x8AE6, 0xB501, 0x8AE7, 0xB502, 0x8AE8, 0xB503, 0x8AE9, + 0xB504, 0x8AEA, 0xB505, 0x8AEB, 0xB506, 0x8AEC, 0xB507, 0x8AED, + 0xB508, 0x8AEE, 0xB509, 0x8AEF, 0xB50A, 0x8AF0, 0xB50B, 0x8AF1, + 0xB50C, 0x8AF2, 0xB50D, 0x8AF3, 0xB50E, 0x8AF4, 0xB50F, 0x8AF5, + 0xB510, 0x8AF6, 0xB511, 0x8AF7, 0xB512, 0x8AF8, 0xB513, 0x8AF9, + 0xB514, 0xB5F0, 0xB515, 0xB5F1, 0xB516, 0x8AFA, 0xB517, 0x8AFB, + 0xB518, 0xB5F2, 0xB519, 0x8AFC, 0xB51A, 0x8AFD, 0xB51B, 0xB5F3, + 0xB51C, 0xB5F4, 0xB51D, 0x8AFE, 0xB51E, 0x8B41, 0xB51F, 0x8B42, + 0xB520, 0x8B43, 0xB521, 0x8B44, 0xB522, 0x8B45, 0xB523, 0x8B46, + 0xB524, 0xB5F5, 0xB525, 0xB5F6, 0xB526, 0x8B47, 0xB527, 0xB5F7, + 0xB528, 0xB5F8, 0xB529, 0xB5F9, 0xB52A, 0xB5FA, 0xB52B, 0x8B48, + 0xB52C, 0x8B49, 0xB52D, 0x8B4A, 0xB52E, 0x8B4B, 0xB52F, 0x8B4C, + 0xB530, 0xB5FB, 0xB531, 0xB5FC, 0xB532, 0x8B4D, 0xB533, 0x8B4E, + 0xB534, 0xB5FD, 0xB535, 0x8B4F, 0xB536, 0x8B50, 0xB537, 0x8B51, + 0xB538, 0xB5FE, 0xB539, 0x8B52, 0xB53A, 0x8B53, 0xB53B, 0x8B54, + 0xB53C, 0x8B55, 0xB53D, 0x8B56, 0xB53E, 0x8B57, 0xB53F, 0x8B58, + 0xB540, 0xB6A1, 0xB541, 0xB6A2, 0xB542, 0x8B59, 0xB543, 0xB6A3, + 0xB544, 0xB6A4, 0xB545, 0xB6A5, 0xB546, 0x8B5A, 0xB547, 0x8B61, + 0xB548, 0x8B62, 0xB549, 0x8B63, 0xB54A, 0x8B64, 0xB54B, 0xB6A6, + 0xB54C, 0xB6A7, 0xB54D, 0xB6A8, 0xB54E, 0x8B65, 0xB54F, 0x8B66, + 0xB550, 0xB6A9, 0xB551, 0x8B67, 0xB552, 0x8B68, 0xB553, 0x8B69, + 0xB554, 0xB6AA, 0xB555, 0x8B6A, 0xB556, 0x8B6B, 0xB557, 0x8B6C, + 0xB558, 0x8B6D, 0xB559, 0x8B6E, 0xB55A, 0x8B6F, 0xB55B, 0x8B70, + 0xB55C, 0xB6AB, 0xB55D, 0xB6AC, 0xB55E, 0x8B71, 0xB55F, 0xB6AD, + 0xB560, 0xB6AE, 0xB561, 0xB6AF, 0xB562, 0x8B72, 0xB563, 0x8B73, + 0xB564, 0x8B74, 0xB565, 0x8B75, 0xB566, 0x8B76, 0xB567, 0x8B77, + 0xB568, 0x8B78, 0xB569, 0x8B79, 0xB56A, 0x8B7A, 0xB56B, 0x8B81, + 0xB56C, 0x8B82, 0xB56D, 0x8B83, 0xB56E, 0x8B84, 0xB56F, 0x8B85, + 0xB570, 0x8B86, 0xB571, 0x8B87, 0xB572, 0x8B88, 0xB573, 0x8B89, + 0xB574, 0x8B8A, 0xB575, 0x8B8B, 0xB576, 0x8B8C, 0xB577, 0x8B8D, + 0xB578, 0x8B8E, 0xB579, 0x8B8F, 0xB57A, 0x8B90, 0xB57B, 0x8B91, + 0xB57C, 0x8B92, 0xB57D, 0x8B93, 0xB57E, 0x8B94, 0xB57F, 0x8B95, + 0xB580, 0x8B96, 0xB581, 0x8B97, 0xB582, 0x8B98, 0xB583, 0x8B99, + 0xB584, 0x8B9A, 0xB585, 0x8B9B, 0xB586, 0x8B9C, 0xB587, 0x8B9D, + 0xB588, 0x8B9E, 0xB589, 0x8B9F, 0xB58A, 0x8BA0, 0xB58B, 0x8BA1, + 0xB58C, 0x8BA2, 0xB58D, 0x8BA3, 0xB58E, 0x8BA4, 0xB58F, 0x8BA5, + 0xB590, 0x8BA6, 0xB591, 0x8BA7, 0xB592, 0x8BA8, 0xB593, 0x8BA9, + 0xB594, 0x8BAA, 0xB595, 0x8BAB, 0xB596, 0x8BAC, 0xB597, 0x8BAD, + 0xB598, 0x8BAE, 0xB599, 0x8BAF, 0xB59A, 0x8BB0, 0xB59B, 0x8BB1, + 0xB59C, 0x8BB2, 0xB59D, 0x8BB3, 0xB59E, 0x8BB4, 0xB59F, 0x8BB5, + 0xB5A0, 0xB6B0, 0xB5A1, 0xB6B1, 0xB5A2, 0x8BB6, 0xB5A3, 0x8BB7, + 0xB5A4, 0xB6B2, 0xB5A5, 0x8BB8, 0xB5A6, 0x8BB9, 0xB5A7, 0x8BBA, + 0xB5A8, 0xB6B3, 0xB5A9, 0x8BBB, 0xB5AA, 0xB6B4, 0xB5AB, 0xB6B5, + 0xB5AC, 0x8BBC, 0xB5AD, 0x8BBD, 0xB5AE, 0x8BBE, 0xB5AF, 0x8BBF, + 0xB5B0, 0xB6B6, 0xB5B1, 0xB6B7, 0xB5B2, 0x8BC0, 0xB5B3, 0xB6B8, + 0xB5B4, 0xB6B9, 0xB5B5, 0xB6BA, 0xB5B6, 0x8BC1, 0xB5B7, 0x8BC2, + 0xB5B8, 0x8BC3, 0xB5B9, 0x8BC4, 0xB5BA, 0x8BC5, 0xB5BB, 0xB6BB, + 0xB5BC, 0xB6BC, 0xB5BD, 0xB6BD, 0xB5BE, 0x8BC6, 0xB5BF, 0x8BC7, + 0xB5C0, 0xB6BE, 0xB5C1, 0x8BC8, 0xB5C2, 0x8BC9, 0xB5C3, 0x8BCA, + 0xB5C4, 0xB6BF, 0xB5C5, 0x8BCB, 0xB5C6, 0x8BCC, 0xB5C7, 0x8BCD, + 0xB5C8, 0x8BCE, 0xB5C9, 0x8BCF, 0xB5CA, 0x8BD0, 0xB5CB, 0x8BD1, + 0xB5CC, 0xB6C0, 0xB5CD, 0xB6C1, 0xB5CE, 0x8BD2, 0xB5CF, 0xB6C2, + 0xB5D0, 0xB6C3, 0xB5D1, 0xB6C4, 0xB5D2, 0x8BD3, 0xB5D3, 0x8BD4, + 0xB5D4, 0x8BD5, 0xB5D5, 0x8BD6, 0xB5D6, 0x8BD7, 0xB5D7, 0x8BD8, + 0xB5D8, 0xB6C5, 0xB5D9, 0x8BD9, 0xB5DA, 0x8BDA, 0xB5DB, 0x8BDB, + 0xB5DC, 0x8BDC, 0xB5DD, 0x8BDD, 0xB5DE, 0x8BDE, 0xB5DF, 0x8BDF, + 0xB5E0, 0x8BE0, 0xB5E1, 0x8BE1, 0xB5E2, 0x8BE2, 0xB5E3, 0x8BE3, + 0xB5E4, 0x8BE4, 0xB5E5, 0x8BE5, 0xB5E6, 0x8BE6, 0xB5E7, 0x8BE7, + 0xB5E8, 0x8BE8, 0xB5E9, 0x8BE9, 0xB5EA, 0x8BEA, 0xB5EB, 0x8BEB, + 0xB5EC, 0xB6C6, 0xB5ED, 0x8BEC, 0xB5EE, 0x8BED, 0xB5EF, 0x8BEE, + 0xB5F0, 0x8BEF, 0xB5F1, 0x8BF0, 0xB5F2, 0x8BF1, 0xB5F3, 0x8BF2, + 0xB5F4, 0x8BF3, 0xB5F5, 0x8BF4, 0xB5F6, 0x8BF5, 0xB5F7, 0x8BF6, + 0xB5F8, 0x8BF7, 0xB5F9, 0x8BF8, 0xB5FA, 0x8BF9, 0xB5FB, 0x8BFA, + 0xB5FC, 0x8BFB, 0xB5FD, 0x8BFC, 0xB5FE, 0x8BFD, 0xB5FF, 0x8BFE, + 0xB600, 0x8C41, 0xB601, 0x8C42, 0xB602, 0x8C43, 0xB603, 0x8C44, + 0xB604, 0x8C45, 0xB605, 0x8C46, 0xB606, 0x8C47, 0xB607, 0x8C48, + 0xB608, 0x8C49, 0xB609, 0x8C4A, 0xB60A, 0x8C4B, 0xB60B, 0x8C4C, + 0xB60C, 0x8C4D, 0xB60D, 0x8C4E, 0xB60E, 0x8C4F, 0xB60F, 0x8C50, + 0xB610, 0xB6C7, 0xB611, 0xB6C8, 0xB612, 0x8C51, 0xB613, 0x8C52, + 0xB614, 0xB6C9, 0xB615, 0x8C53, 0xB616, 0x8C54, 0xB617, 0x8C55, + 0xB618, 0xB6CA, 0xB619, 0x8C56, 0xB61A, 0x8C57, 0xB61B, 0x8C58, + 0xB61C, 0x8C59, 0xB61D, 0x8C5A, 0xB61E, 0x8C61, 0xB61F, 0x8C62, + 0xB620, 0x8C63, 0xB621, 0x8C64, 0xB622, 0x8C65, 0xB623, 0x8C66, + 0xB624, 0x8C67, 0xB625, 0xB6CB, 0xB626, 0x8C68, 0xB627, 0x8C69, + 0xB628, 0x8C6A, 0xB629, 0x8C6B, 0xB62A, 0x8C6C, 0xB62B, 0x8C6D, + 0xB62C, 0xB6CC, 0xB62D, 0x8C6E, 0xB62E, 0x8C6F, 0xB62F, 0x8C70, + 0xB630, 0x8C71, 0xB631, 0x8C72, 0xB632, 0x8C73, 0xB633, 0x8C74, + 0xB634, 0xB6CD, 0xB635, 0x8C75, 0xB636, 0x8C76, 0xB637, 0x8C77, + 0xB638, 0x8C78, 0xB639, 0x8C79, 0xB63A, 0x8C7A, 0xB63B, 0x8C81, + 0xB63C, 0x8C82, 0xB63D, 0x8C83, 0xB63E, 0x8C84, 0xB63F, 0x8C85, + 0xB640, 0x8C86, 0xB641, 0x8C87, 0xB642, 0x8C88, 0xB643, 0x8C89, + 0xB644, 0x8C8A, 0xB645, 0x8C8B, 0xB646, 0x8C8C, 0xB647, 0x8C8D, + 0xB648, 0xB6CE, 0xB649, 0x8C8E, 0xB64A, 0x8C8F, 0xB64B, 0x8C90, + 0xB64C, 0x8C91, 0xB64D, 0x8C92, 0xB64E, 0x8C93, 0xB64F, 0x8C94, + 0xB650, 0x8C95, 0xB651, 0x8C96, 0xB652, 0x8C97, 0xB653, 0x8C98, + 0xB654, 0x8C99, 0xB655, 0x8C9A, 0xB656, 0x8C9B, 0xB657, 0x8C9C, + 0xB658, 0x8C9D, 0xB659, 0x8C9E, 0xB65A, 0x8C9F, 0xB65B, 0x8CA0, + 0xB65C, 0x8CA1, 0xB65D, 0x8CA2, 0xB65E, 0x8CA3, 0xB65F, 0x8CA4, + 0xB660, 0x8CA5, 0xB661, 0x8CA6, 0xB662, 0x8CA7, 0xB663, 0x8CA8, + 0xB664, 0xB6CF, 0xB665, 0x8CA9, 0xB666, 0x8CAA, 0xB667, 0x8CAB, + 0xB668, 0xB6D0, 0xB669, 0x8CAC, 0xB66A, 0x8CAD, 0xB66B, 0x8CAE, + 0xB66C, 0x8CAF, 0xB66D, 0x8CB0, 0xB66E, 0x8CB1, 0xB66F, 0x8CB2, + 0xB670, 0x8CB3, 0xB671, 0x8CB4, 0xB672, 0x8CB5, 0xB673, 0x8CB6, + 0xB674, 0x8CB7, 0xB675, 0x8CB8, 0xB676, 0x8CB9, 0xB677, 0x8CBA, + 0xB678, 0x8CBB, 0xB679, 0x8CBC, 0xB67A, 0x8CBD, 0xB67B, 0x8CBE, + 0xB67C, 0x8CBF, 0xB67D, 0x8CC0, 0xB67E, 0x8CC1, 0xB67F, 0x8CC2, + 0xB680, 0x8CC3, 0xB681, 0x8CC4, 0xB682, 0x8CC5, 0xB683, 0x8CC6, + 0xB684, 0x8CC7, 0xB685, 0x8CC8, 0xB686, 0x8CC9, 0xB687, 0x8CCA, + 0xB688, 0x8CCB, 0xB689, 0x8CCC, 0xB68A, 0x8CCD, 0xB68B, 0x8CCE, + 0xB68C, 0x8CCF, 0xB68D, 0x8CD0, 0xB68E, 0x8CD1, 0xB68F, 0x8CD2, + 0xB690, 0x8CD3, 0xB691, 0x8CD4, 0xB692, 0x8CD5, 0xB693, 0x8CD6, + 0xB694, 0x8CD7, 0xB695, 0x8CD8, 0xB696, 0x8CD9, 0xB697, 0x8CDA, + 0xB698, 0x8CDB, 0xB699, 0x8CDC, 0xB69A, 0x8CDD, 0xB69B, 0x8CDE, + 0xB69C, 0xB6D1, 0xB69D, 0xB6D2, 0xB69E, 0x8CDF, 0xB69F, 0x8CE0, + 0xB6A0, 0xB6D3, 0xB6A1, 0x8CE1, 0xB6A2, 0x8CE2, 0xB6A3, 0x8CE3, + 0xB6A4, 0xB6D4, 0xB6A5, 0x8CE4, 0xB6A6, 0x8CE5, 0xB6A7, 0x8CE6, + 0xB6A8, 0x8CE7, 0xB6A9, 0x8CE8, 0xB6AA, 0x8CE9, 0xB6AB, 0xB6D5, + 0xB6AC, 0xB6D6, 0xB6AD, 0x8CEA, 0xB6AE, 0x8CEB, 0xB6AF, 0x8CEC, + 0xB6B0, 0x8CED, 0xB6B1, 0xB6D7, 0xB6B2, 0x8CEE, 0xB6B3, 0x8CEF, + 0xB6B4, 0x8CF0, 0xB6B5, 0x8CF1, 0xB6B6, 0x8CF2, 0xB6B7, 0x8CF3, + 0xB6B8, 0x8CF4, 0xB6B9, 0x8CF5, 0xB6BA, 0x8CF6, 0xB6BB, 0x8CF7, + 0xB6BC, 0x8CF8, 0xB6BD, 0x8CF9, 0xB6BE, 0x8CFA, 0xB6BF, 0x8CFB, + 0xB6C0, 0x8CFC, 0xB6C1, 0x8CFD, 0xB6C2, 0x8CFE, 0xB6C3, 0x8D41, + 0xB6C4, 0x8D42, 0xB6C5, 0x8D43, 0xB6C6, 0x8D44, 0xB6C7, 0x8D45, + 0xB6C8, 0x8D46, 0xB6C9, 0x8D47, 0xB6CA, 0x8D48, 0xB6CB, 0x8D49, + 0xB6CC, 0x8D4A, 0xB6CD, 0x8D4B, 0xB6CE, 0x8D4C, 0xB6CF, 0x8D4D, + 0xB6D0, 0x8D4E, 0xB6D1, 0x8D4F, 0xB6D2, 0x8D50, 0xB6D3, 0x8D51, + 0xB6D4, 0xB6D8, 0xB6D5, 0x8D52, 0xB6D6, 0x8D53, 0xB6D7, 0x8D54, + 0xB6D8, 0x8D55, 0xB6D9, 0x8D56, 0xB6DA, 0x8D57, 0xB6DB, 0x8D58, + 0xB6DC, 0x8D59, 0xB6DD, 0x8D5A, 0xB6DE, 0x8D61, 0xB6DF, 0x8D62, + 0xB6E0, 0x8D63, 0xB6E1, 0x8D64, 0xB6E2, 0x8D65, 0xB6E3, 0x8D66, + 0xB6E4, 0x8D67, 0xB6E5, 0x8D68, 0xB6E6, 0x8D69, 0xB6E7, 0x8D6A, + 0xB6E8, 0x8D6B, 0xB6E9, 0x8D6C, 0xB6EA, 0x8D6D, 0xB6EB, 0x8D6E, + 0xB6EC, 0x8D6F, 0xB6ED, 0x8D70, 0xB6EE, 0x8D71, 0xB6EF, 0x8D72, + 0xB6F0, 0xB6D9, 0xB6F1, 0x8D73, 0xB6F2, 0x8D74, 0xB6F3, 0x8D75, + 0xB6F4, 0xB6DA, 0xB6F5, 0x8D76, 0xB6F6, 0x8D77, 0xB6F7, 0x8D78, + 0xB6F8, 0xB6DB, 0xB6F9, 0x8D79, 0xB6FA, 0x8D7A, 0xB6FB, 0x8D81, + 0xB6FC, 0x8D82, 0xB6FD, 0x8D83, 0xB6FE, 0x8D84, 0xB6FF, 0x8D85, + 0xB700, 0xB6DC, 0xB701, 0xB6DD, 0xB702, 0x8D86, 0xB703, 0x8D87, + 0xB704, 0x8D88, 0xB705, 0xB6DE, 0xB706, 0x8D89, 0xB707, 0x8D8A, + 0xB708, 0x8D8B, 0xB709, 0x8D8C, 0xB70A, 0x8D8D, 0xB70B, 0x8D8E, + 0xB70C, 0x8D8F, 0xB70D, 0x8D90, 0xB70E, 0x8D91, 0xB70F, 0x8D92, + 0xB710, 0x8D93, 0xB711, 0x8D94, 0xB712, 0x8D95, 0xB713, 0x8D96, + 0xB714, 0x8D97, 0xB715, 0x8D98, 0xB716, 0x8D99, 0xB717, 0x8D9A, + 0xB718, 0x8D9B, 0xB719, 0x8D9C, 0xB71A, 0x8D9D, 0xB71B, 0x8D9E, + 0xB71C, 0x8D9F, 0xB71D, 0x8DA0, 0xB71E, 0x8DA1, 0xB71F, 0x8DA2, + 0xB720, 0x8DA3, 0xB721, 0x8DA4, 0xB722, 0x8DA5, 0xB723, 0x8DA6, + 0xB724, 0x8DA7, 0xB725, 0x8DA8, 0xB726, 0x8DA9, 0xB727, 0x8DAA, + 0xB728, 0xB6DF, 0xB729, 0xB6E0, 0xB72A, 0x8DAB, 0xB72B, 0x8DAC, + 0xB72C, 0xB6E1, 0xB72D, 0x8DAD, 0xB72E, 0x8DAE, 0xB72F, 0xB6E2, + 0xB730, 0xB6E3, 0xB731, 0x8DAF, 0xB732, 0x8DB0, 0xB733, 0x8DB1, + 0xB734, 0x8DB2, 0xB735, 0x8DB3, 0xB736, 0x8DB4, 0xB737, 0x8DB5, + 0xB738, 0xB6E4, 0xB739, 0xB6E5, 0xB73A, 0x8DB6, 0xB73B, 0xB6E6, + 0xB73C, 0x8DB7, 0xB73D, 0x8DB8, 0xB73E, 0x8DB9, 0xB73F, 0x8DBA, + 0xB740, 0x8DBB, 0xB741, 0x8DBC, 0xB742, 0x8DBD, 0xB743, 0x8DBE, + 0xB744, 0xB6E7, 0xB745, 0x8DBF, 0xB746, 0x8DC0, 0xB747, 0x8DC1, + 0xB748, 0xB6E8, 0xB749, 0x8DC2, 0xB74A, 0x8DC3, 0xB74B, 0x8DC4, + 0xB74C, 0xB6E9, 0xB74D, 0x8DC5, 0xB74E, 0x8DC6, 0xB74F, 0x8DC7, + 0xB750, 0x8DC8, 0xB751, 0x8DC9, 0xB752, 0x8DCA, 0xB753, 0x8DCB, + 0xB754, 0xB6EA, 0xB755, 0xB6EB, 0xB756, 0x8DCC, 0xB757, 0x8DCD, + 0xB758, 0x8DCE, 0xB759, 0x8DCF, 0xB75A, 0x8DD0, 0xB75B, 0x8DD1, + 0xB75C, 0x8DD2, 0xB75D, 0x8DD3, 0xB75E, 0x8DD4, 0xB75F, 0x8DD5, + 0xB760, 0xB6EC, 0xB761, 0x8DD6, 0xB762, 0x8DD7, 0xB763, 0x8DD8, + 0xB764, 0xB6ED, 0xB765, 0x8DD9, 0xB766, 0x8DDA, 0xB767, 0x8DDB, + 0xB768, 0xB6EE, 0xB769, 0x8DDC, 0xB76A, 0x8DDD, 0xB76B, 0x8DDE, + 0xB76C, 0x8DDF, 0xB76D, 0x8DE0, 0xB76E, 0x8DE1, 0xB76F, 0x8DE2, + 0xB770, 0xB6EF, 0xB771, 0xB6F0, 0xB772, 0x8DE3, 0xB773, 0xB6F1, + 0xB774, 0x8DE4, 0xB775, 0xB6F2, 0xB776, 0x8DE5, 0xB777, 0x8DE6, + 0xB778, 0x8DE7, 0xB779, 0x8DE8, 0xB77A, 0x8DE9, 0xB77B, 0x8DEA, + 0xB77C, 0xB6F3, 0xB77D, 0xB6F4, 0xB77E, 0x8DEB, 0xB77F, 0x8DEC, + 0xB780, 0xB6F5, 0xB781, 0x8DED, 0xB782, 0x8DEE, 0xB783, 0x8DEF, + 0xB784, 0xB6F6, 0xB785, 0x8DF0, 0xB786, 0x8DF1, 0xB787, 0x8DF2, + 0xB788, 0x8DF3, 0xB789, 0x8DF4, 0xB78A, 0x8DF5, 0xB78B, 0x8DF6, + 0xB78C, 0xB6F7, 0xB78D, 0xB6F8, 0xB78E, 0x8DF7, 0xB78F, 0xB6F9, + 0xB790, 0xB6FA, 0xB791, 0xB6FB, 0xB792, 0xB6FC, 0xB793, 0x8DF8, + 0xB794, 0x8DF9, 0xB795, 0x8DFA, 0xB796, 0xB6FD, 0xB797, 0xB6FE, + 0xB798, 0xB7A1, 0xB799, 0xB7A2, 0xB79A, 0x8DFB, 0xB79B, 0x8DFC, + 0xB79C, 0xB7A3, 0xB79D, 0x8DFD, 0xB79E, 0x8DFE, 0xB79F, 0x8E41, + 0xB7A0, 0xB7A4, 0xB7A1, 0x8E42, 0xB7A2, 0x8E43, 0xB7A3, 0x8E44, + 0xB7A4, 0x8E45, 0xB7A5, 0x8E46, 0xB7A6, 0x8E47, 0xB7A7, 0x8E48, + 0xB7A8, 0xB7A5, 0xB7A9, 0xB7A6, 0xB7AA, 0x8E49, 0xB7AB, 0xB7A7, + 0xB7AC, 0xB7A8, 0xB7AD, 0xB7A9, 0xB7AE, 0x8E4A, 0xB7AF, 0x8E4B, + 0xB7B0, 0x8E4C, 0xB7B1, 0x8E4D, 0xB7B2, 0x8E4E, 0xB7B3, 0x8E4F, + 0xB7B4, 0xB7AA, 0xB7B5, 0xB7AB, 0xB7B6, 0x8E50, 0xB7B7, 0x8E51, + 0xB7B8, 0xB7AC, 0xB7B9, 0x8E52, 0xB7BA, 0x8E53, 0xB7BB, 0x8E54, + 0xB7BC, 0x8E55, 0xB7BD, 0x8E56, 0xB7BE, 0x8E57, 0xB7BF, 0x8E58, + 0xB7C0, 0x8E59, 0xB7C1, 0x8E5A, 0xB7C2, 0x8E61, 0xB7C3, 0x8E62, + 0xB7C4, 0x8E63, 0xB7C5, 0x8E64, 0xB7C6, 0x8E65, 0xB7C7, 0xB7AD, + 0xB7C8, 0x8E66, 0xB7C9, 0xB7AE, 0xB7CA, 0x8E67, 0xB7CB, 0x8E68, + 0xB7CC, 0x8E69, 0xB7CD, 0x8E6A, 0xB7CE, 0x8E6B, 0xB7CF, 0x8E6C, + 0xB7D0, 0x8E6D, 0xB7D1, 0x8E6E, 0xB7D2, 0x8E6F, 0xB7D3, 0x8E70, + 0xB7D4, 0x8E71, 0xB7D5, 0x8E72, 0xB7D6, 0x8E73, 0xB7D7, 0x8E74, + 0xB7D8, 0x8E75, 0xB7D9, 0x8E76, 0xB7DA, 0x8E77, 0xB7DB, 0x8E78, + 0xB7DC, 0x8E79, 0xB7DD, 0x8E7A, 0xB7DE, 0x8E81, 0xB7DF, 0x8E82, + 0xB7E0, 0x8E83, 0xB7E1, 0x8E84, 0xB7E2, 0x8E85, 0xB7E3, 0x8E86, + 0xB7E4, 0x8E87, 0xB7E5, 0x8E88, 0xB7E6, 0x8E89, 0xB7E7, 0x8E8A, + 0xB7E8, 0x8E8B, 0xB7E9, 0x8E8C, 0xB7EA, 0x8E8D, 0xB7EB, 0x8E8E, + 0xB7EC, 0xB7AF, 0xB7ED, 0xB7B0, 0xB7EE, 0x8E8F, 0xB7EF, 0x8E90, + 0xB7F0, 0xB7B1, 0xB7F1, 0x8E91, 0xB7F2, 0x8E92, 0xB7F3, 0x8E93, + 0xB7F4, 0xB7B2, 0xB7F5, 0x8E94, 0xB7F6, 0x8E95, 0xB7F7, 0x8E96, + 0xB7F8, 0x8E97, 0xB7F9, 0x8E98, 0xB7FA, 0x8E99, 0xB7FB, 0x8E9A, + 0xB7FC, 0xB7B3, 0xB7FD, 0xB7B4, 0xB7FE, 0x8E9B, 0xB7FF, 0xB7B5, + 0xB800, 0xB7B6, 0xB801, 0xB7B7, 0xB802, 0x8E9C, 0xB803, 0x8E9D, + 0xB804, 0x8E9E, 0xB805, 0x8E9F, 0xB806, 0x8EA0, 0xB807, 0xB7B8, + 0xB808, 0xB7B9, 0xB809, 0xB7BA, 0xB80A, 0x8EA1, 0xB80B, 0x8EA2, + 0xB80C, 0xB7BB, 0xB80D, 0x8EA3, 0xB80E, 0x8EA4, 0xB80F, 0x8EA5, + 0xB810, 0xB7BC, 0xB811, 0x8EA6, 0xB812, 0x8EA7, 0xB813, 0x8EA8, + 0xB814, 0x8EA9, 0xB815, 0x8EAA, 0xB816, 0x8EAB, 0xB817, 0x8EAC, + 0xB818, 0xB7BD, 0xB819, 0xB7BE, 0xB81A, 0x8EAD, 0xB81B, 0xB7BF, + 0xB81C, 0x8EAE, 0xB81D, 0xB7C0, 0xB81E, 0x8EAF, 0xB81F, 0x8EB0, + 0xB820, 0x8EB1, 0xB821, 0x8EB2, 0xB822, 0x8EB3, 0xB823, 0x8EB4, + 0xB824, 0xB7C1, 0xB825, 0xB7C2, 0xB826, 0x8EB5, 0xB827, 0x8EB6, + 0xB828, 0xB7C3, 0xB829, 0x8EB7, 0xB82A, 0x8EB8, 0xB82B, 0x8EB9, + 0xB82C, 0xB7C4, 0xB82D, 0x8EBA, 0xB82E, 0x8EBB, 0xB82F, 0x8EBC, + 0xB830, 0x8EBD, 0xB831, 0x8EBE, 0xB832, 0x8EBF, 0xB833, 0x8EC0, + 0xB834, 0xB7C5, 0xB835, 0xB7C6, 0xB836, 0x8EC1, 0xB837, 0xB7C7, + 0xB838, 0xB7C8, 0xB839, 0xB7C9, 0xB83A, 0x8EC2, 0xB83B, 0x8EC3, + 0xB83C, 0x8EC4, 0xB83D, 0x8EC5, 0xB83E, 0x8EC6, 0xB83F, 0x8EC7, + 0xB840, 0xB7CA, 0xB841, 0x8EC8, 0xB842, 0x8EC9, 0xB843, 0x8ECA, + 0xB844, 0xB7CB, 0xB845, 0x8ECB, 0xB846, 0x8ECC, 0xB847, 0x8ECD, + 0xB848, 0x8ECE, 0xB849, 0x8ECF, 0xB84A, 0x8ED0, 0xB84B, 0x8ED1, + 0xB84C, 0x8ED2, 0xB84D, 0x8ED3, 0xB84E, 0x8ED4, 0xB84F, 0x8ED5, + 0xB850, 0x8ED6, 0xB851, 0xB7CC, 0xB852, 0x8ED7, 0xB853, 0xB7CD, + 0xB854, 0x8ED8, 0xB855, 0x8ED9, 0xB856, 0x8EDA, 0xB857, 0x8EDB, + 0xB858, 0x8EDC, 0xB859, 0x8EDD, 0xB85A, 0x8EDE, 0xB85B, 0x8EDF, + 0xB85C, 0xB7CE, 0xB85D, 0xB7CF, 0xB85E, 0x8EE0, 0xB85F, 0x8EE1, + 0xB860, 0xB7D0, 0xB861, 0x8EE2, 0xB862, 0x8EE3, 0xB863, 0x8EE4, + 0xB864, 0xB7D1, 0xB865, 0x8EE5, 0xB866, 0x8EE6, 0xB867, 0x8EE7, + 0xB868, 0x8EE8, 0xB869, 0x8EE9, 0xB86A, 0x8EEA, 0xB86B, 0x8EEB, + 0xB86C, 0xB7D2, 0xB86D, 0xB7D3, 0xB86E, 0x8EEC, 0xB86F, 0xB7D4, + 0xB870, 0x8EED, 0xB871, 0xB7D5, 0xB872, 0x8EEE, 0xB873, 0x8EEF, + 0xB874, 0x8EF0, 0xB875, 0x8EF1, 0xB876, 0x8EF2, 0xB877, 0x8EF3, + 0xB878, 0xB7D6, 0xB879, 0x8EF4, 0xB87A, 0x8EF5, 0xB87B, 0x8EF6, + 0xB87C, 0xB7D7, 0xB87D, 0x8EF7, 0xB87E, 0x8EF8, 0xB87F, 0x8EF9, + 0xB880, 0x8EFA, 0xB881, 0x8EFB, 0xB882, 0x8EFC, 0xB883, 0x8EFD, + 0xB884, 0x8EFE, 0xB885, 0x8F41, 0xB886, 0x8F42, 0xB887, 0x8F43, + 0xB888, 0x8F44, 0xB889, 0x8F45, 0xB88A, 0x8F46, 0xB88B, 0x8F47, + 0xB88C, 0x8F48, 0xB88D, 0xB7D8, 0xB88E, 0x8F49, 0xB88F, 0x8F4A, + 0xB890, 0x8F4B, 0xB891, 0x8F4C, 0xB892, 0x8F4D, 0xB893, 0x8F4E, + 0xB894, 0x8F4F, 0xB895, 0x8F50, 0xB896, 0x8F51, 0xB897, 0x8F52, + 0xB898, 0x8F53, 0xB899, 0x8F54, 0xB89A, 0x8F55, 0xB89B, 0x8F56, + 0xB89C, 0x8F57, 0xB89D, 0x8F58, 0xB89E, 0x8F59, 0xB89F, 0x8F5A, + 0xB8A0, 0x8F61, 0xB8A1, 0x8F62, 0xB8A2, 0x8F63, 0xB8A3, 0x8F64, + 0xB8A4, 0x8F65, 0xB8A5, 0x8F66, 0xB8A6, 0x8F67, 0xB8A7, 0x8F68, + 0xB8A8, 0xB7D9, 0xB8A9, 0x8F69, 0xB8AA, 0x8F6A, 0xB8AB, 0x8F6B, + 0xB8AC, 0x8F6C, 0xB8AD, 0x8F6D, 0xB8AE, 0x8F6E, 0xB8AF, 0x8F6F, + 0xB8B0, 0xB7DA, 0xB8B1, 0x8F70, 0xB8B2, 0x8F71, 0xB8B3, 0x8F72, + 0xB8B4, 0xB7DB, 0xB8B5, 0x8F73, 0xB8B6, 0x8F74, 0xB8B7, 0x8F75, + 0xB8B8, 0xB7DC, 0xB8B9, 0x8F76, 0xB8BA, 0x8F77, 0xB8BB, 0x8F78, + 0xB8BC, 0x8F79, 0xB8BD, 0x8F7A, 0xB8BE, 0x8F81, 0xB8BF, 0x8F82, + 0xB8C0, 0xB7DD, 0xB8C1, 0xB7DE, 0xB8C2, 0x8F83, 0xB8C3, 0xB7DF, + 0xB8C4, 0x8F84, 0xB8C5, 0xB7E0, 0xB8C6, 0x8F85, 0xB8C7, 0x8F86, + 0xB8C8, 0x8F87, 0xB8C9, 0x8F88, 0xB8CA, 0x8F89, 0xB8CB, 0x8F8A, + 0xB8CC, 0xB7E1, 0xB8CD, 0x8F8B, 0xB8CE, 0x8F8C, 0xB8CF, 0x8F8D, + 0xB8D0, 0xB7E2, 0xB8D1, 0x8F8E, 0xB8D2, 0x8F8F, 0xB8D3, 0x8F90, + 0xB8D4, 0xB7E3, 0xB8D5, 0x8F91, 0xB8D6, 0x8F92, 0xB8D7, 0x8F93, + 0xB8D8, 0x8F94, 0xB8D9, 0x8F95, 0xB8DA, 0x8F96, 0xB8DB, 0x8F97, + 0xB8DC, 0x8F98, 0xB8DD, 0xB7E4, 0xB8DE, 0x8F99, 0xB8DF, 0xB7E5, + 0xB8E0, 0x8F9A, 0xB8E1, 0xB7E6, 0xB8E2, 0x8F9B, 0xB8E3, 0x8F9C, + 0xB8E4, 0x8F9D, 0xB8E5, 0x8F9E, 0xB8E6, 0x8F9F, 0xB8E7, 0x8FA0, + 0xB8E8, 0xB7E7, 0xB8E9, 0xB7E8, 0xB8EA, 0x8FA1, 0xB8EB, 0x8FA2, + 0xB8EC, 0xB7E9, 0xB8ED, 0x8FA3, 0xB8EE, 0x8FA4, 0xB8EF, 0x8FA5, + 0xB8F0, 0xB7EA, 0xB8F1, 0x8FA6, 0xB8F2, 0x8FA7, 0xB8F3, 0x8FA8, + 0xB8F4, 0x8FA9, 0xB8F5, 0x8FAA, 0xB8F6, 0x8FAB, 0xB8F7, 0x8FAC, + 0xB8F8, 0xB7EB, 0xB8F9, 0xB7EC, 0xB8FA, 0x8FAD, 0xB8FB, 0xB7ED, + 0xB8FC, 0x8FAE, 0xB8FD, 0xB7EE, 0xB8FE, 0x8FAF, 0xB8FF, 0x8FB0, + 0xB900, 0x8FB1, 0xB901, 0x8FB2, 0xB902, 0x8FB3, 0xB903, 0x8FB4, + 0xB904, 0xB7EF, 0xB905, 0x8FB5, 0xB906, 0x8FB6, 0xB907, 0x8FB7, + 0xB908, 0x8FB8, 0xB909, 0x8FB9, 0xB90A, 0x8FBA, 0xB90B, 0x8FBB, + 0xB90C, 0x8FBC, 0xB90D, 0x8FBD, 0xB90E, 0x8FBE, 0xB90F, 0x8FBF, + 0xB910, 0x8FC0, 0xB911, 0x8FC1, 0xB912, 0x8FC2, 0xB913, 0x8FC3, + 0xB914, 0x8FC4, 0xB915, 0x8FC5, 0xB916, 0x8FC6, 0xB917, 0x8FC7, + 0xB918, 0xB7F0, 0xB919, 0x8FC8, 0xB91A, 0x8FC9, 0xB91B, 0x8FCA, + 0xB91C, 0x8FCB, 0xB91D, 0x8FCC, 0xB91E, 0x8FCD, 0xB91F, 0x8FCE, + 0xB920, 0xB7F1, 0xB921, 0x8FCF, 0xB922, 0x8FD0, 0xB923, 0x8FD1, + 0xB924, 0x8FD2, 0xB925, 0x8FD3, 0xB926, 0x8FD4, 0xB927, 0x8FD5, + 0xB928, 0x8FD6, 0xB929, 0x8FD7, 0xB92A, 0x8FD8, 0xB92B, 0x8FD9, + 0xB92C, 0x8FDA, 0xB92D, 0x8FDB, 0xB92E, 0x8FDC, 0xB92F, 0x8FDD, + 0xB930, 0x8FDE, 0xB931, 0x8FDF, 0xB932, 0x8FE0, 0xB933, 0x8FE1, + 0xB934, 0x8FE2, 0xB935, 0x8FE3, 0xB936, 0x8FE4, 0xB937, 0x8FE5, + 0xB938, 0x8FE6, 0xB939, 0x8FE7, 0xB93A, 0x8FE8, 0xB93B, 0x8FE9, + 0xB93C, 0xB7F2, 0xB93D, 0xB7F3, 0xB93E, 0x8FEA, 0xB93F, 0x8FEB, + 0xB940, 0xB7F4, 0xB941, 0x8FEC, 0xB942, 0x8FED, 0xB943, 0x8FEE, + 0xB944, 0xB7F5, 0xB945, 0x8FEF, 0xB946, 0x8FF0, 0xB947, 0x8FF1, + 0xB948, 0x8FF2, 0xB949, 0x8FF3, 0xB94A, 0x8FF4, 0xB94B, 0x8FF5, + 0xB94C, 0xB7F6, 0xB94D, 0x8FF6, 0xB94E, 0x8FF7, 0xB94F, 0xB7F7, + 0xB950, 0x8FF8, 0xB951, 0xB7F8, 0xB952, 0x8FF9, 0xB953, 0x8FFA, + 0xB954, 0x8FFB, 0xB955, 0x8FFC, 0xB956, 0x8FFD, 0xB957, 0x8FFE, + 0xB958, 0xB7F9, 0xB959, 0xB7FA, 0xB95A, 0x9041, 0xB95B, 0x9042, + 0xB95C, 0xB7FB, 0xB95D, 0x9043, 0xB95E, 0x9044, 0xB95F, 0x9045, + 0xB960, 0xB7FC, 0xB961, 0x9046, 0xB962, 0x9047, 0xB963, 0x9048, + 0xB964, 0x9049, 0xB965, 0x904A, 0xB966, 0x904B, 0xB967, 0x904C, + 0xB968, 0xB7FD, 0xB969, 0xB7FE, 0xB96A, 0x904D, 0xB96B, 0xB8A1, + 0xB96C, 0x904E, 0xB96D, 0xB8A2, 0xB96E, 0x904F, 0xB96F, 0x9050, + 0xB970, 0x9051, 0xB971, 0x9052, 0xB972, 0x9053, 0xB973, 0x9054, + 0xB974, 0xB8A3, 0xB975, 0xB8A4, 0xB976, 0x9055, 0xB977, 0x9056, + 0xB978, 0xB8A5, 0xB979, 0x9057, 0xB97A, 0x9058, 0xB97B, 0x9059, + 0xB97C, 0xB8A6, 0xB97D, 0x905A, 0xB97E, 0x9061, 0xB97F, 0x9062, + 0xB980, 0x9063, 0xB981, 0x9064, 0xB982, 0x9065, 0xB983, 0x9066, + 0xB984, 0xB8A7, 0xB985, 0xB8A8, 0xB986, 0x9067, 0xB987, 0xB8A9, + 0xB988, 0x9068, 0xB989, 0xB8AA, 0xB98A, 0xB8AB, 0xB98B, 0x9069, + 0xB98C, 0x906A, 0xB98D, 0xB8AC, 0xB98E, 0xB8AD, 0xB98F, 0x906B, + 0xB990, 0x906C, 0xB991, 0x906D, 0xB992, 0x906E, 0xB993, 0x906F, + 0xB994, 0x9070, 0xB995, 0x9071, 0xB996, 0x9072, 0xB997, 0x9073, + 0xB998, 0x9074, 0xB999, 0x9075, 0xB99A, 0x9076, 0xB99B, 0x9077, + 0xB99C, 0x9078, 0xB99D, 0x9079, 0xB99E, 0x907A, 0xB99F, 0x9081, + 0xB9A0, 0x9082, 0xB9A1, 0x9083, 0xB9A2, 0x9084, 0xB9A3, 0x9085, + 0xB9A4, 0x9086, 0xB9A5, 0x9087, 0xB9A6, 0x9088, 0xB9A7, 0x9089, + 0xB9A8, 0x908A, 0xB9A9, 0x908B, 0xB9AA, 0x908C, 0xB9AB, 0x908D, + 0xB9AC, 0xB8AE, 0xB9AD, 0xB8AF, 0xB9AE, 0x908E, 0xB9AF, 0x908F, + 0xB9B0, 0xB8B0, 0xB9B1, 0x9090, 0xB9B2, 0x9091, 0xB9B3, 0x9092, + 0xB9B4, 0xB8B1, 0xB9B5, 0x9093, 0xB9B6, 0x9094, 0xB9B7, 0x9095, + 0xB9B8, 0x9096, 0xB9B9, 0x9097, 0xB9BA, 0x9098, 0xB9BB, 0x9099, + 0xB9BC, 0xB8B2, 0xB9BD, 0xB8B3, 0xB9BE, 0x909A, 0xB9BF, 0xB8B4, + 0xB9C0, 0x909B, 0xB9C1, 0xB8B5, 0xB9C2, 0x909C, 0xB9C3, 0x909D, + 0xB9C4, 0x909E, 0xB9C5, 0x909F, 0xB9C6, 0x90A0, 0xB9C7, 0x90A1, + 0xB9C8, 0xB8B6, 0xB9C9, 0xB8B7, 0xB9CA, 0x90A2, 0xB9CB, 0x90A3, + 0xB9CC, 0xB8B8, 0xB9CD, 0x90A4, 0xB9CE, 0xB8B9, 0xB9CF, 0xB8BA, + 0xB9D0, 0xB8BB, 0xB9D1, 0xB8BC, 0xB9D2, 0xB8BD, 0xB9D3, 0x90A5, + 0xB9D4, 0x90A6, 0xB9D5, 0x90A7, 0xB9D6, 0x90A8, 0xB9D7, 0x90A9, + 0xB9D8, 0xB8BE, 0xB9D9, 0xB8BF, 0xB9DA, 0x90AA, 0xB9DB, 0xB8C0, + 0xB9DC, 0x90AB, 0xB9DD, 0xB8C1, 0xB9DE, 0xB8C2, 0xB9DF, 0x90AC, + 0xB9E0, 0x90AD, 0xB9E1, 0xB8C3, 0xB9E2, 0x90AE, 0xB9E3, 0xB8C4, + 0xB9E4, 0xB8C5, 0xB9E5, 0xB8C6, 0xB9E6, 0x90AF, 0xB9E7, 0x90B0, + 0xB9E8, 0xB8C7, 0xB9E9, 0x90B1, 0xB9EA, 0x90B2, 0xB9EB, 0x90B3, + 0xB9EC, 0xB8C8, 0xB9ED, 0x90B4, 0xB9EE, 0x90B5, 0xB9EF, 0x90B6, + 0xB9F0, 0x90B7, 0xB9F1, 0x90B8, 0xB9F2, 0x90B9, 0xB9F3, 0x90BA, + 0xB9F4, 0xB8C9, 0xB9F5, 0xB8CA, 0xB9F6, 0x90BB, 0xB9F7, 0xB8CB, + 0xB9F8, 0xB8CC, 0xB9F9, 0xB8CD, 0xB9FA, 0xB8CE, 0xB9FB, 0x90BC, + 0xB9FC, 0x90BD, 0xB9FD, 0x90BE, 0xB9FE, 0x90BF, 0xB9FF, 0x90C0, + 0xBA00, 0xB8CF, 0xBA01, 0xB8D0, 0xBA02, 0x90C1, 0xBA03, 0x90C2, + 0xBA04, 0x90C3, 0xBA05, 0x90C4, 0xBA06, 0x90C5, 0xBA07, 0x90C6, + 0xBA08, 0xB8D1, 0xBA09, 0x90C7, 0xBA0A, 0x90C8, 0xBA0B, 0x90C9, + 0xBA0C, 0x90CA, 0xBA0D, 0x90CB, 0xBA0E, 0x90CC, 0xBA0F, 0x90CD, + 0xBA10, 0x90CE, 0xBA11, 0x90CF, 0xBA12, 0x90D0, 0xBA13, 0x90D1, + 0xBA14, 0x90D2, 0xBA15, 0xB8D2, 0xBA16, 0x90D3, 0xBA17, 0x90D4, + 0xBA18, 0x90D5, 0xBA19, 0x90D6, 0xBA1A, 0x90D7, 0xBA1B, 0x90D8, + 0xBA1C, 0x90D9, 0xBA1D, 0x90DA, 0xBA1E, 0x90DB, 0xBA1F, 0x90DC, + 0xBA20, 0x90DD, 0xBA21, 0x90DE, 0xBA22, 0x90DF, 0xBA23, 0x90E0, + 0xBA24, 0x90E1, 0xBA25, 0x90E2, 0xBA26, 0x90E3, 0xBA27, 0x90E4, + 0xBA28, 0x90E5, 0xBA29, 0x90E6, 0xBA2A, 0x90E7, 0xBA2B, 0x90E8, + 0xBA2C, 0x90E9, 0xBA2D, 0x90EA, 0xBA2E, 0x90EB, 0xBA2F, 0x90EC, + 0xBA30, 0x90ED, 0xBA31, 0x90EE, 0xBA32, 0x90EF, 0xBA33, 0x90F0, + 0xBA34, 0x90F1, 0xBA35, 0x90F2, 0xBA36, 0x90F3, 0xBA37, 0x90F4, + 0xBA38, 0xB8D3, 0xBA39, 0xB8D4, 0xBA3A, 0x90F5, 0xBA3B, 0x90F6, + 0xBA3C, 0xB8D5, 0xBA3D, 0x90F7, 0xBA3E, 0x90F8, 0xBA3F, 0x90F9, + 0xBA40, 0xB8D6, 0xBA41, 0x90FA, 0xBA42, 0xB8D7, 0xBA43, 0x90FB, + 0xBA44, 0x90FC, 0xBA45, 0x90FD, 0xBA46, 0x90FE, 0xBA47, 0x9141, + 0xBA48, 0xB8D8, 0xBA49, 0xB8D9, 0xBA4A, 0x9142, 0xBA4B, 0xB8DA, + 0xBA4C, 0x9143, 0xBA4D, 0xB8DB, 0xBA4E, 0xB8DC, 0xBA4F, 0x9144, + 0xBA50, 0x9145, 0xBA51, 0x9146, 0xBA52, 0x9147, 0xBA53, 0xB8DD, + 0xBA54, 0xB8DE, 0xBA55, 0xB8DF, 0xBA56, 0x9148, 0xBA57, 0x9149, + 0xBA58, 0xB8E0, 0xBA59, 0x914A, 0xBA5A, 0x914B, 0xBA5B, 0x914C, + 0xBA5C, 0xB8E1, 0xBA5D, 0x914D, 0xBA5E, 0x914E, 0xBA5F, 0x914F, + 0xBA60, 0x9150, 0xBA61, 0x9151, 0xBA62, 0x9152, 0xBA63, 0x9153, + 0xBA64, 0xB8E2, 0xBA65, 0xB8E3, 0xBA66, 0x9154, 0xBA67, 0xB8E4, + 0xBA68, 0xB8E5, 0xBA69, 0xB8E6, 0xBA6A, 0x9155, 0xBA6B, 0x9156, + 0xBA6C, 0x9157, 0xBA6D, 0x9158, 0xBA6E, 0x9159, 0xBA6F, 0x915A, + 0xBA70, 0xB8E7, 0xBA71, 0xB8E8, 0xBA72, 0x9161, 0xBA73, 0x9162, + 0xBA74, 0xB8E9, 0xBA75, 0x9163, 0xBA76, 0x9164, 0xBA77, 0x9165, + 0xBA78, 0xB8EA, 0xBA79, 0x9166, 0xBA7A, 0x9167, 0xBA7B, 0x9168, + 0xBA7C, 0x9169, 0xBA7D, 0x916A, 0xBA7E, 0x916B, 0xBA7F, 0x916C, + 0xBA80, 0x916D, 0xBA81, 0x916E, 0xBA82, 0x916F, 0xBA83, 0xB8EB, + 0xBA84, 0xB8EC, 0xBA85, 0xB8ED, 0xBA86, 0x9170, 0xBA87, 0xB8EE, + 0xBA88, 0x9171, 0xBA89, 0x9172, 0xBA8A, 0x9173, 0xBA8B, 0x9174, + 0xBA8C, 0xB8EF, 0xBA8D, 0x9175, 0xBA8E, 0x9176, 0xBA8F, 0x9177, + 0xBA90, 0x9178, 0xBA91, 0x9179, 0xBA92, 0x917A, 0xBA93, 0x9181, + 0xBA94, 0x9182, 0xBA95, 0x9183, 0xBA96, 0x9184, 0xBA97, 0x9185, + 0xBA98, 0x9186, 0xBA99, 0x9187, 0xBA9A, 0x9188, 0xBA9B, 0x9189, + 0xBA9C, 0x918A, 0xBA9D, 0x918B, 0xBA9E, 0x918C, 0xBA9F, 0x918D, + 0xBAA0, 0x918E, 0xBAA1, 0x918F, 0xBAA2, 0x9190, 0xBAA3, 0x9191, + 0xBAA4, 0x9192, 0xBAA5, 0x9193, 0xBAA6, 0x9194, 0xBAA7, 0x9195, + 0xBAA8, 0xB8F0, 0xBAA9, 0xB8F1, 0xBAAA, 0x9196, 0xBAAB, 0xB8F2, + 0xBAAC, 0xB8F3, 0xBAAD, 0x9197, 0xBAAE, 0x9198, 0xBAAF, 0x9199, + 0xBAB0, 0xB8F4, 0xBAB1, 0x919A, 0xBAB2, 0xB8F5, 0xBAB3, 0x919B, + 0xBAB4, 0x919C, 0xBAB5, 0x919D, 0xBAB6, 0x919E, 0xBAB7, 0x919F, + 0xBAB8, 0xB8F6, 0xBAB9, 0xB8F7, 0xBABA, 0x91A0, 0xBABB, 0xB8F8, + 0xBABC, 0x91A1, 0xBABD, 0xB8F9, 0xBABE, 0x91A2, 0xBABF, 0x91A3, + 0xBAC0, 0x91A4, 0xBAC1, 0x91A5, 0xBAC2, 0x91A6, 0xBAC3, 0x91A7, + 0xBAC4, 0xB8FA, 0xBAC5, 0x91A8, 0xBAC6, 0x91A9, 0xBAC7, 0x91AA, + 0xBAC8, 0xB8FB, 0xBAC9, 0x91AB, 0xBACA, 0x91AC, 0xBACB, 0x91AD, + 0xBACC, 0x91AE, 0xBACD, 0x91AF, 0xBACE, 0x91B0, 0xBACF, 0x91B1, + 0xBAD0, 0x91B2, 0xBAD1, 0x91B3, 0xBAD2, 0x91B4, 0xBAD3, 0x91B5, + 0xBAD4, 0x91B6, 0xBAD5, 0x91B7, 0xBAD6, 0x91B8, 0xBAD7, 0x91B9, + 0xBAD8, 0xB8FC, 0xBAD9, 0xB8FD, 0xBADA, 0x91BA, 0xBADB, 0x91BB, + 0xBADC, 0x91BC, 0xBADD, 0x91BD, 0xBADE, 0x91BE, 0xBADF, 0x91BF, + 0xBAE0, 0x91C0, 0xBAE1, 0x91C1, 0xBAE2, 0x91C2, 0xBAE3, 0x91C3, + 0xBAE4, 0x91C4, 0xBAE5, 0x91C5, 0xBAE6, 0x91C6, 0xBAE7, 0x91C7, + 0xBAE8, 0x91C8, 0xBAE9, 0x91C9, 0xBAEA, 0x91CA, 0xBAEB, 0x91CB, + 0xBAEC, 0x91CC, 0xBAED, 0x91CD, 0xBAEE, 0x91CE, 0xBAEF, 0x91CF, + 0xBAF0, 0x91D0, 0xBAF1, 0x91D1, 0xBAF2, 0x91D2, 0xBAF3, 0x91D3, + 0xBAF4, 0x91D4, 0xBAF5, 0x91D5, 0xBAF6, 0x91D6, 0xBAF7, 0x91D7, + 0xBAF8, 0x91D8, 0xBAF9, 0x91D9, 0xBAFA, 0x91DA, 0xBAFB, 0x91DB, + 0xBAFC, 0xB8FE, 0xBAFD, 0x91DC, 0xBAFE, 0x91DD, 0xBAFF, 0x91DE, + 0xBB00, 0xB9A1, 0xBB01, 0x91DF, 0xBB02, 0x91E0, 0xBB03, 0x91E1, + 0xBB04, 0xB9A2, 0xBB05, 0x91E2, 0xBB06, 0x91E3, 0xBB07, 0x91E4, + 0xBB08, 0x91E5, 0xBB09, 0x91E6, 0xBB0A, 0x91E7, 0xBB0B, 0x91E8, + 0xBB0C, 0x91E9, 0xBB0D, 0xB9A3, 0xBB0E, 0x91EA, 0xBB0F, 0xB9A4, + 0xBB10, 0x91EB, 0xBB11, 0xB9A5, 0xBB12, 0x91EC, 0xBB13, 0x91ED, + 0xBB14, 0x91EE, 0xBB15, 0x91EF, 0xBB16, 0x91F0, 0xBB17, 0x91F1, + 0xBB18, 0xB9A6, 0xBB19, 0x91F2, 0xBB1A, 0x91F3, 0xBB1B, 0x91F4, + 0xBB1C, 0xB9A7, 0xBB1D, 0x91F5, 0xBB1E, 0x91F6, 0xBB1F, 0x91F7, + 0xBB20, 0xB9A8, 0xBB21, 0x91F8, 0xBB22, 0x91F9, 0xBB23, 0x91FA, + 0xBB24, 0x91FB, 0xBB25, 0x91FC, 0xBB26, 0x91FD, 0xBB27, 0x91FE, + 0xBB28, 0x9241, 0xBB29, 0xB9A9, 0xBB2A, 0x9242, 0xBB2B, 0xB9AA, + 0xBB2C, 0x9243, 0xBB2D, 0x9244, 0xBB2E, 0x9245, 0xBB2F, 0x9246, + 0xBB30, 0x9247, 0xBB31, 0x9248, 0xBB32, 0x9249, 0xBB33, 0x924A, + 0xBB34, 0xB9AB, 0xBB35, 0xB9AC, 0xBB36, 0xB9AD, 0xBB37, 0x924B, + 0xBB38, 0xB9AE, 0xBB39, 0x924C, 0xBB3A, 0x924D, 0xBB3B, 0xB9AF, + 0xBB3C, 0xB9B0, 0xBB3D, 0xB9B1, 0xBB3E, 0xB9B2, 0xBB3F, 0x924E, + 0xBB40, 0x924F, 0xBB41, 0x9250, 0xBB42, 0x9251, 0xBB43, 0x9252, + 0xBB44, 0xB9B3, 0xBB45, 0xB9B4, 0xBB46, 0x9253, 0xBB47, 0xB9B5, + 0xBB48, 0x9254, 0xBB49, 0xB9B6, 0xBB4A, 0x9255, 0xBB4B, 0x9256, + 0xBB4C, 0x9257, 0xBB4D, 0xB9B7, 0xBB4E, 0x9258, 0xBB4F, 0xB9B8, + 0xBB50, 0xB9B9, 0xBB51, 0x9259, 0xBB52, 0x925A, 0xBB53, 0x9261, + 0xBB54, 0xB9BA, 0xBB55, 0x9262, 0xBB56, 0x9263, 0xBB57, 0x9264, + 0xBB58, 0xB9BB, 0xBB59, 0x9265, 0xBB5A, 0x9266, 0xBB5B, 0x9267, + 0xBB5C, 0x9268, 0xBB5D, 0x9269, 0xBB5E, 0x926A, 0xBB5F, 0x926B, + 0xBB60, 0x926C, 0xBB61, 0xB9BC, 0xBB62, 0x926D, 0xBB63, 0xB9BD, + 0xBB64, 0x926E, 0xBB65, 0x926F, 0xBB66, 0x9270, 0xBB67, 0x9271, + 0xBB68, 0x9272, 0xBB69, 0x9273, 0xBB6A, 0x9274, 0xBB6B, 0x9275, + 0xBB6C, 0xB9BE, 0xBB6D, 0x9276, 0xBB6E, 0x9277, 0xBB6F, 0x9278, + 0xBB70, 0x9279, 0xBB71, 0x927A, 0xBB72, 0x9281, 0xBB73, 0x9282, + 0xBB74, 0x9283, 0xBB75, 0x9284, 0xBB76, 0x9285, 0xBB77, 0x9286, + 0xBB78, 0x9287, 0xBB79, 0x9288, 0xBB7A, 0x9289, 0xBB7B, 0x928A, + 0xBB7C, 0x928B, 0xBB7D, 0x928C, 0xBB7E, 0x928D, 0xBB7F, 0x928E, + 0xBB80, 0x928F, 0xBB81, 0x9290, 0xBB82, 0x9291, 0xBB83, 0x9292, + 0xBB84, 0x9293, 0xBB85, 0x9294, 0xBB86, 0x9295, 0xBB87, 0x9296, + 0xBB88, 0xB9BF, 0xBB89, 0x9297, 0xBB8A, 0x9298, 0xBB8B, 0x9299, + 0xBB8C, 0xB9C0, 0xBB8D, 0x929A, 0xBB8E, 0x929B, 0xBB8F, 0x929C, + 0xBB90, 0xB9C1, 0xBB91, 0x929D, 0xBB92, 0x929E, 0xBB93, 0x929F, + 0xBB94, 0x92A0, 0xBB95, 0x92A1, 0xBB96, 0x92A2, 0xBB97, 0x92A3, + 0xBB98, 0x92A4, 0xBB99, 0x92A5, 0xBB9A, 0x92A6, 0xBB9B, 0x92A7, + 0xBB9C, 0x92A8, 0xBB9D, 0x92A9, 0xBB9E, 0x92AA, 0xBB9F, 0x92AB, + 0xBBA0, 0x92AC, 0xBBA1, 0x92AD, 0xBBA2, 0x92AE, 0xBBA3, 0x92AF, + 0xBBA4, 0xB9C2, 0xBBA5, 0x92B0, 0xBBA6, 0x92B1, 0xBBA7, 0x92B2, + 0xBBA8, 0xB9C3, 0xBBA9, 0x92B3, 0xBBAA, 0x92B4, 0xBBAB, 0x92B5, + 0xBBAC, 0xB9C4, 0xBBAD, 0x92B6, 0xBBAE, 0x92B7, 0xBBAF, 0x92B8, + 0xBBB0, 0x92B9, 0xBBB1, 0x92BA, 0xBBB2, 0x92BB, 0xBBB3, 0x92BC, + 0xBBB4, 0xB9C5, 0xBBB5, 0x92BD, 0xBBB6, 0x92BE, 0xBBB7, 0xB9C6, + 0xBBB8, 0x92BF, 0xBBB9, 0x92C0, 0xBBBA, 0x92C1, 0xBBBB, 0x92C2, + 0xBBBC, 0x92C3, 0xBBBD, 0x92C4, 0xBBBE, 0x92C5, 0xBBBF, 0x92C6, + 0xBBC0, 0xB9C7, 0xBBC1, 0x92C7, 0xBBC2, 0x92C8, 0xBBC3, 0x92C9, + 0xBBC4, 0xB9C8, 0xBBC5, 0x92CA, 0xBBC6, 0x92CB, 0xBBC7, 0x92CC, + 0xBBC8, 0xB9C9, 0xBBC9, 0x92CD, 0xBBCA, 0x92CE, 0xBBCB, 0x92CF, + 0xBBCC, 0x92D0, 0xBBCD, 0x92D1, 0xBBCE, 0x92D2, 0xBBCF, 0x92D3, + 0xBBD0, 0xB9CA, 0xBBD1, 0x92D4, 0xBBD2, 0x92D5, 0xBBD3, 0xB9CB, + 0xBBD4, 0x92D6, 0xBBD5, 0x92D7, 0xBBD6, 0x92D8, 0xBBD7, 0x92D9, + 0xBBD8, 0x92DA, 0xBBD9, 0x92DB, 0xBBDA, 0x92DC, 0xBBDB, 0x92DD, + 0xBBDC, 0x92DE, 0xBBDD, 0x92DF, 0xBBDE, 0x92E0, 0xBBDF, 0x92E1, + 0xBBE0, 0x92E2, 0xBBE1, 0x92E3, 0xBBE2, 0x92E4, 0xBBE3, 0x92E5, + 0xBBE4, 0x92E6, 0xBBE5, 0x92E7, 0xBBE6, 0x92E8, 0xBBE7, 0x92E9, + 0xBBE8, 0x92EA, 0xBBE9, 0x92EB, 0xBBEA, 0x92EC, 0xBBEB, 0x92ED, + 0xBBEC, 0x92EE, 0xBBED, 0x92EF, 0xBBEE, 0x92F0, 0xBBEF, 0x92F1, + 0xBBF0, 0x92F2, 0xBBF1, 0x92F3, 0xBBF2, 0x92F4, 0xBBF3, 0x92F5, + 0xBBF4, 0x92F6, 0xBBF5, 0x92F7, 0xBBF6, 0x92F8, 0xBBF7, 0x92F9, + 0xBBF8, 0xB9CC, 0xBBF9, 0xB9CD, 0xBBFA, 0x92FA, 0xBBFB, 0x92FB, + 0xBBFC, 0xB9CE, 0xBBFD, 0x92FC, 0xBBFE, 0x92FD, 0xBBFF, 0xB9CF, + 0xBC00, 0xB9D0, 0xBC01, 0x92FE, 0xBC02, 0xB9D1, 0xBC03, 0x9341, + 0xBC04, 0x9342, 0xBC05, 0x9343, 0xBC06, 0x9344, 0xBC07, 0x9345, + 0xBC08, 0xB9D2, 0xBC09, 0xB9D3, 0xBC0A, 0x9346, 0xBC0B, 0xB9D4, + 0xBC0C, 0xB9D5, 0xBC0D, 0xB9D6, 0xBC0E, 0x9347, 0xBC0F, 0xB9D7, + 0xBC10, 0x9348, 0xBC11, 0xB9D8, 0xBC12, 0x9349, 0xBC13, 0x934A, + 0xBC14, 0xB9D9, 0xBC15, 0xB9DA, 0xBC16, 0xB9DB, 0xBC17, 0xB9DC, + 0xBC18, 0xB9DD, 0xBC19, 0x934B, 0xBC1A, 0x934C, 0xBC1B, 0xB9DE, + 0xBC1C, 0xB9DF, 0xBC1D, 0xB9E0, 0xBC1E, 0xB9E1, 0xBC1F, 0xB9E2, + 0xBC20, 0x934D, 0xBC21, 0x934E, 0xBC22, 0x934F, 0xBC23, 0x9350, + 0xBC24, 0xB9E3, 0xBC25, 0xB9E4, 0xBC26, 0x9351, 0xBC27, 0xB9E5, + 0xBC28, 0x9352, 0xBC29, 0xB9E6, 0xBC2A, 0x9353, 0xBC2B, 0x9354, + 0xBC2C, 0x9355, 0xBC2D, 0xB9E7, 0xBC2E, 0x9356, 0xBC2F, 0x9357, + 0xBC30, 0xB9E8, 0xBC31, 0xB9E9, 0xBC32, 0x9358, 0xBC33, 0x9359, + 0xBC34, 0xB9EA, 0xBC35, 0x935A, 0xBC36, 0x9361, 0xBC37, 0x9362, + 0xBC38, 0xB9EB, 0xBC39, 0x9363, 0xBC3A, 0x9364, 0xBC3B, 0x9365, + 0xBC3C, 0x9366, 0xBC3D, 0x9367, 0xBC3E, 0x9368, 0xBC3F, 0x9369, + 0xBC40, 0xB9EC, 0xBC41, 0xB9ED, 0xBC42, 0x936A, 0xBC43, 0xB9EE, + 0xBC44, 0xB9EF, 0xBC45, 0xB9F0, 0xBC46, 0x936B, 0xBC47, 0x936C, + 0xBC48, 0x936D, 0xBC49, 0xB9F1, 0xBC4A, 0x936E, 0xBC4B, 0x936F, + 0xBC4C, 0xB9F2, 0xBC4D, 0xB9F3, 0xBC4E, 0x9370, 0xBC4F, 0x9371, + 0xBC50, 0xB9F4, 0xBC51, 0x9372, 0xBC52, 0x9373, 0xBC53, 0x9374, + 0xBC54, 0x9375, 0xBC55, 0x9376, 0xBC56, 0x9377, 0xBC57, 0x9378, + 0xBC58, 0x9379, 0xBC59, 0x937A, 0xBC5A, 0x9381, 0xBC5B, 0x9382, + 0xBC5C, 0x9383, 0xBC5D, 0xB9F5, 0xBC5E, 0x9384, 0xBC5F, 0x9385, + 0xBC60, 0x9386, 0xBC61, 0x9387, 0xBC62, 0x9388, 0xBC63, 0x9389, + 0xBC64, 0x938A, 0xBC65, 0x938B, 0xBC66, 0x938C, 0xBC67, 0x938D, + 0xBC68, 0x938E, 0xBC69, 0x938F, 0xBC6A, 0x9390, 0xBC6B, 0x9391, + 0xBC6C, 0x9392, 0xBC6D, 0x9393, 0xBC6E, 0x9394, 0xBC6F, 0x9395, + 0xBC70, 0x9396, 0xBC71, 0x9397, 0xBC72, 0x9398, 0xBC73, 0x9399, + 0xBC74, 0x939A, 0xBC75, 0x939B, 0xBC76, 0x939C, 0xBC77, 0x939D, + 0xBC78, 0x939E, 0xBC79, 0x939F, 0xBC7A, 0x93A0, 0xBC7B, 0x93A1, + 0xBC7C, 0x93A2, 0xBC7D, 0x93A3, 0xBC7E, 0x93A4, 0xBC7F, 0x93A5, + 0xBC80, 0x93A6, 0xBC81, 0x93A7, 0xBC82, 0x93A8, 0xBC83, 0x93A9, + 0xBC84, 0xB9F6, 0xBC85, 0xB9F7, 0xBC86, 0x93AA, 0xBC87, 0x93AB, + 0xBC88, 0xB9F8, 0xBC89, 0x93AC, 0xBC8A, 0x93AD, 0xBC8B, 0xB9F9, + 0xBC8C, 0xB9FA, 0xBC8D, 0x93AE, 0xBC8E, 0xB9FB, 0xBC8F, 0x93AF, + 0xBC90, 0x93B0, 0xBC91, 0x93B1, 0xBC92, 0x93B2, 0xBC93, 0x93B3, + 0xBC94, 0xB9FC, 0xBC95, 0xB9FD, 0xBC96, 0x93B4, 0xBC97, 0xB9FE, + 0xBC98, 0x93B5, 0xBC99, 0xBAA1, 0xBC9A, 0xBAA2, 0xBC9B, 0x93B6, + 0xBC9C, 0x93B7, 0xBC9D, 0x93B8, 0xBC9E, 0x93B9, 0xBC9F, 0x93BA, + 0xBCA0, 0xBAA3, 0xBCA1, 0xBAA4, 0xBCA2, 0x93BB, 0xBCA3, 0x93BC, + 0xBCA4, 0xBAA5, 0xBCA5, 0x93BD, 0xBCA6, 0x93BE, 0xBCA7, 0xBAA6, + 0xBCA8, 0xBAA7, 0xBCA9, 0x93BF, 0xBCAA, 0x93C0, 0xBCAB, 0x93C1, + 0xBCAC, 0x93C2, 0xBCAD, 0x93C3, 0xBCAE, 0x93C4, 0xBCAF, 0x93C5, + 0xBCB0, 0xBAA8, 0xBCB1, 0xBAA9, 0xBCB2, 0x93C6, 0xBCB3, 0xBAAA, + 0xBCB4, 0xBAAB, 0xBCB5, 0xBAAC, 0xBCB6, 0x93C7, 0xBCB7, 0x93C8, + 0xBCB8, 0x93C9, 0xBCB9, 0x93CA, 0xBCBA, 0x93CB, 0xBCBB, 0x93CC, + 0xBCBC, 0xBAAD, 0xBCBD, 0xBAAE, 0xBCBE, 0x93CD, 0xBCBF, 0x93CE, + 0xBCC0, 0xBAAF, 0xBCC1, 0x93CF, 0xBCC2, 0x93D0, 0xBCC3, 0x93D1, + 0xBCC4, 0xBAB0, 0xBCC5, 0x93D2, 0xBCC6, 0x93D3, 0xBCC7, 0x93D4, + 0xBCC8, 0x93D5, 0xBCC9, 0x93D6, 0xBCCA, 0x93D7, 0xBCCB, 0x93D8, + 0xBCCC, 0x93D9, 0xBCCD, 0xBAB1, 0xBCCE, 0x93DA, 0xBCCF, 0xBAB2, + 0xBCD0, 0xBAB3, 0xBCD1, 0xBAB4, 0xBCD2, 0x93DB, 0xBCD3, 0x93DC, + 0xBCD4, 0x93DD, 0xBCD5, 0xBAB5, 0xBCD6, 0x93DE, 0xBCD7, 0x93DF, + 0xBCD8, 0xBAB6, 0xBCD9, 0x93E0, 0xBCDA, 0x93E1, 0xBCDB, 0x93E2, + 0xBCDC, 0xBAB7, 0xBCDD, 0x93E3, 0xBCDE, 0x93E4, 0xBCDF, 0x93E5, + 0xBCE0, 0x93E6, 0xBCE1, 0x93E7, 0xBCE2, 0x93E8, 0xBCE3, 0x93E9, + 0xBCE4, 0x93EA, 0xBCE5, 0x93EB, 0xBCE6, 0x93EC, 0xBCE7, 0x93ED, + 0xBCE8, 0x93EE, 0xBCE9, 0x93EF, 0xBCEA, 0x93F0, 0xBCEB, 0x93F1, + 0xBCEC, 0x93F2, 0xBCED, 0x93F3, 0xBCEE, 0x93F4, 0xBCEF, 0x93F5, + 0xBCF0, 0x93F6, 0xBCF1, 0x93F7, 0xBCF2, 0x93F8, 0xBCF3, 0x93F9, + 0xBCF4, 0xBAB8, 0xBCF5, 0xBAB9, 0xBCF6, 0xBABA, 0xBCF7, 0x93FA, + 0xBCF8, 0xBABB, 0xBCF9, 0x93FB, 0xBCFA, 0x93FC, 0xBCFB, 0x93FD, + 0xBCFC, 0xBABC, 0xBCFD, 0x93FE, 0xBCFE, 0x9441, 0xBCFF, 0x9442, + 0xBD00, 0x9443, 0xBD01, 0x9444, 0xBD02, 0x9445, 0xBD03, 0x9446, + 0xBD04, 0xBABD, 0xBD05, 0xBABE, 0xBD06, 0x9447, 0xBD07, 0xBABF, + 0xBD08, 0x9448, 0xBD09, 0xBAC0, 0xBD0A, 0x9449, 0xBD0B, 0x944A, + 0xBD0C, 0x944B, 0xBD0D, 0x944C, 0xBD0E, 0x944D, 0xBD0F, 0x944E, + 0xBD10, 0xBAC1, 0xBD11, 0x944F, 0xBD12, 0x9450, 0xBD13, 0x9451, + 0xBD14, 0xBAC2, 0xBD15, 0x9452, 0xBD16, 0x9453, 0xBD17, 0x9454, + 0xBD18, 0x9455, 0xBD19, 0x9456, 0xBD1A, 0x9457, 0xBD1B, 0x9458, + 0xBD1C, 0x9459, 0xBD1D, 0x945A, 0xBD1E, 0x9461, 0xBD1F, 0x9462, + 0xBD20, 0x9463, 0xBD21, 0x9464, 0xBD22, 0x9465, 0xBD23, 0x9466, + 0xBD24, 0xBAC3, 0xBD25, 0x9467, 0xBD26, 0x9468, 0xBD27, 0x9469, + 0xBD28, 0x946A, 0xBD29, 0x946B, 0xBD2A, 0x946C, 0xBD2B, 0x946D, + 0xBD2C, 0xBAC4, 0xBD2D, 0x946E, 0xBD2E, 0x946F, 0xBD2F, 0x9470, + 0xBD30, 0x9471, 0xBD31, 0x9472, 0xBD32, 0x9473, 0xBD33, 0x9474, + 0xBD34, 0x9475, 0xBD35, 0x9476, 0xBD36, 0x9477, 0xBD37, 0x9478, + 0xBD38, 0x9479, 0xBD39, 0x947A, 0xBD3A, 0x9481, 0xBD3B, 0x9482, + 0xBD3C, 0x9483, 0xBD3D, 0x9484, 0xBD3E, 0x9485, 0xBD3F, 0x9486, + 0xBD40, 0xBAC5, 0xBD41, 0x9487, 0xBD42, 0x9488, 0xBD43, 0x9489, + 0xBD44, 0x948A, 0xBD45, 0x948B, 0xBD46, 0x948C, 0xBD47, 0x948D, + 0xBD48, 0xBAC6, 0xBD49, 0xBAC7, 0xBD4A, 0x948E, 0xBD4B, 0x948F, + 0xBD4C, 0xBAC8, 0xBD4D, 0x9490, 0xBD4E, 0x9491, 0xBD4F, 0x9492, + 0xBD50, 0xBAC9, 0xBD51, 0x9493, 0xBD52, 0x9494, 0xBD53, 0x9495, + 0xBD54, 0x9496, 0xBD55, 0x9497, 0xBD56, 0x9498, 0xBD57, 0x9499, + 0xBD58, 0xBACA, 0xBD59, 0xBACB, 0xBD5A, 0x949A, 0xBD5B, 0x949B, + 0xBD5C, 0x949C, 0xBD5D, 0x949D, 0xBD5E, 0x949E, 0xBD5F, 0x949F, + 0xBD60, 0x94A0, 0xBD61, 0x94A1, 0xBD62, 0x94A2, 0xBD63, 0x94A3, + 0xBD64, 0xBACC, 0xBD65, 0x94A4, 0xBD66, 0x94A5, 0xBD67, 0x94A6, + 0xBD68, 0xBACD, 0xBD69, 0x94A7, 0xBD6A, 0x94A8, 0xBD6B, 0x94A9, + 0xBD6C, 0x94AA, 0xBD6D, 0x94AB, 0xBD6E, 0x94AC, 0xBD6F, 0x94AD, + 0xBD70, 0x94AE, 0xBD71, 0x94AF, 0xBD72, 0x94B0, 0xBD73, 0x94B1, + 0xBD74, 0x94B2, 0xBD75, 0x94B3, 0xBD76, 0x94B4, 0xBD77, 0x94B5, + 0xBD78, 0x94B6, 0xBD79, 0x94B7, 0xBD7A, 0x94B8, 0xBD7B, 0x94B9, + 0xBD7C, 0x94BA, 0xBD7D, 0x94BB, 0xBD7E, 0x94BC, 0xBD7F, 0x94BD, + 0xBD80, 0xBACE, 0xBD81, 0xBACF, 0xBD82, 0x94BE, 0xBD83, 0x94BF, + 0xBD84, 0xBAD0, 0xBD85, 0x94C0, 0xBD86, 0x94C1, 0xBD87, 0xBAD1, + 0xBD88, 0xBAD2, 0xBD89, 0xBAD3, 0xBD8A, 0xBAD4, 0xBD8B, 0x94C2, + 0xBD8C, 0x94C3, 0xBD8D, 0x94C4, 0xBD8E, 0x94C5, 0xBD8F, 0x94C6, + 0xBD90, 0xBAD5, 0xBD91, 0xBAD6, 0xBD92, 0x94C7, 0xBD93, 0xBAD7, + 0xBD94, 0x94C8, 0xBD95, 0xBAD8, 0xBD96, 0x94C9, 0xBD97, 0x94CA, + 0xBD98, 0x94CB, 0xBD99, 0xBAD9, 0xBD9A, 0xBADA, 0xBD9B, 0x94CC, + 0xBD9C, 0xBADB, 0xBD9D, 0x94CD, 0xBD9E, 0x94CE, 0xBD9F, 0x94CF, + 0xBDA0, 0x94D0, 0xBDA1, 0x94D1, 0xBDA2, 0x94D2, 0xBDA3, 0x94D3, + 0xBDA4, 0xBADC, 0xBDA5, 0x94D4, 0xBDA6, 0x94D5, 0xBDA7, 0x94D6, + 0xBDA8, 0x94D7, 0xBDA9, 0x94D8, 0xBDAA, 0x94D9, 0xBDAB, 0x94DA, + 0xBDAC, 0x94DB, 0xBDAD, 0x94DC, 0xBDAE, 0x94DD, 0xBDAF, 0x94DE, + 0xBDB0, 0xBADD, 0xBDB1, 0x94DF, 0xBDB2, 0x94E0, 0xBDB3, 0x94E1, + 0xBDB4, 0x94E2, 0xBDB5, 0x94E3, 0xBDB6, 0x94E4, 0xBDB7, 0x94E5, + 0xBDB8, 0xBADE, 0xBDB9, 0x94E6, 0xBDBA, 0x94E7, 0xBDBB, 0x94E8, + 0xBDBC, 0x94E9, 0xBDBD, 0x94EA, 0xBDBE, 0x94EB, 0xBDBF, 0x94EC, + 0xBDC0, 0x94ED, 0xBDC1, 0x94EE, 0xBDC2, 0x94EF, 0xBDC3, 0x94F0, + 0xBDC4, 0x94F1, 0xBDC5, 0x94F2, 0xBDC6, 0x94F3, 0xBDC7, 0x94F4, + 0xBDC8, 0x94F5, 0xBDC9, 0x94F6, 0xBDCA, 0x94F7, 0xBDCB, 0x94F8, + 0xBDCC, 0x94F9, 0xBDCD, 0x94FA, 0xBDCE, 0x94FB, 0xBDCF, 0x94FC, + 0xBDD0, 0x94FD, 0xBDD1, 0x94FE, 0xBDD2, 0x9541, 0xBDD3, 0x9542, + 0xBDD4, 0xBADF, 0xBDD5, 0xBAE0, 0xBDD6, 0x9543, 0xBDD7, 0x9544, + 0xBDD8, 0xBAE1, 0xBDD9, 0x9545, 0xBDDA, 0x9546, 0xBDDB, 0x9547, + 0xBDDC, 0xBAE2, 0xBDDD, 0x9548, 0xBDDE, 0x9549, 0xBDDF, 0x954A, + 0xBDE0, 0x954B, 0xBDE1, 0x954C, 0xBDE2, 0x954D, 0xBDE3, 0x954E, + 0xBDE4, 0x954F, 0xBDE5, 0x9550, 0xBDE6, 0x9551, 0xBDE7, 0x9552, + 0xBDE8, 0x9553, 0xBDE9, 0xBAE3, 0xBDEA, 0x9554, 0xBDEB, 0x9555, + 0xBDEC, 0x9556, 0xBDED, 0x9557, 0xBDEE, 0x9558, 0xBDEF, 0x9559, + 0xBDF0, 0xBAE4, 0xBDF1, 0x955A, 0xBDF2, 0x9561, 0xBDF3, 0x9562, + 0xBDF4, 0xBAE5, 0xBDF5, 0x9563, 0xBDF6, 0x9564, 0xBDF7, 0x9565, + 0xBDF8, 0xBAE6, 0xBDF9, 0x9566, 0xBDFA, 0x9567, 0xBDFB, 0x9568, + 0xBDFC, 0x9569, 0xBDFD, 0x956A, 0xBDFE, 0x956B, 0xBDFF, 0x956C, + 0xBE00, 0xBAE7, 0xBE01, 0x956D, 0xBE02, 0x956E, 0xBE03, 0xBAE8, + 0xBE04, 0x956F, 0xBE05, 0xBAE9, 0xBE06, 0x9570, 0xBE07, 0x9571, + 0xBE08, 0x9572, 0xBE09, 0x9573, 0xBE0A, 0x9574, 0xBE0B, 0x9575, + 0xBE0C, 0xBAEA, 0xBE0D, 0xBAEB, 0xBE0E, 0x9576, 0xBE0F, 0x9577, + 0xBE10, 0xBAEC, 0xBE11, 0x9578, 0xBE12, 0x9579, 0xBE13, 0x957A, + 0xBE14, 0xBAED, 0xBE15, 0x9581, 0xBE16, 0x9582, 0xBE17, 0x9583, + 0xBE18, 0x9584, 0xBE19, 0x9585, 0xBE1A, 0x9586, 0xBE1B, 0x9587, + 0xBE1C, 0xBAEE, 0xBE1D, 0xBAEF, 0xBE1E, 0x9588, 0xBE1F, 0xBAF0, + 0xBE20, 0x9589, 0xBE21, 0x958A, 0xBE22, 0x958B, 0xBE23, 0x958C, + 0xBE24, 0x958D, 0xBE25, 0x958E, 0xBE26, 0x958F, 0xBE27, 0x9590, + 0xBE28, 0x9591, 0xBE29, 0x9592, 0xBE2A, 0x9593, 0xBE2B, 0x9594, + 0xBE2C, 0x9595, 0xBE2D, 0x9596, 0xBE2E, 0x9597, 0xBE2F, 0x9598, + 0xBE30, 0x9599, 0xBE31, 0x959A, 0xBE32, 0x959B, 0xBE33, 0x959C, + 0xBE34, 0x959D, 0xBE35, 0x959E, 0xBE36, 0x959F, 0xBE37, 0x95A0, + 0xBE38, 0x95A1, 0xBE39, 0x95A2, 0xBE3A, 0x95A3, 0xBE3B, 0x95A4, + 0xBE3C, 0x95A5, 0xBE3D, 0x95A6, 0xBE3E, 0x95A7, 0xBE3F, 0x95A8, + 0xBE40, 0x95A9, 0xBE41, 0x95AA, 0xBE42, 0x95AB, 0xBE43, 0x95AC, + 0xBE44, 0xBAF1, 0xBE45, 0xBAF2, 0xBE46, 0x95AD, 0xBE47, 0x95AE, + 0xBE48, 0xBAF3, 0xBE49, 0x95AF, 0xBE4A, 0x95B0, 0xBE4B, 0x95B1, + 0xBE4C, 0xBAF4, 0xBE4D, 0x95B2, 0xBE4E, 0xBAF5, 0xBE4F, 0x95B3, + 0xBE50, 0x95B4, 0xBE51, 0x95B5, 0xBE52, 0x95B6, 0xBE53, 0x95B7, + 0xBE54, 0xBAF6, 0xBE55, 0xBAF7, 0xBE56, 0x95B8, 0xBE57, 0xBAF8, + 0xBE58, 0x95B9, 0xBE59, 0xBAF9, 0xBE5A, 0xBAFA, 0xBE5B, 0xBAFB, + 0xBE5C, 0x95BA, 0xBE5D, 0x95BB, 0xBE5E, 0x95BC, 0xBE5F, 0x95BD, + 0xBE60, 0xBAFC, 0xBE61, 0xBAFD, 0xBE62, 0x95BE, 0xBE63, 0x95BF, + 0xBE64, 0xBAFE, 0xBE65, 0x95C0, 0xBE66, 0x95C1, 0xBE67, 0x95C2, + 0xBE68, 0xBBA1, 0xBE69, 0x95C3, 0xBE6A, 0xBBA2, 0xBE6B, 0x95C4, + 0xBE6C, 0x95C5, 0xBE6D, 0x95C6, 0xBE6E, 0x95C7, 0xBE6F, 0x95C8, + 0xBE70, 0xBBA3, 0xBE71, 0xBBA4, 0xBE72, 0x95C9, 0xBE73, 0xBBA5, + 0xBE74, 0xBBA6, 0xBE75, 0xBBA7, 0xBE76, 0x95CA, 0xBE77, 0x95CB, + 0xBE78, 0x95CC, 0xBE79, 0x95CD, 0xBE7A, 0x95CE, 0xBE7B, 0xBBA8, + 0xBE7C, 0xBBA9, 0xBE7D, 0xBBAA, 0xBE7E, 0x95CF, 0xBE7F, 0x95D0, + 0xBE80, 0xBBAB, 0xBE81, 0x95D1, 0xBE82, 0x95D2, 0xBE83, 0x95D3, + 0xBE84, 0xBBAC, 0xBE85, 0x95D4, 0xBE86, 0x95D5, 0xBE87, 0x95D6, + 0xBE88, 0x95D7, 0xBE89, 0x95D8, 0xBE8A, 0x95D9, 0xBE8B, 0x95DA, + 0xBE8C, 0xBBAD, 0xBE8D, 0xBBAE, 0xBE8E, 0x95DB, 0xBE8F, 0xBBAF, + 0xBE90, 0xBBB0, 0xBE91, 0xBBB1, 0xBE92, 0x95DC, 0xBE93, 0x95DD, + 0xBE94, 0x95DE, 0xBE95, 0x95DF, 0xBE96, 0x95E0, 0xBE97, 0x95E1, + 0xBE98, 0xBBB2, 0xBE99, 0xBBB3, 0xBE9A, 0x95E2, 0xBE9B, 0x95E3, + 0xBE9C, 0x95E4, 0xBE9D, 0x95E5, 0xBE9E, 0x95E6, 0xBE9F, 0x95E7, + 0xBEA0, 0x95E8, 0xBEA1, 0x95E9, 0xBEA2, 0x95EA, 0xBEA3, 0x95EB, + 0xBEA4, 0x95EC, 0xBEA5, 0x95ED, 0xBEA6, 0x95EE, 0xBEA7, 0x95EF, + 0xBEA8, 0xBBB4, 0xBEA9, 0x95F0, 0xBEAA, 0x95F1, 0xBEAB, 0x95F2, + 0xBEAC, 0x95F3, 0xBEAD, 0x95F4, 0xBEAE, 0x95F5, 0xBEAF, 0x95F6, + 0xBEB0, 0x95F7, 0xBEB1, 0x95F8, 0xBEB2, 0x95F9, 0xBEB3, 0x95FA, + 0xBEB4, 0x95FB, 0xBEB5, 0x95FC, 0xBEB6, 0x95FD, 0xBEB7, 0x95FE, + 0xBEB8, 0x9641, 0xBEB9, 0x9642, 0xBEBA, 0x9643, 0xBEBB, 0x9644, + 0xBEBC, 0x9645, 0xBEBD, 0x9646, 0xBEBE, 0x9647, 0xBEBF, 0x9648, + 0xBEC0, 0x9649, 0xBEC1, 0x964A, 0xBEC2, 0x964B, 0xBEC3, 0x964C, + 0xBEC4, 0x964D, 0xBEC5, 0x964E, 0xBEC6, 0x964F, 0xBEC7, 0x9650, + 0xBEC8, 0x9651, 0xBEC9, 0x9652, 0xBECA, 0x9653, 0xBECB, 0x9654, + 0xBECC, 0x9655, 0xBECD, 0x9656, 0xBECE, 0x9657, 0xBECF, 0x9658, + 0xBED0, 0xBBB5, 0xBED1, 0xBBB6, 0xBED2, 0x9659, 0xBED3, 0x965A, + 0xBED4, 0xBBB7, 0xBED5, 0x9661, 0xBED6, 0x9662, 0xBED7, 0xBBB8, + 0xBED8, 0xBBB9, 0xBED9, 0x9663, 0xBEDA, 0x9664, 0xBEDB, 0x9665, + 0xBEDC, 0x9666, 0xBEDD, 0x9667, 0xBEDE, 0x9668, 0xBEDF, 0x9669, + 0xBEE0, 0xBBBA, 0xBEE1, 0x966A, 0xBEE2, 0x966B, 0xBEE3, 0xBBBB, + 0xBEE4, 0xBBBC, 0xBEE5, 0xBBBD, 0xBEE6, 0x966C, 0xBEE7, 0x966D, + 0xBEE8, 0x966E, 0xBEE9, 0x966F, 0xBEEA, 0x9670, 0xBEEB, 0x9671, + 0xBEEC, 0xBBBE, 0xBEED, 0x9672, 0xBEEE, 0x9673, 0xBEEF, 0x9674, + 0xBEF0, 0x9675, 0xBEF1, 0x9676, 0xBEF2, 0x9677, 0xBEF3, 0x9678, + 0xBEF4, 0x9679, 0xBEF5, 0x967A, 0xBEF6, 0x9681, 0xBEF7, 0x9682, + 0xBEF8, 0x9683, 0xBEF9, 0x9684, 0xBEFA, 0x9685, 0xBEFB, 0x9686, + 0xBEFC, 0x9687, 0xBEFD, 0x9688, 0xBEFE, 0x9689, 0xBEFF, 0x968A, + 0xBF00, 0x968B, 0xBF01, 0xBBBF, 0xBF02, 0x968C, 0xBF03, 0x968D, + 0xBF04, 0x968E, 0xBF05, 0x968F, 0xBF06, 0x9690, 0xBF07, 0x9691, + 0xBF08, 0xBBC0, 0xBF09, 0xBBC1, 0xBF0A, 0x9692, 0xBF0B, 0x9693, + 0xBF0C, 0x9694, 0xBF0D, 0x9695, 0xBF0E, 0x9696, 0xBF0F, 0x9697, + 0xBF10, 0x9698, 0xBF11, 0x9699, 0xBF12, 0x969A, 0xBF13, 0x969B, + 0xBF14, 0x969C, 0xBF15, 0x969D, 0xBF16, 0x969E, 0xBF17, 0x969F, + 0xBF18, 0xBBC2, 0xBF19, 0xBBC3, 0xBF1A, 0x96A0, 0xBF1B, 0xBBC4, + 0xBF1C, 0xBBC5, 0xBF1D, 0xBBC6, 0xBF1E, 0x96A1, 0xBF1F, 0x96A2, + 0xBF20, 0x96A3, 0xBF21, 0x96A4, 0xBF22, 0x96A5, 0xBF23, 0x96A6, + 0xBF24, 0x96A7, 0xBF25, 0x96A8, 0xBF26, 0x96A9, 0xBF27, 0x96AA, + 0xBF28, 0x96AB, 0xBF29, 0x96AC, 0xBF2A, 0x96AD, 0xBF2B, 0x96AE, + 0xBF2C, 0x96AF, 0xBF2D, 0x96B0, 0xBF2E, 0x96B1, 0xBF2F, 0x96B2, + 0xBF30, 0x96B3, 0xBF31, 0x96B4, 0xBF32, 0x96B5, 0xBF33, 0x96B6, + 0xBF34, 0x96B7, 0xBF35, 0x96B8, 0xBF36, 0x96B9, 0xBF37, 0x96BA, + 0xBF38, 0x96BB, 0xBF39, 0x96BC, 0xBF3A, 0x96BD, 0xBF3B, 0x96BE, + 0xBF3C, 0x96BF, 0xBF3D, 0x96C0, 0xBF3E, 0x96C1, 0xBF3F, 0x96C2, + 0xBF40, 0xBBC7, 0xBF41, 0xBBC8, 0xBF42, 0x96C3, 0xBF43, 0x96C4, + 0xBF44, 0xBBC9, 0xBF45, 0x96C5, 0xBF46, 0x96C6, 0xBF47, 0x96C7, + 0xBF48, 0xBBCA, 0xBF49, 0x96C8, 0xBF4A, 0x96C9, 0xBF4B, 0x96CA, + 0xBF4C, 0x96CB, 0xBF4D, 0x96CC, 0xBF4E, 0x96CD, 0xBF4F, 0x96CE, + 0xBF50, 0xBBCB, 0xBF51, 0xBBCC, 0xBF52, 0x96CF, 0xBF53, 0x96D0, + 0xBF54, 0x96D1, 0xBF55, 0xBBCD, 0xBF56, 0x96D2, 0xBF57, 0x96D3, + 0xBF58, 0x96D4, 0xBF59, 0x96D5, 0xBF5A, 0x96D6, 0xBF5B, 0x96D7, + 0xBF5C, 0x96D8, 0xBF5D, 0x96D9, 0xBF5E, 0x96DA, 0xBF5F, 0x96DB, + 0xBF60, 0x96DC, 0xBF61, 0x96DD, 0xBF62, 0x96DE, 0xBF63, 0x96DF, + 0xBF64, 0x96E0, 0xBF65, 0x96E1, 0xBF66, 0x96E2, 0xBF67, 0x96E3, + 0xBF68, 0x96E4, 0xBF69, 0x96E5, 0xBF6A, 0x96E6, 0xBF6B, 0x96E7, + 0xBF6C, 0x96E8, 0xBF6D, 0x96E9, 0xBF6E, 0x96EA, 0xBF6F, 0x96EB, + 0xBF70, 0x96EC, 0xBF71, 0x96ED, 0xBF72, 0x96EE, 0xBF73, 0x96EF, + 0xBF74, 0x96F0, 0xBF75, 0x96F1, 0xBF76, 0x96F2, 0xBF77, 0x96F3, + 0xBF78, 0x96F4, 0xBF79, 0x96F5, 0xBF7A, 0x96F6, 0xBF7B, 0x96F7, + 0xBF7C, 0x96F8, 0xBF7D, 0x96F9, 0xBF7E, 0x96FA, 0xBF7F, 0x96FB, + 0xBF80, 0x96FC, 0xBF81, 0x96FD, 0xBF82, 0x96FE, 0xBF83, 0x9741, + 0xBF84, 0x9742, 0xBF85, 0x9743, 0xBF86, 0x9744, 0xBF87, 0x9745, + 0xBF88, 0x9746, 0xBF89, 0x9747, 0xBF8A, 0x9748, 0xBF8B, 0x9749, + 0xBF8C, 0x974A, 0xBF8D, 0x974B, 0xBF8E, 0x974C, 0xBF8F, 0x974D, + 0xBF90, 0x974E, 0xBF91, 0x974F, 0xBF92, 0x9750, 0xBF93, 0x9751, + 0xBF94, 0xBBCE, 0xBF95, 0x9752, 0xBF96, 0x9753, 0xBF97, 0x9754, + 0xBF98, 0x9755, 0xBF99, 0x9756, 0xBF9A, 0x9757, 0xBF9B, 0x9758, + 0xBF9C, 0x9759, 0xBF9D, 0x975A, 0xBF9E, 0x9761, 0xBF9F, 0x9762, + 0xBFA0, 0x9763, 0xBFA1, 0x9764, 0xBFA2, 0x9765, 0xBFA3, 0x9766, + 0xBFA4, 0x9767, 0xBFA5, 0x9768, 0xBFA6, 0x9769, 0xBFA7, 0x976A, + 0xBFA8, 0x976B, 0xBFA9, 0x976C, 0xBFAA, 0x976D, 0xBFAB, 0x976E, + 0xBFAC, 0x976F, 0xBFAD, 0x9770, 0xBFAE, 0x9771, 0xBFAF, 0x9772, + 0xBFB0, 0xBBCF, 0xBFB1, 0x9773, 0xBFB2, 0x9774, 0xBFB3, 0x9775, + 0xBFB4, 0x9776, 0xBFB5, 0x9777, 0xBFB6, 0x9778, 0xBFB7, 0x9779, + 0xBFB8, 0x977A, 0xBFB9, 0x9781, 0xBFBA, 0x9782, 0xBFBB, 0x9783, + 0xBFBC, 0x9784, 0xBFBD, 0x9785, 0xBFBE, 0x9786, 0xBFBF, 0x9787, + 0xBFC0, 0x9788, 0xBFC1, 0x9789, 0xBFC2, 0x978A, 0xBFC3, 0x978B, + 0xBFC4, 0x978C, 0xBFC5, 0xBBD0, 0xBFC6, 0x978D, 0xBFC7, 0x978E, + 0xBFC8, 0x978F, 0xBFC9, 0x9790, 0xBFCA, 0x9791, 0xBFCB, 0x9792, + 0xBFCC, 0xBBD1, 0xBFCD, 0xBBD2, 0xBFCE, 0x9793, 0xBFCF, 0x9794, + 0xBFD0, 0xBBD3, 0xBFD1, 0x9795, 0xBFD2, 0x9796, 0xBFD3, 0x9797, + 0xBFD4, 0xBBD4, 0xBFD5, 0x9798, 0xBFD6, 0x9799, 0xBFD7, 0x979A, + 0xBFD8, 0x979B, 0xBFD9, 0x979C, 0xBFDA, 0x979D, 0xBFDB, 0x979E, + 0xBFDC, 0xBBD5, 0xBFDD, 0x979F, 0xBFDE, 0x97A0, 0xBFDF, 0xBBD6, + 0xBFE0, 0x97A1, 0xBFE1, 0xBBD7, 0xBFE2, 0x97A2, 0xBFE3, 0x97A3, + 0xBFE4, 0x97A4, 0xBFE5, 0x97A5, 0xBFE6, 0x97A6, 0xBFE7, 0x97A7, + 0xBFE8, 0x97A8, 0xBFE9, 0x97A9, 0xBFEA, 0x97AA, 0xBFEB, 0x97AB, + 0xBFEC, 0x97AC, 0xBFED, 0x97AD, 0xBFEE, 0x97AE, 0xBFEF, 0x97AF, + 0xBFF0, 0x97B0, 0xBFF1, 0x97B1, 0xBFF2, 0x97B2, 0xBFF3, 0x97B3, + 0xBFF4, 0x97B4, 0xBFF5, 0x97B5, 0xBFF6, 0x97B6, 0xBFF7, 0x97B7, + 0xBFF8, 0x97B8, 0xBFF9, 0x97B9, 0xBFFA, 0x97BA, 0xBFFB, 0x97BB, + 0xBFFC, 0x97BC, 0xBFFD, 0x97BD, 0xBFFE, 0x97BE, 0xBFFF, 0x97BF, + 0xC000, 0x97C0, 0xC001, 0x97C1, 0xC002, 0x97C2, 0xC003, 0x97C3, + 0xC004, 0x97C4, 0xC005, 0x97C5, 0xC006, 0x97C6, 0xC007, 0x97C7, + 0xC008, 0x97C8, 0xC009, 0x97C9, 0xC00A, 0x97CA, 0xC00B, 0x97CB, + 0xC00C, 0x97CC, 0xC00D, 0x97CD, 0xC00E, 0x97CE, 0xC00F, 0x97CF, + 0xC010, 0x97D0, 0xC011, 0x97D1, 0xC012, 0x97D2, 0xC013, 0x97D3, + 0xC014, 0x97D4, 0xC015, 0x97D5, 0xC016, 0x97D6, 0xC017, 0x97D7, + 0xC018, 0x97D8, 0xC019, 0x97D9, 0xC01A, 0x97DA, 0xC01B, 0x97DB, + 0xC01C, 0x97DC, 0xC01D, 0x97DD, 0xC01E, 0x97DE, 0xC01F, 0x97DF, + 0xC020, 0x97E0, 0xC021, 0x97E1, 0xC022, 0x97E2, 0xC023, 0x97E3, + 0xC024, 0x97E4, 0xC025, 0x97E5, 0xC026, 0x97E6, 0xC027, 0x97E7, + 0xC028, 0x97E8, 0xC029, 0x97E9, 0xC02A, 0x97EA, 0xC02B, 0x97EB, + 0xC02C, 0x97EC, 0xC02D, 0x97ED, 0xC02E, 0x97EE, 0xC02F, 0x97EF, + 0xC030, 0x97F0, 0xC031, 0x97F1, 0xC032, 0x97F2, 0xC033, 0x97F3, + 0xC034, 0x97F4, 0xC035, 0x97F5, 0xC036, 0x97F6, 0xC037, 0x97F7, + 0xC038, 0x97F8, 0xC039, 0x97F9, 0xC03A, 0x97FA, 0xC03B, 0x97FB, + 0xC03C, 0xBBD8, 0xC03D, 0x97FC, 0xC03E, 0x97FD, 0xC03F, 0x97FE, + 0xC040, 0x9841, 0xC041, 0x9842, 0xC042, 0x9843, 0xC043, 0x9844, + 0xC044, 0x9845, 0xC045, 0x9846, 0xC046, 0x9847, 0xC047, 0x9848, + 0xC048, 0x9849, 0xC049, 0x984A, 0xC04A, 0x984B, 0xC04B, 0x984C, + 0xC04C, 0x984D, 0xC04D, 0x984E, 0xC04E, 0x984F, 0xC04F, 0x9850, + 0xC050, 0x9851, 0xC051, 0xBBD9, 0xC052, 0x9852, 0xC053, 0x9853, + 0xC054, 0x9854, 0xC055, 0x9855, 0xC056, 0x9856, 0xC057, 0x9857, + 0xC058, 0xBBDA, 0xC059, 0x9858, 0xC05A, 0x9859, 0xC05B, 0x985A, + 0xC05C, 0xBBDB, 0xC05D, 0x9861, 0xC05E, 0x9862, 0xC05F, 0x9863, + 0xC060, 0xBBDC, 0xC061, 0x9864, 0xC062, 0x9865, 0xC063, 0x9866, + 0xC064, 0x9867, 0xC065, 0x9868, 0xC066, 0x9869, 0xC067, 0x986A, + 0xC068, 0xBBDD, 0xC069, 0xBBDE, 0xC06A, 0x986B, 0xC06B, 0x986C, + 0xC06C, 0x986D, 0xC06D, 0x986E, 0xC06E, 0x986F, 0xC06F, 0x9870, + 0xC070, 0x9871, 0xC071, 0x9872, 0xC072, 0x9873, 0xC073, 0x9874, + 0xC074, 0x9875, 0xC075, 0x9876, 0xC076, 0x9877, 0xC077, 0x9878, + 0xC078, 0x9879, 0xC079, 0x987A, 0xC07A, 0x9881, 0xC07B, 0x9882, + 0xC07C, 0x9883, 0xC07D, 0x9884, 0xC07E, 0x9885, 0xC07F, 0x9886, + 0xC080, 0x9887, 0xC081, 0x9888, 0xC082, 0x9889, 0xC083, 0x988A, + 0xC084, 0x988B, 0xC085, 0x988C, 0xC086, 0x988D, 0xC087, 0x988E, + 0xC088, 0x988F, 0xC089, 0x9890, 0xC08A, 0x9891, 0xC08B, 0x9892, + 0xC08C, 0x9893, 0xC08D, 0x9894, 0xC08E, 0x9895, 0xC08F, 0x9896, + 0xC090, 0xBBDF, 0xC091, 0xBBE0, 0xC092, 0x9897, 0xC093, 0x9898, + 0xC094, 0xBBE1, 0xC095, 0x9899, 0xC096, 0x989A, 0xC097, 0x989B, + 0xC098, 0xBBE2, 0xC099, 0x989C, 0xC09A, 0x989D, 0xC09B, 0x989E, + 0xC09C, 0x989F, 0xC09D, 0x98A0, 0xC09E, 0x98A1, 0xC09F, 0x98A2, + 0xC0A0, 0xBBE3, 0xC0A1, 0xBBE4, 0xC0A2, 0x98A3, 0xC0A3, 0xBBE5, + 0xC0A4, 0x98A4, 0xC0A5, 0xBBE6, 0xC0A6, 0x98A5, 0xC0A7, 0x98A6, + 0xC0A8, 0x98A7, 0xC0A9, 0x98A8, 0xC0AA, 0x98A9, 0xC0AB, 0x98AA, + 0xC0AC, 0xBBE7, 0xC0AD, 0xBBE8, 0xC0AE, 0x98AB, 0xC0AF, 0xBBE9, + 0xC0B0, 0xBBEA, 0xC0B1, 0x98AC, 0xC0B2, 0x98AD, 0xC0B3, 0xBBEB, + 0xC0B4, 0xBBEC, 0xC0B5, 0xBBED, 0xC0B6, 0xBBEE, 0xC0B7, 0x98AE, + 0xC0B8, 0x98AF, 0xC0B9, 0x98B0, 0xC0BA, 0x98B1, 0xC0BB, 0x98B2, + 0xC0BC, 0xBBEF, 0xC0BD, 0xBBF0, 0xC0BE, 0x98B3, 0xC0BF, 0xBBF1, + 0xC0C0, 0xBBF2, 0xC0C1, 0xBBF3, 0xC0C2, 0x98B4, 0xC0C3, 0x98B5, + 0xC0C4, 0x98B6, 0xC0C5, 0xBBF4, 0xC0C6, 0x98B7, 0xC0C7, 0x98B8, + 0xC0C8, 0xBBF5, 0xC0C9, 0xBBF6, 0xC0CA, 0x98B9, 0xC0CB, 0x98BA, + 0xC0CC, 0xBBF7, 0xC0CD, 0x98BB, 0xC0CE, 0x98BC, 0xC0CF, 0x98BD, + 0xC0D0, 0xBBF8, 0xC0D1, 0x98BE, 0xC0D2, 0x98BF, 0xC0D3, 0x98C0, + 0xC0D4, 0x98C1, 0xC0D5, 0x98C2, 0xC0D6, 0x98C3, 0xC0D7, 0x98C4, + 0xC0D8, 0xBBF9, 0xC0D9, 0xBBFA, 0xC0DA, 0x98C5, 0xC0DB, 0xBBFB, + 0xC0DC, 0xBBFC, 0xC0DD, 0xBBFD, 0xC0DE, 0x98C6, 0xC0DF, 0x98C7, + 0xC0E0, 0x98C8, 0xC0E1, 0x98C9, 0xC0E2, 0x98CA, 0xC0E3, 0x98CB, + 0xC0E4, 0xBBFE, 0xC0E5, 0xBCA1, 0xC0E6, 0x98CC, 0xC0E7, 0x98CD, + 0xC0E8, 0xBCA2, 0xC0E9, 0x98CE, 0xC0EA, 0x98CF, 0xC0EB, 0x98D0, + 0xC0EC, 0xBCA3, 0xC0ED, 0x98D1, 0xC0EE, 0x98D2, 0xC0EF, 0x98D3, + 0xC0F0, 0x98D4, 0xC0F1, 0x98D5, 0xC0F2, 0x98D6, 0xC0F3, 0x98D7, + 0xC0F4, 0xBCA4, 0xC0F5, 0xBCA5, 0xC0F6, 0x98D8, 0xC0F7, 0xBCA6, + 0xC0F8, 0x98D9, 0xC0F9, 0xBCA7, 0xC0FA, 0x98DA, 0xC0FB, 0x98DB, + 0xC0FC, 0x98DC, 0xC0FD, 0x98DD, 0xC0FE, 0x98DE, 0xC0FF, 0x98DF, + 0xC100, 0xBCA8, 0xC101, 0x98E0, 0xC102, 0x98E1, 0xC103, 0x98E2, + 0xC104, 0xBCA9, 0xC105, 0x98E3, 0xC106, 0x98E4, 0xC107, 0x98E5, + 0xC108, 0xBCAA, 0xC109, 0x98E6, 0xC10A, 0x98E7, 0xC10B, 0x98E8, + 0xC10C, 0x98E9, 0xC10D, 0x98EA, 0xC10E, 0x98EB, 0xC10F, 0x98EC, + 0xC110, 0xBCAB, 0xC111, 0x98ED, 0xC112, 0x98EE, 0xC113, 0x98EF, + 0xC114, 0x98F0, 0xC115, 0xBCAC, 0xC116, 0x98F1, 0xC117, 0x98F2, + 0xC118, 0x98F3, 0xC119, 0x98F4, 0xC11A, 0x98F5, 0xC11B, 0x98F6, + 0xC11C, 0xBCAD, 0xC11D, 0xBCAE, 0xC11E, 0xBCAF, 0xC11F, 0xBCB0, + 0xC120, 0xBCB1, 0xC121, 0x98F7, 0xC122, 0x98F8, 0xC123, 0xBCB2, + 0xC124, 0xBCB3, 0xC125, 0x98F9, 0xC126, 0xBCB4, 0xC127, 0xBCB5, + 0xC128, 0x98FA, 0xC129, 0x98FB, 0xC12A, 0x98FC, 0xC12B, 0x98FD, + 0xC12C, 0xBCB6, 0xC12D, 0xBCB7, 0xC12E, 0x98FE, 0xC12F, 0xBCB8, + 0xC130, 0xBCB9, 0xC131, 0xBCBA, 0xC132, 0x9941, 0xC133, 0x9942, + 0xC134, 0x9943, 0xC135, 0x9944, 0xC136, 0xBCBB, 0xC137, 0x9945, + 0xC138, 0xBCBC, 0xC139, 0xBCBD, 0xC13A, 0x9946, 0xC13B, 0x9947, + 0xC13C, 0xBCBE, 0xC13D, 0x9948, 0xC13E, 0x9949, 0xC13F, 0x994A, + 0xC140, 0xBCBF, 0xC141, 0x994B, 0xC142, 0x994C, 0xC143, 0x994D, + 0xC144, 0x994E, 0xC145, 0x994F, 0xC146, 0x9950, 0xC147, 0x9951, + 0xC148, 0xBCC0, 0xC149, 0xBCC1, 0xC14A, 0x9952, 0xC14B, 0xBCC2, + 0xC14C, 0xBCC3, 0xC14D, 0xBCC4, 0xC14E, 0x9953, 0xC14F, 0x9954, + 0xC150, 0x9955, 0xC151, 0x9956, 0xC152, 0x9957, 0xC153, 0x9958, + 0xC154, 0xBCC5, 0xC155, 0xBCC6, 0xC156, 0x9959, 0xC157, 0x995A, + 0xC158, 0xBCC7, 0xC159, 0x9961, 0xC15A, 0x9962, 0xC15B, 0x9963, + 0xC15C, 0xBCC8, 0xC15D, 0x9964, 0xC15E, 0x9965, 0xC15F, 0x9966, + 0xC160, 0x9967, 0xC161, 0x9968, 0xC162, 0x9969, 0xC163, 0x996A, + 0xC164, 0xBCC9, 0xC165, 0xBCCA, 0xC166, 0x996B, 0xC167, 0xBCCB, + 0xC168, 0xBCCC, 0xC169, 0xBCCD, 0xC16A, 0x996C, 0xC16B, 0x996D, + 0xC16C, 0x996E, 0xC16D, 0x996F, 0xC16E, 0x9970, 0xC16F, 0x9971, + 0xC170, 0xBCCE, 0xC171, 0x9972, 0xC172, 0x9973, 0xC173, 0x9974, + 0xC174, 0xBCCF, 0xC175, 0x9975, 0xC176, 0x9976, 0xC177, 0x9977, + 0xC178, 0xBCD0, 0xC179, 0x9978, 0xC17A, 0x9979, 0xC17B, 0x997A, + 0xC17C, 0x9981, 0xC17D, 0x9982, 0xC17E, 0x9983, 0xC17F, 0x9984, + 0xC180, 0x9985, 0xC181, 0x9986, 0xC182, 0x9987, 0xC183, 0x9988, + 0xC184, 0x9989, 0xC185, 0xBCD1, 0xC186, 0x998A, 0xC187, 0x998B, + 0xC188, 0x998C, 0xC189, 0x998D, 0xC18A, 0x998E, 0xC18B, 0x998F, + 0xC18C, 0xBCD2, 0xC18D, 0xBCD3, 0xC18E, 0xBCD4, 0xC18F, 0x9990, + 0xC190, 0xBCD5, 0xC191, 0x9991, 0xC192, 0x9992, 0xC193, 0x9993, + 0xC194, 0xBCD6, 0xC195, 0x9994, 0xC196, 0xBCD7, 0xC197, 0x9995, + 0xC198, 0x9996, 0xC199, 0x9997, 0xC19A, 0x9998, 0xC19B, 0x9999, + 0xC19C, 0xBCD8, 0xC19D, 0xBCD9, 0xC19E, 0x999A, 0xC19F, 0xBCDA, + 0xC1A0, 0x999B, 0xC1A1, 0xBCDB, 0xC1A2, 0x999C, 0xC1A3, 0x999D, + 0xC1A4, 0x999E, 0xC1A5, 0xBCDC, 0xC1A6, 0x999F, 0xC1A7, 0x99A0, + 0xC1A8, 0xBCDD, 0xC1A9, 0xBCDE, 0xC1AA, 0x99A1, 0xC1AB, 0x99A2, + 0xC1AC, 0xBCDF, 0xC1AD, 0x99A3, 0xC1AE, 0x99A4, 0xC1AF, 0x99A5, + 0xC1B0, 0xBCE0, 0xC1B1, 0x99A6, 0xC1B2, 0x99A7, 0xC1B3, 0x99A8, + 0xC1B4, 0x99A9, 0xC1B5, 0x99AA, 0xC1B6, 0x99AB, 0xC1B7, 0x99AC, + 0xC1B8, 0x99AD, 0xC1B9, 0x99AE, 0xC1BA, 0x99AF, 0xC1BB, 0x99B0, + 0xC1BC, 0x99B1, 0xC1BD, 0xBCE1, 0xC1BE, 0x99B2, 0xC1BF, 0x99B3, + 0xC1C0, 0x99B4, 0xC1C1, 0x99B5, 0xC1C2, 0x99B6, 0xC1C3, 0x99B7, + 0xC1C4, 0xBCE2, 0xC1C5, 0x99B8, 0xC1C6, 0x99B9, 0xC1C7, 0x99BA, + 0xC1C8, 0xBCE3, 0xC1C9, 0x99BB, 0xC1CA, 0x99BC, 0xC1CB, 0x99BD, + 0xC1CC, 0xBCE4, 0xC1CD, 0x99BE, 0xC1CE, 0x99BF, 0xC1CF, 0x99C0, + 0xC1D0, 0x99C1, 0xC1D1, 0x99C2, 0xC1D2, 0x99C3, 0xC1D3, 0x99C4, + 0xC1D4, 0xBCE5, 0xC1D5, 0x99C5, 0xC1D6, 0x99C6, 0xC1D7, 0xBCE6, + 0xC1D8, 0xBCE7, 0xC1D9, 0x99C7, 0xC1DA, 0x99C8, 0xC1DB, 0x99C9, + 0xC1DC, 0x99CA, 0xC1DD, 0x99CB, 0xC1DE, 0x99CC, 0xC1DF, 0x99CD, + 0xC1E0, 0xBCE8, 0xC1E1, 0x99CE, 0xC1E2, 0x99CF, 0xC1E3, 0x99D0, + 0xC1E4, 0xBCE9, 0xC1E5, 0x99D1, 0xC1E6, 0x99D2, 0xC1E7, 0x99D3, + 0xC1E8, 0xBCEA, 0xC1E9, 0x99D4, 0xC1EA, 0x99D5, 0xC1EB, 0x99D6, + 0xC1EC, 0x99D7, 0xC1ED, 0x99D8, 0xC1EE, 0x99D9, 0xC1EF, 0x99DA, + 0xC1F0, 0xBCEB, 0xC1F1, 0xBCEC, 0xC1F2, 0x99DB, 0xC1F3, 0xBCED, + 0xC1F4, 0x99DC, 0xC1F5, 0x99DD, 0xC1F6, 0x99DE, 0xC1F7, 0x99DF, + 0xC1F8, 0x99E0, 0xC1F9, 0x99E1, 0xC1FA, 0x99E2, 0xC1FB, 0x99E3, + 0xC1FC, 0xBCEE, 0xC1FD, 0xBCEF, 0xC1FE, 0x99E4, 0xC1FF, 0x99E5, + 0xC200, 0xBCF0, 0xC201, 0x99E6, 0xC202, 0x99E7, 0xC203, 0x99E8, + 0xC204, 0xBCF1, 0xC205, 0x99E9, 0xC206, 0x99EA, 0xC207, 0x99EB, + 0xC208, 0x99EC, 0xC209, 0x99ED, 0xC20A, 0x99EE, 0xC20B, 0x99EF, + 0xC20C, 0xBCF2, 0xC20D, 0xBCF3, 0xC20E, 0x99F0, 0xC20F, 0xBCF4, + 0xC210, 0x99F1, 0xC211, 0xBCF5, 0xC212, 0x99F2, 0xC213, 0x99F3, + 0xC214, 0x99F4, 0xC215, 0x99F5, 0xC216, 0x99F6, 0xC217, 0x99F7, + 0xC218, 0xBCF6, 0xC219, 0xBCF7, 0xC21A, 0x99F8, 0xC21B, 0x99F9, + 0xC21C, 0xBCF8, 0xC21D, 0x99FA, 0xC21E, 0x99FB, 0xC21F, 0xBCF9, + 0xC220, 0xBCFA, 0xC221, 0x99FC, 0xC222, 0x99FD, 0xC223, 0x99FE, + 0xC224, 0x9A41, 0xC225, 0x9A42, 0xC226, 0x9A43, 0xC227, 0x9A44, + 0xC228, 0xBCFB, 0xC229, 0xBCFC, 0xC22A, 0x9A45, 0xC22B, 0xBCFD, + 0xC22C, 0x9A46, 0xC22D, 0xBCFE, 0xC22E, 0x9A47, 0xC22F, 0xBDA1, + 0xC230, 0x9A48, 0xC231, 0xBDA2, 0xC232, 0xBDA3, 0xC233, 0x9A49, + 0xC234, 0xBDA4, 0xC235, 0x9A4A, 0xC236, 0x9A4B, 0xC237, 0x9A4C, + 0xC238, 0x9A4D, 0xC239, 0x9A4E, 0xC23A, 0x9A4F, 0xC23B, 0x9A50, + 0xC23C, 0x9A51, 0xC23D, 0x9A52, 0xC23E, 0x9A53, 0xC23F, 0x9A54, + 0xC240, 0x9A55, 0xC241, 0x9A56, 0xC242, 0x9A57, 0xC243, 0x9A58, + 0xC244, 0x9A59, 0xC245, 0x9A5A, 0xC246, 0x9A61, 0xC247, 0x9A62, + 0xC248, 0xBDA5, 0xC249, 0x9A63, 0xC24A, 0x9A64, 0xC24B, 0x9A65, + 0xC24C, 0x9A66, 0xC24D, 0x9A67, 0xC24E, 0x9A68, 0xC24F, 0x9A69, + 0xC250, 0xBDA6, 0xC251, 0xBDA7, 0xC252, 0x9A6A, 0xC253, 0x9A6B, + 0xC254, 0xBDA8, 0xC255, 0x9A6C, 0xC256, 0x9A6D, 0xC257, 0x9A6E, + 0xC258, 0xBDA9, 0xC259, 0x9A6F, 0xC25A, 0x9A70, 0xC25B, 0x9A71, + 0xC25C, 0x9A72, 0xC25D, 0x9A73, 0xC25E, 0x9A74, 0xC25F, 0x9A75, + 0xC260, 0xBDAA, 0xC261, 0x9A76, 0xC262, 0x9A77, 0xC263, 0x9A78, + 0xC264, 0x9A79, 0xC265, 0xBDAB, 0xC266, 0x9A7A, 0xC267, 0x9A81, + 0xC268, 0x9A82, 0xC269, 0x9A83, 0xC26A, 0x9A84, 0xC26B, 0x9A85, + 0xC26C, 0xBDAC, 0xC26D, 0xBDAD, 0xC26E, 0x9A86, 0xC26F, 0x9A87, + 0xC270, 0xBDAE, 0xC271, 0x9A88, 0xC272, 0x9A89, 0xC273, 0x9A8A, + 0xC274, 0xBDAF, 0xC275, 0x9A8B, 0xC276, 0x9A8C, 0xC277, 0x9A8D, + 0xC278, 0x9A8E, 0xC279, 0x9A8F, 0xC27A, 0x9A90, 0xC27B, 0x9A91, + 0xC27C, 0xBDB0, 0xC27D, 0xBDB1, 0xC27E, 0x9A92, 0xC27F, 0xBDB2, + 0xC280, 0x9A93, 0xC281, 0xBDB3, 0xC282, 0x9A94, 0xC283, 0x9A95, + 0xC284, 0x9A96, 0xC285, 0x9A97, 0xC286, 0x9A98, 0xC287, 0x9A99, + 0xC288, 0xBDB4, 0xC289, 0xBDB5, 0xC28A, 0x9A9A, 0xC28B, 0x9A9B, + 0xC28C, 0x9A9C, 0xC28D, 0x9A9D, 0xC28E, 0x9A9E, 0xC28F, 0x9A9F, + 0xC290, 0xBDB6, 0xC291, 0x9AA0, 0xC292, 0x9AA1, 0xC293, 0x9AA2, + 0xC294, 0x9AA3, 0xC295, 0x9AA4, 0xC296, 0x9AA5, 0xC297, 0x9AA6, + 0xC298, 0xBDB7, 0xC299, 0x9AA7, 0xC29A, 0x9AA8, 0xC29B, 0xBDB8, + 0xC29C, 0x9AA9, 0xC29D, 0xBDB9, 0xC29E, 0x9AAA, 0xC29F, 0x9AAB, + 0xC2A0, 0x9AAC, 0xC2A1, 0x9AAD, 0xC2A2, 0x9AAE, 0xC2A3, 0x9AAF, + 0xC2A4, 0xBDBA, 0xC2A5, 0xBDBB, 0xC2A6, 0x9AB0, 0xC2A7, 0x9AB1, + 0xC2A8, 0xBDBC, 0xC2A9, 0x9AB2, 0xC2AA, 0x9AB3, 0xC2AB, 0x9AB4, + 0xC2AC, 0xBDBD, 0xC2AD, 0xBDBE, 0xC2AE, 0x9AB5, 0xC2AF, 0x9AB6, + 0xC2B0, 0x9AB7, 0xC2B1, 0x9AB8, 0xC2B2, 0x9AB9, 0xC2B3, 0x9ABA, + 0xC2B4, 0xBDBF, 0xC2B5, 0xBDC0, 0xC2B6, 0x9ABB, 0xC2B7, 0xBDC1, + 0xC2B8, 0x9ABC, 0xC2B9, 0xBDC2, 0xC2BA, 0x9ABD, 0xC2BB, 0x9ABE, + 0xC2BC, 0x9ABF, 0xC2BD, 0x9AC0, 0xC2BE, 0x9AC1, 0xC2BF, 0x9AC2, + 0xC2C0, 0x9AC3, 0xC2C1, 0x9AC4, 0xC2C2, 0x9AC5, 0xC2C3, 0x9AC6, + 0xC2C4, 0x9AC7, 0xC2C5, 0x9AC8, 0xC2C6, 0x9AC9, 0xC2C7, 0x9ACA, + 0xC2C8, 0x9ACB, 0xC2C9, 0x9ACC, 0xC2CA, 0x9ACD, 0xC2CB, 0x9ACE, + 0xC2CC, 0x9ACF, 0xC2CD, 0x9AD0, 0xC2CE, 0x9AD1, 0xC2CF, 0x9AD2, + 0xC2D0, 0x9AD3, 0xC2D1, 0x9AD4, 0xC2D2, 0x9AD5, 0xC2D3, 0x9AD6, + 0xC2D4, 0x9AD7, 0xC2D5, 0x9AD8, 0xC2D6, 0x9AD9, 0xC2D7, 0x9ADA, + 0xC2D8, 0x9ADB, 0xC2D9, 0x9ADC, 0xC2DA, 0x9ADD, 0xC2DB, 0x9ADE, + 0xC2DC, 0xBDC3, 0xC2DD, 0xBDC4, 0xC2DE, 0x9ADF, 0xC2DF, 0x9AE0, + 0xC2E0, 0xBDC5, 0xC2E1, 0x9AE1, 0xC2E2, 0x9AE2, 0xC2E3, 0xBDC6, + 0xC2E4, 0xBDC7, 0xC2E5, 0x9AE3, 0xC2E6, 0x9AE4, 0xC2E7, 0x9AE5, + 0xC2E8, 0x9AE6, 0xC2E9, 0x9AE7, 0xC2EA, 0x9AE8, 0xC2EB, 0xBDC8, + 0xC2EC, 0xBDC9, 0xC2ED, 0xBDCA, 0xC2EE, 0x9AE9, 0xC2EF, 0xBDCB, + 0xC2F0, 0x9AEA, 0xC2F1, 0xBDCC, 0xC2F2, 0x9AEB, 0xC2F3, 0x9AEC, + 0xC2F4, 0x9AED, 0xC2F5, 0x9AEE, 0xC2F6, 0xBDCD, 0xC2F7, 0x9AEF, + 0xC2F8, 0xBDCE, 0xC2F9, 0xBDCF, 0xC2FA, 0x9AF0, 0xC2FB, 0xBDD0, + 0xC2FC, 0xBDD1, 0xC2FD, 0x9AF1, 0xC2FE, 0x9AF2, 0xC2FF, 0x9AF3, + 0xC300, 0xBDD2, 0xC301, 0x9AF4, 0xC302, 0x9AF5, 0xC303, 0x9AF6, + 0xC304, 0x9AF7, 0xC305, 0x9AF8, 0xC306, 0x9AF9, 0xC307, 0x9AFA, + 0xC308, 0xBDD3, 0xC309, 0xBDD4, 0xC30A, 0x9AFB, 0xC30B, 0x9AFC, + 0xC30C, 0xBDD5, 0xC30D, 0xBDD6, 0xC30E, 0x9AFD, 0xC30F, 0x9AFE, + 0xC310, 0x9B41, 0xC311, 0x9B42, 0xC312, 0x9B43, 0xC313, 0xBDD7, + 0xC314, 0xBDD8, 0xC315, 0xBDD9, 0xC316, 0x9B44, 0xC317, 0x9B45, + 0xC318, 0xBDDA, 0xC319, 0x9B46, 0xC31A, 0x9B47, 0xC31B, 0x9B48, + 0xC31C, 0xBDDB, 0xC31D, 0x9B49, 0xC31E, 0x9B4A, 0xC31F, 0x9B4B, + 0xC320, 0x9B4C, 0xC321, 0x9B4D, 0xC322, 0x9B4E, 0xC323, 0x9B4F, + 0xC324, 0xBDDC, 0xC325, 0xBDDD, 0xC326, 0x9B50, 0xC327, 0x9B51, + 0xC328, 0xBDDE, 0xC329, 0xBDDF, 0xC32A, 0x9B52, 0xC32B, 0x9B53, + 0xC32C, 0x9B54, 0xC32D, 0x9B55, 0xC32E, 0x9B56, 0xC32F, 0x9B57, + 0xC330, 0x9B58, 0xC331, 0x9B59, 0xC332, 0x9B5A, 0xC333, 0x9B61, + 0xC334, 0x9B62, 0xC335, 0x9B63, 0xC336, 0x9B64, 0xC337, 0x9B65, + 0xC338, 0x9B66, 0xC339, 0x9B67, 0xC33A, 0x9B68, 0xC33B, 0x9B69, + 0xC33C, 0x9B6A, 0xC33D, 0x9B6B, 0xC33E, 0x9B6C, 0xC33F, 0x9B6D, + 0xC340, 0x9B6E, 0xC341, 0x9B6F, 0xC342, 0x9B70, 0xC343, 0x9B71, + 0xC344, 0x9B72, 0xC345, 0xBDE0, 0xC346, 0x9B73, 0xC347, 0x9B74, + 0xC348, 0x9B75, 0xC349, 0x9B76, 0xC34A, 0x9B77, 0xC34B, 0x9B78, + 0xC34C, 0x9B79, 0xC34D, 0x9B7A, 0xC34E, 0x9B81, 0xC34F, 0x9B82, + 0xC350, 0x9B83, 0xC351, 0x9B84, 0xC352, 0x9B85, 0xC353, 0x9B86, + 0xC354, 0x9B87, 0xC355, 0x9B88, 0xC356, 0x9B89, 0xC357, 0x9B8A, + 0xC358, 0x9B8B, 0xC359, 0x9B8C, 0xC35A, 0x9B8D, 0xC35B, 0x9B8E, + 0xC35C, 0x9B8F, 0xC35D, 0x9B90, 0xC35E, 0x9B91, 0xC35F, 0x9B92, + 0xC360, 0x9B93, 0xC361, 0x9B94, 0xC362, 0x9B95, 0xC363, 0x9B96, + 0xC364, 0x9B97, 0xC365, 0x9B98, 0xC366, 0x9B99, 0xC367, 0x9B9A, + 0xC368, 0xBDE1, 0xC369, 0xBDE2, 0xC36A, 0x9B9B, 0xC36B, 0x9B9C, + 0xC36C, 0xBDE3, 0xC36D, 0x9B9D, 0xC36E, 0x9B9E, 0xC36F, 0x9B9F, + 0xC370, 0xBDE4, 0xC371, 0x9BA0, 0xC372, 0xBDE5, 0xC373, 0x9BA1, + 0xC374, 0x9BA2, 0xC375, 0x9BA3, 0xC376, 0x9BA4, 0xC377, 0x9BA5, + 0xC378, 0xBDE6, 0xC379, 0xBDE7, 0xC37A, 0x9BA6, 0xC37B, 0x9BA7, + 0xC37C, 0xBDE8, 0xC37D, 0xBDE9, 0xC37E, 0x9BA8, 0xC37F, 0x9BA9, + 0xC380, 0x9BAA, 0xC381, 0x9BAB, 0xC382, 0x9BAC, 0xC383, 0x9BAD, + 0xC384, 0xBDEA, 0xC385, 0x9BAE, 0xC386, 0x9BAF, 0xC387, 0x9BB0, + 0xC388, 0xBDEB, 0xC389, 0x9BB1, 0xC38A, 0x9BB2, 0xC38B, 0x9BB3, + 0xC38C, 0xBDEC, 0xC38D, 0x9BB4, 0xC38E, 0x9BB5, 0xC38F, 0x9BB6, + 0xC390, 0x9BB7, 0xC391, 0x9BB8, 0xC392, 0x9BB9, 0xC393, 0x9BBA, + 0xC394, 0x9BBB, 0xC395, 0x9BBC, 0xC396, 0x9BBD, 0xC397, 0x9BBE, + 0xC398, 0x9BBF, 0xC399, 0x9BC0, 0xC39A, 0x9BC1, 0xC39B, 0x9BC2, + 0xC39C, 0x9BC3, 0xC39D, 0x9BC4, 0xC39E, 0x9BC5, 0xC39F, 0x9BC6, + 0xC3A0, 0x9BC7, 0xC3A1, 0x9BC8, 0xC3A2, 0x9BC9, 0xC3A3, 0x9BCA, + 0xC3A4, 0x9BCB, 0xC3A5, 0x9BCC, 0xC3A6, 0x9BCD, 0xC3A7, 0x9BCE, + 0xC3A8, 0x9BCF, 0xC3A9, 0x9BD0, 0xC3AA, 0x9BD1, 0xC3AB, 0x9BD2, + 0xC3AC, 0x9BD3, 0xC3AD, 0x9BD4, 0xC3AE, 0x9BD5, 0xC3AF, 0x9BD6, + 0xC3B0, 0x9BD7, 0xC3B1, 0x9BD8, 0xC3B2, 0x9BD9, 0xC3B3, 0x9BDA, + 0xC3B4, 0x9BDB, 0xC3B5, 0x9BDC, 0xC3B6, 0x9BDD, 0xC3B7, 0x9BDE, + 0xC3B8, 0x9BDF, 0xC3B9, 0x9BE0, 0xC3BA, 0x9BE1, 0xC3BB, 0x9BE2, + 0xC3BC, 0x9BE3, 0xC3BD, 0x9BE4, 0xC3BE, 0x9BE5, 0xC3BF, 0x9BE6, + 0xC3C0, 0xBDED, 0xC3C1, 0x9BE7, 0xC3C2, 0x9BE8, 0xC3C3, 0x9BE9, + 0xC3C4, 0x9BEA, 0xC3C5, 0x9BEB, 0xC3C6, 0x9BEC, 0xC3C7, 0x9BED, + 0xC3C8, 0x9BEE, 0xC3C9, 0x9BEF, 0xC3CA, 0x9BF0, 0xC3CB, 0x9BF1, + 0xC3CC, 0x9BF2, 0xC3CD, 0x9BF3, 0xC3CE, 0x9BF4, 0xC3CF, 0x9BF5, + 0xC3D0, 0x9BF6, 0xC3D1, 0x9BF7, 0xC3D2, 0x9BF8, 0xC3D3, 0x9BF9, + 0xC3D4, 0x9BFA, 0xC3D5, 0x9BFB, 0xC3D6, 0x9BFC, 0xC3D7, 0x9BFD, + 0xC3D8, 0xBDEE, 0xC3D9, 0xBDEF, 0xC3DA, 0x9BFE, 0xC3DB, 0x9C41, + 0xC3DC, 0xBDF0, 0xC3DD, 0x9C42, 0xC3DE, 0x9C43, 0xC3DF, 0xBDF1, + 0xC3E0, 0xBDF2, 0xC3E1, 0x9C44, 0xC3E2, 0xBDF3, 0xC3E3, 0x9C45, + 0xC3E4, 0x9C46, 0xC3E5, 0x9C47, 0xC3E6, 0x9C48, 0xC3E7, 0x9C49, + 0xC3E8, 0xBDF4, 0xC3E9, 0xBDF5, 0xC3EA, 0x9C4A, 0xC3EB, 0x9C4B, + 0xC3EC, 0x9C4C, 0xC3ED, 0xBDF6, 0xC3EE, 0x9C4D, 0xC3EF, 0x9C4E, + 0xC3F0, 0x9C4F, 0xC3F1, 0x9C50, 0xC3F2, 0x9C51, 0xC3F3, 0x9C52, + 0xC3F4, 0xBDF7, 0xC3F5, 0xBDF8, 0xC3F6, 0x9C53, 0xC3F7, 0x9C54, + 0xC3F8, 0xBDF9, 0xC3F9, 0x9C55, 0xC3FA, 0x9C56, 0xC3FB, 0x9C57, + 0xC3FC, 0x9C58, 0xC3FD, 0x9C59, 0xC3FE, 0x9C5A, 0xC3FF, 0x9C61, + 0xC400, 0x9C62, 0xC401, 0x9C63, 0xC402, 0x9C64, 0xC403, 0x9C65, + 0xC404, 0x9C66, 0xC405, 0x9C67, 0xC406, 0x9C68, 0xC407, 0x9C69, + 0xC408, 0xBDFA, 0xC409, 0x9C6A, 0xC40A, 0x9C6B, 0xC40B, 0x9C6C, + 0xC40C, 0x9C6D, 0xC40D, 0x9C6E, 0xC40E, 0x9C6F, 0xC40F, 0x9C70, + 0xC410, 0xBDFB, 0xC411, 0x9C71, 0xC412, 0x9C72, 0xC413, 0x9C73, + 0xC414, 0x9C74, 0xC415, 0x9C75, 0xC416, 0x9C76, 0xC417, 0x9C77, + 0xC418, 0x9C78, 0xC419, 0x9C79, 0xC41A, 0x9C7A, 0xC41B, 0x9C81, + 0xC41C, 0x9C82, 0xC41D, 0x9C83, 0xC41E, 0x9C84, 0xC41F, 0x9C85, + 0xC420, 0x9C86, 0xC421, 0x9C87, 0xC422, 0x9C88, 0xC423, 0x9C89, + 0xC424, 0xBDFC, 0xC425, 0x9C8A, 0xC426, 0x9C8B, 0xC427, 0x9C8C, + 0xC428, 0x9C8D, 0xC429, 0x9C8E, 0xC42A, 0x9C8F, 0xC42B, 0x9C90, + 0xC42C, 0xBDFD, 0xC42D, 0x9C91, 0xC42E, 0x9C92, 0xC42F, 0x9C93, + 0xC430, 0xBDFE, 0xC431, 0x9C94, 0xC432, 0x9C95, 0xC433, 0x9C96, + 0xC434, 0xBEA1, 0xC435, 0x9C97, 0xC436, 0x9C98, 0xC437, 0x9C99, + 0xC438, 0x9C9A, 0xC439, 0x9C9B, 0xC43A, 0x9C9C, 0xC43B, 0x9C9D, + 0xC43C, 0xBEA2, 0xC43D, 0xBEA3, 0xC43E, 0x9C9E, 0xC43F, 0x9C9F, + 0xC440, 0x9CA0, 0xC441, 0x9CA1, 0xC442, 0x9CA2, 0xC443, 0x9CA3, + 0xC444, 0x9CA4, 0xC445, 0x9CA5, 0xC446, 0x9CA6, 0xC447, 0x9CA7, + 0xC448, 0xBEA4, 0xC449, 0x9CA8, 0xC44A, 0x9CA9, 0xC44B, 0x9CAA, + 0xC44C, 0x9CAB, 0xC44D, 0x9CAC, 0xC44E, 0x9CAD, 0xC44F, 0x9CAE, + 0xC450, 0x9CAF, 0xC451, 0x9CB0, 0xC452, 0x9CB1, 0xC453, 0x9CB2, + 0xC454, 0x9CB3, 0xC455, 0x9CB4, 0xC456, 0x9CB5, 0xC457, 0x9CB6, + 0xC458, 0x9CB7, 0xC459, 0x9CB8, 0xC45A, 0x9CB9, 0xC45B, 0x9CBA, + 0xC45C, 0x9CBB, 0xC45D, 0x9CBC, 0xC45E, 0x9CBD, 0xC45F, 0x9CBE, + 0xC460, 0x9CBF, 0xC461, 0x9CC0, 0xC462, 0x9CC1, 0xC463, 0x9CC2, + 0xC464, 0xBEA5, 0xC465, 0xBEA6, 0xC466, 0x9CC3, 0xC467, 0x9CC4, + 0xC468, 0xBEA7, 0xC469, 0x9CC5, 0xC46A, 0x9CC6, 0xC46B, 0x9CC7, + 0xC46C, 0xBEA8, 0xC46D, 0x9CC8, 0xC46E, 0x9CC9, 0xC46F, 0x9CCA, + 0xC470, 0x9CCB, 0xC471, 0x9CCC, 0xC472, 0x9CCD, 0xC473, 0x9CCE, + 0xC474, 0xBEA9, 0xC475, 0xBEAA, 0xC476, 0x9CCF, 0xC477, 0x9CD0, + 0xC478, 0x9CD1, 0xC479, 0xBEAB, 0xC47A, 0x9CD2, 0xC47B, 0x9CD3, + 0xC47C, 0x9CD4, 0xC47D, 0x9CD5, 0xC47E, 0x9CD6, 0xC47F, 0x9CD7, + 0xC480, 0xBEAC, 0xC481, 0x9CD8, 0xC482, 0x9CD9, 0xC483, 0x9CDA, + 0xC484, 0x9CDB, 0xC485, 0x9CDC, 0xC486, 0x9CDD, 0xC487, 0x9CDE, + 0xC488, 0x9CDF, 0xC489, 0x9CE0, 0xC48A, 0x9CE1, 0xC48B, 0x9CE2, + 0xC48C, 0x9CE3, 0xC48D, 0x9CE4, 0xC48E, 0x9CE5, 0xC48F, 0x9CE6, + 0xC490, 0x9CE7, 0xC491, 0x9CE8, 0xC492, 0x9CE9, 0xC493, 0x9CEA, + 0xC494, 0xBEAD, 0xC495, 0x9CEB, 0xC496, 0x9CEC, 0xC497, 0x9CED, + 0xC498, 0x9CEE, 0xC499, 0x9CEF, 0xC49A, 0x9CF0, 0xC49B, 0x9CF1, + 0xC49C, 0xBEAE, 0xC49D, 0x9CF2, 0xC49E, 0x9CF3, 0xC49F, 0x9CF4, + 0xC4A0, 0x9CF5, 0xC4A1, 0x9CF6, 0xC4A2, 0x9CF7, 0xC4A3, 0x9CF8, + 0xC4A4, 0x9CF9, 0xC4A5, 0x9CFA, 0xC4A6, 0x9CFB, 0xC4A7, 0x9CFC, + 0xC4A8, 0x9CFD, 0xC4A9, 0x9CFE, 0xC4AA, 0x9D41, 0xC4AB, 0x9D42, + 0xC4AC, 0x9D43, 0xC4AD, 0x9D44, 0xC4AE, 0x9D45, 0xC4AF, 0x9D46, + 0xC4B0, 0x9D47, 0xC4B1, 0x9D48, 0xC4B2, 0x9D49, 0xC4B3, 0x9D4A, + 0xC4B4, 0x9D4B, 0xC4B5, 0x9D4C, 0xC4B6, 0x9D4D, 0xC4B7, 0x9D4E, + 0xC4B8, 0xBEAF, 0xC4B9, 0x9D4F, 0xC4BA, 0x9D50, 0xC4BB, 0x9D51, + 0xC4BC, 0xBEB0, 0xC4BD, 0x9D52, 0xC4BE, 0x9D53, 0xC4BF, 0x9D54, + 0xC4C0, 0x9D55, 0xC4C1, 0x9D56, 0xC4C2, 0x9D57, 0xC4C3, 0x9D58, + 0xC4C4, 0x9D59, 0xC4C5, 0x9D5A, 0xC4C6, 0x9D61, 0xC4C7, 0x9D62, + 0xC4C8, 0x9D63, 0xC4C9, 0x9D64, 0xC4CA, 0x9D65, 0xC4CB, 0x9D66, + 0xC4CC, 0x9D67, 0xC4CD, 0x9D68, 0xC4CE, 0x9D69, 0xC4CF, 0x9D6A, + 0xC4D0, 0x9D6B, 0xC4D1, 0x9D6C, 0xC4D2, 0x9D6D, 0xC4D3, 0x9D6E, + 0xC4D4, 0x9D6F, 0xC4D5, 0x9D70, 0xC4D6, 0x9D71, 0xC4D7, 0x9D72, + 0xC4D8, 0x9D73, 0xC4D9, 0x9D74, 0xC4DA, 0x9D75, 0xC4DB, 0x9D76, + 0xC4DC, 0x9D77, 0xC4DD, 0x9D78, 0xC4DE, 0x9D79, 0xC4DF, 0x9D7A, + 0xC4E0, 0x9D81, 0xC4E1, 0x9D82, 0xC4E2, 0x9D83, 0xC4E3, 0x9D84, + 0xC4E4, 0x9D85, 0xC4E5, 0x9D86, 0xC4E6, 0x9D87, 0xC4E7, 0x9D88, + 0xC4E8, 0x9D89, 0xC4E9, 0xBEB1, 0xC4EA, 0x9D8A, 0xC4EB, 0x9D8B, + 0xC4EC, 0x9D8C, 0xC4ED, 0x9D8D, 0xC4EE, 0x9D8E, 0xC4EF, 0x9D8F, + 0xC4F0, 0xBEB2, 0xC4F1, 0xBEB3, 0xC4F2, 0x9D90, 0xC4F3, 0x9D91, + 0xC4F4, 0xBEB4, 0xC4F5, 0x9D92, 0xC4F6, 0x9D93, 0xC4F7, 0x9D94, + 0xC4F8, 0xBEB5, 0xC4F9, 0x9D95, 0xC4FA, 0xBEB6, 0xC4FB, 0x9D96, + 0xC4FC, 0x9D97, 0xC4FD, 0x9D98, 0xC4FE, 0x9D99, 0xC4FF, 0xBEB7, + 0xC500, 0xBEB8, 0xC501, 0xBEB9, 0xC502, 0x9D9A, 0xC503, 0x9D9B, + 0xC504, 0x9D9C, 0xC505, 0x9D9D, 0xC506, 0x9D9E, 0xC507, 0x9D9F, + 0xC508, 0x9DA0, 0xC509, 0x9DA1, 0xC50A, 0x9DA2, 0xC50B, 0x9DA3, + 0xC50C, 0xBEBA, 0xC50D, 0x9DA4, 0xC50E, 0x9DA5, 0xC50F, 0x9DA6, + 0xC510, 0xBEBB, 0xC511, 0x9DA7, 0xC512, 0x9DA8, 0xC513, 0x9DA9, + 0xC514, 0xBEBC, 0xC515, 0x9DAA, 0xC516, 0x9DAB, 0xC517, 0x9DAC, + 0xC518, 0x9DAD, 0xC519, 0x9DAE, 0xC51A, 0x9DAF, 0xC51B, 0x9DB0, + 0xC51C, 0xBEBD, 0xC51D, 0x9DB1, 0xC51E, 0x9DB2, 0xC51F, 0x9DB3, + 0xC520, 0x9DB4, 0xC521, 0x9DB5, 0xC522, 0x9DB6, 0xC523, 0x9DB7, + 0xC524, 0x9DB8, 0xC525, 0x9DB9, 0xC526, 0x9DBA, 0xC527, 0x9DBB, + 0xC528, 0xBEBE, 0xC529, 0xBEBF, 0xC52A, 0x9DBC, 0xC52B, 0x9DBD, + 0xC52C, 0xBEC0, 0xC52D, 0x9DBE, 0xC52E, 0x9DBF, 0xC52F, 0x9DC0, + 0xC530, 0xBEC1, 0xC531, 0x9DC1, 0xC532, 0x9DC2, 0xC533, 0x9DC3, + 0xC534, 0x9DC4, 0xC535, 0x9DC5, 0xC536, 0x9DC6, 0xC537, 0x9DC7, + 0xC538, 0xBEC2, 0xC539, 0xBEC3, 0xC53A, 0x9DC8, 0xC53B, 0xBEC4, + 0xC53C, 0x9DC9, 0xC53D, 0xBEC5, 0xC53E, 0x9DCA, 0xC53F, 0x9DCB, + 0xC540, 0x9DCC, 0xC541, 0x9DCD, 0xC542, 0x9DCE, 0xC543, 0x9DCF, + 0xC544, 0xBEC6, 0xC545, 0xBEC7, 0xC546, 0x9DD0, 0xC547, 0x9DD1, + 0xC548, 0xBEC8, 0xC549, 0xBEC9, 0xC54A, 0xBECA, 0xC54B, 0x9DD2, + 0xC54C, 0xBECB, 0xC54D, 0xBECC, 0xC54E, 0xBECD, 0xC54F, 0x9DD3, + 0xC550, 0x9DD4, 0xC551, 0x9DD5, 0xC552, 0x9DD6, 0xC553, 0xBECE, + 0xC554, 0xBECF, 0xC555, 0xBED0, 0xC556, 0x9DD7, 0xC557, 0xBED1, + 0xC558, 0xBED2, 0xC559, 0xBED3, 0xC55A, 0x9DD8, 0xC55B, 0x9DD9, + 0xC55C, 0x9DDA, 0xC55D, 0xBED4, 0xC55E, 0xBED5, 0xC55F, 0x9DDB, + 0xC560, 0xBED6, 0xC561, 0xBED7, 0xC562, 0x9DDC, 0xC563, 0x9DDD, + 0xC564, 0xBED8, 0xC565, 0x9DDE, 0xC566, 0x9DDF, 0xC567, 0x9DE0, + 0xC568, 0xBED9, 0xC569, 0x9DE1, 0xC56A, 0x9DE2, 0xC56B, 0x9DE3, + 0xC56C, 0x9DE4, 0xC56D, 0x9DE5, 0xC56E, 0x9DE6, 0xC56F, 0x9DE7, + 0xC570, 0xBEDA, 0xC571, 0xBEDB, 0xC572, 0x9DE8, 0xC573, 0xBEDC, + 0xC574, 0xBEDD, 0xC575, 0xBEDE, 0xC576, 0x9DE9, 0xC577, 0x9DEA, + 0xC578, 0x9DEB, 0xC579, 0x9DEC, 0xC57A, 0x9DED, 0xC57B, 0x9DEE, + 0xC57C, 0xBEDF, 0xC57D, 0xBEE0, 0xC57E, 0x9DEF, 0xC57F, 0x9DF0, + 0xC580, 0xBEE1, 0xC581, 0x9DF1, 0xC582, 0x9DF2, 0xC583, 0x9DF3, + 0xC584, 0xBEE2, 0xC585, 0x9DF4, 0xC586, 0x9DF5, 0xC587, 0xBEE3, + 0xC588, 0x9DF6, 0xC589, 0x9DF7, 0xC58A, 0x9DF8, 0xC58B, 0x9DF9, + 0xC58C, 0xBEE4, 0xC58D, 0xBEE5, 0xC58E, 0x9DFA, 0xC58F, 0xBEE6, + 0xC590, 0x9DFB, 0xC591, 0xBEE7, 0xC592, 0x9DFC, 0xC593, 0x9DFD, + 0xC594, 0x9DFE, 0xC595, 0xBEE8, 0xC596, 0x9E41, 0xC597, 0xBEE9, + 0xC598, 0xBEEA, 0xC599, 0x9E42, 0xC59A, 0x9E43, 0xC59B, 0x9E44, + 0xC59C, 0xBEEB, 0xC59D, 0x9E45, 0xC59E, 0x9E46, 0xC59F, 0x9E47, + 0xC5A0, 0xBEEC, 0xC5A1, 0x9E48, 0xC5A2, 0x9E49, 0xC5A3, 0x9E4A, + 0xC5A4, 0x9E4B, 0xC5A5, 0x9E4C, 0xC5A6, 0x9E4D, 0xC5A7, 0x9E4E, + 0xC5A8, 0x9E4F, 0xC5A9, 0xBEED, 0xC5AA, 0x9E50, 0xC5AB, 0x9E51, + 0xC5AC, 0x9E52, 0xC5AD, 0x9E53, 0xC5AE, 0x9E54, 0xC5AF, 0x9E55, + 0xC5B0, 0x9E56, 0xC5B1, 0x9E57, 0xC5B2, 0x9E58, 0xC5B3, 0x9E59, + 0xC5B4, 0xBEEE, 0xC5B5, 0xBEEF, 0xC5B6, 0x9E5A, 0xC5B7, 0x9E61, + 0xC5B8, 0xBEF0, 0xC5B9, 0xBEF1, 0xC5BA, 0x9E62, 0xC5BB, 0xBEF2, + 0xC5BC, 0xBEF3, 0xC5BD, 0xBEF4, 0xC5BE, 0xBEF5, 0xC5BF, 0x9E63, + 0xC5C0, 0x9E64, 0xC5C1, 0x9E65, 0xC5C2, 0x9E66, 0xC5C3, 0x9E67, + 0xC5C4, 0xBEF6, 0xC5C5, 0xBEF7, 0xC5C6, 0xBEF8, 0xC5C7, 0xBEF9, + 0xC5C8, 0xBEFA, 0xC5C9, 0xBEFB, 0xC5CA, 0xBEFC, 0xC5CB, 0x9E68, + 0xC5CC, 0xBEFD, 0xC5CD, 0x9E69, 0xC5CE, 0xBEFE, 0xC5CF, 0x9E6A, + 0xC5D0, 0xBFA1, 0xC5D1, 0xBFA2, 0xC5D2, 0x9E6B, 0xC5D3, 0x9E6C, + 0xC5D4, 0xBFA3, 0xC5D5, 0x9E6D, 0xC5D6, 0x9E6E, 0xC5D7, 0x9E6F, + 0xC5D8, 0xBFA4, 0xC5D9, 0x9E70, 0xC5DA, 0x9E71, 0xC5DB, 0x9E72, + 0xC5DC, 0x9E73, 0xC5DD, 0x9E74, 0xC5DE, 0x9E75, 0xC5DF, 0x9E76, + 0xC5E0, 0xBFA5, 0xC5E1, 0xBFA6, 0xC5E2, 0x9E77, 0xC5E3, 0xBFA7, + 0xC5E4, 0x9E78, 0xC5E5, 0xBFA8, 0xC5E6, 0x9E79, 0xC5E7, 0x9E7A, + 0xC5E8, 0x9E81, 0xC5E9, 0x9E82, 0xC5EA, 0x9E83, 0xC5EB, 0x9E84, + 0xC5EC, 0xBFA9, 0xC5ED, 0xBFAA, 0xC5EE, 0xBFAB, 0xC5EF, 0x9E85, + 0xC5F0, 0xBFAC, 0xC5F1, 0x9E86, 0xC5F2, 0x9E87, 0xC5F3, 0x9E88, + 0xC5F4, 0xBFAD, 0xC5F5, 0x9E89, 0xC5F6, 0xBFAE, 0xC5F7, 0xBFAF, + 0xC5F8, 0x9E8A, 0xC5F9, 0x9E8B, 0xC5FA, 0x9E8C, 0xC5FB, 0x9E8D, + 0xC5FC, 0xBFB0, 0xC5FD, 0xBFB1, 0xC5FE, 0xBFB2, 0xC5FF, 0xBFB3, + 0xC600, 0xBFB4, 0xC601, 0xBFB5, 0xC602, 0x9E8E, 0xC603, 0x9E8F, + 0xC604, 0x9E90, 0xC605, 0xBFB6, 0xC606, 0xBFB7, 0xC607, 0xBFB8, + 0xC608, 0xBFB9, 0xC609, 0x9E91, 0xC60A, 0x9E92, 0xC60B, 0x9E93, + 0xC60C, 0xBFBA, 0xC60D, 0x9E94, 0xC60E, 0x9E95, 0xC60F, 0x9E96, + 0xC610, 0xBFBB, 0xC611, 0x9E97, 0xC612, 0x9E98, 0xC613, 0x9E99, + 0xC614, 0x9E9A, 0xC615, 0x9E9B, 0xC616, 0x9E9C, 0xC617, 0x9E9D, + 0xC618, 0xBFBC, 0xC619, 0xBFBD, 0xC61A, 0x9E9E, 0xC61B, 0xBFBE, + 0xC61C, 0xBFBF, 0xC61D, 0x9E9F, 0xC61E, 0x9EA0, 0xC61F, 0x9EA1, + 0xC620, 0x9EA2, 0xC621, 0x9EA3, 0xC622, 0x9EA4, 0xC623, 0x9EA5, + 0xC624, 0xBFC0, 0xC625, 0xBFC1, 0xC626, 0x9EA6, 0xC627, 0x9EA7, + 0xC628, 0xBFC2, 0xC629, 0x9EA8, 0xC62A, 0x9EA9, 0xC62B, 0x9EAA, + 0xC62C, 0xBFC3, 0xC62D, 0xBFC4, 0xC62E, 0xBFC5, 0xC62F, 0x9EAB, + 0xC630, 0xBFC6, 0xC631, 0x9EAC, 0xC632, 0x9EAD, 0xC633, 0xBFC7, + 0xC634, 0xBFC8, 0xC635, 0xBFC9, 0xC636, 0x9EAE, 0xC637, 0xBFCA, + 0xC638, 0x9EAF, 0xC639, 0xBFCB, 0xC63A, 0x9EB0, 0xC63B, 0xBFCC, + 0xC63C, 0x9EB1, 0xC63D, 0x9EB2, 0xC63E, 0x9EB3, 0xC63F, 0x9EB4, + 0xC640, 0xBFCD, 0xC641, 0xBFCE, 0xC642, 0x9EB5, 0xC643, 0x9EB6, + 0xC644, 0xBFCF, 0xC645, 0x9EB7, 0xC646, 0x9EB8, 0xC647, 0x9EB9, + 0xC648, 0xBFD0, 0xC649, 0x9EBA, 0xC64A, 0x9EBB, 0xC64B, 0x9EBC, + 0xC64C, 0x9EBD, 0xC64D, 0x9EBE, 0xC64E, 0x9EBF, 0xC64F, 0x9EC0, + 0xC650, 0xBFD1, 0xC651, 0xBFD2, 0xC652, 0x9EC1, 0xC653, 0xBFD3, + 0xC654, 0xBFD4, 0xC655, 0xBFD5, 0xC656, 0x9EC2, 0xC657, 0x9EC3, + 0xC658, 0x9EC4, 0xC659, 0x9EC5, 0xC65A, 0x9EC6, 0xC65B, 0x9EC7, + 0xC65C, 0xBFD6, 0xC65D, 0xBFD7, 0xC65E, 0x9EC8, 0xC65F, 0x9EC9, + 0xC660, 0xBFD8, 0xC661, 0x9ECA, 0xC662, 0x9ECB, 0xC663, 0x9ECC, + 0xC664, 0x9ECD, 0xC665, 0x9ECE, 0xC666, 0x9ECF, 0xC667, 0x9ED0, + 0xC668, 0x9ED1, 0xC669, 0x9ED2, 0xC66A, 0x9ED3, 0xC66B, 0x9ED4, + 0xC66C, 0xBFD9, 0xC66D, 0x9ED5, 0xC66E, 0x9ED6, 0xC66F, 0xBFDA, + 0xC670, 0x9ED7, 0xC671, 0xBFDB, 0xC672, 0x9ED8, 0xC673, 0x9ED9, + 0xC674, 0x9EDA, 0xC675, 0x9EDB, 0xC676, 0x9EDC, 0xC677, 0x9EDD, + 0xC678, 0xBFDC, 0xC679, 0xBFDD, 0xC67A, 0x9EDE, 0xC67B, 0x9EDF, + 0xC67C, 0xBFDE, 0xC67D, 0x9EE0, 0xC67E, 0x9EE1, 0xC67F, 0x9EE2, + 0xC680, 0xBFDF, 0xC681, 0x9EE3, 0xC682, 0x9EE4, 0xC683, 0x9EE5, + 0xC684, 0x9EE6, 0xC685, 0x9EE7, 0xC686, 0x9EE8, 0xC687, 0x9EE9, + 0xC688, 0xBFE0, 0xC689, 0xBFE1, 0xC68A, 0x9EEA, 0xC68B, 0xBFE2, + 0xC68C, 0x9EEB, 0xC68D, 0xBFE3, 0xC68E, 0x9EEC, 0xC68F, 0x9EED, + 0xC690, 0x9EEE, 0xC691, 0x9EEF, 0xC692, 0x9EF0, 0xC693, 0x9EF1, + 0xC694, 0xBFE4, 0xC695, 0xBFE5, 0xC696, 0x9EF2, 0xC697, 0x9EF3, + 0xC698, 0xBFE6, 0xC699, 0x9EF4, 0xC69A, 0x9EF5, 0xC69B, 0x9EF6, + 0xC69C, 0xBFE7, 0xC69D, 0x9EF7, 0xC69E, 0x9EF8, 0xC69F, 0x9EF9, + 0xC6A0, 0x9EFA, 0xC6A1, 0x9EFB, 0xC6A2, 0x9EFC, 0xC6A3, 0x9EFD, + 0xC6A4, 0xBFE8, 0xC6A5, 0xBFE9, 0xC6A6, 0x9EFE, 0xC6A7, 0xBFEA, + 0xC6A8, 0x9F41, 0xC6A9, 0xBFEB, 0xC6AA, 0x9F42, 0xC6AB, 0x9F43, + 0xC6AC, 0x9F44, 0xC6AD, 0x9F45, 0xC6AE, 0x9F46, 0xC6AF, 0x9F47, + 0xC6B0, 0xBFEC, 0xC6B1, 0xBFED, 0xC6B2, 0x9F48, 0xC6B3, 0x9F49, + 0xC6B4, 0xBFEE, 0xC6B5, 0x9F4A, 0xC6B6, 0x9F4B, 0xC6B7, 0x9F4C, + 0xC6B8, 0xBFEF, 0xC6B9, 0xBFF0, 0xC6BA, 0xBFF1, 0xC6BB, 0x9F4D, + 0xC6BC, 0x9F4E, 0xC6BD, 0x9F4F, 0xC6BE, 0x9F50, 0xC6BF, 0x9F51, + 0xC6C0, 0xBFF2, 0xC6C1, 0xBFF3, 0xC6C2, 0x9F52, 0xC6C3, 0xBFF4, + 0xC6C4, 0x9F53, 0xC6C5, 0xBFF5, 0xC6C6, 0x9F54, 0xC6C7, 0x9F55, + 0xC6C8, 0x9F56, 0xC6C9, 0x9F57, 0xC6CA, 0x9F58, 0xC6CB, 0x9F59, + 0xC6CC, 0xBFF6, 0xC6CD, 0xBFF7, 0xC6CE, 0x9F5A, 0xC6CF, 0x9F61, + 0xC6D0, 0xBFF8, 0xC6D1, 0x9F62, 0xC6D2, 0x9F63, 0xC6D3, 0x9F64, + 0xC6D4, 0xBFF9, 0xC6D5, 0x9F65, 0xC6D6, 0x9F66, 0xC6D7, 0x9F67, + 0xC6D8, 0x9F68, 0xC6D9, 0x9F69, 0xC6DA, 0x9F6A, 0xC6DB, 0x9F6B, + 0xC6DC, 0xBFFA, 0xC6DD, 0xBFFB, 0xC6DE, 0x9F6C, 0xC6DF, 0x9F6D, + 0xC6E0, 0xBFFC, 0xC6E1, 0xBFFD, 0xC6E2, 0x9F6E, 0xC6E3, 0x9F6F, + 0xC6E4, 0x9F70, 0xC6E5, 0x9F71, 0xC6E6, 0x9F72, 0xC6E7, 0x9F73, + 0xC6E8, 0xBFFE, 0xC6E9, 0xC0A1, 0xC6EA, 0x9F74, 0xC6EB, 0x9F75, + 0xC6EC, 0xC0A2, 0xC6ED, 0x9F76, 0xC6EE, 0x9F77, 0xC6EF, 0x9F78, + 0xC6F0, 0xC0A3, 0xC6F1, 0x9F79, 0xC6F2, 0x9F7A, 0xC6F3, 0x9F81, + 0xC6F4, 0x9F82, 0xC6F5, 0x9F83, 0xC6F6, 0x9F84, 0xC6F7, 0x9F85, + 0xC6F8, 0xC0A4, 0xC6F9, 0xC0A5, 0xC6FA, 0x9F86, 0xC6FB, 0x9F87, + 0xC6FC, 0x9F88, 0xC6FD, 0xC0A6, 0xC6FE, 0x9F89, 0xC6FF, 0x9F8A, + 0xC700, 0x9F8B, 0xC701, 0x9F8C, 0xC702, 0x9F8D, 0xC703, 0x9F8E, + 0xC704, 0xC0A7, 0xC705, 0xC0A8, 0xC706, 0x9F8F, 0xC707, 0x9F90, + 0xC708, 0xC0A9, 0xC709, 0x9F91, 0xC70A, 0x9F92, 0xC70B, 0x9F93, + 0xC70C, 0xC0AA, 0xC70D, 0x9F94, 0xC70E, 0x9F95, 0xC70F, 0x9F96, + 0xC710, 0x9F97, 0xC711, 0x9F98, 0xC712, 0x9F99, 0xC713, 0x9F9A, + 0xC714, 0xC0AB, 0xC715, 0xC0AC, 0xC716, 0x9F9B, 0xC717, 0xC0AD, + 0xC718, 0x9F9C, 0xC719, 0xC0AE, 0xC71A, 0x9F9D, 0xC71B, 0x9F9E, + 0xC71C, 0x9F9F, 0xC71D, 0x9FA0, 0xC71E, 0x9FA1, 0xC71F, 0x9FA2, + 0xC720, 0xC0AF, 0xC721, 0xC0B0, 0xC722, 0x9FA3, 0xC723, 0x9FA4, + 0xC724, 0xC0B1, 0xC725, 0x9FA5, 0xC726, 0x9FA6, 0xC727, 0x9FA7, + 0xC728, 0xC0B2, 0xC729, 0x9FA8, 0xC72A, 0x9FA9, 0xC72B, 0x9FAA, + 0xC72C, 0x9FAB, 0xC72D, 0x9FAC, 0xC72E, 0x9FAD, 0xC72F, 0x9FAE, + 0xC730, 0xC0B3, 0xC731, 0xC0B4, 0xC732, 0x9FAF, 0xC733, 0xC0B5, + 0xC734, 0x9FB0, 0xC735, 0xC0B6, 0xC736, 0x9FB1, 0xC737, 0xC0B7, + 0xC738, 0x9FB2, 0xC739, 0x9FB3, 0xC73A, 0x9FB4, 0xC73B, 0x9FB5, + 0xC73C, 0xC0B8, 0xC73D, 0xC0B9, 0xC73E, 0x9FB6, 0xC73F, 0x9FB7, + 0xC740, 0xC0BA, 0xC741, 0x9FB8, 0xC742, 0x9FB9, 0xC743, 0x9FBA, + 0xC744, 0xC0BB, 0xC745, 0x9FBB, 0xC746, 0x9FBC, 0xC747, 0x9FBD, + 0xC748, 0x9FBE, 0xC749, 0x9FBF, 0xC74A, 0xC0BC, 0xC74B, 0x9FC0, + 0xC74C, 0xC0BD, 0xC74D, 0xC0BE, 0xC74E, 0x9FC1, 0xC74F, 0xC0BF, + 0xC750, 0x9FC2, 0xC751, 0xC0C0, 0xC752, 0xC0C1, 0xC753, 0xC0C2, + 0xC754, 0xC0C3, 0xC755, 0xC0C4, 0xC756, 0xC0C5, 0xC757, 0xC0C6, + 0xC758, 0xC0C7, 0xC759, 0x9FC3, 0xC75A, 0x9FC4, 0xC75B, 0x9FC5, + 0xC75C, 0xC0C8, 0xC75D, 0x9FC6, 0xC75E, 0x9FC7, 0xC75F, 0x9FC8, + 0xC760, 0xC0C9, 0xC761, 0x9FC9, 0xC762, 0x9FCA, 0xC763, 0x9FCB, + 0xC764, 0x9FCC, 0xC765, 0x9FCD, 0xC766, 0x9FCE, 0xC767, 0x9FCF, + 0xC768, 0xC0CA, 0xC769, 0x9FD0, 0xC76A, 0x9FD1, 0xC76B, 0xC0CB, + 0xC76C, 0x9FD2, 0xC76D, 0x9FD3, 0xC76E, 0x9FD4, 0xC76F, 0x9FD5, + 0xC770, 0x9FD6, 0xC771, 0x9FD7, 0xC772, 0x9FD8, 0xC773, 0x9FD9, + 0xC774, 0xC0CC, 0xC775, 0xC0CD, 0xC776, 0x9FDA, 0xC777, 0x9FDB, + 0xC778, 0xC0CE, 0xC779, 0x9FDC, 0xC77A, 0x9FDD, 0xC77B, 0x9FDE, + 0xC77C, 0xC0CF, 0xC77D, 0xC0D0, 0xC77E, 0xC0D1, 0xC77F, 0x9FDF, + 0xC780, 0x9FE0, 0xC781, 0x9FE1, 0xC782, 0x9FE2, 0xC783, 0xC0D2, + 0xC784, 0xC0D3, 0xC785, 0xC0D4, 0xC786, 0x9FE3, 0xC787, 0xC0D5, + 0xC788, 0xC0D6, 0xC789, 0xC0D7, 0xC78A, 0xC0D8, 0xC78B, 0x9FE4, + 0xC78C, 0x9FE5, 0xC78D, 0x9FE6, 0xC78E, 0xC0D9, 0xC78F, 0x9FE7, + 0xC790, 0xC0DA, 0xC791, 0xC0DB, 0xC792, 0x9FE8, 0xC793, 0x9FE9, + 0xC794, 0xC0DC, 0xC795, 0x9FEA, 0xC796, 0xC0DD, 0xC797, 0xC0DE, + 0xC798, 0xC0DF, 0xC799, 0x9FEB, 0xC79A, 0xC0E0, 0xC79B, 0x9FEC, + 0xC79C, 0x9FED, 0xC79D, 0x9FEE, 0xC79E, 0x9FEF, 0xC79F, 0x9FF0, + 0xC7A0, 0xC0E1, 0xC7A1, 0xC0E2, 0xC7A2, 0x9FF1, 0xC7A3, 0xC0E3, + 0xC7A4, 0xC0E4, 0xC7A5, 0xC0E5, 0xC7A6, 0xC0E6, 0xC7A7, 0x9FF2, + 0xC7A8, 0x9FF3, 0xC7A9, 0x9FF4, 0xC7AA, 0x9FF5, 0xC7AB, 0x9FF6, + 0xC7AC, 0xC0E7, 0xC7AD, 0xC0E8, 0xC7AE, 0x9FF7, 0xC7AF, 0x9FF8, + 0xC7B0, 0xC0E9, 0xC7B1, 0x9FF9, 0xC7B2, 0x9FFA, 0xC7B3, 0x9FFB, + 0xC7B4, 0xC0EA, 0xC7B5, 0x9FFC, 0xC7B6, 0x9FFD, 0xC7B7, 0x9FFE, + 0xC7B8, 0xA041, 0xC7B9, 0xA042, 0xC7BA, 0xA043, 0xC7BB, 0xA044, + 0xC7BC, 0xC0EB, 0xC7BD, 0xC0EC, 0xC7BE, 0xA045, 0xC7BF, 0xC0ED, + 0xC7C0, 0xC0EE, 0xC7C1, 0xC0EF, 0xC7C2, 0xA046, 0xC7C3, 0xA047, + 0xC7C4, 0xA048, 0xC7C5, 0xA049, 0xC7C6, 0xA04A, 0xC7C7, 0xA04B, + 0xC7C8, 0xC0F0, 0xC7C9, 0xC0F1, 0xC7CA, 0xA04C, 0xC7CB, 0xA04D, + 0xC7CC, 0xC0F2, 0xC7CD, 0xA04E, 0xC7CE, 0xC0F3, 0xC7CF, 0xA04F, + 0xC7D0, 0xC0F4, 0xC7D1, 0xA050, 0xC7D2, 0xA051, 0xC7D3, 0xA052, + 0xC7D4, 0xA053, 0xC7D5, 0xA054, 0xC7D6, 0xA055, 0xC7D7, 0xA056, + 0xC7D8, 0xC0F5, 0xC7D9, 0xA057, 0xC7DA, 0xA058, 0xC7DB, 0xA059, + 0xC7DC, 0xA05A, 0xC7DD, 0xC0F6, 0xC7DE, 0xA061, 0xC7DF, 0xA062, + 0xC7E0, 0xA063, 0xC7E1, 0xA064, 0xC7E2, 0xA065, 0xC7E3, 0xA066, + 0xC7E4, 0xC0F7, 0xC7E5, 0xA067, 0xC7E6, 0xA068, 0xC7E7, 0xA069, + 0xC7E8, 0xC0F8, 0xC7E9, 0xA06A, 0xC7EA, 0xA06B, 0xC7EB, 0xA06C, + 0xC7EC, 0xC0F9, 0xC7ED, 0xA06D, 0xC7EE, 0xA06E, 0xC7EF, 0xA06F, + 0xC7F0, 0xA070, 0xC7F1, 0xA071, 0xC7F2, 0xA072, 0xC7F3, 0xA073, + 0xC7F4, 0xA074, 0xC7F5, 0xA075, 0xC7F6, 0xA076, 0xC7F7, 0xA077, + 0xC7F8, 0xA078, 0xC7F9, 0xA079, 0xC7FA, 0xA07A, 0xC7FB, 0xA081, + 0xC7FC, 0xA082, 0xC7FD, 0xA083, 0xC7FE, 0xA084, 0xC7FF, 0xA085, + 0xC800, 0xC0FA, 0xC801, 0xC0FB, 0xC802, 0xA086, 0xC803, 0xA087, + 0xC804, 0xC0FC, 0xC805, 0xA088, 0xC806, 0xA089, 0xC807, 0xA08A, + 0xC808, 0xC0FD, 0xC809, 0xA08B, 0xC80A, 0xC0FE, 0xC80B, 0xA08C, + 0xC80C, 0xA08D, 0xC80D, 0xA08E, 0xC80E, 0xA08F, 0xC80F, 0xA090, + 0xC810, 0xC1A1, 0xC811, 0xC1A2, 0xC812, 0xA091, 0xC813, 0xC1A3, + 0xC814, 0xA092, 0xC815, 0xC1A4, 0xC816, 0xC1A5, 0xC817, 0xA093, + 0xC818, 0xA094, 0xC819, 0xA095, 0xC81A, 0xA096, 0xC81B, 0xA097, + 0xC81C, 0xC1A6, 0xC81D, 0xC1A7, 0xC81E, 0xA098, 0xC81F, 0xA099, + 0xC820, 0xC1A8, 0xC821, 0xA09A, 0xC822, 0xA09B, 0xC823, 0xA09C, + 0xC824, 0xC1A9, 0xC825, 0xA09D, 0xC826, 0xA09E, 0xC827, 0xA09F, + 0xC828, 0xA0A0, 0xC829, 0xA0A1, 0xC82A, 0xA0A2, 0xC82B, 0xA0A3, + 0xC82C, 0xC1AA, 0xC82D, 0xC1AB, 0xC82E, 0xA0A4, 0xC82F, 0xC1AC, + 0xC830, 0xA0A5, 0xC831, 0xC1AD, 0xC832, 0xA0A6, 0xC833, 0xA0A7, + 0xC834, 0xA0A8, 0xC835, 0xA0A9, 0xC836, 0xA0AA, 0xC837, 0xA0AB, + 0xC838, 0xC1AE, 0xC839, 0xA0AC, 0xC83A, 0xA0AD, 0xC83B, 0xA0AE, + 0xC83C, 0xC1AF, 0xC83D, 0xA0AF, 0xC83E, 0xA0B0, 0xC83F, 0xA0B1, + 0xC840, 0xC1B0, 0xC841, 0xA0B2, 0xC842, 0xA0B3, 0xC843, 0xA0B4, + 0xC844, 0xA0B5, 0xC845, 0xA0B6, 0xC846, 0xA0B7, 0xC847, 0xA0B8, + 0xC848, 0xC1B1, 0xC849, 0xC1B2, 0xC84A, 0xA0B9, 0xC84B, 0xA0BA, + 0xC84C, 0xC1B3, 0xC84D, 0xC1B4, 0xC84E, 0xA0BB, 0xC84F, 0xA0BC, + 0xC850, 0xA0BD, 0xC851, 0xA0BE, 0xC852, 0xA0BF, 0xC853, 0xA0C0, + 0xC854, 0xC1B5, 0xC855, 0xA0C1, 0xC856, 0xA0C2, 0xC857, 0xA0C3, + 0xC858, 0xA0C4, 0xC859, 0xA0C5, 0xC85A, 0xA0C6, 0xC85B, 0xA0C7, + 0xC85C, 0xA0C8, 0xC85D, 0xA0C9, 0xC85E, 0xA0CA, 0xC85F, 0xA0CB, + 0xC860, 0xA0CC, 0xC861, 0xA0CD, 0xC862, 0xA0CE, 0xC863, 0xA0CF, + 0xC864, 0xA0D0, 0xC865, 0xA0D1, 0xC866, 0xA0D2, 0xC867, 0xA0D3, + 0xC868, 0xA0D4, 0xC869, 0xA0D5, 0xC86A, 0xA0D6, 0xC86B, 0xA0D7, + 0xC86C, 0xA0D8, 0xC86D, 0xA0D9, 0xC86E, 0xA0DA, 0xC86F, 0xA0DB, + 0xC870, 0xC1B6, 0xC871, 0xC1B7, 0xC872, 0xA0DC, 0xC873, 0xA0DD, + 0xC874, 0xC1B8, 0xC875, 0xA0DE, 0xC876, 0xA0DF, 0xC877, 0xA0E0, + 0xC878, 0xC1B9, 0xC879, 0xA0E1, 0xC87A, 0xC1BA, 0xC87B, 0xA0E2, + 0xC87C, 0xA0E3, 0xC87D, 0xA0E4, 0xC87E, 0xA0E5, 0xC87F, 0xA0E6, + 0xC880, 0xC1BB, 0xC881, 0xC1BC, 0xC882, 0xA0E7, 0xC883, 0xC1BD, + 0xC884, 0xA0E8, 0xC885, 0xC1BE, 0xC886, 0xC1BF, 0xC887, 0xC1C0, + 0xC888, 0xA0E9, 0xC889, 0xA0EA, 0xC88A, 0xA0EB, 0xC88B, 0xC1C1, + 0xC88C, 0xC1C2, 0xC88D, 0xC1C3, 0xC88E, 0xA0EC, 0xC88F, 0xA0ED, + 0xC890, 0xA0EE, 0xC891, 0xA0EF, 0xC892, 0xA0F0, 0xC893, 0xA0F1, + 0xC894, 0xC1C4, 0xC895, 0xA0F2, 0xC896, 0xA0F3, 0xC897, 0xA0F4, + 0xC898, 0xA0F5, 0xC899, 0xA0F6, 0xC89A, 0xA0F7, 0xC89B, 0xA0F8, + 0xC89C, 0xA0F9, 0xC89D, 0xC1C5, 0xC89E, 0xA0FA, 0xC89F, 0xC1C6, + 0xC8A0, 0xA0FB, 0xC8A1, 0xC1C7, 0xC8A2, 0xA0FC, 0xC8A3, 0xA0FD, + 0xC8A4, 0xA0FE, 0xC8A5, 0xA141, 0xC8A6, 0xA142, 0xC8A7, 0xA143, + 0xC8A8, 0xC1C8, 0xC8A9, 0xA144, 0xC8AA, 0xA145, 0xC8AB, 0xA146, + 0xC8AC, 0xA147, 0xC8AD, 0xA148, 0xC8AE, 0xA149, 0xC8AF, 0xA14A, + 0xC8B0, 0xA14B, 0xC8B1, 0xA14C, 0xC8B2, 0xA14D, 0xC8B3, 0xA14E, + 0xC8B4, 0xA14F, 0xC8B5, 0xA150, 0xC8B6, 0xA151, 0xC8B7, 0xA152, + 0xC8B8, 0xA153, 0xC8B9, 0xA154, 0xC8BA, 0xA155, 0xC8BB, 0xA156, + 0xC8BC, 0xC1C9, 0xC8BD, 0xC1CA, 0xC8BE, 0xA157, 0xC8BF, 0xA158, + 0xC8C0, 0xA159, 0xC8C1, 0xA15A, 0xC8C2, 0xA161, 0xC8C3, 0xA162, + 0xC8C4, 0xC1CB, 0xC8C5, 0xA163, 0xC8C6, 0xA164, 0xC8C7, 0xA165, + 0xC8C8, 0xC1CC, 0xC8C9, 0xA166, 0xC8CA, 0xA167, 0xC8CB, 0xA168, + 0xC8CC, 0xC1CD, 0xC8CD, 0xA169, 0xC8CE, 0xA16A, 0xC8CF, 0xA16B, + 0xC8D0, 0xA16C, 0xC8D1, 0xA16D, 0xC8D2, 0xA16E, 0xC8D3, 0xA16F, + 0xC8D4, 0xC1CE, 0xC8D5, 0xC1CF, 0xC8D6, 0xA170, 0xC8D7, 0xC1D0, + 0xC8D8, 0xA171, 0xC8D9, 0xC1D1, 0xC8DA, 0xA172, 0xC8DB, 0xA173, + 0xC8DC, 0xA174, 0xC8DD, 0xA175, 0xC8DE, 0xA176, 0xC8DF, 0xA177, + 0xC8E0, 0xC1D2, 0xC8E1, 0xC1D3, 0xC8E2, 0xA178, 0xC8E3, 0xA179, + 0xC8E4, 0xC1D4, 0xC8E5, 0xA17A, 0xC8E6, 0xA181, 0xC8E7, 0xA182, + 0xC8E8, 0xA183, 0xC8E9, 0xA184, 0xC8EA, 0xA185, 0xC8EB, 0xA186, + 0xC8EC, 0xA187, 0xC8ED, 0xA188, 0xC8EE, 0xA189, 0xC8EF, 0xA18A, + 0xC8F0, 0xA18B, 0xC8F1, 0xA18C, 0xC8F2, 0xA18D, 0xC8F3, 0xA18E, + 0xC8F4, 0xA18F, 0xC8F5, 0xC1D5, 0xC8F6, 0xA190, 0xC8F7, 0xA191, + 0xC8F8, 0xA192, 0xC8F9, 0xA193, 0xC8FA, 0xA194, 0xC8FB, 0xA195, + 0xC8FC, 0xC1D6, 0xC8FD, 0xC1D7, 0xC8FE, 0xA196, 0xC8FF, 0xA197, + 0xC900, 0xC1D8, 0xC901, 0xA198, 0xC902, 0xA199, 0xC903, 0xA19A, + 0xC904, 0xC1D9, 0xC905, 0xC1DA, 0xC906, 0xC1DB, 0xC907, 0xA19B, + 0xC908, 0xA19C, 0xC909, 0xA19D, 0xC90A, 0xA19E, 0xC90B, 0xA19F, + 0xC90C, 0xC1DC, 0xC90D, 0xC1DD, 0xC90E, 0xA1A0, 0xC90F, 0xC1DE, + 0xC910, 0xA241, 0xC911, 0xC1DF, 0xC912, 0xA242, 0xC913, 0xA243, + 0xC914, 0xA244, 0xC915, 0xA245, 0xC916, 0xA246, 0xC917, 0xA247, + 0xC918, 0xC1E0, 0xC919, 0xA248, 0xC91A, 0xA249, 0xC91B, 0xA24A, + 0xC91C, 0xA24B, 0xC91D, 0xA24C, 0xC91E, 0xA24D, 0xC91F, 0xA24E, + 0xC920, 0xA24F, 0xC921, 0xA250, 0xC922, 0xA251, 0xC923, 0xA252, + 0xC924, 0xA253, 0xC925, 0xA254, 0xC926, 0xA255, 0xC927, 0xA256, + 0xC928, 0xA257, 0xC929, 0xA258, 0xC92A, 0xA259, 0xC92B, 0xA25A, + 0xC92C, 0xC1E1, 0xC92D, 0xA261, 0xC92E, 0xA262, 0xC92F, 0xA263, + 0xC930, 0xA264, 0xC931, 0xA265, 0xC932, 0xA266, 0xC933, 0xA267, + 0xC934, 0xC1E2, 0xC935, 0xA268, 0xC936, 0xA269, 0xC937, 0xA26A, + 0xC938, 0xA26B, 0xC939, 0xA26C, 0xC93A, 0xA26D, 0xC93B, 0xA26E, + 0xC93C, 0xA26F, 0xC93D, 0xA270, 0xC93E, 0xA271, 0xC93F, 0xA272, + 0xC940, 0xA273, 0xC941, 0xA274, 0xC942, 0xA275, 0xC943, 0xA276, + 0xC944, 0xA277, 0xC945, 0xA278, 0xC946, 0xA279, 0xC947, 0xA27A, + 0xC948, 0xA281, 0xC949, 0xA282, 0xC94A, 0xA283, 0xC94B, 0xA284, + 0xC94C, 0xA285, 0xC94D, 0xA286, 0xC94E, 0xA287, 0xC94F, 0xA288, + 0xC950, 0xC1E3, 0xC951, 0xC1E4, 0xC952, 0xA289, 0xC953, 0xA28A, + 0xC954, 0xC1E5, 0xC955, 0xA28B, 0xC956, 0xA28C, 0xC957, 0xA28D, + 0xC958, 0xC1E6, 0xC959, 0xA28E, 0xC95A, 0xA28F, 0xC95B, 0xA290, + 0xC95C, 0xA291, 0xC95D, 0xA292, 0xC95E, 0xA293, 0xC95F, 0xA294, + 0xC960, 0xC1E7, 0xC961, 0xC1E8, 0xC962, 0xA295, 0xC963, 0xC1E9, + 0xC964, 0xA296, 0xC965, 0xA297, 0xC966, 0xA298, 0xC967, 0xA299, + 0xC968, 0xA29A, 0xC969, 0xA29B, 0xC96A, 0xA29C, 0xC96B, 0xA29D, + 0xC96C, 0xC1EA, 0xC96D, 0xA29E, 0xC96E, 0xA29F, 0xC96F, 0xA2A0, + 0xC970, 0xC1EB, 0xC971, 0xA341, 0xC972, 0xA342, 0xC973, 0xA343, + 0xC974, 0xC1EC, 0xC975, 0xA344, 0xC976, 0xA345, 0xC977, 0xA346, + 0xC978, 0xA347, 0xC979, 0xA348, 0xC97A, 0xA349, 0xC97B, 0xA34A, + 0xC97C, 0xC1ED, 0xC97D, 0xA34B, 0xC97E, 0xA34C, 0xC97F, 0xA34D, + 0xC980, 0xA34E, 0xC981, 0xA34F, 0xC982, 0xA350, 0xC983, 0xA351, + 0xC984, 0xA352, 0xC985, 0xA353, 0xC986, 0xA354, 0xC987, 0xA355, + 0xC988, 0xC1EE, 0xC989, 0xC1EF, 0xC98A, 0xA356, 0xC98B, 0xA357, + 0xC98C, 0xC1F0, 0xC98D, 0xA358, 0xC98E, 0xA359, 0xC98F, 0xA35A, + 0xC990, 0xC1F1, 0xC991, 0xA361, 0xC992, 0xA362, 0xC993, 0xA363, + 0xC994, 0xA364, 0xC995, 0xA365, 0xC996, 0xA366, 0xC997, 0xA367, + 0xC998, 0xC1F2, 0xC999, 0xC1F3, 0xC99A, 0xA368, 0xC99B, 0xC1F4, + 0xC99C, 0xA369, 0xC99D, 0xC1F5, 0xC99E, 0xA36A, 0xC99F, 0xA36B, + 0xC9A0, 0xA36C, 0xC9A1, 0xA36D, 0xC9A2, 0xA36E, 0xC9A3, 0xA36F, + 0xC9A4, 0xA370, 0xC9A5, 0xA371, 0xC9A6, 0xA372, 0xC9A7, 0xA373, + 0xC9A8, 0xA374, 0xC9A9, 0xA375, 0xC9AA, 0xA376, 0xC9AB, 0xA377, + 0xC9AC, 0xA378, 0xC9AD, 0xA379, 0xC9AE, 0xA37A, 0xC9AF, 0xA381, + 0xC9B0, 0xA382, 0xC9B1, 0xA383, 0xC9B2, 0xA384, 0xC9B3, 0xA385, + 0xC9B4, 0xA386, 0xC9B5, 0xA387, 0xC9B6, 0xA388, 0xC9B7, 0xA389, + 0xC9B8, 0xA38A, 0xC9B9, 0xA38B, 0xC9BA, 0xA38C, 0xC9BB, 0xA38D, + 0xC9BC, 0xA38E, 0xC9BD, 0xA38F, 0xC9BE, 0xA390, 0xC9BF, 0xA391, + 0xC9C0, 0xC1F6, 0xC9C1, 0xC1F7, 0xC9C2, 0xA392, 0xC9C3, 0xA393, + 0xC9C4, 0xC1F8, 0xC9C5, 0xA394, 0xC9C6, 0xA395, 0xC9C7, 0xC1F9, + 0xC9C8, 0xC1FA, 0xC9C9, 0xA396, 0xC9CA, 0xC1FB, 0xC9CB, 0xA397, + 0xC9CC, 0xA398, 0xC9CD, 0xA399, 0xC9CE, 0xA39A, 0xC9CF, 0xA39B, + 0xC9D0, 0xC1FC, 0xC9D1, 0xC1FD, 0xC9D2, 0xA39C, 0xC9D3, 0xC1FE, + 0xC9D4, 0xA39D, 0xC9D5, 0xC2A1, 0xC9D6, 0xC2A2, 0xC9D7, 0xA39E, + 0xC9D8, 0xA39F, 0xC9D9, 0xC2A3, 0xC9DA, 0xC2A4, 0xC9DB, 0xA3A0, + 0xC9DC, 0xC2A5, 0xC9DD, 0xC2A6, 0xC9DE, 0xA441, 0xC9DF, 0xA442, + 0xC9E0, 0xC2A7, 0xC9E1, 0xA443, 0xC9E2, 0xC2A8, 0xC9E3, 0xA444, + 0xC9E4, 0xC2A9, 0xC9E5, 0xA445, 0xC9E6, 0xA446, 0xC9E7, 0xC2AA, + 0xC9E8, 0xA447, 0xC9E9, 0xA448, 0xC9EA, 0xA449, 0xC9EB, 0xA44A, + 0xC9EC, 0xC2AB, 0xC9ED, 0xC2AC, 0xC9EE, 0xA44B, 0xC9EF, 0xC2AD, + 0xC9F0, 0xC2AE, 0xC9F1, 0xC2AF, 0xC9F2, 0xA44C, 0xC9F3, 0xA44D, + 0xC9F4, 0xA44E, 0xC9F5, 0xA44F, 0xC9F6, 0xA450, 0xC9F7, 0xA451, + 0xC9F8, 0xC2B0, 0xC9F9, 0xC2B1, 0xC9FA, 0xA452, 0xC9FB, 0xA453, + 0xC9FC, 0xC2B2, 0xC9FD, 0xA454, 0xC9FE, 0xA455, 0xC9FF, 0xA456, + 0xCA00, 0xC2B3, 0xCA01, 0xA457, 0xCA02, 0xA458, 0xCA03, 0xA459, + 0xCA04, 0xA45A, 0xCA05, 0xA461, 0xCA06, 0xA462, 0xCA07, 0xA463, + 0xCA08, 0xC2B4, 0xCA09, 0xC2B5, 0xCA0A, 0xA464, 0xCA0B, 0xC2B6, + 0xCA0C, 0xC2B7, 0xCA0D, 0xC2B8, 0xCA0E, 0xA465, 0xCA0F, 0xA466, + 0xCA10, 0xA467, 0xCA11, 0xA468, 0xCA12, 0xA469, 0xCA13, 0xA46A, + 0xCA14, 0xC2B9, 0xCA15, 0xA46B, 0xCA16, 0xA46C, 0xCA17, 0xA46D, + 0xCA18, 0xC2BA, 0xCA19, 0xA46E, 0xCA1A, 0xA46F, 0xCA1B, 0xA470, + 0xCA1C, 0xA471, 0xCA1D, 0xA472, 0xCA1E, 0xA473, 0xCA1F, 0xA474, + 0xCA20, 0xA475, 0xCA21, 0xA476, 0xCA22, 0xA477, 0xCA23, 0xA478, + 0xCA24, 0xA479, 0xCA25, 0xA47A, 0xCA26, 0xA481, 0xCA27, 0xA482, + 0xCA28, 0xA483, 0xCA29, 0xC2BB, 0xCA2A, 0xA484, 0xCA2B, 0xA485, + 0xCA2C, 0xA486, 0xCA2D, 0xA487, 0xCA2E, 0xA488, 0xCA2F, 0xA489, + 0xCA30, 0xA48A, 0xCA31, 0xA48B, 0xCA32, 0xA48C, 0xCA33, 0xA48D, + 0xCA34, 0xA48E, 0xCA35, 0xA48F, 0xCA36, 0xA490, 0xCA37, 0xA491, + 0xCA38, 0xA492, 0xCA39, 0xA493, 0xCA3A, 0xA494, 0xCA3B, 0xA495, + 0xCA3C, 0xA496, 0xCA3D, 0xA497, 0xCA3E, 0xA498, 0xCA3F, 0xA499, + 0xCA40, 0xA49A, 0xCA41, 0xA49B, 0xCA42, 0xA49C, 0xCA43, 0xA49D, + 0xCA44, 0xA49E, 0xCA45, 0xA49F, 0xCA46, 0xA4A0, 0xCA47, 0xA541, + 0xCA48, 0xA542, 0xCA49, 0xA543, 0xCA4A, 0xA544, 0xCA4B, 0xA545, + 0xCA4C, 0xC2BC, 0xCA4D, 0xC2BD, 0xCA4E, 0xA546, 0xCA4F, 0xA547, + 0xCA50, 0xC2BE, 0xCA51, 0xA548, 0xCA52, 0xA549, 0xCA53, 0xA54A, + 0xCA54, 0xC2BF, 0xCA55, 0xA54B, 0xCA56, 0xA54C, 0xCA57, 0xA54D, + 0xCA58, 0xA54E, 0xCA59, 0xA54F, 0xCA5A, 0xA550, 0xCA5B, 0xA551, + 0xCA5C, 0xC2C0, 0xCA5D, 0xC2C1, 0xCA5E, 0xA552, 0xCA5F, 0xC2C2, + 0xCA60, 0xC2C3, 0xCA61, 0xC2C4, 0xCA62, 0xA553, 0xCA63, 0xA554, + 0xCA64, 0xA555, 0xCA65, 0xA556, 0xCA66, 0xA557, 0xCA67, 0xA558, + 0xCA68, 0xC2C5, 0xCA69, 0xA559, 0xCA6A, 0xA55A, 0xCA6B, 0xA561, + 0xCA6C, 0xA562, 0xCA6D, 0xA563, 0xCA6E, 0xA564, 0xCA6F, 0xA565, + 0xCA70, 0xA566, 0xCA71, 0xA567, 0xCA72, 0xA568, 0xCA73, 0xA569, + 0xCA74, 0xA56A, 0xCA75, 0xA56B, 0xCA76, 0xA56C, 0xCA77, 0xA56D, + 0xCA78, 0xA56E, 0xCA79, 0xA56F, 0xCA7A, 0xA570, 0xCA7B, 0xA571, + 0xCA7C, 0xA572, 0xCA7D, 0xC2C6, 0xCA7E, 0xA573, 0xCA7F, 0xA574, + 0xCA80, 0xA575, 0xCA81, 0xA576, 0xCA82, 0xA577, 0xCA83, 0xA578, + 0xCA84, 0xC2C7, 0xCA85, 0xA579, 0xCA86, 0xA57A, 0xCA87, 0xA581, + 0xCA88, 0xA582, 0xCA89, 0xA583, 0xCA8A, 0xA584, 0xCA8B, 0xA585, + 0xCA8C, 0xA586, 0xCA8D, 0xA587, 0xCA8E, 0xA588, 0xCA8F, 0xA589, + 0xCA90, 0xA58A, 0xCA91, 0xA58B, 0xCA92, 0xA58C, 0xCA93, 0xA58D, + 0xCA94, 0xA58E, 0xCA95, 0xA58F, 0xCA96, 0xA590, 0xCA97, 0xA591, + 0xCA98, 0xC2C8, 0xCA99, 0xA592, 0xCA9A, 0xA593, 0xCA9B, 0xA594, + 0xCA9C, 0xA595, 0xCA9D, 0xA596, 0xCA9E, 0xA597, 0xCA9F, 0xA598, + 0xCAA0, 0xA599, 0xCAA1, 0xA59A, 0xCAA2, 0xA59B, 0xCAA3, 0xA59C, + 0xCAA4, 0xA59D, 0xCAA5, 0xA59E, 0xCAA6, 0xA59F, 0xCAA7, 0xA5A0, + 0xCAA8, 0xA641, 0xCAA9, 0xA642, 0xCAAA, 0xA643, 0xCAAB, 0xA644, + 0xCAAC, 0xA645, 0xCAAD, 0xA646, 0xCAAE, 0xA647, 0xCAAF, 0xA648, + 0xCAB0, 0xA649, 0xCAB1, 0xA64A, 0xCAB2, 0xA64B, 0xCAB3, 0xA64C, + 0xCAB4, 0xA64D, 0xCAB5, 0xA64E, 0xCAB6, 0xA64F, 0xCAB7, 0xA650, + 0xCAB8, 0xA651, 0xCAB9, 0xA652, 0xCABA, 0xA653, 0xCABB, 0xA654, + 0xCABC, 0xC2C9, 0xCABD, 0xC2CA, 0xCABE, 0xA655, 0xCABF, 0xA656, + 0xCAC0, 0xC2CB, 0xCAC1, 0xA657, 0xCAC2, 0xA658, 0xCAC3, 0xA659, + 0xCAC4, 0xC2CC, 0xCAC5, 0xA65A, 0xCAC6, 0xA661, 0xCAC7, 0xA662, + 0xCAC8, 0xA663, 0xCAC9, 0xA664, 0xCACA, 0xA665, 0xCACB, 0xA666, + 0xCACC, 0xC2CD, 0xCACD, 0xC2CE, 0xCACE, 0xA667, 0xCACF, 0xC2CF, + 0xCAD0, 0xA668, 0xCAD1, 0xC2D0, 0xCAD2, 0xA669, 0xCAD3, 0xC2D1, + 0xCAD4, 0xA66A, 0xCAD5, 0xA66B, 0xCAD6, 0xA66C, 0xCAD7, 0xA66D, + 0xCAD8, 0xC2D2, 0xCAD9, 0xC2D3, 0xCADA, 0xA66E, 0xCADB, 0xA66F, + 0xCADC, 0xA670, 0xCADD, 0xA671, 0xCADE, 0xA672, 0xCADF, 0xA673, + 0xCAE0, 0xC2D4, 0xCAE1, 0xA674, 0xCAE2, 0xA675, 0xCAE3, 0xA676, + 0xCAE4, 0xA677, 0xCAE5, 0xA678, 0xCAE6, 0xA679, 0xCAE7, 0xA67A, + 0xCAE8, 0xA681, 0xCAE9, 0xA682, 0xCAEA, 0xA683, 0xCAEB, 0xA684, + 0xCAEC, 0xC2D5, 0xCAED, 0xA685, 0xCAEE, 0xA686, 0xCAEF, 0xA687, + 0xCAF0, 0xA688, 0xCAF1, 0xA689, 0xCAF2, 0xA68A, 0xCAF3, 0xA68B, + 0xCAF4, 0xC2D6, 0xCAF5, 0xA68C, 0xCAF6, 0xA68D, 0xCAF7, 0xA68E, + 0xCAF8, 0xA68F, 0xCAF9, 0xA690, 0xCAFA, 0xA691, 0xCAFB, 0xA692, + 0xCAFC, 0xA693, 0xCAFD, 0xA694, 0xCAFE, 0xA695, 0xCAFF, 0xA696, + 0xCB00, 0xA697, 0xCB01, 0xA698, 0xCB02, 0xA699, 0xCB03, 0xA69A, + 0xCB04, 0xA69B, 0xCB05, 0xA69C, 0xCB06, 0xA69D, 0xCB07, 0xA69E, + 0xCB08, 0xC2D7, 0xCB09, 0xA69F, 0xCB0A, 0xA6A0, 0xCB0B, 0xA741, + 0xCB0C, 0xA742, 0xCB0D, 0xA743, 0xCB0E, 0xA744, 0xCB0F, 0xA745, + 0xCB10, 0xC2D8, 0xCB11, 0xA746, 0xCB12, 0xA747, 0xCB13, 0xA748, + 0xCB14, 0xC2D9, 0xCB15, 0xA749, 0xCB16, 0xA74A, 0xCB17, 0xA74B, + 0xCB18, 0xC2DA, 0xCB19, 0xA74C, 0xCB1A, 0xA74D, 0xCB1B, 0xA74E, + 0xCB1C, 0xA74F, 0xCB1D, 0xA750, 0xCB1E, 0xA751, 0xCB1F, 0xA752, + 0xCB20, 0xC2DB, 0xCB21, 0xC2DC, 0xCB22, 0xA753, 0xCB23, 0xA754, + 0xCB24, 0xA755, 0xCB25, 0xA756, 0xCB26, 0xA757, 0xCB27, 0xA758, + 0xCB28, 0xA759, 0xCB29, 0xA75A, 0xCB2A, 0xA761, 0xCB2B, 0xA762, + 0xCB2C, 0xA763, 0xCB2D, 0xA764, 0xCB2E, 0xA765, 0xCB2F, 0xA766, + 0xCB30, 0xA767, 0xCB31, 0xA768, 0xCB32, 0xA769, 0xCB33, 0xA76A, + 0xCB34, 0xA76B, 0xCB35, 0xA76C, 0xCB36, 0xA76D, 0xCB37, 0xA76E, + 0xCB38, 0xA76F, 0xCB39, 0xA770, 0xCB3A, 0xA771, 0xCB3B, 0xA772, + 0xCB3C, 0xA773, 0xCB3D, 0xA774, 0xCB3E, 0xA775, 0xCB3F, 0xA776, + 0xCB40, 0xA777, 0xCB41, 0xC2DD, 0xCB42, 0xA778, 0xCB43, 0xA779, + 0xCB44, 0xA77A, 0xCB45, 0xA781, 0xCB46, 0xA782, 0xCB47, 0xA783, + 0xCB48, 0xC2DE, 0xCB49, 0xC2DF, 0xCB4A, 0xA784, 0xCB4B, 0xA785, + 0xCB4C, 0xC2E0, 0xCB4D, 0xA786, 0xCB4E, 0xA787, 0xCB4F, 0xA788, + 0xCB50, 0xC2E1, 0xCB51, 0xA789, 0xCB52, 0xA78A, 0xCB53, 0xA78B, + 0xCB54, 0xA78C, 0xCB55, 0xA78D, 0xCB56, 0xA78E, 0xCB57, 0xA78F, + 0xCB58, 0xC2E2, 0xCB59, 0xC2E3, 0xCB5A, 0xA790, 0xCB5B, 0xA791, + 0xCB5C, 0xA792, 0xCB5D, 0xC2E4, 0xCB5E, 0xA793, 0xCB5F, 0xA794, + 0xCB60, 0xA795, 0xCB61, 0xA796, 0xCB62, 0xA797, 0xCB63, 0xA798, + 0xCB64, 0xC2E5, 0xCB65, 0xA799, 0xCB66, 0xA79A, 0xCB67, 0xA79B, + 0xCB68, 0xA79C, 0xCB69, 0xA79D, 0xCB6A, 0xA79E, 0xCB6B, 0xA79F, + 0xCB6C, 0xA7A0, 0xCB6D, 0xA841, 0xCB6E, 0xA842, 0xCB6F, 0xA843, + 0xCB70, 0xA844, 0xCB71, 0xA845, 0xCB72, 0xA846, 0xCB73, 0xA847, + 0xCB74, 0xA848, 0xCB75, 0xA849, 0xCB76, 0xA84A, 0xCB77, 0xA84B, + 0xCB78, 0xC2E6, 0xCB79, 0xC2E7, 0xCB7A, 0xA84C, 0xCB7B, 0xA84D, + 0xCB7C, 0xA84E, 0xCB7D, 0xA84F, 0xCB7E, 0xA850, 0xCB7F, 0xA851, + 0xCB80, 0xA852, 0xCB81, 0xA853, 0xCB82, 0xA854, 0xCB83, 0xA855, + 0xCB84, 0xA856, 0xCB85, 0xA857, 0xCB86, 0xA858, 0xCB87, 0xA859, + 0xCB88, 0xA85A, 0xCB89, 0xA861, 0xCB8A, 0xA862, 0xCB8B, 0xA863, + 0xCB8C, 0xA864, 0xCB8D, 0xA865, 0xCB8E, 0xA866, 0xCB8F, 0xA867, + 0xCB90, 0xA868, 0xCB91, 0xA869, 0xCB92, 0xA86A, 0xCB93, 0xA86B, + 0xCB94, 0xA86C, 0xCB95, 0xA86D, 0xCB96, 0xA86E, 0xCB97, 0xA86F, + 0xCB98, 0xA870, 0xCB99, 0xA871, 0xCB9A, 0xA872, 0xCB9B, 0xA873, + 0xCB9C, 0xC2E8, 0xCB9D, 0xA874, 0xCB9E, 0xA875, 0xCB9F, 0xA876, + 0xCBA0, 0xA877, 0xCBA1, 0xA878, 0xCBA2, 0xA879, 0xCBA3, 0xA87A, + 0xCBA4, 0xA881, 0xCBA5, 0xA882, 0xCBA6, 0xA883, 0xCBA7, 0xA884, + 0xCBA8, 0xA885, 0xCBA9, 0xA886, 0xCBAA, 0xA887, 0xCBAB, 0xA888, + 0xCBAC, 0xA889, 0xCBAD, 0xA88A, 0xCBAE, 0xA88B, 0xCBAF, 0xA88C, + 0xCBB0, 0xA88D, 0xCBB1, 0xA88E, 0xCBB2, 0xA88F, 0xCBB3, 0xA890, + 0xCBB4, 0xA891, 0xCBB5, 0xA892, 0xCBB6, 0xA893, 0xCBB7, 0xA894, + 0xCBB8, 0xC2E9, 0xCBB9, 0xA895, 0xCBBA, 0xA896, 0xCBBB, 0xA897, + 0xCBBC, 0xA898, 0xCBBD, 0xA899, 0xCBBE, 0xA89A, 0xCBBF, 0xA89B, + 0xCBC0, 0xA89C, 0xCBC1, 0xA89D, 0xCBC2, 0xA89E, 0xCBC3, 0xA89F, + 0xCBC4, 0xA8A0, 0xCBC5, 0xA941, 0xCBC6, 0xA942, 0xCBC7, 0xA943, + 0xCBC8, 0xA944, 0xCBC9, 0xA945, 0xCBCA, 0xA946, 0xCBCB, 0xA947, + 0xCBCC, 0xA948, 0xCBCD, 0xA949, 0xCBCE, 0xA94A, 0xCBCF, 0xA94B, + 0xCBD0, 0xA94C, 0xCBD1, 0xA94D, 0xCBD2, 0xA94E, 0xCBD3, 0xA94F, + 0xCBD4, 0xC2EA, 0xCBD5, 0xA950, 0xCBD6, 0xA951, 0xCBD7, 0xA952, + 0xCBD8, 0xA953, 0xCBD9, 0xA954, 0xCBDA, 0xA955, 0xCBDB, 0xA956, + 0xCBDC, 0xA957, 0xCBDD, 0xA958, 0xCBDE, 0xA959, 0xCBDF, 0xA95A, + 0xCBE0, 0xA961, 0xCBE1, 0xA962, 0xCBE2, 0xA963, 0xCBE3, 0xA964, + 0xCBE4, 0xC2EB, 0xCBE5, 0xA965, 0xCBE6, 0xA966, 0xCBE7, 0xC2EC, + 0xCBE8, 0xA967, 0xCBE9, 0xC2ED, 0xCBEA, 0xA968, 0xCBEB, 0xA969, + 0xCBEC, 0xA96A, 0xCBED, 0xA96B, 0xCBEE, 0xA96C, 0xCBEF, 0xA96D, + 0xCBF0, 0xA96E, 0xCBF1, 0xA96F, 0xCBF2, 0xA970, 0xCBF3, 0xA971, + 0xCBF4, 0xA972, 0xCBF5, 0xA973, 0xCBF6, 0xA974, 0xCBF7, 0xA975, + 0xCBF8, 0xA976, 0xCBF9, 0xA977, 0xCBFA, 0xA978, 0xCBFB, 0xA979, + 0xCBFC, 0xA97A, 0xCBFD, 0xA981, 0xCBFE, 0xA982, 0xCBFF, 0xA983, + 0xCC00, 0xA984, 0xCC01, 0xA985, 0xCC02, 0xA986, 0xCC03, 0xA987, + 0xCC04, 0xA988, 0xCC05, 0xA989, 0xCC06, 0xA98A, 0xCC07, 0xA98B, + 0xCC08, 0xA98C, 0xCC09, 0xA98D, 0xCC0A, 0xA98E, 0xCC0B, 0xA98F, + 0xCC0C, 0xC2EE, 0xCC0D, 0xC2EF, 0xCC0E, 0xA990, 0xCC0F, 0xA991, + 0xCC10, 0xC2F0, 0xCC11, 0xA992, 0xCC12, 0xA993, 0xCC13, 0xA994, + 0xCC14, 0xC2F1, 0xCC15, 0xA995, 0xCC16, 0xA996, 0xCC17, 0xA997, + 0xCC18, 0xA998, 0xCC19, 0xA999, 0xCC1A, 0xA99A, 0xCC1B, 0xA99B, + 0xCC1C, 0xC2F2, 0xCC1D, 0xC2F3, 0xCC1E, 0xA99C, 0xCC1F, 0xA99D, + 0xCC20, 0xA99E, 0xCC21, 0xC2F4, 0xCC22, 0xC2F5, 0xCC23, 0xA99F, + 0xCC24, 0xA9A0, 0xCC25, 0xAA41, 0xCC26, 0xAA42, 0xCC27, 0xC2F6, + 0xCC28, 0xC2F7, 0xCC29, 0xC2F8, 0xCC2A, 0xAA43, 0xCC2B, 0xAA44, + 0xCC2C, 0xC2F9, 0xCC2D, 0xAA45, 0xCC2E, 0xC2FA, 0xCC2F, 0xAA46, + 0xCC30, 0xC2FB, 0xCC31, 0xAA47, 0xCC32, 0xAA48, 0xCC33, 0xAA49, + 0xCC34, 0xAA4A, 0xCC35, 0xAA4B, 0xCC36, 0xAA4C, 0xCC37, 0xAA4D, + 0xCC38, 0xC2FC, 0xCC39, 0xC2FD, 0xCC3A, 0xAA4E, 0xCC3B, 0xC2FE, + 0xCC3C, 0xC3A1, 0xCC3D, 0xC3A2, 0xCC3E, 0xC3A3, 0xCC3F, 0xAA4F, + 0xCC40, 0xAA50, 0xCC41, 0xAA51, 0xCC42, 0xAA52, 0xCC43, 0xAA53, + 0xCC44, 0xC3A4, 0xCC45, 0xC3A5, 0xCC46, 0xAA54, 0xCC47, 0xAA55, + 0xCC48, 0xC3A6, 0xCC49, 0xAA56, 0xCC4A, 0xAA57, 0xCC4B, 0xAA58, + 0xCC4C, 0xC3A7, 0xCC4D, 0xAA59, 0xCC4E, 0xAA5A, 0xCC4F, 0xAA61, + 0xCC50, 0xAA62, 0xCC51, 0xAA63, 0xCC52, 0xAA64, 0xCC53, 0xAA65, + 0xCC54, 0xC3A8, 0xCC55, 0xC3A9, 0xCC56, 0xAA66, 0xCC57, 0xC3AA, + 0xCC58, 0xC3AB, 0xCC59, 0xC3AC, 0xCC5A, 0xAA67, 0xCC5B, 0xAA68, + 0xCC5C, 0xAA69, 0xCC5D, 0xAA6A, 0xCC5E, 0xAA6B, 0xCC5F, 0xAA6C, + 0xCC60, 0xC3AD, 0xCC61, 0xAA6D, 0xCC62, 0xAA6E, 0xCC63, 0xAA6F, + 0xCC64, 0xC3AE, 0xCC65, 0xAA70, 0xCC66, 0xC3AF, 0xCC67, 0xAA71, + 0xCC68, 0xC3B0, 0xCC69, 0xAA72, 0xCC6A, 0xAA73, 0xCC6B, 0xAA74, + 0xCC6C, 0xAA75, 0xCC6D, 0xAA76, 0xCC6E, 0xAA77, 0xCC6F, 0xAA78, + 0xCC70, 0xC3B1, 0xCC71, 0xAA79, 0xCC72, 0xAA7A, 0xCC73, 0xAA81, + 0xCC74, 0xAA82, 0xCC75, 0xC3B2, 0xCC76, 0xAA83, 0xCC77, 0xAA84, + 0xCC78, 0xAA85, 0xCC79, 0xAA86, 0xCC7A, 0xAA87, 0xCC7B, 0xAA88, + 0xCC7C, 0xAA89, 0xCC7D, 0xAA8A, 0xCC7E, 0xAA8B, 0xCC7F, 0xAA8C, + 0xCC80, 0xAA8D, 0xCC81, 0xAA8E, 0xCC82, 0xAA8F, 0xCC83, 0xAA90, + 0xCC84, 0xAA91, 0xCC85, 0xAA92, 0xCC86, 0xAA93, 0xCC87, 0xAA94, + 0xCC88, 0xAA95, 0xCC89, 0xAA96, 0xCC8A, 0xAA97, 0xCC8B, 0xAA98, + 0xCC8C, 0xAA99, 0xCC8D, 0xAA9A, 0xCC8E, 0xAA9B, 0xCC8F, 0xAA9C, + 0xCC90, 0xAA9D, 0xCC91, 0xAA9E, 0xCC92, 0xAA9F, 0xCC93, 0xAAA0, + 0xCC94, 0xAB41, 0xCC95, 0xAB42, 0xCC96, 0xAB43, 0xCC97, 0xAB44, + 0xCC98, 0xC3B3, 0xCC99, 0xC3B4, 0xCC9A, 0xAB45, 0xCC9B, 0xAB46, + 0xCC9C, 0xC3B5, 0xCC9D, 0xAB47, 0xCC9E, 0xAB48, 0xCC9F, 0xAB49, + 0xCCA0, 0xC3B6, 0xCCA1, 0xAB4A, 0xCCA2, 0xAB4B, 0xCCA3, 0xAB4C, + 0xCCA4, 0xAB4D, 0xCCA5, 0xAB4E, 0xCCA6, 0xAB4F, 0xCCA7, 0xAB50, + 0xCCA8, 0xC3B7, 0xCCA9, 0xC3B8, 0xCCAA, 0xAB51, 0xCCAB, 0xC3B9, + 0xCCAC, 0xC3BA, 0xCCAD, 0xC3BB, 0xCCAE, 0xAB52, 0xCCAF, 0xAB53, + 0xCCB0, 0xAB54, 0xCCB1, 0xAB55, 0xCCB2, 0xAB56, 0xCCB3, 0xAB57, + 0xCCB4, 0xC3BC, 0xCCB5, 0xC3BD, 0xCCB6, 0xAB58, 0xCCB7, 0xAB59, + 0xCCB8, 0xC3BE, 0xCCB9, 0xAB5A, 0xCCBA, 0xAB61, 0xCCBB, 0xAB62, + 0xCCBC, 0xC3BF, 0xCCBD, 0xAB63, 0xCCBE, 0xAB64, 0xCCBF, 0xAB65, + 0xCCC0, 0xAB66, 0xCCC1, 0xAB67, 0xCCC2, 0xAB68, 0xCCC3, 0xAB69, + 0xCCC4, 0xC3C0, 0xCCC5, 0xC3C1, 0xCCC6, 0xAB6A, 0xCCC7, 0xC3C2, + 0xCCC8, 0xAB6B, 0xCCC9, 0xC3C3, 0xCCCA, 0xAB6C, 0xCCCB, 0xAB6D, + 0xCCCC, 0xAB6E, 0xCCCD, 0xAB6F, 0xCCCE, 0xAB70, 0xCCCF, 0xAB71, + 0xCCD0, 0xC3C4, 0xCCD1, 0xAB72, 0xCCD2, 0xAB73, 0xCCD3, 0xAB74, + 0xCCD4, 0xC3C5, 0xCCD5, 0xAB75, 0xCCD6, 0xAB76, 0xCCD7, 0xAB77, + 0xCCD8, 0xAB78, 0xCCD9, 0xAB79, 0xCCDA, 0xAB7A, 0xCCDB, 0xAB81, + 0xCCDC, 0xAB82, 0xCCDD, 0xAB83, 0xCCDE, 0xAB84, 0xCCDF, 0xAB85, + 0xCCE0, 0xAB86, 0xCCE1, 0xAB87, 0xCCE2, 0xAB88, 0xCCE3, 0xAB89, + 0xCCE4, 0xC3C6, 0xCCE5, 0xAB8A, 0xCCE6, 0xAB8B, 0xCCE7, 0xAB8C, + 0xCCE8, 0xAB8D, 0xCCE9, 0xAB8E, 0xCCEA, 0xAB8F, 0xCCEB, 0xAB90, + 0xCCEC, 0xC3C7, 0xCCED, 0xAB91, 0xCCEE, 0xAB92, 0xCCEF, 0xAB93, + 0xCCF0, 0xC3C8, 0xCCF1, 0xAB94, 0xCCF2, 0xAB95, 0xCCF3, 0xAB96, + 0xCCF4, 0xAB97, 0xCCF5, 0xAB98, 0xCCF6, 0xAB99, 0xCCF7, 0xAB9A, + 0xCCF8, 0xAB9B, 0xCCF9, 0xAB9C, 0xCCFA, 0xAB9D, 0xCCFB, 0xAB9E, + 0xCCFC, 0xAB9F, 0xCCFD, 0xABA0, 0xCCFE, 0xAC41, 0xCCFF, 0xAC42, + 0xCD00, 0xAC43, 0xCD01, 0xC3C9, 0xCD02, 0xAC44, 0xCD03, 0xAC45, + 0xCD04, 0xAC46, 0xCD05, 0xAC47, 0xCD06, 0xAC48, 0xCD07, 0xAC49, + 0xCD08, 0xC3CA, 0xCD09, 0xC3CB, 0xCD0A, 0xAC4A, 0xCD0B, 0xAC4B, + 0xCD0C, 0xC3CC, 0xCD0D, 0xAC4C, 0xCD0E, 0xAC4D, 0xCD0F, 0xAC4E, + 0xCD10, 0xC3CD, 0xCD11, 0xAC4F, 0xCD12, 0xAC50, 0xCD13, 0xAC51, + 0xCD14, 0xAC52, 0xCD15, 0xAC53, 0xCD16, 0xAC54, 0xCD17, 0xAC55, + 0xCD18, 0xC3CE, 0xCD19, 0xC3CF, 0xCD1A, 0xAC56, 0xCD1B, 0xC3D0, + 0xCD1C, 0xAC57, 0xCD1D, 0xC3D1, 0xCD1E, 0xAC58, 0xCD1F, 0xAC59, + 0xCD20, 0xAC5A, 0xCD21, 0xAC61, 0xCD22, 0xAC62, 0xCD23, 0xAC63, + 0xCD24, 0xC3D2, 0xCD25, 0xAC64, 0xCD26, 0xAC65, 0xCD27, 0xAC66, + 0xCD28, 0xC3D3, 0xCD29, 0xAC67, 0xCD2A, 0xAC68, 0xCD2B, 0xAC69, + 0xCD2C, 0xC3D4, 0xCD2D, 0xAC6A, 0xCD2E, 0xAC6B, 0xCD2F, 0xAC6C, + 0xCD30, 0xAC6D, 0xCD31, 0xAC6E, 0xCD32, 0xAC6F, 0xCD33, 0xAC70, + 0xCD34, 0xAC71, 0xCD35, 0xAC72, 0xCD36, 0xAC73, 0xCD37, 0xAC74, + 0xCD38, 0xAC75, 0xCD39, 0xC3D5, 0xCD3A, 0xAC76, 0xCD3B, 0xAC77, + 0xCD3C, 0xAC78, 0xCD3D, 0xAC79, 0xCD3E, 0xAC7A, 0xCD3F, 0xAC81, + 0xCD40, 0xAC82, 0xCD41, 0xAC83, 0xCD42, 0xAC84, 0xCD43, 0xAC85, + 0xCD44, 0xAC86, 0xCD45, 0xAC87, 0xCD46, 0xAC88, 0xCD47, 0xAC89, + 0xCD48, 0xAC8A, 0xCD49, 0xAC8B, 0xCD4A, 0xAC8C, 0xCD4B, 0xAC8D, + 0xCD4C, 0xAC8E, 0xCD4D, 0xAC8F, 0xCD4E, 0xAC90, 0xCD4F, 0xAC91, + 0xCD50, 0xAC92, 0xCD51, 0xAC93, 0xCD52, 0xAC94, 0xCD53, 0xAC95, + 0xCD54, 0xAC96, 0xCD55, 0xAC97, 0xCD56, 0xAC98, 0xCD57, 0xAC99, + 0xCD58, 0xAC9A, 0xCD59, 0xAC9B, 0xCD5A, 0xAC9C, 0xCD5B, 0xAC9D, + 0xCD5C, 0xC3D6, 0xCD5D, 0xAC9E, 0xCD5E, 0xAC9F, 0xCD5F, 0xACA0, + 0xCD60, 0xC3D7, 0xCD61, 0xAD41, 0xCD62, 0xAD42, 0xCD63, 0xAD43, + 0xCD64, 0xC3D8, 0xCD65, 0xAD44, 0xCD66, 0xAD45, 0xCD67, 0xAD46, + 0xCD68, 0xAD47, 0xCD69, 0xAD48, 0xCD6A, 0xAD49, 0xCD6B, 0xAD4A, + 0xCD6C, 0xC3D9, 0xCD6D, 0xC3DA, 0xCD6E, 0xAD4B, 0xCD6F, 0xC3DB, + 0xCD70, 0xAD4C, 0xCD71, 0xC3DC, 0xCD72, 0xAD4D, 0xCD73, 0xAD4E, + 0xCD74, 0xAD4F, 0xCD75, 0xAD50, 0xCD76, 0xAD51, 0xCD77, 0xAD52, + 0xCD78, 0xC3DD, 0xCD79, 0xAD53, 0xCD7A, 0xAD54, 0xCD7B, 0xAD55, + 0xCD7C, 0xAD56, 0xCD7D, 0xAD57, 0xCD7E, 0xAD58, 0xCD7F, 0xAD59, + 0xCD80, 0xAD5A, 0xCD81, 0xAD61, 0xCD82, 0xAD62, 0xCD83, 0xAD63, + 0xCD84, 0xAD64, 0xCD85, 0xAD65, 0xCD86, 0xAD66, 0xCD87, 0xAD67, + 0xCD88, 0xC3DE, 0xCD89, 0xAD68, 0xCD8A, 0xAD69, 0xCD8B, 0xAD6A, + 0xCD8C, 0xAD6B, 0xCD8D, 0xAD6C, 0xCD8E, 0xAD6D, 0xCD8F, 0xAD6E, + 0xCD90, 0xAD6F, 0xCD91, 0xAD70, 0xCD92, 0xAD71, 0xCD93, 0xAD72, + 0xCD94, 0xC3DF, 0xCD95, 0xC3E0, 0xCD96, 0xAD73, 0xCD97, 0xAD74, + 0xCD98, 0xC3E1, 0xCD99, 0xAD75, 0xCD9A, 0xAD76, 0xCD9B, 0xAD77, + 0xCD9C, 0xC3E2, 0xCD9D, 0xAD78, 0xCD9E, 0xAD79, 0xCD9F, 0xAD7A, + 0xCDA0, 0xAD81, 0xCDA1, 0xAD82, 0xCDA2, 0xAD83, 0xCDA3, 0xAD84, + 0xCDA4, 0xC3E3, 0xCDA5, 0xC3E4, 0xCDA6, 0xAD85, 0xCDA7, 0xC3E5, + 0xCDA8, 0xAD86, 0xCDA9, 0xC3E6, 0xCDAA, 0xAD87, 0xCDAB, 0xAD88, + 0xCDAC, 0xAD89, 0xCDAD, 0xAD8A, 0xCDAE, 0xAD8B, 0xCDAF, 0xAD8C, + 0xCDB0, 0xC3E7, 0xCDB1, 0xAD8D, 0xCDB2, 0xAD8E, 0xCDB3, 0xAD8F, + 0xCDB4, 0xAD90, 0xCDB5, 0xAD91, 0xCDB6, 0xAD92, 0xCDB7, 0xAD93, + 0xCDB8, 0xAD94, 0xCDB9, 0xAD95, 0xCDBA, 0xAD96, 0xCDBB, 0xAD97, + 0xCDBC, 0xAD98, 0xCDBD, 0xAD99, 0xCDBE, 0xAD9A, 0xCDBF, 0xAD9B, + 0xCDC0, 0xAD9C, 0xCDC1, 0xAD9D, 0xCDC2, 0xAD9E, 0xCDC3, 0xAD9F, + 0xCDC4, 0xC3E8, 0xCDC5, 0xADA0, 0xCDC6, 0xAE41, 0xCDC7, 0xAE42, + 0xCDC8, 0xAE43, 0xCDC9, 0xAE44, 0xCDCA, 0xAE45, 0xCDCB, 0xAE46, + 0xCDCC, 0xC3E9, 0xCDCD, 0xAE47, 0xCDCE, 0xAE48, 0xCDCF, 0xAE49, + 0xCDD0, 0xC3EA, 0xCDD1, 0xAE4A, 0xCDD2, 0xAE4B, 0xCDD3, 0xAE4C, + 0xCDD4, 0xAE4D, 0xCDD5, 0xAE4E, 0xCDD6, 0xAE4F, 0xCDD7, 0xAE50, + 0xCDD8, 0xAE51, 0xCDD9, 0xAE52, 0xCDDA, 0xAE53, 0xCDDB, 0xAE54, + 0xCDDC, 0xAE55, 0xCDDD, 0xAE56, 0xCDDE, 0xAE57, 0xCDDF, 0xAE58, + 0xCDE0, 0xAE59, 0xCDE1, 0xAE5A, 0xCDE2, 0xAE61, 0xCDE3, 0xAE62, + 0xCDE4, 0xAE63, 0xCDE5, 0xAE64, 0xCDE6, 0xAE65, 0xCDE7, 0xAE66, + 0xCDE8, 0xC3EB, 0xCDE9, 0xAE67, 0xCDEA, 0xAE68, 0xCDEB, 0xAE69, + 0xCDEC, 0xC3EC, 0xCDED, 0xAE6A, 0xCDEE, 0xAE6B, 0xCDEF, 0xAE6C, + 0xCDF0, 0xC3ED, 0xCDF1, 0xAE6D, 0xCDF2, 0xAE6E, 0xCDF3, 0xAE6F, + 0xCDF4, 0xAE70, 0xCDF5, 0xAE71, 0xCDF6, 0xAE72, 0xCDF7, 0xAE73, + 0xCDF8, 0xC3EE, 0xCDF9, 0xC3EF, 0xCDFA, 0xAE74, 0xCDFB, 0xC3F0, + 0xCDFC, 0xAE75, 0xCDFD, 0xC3F1, 0xCDFE, 0xAE76, 0xCDFF, 0xAE77, + 0xCE00, 0xAE78, 0xCE01, 0xAE79, 0xCE02, 0xAE7A, 0xCE03, 0xAE81, + 0xCE04, 0xC3F2, 0xCE05, 0xAE82, 0xCE06, 0xAE83, 0xCE07, 0xAE84, + 0xCE08, 0xC3F3, 0xCE09, 0xAE85, 0xCE0A, 0xAE86, 0xCE0B, 0xAE87, + 0xCE0C, 0xC3F4, 0xCE0D, 0xAE88, 0xCE0E, 0xAE89, 0xCE0F, 0xAE8A, + 0xCE10, 0xAE8B, 0xCE11, 0xAE8C, 0xCE12, 0xAE8D, 0xCE13, 0xAE8E, + 0xCE14, 0xC3F5, 0xCE15, 0xAE8F, 0xCE16, 0xAE90, 0xCE17, 0xAE91, + 0xCE18, 0xAE92, 0xCE19, 0xC3F6, 0xCE1A, 0xAE93, 0xCE1B, 0xAE94, + 0xCE1C, 0xAE95, 0xCE1D, 0xAE96, 0xCE1E, 0xAE97, 0xCE1F, 0xAE98, + 0xCE20, 0xC3F7, 0xCE21, 0xC3F8, 0xCE22, 0xAE99, 0xCE23, 0xAE9A, + 0xCE24, 0xC3F9, 0xCE25, 0xAE9B, 0xCE26, 0xAE9C, 0xCE27, 0xAE9D, + 0xCE28, 0xC3FA, 0xCE29, 0xAE9E, 0xCE2A, 0xAE9F, 0xCE2B, 0xAEA0, + 0xCE2C, 0xAF41, 0xCE2D, 0xAF42, 0xCE2E, 0xAF43, 0xCE2F, 0xAF44, + 0xCE30, 0xC3FB, 0xCE31, 0xC3FC, 0xCE32, 0xAF45, 0xCE33, 0xC3FD, + 0xCE34, 0xAF46, 0xCE35, 0xC3FE, 0xCE36, 0xAF47, 0xCE37, 0xAF48, + 0xCE38, 0xAF49, 0xCE39, 0xAF4A, 0xCE3A, 0xAF4B, 0xCE3B, 0xAF4C, + 0xCE3C, 0xAF4D, 0xCE3D, 0xAF4E, 0xCE3E, 0xAF4F, 0xCE3F, 0xAF50, + 0xCE40, 0xAF51, 0xCE41, 0xAF52, 0xCE42, 0xAF53, 0xCE43, 0xAF54, + 0xCE44, 0xAF55, 0xCE45, 0xAF56, 0xCE46, 0xAF57, 0xCE47, 0xAF58, + 0xCE48, 0xAF59, 0xCE49, 0xAF5A, 0xCE4A, 0xAF61, 0xCE4B, 0xAF62, + 0xCE4C, 0xAF63, 0xCE4D, 0xAF64, 0xCE4E, 0xAF65, 0xCE4F, 0xAF66, + 0xCE50, 0xAF67, 0xCE51, 0xAF68, 0xCE52, 0xAF69, 0xCE53, 0xAF6A, + 0xCE54, 0xAF6B, 0xCE55, 0xAF6C, 0xCE56, 0xAF6D, 0xCE57, 0xAF6E, + 0xCE58, 0xC4A1, 0xCE59, 0xC4A2, 0xCE5A, 0xAF6F, 0xCE5B, 0xAF70, + 0xCE5C, 0xC4A3, 0xCE5D, 0xAF71, 0xCE5E, 0xAF72, 0xCE5F, 0xC4A4, + 0xCE60, 0xC4A5, 0xCE61, 0xC4A6, 0xCE62, 0xAF73, 0xCE63, 0xAF74, + 0xCE64, 0xAF75, 0xCE65, 0xAF76, 0xCE66, 0xAF77, 0xCE67, 0xAF78, + 0xCE68, 0xC4A7, 0xCE69, 0xC4A8, 0xCE6A, 0xAF79, 0xCE6B, 0xC4A9, + 0xCE6C, 0xAF7A, 0xCE6D, 0xC4AA, 0xCE6E, 0xAF81, 0xCE6F, 0xAF82, + 0xCE70, 0xAF83, 0xCE71, 0xAF84, 0xCE72, 0xAF85, 0xCE73, 0xAF86, + 0xCE74, 0xC4AB, 0xCE75, 0xC4AC, 0xCE76, 0xAF87, 0xCE77, 0xAF88, + 0xCE78, 0xC4AD, 0xCE79, 0xAF89, 0xCE7A, 0xAF8A, 0xCE7B, 0xAF8B, + 0xCE7C, 0xC4AE, 0xCE7D, 0xAF8C, 0xCE7E, 0xAF8D, 0xCE7F, 0xAF8E, + 0xCE80, 0xAF8F, 0xCE81, 0xAF90, 0xCE82, 0xAF91, 0xCE83, 0xAF92, + 0xCE84, 0xC4AF, 0xCE85, 0xC4B0, 0xCE86, 0xAF93, 0xCE87, 0xC4B1, + 0xCE88, 0xAF94, 0xCE89, 0xC4B2, 0xCE8A, 0xAF95, 0xCE8B, 0xAF96, + 0xCE8C, 0xAF97, 0xCE8D, 0xAF98, 0xCE8E, 0xAF99, 0xCE8F, 0xAF9A, + 0xCE90, 0xC4B3, 0xCE91, 0xC4B4, 0xCE92, 0xAF9B, 0xCE93, 0xAF9C, + 0xCE94, 0xC4B5, 0xCE95, 0xAF9D, 0xCE96, 0xAF9E, 0xCE97, 0xAF9F, + 0xCE98, 0xC4B6, 0xCE99, 0xAFA0, 0xCE9A, 0xB041, 0xCE9B, 0xB042, + 0xCE9C, 0xB043, 0xCE9D, 0xB044, 0xCE9E, 0xB045, 0xCE9F, 0xB046, + 0xCEA0, 0xC4B7, 0xCEA1, 0xC4B8, 0xCEA2, 0xB047, 0xCEA3, 0xC4B9, + 0xCEA4, 0xC4BA, 0xCEA5, 0xC4BB, 0xCEA6, 0xB048, 0xCEA7, 0xB049, + 0xCEA8, 0xB04A, 0xCEA9, 0xB04B, 0xCEAA, 0xB04C, 0xCEAB, 0xB04D, + 0xCEAC, 0xC4BC, 0xCEAD, 0xC4BD, 0xCEAE, 0xB04E, 0xCEAF, 0xB04F, + 0xCEB0, 0xB050, 0xCEB1, 0xB051, 0xCEB2, 0xB052, 0xCEB3, 0xB053, + 0xCEB4, 0xB054, 0xCEB5, 0xB055, 0xCEB6, 0xB056, 0xCEB7, 0xB057, + 0xCEB8, 0xB058, 0xCEB9, 0xB059, 0xCEBA, 0xB05A, 0xCEBB, 0xB061, + 0xCEBC, 0xB062, 0xCEBD, 0xB063, 0xCEBE, 0xB064, 0xCEBF, 0xB065, + 0xCEC0, 0xB066, 0xCEC1, 0xC4BE, 0xCEC2, 0xB067, 0xCEC3, 0xB068, + 0xCEC4, 0xB069, 0xCEC5, 0xB06A, 0xCEC6, 0xB06B, 0xCEC7, 0xB06C, + 0xCEC8, 0xB06D, 0xCEC9, 0xB06E, 0xCECA, 0xB06F, 0xCECB, 0xB070, + 0xCECC, 0xB071, 0xCECD, 0xB072, 0xCECE, 0xB073, 0xCECF, 0xB074, + 0xCED0, 0xB075, 0xCED1, 0xB076, 0xCED2, 0xB077, 0xCED3, 0xB078, + 0xCED4, 0xB079, 0xCED5, 0xB07A, 0xCED6, 0xB081, 0xCED7, 0xB082, + 0xCED8, 0xB083, 0xCED9, 0xB084, 0xCEDA, 0xB085, 0xCEDB, 0xB086, + 0xCEDC, 0xB087, 0xCEDD, 0xB088, 0xCEDE, 0xB089, 0xCEDF, 0xB08A, + 0xCEE0, 0xB08B, 0xCEE1, 0xB08C, 0xCEE2, 0xB08D, 0xCEE3, 0xB08E, + 0xCEE4, 0xC4BF, 0xCEE5, 0xC4C0, 0xCEE6, 0xB08F, 0xCEE7, 0xB090, + 0xCEE8, 0xC4C1, 0xCEE9, 0xB091, 0xCEEA, 0xB092, 0xCEEB, 0xC4C2, + 0xCEEC, 0xC4C3, 0xCEED, 0xB093, 0xCEEE, 0xB094, 0xCEEF, 0xB095, + 0xCEF0, 0xB096, 0xCEF1, 0xB097, 0xCEF2, 0xB098, 0xCEF3, 0xB099, + 0xCEF4, 0xC4C4, 0xCEF5, 0xC4C5, 0xCEF6, 0xB09A, 0xCEF7, 0xC4C6, + 0xCEF8, 0xC4C7, 0xCEF9, 0xC4C8, 0xCEFA, 0xB09B, 0xCEFB, 0xB09C, + 0xCEFC, 0xB09D, 0xCEFD, 0xB09E, 0xCEFE, 0xB09F, 0xCEFF, 0xB0A0, + 0xCF00, 0xC4C9, 0xCF01, 0xC4CA, 0xCF02, 0xB141, 0xCF03, 0xB142, + 0xCF04, 0xC4CB, 0xCF05, 0xB143, 0xCF06, 0xB144, 0xCF07, 0xB145, + 0xCF08, 0xC4CC, 0xCF09, 0xB146, 0xCF0A, 0xB147, 0xCF0B, 0xB148, + 0xCF0C, 0xB149, 0xCF0D, 0xB14A, 0xCF0E, 0xB14B, 0xCF0F, 0xB14C, + 0xCF10, 0xC4CD, 0xCF11, 0xC4CE, 0xCF12, 0xB14D, 0xCF13, 0xC4CF, + 0xCF14, 0xB14E, 0xCF15, 0xC4D0, 0xCF16, 0xB14F, 0xCF17, 0xB150, + 0xCF18, 0xB151, 0xCF19, 0xB152, 0xCF1A, 0xB153, 0xCF1B, 0xB154, + 0xCF1C, 0xC4D1, 0xCF1D, 0xB155, 0xCF1E, 0xB156, 0xCF1F, 0xB157, + 0xCF20, 0xC4D2, 0xCF21, 0xB158, 0xCF22, 0xB159, 0xCF23, 0xB15A, + 0xCF24, 0xC4D3, 0xCF25, 0xB161, 0xCF26, 0xB162, 0xCF27, 0xB163, + 0xCF28, 0xB164, 0xCF29, 0xB165, 0xCF2A, 0xB166, 0xCF2B, 0xB167, + 0xCF2C, 0xC4D4, 0xCF2D, 0xC4D5, 0xCF2E, 0xB168, 0xCF2F, 0xC4D6, + 0xCF30, 0xC4D7, 0xCF31, 0xC4D8, 0xCF32, 0xB169, 0xCF33, 0xB16A, + 0xCF34, 0xB16B, 0xCF35, 0xB16C, 0xCF36, 0xB16D, 0xCF37, 0xB16E, + 0xCF38, 0xC4D9, 0xCF39, 0xB16F, 0xCF3A, 0xB170, 0xCF3B, 0xB171, + 0xCF3C, 0xB172, 0xCF3D, 0xB173, 0xCF3E, 0xB174, 0xCF3F, 0xB175, + 0xCF40, 0xB176, 0xCF41, 0xB177, 0xCF42, 0xB178, 0xCF43, 0xB179, + 0xCF44, 0xB17A, 0xCF45, 0xB181, 0xCF46, 0xB182, 0xCF47, 0xB183, + 0xCF48, 0xB184, 0xCF49, 0xB185, 0xCF4A, 0xB186, 0xCF4B, 0xB187, + 0xCF4C, 0xB188, 0xCF4D, 0xB189, 0xCF4E, 0xB18A, 0xCF4F, 0xB18B, + 0xCF50, 0xB18C, 0xCF51, 0xB18D, 0xCF52, 0xB18E, 0xCF53, 0xB18F, + 0xCF54, 0xC4DA, 0xCF55, 0xC4DB, 0xCF56, 0xB190, 0xCF57, 0xB191, + 0xCF58, 0xC4DC, 0xCF59, 0xB192, 0xCF5A, 0xB193, 0xCF5B, 0xB194, + 0xCF5C, 0xC4DD, 0xCF5D, 0xB195, 0xCF5E, 0xB196, 0xCF5F, 0xB197, + 0xCF60, 0xB198, 0xCF61, 0xB199, 0xCF62, 0xB19A, 0xCF63, 0xB19B, + 0xCF64, 0xC4DE, 0xCF65, 0xC4DF, 0xCF66, 0xB19C, 0xCF67, 0xC4E0, + 0xCF68, 0xB19D, 0xCF69, 0xC4E1, 0xCF6A, 0xB19E, 0xCF6B, 0xB19F, + 0xCF6C, 0xB1A0, 0xCF6D, 0xB241, 0xCF6E, 0xB242, 0xCF6F, 0xB243, + 0xCF70, 0xC4E2, 0xCF71, 0xC4E3, 0xCF72, 0xB244, 0xCF73, 0xB245, + 0xCF74, 0xC4E4, 0xCF75, 0xB246, 0xCF76, 0xB247, 0xCF77, 0xB248, + 0xCF78, 0xC4E5, 0xCF79, 0xB249, 0xCF7A, 0xB24A, 0xCF7B, 0xB24B, + 0xCF7C, 0xB24C, 0xCF7D, 0xB24D, 0xCF7E, 0xB24E, 0xCF7F, 0xB24F, + 0xCF80, 0xC4E6, 0xCF81, 0xB250, 0xCF82, 0xB251, 0xCF83, 0xB252, + 0xCF84, 0xB253, 0xCF85, 0xC4E7, 0xCF86, 0xB254, 0xCF87, 0xB255, + 0xCF88, 0xB256, 0xCF89, 0xB257, 0xCF8A, 0xB258, 0xCF8B, 0xB259, + 0xCF8C, 0xC4E8, 0xCF8D, 0xB25A, 0xCF8E, 0xB261, 0xCF8F, 0xB262, + 0xCF90, 0xB263, 0xCF91, 0xB264, 0xCF92, 0xB265, 0xCF93, 0xB266, + 0xCF94, 0xB267, 0xCF95, 0xB268, 0xCF96, 0xB269, 0xCF97, 0xB26A, + 0xCF98, 0xB26B, 0xCF99, 0xB26C, 0xCF9A, 0xB26D, 0xCF9B, 0xB26E, + 0xCF9C, 0xB26F, 0xCF9D, 0xB270, 0xCF9E, 0xB271, 0xCF9F, 0xB272, + 0xCFA0, 0xB273, 0xCFA1, 0xC4E9, 0xCFA2, 0xB274, 0xCFA3, 0xB275, + 0xCFA4, 0xB276, 0xCFA5, 0xB277, 0xCFA6, 0xB278, 0xCFA7, 0xB279, + 0xCFA8, 0xC4EA, 0xCFA9, 0xB27A, 0xCFAA, 0xB281, 0xCFAB, 0xB282, + 0xCFAC, 0xB283, 0xCFAD, 0xB284, 0xCFAE, 0xB285, 0xCFAF, 0xB286, + 0xCFB0, 0xC4EB, 0xCFB1, 0xB287, 0xCFB2, 0xB288, 0xCFB3, 0xB289, + 0xCFB4, 0xB28A, 0xCFB5, 0xB28B, 0xCFB6, 0xB28C, 0xCFB7, 0xB28D, + 0xCFB8, 0xB28E, 0xCFB9, 0xB28F, 0xCFBA, 0xB290, 0xCFBB, 0xB291, + 0xCFBC, 0xB292, 0xCFBD, 0xB293, 0xCFBE, 0xB294, 0xCFBF, 0xB295, + 0xCFC0, 0xB296, 0xCFC1, 0xB297, 0xCFC2, 0xB298, 0xCFC3, 0xB299, + 0xCFC4, 0xC4EC, 0xCFC5, 0xB29A, 0xCFC6, 0xB29B, 0xCFC7, 0xB29C, + 0xCFC8, 0xB29D, 0xCFC9, 0xB29E, 0xCFCA, 0xB29F, 0xCFCB, 0xB2A0, + 0xCFCC, 0xB341, 0xCFCD, 0xB342, 0xCFCE, 0xB343, 0xCFCF, 0xB344, + 0xCFD0, 0xB345, 0xCFD1, 0xB346, 0xCFD2, 0xB347, 0xCFD3, 0xB348, + 0xCFD4, 0xB349, 0xCFD5, 0xB34A, 0xCFD6, 0xB34B, 0xCFD7, 0xB34C, + 0xCFD8, 0xB34D, 0xCFD9, 0xB34E, 0xCFDA, 0xB34F, 0xCFDB, 0xB350, + 0xCFDC, 0xB351, 0xCFDD, 0xB352, 0xCFDE, 0xB353, 0xCFDF, 0xB354, + 0xCFE0, 0xC4ED, 0xCFE1, 0xC4EE, 0xCFE2, 0xB355, 0xCFE3, 0xB356, + 0xCFE4, 0xC4EF, 0xCFE5, 0xB357, 0xCFE6, 0xB358, 0xCFE7, 0xB359, + 0xCFE8, 0xC4F0, 0xCFE9, 0xB35A, 0xCFEA, 0xB361, 0xCFEB, 0xB362, + 0xCFEC, 0xB363, 0xCFED, 0xB364, 0xCFEE, 0xB365, 0xCFEF, 0xB366, + 0xCFF0, 0xC4F1, 0xCFF1, 0xC4F2, 0xCFF2, 0xB367, 0xCFF3, 0xC4F3, + 0xCFF4, 0xB368, 0xCFF5, 0xC4F4, 0xCFF6, 0xB369, 0xCFF7, 0xB36A, + 0xCFF8, 0xB36B, 0xCFF9, 0xB36C, 0xCFFA, 0xB36D, 0xCFFB, 0xB36E, + 0xCFFC, 0xC4F5, 0xCFFD, 0xB36F, 0xCFFE, 0xB370, 0xCFFF, 0xB371, + 0xD000, 0xC4F6, 0xD001, 0xB372, 0xD002, 0xB373, 0xD003, 0xB374, + 0xD004, 0xC4F7, 0xD005, 0xB375, 0xD006, 0xB376, 0xD007, 0xB377, + 0xD008, 0xB378, 0xD009, 0xB379, 0xD00A, 0xB37A, 0xD00B, 0xB381, + 0xD00C, 0xB382, 0xD00D, 0xB383, 0xD00E, 0xB384, 0xD00F, 0xB385, + 0xD010, 0xB386, 0xD011, 0xC4F8, 0xD012, 0xB387, 0xD013, 0xB388, + 0xD014, 0xB389, 0xD015, 0xB38A, 0xD016, 0xB38B, 0xD017, 0xB38C, + 0xD018, 0xC4F9, 0xD019, 0xB38D, 0xD01A, 0xB38E, 0xD01B, 0xB38F, + 0xD01C, 0xB390, 0xD01D, 0xB391, 0xD01E, 0xB392, 0xD01F, 0xB393, + 0xD020, 0xB394, 0xD021, 0xB395, 0xD022, 0xB396, 0xD023, 0xB397, + 0xD024, 0xB398, 0xD025, 0xB399, 0xD026, 0xB39A, 0xD027, 0xB39B, + 0xD028, 0xB39C, 0xD029, 0xB39D, 0xD02A, 0xB39E, 0xD02B, 0xB39F, + 0xD02C, 0xB3A0, 0xD02D, 0xC4FA, 0xD02E, 0xB441, 0xD02F, 0xB442, + 0xD030, 0xB443, 0xD031, 0xB444, 0xD032, 0xB445, 0xD033, 0xB446, + 0xD034, 0xC4FB, 0xD035, 0xC4FC, 0xD036, 0xB447, 0xD037, 0xB448, + 0xD038, 0xC4FD, 0xD039, 0xB449, 0xD03A, 0xB44A, 0xD03B, 0xB44B, + 0xD03C, 0xC4FE, 0xD03D, 0xB44C, 0xD03E, 0xB44D, 0xD03F, 0xB44E, + 0xD040, 0xB44F, 0xD041, 0xB450, 0xD042, 0xB451, 0xD043, 0xB452, + 0xD044, 0xC5A1, 0xD045, 0xC5A2, 0xD046, 0xB453, 0xD047, 0xC5A3, + 0xD048, 0xB454, 0xD049, 0xC5A4, 0xD04A, 0xB455, 0xD04B, 0xB456, + 0xD04C, 0xB457, 0xD04D, 0xB458, 0xD04E, 0xB459, 0xD04F, 0xB45A, + 0xD050, 0xC5A5, 0xD051, 0xB461, 0xD052, 0xB462, 0xD053, 0xB463, + 0xD054, 0xC5A6, 0xD055, 0xB464, 0xD056, 0xB465, 0xD057, 0xB466, + 0xD058, 0xC5A7, 0xD059, 0xB467, 0xD05A, 0xB468, 0xD05B, 0xB469, + 0xD05C, 0xB46A, 0xD05D, 0xB46B, 0xD05E, 0xB46C, 0xD05F, 0xB46D, + 0xD060, 0xC5A8, 0xD061, 0xB46E, 0xD062, 0xB46F, 0xD063, 0xB470, + 0xD064, 0xB471, 0xD065, 0xB472, 0xD066, 0xB473, 0xD067, 0xB474, + 0xD068, 0xB475, 0xD069, 0xB476, 0xD06A, 0xB477, 0xD06B, 0xB478, + 0xD06C, 0xC5A9, 0xD06D, 0xC5AA, 0xD06E, 0xB479, 0xD06F, 0xB47A, + 0xD070, 0xC5AB, 0xD071, 0xB481, 0xD072, 0xB482, 0xD073, 0xB483, + 0xD074, 0xC5AC, 0xD075, 0xB484, 0xD076, 0xB485, 0xD077, 0xB486, + 0xD078, 0xB487, 0xD079, 0xB488, 0xD07A, 0xB489, 0xD07B, 0xB48A, + 0xD07C, 0xC5AD, 0xD07D, 0xC5AE, 0xD07E, 0xB48B, 0xD07F, 0xB48C, + 0xD080, 0xB48D, 0xD081, 0xC5AF, 0xD082, 0xB48E, 0xD083, 0xB48F, + 0xD084, 0xB490, 0xD085, 0xB491, 0xD086, 0xB492, 0xD087, 0xB493, + 0xD088, 0xB494, 0xD089, 0xB495, 0xD08A, 0xB496, 0xD08B, 0xB497, + 0xD08C, 0xB498, 0xD08D, 0xB499, 0xD08E, 0xB49A, 0xD08F, 0xB49B, + 0xD090, 0xB49C, 0xD091, 0xB49D, 0xD092, 0xB49E, 0xD093, 0xB49F, + 0xD094, 0xB4A0, 0xD095, 0xB541, 0xD096, 0xB542, 0xD097, 0xB543, + 0xD098, 0xB544, 0xD099, 0xB545, 0xD09A, 0xB546, 0xD09B, 0xB547, + 0xD09C, 0xB548, 0xD09D, 0xB549, 0xD09E, 0xB54A, 0xD09F, 0xB54B, + 0xD0A0, 0xB54C, 0xD0A1, 0xB54D, 0xD0A2, 0xB54E, 0xD0A3, 0xB54F, + 0xD0A4, 0xC5B0, 0xD0A5, 0xC5B1, 0xD0A6, 0xB550, 0xD0A7, 0xB551, + 0xD0A8, 0xC5B2, 0xD0A9, 0xB552, 0xD0AA, 0xB553, 0xD0AB, 0xB554, + 0xD0AC, 0xC5B3, 0xD0AD, 0xB555, 0xD0AE, 0xB556, 0xD0AF, 0xB557, + 0xD0B0, 0xB558, 0xD0B1, 0xB559, 0xD0B2, 0xB55A, 0xD0B3, 0xB561, + 0xD0B4, 0xC5B4, 0xD0B5, 0xC5B5, 0xD0B6, 0xB562, 0xD0B7, 0xC5B6, + 0xD0B8, 0xB563, 0xD0B9, 0xC5B7, 0xD0BA, 0xB564, 0xD0BB, 0xB565, + 0xD0BC, 0xB566, 0xD0BD, 0xB567, 0xD0BE, 0xB568, 0xD0BF, 0xB569, + 0xD0C0, 0xC5B8, 0xD0C1, 0xC5B9, 0xD0C2, 0xB56A, 0xD0C3, 0xB56B, + 0xD0C4, 0xC5BA, 0xD0C5, 0xB56C, 0xD0C6, 0xB56D, 0xD0C7, 0xB56E, + 0xD0C8, 0xC5BB, 0xD0C9, 0xC5BC, 0xD0CA, 0xB56F, 0xD0CB, 0xB570, + 0xD0CC, 0xB571, 0xD0CD, 0xB572, 0xD0CE, 0xB573, 0xD0CF, 0xB574, + 0xD0D0, 0xC5BD, 0xD0D1, 0xC5BE, 0xD0D2, 0xB575, 0xD0D3, 0xC5BF, + 0xD0D4, 0xC5C0, 0xD0D5, 0xC5C1, 0xD0D6, 0xB576, 0xD0D7, 0xB577, + 0xD0D8, 0xB578, 0xD0D9, 0xB579, 0xD0DA, 0xB57A, 0xD0DB, 0xB581, + 0xD0DC, 0xC5C2, 0xD0DD, 0xC5C3, 0xD0DE, 0xB582, 0xD0DF, 0xB583, + 0xD0E0, 0xC5C4, 0xD0E1, 0xB584, 0xD0E2, 0xB585, 0xD0E3, 0xB586, + 0xD0E4, 0xC5C5, 0xD0E5, 0xB587, 0xD0E6, 0xB588, 0xD0E7, 0xB589, + 0xD0E8, 0xB58A, 0xD0E9, 0xB58B, 0xD0EA, 0xB58C, 0xD0EB, 0xB58D, + 0xD0EC, 0xC5C6, 0xD0ED, 0xC5C7, 0xD0EE, 0xB58E, 0xD0EF, 0xC5C8, + 0xD0F0, 0xC5C9, 0xD0F1, 0xC5CA, 0xD0F2, 0xB58F, 0xD0F3, 0xB590, + 0xD0F4, 0xB591, 0xD0F5, 0xB592, 0xD0F6, 0xB593, 0xD0F7, 0xB594, + 0xD0F8, 0xC5CB, 0xD0F9, 0xB595, 0xD0FA, 0xB596, 0xD0FB, 0xB597, + 0xD0FC, 0xB598, 0xD0FD, 0xB599, 0xD0FE, 0xB59A, 0xD0FF, 0xB59B, + 0xD100, 0xB59C, 0xD101, 0xB59D, 0xD102, 0xB59E, 0xD103, 0xB59F, + 0xD104, 0xB5A0, 0xD105, 0xB641, 0xD106, 0xB642, 0xD107, 0xB643, + 0xD108, 0xB644, 0xD109, 0xB645, 0xD10A, 0xB646, 0xD10B, 0xB647, + 0xD10C, 0xB648, 0xD10D, 0xC5CC, 0xD10E, 0xB649, 0xD10F, 0xB64A, + 0xD110, 0xB64B, 0xD111, 0xB64C, 0xD112, 0xB64D, 0xD113, 0xB64E, + 0xD114, 0xB64F, 0xD115, 0xB650, 0xD116, 0xB651, 0xD117, 0xB652, + 0xD118, 0xB653, 0xD119, 0xB654, 0xD11A, 0xB655, 0xD11B, 0xB656, + 0xD11C, 0xB657, 0xD11D, 0xB658, 0xD11E, 0xB659, 0xD11F, 0xB65A, + 0xD120, 0xB661, 0xD121, 0xB662, 0xD122, 0xB663, 0xD123, 0xB664, + 0xD124, 0xB665, 0xD125, 0xB666, 0xD126, 0xB667, 0xD127, 0xB668, + 0xD128, 0xB669, 0xD129, 0xB66A, 0xD12A, 0xB66B, 0xD12B, 0xB66C, + 0xD12C, 0xB66D, 0xD12D, 0xB66E, 0xD12E, 0xB66F, 0xD12F, 0xB670, + 0xD130, 0xC5CD, 0xD131, 0xC5CE, 0xD132, 0xB671, 0xD133, 0xB672, + 0xD134, 0xC5CF, 0xD135, 0xB673, 0xD136, 0xB674, 0xD137, 0xB675, + 0xD138, 0xC5D0, 0xD139, 0xB676, 0xD13A, 0xC5D1, 0xD13B, 0xB677, + 0xD13C, 0xB678, 0xD13D, 0xB679, 0xD13E, 0xB67A, 0xD13F, 0xB681, + 0xD140, 0xC5D2, 0xD141, 0xC5D3, 0xD142, 0xB682, 0xD143, 0xC5D4, + 0xD144, 0xC5D5, 0xD145, 0xC5D6, 0xD146, 0xB683, 0xD147, 0xB684, + 0xD148, 0xB685, 0xD149, 0xB686, 0xD14A, 0xB687, 0xD14B, 0xB688, + 0xD14C, 0xC5D7, 0xD14D, 0xC5D8, 0xD14E, 0xB689, 0xD14F, 0xB68A, + 0xD150, 0xC5D9, 0xD151, 0xB68B, 0xD152, 0xB68C, 0xD153, 0xB68D, + 0xD154, 0xC5DA, 0xD155, 0xB68E, 0xD156, 0xB68F, 0xD157, 0xB690, + 0xD158, 0xB691, 0xD159, 0xB692, 0xD15A, 0xB693, 0xD15B, 0xB694, + 0xD15C, 0xC5DB, 0xD15D, 0xC5DC, 0xD15E, 0xB695, 0xD15F, 0xC5DD, + 0xD160, 0xB696, 0xD161, 0xC5DE, 0xD162, 0xB697, 0xD163, 0xB698, + 0xD164, 0xB699, 0xD165, 0xB69A, 0xD166, 0xB69B, 0xD167, 0xB69C, + 0xD168, 0xC5DF, 0xD169, 0xB69D, 0xD16A, 0xB69E, 0xD16B, 0xB69F, + 0xD16C, 0xC5E0, 0xD16D, 0xB6A0, 0xD16E, 0xB741, 0xD16F, 0xB742, + 0xD170, 0xB743, 0xD171, 0xB744, 0xD172, 0xB745, 0xD173, 0xB746, + 0xD174, 0xB747, 0xD175, 0xB748, 0xD176, 0xB749, 0xD177, 0xB74A, + 0xD178, 0xB74B, 0xD179, 0xB74C, 0xD17A, 0xB74D, 0xD17B, 0xB74E, + 0xD17C, 0xC5E1, 0xD17D, 0xB74F, 0xD17E, 0xB750, 0xD17F, 0xB751, + 0xD180, 0xB752, 0xD181, 0xB753, 0xD182, 0xB754, 0xD183, 0xB755, + 0xD184, 0xC5E2, 0xD185, 0xB756, 0xD186, 0xB757, 0xD187, 0xB758, + 0xD188, 0xC5E3, 0xD189, 0xB759, 0xD18A, 0xB75A, 0xD18B, 0xB761, + 0xD18C, 0xB762, 0xD18D, 0xB763, 0xD18E, 0xB764, 0xD18F, 0xB765, + 0xD190, 0xB766, 0xD191, 0xB767, 0xD192, 0xB768, 0xD193, 0xB769, + 0xD194, 0xB76A, 0xD195, 0xB76B, 0xD196, 0xB76C, 0xD197, 0xB76D, + 0xD198, 0xB76E, 0xD199, 0xB76F, 0xD19A, 0xB770, 0xD19B, 0xB771, + 0xD19C, 0xB772, 0xD19D, 0xB773, 0xD19E, 0xB774, 0xD19F, 0xB775, + 0xD1A0, 0xC5E4, 0xD1A1, 0xC5E5, 0xD1A2, 0xB776, 0xD1A3, 0xB777, + 0xD1A4, 0xC5E6, 0xD1A5, 0xB778, 0xD1A6, 0xB779, 0xD1A7, 0xB77A, + 0xD1A8, 0xC5E7, 0xD1A9, 0xB781, 0xD1AA, 0xB782, 0xD1AB, 0xB783, + 0xD1AC, 0xB784, 0xD1AD, 0xB785, 0xD1AE, 0xB786, 0xD1AF, 0xB787, + 0xD1B0, 0xC5E8, 0xD1B1, 0xC5E9, 0xD1B2, 0xB788, 0xD1B3, 0xC5EA, + 0xD1B4, 0xB789, 0xD1B5, 0xC5EB, 0xD1B6, 0xB78A, 0xD1B7, 0xB78B, + 0xD1B8, 0xB78C, 0xD1B9, 0xB78D, 0xD1BA, 0xC5EC, 0xD1BB, 0xB78E, + 0xD1BC, 0xC5ED, 0xD1BD, 0xB78F, 0xD1BE, 0xB790, 0xD1BF, 0xB791, + 0xD1C0, 0xC5EE, 0xD1C1, 0xB792, 0xD1C2, 0xB793, 0xD1C3, 0xB794, + 0xD1C4, 0xB795, 0xD1C5, 0xB796, 0xD1C6, 0xB797, 0xD1C7, 0xB798, + 0xD1C8, 0xB799, 0xD1C9, 0xB79A, 0xD1CA, 0xB79B, 0xD1CB, 0xB79C, + 0xD1CC, 0xB79D, 0xD1CD, 0xB79E, 0xD1CE, 0xB79F, 0xD1CF, 0xB7A0, + 0xD1D0, 0xB841, 0xD1D1, 0xB842, 0xD1D2, 0xB843, 0xD1D3, 0xB844, + 0xD1D4, 0xB845, 0xD1D5, 0xB846, 0xD1D6, 0xB847, 0xD1D7, 0xB848, + 0xD1D8, 0xC5EF, 0xD1D9, 0xB849, 0xD1DA, 0xB84A, 0xD1DB, 0xB84B, + 0xD1DC, 0xB84C, 0xD1DD, 0xB84D, 0xD1DE, 0xB84E, 0xD1DF, 0xB84F, + 0xD1E0, 0xB850, 0xD1E1, 0xB851, 0xD1E2, 0xB852, 0xD1E3, 0xB853, + 0xD1E4, 0xB854, 0xD1E5, 0xB855, 0xD1E6, 0xB856, 0xD1E7, 0xB857, + 0xD1E8, 0xB858, 0xD1E9, 0xB859, 0xD1EA, 0xB85A, 0xD1EB, 0xB861, + 0xD1EC, 0xB862, 0xD1ED, 0xB863, 0xD1EE, 0xB864, 0xD1EF, 0xB865, + 0xD1F0, 0xB866, 0xD1F1, 0xB867, 0xD1F2, 0xB868, 0xD1F3, 0xB869, + 0xD1F4, 0xC5F0, 0xD1F5, 0xB86A, 0xD1F6, 0xB86B, 0xD1F7, 0xB86C, + 0xD1F8, 0xC5F1, 0xD1F9, 0xB86D, 0xD1FA, 0xB86E, 0xD1FB, 0xB86F, + 0xD1FC, 0xB870, 0xD1FD, 0xB871, 0xD1FE, 0xB872, 0xD1FF, 0xB873, + 0xD200, 0xB874, 0xD201, 0xB875, 0xD202, 0xB876, 0xD203, 0xB877, + 0xD204, 0xB878, 0xD205, 0xB879, 0xD206, 0xB87A, 0xD207, 0xC5F2, + 0xD208, 0xB881, 0xD209, 0xC5F3, 0xD20A, 0xB882, 0xD20B, 0xB883, + 0xD20C, 0xB884, 0xD20D, 0xB885, 0xD20E, 0xB886, 0xD20F, 0xB887, + 0xD210, 0xC5F4, 0xD211, 0xB888, 0xD212, 0xB889, 0xD213, 0xB88A, + 0xD214, 0xB88B, 0xD215, 0xB88C, 0xD216, 0xB88D, 0xD217, 0xB88E, + 0xD218, 0xB88F, 0xD219, 0xB890, 0xD21A, 0xB891, 0xD21B, 0xB892, + 0xD21C, 0xB893, 0xD21D, 0xB894, 0xD21E, 0xB895, 0xD21F, 0xB896, + 0xD220, 0xB897, 0xD221, 0xB898, 0xD222, 0xB899, 0xD223, 0xB89A, + 0xD224, 0xB89B, 0xD225, 0xB89C, 0xD226, 0xB89D, 0xD227, 0xB89E, + 0xD228, 0xB89F, 0xD229, 0xB8A0, 0xD22A, 0xB941, 0xD22B, 0xB942, + 0xD22C, 0xC5F5, 0xD22D, 0xC5F6, 0xD22E, 0xB943, 0xD22F, 0xB944, + 0xD230, 0xC5F7, 0xD231, 0xB945, 0xD232, 0xB946, 0xD233, 0xB947, + 0xD234, 0xC5F8, 0xD235, 0xB948, 0xD236, 0xB949, 0xD237, 0xB94A, + 0xD238, 0xB94B, 0xD239, 0xB94C, 0xD23A, 0xB94D, 0xD23B, 0xB94E, + 0xD23C, 0xC5F9, 0xD23D, 0xC5FA, 0xD23E, 0xB94F, 0xD23F, 0xC5FB, + 0xD240, 0xB950, 0xD241, 0xC5FC, 0xD242, 0xB951, 0xD243, 0xB952, + 0xD244, 0xB953, 0xD245, 0xB954, 0xD246, 0xB955, 0xD247, 0xB956, + 0xD248, 0xC5FD, 0xD249, 0xB957, 0xD24A, 0xB958, 0xD24B, 0xB959, + 0xD24C, 0xB95A, 0xD24D, 0xB961, 0xD24E, 0xB962, 0xD24F, 0xB963, + 0xD250, 0xB964, 0xD251, 0xB965, 0xD252, 0xB966, 0xD253, 0xB967, + 0xD254, 0xB968, 0xD255, 0xB969, 0xD256, 0xB96A, 0xD257, 0xB96B, + 0xD258, 0xB96C, 0xD259, 0xB96D, 0xD25A, 0xB96E, 0xD25B, 0xB96F, + 0xD25C, 0xC5FE, 0xD25D, 0xB970, 0xD25E, 0xB971, 0xD25F, 0xB972, + 0xD260, 0xB973, 0xD261, 0xB974, 0xD262, 0xB975, 0xD263, 0xB976, + 0xD264, 0xC6A1, 0xD265, 0xB977, 0xD266, 0xB978, 0xD267, 0xB979, + 0xD268, 0xB97A, 0xD269, 0xB981, 0xD26A, 0xB982, 0xD26B, 0xB983, + 0xD26C, 0xB984, 0xD26D, 0xB985, 0xD26E, 0xB986, 0xD26F, 0xB987, + 0xD270, 0xB988, 0xD271, 0xB989, 0xD272, 0xB98A, 0xD273, 0xB98B, + 0xD274, 0xB98C, 0xD275, 0xB98D, 0xD276, 0xB98E, 0xD277, 0xB98F, + 0xD278, 0xB990, 0xD279, 0xB991, 0xD27A, 0xB992, 0xD27B, 0xB993, + 0xD27C, 0xB994, 0xD27D, 0xB995, 0xD27E, 0xB996, 0xD27F, 0xB997, + 0xD280, 0xC6A2, 0xD281, 0xC6A3, 0xD282, 0xB998, 0xD283, 0xB999, + 0xD284, 0xC6A4, 0xD285, 0xB99A, 0xD286, 0xB99B, 0xD287, 0xB99C, + 0xD288, 0xC6A5, 0xD289, 0xB99D, 0xD28A, 0xB99E, 0xD28B, 0xB99F, + 0xD28C, 0xB9A0, 0xD28D, 0xBA41, 0xD28E, 0xBA42, 0xD28F, 0xBA43, + 0xD290, 0xC6A6, 0xD291, 0xC6A7, 0xD292, 0xBA44, 0xD293, 0xBA45, + 0xD294, 0xBA46, 0xD295, 0xC6A8, 0xD296, 0xBA47, 0xD297, 0xBA48, + 0xD298, 0xBA49, 0xD299, 0xBA4A, 0xD29A, 0xBA4B, 0xD29B, 0xBA4C, + 0xD29C, 0xC6A9, 0xD29D, 0xBA4D, 0xD29E, 0xBA4E, 0xD29F, 0xBA4F, + 0xD2A0, 0xC6AA, 0xD2A1, 0xBA50, 0xD2A2, 0xBA51, 0xD2A3, 0xBA52, + 0xD2A4, 0xC6AB, 0xD2A5, 0xBA53, 0xD2A6, 0xBA54, 0xD2A7, 0xBA55, + 0xD2A8, 0xBA56, 0xD2A9, 0xBA57, 0xD2AA, 0xBA58, 0xD2AB, 0xBA59, + 0xD2AC, 0xC6AC, 0xD2AD, 0xBA5A, 0xD2AE, 0xBA61, 0xD2AF, 0xBA62, + 0xD2B0, 0xBA63, 0xD2B1, 0xC6AD, 0xD2B2, 0xBA64, 0xD2B3, 0xBA65, + 0xD2B4, 0xBA66, 0xD2B5, 0xBA67, 0xD2B6, 0xBA68, 0xD2B7, 0xBA69, + 0xD2B8, 0xC6AE, 0xD2B9, 0xC6AF, 0xD2BA, 0xBA6A, 0xD2BB, 0xBA6B, + 0xD2BC, 0xC6B0, 0xD2BD, 0xBA6C, 0xD2BE, 0xBA6D, 0xD2BF, 0xC6B1, + 0xD2C0, 0xC6B2, 0xD2C1, 0xBA6E, 0xD2C2, 0xC6B3, 0xD2C3, 0xBA6F, + 0xD2C4, 0xBA70, 0xD2C5, 0xBA71, 0xD2C6, 0xBA72, 0xD2C7, 0xBA73, + 0xD2C8, 0xC6B4, 0xD2C9, 0xC6B5, 0xD2CA, 0xBA74, 0xD2CB, 0xC6B6, + 0xD2CC, 0xBA75, 0xD2CD, 0xBA76, 0xD2CE, 0xBA77, 0xD2CF, 0xBA78, + 0xD2D0, 0xBA79, 0xD2D1, 0xBA7A, 0xD2D2, 0xBA81, 0xD2D3, 0xBA82, + 0xD2D4, 0xC6B7, 0xD2D5, 0xBA83, 0xD2D6, 0xBA84, 0xD2D7, 0xBA85, + 0xD2D8, 0xC6B8, 0xD2D9, 0xBA86, 0xD2DA, 0xBA87, 0xD2DB, 0xBA88, + 0xD2DC, 0xC6B9, 0xD2DD, 0xBA89, 0xD2DE, 0xBA8A, 0xD2DF, 0xBA8B, + 0xD2E0, 0xBA8C, 0xD2E1, 0xBA8D, 0xD2E2, 0xBA8E, 0xD2E3, 0xBA8F, + 0xD2E4, 0xC6BA, 0xD2E5, 0xC6BB, 0xD2E6, 0xBA90, 0xD2E7, 0xBA91, + 0xD2E8, 0xBA92, 0xD2E9, 0xBA93, 0xD2EA, 0xBA94, 0xD2EB, 0xBA95, + 0xD2EC, 0xBA96, 0xD2ED, 0xBA97, 0xD2EE, 0xBA98, 0xD2EF, 0xBA99, + 0xD2F0, 0xC6BC, 0xD2F1, 0xC6BD, 0xD2F2, 0xBA9A, 0xD2F3, 0xBA9B, + 0xD2F4, 0xC6BE, 0xD2F5, 0xBA9C, 0xD2F6, 0xBA9D, 0xD2F7, 0xBA9E, + 0xD2F8, 0xC6BF, 0xD2F9, 0xBA9F, 0xD2FA, 0xBAA0, 0xD2FB, 0xBB41, + 0xD2FC, 0xBB42, 0xD2FD, 0xBB43, 0xD2FE, 0xBB44, 0xD2FF, 0xBB45, + 0xD300, 0xC6C0, 0xD301, 0xC6C1, 0xD302, 0xBB46, 0xD303, 0xC6C2, + 0xD304, 0xBB47, 0xD305, 0xC6C3, 0xD306, 0xBB48, 0xD307, 0xBB49, + 0xD308, 0xBB4A, 0xD309, 0xBB4B, 0xD30A, 0xBB4C, 0xD30B, 0xBB4D, + 0xD30C, 0xC6C4, 0xD30D, 0xC6C5, 0xD30E, 0xC6C6, 0xD30F, 0xBB4E, + 0xD310, 0xC6C7, 0xD311, 0xBB4F, 0xD312, 0xBB50, 0xD313, 0xBB51, + 0xD314, 0xC6C8, 0xD315, 0xBB52, 0xD316, 0xC6C9, 0xD317, 0xBB53, + 0xD318, 0xBB54, 0xD319, 0xBB55, 0xD31A, 0xBB56, 0xD31B, 0xBB57, + 0xD31C, 0xC6CA, 0xD31D, 0xC6CB, 0xD31E, 0xBB58, 0xD31F, 0xC6CC, + 0xD320, 0xC6CD, 0xD321, 0xC6CE, 0xD322, 0xBB59, 0xD323, 0xBB5A, + 0xD324, 0xBB61, 0xD325, 0xC6CF, 0xD326, 0xBB62, 0xD327, 0xBB63, + 0xD328, 0xC6D0, 0xD329, 0xC6D1, 0xD32A, 0xBB64, 0xD32B, 0xBB65, + 0xD32C, 0xC6D2, 0xD32D, 0xBB66, 0xD32E, 0xBB67, 0xD32F, 0xBB68, + 0xD330, 0xC6D3, 0xD331, 0xBB69, 0xD332, 0xBB6A, 0xD333, 0xBB6B, + 0xD334, 0xBB6C, 0xD335, 0xBB6D, 0xD336, 0xBB6E, 0xD337, 0xBB6F, + 0xD338, 0xC6D4, 0xD339, 0xC6D5, 0xD33A, 0xBB70, 0xD33B, 0xC6D6, + 0xD33C, 0xC6D7, 0xD33D, 0xC6D8, 0xD33E, 0xBB71, 0xD33F, 0xBB72, + 0xD340, 0xBB73, 0xD341, 0xBB74, 0xD342, 0xBB75, 0xD343, 0xBB76, + 0xD344, 0xC6D9, 0xD345, 0xC6DA, 0xD346, 0xBB77, 0xD347, 0xBB78, + 0xD348, 0xBB79, 0xD349, 0xBB7A, 0xD34A, 0xBB81, 0xD34B, 0xBB82, + 0xD34C, 0xBB83, 0xD34D, 0xBB84, 0xD34E, 0xBB85, 0xD34F, 0xBB86, + 0xD350, 0xBB87, 0xD351, 0xBB88, 0xD352, 0xBB89, 0xD353, 0xBB8A, + 0xD354, 0xBB8B, 0xD355, 0xBB8C, 0xD356, 0xBB8D, 0xD357, 0xBB8E, + 0xD358, 0xBB8F, 0xD359, 0xBB90, 0xD35A, 0xBB91, 0xD35B, 0xBB92, + 0xD35C, 0xBB93, 0xD35D, 0xBB94, 0xD35E, 0xBB95, 0xD35F, 0xBB96, + 0xD360, 0xBB97, 0xD361, 0xBB98, 0xD362, 0xBB99, 0xD363, 0xBB9A, + 0xD364, 0xBB9B, 0xD365, 0xBB9C, 0xD366, 0xBB9D, 0xD367, 0xBB9E, + 0xD368, 0xBB9F, 0xD369, 0xBBA0, 0xD36A, 0xBC41, 0xD36B, 0xBC42, + 0xD36C, 0xBC43, 0xD36D, 0xBC44, 0xD36E, 0xBC45, 0xD36F, 0xBC46, + 0xD370, 0xBC47, 0xD371, 0xBC48, 0xD372, 0xBC49, 0xD373, 0xBC4A, + 0xD374, 0xBC4B, 0xD375, 0xBC4C, 0xD376, 0xBC4D, 0xD377, 0xBC4E, + 0xD378, 0xBC4F, 0xD379, 0xBC50, 0xD37A, 0xBC51, 0xD37B, 0xBC52, + 0xD37C, 0xC6DB, 0xD37D, 0xC6DC, 0xD37E, 0xBC53, 0xD37F, 0xBC54, + 0xD380, 0xC6DD, 0xD381, 0xBC55, 0xD382, 0xBC56, 0xD383, 0xBC57, + 0xD384, 0xC6DE, 0xD385, 0xBC58, 0xD386, 0xBC59, 0xD387, 0xBC5A, + 0xD388, 0xBC61, 0xD389, 0xBC62, 0xD38A, 0xBC63, 0xD38B, 0xBC64, + 0xD38C, 0xC6DF, 0xD38D, 0xC6E0, 0xD38E, 0xBC65, 0xD38F, 0xC6E1, + 0xD390, 0xC6E2, 0xD391, 0xC6E3, 0xD392, 0xBC66, 0xD393, 0xBC67, + 0xD394, 0xBC68, 0xD395, 0xBC69, 0xD396, 0xBC6A, 0xD397, 0xBC6B, + 0xD398, 0xC6E4, 0xD399, 0xC6E5, 0xD39A, 0xBC6C, 0xD39B, 0xBC6D, + 0xD39C, 0xC6E6, 0xD39D, 0xBC6E, 0xD39E, 0xBC6F, 0xD39F, 0xBC70, + 0xD3A0, 0xC6E7, 0xD3A1, 0xBC71, 0xD3A2, 0xBC72, 0xD3A3, 0xBC73, + 0xD3A4, 0xBC74, 0xD3A5, 0xBC75, 0xD3A6, 0xBC76, 0xD3A7, 0xBC77, + 0xD3A8, 0xC6E8, 0xD3A9, 0xC6E9, 0xD3AA, 0xBC78, 0xD3AB, 0xC6EA, + 0xD3AC, 0xBC79, 0xD3AD, 0xC6EB, 0xD3AE, 0xBC7A, 0xD3AF, 0xBC81, + 0xD3B0, 0xBC82, 0xD3B1, 0xBC83, 0xD3B2, 0xBC84, 0xD3B3, 0xBC85, + 0xD3B4, 0xC6EC, 0xD3B5, 0xBC86, 0xD3B6, 0xBC87, 0xD3B7, 0xBC88, + 0xD3B8, 0xC6ED, 0xD3B9, 0xBC89, 0xD3BA, 0xBC8A, 0xD3BB, 0xBC8B, + 0xD3BC, 0xC6EE, 0xD3BD, 0xBC8C, 0xD3BE, 0xBC8D, 0xD3BF, 0xBC8E, + 0xD3C0, 0xBC8F, 0xD3C1, 0xBC90, 0xD3C2, 0xBC91, 0xD3C3, 0xBC92, + 0xD3C4, 0xC6EF, 0xD3C5, 0xC6F0, 0xD3C6, 0xBC93, 0xD3C7, 0xBC94, + 0xD3C8, 0xC6F1, 0xD3C9, 0xC6F2, 0xD3CA, 0xBC95, 0xD3CB, 0xBC96, + 0xD3CC, 0xBC97, 0xD3CD, 0xBC98, 0xD3CE, 0xBC99, 0xD3CF, 0xBC9A, + 0xD3D0, 0xC6F3, 0xD3D1, 0xBC9B, 0xD3D2, 0xBC9C, 0xD3D3, 0xBC9D, + 0xD3D4, 0xBC9E, 0xD3D5, 0xBC9F, 0xD3D6, 0xBCA0, 0xD3D7, 0xBD41, + 0xD3D8, 0xC6F4, 0xD3D9, 0xBD42, 0xD3DA, 0xBD43, 0xD3DB, 0xBD44, + 0xD3DC, 0xBD45, 0xD3DD, 0xBD46, 0xD3DE, 0xBD47, 0xD3DF, 0xBD48, + 0xD3E0, 0xBD49, 0xD3E1, 0xC6F5, 0xD3E2, 0xBD4A, 0xD3E3, 0xC6F6, + 0xD3E4, 0xBD4B, 0xD3E5, 0xBD4C, 0xD3E6, 0xBD4D, 0xD3E7, 0xBD4E, + 0xD3E8, 0xBD4F, 0xD3E9, 0xBD50, 0xD3EA, 0xBD51, 0xD3EB, 0xBD52, + 0xD3EC, 0xC6F7, 0xD3ED, 0xC6F8, 0xD3EE, 0xBD53, 0xD3EF, 0xBD54, + 0xD3F0, 0xC6F9, 0xD3F1, 0xBD55, 0xD3F2, 0xBD56, 0xD3F3, 0xBD57, + 0xD3F4, 0xC6FA, 0xD3F5, 0xBD58, 0xD3F6, 0xBD59, 0xD3F7, 0xBD5A, + 0xD3F8, 0xBD61, 0xD3F9, 0xBD62, 0xD3FA, 0xBD63, 0xD3FB, 0xBD64, + 0xD3FC, 0xC6FB, 0xD3FD, 0xC6FC, 0xD3FE, 0xBD65, 0xD3FF, 0xC6FD, + 0xD400, 0xBD66, 0xD401, 0xC6FE, 0xD402, 0xBD67, 0xD403, 0xBD68, + 0xD404, 0xBD69, 0xD405, 0xBD6A, 0xD406, 0xBD6B, 0xD407, 0xBD6C, + 0xD408, 0xC7A1, 0xD409, 0xBD6D, 0xD40A, 0xBD6E, 0xD40B, 0xBD6F, + 0xD40C, 0xBD70, 0xD40D, 0xBD71, 0xD40E, 0xBD72, 0xD40F, 0xBD73, + 0xD410, 0xBD74, 0xD411, 0xBD75, 0xD412, 0xBD76, 0xD413, 0xBD77, + 0xD414, 0xBD78, 0xD415, 0xBD79, 0xD416, 0xBD7A, 0xD417, 0xBD81, + 0xD418, 0xBD82, 0xD419, 0xBD83, 0xD41A, 0xBD84, 0xD41B, 0xBD85, + 0xD41C, 0xBD86, 0xD41D, 0xC7A2, 0xD41E, 0xBD87, 0xD41F, 0xBD88, + 0xD420, 0xBD89, 0xD421, 0xBD8A, 0xD422, 0xBD8B, 0xD423, 0xBD8C, + 0xD424, 0xBD8D, 0xD425, 0xBD8E, 0xD426, 0xBD8F, 0xD427, 0xBD90, + 0xD428, 0xBD91, 0xD429, 0xBD92, 0xD42A, 0xBD93, 0xD42B, 0xBD94, + 0xD42C, 0xBD95, 0xD42D, 0xBD96, 0xD42E, 0xBD97, 0xD42F, 0xBD98, + 0xD430, 0xBD99, 0xD431, 0xBD9A, 0xD432, 0xBD9B, 0xD433, 0xBD9C, + 0xD434, 0xBD9D, 0xD435, 0xBD9E, 0xD436, 0xBD9F, 0xD437, 0xBDA0, + 0xD438, 0xBE41, 0xD439, 0xBE42, 0xD43A, 0xBE43, 0xD43B, 0xBE44, + 0xD43C, 0xBE45, 0xD43D, 0xBE46, 0xD43E, 0xBE47, 0xD43F, 0xBE48, + 0xD440, 0xC7A3, 0xD441, 0xBE49, 0xD442, 0xBE4A, 0xD443, 0xBE4B, + 0xD444, 0xC7A4, 0xD445, 0xBE4C, 0xD446, 0xBE4D, 0xD447, 0xBE4E, + 0xD448, 0xBE4F, 0xD449, 0xBE50, 0xD44A, 0xBE51, 0xD44B, 0xBE52, + 0xD44C, 0xBE53, 0xD44D, 0xBE54, 0xD44E, 0xBE55, 0xD44F, 0xBE56, + 0xD450, 0xBE57, 0xD451, 0xBE58, 0xD452, 0xBE59, 0xD453, 0xBE5A, + 0xD454, 0xBE61, 0xD455, 0xBE62, 0xD456, 0xBE63, 0xD457, 0xBE64, + 0xD458, 0xBE65, 0xD459, 0xBE66, 0xD45A, 0xBE67, 0xD45B, 0xBE68, + 0xD45C, 0xC7A5, 0xD45D, 0xBE69, 0xD45E, 0xBE6A, 0xD45F, 0xBE6B, + 0xD460, 0xC7A6, 0xD461, 0xBE6C, 0xD462, 0xBE6D, 0xD463, 0xBE6E, + 0xD464, 0xC7A7, 0xD465, 0xBE6F, 0xD466, 0xBE70, 0xD467, 0xBE71, + 0xD468, 0xBE72, 0xD469, 0xBE73, 0xD46A, 0xBE74, 0xD46B, 0xBE75, + 0xD46C, 0xBE76, 0xD46D, 0xC7A8, 0xD46E, 0xBE77, 0xD46F, 0xC7A9, + 0xD470, 0xBE78, 0xD471, 0xBE79, 0xD472, 0xBE7A, 0xD473, 0xBE81, + 0xD474, 0xBE82, 0xD475, 0xBE83, 0xD476, 0xBE84, 0xD477, 0xBE85, + 0xD478, 0xC7AA, 0xD479, 0xC7AB, 0xD47A, 0xBE86, 0xD47B, 0xBE87, + 0xD47C, 0xC7AC, 0xD47D, 0xBE88, 0xD47E, 0xBE89, 0xD47F, 0xC7AD, + 0xD480, 0xC7AE, 0xD481, 0xBE8A, 0xD482, 0xC7AF, 0xD483, 0xBE8B, + 0xD484, 0xBE8C, 0xD485, 0xBE8D, 0xD486, 0xBE8E, 0xD487, 0xBE8F, + 0xD488, 0xC7B0, 0xD489, 0xC7B1, 0xD48A, 0xBE90, 0xD48B, 0xC7B2, + 0xD48C, 0xBE91, 0xD48D, 0xC7B3, 0xD48E, 0xBE92, 0xD48F, 0xBE93, + 0xD490, 0xBE94, 0xD491, 0xBE95, 0xD492, 0xBE96, 0xD493, 0xBE97, + 0xD494, 0xC7B4, 0xD495, 0xBE98, 0xD496, 0xBE99, 0xD497, 0xBE9A, + 0xD498, 0xBE9B, 0xD499, 0xBE9C, 0xD49A, 0xBE9D, 0xD49B, 0xBE9E, + 0xD49C, 0xBE9F, 0xD49D, 0xBEA0, 0xD49E, 0xBF41, 0xD49F, 0xBF42, + 0xD4A0, 0xBF43, 0xD4A1, 0xBF44, 0xD4A2, 0xBF45, 0xD4A3, 0xBF46, + 0xD4A4, 0xBF47, 0xD4A5, 0xBF48, 0xD4A6, 0xBF49, 0xD4A7, 0xBF4A, + 0xD4A8, 0xBF4B, 0xD4A9, 0xC7B5, 0xD4AA, 0xBF4C, 0xD4AB, 0xBF4D, + 0xD4AC, 0xBF4E, 0xD4AD, 0xBF4F, 0xD4AE, 0xBF50, 0xD4AF, 0xBF51, + 0xD4B0, 0xBF52, 0xD4B1, 0xBF53, 0xD4B2, 0xBF54, 0xD4B3, 0xBF55, + 0xD4B4, 0xBF56, 0xD4B5, 0xBF57, 0xD4B6, 0xBF58, 0xD4B7, 0xBF59, + 0xD4B8, 0xBF5A, 0xD4B9, 0xBF61, 0xD4BA, 0xBF62, 0xD4BB, 0xBF63, + 0xD4BC, 0xBF64, 0xD4BD, 0xBF65, 0xD4BE, 0xBF66, 0xD4BF, 0xBF67, + 0xD4C0, 0xBF68, 0xD4C1, 0xBF69, 0xD4C2, 0xBF6A, 0xD4C3, 0xBF6B, + 0xD4C4, 0xBF6C, 0xD4C5, 0xBF6D, 0xD4C6, 0xBF6E, 0xD4C7, 0xBF6F, + 0xD4C8, 0xBF70, 0xD4C9, 0xBF71, 0xD4CA, 0xBF72, 0xD4CB, 0xBF73, + 0xD4CC, 0xC7B6, 0xD4CD, 0xBF74, 0xD4CE, 0xBF75, 0xD4CF, 0xBF76, + 0xD4D0, 0xC7B7, 0xD4D1, 0xBF77, 0xD4D2, 0xBF78, 0xD4D3, 0xBF79, + 0xD4D4, 0xC7B8, 0xD4D5, 0xBF7A, 0xD4D6, 0xBF81, 0xD4D7, 0xBF82, + 0xD4D8, 0xBF83, 0xD4D9, 0xBF84, 0xD4DA, 0xBF85, 0xD4DB, 0xBF86, + 0xD4DC, 0xC7B9, 0xD4DD, 0xBF87, 0xD4DE, 0xBF88, 0xD4DF, 0xC7BA, + 0xD4E0, 0xBF89, 0xD4E1, 0xBF8A, 0xD4E2, 0xBF8B, 0xD4E3, 0xBF8C, + 0xD4E4, 0xBF8D, 0xD4E5, 0xBF8E, 0xD4E6, 0xBF8F, 0xD4E7, 0xBF90, + 0xD4E8, 0xC7BB, 0xD4E9, 0xBF91, 0xD4EA, 0xBF92, 0xD4EB, 0xBF93, + 0xD4EC, 0xC7BC, 0xD4ED, 0xBF94, 0xD4EE, 0xBF95, 0xD4EF, 0xBF96, + 0xD4F0, 0xC7BD, 0xD4F1, 0xBF97, 0xD4F2, 0xBF98, 0xD4F3, 0xBF99, + 0xD4F4, 0xBF9A, 0xD4F5, 0xBF9B, 0xD4F6, 0xBF9C, 0xD4F7, 0xBF9D, + 0xD4F8, 0xC7BE, 0xD4F9, 0xBF9E, 0xD4FA, 0xBF9F, 0xD4FB, 0xC7BF, + 0xD4FC, 0xBFA0, 0xD4FD, 0xC7C0, 0xD4FE, 0xC041, 0xD4FF, 0xC042, + 0xD500, 0xC043, 0xD501, 0xC044, 0xD502, 0xC045, 0xD503, 0xC046, + 0xD504, 0xC7C1, 0xD505, 0xC047, 0xD506, 0xC048, 0xD507, 0xC049, + 0xD508, 0xC7C2, 0xD509, 0xC04A, 0xD50A, 0xC04B, 0xD50B, 0xC04C, + 0xD50C, 0xC7C3, 0xD50D, 0xC04D, 0xD50E, 0xC04E, 0xD50F, 0xC04F, + 0xD510, 0xC050, 0xD511, 0xC051, 0xD512, 0xC052, 0xD513, 0xC053, + 0xD514, 0xC7C4, 0xD515, 0xC7C5, 0xD516, 0xC054, 0xD517, 0xC7C6, + 0xD518, 0xC055, 0xD519, 0xC056, 0xD51A, 0xC057, 0xD51B, 0xC058, + 0xD51C, 0xC059, 0xD51D, 0xC05A, 0xD51E, 0xC061, 0xD51F, 0xC062, + 0xD520, 0xC063, 0xD521, 0xC064, 0xD522, 0xC065, 0xD523, 0xC066, + 0xD524, 0xC067, 0xD525, 0xC068, 0xD526, 0xC069, 0xD527, 0xC06A, + 0xD528, 0xC06B, 0xD529, 0xC06C, 0xD52A, 0xC06D, 0xD52B, 0xC06E, + 0xD52C, 0xC06F, 0xD52D, 0xC070, 0xD52E, 0xC071, 0xD52F, 0xC072, + 0xD530, 0xC073, 0xD531, 0xC074, 0xD532, 0xC075, 0xD533, 0xC076, + 0xD534, 0xC077, 0xD535, 0xC078, 0xD536, 0xC079, 0xD537, 0xC07A, + 0xD538, 0xC081, 0xD539, 0xC082, 0xD53A, 0xC083, 0xD53B, 0xC084, + 0xD53C, 0xC7C7, 0xD53D, 0xC7C8, 0xD53E, 0xC085, 0xD53F, 0xC086, + 0xD540, 0xC7C9, 0xD541, 0xC087, 0xD542, 0xC088, 0xD543, 0xC089, + 0xD544, 0xC7CA, 0xD545, 0xC08A, 0xD546, 0xC08B, 0xD547, 0xC08C, + 0xD548, 0xC08D, 0xD549, 0xC08E, 0xD54A, 0xC08F, 0xD54B, 0xC090, + 0xD54C, 0xC7CB, 0xD54D, 0xC7CC, 0xD54E, 0xC091, 0xD54F, 0xC7CD, + 0xD550, 0xC092, 0xD551, 0xC7CE, 0xD552, 0xC093, 0xD553, 0xC094, + 0xD554, 0xC095, 0xD555, 0xC096, 0xD556, 0xC097, 0xD557, 0xC098, + 0xD558, 0xC7CF, 0xD559, 0xC7D0, 0xD55A, 0xC099, 0xD55B, 0xC09A, + 0xD55C, 0xC7D1, 0xD55D, 0xC09B, 0xD55E, 0xC09C, 0xD55F, 0xC09D, + 0xD560, 0xC7D2, 0xD561, 0xC09E, 0xD562, 0xC09F, 0xD563, 0xC0A0, + 0xD564, 0xC141, 0xD565, 0xC7D3, 0xD566, 0xC142, 0xD567, 0xC143, + 0xD568, 0xC7D4, 0xD569, 0xC7D5, 0xD56A, 0xC144, 0xD56B, 0xC7D6, + 0xD56C, 0xC145, 0xD56D, 0xC7D7, 0xD56E, 0xC146, 0xD56F, 0xC147, + 0xD570, 0xC148, 0xD571, 0xC149, 0xD572, 0xC14A, 0xD573, 0xC14B, + 0xD574, 0xC7D8, 0xD575, 0xC7D9, 0xD576, 0xC14C, 0xD577, 0xC14D, + 0xD578, 0xC7DA, 0xD579, 0xC14E, 0xD57A, 0xC14F, 0xD57B, 0xC150, + 0xD57C, 0xC7DB, 0xD57D, 0xC151, 0xD57E, 0xC152, 0xD57F, 0xC153, + 0xD580, 0xC154, 0xD581, 0xC155, 0xD582, 0xC156, 0xD583, 0xC157, + 0xD584, 0xC7DC, 0xD585, 0xC7DD, 0xD586, 0xC158, 0xD587, 0xC7DE, + 0xD588, 0xC7DF, 0xD589, 0xC7E0, 0xD58A, 0xC159, 0xD58B, 0xC15A, + 0xD58C, 0xC161, 0xD58D, 0xC162, 0xD58E, 0xC163, 0xD58F, 0xC164, + 0xD590, 0xC7E1, 0xD591, 0xC165, 0xD592, 0xC166, 0xD593, 0xC167, + 0xD594, 0xC168, 0xD595, 0xC169, 0xD596, 0xC16A, 0xD597, 0xC16B, + 0xD598, 0xC16C, 0xD599, 0xC16D, 0xD59A, 0xC16E, 0xD59B, 0xC16F, + 0xD59C, 0xC170, 0xD59D, 0xC171, 0xD59E, 0xC172, 0xD59F, 0xC173, + 0xD5A0, 0xC174, 0xD5A1, 0xC175, 0xD5A2, 0xC176, 0xD5A3, 0xC177, + 0xD5A4, 0xC178, 0xD5A5, 0xC7E2, 0xD5A6, 0xC179, 0xD5A7, 0xC17A, + 0xD5A8, 0xC181, 0xD5A9, 0xC182, 0xD5AA, 0xC183, 0xD5AB, 0xC184, + 0xD5AC, 0xC185, 0xD5AD, 0xC186, 0xD5AE, 0xC187, 0xD5AF, 0xC188, + 0xD5B0, 0xC189, 0xD5B1, 0xC18A, 0xD5B2, 0xC18B, 0xD5B3, 0xC18C, + 0xD5B4, 0xC18D, 0xD5B5, 0xC18E, 0xD5B6, 0xC18F, 0xD5B7, 0xC190, + 0xD5B8, 0xC191, 0xD5B9, 0xC192, 0xD5BA, 0xC193, 0xD5BB, 0xC194, + 0xD5BC, 0xC195, 0xD5BD, 0xC196, 0xD5BE, 0xC197, 0xD5BF, 0xC198, + 0xD5C0, 0xC199, 0xD5C1, 0xC19A, 0xD5C2, 0xC19B, 0xD5C3, 0xC19C, + 0xD5C4, 0xC19D, 0xD5C5, 0xC19E, 0xD5C6, 0xC19F, 0xD5C7, 0xC1A0, + 0xD5C8, 0xC7E3, 0xD5C9, 0xC7E4, 0xD5CA, 0xC241, 0xD5CB, 0xC242, + 0xD5CC, 0xC7E5, 0xD5CD, 0xC243, 0xD5CE, 0xC244, 0xD5CF, 0xC245, + 0xD5D0, 0xC7E6, 0xD5D1, 0xC246, 0xD5D2, 0xC7E7, 0xD5D3, 0xC247, + 0xD5D4, 0xC248, 0xD5D5, 0xC249, 0xD5D6, 0xC24A, 0xD5D7, 0xC24B, + 0xD5D8, 0xC7E8, 0xD5D9, 0xC7E9, 0xD5DA, 0xC24C, 0xD5DB, 0xC7EA, + 0xD5DC, 0xC24D, 0xD5DD, 0xC7EB, 0xD5DE, 0xC24E, 0xD5DF, 0xC24F, + 0xD5E0, 0xC250, 0xD5E1, 0xC251, 0xD5E2, 0xC252, 0xD5E3, 0xC253, + 0xD5E4, 0xC7EC, 0xD5E5, 0xC7ED, 0xD5E6, 0xC254, 0xD5E7, 0xC255, + 0xD5E8, 0xC7EE, 0xD5E9, 0xC256, 0xD5EA, 0xC257, 0xD5EB, 0xC258, + 0xD5EC, 0xC7EF, 0xD5ED, 0xC259, 0xD5EE, 0xC25A, 0xD5EF, 0xC261, + 0xD5F0, 0xC262, 0xD5F1, 0xC263, 0xD5F2, 0xC264, 0xD5F3, 0xC265, + 0xD5F4, 0xC7F0, 0xD5F5, 0xC7F1, 0xD5F6, 0xC266, 0xD5F7, 0xC7F2, + 0xD5F8, 0xC267, 0xD5F9, 0xC7F3, 0xD5FA, 0xC268, 0xD5FB, 0xC269, + 0xD5FC, 0xC26A, 0xD5FD, 0xC26B, 0xD5FE, 0xC26C, 0xD5FF, 0xC26D, + 0xD600, 0xC7F4, 0xD601, 0xC7F5, 0xD602, 0xC26E, 0xD603, 0xC26F, + 0xD604, 0xC7F6, 0xD605, 0xC270, 0xD606, 0xC271, 0xD607, 0xC272, + 0xD608, 0xC7F7, 0xD609, 0xC273, 0xD60A, 0xC274, 0xD60B, 0xC275, + 0xD60C, 0xC276, 0xD60D, 0xC277, 0xD60E, 0xC278, 0xD60F, 0xC279, + 0xD610, 0xC7F8, 0xD611, 0xC7F9, 0xD612, 0xC27A, 0xD613, 0xC7FA, + 0xD614, 0xC7FB, 0xD615, 0xC7FC, 0xD616, 0xC281, 0xD617, 0xC282, + 0xD618, 0xC283, 0xD619, 0xC284, 0xD61A, 0xC285, 0xD61B, 0xC286, + 0xD61C, 0xC7FD, 0xD61D, 0xC287, 0xD61E, 0xC288, 0xD61F, 0xC289, + 0xD620, 0xC7FE, 0xD621, 0xC28A, 0xD622, 0xC28B, 0xD623, 0xC28C, + 0xD624, 0xC8A1, 0xD625, 0xC28D, 0xD626, 0xC28E, 0xD627, 0xC28F, + 0xD628, 0xC290, 0xD629, 0xC291, 0xD62A, 0xC292, 0xD62B, 0xC293, + 0xD62C, 0xC294, 0xD62D, 0xC8A2, 0xD62E, 0xC295, 0xD62F, 0xC296, + 0xD630, 0xC297, 0xD631, 0xC298, 0xD632, 0xC299, 0xD633, 0xC29A, + 0xD634, 0xC29B, 0xD635, 0xC29C, 0xD636, 0xC29D, 0xD637, 0xC29E, + 0xD638, 0xC8A3, 0xD639, 0xC8A4, 0xD63A, 0xC29F, 0xD63B, 0xC2A0, + 0xD63C, 0xC8A5, 0xD63D, 0xC341, 0xD63E, 0xC342, 0xD63F, 0xC343, + 0xD640, 0xC8A6, 0xD641, 0xC344, 0xD642, 0xC345, 0xD643, 0xC346, + 0xD644, 0xC347, 0xD645, 0xC8A7, 0xD646, 0xC348, 0xD647, 0xC349, + 0xD648, 0xC8A8, 0xD649, 0xC8A9, 0xD64A, 0xC34A, 0xD64B, 0xC8AA, + 0xD64C, 0xC34B, 0xD64D, 0xC8AB, 0xD64E, 0xC34C, 0xD64F, 0xC34D, + 0xD650, 0xC34E, 0xD651, 0xC8AC, 0xD652, 0xC34F, 0xD653, 0xC350, + 0xD654, 0xC8AD, 0xD655, 0xC8AE, 0xD656, 0xC351, 0xD657, 0xC352, + 0xD658, 0xC8AF, 0xD659, 0xC353, 0xD65A, 0xC354, 0xD65B, 0xC355, + 0xD65C, 0xC8B0, 0xD65D, 0xC356, 0xD65E, 0xC357, 0xD65F, 0xC358, + 0xD660, 0xC359, 0xD661, 0xC35A, 0xD662, 0xC361, 0xD663, 0xC362, + 0xD664, 0xC363, 0xD665, 0xC364, 0xD666, 0xC365, 0xD667, 0xC8B1, + 0xD668, 0xC366, 0xD669, 0xC8B2, 0xD66A, 0xC367, 0xD66B, 0xC368, + 0xD66C, 0xC369, 0xD66D, 0xC36A, 0xD66E, 0xC36B, 0xD66F, 0xC36C, + 0xD670, 0xC8B3, 0xD671, 0xC8B4, 0xD672, 0xC36D, 0xD673, 0xC36E, + 0xD674, 0xC8B5, 0xD675, 0xC36F, 0xD676, 0xC370, 0xD677, 0xC371, + 0xD678, 0xC372, 0xD679, 0xC373, 0xD67A, 0xC374, 0xD67B, 0xC375, + 0xD67C, 0xC376, 0xD67D, 0xC377, 0xD67E, 0xC378, 0xD67F, 0xC379, + 0xD680, 0xC37A, 0xD681, 0xC381, 0xD682, 0xC382, 0xD683, 0xC8B6, + 0xD684, 0xC383, 0xD685, 0xC8B7, 0xD686, 0xC384, 0xD687, 0xC385, + 0xD688, 0xC386, 0xD689, 0xC387, 0xD68A, 0xC388, 0xD68B, 0xC389, + 0xD68C, 0xC8B8, 0xD68D, 0xC8B9, 0xD68E, 0xC38A, 0xD68F, 0xC38B, + 0xD690, 0xC8BA, 0xD691, 0xC38C, 0xD692, 0xC38D, 0xD693, 0xC38E, + 0xD694, 0xC8BB, 0xD695, 0xC38F, 0xD696, 0xC390, 0xD697, 0xC391, + 0xD698, 0xC392, 0xD699, 0xC393, 0xD69A, 0xC394, 0xD69B, 0xC395, + 0xD69C, 0xC396, 0xD69D, 0xC8BC, 0xD69E, 0xC397, 0xD69F, 0xC8BD, + 0xD6A0, 0xC398, 0xD6A1, 0xC8BE, 0xD6A2, 0xC399, 0xD6A3, 0xC39A, + 0xD6A4, 0xC39B, 0xD6A5, 0xC39C, 0xD6A6, 0xC39D, 0xD6A7, 0xC39E, + 0xD6A8, 0xC8BF, 0xD6A9, 0xC39F, 0xD6AA, 0xC3A0, 0xD6AB, 0xC441, + 0xD6AC, 0xC8C0, 0xD6AD, 0xC442, 0xD6AE, 0xC443, 0xD6AF, 0xC444, + 0xD6B0, 0xC8C1, 0xD6B1, 0xC445, 0xD6B2, 0xC446, 0xD6B3, 0xC447, + 0xD6B4, 0xC448, 0xD6B5, 0xC449, 0xD6B6, 0xC44A, 0xD6B7, 0xC44B, + 0xD6B8, 0xC44C, 0xD6B9, 0xC8C2, 0xD6BA, 0xC44D, 0xD6BB, 0xC8C3, + 0xD6BC, 0xC44E, 0xD6BD, 0xC44F, 0xD6BE, 0xC450, 0xD6BF, 0xC451, + 0xD6C0, 0xC452, 0xD6C1, 0xC453, 0xD6C2, 0xC454, 0xD6C3, 0xC455, + 0xD6C4, 0xC8C4, 0xD6C5, 0xC8C5, 0xD6C6, 0xC456, 0xD6C7, 0xC457, + 0xD6C8, 0xC8C6, 0xD6C9, 0xC458, 0xD6CA, 0xC459, 0xD6CB, 0xC45A, + 0xD6CC, 0xC8C7, 0xD6CD, 0xC461, 0xD6CE, 0xC462, 0xD6CF, 0xC463, + 0xD6D0, 0xC464, 0xD6D1, 0xC8C8, 0xD6D2, 0xC465, 0xD6D3, 0xC466, + 0xD6D4, 0xC8C9, 0xD6D5, 0xC467, 0xD6D6, 0xC468, 0xD6D7, 0xC8CA, + 0xD6D8, 0xC469, 0xD6D9, 0xC8CB, 0xD6DA, 0xC46A, 0xD6DB, 0xC46B, + 0xD6DC, 0xC46C, 0xD6DD, 0xC46D, 0xD6DE, 0xC46E, 0xD6DF, 0xC46F, + 0xD6E0, 0xC8CC, 0xD6E1, 0xC470, 0xD6E2, 0xC471, 0xD6E3, 0xC472, + 0xD6E4, 0xC8CD, 0xD6E5, 0xC473, 0xD6E6, 0xC474, 0xD6E7, 0xC475, + 0xD6E8, 0xC8CE, 0xD6E9, 0xC476, 0xD6EA, 0xC477, 0xD6EB, 0xC478, + 0xD6EC, 0xC479, 0xD6ED, 0xC47A, 0xD6EE, 0xC481, 0xD6EF, 0xC482, + 0xD6F0, 0xC8CF, 0xD6F1, 0xC483, 0xD6F2, 0xC484, 0xD6F3, 0xC485, + 0xD6F4, 0xC486, 0xD6F5, 0xC8D0, 0xD6F6, 0xC487, 0xD6F7, 0xC488, + 0xD6F8, 0xC489, 0xD6F9, 0xC48A, 0xD6FA, 0xC48B, 0xD6FB, 0xC48C, + 0xD6FC, 0xC8D1, 0xD6FD, 0xC8D2, 0xD6FE, 0xC48D, 0xD6FF, 0xC48E, + 0xD700, 0xC8D3, 0xD701, 0xC48F, 0xD702, 0xC490, 0xD703, 0xC491, + 0xD704, 0xC8D4, 0xD705, 0xC492, 0xD706, 0xC493, 0xD707, 0xC494, + 0xD708, 0xC495, 0xD709, 0xC496, 0xD70A, 0xC497, 0xD70B, 0xC498, + 0xD70C, 0xC499, 0xD70D, 0xC49A, 0xD70E, 0xC49B, 0xD70F, 0xC49C, + 0xD710, 0xC49D, 0xD711, 0xC8D5, 0xD712, 0xC49E, 0xD713, 0xC49F, + 0xD714, 0xC4A0, 0xD715, 0xC541, 0xD716, 0xC542, 0xD717, 0xC543, + 0xD718, 0xC8D6, 0xD719, 0xC8D7, 0xD71A, 0xC544, 0xD71B, 0xC545, + 0xD71C, 0xC8D8, 0xD71D, 0xC546, 0xD71E, 0xC547, 0xD71F, 0xC548, + 0xD720, 0xC8D9, 0xD721, 0xC549, 0xD722, 0xC54A, 0xD723, 0xC54B, + 0xD724, 0xC54C, 0xD725, 0xC54D, 0xD726, 0xC54E, 0xD727, 0xC54F, + 0xD728, 0xC8DA, 0xD729, 0xC8DB, 0xD72A, 0xC550, 0xD72B, 0xC8DC, + 0xD72C, 0xC551, 0xD72D, 0xC8DD, 0xD72E, 0xC552, 0xD72F, 0xC553, + 0xD730, 0xC554, 0xD731, 0xC555, 0xD732, 0xC556, 0xD733, 0xC557, + 0xD734, 0xC8DE, 0xD735, 0xC8DF, 0xD736, 0xC558, 0xD737, 0xC559, + 0xD738, 0xC8E0, 0xD739, 0xC55A, 0xD73A, 0xC561, 0xD73B, 0xC562, + 0xD73C, 0xC8E1, 0xD73D, 0xC563, 0xD73E, 0xC564, 0xD73F, 0xC565, + 0xD740, 0xC566, 0xD741, 0xC567, 0xD742, 0xC568, 0xD743, 0xC569, + 0xD744, 0xC8E2, 0xD745, 0xC56A, 0xD746, 0xC56B, 0xD747, 0xC8E3, + 0xD748, 0xC56C, 0xD749, 0xC8E4, 0xD74A, 0xC56D, 0xD74B, 0xC56E, + 0xD74C, 0xC56F, 0xD74D, 0xC570, 0xD74E, 0xC571, 0xD74F, 0xC572, + 0xD750, 0xC8E5, 0xD751, 0xC8E6, 0xD752, 0xC573, 0xD753, 0xC574, + 0xD754, 0xC8E7, 0xD755, 0xC575, 0xD756, 0xC8E8, 0xD757, 0xC8E9, + 0xD758, 0xC8EA, 0xD759, 0xC8EB, 0xD75A, 0xC576, 0xD75B, 0xC577, + 0xD75C, 0xC578, 0xD75D, 0xC579, 0xD75E, 0xC57A, 0xD75F, 0xC581, + 0xD760, 0xC8EC, 0xD761, 0xC8ED, 0xD762, 0xC582, 0xD763, 0xC8EE, + 0xD764, 0xC583, 0xD765, 0xC8EF, 0xD766, 0xC584, 0xD767, 0xC585, + 0xD768, 0xC586, 0xD769, 0xC8F0, 0xD76A, 0xC587, 0xD76B, 0xC588, + 0xD76C, 0xC8F1, 0xD76D, 0xC589, 0xD76E, 0xC58A, 0xD76F, 0xC58B, + 0xD770, 0xC8F2, 0xD771, 0xC58C, 0xD772, 0xC58D, 0xD773, 0xC58E, + 0xD774, 0xC8F3, 0xD775, 0xC58F, 0xD776, 0xC590, 0xD777, 0xC591, + 0xD778, 0xC592, 0xD779, 0xC593, 0xD77A, 0xC594, 0xD77B, 0xC595, + 0xD77C, 0xC8F4, 0xD77D, 0xC8F5, 0xD77E, 0xC596, 0xD77F, 0xC597, + 0xD780, 0xC598, 0xD781, 0xC8F6, 0xD782, 0xC599, 0xD783, 0xC59A, + 0xD784, 0xC59B, 0xD785, 0xC59C, 0xD786, 0xC59D, 0xD787, 0xC59E, + 0xD788, 0xC8F7, 0xD789, 0xC8F8, 0xD78A, 0xC59F, 0xD78B, 0xC5A0, + 0xD78C, 0xC8F9, 0xD78D, 0xC641, 0xD78E, 0xC642, 0xD78F, 0xC643, + 0xD790, 0xC8FA, 0xD791, 0xC644, 0xD792, 0xC645, 0xD793, 0xC646, + 0xD794, 0xC647, 0xD795, 0xC648, 0xD796, 0xC649, 0xD797, 0xC64A, + 0xD798, 0xC8FB, 0xD799, 0xC8FC, 0xD79A, 0xC64B, 0xD79B, 0xC8FD, + 0xD79C, 0xC64C, 0xD79D, 0xC8FE, 0xD79E, 0xC64D, 0xD79F, 0xC64E, + 0xD7A0, 0xC64F, 0xD7A1, 0xC650, 0xD7A2, 0xC651, 0xD7A3, 0xC652, + 0xF900, 0xCBD0, 0xF901, 0xCBD6, 0xF902, 0xCBE7, 0xF903, 0xCDCF, + 0xF904, 0xCDE8, 0xF905, 0xCEAD, 0xF906, 0xCFFB, 0xF907, 0xD0A2, + 0xF908, 0xD0B8, 0xF909, 0xD0D0, 0xF90A, 0xD0DD, 0xF90B, 0xD1D4, + 0xF90C, 0xD1D5, 0xF90D, 0xD1D8, 0xF90E, 0xD1DB, 0xF90F, 0xD1DC, + 0xF910, 0xD1DD, 0xF911, 0xD1DE, 0xF912, 0xD1DF, 0xF913, 0xD1E0, + 0xF914, 0xD1E2, 0xF915, 0xD1E3, 0xF916, 0xD1E4, 0xF917, 0xD1E5, + 0xF918, 0xD1E6, 0xF919, 0xD1E8, 0xF91A, 0xD1E9, 0xF91B, 0xD1EA, + 0xF91C, 0xD1EB, 0xF91D, 0xD1ED, 0xF91E, 0xD1EF, 0xF91F, 0xD1F0, + 0xF920, 0xD1F2, 0xF921, 0xD1F6, 0xF922, 0xD1FA, 0xF923, 0xD1FC, + 0xF924, 0xD1FD, 0xF925, 0xD1FE, 0xF926, 0xD2A2, 0xF927, 0xD2A3, + 0xF928, 0xD2A7, 0xF929, 0xD2A8, 0xF92A, 0xD2A9, 0xF92B, 0xD2AA, + 0xF92C, 0xD2AB, 0xF92D, 0xD2AD, 0xF92E, 0xD2B2, 0xF92F, 0xD2BE, + 0xF930, 0xD2C2, 0xF931, 0xD2C3, 0xF932, 0xD2C4, 0xF933, 0xD2C6, + 0xF934, 0xD2C7, 0xF935, 0xD2C8, 0xF936, 0xD2C9, 0xF937, 0xD2CA, + 0xF938, 0xD2CB, 0xF939, 0xD2CD, 0xF93A, 0xD2CE, 0xF93B, 0xD2CF, + 0xF93C, 0xD2D0, 0xF93D, 0xD2D1, 0xF93E, 0xD2D2, 0xF93F, 0xD2D3, + 0xF940, 0xD2D4, 0xF941, 0xD2D5, 0xF942, 0xD2D6, 0xF943, 0xD2D7, + 0xF944, 0xD2D9, 0xF945, 0xD2DA, 0xF946, 0xD2DE, 0xF947, 0xD2DF, + 0xF948, 0xD2E1, 0xF949, 0xD2E2, 0xF94A, 0xD2E4, 0xF94B, 0xD2E5, + 0xF94C, 0xD2E6, 0xF94D, 0xD2E7, 0xF94E, 0xD2E8, 0xF94F, 0xD2E9, + 0xF950, 0xD2EA, 0xF951, 0xD2EB, 0xF952, 0xD2F0, 0xF953, 0xD2F1, + 0xF954, 0xD2F2, 0xF955, 0xD2F3, 0xF956, 0xD2F4, 0xF957, 0xD2F5, + 0xF958, 0xD2F7, 0xF959, 0xD2F8, 0xF95A, 0xD4E6, 0xF95B, 0xD4FC, + 0xF95C, 0xD5A5, 0xF95D, 0xD5AB, 0xF95E, 0xD5AE, 0xF95F, 0xD6B8, + 0xF960, 0xD6CD, 0xF961, 0xD7CB, 0xF962, 0xD7E4, 0xF963, 0xDBC5, + 0xF964, 0xDBE4, 0xF965, 0xDCA5, 0xF966, 0xDDA5, 0xF967, 0xDDD5, + 0xF968, 0xDDF4, 0xF969, 0xDEFC, 0xF96A, 0xDEFE, 0xF96B, 0xDFB3, + 0xF96C, 0xDFE1, 0xF96D, 0xDFE8, 0xF96E, 0xE0F1, 0xF96F, 0xE1AD, + 0xF970, 0xE1ED, 0xF971, 0xE3F5, 0xF972, 0xE4A1, 0xF973, 0xE4A9, + 0xF974, 0xE5AE, 0xF975, 0xE5B1, 0xF976, 0xE5B2, 0xF977, 0xE5B9, + 0xF978, 0xE5BB, 0xF979, 0xE5BC, 0xF97A, 0xE5C4, 0xF97B, 0xE5CE, + 0xF97C, 0xE5D0, 0xF97D, 0xE5D2, 0xF97E, 0xE5D6, 0xF97F, 0xE5FA, + 0xF980, 0xE5FB, 0xF981, 0xE5FC, 0xF982, 0xE5FE, 0xF983, 0xE6A1, + 0xF984, 0xE6A4, 0xF985, 0xE6A7, 0xF986, 0xE6AD, 0xF987, 0xE6AF, + 0xF988, 0xE6B0, 0xF989, 0xE6B1, 0xF98A, 0xE6B3, 0xF98B, 0xE6B7, + 0xF98C, 0xE6B8, 0xF98D, 0xE6BC, 0xF98E, 0xE6C4, 0xF98F, 0xE6C6, + 0xF990, 0xE6C7, 0xF991, 0xE6CA, 0xF992, 0xE6D2, 0xF993, 0xE6D6, + 0xF994, 0xE6D9, 0xF995, 0xE6DC, 0xF996, 0xE6DF, 0xF997, 0xE6E1, + 0xF998, 0xE6E4, 0xF999, 0xE6E5, 0xF99A, 0xE6E6, 0xF99B, 0xE6E8, + 0xF99C, 0xE6EA, 0xF99D, 0xE6EB, 0xF99E, 0xE6EC, 0xF99F, 0xE6EF, + 0xF9A0, 0xE6F1, 0xF9A1, 0xE6F2, 0xF9A2, 0xE6F5, 0xF9A3, 0xE6F6, + 0xF9A4, 0xE6F7, 0xF9A5, 0xE6F9, 0xF9A6, 0xE7A1, 0xF9A7, 0xE7A6, + 0xF9A8, 0xE7A9, 0xF9A9, 0xE7AA, 0xF9AA, 0xE7AC, 0xF9AB, 0xE7AD, + 0xF9AC, 0xE7B0, 0xF9AD, 0xE7BF, 0xF9AE, 0xE7C1, 0xF9AF, 0xE7C6, + 0xF9B0, 0xE7C7, 0xF9B1, 0xE7CB, 0xF9B2, 0xE7CD, 0xF9B3, 0xE7CF, + 0xF9B4, 0xE7D0, 0xF9B5, 0xE7D3, 0xF9B6, 0xE7DF, 0xF9B7, 0xE7E4, + 0xF9B8, 0xE7E6, 0xF9B9, 0xE7F7, 0xF9BA, 0xE8E7, 0xF9BB, 0xE8E8, + 0xF9BC, 0xE8F0, 0xF9BD, 0xE8F1, 0xF9BE, 0xE8F7, 0xF9BF, 0xE8F9, + 0xF9C0, 0xE8FB, 0xF9C1, 0xE8FE, 0xF9C2, 0xE9A7, 0xF9C3, 0xE9AC, + 0xF9C4, 0xE9CC, 0xF9C5, 0xE9F7, 0xF9C6, 0xEAC1, 0xF9C7, 0xEAE5, + 0xF9C8, 0xEAF4, 0xF9C9, 0xEAF7, 0xF9CA, 0xEAFC, 0xF9CB, 0xEAFE, + 0xF9CC, 0xEBA4, 0xF9CD, 0xEBA7, 0xF9CE, 0xEBA9, 0xF9CF, 0xEBAA, + 0xF9D0, 0xEBBA, 0xF9D1, 0xEBBB, 0xF9D2, 0xEBBD, 0xF9D3, 0xEBC1, + 0xF9D4, 0xEBC2, 0xF9D5, 0xEBC6, 0xF9D6, 0xEBC7, 0xF9D7, 0xEBCC, + 0xF9D8, 0xEBCF, 0xF9D9, 0xEBD0, 0xF9DA, 0xEBD1, 0xF9DB, 0xEBD2, + 0xF9DC, 0xEBD8, 0xF9DD, 0xECA6, 0xF9DE, 0xECA7, 0xF9DF, 0xECAA, + 0xF9E0, 0xECAF, 0xF9E1, 0xECB0, 0xF9E2, 0xECB1, 0xF9E3, 0xECB2, + 0xF9E4, 0xECB5, 0xF9E5, 0xECB8, 0xF9E6, 0xECBA, 0xF9E7, 0xECC0, + 0xF9E8, 0xECC1, 0xF9E9, 0xECC5, 0xF9EA, 0xECC6, 0xF9EB, 0xECC9, + 0xF9EC, 0xECCA, 0xF9ED, 0xECD5, 0xF9EE, 0xECDD, 0xF9EF, 0xECDE, + 0xF9F0, 0xECE1, 0xF9F1, 0xECE4, 0xF9F2, 0xECE7, 0xF9F3, 0xECE8, + 0xF9F4, 0xECF7, 0xF9F5, 0xECF8, 0xF9F6, 0xECFA, 0xF9F7, 0xEDA1, + 0xF9F8, 0xEDA2, 0xF9F9, 0xEDA3, 0xF9FA, 0xEDEE, 0xF9FB, 0xEEDB, + 0xF9FC, 0xF2BD, 0xF9FD, 0xF2FA, 0xF9FE, 0xF3B1, 0xF9FF, 0xF4A7, + 0xFA00, 0xF4EE, 0xFA01, 0xF6F4, 0xFA02, 0xF6F6, 0xFA03, 0xF7B8, + 0xFA04, 0xF7C8, 0xFA05, 0xF7D3, 0xFA06, 0xF8DB, 0xFA07, 0xF8F0, + 0xFA08, 0xFAA1, 0xFA09, 0xFAA2, 0xFA0A, 0xFAE6, 0xFA0B, 0xFCA9, + 0xFF01, 0xA3A1, 0xFF02, 0xA3A2, 0xFF03, 0xA3A3, 0xFF04, 0xA3A4, + 0xFF05, 0xA3A5, 0xFF06, 0xA3A6, 0xFF07, 0xA3A7, 0xFF08, 0xA3A8, + 0xFF09, 0xA3A9, 0xFF0A, 0xA3AA, 0xFF0B, 0xA3AB, 0xFF0C, 0xA3AC, + 0xFF0D, 0xA3AD, 0xFF0E, 0xA3AE, 0xFF0F, 0xA3AF, 0xFF10, 0xA3B0, + 0xFF11, 0xA3B1, 0xFF12, 0xA3B2, 0xFF13, 0xA3B3, 0xFF14, 0xA3B4, + 0xFF15, 0xA3B5, 0xFF16, 0xA3B6, 0xFF17, 0xA3B7, 0xFF18, 0xA3B8, + 0xFF19, 0xA3B9, 0xFF1A, 0xA3BA, 0xFF1B, 0xA3BB, 0xFF1C, 0xA3BC, + 0xFF1D, 0xA3BD, 0xFF1E, 0xA3BE, 0xFF1F, 0xA3BF, 0xFF20, 0xA3C0, + 0xFF21, 0xA3C1, 0xFF22, 0xA3C2, 0xFF23, 0xA3C3, 0xFF24, 0xA3C4, + 0xFF25, 0xA3C5, 0xFF26, 0xA3C6, 0xFF27, 0xA3C7, 0xFF28, 0xA3C8, + 0xFF29, 0xA3C9, 0xFF2A, 0xA3CA, 0xFF2B, 0xA3CB, 0xFF2C, 0xA3CC, + 0xFF2D, 0xA3CD, 0xFF2E, 0xA3CE, 0xFF2F, 0xA3CF, 0xFF30, 0xA3D0, + 0xFF31, 0xA3D1, 0xFF32, 0xA3D2, 0xFF33, 0xA3D3, 0xFF34, 0xA3D4, + 0xFF35, 0xA3D5, 0xFF36, 0xA3D6, 0xFF37, 0xA3D7, 0xFF38, 0xA3D8, + 0xFF39, 0xA3D9, 0xFF3A, 0xA3DA, 0xFF3B, 0xA3DB, 0xFF3C, 0xA1AC, + 0xFF3D, 0xA3DD, 0xFF3E, 0xA3DE, 0xFF3F, 0xA3DF, 0xFF40, 0xA3E0, + 0xFF41, 0xA3E1, 0xFF42, 0xA3E2, 0xFF43, 0xA3E3, 0xFF44, 0xA3E4, + 0xFF45, 0xA3E5, 0xFF46, 0xA3E6, 0xFF47, 0xA3E7, 0xFF48, 0xA3E8, + 0xFF49, 0xA3E9, 0xFF4A, 0xA3EA, 0xFF4B, 0xA3EB, 0xFF4C, 0xA3EC, + 0xFF4D, 0xA3ED, 0xFF4E, 0xA3EE, 0xFF4F, 0xA3EF, 0xFF50, 0xA3F0, + 0xFF51, 0xA3F1, 0xFF52, 0xA3F2, 0xFF53, 0xA3F3, 0xFF54, 0xA3F4, + 0xFF55, 0xA3F5, 0xFF56, 0xA3F6, 0xFF57, 0xA3F7, 0xFF58, 0xA3F8, + 0xFF59, 0xA3F9, 0xFF5A, 0xA3FA, 0xFF5B, 0xA3FB, 0xFF5C, 0xA3FC, + 0xFF5D, 0xA3FD, 0xFF5E, 0xA2A6, 0xFFE0, 0xA1CB, 0xFFE1, 0xA1CC, + 0xFFE2, 0xA1FE, 0xFFE3, 0xA3FE, 0xFFE5, 0xA1CD, 0xFFE6, 0xA3DC, + 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0x8141, 0xAC02, 0x8142, 0xAC03, 0x8143, 0xAC05, 0x8144, 0xAC06, + 0x8145, 0xAC0B, 0x8146, 0xAC0C, 0x8147, 0xAC0D, 0x8148, 0xAC0E, + 0x8149, 0xAC0F, 0x814A, 0xAC18, 0x814B, 0xAC1E, 0x814C, 0xAC1F, + 0x814D, 0xAC21, 0x814E, 0xAC22, 0x814F, 0xAC23, 0x8150, 0xAC25, + 0x8151, 0xAC26, 0x8152, 0xAC27, 0x8153, 0xAC28, 0x8154, 0xAC29, + 0x8155, 0xAC2A, 0x8156, 0xAC2B, 0x8157, 0xAC2E, 0x8158, 0xAC32, + 0x8159, 0xAC33, 0x815A, 0xAC34, 0x8161, 0xAC35, 0x8162, 0xAC36, + 0x8163, 0xAC37, 0x8164, 0xAC3A, 0x8165, 0xAC3B, 0x8166, 0xAC3D, + 0x8167, 0xAC3E, 0x8168, 0xAC3F, 0x8169, 0xAC41, 0x816A, 0xAC42, + 0x816B, 0xAC43, 0x816C, 0xAC44, 0x816D, 0xAC45, 0x816E, 0xAC46, + 0x816F, 0xAC47, 0x8170, 0xAC48, 0x8171, 0xAC49, 0x8172, 0xAC4A, + 0x8173, 0xAC4C, 0x8174, 0xAC4E, 0x8175, 0xAC4F, 0x8176, 0xAC50, + 0x8177, 0xAC51, 0x8178, 0xAC52, 0x8179, 0xAC53, 0x817A, 0xAC55, + 0x8181, 0xAC56, 0x8182, 0xAC57, 0x8183, 0xAC59, 0x8184, 0xAC5A, + 0x8185, 0xAC5B, 0x8186, 0xAC5D, 0x8187, 0xAC5E, 0x8188, 0xAC5F, + 0x8189, 0xAC60, 0x818A, 0xAC61, 0x818B, 0xAC62, 0x818C, 0xAC63, + 0x818D, 0xAC64, 0x818E, 0xAC65, 0x818F, 0xAC66, 0x8190, 0xAC67, + 0x8191, 0xAC68, 0x8192, 0xAC69, 0x8193, 0xAC6A, 0x8194, 0xAC6B, + 0x8195, 0xAC6C, 0x8196, 0xAC6D, 0x8197, 0xAC6E, 0x8198, 0xAC6F, + 0x8199, 0xAC72, 0x819A, 0xAC73, 0x819B, 0xAC75, 0x819C, 0xAC76, + 0x819D, 0xAC79, 0x819E, 0xAC7B, 0x819F, 0xAC7C, 0x81A0, 0xAC7D, + 0x81A1, 0xAC7E, 0x81A2, 0xAC7F, 0x81A3, 0xAC82, 0x81A4, 0xAC87, + 0x81A5, 0xAC88, 0x81A6, 0xAC8D, 0x81A7, 0xAC8E, 0x81A8, 0xAC8F, + 0x81A9, 0xAC91, 0x81AA, 0xAC92, 0x81AB, 0xAC93, 0x81AC, 0xAC95, + 0x81AD, 0xAC96, 0x81AE, 0xAC97, 0x81AF, 0xAC98, 0x81B0, 0xAC99, + 0x81B1, 0xAC9A, 0x81B2, 0xAC9B, 0x81B3, 0xAC9E, 0x81B4, 0xACA2, + 0x81B5, 0xACA3, 0x81B6, 0xACA4, 0x81B7, 0xACA5, 0x81B8, 0xACA6, + 0x81B9, 0xACA7, 0x81BA, 0xACAB, 0x81BB, 0xACAD, 0x81BC, 0xACAE, + 0x81BD, 0xACB1, 0x81BE, 0xACB2, 0x81BF, 0xACB3, 0x81C0, 0xACB4, + 0x81C1, 0xACB5, 0x81C2, 0xACB6, 0x81C3, 0xACB7, 0x81C4, 0xACBA, + 0x81C5, 0xACBE, 0x81C6, 0xACBF, 0x81C7, 0xACC0, 0x81C8, 0xACC2, + 0x81C9, 0xACC3, 0x81CA, 0xACC5, 0x81CB, 0xACC6, 0x81CC, 0xACC7, + 0x81CD, 0xACC9, 0x81CE, 0xACCA, 0x81CF, 0xACCB, 0x81D0, 0xACCD, + 0x81D1, 0xACCE, 0x81D2, 0xACCF, 0x81D3, 0xACD0, 0x81D4, 0xACD1, + 0x81D5, 0xACD2, 0x81D6, 0xACD3, 0x81D7, 0xACD4, 0x81D8, 0xACD6, + 0x81D9, 0xACD8, 0x81DA, 0xACD9, 0x81DB, 0xACDA, 0x81DC, 0xACDB, + 0x81DD, 0xACDC, 0x81DE, 0xACDD, 0x81DF, 0xACDE, 0x81E0, 0xACDF, + 0x81E1, 0xACE2, 0x81E2, 0xACE3, 0x81E3, 0xACE5, 0x81E4, 0xACE6, + 0x81E5, 0xACE9, 0x81E6, 0xACEB, 0x81E7, 0xACED, 0x81E8, 0xACEE, + 0x81E9, 0xACF2, 0x81EA, 0xACF4, 0x81EB, 0xACF7, 0x81EC, 0xACF8, + 0x81ED, 0xACF9, 0x81EE, 0xACFA, 0x81EF, 0xACFB, 0x81F0, 0xACFE, + 0x81F1, 0xACFF, 0x81F2, 0xAD01, 0x81F3, 0xAD02, 0x81F4, 0xAD03, + 0x81F5, 0xAD05, 0x81F6, 0xAD07, 0x81F7, 0xAD08, 0x81F8, 0xAD09, + 0x81F9, 0xAD0A, 0x81FA, 0xAD0B, 0x81FB, 0xAD0E, 0x81FC, 0xAD10, + 0x81FD, 0xAD12, 0x81FE, 0xAD13, 0x8241, 0xAD14, 0x8242, 0xAD15, + 0x8243, 0xAD16, 0x8244, 0xAD17, 0x8245, 0xAD19, 0x8246, 0xAD1A, + 0x8247, 0xAD1B, 0x8248, 0xAD1D, 0x8249, 0xAD1E, 0x824A, 0xAD1F, + 0x824B, 0xAD21, 0x824C, 0xAD22, 0x824D, 0xAD23, 0x824E, 0xAD24, + 0x824F, 0xAD25, 0x8250, 0xAD26, 0x8251, 0xAD27, 0x8252, 0xAD28, + 0x8253, 0xAD2A, 0x8254, 0xAD2B, 0x8255, 0xAD2E, 0x8256, 0xAD2F, + 0x8257, 0xAD30, 0x8258, 0xAD31, 0x8259, 0xAD32, 0x825A, 0xAD33, + 0x8261, 0xAD36, 0x8262, 0xAD37, 0x8263, 0xAD39, 0x8264, 0xAD3A, + 0x8265, 0xAD3B, 0x8266, 0xAD3D, 0x8267, 0xAD3E, 0x8268, 0xAD3F, + 0x8269, 0xAD40, 0x826A, 0xAD41, 0x826B, 0xAD42, 0x826C, 0xAD43, + 0x826D, 0xAD46, 0x826E, 0xAD48, 0x826F, 0xAD4A, 0x8270, 0xAD4B, + 0x8271, 0xAD4C, 0x8272, 0xAD4D, 0x8273, 0xAD4E, 0x8274, 0xAD4F, + 0x8275, 0xAD51, 0x8276, 0xAD52, 0x8277, 0xAD53, 0x8278, 0xAD55, + 0x8279, 0xAD56, 0x827A, 0xAD57, 0x8281, 0xAD59, 0x8282, 0xAD5A, + 0x8283, 0xAD5B, 0x8284, 0xAD5C, 0x8285, 0xAD5D, 0x8286, 0xAD5E, + 0x8287, 0xAD5F, 0x8288, 0xAD60, 0x8289, 0xAD62, 0x828A, 0xAD64, + 0x828B, 0xAD65, 0x828C, 0xAD66, 0x828D, 0xAD67, 0x828E, 0xAD68, + 0x828F, 0xAD69, 0x8290, 0xAD6A, 0x8291, 0xAD6B, 0x8292, 0xAD6E, + 0x8293, 0xAD6F, 0x8294, 0xAD71, 0x8295, 0xAD72, 0x8296, 0xAD77, + 0x8297, 0xAD78, 0x8298, 0xAD79, 0x8299, 0xAD7A, 0x829A, 0xAD7E, + 0x829B, 0xAD80, 0x829C, 0xAD83, 0x829D, 0xAD84, 0x829E, 0xAD85, + 0x829F, 0xAD86, 0x82A0, 0xAD87, 0x82A1, 0xAD8A, 0x82A2, 0xAD8B, + 0x82A3, 0xAD8D, 0x82A4, 0xAD8E, 0x82A5, 0xAD8F, 0x82A6, 0xAD91, + 0x82A7, 0xAD92, 0x82A8, 0xAD93, 0x82A9, 0xAD94, 0x82AA, 0xAD95, + 0x82AB, 0xAD96, 0x82AC, 0xAD97, 0x82AD, 0xAD98, 0x82AE, 0xAD99, + 0x82AF, 0xAD9A, 0x82B0, 0xAD9B, 0x82B1, 0xAD9E, 0x82B2, 0xAD9F, + 0x82B3, 0xADA0, 0x82B4, 0xADA1, 0x82B5, 0xADA2, 0x82B6, 0xADA3, + 0x82B7, 0xADA5, 0x82B8, 0xADA6, 0x82B9, 0xADA7, 0x82BA, 0xADA8, + 0x82BB, 0xADA9, 0x82BC, 0xADAA, 0x82BD, 0xADAB, 0x82BE, 0xADAC, + 0x82BF, 0xADAD, 0x82C0, 0xADAE, 0x82C1, 0xADAF, 0x82C2, 0xADB0, + 0x82C3, 0xADB1, 0x82C4, 0xADB2, 0x82C5, 0xADB3, 0x82C6, 0xADB4, + 0x82C7, 0xADB5, 0x82C8, 0xADB6, 0x82C9, 0xADB8, 0x82CA, 0xADB9, + 0x82CB, 0xADBA, 0x82CC, 0xADBB, 0x82CD, 0xADBC, 0x82CE, 0xADBD, + 0x82CF, 0xADBE, 0x82D0, 0xADBF, 0x82D1, 0xADC2, 0x82D2, 0xADC3, + 0x82D3, 0xADC5, 0x82D4, 0xADC6, 0x82D5, 0xADC7, 0x82D6, 0xADC9, + 0x82D7, 0xADCA, 0x82D8, 0xADCB, 0x82D9, 0xADCC, 0x82DA, 0xADCD, + 0x82DB, 0xADCE, 0x82DC, 0xADCF, 0x82DD, 0xADD2, 0x82DE, 0xADD4, + 0x82DF, 0xADD5, 0x82E0, 0xADD6, 0x82E1, 0xADD7, 0x82E2, 0xADD8, + 0x82E3, 0xADD9, 0x82E4, 0xADDA, 0x82E5, 0xADDB, 0x82E6, 0xADDD, + 0x82E7, 0xADDE, 0x82E8, 0xADDF, 0x82E9, 0xADE1, 0x82EA, 0xADE2, + 0x82EB, 0xADE3, 0x82EC, 0xADE5, 0x82ED, 0xADE6, 0x82EE, 0xADE7, + 0x82EF, 0xADE8, 0x82F0, 0xADE9, 0x82F1, 0xADEA, 0x82F2, 0xADEB, + 0x82F3, 0xADEC, 0x82F4, 0xADED, 0x82F5, 0xADEE, 0x82F6, 0xADEF, + 0x82F7, 0xADF0, 0x82F8, 0xADF1, 0x82F9, 0xADF2, 0x82FA, 0xADF3, + 0x82FB, 0xADF4, 0x82FC, 0xADF5, 0x82FD, 0xADF6, 0x82FE, 0xADF7, + 0x8341, 0xADFA, 0x8342, 0xADFB, 0x8343, 0xADFD, 0x8344, 0xADFE, + 0x8345, 0xAE02, 0x8346, 0xAE03, 0x8347, 0xAE04, 0x8348, 0xAE05, + 0x8349, 0xAE06, 0x834A, 0xAE07, 0x834B, 0xAE0A, 0x834C, 0xAE0C, + 0x834D, 0xAE0E, 0x834E, 0xAE0F, 0x834F, 0xAE10, 0x8350, 0xAE11, + 0x8351, 0xAE12, 0x8352, 0xAE13, 0x8353, 0xAE15, 0x8354, 0xAE16, + 0x8355, 0xAE17, 0x8356, 0xAE18, 0x8357, 0xAE19, 0x8358, 0xAE1A, + 0x8359, 0xAE1B, 0x835A, 0xAE1C, 0x8361, 0xAE1D, 0x8362, 0xAE1E, + 0x8363, 0xAE1F, 0x8364, 0xAE20, 0x8365, 0xAE21, 0x8366, 0xAE22, + 0x8367, 0xAE23, 0x8368, 0xAE24, 0x8369, 0xAE25, 0x836A, 0xAE26, + 0x836B, 0xAE27, 0x836C, 0xAE28, 0x836D, 0xAE29, 0x836E, 0xAE2A, + 0x836F, 0xAE2B, 0x8370, 0xAE2C, 0x8371, 0xAE2D, 0x8372, 0xAE2E, + 0x8373, 0xAE2F, 0x8374, 0xAE32, 0x8375, 0xAE33, 0x8376, 0xAE35, + 0x8377, 0xAE36, 0x8378, 0xAE39, 0x8379, 0xAE3B, 0x837A, 0xAE3C, + 0x8381, 0xAE3D, 0x8382, 0xAE3E, 0x8383, 0xAE3F, 0x8384, 0xAE42, + 0x8385, 0xAE44, 0x8386, 0xAE47, 0x8387, 0xAE48, 0x8388, 0xAE49, + 0x8389, 0xAE4B, 0x838A, 0xAE4F, 0x838B, 0xAE51, 0x838C, 0xAE52, + 0x838D, 0xAE53, 0x838E, 0xAE55, 0x838F, 0xAE57, 0x8390, 0xAE58, + 0x8391, 0xAE59, 0x8392, 0xAE5A, 0x8393, 0xAE5B, 0x8394, 0xAE5E, + 0x8395, 0xAE62, 0x8396, 0xAE63, 0x8397, 0xAE64, 0x8398, 0xAE66, + 0x8399, 0xAE67, 0x839A, 0xAE6A, 0x839B, 0xAE6B, 0x839C, 0xAE6D, + 0x839D, 0xAE6E, 0x839E, 0xAE6F, 0x839F, 0xAE71, 0x83A0, 0xAE72, + 0x83A1, 0xAE73, 0x83A2, 0xAE74, 0x83A3, 0xAE75, 0x83A4, 0xAE76, + 0x83A5, 0xAE77, 0x83A6, 0xAE7A, 0x83A7, 0xAE7E, 0x83A8, 0xAE7F, + 0x83A9, 0xAE80, 0x83AA, 0xAE81, 0x83AB, 0xAE82, 0x83AC, 0xAE83, + 0x83AD, 0xAE86, 0x83AE, 0xAE87, 0x83AF, 0xAE88, 0x83B0, 0xAE89, + 0x83B1, 0xAE8A, 0x83B2, 0xAE8B, 0x83B3, 0xAE8D, 0x83B4, 0xAE8E, + 0x83B5, 0xAE8F, 0x83B6, 0xAE90, 0x83B7, 0xAE91, 0x83B8, 0xAE92, + 0x83B9, 0xAE93, 0x83BA, 0xAE94, 0x83BB, 0xAE95, 0x83BC, 0xAE96, + 0x83BD, 0xAE97, 0x83BE, 0xAE98, 0x83BF, 0xAE99, 0x83C0, 0xAE9A, + 0x83C1, 0xAE9B, 0x83C2, 0xAE9C, 0x83C3, 0xAE9D, 0x83C4, 0xAE9E, + 0x83C5, 0xAE9F, 0x83C6, 0xAEA0, 0x83C7, 0xAEA1, 0x83C8, 0xAEA2, + 0x83C9, 0xAEA3, 0x83CA, 0xAEA4, 0x83CB, 0xAEA5, 0x83CC, 0xAEA6, + 0x83CD, 0xAEA7, 0x83CE, 0xAEA8, 0x83CF, 0xAEA9, 0x83D0, 0xAEAA, + 0x83D1, 0xAEAB, 0x83D2, 0xAEAC, 0x83D3, 0xAEAD, 0x83D4, 0xAEAE, + 0x83D5, 0xAEAF, 0x83D6, 0xAEB0, 0x83D7, 0xAEB1, 0x83D8, 0xAEB2, + 0x83D9, 0xAEB3, 0x83DA, 0xAEB4, 0x83DB, 0xAEB5, 0x83DC, 0xAEB6, + 0x83DD, 0xAEB7, 0x83DE, 0xAEB8, 0x83DF, 0xAEB9, 0x83E0, 0xAEBA, + 0x83E1, 0xAEBB, 0x83E2, 0xAEBF, 0x83E3, 0xAEC1, 0x83E4, 0xAEC2, + 0x83E5, 0xAEC3, 0x83E6, 0xAEC5, 0x83E7, 0xAEC6, 0x83E8, 0xAEC7, + 0x83E9, 0xAEC8, 0x83EA, 0xAEC9, 0x83EB, 0xAECA, 0x83EC, 0xAECB, + 0x83ED, 0xAECE, 0x83EE, 0xAED2, 0x83EF, 0xAED3, 0x83F0, 0xAED4, + 0x83F1, 0xAED5, 0x83F2, 0xAED6, 0x83F3, 0xAED7, 0x83F4, 0xAEDA, + 0x83F5, 0xAEDB, 0x83F6, 0xAEDD, 0x83F7, 0xAEDE, 0x83F8, 0xAEDF, + 0x83F9, 0xAEE0, 0x83FA, 0xAEE1, 0x83FB, 0xAEE2, 0x83FC, 0xAEE3, + 0x83FD, 0xAEE4, 0x83FE, 0xAEE5, 0x8441, 0xAEE6, 0x8442, 0xAEE7, + 0x8443, 0xAEE9, 0x8444, 0xAEEA, 0x8445, 0xAEEC, 0x8446, 0xAEEE, + 0x8447, 0xAEEF, 0x8448, 0xAEF0, 0x8449, 0xAEF1, 0x844A, 0xAEF2, + 0x844B, 0xAEF3, 0x844C, 0xAEF5, 0x844D, 0xAEF6, 0x844E, 0xAEF7, + 0x844F, 0xAEF9, 0x8450, 0xAEFA, 0x8451, 0xAEFB, 0x8452, 0xAEFD, + 0x8453, 0xAEFE, 0x8454, 0xAEFF, 0x8455, 0xAF00, 0x8456, 0xAF01, + 0x8457, 0xAF02, 0x8458, 0xAF03, 0x8459, 0xAF04, 0x845A, 0xAF05, + 0x8461, 0xAF06, 0x8462, 0xAF09, 0x8463, 0xAF0A, 0x8464, 0xAF0B, + 0x8465, 0xAF0C, 0x8466, 0xAF0E, 0x8467, 0xAF0F, 0x8468, 0xAF11, + 0x8469, 0xAF12, 0x846A, 0xAF13, 0x846B, 0xAF14, 0x846C, 0xAF15, + 0x846D, 0xAF16, 0x846E, 0xAF17, 0x846F, 0xAF18, 0x8470, 0xAF19, + 0x8471, 0xAF1A, 0x8472, 0xAF1B, 0x8473, 0xAF1C, 0x8474, 0xAF1D, + 0x8475, 0xAF1E, 0x8476, 0xAF1F, 0x8477, 0xAF20, 0x8478, 0xAF21, + 0x8479, 0xAF22, 0x847A, 0xAF23, 0x8481, 0xAF24, 0x8482, 0xAF25, + 0x8483, 0xAF26, 0x8484, 0xAF27, 0x8485, 0xAF28, 0x8486, 0xAF29, + 0x8487, 0xAF2A, 0x8488, 0xAF2B, 0x8489, 0xAF2E, 0x848A, 0xAF2F, + 0x848B, 0xAF31, 0x848C, 0xAF33, 0x848D, 0xAF35, 0x848E, 0xAF36, + 0x848F, 0xAF37, 0x8490, 0xAF38, 0x8491, 0xAF39, 0x8492, 0xAF3A, + 0x8493, 0xAF3B, 0x8494, 0xAF3E, 0x8495, 0xAF40, 0x8496, 0xAF44, + 0x8497, 0xAF45, 0x8498, 0xAF46, 0x8499, 0xAF47, 0x849A, 0xAF4A, + 0x849B, 0xAF4B, 0x849C, 0xAF4C, 0x849D, 0xAF4D, 0x849E, 0xAF4E, + 0x849F, 0xAF4F, 0x84A0, 0xAF51, 0x84A1, 0xAF52, 0x84A2, 0xAF53, + 0x84A3, 0xAF54, 0x84A4, 0xAF55, 0x84A5, 0xAF56, 0x84A6, 0xAF57, + 0x84A7, 0xAF58, 0x84A8, 0xAF59, 0x84A9, 0xAF5A, 0x84AA, 0xAF5B, + 0x84AB, 0xAF5E, 0x84AC, 0xAF5F, 0x84AD, 0xAF60, 0x84AE, 0xAF61, + 0x84AF, 0xAF62, 0x84B0, 0xAF63, 0x84B1, 0xAF66, 0x84B2, 0xAF67, + 0x84B3, 0xAF68, 0x84B4, 0xAF69, 0x84B5, 0xAF6A, 0x84B6, 0xAF6B, + 0x84B7, 0xAF6C, 0x84B8, 0xAF6D, 0x84B9, 0xAF6E, 0x84BA, 0xAF6F, + 0x84BB, 0xAF70, 0x84BC, 0xAF71, 0x84BD, 0xAF72, 0x84BE, 0xAF73, + 0x84BF, 0xAF74, 0x84C0, 0xAF75, 0x84C1, 0xAF76, 0x84C2, 0xAF77, + 0x84C3, 0xAF78, 0x84C4, 0xAF7A, 0x84C5, 0xAF7B, 0x84C6, 0xAF7C, + 0x84C7, 0xAF7D, 0x84C8, 0xAF7E, 0x84C9, 0xAF7F, 0x84CA, 0xAF81, + 0x84CB, 0xAF82, 0x84CC, 0xAF83, 0x84CD, 0xAF85, 0x84CE, 0xAF86, + 0x84CF, 0xAF87, 0x84D0, 0xAF89, 0x84D1, 0xAF8A, 0x84D2, 0xAF8B, + 0x84D3, 0xAF8C, 0x84D4, 0xAF8D, 0x84D5, 0xAF8E, 0x84D6, 0xAF8F, + 0x84D7, 0xAF92, 0x84D8, 0xAF93, 0x84D9, 0xAF94, 0x84DA, 0xAF96, + 0x84DB, 0xAF97, 0x84DC, 0xAF98, 0x84DD, 0xAF99, 0x84DE, 0xAF9A, + 0x84DF, 0xAF9B, 0x84E0, 0xAF9D, 0x84E1, 0xAF9E, 0x84E2, 0xAF9F, + 0x84E3, 0xAFA0, 0x84E4, 0xAFA1, 0x84E5, 0xAFA2, 0x84E6, 0xAFA3, + 0x84E7, 0xAFA4, 0x84E8, 0xAFA5, 0x84E9, 0xAFA6, 0x84EA, 0xAFA7, + 0x84EB, 0xAFA8, 0x84EC, 0xAFA9, 0x84ED, 0xAFAA, 0x84EE, 0xAFAB, + 0x84EF, 0xAFAC, 0x84F0, 0xAFAD, 0x84F1, 0xAFAE, 0x84F2, 0xAFAF, + 0x84F3, 0xAFB0, 0x84F4, 0xAFB1, 0x84F5, 0xAFB2, 0x84F6, 0xAFB3, + 0x84F7, 0xAFB4, 0x84F8, 0xAFB5, 0x84F9, 0xAFB6, 0x84FA, 0xAFB7, + 0x84FB, 0xAFBA, 0x84FC, 0xAFBB, 0x84FD, 0xAFBD, 0x84FE, 0xAFBE, + 0x8541, 0xAFBF, 0x8542, 0xAFC1, 0x8543, 0xAFC2, 0x8544, 0xAFC3, + 0x8545, 0xAFC4, 0x8546, 0xAFC5, 0x8547, 0xAFC6, 0x8548, 0xAFCA, + 0x8549, 0xAFCC, 0x854A, 0xAFCF, 0x854B, 0xAFD0, 0x854C, 0xAFD1, + 0x854D, 0xAFD2, 0x854E, 0xAFD3, 0x854F, 0xAFD5, 0x8550, 0xAFD6, + 0x8551, 0xAFD7, 0x8552, 0xAFD8, 0x8553, 0xAFD9, 0x8554, 0xAFDA, + 0x8555, 0xAFDB, 0x8556, 0xAFDD, 0x8557, 0xAFDE, 0x8558, 0xAFDF, + 0x8559, 0xAFE0, 0x855A, 0xAFE1, 0x8561, 0xAFE2, 0x8562, 0xAFE3, + 0x8563, 0xAFE4, 0x8564, 0xAFE5, 0x8565, 0xAFE6, 0x8566, 0xAFE7, + 0x8567, 0xAFEA, 0x8568, 0xAFEB, 0x8569, 0xAFEC, 0x856A, 0xAFED, + 0x856B, 0xAFEE, 0x856C, 0xAFEF, 0x856D, 0xAFF2, 0x856E, 0xAFF3, + 0x856F, 0xAFF5, 0x8570, 0xAFF6, 0x8571, 0xAFF7, 0x8572, 0xAFF9, + 0x8573, 0xAFFA, 0x8574, 0xAFFB, 0x8575, 0xAFFC, 0x8576, 0xAFFD, + 0x8577, 0xAFFE, 0x8578, 0xAFFF, 0x8579, 0xB002, 0x857A, 0xB003, + 0x8581, 0xB005, 0x8582, 0xB006, 0x8583, 0xB007, 0x8584, 0xB008, + 0x8585, 0xB009, 0x8586, 0xB00A, 0x8587, 0xB00B, 0x8588, 0xB00D, + 0x8589, 0xB00E, 0x858A, 0xB00F, 0x858B, 0xB011, 0x858C, 0xB012, + 0x858D, 0xB013, 0x858E, 0xB015, 0x858F, 0xB016, 0x8590, 0xB017, + 0x8591, 0xB018, 0x8592, 0xB019, 0x8593, 0xB01A, 0x8594, 0xB01B, + 0x8595, 0xB01E, 0x8596, 0xB01F, 0x8597, 0xB020, 0x8598, 0xB021, + 0x8599, 0xB022, 0x859A, 0xB023, 0x859B, 0xB024, 0x859C, 0xB025, + 0x859D, 0xB026, 0x859E, 0xB027, 0x859F, 0xB029, 0x85A0, 0xB02A, + 0x85A1, 0xB02B, 0x85A2, 0xB02C, 0x85A3, 0xB02D, 0x85A4, 0xB02E, + 0x85A5, 0xB02F, 0x85A6, 0xB030, 0x85A7, 0xB031, 0x85A8, 0xB032, + 0x85A9, 0xB033, 0x85AA, 0xB034, 0x85AB, 0xB035, 0x85AC, 0xB036, + 0x85AD, 0xB037, 0x85AE, 0xB038, 0x85AF, 0xB039, 0x85B0, 0xB03A, + 0x85B1, 0xB03B, 0x85B2, 0xB03C, 0x85B3, 0xB03D, 0x85B4, 0xB03E, + 0x85B5, 0xB03F, 0x85B6, 0xB040, 0x85B7, 0xB041, 0x85B8, 0xB042, + 0x85B9, 0xB043, 0x85BA, 0xB046, 0x85BB, 0xB047, 0x85BC, 0xB049, + 0x85BD, 0xB04B, 0x85BE, 0xB04D, 0x85BF, 0xB04F, 0x85C0, 0xB050, + 0x85C1, 0xB051, 0x85C2, 0xB052, 0x85C3, 0xB056, 0x85C4, 0xB058, + 0x85C5, 0xB05A, 0x85C6, 0xB05B, 0x85C7, 0xB05C, 0x85C8, 0xB05E, + 0x85C9, 0xB05F, 0x85CA, 0xB060, 0x85CB, 0xB061, 0x85CC, 0xB062, + 0x85CD, 0xB063, 0x85CE, 0xB064, 0x85CF, 0xB065, 0x85D0, 0xB066, + 0x85D1, 0xB067, 0x85D2, 0xB068, 0x85D3, 0xB069, 0x85D4, 0xB06A, + 0x85D5, 0xB06B, 0x85D6, 0xB06C, 0x85D7, 0xB06D, 0x85D8, 0xB06E, + 0x85D9, 0xB06F, 0x85DA, 0xB070, 0x85DB, 0xB071, 0x85DC, 0xB072, + 0x85DD, 0xB073, 0x85DE, 0xB074, 0x85DF, 0xB075, 0x85E0, 0xB076, + 0x85E1, 0xB077, 0x85E2, 0xB078, 0x85E3, 0xB079, 0x85E4, 0xB07A, + 0x85E5, 0xB07B, 0x85E6, 0xB07E, 0x85E7, 0xB07F, 0x85E8, 0xB081, + 0x85E9, 0xB082, 0x85EA, 0xB083, 0x85EB, 0xB085, 0x85EC, 0xB086, + 0x85ED, 0xB087, 0x85EE, 0xB088, 0x85EF, 0xB089, 0x85F0, 0xB08A, + 0x85F1, 0xB08B, 0x85F2, 0xB08E, 0x85F3, 0xB090, 0x85F4, 0xB092, + 0x85F5, 0xB093, 0x85F6, 0xB094, 0x85F7, 0xB095, 0x85F8, 0xB096, + 0x85F9, 0xB097, 0x85FA, 0xB09B, 0x85FB, 0xB09D, 0x85FC, 0xB09E, + 0x85FD, 0xB0A3, 0x85FE, 0xB0A4, 0x8641, 0xB0A5, 0x8642, 0xB0A6, + 0x8643, 0xB0A7, 0x8644, 0xB0AA, 0x8645, 0xB0B0, 0x8646, 0xB0B2, + 0x8647, 0xB0B6, 0x8648, 0xB0B7, 0x8649, 0xB0B9, 0x864A, 0xB0BA, + 0x864B, 0xB0BB, 0x864C, 0xB0BD, 0x864D, 0xB0BE, 0x864E, 0xB0BF, + 0x864F, 0xB0C0, 0x8650, 0xB0C1, 0x8651, 0xB0C2, 0x8652, 0xB0C3, + 0x8653, 0xB0C6, 0x8654, 0xB0CA, 0x8655, 0xB0CB, 0x8656, 0xB0CC, + 0x8657, 0xB0CD, 0x8658, 0xB0CE, 0x8659, 0xB0CF, 0x865A, 0xB0D2, + 0x8661, 0xB0D3, 0x8662, 0xB0D5, 0x8663, 0xB0D6, 0x8664, 0xB0D7, + 0x8665, 0xB0D9, 0x8666, 0xB0DA, 0x8667, 0xB0DB, 0x8668, 0xB0DC, + 0x8669, 0xB0DD, 0x866A, 0xB0DE, 0x866B, 0xB0DF, 0x866C, 0xB0E1, + 0x866D, 0xB0E2, 0x866E, 0xB0E3, 0x866F, 0xB0E4, 0x8670, 0xB0E6, + 0x8671, 0xB0E7, 0x8672, 0xB0E8, 0x8673, 0xB0E9, 0x8674, 0xB0EA, + 0x8675, 0xB0EB, 0x8676, 0xB0EC, 0x8677, 0xB0ED, 0x8678, 0xB0EE, + 0x8679, 0xB0EF, 0x867A, 0xB0F0, 0x8681, 0xB0F1, 0x8682, 0xB0F2, + 0x8683, 0xB0F3, 0x8684, 0xB0F4, 0x8685, 0xB0F5, 0x8686, 0xB0F6, + 0x8687, 0xB0F7, 0x8688, 0xB0F8, 0x8689, 0xB0F9, 0x868A, 0xB0FA, + 0x868B, 0xB0FB, 0x868C, 0xB0FC, 0x868D, 0xB0FD, 0x868E, 0xB0FE, + 0x868F, 0xB0FF, 0x8690, 0xB100, 0x8691, 0xB101, 0x8692, 0xB102, + 0x8693, 0xB103, 0x8694, 0xB104, 0x8695, 0xB105, 0x8696, 0xB106, + 0x8697, 0xB107, 0x8698, 0xB10A, 0x8699, 0xB10D, 0x869A, 0xB10E, + 0x869B, 0xB10F, 0x869C, 0xB111, 0x869D, 0xB114, 0x869E, 0xB115, + 0x869F, 0xB116, 0x86A0, 0xB117, 0x86A1, 0xB11A, 0x86A2, 0xB11E, + 0x86A3, 0xB11F, 0x86A4, 0xB120, 0x86A5, 0xB121, 0x86A6, 0xB122, + 0x86A7, 0xB126, 0x86A8, 0xB127, 0x86A9, 0xB129, 0x86AA, 0xB12A, + 0x86AB, 0xB12B, 0x86AC, 0xB12D, 0x86AD, 0xB12E, 0x86AE, 0xB12F, + 0x86AF, 0xB130, 0x86B0, 0xB131, 0x86B1, 0xB132, 0x86B2, 0xB133, + 0x86B3, 0xB136, 0x86B4, 0xB13A, 0x86B5, 0xB13B, 0x86B6, 0xB13C, + 0x86B7, 0xB13D, 0x86B8, 0xB13E, 0x86B9, 0xB13F, 0x86BA, 0xB142, + 0x86BB, 0xB143, 0x86BC, 0xB145, 0x86BD, 0xB146, 0x86BE, 0xB147, + 0x86BF, 0xB149, 0x86C0, 0xB14A, 0x86C1, 0xB14B, 0x86C2, 0xB14C, + 0x86C3, 0xB14D, 0x86C4, 0xB14E, 0x86C5, 0xB14F, 0x86C6, 0xB152, + 0x86C7, 0xB153, 0x86C8, 0xB156, 0x86C9, 0xB157, 0x86CA, 0xB159, + 0x86CB, 0xB15A, 0x86CC, 0xB15B, 0x86CD, 0xB15D, 0x86CE, 0xB15E, + 0x86CF, 0xB15F, 0x86D0, 0xB161, 0x86D1, 0xB162, 0x86D2, 0xB163, + 0x86D3, 0xB164, 0x86D4, 0xB165, 0x86D5, 0xB166, 0x86D6, 0xB167, + 0x86D7, 0xB168, 0x86D8, 0xB169, 0x86D9, 0xB16A, 0x86DA, 0xB16B, + 0x86DB, 0xB16C, 0x86DC, 0xB16D, 0x86DD, 0xB16E, 0x86DE, 0xB16F, + 0x86DF, 0xB170, 0x86E0, 0xB171, 0x86E1, 0xB172, 0x86E2, 0xB173, + 0x86E3, 0xB174, 0x86E4, 0xB175, 0x86E5, 0xB176, 0x86E6, 0xB177, + 0x86E7, 0xB17A, 0x86E8, 0xB17B, 0x86E9, 0xB17D, 0x86EA, 0xB17E, + 0x86EB, 0xB17F, 0x86EC, 0xB181, 0x86ED, 0xB183, 0x86EE, 0xB184, + 0x86EF, 0xB185, 0x86F0, 0xB186, 0x86F1, 0xB187, 0x86F2, 0xB18A, + 0x86F3, 0xB18C, 0x86F4, 0xB18E, 0x86F5, 0xB18F, 0x86F6, 0xB190, + 0x86F7, 0xB191, 0x86F8, 0xB195, 0x86F9, 0xB196, 0x86FA, 0xB197, + 0x86FB, 0xB199, 0x86FC, 0xB19A, 0x86FD, 0xB19B, 0x86FE, 0xB19D, + 0x8741, 0xB19E, 0x8742, 0xB19F, 0x8743, 0xB1A0, 0x8744, 0xB1A1, + 0x8745, 0xB1A2, 0x8746, 0xB1A3, 0x8747, 0xB1A4, 0x8748, 0xB1A5, + 0x8749, 0xB1A6, 0x874A, 0xB1A7, 0x874B, 0xB1A9, 0x874C, 0xB1AA, + 0x874D, 0xB1AB, 0x874E, 0xB1AC, 0x874F, 0xB1AD, 0x8750, 0xB1AE, + 0x8751, 0xB1AF, 0x8752, 0xB1B0, 0x8753, 0xB1B1, 0x8754, 0xB1B2, + 0x8755, 0xB1B3, 0x8756, 0xB1B4, 0x8757, 0xB1B5, 0x8758, 0xB1B6, + 0x8759, 0xB1B7, 0x875A, 0xB1B8, 0x8761, 0xB1B9, 0x8762, 0xB1BA, + 0x8763, 0xB1BB, 0x8764, 0xB1BC, 0x8765, 0xB1BD, 0x8766, 0xB1BE, + 0x8767, 0xB1BF, 0x8768, 0xB1C0, 0x8769, 0xB1C1, 0x876A, 0xB1C2, + 0x876B, 0xB1C3, 0x876C, 0xB1C4, 0x876D, 0xB1C5, 0x876E, 0xB1C6, + 0x876F, 0xB1C7, 0x8770, 0xB1C8, 0x8771, 0xB1C9, 0x8772, 0xB1CA, + 0x8773, 0xB1CB, 0x8774, 0xB1CD, 0x8775, 0xB1CE, 0x8776, 0xB1CF, + 0x8777, 0xB1D1, 0x8778, 0xB1D2, 0x8779, 0xB1D3, 0x877A, 0xB1D5, + 0x8781, 0xB1D6, 0x8782, 0xB1D7, 0x8783, 0xB1D8, 0x8784, 0xB1D9, + 0x8785, 0xB1DA, 0x8786, 0xB1DB, 0x8787, 0xB1DE, 0x8788, 0xB1E0, + 0x8789, 0xB1E1, 0x878A, 0xB1E2, 0x878B, 0xB1E3, 0x878C, 0xB1E4, + 0x878D, 0xB1E5, 0x878E, 0xB1E6, 0x878F, 0xB1E7, 0x8790, 0xB1EA, + 0x8791, 0xB1EB, 0x8792, 0xB1ED, 0x8793, 0xB1EE, 0x8794, 0xB1EF, + 0x8795, 0xB1F1, 0x8796, 0xB1F2, 0x8797, 0xB1F3, 0x8798, 0xB1F4, + 0x8799, 0xB1F5, 0x879A, 0xB1F6, 0x879B, 0xB1F7, 0x879C, 0xB1F8, + 0x879D, 0xB1FA, 0x879E, 0xB1FC, 0x879F, 0xB1FE, 0x87A0, 0xB1FF, + 0x87A1, 0xB200, 0x87A2, 0xB201, 0x87A3, 0xB202, 0x87A4, 0xB203, + 0x87A5, 0xB206, 0x87A6, 0xB207, 0x87A7, 0xB209, 0x87A8, 0xB20A, + 0x87A9, 0xB20D, 0x87AA, 0xB20E, 0x87AB, 0xB20F, 0x87AC, 0xB210, + 0x87AD, 0xB211, 0x87AE, 0xB212, 0x87AF, 0xB213, 0x87B0, 0xB216, + 0x87B1, 0xB218, 0x87B2, 0xB21A, 0x87B3, 0xB21B, 0x87B4, 0xB21C, + 0x87B5, 0xB21D, 0x87B6, 0xB21E, 0x87B7, 0xB21F, 0x87B8, 0xB221, + 0x87B9, 0xB222, 0x87BA, 0xB223, 0x87BB, 0xB224, 0x87BC, 0xB225, + 0x87BD, 0xB226, 0x87BE, 0xB227, 0x87BF, 0xB228, 0x87C0, 0xB229, + 0x87C1, 0xB22A, 0x87C2, 0xB22B, 0x87C3, 0xB22C, 0x87C4, 0xB22D, + 0x87C5, 0xB22E, 0x87C6, 0xB22F, 0x87C7, 0xB230, 0x87C8, 0xB231, + 0x87C9, 0xB232, 0x87CA, 0xB233, 0x87CB, 0xB235, 0x87CC, 0xB236, + 0x87CD, 0xB237, 0x87CE, 0xB238, 0x87CF, 0xB239, 0x87D0, 0xB23A, + 0x87D1, 0xB23B, 0x87D2, 0xB23D, 0x87D3, 0xB23E, 0x87D4, 0xB23F, + 0x87D5, 0xB240, 0x87D6, 0xB241, 0x87D7, 0xB242, 0x87D8, 0xB243, + 0x87D9, 0xB244, 0x87DA, 0xB245, 0x87DB, 0xB246, 0x87DC, 0xB247, + 0x87DD, 0xB248, 0x87DE, 0xB249, 0x87DF, 0xB24A, 0x87E0, 0xB24B, + 0x87E1, 0xB24C, 0x87E2, 0xB24D, 0x87E3, 0xB24E, 0x87E4, 0xB24F, + 0x87E5, 0xB250, 0x87E6, 0xB251, 0x87E7, 0xB252, 0x87E8, 0xB253, + 0x87E9, 0xB254, 0x87EA, 0xB255, 0x87EB, 0xB256, 0x87EC, 0xB257, + 0x87ED, 0xB259, 0x87EE, 0xB25A, 0x87EF, 0xB25B, 0x87F0, 0xB25D, + 0x87F1, 0xB25E, 0x87F2, 0xB25F, 0x87F3, 0xB261, 0x87F4, 0xB262, + 0x87F5, 0xB263, 0x87F6, 0xB264, 0x87F7, 0xB265, 0x87F8, 0xB266, + 0x87F9, 0xB267, 0x87FA, 0xB26A, 0x87FB, 0xB26B, 0x87FC, 0xB26C, + 0x87FD, 0xB26D, 0x87FE, 0xB26E, 0x8841, 0xB26F, 0x8842, 0xB270, + 0x8843, 0xB271, 0x8844, 0xB272, 0x8845, 0xB273, 0x8846, 0xB276, + 0x8847, 0xB277, 0x8848, 0xB278, 0x8849, 0xB279, 0x884A, 0xB27A, + 0x884B, 0xB27B, 0x884C, 0xB27D, 0x884D, 0xB27E, 0x884E, 0xB27F, + 0x884F, 0xB280, 0x8850, 0xB281, 0x8851, 0xB282, 0x8852, 0xB283, + 0x8853, 0xB286, 0x8854, 0xB287, 0x8855, 0xB288, 0x8856, 0xB28A, + 0x8857, 0xB28B, 0x8858, 0xB28C, 0x8859, 0xB28D, 0x885A, 0xB28E, + 0x8861, 0xB28F, 0x8862, 0xB292, 0x8863, 0xB293, 0x8864, 0xB295, + 0x8865, 0xB296, 0x8866, 0xB297, 0x8867, 0xB29B, 0x8868, 0xB29C, + 0x8869, 0xB29D, 0x886A, 0xB29E, 0x886B, 0xB29F, 0x886C, 0xB2A2, + 0x886D, 0xB2A4, 0x886E, 0xB2A7, 0x886F, 0xB2A8, 0x8870, 0xB2A9, + 0x8871, 0xB2AB, 0x8872, 0xB2AD, 0x8873, 0xB2AE, 0x8874, 0xB2AF, + 0x8875, 0xB2B1, 0x8876, 0xB2B2, 0x8877, 0xB2B3, 0x8878, 0xB2B5, + 0x8879, 0xB2B6, 0x887A, 0xB2B7, 0x8881, 0xB2B8, 0x8882, 0xB2B9, + 0x8883, 0xB2BA, 0x8884, 0xB2BB, 0x8885, 0xB2BC, 0x8886, 0xB2BD, + 0x8887, 0xB2BE, 0x8888, 0xB2BF, 0x8889, 0xB2C0, 0x888A, 0xB2C1, + 0x888B, 0xB2C2, 0x888C, 0xB2C3, 0x888D, 0xB2C4, 0x888E, 0xB2C5, + 0x888F, 0xB2C6, 0x8890, 0xB2C7, 0x8891, 0xB2CA, 0x8892, 0xB2CB, + 0x8893, 0xB2CD, 0x8894, 0xB2CE, 0x8895, 0xB2CF, 0x8896, 0xB2D1, + 0x8897, 0xB2D3, 0x8898, 0xB2D4, 0x8899, 0xB2D5, 0x889A, 0xB2D6, + 0x889B, 0xB2D7, 0x889C, 0xB2DA, 0x889D, 0xB2DC, 0x889E, 0xB2DE, + 0x889F, 0xB2DF, 0x88A0, 0xB2E0, 0x88A1, 0xB2E1, 0x88A2, 0xB2E3, + 0x88A3, 0xB2E7, 0x88A4, 0xB2E9, 0x88A5, 0xB2EA, 0x88A6, 0xB2F0, + 0x88A7, 0xB2F1, 0x88A8, 0xB2F2, 0x88A9, 0xB2F6, 0x88AA, 0xB2FC, + 0x88AB, 0xB2FD, 0x88AC, 0xB2FE, 0x88AD, 0xB302, 0x88AE, 0xB303, + 0x88AF, 0xB305, 0x88B0, 0xB306, 0x88B1, 0xB307, 0x88B2, 0xB309, + 0x88B3, 0xB30A, 0x88B4, 0xB30B, 0x88B5, 0xB30C, 0x88B6, 0xB30D, + 0x88B7, 0xB30E, 0x88B8, 0xB30F, 0x88B9, 0xB312, 0x88BA, 0xB316, + 0x88BB, 0xB317, 0x88BC, 0xB318, 0x88BD, 0xB319, 0x88BE, 0xB31A, + 0x88BF, 0xB31B, 0x88C0, 0xB31D, 0x88C1, 0xB31E, 0x88C2, 0xB31F, + 0x88C3, 0xB320, 0x88C4, 0xB321, 0x88C5, 0xB322, 0x88C6, 0xB323, + 0x88C7, 0xB324, 0x88C8, 0xB325, 0x88C9, 0xB326, 0x88CA, 0xB327, + 0x88CB, 0xB328, 0x88CC, 0xB329, 0x88CD, 0xB32A, 0x88CE, 0xB32B, + 0x88CF, 0xB32C, 0x88D0, 0xB32D, 0x88D1, 0xB32E, 0x88D2, 0xB32F, + 0x88D3, 0xB330, 0x88D4, 0xB331, 0x88D5, 0xB332, 0x88D6, 0xB333, + 0x88D7, 0xB334, 0x88D8, 0xB335, 0x88D9, 0xB336, 0x88DA, 0xB337, + 0x88DB, 0xB338, 0x88DC, 0xB339, 0x88DD, 0xB33A, 0x88DE, 0xB33B, + 0x88DF, 0xB33C, 0x88E0, 0xB33D, 0x88E1, 0xB33E, 0x88E2, 0xB33F, + 0x88E3, 0xB340, 0x88E4, 0xB341, 0x88E5, 0xB342, 0x88E6, 0xB343, + 0x88E7, 0xB344, 0x88E8, 0xB345, 0x88E9, 0xB346, 0x88EA, 0xB347, + 0x88EB, 0xB348, 0x88EC, 0xB349, 0x88ED, 0xB34A, 0x88EE, 0xB34B, + 0x88EF, 0xB34C, 0x88F0, 0xB34D, 0x88F1, 0xB34E, 0x88F2, 0xB34F, + 0x88F3, 0xB350, 0x88F4, 0xB351, 0x88F5, 0xB352, 0x88F6, 0xB353, + 0x88F7, 0xB357, 0x88F8, 0xB359, 0x88F9, 0xB35A, 0x88FA, 0xB35D, + 0x88FB, 0xB360, 0x88FC, 0xB361, 0x88FD, 0xB362, 0x88FE, 0xB363, + 0x8941, 0xB366, 0x8942, 0xB368, 0x8943, 0xB36A, 0x8944, 0xB36C, + 0x8945, 0xB36D, 0x8946, 0xB36F, 0x8947, 0xB372, 0x8948, 0xB373, + 0x8949, 0xB375, 0x894A, 0xB376, 0x894B, 0xB377, 0x894C, 0xB379, + 0x894D, 0xB37A, 0x894E, 0xB37B, 0x894F, 0xB37C, 0x8950, 0xB37D, + 0x8951, 0xB37E, 0x8952, 0xB37F, 0x8953, 0xB382, 0x8954, 0xB386, + 0x8955, 0xB387, 0x8956, 0xB388, 0x8957, 0xB389, 0x8958, 0xB38A, + 0x8959, 0xB38B, 0x895A, 0xB38D, 0x8961, 0xB38E, 0x8962, 0xB38F, + 0x8963, 0xB391, 0x8964, 0xB392, 0x8965, 0xB393, 0x8966, 0xB395, + 0x8967, 0xB396, 0x8968, 0xB397, 0x8969, 0xB398, 0x896A, 0xB399, + 0x896B, 0xB39A, 0x896C, 0xB39B, 0x896D, 0xB39C, 0x896E, 0xB39D, + 0x896F, 0xB39E, 0x8970, 0xB39F, 0x8971, 0xB3A2, 0x8972, 0xB3A3, + 0x8973, 0xB3A4, 0x8974, 0xB3A5, 0x8975, 0xB3A6, 0x8976, 0xB3A7, + 0x8977, 0xB3A9, 0x8978, 0xB3AA, 0x8979, 0xB3AB, 0x897A, 0xB3AD, + 0x8981, 0xB3AE, 0x8982, 0xB3AF, 0x8983, 0xB3B0, 0x8984, 0xB3B1, + 0x8985, 0xB3B2, 0x8986, 0xB3B3, 0x8987, 0xB3B4, 0x8988, 0xB3B5, + 0x8989, 0xB3B6, 0x898A, 0xB3B7, 0x898B, 0xB3B8, 0x898C, 0xB3B9, + 0x898D, 0xB3BA, 0x898E, 0xB3BB, 0x898F, 0xB3BC, 0x8990, 0xB3BD, + 0x8991, 0xB3BE, 0x8992, 0xB3BF, 0x8993, 0xB3C0, 0x8994, 0xB3C1, + 0x8995, 0xB3C2, 0x8996, 0xB3C3, 0x8997, 0xB3C6, 0x8998, 0xB3C7, + 0x8999, 0xB3C9, 0x899A, 0xB3CA, 0x899B, 0xB3CD, 0x899C, 0xB3CF, + 0x899D, 0xB3D1, 0x899E, 0xB3D2, 0x899F, 0xB3D3, 0x89A0, 0xB3D6, + 0x89A1, 0xB3D8, 0x89A2, 0xB3DA, 0x89A3, 0xB3DC, 0x89A4, 0xB3DE, + 0x89A5, 0xB3DF, 0x89A6, 0xB3E1, 0x89A7, 0xB3E2, 0x89A8, 0xB3E3, + 0x89A9, 0xB3E5, 0x89AA, 0xB3E6, 0x89AB, 0xB3E7, 0x89AC, 0xB3E9, + 0x89AD, 0xB3EA, 0x89AE, 0xB3EB, 0x89AF, 0xB3EC, 0x89B0, 0xB3ED, + 0x89B1, 0xB3EE, 0x89B2, 0xB3EF, 0x89B3, 0xB3F0, 0x89B4, 0xB3F1, + 0x89B5, 0xB3F2, 0x89B6, 0xB3F3, 0x89B7, 0xB3F4, 0x89B8, 0xB3F5, + 0x89B9, 0xB3F6, 0x89BA, 0xB3F7, 0x89BB, 0xB3F8, 0x89BC, 0xB3F9, + 0x89BD, 0xB3FA, 0x89BE, 0xB3FB, 0x89BF, 0xB3FD, 0x89C0, 0xB3FE, + 0x89C1, 0xB3FF, 0x89C2, 0xB400, 0x89C3, 0xB401, 0x89C4, 0xB402, + 0x89C5, 0xB403, 0x89C6, 0xB404, 0x89C7, 0xB405, 0x89C8, 0xB406, + 0x89C9, 0xB407, 0x89CA, 0xB408, 0x89CB, 0xB409, 0x89CC, 0xB40A, + 0x89CD, 0xB40B, 0x89CE, 0xB40C, 0x89CF, 0xB40D, 0x89D0, 0xB40E, + 0x89D1, 0xB40F, 0x89D2, 0xB411, 0x89D3, 0xB412, 0x89D4, 0xB413, + 0x89D5, 0xB414, 0x89D6, 0xB415, 0x89D7, 0xB416, 0x89D8, 0xB417, + 0x89D9, 0xB419, 0x89DA, 0xB41A, 0x89DB, 0xB41B, 0x89DC, 0xB41D, + 0x89DD, 0xB41E, 0x89DE, 0xB41F, 0x89DF, 0xB421, 0x89E0, 0xB422, + 0x89E1, 0xB423, 0x89E2, 0xB424, 0x89E3, 0xB425, 0x89E4, 0xB426, + 0x89E5, 0xB427, 0x89E6, 0xB42A, 0x89E7, 0xB42C, 0x89E8, 0xB42D, + 0x89E9, 0xB42E, 0x89EA, 0xB42F, 0x89EB, 0xB430, 0x89EC, 0xB431, + 0x89ED, 0xB432, 0x89EE, 0xB433, 0x89EF, 0xB435, 0x89F0, 0xB436, + 0x89F1, 0xB437, 0x89F2, 0xB438, 0x89F3, 0xB439, 0x89F4, 0xB43A, + 0x89F5, 0xB43B, 0x89F6, 0xB43C, 0x89F7, 0xB43D, 0x89F8, 0xB43E, + 0x89F9, 0xB43F, 0x89FA, 0xB440, 0x89FB, 0xB441, 0x89FC, 0xB442, + 0x89FD, 0xB443, 0x89FE, 0xB444, 0x8A41, 0xB445, 0x8A42, 0xB446, + 0x8A43, 0xB447, 0x8A44, 0xB448, 0x8A45, 0xB449, 0x8A46, 0xB44A, + 0x8A47, 0xB44B, 0x8A48, 0xB44C, 0x8A49, 0xB44D, 0x8A4A, 0xB44E, + 0x8A4B, 0xB44F, 0x8A4C, 0xB452, 0x8A4D, 0xB453, 0x8A4E, 0xB455, + 0x8A4F, 0xB456, 0x8A50, 0xB457, 0x8A51, 0xB459, 0x8A52, 0xB45A, + 0x8A53, 0xB45B, 0x8A54, 0xB45C, 0x8A55, 0xB45D, 0x8A56, 0xB45E, + 0x8A57, 0xB45F, 0x8A58, 0xB462, 0x8A59, 0xB464, 0x8A5A, 0xB466, + 0x8A61, 0xB467, 0x8A62, 0xB468, 0x8A63, 0xB469, 0x8A64, 0xB46A, + 0x8A65, 0xB46B, 0x8A66, 0xB46D, 0x8A67, 0xB46E, 0x8A68, 0xB46F, + 0x8A69, 0xB470, 0x8A6A, 0xB471, 0x8A6B, 0xB472, 0x8A6C, 0xB473, + 0x8A6D, 0xB474, 0x8A6E, 0xB475, 0x8A6F, 0xB476, 0x8A70, 0xB477, + 0x8A71, 0xB478, 0x8A72, 0xB479, 0x8A73, 0xB47A, 0x8A74, 0xB47B, + 0x8A75, 0xB47C, 0x8A76, 0xB47D, 0x8A77, 0xB47E, 0x8A78, 0xB47F, + 0x8A79, 0xB481, 0x8A7A, 0xB482, 0x8A81, 0xB483, 0x8A82, 0xB484, + 0x8A83, 0xB485, 0x8A84, 0xB486, 0x8A85, 0xB487, 0x8A86, 0xB489, + 0x8A87, 0xB48A, 0x8A88, 0xB48B, 0x8A89, 0xB48C, 0x8A8A, 0xB48D, + 0x8A8B, 0xB48E, 0x8A8C, 0xB48F, 0x8A8D, 0xB490, 0x8A8E, 0xB491, + 0x8A8F, 0xB492, 0x8A90, 0xB493, 0x8A91, 0xB494, 0x8A92, 0xB495, + 0x8A93, 0xB496, 0x8A94, 0xB497, 0x8A95, 0xB498, 0x8A96, 0xB499, + 0x8A97, 0xB49A, 0x8A98, 0xB49B, 0x8A99, 0xB49C, 0x8A9A, 0xB49E, + 0x8A9B, 0xB49F, 0x8A9C, 0xB4A0, 0x8A9D, 0xB4A1, 0x8A9E, 0xB4A2, + 0x8A9F, 0xB4A3, 0x8AA0, 0xB4A5, 0x8AA1, 0xB4A6, 0x8AA2, 0xB4A7, + 0x8AA3, 0xB4A9, 0x8AA4, 0xB4AA, 0x8AA5, 0xB4AB, 0x8AA6, 0xB4AD, + 0x8AA7, 0xB4AE, 0x8AA8, 0xB4AF, 0x8AA9, 0xB4B0, 0x8AAA, 0xB4B1, + 0x8AAB, 0xB4B2, 0x8AAC, 0xB4B3, 0x8AAD, 0xB4B4, 0x8AAE, 0xB4B6, + 0x8AAF, 0xB4B8, 0x8AB0, 0xB4BA, 0x8AB1, 0xB4BB, 0x8AB2, 0xB4BC, + 0x8AB3, 0xB4BD, 0x8AB4, 0xB4BE, 0x8AB5, 0xB4BF, 0x8AB6, 0xB4C1, + 0x8AB7, 0xB4C2, 0x8AB8, 0xB4C3, 0x8AB9, 0xB4C5, 0x8ABA, 0xB4C6, + 0x8ABB, 0xB4C7, 0x8ABC, 0xB4C9, 0x8ABD, 0xB4CA, 0x8ABE, 0xB4CB, + 0x8ABF, 0xB4CC, 0x8AC0, 0xB4CD, 0x8AC1, 0xB4CE, 0x8AC2, 0xB4CF, + 0x8AC3, 0xB4D1, 0x8AC4, 0xB4D2, 0x8AC5, 0xB4D3, 0x8AC6, 0xB4D4, + 0x8AC7, 0xB4D6, 0x8AC8, 0xB4D7, 0x8AC9, 0xB4D8, 0x8ACA, 0xB4D9, + 0x8ACB, 0xB4DA, 0x8ACC, 0xB4DB, 0x8ACD, 0xB4DE, 0x8ACE, 0xB4DF, + 0x8ACF, 0xB4E1, 0x8AD0, 0xB4E2, 0x8AD1, 0xB4E5, 0x8AD2, 0xB4E7, + 0x8AD3, 0xB4E8, 0x8AD4, 0xB4E9, 0x8AD5, 0xB4EA, 0x8AD6, 0xB4EB, + 0x8AD7, 0xB4EE, 0x8AD8, 0xB4F0, 0x8AD9, 0xB4F2, 0x8ADA, 0xB4F3, + 0x8ADB, 0xB4F4, 0x8ADC, 0xB4F5, 0x8ADD, 0xB4F6, 0x8ADE, 0xB4F7, + 0x8ADF, 0xB4F9, 0x8AE0, 0xB4FA, 0x8AE1, 0xB4FB, 0x8AE2, 0xB4FC, + 0x8AE3, 0xB4FD, 0x8AE4, 0xB4FE, 0x8AE5, 0xB4FF, 0x8AE6, 0xB500, + 0x8AE7, 0xB501, 0x8AE8, 0xB502, 0x8AE9, 0xB503, 0x8AEA, 0xB504, + 0x8AEB, 0xB505, 0x8AEC, 0xB506, 0x8AED, 0xB507, 0x8AEE, 0xB508, + 0x8AEF, 0xB509, 0x8AF0, 0xB50A, 0x8AF1, 0xB50B, 0x8AF2, 0xB50C, + 0x8AF3, 0xB50D, 0x8AF4, 0xB50E, 0x8AF5, 0xB50F, 0x8AF6, 0xB510, + 0x8AF7, 0xB511, 0x8AF8, 0xB512, 0x8AF9, 0xB513, 0x8AFA, 0xB516, + 0x8AFB, 0xB517, 0x8AFC, 0xB519, 0x8AFD, 0xB51A, 0x8AFE, 0xB51D, + 0x8B41, 0xB51E, 0x8B42, 0xB51F, 0x8B43, 0xB520, 0x8B44, 0xB521, + 0x8B45, 0xB522, 0x8B46, 0xB523, 0x8B47, 0xB526, 0x8B48, 0xB52B, + 0x8B49, 0xB52C, 0x8B4A, 0xB52D, 0x8B4B, 0xB52E, 0x8B4C, 0xB52F, + 0x8B4D, 0xB532, 0x8B4E, 0xB533, 0x8B4F, 0xB535, 0x8B50, 0xB536, + 0x8B51, 0xB537, 0x8B52, 0xB539, 0x8B53, 0xB53A, 0x8B54, 0xB53B, + 0x8B55, 0xB53C, 0x8B56, 0xB53D, 0x8B57, 0xB53E, 0x8B58, 0xB53F, + 0x8B59, 0xB542, 0x8B5A, 0xB546, 0x8B61, 0xB547, 0x8B62, 0xB548, + 0x8B63, 0xB549, 0x8B64, 0xB54A, 0x8B65, 0xB54E, 0x8B66, 0xB54F, + 0x8B67, 0xB551, 0x8B68, 0xB552, 0x8B69, 0xB553, 0x8B6A, 0xB555, + 0x8B6B, 0xB556, 0x8B6C, 0xB557, 0x8B6D, 0xB558, 0x8B6E, 0xB559, + 0x8B6F, 0xB55A, 0x8B70, 0xB55B, 0x8B71, 0xB55E, 0x8B72, 0xB562, + 0x8B73, 0xB563, 0x8B74, 0xB564, 0x8B75, 0xB565, 0x8B76, 0xB566, + 0x8B77, 0xB567, 0x8B78, 0xB568, 0x8B79, 0xB569, 0x8B7A, 0xB56A, + 0x8B81, 0xB56B, 0x8B82, 0xB56C, 0x8B83, 0xB56D, 0x8B84, 0xB56E, + 0x8B85, 0xB56F, 0x8B86, 0xB570, 0x8B87, 0xB571, 0x8B88, 0xB572, + 0x8B89, 0xB573, 0x8B8A, 0xB574, 0x8B8B, 0xB575, 0x8B8C, 0xB576, + 0x8B8D, 0xB577, 0x8B8E, 0xB578, 0x8B8F, 0xB579, 0x8B90, 0xB57A, + 0x8B91, 0xB57B, 0x8B92, 0xB57C, 0x8B93, 0xB57D, 0x8B94, 0xB57E, + 0x8B95, 0xB57F, 0x8B96, 0xB580, 0x8B97, 0xB581, 0x8B98, 0xB582, + 0x8B99, 0xB583, 0x8B9A, 0xB584, 0x8B9B, 0xB585, 0x8B9C, 0xB586, + 0x8B9D, 0xB587, 0x8B9E, 0xB588, 0x8B9F, 0xB589, 0x8BA0, 0xB58A, + 0x8BA1, 0xB58B, 0x8BA2, 0xB58C, 0x8BA3, 0xB58D, 0x8BA4, 0xB58E, + 0x8BA5, 0xB58F, 0x8BA6, 0xB590, 0x8BA7, 0xB591, 0x8BA8, 0xB592, + 0x8BA9, 0xB593, 0x8BAA, 0xB594, 0x8BAB, 0xB595, 0x8BAC, 0xB596, + 0x8BAD, 0xB597, 0x8BAE, 0xB598, 0x8BAF, 0xB599, 0x8BB0, 0xB59A, + 0x8BB1, 0xB59B, 0x8BB2, 0xB59C, 0x8BB3, 0xB59D, 0x8BB4, 0xB59E, + 0x8BB5, 0xB59F, 0x8BB6, 0xB5A2, 0x8BB7, 0xB5A3, 0x8BB8, 0xB5A5, + 0x8BB9, 0xB5A6, 0x8BBA, 0xB5A7, 0x8BBB, 0xB5A9, 0x8BBC, 0xB5AC, + 0x8BBD, 0xB5AD, 0x8BBE, 0xB5AE, 0x8BBF, 0xB5AF, 0x8BC0, 0xB5B2, + 0x8BC1, 0xB5B6, 0x8BC2, 0xB5B7, 0x8BC3, 0xB5B8, 0x8BC4, 0xB5B9, + 0x8BC5, 0xB5BA, 0x8BC6, 0xB5BE, 0x8BC7, 0xB5BF, 0x8BC8, 0xB5C1, + 0x8BC9, 0xB5C2, 0x8BCA, 0xB5C3, 0x8BCB, 0xB5C5, 0x8BCC, 0xB5C6, + 0x8BCD, 0xB5C7, 0x8BCE, 0xB5C8, 0x8BCF, 0xB5C9, 0x8BD0, 0xB5CA, + 0x8BD1, 0xB5CB, 0x8BD2, 0xB5CE, 0x8BD3, 0xB5D2, 0x8BD4, 0xB5D3, + 0x8BD5, 0xB5D4, 0x8BD6, 0xB5D5, 0x8BD7, 0xB5D6, 0x8BD8, 0xB5D7, + 0x8BD9, 0xB5D9, 0x8BDA, 0xB5DA, 0x8BDB, 0xB5DB, 0x8BDC, 0xB5DC, + 0x8BDD, 0xB5DD, 0x8BDE, 0xB5DE, 0x8BDF, 0xB5DF, 0x8BE0, 0xB5E0, + 0x8BE1, 0xB5E1, 0x8BE2, 0xB5E2, 0x8BE3, 0xB5E3, 0x8BE4, 0xB5E4, + 0x8BE5, 0xB5E5, 0x8BE6, 0xB5E6, 0x8BE7, 0xB5E7, 0x8BE8, 0xB5E8, + 0x8BE9, 0xB5E9, 0x8BEA, 0xB5EA, 0x8BEB, 0xB5EB, 0x8BEC, 0xB5ED, + 0x8BED, 0xB5EE, 0x8BEE, 0xB5EF, 0x8BEF, 0xB5F0, 0x8BF0, 0xB5F1, + 0x8BF1, 0xB5F2, 0x8BF2, 0xB5F3, 0x8BF3, 0xB5F4, 0x8BF4, 0xB5F5, + 0x8BF5, 0xB5F6, 0x8BF6, 0xB5F7, 0x8BF7, 0xB5F8, 0x8BF8, 0xB5F9, + 0x8BF9, 0xB5FA, 0x8BFA, 0xB5FB, 0x8BFB, 0xB5FC, 0x8BFC, 0xB5FD, + 0x8BFD, 0xB5FE, 0x8BFE, 0xB5FF, 0x8C41, 0xB600, 0x8C42, 0xB601, + 0x8C43, 0xB602, 0x8C44, 0xB603, 0x8C45, 0xB604, 0x8C46, 0xB605, + 0x8C47, 0xB606, 0x8C48, 0xB607, 0x8C49, 0xB608, 0x8C4A, 0xB609, + 0x8C4B, 0xB60A, 0x8C4C, 0xB60B, 0x8C4D, 0xB60C, 0x8C4E, 0xB60D, + 0x8C4F, 0xB60E, 0x8C50, 0xB60F, 0x8C51, 0xB612, 0x8C52, 0xB613, + 0x8C53, 0xB615, 0x8C54, 0xB616, 0x8C55, 0xB617, 0x8C56, 0xB619, + 0x8C57, 0xB61A, 0x8C58, 0xB61B, 0x8C59, 0xB61C, 0x8C5A, 0xB61D, + 0x8C61, 0xB61E, 0x8C62, 0xB61F, 0x8C63, 0xB620, 0x8C64, 0xB621, + 0x8C65, 0xB622, 0x8C66, 0xB623, 0x8C67, 0xB624, 0x8C68, 0xB626, + 0x8C69, 0xB627, 0x8C6A, 0xB628, 0x8C6B, 0xB629, 0x8C6C, 0xB62A, + 0x8C6D, 0xB62B, 0x8C6E, 0xB62D, 0x8C6F, 0xB62E, 0x8C70, 0xB62F, + 0x8C71, 0xB630, 0x8C72, 0xB631, 0x8C73, 0xB632, 0x8C74, 0xB633, + 0x8C75, 0xB635, 0x8C76, 0xB636, 0x8C77, 0xB637, 0x8C78, 0xB638, + 0x8C79, 0xB639, 0x8C7A, 0xB63A, 0x8C81, 0xB63B, 0x8C82, 0xB63C, + 0x8C83, 0xB63D, 0x8C84, 0xB63E, 0x8C85, 0xB63F, 0x8C86, 0xB640, + 0x8C87, 0xB641, 0x8C88, 0xB642, 0x8C89, 0xB643, 0x8C8A, 0xB644, + 0x8C8B, 0xB645, 0x8C8C, 0xB646, 0x8C8D, 0xB647, 0x8C8E, 0xB649, + 0x8C8F, 0xB64A, 0x8C90, 0xB64B, 0x8C91, 0xB64C, 0x8C92, 0xB64D, + 0x8C93, 0xB64E, 0x8C94, 0xB64F, 0x8C95, 0xB650, 0x8C96, 0xB651, + 0x8C97, 0xB652, 0x8C98, 0xB653, 0x8C99, 0xB654, 0x8C9A, 0xB655, + 0x8C9B, 0xB656, 0x8C9C, 0xB657, 0x8C9D, 0xB658, 0x8C9E, 0xB659, + 0x8C9F, 0xB65A, 0x8CA0, 0xB65B, 0x8CA1, 0xB65C, 0x8CA2, 0xB65D, + 0x8CA3, 0xB65E, 0x8CA4, 0xB65F, 0x8CA5, 0xB660, 0x8CA6, 0xB661, + 0x8CA7, 0xB662, 0x8CA8, 0xB663, 0x8CA9, 0xB665, 0x8CAA, 0xB666, + 0x8CAB, 0xB667, 0x8CAC, 0xB669, 0x8CAD, 0xB66A, 0x8CAE, 0xB66B, + 0x8CAF, 0xB66C, 0x8CB0, 0xB66D, 0x8CB1, 0xB66E, 0x8CB2, 0xB66F, + 0x8CB3, 0xB670, 0x8CB4, 0xB671, 0x8CB5, 0xB672, 0x8CB6, 0xB673, + 0x8CB7, 0xB674, 0x8CB8, 0xB675, 0x8CB9, 0xB676, 0x8CBA, 0xB677, + 0x8CBB, 0xB678, 0x8CBC, 0xB679, 0x8CBD, 0xB67A, 0x8CBE, 0xB67B, + 0x8CBF, 0xB67C, 0x8CC0, 0xB67D, 0x8CC1, 0xB67E, 0x8CC2, 0xB67F, + 0x8CC3, 0xB680, 0x8CC4, 0xB681, 0x8CC5, 0xB682, 0x8CC6, 0xB683, + 0x8CC7, 0xB684, 0x8CC8, 0xB685, 0x8CC9, 0xB686, 0x8CCA, 0xB687, + 0x8CCB, 0xB688, 0x8CCC, 0xB689, 0x8CCD, 0xB68A, 0x8CCE, 0xB68B, + 0x8CCF, 0xB68C, 0x8CD0, 0xB68D, 0x8CD1, 0xB68E, 0x8CD2, 0xB68F, + 0x8CD3, 0xB690, 0x8CD4, 0xB691, 0x8CD5, 0xB692, 0x8CD6, 0xB693, + 0x8CD7, 0xB694, 0x8CD8, 0xB695, 0x8CD9, 0xB696, 0x8CDA, 0xB697, + 0x8CDB, 0xB698, 0x8CDC, 0xB699, 0x8CDD, 0xB69A, 0x8CDE, 0xB69B, + 0x8CDF, 0xB69E, 0x8CE0, 0xB69F, 0x8CE1, 0xB6A1, 0x8CE2, 0xB6A2, + 0x8CE3, 0xB6A3, 0x8CE4, 0xB6A5, 0x8CE5, 0xB6A6, 0x8CE6, 0xB6A7, + 0x8CE7, 0xB6A8, 0x8CE8, 0xB6A9, 0x8CE9, 0xB6AA, 0x8CEA, 0xB6AD, + 0x8CEB, 0xB6AE, 0x8CEC, 0xB6AF, 0x8CED, 0xB6B0, 0x8CEE, 0xB6B2, + 0x8CEF, 0xB6B3, 0x8CF0, 0xB6B4, 0x8CF1, 0xB6B5, 0x8CF2, 0xB6B6, + 0x8CF3, 0xB6B7, 0x8CF4, 0xB6B8, 0x8CF5, 0xB6B9, 0x8CF6, 0xB6BA, + 0x8CF7, 0xB6BB, 0x8CF8, 0xB6BC, 0x8CF9, 0xB6BD, 0x8CFA, 0xB6BE, + 0x8CFB, 0xB6BF, 0x8CFC, 0xB6C0, 0x8CFD, 0xB6C1, 0x8CFE, 0xB6C2, + 0x8D41, 0xB6C3, 0x8D42, 0xB6C4, 0x8D43, 0xB6C5, 0x8D44, 0xB6C6, + 0x8D45, 0xB6C7, 0x8D46, 0xB6C8, 0x8D47, 0xB6C9, 0x8D48, 0xB6CA, + 0x8D49, 0xB6CB, 0x8D4A, 0xB6CC, 0x8D4B, 0xB6CD, 0x8D4C, 0xB6CE, + 0x8D4D, 0xB6CF, 0x8D4E, 0xB6D0, 0x8D4F, 0xB6D1, 0x8D50, 0xB6D2, + 0x8D51, 0xB6D3, 0x8D52, 0xB6D5, 0x8D53, 0xB6D6, 0x8D54, 0xB6D7, + 0x8D55, 0xB6D8, 0x8D56, 0xB6D9, 0x8D57, 0xB6DA, 0x8D58, 0xB6DB, + 0x8D59, 0xB6DC, 0x8D5A, 0xB6DD, 0x8D61, 0xB6DE, 0x8D62, 0xB6DF, + 0x8D63, 0xB6E0, 0x8D64, 0xB6E1, 0x8D65, 0xB6E2, 0x8D66, 0xB6E3, + 0x8D67, 0xB6E4, 0x8D68, 0xB6E5, 0x8D69, 0xB6E6, 0x8D6A, 0xB6E7, + 0x8D6B, 0xB6E8, 0x8D6C, 0xB6E9, 0x8D6D, 0xB6EA, 0x8D6E, 0xB6EB, + 0x8D6F, 0xB6EC, 0x8D70, 0xB6ED, 0x8D71, 0xB6EE, 0x8D72, 0xB6EF, + 0x8D73, 0xB6F1, 0x8D74, 0xB6F2, 0x8D75, 0xB6F3, 0x8D76, 0xB6F5, + 0x8D77, 0xB6F6, 0x8D78, 0xB6F7, 0x8D79, 0xB6F9, 0x8D7A, 0xB6FA, + 0x8D81, 0xB6FB, 0x8D82, 0xB6FC, 0x8D83, 0xB6FD, 0x8D84, 0xB6FE, + 0x8D85, 0xB6FF, 0x8D86, 0xB702, 0x8D87, 0xB703, 0x8D88, 0xB704, + 0x8D89, 0xB706, 0x8D8A, 0xB707, 0x8D8B, 0xB708, 0x8D8C, 0xB709, + 0x8D8D, 0xB70A, 0x8D8E, 0xB70B, 0x8D8F, 0xB70C, 0x8D90, 0xB70D, + 0x8D91, 0xB70E, 0x8D92, 0xB70F, 0x8D93, 0xB710, 0x8D94, 0xB711, + 0x8D95, 0xB712, 0x8D96, 0xB713, 0x8D97, 0xB714, 0x8D98, 0xB715, + 0x8D99, 0xB716, 0x8D9A, 0xB717, 0x8D9B, 0xB718, 0x8D9C, 0xB719, + 0x8D9D, 0xB71A, 0x8D9E, 0xB71B, 0x8D9F, 0xB71C, 0x8DA0, 0xB71D, + 0x8DA1, 0xB71E, 0x8DA2, 0xB71F, 0x8DA3, 0xB720, 0x8DA4, 0xB721, + 0x8DA5, 0xB722, 0x8DA6, 0xB723, 0x8DA7, 0xB724, 0x8DA8, 0xB725, + 0x8DA9, 0xB726, 0x8DAA, 0xB727, 0x8DAB, 0xB72A, 0x8DAC, 0xB72B, + 0x8DAD, 0xB72D, 0x8DAE, 0xB72E, 0x8DAF, 0xB731, 0x8DB0, 0xB732, + 0x8DB1, 0xB733, 0x8DB2, 0xB734, 0x8DB3, 0xB735, 0x8DB4, 0xB736, + 0x8DB5, 0xB737, 0x8DB6, 0xB73A, 0x8DB7, 0xB73C, 0x8DB8, 0xB73D, + 0x8DB9, 0xB73E, 0x8DBA, 0xB73F, 0x8DBB, 0xB740, 0x8DBC, 0xB741, + 0x8DBD, 0xB742, 0x8DBE, 0xB743, 0x8DBF, 0xB745, 0x8DC0, 0xB746, + 0x8DC1, 0xB747, 0x8DC2, 0xB749, 0x8DC3, 0xB74A, 0x8DC4, 0xB74B, + 0x8DC5, 0xB74D, 0x8DC6, 0xB74E, 0x8DC7, 0xB74F, 0x8DC8, 0xB750, + 0x8DC9, 0xB751, 0x8DCA, 0xB752, 0x8DCB, 0xB753, 0x8DCC, 0xB756, + 0x8DCD, 0xB757, 0x8DCE, 0xB758, 0x8DCF, 0xB759, 0x8DD0, 0xB75A, + 0x8DD1, 0xB75B, 0x8DD2, 0xB75C, 0x8DD3, 0xB75D, 0x8DD4, 0xB75E, + 0x8DD5, 0xB75F, 0x8DD6, 0xB761, 0x8DD7, 0xB762, 0x8DD8, 0xB763, + 0x8DD9, 0xB765, 0x8DDA, 0xB766, 0x8DDB, 0xB767, 0x8DDC, 0xB769, + 0x8DDD, 0xB76A, 0x8DDE, 0xB76B, 0x8DDF, 0xB76C, 0x8DE0, 0xB76D, + 0x8DE1, 0xB76E, 0x8DE2, 0xB76F, 0x8DE3, 0xB772, 0x8DE4, 0xB774, + 0x8DE5, 0xB776, 0x8DE6, 0xB777, 0x8DE7, 0xB778, 0x8DE8, 0xB779, + 0x8DE9, 0xB77A, 0x8DEA, 0xB77B, 0x8DEB, 0xB77E, 0x8DEC, 0xB77F, + 0x8DED, 0xB781, 0x8DEE, 0xB782, 0x8DEF, 0xB783, 0x8DF0, 0xB785, + 0x8DF1, 0xB786, 0x8DF2, 0xB787, 0x8DF3, 0xB788, 0x8DF4, 0xB789, + 0x8DF5, 0xB78A, 0x8DF6, 0xB78B, 0x8DF7, 0xB78E, 0x8DF8, 0xB793, + 0x8DF9, 0xB794, 0x8DFA, 0xB795, 0x8DFB, 0xB79A, 0x8DFC, 0xB79B, + 0x8DFD, 0xB79D, 0x8DFE, 0xB79E, 0x8E41, 0xB79F, 0x8E42, 0xB7A1, + 0x8E43, 0xB7A2, 0x8E44, 0xB7A3, 0x8E45, 0xB7A4, 0x8E46, 0xB7A5, + 0x8E47, 0xB7A6, 0x8E48, 0xB7A7, 0x8E49, 0xB7AA, 0x8E4A, 0xB7AE, + 0x8E4B, 0xB7AF, 0x8E4C, 0xB7B0, 0x8E4D, 0xB7B1, 0x8E4E, 0xB7B2, + 0x8E4F, 0xB7B3, 0x8E50, 0xB7B6, 0x8E51, 0xB7B7, 0x8E52, 0xB7B9, + 0x8E53, 0xB7BA, 0x8E54, 0xB7BB, 0x8E55, 0xB7BC, 0x8E56, 0xB7BD, + 0x8E57, 0xB7BE, 0x8E58, 0xB7BF, 0x8E59, 0xB7C0, 0x8E5A, 0xB7C1, + 0x8E61, 0xB7C2, 0x8E62, 0xB7C3, 0x8E63, 0xB7C4, 0x8E64, 0xB7C5, + 0x8E65, 0xB7C6, 0x8E66, 0xB7C8, 0x8E67, 0xB7CA, 0x8E68, 0xB7CB, + 0x8E69, 0xB7CC, 0x8E6A, 0xB7CD, 0x8E6B, 0xB7CE, 0x8E6C, 0xB7CF, + 0x8E6D, 0xB7D0, 0x8E6E, 0xB7D1, 0x8E6F, 0xB7D2, 0x8E70, 0xB7D3, + 0x8E71, 0xB7D4, 0x8E72, 0xB7D5, 0x8E73, 0xB7D6, 0x8E74, 0xB7D7, + 0x8E75, 0xB7D8, 0x8E76, 0xB7D9, 0x8E77, 0xB7DA, 0x8E78, 0xB7DB, + 0x8E79, 0xB7DC, 0x8E7A, 0xB7DD, 0x8E81, 0xB7DE, 0x8E82, 0xB7DF, + 0x8E83, 0xB7E0, 0x8E84, 0xB7E1, 0x8E85, 0xB7E2, 0x8E86, 0xB7E3, + 0x8E87, 0xB7E4, 0x8E88, 0xB7E5, 0x8E89, 0xB7E6, 0x8E8A, 0xB7E7, + 0x8E8B, 0xB7E8, 0x8E8C, 0xB7E9, 0x8E8D, 0xB7EA, 0x8E8E, 0xB7EB, + 0x8E8F, 0xB7EE, 0x8E90, 0xB7EF, 0x8E91, 0xB7F1, 0x8E92, 0xB7F2, + 0x8E93, 0xB7F3, 0x8E94, 0xB7F5, 0x8E95, 0xB7F6, 0x8E96, 0xB7F7, + 0x8E97, 0xB7F8, 0x8E98, 0xB7F9, 0x8E99, 0xB7FA, 0x8E9A, 0xB7FB, + 0x8E9B, 0xB7FE, 0x8E9C, 0xB802, 0x8E9D, 0xB803, 0x8E9E, 0xB804, + 0x8E9F, 0xB805, 0x8EA0, 0xB806, 0x8EA1, 0xB80A, 0x8EA2, 0xB80B, + 0x8EA3, 0xB80D, 0x8EA4, 0xB80E, 0x8EA5, 0xB80F, 0x8EA6, 0xB811, + 0x8EA7, 0xB812, 0x8EA8, 0xB813, 0x8EA9, 0xB814, 0x8EAA, 0xB815, + 0x8EAB, 0xB816, 0x8EAC, 0xB817, 0x8EAD, 0xB81A, 0x8EAE, 0xB81C, + 0x8EAF, 0xB81E, 0x8EB0, 0xB81F, 0x8EB1, 0xB820, 0x8EB2, 0xB821, + 0x8EB3, 0xB822, 0x8EB4, 0xB823, 0x8EB5, 0xB826, 0x8EB6, 0xB827, + 0x8EB7, 0xB829, 0x8EB8, 0xB82A, 0x8EB9, 0xB82B, 0x8EBA, 0xB82D, + 0x8EBB, 0xB82E, 0x8EBC, 0xB82F, 0x8EBD, 0xB830, 0x8EBE, 0xB831, + 0x8EBF, 0xB832, 0x8EC0, 0xB833, 0x8EC1, 0xB836, 0x8EC2, 0xB83A, + 0x8EC3, 0xB83B, 0x8EC4, 0xB83C, 0x8EC5, 0xB83D, 0x8EC6, 0xB83E, + 0x8EC7, 0xB83F, 0x8EC8, 0xB841, 0x8EC9, 0xB842, 0x8ECA, 0xB843, + 0x8ECB, 0xB845, 0x8ECC, 0xB846, 0x8ECD, 0xB847, 0x8ECE, 0xB848, + 0x8ECF, 0xB849, 0x8ED0, 0xB84A, 0x8ED1, 0xB84B, 0x8ED2, 0xB84C, + 0x8ED3, 0xB84D, 0x8ED4, 0xB84E, 0x8ED5, 0xB84F, 0x8ED6, 0xB850, + 0x8ED7, 0xB852, 0x8ED8, 0xB854, 0x8ED9, 0xB855, 0x8EDA, 0xB856, + 0x8EDB, 0xB857, 0x8EDC, 0xB858, 0x8EDD, 0xB859, 0x8EDE, 0xB85A, + 0x8EDF, 0xB85B, 0x8EE0, 0xB85E, 0x8EE1, 0xB85F, 0x8EE2, 0xB861, + 0x8EE3, 0xB862, 0x8EE4, 0xB863, 0x8EE5, 0xB865, 0x8EE6, 0xB866, + 0x8EE7, 0xB867, 0x8EE8, 0xB868, 0x8EE9, 0xB869, 0x8EEA, 0xB86A, + 0x8EEB, 0xB86B, 0x8EEC, 0xB86E, 0x8EED, 0xB870, 0x8EEE, 0xB872, + 0x8EEF, 0xB873, 0x8EF0, 0xB874, 0x8EF1, 0xB875, 0x8EF2, 0xB876, + 0x8EF3, 0xB877, 0x8EF4, 0xB879, 0x8EF5, 0xB87A, 0x8EF6, 0xB87B, + 0x8EF7, 0xB87D, 0x8EF8, 0xB87E, 0x8EF9, 0xB87F, 0x8EFA, 0xB880, + 0x8EFB, 0xB881, 0x8EFC, 0xB882, 0x8EFD, 0xB883, 0x8EFE, 0xB884, + 0x8F41, 0xB885, 0x8F42, 0xB886, 0x8F43, 0xB887, 0x8F44, 0xB888, + 0x8F45, 0xB889, 0x8F46, 0xB88A, 0x8F47, 0xB88B, 0x8F48, 0xB88C, + 0x8F49, 0xB88E, 0x8F4A, 0xB88F, 0x8F4B, 0xB890, 0x8F4C, 0xB891, + 0x8F4D, 0xB892, 0x8F4E, 0xB893, 0x8F4F, 0xB894, 0x8F50, 0xB895, + 0x8F51, 0xB896, 0x8F52, 0xB897, 0x8F53, 0xB898, 0x8F54, 0xB899, + 0x8F55, 0xB89A, 0x8F56, 0xB89B, 0x8F57, 0xB89C, 0x8F58, 0xB89D, + 0x8F59, 0xB89E, 0x8F5A, 0xB89F, 0x8F61, 0xB8A0, 0x8F62, 0xB8A1, + 0x8F63, 0xB8A2, 0x8F64, 0xB8A3, 0x8F65, 0xB8A4, 0x8F66, 0xB8A5, + 0x8F67, 0xB8A6, 0x8F68, 0xB8A7, 0x8F69, 0xB8A9, 0x8F6A, 0xB8AA, + 0x8F6B, 0xB8AB, 0x8F6C, 0xB8AC, 0x8F6D, 0xB8AD, 0x8F6E, 0xB8AE, + 0x8F6F, 0xB8AF, 0x8F70, 0xB8B1, 0x8F71, 0xB8B2, 0x8F72, 0xB8B3, + 0x8F73, 0xB8B5, 0x8F74, 0xB8B6, 0x8F75, 0xB8B7, 0x8F76, 0xB8B9, + 0x8F77, 0xB8BA, 0x8F78, 0xB8BB, 0x8F79, 0xB8BC, 0x8F7A, 0xB8BD, + 0x8F81, 0xB8BE, 0x8F82, 0xB8BF, 0x8F83, 0xB8C2, 0x8F84, 0xB8C4, + 0x8F85, 0xB8C6, 0x8F86, 0xB8C7, 0x8F87, 0xB8C8, 0x8F88, 0xB8C9, + 0x8F89, 0xB8CA, 0x8F8A, 0xB8CB, 0x8F8B, 0xB8CD, 0x8F8C, 0xB8CE, + 0x8F8D, 0xB8CF, 0x8F8E, 0xB8D1, 0x8F8F, 0xB8D2, 0x8F90, 0xB8D3, + 0x8F91, 0xB8D5, 0x8F92, 0xB8D6, 0x8F93, 0xB8D7, 0x8F94, 0xB8D8, + 0x8F95, 0xB8D9, 0x8F96, 0xB8DA, 0x8F97, 0xB8DB, 0x8F98, 0xB8DC, + 0x8F99, 0xB8DE, 0x8F9A, 0xB8E0, 0x8F9B, 0xB8E2, 0x8F9C, 0xB8E3, + 0x8F9D, 0xB8E4, 0x8F9E, 0xB8E5, 0x8F9F, 0xB8E6, 0x8FA0, 0xB8E7, + 0x8FA1, 0xB8EA, 0x8FA2, 0xB8EB, 0x8FA3, 0xB8ED, 0x8FA4, 0xB8EE, + 0x8FA5, 0xB8EF, 0x8FA6, 0xB8F1, 0x8FA7, 0xB8F2, 0x8FA8, 0xB8F3, + 0x8FA9, 0xB8F4, 0x8FAA, 0xB8F5, 0x8FAB, 0xB8F6, 0x8FAC, 0xB8F7, + 0x8FAD, 0xB8FA, 0x8FAE, 0xB8FC, 0x8FAF, 0xB8FE, 0x8FB0, 0xB8FF, + 0x8FB1, 0xB900, 0x8FB2, 0xB901, 0x8FB3, 0xB902, 0x8FB4, 0xB903, + 0x8FB5, 0xB905, 0x8FB6, 0xB906, 0x8FB7, 0xB907, 0x8FB8, 0xB908, + 0x8FB9, 0xB909, 0x8FBA, 0xB90A, 0x8FBB, 0xB90B, 0x8FBC, 0xB90C, + 0x8FBD, 0xB90D, 0x8FBE, 0xB90E, 0x8FBF, 0xB90F, 0x8FC0, 0xB910, + 0x8FC1, 0xB911, 0x8FC2, 0xB912, 0x8FC3, 0xB913, 0x8FC4, 0xB914, + 0x8FC5, 0xB915, 0x8FC6, 0xB916, 0x8FC7, 0xB917, 0x8FC8, 0xB919, + 0x8FC9, 0xB91A, 0x8FCA, 0xB91B, 0x8FCB, 0xB91C, 0x8FCC, 0xB91D, + 0x8FCD, 0xB91E, 0x8FCE, 0xB91F, 0x8FCF, 0xB921, 0x8FD0, 0xB922, + 0x8FD1, 0xB923, 0x8FD2, 0xB924, 0x8FD3, 0xB925, 0x8FD4, 0xB926, + 0x8FD5, 0xB927, 0x8FD6, 0xB928, 0x8FD7, 0xB929, 0x8FD8, 0xB92A, + 0x8FD9, 0xB92B, 0x8FDA, 0xB92C, 0x8FDB, 0xB92D, 0x8FDC, 0xB92E, + 0x8FDD, 0xB92F, 0x8FDE, 0xB930, 0x8FDF, 0xB931, 0x8FE0, 0xB932, + 0x8FE1, 0xB933, 0x8FE2, 0xB934, 0x8FE3, 0xB935, 0x8FE4, 0xB936, + 0x8FE5, 0xB937, 0x8FE6, 0xB938, 0x8FE7, 0xB939, 0x8FE8, 0xB93A, + 0x8FE9, 0xB93B, 0x8FEA, 0xB93E, 0x8FEB, 0xB93F, 0x8FEC, 0xB941, + 0x8FED, 0xB942, 0x8FEE, 0xB943, 0x8FEF, 0xB945, 0x8FF0, 0xB946, + 0x8FF1, 0xB947, 0x8FF2, 0xB948, 0x8FF3, 0xB949, 0x8FF4, 0xB94A, + 0x8FF5, 0xB94B, 0x8FF6, 0xB94D, 0x8FF7, 0xB94E, 0x8FF8, 0xB950, + 0x8FF9, 0xB952, 0x8FFA, 0xB953, 0x8FFB, 0xB954, 0x8FFC, 0xB955, + 0x8FFD, 0xB956, 0x8FFE, 0xB957, 0x9041, 0xB95A, 0x9042, 0xB95B, + 0x9043, 0xB95D, 0x9044, 0xB95E, 0x9045, 0xB95F, 0x9046, 0xB961, + 0x9047, 0xB962, 0x9048, 0xB963, 0x9049, 0xB964, 0x904A, 0xB965, + 0x904B, 0xB966, 0x904C, 0xB967, 0x904D, 0xB96A, 0x904E, 0xB96C, + 0x904F, 0xB96E, 0x9050, 0xB96F, 0x9051, 0xB970, 0x9052, 0xB971, + 0x9053, 0xB972, 0x9054, 0xB973, 0x9055, 0xB976, 0x9056, 0xB977, + 0x9057, 0xB979, 0x9058, 0xB97A, 0x9059, 0xB97B, 0x905A, 0xB97D, + 0x9061, 0xB97E, 0x9062, 0xB97F, 0x9063, 0xB980, 0x9064, 0xB981, + 0x9065, 0xB982, 0x9066, 0xB983, 0x9067, 0xB986, 0x9068, 0xB988, + 0x9069, 0xB98B, 0x906A, 0xB98C, 0x906B, 0xB98F, 0x906C, 0xB990, + 0x906D, 0xB991, 0x906E, 0xB992, 0x906F, 0xB993, 0x9070, 0xB994, + 0x9071, 0xB995, 0x9072, 0xB996, 0x9073, 0xB997, 0x9074, 0xB998, + 0x9075, 0xB999, 0x9076, 0xB99A, 0x9077, 0xB99B, 0x9078, 0xB99C, + 0x9079, 0xB99D, 0x907A, 0xB99E, 0x9081, 0xB99F, 0x9082, 0xB9A0, + 0x9083, 0xB9A1, 0x9084, 0xB9A2, 0x9085, 0xB9A3, 0x9086, 0xB9A4, + 0x9087, 0xB9A5, 0x9088, 0xB9A6, 0x9089, 0xB9A7, 0x908A, 0xB9A8, + 0x908B, 0xB9A9, 0x908C, 0xB9AA, 0x908D, 0xB9AB, 0x908E, 0xB9AE, + 0x908F, 0xB9AF, 0x9090, 0xB9B1, 0x9091, 0xB9B2, 0x9092, 0xB9B3, + 0x9093, 0xB9B5, 0x9094, 0xB9B6, 0x9095, 0xB9B7, 0x9096, 0xB9B8, + 0x9097, 0xB9B9, 0x9098, 0xB9BA, 0x9099, 0xB9BB, 0x909A, 0xB9BE, + 0x909B, 0xB9C0, 0x909C, 0xB9C2, 0x909D, 0xB9C3, 0x909E, 0xB9C4, + 0x909F, 0xB9C5, 0x90A0, 0xB9C6, 0x90A1, 0xB9C7, 0x90A2, 0xB9CA, + 0x90A3, 0xB9CB, 0x90A4, 0xB9CD, 0x90A5, 0xB9D3, 0x90A6, 0xB9D4, + 0x90A7, 0xB9D5, 0x90A8, 0xB9D6, 0x90A9, 0xB9D7, 0x90AA, 0xB9DA, + 0x90AB, 0xB9DC, 0x90AC, 0xB9DF, 0x90AD, 0xB9E0, 0x90AE, 0xB9E2, + 0x90AF, 0xB9E6, 0x90B0, 0xB9E7, 0x90B1, 0xB9E9, 0x90B2, 0xB9EA, + 0x90B3, 0xB9EB, 0x90B4, 0xB9ED, 0x90B5, 0xB9EE, 0x90B6, 0xB9EF, + 0x90B7, 0xB9F0, 0x90B8, 0xB9F1, 0x90B9, 0xB9F2, 0x90BA, 0xB9F3, + 0x90BB, 0xB9F6, 0x90BC, 0xB9FB, 0x90BD, 0xB9FC, 0x90BE, 0xB9FD, + 0x90BF, 0xB9FE, 0x90C0, 0xB9FF, 0x90C1, 0xBA02, 0x90C2, 0xBA03, + 0x90C3, 0xBA04, 0x90C4, 0xBA05, 0x90C5, 0xBA06, 0x90C6, 0xBA07, + 0x90C7, 0xBA09, 0x90C8, 0xBA0A, 0x90C9, 0xBA0B, 0x90CA, 0xBA0C, + 0x90CB, 0xBA0D, 0x90CC, 0xBA0E, 0x90CD, 0xBA0F, 0x90CE, 0xBA10, + 0x90CF, 0xBA11, 0x90D0, 0xBA12, 0x90D1, 0xBA13, 0x90D2, 0xBA14, + 0x90D3, 0xBA16, 0x90D4, 0xBA17, 0x90D5, 0xBA18, 0x90D6, 0xBA19, + 0x90D7, 0xBA1A, 0x90D8, 0xBA1B, 0x90D9, 0xBA1C, 0x90DA, 0xBA1D, + 0x90DB, 0xBA1E, 0x90DC, 0xBA1F, 0x90DD, 0xBA20, 0x90DE, 0xBA21, + 0x90DF, 0xBA22, 0x90E0, 0xBA23, 0x90E1, 0xBA24, 0x90E2, 0xBA25, + 0x90E3, 0xBA26, 0x90E4, 0xBA27, 0x90E5, 0xBA28, 0x90E6, 0xBA29, + 0x90E7, 0xBA2A, 0x90E8, 0xBA2B, 0x90E9, 0xBA2C, 0x90EA, 0xBA2D, + 0x90EB, 0xBA2E, 0x90EC, 0xBA2F, 0x90ED, 0xBA30, 0x90EE, 0xBA31, + 0x90EF, 0xBA32, 0x90F0, 0xBA33, 0x90F1, 0xBA34, 0x90F2, 0xBA35, + 0x90F3, 0xBA36, 0x90F4, 0xBA37, 0x90F5, 0xBA3A, 0x90F6, 0xBA3B, + 0x90F7, 0xBA3D, 0x90F8, 0xBA3E, 0x90F9, 0xBA3F, 0x90FA, 0xBA41, + 0x90FB, 0xBA43, 0x90FC, 0xBA44, 0x90FD, 0xBA45, 0x90FE, 0xBA46, + 0x9141, 0xBA47, 0x9142, 0xBA4A, 0x9143, 0xBA4C, 0x9144, 0xBA4F, + 0x9145, 0xBA50, 0x9146, 0xBA51, 0x9147, 0xBA52, 0x9148, 0xBA56, + 0x9149, 0xBA57, 0x914A, 0xBA59, 0x914B, 0xBA5A, 0x914C, 0xBA5B, + 0x914D, 0xBA5D, 0x914E, 0xBA5E, 0x914F, 0xBA5F, 0x9150, 0xBA60, + 0x9151, 0xBA61, 0x9152, 0xBA62, 0x9153, 0xBA63, 0x9154, 0xBA66, + 0x9155, 0xBA6A, 0x9156, 0xBA6B, 0x9157, 0xBA6C, 0x9158, 0xBA6D, + 0x9159, 0xBA6E, 0x915A, 0xBA6F, 0x9161, 0xBA72, 0x9162, 0xBA73, + 0x9163, 0xBA75, 0x9164, 0xBA76, 0x9165, 0xBA77, 0x9166, 0xBA79, + 0x9167, 0xBA7A, 0x9168, 0xBA7B, 0x9169, 0xBA7C, 0x916A, 0xBA7D, + 0x916B, 0xBA7E, 0x916C, 0xBA7F, 0x916D, 0xBA80, 0x916E, 0xBA81, + 0x916F, 0xBA82, 0x9170, 0xBA86, 0x9171, 0xBA88, 0x9172, 0xBA89, + 0x9173, 0xBA8A, 0x9174, 0xBA8B, 0x9175, 0xBA8D, 0x9176, 0xBA8E, + 0x9177, 0xBA8F, 0x9178, 0xBA90, 0x9179, 0xBA91, 0x917A, 0xBA92, + 0x9181, 0xBA93, 0x9182, 0xBA94, 0x9183, 0xBA95, 0x9184, 0xBA96, + 0x9185, 0xBA97, 0x9186, 0xBA98, 0x9187, 0xBA99, 0x9188, 0xBA9A, + 0x9189, 0xBA9B, 0x918A, 0xBA9C, 0x918B, 0xBA9D, 0x918C, 0xBA9E, + 0x918D, 0xBA9F, 0x918E, 0xBAA0, 0x918F, 0xBAA1, 0x9190, 0xBAA2, + 0x9191, 0xBAA3, 0x9192, 0xBAA4, 0x9193, 0xBAA5, 0x9194, 0xBAA6, + 0x9195, 0xBAA7, 0x9196, 0xBAAA, 0x9197, 0xBAAD, 0x9198, 0xBAAE, + 0x9199, 0xBAAF, 0x919A, 0xBAB1, 0x919B, 0xBAB3, 0x919C, 0xBAB4, + 0x919D, 0xBAB5, 0x919E, 0xBAB6, 0x919F, 0xBAB7, 0x91A0, 0xBABA, + 0x91A1, 0xBABC, 0x91A2, 0xBABE, 0x91A3, 0xBABF, 0x91A4, 0xBAC0, + 0x91A5, 0xBAC1, 0x91A6, 0xBAC2, 0x91A7, 0xBAC3, 0x91A8, 0xBAC5, + 0x91A9, 0xBAC6, 0x91AA, 0xBAC7, 0x91AB, 0xBAC9, 0x91AC, 0xBACA, + 0x91AD, 0xBACB, 0x91AE, 0xBACC, 0x91AF, 0xBACD, 0x91B0, 0xBACE, + 0x91B1, 0xBACF, 0x91B2, 0xBAD0, 0x91B3, 0xBAD1, 0x91B4, 0xBAD2, + 0x91B5, 0xBAD3, 0x91B6, 0xBAD4, 0x91B7, 0xBAD5, 0x91B8, 0xBAD6, + 0x91B9, 0xBAD7, 0x91BA, 0xBADA, 0x91BB, 0xBADB, 0x91BC, 0xBADC, + 0x91BD, 0xBADD, 0x91BE, 0xBADE, 0x91BF, 0xBADF, 0x91C0, 0xBAE0, + 0x91C1, 0xBAE1, 0x91C2, 0xBAE2, 0x91C3, 0xBAE3, 0x91C4, 0xBAE4, + 0x91C5, 0xBAE5, 0x91C6, 0xBAE6, 0x91C7, 0xBAE7, 0x91C8, 0xBAE8, + 0x91C9, 0xBAE9, 0x91CA, 0xBAEA, 0x91CB, 0xBAEB, 0x91CC, 0xBAEC, + 0x91CD, 0xBAED, 0x91CE, 0xBAEE, 0x91CF, 0xBAEF, 0x91D0, 0xBAF0, + 0x91D1, 0xBAF1, 0x91D2, 0xBAF2, 0x91D3, 0xBAF3, 0x91D4, 0xBAF4, + 0x91D5, 0xBAF5, 0x91D6, 0xBAF6, 0x91D7, 0xBAF7, 0x91D8, 0xBAF8, + 0x91D9, 0xBAF9, 0x91DA, 0xBAFA, 0x91DB, 0xBAFB, 0x91DC, 0xBAFD, + 0x91DD, 0xBAFE, 0x91DE, 0xBAFF, 0x91DF, 0xBB01, 0x91E0, 0xBB02, + 0x91E1, 0xBB03, 0x91E2, 0xBB05, 0x91E3, 0xBB06, 0x91E4, 0xBB07, + 0x91E5, 0xBB08, 0x91E6, 0xBB09, 0x91E7, 0xBB0A, 0x91E8, 0xBB0B, + 0x91E9, 0xBB0C, 0x91EA, 0xBB0E, 0x91EB, 0xBB10, 0x91EC, 0xBB12, + 0x91ED, 0xBB13, 0x91EE, 0xBB14, 0x91EF, 0xBB15, 0x91F0, 0xBB16, + 0x91F1, 0xBB17, 0x91F2, 0xBB19, 0x91F3, 0xBB1A, 0x91F4, 0xBB1B, + 0x91F5, 0xBB1D, 0x91F6, 0xBB1E, 0x91F7, 0xBB1F, 0x91F8, 0xBB21, + 0x91F9, 0xBB22, 0x91FA, 0xBB23, 0x91FB, 0xBB24, 0x91FC, 0xBB25, + 0x91FD, 0xBB26, 0x91FE, 0xBB27, 0x9241, 0xBB28, 0x9242, 0xBB2A, + 0x9243, 0xBB2C, 0x9244, 0xBB2D, 0x9245, 0xBB2E, 0x9246, 0xBB2F, + 0x9247, 0xBB30, 0x9248, 0xBB31, 0x9249, 0xBB32, 0x924A, 0xBB33, + 0x924B, 0xBB37, 0x924C, 0xBB39, 0x924D, 0xBB3A, 0x924E, 0xBB3F, + 0x924F, 0xBB40, 0x9250, 0xBB41, 0x9251, 0xBB42, 0x9252, 0xBB43, + 0x9253, 0xBB46, 0x9254, 0xBB48, 0x9255, 0xBB4A, 0x9256, 0xBB4B, + 0x9257, 0xBB4C, 0x9258, 0xBB4E, 0x9259, 0xBB51, 0x925A, 0xBB52, + 0x9261, 0xBB53, 0x9262, 0xBB55, 0x9263, 0xBB56, 0x9264, 0xBB57, + 0x9265, 0xBB59, 0x9266, 0xBB5A, 0x9267, 0xBB5B, 0x9268, 0xBB5C, + 0x9269, 0xBB5D, 0x926A, 0xBB5E, 0x926B, 0xBB5F, 0x926C, 0xBB60, + 0x926D, 0xBB62, 0x926E, 0xBB64, 0x926F, 0xBB65, 0x9270, 0xBB66, + 0x9271, 0xBB67, 0x9272, 0xBB68, 0x9273, 0xBB69, 0x9274, 0xBB6A, + 0x9275, 0xBB6B, 0x9276, 0xBB6D, 0x9277, 0xBB6E, 0x9278, 0xBB6F, + 0x9279, 0xBB70, 0x927A, 0xBB71, 0x9281, 0xBB72, 0x9282, 0xBB73, + 0x9283, 0xBB74, 0x9284, 0xBB75, 0x9285, 0xBB76, 0x9286, 0xBB77, + 0x9287, 0xBB78, 0x9288, 0xBB79, 0x9289, 0xBB7A, 0x928A, 0xBB7B, + 0x928B, 0xBB7C, 0x928C, 0xBB7D, 0x928D, 0xBB7E, 0x928E, 0xBB7F, + 0x928F, 0xBB80, 0x9290, 0xBB81, 0x9291, 0xBB82, 0x9292, 0xBB83, + 0x9293, 0xBB84, 0x9294, 0xBB85, 0x9295, 0xBB86, 0x9296, 0xBB87, + 0x9297, 0xBB89, 0x9298, 0xBB8A, 0x9299, 0xBB8B, 0x929A, 0xBB8D, + 0x929B, 0xBB8E, 0x929C, 0xBB8F, 0x929D, 0xBB91, 0x929E, 0xBB92, + 0x929F, 0xBB93, 0x92A0, 0xBB94, 0x92A1, 0xBB95, 0x92A2, 0xBB96, + 0x92A3, 0xBB97, 0x92A4, 0xBB98, 0x92A5, 0xBB99, 0x92A6, 0xBB9A, + 0x92A7, 0xBB9B, 0x92A8, 0xBB9C, 0x92A9, 0xBB9D, 0x92AA, 0xBB9E, + 0x92AB, 0xBB9F, 0x92AC, 0xBBA0, 0x92AD, 0xBBA1, 0x92AE, 0xBBA2, + 0x92AF, 0xBBA3, 0x92B0, 0xBBA5, 0x92B1, 0xBBA6, 0x92B2, 0xBBA7, + 0x92B3, 0xBBA9, 0x92B4, 0xBBAA, 0x92B5, 0xBBAB, 0x92B6, 0xBBAD, + 0x92B7, 0xBBAE, 0x92B8, 0xBBAF, 0x92B9, 0xBBB0, 0x92BA, 0xBBB1, + 0x92BB, 0xBBB2, 0x92BC, 0xBBB3, 0x92BD, 0xBBB5, 0x92BE, 0xBBB6, + 0x92BF, 0xBBB8, 0x92C0, 0xBBB9, 0x92C1, 0xBBBA, 0x92C2, 0xBBBB, + 0x92C3, 0xBBBC, 0x92C4, 0xBBBD, 0x92C5, 0xBBBE, 0x92C6, 0xBBBF, + 0x92C7, 0xBBC1, 0x92C8, 0xBBC2, 0x92C9, 0xBBC3, 0x92CA, 0xBBC5, + 0x92CB, 0xBBC6, 0x92CC, 0xBBC7, 0x92CD, 0xBBC9, 0x92CE, 0xBBCA, + 0x92CF, 0xBBCB, 0x92D0, 0xBBCC, 0x92D1, 0xBBCD, 0x92D2, 0xBBCE, + 0x92D3, 0xBBCF, 0x92D4, 0xBBD1, 0x92D5, 0xBBD2, 0x92D6, 0xBBD4, + 0x92D7, 0xBBD5, 0x92D8, 0xBBD6, 0x92D9, 0xBBD7, 0x92DA, 0xBBD8, + 0x92DB, 0xBBD9, 0x92DC, 0xBBDA, 0x92DD, 0xBBDB, 0x92DE, 0xBBDC, + 0x92DF, 0xBBDD, 0x92E0, 0xBBDE, 0x92E1, 0xBBDF, 0x92E2, 0xBBE0, + 0x92E3, 0xBBE1, 0x92E4, 0xBBE2, 0x92E5, 0xBBE3, 0x92E6, 0xBBE4, + 0x92E7, 0xBBE5, 0x92E8, 0xBBE6, 0x92E9, 0xBBE7, 0x92EA, 0xBBE8, + 0x92EB, 0xBBE9, 0x92EC, 0xBBEA, 0x92ED, 0xBBEB, 0x92EE, 0xBBEC, + 0x92EF, 0xBBED, 0x92F0, 0xBBEE, 0x92F1, 0xBBEF, 0x92F2, 0xBBF0, + 0x92F3, 0xBBF1, 0x92F4, 0xBBF2, 0x92F5, 0xBBF3, 0x92F6, 0xBBF4, + 0x92F7, 0xBBF5, 0x92F8, 0xBBF6, 0x92F9, 0xBBF7, 0x92FA, 0xBBFA, + 0x92FB, 0xBBFB, 0x92FC, 0xBBFD, 0x92FD, 0xBBFE, 0x92FE, 0xBC01, + 0x9341, 0xBC03, 0x9342, 0xBC04, 0x9343, 0xBC05, 0x9344, 0xBC06, + 0x9345, 0xBC07, 0x9346, 0xBC0A, 0x9347, 0xBC0E, 0x9348, 0xBC10, + 0x9349, 0xBC12, 0x934A, 0xBC13, 0x934B, 0xBC19, 0x934C, 0xBC1A, + 0x934D, 0xBC20, 0x934E, 0xBC21, 0x934F, 0xBC22, 0x9350, 0xBC23, + 0x9351, 0xBC26, 0x9352, 0xBC28, 0x9353, 0xBC2A, 0x9354, 0xBC2B, + 0x9355, 0xBC2C, 0x9356, 0xBC2E, 0x9357, 0xBC2F, 0x9358, 0xBC32, + 0x9359, 0xBC33, 0x935A, 0xBC35, 0x9361, 0xBC36, 0x9362, 0xBC37, + 0x9363, 0xBC39, 0x9364, 0xBC3A, 0x9365, 0xBC3B, 0x9366, 0xBC3C, + 0x9367, 0xBC3D, 0x9368, 0xBC3E, 0x9369, 0xBC3F, 0x936A, 0xBC42, + 0x936B, 0xBC46, 0x936C, 0xBC47, 0x936D, 0xBC48, 0x936E, 0xBC4A, + 0x936F, 0xBC4B, 0x9370, 0xBC4E, 0x9371, 0xBC4F, 0x9372, 0xBC51, + 0x9373, 0xBC52, 0x9374, 0xBC53, 0x9375, 0xBC54, 0x9376, 0xBC55, + 0x9377, 0xBC56, 0x9378, 0xBC57, 0x9379, 0xBC58, 0x937A, 0xBC59, + 0x9381, 0xBC5A, 0x9382, 0xBC5B, 0x9383, 0xBC5C, 0x9384, 0xBC5E, + 0x9385, 0xBC5F, 0x9386, 0xBC60, 0x9387, 0xBC61, 0x9388, 0xBC62, + 0x9389, 0xBC63, 0x938A, 0xBC64, 0x938B, 0xBC65, 0x938C, 0xBC66, + 0x938D, 0xBC67, 0x938E, 0xBC68, 0x938F, 0xBC69, 0x9390, 0xBC6A, + 0x9391, 0xBC6B, 0x9392, 0xBC6C, 0x9393, 0xBC6D, 0x9394, 0xBC6E, + 0x9395, 0xBC6F, 0x9396, 0xBC70, 0x9397, 0xBC71, 0x9398, 0xBC72, + 0x9399, 0xBC73, 0x939A, 0xBC74, 0x939B, 0xBC75, 0x939C, 0xBC76, + 0x939D, 0xBC77, 0x939E, 0xBC78, 0x939F, 0xBC79, 0x93A0, 0xBC7A, + 0x93A1, 0xBC7B, 0x93A2, 0xBC7C, 0x93A3, 0xBC7D, 0x93A4, 0xBC7E, + 0x93A5, 0xBC7F, 0x93A6, 0xBC80, 0x93A7, 0xBC81, 0x93A8, 0xBC82, + 0x93A9, 0xBC83, 0x93AA, 0xBC86, 0x93AB, 0xBC87, 0x93AC, 0xBC89, + 0x93AD, 0xBC8A, 0x93AE, 0xBC8D, 0x93AF, 0xBC8F, 0x93B0, 0xBC90, + 0x93B1, 0xBC91, 0x93B2, 0xBC92, 0x93B3, 0xBC93, 0x93B4, 0xBC96, + 0x93B5, 0xBC98, 0x93B6, 0xBC9B, 0x93B7, 0xBC9C, 0x93B8, 0xBC9D, + 0x93B9, 0xBC9E, 0x93BA, 0xBC9F, 0x93BB, 0xBCA2, 0x93BC, 0xBCA3, + 0x93BD, 0xBCA5, 0x93BE, 0xBCA6, 0x93BF, 0xBCA9, 0x93C0, 0xBCAA, + 0x93C1, 0xBCAB, 0x93C2, 0xBCAC, 0x93C3, 0xBCAD, 0x93C4, 0xBCAE, + 0x93C5, 0xBCAF, 0x93C6, 0xBCB2, 0x93C7, 0xBCB6, 0x93C8, 0xBCB7, + 0x93C9, 0xBCB8, 0x93CA, 0xBCB9, 0x93CB, 0xBCBA, 0x93CC, 0xBCBB, + 0x93CD, 0xBCBE, 0x93CE, 0xBCBF, 0x93CF, 0xBCC1, 0x93D0, 0xBCC2, + 0x93D1, 0xBCC3, 0x93D2, 0xBCC5, 0x93D3, 0xBCC6, 0x93D4, 0xBCC7, + 0x93D5, 0xBCC8, 0x93D6, 0xBCC9, 0x93D7, 0xBCCA, 0x93D8, 0xBCCB, + 0x93D9, 0xBCCC, 0x93DA, 0xBCCE, 0x93DB, 0xBCD2, 0x93DC, 0xBCD3, + 0x93DD, 0xBCD4, 0x93DE, 0xBCD6, 0x93DF, 0xBCD7, 0x93E0, 0xBCD9, + 0x93E1, 0xBCDA, 0x93E2, 0xBCDB, 0x93E3, 0xBCDD, 0x93E4, 0xBCDE, + 0x93E5, 0xBCDF, 0x93E6, 0xBCE0, 0x93E7, 0xBCE1, 0x93E8, 0xBCE2, + 0x93E9, 0xBCE3, 0x93EA, 0xBCE4, 0x93EB, 0xBCE5, 0x93EC, 0xBCE6, + 0x93ED, 0xBCE7, 0x93EE, 0xBCE8, 0x93EF, 0xBCE9, 0x93F0, 0xBCEA, + 0x93F1, 0xBCEB, 0x93F2, 0xBCEC, 0x93F3, 0xBCED, 0x93F4, 0xBCEE, + 0x93F5, 0xBCEF, 0x93F6, 0xBCF0, 0x93F7, 0xBCF1, 0x93F8, 0xBCF2, + 0x93F9, 0xBCF3, 0x93FA, 0xBCF7, 0x93FB, 0xBCF9, 0x93FC, 0xBCFA, + 0x93FD, 0xBCFB, 0x93FE, 0xBCFD, 0x9441, 0xBCFE, 0x9442, 0xBCFF, + 0x9443, 0xBD00, 0x9444, 0xBD01, 0x9445, 0xBD02, 0x9446, 0xBD03, + 0x9447, 0xBD06, 0x9448, 0xBD08, 0x9449, 0xBD0A, 0x944A, 0xBD0B, + 0x944B, 0xBD0C, 0x944C, 0xBD0D, 0x944D, 0xBD0E, 0x944E, 0xBD0F, + 0x944F, 0xBD11, 0x9450, 0xBD12, 0x9451, 0xBD13, 0x9452, 0xBD15, + 0x9453, 0xBD16, 0x9454, 0xBD17, 0x9455, 0xBD18, 0x9456, 0xBD19, + 0x9457, 0xBD1A, 0x9458, 0xBD1B, 0x9459, 0xBD1C, 0x945A, 0xBD1D, + 0x9461, 0xBD1E, 0x9462, 0xBD1F, 0x9463, 0xBD20, 0x9464, 0xBD21, + 0x9465, 0xBD22, 0x9466, 0xBD23, 0x9467, 0xBD25, 0x9468, 0xBD26, + 0x9469, 0xBD27, 0x946A, 0xBD28, 0x946B, 0xBD29, 0x946C, 0xBD2A, + 0x946D, 0xBD2B, 0x946E, 0xBD2D, 0x946F, 0xBD2E, 0x9470, 0xBD2F, + 0x9471, 0xBD30, 0x9472, 0xBD31, 0x9473, 0xBD32, 0x9474, 0xBD33, + 0x9475, 0xBD34, 0x9476, 0xBD35, 0x9477, 0xBD36, 0x9478, 0xBD37, + 0x9479, 0xBD38, 0x947A, 0xBD39, 0x9481, 0xBD3A, 0x9482, 0xBD3B, + 0x9483, 0xBD3C, 0x9484, 0xBD3D, 0x9485, 0xBD3E, 0x9486, 0xBD3F, + 0x9487, 0xBD41, 0x9488, 0xBD42, 0x9489, 0xBD43, 0x948A, 0xBD44, + 0x948B, 0xBD45, 0x948C, 0xBD46, 0x948D, 0xBD47, 0x948E, 0xBD4A, + 0x948F, 0xBD4B, 0x9490, 0xBD4D, 0x9491, 0xBD4E, 0x9492, 0xBD4F, + 0x9493, 0xBD51, 0x9494, 0xBD52, 0x9495, 0xBD53, 0x9496, 0xBD54, + 0x9497, 0xBD55, 0x9498, 0xBD56, 0x9499, 0xBD57, 0x949A, 0xBD5A, + 0x949B, 0xBD5B, 0x949C, 0xBD5C, 0x949D, 0xBD5D, 0x949E, 0xBD5E, + 0x949F, 0xBD5F, 0x94A0, 0xBD60, 0x94A1, 0xBD61, 0x94A2, 0xBD62, + 0x94A3, 0xBD63, 0x94A4, 0xBD65, 0x94A5, 0xBD66, 0x94A6, 0xBD67, + 0x94A7, 0xBD69, 0x94A8, 0xBD6A, 0x94A9, 0xBD6B, 0x94AA, 0xBD6C, + 0x94AB, 0xBD6D, 0x94AC, 0xBD6E, 0x94AD, 0xBD6F, 0x94AE, 0xBD70, + 0x94AF, 0xBD71, 0x94B0, 0xBD72, 0x94B1, 0xBD73, 0x94B2, 0xBD74, + 0x94B3, 0xBD75, 0x94B4, 0xBD76, 0x94B5, 0xBD77, 0x94B6, 0xBD78, + 0x94B7, 0xBD79, 0x94B8, 0xBD7A, 0x94B9, 0xBD7B, 0x94BA, 0xBD7C, + 0x94BB, 0xBD7D, 0x94BC, 0xBD7E, 0x94BD, 0xBD7F, 0x94BE, 0xBD82, + 0x94BF, 0xBD83, 0x94C0, 0xBD85, 0x94C1, 0xBD86, 0x94C2, 0xBD8B, + 0x94C3, 0xBD8C, 0x94C4, 0xBD8D, 0x94C5, 0xBD8E, 0x94C6, 0xBD8F, + 0x94C7, 0xBD92, 0x94C8, 0xBD94, 0x94C9, 0xBD96, 0x94CA, 0xBD97, + 0x94CB, 0xBD98, 0x94CC, 0xBD9B, 0x94CD, 0xBD9D, 0x94CE, 0xBD9E, + 0x94CF, 0xBD9F, 0x94D0, 0xBDA0, 0x94D1, 0xBDA1, 0x94D2, 0xBDA2, + 0x94D3, 0xBDA3, 0x94D4, 0xBDA5, 0x94D5, 0xBDA6, 0x94D6, 0xBDA7, + 0x94D7, 0xBDA8, 0x94D8, 0xBDA9, 0x94D9, 0xBDAA, 0x94DA, 0xBDAB, + 0x94DB, 0xBDAC, 0x94DC, 0xBDAD, 0x94DD, 0xBDAE, 0x94DE, 0xBDAF, + 0x94DF, 0xBDB1, 0x94E0, 0xBDB2, 0x94E1, 0xBDB3, 0x94E2, 0xBDB4, + 0x94E3, 0xBDB5, 0x94E4, 0xBDB6, 0x94E5, 0xBDB7, 0x94E6, 0xBDB9, + 0x94E7, 0xBDBA, 0x94E8, 0xBDBB, 0x94E9, 0xBDBC, 0x94EA, 0xBDBD, + 0x94EB, 0xBDBE, 0x94EC, 0xBDBF, 0x94ED, 0xBDC0, 0x94EE, 0xBDC1, + 0x94EF, 0xBDC2, 0x94F0, 0xBDC3, 0x94F1, 0xBDC4, 0x94F2, 0xBDC5, + 0x94F3, 0xBDC6, 0x94F4, 0xBDC7, 0x94F5, 0xBDC8, 0x94F6, 0xBDC9, + 0x94F7, 0xBDCA, 0x94F8, 0xBDCB, 0x94F9, 0xBDCC, 0x94FA, 0xBDCD, + 0x94FB, 0xBDCE, 0x94FC, 0xBDCF, 0x94FD, 0xBDD0, 0x94FE, 0xBDD1, + 0x9541, 0xBDD2, 0x9542, 0xBDD3, 0x9543, 0xBDD6, 0x9544, 0xBDD7, + 0x9545, 0xBDD9, 0x9546, 0xBDDA, 0x9547, 0xBDDB, 0x9548, 0xBDDD, + 0x9549, 0xBDDE, 0x954A, 0xBDDF, 0x954B, 0xBDE0, 0x954C, 0xBDE1, + 0x954D, 0xBDE2, 0x954E, 0xBDE3, 0x954F, 0xBDE4, 0x9550, 0xBDE5, + 0x9551, 0xBDE6, 0x9552, 0xBDE7, 0x9553, 0xBDE8, 0x9554, 0xBDEA, + 0x9555, 0xBDEB, 0x9556, 0xBDEC, 0x9557, 0xBDED, 0x9558, 0xBDEE, + 0x9559, 0xBDEF, 0x955A, 0xBDF1, 0x9561, 0xBDF2, 0x9562, 0xBDF3, + 0x9563, 0xBDF5, 0x9564, 0xBDF6, 0x9565, 0xBDF7, 0x9566, 0xBDF9, + 0x9567, 0xBDFA, 0x9568, 0xBDFB, 0x9569, 0xBDFC, 0x956A, 0xBDFD, + 0x956B, 0xBDFE, 0x956C, 0xBDFF, 0x956D, 0xBE01, 0x956E, 0xBE02, + 0x956F, 0xBE04, 0x9570, 0xBE06, 0x9571, 0xBE07, 0x9572, 0xBE08, + 0x9573, 0xBE09, 0x9574, 0xBE0A, 0x9575, 0xBE0B, 0x9576, 0xBE0E, + 0x9577, 0xBE0F, 0x9578, 0xBE11, 0x9579, 0xBE12, 0x957A, 0xBE13, + 0x9581, 0xBE15, 0x9582, 0xBE16, 0x9583, 0xBE17, 0x9584, 0xBE18, + 0x9585, 0xBE19, 0x9586, 0xBE1A, 0x9587, 0xBE1B, 0x9588, 0xBE1E, + 0x9589, 0xBE20, 0x958A, 0xBE21, 0x958B, 0xBE22, 0x958C, 0xBE23, + 0x958D, 0xBE24, 0x958E, 0xBE25, 0x958F, 0xBE26, 0x9590, 0xBE27, + 0x9591, 0xBE28, 0x9592, 0xBE29, 0x9593, 0xBE2A, 0x9594, 0xBE2B, + 0x9595, 0xBE2C, 0x9596, 0xBE2D, 0x9597, 0xBE2E, 0x9598, 0xBE2F, + 0x9599, 0xBE30, 0x959A, 0xBE31, 0x959B, 0xBE32, 0x959C, 0xBE33, + 0x959D, 0xBE34, 0x959E, 0xBE35, 0x959F, 0xBE36, 0x95A0, 0xBE37, + 0x95A1, 0xBE38, 0x95A2, 0xBE39, 0x95A3, 0xBE3A, 0x95A4, 0xBE3B, + 0x95A5, 0xBE3C, 0x95A6, 0xBE3D, 0x95A7, 0xBE3E, 0x95A8, 0xBE3F, + 0x95A9, 0xBE40, 0x95AA, 0xBE41, 0x95AB, 0xBE42, 0x95AC, 0xBE43, + 0x95AD, 0xBE46, 0x95AE, 0xBE47, 0x95AF, 0xBE49, 0x95B0, 0xBE4A, + 0x95B1, 0xBE4B, 0x95B2, 0xBE4D, 0x95B3, 0xBE4F, 0x95B4, 0xBE50, + 0x95B5, 0xBE51, 0x95B6, 0xBE52, 0x95B7, 0xBE53, 0x95B8, 0xBE56, + 0x95B9, 0xBE58, 0x95BA, 0xBE5C, 0x95BB, 0xBE5D, 0x95BC, 0xBE5E, + 0x95BD, 0xBE5F, 0x95BE, 0xBE62, 0x95BF, 0xBE63, 0x95C0, 0xBE65, + 0x95C1, 0xBE66, 0x95C2, 0xBE67, 0x95C3, 0xBE69, 0x95C4, 0xBE6B, + 0x95C5, 0xBE6C, 0x95C6, 0xBE6D, 0x95C7, 0xBE6E, 0x95C8, 0xBE6F, + 0x95C9, 0xBE72, 0x95CA, 0xBE76, 0x95CB, 0xBE77, 0x95CC, 0xBE78, + 0x95CD, 0xBE79, 0x95CE, 0xBE7A, 0x95CF, 0xBE7E, 0x95D0, 0xBE7F, + 0x95D1, 0xBE81, 0x95D2, 0xBE82, 0x95D3, 0xBE83, 0x95D4, 0xBE85, + 0x95D5, 0xBE86, 0x95D6, 0xBE87, 0x95D7, 0xBE88, 0x95D8, 0xBE89, + 0x95D9, 0xBE8A, 0x95DA, 0xBE8B, 0x95DB, 0xBE8E, 0x95DC, 0xBE92, + 0x95DD, 0xBE93, 0x95DE, 0xBE94, 0x95DF, 0xBE95, 0x95E0, 0xBE96, + 0x95E1, 0xBE97, 0x95E2, 0xBE9A, 0x95E3, 0xBE9B, 0x95E4, 0xBE9C, + 0x95E5, 0xBE9D, 0x95E6, 0xBE9E, 0x95E7, 0xBE9F, 0x95E8, 0xBEA0, + 0x95E9, 0xBEA1, 0x95EA, 0xBEA2, 0x95EB, 0xBEA3, 0x95EC, 0xBEA4, + 0x95ED, 0xBEA5, 0x95EE, 0xBEA6, 0x95EF, 0xBEA7, 0x95F0, 0xBEA9, + 0x95F1, 0xBEAA, 0x95F2, 0xBEAB, 0x95F3, 0xBEAC, 0x95F4, 0xBEAD, + 0x95F5, 0xBEAE, 0x95F6, 0xBEAF, 0x95F7, 0xBEB0, 0x95F8, 0xBEB1, + 0x95F9, 0xBEB2, 0x95FA, 0xBEB3, 0x95FB, 0xBEB4, 0x95FC, 0xBEB5, + 0x95FD, 0xBEB6, 0x95FE, 0xBEB7, 0x9641, 0xBEB8, 0x9642, 0xBEB9, + 0x9643, 0xBEBA, 0x9644, 0xBEBB, 0x9645, 0xBEBC, 0x9646, 0xBEBD, + 0x9647, 0xBEBE, 0x9648, 0xBEBF, 0x9649, 0xBEC0, 0x964A, 0xBEC1, + 0x964B, 0xBEC2, 0x964C, 0xBEC3, 0x964D, 0xBEC4, 0x964E, 0xBEC5, + 0x964F, 0xBEC6, 0x9650, 0xBEC7, 0x9651, 0xBEC8, 0x9652, 0xBEC9, + 0x9653, 0xBECA, 0x9654, 0xBECB, 0x9655, 0xBECC, 0x9656, 0xBECD, + 0x9657, 0xBECE, 0x9658, 0xBECF, 0x9659, 0xBED2, 0x965A, 0xBED3, + 0x9661, 0xBED5, 0x9662, 0xBED6, 0x9663, 0xBED9, 0x9664, 0xBEDA, + 0x9665, 0xBEDB, 0x9666, 0xBEDC, 0x9667, 0xBEDD, 0x9668, 0xBEDE, + 0x9669, 0xBEDF, 0x966A, 0xBEE1, 0x966B, 0xBEE2, 0x966C, 0xBEE6, + 0x966D, 0xBEE7, 0x966E, 0xBEE8, 0x966F, 0xBEE9, 0x9670, 0xBEEA, + 0x9671, 0xBEEB, 0x9672, 0xBEED, 0x9673, 0xBEEE, 0x9674, 0xBEEF, + 0x9675, 0xBEF0, 0x9676, 0xBEF1, 0x9677, 0xBEF2, 0x9678, 0xBEF3, + 0x9679, 0xBEF4, 0x967A, 0xBEF5, 0x9681, 0xBEF6, 0x9682, 0xBEF7, + 0x9683, 0xBEF8, 0x9684, 0xBEF9, 0x9685, 0xBEFA, 0x9686, 0xBEFB, + 0x9687, 0xBEFC, 0x9688, 0xBEFD, 0x9689, 0xBEFE, 0x968A, 0xBEFF, + 0x968B, 0xBF00, 0x968C, 0xBF02, 0x968D, 0xBF03, 0x968E, 0xBF04, + 0x968F, 0xBF05, 0x9690, 0xBF06, 0x9691, 0xBF07, 0x9692, 0xBF0A, + 0x9693, 0xBF0B, 0x9694, 0xBF0C, 0x9695, 0xBF0D, 0x9696, 0xBF0E, + 0x9697, 0xBF0F, 0x9698, 0xBF10, 0x9699, 0xBF11, 0x969A, 0xBF12, + 0x969B, 0xBF13, 0x969C, 0xBF14, 0x969D, 0xBF15, 0x969E, 0xBF16, + 0x969F, 0xBF17, 0x96A0, 0xBF1A, 0x96A1, 0xBF1E, 0x96A2, 0xBF1F, + 0x96A3, 0xBF20, 0x96A4, 0xBF21, 0x96A5, 0xBF22, 0x96A6, 0xBF23, + 0x96A7, 0xBF24, 0x96A8, 0xBF25, 0x96A9, 0xBF26, 0x96AA, 0xBF27, + 0x96AB, 0xBF28, 0x96AC, 0xBF29, 0x96AD, 0xBF2A, 0x96AE, 0xBF2B, + 0x96AF, 0xBF2C, 0x96B0, 0xBF2D, 0x96B1, 0xBF2E, 0x96B2, 0xBF2F, + 0x96B3, 0xBF30, 0x96B4, 0xBF31, 0x96B5, 0xBF32, 0x96B6, 0xBF33, + 0x96B7, 0xBF34, 0x96B8, 0xBF35, 0x96B9, 0xBF36, 0x96BA, 0xBF37, + 0x96BB, 0xBF38, 0x96BC, 0xBF39, 0x96BD, 0xBF3A, 0x96BE, 0xBF3B, + 0x96BF, 0xBF3C, 0x96C0, 0xBF3D, 0x96C1, 0xBF3E, 0x96C2, 0xBF3F, + 0x96C3, 0xBF42, 0x96C4, 0xBF43, 0x96C5, 0xBF45, 0x96C6, 0xBF46, + 0x96C7, 0xBF47, 0x96C8, 0xBF49, 0x96C9, 0xBF4A, 0x96CA, 0xBF4B, + 0x96CB, 0xBF4C, 0x96CC, 0xBF4D, 0x96CD, 0xBF4E, 0x96CE, 0xBF4F, + 0x96CF, 0xBF52, 0x96D0, 0xBF53, 0x96D1, 0xBF54, 0x96D2, 0xBF56, + 0x96D3, 0xBF57, 0x96D4, 0xBF58, 0x96D5, 0xBF59, 0x96D6, 0xBF5A, + 0x96D7, 0xBF5B, 0x96D8, 0xBF5C, 0x96D9, 0xBF5D, 0x96DA, 0xBF5E, + 0x96DB, 0xBF5F, 0x96DC, 0xBF60, 0x96DD, 0xBF61, 0x96DE, 0xBF62, + 0x96DF, 0xBF63, 0x96E0, 0xBF64, 0x96E1, 0xBF65, 0x96E2, 0xBF66, + 0x96E3, 0xBF67, 0x96E4, 0xBF68, 0x96E5, 0xBF69, 0x96E6, 0xBF6A, + 0x96E7, 0xBF6B, 0x96E8, 0xBF6C, 0x96E9, 0xBF6D, 0x96EA, 0xBF6E, + 0x96EB, 0xBF6F, 0x96EC, 0xBF70, 0x96ED, 0xBF71, 0x96EE, 0xBF72, + 0x96EF, 0xBF73, 0x96F0, 0xBF74, 0x96F1, 0xBF75, 0x96F2, 0xBF76, + 0x96F3, 0xBF77, 0x96F4, 0xBF78, 0x96F5, 0xBF79, 0x96F6, 0xBF7A, + 0x96F7, 0xBF7B, 0x96F8, 0xBF7C, 0x96F9, 0xBF7D, 0x96FA, 0xBF7E, + 0x96FB, 0xBF7F, 0x96FC, 0xBF80, 0x96FD, 0xBF81, 0x96FE, 0xBF82, + 0x9741, 0xBF83, 0x9742, 0xBF84, 0x9743, 0xBF85, 0x9744, 0xBF86, + 0x9745, 0xBF87, 0x9746, 0xBF88, 0x9747, 0xBF89, 0x9748, 0xBF8A, + 0x9749, 0xBF8B, 0x974A, 0xBF8C, 0x974B, 0xBF8D, 0x974C, 0xBF8E, + 0x974D, 0xBF8F, 0x974E, 0xBF90, 0x974F, 0xBF91, 0x9750, 0xBF92, + 0x9751, 0xBF93, 0x9752, 0xBF95, 0x9753, 0xBF96, 0x9754, 0xBF97, + 0x9755, 0xBF98, 0x9756, 0xBF99, 0x9757, 0xBF9A, 0x9758, 0xBF9B, + 0x9759, 0xBF9C, 0x975A, 0xBF9D, 0x9761, 0xBF9E, 0x9762, 0xBF9F, + 0x9763, 0xBFA0, 0x9764, 0xBFA1, 0x9765, 0xBFA2, 0x9766, 0xBFA3, + 0x9767, 0xBFA4, 0x9768, 0xBFA5, 0x9769, 0xBFA6, 0x976A, 0xBFA7, + 0x976B, 0xBFA8, 0x976C, 0xBFA9, 0x976D, 0xBFAA, 0x976E, 0xBFAB, + 0x976F, 0xBFAC, 0x9770, 0xBFAD, 0x9771, 0xBFAE, 0x9772, 0xBFAF, + 0x9773, 0xBFB1, 0x9774, 0xBFB2, 0x9775, 0xBFB3, 0x9776, 0xBFB4, + 0x9777, 0xBFB5, 0x9778, 0xBFB6, 0x9779, 0xBFB7, 0x977A, 0xBFB8, + 0x9781, 0xBFB9, 0x9782, 0xBFBA, 0x9783, 0xBFBB, 0x9784, 0xBFBC, + 0x9785, 0xBFBD, 0x9786, 0xBFBE, 0x9787, 0xBFBF, 0x9788, 0xBFC0, + 0x9789, 0xBFC1, 0x978A, 0xBFC2, 0x978B, 0xBFC3, 0x978C, 0xBFC4, + 0x978D, 0xBFC6, 0x978E, 0xBFC7, 0x978F, 0xBFC8, 0x9790, 0xBFC9, + 0x9791, 0xBFCA, 0x9792, 0xBFCB, 0x9793, 0xBFCE, 0x9794, 0xBFCF, + 0x9795, 0xBFD1, 0x9796, 0xBFD2, 0x9797, 0xBFD3, 0x9798, 0xBFD5, + 0x9799, 0xBFD6, 0x979A, 0xBFD7, 0x979B, 0xBFD8, 0x979C, 0xBFD9, + 0x979D, 0xBFDA, 0x979E, 0xBFDB, 0x979F, 0xBFDD, 0x97A0, 0xBFDE, + 0x97A1, 0xBFE0, 0x97A2, 0xBFE2, 0x97A3, 0xBFE3, 0x97A4, 0xBFE4, + 0x97A5, 0xBFE5, 0x97A6, 0xBFE6, 0x97A7, 0xBFE7, 0x97A8, 0xBFE8, + 0x97A9, 0xBFE9, 0x97AA, 0xBFEA, 0x97AB, 0xBFEB, 0x97AC, 0xBFEC, + 0x97AD, 0xBFED, 0x97AE, 0xBFEE, 0x97AF, 0xBFEF, 0x97B0, 0xBFF0, + 0x97B1, 0xBFF1, 0x97B2, 0xBFF2, 0x97B3, 0xBFF3, 0x97B4, 0xBFF4, + 0x97B5, 0xBFF5, 0x97B6, 0xBFF6, 0x97B7, 0xBFF7, 0x97B8, 0xBFF8, + 0x97B9, 0xBFF9, 0x97BA, 0xBFFA, 0x97BB, 0xBFFB, 0x97BC, 0xBFFC, + 0x97BD, 0xBFFD, 0x97BE, 0xBFFE, 0x97BF, 0xBFFF, 0x97C0, 0xC000, + 0x97C1, 0xC001, 0x97C2, 0xC002, 0x97C3, 0xC003, 0x97C4, 0xC004, + 0x97C5, 0xC005, 0x97C6, 0xC006, 0x97C7, 0xC007, 0x97C8, 0xC008, + 0x97C9, 0xC009, 0x97CA, 0xC00A, 0x97CB, 0xC00B, 0x97CC, 0xC00C, + 0x97CD, 0xC00D, 0x97CE, 0xC00E, 0x97CF, 0xC00F, 0x97D0, 0xC010, + 0x97D1, 0xC011, 0x97D2, 0xC012, 0x97D3, 0xC013, 0x97D4, 0xC014, + 0x97D5, 0xC015, 0x97D6, 0xC016, 0x97D7, 0xC017, 0x97D8, 0xC018, + 0x97D9, 0xC019, 0x97DA, 0xC01A, 0x97DB, 0xC01B, 0x97DC, 0xC01C, + 0x97DD, 0xC01D, 0x97DE, 0xC01E, 0x97DF, 0xC01F, 0x97E0, 0xC020, + 0x97E1, 0xC021, 0x97E2, 0xC022, 0x97E3, 0xC023, 0x97E4, 0xC024, + 0x97E5, 0xC025, 0x97E6, 0xC026, 0x97E7, 0xC027, 0x97E8, 0xC028, + 0x97E9, 0xC029, 0x97EA, 0xC02A, 0x97EB, 0xC02B, 0x97EC, 0xC02C, + 0x97ED, 0xC02D, 0x97EE, 0xC02E, 0x97EF, 0xC02F, 0x97F0, 0xC030, + 0x97F1, 0xC031, 0x97F2, 0xC032, 0x97F3, 0xC033, 0x97F4, 0xC034, + 0x97F5, 0xC035, 0x97F6, 0xC036, 0x97F7, 0xC037, 0x97F8, 0xC038, + 0x97F9, 0xC039, 0x97FA, 0xC03A, 0x97FB, 0xC03B, 0x97FC, 0xC03D, + 0x97FD, 0xC03E, 0x97FE, 0xC03F, 0x9841, 0xC040, 0x9842, 0xC041, + 0x9843, 0xC042, 0x9844, 0xC043, 0x9845, 0xC044, 0x9846, 0xC045, + 0x9847, 0xC046, 0x9848, 0xC047, 0x9849, 0xC048, 0x984A, 0xC049, + 0x984B, 0xC04A, 0x984C, 0xC04B, 0x984D, 0xC04C, 0x984E, 0xC04D, + 0x984F, 0xC04E, 0x9850, 0xC04F, 0x9851, 0xC050, 0x9852, 0xC052, + 0x9853, 0xC053, 0x9854, 0xC054, 0x9855, 0xC055, 0x9856, 0xC056, + 0x9857, 0xC057, 0x9858, 0xC059, 0x9859, 0xC05A, 0x985A, 0xC05B, + 0x9861, 0xC05D, 0x9862, 0xC05E, 0x9863, 0xC05F, 0x9864, 0xC061, + 0x9865, 0xC062, 0x9866, 0xC063, 0x9867, 0xC064, 0x9868, 0xC065, + 0x9869, 0xC066, 0x986A, 0xC067, 0x986B, 0xC06A, 0x986C, 0xC06B, + 0x986D, 0xC06C, 0x986E, 0xC06D, 0x986F, 0xC06E, 0x9870, 0xC06F, + 0x9871, 0xC070, 0x9872, 0xC071, 0x9873, 0xC072, 0x9874, 0xC073, + 0x9875, 0xC074, 0x9876, 0xC075, 0x9877, 0xC076, 0x9878, 0xC077, + 0x9879, 0xC078, 0x987A, 0xC079, 0x9881, 0xC07A, 0x9882, 0xC07B, + 0x9883, 0xC07C, 0x9884, 0xC07D, 0x9885, 0xC07E, 0x9886, 0xC07F, + 0x9887, 0xC080, 0x9888, 0xC081, 0x9889, 0xC082, 0x988A, 0xC083, + 0x988B, 0xC084, 0x988C, 0xC085, 0x988D, 0xC086, 0x988E, 0xC087, + 0x988F, 0xC088, 0x9890, 0xC089, 0x9891, 0xC08A, 0x9892, 0xC08B, + 0x9893, 0xC08C, 0x9894, 0xC08D, 0x9895, 0xC08E, 0x9896, 0xC08F, + 0x9897, 0xC092, 0x9898, 0xC093, 0x9899, 0xC095, 0x989A, 0xC096, + 0x989B, 0xC097, 0x989C, 0xC099, 0x989D, 0xC09A, 0x989E, 0xC09B, + 0x989F, 0xC09C, 0x98A0, 0xC09D, 0x98A1, 0xC09E, 0x98A2, 0xC09F, + 0x98A3, 0xC0A2, 0x98A4, 0xC0A4, 0x98A5, 0xC0A6, 0x98A6, 0xC0A7, + 0x98A7, 0xC0A8, 0x98A8, 0xC0A9, 0x98A9, 0xC0AA, 0x98AA, 0xC0AB, + 0x98AB, 0xC0AE, 0x98AC, 0xC0B1, 0x98AD, 0xC0B2, 0x98AE, 0xC0B7, + 0x98AF, 0xC0B8, 0x98B0, 0xC0B9, 0x98B1, 0xC0BA, 0x98B2, 0xC0BB, + 0x98B3, 0xC0BE, 0x98B4, 0xC0C2, 0x98B5, 0xC0C3, 0x98B6, 0xC0C4, + 0x98B7, 0xC0C6, 0x98B8, 0xC0C7, 0x98B9, 0xC0CA, 0x98BA, 0xC0CB, + 0x98BB, 0xC0CD, 0x98BC, 0xC0CE, 0x98BD, 0xC0CF, 0x98BE, 0xC0D1, + 0x98BF, 0xC0D2, 0x98C0, 0xC0D3, 0x98C1, 0xC0D4, 0x98C2, 0xC0D5, + 0x98C3, 0xC0D6, 0x98C4, 0xC0D7, 0x98C5, 0xC0DA, 0x98C6, 0xC0DE, + 0x98C7, 0xC0DF, 0x98C8, 0xC0E0, 0x98C9, 0xC0E1, 0x98CA, 0xC0E2, + 0x98CB, 0xC0E3, 0x98CC, 0xC0E6, 0x98CD, 0xC0E7, 0x98CE, 0xC0E9, + 0x98CF, 0xC0EA, 0x98D0, 0xC0EB, 0x98D1, 0xC0ED, 0x98D2, 0xC0EE, + 0x98D3, 0xC0EF, 0x98D4, 0xC0F0, 0x98D5, 0xC0F1, 0x98D6, 0xC0F2, + 0x98D7, 0xC0F3, 0x98D8, 0xC0F6, 0x98D9, 0xC0F8, 0x98DA, 0xC0FA, + 0x98DB, 0xC0FB, 0x98DC, 0xC0FC, 0x98DD, 0xC0FD, 0x98DE, 0xC0FE, + 0x98DF, 0xC0FF, 0x98E0, 0xC101, 0x98E1, 0xC102, 0x98E2, 0xC103, + 0x98E3, 0xC105, 0x98E4, 0xC106, 0x98E5, 0xC107, 0x98E6, 0xC109, + 0x98E7, 0xC10A, 0x98E8, 0xC10B, 0x98E9, 0xC10C, 0x98EA, 0xC10D, + 0x98EB, 0xC10E, 0x98EC, 0xC10F, 0x98ED, 0xC111, 0x98EE, 0xC112, + 0x98EF, 0xC113, 0x98F0, 0xC114, 0x98F1, 0xC116, 0x98F2, 0xC117, + 0x98F3, 0xC118, 0x98F4, 0xC119, 0x98F5, 0xC11A, 0x98F6, 0xC11B, + 0x98F7, 0xC121, 0x98F8, 0xC122, 0x98F9, 0xC125, 0x98FA, 0xC128, + 0x98FB, 0xC129, 0x98FC, 0xC12A, 0x98FD, 0xC12B, 0x98FE, 0xC12E, + 0x9941, 0xC132, 0x9942, 0xC133, 0x9943, 0xC134, 0x9944, 0xC135, + 0x9945, 0xC137, 0x9946, 0xC13A, 0x9947, 0xC13B, 0x9948, 0xC13D, + 0x9949, 0xC13E, 0x994A, 0xC13F, 0x994B, 0xC141, 0x994C, 0xC142, + 0x994D, 0xC143, 0x994E, 0xC144, 0x994F, 0xC145, 0x9950, 0xC146, + 0x9951, 0xC147, 0x9952, 0xC14A, 0x9953, 0xC14E, 0x9954, 0xC14F, + 0x9955, 0xC150, 0x9956, 0xC151, 0x9957, 0xC152, 0x9958, 0xC153, + 0x9959, 0xC156, 0x995A, 0xC157, 0x9961, 0xC159, 0x9962, 0xC15A, + 0x9963, 0xC15B, 0x9964, 0xC15D, 0x9965, 0xC15E, 0x9966, 0xC15F, + 0x9967, 0xC160, 0x9968, 0xC161, 0x9969, 0xC162, 0x996A, 0xC163, + 0x996B, 0xC166, 0x996C, 0xC16A, 0x996D, 0xC16B, 0x996E, 0xC16C, + 0x996F, 0xC16D, 0x9970, 0xC16E, 0x9971, 0xC16F, 0x9972, 0xC171, + 0x9973, 0xC172, 0x9974, 0xC173, 0x9975, 0xC175, 0x9976, 0xC176, + 0x9977, 0xC177, 0x9978, 0xC179, 0x9979, 0xC17A, 0x997A, 0xC17B, + 0x9981, 0xC17C, 0x9982, 0xC17D, 0x9983, 0xC17E, 0x9984, 0xC17F, + 0x9985, 0xC180, 0x9986, 0xC181, 0x9987, 0xC182, 0x9988, 0xC183, + 0x9989, 0xC184, 0x998A, 0xC186, 0x998B, 0xC187, 0x998C, 0xC188, + 0x998D, 0xC189, 0x998E, 0xC18A, 0x998F, 0xC18B, 0x9990, 0xC18F, + 0x9991, 0xC191, 0x9992, 0xC192, 0x9993, 0xC193, 0x9994, 0xC195, + 0x9995, 0xC197, 0x9996, 0xC198, 0x9997, 0xC199, 0x9998, 0xC19A, + 0x9999, 0xC19B, 0x999A, 0xC19E, 0x999B, 0xC1A0, 0x999C, 0xC1A2, + 0x999D, 0xC1A3, 0x999E, 0xC1A4, 0x999F, 0xC1A6, 0x99A0, 0xC1A7, + 0x99A1, 0xC1AA, 0x99A2, 0xC1AB, 0x99A3, 0xC1AD, 0x99A4, 0xC1AE, + 0x99A5, 0xC1AF, 0x99A6, 0xC1B1, 0x99A7, 0xC1B2, 0x99A8, 0xC1B3, + 0x99A9, 0xC1B4, 0x99AA, 0xC1B5, 0x99AB, 0xC1B6, 0x99AC, 0xC1B7, + 0x99AD, 0xC1B8, 0x99AE, 0xC1B9, 0x99AF, 0xC1BA, 0x99B0, 0xC1BB, + 0x99B1, 0xC1BC, 0x99B2, 0xC1BE, 0x99B3, 0xC1BF, 0x99B4, 0xC1C0, + 0x99B5, 0xC1C1, 0x99B6, 0xC1C2, 0x99B7, 0xC1C3, 0x99B8, 0xC1C5, + 0x99B9, 0xC1C6, 0x99BA, 0xC1C7, 0x99BB, 0xC1C9, 0x99BC, 0xC1CA, + 0x99BD, 0xC1CB, 0x99BE, 0xC1CD, 0x99BF, 0xC1CE, 0x99C0, 0xC1CF, + 0x99C1, 0xC1D0, 0x99C2, 0xC1D1, 0x99C3, 0xC1D2, 0x99C4, 0xC1D3, + 0x99C5, 0xC1D5, 0x99C6, 0xC1D6, 0x99C7, 0xC1D9, 0x99C8, 0xC1DA, + 0x99C9, 0xC1DB, 0x99CA, 0xC1DC, 0x99CB, 0xC1DD, 0x99CC, 0xC1DE, + 0x99CD, 0xC1DF, 0x99CE, 0xC1E1, 0x99CF, 0xC1E2, 0x99D0, 0xC1E3, + 0x99D1, 0xC1E5, 0x99D2, 0xC1E6, 0x99D3, 0xC1E7, 0x99D4, 0xC1E9, + 0x99D5, 0xC1EA, 0x99D6, 0xC1EB, 0x99D7, 0xC1EC, 0x99D8, 0xC1ED, + 0x99D9, 0xC1EE, 0x99DA, 0xC1EF, 0x99DB, 0xC1F2, 0x99DC, 0xC1F4, + 0x99DD, 0xC1F5, 0x99DE, 0xC1F6, 0x99DF, 0xC1F7, 0x99E0, 0xC1F8, + 0x99E1, 0xC1F9, 0x99E2, 0xC1FA, 0x99E3, 0xC1FB, 0x99E4, 0xC1FE, + 0x99E5, 0xC1FF, 0x99E6, 0xC201, 0x99E7, 0xC202, 0x99E8, 0xC203, + 0x99E9, 0xC205, 0x99EA, 0xC206, 0x99EB, 0xC207, 0x99EC, 0xC208, + 0x99ED, 0xC209, 0x99EE, 0xC20A, 0x99EF, 0xC20B, 0x99F0, 0xC20E, + 0x99F1, 0xC210, 0x99F2, 0xC212, 0x99F3, 0xC213, 0x99F4, 0xC214, + 0x99F5, 0xC215, 0x99F6, 0xC216, 0x99F7, 0xC217, 0x99F8, 0xC21A, + 0x99F9, 0xC21B, 0x99FA, 0xC21D, 0x99FB, 0xC21E, 0x99FC, 0xC221, + 0x99FD, 0xC222, 0x99FE, 0xC223, 0x9A41, 0xC224, 0x9A42, 0xC225, + 0x9A43, 0xC226, 0x9A44, 0xC227, 0x9A45, 0xC22A, 0x9A46, 0xC22C, + 0x9A47, 0xC22E, 0x9A48, 0xC230, 0x9A49, 0xC233, 0x9A4A, 0xC235, + 0x9A4B, 0xC236, 0x9A4C, 0xC237, 0x9A4D, 0xC238, 0x9A4E, 0xC239, + 0x9A4F, 0xC23A, 0x9A50, 0xC23B, 0x9A51, 0xC23C, 0x9A52, 0xC23D, + 0x9A53, 0xC23E, 0x9A54, 0xC23F, 0x9A55, 0xC240, 0x9A56, 0xC241, + 0x9A57, 0xC242, 0x9A58, 0xC243, 0x9A59, 0xC244, 0x9A5A, 0xC245, + 0x9A61, 0xC246, 0x9A62, 0xC247, 0x9A63, 0xC249, 0x9A64, 0xC24A, + 0x9A65, 0xC24B, 0x9A66, 0xC24C, 0x9A67, 0xC24D, 0x9A68, 0xC24E, + 0x9A69, 0xC24F, 0x9A6A, 0xC252, 0x9A6B, 0xC253, 0x9A6C, 0xC255, + 0x9A6D, 0xC256, 0x9A6E, 0xC257, 0x9A6F, 0xC259, 0x9A70, 0xC25A, + 0x9A71, 0xC25B, 0x9A72, 0xC25C, 0x9A73, 0xC25D, 0x9A74, 0xC25E, + 0x9A75, 0xC25F, 0x9A76, 0xC261, 0x9A77, 0xC262, 0x9A78, 0xC263, + 0x9A79, 0xC264, 0x9A7A, 0xC266, 0x9A81, 0xC267, 0x9A82, 0xC268, + 0x9A83, 0xC269, 0x9A84, 0xC26A, 0x9A85, 0xC26B, 0x9A86, 0xC26E, + 0x9A87, 0xC26F, 0x9A88, 0xC271, 0x9A89, 0xC272, 0x9A8A, 0xC273, + 0x9A8B, 0xC275, 0x9A8C, 0xC276, 0x9A8D, 0xC277, 0x9A8E, 0xC278, + 0x9A8F, 0xC279, 0x9A90, 0xC27A, 0x9A91, 0xC27B, 0x9A92, 0xC27E, + 0x9A93, 0xC280, 0x9A94, 0xC282, 0x9A95, 0xC283, 0x9A96, 0xC284, + 0x9A97, 0xC285, 0x9A98, 0xC286, 0x9A99, 0xC287, 0x9A9A, 0xC28A, + 0x9A9B, 0xC28B, 0x9A9C, 0xC28C, 0x9A9D, 0xC28D, 0x9A9E, 0xC28E, + 0x9A9F, 0xC28F, 0x9AA0, 0xC291, 0x9AA1, 0xC292, 0x9AA2, 0xC293, + 0x9AA3, 0xC294, 0x9AA4, 0xC295, 0x9AA5, 0xC296, 0x9AA6, 0xC297, + 0x9AA7, 0xC299, 0x9AA8, 0xC29A, 0x9AA9, 0xC29C, 0x9AAA, 0xC29E, + 0x9AAB, 0xC29F, 0x9AAC, 0xC2A0, 0x9AAD, 0xC2A1, 0x9AAE, 0xC2A2, + 0x9AAF, 0xC2A3, 0x9AB0, 0xC2A6, 0x9AB1, 0xC2A7, 0x9AB2, 0xC2A9, + 0x9AB3, 0xC2AA, 0x9AB4, 0xC2AB, 0x9AB5, 0xC2AE, 0x9AB6, 0xC2AF, + 0x9AB7, 0xC2B0, 0x9AB8, 0xC2B1, 0x9AB9, 0xC2B2, 0x9ABA, 0xC2B3, + 0x9ABB, 0xC2B6, 0x9ABC, 0xC2B8, 0x9ABD, 0xC2BA, 0x9ABE, 0xC2BB, + 0x9ABF, 0xC2BC, 0x9AC0, 0xC2BD, 0x9AC1, 0xC2BE, 0x9AC2, 0xC2BF, + 0x9AC3, 0xC2C0, 0x9AC4, 0xC2C1, 0x9AC5, 0xC2C2, 0x9AC6, 0xC2C3, + 0x9AC7, 0xC2C4, 0x9AC8, 0xC2C5, 0x9AC9, 0xC2C6, 0x9ACA, 0xC2C7, + 0x9ACB, 0xC2C8, 0x9ACC, 0xC2C9, 0x9ACD, 0xC2CA, 0x9ACE, 0xC2CB, + 0x9ACF, 0xC2CC, 0x9AD0, 0xC2CD, 0x9AD1, 0xC2CE, 0x9AD2, 0xC2CF, + 0x9AD3, 0xC2D0, 0x9AD4, 0xC2D1, 0x9AD5, 0xC2D2, 0x9AD6, 0xC2D3, + 0x9AD7, 0xC2D4, 0x9AD8, 0xC2D5, 0x9AD9, 0xC2D6, 0x9ADA, 0xC2D7, + 0x9ADB, 0xC2D8, 0x9ADC, 0xC2D9, 0x9ADD, 0xC2DA, 0x9ADE, 0xC2DB, + 0x9ADF, 0xC2DE, 0x9AE0, 0xC2DF, 0x9AE1, 0xC2E1, 0x9AE2, 0xC2E2, + 0x9AE3, 0xC2E5, 0x9AE4, 0xC2E6, 0x9AE5, 0xC2E7, 0x9AE6, 0xC2E8, + 0x9AE7, 0xC2E9, 0x9AE8, 0xC2EA, 0x9AE9, 0xC2EE, 0x9AEA, 0xC2F0, + 0x9AEB, 0xC2F2, 0x9AEC, 0xC2F3, 0x9AED, 0xC2F4, 0x9AEE, 0xC2F5, + 0x9AEF, 0xC2F7, 0x9AF0, 0xC2FA, 0x9AF1, 0xC2FD, 0x9AF2, 0xC2FE, + 0x9AF3, 0xC2FF, 0x9AF4, 0xC301, 0x9AF5, 0xC302, 0x9AF6, 0xC303, + 0x9AF7, 0xC304, 0x9AF8, 0xC305, 0x9AF9, 0xC306, 0x9AFA, 0xC307, + 0x9AFB, 0xC30A, 0x9AFC, 0xC30B, 0x9AFD, 0xC30E, 0x9AFE, 0xC30F, + 0x9B41, 0xC310, 0x9B42, 0xC311, 0x9B43, 0xC312, 0x9B44, 0xC316, + 0x9B45, 0xC317, 0x9B46, 0xC319, 0x9B47, 0xC31A, 0x9B48, 0xC31B, + 0x9B49, 0xC31D, 0x9B4A, 0xC31E, 0x9B4B, 0xC31F, 0x9B4C, 0xC320, + 0x9B4D, 0xC321, 0x9B4E, 0xC322, 0x9B4F, 0xC323, 0x9B50, 0xC326, + 0x9B51, 0xC327, 0x9B52, 0xC32A, 0x9B53, 0xC32B, 0x9B54, 0xC32C, + 0x9B55, 0xC32D, 0x9B56, 0xC32E, 0x9B57, 0xC32F, 0x9B58, 0xC330, + 0x9B59, 0xC331, 0x9B5A, 0xC332, 0x9B61, 0xC333, 0x9B62, 0xC334, + 0x9B63, 0xC335, 0x9B64, 0xC336, 0x9B65, 0xC337, 0x9B66, 0xC338, + 0x9B67, 0xC339, 0x9B68, 0xC33A, 0x9B69, 0xC33B, 0x9B6A, 0xC33C, + 0x9B6B, 0xC33D, 0x9B6C, 0xC33E, 0x9B6D, 0xC33F, 0x9B6E, 0xC340, + 0x9B6F, 0xC341, 0x9B70, 0xC342, 0x9B71, 0xC343, 0x9B72, 0xC344, + 0x9B73, 0xC346, 0x9B74, 0xC347, 0x9B75, 0xC348, 0x9B76, 0xC349, + 0x9B77, 0xC34A, 0x9B78, 0xC34B, 0x9B79, 0xC34C, 0x9B7A, 0xC34D, + 0x9B81, 0xC34E, 0x9B82, 0xC34F, 0x9B83, 0xC350, 0x9B84, 0xC351, + 0x9B85, 0xC352, 0x9B86, 0xC353, 0x9B87, 0xC354, 0x9B88, 0xC355, + 0x9B89, 0xC356, 0x9B8A, 0xC357, 0x9B8B, 0xC358, 0x9B8C, 0xC359, + 0x9B8D, 0xC35A, 0x9B8E, 0xC35B, 0x9B8F, 0xC35C, 0x9B90, 0xC35D, + 0x9B91, 0xC35E, 0x9B92, 0xC35F, 0x9B93, 0xC360, 0x9B94, 0xC361, + 0x9B95, 0xC362, 0x9B96, 0xC363, 0x9B97, 0xC364, 0x9B98, 0xC365, + 0x9B99, 0xC366, 0x9B9A, 0xC367, 0x9B9B, 0xC36A, 0x9B9C, 0xC36B, + 0x9B9D, 0xC36D, 0x9B9E, 0xC36E, 0x9B9F, 0xC36F, 0x9BA0, 0xC371, + 0x9BA1, 0xC373, 0x9BA2, 0xC374, 0x9BA3, 0xC375, 0x9BA4, 0xC376, + 0x9BA5, 0xC377, 0x9BA6, 0xC37A, 0x9BA7, 0xC37B, 0x9BA8, 0xC37E, + 0x9BA9, 0xC37F, 0x9BAA, 0xC380, 0x9BAB, 0xC381, 0x9BAC, 0xC382, + 0x9BAD, 0xC383, 0x9BAE, 0xC385, 0x9BAF, 0xC386, 0x9BB0, 0xC387, + 0x9BB1, 0xC389, 0x9BB2, 0xC38A, 0x9BB3, 0xC38B, 0x9BB4, 0xC38D, + 0x9BB5, 0xC38E, 0x9BB6, 0xC38F, 0x9BB7, 0xC390, 0x9BB8, 0xC391, + 0x9BB9, 0xC392, 0x9BBA, 0xC393, 0x9BBB, 0xC394, 0x9BBC, 0xC395, + 0x9BBD, 0xC396, 0x9BBE, 0xC397, 0x9BBF, 0xC398, 0x9BC0, 0xC399, + 0x9BC1, 0xC39A, 0x9BC2, 0xC39B, 0x9BC3, 0xC39C, 0x9BC4, 0xC39D, + 0x9BC5, 0xC39E, 0x9BC6, 0xC39F, 0x9BC7, 0xC3A0, 0x9BC8, 0xC3A1, + 0x9BC9, 0xC3A2, 0x9BCA, 0xC3A3, 0x9BCB, 0xC3A4, 0x9BCC, 0xC3A5, + 0x9BCD, 0xC3A6, 0x9BCE, 0xC3A7, 0x9BCF, 0xC3A8, 0x9BD0, 0xC3A9, + 0x9BD1, 0xC3AA, 0x9BD2, 0xC3AB, 0x9BD3, 0xC3AC, 0x9BD4, 0xC3AD, + 0x9BD5, 0xC3AE, 0x9BD6, 0xC3AF, 0x9BD7, 0xC3B0, 0x9BD8, 0xC3B1, + 0x9BD9, 0xC3B2, 0x9BDA, 0xC3B3, 0x9BDB, 0xC3B4, 0x9BDC, 0xC3B5, + 0x9BDD, 0xC3B6, 0x9BDE, 0xC3B7, 0x9BDF, 0xC3B8, 0x9BE0, 0xC3B9, + 0x9BE1, 0xC3BA, 0x9BE2, 0xC3BB, 0x9BE3, 0xC3BC, 0x9BE4, 0xC3BD, + 0x9BE5, 0xC3BE, 0x9BE6, 0xC3BF, 0x9BE7, 0xC3C1, 0x9BE8, 0xC3C2, + 0x9BE9, 0xC3C3, 0x9BEA, 0xC3C4, 0x9BEB, 0xC3C5, 0x9BEC, 0xC3C6, + 0x9BED, 0xC3C7, 0x9BEE, 0xC3C8, 0x9BEF, 0xC3C9, 0x9BF0, 0xC3CA, + 0x9BF1, 0xC3CB, 0x9BF2, 0xC3CC, 0x9BF3, 0xC3CD, 0x9BF4, 0xC3CE, + 0x9BF5, 0xC3CF, 0x9BF6, 0xC3D0, 0x9BF7, 0xC3D1, 0x9BF8, 0xC3D2, + 0x9BF9, 0xC3D3, 0x9BFA, 0xC3D4, 0x9BFB, 0xC3D5, 0x9BFC, 0xC3D6, + 0x9BFD, 0xC3D7, 0x9BFE, 0xC3DA, 0x9C41, 0xC3DB, 0x9C42, 0xC3DD, + 0x9C43, 0xC3DE, 0x9C44, 0xC3E1, 0x9C45, 0xC3E3, 0x9C46, 0xC3E4, + 0x9C47, 0xC3E5, 0x9C48, 0xC3E6, 0x9C49, 0xC3E7, 0x9C4A, 0xC3EA, + 0x9C4B, 0xC3EB, 0x9C4C, 0xC3EC, 0x9C4D, 0xC3EE, 0x9C4E, 0xC3EF, + 0x9C4F, 0xC3F0, 0x9C50, 0xC3F1, 0x9C51, 0xC3F2, 0x9C52, 0xC3F3, + 0x9C53, 0xC3F6, 0x9C54, 0xC3F7, 0x9C55, 0xC3F9, 0x9C56, 0xC3FA, + 0x9C57, 0xC3FB, 0x9C58, 0xC3FC, 0x9C59, 0xC3FD, 0x9C5A, 0xC3FE, + 0x9C61, 0xC3FF, 0x9C62, 0xC400, 0x9C63, 0xC401, 0x9C64, 0xC402, + 0x9C65, 0xC403, 0x9C66, 0xC404, 0x9C67, 0xC405, 0x9C68, 0xC406, + 0x9C69, 0xC407, 0x9C6A, 0xC409, 0x9C6B, 0xC40A, 0x9C6C, 0xC40B, + 0x9C6D, 0xC40C, 0x9C6E, 0xC40D, 0x9C6F, 0xC40E, 0x9C70, 0xC40F, + 0x9C71, 0xC411, 0x9C72, 0xC412, 0x9C73, 0xC413, 0x9C74, 0xC414, + 0x9C75, 0xC415, 0x9C76, 0xC416, 0x9C77, 0xC417, 0x9C78, 0xC418, + 0x9C79, 0xC419, 0x9C7A, 0xC41A, 0x9C81, 0xC41B, 0x9C82, 0xC41C, + 0x9C83, 0xC41D, 0x9C84, 0xC41E, 0x9C85, 0xC41F, 0x9C86, 0xC420, + 0x9C87, 0xC421, 0x9C88, 0xC422, 0x9C89, 0xC423, 0x9C8A, 0xC425, + 0x9C8B, 0xC426, 0x9C8C, 0xC427, 0x9C8D, 0xC428, 0x9C8E, 0xC429, + 0x9C8F, 0xC42A, 0x9C90, 0xC42B, 0x9C91, 0xC42D, 0x9C92, 0xC42E, + 0x9C93, 0xC42F, 0x9C94, 0xC431, 0x9C95, 0xC432, 0x9C96, 0xC433, + 0x9C97, 0xC435, 0x9C98, 0xC436, 0x9C99, 0xC437, 0x9C9A, 0xC438, + 0x9C9B, 0xC439, 0x9C9C, 0xC43A, 0x9C9D, 0xC43B, 0x9C9E, 0xC43E, + 0x9C9F, 0xC43F, 0x9CA0, 0xC440, 0x9CA1, 0xC441, 0x9CA2, 0xC442, + 0x9CA3, 0xC443, 0x9CA4, 0xC444, 0x9CA5, 0xC445, 0x9CA6, 0xC446, + 0x9CA7, 0xC447, 0x9CA8, 0xC449, 0x9CA9, 0xC44A, 0x9CAA, 0xC44B, + 0x9CAB, 0xC44C, 0x9CAC, 0xC44D, 0x9CAD, 0xC44E, 0x9CAE, 0xC44F, + 0x9CAF, 0xC450, 0x9CB0, 0xC451, 0x9CB1, 0xC452, 0x9CB2, 0xC453, + 0x9CB3, 0xC454, 0x9CB4, 0xC455, 0x9CB5, 0xC456, 0x9CB6, 0xC457, + 0x9CB7, 0xC458, 0x9CB8, 0xC459, 0x9CB9, 0xC45A, 0x9CBA, 0xC45B, + 0x9CBB, 0xC45C, 0x9CBC, 0xC45D, 0x9CBD, 0xC45E, 0x9CBE, 0xC45F, + 0x9CBF, 0xC460, 0x9CC0, 0xC461, 0x9CC1, 0xC462, 0x9CC2, 0xC463, + 0x9CC3, 0xC466, 0x9CC4, 0xC467, 0x9CC5, 0xC469, 0x9CC6, 0xC46A, + 0x9CC7, 0xC46B, 0x9CC8, 0xC46D, 0x9CC9, 0xC46E, 0x9CCA, 0xC46F, + 0x9CCB, 0xC470, 0x9CCC, 0xC471, 0x9CCD, 0xC472, 0x9CCE, 0xC473, + 0x9CCF, 0xC476, 0x9CD0, 0xC477, 0x9CD1, 0xC478, 0x9CD2, 0xC47A, + 0x9CD3, 0xC47B, 0x9CD4, 0xC47C, 0x9CD5, 0xC47D, 0x9CD6, 0xC47E, + 0x9CD7, 0xC47F, 0x9CD8, 0xC481, 0x9CD9, 0xC482, 0x9CDA, 0xC483, + 0x9CDB, 0xC484, 0x9CDC, 0xC485, 0x9CDD, 0xC486, 0x9CDE, 0xC487, + 0x9CDF, 0xC488, 0x9CE0, 0xC489, 0x9CE1, 0xC48A, 0x9CE2, 0xC48B, + 0x9CE3, 0xC48C, 0x9CE4, 0xC48D, 0x9CE5, 0xC48E, 0x9CE6, 0xC48F, + 0x9CE7, 0xC490, 0x9CE8, 0xC491, 0x9CE9, 0xC492, 0x9CEA, 0xC493, + 0x9CEB, 0xC495, 0x9CEC, 0xC496, 0x9CED, 0xC497, 0x9CEE, 0xC498, + 0x9CEF, 0xC499, 0x9CF0, 0xC49A, 0x9CF1, 0xC49B, 0x9CF2, 0xC49D, + 0x9CF3, 0xC49E, 0x9CF4, 0xC49F, 0x9CF5, 0xC4A0, 0x9CF6, 0xC4A1, + 0x9CF7, 0xC4A2, 0x9CF8, 0xC4A3, 0x9CF9, 0xC4A4, 0x9CFA, 0xC4A5, + 0x9CFB, 0xC4A6, 0x9CFC, 0xC4A7, 0x9CFD, 0xC4A8, 0x9CFE, 0xC4A9, + 0x9D41, 0xC4AA, 0x9D42, 0xC4AB, 0x9D43, 0xC4AC, 0x9D44, 0xC4AD, + 0x9D45, 0xC4AE, 0x9D46, 0xC4AF, 0x9D47, 0xC4B0, 0x9D48, 0xC4B1, + 0x9D49, 0xC4B2, 0x9D4A, 0xC4B3, 0x9D4B, 0xC4B4, 0x9D4C, 0xC4B5, + 0x9D4D, 0xC4B6, 0x9D4E, 0xC4B7, 0x9D4F, 0xC4B9, 0x9D50, 0xC4BA, + 0x9D51, 0xC4BB, 0x9D52, 0xC4BD, 0x9D53, 0xC4BE, 0x9D54, 0xC4BF, + 0x9D55, 0xC4C0, 0x9D56, 0xC4C1, 0x9D57, 0xC4C2, 0x9D58, 0xC4C3, + 0x9D59, 0xC4C4, 0x9D5A, 0xC4C5, 0x9D61, 0xC4C6, 0x9D62, 0xC4C7, + 0x9D63, 0xC4C8, 0x9D64, 0xC4C9, 0x9D65, 0xC4CA, 0x9D66, 0xC4CB, + 0x9D67, 0xC4CC, 0x9D68, 0xC4CD, 0x9D69, 0xC4CE, 0x9D6A, 0xC4CF, + 0x9D6B, 0xC4D0, 0x9D6C, 0xC4D1, 0x9D6D, 0xC4D2, 0x9D6E, 0xC4D3, + 0x9D6F, 0xC4D4, 0x9D70, 0xC4D5, 0x9D71, 0xC4D6, 0x9D72, 0xC4D7, + 0x9D73, 0xC4D8, 0x9D74, 0xC4D9, 0x9D75, 0xC4DA, 0x9D76, 0xC4DB, + 0x9D77, 0xC4DC, 0x9D78, 0xC4DD, 0x9D79, 0xC4DE, 0x9D7A, 0xC4DF, + 0x9D81, 0xC4E0, 0x9D82, 0xC4E1, 0x9D83, 0xC4E2, 0x9D84, 0xC4E3, + 0x9D85, 0xC4E4, 0x9D86, 0xC4E5, 0x9D87, 0xC4E6, 0x9D88, 0xC4E7, + 0x9D89, 0xC4E8, 0x9D8A, 0xC4EA, 0x9D8B, 0xC4EB, 0x9D8C, 0xC4EC, + 0x9D8D, 0xC4ED, 0x9D8E, 0xC4EE, 0x9D8F, 0xC4EF, 0x9D90, 0xC4F2, + 0x9D91, 0xC4F3, 0x9D92, 0xC4F5, 0x9D93, 0xC4F6, 0x9D94, 0xC4F7, + 0x9D95, 0xC4F9, 0x9D96, 0xC4FB, 0x9D97, 0xC4FC, 0x9D98, 0xC4FD, + 0x9D99, 0xC4FE, 0x9D9A, 0xC502, 0x9D9B, 0xC503, 0x9D9C, 0xC504, + 0x9D9D, 0xC505, 0x9D9E, 0xC506, 0x9D9F, 0xC507, 0x9DA0, 0xC508, + 0x9DA1, 0xC509, 0x9DA2, 0xC50A, 0x9DA3, 0xC50B, 0x9DA4, 0xC50D, + 0x9DA5, 0xC50E, 0x9DA6, 0xC50F, 0x9DA7, 0xC511, 0x9DA8, 0xC512, + 0x9DA9, 0xC513, 0x9DAA, 0xC515, 0x9DAB, 0xC516, 0x9DAC, 0xC517, + 0x9DAD, 0xC518, 0x9DAE, 0xC519, 0x9DAF, 0xC51A, 0x9DB0, 0xC51B, + 0x9DB1, 0xC51D, 0x9DB2, 0xC51E, 0x9DB3, 0xC51F, 0x9DB4, 0xC520, + 0x9DB5, 0xC521, 0x9DB6, 0xC522, 0x9DB7, 0xC523, 0x9DB8, 0xC524, + 0x9DB9, 0xC525, 0x9DBA, 0xC526, 0x9DBB, 0xC527, 0x9DBC, 0xC52A, + 0x9DBD, 0xC52B, 0x9DBE, 0xC52D, 0x9DBF, 0xC52E, 0x9DC0, 0xC52F, + 0x9DC1, 0xC531, 0x9DC2, 0xC532, 0x9DC3, 0xC533, 0x9DC4, 0xC534, + 0x9DC5, 0xC535, 0x9DC6, 0xC536, 0x9DC7, 0xC537, 0x9DC8, 0xC53A, + 0x9DC9, 0xC53C, 0x9DCA, 0xC53E, 0x9DCB, 0xC53F, 0x9DCC, 0xC540, + 0x9DCD, 0xC541, 0x9DCE, 0xC542, 0x9DCF, 0xC543, 0x9DD0, 0xC546, + 0x9DD1, 0xC547, 0x9DD2, 0xC54B, 0x9DD3, 0xC54F, 0x9DD4, 0xC550, + 0x9DD5, 0xC551, 0x9DD6, 0xC552, 0x9DD7, 0xC556, 0x9DD8, 0xC55A, + 0x9DD9, 0xC55B, 0x9DDA, 0xC55C, 0x9DDB, 0xC55F, 0x9DDC, 0xC562, + 0x9DDD, 0xC563, 0x9DDE, 0xC565, 0x9DDF, 0xC566, 0x9DE0, 0xC567, + 0x9DE1, 0xC569, 0x9DE2, 0xC56A, 0x9DE3, 0xC56B, 0x9DE4, 0xC56C, + 0x9DE5, 0xC56D, 0x9DE6, 0xC56E, 0x9DE7, 0xC56F, 0x9DE8, 0xC572, + 0x9DE9, 0xC576, 0x9DEA, 0xC577, 0x9DEB, 0xC578, 0x9DEC, 0xC579, + 0x9DED, 0xC57A, 0x9DEE, 0xC57B, 0x9DEF, 0xC57E, 0x9DF0, 0xC57F, + 0x9DF1, 0xC581, 0x9DF2, 0xC582, 0x9DF3, 0xC583, 0x9DF4, 0xC585, + 0x9DF5, 0xC586, 0x9DF6, 0xC588, 0x9DF7, 0xC589, 0x9DF8, 0xC58A, + 0x9DF9, 0xC58B, 0x9DFA, 0xC58E, 0x9DFB, 0xC590, 0x9DFC, 0xC592, + 0x9DFD, 0xC593, 0x9DFE, 0xC594, 0x9E41, 0xC596, 0x9E42, 0xC599, + 0x9E43, 0xC59A, 0x9E44, 0xC59B, 0x9E45, 0xC59D, 0x9E46, 0xC59E, + 0x9E47, 0xC59F, 0x9E48, 0xC5A1, 0x9E49, 0xC5A2, 0x9E4A, 0xC5A3, + 0x9E4B, 0xC5A4, 0x9E4C, 0xC5A5, 0x9E4D, 0xC5A6, 0x9E4E, 0xC5A7, + 0x9E4F, 0xC5A8, 0x9E50, 0xC5AA, 0x9E51, 0xC5AB, 0x9E52, 0xC5AC, + 0x9E53, 0xC5AD, 0x9E54, 0xC5AE, 0x9E55, 0xC5AF, 0x9E56, 0xC5B0, + 0x9E57, 0xC5B1, 0x9E58, 0xC5B2, 0x9E59, 0xC5B3, 0x9E5A, 0xC5B6, + 0x9E61, 0xC5B7, 0x9E62, 0xC5BA, 0x9E63, 0xC5BF, 0x9E64, 0xC5C0, + 0x9E65, 0xC5C1, 0x9E66, 0xC5C2, 0x9E67, 0xC5C3, 0x9E68, 0xC5CB, + 0x9E69, 0xC5CD, 0x9E6A, 0xC5CF, 0x9E6B, 0xC5D2, 0x9E6C, 0xC5D3, + 0x9E6D, 0xC5D5, 0x9E6E, 0xC5D6, 0x9E6F, 0xC5D7, 0x9E70, 0xC5D9, + 0x9E71, 0xC5DA, 0x9E72, 0xC5DB, 0x9E73, 0xC5DC, 0x9E74, 0xC5DD, + 0x9E75, 0xC5DE, 0x9E76, 0xC5DF, 0x9E77, 0xC5E2, 0x9E78, 0xC5E4, + 0x9E79, 0xC5E6, 0x9E7A, 0xC5E7, 0x9E81, 0xC5E8, 0x9E82, 0xC5E9, + 0x9E83, 0xC5EA, 0x9E84, 0xC5EB, 0x9E85, 0xC5EF, 0x9E86, 0xC5F1, + 0x9E87, 0xC5F2, 0x9E88, 0xC5F3, 0x9E89, 0xC5F5, 0x9E8A, 0xC5F8, + 0x9E8B, 0xC5F9, 0x9E8C, 0xC5FA, 0x9E8D, 0xC5FB, 0x9E8E, 0xC602, + 0x9E8F, 0xC603, 0x9E90, 0xC604, 0x9E91, 0xC609, 0x9E92, 0xC60A, + 0x9E93, 0xC60B, 0x9E94, 0xC60D, 0x9E95, 0xC60E, 0x9E96, 0xC60F, + 0x9E97, 0xC611, 0x9E98, 0xC612, 0x9E99, 0xC613, 0x9E9A, 0xC614, + 0x9E9B, 0xC615, 0x9E9C, 0xC616, 0x9E9D, 0xC617, 0x9E9E, 0xC61A, + 0x9E9F, 0xC61D, 0x9EA0, 0xC61E, 0x9EA1, 0xC61F, 0x9EA2, 0xC620, + 0x9EA3, 0xC621, 0x9EA4, 0xC622, 0x9EA5, 0xC623, 0x9EA6, 0xC626, + 0x9EA7, 0xC627, 0x9EA8, 0xC629, 0x9EA9, 0xC62A, 0x9EAA, 0xC62B, + 0x9EAB, 0xC62F, 0x9EAC, 0xC631, 0x9EAD, 0xC632, 0x9EAE, 0xC636, + 0x9EAF, 0xC638, 0x9EB0, 0xC63A, 0x9EB1, 0xC63C, 0x9EB2, 0xC63D, + 0x9EB3, 0xC63E, 0x9EB4, 0xC63F, 0x9EB5, 0xC642, 0x9EB6, 0xC643, + 0x9EB7, 0xC645, 0x9EB8, 0xC646, 0x9EB9, 0xC647, 0x9EBA, 0xC649, + 0x9EBB, 0xC64A, 0x9EBC, 0xC64B, 0x9EBD, 0xC64C, 0x9EBE, 0xC64D, + 0x9EBF, 0xC64E, 0x9EC0, 0xC64F, 0x9EC1, 0xC652, 0x9EC2, 0xC656, + 0x9EC3, 0xC657, 0x9EC4, 0xC658, 0x9EC5, 0xC659, 0x9EC6, 0xC65A, + 0x9EC7, 0xC65B, 0x9EC8, 0xC65E, 0x9EC9, 0xC65F, 0x9ECA, 0xC661, + 0x9ECB, 0xC662, 0x9ECC, 0xC663, 0x9ECD, 0xC664, 0x9ECE, 0xC665, + 0x9ECF, 0xC666, 0x9ED0, 0xC667, 0x9ED1, 0xC668, 0x9ED2, 0xC669, + 0x9ED3, 0xC66A, 0x9ED4, 0xC66B, 0x9ED5, 0xC66D, 0x9ED6, 0xC66E, + 0x9ED7, 0xC670, 0x9ED8, 0xC672, 0x9ED9, 0xC673, 0x9EDA, 0xC674, + 0x9EDB, 0xC675, 0x9EDC, 0xC676, 0x9EDD, 0xC677, 0x9EDE, 0xC67A, + 0x9EDF, 0xC67B, 0x9EE0, 0xC67D, 0x9EE1, 0xC67E, 0x9EE2, 0xC67F, + 0x9EE3, 0xC681, 0x9EE4, 0xC682, 0x9EE5, 0xC683, 0x9EE6, 0xC684, + 0x9EE7, 0xC685, 0x9EE8, 0xC686, 0x9EE9, 0xC687, 0x9EEA, 0xC68A, + 0x9EEB, 0xC68C, 0x9EEC, 0xC68E, 0x9EED, 0xC68F, 0x9EEE, 0xC690, + 0x9EEF, 0xC691, 0x9EF0, 0xC692, 0x9EF1, 0xC693, 0x9EF2, 0xC696, + 0x9EF3, 0xC697, 0x9EF4, 0xC699, 0x9EF5, 0xC69A, 0x9EF6, 0xC69B, + 0x9EF7, 0xC69D, 0x9EF8, 0xC69E, 0x9EF9, 0xC69F, 0x9EFA, 0xC6A0, + 0x9EFB, 0xC6A1, 0x9EFC, 0xC6A2, 0x9EFD, 0xC6A3, 0x9EFE, 0xC6A6, + 0x9F41, 0xC6A8, 0x9F42, 0xC6AA, 0x9F43, 0xC6AB, 0x9F44, 0xC6AC, + 0x9F45, 0xC6AD, 0x9F46, 0xC6AE, 0x9F47, 0xC6AF, 0x9F48, 0xC6B2, + 0x9F49, 0xC6B3, 0x9F4A, 0xC6B5, 0x9F4B, 0xC6B6, 0x9F4C, 0xC6B7, + 0x9F4D, 0xC6BB, 0x9F4E, 0xC6BC, 0x9F4F, 0xC6BD, 0x9F50, 0xC6BE, + 0x9F51, 0xC6BF, 0x9F52, 0xC6C2, 0x9F53, 0xC6C4, 0x9F54, 0xC6C6, + 0x9F55, 0xC6C7, 0x9F56, 0xC6C8, 0x9F57, 0xC6C9, 0x9F58, 0xC6CA, + 0x9F59, 0xC6CB, 0x9F5A, 0xC6CE, 0x9F61, 0xC6CF, 0x9F62, 0xC6D1, + 0x9F63, 0xC6D2, 0x9F64, 0xC6D3, 0x9F65, 0xC6D5, 0x9F66, 0xC6D6, + 0x9F67, 0xC6D7, 0x9F68, 0xC6D8, 0x9F69, 0xC6D9, 0x9F6A, 0xC6DA, + 0x9F6B, 0xC6DB, 0x9F6C, 0xC6DE, 0x9F6D, 0xC6DF, 0x9F6E, 0xC6E2, + 0x9F6F, 0xC6E3, 0x9F70, 0xC6E4, 0x9F71, 0xC6E5, 0x9F72, 0xC6E6, + 0x9F73, 0xC6E7, 0x9F74, 0xC6EA, 0x9F75, 0xC6EB, 0x9F76, 0xC6ED, + 0x9F77, 0xC6EE, 0x9F78, 0xC6EF, 0x9F79, 0xC6F1, 0x9F7A, 0xC6F2, + 0x9F81, 0xC6F3, 0x9F82, 0xC6F4, 0x9F83, 0xC6F5, 0x9F84, 0xC6F6, + 0x9F85, 0xC6F7, 0x9F86, 0xC6FA, 0x9F87, 0xC6FB, 0x9F88, 0xC6FC, + 0x9F89, 0xC6FE, 0x9F8A, 0xC6FF, 0x9F8B, 0xC700, 0x9F8C, 0xC701, + 0x9F8D, 0xC702, 0x9F8E, 0xC703, 0x9F8F, 0xC706, 0x9F90, 0xC707, + 0x9F91, 0xC709, 0x9F92, 0xC70A, 0x9F93, 0xC70B, 0x9F94, 0xC70D, + 0x9F95, 0xC70E, 0x9F96, 0xC70F, 0x9F97, 0xC710, 0x9F98, 0xC711, + 0x9F99, 0xC712, 0x9F9A, 0xC713, 0x9F9B, 0xC716, 0x9F9C, 0xC718, + 0x9F9D, 0xC71A, 0x9F9E, 0xC71B, 0x9F9F, 0xC71C, 0x9FA0, 0xC71D, + 0x9FA1, 0xC71E, 0x9FA2, 0xC71F, 0x9FA3, 0xC722, 0x9FA4, 0xC723, + 0x9FA5, 0xC725, 0x9FA6, 0xC726, 0x9FA7, 0xC727, 0x9FA8, 0xC729, + 0x9FA9, 0xC72A, 0x9FAA, 0xC72B, 0x9FAB, 0xC72C, 0x9FAC, 0xC72D, + 0x9FAD, 0xC72E, 0x9FAE, 0xC72F, 0x9FAF, 0xC732, 0x9FB0, 0xC734, + 0x9FB1, 0xC736, 0x9FB2, 0xC738, 0x9FB3, 0xC739, 0x9FB4, 0xC73A, + 0x9FB5, 0xC73B, 0x9FB6, 0xC73E, 0x9FB7, 0xC73F, 0x9FB8, 0xC741, + 0x9FB9, 0xC742, 0x9FBA, 0xC743, 0x9FBB, 0xC745, 0x9FBC, 0xC746, + 0x9FBD, 0xC747, 0x9FBE, 0xC748, 0x9FBF, 0xC749, 0x9FC0, 0xC74B, + 0x9FC1, 0xC74E, 0x9FC2, 0xC750, 0x9FC3, 0xC759, 0x9FC4, 0xC75A, + 0x9FC5, 0xC75B, 0x9FC6, 0xC75D, 0x9FC7, 0xC75E, 0x9FC8, 0xC75F, + 0x9FC9, 0xC761, 0x9FCA, 0xC762, 0x9FCB, 0xC763, 0x9FCC, 0xC764, + 0x9FCD, 0xC765, 0x9FCE, 0xC766, 0x9FCF, 0xC767, 0x9FD0, 0xC769, + 0x9FD1, 0xC76A, 0x9FD2, 0xC76C, 0x9FD3, 0xC76D, 0x9FD4, 0xC76E, + 0x9FD5, 0xC76F, 0x9FD6, 0xC770, 0x9FD7, 0xC771, 0x9FD8, 0xC772, + 0x9FD9, 0xC773, 0x9FDA, 0xC776, 0x9FDB, 0xC777, 0x9FDC, 0xC779, + 0x9FDD, 0xC77A, 0x9FDE, 0xC77B, 0x9FDF, 0xC77F, 0x9FE0, 0xC780, + 0x9FE1, 0xC781, 0x9FE2, 0xC782, 0x9FE3, 0xC786, 0x9FE4, 0xC78B, + 0x9FE5, 0xC78C, 0x9FE6, 0xC78D, 0x9FE7, 0xC78F, 0x9FE8, 0xC792, + 0x9FE9, 0xC793, 0x9FEA, 0xC795, 0x9FEB, 0xC799, 0x9FEC, 0xC79B, + 0x9FED, 0xC79C, 0x9FEE, 0xC79D, 0x9FEF, 0xC79E, 0x9FF0, 0xC79F, + 0x9FF1, 0xC7A2, 0x9FF2, 0xC7A7, 0x9FF3, 0xC7A8, 0x9FF4, 0xC7A9, + 0x9FF5, 0xC7AA, 0x9FF6, 0xC7AB, 0x9FF7, 0xC7AE, 0x9FF8, 0xC7AF, + 0x9FF9, 0xC7B1, 0x9FFA, 0xC7B2, 0x9FFB, 0xC7B3, 0x9FFC, 0xC7B5, + 0x9FFD, 0xC7B6, 0x9FFE, 0xC7B7, 0xA041, 0xC7B8, 0xA042, 0xC7B9, + 0xA043, 0xC7BA, 0xA044, 0xC7BB, 0xA045, 0xC7BE, 0xA046, 0xC7C2, + 0xA047, 0xC7C3, 0xA048, 0xC7C4, 0xA049, 0xC7C5, 0xA04A, 0xC7C6, + 0xA04B, 0xC7C7, 0xA04C, 0xC7CA, 0xA04D, 0xC7CB, 0xA04E, 0xC7CD, + 0xA04F, 0xC7CF, 0xA050, 0xC7D1, 0xA051, 0xC7D2, 0xA052, 0xC7D3, + 0xA053, 0xC7D4, 0xA054, 0xC7D5, 0xA055, 0xC7D6, 0xA056, 0xC7D7, + 0xA057, 0xC7D9, 0xA058, 0xC7DA, 0xA059, 0xC7DB, 0xA05A, 0xC7DC, + 0xA061, 0xC7DE, 0xA062, 0xC7DF, 0xA063, 0xC7E0, 0xA064, 0xC7E1, + 0xA065, 0xC7E2, 0xA066, 0xC7E3, 0xA067, 0xC7E5, 0xA068, 0xC7E6, + 0xA069, 0xC7E7, 0xA06A, 0xC7E9, 0xA06B, 0xC7EA, 0xA06C, 0xC7EB, + 0xA06D, 0xC7ED, 0xA06E, 0xC7EE, 0xA06F, 0xC7EF, 0xA070, 0xC7F0, + 0xA071, 0xC7F1, 0xA072, 0xC7F2, 0xA073, 0xC7F3, 0xA074, 0xC7F4, + 0xA075, 0xC7F5, 0xA076, 0xC7F6, 0xA077, 0xC7F7, 0xA078, 0xC7F8, + 0xA079, 0xC7F9, 0xA07A, 0xC7FA, 0xA081, 0xC7FB, 0xA082, 0xC7FC, + 0xA083, 0xC7FD, 0xA084, 0xC7FE, 0xA085, 0xC7FF, 0xA086, 0xC802, + 0xA087, 0xC803, 0xA088, 0xC805, 0xA089, 0xC806, 0xA08A, 0xC807, + 0xA08B, 0xC809, 0xA08C, 0xC80B, 0xA08D, 0xC80C, 0xA08E, 0xC80D, + 0xA08F, 0xC80E, 0xA090, 0xC80F, 0xA091, 0xC812, 0xA092, 0xC814, + 0xA093, 0xC817, 0xA094, 0xC818, 0xA095, 0xC819, 0xA096, 0xC81A, + 0xA097, 0xC81B, 0xA098, 0xC81E, 0xA099, 0xC81F, 0xA09A, 0xC821, + 0xA09B, 0xC822, 0xA09C, 0xC823, 0xA09D, 0xC825, 0xA09E, 0xC826, + 0xA09F, 0xC827, 0xA0A0, 0xC828, 0xA0A1, 0xC829, 0xA0A2, 0xC82A, + 0xA0A3, 0xC82B, 0xA0A4, 0xC82E, 0xA0A5, 0xC830, 0xA0A6, 0xC832, + 0xA0A7, 0xC833, 0xA0A8, 0xC834, 0xA0A9, 0xC835, 0xA0AA, 0xC836, + 0xA0AB, 0xC837, 0xA0AC, 0xC839, 0xA0AD, 0xC83A, 0xA0AE, 0xC83B, + 0xA0AF, 0xC83D, 0xA0B0, 0xC83E, 0xA0B1, 0xC83F, 0xA0B2, 0xC841, + 0xA0B3, 0xC842, 0xA0B4, 0xC843, 0xA0B5, 0xC844, 0xA0B6, 0xC845, + 0xA0B7, 0xC846, 0xA0B8, 0xC847, 0xA0B9, 0xC84A, 0xA0BA, 0xC84B, + 0xA0BB, 0xC84E, 0xA0BC, 0xC84F, 0xA0BD, 0xC850, 0xA0BE, 0xC851, + 0xA0BF, 0xC852, 0xA0C0, 0xC853, 0xA0C1, 0xC855, 0xA0C2, 0xC856, + 0xA0C3, 0xC857, 0xA0C4, 0xC858, 0xA0C5, 0xC859, 0xA0C6, 0xC85A, + 0xA0C7, 0xC85B, 0xA0C8, 0xC85C, 0xA0C9, 0xC85D, 0xA0CA, 0xC85E, + 0xA0CB, 0xC85F, 0xA0CC, 0xC860, 0xA0CD, 0xC861, 0xA0CE, 0xC862, + 0xA0CF, 0xC863, 0xA0D0, 0xC864, 0xA0D1, 0xC865, 0xA0D2, 0xC866, + 0xA0D3, 0xC867, 0xA0D4, 0xC868, 0xA0D5, 0xC869, 0xA0D6, 0xC86A, + 0xA0D7, 0xC86B, 0xA0D8, 0xC86C, 0xA0D9, 0xC86D, 0xA0DA, 0xC86E, + 0xA0DB, 0xC86F, 0xA0DC, 0xC872, 0xA0DD, 0xC873, 0xA0DE, 0xC875, + 0xA0DF, 0xC876, 0xA0E0, 0xC877, 0xA0E1, 0xC879, 0xA0E2, 0xC87B, + 0xA0E3, 0xC87C, 0xA0E4, 0xC87D, 0xA0E5, 0xC87E, 0xA0E6, 0xC87F, + 0xA0E7, 0xC882, 0xA0E8, 0xC884, 0xA0E9, 0xC888, 0xA0EA, 0xC889, + 0xA0EB, 0xC88A, 0xA0EC, 0xC88E, 0xA0ED, 0xC88F, 0xA0EE, 0xC890, + 0xA0EF, 0xC891, 0xA0F0, 0xC892, 0xA0F1, 0xC893, 0xA0F2, 0xC895, + 0xA0F3, 0xC896, 0xA0F4, 0xC897, 0xA0F5, 0xC898, 0xA0F6, 0xC899, + 0xA0F7, 0xC89A, 0xA0F8, 0xC89B, 0xA0F9, 0xC89C, 0xA0FA, 0xC89E, + 0xA0FB, 0xC8A0, 0xA0FC, 0xC8A2, 0xA0FD, 0xC8A3, 0xA0FE, 0xC8A4, + 0xA141, 0xC8A5, 0xA142, 0xC8A6, 0xA143, 0xC8A7, 0xA144, 0xC8A9, + 0xA145, 0xC8AA, 0xA146, 0xC8AB, 0xA147, 0xC8AC, 0xA148, 0xC8AD, + 0xA149, 0xC8AE, 0xA14A, 0xC8AF, 0xA14B, 0xC8B0, 0xA14C, 0xC8B1, + 0xA14D, 0xC8B2, 0xA14E, 0xC8B3, 0xA14F, 0xC8B4, 0xA150, 0xC8B5, + 0xA151, 0xC8B6, 0xA152, 0xC8B7, 0xA153, 0xC8B8, 0xA154, 0xC8B9, + 0xA155, 0xC8BA, 0xA156, 0xC8BB, 0xA157, 0xC8BE, 0xA158, 0xC8BF, + 0xA159, 0xC8C0, 0xA15A, 0xC8C1, 0xA161, 0xC8C2, 0xA162, 0xC8C3, + 0xA163, 0xC8C5, 0xA164, 0xC8C6, 0xA165, 0xC8C7, 0xA166, 0xC8C9, + 0xA167, 0xC8CA, 0xA168, 0xC8CB, 0xA169, 0xC8CD, 0xA16A, 0xC8CE, + 0xA16B, 0xC8CF, 0xA16C, 0xC8D0, 0xA16D, 0xC8D1, 0xA16E, 0xC8D2, + 0xA16F, 0xC8D3, 0xA170, 0xC8D6, 0xA171, 0xC8D8, 0xA172, 0xC8DA, + 0xA173, 0xC8DB, 0xA174, 0xC8DC, 0xA175, 0xC8DD, 0xA176, 0xC8DE, + 0xA177, 0xC8DF, 0xA178, 0xC8E2, 0xA179, 0xC8E3, 0xA17A, 0xC8E5, + 0xA181, 0xC8E6, 0xA182, 0xC8E7, 0xA183, 0xC8E8, 0xA184, 0xC8E9, + 0xA185, 0xC8EA, 0xA186, 0xC8EB, 0xA187, 0xC8EC, 0xA188, 0xC8ED, + 0xA189, 0xC8EE, 0xA18A, 0xC8EF, 0xA18B, 0xC8F0, 0xA18C, 0xC8F1, + 0xA18D, 0xC8F2, 0xA18E, 0xC8F3, 0xA18F, 0xC8F4, 0xA190, 0xC8F6, + 0xA191, 0xC8F7, 0xA192, 0xC8F8, 0xA193, 0xC8F9, 0xA194, 0xC8FA, + 0xA195, 0xC8FB, 0xA196, 0xC8FE, 0xA197, 0xC8FF, 0xA198, 0xC901, + 0xA199, 0xC902, 0xA19A, 0xC903, 0xA19B, 0xC907, 0xA19C, 0xC908, + 0xA19D, 0xC909, 0xA19E, 0xC90A, 0xA19F, 0xC90B, 0xA1A0, 0xC90E, + 0xA1A1, 0x3000, 0xA1A2, 0x3001, 0xA1A3, 0x3002, 0xA1A4, 0x00B7, + 0xA1A5, 0x2025, 0xA1A6, 0x2026, 0xA1A7, 0x00A8, 0xA1A8, 0x3003, + 0xA1A9, 0x00AD, 0xA1AA, 0x2015, 0xA1AB, 0x2225, 0xA1AC, 0xFF3C, + 0xA1AD, 0x223C, 0xA1AE, 0x2018, 0xA1AF, 0x2019, 0xA1B0, 0x201C, + 0xA1B1, 0x201D, 0xA1B2, 0x3014, 0xA1B3, 0x3015, 0xA1B4, 0x3008, + 0xA1B5, 0x3009, 0xA1B6, 0x300A, 0xA1B7, 0x300B, 0xA1B8, 0x300C, + 0xA1B9, 0x300D, 0xA1BA, 0x300E, 0xA1BB, 0x300F, 0xA1BC, 0x3010, + 0xA1BD, 0x3011, 0xA1BE, 0x00B1, 0xA1BF, 0x00D7, 0xA1C0, 0x00F7, + 0xA1C1, 0x2260, 0xA1C2, 0x2264, 0xA1C3, 0x2265, 0xA1C4, 0x221E, + 0xA1C5, 0x2234, 0xA1C6, 0x00B0, 0xA1C7, 0x2032, 0xA1C8, 0x2033, + 0xA1C9, 0x2103, 0xA1CA, 0x212B, 0xA1CB, 0xFFE0, 0xA1CC, 0xFFE1, + 0xA1CD, 0xFFE5, 0xA1CE, 0x2642, 0xA1CF, 0x2640, 0xA1D0, 0x2220, + 0xA1D1, 0x22A5, 0xA1D2, 0x2312, 0xA1D3, 0x2202, 0xA1D4, 0x2207, + 0xA1D5, 0x2261, 0xA1D6, 0x2252, 0xA1D7, 0x00A7, 0xA1D8, 0x203B, + 0xA1D9, 0x2606, 0xA1DA, 0x2605, 0xA1DB, 0x25CB, 0xA1DC, 0x25CF, + 0xA1DD, 0x25CE, 0xA1DE, 0x25C7, 0xA1DF, 0x25C6, 0xA1E0, 0x25A1, + 0xA1E1, 0x25A0, 0xA1E2, 0x25B3, 0xA1E3, 0x25B2, 0xA1E4, 0x25BD, + 0xA1E5, 0x25BC, 0xA1E6, 0x2192, 0xA1E7, 0x2190, 0xA1E8, 0x2191, + 0xA1E9, 0x2193, 0xA1EA, 0x2194, 0xA1EB, 0x3013, 0xA1EC, 0x226A, + 0xA1ED, 0x226B, 0xA1EE, 0x221A, 0xA1EF, 0x223D, 0xA1F0, 0x221D, + 0xA1F1, 0x2235, 0xA1F2, 0x222B, 0xA1F3, 0x222C, 0xA1F4, 0x2208, + 0xA1F5, 0x220B, 0xA1F6, 0x2286, 0xA1F7, 0x2287, 0xA1F8, 0x2282, + 0xA1F9, 0x2283, 0xA1FA, 0x222A, 0xA1FB, 0x2229, 0xA1FC, 0x2227, + 0xA1FD, 0x2228, 0xA1FE, 0xFFE2, 0xA241, 0xC910, 0xA242, 0xC912, + 0xA243, 0xC913, 0xA244, 0xC914, 0xA245, 0xC915, 0xA246, 0xC916, + 0xA247, 0xC917, 0xA248, 0xC919, 0xA249, 0xC91A, 0xA24A, 0xC91B, + 0xA24B, 0xC91C, 0xA24C, 0xC91D, 0xA24D, 0xC91E, 0xA24E, 0xC91F, + 0xA24F, 0xC920, 0xA250, 0xC921, 0xA251, 0xC922, 0xA252, 0xC923, + 0xA253, 0xC924, 0xA254, 0xC925, 0xA255, 0xC926, 0xA256, 0xC927, + 0xA257, 0xC928, 0xA258, 0xC929, 0xA259, 0xC92A, 0xA25A, 0xC92B, + 0xA261, 0xC92D, 0xA262, 0xC92E, 0xA263, 0xC92F, 0xA264, 0xC930, + 0xA265, 0xC931, 0xA266, 0xC932, 0xA267, 0xC933, 0xA268, 0xC935, + 0xA269, 0xC936, 0xA26A, 0xC937, 0xA26B, 0xC938, 0xA26C, 0xC939, + 0xA26D, 0xC93A, 0xA26E, 0xC93B, 0xA26F, 0xC93C, 0xA270, 0xC93D, + 0xA271, 0xC93E, 0xA272, 0xC93F, 0xA273, 0xC940, 0xA274, 0xC941, + 0xA275, 0xC942, 0xA276, 0xC943, 0xA277, 0xC944, 0xA278, 0xC945, + 0xA279, 0xC946, 0xA27A, 0xC947, 0xA281, 0xC948, 0xA282, 0xC949, + 0xA283, 0xC94A, 0xA284, 0xC94B, 0xA285, 0xC94C, 0xA286, 0xC94D, + 0xA287, 0xC94E, 0xA288, 0xC94F, 0xA289, 0xC952, 0xA28A, 0xC953, + 0xA28B, 0xC955, 0xA28C, 0xC956, 0xA28D, 0xC957, 0xA28E, 0xC959, + 0xA28F, 0xC95A, 0xA290, 0xC95B, 0xA291, 0xC95C, 0xA292, 0xC95D, + 0xA293, 0xC95E, 0xA294, 0xC95F, 0xA295, 0xC962, 0xA296, 0xC964, + 0xA297, 0xC965, 0xA298, 0xC966, 0xA299, 0xC967, 0xA29A, 0xC968, + 0xA29B, 0xC969, 0xA29C, 0xC96A, 0xA29D, 0xC96B, 0xA29E, 0xC96D, + 0xA29F, 0xC96E, 0xA2A0, 0xC96F, 0xA2A1, 0x21D2, 0xA2A2, 0x21D4, + 0xA2A3, 0x2200, 0xA2A4, 0x2203, 0xA2A5, 0x00B4, 0xA2A6, 0xFF5E, + 0xA2A7, 0x02C7, 0xA2A8, 0x02D8, 0xA2A9, 0x02DD, 0xA2AA, 0x02DA, + 0xA2AB, 0x02D9, 0xA2AC, 0x00B8, 0xA2AD, 0x02DB, 0xA2AE, 0x00A1, + 0xA2AF, 0x00BF, 0xA2B0, 0x02D0, 0xA2B1, 0x222E, 0xA2B2, 0x2211, + 0xA2B3, 0x220F, 0xA2B4, 0x00A4, 0xA2B5, 0x2109, 0xA2B6, 0x2030, + 0xA2B7, 0x25C1, 0xA2B8, 0x25C0, 0xA2B9, 0x25B7, 0xA2BA, 0x25B6, + 0xA2BB, 0x2664, 0xA2BC, 0x2660, 0xA2BD, 0x2661, 0xA2BE, 0x2665, + 0xA2BF, 0x2667, 0xA2C0, 0x2663, 0xA2C1, 0x2299, 0xA2C2, 0x25C8, + 0xA2C3, 0x25A3, 0xA2C4, 0x25D0, 0xA2C5, 0x25D1, 0xA2C6, 0x2592, + 0xA2C7, 0x25A4, 0xA2C8, 0x25A5, 0xA2C9, 0x25A8, 0xA2CA, 0x25A7, + 0xA2CB, 0x25A6, 0xA2CC, 0x25A9, 0xA2CD, 0x2668, 0xA2CE, 0x260F, + 0xA2CF, 0x260E, 0xA2D0, 0x261C, 0xA2D1, 0x261E, 0xA2D2, 0x00B6, + 0xA2D3, 0x2020, 0xA2D4, 0x2021, 0xA2D5, 0x2195, 0xA2D6, 0x2197, + 0xA2D7, 0x2199, 0xA2D8, 0x2196, 0xA2D9, 0x2198, 0xA2DA, 0x266D, + 0xA2DB, 0x2669, 0xA2DC, 0x266A, 0xA2DD, 0x266C, 0xA2DE, 0x327F, + 0xA2DF, 0x321C, 0xA2E0, 0x2116, 0xA2E1, 0x33C7, 0xA2E2, 0x2122, + 0xA2E3, 0x33C2, 0xA2E4, 0x33D8, 0xA2E5, 0x2121, 0xA2E6, 0x20AC, + 0xA2E7, 0x00AE, 0xA341, 0xC971, 0xA342, 0xC972, 0xA343, 0xC973, + 0xA344, 0xC975, 0xA345, 0xC976, 0xA346, 0xC977, 0xA347, 0xC978, + 0xA348, 0xC979, 0xA349, 0xC97A, 0xA34A, 0xC97B, 0xA34B, 0xC97D, + 0xA34C, 0xC97E, 0xA34D, 0xC97F, 0xA34E, 0xC980, 0xA34F, 0xC981, + 0xA350, 0xC982, 0xA351, 0xC983, 0xA352, 0xC984, 0xA353, 0xC985, + 0xA354, 0xC986, 0xA355, 0xC987, 0xA356, 0xC98A, 0xA357, 0xC98B, + 0xA358, 0xC98D, 0xA359, 0xC98E, 0xA35A, 0xC98F, 0xA361, 0xC991, + 0xA362, 0xC992, 0xA363, 0xC993, 0xA364, 0xC994, 0xA365, 0xC995, + 0xA366, 0xC996, 0xA367, 0xC997, 0xA368, 0xC99A, 0xA369, 0xC99C, + 0xA36A, 0xC99E, 0xA36B, 0xC99F, 0xA36C, 0xC9A0, 0xA36D, 0xC9A1, + 0xA36E, 0xC9A2, 0xA36F, 0xC9A3, 0xA370, 0xC9A4, 0xA371, 0xC9A5, + 0xA372, 0xC9A6, 0xA373, 0xC9A7, 0xA374, 0xC9A8, 0xA375, 0xC9A9, + 0xA376, 0xC9AA, 0xA377, 0xC9AB, 0xA378, 0xC9AC, 0xA379, 0xC9AD, + 0xA37A, 0xC9AE, 0xA381, 0xC9AF, 0xA382, 0xC9B0, 0xA383, 0xC9B1, + 0xA384, 0xC9B2, 0xA385, 0xC9B3, 0xA386, 0xC9B4, 0xA387, 0xC9B5, + 0xA388, 0xC9B6, 0xA389, 0xC9B7, 0xA38A, 0xC9B8, 0xA38B, 0xC9B9, + 0xA38C, 0xC9BA, 0xA38D, 0xC9BB, 0xA38E, 0xC9BC, 0xA38F, 0xC9BD, + 0xA390, 0xC9BE, 0xA391, 0xC9BF, 0xA392, 0xC9C2, 0xA393, 0xC9C3, + 0xA394, 0xC9C5, 0xA395, 0xC9C6, 0xA396, 0xC9C9, 0xA397, 0xC9CB, + 0xA398, 0xC9CC, 0xA399, 0xC9CD, 0xA39A, 0xC9CE, 0xA39B, 0xC9CF, + 0xA39C, 0xC9D2, 0xA39D, 0xC9D4, 0xA39E, 0xC9D7, 0xA39F, 0xC9D8, + 0xA3A0, 0xC9DB, 0xA3A1, 0xFF01, 0xA3A2, 0xFF02, 0xA3A3, 0xFF03, + 0xA3A4, 0xFF04, 0xA3A5, 0xFF05, 0xA3A6, 0xFF06, 0xA3A7, 0xFF07, + 0xA3A8, 0xFF08, 0xA3A9, 0xFF09, 0xA3AA, 0xFF0A, 0xA3AB, 0xFF0B, + 0xA3AC, 0xFF0C, 0xA3AD, 0xFF0D, 0xA3AE, 0xFF0E, 0xA3AF, 0xFF0F, + 0xA3B0, 0xFF10, 0xA3B1, 0xFF11, 0xA3B2, 0xFF12, 0xA3B3, 0xFF13, + 0xA3B4, 0xFF14, 0xA3B5, 0xFF15, 0xA3B6, 0xFF16, 0xA3B7, 0xFF17, + 0xA3B8, 0xFF18, 0xA3B9, 0xFF19, 0xA3BA, 0xFF1A, 0xA3BB, 0xFF1B, + 0xA3BC, 0xFF1C, 0xA3BD, 0xFF1D, 0xA3BE, 0xFF1E, 0xA3BF, 0xFF1F, + 0xA3C0, 0xFF20, 0xA3C1, 0xFF21, 0xA3C2, 0xFF22, 0xA3C3, 0xFF23, + 0xA3C4, 0xFF24, 0xA3C5, 0xFF25, 0xA3C6, 0xFF26, 0xA3C7, 0xFF27, + 0xA3C8, 0xFF28, 0xA3C9, 0xFF29, 0xA3CA, 0xFF2A, 0xA3CB, 0xFF2B, + 0xA3CC, 0xFF2C, 0xA3CD, 0xFF2D, 0xA3CE, 0xFF2E, 0xA3CF, 0xFF2F, + 0xA3D0, 0xFF30, 0xA3D1, 0xFF31, 0xA3D2, 0xFF32, 0xA3D3, 0xFF33, + 0xA3D4, 0xFF34, 0xA3D5, 0xFF35, 0xA3D6, 0xFF36, 0xA3D7, 0xFF37, + 0xA3D8, 0xFF38, 0xA3D9, 0xFF39, 0xA3DA, 0xFF3A, 0xA3DB, 0xFF3B, + 0xA3DC, 0xFFE6, 0xA3DD, 0xFF3D, 0xA3DE, 0xFF3E, 0xA3DF, 0xFF3F, + 0xA3E0, 0xFF40, 0xA3E1, 0xFF41, 0xA3E2, 0xFF42, 0xA3E3, 0xFF43, + 0xA3E4, 0xFF44, 0xA3E5, 0xFF45, 0xA3E6, 0xFF46, 0xA3E7, 0xFF47, + 0xA3E8, 0xFF48, 0xA3E9, 0xFF49, 0xA3EA, 0xFF4A, 0xA3EB, 0xFF4B, + 0xA3EC, 0xFF4C, 0xA3ED, 0xFF4D, 0xA3EE, 0xFF4E, 0xA3EF, 0xFF4F, + 0xA3F0, 0xFF50, 0xA3F1, 0xFF51, 0xA3F2, 0xFF52, 0xA3F3, 0xFF53, + 0xA3F4, 0xFF54, 0xA3F5, 0xFF55, 0xA3F6, 0xFF56, 0xA3F7, 0xFF57, + 0xA3F8, 0xFF58, 0xA3F9, 0xFF59, 0xA3FA, 0xFF5A, 0xA3FB, 0xFF5B, + 0xA3FC, 0xFF5C, 0xA3FD, 0xFF5D, 0xA3FE, 0xFFE3, 0xA441, 0xC9DE, + 0xA442, 0xC9DF, 0xA443, 0xC9E1, 0xA444, 0xC9E3, 0xA445, 0xC9E5, + 0xA446, 0xC9E6, 0xA447, 0xC9E8, 0xA448, 0xC9E9, 0xA449, 0xC9EA, + 0xA44A, 0xC9EB, 0xA44B, 0xC9EE, 0xA44C, 0xC9F2, 0xA44D, 0xC9F3, + 0xA44E, 0xC9F4, 0xA44F, 0xC9F5, 0xA450, 0xC9F6, 0xA451, 0xC9F7, + 0xA452, 0xC9FA, 0xA453, 0xC9FB, 0xA454, 0xC9FD, 0xA455, 0xC9FE, + 0xA456, 0xC9FF, 0xA457, 0xCA01, 0xA458, 0xCA02, 0xA459, 0xCA03, + 0xA45A, 0xCA04, 0xA461, 0xCA05, 0xA462, 0xCA06, 0xA463, 0xCA07, + 0xA464, 0xCA0A, 0xA465, 0xCA0E, 0xA466, 0xCA0F, 0xA467, 0xCA10, + 0xA468, 0xCA11, 0xA469, 0xCA12, 0xA46A, 0xCA13, 0xA46B, 0xCA15, + 0xA46C, 0xCA16, 0xA46D, 0xCA17, 0xA46E, 0xCA19, 0xA46F, 0xCA1A, + 0xA470, 0xCA1B, 0xA471, 0xCA1C, 0xA472, 0xCA1D, 0xA473, 0xCA1E, + 0xA474, 0xCA1F, 0xA475, 0xCA20, 0xA476, 0xCA21, 0xA477, 0xCA22, + 0xA478, 0xCA23, 0xA479, 0xCA24, 0xA47A, 0xCA25, 0xA481, 0xCA26, + 0xA482, 0xCA27, 0xA483, 0xCA28, 0xA484, 0xCA2A, 0xA485, 0xCA2B, + 0xA486, 0xCA2C, 0xA487, 0xCA2D, 0xA488, 0xCA2E, 0xA489, 0xCA2F, + 0xA48A, 0xCA30, 0xA48B, 0xCA31, 0xA48C, 0xCA32, 0xA48D, 0xCA33, + 0xA48E, 0xCA34, 0xA48F, 0xCA35, 0xA490, 0xCA36, 0xA491, 0xCA37, + 0xA492, 0xCA38, 0xA493, 0xCA39, 0xA494, 0xCA3A, 0xA495, 0xCA3B, + 0xA496, 0xCA3C, 0xA497, 0xCA3D, 0xA498, 0xCA3E, 0xA499, 0xCA3F, + 0xA49A, 0xCA40, 0xA49B, 0xCA41, 0xA49C, 0xCA42, 0xA49D, 0xCA43, + 0xA49E, 0xCA44, 0xA49F, 0xCA45, 0xA4A0, 0xCA46, 0xA4A1, 0x3131, + 0xA4A2, 0x3132, 0xA4A3, 0x3133, 0xA4A4, 0x3134, 0xA4A5, 0x3135, + 0xA4A6, 0x3136, 0xA4A7, 0x3137, 0xA4A8, 0x3138, 0xA4A9, 0x3139, + 0xA4AA, 0x313A, 0xA4AB, 0x313B, 0xA4AC, 0x313C, 0xA4AD, 0x313D, + 0xA4AE, 0x313E, 0xA4AF, 0x313F, 0xA4B0, 0x3140, 0xA4B1, 0x3141, + 0xA4B2, 0x3142, 0xA4B3, 0x3143, 0xA4B4, 0x3144, 0xA4B5, 0x3145, + 0xA4B6, 0x3146, 0xA4B7, 0x3147, 0xA4B8, 0x3148, 0xA4B9, 0x3149, + 0xA4BA, 0x314A, 0xA4BB, 0x314B, 0xA4BC, 0x314C, 0xA4BD, 0x314D, + 0xA4BE, 0x314E, 0xA4BF, 0x314F, 0xA4C0, 0x3150, 0xA4C1, 0x3151, + 0xA4C2, 0x3152, 0xA4C3, 0x3153, 0xA4C4, 0x3154, 0xA4C5, 0x3155, + 0xA4C6, 0x3156, 0xA4C7, 0x3157, 0xA4C8, 0x3158, 0xA4C9, 0x3159, + 0xA4CA, 0x315A, 0xA4CB, 0x315B, 0xA4CC, 0x315C, 0xA4CD, 0x315D, + 0xA4CE, 0x315E, 0xA4CF, 0x315F, 0xA4D0, 0x3160, 0xA4D1, 0x3161, + 0xA4D2, 0x3162, 0xA4D3, 0x3163, 0xA4D4, 0x3164, 0xA4D5, 0x3165, + 0xA4D6, 0x3166, 0xA4D7, 0x3167, 0xA4D8, 0x3168, 0xA4D9, 0x3169, + 0xA4DA, 0x316A, 0xA4DB, 0x316B, 0xA4DC, 0x316C, 0xA4DD, 0x316D, + 0xA4DE, 0x316E, 0xA4DF, 0x316F, 0xA4E0, 0x3170, 0xA4E1, 0x3171, + 0xA4E2, 0x3172, 0xA4E3, 0x3173, 0xA4E4, 0x3174, 0xA4E5, 0x3175, + 0xA4E6, 0x3176, 0xA4E7, 0x3177, 0xA4E8, 0x3178, 0xA4E9, 0x3179, + 0xA4EA, 0x317A, 0xA4EB, 0x317B, 0xA4EC, 0x317C, 0xA4ED, 0x317D, + 0xA4EE, 0x317E, 0xA4EF, 0x317F, 0xA4F0, 0x3180, 0xA4F1, 0x3181, + 0xA4F2, 0x3182, 0xA4F3, 0x3183, 0xA4F4, 0x3184, 0xA4F5, 0x3185, + 0xA4F6, 0x3186, 0xA4F7, 0x3187, 0xA4F8, 0x3188, 0xA4F9, 0x3189, + 0xA4FA, 0x318A, 0xA4FB, 0x318B, 0xA4FC, 0x318C, 0xA4FD, 0x318D, + 0xA4FE, 0x318E, 0xA541, 0xCA47, 0xA542, 0xCA48, 0xA543, 0xCA49, + 0xA544, 0xCA4A, 0xA545, 0xCA4B, 0xA546, 0xCA4E, 0xA547, 0xCA4F, + 0xA548, 0xCA51, 0xA549, 0xCA52, 0xA54A, 0xCA53, 0xA54B, 0xCA55, + 0xA54C, 0xCA56, 0xA54D, 0xCA57, 0xA54E, 0xCA58, 0xA54F, 0xCA59, + 0xA550, 0xCA5A, 0xA551, 0xCA5B, 0xA552, 0xCA5E, 0xA553, 0xCA62, + 0xA554, 0xCA63, 0xA555, 0xCA64, 0xA556, 0xCA65, 0xA557, 0xCA66, + 0xA558, 0xCA67, 0xA559, 0xCA69, 0xA55A, 0xCA6A, 0xA561, 0xCA6B, + 0xA562, 0xCA6C, 0xA563, 0xCA6D, 0xA564, 0xCA6E, 0xA565, 0xCA6F, + 0xA566, 0xCA70, 0xA567, 0xCA71, 0xA568, 0xCA72, 0xA569, 0xCA73, + 0xA56A, 0xCA74, 0xA56B, 0xCA75, 0xA56C, 0xCA76, 0xA56D, 0xCA77, + 0xA56E, 0xCA78, 0xA56F, 0xCA79, 0xA570, 0xCA7A, 0xA571, 0xCA7B, + 0xA572, 0xCA7C, 0xA573, 0xCA7E, 0xA574, 0xCA7F, 0xA575, 0xCA80, + 0xA576, 0xCA81, 0xA577, 0xCA82, 0xA578, 0xCA83, 0xA579, 0xCA85, + 0xA57A, 0xCA86, 0xA581, 0xCA87, 0xA582, 0xCA88, 0xA583, 0xCA89, + 0xA584, 0xCA8A, 0xA585, 0xCA8B, 0xA586, 0xCA8C, 0xA587, 0xCA8D, + 0xA588, 0xCA8E, 0xA589, 0xCA8F, 0xA58A, 0xCA90, 0xA58B, 0xCA91, + 0xA58C, 0xCA92, 0xA58D, 0xCA93, 0xA58E, 0xCA94, 0xA58F, 0xCA95, + 0xA590, 0xCA96, 0xA591, 0xCA97, 0xA592, 0xCA99, 0xA593, 0xCA9A, + 0xA594, 0xCA9B, 0xA595, 0xCA9C, 0xA596, 0xCA9D, 0xA597, 0xCA9E, + 0xA598, 0xCA9F, 0xA599, 0xCAA0, 0xA59A, 0xCAA1, 0xA59B, 0xCAA2, + 0xA59C, 0xCAA3, 0xA59D, 0xCAA4, 0xA59E, 0xCAA5, 0xA59F, 0xCAA6, + 0xA5A0, 0xCAA7, 0xA5A1, 0x2170, 0xA5A2, 0x2171, 0xA5A3, 0x2172, + 0xA5A4, 0x2173, 0xA5A5, 0x2174, 0xA5A6, 0x2175, 0xA5A7, 0x2176, + 0xA5A8, 0x2177, 0xA5A9, 0x2178, 0xA5AA, 0x2179, 0xA5B0, 0x2160, + 0xA5B1, 0x2161, 0xA5B2, 0x2162, 0xA5B3, 0x2163, 0xA5B4, 0x2164, + 0xA5B5, 0x2165, 0xA5B6, 0x2166, 0xA5B7, 0x2167, 0xA5B8, 0x2168, + 0xA5B9, 0x2169, 0xA5C1, 0x0391, 0xA5C2, 0x0392, 0xA5C3, 0x0393, + 0xA5C4, 0x0394, 0xA5C5, 0x0395, 0xA5C6, 0x0396, 0xA5C7, 0x0397, + 0xA5C8, 0x0398, 0xA5C9, 0x0399, 0xA5CA, 0x039A, 0xA5CB, 0x039B, + 0xA5CC, 0x039C, 0xA5CD, 0x039D, 0xA5CE, 0x039E, 0xA5CF, 0x039F, + 0xA5D0, 0x03A0, 0xA5D1, 0x03A1, 0xA5D2, 0x03A3, 0xA5D3, 0x03A4, + 0xA5D4, 0x03A5, 0xA5D5, 0x03A6, 0xA5D6, 0x03A7, 0xA5D7, 0x03A8, + 0xA5D8, 0x03A9, 0xA5E1, 0x03B1, 0xA5E2, 0x03B2, 0xA5E3, 0x03B3, + 0xA5E4, 0x03B4, 0xA5E5, 0x03B5, 0xA5E6, 0x03B6, 0xA5E7, 0x03B7, + 0xA5E8, 0x03B8, 0xA5E9, 0x03B9, 0xA5EA, 0x03BA, 0xA5EB, 0x03BB, + 0xA5EC, 0x03BC, 0xA5ED, 0x03BD, 0xA5EE, 0x03BE, 0xA5EF, 0x03BF, + 0xA5F0, 0x03C0, 0xA5F1, 0x03C1, 0xA5F2, 0x03C3, 0xA5F3, 0x03C4, + 0xA5F4, 0x03C5, 0xA5F5, 0x03C6, 0xA5F6, 0x03C7, 0xA5F7, 0x03C8, + 0xA5F8, 0x03C9, 0xA641, 0xCAA8, 0xA642, 0xCAA9, 0xA643, 0xCAAA, + 0xA644, 0xCAAB, 0xA645, 0xCAAC, 0xA646, 0xCAAD, 0xA647, 0xCAAE, + 0xA648, 0xCAAF, 0xA649, 0xCAB0, 0xA64A, 0xCAB1, 0xA64B, 0xCAB2, + 0xA64C, 0xCAB3, 0xA64D, 0xCAB4, 0xA64E, 0xCAB5, 0xA64F, 0xCAB6, + 0xA650, 0xCAB7, 0xA651, 0xCAB8, 0xA652, 0xCAB9, 0xA653, 0xCABA, + 0xA654, 0xCABB, 0xA655, 0xCABE, 0xA656, 0xCABF, 0xA657, 0xCAC1, + 0xA658, 0xCAC2, 0xA659, 0xCAC3, 0xA65A, 0xCAC5, 0xA661, 0xCAC6, + 0xA662, 0xCAC7, 0xA663, 0xCAC8, 0xA664, 0xCAC9, 0xA665, 0xCACA, + 0xA666, 0xCACB, 0xA667, 0xCACE, 0xA668, 0xCAD0, 0xA669, 0xCAD2, + 0xA66A, 0xCAD4, 0xA66B, 0xCAD5, 0xA66C, 0xCAD6, 0xA66D, 0xCAD7, + 0xA66E, 0xCADA, 0xA66F, 0xCADB, 0xA670, 0xCADC, 0xA671, 0xCADD, + 0xA672, 0xCADE, 0xA673, 0xCADF, 0xA674, 0xCAE1, 0xA675, 0xCAE2, + 0xA676, 0xCAE3, 0xA677, 0xCAE4, 0xA678, 0xCAE5, 0xA679, 0xCAE6, + 0xA67A, 0xCAE7, 0xA681, 0xCAE8, 0xA682, 0xCAE9, 0xA683, 0xCAEA, + 0xA684, 0xCAEB, 0xA685, 0xCAED, 0xA686, 0xCAEE, 0xA687, 0xCAEF, + 0xA688, 0xCAF0, 0xA689, 0xCAF1, 0xA68A, 0xCAF2, 0xA68B, 0xCAF3, + 0xA68C, 0xCAF5, 0xA68D, 0xCAF6, 0xA68E, 0xCAF7, 0xA68F, 0xCAF8, + 0xA690, 0xCAF9, 0xA691, 0xCAFA, 0xA692, 0xCAFB, 0xA693, 0xCAFC, + 0xA694, 0xCAFD, 0xA695, 0xCAFE, 0xA696, 0xCAFF, 0xA697, 0xCB00, + 0xA698, 0xCB01, 0xA699, 0xCB02, 0xA69A, 0xCB03, 0xA69B, 0xCB04, + 0xA69C, 0xCB05, 0xA69D, 0xCB06, 0xA69E, 0xCB07, 0xA69F, 0xCB09, + 0xA6A0, 0xCB0A, 0xA6A1, 0x2500, 0xA6A2, 0x2502, 0xA6A3, 0x250C, + 0xA6A4, 0x2510, 0xA6A5, 0x2518, 0xA6A6, 0x2514, 0xA6A7, 0x251C, + 0xA6A8, 0x252C, 0xA6A9, 0x2524, 0xA6AA, 0x2534, 0xA6AB, 0x253C, + 0xA6AC, 0x2501, 0xA6AD, 0x2503, 0xA6AE, 0x250F, 0xA6AF, 0x2513, + 0xA6B0, 0x251B, 0xA6B1, 0x2517, 0xA6B2, 0x2523, 0xA6B3, 0x2533, + 0xA6B4, 0x252B, 0xA6B5, 0x253B, 0xA6B6, 0x254B, 0xA6B7, 0x2520, + 0xA6B8, 0x252F, 0xA6B9, 0x2528, 0xA6BA, 0x2537, 0xA6BB, 0x253F, + 0xA6BC, 0x251D, 0xA6BD, 0x2530, 0xA6BE, 0x2525, 0xA6BF, 0x2538, + 0xA6C0, 0x2542, 0xA6C1, 0x2512, 0xA6C2, 0x2511, 0xA6C3, 0x251A, + 0xA6C4, 0x2519, 0xA6C5, 0x2516, 0xA6C6, 0x2515, 0xA6C7, 0x250E, + 0xA6C8, 0x250D, 0xA6C9, 0x251E, 0xA6CA, 0x251F, 0xA6CB, 0x2521, + 0xA6CC, 0x2522, 0xA6CD, 0x2526, 0xA6CE, 0x2527, 0xA6CF, 0x2529, + 0xA6D0, 0x252A, 0xA6D1, 0x252D, 0xA6D2, 0x252E, 0xA6D3, 0x2531, + 0xA6D4, 0x2532, 0xA6D5, 0x2535, 0xA6D6, 0x2536, 0xA6D7, 0x2539, + 0xA6D8, 0x253A, 0xA6D9, 0x253D, 0xA6DA, 0x253E, 0xA6DB, 0x2540, + 0xA6DC, 0x2541, 0xA6DD, 0x2543, 0xA6DE, 0x2544, 0xA6DF, 0x2545, + 0xA6E0, 0x2546, 0xA6E1, 0x2547, 0xA6E2, 0x2548, 0xA6E3, 0x2549, + 0xA6E4, 0x254A, 0xA741, 0xCB0B, 0xA742, 0xCB0C, 0xA743, 0xCB0D, + 0xA744, 0xCB0E, 0xA745, 0xCB0F, 0xA746, 0xCB11, 0xA747, 0xCB12, + 0xA748, 0xCB13, 0xA749, 0xCB15, 0xA74A, 0xCB16, 0xA74B, 0xCB17, + 0xA74C, 0xCB19, 0xA74D, 0xCB1A, 0xA74E, 0xCB1B, 0xA74F, 0xCB1C, + 0xA750, 0xCB1D, 0xA751, 0xCB1E, 0xA752, 0xCB1F, 0xA753, 0xCB22, + 0xA754, 0xCB23, 0xA755, 0xCB24, 0xA756, 0xCB25, 0xA757, 0xCB26, + 0xA758, 0xCB27, 0xA759, 0xCB28, 0xA75A, 0xCB29, 0xA761, 0xCB2A, + 0xA762, 0xCB2B, 0xA763, 0xCB2C, 0xA764, 0xCB2D, 0xA765, 0xCB2E, + 0xA766, 0xCB2F, 0xA767, 0xCB30, 0xA768, 0xCB31, 0xA769, 0xCB32, + 0xA76A, 0xCB33, 0xA76B, 0xCB34, 0xA76C, 0xCB35, 0xA76D, 0xCB36, + 0xA76E, 0xCB37, 0xA76F, 0xCB38, 0xA770, 0xCB39, 0xA771, 0xCB3A, + 0xA772, 0xCB3B, 0xA773, 0xCB3C, 0xA774, 0xCB3D, 0xA775, 0xCB3E, + 0xA776, 0xCB3F, 0xA777, 0xCB40, 0xA778, 0xCB42, 0xA779, 0xCB43, + 0xA77A, 0xCB44, 0xA781, 0xCB45, 0xA782, 0xCB46, 0xA783, 0xCB47, + 0xA784, 0xCB4A, 0xA785, 0xCB4B, 0xA786, 0xCB4D, 0xA787, 0xCB4E, + 0xA788, 0xCB4F, 0xA789, 0xCB51, 0xA78A, 0xCB52, 0xA78B, 0xCB53, + 0xA78C, 0xCB54, 0xA78D, 0xCB55, 0xA78E, 0xCB56, 0xA78F, 0xCB57, + 0xA790, 0xCB5A, 0xA791, 0xCB5B, 0xA792, 0xCB5C, 0xA793, 0xCB5E, + 0xA794, 0xCB5F, 0xA795, 0xCB60, 0xA796, 0xCB61, 0xA797, 0xCB62, + 0xA798, 0xCB63, 0xA799, 0xCB65, 0xA79A, 0xCB66, 0xA79B, 0xCB67, + 0xA79C, 0xCB68, 0xA79D, 0xCB69, 0xA79E, 0xCB6A, 0xA79F, 0xCB6B, + 0xA7A0, 0xCB6C, 0xA7A1, 0x3395, 0xA7A2, 0x3396, 0xA7A3, 0x3397, + 0xA7A4, 0x2113, 0xA7A5, 0x3398, 0xA7A6, 0x33C4, 0xA7A7, 0x33A3, + 0xA7A8, 0x33A4, 0xA7A9, 0x33A5, 0xA7AA, 0x33A6, 0xA7AB, 0x3399, + 0xA7AC, 0x339A, 0xA7AD, 0x339B, 0xA7AE, 0x339C, 0xA7AF, 0x339D, + 0xA7B0, 0x339E, 0xA7B1, 0x339F, 0xA7B2, 0x33A0, 0xA7B3, 0x33A1, + 0xA7B4, 0x33A2, 0xA7B5, 0x33CA, 0xA7B6, 0x338D, 0xA7B7, 0x338E, + 0xA7B8, 0x338F, 0xA7B9, 0x33CF, 0xA7BA, 0x3388, 0xA7BB, 0x3389, + 0xA7BC, 0x33C8, 0xA7BD, 0x33A7, 0xA7BE, 0x33A8, 0xA7BF, 0x33B0, + 0xA7C0, 0x33B1, 0xA7C1, 0x33B2, 0xA7C2, 0x33B3, 0xA7C3, 0x33B4, + 0xA7C4, 0x33B5, 0xA7C5, 0x33B6, 0xA7C6, 0x33B7, 0xA7C7, 0x33B8, + 0xA7C8, 0x33B9, 0xA7C9, 0x3380, 0xA7CA, 0x3381, 0xA7CB, 0x3382, + 0xA7CC, 0x3383, 0xA7CD, 0x3384, 0xA7CE, 0x33BA, 0xA7CF, 0x33BB, + 0xA7D0, 0x33BC, 0xA7D1, 0x33BD, 0xA7D2, 0x33BE, 0xA7D3, 0x33BF, + 0xA7D4, 0x3390, 0xA7D5, 0x3391, 0xA7D6, 0x3392, 0xA7D7, 0x3393, + 0xA7D8, 0x3394, 0xA7D9, 0x2126, 0xA7DA, 0x33C0, 0xA7DB, 0x33C1, + 0xA7DC, 0x338A, 0xA7DD, 0x338B, 0xA7DE, 0x338C, 0xA7DF, 0x33D6, + 0xA7E0, 0x33C5, 0xA7E1, 0x33AD, 0xA7E2, 0x33AE, 0xA7E3, 0x33AF, + 0xA7E4, 0x33DB, 0xA7E5, 0x33A9, 0xA7E6, 0x33AA, 0xA7E7, 0x33AB, + 0xA7E8, 0x33AC, 0xA7E9, 0x33DD, 0xA7EA, 0x33D0, 0xA7EB, 0x33D3, + 0xA7EC, 0x33C3, 0xA7ED, 0x33C9, 0xA7EE, 0x33DC, 0xA7EF, 0x33C6, + 0xA841, 0xCB6D, 0xA842, 0xCB6E, 0xA843, 0xCB6F, 0xA844, 0xCB70, + 0xA845, 0xCB71, 0xA846, 0xCB72, 0xA847, 0xCB73, 0xA848, 0xCB74, + 0xA849, 0xCB75, 0xA84A, 0xCB76, 0xA84B, 0xCB77, 0xA84C, 0xCB7A, + 0xA84D, 0xCB7B, 0xA84E, 0xCB7C, 0xA84F, 0xCB7D, 0xA850, 0xCB7E, + 0xA851, 0xCB7F, 0xA852, 0xCB80, 0xA853, 0xCB81, 0xA854, 0xCB82, + 0xA855, 0xCB83, 0xA856, 0xCB84, 0xA857, 0xCB85, 0xA858, 0xCB86, + 0xA859, 0xCB87, 0xA85A, 0xCB88, 0xA861, 0xCB89, 0xA862, 0xCB8A, + 0xA863, 0xCB8B, 0xA864, 0xCB8C, 0xA865, 0xCB8D, 0xA866, 0xCB8E, + 0xA867, 0xCB8F, 0xA868, 0xCB90, 0xA869, 0xCB91, 0xA86A, 0xCB92, + 0xA86B, 0xCB93, 0xA86C, 0xCB94, 0xA86D, 0xCB95, 0xA86E, 0xCB96, + 0xA86F, 0xCB97, 0xA870, 0xCB98, 0xA871, 0xCB99, 0xA872, 0xCB9A, + 0xA873, 0xCB9B, 0xA874, 0xCB9D, 0xA875, 0xCB9E, 0xA876, 0xCB9F, + 0xA877, 0xCBA0, 0xA878, 0xCBA1, 0xA879, 0xCBA2, 0xA87A, 0xCBA3, + 0xA881, 0xCBA4, 0xA882, 0xCBA5, 0xA883, 0xCBA6, 0xA884, 0xCBA7, + 0xA885, 0xCBA8, 0xA886, 0xCBA9, 0xA887, 0xCBAA, 0xA888, 0xCBAB, + 0xA889, 0xCBAC, 0xA88A, 0xCBAD, 0xA88B, 0xCBAE, 0xA88C, 0xCBAF, + 0xA88D, 0xCBB0, 0xA88E, 0xCBB1, 0xA88F, 0xCBB2, 0xA890, 0xCBB3, + 0xA891, 0xCBB4, 0xA892, 0xCBB5, 0xA893, 0xCBB6, 0xA894, 0xCBB7, + 0xA895, 0xCBB9, 0xA896, 0xCBBA, 0xA897, 0xCBBB, 0xA898, 0xCBBC, + 0xA899, 0xCBBD, 0xA89A, 0xCBBE, 0xA89B, 0xCBBF, 0xA89C, 0xCBC0, + 0xA89D, 0xCBC1, 0xA89E, 0xCBC2, 0xA89F, 0xCBC3, 0xA8A0, 0xCBC4, + 0xA8A1, 0x00C6, 0xA8A2, 0x00D0, 0xA8A3, 0x00AA, 0xA8A4, 0x0126, + 0xA8A6, 0x0132, 0xA8A8, 0x013F, 0xA8A9, 0x0141, 0xA8AA, 0x00D8, + 0xA8AB, 0x0152, 0xA8AC, 0x00BA, 0xA8AD, 0x00DE, 0xA8AE, 0x0166, + 0xA8AF, 0x014A, 0xA8B1, 0x3260, 0xA8B2, 0x3261, 0xA8B3, 0x3262, + 0xA8B4, 0x3263, 0xA8B5, 0x3264, 0xA8B6, 0x3265, 0xA8B7, 0x3266, + 0xA8B8, 0x3267, 0xA8B9, 0x3268, 0xA8BA, 0x3269, 0xA8BB, 0x326A, + 0xA8BC, 0x326B, 0xA8BD, 0x326C, 0xA8BE, 0x326D, 0xA8BF, 0x326E, + 0xA8C0, 0x326F, 0xA8C1, 0x3270, 0xA8C2, 0x3271, 0xA8C3, 0x3272, + 0xA8C4, 0x3273, 0xA8C5, 0x3274, 0xA8C6, 0x3275, 0xA8C7, 0x3276, + 0xA8C8, 0x3277, 0xA8C9, 0x3278, 0xA8CA, 0x3279, 0xA8CB, 0x327A, + 0xA8CC, 0x327B, 0xA8CD, 0x24D0, 0xA8CE, 0x24D1, 0xA8CF, 0x24D2, + 0xA8D0, 0x24D3, 0xA8D1, 0x24D4, 0xA8D2, 0x24D5, 0xA8D3, 0x24D6, + 0xA8D4, 0x24D7, 0xA8D5, 0x24D8, 0xA8D6, 0x24D9, 0xA8D7, 0x24DA, + 0xA8D8, 0x24DB, 0xA8D9, 0x24DC, 0xA8DA, 0x24DD, 0xA8DB, 0x24DE, + 0xA8DC, 0x24DF, 0xA8DD, 0x24E0, 0xA8DE, 0x24E1, 0xA8DF, 0x24E2, + 0xA8E0, 0x24E3, 0xA8E1, 0x24E4, 0xA8E2, 0x24E5, 0xA8E3, 0x24E6, + 0xA8E4, 0x24E7, 0xA8E5, 0x24E8, 0xA8E6, 0x24E9, 0xA8E7, 0x2460, + 0xA8E8, 0x2461, 0xA8E9, 0x2462, 0xA8EA, 0x2463, 0xA8EB, 0x2464, + 0xA8EC, 0x2465, 0xA8ED, 0x2466, 0xA8EE, 0x2467, 0xA8EF, 0x2468, + 0xA8F0, 0x2469, 0xA8F1, 0x246A, 0xA8F2, 0x246B, 0xA8F3, 0x246C, + 0xA8F4, 0x246D, 0xA8F5, 0x246E, 0xA8F6, 0x00BD, 0xA8F7, 0x2153, + 0xA8F8, 0x2154, 0xA8F9, 0x00BC, 0xA8FA, 0x00BE, 0xA8FB, 0x215B, + 0xA8FC, 0x215C, 0xA8FD, 0x215D, 0xA8FE, 0x215E, 0xA941, 0xCBC5, + 0xA942, 0xCBC6, 0xA943, 0xCBC7, 0xA944, 0xCBC8, 0xA945, 0xCBC9, + 0xA946, 0xCBCA, 0xA947, 0xCBCB, 0xA948, 0xCBCC, 0xA949, 0xCBCD, + 0xA94A, 0xCBCE, 0xA94B, 0xCBCF, 0xA94C, 0xCBD0, 0xA94D, 0xCBD1, + 0xA94E, 0xCBD2, 0xA94F, 0xCBD3, 0xA950, 0xCBD5, 0xA951, 0xCBD6, + 0xA952, 0xCBD7, 0xA953, 0xCBD8, 0xA954, 0xCBD9, 0xA955, 0xCBDA, + 0xA956, 0xCBDB, 0xA957, 0xCBDC, 0xA958, 0xCBDD, 0xA959, 0xCBDE, + 0xA95A, 0xCBDF, 0xA961, 0xCBE0, 0xA962, 0xCBE1, 0xA963, 0xCBE2, + 0xA964, 0xCBE3, 0xA965, 0xCBE5, 0xA966, 0xCBE6, 0xA967, 0xCBE8, + 0xA968, 0xCBEA, 0xA969, 0xCBEB, 0xA96A, 0xCBEC, 0xA96B, 0xCBED, + 0xA96C, 0xCBEE, 0xA96D, 0xCBEF, 0xA96E, 0xCBF0, 0xA96F, 0xCBF1, + 0xA970, 0xCBF2, 0xA971, 0xCBF3, 0xA972, 0xCBF4, 0xA973, 0xCBF5, + 0xA974, 0xCBF6, 0xA975, 0xCBF7, 0xA976, 0xCBF8, 0xA977, 0xCBF9, + 0xA978, 0xCBFA, 0xA979, 0xCBFB, 0xA97A, 0xCBFC, 0xA981, 0xCBFD, + 0xA982, 0xCBFE, 0xA983, 0xCBFF, 0xA984, 0xCC00, 0xA985, 0xCC01, + 0xA986, 0xCC02, 0xA987, 0xCC03, 0xA988, 0xCC04, 0xA989, 0xCC05, + 0xA98A, 0xCC06, 0xA98B, 0xCC07, 0xA98C, 0xCC08, 0xA98D, 0xCC09, + 0xA98E, 0xCC0A, 0xA98F, 0xCC0B, 0xA990, 0xCC0E, 0xA991, 0xCC0F, + 0xA992, 0xCC11, 0xA993, 0xCC12, 0xA994, 0xCC13, 0xA995, 0xCC15, + 0xA996, 0xCC16, 0xA997, 0xCC17, 0xA998, 0xCC18, 0xA999, 0xCC19, + 0xA99A, 0xCC1A, 0xA99B, 0xCC1B, 0xA99C, 0xCC1E, 0xA99D, 0xCC1F, + 0xA99E, 0xCC20, 0xA99F, 0xCC23, 0xA9A0, 0xCC24, 0xA9A1, 0x00E6, + 0xA9A2, 0x0111, 0xA9A3, 0x00F0, 0xA9A4, 0x0127, 0xA9A5, 0x0131, + 0xA9A6, 0x0133, 0xA9A7, 0x0138, 0xA9A8, 0x0140, 0xA9A9, 0x0142, + 0xA9AA, 0x00F8, 0xA9AB, 0x0153, 0xA9AC, 0x00DF, 0xA9AD, 0x00FE, + 0xA9AE, 0x0167, 0xA9AF, 0x014B, 0xA9B0, 0x0149, 0xA9B1, 0x3200, + 0xA9B2, 0x3201, 0xA9B3, 0x3202, 0xA9B4, 0x3203, 0xA9B5, 0x3204, + 0xA9B6, 0x3205, 0xA9B7, 0x3206, 0xA9B8, 0x3207, 0xA9B9, 0x3208, + 0xA9BA, 0x3209, 0xA9BB, 0x320A, 0xA9BC, 0x320B, 0xA9BD, 0x320C, + 0xA9BE, 0x320D, 0xA9BF, 0x320E, 0xA9C0, 0x320F, 0xA9C1, 0x3210, + 0xA9C2, 0x3211, 0xA9C3, 0x3212, 0xA9C4, 0x3213, 0xA9C5, 0x3214, + 0xA9C6, 0x3215, 0xA9C7, 0x3216, 0xA9C8, 0x3217, 0xA9C9, 0x3218, + 0xA9CA, 0x3219, 0xA9CB, 0x321A, 0xA9CC, 0x321B, 0xA9CD, 0x249C, + 0xA9CE, 0x249D, 0xA9CF, 0x249E, 0xA9D0, 0x249F, 0xA9D1, 0x24A0, + 0xA9D2, 0x24A1, 0xA9D3, 0x24A2, 0xA9D4, 0x24A3, 0xA9D5, 0x24A4, + 0xA9D6, 0x24A5, 0xA9D7, 0x24A6, 0xA9D8, 0x24A7, 0xA9D9, 0x24A8, + 0xA9DA, 0x24A9, 0xA9DB, 0x24AA, 0xA9DC, 0x24AB, 0xA9DD, 0x24AC, + 0xA9DE, 0x24AD, 0xA9DF, 0x24AE, 0xA9E0, 0x24AF, 0xA9E1, 0x24B0, + 0xA9E2, 0x24B1, 0xA9E3, 0x24B2, 0xA9E4, 0x24B3, 0xA9E5, 0x24B4, + 0xA9E6, 0x24B5, 0xA9E7, 0x2474, 0xA9E8, 0x2475, 0xA9E9, 0x2476, + 0xA9EA, 0x2477, 0xA9EB, 0x2478, 0xA9EC, 0x2479, 0xA9ED, 0x247A, + 0xA9EE, 0x247B, 0xA9EF, 0x247C, 0xA9F0, 0x247D, 0xA9F1, 0x247E, + 0xA9F2, 0x247F, 0xA9F3, 0x2480, 0xA9F4, 0x2481, 0xA9F5, 0x2482, + 0xA9F6, 0x00B9, 0xA9F7, 0x00B2, 0xA9F8, 0x00B3, 0xA9F9, 0x2074, + 0xA9FA, 0x207F, 0xA9FB, 0x2081, 0xA9FC, 0x2082, 0xA9FD, 0x2083, + 0xA9FE, 0x2084, 0xAA41, 0xCC25, 0xAA42, 0xCC26, 0xAA43, 0xCC2A, + 0xAA44, 0xCC2B, 0xAA45, 0xCC2D, 0xAA46, 0xCC2F, 0xAA47, 0xCC31, + 0xAA48, 0xCC32, 0xAA49, 0xCC33, 0xAA4A, 0xCC34, 0xAA4B, 0xCC35, + 0xAA4C, 0xCC36, 0xAA4D, 0xCC37, 0xAA4E, 0xCC3A, 0xAA4F, 0xCC3F, + 0xAA50, 0xCC40, 0xAA51, 0xCC41, 0xAA52, 0xCC42, 0xAA53, 0xCC43, + 0xAA54, 0xCC46, 0xAA55, 0xCC47, 0xAA56, 0xCC49, 0xAA57, 0xCC4A, + 0xAA58, 0xCC4B, 0xAA59, 0xCC4D, 0xAA5A, 0xCC4E, 0xAA61, 0xCC4F, + 0xAA62, 0xCC50, 0xAA63, 0xCC51, 0xAA64, 0xCC52, 0xAA65, 0xCC53, + 0xAA66, 0xCC56, 0xAA67, 0xCC5A, 0xAA68, 0xCC5B, 0xAA69, 0xCC5C, + 0xAA6A, 0xCC5D, 0xAA6B, 0xCC5E, 0xAA6C, 0xCC5F, 0xAA6D, 0xCC61, + 0xAA6E, 0xCC62, 0xAA6F, 0xCC63, 0xAA70, 0xCC65, 0xAA71, 0xCC67, + 0xAA72, 0xCC69, 0xAA73, 0xCC6A, 0xAA74, 0xCC6B, 0xAA75, 0xCC6C, + 0xAA76, 0xCC6D, 0xAA77, 0xCC6E, 0xAA78, 0xCC6F, 0xAA79, 0xCC71, + 0xAA7A, 0xCC72, 0xAA81, 0xCC73, 0xAA82, 0xCC74, 0xAA83, 0xCC76, + 0xAA84, 0xCC77, 0xAA85, 0xCC78, 0xAA86, 0xCC79, 0xAA87, 0xCC7A, + 0xAA88, 0xCC7B, 0xAA89, 0xCC7C, 0xAA8A, 0xCC7D, 0xAA8B, 0xCC7E, + 0xAA8C, 0xCC7F, 0xAA8D, 0xCC80, 0xAA8E, 0xCC81, 0xAA8F, 0xCC82, + 0xAA90, 0xCC83, 0xAA91, 0xCC84, 0xAA92, 0xCC85, 0xAA93, 0xCC86, + 0xAA94, 0xCC87, 0xAA95, 0xCC88, 0xAA96, 0xCC89, 0xAA97, 0xCC8A, + 0xAA98, 0xCC8B, 0xAA99, 0xCC8C, 0xAA9A, 0xCC8D, 0xAA9B, 0xCC8E, + 0xAA9C, 0xCC8F, 0xAA9D, 0xCC90, 0xAA9E, 0xCC91, 0xAA9F, 0xCC92, + 0xAAA0, 0xCC93, 0xAAA1, 0x3041, 0xAAA2, 0x3042, 0xAAA3, 0x3043, + 0xAAA4, 0x3044, 0xAAA5, 0x3045, 0xAAA6, 0x3046, 0xAAA7, 0x3047, + 0xAAA8, 0x3048, 0xAAA9, 0x3049, 0xAAAA, 0x304A, 0xAAAB, 0x304B, + 0xAAAC, 0x304C, 0xAAAD, 0x304D, 0xAAAE, 0x304E, 0xAAAF, 0x304F, + 0xAAB0, 0x3050, 0xAAB1, 0x3051, 0xAAB2, 0x3052, 0xAAB3, 0x3053, + 0xAAB4, 0x3054, 0xAAB5, 0x3055, 0xAAB6, 0x3056, 0xAAB7, 0x3057, + 0xAAB8, 0x3058, 0xAAB9, 0x3059, 0xAABA, 0x305A, 0xAABB, 0x305B, + 0xAABC, 0x305C, 0xAABD, 0x305D, 0xAABE, 0x305E, 0xAABF, 0x305F, + 0xAAC0, 0x3060, 0xAAC1, 0x3061, 0xAAC2, 0x3062, 0xAAC3, 0x3063, + 0xAAC4, 0x3064, 0xAAC5, 0x3065, 0xAAC6, 0x3066, 0xAAC7, 0x3067, + 0xAAC8, 0x3068, 0xAAC9, 0x3069, 0xAACA, 0x306A, 0xAACB, 0x306B, + 0xAACC, 0x306C, 0xAACD, 0x306D, 0xAACE, 0x306E, 0xAACF, 0x306F, + 0xAAD0, 0x3070, 0xAAD1, 0x3071, 0xAAD2, 0x3072, 0xAAD3, 0x3073, + 0xAAD4, 0x3074, 0xAAD5, 0x3075, 0xAAD6, 0x3076, 0xAAD7, 0x3077, + 0xAAD8, 0x3078, 0xAAD9, 0x3079, 0xAADA, 0x307A, 0xAADB, 0x307B, + 0xAADC, 0x307C, 0xAADD, 0x307D, 0xAADE, 0x307E, 0xAADF, 0x307F, + 0xAAE0, 0x3080, 0xAAE1, 0x3081, 0xAAE2, 0x3082, 0xAAE3, 0x3083, + 0xAAE4, 0x3084, 0xAAE5, 0x3085, 0xAAE6, 0x3086, 0xAAE7, 0x3087, + 0xAAE8, 0x3088, 0xAAE9, 0x3089, 0xAAEA, 0x308A, 0xAAEB, 0x308B, + 0xAAEC, 0x308C, 0xAAED, 0x308D, 0xAAEE, 0x308E, 0xAAEF, 0x308F, + 0xAAF0, 0x3090, 0xAAF1, 0x3091, 0xAAF2, 0x3092, 0xAAF3, 0x3093, + 0xAB41, 0xCC94, 0xAB42, 0xCC95, 0xAB43, 0xCC96, 0xAB44, 0xCC97, + 0xAB45, 0xCC9A, 0xAB46, 0xCC9B, 0xAB47, 0xCC9D, 0xAB48, 0xCC9E, + 0xAB49, 0xCC9F, 0xAB4A, 0xCCA1, 0xAB4B, 0xCCA2, 0xAB4C, 0xCCA3, + 0xAB4D, 0xCCA4, 0xAB4E, 0xCCA5, 0xAB4F, 0xCCA6, 0xAB50, 0xCCA7, + 0xAB51, 0xCCAA, 0xAB52, 0xCCAE, 0xAB53, 0xCCAF, 0xAB54, 0xCCB0, + 0xAB55, 0xCCB1, 0xAB56, 0xCCB2, 0xAB57, 0xCCB3, 0xAB58, 0xCCB6, + 0xAB59, 0xCCB7, 0xAB5A, 0xCCB9, 0xAB61, 0xCCBA, 0xAB62, 0xCCBB, + 0xAB63, 0xCCBD, 0xAB64, 0xCCBE, 0xAB65, 0xCCBF, 0xAB66, 0xCCC0, + 0xAB67, 0xCCC1, 0xAB68, 0xCCC2, 0xAB69, 0xCCC3, 0xAB6A, 0xCCC6, + 0xAB6B, 0xCCC8, 0xAB6C, 0xCCCA, 0xAB6D, 0xCCCB, 0xAB6E, 0xCCCC, + 0xAB6F, 0xCCCD, 0xAB70, 0xCCCE, 0xAB71, 0xCCCF, 0xAB72, 0xCCD1, + 0xAB73, 0xCCD2, 0xAB74, 0xCCD3, 0xAB75, 0xCCD5, 0xAB76, 0xCCD6, + 0xAB77, 0xCCD7, 0xAB78, 0xCCD8, 0xAB79, 0xCCD9, 0xAB7A, 0xCCDA, + 0xAB81, 0xCCDB, 0xAB82, 0xCCDC, 0xAB83, 0xCCDD, 0xAB84, 0xCCDE, + 0xAB85, 0xCCDF, 0xAB86, 0xCCE0, 0xAB87, 0xCCE1, 0xAB88, 0xCCE2, + 0xAB89, 0xCCE3, 0xAB8A, 0xCCE5, 0xAB8B, 0xCCE6, 0xAB8C, 0xCCE7, + 0xAB8D, 0xCCE8, 0xAB8E, 0xCCE9, 0xAB8F, 0xCCEA, 0xAB90, 0xCCEB, + 0xAB91, 0xCCED, 0xAB92, 0xCCEE, 0xAB93, 0xCCEF, 0xAB94, 0xCCF1, + 0xAB95, 0xCCF2, 0xAB96, 0xCCF3, 0xAB97, 0xCCF4, 0xAB98, 0xCCF5, + 0xAB99, 0xCCF6, 0xAB9A, 0xCCF7, 0xAB9B, 0xCCF8, 0xAB9C, 0xCCF9, + 0xAB9D, 0xCCFA, 0xAB9E, 0xCCFB, 0xAB9F, 0xCCFC, 0xABA0, 0xCCFD, + 0xABA1, 0x30A1, 0xABA2, 0x30A2, 0xABA3, 0x30A3, 0xABA4, 0x30A4, + 0xABA5, 0x30A5, 0xABA6, 0x30A6, 0xABA7, 0x30A7, 0xABA8, 0x30A8, + 0xABA9, 0x30A9, 0xABAA, 0x30AA, 0xABAB, 0x30AB, 0xABAC, 0x30AC, + 0xABAD, 0x30AD, 0xABAE, 0x30AE, 0xABAF, 0x30AF, 0xABB0, 0x30B0, + 0xABB1, 0x30B1, 0xABB2, 0x30B2, 0xABB3, 0x30B3, 0xABB4, 0x30B4, + 0xABB5, 0x30B5, 0xABB6, 0x30B6, 0xABB7, 0x30B7, 0xABB8, 0x30B8, + 0xABB9, 0x30B9, 0xABBA, 0x30BA, 0xABBB, 0x30BB, 0xABBC, 0x30BC, + 0xABBD, 0x30BD, 0xABBE, 0x30BE, 0xABBF, 0x30BF, 0xABC0, 0x30C0, + 0xABC1, 0x30C1, 0xABC2, 0x30C2, 0xABC3, 0x30C3, 0xABC4, 0x30C4, + 0xABC5, 0x30C5, 0xABC6, 0x30C6, 0xABC7, 0x30C7, 0xABC8, 0x30C8, + 0xABC9, 0x30C9, 0xABCA, 0x30CA, 0xABCB, 0x30CB, 0xABCC, 0x30CC, + 0xABCD, 0x30CD, 0xABCE, 0x30CE, 0xABCF, 0x30CF, 0xABD0, 0x30D0, + 0xABD1, 0x30D1, 0xABD2, 0x30D2, 0xABD3, 0x30D3, 0xABD4, 0x30D4, + 0xABD5, 0x30D5, 0xABD6, 0x30D6, 0xABD7, 0x30D7, 0xABD8, 0x30D8, + 0xABD9, 0x30D9, 0xABDA, 0x30DA, 0xABDB, 0x30DB, 0xABDC, 0x30DC, + 0xABDD, 0x30DD, 0xABDE, 0x30DE, 0xABDF, 0x30DF, 0xABE0, 0x30E0, + 0xABE1, 0x30E1, 0xABE2, 0x30E2, 0xABE3, 0x30E3, 0xABE4, 0x30E4, + 0xABE5, 0x30E5, 0xABE6, 0x30E6, 0xABE7, 0x30E7, 0xABE8, 0x30E8, + 0xABE9, 0x30E9, 0xABEA, 0x30EA, 0xABEB, 0x30EB, 0xABEC, 0x30EC, + 0xABED, 0x30ED, 0xABEE, 0x30EE, 0xABEF, 0x30EF, 0xABF0, 0x30F0, + 0xABF1, 0x30F1, 0xABF2, 0x30F2, 0xABF3, 0x30F3, 0xABF4, 0x30F4, + 0xABF5, 0x30F5, 0xABF6, 0x30F6, 0xAC41, 0xCCFE, 0xAC42, 0xCCFF, + 0xAC43, 0xCD00, 0xAC44, 0xCD02, 0xAC45, 0xCD03, 0xAC46, 0xCD04, + 0xAC47, 0xCD05, 0xAC48, 0xCD06, 0xAC49, 0xCD07, 0xAC4A, 0xCD0A, + 0xAC4B, 0xCD0B, 0xAC4C, 0xCD0D, 0xAC4D, 0xCD0E, 0xAC4E, 0xCD0F, + 0xAC4F, 0xCD11, 0xAC50, 0xCD12, 0xAC51, 0xCD13, 0xAC52, 0xCD14, + 0xAC53, 0xCD15, 0xAC54, 0xCD16, 0xAC55, 0xCD17, 0xAC56, 0xCD1A, + 0xAC57, 0xCD1C, 0xAC58, 0xCD1E, 0xAC59, 0xCD1F, 0xAC5A, 0xCD20, + 0xAC61, 0xCD21, 0xAC62, 0xCD22, 0xAC63, 0xCD23, 0xAC64, 0xCD25, + 0xAC65, 0xCD26, 0xAC66, 0xCD27, 0xAC67, 0xCD29, 0xAC68, 0xCD2A, + 0xAC69, 0xCD2B, 0xAC6A, 0xCD2D, 0xAC6B, 0xCD2E, 0xAC6C, 0xCD2F, + 0xAC6D, 0xCD30, 0xAC6E, 0xCD31, 0xAC6F, 0xCD32, 0xAC70, 0xCD33, + 0xAC71, 0xCD34, 0xAC72, 0xCD35, 0xAC73, 0xCD36, 0xAC74, 0xCD37, + 0xAC75, 0xCD38, 0xAC76, 0xCD3A, 0xAC77, 0xCD3B, 0xAC78, 0xCD3C, + 0xAC79, 0xCD3D, 0xAC7A, 0xCD3E, 0xAC81, 0xCD3F, 0xAC82, 0xCD40, + 0xAC83, 0xCD41, 0xAC84, 0xCD42, 0xAC85, 0xCD43, 0xAC86, 0xCD44, + 0xAC87, 0xCD45, 0xAC88, 0xCD46, 0xAC89, 0xCD47, 0xAC8A, 0xCD48, + 0xAC8B, 0xCD49, 0xAC8C, 0xCD4A, 0xAC8D, 0xCD4B, 0xAC8E, 0xCD4C, + 0xAC8F, 0xCD4D, 0xAC90, 0xCD4E, 0xAC91, 0xCD4F, 0xAC92, 0xCD50, + 0xAC93, 0xCD51, 0xAC94, 0xCD52, 0xAC95, 0xCD53, 0xAC96, 0xCD54, + 0xAC97, 0xCD55, 0xAC98, 0xCD56, 0xAC99, 0xCD57, 0xAC9A, 0xCD58, + 0xAC9B, 0xCD59, 0xAC9C, 0xCD5A, 0xAC9D, 0xCD5B, 0xAC9E, 0xCD5D, + 0xAC9F, 0xCD5E, 0xACA0, 0xCD5F, 0xACA1, 0x0410, 0xACA2, 0x0411, + 0xACA3, 0x0412, 0xACA4, 0x0413, 0xACA5, 0x0414, 0xACA6, 0x0415, + 0xACA7, 0x0401, 0xACA8, 0x0416, 0xACA9, 0x0417, 0xACAA, 0x0418, + 0xACAB, 0x0419, 0xACAC, 0x041A, 0xACAD, 0x041B, 0xACAE, 0x041C, + 0xACAF, 0x041D, 0xACB0, 0x041E, 0xACB1, 0x041F, 0xACB2, 0x0420, + 0xACB3, 0x0421, 0xACB4, 0x0422, 0xACB5, 0x0423, 0xACB6, 0x0424, + 0xACB7, 0x0425, 0xACB8, 0x0426, 0xACB9, 0x0427, 0xACBA, 0x0428, + 0xACBB, 0x0429, 0xACBC, 0x042A, 0xACBD, 0x042B, 0xACBE, 0x042C, + 0xACBF, 0x042D, 0xACC0, 0x042E, 0xACC1, 0x042F, 0xACD1, 0x0430, + 0xACD2, 0x0431, 0xACD3, 0x0432, 0xACD4, 0x0433, 0xACD5, 0x0434, + 0xACD6, 0x0435, 0xACD7, 0x0451, 0xACD8, 0x0436, 0xACD9, 0x0437, + 0xACDA, 0x0438, 0xACDB, 0x0439, 0xACDC, 0x043A, 0xACDD, 0x043B, + 0xACDE, 0x043C, 0xACDF, 0x043D, 0xACE0, 0x043E, 0xACE1, 0x043F, + 0xACE2, 0x0440, 0xACE3, 0x0441, 0xACE4, 0x0442, 0xACE5, 0x0443, + 0xACE6, 0x0444, 0xACE7, 0x0445, 0xACE8, 0x0446, 0xACE9, 0x0447, + 0xACEA, 0x0448, 0xACEB, 0x0449, 0xACEC, 0x044A, 0xACED, 0x044B, + 0xACEE, 0x044C, 0xACEF, 0x044D, 0xACF0, 0x044E, 0xACF1, 0x044F, + 0xAD41, 0xCD61, 0xAD42, 0xCD62, 0xAD43, 0xCD63, 0xAD44, 0xCD65, + 0xAD45, 0xCD66, 0xAD46, 0xCD67, 0xAD47, 0xCD68, 0xAD48, 0xCD69, + 0xAD49, 0xCD6A, 0xAD4A, 0xCD6B, 0xAD4B, 0xCD6E, 0xAD4C, 0xCD70, + 0xAD4D, 0xCD72, 0xAD4E, 0xCD73, 0xAD4F, 0xCD74, 0xAD50, 0xCD75, + 0xAD51, 0xCD76, 0xAD52, 0xCD77, 0xAD53, 0xCD79, 0xAD54, 0xCD7A, + 0xAD55, 0xCD7B, 0xAD56, 0xCD7C, 0xAD57, 0xCD7D, 0xAD58, 0xCD7E, + 0xAD59, 0xCD7F, 0xAD5A, 0xCD80, 0xAD61, 0xCD81, 0xAD62, 0xCD82, + 0xAD63, 0xCD83, 0xAD64, 0xCD84, 0xAD65, 0xCD85, 0xAD66, 0xCD86, + 0xAD67, 0xCD87, 0xAD68, 0xCD89, 0xAD69, 0xCD8A, 0xAD6A, 0xCD8B, + 0xAD6B, 0xCD8C, 0xAD6C, 0xCD8D, 0xAD6D, 0xCD8E, 0xAD6E, 0xCD8F, + 0xAD6F, 0xCD90, 0xAD70, 0xCD91, 0xAD71, 0xCD92, 0xAD72, 0xCD93, + 0xAD73, 0xCD96, 0xAD74, 0xCD97, 0xAD75, 0xCD99, 0xAD76, 0xCD9A, + 0xAD77, 0xCD9B, 0xAD78, 0xCD9D, 0xAD79, 0xCD9E, 0xAD7A, 0xCD9F, + 0xAD81, 0xCDA0, 0xAD82, 0xCDA1, 0xAD83, 0xCDA2, 0xAD84, 0xCDA3, + 0xAD85, 0xCDA6, 0xAD86, 0xCDA8, 0xAD87, 0xCDAA, 0xAD88, 0xCDAB, + 0xAD89, 0xCDAC, 0xAD8A, 0xCDAD, 0xAD8B, 0xCDAE, 0xAD8C, 0xCDAF, + 0xAD8D, 0xCDB1, 0xAD8E, 0xCDB2, 0xAD8F, 0xCDB3, 0xAD90, 0xCDB4, + 0xAD91, 0xCDB5, 0xAD92, 0xCDB6, 0xAD93, 0xCDB7, 0xAD94, 0xCDB8, + 0xAD95, 0xCDB9, 0xAD96, 0xCDBA, 0xAD97, 0xCDBB, 0xAD98, 0xCDBC, + 0xAD99, 0xCDBD, 0xAD9A, 0xCDBE, 0xAD9B, 0xCDBF, 0xAD9C, 0xCDC0, + 0xAD9D, 0xCDC1, 0xAD9E, 0xCDC2, 0xAD9F, 0xCDC3, 0xADA0, 0xCDC5, + 0xAE41, 0xCDC6, 0xAE42, 0xCDC7, 0xAE43, 0xCDC8, 0xAE44, 0xCDC9, + 0xAE45, 0xCDCA, 0xAE46, 0xCDCB, 0xAE47, 0xCDCD, 0xAE48, 0xCDCE, + 0xAE49, 0xCDCF, 0xAE4A, 0xCDD1, 0xAE4B, 0xCDD2, 0xAE4C, 0xCDD3, + 0xAE4D, 0xCDD4, 0xAE4E, 0xCDD5, 0xAE4F, 0xCDD6, 0xAE50, 0xCDD7, + 0xAE51, 0xCDD8, 0xAE52, 0xCDD9, 0xAE53, 0xCDDA, 0xAE54, 0xCDDB, + 0xAE55, 0xCDDC, 0xAE56, 0xCDDD, 0xAE57, 0xCDDE, 0xAE58, 0xCDDF, + 0xAE59, 0xCDE0, 0xAE5A, 0xCDE1, 0xAE61, 0xCDE2, 0xAE62, 0xCDE3, + 0xAE63, 0xCDE4, 0xAE64, 0xCDE5, 0xAE65, 0xCDE6, 0xAE66, 0xCDE7, + 0xAE67, 0xCDE9, 0xAE68, 0xCDEA, 0xAE69, 0xCDEB, 0xAE6A, 0xCDED, + 0xAE6B, 0xCDEE, 0xAE6C, 0xCDEF, 0xAE6D, 0xCDF1, 0xAE6E, 0xCDF2, + 0xAE6F, 0xCDF3, 0xAE70, 0xCDF4, 0xAE71, 0xCDF5, 0xAE72, 0xCDF6, + 0xAE73, 0xCDF7, 0xAE74, 0xCDFA, 0xAE75, 0xCDFC, 0xAE76, 0xCDFE, + 0xAE77, 0xCDFF, 0xAE78, 0xCE00, 0xAE79, 0xCE01, 0xAE7A, 0xCE02, + 0xAE81, 0xCE03, 0xAE82, 0xCE05, 0xAE83, 0xCE06, 0xAE84, 0xCE07, + 0xAE85, 0xCE09, 0xAE86, 0xCE0A, 0xAE87, 0xCE0B, 0xAE88, 0xCE0D, + 0xAE89, 0xCE0E, 0xAE8A, 0xCE0F, 0xAE8B, 0xCE10, 0xAE8C, 0xCE11, + 0xAE8D, 0xCE12, 0xAE8E, 0xCE13, 0xAE8F, 0xCE15, 0xAE90, 0xCE16, + 0xAE91, 0xCE17, 0xAE92, 0xCE18, 0xAE93, 0xCE1A, 0xAE94, 0xCE1B, + 0xAE95, 0xCE1C, 0xAE96, 0xCE1D, 0xAE97, 0xCE1E, 0xAE98, 0xCE1F, + 0xAE99, 0xCE22, 0xAE9A, 0xCE23, 0xAE9B, 0xCE25, 0xAE9C, 0xCE26, + 0xAE9D, 0xCE27, 0xAE9E, 0xCE29, 0xAE9F, 0xCE2A, 0xAEA0, 0xCE2B, + 0xAF41, 0xCE2C, 0xAF42, 0xCE2D, 0xAF43, 0xCE2E, 0xAF44, 0xCE2F, + 0xAF45, 0xCE32, 0xAF46, 0xCE34, 0xAF47, 0xCE36, 0xAF48, 0xCE37, + 0xAF49, 0xCE38, 0xAF4A, 0xCE39, 0xAF4B, 0xCE3A, 0xAF4C, 0xCE3B, + 0xAF4D, 0xCE3C, 0xAF4E, 0xCE3D, 0xAF4F, 0xCE3E, 0xAF50, 0xCE3F, + 0xAF51, 0xCE40, 0xAF52, 0xCE41, 0xAF53, 0xCE42, 0xAF54, 0xCE43, + 0xAF55, 0xCE44, 0xAF56, 0xCE45, 0xAF57, 0xCE46, 0xAF58, 0xCE47, + 0xAF59, 0xCE48, 0xAF5A, 0xCE49, 0xAF61, 0xCE4A, 0xAF62, 0xCE4B, + 0xAF63, 0xCE4C, 0xAF64, 0xCE4D, 0xAF65, 0xCE4E, 0xAF66, 0xCE4F, + 0xAF67, 0xCE50, 0xAF68, 0xCE51, 0xAF69, 0xCE52, 0xAF6A, 0xCE53, + 0xAF6B, 0xCE54, 0xAF6C, 0xCE55, 0xAF6D, 0xCE56, 0xAF6E, 0xCE57, + 0xAF6F, 0xCE5A, 0xAF70, 0xCE5B, 0xAF71, 0xCE5D, 0xAF72, 0xCE5E, + 0xAF73, 0xCE62, 0xAF74, 0xCE63, 0xAF75, 0xCE64, 0xAF76, 0xCE65, + 0xAF77, 0xCE66, 0xAF78, 0xCE67, 0xAF79, 0xCE6A, 0xAF7A, 0xCE6C, + 0xAF81, 0xCE6E, 0xAF82, 0xCE6F, 0xAF83, 0xCE70, 0xAF84, 0xCE71, + 0xAF85, 0xCE72, 0xAF86, 0xCE73, 0xAF87, 0xCE76, 0xAF88, 0xCE77, + 0xAF89, 0xCE79, 0xAF8A, 0xCE7A, 0xAF8B, 0xCE7B, 0xAF8C, 0xCE7D, + 0xAF8D, 0xCE7E, 0xAF8E, 0xCE7F, 0xAF8F, 0xCE80, 0xAF90, 0xCE81, + 0xAF91, 0xCE82, 0xAF92, 0xCE83, 0xAF93, 0xCE86, 0xAF94, 0xCE88, + 0xAF95, 0xCE8A, 0xAF96, 0xCE8B, 0xAF97, 0xCE8C, 0xAF98, 0xCE8D, + 0xAF99, 0xCE8E, 0xAF9A, 0xCE8F, 0xAF9B, 0xCE92, 0xAF9C, 0xCE93, + 0xAF9D, 0xCE95, 0xAF9E, 0xCE96, 0xAF9F, 0xCE97, 0xAFA0, 0xCE99, + 0xB041, 0xCE9A, 0xB042, 0xCE9B, 0xB043, 0xCE9C, 0xB044, 0xCE9D, + 0xB045, 0xCE9E, 0xB046, 0xCE9F, 0xB047, 0xCEA2, 0xB048, 0xCEA6, + 0xB049, 0xCEA7, 0xB04A, 0xCEA8, 0xB04B, 0xCEA9, 0xB04C, 0xCEAA, + 0xB04D, 0xCEAB, 0xB04E, 0xCEAE, 0xB04F, 0xCEAF, 0xB050, 0xCEB0, + 0xB051, 0xCEB1, 0xB052, 0xCEB2, 0xB053, 0xCEB3, 0xB054, 0xCEB4, + 0xB055, 0xCEB5, 0xB056, 0xCEB6, 0xB057, 0xCEB7, 0xB058, 0xCEB8, + 0xB059, 0xCEB9, 0xB05A, 0xCEBA, 0xB061, 0xCEBB, 0xB062, 0xCEBC, + 0xB063, 0xCEBD, 0xB064, 0xCEBE, 0xB065, 0xCEBF, 0xB066, 0xCEC0, + 0xB067, 0xCEC2, 0xB068, 0xCEC3, 0xB069, 0xCEC4, 0xB06A, 0xCEC5, + 0xB06B, 0xCEC6, 0xB06C, 0xCEC7, 0xB06D, 0xCEC8, 0xB06E, 0xCEC9, + 0xB06F, 0xCECA, 0xB070, 0xCECB, 0xB071, 0xCECC, 0xB072, 0xCECD, + 0xB073, 0xCECE, 0xB074, 0xCECF, 0xB075, 0xCED0, 0xB076, 0xCED1, + 0xB077, 0xCED2, 0xB078, 0xCED3, 0xB079, 0xCED4, 0xB07A, 0xCED5, + 0xB081, 0xCED6, 0xB082, 0xCED7, 0xB083, 0xCED8, 0xB084, 0xCED9, + 0xB085, 0xCEDA, 0xB086, 0xCEDB, 0xB087, 0xCEDC, 0xB088, 0xCEDD, + 0xB089, 0xCEDE, 0xB08A, 0xCEDF, 0xB08B, 0xCEE0, 0xB08C, 0xCEE1, + 0xB08D, 0xCEE2, 0xB08E, 0xCEE3, 0xB08F, 0xCEE6, 0xB090, 0xCEE7, + 0xB091, 0xCEE9, 0xB092, 0xCEEA, 0xB093, 0xCEED, 0xB094, 0xCEEE, + 0xB095, 0xCEEF, 0xB096, 0xCEF0, 0xB097, 0xCEF1, 0xB098, 0xCEF2, + 0xB099, 0xCEF3, 0xB09A, 0xCEF6, 0xB09B, 0xCEFA, 0xB09C, 0xCEFB, + 0xB09D, 0xCEFC, 0xB09E, 0xCEFD, 0xB09F, 0xCEFE, 0xB0A0, 0xCEFF, + 0xB0A1, 0xAC00, 0xB0A2, 0xAC01, 0xB0A3, 0xAC04, 0xB0A4, 0xAC07, + 0xB0A5, 0xAC08, 0xB0A6, 0xAC09, 0xB0A7, 0xAC0A, 0xB0A8, 0xAC10, + 0xB0A9, 0xAC11, 0xB0AA, 0xAC12, 0xB0AB, 0xAC13, 0xB0AC, 0xAC14, + 0xB0AD, 0xAC15, 0xB0AE, 0xAC16, 0xB0AF, 0xAC17, 0xB0B0, 0xAC19, + 0xB0B1, 0xAC1A, 0xB0B2, 0xAC1B, 0xB0B3, 0xAC1C, 0xB0B4, 0xAC1D, + 0xB0B5, 0xAC20, 0xB0B6, 0xAC24, 0xB0B7, 0xAC2C, 0xB0B8, 0xAC2D, + 0xB0B9, 0xAC2F, 0xB0BA, 0xAC30, 0xB0BB, 0xAC31, 0xB0BC, 0xAC38, + 0xB0BD, 0xAC39, 0xB0BE, 0xAC3C, 0xB0BF, 0xAC40, 0xB0C0, 0xAC4B, + 0xB0C1, 0xAC4D, 0xB0C2, 0xAC54, 0xB0C3, 0xAC58, 0xB0C4, 0xAC5C, + 0xB0C5, 0xAC70, 0xB0C6, 0xAC71, 0xB0C7, 0xAC74, 0xB0C8, 0xAC77, + 0xB0C9, 0xAC78, 0xB0CA, 0xAC7A, 0xB0CB, 0xAC80, 0xB0CC, 0xAC81, + 0xB0CD, 0xAC83, 0xB0CE, 0xAC84, 0xB0CF, 0xAC85, 0xB0D0, 0xAC86, + 0xB0D1, 0xAC89, 0xB0D2, 0xAC8A, 0xB0D3, 0xAC8B, 0xB0D4, 0xAC8C, + 0xB0D5, 0xAC90, 0xB0D6, 0xAC94, 0xB0D7, 0xAC9C, 0xB0D8, 0xAC9D, + 0xB0D9, 0xAC9F, 0xB0DA, 0xACA0, 0xB0DB, 0xACA1, 0xB0DC, 0xACA8, + 0xB0DD, 0xACA9, 0xB0DE, 0xACAA, 0xB0DF, 0xACAC, 0xB0E0, 0xACAF, + 0xB0E1, 0xACB0, 0xB0E2, 0xACB8, 0xB0E3, 0xACB9, 0xB0E4, 0xACBB, + 0xB0E5, 0xACBC, 0xB0E6, 0xACBD, 0xB0E7, 0xACC1, 0xB0E8, 0xACC4, + 0xB0E9, 0xACC8, 0xB0EA, 0xACCC, 0xB0EB, 0xACD5, 0xB0EC, 0xACD7, + 0xB0ED, 0xACE0, 0xB0EE, 0xACE1, 0xB0EF, 0xACE4, 0xB0F0, 0xACE7, + 0xB0F1, 0xACE8, 0xB0F2, 0xACEA, 0xB0F3, 0xACEC, 0xB0F4, 0xACEF, + 0xB0F5, 0xACF0, 0xB0F6, 0xACF1, 0xB0F7, 0xACF3, 0xB0F8, 0xACF5, + 0xB0F9, 0xACF6, 0xB0FA, 0xACFC, 0xB0FB, 0xACFD, 0xB0FC, 0xAD00, + 0xB0FD, 0xAD04, 0xB0FE, 0xAD06, 0xB141, 0xCF02, 0xB142, 0xCF03, + 0xB143, 0xCF05, 0xB144, 0xCF06, 0xB145, 0xCF07, 0xB146, 0xCF09, + 0xB147, 0xCF0A, 0xB148, 0xCF0B, 0xB149, 0xCF0C, 0xB14A, 0xCF0D, + 0xB14B, 0xCF0E, 0xB14C, 0xCF0F, 0xB14D, 0xCF12, 0xB14E, 0xCF14, + 0xB14F, 0xCF16, 0xB150, 0xCF17, 0xB151, 0xCF18, 0xB152, 0xCF19, + 0xB153, 0xCF1A, 0xB154, 0xCF1B, 0xB155, 0xCF1D, 0xB156, 0xCF1E, + 0xB157, 0xCF1F, 0xB158, 0xCF21, 0xB159, 0xCF22, 0xB15A, 0xCF23, + 0xB161, 0xCF25, 0xB162, 0xCF26, 0xB163, 0xCF27, 0xB164, 0xCF28, + 0xB165, 0xCF29, 0xB166, 0xCF2A, 0xB167, 0xCF2B, 0xB168, 0xCF2E, + 0xB169, 0xCF32, 0xB16A, 0xCF33, 0xB16B, 0xCF34, 0xB16C, 0xCF35, + 0xB16D, 0xCF36, 0xB16E, 0xCF37, 0xB16F, 0xCF39, 0xB170, 0xCF3A, + 0xB171, 0xCF3B, 0xB172, 0xCF3C, 0xB173, 0xCF3D, 0xB174, 0xCF3E, + 0xB175, 0xCF3F, 0xB176, 0xCF40, 0xB177, 0xCF41, 0xB178, 0xCF42, + 0xB179, 0xCF43, 0xB17A, 0xCF44, 0xB181, 0xCF45, 0xB182, 0xCF46, + 0xB183, 0xCF47, 0xB184, 0xCF48, 0xB185, 0xCF49, 0xB186, 0xCF4A, + 0xB187, 0xCF4B, 0xB188, 0xCF4C, 0xB189, 0xCF4D, 0xB18A, 0xCF4E, + 0xB18B, 0xCF4F, 0xB18C, 0xCF50, 0xB18D, 0xCF51, 0xB18E, 0xCF52, + 0xB18F, 0xCF53, 0xB190, 0xCF56, 0xB191, 0xCF57, 0xB192, 0xCF59, + 0xB193, 0xCF5A, 0xB194, 0xCF5B, 0xB195, 0xCF5D, 0xB196, 0xCF5E, + 0xB197, 0xCF5F, 0xB198, 0xCF60, 0xB199, 0xCF61, 0xB19A, 0xCF62, + 0xB19B, 0xCF63, 0xB19C, 0xCF66, 0xB19D, 0xCF68, 0xB19E, 0xCF6A, + 0xB19F, 0xCF6B, 0xB1A0, 0xCF6C, 0xB1A1, 0xAD0C, 0xB1A2, 0xAD0D, + 0xB1A3, 0xAD0F, 0xB1A4, 0xAD11, 0xB1A5, 0xAD18, 0xB1A6, 0xAD1C, + 0xB1A7, 0xAD20, 0xB1A8, 0xAD29, 0xB1A9, 0xAD2C, 0xB1AA, 0xAD2D, + 0xB1AB, 0xAD34, 0xB1AC, 0xAD35, 0xB1AD, 0xAD38, 0xB1AE, 0xAD3C, + 0xB1AF, 0xAD44, 0xB1B0, 0xAD45, 0xB1B1, 0xAD47, 0xB1B2, 0xAD49, + 0xB1B3, 0xAD50, 0xB1B4, 0xAD54, 0xB1B5, 0xAD58, 0xB1B6, 0xAD61, + 0xB1B7, 0xAD63, 0xB1B8, 0xAD6C, 0xB1B9, 0xAD6D, 0xB1BA, 0xAD70, + 0xB1BB, 0xAD73, 0xB1BC, 0xAD74, 0xB1BD, 0xAD75, 0xB1BE, 0xAD76, + 0xB1BF, 0xAD7B, 0xB1C0, 0xAD7C, 0xB1C1, 0xAD7D, 0xB1C2, 0xAD7F, + 0xB1C3, 0xAD81, 0xB1C4, 0xAD82, 0xB1C5, 0xAD88, 0xB1C6, 0xAD89, + 0xB1C7, 0xAD8C, 0xB1C8, 0xAD90, 0xB1C9, 0xAD9C, 0xB1CA, 0xAD9D, + 0xB1CB, 0xADA4, 0xB1CC, 0xADB7, 0xB1CD, 0xADC0, 0xB1CE, 0xADC1, + 0xB1CF, 0xADC4, 0xB1D0, 0xADC8, 0xB1D1, 0xADD0, 0xB1D2, 0xADD1, + 0xB1D3, 0xADD3, 0xB1D4, 0xADDC, 0xB1D5, 0xADE0, 0xB1D6, 0xADE4, + 0xB1D7, 0xADF8, 0xB1D8, 0xADF9, 0xB1D9, 0xADFC, 0xB1DA, 0xADFF, + 0xB1DB, 0xAE00, 0xB1DC, 0xAE01, 0xB1DD, 0xAE08, 0xB1DE, 0xAE09, + 0xB1DF, 0xAE0B, 0xB1E0, 0xAE0D, 0xB1E1, 0xAE14, 0xB1E2, 0xAE30, + 0xB1E3, 0xAE31, 0xB1E4, 0xAE34, 0xB1E5, 0xAE37, 0xB1E6, 0xAE38, + 0xB1E7, 0xAE3A, 0xB1E8, 0xAE40, 0xB1E9, 0xAE41, 0xB1EA, 0xAE43, + 0xB1EB, 0xAE45, 0xB1EC, 0xAE46, 0xB1ED, 0xAE4A, 0xB1EE, 0xAE4C, + 0xB1EF, 0xAE4D, 0xB1F0, 0xAE4E, 0xB1F1, 0xAE50, 0xB1F2, 0xAE54, + 0xB1F3, 0xAE56, 0xB1F4, 0xAE5C, 0xB1F5, 0xAE5D, 0xB1F6, 0xAE5F, + 0xB1F7, 0xAE60, 0xB1F8, 0xAE61, 0xB1F9, 0xAE65, 0xB1FA, 0xAE68, + 0xB1FB, 0xAE69, 0xB1FC, 0xAE6C, 0xB1FD, 0xAE70, 0xB1FE, 0xAE78, + 0xB241, 0xCF6D, 0xB242, 0xCF6E, 0xB243, 0xCF6F, 0xB244, 0xCF72, + 0xB245, 0xCF73, 0xB246, 0xCF75, 0xB247, 0xCF76, 0xB248, 0xCF77, + 0xB249, 0xCF79, 0xB24A, 0xCF7A, 0xB24B, 0xCF7B, 0xB24C, 0xCF7C, + 0xB24D, 0xCF7D, 0xB24E, 0xCF7E, 0xB24F, 0xCF7F, 0xB250, 0xCF81, + 0xB251, 0xCF82, 0xB252, 0xCF83, 0xB253, 0xCF84, 0xB254, 0xCF86, + 0xB255, 0xCF87, 0xB256, 0xCF88, 0xB257, 0xCF89, 0xB258, 0xCF8A, + 0xB259, 0xCF8B, 0xB25A, 0xCF8D, 0xB261, 0xCF8E, 0xB262, 0xCF8F, + 0xB263, 0xCF90, 0xB264, 0xCF91, 0xB265, 0xCF92, 0xB266, 0xCF93, + 0xB267, 0xCF94, 0xB268, 0xCF95, 0xB269, 0xCF96, 0xB26A, 0xCF97, + 0xB26B, 0xCF98, 0xB26C, 0xCF99, 0xB26D, 0xCF9A, 0xB26E, 0xCF9B, + 0xB26F, 0xCF9C, 0xB270, 0xCF9D, 0xB271, 0xCF9E, 0xB272, 0xCF9F, + 0xB273, 0xCFA0, 0xB274, 0xCFA2, 0xB275, 0xCFA3, 0xB276, 0xCFA4, + 0xB277, 0xCFA5, 0xB278, 0xCFA6, 0xB279, 0xCFA7, 0xB27A, 0xCFA9, + 0xB281, 0xCFAA, 0xB282, 0xCFAB, 0xB283, 0xCFAC, 0xB284, 0xCFAD, + 0xB285, 0xCFAE, 0xB286, 0xCFAF, 0xB287, 0xCFB1, 0xB288, 0xCFB2, + 0xB289, 0xCFB3, 0xB28A, 0xCFB4, 0xB28B, 0xCFB5, 0xB28C, 0xCFB6, + 0xB28D, 0xCFB7, 0xB28E, 0xCFB8, 0xB28F, 0xCFB9, 0xB290, 0xCFBA, + 0xB291, 0xCFBB, 0xB292, 0xCFBC, 0xB293, 0xCFBD, 0xB294, 0xCFBE, + 0xB295, 0xCFBF, 0xB296, 0xCFC0, 0xB297, 0xCFC1, 0xB298, 0xCFC2, + 0xB299, 0xCFC3, 0xB29A, 0xCFC5, 0xB29B, 0xCFC6, 0xB29C, 0xCFC7, + 0xB29D, 0xCFC8, 0xB29E, 0xCFC9, 0xB29F, 0xCFCA, 0xB2A0, 0xCFCB, + 0xB2A1, 0xAE79, 0xB2A2, 0xAE7B, 0xB2A3, 0xAE7C, 0xB2A4, 0xAE7D, + 0xB2A5, 0xAE84, 0xB2A6, 0xAE85, 0xB2A7, 0xAE8C, 0xB2A8, 0xAEBC, + 0xB2A9, 0xAEBD, 0xB2AA, 0xAEBE, 0xB2AB, 0xAEC0, 0xB2AC, 0xAEC4, + 0xB2AD, 0xAECC, 0xB2AE, 0xAECD, 0xB2AF, 0xAECF, 0xB2B0, 0xAED0, + 0xB2B1, 0xAED1, 0xB2B2, 0xAED8, 0xB2B3, 0xAED9, 0xB2B4, 0xAEDC, + 0xB2B5, 0xAEE8, 0xB2B6, 0xAEEB, 0xB2B7, 0xAEED, 0xB2B8, 0xAEF4, + 0xB2B9, 0xAEF8, 0xB2BA, 0xAEFC, 0xB2BB, 0xAF07, 0xB2BC, 0xAF08, + 0xB2BD, 0xAF0D, 0xB2BE, 0xAF10, 0xB2BF, 0xAF2C, 0xB2C0, 0xAF2D, + 0xB2C1, 0xAF30, 0xB2C2, 0xAF32, 0xB2C3, 0xAF34, 0xB2C4, 0xAF3C, + 0xB2C5, 0xAF3D, 0xB2C6, 0xAF3F, 0xB2C7, 0xAF41, 0xB2C8, 0xAF42, + 0xB2C9, 0xAF43, 0xB2CA, 0xAF48, 0xB2CB, 0xAF49, 0xB2CC, 0xAF50, + 0xB2CD, 0xAF5C, 0xB2CE, 0xAF5D, 0xB2CF, 0xAF64, 0xB2D0, 0xAF65, + 0xB2D1, 0xAF79, 0xB2D2, 0xAF80, 0xB2D3, 0xAF84, 0xB2D4, 0xAF88, + 0xB2D5, 0xAF90, 0xB2D6, 0xAF91, 0xB2D7, 0xAF95, 0xB2D8, 0xAF9C, + 0xB2D9, 0xAFB8, 0xB2DA, 0xAFB9, 0xB2DB, 0xAFBC, 0xB2DC, 0xAFC0, + 0xB2DD, 0xAFC7, 0xB2DE, 0xAFC8, 0xB2DF, 0xAFC9, 0xB2E0, 0xAFCB, + 0xB2E1, 0xAFCD, 0xB2E2, 0xAFCE, 0xB2E3, 0xAFD4, 0xB2E4, 0xAFDC, + 0xB2E5, 0xAFE8, 0xB2E6, 0xAFE9, 0xB2E7, 0xAFF0, 0xB2E8, 0xAFF1, + 0xB2E9, 0xAFF4, 0xB2EA, 0xAFF8, 0xB2EB, 0xB000, 0xB2EC, 0xB001, + 0xB2ED, 0xB004, 0xB2EE, 0xB00C, 0xB2EF, 0xB010, 0xB2F0, 0xB014, + 0xB2F1, 0xB01C, 0xB2F2, 0xB01D, 0xB2F3, 0xB028, 0xB2F4, 0xB044, + 0xB2F5, 0xB045, 0xB2F6, 0xB048, 0xB2F7, 0xB04A, 0xB2F8, 0xB04C, + 0xB2F9, 0xB04E, 0xB2FA, 0xB053, 0xB2FB, 0xB054, 0xB2FC, 0xB055, + 0xB2FD, 0xB057, 0xB2FE, 0xB059, 0xB341, 0xCFCC, 0xB342, 0xCFCD, + 0xB343, 0xCFCE, 0xB344, 0xCFCF, 0xB345, 0xCFD0, 0xB346, 0xCFD1, + 0xB347, 0xCFD2, 0xB348, 0xCFD3, 0xB349, 0xCFD4, 0xB34A, 0xCFD5, + 0xB34B, 0xCFD6, 0xB34C, 0xCFD7, 0xB34D, 0xCFD8, 0xB34E, 0xCFD9, + 0xB34F, 0xCFDA, 0xB350, 0xCFDB, 0xB351, 0xCFDC, 0xB352, 0xCFDD, + 0xB353, 0xCFDE, 0xB354, 0xCFDF, 0xB355, 0xCFE2, 0xB356, 0xCFE3, + 0xB357, 0xCFE5, 0xB358, 0xCFE6, 0xB359, 0xCFE7, 0xB35A, 0xCFE9, + 0xB361, 0xCFEA, 0xB362, 0xCFEB, 0xB363, 0xCFEC, 0xB364, 0xCFED, + 0xB365, 0xCFEE, 0xB366, 0xCFEF, 0xB367, 0xCFF2, 0xB368, 0xCFF4, + 0xB369, 0xCFF6, 0xB36A, 0xCFF7, 0xB36B, 0xCFF8, 0xB36C, 0xCFF9, + 0xB36D, 0xCFFA, 0xB36E, 0xCFFB, 0xB36F, 0xCFFD, 0xB370, 0xCFFE, + 0xB371, 0xCFFF, 0xB372, 0xD001, 0xB373, 0xD002, 0xB374, 0xD003, + 0xB375, 0xD005, 0xB376, 0xD006, 0xB377, 0xD007, 0xB378, 0xD008, + 0xB379, 0xD009, 0xB37A, 0xD00A, 0xB381, 0xD00B, 0xB382, 0xD00C, + 0xB383, 0xD00D, 0xB384, 0xD00E, 0xB385, 0xD00F, 0xB386, 0xD010, + 0xB387, 0xD012, 0xB388, 0xD013, 0xB389, 0xD014, 0xB38A, 0xD015, + 0xB38B, 0xD016, 0xB38C, 0xD017, 0xB38D, 0xD019, 0xB38E, 0xD01A, + 0xB38F, 0xD01B, 0xB390, 0xD01C, 0xB391, 0xD01D, 0xB392, 0xD01E, + 0xB393, 0xD01F, 0xB394, 0xD020, 0xB395, 0xD021, 0xB396, 0xD022, + 0xB397, 0xD023, 0xB398, 0xD024, 0xB399, 0xD025, 0xB39A, 0xD026, + 0xB39B, 0xD027, 0xB39C, 0xD028, 0xB39D, 0xD029, 0xB39E, 0xD02A, + 0xB39F, 0xD02B, 0xB3A0, 0xD02C, 0xB3A1, 0xB05D, 0xB3A2, 0xB07C, + 0xB3A3, 0xB07D, 0xB3A4, 0xB080, 0xB3A5, 0xB084, 0xB3A6, 0xB08C, + 0xB3A7, 0xB08D, 0xB3A8, 0xB08F, 0xB3A9, 0xB091, 0xB3AA, 0xB098, + 0xB3AB, 0xB099, 0xB3AC, 0xB09A, 0xB3AD, 0xB09C, 0xB3AE, 0xB09F, + 0xB3AF, 0xB0A0, 0xB3B0, 0xB0A1, 0xB3B1, 0xB0A2, 0xB3B2, 0xB0A8, + 0xB3B3, 0xB0A9, 0xB3B4, 0xB0AB, 0xB3B5, 0xB0AC, 0xB3B6, 0xB0AD, + 0xB3B7, 0xB0AE, 0xB3B8, 0xB0AF, 0xB3B9, 0xB0B1, 0xB3BA, 0xB0B3, + 0xB3BB, 0xB0B4, 0xB3BC, 0xB0B5, 0xB3BD, 0xB0B8, 0xB3BE, 0xB0BC, + 0xB3BF, 0xB0C4, 0xB3C0, 0xB0C5, 0xB3C1, 0xB0C7, 0xB3C2, 0xB0C8, + 0xB3C3, 0xB0C9, 0xB3C4, 0xB0D0, 0xB3C5, 0xB0D1, 0xB3C6, 0xB0D4, + 0xB3C7, 0xB0D8, 0xB3C8, 0xB0E0, 0xB3C9, 0xB0E5, 0xB3CA, 0xB108, + 0xB3CB, 0xB109, 0xB3CC, 0xB10B, 0xB3CD, 0xB10C, 0xB3CE, 0xB110, + 0xB3CF, 0xB112, 0xB3D0, 0xB113, 0xB3D1, 0xB118, 0xB3D2, 0xB119, + 0xB3D3, 0xB11B, 0xB3D4, 0xB11C, 0xB3D5, 0xB11D, 0xB3D6, 0xB123, + 0xB3D7, 0xB124, 0xB3D8, 0xB125, 0xB3D9, 0xB128, 0xB3DA, 0xB12C, + 0xB3DB, 0xB134, 0xB3DC, 0xB135, 0xB3DD, 0xB137, 0xB3DE, 0xB138, + 0xB3DF, 0xB139, 0xB3E0, 0xB140, 0xB3E1, 0xB141, 0xB3E2, 0xB144, + 0xB3E3, 0xB148, 0xB3E4, 0xB150, 0xB3E5, 0xB151, 0xB3E6, 0xB154, + 0xB3E7, 0xB155, 0xB3E8, 0xB158, 0xB3E9, 0xB15C, 0xB3EA, 0xB160, + 0xB3EB, 0xB178, 0xB3EC, 0xB179, 0xB3ED, 0xB17C, 0xB3EE, 0xB180, + 0xB3EF, 0xB182, 0xB3F0, 0xB188, 0xB3F1, 0xB189, 0xB3F2, 0xB18B, + 0xB3F3, 0xB18D, 0xB3F4, 0xB192, 0xB3F5, 0xB193, 0xB3F6, 0xB194, + 0xB3F7, 0xB198, 0xB3F8, 0xB19C, 0xB3F9, 0xB1A8, 0xB3FA, 0xB1CC, + 0xB3FB, 0xB1D0, 0xB3FC, 0xB1D4, 0xB3FD, 0xB1DC, 0xB3FE, 0xB1DD, + 0xB441, 0xD02E, 0xB442, 0xD02F, 0xB443, 0xD030, 0xB444, 0xD031, + 0xB445, 0xD032, 0xB446, 0xD033, 0xB447, 0xD036, 0xB448, 0xD037, + 0xB449, 0xD039, 0xB44A, 0xD03A, 0xB44B, 0xD03B, 0xB44C, 0xD03D, + 0xB44D, 0xD03E, 0xB44E, 0xD03F, 0xB44F, 0xD040, 0xB450, 0xD041, + 0xB451, 0xD042, 0xB452, 0xD043, 0xB453, 0xD046, 0xB454, 0xD048, + 0xB455, 0xD04A, 0xB456, 0xD04B, 0xB457, 0xD04C, 0xB458, 0xD04D, + 0xB459, 0xD04E, 0xB45A, 0xD04F, 0xB461, 0xD051, 0xB462, 0xD052, + 0xB463, 0xD053, 0xB464, 0xD055, 0xB465, 0xD056, 0xB466, 0xD057, + 0xB467, 0xD059, 0xB468, 0xD05A, 0xB469, 0xD05B, 0xB46A, 0xD05C, + 0xB46B, 0xD05D, 0xB46C, 0xD05E, 0xB46D, 0xD05F, 0xB46E, 0xD061, + 0xB46F, 0xD062, 0xB470, 0xD063, 0xB471, 0xD064, 0xB472, 0xD065, + 0xB473, 0xD066, 0xB474, 0xD067, 0xB475, 0xD068, 0xB476, 0xD069, + 0xB477, 0xD06A, 0xB478, 0xD06B, 0xB479, 0xD06E, 0xB47A, 0xD06F, + 0xB481, 0xD071, 0xB482, 0xD072, 0xB483, 0xD073, 0xB484, 0xD075, + 0xB485, 0xD076, 0xB486, 0xD077, 0xB487, 0xD078, 0xB488, 0xD079, + 0xB489, 0xD07A, 0xB48A, 0xD07B, 0xB48B, 0xD07E, 0xB48C, 0xD07F, + 0xB48D, 0xD080, 0xB48E, 0xD082, 0xB48F, 0xD083, 0xB490, 0xD084, + 0xB491, 0xD085, 0xB492, 0xD086, 0xB493, 0xD087, 0xB494, 0xD088, + 0xB495, 0xD089, 0xB496, 0xD08A, 0xB497, 0xD08B, 0xB498, 0xD08C, + 0xB499, 0xD08D, 0xB49A, 0xD08E, 0xB49B, 0xD08F, 0xB49C, 0xD090, + 0xB49D, 0xD091, 0xB49E, 0xD092, 0xB49F, 0xD093, 0xB4A0, 0xD094, + 0xB4A1, 0xB1DF, 0xB4A2, 0xB1E8, 0xB4A3, 0xB1E9, 0xB4A4, 0xB1EC, + 0xB4A5, 0xB1F0, 0xB4A6, 0xB1F9, 0xB4A7, 0xB1FB, 0xB4A8, 0xB1FD, + 0xB4A9, 0xB204, 0xB4AA, 0xB205, 0xB4AB, 0xB208, 0xB4AC, 0xB20B, + 0xB4AD, 0xB20C, 0xB4AE, 0xB214, 0xB4AF, 0xB215, 0xB4B0, 0xB217, + 0xB4B1, 0xB219, 0xB4B2, 0xB220, 0xB4B3, 0xB234, 0xB4B4, 0xB23C, + 0xB4B5, 0xB258, 0xB4B6, 0xB25C, 0xB4B7, 0xB260, 0xB4B8, 0xB268, + 0xB4B9, 0xB269, 0xB4BA, 0xB274, 0xB4BB, 0xB275, 0xB4BC, 0xB27C, + 0xB4BD, 0xB284, 0xB4BE, 0xB285, 0xB4BF, 0xB289, 0xB4C0, 0xB290, + 0xB4C1, 0xB291, 0xB4C2, 0xB294, 0xB4C3, 0xB298, 0xB4C4, 0xB299, + 0xB4C5, 0xB29A, 0xB4C6, 0xB2A0, 0xB4C7, 0xB2A1, 0xB4C8, 0xB2A3, + 0xB4C9, 0xB2A5, 0xB4CA, 0xB2A6, 0xB4CB, 0xB2AA, 0xB4CC, 0xB2AC, + 0xB4CD, 0xB2B0, 0xB4CE, 0xB2B4, 0xB4CF, 0xB2C8, 0xB4D0, 0xB2C9, + 0xB4D1, 0xB2CC, 0xB4D2, 0xB2D0, 0xB4D3, 0xB2D2, 0xB4D4, 0xB2D8, + 0xB4D5, 0xB2D9, 0xB4D6, 0xB2DB, 0xB4D7, 0xB2DD, 0xB4D8, 0xB2E2, + 0xB4D9, 0xB2E4, 0xB4DA, 0xB2E5, 0xB4DB, 0xB2E6, 0xB4DC, 0xB2E8, + 0xB4DD, 0xB2EB, 0xB4DE, 0xB2EC, 0xB4DF, 0xB2ED, 0xB4E0, 0xB2EE, + 0xB4E1, 0xB2EF, 0xB4E2, 0xB2F3, 0xB4E3, 0xB2F4, 0xB4E4, 0xB2F5, + 0xB4E5, 0xB2F7, 0xB4E6, 0xB2F8, 0xB4E7, 0xB2F9, 0xB4E8, 0xB2FA, + 0xB4E9, 0xB2FB, 0xB4EA, 0xB2FF, 0xB4EB, 0xB300, 0xB4EC, 0xB301, + 0xB4ED, 0xB304, 0xB4EE, 0xB308, 0xB4EF, 0xB310, 0xB4F0, 0xB311, + 0xB4F1, 0xB313, 0xB4F2, 0xB314, 0xB4F3, 0xB315, 0xB4F4, 0xB31C, + 0xB4F5, 0xB354, 0xB4F6, 0xB355, 0xB4F7, 0xB356, 0xB4F8, 0xB358, + 0xB4F9, 0xB35B, 0xB4FA, 0xB35C, 0xB4FB, 0xB35E, 0xB4FC, 0xB35F, + 0xB4FD, 0xB364, 0xB4FE, 0xB365, 0xB541, 0xD095, 0xB542, 0xD096, + 0xB543, 0xD097, 0xB544, 0xD098, 0xB545, 0xD099, 0xB546, 0xD09A, + 0xB547, 0xD09B, 0xB548, 0xD09C, 0xB549, 0xD09D, 0xB54A, 0xD09E, + 0xB54B, 0xD09F, 0xB54C, 0xD0A0, 0xB54D, 0xD0A1, 0xB54E, 0xD0A2, + 0xB54F, 0xD0A3, 0xB550, 0xD0A6, 0xB551, 0xD0A7, 0xB552, 0xD0A9, + 0xB553, 0xD0AA, 0xB554, 0xD0AB, 0xB555, 0xD0AD, 0xB556, 0xD0AE, + 0xB557, 0xD0AF, 0xB558, 0xD0B0, 0xB559, 0xD0B1, 0xB55A, 0xD0B2, + 0xB561, 0xD0B3, 0xB562, 0xD0B6, 0xB563, 0xD0B8, 0xB564, 0xD0BA, + 0xB565, 0xD0BB, 0xB566, 0xD0BC, 0xB567, 0xD0BD, 0xB568, 0xD0BE, + 0xB569, 0xD0BF, 0xB56A, 0xD0C2, 0xB56B, 0xD0C3, 0xB56C, 0xD0C5, + 0xB56D, 0xD0C6, 0xB56E, 0xD0C7, 0xB56F, 0xD0CA, 0xB570, 0xD0CB, + 0xB571, 0xD0CC, 0xB572, 0xD0CD, 0xB573, 0xD0CE, 0xB574, 0xD0CF, + 0xB575, 0xD0D2, 0xB576, 0xD0D6, 0xB577, 0xD0D7, 0xB578, 0xD0D8, + 0xB579, 0xD0D9, 0xB57A, 0xD0DA, 0xB581, 0xD0DB, 0xB582, 0xD0DE, + 0xB583, 0xD0DF, 0xB584, 0xD0E1, 0xB585, 0xD0E2, 0xB586, 0xD0E3, + 0xB587, 0xD0E5, 0xB588, 0xD0E6, 0xB589, 0xD0E7, 0xB58A, 0xD0E8, + 0xB58B, 0xD0E9, 0xB58C, 0xD0EA, 0xB58D, 0xD0EB, 0xB58E, 0xD0EE, + 0xB58F, 0xD0F2, 0xB590, 0xD0F3, 0xB591, 0xD0F4, 0xB592, 0xD0F5, + 0xB593, 0xD0F6, 0xB594, 0xD0F7, 0xB595, 0xD0F9, 0xB596, 0xD0FA, + 0xB597, 0xD0FB, 0xB598, 0xD0FC, 0xB599, 0xD0FD, 0xB59A, 0xD0FE, + 0xB59B, 0xD0FF, 0xB59C, 0xD100, 0xB59D, 0xD101, 0xB59E, 0xD102, + 0xB59F, 0xD103, 0xB5A0, 0xD104, 0xB5A1, 0xB367, 0xB5A2, 0xB369, + 0xB5A3, 0xB36B, 0xB5A4, 0xB36E, 0xB5A5, 0xB370, 0xB5A6, 0xB371, + 0xB5A7, 0xB374, 0xB5A8, 0xB378, 0xB5A9, 0xB380, 0xB5AA, 0xB381, + 0xB5AB, 0xB383, 0xB5AC, 0xB384, 0xB5AD, 0xB385, 0xB5AE, 0xB38C, + 0xB5AF, 0xB390, 0xB5B0, 0xB394, 0xB5B1, 0xB3A0, 0xB5B2, 0xB3A1, + 0xB5B3, 0xB3A8, 0xB5B4, 0xB3AC, 0xB5B5, 0xB3C4, 0xB5B6, 0xB3C5, + 0xB5B7, 0xB3C8, 0xB5B8, 0xB3CB, 0xB5B9, 0xB3CC, 0xB5BA, 0xB3CE, + 0xB5BB, 0xB3D0, 0xB5BC, 0xB3D4, 0xB5BD, 0xB3D5, 0xB5BE, 0xB3D7, + 0xB5BF, 0xB3D9, 0xB5C0, 0xB3DB, 0xB5C1, 0xB3DD, 0xB5C2, 0xB3E0, + 0xB5C3, 0xB3E4, 0xB5C4, 0xB3E8, 0xB5C5, 0xB3FC, 0xB5C6, 0xB410, + 0xB5C7, 0xB418, 0xB5C8, 0xB41C, 0xB5C9, 0xB420, 0xB5CA, 0xB428, + 0xB5CB, 0xB429, 0xB5CC, 0xB42B, 0xB5CD, 0xB434, 0xB5CE, 0xB450, + 0xB5CF, 0xB451, 0xB5D0, 0xB454, 0xB5D1, 0xB458, 0xB5D2, 0xB460, + 0xB5D3, 0xB461, 0xB5D4, 0xB463, 0xB5D5, 0xB465, 0xB5D6, 0xB46C, + 0xB5D7, 0xB480, 0xB5D8, 0xB488, 0xB5D9, 0xB49D, 0xB5DA, 0xB4A4, + 0xB5DB, 0xB4A8, 0xB5DC, 0xB4AC, 0xB5DD, 0xB4B5, 0xB5DE, 0xB4B7, + 0xB5DF, 0xB4B9, 0xB5E0, 0xB4C0, 0xB5E1, 0xB4C4, 0xB5E2, 0xB4C8, + 0xB5E3, 0xB4D0, 0xB5E4, 0xB4D5, 0xB5E5, 0xB4DC, 0xB5E6, 0xB4DD, + 0xB5E7, 0xB4E0, 0xB5E8, 0xB4E3, 0xB5E9, 0xB4E4, 0xB5EA, 0xB4E6, + 0xB5EB, 0xB4EC, 0xB5EC, 0xB4ED, 0xB5ED, 0xB4EF, 0xB5EE, 0xB4F1, + 0xB5EF, 0xB4F8, 0xB5F0, 0xB514, 0xB5F1, 0xB515, 0xB5F2, 0xB518, + 0xB5F3, 0xB51B, 0xB5F4, 0xB51C, 0xB5F5, 0xB524, 0xB5F6, 0xB525, + 0xB5F7, 0xB527, 0xB5F8, 0xB528, 0xB5F9, 0xB529, 0xB5FA, 0xB52A, + 0xB5FB, 0xB530, 0xB5FC, 0xB531, 0xB5FD, 0xB534, 0xB5FE, 0xB538, + 0xB641, 0xD105, 0xB642, 0xD106, 0xB643, 0xD107, 0xB644, 0xD108, + 0xB645, 0xD109, 0xB646, 0xD10A, 0xB647, 0xD10B, 0xB648, 0xD10C, + 0xB649, 0xD10E, 0xB64A, 0xD10F, 0xB64B, 0xD110, 0xB64C, 0xD111, + 0xB64D, 0xD112, 0xB64E, 0xD113, 0xB64F, 0xD114, 0xB650, 0xD115, + 0xB651, 0xD116, 0xB652, 0xD117, 0xB653, 0xD118, 0xB654, 0xD119, + 0xB655, 0xD11A, 0xB656, 0xD11B, 0xB657, 0xD11C, 0xB658, 0xD11D, + 0xB659, 0xD11E, 0xB65A, 0xD11F, 0xB661, 0xD120, 0xB662, 0xD121, + 0xB663, 0xD122, 0xB664, 0xD123, 0xB665, 0xD124, 0xB666, 0xD125, + 0xB667, 0xD126, 0xB668, 0xD127, 0xB669, 0xD128, 0xB66A, 0xD129, + 0xB66B, 0xD12A, 0xB66C, 0xD12B, 0xB66D, 0xD12C, 0xB66E, 0xD12D, + 0xB66F, 0xD12E, 0xB670, 0xD12F, 0xB671, 0xD132, 0xB672, 0xD133, + 0xB673, 0xD135, 0xB674, 0xD136, 0xB675, 0xD137, 0xB676, 0xD139, + 0xB677, 0xD13B, 0xB678, 0xD13C, 0xB679, 0xD13D, 0xB67A, 0xD13E, + 0xB681, 0xD13F, 0xB682, 0xD142, 0xB683, 0xD146, 0xB684, 0xD147, + 0xB685, 0xD148, 0xB686, 0xD149, 0xB687, 0xD14A, 0xB688, 0xD14B, + 0xB689, 0xD14E, 0xB68A, 0xD14F, 0xB68B, 0xD151, 0xB68C, 0xD152, + 0xB68D, 0xD153, 0xB68E, 0xD155, 0xB68F, 0xD156, 0xB690, 0xD157, + 0xB691, 0xD158, 0xB692, 0xD159, 0xB693, 0xD15A, 0xB694, 0xD15B, + 0xB695, 0xD15E, 0xB696, 0xD160, 0xB697, 0xD162, 0xB698, 0xD163, + 0xB699, 0xD164, 0xB69A, 0xD165, 0xB69B, 0xD166, 0xB69C, 0xD167, + 0xB69D, 0xD169, 0xB69E, 0xD16A, 0xB69F, 0xD16B, 0xB6A0, 0xD16D, + 0xB6A1, 0xB540, 0xB6A2, 0xB541, 0xB6A3, 0xB543, 0xB6A4, 0xB544, + 0xB6A5, 0xB545, 0xB6A6, 0xB54B, 0xB6A7, 0xB54C, 0xB6A8, 0xB54D, + 0xB6A9, 0xB550, 0xB6AA, 0xB554, 0xB6AB, 0xB55C, 0xB6AC, 0xB55D, + 0xB6AD, 0xB55F, 0xB6AE, 0xB560, 0xB6AF, 0xB561, 0xB6B0, 0xB5A0, + 0xB6B1, 0xB5A1, 0xB6B2, 0xB5A4, 0xB6B3, 0xB5A8, 0xB6B4, 0xB5AA, + 0xB6B5, 0xB5AB, 0xB6B6, 0xB5B0, 0xB6B7, 0xB5B1, 0xB6B8, 0xB5B3, + 0xB6B9, 0xB5B4, 0xB6BA, 0xB5B5, 0xB6BB, 0xB5BB, 0xB6BC, 0xB5BC, + 0xB6BD, 0xB5BD, 0xB6BE, 0xB5C0, 0xB6BF, 0xB5C4, 0xB6C0, 0xB5CC, + 0xB6C1, 0xB5CD, 0xB6C2, 0xB5CF, 0xB6C3, 0xB5D0, 0xB6C4, 0xB5D1, + 0xB6C5, 0xB5D8, 0xB6C6, 0xB5EC, 0xB6C7, 0xB610, 0xB6C8, 0xB611, + 0xB6C9, 0xB614, 0xB6CA, 0xB618, 0xB6CB, 0xB625, 0xB6CC, 0xB62C, + 0xB6CD, 0xB634, 0xB6CE, 0xB648, 0xB6CF, 0xB664, 0xB6D0, 0xB668, + 0xB6D1, 0xB69C, 0xB6D2, 0xB69D, 0xB6D3, 0xB6A0, 0xB6D4, 0xB6A4, + 0xB6D5, 0xB6AB, 0xB6D6, 0xB6AC, 0xB6D7, 0xB6B1, 0xB6D8, 0xB6D4, + 0xB6D9, 0xB6F0, 0xB6DA, 0xB6F4, 0xB6DB, 0xB6F8, 0xB6DC, 0xB700, + 0xB6DD, 0xB701, 0xB6DE, 0xB705, 0xB6DF, 0xB728, 0xB6E0, 0xB729, + 0xB6E1, 0xB72C, 0xB6E2, 0xB72F, 0xB6E3, 0xB730, 0xB6E4, 0xB738, + 0xB6E5, 0xB739, 0xB6E6, 0xB73B, 0xB6E7, 0xB744, 0xB6E8, 0xB748, + 0xB6E9, 0xB74C, 0xB6EA, 0xB754, 0xB6EB, 0xB755, 0xB6EC, 0xB760, + 0xB6ED, 0xB764, 0xB6EE, 0xB768, 0xB6EF, 0xB770, 0xB6F0, 0xB771, + 0xB6F1, 0xB773, 0xB6F2, 0xB775, 0xB6F3, 0xB77C, 0xB6F4, 0xB77D, + 0xB6F5, 0xB780, 0xB6F6, 0xB784, 0xB6F7, 0xB78C, 0xB6F8, 0xB78D, + 0xB6F9, 0xB78F, 0xB6FA, 0xB790, 0xB6FB, 0xB791, 0xB6FC, 0xB792, + 0xB6FD, 0xB796, 0xB6FE, 0xB797, 0xB741, 0xD16E, 0xB742, 0xD16F, + 0xB743, 0xD170, 0xB744, 0xD171, 0xB745, 0xD172, 0xB746, 0xD173, + 0xB747, 0xD174, 0xB748, 0xD175, 0xB749, 0xD176, 0xB74A, 0xD177, + 0xB74B, 0xD178, 0xB74C, 0xD179, 0xB74D, 0xD17A, 0xB74E, 0xD17B, + 0xB74F, 0xD17D, 0xB750, 0xD17E, 0xB751, 0xD17F, 0xB752, 0xD180, + 0xB753, 0xD181, 0xB754, 0xD182, 0xB755, 0xD183, 0xB756, 0xD185, + 0xB757, 0xD186, 0xB758, 0xD187, 0xB759, 0xD189, 0xB75A, 0xD18A, + 0xB761, 0xD18B, 0xB762, 0xD18C, 0xB763, 0xD18D, 0xB764, 0xD18E, + 0xB765, 0xD18F, 0xB766, 0xD190, 0xB767, 0xD191, 0xB768, 0xD192, + 0xB769, 0xD193, 0xB76A, 0xD194, 0xB76B, 0xD195, 0xB76C, 0xD196, + 0xB76D, 0xD197, 0xB76E, 0xD198, 0xB76F, 0xD199, 0xB770, 0xD19A, + 0xB771, 0xD19B, 0xB772, 0xD19C, 0xB773, 0xD19D, 0xB774, 0xD19E, + 0xB775, 0xD19F, 0xB776, 0xD1A2, 0xB777, 0xD1A3, 0xB778, 0xD1A5, + 0xB779, 0xD1A6, 0xB77A, 0xD1A7, 0xB781, 0xD1A9, 0xB782, 0xD1AA, + 0xB783, 0xD1AB, 0xB784, 0xD1AC, 0xB785, 0xD1AD, 0xB786, 0xD1AE, + 0xB787, 0xD1AF, 0xB788, 0xD1B2, 0xB789, 0xD1B4, 0xB78A, 0xD1B6, + 0xB78B, 0xD1B7, 0xB78C, 0xD1B8, 0xB78D, 0xD1B9, 0xB78E, 0xD1BB, + 0xB78F, 0xD1BD, 0xB790, 0xD1BE, 0xB791, 0xD1BF, 0xB792, 0xD1C1, + 0xB793, 0xD1C2, 0xB794, 0xD1C3, 0xB795, 0xD1C4, 0xB796, 0xD1C5, + 0xB797, 0xD1C6, 0xB798, 0xD1C7, 0xB799, 0xD1C8, 0xB79A, 0xD1C9, + 0xB79B, 0xD1CA, 0xB79C, 0xD1CB, 0xB79D, 0xD1CC, 0xB79E, 0xD1CD, + 0xB79F, 0xD1CE, 0xB7A0, 0xD1CF, 0xB7A1, 0xB798, 0xB7A2, 0xB799, + 0xB7A3, 0xB79C, 0xB7A4, 0xB7A0, 0xB7A5, 0xB7A8, 0xB7A6, 0xB7A9, + 0xB7A7, 0xB7AB, 0xB7A8, 0xB7AC, 0xB7A9, 0xB7AD, 0xB7AA, 0xB7B4, + 0xB7AB, 0xB7B5, 0xB7AC, 0xB7B8, 0xB7AD, 0xB7C7, 0xB7AE, 0xB7C9, + 0xB7AF, 0xB7EC, 0xB7B0, 0xB7ED, 0xB7B1, 0xB7F0, 0xB7B2, 0xB7F4, + 0xB7B3, 0xB7FC, 0xB7B4, 0xB7FD, 0xB7B5, 0xB7FF, 0xB7B6, 0xB800, + 0xB7B7, 0xB801, 0xB7B8, 0xB807, 0xB7B9, 0xB808, 0xB7BA, 0xB809, + 0xB7BB, 0xB80C, 0xB7BC, 0xB810, 0xB7BD, 0xB818, 0xB7BE, 0xB819, + 0xB7BF, 0xB81B, 0xB7C0, 0xB81D, 0xB7C1, 0xB824, 0xB7C2, 0xB825, + 0xB7C3, 0xB828, 0xB7C4, 0xB82C, 0xB7C5, 0xB834, 0xB7C6, 0xB835, + 0xB7C7, 0xB837, 0xB7C8, 0xB838, 0xB7C9, 0xB839, 0xB7CA, 0xB840, + 0xB7CB, 0xB844, 0xB7CC, 0xB851, 0xB7CD, 0xB853, 0xB7CE, 0xB85C, + 0xB7CF, 0xB85D, 0xB7D0, 0xB860, 0xB7D1, 0xB864, 0xB7D2, 0xB86C, + 0xB7D3, 0xB86D, 0xB7D4, 0xB86F, 0xB7D5, 0xB871, 0xB7D6, 0xB878, + 0xB7D7, 0xB87C, 0xB7D8, 0xB88D, 0xB7D9, 0xB8A8, 0xB7DA, 0xB8B0, + 0xB7DB, 0xB8B4, 0xB7DC, 0xB8B8, 0xB7DD, 0xB8C0, 0xB7DE, 0xB8C1, + 0xB7DF, 0xB8C3, 0xB7E0, 0xB8C5, 0xB7E1, 0xB8CC, 0xB7E2, 0xB8D0, + 0xB7E3, 0xB8D4, 0xB7E4, 0xB8DD, 0xB7E5, 0xB8DF, 0xB7E6, 0xB8E1, + 0xB7E7, 0xB8E8, 0xB7E8, 0xB8E9, 0xB7E9, 0xB8EC, 0xB7EA, 0xB8F0, + 0xB7EB, 0xB8F8, 0xB7EC, 0xB8F9, 0xB7ED, 0xB8FB, 0xB7EE, 0xB8FD, + 0xB7EF, 0xB904, 0xB7F0, 0xB918, 0xB7F1, 0xB920, 0xB7F2, 0xB93C, + 0xB7F3, 0xB93D, 0xB7F4, 0xB940, 0xB7F5, 0xB944, 0xB7F6, 0xB94C, + 0xB7F7, 0xB94F, 0xB7F8, 0xB951, 0xB7F9, 0xB958, 0xB7FA, 0xB959, + 0xB7FB, 0xB95C, 0xB7FC, 0xB960, 0xB7FD, 0xB968, 0xB7FE, 0xB969, + 0xB841, 0xD1D0, 0xB842, 0xD1D1, 0xB843, 0xD1D2, 0xB844, 0xD1D3, + 0xB845, 0xD1D4, 0xB846, 0xD1D5, 0xB847, 0xD1D6, 0xB848, 0xD1D7, + 0xB849, 0xD1D9, 0xB84A, 0xD1DA, 0xB84B, 0xD1DB, 0xB84C, 0xD1DC, + 0xB84D, 0xD1DD, 0xB84E, 0xD1DE, 0xB84F, 0xD1DF, 0xB850, 0xD1E0, + 0xB851, 0xD1E1, 0xB852, 0xD1E2, 0xB853, 0xD1E3, 0xB854, 0xD1E4, + 0xB855, 0xD1E5, 0xB856, 0xD1E6, 0xB857, 0xD1E7, 0xB858, 0xD1E8, + 0xB859, 0xD1E9, 0xB85A, 0xD1EA, 0xB861, 0xD1EB, 0xB862, 0xD1EC, + 0xB863, 0xD1ED, 0xB864, 0xD1EE, 0xB865, 0xD1EF, 0xB866, 0xD1F0, + 0xB867, 0xD1F1, 0xB868, 0xD1F2, 0xB869, 0xD1F3, 0xB86A, 0xD1F5, + 0xB86B, 0xD1F6, 0xB86C, 0xD1F7, 0xB86D, 0xD1F9, 0xB86E, 0xD1FA, + 0xB86F, 0xD1FB, 0xB870, 0xD1FC, 0xB871, 0xD1FD, 0xB872, 0xD1FE, + 0xB873, 0xD1FF, 0xB874, 0xD200, 0xB875, 0xD201, 0xB876, 0xD202, + 0xB877, 0xD203, 0xB878, 0xD204, 0xB879, 0xD205, 0xB87A, 0xD206, + 0xB881, 0xD208, 0xB882, 0xD20A, 0xB883, 0xD20B, 0xB884, 0xD20C, + 0xB885, 0xD20D, 0xB886, 0xD20E, 0xB887, 0xD20F, 0xB888, 0xD211, + 0xB889, 0xD212, 0xB88A, 0xD213, 0xB88B, 0xD214, 0xB88C, 0xD215, + 0xB88D, 0xD216, 0xB88E, 0xD217, 0xB88F, 0xD218, 0xB890, 0xD219, + 0xB891, 0xD21A, 0xB892, 0xD21B, 0xB893, 0xD21C, 0xB894, 0xD21D, + 0xB895, 0xD21E, 0xB896, 0xD21F, 0xB897, 0xD220, 0xB898, 0xD221, + 0xB899, 0xD222, 0xB89A, 0xD223, 0xB89B, 0xD224, 0xB89C, 0xD225, + 0xB89D, 0xD226, 0xB89E, 0xD227, 0xB89F, 0xD228, 0xB8A0, 0xD229, + 0xB8A1, 0xB96B, 0xB8A2, 0xB96D, 0xB8A3, 0xB974, 0xB8A4, 0xB975, + 0xB8A5, 0xB978, 0xB8A6, 0xB97C, 0xB8A7, 0xB984, 0xB8A8, 0xB985, + 0xB8A9, 0xB987, 0xB8AA, 0xB989, 0xB8AB, 0xB98A, 0xB8AC, 0xB98D, + 0xB8AD, 0xB98E, 0xB8AE, 0xB9AC, 0xB8AF, 0xB9AD, 0xB8B0, 0xB9B0, + 0xB8B1, 0xB9B4, 0xB8B2, 0xB9BC, 0xB8B3, 0xB9BD, 0xB8B4, 0xB9BF, + 0xB8B5, 0xB9C1, 0xB8B6, 0xB9C8, 0xB8B7, 0xB9C9, 0xB8B8, 0xB9CC, + 0xB8B9, 0xB9CE, 0xB8BA, 0xB9CF, 0xB8BB, 0xB9D0, 0xB8BC, 0xB9D1, + 0xB8BD, 0xB9D2, 0xB8BE, 0xB9D8, 0xB8BF, 0xB9D9, 0xB8C0, 0xB9DB, + 0xB8C1, 0xB9DD, 0xB8C2, 0xB9DE, 0xB8C3, 0xB9E1, 0xB8C4, 0xB9E3, + 0xB8C5, 0xB9E4, 0xB8C6, 0xB9E5, 0xB8C7, 0xB9E8, 0xB8C8, 0xB9EC, + 0xB8C9, 0xB9F4, 0xB8CA, 0xB9F5, 0xB8CB, 0xB9F7, 0xB8CC, 0xB9F8, + 0xB8CD, 0xB9F9, 0xB8CE, 0xB9FA, 0xB8CF, 0xBA00, 0xB8D0, 0xBA01, + 0xB8D1, 0xBA08, 0xB8D2, 0xBA15, 0xB8D3, 0xBA38, 0xB8D4, 0xBA39, + 0xB8D5, 0xBA3C, 0xB8D6, 0xBA40, 0xB8D7, 0xBA42, 0xB8D8, 0xBA48, + 0xB8D9, 0xBA49, 0xB8DA, 0xBA4B, 0xB8DB, 0xBA4D, 0xB8DC, 0xBA4E, + 0xB8DD, 0xBA53, 0xB8DE, 0xBA54, 0xB8DF, 0xBA55, 0xB8E0, 0xBA58, + 0xB8E1, 0xBA5C, 0xB8E2, 0xBA64, 0xB8E3, 0xBA65, 0xB8E4, 0xBA67, + 0xB8E5, 0xBA68, 0xB8E6, 0xBA69, 0xB8E7, 0xBA70, 0xB8E8, 0xBA71, + 0xB8E9, 0xBA74, 0xB8EA, 0xBA78, 0xB8EB, 0xBA83, 0xB8EC, 0xBA84, + 0xB8ED, 0xBA85, 0xB8EE, 0xBA87, 0xB8EF, 0xBA8C, 0xB8F0, 0xBAA8, + 0xB8F1, 0xBAA9, 0xB8F2, 0xBAAB, 0xB8F3, 0xBAAC, 0xB8F4, 0xBAB0, + 0xB8F5, 0xBAB2, 0xB8F6, 0xBAB8, 0xB8F7, 0xBAB9, 0xB8F8, 0xBABB, + 0xB8F9, 0xBABD, 0xB8FA, 0xBAC4, 0xB8FB, 0xBAC8, 0xB8FC, 0xBAD8, + 0xB8FD, 0xBAD9, 0xB8FE, 0xBAFC, 0xB941, 0xD22A, 0xB942, 0xD22B, + 0xB943, 0xD22E, 0xB944, 0xD22F, 0xB945, 0xD231, 0xB946, 0xD232, + 0xB947, 0xD233, 0xB948, 0xD235, 0xB949, 0xD236, 0xB94A, 0xD237, + 0xB94B, 0xD238, 0xB94C, 0xD239, 0xB94D, 0xD23A, 0xB94E, 0xD23B, + 0xB94F, 0xD23E, 0xB950, 0xD240, 0xB951, 0xD242, 0xB952, 0xD243, + 0xB953, 0xD244, 0xB954, 0xD245, 0xB955, 0xD246, 0xB956, 0xD247, + 0xB957, 0xD249, 0xB958, 0xD24A, 0xB959, 0xD24B, 0xB95A, 0xD24C, + 0xB961, 0xD24D, 0xB962, 0xD24E, 0xB963, 0xD24F, 0xB964, 0xD250, + 0xB965, 0xD251, 0xB966, 0xD252, 0xB967, 0xD253, 0xB968, 0xD254, + 0xB969, 0xD255, 0xB96A, 0xD256, 0xB96B, 0xD257, 0xB96C, 0xD258, + 0xB96D, 0xD259, 0xB96E, 0xD25A, 0xB96F, 0xD25B, 0xB970, 0xD25D, + 0xB971, 0xD25E, 0xB972, 0xD25F, 0xB973, 0xD260, 0xB974, 0xD261, + 0xB975, 0xD262, 0xB976, 0xD263, 0xB977, 0xD265, 0xB978, 0xD266, + 0xB979, 0xD267, 0xB97A, 0xD268, 0xB981, 0xD269, 0xB982, 0xD26A, + 0xB983, 0xD26B, 0xB984, 0xD26C, 0xB985, 0xD26D, 0xB986, 0xD26E, + 0xB987, 0xD26F, 0xB988, 0xD270, 0xB989, 0xD271, 0xB98A, 0xD272, + 0xB98B, 0xD273, 0xB98C, 0xD274, 0xB98D, 0xD275, 0xB98E, 0xD276, + 0xB98F, 0xD277, 0xB990, 0xD278, 0xB991, 0xD279, 0xB992, 0xD27A, + 0xB993, 0xD27B, 0xB994, 0xD27C, 0xB995, 0xD27D, 0xB996, 0xD27E, + 0xB997, 0xD27F, 0xB998, 0xD282, 0xB999, 0xD283, 0xB99A, 0xD285, + 0xB99B, 0xD286, 0xB99C, 0xD287, 0xB99D, 0xD289, 0xB99E, 0xD28A, + 0xB99F, 0xD28B, 0xB9A0, 0xD28C, 0xB9A1, 0xBB00, 0xB9A2, 0xBB04, + 0xB9A3, 0xBB0D, 0xB9A4, 0xBB0F, 0xB9A5, 0xBB11, 0xB9A6, 0xBB18, + 0xB9A7, 0xBB1C, 0xB9A8, 0xBB20, 0xB9A9, 0xBB29, 0xB9AA, 0xBB2B, + 0xB9AB, 0xBB34, 0xB9AC, 0xBB35, 0xB9AD, 0xBB36, 0xB9AE, 0xBB38, + 0xB9AF, 0xBB3B, 0xB9B0, 0xBB3C, 0xB9B1, 0xBB3D, 0xB9B2, 0xBB3E, + 0xB9B3, 0xBB44, 0xB9B4, 0xBB45, 0xB9B5, 0xBB47, 0xB9B6, 0xBB49, + 0xB9B7, 0xBB4D, 0xB9B8, 0xBB4F, 0xB9B9, 0xBB50, 0xB9BA, 0xBB54, + 0xB9BB, 0xBB58, 0xB9BC, 0xBB61, 0xB9BD, 0xBB63, 0xB9BE, 0xBB6C, + 0xB9BF, 0xBB88, 0xB9C0, 0xBB8C, 0xB9C1, 0xBB90, 0xB9C2, 0xBBA4, + 0xB9C3, 0xBBA8, 0xB9C4, 0xBBAC, 0xB9C5, 0xBBB4, 0xB9C6, 0xBBB7, + 0xB9C7, 0xBBC0, 0xB9C8, 0xBBC4, 0xB9C9, 0xBBC8, 0xB9CA, 0xBBD0, + 0xB9CB, 0xBBD3, 0xB9CC, 0xBBF8, 0xB9CD, 0xBBF9, 0xB9CE, 0xBBFC, + 0xB9CF, 0xBBFF, 0xB9D0, 0xBC00, 0xB9D1, 0xBC02, 0xB9D2, 0xBC08, + 0xB9D3, 0xBC09, 0xB9D4, 0xBC0B, 0xB9D5, 0xBC0C, 0xB9D6, 0xBC0D, + 0xB9D7, 0xBC0F, 0xB9D8, 0xBC11, 0xB9D9, 0xBC14, 0xB9DA, 0xBC15, + 0xB9DB, 0xBC16, 0xB9DC, 0xBC17, 0xB9DD, 0xBC18, 0xB9DE, 0xBC1B, + 0xB9DF, 0xBC1C, 0xB9E0, 0xBC1D, 0xB9E1, 0xBC1E, 0xB9E2, 0xBC1F, + 0xB9E3, 0xBC24, 0xB9E4, 0xBC25, 0xB9E5, 0xBC27, 0xB9E6, 0xBC29, + 0xB9E7, 0xBC2D, 0xB9E8, 0xBC30, 0xB9E9, 0xBC31, 0xB9EA, 0xBC34, + 0xB9EB, 0xBC38, 0xB9EC, 0xBC40, 0xB9ED, 0xBC41, 0xB9EE, 0xBC43, + 0xB9EF, 0xBC44, 0xB9F0, 0xBC45, 0xB9F1, 0xBC49, 0xB9F2, 0xBC4C, + 0xB9F3, 0xBC4D, 0xB9F4, 0xBC50, 0xB9F5, 0xBC5D, 0xB9F6, 0xBC84, + 0xB9F7, 0xBC85, 0xB9F8, 0xBC88, 0xB9F9, 0xBC8B, 0xB9FA, 0xBC8C, + 0xB9FB, 0xBC8E, 0xB9FC, 0xBC94, 0xB9FD, 0xBC95, 0xB9FE, 0xBC97, + 0xBA41, 0xD28D, 0xBA42, 0xD28E, 0xBA43, 0xD28F, 0xBA44, 0xD292, + 0xBA45, 0xD293, 0xBA46, 0xD294, 0xBA47, 0xD296, 0xBA48, 0xD297, + 0xBA49, 0xD298, 0xBA4A, 0xD299, 0xBA4B, 0xD29A, 0xBA4C, 0xD29B, + 0xBA4D, 0xD29D, 0xBA4E, 0xD29E, 0xBA4F, 0xD29F, 0xBA50, 0xD2A1, + 0xBA51, 0xD2A2, 0xBA52, 0xD2A3, 0xBA53, 0xD2A5, 0xBA54, 0xD2A6, + 0xBA55, 0xD2A7, 0xBA56, 0xD2A8, 0xBA57, 0xD2A9, 0xBA58, 0xD2AA, + 0xBA59, 0xD2AB, 0xBA5A, 0xD2AD, 0xBA61, 0xD2AE, 0xBA62, 0xD2AF, + 0xBA63, 0xD2B0, 0xBA64, 0xD2B2, 0xBA65, 0xD2B3, 0xBA66, 0xD2B4, + 0xBA67, 0xD2B5, 0xBA68, 0xD2B6, 0xBA69, 0xD2B7, 0xBA6A, 0xD2BA, + 0xBA6B, 0xD2BB, 0xBA6C, 0xD2BD, 0xBA6D, 0xD2BE, 0xBA6E, 0xD2C1, + 0xBA6F, 0xD2C3, 0xBA70, 0xD2C4, 0xBA71, 0xD2C5, 0xBA72, 0xD2C6, + 0xBA73, 0xD2C7, 0xBA74, 0xD2CA, 0xBA75, 0xD2CC, 0xBA76, 0xD2CD, + 0xBA77, 0xD2CE, 0xBA78, 0xD2CF, 0xBA79, 0xD2D0, 0xBA7A, 0xD2D1, + 0xBA81, 0xD2D2, 0xBA82, 0xD2D3, 0xBA83, 0xD2D5, 0xBA84, 0xD2D6, + 0xBA85, 0xD2D7, 0xBA86, 0xD2D9, 0xBA87, 0xD2DA, 0xBA88, 0xD2DB, + 0xBA89, 0xD2DD, 0xBA8A, 0xD2DE, 0xBA8B, 0xD2DF, 0xBA8C, 0xD2E0, + 0xBA8D, 0xD2E1, 0xBA8E, 0xD2E2, 0xBA8F, 0xD2E3, 0xBA90, 0xD2E6, + 0xBA91, 0xD2E7, 0xBA92, 0xD2E8, 0xBA93, 0xD2E9, 0xBA94, 0xD2EA, + 0xBA95, 0xD2EB, 0xBA96, 0xD2EC, 0xBA97, 0xD2ED, 0xBA98, 0xD2EE, + 0xBA99, 0xD2EF, 0xBA9A, 0xD2F2, 0xBA9B, 0xD2F3, 0xBA9C, 0xD2F5, + 0xBA9D, 0xD2F6, 0xBA9E, 0xD2F7, 0xBA9F, 0xD2F9, 0xBAA0, 0xD2FA, + 0xBAA1, 0xBC99, 0xBAA2, 0xBC9A, 0xBAA3, 0xBCA0, 0xBAA4, 0xBCA1, + 0xBAA5, 0xBCA4, 0xBAA6, 0xBCA7, 0xBAA7, 0xBCA8, 0xBAA8, 0xBCB0, + 0xBAA9, 0xBCB1, 0xBAAA, 0xBCB3, 0xBAAB, 0xBCB4, 0xBAAC, 0xBCB5, + 0xBAAD, 0xBCBC, 0xBAAE, 0xBCBD, 0xBAAF, 0xBCC0, 0xBAB0, 0xBCC4, + 0xBAB1, 0xBCCD, 0xBAB2, 0xBCCF, 0xBAB3, 0xBCD0, 0xBAB4, 0xBCD1, + 0xBAB5, 0xBCD5, 0xBAB6, 0xBCD8, 0xBAB7, 0xBCDC, 0xBAB8, 0xBCF4, + 0xBAB9, 0xBCF5, 0xBABA, 0xBCF6, 0xBABB, 0xBCF8, 0xBABC, 0xBCFC, + 0xBABD, 0xBD04, 0xBABE, 0xBD05, 0xBABF, 0xBD07, 0xBAC0, 0xBD09, + 0xBAC1, 0xBD10, 0xBAC2, 0xBD14, 0xBAC3, 0xBD24, 0xBAC4, 0xBD2C, + 0xBAC5, 0xBD40, 0xBAC6, 0xBD48, 0xBAC7, 0xBD49, 0xBAC8, 0xBD4C, + 0xBAC9, 0xBD50, 0xBACA, 0xBD58, 0xBACB, 0xBD59, 0xBACC, 0xBD64, + 0xBACD, 0xBD68, 0xBACE, 0xBD80, 0xBACF, 0xBD81, 0xBAD0, 0xBD84, + 0xBAD1, 0xBD87, 0xBAD2, 0xBD88, 0xBAD3, 0xBD89, 0xBAD4, 0xBD8A, + 0xBAD5, 0xBD90, 0xBAD6, 0xBD91, 0xBAD7, 0xBD93, 0xBAD8, 0xBD95, + 0xBAD9, 0xBD99, 0xBADA, 0xBD9A, 0xBADB, 0xBD9C, 0xBADC, 0xBDA4, + 0xBADD, 0xBDB0, 0xBADE, 0xBDB8, 0xBADF, 0xBDD4, 0xBAE0, 0xBDD5, + 0xBAE1, 0xBDD8, 0xBAE2, 0xBDDC, 0xBAE3, 0xBDE9, 0xBAE4, 0xBDF0, + 0xBAE5, 0xBDF4, 0xBAE6, 0xBDF8, 0xBAE7, 0xBE00, 0xBAE8, 0xBE03, + 0xBAE9, 0xBE05, 0xBAEA, 0xBE0C, 0xBAEB, 0xBE0D, 0xBAEC, 0xBE10, + 0xBAED, 0xBE14, 0xBAEE, 0xBE1C, 0xBAEF, 0xBE1D, 0xBAF0, 0xBE1F, + 0xBAF1, 0xBE44, 0xBAF2, 0xBE45, 0xBAF3, 0xBE48, 0xBAF4, 0xBE4C, + 0xBAF5, 0xBE4E, 0xBAF6, 0xBE54, 0xBAF7, 0xBE55, 0xBAF8, 0xBE57, + 0xBAF9, 0xBE59, 0xBAFA, 0xBE5A, 0xBAFB, 0xBE5B, 0xBAFC, 0xBE60, + 0xBAFD, 0xBE61, 0xBAFE, 0xBE64, 0xBB41, 0xD2FB, 0xBB42, 0xD2FC, + 0xBB43, 0xD2FD, 0xBB44, 0xD2FE, 0xBB45, 0xD2FF, 0xBB46, 0xD302, + 0xBB47, 0xD304, 0xBB48, 0xD306, 0xBB49, 0xD307, 0xBB4A, 0xD308, + 0xBB4B, 0xD309, 0xBB4C, 0xD30A, 0xBB4D, 0xD30B, 0xBB4E, 0xD30F, + 0xBB4F, 0xD311, 0xBB50, 0xD312, 0xBB51, 0xD313, 0xBB52, 0xD315, + 0xBB53, 0xD317, 0xBB54, 0xD318, 0xBB55, 0xD319, 0xBB56, 0xD31A, + 0xBB57, 0xD31B, 0xBB58, 0xD31E, 0xBB59, 0xD322, 0xBB5A, 0xD323, + 0xBB61, 0xD324, 0xBB62, 0xD326, 0xBB63, 0xD327, 0xBB64, 0xD32A, + 0xBB65, 0xD32B, 0xBB66, 0xD32D, 0xBB67, 0xD32E, 0xBB68, 0xD32F, + 0xBB69, 0xD331, 0xBB6A, 0xD332, 0xBB6B, 0xD333, 0xBB6C, 0xD334, + 0xBB6D, 0xD335, 0xBB6E, 0xD336, 0xBB6F, 0xD337, 0xBB70, 0xD33A, + 0xBB71, 0xD33E, 0xBB72, 0xD33F, 0xBB73, 0xD340, 0xBB74, 0xD341, + 0xBB75, 0xD342, 0xBB76, 0xD343, 0xBB77, 0xD346, 0xBB78, 0xD347, + 0xBB79, 0xD348, 0xBB7A, 0xD349, 0xBB81, 0xD34A, 0xBB82, 0xD34B, + 0xBB83, 0xD34C, 0xBB84, 0xD34D, 0xBB85, 0xD34E, 0xBB86, 0xD34F, + 0xBB87, 0xD350, 0xBB88, 0xD351, 0xBB89, 0xD352, 0xBB8A, 0xD353, + 0xBB8B, 0xD354, 0xBB8C, 0xD355, 0xBB8D, 0xD356, 0xBB8E, 0xD357, + 0xBB8F, 0xD358, 0xBB90, 0xD359, 0xBB91, 0xD35A, 0xBB92, 0xD35B, + 0xBB93, 0xD35C, 0xBB94, 0xD35D, 0xBB95, 0xD35E, 0xBB96, 0xD35F, + 0xBB97, 0xD360, 0xBB98, 0xD361, 0xBB99, 0xD362, 0xBB9A, 0xD363, + 0xBB9B, 0xD364, 0xBB9C, 0xD365, 0xBB9D, 0xD366, 0xBB9E, 0xD367, + 0xBB9F, 0xD368, 0xBBA0, 0xD369, 0xBBA1, 0xBE68, 0xBBA2, 0xBE6A, + 0xBBA3, 0xBE70, 0xBBA4, 0xBE71, 0xBBA5, 0xBE73, 0xBBA6, 0xBE74, + 0xBBA7, 0xBE75, 0xBBA8, 0xBE7B, 0xBBA9, 0xBE7C, 0xBBAA, 0xBE7D, + 0xBBAB, 0xBE80, 0xBBAC, 0xBE84, 0xBBAD, 0xBE8C, 0xBBAE, 0xBE8D, + 0xBBAF, 0xBE8F, 0xBBB0, 0xBE90, 0xBBB1, 0xBE91, 0xBBB2, 0xBE98, + 0xBBB3, 0xBE99, 0xBBB4, 0xBEA8, 0xBBB5, 0xBED0, 0xBBB6, 0xBED1, + 0xBBB7, 0xBED4, 0xBBB8, 0xBED7, 0xBBB9, 0xBED8, 0xBBBA, 0xBEE0, + 0xBBBB, 0xBEE3, 0xBBBC, 0xBEE4, 0xBBBD, 0xBEE5, 0xBBBE, 0xBEEC, + 0xBBBF, 0xBF01, 0xBBC0, 0xBF08, 0xBBC1, 0xBF09, 0xBBC2, 0xBF18, + 0xBBC3, 0xBF19, 0xBBC4, 0xBF1B, 0xBBC5, 0xBF1C, 0xBBC6, 0xBF1D, + 0xBBC7, 0xBF40, 0xBBC8, 0xBF41, 0xBBC9, 0xBF44, 0xBBCA, 0xBF48, + 0xBBCB, 0xBF50, 0xBBCC, 0xBF51, 0xBBCD, 0xBF55, 0xBBCE, 0xBF94, + 0xBBCF, 0xBFB0, 0xBBD0, 0xBFC5, 0xBBD1, 0xBFCC, 0xBBD2, 0xBFCD, + 0xBBD3, 0xBFD0, 0xBBD4, 0xBFD4, 0xBBD5, 0xBFDC, 0xBBD6, 0xBFDF, + 0xBBD7, 0xBFE1, 0xBBD8, 0xC03C, 0xBBD9, 0xC051, 0xBBDA, 0xC058, + 0xBBDB, 0xC05C, 0xBBDC, 0xC060, 0xBBDD, 0xC068, 0xBBDE, 0xC069, + 0xBBDF, 0xC090, 0xBBE0, 0xC091, 0xBBE1, 0xC094, 0xBBE2, 0xC098, + 0xBBE3, 0xC0A0, 0xBBE4, 0xC0A1, 0xBBE5, 0xC0A3, 0xBBE6, 0xC0A5, + 0xBBE7, 0xC0AC, 0xBBE8, 0xC0AD, 0xBBE9, 0xC0AF, 0xBBEA, 0xC0B0, + 0xBBEB, 0xC0B3, 0xBBEC, 0xC0B4, 0xBBED, 0xC0B5, 0xBBEE, 0xC0B6, + 0xBBEF, 0xC0BC, 0xBBF0, 0xC0BD, 0xBBF1, 0xC0BF, 0xBBF2, 0xC0C0, + 0xBBF3, 0xC0C1, 0xBBF4, 0xC0C5, 0xBBF5, 0xC0C8, 0xBBF6, 0xC0C9, + 0xBBF7, 0xC0CC, 0xBBF8, 0xC0D0, 0xBBF9, 0xC0D8, 0xBBFA, 0xC0D9, + 0xBBFB, 0xC0DB, 0xBBFC, 0xC0DC, 0xBBFD, 0xC0DD, 0xBBFE, 0xC0E4, + 0xBC41, 0xD36A, 0xBC42, 0xD36B, 0xBC43, 0xD36C, 0xBC44, 0xD36D, + 0xBC45, 0xD36E, 0xBC46, 0xD36F, 0xBC47, 0xD370, 0xBC48, 0xD371, + 0xBC49, 0xD372, 0xBC4A, 0xD373, 0xBC4B, 0xD374, 0xBC4C, 0xD375, + 0xBC4D, 0xD376, 0xBC4E, 0xD377, 0xBC4F, 0xD378, 0xBC50, 0xD379, + 0xBC51, 0xD37A, 0xBC52, 0xD37B, 0xBC53, 0xD37E, 0xBC54, 0xD37F, + 0xBC55, 0xD381, 0xBC56, 0xD382, 0xBC57, 0xD383, 0xBC58, 0xD385, + 0xBC59, 0xD386, 0xBC5A, 0xD387, 0xBC61, 0xD388, 0xBC62, 0xD389, + 0xBC63, 0xD38A, 0xBC64, 0xD38B, 0xBC65, 0xD38E, 0xBC66, 0xD392, + 0xBC67, 0xD393, 0xBC68, 0xD394, 0xBC69, 0xD395, 0xBC6A, 0xD396, + 0xBC6B, 0xD397, 0xBC6C, 0xD39A, 0xBC6D, 0xD39B, 0xBC6E, 0xD39D, + 0xBC6F, 0xD39E, 0xBC70, 0xD39F, 0xBC71, 0xD3A1, 0xBC72, 0xD3A2, + 0xBC73, 0xD3A3, 0xBC74, 0xD3A4, 0xBC75, 0xD3A5, 0xBC76, 0xD3A6, + 0xBC77, 0xD3A7, 0xBC78, 0xD3AA, 0xBC79, 0xD3AC, 0xBC7A, 0xD3AE, + 0xBC81, 0xD3AF, 0xBC82, 0xD3B0, 0xBC83, 0xD3B1, 0xBC84, 0xD3B2, + 0xBC85, 0xD3B3, 0xBC86, 0xD3B5, 0xBC87, 0xD3B6, 0xBC88, 0xD3B7, + 0xBC89, 0xD3B9, 0xBC8A, 0xD3BA, 0xBC8B, 0xD3BB, 0xBC8C, 0xD3BD, + 0xBC8D, 0xD3BE, 0xBC8E, 0xD3BF, 0xBC8F, 0xD3C0, 0xBC90, 0xD3C1, + 0xBC91, 0xD3C2, 0xBC92, 0xD3C3, 0xBC93, 0xD3C6, 0xBC94, 0xD3C7, + 0xBC95, 0xD3CA, 0xBC96, 0xD3CB, 0xBC97, 0xD3CC, 0xBC98, 0xD3CD, + 0xBC99, 0xD3CE, 0xBC9A, 0xD3CF, 0xBC9B, 0xD3D1, 0xBC9C, 0xD3D2, + 0xBC9D, 0xD3D3, 0xBC9E, 0xD3D4, 0xBC9F, 0xD3D5, 0xBCA0, 0xD3D6, + 0xBCA1, 0xC0E5, 0xBCA2, 0xC0E8, 0xBCA3, 0xC0EC, 0xBCA4, 0xC0F4, + 0xBCA5, 0xC0F5, 0xBCA6, 0xC0F7, 0xBCA7, 0xC0F9, 0xBCA8, 0xC100, + 0xBCA9, 0xC104, 0xBCAA, 0xC108, 0xBCAB, 0xC110, 0xBCAC, 0xC115, + 0xBCAD, 0xC11C, 0xBCAE, 0xC11D, 0xBCAF, 0xC11E, 0xBCB0, 0xC11F, + 0xBCB1, 0xC120, 0xBCB2, 0xC123, 0xBCB3, 0xC124, 0xBCB4, 0xC126, + 0xBCB5, 0xC127, 0xBCB6, 0xC12C, 0xBCB7, 0xC12D, 0xBCB8, 0xC12F, + 0xBCB9, 0xC130, 0xBCBA, 0xC131, 0xBCBB, 0xC136, 0xBCBC, 0xC138, + 0xBCBD, 0xC139, 0xBCBE, 0xC13C, 0xBCBF, 0xC140, 0xBCC0, 0xC148, + 0xBCC1, 0xC149, 0xBCC2, 0xC14B, 0xBCC3, 0xC14C, 0xBCC4, 0xC14D, + 0xBCC5, 0xC154, 0xBCC6, 0xC155, 0xBCC7, 0xC158, 0xBCC8, 0xC15C, + 0xBCC9, 0xC164, 0xBCCA, 0xC165, 0xBCCB, 0xC167, 0xBCCC, 0xC168, + 0xBCCD, 0xC169, 0xBCCE, 0xC170, 0xBCCF, 0xC174, 0xBCD0, 0xC178, + 0xBCD1, 0xC185, 0xBCD2, 0xC18C, 0xBCD3, 0xC18D, 0xBCD4, 0xC18E, + 0xBCD5, 0xC190, 0xBCD6, 0xC194, 0xBCD7, 0xC196, 0xBCD8, 0xC19C, + 0xBCD9, 0xC19D, 0xBCDA, 0xC19F, 0xBCDB, 0xC1A1, 0xBCDC, 0xC1A5, + 0xBCDD, 0xC1A8, 0xBCDE, 0xC1A9, 0xBCDF, 0xC1AC, 0xBCE0, 0xC1B0, + 0xBCE1, 0xC1BD, 0xBCE2, 0xC1C4, 0xBCE3, 0xC1C8, 0xBCE4, 0xC1CC, + 0xBCE5, 0xC1D4, 0xBCE6, 0xC1D7, 0xBCE7, 0xC1D8, 0xBCE8, 0xC1E0, + 0xBCE9, 0xC1E4, 0xBCEA, 0xC1E8, 0xBCEB, 0xC1F0, 0xBCEC, 0xC1F1, + 0xBCED, 0xC1F3, 0xBCEE, 0xC1FC, 0xBCEF, 0xC1FD, 0xBCF0, 0xC200, + 0xBCF1, 0xC204, 0xBCF2, 0xC20C, 0xBCF3, 0xC20D, 0xBCF4, 0xC20F, + 0xBCF5, 0xC211, 0xBCF6, 0xC218, 0xBCF7, 0xC219, 0xBCF8, 0xC21C, + 0xBCF9, 0xC21F, 0xBCFA, 0xC220, 0xBCFB, 0xC228, 0xBCFC, 0xC229, + 0xBCFD, 0xC22B, 0xBCFE, 0xC22D, 0xBD41, 0xD3D7, 0xBD42, 0xD3D9, + 0xBD43, 0xD3DA, 0xBD44, 0xD3DB, 0xBD45, 0xD3DC, 0xBD46, 0xD3DD, + 0xBD47, 0xD3DE, 0xBD48, 0xD3DF, 0xBD49, 0xD3E0, 0xBD4A, 0xD3E2, + 0xBD4B, 0xD3E4, 0xBD4C, 0xD3E5, 0xBD4D, 0xD3E6, 0xBD4E, 0xD3E7, + 0xBD4F, 0xD3E8, 0xBD50, 0xD3E9, 0xBD51, 0xD3EA, 0xBD52, 0xD3EB, + 0xBD53, 0xD3EE, 0xBD54, 0xD3EF, 0xBD55, 0xD3F1, 0xBD56, 0xD3F2, + 0xBD57, 0xD3F3, 0xBD58, 0xD3F5, 0xBD59, 0xD3F6, 0xBD5A, 0xD3F7, + 0xBD61, 0xD3F8, 0xBD62, 0xD3F9, 0xBD63, 0xD3FA, 0xBD64, 0xD3FB, + 0xBD65, 0xD3FE, 0xBD66, 0xD400, 0xBD67, 0xD402, 0xBD68, 0xD403, + 0xBD69, 0xD404, 0xBD6A, 0xD405, 0xBD6B, 0xD406, 0xBD6C, 0xD407, + 0xBD6D, 0xD409, 0xBD6E, 0xD40A, 0xBD6F, 0xD40B, 0xBD70, 0xD40C, + 0xBD71, 0xD40D, 0xBD72, 0xD40E, 0xBD73, 0xD40F, 0xBD74, 0xD410, + 0xBD75, 0xD411, 0xBD76, 0xD412, 0xBD77, 0xD413, 0xBD78, 0xD414, + 0xBD79, 0xD415, 0xBD7A, 0xD416, 0xBD81, 0xD417, 0xBD82, 0xD418, + 0xBD83, 0xD419, 0xBD84, 0xD41A, 0xBD85, 0xD41B, 0xBD86, 0xD41C, + 0xBD87, 0xD41E, 0xBD88, 0xD41F, 0xBD89, 0xD420, 0xBD8A, 0xD421, + 0xBD8B, 0xD422, 0xBD8C, 0xD423, 0xBD8D, 0xD424, 0xBD8E, 0xD425, + 0xBD8F, 0xD426, 0xBD90, 0xD427, 0xBD91, 0xD428, 0xBD92, 0xD429, + 0xBD93, 0xD42A, 0xBD94, 0xD42B, 0xBD95, 0xD42C, 0xBD96, 0xD42D, + 0xBD97, 0xD42E, 0xBD98, 0xD42F, 0xBD99, 0xD430, 0xBD9A, 0xD431, + 0xBD9B, 0xD432, 0xBD9C, 0xD433, 0xBD9D, 0xD434, 0xBD9E, 0xD435, + 0xBD9F, 0xD436, 0xBDA0, 0xD437, 0xBDA1, 0xC22F, 0xBDA2, 0xC231, + 0xBDA3, 0xC232, 0xBDA4, 0xC234, 0xBDA5, 0xC248, 0xBDA6, 0xC250, + 0xBDA7, 0xC251, 0xBDA8, 0xC254, 0xBDA9, 0xC258, 0xBDAA, 0xC260, + 0xBDAB, 0xC265, 0xBDAC, 0xC26C, 0xBDAD, 0xC26D, 0xBDAE, 0xC270, + 0xBDAF, 0xC274, 0xBDB0, 0xC27C, 0xBDB1, 0xC27D, 0xBDB2, 0xC27F, + 0xBDB3, 0xC281, 0xBDB4, 0xC288, 0xBDB5, 0xC289, 0xBDB6, 0xC290, + 0xBDB7, 0xC298, 0xBDB8, 0xC29B, 0xBDB9, 0xC29D, 0xBDBA, 0xC2A4, + 0xBDBB, 0xC2A5, 0xBDBC, 0xC2A8, 0xBDBD, 0xC2AC, 0xBDBE, 0xC2AD, + 0xBDBF, 0xC2B4, 0xBDC0, 0xC2B5, 0xBDC1, 0xC2B7, 0xBDC2, 0xC2B9, + 0xBDC3, 0xC2DC, 0xBDC4, 0xC2DD, 0xBDC5, 0xC2E0, 0xBDC6, 0xC2E3, + 0xBDC7, 0xC2E4, 0xBDC8, 0xC2EB, 0xBDC9, 0xC2EC, 0xBDCA, 0xC2ED, + 0xBDCB, 0xC2EF, 0xBDCC, 0xC2F1, 0xBDCD, 0xC2F6, 0xBDCE, 0xC2F8, + 0xBDCF, 0xC2F9, 0xBDD0, 0xC2FB, 0xBDD1, 0xC2FC, 0xBDD2, 0xC300, + 0xBDD3, 0xC308, 0xBDD4, 0xC309, 0xBDD5, 0xC30C, 0xBDD6, 0xC30D, + 0xBDD7, 0xC313, 0xBDD8, 0xC314, 0xBDD9, 0xC315, 0xBDDA, 0xC318, + 0xBDDB, 0xC31C, 0xBDDC, 0xC324, 0xBDDD, 0xC325, 0xBDDE, 0xC328, + 0xBDDF, 0xC329, 0xBDE0, 0xC345, 0xBDE1, 0xC368, 0xBDE2, 0xC369, + 0xBDE3, 0xC36C, 0xBDE4, 0xC370, 0xBDE5, 0xC372, 0xBDE6, 0xC378, + 0xBDE7, 0xC379, 0xBDE8, 0xC37C, 0xBDE9, 0xC37D, 0xBDEA, 0xC384, + 0xBDEB, 0xC388, 0xBDEC, 0xC38C, 0xBDED, 0xC3C0, 0xBDEE, 0xC3D8, + 0xBDEF, 0xC3D9, 0xBDF0, 0xC3DC, 0xBDF1, 0xC3DF, 0xBDF2, 0xC3E0, + 0xBDF3, 0xC3E2, 0xBDF4, 0xC3E8, 0xBDF5, 0xC3E9, 0xBDF6, 0xC3ED, + 0xBDF7, 0xC3F4, 0xBDF8, 0xC3F5, 0xBDF9, 0xC3F8, 0xBDFA, 0xC408, + 0xBDFB, 0xC410, 0xBDFC, 0xC424, 0xBDFD, 0xC42C, 0xBDFE, 0xC430, + 0xBE41, 0xD438, 0xBE42, 0xD439, 0xBE43, 0xD43A, 0xBE44, 0xD43B, + 0xBE45, 0xD43C, 0xBE46, 0xD43D, 0xBE47, 0xD43E, 0xBE48, 0xD43F, + 0xBE49, 0xD441, 0xBE4A, 0xD442, 0xBE4B, 0xD443, 0xBE4C, 0xD445, + 0xBE4D, 0xD446, 0xBE4E, 0xD447, 0xBE4F, 0xD448, 0xBE50, 0xD449, + 0xBE51, 0xD44A, 0xBE52, 0xD44B, 0xBE53, 0xD44C, 0xBE54, 0xD44D, + 0xBE55, 0xD44E, 0xBE56, 0xD44F, 0xBE57, 0xD450, 0xBE58, 0xD451, + 0xBE59, 0xD452, 0xBE5A, 0xD453, 0xBE61, 0xD454, 0xBE62, 0xD455, + 0xBE63, 0xD456, 0xBE64, 0xD457, 0xBE65, 0xD458, 0xBE66, 0xD459, + 0xBE67, 0xD45A, 0xBE68, 0xD45B, 0xBE69, 0xD45D, 0xBE6A, 0xD45E, + 0xBE6B, 0xD45F, 0xBE6C, 0xD461, 0xBE6D, 0xD462, 0xBE6E, 0xD463, + 0xBE6F, 0xD465, 0xBE70, 0xD466, 0xBE71, 0xD467, 0xBE72, 0xD468, + 0xBE73, 0xD469, 0xBE74, 0xD46A, 0xBE75, 0xD46B, 0xBE76, 0xD46C, + 0xBE77, 0xD46E, 0xBE78, 0xD470, 0xBE79, 0xD471, 0xBE7A, 0xD472, + 0xBE81, 0xD473, 0xBE82, 0xD474, 0xBE83, 0xD475, 0xBE84, 0xD476, + 0xBE85, 0xD477, 0xBE86, 0xD47A, 0xBE87, 0xD47B, 0xBE88, 0xD47D, + 0xBE89, 0xD47E, 0xBE8A, 0xD481, 0xBE8B, 0xD483, 0xBE8C, 0xD484, + 0xBE8D, 0xD485, 0xBE8E, 0xD486, 0xBE8F, 0xD487, 0xBE90, 0xD48A, + 0xBE91, 0xD48C, 0xBE92, 0xD48E, 0xBE93, 0xD48F, 0xBE94, 0xD490, + 0xBE95, 0xD491, 0xBE96, 0xD492, 0xBE97, 0xD493, 0xBE98, 0xD495, + 0xBE99, 0xD496, 0xBE9A, 0xD497, 0xBE9B, 0xD498, 0xBE9C, 0xD499, + 0xBE9D, 0xD49A, 0xBE9E, 0xD49B, 0xBE9F, 0xD49C, 0xBEA0, 0xD49D, + 0xBEA1, 0xC434, 0xBEA2, 0xC43C, 0xBEA3, 0xC43D, 0xBEA4, 0xC448, + 0xBEA5, 0xC464, 0xBEA6, 0xC465, 0xBEA7, 0xC468, 0xBEA8, 0xC46C, + 0xBEA9, 0xC474, 0xBEAA, 0xC475, 0xBEAB, 0xC479, 0xBEAC, 0xC480, + 0xBEAD, 0xC494, 0xBEAE, 0xC49C, 0xBEAF, 0xC4B8, 0xBEB0, 0xC4BC, + 0xBEB1, 0xC4E9, 0xBEB2, 0xC4F0, 0xBEB3, 0xC4F1, 0xBEB4, 0xC4F4, + 0xBEB5, 0xC4F8, 0xBEB6, 0xC4FA, 0xBEB7, 0xC4FF, 0xBEB8, 0xC500, + 0xBEB9, 0xC501, 0xBEBA, 0xC50C, 0xBEBB, 0xC510, 0xBEBC, 0xC514, + 0xBEBD, 0xC51C, 0xBEBE, 0xC528, 0xBEBF, 0xC529, 0xBEC0, 0xC52C, + 0xBEC1, 0xC530, 0xBEC2, 0xC538, 0xBEC3, 0xC539, 0xBEC4, 0xC53B, + 0xBEC5, 0xC53D, 0xBEC6, 0xC544, 0xBEC7, 0xC545, 0xBEC8, 0xC548, + 0xBEC9, 0xC549, 0xBECA, 0xC54A, 0xBECB, 0xC54C, 0xBECC, 0xC54D, + 0xBECD, 0xC54E, 0xBECE, 0xC553, 0xBECF, 0xC554, 0xBED0, 0xC555, + 0xBED1, 0xC557, 0xBED2, 0xC558, 0xBED3, 0xC559, 0xBED4, 0xC55D, + 0xBED5, 0xC55E, 0xBED6, 0xC560, 0xBED7, 0xC561, 0xBED8, 0xC564, + 0xBED9, 0xC568, 0xBEDA, 0xC570, 0xBEDB, 0xC571, 0xBEDC, 0xC573, + 0xBEDD, 0xC574, 0xBEDE, 0xC575, 0xBEDF, 0xC57C, 0xBEE0, 0xC57D, + 0xBEE1, 0xC580, 0xBEE2, 0xC584, 0xBEE3, 0xC587, 0xBEE4, 0xC58C, + 0xBEE5, 0xC58D, 0xBEE6, 0xC58F, 0xBEE7, 0xC591, 0xBEE8, 0xC595, + 0xBEE9, 0xC597, 0xBEEA, 0xC598, 0xBEEB, 0xC59C, 0xBEEC, 0xC5A0, + 0xBEED, 0xC5A9, 0xBEEE, 0xC5B4, 0xBEEF, 0xC5B5, 0xBEF0, 0xC5B8, + 0xBEF1, 0xC5B9, 0xBEF2, 0xC5BB, 0xBEF3, 0xC5BC, 0xBEF4, 0xC5BD, + 0xBEF5, 0xC5BE, 0xBEF6, 0xC5C4, 0xBEF7, 0xC5C5, 0xBEF8, 0xC5C6, + 0xBEF9, 0xC5C7, 0xBEFA, 0xC5C8, 0xBEFB, 0xC5C9, 0xBEFC, 0xC5CA, + 0xBEFD, 0xC5CC, 0xBEFE, 0xC5CE, 0xBF41, 0xD49E, 0xBF42, 0xD49F, + 0xBF43, 0xD4A0, 0xBF44, 0xD4A1, 0xBF45, 0xD4A2, 0xBF46, 0xD4A3, + 0xBF47, 0xD4A4, 0xBF48, 0xD4A5, 0xBF49, 0xD4A6, 0xBF4A, 0xD4A7, + 0xBF4B, 0xD4A8, 0xBF4C, 0xD4AA, 0xBF4D, 0xD4AB, 0xBF4E, 0xD4AC, + 0xBF4F, 0xD4AD, 0xBF50, 0xD4AE, 0xBF51, 0xD4AF, 0xBF52, 0xD4B0, + 0xBF53, 0xD4B1, 0xBF54, 0xD4B2, 0xBF55, 0xD4B3, 0xBF56, 0xD4B4, + 0xBF57, 0xD4B5, 0xBF58, 0xD4B6, 0xBF59, 0xD4B7, 0xBF5A, 0xD4B8, + 0xBF61, 0xD4B9, 0xBF62, 0xD4BA, 0xBF63, 0xD4BB, 0xBF64, 0xD4BC, + 0xBF65, 0xD4BD, 0xBF66, 0xD4BE, 0xBF67, 0xD4BF, 0xBF68, 0xD4C0, + 0xBF69, 0xD4C1, 0xBF6A, 0xD4C2, 0xBF6B, 0xD4C3, 0xBF6C, 0xD4C4, + 0xBF6D, 0xD4C5, 0xBF6E, 0xD4C6, 0xBF6F, 0xD4C7, 0xBF70, 0xD4C8, + 0xBF71, 0xD4C9, 0xBF72, 0xD4CA, 0xBF73, 0xD4CB, 0xBF74, 0xD4CD, + 0xBF75, 0xD4CE, 0xBF76, 0xD4CF, 0xBF77, 0xD4D1, 0xBF78, 0xD4D2, + 0xBF79, 0xD4D3, 0xBF7A, 0xD4D5, 0xBF81, 0xD4D6, 0xBF82, 0xD4D7, + 0xBF83, 0xD4D8, 0xBF84, 0xD4D9, 0xBF85, 0xD4DA, 0xBF86, 0xD4DB, + 0xBF87, 0xD4DD, 0xBF88, 0xD4DE, 0xBF89, 0xD4E0, 0xBF8A, 0xD4E1, + 0xBF8B, 0xD4E2, 0xBF8C, 0xD4E3, 0xBF8D, 0xD4E4, 0xBF8E, 0xD4E5, + 0xBF8F, 0xD4E6, 0xBF90, 0xD4E7, 0xBF91, 0xD4E9, 0xBF92, 0xD4EA, + 0xBF93, 0xD4EB, 0xBF94, 0xD4ED, 0xBF95, 0xD4EE, 0xBF96, 0xD4EF, + 0xBF97, 0xD4F1, 0xBF98, 0xD4F2, 0xBF99, 0xD4F3, 0xBF9A, 0xD4F4, + 0xBF9B, 0xD4F5, 0xBF9C, 0xD4F6, 0xBF9D, 0xD4F7, 0xBF9E, 0xD4F9, + 0xBF9F, 0xD4FA, 0xBFA0, 0xD4FC, 0xBFA1, 0xC5D0, 0xBFA2, 0xC5D1, + 0xBFA3, 0xC5D4, 0xBFA4, 0xC5D8, 0xBFA5, 0xC5E0, 0xBFA6, 0xC5E1, + 0xBFA7, 0xC5E3, 0xBFA8, 0xC5E5, 0xBFA9, 0xC5EC, 0xBFAA, 0xC5ED, + 0xBFAB, 0xC5EE, 0xBFAC, 0xC5F0, 0xBFAD, 0xC5F4, 0xBFAE, 0xC5F6, + 0xBFAF, 0xC5F7, 0xBFB0, 0xC5FC, 0xBFB1, 0xC5FD, 0xBFB2, 0xC5FE, + 0xBFB3, 0xC5FF, 0xBFB4, 0xC600, 0xBFB5, 0xC601, 0xBFB6, 0xC605, + 0xBFB7, 0xC606, 0xBFB8, 0xC607, 0xBFB9, 0xC608, 0xBFBA, 0xC60C, + 0xBFBB, 0xC610, 0xBFBC, 0xC618, 0xBFBD, 0xC619, 0xBFBE, 0xC61B, + 0xBFBF, 0xC61C, 0xBFC0, 0xC624, 0xBFC1, 0xC625, 0xBFC2, 0xC628, + 0xBFC3, 0xC62C, 0xBFC4, 0xC62D, 0xBFC5, 0xC62E, 0xBFC6, 0xC630, + 0xBFC7, 0xC633, 0xBFC8, 0xC634, 0xBFC9, 0xC635, 0xBFCA, 0xC637, + 0xBFCB, 0xC639, 0xBFCC, 0xC63B, 0xBFCD, 0xC640, 0xBFCE, 0xC641, + 0xBFCF, 0xC644, 0xBFD0, 0xC648, 0xBFD1, 0xC650, 0xBFD2, 0xC651, + 0xBFD3, 0xC653, 0xBFD4, 0xC654, 0xBFD5, 0xC655, 0xBFD6, 0xC65C, + 0xBFD7, 0xC65D, 0xBFD8, 0xC660, 0xBFD9, 0xC66C, 0xBFDA, 0xC66F, + 0xBFDB, 0xC671, 0xBFDC, 0xC678, 0xBFDD, 0xC679, 0xBFDE, 0xC67C, + 0xBFDF, 0xC680, 0xBFE0, 0xC688, 0xBFE1, 0xC689, 0xBFE2, 0xC68B, + 0xBFE3, 0xC68D, 0xBFE4, 0xC694, 0xBFE5, 0xC695, 0xBFE6, 0xC698, + 0xBFE7, 0xC69C, 0xBFE8, 0xC6A4, 0xBFE9, 0xC6A5, 0xBFEA, 0xC6A7, + 0xBFEB, 0xC6A9, 0xBFEC, 0xC6B0, 0xBFED, 0xC6B1, 0xBFEE, 0xC6B4, + 0xBFEF, 0xC6B8, 0xBFF0, 0xC6B9, 0xBFF1, 0xC6BA, 0xBFF2, 0xC6C0, + 0xBFF3, 0xC6C1, 0xBFF4, 0xC6C3, 0xBFF5, 0xC6C5, 0xBFF6, 0xC6CC, + 0xBFF7, 0xC6CD, 0xBFF8, 0xC6D0, 0xBFF9, 0xC6D4, 0xBFFA, 0xC6DC, + 0xBFFB, 0xC6DD, 0xBFFC, 0xC6E0, 0xBFFD, 0xC6E1, 0xBFFE, 0xC6E8, + 0xC041, 0xD4FE, 0xC042, 0xD4FF, 0xC043, 0xD500, 0xC044, 0xD501, + 0xC045, 0xD502, 0xC046, 0xD503, 0xC047, 0xD505, 0xC048, 0xD506, + 0xC049, 0xD507, 0xC04A, 0xD509, 0xC04B, 0xD50A, 0xC04C, 0xD50B, + 0xC04D, 0xD50D, 0xC04E, 0xD50E, 0xC04F, 0xD50F, 0xC050, 0xD510, + 0xC051, 0xD511, 0xC052, 0xD512, 0xC053, 0xD513, 0xC054, 0xD516, + 0xC055, 0xD518, 0xC056, 0xD519, 0xC057, 0xD51A, 0xC058, 0xD51B, + 0xC059, 0xD51C, 0xC05A, 0xD51D, 0xC061, 0xD51E, 0xC062, 0xD51F, + 0xC063, 0xD520, 0xC064, 0xD521, 0xC065, 0xD522, 0xC066, 0xD523, + 0xC067, 0xD524, 0xC068, 0xD525, 0xC069, 0xD526, 0xC06A, 0xD527, + 0xC06B, 0xD528, 0xC06C, 0xD529, 0xC06D, 0xD52A, 0xC06E, 0xD52B, + 0xC06F, 0xD52C, 0xC070, 0xD52D, 0xC071, 0xD52E, 0xC072, 0xD52F, + 0xC073, 0xD530, 0xC074, 0xD531, 0xC075, 0xD532, 0xC076, 0xD533, + 0xC077, 0xD534, 0xC078, 0xD535, 0xC079, 0xD536, 0xC07A, 0xD537, + 0xC081, 0xD538, 0xC082, 0xD539, 0xC083, 0xD53A, 0xC084, 0xD53B, + 0xC085, 0xD53E, 0xC086, 0xD53F, 0xC087, 0xD541, 0xC088, 0xD542, + 0xC089, 0xD543, 0xC08A, 0xD545, 0xC08B, 0xD546, 0xC08C, 0xD547, + 0xC08D, 0xD548, 0xC08E, 0xD549, 0xC08F, 0xD54A, 0xC090, 0xD54B, + 0xC091, 0xD54E, 0xC092, 0xD550, 0xC093, 0xD552, 0xC094, 0xD553, + 0xC095, 0xD554, 0xC096, 0xD555, 0xC097, 0xD556, 0xC098, 0xD557, + 0xC099, 0xD55A, 0xC09A, 0xD55B, 0xC09B, 0xD55D, 0xC09C, 0xD55E, + 0xC09D, 0xD55F, 0xC09E, 0xD561, 0xC09F, 0xD562, 0xC0A0, 0xD563, + 0xC0A1, 0xC6E9, 0xC0A2, 0xC6EC, 0xC0A3, 0xC6F0, 0xC0A4, 0xC6F8, + 0xC0A5, 0xC6F9, 0xC0A6, 0xC6FD, 0xC0A7, 0xC704, 0xC0A8, 0xC705, + 0xC0A9, 0xC708, 0xC0AA, 0xC70C, 0xC0AB, 0xC714, 0xC0AC, 0xC715, + 0xC0AD, 0xC717, 0xC0AE, 0xC719, 0xC0AF, 0xC720, 0xC0B0, 0xC721, + 0xC0B1, 0xC724, 0xC0B2, 0xC728, 0xC0B3, 0xC730, 0xC0B4, 0xC731, + 0xC0B5, 0xC733, 0xC0B6, 0xC735, 0xC0B7, 0xC737, 0xC0B8, 0xC73C, + 0xC0B9, 0xC73D, 0xC0BA, 0xC740, 0xC0BB, 0xC744, 0xC0BC, 0xC74A, + 0xC0BD, 0xC74C, 0xC0BE, 0xC74D, 0xC0BF, 0xC74F, 0xC0C0, 0xC751, + 0xC0C1, 0xC752, 0xC0C2, 0xC753, 0xC0C3, 0xC754, 0xC0C4, 0xC755, + 0xC0C5, 0xC756, 0xC0C6, 0xC757, 0xC0C7, 0xC758, 0xC0C8, 0xC75C, + 0xC0C9, 0xC760, 0xC0CA, 0xC768, 0xC0CB, 0xC76B, 0xC0CC, 0xC774, + 0xC0CD, 0xC775, 0xC0CE, 0xC778, 0xC0CF, 0xC77C, 0xC0D0, 0xC77D, + 0xC0D1, 0xC77E, 0xC0D2, 0xC783, 0xC0D3, 0xC784, 0xC0D4, 0xC785, + 0xC0D5, 0xC787, 0xC0D6, 0xC788, 0xC0D7, 0xC789, 0xC0D8, 0xC78A, + 0xC0D9, 0xC78E, 0xC0DA, 0xC790, 0xC0DB, 0xC791, 0xC0DC, 0xC794, + 0xC0DD, 0xC796, 0xC0DE, 0xC797, 0xC0DF, 0xC798, 0xC0E0, 0xC79A, + 0xC0E1, 0xC7A0, 0xC0E2, 0xC7A1, 0xC0E3, 0xC7A3, 0xC0E4, 0xC7A4, + 0xC0E5, 0xC7A5, 0xC0E6, 0xC7A6, 0xC0E7, 0xC7AC, 0xC0E8, 0xC7AD, + 0xC0E9, 0xC7B0, 0xC0EA, 0xC7B4, 0xC0EB, 0xC7BC, 0xC0EC, 0xC7BD, + 0xC0ED, 0xC7BF, 0xC0EE, 0xC7C0, 0xC0EF, 0xC7C1, 0xC0F0, 0xC7C8, + 0xC0F1, 0xC7C9, 0xC0F2, 0xC7CC, 0xC0F3, 0xC7CE, 0xC0F4, 0xC7D0, + 0xC0F5, 0xC7D8, 0xC0F6, 0xC7DD, 0xC0F7, 0xC7E4, 0xC0F8, 0xC7E8, + 0xC0F9, 0xC7EC, 0xC0FA, 0xC800, 0xC0FB, 0xC801, 0xC0FC, 0xC804, + 0xC0FD, 0xC808, 0xC0FE, 0xC80A, 0xC141, 0xD564, 0xC142, 0xD566, + 0xC143, 0xD567, 0xC144, 0xD56A, 0xC145, 0xD56C, 0xC146, 0xD56E, + 0xC147, 0xD56F, 0xC148, 0xD570, 0xC149, 0xD571, 0xC14A, 0xD572, + 0xC14B, 0xD573, 0xC14C, 0xD576, 0xC14D, 0xD577, 0xC14E, 0xD579, + 0xC14F, 0xD57A, 0xC150, 0xD57B, 0xC151, 0xD57D, 0xC152, 0xD57E, + 0xC153, 0xD57F, 0xC154, 0xD580, 0xC155, 0xD581, 0xC156, 0xD582, + 0xC157, 0xD583, 0xC158, 0xD586, 0xC159, 0xD58A, 0xC15A, 0xD58B, + 0xC161, 0xD58C, 0xC162, 0xD58D, 0xC163, 0xD58E, 0xC164, 0xD58F, + 0xC165, 0xD591, 0xC166, 0xD592, 0xC167, 0xD593, 0xC168, 0xD594, + 0xC169, 0xD595, 0xC16A, 0xD596, 0xC16B, 0xD597, 0xC16C, 0xD598, + 0xC16D, 0xD599, 0xC16E, 0xD59A, 0xC16F, 0xD59B, 0xC170, 0xD59C, + 0xC171, 0xD59D, 0xC172, 0xD59E, 0xC173, 0xD59F, 0xC174, 0xD5A0, + 0xC175, 0xD5A1, 0xC176, 0xD5A2, 0xC177, 0xD5A3, 0xC178, 0xD5A4, + 0xC179, 0xD5A6, 0xC17A, 0xD5A7, 0xC181, 0xD5A8, 0xC182, 0xD5A9, + 0xC183, 0xD5AA, 0xC184, 0xD5AB, 0xC185, 0xD5AC, 0xC186, 0xD5AD, + 0xC187, 0xD5AE, 0xC188, 0xD5AF, 0xC189, 0xD5B0, 0xC18A, 0xD5B1, + 0xC18B, 0xD5B2, 0xC18C, 0xD5B3, 0xC18D, 0xD5B4, 0xC18E, 0xD5B5, + 0xC18F, 0xD5B6, 0xC190, 0xD5B7, 0xC191, 0xD5B8, 0xC192, 0xD5B9, + 0xC193, 0xD5BA, 0xC194, 0xD5BB, 0xC195, 0xD5BC, 0xC196, 0xD5BD, + 0xC197, 0xD5BE, 0xC198, 0xD5BF, 0xC199, 0xD5C0, 0xC19A, 0xD5C1, + 0xC19B, 0xD5C2, 0xC19C, 0xD5C3, 0xC19D, 0xD5C4, 0xC19E, 0xD5C5, + 0xC19F, 0xD5C6, 0xC1A0, 0xD5C7, 0xC1A1, 0xC810, 0xC1A2, 0xC811, + 0xC1A3, 0xC813, 0xC1A4, 0xC815, 0xC1A5, 0xC816, 0xC1A6, 0xC81C, + 0xC1A7, 0xC81D, 0xC1A8, 0xC820, 0xC1A9, 0xC824, 0xC1AA, 0xC82C, + 0xC1AB, 0xC82D, 0xC1AC, 0xC82F, 0xC1AD, 0xC831, 0xC1AE, 0xC838, + 0xC1AF, 0xC83C, 0xC1B0, 0xC840, 0xC1B1, 0xC848, 0xC1B2, 0xC849, + 0xC1B3, 0xC84C, 0xC1B4, 0xC84D, 0xC1B5, 0xC854, 0xC1B6, 0xC870, + 0xC1B7, 0xC871, 0xC1B8, 0xC874, 0xC1B9, 0xC878, 0xC1BA, 0xC87A, + 0xC1BB, 0xC880, 0xC1BC, 0xC881, 0xC1BD, 0xC883, 0xC1BE, 0xC885, + 0xC1BF, 0xC886, 0xC1C0, 0xC887, 0xC1C1, 0xC88B, 0xC1C2, 0xC88C, + 0xC1C3, 0xC88D, 0xC1C4, 0xC894, 0xC1C5, 0xC89D, 0xC1C6, 0xC89F, + 0xC1C7, 0xC8A1, 0xC1C8, 0xC8A8, 0xC1C9, 0xC8BC, 0xC1CA, 0xC8BD, + 0xC1CB, 0xC8C4, 0xC1CC, 0xC8C8, 0xC1CD, 0xC8CC, 0xC1CE, 0xC8D4, + 0xC1CF, 0xC8D5, 0xC1D0, 0xC8D7, 0xC1D1, 0xC8D9, 0xC1D2, 0xC8E0, + 0xC1D3, 0xC8E1, 0xC1D4, 0xC8E4, 0xC1D5, 0xC8F5, 0xC1D6, 0xC8FC, + 0xC1D7, 0xC8FD, 0xC1D8, 0xC900, 0xC1D9, 0xC904, 0xC1DA, 0xC905, + 0xC1DB, 0xC906, 0xC1DC, 0xC90C, 0xC1DD, 0xC90D, 0xC1DE, 0xC90F, + 0xC1DF, 0xC911, 0xC1E0, 0xC918, 0xC1E1, 0xC92C, 0xC1E2, 0xC934, + 0xC1E3, 0xC950, 0xC1E4, 0xC951, 0xC1E5, 0xC954, 0xC1E6, 0xC958, + 0xC1E7, 0xC960, 0xC1E8, 0xC961, 0xC1E9, 0xC963, 0xC1EA, 0xC96C, + 0xC1EB, 0xC970, 0xC1EC, 0xC974, 0xC1ED, 0xC97C, 0xC1EE, 0xC988, + 0xC1EF, 0xC989, 0xC1F0, 0xC98C, 0xC1F1, 0xC990, 0xC1F2, 0xC998, + 0xC1F3, 0xC999, 0xC1F4, 0xC99B, 0xC1F5, 0xC99D, 0xC1F6, 0xC9C0, + 0xC1F7, 0xC9C1, 0xC1F8, 0xC9C4, 0xC1F9, 0xC9C7, 0xC1FA, 0xC9C8, + 0xC1FB, 0xC9CA, 0xC1FC, 0xC9D0, 0xC1FD, 0xC9D1, 0xC1FE, 0xC9D3, + 0xC241, 0xD5CA, 0xC242, 0xD5CB, 0xC243, 0xD5CD, 0xC244, 0xD5CE, + 0xC245, 0xD5CF, 0xC246, 0xD5D1, 0xC247, 0xD5D3, 0xC248, 0xD5D4, + 0xC249, 0xD5D5, 0xC24A, 0xD5D6, 0xC24B, 0xD5D7, 0xC24C, 0xD5DA, + 0xC24D, 0xD5DC, 0xC24E, 0xD5DE, 0xC24F, 0xD5DF, 0xC250, 0xD5E0, + 0xC251, 0xD5E1, 0xC252, 0xD5E2, 0xC253, 0xD5E3, 0xC254, 0xD5E6, + 0xC255, 0xD5E7, 0xC256, 0xD5E9, 0xC257, 0xD5EA, 0xC258, 0xD5EB, + 0xC259, 0xD5ED, 0xC25A, 0xD5EE, 0xC261, 0xD5EF, 0xC262, 0xD5F0, + 0xC263, 0xD5F1, 0xC264, 0xD5F2, 0xC265, 0xD5F3, 0xC266, 0xD5F6, + 0xC267, 0xD5F8, 0xC268, 0xD5FA, 0xC269, 0xD5FB, 0xC26A, 0xD5FC, + 0xC26B, 0xD5FD, 0xC26C, 0xD5FE, 0xC26D, 0xD5FF, 0xC26E, 0xD602, + 0xC26F, 0xD603, 0xC270, 0xD605, 0xC271, 0xD606, 0xC272, 0xD607, + 0xC273, 0xD609, 0xC274, 0xD60A, 0xC275, 0xD60B, 0xC276, 0xD60C, + 0xC277, 0xD60D, 0xC278, 0xD60E, 0xC279, 0xD60F, 0xC27A, 0xD612, + 0xC281, 0xD616, 0xC282, 0xD617, 0xC283, 0xD618, 0xC284, 0xD619, + 0xC285, 0xD61A, 0xC286, 0xD61B, 0xC287, 0xD61D, 0xC288, 0xD61E, + 0xC289, 0xD61F, 0xC28A, 0xD621, 0xC28B, 0xD622, 0xC28C, 0xD623, + 0xC28D, 0xD625, 0xC28E, 0xD626, 0xC28F, 0xD627, 0xC290, 0xD628, + 0xC291, 0xD629, 0xC292, 0xD62A, 0xC293, 0xD62B, 0xC294, 0xD62C, + 0xC295, 0xD62E, 0xC296, 0xD62F, 0xC297, 0xD630, 0xC298, 0xD631, + 0xC299, 0xD632, 0xC29A, 0xD633, 0xC29B, 0xD634, 0xC29C, 0xD635, + 0xC29D, 0xD636, 0xC29E, 0xD637, 0xC29F, 0xD63A, 0xC2A0, 0xD63B, + 0xC2A1, 0xC9D5, 0xC2A2, 0xC9D6, 0xC2A3, 0xC9D9, 0xC2A4, 0xC9DA, + 0xC2A5, 0xC9DC, 0xC2A6, 0xC9DD, 0xC2A7, 0xC9E0, 0xC2A8, 0xC9E2, + 0xC2A9, 0xC9E4, 0xC2AA, 0xC9E7, 0xC2AB, 0xC9EC, 0xC2AC, 0xC9ED, + 0xC2AD, 0xC9EF, 0xC2AE, 0xC9F0, 0xC2AF, 0xC9F1, 0xC2B0, 0xC9F8, + 0xC2B1, 0xC9F9, 0xC2B2, 0xC9FC, 0xC2B3, 0xCA00, 0xC2B4, 0xCA08, + 0xC2B5, 0xCA09, 0xC2B6, 0xCA0B, 0xC2B7, 0xCA0C, 0xC2B8, 0xCA0D, + 0xC2B9, 0xCA14, 0xC2BA, 0xCA18, 0xC2BB, 0xCA29, 0xC2BC, 0xCA4C, + 0xC2BD, 0xCA4D, 0xC2BE, 0xCA50, 0xC2BF, 0xCA54, 0xC2C0, 0xCA5C, + 0xC2C1, 0xCA5D, 0xC2C2, 0xCA5F, 0xC2C3, 0xCA60, 0xC2C4, 0xCA61, + 0xC2C5, 0xCA68, 0xC2C6, 0xCA7D, 0xC2C7, 0xCA84, 0xC2C8, 0xCA98, + 0xC2C9, 0xCABC, 0xC2CA, 0xCABD, 0xC2CB, 0xCAC0, 0xC2CC, 0xCAC4, + 0xC2CD, 0xCACC, 0xC2CE, 0xCACD, 0xC2CF, 0xCACF, 0xC2D0, 0xCAD1, + 0xC2D1, 0xCAD3, 0xC2D2, 0xCAD8, 0xC2D3, 0xCAD9, 0xC2D4, 0xCAE0, + 0xC2D5, 0xCAEC, 0xC2D6, 0xCAF4, 0xC2D7, 0xCB08, 0xC2D8, 0xCB10, + 0xC2D9, 0xCB14, 0xC2DA, 0xCB18, 0xC2DB, 0xCB20, 0xC2DC, 0xCB21, + 0xC2DD, 0xCB41, 0xC2DE, 0xCB48, 0xC2DF, 0xCB49, 0xC2E0, 0xCB4C, + 0xC2E1, 0xCB50, 0xC2E2, 0xCB58, 0xC2E3, 0xCB59, 0xC2E4, 0xCB5D, + 0xC2E5, 0xCB64, 0xC2E6, 0xCB78, 0xC2E7, 0xCB79, 0xC2E8, 0xCB9C, + 0xC2E9, 0xCBB8, 0xC2EA, 0xCBD4, 0xC2EB, 0xCBE4, 0xC2EC, 0xCBE7, + 0xC2ED, 0xCBE9, 0xC2EE, 0xCC0C, 0xC2EF, 0xCC0D, 0xC2F0, 0xCC10, + 0xC2F1, 0xCC14, 0xC2F2, 0xCC1C, 0xC2F3, 0xCC1D, 0xC2F4, 0xCC21, + 0xC2F5, 0xCC22, 0xC2F6, 0xCC27, 0xC2F7, 0xCC28, 0xC2F8, 0xCC29, + 0xC2F9, 0xCC2C, 0xC2FA, 0xCC2E, 0xC2FB, 0xCC30, 0xC2FC, 0xCC38, + 0xC2FD, 0xCC39, 0xC2FE, 0xCC3B, 0xC341, 0xD63D, 0xC342, 0xD63E, + 0xC343, 0xD63F, 0xC344, 0xD641, 0xC345, 0xD642, 0xC346, 0xD643, + 0xC347, 0xD644, 0xC348, 0xD646, 0xC349, 0xD647, 0xC34A, 0xD64A, + 0xC34B, 0xD64C, 0xC34C, 0xD64E, 0xC34D, 0xD64F, 0xC34E, 0xD650, + 0xC34F, 0xD652, 0xC350, 0xD653, 0xC351, 0xD656, 0xC352, 0xD657, + 0xC353, 0xD659, 0xC354, 0xD65A, 0xC355, 0xD65B, 0xC356, 0xD65D, + 0xC357, 0xD65E, 0xC358, 0xD65F, 0xC359, 0xD660, 0xC35A, 0xD661, + 0xC361, 0xD662, 0xC362, 0xD663, 0xC363, 0xD664, 0xC364, 0xD665, + 0xC365, 0xD666, 0xC366, 0xD668, 0xC367, 0xD66A, 0xC368, 0xD66B, + 0xC369, 0xD66C, 0xC36A, 0xD66D, 0xC36B, 0xD66E, 0xC36C, 0xD66F, + 0xC36D, 0xD672, 0xC36E, 0xD673, 0xC36F, 0xD675, 0xC370, 0xD676, + 0xC371, 0xD677, 0xC372, 0xD678, 0xC373, 0xD679, 0xC374, 0xD67A, + 0xC375, 0xD67B, 0xC376, 0xD67C, 0xC377, 0xD67D, 0xC378, 0xD67E, + 0xC379, 0xD67F, 0xC37A, 0xD680, 0xC381, 0xD681, 0xC382, 0xD682, + 0xC383, 0xD684, 0xC384, 0xD686, 0xC385, 0xD687, 0xC386, 0xD688, + 0xC387, 0xD689, 0xC388, 0xD68A, 0xC389, 0xD68B, 0xC38A, 0xD68E, + 0xC38B, 0xD68F, 0xC38C, 0xD691, 0xC38D, 0xD692, 0xC38E, 0xD693, + 0xC38F, 0xD695, 0xC390, 0xD696, 0xC391, 0xD697, 0xC392, 0xD698, + 0xC393, 0xD699, 0xC394, 0xD69A, 0xC395, 0xD69B, 0xC396, 0xD69C, + 0xC397, 0xD69E, 0xC398, 0xD6A0, 0xC399, 0xD6A2, 0xC39A, 0xD6A3, + 0xC39B, 0xD6A4, 0xC39C, 0xD6A5, 0xC39D, 0xD6A6, 0xC39E, 0xD6A7, + 0xC39F, 0xD6A9, 0xC3A0, 0xD6AA, 0xC3A1, 0xCC3C, 0xC3A2, 0xCC3D, + 0xC3A3, 0xCC3E, 0xC3A4, 0xCC44, 0xC3A5, 0xCC45, 0xC3A6, 0xCC48, + 0xC3A7, 0xCC4C, 0xC3A8, 0xCC54, 0xC3A9, 0xCC55, 0xC3AA, 0xCC57, + 0xC3AB, 0xCC58, 0xC3AC, 0xCC59, 0xC3AD, 0xCC60, 0xC3AE, 0xCC64, + 0xC3AF, 0xCC66, 0xC3B0, 0xCC68, 0xC3B1, 0xCC70, 0xC3B2, 0xCC75, + 0xC3B3, 0xCC98, 0xC3B4, 0xCC99, 0xC3B5, 0xCC9C, 0xC3B6, 0xCCA0, + 0xC3B7, 0xCCA8, 0xC3B8, 0xCCA9, 0xC3B9, 0xCCAB, 0xC3BA, 0xCCAC, + 0xC3BB, 0xCCAD, 0xC3BC, 0xCCB4, 0xC3BD, 0xCCB5, 0xC3BE, 0xCCB8, + 0xC3BF, 0xCCBC, 0xC3C0, 0xCCC4, 0xC3C1, 0xCCC5, 0xC3C2, 0xCCC7, + 0xC3C3, 0xCCC9, 0xC3C4, 0xCCD0, 0xC3C5, 0xCCD4, 0xC3C6, 0xCCE4, + 0xC3C7, 0xCCEC, 0xC3C8, 0xCCF0, 0xC3C9, 0xCD01, 0xC3CA, 0xCD08, + 0xC3CB, 0xCD09, 0xC3CC, 0xCD0C, 0xC3CD, 0xCD10, 0xC3CE, 0xCD18, + 0xC3CF, 0xCD19, 0xC3D0, 0xCD1B, 0xC3D1, 0xCD1D, 0xC3D2, 0xCD24, + 0xC3D3, 0xCD28, 0xC3D4, 0xCD2C, 0xC3D5, 0xCD39, 0xC3D6, 0xCD5C, + 0xC3D7, 0xCD60, 0xC3D8, 0xCD64, 0xC3D9, 0xCD6C, 0xC3DA, 0xCD6D, + 0xC3DB, 0xCD6F, 0xC3DC, 0xCD71, 0xC3DD, 0xCD78, 0xC3DE, 0xCD88, + 0xC3DF, 0xCD94, 0xC3E0, 0xCD95, 0xC3E1, 0xCD98, 0xC3E2, 0xCD9C, + 0xC3E3, 0xCDA4, 0xC3E4, 0xCDA5, 0xC3E5, 0xCDA7, 0xC3E6, 0xCDA9, + 0xC3E7, 0xCDB0, 0xC3E8, 0xCDC4, 0xC3E9, 0xCDCC, 0xC3EA, 0xCDD0, + 0xC3EB, 0xCDE8, 0xC3EC, 0xCDEC, 0xC3ED, 0xCDF0, 0xC3EE, 0xCDF8, + 0xC3EF, 0xCDF9, 0xC3F0, 0xCDFB, 0xC3F1, 0xCDFD, 0xC3F2, 0xCE04, + 0xC3F3, 0xCE08, 0xC3F4, 0xCE0C, 0xC3F5, 0xCE14, 0xC3F6, 0xCE19, + 0xC3F7, 0xCE20, 0xC3F8, 0xCE21, 0xC3F9, 0xCE24, 0xC3FA, 0xCE28, + 0xC3FB, 0xCE30, 0xC3FC, 0xCE31, 0xC3FD, 0xCE33, 0xC3FE, 0xCE35, + 0xC441, 0xD6AB, 0xC442, 0xD6AD, 0xC443, 0xD6AE, 0xC444, 0xD6AF, + 0xC445, 0xD6B1, 0xC446, 0xD6B2, 0xC447, 0xD6B3, 0xC448, 0xD6B4, + 0xC449, 0xD6B5, 0xC44A, 0xD6B6, 0xC44B, 0xD6B7, 0xC44C, 0xD6B8, + 0xC44D, 0xD6BA, 0xC44E, 0xD6BC, 0xC44F, 0xD6BD, 0xC450, 0xD6BE, + 0xC451, 0xD6BF, 0xC452, 0xD6C0, 0xC453, 0xD6C1, 0xC454, 0xD6C2, + 0xC455, 0xD6C3, 0xC456, 0xD6C6, 0xC457, 0xD6C7, 0xC458, 0xD6C9, + 0xC459, 0xD6CA, 0xC45A, 0xD6CB, 0xC461, 0xD6CD, 0xC462, 0xD6CE, + 0xC463, 0xD6CF, 0xC464, 0xD6D0, 0xC465, 0xD6D2, 0xC466, 0xD6D3, + 0xC467, 0xD6D5, 0xC468, 0xD6D6, 0xC469, 0xD6D8, 0xC46A, 0xD6DA, + 0xC46B, 0xD6DB, 0xC46C, 0xD6DC, 0xC46D, 0xD6DD, 0xC46E, 0xD6DE, + 0xC46F, 0xD6DF, 0xC470, 0xD6E1, 0xC471, 0xD6E2, 0xC472, 0xD6E3, + 0xC473, 0xD6E5, 0xC474, 0xD6E6, 0xC475, 0xD6E7, 0xC476, 0xD6E9, + 0xC477, 0xD6EA, 0xC478, 0xD6EB, 0xC479, 0xD6EC, 0xC47A, 0xD6ED, + 0xC481, 0xD6EE, 0xC482, 0xD6EF, 0xC483, 0xD6F1, 0xC484, 0xD6F2, + 0xC485, 0xD6F3, 0xC486, 0xD6F4, 0xC487, 0xD6F6, 0xC488, 0xD6F7, + 0xC489, 0xD6F8, 0xC48A, 0xD6F9, 0xC48B, 0xD6FA, 0xC48C, 0xD6FB, + 0xC48D, 0xD6FE, 0xC48E, 0xD6FF, 0xC48F, 0xD701, 0xC490, 0xD702, + 0xC491, 0xD703, 0xC492, 0xD705, 0xC493, 0xD706, 0xC494, 0xD707, + 0xC495, 0xD708, 0xC496, 0xD709, 0xC497, 0xD70A, 0xC498, 0xD70B, + 0xC499, 0xD70C, 0xC49A, 0xD70D, 0xC49B, 0xD70E, 0xC49C, 0xD70F, + 0xC49D, 0xD710, 0xC49E, 0xD712, 0xC49F, 0xD713, 0xC4A0, 0xD714, + 0xC4A1, 0xCE58, 0xC4A2, 0xCE59, 0xC4A3, 0xCE5C, 0xC4A4, 0xCE5F, + 0xC4A5, 0xCE60, 0xC4A6, 0xCE61, 0xC4A7, 0xCE68, 0xC4A8, 0xCE69, + 0xC4A9, 0xCE6B, 0xC4AA, 0xCE6D, 0xC4AB, 0xCE74, 0xC4AC, 0xCE75, + 0xC4AD, 0xCE78, 0xC4AE, 0xCE7C, 0xC4AF, 0xCE84, 0xC4B0, 0xCE85, + 0xC4B1, 0xCE87, 0xC4B2, 0xCE89, 0xC4B3, 0xCE90, 0xC4B4, 0xCE91, + 0xC4B5, 0xCE94, 0xC4B6, 0xCE98, 0xC4B7, 0xCEA0, 0xC4B8, 0xCEA1, + 0xC4B9, 0xCEA3, 0xC4BA, 0xCEA4, 0xC4BB, 0xCEA5, 0xC4BC, 0xCEAC, + 0xC4BD, 0xCEAD, 0xC4BE, 0xCEC1, 0xC4BF, 0xCEE4, 0xC4C0, 0xCEE5, + 0xC4C1, 0xCEE8, 0xC4C2, 0xCEEB, 0xC4C3, 0xCEEC, 0xC4C4, 0xCEF4, + 0xC4C5, 0xCEF5, 0xC4C6, 0xCEF7, 0xC4C7, 0xCEF8, 0xC4C8, 0xCEF9, + 0xC4C9, 0xCF00, 0xC4CA, 0xCF01, 0xC4CB, 0xCF04, 0xC4CC, 0xCF08, + 0xC4CD, 0xCF10, 0xC4CE, 0xCF11, 0xC4CF, 0xCF13, 0xC4D0, 0xCF15, + 0xC4D1, 0xCF1C, 0xC4D2, 0xCF20, 0xC4D3, 0xCF24, 0xC4D4, 0xCF2C, + 0xC4D5, 0xCF2D, 0xC4D6, 0xCF2F, 0xC4D7, 0xCF30, 0xC4D8, 0xCF31, + 0xC4D9, 0xCF38, 0xC4DA, 0xCF54, 0xC4DB, 0xCF55, 0xC4DC, 0xCF58, + 0xC4DD, 0xCF5C, 0xC4DE, 0xCF64, 0xC4DF, 0xCF65, 0xC4E0, 0xCF67, + 0xC4E1, 0xCF69, 0xC4E2, 0xCF70, 0xC4E3, 0xCF71, 0xC4E4, 0xCF74, + 0xC4E5, 0xCF78, 0xC4E6, 0xCF80, 0xC4E7, 0xCF85, 0xC4E8, 0xCF8C, + 0xC4E9, 0xCFA1, 0xC4EA, 0xCFA8, 0xC4EB, 0xCFB0, 0xC4EC, 0xCFC4, + 0xC4ED, 0xCFE0, 0xC4EE, 0xCFE1, 0xC4EF, 0xCFE4, 0xC4F0, 0xCFE8, + 0xC4F1, 0xCFF0, 0xC4F2, 0xCFF1, 0xC4F3, 0xCFF3, 0xC4F4, 0xCFF5, + 0xC4F5, 0xCFFC, 0xC4F6, 0xD000, 0xC4F7, 0xD004, 0xC4F8, 0xD011, + 0xC4F9, 0xD018, 0xC4FA, 0xD02D, 0xC4FB, 0xD034, 0xC4FC, 0xD035, + 0xC4FD, 0xD038, 0xC4FE, 0xD03C, 0xC541, 0xD715, 0xC542, 0xD716, + 0xC543, 0xD717, 0xC544, 0xD71A, 0xC545, 0xD71B, 0xC546, 0xD71D, + 0xC547, 0xD71E, 0xC548, 0xD71F, 0xC549, 0xD721, 0xC54A, 0xD722, + 0xC54B, 0xD723, 0xC54C, 0xD724, 0xC54D, 0xD725, 0xC54E, 0xD726, + 0xC54F, 0xD727, 0xC550, 0xD72A, 0xC551, 0xD72C, 0xC552, 0xD72E, + 0xC553, 0xD72F, 0xC554, 0xD730, 0xC555, 0xD731, 0xC556, 0xD732, + 0xC557, 0xD733, 0xC558, 0xD736, 0xC559, 0xD737, 0xC55A, 0xD739, + 0xC561, 0xD73A, 0xC562, 0xD73B, 0xC563, 0xD73D, 0xC564, 0xD73E, + 0xC565, 0xD73F, 0xC566, 0xD740, 0xC567, 0xD741, 0xC568, 0xD742, + 0xC569, 0xD743, 0xC56A, 0xD745, 0xC56B, 0xD746, 0xC56C, 0xD748, + 0xC56D, 0xD74A, 0xC56E, 0xD74B, 0xC56F, 0xD74C, 0xC570, 0xD74D, + 0xC571, 0xD74E, 0xC572, 0xD74F, 0xC573, 0xD752, 0xC574, 0xD753, + 0xC575, 0xD755, 0xC576, 0xD75A, 0xC577, 0xD75B, 0xC578, 0xD75C, + 0xC579, 0xD75D, 0xC57A, 0xD75E, 0xC581, 0xD75F, 0xC582, 0xD762, + 0xC583, 0xD764, 0xC584, 0xD766, 0xC585, 0xD767, 0xC586, 0xD768, + 0xC587, 0xD76A, 0xC588, 0xD76B, 0xC589, 0xD76D, 0xC58A, 0xD76E, + 0xC58B, 0xD76F, 0xC58C, 0xD771, 0xC58D, 0xD772, 0xC58E, 0xD773, + 0xC58F, 0xD775, 0xC590, 0xD776, 0xC591, 0xD777, 0xC592, 0xD778, + 0xC593, 0xD779, 0xC594, 0xD77A, 0xC595, 0xD77B, 0xC596, 0xD77E, + 0xC597, 0xD77F, 0xC598, 0xD780, 0xC599, 0xD782, 0xC59A, 0xD783, + 0xC59B, 0xD784, 0xC59C, 0xD785, 0xC59D, 0xD786, 0xC59E, 0xD787, + 0xC59F, 0xD78A, 0xC5A0, 0xD78B, 0xC5A1, 0xD044, 0xC5A2, 0xD045, + 0xC5A3, 0xD047, 0xC5A4, 0xD049, 0xC5A5, 0xD050, 0xC5A6, 0xD054, + 0xC5A7, 0xD058, 0xC5A8, 0xD060, 0xC5A9, 0xD06C, 0xC5AA, 0xD06D, + 0xC5AB, 0xD070, 0xC5AC, 0xD074, 0xC5AD, 0xD07C, 0xC5AE, 0xD07D, + 0xC5AF, 0xD081, 0xC5B0, 0xD0A4, 0xC5B1, 0xD0A5, 0xC5B2, 0xD0A8, + 0xC5B3, 0xD0AC, 0xC5B4, 0xD0B4, 0xC5B5, 0xD0B5, 0xC5B6, 0xD0B7, + 0xC5B7, 0xD0B9, 0xC5B8, 0xD0C0, 0xC5B9, 0xD0C1, 0xC5BA, 0xD0C4, + 0xC5BB, 0xD0C8, 0xC5BC, 0xD0C9, 0xC5BD, 0xD0D0, 0xC5BE, 0xD0D1, + 0xC5BF, 0xD0D3, 0xC5C0, 0xD0D4, 0xC5C1, 0xD0D5, 0xC5C2, 0xD0DC, + 0xC5C3, 0xD0DD, 0xC5C4, 0xD0E0, 0xC5C5, 0xD0E4, 0xC5C6, 0xD0EC, + 0xC5C7, 0xD0ED, 0xC5C8, 0xD0EF, 0xC5C9, 0xD0F0, 0xC5CA, 0xD0F1, + 0xC5CB, 0xD0F8, 0xC5CC, 0xD10D, 0xC5CD, 0xD130, 0xC5CE, 0xD131, + 0xC5CF, 0xD134, 0xC5D0, 0xD138, 0xC5D1, 0xD13A, 0xC5D2, 0xD140, + 0xC5D3, 0xD141, 0xC5D4, 0xD143, 0xC5D5, 0xD144, 0xC5D6, 0xD145, + 0xC5D7, 0xD14C, 0xC5D8, 0xD14D, 0xC5D9, 0xD150, 0xC5DA, 0xD154, + 0xC5DB, 0xD15C, 0xC5DC, 0xD15D, 0xC5DD, 0xD15F, 0xC5DE, 0xD161, + 0xC5DF, 0xD168, 0xC5E0, 0xD16C, 0xC5E1, 0xD17C, 0xC5E2, 0xD184, + 0xC5E3, 0xD188, 0xC5E4, 0xD1A0, 0xC5E5, 0xD1A1, 0xC5E6, 0xD1A4, + 0xC5E7, 0xD1A8, 0xC5E8, 0xD1B0, 0xC5E9, 0xD1B1, 0xC5EA, 0xD1B3, + 0xC5EB, 0xD1B5, 0xC5EC, 0xD1BA, 0xC5ED, 0xD1BC, 0xC5EE, 0xD1C0, + 0xC5EF, 0xD1D8, 0xC5F0, 0xD1F4, 0xC5F1, 0xD1F8, 0xC5F2, 0xD207, + 0xC5F3, 0xD209, 0xC5F4, 0xD210, 0xC5F5, 0xD22C, 0xC5F6, 0xD22D, + 0xC5F7, 0xD230, 0xC5F8, 0xD234, 0xC5F9, 0xD23C, 0xC5FA, 0xD23D, + 0xC5FB, 0xD23F, 0xC5FC, 0xD241, 0xC5FD, 0xD248, 0xC5FE, 0xD25C, + 0xC641, 0xD78D, 0xC642, 0xD78E, 0xC643, 0xD78F, 0xC644, 0xD791, + 0xC645, 0xD792, 0xC646, 0xD793, 0xC647, 0xD794, 0xC648, 0xD795, + 0xC649, 0xD796, 0xC64A, 0xD797, 0xC64B, 0xD79A, 0xC64C, 0xD79C, + 0xC64D, 0xD79E, 0xC64E, 0xD79F, 0xC64F, 0xD7A0, 0xC650, 0xD7A1, + 0xC651, 0xD7A2, 0xC652, 0xD7A3, 0xC6A1, 0xD264, 0xC6A2, 0xD280, + 0xC6A3, 0xD281, 0xC6A4, 0xD284, 0xC6A5, 0xD288, 0xC6A6, 0xD290, + 0xC6A7, 0xD291, 0xC6A8, 0xD295, 0xC6A9, 0xD29C, 0xC6AA, 0xD2A0, + 0xC6AB, 0xD2A4, 0xC6AC, 0xD2AC, 0xC6AD, 0xD2B1, 0xC6AE, 0xD2B8, + 0xC6AF, 0xD2B9, 0xC6B0, 0xD2BC, 0xC6B1, 0xD2BF, 0xC6B2, 0xD2C0, + 0xC6B3, 0xD2C2, 0xC6B4, 0xD2C8, 0xC6B5, 0xD2C9, 0xC6B6, 0xD2CB, + 0xC6B7, 0xD2D4, 0xC6B8, 0xD2D8, 0xC6B9, 0xD2DC, 0xC6BA, 0xD2E4, + 0xC6BB, 0xD2E5, 0xC6BC, 0xD2F0, 0xC6BD, 0xD2F1, 0xC6BE, 0xD2F4, + 0xC6BF, 0xD2F8, 0xC6C0, 0xD300, 0xC6C1, 0xD301, 0xC6C2, 0xD303, + 0xC6C3, 0xD305, 0xC6C4, 0xD30C, 0xC6C5, 0xD30D, 0xC6C6, 0xD30E, + 0xC6C7, 0xD310, 0xC6C8, 0xD314, 0xC6C9, 0xD316, 0xC6CA, 0xD31C, + 0xC6CB, 0xD31D, 0xC6CC, 0xD31F, 0xC6CD, 0xD320, 0xC6CE, 0xD321, + 0xC6CF, 0xD325, 0xC6D0, 0xD328, 0xC6D1, 0xD329, 0xC6D2, 0xD32C, + 0xC6D3, 0xD330, 0xC6D4, 0xD338, 0xC6D5, 0xD339, 0xC6D6, 0xD33B, + 0xC6D7, 0xD33C, 0xC6D8, 0xD33D, 0xC6D9, 0xD344, 0xC6DA, 0xD345, + 0xC6DB, 0xD37C, 0xC6DC, 0xD37D, 0xC6DD, 0xD380, 0xC6DE, 0xD384, + 0xC6DF, 0xD38C, 0xC6E0, 0xD38D, 0xC6E1, 0xD38F, 0xC6E2, 0xD390, + 0xC6E3, 0xD391, 0xC6E4, 0xD398, 0xC6E5, 0xD399, 0xC6E6, 0xD39C, + 0xC6E7, 0xD3A0, 0xC6E8, 0xD3A8, 0xC6E9, 0xD3A9, 0xC6EA, 0xD3AB, + 0xC6EB, 0xD3AD, 0xC6EC, 0xD3B4, 0xC6ED, 0xD3B8, 0xC6EE, 0xD3BC, + 0xC6EF, 0xD3C4, 0xC6F0, 0xD3C5, 0xC6F1, 0xD3C8, 0xC6F2, 0xD3C9, + 0xC6F3, 0xD3D0, 0xC6F4, 0xD3D8, 0xC6F5, 0xD3E1, 0xC6F6, 0xD3E3, + 0xC6F7, 0xD3EC, 0xC6F8, 0xD3ED, 0xC6F9, 0xD3F0, 0xC6FA, 0xD3F4, + 0xC6FB, 0xD3FC, 0xC6FC, 0xD3FD, 0xC6FD, 0xD3FF, 0xC6FE, 0xD401, + 0xC7A1, 0xD408, 0xC7A2, 0xD41D, 0xC7A3, 0xD440, 0xC7A4, 0xD444, + 0xC7A5, 0xD45C, 0xC7A6, 0xD460, 0xC7A7, 0xD464, 0xC7A8, 0xD46D, + 0xC7A9, 0xD46F, 0xC7AA, 0xD478, 0xC7AB, 0xD479, 0xC7AC, 0xD47C, + 0xC7AD, 0xD47F, 0xC7AE, 0xD480, 0xC7AF, 0xD482, 0xC7B0, 0xD488, + 0xC7B1, 0xD489, 0xC7B2, 0xD48B, 0xC7B3, 0xD48D, 0xC7B4, 0xD494, + 0xC7B5, 0xD4A9, 0xC7B6, 0xD4CC, 0xC7B7, 0xD4D0, 0xC7B8, 0xD4D4, + 0xC7B9, 0xD4DC, 0xC7BA, 0xD4DF, 0xC7BB, 0xD4E8, 0xC7BC, 0xD4EC, + 0xC7BD, 0xD4F0, 0xC7BE, 0xD4F8, 0xC7BF, 0xD4FB, 0xC7C0, 0xD4FD, + 0xC7C1, 0xD504, 0xC7C2, 0xD508, 0xC7C3, 0xD50C, 0xC7C4, 0xD514, + 0xC7C5, 0xD515, 0xC7C6, 0xD517, 0xC7C7, 0xD53C, 0xC7C8, 0xD53D, + 0xC7C9, 0xD540, 0xC7CA, 0xD544, 0xC7CB, 0xD54C, 0xC7CC, 0xD54D, + 0xC7CD, 0xD54F, 0xC7CE, 0xD551, 0xC7CF, 0xD558, 0xC7D0, 0xD559, + 0xC7D1, 0xD55C, 0xC7D2, 0xD560, 0xC7D3, 0xD565, 0xC7D4, 0xD568, + 0xC7D5, 0xD569, 0xC7D6, 0xD56B, 0xC7D7, 0xD56D, 0xC7D8, 0xD574, + 0xC7D9, 0xD575, 0xC7DA, 0xD578, 0xC7DB, 0xD57C, 0xC7DC, 0xD584, + 0xC7DD, 0xD585, 0xC7DE, 0xD587, 0xC7DF, 0xD588, 0xC7E0, 0xD589, + 0xC7E1, 0xD590, 0xC7E2, 0xD5A5, 0xC7E3, 0xD5C8, 0xC7E4, 0xD5C9, + 0xC7E5, 0xD5CC, 0xC7E6, 0xD5D0, 0xC7E7, 0xD5D2, 0xC7E8, 0xD5D8, + 0xC7E9, 0xD5D9, 0xC7EA, 0xD5DB, 0xC7EB, 0xD5DD, 0xC7EC, 0xD5E4, + 0xC7ED, 0xD5E5, 0xC7EE, 0xD5E8, 0xC7EF, 0xD5EC, 0xC7F0, 0xD5F4, + 0xC7F1, 0xD5F5, 0xC7F2, 0xD5F7, 0xC7F3, 0xD5F9, 0xC7F4, 0xD600, + 0xC7F5, 0xD601, 0xC7F6, 0xD604, 0xC7F7, 0xD608, 0xC7F8, 0xD610, + 0xC7F9, 0xD611, 0xC7FA, 0xD613, 0xC7FB, 0xD614, 0xC7FC, 0xD615, + 0xC7FD, 0xD61C, 0xC7FE, 0xD620, 0xC8A1, 0xD624, 0xC8A2, 0xD62D, + 0xC8A3, 0xD638, 0xC8A4, 0xD639, 0xC8A5, 0xD63C, 0xC8A6, 0xD640, + 0xC8A7, 0xD645, 0xC8A8, 0xD648, 0xC8A9, 0xD649, 0xC8AA, 0xD64B, + 0xC8AB, 0xD64D, 0xC8AC, 0xD651, 0xC8AD, 0xD654, 0xC8AE, 0xD655, + 0xC8AF, 0xD658, 0xC8B0, 0xD65C, 0xC8B1, 0xD667, 0xC8B2, 0xD669, + 0xC8B3, 0xD670, 0xC8B4, 0xD671, 0xC8B5, 0xD674, 0xC8B6, 0xD683, + 0xC8B7, 0xD685, 0xC8B8, 0xD68C, 0xC8B9, 0xD68D, 0xC8BA, 0xD690, + 0xC8BB, 0xD694, 0xC8BC, 0xD69D, 0xC8BD, 0xD69F, 0xC8BE, 0xD6A1, + 0xC8BF, 0xD6A8, 0xC8C0, 0xD6AC, 0xC8C1, 0xD6B0, 0xC8C2, 0xD6B9, + 0xC8C3, 0xD6BB, 0xC8C4, 0xD6C4, 0xC8C5, 0xD6C5, 0xC8C6, 0xD6C8, + 0xC8C7, 0xD6CC, 0xC8C8, 0xD6D1, 0xC8C9, 0xD6D4, 0xC8CA, 0xD6D7, + 0xC8CB, 0xD6D9, 0xC8CC, 0xD6E0, 0xC8CD, 0xD6E4, 0xC8CE, 0xD6E8, + 0xC8CF, 0xD6F0, 0xC8D0, 0xD6F5, 0xC8D1, 0xD6FC, 0xC8D2, 0xD6FD, + 0xC8D3, 0xD700, 0xC8D4, 0xD704, 0xC8D5, 0xD711, 0xC8D6, 0xD718, + 0xC8D7, 0xD719, 0xC8D8, 0xD71C, 0xC8D9, 0xD720, 0xC8DA, 0xD728, + 0xC8DB, 0xD729, 0xC8DC, 0xD72B, 0xC8DD, 0xD72D, 0xC8DE, 0xD734, + 0xC8DF, 0xD735, 0xC8E0, 0xD738, 0xC8E1, 0xD73C, 0xC8E2, 0xD744, + 0xC8E3, 0xD747, 0xC8E4, 0xD749, 0xC8E5, 0xD750, 0xC8E6, 0xD751, + 0xC8E7, 0xD754, 0xC8E8, 0xD756, 0xC8E9, 0xD757, 0xC8EA, 0xD758, + 0xC8EB, 0xD759, 0xC8EC, 0xD760, 0xC8ED, 0xD761, 0xC8EE, 0xD763, + 0xC8EF, 0xD765, 0xC8F0, 0xD769, 0xC8F1, 0xD76C, 0xC8F2, 0xD770, + 0xC8F3, 0xD774, 0xC8F4, 0xD77C, 0xC8F5, 0xD77D, 0xC8F6, 0xD781, + 0xC8F7, 0xD788, 0xC8F8, 0xD789, 0xC8F9, 0xD78C, 0xC8FA, 0xD790, + 0xC8FB, 0xD798, 0xC8FC, 0xD799, 0xC8FD, 0xD79B, 0xC8FE, 0xD79D, + 0xCAA1, 0x4F3D, 0xCAA2, 0x4F73, 0xCAA3, 0x5047, 0xCAA4, 0x50F9, + 0xCAA5, 0x52A0, 0xCAA6, 0x53EF, 0xCAA7, 0x5475, 0xCAA8, 0x54E5, + 0xCAA9, 0x5609, 0xCAAA, 0x5AC1, 0xCAAB, 0x5BB6, 0xCAAC, 0x6687, + 0xCAAD, 0x67B6, 0xCAAE, 0x67B7, 0xCAAF, 0x67EF, 0xCAB0, 0x6B4C, + 0xCAB1, 0x73C2, 0xCAB2, 0x75C2, 0xCAB3, 0x7A3C, 0xCAB4, 0x82DB, + 0xCAB5, 0x8304, 0xCAB6, 0x8857, 0xCAB7, 0x8888, 0xCAB8, 0x8A36, + 0xCAB9, 0x8CC8, 0xCABA, 0x8DCF, 0xCABB, 0x8EFB, 0xCABC, 0x8FE6, + 0xCABD, 0x99D5, 0xCABE, 0x523B, 0xCABF, 0x5374, 0xCAC0, 0x5404, + 0xCAC1, 0x606A, 0xCAC2, 0x6164, 0xCAC3, 0x6BBC, 0xCAC4, 0x73CF, + 0xCAC5, 0x811A, 0xCAC6, 0x89BA, 0xCAC7, 0x89D2, 0xCAC8, 0x95A3, + 0xCAC9, 0x4F83, 0xCACA, 0x520A, 0xCACB, 0x58BE, 0xCACC, 0x5978, + 0xCACD, 0x59E6, 0xCACE, 0x5E72, 0xCACF, 0x5E79, 0xCAD0, 0x61C7, + 0xCAD1, 0x63C0, 0xCAD2, 0x6746, 0xCAD3, 0x67EC, 0xCAD4, 0x687F, + 0xCAD5, 0x6F97, 0xCAD6, 0x764E, 0xCAD7, 0x770B, 0xCAD8, 0x78F5, + 0xCAD9, 0x7A08, 0xCADA, 0x7AFF, 0xCADB, 0x7C21, 0xCADC, 0x809D, + 0xCADD, 0x826E, 0xCADE, 0x8271, 0xCADF, 0x8AEB, 0xCAE0, 0x9593, + 0xCAE1, 0x4E6B, 0xCAE2, 0x559D, 0xCAE3, 0x66F7, 0xCAE4, 0x6E34, + 0xCAE5, 0x78A3, 0xCAE6, 0x7AED, 0xCAE7, 0x845B, 0xCAE8, 0x8910, + 0xCAE9, 0x874E, 0xCAEA, 0x97A8, 0xCAEB, 0x52D8, 0xCAEC, 0x574E, + 0xCAED, 0x582A, 0xCAEE, 0x5D4C, 0xCAEF, 0x611F, 0xCAF0, 0x61BE, + 0xCAF1, 0x6221, 0xCAF2, 0x6562, 0xCAF3, 0x67D1, 0xCAF4, 0x6A44, + 0xCAF5, 0x6E1B, 0xCAF6, 0x7518, 0xCAF7, 0x75B3, 0xCAF8, 0x76E3, + 0xCAF9, 0x77B0, 0xCAFA, 0x7D3A, 0xCAFB, 0x90AF, 0xCAFC, 0x9451, + 0xCAFD, 0x9452, 0xCAFE, 0x9F95, 0xCBA1, 0x5323, 0xCBA2, 0x5CAC, + 0xCBA3, 0x7532, 0xCBA4, 0x80DB, 0xCBA5, 0x9240, 0xCBA6, 0x9598, + 0xCBA7, 0x525B, 0xCBA8, 0x5808, 0xCBA9, 0x59DC, 0xCBAA, 0x5CA1, + 0xCBAB, 0x5D17, 0xCBAC, 0x5EB7, 0xCBAD, 0x5F3A, 0xCBAE, 0x5F4A, + 0xCBAF, 0x6177, 0xCBB0, 0x6C5F, 0xCBB1, 0x757A, 0xCBB2, 0x7586, + 0xCBB3, 0x7CE0, 0xCBB4, 0x7D73, 0xCBB5, 0x7DB1, 0xCBB6, 0x7F8C, + 0xCBB7, 0x8154, 0xCBB8, 0x8221, 0xCBB9, 0x8591, 0xCBBA, 0x8941, + 0xCBBB, 0x8B1B, 0xCBBC, 0x92FC, 0xCBBD, 0x964D, 0xCBBE, 0x9C47, + 0xCBBF, 0x4ECB, 0xCBC0, 0x4EF7, 0xCBC1, 0x500B, 0xCBC2, 0x51F1, + 0xCBC3, 0x584F, 0xCBC4, 0x6137, 0xCBC5, 0x613E, 0xCBC6, 0x6168, + 0xCBC7, 0x6539, 0xCBC8, 0x69EA, 0xCBC9, 0x6F11, 0xCBCA, 0x75A5, + 0xCBCB, 0x7686, 0xCBCC, 0x76D6, 0xCBCD, 0x7B87, 0xCBCE, 0x82A5, + 0xCBCF, 0x84CB, 0xCBD0, 0xF900, 0xCBD1, 0x93A7, 0xCBD2, 0x958B, + 0xCBD3, 0x5580, 0xCBD4, 0x5BA2, 0xCBD5, 0x5751, 0xCBD6, 0xF901, + 0xCBD7, 0x7CB3, 0xCBD8, 0x7FB9, 0xCBD9, 0x91B5, 0xCBDA, 0x5028, + 0xCBDB, 0x53BB, 0xCBDC, 0x5C45, 0xCBDD, 0x5DE8, 0xCBDE, 0x62D2, + 0xCBDF, 0x636E, 0xCBE0, 0x64DA, 0xCBE1, 0x64E7, 0xCBE2, 0x6E20, + 0xCBE3, 0x70AC, 0xCBE4, 0x795B, 0xCBE5, 0x8DDD, 0xCBE6, 0x8E1E, + 0xCBE7, 0xF902, 0xCBE8, 0x907D, 0xCBE9, 0x9245, 0xCBEA, 0x92F8, + 0xCBEB, 0x4E7E, 0xCBEC, 0x4EF6, 0xCBED, 0x5065, 0xCBEE, 0x5DFE, + 0xCBEF, 0x5EFA, 0xCBF0, 0x6106, 0xCBF1, 0x6957, 0xCBF2, 0x8171, + 0xCBF3, 0x8654, 0xCBF4, 0x8E47, 0xCBF5, 0x9375, 0xCBF6, 0x9A2B, + 0xCBF7, 0x4E5E, 0xCBF8, 0x5091, 0xCBF9, 0x6770, 0xCBFA, 0x6840, + 0xCBFB, 0x5109, 0xCBFC, 0x528D, 0xCBFD, 0x5292, 0xCBFE, 0x6AA2, + 0xCCA1, 0x77BC, 0xCCA2, 0x9210, 0xCCA3, 0x9ED4, 0xCCA4, 0x52AB, + 0xCCA5, 0x602F, 0xCCA6, 0x8FF2, 0xCCA7, 0x5048, 0xCCA8, 0x61A9, + 0xCCA9, 0x63ED, 0xCCAA, 0x64CA, 0xCCAB, 0x683C, 0xCCAC, 0x6A84, + 0xCCAD, 0x6FC0, 0xCCAE, 0x8188, 0xCCAF, 0x89A1, 0xCCB0, 0x9694, + 0xCCB1, 0x5805, 0xCCB2, 0x727D, 0xCCB3, 0x72AC, 0xCCB4, 0x7504, + 0xCCB5, 0x7D79, 0xCCB6, 0x7E6D, 0xCCB7, 0x80A9, 0xCCB8, 0x898B, + 0xCCB9, 0x8B74, 0xCCBA, 0x9063, 0xCCBB, 0x9D51, 0xCCBC, 0x6289, + 0xCCBD, 0x6C7A, 0xCCBE, 0x6F54, 0xCCBF, 0x7D50, 0xCCC0, 0x7F3A, + 0xCCC1, 0x8A23, 0xCCC2, 0x517C, 0xCCC3, 0x614A, 0xCCC4, 0x7B9D, + 0xCCC5, 0x8B19, 0xCCC6, 0x9257, 0xCCC7, 0x938C, 0xCCC8, 0x4EAC, + 0xCCC9, 0x4FD3, 0xCCCA, 0x501E, 0xCCCB, 0x50BE, 0xCCCC, 0x5106, + 0xCCCD, 0x52C1, 0xCCCE, 0x52CD, 0xCCCF, 0x537F, 0xCCD0, 0x5770, + 0xCCD1, 0x5883, 0xCCD2, 0x5E9A, 0xCCD3, 0x5F91, 0xCCD4, 0x6176, + 0xCCD5, 0x61AC, 0xCCD6, 0x64CE, 0xCCD7, 0x656C, 0xCCD8, 0x666F, + 0xCCD9, 0x66BB, 0xCCDA, 0x66F4, 0xCCDB, 0x6897, 0xCCDC, 0x6D87, + 0xCCDD, 0x7085, 0xCCDE, 0x70F1, 0xCCDF, 0x749F, 0xCCE0, 0x74A5, + 0xCCE1, 0x74CA, 0xCCE2, 0x75D9, 0xCCE3, 0x786C, 0xCCE4, 0x78EC, + 0xCCE5, 0x7ADF, 0xCCE6, 0x7AF6, 0xCCE7, 0x7D45, 0xCCE8, 0x7D93, + 0xCCE9, 0x8015, 0xCCEA, 0x803F, 0xCCEB, 0x811B, 0xCCEC, 0x8396, + 0xCCED, 0x8B66, 0xCCEE, 0x8F15, 0xCCEF, 0x9015, 0xCCF0, 0x93E1, + 0xCCF1, 0x9803, 0xCCF2, 0x9838, 0xCCF3, 0x9A5A, 0xCCF4, 0x9BE8, + 0xCCF5, 0x4FC2, 0xCCF6, 0x5553, 0xCCF7, 0x583A, 0xCCF8, 0x5951, + 0xCCF9, 0x5B63, 0xCCFA, 0x5C46, 0xCCFB, 0x60B8, 0xCCFC, 0x6212, + 0xCCFD, 0x6842, 0xCCFE, 0x68B0, 0xCDA1, 0x68E8, 0xCDA2, 0x6EAA, + 0xCDA3, 0x754C, 0xCDA4, 0x7678, 0xCDA5, 0x78CE, 0xCDA6, 0x7A3D, + 0xCDA7, 0x7CFB, 0xCDA8, 0x7E6B, 0xCDA9, 0x7E7C, 0xCDAA, 0x8A08, + 0xCDAB, 0x8AA1, 0xCDAC, 0x8C3F, 0xCDAD, 0x968E, 0xCDAE, 0x9DC4, + 0xCDAF, 0x53E4, 0xCDB0, 0x53E9, 0xCDB1, 0x544A, 0xCDB2, 0x5471, + 0xCDB3, 0x56FA, 0xCDB4, 0x59D1, 0xCDB5, 0x5B64, 0xCDB6, 0x5C3B, + 0xCDB7, 0x5EAB, 0xCDB8, 0x62F7, 0xCDB9, 0x6537, 0xCDBA, 0x6545, + 0xCDBB, 0x6572, 0xCDBC, 0x66A0, 0xCDBD, 0x67AF, 0xCDBE, 0x69C1, + 0xCDBF, 0x6CBD, 0xCDC0, 0x75FC, 0xCDC1, 0x7690, 0xCDC2, 0x777E, + 0xCDC3, 0x7A3F, 0xCDC4, 0x7F94, 0xCDC5, 0x8003, 0xCDC6, 0x80A1, + 0xCDC7, 0x818F, 0xCDC8, 0x82E6, 0xCDC9, 0x82FD, 0xCDCA, 0x83F0, + 0xCDCB, 0x85C1, 0xCDCC, 0x8831, 0xCDCD, 0x88B4, 0xCDCE, 0x8AA5, + 0xCDCF, 0xF903, 0xCDD0, 0x8F9C, 0xCDD1, 0x932E, 0xCDD2, 0x96C7, + 0xCDD3, 0x9867, 0xCDD4, 0x9AD8, 0xCDD5, 0x9F13, 0xCDD6, 0x54ED, + 0xCDD7, 0x659B, 0xCDD8, 0x66F2, 0xCDD9, 0x688F, 0xCDDA, 0x7A40, + 0xCDDB, 0x8C37, 0xCDDC, 0x9D60, 0xCDDD, 0x56F0, 0xCDDE, 0x5764, + 0xCDDF, 0x5D11, 0xCDE0, 0x6606, 0xCDE1, 0x68B1, 0xCDE2, 0x68CD, + 0xCDE3, 0x6EFE, 0xCDE4, 0x7428, 0xCDE5, 0x889E, 0xCDE6, 0x9BE4, + 0xCDE7, 0x6C68, 0xCDE8, 0xF904, 0xCDE9, 0x9AA8, 0xCDEA, 0x4F9B, + 0xCDEB, 0x516C, 0xCDEC, 0x5171, 0xCDED, 0x529F, 0xCDEE, 0x5B54, + 0xCDEF, 0x5DE5, 0xCDF0, 0x6050, 0xCDF1, 0x606D, 0xCDF2, 0x62F1, + 0xCDF3, 0x63A7, 0xCDF4, 0x653B, 0xCDF5, 0x73D9, 0xCDF6, 0x7A7A, + 0xCDF7, 0x86A3, 0xCDF8, 0x8CA2, 0xCDF9, 0x978F, 0xCDFA, 0x4E32, + 0xCDFB, 0x5BE1, 0xCDFC, 0x6208, 0xCDFD, 0x679C, 0xCDFE, 0x74DC, + 0xCEA1, 0x79D1, 0xCEA2, 0x83D3, 0xCEA3, 0x8A87, 0xCEA4, 0x8AB2, + 0xCEA5, 0x8DE8, 0xCEA6, 0x904E, 0xCEA7, 0x934B, 0xCEA8, 0x9846, + 0xCEA9, 0x5ED3, 0xCEAA, 0x69E8, 0xCEAB, 0x85FF, 0xCEAC, 0x90ED, + 0xCEAD, 0xF905, 0xCEAE, 0x51A0, 0xCEAF, 0x5B98, 0xCEB0, 0x5BEC, + 0xCEB1, 0x6163, 0xCEB2, 0x68FA, 0xCEB3, 0x6B3E, 0xCEB4, 0x704C, + 0xCEB5, 0x742F, 0xCEB6, 0x74D8, 0xCEB7, 0x7BA1, 0xCEB8, 0x7F50, + 0xCEB9, 0x83C5, 0xCEBA, 0x89C0, 0xCEBB, 0x8CAB, 0xCEBC, 0x95DC, + 0xCEBD, 0x9928, 0xCEBE, 0x522E, 0xCEBF, 0x605D, 0xCEC0, 0x62EC, + 0xCEC1, 0x9002, 0xCEC2, 0x4F8A, 0xCEC3, 0x5149, 0xCEC4, 0x5321, + 0xCEC5, 0x58D9, 0xCEC6, 0x5EE3, 0xCEC7, 0x66E0, 0xCEC8, 0x6D38, + 0xCEC9, 0x709A, 0xCECA, 0x72C2, 0xCECB, 0x73D6, 0xCECC, 0x7B50, + 0xCECD, 0x80F1, 0xCECE, 0x945B, 0xCECF, 0x5366, 0xCED0, 0x639B, + 0xCED1, 0x7F6B, 0xCED2, 0x4E56, 0xCED3, 0x5080, 0xCED4, 0x584A, + 0xCED5, 0x58DE, 0xCED6, 0x602A, 0xCED7, 0x6127, 0xCED8, 0x62D0, + 0xCED9, 0x69D0, 0xCEDA, 0x9B41, 0xCEDB, 0x5B8F, 0xCEDC, 0x7D18, + 0xCEDD, 0x80B1, 0xCEDE, 0x8F5F, 0xCEDF, 0x4EA4, 0xCEE0, 0x50D1, + 0xCEE1, 0x54AC, 0xCEE2, 0x55AC, 0xCEE3, 0x5B0C, 0xCEE4, 0x5DA0, + 0xCEE5, 0x5DE7, 0xCEE6, 0x652A, 0xCEE7, 0x654E, 0xCEE8, 0x6821, + 0xCEE9, 0x6A4B, 0xCEEA, 0x72E1, 0xCEEB, 0x768E, 0xCEEC, 0x77EF, + 0xCEED, 0x7D5E, 0xCEEE, 0x7FF9, 0xCEEF, 0x81A0, 0xCEF0, 0x854E, + 0xCEF1, 0x86DF, 0xCEF2, 0x8F03, 0xCEF3, 0x8F4E, 0xCEF4, 0x90CA, + 0xCEF5, 0x9903, 0xCEF6, 0x9A55, 0xCEF7, 0x9BAB, 0xCEF8, 0x4E18, + 0xCEF9, 0x4E45, 0xCEFA, 0x4E5D, 0xCEFB, 0x4EC7, 0xCEFC, 0x4FF1, + 0xCEFD, 0x5177, 0xCEFE, 0x52FE, 0xCFA1, 0x5340, 0xCFA2, 0x53E3, + 0xCFA3, 0x53E5, 0xCFA4, 0x548E, 0xCFA5, 0x5614, 0xCFA6, 0x5775, + 0xCFA7, 0x57A2, 0xCFA8, 0x5BC7, 0xCFA9, 0x5D87, 0xCFAA, 0x5ED0, + 0xCFAB, 0x61FC, 0xCFAC, 0x62D8, 0xCFAD, 0x6551, 0xCFAE, 0x67B8, + 0xCFAF, 0x67E9, 0xCFB0, 0x69CB, 0xCFB1, 0x6B50, 0xCFB2, 0x6BC6, + 0xCFB3, 0x6BEC, 0xCFB4, 0x6C42, 0xCFB5, 0x6E9D, 0xCFB6, 0x7078, + 0xCFB7, 0x72D7, 0xCFB8, 0x7396, 0xCFB9, 0x7403, 0xCFBA, 0x77BF, + 0xCFBB, 0x77E9, 0xCFBC, 0x7A76, 0xCFBD, 0x7D7F, 0xCFBE, 0x8009, + 0xCFBF, 0x81FC, 0xCFC0, 0x8205, 0xCFC1, 0x820A, 0xCFC2, 0x82DF, + 0xCFC3, 0x8862, 0xCFC4, 0x8B33, 0xCFC5, 0x8CFC, 0xCFC6, 0x8EC0, + 0xCFC7, 0x9011, 0xCFC8, 0x90B1, 0xCFC9, 0x9264, 0xCFCA, 0x92B6, + 0xCFCB, 0x99D2, 0xCFCC, 0x9A45, 0xCFCD, 0x9CE9, 0xCFCE, 0x9DD7, + 0xCFCF, 0x9F9C, 0xCFD0, 0x570B, 0xCFD1, 0x5C40, 0xCFD2, 0x83CA, + 0xCFD3, 0x97A0, 0xCFD4, 0x97AB, 0xCFD5, 0x9EB4, 0xCFD6, 0x541B, + 0xCFD7, 0x7A98, 0xCFD8, 0x7FA4, 0xCFD9, 0x88D9, 0xCFDA, 0x8ECD, + 0xCFDB, 0x90E1, 0xCFDC, 0x5800, 0xCFDD, 0x5C48, 0xCFDE, 0x6398, + 0xCFDF, 0x7A9F, 0xCFE0, 0x5BAE, 0xCFE1, 0x5F13, 0xCFE2, 0x7A79, + 0xCFE3, 0x7AAE, 0xCFE4, 0x828E, 0xCFE5, 0x8EAC, 0xCFE6, 0x5026, + 0xCFE7, 0x5238, 0xCFE8, 0x52F8, 0xCFE9, 0x5377, 0xCFEA, 0x5708, + 0xCFEB, 0x62F3, 0xCFEC, 0x6372, 0xCFED, 0x6B0A, 0xCFEE, 0x6DC3, + 0xCFEF, 0x7737, 0xCFF0, 0x53A5, 0xCFF1, 0x7357, 0xCFF2, 0x8568, + 0xCFF3, 0x8E76, 0xCFF4, 0x95D5, 0xCFF5, 0x673A, 0xCFF6, 0x6AC3, + 0xCFF7, 0x6F70, 0xCFF8, 0x8A6D, 0xCFF9, 0x8ECC, 0xCFFA, 0x994B, + 0xCFFB, 0xF906, 0xCFFC, 0x6677, 0xCFFD, 0x6B78, 0xCFFE, 0x8CB4, + 0xD0A1, 0x9B3C, 0xD0A2, 0xF907, 0xD0A3, 0x53EB, 0xD0A4, 0x572D, + 0xD0A5, 0x594E, 0xD0A6, 0x63C6, 0xD0A7, 0x69FB, 0xD0A8, 0x73EA, + 0xD0A9, 0x7845, 0xD0AA, 0x7ABA, 0xD0AB, 0x7AC5, 0xD0AC, 0x7CFE, + 0xD0AD, 0x8475, 0xD0AE, 0x898F, 0xD0AF, 0x8D73, 0xD0B0, 0x9035, + 0xD0B1, 0x95A8, 0xD0B2, 0x52FB, 0xD0B3, 0x5747, 0xD0B4, 0x7547, + 0xD0B5, 0x7B60, 0xD0B6, 0x83CC, 0xD0B7, 0x921E, 0xD0B8, 0xF908, + 0xD0B9, 0x6A58, 0xD0BA, 0x514B, 0xD0BB, 0x524B, 0xD0BC, 0x5287, + 0xD0BD, 0x621F, 0xD0BE, 0x68D8, 0xD0BF, 0x6975, 0xD0C0, 0x9699, + 0xD0C1, 0x50C5, 0xD0C2, 0x52A4, 0xD0C3, 0x52E4, 0xD0C4, 0x61C3, + 0xD0C5, 0x65A4, 0xD0C6, 0x6839, 0xD0C7, 0x69FF, 0xD0C8, 0x747E, + 0xD0C9, 0x7B4B, 0xD0CA, 0x82B9, 0xD0CB, 0x83EB, 0xD0CC, 0x89B2, + 0xD0CD, 0x8B39, 0xD0CE, 0x8FD1, 0xD0CF, 0x9949, 0xD0D0, 0xF909, + 0xD0D1, 0x4ECA, 0xD0D2, 0x5997, 0xD0D3, 0x64D2, 0xD0D4, 0x6611, + 0xD0D5, 0x6A8E, 0xD0D6, 0x7434, 0xD0D7, 0x7981, 0xD0D8, 0x79BD, + 0xD0D9, 0x82A9, 0xD0DA, 0x887E, 0xD0DB, 0x887F, 0xD0DC, 0x895F, + 0xD0DD, 0xF90A, 0xD0DE, 0x9326, 0xD0DF, 0x4F0B, 0xD0E0, 0x53CA, + 0xD0E1, 0x6025, 0xD0E2, 0x6271, 0xD0E3, 0x6C72, 0xD0E4, 0x7D1A, + 0xD0E5, 0x7D66, 0xD0E6, 0x4E98, 0xD0E7, 0x5162, 0xD0E8, 0x77DC, + 0xD0E9, 0x80AF, 0xD0EA, 0x4F01, 0xD0EB, 0x4F0E, 0xD0EC, 0x5176, + 0xD0ED, 0x5180, 0xD0EE, 0x55DC, 0xD0EF, 0x5668, 0xD0F0, 0x573B, + 0xD0F1, 0x57FA, 0xD0F2, 0x57FC, 0xD0F3, 0x5914, 0xD0F4, 0x5947, + 0xD0F5, 0x5993, 0xD0F6, 0x5BC4, 0xD0F7, 0x5C90, 0xD0F8, 0x5D0E, + 0xD0F9, 0x5DF1, 0xD0FA, 0x5E7E, 0xD0FB, 0x5FCC, 0xD0FC, 0x6280, + 0xD0FD, 0x65D7, 0xD0FE, 0x65E3, 0xD1A1, 0x671E, 0xD1A2, 0x671F, + 0xD1A3, 0x675E, 0xD1A4, 0x68CB, 0xD1A5, 0x68C4, 0xD1A6, 0x6A5F, + 0xD1A7, 0x6B3A, 0xD1A8, 0x6C23, 0xD1A9, 0x6C7D, 0xD1AA, 0x6C82, + 0xD1AB, 0x6DC7, 0xD1AC, 0x7398, 0xD1AD, 0x7426, 0xD1AE, 0x742A, + 0xD1AF, 0x7482, 0xD1B0, 0x74A3, 0xD1B1, 0x7578, 0xD1B2, 0x757F, + 0xD1B3, 0x7881, 0xD1B4, 0x78EF, 0xD1B5, 0x7941, 0xD1B6, 0x7947, + 0xD1B7, 0x7948, 0xD1B8, 0x797A, 0xD1B9, 0x7B95, 0xD1BA, 0x7D00, + 0xD1BB, 0x7DBA, 0xD1BC, 0x7F88, 0xD1BD, 0x8006, 0xD1BE, 0x802D, + 0xD1BF, 0x808C, 0xD1C0, 0x8A18, 0xD1C1, 0x8B4F, 0xD1C2, 0x8C48, + 0xD1C3, 0x8D77, 0xD1C4, 0x9321, 0xD1C5, 0x9324, 0xD1C6, 0x98E2, + 0xD1C7, 0x9951, 0xD1C8, 0x9A0E, 0xD1C9, 0x9A0F, 0xD1CA, 0x9A65, + 0xD1CB, 0x9E92, 0xD1CC, 0x7DCA, 0xD1CD, 0x4F76, 0xD1CE, 0x5409, + 0xD1CF, 0x62EE, 0xD1D0, 0x6854, 0xD1D1, 0x91D1, 0xD1D2, 0x55AB, + 0xD1D3, 0x513A, 0xD1D4, 0xF90B, 0xD1D5, 0xF90C, 0xD1D6, 0x5A1C, + 0xD1D7, 0x61E6, 0xD1D8, 0xF90D, 0xD1D9, 0x62CF, 0xD1DA, 0x62FF, + 0xD1DB, 0xF90E, 0xD1DC, 0xF90F, 0xD1DD, 0xF910, 0xD1DE, 0xF911, + 0xD1DF, 0xF912, 0xD1E0, 0xF913, 0xD1E1, 0x90A3, 0xD1E2, 0xF914, + 0xD1E3, 0xF915, 0xD1E4, 0xF916, 0xD1E5, 0xF917, 0xD1E6, 0xF918, + 0xD1E7, 0x8AFE, 0xD1E8, 0xF919, 0xD1E9, 0xF91A, 0xD1EA, 0xF91B, + 0xD1EB, 0xF91C, 0xD1EC, 0x6696, 0xD1ED, 0xF91D, 0xD1EE, 0x7156, + 0xD1EF, 0xF91E, 0xD1F0, 0xF91F, 0xD1F1, 0x96E3, 0xD1F2, 0xF920, + 0xD1F3, 0x634F, 0xD1F4, 0x637A, 0xD1F5, 0x5357, 0xD1F6, 0xF921, + 0xD1F7, 0x678F, 0xD1F8, 0x6960, 0xD1F9, 0x6E73, 0xD1FA, 0xF922, + 0xD1FB, 0x7537, 0xD1FC, 0xF923, 0xD1FD, 0xF924, 0xD1FE, 0xF925, + 0xD2A1, 0x7D0D, 0xD2A2, 0xF926, 0xD2A3, 0xF927, 0xD2A4, 0x8872, + 0xD2A5, 0x56CA, 0xD2A6, 0x5A18, 0xD2A7, 0xF928, 0xD2A8, 0xF929, + 0xD2A9, 0xF92A, 0xD2AA, 0xF92B, 0xD2AB, 0xF92C, 0xD2AC, 0x4E43, + 0xD2AD, 0xF92D, 0xD2AE, 0x5167, 0xD2AF, 0x5948, 0xD2B0, 0x67F0, + 0xD2B1, 0x8010, 0xD2B2, 0xF92E, 0xD2B3, 0x5973, 0xD2B4, 0x5E74, + 0xD2B5, 0x649A, 0xD2B6, 0x79CA, 0xD2B7, 0x5FF5, 0xD2B8, 0x606C, + 0xD2B9, 0x62C8, 0xD2BA, 0x637B, 0xD2BB, 0x5BE7, 0xD2BC, 0x5BD7, + 0xD2BD, 0x52AA, 0xD2BE, 0xF92F, 0xD2BF, 0x5974, 0xD2C0, 0x5F29, + 0xD2C1, 0x6012, 0xD2C2, 0xF930, 0xD2C3, 0xF931, 0xD2C4, 0xF932, + 0xD2C5, 0x7459, 0xD2C6, 0xF933, 0xD2C7, 0xF934, 0xD2C8, 0xF935, + 0xD2C9, 0xF936, 0xD2CA, 0xF937, 0xD2CB, 0xF938, 0xD2CC, 0x99D1, + 0xD2CD, 0xF939, 0xD2CE, 0xF93A, 0xD2CF, 0xF93B, 0xD2D0, 0xF93C, + 0xD2D1, 0xF93D, 0xD2D2, 0xF93E, 0xD2D3, 0xF93F, 0xD2D4, 0xF940, + 0xD2D5, 0xF941, 0xD2D6, 0xF942, 0xD2D7, 0xF943, 0xD2D8, 0x6FC3, + 0xD2D9, 0xF944, 0xD2DA, 0xF945, 0xD2DB, 0x81BF, 0xD2DC, 0x8FB2, + 0xD2DD, 0x60F1, 0xD2DE, 0xF946, 0xD2DF, 0xF947, 0xD2E0, 0x8166, + 0xD2E1, 0xF948, 0xD2E2, 0xF949, 0xD2E3, 0x5C3F, 0xD2E4, 0xF94A, + 0xD2E5, 0xF94B, 0xD2E6, 0xF94C, 0xD2E7, 0xF94D, 0xD2E8, 0xF94E, + 0xD2E9, 0xF94F, 0xD2EA, 0xF950, 0xD2EB, 0xF951, 0xD2EC, 0x5AE9, + 0xD2ED, 0x8A25, 0xD2EE, 0x677B, 0xD2EF, 0x7D10, 0xD2F0, 0xF952, + 0xD2F1, 0xF953, 0xD2F2, 0xF954, 0xD2F3, 0xF955, 0xD2F4, 0xF956, + 0xD2F5, 0xF957, 0xD2F6, 0x80FD, 0xD2F7, 0xF958, 0xD2F8, 0xF959, + 0xD2F9, 0x5C3C, 0xD2FA, 0x6CE5, 0xD2FB, 0x533F, 0xD2FC, 0x6EBA, + 0xD2FD, 0x591A, 0xD2FE, 0x8336, 0xD3A1, 0x4E39, 0xD3A2, 0x4EB6, + 0xD3A3, 0x4F46, 0xD3A4, 0x55AE, 0xD3A5, 0x5718, 0xD3A6, 0x58C7, + 0xD3A7, 0x5F56, 0xD3A8, 0x65B7, 0xD3A9, 0x65E6, 0xD3AA, 0x6A80, + 0xD3AB, 0x6BB5, 0xD3AC, 0x6E4D, 0xD3AD, 0x77ED, 0xD3AE, 0x7AEF, + 0xD3AF, 0x7C1E, 0xD3B0, 0x7DDE, 0xD3B1, 0x86CB, 0xD3B2, 0x8892, + 0xD3B3, 0x9132, 0xD3B4, 0x935B, 0xD3B5, 0x64BB, 0xD3B6, 0x6FBE, + 0xD3B7, 0x737A, 0xD3B8, 0x75B8, 0xD3B9, 0x9054, 0xD3BA, 0x5556, + 0xD3BB, 0x574D, 0xD3BC, 0x61BA, 0xD3BD, 0x64D4, 0xD3BE, 0x66C7, + 0xD3BF, 0x6DE1, 0xD3C0, 0x6E5B, 0xD3C1, 0x6F6D, 0xD3C2, 0x6FB9, + 0xD3C3, 0x75F0, 0xD3C4, 0x8043, 0xD3C5, 0x81BD, 0xD3C6, 0x8541, + 0xD3C7, 0x8983, 0xD3C8, 0x8AC7, 0xD3C9, 0x8B5A, 0xD3CA, 0x931F, + 0xD3CB, 0x6C93, 0xD3CC, 0x7553, 0xD3CD, 0x7B54, 0xD3CE, 0x8E0F, + 0xD3CF, 0x905D, 0xD3D0, 0x5510, 0xD3D1, 0x5802, 0xD3D2, 0x5858, + 0xD3D3, 0x5E62, 0xD3D4, 0x6207, 0xD3D5, 0x649E, 0xD3D6, 0x68E0, + 0xD3D7, 0x7576, 0xD3D8, 0x7CD6, 0xD3D9, 0x87B3, 0xD3DA, 0x9EE8, + 0xD3DB, 0x4EE3, 0xD3DC, 0x5788, 0xD3DD, 0x576E, 0xD3DE, 0x5927, + 0xD3DF, 0x5C0D, 0xD3E0, 0x5CB1, 0xD3E1, 0x5E36, 0xD3E2, 0x5F85, + 0xD3E3, 0x6234, 0xD3E4, 0x64E1, 0xD3E5, 0x73B3, 0xD3E6, 0x81FA, + 0xD3E7, 0x888B, 0xD3E8, 0x8CB8, 0xD3E9, 0x968A, 0xD3EA, 0x9EDB, + 0xD3EB, 0x5B85, 0xD3EC, 0x5FB7, 0xD3ED, 0x60B3, 0xD3EE, 0x5012, + 0xD3EF, 0x5200, 0xD3F0, 0x5230, 0xD3F1, 0x5716, 0xD3F2, 0x5835, + 0xD3F3, 0x5857, 0xD3F4, 0x5C0E, 0xD3F5, 0x5C60, 0xD3F6, 0x5CF6, + 0xD3F7, 0x5D8B, 0xD3F8, 0x5EA6, 0xD3F9, 0x5F92, 0xD3FA, 0x60BC, + 0xD3FB, 0x6311, 0xD3FC, 0x6389, 0xD3FD, 0x6417, 0xD3FE, 0x6843, + 0xD4A1, 0x68F9, 0xD4A2, 0x6AC2, 0xD4A3, 0x6DD8, 0xD4A4, 0x6E21, + 0xD4A5, 0x6ED4, 0xD4A6, 0x6FE4, 0xD4A7, 0x71FE, 0xD4A8, 0x76DC, + 0xD4A9, 0x7779, 0xD4AA, 0x79B1, 0xD4AB, 0x7A3B, 0xD4AC, 0x8404, + 0xD4AD, 0x89A9, 0xD4AE, 0x8CED, 0xD4AF, 0x8DF3, 0xD4B0, 0x8E48, + 0xD4B1, 0x9003, 0xD4B2, 0x9014, 0xD4B3, 0x9053, 0xD4B4, 0x90FD, + 0xD4B5, 0x934D, 0xD4B6, 0x9676, 0xD4B7, 0x97DC, 0xD4B8, 0x6BD2, + 0xD4B9, 0x7006, 0xD4BA, 0x7258, 0xD4BB, 0x72A2, 0xD4BC, 0x7368, + 0xD4BD, 0x7763, 0xD4BE, 0x79BF, 0xD4BF, 0x7BE4, 0xD4C0, 0x7E9B, + 0xD4C1, 0x8B80, 0xD4C2, 0x58A9, 0xD4C3, 0x60C7, 0xD4C4, 0x6566, + 0xD4C5, 0x65FD, 0xD4C6, 0x66BE, 0xD4C7, 0x6C8C, 0xD4C8, 0x711E, + 0xD4C9, 0x71C9, 0xD4CA, 0x8C5A, 0xD4CB, 0x9813, 0xD4CC, 0x4E6D, + 0xD4CD, 0x7A81, 0xD4CE, 0x4EDD, 0xD4CF, 0x51AC, 0xD4D0, 0x51CD, + 0xD4D1, 0x52D5, 0xD4D2, 0x540C, 0xD4D3, 0x61A7, 0xD4D4, 0x6771, + 0xD4D5, 0x6850, 0xD4D6, 0x68DF, 0xD4D7, 0x6D1E, 0xD4D8, 0x6F7C, + 0xD4D9, 0x75BC, 0xD4DA, 0x77B3, 0xD4DB, 0x7AE5, 0xD4DC, 0x80F4, + 0xD4DD, 0x8463, 0xD4DE, 0x9285, 0xD4DF, 0x515C, 0xD4E0, 0x6597, + 0xD4E1, 0x675C, 0xD4E2, 0x6793, 0xD4E3, 0x75D8, 0xD4E4, 0x7AC7, + 0xD4E5, 0x8373, 0xD4E6, 0xF95A, 0xD4E7, 0x8C46, 0xD4E8, 0x9017, + 0xD4E9, 0x982D, 0xD4EA, 0x5C6F, 0xD4EB, 0x81C0, 0xD4EC, 0x829A, + 0xD4ED, 0x9041, 0xD4EE, 0x906F, 0xD4EF, 0x920D, 0xD4F0, 0x5F97, + 0xD4F1, 0x5D9D, 0xD4F2, 0x6A59, 0xD4F3, 0x71C8, 0xD4F4, 0x767B, + 0xD4F5, 0x7B49, 0xD4F6, 0x85E4, 0xD4F7, 0x8B04, 0xD4F8, 0x9127, + 0xD4F9, 0x9A30, 0xD4FA, 0x5587, 0xD4FB, 0x61F6, 0xD4FC, 0xF95B, + 0xD4FD, 0x7669, 0xD4FE, 0x7F85, 0xD5A1, 0x863F, 0xD5A2, 0x87BA, + 0xD5A3, 0x88F8, 0xD5A4, 0x908F, 0xD5A5, 0xF95C, 0xD5A6, 0x6D1B, + 0xD5A7, 0x70D9, 0xD5A8, 0x73DE, 0xD5A9, 0x7D61, 0xD5AA, 0x843D, + 0xD5AB, 0xF95D, 0xD5AC, 0x916A, 0xD5AD, 0x99F1, 0xD5AE, 0xF95E, + 0xD5AF, 0x4E82, 0xD5B0, 0x5375, 0xD5B1, 0x6B04, 0xD5B2, 0x6B12, + 0xD5B3, 0x703E, 0xD5B4, 0x721B, 0xD5B5, 0x862D, 0xD5B6, 0x9E1E, + 0xD5B7, 0x524C, 0xD5B8, 0x8FA3, 0xD5B9, 0x5D50, 0xD5BA, 0x64E5, + 0xD5BB, 0x652C, 0xD5BC, 0x6B16, 0xD5BD, 0x6FEB, 0xD5BE, 0x7C43, + 0xD5BF, 0x7E9C, 0xD5C0, 0x85CD, 0xD5C1, 0x8964, 0xD5C2, 0x89BD, + 0xD5C3, 0x62C9, 0xD5C4, 0x81D8, 0xD5C5, 0x881F, 0xD5C6, 0x5ECA, + 0xD5C7, 0x6717, 0xD5C8, 0x6D6A, 0xD5C9, 0x72FC, 0xD5CA, 0x7405, + 0xD5CB, 0x746F, 0xD5CC, 0x8782, 0xD5CD, 0x90DE, 0xD5CE, 0x4F86, + 0xD5CF, 0x5D0D, 0xD5D0, 0x5FA0, 0xD5D1, 0x840A, 0xD5D2, 0x51B7, + 0xD5D3, 0x63A0, 0xD5D4, 0x7565, 0xD5D5, 0x4EAE, 0xD5D6, 0x5006, + 0xD5D7, 0x5169, 0xD5D8, 0x51C9, 0xD5D9, 0x6881, 0xD5DA, 0x6A11, + 0xD5DB, 0x7CAE, 0xD5DC, 0x7CB1, 0xD5DD, 0x7CE7, 0xD5DE, 0x826F, + 0xD5DF, 0x8AD2, 0xD5E0, 0x8F1B, 0xD5E1, 0x91CF, 0xD5E2, 0x4FB6, + 0xD5E3, 0x5137, 0xD5E4, 0x52F5, 0xD5E5, 0x5442, 0xD5E6, 0x5EEC, + 0xD5E7, 0x616E, 0xD5E8, 0x623E, 0xD5E9, 0x65C5, 0xD5EA, 0x6ADA, + 0xD5EB, 0x6FFE, 0xD5EC, 0x792A, 0xD5ED, 0x85DC, 0xD5EE, 0x8823, + 0xD5EF, 0x95AD, 0xD5F0, 0x9A62, 0xD5F1, 0x9A6A, 0xD5F2, 0x9E97, + 0xD5F3, 0x9ECE, 0xD5F4, 0x529B, 0xD5F5, 0x66C6, 0xD5F6, 0x6B77, + 0xD5F7, 0x701D, 0xD5F8, 0x792B, 0xD5F9, 0x8F62, 0xD5FA, 0x9742, + 0xD5FB, 0x6190, 0xD5FC, 0x6200, 0xD5FD, 0x6523, 0xD5FE, 0x6F23, + 0xD6A1, 0x7149, 0xD6A2, 0x7489, 0xD6A3, 0x7DF4, 0xD6A4, 0x806F, + 0xD6A5, 0x84EE, 0xD6A6, 0x8F26, 0xD6A7, 0x9023, 0xD6A8, 0x934A, + 0xD6A9, 0x51BD, 0xD6AA, 0x5217, 0xD6AB, 0x52A3, 0xD6AC, 0x6D0C, + 0xD6AD, 0x70C8, 0xD6AE, 0x88C2, 0xD6AF, 0x5EC9, 0xD6B0, 0x6582, + 0xD6B1, 0x6BAE, 0xD6B2, 0x6FC2, 0xD6B3, 0x7C3E, 0xD6B4, 0x7375, + 0xD6B5, 0x4EE4, 0xD6B6, 0x4F36, 0xD6B7, 0x56F9, 0xD6B8, 0xF95F, + 0xD6B9, 0x5CBA, 0xD6BA, 0x5DBA, 0xD6BB, 0x601C, 0xD6BC, 0x73B2, + 0xD6BD, 0x7B2D, 0xD6BE, 0x7F9A, 0xD6BF, 0x7FCE, 0xD6C0, 0x8046, + 0xD6C1, 0x901E, 0xD6C2, 0x9234, 0xD6C3, 0x96F6, 0xD6C4, 0x9748, + 0xD6C5, 0x9818, 0xD6C6, 0x9F61, 0xD6C7, 0x4F8B, 0xD6C8, 0x6FA7, + 0xD6C9, 0x79AE, 0xD6CA, 0x91B4, 0xD6CB, 0x96B7, 0xD6CC, 0x52DE, + 0xD6CD, 0xF960, 0xD6CE, 0x6488, 0xD6CF, 0x64C4, 0xD6D0, 0x6AD3, + 0xD6D1, 0x6F5E, 0xD6D2, 0x7018, 0xD6D3, 0x7210, 0xD6D4, 0x76E7, + 0xD6D5, 0x8001, 0xD6D6, 0x8606, 0xD6D7, 0x865C, 0xD6D8, 0x8DEF, + 0xD6D9, 0x8F05, 0xD6DA, 0x9732, 0xD6DB, 0x9B6F, 0xD6DC, 0x9DFA, + 0xD6DD, 0x9E75, 0xD6DE, 0x788C, 0xD6DF, 0x797F, 0xD6E0, 0x7DA0, + 0xD6E1, 0x83C9, 0xD6E2, 0x9304, 0xD6E3, 0x9E7F, 0xD6E4, 0x9E93, + 0xD6E5, 0x8AD6, 0xD6E6, 0x58DF, 0xD6E7, 0x5F04, 0xD6E8, 0x6727, + 0xD6E9, 0x7027, 0xD6EA, 0x74CF, 0xD6EB, 0x7C60, 0xD6EC, 0x807E, + 0xD6ED, 0x5121, 0xD6EE, 0x7028, 0xD6EF, 0x7262, 0xD6F0, 0x78CA, + 0xD6F1, 0x8CC2, 0xD6F2, 0x8CDA, 0xD6F3, 0x8CF4, 0xD6F4, 0x96F7, + 0xD6F5, 0x4E86, 0xD6F6, 0x50DA, 0xD6F7, 0x5BEE, 0xD6F8, 0x5ED6, + 0xD6F9, 0x6599, 0xD6FA, 0x71CE, 0xD6FB, 0x7642, 0xD6FC, 0x77AD, + 0xD6FD, 0x804A, 0xD6FE, 0x84FC, 0xD7A1, 0x907C, 0xD7A2, 0x9B27, + 0xD7A3, 0x9F8D, 0xD7A4, 0x58D8, 0xD7A5, 0x5A41, 0xD7A6, 0x5C62, + 0xD7A7, 0x6A13, 0xD7A8, 0x6DDA, 0xD7A9, 0x6F0F, 0xD7AA, 0x763B, + 0xD7AB, 0x7D2F, 0xD7AC, 0x7E37, 0xD7AD, 0x851E, 0xD7AE, 0x8938, + 0xD7AF, 0x93E4, 0xD7B0, 0x964B, 0xD7B1, 0x5289, 0xD7B2, 0x65D2, + 0xD7B3, 0x67F3, 0xD7B4, 0x69B4, 0xD7B5, 0x6D41, 0xD7B6, 0x6E9C, + 0xD7B7, 0x700F, 0xD7B8, 0x7409, 0xD7B9, 0x7460, 0xD7BA, 0x7559, + 0xD7BB, 0x7624, 0xD7BC, 0x786B, 0xD7BD, 0x8B2C, 0xD7BE, 0x985E, + 0xD7BF, 0x516D, 0xD7C0, 0x622E, 0xD7C1, 0x9678, 0xD7C2, 0x4F96, + 0xD7C3, 0x502B, 0xD7C4, 0x5D19, 0xD7C5, 0x6DEA, 0xD7C6, 0x7DB8, + 0xD7C7, 0x8F2A, 0xD7C8, 0x5F8B, 0xD7C9, 0x6144, 0xD7CA, 0x6817, + 0xD7CB, 0xF961, 0xD7CC, 0x9686, 0xD7CD, 0x52D2, 0xD7CE, 0x808B, + 0xD7CF, 0x51DC, 0xD7D0, 0x51CC, 0xD7D1, 0x695E, 0xD7D2, 0x7A1C, + 0xD7D3, 0x7DBE, 0xD7D4, 0x83F1, 0xD7D5, 0x9675, 0xD7D6, 0x4FDA, + 0xD7D7, 0x5229, 0xD7D8, 0x5398, 0xD7D9, 0x540F, 0xD7DA, 0x550E, + 0xD7DB, 0x5C65, 0xD7DC, 0x60A7, 0xD7DD, 0x674E, 0xD7DE, 0x68A8, + 0xD7DF, 0x6D6C, 0xD7E0, 0x7281, 0xD7E1, 0x72F8, 0xD7E2, 0x7406, + 0xD7E3, 0x7483, 0xD7E4, 0xF962, 0xD7E5, 0x75E2, 0xD7E6, 0x7C6C, + 0xD7E7, 0x7F79, 0xD7E8, 0x7FB8, 0xD7E9, 0x8389, 0xD7EA, 0x88CF, + 0xD7EB, 0x88E1, 0xD7EC, 0x91CC, 0xD7ED, 0x91D0, 0xD7EE, 0x96E2, + 0xD7EF, 0x9BC9, 0xD7F0, 0x541D, 0xD7F1, 0x6F7E, 0xD7F2, 0x71D0, + 0xD7F3, 0x7498, 0xD7F4, 0x85FA, 0xD7F5, 0x8EAA, 0xD7F6, 0x96A3, + 0xD7F7, 0x9C57, 0xD7F8, 0x9E9F, 0xD7F9, 0x6797, 0xD7FA, 0x6DCB, + 0xD7FB, 0x7433, 0xD7FC, 0x81E8, 0xD7FD, 0x9716, 0xD7FE, 0x782C, + 0xD8A1, 0x7ACB, 0xD8A2, 0x7B20, 0xD8A3, 0x7C92, 0xD8A4, 0x6469, + 0xD8A5, 0x746A, 0xD8A6, 0x75F2, 0xD8A7, 0x78BC, 0xD8A8, 0x78E8, + 0xD8A9, 0x99AC, 0xD8AA, 0x9B54, 0xD8AB, 0x9EBB, 0xD8AC, 0x5BDE, + 0xD8AD, 0x5E55, 0xD8AE, 0x6F20, 0xD8AF, 0x819C, 0xD8B0, 0x83AB, + 0xD8B1, 0x9088, 0xD8B2, 0x4E07, 0xD8B3, 0x534D, 0xD8B4, 0x5A29, + 0xD8B5, 0x5DD2, 0xD8B6, 0x5F4E, 0xD8B7, 0x6162, 0xD8B8, 0x633D, + 0xD8B9, 0x6669, 0xD8BA, 0x66FC, 0xD8BB, 0x6EFF, 0xD8BC, 0x6F2B, + 0xD8BD, 0x7063, 0xD8BE, 0x779E, 0xD8BF, 0x842C, 0xD8C0, 0x8513, + 0xD8C1, 0x883B, 0xD8C2, 0x8F13, 0xD8C3, 0x9945, 0xD8C4, 0x9C3B, + 0xD8C5, 0x551C, 0xD8C6, 0x62B9, 0xD8C7, 0x672B, 0xD8C8, 0x6CAB, + 0xD8C9, 0x8309, 0xD8CA, 0x896A, 0xD8CB, 0x977A, 0xD8CC, 0x4EA1, + 0xD8CD, 0x5984, 0xD8CE, 0x5FD8, 0xD8CF, 0x5FD9, 0xD8D0, 0x671B, + 0xD8D1, 0x7DB2, 0xD8D2, 0x7F54, 0xD8D3, 0x8292, 0xD8D4, 0x832B, + 0xD8D5, 0x83BD, 0xD8D6, 0x8F1E, 0xD8D7, 0x9099, 0xD8D8, 0x57CB, + 0xD8D9, 0x59B9, 0xD8DA, 0x5A92, 0xD8DB, 0x5BD0, 0xD8DC, 0x6627, + 0xD8DD, 0x679A, 0xD8DE, 0x6885, 0xD8DF, 0x6BCF, 0xD8E0, 0x7164, + 0xD8E1, 0x7F75, 0xD8E2, 0x8CB7, 0xD8E3, 0x8CE3, 0xD8E4, 0x9081, + 0xD8E5, 0x9B45, 0xD8E6, 0x8108, 0xD8E7, 0x8C8A, 0xD8E8, 0x964C, + 0xD8E9, 0x9A40, 0xD8EA, 0x9EA5, 0xD8EB, 0x5B5F, 0xD8EC, 0x6C13, + 0xD8ED, 0x731B, 0xD8EE, 0x76F2, 0xD8EF, 0x76DF, 0xD8F0, 0x840C, + 0xD8F1, 0x51AA, 0xD8F2, 0x8993, 0xD8F3, 0x514D, 0xD8F4, 0x5195, + 0xD8F5, 0x52C9, 0xD8F6, 0x68C9, 0xD8F7, 0x6C94, 0xD8F8, 0x7704, + 0xD8F9, 0x7720, 0xD8FA, 0x7DBF, 0xD8FB, 0x7DEC, 0xD8FC, 0x9762, + 0xD8FD, 0x9EB5, 0xD8FE, 0x6EC5, 0xD9A1, 0x8511, 0xD9A2, 0x51A5, + 0xD9A3, 0x540D, 0xD9A4, 0x547D, 0xD9A5, 0x660E, 0xD9A6, 0x669D, + 0xD9A7, 0x6927, 0xD9A8, 0x6E9F, 0xD9A9, 0x76BF, 0xD9AA, 0x7791, + 0xD9AB, 0x8317, 0xD9AC, 0x84C2, 0xD9AD, 0x879F, 0xD9AE, 0x9169, + 0xD9AF, 0x9298, 0xD9B0, 0x9CF4, 0xD9B1, 0x8882, 0xD9B2, 0x4FAE, + 0xD9B3, 0x5192, 0xD9B4, 0x52DF, 0xD9B5, 0x59C6, 0xD9B6, 0x5E3D, + 0xD9B7, 0x6155, 0xD9B8, 0x6478, 0xD9B9, 0x6479, 0xD9BA, 0x66AE, + 0xD9BB, 0x67D0, 0xD9BC, 0x6A21, 0xD9BD, 0x6BCD, 0xD9BE, 0x6BDB, + 0xD9BF, 0x725F, 0xD9C0, 0x7261, 0xD9C1, 0x7441, 0xD9C2, 0x7738, + 0xD9C3, 0x77DB, 0xD9C4, 0x8017, 0xD9C5, 0x82BC, 0xD9C6, 0x8305, + 0xD9C7, 0x8B00, 0xD9C8, 0x8B28, 0xD9C9, 0x8C8C, 0xD9CA, 0x6728, + 0xD9CB, 0x6C90, 0xD9CC, 0x7267, 0xD9CD, 0x76EE, 0xD9CE, 0x7766, + 0xD9CF, 0x7A46, 0xD9D0, 0x9DA9, 0xD9D1, 0x6B7F, 0xD9D2, 0x6C92, + 0xD9D3, 0x5922, 0xD9D4, 0x6726, 0xD9D5, 0x8499, 0xD9D6, 0x536F, + 0xD9D7, 0x5893, 0xD9D8, 0x5999, 0xD9D9, 0x5EDF, 0xD9DA, 0x63CF, + 0xD9DB, 0x6634, 0xD9DC, 0x6773, 0xD9DD, 0x6E3A, 0xD9DE, 0x732B, + 0xD9DF, 0x7AD7, 0xD9E0, 0x82D7, 0xD9E1, 0x9328, 0xD9E2, 0x52D9, + 0xD9E3, 0x5DEB, 0xD9E4, 0x61AE, 0xD9E5, 0x61CB, 0xD9E6, 0x620A, + 0xD9E7, 0x62C7, 0xD9E8, 0x64AB, 0xD9E9, 0x65E0, 0xD9EA, 0x6959, + 0xD9EB, 0x6B66, 0xD9EC, 0x6BCB, 0xD9ED, 0x7121, 0xD9EE, 0x73F7, + 0xD9EF, 0x755D, 0xD9F0, 0x7E46, 0xD9F1, 0x821E, 0xD9F2, 0x8302, + 0xD9F3, 0x856A, 0xD9F4, 0x8AA3, 0xD9F5, 0x8CBF, 0xD9F6, 0x9727, + 0xD9F7, 0x9D61, 0xD9F8, 0x58A8, 0xD9F9, 0x9ED8, 0xD9FA, 0x5011, + 0xD9FB, 0x520E, 0xD9FC, 0x543B, 0xD9FD, 0x554F, 0xD9FE, 0x6587, + 0xDAA1, 0x6C76, 0xDAA2, 0x7D0A, 0xDAA3, 0x7D0B, 0xDAA4, 0x805E, + 0xDAA5, 0x868A, 0xDAA6, 0x9580, 0xDAA7, 0x96EF, 0xDAA8, 0x52FF, + 0xDAA9, 0x6C95, 0xDAAA, 0x7269, 0xDAAB, 0x5473, 0xDAAC, 0x5A9A, + 0xDAAD, 0x5C3E, 0xDAAE, 0x5D4B, 0xDAAF, 0x5F4C, 0xDAB0, 0x5FAE, + 0xDAB1, 0x672A, 0xDAB2, 0x68B6, 0xDAB3, 0x6963, 0xDAB4, 0x6E3C, + 0xDAB5, 0x6E44, 0xDAB6, 0x7709, 0xDAB7, 0x7C73, 0xDAB8, 0x7F8E, + 0xDAB9, 0x8587, 0xDABA, 0x8B0E, 0xDABB, 0x8FF7, 0xDABC, 0x9761, + 0xDABD, 0x9EF4, 0xDABE, 0x5CB7, 0xDABF, 0x60B6, 0xDAC0, 0x610D, + 0xDAC1, 0x61AB, 0xDAC2, 0x654F, 0xDAC3, 0x65FB, 0xDAC4, 0x65FC, + 0xDAC5, 0x6C11, 0xDAC6, 0x6CEF, 0xDAC7, 0x739F, 0xDAC8, 0x73C9, + 0xDAC9, 0x7DE1, 0xDACA, 0x9594, 0xDACB, 0x5BC6, 0xDACC, 0x871C, + 0xDACD, 0x8B10, 0xDACE, 0x525D, 0xDACF, 0x535A, 0xDAD0, 0x62CD, + 0xDAD1, 0x640F, 0xDAD2, 0x64B2, 0xDAD3, 0x6734, 0xDAD4, 0x6A38, + 0xDAD5, 0x6CCA, 0xDAD6, 0x73C0, 0xDAD7, 0x749E, 0xDAD8, 0x7B94, + 0xDAD9, 0x7C95, 0xDADA, 0x7E1B, 0xDADB, 0x818A, 0xDADC, 0x8236, + 0xDADD, 0x8584, 0xDADE, 0x8FEB, 0xDADF, 0x96F9, 0xDAE0, 0x99C1, + 0xDAE1, 0x4F34, 0xDAE2, 0x534A, 0xDAE3, 0x53CD, 0xDAE4, 0x53DB, + 0xDAE5, 0x62CC, 0xDAE6, 0x642C, 0xDAE7, 0x6500, 0xDAE8, 0x6591, + 0xDAE9, 0x69C3, 0xDAEA, 0x6CEE, 0xDAEB, 0x6F58, 0xDAEC, 0x73ED, + 0xDAED, 0x7554, 0xDAEE, 0x7622, 0xDAEF, 0x76E4, 0xDAF0, 0x76FC, + 0xDAF1, 0x78D0, 0xDAF2, 0x78FB, 0xDAF3, 0x792C, 0xDAF4, 0x7D46, + 0xDAF5, 0x822C, 0xDAF6, 0x87E0, 0xDAF7, 0x8FD4, 0xDAF8, 0x9812, + 0xDAF9, 0x98EF, 0xDAFA, 0x52C3, 0xDAFB, 0x62D4, 0xDAFC, 0x64A5, + 0xDAFD, 0x6E24, 0xDAFE, 0x6F51, 0xDBA1, 0x767C, 0xDBA2, 0x8DCB, + 0xDBA3, 0x91B1, 0xDBA4, 0x9262, 0xDBA5, 0x9AEE, 0xDBA6, 0x9B43, + 0xDBA7, 0x5023, 0xDBA8, 0x508D, 0xDBA9, 0x574A, 0xDBAA, 0x59A8, + 0xDBAB, 0x5C28, 0xDBAC, 0x5E47, 0xDBAD, 0x5F77, 0xDBAE, 0x623F, + 0xDBAF, 0x653E, 0xDBB0, 0x65B9, 0xDBB1, 0x65C1, 0xDBB2, 0x6609, + 0xDBB3, 0x678B, 0xDBB4, 0x699C, 0xDBB5, 0x6EC2, 0xDBB6, 0x78C5, + 0xDBB7, 0x7D21, 0xDBB8, 0x80AA, 0xDBB9, 0x8180, 0xDBBA, 0x822B, + 0xDBBB, 0x82B3, 0xDBBC, 0x84A1, 0xDBBD, 0x868C, 0xDBBE, 0x8A2A, + 0xDBBF, 0x8B17, 0xDBC0, 0x90A6, 0xDBC1, 0x9632, 0xDBC2, 0x9F90, + 0xDBC3, 0x500D, 0xDBC4, 0x4FF3, 0xDBC5, 0xF963, 0xDBC6, 0x57F9, + 0xDBC7, 0x5F98, 0xDBC8, 0x62DC, 0xDBC9, 0x6392, 0xDBCA, 0x676F, + 0xDBCB, 0x6E43, 0xDBCC, 0x7119, 0xDBCD, 0x76C3, 0xDBCE, 0x80CC, + 0xDBCF, 0x80DA, 0xDBD0, 0x88F4, 0xDBD1, 0x88F5, 0xDBD2, 0x8919, + 0xDBD3, 0x8CE0, 0xDBD4, 0x8F29, 0xDBD5, 0x914D, 0xDBD6, 0x966A, + 0xDBD7, 0x4F2F, 0xDBD8, 0x4F70, 0xDBD9, 0x5E1B, 0xDBDA, 0x67CF, + 0xDBDB, 0x6822, 0xDBDC, 0x767D, 0xDBDD, 0x767E, 0xDBDE, 0x9B44, + 0xDBDF, 0x5E61, 0xDBE0, 0x6A0A, 0xDBE1, 0x7169, 0xDBE2, 0x71D4, + 0xDBE3, 0x756A, 0xDBE4, 0xF964, 0xDBE5, 0x7E41, 0xDBE6, 0x8543, + 0xDBE7, 0x85E9, 0xDBE8, 0x98DC, 0xDBE9, 0x4F10, 0xDBEA, 0x7B4F, + 0xDBEB, 0x7F70, 0xDBEC, 0x95A5, 0xDBED, 0x51E1, 0xDBEE, 0x5E06, + 0xDBEF, 0x68B5, 0xDBF0, 0x6C3E, 0xDBF1, 0x6C4E, 0xDBF2, 0x6CDB, + 0xDBF3, 0x72AF, 0xDBF4, 0x7BC4, 0xDBF5, 0x8303, 0xDBF6, 0x6CD5, + 0xDBF7, 0x743A, 0xDBF8, 0x50FB, 0xDBF9, 0x5288, 0xDBFA, 0x58C1, + 0xDBFB, 0x64D8, 0xDBFC, 0x6A97, 0xDBFD, 0x74A7, 0xDBFE, 0x7656, + 0xDCA1, 0x78A7, 0xDCA2, 0x8617, 0xDCA3, 0x95E2, 0xDCA4, 0x9739, + 0xDCA5, 0xF965, 0xDCA6, 0x535E, 0xDCA7, 0x5F01, 0xDCA8, 0x8B8A, + 0xDCA9, 0x8FA8, 0xDCAA, 0x8FAF, 0xDCAB, 0x908A, 0xDCAC, 0x5225, + 0xDCAD, 0x77A5, 0xDCAE, 0x9C49, 0xDCAF, 0x9F08, 0xDCB0, 0x4E19, + 0xDCB1, 0x5002, 0xDCB2, 0x5175, 0xDCB3, 0x5C5B, 0xDCB4, 0x5E77, + 0xDCB5, 0x661E, 0xDCB6, 0x663A, 0xDCB7, 0x67C4, 0xDCB8, 0x68C5, + 0xDCB9, 0x70B3, 0xDCBA, 0x7501, 0xDCBB, 0x75C5, 0xDCBC, 0x79C9, + 0xDCBD, 0x7ADD, 0xDCBE, 0x8F27, 0xDCBF, 0x9920, 0xDCC0, 0x9A08, + 0xDCC1, 0x4FDD, 0xDCC2, 0x5821, 0xDCC3, 0x5831, 0xDCC4, 0x5BF6, + 0xDCC5, 0x666E, 0xDCC6, 0x6B65, 0xDCC7, 0x6D11, 0xDCC8, 0x6E7A, + 0xDCC9, 0x6F7D, 0xDCCA, 0x73E4, 0xDCCB, 0x752B, 0xDCCC, 0x83E9, + 0xDCCD, 0x88DC, 0xDCCE, 0x8913, 0xDCCF, 0x8B5C, 0xDCD0, 0x8F14, + 0xDCD1, 0x4F0F, 0xDCD2, 0x50D5, 0xDCD3, 0x5310, 0xDCD4, 0x535C, + 0xDCD5, 0x5B93, 0xDCD6, 0x5FA9, 0xDCD7, 0x670D, 0xDCD8, 0x798F, + 0xDCD9, 0x8179, 0xDCDA, 0x832F, 0xDCDB, 0x8514, 0xDCDC, 0x8907, + 0xDCDD, 0x8986, 0xDCDE, 0x8F39, 0xDCDF, 0x8F3B, 0xDCE0, 0x99A5, + 0xDCE1, 0x9C12, 0xDCE2, 0x672C, 0xDCE3, 0x4E76, 0xDCE4, 0x4FF8, + 0xDCE5, 0x5949, 0xDCE6, 0x5C01, 0xDCE7, 0x5CEF, 0xDCE8, 0x5CF0, + 0xDCE9, 0x6367, 0xDCEA, 0x68D2, 0xDCEB, 0x70FD, 0xDCEC, 0x71A2, + 0xDCED, 0x742B, 0xDCEE, 0x7E2B, 0xDCEF, 0x84EC, 0xDCF0, 0x8702, + 0xDCF1, 0x9022, 0xDCF2, 0x92D2, 0xDCF3, 0x9CF3, 0xDCF4, 0x4E0D, + 0xDCF5, 0x4ED8, 0xDCF6, 0x4FEF, 0xDCF7, 0x5085, 0xDCF8, 0x5256, + 0xDCF9, 0x526F, 0xDCFA, 0x5426, 0xDCFB, 0x5490, 0xDCFC, 0x57E0, + 0xDCFD, 0x592B, 0xDCFE, 0x5A66, 0xDDA1, 0x5B5A, 0xDDA2, 0x5B75, + 0xDDA3, 0x5BCC, 0xDDA4, 0x5E9C, 0xDDA5, 0xF966, 0xDDA6, 0x6276, + 0xDDA7, 0x6577, 0xDDA8, 0x65A7, 0xDDA9, 0x6D6E, 0xDDAA, 0x6EA5, + 0xDDAB, 0x7236, 0xDDAC, 0x7B26, 0xDDAD, 0x7C3F, 0xDDAE, 0x7F36, + 0xDDAF, 0x8150, 0xDDB0, 0x8151, 0xDDB1, 0x819A, 0xDDB2, 0x8240, + 0xDDB3, 0x8299, 0xDDB4, 0x83A9, 0xDDB5, 0x8A03, 0xDDB6, 0x8CA0, + 0xDDB7, 0x8CE6, 0xDDB8, 0x8CFB, 0xDDB9, 0x8D74, 0xDDBA, 0x8DBA, + 0xDDBB, 0x90E8, 0xDDBC, 0x91DC, 0xDDBD, 0x961C, 0xDDBE, 0x9644, + 0xDDBF, 0x99D9, 0xDDC0, 0x9CE7, 0xDDC1, 0x5317, 0xDDC2, 0x5206, + 0xDDC3, 0x5429, 0xDDC4, 0x5674, 0xDDC5, 0x58B3, 0xDDC6, 0x5954, + 0xDDC7, 0x596E, 0xDDC8, 0x5FFF, 0xDDC9, 0x61A4, 0xDDCA, 0x626E, + 0xDDCB, 0x6610, 0xDDCC, 0x6C7E, 0xDDCD, 0x711A, 0xDDCE, 0x76C6, + 0xDDCF, 0x7C89, 0xDDD0, 0x7CDE, 0xDDD1, 0x7D1B, 0xDDD2, 0x82AC, + 0xDDD3, 0x8CC1, 0xDDD4, 0x96F0, 0xDDD5, 0xF967, 0xDDD6, 0x4F5B, + 0xDDD7, 0x5F17, 0xDDD8, 0x5F7F, 0xDDD9, 0x62C2, 0xDDDA, 0x5D29, + 0xDDDB, 0x670B, 0xDDDC, 0x68DA, 0xDDDD, 0x787C, 0xDDDE, 0x7E43, + 0xDDDF, 0x9D6C, 0xDDE0, 0x4E15, 0xDDE1, 0x5099, 0xDDE2, 0x5315, + 0xDDE3, 0x532A, 0xDDE4, 0x5351, 0xDDE5, 0x5983, 0xDDE6, 0x5A62, + 0xDDE7, 0x5E87, 0xDDE8, 0x60B2, 0xDDE9, 0x618A, 0xDDEA, 0x6249, + 0xDDEB, 0x6279, 0xDDEC, 0x6590, 0xDDED, 0x6787, 0xDDEE, 0x69A7, + 0xDDEF, 0x6BD4, 0xDDF0, 0x6BD6, 0xDDF1, 0x6BD7, 0xDDF2, 0x6BD8, + 0xDDF3, 0x6CB8, 0xDDF4, 0xF968, 0xDDF5, 0x7435, 0xDDF6, 0x75FA, + 0xDDF7, 0x7812, 0xDDF8, 0x7891, 0xDDF9, 0x79D5, 0xDDFA, 0x79D8, + 0xDDFB, 0x7C83, 0xDDFC, 0x7DCB, 0xDDFD, 0x7FE1, 0xDDFE, 0x80A5, + 0xDEA1, 0x813E, 0xDEA2, 0x81C2, 0xDEA3, 0x83F2, 0xDEA4, 0x871A, + 0xDEA5, 0x88E8, 0xDEA6, 0x8AB9, 0xDEA7, 0x8B6C, 0xDEA8, 0x8CBB, + 0xDEA9, 0x9119, 0xDEAA, 0x975E, 0xDEAB, 0x98DB, 0xDEAC, 0x9F3B, + 0xDEAD, 0x56AC, 0xDEAE, 0x5B2A, 0xDEAF, 0x5F6C, 0xDEB0, 0x658C, + 0xDEB1, 0x6AB3, 0xDEB2, 0x6BAF, 0xDEB3, 0x6D5C, 0xDEB4, 0x6FF1, + 0xDEB5, 0x7015, 0xDEB6, 0x725D, 0xDEB7, 0x73AD, 0xDEB8, 0x8CA7, + 0xDEB9, 0x8CD3, 0xDEBA, 0x983B, 0xDEBB, 0x6191, 0xDEBC, 0x6C37, + 0xDEBD, 0x8058, 0xDEBE, 0x9A01, 0xDEBF, 0x4E4D, 0xDEC0, 0x4E8B, + 0xDEC1, 0x4E9B, 0xDEC2, 0x4ED5, 0xDEC3, 0x4F3A, 0xDEC4, 0x4F3C, + 0xDEC5, 0x4F7F, 0xDEC6, 0x4FDF, 0xDEC7, 0x50FF, 0xDEC8, 0x53F2, + 0xDEC9, 0x53F8, 0xDECA, 0x5506, 0xDECB, 0x55E3, 0xDECC, 0x56DB, + 0xDECD, 0x58EB, 0xDECE, 0x5962, 0xDECF, 0x5A11, 0xDED0, 0x5BEB, + 0xDED1, 0x5BFA, 0xDED2, 0x5C04, 0xDED3, 0x5DF3, 0xDED4, 0x5E2B, + 0xDED5, 0x5F99, 0xDED6, 0x601D, 0xDED7, 0x6368, 0xDED8, 0x659C, + 0xDED9, 0x65AF, 0xDEDA, 0x67F6, 0xDEDB, 0x67FB, 0xDEDC, 0x68AD, + 0xDEDD, 0x6B7B, 0xDEDE, 0x6C99, 0xDEDF, 0x6CD7, 0xDEE0, 0x6E23, + 0xDEE1, 0x7009, 0xDEE2, 0x7345, 0xDEE3, 0x7802, 0xDEE4, 0x793E, + 0xDEE5, 0x7940, 0xDEE6, 0x7960, 0xDEE7, 0x79C1, 0xDEE8, 0x7BE9, + 0xDEE9, 0x7D17, 0xDEEA, 0x7D72, 0xDEEB, 0x8086, 0xDEEC, 0x820D, + 0xDEED, 0x838E, 0xDEEE, 0x84D1, 0xDEEF, 0x86C7, 0xDEF0, 0x88DF, + 0xDEF1, 0x8A50, 0xDEF2, 0x8A5E, 0xDEF3, 0x8B1D, 0xDEF4, 0x8CDC, + 0xDEF5, 0x8D66, 0xDEF6, 0x8FAD, 0xDEF7, 0x90AA, 0xDEF8, 0x98FC, + 0xDEF9, 0x99DF, 0xDEFA, 0x9E9D, 0xDEFB, 0x524A, 0xDEFC, 0xF969, + 0xDEFD, 0x6714, 0xDEFE, 0xF96A, 0xDFA1, 0x5098, 0xDFA2, 0x522A, + 0xDFA3, 0x5C71, 0xDFA4, 0x6563, 0xDFA5, 0x6C55, 0xDFA6, 0x73CA, + 0xDFA7, 0x7523, 0xDFA8, 0x759D, 0xDFA9, 0x7B97, 0xDFAA, 0x849C, + 0xDFAB, 0x9178, 0xDFAC, 0x9730, 0xDFAD, 0x4E77, 0xDFAE, 0x6492, + 0xDFAF, 0x6BBA, 0xDFB0, 0x715E, 0xDFB1, 0x85A9, 0xDFB2, 0x4E09, + 0xDFB3, 0xF96B, 0xDFB4, 0x6749, 0xDFB5, 0x68EE, 0xDFB6, 0x6E17, + 0xDFB7, 0x829F, 0xDFB8, 0x8518, 0xDFB9, 0x886B, 0xDFBA, 0x63F7, + 0xDFBB, 0x6F81, 0xDFBC, 0x9212, 0xDFBD, 0x98AF, 0xDFBE, 0x4E0A, + 0xDFBF, 0x50B7, 0xDFC0, 0x50CF, 0xDFC1, 0x511F, 0xDFC2, 0x5546, + 0xDFC3, 0x55AA, 0xDFC4, 0x5617, 0xDFC5, 0x5B40, 0xDFC6, 0x5C19, + 0xDFC7, 0x5CE0, 0xDFC8, 0x5E38, 0xDFC9, 0x5E8A, 0xDFCA, 0x5EA0, + 0xDFCB, 0x5EC2, 0xDFCC, 0x60F3, 0xDFCD, 0x6851, 0xDFCE, 0x6A61, + 0xDFCF, 0x6E58, 0xDFD0, 0x723D, 0xDFD1, 0x7240, 0xDFD2, 0x72C0, + 0xDFD3, 0x76F8, 0xDFD4, 0x7965, 0xDFD5, 0x7BB1, 0xDFD6, 0x7FD4, + 0xDFD7, 0x88F3, 0xDFD8, 0x89F4, 0xDFD9, 0x8A73, 0xDFDA, 0x8C61, + 0xDFDB, 0x8CDE, 0xDFDC, 0x971C, 0xDFDD, 0x585E, 0xDFDE, 0x74BD, + 0xDFDF, 0x8CFD, 0xDFE0, 0x55C7, 0xDFE1, 0xF96C, 0xDFE2, 0x7A61, + 0xDFE3, 0x7D22, 0xDFE4, 0x8272, 0xDFE5, 0x7272, 0xDFE6, 0x751F, + 0xDFE7, 0x7525, 0xDFE8, 0xF96D, 0xDFE9, 0x7B19, 0xDFEA, 0x5885, + 0xDFEB, 0x58FB, 0xDFEC, 0x5DBC, 0xDFED, 0x5E8F, 0xDFEE, 0x5EB6, + 0xDFEF, 0x5F90, 0xDFF0, 0x6055, 0xDFF1, 0x6292, 0xDFF2, 0x637F, + 0xDFF3, 0x654D, 0xDFF4, 0x6691, 0xDFF5, 0x66D9, 0xDFF6, 0x66F8, + 0xDFF7, 0x6816, 0xDFF8, 0x68F2, 0xDFF9, 0x7280, 0xDFFA, 0x745E, + 0xDFFB, 0x7B6E, 0xDFFC, 0x7D6E, 0xDFFD, 0x7DD6, 0xDFFE, 0x7F72, + 0xE0A1, 0x80E5, 0xE0A2, 0x8212, 0xE0A3, 0x85AF, 0xE0A4, 0x897F, + 0xE0A5, 0x8A93, 0xE0A6, 0x901D, 0xE0A7, 0x92E4, 0xE0A8, 0x9ECD, + 0xE0A9, 0x9F20, 0xE0AA, 0x5915, 0xE0AB, 0x596D, 0xE0AC, 0x5E2D, + 0xE0AD, 0x60DC, 0xE0AE, 0x6614, 0xE0AF, 0x6673, 0xE0B0, 0x6790, + 0xE0B1, 0x6C50, 0xE0B2, 0x6DC5, 0xE0B3, 0x6F5F, 0xE0B4, 0x77F3, + 0xE0B5, 0x78A9, 0xE0B6, 0x84C6, 0xE0B7, 0x91CB, 0xE0B8, 0x932B, + 0xE0B9, 0x4ED9, 0xE0BA, 0x50CA, 0xE0BB, 0x5148, 0xE0BC, 0x5584, + 0xE0BD, 0x5B0B, 0xE0BE, 0x5BA3, 0xE0BF, 0x6247, 0xE0C0, 0x657E, + 0xE0C1, 0x65CB, 0xE0C2, 0x6E32, 0xE0C3, 0x717D, 0xE0C4, 0x7401, + 0xE0C5, 0x7444, 0xE0C6, 0x7487, 0xE0C7, 0x74BF, 0xE0C8, 0x766C, + 0xE0C9, 0x79AA, 0xE0CA, 0x7DDA, 0xE0CB, 0x7E55, 0xE0CC, 0x7FA8, + 0xE0CD, 0x817A, 0xE0CE, 0x81B3, 0xE0CF, 0x8239, 0xE0D0, 0x861A, + 0xE0D1, 0x87EC, 0xE0D2, 0x8A75, 0xE0D3, 0x8DE3, 0xE0D4, 0x9078, + 0xE0D5, 0x9291, 0xE0D6, 0x9425, 0xE0D7, 0x994D, 0xE0D8, 0x9BAE, + 0xE0D9, 0x5368, 0xE0DA, 0x5C51, 0xE0DB, 0x6954, 0xE0DC, 0x6CC4, + 0xE0DD, 0x6D29, 0xE0DE, 0x6E2B, 0xE0DF, 0x820C, 0xE0E0, 0x859B, + 0xE0E1, 0x893B, 0xE0E2, 0x8A2D, 0xE0E3, 0x8AAA, 0xE0E4, 0x96EA, + 0xE0E5, 0x9F67, 0xE0E6, 0x5261, 0xE0E7, 0x66B9, 0xE0E8, 0x6BB2, + 0xE0E9, 0x7E96, 0xE0EA, 0x87FE, 0xE0EB, 0x8D0D, 0xE0EC, 0x9583, + 0xE0ED, 0x965D, 0xE0EE, 0x651D, 0xE0EF, 0x6D89, 0xE0F0, 0x71EE, + 0xE0F1, 0xF96E, 0xE0F2, 0x57CE, 0xE0F3, 0x59D3, 0xE0F4, 0x5BAC, + 0xE0F5, 0x6027, 0xE0F6, 0x60FA, 0xE0F7, 0x6210, 0xE0F8, 0x661F, + 0xE0F9, 0x665F, 0xE0FA, 0x7329, 0xE0FB, 0x73F9, 0xE0FC, 0x76DB, + 0xE0FD, 0x7701, 0xE0FE, 0x7B6C, 0xE1A1, 0x8056, 0xE1A2, 0x8072, + 0xE1A3, 0x8165, 0xE1A4, 0x8AA0, 0xE1A5, 0x9192, 0xE1A6, 0x4E16, + 0xE1A7, 0x52E2, 0xE1A8, 0x6B72, 0xE1A9, 0x6D17, 0xE1AA, 0x7A05, + 0xE1AB, 0x7B39, 0xE1AC, 0x7D30, 0xE1AD, 0xF96F, 0xE1AE, 0x8CB0, + 0xE1AF, 0x53EC, 0xE1B0, 0x562F, 0xE1B1, 0x5851, 0xE1B2, 0x5BB5, + 0xE1B3, 0x5C0F, 0xE1B4, 0x5C11, 0xE1B5, 0x5DE2, 0xE1B6, 0x6240, + 0xE1B7, 0x6383, 0xE1B8, 0x6414, 0xE1B9, 0x662D, 0xE1BA, 0x68B3, + 0xE1BB, 0x6CBC, 0xE1BC, 0x6D88, 0xE1BD, 0x6EAF, 0xE1BE, 0x701F, + 0xE1BF, 0x70A4, 0xE1C0, 0x71D2, 0xE1C1, 0x7526, 0xE1C2, 0x758F, + 0xE1C3, 0x758E, 0xE1C4, 0x7619, 0xE1C5, 0x7B11, 0xE1C6, 0x7BE0, + 0xE1C7, 0x7C2B, 0xE1C8, 0x7D20, 0xE1C9, 0x7D39, 0xE1CA, 0x852C, + 0xE1CB, 0x856D, 0xE1CC, 0x8607, 0xE1CD, 0x8A34, 0xE1CE, 0x900D, + 0xE1CF, 0x9061, 0xE1D0, 0x90B5, 0xE1D1, 0x92B7, 0xE1D2, 0x97F6, + 0xE1D3, 0x9A37, 0xE1D4, 0x4FD7, 0xE1D5, 0x5C6C, 0xE1D6, 0x675F, + 0xE1D7, 0x6D91, 0xE1D8, 0x7C9F, 0xE1D9, 0x7E8C, 0xE1DA, 0x8B16, + 0xE1DB, 0x8D16, 0xE1DC, 0x901F, 0xE1DD, 0x5B6B, 0xE1DE, 0x5DFD, + 0xE1DF, 0x640D, 0xE1E0, 0x84C0, 0xE1E1, 0x905C, 0xE1E2, 0x98E1, + 0xE1E3, 0x7387, 0xE1E4, 0x5B8B, 0xE1E5, 0x609A, 0xE1E6, 0x677E, + 0xE1E7, 0x6DDE, 0xE1E8, 0x8A1F, 0xE1E9, 0x8AA6, 0xE1EA, 0x9001, + 0xE1EB, 0x980C, 0xE1EC, 0x5237, 0xE1ED, 0xF970, 0xE1EE, 0x7051, + 0xE1EF, 0x788E, 0xE1F0, 0x9396, 0xE1F1, 0x8870, 0xE1F2, 0x91D7, + 0xE1F3, 0x4FEE, 0xE1F4, 0x53D7, 0xE1F5, 0x55FD, 0xE1F6, 0x56DA, + 0xE1F7, 0x5782, 0xE1F8, 0x58FD, 0xE1F9, 0x5AC2, 0xE1FA, 0x5B88, + 0xE1FB, 0x5CAB, 0xE1FC, 0x5CC0, 0xE1FD, 0x5E25, 0xE1FE, 0x6101, + 0xE2A1, 0x620D, 0xE2A2, 0x624B, 0xE2A3, 0x6388, 0xE2A4, 0x641C, + 0xE2A5, 0x6536, 0xE2A6, 0x6578, 0xE2A7, 0x6A39, 0xE2A8, 0x6B8A, + 0xE2A9, 0x6C34, 0xE2AA, 0x6D19, 0xE2AB, 0x6F31, 0xE2AC, 0x71E7, + 0xE2AD, 0x72E9, 0xE2AE, 0x7378, 0xE2AF, 0x7407, 0xE2B0, 0x74B2, + 0xE2B1, 0x7626, 0xE2B2, 0x7761, 0xE2B3, 0x79C0, 0xE2B4, 0x7A57, + 0xE2B5, 0x7AEA, 0xE2B6, 0x7CB9, 0xE2B7, 0x7D8F, 0xE2B8, 0x7DAC, + 0xE2B9, 0x7E61, 0xE2BA, 0x7F9E, 0xE2BB, 0x8129, 0xE2BC, 0x8331, + 0xE2BD, 0x8490, 0xE2BE, 0x84DA, 0xE2BF, 0x85EA, 0xE2C0, 0x8896, + 0xE2C1, 0x8AB0, 0xE2C2, 0x8B90, 0xE2C3, 0x8F38, 0xE2C4, 0x9042, + 0xE2C5, 0x9083, 0xE2C6, 0x916C, 0xE2C7, 0x9296, 0xE2C8, 0x92B9, + 0xE2C9, 0x968B, 0xE2CA, 0x96A7, 0xE2CB, 0x96A8, 0xE2CC, 0x96D6, + 0xE2CD, 0x9700, 0xE2CE, 0x9808, 0xE2CF, 0x9996, 0xE2D0, 0x9AD3, + 0xE2D1, 0x9B1A, 0xE2D2, 0x53D4, 0xE2D3, 0x587E, 0xE2D4, 0x5919, + 0xE2D5, 0x5B70, 0xE2D6, 0x5BBF, 0xE2D7, 0x6DD1, 0xE2D8, 0x6F5A, + 0xE2D9, 0x719F, 0xE2DA, 0x7421, 0xE2DB, 0x74B9, 0xE2DC, 0x8085, + 0xE2DD, 0x83FD, 0xE2DE, 0x5DE1, 0xE2DF, 0x5F87, 0xE2E0, 0x5FAA, + 0xE2E1, 0x6042, 0xE2E2, 0x65EC, 0xE2E3, 0x6812, 0xE2E4, 0x696F, + 0xE2E5, 0x6A53, 0xE2E6, 0x6B89, 0xE2E7, 0x6D35, 0xE2E8, 0x6DF3, + 0xE2E9, 0x73E3, 0xE2EA, 0x76FE, 0xE2EB, 0x77AC, 0xE2EC, 0x7B4D, + 0xE2ED, 0x7D14, 0xE2EE, 0x8123, 0xE2EF, 0x821C, 0xE2F0, 0x8340, + 0xE2F1, 0x84F4, 0xE2F2, 0x8563, 0xE2F3, 0x8A62, 0xE2F4, 0x8AC4, + 0xE2F5, 0x9187, 0xE2F6, 0x931E, 0xE2F7, 0x9806, 0xE2F8, 0x99B4, + 0xE2F9, 0x620C, 0xE2FA, 0x8853, 0xE2FB, 0x8FF0, 0xE2FC, 0x9265, + 0xE2FD, 0x5D07, 0xE2FE, 0x5D27, 0xE3A1, 0x5D69, 0xE3A2, 0x745F, + 0xE3A3, 0x819D, 0xE3A4, 0x8768, 0xE3A5, 0x6FD5, 0xE3A6, 0x62FE, + 0xE3A7, 0x7FD2, 0xE3A8, 0x8936, 0xE3A9, 0x8972, 0xE3AA, 0x4E1E, + 0xE3AB, 0x4E58, 0xE3AC, 0x50E7, 0xE3AD, 0x52DD, 0xE3AE, 0x5347, + 0xE3AF, 0x627F, 0xE3B0, 0x6607, 0xE3B1, 0x7E69, 0xE3B2, 0x8805, + 0xE3B3, 0x965E, 0xE3B4, 0x4F8D, 0xE3B5, 0x5319, 0xE3B6, 0x5636, + 0xE3B7, 0x59CB, 0xE3B8, 0x5AA4, 0xE3B9, 0x5C38, 0xE3BA, 0x5C4E, + 0xE3BB, 0x5C4D, 0xE3BC, 0x5E02, 0xE3BD, 0x5F11, 0xE3BE, 0x6043, + 0xE3BF, 0x65BD, 0xE3C0, 0x662F, 0xE3C1, 0x6642, 0xE3C2, 0x67BE, + 0xE3C3, 0x67F4, 0xE3C4, 0x731C, 0xE3C5, 0x77E2, 0xE3C6, 0x793A, + 0xE3C7, 0x7FC5, 0xE3C8, 0x8494, 0xE3C9, 0x84CD, 0xE3CA, 0x8996, + 0xE3CB, 0x8A66, 0xE3CC, 0x8A69, 0xE3CD, 0x8AE1, 0xE3CE, 0x8C55, + 0xE3CF, 0x8C7A, 0xE3D0, 0x57F4, 0xE3D1, 0x5BD4, 0xE3D2, 0x5F0F, + 0xE3D3, 0x606F, 0xE3D4, 0x62ED, 0xE3D5, 0x690D, 0xE3D6, 0x6B96, + 0xE3D7, 0x6E5C, 0xE3D8, 0x7184, 0xE3D9, 0x7BD2, 0xE3DA, 0x8755, + 0xE3DB, 0x8B58, 0xE3DC, 0x8EFE, 0xE3DD, 0x98DF, 0xE3DE, 0x98FE, + 0xE3DF, 0x4F38, 0xE3E0, 0x4F81, 0xE3E1, 0x4FE1, 0xE3E2, 0x547B, + 0xE3E3, 0x5A20, 0xE3E4, 0x5BB8, 0xE3E5, 0x613C, 0xE3E6, 0x65B0, + 0xE3E7, 0x6668, 0xE3E8, 0x71FC, 0xE3E9, 0x7533, 0xE3EA, 0x795E, + 0xE3EB, 0x7D33, 0xE3EC, 0x814E, 0xE3ED, 0x81E3, 0xE3EE, 0x8398, + 0xE3EF, 0x85AA, 0xE3F0, 0x85CE, 0xE3F1, 0x8703, 0xE3F2, 0x8A0A, + 0xE3F3, 0x8EAB, 0xE3F4, 0x8F9B, 0xE3F5, 0xF971, 0xE3F6, 0x8FC5, + 0xE3F7, 0x5931, 0xE3F8, 0x5BA4, 0xE3F9, 0x5BE6, 0xE3FA, 0x6089, + 0xE3FB, 0x5BE9, 0xE3FC, 0x5C0B, 0xE3FD, 0x5FC3, 0xE3FE, 0x6C81, + 0xE4A1, 0xF972, 0xE4A2, 0x6DF1, 0xE4A3, 0x700B, 0xE4A4, 0x751A, + 0xE4A5, 0x82AF, 0xE4A6, 0x8AF6, 0xE4A7, 0x4EC0, 0xE4A8, 0x5341, + 0xE4A9, 0xF973, 0xE4AA, 0x96D9, 0xE4AB, 0x6C0F, 0xE4AC, 0x4E9E, + 0xE4AD, 0x4FC4, 0xE4AE, 0x5152, 0xE4AF, 0x555E, 0xE4B0, 0x5A25, + 0xE4B1, 0x5CE8, 0xE4B2, 0x6211, 0xE4B3, 0x7259, 0xE4B4, 0x82BD, + 0xE4B5, 0x83AA, 0xE4B6, 0x86FE, 0xE4B7, 0x8859, 0xE4B8, 0x8A1D, + 0xE4B9, 0x963F, 0xE4BA, 0x96C5, 0xE4BB, 0x9913, 0xE4BC, 0x9D09, + 0xE4BD, 0x9D5D, 0xE4BE, 0x580A, 0xE4BF, 0x5CB3, 0xE4C0, 0x5DBD, + 0xE4C1, 0x5E44, 0xE4C2, 0x60E1, 0xE4C3, 0x6115, 0xE4C4, 0x63E1, + 0xE4C5, 0x6A02, 0xE4C6, 0x6E25, 0xE4C7, 0x9102, 0xE4C8, 0x9354, + 0xE4C9, 0x984E, 0xE4CA, 0x9C10, 0xE4CB, 0x9F77, 0xE4CC, 0x5B89, + 0xE4CD, 0x5CB8, 0xE4CE, 0x6309, 0xE4CF, 0x664F, 0xE4D0, 0x6848, + 0xE4D1, 0x773C, 0xE4D2, 0x96C1, 0xE4D3, 0x978D, 0xE4D4, 0x9854, + 0xE4D5, 0x9B9F, 0xE4D6, 0x65A1, 0xE4D7, 0x8B01, 0xE4D8, 0x8ECB, + 0xE4D9, 0x95BC, 0xE4DA, 0x5535, 0xE4DB, 0x5CA9, 0xE4DC, 0x5DD6, + 0xE4DD, 0x5EB5, 0xE4DE, 0x6697, 0xE4DF, 0x764C, 0xE4E0, 0x83F4, + 0xE4E1, 0x95C7, 0xE4E2, 0x58D3, 0xE4E3, 0x62BC, 0xE4E4, 0x72CE, + 0xE4E5, 0x9D28, 0xE4E6, 0x4EF0, 0xE4E7, 0x592E, 0xE4E8, 0x600F, + 0xE4E9, 0x663B, 0xE4EA, 0x6B83, 0xE4EB, 0x79E7, 0xE4EC, 0x9D26, + 0xE4ED, 0x5393, 0xE4EE, 0x54C0, 0xE4EF, 0x57C3, 0xE4F0, 0x5D16, + 0xE4F1, 0x611B, 0xE4F2, 0x66D6, 0xE4F3, 0x6DAF, 0xE4F4, 0x788D, + 0xE4F5, 0x827E, 0xE4F6, 0x9698, 0xE4F7, 0x9744, 0xE4F8, 0x5384, + 0xE4F9, 0x627C, 0xE4FA, 0x6396, 0xE4FB, 0x6DB2, 0xE4FC, 0x7E0A, + 0xE4FD, 0x814B, 0xE4FE, 0x984D, 0xE5A1, 0x6AFB, 0xE5A2, 0x7F4C, + 0xE5A3, 0x9DAF, 0xE5A4, 0x9E1A, 0xE5A5, 0x4E5F, 0xE5A6, 0x503B, + 0xE5A7, 0x51B6, 0xE5A8, 0x591C, 0xE5A9, 0x60F9, 0xE5AA, 0x63F6, + 0xE5AB, 0x6930, 0xE5AC, 0x723A, 0xE5AD, 0x8036, 0xE5AE, 0xF974, + 0xE5AF, 0x91CE, 0xE5B0, 0x5F31, 0xE5B1, 0xF975, 0xE5B2, 0xF976, + 0xE5B3, 0x7D04, 0xE5B4, 0x82E5, 0xE5B5, 0x846F, 0xE5B6, 0x84BB, + 0xE5B7, 0x85E5, 0xE5B8, 0x8E8D, 0xE5B9, 0xF977, 0xE5BA, 0x4F6F, + 0xE5BB, 0xF978, 0xE5BC, 0xF979, 0xE5BD, 0x58E4, 0xE5BE, 0x5B43, + 0xE5BF, 0x6059, 0xE5C0, 0x63DA, 0xE5C1, 0x6518, 0xE5C2, 0x656D, + 0xE5C3, 0x6698, 0xE5C4, 0xF97A, 0xE5C5, 0x694A, 0xE5C6, 0x6A23, + 0xE5C7, 0x6D0B, 0xE5C8, 0x7001, 0xE5C9, 0x716C, 0xE5CA, 0x75D2, + 0xE5CB, 0x760D, 0xE5CC, 0x79B3, 0xE5CD, 0x7A70, 0xE5CE, 0xF97B, + 0xE5CF, 0x7F8A, 0xE5D0, 0xF97C, 0xE5D1, 0x8944, 0xE5D2, 0xF97D, + 0xE5D3, 0x8B93, 0xE5D4, 0x91C0, 0xE5D5, 0x967D, 0xE5D6, 0xF97E, + 0xE5D7, 0x990A, 0xE5D8, 0x5704, 0xE5D9, 0x5FA1, 0xE5DA, 0x65BC, + 0xE5DB, 0x6F01, 0xE5DC, 0x7600, 0xE5DD, 0x79A6, 0xE5DE, 0x8A9E, + 0xE5DF, 0x99AD, 0xE5E0, 0x9B5A, 0xE5E1, 0x9F6C, 0xE5E2, 0x5104, + 0xE5E3, 0x61B6, 0xE5E4, 0x6291, 0xE5E5, 0x6A8D, 0xE5E6, 0x81C6, + 0xE5E7, 0x5043, 0xE5E8, 0x5830, 0xE5E9, 0x5F66, 0xE5EA, 0x7109, + 0xE5EB, 0x8A00, 0xE5EC, 0x8AFA, 0xE5ED, 0x5B7C, 0xE5EE, 0x8616, + 0xE5EF, 0x4FFA, 0xE5F0, 0x513C, 0xE5F1, 0x56B4, 0xE5F2, 0x5944, + 0xE5F3, 0x63A9, 0xE5F4, 0x6DF9, 0xE5F5, 0x5DAA, 0xE5F6, 0x696D, + 0xE5F7, 0x5186, 0xE5F8, 0x4E88, 0xE5F9, 0x4F59, 0xE5FA, 0xF97F, + 0xE5FB, 0xF980, 0xE5FC, 0xF981, 0xE5FD, 0x5982, 0xE5FE, 0xF982, + 0xE6A1, 0xF983, 0xE6A2, 0x6B5F, 0xE6A3, 0x6C5D, 0xE6A4, 0xF984, + 0xE6A5, 0x74B5, 0xE6A6, 0x7916, 0xE6A7, 0xF985, 0xE6A8, 0x8207, + 0xE6A9, 0x8245, 0xE6AA, 0x8339, 0xE6AB, 0x8F3F, 0xE6AC, 0x8F5D, + 0xE6AD, 0xF986, 0xE6AE, 0x9918, 0xE6AF, 0xF987, 0xE6B0, 0xF988, + 0xE6B1, 0xF989, 0xE6B2, 0x4EA6, 0xE6B3, 0xF98A, 0xE6B4, 0x57DF, + 0xE6B5, 0x5F79, 0xE6B6, 0x6613, 0xE6B7, 0xF98B, 0xE6B8, 0xF98C, + 0xE6B9, 0x75AB, 0xE6BA, 0x7E79, 0xE6BB, 0x8B6F, 0xE6BC, 0xF98D, + 0xE6BD, 0x9006, 0xE6BE, 0x9A5B, 0xE6BF, 0x56A5, 0xE6C0, 0x5827, + 0xE6C1, 0x59F8, 0xE6C2, 0x5A1F, 0xE6C3, 0x5BB4, 0xE6C4, 0xF98E, + 0xE6C5, 0x5EF6, 0xE6C6, 0xF98F, 0xE6C7, 0xF990, 0xE6C8, 0x6350, + 0xE6C9, 0x633B, 0xE6CA, 0xF991, 0xE6CB, 0x693D, 0xE6CC, 0x6C87, + 0xE6CD, 0x6CBF, 0xE6CE, 0x6D8E, 0xE6CF, 0x6D93, 0xE6D0, 0x6DF5, + 0xE6D1, 0x6F14, 0xE6D2, 0xF992, 0xE6D3, 0x70DF, 0xE6D4, 0x7136, + 0xE6D5, 0x7159, 0xE6D6, 0xF993, 0xE6D7, 0x71C3, 0xE6D8, 0x71D5, + 0xE6D9, 0xF994, 0xE6DA, 0x784F, 0xE6DB, 0x786F, 0xE6DC, 0xF995, + 0xE6DD, 0x7B75, 0xE6DE, 0x7DE3, 0xE6DF, 0xF996, 0xE6E0, 0x7E2F, + 0xE6E1, 0xF997, 0xE6E2, 0x884D, 0xE6E3, 0x8EDF, 0xE6E4, 0xF998, + 0xE6E5, 0xF999, 0xE6E6, 0xF99A, 0xE6E7, 0x925B, 0xE6E8, 0xF99B, + 0xE6E9, 0x9CF6, 0xE6EA, 0xF99C, 0xE6EB, 0xF99D, 0xE6EC, 0xF99E, + 0xE6ED, 0x6085, 0xE6EE, 0x6D85, 0xE6EF, 0xF99F, 0xE6F0, 0x71B1, + 0xE6F1, 0xF9A0, 0xE6F2, 0xF9A1, 0xE6F3, 0x95B1, 0xE6F4, 0x53AD, + 0xE6F5, 0xF9A2, 0xE6F6, 0xF9A3, 0xE6F7, 0xF9A4, 0xE6F8, 0x67D3, + 0xE6F9, 0xF9A5, 0xE6FA, 0x708E, 0xE6FB, 0x7130, 0xE6FC, 0x7430, + 0xE6FD, 0x8276, 0xE6FE, 0x82D2, 0xE7A1, 0xF9A6, 0xE7A2, 0x95BB, + 0xE7A3, 0x9AE5, 0xE7A4, 0x9E7D, 0xE7A5, 0x66C4, 0xE7A6, 0xF9A7, + 0xE7A7, 0x71C1, 0xE7A8, 0x8449, 0xE7A9, 0xF9A8, 0xE7AA, 0xF9A9, + 0xE7AB, 0x584B, 0xE7AC, 0xF9AA, 0xE7AD, 0xF9AB, 0xE7AE, 0x5DB8, + 0xE7AF, 0x5F71, 0xE7B0, 0xF9AC, 0xE7B1, 0x6620, 0xE7B2, 0x668E, + 0xE7B3, 0x6979, 0xE7B4, 0x69AE, 0xE7B5, 0x6C38, 0xE7B6, 0x6CF3, + 0xE7B7, 0x6E36, 0xE7B8, 0x6F41, 0xE7B9, 0x6FDA, 0xE7BA, 0x701B, + 0xE7BB, 0x702F, 0xE7BC, 0x7150, 0xE7BD, 0x71DF, 0xE7BE, 0x7370, + 0xE7BF, 0xF9AD, 0xE7C0, 0x745B, 0xE7C1, 0xF9AE, 0xE7C2, 0x74D4, + 0xE7C3, 0x76C8, 0xE7C4, 0x7A4E, 0xE7C5, 0x7E93, 0xE7C6, 0xF9AF, + 0xE7C7, 0xF9B0, 0xE7C8, 0x82F1, 0xE7C9, 0x8A60, 0xE7CA, 0x8FCE, + 0xE7CB, 0xF9B1, 0xE7CC, 0x9348, 0xE7CD, 0xF9B2, 0xE7CE, 0x9719, + 0xE7CF, 0xF9B3, 0xE7D0, 0xF9B4, 0xE7D1, 0x4E42, 0xE7D2, 0x502A, + 0xE7D3, 0xF9B5, 0xE7D4, 0x5208, 0xE7D5, 0x53E1, 0xE7D6, 0x66F3, + 0xE7D7, 0x6C6D, 0xE7D8, 0x6FCA, 0xE7D9, 0x730A, 0xE7DA, 0x777F, + 0xE7DB, 0x7A62, 0xE7DC, 0x82AE, 0xE7DD, 0x85DD, 0xE7DE, 0x8602, + 0xE7DF, 0xF9B6, 0xE7E0, 0x88D4, 0xE7E1, 0x8A63, 0xE7E2, 0x8B7D, + 0xE7E3, 0x8C6B, 0xE7E4, 0xF9B7, 0xE7E5, 0x92B3, 0xE7E6, 0xF9B8, + 0xE7E7, 0x9713, 0xE7E8, 0x9810, 0xE7E9, 0x4E94, 0xE7EA, 0x4F0D, + 0xE7EB, 0x4FC9, 0xE7EC, 0x50B2, 0xE7ED, 0x5348, 0xE7EE, 0x543E, + 0xE7EF, 0x5433, 0xE7F0, 0x55DA, 0xE7F1, 0x5862, 0xE7F2, 0x58BA, + 0xE7F3, 0x5967, 0xE7F4, 0x5A1B, 0xE7F5, 0x5BE4, 0xE7F6, 0x609F, + 0xE7F7, 0xF9B9, 0xE7F8, 0x61CA, 0xE7F9, 0x6556, 0xE7FA, 0x65FF, + 0xE7FB, 0x6664, 0xE7FC, 0x68A7, 0xE7FD, 0x6C5A, 0xE7FE, 0x6FB3, + 0xE8A1, 0x70CF, 0xE8A2, 0x71AC, 0xE8A3, 0x7352, 0xE8A4, 0x7B7D, + 0xE8A5, 0x8708, 0xE8A6, 0x8AA4, 0xE8A7, 0x9C32, 0xE8A8, 0x9F07, + 0xE8A9, 0x5C4B, 0xE8AA, 0x6C83, 0xE8AB, 0x7344, 0xE8AC, 0x7389, + 0xE8AD, 0x923A, 0xE8AE, 0x6EAB, 0xE8AF, 0x7465, 0xE8B0, 0x761F, + 0xE8B1, 0x7A69, 0xE8B2, 0x7E15, 0xE8B3, 0x860A, 0xE8B4, 0x5140, + 0xE8B5, 0x58C5, 0xE8B6, 0x64C1, 0xE8B7, 0x74EE, 0xE8B8, 0x7515, + 0xE8B9, 0x7670, 0xE8BA, 0x7FC1, 0xE8BB, 0x9095, 0xE8BC, 0x96CD, + 0xE8BD, 0x9954, 0xE8BE, 0x6E26, 0xE8BF, 0x74E6, 0xE8C0, 0x7AA9, + 0xE8C1, 0x7AAA, 0xE8C2, 0x81E5, 0xE8C3, 0x86D9, 0xE8C4, 0x8778, + 0xE8C5, 0x8A1B, 0xE8C6, 0x5A49, 0xE8C7, 0x5B8C, 0xE8C8, 0x5B9B, + 0xE8C9, 0x68A1, 0xE8CA, 0x6900, 0xE8CB, 0x6D63, 0xE8CC, 0x73A9, + 0xE8CD, 0x7413, 0xE8CE, 0x742C, 0xE8CF, 0x7897, 0xE8D0, 0x7DE9, + 0xE8D1, 0x7FEB, 0xE8D2, 0x8118, 0xE8D3, 0x8155, 0xE8D4, 0x839E, + 0xE8D5, 0x8C4C, 0xE8D6, 0x962E, 0xE8D7, 0x9811, 0xE8D8, 0x66F0, + 0xE8D9, 0x5F80, 0xE8DA, 0x65FA, 0xE8DB, 0x6789, 0xE8DC, 0x6C6A, + 0xE8DD, 0x738B, 0xE8DE, 0x502D, 0xE8DF, 0x5A03, 0xE8E0, 0x6B6A, + 0xE8E1, 0x77EE, 0xE8E2, 0x5916, 0xE8E3, 0x5D6C, 0xE8E4, 0x5DCD, + 0xE8E5, 0x7325, 0xE8E6, 0x754F, 0xE8E7, 0xF9BA, 0xE8E8, 0xF9BB, + 0xE8E9, 0x50E5, 0xE8EA, 0x51F9, 0xE8EB, 0x582F, 0xE8EC, 0x592D, + 0xE8ED, 0x5996, 0xE8EE, 0x59DA, 0xE8EF, 0x5BE5, 0xE8F0, 0xF9BC, + 0xE8F1, 0xF9BD, 0xE8F2, 0x5DA2, 0xE8F3, 0x62D7, 0xE8F4, 0x6416, + 0xE8F5, 0x6493, 0xE8F6, 0x64FE, 0xE8F7, 0xF9BE, 0xE8F8, 0x66DC, + 0xE8F9, 0xF9BF, 0xE8FA, 0x6A48, 0xE8FB, 0xF9C0, 0xE8FC, 0x71FF, + 0xE8FD, 0x7464, 0xE8FE, 0xF9C1, 0xE9A1, 0x7A88, 0xE9A2, 0x7AAF, + 0xE9A3, 0x7E47, 0xE9A4, 0x7E5E, 0xE9A5, 0x8000, 0xE9A6, 0x8170, + 0xE9A7, 0xF9C2, 0xE9A8, 0x87EF, 0xE9A9, 0x8981, 0xE9AA, 0x8B20, + 0xE9AB, 0x9059, 0xE9AC, 0xF9C3, 0xE9AD, 0x9080, 0xE9AE, 0x9952, + 0xE9AF, 0x617E, 0xE9B0, 0x6B32, 0xE9B1, 0x6D74, 0xE9B2, 0x7E1F, + 0xE9B3, 0x8925, 0xE9B4, 0x8FB1, 0xE9B5, 0x4FD1, 0xE9B6, 0x50AD, + 0xE9B7, 0x5197, 0xE9B8, 0x52C7, 0xE9B9, 0x57C7, 0xE9BA, 0x5889, + 0xE9BB, 0x5BB9, 0xE9BC, 0x5EB8, 0xE9BD, 0x6142, 0xE9BE, 0x6995, + 0xE9BF, 0x6D8C, 0xE9C0, 0x6E67, 0xE9C1, 0x6EB6, 0xE9C2, 0x7194, + 0xE9C3, 0x7462, 0xE9C4, 0x7528, 0xE9C5, 0x752C, 0xE9C6, 0x8073, + 0xE9C7, 0x8338, 0xE9C8, 0x84C9, 0xE9C9, 0x8E0A, 0xE9CA, 0x9394, + 0xE9CB, 0x93DE, 0xE9CC, 0xF9C4, 0xE9CD, 0x4E8E, 0xE9CE, 0x4F51, + 0xE9CF, 0x5076, 0xE9D0, 0x512A, 0xE9D1, 0x53C8, 0xE9D2, 0x53CB, + 0xE9D3, 0x53F3, 0xE9D4, 0x5B87, 0xE9D5, 0x5BD3, 0xE9D6, 0x5C24, + 0xE9D7, 0x611A, 0xE9D8, 0x6182, 0xE9D9, 0x65F4, 0xE9DA, 0x725B, + 0xE9DB, 0x7397, 0xE9DC, 0x7440, 0xE9DD, 0x76C2, 0xE9DE, 0x7950, + 0xE9DF, 0x7991, 0xE9E0, 0x79B9, 0xE9E1, 0x7D06, 0xE9E2, 0x7FBD, + 0xE9E3, 0x828B, 0xE9E4, 0x85D5, 0xE9E5, 0x865E, 0xE9E6, 0x8FC2, + 0xE9E7, 0x9047, 0xE9E8, 0x90F5, 0xE9E9, 0x91EA, 0xE9EA, 0x9685, + 0xE9EB, 0x96E8, 0xE9EC, 0x96E9, 0xE9ED, 0x52D6, 0xE9EE, 0x5F67, + 0xE9EF, 0x65ED, 0xE9F0, 0x6631, 0xE9F1, 0x682F, 0xE9F2, 0x715C, + 0xE9F3, 0x7A36, 0xE9F4, 0x90C1, 0xE9F5, 0x980A, 0xE9F6, 0x4E91, + 0xE9F7, 0xF9C5, 0xE9F8, 0x6A52, 0xE9F9, 0x6B9E, 0xE9FA, 0x6F90, + 0xE9FB, 0x7189, 0xE9FC, 0x8018, 0xE9FD, 0x82B8, 0xE9FE, 0x8553, + 0xEAA1, 0x904B, 0xEAA2, 0x9695, 0xEAA3, 0x96F2, 0xEAA4, 0x97FB, + 0xEAA5, 0x851A, 0xEAA6, 0x9B31, 0xEAA7, 0x4E90, 0xEAA8, 0x718A, + 0xEAA9, 0x96C4, 0xEAAA, 0x5143, 0xEAAB, 0x539F, 0xEAAC, 0x54E1, + 0xEAAD, 0x5713, 0xEAAE, 0x5712, 0xEAAF, 0x57A3, 0xEAB0, 0x5A9B, + 0xEAB1, 0x5AC4, 0xEAB2, 0x5BC3, 0xEAB3, 0x6028, 0xEAB4, 0x613F, + 0xEAB5, 0x63F4, 0xEAB6, 0x6C85, 0xEAB7, 0x6D39, 0xEAB8, 0x6E72, + 0xEAB9, 0x6E90, 0xEABA, 0x7230, 0xEABB, 0x733F, 0xEABC, 0x7457, + 0xEABD, 0x82D1, 0xEABE, 0x8881, 0xEABF, 0x8F45, 0xEAC0, 0x9060, + 0xEAC1, 0xF9C6, 0xEAC2, 0x9662, 0xEAC3, 0x9858, 0xEAC4, 0x9D1B, + 0xEAC5, 0x6708, 0xEAC6, 0x8D8A, 0xEAC7, 0x925E, 0xEAC8, 0x4F4D, + 0xEAC9, 0x5049, 0xEACA, 0x50DE, 0xEACB, 0x5371, 0xEACC, 0x570D, + 0xEACD, 0x59D4, 0xEACE, 0x5A01, 0xEACF, 0x5C09, 0xEAD0, 0x6170, + 0xEAD1, 0x6690, 0xEAD2, 0x6E2D, 0xEAD3, 0x7232, 0xEAD4, 0x744B, + 0xEAD5, 0x7DEF, 0xEAD6, 0x80C3, 0xEAD7, 0x840E, 0xEAD8, 0x8466, + 0xEAD9, 0x853F, 0xEADA, 0x875F, 0xEADB, 0x885B, 0xEADC, 0x8918, + 0xEADD, 0x8B02, 0xEADE, 0x9055, 0xEADF, 0x97CB, 0xEAE0, 0x9B4F, + 0xEAE1, 0x4E73, 0xEAE2, 0x4F91, 0xEAE3, 0x5112, 0xEAE4, 0x516A, + 0xEAE5, 0xF9C7, 0xEAE6, 0x552F, 0xEAE7, 0x55A9, 0xEAE8, 0x5B7A, + 0xEAE9, 0x5BA5, 0xEAEA, 0x5E7C, 0xEAEB, 0x5E7D, 0xEAEC, 0x5EBE, + 0xEAED, 0x60A0, 0xEAEE, 0x60DF, 0xEAEF, 0x6108, 0xEAF0, 0x6109, + 0xEAF1, 0x63C4, 0xEAF2, 0x6538, 0xEAF3, 0x6709, 0xEAF4, 0xF9C8, + 0xEAF5, 0x67D4, 0xEAF6, 0x67DA, 0xEAF7, 0xF9C9, 0xEAF8, 0x6961, + 0xEAF9, 0x6962, 0xEAFA, 0x6CB9, 0xEAFB, 0x6D27, 0xEAFC, 0xF9CA, + 0xEAFD, 0x6E38, 0xEAFE, 0xF9CB, 0xEBA1, 0x6FE1, 0xEBA2, 0x7336, + 0xEBA3, 0x7337, 0xEBA4, 0xF9CC, 0xEBA5, 0x745C, 0xEBA6, 0x7531, + 0xEBA7, 0xF9CD, 0xEBA8, 0x7652, 0xEBA9, 0xF9CE, 0xEBAA, 0xF9CF, + 0xEBAB, 0x7DAD, 0xEBAC, 0x81FE, 0xEBAD, 0x8438, 0xEBAE, 0x88D5, + 0xEBAF, 0x8A98, 0xEBB0, 0x8ADB, 0xEBB1, 0x8AED, 0xEBB2, 0x8E30, + 0xEBB3, 0x8E42, 0xEBB4, 0x904A, 0xEBB5, 0x903E, 0xEBB6, 0x907A, + 0xEBB7, 0x9149, 0xEBB8, 0x91C9, 0xEBB9, 0x936E, 0xEBBA, 0xF9D0, + 0xEBBB, 0xF9D1, 0xEBBC, 0x5809, 0xEBBD, 0xF9D2, 0xEBBE, 0x6BD3, + 0xEBBF, 0x8089, 0xEBC0, 0x80B2, 0xEBC1, 0xF9D3, 0xEBC2, 0xF9D4, + 0xEBC3, 0x5141, 0xEBC4, 0x596B, 0xEBC5, 0x5C39, 0xEBC6, 0xF9D5, + 0xEBC7, 0xF9D6, 0xEBC8, 0x6F64, 0xEBC9, 0x73A7, 0xEBCA, 0x80E4, + 0xEBCB, 0x8D07, 0xEBCC, 0xF9D7, 0xEBCD, 0x9217, 0xEBCE, 0x958F, + 0xEBCF, 0xF9D8, 0xEBD0, 0xF9D9, 0xEBD1, 0xF9DA, 0xEBD2, 0xF9DB, + 0xEBD3, 0x807F, 0xEBD4, 0x620E, 0xEBD5, 0x701C, 0xEBD6, 0x7D68, + 0xEBD7, 0x878D, 0xEBD8, 0xF9DC, 0xEBD9, 0x57A0, 0xEBDA, 0x6069, + 0xEBDB, 0x6147, 0xEBDC, 0x6BB7, 0xEBDD, 0x8ABE, 0xEBDE, 0x9280, + 0xEBDF, 0x96B1, 0xEBE0, 0x4E59, 0xEBE1, 0x541F, 0xEBE2, 0x6DEB, + 0xEBE3, 0x852D, 0xEBE4, 0x9670, 0xEBE5, 0x97F3, 0xEBE6, 0x98EE, + 0xEBE7, 0x63D6, 0xEBE8, 0x6CE3, 0xEBE9, 0x9091, 0xEBEA, 0x51DD, + 0xEBEB, 0x61C9, 0xEBEC, 0x81BA, 0xEBED, 0x9DF9, 0xEBEE, 0x4F9D, + 0xEBEF, 0x501A, 0xEBF0, 0x5100, 0xEBF1, 0x5B9C, 0xEBF2, 0x610F, + 0xEBF3, 0x61FF, 0xEBF4, 0x64EC, 0xEBF5, 0x6905, 0xEBF6, 0x6BC5, + 0xEBF7, 0x7591, 0xEBF8, 0x77E3, 0xEBF9, 0x7FA9, 0xEBFA, 0x8264, + 0xEBFB, 0x858F, 0xEBFC, 0x87FB, 0xEBFD, 0x8863, 0xEBFE, 0x8ABC, + 0xECA1, 0x8B70, 0xECA2, 0x91AB, 0xECA3, 0x4E8C, 0xECA4, 0x4EE5, + 0xECA5, 0x4F0A, 0xECA6, 0xF9DD, 0xECA7, 0xF9DE, 0xECA8, 0x5937, + 0xECA9, 0x59E8, 0xECAA, 0xF9DF, 0xECAB, 0x5DF2, 0xECAC, 0x5F1B, + 0xECAD, 0x5F5B, 0xECAE, 0x6021, 0xECAF, 0xF9E0, 0xECB0, 0xF9E1, + 0xECB1, 0xF9E2, 0xECB2, 0xF9E3, 0xECB3, 0x723E, 0xECB4, 0x73E5, + 0xECB5, 0xF9E4, 0xECB6, 0x7570, 0xECB7, 0x75CD, 0xECB8, 0xF9E5, + 0xECB9, 0x79FB, 0xECBA, 0xF9E6, 0xECBB, 0x800C, 0xECBC, 0x8033, + 0xECBD, 0x8084, 0xECBE, 0x82E1, 0xECBF, 0x8351, 0xECC0, 0xF9E7, + 0xECC1, 0xF9E8, 0xECC2, 0x8CBD, 0xECC3, 0x8CB3, 0xECC4, 0x9087, + 0xECC5, 0xF9E9, 0xECC6, 0xF9EA, 0xECC7, 0x98F4, 0xECC8, 0x990C, + 0xECC9, 0xF9EB, 0xECCA, 0xF9EC, 0xECCB, 0x7037, 0xECCC, 0x76CA, + 0xECCD, 0x7FCA, 0xECCE, 0x7FCC, 0xECCF, 0x7FFC, 0xECD0, 0x8B1A, + 0xECD1, 0x4EBA, 0xECD2, 0x4EC1, 0xECD3, 0x5203, 0xECD4, 0x5370, + 0xECD5, 0xF9ED, 0xECD6, 0x54BD, 0xECD7, 0x56E0, 0xECD8, 0x59FB, + 0xECD9, 0x5BC5, 0xECDA, 0x5F15, 0xECDB, 0x5FCD, 0xECDC, 0x6E6E, + 0xECDD, 0xF9EE, 0xECDE, 0xF9EF, 0xECDF, 0x7D6A, 0xECE0, 0x8335, + 0xECE1, 0xF9F0, 0xECE2, 0x8693, 0xECE3, 0x8A8D, 0xECE4, 0xF9F1, + 0xECE5, 0x976D, 0xECE6, 0x9777, 0xECE7, 0xF9F2, 0xECE8, 0xF9F3, + 0xECE9, 0x4E00, 0xECEA, 0x4F5A, 0xECEB, 0x4F7E, 0xECEC, 0x58F9, + 0xECED, 0x65E5, 0xECEE, 0x6EA2, 0xECEF, 0x9038, 0xECF0, 0x93B0, + 0xECF1, 0x99B9, 0xECF2, 0x4EFB, 0xECF3, 0x58EC, 0xECF4, 0x598A, + 0xECF5, 0x59D9, 0xECF6, 0x6041, 0xECF7, 0xF9F4, 0xECF8, 0xF9F5, + 0xECF9, 0x7A14, 0xECFA, 0xF9F6, 0xECFB, 0x834F, 0xECFC, 0x8CC3, + 0xECFD, 0x5165, 0xECFE, 0x5344, 0xEDA1, 0xF9F7, 0xEDA2, 0xF9F8, + 0xEDA3, 0xF9F9, 0xEDA4, 0x4ECD, 0xEDA5, 0x5269, 0xEDA6, 0x5B55, + 0xEDA7, 0x82BF, 0xEDA8, 0x4ED4, 0xEDA9, 0x523A, 0xEDAA, 0x54A8, + 0xEDAB, 0x59C9, 0xEDAC, 0x59FF, 0xEDAD, 0x5B50, 0xEDAE, 0x5B57, + 0xEDAF, 0x5B5C, 0xEDB0, 0x6063, 0xEDB1, 0x6148, 0xEDB2, 0x6ECB, + 0xEDB3, 0x7099, 0xEDB4, 0x716E, 0xEDB5, 0x7386, 0xEDB6, 0x74F7, + 0xEDB7, 0x75B5, 0xEDB8, 0x78C1, 0xEDB9, 0x7D2B, 0xEDBA, 0x8005, + 0xEDBB, 0x81EA, 0xEDBC, 0x8328, 0xEDBD, 0x8517, 0xEDBE, 0x85C9, + 0xEDBF, 0x8AEE, 0xEDC0, 0x8CC7, 0xEDC1, 0x96CC, 0xEDC2, 0x4F5C, + 0xEDC3, 0x52FA, 0xEDC4, 0x56BC, 0xEDC5, 0x65AB, 0xEDC6, 0x6628, + 0xEDC7, 0x707C, 0xEDC8, 0x70B8, 0xEDC9, 0x7235, 0xEDCA, 0x7DBD, + 0xEDCB, 0x828D, 0xEDCC, 0x914C, 0xEDCD, 0x96C0, 0xEDCE, 0x9D72, + 0xEDCF, 0x5B71, 0xEDD0, 0x68E7, 0xEDD1, 0x6B98, 0xEDD2, 0x6F7A, + 0xEDD3, 0x76DE, 0xEDD4, 0x5C91, 0xEDD5, 0x66AB, 0xEDD6, 0x6F5B, + 0xEDD7, 0x7BB4, 0xEDD8, 0x7C2A, 0xEDD9, 0x8836, 0xEDDA, 0x96DC, + 0xEDDB, 0x4E08, 0xEDDC, 0x4ED7, 0xEDDD, 0x5320, 0xEDDE, 0x5834, + 0xEDDF, 0x58BB, 0xEDE0, 0x58EF, 0xEDE1, 0x596C, 0xEDE2, 0x5C07, + 0xEDE3, 0x5E33, 0xEDE4, 0x5E84, 0xEDE5, 0x5F35, 0xEDE6, 0x638C, + 0xEDE7, 0x66B2, 0xEDE8, 0x6756, 0xEDE9, 0x6A1F, 0xEDEA, 0x6AA3, + 0xEDEB, 0x6B0C, 0xEDEC, 0x6F3F, 0xEDED, 0x7246, 0xEDEE, 0xF9FA, + 0xEDEF, 0x7350, 0xEDF0, 0x748B, 0xEDF1, 0x7AE0, 0xEDF2, 0x7CA7, + 0xEDF3, 0x8178, 0xEDF4, 0x81DF, 0xEDF5, 0x81E7, 0xEDF6, 0x838A, + 0xEDF7, 0x846C, 0xEDF8, 0x8523, 0xEDF9, 0x8594, 0xEDFA, 0x85CF, + 0xEDFB, 0x88DD, 0xEDFC, 0x8D13, 0xEDFD, 0x91AC, 0xEDFE, 0x9577, + 0xEEA1, 0x969C, 0xEEA2, 0x518D, 0xEEA3, 0x54C9, 0xEEA4, 0x5728, + 0xEEA5, 0x5BB0, 0xEEA6, 0x624D, 0xEEA7, 0x6750, 0xEEA8, 0x683D, + 0xEEA9, 0x6893, 0xEEAA, 0x6E3D, 0xEEAB, 0x6ED3, 0xEEAC, 0x707D, + 0xEEAD, 0x7E21, 0xEEAE, 0x88C1, 0xEEAF, 0x8CA1, 0xEEB0, 0x8F09, + 0xEEB1, 0x9F4B, 0xEEB2, 0x9F4E, 0xEEB3, 0x722D, 0xEEB4, 0x7B8F, + 0xEEB5, 0x8ACD, 0xEEB6, 0x931A, 0xEEB7, 0x4F47, 0xEEB8, 0x4F4E, + 0xEEB9, 0x5132, 0xEEBA, 0x5480, 0xEEBB, 0x59D0, 0xEEBC, 0x5E95, + 0xEEBD, 0x62B5, 0xEEBE, 0x6775, 0xEEBF, 0x696E, 0xEEC0, 0x6A17, + 0xEEC1, 0x6CAE, 0xEEC2, 0x6E1A, 0xEEC3, 0x72D9, 0xEEC4, 0x732A, + 0xEEC5, 0x75BD, 0xEEC6, 0x7BB8, 0xEEC7, 0x7D35, 0xEEC8, 0x82E7, + 0xEEC9, 0x83F9, 0xEECA, 0x8457, 0xEECB, 0x85F7, 0xEECC, 0x8A5B, + 0xEECD, 0x8CAF, 0xEECE, 0x8E87, 0xEECF, 0x9019, 0xEED0, 0x90B8, + 0xEED1, 0x96CE, 0xEED2, 0x9F5F, 0xEED3, 0x52E3, 0xEED4, 0x540A, + 0xEED5, 0x5AE1, 0xEED6, 0x5BC2, 0xEED7, 0x6458, 0xEED8, 0x6575, + 0xEED9, 0x6EF4, 0xEEDA, 0x72C4, 0xEEDB, 0xF9FB, 0xEEDC, 0x7684, + 0xEEDD, 0x7A4D, 0xEEDE, 0x7B1B, 0xEEDF, 0x7C4D, 0xEEE0, 0x7E3E, + 0xEEE1, 0x7FDF, 0xEEE2, 0x837B, 0xEEE3, 0x8B2B, 0xEEE4, 0x8CCA, + 0xEEE5, 0x8D64, 0xEEE6, 0x8DE1, 0xEEE7, 0x8E5F, 0xEEE8, 0x8FEA, + 0xEEE9, 0x8FF9, 0xEEEA, 0x9069, 0xEEEB, 0x93D1, 0xEEEC, 0x4F43, + 0xEEED, 0x4F7A, 0xEEEE, 0x50B3, 0xEEEF, 0x5168, 0xEEF0, 0x5178, + 0xEEF1, 0x524D, 0xEEF2, 0x526A, 0xEEF3, 0x5861, 0xEEF4, 0x587C, + 0xEEF5, 0x5960, 0xEEF6, 0x5C08, 0xEEF7, 0x5C55, 0xEEF8, 0x5EDB, + 0xEEF9, 0x609B, 0xEEFA, 0x6230, 0xEEFB, 0x6813, 0xEEFC, 0x6BBF, + 0xEEFD, 0x6C08, 0xEEFE, 0x6FB1, 0xEFA1, 0x714E, 0xEFA2, 0x7420, + 0xEFA3, 0x7530, 0xEFA4, 0x7538, 0xEFA5, 0x7551, 0xEFA6, 0x7672, + 0xEFA7, 0x7B4C, 0xEFA8, 0x7B8B, 0xEFA9, 0x7BAD, 0xEFAA, 0x7BC6, + 0xEFAB, 0x7E8F, 0xEFAC, 0x8A6E, 0xEFAD, 0x8F3E, 0xEFAE, 0x8F49, + 0xEFAF, 0x923F, 0xEFB0, 0x9293, 0xEFB1, 0x9322, 0xEFB2, 0x942B, + 0xEFB3, 0x96FB, 0xEFB4, 0x985A, 0xEFB5, 0x986B, 0xEFB6, 0x991E, + 0xEFB7, 0x5207, 0xEFB8, 0x622A, 0xEFB9, 0x6298, 0xEFBA, 0x6D59, + 0xEFBB, 0x7664, 0xEFBC, 0x7ACA, 0xEFBD, 0x7BC0, 0xEFBE, 0x7D76, + 0xEFBF, 0x5360, 0xEFC0, 0x5CBE, 0xEFC1, 0x5E97, 0xEFC2, 0x6F38, + 0xEFC3, 0x70B9, 0xEFC4, 0x7C98, 0xEFC5, 0x9711, 0xEFC6, 0x9B8E, + 0xEFC7, 0x9EDE, 0xEFC8, 0x63A5, 0xEFC9, 0x647A, 0xEFCA, 0x8776, + 0xEFCB, 0x4E01, 0xEFCC, 0x4E95, 0xEFCD, 0x4EAD, 0xEFCE, 0x505C, + 0xEFCF, 0x5075, 0xEFD0, 0x5448, 0xEFD1, 0x59C3, 0xEFD2, 0x5B9A, + 0xEFD3, 0x5E40, 0xEFD4, 0x5EAD, 0xEFD5, 0x5EF7, 0xEFD6, 0x5F81, + 0xEFD7, 0x60C5, 0xEFD8, 0x633A, 0xEFD9, 0x653F, 0xEFDA, 0x6574, + 0xEFDB, 0x65CC, 0xEFDC, 0x6676, 0xEFDD, 0x6678, 0xEFDE, 0x67FE, + 0xEFDF, 0x6968, 0xEFE0, 0x6A89, 0xEFE1, 0x6B63, 0xEFE2, 0x6C40, + 0xEFE3, 0x6DC0, 0xEFE4, 0x6DE8, 0xEFE5, 0x6E1F, 0xEFE6, 0x6E5E, + 0xEFE7, 0x701E, 0xEFE8, 0x70A1, 0xEFE9, 0x738E, 0xEFEA, 0x73FD, + 0xEFEB, 0x753A, 0xEFEC, 0x775B, 0xEFED, 0x7887, 0xEFEE, 0x798E, + 0xEFEF, 0x7A0B, 0xEFF0, 0x7A7D, 0xEFF1, 0x7CBE, 0xEFF2, 0x7D8E, + 0xEFF3, 0x8247, 0xEFF4, 0x8A02, 0xEFF5, 0x8AEA, 0xEFF6, 0x8C9E, + 0xEFF7, 0x912D, 0xEFF8, 0x914A, 0xEFF9, 0x91D8, 0xEFFA, 0x9266, + 0xEFFB, 0x92CC, 0xEFFC, 0x9320, 0xEFFD, 0x9706, 0xEFFE, 0x9756, + 0xF0A1, 0x975C, 0xF0A2, 0x9802, 0xF0A3, 0x9F0E, 0xF0A4, 0x5236, + 0xF0A5, 0x5291, 0xF0A6, 0x557C, 0xF0A7, 0x5824, 0xF0A8, 0x5E1D, + 0xF0A9, 0x5F1F, 0xF0AA, 0x608C, 0xF0AB, 0x63D0, 0xF0AC, 0x68AF, + 0xF0AD, 0x6FDF, 0xF0AE, 0x796D, 0xF0AF, 0x7B2C, 0xF0B0, 0x81CD, + 0xF0B1, 0x85BA, 0xF0B2, 0x88FD, 0xF0B3, 0x8AF8, 0xF0B4, 0x8E44, + 0xF0B5, 0x918D, 0xF0B6, 0x9664, 0xF0B7, 0x969B, 0xF0B8, 0x973D, + 0xF0B9, 0x984C, 0xF0BA, 0x9F4A, 0xF0BB, 0x4FCE, 0xF0BC, 0x5146, + 0xF0BD, 0x51CB, 0xF0BE, 0x52A9, 0xF0BF, 0x5632, 0xF0C0, 0x5F14, + 0xF0C1, 0x5F6B, 0xF0C2, 0x63AA, 0xF0C3, 0x64CD, 0xF0C4, 0x65E9, + 0xF0C5, 0x6641, 0xF0C6, 0x66FA, 0xF0C7, 0x66F9, 0xF0C8, 0x671D, + 0xF0C9, 0x689D, 0xF0CA, 0x68D7, 0xF0CB, 0x69FD, 0xF0CC, 0x6F15, + 0xF0CD, 0x6F6E, 0xF0CE, 0x7167, 0xF0CF, 0x71E5, 0xF0D0, 0x722A, + 0xF0D1, 0x74AA, 0xF0D2, 0x773A, 0xF0D3, 0x7956, 0xF0D4, 0x795A, + 0xF0D5, 0x79DF, 0xF0D6, 0x7A20, 0xF0D7, 0x7A95, 0xF0D8, 0x7C97, + 0xF0D9, 0x7CDF, 0xF0DA, 0x7D44, 0xF0DB, 0x7E70, 0xF0DC, 0x8087, + 0xF0DD, 0x85FB, 0xF0DE, 0x86A4, 0xF0DF, 0x8A54, 0xF0E0, 0x8ABF, + 0xF0E1, 0x8D99, 0xF0E2, 0x8E81, 0xF0E3, 0x9020, 0xF0E4, 0x906D, + 0xF0E5, 0x91E3, 0xF0E6, 0x963B, 0xF0E7, 0x96D5, 0xF0E8, 0x9CE5, + 0xF0E9, 0x65CF, 0xF0EA, 0x7C07, 0xF0EB, 0x8DB3, 0xF0EC, 0x93C3, + 0xF0ED, 0x5B58, 0xF0EE, 0x5C0A, 0xF0EF, 0x5352, 0xF0F0, 0x62D9, + 0xF0F1, 0x731D, 0xF0F2, 0x5027, 0xF0F3, 0x5B97, 0xF0F4, 0x5F9E, + 0xF0F5, 0x60B0, 0xF0F6, 0x616B, 0xF0F7, 0x68D5, 0xF0F8, 0x6DD9, + 0xF0F9, 0x742E, 0xF0FA, 0x7A2E, 0xF0FB, 0x7D42, 0xF0FC, 0x7D9C, + 0xF0FD, 0x7E31, 0xF0FE, 0x816B, 0xF1A1, 0x8E2A, 0xF1A2, 0x8E35, + 0xF1A3, 0x937E, 0xF1A4, 0x9418, 0xF1A5, 0x4F50, 0xF1A6, 0x5750, + 0xF1A7, 0x5DE6, 0xF1A8, 0x5EA7, 0xF1A9, 0x632B, 0xF1AA, 0x7F6A, + 0xF1AB, 0x4E3B, 0xF1AC, 0x4F4F, 0xF1AD, 0x4F8F, 0xF1AE, 0x505A, + 0xF1AF, 0x59DD, 0xF1B0, 0x80C4, 0xF1B1, 0x546A, 0xF1B2, 0x5468, + 0xF1B3, 0x55FE, 0xF1B4, 0x594F, 0xF1B5, 0x5B99, 0xF1B6, 0x5DDE, + 0xF1B7, 0x5EDA, 0xF1B8, 0x665D, 0xF1B9, 0x6731, 0xF1BA, 0x67F1, + 0xF1BB, 0x682A, 0xF1BC, 0x6CE8, 0xF1BD, 0x6D32, 0xF1BE, 0x6E4A, + 0xF1BF, 0x6F8D, 0xF1C0, 0x70B7, 0xF1C1, 0x73E0, 0xF1C2, 0x7587, + 0xF1C3, 0x7C4C, 0xF1C4, 0x7D02, 0xF1C5, 0x7D2C, 0xF1C6, 0x7DA2, + 0xF1C7, 0x821F, 0xF1C8, 0x86DB, 0xF1C9, 0x8A3B, 0xF1CA, 0x8A85, + 0xF1CB, 0x8D70, 0xF1CC, 0x8E8A, 0xF1CD, 0x8F33, 0xF1CE, 0x9031, + 0xF1CF, 0x914E, 0xF1D0, 0x9152, 0xF1D1, 0x9444, 0xF1D2, 0x99D0, + 0xF1D3, 0x7AF9, 0xF1D4, 0x7CA5, 0xF1D5, 0x4FCA, 0xF1D6, 0x5101, + 0xF1D7, 0x51C6, 0xF1D8, 0x57C8, 0xF1D9, 0x5BEF, 0xF1DA, 0x5CFB, + 0xF1DB, 0x6659, 0xF1DC, 0x6A3D, 0xF1DD, 0x6D5A, 0xF1DE, 0x6E96, + 0xF1DF, 0x6FEC, 0xF1E0, 0x710C, 0xF1E1, 0x756F, 0xF1E2, 0x7AE3, + 0xF1E3, 0x8822, 0xF1E4, 0x9021, 0xF1E5, 0x9075, 0xF1E6, 0x96CB, + 0xF1E7, 0x99FF, 0xF1E8, 0x8301, 0xF1E9, 0x4E2D, 0xF1EA, 0x4EF2, + 0xF1EB, 0x8846, 0xF1EC, 0x91CD, 0xF1ED, 0x537D, 0xF1EE, 0x6ADB, + 0xF1EF, 0x696B, 0xF1F0, 0x6C41, 0xF1F1, 0x847A, 0xF1F2, 0x589E, + 0xF1F3, 0x618E, 0xF1F4, 0x66FE, 0xF1F5, 0x62EF, 0xF1F6, 0x70DD, + 0xF1F7, 0x7511, 0xF1F8, 0x75C7, 0xF1F9, 0x7E52, 0xF1FA, 0x84B8, + 0xF1FB, 0x8B49, 0xF1FC, 0x8D08, 0xF1FD, 0x4E4B, 0xF1FE, 0x53EA, + 0xF2A1, 0x54AB, 0xF2A2, 0x5730, 0xF2A3, 0x5740, 0xF2A4, 0x5FD7, + 0xF2A5, 0x6301, 0xF2A6, 0x6307, 0xF2A7, 0x646F, 0xF2A8, 0x652F, + 0xF2A9, 0x65E8, 0xF2AA, 0x667A, 0xF2AB, 0x679D, 0xF2AC, 0x67B3, + 0xF2AD, 0x6B62, 0xF2AE, 0x6C60, 0xF2AF, 0x6C9A, 0xF2B0, 0x6F2C, + 0xF2B1, 0x77E5, 0xF2B2, 0x7825, 0xF2B3, 0x7949, 0xF2B4, 0x7957, + 0xF2B5, 0x7D19, 0xF2B6, 0x80A2, 0xF2B7, 0x8102, 0xF2B8, 0x81F3, + 0xF2B9, 0x829D, 0xF2BA, 0x82B7, 0xF2BB, 0x8718, 0xF2BC, 0x8A8C, + 0xF2BD, 0xF9FC, 0xF2BE, 0x8D04, 0xF2BF, 0x8DBE, 0xF2C0, 0x9072, + 0xF2C1, 0x76F4, 0xF2C2, 0x7A19, 0xF2C3, 0x7A37, 0xF2C4, 0x7E54, + 0xF2C5, 0x8077, 0xF2C6, 0x5507, 0xF2C7, 0x55D4, 0xF2C8, 0x5875, + 0xF2C9, 0x632F, 0xF2CA, 0x6422, 0xF2CB, 0x6649, 0xF2CC, 0x664B, + 0xF2CD, 0x686D, 0xF2CE, 0x699B, 0xF2CF, 0x6B84, 0xF2D0, 0x6D25, + 0xF2D1, 0x6EB1, 0xF2D2, 0x73CD, 0xF2D3, 0x7468, 0xF2D4, 0x74A1, + 0xF2D5, 0x755B, 0xF2D6, 0x75B9, 0xF2D7, 0x76E1, 0xF2D8, 0x771E, + 0xF2D9, 0x778B, 0xF2DA, 0x79E6, 0xF2DB, 0x7E09, 0xF2DC, 0x7E1D, + 0xF2DD, 0x81FB, 0xF2DE, 0x852F, 0xF2DF, 0x8897, 0xF2E0, 0x8A3A, + 0xF2E1, 0x8CD1, 0xF2E2, 0x8EEB, 0xF2E3, 0x8FB0, 0xF2E4, 0x9032, + 0xF2E5, 0x93AD, 0xF2E6, 0x9663, 0xF2E7, 0x9673, 0xF2E8, 0x9707, + 0xF2E9, 0x4F84, 0xF2EA, 0x53F1, 0xF2EB, 0x59EA, 0xF2EC, 0x5AC9, + 0xF2ED, 0x5E19, 0xF2EE, 0x684E, 0xF2EF, 0x74C6, 0xF2F0, 0x75BE, + 0xF2F1, 0x79E9, 0xF2F2, 0x7A92, 0xF2F3, 0x81A3, 0xF2F4, 0x86ED, + 0xF2F5, 0x8CEA, 0xF2F6, 0x8DCC, 0xF2F7, 0x8FED, 0xF2F8, 0x659F, + 0xF2F9, 0x6715, 0xF2FA, 0xF9FD, 0xF2FB, 0x57F7, 0xF2FC, 0x6F57, + 0xF2FD, 0x7DDD, 0xF2FE, 0x8F2F, 0xF3A1, 0x93F6, 0xF3A2, 0x96C6, + 0xF3A3, 0x5FB5, 0xF3A4, 0x61F2, 0xF3A5, 0x6F84, 0xF3A6, 0x4E14, + 0xF3A7, 0x4F98, 0xF3A8, 0x501F, 0xF3A9, 0x53C9, 0xF3AA, 0x55DF, + 0xF3AB, 0x5D6F, 0xF3AC, 0x5DEE, 0xF3AD, 0x6B21, 0xF3AE, 0x6B64, + 0xF3AF, 0x78CB, 0xF3B0, 0x7B9A, 0xF3B1, 0xF9FE, 0xF3B2, 0x8E49, + 0xF3B3, 0x8ECA, 0xF3B4, 0x906E, 0xF3B5, 0x6349, 0xF3B6, 0x643E, + 0xF3B7, 0x7740, 0xF3B8, 0x7A84, 0xF3B9, 0x932F, 0xF3BA, 0x947F, + 0xF3BB, 0x9F6A, 0xF3BC, 0x64B0, 0xF3BD, 0x6FAF, 0xF3BE, 0x71E6, + 0xF3BF, 0x74A8, 0xF3C0, 0x74DA, 0xF3C1, 0x7AC4, 0xF3C2, 0x7C12, + 0xF3C3, 0x7E82, 0xF3C4, 0x7CB2, 0xF3C5, 0x7E98, 0xF3C6, 0x8B9A, + 0xF3C7, 0x8D0A, 0xF3C8, 0x947D, 0xF3C9, 0x9910, 0xF3CA, 0x994C, + 0xF3CB, 0x5239, 0xF3CC, 0x5BDF, 0xF3CD, 0x64E6, 0xF3CE, 0x672D, + 0xF3CF, 0x7D2E, 0xF3D0, 0x50ED, 0xF3D1, 0x53C3, 0xF3D2, 0x5879, + 0xF3D3, 0x6158, 0xF3D4, 0x6159, 0xF3D5, 0x61FA, 0xF3D6, 0x65AC, + 0xF3D7, 0x7AD9, 0xF3D8, 0x8B92, 0xF3D9, 0x8B96, 0xF3DA, 0x5009, + 0xF3DB, 0x5021, 0xF3DC, 0x5275, 0xF3DD, 0x5531, 0xF3DE, 0x5A3C, + 0xF3DF, 0x5EE0, 0xF3E0, 0x5F70, 0xF3E1, 0x6134, 0xF3E2, 0x655E, + 0xF3E3, 0x660C, 0xF3E4, 0x6636, 0xF3E5, 0x66A2, 0xF3E6, 0x69CD, + 0xF3E7, 0x6EC4, 0xF3E8, 0x6F32, 0xF3E9, 0x7316, 0xF3EA, 0x7621, + 0xF3EB, 0x7A93, 0xF3EC, 0x8139, 0xF3ED, 0x8259, 0xF3EE, 0x83D6, + 0xF3EF, 0x84BC, 0xF3F0, 0x50B5, 0xF3F1, 0x57F0, 0xF3F2, 0x5BC0, + 0xF3F3, 0x5BE8, 0xF3F4, 0x5F69, 0xF3F5, 0x63A1, 0xF3F6, 0x7826, + 0xF3F7, 0x7DB5, 0xF3F8, 0x83DC, 0xF3F9, 0x8521, 0xF3FA, 0x91C7, + 0xF3FB, 0x91F5, 0xF3FC, 0x518A, 0xF3FD, 0x67F5, 0xF3FE, 0x7B56, + 0xF4A1, 0x8CAC, 0xF4A2, 0x51C4, 0xF4A3, 0x59BB, 0xF4A4, 0x60BD, + 0xF4A5, 0x8655, 0xF4A6, 0x501C, 0xF4A7, 0xF9FF, 0xF4A8, 0x5254, + 0xF4A9, 0x5C3A, 0xF4AA, 0x617D, 0xF4AB, 0x621A, 0xF4AC, 0x62D3, + 0xF4AD, 0x64F2, 0xF4AE, 0x65A5, 0xF4AF, 0x6ECC, 0xF4B0, 0x7620, + 0xF4B1, 0x810A, 0xF4B2, 0x8E60, 0xF4B3, 0x965F, 0xF4B4, 0x96BB, + 0xF4B5, 0x4EDF, 0xF4B6, 0x5343, 0xF4B7, 0x5598, 0xF4B8, 0x5929, + 0xF4B9, 0x5DDD, 0xF4BA, 0x64C5, 0xF4BB, 0x6CC9, 0xF4BC, 0x6DFA, + 0xF4BD, 0x7394, 0xF4BE, 0x7A7F, 0xF4BF, 0x821B, 0xF4C0, 0x85A6, + 0xF4C1, 0x8CE4, 0xF4C2, 0x8E10, 0xF4C3, 0x9077, 0xF4C4, 0x91E7, + 0xF4C5, 0x95E1, 0xF4C6, 0x9621, 0xF4C7, 0x97C6, 0xF4C8, 0x51F8, + 0xF4C9, 0x54F2, 0xF4CA, 0x5586, 0xF4CB, 0x5FB9, 0xF4CC, 0x64A4, + 0xF4CD, 0x6F88, 0xF4CE, 0x7DB4, 0xF4CF, 0x8F1F, 0xF4D0, 0x8F4D, + 0xF4D1, 0x9435, 0xF4D2, 0x50C9, 0xF4D3, 0x5C16, 0xF4D4, 0x6CBE, + 0xF4D5, 0x6DFB, 0xF4D6, 0x751B, 0xF4D7, 0x77BB, 0xF4D8, 0x7C3D, + 0xF4D9, 0x7C64, 0xF4DA, 0x8A79, 0xF4DB, 0x8AC2, 0xF4DC, 0x581E, + 0xF4DD, 0x59BE, 0xF4DE, 0x5E16, 0xF4DF, 0x6377, 0xF4E0, 0x7252, + 0xF4E1, 0x758A, 0xF4E2, 0x776B, 0xF4E3, 0x8ADC, 0xF4E4, 0x8CBC, + 0xF4E5, 0x8F12, 0xF4E6, 0x5EF3, 0xF4E7, 0x6674, 0xF4E8, 0x6DF8, + 0xF4E9, 0x807D, 0xF4EA, 0x83C1, 0xF4EB, 0x8ACB, 0xF4EC, 0x9751, + 0xF4ED, 0x9BD6, 0xF4EE, 0xFA00, 0xF4EF, 0x5243, 0xF4F0, 0x66FF, + 0xF4F1, 0x6D95, 0xF4F2, 0x6EEF, 0xF4F3, 0x7DE0, 0xF4F4, 0x8AE6, + 0xF4F5, 0x902E, 0xF4F6, 0x905E, 0xF4F7, 0x9AD4, 0xF4F8, 0x521D, + 0xF4F9, 0x527F, 0xF4FA, 0x54E8, 0xF4FB, 0x6194, 0xF4FC, 0x6284, + 0xF4FD, 0x62DB, 0xF4FE, 0x68A2, 0xF5A1, 0x6912, 0xF5A2, 0x695A, + 0xF5A3, 0x6A35, 0xF5A4, 0x7092, 0xF5A5, 0x7126, 0xF5A6, 0x785D, + 0xF5A7, 0x7901, 0xF5A8, 0x790E, 0xF5A9, 0x79D2, 0xF5AA, 0x7A0D, + 0xF5AB, 0x8096, 0xF5AC, 0x8278, 0xF5AD, 0x82D5, 0xF5AE, 0x8349, + 0xF5AF, 0x8549, 0xF5B0, 0x8C82, 0xF5B1, 0x8D85, 0xF5B2, 0x9162, + 0xF5B3, 0x918B, 0xF5B4, 0x91AE, 0xF5B5, 0x4FC3, 0xF5B6, 0x56D1, + 0xF5B7, 0x71ED, 0xF5B8, 0x77D7, 0xF5B9, 0x8700, 0xF5BA, 0x89F8, + 0xF5BB, 0x5BF8, 0xF5BC, 0x5FD6, 0xF5BD, 0x6751, 0xF5BE, 0x90A8, + 0xF5BF, 0x53E2, 0xF5C0, 0x585A, 0xF5C1, 0x5BF5, 0xF5C2, 0x60A4, + 0xF5C3, 0x6181, 0xF5C4, 0x6460, 0xF5C5, 0x7E3D, 0xF5C6, 0x8070, + 0xF5C7, 0x8525, 0xF5C8, 0x9283, 0xF5C9, 0x64AE, 0xF5CA, 0x50AC, + 0xF5CB, 0x5D14, 0xF5CC, 0x6700, 0xF5CD, 0x589C, 0xF5CE, 0x62BD, + 0xF5CF, 0x63A8, 0xF5D0, 0x690E, 0xF5D1, 0x6978, 0xF5D2, 0x6A1E, + 0xF5D3, 0x6E6B, 0xF5D4, 0x76BA, 0xF5D5, 0x79CB, 0xF5D6, 0x82BB, + 0xF5D7, 0x8429, 0xF5D8, 0x8ACF, 0xF5D9, 0x8DA8, 0xF5DA, 0x8FFD, + 0xF5DB, 0x9112, 0xF5DC, 0x914B, 0xF5DD, 0x919C, 0xF5DE, 0x9310, + 0xF5DF, 0x9318, 0xF5E0, 0x939A, 0xF5E1, 0x96DB, 0xF5E2, 0x9A36, + 0xF5E3, 0x9C0D, 0xF5E4, 0x4E11, 0xF5E5, 0x755C, 0xF5E6, 0x795D, + 0xF5E7, 0x7AFA, 0xF5E8, 0x7B51, 0xF5E9, 0x7BC9, 0xF5EA, 0x7E2E, + 0xF5EB, 0x84C4, 0xF5EC, 0x8E59, 0xF5ED, 0x8E74, 0xF5EE, 0x8EF8, + 0xF5EF, 0x9010, 0xF5F0, 0x6625, 0xF5F1, 0x693F, 0xF5F2, 0x7443, + 0xF5F3, 0x51FA, 0xF5F4, 0x672E, 0xF5F5, 0x9EDC, 0xF5F6, 0x5145, + 0xF5F7, 0x5FE0, 0xF5F8, 0x6C96, 0xF5F9, 0x87F2, 0xF5FA, 0x885D, + 0xF5FB, 0x8877, 0xF5FC, 0x60B4, 0xF5FD, 0x81B5, 0xF5FE, 0x8403, + 0xF6A1, 0x8D05, 0xF6A2, 0x53D6, 0xF6A3, 0x5439, 0xF6A4, 0x5634, + 0xF6A5, 0x5A36, 0xF6A6, 0x5C31, 0xF6A7, 0x708A, 0xF6A8, 0x7FE0, + 0xF6A9, 0x805A, 0xF6AA, 0x8106, 0xF6AB, 0x81ED, 0xF6AC, 0x8DA3, + 0xF6AD, 0x9189, 0xF6AE, 0x9A5F, 0xF6AF, 0x9DF2, 0xF6B0, 0x5074, + 0xF6B1, 0x4EC4, 0xF6B2, 0x53A0, 0xF6B3, 0x60FB, 0xF6B4, 0x6E2C, + 0xF6B5, 0x5C64, 0xF6B6, 0x4F88, 0xF6B7, 0x5024, 0xF6B8, 0x55E4, + 0xF6B9, 0x5CD9, 0xF6BA, 0x5E5F, 0xF6BB, 0x6065, 0xF6BC, 0x6894, + 0xF6BD, 0x6CBB, 0xF6BE, 0x6DC4, 0xF6BF, 0x71BE, 0xF6C0, 0x75D4, + 0xF6C1, 0x75F4, 0xF6C2, 0x7661, 0xF6C3, 0x7A1A, 0xF6C4, 0x7A49, + 0xF6C5, 0x7DC7, 0xF6C6, 0x7DFB, 0xF6C7, 0x7F6E, 0xF6C8, 0x81F4, + 0xF6C9, 0x86A9, 0xF6CA, 0x8F1C, 0xF6CB, 0x96C9, 0xF6CC, 0x99B3, + 0xF6CD, 0x9F52, 0xF6CE, 0x5247, 0xF6CF, 0x52C5, 0xF6D0, 0x98ED, + 0xF6D1, 0x89AA, 0xF6D2, 0x4E03, 0xF6D3, 0x67D2, 0xF6D4, 0x6F06, + 0xF6D5, 0x4FB5, 0xF6D6, 0x5BE2, 0xF6D7, 0x6795, 0xF6D8, 0x6C88, + 0xF6D9, 0x6D78, 0xF6DA, 0x741B, 0xF6DB, 0x7827, 0xF6DC, 0x91DD, + 0xF6DD, 0x937C, 0xF6DE, 0x87C4, 0xF6DF, 0x79E4, 0xF6E0, 0x7A31, + 0xF6E1, 0x5FEB, 0xF6E2, 0x4ED6, 0xF6E3, 0x54A4, 0xF6E4, 0x553E, + 0xF6E5, 0x58AE, 0xF6E6, 0x59A5, 0xF6E7, 0x60F0, 0xF6E8, 0x6253, + 0xF6E9, 0x62D6, 0xF6EA, 0x6736, 0xF6EB, 0x6955, 0xF6EC, 0x8235, + 0xF6ED, 0x9640, 0xF6EE, 0x99B1, 0xF6EF, 0x99DD, 0xF6F0, 0x502C, + 0xF6F1, 0x5353, 0xF6F2, 0x5544, 0xF6F3, 0x577C, 0xF6F4, 0xFA01, + 0xF6F5, 0x6258, 0xF6F6, 0xFA02, 0xF6F7, 0x64E2, 0xF6F8, 0x666B, + 0xF6F9, 0x67DD, 0xF6FA, 0x6FC1, 0xF6FB, 0x6FEF, 0xF6FC, 0x7422, + 0xF6FD, 0x7438, 0xF6FE, 0x8A17, 0xF7A1, 0x9438, 0xF7A2, 0x5451, + 0xF7A3, 0x5606, 0xF7A4, 0x5766, 0xF7A5, 0x5F48, 0xF7A6, 0x619A, + 0xF7A7, 0x6B4E, 0xF7A8, 0x7058, 0xF7A9, 0x70AD, 0xF7AA, 0x7DBB, + 0xF7AB, 0x8A95, 0xF7AC, 0x596A, 0xF7AD, 0x812B, 0xF7AE, 0x63A2, + 0xF7AF, 0x7708, 0xF7B0, 0x803D, 0xF7B1, 0x8CAA, 0xF7B2, 0x5854, + 0xF7B3, 0x642D, 0xF7B4, 0x69BB, 0xF7B5, 0x5B95, 0xF7B6, 0x5E11, + 0xF7B7, 0x6E6F, 0xF7B8, 0xFA03, 0xF7B9, 0x8569, 0xF7BA, 0x514C, + 0xF7BB, 0x53F0, 0xF7BC, 0x592A, 0xF7BD, 0x6020, 0xF7BE, 0x614B, + 0xF7BF, 0x6B86, 0xF7C0, 0x6C70, 0xF7C1, 0x6CF0, 0xF7C2, 0x7B1E, + 0xF7C3, 0x80CE, 0xF7C4, 0x82D4, 0xF7C5, 0x8DC6, 0xF7C6, 0x90B0, + 0xF7C7, 0x98B1, 0xF7C8, 0xFA04, 0xF7C9, 0x64C7, 0xF7CA, 0x6FA4, + 0xF7CB, 0x6491, 0xF7CC, 0x6504, 0xF7CD, 0x514E, 0xF7CE, 0x5410, + 0xF7CF, 0x571F, 0xF7D0, 0x8A0E, 0xF7D1, 0x615F, 0xF7D2, 0x6876, + 0xF7D3, 0xFA05, 0xF7D4, 0x75DB, 0xF7D5, 0x7B52, 0xF7D6, 0x7D71, + 0xF7D7, 0x901A, 0xF7D8, 0x5806, 0xF7D9, 0x69CC, 0xF7DA, 0x817F, + 0xF7DB, 0x892A, 0xF7DC, 0x9000, 0xF7DD, 0x9839, 0xF7DE, 0x5078, + 0xF7DF, 0x5957, 0xF7E0, 0x59AC, 0xF7E1, 0x6295, 0xF7E2, 0x900F, + 0xF7E3, 0x9B2A, 0xF7E4, 0x615D, 0xF7E5, 0x7279, 0xF7E6, 0x95D6, + 0xF7E7, 0x5761, 0xF7E8, 0x5A46, 0xF7E9, 0x5DF4, 0xF7EA, 0x628A, + 0xF7EB, 0x64AD, 0xF7EC, 0x64FA, 0xF7ED, 0x6777, 0xF7EE, 0x6CE2, + 0xF7EF, 0x6D3E, 0xF7F0, 0x722C, 0xF7F1, 0x7436, 0xF7F2, 0x7834, + 0xF7F3, 0x7F77, 0xF7F4, 0x82AD, 0xF7F5, 0x8DDB, 0xF7F6, 0x9817, + 0xF7F7, 0x5224, 0xF7F8, 0x5742, 0xF7F9, 0x677F, 0xF7FA, 0x7248, + 0xF7FB, 0x74E3, 0xF7FC, 0x8CA9, 0xF7FD, 0x8FA6, 0xF7FE, 0x9211, + 0xF8A1, 0x962A, 0xF8A2, 0x516B, 0xF8A3, 0x53ED, 0xF8A4, 0x634C, + 0xF8A5, 0x4F69, 0xF8A6, 0x5504, 0xF8A7, 0x6096, 0xF8A8, 0x6557, + 0xF8A9, 0x6C9B, 0xF8AA, 0x6D7F, 0xF8AB, 0x724C, 0xF8AC, 0x72FD, + 0xF8AD, 0x7A17, 0xF8AE, 0x8987, 0xF8AF, 0x8C9D, 0xF8B0, 0x5F6D, + 0xF8B1, 0x6F8E, 0xF8B2, 0x70F9, 0xF8B3, 0x81A8, 0xF8B4, 0x610E, + 0xF8B5, 0x4FBF, 0xF8B6, 0x504F, 0xF8B7, 0x6241, 0xF8B8, 0x7247, + 0xF8B9, 0x7BC7, 0xF8BA, 0x7DE8, 0xF8BB, 0x7FE9, 0xF8BC, 0x904D, + 0xF8BD, 0x97AD, 0xF8BE, 0x9A19, 0xF8BF, 0x8CB6, 0xF8C0, 0x576A, + 0xF8C1, 0x5E73, 0xF8C2, 0x67B0, 0xF8C3, 0x840D, 0xF8C4, 0x8A55, + 0xF8C5, 0x5420, 0xF8C6, 0x5B16, 0xF8C7, 0x5E63, 0xF8C8, 0x5EE2, + 0xF8C9, 0x5F0A, 0xF8CA, 0x6583, 0xF8CB, 0x80BA, 0xF8CC, 0x853D, + 0xF8CD, 0x9589, 0xF8CE, 0x965B, 0xF8CF, 0x4F48, 0xF8D0, 0x5305, + 0xF8D1, 0x530D, 0xF8D2, 0x530F, 0xF8D3, 0x5486, 0xF8D4, 0x54FA, + 0xF8D5, 0x5703, 0xF8D6, 0x5E03, 0xF8D7, 0x6016, 0xF8D8, 0x629B, + 0xF8D9, 0x62B1, 0xF8DA, 0x6355, 0xF8DB, 0xFA06, 0xF8DC, 0x6CE1, + 0xF8DD, 0x6D66, 0xF8DE, 0x75B1, 0xF8DF, 0x7832, 0xF8E0, 0x80DE, + 0xF8E1, 0x812F, 0xF8E2, 0x82DE, 0xF8E3, 0x8461, 0xF8E4, 0x84B2, + 0xF8E5, 0x888D, 0xF8E6, 0x8912, 0xF8E7, 0x900B, 0xF8E8, 0x92EA, + 0xF8E9, 0x98FD, 0xF8EA, 0x9B91, 0xF8EB, 0x5E45, 0xF8EC, 0x66B4, + 0xF8ED, 0x66DD, 0xF8EE, 0x7011, 0xF8EF, 0x7206, 0xF8F0, 0xFA07, + 0xF8F1, 0x4FF5, 0xF8F2, 0x527D, 0xF8F3, 0x5F6A, 0xF8F4, 0x6153, + 0xF8F5, 0x6753, 0xF8F6, 0x6A19, 0xF8F7, 0x6F02, 0xF8F8, 0x74E2, + 0xF8F9, 0x7968, 0xF8FA, 0x8868, 0xF8FB, 0x8C79, 0xF8FC, 0x98C7, + 0xF8FD, 0x98C4, 0xF8FE, 0x9A43, 0xF9A1, 0x54C1, 0xF9A2, 0x7A1F, + 0xF9A3, 0x6953, 0xF9A4, 0x8AF7, 0xF9A5, 0x8C4A, 0xF9A6, 0x98A8, + 0xF9A7, 0x99AE, 0xF9A8, 0x5F7C, 0xF9A9, 0x62AB, 0xF9AA, 0x75B2, + 0xF9AB, 0x76AE, 0xF9AC, 0x88AB, 0xF9AD, 0x907F, 0xF9AE, 0x9642, + 0xF9AF, 0x5339, 0xF9B0, 0x5F3C, 0xF9B1, 0x5FC5, 0xF9B2, 0x6CCC, + 0xF9B3, 0x73CC, 0xF9B4, 0x7562, 0xF9B5, 0x758B, 0xF9B6, 0x7B46, + 0xF9B7, 0x82FE, 0xF9B8, 0x999D, 0xF9B9, 0x4E4F, 0xF9BA, 0x903C, + 0xF9BB, 0x4E0B, 0xF9BC, 0x4F55, 0xF9BD, 0x53A6, 0xF9BE, 0x590F, + 0xF9BF, 0x5EC8, 0xF9C0, 0x6630, 0xF9C1, 0x6CB3, 0xF9C2, 0x7455, + 0xF9C3, 0x8377, 0xF9C4, 0x8766, 0xF9C5, 0x8CC0, 0xF9C6, 0x9050, + 0xF9C7, 0x971E, 0xF9C8, 0x9C15, 0xF9C9, 0x58D1, 0xF9CA, 0x5B78, + 0xF9CB, 0x8650, 0xF9CC, 0x8B14, 0xF9CD, 0x9DB4, 0xF9CE, 0x5BD2, + 0xF9CF, 0x6068, 0xF9D0, 0x608D, 0xF9D1, 0x65F1, 0xF9D2, 0x6C57, + 0xF9D3, 0x6F22, 0xF9D4, 0x6FA3, 0xF9D5, 0x701A, 0xF9D6, 0x7F55, + 0xF9D7, 0x7FF0, 0xF9D8, 0x9591, 0xF9D9, 0x9592, 0xF9DA, 0x9650, + 0xF9DB, 0x97D3, 0xF9DC, 0x5272, 0xF9DD, 0x8F44, 0xF9DE, 0x51FD, + 0xF9DF, 0x542B, 0xF9E0, 0x54B8, 0xF9E1, 0x5563, 0xF9E2, 0x558A, + 0xF9E3, 0x6ABB, 0xF9E4, 0x6DB5, 0xF9E5, 0x7DD8, 0xF9E6, 0x8266, + 0xF9E7, 0x929C, 0xF9E8, 0x9677, 0xF9E9, 0x9E79, 0xF9EA, 0x5408, + 0xF9EB, 0x54C8, 0xF9EC, 0x76D2, 0xF9ED, 0x86E4, 0xF9EE, 0x95A4, + 0xF9EF, 0x95D4, 0xF9F0, 0x965C, 0xF9F1, 0x4EA2, 0xF9F2, 0x4F09, + 0xF9F3, 0x59EE, 0xF9F4, 0x5AE6, 0xF9F5, 0x5DF7, 0xF9F6, 0x6052, + 0xF9F7, 0x6297, 0xF9F8, 0x676D, 0xF9F9, 0x6841, 0xF9FA, 0x6C86, + 0xF9FB, 0x6E2F, 0xF9FC, 0x7F38, 0xF9FD, 0x809B, 0xF9FE, 0x822A, + 0xFAA1, 0xFA08, 0xFAA2, 0xFA09, 0xFAA3, 0x9805, 0xFAA4, 0x4EA5, + 0xFAA5, 0x5055, 0xFAA6, 0x54B3, 0xFAA7, 0x5793, 0xFAA8, 0x595A, + 0xFAA9, 0x5B69, 0xFAAA, 0x5BB3, 0xFAAB, 0x61C8, 0xFAAC, 0x6977, + 0xFAAD, 0x6D77, 0xFAAE, 0x7023, 0xFAAF, 0x87F9, 0xFAB0, 0x89E3, + 0xFAB1, 0x8A72, 0xFAB2, 0x8AE7, 0xFAB3, 0x9082, 0xFAB4, 0x99ED, + 0xFAB5, 0x9AB8, 0xFAB6, 0x52BE, 0xFAB7, 0x6838, 0xFAB8, 0x5016, + 0xFAB9, 0x5E78, 0xFABA, 0x674F, 0xFABB, 0x8347, 0xFABC, 0x884C, + 0xFABD, 0x4EAB, 0xFABE, 0x5411, 0xFABF, 0x56AE, 0xFAC0, 0x73E6, + 0xFAC1, 0x9115, 0xFAC2, 0x97FF, 0xFAC3, 0x9909, 0xFAC4, 0x9957, + 0xFAC5, 0x9999, 0xFAC6, 0x5653, 0xFAC7, 0x589F, 0xFAC8, 0x865B, + 0xFAC9, 0x8A31, 0xFACA, 0x61B2, 0xFACB, 0x6AF6, 0xFACC, 0x737B, + 0xFACD, 0x8ED2, 0xFACE, 0x6B47, 0xFACF, 0x96AA, 0xFAD0, 0x9A57, + 0xFAD1, 0x5955, 0xFAD2, 0x7200, 0xFAD3, 0x8D6B, 0xFAD4, 0x9769, + 0xFAD5, 0x4FD4, 0xFAD6, 0x5CF4, 0xFAD7, 0x5F26, 0xFAD8, 0x61F8, + 0xFAD9, 0x665B, 0xFADA, 0x6CEB, 0xFADB, 0x70AB, 0xFADC, 0x7384, + 0xFADD, 0x73B9, 0xFADE, 0x73FE, 0xFADF, 0x7729, 0xFAE0, 0x774D, + 0xFAE1, 0x7D43, 0xFAE2, 0x7D62, 0xFAE3, 0x7E23, 0xFAE4, 0x8237, + 0xFAE5, 0x8852, 0xFAE6, 0xFA0A, 0xFAE7, 0x8CE2, 0xFAE8, 0x9249, + 0xFAE9, 0x986F, 0xFAEA, 0x5B51, 0xFAEB, 0x7A74, 0xFAEC, 0x8840, + 0xFAED, 0x9801, 0xFAEE, 0x5ACC, 0xFAEF, 0x4FE0, 0xFAF0, 0x5354, + 0xFAF1, 0x593E, 0xFAF2, 0x5CFD, 0xFAF3, 0x633E, 0xFAF4, 0x6D79, + 0xFAF5, 0x72F9, 0xFAF6, 0x8105, 0xFAF7, 0x8107, 0xFAF8, 0x83A2, + 0xFAF9, 0x92CF, 0xFAFA, 0x9830, 0xFAFB, 0x4EA8, 0xFAFC, 0x5144, + 0xFAFD, 0x5211, 0xFAFE, 0x578B, 0xFBA1, 0x5F62, 0xFBA2, 0x6CC2, + 0xFBA3, 0x6ECE, 0xFBA4, 0x7005, 0xFBA5, 0x7050, 0xFBA6, 0x70AF, + 0xFBA7, 0x7192, 0xFBA8, 0x73E9, 0xFBA9, 0x7469, 0xFBAA, 0x834A, + 0xFBAB, 0x87A2, 0xFBAC, 0x8861, 0xFBAD, 0x9008, 0xFBAE, 0x90A2, + 0xFBAF, 0x93A3, 0xFBB0, 0x99A8, 0xFBB1, 0x516E, 0xFBB2, 0x5F57, + 0xFBB3, 0x60E0, 0xFBB4, 0x6167, 0xFBB5, 0x66B3, 0xFBB6, 0x8559, + 0xFBB7, 0x8E4A, 0xFBB8, 0x91AF, 0xFBB9, 0x978B, 0xFBBA, 0x4E4E, + 0xFBBB, 0x4E92, 0xFBBC, 0x547C, 0xFBBD, 0x58D5, 0xFBBE, 0x58FA, + 0xFBBF, 0x597D, 0xFBC0, 0x5CB5, 0xFBC1, 0x5F27, 0xFBC2, 0x6236, + 0xFBC3, 0x6248, 0xFBC4, 0x660A, 0xFBC5, 0x6667, 0xFBC6, 0x6BEB, + 0xFBC7, 0x6D69, 0xFBC8, 0x6DCF, 0xFBC9, 0x6E56, 0xFBCA, 0x6EF8, + 0xFBCB, 0x6F94, 0xFBCC, 0x6FE0, 0xFBCD, 0x6FE9, 0xFBCE, 0x705D, + 0xFBCF, 0x72D0, 0xFBD0, 0x7425, 0xFBD1, 0x745A, 0xFBD2, 0x74E0, + 0xFBD3, 0x7693, 0xFBD4, 0x795C, 0xFBD5, 0x7CCA, 0xFBD6, 0x7E1E, + 0xFBD7, 0x80E1, 0xFBD8, 0x82A6, 0xFBD9, 0x846B, 0xFBDA, 0x84BF, + 0xFBDB, 0x864E, 0xFBDC, 0x865F, 0xFBDD, 0x8774, 0xFBDE, 0x8B77, + 0xFBDF, 0x8C6A, 0xFBE0, 0x93AC, 0xFBE1, 0x9800, 0xFBE2, 0x9865, + 0xFBE3, 0x60D1, 0xFBE4, 0x6216, 0xFBE5, 0x9177, 0xFBE6, 0x5A5A, + 0xFBE7, 0x660F, 0xFBE8, 0x6DF7, 0xFBE9, 0x6E3E, 0xFBEA, 0x743F, + 0xFBEB, 0x9B42, 0xFBEC, 0x5FFD, 0xFBED, 0x60DA, 0xFBEE, 0x7B0F, + 0xFBEF, 0x54C4, 0xFBF0, 0x5F18, 0xFBF1, 0x6C5E, 0xFBF2, 0x6CD3, + 0xFBF3, 0x6D2A, 0xFBF4, 0x70D8, 0xFBF5, 0x7D05, 0xFBF6, 0x8679, + 0xFBF7, 0x8A0C, 0xFBF8, 0x9D3B, 0xFBF9, 0x5316, 0xFBFA, 0x548C, + 0xFBFB, 0x5B05, 0xFBFC, 0x6A3A, 0xFBFD, 0x706B, 0xFBFE, 0x7575, + 0xFCA1, 0x798D, 0xFCA2, 0x79BE, 0xFCA3, 0x82B1, 0xFCA4, 0x83EF, + 0xFCA5, 0x8A71, 0xFCA6, 0x8B41, 0xFCA7, 0x8CA8, 0xFCA8, 0x9774, + 0xFCA9, 0xFA0B, 0xFCAA, 0x64F4, 0xFCAB, 0x652B, 0xFCAC, 0x78BA, + 0xFCAD, 0x78BB, 0xFCAE, 0x7A6B, 0xFCAF, 0x4E38, 0xFCB0, 0x559A, + 0xFCB1, 0x5950, 0xFCB2, 0x5BA6, 0xFCB3, 0x5E7B, 0xFCB4, 0x60A3, + 0xFCB5, 0x63DB, 0xFCB6, 0x6B61, 0xFCB7, 0x6665, 0xFCB8, 0x6853, + 0xFCB9, 0x6E19, 0xFCBA, 0x7165, 0xFCBB, 0x74B0, 0xFCBC, 0x7D08, + 0xFCBD, 0x9084, 0xFCBE, 0x9A69, 0xFCBF, 0x9C25, 0xFCC0, 0x6D3B, + 0xFCC1, 0x6ED1, 0xFCC2, 0x733E, 0xFCC3, 0x8C41, 0xFCC4, 0x95CA, + 0xFCC5, 0x51F0, 0xFCC6, 0x5E4C, 0xFCC7, 0x5FA8, 0xFCC8, 0x604D, + 0xFCC9, 0x60F6, 0xFCCA, 0x6130, 0xFCCB, 0x614C, 0xFCCC, 0x6643, + 0xFCCD, 0x6644, 0xFCCE, 0x69A5, 0xFCCF, 0x6CC1, 0xFCD0, 0x6E5F, + 0xFCD1, 0x6EC9, 0xFCD2, 0x6F62, 0xFCD3, 0x714C, 0xFCD4, 0x749C, + 0xFCD5, 0x7687, 0xFCD6, 0x7BC1, 0xFCD7, 0x7C27, 0xFCD8, 0x8352, + 0xFCD9, 0x8757, 0xFCDA, 0x9051, 0xFCDB, 0x968D, 0xFCDC, 0x9EC3, + 0xFCDD, 0x532F, 0xFCDE, 0x56DE, 0xFCDF, 0x5EFB, 0xFCE0, 0x5F8A, + 0xFCE1, 0x6062, 0xFCE2, 0x6094, 0xFCE3, 0x61F7, 0xFCE4, 0x6666, + 0xFCE5, 0x6703, 0xFCE6, 0x6A9C, 0xFCE7, 0x6DEE, 0xFCE8, 0x6FAE, + 0xFCE9, 0x7070, 0xFCEA, 0x736A, 0xFCEB, 0x7E6A, 0xFCEC, 0x81BE, + 0xFCED, 0x8334, 0xFCEE, 0x86D4, 0xFCEF, 0x8AA8, 0xFCF0, 0x8CC4, + 0xFCF1, 0x5283, 0xFCF2, 0x7372, 0xFCF3, 0x5B96, 0xFCF4, 0x6A6B, + 0xFCF5, 0x9404, 0xFCF6, 0x54EE, 0xFCF7, 0x5686, 0xFCF8, 0x5B5D, + 0xFCF9, 0x6548, 0xFCFA, 0x6585, 0xFCFB, 0x66C9, 0xFCFC, 0x689F, + 0xFCFD, 0x6D8D, 0xFCFE, 0x6DC6, 0xFDA1, 0x723B, 0xFDA2, 0x80B4, + 0xFDA3, 0x9175, 0xFDA4, 0x9A4D, 0xFDA5, 0x4FAF, 0xFDA6, 0x5019, + 0xFDA7, 0x539A, 0xFDA8, 0x540E, 0xFDA9, 0x543C, 0xFDAA, 0x5589, + 0xFDAB, 0x55C5, 0xFDAC, 0x5E3F, 0xFDAD, 0x5F8C, 0xFDAE, 0x673D, + 0xFDAF, 0x7166, 0xFDB0, 0x73DD, 0xFDB1, 0x9005, 0xFDB2, 0x52DB, + 0xFDB3, 0x52F3, 0xFDB4, 0x5864, 0xFDB5, 0x58CE, 0xFDB6, 0x7104, + 0xFDB7, 0x718F, 0xFDB8, 0x71FB, 0xFDB9, 0x85B0, 0xFDBA, 0x8A13, + 0xFDBB, 0x6688, 0xFDBC, 0x85A8, 0xFDBD, 0x55A7, 0xFDBE, 0x6684, + 0xFDBF, 0x714A, 0xFDC0, 0x8431, 0xFDC1, 0x5349, 0xFDC2, 0x5599, + 0xFDC3, 0x6BC1, 0xFDC4, 0x5F59, 0xFDC5, 0x5FBD, 0xFDC6, 0x63EE, + 0xFDC7, 0x6689, 0xFDC8, 0x7147, 0xFDC9, 0x8AF1, 0xFDCA, 0x8F1D, + 0xFDCB, 0x9EBE, 0xFDCC, 0x4F11, 0xFDCD, 0x643A, 0xFDCE, 0x70CB, + 0xFDCF, 0x7566, 0xFDD0, 0x8667, 0xFDD1, 0x6064, 0xFDD2, 0x8B4E, + 0xFDD3, 0x9DF8, 0xFDD4, 0x5147, 0xFDD5, 0x51F6, 0xFDD6, 0x5308, + 0xFDD7, 0x6D36, 0xFDD8, 0x80F8, 0xFDD9, 0x9ED1, 0xFDDA, 0x6615, + 0xFDDB, 0x6B23, 0xFDDC, 0x7098, 0xFDDD, 0x75D5, 0xFDDE, 0x5403, + 0xFDDF, 0x5C79, 0xFDE0, 0x7D07, 0xFDE1, 0x8A16, 0xFDE2, 0x6B20, + 0xFDE3, 0x6B3D, 0xFDE4, 0x6B46, 0xFDE5, 0x5438, 0xFDE6, 0x6070, + 0xFDE7, 0x6D3D, 0xFDE8, 0x7FD5, 0xFDE9, 0x8208, 0xFDEA, 0x50D6, + 0xFDEB, 0x51DE, 0xFDEC, 0x559C, 0xFDED, 0x566B, 0xFDEE, 0x56CD, + 0xFDEF, 0x59EC, 0xFDF0, 0x5B09, 0xFDF1, 0x5E0C, 0xFDF2, 0x6199, + 0xFDF3, 0x6198, 0xFDF4, 0x6231, 0xFDF5, 0x665E, 0xFDF6, 0x66E6, + 0xFDF7, 0x7199, 0xFDF8, 0x71B9, 0xFDF9, 0x71BA, 0xFDFA, 0x72A7, + 0xFDFB, 0x79A7, 0xFDFC, 0x7A00, 0xFDFD, 0x7FB2, 0xFDFE, 0x8A70, + 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (chr < 0x80) { /* ASCII */ + c = chr; + } else { + if (dir) { /* OEM code to unicode */ + p = oem2uni; + hi = sizeof oem2uni / 4 - 1; + } else { /* Unicode to OEM code */ + p = uni2oem; + hi = sizeof uni2oem / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (chr == p[i * 2]) break; + if (chr > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + + +WCHAR ff_wtoupper ( + WCHAR chr /* Unicode character to be upper converted */ +) +{ + static const WCHAR lower[] = { /* Lower case characters to be converted */ + /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, + /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E, + /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217, + /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB, + /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9, + /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586, + /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9, + /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A + }; + static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D, + 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216, + 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8, + 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556, + 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A + }; + UINT i, n, hi, li; + + + if (chr < 0x80) { /* ASCII characters (acceleration) */ + if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20; + + } else { /* Extended characters */ + n = 12; li = 0; hi = sizeof lower / sizeof lower[0]; + do { + i = li + (hi - li) / 2; + if (chr == lower[i]) break; + if (chr > lower[i]) li = i; else hi = i; + } while (--n); + if (n) chr = upper[i]; + } + + return chr; +} + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc950.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc950.c new file mode 100644 index 0000000..c61f994 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/cc950.c @@ -0,0 +1,6860 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - OEM code bidirectional converter (C)ChaN, 2015 */ +/* CP950 (Traditional Chinese Big5) */ +/*------------------------------------------------------------------------*/ + +#include "ff.h" + + +#if !_USE_LFN || _CODE_PAGE != 950 +#error This file is not needed in current configuration. Remove from the project. +#endif + + +static +const WCHAR uni2oem[] = { +/* Unicode - OEM, Unicode - OEM, Unicode - OEM, Unicode - OEM */ + 0x00A7, 0xA1B1, 0x00AF, 0xA1C2, 0x00B0, 0xA258, 0x00B1, 0xA1D3, + 0x00B7, 0xA150, 0x00D7, 0xA1D1, 0x00F7, 0xA1D2, 0x02C7, 0xA3BE, + 0x02C9, 0xA3BC, 0x02CA, 0xA3BD, 0x02CB, 0xA3BF, 0x02CD, 0xA1C5, + 0x02D9, 0xA3BB, 0x0391, 0xA344, 0x0392, 0xA345, 0x0393, 0xA346, + 0x0394, 0xA347, 0x0395, 0xA348, 0x0396, 0xA349, 0x0397, 0xA34A, + 0x0398, 0xA34B, 0x0399, 0xA34C, 0x039A, 0xA34D, 0x039B, 0xA34E, + 0x039C, 0xA34F, 0x039D, 0xA350, 0x039E, 0xA351, 0x039F, 0xA352, + 0x03A0, 0xA353, 0x03A1, 0xA354, 0x03A3, 0xA355, 0x03A4, 0xA356, + 0x03A5, 0xA357, 0x03A6, 0xA358, 0x03A7, 0xA359, 0x03A8, 0xA35A, + 0x03A9, 0xA35B, 0x03B1, 0xA35C, 0x03B2, 0xA35D, 0x03B3, 0xA35E, + 0x03B4, 0xA35F, 0x03B5, 0xA360, 0x03B6, 0xA361, 0x03B7, 0xA362, + 0x03B8, 0xA363, 0x03B9, 0xA364, 0x03BA, 0xA365, 0x03BB, 0xA366, + 0x03BC, 0xA367, 0x03BD, 0xA368, 0x03BE, 0xA369, 0x03BF, 0xA36A, + 0x03C0, 0xA36B, 0x03C1, 0xA36C, 0x03C3, 0xA36D, 0x03C4, 0xA36E, + 0x03C5, 0xA36F, 0x03C6, 0xA370, 0x03C7, 0xA371, 0x03C8, 0xA372, + 0x03C9, 0xA373, 0x2013, 0xA156, 0x2014, 0xA158, 0x2018, 0xA1A5, + 0x2019, 0xA1A6, 0x201C, 0xA1A7, 0x201D, 0xA1A8, 0x2025, 0xA14C, + 0x2026, 0xA14B, 0x2027, 0xA145, 0x2032, 0xA1AC, 0x2035, 0xA1AB, + 0x203B, 0xA1B0, 0x20AC, 0xA3E1, 0x2103, 0xA24A, 0x2105, 0xA1C1, + 0x2109, 0xA24B, 0x2160, 0xA2B9, 0x2161, 0xA2BA, 0x2162, 0xA2BB, + 0x2163, 0xA2BC, 0x2164, 0xA2BD, 0x2165, 0xA2BE, 0x2166, 0xA2BF, + 0x2167, 0xA2C0, 0x2168, 0xA2C1, 0x2169, 0xA2C2, 0x2190, 0xA1F6, + 0x2191, 0xA1F4, 0x2192, 0xA1F7, 0x2193, 0xA1F5, 0x2196, 0xA1F8, + 0x2197, 0xA1F9, 0x2198, 0xA1FB, 0x2199, 0xA1FA, 0x2215, 0xA241, + 0x221A, 0xA1D4, 0x221E, 0xA1DB, 0x221F, 0xA1E8, 0x2220, 0xA1E7, + 0x2223, 0xA1FD, 0x2225, 0xA1FC, 0x2229, 0xA1E4, 0x222A, 0xA1E5, + 0x222B, 0xA1EC, 0x222E, 0xA1ED, 0x2234, 0xA1EF, 0x2235, 0xA1EE, + 0x2252, 0xA1DC, 0x2260, 0xA1DA, 0x2261, 0xA1DD, 0x2266, 0xA1D8, + 0x2267, 0xA1D9, 0x2295, 0xA1F2, 0x2299, 0xA1F3, 0x22A5, 0xA1E6, + 0x22BF, 0xA1E9, 0x2500, 0xA277, 0x2502, 0xA278, 0x250C, 0xA27A, + 0x2510, 0xA27B, 0x2514, 0xA27C, 0x2518, 0xA27D, 0x251C, 0xA275, + 0x2524, 0xA274, 0x252C, 0xA273, 0x2534, 0xA272, 0x253C, 0xA271, + 0x2550, 0xA2A4, 0x2550, 0xF9F9, 0x2551, 0xF9F8, 0x2552, 0xF9E6, + 0x2553, 0xF9EF, 0x2554, 0xF9DD, 0x2555, 0xF9E8, 0x2556, 0xF9F1, + 0x2557, 0xF9DF, 0x2558, 0xF9EC, 0x2559, 0xF9F5, 0x255A, 0xF9E3, + 0x255B, 0xF9EE, 0x255C, 0xF9F7, 0x255D, 0xF9E5, 0x255E, 0xA2A5, + 0x255E, 0xF9E9, 0x255F, 0xF9F2, 0x2560, 0xF9E0, 0x2561, 0xA2A7, + 0x2561, 0xF9EB, 0x2562, 0xF9F4, 0x2563, 0xF9E2, 0x2564, 0xF9E7, + 0x2565, 0xF9F0, 0x2566, 0xF9DE, 0x2567, 0xF9ED, 0x2568, 0xF9F6, + 0x2569, 0xF9E4, 0x256A, 0xA2A6, 0x256A, 0xF9EA, 0x256B, 0xF9F3, + 0x256C, 0xF9E1, 0x256D, 0xA27E, 0x256D, 0xF9FA, 0x256E, 0xA2A1, + 0x256E, 0xF9FB, 0x256F, 0xA2A3, 0x256F, 0xF9FD, 0x2570, 0xA2A2, + 0x2570, 0xF9FC, 0x2571, 0xA2AC, 0x2572, 0xA2AD, 0x2573, 0xA2AE, + 0x2574, 0xA15A, 0x2581, 0xA262, 0x2582, 0xA263, 0x2583, 0xA264, + 0x2584, 0xA265, 0x2585, 0xA266, 0x2586, 0xA267, 0x2587, 0xA268, + 0x2588, 0xA269, 0x2589, 0xA270, 0x258A, 0xA26F, 0x258B, 0xA26E, + 0x258C, 0xA26D, 0x258D, 0xA26C, 0x258E, 0xA26B, 0x258F, 0xA26A, + 0x2593, 0xF9FE, 0x2594, 0xA276, 0x2595, 0xA279, 0x25A0, 0xA1BD, + 0x25A1, 0xA1BC, 0x25B2, 0xA1B6, 0x25B3, 0xA1B5, 0x25BC, 0xA1BF, + 0x25BD, 0xA1BE, 0x25C6, 0xA1BB, 0x25C7, 0xA1BA, 0x25CB, 0xA1B3, + 0x25CE, 0xA1B7, 0x25CF, 0xA1B4, 0x25E2, 0xA2A8, 0x25E3, 0xA2A9, + 0x25E4, 0xA2AB, 0x25E5, 0xA2AA, 0x2605, 0xA1B9, 0x2606, 0xA1B8, + 0x2640, 0xA1F0, 0x2642, 0xA1F1, 0x3000, 0xA140, 0x3001, 0xA142, + 0x3002, 0xA143, 0x3003, 0xA1B2, 0x3008, 0xA171, 0x3009, 0xA172, + 0x300A, 0xA16D, 0x300B, 0xA16E, 0x300C, 0xA175, 0x300D, 0xA176, + 0x300E, 0xA179, 0x300F, 0xA17A, 0x3010, 0xA169, 0x3011, 0xA16A, + 0x3012, 0xA245, 0x3014, 0xA165, 0x3015, 0xA166, 0x301D, 0xA1A9, + 0x301E, 0xA1AA, 0x3021, 0xA2C3, 0x3022, 0xA2C4, 0x3023, 0xA2C5, + 0x3024, 0xA2C6, 0x3025, 0xA2C7, 0x3026, 0xA2C8, 0x3027, 0xA2C9, + 0x3028, 0xA2CA, 0x3029, 0xA2CB, 0x3105, 0xA374, 0x3106, 0xA375, + 0x3107, 0xA376, 0x3108, 0xA377, 0x3109, 0xA378, 0x310A, 0xA379, + 0x310B, 0xA37A, 0x310C, 0xA37B, 0x310D, 0xA37C, 0x310E, 0xA37D, + 0x310F, 0xA37E, 0x3110, 0xA3A1, 0x3111, 0xA3A2, 0x3112, 0xA3A3, + 0x3113, 0xA3A4, 0x3114, 0xA3A5, 0x3115, 0xA3A6, 0x3116, 0xA3A7, + 0x3117, 0xA3A8, 0x3118, 0xA3A9, 0x3119, 0xA3AA, 0x311A, 0xA3AB, + 0x311B, 0xA3AC, 0x311C, 0xA3AD, 0x311D, 0xA3AE, 0x311E, 0xA3AF, + 0x311F, 0xA3B0, 0x3120, 0xA3B1, 0x3121, 0xA3B2, 0x3122, 0xA3B3, + 0x3123, 0xA3B4, 0x3124, 0xA3B5, 0x3125, 0xA3B6, 0x3126, 0xA3B7, + 0x3127, 0xA3B8, 0x3128, 0xA3B9, 0x3129, 0xA3BA, 0x32A3, 0xA1C0, + 0x338E, 0xA255, 0x338F, 0xA256, 0x339C, 0xA250, 0x339D, 0xA251, + 0x339E, 0xA252, 0x33A1, 0xA254, 0x33C4, 0xA257, 0x33CE, 0xA253, + 0x33D1, 0xA1EB, 0x33D2, 0xA1EA, 0x33D5, 0xA24F, 0x4E00, 0xA440, + 0x4E01, 0xA442, 0x4E03, 0xA443, 0x4E07, 0xC945, 0x4E08, 0xA456, + 0x4E09, 0xA454, 0x4E0A, 0xA457, 0x4E0B, 0xA455, 0x4E0C, 0xC946, + 0x4E0D, 0xA4A3, 0x4E0E, 0xC94F, 0x4E0F, 0xC94D, 0x4E10, 0xA4A2, + 0x4E11, 0xA4A1, 0x4E14, 0xA542, 0x4E15, 0xA541, 0x4E16, 0xA540, + 0x4E18, 0xA543, 0x4E19, 0xA4FE, 0x4E1E, 0xA5E0, 0x4E1F, 0xA5E1, + 0x4E26, 0xA8C3, 0x4E2B, 0xA458, 0x4E2D, 0xA4A4, 0x4E2E, 0xC950, + 0x4E30, 0xA4A5, 0x4E31, 0xC963, 0x4E32, 0xA6EA, 0x4E33, 0xCBB1, + 0x4E38, 0xA459, 0x4E39, 0xA4A6, 0x4E3B, 0xA544, 0x4E3C, 0xC964, + 0x4E42, 0xC940, 0x4E43, 0xA444, 0x4E45, 0xA45B, 0x4E47, 0xC947, + 0x4E48, 0xA45C, 0x4E4B, 0xA4A7, 0x4E4D, 0xA545, 0x4E4E, 0xA547, + 0x4E4F, 0xA546, 0x4E52, 0xA5E2, 0x4E53, 0xA5E3, 0x4E56, 0xA8C4, + 0x4E58, 0xADBC, 0x4E59, 0xA441, 0x4E5C, 0xC941, 0x4E5D, 0xA445, + 0x4E5E, 0xA45E, 0x4E5F, 0xA45D, 0x4E69, 0xA5E4, 0x4E73, 0xA8C5, + 0x4E7E, 0xB0AE, 0x4E7F, 0xD44B, 0x4E82, 0xB6C3, 0x4E83, 0xDCB1, + 0x4E84, 0xDCB2, 0x4E86, 0xA446, 0x4E88, 0xA4A9, 0x4E8B, 0xA8C6, + 0x4E8C, 0xA447, 0x4E8D, 0xC948, 0x4E8E, 0xA45F, 0x4E91, 0xA4AA, + 0x4E92, 0xA4AC, 0x4E93, 0xC951, 0x4E94, 0xA4AD, 0x4E95, 0xA4AB, + 0x4E99, 0xA5E5, 0x4E9B, 0xA8C7, 0x4E9E, 0xA8C8, 0x4E9F, 0xAB45, + 0x4EA1, 0xA460, 0x4EA2, 0xA4AE, 0x4EA4, 0xA5E6, 0x4EA5, 0xA5E8, + 0x4EA6, 0xA5E7, 0x4EA8, 0xA6EB, 0x4EAB, 0xA8C9, 0x4EAC, 0xA8CA, + 0x4EAD, 0xAB46, 0x4EAE, 0xAB47, 0x4EB3, 0xADBD, 0x4EB6, 0xDCB3, + 0x4EB9, 0xF6D6, 0x4EBA, 0xA448, 0x4EC0, 0xA4B0, 0x4EC1, 0xA4AF, + 0x4EC2, 0xC952, 0x4EC3, 0xA4B1, 0x4EC4, 0xA4B7, 0x4EC6, 0xA4B2, + 0x4EC7, 0xA4B3, 0x4EC8, 0xC954, 0x4EC9, 0xC953, 0x4ECA, 0xA4B5, + 0x4ECB, 0xA4B6, 0x4ECD, 0xA4B4, 0x4ED4, 0xA54A, 0x4ED5, 0xA54B, + 0x4ED6, 0xA54C, 0x4ED7, 0xA54D, 0x4ED8, 0xA549, 0x4ED9, 0xA550, + 0x4EDA, 0xC96A, 0x4EDC, 0xC966, 0x4EDD, 0xC969, 0x4EDE, 0xA551, + 0x4EDF, 0xA561, 0x4EE1, 0xC968, 0x4EE3, 0xA54E, 0x4EE4, 0xA54F, + 0x4EE5, 0xA548, 0x4EE8, 0xC965, 0x4EE9, 0xC967, 0x4EF0, 0xA5F5, + 0x4EF1, 0xC9B0, 0x4EF2, 0xA5F2, 0x4EF3, 0xA5F6, 0x4EF4, 0xC9BA, + 0x4EF5, 0xC9AE, 0x4EF6, 0xA5F3, 0x4EF7, 0xC9B2, 0x4EFB, 0xA5F4, + 0x4EFD, 0xA5F7, 0x4EFF, 0xA5E9, 0x4F00, 0xC9B1, 0x4F01, 0xA5F8, + 0x4F02, 0xC9B5, 0x4F04, 0xC9B9, 0x4F05, 0xC9B6, 0x4F08, 0xC9B3, + 0x4F09, 0xA5EA, 0x4F0A, 0xA5EC, 0x4F0B, 0xA5F9, 0x4F0D, 0xA5EE, + 0x4F0E, 0xC9AB, 0x4F0F, 0xA5F1, 0x4F10, 0xA5EF, 0x4F11, 0xA5F0, + 0x4F12, 0xC9BB, 0x4F13, 0xC9B8, 0x4F14, 0xC9AF, 0x4F15, 0xA5ED, + 0x4F18, 0xC9AC, 0x4F19, 0xA5EB, 0x4F1D, 0xC9B4, 0x4F22, 0xC9B7, + 0x4F2C, 0xC9AD, 0x4F2D, 0xCA66, 0x4F2F, 0xA742, 0x4F30, 0xA6F4, + 0x4F33, 0xCA67, 0x4F34, 0xA6F1, 0x4F36, 0xA744, 0x4F38, 0xA6F9, + 0x4F3A, 0xA6F8, 0x4F3B, 0xCA5B, 0x4F3C, 0xA6FC, 0x4F3D, 0xA6F7, + 0x4F3E, 0xCA60, 0x4F3F, 0xCA68, 0x4F41, 0xCA64, 0x4F43, 0xA6FA, + 0x4F46, 0xA6FD, 0x4F47, 0xA6EE, 0x4F48, 0xA747, 0x4F49, 0xCA5D, + 0x4F4C, 0xCBBD, 0x4F4D, 0xA6EC, 0x4F4E, 0xA743, 0x4F4F, 0xA6ED, + 0x4F50, 0xA6F5, 0x4F51, 0xA6F6, 0x4F52, 0xCA62, 0x4F53, 0xCA5E, + 0x4F54, 0xA6FB, 0x4F55, 0xA6F3, 0x4F56, 0xCA5A, 0x4F57, 0xA6EF, + 0x4F58, 0xCA65, 0x4F59, 0xA745, 0x4F5A, 0xA748, 0x4F5B, 0xA6F2, + 0x4F5C, 0xA740, 0x4F5D, 0xA746, 0x4F5E, 0xA6F0, 0x4F5F, 0xCA63, + 0x4F60, 0xA741, 0x4F61, 0xCA69, 0x4F62, 0xCA5C, 0x4F63, 0xA6FE, + 0x4F64, 0xCA5F, 0x4F67, 0xCA61, 0x4F69, 0xA8D8, 0x4F6A, 0xCBBF, + 0x4F6B, 0xCBCB, 0x4F6C, 0xA8D0, 0x4F6E, 0xCBCC, 0x4F6F, 0xA8CB, + 0x4F70, 0xA8D5, 0x4F73, 0xA8CE, 0x4F74, 0xCBB9, 0x4F75, 0xA8D6, + 0x4F76, 0xCBB8, 0x4F77, 0xCBBC, 0x4F78, 0xCBC3, 0x4F79, 0xCBC1, + 0x4F7A, 0xA8DE, 0x4F7B, 0xA8D9, 0x4F7C, 0xCBB3, 0x4F7D, 0xCBB5, + 0x4F7E, 0xA8DB, 0x4F7F, 0xA8CF, 0x4F80, 0xCBB6, 0x4F81, 0xCBC2, + 0x4F82, 0xCBC9, 0x4F83, 0xA8D4, 0x4F84, 0xCBBB, 0x4F85, 0xCBB4, + 0x4F86, 0xA8D3, 0x4F87, 0xCBB7, 0x4F88, 0xA8D7, 0x4F89, 0xCBBA, + 0x4F8B, 0xA8D2, 0x4F8D, 0xA8CD, 0x4F8F, 0xA8DC, 0x4F90, 0xCBC4, + 0x4F91, 0xA8DD, 0x4F92, 0xCBC8, 0x4F94, 0xCBC6, 0x4F95, 0xCBCA, + 0x4F96, 0xA8DA, 0x4F97, 0xCBBE, 0x4F98, 0xCBB2, 0x4F9A, 0xCBC0, + 0x4F9B, 0xA8D1, 0x4F9C, 0xCBC5, 0x4F9D, 0xA8CC, 0x4F9E, 0xCBC7, + 0x4FAE, 0xAB56, 0x4FAF, 0xAB4A, 0x4FB2, 0xCDE0, 0x4FB3, 0xCDE8, + 0x4FB5, 0xAB49, 0x4FB6, 0xAB51, 0x4FB7, 0xAB5D, 0x4FB9, 0xCDEE, + 0x4FBA, 0xCDEC, 0x4FBB, 0xCDE7, 0x4FBF, 0xAB4B, 0x4FC0, 0xCDED, + 0x4FC1, 0xCDE3, 0x4FC2, 0xAB59, 0x4FC3, 0xAB50, 0x4FC4, 0xAB58, + 0x4FC5, 0xCDDE, 0x4FC7, 0xCDEA, 0x4FC9, 0xCDE1, 0x4FCA, 0xAB54, + 0x4FCB, 0xCDE2, 0x4FCD, 0xCDDD, 0x4FCE, 0xAB5B, 0x4FCF, 0xAB4E, + 0x4FD0, 0xAB57, 0x4FD1, 0xAB4D, 0x4FD3, 0xCDDF, 0x4FD4, 0xCDE4, + 0x4FD6, 0xCDEB, 0x4FD7, 0xAB55, 0x4FD8, 0xAB52, 0x4FD9, 0xCDE6, + 0x4FDA, 0xAB5A, 0x4FDB, 0xCDE9, 0x4FDC, 0xCDE5, 0x4FDD, 0xAB4F, + 0x4FDE, 0xAB5C, 0x4FDF, 0xAB53, 0x4FE0, 0xAB4C, 0x4FE1, 0xAB48, + 0x4FEC, 0xCDEF, 0x4FEE, 0xADD7, 0x4FEF, 0xADC1, 0x4FF1, 0xADD1, + 0x4FF3, 0xADD6, 0x4FF4, 0xD0D0, 0x4FF5, 0xD0CF, 0x4FF6, 0xD0D4, + 0x4FF7, 0xD0D5, 0x4FF8, 0xADC4, 0x4FFA, 0xADCD, 0x4FFE, 0xADDA, + 0x5000, 0xADCE, 0x5005, 0xD0C9, 0x5006, 0xADC7, 0x5007, 0xD0CA, + 0x5009, 0xADDC, 0x500B, 0xADD3, 0x500C, 0xADBE, 0x500D, 0xADBF, + 0x500E, 0xD0DD, 0x500F, 0xB0BF, 0x5011, 0xADCC, 0x5012, 0xADCB, + 0x5013, 0xD0CB, 0x5014, 0xADCF, 0x5015, 0xD45B, 0x5016, 0xADC6, + 0x5017, 0xD0D6, 0x5018, 0xADD5, 0x5019, 0xADD4, 0x501A, 0xADCA, + 0x501B, 0xD0CE, 0x501C, 0xD0D7, 0x501E, 0xD0C8, 0x501F, 0xADC9, + 0x5020, 0xD0D8, 0x5021, 0xADD2, 0x5022, 0xD0CC, 0x5023, 0xADC0, + 0x5025, 0xADC3, 0x5026, 0xADC2, 0x5027, 0xD0D9, 0x5028, 0xADD0, + 0x5029, 0xADC5, 0x502A, 0xADD9, 0x502B, 0xADDB, 0x502C, 0xD0D3, + 0x502D, 0xADD8, 0x502F, 0xD0DB, 0x5030, 0xD0CD, 0x5031, 0xD0DC, + 0x5033, 0xD0D1, 0x5035, 0xD0DA, 0x5037, 0xD0D2, 0x503C, 0xADC8, + 0x5040, 0xD463, 0x5041, 0xD457, 0x5043, 0xB0B3, 0x5045, 0xD45C, + 0x5046, 0xD462, 0x5047, 0xB0B2, 0x5048, 0xD455, 0x5049, 0xB0B6, + 0x504A, 0xD459, 0x504B, 0xD452, 0x504C, 0xB0B4, 0x504D, 0xD456, + 0x504E, 0xB0B9, 0x504F, 0xB0BE, 0x5051, 0xD467, 0x5053, 0xD451, + 0x5055, 0xB0BA, 0x5057, 0xD466, 0x505A, 0xB0B5, 0x505B, 0xD458, + 0x505C, 0xB0B1, 0x505D, 0xD453, 0x505E, 0xD44F, 0x505F, 0xD45D, + 0x5060, 0xD450, 0x5061, 0xD44E, 0x5062, 0xD45A, 0x5063, 0xD460, + 0x5064, 0xD461, 0x5065, 0xB0B7, 0x5068, 0xD85B, 0x5069, 0xD45E, + 0x506A, 0xD44D, 0x506B, 0xD45F, 0x506D, 0xB0C1, 0x506E, 0xD464, + 0x506F, 0xB0C0, 0x5070, 0xD44C, 0x5072, 0xD454, 0x5073, 0xD465, + 0x5074, 0xB0BC, 0x5075, 0xB0BB, 0x5076, 0xB0B8, 0x5077, 0xB0BD, + 0x507A, 0xB0AF, 0x507D, 0xB0B0, 0x5080, 0xB3C8, 0x5082, 0xD85E, + 0x5083, 0xD857, 0x5085, 0xB3C5, 0x5087, 0xD85F, 0x508B, 0xD855, + 0x508C, 0xD858, 0x508D, 0xB3C4, 0x508E, 0xD859, 0x5091, 0xB3C7, + 0x5092, 0xD85D, 0x5094, 0xD853, 0x5095, 0xD852, 0x5096, 0xB3C9, + 0x5098, 0xB3CA, 0x5099, 0xB3C6, 0x509A, 0xB3CB, 0x509B, 0xD851, + 0x509C, 0xD85C, 0x509D, 0xD85A, 0x509E, 0xD854, 0x50A2, 0xB3C3, + 0x50A3, 0xD856, 0x50AC, 0xB6CA, 0x50AD, 0xB6C4, 0x50AE, 0xDCB7, + 0x50AF, 0xB6CD, 0x50B0, 0xDCBD, 0x50B1, 0xDCC0, 0x50B2, 0xB6C6, + 0x50B3, 0xB6C7, 0x50B4, 0xDCBA, 0x50B5, 0xB6C5, 0x50B6, 0xDCC3, + 0x50B7, 0xB6CB, 0x50B8, 0xDCC4, 0x50BA, 0xDCBF, 0x50BB, 0xB6CC, + 0x50BD, 0xDCB4, 0x50BE, 0xB6C9, 0x50BF, 0xDCB5, 0x50C1, 0xDCBE, + 0x50C2, 0xDCBC, 0x50C4, 0xDCB8, 0x50C5, 0xB6C8, 0x50C6, 0xDCB6, + 0x50C7, 0xB6CE, 0x50C8, 0xDCBB, 0x50C9, 0xDCC2, 0x50CA, 0xDCB9, + 0x50CB, 0xDCC1, 0x50CE, 0xB9B6, 0x50CF, 0xB9B3, 0x50D1, 0xB9B4, + 0x50D3, 0xE0F9, 0x50D4, 0xE0F1, 0x50D5, 0xB9B2, 0x50D6, 0xB9AF, + 0x50D7, 0xE0F2, 0x50DA, 0xB9B1, 0x50DB, 0xE0F5, 0x50DD, 0xE0F7, + 0x50E0, 0xE0FE, 0x50E3, 0xE0FD, 0x50E4, 0xE0F8, 0x50E5, 0xB9AE, + 0x50E6, 0xE0F0, 0x50E7, 0xB9AC, 0x50E8, 0xE0F3, 0x50E9, 0xB9B7, + 0x50EA, 0xE0F6, 0x50EC, 0xE0FA, 0x50ED, 0xB9B0, 0x50EE, 0xB9AD, + 0x50EF, 0xE0FC, 0x50F0, 0xE0FB, 0x50F1, 0xB9B5, 0x50F3, 0xE0F4, + 0x50F5, 0xBBF8, 0x50F6, 0xE4EC, 0x50F8, 0xE4E9, 0x50F9, 0xBBF9, + 0x50FB, 0xBBF7, 0x50FD, 0xE4F0, 0x50FE, 0xE4ED, 0x50FF, 0xE4E6, + 0x5100, 0xBBF6, 0x5102, 0xBBFA, 0x5103, 0xE4E7, 0x5104, 0xBBF5, + 0x5105, 0xBBFD, 0x5106, 0xE4EA, 0x5107, 0xE4EB, 0x5108, 0xBBFB, + 0x5109, 0xBBFC, 0x510A, 0xE4F1, 0x510B, 0xE4EE, 0x510C, 0xE4EF, + 0x5110, 0xBEAA, 0x5111, 0xE8F8, 0x5112, 0xBEA7, 0x5113, 0xE8F5, + 0x5114, 0xBEA9, 0x5115, 0xBEAB, 0x5117, 0xE8F6, 0x5118, 0xBEA8, + 0x511A, 0xE8F7, 0x511C, 0xE8F4, 0x511F, 0xC076, 0x5120, 0xECBD, + 0x5121, 0xC077, 0x5122, 0xECBB, 0x5124, 0xECBC, 0x5125, 0xECBA, + 0x5126, 0xECB9, 0x5129, 0xECBE, 0x512A, 0xC075, 0x512D, 0xEFB8, + 0x512E, 0xEFB9, 0x5130, 0xE4E8, 0x5131, 0xEFB7, 0x5132, 0xC078, + 0x5133, 0xC35F, 0x5134, 0xF1EB, 0x5135, 0xF1EC, 0x5137, 0xC4D7, + 0x5138, 0xC4D8, 0x5139, 0xF5C1, 0x513A, 0xF5C0, 0x513B, 0xC56C, + 0x513C, 0xC56B, 0x513D, 0xF7D0, 0x513F, 0xA449, 0x5140, 0xA461, + 0x5141, 0xA4B9, 0x5143, 0xA4B8, 0x5144, 0xA553, 0x5145, 0xA552, + 0x5146, 0xA5FC, 0x5147, 0xA5FB, 0x5148, 0xA5FD, 0x5149, 0xA5FA, + 0x514B, 0xA74A, 0x514C, 0xA749, 0x514D, 0xA74B, 0x5152, 0xA8E0, + 0x5154, 0xA8DF, 0x5155, 0xA8E1, 0x5157, 0xAB5E, 0x5159, 0xA259, + 0x515A, 0xD0DE, 0x515B, 0xA25A, 0x515C, 0xB0C2, 0x515D, 0xA25C, + 0x515E, 0xA25B, 0x515F, 0xD860, 0x5161, 0xA25D, 0x5162, 0xB9B8, + 0x5163, 0xA25E, 0x5165, 0xA44A, 0x5167, 0xA4BA, 0x5168, 0xA5FE, + 0x5169, 0xA8E2, 0x516B, 0xA44B, 0x516C, 0xA4BD, 0x516D, 0xA4BB, + 0x516E, 0xA4BC, 0x5171, 0xA640, 0x5175, 0xA74C, 0x5176, 0xA8E4, + 0x5177, 0xA8E3, 0x5178, 0xA8E5, 0x517C, 0xADDD, 0x5180, 0xBEAC, + 0x5187, 0xC94E, 0x5189, 0xA554, 0x518A, 0xA555, 0x518D, 0xA641, + 0x518F, 0xCA6A, 0x5191, 0xAB60, 0x5192, 0xAB5F, 0x5193, 0xD0E0, + 0x5194, 0xD0DF, 0x5195, 0xB0C3, 0x5197, 0xA4BE, 0x5198, 0xC955, + 0x519E, 0xCBCD, 0x51A0, 0xAB61, 0x51A2, 0xADE0, 0x51A4, 0xADDE, + 0x51A5, 0xADDF, 0x51AA, 0xBEAD, 0x51AC, 0xA556, 0x51B0, 0xA642, + 0x51B1, 0xC9BC, 0x51B6, 0xA74D, 0x51B7, 0xA74E, 0x51B9, 0xCA6B, + 0x51BC, 0xCBCE, 0x51BD, 0xA8E6, 0x51BE, 0xCBCF, 0x51C4, 0xD0E2, + 0x51C5, 0xD0E3, 0x51C6, 0xADE3, 0x51C8, 0xD0E4, 0x51CA, 0xD0E1, + 0x51CB, 0xADE4, 0x51CC, 0xADE2, 0x51CD, 0xADE1, 0x51CE, 0xD0E5, + 0x51D0, 0xD468, 0x51D4, 0xD861, 0x51D7, 0xDCC5, 0x51D8, 0xE140, + 0x51DC, 0xBBFE, 0x51DD, 0xBEAE, 0x51DE, 0xE8F9, 0x51E0, 0xA44C, + 0x51E1, 0xA45A, 0x51F0, 0xB0C4, 0x51F1, 0xB3CD, 0x51F3, 0xB9B9, + 0x51F5, 0xC942, 0x51F6, 0xA4BF, 0x51F8, 0xA559, 0x51F9, 0xA557, + 0x51FA, 0xA558, 0x51FD, 0xA8E7, 0x5200, 0xA44D, 0x5201, 0xA44E, + 0x5203, 0xA462, 0x5206, 0xA4C0, 0x5207, 0xA4C1, 0x5208, 0xA4C2, + 0x5209, 0xC9BE, 0x520A, 0xA55A, 0x520C, 0xC96B, 0x520E, 0xA646, + 0x5210, 0xC9BF, 0x5211, 0xA644, 0x5212, 0xA645, 0x5213, 0xC9BD, + 0x5216, 0xA647, 0x5217, 0xA643, 0x521C, 0xCA6C, 0x521D, 0xAAEC, + 0x521E, 0xCA6D, 0x5221, 0xCA6E, 0x5224, 0xA750, 0x5225, 0xA74F, + 0x5228, 0xA753, 0x5229, 0xA751, 0x522A, 0xA752, 0x522E, 0xA8ED, + 0x5230, 0xA8EC, 0x5231, 0xCBD4, 0x5232, 0xCBD1, 0x5233, 0xCBD2, + 0x5235, 0xCBD0, 0x5236, 0xA8EE, 0x5237, 0xA8EA, 0x5238, 0xA8E9, + 0x523A, 0xA8EB, 0x523B, 0xA8E8, 0x5241, 0xA8EF, 0x5243, 0xAB63, + 0x5244, 0xCDF0, 0x5246, 0xCBD3, 0x5247, 0xAB68, 0x5249, 0xCDF1, + 0x524A, 0xAB64, 0x524B, 0xAB67, 0x524C, 0xAB66, 0x524D, 0xAB65, + 0x524E, 0xAB62, 0x5252, 0xD0E8, 0x5254, 0xADE7, 0x5255, 0xD0EB, + 0x5256, 0xADE5, 0x525A, 0xD0E7, 0x525B, 0xADE8, 0x525C, 0xADE6, + 0x525D, 0xADE9, 0x525E, 0xD0E9, 0x525F, 0xD0EA, 0x5261, 0xD0E6, + 0x5262, 0xD0EC, 0x5269, 0xB3D1, 0x526A, 0xB0C5, 0x526B, 0xD469, + 0x526C, 0xD46B, 0x526D, 0xD46A, 0x526E, 0xD46C, 0x526F, 0xB0C6, + 0x5272, 0xB3CE, 0x5274, 0xB3CF, 0x5275, 0xB3D0, 0x5277, 0xB6D0, + 0x5278, 0xDCC7, 0x527A, 0xDCC6, 0x527B, 0xDCC8, 0x527C, 0xDCC9, + 0x527D, 0xB6D1, 0x527F, 0xB6CF, 0x5280, 0xE141, 0x5281, 0xE142, + 0x5282, 0xB9BB, 0x5283, 0xB9BA, 0x5284, 0xE35A, 0x5287, 0xBC40, + 0x5288, 0xBC41, 0x5289, 0xBC42, 0x528A, 0xBC44, 0x528B, 0xE4F2, + 0x528C, 0xE4F3, 0x528D, 0xBC43, 0x5291, 0xBEAF, 0x5293, 0xBEB0, + 0x5296, 0xF1ED, 0x5297, 0xF5C3, 0x5298, 0xF5C2, 0x5299, 0xF7D1, + 0x529B, 0xA44F, 0x529F, 0xA55C, 0x52A0, 0xA55B, 0x52A3, 0xA648, + 0x52A6, 0xC9C0, 0x52A9, 0xA755, 0x52AA, 0xA756, 0x52AB, 0xA754, + 0x52AC, 0xA757, 0x52AD, 0xCA6F, 0x52AE, 0xCA70, 0x52BB, 0xA8F1, + 0x52BC, 0xCBD5, 0x52BE, 0xA8F0, 0x52C0, 0xCDF2, 0x52C1, 0xAB6C, + 0x52C2, 0xCDF3, 0x52C3, 0xAB6B, 0x52C7, 0xAB69, 0x52C9, 0xAB6A, + 0x52CD, 0xD0ED, 0x52D2, 0xB0C7, 0x52D3, 0xD46E, 0x52D5, 0xB0CA, + 0x52D6, 0xD46D, 0x52D7, 0xB1E5, 0x52D8, 0xB0C9, 0x52D9, 0xB0C8, + 0x52DB, 0xB3D4, 0x52DD, 0xB3D3, 0x52DE, 0xB3D2, 0x52DF, 0xB6D2, + 0x52E2, 0xB6D5, 0x52E3, 0xB6D6, 0x52E4, 0xB6D4, 0x52E6, 0xB6D3, + 0x52E9, 0xE143, 0x52EB, 0xE144, 0x52EF, 0xE4F5, 0x52F0, 0xBC45, + 0x52F1, 0xE4F4, 0x52F3, 0xBEB1, 0x52F4, 0xECBF, 0x52F5, 0xC079, + 0x52F7, 0xF1EE, 0x52F8, 0xC455, 0x52FA, 0xA463, 0x52FB, 0xA4C3, + 0x52FC, 0xC956, 0x52FE, 0xA4C4, 0x52FF, 0xA4C5, 0x5305, 0xA55D, + 0x5306, 0xA55E, 0x5308, 0xA649, 0x5309, 0xCA71, 0x530A, 0xCBD6, + 0x530B, 0xCBD7, 0x530D, 0xAB6D, 0x530E, 0xD0EE, 0x530F, 0xB0CC, + 0x5310, 0xB0CB, 0x5311, 0xD863, 0x5312, 0xD862, 0x5315, 0xA450, + 0x5316, 0xA4C6, 0x5317, 0xA55F, 0x5319, 0xB0CD, 0x531A, 0xC943, + 0x531C, 0xC96C, 0x531D, 0xA560, 0x531F, 0xC9C2, 0x5320, 0xA64B, + 0x5321, 0xA64A, 0x5322, 0xC9C1, 0x5323, 0xA758, 0x532A, 0xADEA, + 0x532D, 0xD46F, 0x532F, 0xB6D7, 0x5330, 0xE145, 0x5331, 0xB9BC, + 0x5334, 0xE8FA, 0x5337, 0xF3FD, 0x5339, 0xA4C7, 0x533C, 0xCBD8, + 0x533D, 0xCDF4, 0x533E, 0xB0D0, 0x533F, 0xB0CE, 0x5340, 0xB0CF, + 0x5341, 0xA2CC, 0x5341, 0xA451, 0x5343, 0xA464, 0x5344, 0xA2CD, + 0x5345, 0xA2CE, 0x5345, 0xA4CA, 0x5347, 0xA4C9, 0x5348, 0xA4C8, + 0x5349, 0xA563, 0x534A, 0xA562, 0x534C, 0xC96D, 0x534D, 0xC9C3, + 0x5351, 0xA8F5, 0x5352, 0xA8F2, 0x5353, 0xA8F4, 0x5354, 0xA8F3, + 0x5357, 0xAB6E, 0x535A, 0xB3D5, 0x535C, 0xA452, 0x535E, 0xA4CB, + 0x5360, 0xA565, 0x5361, 0xA564, 0x5363, 0xCA72, 0x5366, 0xA8F6, + 0x536C, 0xC957, 0x536E, 0xA567, 0x536F, 0xA566, 0x5370, 0xA64C, + 0x5371, 0xA64D, 0x5372, 0xCA73, 0x5373, 0xA759, 0x5375, 0xA75A, + 0x5377, 0xA8F7, 0x5378, 0xA8F8, 0x5379, 0xA8F9, 0x537B, 0xAB6F, + 0x537C, 0xCDF5, 0x537F, 0xADEB, 0x5382, 0xC944, 0x5384, 0xA4CC, + 0x538A, 0xC9C4, 0x538E, 0xCA74, 0x538F, 0xCA75, 0x5392, 0xCBD9, + 0x5394, 0xCBDA, 0x5396, 0xCDF7, 0x5397, 0xCDF6, 0x5398, 0xCDF9, + 0x5399, 0xCDF8, 0x539A, 0xAB70, 0x539C, 0xD470, 0x539D, 0xADED, + 0x539E, 0xD0EF, 0x539F, 0xADEC, 0x53A4, 0xD864, 0x53A5, 0xB3D6, + 0x53A7, 0xD865, 0x53AC, 0xE146, 0x53AD, 0xB9BD, 0x53B2, 0xBC46, + 0x53B4, 0xF1EF, 0x53B9, 0xC958, 0x53BB, 0xA568, 0x53C3, 0xB0D1, + 0x53C8, 0xA453, 0x53C9, 0xA465, 0x53CA, 0xA4CE, 0x53CB, 0xA4CD, + 0x53CD, 0xA4CF, 0x53D4, 0xA8FB, 0x53D6, 0xA8FA, 0x53D7, 0xA8FC, + 0x53DB, 0xAB71, 0x53DF, 0xADEE, 0x53E1, 0xE8FB, 0x53E2, 0xC24F, + 0x53E3, 0xA466, 0x53E4, 0xA56A, 0x53E5, 0xA579, 0x53E6, 0xA574, + 0x53E8, 0xA56F, 0x53E9, 0xA56E, 0x53EA, 0xA575, 0x53EB, 0xA573, + 0x53EC, 0xA56C, 0x53ED, 0xA57A, 0x53EE, 0xA56D, 0x53EF, 0xA569, + 0x53F0, 0xA578, 0x53F1, 0xA577, 0x53F2, 0xA576, 0x53F3, 0xA56B, + 0x53F5, 0xA572, 0x53F8, 0xA571, 0x53FB, 0xA57B, 0x53FC, 0xA570, + 0x5401, 0xA653, 0x5403, 0xA659, 0x5404, 0xA655, 0x5406, 0xA65B, + 0x5407, 0xC9C5, 0x5408, 0xA658, 0x5409, 0xA64E, 0x540A, 0xA651, + 0x540B, 0xA654, 0x540C, 0xA650, 0x540D, 0xA657, 0x540E, 0xA65A, + 0x540F, 0xA64F, 0x5410, 0xA652, 0x5411, 0xA656, 0x5412, 0xA65C, + 0x5418, 0xCA7E, 0x5419, 0xCA7B, 0x541B, 0xA767, 0x541C, 0xCA7C, + 0x541D, 0xA75B, 0x541E, 0xA75D, 0x541F, 0xA775, 0x5420, 0xA770, + 0x5424, 0xCAA5, 0x5425, 0xCA7D, 0x5426, 0xA75F, 0x5427, 0xA761, + 0x5428, 0xCAA4, 0x5429, 0xA768, 0x542A, 0xCA78, 0x542B, 0xA774, + 0x542C, 0xA776, 0x542D, 0xA75C, 0x542E, 0xA76D, 0x5430, 0xCA76, + 0x5431, 0xA773, 0x5433, 0xA764, 0x5435, 0xA76E, 0x5436, 0xA76F, + 0x5437, 0xCA77, 0x5438, 0xA76C, 0x5439, 0xA76A, 0x543B, 0xA76B, + 0x543C, 0xA771, 0x543D, 0xCAA1, 0x543E, 0xA75E, 0x5440, 0xA772, + 0x5441, 0xCAA3, 0x5442, 0xA766, 0x5443, 0xA763, 0x5445, 0xCA7A, + 0x5446, 0xA762, 0x5447, 0xCAA6, 0x5448, 0xA765, 0x544A, 0xA769, + 0x544E, 0xA760, 0x544F, 0xCAA2, 0x5454, 0xCA79, 0x5460, 0xCBEB, + 0x5461, 0xCBEA, 0x5462, 0xA94F, 0x5463, 0xCBED, 0x5464, 0xCBEF, + 0x5465, 0xCBE4, 0x5466, 0xCBE7, 0x5467, 0xCBEE, 0x5468, 0xA950, + 0x546B, 0xCBE1, 0x546C, 0xCBE5, 0x546F, 0xCBE9, 0x5470, 0xCE49, + 0x5471, 0xA94B, 0x5472, 0xCE4D, 0x5473, 0xA8FD, 0x5474, 0xCBE6, + 0x5475, 0xA8FE, 0x5476, 0xA94C, 0x5477, 0xA945, 0x5478, 0xA941, + 0x547A, 0xCBE2, 0x547B, 0xA944, 0x547C, 0xA949, 0x547D, 0xA952, + 0x547E, 0xCBE3, 0x547F, 0xCBDC, 0x5480, 0xA943, 0x5481, 0xCBDD, + 0x5482, 0xCBDF, 0x5484, 0xA946, 0x5486, 0xA948, 0x5487, 0xCBDB, + 0x5488, 0xCBE0, 0x548B, 0xA951, 0x548C, 0xA94D, 0x548D, 0xCBE8, + 0x548E, 0xA953, 0x5490, 0xA94A, 0x5491, 0xCBDE, 0x5492, 0xA947, + 0x5495, 0xA942, 0x5496, 0xA940, 0x5498, 0xCBEC, 0x549A, 0xA94E, + 0x54A0, 0xCE48, 0x54A1, 0xCDFB, 0x54A2, 0xCE4B, 0x54A5, 0xCDFD, + 0x54A6, 0xAB78, 0x54A7, 0xABA8, 0x54A8, 0xAB74, 0x54A9, 0xABA7, + 0x54AA, 0xAB7D, 0x54AB, 0xABA4, 0x54AC, 0xAB72, 0x54AD, 0xCDFC, + 0x54AE, 0xCE43, 0x54AF, 0xABA3, 0x54B0, 0xCE4F, 0x54B1, 0xABA5, + 0x54B3, 0xAB79, 0x54B6, 0xCE45, 0x54B7, 0xCE42, 0x54B8, 0xAB77, + 0x54BA, 0xCDFA, 0x54BB, 0xABA6, 0x54BC, 0xCE4A, 0x54BD, 0xAB7C, + 0x54BE, 0xCE4C, 0x54BF, 0xABA9, 0x54C0, 0xAB73, 0x54C1, 0xAB7E, + 0x54C2, 0xAB7B, 0x54C3, 0xCE40, 0x54C4, 0xABA1, 0x54C5, 0xCE46, + 0x54C6, 0xCE47, 0x54C7, 0xAB7A, 0x54C8, 0xABA2, 0x54C9, 0xAB76, + 0x54CE, 0xAB75, 0x54CF, 0xCDFE, 0x54D6, 0xCE44, 0x54DE, 0xCE4E, + 0x54E0, 0xD144, 0x54E1, 0xADFB, 0x54E2, 0xD0F1, 0x54E4, 0xD0F6, + 0x54E5, 0xADF4, 0x54E6, 0xAE40, 0x54E7, 0xD0F4, 0x54E8, 0xADEF, + 0x54E9, 0xADF9, 0x54EA, 0xADFE, 0x54EB, 0xD0FB, 0x54ED, 0xADFA, + 0x54EE, 0xADFD, 0x54F1, 0xD0FE, 0x54F2, 0xADF5, 0x54F3, 0xD0F5, + 0x54F7, 0xD142, 0x54F8, 0xD143, 0x54FA, 0xADF7, 0x54FB, 0xD141, + 0x54FC, 0xADF3, 0x54FD, 0xAE43, 0x54FF, 0xD0F8, 0x5501, 0xADF1, + 0x5503, 0xD146, 0x5504, 0xD0F9, 0x5505, 0xD0FD, 0x5506, 0xADF6, + 0x5507, 0xAE42, 0x5508, 0xD0FA, 0x5509, 0xADFC, 0x550A, 0xD140, + 0x550B, 0xD147, 0x550C, 0xD4A1, 0x550E, 0xD145, 0x550F, 0xAE44, + 0x5510, 0xADF0, 0x5511, 0xD0FC, 0x5512, 0xD0F3, 0x5514, 0xADF8, + 0x5517, 0xD0F2, 0x551A, 0xD0F7, 0x5526, 0xD0F0, 0x5527, 0xAE41, + 0x552A, 0xD477, 0x552C, 0xB0E4, 0x552D, 0xD4A7, 0x552E, 0xB0E2, + 0x552F, 0xB0DF, 0x5530, 0xD47C, 0x5531, 0xB0DB, 0x5532, 0xD4A2, + 0x5533, 0xB0E6, 0x5534, 0xD476, 0x5535, 0xD47B, 0x5536, 0xD47A, + 0x5537, 0xADF2, 0x5538, 0xB0E1, 0x5539, 0xD4A5, 0x553B, 0xD4A8, + 0x553C, 0xD473, 0x553E, 0xB3E8, 0x5540, 0xD4A9, 0x5541, 0xB0E7, + 0x5543, 0xB0D9, 0x5544, 0xB0D6, 0x5545, 0xD47E, 0x5546, 0xB0D3, + 0x5548, 0xD4A6, 0x554A, 0xB0DA, 0x554B, 0xD4AA, 0x554D, 0xD474, + 0x554E, 0xD4A4, 0x554F, 0xB0DD, 0x5550, 0xD475, 0x5551, 0xD478, + 0x5552, 0xD47D, 0x5555, 0xB0DE, 0x5556, 0xB0DC, 0x5557, 0xB0E8, + 0x555C, 0xB0E3, 0x555E, 0xB0D7, 0x555F, 0xB1D2, 0x5561, 0xB0D8, + 0x5562, 0xD479, 0x5563, 0xB0E5, 0x5564, 0xB0E0, 0x5565, 0xD4A3, + 0x5566, 0xB0D5, 0x556A, 0xB0D4, 0x5575, 0xD471, 0x5576, 0xD472, + 0x5577, 0xD86A, 0x557B, 0xB3D7, 0x557C, 0xB3DA, 0x557D, 0xD875, + 0x557E, 0xB3EE, 0x557F, 0xD878, 0x5580, 0xB3D8, 0x5581, 0xD871, + 0x5582, 0xB3DE, 0x5583, 0xB3E4, 0x5584, 0xB5BD, 0x5587, 0xB3E2, + 0x5588, 0xD86E, 0x5589, 0xB3EF, 0x558A, 0xB3DB, 0x558B, 0xB3E3, + 0x558C, 0xD876, 0x558D, 0xDCD7, 0x558E, 0xD87B, 0x558F, 0xD86F, + 0x5591, 0xD866, 0x5592, 0xD873, 0x5593, 0xD86D, 0x5594, 0xB3E1, + 0x5595, 0xD879, 0x5598, 0xB3DD, 0x5599, 0xB3F1, 0x559A, 0xB3EA, + 0x559C, 0xB3DF, 0x559D, 0xB3DC, 0x559F, 0xB3E7, 0x55A1, 0xD87A, + 0x55A2, 0xD86C, 0x55A3, 0xD872, 0x55A4, 0xD874, 0x55A5, 0xD868, + 0x55A6, 0xD877, 0x55A7, 0xB3D9, 0x55A8, 0xD867, 0x55AA, 0xB3E0, + 0x55AB, 0xB3F0, 0x55AC, 0xB3EC, 0x55AD, 0xD869, 0x55AE, 0xB3E6, + 0x55B1, 0xB3ED, 0x55B2, 0xB3E9, 0x55B3, 0xB3E5, 0x55B5, 0xD870, + 0x55BB, 0xB3EB, 0x55BF, 0xDCD5, 0x55C0, 0xDCD1, 0x55C2, 0xDCE0, + 0x55C3, 0xDCCA, 0x55C4, 0xDCD3, 0x55C5, 0xB6E5, 0x55C6, 0xB6E6, + 0x55C7, 0xB6DE, 0x55C8, 0xDCDC, 0x55C9, 0xB6E8, 0x55CA, 0xDCCF, + 0x55CB, 0xDCCE, 0x55CC, 0xDCCC, 0x55CD, 0xDCDE, 0x55CE, 0xB6DC, + 0x55CF, 0xDCD8, 0x55D0, 0xDCCD, 0x55D1, 0xB6DF, 0x55D2, 0xDCD6, + 0x55D3, 0xB6DA, 0x55D4, 0xDCD2, 0x55D5, 0xDCD9, 0x55D6, 0xDCDB, + 0x55D9, 0xDCDF, 0x55DA, 0xB6E3, 0x55DB, 0xDCCB, 0x55DC, 0xB6DD, + 0x55DD, 0xDCD0, 0x55DF, 0xB6D8, 0x55E1, 0xB6E4, 0x55E2, 0xDCDA, + 0x55E3, 0xB6E0, 0x55E4, 0xB6E1, 0x55E5, 0xB6E7, 0x55E6, 0xB6DB, + 0x55E7, 0xA25F, 0x55E8, 0xB6D9, 0x55E9, 0xDCD4, 0x55EF, 0xB6E2, + 0x55F2, 0xDCDD, 0x55F6, 0xB9CD, 0x55F7, 0xB9C8, 0x55F9, 0xE155, + 0x55FA, 0xE151, 0x55FC, 0xE14B, 0x55FD, 0xB9C2, 0x55FE, 0xB9BE, + 0x55FF, 0xE154, 0x5600, 0xB9BF, 0x5601, 0xE14E, 0x5602, 0xE150, + 0x5604, 0xE153, 0x5606, 0xB9C4, 0x5608, 0xB9CB, 0x5609, 0xB9C5, + 0x560C, 0xE149, 0x560D, 0xB9C6, 0x560E, 0xB9C7, 0x560F, 0xE14C, + 0x5610, 0xB9CC, 0x5612, 0xE14A, 0x5613, 0xE14F, 0x5614, 0xB9C3, + 0x5615, 0xE148, 0x5616, 0xB9C9, 0x5617, 0xB9C1, 0x561B, 0xB9C0, + 0x561C, 0xE14D, 0x561D, 0xE152, 0x561F, 0xB9CA, 0x5627, 0xE147, + 0x5629, 0xBC4D, 0x562A, 0xE547, 0x562C, 0xE544, 0x562E, 0xBC47, + 0x562F, 0xBC53, 0x5630, 0xBC54, 0x5632, 0xBC4A, 0x5633, 0xE542, + 0x5634, 0xBC4C, 0x5635, 0xE4F9, 0x5636, 0xBC52, 0x5638, 0xE546, + 0x5639, 0xBC49, 0x563A, 0xE548, 0x563B, 0xBC48, 0x563D, 0xE543, + 0x563E, 0xE545, 0x563F, 0xBC4B, 0x5640, 0xE541, 0x5641, 0xE4FA, + 0x5642, 0xE4F7, 0x5645, 0xD86B, 0x5646, 0xE4FD, 0x5648, 0xE4F6, + 0x5649, 0xE4FC, 0x564A, 0xE4FB, 0x564C, 0xE4F8, 0x564E, 0xBC4F, + 0x5653, 0xBC4E, 0x5657, 0xBC50, 0x5658, 0xE4FE, 0x5659, 0xBEB2, + 0x565A, 0xE540, 0x565E, 0xE945, 0x5660, 0xE8FD, 0x5662, 0xBEBE, + 0x5663, 0xE942, 0x5664, 0xBEB6, 0x5665, 0xBEBA, 0x5666, 0xE941, + 0x5668, 0xBEB9, 0x5669, 0xBEB5, 0x566A, 0xBEB8, 0x566B, 0xBEB3, + 0x566C, 0xBEBD, 0x566D, 0xE943, 0x566E, 0xE8FE, 0x566F, 0xBEBC, + 0x5670, 0xE8FC, 0x5671, 0xBEBB, 0x5672, 0xE944, 0x5673, 0xE940, + 0x5674, 0xBC51, 0x5676, 0xBEBF, 0x5677, 0xE946, 0x5678, 0xBEB7, + 0x5679, 0xBEB4, 0x567E, 0xECC6, 0x567F, 0xECC8, 0x5680, 0xC07B, + 0x5681, 0xECC9, 0x5682, 0xECC7, 0x5683, 0xECC5, 0x5684, 0xECC4, + 0x5685, 0xC07D, 0x5686, 0xECC3, 0x5687, 0xC07E, 0x568C, 0xECC1, + 0x568D, 0xECC2, 0x568E, 0xC07A, 0x568F, 0xC0A1, 0x5690, 0xC07C, + 0x5693, 0xECC0, 0x5695, 0xC250, 0x5697, 0xEFBC, 0x5698, 0xEFBA, + 0x5699, 0xEFBF, 0x569A, 0xEFBD, 0x569C, 0xEFBB, 0x569D, 0xEFBE, + 0x56A5, 0xC360, 0x56A6, 0xF1F2, 0x56A7, 0xF1F3, 0x56A8, 0xC456, + 0x56AA, 0xF1F4, 0x56AB, 0xF1F0, 0x56AC, 0xF1F5, 0x56AD, 0xF1F1, + 0x56AE, 0xC251, 0x56B2, 0xF3FE, 0x56B3, 0xF441, 0x56B4, 0xC459, + 0x56B5, 0xF440, 0x56B6, 0xC458, 0x56B7, 0xC457, 0x56BC, 0xC45A, + 0x56BD, 0xF5C5, 0x56BE, 0xF5C6, 0x56C0, 0xC4DA, 0x56C1, 0xC4D9, + 0x56C2, 0xC4DB, 0x56C3, 0xF5C4, 0x56C5, 0xF6D8, 0x56C6, 0xF6D7, + 0x56C8, 0xC56D, 0x56C9, 0xC56F, 0x56CA, 0xC56E, 0x56CB, 0xF6D9, + 0x56CC, 0xC5C8, 0x56CD, 0xF8A6, 0x56D1, 0xC5F1, 0x56D3, 0xF8A5, + 0x56D4, 0xF8EE, 0x56D7, 0xC949, 0x56DA, 0xA57D, 0x56DB, 0xA57C, + 0x56DD, 0xA65F, 0x56DE, 0xA65E, 0x56DF, 0xC9C7, 0x56E0, 0xA65D, + 0x56E1, 0xC9C6, 0x56E4, 0xA779, 0x56E5, 0xCAA9, 0x56E7, 0xCAA8, + 0x56EA, 0xA777, 0x56EB, 0xA77A, 0x56EE, 0xCAA7, 0x56F0, 0xA778, + 0x56F7, 0xCBF0, 0x56F9, 0xCBF1, 0x56FA, 0xA954, 0x56FF, 0xABAA, + 0x5701, 0xD148, 0x5702, 0xD149, 0x5703, 0xAE45, 0x5704, 0xAE46, + 0x5707, 0xD4AC, 0x5708, 0xB0E9, 0x5709, 0xB0EB, 0x570A, 0xD4AB, + 0x570B, 0xB0EA, 0x570C, 0xD87C, 0x570D, 0xB3F2, 0x5712, 0xB6E9, + 0x5713, 0xB6EA, 0x5714, 0xDCE1, 0x5716, 0xB9CF, 0x5718, 0xB9CE, + 0x571A, 0xE549, 0x571B, 0xE948, 0x571C, 0xE947, 0x571E, 0xF96B, + 0x571F, 0xA467, 0x5720, 0xC959, 0x5722, 0xC96E, 0x5723, 0xC96F, + 0x5728, 0xA662, 0x5729, 0xA666, 0x572A, 0xC9C9, 0x572C, 0xA664, + 0x572D, 0xA663, 0x572E, 0xC9C8, 0x572F, 0xA665, 0x5730, 0xA661, + 0x5733, 0xA660, 0x5734, 0xC9CA, 0x573B, 0xA7A6, 0x573E, 0xA7A3, + 0x5740, 0xA77D, 0x5741, 0xCAAA, 0x5745, 0xCAAB, 0x5747, 0xA7A1, + 0x5749, 0xCAAD, 0x574A, 0xA77B, 0x574B, 0xCAAE, 0x574C, 0xCAAC, + 0x574D, 0xA77E, 0x574E, 0xA7A2, 0x574F, 0xA7A5, 0x5750, 0xA7A4, + 0x5751, 0xA77C, 0x5752, 0xCAAF, 0x5761, 0xA959, 0x5762, 0xCBFE, + 0x5764, 0xA95B, 0x5766, 0xA95A, 0x5768, 0xCC40, 0x5769, 0xA958, + 0x576A, 0xA957, 0x576B, 0xCBF5, 0x576D, 0xCBF4, 0x576F, 0xCBF2, + 0x5770, 0xCBF7, 0x5771, 0xCBF6, 0x5772, 0xCBF3, 0x5773, 0xCBFC, + 0x5774, 0xCBFD, 0x5775, 0xCBFA, 0x5776, 0xCBF8, 0x5777, 0xA956, + 0x577B, 0xCBFB, 0x577C, 0xA95C, 0x577D, 0xCC41, 0x5780, 0xCBF9, + 0x5782, 0xABAB, 0x5783, 0xA955, 0x578B, 0xABAC, 0x578C, 0xCE54, + 0x578F, 0xCE5A, 0x5793, 0xABB2, 0x5794, 0xCE58, 0x5795, 0xCE5E, + 0x5797, 0xCE55, 0x5798, 0xCE59, 0x5799, 0xCE5B, 0x579A, 0xCE5D, + 0x579B, 0xCE57, 0x579D, 0xCE56, 0x579E, 0xCE51, 0x579F, 0xCE52, + 0x57A0, 0xABAD, 0x57A2, 0xABAF, 0x57A3, 0xABAE, 0x57A4, 0xCE53, + 0x57A5, 0xCE5C, 0x57AE, 0xABB1, 0x57B5, 0xCE50, 0x57B6, 0xD153, + 0x57B8, 0xD152, 0x57B9, 0xD157, 0x57BA, 0xD14E, 0x57BC, 0xD151, + 0x57BD, 0xD150, 0x57BF, 0xD154, 0x57C1, 0xD158, 0x57C2, 0xAE47, + 0x57C3, 0xAE4A, 0x57C6, 0xD14F, 0x57C7, 0xD155, 0x57CB, 0xAE49, + 0x57CC, 0xD14A, 0x57CE, 0xABB0, 0x57CF, 0xD4BA, 0x57D0, 0xD156, + 0x57D2, 0xD14D, 0x57D4, 0xAE48, 0x57D5, 0xD14C, 0x57DC, 0xD4B1, + 0x57DF, 0xB0EC, 0x57E0, 0xB0F0, 0x57E1, 0xD4C1, 0x57E2, 0xD4AF, + 0x57E3, 0xD4BD, 0x57E4, 0xB0F1, 0x57E5, 0xD4BF, 0x57E7, 0xD4C5, + 0x57E9, 0xD4C9, 0x57EC, 0xD4C0, 0x57ED, 0xD4B4, 0x57EE, 0xD4BC, + 0x57F0, 0xD4CA, 0x57F1, 0xD4C8, 0x57F2, 0xD4BE, 0x57F3, 0xD4B9, + 0x57F4, 0xD4B2, 0x57F5, 0xD8A6, 0x57F6, 0xD4B0, 0x57F7, 0xB0F5, + 0x57F8, 0xD4B7, 0x57F9, 0xB0F6, 0x57FA, 0xB0F2, 0x57FB, 0xD4AD, + 0x57FC, 0xD4C3, 0x57FD, 0xD4B5, 0x5800, 0xD4B3, 0x5801, 0xD4C6, + 0x5802, 0xB0F3, 0x5804, 0xD4CC, 0x5805, 0xB0ED, 0x5806, 0xB0EF, + 0x5807, 0xD4BB, 0x5808, 0xD4B6, 0x5809, 0xAE4B, 0x580A, 0xB0EE, + 0x580B, 0xD4B8, 0x580C, 0xD4C7, 0x580D, 0xD4CB, 0x580E, 0xD4C2, + 0x5810, 0xD4C4, 0x5814, 0xD4AE, 0x5819, 0xD8A1, 0x581B, 0xD8AA, + 0x581C, 0xD8A9, 0x581D, 0xB3FA, 0x581E, 0xD8A2, 0x5820, 0xB3FB, + 0x5821, 0xB3F9, 0x5823, 0xD8A4, 0x5824, 0xB3F6, 0x5825, 0xD8A8, + 0x5827, 0xD8A3, 0x5828, 0xD8A5, 0x5829, 0xD87D, 0x582A, 0xB3F4, + 0x582C, 0xD8B2, 0x582D, 0xD8B1, 0x582E, 0xD8AE, 0x582F, 0xB3F3, + 0x5830, 0xB3F7, 0x5831, 0xB3F8, 0x5832, 0xD14B, 0x5833, 0xD8AB, + 0x5834, 0xB3F5, 0x5835, 0xB0F4, 0x5836, 0xD8AD, 0x5837, 0xD87E, + 0x5838, 0xD8B0, 0x5839, 0xD8AF, 0x583B, 0xD8B3, 0x583D, 0xDCEF, + 0x583F, 0xD8AC, 0x5848, 0xD8A7, 0x5849, 0xDCE7, 0x584A, 0xB6F4, + 0x584B, 0xB6F7, 0x584C, 0xB6F2, 0x584D, 0xDCE6, 0x584E, 0xDCEA, + 0x584F, 0xDCE5, 0x5851, 0xB6EC, 0x5852, 0xB6F6, 0x5853, 0xDCE2, + 0x5854, 0xB6F0, 0x5855, 0xDCE9, 0x5857, 0xB6EE, 0x5858, 0xB6ED, + 0x5859, 0xDCEC, 0x585A, 0xB6EF, 0x585B, 0xDCEE, 0x585D, 0xDCEB, + 0x585E, 0xB6EB, 0x5862, 0xB6F5, 0x5863, 0xDCF0, 0x5864, 0xDCE4, + 0x5865, 0xDCED, 0x5868, 0xDCE3, 0x586B, 0xB6F1, 0x586D, 0xB6F3, + 0x586F, 0xDCE8, 0x5871, 0xDCF1, 0x5874, 0xE15D, 0x5875, 0xB9D0, + 0x5876, 0xE163, 0x5879, 0xB9D5, 0x587A, 0xE15F, 0x587B, 0xE166, + 0x587C, 0xE157, 0x587D, 0xB9D7, 0x587E, 0xB9D1, 0x587F, 0xE15C, + 0x5880, 0xBC55, 0x5881, 0xE15B, 0x5882, 0xE164, 0x5883, 0xB9D2, + 0x5885, 0xB9D6, 0x5886, 0xE15A, 0x5887, 0xE160, 0x5888, 0xE165, + 0x5889, 0xE156, 0x588A, 0xB9D4, 0x588B, 0xE15E, 0x588E, 0xE162, + 0x588F, 0xE168, 0x5890, 0xE158, 0x5891, 0xE161, 0x5893, 0xB9D3, + 0x5894, 0xE167, 0x5898, 0xE159, 0x589C, 0xBC59, 0x589D, 0xE54B, + 0x589E, 0xBC57, 0x589F, 0xBC56, 0x58A0, 0xE54D, 0x58A1, 0xE552, + 0x58A3, 0xE54E, 0x58A5, 0xE551, 0x58A6, 0xBC5C, 0x58A8, 0xBEA5, + 0x58A9, 0xBC5B, 0x58AB, 0xE54A, 0x58AC, 0xE550, 0x58AE, 0xBC5A, + 0x58AF, 0xE54F, 0x58B1, 0xE54C, 0x58B3, 0xBC58, 0x58BA, 0xE94D, + 0x58BB, 0xF9D9, 0x58BC, 0xE94F, 0x58BD, 0xE94A, 0x58BE, 0xBEC1, + 0x58BF, 0xE94C, 0x58C1, 0xBEC0, 0x58C2, 0xE94E, 0x58C5, 0xBEC3, + 0x58C6, 0xE950, 0x58C7, 0xBEC2, 0x58C8, 0xE949, 0x58C9, 0xE94B, + 0x58CE, 0xC0A5, 0x58CF, 0xECCC, 0x58D1, 0xC0A4, 0x58D2, 0xECCD, + 0x58D3, 0xC0A3, 0x58D4, 0xECCB, 0x58D5, 0xC0A2, 0x58D6, 0xECCA, + 0x58D8, 0xC253, 0x58D9, 0xC252, 0x58DA, 0xF1F6, 0x58DB, 0xF1F8, + 0x58DD, 0xF1F7, 0x58DE, 0xC361, 0x58DF, 0xC362, 0x58E2, 0xC363, + 0x58E3, 0xF442, 0x58E4, 0xC45B, 0x58E7, 0xF7D3, 0x58E8, 0xF7D2, + 0x58E9, 0xC5F2, 0x58EB, 0xA468, 0x58EC, 0xA4D0, 0x58EF, 0xA7A7, + 0x58F4, 0xCE5F, 0x58F9, 0xB3FC, 0x58FA, 0xB3FD, 0x58FC, 0xDCF2, + 0x58FD, 0xB9D8, 0x58FE, 0xE169, 0x58FF, 0xE553, 0x5903, 0xC95A, + 0x5906, 0xCAB0, 0x590C, 0xCC42, 0x590D, 0xCE60, 0x590E, 0xD159, + 0x590F, 0xAE4C, 0x5912, 0xF1F9, 0x5914, 0xC4DC, 0x5915, 0xA469, + 0x5916, 0xA57E, 0x5917, 0xC970, 0x5919, 0xA667, 0x591A, 0xA668, + 0x591C, 0xA95D, 0x5920, 0xB0F7, 0x5922, 0xB9DA, 0x5924, 0xB9DB, + 0x5925, 0xB9D9, 0x5927, 0xA46A, 0x5929, 0xA4D1, 0x592A, 0xA4D3, + 0x592B, 0xA4D2, 0x592C, 0xC95B, 0x592D, 0xA4D4, 0x592E, 0xA5A1, + 0x592F, 0xC971, 0x5931, 0xA5A2, 0x5937, 0xA669, 0x5938, 0xA66A, + 0x593C, 0xC9CB, 0x593E, 0xA7A8, 0x5940, 0xCAB1, 0x5944, 0xA961, + 0x5945, 0xCC43, 0x5947, 0xA95F, 0x5948, 0xA960, 0x5949, 0xA95E, + 0x594A, 0xD15A, 0x594E, 0xABB6, 0x594F, 0xABB5, 0x5950, 0xABB7, + 0x5951, 0xABB4, 0x5953, 0xCE61, 0x5954, 0xA962, 0x5955, 0xABB3, + 0x5957, 0xAE4D, 0x5958, 0xAE4E, 0x595A, 0xAE4F, 0x595C, 0xD4CD, + 0x5960, 0xB3FE, 0x5961, 0xD8B4, 0x5962, 0xB0F8, 0x5967, 0xB6F8, + 0x5969, 0xB9DD, 0x596A, 0xB9DC, 0x596B, 0xE16A, 0x596D, 0xBC5D, + 0x596E, 0xBEC4, 0x5970, 0xEFC0, 0x5971, 0xF6DA, 0x5972, 0xF7D4, + 0x5973, 0xA46B, 0x5974, 0xA5A3, 0x5976, 0xA5A4, 0x5977, 0xC9D1, + 0x5978, 0xA66C, 0x5979, 0xA66F, 0x597B, 0xC9CF, 0x597C, 0xC9CD, + 0x597D, 0xA66E, 0x597E, 0xC9D0, 0x597F, 0xC9D2, 0x5980, 0xC9CC, + 0x5981, 0xA671, 0x5982, 0xA670, 0x5983, 0xA66D, 0x5984, 0xA66B, + 0x5985, 0xC9CE, 0x598A, 0xA7B3, 0x598D, 0xA7B0, 0x598E, 0xCAB6, + 0x598F, 0xCAB9, 0x5990, 0xCAB8, 0x5992, 0xA7AA, 0x5993, 0xA7B2, + 0x5996, 0xA7AF, 0x5997, 0xCAB5, 0x5998, 0xCAB3, 0x5999, 0xA7AE, + 0x599D, 0xA7A9, 0x599E, 0xA7AC, 0x59A0, 0xCAB4, 0x59A1, 0xCABB, + 0x59A2, 0xCAB7, 0x59A3, 0xA7AD, 0x59A4, 0xA7B1, 0x59A5, 0xA7B4, + 0x59A6, 0xCAB2, 0x59A7, 0xCABA, 0x59A8, 0xA7AB, 0x59AE, 0xA967, + 0x59AF, 0xA96F, 0x59B1, 0xCC4F, 0x59B2, 0xCC48, 0x59B3, 0xA970, + 0x59B4, 0xCC53, 0x59B5, 0xCC44, 0x59B6, 0xCC4B, 0x59B9, 0xA966, + 0x59BA, 0xCC45, 0x59BB, 0xA964, 0x59BC, 0xCC4C, 0x59BD, 0xCC50, + 0x59BE, 0xA963, 0x59C0, 0xCC51, 0x59C1, 0xCC4A, 0x59C3, 0xCC4D, + 0x59C5, 0xA972, 0x59C6, 0xA969, 0x59C7, 0xCC54, 0x59C8, 0xCC52, + 0x59CA, 0xA96E, 0x59CB, 0xA96C, 0x59CC, 0xCC49, 0x59CD, 0xA96B, + 0x59CE, 0xCC47, 0x59CF, 0xCC46, 0x59D0, 0xA96A, 0x59D1, 0xA968, + 0x59D2, 0xA971, 0x59D3, 0xA96D, 0x59D4, 0xA965, 0x59D6, 0xCC4E, + 0x59D8, 0xABB9, 0x59DA, 0xABC0, 0x59DB, 0xCE6F, 0x59DC, 0xABB8, + 0x59DD, 0xCE67, 0x59DE, 0xCE63, 0x59E0, 0xCE73, 0x59E1, 0xCE62, + 0x59E3, 0xABBB, 0x59E4, 0xCE6C, 0x59E5, 0xABBE, 0x59E6, 0xABC1, + 0x59E8, 0xABBC, 0x59E9, 0xCE70, 0x59EA, 0xABBF, 0x59EC, 0xAE56, + 0x59ED, 0xCE76, 0x59EE, 0xCE64, 0x59F1, 0xCE66, 0x59F2, 0xCE6D, + 0x59F3, 0xCE71, 0x59F4, 0xCE75, 0x59F5, 0xCE72, 0x59F6, 0xCE6B, + 0x59F7, 0xCE6E, 0x59FA, 0xCE68, 0x59FB, 0xABC3, 0x59FC, 0xCE6A, + 0x59FD, 0xCE69, 0x59FE, 0xCE74, 0x59FF, 0xABBA, 0x5A00, 0xCE65, + 0x5A01, 0xABC2, 0x5A03, 0xABBD, 0x5A09, 0xAE5C, 0x5A0A, 0xD162, + 0x5A0C, 0xAE5B, 0x5A0F, 0xD160, 0x5A11, 0xAE50, 0x5A13, 0xAE55, + 0x5A15, 0xD15F, 0x5A16, 0xD15C, 0x5A17, 0xD161, 0x5A18, 0xAE51, + 0x5A19, 0xD15B, 0x5A1B, 0xAE54, 0x5A1C, 0xAE52, 0x5A1E, 0xD163, + 0x5A1F, 0xAE53, 0x5A20, 0xAE57, 0x5A23, 0xAE58, 0x5A25, 0xAE5A, + 0x5A29, 0xAE59, 0x5A2D, 0xD15D, 0x5A2E, 0xD15E, 0x5A33, 0xD164, + 0x5A35, 0xD4D4, 0x5A36, 0xB0F9, 0x5A37, 0xD8C2, 0x5A38, 0xD4D3, + 0x5A39, 0xD4E6, 0x5A3C, 0xB140, 0x5A3E, 0xD4E4, 0x5A40, 0xB0FE, + 0x5A41, 0xB0FA, 0x5A42, 0xD4ED, 0x5A43, 0xD4DD, 0x5A44, 0xD4E0, + 0x5A46, 0xB143, 0x5A47, 0xD4EA, 0x5A48, 0xD4E2, 0x5A49, 0xB0FB, + 0x5A4A, 0xB144, 0x5A4C, 0xD4E7, 0x5A4D, 0xD4E5, 0x5A50, 0xD4D6, + 0x5A51, 0xD4EB, 0x5A52, 0xD4DF, 0x5A53, 0xD4DA, 0x5A55, 0xD4D0, + 0x5A56, 0xD4EC, 0x5A57, 0xD4DC, 0x5A58, 0xD4CF, 0x5A5A, 0xB142, + 0x5A5B, 0xD4E1, 0x5A5C, 0xD4EE, 0x5A5D, 0xD4DE, 0x5A5E, 0xD4D2, + 0x5A5F, 0xD4D7, 0x5A60, 0xD4CE, 0x5A62, 0xB141, 0x5A64, 0xD4DB, + 0x5A65, 0xD4D8, 0x5A66, 0xB0FC, 0x5A67, 0xD4D1, 0x5A69, 0xD4E9, + 0x5A6A, 0xB0FD, 0x5A6C, 0xD4D9, 0x5A6D, 0xD4D5, 0x5A70, 0xD4E8, + 0x5A77, 0xB440, 0x5A78, 0xD8BB, 0x5A7A, 0xD8B8, 0x5A7B, 0xD8C9, + 0x5A7C, 0xD8BD, 0x5A7D, 0xD8CA, 0x5A7F, 0xB442, 0x5A83, 0xD8C6, + 0x5A84, 0xD8C3, 0x5A8A, 0xD8C4, 0x5A8B, 0xD8C7, 0x5A8C, 0xD8CB, + 0x5A8E, 0xD4E3, 0x5A8F, 0xD8CD, 0x5A90, 0xDD47, 0x5A92, 0xB443, + 0x5A93, 0xD8CE, 0x5A94, 0xD8B6, 0x5A95, 0xD8C0, 0x5A97, 0xD8C5, + 0x5A9A, 0xB441, 0x5A9B, 0xB444, 0x5A9C, 0xD8CC, 0x5A9D, 0xD8CF, + 0x5A9E, 0xD8BA, 0x5A9F, 0xD8B7, 0x5AA2, 0xD8B9, 0x5AA5, 0xD8BE, + 0x5AA6, 0xD8BC, 0x5AA7, 0xB445, 0x5AA9, 0xD8C8, 0x5AAC, 0xD8BF, + 0x5AAE, 0xD8C1, 0x5AAF, 0xD8B5, 0x5AB0, 0xDCFA, 0x5AB1, 0xDCF8, + 0x5AB2, 0xB742, 0x5AB3, 0xB740, 0x5AB4, 0xDD43, 0x5AB5, 0xDCF9, + 0x5AB6, 0xDD44, 0x5AB7, 0xDD40, 0x5AB8, 0xDCF7, 0x5AB9, 0xDD46, + 0x5ABA, 0xDCF6, 0x5ABB, 0xDCFD, 0x5ABC, 0xB6FE, 0x5ABD, 0xB6FD, + 0x5ABE, 0xB6FC, 0x5ABF, 0xDCFB, 0x5AC0, 0xDD41, 0x5AC1, 0xB6F9, + 0x5AC2, 0xB741, 0x5AC4, 0xDCF4, 0x5AC6, 0xDCFE, 0x5AC7, 0xDCF3, + 0x5AC8, 0xDCFC, 0x5AC9, 0xB6FA, 0x5ACA, 0xDD42, 0x5ACB, 0xDCF5, + 0x5ACC, 0xB6FB, 0x5ACD, 0xDD45, 0x5AD5, 0xE16E, 0x5AD6, 0xB9E2, + 0x5AD7, 0xB9E1, 0x5AD8, 0xB9E3, 0x5AD9, 0xE17A, 0x5ADA, 0xE170, + 0x5ADB, 0xE176, 0x5ADC, 0xE16B, 0x5ADD, 0xE179, 0x5ADE, 0xE178, + 0x5ADF, 0xE17C, 0x5AE0, 0xE175, 0x5AE1, 0xB9DE, 0x5AE2, 0xE174, + 0x5AE3, 0xB9E4, 0x5AE5, 0xE16D, 0x5AE6, 0xB9DF, 0x5AE8, 0xE17B, + 0x5AE9, 0xB9E0, 0x5AEA, 0xE16F, 0x5AEB, 0xE172, 0x5AEC, 0xE177, + 0x5AED, 0xE171, 0x5AEE, 0xE16C, 0x5AF3, 0xE173, 0x5AF4, 0xE555, + 0x5AF5, 0xBC61, 0x5AF6, 0xE558, 0x5AF7, 0xE557, 0x5AF8, 0xE55A, + 0x5AF9, 0xE55C, 0x5AFA, 0xF9DC, 0x5AFB, 0xBC5F, 0x5AFD, 0xE556, + 0x5AFF, 0xE554, 0x5B01, 0xE55D, 0x5B02, 0xE55B, 0x5B03, 0xE559, + 0x5B05, 0xE55F, 0x5B07, 0xE55E, 0x5B08, 0xBC63, 0x5B09, 0xBC5E, + 0x5B0B, 0xBC60, 0x5B0C, 0xBC62, 0x5B0F, 0xE560, 0x5B10, 0xE957, + 0x5B13, 0xE956, 0x5B14, 0xE955, 0x5B16, 0xE958, 0x5B17, 0xE951, + 0x5B19, 0xE952, 0x5B1A, 0xE95A, 0x5B1B, 0xE953, 0x5B1D, 0xBEC5, + 0x5B1E, 0xE95C, 0x5B20, 0xE95B, 0x5B21, 0xE954, 0x5B23, 0xECD1, + 0x5B24, 0xC0A8, 0x5B25, 0xECCF, 0x5B26, 0xECD4, 0x5B27, 0xECD3, + 0x5B28, 0xE959, 0x5B2A, 0xC0A7, 0x5B2C, 0xECD2, 0x5B2D, 0xECCE, + 0x5B2E, 0xECD6, 0x5B2F, 0xECD5, 0x5B30, 0xC0A6, 0x5B32, 0xECD0, + 0x5B34, 0xBEC6, 0x5B38, 0xC254, 0x5B3C, 0xEFC1, 0x5B3D, 0xF1FA, + 0x5B3E, 0xF1FB, 0x5B3F, 0xF1FC, 0x5B40, 0xC45C, 0x5B43, 0xC45D, + 0x5B45, 0xF443, 0x5B47, 0xF5C8, 0x5B48, 0xF5C7, 0x5B4B, 0xF6DB, + 0x5B4C, 0xF6DC, 0x5B4D, 0xF7D5, 0x5B4E, 0xF8A7, 0x5B50, 0xA46C, + 0x5B51, 0xA46D, 0x5B53, 0xA46E, 0x5B54, 0xA4D5, 0x5B55, 0xA5A5, + 0x5B56, 0xC9D3, 0x5B57, 0xA672, 0x5B58, 0xA673, 0x5B5A, 0xA7B7, + 0x5B5B, 0xA7B8, 0x5B5C, 0xA7B6, 0x5B5D, 0xA7B5, 0x5B5F, 0xA973, + 0x5B62, 0xCC55, 0x5B63, 0xA975, 0x5B64, 0xA974, 0x5B65, 0xCC56, + 0x5B69, 0xABC4, 0x5B6B, 0xAE5D, 0x5B6C, 0xD165, 0x5B6E, 0xD4F0, + 0x5B70, 0xB145, 0x5B71, 0xB447, 0x5B72, 0xD4EF, 0x5B73, 0xB446, + 0x5B75, 0xB9E5, 0x5B77, 0xE17D, 0x5B78, 0xBEC7, 0x5B7A, 0xC0A9, + 0x5B7B, 0xECD7, 0x5B7D, 0xC45E, 0x5B7F, 0xC570, 0x5B81, 0xC972, + 0x5B83, 0xA5A6, 0x5B84, 0xC973, 0x5B85, 0xA676, 0x5B87, 0xA674, + 0x5B88, 0xA675, 0x5B89, 0xA677, 0x5B8B, 0xA7BA, 0x5B8C, 0xA7B9, + 0x5B8E, 0xCABC, 0x5B8F, 0xA7BB, 0x5B92, 0xCABD, 0x5B93, 0xCC57, + 0x5B95, 0xCC58, 0x5B97, 0xA976, 0x5B98, 0xA978, 0x5B99, 0xA97A, + 0x5B9A, 0xA977, 0x5B9B, 0xA97B, 0x5B9C, 0xA979, 0x5BA2, 0xABC8, + 0x5BA3, 0xABC5, 0x5BA4, 0xABC7, 0x5BA5, 0xABC9, 0x5BA6, 0xABC6, + 0x5BA7, 0xD166, 0x5BA8, 0xCE77, 0x5BAC, 0xD168, 0x5BAD, 0xD167, + 0x5BAE, 0xAE63, 0x5BB0, 0xAE5F, 0x5BB3, 0xAE60, 0x5BB4, 0xAE62, + 0x5BB5, 0xAE64, 0x5BB6, 0xAE61, 0x5BB8, 0xAE66, 0x5BB9, 0xAE65, + 0x5BBF, 0xB14A, 0x5BC0, 0xD4F2, 0x5BC1, 0xD4F1, 0x5BC2, 0xB149, + 0x5BC4, 0xB148, 0x5BC5, 0xB147, 0x5BC6, 0xB14B, 0x5BC7, 0xB146, + 0x5BCA, 0xD8D5, 0x5BCB, 0xD8D2, 0x5BCC, 0xB449, 0x5BCD, 0xD8D1, + 0x5BCE, 0xD8D6, 0x5BD0, 0xB44B, 0x5BD1, 0xD8D4, 0x5BD2, 0xB448, + 0x5BD3, 0xB44A, 0x5BD4, 0xD8D3, 0x5BD6, 0xDD48, 0x5BD8, 0xDD49, + 0x5BD9, 0xDD4A, 0x5BDE, 0xB9E6, 0x5BDF, 0xB9EE, 0x5BE0, 0xE17E, + 0x5BE1, 0xB9E8, 0x5BE2, 0xB9EC, 0x5BE3, 0xE1A1, 0x5BE4, 0xB9ED, + 0x5BE5, 0xB9E9, 0x5BE6, 0xB9EA, 0x5BE7, 0xB9E7, 0x5BE8, 0xB9EB, + 0x5BE9, 0xBC66, 0x5BEA, 0xD8D0, 0x5BEB, 0xBC67, 0x5BEC, 0xBC65, + 0x5BEE, 0xBC64, 0x5BEF, 0xE95D, 0x5BF0, 0xBEC8, 0x5BF1, 0xECD8, + 0x5BF2, 0xECD9, 0x5BF5, 0xC364, 0x5BF6, 0xC45F, 0x5BF8, 0xA46F, + 0x5BFA, 0xA678, 0x5C01, 0xABCA, 0x5C03, 0xD169, 0x5C04, 0xAE67, + 0x5C07, 0xB14E, 0x5C08, 0xB14D, 0x5C09, 0xB14C, 0x5C0A, 0xB44C, + 0x5C0B, 0xB44D, 0x5C0C, 0xD8D7, 0x5C0D, 0xB9EF, 0x5C0E, 0xBEC9, + 0x5C0F, 0xA470, 0x5C10, 0xC95C, 0x5C11, 0xA4D6, 0x5C12, 0xC974, + 0x5C15, 0xC9D4, 0x5C16, 0xA679, 0x5C1A, 0xA97C, 0x5C1F, 0xDD4B, + 0x5C22, 0xA471, 0x5C24, 0xA4D7, 0x5C25, 0xC9D5, 0x5C28, 0xCABE, + 0x5C2A, 0xCABF, 0x5C2C, 0xA7BC, 0x5C30, 0xD8D8, 0x5C31, 0xB44E, + 0x5C33, 0xDD4C, 0x5C37, 0xC0AA, 0x5C38, 0xA472, 0x5C39, 0xA4A8, + 0x5C3A, 0xA4D8, 0x5C3B, 0xC975, 0x5C3C, 0xA5A7, 0x5C3E, 0xA7C0, + 0x5C3F, 0xA7BF, 0x5C40, 0xA7BD, 0x5C41, 0xA7BE, 0x5C44, 0xCC59, + 0x5C45, 0xA97E, 0x5C46, 0xA9A1, 0x5C47, 0xCC5A, 0x5C48, 0xA97D, + 0x5C4B, 0xABCE, 0x5C4C, 0xCE78, 0x5C4D, 0xABCD, 0x5C4E, 0xABCB, + 0x5C4F, 0xABCC, 0x5C50, 0xAE6A, 0x5C51, 0xAE68, 0x5C54, 0xD16B, + 0x5C55, 0xAE69, 0x5C56, 0xD16A, 0x5C58, 0xAE5E, 0x5C59, 0xD4F3, + 0x5C5C, 0xB150, 0x5C5D, 0xB151, 0x5C60, 0xB14F, 0x5C62, 0xB9F0, + 0x5C63, 0xE1A2, 0x5C64, 0xBC68, 0x5C65, 0xBC69, 0x5C67, 0xE561, + 0x5C68, 0xC0AB, 0x5C69, 0xEFC2, 0x5C6A, 0xEFC3, 0x5C6C, 0xC4DD, + 0x5C6D, 0xF8A8, 0x5C6E, 0xC94B, 0x5C6F, 0xA4D9, 0x5C71, 0xA473, + 0x5C73, 0xC977, 0x5C74, 0xC976, 0x5C79, 0xA67A, 0x5C7A, 0xC9D7, + 0x5C7B, 0xC9D8, 0x5C7C, 0xC9D6, 0x5C7E, 0xC9D9, 0x5C86, 0xCAC7, + 0x5C88, 0xCAC2, 0x5C89, 0xCAC4, 0x5C8A, 0xCAC6, 0x5C8B, 0xCAC3, + 0x5C8C, 0xA7C4, 0x5C8D, 0xCAC0, 0x5C8F, 0xCAC1, 0x5C90, 0xA7C1, + 0x5C91, 0xA7C2, 0x5C92, 0xCAC5, 0x5C93, 0xCAC8, 0x5C94, 0xA7C3, + 0x5C95, 0xCAC9, 0x5C9D, 0xCC68, 0x5C9F, 0xCC62, 0x5CA0, 0xCC5D, + 0x5CA1, 0xA9A3, 0x5CA2, 0xCC65, 0x5CA3, 0xCC63, 0x5CA4, 0xCC5C, + 0x5CA5, 0xCC69, 0x5CA6, 0xCC6C, 0x5CA7, 0xCC67, 0x5CA8, 0xCC60, + 0x5CA9, 0xA9A5, 0x5CAA, 0xCC66, 0x5CAB, 0xA9A6, 0x5CAC, 0xCC61, + 0x5CAD, 0xCC64, 0x5CAE, 0xCC5B, 0x5CAF, 0xCC5F, 0x5CB0, 0xCC6B, + 0x5CB1, 0xA9A7, 0x5CB3, 0xA9A8, 0x5CB5, 0xCC5E, 0x5CB6, 0xCC6A, + 0x5CB7, 0xA9A2, 0x5CB8, 0xA9A4, 0x5CC6, 0xCEAB, 0x5CC7, 0xCEA4, + 0x5CC8, 0xCEAA, 0x5CC9, 0xCEA3, 0x5CCA, 0xCEA5, 0x5CCB, 0xCE7D, + 0x5CCC, 0xCE7B, 0x5CCE, 0xCEAC, 0x5CCF, 0xCEA9, 0x5CD0, 0xCE79, + 0x5CD2, 0xABD0, 0x5CD3, 0xCEA7, 0x5CD4, 0xCEA8, 0x5CD6, 0xCEA6, + 0x5CD7, 0xCE7C, 0x5CD8, 0xCE7A, 0x5CD9, 0xABCF, 0x5CDA, 0xCEA2, + 0x5CDB, 0xCE7E, 0x5CDE, 0xCEA1, 0x5CDF, 0xCEAD, 0x5CE8, 0xAE6F, + 0x5CEA, 0xAE6E, 0x5CEC, 0xD16C, 0x5CED, 0xAE6B, 0x5CEE, 0xD16E, + 0x5CF0, 0xAE70, 0x5CF1, 0xD16F, 0x5CF4, 0xAE73, 0x5CF6, 0xAE71, + 0x5CF7, 0xD170, 0x5CF8, 0xCEAE, 0x5CF9, 0xD172, 0x5CFB, 0xAE6D, + 0x5CFD, 0xAE6C, 0x5CFF, 0xD16D, 0x5D00, 0xD171, 0x5D01, 0xAE72, + 0x5D06, 0xB153, 0x5D07, 0xB152, 0x5D0B, 0xD4F5, 0x5D0C, 0xD4F9, + 0x5D0D, 0xD4FB, 0x5D0E, 0xB154, 0x5D0F, 0xD4FE, 0x5D11, 0xB158, + 0x5D12, 0xD541, 0x5D14, 0xB15A, 0x5D16, 0xB156, 0x5D17, 0xB15E, + 0x5D19, 0xB15B, 0x5D1A, 0xD4F7, 0x5D1B, 0xB155, 0x5D1D, 0xD4F6, + 0x5D1E, 0xD4F4, 0x5D1F, 0xD543, 0x5D20, 0xD4F8, 0x5D22, 0xB157, + 0x5D23, 0xD542, 0x5D24, 0xB15C, 0x5D25, 0xD4FD, 0x5D26, 0xD4FC, + 0x5D27, 0xB15D, 0x5D28, 0xD4FA, 0x5D29, 0xB159, 0x5D2E, 0xD544, + 0x5D30, 0xD540, 0x5D31, 0xD8E7, 0x5D32, 0xD8EE, 0x5D33, 0xD8E3, + 0x5D34, 0xB451, 0x5D35, 0xD8DF, 0x5D36, 0xD8EF, 0x5D37, 0xD8D9, + 0x5D38, 0xD8EC, 0x5D39, 0xD8EA, 0x5D3A, 0xD8E4, 0x5D3C, 0xD8ED, + 0x5D3D, 0xD8E6, 0x5D3F, 0xD8DE, 0x5D40, 0xD8F0, 0x5D41, 0xD8DC, + 0x5D42, 0xD8E9, 0x5D43, 0xD8DA, 0x5D45, 0xD8F1, 0x5D47, 0xB452, + 0x5D49, 0xD8EB, 0x5D4A, 0xDD4F, 0x5D4B, 0xD8DD, 0x5D4C, 0xB44F, + 0x5D4E, 0xD8E1, 0x5D50, 0xB450, 0x5D51, 0xD8E0, 0x5D52, 0xD8E5, + 0x5D55, 0xD8E2, 0x5D59, 0xD8E8, 0x5D5E, 0xDD53, 0x5D62, 0xDD56, + 0x5D63, 0xDD4E, 0x5D65, 0xDD50, 0x5D67, 0xDD55, 0x5D68, 0xDD54, + 0x5D69, 0xB743, 0x5D6B, 0xD8DB, 0x5D6C, 0xDD52, 0x5D6F, 0xB744, + 0x5D71, 0xDD4D, 0x5D72, 0xDD51, 0x5D77, 0xE1A9, 0x5D79, 0xE1B0, + 0x5D7A, 0xE1A7, 0x5D7C, 0xE1AE, 0x5D7D, 0xE1A5, 0x5D7E, 0xE1AD, + 0x5D7F, 0xE1B1, 0x5D80, 0xE1A4, 0x5D81, 0xE1A8, 0x5D82, 0xE1A3, + 0x5D84, 0xB9F1, 0x5D86, 0xE1A6, 0x5D87, 0xB9F2, 0x5D88, 0xE1AC, + 0x5D89, 0xE1AB, 0x5D8A, 0xE1AA, 0x5D8D, 0xE1AF, 0x5D92, 0xE565, + 0x5D93, 0xE567, 0x5D94, 0xBC6B, 0x5D95, 0xE568, 0x5D97, 0xE563, + 0x5D99, 0xE562, 0x5D9A, 0xE56C, 0x5D9C, 0xE56A, 0x5D9D, 0xBC6A, + 0x5D9E, 0xE56D, 0x5D9F, 0xE564, 0x5DA0, 0xE569, 0x5DA1, 0xE56B, + 0x5DA2, 0xE566, 0x5DA7, 0xE961, 0x5DA8, 0xE966, 0x5DA9, 0xE960, + 0x5DAA, 0xE965, 0x5DAC, 0xE95E, 0x5DAD, 0xE968, 0x5DAE, 0xE964, + 0x5DAF, 0xE969, 0x5DB0, 0xE963, 0x5DB1, 0xE95F, 0x5DB2, 0xE967, + 0x5DB4, 0xE96A, 0x5DB5, 0xE962, 0x5DB7, 0xECDA, 0x5DB8, 0xC0AF, + 0x5DBA, 0xC0AD, 0x5DBC, 0xC0AC, 0x5DBD, 0xC0AE, 0x5DC0, 0xEFC4, + 0x5DC2, 0xF172, 0x5DC3, 0xF1FD, 0x5DC6, 0xF444, 0x5DC7, 0xF445, + 0x5DC9, 0xC460, 0x5DCB, 0xF5C9, 0x5DCD, 0xC4DE, 0x5DCF, 0xF5CA, + 0x5DD1, 0xF6DE, 0x5DD2, 0xC572, 0x5DD4, 0xC571, 0x5DD5, 0xF6DD, + 0x5DD6, 0xC5C9, 0x5DD8, 0xF7D6, 0x5DDD, 0xA474, 0x5DDE, 0xA67B, + 0x5DDF, 0xC9DA, 0x5DE0, 0xCACA, 0x5DE1, 0xA8B5, 0x5DE2, 0xB15F, + 0x5DE5, 0xA475, 0x5DE6, 0xA5AA, 0x5DE7, 0xA5A9, 0x5DE8, 0xA5A8, + 0x5DEB, 0xA7C5, 0x5DEE, 0xAE74, 0x5DF0, 0xDD57, 0x5DF1, 0xA476, + 0x5DF2, 0xA477, 0x5DF3, 0xA478, 0x5DF4, 0xA4DA, 0x5DF7, 0xABD1, + 0x5DF9, 0xCEAF, 0x5DFD, 0xB453, 0x5DFE, 0xA479, 0x5DFF, 0xC95D, + 0x5E02, 0xA5AB, 0x5E03, 0xA5AC, 0x5E04, 0xC978, 0x5E06, 0xA67C, + 0x5E0A, 0xCACB, 0x5E0C, 0xA7C6, 0x5E0E, 0xCACC, 0x5E11, 0xA9AE, + 0x5E14, 0xCC6E, 0x5E15, 0xA9AC, 0x5E16, 0xA9AB, 0x5E17, 0xCC6D, + 0x5E18, 0xA9A9, 0x5E19, 0xCC6F, 0x5E1A, 0xA9AA, 0x5E1B, 0xA9AD, + 0x5E1D, 0xABD2, 0x5E1F, 0xABD4, 0x5E20, 0xCEB3, 0x5E21, 0xCEB0, + 0x5E22, 0xCEB1, 0x5E23, 0xCEB2, 0x5E24, 0xCEB4, 0x5E25, 0xABD3, + 0x5E28, 0xD174, 0x5E29, 0xD173, 0x5E2B, 0xAE76, 0x5E2D, 0xAE75, + 0x5E33, 0xB162, 0x5E34, 0xD546, 0x5E36, 0xB161, 0x5E37, 0xB163, + 0x5E38, 0xB160, 0x5E3D, 0xB455, 0x5E3E, 0xD545, 0x5E40, 0xB456, + 0x5E41, 0xD8F3, 0x5E43, 0xB457, 0x5E44, 0xD8F2, 0x5E45, 0xB454, + 0x5E4A, 0xDD5A, 0x5E4B, 0xDD5C, 0x5E4C, 0xB745, 0x5E4D, 0xDD5B, + 0x5E4E, 0xDD59, 0x5E4F, 0xDD58, 0x5E53, 0xE1B4, 0x5E54, 0xB9F7, + 0x5E55, 0xB9F5, 0x5E57, 0xB9F6, 0x5E58, 0xE1B2, 0x5E59, 0xE1B3, + 0x5E5B, 0xB9F3, 0x5E5C, 0xE571, 0x5E5D, 0xE56F, 0x5E5F, 0xBC6D, + 0x5E60, 0xE570, 0x5E61, 0xBC6E, 0x5E62, 0xBC6C, 0x5E63, 0xB9F4, + 0x5E66, 0xE96D, 0x5E67, 0xE96B, 0x5E68, 0xE96C, 0x5E69, 0xE56E, + 0x5E6A, 0xECDC, 0x5E6B, 0xC0B0, 0x5E6C, 0xECDB, 0x5E6D, 0xEFC5, + 0x5E6E, 0xEFC6, 0x5E6F, 0xE96E, 0x5E70, 0xF1FE, 0x5E72, 0xA47A, + 0x5E73, 0xA5AD, 0x5E74, 0xA67E, 0x5E75, 0xC9DB, 0x5E76, 0xA67D, + 0x5E78, 0xA9AF, 0x5E79, 0xB746, 0x5E7B, 0xA4DB, 0x5E7C, 0xA5AE, + 0x5E7D, 0xABD5, 0x5E7E, 0xB458, 0x5E80, 0xC979, 0x5E82, 0xC97A, + 0x5E84, 0xC9DC, 0x5E87, 0xA7C8, 0x5E88, 0xCAD0, 0x5E89, 0xCACE, + 0x5E8A, 0xA7C9, 0x5E8B, 0xCACD, 0x5E8C, 0xCACF, 0x5E8D, 0xCAD1, + 0x5E8F, 0xA7C7, 0x5E95, 0xA9B3, 0x5E96, 0xA9B4, 0x5E97, 0xA9B1, + 0x5E9A, 0xA9B0, 0x5E9B, 0xCEB8, 0x5E9C, 0xA9B2, 0x5EA0, 0xABD6, + 0x5EA2, 0xCEB7, 0x5EA3, 0xCEB9, 0x5EA4, 0xCEB6, 0x5EA5, 0xCEBA, + 0x5EA6, 0xABD7, 0x5EA7, 0xAE79, 0x5EA8, 0xD175, 0x5EAA, 0xD177, + 0x5EAB, 0xAE77, 0x5EAC, 0xD178, 0x5EAD, 0xAE78, 0x5EAE, 0xD176, + 0x5EB0, 0xCEB5, 0x5EB1, 0xD547, 0x5EB2, 0xD54A, 0x5EB3, 0xD54B, + 0x5EB4, 0xD548, 0x5EB5, 0xB167, 0x5EB6, 0xB166, 0x5EB7, 0xB164, + 0x5EB8, 0xB165, 0x5EB9, 0xD549, 0x5EBE, 0xB168, 0x5EC1, 0xB45A, + 0x5EC2, 0xB45B, 0x5EC4, 0xB45C, 0x5EC5, 0xDD5D, 0x5EC6, 0xDD5F, + 0x5EC7, 0xDD61, 0x5EC8, 0xB748, 0x5EC9, 0xB747, 0x5ECA, 0xB459, + 0x5ECB, 0xDD60, 0x5ECC, 0xDD5E, 0x5ECE, 0xE1B8, 0x5ED1, 0xE1B6, + 0x5ED2, 0xE1BC, 0x5ED3, 0xB9F8, 0x5ED4, 0xE1BD, 0x5ED5, 0xE1BA, + 0x5ED6, 0xB9F9, 0x5ED7, 0xE1B7, 0x5ED8, 0xE1B5, 0x5ED9, 0xE1BB, + 0x5EDA, 0xBC70, 0x5EDB, 0xE573, 0x5EDC, 0xE1B9, 0x5EDD, 0xBC72, + 0x5EDE, 0xE574, 0x5EDF, 0xBC71, 0x5EE0, 0xBC74, 0x5EE1, 0xE575, + 0x5EE2, 0xBC6F, 0x5EE3, 0xBC73, 0x5EE5, 0xE973, 0x5EE6, 0xE971, + 0x5EE7, 0xE970, 0x5EE8, 0xE972, 0x5EE9, 0xE96F, 0x5EEC, 0xC366, + 0x5EEE, 0xF446, 0x5EEF, 0xF447, 0x5EF1, 0xF5CB, 0x5EF2, 0xF6DF, + 0x5EF3, 0xC655, 0x5EF6, 0xA9B5, 0x5EF7, 0xA7CA, 0x5EFA, 0xABD8, + 0x5EFE, 0xA47B, 0x5EFF, 0xA4DC, 0x5F01, 0xA5AF, 0x5F02, 0xC9DD, + 0x5F04, 0xA7CB, 0x5F05, 0xCAD2, 0x5F07, 0xCEBB, 0x5F08, 0xABD9, + 0x5F0A, 0xB9FA, 0x5F0B, 0xA47C, 0x5F0F, 0xA6A1, 0x5F12, 0xB749, + 0x5F13, 0xA47D, 0x5F14, 0xA4DD, 0x5F15, 0xA4DE, 0x5F17, 0xA5B1, + 0x5F18, 0xA5B0, 0x5F1A, 0xC9DE, 0x5F1B, 0xA6A2, 0x5F1D, 0xCAD3, + 0x5F1F, 0xA7CC, 0x5F22, 0xCC71, 0x5F23, 0xCC72, 0x5F24, 0xCC73, + 0x5F26, 0xA9B6, 0x5F27, 0xA9B7, 0x5F28, 0xCC70, 0x5F29, 0xA9B8, + 0x5F2D, 0xABDA, 0x5F2E, 0xCEBC, 0x5F30, 0xD17A, 0x5F31, 0xAE7A, + 0x5F33, 0xD179, 0x5F35, 0xB169, 0x5F36, 0xD54C, 0x5F37, 0xB16A, + 0x5F38, 0xD54D, 0x5F3C, 0xB45D, 0x5F40, 0xDD62, 0x5F43, 0xE1BF, + 0x5F44, 0xE1BE, 0x5F46, 0xB9FB, 0x5F48, 0xBC75, 0x5F49, 0xE576, + 0x5F4A, 0xBECA, 0x5F4B, 0xE974, 0x5F4C, 0xC0B1, 0x5F4E, 0xC573, + 0x5F4F, 0xF7D8, 0x5F54, 0xCC74, 0x5F56, 0xCEBD, 0x5F57, 0xB16B, + 0x5F58, 0xD8F4, 0x5F59, 0xB74A, 0x5F5D, 0xC255, 0x5F62, 0xA7CE, + 0x5F64, 0xA7CD, 0x5F65, 0xABDB, 0x5F67, 0xD17B, 0x5F69, 0xB16D, + 0x5F6A, 0xB343, 0x5F6B, 0xB16E, 0x5F6C, 0xB16C, 0x5F6D, 0xB45E, + 0x5F6F, 0xE1C0, 0x5F70, 0xB9FC, 0x5F71, 0xBC76, 0x5F73, 0xC94C, + 0x5F74, 0xC9DF, 0x5F76, 0xCAD5, 0x5F77, 0xA7CF, 0x5F78, 0xCAD4, + 0x5F79, 0xA7D0, 0x5F7C, 0xA9BC, 0x5F7D, 0xCC77, 0x5F7E, 0xCC76, + 0x5F7F, 0xA9BB, 0x5F80, 0xA9B9, 0x5F81, 0xA9BA, 0x5F82, 0xCC75, + 0x5F85, 0xABDD, 0x5F86, 0xCEBE, 0x5F87, 0xABE0, 0x5F88, 0xABDC, + 0x5F89, 0xABE2, 0x5F8A, 0xABDE, 0x5F8B, 0xABDF, 0x5F8C, 0xABE1, + 0x5F90, 0xAE7D, 0x5F91, 0xAE7C, 0x5F92, 0xAE7B, 0x5F96, 0xD54F, + 0x5F97, 0xB16F, 0x5F98, 0xB172, 0x5F99, 0xB170, 0x5F9B, 0xD54E, + 0x5F9C, 0xB175, 0x5F9E, 0xB171, 0x5F9F, 0xD550, 0x5FA0, 0xB174, + 0x5FA1, 0xB173, 0x5FA5, 0xD8F6, 0x5FA6, 0xD8F5, 0x5FA8, 0xB461, + 0x5FA9, 0xB45F, 0x5FAA, 0xB460, 0x5FAB, 0xD8F7, 0x5FAC, 0xB74B, + 0x5FAD, 0xDD64, 0x5FAE, 0xB74C, 0x5FAF, 0xDD63, 0x5FB2, 0xE577, + 0x5FB5, 0xBC78, 0x5FB6, 0xE1C1, 0x5FB7, 0xBC77, 0x5FB9, 0xB9FD, + 0x5FBB, 0xECDE, 0x5FBC, 0xE975, 0x5FBD, 0xC0B2, 0x5FBE, 0xECDD, + 0x5FBF, 0xF240, 0x5FC0, 0xF448, 0x5FC1, 0xF449, 0x5FC3, 0xA4DF, + 0x5FC5, 0xA5B2, 0x5FC9, 0xC97B, 0x5FCC, 0xA7D2, 0x5FCD, 0xA7D4, + 0x5FCF, 0xC9E2, 0x5FD0, 0xCAD8, 0x5FD1, 0xCAD7, 0x5FD2, 0xCAD6, + 0x5FD4, 0xC9E1, 0x5FD5, 0xC9E0, 0x5FD6, 0xA6A4, 0x5FD7, 0xA7D3, + 0x5FD8, 0xA7D1, 0x5FD9, 0xA6A3, 0x5FDD, 0xA9BD, 0x5FDE, 0xCC78, + 0x5FE0, 0xA9BE, 0x5FE1, 0xCADD, 0x5FE3, 0xCADF, 0x5FE4, 0xCADE, + 0x5FE5, 0xCC79, 0x5FE8, 0xCADA, 0x5FEA, 0xA7D8, 0x5FEB, 0xA7D6, + 0x5FED, 0xCAD9, 0x5FEE, 0xCADB, 0x5FEF, 0xCAE1, 0x5FF1, 0xA7D5, + 0x5FF3, 0xCADC, 0x5FF4, 0xCAE5, 0x5FF5, 0xA9C0, 0x5FF7, 0xCAE2, + 0x5FF8, 0xA7D7, 0x5FFA, 0xCAE0, 0x5FFB, 0xCAE3, 0x5FFD, 0xA9BF, + 0x5FFF, 0xA9C1, 0x6000, 0xCAE4, 0x6009, 0xCCAF, 0x600A, 0xCCA2, + 0x600B, 0xCC7E, 0x600C, 0xCCAE, 0x600D, 0xCCA9, 0x600E, 0xABE7, + 0x600F, 0xA9C2, 0x6010, 0xCCAA, 0x6011, 0xCCAD, 0x6012, 0xABE3, + 0x6013, 0xCCAC, 0x6014, 0xA9C3, 0x6015, 0xA9C8, 0x6016, 0xA9C6, + 0x6017, 0xCCA3, 0x6019, 0xCC7C, 0x601A, 0xCCA5, 0x601B, 0xA9CD, + 0x601C, 0xCCB0, 0x601D, 0xABE4, 0x601E, 0xCCA6, 0x6020, 0xABE5, + 0x6021, 0xA9C9, 0x6022, 0xCCA8, 0x6024, 0xCECD, 0x6025, 0xABE6, + 0x6026, 0xCC7B, 0x6027, 0xA9CA, 0x6028, 0xABE8, 0x6029, 0xA9CB, + 0x602A, 0xA9C7, 0x602B, 0xA9CC, 0x602C, 0xCCA7, 0x602D, 0xCC7A, + 0x602E, 0xCCAB, 0x602F, 0xA9C4, 0x6032, 0xCC7D, 0x6033, 0xCCA4, + 0x6034, 0xCCA1, 0x6035, 0xA9C5, 0x6037, 0xCEBF, 0x6039, 0xCEC0, + 0x6040, 0xCECA, 0x6041, 0xD1A1, 0x6042, 0xCECB, 0x6043, 0xABEE, + 0x6044, 0xCECE, 0x6045, 0xCEC4, 0x6046, 0xABED, 0x6047, 0xCEC6, + 0x6049, 0xCEC7, 0x604C, 0xCEC9, 0x604D, 0xABE9, 0x6050, 0xAEA3, + 0x6052, 0xF9DA, 0x6053, 0xCEC5, 0x6054, 0xCEC1, 0x6055, 0xAEA4, + 0x6058, 0xCECF, 0x6059, 0xAE7E, 0x605A, 0xD17D, 0x605B, 0xCEC8, + 0x605D, 0xD17C, 0x605E, 0xCEC3, 0x605F, 0xCECC, 0x6062, 0xABEC, + 0x6063, 0xAEA1, 0x6064, 0xABF2, 0x6065, 0xAEA2, 0x6066, 0xCED0, + 0x6067, 0xD17E, 0x6068, 0xABEB, 0x6069, 0xAEA6, 0x606A, 0xABF1, + 0x606B, 0xABF0, 0x606C, 0xABEF, 0x606D, 0xAEA5, 0x606E, 0xCED1, + 0x606F, 0xAEA7, 0x6070, 0xABEA, 0x6072, 0xCEC2, 0x607F, 0xB176, + 0x6080, 0xD1A4, 0x6081, 0xD1A6, 0x6083, 0xD1A8, 0x6084, 0xAEA8, + 0x6085, 0xAEAE, 0x6086, 0xD553, 0x6087, 0xD1AC, 0x6088, 0xD1A3, + 0x6089, 0xB178, 0x608A, 0xD551, 0x608C, 0xAEAD, 0x608D, 0xAEAB, + 0x608E, 0xD1AE, 0x6090, 0xD552, 0x6092, 0xD1A5, 0x6094, 0xAEAC, + 0x6095, 0xD1A9, 0x6096, 0xAEAF, 0x6097, 0xD1AB, 0x609A, 0xAEAA, + 0x609B, 0xD1AA, 0x609C, 0xD1AD, 0x609D, 0xD1A7, 0x609F, 0xAEA9, + 0x60A0, 0xB179, 0x60A2, 0xD1A2, 0x60A3, 0xB177, 0x60A8, 0xB17A, + 0x60B0, 0xD555, 0x60B1, 0xD55E, 0x60B2, 0xB464, 0x60B4, 0xB17C, + 0x60B5, 0xB1A3, 0x60B6, 0xB465, 0x60B7, 0xD560, 0x60B8, 0xB1AA, + 0x60B9, 0xD8F9, 0x60BA, 0xD556, 0x60BB, 0xB1A2, 0x60BC, 0xB1A5, + 0x60BD, 0xB17E, 0x60BE, 0xD554, 0x60BF, 0xD562, 0x60C0, 0xD565, + 0x60C1, 0xD949, 0x60C3, 0xD563, 0x60C4, 0xD8FD, 0x60C5, 0xB1A1, + 0x60C6, 0xB1A8, 0x60C7, 0xB1AC, 0x60C8, 0xD55D, 0x60C9, 0xD8F8, + 0x60CA, 0xD561, 0x60CB, 0xB17B, 0x60CC, 0xD8FA, 0x60CD, 0xD564, + 0x60CE, 0xD8FC, 0x60CF, 0xD559, 0x60D1, 0xB462, 0x60D3, 0xD557, + 0x60D4, 0xD558, 0x60D5, 0xB1A7, 0x60D8, 0xB1A6, 0x60D9, 0xD55B, + 0x60DA, 0xB1AB, 0x60DB, 0xD55F, 0x60DC, 0xB1A4, 0x60DD, 0xD55C, + 0x60DF, 0xB1A9, 0x60E0, 0xB466, 0x60E1, 0xB463, 0x60E2, 0xD8FB, + 0x60E4, 0xD55A, 0x60E6, 0xB17D, 0x60F0, 0xB46B, 0x60F1, 0xB46F, + 0x60F2, 0xD940, 0x60F3, 0xB751, 0x60F4, 0xB46D, 0x60F5, 0xD944, + 0x60F6, 0xB471, 0x60F7, 0xDD65, 0x60F8, 0xD946, 0x60F9, 0xB753, + 0x60FA, 0xB469, 0x60FB, 0xB46C, 0x60FC, 0xD947, 0x60FE, 0xD948, + 0x60FF, 0xD94E, 0x6100, 0xB473, 0x6101, 0xB754, 0x6103, 0xD94A, + 0x6104, 0xD94F, 0x6105, 0xD943, 0x6106, 0xB75E, 0x6108, 0xB755, + 0x6109, 0xB472, 0x610A, 0xD941, 0x610B, 0xD950, 0x610D, 0xB75D, + 0x610E, 0xB470, 0x610F, 0xB74E, 0x6110, 0xD94D, 0x6112, 0xB474, + 0x6113, 0xD945, 0x6114, 0xD8FE, 0x6115, 0xB46A, 0x6116, 0xD942, + 0x6118, 0xD94B, 0x611A, 0xB74D, 0x611B, 0xB752, 0x611C, 0xB467, + 0x611D, 0xD94C, 0x611F, 0xB750, 0x6123, 0xB468, 0x6127, 0xB75C, + 0x6128, 0xE1C3, 0x6129, 0xDD70, 0x612B, 0xDD68, 0x612C, 0xE1C2, + 0x612E, 0xDD6C, 0x612F, 0xDD6E, 0x6132, 0xDD6B, 0x6134, 0xB75B, + 0x6136, 0xDD6A, 0x6137, 0xB75F, 0x613B, 0xE1D2, 0x613E, 0xB75A, + 0x613F, 0xBA40, 0x6140, 0xDD71, 0x6141, 0xE1C4, 0x6144, 0xB758, + 0x6145, 0xDD69, 0x6146, 0xDD6D, 0x6147, 0xB9FE, 0x6148, 0xB74F, + 0x6149, 0xDD66, 0x614A, 0xDD67, 0x614B, 0xBA41, 0x614C, 0xB757, + 0x614D, 0xB759, 0x614E, 0xB756, 0x614F, 0xDD6F, 0x6152, 0xE1C8, + 0x6153, 0xE1C9, 0x6154, 0xE1CE, 0x6155, 0xBC7D, 0x6156, 0xE1D5, + 0x6158, 0xBA47, 0x615A, 0xBA46, 0x615B, 0xE1D0, 0x615D, 0xBC7C, + 0x615E, 0xE1C5, 0x615F, 0xBA45, 0x6161, 0xE1D4, 0x6162, 0xBA43, + 0x6163, 0xBA44, 0x6165, 0xE1D1, 0x6166, 0xE5AA, 0x6167, 0xBC7A, + 0x6168, 0xB46E, 0x616A, 0xE1D3, 0x616B, 0xBCA3, 0x616C, 0xE1CB, + 0x616E, 0xBC7B, 0x6170, 0xBCA2, 0x6171, 0xE1C6, 0x6172, 0xE1CA, + 0x6173, 0xE1C7, 0x6174, 0xE1CD, 0x6175, 0xBA48, 0x6176, 0xBC79, + 0x6177, 0xBA42, 0x6179, 0xE57A, 0x617A, 0xE1CF, 0x617C, 0xBCA1, + 0x617E, 0xBCA4, 0x6180, 0xE1CC, 0x6182, 0xBC7E, 0x6183, 0xE579, + 0x6189, 0xE57E, 0x618A, 0xBECE, 0x618B, 0xE578, 0x618C, 0xE9A3, + 0x618D, 0xE5A9, 0x618E, 0xBCA8, 0x6190, 0xBCA6, 0x6191, 0xBECC, + 0x6192, 0xE5A6, 0x6193, 0xE5A2, 0x6194, 0xBCAC, 0x6196, 0xE978, + 0x619A, 0xBCAA, 0x619B, 0xE5A1, 0x619D, 0xE976, 0x619F, 0xE5A5, + 0x61A1, 0xE5A8, 0x61A2, 0xE57D, 0x61A4, 0xBCAB, 0x61A7, 0xBCA5, + 0x61A8, 0xE977, 0x61A9, 0xBECD, 0x61AA, 0xE5A7, 0x61AB, 0xBCA7, + 0x61AC, 0xBCA9, 0x61AD, 0xE5A4, 0x61AE, 0xBCAD, 0x61AF, 0xE5A3, + 0x61B0, 0xE57C, 0x61B1, 0xE57B, 0x61B2, 0xBECB, 0x61B3, 0xE5AB, + 0x61B4, 0xE97A, 0x61B5, 0xECE0, 0x61B6, 0xBED0, 0x61B8, 0xE9A2, + 0x61BA, 0xE97E, 0x61BC, 0xECE1, 0x61BE, 0xBED1, 0x61BF, 0xE9A1, + 0x61C1, 0xE97C, 0x61C2, 0xC0B4, 0x61C3, 0xECDF, 0x61C5, 0xE979, + 0x61C6, 0xE97B, 0x61C7, 0xC0B5, 0x61C8, 0xBED3, 0x61C9, 0xC0B3, + 0x61CA, 0xBED2, 0x61CB, 0xC0B7, 0x61CC, 0xE97D, 0x61CD, 0xBECF, + 0x61D6, 0xEFCF, 0x61D8, 0xEFC7, 0x61DE, 0xECE7, 0x61DF, 0xEFC8, + 0x61E0, 0xECE3, 0x61E3, 0xC256, 0x61E4, 0xECE5, 0x61E5, 0xECE4, + 0x61E6, 0xC0B6, 0x61E7, 0xECE2, 0x61E8, 0xECE6, 0x61E9, 0xEFD0, + 0x61EA, 0xEFCC, 0x61EB, 0xEFCE, 0x61ED, 0xEFC9, 0x61EE, 0xEFCA, + 0x61F0, 0xEFCD, 0x61F1, 0xEFCB, 0x61F2, 0xC367, 0x61F5, 0xC36A, + 0x61F6, 0xC369, 0x61F7, 0xC368, 0x61F8, 0xC461, 0x61F9, 0xF44A, + 0x61FA, 0xC462, 0x61FB, 0xF241, 0x61FC, 0xC4DF, 0x61FD, 0xF5CC, + 0x61FE, 0xC4E0, 0x61FF, 0xC574, 0x6200, 0xC5CA, 0x6201, 0xF7D9, + 0x6203, 0xF7DA, 0x6204, 0xF7DB, 0x6207, 0xF9BA, 0x6208, 0xA4E0, + 0x6209, 0xC97C, 0x620A, 0xA5B3, 0x620C, 0xA6A6, 0x620D, 0xA6A7, + 0x620E, 0xA6A5, 0x6210, 0xA6A8, 0x6211, 0xA7DA, 0x6212, 0xA7D9, + 0x6214, 0xCCB1, 0x6215, 0xA9CF, 0x6216, 0xA9CE, 0x6219, 0xD1AF, + 0x621A, 0xB1AD, 0x621B, 0xB1AE, 0x621F, 0xB475, 0x6220, 0xDD72, + 0x6221, 0xB760, 0x6222, 0xB761, 0x6223, 0xDD74, 0x6224, 0xDD76, + 0x6225, 0xDD75, 0x6227, 0xE1D7, 0x6229, 0xE1D6, 0x622A, 0xBA49, + 0x622B, 0xE1D8, 0x622D, 0xE5AC, 0x622E, 0xBCAE, 0x6230, 0xBED4, + 0x6232, 0xC0B8, 0x6233, 0xC257, 0x6234, 0xC0B9, 0x6236, 0xA4E1, + 0x623A, 0xCAE6, 0x623D, 0xCCB2, 0x623E, 0xA9D1, 0x623F, 0xA9D0, + 0x6240, 0xA9D2, 0x6241, 0xABF3, 0x6242, 0xCED2, 0x6243, 0xCED3, + 0x6246, 0xD1B0, 0x6247, 0xAEB0, 0x6248, 0xB1AF, 0x6249, 0xB476, + 0x624A, 0xD951, 0x624B, 0xA4E2, 0x624D, 0xA47E, 0x624E, 0xA4E3, + 0x6250, 0xC97D, 0x6251, 0xA5B7, 0x6252, 0xA5B6, 0x6253, 0xA5B4, + 0x6254, 0xA5B5, 0x6258, 0xA6AB, 0x6259, 0xC9E9, 0x625A, 0xC9EB, + 0x625B, 0xA6AA, 0x625C, 0xC9E3, 0x625E, 0xC9E4, 0x6260, 0xC9EA, + 0x6261, 0xC9E6, 0x6262, 0xC9E8, 0x6263, 0xA6A9, 0x6264, 0xC9E5, + 0x6265, 0xC9EC, 0x6266, 0xC9E7, 0x626D, 0xA7E1, 0x626E, 0xA7EA, + 0x626F, 0xA7E8, 0x6270, 0xCAF0, 0x6271, 0xCAED, 0x6272, 0xCAF5, + 0x6273, 0xA7E6, 0x6274, 0xCAF6, 0x6276, 0xA7DF, 0x6277, 0xCAF3, + 0x6279, 0xA7E5, 0x627A, 0xCAEF, 0x627B, 0xCAEE, 0x627C, 0xA7E3, + 0x627D, 0xCAF4, 0x627E, 0xA7E4, 0x627F, 0xA9D3, 0x6280, 0xA7DE, + 0x6281, 0xCAF1, 0x6283, 0xCAE7, 0x6284, 0xA7DB, 0x6286, 0xA7EE, + 0x6287, 0xCAEC, 0x6288, 0xCAF2, 0x6289, 0xA7E0, 0x628A, 0xA7E2, + 0x628C, 0xCAE8, 0x628E, 0xCAE9, 0x628F, 0xCAEA, 0x6291, 0xA7ED, + 0x6292, 0xA7E7, 0x6293, 0xA7EC, 0x6294, 0xCAEB, 0x6295, 0xA7EB, + 0x6296, 0xA7DD, 0x6297, 0xA7DC, 0x6298, 0xA7E9, 0x62A8, 0xA9E1, + 0x62A9, 0xCCBE, 0x62AA, 0xCCB7, 0x62AB, 0xA9DC, 0x62AC, 0xA9EF, + 0x62AD, 0xCCB3, 0x62AE, 0xCCBA, 0x62AF, 0xCCBC, 0x62B0, 0xCCBF, + 0x62B1, 0xA9EA, 0x62B3, 0xCCBB, 0x62B4, 0xCCB4, 0x62B5, 0xA9E8, + 0x62B6, 0xCCB8, 0x62B8, 0xCCC0, 0x62B9, 0xA9D9, 0x62BB, 0xCCBD, + 0x62BC, 0xA9E3, 0x62BD, 0xA9E2, 0x62BE, 0xCCB6, 0x62BF, 0xA9D7, + 0x62C2, 0xA9D8, 0x62C4, 0xA9D6, 0x62C6, 0xA9EE, 0x62C7, 0xA9E6, + 0x62C8, 0xA9E0, 0x62C9, 0xA9D4, 0x62CA, 0xCCB9, 0x62CB, 0xA9DF, + 0x62CC, 0xA9D5, 0x62CD, 0xA9E7, 0x62CE, 0xA9F0, 0x62CF, 0xCED4, + 0x62D0, 0xA9E4, 0x62D1, 0xCCB5, 0x62D2, 0xA9DA, 0x62D3, 0xA9DD, + 0x62D4, 0xA9DE, 0x62D6, 0xA9EC, 0x62D7, 0xA9ED, 0x62D8, 0xA9EB, + 0x62D9, 0xA9E5, 0x62DA, 0xA9E9, 0x62DB, 0xA9DB, 0x62DC, 0xABF4, + 0x62EB, 0xCEDA, 0x62EC, 0xAC41, 0x62ED, 0xABF8, 0x62EE, 0xABFA, + 0x62EF, 0xAC40, 0x62F0, 0xCEE6, 0x62F1, 0xABFD, 0x62F2, 0xD1B1, + 0x62F3, 0xAEB1, 0x62F4, 0xAC43, 0x62F5, 0xCED7, 0x62F6, 0xCEDF, + 0x62F7, 0xABFE, 0x62F8, 0xCEDE, 0x62F9, 0xCEDB, 0x62FA, 0xCEE3, + 0x62FB, 0xCEE5, 0x62FC, 0xABF7, 0x62FD, 0xABFB, 0x62FE, 0xAC42, + 0x62FF, 0xAEB3, 0x6300, 0xCEE0, 0x6301, 0xABF9, 0x6302, 0xAC45, + 0x6303, 0xCED9, 0x6307, 0xABFC, 0x6308, 0xAEB2, 0x6309, 0xABF6, + 0x630B, 0xCED6, 0x630C, 0xCEDD, 0x630D, 0xCED5, 0x630E, 0xCED8, + 0x630F, 0xCEDC, 0x6310, 0xD1B2, 0x6311, 0xAC44, 0x6313, 0xCEE1, + 0x6314, 0xCEE2, 0x6315, 0xCEE4, 0x6316, 0xABF5, 0x6328, 0xAEC1, + 0x6329, 0xD1BE, 0x632A, 0xAEBF, 0x632B, 0xAEC0, 0x632C, 0xD1B4, + 0x632D, 0xD1C4, 0x632F, 0xAEB6, 0x6332, 0xD566, 0x6333, 0xD1C6, + 0x6334, 0xD1C0, 0x6336, 0xD1B7, 0x6338, 0xD1C9, 0x6339, 0xD1BA, + 0x633A, 0xAEBC, 0x633B, 0xD57D, 0x633C, 0xD1BD, 0x633D, 0xAEBE, + 0x633E, 0xAEB5, 0x6340, 0xD1CB, 0x6341, 0xD1BF, 0x6342, 0xAEB8, + 0x6343, 0xD1B8, 0x6344, 0xD1B5, 0x6345, 0xD1B6, 0x6346, 0xAEB9, + 0x6347, 0xD1C5, 0x6348, 0xD1CC, 0x6349, 0xAEBB, 0x634A, 0xD1BC, + 0x634B, 0xD1BB, 0x634C, 0xAEC3, 0x634D, 0xAEC2, 0x634E, 0xAEB4, + 0x634F, 0xAEBA, 0x6350, 0xAEBD, 0x6351, 0xD1C8, 0x6354, 0xD1C2, + 0x6355, 0xAEB7, 0x6356, 0xD1B3, 0x6357, 0xD1CA, 0x6358, 0xD1C1, + 0x6359, 0xD1C3, 0x635A, 0xD1C7, 0x6365, 0xD567, 0x6367, 0xB1B7, + 0x6368, 0xB1CB, 0x6369, 0xB1CA, 0x636B, 0xB1BF, 0x636D, 0xD579, + 0x636E, 0xD575, 0x636F, 0xD572, 0x6370, 0xD5A6, 0x6371, 0xB1BA, + 0x6372, 0xB1B2, 0x6375, 0xD577, 0x6376, 0xB4A8, 0x6377, 0xB1B6, + 0x6378, 0xD5A1, 0x637A, 0xB1CC, 0x637B, 0xB1C9, 0x637C, 0xD57B, + 0x637D, 0xD56A, 0x6380, 0xB1C8, 0x6381, 0xD5A3, 0x6382, 0xD569, + 0x6383, 0xB1BD, 0x6384, 0xB1C1, 0x6385, 0xD5A2, 0x6387, 0xD573, + 0x6388, 0xB1C2, 0x6389, 0xB1BC, 0x638A, 0xD568, 0x638C, 0xB478, + 0x638D, 0xD5A5, 0x638E, 0xD571, 0x638F, 0xB1C7, 0x6390, 0xD574, + 0x6391, 0xD5A4, 0x6392, 0xB1C6, 0x6394, 0xD952, 0x6396, 0xB1B3, + 0x6397, 0xD56F, 0x6398, 0xB1B8, 0x6399, 0xB1C3, 0x639B, 0xB1BE, + 0x639C, 0xD578, 0x639D, 0xD56E, 0x639E, 0xD56C, 0x639F, 0xD57E, + 0x63A0, 0xB1B0, 0x63A1, 0xB1C4, 0x63A2, 0xB1B4, 0x63A3, 0xB477, + 0x63A4, 0xD57C, 0x63A5, 0xB1B5, 0x63A7, 0xB1B1, 0x63A8, 0xB1C0, + 0x63A9, 0xB1BB, 0x63AA, 0xB1B9, 0x63AB, 0xD570, 0x63AC, 0xB1C5, + 0x63AD, 0xD56D, 0x63AE, 0xD57A, 0x63AF, 0xD576, 0x63B0, 0xD954, + 0x63B1, 0xD953, 0x63BD, 0xD56B, 0x63BE, 0xD964, 0x63C0, 0xB47A, + 0x63C2, 0xD96A, 0x63C3, 0xD959, 0x63C4, 0xD967, 0x63C5, 0xDD77, + 0x63C6, 0xB47D, 0x63C7, 0xD96B, 0x63C8, 0xD96E, 0x63C9, 0xB47C, + 0x63CA, 0xD95C, 0x63CB, 0xD96D, 0x63CC, 0xD96C, 0x63CD, 0xB47E, + 0x63CE, 0xD955, 0x63CF, 0xB479, 0x63D0, 0xB4A3, 0x63D2, 0xB4A1, + 0x63D3, 0xD969, 0x63D5, 0xD95F, 0x63D6, 0xB4A5, 0x63D7, 0xD970, + 0x63D8, 0xD968, 0x63D9, 0xD971, 0x63DA, 0xB4AD, 0x63DB, 0xB4AB, + 0x63DC, 0xD966, 0x63DD, 0xD965, 0x63DF, 0xD963, 0x63E0, 0xD95D, + 0x63E1, 0xB4A4, 0x63E3, 0xB4A2, 0x63E4, 0xD1B9, 0x63E5, 0xD956, + 0x63E7, 0xDDB7, 0x63E8, 0xD957, 0x63E9, 0xB47B, 0x63EA, 0xB4AA, + 0x63EB, 0xDD79, 0x63ED, 0xB4A6, 0x63EE, 0xB4A7, 0x63EF, 0xD958, + 0x63F0, 0xD96F, 0x63F1, 0xDD78, 0x63F2, 0xD960, 0x63F3, 0xD95B, + 0x63F4, 0xB4A9, 0x63F5, 0xD961, 0x63F6, 0xD95E, 0x63F9, 0xB4AE, + 0x6406, 0xB770, 0x6409, 0xDD7C, 0x640A, 0xDDB1, 0x640B, 0xDDB6, + 0x640C, 0xDDAA, 0x640D, 0xB76C, 0x640E, 0xDDBB, 0x640F, 0xB769, + 0x6410, 0xDD7A, 0x6412, 0xDD7B, 0x6413, 0xB762, 0x6414, 0xB76B, + 0x6415, 0xDDA4, 0x6416, 0xB76E, 0x6417, 0xB76F, 0x6418, 0xDDA5, + 0x641A, 0xDDB2, 0x641B, 0xDDB8, 0x641C, 0xB76A, 0x641E, 0xB764, + 0x641F, 0xDDA3, 0x6420, 0xDD7D, 0x6421, 0xDDBA, 0x6422, 0xDDA8, + 0x6423, 0xDDA9, 0x6424, 0xDD7E, 0x6425, 0xDDB4, 0x6426, 0xDDAB, + 0x6427, 0xDDB5, 0x6428, 0xDDAD, 0x642A, 0xB765, 0x642B, 0xE1D9, + 0x642C, 0xB768, 0x642D, 0xB766, 0x642E, 0xDDB9, 0x642F, 0xDDB0, + 0x6430, 0xDDAC, 0x6433, 0xDDA1, 0x6434, 0xBA53, 0x6435, 0xDDAF, + 0x6436, 0xB76D, 0x6437, 0xDDA7, 0x6439, 0xDDA6, 0x643D, 0xB767, + 0x643E, 0xB763, 0x643F, 0xE1EE, 0x6440, 0xDDB3, 0x6441, 0xDDAE, + 0x6443, 0xDDA2, 0x644B, 0xE1E9, 0x644D, 0xE1DA, 0x644E, 0xE1E5, + 0x6450, 0xE1EC, 0x6451, 0xBA51, 0x6452, 0xB4AC, 0x6453, 0xE1EA, + 0x6454, 0xBA4C, 0x6458, 0xBA4B, 0x6459, 0xE1F1, 0x645B, 0xE1DB, + 0x645C, 0xE1E8, 0x645D, 0xE1DC, 0x645E, 0xE1E7, 0x645F, 0xBA4F, + 0x6460, 0xE1EB, 0x6461, 0xD962, 0x6465, 0xE1F2, 0x6466, 0xE1E3, + 0x6467, 0xBA52, 0x6468, 0xE5BA, 0x6469, 0xBCAF, 0x646B, 0xE1F0, + 0x646C, 0xE1EF, 0x646D, 0xBA54, 0x646E, 0xE5AD, 0x646F, 0xBCB0, + 0x6470, 0xE5AE, 0x6472, 0xE1DF, 0x6473, 0xE1E0, 0x6474, 0xE1DD, + 0x6475, 0xE1E2, 0x6476, 0xE1DE, 0x6477, 0xE1F3, 0x6478, 0xBA4E, + 0x6479, 0xBCB1, 0x647A, 0xBA50, 0x647B, 0xBA55, 0x647D, 0xE1E1, + 0x647F, 0xE1ED, 0x6482, 0xE1E6, 0x6485, 0xE5B1, 0x6487, 0xBA4A, + 0x6488, 0xBCB4, 0x6489, 0xE9AA, 0x648A, 0xE5B6, 0x648B, 0xE5B5, + 0x648C, 0xE5B7, 0x648F, 0xE5B4, 0x6490, 0xBCB5, 0x6492, 0xBCBB, + 0x6493, 0xBCB8, 0x6495, 0xBCB9, 0x6496, 0xE5AF, 0x6497, 0xE5B2, + 0x6498, 0xE5BC, 0x6499, 0xBCC1, 0x649A, 0xBCBF, 0x649C, 0xE5B3, + 0x649D, 0xD95A, 0x649E, 0xBCB2, 0x649F, 0xE5B9, 0x64A0, 0xE5B0, + 0x64A2, 0xBCC2, 0x64A3, 0xE5B8, 0x64A4, 0xBA4D, 0x64A5, 0xBCB7, + 0x64A6, 0xE1E4, 0x64A9, 0xBCBA, 0x64AB, 0xBCBE, 0x64AC, 0xBCC0, + 0x64AD, 0xBCBD, 0x64AE, 0xBCBC, 0x64B0, 0xBCB6, 0x64B1, 0xE5BB, + 0x64B2, 0xBCB3, 0x64B3, 0xBCC3, 0x64BB, 0xBED8, 0x64BC, 0xBED9, + 0x64BD, 0xE9A9, 0x64BE, 0xBEE2, 0x64BF, 0xBEDF, 0x64C1, 0xBED6, + 0x64C2, 0xBEDD, 0x64C3, 0xE9AB, 0x64C4, 0xBEDB, 0x64C5, 0xBED5, + 0x64C7, 0xBEDC, 0x64C9, 0xE9A8, 0x64CA, 0xC0BB, 0x64CB, 0xBED7, + 0x64CD, 0xBEDE, 0x64CE, 0xC0BA, 0x64CF, 0xE9A7, 0x64D0, 0xE9A6, + 0x64D2, 0xBEE0, 0x64D4, 0xBEE1, 0x64D6, 0xE9A5, 0x64D7, 0xE9A4, + 0x64D8, 0xC0BC, 0x64D9, 0xE9AE, 0x64DA, 0xBEDA, 0x64DB, 0xE9AC, + 0x64E0, 0xC0BD, 0x64E2, 0xC0C2, 0x64E3, 0xECEA, 0x64E4, 0xECEC, + 0x64E6, 0xC0BF, 0x64E8, 0xECED, 0x64E9, 0xECE9, 0x64EB, 0xECEB, + 0x64EC, 0xC0C0, 0x64ED, 0xC0C3, 0x64EF, 0xECE8, 0x64F0, 0xC0BE, + 0x64F1, 0xC0C1, 0x64F2, 0xC259, 0x64F3, 0xE9AD, 0x64F4, 0xC258, + 0x64F7, 0xC25E, 0x64F8, 0xEFD4, 0x64FA, 0xC25C, 0x64FB, 0xC25D, + 0x64FC, 0xEFD7, 0x64FD, 0xEFD3, 0x64FE, 0xC25A, 0x64FF, 0xEFD1, + 0x6500, 0xC36B, 0x6501, 0xEFD5, 0x6503, 0xEFD6, 0x6504, 0xEFD2, + 0x6506, 0xC25B, 0x6507, 0xF242, 0x6509, 0xF245, 0x650C, 0xF246, + 0x650D, 0xF244, 0x650E, 0xF247, 0x650F, 0xC36C, 0x6510, 0xF243, + 0x6513, 0xF44E, 0x6514, 0xC464, 0x6515, 0xF44D, 0x6516, 0xF44C, + 0x6517, 0xF44B, 0x6518, 0xC463, 0x6519, 0xC465, 0x651B, 0xF5CD, + 0x651C, 0xC4E2, 0x651D, 0xC4E1, 0x6520, 0xF6E1, 0x6521, 0xF6E0, + 0x6522, 0xF6E3, 0x6523, 0xC5CB, 0x6524, 0xC575, 0x6525, 0xF7DD, + 0x6526, 0xF6E2, 0x6529, 0xF7DC, 0x652A, 0xC5CD, 0x652B, 0xC5CC, + 0x652C, 0xC5F3, 0x652D, 0xF8A9, 0x652E, 0xF8EF, 0x652F, 0xA4E4, + 0x6532, 0xD972, 0x6533, 0xE9AF, 0x6536, 0xA6AC, 0x6537, 0xCAF7, + 0x6538, 0xA7F1, 0x6539, 0xA7EF, 0x653B, 0xA7F0, 0x653D, 0xCCC1, + 0x653E, 0xA9F1, 0x653F, 0xAC46, 0x6541, 0xCEE7, 0x6543, 0xCEE8, + 0x6545, 0xAC47, 0x6546, 0xD1CE, 0x6548, 0xAEC4, 0x6549, 0xAEC5, + 0x654A, 0xD1CD, 0x654F, 0xB1D3, 0x6551, 0xB1CF, 0x6553, 0xD5A7, + 0x6554, 0xB1D6, 0x6555, 0xB1D5, 0x6556, 0xB1CE, 0x6557, 0xB1D1, + 0x6558, 0xB1D4, 0x6559, 0xB1D0, 0x655C, 0xD976, 0x655D, 0xB1CD, + 0x655E, 0xB4AF, 0x6562, 0xB4B1, 0x6563, 0xB4B2, 0x6564, 0xD975, + 0x6565, 0xD978, 0x6566, 0xB4B0, 0x6567, 0xD973, 0x6568, 0xD977, + 0x656A, 0xD974, 0x656C, 0xB771, 0x656F, 0xDDBC, 0x6572, 0xBA56, + 0x6573, 0xE1F4, 0x6574, 0xBEE3, 0x6575, 0xBCC4, 0x6576, 0xE5BD, + 0x6577, 0xBCC5, 0x6578, 0xBCC6, 0x6579, 0xE5BF, 0x657A, 0xE5BE, + 0x657B, 0xE5C0, 0x657C, 0xE9B1, 0x657F, 0xE9B0, 0x6580, 0xECEF, + 0x6581, 0xECEE, 0x6582, 0xC0C4, 0x6583, 0xC0C5, 0x6584, 0xF248, + 0x6587, 0xA4E5, 0x658C, 0xD979, 0x6590, 0xB4B4, 0x6591, 0xB4B3, + 0x6592, 0xDDBD, 0x6594, 0xEFD8, 0x6595, 0xC4E3, 0x6596, 0xF7DE, + 0x6597, 0xA4E6, 0x6599, 0xAEC6, 0x659B, 0xB1D8, 0x659C, 0xB1D7, + 0x659D, 0xD97A, 0x659E, 0xD97B, 0x659F, 0xB772, 0x65A0, 0xE1F5, + 0x65A1, 0xBA57, 0x65A2, 0xE9B2, 0x65A4, 0xA4E7, 0x65A5, 0xA5B8, + 0x65A7, 0xA9F2, 0x65A8, 0xCCC2, 0x65AA, 0xCEE9, 0x65AB, 0xAC48, + 0x65AC, 0xB1D9, 0x65AE, 0xD97C, 0x65AF, 0xB4B5, 0x65B0, 0xB773, + 0x65B2, 0xE5C1, 0x65B3, 0xE5C2, 0x65B6, 0xECF0, 0x65B7, 0xC25F, + 0x65B8, 0xF8F0, 0x65B9, 0xA4E8, 0x65BB, 0xCCC3, 0x65BC, 0xA9F3, + 0x65BD, 0xAC49, 0x65BF, 0xCEEA, 0x65C1, 0xAEC7, 0x65C2, 0xD1D2, + 0x65C3, 0xD1D0, 0x65C4, 0xD1D1, 0x65C5, 0xAEC8, 0x65C6, 0xD1CF, + 0x65CB, 0xB1DB, 0x65CC, 0xB1DC, 0x65CD, 0xD5A8, 0x65CE, 0xB1DD, + 0x65CF, 0xB1DA, 0x65D0, 0xD97D, 0x65D2, 0xD97E, 0x65D3, 0xDDBE, + 0x65D6, 0xBA59, 0x65D7, 0xBA58, 0x65DA, 0xECF1, 0x65DB, 0xEFD9, + 0x65DD, 0xF24A, 0x65DE, 0xF249, 0x65DF, 0xF44F, 0x65E1, 0xC95E, + 0x65E2, 0xAC4A, 0x65E5, 0xA4E9, 0x65E6, 0xA5B9, 0x65E8, 0xA6AE, + 0x65E9, 0xA6AD, 0x65EC, 0xA6AF, 0x65ED, 0xA6B0, 0x65EE, 0xC9EE, + 0x65EF, 0xC9ED, 0x65F0, 0xCAF8, 0x65F1, 0xA7F2, 0x65F2, 0xCAFB, + 0x65F3, 0xCAFA, 0x65F4, 0xCAF9, 0x65F5, 0xCAFC, 0x65FA, 0xA9F4, + 0x65FB, 0xCCC9, 0x65FC, 0xCCC5, 0x65FD, 0xCCCE, 0x6600, 0xA9FB, + 0x6602, 0xA9F9, 0x6603, 0xCCCA, 0x6604, 0xCCC6, 0x6605, 0xCCCD, + 0x6606, 0xA9F8, 0x6607, 0xAA40, 0x6608, 0xCCC8, 0x6609, 0xCCC4, + 0x660A, 0xA9FE, 0x660B, 0xCCCB, 0x660C, 0xA9F7, 0x660D, 0xCCCC, + 0x660E, 0xA9FA, 0x660F, 0xA9FC, 0x6610, 0xCCD0, 0x6611, 0xCCCF, + 0x6612, 0xCCC7, 0x6613, 0xA9F6, 0x6614, 0xA9F5, 0x6615, 0xA9FD, + 0x661C, 0xCEEF, 0x661D, 0xCEF5, 0x661F, 0xAC50, 0x6620, 0xAC4D, + 0x6621, 0xCEEC, 0x6622, 0xCEF1, 0x6624, 0xAC53, 0x6625, 0xAC4B, + 0x6626, 0xCEF0, 0x6627, 0xAC4E, 0x6628, 0xAC51, 0x662B, 0xCEF3, + 0x662D, 0xAC4C, 0x662E, 0xCEF8, 0x662F, 0xAC4F, 0x6631, 0xAC52, + 0x6632, 0xCEED, 0x6633, 0xCEF2, 0x6634, 0xCEF6, 0x6635, 0xCEEE, + 0x6636, 0xCEEB, 0x6639, 0xCEF7, 0x663A, 0xCEF4, 0x6641, 0xAED0, + 0x6642, 0xAEC9, 0x6643, 0xAECC, 0x6645, 0xAECF, 0x6647, 0xD1D5, + 0x6649, 0xAECA, 0x664A, 0xD1D3, 0x664C, 0xAECE, 0x664F, 0xAECB, + 0x6651, 0xD1D6, 0x6652, 0xAECD, 0x6659, 0xD5AC, 0x665A, 0xB1DF, + 0x665B, 0xD5AB, 0x665C, 0xD5AD, 0x665D, 0xB1DE, 0x665E, 0xB1E3, + 0x665F, 0xD1D4, 0x6661, 0xD5AA, 0x6662, 0xD5AE, 0x6664, 0xB1E0, + 0x6665, 0xD5A9, 0x6666, 0xB1E2, 0x6668, 0xB1E1, 0x666A, 0xD9A7, + 0x666C, 0xD9A2, 0x666E, 0xB4B6, 0x666F, 0xB4BA, 0x6670, 0xB4B7, + 0x6671, 0xD9A5, 0x6672, 0xD9A8, 0x6674, 0xB4B8, 0x6676, 0xB4B9, + 0x6677, 0xB4BE, 0x6678, 0xDDC7, 0x6679, 0xD9A6, 0x667A, 0xB4BC, + 0x667B, 0xD9A3, 0x667C, 0xD9A1, 0x667E, 0xB4BD, 0x6680, 0xD9A4, + 0x6684, 0xB779, 0x6686, 0xDDBF, 0x6687, 0xB776, 0x6688, 0xB777, + 0x6689, 0xB775, 0x668A, 0xDDC4, 0x668B, 0xDDC3, 0x668C, 0xDDC0, + 0x668D, 0xB77B, 0x6690, 0xDDC2, 0x6691, 0xB4BB, 0x6694, 0xDDC6, + 0x6695, 0xDDC1, 0x6696, 0xB778, 0x6697, 0xB774, 0x6698, 0xB77A, + 0x6699, 0xDDC5, 0x669D, 0xBA5C, 0x669F, 0xE1F8, 0x66A0, 0xE1F7, + 0x66A1, 0xE1F6, 0x66A2, 0xBA5A, 0x66A8, 0xBA5B, 0x66A9, 0xE5C5, + 0x66AA, 0xE5C8, 0x66AB, 0xBCC8, 0x66AE, 0xBCC7, 0x66AF, 0xE5C9, + 0x66B0, 0xE5C4, 0x66B1, 0xBCCA, 0x66B2, 0xE5C6, 0x66B4, 0xBCC9, + 0x66B5, 0xE5C3, 0x66B7, 0xE5C7, 0x66B8, 0xBEE9, 0x66B9, 0xBEE6, + 0x66BA, 0xE9BB, 0x66BB, 0xE9BA, 0x66BD, 0xE9B9, 0x66BE, 0xE9B4, + 0x66C0, 0xE9B5, 0x66C4, 0xBEE7, 0x66C6, 0xBEE4, 0x66C7, 0xBEE8, + 0x66C8, 0xE9B3, 0x66C9, 0xBEE5, 0x66CA, 0xE9B6, 0x66CB, 0xE9B7, + 0x66CC, 0xE9BC, 0x66CF, 0xE9B8, 0x66D2, 0xECF2, 0x66D6, 0xC0C7, + 0x66D8, 0xEFDC, 0x66D9, 0xC0C6, 0x66DA, 0xEFDA, 0x66DB, 0xEFDB, + 0x66DC, 0xC260, 0x66DD, 0xC36E, 0x66DE, 0xF24B, 0x66E0, 0xC36D, + 0x66E3, 0xF451, 0x66E4, 0xF452, 0x66E6, 0xC466, 0x66E8, 0xF450, + 0x66E9, 0xC4E4, 0x66EB, 0xF7DF, 0x66EC, 0xC5CE, 0x66ED, 0xF8AA, + 0x66EE, 0xF8AB, 0x66F0, 0xA4EA, 0x66F2, 0xA6B1, 0x66F3, 0xA6B2, + 0x66F4, 0xA7F3, 0x66F6, 0xCCD1, 0x66F7, 0xAC54, 0x66F8, 0xAED1, + 0x66F9, 0xB1E4, 0x66FC, 0xB0D2, 0x66FE, 0xB4BF, 0x66FF, 0xB4C0, + 0x6700, 0xB3CC, 0x6701, 0xD9A9, 0x6703, 0xB77C, 0x6704, 0xE1FA, + 0x6705, 0xE1F9, 0x6708, 0xA4EB, 0x6709, 0xA6B3, 0x670A, 0xCCD2, + 0x670B, 0xAA42, 0x670D, 0xAA41, 0x670F, 0xCEF9, 0x6710, 0xCEFA, + 0x6712, 0xD1D7, 0x6713, 0xD1D8, 0x6714, 0xAED2, 0x6715, 0xAED3, + 0x6717, 0xAED4, 0x6718, 0xD5AF, 0x671B, 0xB1E6, 0x671D, 0xB4C2, + 0x671F, 0xB4C1, 0x6720, 0xDDC8, 0x6721, 0xDF7A, 0x6722, 0xE1FB, + 0x6723, 0xE9BD, 0x6726, 0xC261, 0x6727, 0xC467, 0x6728, 0xA4EC, + 0x672A, 0xA5BC, 0x672B, 0xA5BD, 0x672C, 0xA5BB, 0x672D, 0xA5BE, + 0x672E, 0xA5BA, 0x6731, 0xA6B6, 0x6733, 0xC9F6, 0x6734, 0xA6B5, + 0x6735, 0xA6B7, 0x6738, 0xC9F1, 0x6739, 0xC9F0, 0x673A, 0xC9F3, + 0x673B, 0xC9F2, 0x673C, 0xC9F5, 0x673D, 0xA6B4, 0x673E, 0xC9EF, + 0x673F, 0xC9F4, 0x6745, 0xCAFD, 0x6746, 0xA7FD, 0x6747, 0xCAFE, + 0x6748, 0xCB43, 0x6749, 0xA7FC, 0x674B, 0xCB47, 0x674C, 0xCB42, + 0x674D, 0xCB45, 0x674E, 0xA7F5, 0x674F, 0xA7F6, 0x6750, 0xA7F7, + 0x6751, 0xA7F8, 0x6753, 0xA840, 0x6755, 0xCB41, 0x6756, 0xA7FA, + 0x6757, 0xA841, 0x6759, 0xCB40, 0x675A, 0xCB46, 0x675C, 0xA7F9, + 0x675D, 0xCB44, 0x675E, 0xA7FB, 0x675F, 0xA7F4, 0x6760, 0xA7FE, + 0x676A, 0xAA57, 0x676C, 0xCCD4, 0x676D, 0xAA43, 0x676F, 0xAA4D, + 0x6770, 0xAA4E, 0x6771, 0xAA46, 0x6772, 0xAA58, 0x6773, 0xAA48, + 0x6774, 0xCCDC, 0x6775, 0xAA53, 0x6776, 0xCCD7, 0x6777, 0xAA49, + 0x6778, 0xCCE6, 0x6779, 0xCCE7, 0x677A, 0xCCDF, 0x677B, 0xCCD8, + 0x677C, 0xAA56, 0x677D, 0xCCE4, 0x677E, 0xAA51, 0x677F, 0xAA4F, + 0x6781, 0xCCE5, 0x6783, 0xCCE3, 0x6784, 0xCCDB, 0x6785, 0xCCD3, + 0x6786, 0xCCDA, 0x6787, 0xAA4A, 0x6789, 0xAA50, 0x678B, 0xAA44, + 0x678C, 0xCCDE, 0x678D, 0xCCDD, 0x678E, 0xCCD5, 0x6790, 0xAA52, + 0x6791, 0xCCE1, 0x6792, 0xCCD6, 0x6793, 0xAA55, 0x6794, 0xCCE8, + 0x6795, 0xAA45, 0x6797, 0xAA4C, 0x6798, 0xCCD9, 0x6799, 0xCCE2, + 0x679A, 0xAA54, 0x679C, 0xAA47, 0x679D, 0xAA4B, 0x679F, 0xCCE0, + 0x67AE, 0xCF5B, 0x67AF, 0xAC5C, 0x67B0, 0xAC69, 0x67B2, 0xCF56, + 0x67B3, 0xCF4C, 0x67B4, 0xAC62, 0x67B5, 0xCF4A, 0x67B6, 0xAC5B, + 0x67B7, 0xCF45, 0x67B8, 0xAC65, 0x67B9, 0xCF52, 0x67BA, 0xCEFE, + 0x67BB, 0xCF41, 0x67C0, 0xCF44, 0x67C1, 0xCEFB, 0x67C2, 0xCF51, + 0x67C3, 0xCF61, 0x67C4, 0xAC60, 0x67C5, 0xCF46, 0x67C6, 0xCF58, + 0x67C8, 0xCEFD, 0x67C9, 0xCF5F, 0x67CA, 0xCF60, 0x67CB, 0xCF63, + 0x67CC, 0xCF5A, 0x67CD, 0xCF4B, 0x67CE, 0xCF53, 0x67CF, 0xAC66, + 0x67D0, 0xAC59, 0x67D1, 0xAC61, 0x67D2, 0xAC6D, 0x67D3, 0xAC56, + 0x67D4, 0xAC58, 0x67D8, 0xCF43, 0x67D9, 0xAC6A, 0x67DA, 0xAC63, + 0x67DB, 0xCF5D, 0x67DC, 0xCF40, 0x67DD, 0xAC6C, 0x67DE, 0xAC67, + 0x67DF, 0xCF49, 0x67E2, 0xAC6B, 0x67E3, 0xCF50, 0x67E4, 0xCF48, + 0x67E5, 0xAC64, 0x67E6, 0xCF5C, 0x67E7, 0xCF54, 0x67E9, 0xAC5E, + 0x67EA, 0xCF62, 0x67EB, 0xCF47, 0x67EC, 0xAC5A, 0x67ED, 0xCF59, + 0x67EE, 0xCF4F, 0x67EF, 0xAC5F, 0x67F0, 0xCF55, 0x67F1, 0xAC57, + 0x67F2, 0xCEFC, 0x67F3, 0xAC68, 0x67F4, 0xAEE3, 0x67F5, 0xAC5D, + 0x67F6, 0xCF4E, 0x67F7, 0xCF4D, 0x67F8, 0xCF42, 0x67FA, 0xCF5E, + 0x67FC, 0xCF57, 0x67FF, 0xAC55, 0x6812, 0xD1EC, 0x6813, 0xAEEA, + 0x6814, 0xD1ED, 0x6816, 0xD1E1, 0x6817, 0xAEDF, 0x6818, 0xAEEB, + 0x681A, 0xD1DA, 0x681C, 0xD1E3, 0x681D, 0xD1EB, 0x681F, 0xD1D9, + 0x6820, 0xD1F4, 0x6821, 0xAED5, 0x6825, 0xD1F3, 0x6826, 0xD1EE, + 0x6828, 0xD1EF, 0x6829, 0xAEDD, 0x682A, 0xAEE8, 0x682B, 0xD1E5, + 0x682D, 0xD1E6, 0x682E, 0xD1F0, 0x682F, 0xD1E7, 0x6831, 0xD1E2, + 0x6832, 0xD1DC, 0x6833, 0xD1DD, 0x6834, 0xD1EA, 0x6835, 0xD1E4, + 0x6838, 0xAED6, 0x6839, 0xAEDA, 0x683A, 0xD1F2, 0x683B, 0xD1DE, + 0x683C, 0xAEE6, 0x683D, 0xAEE2, 0x6840, 0xAEE5, 0x6841, 0xAEEC, + 0x6842, 0xAEDB, 0x6843, 0xAEE7, 0x6844, 0xD1E9, 0x6845, 0xAEE9, + 0x6846, 0xAED8, 0x6848, 0xAED7, 0x6849, 0xD1DB, 0x684B, 0xD1DF, + 0x684C, 0xAEE0, 0x684D, 0xD1F1, 0x684E, 0xD1E8, 0x684F, 0xD1E0, + 0x6850, 0xAEE4, 0x6851, 0xAEE1, 0x6853, 0xAED9, 0x6854, 0xAEDC, + 0x686B, 0xD5C4, 0x686D, 0xD5B4, 0x686E, 0xD5B5, 0x686F, 0xD5B9, + 0x6871, 0xD5C8, 0x6872, 0xD5C5, 0x6874, 0xD5BE, 0x6875, 0xD5BD, + 0x6876, 0xB1ED, 0x6877, 0xD5C1, 0x6878, 0xD5D0, 0x6879, 0xD5B0, + 0x687B, 0xD5D1, 0x687C, 0xD5C3, 0x687D, 0xD5D5, 0x687E, 0xD5C9, + 0x687F, 0xB1EC, 0x6880, 0xD5C7, 0x6881, 0xB1E7, 0x6882, 0xB1FC, + 0x6883, 0xB1F2, 0x6885, 0xB1F6, 0x6886, 0xB1F5, 0x6887, 0xD5B1, + 0x6889, 0xD5CE, 0x688A, 0xD5D4, 0x688B, 0xD5CC, 0x688C, 0xD5D3, + 0x688F, 0xD5C0, 0x6890, 0xD5B2, 0x6891, 0xD5D2, 0x6892, 0xD5C2, + 0x6893, 0xB1EA, 0x6894, 0xB1F7, 0x6896, 0xD5CB, 0x6897, 0xB1F0, + 0x689B, 0xD5CA, 0x689C, 0xD5B3, 0x689D, 0xB1F8, 0x689F, 0xB1FA, + 0x68A0, 0xD5CD, 0x68A1, 0xB1FB, 0x68A2, 0xB1E9, 0x68A3, 0xD5BA, + 0x68A4, 0xD5CF, 0x68A7, 0xB1EF, 0x68A8, 0xB1F9, 0x68A9, 0xD5BC, + 0x68AA, 0xD5C6, 0x68AB, 0xD5B7, 0x68AC, 0xD5BB, 0x68AD, 0xB1F4, + 0x68AE, 0xD5B6, 0x68AF, 0xB1E8, 0x68B0, 0xB1F1, 0x68B1, 0xB1EE, + 0x68B2, 0xD5BF, 0x68B3, 0xAEDE, 0x68B4, 0xD9C0, 0x68B5, 0xB1EB, + 0x68C4, 0xB1F3, 0x68C6, 0xD9C3, 0x68C7, 0xD9D9, 0x68C8, 0xD9CE, + 0x68C9, 0xB4D6, 0x68CB, 0xB4D1, 0x68CC, 0xD9BD, 0x68CD, 0xB4D2, + 0x68CE, 0xD9CD, 0x68D0, 0xD9C6, 0x68D1, 0xD9D3, 0x68D2, 0xB4CE, + 0x68D3, 0xD9AB, 0x68D4, 0xD9D5, 0x68D5, 0xB4C4, 0x68D6, 0xD9B3, + 0x68D7, 0xB4C7, 0x68D8, 0xB4C6, 0x68DA, 0xB4D7, 0x68DC, 0xD9AD, + 0x68DD, 0xD9CF, 0x68DE, 0xD9D0, 0x68DF, 0xB4C9, 0x68E0, 0xB4C5, + 0x68E1, 0xD9BB, 0x68E3, 0xB4D0, 0x68E4, 0xD9B6, 0x68E6, 0xD9D1, + 0x68E7, 0xB4CC, 0x68E8, 0xD9C9, 0x68E9, 0xD9D6, 0x68EA, 0xD9B0, + 0x68EB, 0xD9B5, 0x68EC, 0xD9AF, 0x68EE, 0xB4CB, 0x68EF, 0xD9C2, + 0x68F0, 0xDDDE, 0x68F1, 0xD9B1, 0x68F2, 0xB4CF, 0x68F3, 0xD9BA, + 0x68F4, 0xD9D2, 0x68F5, 0xB4CA, 0x68F6, 0xD9B7, 0x68F7, 0xD9B4, + 0x68F8, 0xD9C5, 0x68F9, 0xB4CD, 0x68FA, 0xB4C3, 0x68FB, 0xB4D9, + 0x68FC, 0xD9C8, 0x68FD, 0xD9C7, 0x6904, 0xD9AC, 0x6905, 0xB4C8, + 0x6906, 0xD9D4, 0x6907, 0xD9BC, 0x6908, 0xD9BE, 0x690A, 0xD9CB, + 0x690B, 0xD9CA, 0x690C, 0xD9AA, 0x690D, 0xB4D3, 0x690E, 0xB4D5, + 0x690F, 0xD9B2, 0x6910, 0xD9B9, 0x6911, 0xD9C1, 0x6912, 0xB4D4, + 0x6913, 0xD9B8, 0x6914, 0xD9C4, 0x6915, 0xD9D7, 0x6917, 0xD9CC, + 0x6925, 0xD9D8, 0x692A, 0xD9AE, 0x692F, 0xDDF2, 0x6930, 0xB7A6, + 0x6932, 0xDDF0, 0x6933, 0xDDDB, 0x6934, 0xDDE0, 0x6935, 0xDDD9, + 0x6937, 0xDDEC, 0x6938, 0xDDCB, 0x6939, 0xDDD2, 0x693B, 0xDDEA, + 0x693C, 0xDDF4, 0x693D, 0xDDDC, 0x693F, 0xDDCF, 0x6940, 0xDDE2, + 0x6941, 0xDDE7, 0x6942, 0xDDD3, 0x6944, 0xDDE4, 0x6945, 0xDDD0, + 0x6948, 0xDDD7, 0x6949, 0xDDD8, 0x694A, 0xB7A8, 0x694B, 0xDDEB, + 0x694C, 0xDDE9, 0x694E, 0xDDCC, 0x694F, 0xDDEE, 0x6951, 0xDDEF, + 0x6952, 0xDDF1, 0x6953, 0xB7AC, 0x6954, 0xB7A4, 0x6956, 0xD5B8, + 0x6957, 0xDDD4, 0x6958, 0xDDE6, 0x6959, 0xDDD5, 0x695A, 0xB7A1, + 0x695B, 0xB7B1, 0x695C, 0xDDED, 0x695D, 0xB7AF, 0x695E, 0xB7AB, + 0x695F, 0xDDCA, 0x6960, 0xB7A3, 0x6962, 0xDDCD, 0x6963, 0xB7B0, + 0x6965, 0xDDDD, 0x6966, 0xDDC9, 0x6968, 0xB7A9, 0x6969, 0xDDE1, + 0x696A, 0xDDD1, 0x696B, 0xB7AA, 0x696C, 0xDDDA, 0x696D, 0xB77E, + 0x696E, 0xB4D8, 0x696F, 0xDDE3, 0x6970, 0xD9BF, 0x6971, 0xDDCE, + 0x6974, 0xDDE8, 0x6975, 0xB7A5, 0x6976, 0xDDE5, 0x6977, 0xB7A2, + 0x6978, 0xDDDF, 0x6979, 0xB7AD, 0x697A, 0xDDD6, 0x697B, 0xDDF3, + 0x6982, 0xB7A7, 0x6983, 0xDEC6, 0x6986, 0xB7AE, 0x698D, 0xE24A, + 0x698E, 0xE248, 0x6990, 0xE25E, 0x6991, 0xE246, 0x6993, 0xE258, + 0x6994, 0xB77D, 0x6995, 0xBA5F, 0x6996, 0xE242, 0x6997, 0xE25D, + 0x6999, 0xE247, 0x699A, 0xE255, 0x699B, 0xBA64, 0x699C, 0xBA5D, + 0x699E, 0xE25B, 0x69A0, 0xE240, 0x69A1, 0xE25A, 0x69A3, 0xBA6F, + 0x69A4, 0xE251, 0x69A5, 0xE261, 0x69A6, 0xBA6D, 0x69A7, 0xE249, + 0x69A8, 0xBA5E, 0x69A9, 0xE24B, 0x69AA, 0xE259, 0x69AB, 0xBA67, + 0x69AC, 0xE244, 0x69AD, 0xBA6B, 0x69AE, 0xBA61, 0x69AF, 0xE24D, + 0x69B0, 0xE243, 0x69B1, 0xE1FC, 0x69B3, 0xE257, 0x69B4, 0xBA68, + 0x69B5, 0xE260, 0x69B6, 0xE1FD, 0x69B7, 0xBA65, 0x69B9, 0xE253, + 0x69BB, 0xBA66, 0x69BC, 0xE245, 0x69BD, 0xE250, 0x69BE, 0xE24C, + 0x69BF, 0xE24E, 0x69C1, 0xBA60, 0x69C2, 0xE25F, 0x69C3, 0xBA6E, + 0x69C4, 0xE24F, 0x69C6, 0xE262, 0x69C9, 0xE1FE, 0x69CA, 0xE254, + 0x69CB, 0xBA63, 0x69CC, 0xBA6C, 0x69CD, 0xBA6A, 0x69CE, 0xE241, + 0x69CF, 0xE256, 0x69D0, 0xBA69, 0x69D3, 0xBA62, 0x69D4, 0xE252, + 0x69D9, 0xE25C, 0x69E2, 0xE5D5, 0x69E4, 0xE5D1, 0x69E5, 0xE5CD, + 0x69E6, 0xE5E1, 0x69E7, 0xE5DE, 0x69E8, 0xBCCD, 0x69EB, 0xE5E5, + 0x69EC, 0xE5D4, 0x69ED, 0xBCD8, 0x69EE, 0xE5DB, 0x69F1, 0xE5D0, + 0x69F2, 0xE5DA, 0x69F3, 0xBCD5, 0x69F4, 0xE5EE, 0x69F6, 0xE5EB, + 0x69F7, 0xE5DD, 0x69F8, 0xE5CE, 0x69FB, 0xE5E2, 0x69FC, 0xE5E4, + 0x69FD, 0xBCD1, 0x69FE, 0xE5D8, 0x69FF, 0xE5D3, 0x6A00, 0xE5CA, + 0x6A01, 0xBCCE, 0x6A02, 0xBCD6, 0x6A04, 0xE5E7, 0x6A05, 0xBCD7, + 0x6A06, 0xE5CB, 0x6A07, 0xE5ED, 0x6A08, 0xE5E0, 0x6A09, 0xE5E6, + 0x6A0A, 0xBCD4, 0x6A0D, 0xE5E3, 0x6A0F, 0xE5EA, 0x6A11, 0xBCD9, + 0x6A13, 0xBCD3, 0x6A14, 0xE5DC, 0x6A15, 0xE5CF, 0x6A16, 0xE5EF, + 0x6A17, 0xE5CC, 0x6A18, 0xE5E8, 0x6A19, 0xBCD0, 0x6A1B, 0xE5D6, + 0x6A1D, 0xE5D7, 0x6A1E, 0xBCCF, 0x6A1F, 0xBCCC, 0x6A20, 0xE5D2, + 0x6A21, 0xBCD2, 0x6A23, 0xBCCB, 0x6A25, 0xE5E9, 0x6A26, 0xE5EC, + 0x6A27, 0xE5D9, 0x6A28, 0xE9CA, 0x6A32, 0xE9C2, 0x6A34, 0xE9BE, + 0x6A35, 0xBEF6, 0x6A38, 0xBEEB, 0x6A39, 0xBEF0, 0x6A3A, 0xBEEC, + 0x6A3B, 0xE9CC, 0x6A3C, 0xE9D7, 0x6A3D, 0xBEEA, 0x6A3E, 0xE9C4, + 0x6A3F, 0xE9CD, 0x6A40, 0xE5DF, 0x6A41, 0xE9CE, 0x6A44, 0xBEF1, + 0x6A46, 0xE9DD, 0x6A47, 0xBEF5, 0x6A48, 0xBEF8, 0x6A49, 0xE9C0, + 0x6A4B, 0xBEF4, 0x6A4D, 0xE9DB, 0x6A4E, 0xE9DC, 0x6A4F, 0xE9D2, + 0x6A50, 0xE9D1, 0x6A51, 0xE9C9, 0x6A54, 0xE9D3, 0x6A55, 0xE9DA, + 0x6A56, 0xE9D9, 0x6A58, 0xBEEF, 0x6A59, 0xBEED, 0x6A5A, 0xE9CB, + 0x6A5B, 0xE9C8, 0x6A5D, 0xE9C5, 0x6A5E, 0xE9D8, 0x6A5F, 0xBEF7, + 0x6A60, 0xE9D6, 0x6A61, 0xBEF3, 0x6A62, 0xBEF2, 0x6A64, 0xE9D0, + 0x6A66, 0xE9BF, 0x6A67, 0xE9C1, 0x6A68, 0xE9C3, 0x6A69, 0xE9D5, + 0x6A6A, 0xE9CF, 0x6A6B, 0xBEEE, 0x6A6D, 0xE9C6, 0x6A6F, 0xE9D4, + 0x6A76, 0xE9C7, 0x6A7E, 0xC0CF, 0x6A7F, 0xED45, 0x6A80, 0xC0C8, + 0x6A81, 0xECF5, 0x6A83, 0xED41, 0x6A84, 0xC0CA, 0x6A85, 0xED48, + 0x6A87, 0xECFC, 0x6A89, 0xECF7, 0x6A8C, 0xED49, 0x6A8D, 0xECF3, + 0x6A8E, 0xECFE, 0x6A90, 0xC0D1, 0x6A91, 0xED44, 0x6A92, 0xED4A, + 0x6A93, 0xECFD, 0x6A94, 0xC0C9, 0x6A95, 0xED40, 0x6A96, 0xECF4, + 0x6A97, 0xC0D0, 0x6A9A, 0xED47, 0x6A9B, 0xECF9, 0x6A9C, 0xC0CC, + 0x6A9E, 0xECFB, 0x6A9F, 0xECF8, 0x6AA0, 0xC0D2, 0x6AA1, 0xECFA, + 0x6AA2, 0xC0CB, 0x6AA3, 0xC0CE, 0x6AA4, 0xED43, 0x6AA5, 0xECF6, + 0x6AA6, 0xED46, 0x6AA8, 0xED42, 0x6AAC, 0xC263, 0x6AAD, 0xEFE7, + 0x6AAE, 0xC268, 0x6AAF, 0xC269, 0x6AB3, 0xC262, 0x6AB4, 0xEFE6, + 0x6AB6, 0xEFE3, 0x6AB7, 0xEFE4, 0x6AB8, 0xC266, 0x6AB9, 0xEFDE, + 0x6ABA, 0xEFE2, 0x6ABB, 0xC265, 0x6ABD, 0xEFDF, 0x6AC2, 0xC267, + 0x6AC3, 0xC264, 0x6AC5, 0xEFDD, 0x6AC6, 0xEFE1, 0x6AC7, 0xEFE5, + 0x6ACB, 0xF251, 0x6ACC, 0xF24E, 0x6ACD, 0xF257, 0x6ACF, 0xF256, + 0x6AD0, 0xF254, 0x6AD1, 0xF24F, 0x6AD3, 0xC372, 0x6AD9, 0xF250, + 0x6ADA, 0xC371, 0x6ADB, 0xC0CD, 0x6ADC, 0xF253, 0x6ADD, 0xC370, + 0x6ADE, 0xF258, 0x6ADF, 0xF252, 0x6AE0, 0xF24D, 0x6AE1, 0xEFE0, + 0x6AE5, 0xC36F, 0x6AE7, 0xF24C, 0x6AE8, 0xF456, 0x6AEA, 0xF455, + 0x6AEB, 0xF255, 0x6AEC, 0xC468, 0x6AEE, 0xF459, 0x6AEF, 0xF45A, + 0x6AF0, 0xF454, 0x6AF1, 0xF458, 0x6AF3, 0xF453, 0x6AF8, 0xF5D1, + 0x6AF9, 0xF457, 0x6AFA, 0xC4E7, 0x6AFB, 0xC4E5, 0x6AFC, 0xF5CF, + 0x6B00, 0xF5D2, 0x6B02, 0xF5CE, 0x6B03, 0xF5D0, 0x6B04, 0xC4E6, + 0x6B08, 0xF6E5, 0x6B09, 0xF6E6, 0x6B0A, 0xC576, 0x6B0B, 0xF6E4, + 0x6B0F, 0xF7E2, 0x6B10, 0xC5CF, 0x6B11, 0xF7E0, 0x6B12, 0xF7E1, + 0x6B13, 0xF8AC, 0x6B16, 0xC656, 0x6B17, 0xF8F3, 0x6B18, 0xF8F1, + 0x6B19, 0xF8F2, 0x6B1A, 0xF8F4, 0x6B1E, 0xF9BB, 0x6B20, 0xA4ED, + 0x6B21, 0xA6B8, 0x6B23, 0xAA59, 0x6B25, 0xCCE9, 0x6B28, 0xCF64, + 0x6B2C, 0xD1F5, 0x6B2D, 0xD1F7, 0x6B2F, 0xD1F6, 0x6B31, 0xD1F8, + 0x6B32, 0xB1FD, 0x6B33, 0xD5D7, 0x6B34, 0xD1F9, 0x6B36, 0xD5D6, + 0x6B37, 0xD5D8, 0x6B38, 0xD5D9, 0x6B39, 0xD9DA, 0x6B3A, 0xB4DB, + 0x6B3B, 0xD9DB, 0x6B3C, 0xD9DD, 0x6B3D, 0xB4DC, 0x6B3E, 0xB4DA, + 0x6B3F, 0xD9DC, 0x6B41, 0xDDFA, 0x6B42, 0xDDF8, 0x6B43, 0xDDF7, + 0x6B45, 0xDDF6, 0x6B46, 0xDDF5, 0x6B47, 0xB7B2, 0x6B48, 0xDDF9, + 0x6B49, 0xBA70, 0x6B4A, 0xE263, 0x6B4B, 0xE265, 0x6B4C, 0xBA71, + 0x6B4D, 0xE264, 0x6B4E, 0xBCDB, 0x6B50, 0xBCDA, 0x6B51, 0xE5F0, + 0x6B54, 0xE9DF, 0x6B55, 0xE9DE, 0x6B56, 0xE9E0, 0x6B59, 0xBEF9, + 0x6B5B, 0xED4B, 0x6B5C, 0xC0D3, 0x6B5E, 0xEFE8, 0x6B5F, 0xC26A, + 0x6B60, 0xF259, 0x6B61, 0xC577, 0x6B62, 0xA4EE, 0x6B63, 0xA5BF, + 0x6B64, 0xA6B9, 0x6B65, 0xA842, 0x6B66, 0xAA5A, 0x6B67, 0xAA5B, + 0x6B6A, 0xAC6E, 0x6B6D, 0xD1FA, 0x6B72, 0xB7B3, 0x6B76, 0xE6D1, + 0x6B77, 0xBEFA, 0x6B78, 0xC26B, 0x6B79, 0xA4EF, 0x6B7B, 0xA6BA, + 0x6B7E, 0xCCEB, 0x6B7F, 0xAA5C, 0x6B80, 0xCCEA, 0x6B82, 0xCF65, + 0x6B83, 0xAC6F, 0x6B84, 0xCF66, 0x6B86, 0xAC70, 0x6B88, 0xD1FC, + 0x6B89, 0xAEEE, 0x6B8A, 0xAEED, 0x6B8C, 0xD5DE, 0x6B8D, 0xD5DC, + 0x6B8E, 0xD5DD, 0x6B8F, 0xD5DB, 0x6B91, 0xD5DA, 0x6B94, 0xD9DE, + 0x6B95, 0xD9E1, 0x6B96, 0xB4DE, 0x6B97, 0xD9DF, 0x6B98, 0xB4DD, + 0x6B99, 0xD9E0, 0x6B9B, 0xDDFB, 0x6B9E, 0xE266, 0x6B9F, 0xE267, + 0x6BA0, 0xE268, 0x6BA2, 0xE5F3, 0x6BA3, 0xE5F2, 0x6BA4, 0xBCDC, + 0x6BA5, 0xE5F1, 0x6BA6, 0xE5F4, 0x6BA7, 0xE9E1, 0x6BAA, 0xE9E2, + 0x6BAB, 0xE9E3, 0x6BAD, 0xED4C, 0x6BAE, 0xC0D4, 0x6BAF, 0xC26C, + 0x6BB0, 0xF25A, 0x6BB2, 0xC4E8, 0x6BB3, 0xC95F, 0x6BB5, 0xAC71, + 0x6BB6, 0xCF67, 0x6BB7, 0xAEEF, 0x6BBA, 0xB1FE, 0x6BBC, 0xB4DF, + 0x6BBD, 0xD9E2, 0x6BBF, 0xB7B5, 0x6BC0, 0xB7B4, 0x6BC3, 0xE269, + 0x6BC4, 0xE26A, 0x6BC5, 0xBCDD, 0x6BC6, 0xBCDE, 0x6BC7, 0xE9E5, + 0x6BC8, 0xE9E4, 0x6BC9, 0xEFE9, 0x6BCA, 0xF7E3, 0x6BCB, 0xA4F0, + 0x6BCC, 0xC960, 0x6BCD, 0xA5C0, 0x6BCF, 0xA843, 0x6BD0, 0xCB48, + 0x6BD2, 0xAC72, 0x6BD3, 0xB7B6, 0x6BD4, 0xA4F1, 0x6BD6, 0xCF68, + 0x6BD7, 0xAC73, 0x6BD8, 0xCF69, 0x6BDA, 0xC0D5, 0x6BDB, 0xA4F2, + 0x6BDE, 0xCCEC, 0x6BE0, 0xCF6A, 0x6BE2, 0xD242, 0x6BE3, 0xD241, + 0x6BE4, 0xD1FE, 0x6BE6, 0xD1FD, 0x6BE7, 0xD243, 0x6BE8, 0xD240, + 0x6BEB, 0xB240, 0x6BEC, 0xB241, 0x6BEF, 0xB4E0, 0x6BF0, 0xD9E3, + 0x6BF2, 0xD9E4, 0x6BF3, 0xD9E5, 0x6BF7, 0xDE41, 0x6BF8, 0xDE42, + 0x6BF9, 0xDE40, 0x6BFB, 0xDDFD, 0x6BFC, 0xDDFE, 0x6BFD, 0xB7B7, + 0x6BFE, 0xE26B, 0x6BFF, 0xE5F7, 0x6C00, 0xE5F6, 0x6C01, 0xE5F5, + 0x6C02, 0xE5F8, 0x6C03, 0xE9E7, 0x6C04, 0xE9E6, 0x6C05, 0xBEFB, + 0x6C06, 0xE9E8, 0x6C08, 0xC0D6, 0x6C09, 0xED4D, 0x6C0B, 0xEFEA, + 0x6C0C, 0xF25B, 0x6C0D, 0xF6E7, 0x6C0F, 0xA4F3, 0x6C10, 0xA5C2, + 0x6C11, 0xA5C1, 0x6C13, 0xAA5D, 0x6C14, 0xC961, 0x6C15, 0xC97E, + 0x6C16, 0xA6BB, 0x6C18, 0xC9F7, 0x6C19, 0xCB49, 0x6C1A, 0xCB4A, + 0x6C1B, 0xAA5E, 0x6C1D, 0xCCED, 0x6C1F, 0xAC74, 0x6C20, 0xCF6B, + 0x6C21, 0xCF6C, 0x6C23, 0xAEF0, 0x6C24, 0xAEF4, 0x6C25, 0xD244, + 0x6C26, 0xAEF3, 0x6C27, 0xAEF1, 0x6C28, 0xAEF2, 0x6C2A, 0xD5DF, + 0x6C2B, 0xB242, 0x6C2C, 0xB4E3, 0x6C2E, 0xB4E1, 0x6C2F, 0xB4E2, + 0x6C30, 0xD9E6, 0x6C33, 0xBA72, 0x6C34, 0xA4F4, 0x6C36, 0xC9A1, + 0x6C38, 0xA5C3, 0x6C3B, 0xC9A4, 0x6C3E, 0xA5C6, 0x6C3F, 0xC9A3, + 0x6C40, 0xA5C5, 0x6C41, 0xA5C4, 0x6C42, 0xA844, 0x6C43, 0xC9A2, + 0x6C46, 0xC9F8, 0x6C4A, 0xC9FC, 0x6C4B, 0xC9FE, 0x6C4C, 0xCA40, + 0x6C4D, 0xA6C5, 0x6C4E, 0xA6C6, 0x6C4F, 0xC9FB, 0x6C50, 0xA6C1, + 0x6C52, 0xC9F9, 0x6C54, 0xC9FD, 0x6C55, 0xA6C2, 0x6C57, 0xA6BD, + 0x6C59, 0xA6BE, 0x6C5B, 0xA6C4, 0x6C5C, 0xC9FA, 0x6C5D, 0xA6BC, + 0x6C5E, 0xA845, 0x6C5F, 0xA6BF, 0x6C60, 0xA6C0, 0x6C61, 0xA6C3, + 0x6C65, 0xCB5B, 0x6C66, 0xCB59, 0x6C67, 0xCB4C, 0x6C68, 0xA851, + 0x6C69, 0xCB53, 0x6C6A, 0xA84C, 0x6C6B, 0xCB4D, 0x6C6D, 0xCB55, + 0x6C6F, 0xCB52, 0x6C70, 0xA84F, 0x6C71, 0xCB51, 0x6C72, 0xA856, + 0x6C73, 0xCB5A, 0x6C74, 0xA858, 0x6C76, 0xA85A, 0x6C78, 0xCB4B, + 0x6C7A, 0xA84D, 0x6C7B, 0xCB5C, 0x6C7D, 0xA854, 0x6C7E, 0xA857, + 0x6C80, 0xCD45, 0x6C81, 0xA847, 0x6C82, 0xA85E, 0x6C83, 0xA855, + 0x6C84, 0xCB4E, 0x6C85, 0xA84A, 0x6C86, 0xA859, 0x6C87, 0xCB56, + 0x6C88, 0xA848, 0x6C89, 0xA849, 0x6C8A, 0xCD43, 0x6C8B, 0xCB4F, + 0x6C8C, 0xA850, 0x6C8D, 0xA85B, 0x6C8E, 0xCB5D, 0x6C8F, 0xCB50, + 0x6C90, 0xA84E, 0x6C92, 0xA853, 0x6C93, 0xCCEE, 0x6C94, 0xA85C, + 0x6C95, 0xCB57, 0x6C96, 0xA852, 0x6C98, 0xA85D, 0x6C99, 0xA846, + 0x6C9A, 0xCB54, 0x6C9B, 0xA84B, 0x6C9C, 0xCB58, 0x6C9D, 0xCD44, + 0x6CAB, 0xAA6A, 0x6CAC, 0xAA7A, 0x6CAD, 0xCCF5, 0x6CAE, 0xAA71, + 0x6CB0, 0xCD4B, 0x6CB1, 0xAA62, 0x6CB3, 0xAA65, 0x6CB4, 0xCD42, + 0x6CB6, 0xCCF3, 0x6CB7, 0xCCF7, 0x6CB8, 0xAA6D, 0x6CB9, 0xAA6F, + 0x6CBA, 0xCCFA, 0x6CBB, 0xAA76, 0x6CBC, 0xAA68, 0x6CBD, 0xAA66, + 0x6CBE, 0xAA67, 0x6CBF, 0xAA75, 0x6CC0, 0xCD47, 0x6CC1, 0xAA70, + 0x6CC2, 0xCCF9, 0x6CC3, 0xCCFB, 0x6CC4, 0xAA6E, 0x6CC5, 0xAA73, + 0x6CC6, 0xCCFC, 0x6CC7, 0xCD4A, 0x6CC9, 0xAC75, 0x6CCA, 0xAA79, + 0x6CCC, 0xAA63, 0x6CCD, 0xCD49, 0x6CCF, 0xCD4D, 0x6CD0, 0xCCF8, + 0x6CD1, 0xCD4F, 0x6CD2, 0xCD40, 0x6CD3, 0xAA6C, 0x6CD4, 0xCCF4, + 0x6CD5, 0xAA6B, 0x6CD6, 0xAA7D, 0x6CD7, 0xAA72, 0x6CD9, 0xCCF2, + 0x6CDA, 0xCF75, 0x6CDB, 0xAA78, 0x6CDC, 0xAA7C, 0x6CDD, 0xCD41, + 0x6CDE, 0xCD46, 0x6CE0, 0xAA7E, 0x6CE1, 0xAA77, 0x6CE2, 0xAA69, + 0x6CE3, 0xAA5F, 0x6CE5, 0xAA64, 0x6CE7, 0xCCF6, 0x6CE8, 0xAA60, + 0x6CE9, 0xCD4E, 0x6CEB, 0xCCF0, 0x6CEC, 0xCCEF, 0x6CED, 0xCCFD, + 0x6CEE, 0xCCF1, 0x6CEF, 0xAA7B, 0x6CF0, 0xAEF5, 0x6CF1, 0xAA74, + 0x6CF2, 0xCCFE, 0x6CF3, 0xAA61, 0x6CF5, 0xACA6, 0x6CF9, 0xCD4C, + 0x6D00, 0xCF7C, 0x6D01, 0xCFA1, 0x6D03, 0xCFA4, 0x6D04, 0xCF77, + 0x6D07, 0xCFA7, 0x6D08, 0xCFAA, 0x6D09, 0xCFAC, 0x6D0A, 0xCF74, + 0x6D0B, 0xAC76, 0x6D0C, 0xAC7B, 0x6D0D, 0xD249, 0x6D0E, 0xACAD, + 0x6D0F, 0xCFA5, 0x6D10, 0xCFAD, 0x6D11, 0xCF7B, 0x6D12, 0xCF73, + 0x6D16, 0xD264, 0x6D17, 0xAC7E, 0x6D18, 0xCFA2, 0x6D19, 0xCF78, + 0x6D1A, 0xCF7A, 0x6D1B, 0xACA5, 0x6D1D, 0xCF7D, 0x6D1E, 0xAC7D, + 0x6D1F, 0xCF70, 0x6D20, 0xCFA8, 0x6D22, 0xCFAB, 0x6D25, 0xAC7A, + 0x6D27, 0xACA8, 0x6D28, 0xCF6D, 0x6D29, 0xACAA, 0x6D2A, 0xAC78, + 0x6D2B, 0xACAE, 0x6D2C, 0xCFA9, 0x6D2D, 0xCF6F, 0x6D2E, 0xACAB, + 0x6D2F, 0xD25E, 0x6D30, 0xCD48, 0x6D31, 0xAC7C, 0x6D32, 0xAC77, + 0x6D33, 0xCF76, 0x6D34, 0xCF6E, 0x6D35, 0xACAC, 0x6D36, 0xACA4, + 0x6D37, 0xCFA3, 0x6D38, 0xACA9, 0x6D39, 0xACA7, 0x6D3A, 0xCF79, + 0x6D3B, 0xACA1, 0x6D3C, 0xCF71, 0x6D3D, 0xACA2, 0x6D3E, 0xACA3, + 0x6D3F, 0xCF72, 0x6D40, 0xCFA6, 0x6D41, 0xAC79, 0x6D42, 0xCF7E, + 0x6D58, 0xD24C, 0x6D59, 0xAEFD, 0x6D5A, 0xAF43, 0x6D5E, 0xD255, + 0x6D5F, 0xD25B, 0x6D60, 0xD257, 0x6D61, 0xD24A, 0x6D62, 0xD24D, + 0x6D63, 0xD246, 0x6D64, 0xD247, 0x6D65, 0xAF4A, 0x6D66, 0xAEFA, + 0x6D67, 0xD256, 0x6D68, 0xD25F, 0x6D69, 0xAF45, 0x6D6A, 0xAEF6, + 0x6D6C, 0xAF40, 0x6D6D, 0xD24E, 0x6D6E, 0xAF42, 0x6D6F, 0xD24F, + 0x6D70, 0xD259, 0x6D74, 0xAF44, 0x6D75, 0xD268, 0x6D76, 0xD248, + 0x6D77, 0xAEFC, 0x6D78, 0xAEFB, 0x6D79, 0xAF48, 0x6D7A, 0xD245, + 0x6D7B, 0xD266, 0x6D7C, 0xD25A, 0x6D7D, 0xD267, 0x6D7E, 0xD261, + 0x6D7F, 0xD253, 0x6D80, 0xD262, 0x6D82, 0xD25C, 0x6D83, 0xD265, + 0x6D84, 0xD263, 0x6D85, 0xAF49, 0x6D86, 0xD254, 0x6D87, 0xAEF9, + 0x6D88, 0xAEF8, 0x6D89, 0xAF41, 0x6D8A, 0xAF47, 0x6D8B, 0xD260, + 0x6D8C, 0xAF46, 0x6D8D, 0xD251, 0x6D8E, 0xB243, 0x6D90, 0xD269, + 0x6D91, 0xD250, 0x6D92, 0xD24B, 0x6D93, 0xAEFE, 0x6D94, 0xAF4B, + 0x6D95, 0xAEF7, 0x6D97, 0xD258, 0x6D98, 0xD25D, 0x6DAA, 0xB265, + 0x6DAB, 0xD5E1, 0x6DAC, 0xD5E5, 0x6DAE, 0xB252, 0x6DAF, 0xB250, + 0x6DB2, 0xB247, 0x6DB3, 0xD5E3, 0x6DB4, 0xD5E2, 0x6DB5, 0xB25B, + 0x6DB7, 0xD5E8, 0x6DB8, 0xB255, 0x6DBA, 0xD5FA, 0x6DBB, 0xD647, + 0x6DBC, 0xB244, 0x6DBD, 0xD5F7, 0x6DBE, 0xD5F0, 0x6DBF, 0xB267, + 0x6DC0, 0xD5E0, 0x6DC2, 0xD5FC, 0x6DC4, 0xB264, 0x6DC5, 0xB258, + 0x6DC6, 0xB263, 0x6DC7, 0xB24E, 0x6DC8, 0xD5EC, 0x6DC9, 0xD5FE, + 0x6DCA, 0xD5F6, 0x6DCB, 0xB24F, 0x6DCC, 0xB249, 0x6DCD, 0xD645, + 0x6DCF, 0xD5FD, 0x6DD0, 0xD640, 0x6DD1, 0xB251, 0x6DD2, 0xB259, + 0x6DD3, 0xD642, 0x6DD4, 0xD5EA, 0x6DD5, 0xD5FB, 0x6DD6, 0xD5EF, + 0x6DD7, 0xD644, 0x6DD8, 0xB25E, 0x6DD9, 0xB246, 0x6DDA, 0xB25C, + 0x6DDB, 0xD5F4, 0x6DDC, 0xD5F2, 0x6DDD, 0xD5F3, 0x6DDE, 0xB253, + 0x6DDF, 0xD5EE, 0x6DE0, 0xD5ED, 0x6DE1, 0xB248, 0x6DE2, 0xD5E7, + 0x6DE3, 0xD646, 0x6DE4, 0xB24A, 0x6DE5, 0xD5F1, 0x6DE6, 0xB268, + 0x6DE8, 0xB262, 0x6DE9, 0xD5E6, 0x6DEA, 0xB25F, 0x6DEB, 0xB25D, + 0x6DEC, 0xB266, 0x6DED, 0xD5F8, 0x6DEE, 0xB261, 0x6DEF, 0xD252, + 0x6DF0, 0xD5F9, 0x6DF1, 0xB260, 0x6DF2, 0xD641, 0x6DF3, 0xB245, + 0x6DF4, 0xD5F5, 0x6DF5, 0xB257, 0x6DF6, 0xD5E9, 0x6DF7, 0xB256, + 0x6DF9, 0xB254, 0x6DFA, 0xB24C, 0x6DFB, 0xB24B, 0x6DFC, 0xD9E7, + 0x6DFD, 0xD643, 0x6E00, 0xD5EB, 0x6E03, 0xD9FC, 0x6E05, 0xB24D, + 0x6E19, 0xB541, 0x6E1A, 0xB25A, 0x6E1B, 0xB4EE, 0x6E1C, 0xD9F6, + 0x6E1D, 0xB4FC, 0x6E1F, 0xD9EA, 0x6E20, 0xB4EB, 0x6E21, 0xB4E7, + 0x6E22, 0xDA49, 0x6E23, 0xB4ED, 0x6E24, 0xB4F1, 0x6E25, 0xB4EC, + 0x6E26, 0xB4F5, 0x6E27, 0xDA4D, 0x6E28, 0xDA44, 0x6E2B, 0xD9F1, + 0x6E2C, 0xB4FA, 0x6E2D, 0xB4F4, 0x6E2E, 0xD9FD, 0x6E2F, 0xB4E4, + 0x6E30, 0xDA4A, 0x6E31, 0xDA43, 0x6E32, 0xB4E8, 0x6E33, 0xD9F7, + 0x6E34, 0xB4F7, 0x6E35, 0xDA55, 0x6E36, 0xDA56, 0x6E38, 0xB4E5, + 0x6E39, 0xDA48, 0x6E3A, 0xB4F9, 0x6E3B, 0xD9FB, 0x6E3C, 0xD9ED, + 0x6E3D, 0xD9EE, 0x6E3E, 0xB4FD, 0x6E3F, 0xD9F2, 0x6E40, 0xD9F9, + 0x6E41, 0xD9F3, 0x6E43, 0xB4FB, 0x6E44, 0xB544, 0x6E45, 0xD9EF, + 0x6E46, 0xD9E8, 0x6E47, 0xD9E9, 0x6E49, 0xD9EB, 0x6E4A, 0xB4EA, + 0x6E4B, 0xD9F8, 0x6E4D, 0xB4F8, 0x6E4E, 0xB542, 0x6E51, 0xD9FA, + 0x6E52, 0xDA53, 0x6E53, 0xDA4B, 0x6E54, 0xB4E6, 0x6E55, 0xDA51, + 0x6E56, 0xB4F2, 0x6E58, 0xB4F0, 0x6E5A, 0xDA57, 0x6E5B, 0xB4EF, + 0x6E5C, 0xDA41, 0x6E5D, 0xD9F4, 0x6E5E, 0xD9FE, 0x6E5F, 0xB547, + 0x6E60, 0xDA45, 0x6E61, 0xDA42, 0x6E62, 0xD9F0, 0x6E63, 0xB543, + 0x6E64, 0xDA4F, 0x6E65, 0xDA4C, 0x6E66, 0xDA54, 0x6E67, 0xB4E9, + 0x6E68, 0xDA40, 0x6E69, 0xB546, 0x6E6B, 0xDA47, 0x6E6E, 0xB4F3, + 0x6E6F, 0xB4F6, 0x6E71, 0xDA46, 0x6E72, 0xB545, 0x6E73, 0xD9F5, + 0x6E74, 0xD5E4, 0x6E77, 0xDA50, 0x6E78, 0xDA4E, 0x6E79, 0xDA52, + 0x6E88, 0xD9EC, 0x6E89, 0xB540, 0x6E8D, 0xDE61, 0x6E8E, 0xDE60, + 0x6E8F, 0xDE46, 0x6E90, 0xB7BD, 0x6E92, 0xDE5F, 0x6E93, 0xDE49, + 0x6E94, 0xDE4A, 0x6E96, 0xB7C7, 0x6E97, 0xDE68, 0x6E98, 0xB7C2, + 0x6E99, 0xDE5E, 0x6E9B, 0xDE43, 0x6E9C, 0xB7C8, 0x6E9D, 0xB7BE, + 0x6E9E, 0xDE52, 0x6E9F, 0xDE48, 0x6EA0, 0xDE4B, 0x6EA1, 0xDE63, + 0x6EA2, 0xB7B8, 0x6EA3, 0xDE6A, 0x6EA4, 0xDE62, 0x6EA5, 0xB7C1, + 0x6EA6, 0xDE57, 0x6EA7, 0xB7CC, 0x6EAA, 0xB7CB, 0x6EAB, 0xB7C5, + 0x6EAE, 0xDE69, 0x6EAF, 0xB7B9, 0x6EB0, 0xDE55, 0x6EB1, 0xDE4C, + 0x6EB2, 0xDE59, 0x6EB3, 0xDE65, 0x6EB4, 0xB7CD, 0x6EB6, 0xB7BB, + 0x6EB7, 0xDE54, 0x6EB9, 0xDE4D, 0x6EBA, 0xB7C4, 0x6EBC, 0xB7C3, + 0x6EBD, 0xDE50, 0x6EBE, 0xDE5A, 0x6EBF, 0xDE64, 0x6EC0, 0xDE47, + 0x6EC1, 0xDE51, 0x6EC2, 0xB7BC, 0x6EC3, 0xDE5B, 0x6EC4, 0xB7C9, + 0x6EC5, 0xB7C0, 0x6EC6, 0xDE4E, 0x6EC7, 0xB7BF, 0x6EC8, 0xDE45, + 0x6EC9, 0xDE53, 0x6ECA, 0xDE67, 0x6ECB, 0xB4FE, 0x6ECC, 0xBAB0, + 0x6ECD, 0xDE56, 0x6ECE, 0xE26C, 0x6ECF, 0xDE58, 0x6ED0, 0xDE66, + 0x6ED1, 0xB7C6, 0x6ED2, 0xDE4F, 0x6ED3, 0xB7BA, 0x6ED4, 0xB7CA, + 0x6ED5, 0xBCF0, 0x6ED6, 0xDE44, 0x6ED8, 0xDE5D, 0x6EDC, 0xDE5C, + 0x6EEB, 0xE2AA, 0x6EEC, 0xBAAD, 0x6EED, 0xE27D, 0x6EEE, 0xE2A4, + 0x6EEF, 0xBAA2, 0x6EF1, 0xE26E, 0x6EF2, 0xBAAF, 0x6EF4, 0xBA77, + 0x6EF5, 0xE26D, 0x6EF6, 0xE2B0, 0x6EF7, 0xBAB1, 0x6EF8, 0xE271, + 0x6EF9, 0xE2A3, 0x6EFB, 0xE273, 0x6EFC, 0xE2B3, 0x6EFD, 0xE2AF, + 0x6EFE, 0xBA75, 0x6EFF, 0xBAA1, 0x6F00, 0xE653, 0x6F01, 0xBAAE, + 0x6F02, 0xBA7D, 0x6F03, 0xE26F, 0x6F05, 0xE2AE, 0x6F06, 0xBAA3, + 0x6F07, 0xE2AB, 0x6F08, 0xE2B8, 0x6F09, 0xE275, 0x6F0A, 0xE27E, + 0x6F0D, 0xE2B6, 0x6F0E, 0xE2AC, 0x6F0F, 0xBA7C, 0x6F12, 0xE27C, + 0x6F13, 0xBA76, 0x6F14, 0xBA74, 0x6F15, 0xBAA8, 0x6F18, 0xE27A, + 0x6F19, 0xE277, 0x6F1A, 0xE278, 0x6F1C, 0xE2B2, 0x6F1E, 0xE2B7, + 0x6F1F, 0xE2B5, 0x6F20, 0xBA7A, 0x6F21, 0xE2B9, 0x6F22, 0xBA7E, + 0x6F23, 0xBAA7, 0x6F25, 0xE270, 0x6F26, 0xE5FA, 0x6F27, 0xE279, + 0x6F29, 0xBA78, 0x6F2A, 0xBAAC, 0x6F2B, 0xBAA9, 0x6F2C, 0xBA7B, + 0x6F2D, 0xE2A5, 0x6F2E, 0xE274, 0x6F2F, 0xBAAA, 0x6F30, 0xE2A7, + 0x6F31, 0xBAA4, 0x6F32, 0xBAA6, 0x6F33, 0xBA73, 0x6F35, 0xE2A9, + 0x6F36, 0xE2A1, 0x6F37, 0xE272, 0x6F38, 0xBAA5, 0x6F39, 0xE2B1, + 0x6F3A, 0xE2B4, 0x6F3B, 0xE27B, 0x6F3C, 0xE2A8, 0x6F3E, 0xBA79, + 0x6F3F, 0xBCDF, 0x6F40, 0xE2A6, 0x6F41, 0xE5F9, 0x6F43, 0xE2AD, + 0x6F4E, 0xE276, 0x6F4F, 0xE644, 0x6F50, 0xE64E, 0x6F51, 0xBCE2, + 0x6F52, 0xE64D, 0x6F53, 0xE659, 0x6F54, 0xBCE4, 0x6F55, 0xE64B, + 0x6F57, 0xE64F, 0x6F58, 0xBCEF, 0x6F5A, 0xE646, 0x6F5B, 0xBCE7, + 0x6F5D, 0xE652, 0x6F5E, 0xE9F0, 0x6F5F, 0xBCF3, 0x6F60, 0xBCF2, + 0x6F61, 0xE654, 0x6F62, 0xE643, 0x6F63, 0xE65E, 0x6F64, 0xBCED, + 0x6F66, 0xBCE3, 0x6F67, 0xE657, 0x6F69, 0xE65B, 0x6F6A, 0xE660, + 0x6F6B, 0xE655, 0x6F6C, 0xE649, 0x6F6D, 0xBCE6, 0x6F6E, 0xBCE9, + 0x6F6F, 0xBCF1, 0x6F70, 0xBCEC, 0x6F72, 0xE64C, 0x6F73, 0xE2A2, + 0x6F76, 0xE648, 0x6F77, 0xE65F, 0x6F78, 0xBCE8, 0x6F7A, 0xBCEB, + 0x6F7B, 0xE661, 0x6F7C, 0xBCE0, 0x6F7D, 0xE656, 0x6F7E, 0xE5FB, + 0x6F7F, 0xE65C, 0x6F80, 0xC0DF, 0x6F82, 0xE64A, 0x6F84, 0xBCE1, + 0x6F85, 0xE645, 0x6F86, 0xBCE5, 0x6F87, 0xE5FC, 0x6F88, 0xBAAB, + 0x6F89, 0xE641, 0x6F8B, 0xE65A, 0x6F8C, 0xE642, 0x6F8D, 0xE640, + 0x6F8E, 0xBCEA, 0x6F90, 0xE658, 0x6F92, 0xE5FE, 0x6F93, 0xE651, + 0x6F94, 0xE650, 0x6F95, 0xE65D, 0x6F96, 0xE647, 0x6F97, 0xBCEE, + 0x6F9E, 0xE9F3, 0x6FA0, 0xBF49, 0x6FA1, 0xBEFE, 0x6FA2, 0xEA40, + 0x6FA3, 0xE9EB, 0x6FA4, 0xBF41, 0x6FA5, 0xE9F7, 0x6FA6, 0xBF48, + 0x6FA7, 0xBF43, 0x6FA8, 0xE9F5, 0x6FA9, 0xED4F, 0x6FAA, 0xE9FB, + 0x6FAB, 0xEA42, 0x6FAC, 0xE9FA, 0x6FAD, 0xE9E9, 0x6FAE, 0xE9F8, + 0x6FAF, 0xEA44, 0x6FB0, 0xEA46, 0x6FB1, 0xBEFD, 0x6FB2, 0xEA45, + 0x6FB3, 0xBF44, 0x6FB4, 0xBF4A, 0x6FB6, 0xBF47, 0x6FB8, 0xE9FE, + 0x6FB9, 0xBF46, 0x6FBA, 0xE9F9, 0x6FBC, 0xE9ED, 0x6FBD, 0xE9F2, + 0x6FBF, 0xE9FD, 0x6FC0, 0xBF45, 0x6FC1, 0xBF42, 0x6FC2, 0xBEFC, + 0x6FC3, 0xBF40, 0x6FC4, 0xE9F1, 0x6FC6, 0xE5FD, 0x6FC7, 0xE9EC, + 0x6FC8, 0xE9EF, 0x6FC9, 0xEA41, 0x6FCA, 0xE9F4, 0x6FCB, 0xE9EA, + 0x6FCC, 0xED4E, 0x6FCD, 0xEA43, 0x6FCE, 0xE9EE, 0x6FCF, 0xE9FC, + 0x6FD4, 0xED51, 0x6FD5, 0xC0E3, 0x6FD8, 0xC0D7, 0x6FDB, 0xC0DB, + 0x6FDC, 0xED53, 0x6FDD, 0xED59, 0x6FDE, 0xED57, 0x6FDF, 0xC0D9, + 0x6FE0, 0xC0DA, 0x6FE1, 0xC0E1, 0x6FE2, 0xED5A, 0x6FE3, 0xED52, + 0x6FE4, 0xC0DC, 0x6FE6, 0xED56, 0x6FE7, 0xED55, 0x6FE8, 0xED5B, + 0x6FE9, 0xC0E2, 0x6FEB, 0xC0DD, 0x6FEC, 0xC0E0, 0x6FED, 0xED54, + 0x6FEE, 0xC0E4, 0x6FEF, 0xC0DE, 0x6FF0, 0xC0E5, 0x6FF1, 0xC0D8, + 0x6FF2, 0xED58, 0x6FF4, 0xED50, 0x6FF7, 0xEFF7, 0x6FFA, 0xC271, + 0x6FFB, 0xEFF4, 0x6FFC, 0xEFF6, 0x6FFE, 0xC26F, 0x6FFF, 0xEFF2, + 0x7000, 0xEFF3, 0x7001, 0xEFEE, 0x7004, 0xE9F6, 0x7005, 0xEFEF, + 0x7006, 0xC270, 0x7007, 0xEFEB, 0x7009, 0xC26D, 0x700A, 0xEFF8, + 0x700B, 0xC26E, 0x700C, 0xEFEC, 0x700D, 0xEFED, 0x700E, 0xEFF1, + 0x700F, 0xC273, 0x7011, 0xC272, 0x7014, 0xEFF0, 0x7015, 0xC378, + 0x7016, 0xF25F, 0x7017, 0xF265, 0x7018, 0xC379, 0x7019, 0xF25C, + 0x701A, 0xC376, 0x701B, 0xC373, 0x701C, 0xF267, 0x701D, 0xC377, + 0x701F, 0xC374, 0x7020, 0xF25E, 0x7021, 0xF261, 0x7022, 0xF262, + 0x7023, 0xF263, 0x7024, 0xF266, 0x7026, 0xEFF5, 0x7027, 0xF25D, + 0x7028, 0xC375, 0x7029, 0xF264, 0x702A, 0xF268, 0x702B, 0xF260, + 0x702F, 0xF45D, 0x7030, 0xC46A, 0x7031, 0xF460, 0x7032, 0xC46B, + 0x7033, 0xF468, 0x7034, 0xF45F, 0x7035, 0xF45C, 0x7037, 0xF45E, + 0x7038, 0xF462, 0x7039, 0xF465, 0x703A, 0xF464, 0x703B, 0xF467, + 0x703C, 0xF45B, 0x703E, 0xC469, 0x703F, 0xF463, 0x7040, 0xF466, + 0x7041, 0xF469, 0x7042, 0xF461, 0x7043, 0xF5D3, 0x7044, 0xF5D4, + 0x7045, 0xF5D8, 0x7046, 0xF5D9, 0x7048, 0xF5D6, 0x7049, 0xF5D7, + 0x704A, 0xF5D5, 0x704C, 0xC4E9, 0x7051, 0xC578, 0x7052, 0xF6EB, + 0x7055, 0xF6E8, 0x7056, 0xF6E9, 0x7057, 0xF6EA, 0x7058, 0xC579, + 0x705A, 0xF7E5, 0x705B, 0xF7E4, 0x705D, 0xF8AF, 0x705E, 0xC5F4, + 0x705F, 0xF8AD, 0x7060, 0xF8B0, 0x7061, 0xF8AE, 0x7062, 0xF8F5, + 0x7063, 0xC657, 0x7064, 0xC665, 0x7065, 0xF9A3, 0x7066, 0xF96C, + 0x7068, 0xF9A2, 0x7069, 0xF9D0, 0x706A, 0xF9D1, 0x706B, 0xA4F5, + 0x7070, 0xA6C7, 0x7071, 0xCA41, 0x7074, 0xCB5E, 0x7076, 0xA85F, + 0x7078, 0xA862, 0x707A, 0xCB5F, 0x707C, 0xA860, 0x707D, 0xA861, + 0x7082, 0xCD58, 0x7083, 0xCD5A, 0x7084, 0xCD55, 0x7085, 0xCD52, + 0x7086, 0xCD54, 0x708A, 0xAAA4, 0x708E, 0xAAA2, 0x7091, 0xCD56, + 0x7092, 0xAAA3, 0x7093, 0xCD53, 0x7094, 0xCD50, 0x7095, 0xAAA1, + 0x7096, 0xCD57, 0x7098, 0xCD51, 0x7099, 0xAAA5, 0x709A, 0xCD59, + 0x709F, 0xCFAF, 0x70A1, 0xCFB3, 0x70A4, 0xACB7, 0x70A9, 0xCFB6, + 0x70AB, 0xACAF, 0x70AC, 0xACB2, 0x70AD, 0xACB4, 0x70AE, 0xACB6, + 0x70AF, 0xACB3, 0x70B0, 0xCFB2, 0x70B1, 0xCFB1, 0x70B3, 0xACB1, + 0x70B4, 0xCFB4, 0x70B5, 0xCFB5, 0x70B7, 0xCFAE, 0x70B8, 0xACB5, + 0x70BA, 0xACB0, 0x70BE, 0xCFB0, 0x70C5, 0xD277, 0x70C6, 0xD278, + 0x70C7, 0xD279, 0x70C8, 0xAF50, 0x70CA, 0xAF4C, 0x70CB, 0xD26E, + 0x70CD, 0xD276, 0x70CE, 0xD27B, 0x70CF, 0xAF51, 0x70D1, 0xD26C, + 0x70D2, 0xD272, 0x70D3, 0xD26B, 0x70D4, 0xD275, 0x70D7, 0xD271, + 0x70D8, 0xAF4D, 0x70D9, 0xAF4F, 0x70DA, 0xD27A, 0x70DC, 0xD26A, + 0x70DD, 0xD26D, 0x70DE, 0xD273, 0x70E0, 0xD274, 0x70E1, 0xD27C, + 0x70E2, 0xD270, 0x70E4, 0xAF4E, 0x70EF, 0xB26D, 0x70F0, 0xD64E, + 0x70F3, 0xD650, 0x70F4, 0xD64C, 0x70F6, 0xD658, 0x70F7, 0xD64A, + 0x70F8, 0xD657, 0x70F9, 0xB269, 0x70FA, 0xD648, 0x70FB, 0xDA5B, + 0x70FC, 0xD652, 0x70FD, 0xB26C, 0x70FF, 0xD653, 0x7100, 0xD656, + 0x7102, 0xD65A, 0x7104, 0xD64F, 0x7106, 0xD654, 0x7109, 0xB26A, + 0x710A, 0xB26B, 0x710B, 0xD659, 0x710C, 0xD64D, 0x710D, 0xD649, + 0x710E, 0xD65B, 0x7110, 0xD651, 0x7113, 0xD655, 0x7117, 0xD64B, + 0x7119, 0xB548, 0x711A, 0xB549, 0x711B, 0xDA65, 0x711C, 0xB54F, + 0x711E, 0xDA59, 0x711F, 0xDA62, 0x7120, 0xDA58, 0x7121, 0xB54C, + 0x7122, 0xDA60, 0x7123, 0xDA5E, 0x7125, 0xDA5F, 0x7126, 0xB54A, + 0x7128, 0xDA63, 0x712E, 0xDA5C, 0x712F, 0xDA5A, 0x7130, 0xB54B, + 0x7131, 0xDA5D, 0x7132, 0xDA61, 0x7136, 0xB54D, 0x713A, 0xDA64, + 0x7141, 0xDE70, 0x7142, 0xDE77, 0x7143, 0xDE79, 0x7144, 0xDEA1, + 0x7146, 0xB7DA, 0x7147, 0xDE6B, 0x7149, 0xB7D2, 0x714B, 0xDE7A, + 0x714C, 0xB7D7, 0x714D, 0xDEA2, 0x714E, 0xB7CE, 0x7150, 0xDE7D, + 0x7152, 0xDE6D, 0x7153, 0xDE7E, 0x7154, 0xDE6C, 0x7156, 0xB7DC, + 0x7158, 0xDE78, 0x7159, 0xB7CF, 0x715A, 0xDEA3, 0x715C, 0xB7D4, + 0x715D, 0xDE71, 0x715E, 0xB7D9, 0x715F, 0xDE7C, 0x7160, 0xDE6F, + 0x7161, 0xDE76, 0x7162, 0xDE72, 0x7163, 0xDE6E, 0x7164, 0xB7D1, + 0x7165, 0xB7D8, 0x7166, 0xB7D6, 0x7167, 0xB7D3, 0x7168, 0xB7DB, + 0x7169, 0xB7D0, 0x716A, 0xDE75, 0x716C, 0xB7D5, 0x716E, 0xB54E, + 0x7170, 0xDE7B, 0x7172, 0xDE73, 0x7178, 0xDE74, 0x717B, 0xE2C1, + 0x717D, 0xBAB4, 0x7180, 0xE2BD, 0x7181, 0xE2C3, 0x7182, 0xE2BF, + 0x7184, 0xBAB6, 0x7185, 0xE2BE, 0x7186, 0xE2C2, 0x7187, 0xE2BA, + 0x7189, 0xE2BC, 0x718A, 0xBAB5, 0x718F, 0xE2C0, 0x7190, 0xE2BB, + 0x7192, 0xBAB7, 0x7194, 0xBAB2, 0x7197, 0xE2C4, 0x7199, 0xBAB3, + 0x719A, 0xE667, 0x719B, 0xE664, 0x719C, 0xE670, 0x719D, 0xE66A, + 0x719E, 0xE66C, 0x719F, 0xBCF4, 0x71A0, 0xE666, 0x71A1, 0xE66E, + 0x71A4, 0xE66D, 0x71A5, 0xE66B, 0x71A7, 0xE671, 0x71A8, 0xBCF7, + 0x71A9, 0xE668, 0x71AA, 0xE66F, 0x71AC, 0xBCF5, 0x71AF, 0xE663, + 0x71B0, 0xE665, 0x71B1, 0xBCF6, 0x71B2, 0xE662, 0x71B3, 0xE672, + 0x71B5, 0xE669, 0x71B8, 0xEA4A, 0x71B9, 0xBF51, 0x71BC, 0xEA55, + 0x71BD, 0xEA53, 0x71BE, 0xBF4B, 0x71BF, 0xEA49, 0x71C0, 0xEA4C, + 0x71C1, 0xEA4D, 0x71C2, 0xEA48, 0x71C3, 0xBF55, 0x71C4, 0xBF56, + 0x71C5, 0xEA47, 0x71C6, 0xEA56, 0x71C7, 0xEA51, 0x71C8, 0xBF4F, + 0x71C9, 0xBF4C, 0x71CA, 0xEA50, 0x71CB, 0xEA4E, 0x71CE, 0xBF52, + 0x71CF, 0xEA52, 0x71D0, 0xBF4D, 0x71D2, 0xBF4E, 0x71D4, 0xEA4F, + 0x71D5, 0xBF50, 0x71D6, 0xEA4B, 0x71D8, 0xEA54, 0x71D9, 0xBF53, + 0x71DA, 0xEA57, 0x71DB, 0xEA58, 0x71DC, 0xBF54, 0x71DF, 0xC0E7, + 0x71E0, 0xC0EE, 0x71E1, 0xED5C, 0x71E2, 0xED62, 0x71E4, 0xED60, + 0x71E5, 0xC0EA, 0x71E6, 0xC0E9, 0x71E7, 0xC0E6, 0x71E8, 0xED5E, + 0x71EC, 0xC0EC, 0x71ED, 0xC0EB, 0x71EE, 0xC0E8, 0x71F0, 0xED61, + 0x71F1, 0xED5D, 0x71F2, 0xED5F, 0x71F4, 0xC0ED, 0x71F8, 0xC277, + 0x71F9, 0xEFFB, 0x71FB, 0xC274, 0x71FC, 0xC275, 0x71FD, 0xEFFD, + 0x71FE, 0xC276, 0x71FF, 0xEFFA, 0x7201, 0xEFF9, 0x7202, 0xF26C, + 0x7203, 0xEFFC, 0x7205, 0xF26D, 0x7206, 0xC37A, 0x7207, 0xF26B, + 0x720A, 0xF26A, 0x720C, 0xF269, 0x720D, 0xC37B, 0x7210, 0xC46C, + 0x7213, 0xF46A, 0x7214, 0xF46B, 0x7219, 0xF5DC, 0x721A, 0xF5DB, + 0x721B, 0xC4EA, 0x721D, 0xF5DA, 0x721E, 0xF6EC, 0x721F, 0xF6ED, + 0x7222, 0xF7E6, 0x7223, 0xF8B1, 0x7226, 0xF8F6, 0x7227, 0xF9BC, + 0x7228, 0xC679, 0x7229, 0xF9C6, 0x722A, 0xA4F6, 0x722C, 0xAAA6, + 0x722D, 0xAAA7, 0x7230, 0xACB8, 0x7235, 0xC0EF, 0x7236, 0xA4F7, + 0x7238, 0xAAA8, 0x7239, 0xAF52, 0x723A, 0xB7DD, 0x723B, 0xA4F8, + 0x723D, 0xB26E, 0x723E, 0xBAB8, 0x723F, 0xC962, 0x7241, 0xCFB7, + 0x7242, 0xD27D, 0x7244, 0xE2C5, 0x7246, 0xC0F0, 0x7247, 0xA4F9, + 0x7248, 0xAAA9, 0x7249, 0xCFB8, 0x724A, 0xCFB9, 0x724B, 0xDA66, + 0x724C, 0xB550, 0x724F, 0xDEA4, 0x7252, 0xB7DE, 0x7253, 0xE2C6, + 0x7256, 0xBCF8, 0x7258, 0xC37C, 0x7259, 0xA4FA, 0x725A, 0xDA67, + 0x725B, 0xA4FB, 0x725D, 0xA6C9, 0x725E, 0xCA42, 0x725F, 0xA6C8, + 0x7260, 0xA865, 0x7261, 0xA864, 0x7262, 0xA863, 0x7263, 0xCB60, + 0x7267, 0xAAAA, 0x7269, 0xAAAB, 0x726A, 0xCD5B, 0x726C, 0xCFBA, + 0x726E, 0xCFBD, 0x726F, 0xACBA, 0x7270, 0xCFBB, 0x7272, 0xACB9, + 0x7273, 0xCFBC, 0x7274, 0xACBB, 0x7276, 0xD2A2, 0x7277, 0xD2A1, + 0x7278, 0xD27E, 0x7279, 0xAF53, 0x727B, 0xD65D, 0x727C, 0xD65E, + 0x727D, 0xB26F, 0x727E, 0xD65C, 0x727F, 0xD65F, 0x7280, 0xB552, + 0x7281, 0xB270, 0x7284, 0xB551, 0x7285, 0xDA6B, 0x7286, 0xDA6A, + 0x7288, 0xDA68, 0x7289, 0xDA69, 0x728B, 0xDA6C, 0x728C, 0xDEA6, + 0x728D, 0xDEA5, 0x728E, 0xDEA9, 0x7290, 0xDEA8, 0x7291, 0xDEA7, + 0x7292, 0xBAB9, 0x7293, 0xE2C9, 0x7295, 0xE2C8, 0x7296, 0xBABA, + 0x7297, 0xE2C7, 0x7298, 0xE673, 0x729A, 0xE674, 0x729B, 0xBCF9, + 0x729D, 0xEA59, 0x729E, 0xEA5A, 0x72A1, 0xF272, 0x72A2, 0xC37D, + 0x72A3, 0xF271, 0x72A4, 0xF270, 0x72A5, 0xF26E, 0x72A6, 0xF26F, + 0x72A7, 0xC4EB, 0x72A8, 0xF46C, 0x72A9, 0xF6EE, 0x72AA, 0xF8F7, + 0x72AC, 0xA4FC, 0x72AE, 0xC9A5, 0x72AF, 0xA5C7, 0x72B0, 0xC9A6, + 0x72B4, 0xCA43, 0x72B5, 0xCA44, 0x72BA, 0xCB66, 0x72BD, 0xCB62, + 0x72BF, 0xCB61, 0x72C0, 0xAAAC, 0x72C1, 0xCB65, 0x72C2, 0xA867, + 0x72C3, 0xCB63, 0x72C4, 0xA866, 0x72C5, 0xCB67, 0x72C6, 0xCB64, + 0x72C9, 0xCD5F, 0x72CA, 0xCFBE, 0x72CB, 0xCD5D, 0x72CC, 0xCD64, + 0x72CE, 0xAAAD, 0x72D0, 0xAAB0, 0x72D1, 0xCD65, 0x72D2, 0xCD61, + 0x72D4, 0xCD62, 0x72D6, 0xCD5C, 0x72D7, 0xAAAF, 0x72D8, 0xCD5E, + 0x72D9, 0xAAAE, 0x72DA, 0xCD63, 0x72DC, 0xCD60, 0x72DF, 0xCFC2, + 0x72E0, 0xACBD, 0x72E1, 0xACBE, 0x72E3, 0xCFC5, 0x72E4, 0xCFBF, + 0x72E6, 0xCFC4, 0x72E8, 0xCFC0, 0x72E9, 0xACBC, 0x72EA, 0xCFC3, + 0x72EB, 0xCFC1, 0x72F3, 0xD2A8, 0x72F4, 0xD2A5, 0x72F6, 0xD2A7, + 0x72F7, 0xAF58, 0x72F8, 0xAF57, 0x72F9, 0xAF55, 0x72FA, 0xD2A4, + 0x72FB, 0xD2A9, 0x72FC, 0xAF54, 0x72FD, 0xAF56, 0x72FE, 0xD2A6, + 0x72FF, 0xD667, 0x7300, 0xD2A3, 0x7301, 0xD2AA, 0x7307, 0xD662, + 0x7308, 0xD666, 0x730A, 0xD665, 0x730B, 0xDA6E, 0x730C, 0xDA79, + 0x730F, 0xD668, 0x7311, 0xD663, 0x7312, 0xDA6D, 0x7313, 0xB274, + 0x7316, 0xB273, 0x7317, 0xD661, 0x7318, 0xD664, 0x7319, 0xB275, + 0x731B, 0xB272, 0x731C, 0xB271, 0x731D, 0xD660, 0x731E, 0xD669, + 0x7322, 0xDA70, 0x7323, 0xDA77, 0x7325, 0xB554, 0x7326, 0xDA76, + 0x7327, 0xDA73, 0x7329, 0xB556, 0x732D, 0xDA75, 0x7330, 0xDA6F, + 0x7331, 0xDA71, 0x7332, 0xDA74, 0x7333, 0xDA72, 0x7334, 0xB555, + 0x7335, 0xDA78, 0x7336, 0xB553, 0x7337, 0xB7DF, 0x733A, 0xDEAD, + 0x733B, 0xDEAC, 0x733C, 0xDEAA, 0x733E, 0xB7E2, 0x733F, 0xB7E1, + 0x7340, 0xDEAE, 0x7342, 0xDEAB, 0x7343, 0xE2CA, 0x7344, 0xBABB, + 0x7345, 0xB7E0, 0x7349, 0xDEB0, 0x734A, 0xDEAF, 0x734C, 0xE2CD, + 0x734D, 0xE2CB, 0x734E, 0xBCFA, 0x7350, 0xBABC, 0x7351, 0xE2CC, + 0x7352, 0xE676, 0x7357, 0xBCFB, 0x7358, 0xE675, 0x7359, 0xE67E, + 0x735A, 0xE67D, 0x735B, 0xE67B, 0x735D, 0xE67A, 0x735E, 0xE677, + 0x735F, 0xE678, 0x7360, 0xE679, 0x7361, 0xE67C, 0x7362, 0xE6A1, + 0x7365, 0xEA5F, 0x7366, 0xEA5C, 0x7367, 0xEA5D, 0x7368, 0xBF57, + 0x7369, 0xEA5B, 0x736A, 0xEA61, 0x736B, 0xEA60, 0x736C, 0xEA5E, + 0x736E, 0xED64, 0x736F, 0xED65, 0x7370, 0xC0F1, 0x7372, 0xC0F2, + 0x7373, 0xED63, 0x7375, 0xC279, 0x7376, 0xEFFE, 0x7377, 0xC278, + 0x7378, 0xC37E, 0x737A, 0xC3A1, 0x737B, 0xC46D, 0x737C, 0xF46E, + 0x737D, 0xF46D, 0x737E, 0xF5DD, 0x737F, 0xF6EF, 0x7380, 0xC57A, + 0x7381, 0xF7E8, 0x7382, 0xF7E7, 0x7383, 0xF7E9, 0x7384, 0xA5C8, + 0x7385, 0xCFC6, 0x7386, 0xAF59, 0x7387, 0xB276, 0x7388, 0xD66A, + 0x7389, 0xA5C9, 0x738A, 0xC9A7, 0x738B, 0xA4FD, 0x738E, 0xCA45, + 0x7392, 0xCB6C, 0x7393, 0xCB6A, 0x7394, 0xCB6B, 0x7395, 0xCB68, + 0x7396, 0xA868, 0x7397, 0xCB69, 0x739D, 0xCD6D, 0x739F, 0xAAB3, + 0x73A0, 0xCD6B, 0x73A1, 0xCD67, 0x73A2, 0xCD6A, 0x73A4, 0xCD66, + 0x73A5, 0xAAB5, 0x73A6, 0xCD69, 0x73A8, 0xAAB2, 0x73A9, 0xAAB1, + 0x73AB, 0xAAB4, 0x73AC, 0xCD6C, 0x73AD, 0xCD68, 0x73B2, 0xACC2, + 0x73B3, 0xACC5, 0x73B4, 0xCFCE, 0x73B5, 0xCFCD, 0x73B6, 0xCFCC, + 0x73B7, 0xACBF, 0x73B8, 0xCFD5, 0x73B9, 0xCFCB, 0x73BB, 0xACC1, + 0x73BC, 0xD2AF, 0x73BE, 0xCFD2, 0x73BF, 0xCFD0, 0x73C0, 0xACC4, + 0x73C2, 0xCFC8, 0x73C3, 0xCFD3, 0x73C5, 0xCFCA, 0x73C6, 0xCFD4, + 0x73C7, 0xCFD1, 0x73C8, 0xCFC9, 0x73CA, 0xACC0, 0x73CB, 0xCFD6, + 0x73CC, 0xCFC7, 0x73CD, 0xACC3, 0x73D2, 0xD2B4, 0x73D3, 0xD2AB, + 0x73D4, 0xD2B6, 0x73D6, 0xD2AE, 0x73D7, 0xD2B9, 0x73D8, 0xD2BA, + 0x73D9, 0xD2AC, 0x73DA, 0xD2B8, 0x73DB, 0xD2B5, 0x73DC, 0xD2B3, + 0x73DD, 0xD2B7, 0x73DE, 0xAF5F, 0x73E0, 0xAF5D, 0x73E3, 0xD2B1, + 0x73E5, 0xD2AD, 0x73E7, 0xD2B0, 0x73E8, 0xD2BB, 0x73E9, 0xD2B2, + 0x73EA, 0xAF5E, 0x73EB, 0xCFCF, 0x73ED, 0xAF5A, 0x73EE, 0xAF5C, + 0x73F4, 0xD678, 0x73F5, 0xD66D, 0x73F6, 0xD66B, 0x73F8, 0xD66C, + 0x73FA, 0xD673, 0x73FC, 0xD674, 0x73FD, 0xD670, 0x73FE, 0xB27B, + 0x73FF, 0xD675, 0x7400, 0xD672, 0x7401, 0xD66F, 0x7403, 0xB279, + 0x7404, 0xD66E, 0x7405, 0xB277, 0x7406, 0xB27A, 0x7407, 0xD671, + 0x7408, 0xD679, 0x7409, 0xAF5B, 0x740A, 0xB278, 0x740B, 0xD677, + 0x740C, 0xD676, 0x740D, 0xB27C, 0x7416, 0xDA7E, 0x741A, 0xDAA1, + 0x741B, 0xB560, 0x741D, 0xDAA7, 0x7420, 0xDAA9, 0x7421, 0xDAA2, + 0x7422, 0xB55A, 0x7423, 0xDAA6, 0x7424, 0xDAA5, 0x7425, 0xB55B, + 0x7426, 0xB561, 0x7428, 0xB562, 0x7429, 0xDAA8, 0x742A, 0xB558, + 0x742B, 0xDA7D, 0x742C, 0xDA7B, 0x742D, 0xDAA3, 0x742E, 0xDA7A, + 0x742F, 0xB55F, 0x7430, 0xDA7C, 0x7431, 0xDAA4, 0x7432, 0xDAAA, + 0x7433, 0xB559, 0x7434, 0xB55E, 0x7435, 0xB55C, 0x7436, 0xB55D, + 0x743A, 0xB557, 0x743F, 0xB7E9, 0x7440, 0xDEB7, 0x7441, 0xB7E8, + 0x7442, 0xDEBB, 0x7444, 0xDEB1, 0x7446, 0xDEBC, 0x744A, 0xDEB2, + 0x744B, 0xDEB3, 0x744D, 0xDEBD, 0x744E, 0xDEBA, 0x744F, 0xDEB8, + 0x7450, 0xDEB9, 0x7451, 0xDEB5, 0x7452, 0xDEB4, 0x7454, 0xDEBE, + 0x7455, 0xB7E5, 0x7457, 0xDEB6, 0x7459, 0xB7EA, 0x745A, 0xB7E4, + 0x745B, 0xB7EB, 0x745C, 0xB7EC, 0x745E, 0xB7E7, 0x745F, 0xB7E6, + 0x7462, 0xE2CE, 0x7463, 0xBABE, 0x7464, 0xBABD, 0x7467, 0xE2D3, + 0x7469, 0xBCFC, 0x746A, 0xBABF, 0x746D, 0xBAC1, 0x746E, 0xE2D4, + 0x746F, 0xB7E3, 0x7470, 0xBAC0, 0x7471, 0xE2D0, 0x7472, 0xE2D2, + 0x7473, 0xE2CF, 0x7475, 0xE2D1, 0x7479, 0xE6AB, 0x747C, 0xE6AA, + 0x747D, 0xE6A7, 0x747E, 0xBD40, 0x747F, 0xEA62, 0x7480, 0xBD41, + 0x7481, 0xE6A6, 0x7483, 0xBCFE, 0x7485, 0xE6A8, 0x7486, 0xE6A5, + 0x7487, 0xE6A2, 0x7488, 0xE6A9, 0x7489, 0xE6A3, 0x748A, 0xE6A4, + 0x748B, 0xBCFD, 0x7490, 0xED69, 0x7492, 0xEA66, 0x7494, 0xEA65, + 0x7495, 0xEA67, 0x7497, 0xED66, 0x7498, 0xBF5A, 0x749A, 0xEA63, + 0x749C, 0xBF58, 0x749E, 0xBF5C, 0x749F, 0xBF5B, 0x74A0, 0xEA64, + 0x74A1, 0xEA68, 0x74A3, 0xBF59, 0x74A5, 0xED6D, 0x74A6, 0xC0F5, + 0x74A7, 0xC27A, 0x74A8, 0xC0F6, 0x74A9, 0xC0F3, 0x74AA, 0xED6A, + 0x74AB, 0xED68, 0x74AD, 0xED6B, 0x74AF, 0xED6E, 0x74B0, 0xC0F4, + 0x74B1, 0xED6C, 0x74B2, 0xED67, 0x74B5, 0xF042, 0x74B6, 0xF045, + 0x74B7, 0xF275, 0x74B8, 0xF040, 0x74BA, 0xF46F, 0x74BB, 0xF046, + 0x74BD, 0xC3A2, 0x74BE, 0xF044, 0x74BF, 0xC27B, 0x74C0, 0xF041, + 0x74C1, 0xF043, 0x74C2, 0xF047, 0x74C3, 0xF276, 0x74C5, 0xF274, + 0x74CA, 0xC3A3, 0x74CB, 0xF273, 0x74CF, 0xC46E, 0x74D4, 0xC4ED, + 0x74D5, 0xF6F1, 0x74D6, 0xC4EC, 0x74D7, 0xF6F3, 0x74D8, 0xF6F0, + 0x74D9, 0xF6F2, 0x74DA, 0xC5D0, 0x74DB, 0xF8B2, 0x74DC, 0xA5CA, + 0x74DD, 0xCD6E, 0x74DE, 0xD2BC, 0x74DF, 0xD2BD, 0x74E0, 0xB27D, + 0x74E1, 0xDEBF, 0x74E2, 0xBF5D, 0x74E3, 0xC3A4, 0x74E4, 0xC57B, + 0x74E5, 0xF8B3, 0x74E6, 0xA5CB, 0x74E8, 0xCD6F, 0x74E9, 0xA260, + 0x74EC, 0xCFD7, 0x74EE, 0xCFD8, 0x74F4, 0xD2BE, 0x74F5, 0xD2BF, + 0x74F6, 0xB27E, 0x74F7, 0xB2A1, 0x74FB, 0xDAAB, 0x74FD, 0xDEC2, + 0x74FE, 0xDEC1, 0x74FF, 0xDEC0, 0x7500, 0xE2D5, 0x7502, 0xE2D6, + 0x7503, 0xE2D7, 0x7504, 0xBAC2, 0x7507, 0xE6AD, 0x7508, 0xE6AC, + 0x750B, 0xEA69, 0x750C, 0xBF5E, 0x750D, 0xBF5F, 0x750F, 0xED72, + 0x7510, 0xED6F, 0x7511, 0xED70, 0x7512, 0xED71, 0x7513, 0xF049, + 0x7514, 0xF048, 0x7515, 0xC27C, 0x7516, 0xF277, 0x7517, 0xF5DE, + 0x7518, 0xA5CC, 0x751A, 0xACC6, 0x751C, 0xB2A2, 0x751D, 0xDEC3, + 0x751F, 0xA5CD, 0x7521, 0xD2C0, 0x7522, 0xB2A3, 0x7525, 0xB563, + 0x7526, 0xB564, 0x7528, 0xA5CE, 0x7529, 0xA5CF, 0x752A, 0xCA46, + 0x752B, 0xA86A, 0x752C, 0xA869, 0x752D, 0xACC7, 0x752E, 0xCFD9, + 0x752F, 0xDAAC, 0x7530, 0xA5D0, 0x7531, 0xA5D1, 0x7532, 0xA5D2, + 0x7533, 0xA5D3, 0x7537, 0xA86B, 0x7538, 0xA86C, 0x7539, 0xCB6E, + 0x753A, 0xCB6D, 0x753D, 0xAAB6, 0x753E, 0xCD72, 0x753F, 0xCD70, + 0x7540, 0xCD71, 0x7547, 0xCFDA, 0x7548, 0xCFDB, 0x754B, 0xACCB, + 0x754C, 0xACC9, 0x754E, 0xACCA, 0x754F, 0xACC8, 0x7554, 0xAF60, + 0x7559, 0xAF64, 0x755A, 0xAF63, 0x755B, 0xD2C1, 0x755C, 0xAF62, + 0x755D, 0xAF61, 0x755F, 0xD2C2, 0x7562, 0xB2A6, 0x7563, 0xD67B, + 0x7564, 0xD67A, 0x7565, 0xB2A4, 0x7566, 0xB2A5, 0x756A, 0xB566, + 0x756B, 0xB565, 0x756C, 0xDAAE, 0x756F, 0xDAAD, 0x7570, 0xB2A7, + 0x7576, 0xB7ED, 0x7577, 0xDEC5, 0x7578, 0xB7EE, 0x7579, 0xDEC4, + 0x757D, 0xE2D8, 0x757E, 0xE6AE, 0x757F, 0xBD42, 0x7580, 0xEA6A, + 0x7584, 0xED73, 0x7586, 0xC3A6, 0x7587, 0xC3A5, 0x758A, 0xC57C, + 0x758B, 0xA5D4, 0x758C, 0xCD73, 0x758F, 0xB2A8, 0x7590, 0xE2D9, + 0x7591, 0xBAC3, 0x7594, 0xCB6F, 0x7595, 0xCB70, 0x7598, 0xCD74, + 0x7599, 0xAAB8, 0x759A, 0xAAB9, 0x759D, 0xAAB7, 0x75A2, 0xACCF, + 0x75A3, 0xACD0, 0x75A4, 0xACCD, 0x75A5, 0xACCE, 0x75A7, 0xCFDC, + 0x75AA, 0xCFDD, 0x75AB, 0xACCC, 0x75B0, 0xD2C3, 0x75B2, 0xAF68, + 0x75B3, 0xAF69, 0x75B5, 0xB2AB, 0x75B6, 0xD2C9, 0x75B8, 0xAF6E, + 0x75B9, 0xAF6C, 0x75BA, 0xD2CA, 0x75BB, 0xD2C5, 0x75BC, 0xAF6B, + 0x75BD, 0xAF6A, 0x75BE, 0xAF65, 0x75BF, 0xD2C8, 0x75C0, 0xD2C7, + 0x75C1, 0xD2C4, 0x75C2, 0xAF6D, 0x75C4, 0xD2C6, 0x75C5, 0xAF66, + 0x75C7, 0xAF67, 0x75CA, 0xB2AC, 0x75CB, 0xD6A1, 0x75CC, 0xD6A2, + 0x75CD, 0xB2AD, 0x75CE, 0xD67C, 0x75CF, 0xD67E, 0x75D0, 0xD6A4, + 0x75D1, 0xD6A3, 0x75D2, 0xD67D, 0x75D4, 0xB2A9, 0x75D5, 0xB2AA, + 0x75D7, 0xDAB6, 0x75D8, 0xB56B, 0x75D9, 0xB56A, 0x75DA, 0xDAB0, + 0x75DB, 0xB568, 0x75DD, 0xDAB3, 0x75DE, 0xB56C, 0x75DF, 0xDAB4, + 0x75E0, 0xB56D, 0x75E1, 0xDAB1, 0x75E2, 0xB567, 0x75E3, 0xB569, + 0x75E4, 0xDAB5, 0x75E6, 0xDAB2, 0x75E7, 0xDAAF, 0x75ED, 0xDED2, + 0x75EF, 0xDEC7, 0x75F0, 0xB7F0, 0x75F1, 0xB7F3, 0x75F2, 0xB7F2, + 0x75F3, 0xB7F7, 0x75F4, 0xB7F6, 0x75F5, 0xDED3, 0x75F6, 0xDED1, + 0x75F7, 0xDECA, 0x75F8, 0xDECE, 0x75F9, 0xDECD, 0x75FA, 0xB7F4, + 0x75FB, 0xDED0, 0x75FC, 0xDECC, 0x75FD, 0xDED4, 0x75FE, 0xDECB, + 0x75FF, 0xB7F5, 0x7600, 0xB7EF, 0x7601, 0xB7F1, 0x7603, 0xDEC9, + 0x7608, 0xE2DB, 0x7609, 0xBAC7, 0x760A, 0xE2DF, 0x760B, 0xBAC6, + 0x760C, 0xE2DC, 0x760D, 0xBAC5, 0x760F, 0xDEC8, 0x7610, 0xDECF, + 0x7611, 0xE2DE, 0x7613, 0xBAC8, 0x7614, 0xE2E0, 0x7615, 0xE2DD, + 0x7616, 0xE2DA, 0x7619, 0xE6B1, 0x761A, 0xE6B5, 0x761B, 0xE6B7, + 0x761C, 0xE6B3, 0x761D, 0xE6B2, 0x761E, 0xE6B0, 0x761F, 0xBD45, + 0x7620, 0xBD43, 0x7621, 0xBD48, 0x7622, 0xBD49, 0x7623, 0xE6B4, + 0x7624, 0xBD46, 0x7625, 0xE6AF, 0x7626, 0xBD47, 0x7627, 0xBAC4, + 0x7628, 0xE6B6, 0x7629, 0xBD44, 0x762D, 0xEA6C, 0x762F, 0xEA6B, + 0x7630, 0xEA73, 0x7631, 0xEA6D, 0x7632, 0xEA72, 0x7633, 0xEA6F, + 0x7634, 0xBF60, 0x7635, 0xEA71, 0x7638, 0xBF61, 0x763A, 0xBF62, + 0x763C, 0xEA70, 0x763D, 0xEA6E, 0x7642, 0xC0F8, 0x7643, 0xED74, + 0x7646, 0xC0F7, 0x7647, 0xED77, 0x7648, 0xED75, 0x7649, 0xED76, + 0x764C, 0xC0F9, 0x7650, 0xF04D, 0x7652, 0xC2A1, 0x7653, 0xF04E, + 0x7656, 0xC27D, 0x7657, 0xF04F, 0x7658, 0xC27E, 0x7659, 0xF04C, + 0x765A, 0xF050, 0x765C, 0xF04A, 0x765F, 0xC3A7, 0x7660, 0xF278, + 0x7661, 0xC3A8, 0x7662, 0xC46F, 0x7664, 0xF04B, 0x7665, 0xC470, + 0x7669, 0xC4EE, 0x766A, 0xF5DF, 0x766C, 0xC57E, 0x766D, 0xF6F4, + 0x766E, 0xC57D, 0x7670, 0xF7EA, 0x7671, 0xC5F5, 0x7672, 0xC5F6, + 0x7675, 0xF9CC, 0x7678, 0xACD1, 0x7679, 0xCFDE, 0x767B, 0xB56E, + 0x767C, 0xB56F, 0x767D, 0xA5D5, 0x767E, 0xA6CA, 0x767F, 0xCA47, + 0x7681, 0xCB71, 0x7682, 0xA86D, 0x7684, 0xAABA, 0x7686, 0xACD2, + 0x7687, 0xACD3, 0x7688, 0xACD4, 0x7689, 0xD6A6, 0x768A, 0xD2CB, + 0x768B, 0xAF6F, 0x768E, 0xB2AE, 0x768F, 0xD6A5, 0x7692, 0xDAB8, + 0x7693, 0xB571, 0x7695, 0xDAB7, 0x7696, 0xB570, 0x7699, 0xDED5, + 0x769A, 0xBD4A, 0x769B, 0xE6BB, 0x769C, 0xE6B8, 0x769D, 0xE6B9, + 0x769E, 0xE6BA, 0x76A4, 0xED78, 0x76A6, 0xF051, 0x76AA, 0xF471, + 0x76AB, 0xF470, 0x76AD, 0xF6F5, 0x76AE, 0xA5D6, 0x76AF, 0xCD75, + 0x76B0, 0xAF70, 0x76B4, 0xB572, 0x76B5, 0xDED6, 0x76B8, 0xE2E1, + 0x76BA, 0xBD4B, 0x76BB, 0xEA74, 0x76BD, 0xF052, 0x76BE, 0xF472, + 0x76BF, 0xA5D7, 0x76C2, 0xAABB, 0x76C3, 0xACD7, 0x76C4, 0xCFDF, + 0x76C5, 0xACD8, 0x76C6, 0xACD6, 0x76C8, 0xACD5, 0x76C9, 0xD2CC, + 0x76CA, 0xAF71, 0x76CD, 0xAF72, 0x76CE, 0xAF73, 0x76D2, 0xB2B0, + 0x76D3, 0xD6A7, 0x76D4, 0xB2AF, 0x76DA, 0xDAB9, 0x76DB, 0xB2B1, + 0x76DC, 0xB573, 0x76DD, 0xDED7, 0x76DE, 0xB7F8, 0x76DF, 0xB7F9, + 0x76E1, 0xBAC9, 0x76E3, 0xBACA, 0x76E4, 0xBD4C, 0x76E5, 0xBF64, + 0x76E6, 0xEA75, 0x76E7, 0xBF63, 0x76E9, 0xED79, 0x76EA, 0xC0FA, + 0x76EC, 0xF053, 0x76ED, 0xF473, 0x76EE, 0xA5D8, 0x76EF, 0xA86E, + 0x76F0, 0xCD78, 0x76F1, 0xCD77, 0x76F2, 0xAABC, 0x76F3, 0xCD76, + 0x76F4, 0xAABD, 0x76F5, 0xCD79, 0x76F7, 0xCFE5, 0x76F8, 0xACDB, + 0x76F9, 0xACDA, 0x76FA, 0xCFE7, 0x76FB, 0xCFE6, 0x76FC, 0xACDF, + 0x76FE, 0xACDE, 0x7701, 0xACD9, 0x7703, 0xCFE1, 0x7704, 0xCFE2, + 0x7705, 0xCFE3, 0x7707, 0xACE0, 0x7708, 0xCFE0, 0x7709, 0xACDC, + 0x770A, 0xCFE4, 0x770B, 0xACDD, 0x7710, 0xD2CF, 0x7711, 0xD2D3, + 0x7712, 0xD2D1, 0x7713, 0xD2D0, 0x7715, 0xD2D4, 0x7719, 0xD2D5, + 0x771A, 0xD2D6, 0x771B, 0xD2CE, 0x771D, 0xD2CD, 0x771F, 0xAF75, + 0x7720, 0xAF76, 0x7722, 0xD2D7, 0x7723, 0xD2D2, 0x7725, 0xD6B0, + 0x7727, 0xD2D8, 0x7728, 0xAF77, 0x7729, 0xAF74, 0x772D, 0xD6AA, + 0x772F, 0xD6A9, 0x7731, 0xD6AB, 0x7732, 0xD6AC, 0x7733, 0xD6AE, + 0x7734, 0xD6AD, 0x7735, 0xD6B2, 0x7736, 0xB2B5, 0x7737, 0xB2B2, + 0x7738, 0xB2B6, 0x7739, 0xD6A8, 0x773A, 0xB2B7, 0x773B, 0xD6B1, + 0x773C, 0xB2B4, 0x773D, 0xD6AF, 0x773E, 0xB2B3, 0x7744, 0xDABC, + 0x7745, 0xDABE, 0x7746, 0xDABA, 0x7747, 0xDABB, 0x774A, 0xDABF, + 0x774B, 0xDAC1, 0x774C, 0xDAC2, 0x774D, 0xDABD, 0x774E, 0xDAC0, + 0x774F, 0xB574, 0x7752, 0xDEDB, 0x7754, 0xDEE0, 0x7755, 0xDED8, + 0x7756, 0xDEDC, 0x7759, 0xDEE1, 0x775A, 0xDEDD, 0x775B, 0xB7FA, + 0x775C, 0xB843, 0x775E, 0xB7FD, 0x775F, 0xDED9, 0x7760, 0xDEDA, + 0x7761, 0xBACE, 0x7762, 0xB846, 0x7763, 0xB7FE, 0x7765, 0xB844, + 0x7766, 0xB7FC, 0x7767, 0xDEDF, 0x7768, 0xB845, 0x7769, 0xDEDE, + 0x776A, 0xB841, 0x776B, 0xB7FB, 0x776C, 0xB842, 0x776D, 0xDEE2, + 0x776E, 0xE2E6, 0x776F, 0xE2E8, 0x7779, 0xB840, 0x777C, 0xE2E3, + 0x777D, 0xBACC, 0x777E, 0xE2E9, 0x777F, 0xBACD, 0x7780, 0xE2E7, + 0x7781, 0xE2E2, 0x7782, 0xE2E5, 0x7783, 0xE2EA, 0x7784, 0xBACB, + 0x7785, 0xE2E4, 0x7787, 0xBD4E, 0x7788, 0xE6BF, 0x7789, 0xE6BE, + 0x778B, 0xBD51, 0x778C, 0xBD4F, 0x778D, 0xE6BC, 0x778E, 0xBD4D, + 0x778F, 0xE6BD, 0x7791, 0xBD50, 0x7795, 0xEA7D, 0x7797, 0xEAA1, + 0x7799, 0xEA7E, 0x779A, 0xEA76, 0x779B, 0xEA7A, 0x779C, 0xEA79, + 0x779D, 0xEA77, 0x779E, 0xBF66, 0x779F, 0xBF67, 0x77A0, 0xBF65, + 0x77A1, 0xEA78, 0x77A2, 0xEA7B, 0x77A3, 0xEA7C, 0x77A5, 0xBF68, + 0x77A7, 0xC140, 0x77A8, 0xEDA3, 0x77AA, 0xC0FC, 0x77AB, 0xED7B, + 0x77AC, 0xC0FE, 0x77AD, 0xC141, 0x77B0, 0xC0FD, 0x77B1, 0xEDA2, + 0x77B2, 0xED7C, 0x77B3, 0xC0FB, 0x77B4, 0xEDA1, 0x77B5, 0xED7A, + 0x77B6, 0xED7E, 0x77B7, 0xED7D, 0x77BA, 0xF055, 0x77BB, 0xC2A4, + 0x77BC, 0xC2A5, 0x77BD, 0xC2A2, 0x77BF, 0xC2A3, 0x77C2, 0xF054, + 0x77C4, 0xF27B, 0x77C7, 0xC3A9, 0x77C9, 0xF279, 0x77CA, 0xF27A, + 0x77CC, 0xF474, 0x77CD, 0xF477, 0x77CE, 0xF475, 0x77CF, 0xF476, + 0x77D0, 0xF5E0, 0x77D3, 0xC4EF, 0x77D4, 0xF7EB, 0x77D5, 0xF8B4, + 0x77D7, 0xC5F7, 0x77D8, 0xF8F8, 0x77D9, 0xF8F9, 0x77DA, 0xC666, + 0x77DB, 0xA5D9, 0x77DC, 0xACE1, 0x77DE, 0xDAC3, 0x77E0, 0xDEE3, + 0x77E2, 0xA5DA, 0x77E3, 0xA86F, 0x77E5, 0xAABE, 0x77E7, 0xCFE8, + 0x77E8, 0xCFE9, 0x77E9, 0xAF78, 0x77EC, 0xDAC4, 0x77ED, 0xB575, + 0x77EE, 0xB847, 0x77EF, 0xC142, 0x77F0, 0xEDA4, 0x77F1, 0xF27C, + 0x77F2, 0xF478, 0x77F3, 0xA5DB, 0x77F7, 0xCDA1, 0x77F8, 0xCD7A, + 0x77F9, 0xCD7C, 0x77FA, 0xCD7E, 0x77FB, 0xCD7D, 0x77FC, 0xCD7B, + 0x77FD, 0xAABF, 0x7802, 0xACE2, 0x7803, 0xCFF2, 0x7805, 0xCFED, + 0x7806, 0xCFEA, 0x7809, 0xCFF1, 0x780C, 0xACE4, 0x780D, 0xACE5, + 0x780E, 0xCFF0, 0x780F, 0xCFEF, 0x7810, 0xCFEE, 0x7811, 0xCFEB, + 0x7812, 0xCFEC, 0x7813, 0xCFF3, 0x7814, 0xACE3, 0x781D, 0xAF7C, + 0x781F, 0xAFA4, 0x7820, 0xAFA3, 0x7821, 0xD2E1, 0x7822, 0xD2DB, + 0x7823, 0xD2D9, 0x7825, 0xAFA1, 0x7826, 0xD6B9, 0x7827, 0xAF7A, + 0x7828, 0xD2DE, 0x7829, 0xD2E2, 0x782A, 0xD2E4, 0x782B, 0xD2E0, + 0x782C, 0xD2DA, 0x782D, 0xAFA2, 0x782E, 0xD2DF, 0x782F, 0xD2DD, + 0x7830, 0xAF79, 0x7831, 0xD2E5, 0x7832, 0xAFA5, 0x7833, 0xD2E3, + 0x7834, 0xAF7D, 0x7835, 0xD2DC, 0x7837, 0xAF7E, 0x7838, 0xAF7B, + 0x7843, 0xB2B9, 0x7845, 0xD6BA, 0x7848, 0xD6B3, 0x7849, 0xD6B5, + 0x784A, 0xD6B7, 0x784C, 0xD6B8, 0x784D, 0xD6B6, 0x784E, 0xB2BA, + 0x7850, 0xD6BB, 0x7852, 0xD6B4, 0x785C, 0xDAC8, 0x785D, 0xB576, + 0x785E, 0xDAD0, 0x7860, 0xDAC5, 0x7862, 0xDAD1, 0x7864, 0xDAC6, + 0x7865, 0xDAC7, 0x7868, 0xDACF, 0x7869, 0xDACE, 0x786A, 0xDACB, + 0x786B, 0xB2B8, 0x786C, 0xB577, 0x786D, 0xDAC9, 0x786E, 0xDACC, + 0x786F, 0xB578, 0x7870, 0xDACD, 0x7871, 0xDACA, 0x7879, 0xDEEE, + 0x787B, 0xDEF2, 0x787C, 0xB84E, 0x787E, 0xE2F0, 0x787F, 0xB851, + 0x7880, 0xDEF0, 0x7881, 0xF9D6, 0x7883, 0xDEED, 0x7884, 0xDEE8, + 0x7885, 0xDEEA, 0x7886, 0xDEEB, 0x7887, 0xDEE4, 0x7889, 0xB84D, + 0x788C, 0xB84C, 0x788E, 0xB848, 0x788F, 0xDEE7, 0x7891, 0xB84F, + 0x7893, 0xB850, 0x7894, 0xDEE6, 0x7895, 0xDEE9, 0x7896, 0xDEF1, + 0x7897, 0xB84A, 0x7898, 0xB84B, 0x7899, 0xDEEF, 0x789A, 0xDEE5, + 0x789E, 0xE2F2, 0x789F, 0xBAD0, 0x78A0, 0xE2F4, 0x78A1, 0xDEEC, + 0x78A2, 0xE2F6, 0x78A3, 0xBAD4, 0x78A4, 0xE2F7, 0x78A5, 0xE2F3, + 0x78A7, 0xBAD1, 0x78A8, 0xE2EF, 0x78A9, 0xBAD3, 0x78AA, 0xE2EC, + 0x78AB, 0xE2F1, 0x78AC, 0xE2F5, 0x78AD, 0xE2EE, 0x78B0, 0xB849, + 0x78B2, 0xE2EB, 0x78B3, 0xBAD2, 0x78B4, 0xE2ED, 0x78BA, 0xBD54, + 0x78BB, 0xE6C1, 0x78BC, 0xBD58, 0x78BE, 0xBD56, 0x78C1, 0xBACF, + 0x78C3, 0xE6C8, 0x78C4, 0xE6C9, 0x78C5, 0xBD53, 0x78C8, 0xE6C7, + 0x78C9, 0xE6CA, 0x78CA, 0xBD55, 0x78CB, 0xBD52, 0x78CC, 0xE6C3, + 0x78CD, 0xE6C0, 0x78CE, 0xE6C5, 0x78CF, 0xE6C2, 0x78D0, 0xBD59, + 0x78D1, 0xE6C4, 0x78D4, 0xE6C6, 0x78D5, 0xBD57, 0x78DA, 0xBF6A, + 0x78DB, 0xEAA8, 0x78DD, 0xEAA2, 0x78DE, 0xEAA6, 0x78DF, 0xEAAC, + 0x78E0, 0xEAAD, 0x78E1, 0xEAA9, 0x78E2, 0xEAAA, 0x78E3, 0xEAA7, + 0x78E5, 0xEAA4, 0x78E7, 0xBF6C, 0x78E8, 0xBF69, 0x78E9, 0xEAA3, + 0x78EA, 0xEAA5, 0x78EC, 0xBF6B, 0x78ED, 0xEAAB, 0x78EF, 0xC146, + 0x78F2, 0xEDAA, 0x78F3, 0xEDA5, 0x78F4, 0xC145, 0x78F7, 0xC143, + 0x78F9, 0xEDAC, 0x78FA, 0xC144, 0x78FB, 0xEDA8, 0x78FC, 0xEDA9, + 0x78FD, 0xEDA6, 0x78FE, 0xEDAD, 0x78FF, 0xF056, 0x7901, 0xC147, + 0x7902, 0xEDA7, 0x7904, 0xEDAE, 0x7905, 0xEDAB, 0x7909, 0xF05A, + 0x790C, 0xF057, 0x790E, 0xC2A6, 0x7910, 0xF05B, 0x7911, 0xF05D, + 0x7912, 0xF05C, 0x7913, 0xF058, 0x7914, 0xF059, 0x7917, 0xF2A3, + 0x7919, 0xC3AA, 0x791B, 0xF27E, 0x791C, 0xF2A2, 0x791D, 0xF27D, + 0x791E, 0xF2A4, 0x7921, 0xF2A1, 0x7923, 0xF47A, 0x7924, 0xF47D, + 0x7925, 0xF479, 0x7926, 0xC471, 0x7927, 0xF47B, 0x7928, 0xF47C, + 0x7929, 0xF47E, 0x792A, 0xC472, 0x792B, 0xC474, 0x792C, 0xC473, + 0x792D, 0xF5E1, 0x792F, 0xF5E3, 0x7931, 0xF5E2, 0x7935, 0xF6F6, + 0x7938, 0xF8B5, 0x7939, 0xF8FA, 0x793A, 0xA5DC, 0x793D, 0xCB72, + 0x793E, 0xAAC0, 0x793F, 0xCDA3, 0x7940, 0xAAC1, 0x7941, 0xAAC2, + 0x7942, 0xCDA2, 0x7944, 0xCFF8, 0x7945, 0xCFF7, 0x7946, 0xACE6, + 0x7947, 0xACE9, 0x7948, 0xACE8, 0x7949, 0xACE7, 0x794A, 0xCFF4, + 0x794B, 0xCFF6, 0x794C, 0xCFF5, 0x794F, 0xD2E8, 0x7950, 0xAFA7, + 0x7951, 0xD2EC, 0x7952, 0xD2EB, 0x7953, 0xD2EA, 0x7954, 0xD2E6, + 0x7955, 0xAFA6, 0x7956, 0xAFAA, 0x7957, 0xAFAD, 0x795A, 0xAFAE, + 0x795B, 0xD2E7, 0x795C, 0xD2E9, 0x795D, 0xAFAC, 0x795E, 0xAFAB, + 0x795F, 0xAFA9, 0x7960, 0xAFA8, 0x7961, 0xD6C2, 0x7963, 0xD6C0, + 0x7964, 0xD6BC, 0x7965, 0xB2BB, 0x7967, 0xD6BD, 0x7968, 0xB2BC, + 0x7969, 0xD6BE, 0x796A, 0xD6BF, 0x796B, 0xD6C1, 0x796D, 0xB2BD, + 0x7970, 0xDAD5, 0x7972, 0xDAD4, 0x7973, 0xDAD3, 0x7974, 0xDAD2, + 0x7979, 0xDEF6, 0x797A, 0xB852, 0x797C, 0xDEF3, 0x797D, 0xDEF5, + 0x797F, 0xB853, 0x7981, 0xB854, 0x7982, 0xDEF4, 0x7988, 0xE341, + 0x798A, 0xE2F9, 0x798B, 0xE2FA, 0x798D, 0xBAD7, 0x798E, 0xBAD5, + 0x798F, 0xBAD6, 0x7990, 0xE343, 0x7992, 0xE342, 0x7993, 0xE2FE, + 0x7994, 0xE2FD, 0x7995, 0xE2FC, 0x7996, 0xE2FB, 0x7997, 0xE340, + 0x7998, 0xE2F8, 0x799A, 0xE6CB, 0x799B, 0xE6D0, 0x799C, 0xE6CE, + 0x79A0, 0xE6CD, 0x79A1, 0xE6CC, 0x79A2, 0xE6CF, 0x79A4, 0xEAAE, + 0x79A6, 0xBF6D, 0x79A7, 0xC148, 0x79A8, 0xEDB0, 0x79AA, 0xC149, + 0x79AB, 0xEDAF, 0x79AC, 0xF05F, 0x79AD, 0xF05E, 0x79AE, 0xC2A7, + 0x79B0, 0xF2A5, 0x79B1, 0xC3AB, 0x79B2, 0xF4A1, 0x79B3, 0xC5A1, + 0x79B4, 0xF6F7, 0x79B6, 0xF8B7, 0x79B7, 0xF8B6, 0x79B8, 0xC9A8, + 0x79B9, 0xACEA, 0x79BA, 0xACEB, 0x79BB, 0xD6C3, 0x79BD, 0xB856, + 0x79BE, 0xA5DD, 0x79BF, 0xA872, 0x79C0, 0xA871, 0x79C1, 0xA870, + 0x79C5, 0xCDA4, 0x79C8, 0xAAC4, 0x79C9, 0xAAC3, 0x79CB, 0xACEE, + 0x79CD, 0xCFFA, 0x79CE, 0xCFFD, 0x79CF, 0xCFFB, 0x79D1, 0xACEC, + 0x79D2, 0xACED, 0x79D5, 0xCFF9, 0x79D6, 0xCFFC, 0x79D8, 0xAFB5, + 0x79DC, 0xD2F3, 0x79DD, 0xD2F5, 0x79DE, 0xD2F4, 0x79DF, 0xAFB2, + 0x79E0, 0xD2EF, 0x79E3, 0xAFB0, 0x79E4, 0xAFAF, 0x79E6, 0xAFB3, + 0x79E7, 0xAFB1, 0x79E9, 0xAFB4, 0x79EA, 0xD2F2, 0x79EB, 0xD2ED, + 0x79EC, 0xD2EE, 0x79ED, 0xD2F1, 0x79EE, 0xD2F0, 0x79F6, 0xD6C6, + 0x79F7, 0xD6C7, 0x79F8, 0xD6C5, 0x79FA, 0xD6C4, 0x79FB, 0xB2BE, + 0x7A00, 0xB57D, 0x7A02, 0xDAD6, 0x7A03, 0xDAD8, 0x7A04, 0xDADA, + 0x7A05, 0xB57C, 0x7A08, 0xB57A, 0x7A0A, 0xDAD7, 0x7A0B, 0xB57B, + 0x7A0C, 0xDAD9, 0x7A0D, 0xB579, 0x7A10, 0xDF41, 0x7A11, 0xDEF7, + 0x7A12, 0xDEFA, 0x7A13, 0xDEFE, 0x7A14, 0xB85A, 0x7A15, 0xDEFC, + 0x7A17, 0xDEFB, 0x7A18, 0xDEF8, 0x7A19, 0xDEF9, 0x7A1A, 0xB858, + 0x7A1B, 0xDF40, 0x7A1C, 0xB857, 0x7A1E, 0xB85C, 0x7A1F, 0xB85B, + 0x7A20, 0xB859, 0x7A22, 0xDEFD, 0x7A26, 0xE349, 0x7A28, 0xE348, + 0x7A2B, 0xE344, 0x7A2E, 0xBAD8, 0x7A2F, 0xE347, 0x7A30, 0xE346, + 0x7A31, 0xBAD9, 0x7A37, 0xBD5E, 0x7A39, 0xE6D2, 0x7A3B, 0xBD5F, + 0x7A3C, 0xBD5B, 0x7A3D, 0xBD5D, 0x7A3F, 0xBD5A, 0x7A40, 0xBD5C, + 0x7A44, 0xEAAF, 0x7A46, 0xBF70, 0x7A47, 0xEAB1, 0x7A48, 0xEAB0, + 0x7A4A, 0xE345, 0x7A4B, 0xBF72, 0x7A4C, 0xBF71, 0x7A4D, 0xBF6E, + 0x7A4E, 0xBF6F, 0x7A54, 0xEDB5, 0x7A56, 0xEDB3, 0x7A57, 0xC14A, + 0x7A58, 0xEDB4, 0x7A5A, 0xEDB6, 0x7A5B, 0xEDB2, 0x7A5C, 0xEDB1, + 0x7A5F, 0xF060, 0x7A60, 0xC2AA, 0x7A61, 0xC2A8, 0x7A62, 0xC2A9, + 0x7A67, 0xF2A6, 0x7A68, 0xF2A7, 0x7A69, 0xC3AD, 0x7A6B, 0xC3AC, + 0x7A6C, 0xF4A3, 0x7A6D, 0xF4A4, 0x7A6E, 0xF4A2, 0x7A70, 0xF6F8, + 0x7A71, 0xF6F9, 0x7A74, 0xA5DE, 0x7A75, 0xCA48, 0x7A76, 0xA873, + 0x7A78, 0xCDA5, 0x7A79, 0xAAC6, 0x7A7A, 0xAAC5, 0x7A7B, 0xCDA6, + 0x7A7E, 0xD040, 0x7A7F, 0xACEF, 0x7A80, 0xCFFE, 0x7A81, 0xACF0, + 0x7A84, 0xAFB6, 0x7A85, 0xD2F8, 0x7A86, 0xD2F6, 0x7A87, 0xD2FC, + 0x7A88, 0xAFB7, 0x7A89, 0xD2F7, 0x7A8A, 0xD2FB, 0x7A8B, 0xD2F9, + 0x7A8C, 0xD2FA, 0x7A8F, 0xD6C8, 0x7A90, 0xD6CA, 0x7A92, 0xB2BF, + 0x7A94, 0xD6C9, 0x7A95, 0xB2C0, 0x7A96, 0xB5A2, 0x7A97, 0xB5A1, + 0x7A98, 0xB57E, 0x7A99, 0xDADB, 0x7A9E, 0xDF44, 0x7A9F, 0xB85D, + 0x7AA0, 0xB85E, 0x7AA2, 0xDF43, 0x7AA3, 0xDF42, 0x7AA8, 0xE34A, + 0x7AA9, 0xBADB, 0x7AAA, 0xBADA, 0x7AAB, 0xE34B, 0x7AAC, 0xE34C, + 0x7AAE, 0xBD61, 0x7AAF, 0xBD60, 0x7AB1, 0xEAB5, 0x7AB2, 0xE6D3, + 0x7AB3, 0xE6D5, 0x7AB4, 0xE6D4, 0x7AB5, 0xEAB4, 0x7AB6, 0xEAB2, + 0x7AB7, 0xEAB6, 0x7AB8, 0xEAB3, 0x7ABA, 0xBF73, 0x7ABE, 0xEDB7, + 0x7ABF, 0xC14B, 0x7AC0, 0xEDB8, 0x7AC1, 0xEDB9, 0x7AC4, 0xC2AB, + 0x7AC5, 0xC2AC, 0x7AC7, 0xC475, 0x7ACA, 0xC5D1, 0x7ACB, 0xA5DF, + 0x7AD1, 0xD041, 0x7AD8, 0xD2FD, 0x7AD9, 0xAFB8, 0x7ADF, 0xB3BA, + 0x7AE0, 0xB3B9, 0x7AE3, 0xB5A4, 0x7AE4, 0xDADD, 0x7AE5, 0xB5A3, + 0x7AE6, 0xDADC, 0x7AEB, 0xDF45, 0x7AED, 0xBADC, 0x7AEE, 0xE34D, + 0x7AEF, 0xBADD, 0x7AF6, 0xC476, 0x7AF7, 0xF4A5, 0x7AF9, 0xA6CB, + 0x7AFA, 0xAAC7, 0x7AFB, 0xCDA7, 0x7AFD, 0xACF2, 0x7AFF, 0xACF1, + 0x7B00, 0xD042, 0x7B01, 0xD043, 0x7B04, 0xD340, 0x7B05, 0xD342, + 0x7B06, 0xAFB9, 0x7B08, 0xD344, 0x7B09, 0xD347, 0x7B0A, 0xD345, + 0x7B0E, 0xD346, 0x7B0F, 0xD343, 0x7B10, 0xD2FE, 0x7B11, 0xAFBA, + 0x7B12, 0xD348, 0x7B13, 0xD341, 0x7B18, 0xD6D3, 0x7B19, 0xB2C6, + 0x7B1A, 0xD6DC, 0x7B1B, 0xB2C3, 0x7B1D, 0xD6D5, 0x7B1E, 0xB2C7, + 0x7B20, 0xB2C1, 0x7B22, 0xD6D0, 0x7B23, 0xD6DD, 0x7B24, 0xD6D1, + 0x7B25, 0xD6CE, 0x7B26, 0xB2C5, 0x7B28, 0xB2C2, 0x7B2A, 0xD6D4, + 0x7B2B, 0xD6D7, 0x7B2C, 0xB2C4, 0x7B2D, 0xD6D8, 0x7B2E, 0xB2C8, + 0x7B2F, 0xD6D9, 0x7B30, 0xD6CF, 0x7B31, 0xD6D6, 0x7B32, 0xD6DA, + 0x7B33, 0xD6D2, 0x7B34, 0xD6CD, 0x7B35, 0xD6CB, 0x7B38, 0xD6DB, + 0x7B3B, 0xDADF, 0x7B40, 0xDAE4, 0x7B44, 0xDAE0, 0x7B45, 0xDAE6, + 0x7B46, 0xB5A7, 0x7B47, 0xD6CC, 0x7B48, 0xDAE1, 0x7B49, 0xB5A5, + 0x7B4A, 0xDADE, 0x7B4B, 0xB5AC, 0x7B4C, 0xDAE2, 0x7B4D, 0xB5AB, + 0x7B4E, 0xDAE3, 0x7B4F, 0xB5AD, 0x7B50, 0xB5A8, 0x7B51, 0xB5AE, + 0x7B52, 0xB5A9, 0x7B54, 0xB5AA, 0x7B56, 0xB5A6, 0x7B58, 0xDAE5, + 0x7B60, 0xB861, 0x7B61, 0xDF50, 0x7B63, 0xDF53, 0x7B64, 0xDF47, + 0x7B65, 0xDF4C, 0x7B66, 0xDF46, 0x7B67, 0xB863, 0x7B69, 0xDF4A, + 0x7B6D, 0xDF48, 0x7B6E, 0xB862, 0x7B70, 0xDF4F, 0x7B71, 0xDF4E, + 0x7B72, 0xDF4B, 0x7B73, 0xDF4D, 0x7B74, 0xDF49, 0x7B75, 0xBAE1, + 0x7B76, 0xDF52, 0x7B77, 0xB85F, 0x7B78, 0xDF51, 0x7B82, 0xE35D, + 0x7B84, 0xBAE8, 0x7B85, 0xE358, 0x7B87, 0xBAE7, 0x7B88, 0xE34E, + 0x7B8A, 0xE350, 0x7B8B, 0xBAE0, 0x7B8C, 0xE355, 0x7B8D, 0xE354, + 0x7B8E, 0xE357, 0x7B8F, 0xBAE5, 0x7B90, 0xE352, 0x7B91, 0xE351, + 0x7B94, 0xBAE4, 0x7B95, 0xBADF, 0x7B96, 0xE353, 0x7B97, 0xBAE2, + 0x7B98, 0xE359, 0x7B99, 0xE35B, 0x7B9B, 0xE356, 0x7B9C, 0xE34F, + 0x7B9D, 0xBAE3, 0x7BA0, 0xBD69, 0x7BA1, 0xBADE, 0x7BA4, 0xE35C, + 0x7BAC, 0xE6D9, 0x7BAD, 0xBD62, 0x7BAF, 0xE6DB, 0x7BB1, 0xBD63, + 0x7BB4, 0xBD65, 0x7BB5, 0xE6DE, 0x7BB7, 0xE6D6, 0x7BB8, 0xBAE6, + 0x7BB9, 0xE6DC, 0x7BBE, 0xE6D8, 0x7BC0, 0xB860, 0x7BC1, 0xBD68, + 0x7BC4, 0xBD64, 0x7BC6, 0xBD66, 0x7BC7, 0xBD67, 0x7BC9, 0xBF76, + 0x7BCA, 0xE6DD, 0x7BCB, 0xE6D7, 0x7BCC, 0xBD6A, 0x7BCE, 0xE6DA, + 0x7BD4, 0xEAC0, 0x7BD5, 0xEABB, 0x7BD8, 0xEAC5, 0x7BD9, 0xBF74, + 0x7BDA, 0xEABD, 0x7BDB, 0xBF78, 0x7BDC, 0xEAC3, 0x7BDD, 0xEABA, + 0x7BDE, 0xEAB7, 0x7BDF, 0xEAC6, 0x7BE0, 0xC151, 0x7BE1, 0xBF79, + 0x7BE2, 0xEAC2, 0x7BE3, 0xEAB8, 0x7BE4, 0xBF77, 0x7BE5, 0xEABC, + 0x7BE6, 0xBF7B, 0x7BE7, 0xEAB9, 0x7BE8, 0xEABE, 0x7BE9, 0xBF7A, + 0x7BEA, 0xEAC1, 0x7BEB, 0xEAC4, 0x7BF0, 0xEDCB, 0x7BF1, 0xEDCC, + 0x7BF2, 0xEDBC, 0x7BF3, 0xEDC3, 0x7BF4, 0xEDC1, 0x7BF7, 0xC14F, + 0x7BF8, 0xEDC8, 0x7BF9, 0xEABF, 0x7BFB, 0xEDBF, 0x7BFD, 0xEDC9, + 0x7BFE, 0xC14E, 0x7BFF, 0xEDBE, 0x7C00, 0xEDBD, 0x7C01, 0xEDC7, + 0x7C02, 0xEDC4, 0x7C03, 0xEDC6, 0x7C05, 0xEDBA, 0x7C06, 0xEDCA, + 0x7C07, 0xC14C, 0x7C09, 0xEDC5, 0x7C0A, 0xEDCE, 0x7C0B, 0xEDC2, + 0x7C0C, 0xC150, 0x7C0D, 0xC14D, 0x7C0E, 0xEDC0, 0x7C0F, 0xEDBB, + 0x7C10, 0xEDCD, 0x7C11, 0xBF75, 0x7C19, 0xF063, 0x7C1C, 0xF061, + 0x7C1D, 0xF067, 0x7C1E, 0xC2B0, 0x7C1F, 0xF065, 0x7C20, 0xF064, + 0x7C21, 0xC2B2, 0x7C22, 0xF06A, 0x7C23, 0xC2B1, 0x7C25, 0xF06B, + 0x7C26, 0xF068, 0x7C27, 0xC2AE, 0x7C28, 0xF069, 0x7C29, 0xF062, + 0x7C2A, 0xC2AF, 0x7C2B, 0xC2AD, 0x7C2C, 0xF2AB, 0x7C2D, 0xF066, + 0x7C30, 0xF06C, 0x7C33, 0xF2A8, 0x7C37, 0xC3B2, 0x7C38, 0xC3B0, + 0x7C39, 0xF2AA, 0x7C3B, 0xF2AC, 0x7C3C, 0xF2A9, 0x7C3D, 0xC3B1, + 0x7C3E, 0xC3AE, 0x7C3F, 0xC3AF, 0x7C40, 0xC3B3, 0x7C43, 0xC478, + 0x7C45, 0xF4AA, 0x7C47, 0xF4A9, 0x7C48, 0xF4A7, 0x7C49, 0xF4A6, + 0x7C4A, 0xF4A8, 0x7C4C, 0xC477, 0x7C4D, 0xC479, 0x7C50, 0xC4F0, + 0x7C53, 0xF5E5, 0x7C54, 0xF5E4, 0x7C57, 0xF6FA, 0x7C59, 0xF6FC, + 0x7C5A, 0xF6FE, 0x7C5B, 0xF6FD, 0x7C5C, 0xF6FB, 0x7C5F, 0xC5A3, + 0x7C60, 0xC5A2, 0x7C63, 0xC5D3, 0x7C64, 0xC5D2, 0x7C65, 0xC5D4, + 0x7C66, 0xF7ED, 0x7C67, 0xF7EC, 0x7C69, 0xF8FB, 0x7C6A, 0xF8B8, + 0x7C6B, 0xF8FC, 0x7C6C, 0xC658, 0x7C6E, 0xC659, 0x7C6F, 0xF96D, + 0x7C72, 0xC67E, 0x7C73, 0xA6CC, 0x7C75, 0xCDA8, 0x7C78, 0xD045, + 0x7C79, 0xD046, 0x7C7A, 0xD044, 0x7C7D, 0xACF3, 0x7C7F, 0xD047, + 0x7C80, 0xD048, 0x7C81, 0xD049, 0x7C84, 0xD349, 0x7C85, 0xD34F, + 0x7C88, 0xD34D, 0x7C89, 0xAFBB, 0x7C8A, 0xD34B, 0x7C8C, 0xD34C, + 0x7C8D, 0xD34E, 0x7C91, 0xD34A, 0x7C92, 0xB2C9, 0x7C94, 0xD6DE, + 0x7C95, 0xB2CB, 0x7C96, 0xD6E0, 0x7C97, 0xB2CA, 0x7C98, 0xD6DF, + 0x7C9E, 0xDAE8, 0x7C9F, 0xB5AF, 0x7CA1, 0xDAEA, 0x7CA2, 0xDAE7, + 0x7CA3, 0xD6E1, 0x7CA5, 0xB5B0, 0x7CA7, 0xF9DB, 0x7CA8, 0xDAE9, + 0x7CAF, 0xDF56, 0x7CB1, 0xB864, 0x7CB2, 0xDF54, 0x7CB3, 0xB865, + 0x7CB4, 0xDF55, 0x7CB5, 0xB866, 0x7CB9, 0xBAE9, 0x7CBA, 0xE361, + 0x7CBB, 0xE35E, 0x7CBC, 0xE360, 0x7CBD, 0xBAEA, 0x7CBE, 0xBAEB, + 0x7CBF, 0xE35F, 0x7CC5, 0xE6DF, 0x7CC8, 0xE6E0, 0x7CCA, 0xBD6B, + 0x7CCB, 0xE6E2, 0x7CCC, 0xE6E1, 0x7CCE, 0xA261, 0x7CD0, 0xEACA, + 0x7CD1, 0xEACB, 0x7CD2, 0xEAC7, 0x7CD4, 0xEAC8, 0x7CD5, 0xBF7C, + 0x7CD6, 0xBF7D, 0x7CD7, 0xEAC9, 0x7CD9, 0xC157, 0x7CDC, 0xC153, + 0x7CDD, 0xC158, 0x7CDE, 0xC154, 0x7CDF, 0xC156, 0x7CE0, 0xC152, + 0x7CE2, 0xC155, 0x7CE7, 0xC2B3, 0x7CE8, 0xEDCF, 0x7CEA, 0xF2AE, + 0x7CEC, 0xF2AD, 0x7CEE, 0xF4AB, 0x7CEF, 0xC47A, 0x7CF0, 0xC47B, + 0x7CF1, 0xF741, 0x7CF2, 0xF5E6, 0x7CF4, 0xF740, 0x7CF6, 0xF8FD, + 0x7CF7, 0xF9A4, 0x7CF8, 0xA6CD, 0x7CFB, 0xA874, 0x7CFD, 0xCDA9, + 0x7CFE, 0xAAC8, 0x7D00, 0xACF6, 0x7D01, 0xD04C, 0x7D02, 0xACF4, + 0x7D03, 0xD04A, 0x7D04, 0xACF9, 0x7D05, 0xACF5, 0x7D06, 0xACFA, + 0x7D07, 0xACF8, 0x7D08, 0xD04B, 0x7D09, 0xACF7, 0x7D0A, 0xAFBF, + 0x7D0B, 0xAFBE, 0x7D0C, 0xD35A, 0x7D0D, 0xAFC7, 0x7D0E, 0xD353, + 0x7D0F, 0xD359, 0x7D10, 0xAFC3, 0x7D11, 0xD352, 0x7D12, 0xD358, + 0x7D13, 0xD356, 0x7D14, 0xAFC2, 0x7D15, 0xAFC4, 0x7D16, 0xD355, + 0x7D17, 0xAFBD, 0x7D18, 0xD354, 0x7D19, 0xAFC8, 0x7D1A, 0xAFC5, + 0x7D1B, 0xAFC9, 0x7D1C, 0xAFC6, 0x7D1D, 0xD351, 0x7D1E, 0xD350, + 0x7D1F, 0xD357, 0x7D20, 0xAFC0, 0x7D21, 0xAFBC, 0x7D22, 0xAFC1, + 0x7D28, 0xD6F0, 0x7D29, 0xD6E9, 0x7D2B, 0xB5B5, 0x7D2C, 0xD6E8, + 0x7D2E, 0xB2CF, 0x7D2F, 0xB2D6, 0x7D30, 0xB2D3, 0x7D31, 0xB2D9, + 0x7D32, 0xB2D8, 0x7D33, 0xB2D4, 0x7D35, 0xD6E2, 0x7D36, 0xD6E5, + 0x7D38, 0xD6E4, 0x7D39, 0xB2D0, 0x7D3A, 0xD6E6, 0x7D3B, 0xD6EF, + 0x7D3C, 0xB2D1, 0x7D3D, 0xD6E3, 0x7D3E, 0xD6EC, 0x7D3F, 0xD6ED, + 0x7D40, 0xB2D2, 0x7D41, 0xD6EA, 0x7D42, 0xB2D7, 0x7D43, 0xB2CD, + 0x7D44, 0xB2D5, 0x7D45, 0xD6E7, 0x7D46, 0xB2CC, 0x7D47, 0xD6EB, + 0x7D4A, 0xD6EE, 0x7D4E, 0xDAFB, 0x7D4F, 0xDAF2, 0x7D50, 0xB5B2, + 0x7D51, 0xDAF9, 0x7D52, 0xDAF6, 0x7D53, 0xDAEE, 0x7D54, 0xDAF7, + 0x7D55, 0xB5B4, 0x7D56, 0xDAEF, 0x7D58, 0xDAEB, 0x7D5B, 0xB86C, + 0x7D5C, 0xDAF4, 0x7D5E, 0xB5B1, 0x7D5F, 0xDAFA, 0x7D61, 0xB5B8, + 0x7D62, 0xB5BA, 0x7D63, 0xDAED, 0x7D66, 0xB5B9, 0x7D67, 0xDAF0, + 0x7D68, 0xB5B3, 0x7D69, 0xDAF8, 0x7D6A, 0xDAF1, 0x7D6B, 0xDAF5, + 0x7D6D, 0xDAF3, 0x7D6E, 0xB5B6, 0x7D6F, 0xDAEC, 0x7D70, 0xB5BB, + 0x7D71, 0xB2CE, 0x7D72, 0xB5B7, 0x7D73, 0xB5BC, 0x7D79, 0xB868, + 0x7D7A, 0xDF5D, 0x7D7B, 0xDF5F, 0x7D7C, 0xDF61, 0x7D7D, 0xDF65, + 0x7D7F, 0xDF5B, 0x7D80, 0xDF59, 0x7D81, 0xB86A, 0x7D83, 0xDF60, + 0x7D84, 0xDF64, 0x7D85, 0xDF5C, 0x7D86, 0xDF58, 0x7D88, 0xDF57, + 0x7D8C, 0xDF62, 0x7D8D, 0xDF5A, 0x7D8E, 0xDF5E, 0x7D8F, 0xB86B, + 0x7D91, 0xB869, 0x7D92, 0xDF66, 0x7D93, 0xB867, 0x7D94, 0xDF63, + 0x7D96, 0xE372, 0x7D9C, 0xBAEE, 0x7D9D, 0xE36A, 0x7D9E, 0xBD78, + 0x7D9F, 0xE374, 0x7DA0, 0xBAF1, 0x7DA1, 0xE378, 0x7DA2, 0xBAF7, + 0x7DA3, 0xE365, 0x7DA6, 0xE375, 0x7DA7, 0xE362, 0x7DA9, 0xE377, + 0x7DAA, 0xE366, 0x7DAC, 0xBAFE, 0x7DAD, 0xBAFB, 0x7DAE, 0xE376, + 0x7DAF, 0xE370, 0x7DB0, 0xBAED, 0x7DB1, 0xBAF5, 0x7DB2, 0xBAF4, + 0x7DB4, 0xBAF3, 0x7DB5, 0xBAF9, 0x7DB7, 0xE363, 0x7DB8, 0xBAFA, + 0x7DB9, 0xE371, 0x7DBA, 0xBAF6, 0x7DBB, 0xBAEC, 0x7DBC, 0xE373, + 0x7DBD, 0xBAEF, 0x7DBE, 0xBAF0, 0x7DBF, 0xBAF8, 0x7DC0, 0xE368, + 0x7DC1, 0xE367, 0x7DC2, 0xE364, 0x7DC4, 0xE36C, 0x7DC5, 0xE369, + 0x7DC6, 0xE36D, 0x7DC7, 0xBAFD, 0x7DC9, 0xE379, 0x7DCA, 0xBAF2, + 0x7DCB, 0xE36E, 0x7DCC, 0xE36F, 0x7DCE, 0xE36B, 0x7DD2, 0xBAFC, + 0x7DD7, 0xE6E7, 0x7DD8, 0xBD70, 0x7DD9, 0xBD79, 0x7DDA, 0xBD75, + 0x7DDB, 0xE6E4, 0x7DDD, 0xBD72, 0x7DDE, 0xBD76, 0x7DDF, 0xE6F0, + 0x7DE0, 0xBD6C, 0x7DE1, 0xE6E8, 0x7DE3, 0xBD74, 0x7DE6, 0xE6EB, + 0x7DE7, 0xE6E6, 0x7DE8, 0xBD73, 0x7DE9, 0xBD77, 0x7DEA, 0xE6E5, + 0x7DEC, 0xBD71, 0x7DEE, 0xE6EF, 0x7DEF, 0xBD6E, 0x7DF0, 0xE6EE, + 0x7DF1, 0xE6ED, 0x7DF2, 0xBD7A, 0x7DF3, 0xE572, 0x7DF4, 0xBD6D, + 0x7DF6, 0xE6EC, 0x7DF7, 0xE6E3, 0x7DF9, 0xBD7B, 0x7DFA, 0xE6EA, + 0x7DFB, 0xBD6F, 0x7E03, 0xE6E9, 0x7E08, 0xBFA2, 0x7E09, 0xBFA7, + 0x7E0A, 0xBF7E, 0x7E0B, 0xEAD8, 0x7E0C, 0xEACF, 0x7E0D, 0xEADB, + 0x7E0E, 0xEAD3, 0x7E0F, 0xEAD9, 0x7E10, 0xBFA8, 0x7E11, 0xBFA1, + 0x7E12, 0xEACC, 0x7E13, 0xEAD2, 0x7E14, 0xEADC, 0x7E15, 0xEAD5, + 0x7E16, 0xEADA, 0x7E17, 0xEACE, 0x7E1A, 0xEAD6, 0x7E1B, 0xBFA3, + 0x7E1C, 0xEAD4, 0x7E1D, 0xBFA6, 0x7E1E, 0xBFA5, 0x7E1F, 0xEAD0, + 0x7E20, 0xEAD1, 0x7E21, 0xEACD, 0x7E22, 0xEAD7, 0x7E23, 0xBFA4, + 0x7E24, 0xEADE, 0x7E25, 0xEADD, 0x7E29, 0xEDDA, 0x7E2A, 0xEDD6, + 0x7E2B, 0xC15F, 0x7E2D, 0xEDD0, 0x7E2E, 0xC159, 0x7E2F, 0xC169, + 0x7E30, 0xEDDC, 0x7E31, 0xC161, 0x7E32, 0xC15D, 0x7E33, 0xEDD3, + 0x7E34, 0xC164, 0x7E35, 0xC167, 0x7E36, 0xEDDE, 0x7E37, 0xC15C, + 0x7E38, 0xEDD5, 0x7E39, 0xC165, 0x7E3A, 0xEDE0, 0x7E3B, 0xEDDD, + 0x7E3C, 0xEDD1, 0x7E3D, 0xC160, 0x7E3E, 0xC15A, 0x7E3F, 0xC168, + 0x7E40, 0xEDD8, 0x7E41, 0xC163, 0x7E42, 0xEDD2, 0x7E43, 0xC15E, + 0x7E44, 0xEDDF, 0x7E45, 0xC162, 0x7E46, 0xC15B, 0x7E47, 0xEDD9, + 0x7E48, 0xC166, 0x7E49, 0xEDD7, 0x7E4C, 0xEDDB, 0x7E50, 0xF06E, + 0x7E51, 0xF074, 0x7E52, 0xC2B9, 0x7E53, 0xF077, 0x7E54, 0xC2B4, + 0x7E55, 0xC2B5, 0x7E56, 0xF06F, 0x7E57, 0xF076, 0x7E58, 0xF071, + 0x7E59, 0xC2BA, 0x7E5A, 0xC2B7, 0x7E5C, 0xF06D, 0x7E5E, 0xC2B6, + 0x7E5F, 0xF073, 0x7E60, 0xF075, 0x7E61, 0xC2B8, 0x7E62, 0xF072, + 0x7E63, 0xF070, 0x7E68, 0xF2B8, 0x7E69, 0xC3B7, 0x7E6A, 0xC3B8, + 0x7E6B, 0xC3B4, 0x7E6D, 0xC3B5, 0x7E6F, 0xF2B4, 0x7E70, 0xF2B2, + 0x7E72, 0xF2B6, 0x7E73, 0xC3BA, 0x7E74, 0xF2B7, 0x7E75, 0xF2B0, + 0x7E76, 0xF2AF, 0x7E77, 0xF2B3, 0x7E78, 0xF2B1, 0x7E79, 0xC3B6, + 0x7E7A, 0xF2B5, 0x7E7B, 0xF4AC, 0x7E7C, 0xC47E, 0x7E7D, 0xC47D, + 0x7E7E, 0xF4AD, 0x7E80, 0xF4AF, 0x7E81, 0xF4AE, 0x7E82, 0xC4A1, + 0x7E86, 0xF5EB, 0x7E87, 0xF5E8, 0x7E88, 0xF5E9, 0x7E8A, 0xF5E7, + 0x7E8B, 0xF5EA, 0x7E8C, 0xC4F2, 0x7E8D, 0xF5EC, 0x7E8F, 0xC4F1, + 0x7E91, 0xF742, 0x7E93, 0xC5D5, 0x7E94, 0xC5D7, 0x7E95, 0xF7EE, + 0x7E96, 0xC5D6, 0x7E97, 0xF8B9, 0x7E98, 0xF940, 0x7E99, 0xF942, + 0x7E9A, 0xF8FE, 0x7E9B, 0xF941, 0x7E9C, 0xC66C, 0x7F36, 0xA6CE, + 0x7F38, 0xACFB, 0x7F39, 0xD26F, 0x7F3A, 0xAFCA, 0x7F3D, 0xB2DA, + 0x7F3E, 0xDAFC, 0x7F3F, 0xDAFD, 0x7F43, 0xEADF, 0x7F44, 0xC16A, + 0x7F45, 0xEDE1, 0x7F48, 0xC2BB, 0x7F4A, 0xF2BA, 0x7F4B, 0xF2B9, + 0x7F4C, 0xC4A2, 0x7F4D, 0xF5ED, 0x7F4F, 0xF743, 0x7F50, 0xC5F8, + 0x7F51, 0xCA49, 0x7F54, 0xAAC9, 0x7F55, 0xA875, 0x7F58, 0xD04D, + 0x7F5B, 0xD360, 0x7F5C, 0xD35B, 0x7F5D, 0xD35F, 0x7F5E, 0xD35D, + 0x7F5F, 0xAFCB, 0x7F60, 0xD35E, 0x7F61, 0xD35C, 0x7F63, 0xD6F1, + 0x7F65, 0xDAFE, 0x7F66, 0xDB40, 0x7F67, 0xDF69, 0x7F68, 0xDF6A, + 0x7F69, 0xB86E, 0x7F6A, 0xB86F, 0x7F6B, 0xDF68, 0x7F6C, 0xDF6B, + 0x7F6D, 0xDF67, 0x7F6E, 0xB86D, 0x7F70, 0xBB40, 0x7F72, 0xB870, + 0x7F73, 0xE37A, 0x7F75, 0xBD7C, 0x7F76, 0xE6F1, 0x7F77, 0xBD7D, + 0x7F79, 0xBFA9, 0x7F7A, 0xEAE2, 0x7F7B, 0xEAE0, 0x7F7C, 0xEAE1, + 0x7F7D, 0xEDE4, 0x7F7E, 0xEDE3, 0x7F7F, 0xEDE2, 0x7F83, 0xF2BB, + 0x7F85, 0xC3B9, 0x7F86, 0xF2BC, 0x7F87, 0xF744, 0x7F88, 0xC5F9, + 0x7F89, 0xF8BA, 0x7F8A, 0xA6CF, 0x7F8B, 0xAACB, 0x7F8C, 0xAACA, + 0x7F8D, 0xD04F, 0x7F8E, 0xACFC, 0x7F91, 0xD04E, 0x7F92, 0xD362, + 0x7F94, 0xAFCC, 0x7F95, 0xD6F2, 0x7F96, 0xD361, 0x7F9A, 0xB2DC, + 0x7F9B, 0xD6F5, 0x7F9C, 0xD6F3, 0x7F9D, 0xD6F4, 0x7F9E, 0xB2DB, + 0x7FA0, 0xDB42, 0x7FA1, 0xDB43, 0x7FA2, 0xDB41, 0x7FA4, 0xB873, + 0x7FA5, 0xDF6D, 0x7FA6, 0xDF6C, 0x7FA7, 0xDF6E, 0x7FA8, 0xB872, + 0x7FA9, 0xB871, 0x7FAC, 0xE6F2, 0x7FAD, 0xE6F4, 0x7FAF, 0xBD7E, + 0x7FB0, 0xE6F3, 0x7FB1, 0xEAE3, 0x7FB2, 0xBFAA, 0x7FB3, 0xF079, + 0x7FB5, 0xF078, 0x7FB6, 0xC3BB, 0x7FB7, 0xF2BD, 0x7FB8, 0xC3BD, + 0x7FB9, 0xC3BC, 0x7FBA, 0xF4B0, 0x7FBB, 0xF5EE, 0x7FBC, 0xC4F3, + 0x7FBD, 0xA6D0, 0x7FBE, 0xD050, 0x7FBF, 0xACFD, 0x7FC0, 0xD365, + 0x7FC1, 0xAFCE, 0x7FC2, 0xD364, 0x7FC3, 0xD363, 0x7FC5, 0xAFCD, + 0x7FC7, 0xD6FB, 0x7FC9, 0xD6FD, 0x7FCA, 0xD6F6, 0x7FCB, 0xD6F7, + 0x7FCC, 0xB2DD, 0x7FCD, 0xD6F8, 0x7FCE, 0xB2DE, 0x7FCF, 0xD6FC, + 0x7FD0, 0xD6F9, 0x7FD1, 0xD6FA, 0x7FD2, 0xB2DF, 0x7FD4, 0xB5BE, + 0x7FD5, 0xB5BF, 0x7FD7, 0xDB44, 0x7FDB, 0xDF6F, 0x7FDC, 0xDF70, + 0x7FDE, 0xE37E, 0x7FDF, 0xBB43, 0x7FE0, 0xBB41, 0x7FE1, 0xBB42, + 0x7FE2, 0xE37B, 0x7FE3, 0xE37C, 0x7FE5, 0xE37D, 0x7FE6, 0xE6F9, + 0x7FE8, 0xE6FA, 0x7FE9, 0xBDA1, 0x7FEA, 0xE6F7, 0x7FEB, 0xE6F6, + 0x7FEC, 0xE6F8, 0x7FED, 0xE6F5, 0x7FEE, 0xBFAD, 0x7FEF, 0xEAE4, + 0x7FF0, 0xBFAB, 0x7FF1, 0xBFAC, 0x7FF2, 0xEDE6, 0x7FF3, 0xC16B, + 0x7FF4, 0xEDE5, 0x7FF5, 0xEFA8, 0x7FF7, 0xF07A, 0x7FF8, 0xF07B, + 0x7FF9, 0xC2BC, 0x7FFB, 0xC2BD, 0x7FFC, 0xC16C, 0x7FFD, 0xF2BE, + 0x7FFE, 0xF2BF, 0x7FFF, 0xF4B1, 0x8000, 0xC4A3, 0x8001, 0xA6D1, + 0x8003, 0xA6D2, 0x8004, 0xACFE, 0x8005, 0xAACC, 0x8006, 0xAFCF, + 0x8007, 0xD051, 0x800B, 0xB5C0, 0x800C, 0xA6D3, 0x800D, 0xAD41, + 0x800E, 0xD052, 0x800F, 0xD053, 0x8010, 0xAD40, 0x8011, 0xAD42, + 0x8012, 0xA6D4, 0x8014, 0xD054, 0x8015, 0xAFD1, 0x8016, 0xD366, + 0x8017, 0xAFD3, 0x8018, 0xAFD0, 0x8019, 0xAFD2, 0x801B, 0xD741, + 0x801C, 0xB2E0, 0x801E, 0xD740, 0x801F, 0xD6FE, 0x8021, 0xDF71, + 0x8024, 0xE3A1, 0x8026, 0xBDA2, 0x8028, 0xBFAE, 0x8029, 0xEAE6, + 0x802A, 0xEAE5, 0x802C, 0xEDE7, 0x8030, 0xF5EF, 0x8033, 0xA6D5, + 0x8034, 0xCB73, 0x8035, 0xCDAA, 0x8036, 0xAD43, 0x8037, 0xD055, + 0x8039, 0xD368, 0x803D, 0xAFD4, 0x803E, 0xD367, 0x803F, 0xAFD5, + 0x8043, 0xD743, 0x8046, 0xB2E2, 0x8047, 0xD742, 0x8048, 0xD744, + 0x804A, 0xB2E1, 0x804F, 0xDB46, 0x8050, 0xDB47, 0x8051, 0xDB45, + 0x8052, 0xB5C1, 0x8056, 0xB874, 0x8058, 0xB875, 0x805A, 0xBB45, + 0x805C, 0xE3A3, 0x805D, 0xE3A2, 0x805E, 0xBB44, 0x8064, 0xE6FB, + 0x8067, 0xE6FC, 0x806C, 0xEAE7, 0x806F, 0xC170, 0x8070, 0xC16F, + 0x8071, 0xC16D, 0x8072, 0xC16E, 0x8073, 0xC171, 0x8075, 0xF07C, + 0x8076, 0xC2BF, 0x8077, 0xC2BE, 0x8078, 0xF2C0, 0x8079, 0xF4B2, + 0x807D, 0xC5A5, 0x807E, 0xC5A4, 0x807F, 0xA6D6, 0x8082, 0xD1FB, + 0x8084, 0xB877, 0x8085, 0xB5C2, 0x8086, 0xB876, 0x8087, 0xBB46, + 0x8089, 0xA6D7, 0x808A, 0xC9A9, 0x808B, 0xA6D8, 0x808C, 0xA6D9, + 0x808F, 0xCDAB, 0x8090, 0xCB76, 0x8092, 0xCB77, 0x8093, 0xA877, + 0x8095, 0xCB74, 0x8096, 0xA876, 0x8098, 0xA879, 0x8099, 0xCB75, + 0x809A, 0xA87B, 0x809B, 0xA87A, 0x809C, 0xCB78, 0x809D, 0xA878, + 0x80A1, 0xAAD1, 0x80A2, 0xAACF, 0x80A3, 0xCDAD, 0x80A5, 0xAACE, + 0x80A9, 0xAAD3, 0x80AA, 0xAAD5, 0x80AB, 0xAAD2, 0x80AD, 0xCDB0, + 0x80AE, 0xCDAC, 0x80AF, 0xAAD6, 0x80B1, 0xAAD0, 0x80B2, 0xA87C, + 0x80B4, 0xAAD4, 0x80B5, 0xCDAF, 0x80B8, 0xCDAE, 0x80BA, 0xAACD, + 0x80C2, 0xD05B, 0x80C3, 0xAD47, 0x80C4, 0xAD48, 0x80C5, 0xD05D, + 0x80C7, 0xD057, 0x80C8, 0xD05A, 0x80C9, 0xD063, 0x80CA, 0xD061, + 0x80CC, 0xAD49, 0x80CD, 0xD067, 0x80CE, 0xAD4C, 0x80CF, 0xD064, + 0x80D0, 0xD05C, 0x80D1, 0xD059, 0x80D4, 0xDB49, 0x80D5, 0xD062, + 0x80D6, 0xAD44, 0x80D7, 0xD065, 0x80D8, 0xD056, 0x80D9, 0xD05F, + 0x80DA, 0xAD46, 0x80DB, 0xAD4B, 0x80DC, 0xD060, 0x80DD, 0xAD4F, + 0x80DE, 0xAD4D, 0x80E0, 0xD058, 0x80E1, 0xAD4A, 0x80E3, 0xD05E, + 0x80E4, 0xAD4E, 0x80E5, 0xAD45, 0x80E6, 0xD066, 0x80ED, 0xAFDA, + 0x80EF, 0xAFE3, 0x80F0, 0xAFD8, 0x80F1, 0xAFD6, 0x80F2, 0xD36A, + 0x80F3, 0xAFDE, 0x80F4, 0xAFDB, 0x80F5, 0xD36C, 0x80F8, 0xAFDD, + 0x80F9, 0xD36B, 0x80FA, 0xD369, 0x80FB, 0xD36E, 0x80FC, 0xAFE2, + 0x80FD, 0xAFE0, 0x80FE, 0xDB48, 0x8100, 0xD36F, 0x8101, 0xD36D, + 0x8102, 0xAFD7, 0x8105, 0xAFD9, 0x8106, 0xAFDC, 0x8108, 0xAFDF, + 0x810A, 0xAFE1, 0x8115, 0xD74E, 0x8116, 0xB2E4, 0x8118, 0xD745, + 0x8119, 0xD747, 0x811B, 0xD748, 0x811D, 0xD750, 0x811E, 0xD74C, + 0x811F, 0xD74A, 0x8121, 0xD74D, 0x8122, 0xD751, 0x8123, 0xB2E5, + 0x8124, 0xB2E9, 0x8125, 0xD746, 0x8127, 0xD74F, 0x8129, 0xB2E7, + 0x812B, 0xB2E6, 0x812C, 0xD74B, 0x812D, 0xD749, 0x812F, 0xB2E3, + 0x8130, 0xB2E8, 0x8139, 0xB5C8, 0x813A, 0xDB51, 0x813D, 0xDB4F, + 0x813E, 0xB5CA, 0x8143, 0xDB4A, 0x8144, 0xDFA1, 0x8146, 0xB5C9, + 0x8147, 0xDB4E, 0x814A, 0xDB4B, 0x814B, 0xB5C5, 0x814C, 0xB5CB, + 0x814D, 0xDB50, 0x814E, 0xB5C7, 0x814F, 0xDB4D, 0x8150, 0xBB47, + 0x8151, 0xB5C6, 0x8152, 0xDB4C, 0x8153, 0xB5CC, 0x8154, 0xB5C4, + 0x8155, 0xB5C3, 0x815B, 0xDF77, 0x815C, 0xDF75, 0x815E, 0xDF7B, + 0x8160, 0xDF73, 0x8161, 0xDFA2, 0x8162, 0xDF78, 0x8164, 0xDF72, + 0x8165, 0xB87B, 0x8166, 0xB8A3, 0x8167, 0xDF7D, 0x8169, 0xDF76, + 0x816B, 0xB87E, 0x816E, 0xB87C, 0x816F, 0xDF7E, 0x8170, 0xB879, + 0x8171, 0xB878, 0x8172, 0xDF79, 0x8173, 0xB87D, 0x8174, 0xB5CD, + 0x8176, 0xDF7C, 0x8177, 0xDF74, 0x8178, 0xB87A, 0x8179, 0xB8A1, + 0x817A, 0xB8A2, 0x817F, 0xBB4C, 0x8180, 0xBB48, 0x8182, 0xBB4D, + 0x8183, 0xE3A6, 0x8186, 0xE3A5, 0x8187, 0xE3A7, 0x8188, 0xBB4A, + 0x8189, 0xE3A4, 0x818A, 0xBB4B, 0x818B, 0xE3AA, 0x818C, 0xE3A9, + 0x818D, 0xE3A8, 0x818F, 0xBB49, 0x8195, 0xE741, 0x8197, 0xE744, + 0x8198, 0xBDA8, 0x8199, 0xE743, 0x819A, 0xBDA7, 0x819B, 0xBDA3, + 0x819C, 0xBDA4, 0x819D, 0xBDA5, 0x819E, 0xE740, 0x819F, 0xE6FE, + 0x81A0, 0xBDA6, 0x81A2, 0xE742, 0x81A3, 0xE6FD, 0x81A6, 0xEAE9, + 0x81A7, 0xEAF3, 0x81A8, 0xBFB1, 0x81A9, 0xBFB0, 0x81AB, 0xEAED, + 0x81AC, 0xEAEF, 0x81AE, 0xEAEA, 0x81B0, 0xEAEE, 0x81B1, 0xEAE8, + 0x81B2, 0xEAF1, 0x81B3, 0xBFAF, 0x81B4, 0xEAF0, 0x81B5, 0xEAEC, + 0x81B7, 0xEAF2, 0x81B9, 0xEAEB, 0x81BA, 0xC174, 0x81BB, 0xEDE8, + 0x81BC, 0xEDEE, 0x81BD, 0xC178, 0x81BE, 0xC17A, 0x81BF, 0xC177, + 0x81C0, 0xC176, 0x81C2, 0xC175, 0x81C3, 0xC173, 0x81C4, 0xEDE9, + 0x81C5, 0xEDEC, 0x81C6, 0xC172, 0x81C7, 0xEDED, 0x81C9, 0xC179, + 0x81CA, 0xEDEB, 0x81CC, 0xEDEA, 0x81CD, 0xC2C0, 0x81CF, 0xC2C1, + 0x81D0, 0xF0A1, 0x81D1, 0xF07D, 0x81D2, 0xF07E, 0x81D5, 0xF2C2, + 0x81D7, 0xF2C1, 0x81D8, 0xC3BE, 0x81D9, 0xF4B4, 0x81DA, 0xC4A4, + 0x81DB, 0xF4B3, 0x81DD, 0xF5F0, 0x81DE, 0xF745, 0x81DF, 0xC5A6, + 0x81E0, 0xF943, 0x81E1, 0xF944, 0x81E2, 0xC5D8, 0x81E3, 0xA6DA, + 0x81E5, 0xAAD7, 0x81E6, 0xDB52, 0x81E7, 0xBB4E, 0x81E8, 0xC17B, + 0x81E9, 0xEDEF, 0x81EA, 0xA6DB, 0x81EC, 0xAFE5, 0x81ED, 0xAFE4, + 0x81EE, 0xDB53, 0x81F2, 0xEAF4, 0x81F3, 0xA6DC, 0x81F4, 0xAD50, + 0x81F7, 0xDB54, 0x81F8, 0xDB55, 0x81F9, 0xDB56, 0x81FA, 0xBB4F, + 0x81FB, 0xBFB2, 0x81FC, 0xA6DD, 0x81FE, 0xAAD8, 0x81FF, 0xD068, + 0x8200, 0xAFE6, 0x8201, 0xD370, 0x8202, 0xB2EA, 0x8204, 0xDB57, + 0x8205, 0xB8A4, 0x8207, 0xBB50, 0x8208, 0xBFB3, 0x8209, 0xC17C, + 0x820A, 0xC2C2, 0x820B, 0xF4B5, 0x820C, 0xA6DE, 0x820D, 0xAAD9, + 0x8210, 0xAFE7, 0x8211, 0xD752, 0x8212, 0xB5CE, 0x8214, 0xBB51, + 0x8215, 0xE3AB, 0x8216, 0xE745, 0x821B, 0xA6DF, 0x821C, 0xB5CF, + 0x821D, 0xDFA3, 0x821E, 0xBB52, 0x821F, 0xA6E0, 0x8220, 0xCDB1, + 0x8221, 0xD069, 0x8222, 0xAD51, 0x8225, 0xD372, 0x8228, 0xAFEA, + 0x822A, 0xAFE8, 0x822B, 0xAFE9, 0x822C, 0xAFEB, 0x822F, 0xD371, + 0x8232, 0xD757, 0x8233, 0xD754, 0x8234, 0xD756, 0x8235, 0xB2EB, + 0x8236, 0xB2ED, 0x8237, 0xB2EC, 0x8238, 0xD753, 0x8239, 0xB2EE, + 0x823A, 0xD755, 0x823C, 0xDB58, 0x823D, 0xDB59, 0x823F, 0xDB5A, + 0x8240, 0xDFA6, 0x8242, 0xDFA7, 0x8244, 0xDFA5, 0x8245, 0xDFA8, + 0x8247, 0xB8A5, 0x8249, 0xDFA4, 0x824B, 0xBB53, 0x824E, 0xE74A, + 0x824F, 0xE746, 0x8250, 0xE749, 0x8251, 0xE74B, 0x8252, 0xE748, + 0x8253, 0xE747, 0x8255, 0xEAF5, 0x8256, 0xEAF6, 0x8257, 0xEAF7, + 0x8258, 0xBFB4, 0x8259, 0xBFB5, 0x825A, 0xEDF1, 0x825B, 0xEDF0, + 0x825C, 0xEDF2, 0x825E, 0xF0A3, 0x825F, 0xF0A2, 0x8261, 0xF2C4, + 0x8263, 0xF2C5, 0x8264, 0xF2C3, 0x8266, 0xC4A5, 0x8268, 0xF4B6, + 0x8269, 0xF4B7, 0x826B, 0xF746, 0x826C, 0xF7EF, 0x826D, 0xF8BB, + 0x826E, 0xA6E1, 0x826F, 0xA87D, 0x8271, 0xC17D, 0x8272, 0xA6E2, + 0x8274, 0xD758, 0x8275, 0xDB5B, 0x8277, 0xC641, 0x8278, 0xCA4A, + 0x827C, 0xCA4B, 0x827D, 0xCA4D, 0x827E, 0xA6E3, 0x827F, 0xCA4E, + 0x8280, 0xCA4C, 0x8283, 0xCBA2, 0x8284, 0xCBA3, 0x8285, 0xCB7B, + 0x828A, 0xCBA1, 0x828B, 0xA8A1, 0x828D, 0xA8A2, 0x828E, 0xCB7C, + 0x828F, 0xCB7A, 0x8290, 0xCB79, 0x8291, 0xCB7D, 0x8292, 0xA87E, + 0x8293, 0xCB7E, 0x8294, 0xD06A, 0x8298, 0xCDB6, 0x8299, 0xAADC, + 0x829A, 0xCDB5, 0x829B, 0xCDB7, 0x829D, 0xAADB, 0x829E, 0xCDBC, + 0x829F, 0xAADF, 0x82A0, 0xCDB2, 0x82A1, 0xCDC0, 0x82A2, 0xCDC6, + 0x82A3, 0xAAE6, 0x82A4, 0xCDC3, 0x82A5, 0xAAE3, 0x82A7, 0xCDB9, + 0x82A8, 0xCDBF, 0x82A9, 0xCDC1, 0x82AB, 0xCDB4, 0x82AC, 0xAAE2, + 0x82AD, 0xAADD, 0x82AE, 0xCDBA, 0x82AF, 0xAAE4, 0x82B0, 0xAAE7, + 0x82B1, 0xAAE1, 0x82B3, 0xAADA, 0x82B4, 0xCDBE, 0x82B5, 0xCDB8, + 0x82B6, 0xCDC5, 0x82B7, 0xAAE9, 0x82B8, 0xAAE5, 0x82B9, 0xAAE0, + 0x82BA, 0xCDBD, 0x82BB, 0xAFEC, 0x82BC, 0xCDBB, 0x82BD, 0xAADE, + 0x82BE, 0xAAE8, 0x82C0, 0xCDB3, 0x82C2, 0xCDC2, 0x82C3, 0xCDC4, + 0x82D1, 0xAD62, 0x82D2, 0xAD5C, 0x82D3, 0xAD64, 0x82D4, 0xAD61, + 0x82D5, 0xD071, 0x82D6, 0xD074, 0x82D7, 0xAD5D, 0x82D9, 0xD06B, + 0x82DB, 0xAD56, 0x82DC, 0xAD60, 0x82DE, 0xAD63, 0x82DF, 0xAD65, + 0x82E0, 0xD0A2, 0x82E1, 0xD077, 0x82E3, 0xAD55, 0x82E4, 0xD0A1, + 0x82E5, 0xAD59, 0x82E6, 0xAD57, 0x82E7, 0xAD52, 0x82E8, 0xD06F, + 0x82EA, 0xD07E, 0x82EB, 0xD073, 0x82EC, 0xD076, 0x82ED, 0xD0A5, + 0x82EF, 0xAD66, 0x82F0, 0xD07D, 0x82F1, 0xAD5E, 0x82F2, 0xD078, + 0x82F3, 0xD0A4, 0x82F4, 0xD075, 0x82F5, 0xD079, 0x82F6, 0xD07C, + 0x82F9, 0xD06D, 0x82FA, 0xD0A3, 0x82FB, 0xD07B, 0x82FE, 0xD06C, + 0x8300, 0xD070, 0x8301, 0xAD5F, 0x8302, 0xAD5A, 0x8303, 0xAD53, + 0x8304, 0xAD58, 0x8305, 0xAD54, 0x8306, 0xAD67, 0x8307, 0xD06E, + 0x8308, 0xD3A5, 0x8309, 0xAD5B, 0x830C, 0xD07A, 0x830D, 0xCE41, + 0x8316, 0xD3A8, 0x8317, 0xAFFA, 0x8319, 0xD376, 0x831B, 0xD3A3, + 0x831C, 0xD37D, 0x831E, 0xD3B2, 0x8320, 0xD3AA, 0x8322, 0xD37E, + 0x8324, 0xD3A9, 0x8325, 0xD378, 0x8326, 0xD37C, 0x8327, 0xD3B5, + 0x8328, 0xAFFD, 0x8329, 0xD3AD, 0x832A, 0xD3A4, 0x832B, 0xAFED, + 0x832C, 0xD3B3, 0x832D, 0xD374, 0x832F, 0xD3AC, 0x8331, 0xAFFC, + 0x8332, 0xAFF7, 0x8333, 0xD373, 0x8334, 0xAFF5, 0x8335, 0xAFF4, + 0x8336, 0xAFF9, 0x8337, 0xD3AB, 0x8338, 0xAFF1, 0x8339, 0xAFF8, + 0x833A, 0xD072, 0x833B, 0xDB5C, 0x833C, 0xD3A6, 0x833F, 0xD37A, + 0x8340, 0xAFFB, 0x8341, 0xD37B, 0x8342, 0xD3A1, 0x8343, 0xAFFE, + 0x8344, 0xD375, 0x8345, 0xD3AF, 0x8347, 0xD3AE, 0x8348, 0xD3B6, + 0x8349, 0xAFF3, 0x834A, 0xAFF0, 0x834B, 0xD3B4, 0x834C, 0xD3B0, + 0x834D, 0xD3A7, 0x834E, 0xD3A2, 0x834F, 0xAFF6, 0x8350, 0xAFF2, + 0x8351, 0xD377, 0x8352, 0xAFEE, 0x8353, 0xD3B1, 0x8354, 0xAFEF, + 0x8356, 0xD379, 0x8373, 0xD75E, 0x8374, 0xD760, 0x8375, 0xD765, + 0x8376, 0xD779, 0x8377, 0xB2FC, 0x8378, 0xB2F2, 0x837A, 0xD75D, + 0x837B, 0xB2FD, 0x837C, 0xB2FE, 0x837D, 0xD768, 0x837E, 0xD76F, + 0x837F, 0xD775, 0x8381, 0xD762, 0x8383, 0xD769, 0x8386, 0xB340, + 0x8387, 0xD777, 0x8388, 0xD772, 0x8389, 0xB2FA, 0x838A, 0xB2F8, + 0x838B, 0xD76E, 0x838C, 0xD76A, 0x838D, 0xD75C, 0x838E, 0xB2EF, + 0x838F, 0xD761, 0x8390, 0xD759, 0x8392, 0xB2F7, 0x8393, 0xB2F9, + 0x8394, 0xD766, 0x8395, 0xD763, 0x8396, 0xB2F4, 0x8397, 0xD773, + 0x8398, 0xB2F1, 0x8399, 0xD764, 0x839A, 0xD77A, 0x839B, 0xD76C, + 0x839D, 0xD76B, 0x839E, 0xB2F0, 0x83A0, 0xB2FB, 0x83A2, 0xB2F3, + 0x83A3, 0xD75A, 0x83A4, 0xD75F, 0x83A5, 0xD770, 0x83A6, 0xD776, + 0x83A7, 0xB341, 0x83A8, 0xD75B, 0x83A9, 0xD767, 0x83AA, 0xD76D, + 0x83AB, 0xB2F6, 0x83AE, 0xD778, 0x83AF, 0xD771, 0x83B0, 0xD774, + 0x83BD, 0xB2F5, 0x83BF, 0xDB6C, 0x83C0, 0xDB60, 0x83C1, 0xB5D7, + 0x83C2, 0xDB7D, 0x83C3, 0xDBA7, 0x83C4, 0xDBAA, 0x83C5, 0xB5D5, + 0x83C6, 0xDB68, 0x83C7, 0xDBA3, 0x83C8, 0xDB69, 0x83C9, 0xDB77, + 0x83CA, 0xB5E2, 0x83CB, 0xDB73, 0x83CC, 0xB5DF, 0x83CE, 0xDB74, + 0x83CF, 0xDB5D, 0x83D1, 0xDBA4, 0x83D4, 0xB5E8, 0x83D5, 0xDBA1, + 0x83D6, 0xDB75, 0x83D7, 0xDBAC, 0x83D8, 0xDB70, 0x83D9, 0xDFC8, + 0x83DB, 0xDBAF, 0x83DC, 0xB5E6, 0x83DD, 0xDB6E, 0x83DE, 0xDB7A, + 0x83DF, 0xB5E9, 0x83E0, 0xB5D4, 0x83E1, 0xDB72, 0x83E2, 0xDBAD, + 0x83E3, 0xDB6B, 0x83E4, 0xDB64, 0x83E5, 0xDB6F, 0x83E7, 0xDB63, + 0x83E8, 0xDB61, 0x83E9, 0xB5D0, 0x83EA, 0xDBA5, 0x83EB, 0xDB6A, + 0x83EC, 0xDBA8, 0x83EE, 0xDBA9, 0x83EF, 0xB5D8, 0x83F0, 0xB5DD, + 0x83F1, 0xB5D9, 0x83F2, 0xB5E1, 0x83F3, 0xDB7E, 0x83F4, 0xB5DA, + 0x83F5, 0xDB76, 0x83F6, 0xDB66, 0x83F8, 0xB5D2, 0x83F9, 0xDB5E, + 0x83FA, 0xDBA2, 0x83FB, 0xDBAB, 0x83FC, 0xDB65, 0x83FD, 0xB5E0, + 0x83FE, 0xDBB0, 0x83FF, 0xDB71, 0x8401, 0xDB6D, 0x8403, 0xB5D1, + 0x8404, 0xB5E5, 0x8406, 0xDB7C, 0x8407, 0xB5E7, 0x8409, 0xDB78, + 0x840A, 0xB5DC, 0x840B, 0xB5D6, 0x840C, 0xB5DE, 0x840D, 0xB5D3, + 0x840E, 0xB5E4, 0x840F, 0xDB79, 0x8410, 0xDB67, 0x8411, 0xDB7B, + 0x8412, 0xDB62, 0x8413, 0xDBA6, 0x841B, 0xDBAE, 0x8423, 0xDB5F, + 0x8429, 0xDFC7, 0x842B, 0xDFDD, 0x842C, 0xB855, 0x842D, 0xDFCC, + 0x842F, 0xDFCA, 0x8430, 0xDFB5, 0x8431, 0xB8A9, 0x8432, 0xDFC5, + 0x8433, 0xDFD9, 0x8434, 0xDFC1, 0x8435, 0xB8B1, 0x8436, 0xDFD8, + 0x8437, 0xDFBF, 0x8438, 0xB5E3, 0x8439, 0xDFCF, 0x843A, 0xDFC0, + 0x843B, 0xDFD6, 0x843C, 0xB8B0, 0x843D, 0xB8A8, 0x843F, 0xDFAA, + 0x8440, 0xDFB2, 0x8442, 0xDFCB, 0x8443, 0xDFC3, 0x8444, 0xDFDC, + 0x8445, 0xDFC6, 0x8446, 0xB8B6, 0x8447, 0xDFD7, 0x8449, 0xB8AD, + 0x844B, 0xDFC9, 0x844C, 0xDFD1, 0x844D, 0xDFB6, 0x844E, 0xDFD0, + 0x8450, 0xDFE1, 0x8451, 0xDFB1, 0x8452, 0xDFD2, 0x8454, 0xDFDF, + 0x8456, 0xDFAB, 0x8457, 0xB5DB, 0x8459, 0xDFB9, 0x845A, 0xDFB8, + 0x845B, 0xB8AF, 0x845D, 0xDFBC, 0x845E, 0xDFBE, 0x845F, 0xDFCD, + 0x8460, 0xDFDE, 0x8461, 0xB8B2, 0x8463, 0xB8B3, 0x8465, 0xDFB0, + 0x8466, 0xB8AB, 0x8467, 0xDFB4, 0x8468, 0xDFDA, 0x8469, 0xB8B4, + 0x846B, 0xB8AC, 0x846C, 0xB8AE, 0x846D, 0xB8B5, 0x846E, 0xDFE0, + 0x846F, 0xDFD3, 0x8470, 0xDFCE, 0x8473, 0xDFBB, 0x8474, 0xDFBA, + 0x8475, 0xB8AA, 0x8476, 0xDFAC, 0x8477, 0xB8A7, 0x8478, 0xDFC4, + 0x8479, 0xDFAD, 0x847A, 0xDFC2, 0x847D, 0xDFB7, 0x847E, 0xDFDB, + 0x8482, 0xB8A6, 0x8486, 0xDFB3, 0x848D, 0xDFAF, 0x848E, 0xDFD5, + 0x848F, 0xDFAE, 0x8490, 0xBB60, 0x8491, 0xE3D3, 0x8494, 0xE3C2, + 0x8497, 0xE3AC, 0x8498, 0xE3CA, 0x8499, 0xBB58, 0x849A, 0xE3BB, + 0x849B, 0xE3C5, 0x849C, 0xBB5B, 0x849D, 0xE3BE, 0x849E, 0xBB59, + 0x849F, 0xE3AF, 0x84A0, 0xE3CD, 0x84A1, 0xE3AE, 0x84A2, 0xE3C1, + 0x84A4, 0xE3AD, 0x84A7, 0xE3BF, 0x84A8, 0xE3C8, 0x84A9, 0xE3C6, + 0x84AA, 0xE3BA, 0x84AB, 0xE3B5, 0x84AC, 0xE3B3, 0x84AE, 0xE3B4, + 0x84AF, 0xE3C7, 0x84B0, 0xE3D2, 0x84B1, 0xE3BC, 0x84B2, 0xBB5A, + 0x84B4, 0xE3B7, 0x84B6, 0xE3CB, 0x84B8, 0xBB5D, 0x84B9, 0xE3B6, + 0x84BA, 0xE3B0, 0x84BB, 0xE3C0, 0x84BC, 0xBB61, 0x84BF, 0xBB55, + 0x84C0, 0xBB5E, 0x84C1, 0xE3B8, 0x84C2, 0xE3B2, 0x84C4, 0xBB57, + 0x84C5, 0xDFD4, 0x84C6, 0xBB56, 0x84C7, 0xE3C3, 0x84C9, 0xBB54, + 0x84CA, 0xBB63, 0x84CB, 0xBB5C, 0x84CC, 0xE3C4, 0x84CD, 0xE3B9, + 0x84CE, 0xE3B1, 0x84CF, 0xE3CC, 0x84D0, 0xE3BD, 0x84D1, 0xBB62, + 0x84D2, 0xE3D0, 0x84D3, 0xBB5F, 0x84D4, 0xE3CF, 0x84D6, 0xE3C9, + 0x84D7, 0xE3CE, 0x84DB, 0xE3D1, 0x84E7, 0xE773, 0x84E8, 0xE774, + 0x84E9, 0xE767, 0x84EA, 0xE766, 0x84EB, 0xE762, 0x84EC, 0xBDB4, + 0x84EE, 0xBDAC, 0x84EF, 0xE776, 0x84F0, 0xE775, 0x84F1, 0xDFA9, + 0x84F2, 0xE75F, 0x84F3, 0xE763, 0x84F4, 0xE75D, 0x84F6, 0xE770, + 0x84F7, 0xE761, 0x84F9, 0xE777, 0x84FA, 0xE75A, 0x84FB, 0xE758, + 0x84FC, 0xE764, 0x84FD, 0xE76E, 0x84FE, 0xE769, 0x84FF, 0xBDB6, + 0x8500, 0xE74F, 0x8502, 0xE76D, 0x8506, 0xBDB7, 0x8507, 0xDFBD, + 0x8508, 0xE75B, 0x8509, 0xE752, 0x850A, 0xE755, 0x850B, 0xE77B, + 0x850C, 0xE75C, 0x850D, 0xE753, 0x850E, 0xE751, 0x850F, 0xE74E, + 0x8511, 0xBDB0, 0x8512, 0xE765, 0x8513, 0xBDAF, 0x8514, 0xBDB3, + 0x8515, 0xE760, 0x8516, 0xE768, 0x8517, 0xBDA9, 0x8518, 0xE778, + 0x8519, 0xE77C, 0x851A, 0xBDAB, 0x851C, 0xE757, 0x851D, 0xE76B, + 0x851E, 0xE76F, 0x851F, 0xE754, 0x8520, 0xE779, 0x8521, 0xBDB2, + 0x8523, 0xBDB1, 0x8524, 0xE74C, 0x8525, 0xBDB5, 0x8526, 0xE772, + 0x8527, 0xE756, 0x8528, 0xE76A, 0x8529, 0xE750, 0x852A, 0xE75E, + 0x852B, 0xE759, 0x852C, 0xBDAD, 0x852D, 0xBDAE, 0x852E, 0xE76C, + 0x852F, 0xE77D, 0x8530, 0xE77A, 0x8531, 0xE771, 0x853B, 0xE74D, + 0x853D, 0xBDAA, 0x853E, 0xEB49, 0x8540, 0xEB40, 0x8541, 0xEB43, + 0x8543, 0xBFBB, 0x8544, 0xEB45, 0x8545, 0xEAF9, 0x8546, 0xEB41, + 0x8547, 0xEB47, 0x8548, 0xBFB8, 0x8549, 0xBFBC, 0x854A, 0xBFB6, + 0x854D, 0xEAFB, 0x854E, 0xEB4C, 0x8551, 0xEB46, 0x8553, 0xEAFC, + 0x8554, 0xEB55, 0x8555, 0xEB4F, 0x8556, 0xEAF8, 0x8557, 0xEE46, + 0x8558, 0xEAFE, 0x8559, 0xBFB7, 0x855B, 0xEB4A, 0x855D, 0xEB54, + 0x855E, 0xBFBF, 0x8560, 0xEB51, 0x8561, 0xEAFD, 0x8562, 0xEB44, + 0x8563, 0xEB48, 0x8564, 0xEB42, 0x8565, 0xEB56, 0x8566, 0xEB53, + 0x8567, 0xEB50, 0x8568, 0xBFB9, 0x8569, 0xBFBA, 0x856A, 0xBFBE, + 0x856B, 0xEAFA, 0x856C, 0xEB57, 0x856D, 0xBFBD, 0x856E, 0xEB4D, + 0x8571, 0xEB4B, 0x8575, 0xEB4E, 0x8576, 0xEE53, 0x8577, 0xEE40, + 0x8578, 0xEE45, 0x8579, 0xEE52, 0x857A, 0xEE44, 0x857B, 0xEDFB, + 0x857C, 0xEE41, 0x857E, 0xC1A2, 0x8580, 0xEDF4, 0x8581, 0xEE4D, + 0x8582, 0xEE4F, 0x8583, 0xEDF3, 0x8584, 0xC1A1, 0x8585, 0xEE51, + 0x8586, 0xEE49, 0x8587, 0xC1A8, 0x8588, 0xEE50, 0x8589, 0xEE42, + 0x858A, 0xC1AA, 0x858B, 0xEDF9, 0x858C, 0xEB52, 0x858D, 0xEE4A, + 0x858E, 0xEE47, 0x858F, 0xEDF5, 0x8590, 0xEE55, 0x8591, 0xC1A4, + 0x8594, 0xC1A5, 0x8595, 0xEDF7, 0x8596, 0xEE48, 0x8598, 0xEE54, + 0x8599, 0xEE4B, 0x859A, 0xEDFD, 0x859B, 0xC1A7, 0x859C, 0xC1A3, + 0x859D, 0xEE4C, 0x859E, 0xEDFE, 0x859F, 0xEE56, 0x85A0, 0xEDF8, + 0x85A1, 0xEE43, 0x85A2, 0xEE4E, 0x85A3, 0xEDFA, 0x85A4, 0xEDFC, + 0x85A6, 0xC2CB, 0x85A7, 0xEDF6, 0x85A8, 0xC1A9, 0x85A9, 0xC2C4, + 0x85AA, 0xC17E, 0x85AF, 0xC1A6, 0x85B0, 0xC2C8, 0x85B1, 0xF0B3, + 0x85B3, 0xF0A9, 0x85B4, 0xF0A4, 0x85B5, 0xF0AA, 0x85B6, 0xF0B4, + 0x85B7, 0xF0B8, 0x85B8, 0xF0B7, 0x85B9, 0xC2CA, 0x85BA, 0xC2C9, + 0x85BD, 0xF0AB, 0x85BE, 0xF0B9, 0x85BF, 0xF0AE, 0x85C0, 0xF0A6, + 0x85C2, 0xF0A8, 0x85C3, 0xF0A7, 0x85C4, 0xF0AD, 0x85C5, 0xF0B2, + 0x85C6, 0xF0A5, 0x85C7, 0xF0AC, 0x85C8, 0xF0B1, 0x85C9, 0xC2C7, + 0x85CB, 0xF0AF, 0x85CD, 0xC2C5, 0x85CE, 0xF0B0, 0x85CF, 0xC2C3, + 0x85D0, 0xC2C6, 0x85D1, 0xF2D5, 0x85D2, 0xF0B5, 0x85D5, 0xC3C2, + 0x85D7, 0xF2CD, 0x85D8, 0xF2D1, 0x85D9, 0xF2C9, 0x85DA, 0xF2CC, + 0x85DC, 0xF2D4, 0x85DD, 0xC3C0, 0x85DE, 0xF2D9, 0x85DF, 0xF2D2, + 0x85E1, 0xF2CA, 0x85E2, 0xF2DA, 0x85E3, 0xF2D3, 0x85E4, 0xC3C3, + 0x85E5, 0xC3C4, 0x85E6, 0xF2D7, 0x85E8, 0xF2CB, 0x85E9, 0xC3BF, + 0x85EA, 0xC3C1, 0x85EB, 0xF2C6, 0x85EC, 0xF2CE, 0x85ED, 0xF2C8, + 0x85EF, 0xF2D8, 0x85F0, 0xF2D6, 0x85F1, 0xF2C7, 0x85F2, 0xF2CF, + 0x85F6, 0xF4BE, 0x85F7, 0xC3C5, 0x85F8, 0xF2D0, 0x85F9, 0xC4A7, + 0x85FA, 0xC4A9, 0x85FB, 0xC4A6, 0x85FD, 0xF4C3, 0x85FE, 0xF4BB, + 0x85FF, 0xF4B9, 0x8600, 0xF4BD, 0x8601, 0xF4BA, 0x8604, 0xF4BF, + 0x8605, 0xF4C1, 0x8606, 0xC4AA, 0x8607, 0xC4AC, 0x8609, 0xF4C0, + 0x860A, 0xC4AD, 0x860B, 0xC4AB, 0x860C, 0xF4C2, 0x8611, 0xC4A8, + 0x8617, 0xC4F4, 0x8618, 0xF5F1, 0x8619, 0xF5F7, 0x861A, 0xC4F6, + 0x861B, 0xF4BC, 0x861C, 0xF5F6, 0x861E, 0xF5FD, 0x861F, 0xF5F4, + 0x8620, 0xF5FB, 0x8621, 0xF5FA, 0x8622, 0xF4B8, 0x8623, 0xF5F5, + 0x8624, 0xF0B6, 0x8625, 0xF5FE, 0x8626, 0xF5F3, 0x8627, 0xF5F8, + 0x8629, 0xF5FC, 0x862A, 0xF5F2, 0x862C, 0xF74A, 0x862D, 0xC4F5, + 0x862E, 0xF5F9, 0x8631, 0xF7F4, 0x8632, 0xF74B, 0x8633, 0xF749, + 0x8634, 0xF747, 0x8635, 0xF748, 0x8636, 0xF74C, 0x8638, 0xC5D9, + 0x8639, 0xF7F2, 0x863A, 0xF7F0, 0x863B, 0xF7F5, 0x863C, 0xF7F3, + 0x863E, 0xF7F6, 0x863F, 0xC5DA, 0x8640, 0xF7F1, 0x8643, 0xF8BC, + 0x8646, 0xF945, 0x8647, 0xF946, 0x8648, 0xF947, 0x864B, 0xF9C7, + 0x864C, 0xF9BD, 0x864D, 0xCA4F, 0x864E, 0xAAEA, 0x8650, 0xAD68, + 0x8652, 0xD3B8, 0x8653, 0xD3B7, 0x8654, 0xB040, 0x8655, 0xB342, + 0x8656, 0xD77C, 0x8659, 0xD77B, 0x865B, 0xB5EA, 0x865C, 0xB8B8, + 0x865E, 0xB8B7, 0x865F, 0xB8B9, 0x8661, 0xE3D4, 0x8662, 0xE77E, + 0x8663, 0xEB58, 0x8664, 0xEB5A, 0x8665, 0xEB59, 0x8667, 0xC1AB, + 0x8668, 0xEE57, 0x8669, 0xF0BA, 0x866A, 0xF9A5, 0x866B, 0xA6E4, + 0x866D, 0xCDC9, 0x866E, 0xCDCA, 0x866F, 0xCDC8, 0x8670, 0xCDC7, + 0x8671, 0xAAEB, 0x8673, 0xD0A9, 0x8674, 0xD0A7, 0x8677, 0xD0A6, + 0x8679, 0xAD69, 0x867A, 0xAD6B, 0x867B, 0xAD6A, 0x867C, 0xD0A8, + 0x8685, 0xD3C4, 0x8686, 0xD3C1, 0x8687, 0xD3BF, 0x868A, 0xB041, + 0x868B, 0xD3C2, 0x868C, 0xB046, 0x868D, 0xD3BC, 0x868E, 0xD3CB, + 0x8690, 0xD3CD, 0x8691, 0xD3BD, 0x8693, 0xB043, 0x8694, 0xD3CE, + 0x8695, 0xD3C9, 0x8696, 0xD3BB, 0x8697, 0xD3C0, 0x8698, 0xD3CA, + 0x8699, 0xD3C6, 0x869A, 0xD3C3, 0x869C, 0xB048, 0x869D, 0xD3CC, + 0x869E, 0xD3BE, 0x86A1, 0xD3C7, 0x86A2, 0xD3B9, 0x86A3, 0xB047, + 0x86A4, 0xB044, 0x86A5, 0xD3C5, 0x86A7, 0xD3C8, 0x86A8, 0xD3BA, + 0x86A9, 0xB045, 0x86AA, 0xB042, 0x86AF, 0xB34C, 0x86B0, 0xD7A5, + 0x86B1, 0xB34B, 0x86B3, 0xD7A8, 0x86B4, 0xD7AB, 0x86B5, 0xB348, + 0x86B6, 0xB346, 0x86B7, 0xD77E, 0x86B8, 0xD7A9, 0x86B9, 0xD7A7, + 0x86BA, 0xD7A4, 0x86BB, 0xD7AC, 0x86BC, 0xD7AD, 0x86BD, 0xD7AF, + 0x86BE, 0xD7B0, 0x86BF, 0xD77D, 0x86C0, 0xB345, 0x86C1, 0xD7A2, + 0x86C2, 0xD7A1, 0x86C3, 0xD7AE, 0x86C4, 0xB347, 0x86C5, 0xD7A3, + 0x86C6, 0xB349, 0x86C7, 0xB344, 0x86C8, 0xD7A6, 0x86C9, 0xB34D, + 0x86CB, 0xB34A, 0x86CC, 0xD7AA, 0x86D0, 0xB5F1, 0x86D1, 0xDBBF, + 0x86D3, 0xDBB4, 0x86D4, 0xB5EE, 0x86D6, 0xDFE7, 0x86D7, 0xDBBD, + 0x86D8, 0xDBB1, 0x86D9, 0xB5EC, 0x86DA, 0xDBB6, 0x86DB, 0xB5EF, + 0x86DC, 0xDBBA, 0x86DD, 0xDBB8, 0x86DE, 0xB5F2, 0x86DF, 0xB5EB, + 0x86E2, 0xDBB2, 0x86E3, 0xDBB5, 0x86E4, 0xB5F0, 0x86E6, 0xDBB3, + 0x86E8, 0xDBBE, 0x86E9, 0xDBBC, 0x86EA, 0xDBB7, 0x86EB, 0xDBB9, + 0x86EC, 0xDBBB, 0x86ED, 0xB5ED, 0x86F5, 0xDFE8, 0x86F6, 0xDFEE, + 0x86F7, 0xDFE4, 0x86F8, 0xDFEA, 0x86F9, 0xB8BA, 0x86FA, 0xDFE6, + 0x86FB, 0xB8C0, 0x86FE, 0xB8BF, 0x8700, 0xB8BE, 0x8701, 0xDFED, + 0x8702, 0xB8C1, 0x8703, 0xB8C2, 0x8704, 0xDFE3, 0x8705, 0xDFF0, + 0x8706, 0xB8C3, 0x8707, 0xB8BD, 0x8708, 0xB8BC, 0x8709, 0xDFEC, + 0x870A, 0xB8C4, 0x870B, 0xDFE2, 0x870C, 0xDFE5, 0x870D, 0xDFEF, + 0x870E, 0xDFEB, 0x8711, 0xE3F4, 0x8712, 0xE3E9, 0x8713, 0xB8BB, + 0x8718, 0xBB6A, 0x8719, 0xE3DD, 0x871A, 0xE3F2, 0x871B, 0xE3DE, + 0x871C, 0xBB65, 0x871E, 0xE3DB, 0x8720, 0xE3E4, 0x8721, 0xE3DC, + 0x8722, 0xBB67, 0x8723, 0xE3D6, 0x8724, 0xE3F1, 0x8725, 0xBB68, + 0x8726, 0xE3EE, 0x8727, 0xE3EF, 0x8728, 0xE3D7, 0x8729, 0xBB6D, + 0x872A, 0xE3E6, 0x872C, 0xE3E0, 0x872D, 0xE3E7, 0x872E, 0xE3DA, + 0x8730, 0xE3F3, 0x8731, 0xE3EB, 0x8732, 0xE3E5, 0x8733, 0xE3D5, + 0x8734, 0xBB69, 0x8735, 0xE3EC, 0x8737, 0xBB6C, 0x8738, 0xE3F0, + 0x873A, 0xE3EA, 0x873B, 0xBB66, 0x873C, 0xE3E8, 0x873E, 0xE3E2, + 0x873F, 0xBB64, 0x8740, 0xE3D9, 0x8741, 0xE3E1, 0x8742, 0xE3ED, + 0x8743, 0xE3DF, 0x8746, 0xE3E3, 0x874C, 0xBDC1, 0x874D, 0xDFE9, + 0x874E, 0xE7B2, 0x874F, 0xE7BB, 0x8750, 0xE7B1, 0x8751, 0xE7AD, + 0x8752, 0xE7AA, 0x8753, 0xBDC2, 0x8754, 0xE7A8, 0x8755, 0xBB6B, + 0x8756, 0xE7A1, 0x8757, 0xBDC0, 0x8758, 0xE7A7, 0x8759, 0xBDBF, + 0x875A, 0xE7AC, 0x875B, 0xE7A9, 0x875C, 0xE7B9, 0x875D, 0xE7B4, + 0x875E, 0xE7AE, 0x875F, 0xE7B3, 0x8760, 0xBDBB, 0x8761, 0xE7AB, + 0x8762, 0xE7BE, 0x8763, 0xE7A2, 0x8764, 0xE7A3, 0x8765, 0xE7BA, + 0x8766, 0xBDBC, 0x8767, 0xE7BF, 0x8768, 0xBDBE, 0x8769, 0xE7C0, + 0x876A, 0xE7B0, 0x876B, 0xE3D8, 0x876C, 0xE7B6, 0x876D, 0xE7AF, + 0x876E, 0xE7B8, 0x876F, 0xE7B5, 0x8773, 0xE7A6, 0x8774, 0xBDB9, + 0x8775, 0xE7BD, 0x8776, 0xBDBA, 0x8777, 0xE7A4, 0x8778, 0xBDBD, + 0x8779, 0xEB64, 0x877A, 0xE7B7, 0x877B, 0xE7BC, 0x8781, 0xEB61, + 0x8782, 0xBDB8, 0x8783, 0xBFC0, 0x8784, 0xEB6B, 0x8785, 0xEB67, + 0x8787, 0xEB65, 0x8788, 0xEB60, 0x8789, 0xEB6F, 0x878D, 0xBFC4, + 0x878F, 0xEB5C, 0x8790, 0xEB68, 0x8791, 0xEB69, 0x8792, 0xEB5F, + 0x8793, 0xEB5E, 0x8794, 0xEB6C, 0x8796, 0xEB62, 0x8797, 0xEB5D, + 0x8798, 0xEB63, 0x879A, 0xEB6E, 0x879B, 0xEB5B, 0x879C, 0xEB6D, + 0x879D, 0xEB6A, 0x879E, 0xBFC2, 0x879F, 0xBFC1, 0x87A2, 0xBFC3, + 0x87A3, 0xEB66, 0x87A4, 0xF0CB, 0x87AA, 0xEE59, 0x87AB, 0xC1B1, + 0x87AC, 0xEE5D, 0x87AD, 0xEE5A, 0x87AE, 0xEE61, 0x87AF, 0xEE67, + 0x87B0, 0xEE5C, 0x87B2, 0xEE70, 0x87B3, 0xC1AE, 0x87B4, 0xEE6A, + 0x87B5, 0xEE5F, 0x87B6, 0xEE6B, 0x87B7, 0xEE66, 0x87B8, 0xEE6D, + 0x87B9, 0xEE5E, 0x87BA, 0xC1B3, 0x87BB, 0xC1B2, 0x87BC, 0xEE60, + 0x87BD, 0xEE6E, 0x87BE, 0xEE58, 0x87BF, 0xEE6C, 0x87C0, 0xC1AC, + 0x87C2, 0xEE64, 0x87C3, 0xEE63, 0x87C4, 0xEE68, 0x87C5, 0xEE5B, + 0x87C6, 0xC1B0, 0x87C8, 0xC1B4, 0x87C9, 0xEE62, 0x87CA, 0xEE69, + 0x87CB, 0xC1B5, 0x87CC, 0xEE65, 0x87D1, 0xC1AD, 0x87D2, 0xC1AF, + 0x87D3, 0xF0C7, 0x87D4, 0xF0C5, 0x87D7, 0xF0CC, 0x87D8, 0xF0C9, + 0x87D9, 0xF0CD, 0x87DB, 0xF0BE, 0x87DC, 0xF0C6, 0x87DD, 0xF0D1, + 0x87DE, 0xEE6F, 0x87DF, 0xF0C2, 0x87E0, 0xC2CF, 0x87E1, 0xE7A5, + 0x87E2, 0xF0BD, 0x87E3, 0xF0CA, 0x87E4, 0xF0C4, 0x87E5, 0xF0C1, + 0x87E6, 0xF0BC, 0x87E7, 0xF0BB, 0x87E8, 0xF0D0, 0x87EA, 0xF0C0, + 0x87EB, 0xF0BF, 0x87EC, 0xC2CD, 0x87ED, 0xF0C8, 0x87EF, 0xC2CC, + 0x87F2, 0xC2CE, 0x87F3, 0xF0C3, 0x87F4, 0xF0CF, 0x87F6, 0xF2DE, + 0x87F7, 0xF2DF, 0x87F9, 0xC3C9, 0x87FA, 0xF2DC, 0x87FB, 0xC3C6, + 0x87FC, 0xF2E4, 0x87FE, 0xC3CA, 0x87FF, 0xF2E6, 0x8800, 0xF2DB, + 0x8801, 0xF0CE, 0x8802, 0xF2E8, 0x8803, 0xF2DD, 0x8805, 0xC3C7, + 0x8806, 0xF2E3, 0x8808, 0xF2E5, 0x8809, 0xF2E0, 0x880A, 0xF2E7, + 0x880B, 0xF2E2, 0x880C, 0xF2E1, 0x880D, 0xC3C8, 0x8810, 0xF4C5, + 0x8811, 0xF4C6, 0x8813, 0xF4C8, 0x8814, 0xC4AE, 0x8815, 0xC4AF, + 0x8816, 0xF4C9, 0x8817, 0xF4C7, 0x8819, 0xF4C4, 0x881B, 0xF642, + 0x881C, 0xF645, 0x881D, 0xF641, 0x881F, 0xC4FA, 0x8820, 0xF643, + 0x8821, 0xC4F9, 0x8822, 0xC4F8, 0x8823, 0xC4F7, 0x8824, 0xF644, + 0x8825, 0xF751, 0x8826, 0xF74F, 0x8828, 0xF74E, 0x8829, 0xF640, + 0x882A, 0xF750, 0x882B, 0xF646, 0x882C, 0xF74D, 0x882E, 0xF7F9, + 0x882F, 0xF7D7, 0x8830, 0xF7F7, 0x8831, 0xC5DB, 0x8832, 0xF7F8, + 0x8833, 0xF7FA, 0x8835, 0xF8BF, 0x8836, 0xC5FA, 0x8837, 0xF8BE, + 0x8838, 0xF8BD, 0x8839, 0xC5FB, 0x883B, 0xC65A, 0x883C, 0xF96E, + 0x883D, 0xF9A7, 0x883E, 0xF9A6, 0x883F, 0xF9A8, 0x8840, 0xA6E5, + 0x8841, 0xD0AA, 0x8843, 0xD3CF, 0x8844, 0xD3D0, 0x8848, 0xDBC0, + 0x884A, 0xF647, 0x884B, 0xF8C0, 0x884C, 0xA6E6, 0x884D, 0xAD6C, + 0x884E, 0xD0AB, 0x8852, 0xD7B1, 0x8853, 0xB34E, 0x8855, 0xDBC2, + 0x8856, 0xDBC1, 0x8857, 0xB5F3, 0x8859, 0xB8C5, 0x885A, 0xE7C1, + 0x885B, 0xBDC3, 0x885D, 0xBDC4, 0x8861, 0xBFC5, 0x8862, 0xC5FC, + 0x8863, 0xA6E7, 0x8867, 0xD0AC, 0x8868, 0xAAED, 0x8869, 0xD0AE, + 0x886A, 0xD0AD, 0x886B, 0xAD6D, 0x886D, 0xD3D1, 0x886F, 0xD3D8, + 0x8870, 0xB049, 0x8871, 0xD3D6, 0x8872, 0xD3D4, 0x8874, 0xD3DB, + 0x8875, 0xD3D2, 0x8876, 0xD3D3, 0x8877, 0xB04A, 0x8879, 0xB04E, + 0x887C, 0xD3DC, 0x887D, 0xB04D, 0x887E, 0xD3DA, 0x887F, 0xD3D7, + 0x8880, 0xD3D5, 0x8881, 0xB04B, 0x8882, 0xB04C, 0x8883, 0xD3D9, + 0x8888, 0xB350, 0x8889, 0xD7B2, 0x888B, 0xB355, 0x888C, 0xD7C2, + 0x888D, 0xB354, 0x888E, 0xD7C4, 0x8891, 0xD7B8, 0x8892, 0xB352, + 0x8893, 0xD7C3, 0x8895, 0xD7B3, 0x8896, 0xB353, 0x8897, 0xD7BF, + 0x8898, 0xD7BB, 0x8899, 0xD7BD, 0x889A, 0xD7B7, 0x889B, 0xD7BE, + 0x889E, 0xB34F, 0x889F, 0xD7BA, 0x88A1, 0xD7B9, 0x88A2, 0xD7B5, + 0x88A4, 0xD7C0, 0x88A7, 0xD7BC, 0x88A8, 0xD7B4, 0x88AA, 0xD7B6, + 0x88AB, 0xB351, 0x88AC, 0xD7C1, 0x88B1, 0xB5F6, 0x88B2, 0xDBCD, + 0x88B6, 0xDBC9, 0x88B7, 0xDBCB, 0x88B8, 0xDBC6, 0x88B9, 0xDBC5, + 0x88BA, 0xDBC3, 0x88BC, 0xDBCA, 0x88BD, 0xDBCC, 0x88BE, 0xDBC8, + 0x88C0, 0xDBC7, 0x88C1, 0xB5F4, 0x88C2, 0xB5F5, 0x88C9, 0xDBCF, + 0x88CA, 0xB8CD, 0x88CB, 0xDFF2, 0x88CC, 0xDFF8, 0x88CD, 0xDFF3, + 0x88CE, 0xDFF4, 0x88CF, 0xF9D8, 0x88D0, 0xDFF9, 0x88D2, 0xB8CF, + 0x88D4, 0xB8C7, 0x88D5, 0xB8CE, 0x88D6, 0xDFF1, 0x88D7, 0xDBC4, + 0x88D8, 0xB8CA, 0x88D9, 0xB8C8, 0x88DA, 0xDFF7, 0x88DB, 0xDFF6, + 0x88DC, 0xB8C9, 0x88DD, 0xB8CB, 0x88DE, 0xDFF5, 0x88DF, 0xB8C6, + 0x88E1, 0xB8CC, 0x88E7, 0xE3F6, 0x88E8, 0xBB74, 0x88EB, 0xE442, + 0x88EC, 0xE441, 0x88EE, 0xE3FB, 0x88EF, 0xBB76, 0x88F0, 0xE440, + 0x88F1, 0xE3F7, 0x88F2, 0xE3F8, 0x88F3, 0xBB6E, 0x88F4, 0xBB70, + 0x88F6, 0xE3FD, 0x88F7, 0xE3F5, 0x88F8, 0xBB72, 0x88F9, 0xBB71, + 0x88FA, 0xE3F9, 0x88FB, 0xE3FE, 0x88FC, 0xE3FC, 0x88FD, 0xBB73, + 0x88FE, 0xE3FA, 0x8901, 0xDBCE, 0x8902, 0xBB6F, 0x8905, 0xE7C2, + 0x8906, 0xE7C9, 0x8907, 0xBDC6, 0x8909, 0xE7CD, 0x890A, 0xBDCA, + 0x890B, 0xE7C5, 0x890C, 0xE7C3, 0x890E, 0xE7CC, 0x8910, 0xBDC5, + 0x8911, 0xE7CB, 0x8912, 0xBDC7, 0x8913, 0xBDC8, 0x8914, 0xE7C4, + 0x8915, 0xBDC9, 0x8916, 0xE7CA, 0x8917, 0xE7C6, 0x8918, 0xE7C7, + 0x8919, 0xE7C8, 0x891A, 0xBB75, 0x891E, 0xEB70, 0x891F, 0xEB7C, + 0x8921, 0xBFCA, 0x8922, 0xEB77, 0x8923, 0xEB79, 0x8925, 0xBFC8, + 0x8926, 0xEB71, 0x8927, 0xEB75, 0x8929, 0xEB78, 0x892A, 0xBFC6, + 0x892B, 0xBFC9, 0x892C, 0xEB7B, 0x892D, 0xEB73, 0x892E, 0xEB74, + 0x892F, 0xEB7A, 0x8930, 0xEB72, 0x8931, 0xEB76, 0x8932, 0xBFC7, + 0x8933, 0xEE72, 0x8935, 0xEE71, 0x8936, 0xC1B7, 0x8937, 0xEE77, + 0x8938, 0xC1B9, 0x893B, 0xC1B6, 0x893C, 0xEE73, 0x893D, 0xC1BA, + 0x893E, 0xEE74, 0x8941, 0xEE75, 0x8942, 0xEE78, 0x8944, 0xC1B8, + 0x8946, 0xF0D6, 0x8949, 0xF0D9, 0x894B, 0xF0D3, 0x894C, 0xF0D5, + 0x894F, 0xF0D4, 0x8950, 0xF0D7, 0x8951, 0xF0D8, 0x8952, 0xEE76, + 0x8953, 0xF0D2, 0x8956, 0xC3CD, 0x8957, 0xF2EC, 0x8958, 0xF2EF, + 0x8959, 0xF2F1, 0x895A, 0xF2EA, 0x895B, 0xF2EB, 0x895C, 0xF2EE, + 0x895D, 0xF2F0, 0x895E, 0xC3CE, 0x895F, 0xC3CC, 0x8960, 0xC3CB, + 0x8961, 0xF2ED, 0x8962, 0xF2E9, 0x8963, 0xF4CA, 0x8964, 0xC4B0, + 0x8966, 0xF4CB, 0x8969, 0xF649, 0x896A, 0xC4FB, 0x896B, 0xF64B, + 0x896C, 0xC4FC, 0x896D, 0xF648, 0x896E, 0xF64A, 0x896F, 0xC5A8, + 0x8971, 0xF752, 0x8972, 0xC5A7, 0x8973, 0xF7FD, 0x8974, 0xF7FC, + 0x8976, 0xF7FB, 0x8979, 0xF948, 0x897A, 0xF949, 0x897B, 0xF94B, + 0x897C, 0xF94A, 0x897E, 0xCA50, 0x897F, 0xA6E8, 0x8981, 0xAD6E, + 0x8982, 0xD7C5, 0x8983, 0xB5F7, 0x8985, 0xDFFA, 0x8986, 0xC2D0, + 0x8988, 0xF2F2, 0x898B, 0xA8A3, 0x898F, 0xB357, 0x8993, 0xB356, + 0x8995, 0xDBD0, 0x8996, 0xB5F8, 0x8997, 0xDBD2, 0x8998, 0xDBD1, + 0x899B, 0xDFFB, 0x899C, 0xB8D0, 0x899D, 0xE443, 0x899E, 0xE446, + 0x899F, 0xE445, 0x89A1, 0xE444, 0x89A2, 0xE7CE, 0x89A3, 0xE7D0, + 0x89A4, 0xE7CF, 0x89A6, 0xBFCC, 0x89AA, 0xBFCB, 0x89AC, 0xC1BB, + 0x89AD, 0xEE79, 0x89AE, 0xEE7B, 0x89AF, 0xEE7A, 0x89B2, 0xC2D1, + 0x89B6, 0xF2F4, 0x89B7, 0xF2F3, 0x89B9, 0xF4CC, 0x89BA, 0xC4B1, + 0x89BD, 0xC4FD, 0x89BE, 0xF754, 0x89BF, 0xF753, 0x89C0, 0xC65B, + 0x89D2, 0xA8A4, 0x89D3, 0xD0AF, 0x89D4, 0xAD6F, 0x89D5, 0xD7C8, + 0x89D6, 0xD7C6, 0x89D9, 0xD7C7, 0x89DA, 0xDBD4, 0x89DB, 0xDBD5, + 0x89DC, 0xE043, 0x89DD, 0xDBD3, 0x89DF, 0xDFFC, 0x89E0, 0xE041, + 0x89E1, 0xE040, 0x89E2, 0xE042, 0x89E3, 0xB8D1, 0x89E4, 0xDFFE, + 0x89E5, 0xDFFD, 0x89E6, 0xE044, 0x89E8, 0xE449, 0x89E9, 0xE447, + 0x89EB, 0xE448, 0x89EC, 0xE7D3, 0x89ED, 0xE7D1, 0x89F0, 0xE7D2, + 0x89F1, 0xEB7D, 0x89F2, 0xEE7C, 0x89F3, 0xEE7D, 0x89F4, 0xC2D2, + 0x89F6, 0xF2F5, 0x89F7, 0xF4CD, 0x89F8, 0xC4B2, 0x89FA, 0xF64C, + 0x89FB, 0xF755, 0x89FC, 0xC5A9, 0x89FE, 0xF7FE, 0x89FF, 0xF94C, + 0x8A00, 0xA8A5, 0x8A02, 0xAD71, 0x8A03, 0xAD72, 0x8A04, 0xD0B0, + 0x8A07, 0xD0B1, 0x8A08, 0xAD70, 0x8A0A, 0xB054, 0x8A0C, 0xB052, + 0x8A0E, 0xB051, 0x8A0F, 0xB058, 0x8A10, 0xB050, 0x8A11, 0xB059, + 0x8A12, 0xD3DD, 0x8A13, 0xB056, 0x8A15, 0xB053, 0x8A16, 0xB057, + 0x8A17, 0xB055, 0x8A18, 0xB04F, 0x8A1B, 0xB35F, 0x8A1D, 0xB359, + 0x8A1E, 0xD7CC, 0x8A1F, 0xB35E, 0x8A22, 0xB360, 0x8A23, 0xB35A, + 0x8A25, 0xB35B, 0x8A27, 0xD7CA, 0x8A2A, 0xB358, 0x8A2C, 0xD7CB, + 0x8A2D, 0xB35D, 0x8A30, 0xD7C9, 0x8A31, 0xB35C, 0x8A34, 0xB644, + 0x8A36, 0xB646, 0x8A39, 0xDBD8, 0x8A3A, 0xB645, 0x8A3B, 0xB5F9, + 0x8A3C, 0xB5FD, 0x8A3E, 0xB8E4, 0x8A3F, 0xE049, 0x8A40, 0xDBDA, + 0x8A41, 0xB5FE, 0x8A44, 0xDBDD, 0x8A45, 0xDBDE, 0x8A46, 0xB643, + 0x8A48, 0xDBE0, 0x8A4A, 0xDBE2, 0x8A4C, 0xDBE3, 0x8A4D, 0xDBD7, + 0x8A4E, 0xDBD6, 0x8A4F, 0xDBE4, 0x8A50, 0xB642, 0x8A51, 0xDBE1, + 0x8A52, 0xDBDF, 0x8A54, 0xB640, 0x8A55, 0xB5FB, 0x8A56, 0xB647, + 0x8A57, 0xDBDB, 0x8A58, 0xDBDC, 0x8A59, 0xDBD9, 0x8A5B, 0xB641, + 0x8A5E, 0xB5FC, 0x8A60, 0xB5FA, 0x8A61, 0xE048, 0x8A62, 0xB8DF, + 0x8A63, 0xB8DA, 0x8A66, 0xB8D5, 0x8A68, 0xB8E5, 0x8A69, 0xB8D6, + 0x8A6B, 0xB8D2, 0x8A6C, 0xB8E1, 0x8A6D, 0xB8DE, 0x8A6E, 0xB8E0, + 0x8A70, 0xB8D7, 0x8A71, 0xB8DC, 0x8A72, 0xB8D3, 0x8A73, 0xB8D4, + 0x8A74, 0xE050, 0x8A75, 0xE04D, 0x8A76, 0xE045, 0x8A77, 0xE04A, + 0x8A79, 0xB8E2, 0x8A7A, 0xE051, 0x8A7B, 0xB8E3, 0x8A7C, 0xB8D9, + 0x8A7F, 0xE047, 0x8A81, 0xE04F, 0x8A82, 0xE04B, 0x8A83, 0xE04E, + 0x8A84, 0xE04C, 0x8A85, 0xB8DD, 0x8A86, 0xE046, 0x8A87, 0xB8D8, + 0x8A8B, 0xE44C, 0x8A8C, 0xBB78, 0x8A8D, 0xBB7B, 0x8A8F, 0xE44E, + 0x8A91, 0xBBA5, 0x8A92, 0xE44D, 0x8A93, 0xBB7D, 0x8A95, 0xBDCF, + 0x8A96, 0xE44F, 0x8A98, 0xBBA4, 0x8A99, 0xE44B, 0x8A9A, 0xBBA6, + 0x8A9E, 0xBB79, 0x8AA0, 0xB8DB, 0x8AA1, 0xBB7C, 0x8AA3, 0xBB7A, + 0x8AA4, 0xBB7E, 0x8AA5, 0xBBA2, 0x8AA6, 0xBB77, 0x8AA7, 0xBBA7, + 0x8AA8, 0xBBA3, 0x8AAA, 0xBBA1, 0x8AAB, 0xE44A, 0x8AB0, 0xBDD6, + 0x8AB2, 0xBDD2, 0x8AB6, 0xBDD9, 0x8AB8, 0xE7D6, 0x8AB9, 0xBDDA, + 0x8ABA, 0xE7E2, 0x8ABB, 0xE7DB, 0x8ABC, 0xBDCB, 0x8ABD, 0xE7E3, + 0x8ABE, 0xE7DD, 0x8ABF, 0xBDD5, 0x8AC0, 0xE7DE, 0x8AC2, 0xBDD4, + 0x8AC3, 0xE7E1, 0x8AC4, 0xBDCE, 0x8AC5, 0xE7DF, 0x8AC6, 0xE7D5, + 0x8AC7, 0xBDCD, 0x8AC8, 0xEBAA, 0x8AC9, 0xBDD3, 0x8ACB, 0xBDD0, + 0x8ACD, 0xBDD8, 0x8ACF, 0xE7D4, 0x8AD1, 0xE7D8, 0x8AD2, 0xBDCC, + 0x8AD3, 0xE7D7, 0x8AD4, 0xE7D9, 0x8AD5, 0xE7DA, 0x8AD6, 0xBDD7, + 0x8AD7, 0xE7DC, 0x8AD8, 0xE7E0, 0x8AD9, 0xE7E4, 0x8ADB, 0xBDDB, + 0x8ADC, 0xBFD2, 0x8ADD, 0xEBA5, 0x8ADE, 0xEBAB, 0x8ADF, 0xEBA8, + 0x8AE0, 0xEB7E, 0x8AE1, 0xEBAC, 0x8AE2, 0xEBA1, 0x8AE4, 0xEBA7, + 0x8AE6, 0xBFCD, 0x8AE7, 0xBFD3, 0x8AE8, 0xEBAD, 0x8AEB, 0xBFCF, + 0x8AED, 0xBFD9, 0x8AEE, 0xBFD4, 0x8AEF, 0xEBAF, 0x8AF0, 0xEBA9, + 0x8AF1, 0xBFD0, 0x8AF2, 0xEBA2, 0x8AF3, 0xBFDA, 0x8AF4, 0xEBA3, + 0x8AF5, 0xEBA4, 0x8AF6, 0xBFDB, 0x8AF7, 0xBFD8, 0x8AF8, 0xBDD1, + 0x8AFA, 0xBFCE, 0x8AFB, 0xEBB0, 0x8AFC, 0xBFDC, 0x8AFE, 0xBFD5, + 0x8AFF, 0xEBAE, 0x8B00, 0xBFD1, 0x8B01, 0xBFD6, 0x8B02, 0xBFD7, + 0x8B04, 0xC1C3, 0x8B05, 0xEEA4, 0x8B06, 0xEEAD, 0x8B07, 0xEEAA, + 0x8B08, 0xEEAC, 0x8B0A, 0xC1C0, 0x8B0B, 0xEEA5, 0x8B0D, 0xEEAB, + 0x8B0E, 0xC1BC, 0x8B0F, 0xEEA7, 0x8B10, 0xC1C4, 0x8B11, 0xEEA3, + 0x8B12, 0xEEA8, 0x8B13, 0xEEAF, 0x8B14, 0xEBA6, 0x8B15, 0xEEA9, + 0x8B16, 0xEEA2, 0x8B17, 0xC1BD, 0x8B18, 0xEEA1, 0x8B19, 0xC1BE, + 0x8B1A, 0xEEB0, 0x8B1B, 0xC1BF, 0x8B1C, 0xEEAE, 0x8B1D, 0xC1C2, + 0x8B1E, 0xEE7E, 0x8B20, 0xC1C1, 0x8B22, 0xEEA6, 0x8B23, 0xF0DC, + 0x8B24, 0xF0EA, 0x8B25, 0xF0E5, 0x8B26, 0xF0E7, 0x8B27, 0xF0DB, + 0x8B28, 0xC2D3, 0x8B2A, 0xF0DA, 0x8B2B, 0xC2D6, 0x8B2C, 0xC2D5, + 0x8B2E, 0xF0E9, 0x8B2F, 0xF0E1, 0x8B30, 0xF0DE, 0x8B31, 0xF0E4, + 0x8B33, 0xF0DD, 0x8B35, 0xF0DF, 0x8B36, 0xF0E8, 0x8B37, 0xF0E6, + 0x8B39, 0xC2D4, 0x8B3A, 0xF0ED, 0x8B3B, 0xF0EB, 0x8B3C, 0xF0E2, + 0x8B3D, 0xF0EC, 0x8B3E, 0xF0E3, 0x8B40, 0xF2F9, 0x8B41, 0xC3CF, + 0x8B42, 0xF341, 0x8B45, 0xF64F, 0x8B46, 0xC3D6, 0x8B47, 0xF0E0, + 0x8B48, 0xF2F7, 0x8B49, 0xC3D2, 0x8B4A, 0xF2F8, 0x8B4B, 0xF2FD, + 0x8B4E, 0xC3D4, 0x8B4F, 0xC3D5, 0x8B50, 0xF2F6, 0x8B51, 0xF340, + 0x8B52, 0xF342, 0x8B53, 0xF2FA, 0x8B54, 0xF2FC, 0x8B55, 0xF2FE, + 0x8B56, 0xF2FB, 0x8B57, 0xF343, 0x8B58, 0xC3D1, 0x8B59, 0xC3D7, + 0x8B5A, 0xC3D3, 0x8B5C, 0xC3D0, 0x8B5D, 0xF4D0, 0x8B5F, 0xC4B7, + 0x8B60, 0xF4CE, 0x8B63, 0xF4D2, 0x8B65, 0xF4D3, 0x8B66, 0xC4B5, + 0x8B67, 0xF4D4, 0x8B68, 0xF4D1, 0x8B6A, 0xF4CF, 0x8B6B, 0xC4B8, + 0x8B6C, 0xC4B4, 0x8B6D, 0xF4D5, 0x8B6F, 0xC4B6, 0x8B70, 0xC4B3, + 0x8B74, 0xC4FE, 0x8B77, 0xC540, 0x8B78, 0xF64E, 0x8B79, 0xF64D, + 0x8B7A, 0xF650, 0x8B7B, 0xF651, 0x8B7D, 0xC541, 0x8B7E, 0xF756, + 0x8B7F, 0xF75B, 0x8B80, 0xC5AA, 0x8B82, 0xF758, 0x8B84, 0xF757, + 0x8B85, 0xF75A, 0x8B86, 0xF759, 0x8B88, 0xF843, 0x8B8A, 0xC5DC, + 0x8B8B, 0xF842, 0x8B8C, 0xF840, 0x8B8E, 0xF841, 0x8B92, 0xC5FE, + 0x8B93, 0xC5FD, 0x8B94, 0xF8C1, 0x8B95, 0xF8C2, 0x8B96, 0xC640, + 0x8B98, 0xF94D, 0x8B99, 0xF94E, 0x8B9A, 0xC667, 0x8B9C, 0xC66D, + 0x8B9E, 0xF9A9, 0x8B9F, 0xF9C8, 0x8C37, 0xA8A6, 0x8C39, 0xD7CD, + 0x8C3B, 0xD7CE, 0x8C3C, 0xE052, 0x8C3D, 0xE450, 0x8C3E, 0xE7E5, + 0x8C3F, 0xC1C6, 0x8C41, 0xC1C5, 0x8C42, 0xF0EE, 0x8C43, 0xF344, + 0x8C45, 0xF844, 0x8C46, 0xA8A7, 0x8C47, 0xD3DE, 0x8C48, 0xB05A, + 0x8C49, 0xB361, 0x8C4A, 0xE054, 0x8C4B, 0xE053, 0x8C4C, 0xBDDC, + 0x8C4D, 0xE7E6, 0x8C4E, 0xBDDD, 0x8C4F, 0xEEB1, 0x8C50, 0xC2D7, + 0x8C54, 0xC676, 0x8C55, 0xA8A8, 0x8C56, 0xCDCB, 0x8C57, 0xD3DF, + 0x8C5A, 0xB362, 0x8C5C, 0xD7CF, 0x8C5D, 0xD7D0, 0x8C5F, 0xDBE5, + 0x8C61, 0xB648, 0x8C62, 0xB8E6, 0x8C64, 0xE056, 0x8C65, 0xE055, + 0x8C66, 0xE057, 0x8C68, 0xE451, 0x8C69, 0xE452, 0x8C6A, 0xBBA8, + 0x8C6B, 0xBFDD, 0x8C6C, 0xBDDE, 0x8C6D, 0xBFDE, 0x8C6F, 0xEEB5, + 0x8C70, 0xEEB2, 0x8C71, 0xEEB4, 0x8C72, 0xEEB3, 0x8C73, 0xC1C7, + 0x8C75, 0xF0EF, 0x8C76, 0xF346, 0x8C77, 0xF345, 0x8C78, 0xCBA4, + 0x8C79, 0xB05C, 0x8C7A, 0xB05B, 0x8C7B, 0xD3E0, 0x8C7D, 0xD7D1, + 0x8C80, 0xDBE7, 0x8C81, 0xDBE6, 0x8C82, 0xB649, 0x8C84, 0xE059, + 0x8C85, 0xE05A, 0x8C86, 0xE058, 0x8C89, 0xB8E8, 0x8C8A, 0xB8E7, + 0x8C8C, 0xBBAA, 0x8C8D, 0xBBA9, 0x8C8F, 0xE7E7, 0x8C90, 0xEBB3, + 0x8C91, 0xEBB1, 0x8C92, 0xEBB2, 0x8C93, 0xBFDF, 0x8C94, 0xEEB7, + 0x8C95, 0xEEB6, 0x8C97, 0xF0F2, 0x8C98, 0xF0F1, 0x8C99, 0xF0F0, + 0x8C9A, 0xF347, 0x8C9C, 0xF9AA, 0x8C9D, 0xA8A9, 0x8C9E, 0xAD73, + 0x8CA0, 0xAD74, 0x8CA1, 0xB05D, 0x8CA2, 0xB05E, 0x8CA3, 0xD3E2, + 0x8CA4, 0xD3E1, 0x8CA5, 0xD7D2, 0x8CA7, 0xB368, 0x8CA8, 0xB366, + 0x8CA9, 0xB363, 0x8CAA, 0xB367, 0x8CAB, 0xB365, 0x8CAC, 0xB364, + 0x8CAF, 0xB64A, 0x8CB0, 0xDBEA, 0x8CB2, 0xB8ED, 0x8CB3, 0xB64C, + 0x8CB4, 0xB651, 0x8CB5, 0xDBEC, 0x8CB6, 0xB653, 0x8CB7, 0xB652, + 0x8CB8, 0xB655, 0x8CB9, 0xDBEB, 0x8CBA, 0xDBE8, 0x8CBB, 0xB64F, + 0x8CBC, 0xB64B, 0x8CBD, 0xB64D, 0x8CBE, 0xDBE9, 0x8CBF, 0xB654, + 0x8CC0, 0xB650, 0x8CC1, 0xB64E, 0x8CC2, 0xB8EF, 0x8CC3, 0xB8EE, + 0x8CC4, 0xB8EC, 0x8CC5, 0xB8F0, 0x8CC7, 0xB8EA, 0x8CC8, 0xB8EB, + 0x8CCA, 0xB8E9, 0x8CCC, 0xE05B, 0x8CCF, 0xE454, 0x8CD1, 0xBBAC, + 0x8CD2, 0xBBAD, 0x8CD3, 0xBBAB, 0x8CD5, 0xE453, 0x8CD7, 0xE455, + 0x8CD9, 0xE7EA, 0x8CDA, 0xE7EC, 0x8CDC, 0xBDE7, 0x8CDD, 0xE7ED, + 0x8CDE, 0xBDE0, 0x8CDF, 0xE7E9, 0x8CE0, 0xBDDF, 0x8CE1, 0xBDE9, + 0x8CE2, 0xBDE5, 0x8CE3, 0xBDE6, 0x8CE4, 0xBDE2, 0x8CE5, 0xE7E8, + 0x8CE6, 0xBDE1, 0x8CE7, 0xE7EE, 0x8CE8, 0xE7EB, 0x8CEA, 0xBDE8, + 0x8CEC, 0xBDE3, 0x8CED, 0xBDE4, 0x8CEE, 0xEBB5, 0x8CF0, 0xEBB7, + 0x8CF1, 0xEBB6, 0x8CF3, 0xEBB8, 0x8CF4, 0xBFE0, 0x8CF5, 0xEBB4, + 0x8CF8, 0xC1CB, 0x8CF9, 0xEEB8, 0x8CFA, 0xC1C8, 0x8CFB, 0xC1CC, + 0x8CFC, 0xC1CA, 0x8CFD, 0xC1C9, 0x8CFE, 0xF0F3, 0x8D00, 0xF0F6, + 0x8D02, 0xF0F5, 0x8D04, 0xF0F4, 0x8D05, 0xC2D8, 0x8D06, 0xF348, + 0x8D07, 0xF349, 0x8D08, 0xC3D8, 0x8D09, 0xF34A, 0x8D0A, 0xC3D9, + 0x8D0D, 0xC4BA, 0x8D0F, 0xC4B9, 0x8D10, 0xF652, 0x8D13, 0xC542, + 0x8D14, 0xF653, 0x8D15, 0xF75C, 0x8D16, 0xC5AB, 0x8D17, 0xC5AC, + 0x8D19, 0xF845, 0x8D1B, 0xC642, 0x8D64, 0xA8AA, 0x8D66, 0xB36A, + 0x8D67, 0xB369, 0x8D68, 0xE05C, 0x8D69, 0xE05D, 0x8D6B, 0xBBAE, + 0x8D6C, 0xEBB9, 0x8D6D, 0xBDEA, 0x8D6E, 0xEBBA, 0x8D6F, 0xEEB9, + 0x8D70, 0xA8AB, 0x8D72, 0xD0B2, 0x8D73, 0xAD76, 0x8D74, 0xAD75, + 0x8D76, 0xD3E3, 0x8D77, 0xB05F, 0x8D78, 0xD3E4, 0x8D79, 0xD7D5, + 0x8D7B, 0xD7D4, 0x8D7D, 0xD7D3, 0x8D80, 0xDBEE, 0x8D81, 0xB658, + 0x8D84, 0xDBED, 0x8D85, 0xB657, 0x8D89, 0xDBEF, 0x8D8A, 0xB656, + 0x8D8C, 0xE05F, 0x8D8D, 0xE062, 0x8D8E, 0xE060, 0x8D8F, 0xE061, + 0x8D90, 0xE065, 0x8D91, 0xE05E, 0x8D92, 0xE066, 0x8D93, 0xE063, + 0x8D94, 0xE064, 0x8D95, 0xBBB0, 0x8D96, 0xE456, 0x8D99, 0xBBAF, + 0x8D9B, 0xE7F2, 0x8D9C, 0xE7F0, 0x8D9F, 0xBDEB, 0x8DA0, 0xE7EF, + 0x8DA1, 0xE7F1, 0x8DA3, 0xBDEC, 0x8DA5, 0xEBBB, 0x8DA7, 0xEBBC, + 0x8DA8, 0xC1CD, 0x8DAA, 0xF34C, 0x8DAB, 0xF34E, 0x8DAC, 0xF34B, + 0x8DAD, 0xF34D, 0x8DAE, 0xF4D6, 0x8DAF, 0xF654, 0x8DB2, 0xF96F, + 0x8DB3, 0xA8AC, 0x8DB4, 0xAD77, 0x8DB5, 0xD3E5, 0x8DB6, 0xD3E7, + 0x8DB7, 0xD3E6, 0x8DB9, 0xD7D8, 0x8DBA, 0xB36C, 0x8DBC, 0xD7D6, + 0x8DBE, 0xB36B, 0x8DBF, 0xD7D9, 0x8DC1, 0xD7DA, 0x8DC2, 0xD7D7, + 0x8DC5, 0xDBFB, 0x8DC6, 0xB660, 0x8DC7, 0xDBF3, 0x8DC8, 0xDBF9, + 0x8DCB, 0xB65B, 0x8DCC, 0xB65E, 0x8DCD, 0xDBF2, 0x8DCE, 0xB659, + 0x8DCF, 0xDBF6, 0x8DD0, 0xE06C, 0x8DD1, 0xB65D, 0x8DD3, 0xDBF1, + 0x8DD5, 0xDBF7, 0x8DD6, 0xDBF4, 0x8DD7, 0xDBFA, 0x8DD8, 0xDBF0, + 0x8DD9, 0xDBF8, 0x8DDA, 0xB65C, 0x8DDB, 0xB65F, 0x8DDC, 0xDBF5, + 0x8DDD, 0xB65A, 0x8DDF, 0xB8F2, 0x8DE0, 0xE068, 0x8DE1, 0xB8F1, + 0x8DE2, 0xE06F, 0x8DE3, 0xE06E, 0x8DE4, 0xB8F8, 0x8DE6, 0xB8F9, + 0x8DE7, 0xE070, 0x8DE8, 0xB8F3, 0x8DE9, 0xE06D, 0x8DEA, 0xB8F7, + 0x8DEB, 0xE072, 0x8DEC, 0xE069, 0x8DEE, 0xE06B, 0x8DEF, 0xB8F4, + 0x8DF0, 0xE067, 0x8DF1, 0xE06A, 0x8DF2, 0xE071, 0x8DF3, 0xB8F5, + 0x8DF4, 0xE073, 0x8DFA, 0xB8F6, 0x8DFC, 0xBBB1, 0x8DFD, 0xE45B, + 0x8DFE, 0xE461, 0x8DFF, 0xE459, 0x8E00, 0xE462, 0x8E02, 0xE458, + 0x8E03, 0xE45D, 0x8E04, 0xE463, 0x8E05, 0xE460, 0x8E06, 0xE45F, + 0x8E07, 0xE45E, 0x8E09, 0xE457, 0x8E0A, 0xE45C, 0x8E0D, 0xE45A, + 0x8E0F, 0xBDF1, 0x8E10, 0xBDEE, 0x8E11, 0xE7FB, 0x8E12, 0xE841, + 0x8E13, 0xE843, 0x8E14, 0xE840, 0x8E15, 0xE7F8, 0x8E16, 0xE7FA, + 0x8E17, 0xE845, 0x8E18, 0xE842, 0x8E19, 0xE7FC, 0x8E1A, 0xE846, + 0x8E1B, 0xE7F9, 0x8E1C, 0xE844, 0x8E1D, 0xBDEF, 0x8E1E, 0xBDF5, + 0x8E1F, 0xBDF3, 0x8E20, 0xE7F3, 0x8E21, 0xBDF4, 0x8E22, 0xBDF0, + 0x8E23, 0xE7F4, 0x8E24, 0xE7F6, 0x8E25, 0xE7F5, 0x8E26, 0xE7FD, + 0x8E27, 0xE7FE, 0x8E29, 0xBDF2, 0x8E2B, 0xBDED, 0x8E2E, 0xE7F7, + 0x8E30, 0xEBC6, 0x8E31, 0xBFE2, 0x8E33, 0xEBBD, 0x8E34, 0xBFE3, + 0x8E35, 0xBFE6, 0x8E36, 0xEBC2, 0x8E38, 0xEBBF, 0x8E39, 0xBFE5, + 0x8E3C, 0xEBC3, 0x8E3D, 0xEBC4, 0x8E3E, 0xEBBE, 0x8E3F, 0xEBC7, + 0x8E40, 0xEBC0, 0x8E41, 0xEBC5, 0x8E42, 0xBFE4, 0x8E44, 0xBFE1, + 0x8E45, 0xEBC1, 0x8E47, 0xEEBF, 0x8E48, 0xC1D0, 0x8E49, 0xC1CE, + 0x8E4A, 0xC1D1, 0x8E4B, 0xC1CF, 0x8E4C, 0xEEBE, 0x8E4D, 0xEEBB, + 0x8E4E, 0xEEBA, 0x8E50, 0xEEBD, 0x8E53, 0xEEBC, 0x8E54, 0xF145, + 0x8E55, 0xC2DE, 0x8E56, 0xF0FB, 0x8E57, 0xF0FA, 0x8E59, 0xC2D9, + 0x8E5A, 0xF141, 0x8E5B, 0xF140, 0x8E5C, 0xF0F7, 0x8E5D, 0xF143, + 0x8E5E, 0xF0FC, 0x8E5F, 0xC2DD, 0x8E60, 0xF0F9, 0x8E61, 0xF142, + 0x8E62, 0xF0F8, 0x8E63, 0xC2DA, 0x8E64, 0xC2DC, 0x8E65, 0xF0FD, + 0x8E66, 0xC2DB, 0x8E67, 0xF0FE, 0x8E69, 0xF144, 0x8E6A, 0xF352, + 0x8E6C, 0xC3DE, 0x8E6D, 0xF34F, 0x8E6F, 0xF353, 0x8E72, 0xC3DB, + 0x8E73, 0xF351, 0x8E74, 0xC3E0, 0x8E76, 0xC3DD, 0x8E78, 0xF350, + 0x8E7A, 0xC3DF, 0x8E7B, 0xF354, 0x8E7C, 0xC3DA, 0x8E81, 0xC4BC, + 0x8E82, 0xC4BE, 0x8E84, 0xF4D9, 0x8E85, 0xC4BD, 0x8E86, 0xF4D7, + 0x8E87, 0xC3DC, 0x8E88, 0xF4D8, 0x8E89, 0xC4BB, 0x8E8A, 0xC543, + 0x8E8B, 0xC545, 0x8E8C, 0xF656, 0x8E8D, 0xC544, 0x8E8E, 0xF655, + 0x8E90, 0xF761, 0x8E91, 0xC5AD, 0x8E92, 0xF760, 0x8E93, 0xC5AE, + 0x8E94, 0xF75E, 0x8E95, 0xF75D, 0x8E96, 0xF762, 0x8E97, 0xF763, + 0x8E98, 0xF846, 0x8E9A, 0xF75F, 0x8E9D, 0xF8C6, 0x8E9E, 0xF8C3, + 0x8E9F, 0xF8C4, 0x8EA0, 0xF8C5, 0x8EA1, 0xC65C, 0x8EA3, 0xF951, + 0x8EA4, 0xF950, 0x8EA5, 0xF94F, 0x8EA6, 0xF970, 0x8EA8, 0xF9BE, + 0x8EA9, 0xF9AB, 0x8EAA, 0xC66E, 0x8EAB, 0xA8AD, 0x8EAC, 0xB060, + 0x8EB2, 0xB8FA, 0x8EBA, 0xBDF6, 0x8EBD, 0xEBC8, 0x8EC0, 0xC2DF, + 0x8EC2, 0xF355, 0x8EC9, 0xF9AC, 0x8ECA, 0xA8AE, 0x8ECB, 0xAAEE, + 0x8ECC, 0xAD79, 0x8ECD, 0xAD78, 0x8ECF, 0xB063, 0x8ED1, 0xD3E8, + 0x8ED2, 0xB061, 0x8ED3, 0xD3E9, 0x8ED4, 0xB062, 0x8ED7, 0xD7DF, + 0x8ED8, 0xD7DB, 0x8EDB, 0xB36D, 0x8EDC, 0xD7DE, 0x8EDD, 0xD7DD, + 0x8EDE, 0xD7DC, 0x8EDF, 0xB36E, 0x8EE0, 0xD7E0, 0x8EE1, 0xD7E1, + 0x8EE5, 0xDC43, 0x8EE6, 0xDC41, 0x8EE7, 0xDC45, 0x8EE8, 0xDC46, + 0x8EE9, 0xDC4C, 0x8EEB, 0xDC48, 0x8EEC, 0xDC4A, 0x8EEE, 0xDC42, + 0x8EEF, 0xDBFC, 0x8EF1, 0xDC49, 0x8EF4, 0xDC4B, 0x8EF5, 0xDC44, + 0x8EF6, 0xDC47, 0x8EF7, 0xDBFD, 0x8EF8, 0xB662, 0x8EF9, 0xDC40, + 0x8EFA, 0xDBFE, 0x8EFB, 0xB661, 0x8EFC, 0xB663, 0x8EFE, 0xB8FD, + 0x8EFF, 0xE075, 0x8F00, 0xE077, 0x8F01, 0xE076, 0x8F02, 0xE07B, + 0x8F03, 0xB8FB, 0x8F05, 0xE078, 0x8F06, 0xE074, 0x8F07, 0xE079, + 0x8F08, 0xE07A, 0x8F09, 0xB8FC, 0x8F0A, 0xB8FE, 0x8F0B, 0xE07C, + 0x8F0D, 0xE467, 0x8F0E, 0xE466, 0x8F10, 0xE464, 0x8F11, 0xE465, + 0x8F12, 0xBBB3, 0x8F13, 0xBBB5, 0x8F14, 0xBBB2, 0x8F15, 0xBBB4, + 0x8F16, 0xE84D, 0x8F17, 0xE84E, 0x8F18, 0xE849, 0x8F1A, 0xE84A, + 0x8F1B, 0xBDF8, 0x8F1C, 0xBDFD, 0x8F1D, 0xBDF7, 0x8F1E, 0xBDFE, + 0x8F1F, 0xBDF9, 0x8F20, 0xE84B, 0x8F23, 0xE84C, 0x8F24, 0xE848, + 0x8F25, 0xBE40, 0x8F26, 0xBDFB, 0x8F29, 0xBDFA, 0x8F2A, 0xBDFC, + 0x8F2C, 0xE847, 0x8F2E, 0xEBCA, 0x8F2F, 0xBFE8, 0x8F32, 0xEBCC, + 0x8F33, 0xBFEA, 0x8F34, 0xEBCF, 0x8F35, 0xEBCB, 0x8F36, 0xEBC9, + 0x8F37, 0xEBCE, 0x8F38, 0xBFE9, 0x8F39, 0xEBCD, 0x8F3B, 0xBFE7, + 0x8F3E, 0xC1D3, 0x8F3F, 0xC1D6, 0x8F40, 0xEEC1, 0x8F42, 0xC1D4, + 0x8F43, 0xEEC0, 0x8F44, 0xC1D2, 0x8F45, 0xC1D5, 0x8F46, 0xF146, + 0x8F47, 0xF147, 0x8F48, 0xF148, 0x8F49, 0xC2E0, 0x8F4B, 0xF149, + 0x8F4D, 0xC2E1, 0x8F4E, 0xC3E2, 0x8F4F, 0xF358, 0x8F50, 0xF359, + 0x8F51, 0xF357, 0x8F52, 0xF356, 0x8F53, 0xF35A, 0x8F54, 0xC3E1, + 0x8F55, 0xF4DD, 0x8F56, 0xF4DB, 0x8F57, 0xF4DC, 0x8F58, 0xF4DE, + 0x8F59, 0xF4DA, 0x8F5A, 0xF4DF, 0x8F5B, 0xF658, 0x8F5D, 0xF659, + 0x8F5E, 0xF657, 0x8F5F, 0xC546, 0x8F60, 0xF764, 0x8F61, 0xC5AF, + 0x8F62, 0xF765, 0x8F63, 0xF848, 0x8F64, 0xF847, 0x8F9B, 0xA8AF, + 0x8F9C, 0xB664, 0x8F9F, 0xB940, 0x8FA3, 0xBBB6, 0x8FA6, 0xBFEC, + 0x8FA8, 0xBFEB, 0x8FAD, 0xC3E3, 0x8FAE, 0xC47C, 0x8FAF, 0xC547, + 0x8FB0, 0xA8B0, 0x8FB1, 0xB064, 0x8FB2, 0xB941, 0x8FB4, 0xF35B, + 0x8FBF, 0xCBA6, 0x8FC2, 0xA8B1, 0x8FC4, 0xA8B4, 0x8FC5, 0xA8B3, + 0x8FC6, 0xA8B2, 0x8FC9, 0xCBA5, 0x8FCB, 0xCDCD, 0x8FCD, 0xCDCF, + 0x8FCE, 0xAAEF, 0x8FD1, 0xAAF1, 0x8FD2, 0xCDCC, 0x8FD3, 0xCDCE, + 0x8FD4, 0xAAF0, 0x8FD5, 0xCDD1, 0x8FD6, 0xCDD0, 0x8FD7, 0xCDD2, + 0x8FE0, 0xD0B6, 0x8FE1, 0xD0B4, 0x8FE2, 0xAD7C, 0x8FE3, 0xD0B3, + 0x8FE4, 0xADA3, 0x8FE5, 0xAD7E, 0x8FE6, 0xAD7B, 0x8FE8, 0xADA4, + 0x8FEA, 0xAD7D, 0x8FEB, 0xADA2, 0x8FED, 0xADA1, 0x8FEE, 0xD0B5, + 0x8FF0, 0xAD7A, 0x8FF4, 0xB06A, 0x8FF5, 0xD3EB, 0x8FF6, 0xD3F1, + 0x8FF7, 0xB067, 0x8FF8, 0xB06E, 0x8FFA, 0xB069, 0x8FFB, 0xD3EE, + 0x8FFC, 0xD3F0, 0x8FFD, 0xB06C, 0x8FFE, 0xD3EA, 0x8FFF, 0xD3ED, + 0x9000, 0xB068, 0x9001, 0xB065, 0x9002, 0xD3EC, 0x9003, 0xB06B, + 0x9004, 0xD3EF, 0x9005, 0xB06D, 0x9006, 0xB066, 0x900B, 0xD7E3, + 0x900C, 0xD7E6, 0x900D, 0xB370, 0x900F, 0xB37A, 0x9010, 0xB376, + 0x9011, 0xD7E4, 0x9014, 0xB37E, 0x9015, 0xB377, 0x9016, 0xB37C, + 0x9017, 0xB372, 0x9019, 0xB36F, 0x901A, 0xB371, 0x901B, 0xB37D, + 0x901C, 0xD7E5, 0x901D, 0xB375, 0x901E, 0xB378, 0x901F, 0xB374, + 0x9020, 0xB379, 0x9021, 0xD7E7, 0x9022, 0xB37B, 0x9023, 0xB373, + 0x9024, 0xD7E2, 0x902D, 0xDC4D, 0x902E, 0xB665, 0x902F, 0xDC4F, + 0x9031, 0xB667, 0x9032, 0xB669, 0x9034, 0xDC4E, 0x9035, 0xB666, + 0x9036, 0xB66A, 0x9038, 0xB668, 0x903C, 0xB947, 0x903D, 0xE0A3, + 0x903E, 0xB94F, 0x903F, 0xE07E, 0x9041, 0xB950, 0x9042, 0xB945, + 0x9044, 0xE0A1, 0x9047, 0xB94A, 0x9049, 0xE0A2, 0x904A, 0xB943, + 0x904B, 0xB942, 0x904D, 0xB94D, 0x904E, 0xB94C, 0x904F, 0xB94B, + 0x9050, 0xB949, 0x9051, 0xB94E, 0x9052, 0xE07D, 0x9053, 0xB944, + 0x9054, 0xB946, 0x9055, 0xB948, 0x9058, 0xBBB8, 0x9059, 0xBBBB, + 0x905B, 0xBBBF, 0x905C, 0xBBB9, 0x905D, 0xBBBE, 0x905E, 0xBBBC, + 0x9060, 0xBBB7, 0x9062, 0xBBBD, 0x9063, 0xBBBA, 0x9067, 0xE852, + 0x9068, 0xBE43, 0x9069, 0xBE41, 0x906B, 0xE853, 0x906D, 0xBE44, + 0x906E, 0xBE42, 0x906F, 0xE851, 0x9070, 0xE850, 0x9072, 0xBFF0, + 0x9073, 0xE84F, 0x9074, 0xBFEE, 0x9075, 0xBFED, 0x9076, 0xEBD0, + 0x9077, 0xBE45, 0x9078, 0xBFEF, 0x9079, 0xEBD1, 0x907A, 0xBFF2, + 0x907B, 0xEBD2, 0x907C, 0xBFF1, 0x907D, 0xC1D8, 0x907E, 0xEEC3, + 0x907F, 0xC1D7, 0x9080, 0xC1DC, 0x9081, 0xC1DA, 0x9082, 0xC1DB, + 0x9083, 0xC2E3, 0x9084, 0xC1D9, 0x9085, 0xEEC2, 0x9086, 0xEBD3, + 0x9087, 0xC2E2, 0x9088, 0xC2E4, 0x908A, 0xC3E4, 0x908B, 0xC3E5, + 0x908D, 0xF4E0, 0x908F, 0xC5DE, 0x9090, 0xC5DD, 0x9091, 0xA8B6, + 0x9094, 0xCA55, 0x9095, 0xB06F, 0x9097, 0xCA52, 0x9098, 0xCA53, + 0x9099, 0xCA51, 0x909B, 0xCA54, 0x909E, 0xCBAA, 0x909F, 0xCBA7, + 0x90A0, 0xCBAC, 0x90A1, 0xCBA8, 0x90A2, 0xA8B7, 0x90A3, 0xA8BA, + 0x90A5, 0xCBA9, 0x90A6, 0xA8B9, 0x90A7, 0xCBAB, 0x90AA, 0xA8B8, + 0x90AF, 0xCDD5, 0x90B0, 0xCDD7, 0x90B1, 0xAAF4, 0x90B2, 0xCDD3, + 0x90B3, 0xCDD6, 0x90B4, 0xCDD4, 0x90B5, 0xAAF2, 0x90B6, 0xAAF5, + 0x90B8, 0xAAF3, 0x90BD, 0xD0B8, 0x90BE, 0xD0BC, 0x90BF, 0xD0B9, + 0x90C1, 0xADA7, 0x90C3, 0xADA8, 0x90C5, 0xD0BB, 0x90C7, 0xD0BD, + 0x90C8, 0xD0BF, 0x90CA, 0xADA5, 0x90CB, 0xD0BE, 0x90CE, 0xADA6, + 0x90D4, 0xD7EE, 0x90D5, 0xD0BA, 0x90D6, 0xD3F2, 0x90D7, 0xD3FB, + 0x90D8, 0xD3F9, 0x90D9, 0xD3F4, 0x90DA, 0xD3F5, 0x90DB, 0xD3FA, + 0x90DC, 0xD3FC, 0x90DD, 0xB071, 0x90DF, 0xD3F7, 0x90E0, 0xD3F3, + 0x90E1, 0xB070, 0x90E2, 0xB072, 0x90E3, 0xD3F6, 0x90E4, 0xD3FD, + 0x90E5, 0xD3F8, 0x90E8, 0xB3A1, 0x90E9, 0xD7F1, 0x90EA, 0xD7E9, + 0x90EB, 0xD7EF, 0x90EC, 0xD7F0, 0x90ED, 0xB3A2, 0x90EF, 0xD7E8, + 0x90F0, 0xD7EA, 0x90F1, 0xD0B7, 0x90F2, 0xD7EC, 0x90F3, 0xD7ED, + 0x90F4, 0xD7EB, 0x90F5, 0xB66C, 0x90F9, 0xDC56, 0x90FA, 0xEBD4, + 0x90FB, 0xDC57, 0x90FC, 0xDC54, 0x90FD, 0xB3A3, 0x90FE, 0xB66E, + 0x90FF, 0xDC53, 0x9100, 0xDC59, 0x9101, 0xDC58, 0x9102, 0xB66B, + 0x9103, 0xDC5C, 0x9104, 0xDC52, 0x9105, 0xDC5B, 0x9106, 0xDC50, + 0x9107, 0xDC5A, 0x9108, 0xDC55, 0x9109, 0xB66D, 0x910B, 0xE0AA, + 0x910D, 0xE0A5, 0x910E, 0xE0AB, 0x910F, 0xE0A6, 0x9110, 0xE0A4, + 0x9111, 0xE0A7, 0x9112, 0xB951, 0x9114, 0xE0A9, 0x9116, 0xE0A8, + 0x9117, 0xB952, 0x9118, 0xBBC1, 0x9119, 0xBBC0, 0x911A, 0xE46E, + 0x911B, 0xE471, 0x911C, 0xE469, 0x911D, 0xE46D, 0x911E, 0xBBC2, + 0x911F, 0xE46C, 0x9120, 0xE46A, 0x9121, 0xE470, 0x9122, 0xE46B, + 0x9123, 0xE468, 0x9124, 0xE46F, 0x9126, 0xE859, 0x9127, 0xBE48, + 0x9128, 0xF14A, 0x9129, 0xE856, 0x912A, 0xE857, 0x912B, 0xE855, + 0x912C, 0xDC51, 0x912D, 0xBE47, 0x912E, 0xE85A, 0x912F, 0xE854, + 0x9130, 0xBE46, 0x9131, 0xBE49, 0x9132, 0xE858, 0x9133, 0xEBD5, + 0x9134, 0xBFF3, 0x9135, 0xEBD6, 0x9136, 0xEBD7, 0x9138, 0xEEC4, + 0x9139, 0xC1DD, 0x913A, 0xF14B, 0x913B, 0xF14C, 0x913E, 0xF14D, + 0x913F, 0xF35D, 0x9140, 0xF35C, 0x9141, 0xF4E2, 0x9143, 0xF4E1, + 0x9144, 0xF65B, 0x9145, 0xF65C, 0x9146, 0xF65A, 0x9147, 0xF766, + 0x9148, 0xC5B0, 0x9149, 0xA8BB, 0x914A, 0xADAA, 0x914B, 0xADA9, + 0x914C, 0xB075, 0x914D, 0xB074, 0x914E, 0xD440, 0x914F, 0xD441, + 0x9150, 0xD3FE, 0x9152, 0xB073, 0x9153, 0xD7F5, 0x9155, 0xD7F6, + 0x9156, 0xD7F2, 0x9157, 0xB3A4, 0x9158, 0xD7F3, 0x915A, 0xD7F4, + 0x915F, 0xDC5F, 0x9160, 0xDC61, 0x9161, 0xDC5D, 0x9162, 0xDC60, + 0x9163, 0xB66F, 0x9164, 0xDC5E, 0x9165, 0xB670, 0x9168, 0xDD73, + 0x9169, 0xB955, 0x916A, 0xB954, 0x916C, 0xB953, 0x916E, 0xE0AC, + 0x916F, 0xE0AD, 0x9172, 0xE473, 0x9173, 0xE475, 0x9174, 0xBBC6, + 0x9175, 0xBBC3, 0x9177, 0xBBC5, 0x9178, 0xBBC4, 0x9179, 0xE474, + 0x917A, 0xE472, 0x9180, 0xE861, 0x9181, 0xE85E, 0x9182, 0xE85F, + 0x9183, 0xBE4D, 0x9184, 0xE860, 0x9185, 0xE85B, 0x9186, 0xE85C, + 0x9187, 0xBE4A, 0x9189, 0xBE4B, 0x918A, 0xE85D, 0x918B, 0xBE4C, + 0x918D, 0xEBDB, 0x918F, 0xEBDC, 0x9190, 0xEBD9, 0x9191, 0xEBDA, + 0x9192, 0xBFF4, 0x9193, 0xEBD8, 0x9199, 0xEEC8, 0x919A, 0xEEC5, + 0x919B, 0xEEC7, 0x919C, 0xC1E0, 0x919D, 0xEECB, 0x919E, 0xC1DF, + 0x919F, 0xEEC9, 0x91A0, 0xEECC, 0x91A1, 0xEECA, 0x91A2, 0xEEC6, + 0x91A3, 0xC1DE, 0x91A5, 0xF14F, 0x91A7, 0xF150, 0x91A8, 0xF14E, + 0x91AA, 0xF152, 0x91AB, 0xC2E5, 0x91AC, 0xC2E6, 0x91AD, 0xF35F, + 0x91AE, 0xC3E7, 0x91AF, 0xF151, 0x91B0, 0xF35E, 0x91B1, 0xC3E6, + 0x91B2, 0xF4E5, 0x91B3, 0xF4E6, 0x91B4, 0xC4BF, 0x91B5, 0xF4E4, + 0x91B7, 0xF4E3, 0x91B9, 0xF65D, 0x91BA, 0xC548, 0x91BC, 0xF849, + 0x91BD, 0xF8C8, 0x91BE, 0xF8C7, 0x91C0, 0xC643, 0x91C1, 0xC65D, + 0x91C2, 0xF8C9, 0x91C3, 0xF971, 0x91C5, 0xC66F, 0x91C6, 0xA8BC, + 0x91C7, 0xAAF6, 0x91C9, 0xB956, 0x91CB, 0xC4C0, 0x91CC, 0xA8BD, + 0x91CD, 0xADAB, 0x91CE, 0xB3A5, 0x91CF, 0xB671, 0x91D0, 0xC2E7, + 0x91D1, 0xAAF7, 0x91D3, 0xD0C1, 0x91D4, 0xD0C0, 0x91D5, 0xD442, + 0x91D7, 0xB078, 0x91D8, 0xB076, 0x91D9, 0xB07A, 0x91DA, 0xD444, + 0x91DC, 0xB079, 0x91DD, 0xB077, 0x91E2, 0xD443, 0x91E3, 0xB3A8, + 0x91E4, 0xD7FC, 0x91E6, 0xB3A7, 0x91E7, 0xB3A9, 0x91E8, 0xD842, + 0x91E9, 0xB3AB, 0x91EA, 0xD7FE, 0x91EB, 0xD840, 0x91EC, 0xD7F7, + 0x91ED, 0xB3AA, 0x91EE, 0xD843, 0x91F1, 0xD7F9, 0x91F3, 0xD7FA, + 0x91F4, 0xD7F8, 0x91F5, 0xB3A6, 0x91F7, 0xD841, 0x91F8, 0xD7FB, + 0x91F9, 0xD7FD, 0x91FD, 0xDC6D, 0x91FF, 0xDC6C, 0x9200, 0xDC6A, + 0x9201, 0xDC62, 0x9202, 0xDC71, 0x9203, 0xDC65, 0x9204, 0xDC6F, + 0x9205, 0xDC76, 0x9206, 0xDC6E, 0x9207, 0xB679, 0x9209, 0xB675, + 0x920A, 0xDC63, 0x920C, 0xDC69, 0x920D, 0xB677, 0x920F, 0xDC68, + 0x9210, 0xB678, 0x9211, 0xB67A, 0x9212, 0xDC6B, 0x9214, 0xB672, + 0x9215, 0xB673, 0x9216, 0xDC77, 0x9217, 0xDC75, 0x9219, 0xDC74, + 0x921A, 0xDC66, 0x921C, 0xDC72, 0x921E, 0xB676, 0x9223, 0xB674, + 0x9224, 0xDC73, 0x9225, 0xDC64, 0x9226, 0xDC67, 0x9227, 0xDC70, + 0x922D, 0xE4BA, 0x922E, 0xE0B7, 0x9230, 0xE0B0, 0x9231, 0xE0C3, + 0x9232, 0xE0CC, 0x9233, 0xE0B3, 0x9234, 0xB961, 0x9236, 0xE0C0, + 0x9237, 0xB957, 0x9238, 0xB959, 0x9239, 0xB965, 0x923A, 0xE0B1, + 0x923D, 0xB95A, 0x923E, 0xB95C, 0x923F, 0xB966, 0x9240, 0xB95B, + 0x9245, 0xB964, 0x9246, 0xE0B9, 0x9248, 0xE0AE, 0x9249, 0xB962, + 0x924A, 0xE0B8, 0x924B, 0xB95E, 0x924C, 0xE0CA, 0x924D, 0xB963, + 0x924E, 0xE0C8, 0x924F, 0xE0BC, 0x9250, 0xE0C6, 0x9251, 0xB960, + 0x9252, 0xE0AF, 0x9253, 0xE0C9, 0x9254, 0xE0C4, 0x9256, 0xE0CB, + 0x9257, 0xB958, 0x925A, 0xB967, 0x925B, 0xB95D, 0x925E, 0xE0B5, + 0x9260, 0xE0BD, 0x9261, 0xE0C1, 0x9263, 0xE0C5, 0x9264, 0xB95F, + 0x9265, 0xE0B4, 0x9266, 0xE0B2, 0x9267, 0xE0BE, 0x926C, 0xE0BB, + 0x926D, 0xE0BA, 0x926F, 0xE0BF, 0x9270, 0xE0C2, 0x9272, 0xE0C7, + 0x9276, 0xE478, 0x9278, 0xBBC7, 0x9279, 0xE4A4, 0x927A, 0xE47A, + 0x927B, 0xBBCC, 0x927C, 0xBBD0, 0x927D, 0xE4AD, 0x927E, 0xE4B5, + 0x927F, 0xE4A6, 0x9280, 0xBBC8, 0x9282, 0xE4AA, 0x9283, 0xE0B6, + 0x9285, 0xBBC9, 0x9286, 0xE4B1, 0x9287, 0xE4B6, 0x9288, 0xE4AE, + 0x928A, 0xE4B0, 0x928B, 0xE4B9, 0x928C, 0xE4B2, 0x928D, 0xE47E, + 0x928E, 0xE4A9, 0x9291, 0xBBD1, 0x9293, 0xBBCD, 0x9294, 0xE47C, + 0x9295, 0xE4AB, 0x9296, 0xBBCB, 0x9297, 0xE4A5, 0x9298, 0xBBCA, + 0x9299, 0xE4B3, 0x929A, 0xE4A2, 0x929B, 0xE479, 0x929C, 0xBBCE, + 0x929D, 0xE4B8, 0x92A0, 0xE47B, 0x92A1, 0xE4AF, 0x92A2, 0xE4AC, + 0x92A3, 0xE4A7, 0x92A4, 0xE477, 0x92A5, 0xE476, 0x92A6, 0xE4A1, + 0x92A7, 0xE4B4, 0x92A8, 0xBBCF, 0x92A9, 0xE4B7, 0x92AA, 0xE47D, + 0x92AB, 0xE4A3, 0x92AC, 0xBE52, 0x92B2, 0xBE5A, 0x92B3, 0xBE55, + 0x92B4, 0xE8A4, 0x92B5, 0xE8A1, 0x92B6, 0xE867, 0x92B7, 0xBE50, + 0x92B9, 0xF9D7, 0x92BB, 0xBE4F, 0x92BC, 0xBE56, 0x92C0, 0xE865, + 0x92C1, 0xBE54, 0x92C2, 0xE871, 0x92C3, 0xE863, 0x92C4, 0xE864, + 0x92C5, 0xBE4E, 0x92C6, 0xE8A3, 0x92C7, 0xBE58, 0x92C8, 0xE874, + 0x92C9, 0xE879, 0x92CA, 0xE873, 0x92CB, 0xEBEE, 0x92CC, 0xE86F, + 0x92CD, 0xE877, 0x92CE, 0xE875, 0x92CF, 0xE868, 0x92D0, 0xE862, + 0x92D1, 0xE87D, 0x92D2, 0xBE57, 0x92D3, 0xE87E, 0x92D5, 0xE878, + 0x92D7, 0xE86D, 0x92D8, 0xE86B, 0x92D9, 0xE866, 0x92DD, 0xE86E, + 0x92DE, 0xE87B, 0x92DF, 0xE86A, 0x92E0, 0xE87A, 0x92E1, 0xE8A2, + 0x92E4, 0xBE53, 0x92E6, 0xE876, 0x92E7, 0xE87C, 0x92E8, 0xE872, + 0x92E9, 0xE86C, 0x92EA, 0xBE51, 0x92EE, 0xE4A8, 0x92EF, 0xE870, + 0x92F0, 0xBE59, 0x92F1, 0xE869, 0x92F7, 0xEBF4, 0x92F8, 0xBFF7, + 0x92F9, 0xEBF3, 0x92FA, 0xEBF0, 0x92FB, 0xEC44, 0x92FC, 0xBFFB, + 0x92FE, 0xEC41, 0x92FF, 0xEBF8, 0x9300, 0xEC43, 0x9301, 0xEBE9, + 0x9302, 0xEBF6, 0x9304, 0xBFFD, 0x9306, 0xEBE1, 0x9308, 0xEBDF, + 0x9309, 0xEC42, 0x930B, 0xEC40, 0x930C, 0xEBFE, 0x930D, 0xEBED, + 0x930E, 0xEBEC, 0x930F, 0xEBE2, 0x9310, 0xC040, 0x9312, 0xEBE8, + 0x9313, 0xEBF2, 0x9314, 0xEBFD, 0x9315, 0xC043, 0x9316, 0xEC45, + 0x9318, 0xC1E8, 0x9319, 0xC045, 0x931A, 0xBFFE, 0x931B, 0xEBE6, + 0x931D, 0xEBEF, 0x931E, 0xEBDE, 0x931F, 0xEBE0, 0x9320, 0xBFF5, + 0x9321, 0xC042, 0x9322, 0xBFFA, 0x9323, 0xEBE7, 0x9324, 0xEBF7, + 0x9325, 0xEBF1, 0x9326, 0xC041, 0x9327, 0xEBDD, 0x9328, 0xC1E3, + 0x9329, 0xEBF9, 0x932A, 0xEBFC, 0x932B, 0xBFFC, 0x932D, 0xEBEB, + 0x932E, 0xC044, 0x932F, 0xBFF9, 0x9333, 0xBFF8, 0x9334, 0xEBF5, + 0x9335, 0xEBFB, 0x9336, 0xBFF6, 0x9338, 0xEBE4, 0x9339, 0xEBFA, + 0x933C, 0xEBE5, 0x9346, 0xEBEA, 0x9347, 0xEED2, 0x9349, 0xEED7, + 0x934A, 0xC1E5, 0x934B, 0xC1E7, 0x934C, 0xEEDD, 0x934D, 0xC1E1, + 0x934E, 0xEEEC, 0x934F, 0xEEE3, 0x9350, 0xEED8, 0x9351, 0xEED9, + 0x9352, 0xEEE2, 0x9354, 0xC1EE, 0x9355, 0xEEE1, 0x9356, 0xEED1, + 0x9357, 0xEEE0, 0x9358, 0xEED4, 0x9359, 0xEEED, 0x935A, 0xC1ED, + 0x935B, 0xC1EB, 0x935C, 0xEED5, 0x935E, 0xEEE8, 0x9360, 0xEEDA, + 0x9361, 0xEEE7, 0x9363, 0xEEE9, 0x9364, 0xEED0, 0x9365, 0xC1E6, + 0x9367, 0xEEEA, 0x936A, 0xEEDE, 0x936C, 0xC1EA, 0x936D, 0xEEDB, + 0x9370, 0xC1EC, 0x9371, 0xEEE4, 0x9375, 0xC1E4, 0x9376, 0xEED6, + 0x9377, 0xEEE5, 0x9379, 0xEEDF, 0x937A, 0xEBE3, 0x937B, 0xEEE6, + 0x937C, 0xEED3, 0x937E, 0xC1E9, 0x9380, 0xEEEB, 0x9382, 0xC1E2, + 0x9383, 0xEECE, 0x9388, 0xF160, 0x9389, 0xF159, 0x938A, 0xC2E9, + 0x938C, 0xF154, 0x938D, 0xF163, 0x938E, 0xF15B, 0x938F, 0xEEDC, + 0x9391, 0xF165, 0x9392, 0xF155, 0x9394, 0xC2E8, 0x9395, 0xF15F, + 0x9396, 0xC2EA, 0x9397, 0xC2F2, 0x9398, 0xC2F0, 0x9399, 0xF161, + 0x939A, 0xC2F1, 0x939B, 0xF157, 0x939D, 0xF158, 0x939E, 0xF15D, + 0x939F, 0xF162, 0x93A1, 0xEECD, 0x93A2, 0xC2EB, 0x93A3, 0xF16A, + 0x93A4, 0xF167, 0x93A5, 0xF16B, 0x93A6, 0xF15E, 0x93A7, 0xF15A, + 0x93A8, 0xF168, 0x93A9, 0xF36A, 0x93AA, 0xF15C, 0x93AC, 0xC2EE, + 0x93AE, 0xC2ED, 0x93AF, 0xEECF, 0x93B0, 0xC2EF, 0x93B1, 0xF164, + 0x93B2, 0xF166, 0x93B3, 0xC2EC, 0x93B4, 0xF169, 0x93B5, 0xF153, + 0x93B7, 0xF156, 0x93C0, 0xF373, 0x93C2, 0xF363, 0x93C3, 0xC3EB, + 0x93C4, 0xF371, 0x93C7, 0xF361, 0x93C8, 0xC3EC, 0x93CA, 0xF36C, + 0x93CC, 0xF368, 0x93CD, 0xC3F1, 0x93CE, 0xF372, 0x93CF, 0xF362, + 0x93D0, 0xF365, 0x93D1, 0xC3E9, 0x93D2, 0xF374, 0x93D4, 0xF36D, + 0x93D5, 0xF370, 0x93D6, 0xC3EF, 0x93D7, 0xC3F4, 0x93D8, 0xC3F2, + 0x93D9, 0xF369, 0x93DA, 0xF364, 0x93DC, 0xC3ED, 0x93DD, 0xC3EE, + 0x93DE, 0xF360, 0x93DF, 0xC3EA, 0x93E1, 0xC3E8, 0x93E2, 0xC3F0, + 0x93E3, 0xF36F, 0x93E4, 0xC3F3, 0x93E6, 0xF36B, 0x93E7, 0xF375, + 0x93E8, 0xC3F5, 0x93EC, 0xF367, 0x93EE, 0xF36E, 0x93F5, 0xF4F3, + 0x93F6, 0xF542, 0x93F7, 0xF4F5, 0x93F8, 0xF4FC, 0x93F9, 0xF366, + 0x93FA, 0xF4FA, 0x93FB, 0xF4E9, 0x93FC, 0xF540, 0x93FD, 0xC4C3, + 0x93FE, 0xF4ED, 0x93FF, 0xF4FE, 0x9400, 0xF4F4, 0x9403, 0xC4C2, + 0x9406, 0xF544, 0x9407, 0xF4F6, 0x9409, 0xF4FB, 0x940A, 0xF4FD, + 0x940B, 0xF4E7, 0x940C, 0xF541, 0x940D, 0xF4F2, 0x940E, 0xF4F7, + 0x940F, 0xF4EB, 0x9410, 0xF4EF, 0x9411, 0xF543, 0x9412, 0xF4F9, + 0x9413, 0xF4E8, 0x9414, 0xF4EC, 0x9415, 0xF4EE, 0x9416, 0xF4F8, + 0x9418, 0xC4C1, 0x9419, 0xF4F1, 0x9420, 0xF4EA, 0x9428, 0xF4F0, + 0x9429, 0xF661, 0x942A, 0xF666, 0x942B, 0xC54F, 0x942C, 0xF668, + 0x942E, 0xC549, 0x9430, 0xF664, 0x9431, 0xF66A, 0x9432, 0xC54E, + 0x9433, 0xC54A, 0x9435, 0xC54B, 0x9436, 0xF660, 0x9437, 0xF667, + 0x9438, 0xC54D, 0x9439, 0xF665, 0x943A, 0xC54C, 0x943B, 0xF65F, + 0x943C, 0xF663, 0x943D, 0xF662, 0x943F, 0xF65E, 0x9440, 0xF669, + 0x9444, 0xC5B1, 0x9445, 0xF76D, 0x9446, 0xF770, 0x9447, 0xF76C, + 0x9448, 0xF76E, 0x9449, 0xF76F, 0x944A, 0xF769, 0x944B, 0xF76A, + 0x944C, 0xF767, 0x944F, 0xF76B, 0x9450, 0xF768, 0x9451, 0xC5B2, + 0x9452, 0xC5B3, 0x9455, 0xF84B, 0x9457, 0xF84D, 0x945D, 0xF84C, + 0x945E, 0xF84E, 0x9460, 0xC5E0, 0x9462, 0xF84A, 0x9463, 0xC5DF, + 0x9464, 0xC5E1, 0x9468, 0xF8CB, 0x9469, 0xF8CC, 0x946A, 0xC644, + 0x946B, 0xF8CA, 0x946D, 0xF953, 0x946E, 0xF952, 0x946F, 0xF954, + 0x9470, 0xC65F, 0x9471, 0xF955, 0x9472, 0xC65E, 0x9473, 0xF956, + 0x9474, 0xF972, 0x9475, 0xF975, 0x9476, 0xF974, 0x9477, 0xC668, + 0x9478, 0xF973, 0x947C, 0xC672, 0x947D, 0xC670, 0x947E, 0xC671, + 0x947F, 0xC677, 0x9480, 0xF9C0, 0x9481, 0xF9C1, 0x9482, 0xF9BF, + 0x9483, 0xF9C9, 0x9577, 0xAAF8, 0x957A, 0xD844, 0x957B, 0xDC78, + 0x957C, 0xE8A5, 0x957D, 0xF376, 0x9580, 0xAAF9, 0x9582, 0xADAC, + 0x9583, 0xB07B, 0x9586, 0xD845, 0x9588, 0xD846, 0x9589, 0xB3AC, + 0x958B, 0xB67D, 0x958C, 0xDC7A, 0x958D, 0xDC79, 0x958E, 0xB6A3, + 0x958F, 0xB67C, 0x9590, 0xDC7B, 0x9591, 0xB67E, 0x9592, 0xB6A2, + 0x9593, 0xB6A1, 0x9594, 0xB67B, 0x9598, 0xB968, 0x959B, 0xE0D0, + 0x959C, 0xE0CE, 0x959E, 0xE0CF, 0x959F, 0xE0CD, 0x95A1, 0xBBD2, + 0x95A3, 0xBBD5, 0x95A4, 0xBBD7, 0x95A5, 0xBBD6, 0x95A8, 0xBBD3, + 0x95A9, 0xBBD4, 0x95AB, 0xE8A7, 0x95AC, 0xE8A6, 0x95AD, 0xBE5B, + 0x95AE, 0xE8A8, 0x95B0, 0xE8A9, 0x95B1, 0xBE5C, 0x95B5, 0xEC4D, + 0x95B6, 0xEC4B, 0x95B7, 0xEEF3, 0x95B9, 0xEC49, 0x95BA, 0xEC4A, + 0x95BB, 0xC046, 0x95BC, 0xEC46, 0x95BD, 0xEC4E, 0x95BE, 0xEC48, + 0x95BF, 0xEC4C, 0x95C0, 0xEEEF, 0x95C3, 0xEEF1, 0x95C5, 0xEEF2, + 0x95C6, 0xC1F3, 0x95C7, 0xEEEE, 0x95C8, 0xC1F2, 0x95C9, 0xEEF0, + 0x95CA, 0xC1EF, 0x95CB, 0xC1F0, 0x95CC, 0xC1F1, 0x95CD, 0xEC47, + 0x95D0, 0xC2F5, 0x95D1, 0xF16E, 0x95D2, 0xF16C, 0x95D3, 0xF16D, + 0x95D4, 0xC2F3, 0x95D5, 0xC2F6, 0x95D6, 0xC2F4, 0x95DA, 0xF377, + 0x95DB, 0xF378, 0x95DC, 0xC3F6, 0x95DE, 0xF545, 0x95DF, 0xF547, + 0x95E0, 0xF546, 0x95E1, 0xC4C4, 0x95E2, 0xC550, 0x95E3, 0xF66D, + 0x95E4, 0xF66C, 0x95E5, 0xF66B, 0x961C, 0xAAFA, 0x961E, 0xC9AA, + 0x9620, 0xCA58, 0x9621, 0xA6E9, 0x9622, 0xCA56, 0x9623, 0xCA59, + 0x9624, 0xCA57, 0x9628, 0xCBAE, 0x962A, 0xA8C1, 0x962C, 0xA8C2, + 0x962D, 0xCBB0, 0x962E, 0xA8BF, 0x962F, 0xCBAF, 0x9630, 0xCBAD, + 0x9631, 0xA8C0, 0x9632, 0xA8BE, 0x9639, 0xCDD8, 0x963A, 0xCDDB, + 0x963B, 0xAAFD, 0x963C, 0xCDDA, 0x963D, 0xCDD9, 0x963F, 0xAAFC, + 0x9640, 0xAAFB, 0x9642, 0xAB40, 0x9643, 0xCDDC, 0x9644, 0xAAFE, + 0x964A, 0xD0C6, 0x964B, 0xADAE, 0x964C, 0xADAF, 0x964D, 0xADB0, + 0x964E, 0xD0C7, 0x964F, 0xD0C3, 0x9650, 0xADAD, 0x9651, 0xD0C4, + 0x9653, 0xD0C5, 0x9654, 0xD0C2, 0x9658, 0xB0A4, 0x965B, 0xB0A1, + 0x965C, 0xD445, 0x965D, 0xB0A2, 0x965E, 0xB0A5, 0x965F, 0xD446, + 0x9661, 0xB07E, 0x9662, 0xB07C, 0x9663, 0xB07D, 0x9664, 0xB0A3, + 0x966A, 0xB3AD, 0x966B, 0xD849, 0x966C, 0xB3B5, 0x966D, 0xD848, + 0x966F, 0xD84B, 0x9670, 0xB3B1, 0x9671, 0xD84A, 0x9672, 0xB6AB, + 0x9673, 0xB3AF, 0x9674, 0xB3B2, 0x9675, 0xB3AE, 0x9676, 0xB3B3, + 0x9677, 0xB3B4, 0x9678, 0xB3B0, 0x967C, 0xD847, 0x967D, 0xB6A7, + 0x967E, 0xDC7D, 0x9680, 0xDCA3, 0x9683, 0xDCA2, 0x9684, 0xB6AC, + 0x9685, 0xB6A8, 0x9686, 0xB6A9, 0x9687, 0xDC7C, 0x9688, 0xDC7E, + 0x9689, 0xDCA1, 0x968A, 0xB6A4, 0x968B, 0xB6A6, 0x968D, 0xB6AA, + 0x968E, 0xB6A5, 0x9691, 0xE0D3, 0x9692, 0xE0D1, 0x9693, 0xE0D2, + 0x9694, 0xB96A, 0x9695, 0xB96B, 0x9697, 0xE0D4, 0x9698, 0xB969, + 0x9699, 0xBBD8, 0x969B, 0xBBDA, 0x969C, 0xBBD9, 0x969E, 0xE4BB, + 0x96A1, 0xE4BC, 0x96A2, 0xE8AB, 0x96A4, 0xE8AA, 0x96A7, 0xC047, + 0x96A8, 0xC048, 0x96A9, 0xEC4F, 0x96AA, 0xC049, 0x96AC, 0xEEF6, + 0x96AE, 0xEEF4, 0x96B0, 0xEEF5, 0x96B1, 0xC1F4, 0x96B3, 0xF16F, + 0x96B4, 0xC3F7, 0x96B8, 0xC1F5, 0x96B9, 0xAB41, 0x96BB, 0xB0A6, + 0x96BC, 0xD447, 0x96BF, 0xD84C, 0x96C0, 0xB3B6, 0x96C1, 0xB6AD, + 0x96C2, 0xDCA4, 0x96C3, 0xDCA6, 0x96C4, 0xB6AF, 0x96C5, 0xB6AE, + 0x96C6, 0xB6B0, 0x96C7, 0xB6B1, 0x96C8, 0xDCA5, 0x96C9, 0xB96E, + 0x96CA, 0xB96F, 0x96CB, 0xB96D, 0x96CC, 0xBBDB, 0x96CD, 0xB96C, + 0x96CE, 0xE0D5, 0x96D2, 0xBBDC, 0x96D3, 0xE8AC, 0x96D4, 0xEC50, + 0x96D5, 0xC04A, 0x96D6, 0xC1F6, 0x96D7, 0xF170, 0x96D8, 0xF174, + 0x96D9, 0xC2F9, 0x96DA, 0xF171, 0x96DB, 0xC2FA, 0x96DC, 0xC2F8, + 0x96DD, 0xF175, 0x96DE, 0xC2FB, 0x96DF, 0xF173, 0x96E1, 0xF379, + 0x96E2, 0xC2F7, 0x96E3, 0xC3F8, 0x96E5, 0xF8CD, 0x96E8, 0xAB42, + 0x96E9, 0xB3B8, 0x96EA, 0xB3B7, 0x96EF, 0xB6B2, 0x96F0, 0xDCA8, + 0x96F1, 0xDCA7, 0x96F2, 0xB6B3, 0x96F5, 0xE0D9, 0x96F6, 0xB973, + 0x96F7, 0xB970, 0x96F8, 0xE0D8, 0x96F9, 0xB972, 0x96FA, 0xE0D6, + 0x96FB, 0xB971, 0x96FD, 0xE0D7, 0x96FF, 0xE4BD, 0x9700, 0xBBDD, + 0x9702, 0xE8AF, 0x9704, 0xBE5D, 0x9705, 0xE8AD, 0x9706, 0xBE5E, + 0x9707, 0xBE5F, 0x9708, 0xE8AE, 0x9709, 0xBE60, 0x970B, 0xEC51, + 0x970D, 0xC04E, 0x970E, 0xC04B, 0x970F, 0xC050, 0x9710, 0xEC53, + 0x9711, 0xC04C, 0x9712, 0xEC52, 0x9713, 0xC04F, 0x9716, 0xC04D, + 0x9718, 0xEEF9, 0x9719, 0xEEFB, 0x971C, 0xC1F7, 0x971D, 0xEEFA, + 0x971E, 0xC1F8, 0x971F, 0xEEF8, 0x9720, 0xEEF7, 0x9722, 0xF177, + 0x9723, 0xF176, 0x9724, 0xC2FC, 0x9725, 0xF178, 0x9726, 0xF37E, + 0x9727, 0xC3FA, 0x9728, 0xF37D, 0x9729, 0xF37A, 0x972A, 0xC3F9, + 0x972B, 0xF37B, 0x972C, 0xF37C, 0x972E, 0xF548, 0x972F, 0xF549, + 0x9730, 0xC4C5, 0x9732, 0xC553, 0x9735, 0xF66E, 0x9738, 0xC551, + 0x9739, 0xC552, 0x973A, 0xF66F, 0x973D, 0xC5B4, 0x973E, 0xC5B5, + 0x973F, 0xF771, 0x9742, 0xC645, 0x9743, 0xF8CF, 0x9744, 0xC647, + 0x9746, 0xF8CE, 0x9747, 0xF8D0, 0x9748, 0xC646, 0x9749, 0xF957, + 0x974B, 0xF9AD, 0x9752, 0xAB43, 0x9756, 0xB974, 0x9758, 0xE4BE, + 0x975A, 0xE8B0, 0x975B, 0xC051, 0x975C, 0xC052, 0x975E, 0xAB44, + 0x9760, 0xBE61, 0x9761, 0xC3FB, 0x9762, 0xADB1, 0x9766, 0xC053, + 0x9768, 0xC5E2, 0x9769, 0xADB2, 0x976A, 0xD84D, 0x976C, 0xDCA9, + 0x976E, 0xDCAB, 0x9770, 0xDCAA, 0x9772, 0xE0DD, 0x9773, 0xE0DA, + 0x9774, 0xB975, 0x9776, 0xB976, 0x9777, 0xE0DB, 0x9778, 0xE0DC, + 0x977A, 0xE4C0, 0x977B, 0xE4C5, 0x977C, 0xBBDE, 0x977D, 0xE4BF, + 0x977E, 0xE4C1, 0x977F, 0xE4C8, 0x9780, 0xE4C3, 0x9781, 0xE4C7, + 0x9782, 0xE4C4, 0x9783, 0xE4C2, 0x9784, 0xE4C6, 0x9785, 0xBBDF, + 0x9788, 0xE8B3, 0x978A, 0xE8B1, 0x978B, 0xBE63, 0x978D, 0xBE62, + 0x978E, 0xE8B2, 0x978F, 0xBE64, 0x9794, 0xEC56, 0x9797, 0xEC55, + 0x9798, 0xC054, 0x9799, 0xEC54, 0x979A, 0xEEFC, 0x979C, 0xEEFE, + 0x979D, 0xEF41, 0x979E, 0xEF40, 0x97A0, 0xC1F9, 0x97A1, 0xEEFD, + 0x97A2, 0xF1A1, 0x97A3, 0xC2FD, 0x97A4, 0xF17D, 0x97A5, 0xF1A2, + 0x97A6, 0xC2FE, 0x97A8, 0xF17B, 0x97AA, 0xF17E, 0x97AB, 0xF17C, + 0x97AC, 0xF179, 0x97AD, 0xC340, 0x97AE, 0xF17A, 0x97B3, 0xF3A1, + 0x97B6, 0xF3A3, 0x97B7, 0xF3A2, 0x97B9, 0xF54A, 0x97BB, 0xF54B, + 0x97BF, 0xF670, 0x97C1, 0xC5B7, 0x97C3, 0xC5B6, 0x97C4, 0xF84F, + 0x97C5, 0xF850, 0x97C6, 0xC648, 0x97C7, 0xF8D1, 0x97C9, 0xC669, + 0x97CB, 0xADB3, 0x97CC, 0xB6B4, 0x97CD, 0xE4CA, 0x97CE, 0xE4C9, + 0x97CF, 0xE8B5, 0x97D0, 0xE8B4, 0x97D3, 0xC1FA, 0x97D4, 0xEF43, + 0x97D5, 0xEF42, 0x97D6, 0xF1A5, 0x97D7, 0xF1A3, 0x97D8, 0xF1A6, + 0x97D9, 0xF1A4, 0x97DC, 0xC3FC, 0x97DD, 0xF3A4, 0x97DE, 0xF3A5, + 0x97DF, 0xF3A6, 0x97E1, 0xF671, 0x97E3, 0xF772, 0x97E5, 0xF8D2, + 0x97ED, 0xADB4, 0x97F0, 0xEC57, 0x97F1, 0xEF44, 0x97F3, 0xADB5, + 0x97F6, 0xBBE0, 0x97F8, 0xEC58, 0x97F9, 0xC341, 0x97FA, 0xF1A7, + 0x97FB, 0xC3FD, 0x97FD, 0xF54C, 0x97FE, 0xF54D, 0x97FF, 0xC554, + 0x9800, 0xF851, 0x9801, 0xADB6, 0x9802, 0xB3BB, 0x9803, 0xB3BC, + 0x9804, 0xD84E, 0x9805, 0xB6B5, 0x9806, 0xB6B6, 0x9807, 0xDCAC, + 0x9808, 0xB6B7, 0x980A, 0xB97A, 0x980C, 0xB97C, 0x980D, 0xE0DF, + 0x980E, 0xE0E0, 0x980F, 0xE0DE, 0x9810, 0xB977, 0x9811, 0xB978, + 0x9812, 0xB97B, 0x9813, 0xB979, 0x9816, 0xE4CB, 0x9817, 0xBBE1, + 0x9818, 0xBBE2, 0x981B, 0xE8BC, 0x981C, 0xBE67, 0x981D, 0xE8B7, + 0x981E, 0xE8B6, 0x9820, 0xE8BB, 0x9821, 0xBE65, 0x9824, 0xC05B, + 0x9826, 0xE8B8, 0x9827, 0xE8BD, 0x9828, 0xE8BA, 0x9829, 0xE8B9, + 0x982B, 0xBE66, 0x982D, 0xC059, 0x982F, 0xEC5A, 0x9830, 0xC055, + 0x9832, 0xEC5B, 0x9835, 0xEC59, 0x9837, 0xC058, 0x9838, 0xC056, + 0x9839, 0xC05A, 0x983B, 0xC057, 0x9841, 0xEF45, 0x9843, 0xEF4A, + 0x9844, 0xEF46, 0x9845, 0xEF49, 0x9846, 0xC1FB, 0x9848, 0xEDD4, + 0x9849, 0xEF48, 0x984A, 0xEF47, 0x984C, 0xC344, 0x984D, 0xC342, + 0x984E, 0xC345, 0x984F, 0xC343, 0x9850, 0xF1A8, 0x9851, 0xF1A9, + 0x9852, 0xF1AA, 0x9853, 0xC346, 0x9857, 0xF3AA, 0x9858, 0xC440, + 0x9859, 0xF3A8, 0x985B, 0xC441, 0x985C, 0xF3A7, 0x985D, 0xF3A9, + 0x985E, 0xC3FE, 0x985F, 0xF551, 0x9860, 0xF54E, 0x9862, 0xF54F, + 0x9863, 0xF550, 0x9864, 0xF672, 0x9865, 0xC556, 0x9867, 0xC555, + 0x9869, 0xF774, 0x986A, 0xF773, 0x986B, 0xC5B8, 0x986F, 0xC5E3, + 0x9870, 0xC649, 0x9871, 0xC660, 0x9872, 0xF958, 0x9873, 0xF9AE, + 0x9874, 0xF9AF, 0x98A8, 0xADB7, 0x98A9, 0xDCAD, 0x98AC, 0xE0E1, + 0x98AD, 0xE4CC, 0x98AE, 0xE4CD, 0x98AF, 0xBBE3, 0x98B1, 0xBBE4, + 0x98B2, 0xE8BE, 0x98B3, 0xBE68, 0x98B6, 0xC1FC, 0x98B8, 0xF1AB, + 0x98BA, 0xC347, 0x98BB, 0xF3AD, 0x98BC, 0xC442, 0x98BD, 0xF3AC, + 0x98BE, 0xF3AE, 0x98BF, 0xF3AB, 0x98C0, 0xF675, 0x98C1, 0xF552, + 0x98C2, 0xF553, 0x98C4, 0xC4C6, 0x98C6, 0xF674, 0x98C9, 0xF673, + 0x98CB, 0xF775, 0x98CC, 0xF9B0, 0x98DB, 0xADB8, 0x98DF, 0xADB9, + 0x98E2, 0xB0A7, 0x98E3, 0xD448, 0x98E5, 0xD84F, 0x98E7, 0xB6B8, + 0x98E9, 0xB6BB, 0x98EA, 0xB6B9, 0x98EB, 0xDCAE, 0x98ED, 0xB6BD, + 0x98EF, 0xB6BA, 0x98F2, 0xB6BC, 0x98F4, 0xB97E, 0x98F6, 0xE0E2, + 0x98F9, 0xE0E3, 0x98FA, 0xE8C0, 0x98FC, 0xB97D, 0x98FD, 0xB9A1, + 0x98FE, 0xB9A2, 0x9900, 0xE4CF, 0x9902, 0xE4CE, 0x9903, 0xBBE5, + 0x9905, 0xBBE6, 0x9907, 0xE4D0, 0x9908, 0xE8BF, 0x9909, 0xBBE8, + 0x990A, 0xBE69, 0x990C, 0xBBE7, 0x9910, 0xC05C, 0x9911, 0xE8C1, + 0x9912, 0xBE6B, 0x9913, 0xBE6A, 0x9914, 0xE8C2, 0x9915, 0xE8C5, + 0x9916, 0xE8C3, 0x9917, 0xE8C4, 0x9918, 0xBE6C, 0x991A, 0xC061, + 0x991B, 0xC05F, 0x991E, 0xC05E, 0x991F, 0xEC5D, 0x9921, 0xC060, + 0x9924, 0xEC5C, 0x9925, 0xEF4B, 0x9927, 0xEC5E, 0x9928, 0xC05D, + 0x9929, 0xEC5F, 0x992A, 0xEF4E, 0x992B, 0xEF4C, 0x992C, 0xEF4D, + 0x992D, 0xEF52, 0x992E, 0xC34B, 0x992F, 0xEF51, 0x9930, 0xEF54, + 0x9931, 0xEF53, 0x9932, 0xEF50, 0x9933, 0xEF4F, 0x9935, 0xC1FD, + 0x993A, 0xF1AE, 0x993C, 0xF1AD, 0x993D, 0xC34A, 0x993E, 0xC348, + 0x993F, 0xC349, 0x9941, 0xF1AC, 0x9943, 0xF3B1, 0x9945, 0xC443, + 0x9947, 0xF3B0, 0x9948, 0xF3AF, 0x9949, 0xC444, 0x994B, 0xF558, + 0x994C, 0xF557, 0x994E, 0xF555, 0x9950, 0xF554, 0x9951, 0xC4C8, + 0x9952, 0xC4C7, 0x9953, 0xF559, 0x9954, 0xF776, 0x9955, 0xC5B9, + 0x9956, 0xF677, 0x9957, 0xC557, 0x9958, 0xF676, 0x9959, 0xF556, + 0x995B, 0xF777, 0x995C, 0xC5E4, 0x995E, 0xC661, 0x995F, 0xF959, + 0x9961, 0xF9B1, 0x9996, 0xADBA, 0x9997, 0xD850, 0x9998, 0xEF55, + 0x9999, 0xADBB, 0x999C, 0xE4D2, 0x999D, 0xE4D1, 0x999E, 0xEC60, + 0x99A1, 0xEF57, 0x99A3, 0xEF56, 0x99A5, 0xC34C, 0x99A6, 0xF3B2, + 0x99A7, 0xF3B3, 0x99A8, 0xC4C9, 0x99AB, 0xF9B2, 0x99AC, 0xB0A8, + 0x99AD, 0xB6BF, 0x99AE, 0xB6BE, 0x99AF, 0xE0E4, 0x99B0, 0xE0E6, + 0x99B1, 0xB9A4, 0x99B2, 0xE0E5, 0x99B3, 0xB9A3, 0x99B4, 0xB9A5, + 0x99B5, 0xE0E7, 0x99B9, 0xE4D4, 0x99BA, 0xE4D6, 0x99BB, 0xE4D5, + 0x99BD, 0xE4D8, 0x99C1, 0xBBE9, 0x99C2, 0xE4D7, 0x99C3, 0xE4D3, + 0x99C7, 0xE4D9, 0x99C9, 0xE8CC, 0x99CB, 0xE8CF, 0x99CC, 0xE8D1, + 0x99CD, 0xE8C7, 0x99CE, 0xE8CB, 0x99CF, 0xE8C8, 0x99D0, 0xBE6E, + 0x99D1, 0xBE71, 0x99D2, 0xBE73, 0x99D3, 0xE8C9, 0x99D4, 0xE8CA, + 0x99D5, 0xBE72, 0x99D6, 0xE8CD, 0x99D7, 0xE8D0, 0x99D8, 0xE8CE, + 0x99D9, 0xBE74, 0x99DB, 0xBE70, 0x99DC, 0xE8C6, 0x99DD, 0xBE6D, + 0x99DF, 0xBE6F, 0x99E2, 0xC063, 0x99E3, 0xEC66, 0x99E4, 0xEC64, + 0x99E5, 0xEC63, 0x99E7, 0xEC69, 0x99E9, 0xEC68, 0x99EA, 0xEC67, + 0x99EC, 0xEC62, 0x99ED, 0xC062, 0x99EE, 0xEC61, 0x99F0, 0xEC65, + 0x99F1, 0xC064, 0x99F4, 0xEF5A, 0x99F6, 0xEF5E, 0x99F7, 0xEF5B, + 0x99F8, 0xEF5D, 0x99F9, 0xEF5C, 0x99FA, 0xEF59, 0x99FB, 0xEF5F, + 0x99FC, 0xEF62, 0x99FD, 0xEF60, 0x99FE, 0xEF61, 0x99FF, 0xC240, + 0x9A01, 0xC1FE, 0x9A02, 0xEF58, 0x9A03, 0xEF63, 0x9A04, 0xF1B3, + 0x9A05, 0xF1B6, 0x9A06, 0xF1B8, 0x9A07, 0xF1B7, 0x9A09, 0xF1B1, + 0x9A0A, 0xF1B5, 0x9A0B, 0xF1B0, 0x9A0D, 0xF1B2, 0x9A0E, 0xC34D, + 0x9A0F, 0xF1AF, 0x9A11, 0xF1B4, 0x9A14, 0xF3C0, 0x9A15, 0xF3B5, + 0x9A16, 0xC445, 0x9A19, 0xC446, 0x9A1A, 0xF3B4, 0x9A1B, 0xF3B9, + 0x9A1C, 0xF3BF, 0x9A1D, 0xF3B7, 0x9A1E, 0xF3BE, 0x9A20, 0xF3BB, + 0x9A22, 0xF3BA, 0x9A23, 0xF3BD, 0x9A24, 0xF3B8, 0x9A25, 0xF3B6, + 0x9A27, 0xF3BC, 0x9A29, 0xF560, 0x9A2A, 0xF55E, 0x9A2B, 0xC4CA, + 0x9A2C, 0xF55D, 0x9A2D, 0xF563, 0x9A2E, 0xF561, 0x9A30, 0xC4CB, + 0x9A31, 0xF55C, 0x9A32, 0xF55A, 0x9A34, 0xF55B, 0x9A35, 0xC4CD, + 0x9A36, 0xF55F, 0x9A37, 0xC4CC, 0x9A38, 0xF562, 0x9A39, 0xF678, + 0x9A3A, 0xF67E, 0x9A3D, 0xF679, 0x9A3E, 0xC55B, 0x9A3F, 0xF6A1, + 0x9A40, 0xC55A, 0x9A41, 0xF67D, 0x9A42, 0xF67C, 0x9A43, 0xC559, + 0x9A44, 0xF67B, 0x9A45, 0xC558, 0x9A46, 0xF67A, 0x9A48, 0xF77D, + 0x9A49, 0xF7A1, 0x9A4A, 0xF77E, 0x9A4C, 0xF77B, 0x9A4D, 0xC5BB, + 0x9A4E, 0xF778, 0x9A4F, 0xF77C, 0x9A50, 0xF7A3, 0x9A52, 0xF7A2, + 0x9A53, 0xF779, 0x9A54, 0xF77A, 0x9A55, 0xC5BA, 0x9A56, 0xF852, + 0x9A57, 0xC5E7, 0x9A59, 0xF853, 0x9A5A, 0xC5E5, 0x9A5B, 0xC5E6, + 0x9A5E, 0xF8D3, 0x9A5F, 0xC64A, 0x9A60, 0xF976, 0x9A62, 0xC66A, + 0x9A64, 0xF9B3, 0x9A65, 0xC66B, 0x9A66, 0xF9B4, 0x9A67, 0xF9B5, + 0x9A68, 0xF9C3, 0x9A69, 0xF9C2, 0x9A6A, 0xC67A, 0x9A6B, 0xF9CD, + 0x9AA8, 0xB0A9, 0x9AAB, 0xE0E9, 0x9AAD, 0xE0E8, 0x9AAF, 0xBBEA, + 0x9AB0, 0xBBEB, 0x9AB1, 0xE4DA, 0x9AB3, 0xE8D2, 0x9AB4, 0xEC6C, + 0x9AB7, 0xBE75, 0x9AB8, 0xC065, 0x9AB9, 0xEC6A, 0x9ABB, 0xEC6D, + 0x9ABC, 0xC066, 0x9ABE, 0xEF64, 0x9ABF, 0xEC6B, 0x9AC0, 0xF1B9, + 0x9AC1, 0xC34E, 0x9AC2, 0xF3C1, 0x9AC6, 0xF566, 0x9AC7, 0xF564, + 0x9ACA, 0xF565, 0x9ACD, 0xF6A2, 0x9ACF, 0xC55C, 0x9AD0, 0xF7A4, + 0x9AD1, 0xC5EA, 0x9AD2, 0xC5BC, 0x9AD3, 0xC5E8, 0x9AD4, 0xC5E9, + 0x9AD5, 0xF8D4, 0x9AD6, 0xC662, 0x9AD8, 0xB0AA, 0x9ADC, 0xF1BA, + 0x9ADF, 0xD449, 0x9AE1, 0xB9A6, 0x9AE3, 0xE4DB, 0x9AE6, 0xBBEC, + 0x9AE7, 0xE4DC, 0x9AEB, 0xE8D4, 0x9AEC, 0xE8D3, 0x9AED, 0xC068, + 0x9AEE, 0xBE76, 0x9AEF, 0xBE77, 0x9AF1, 0xE8D7, 0x9AF2, 0xE8D6, + 0x9AF3, 0xE8D5, 0x9AF6, 0xEC6E, 0x9AF7, 0xEC71, 0x9AF9, 0xEC70, + 0x9AFA, 0xEC6F, 0x9AFB, 0xC067, 0x9AFC, 0xEF68, 0x9AFD, 0xEF66, + 0x9AFE, 0xEF65, 0x9B01, 0xEF67, 0x9B03, 0xC34F, 0x9B04, 0xF1BC, + 0x9B05, 0xF1BD, 0x9B06, 0xC350, 0x9B08, 0xF1BB, 0x9B0A, 0xF3C3, + 0x9B0B, 0xF3C2, 0x9B0C, 0xF3C5, 0x9B0D, 0xC447, 0x9B0E, 0xF3C4, + 0x9B10, 0xF567, 0x9B11, 0xF569, 0x9B12, 0xF568, 0x9B15, 0xF6A3, + 0x9B16, 0xF6A6, 0x9B17, 0xF6A4, 0x9B18, 0xF6A5, 0x9B19, 0xF7A5, + 0x9B1A, 0xC5BD, 0x9B1E, 0xF854, 0x9B1F, 0xF855, 0x9B20, 0xF856, + 0x9B22, 0xC64B, 0x9B23, 0xC663, 0x9B24, 0xF9B6, 0x9B25, 0xB0AB, + 0x9B27, 0xBE78, 0x9B28, 0xC069, 0x9B29, 0xF1BE, 0x9B2B, 0xF7A6, + 0x9B2E, 0xF9C4, 0x9B2F, 0xD44A, 0x9B31, 0xC67B, 0x9B32, 0xB0AC, + 0x9B33, 0xEC72, 0x9B35, 0xF1BF, 0x9B37, 0xF3C6, 0x9B3A, 0xF6A7, + 0x9B3B, 0xF7A7, 0x9B3C, 0xB0AD, 0x9B3E, 0xE4DD, 0x9B3F, 0xE4DE, + 0x9B41, 0xBBED, 0x9B42, 0xBBEE, 0x9B43, 0xE8D9, 0x9B44, 0xBE7A, + 0x9B45, 0xBE79, 0x9B46, 0xE8D8, 0x9B48, 0xEF69, 0x9B4A, 0xF1C0, + 0x9B4B, 0xF1C2, 0x9B4C, 0xF1C1, 0x9B4D, 0xC353, 0x9B4E, 0xC352, + 0x9B4F, 0xC351, 0x9B51, 0xC55E, 0x9B52, 0xF6A8, 0x9B54, 0xC55D, + 0x9B55, 0xF7A9, 0x9B56, 0xF7A8, 0x9B58, 0xC64C, 0x9B59, 0xF8D5, + 0x9B5A, 0xB3BD, 0x9B5B, 0xE0EA, 0x9B5F, 0xE4E1, 0x9B60, 0xE4DF, + 0x9B61, 0xE4E0, 0x9B64, 0xE8E2, 0x9B66, 0xE8DD, 0x9B67, 0xE8DA, + 0x9B68, 0xE8E1, 0x9B6C, 0xE8E3, 0x9B6F, 0xBE7C, 0x9B70, 0xE8E0, + 0x9B71, 0xE8DC, 0x9B74, 0xE8DB, 0x9B75, 0xE8DF, 0x9B76, 0xE8DE, + 0x9B77, 0xBE7B, 0x9B7A, 0xEC7D, 0x9B7B, 0xEC78, 0x9B7C, 0xEC76, + 0x9B7D, 0xECA1, 0x9B7E, 0xEC77, 0x9B80, 0xEC73, 0x9B82, 0xEC79, + 0x9B85, 0xEC74, 0x9B86, 0xEF72, 0x9B87, 0xEC75, 0x9B88, 0xECA2, + 0x9B90, 0xEC7C, 0x9B91, 0xC06A, 0x9B92, 0xEC7B, 0x9B93, 0xEC7A, + 0x9B95, 0xEC7E, 0x9B9A, 0xEF6A, 0x9B9B, 0xEF6D, 0x9B9E, 0xEF6C, + 0x9BA0, 0xEF74, 0x9BA1, 0xEF6F, 0x9BA2, 0xEF73, 0x9BA4, 0xEF71, + 0x9BA5, 0xEF70, 0x9BA6, 0xEF6E, 0x9BA8, 0xEF6B, 0x9BAA, 0xC243, + 0x9BAB, 0xC242, 0x9BAD, 0xC244, 0x9BAE, 0xC241, 0x9BAF, 0xEF75, + 0x9BB5, 0xF1C8, 0x9BB6, 0xF1CB, 0x9BB8, 0xF1C9, 0x9BB9, 0xF1CD, + 0x9BBD, 0xF1CE, 0x9BBF, 0xF1C6, 0x9BC0, 0xC358, 0x9BC1, 0xF1C7, + 0x9BC3, 0xF1C5, 0x9BC4, 0xF1CC, 0x9BC6, 0xF1C4, 0x9BC7, 0xF1C3, + 0x9BC8, 0xC357, 0x9BC9, 0xC355, 0x9BCA, 0xC354, 0x9BD3, 0xF1CA, + 0x9BD4, 0xF3CF, 0x9BD5, 0xF3D5, 0x9BD6, 0xC44A, 0x9BD7, 0xF3D0, + 0x9BD9, 0xF3D3, 0x9BDA, 0xF3D7, 0x9BDB, 0xC44B, 0x9BDC, 0xF3D2, + 0x9BDE, 0xF3CA, 0x9BE0, 0xF3C9, 0x9BE1, 0xF3D6, 0x9BE2, 0xF3CD, + 0x9BE4, 0xF3CB, 0x9BE5, 0xF3D4, 0x9BE6, 0xF3CC, 0x9BE7, 0xC449, + 0x9BE8, 0xC448, 0x9BEA, 0xF3C7, 0x9BEB, 0xF3C8, 0x9BEC, 0xF3D1, + 0x9BF0, 0xF3CE, 0x9BF7, 0xF56C, 0x9BF8, 0xF56F, 0x9BFD, 0xC356, + 0x9C05, 0xF56D, 0x9C06, 0xF573, 0x9C07, 0xF571, 0x9C08, 0xF56B, + 0x9C09, 0xF576, 0x9C0B, 0xF56A, 0x9C0D, 0xC4CF, 0x9C0E, 0xF572, + 0x9C12, 0xF56E, 0x9C13, 0xC4CE, 0x9C14, 0xF575, 0x9C17, 0xF574, + 0x9C1C, 0xF6AB, 0x9C1D, 0xF6AA, 0x9C21, 0xF6B1, 0x9C23, 0xF6AD, + 0x9C24, 0xF6B0, 0x9C25, 0xC560, 0x9C28, 0xF6AE, 0x9C29, 0xF6AF, + 0x9C2B, 0xF6A9, 0x9C2C, 0xF6AC, 0x9C2D, 0xC55F, 0x9C31, 0xC5BF, + 0x9C32, 0xF7B4, 0x9C33, 0xF7AF, 0x9C34, 0xF7B3, 0x9C36, 0xF7B6, + 0x9C37, 0xF7B2, 0x9C39, 0xF7AE, 0x9C3B, 0xC5C1, 0x9C3C, 0xF7B1, + 0x9C3D, 0xF7B5, 0x9C3E, 0xC5C0, 0x9C3F, 0xF7AC, 0x9C40, 0xF570, + 0x9C41, 0xF7B0, 0x9C44, 0xF7AD, 0x9C46, 0xF7AA, 0x9C48, 0xF7AB, + 0x9C49, 0xC5BE, 0x9C4A, 0xF85A, 0x9C4B, 0xF85C, 0x9C4C, 0xF85F, + 0x9C4D, 0xF85B, 0x9C4E, 0xF860, 0x9C50, 0xF859, 0x9C52, 0xF857, + 0x9C54, 0xC5EB, 0x9C55, 0xF85D, 0x9C56, 0xC5ED, 0x9C57, 0xC5EC, + 0x9C58, 0xF858, 0x9C59, 0xF85E, 0x9C5E, 0xF8DA, 0x9C5F, 0xC64D, + 0x9C60, 0xF8DB, 0x9C62, 0xF8D9, 0x9C63, 0xF8D6, 0x9C66, 0xF8D8, + 0x9C67, 0xF8D7, 0x9C68, 0xF95A, 0x9C6D, 0xF95C, 0x9C6E, 0xF95B, + 0x9C71, 0xF979, 0x9C73, 0xF978, 0x9C74, 0xF977, 0x9C75, 0xF97A, + 0x9C77, 0xC673, 0x9C78, 0xC674, 0x9C79, 0xF9CA, 0x9C7A, 0xF9CE, + 0x9CE5, 0xB3BE, 0x9CE6, 0xDCAF, 0x9CE7, 0xE0ED, 0x9CE9, 0xB9A7, + 0x9CEA, 0xE0EB, 0x9CED, 0xE0EC, 0x9CF1, 0xE4E2, 0x9CF2, 0xE4E3, + 0x9CF3, 0xBBF1, 0x9CF4, 0xBBEF, 0x9CF5, 0xE4E4, 0x9CF6, 0xBBF0, + 0x9CF7, 0xE8E8, 0x9CF9, 0xE8EB, 0x9CFA, 0xE8E5, 0x9CFB, 0xE8EC, + 0x9CFC, 0xE8E4, 0x9CFD, 0xE8E6, 0x9CFF, 0xE8E7, 0x9D00, 0xE8EA, + 0x9D03, 0xBEA1, 0x9D04, 0xE8EF, 0x9D05, 0xE8EE, 0x9D06, 0xBE7D, + 0x9D07, 0xE8E9, 0x9D08, 0xE8ED, 0x9D09, 0xBE7E, 0x9D10, 0xECAC, + 0x9D12, 0xC06F, 0x9D14, 0xECA7, 0x9D15, 0xC06B, 0x9D17, 0xECA4, + 0x9D18, 0xECAA, 0x9D19, 0xECAD, 0x9D1B, 0xC070, 0x9D1D, 0xECA9, + 0x9D1E, 0xECA6, 0x9D1F, 0xECAE, 0x9D20, 0xECA5, 0x9D22, 0xECAB, + 0x9D23, 0xC06C, 0x9D25, 0xECA3, 0x9D26, 0xC06D, 0x9D28, 0xC06E, + 0x9D29, 0xECA8, 0x9D2D, 0xEFA9, 0x9D2E, 0xEF7A, 0x9D2F, 0xEF7B, + 0x9D30, 0xEF7E, 0x9D31, 0xEF7C, 0x9D33, 0xEF76, 0x9D36, 0xEF79, + 0x9D37, 0xEFA5, 0x9D38, 0xEF7D, 0x9D3B, 0xC245, 0x9D3D, 0xEFA7, + 0x9D3E, 0xEFA4, 0x9D3F, 0xC246, 0x9D40, 0xEFA6, 0x9D41, 0xEF77, + 0x9D42, 0xEFA2, 0x9D43, 0xEFA3, 0x9D45, 0xEFA1, 0x9D4A, 0xF1D2, + 0x9D4B, 0xF1D4, 0x9D4C, 0xF1D7, 0x9D4F, 0xF1D1, 0x9D51, 0xC359, + 0x9D52, 0xF1D9, 0x9D53, 0xF1D0, 0x9D54, 0xF1DA, 0x9D56, 0xF1D6, + 0x9D57, 0xF1D8, 0x9D58, 0xF1DC, 0x9D59, 0xF1D5, 0x9D5A, 0xF1DD, + 0x9D5B, 0xF1D3, 0x9D5C, 0xF1CF, 0x9D5D, 0xC35A, 0x9D5F, 0xF1DB, + 0x9D60, 0xC35B, 0x9D61, 0xC44D, 0x9D67, 0xEF78, 0x9D68, 0xF3F1, + 0x9D69, 0xF3E8, 0x9D6A, 0xC44F, 0x9D6B, 0xF3E4, 0x9D6C, 0xC450, + 0x9D6F, 0xF3ED, 0x9D70, 0xF3E7, 0x9D71, 0xF3DD, 0x9D72, 0xC44E, + 0x9D73, 0xF3EA, 0x9D74, 0xF3E5, 0x9D75, 0xF3E6, 0x9D77, 0xF3D8, + 0x9D78, 0xF3DF, 0x9D79, 0xF3EE, 0x9D7B, 0xF3EB, 0x9D7D, 0xF3E3, + 0x9D7F, 0xF3EF, 0x9D80, 0xF3DE, 0x9D81, 0xF3D9, 0x9D82, 0xF3EC, + 0x9D84, 0xF3DB, 0x9D85, 0xF3E9, 0x9D86, 0xF3E0, 0x9D87, 0xF3F0, + 0x9D88, 0xF3DC, 0x9D89, 0xC44C, 0x9D8A, 0xF3DA, 0x9D8B, 0xF3E1, + 0x9D8C, 0xF3E2, 0x9D90, 0xF57D, 0x9D92, 0xF57B, 0x9D94, 0xF5A2, + 0x9D96, 0xF5AE, 0x9D97, 0xF5A5, 0x9D98, 0xF57C, 0x9D99, 0xF578, + 0x9D9A, 0xF5A7, 0x9D9B, 0xF57E, 0x9D9C, 0xF5A3, 0x9D9D, 0xF57A, + 0x9D9E, 0xF5AA, 0x9D9F, 0xF577, 0x9DA0, 0xF5A1, 0x9DA1, 0xF5A6, + 0x9DA2, 0xF5A8, 0x9DA3, 0xF5AB, 0x9DA4, 0xF579, 0x9DA6, 0xF5AF, + 0x9DA7, 0xF5B0, 0x9DA8, 0xF5A9, 0x9DA9, 0xF5AD, 0x9DAA, 0xF5A4, + 0x9DAC, 0xF6C1, 0x9DAD, 0xF6C4, 0x9DAF, 0xC561, 0x9DB1, 0xF6C3, + 0x9DB2, 0xF6C8, 0x9DB3, 0xF6C6, 0x9DB4, 0xC562, 0x9DB5, 0xF6BD, + 0x9DB6, 0xF6B3, 0x9DB7, 0xF6B2, 0x9DB8, 0xC564, 0x9DB9, 0xF6BF, + 0x9DBA, 0xF6C0, 0x9DBB, 0xF6BC, 0x9DBC, 0xF6B4, 0x9DBE, 0xF6B9, + 0x9DBF, 0xF5AC, 0x9DC1, 0xF6B5, 0x9DC2, 0xC563, 0x9DC3, 0xF6BB, + 0x9DC5, 0xF6BA, 0x9DC7, 0xF6B6, 0x9DC8, 0xF6C2, 0x9DCA, 0xF6B7, + 0x9DCB, 0xF7BB, 0x9DCC, 0xF6C5, 0x9DCD, 0xF6C7, 0x9DCE, 0xF6BE, + 0x9DCF, 0xF6B8, 0x9DD0, 0xF7BC, 0x9DD1, 0xF7BE, 0x9DD2, 0xF7B8, + 0x9DD3, 0xC5C2, 0x9DD5, 0xF7C5, 0x9DD6, 0xF7C3, 0x9DD7, 0xC5C3, + 0x9DD8, 0xF7C2, 0x9DD9, 0xF7C1, 0x9DDA, 0xF7BA, 0x9DDB, 0xF7B7, + 0x9DDC, 0xF7BD, 0x9DDD, 0xF7C6, 0x9DDE, 0xF7B9, 0x9DDF, 0xF7BF, + 0x9DE1, 0xF869, 0x9DE2, 0xF86E, 0x9DE3, 0xF864, 0x9DE4, 0xF867, + 0x9DE5, 0xC5EE, 0x9DE6, 0xF86B, 0x9DE8, 0xF872, 0x9DE9, 0xF7C0, + 0x9DEB, 0xF865, 0x9DEC, 0xF86F, 0x9DED, 0xF873, 0x9DEE, 0xF86A, + 0x9DEF, 0xF863, 0x9DF0, 0xF86D, 0x9DF2, 0xF86C, 0x9DF3, 0xF871, + 0x9DF4, 0xF870, 0x9DF5, 0xF7C4, 0x9DF6, 0xF868, 0x9DF7, 0xF862, + 0x9DF8, 0xF866, 0x9DF9, 0xC64E, 0x9DFA, 0xC64F, 0x9DFB, 0xF861, + 0x9DFD, 0xF8E6, 0x9DFE, 0xF8DD, 0x9DFF, 0xF8E5, 0x9E00, 0xF8E2, + 0x9E01, 0xF8E3, 0x9E02, 0xF8DC, 0x9E03, 0xF8DF, 0x9E04, 0xF8E7, + 0x9E05, 0xF8E1, 0x9E06, 0xF8E0, 0x9E07, 0xF8DE, 0x9E09, 0xF8E4, + 0x9E0B, 0xF95D, 0x9E0D, 0xF95E, 0x9E0F, 0xF960, 0x9E10, 0xF95F, + 0x9E11, 0xF962, 0x9E12, 0xF961, 0x9E13, 0xF97C, 0x9E14, 0xF97B, + 0x9E15, 0xF9B7, 0x9E17, 0xF9B8, 0x9E19, 0xF9C5, 0x9E1A, 0xC678, + 0x9E1B, 0xC67C, 0x9E1D, 0xF9CF, 0x9E1E, 0xC67D, 0x9E75, 0xB3BF, + 0x9E79, 0xC4D0, 0x9E7A, 0xF6C9, 0x9E7C, 0xC650, 0x9E7D, 0xC651, + 0x9E7F, 0xB3C0, 0x9E80, 0xE0EE, 0x9E82, 0xB9A8, 0x9E83, 0xE8F0, + 0x9E86, 0xECB0, 0x9E87, 0xECB1, 0x9E88, 0xECAF, 0x9E89, 0xEFAB, + 0x9E8A, 0xEFAA, 0x9E8B, 0xC247, 0x9E8C, 0xF1DF, 0x9E8D, 0xEFAC, + 0x9E8E, 0xF1DE, 0x9E91, 0xF3F3, 0x9E92, 0xC451, 0x9E93, 0xC453, + 0x9E94, 0xF3F2, 0x9E97, 0xC452, 0x9E99, 0xF5B1, 0x9E9A, 0xF5B3, + 0x9E9B, 0xF5B2, 0x9E9C, 0xF6CA, 0x9E9D, 0xC565, 0x9E9F, 0xC5EF, + 0x9EA0, 0xF8E8, 0x9EA1, 0xF963, 0x9EA4, 0xF9D2, 0x9EA5, 0xB3C1, + 0x9EA7, 0xE4E5, 0x9EA9, 0xBEA2, 0x9EAD, 0xECB3, 0x9EAE, 0xECB2, + 0x9EB0, 0xEFAD, 0x9EB4, 0xC454, 0x9EB5, 0xC4D1, 0x9EB6, 0xF7C7, + 0x9EB7, 0xF9CB, 0x9EBB, 0xB3C2, 0x9EBC, 0xBBF2, 0x9EBE, 0xBEA3, + 0x9EC0, 0xF3F4, 0x9EC2, 0xF874, 0x9EC3, 0xB6C0, 0x9EC8, 0xEFAE, + 0x9ECC, 0xC664, 0x9ECD, 0xB6C1, 0x9ECE, 0xBEA4, 0x9ECF, 0xC248, + 0x9ED0, 0xF875, 0x9ED1, 0xB6C2, 0x9ED3, 0xE8F1, 0x9ED4, 0xC072, + 0x9ED5, 0xECB4, 0x9ED6, 0xECB5, 0x9ED8, 0xC071, 0x9EDA, 0xEFAF, + 0x9EDB, 0xC24C, 0x9EDC, 0xC24A, 0x9EDD, 0xC24B, 0x9EDE, 0xC249, + 0x9EDF, 0xF1E0, 0x9EE0, 0xC35C, 0x9EE4, 0xF5B5, 0x9EE5, 0xF5B4, + 0x9EE6, 0xF5B7, 0x9EE7, 0xF5B6, 0x9EE8, 0xC4D2, 0x9EEB, 0xF6CB, + 0x9EED, 0xF6CD, 0x9EEE, 0xF6CC, 0x9EEF, 0xC566, 0x9EF0, 0xF7C8, + 0x9EF2, 0xF876, 0x9EF3, 0xF877, 0x9EF4, 0xC5F0, 0x9EF5, 0xF964, + 0x9EF6, 0xF97D, 0x9EF7, 0xC675, 0x9EF9, 0xDCB0, 0x9EFA, 0xECB6, + 0x9EFB, 0xEFB0, 0x9EFC, 0xF3F5, 0x9EFD, 0xE0EF, 0x9EFF, 0xEFB1, + 0x9F00, 0xF1E2, 0x9F01, 0xF1E1, 0x9F06, 0xF878, 0x9F07, 0xC652, + 0x9F09, 0xF965, 0x9F0A, 0xF97E, 0x9F0E, 0xB9A9, 0x9F0F, 0xE8F2, + 0x9F10, 0xE8F3, 0x9F12, 0xECB7, 0x9F13, 0xB9AA, 0x9F15, 0xC35D, + 0x9F16, 0xF1E3, 0x9F18, 0xF6CF, 0x9F19, 0xC567, 0x9F1A, 0xF6D0, + 0x9F1B, 0xF6CE, 0x9F1C, 0xF879, 0x9F1E, 0xF8E9, 0x9F20, 0xB9AB, + 0x9F22, 0xEFB4, 0x9F23, 0xEFB3, 0x9F24, 0xEFB2, 0x9F25, 0xF1E4, + 0x9F28, 0xF1E8, 0x9F29, 0xF1E7, 0x9F2A, 0xF1E6, 0x9F2B, 0xF1E5, + 0x9F2C, 0xC35E, 0x9F2D, 0xF3F6, 0x9F2E, 0xF5B9, 0x9F2F, 0xC4D3, + 0x9F30, 0xF5B8, 0x9F31, 0xF6D1, 0x9F32, 0xF7CB, 0x9F33, 0xF7CA, + 0x9F34, 0xC5C4, 0x9F35, 0xF7C9, 0x9F36, 0xF87C, 0x9F37, 0xF87B, + 0x9F38, 0xF87A, 0x9F3B, 0xBBF3, 0x9F3D, 0xECB8, 0x9F3E, 0xC24D, + 0x9F40, 0xF3F7, 0x9F41, 0xF3F8, 0x9F42, 0xF7CC, 0x9F43, 0xF87D, + 0x9F46, 0xF8EA, 0x9F47, 0xF966, 0x9F48, 0xF9B9, 0x9F49, 0xF9D4, + 0x9F4A, 0xBBF4, 0x9F4B, 0xC24E, 0x9F4C, 0xF1E9, 0x9F4D, 0xF3F9, + 0x9F4E, 0xF6D2, 0x9F4F, 0xF87E, 0x9F52, 0xBEA6, 0x9F54, 0xEFB5, + 0x9F55, 0xF1EA, 0x9F56, 0xF3FA, 0x9F57, 0xF3FB, 0x9F58, 0xF3FC, + 0x9F59, 0xF5BE, 0x9F5B, 0xF5BA, 0x9F5C, 0xC568, 0x9F5D, 0xF5BD, + 0x9F5E, 0xF5BC, 0x9F5F, 0xC4D4, 0x9F60, 0xF5BB, 0x9F61, 0xC4D6, + 0x9F63, 0xC4D5, 0x9F64, 0xF6D4, 0x9F65, 0xF6D3, 0x9F66, 0xC569, + 0x9F67, 0xC56A, 0x9F6A, 0xC5C6, 0x9F6B, 0xF7CD, 0x9F6C, 0xC5C5, + 0x9F6E, 0xF8A3, 0x9F6F, 0xF8A4, 0x9F70, 0xF8A2, 0x9F71, 0xF8A1, + 0x9F72, 0xC654, 0x9F74, 0xF8EB, 0x9F75, 0xF8EC, 0x9F76, 0xF8ED, + 0x9F77, 0xC653, 0x9F78, 0xF967, 0x9F79, 0xF96A, 0x9F7A, 0xF969, + 0x9F7B, 0xF968, 0x9F7E, 0xF9D3, 0x9F8D, 0xC073, 0x9F90, 0xC365, + 0x9F91, 0xF5BF, 0x9F92, 0xF6D5, 0x9F94, 0xC5C7, 0x9F95, 0xF7CE, + 0x9F98, 0xF9D5, 0x9F9C, 0xC074, 0x9FA0, 0xEFB6, 0x9FA2, 0xF7CF, + 0x9FA4, 0xF9A1, 0xFA0C, 0xC94A, 0xFA0D, 0xDDFC, 0xFE30, 0xA14A, + 0xFE31, 0xA157, 0xFE33, 0xA159, 0xFE34, 0xA15B, 0xFE35, 0xA15F, + 0xFE36, 0xA160, 0xFE37, 0xA163, 0xFE38, 0xA164, 0xFE39, 0xA167, + 0xFE3A, 0xA168, 0xFE3B, 0xA16B, 0xFE3C, 0xA16C, 0xFE3D, 0xA16F, + 0xFE3E, 0xA170, 0xFE3F, 0xA173, 0xFE40, 0xA174, 0xFE41, 0xA177, + 0xFE42, 0xA178, 0xFE43, 0xA17B, 0xFE44, 0xA17C, 0xFE49, 0xA1C6, + 0xFE4A, 0xA1C7, 0xFE4B, 0xA1CA, 0xFE4C, 0xA1CB, 0xFE4D, 0xA1C8, + 0xFE4E, 0xA1C9, 0xFE4F, 0xA15C, 0xFE50, 0xA14D, 0xFE51, 0xA14E, + 0xFE52, 0xA14F, 0xFE54, 0xA151, 0xFE55, 0xA152, 0xFE56, 0xA153, + 0xFE57, 0xA154, 0xFE59, 0xA17D, 0xFE5A, 0xA17E, 0xFE5B, 0xA1A1, + 0xFE5C, 0xA1A2, 0xFE5D, 0xA1A3, 0xFE5E, 0xA1A4, 0xFE5F, 0xA1CC, + 0xFE60, 0xA1CD, 0xFE61, 0xA1CE, 0xFE62, 0xA1DE, 0xFE63, 0xA1DF, + 0xFE64, 0xA1E0, 0xFE65, 0xA1E1, 0xFE66, 0xA1E2, 0xFE68, 0xA242, + 0xFE69, 0xA24C, 0xFE6A, 0xA24D, 0xFE6B, 0xA24E, 0xFF01, 0xA149, + 0xFF03, 0xA1AD, 0xFF04, 0xA243, 0xFF05, 0xA248, 0xFF06, 0xA1AE, + 0xFF08, 0xA15D, 0xFF09, 0xA15E, 0xFF0A, 0xA1AF, 0xFF0B, 0xA1CF, + 0xFF0C, 0xA141, 0xFF0D, 0xA1D0, 0xFF0E, 0xA144, 0xFF0F, 0xA1FE, + 0xFF10, 0xA2AF, 0xFF11, 0xA2B0, 0xFF12, 0xA2B1, 0xFF13, 0xA2B2, + 0xFF14, 0xA2B3, 0xFF15, 0xA2B4, 0xFF16, 0xA2B5, 0xFF17, 0xA2B6, + 0xFF18, 0xA2B7, 0xFF19, 0xA2B8, 0xFF1A, 0xA147, 0xFF1B, 0xA146, + 0xFF1C, 0xA1D5, 0xFF1D, 0xA1D7, 0xFF1E, 0xA1D6, 0xFF1F, 0xA148, + 0xFF20, 0xA249, 0xFF21, 0xA2CF, 0xFF22, 0xA2D0, 0xFF23, 0xA2D1, + 0xFF24, 0xA2D2, 0xFF25, 0xA2D3, 0xFF26, 0xA2D4, 0xFF27, 0xA2D5, + 0xFF28, 0xA2D6, 0xFF29, 0xA2D7, 0xFF2A, 0xA2D8, 0xFF2B, 0xA2D9, + 0xFF2C, 0xA2DA, 0xFF2D, 0xA2DB, 0xFF2E, 0xA2DC, 0xFF2F, 0xA2DD, + 0xFF30, 0xA2DE, 0xFF31, 0xA2DF, 0xFF32, 0xA2E0, 0xFF33, 0xA2E1, + 0xFF34, 0xA2E2, 0xFF35, 0xA2E3, 0xFF36, 0xA2E4, 0xFF37, 0xA2E5, + 0xFF38, 0xA2E6, 0xFF39, 0xA2E7, 0xFF3A, 0xA2E8, 0xFF3C, 0xA240, + 0xFF3F, 0xA1C4, 0xFF41, 0xA2E9, 0xFF42, 0xA2EA, 0xFF43, 0xA2EB, + 0xFF44, 0xA2EC, 0xFF45, 0xA2ED, 0xFF46, 0xA2EE, 0xFF47, 0xA2EF, + 0xFF48, 0xA2F0, 0xFF49, 0xA2F1, 0xFF4A, 0xA2F2, 0xFF4B, 0xA2F3, + 0xFF4C, 0xA2F4, 0xFF4D, 0xA2F5, 0xFF4E, 0xA2F6, 0xFF4F, 0xA2F7, + 0xFF50, 0xA2F8, 0xFF51, 0xA2F9, 0xFF52, 0xA2FA, 0xFF53, 0xA2FB, + 0xFF54, 0xA2FC, 0xFF55, 0xA2FD, 0xFF56, 0xA2FE, 0xFF57, 0xA340, + 0xFF58, 0xA341, 0xFF59, 0xA342, 0xFF5A, 0xA343, 0xFF5B, 0xA161, + 0xFF5C, 0xA155, 0xFF5D, 0xA162, 0xFF5E, 0xA1E3, 0xFFE0, 0xA246, + 0xFFE1, 0xA247, 0xFFE3, 0xA1C3, 0xFFE5, 0xA244, 0, 0 +}; + +static +const WCHAR oem2uni[] = { +/* OEM - Unicode, OEM - Unicode, OEM - Unicode, OEM - Unicode */ + 0xA140, 0x3000, 0xA141, 0xFF0C, 0xA142, 0x3001, 0xA143, 0x3002, + 0xA144, 0xFF0E, 0xA145, 0x2027, 0xA146, 0xFF1B, 0xA147, 0xFF1A, + 0xA148, 0xFF1F, 0xA149, 0xFF01, 0xA14A, 0xFE30, 0xA14B, 0x2026, + 0xA14C, 0x2025, 0xA14D, 0xFE50, 0xA14E, 0xFE51, 0xA14F, 0xFE52, + 0xA150, 0x00B7, 0xA151, 0xFE54, 0xA152, 0xFE55, 0xA153, 0xFE56, + 0xA154, 0xFE57, 0xA155, 0xFF5C, 0xA156, 0x2013, 0xA157, 0xFE31, + 0xA158, 0x2014, 0xA159, 0xFE33, 0xA15A, 0x2574, 0xA15B, 0xFE34, + 0xA15C, 0xFE4F, 0xA15D, 0xFF08, 0xA15E, 0xFF09, 0xA15F, 0xFE35, + 0xA160, 0xFE36, 0xA161, 0xFF5B, 0xA162, 0xFF5D, 0xA163, 0xFE37, + 0xA164, 0xFE38, 0xA165, 0x3014, 0xA166, 0x3015, 0xA167, 0xFE39, + 0xA168, 0xFE3A, 0xA169, 0x3010, 0xA16A, 0x3011, 0xA16B, 0xFE3B, + 0xA16C, 0xFE3C, 0xA16D, 0x300A, 0xA16E, 0x300B, 0xA16F, 0xFE3D, + 0xA170, 0xFE3E, 0xA171, 0x3008, 0xA172, 0x3009, 0xA173, 0xFE3F, + 0xA174, 0xFE40, 0xA175, 0x300C, 0xA176, 0x300D, 0xA177, 0xFE41, + 0xA178, 0xFE42, 0xA179, 0x300E, 0xA17A, 0x300F, 0xA17B, 0xFE43, + 0xA17C, 0xFE44, 0xA17D, 0xFE59, 0xA17E, 0xFE5A, 0xA1A1, 0xFE5B, + 0xA1A2, 0xFE5C, 0xA1A3, 0xFE5D, 0xA1A4, 0xFE5E, 0xA1A5, 0x2018, + 0xA1A6, 0x2019, 0xA1A7, 0x201C, 0xA1A8, 0x201D, 0xA1A9, 0x301D, + 0xA1AA, 0x301E, 0xA1AB, 0x2035, 0xA1AC, 0x2032, 0xA1AD, 0xFF03, + 0xA1AE, 0xFF06, 0xA1AF, 0xFF0A, 0xA1B0, 0x203B, 0xA1B1, 0x00A7, + 0xA1B2, 0x3003, 0xA1B3, 0x25CB, 0xA1B4, 0x25CF, 0xA1B5, 0x25B3, + 0xA1B6, 0x25B2, 0xA1B7, 0x25CE, 0xA1B8, 0x2606, 0xA1B9, 0x2605, + 0xA1BA, 0x25C7, 0xA1BB, 0x25C6, 0xA1BC, 0x25A1, 0xA1BD, 0x25A0, + 0xA1BE, 0x25BD, 0xA1BF, 0x25BC, 0xA1C0, 0x32A3, 0xA1C1, 0x2105, + 0xA1C2, 0x00AF, 0xA1C3, 0xFFE3, 0xA1C4, 0xFF3F, 0xA1C5, 0x02CD, + 0xA1C6, 0xFE49, 0xA1C7, 0xFE4A, 0xA1C8, 0xFE4D, 0xA1C9, 0xFE4E, + 0xA1CA, 0xFE4B, 0xA1CB, 0xFE4C, 0xA1CC, 0xFE5F, 0xA1CD, 0xFE60, + 0xA1CE, 0xFE61, 0xA1CF, 0xFF0B, 0xA1D0, 0xFF0D, 0xA1D1, 0x00D7, + 0xA1D2, 0x00F7, 0xA1D3, 0x00B1, 0xA1D4, 0x221A, 0xA1D5, 0xFF1C, + 0xA1D6, 0xFF1E, 0xA1D7, 0xFF1D, 0xA1D8, 0x2266, 0xA1D9, 0x2267, + 0xA1DA, 0x2260, 0xA1DB, 0x221E, 0xA1DC, 0x2252, 0xA1DD, 0x2261, + 0xA1DE, 0xFE62, 0xA1DF, 0xFE63, 0xA1E0, 0xFE64, 0xA1E1, 0xFE65, + 0xA1E2, 0xFE66, 0xA1E3, 0xFF5E, 0xA1E4, 0x2229, 0xA1E5, 0x222A, + 0xA1E6, 0x22A5, 0xA1E7, 0x2220, 0xA1E8, 0x221F, 0xA1E9, 0x22BF, + 0xA1EA, 0x33D2, 0xA1EB, 0x33D1, 0xA1EC, 0x222B, 0xA1ED, 0x222E, + 0xA1EE, 0x2235, 0xA1EF, 0x2234, 0xA1F0, 0x2640, 0xA1F1, 0x2642, + 0xA1F2, 0x2295, 0xA1F3, 0x2299, 0xA1F4, 0x2191, 0xA1F5, 0x2193, + 0xA1F6, 0x2190, 0xA1F7, 0x2192, 0xA1F8, 0x2196, 0xA1F9, 0x2197, + 0xA1FA, 0x2199, 0xA1FB, 0x2198, 0xA1FC, 0x2225, 0xA1FD, 0x2223, + 0xA1FE, 0xFF0F, 0xA240, 0xFF3C, 0xA241, 0x2215, 0xA242, 0xFE68, + 0xA243, 0xFF04, 0xA244, 0xFFE5, 0xA245, 0x3012, 0xA246, 0xFFE0, + 0xA247, 0xFFE1, 0xA248, 0xFF05, 0xA249, 0xFF20, 0xA24A, 0x2103, + 0xA24B, 0x2109, 0xA24C, 0xFE69, 0xA24D, 0xFE6A, 0xA24E, 0xFE6B, + 0xA24F, 0x33D5, 0xA250, 0x339C, 0xA251, 0x339D, 0xA252, 0x339E, + 0xA253, 0x33CE, 0xA254, 0x33A1, 0xA255, 0x338E, 0xA256, 0x338F, + 0xA257, 0x33C4, 0xA258, 0x00B0, 0xA259, 0x5159, 0xA25A, 0x515B, + 0xA25B, 0x515E, 0xA25C, 0x515D, 0xA25D, 0x5161, 0xA25E, 0x5163, + 0xA25F, 0x55E7, 0xA260, 0x74E9, 0xA261, 0x7CCE, 0xA262, 0x2581, + 0xA263, 0x2582, 0xA264, 0x2583, 0xA265, 0x2584, 0xA266, 0x2585, + 0xA267, 0x2586, 0xA268, 0x2587, 0xA269, 0x2588, 0xA26A, 0x258F, + 0xA26B, 0x258E, 0xA26C, 0x258D, 0xA26D, 0x258C, 0xA26E, 0x258B, + 0xA26F, 0x258A, 0xA270, 0x2589, 0xA271, 0x253C, 0xA272, 0x2534, + 0xA273, 0x252C, 0xA274, 0x2524, 0xA275, 0x251C, 0xA276, 0x2594, + 0xA277, 0x2500, 0xA278, 0x2502, 0xA279, 0x2595, 0xA27A, 0x250C, + 0xA27B, 0x2510, 0xA27C, 0x2514, 0xA27D, 0x2518, 0xA27E, 0x256D, + 0xA2A1, 0x256E, 0xA2A2, 0x2570, 0xA2A3, 0x256F, 0xA2A4, 0x2550, + 0xA2A5, 0x255E, 0xA2A6, 0x256A, 0xA2A7, 0x2561, 0xA2A8, 0x25E2, + 0xA2A9, 0x25E3, 0xA2AA, 0x25E5, 0xA2AB, 0x25E4, 0xA2AC, 0x2571, + 0xA2AD, 0x2572, 0xA2AE, 0x2573, 0xA2AF, 0xFF10, 0xA2B0, 0xFF11, + 0xA2B1, 0xFF12, 0xA2B2, 0xFF13, 0xA2B3, 0xFF14, 0xA2B4, 0xFF15, + 0xA2B5, 0xFF16, 0xA2B6, 0xFF17, 0xA2B7, 0xFF18, 0xA2B8, 0xFF19, + 0xA2B9, 0x2160, 0xA2BA, 0x2161, 0xA2BB, 0x2162, 0xA2BC, 0x2163, + 0xA2BD, 0x2164, 0xA2BE, 0x2165, 0xA2BF, 0x2166, 0xA2C0, 0x2167, + 0xA2C1, 0x2168, 0xA2C2, 0x2169, 0xA2C3, 0x3021, 0xA2C4, 0x3022, + 0xA2C5, 0x3023, 0xA2C6, 0x3024, 0xA2C7, 0x3025, 0xA2C8, 0x3026, + 0xA2C9, 0x3027, 0xA2CA, 0x3028, 0xA2CB, 0x3029, 0xA2CC, 0x5341, + 0xA2CD, 0x5344, 0xA2CE, 0x5345, 0xA2CF, 0xFF21, 0xA2D0, 0xFF22, + 0xA2D1, 0xFF23, 0xA2D2, 0xFF24, 0xA2D3, 0xFF25, 0xA2D4, 0xFF26, + 0xA2D5, 0xFF27, 0xA2D6, 0xFF28, 0xA2D7, 0xFF29, 0xA2D8, 0xFF2A, + 0xA2D9, 0xFF2B, 0xA2DA, 0xFF2C, 0xA2DB, 0xFF2D, 0xA2DC, 0xFF2E, + 0xA2DD, 0xFF2F, 0xA2DE, 0xFF30, 0xA2DF, 0xFF31, 0xA2E0, 0xFF32, + 0xA2E1, 0xFF33, 0xA2E2, 0xFF34, 0xA2E3, 0xFF35, 0xA2E4, 0xFF36, + 0xA2E5, 0xFF37, 0xA2E6, 0xFF38, 0xA2E7, 0xFF39, 0xA2E8, 0xFF3A, + 0xA2E9, 0xFF41, 0xA2EA, 0xFF42, 0xA2EB, 0xFF43, 0xA2EC, 0xFF44, + 0xA2ED, 0xFF45, 0xA2EE, 0xFF46, 0xA2EF, 0xFF47, 0xA2F0, 0xFF48, + 0xA2F1, 0xFF49, 0xA2F2, 0xFF4A, 0xA2F3, 0xFF4B, 0xA2F4, 0xFF4C, + 0xA2F5, 0xFF4D, 0xA2F6, 0xFF4E, 0xA2F7, 0xFF4F, 0xA2F8, 0xFF50, + 0xA2F9, 0xFF51, 0xA2FA, 0xFF52, 0xA2FB, 0xFF53, 0xA2FC, 0xFF54, + 0xA2FD, 0xFF55, 0xA2FE, 0xFF56, 0xA340, 0xFF57, 0xA341, 0xFF58, + 0xA342, 0xFF59, 0xA343, 0xFF5A, 0xA344, 0x0391, 0xA345, 0x0392, + 0xA346, 0x0393, 0xA347, 0x0394, 0xA348, 0x0395, 0xA349, 0x0396, + 0xA34A, 0x0397, 0xA34B, 0x0398, 0xA34C, 0x0399, 0xA34D, 0x039A, + 0xA34E, 0x039B, 0xA34F, 0x039C, 0xA350, 0x039D, 0xA351, 0x039E, + 0xA352, 0x039F, 0xA353, 0x03A0, 0xA354, 0x03A1, 0xA355, 0x03A3, + 0xA356, 0x03A4, 0xA357, 0x03A5, 0xA358, 0x03A6, 0xA359, 0x03A7, + 0xA35A, 0x03A8, 0xA35B, 0x03A9, 0xA35C, 0x03B1, 0xA35D, 0x03B2, + 0xA35E, 0x03B3, 0xA35F, 0x03B4, 0xA360, 0x03B5, 0xA361, 0x03B6, + 0xA362, 0x03B7, 0xA363, 0x03B8, 0xA364, 0x03B9, 0xA365, 0x03BA, + 0xA366, 0x03BB, 0xA367, 0x03BC, 0xA368, 0x03BD, 0xA369, 0x03BE, + 0xA36A, 0x03BF, 0xA36B, 0x03C0, 0xA36C, 0x03C1, 0xA36D, 0x03C3, + 0xA36E, 0x03C4, 0xA36F, 0x03C5, 0xA370, 0x03C6, 0xA371, 0x03C7, + 0xA372, 0x03C8, 0xA373, 0x03C9, 0xA374, 0x3105, 0xA375, 0x3106, + 0xA376, 0x3107, 0xA377, 0x3108, 0xA378, 0x3109, 0xA379, 0x310A, + 0xA37A, 0x310B, 0xA37B, 0x310C, 0xA37C, 0x310D, 0xA37D, 0x310E, + 0xA37E, 0x310F, 0xA3A1, 0x3110, 0xA3A2, 0x3111, 0xA3A3, 0x3112, + 0xA3A4, 0x3113, 0xA3A5, 0x3114, 0xA3A6, 0x3115, 0xA3A7, 0x3116, + 0xA3A8, 0x3117, 0xA3A9, 0x3118, 0xA3AA, 0x3119, 0xA3AB, 0x311A, + 0xA3AC, 0x311B, 0xA3AD, 0x311C, 0xA3AE, 0x311D, 0xA3AF, 0x311E, + 0xA3B0, 0x311F, 0xA3B1, 0x3120, 0xA3B2, 0x3121, 0xA3B3, 0x3122, + 0xA3B4, 0x3123, 0xA3B5, 0x3124, 0xA3B6, 0x3125, 0xA3B7, 0x3126, + 0xA3B8, 0x3127, 0xA3B9, 0x3128, 0xA3BA, 0x3129, 0xA3BB, 0x02D9, + 0xA3BC, 0x02C9, 0xA3BD, 0x02CA, 0xA3BE, 0x02C7, 0xA3BF, 0x02CB, + 0xA3E1, 0x20AC, 0xA440, 0x4E00, 0xA441, 0x4E59, 0xA442, 0x4E01, + 0xA443, 0x4E03, 0xA444, 0x4E43, 0xA445, 0x4E5D, 0xA446, 0x4E86, + 0xA447, 0x4E8C, 0xA448, 0x4EBA, 0xA449, 0x513F, 0xA44A, 0x5165, + 0xA44B, 0x516B, 0xA44C, 0x51E0, 0xA44D, 0x5200, 0xA44E, 0x5201, + 0xA44F, 0x529B, 0xA450, 0x5315, 0xA451, 0x5341, 0xA452, 0x535C, + 0xA453, 0x53C8, 0xA454, 0x4E09, 0xA455, 0x4E0B, 0xA456, 0x4E08, + 0xA457, 0x4E0A, 0xA458, 0x4E2B, 0xA459, 0x4E38, 0xA45A, 0x51E1, + 0xA45B, 0x4E45, 0xA45C, 0x4E48, 0xA45D, 0x4E5F, 0xA45E, 0x4E5E, + 0xA45F, 0x4E8E, 0xA460, 0x4EA1, 0xA461, 0x5140, 0xA462, 0x5203, + 0xA463, 0x52FA, 0xA464, 0x5343, 0xA465, 0x53C9, 0xA466, 0x53E3, + 0xA467, 0x571F, 0xA468, 0x58EB, 0xA469, 0x5915, 0xA46A, 0x5927, + 0xA46B, 0x5973, 0xA46C, 0x5B50, 0xA46D, 0x5B51, 0xA46E, 0x5B53, + 0xA46F, 0x5BF8, 0xA470, 0x5C0F, 0xA471, 0x5C22, 0xA472, 0x5C38, + 0xA473, 0x5C71, 0xA474, 0x5DDD, 0xA475, 0x5DE5, 0xA476, 0x5DF1, + 0xA477, 0x5DF2, 0xA478, 0x5DF3, 0xA479, 0x5DFE, 0xA47A, 0x5E72, + 0xA47B, 0x5EFE, 0xA47C, 0x5F0B, 0xA47D, 0x5F13, 0xA47E, 0x624D, + 0xA4A1, 0x4E11, 0xA4A2, 0x4E10, 0xA4A3, 0x4E0D, 0xA4A4, 0x4E2D, + 0xA4A5, 0x4E30, 0xA4A6, 0x4E39, 0xA4A7, 0x4E4B, 0xA4A8, 0x5C39, + 0xA4A9, 0x4E88, 0xA4AA, 0x4E91, 0xA4AB, 0x4E95, 0xA4AC, 0x4E92, + 0xA4AD, 0x4E94, 0xA4AE, 0x4EA2, 0xA4AF, 0x4EC1, 0xA4B0, 0x4EC0, + 0xA4B1, 0x4EC3, 0xA4B2, 0x4EC6, 0xA4B3, 0x4EC7, 0xA4B4, 0x4ECD, + 0xA4B5, 0x4ECA, 0xA4B6, 0x4ECB, 0xA4B7, 0x4EC4, 0xA4B8, 0x5143, + 0xA4B9, 0x5141, 0xA4BA, 0x5167, 0xA4BB, 0x516D, 0xA4BC, 0x516E, + 0xA4BD, 0x516C, 0xA4BE, 0x5197, 0xA4BF, 0x51F6, 0xA4C0, 0x5206, + 0xA4C1, 0x5207, 0xA4C2, 0x5208, 0xA4C3, 0x52FB, 0xA4C4, 0x52FE, + 0xA4C5, 0x52FF, 0xA4C6, 0x5316, 0xA4C7, 0x5339, 0xA4C8, 0x5348, + 0xA4C9, 0x5347, 0xA4CA, 0x5345, 0xA4CB, 0x535E, 0xA4CC, 0x5384, + 0xA4CD, 0x53CB, 0xA4CE, 0x53CA, 0xA4CF, 0x53CD, 0xA4D0, 0x58EC, + 0xA4D1, 0x5929, 0xA4D2, 0x592B, 0xA4D3, 0x592A, 0xA4D4, 0x592D, + 0xA4D5, 0x5B54, 0xA4D6, 0x5C11, 0xA4D7, 0x5C24, 0xA4D8, 0x5C3A, + 0xA4D9, 0x5C6F, 0xA4DA, 0x5DF4, 0xA4DB, 0x5E7B, 0xA4DC, 0x5EFF, + 0xA4DD, 0x5F14, 0xA4DE, 0x5F15, 0xA4DF, 0x5FC3, 0xA4E0, 0x6208, + 0xA4E1, 0x6236, 0xA4E2, 0x624B, 0xA4E3, 0x624E, 0xA4E4, 0x652F, + 0xA4E5, 0x6587, 0xA4E6, 0x6597, 0xA4E7, 0x65A4, 0xA4E8, 0x65B9, + 0xA4E9, 0x65E5, 0xA4EA, 0x66F0, 0xA4EB, 0x6708, 0xA4EC, 0x6728, + 0xA4ED, 0x6B20, 0xA4EE, 0x6B62, 0xA4EF, 0x6B79, 0xA4F0, 0x6BCB, + 0xA4F1, 0x6BD4, 0xA4F2, 0x6BDB, 0xA4F3, 0x6C0F, 0xA4F4, 0x6C34, + 0xA4F5, 0x706B, 0xA4F6, 0x722A, 0xA4F7, 0x7236, 0xA4F8, 0x723B, + 0xA4F9, 0x7247, 0xA4FA, 0x7259, 0xA4FB, 0x725B, 0xA4FC, 0x72AC, + 0xA4FD, 0x738B, 0xA4FE, 0x4E19, 0xA540, 0x4E16, 0xA541, 0x4E15, + 0xA542, 0x4E14, 0xA543, 0x4E18, 0xA544, 0x4E3B, 0xA545, 0x4E4D, + 0xA546, 0x4E4F, 0xA547, 0x4E4E, 0xA548, 0x4EE5, 0xA549, 0x4ED8, + 0xA54A, 0x4ED4, 0xA54B, 0x4ED5, 0xA54C, 0x4ED6, 0xA54D, 0x4ED7, + 0xA54E, 0x4EE3, 0xA54F, 0x4EE4, 0xA550, 0x4ED9, 0xA551, 0x4EDE, + 0xA552, 0x5145, 0xA553, 0x5144, 0xA554, 0x5189, 0xA555, 0x518A, + 0xA556, 0x51AC, 0xA557, 0x51F9, 0xA558, 0x51FA, 0xA559, 0x51F8, + 0xA55A, 0x520A, 0xA55B, 0x52A0, 0xA55C, 0x529F, 0xA55D, 0x5305, + 0xA55E, 0x5306, 0xA55F, 0x5317, 0xA560, 0x531D, 0xA561, 0x4EDF, + 0xA562, 0x534A, 0xA563, 0x5349, 0xA564, 0x5361, 0xA565, 0x5360, + 0xA566, 0x536F, 0xA567, 0x536E, 0xA568, 0x53BB, 0xA569, 0x53EF, + 0xA56A, 0x53E4, 0xA56B, 0x53F3, 0xA56C, 0x53EC, 0xA56D, 0x53EE, + 0xA56E, 0x53E9, 0xA56F, 0x53E8, 0xA570, 0x53FC, 0xA571, 0x53F8, + 0xA572, 0x53F5, 0xA573, 0x53EB, 0xA574, 0x53E6, 0xA575, 0x53EA, + 0xA576, 0x53F2, 0xA577, 0x53F1, 0xA578, 0x53F0, 0xA579, 0x53E5, + 0xA57A, 0x53ED, 0xA57B, 0x53FB, 0xA57C, 0x56DB, 0xA57D, 0x56DA, + 0xA57E, 0x5916, 0xA5A1, 0x592E, 0xA5A2, 0x5931, 0xA5A3, 0x5974, + 0xA5A4, 0x5976, 0xA5A5, 0x5B55, 0xA5A6, 0x5B83, 0xA5A7, 0x5C3C, + 0xA5A8, 0x5DE8, 0xA5A9, 0x5DE7, 0xA5AA, 0x5DE6, 0xA5AB, 0x5E02, + 0xA5AC, 0x5E03, 0xA5AD, 0x5E73, 0xA5AE, 0x5E7C, 0xA5AF, 0x5F01, + 0xA5B0, 0x5F18, 0xA5B1, 0x5F17, 0xA5B2, 0x5FC5, 0xA5B3, 0x620A, + 0xA5B4, 0x6253, 0xA5B5, 0x6254, 0xA5B6, 0x6252, 0xA5B7, 0x6251, + 0xA5B8, 0x65A5, 0xA5B9, 0x65E6, 0xA5BA, 0x672E, 0xA5BB, 0x672C, + 0xA5BC, 0x672A, 0xA5BD, 0x672B, 0xA5BE, 0x672D, 0xA5BF, 0x6B63, + 0xA5C0, 0x6BCD, 0xA5C1, 0x6C11, 0xA5C2, 0x6C10, 0xA5C3, 0x6C38, + 0xA5C4, 0x6C41, 0xA5C5, 0x6C40, 0xA5C6, 0x6C3E, 0xA5C7, 0x72AF, + 0xA5C8, 0x7384, 0xA5C9, 0x7389, 0xA5CA, 0x74DC, 0xA5CB, 0x74E6, + 0xA5CC, 0x7518, 0xA5CD, 0x751F, 0xA5CE, 0x7528, 0xA5CF, 0x7529, + 0xA5D0, 0x7530, 0xA5D1, 0x7531, 0xA5D2, 0x7532, 0xA5D3, 0x7533, + 0xA5D4, 0x758B, 0xA5D5, 0x767D, 0xA5D6, 0x76AE, 0xA5D7, 0x76BF, + 0xA5D8, 0x76EE, 0xA5D9, 0x77DB, 0xA5DA, 0x77E2, 0xA5DB, 0x77F3, + 0xA5DC, 0x793A, 0xA5DD, 0x79BE, 0xA5DE, 0x7A74, 0xA5DF, 0x7ACB, + 0xA5E0, 0x4E1E, 0xA5E1, 0x4E1F, 0xA5E2, 0x4E52, 0xA5E3, 0x4E53, + 0xA5E4, 0x4E69, 0xA5E5, 0x4E99, 0xA5E6, 0x4EA4, 0xA5E7, 0x4EA6, + 0xA5E8, 0x4EA5, 0xA5E9, 0x4EFF, 0xA5EA, 0x4F09, 0xA5EB, 0x4F19, + 0xA5EC, 0x4F0A, 0xA5ED, 0x4F15, 0xA5EE, 0x4F0D, 0xA5EF, 0x4F10, + 0xA5F0, 0x4F11, 0xA5F1, 0x4F0F, 0xA5F2, 0x4EF2, 0xA5F3, 0x4EF6, + 0xA5F4, 0x4EFB, 0xA5F5, 0x4EF0, 0xA5F6, 0x4EF3, 0xA5F7, 0x4EFD, + 0xA5F8, 0x4F01, 0xA5F9, 0x4F0B, 0xA5FA, 0x5149, 0xA5FB, 0x5147, + 0xA5FC, 0x5146, 0xA5FD, 0x5148, 0xA5FE, 0x5168, 0xA640, 0x5171, + 0xA641, 0x518D, 0xA642, 0x51B0, 0xA643, 0x5217, 0xA644, 0x5211, + 0xA645, 0x5212, 0xA646, 0x520E, 0xA647, 0x5216, 0xA648, 0x52A3, + 0xA649, 0x5308, 0xA64A, 0x5321, 0xA64B, 0x5320, 0xA64C, 0x5370, + 0xA64D, 0x5371, 0xA64E, 0x5409, 0xA64F, 0x540F, 0xA650, 0x540C, + 0xA651, 0x540A, 0xA652, 0x5410, 0xA653, 0x5401, 0xA654, 0x540B, + 0xA655, 0x5404, 0xA656, 0x5411, 0xA657, 0x540D, 0xA658, 0x5408, + 0xA659, 0x5403, 0xA65A, 0x540E, 0xA65B, 0x5406, 0xA65C, 0x5412, + 0xA65D, 0x56E0, 0xA65E, 0x56DE, 0xA65F, 0x56DD, 0xA660, 0x5733, + 0xA661, 0x5730, 0xA662, 0x5728, 0xA663, 0x572D, 0xA664, 0x572C, + 0xA665, 0x572F, 0xA666, 0x5729, 0xA667, 0x5919, 0xA668, 0x591A, + 0xA669, 0x5937, 0xA66A, 0x5938, 0xA66B, 0x5984, 0xA66C, 0x5978, + 0xA66D, 0x5983, 0xA66E, 0x597D, 0xA66F, 0x5979, 0xA670, 0x5982, + 0xA671, 0x5981, 0xA672, 0x5B57, 0xA673, 0x5B58, 0xA674, 0x5B87, + 0xA675, 0x5B88, 0xA676, 0x5B85, 0xA677, 0x5B89, 0xA678, 0x5BFA, + 0xA679, 0x5C16, 0xA67A, 0x5C79, 0xA67B, 0x5DDE, 0xA67C, 0x5E06, + 0xA67D, 0x5E76, 0xA67E, 0x5E74, 0xA6A1, 0x5F0F, 0xA6A2, 0x5F1B, + 0xA6A3, 0x5FD9, 0xA6A4, 0x5FD6, 0xA6A5, 0x620E, 0xA6A6, 0x620C, + 0xA6A7, 0x620D, 0xA6A8, 0x6210, 0xA6A9, 0x6263, 0xA6AA, 0x625B, + 0xA6AB, 0x6258, 0xA6AC, 0x6536, 0xA6AD, 0x65E9, 0xA6AE, 0x65E8, + 0xA6AF, 0x65EC, 0xA6B0, 0x65ED, 0xA6B1, 0x66F2, 0xA6B2, 0x66F3, + 0xA6B3, 0x6709, 0xA6B4, 0x673D, 0xA6B5, 0x6734, 0xA6B6, 0x6731, + 0xA6B7, 0x6735, 0xA6B8, 0x6B21, 0xA6B9, 0x6B64, 0xA6BA, 0x6B7B, + 0xA6BB, 0x6C16, 0xA6BC, 0x6C5D, 0xA6BD, 0x6C57, 0xA6BE, 0x6C59, + 0xA6BF, 0x6C5F, 0xA6C0, 0x6C60, 0xA6C1, 0x6C50, 0xA6C2, 0x6C55, + 0xA6C3, 0x6C61, 0xA6C4, 0x6C5B, 0xA6C5, 0x6C4D, 0xA6C6, 0x6C4E, + 0xA6C7, 0x7070, 0xA6C8, 0x725F, 0xA6C9, 0x725D, 0xA6CA, 0x767E, + 0xA6CB, 0x7AF9, 0xA6CC, 0x7C73, 0xA6CD, 0x7CF8, 0xA6CE, 0x7F36, + 0xA6CF, 0x7F8A, 0xA6D0, 0x7FBD, 0xA6D1, 0x8001, 0xA6D2, 0x8003, + 0xA6D3, 0x800C, 0xA6D4, 0x8012, 0xA6D5, 0x8033, 0xA6D6, 0x807F, + 0xA6D7, 0x8089, 0xA6D8, 0x808B, 0xA6D9, 0x808C, 0xA6DA, 0x81E3, + 0xA6DB, 0x81EA, 0xA6DC, 0x81F3, 0xA6DD, 0x81FC, 0xA6DE, 0x820C, + 0xA6DF, 0x821B, 0xA6E0, 0x821F, 0xA6E1, 0x826E, 0xA6E2, 0x8272, + 0xA6E3, 0x827E, 0xA6E4, 0x866B, 0xA6E5, 0x8840, 0xA6E6, 0x884C, + 0xA6E7, 0x8863, 0xA6E8, 0x897F, 0xA6E9, 0x9621, 0xA6EA, 0x4E32, + 0xA6EB, 0x4EA8, 0xA6EC, 0x4F4D, 0xA6ED, 0x4F4F, 0xA6EE, 0x4F47, + 0xA6EF, 0x4F57, 0xA6F0, 0x4F5E, 0xA6F1, 0x4F34, 0xA6F2, 0x4F5B, + 0xA6F3, 0x4F55, 0xA6F4, 0x4F30, 0xA6F5, 0x4F50, 0xA6F6, 0x4F51, + 0xA6F7, 0x4F3D, 0xA6F8, 0x4F3A, 0xA6F9, 0x4F38, 0xA6FA, 0x4F43, + 0xA6FB, 0x4F54, 0xA6FC, 0x4F3C, 0xA6FD, 0x4F46, 0xA6FE, 0x4F63, + 0xA740, 0x4F5C, 0xA741, 0x4F60, 0xA742, 0x4F2F, 0xA743, 0x4F4E, + 0xA744, 0x4F36, 0xA745, 0x4F59, 0xA746, 0x4F5D, 0xA747, 0x4F48, + 0xA748, 0x4F5A, 0xA749, 0x514C, 0xA74A, 0x514B, 0xA74B, 0x514D, + 0xA74C, 0x5175, 0xA74D, 0x51B6, 0xA74E, 0x51B7, 0xA74F, 0x5225, + 0xA750, 0x5224, 0xA751, 0x5229, 0xA752, 0x522A, 0xA753, 0x5228, + 0xA754, 0x52AB, 0xA755, 0x52A9, 0xA756, 0x52AA, 0xA757, 0x52AC, + 0xA758, 0x5323, 0xA759, 0x5373, 0xA75A, 0x5375, 0xA75B, 0x541D, + 0xA75C, 0x542D, 0xA75D, 0x541E, 0xA75E, 0x543E, 0xA75F, 0x5426, + 0xA760, 0x544E, 0xA761, 0x5427, 0xA762, 0x5446, 0xA763, 0x5443, + 0xA764, 0x5433, 0xA765, 0x5448, 0xA766, 0x5442, 0xA767, 0x541B, + 0xA768, 0x5429, 0xA769, 0x544A, 0xA76A, 0x5439, 0xA76B, 0x543B, + 0xA76C, 0x5438, 0xA76D, 0x542E, 0xA76E, 0x5435, 0xA76F, 0x5436, + 0xA770, 0x5420, 0xA771, 0x543C, 0xA772, 0x5440, 0xA773, 0x5431, + 0xA774, 0x542B, 0xA775, 0x541F, 0xA776, 0x542C, 0xA777, 0x56EA, + 0xA778, 0x56F0, 0xA779, 0x56E4, 0xA77A, 0x56EB, 0xA77B, 0x574A, + 0xA77C, 0x5751, 0xA77D, 0x5740, 0xA77E, 0x574D, 0xA7A1, 0x5747, + 0xA7A2, 0x574E, 0xA7A3, 0x573E, 0xA7A4, 0x5750, 0xA7A5, 0x574F, + 0xA7A6, 0x573B, 0xA7A7, 0x58EF, 0xA7A8, 0x593E, 0xA7A9, 0x599D, + 0xA7AA, 0x5992, 0xA7AB, 0x59A8, 0xA7AC, 0x599E, 0xA7AD, 0x59A3, + 0xA7AE, 0x5999, 0xA7AF, 0x5996, 0xA7B0, 0x598D, 0xA7B1, 0x59A4, + 0xA7B2, 0x5993, 0xA7B3, 0x598A, 0xA7B4, 0x59A5, 0xA7B5, 0x5B5D, + 0xA7B6, 0x5B5C, 0xA7B7, 0x5B5A, 0xA7B8, 0x5B5B, 0xA7B9, 0x5B8C, + 0xA7BA, 0x5B8B, 0xA7BB, 0x5B8F, 0xA7BC, 0x5C2C, 0xA7BD, 0x5C40, + 0xA7BE, 0x5C41, 0xA7BF, 0x5C3F, 0xA7C0, 0x5C3E, 0xA7C1, 0x5C90, + 0xA7C2, 0x5C91, 0xA7C3, 0x5C94, 0xA7C4, 0x5C8C, 0xA7C5, 0x5DEB, + 0xA7C6, 0x5E0C, 0xA7C7, 0x5E8F, 0xA7C8, 0x5E87, 0xA7C9, 0x5E8A, + 0xA7CA, 0x5EF7, 0xA7CB, 0x5F04, 0xA7CC, 0x5F1F, 0xA7CD, 0x5F64, + 0xA7CE, 0x5F62, 0xA7CF, 0x5F77, 0xA7D0, 0x5F79, 0xA7D1, 0x5FD8, + 0xA7D2, 0x5FCC, 0xA7D3, 0x5FD7, 0xA7D4, 0x5FCD, 0xA7D5, 0x5FF1, + 0xA7D6, 0x5FEB, 0xA7D7, 0x5FF8, 0xA7D8, 0x5FEA, 0xA7D9, 0x6212, + 0xA7DA, 0x6211, 0xA7DB, 0x6284, 0xA7DC, 0x6297, 0xA7DD, 0x6296, + 0xA7DE, 0x6280, 0xA7DF, 0x6276, 0xA7E0, 0x6289, 0xA7E1, 0x626D, + 0xA7E2, 0x628A, 0xA7E3, 0x627C, 0xA7E4, 0x627E, 0xA7E5, 0x6279, + 0xA7E6, 0x6273, 0xA7E7, 0x6292, 0xA7E8, 0x626F, 0xA7E9, 0x6298, + 0xA7EA, 0x626E, 0xA7EB, 0x6295, 0xA7EC, 0x6293, 0xA7ED, 0x6291, + 0xA7EE, 0x6286, 0xA7EF, 0x6539, 0xA7F0, 0x653B, 0xA7F1, 0x6538, + 0xA7F2, 0x65F1, 0xA7F3, 0x66F4, 0xA7F4, 0x675F, 0xA7F5, 0x674E, + 0xA7F6, 0x674F, 0xA7F7, 0x6750, 0xA7F8, 0x6751, 0xA7F9, 0x675C, + 0xA7FA, 0x6756, 0xA7FB, 0x675E, 0xA7FC, 0x6749, 0xA7FD, 0x6746, + 0xA7FE, 0x6760, 0xA840, 0x6753, 0xA841, 0x6757, 0xA842, 0x6B65, + 0xA843, 0x6BCF, 0xA844, 0x6C42, 0xA845, 0x6C5E, 0xA846, 0x6C99, + 0xA847, 0x6C81, 0xA848, 0x6C88, 0xA849, 0x6C89, 0xA84A, 0x6C85, + 0xA84B, 0x6C9B, 0xA84C, 0x6C6A, 0xA84D, 0x6C7A, 0xA84E, 0x6C90, + 0xA84F, 0x6C70, 0xA850, 0x6C8C, 0xA851, 0x6C68, 0xA852, 0x6C96, + 0xA853, 0x6C92, 0xA854, 0x6C7D, 0xA855, 0x6C83, 0xA856, 0x6C72, + 0xA857, 0x6C7E, 0xA858, 0x6C74, 0xA859, 0x6C86, 0xA85A, 0x6C76, + 0xA85B, 0x6C8D, 0xA85C, 0x6C94, 0xA85D, 0x6C98, 0xA85E, 0x6C82, + 0xA85F, 0x7076, 0xA860, 0x707C, 0xA861, 0x707D, 0xA862, 0x7078, + 0xA863, 0x7262, 0xA864, 0x7261, 0xA865, 0x7260, 0xA866, 0x72C4, + 0xA867, 0x72C2, 0xA868, 0x7396, 0xA869, 0x752C, 0xA86A, 0x752B, + 0xA86B, 0x7537, 0xA86C, 0x7538, 0xA86D, 0x7682, 0xA86E, 0x76EF, + 0xA86F, 0x77E3, 0xA870, 0x79C1, 0xA871, 0x79C0, 0xA872, 0x79BF, + 0xA873, 0x7A76, 0xA874, 0x7CFB, 0xA875, 0x7F55, 0xA876, 0x8096, + 0xA877, 0x8093, 0xA878, 0x809D, 0xA879, 0x8098, 0xA87A, 0x809B, + 0xA87B, 0x809A, 0xA87C, 0x80B2, 0xA87D, 0x826F, 0xA87E, 0x8292, + 0xA8A1, 0x828B, 0xA8A2, 0x828D, 0xA8A3, 0x898B, 0xA8A4, 0x89D2, + 0xA8A5, 0x8A00, 0xA8A6, 0x8C37, 0xA8A7, 0x8C46, 0xA8A8, 0x8C55, + 0xA8A9, 0x8C9D, 0xA8AA, 0x8D64, 0xA8AB, 0x8D70, 0xA8AC, 0x8DB3, + 0xA8AD, 0x8EAB, 0xA8AE, 0x8ECA, 0xA8AF, 0x8F9B, 0xA8B0, 0x8FB0, + 0xA8B1, 0x8FC2, 0xA8B2, 0x8FC6, 0xA8B3, 0x8FC5, 0xA8B4, 0x8FC4, + 0xA8B5, 0x5DE1, 0xA8B6, 0x9091, 0xA8B7, 0x90A2, 0xA8B8, 0x90AA, + 0xA8B9, 0x90A6, 0xA8BA, 0x90A3, 0xA8BB, 0x9149, 0xA8BC, 0x91C6, + 0xA8BD, 0x91CC, 0xA8BE, 0x9632, 0xA8BF, 0x962E, 0xA8C0, 0x9631, + 0xA8C1, 0x962A, 0xA8C2, 0x962C, 0xA8C3, 0x4E26, 0xA8C4, 0x4E56, + 0xA8C5, 0x4E73, 0xA8C6, 0x4E8B, 0xA8C7, 0x4E9B, 0xA8C8, 0x4E9E, + 0xA8C9, 0x4EAB, 0xA8CA, 0x4EAC, 0xA8CB, 0x4F6F, 0xA8CC, 0x4F9D, + 0xA8CD, 0x4F8D, 0xA8CE, 0x4F73, 0xA8CF, 0x4F7F, 0xA8D0, 0x4F6C, + 0xA8D1, 0x4F9B, 0xA8D2, 0x4F8B, 0xA8D3, 0x4F86, 0xA8D4, 0x4F83, + 0xA8D5, 0x4F70, 0xA8D6, 0x4F75, 0xA8D7, 0x4F88, 0xA8D8, 0x4F69, + 0xA8D9, 0x4F7B, 0xA8DA, 0x4F96, 0xA8DB, 0x4F7E, 0xA8DC, 0x4F8F, + 0xA8DD, 0x4F91, 0xA8DE, 0x4F7A, 0xA8DF, 0x5154, 0xA8E0, 0x5152, + 0xA8E1, 0x5155, 0xA8E2, 0x5169, 0xA8E3, 0x5177, 0xA8E4, 0x5176, + 0xA8E5, 0x5178, 0xA8E6, 0x51BD, 0xA8E7, 0x51FD, 0xA8E8, 0x523B, + 0xA8E9, 0x5238, 0xA8EA, 0x5237, 0xA8EB, 0x523A, 0xA8EC, 0x5230, + 0xA8ED, 0x522E, 0xA8EE, 0x5236, 0xA8EF, 0x5241, 0xA8F0, 0x52BE, + 0xA8F1, 0x52BB, 0xA8F2, 0x5352, 0xA8F3, 0x5354, 0xA8F4, 0x5353, + 0xA8F5, 0x5351, 0xA8F6, 0x5366, 0xA8F7, 0x5377, 0xA8F8, 0x5378, + 0xA8F9, 0x5379, 0xA8FA, 0x53D6, 0xA8FB, 0x53D4, 0xA8FC, 0x53D7, + 0xA8FD, 0x5473, 0xA8FE, 0x5475, 0xA940, 0x5496, 0xA941, 0x5478, + 0xA942, 0x5495, 0xA943, 0x5480, 0xA944, 0x547B, 0xA945, 0x5477, + 0xA946, 0x5484, 0xA947, 0x5492, 0xA948, 0x5486, 0xA949, 0x547C, + 0xA94A, 0x5490, 0xA94B, 0x5471, 0xA94C, 0x5476, 0xA94D, 0x548C, + 0xA94E, 0x549A, 0xA94F, 0x5462, 0xA950, 0x5468, 0xA951, 0x548B, + 0xA952, 0x547D, 0xA953, 0x548E, 0xA954, 0x56FA, 0xA955, 0x5783, + 0xA956, 0x5777, 0xA957, 0x576A, 0xA958, 0x5769, 0xA959, 0x5761, + 0xA95A, 0x5766, 0xA95B, 0x5764, 0xA95C, 0x577C, 0xA95D, 0x591C, + 0xA95E, 0x5949, 0xA95F, 0x5947, 0xA960, 0x5948, 0xA961, 0x5944, + 0xA962, 0x5954, 0xA963, 0x59BE, 0xA964, 0x59BB, 0xA965, 0x59D4, + 0xA966, 0x59B9, 0xA967, 0x59AE, 0xA968, 0x59D1, 0xA969, 0x59C6, + 0xA96A, 0x59D0, 0xA96B, 0x59CD, 0xA96C, 0x59CB, 0xA96D, 0x59D3, + 0xA96E, 0x59CA, 0xA96F, 0x59AF, 0xA970, 0x59B3, 0xA971, 0x59D2, + 0xA972, 0x59C5, 0xA973, 0x5B5F, 0xA974, 0x5B64, 0xA975, 0x5B63, + 0xA976, 0x5B97, 0xA977, 0x5B9A, 0xA978, 0x5B98, 0xA979, 0x5B9C, + 0xA97A, 0x5B99, 0xA97B, 0x5B9B, 0xA97C, 0x5C1A, 0xA97D, 0x5C48, + 0xA97E, 0x5C45, 0xA9A1, 0x5C46, 0xA9A2, 0x5CB7, 0xA9A3, 0x5CA1, + 0xA9A4, 0x5CB8, 0xA9A5, 0x5CA9, 0xA9A6, 0x5CAB, 0xA9A7, 0x5CB1, + 0xA9A8, 0x5CB3, 0xA9A9, 0x5E18, 0xA9AA, 0x5E1A, 0xA9AB, 0x5E16, + 0xA9AC, 0x5E15, 0xA9AD, 0x5E1B, 0xA9AE, 0x5E11, 0xA9AF, 0x5E78, + 0xA9B0, 0x5E9A, 0xA9B1, 0x5E97, 0xA9B2, 0x5E9C, 0xA9B3, 0x5E95, + 0xA9B4, 0x5E96, 0xA9B5, 0x5EF6, 0xA9B6, 0x5F26, 0xA9B7, 0x5F27, + 0xA9B8, 0x5F29, 0xA9B9, 0x5F80, 0xA9BA, 0x5F81, 0xA9BB, 0x5F7F, + 0xA9BC, 0x5F7C, 0xA9BD, 0x5FDD, 0xA9BE, 0x5FE0, 0xA9BF, 0x5FFD, + 0xA9C0, 0x5FF5, 0xA9C1, 0x5FFF, 0xA9C2, 0x600F, 0xA9C3, 0x6014, + 0xA9C4, 0x602F, 0xA9C5, 0x6035, 0xA9C6, 0x6016, 0xA9C7, 0x602A, + 0xA9C8, 0x6015, 0xA9C9, 0x6021, 0xA9CA, 0x6027, 0xA9CB, 0x6029, + 0xA9CC, 0x602B, 0xA9CD, 0x601B, 0xA9CE, 0x6216, 0xA9CF, 0x6215, + 0xA9D0, 0x623F, 0xA9D1, 0x623E, 0xA9D2, 0x6240, 0xA9D3, 0x627F, + 0xA9D4, 0x62C9, 0xA9D5, 0x62CC, 0xA9D6, 0x62C4, 0xA9D7, 0x62BF, + 0xA9D8, 0x62C2, 0xA9D9, 0x62B9, 0xA9DA, 0x62D2, 0xA9DB, 0x62DB, + 0xA9DC, 0x62AB, 0xA9DD, 0x62D3, 0xA9DE, 0x62D4, 0xA9DF, 0x62CB, + 0xA9E0, 0x62C8, 0xA9E1, 0x62A8, 0xA9E2, 0x62BD, 0xA9E3, 0x62BC, + 0xA9E4, 0x62D0, 0xA9E5, 0x62D9, 0xA9E6, 0x62C7, 0xA9E7, 0x62CD, + 0xA9E8, 0x62B5, 0xA9E9, 0x62DA, 0xA9EA, 0x62B1, 0xA9EB, 0x62D8, + 0xA9EC, 0x62D6, 0xA9ED, 0x62D7, 0xA9EE, 0x62C6, 0xA9EF, 0x62AC, + 0xA9F0, 0x62CE, 0xA9F1, 0x653E, 0xA9F2, 0x65A7, 0xA9F3, 0x65BC, + 0xA9F4, 0x65FA, 0xA9F5, 0x6614, 0xA9F6, 0x6613, 0xA9F7, 0x660C, + 0xA9F8, 0x6606, 0xA9F9, 0x6602, 0xA9FA, 0x660E, 0xA9FB, 0x6600, + 0xA9FC, 0x660F, 0xA9FD, 0x6615, 0xA9FE, 0x660A, 0xAA40, 0x6607, + 0xAA41, 0x670D, 0xAA42, 0x670B, 0xAA43, 0x676D, 0xAA44, 0x678B, + 0xAA45, 0x6795, 0xAA46, 0x6771, 0xAA47, 0x679C, 0xAA48, 0x6773, + 0xAA49, 0x6777, 0xAA4A, 0x6787, 0xAA4B, 0x679D, 0xAA4C, 0x6797, + 0xAA4D, 0x676F, 0xAA4E, 0x6770, 0xAA4F, 0x677F, 0xAA50, 0x6789, + 0xAA51, 0x677E, 0xAA52, 0x6790, 0xAA53, 0x6775, 0xAA54, 0x679A, + 0xAA55, 0x6793, 0xAA56, 0x677C, 0xAA57, 0x676A, 0xAA58, 0x6772, + 0xAA59, 0x6B23, 0xAA5A, 0x6B66, 0xAA5B, 0x6B67, 0xAA5C, 0x6B7F, + 0xAA5D, 0x6C13, 0xAA5E, 0x6C1B, 0xAA5F, 0x6CE3, 0xAA60, 0x6CE8, + 0xAA61, 0x6CF3, 0xAA62, 0x6CB1, 0xAA63, 0x6CCC, 0xAA64, 0x6CE5, + 0xAA65, 0x6CB3, 0xAA66, 0x6CBD, 0xAA67, 0x6CBE, 0xAA68, 0x6CBC, + 0xAA69, 0x6CE2, 0xAA6A, 0x6CAB, 0xAA6B, 0x6CD5, 0xAA6C, 0x6CD3, + 0xAA6D, 0x6CB8, 0xAA6E, 0x6CC4, 0xAA6F, 0x6CB9, 0xAA70, 0x6CC1, + 0xAA71, 0x6CAE, 0xAA72, 0x6CD7, 0xAA73, 0x6CC5, 0xAA74, 0x6CF1, + 0xAA75, 0x6CBF, 0xAA76, 0x6CBB, 0xAA77, 0x6CE1, 0xAA78, 0x6CDB, + 0xAA79, 0x6CCA, 0xAA7A, 0x6CAC, 0xAA7B, 0x6CEF, 0xAA7C, 0x6CDC, + 0xAA7D, 0x6CD6, 0xAA7E, 0x6CE0, 0xAAA1, 0x7095, 0xAAA2, 0x708E, + 0xAAA3, 0x7092, 0xAAA4, 0x708A, 0xAAA5, 0x7099, 0xAAA6, 0x722C, + 0xAAA7, 0x722D, 0xAAA8, 0x7238, 0xAAA9, 0x7248, 0xAAAA, 0x7267, + 0xAAAB, 0x7269, 0xAAAC, 0x72C0, 0xAAAD, 0x72CE, 0xAAAE, 0x72D9, + 0xAAAF, 0x72D7, 0xAAB0, 0x72D0, 0xAAB1, 0x73A9, 0xAAB2, 0x73A8, + 0xAAB3, 0x739F, 0xAAB4, 0x73AB, 0xAAB5, 0x73A5, 0xAAB6, 0x753D, + 0xAAB7, 0x759D, 0xAAB8, 0x7599, 0xAAB9, 0x759A, 0xAABA, 0x7684, + 0xAABB, 0x76C2, 0xAABC, 0x76F2, 0xAABD, 0x76F4, 0xAABE, 0x77E5, + 0xAABF, 0x77FD, 0xAAC0, 0x793E, 0xAAC1, 0x7940, 0xAAC2, 0x7941, + 0xAAC3, 0x79C9, 0xAAC4, 0x79C8, 0xAAC5, 0x7A7A, 0xAAC6, 0x7A79, + 0xAAC7, 0x7AFA, 0xAAC8, 0x7CFE, 0xAAC9, 0x7F54, 0xAACA, 0x7F8C, + 0xAACB, 0x7F8B, 0xAACC, 0x8005, 0xAACD, 0x80BA, 0xAACE, 0x80A5, + 0xAACF, 0x80A2, 0xAAD0, 0x80B1, 0xAAD1, 0x80A1, 0xAAD2, 0x80AB, + 0xAAD3, 0x80A9, 0xAAD4, 0x80B4, 0xAAD5, 0x80AA, 0xAAD6, 0x80AF, + 0xAAD7, 0x81E5, 0xAAD8, 0x81FE, 0xAAD9, 0x820D, 0xAADA, 0x82B3, + 0xAADB, 0x829D, 0xAADC, 0x8299, 0xAADD, 0x82AD, 0xAADE, 0x82BD, + 0xAADF, 0x829F, 0xAAE0, 0x82B9, 0xAAE1, 0x82B1, 0xAAE2, 0x82AC, + 0xAAE3, 0x82A5, 0xAAE4, 0x82AF, 0xAAE5, 0x82B8, 0xAAE6, 0x82A3, + 0xAAE7, 0x82B0, 0xAAE8, 0x82BE, 0xAAE9, 0x82B7, 0xAAEA, 0x864E, + 0xAAEB, 0x8671, 0xAAEC, 0x521D, 0xAAED, 0x8868, 0xAAEE, 0x8ECB, + 0xAAEF, 0x8FCE, 0xAAF0, 0x8FD4, 0xAAF1, 0x8FD1, 0xAAF2, 0x90B5, + 0xAAF3, 0x90B8, 0xAAF4, 0x90B1, 0xAAF5, 0x90B6, 0xAAF6, 0x91C7, + 0xAAF7, 0x91D1, 0xAAF8, 0x9577, 0xAAF9, 0x9580, 0xAAFA, 0x961C, + 0xAAFB, 0x9640, 0xAAFC, 0x963F, 0xAAFD, 0x963B, 0xAAFE, 0x9644, + 0xAB40, 0x9642, 0xAB41, 0x96B9, 0xAB42, 0x96E8, 0xAB43, 0x9752, + 0xAB44, 0x975E, 0xAB45, 0x4E9F, 0xAB46, 0x4EAD, 0xAB47, 0x4EAE, + 0xAB48, 0x4FE1, 0xAB49, 0x4FB5, 0xAB4A, 0x4FAF, 0xAB4B, 0x4FBF, + 0xAB4C, 0x4FE0, 0xAB4D, 0x4FD1, 0xAB4E, 0x4FCF, 0xAB4F, 0x4FDD, + 0xAB50, 0x4FC3, 0xAB51, 0x4FB6, 0xAB52, 0x4FD8, 0xAB53, 0x4FDF, + 0xAB54, 0x4FCA, 0xAB55, 0x4FD7, 0xAB56, 0x4FAE, 0xAB57, 0x4FD0, + 0xAB58, 0x4FC4, 0xAB59, 0x4FC2, 0xAB5A, 0x4FDA, 0xAB5B, 0x4FCE, + 0xAB5C, 0x4FDE, 0xAB5D, 0x4FB7, 0xAB5E, 0x5157, 0xAB5F, 0x5192, + 0xAB60, 0x5191, 0xAB61, 0x51A0, 0xAB62, 0x524E, 0xAB63, 0x5243, + 0xAB64, 0x524A, 0xAB65, 0x524D, 0xAB66, 0x524C, 0xAB67, 0x524B, + 0xAB68, 0x5247, 0xAB69, 0x52C7, 0xAB6A, 0x52C9, 0xAB6B, 0x52C3, + 0xAB6C, 0x52C1, 0xAB6D, 0x530D, 0xAB6E, 0x5357, 0xAB6F, 0x537B, + 0xAB70, 0x539A, 0xAB71, 0x53DB, 0xAB72, 0x54AC, 0xAB73, 0x54C0, + 0xAB74, 0x54A8, 0xAB75, 0x54CE, 0xAB76, 0x54C9, 0xAB77, 0x54B8, + 0xAB78, 0x54A6, 0xAB79, 0x54B3, 0xAB7A, 0x54C7, 0xAB7B, 0x54C2, + 0xAB7C, 0x54BD, 0xAB7D, 0x54AA, 0xAB7E, 0x54C1, 0xABA1, 0x54C4, + 0xABA2, 0x54C8, 0xABA3, 0x54AF, 0xABA4, 0x54AB, 0xABA5, 0x54B1, + 0xABA6, 0x54BB, 0xABA7, 0x54A9, 0xABA8, 0x54A7, 0xABA9, 0x54BF, + 0xABAA, 0x56FF, 0xABAB, 0x5782, 0xABAC, 0x578B, 0xABAD, 0x57A0, + 0xABAE, 0x57A3, 0xABAF, 0x57A2, 0xABB0, 0x57CE, 0xABB1, 0x57AE, + 0xABB2, 0x5793, 0xABB3, 0x5955, 0xABB4, 0x5951, 0xABB5, 0x594F, + 0xABB6, 0x594E, 0xABB7, 0x5950, 0xABB8, 0x59DC, 0xABB9, 0x59D8, + 0xABBA, 0x59FF, 0xABBB, 0x59E3, 0xABBC, 0x59E8, 0xABBD, 0x5A03, + 0xABBE, 0x59E5, 0xABBF, 0x59EA, 0xABC0, 0x59DA, 0xABC1, 0x59E6, + 0xABC2, 0x5A01, 0xABC3, 0x59FB, 0xABC4, 0x5B69, 0xABC5, 0x5BA3, + 0xABC6, 0x5BA6, 0xABC7, 0x5BA4, 0xABC8, 0x5BA2, 0xABC9, 0x5BA5, + 0xABCA, 0x5C01, 0xABCB, 0x5C4E, 0xABCC, 0x5C4F, 0xABCD, 0x5C4D, + 0xABCE, 0x5C4B, 0xABCF, 0x5CD9, 0xABD0, 0x5CD2, 0xABD1, 0x5DF7, + 0xABD2, 0x5E1D, 0xABD3, 0x5E25, 0xABD4, 0x5E1F, 0xABD5, 0x5E7D, + 0xABD6, 0x5EA0, 0xABD7, 0x5EA6, 0xABD8, 0x5EFA, 0xABD9, 0x5F08, + 0xABDA, 0x5F2D, 0xABDB, 0x5F65, 0xABDC, 0x5F88, 0xABDD, 0x5F85, + 0xABDE, 0x5F8A, 0xABDF, 0x5F8B, 0xABE0, 0x5F87, 0xABE1, 0x5F8C, + 0xABE2, 0x5F89, 0xABE3, 0x6012, 0xABE4, 0x601D, 0xABE5, 0x6020, + 0xABE6, 0x6025, 0xABE7, 0x600E, 0xABE8, 0x6028, 0xABE9, 0x604D, + 0xABEA, 0x6070, 0xABEB, 0x6068, 0xABEC, 0x6062, 0xABED, 0x6046, + 0xABEE, 0x6043, 0xABEF, 0x606C, 0xABF0, 0x606B, 0xABF1, 0x606A, + 0xABF2, 0x6064, 0xABF3, 0x6241, 0xABF4, 0x62DC, 0xABF5, 0x6316, + 0xABF6, 0x6309, 0xABF7, 0x62FC, 0xABF8, 0x62ED, 0xABF9, 0x6301, + 0xABFA, 0x62EE, 0xABFB, 0x62FD, 0xABFC, 0x6307, 0xABFD, 0x62F1, + 0xABFE, 0x62F7, 0xAC40, 0x62EF, 0xAC41, 0x62EC, 0xAC42, 0x62FE, + 0xAC43, 0x62F4, 0xAC44, 0x6311, 0xAC45, 0x6302, 0xAC46, 0x653F, + 0xAC47, 0x6545, 0xAC48, 0x65AB, 0xAC49, 0x65BD, 0xAC4A, 0x65E2, + 0xAC4B, 0x6625, 0xAC4C, 0x662D, 0xAC4D, 0x6620, 0xAC4E, 0x6627, + 0xAC4F, 0x662F, 0xAC50, 0x661F, 0xAC51, 0x6628, 0xAC52, 0x6631, + 0xAC53, 0x6624, 0xAC54, 0x66F7, 0xAC55, 0x67FF, 0xAC56, 0x67D3, + 0xAC57, 0x67F1, 0xAC58, 0x67D4, 0xAC59, 0x67D0, 0xAC5A, 0x67EC, + 0xAC5B, 0x67B6, 0xAC5C, 0x67AF, 0xAC5D, 0x67F5, 0xAC5E, 0x67E9, + 0xAC5F, 0x67EF, 0xAC60, 0x67C4, 0xAC61, 0x67D1, 0xAC62, 0x67B4, + 0xAC63, 0x67DA, 0xAC64, 0x67E5, 0xAC65, 0x67B8, 0xAC66, 0x67CF, + 0xAC67, 0x67DE, 0xAC68, 0x67F3, 0xAC69, 0x67B0, 0xAC6A, 0x67D9, + 0xAC6B, 0x67E2, 0xAC6C, 0x67DD, 0xAC6D, 0x67D2, 0xAC6E, 0x6B6A, + 0xAC6F, 0x6B83, 0xAC70, 0x6B86, 0xAC71, 0x6BB5, 0xAC72, 0x6BD2, + 0xAC73, 0x6BD7, 0xAC74, 0x6C1F, 0xAC75, 0x6CC9, 0xAC76, 0x6D0B, + 0xAC77, 0x6D32, 0xAC78, 0x6D2A, 0xAC79, 0x6D41, 0xAC7A, 0x6D25, + 0xAC7B, 0x6D0C, 0xAC7C, 0x6D31, 0xAC7D, 0x6D1E, 0xAC7E, 0x6D17, + 0xACA1, 0x6D3B, 0xACA2, 0x6D3D, 0xACA3, 0x6D3E, 0xACA4, 0x6D36, + 0xACA5, 0x6D1B, 0xACA6, 0x6CF5, 0xACA7, 0x6D39, 0xACA8, 0x6D27, + 0xACA9, 0x6D38, 0xACAA, 0x6D29, 0xACAB, 0x6D2E, 0xACAC, 0x6D35, + 0xACAD, 0x6D0E, 0xACAE, 0x6D2B, 0xACAF, 0x70AB, 0xACB0, 0x70BA, + 0xACB1, 0x70B3, 0xACB2, 0x70AC, 0xACB3, 0x70AF, 0xACB4, 0x70AD, + 0xACB5, 0x70B8, 0xACB6, 0x70AE, 0xACB7, 0x70A4, 0xACB8, 0x7230, + 0xACB9, 0x7272, 0xACBA, 0x726F, 0xACBB, 0x7274, 0xACBC, 0x72E9, + 0xACBD, 0x72E0, 0xACBE, 0x72E1, 0xACBF, 0x73B7, 0xACC0, 0x73CA, + 0xACC1, 0x73BB, 0xACC2, 0x73B2, 0xACC3, 0x73CD, 0xACC4, 0x73C0, + 0xACC5, 0x73B3, 0xACC6, 0x751A, 0xACC7, 0x752D, 0xACC8, 0x754F, + 0xACC9, 0x754C, 0xACCA, 0x754E, 0xACCB, 0x754B, 0xACCC, 0x75AB, + 0xACCD, 0x75A4, 0xACCE, 0x75A5, 0xACCF, 0x75A2, 0xACD0, 0x75A3, + 0xACD1, 0x7678, 0xACD2, 0x7686, 0xACD3, 0x7687, 0xACD4, 0x7688, + 0xACD5, 0x76C8, 0xACD6, 0x76C6, 0xACD7, 0x76C3, 0xACD8, 0x76C5, + 0xACD9, 0x7701, 0xACDA, 0x76F9, 0xACDB, 0x76F8, 0xACDC, 0x7709, + 0xACDD, 0x770B, 0xACDE, 0x76FE, 0xACDF, 0x76FC, 0xACE0, 0x7707, + 0xACE1, 0x77DC, 0xACE2, 0x7802, 0xACE3, 0x7814, 0xACE4, 0x780C, + 0xACE5, 0x780D, 0xACE6, 0x7946, 0xACE7, 0x7949, 0xACE8, 0x7948, + 0xACE9, 0x7947, 0xACEA, 0x79B9, 0xACEB, 0x79BA, 0xACEC, 0x79D1, + 0xACED, 0x79D2, 0xACEE, 0x79CB, 0xACEF, 0x7A7F, 0xACF0, 0x7A81, + 0xACF1, 0x7AFF, 0xACF2, 0x7AFD, 0xACF3, 0x7C7D, 0xACF4, 0x7D02, + 0xACF5, 0x7D05, 0xACF6, 0x7D00, 0xACF7, 0x7D09, 0xACF8, 0x7D07, + 0xACF9, 0x7D04, 0xACFA, 0x7D06, 0xACFB, 0x7F38, 0xACFC, 0x7F8E, + 0xACFD, 0x7FBF, 0xACFE, 0x8004, 0xAD40, 0x8010, 0xAD41, 0x800D, + 0xAD42, 0x8011, 0xAD43, 0x8036, 0xAD44, 0x80D6, 0xAD45, 0x80E5, + 0xAD46, 0x80DA, 0xAD47, 0x80C3, 0xAD48, 0x80C4, 0xAD49, 0x80CC, + 0xAD4A, 0x80E1, 0xAD4B, 0x80DB, 0xAD4C, 0x80CE, 0xAD4D, 0x80DE, + 0xAD4E, 0x80E4, 0xAD4F, 0x80DD, 0xAD50, 0x81F4, 0xAD51, 0x8222, + 0xAD52, 0x82E7, 0xAD53, 0x8303, 0xAD54, 0x8305, 0xAD55, 0x82E3, + 0xAD56, 0x82DB, 0xAD57, 0x82E6, 0xAD58, 0x8304, 0xAD59, 0x82E5, + 0xAD5A, 0x8302, 0xAD5B, 0x8309, 0xAD5C, 0x82D2, 0xAD5D, 0x82D7, + 0xAD5E, 0x82F1, 0xAD5F, 0x8301, 0xAD60, 0x82DC, 0xAD61, 0x82D4, + 0xAD62, 0x82D1, 0xAD63, 0x82DE, 0xAD64, 0x82D3, 0xAD65, 0x82DF, + 0xAD66, 0x82EF, 0xAD67, 0x8306, 0xAD68, 0x8650, 0xAD69, 0x8679, + 0xAD6A, 0x867B, 0xAD6B, 0x867A, 0xAD6C, 0x884D, 0xAD6D, 0x886B, + 0xAD6E, 0x8981, 0xAD6F, 0x89D4, 0xAD70, 0x8A08, 0xAD71, 0x8A02, + 0xAD72, 0x8A03, 0xAD73, 0x8C9E, 0xAD74, 0x8CA0, 0xAD75, 0x8D74, + 0xAD76, 0x8D73, 0xAD77, 0x8DB4, 0xAD78, 0x8ECD, 0xAD79, 0x8ECC, + 0xAD7A, 0x8FF0, 0xAD7B, 0x8FE6, 0xAD7C, 0x8FE2, 0xAD7D, 0x8FEA, + 0xAD7E, 0x8FE5, 0xADA1, 0x8FED, 0xADA2, 0x8FEB, 0xADA3, 0x8FE4, + 0xADA4, 0x8FE8, 0xADA5, 0x90CA, 0xADA6, 0x90CE, 0xADA7, 0x90C1, + 0xADA8, 0x90C3, 0xADA9, 0x914B, 0xADAA, 0x914A, 0xADAB, 0x91CD, + 0xADAC, 0x9582, 0xADAD, 0x9650, 0xADAE, 0x964B, 0xADAF, 0x964C, + 0xADB0, 0x964D, 0xADB1, 0x9762, 0xADB2, 0x9769, 0xADB3, 0x97CB, + 0xADB4, 0x97ED, 0xADB5, 0x97F3, 0xADB6, 0x9801, 0xADB7, 0x98A8, + 0xADB8, 0x98DB, 0xADB9, 0x98DF, 0xADBA, 0x9996, 0xADBB, 0x9999, + 0xADBC, 0x4E58, 0xADBD, 0x4EB3, 0xADBE, 0x500C, 0xADBF, 0x500D, + 0xADC0, 0x5023, 0xADC1, 0x4FEF, 0xADC2, 0x5026, 0xADC3, 0x5025, + 0xADC4, 0x4FF8, 0xADC5, 0x5029, 0xADC6, 0x5016, 0xADC7, 0x5006, + 0xADC8, 0x503C, 0xADC9, 0x501F, 0xADCA, 0x501A, 0xADCB, 0x5012, + 0xADCC, 0x5011, 0xADCD, 0x4FFA, 0xADCE, 0x5000, 0xADCF, 0x5014, + 0xADD0, 0x5028, 0xADD1, 0x4FF1, 0xADD2, 0x5021, 0xADD3, 0x500B, + 0xADD4, 0x5019, 0xADD5, 0x5018, 0xADD6, 0x4FF3, 0xADD7, 0x4FEE, + 0xADD8, 0x502D, 0xADD9, 0x502A, 0xADDA, 0x4FFE, 0xADDB, 0x502B, + 0xADDC, 0x5009, 0xADDD, 0x517C, 0xADDE, 0x51A4, 0xADDF, 0x51A5, + 0xADE0, 0x51A2, 0xADE1, 0x51CD, 0xADE2, 0x51CC, 0xADE3, 0x51C6, + 0xADE4, 0x51CB, 0xADE5, 0x5256, 0xADE6, 0x525C, 0xADE7, 0x5254, + 0xADE8, 0x525B, 0xADE9, 0x525D, 0xADEA, 0x532A, 0xADEB, 0x537F, + 0xADEC, 0x539F, 0xADED, 0x539D, 0xADEE, 0x53DF, 0xADEF, 0x54E8, + 0xADF0, 0x5510, 0xADF1, 0x5501, 0xADF2, 0x5537, 0xADF3, 0x54FC, + 0xADF4, 0x54E5, 0xADF5, 0x54F2, 0xADF6, 0x5506, 0xADF7, 0x54FA, + 0xADF8, 0x5514, 0xADF9, 0x54E9, 0xADFA, 0x54ED, 0xADFB, 0x54E1, + 0xADFC, 0x5509, 0xADFD, 0x54EE, 0xADFE, 0x54EA, 0xAE40, 0x54E6, + 0xAE41, 0x5527, 0xAE42, 0x5507, 0xAE43, 0x54FD, 0xAE44, 0x550F, + 0xAE45, 0x5703, 0xAE46, 0x5704, 0xAE47, 0x57C2, 0xAE48, 0x57D4, + 0xAE49, 0x57CB, 0xAE4A, 0x57C3, 0xAE4B, 0x5809, 0xAE4C, 0x590F, + 0xAE4D, 0x5957, 0xAE4E, 0x5958, 0xAE4F, 0x595A, 0xAE50, 0x5A11, + 0xAE51, 0x5A18, 0xAE52, 0x5A1C, 0xAE53, 0x5A1F, 0xAE54, 0x5A1B, + 0xAE55, 0x5A13, 0xAE56, 0x59EC, 0xAE57, 0x5A20, 0xAE58, 0x5A23, + 0xAE59, 0x5A29, 0xAE5A, 0x5A25, 0xAE5B, 0x5A0C, 0xAE5C, 0x5A09, + 0xAE5D, 0x5B6B, 0xAE5E, 0x5C58, 0xAE5F, 0x5BB0, 0xAE60, 0x5BB3, + 0xAE61, 0x5BB6, 0xAE62, 0x5BB4, 0xAE63, 0x5BAE, 0xAE64, 0x5BB5, + 0xAE65, 0x5BB9, 0xAE66, 0x5BB8, 0xAE67, 0x5C04, 0xAE68, 0x5C51, + 0xAE69, 0x5C55, 0xAE6A, 0x5C50, 0xAE6B, 0x5CED, 0xAE6C, 0x5CFD, + 0xAE6D, 0x5CFB, 0xAE6E, 0x5CEA, 0xAE6F, 0x5CE8, 0xAE70, 0x5CF0, + 0xAE71, 0x5CF6, 0xAE72, 0x5D01, 0xAE73, 0x5CF4, 0xAE74, 0x5DEE, + 0xAE75, 0x5E2D, 0xAE76, 0x5E2B, 0xAE77, 0x5EAB, 0xAE78, 0x5EAD, + 0xAE79, 0x5EA7, 0xAE7A, 0x5F31, 0xAE7B, 0x5F92, 0xAE7C, 0x5F91, + 0xAE7D, 0x5F90, 0xAE7E, 0x6059, 0xAEA1, 0x6063, 0xAEA2, 0x6065, + 0xAEA3, 0x6050, 0xAEA4, 0x6055, 0xAEA5, 0x606D, 0xAEA6, 0x6069, + 0xAEA7, 0x606F, 0xAEA8, 0x6084, 0xAEA9, 0x609F, 0xAEAA, 0x609A, + 0xAEAB, 0x608D, 0xAEAC, 0x6094, 0xAEAD, 0x608C, 0xAEAE, 0x6085, + 0xAEAF, 0x6096, 0xAEB0, 0x6247, 0xAEB1, 0x62F3, 0xAEB2, 0x6308, + 0xAEB3, 0x62FF, 0xAEB4, 0x634E, 0xAEB5, 0x633E, 0xAEB6, 0x632F, + 0xAEB7, 0x6355, 0xAEB8, 0x6342, 0xAEB9, 0x6346, 0xAEBA, 0x634F, + 0xAEBB, 0x6349, 0xAEBC, 0x633A, 0xAEBD, 0x6350, 0xAEBE, 0x633D, + 0xAEBF, 0x632A, 0xAEC0, 0x632B, 0xAEC1, 0x6328, 0xAEC2, 0x634D, + 0xAEC3, 0x634C, 0xAEC4, 0x6548, 0xAEC5, 0x6549, 0xAEC6, 0x6599, + 0xAEC7, 0x65C1, 0xAEC8, 0x65C5, 0xAEC9, 0x6642, 0xAECA, 0x6649, + 0xAECB, 0x664F, 0xAECC, 0x6643, 0xAECD, 0x6652, 0xAECE, 0x664C, + 0xAECF, 0x6645, 0xAED0, 0x6641, 0xAED1, 0x66F8, 0xAED2, 0x6714, + 0xAED3, 0x6715, 0xAED4, 0x6717, 0xAED5, 0x6821, 0xAED6, 0x6838, + 0xAED7, 0x6848, 0xAED8, 0x6846, 0xAED9, 0x6853, 0xAEDA, 0x6839, + 0xAEDB, 0x6842, 0xAEDC, 0x6854, 0xAEDD, 0x6829, 0xAEDE, 0x68B3, + 0xAEDF, 0x6817, 0xAEE0, 0x684C, 0xAEE1, 0x6851, 0xAEE2, 0x683D, + 0xAEE3, 0x67F4, 0xAEE4, 0x6850, 0xAEE5, 0x6840, 0xAEE6, 0x683C, + 0xAEE7, 0x6843, 0xAEE8, 0x682A, 0xAEE9, 0x6845, 0xAEEA, 0x6813, + 0xAEEB, 0x6818, 0xAEEC, 0x6841, 0xAEED, 0x6B8A, 0xAEEE, 0x6B89, + 0xAEEF, 0x6BB7, 0xAEF0, 0x6C23, 0xAEF1, 0x6C27, 0xAEF2, 0x6C28, + 0xAEF3, 0x6C26, 0xAEF4, 0x6C24, 0xAEF5, 0x6CF0, 0xAEF6, 0x6D6A, + 0xAEF7, 0x6D95, 0xAEF8, 0x6D88, 0xAEF9, 0x6D87, 0xAEFA, 0x6D66, + 0xAEFB, 0x6D78, 0xAEFC, 0x6D77, 0xAEFD, 0x6D59, 0xAEFE, 0x6D93, + 0xAF40, 0x6D6C, 0xAF41, 0x6D89, 0xAF42, 0x6D6E, 0xAF43, 0x6D5A, + 0xAF44, 0x6D74, 0xAF45, 0x6D69, 0xAF46, 0x6D8C, 0xAF47, 0x6D8A, + 0xAF48, 0x6D79, 0xAF49, 0x6D85, 0xAF4A, 0x6D65, 0xAF4B, 0x6D94, + 0xAF4C, 0x70CA, 0xAF4D, 0x70D8, 0xAF4E, 0x70E4, 0xAF4F, 0x70D9, + 0xAF50, 0x70C8, 0xAF51, 0x70CF, 0xAF52, 0x7239, 0xAF53, 0x7279, + 0xAF54, 0x72FC, 0xAF55, 0x72F9, 0xAF56, 0x72FD, 0xAF57, 0x72F8, + 0xAF58, 0x72F7, 0xAF59, 0x7386, 0xAF5A, 0x73ED, 0xAF5B, 0x7409, + 0xAF5C, 0x73EE, 0xAF5D, 0x73E0, 0xAF5E, 0x73EA, 0xAF5F, 0x73DE, + 0xAF60, 0x7554, 0xAF61, 0x755D, 0xAF62, 0x755C, 0xAF63, 0x755A, + 0xAF64, 0x7559, 0xAF65, 0x75BE, 0xAF66, 0x75C5, 0xAF67, 0x75C7, + 0xAF68, 0x75B2, 0xAF69, 0x75B3, 0xAF6A, 0x75BD, 0xAF6B, 0x75BC, + 0xAF6C, 0x75B9, 0xAF6D, 0x75C2, 0xAF6E, 0x75B8, 0xAF6F, 0x768B, + 0xAF70, 0x76B0, 0xAF71, 0x76CA, 0xAF72, 0x76CD, 0xAF73, 0x76CE, + 0xAF74, 0x7729, 0xAF75, 0x771F, 0xAF76, 0x7720, 0xAF77, 0x7728, + 0xAF78, 0x77E9, 0xAF79, 0x7830, 0xAF7A, 0x7827, 0xAF7B, 0x7838, + 0xAF7C, 0x781D, 0xAF7D, 0x7834, 0xAF7E, 0x7837, 0xAFA1, 0x7825, + 0xAFA2, 0x782D, 0xAFA3, 0x7820, 0xAFA4, 0x781F, 0xAFA5, 0x7832, + 0xAFA6, 0x7955, 0xAFA7, 0x7950, 0xAFA8, 0x7960, 0xAFA9, 0x795F, + 0xAFAA, 0x7956, 0xAFAB, 0x795E, 0xAFAC, 0x795D, 0xAFAD, 0x7957, + 0xAFAE, 0x795A, 0xAFAF, 0x79E4, 0xAFB0, 0x79E3, 0xAFB1, 0x79E7, + 0xAFB2, 0x79DF, 0xAFB3, 0x79E6, 0xAFB4, 0x79E9, 0xAFB5, 0x79D8, + 0xAFB6, 0x7A84, 0xAFB7, 0x7A88, 0xAFB8, 0x7AD9, 0xAFB9, 0x7B06, + 0xAFBA, 0x7B11, 0xAFBB, 0x7C89, 0xAFBC, 0x7D21, 0xAFBD, 0x7D17, + 0xAFBE, 0x7D0B, 0xAFBF, 0x7D0A, 0xAFC0, 0x7D20, 0xAFC1, 0x7D22, + 0xAFC2, 0x7D14, 0xAFC3, 0x7D10, 0xAFC4, 0x7D15, 0xAFC5, 0x7D1A, + 0xAFC6, 0x7D1C, 0xAFC7, 0x7D0D, 0xAFC8, 0x7D19, 0xAFC9, 0x7D1B, + 0xAFCA, 0x7F3A, 0xAFCB, 0x7F5F, 0xAFCC, 0x7F94, 0xAFCD, 0x7FC5, + 0xAFCE, 0x7FC1, 0xAFCF, 0x8006, 0xAFD0, 0x8018, 0xAFD1, 0x8015, + 0xAFD2, 0x8019, 0xAFD3, 0x8017, 0xAFD4, 0x803D, 0xAFD5, 0x803F, + 0xAFD6, 0x80F1, 0xAFD7, 0x8102, 0xAFD8, 0x80F0, 0xAFD9, 0x8105, + 0xAFDA, 0x80ED, 0xAFDB, 0x80F4, 0xAFDC, 0x8106, 0xAFDD, 0x80F8, + 0xAFDE, 0x80F3, 0xAFDF, 0x8108, 0xAFE0, 0x80FD, 0xAFE1, 0x810A, + 0xAFE2, 0x80FC, 0xAFE3, 0x80EF, 0xAFE4, 0x81ED, 0xAFE5, 0x81EC, + 0xAFE6, 0x8200, 0xAFE7, 0x8210, 0xAFE8, 0x822A, 0xAFE9, 0x822B, + 0xAFEA, 0x8228, 0xAFEB, 0x822C, 0xAFEC, 0x82BB, 0xAFED, 0x832B, + 0xAFEE, 0x8352, 0xAFEF, 0x8354, 0xAFF0, 0x834A, 0xAFF1, 0x8338, + 0xAFF2, 0x8350, 0xAFF3, 0x8349, 0xAFF4, 0x8335, 0xAFF5, 0x8334, + 0xAFF6, 0x834F, 0xAFF7, 0x8332, 0xAFF8, 0x8339, 0xAFF9, 0x8336, + 0xAFFA, 0x8317, 0xAFFB, 0x8340, 0xAFFC, 0x8331, 0xAFFD, 0x8328, + 0xAFFE, 0x8343, 0xB040, 0x8654, 0xB041, 0x868A, 0xB042, 0x86AA, + 0xB043, 0x8693, 0xB044, 0x86A4, 0xB045, 0x86A9, 0xB046, 0x868C, + 0xB047, 0x86A3, 0xB048, 0x869C, 0xB049, 0x8870, 0xB04A, 0x8877, + 0xB04B, 0x8881, 0xB04C, 0x8882, 0xB04D, 0x887D, 0xB04E, 0x8879, + 0xB04F, 0x8A18, 0xB050, 0x8A10, 0xB051, 0x8A0E, 0xB052, 0x8A0C, + 0xB053, 0x8A15, 0xB054, 0x8A0A, 0xB055, 0x8A17, 0xB056, 0x8A13, + 0xB057, 0x8A16, 0xB058, 0x8A0F, 0xB059, 0x8A11, 0xB05A, 0x8C48, + 0xB05B, 0x8C7A, 0xB05C, 0x8C79, 0xB05D, 0x8CA1, 0xB05E, 0x8CA2, + 0xB05F, 0x8D77, 0xB060, 0x8EAC, 0xB061, 0x8ED2, 0xB062, 0x8ED4, + 0xB063, 0x8ECF, 0xB064, 0x8FB1, 0xB065, 0x9001, 0xB066, 0x9006, + 0xB067, 0x8FF7, 0xB068, 0x9000, 0xB069, 0x8FFA, 0xB06A, 0x8FF4, + 0xB06B, 0x9003, 0xB06C, 0x8FFD, 0xB06D, 0x9005, 0xB06E, 0x8FF8, + 0xB06F, 0x9095, 0xB070, 0x90E1, 0xB071, 0x90DD, 0xB072, 0x90E2, + 0xB073, 0x9152, 0xB074, 0x914D, 0xB075, 0x914C, 0xB076, 0x91D8, + 0xB077, 0x91DD, 0xB078, 0x91D7, 0xB079, 0x91DC, 0xB07A, 0x91D9, + 0xB07B, 0x9583, 0xB07C, 0x9662, 0xB07D, 0x9663, 0xB07E, 0x9661, + 0xB0A1, 0x965B, 0xB0A2, 0x965D, 0xB0A3, 0x9664, 0xB0A4, 0x9658, + 0xB0A5, 0x965E, 0xB0A6, 0x96BB, 0xB0A7, 0x98E2, 0xB0A8, 0x99AC, + 0xB0A9, 0x9AA8, 0xB0AA, 0x9AD8, 0xB0AB, 0x9B25, 0xB0AC, 0x9B32, + 0xB0AD, 0x9B3C, 0xB0AE, 0x4E7E, 0xB0AF, 0x507A, 0xB0B0, 0x507D, + 0xB0B1, 0x505C, 0xB0B2, 0x5047, 0xB0B3, 0x5043, 0xB0B4, 0x504C, + 0xB0B5, 0x505A, 0xB0B6, 0x5049, 0xB0B7, 0x5065, 0xB0B8, 0x5076, + 0xB0B9, 0x504E, 0xB0BA, 0x5055, 0xB0BB, 0x5075, 0xB0BC, 0x5074, + 0xB0BD, 0x5077, 0xB0BE, 0x504F, 0xB0BF, 0x500F, 0xB0C0, 0x506F, + 0xB0C1, 0x506D, 0xB0C2, 0x515C, 0xB0C3, 0x5195, 0xB0C4, 0x51F0, + 0xB0C5, 0x526A, 0xB0C6, 0x526F, 0xB0C7, 0x52D2, 0xB0C8, 0x52D9, + 0xB0C9, 0x52D8, 0xB0CA, 0x52D5, 0xB0CB, 0x5310, 0xB0CC, 0x530F, + 0xB0CD, 0x5319, 0xB0CE, 0x533F, 0xB0CF, 0x5340, 0xB0D0, 0x533E, + 0xB0D1, 0x53C3, 0xB0D2, 0x66FC, 0xB0D3, 0x5546, 0xB0D4, 0x556A, + 0xB0D5, 0x5566, 0xB0D6, 0x5544, 0xB0D7, 0x555E, 0xB0D8, 0x5561, + 0xB0D9, 0x5543, 0xB0DA, 0x554A, 0xB0DB, 0x5531, 0xB0DC, 0x5556, + 0xB0DD, 0x554F, 0xB0DE, 0x5555, 0xB0DF, 0x552F, 0xB0E0, 0x5564, + 0xB0E1, 0x5538, 0xB0E2, 0x552E, 0xB0E3, 0x555C, 0xB0E4, 0x552C, + 0xB0E5, 0x5563, 0xB0E6, 0x5533, 0xB0E7, 0x5541, 0xB0E8, 0x5557, + 0xB0E9, 0x5708, 0xB0EA, 0x570B, 0xB0EB, 0x5709, 0xB0EC, 0x57DF, + 0xB0ED, 0x5805, 0xB0EE, 0x580A, 0xB0EF, 0x5806, 0xB0F0, 0x57E0, + 0xB0F1, 0x57E4, 0xB0F2, 0x57FA, 0xB0F3, 0x5802, 0xB0F4, 0x5835, + 0xB0F5, 0x57F7, 0xB0F6, 0x57F9, 0xB0F7, 0x5920, 0xB0F8, 0x5962, + 0xB0F9, 0x5A36, 0xB0FA, 0x5A41, 0xB0FB, 0x5A49, 0xB0FC, 0x5A66, + 0xB0FD, 0x5A6A, 0xB0FE, 0x5A40, 0xB140, 0x5A3C, 0xB141, 0x5A62, + 0xB142, 0x5A5A, 0xB143, 0x5A46, 0xB144, 0x5A4A, 0xB145, 0x5B70, + 0xB146, 0x5BC7, 0xB147, 0x5BC5, 0xB148, 0x5BC4, 0xB149, 0x5BC2, + 0xB14A, 0x5BBF, 0xB14B, 0x5BC6, 0xB14C, 0x5C09, 0xB14D, 0x5C08, + 0xB14E, 0x5C07, 0xB14F, 0x5C60, 0xB150, 0x5C5C, 0xB151, 0x5C5D, + 0xB152, 0x5D07, 0xB153, 0x5D06, 0xB154, 0x5D0E, 0xB155, 0x5D1B, + 0xB156, 0x5D16, 0xB157, 0x5D22, 0xB158, 0x5D11, 0xB159, 0x5D29, + 0xB15A, 0x5D14, 0xB15B, 0x5D19, 0xB15C, 0x5D24, 0xB15D, 0x5D27, + 0xB15E, 0x5D17, 0xB15F, 0x5DE2, 0xB160, 0x5E38, 0xB161, 0x5E36, + 0xB162, 0x5E33, 0xB163, 0x5E37, 0xB164, 0x5EB7, 0xB165, 0x5EB8, + 0xB166, 0x5EB6, 0xB167, 0x5EB5, 0xB168, 0x5EBE, 0xB169, 0x5F35, + 0xB16A, 0x5F37, 0xB16B, 0x5F57, 0xB16C, 0x5F6C, 0xB16D, 0x5F69, + 0xB16E, 0x5F6B, 0xB16F, 0x5F97, 0xB170, 0x5F99, 0xB171, 0x5F9E, + 0xB172, 0x5F98, 0xB173, 0x5FA1, 0xB174, 0x5FA0, 0xB175, 0x5F9C, + 0xB176, 0x607F, 0xB177, 0x60A3, 0xB178, 0x6089, 0xB179, 0x60A0, + 0xB17A, 0x60A8, 0xB17B, 0x60CB, 0xB17C, 0x60B4, 0xB17D, 0x60E6, + 0xB17E, 0x60BD, 0xB1A1, 0x60C5, 0xB1A2, 0x60BB, 0xB1A3, 0x60B5, + 0xB1A4, 0x60DC, 0xB1A5, 0x60BC, 0xB1A6, 0x60D8, 0xB1A7, 0x60D5, + 0xB1A8, 0x60C6, 0xB1A9, 0x60DF, 0xB1AA, 0x60B8, 0xB1AB, 0x60DA, + 0xB1AC, 0x60C7, 0xB1AD, 0x621A, 0xB1AE, 0x621B, 0xB1AF, 0x6248, + 0xB1B0, 0x63A0, 0xB1B1, 0x63A7, 0xB1B2, 0x6372, 0xB1B3, 0x6396, + 0xB1B4, 0x63A2, 0xB1B5, 0x63A5, 0xB1B6, 0x6377, 0xB1B7, 0x6367, + 0xB1B8, 0x6398, 0xB1B9, 0x63AA, 0xB1BA, 0x6371, 0xB1BB, 0x63A9, + 0xB1BC, 0x6389, 0xB1BD, 0x6383, 0xB1BE, 0x639B, 0xB1BF, 0x636B, + 0xB1C0, 0x63A8, 0xB1C1, 0x6384, 0xB1C2, 0x6388, 0xB1C3, 0x6399, + 0xB1C4, 0x63A1, 0xB1C5, 0x63AC, 0xB1C6, 0x6392, 0xB1C7, 0x638F, + 0xB1C8, 0x6380, 0xB1C9, 0x637B, 0xB1CA, 0x6369, 0xB1CB, 0x6368, + 0xB1CC, 0x637A, 0xB1CD, 0x655D, 0xB1CE, 0x6556, 0xB1CF, 0x6551, + 0xB1D0, 0x6559, 0xB1D1, 0x6557, 0xB1D2, 0x555F, 0xB1D3, 0x654F, + 0xB1D4, 0x6558, 0xB1D5, 0x6555, 0xB1D6, 0x6554, 0xB1D7, 0x659C, + 0xB1D8, 0x659B, 0xB1D9, 0x65AC, 0xB1DA, 0x65CF, 0xB1DB, 0x65CB, + 0xB1DC, 0x65CC, 0xB1DD, 0x65CE, 0xB1DE, 0x665D, 0xB1DF, 0x665A, + 0xB1E0, 0x6664, 0xB1E1, 0x6668, 0xB1E2, 0x6666, 0xB1E3, 0x665E, + 0xB1E4, 0x66F9, 0xB1E5, 0x52D7, 0xB1E6, 0x671B, 0xB1E7, 0x6881, + 0xB1E8, 0x68AF, 0xB1E9, 0x68A2, 0xB1EA, 0x6893, 0xB1EB, 0x68B5, + 0xB1EC, 0x687F, 0xB1ED, 0x6876, 0xB1EE, 0x68B1, 0xB1EF, 0x68A7, + 0xB1F0, 0x6897, 0xB1F1, 0x68B0, 0xB1F2, 0x6883, 0xB1F3, 0x68C4, + 0xB1F4, 0x68AD, 0xB1F5, 0x6886, 0xB1F6, 0x6885, 0xB1F7, 0x6894, + 0xB1F8, 0x689D, 0xB1F9, 0x68A8, 0xB1FA, 0x689F, 0xB1FB, 0x68A1, + 0xB1FC, 0x6882, 0xB1FD, 0x6B32, 0xB1FE, 0x6BBA, 0xB240, 0x6BEB, + 0xB241, 0x6BEC, 0xB242, 0x6C2B, 0xB243, 0x6D8E, 0xB244, 0x6DBC, + 0xB245, 0x6DF3, 0xB246, 0x6DD9, 0xB247, 0x6DB2, 0xB248, 0x6DE1, + 0xB249, 0x6DCC, 0xB24A, 0x6DE4, 0xB24B, 0x6DFB, 0xB24C, 0x6DFA, + 0xB24D, 0x6E05, 0xB24E, 0x6DC7, 0xB24F, 0x6DCB, 0xB250, 0x6DAF, + 0xB251, 0x6DD1, 0xB252, 0x6DAE, 0xB253, 0x6DDE, 0xB254, 0x6DF9, + 0xB255, 0x6DB8, 0xB256, 0x6DF7, 0xB257, 0x6DF5, 0xB258, 0x6DC5, + 0xB259, 0x6DD2, 0xB25A, 0x6E1A, 0xB25B, 0x6DB5, 0xB25C, 0x6DDA, + 0xB25D, 0x6DEB, 0xB25E, 0x6DD8, 0xB25F, 0x6DEA, 0xB260, 0x6DF1, + 0xB261, 0x6DEE, 0xB262, 0x6DE8, 0xB263, 0x6DC6, 0xB264, 0x6DC4, + 0xB265, 0x6DAA, 0xB266, 0x6DEC, 0xB267, 0x6DBF, 0xB268, 0x6DE6, + 0xB269, 0x70F9, 0xB26A, 0x7109, 0xB26B, 0x710A, 0xB26C, 0x70FD, + 0xB26D, 0x70EF, 0xB26E, 0x723D, 0xB26F, 0x727D, 0xB270, 0x7281, + 0xB271, 0x731C, 0xB272, 0x731B, 0xB273, 0x7316, 0xB274, 0x7313, + 0xB275, 0x7319, 0xB276, 0x7387, 0xB277, 0x7405, 0xB278, 0x740A, + 0xB279, 0x7403, 0xB27A, 0x7406, 0xB27B, 0x73FE, 0xB27C, 0x740D, + 0xB27D, 0x74E0, 0xB27E, 0x74F6, 0xB2A1, 0x74F7, 0xB2A2, 0x751C, + 0xB2A3, 0x7522, 0xB2A4, 0x7565, 0xB2A5, 0x7566, 0xB2A6, 0x7562, + 0xB2A7, 0x7570, 0xB2A8, 0x758F, 0xB2A9, 0x75D4, 0xB2AA, 0x75D5, + 0xB2AB, 0x75B5, 0xB2AC, 0x75CA, 0xB2AD, 0x75CD, 0xB2AE, 0x768E, + 0xB2AF, 0x76D4, 0xB2B0, 0x76D2, 0xB2B1, 0x76DB, 0xB2B2, 0x7737, + 0xB2B3, 0x773E, 0xB2B4, 0x773C, 0xB2B5, 0x7736, 0xB2B6, 0x7738, + 0xB2B7, 0x773A, 0xB2B8, 0x786B, 0xB2B9, 0x7843, 0xB2BA, 0x784E, + 0xB2BB, 0x7965, 0xB2BC, 0x7968, 0xB2BD, 0x796D, 0xB2BE, 0x79FB, + 0xB2BF, 0x7A92, 0xB2C0, 0x7A95, 0xB2C1, 0x7B20, 0xB2C2, 0x7B28, + 0xB2C3, 0x7B1B, 0xB2C4, 0x7B2C, 0xB2C5, 0x7B26, 0xB2C6, 0x7B19, + 0xB2C7, 0x7B1E, 0xB2C8, 0x7B2E, 0xB2C9, 0x7C92, 0xB2CA, 0x7C97, + 0xB2CB, 0x7C95, 0xB2CC, 0x7D46, 0xB2CD, 0x7D43, 0xB2CE, 0x7D71, + 0xB2CF, 0x7D2E, 0xB2D0, 0x7D39, 0xB2D1, 0x7D3C, 0xB2D2, 0x7D40, + 0xB2D3, 0x7D30, 0xB2D4, 0x7D33, 0xB2D5, 0x7D44, 0xB2D6, 0x7D2F, + 0xB2D7, 0x7D42, 0xB2D8, 0x7D32, 0xB2D9, 0x7D31, 0xB2DA, 0x7F3D, + 0xB2DB, 0x7F9E, 0xB2DC, 0x7F9A, 0xB2DD, 0x7FCC, 0xB2DE, 0x7FCE, + 0xB2DF, 0x7FD2, 0xB2E0, 0x801C, 0xB2E1, 0x804A, 0xB2E2, 0x8046, + 0xB2E3, 0x812F, 0xB2E4, 0x8116, 0xB2E5, 0x8123, 0xB2E6, 0x812B, + 0xB2E7, 0x8129, 0xB2E8, 0x8130, 0xB2E9, 0x8124, 0xB2EA, 0x8202, + 0xB2EB, 0x8235, 0xB2EC, 0x8237, 0xB2ED, 0x8236, 0xB2EE, 0x8239, + 0xB2EF, 0x838E, 0xB2F0, 0x839E, 0xB2F1, 0x8398, 0xB2F2, 0x8378, + 0xB2F3, 0x83A2, 0xB2F4, 0x8396, 0xB2F5, 0x83BD, 0xB2F6, 0x83AB, + 0xB2F7, 0x8392, 0xB2F8, 0x838A, 0xB2F9, 0x8393, 0xB2FA, 0x8389, + 0xB2FB, 0x83A0, 0xB2FC, 0x8377, 0xB2FD, 0x837B, 0xB2FE, 0x837C, + 0xB340, 0x8386, 0xB341, 0x83A7, 0xB342, 0x8655, 0xB343, 0x5F6A, + 0xB344, 0x86C7, 0xB345, 0x86C0, 0xB346, 0x86B6, 0xB347, 0x86C4, + 0xB348, 0x86B5, 0xB349, 0x86C6, 0xB34A, 0x86CB, 0xB34B, 0x86B1, + 0xB34C, 0x86AF, 0xB34D, 0x86C9, 0xB34E, 0x8853, 0xB34F, 0x889E, + 0xB350, 0x8888, 0xB351, 0x88AB, 0xB352, 0x8892, 0xB353, 0x8896, + 0xB354, 0x888D, 0xB355, 0x888B, 0xB356, 0x8993, 0xB357, 0x898F, + 0xB358, 0x8A2A, 0xB359, 0x8A1D, 0xB35A, 0x8A23, 0xB35B, 0x8A25, + 0xB35C, 0x8A31, 0xB35D, 0x8A2D, 0xB35E, 0x8A1F, 0xB35F, 0x8A1B, + 0xB360, 0x8A22, 0xB361, 0x8C49, 0xB362, 0x8C5A, 0xB363, 0x8CA9, + 0xB364, 0x8CAC, 0xB365, 0x8CAB, 0xB366, 0x8CA8, 0xB367, 0x8CAA, + 0xB368, 0x8CA7, 0xB369, 0x8D67, 0xB36A, 0x8D66, 0xB36B, 0x8DBE, + 0xB36C, 0x8DBA, 0xB36D, 0x8EDB, 0xB36E, 0x8EDF, 0xB36F, 0x9019, + 0xB370, 0x900D, 0xB371, 0x901A, 0xB372, 0x9017, 0xB373, 0x9023, + 0xB374, 0x901F, 0xB375, 0x901D, 0xB376, 0x9010, 0xB377, 0x9015, + 0xB378, 0x901E, 0xB379, 0x9020, 0xB37A, 0x900F, 0xB37B, 0x9022, + 0xB37C, 0x9016, 0xB37D, 0x901B, 0xB37E, 0x9014, 0xB3A1, 0x90E8, + 0xB3A2, 0x90ED, 0xB3A3, 0x90FD, 0xB3A4, 0x9157, 0xB3A5, 0x91CE, + 0xB3A6, 0x91F5, 0xB3A7, 0x91E6, 0xB3A8, 0x91E3, 0xB3A9, 0x91E7, + 0xB3AA, 0x91ED, 0xB3AB, 0x91E9, 0xB3AC, 0x9589, 0xB3AD, 0x966A, + 0xB3AE, 0x9675, 0xB3AF, 0x9673, 0xB3B0, 0x9678, 0xB3B1, 0x9670, + 0xB3B2, 0x9674, 0xB3B3, 0x9676, 0xB3B4, 0x9677, 0xB3B5, 0x966C, + 0xB3B6, 0x96C0, 0xB3B7, 0x96EA, 0xB3B8, 0x96E9, 0xB3B9, 0x7AE0, + 0xB3BA, 0x7ADF, 0xB3BB, 0x9802, 0xB3BC, 0x9803, 0xB3BD, 0x9B5A, + 0xB3BE, 0x9CE5, 0xB3BF, 0x9E75, 0xB3C0, 0x9E7F, 0xB3C1, 0x9EA5, + 0xB3C2, 0x9EBB, 0xB3C3, 0x50A2, 0xB3C4, 0x508D, 0xB3C5, 0x5085, + 0xB3C6, 0x5099, 0xB3C7, 0x5091, 0xB3C8, 0x5080, 0xB3C9, 0x5096, + 0xB3CA, 0x5098, 0xB3CB, 0x509A, 0xB3CC, 0x6700, 0xB3CD, 0x51F1, + 0xB3CE, 0x5272, 0xB3CF, 0x5274, 0xB3D0, 0x5275, 0xB3D1, 0x5269, + 0xB3D2, 0x52DE, 0xB3D3, 0x52DD, 0xB3D4, 0x52DB, 0xB3D5, 0x535A, + 0xB3D6, 0x53A5, 0xB3D7, 0x557B, 0xB3D8, 0x5580, 0xB3D9, 0x55A7, + 0xB3DA, 0x557C, 0xB3DB, 0x558A, 0xB3DC, 0x559D, 0xB3DD, 0x5598, + 0xB3DE, 0x5582, 0xB3DF, 0x559C, 0xB3E0, 0x55AA, 0xB3E1, 0x5594, + 0xB3E2, 0x5587, 0xB3E3, 0x558B, 0xB3E4, 0x5583, 0xB3E5, 0x55B3, + 0xB3E6, 0x55AE, 0xB3E7, 0x559F, 0xB3E8, 0x553E, 0xB3E9, 0x55B2, + 0xB3EA, 0x559A, 0xB3EB, 0x55BB, 0xB3EC, 0x55AC, 0xB3ED, 0x55B1, + 0xB3EE, 0x557E, 0xB3EF, 0x5589, 0xB3F0, 0x55AB, 0xB3F1, 0x5599, + 0xB3F2, 0x570D, 0xB3F3, 0x582F, 0xB3F4, 0x582A, 0xB3F5, 0x5834, + 0xB3F6, 0x5824, 0xB3F7, 0x5830, 0xB3F8, 0x5831, 0xB3F9, 0x5821, + 0xB3FA, 0x581D, 0xB3FB, 0x5820, 0xB3FC, 0x58F9, 0xB3FD, 0x58FA, + 0xB3FE, 0x5960, 0xB440, 0x5A77, 0xB441, 0x5A9A, 0xB442, 0x5A7F, + 0xB443, 0x5A92, 0xB444, 0x5A9B, 0xB445, 0x5AA7, 0xB446, 0x5B73, + 0xB447, 0x5B71, 0xB448, 0x5BD2, 0xB449, 0x5BCC, 0xB44A, 0x5BD3, + 0xB44B, 0x5BD0, 0xB44C, 0x5C0A, 0xB44D, 0x5C0B, 0xB44E, 0x5C31, + 0xB44F, 0x5D4C, 0xB450, 0x5D50, 0xB451, 0x5D34, 0xB452, 0x5D47, + 0xB453, 0x5DFD, 0xB454, 0x5E45, 0xB455, 0x5E3D, 0xB456, 0x5E40, + 0xB457, 0x5E43, 0xB458, 0x5E7E, 0xB459, 0x5ECA, 0xB45A, 0x5EC1, + 0xB45B, 0x5EC2, 0xB45C, 0x5EC4, 0xB45D, 0x5F3C, 0xB45E, 0x5F6D, + 0xB45F, 0x5FA9, 0xB460, 0x5FAA, 0xB461, 0x5FA8, 0xB462, 0x60D1, + 0xB463, 0x60E1, 0xB464, 0x60B2, 0xB465, 0x60B6, 0xB466, 0x60E0, + 0xB467, 0x611C, 0xB468, 0x6123, 0xB469, 0x60FA, 0xB46A, 0x6115, + 0xB46B, 0x60F0, 0xB46C, 0x60FB, 0xB46D, 0x60F4, 0xB46E, 0x6168, + 0xB46F, 0x60F1, 0xB470, 0x610E, 0xB471, 0x60F6, 0xB472, 0x6109, + 0xB473, 0x6100, 0xB474, 0x6112, 0xB475, 0x621F, 0xB476, 0x6249, + 0xB477, 0x63A3, 0xB478, 0x638C, 0xB479, 0x63CF, 0xB47A, 0x63C0, + 0xB47B, 0x63E9, 0xB47C, 0x63C9, 0xB47D, 0x63C6, 0xB47E, 0x63CD, + 0xB4A1, 0x63D2, 0xB4A2, 0x63E3, 0xB4A3, 0x63D0, 0xB4A4, 0x63E1, + 0xB4A5, 0x63D6, 0xB4A6, 0x63ED, 0xB4A7, 0x63EE, 0xB4A8, 0x6376, + 0xB4A9, 0x63F4, 0xB4AA, 0x63EA, 0xB4AB, 0x63DB, 0xB4AC, 0x6452, + 0xB4AD, 0x63DA, 0xB4AE, 0x63F9, 0xB4AF, 0x655E, 0xB4B0, 0x6566, + 0xB4B1, 0x6562, 0xB4B2, 0x6563, 0xB4B3, 0x6591, 0xB4B4, 0x6590, + 0xB4B5, 0x65AF, 0xB4B6, 0x666E, 0xB4B7, 0x6670, 0xB4B8, 0x6674, + 0xB4B9, 0x6676, 0xB4BA, 0x666F, 0xB4BB, 0x6691, 0xB4BC, 0x667A, + 0xB4BD, 0x667E, 0xB4BE, 0x6677, 0xB4BF, 0x66FE, 0xB4C0, 0x66FF, + 0xB4C1, 0x671F, 0xB4C2, 0x671D, 0xB4C3, 0x68FA, 0xB4C4, 0x68D5, + 0xB4C5, 0x68E0, 0xB4C6, 0x68D8, 0xB4C7, 0x68D7, 0xB4C8, 0x6905, + 0xB4C9, 0x68DF, 0xB4CA, 0x68F5, 0xB4CB, 0x68EE, 0xB4CC, 0x68E7, + 0xB4CD, 0x68F9, 0xB4CE, 0x68D2, 0xB4CF, 0x68F2, 0xB4D0, 0x68E3, + 0xB4D1, 0x68CB, 0xB4D2, 0x68CD, 0xB4D3, 0x690D, 0xB4D4, 0x6912, + 0xB4D5, 0x690E, 0xB4D6, 0x68C9, 0xB4D7, 0x68DA, 0xB4D8, 0x696E, + 0xB4D9, 0x68FB, 0xB4DA, 0x6B3E, 0xB4DB, 0x6B3A, 0xB4DC, 0x6B3D, + 0xB4DD, 0x6B98, 0xB4DE, 0x6B96, 0xB4DF, 0x6BBC, 0xB4E0, 0x6BEF, + 0xB4E1, 0x6C2E, 0xB4E2, 0x6C2F, 0xB4E3, 0x6C2C, 0xB4E4, 0x6E2F, + 0xB4E5, 0x6E38, 0xB4E6, 0x6E54, 0xB4E7, 0x6E21, 0xB4E8, 0x6E32, + 0xB4E9, 0x6E67, 0xB4EA, 0x6E4A, 0xB4EB, 0x6E20, 0xB4EC, 0x6E25, + 0xB4ED, 0x6E23, 0xB4EE, 0x6E1B, 0xB4EF, 0x6E5B, 0xB4F0, 0x6E58, + 0xB4F1, 0x6E24, 0xB4F2, 0x6E56, 0xB4F3, 0x6E6E, 0xB4F4, 0x6E2D, + 0xB4F5, 0x6E26, 0xB4F6, 0x6E6F, 0xB4F7, 0x6E34, 0xB4F8, 0x6E4D, + 0xB4F9, 0x6E3A, 0xB4FA, 0x6E2C, 0xB4FB, 0x6E43, 0xB4FC, 0x6E1D, + 0xB4FD, 0x6E3E, 0xB4FE, 0x6ECB, 0xB540, 0x6E89, 0xB541, 0x6E19, + 0xB542, 0x6E4E, 0xB543, 0x6E63, 0xB544, 0x6E44, 0xB545, 0x6E72, + 0xB546, 0x6E69, 0xB547, 0x6E5F, 0xB548, 0x7119, 0xB549, 0x711A, + 0xB54A, 0x7126, 0xB54B, 0x7130, 0xB54C, 0x7121, 0xB54D, 0x7136, + 0xB54E, 0x716E, 0xB54F, 0x711C, 0xB550, 0x724C, 0xB551, 0x7284, + 0xB552, 0x7280, 0xB553, 0x7336, 0xB554, 0x7325, 0xB555, 0x7334, + 0xB556, 0x7329, 0xB557, 0x743A, 0xB558, 0x742A, 0xB559, 0x7433, + 0xB55A, 0x7422, 0xB55B, 0x7425, 0xB55C, 0x7435, 0xB55D, 0x7436, + 0xB55E, 0x7434, 0xB55F, 0x742F, 0xB560, 0x741B, 0xB561, 0x7426, + 0xB562, 0x7428, 0xB563, 0x7525, 0xB564, 0x7526, 0xB565, 0x756B, + 0xB566, 0x756A, 0xB567, 0x75E2, 0xB568, 0x75DB, 0xB569, 0x75E3, + 0xB56A, 0x75D9, 0xB56B, 0x75D8, 0xB56C, 0x75DE, 0xB56D, 0x75E0, + 0xB56E, 0x767B, 0xB56F, 0x767C, 0xB570, 0x7696, 0xB571, 0x7693, + 0xB572, 0x76B4, 0xB573, 0x76DC, 0xB574, 0x774F, 0xB575, 0x77ED, + 0xB576, 0x785D, 0xB577, 0x786C, 0xB578, 0x786F, 0xB579, 0x7A0D, + 0xB57A, 0x7A08, 0xB57B, 0x7A0B, 0xB57C, 0x7A05, 0xB57D, 0x7A00, + 0xB57E, 0x7A98, 0xB5A1, 0x7A97, 0xB5A2, 0x7A96, 0xB5A3, 0x7AE5, + 0xB5A4, 0x7AE3, 0xB5A5, 0x7B49, 0xB5A6, 0x7B56, 0xB5A7, 0x7B46, + 0xB5A8, 0x7B50, 0xB5A9, 0x7B52, 0xB5AA, 0x7B54, 0xB5AB, 0x7B4D, + 0xB5AC, 0x7B4B, 0xB5AD, 0x7B4F, 0xB5AE, 0x7B51, 0xB5AF, 0x7C9F, + 0xB5B0, 0x7CA5, 0xB5B1, 0x7D5E, 0xB5B2, 0x7D50, 0xB5B3, 0x7D68, + 0xB5B4, 0x7D55, 0xB5B5, 0x7D2B, 0xB5B6, 0x7D6E, 0xB5B7, 0x7D72, + 0xB5B8, 0x7D61, 0xB5B9, 0x7D66, 0xB5BA, 0x7D62, 0xB5BB, 0x7D70, + 0xB5BC, 0x7D73, 0xB5BD, 0x5584, 0xB5BE, 0x7FD4, 0xB5BF, 0x7FD5, + 0xB5C0, 0x800B, 0xB5C1, 0x8052, 0xB5C2, 0x8085, 0xB5C3, 0x8155, + 0xB5C4, 0x8154, 0xB5C5, 0x814B, 0xB5C6, 0x8151, 0xB5C7, 0x814E, + 0xB5C8, 0x8139, 0xB5C9, 0x8146, 0xB5CA, 0x813E, 0xB5CB, 0x814C, + 0xB5CC, 0x8153, 0xB5CD, 0x8174, 0xB5CE, 0x8212, 0xB5CF, 0x821C, + 0xB5D0, 0x83E9, 0xB5D1, 0x8403, 0xB5D2, 0x83F8, 0xB5D3, 0x840D, + 0xB5D4, 0x83E0, 0xB5D5, 0x83C5, 0xB5D6, 0x840B, 0xB5D7, 0x83C1, + 0xB5D8, 0x83EF, 0xB5D9, 0x83F1, 0xB5DA, 0x83F4, 0xB5DB, 0x8457, + 0xB5DC, 0x840A, 0xB5DD, 0x83F0, 0xB5DE, 0x840C, 0xB5DF, 0x83CC, + 0xB5E0, 0x83FD, 0xB5E1, 0x83F2, 0xB5E2, 0x83CA, 0xB5E3, 0x8438, + 0xB5E4, 0x840E, 0xB5E5, 0x8404, 0xB5E6, 0x83DC, 0xB5E7, 0x8407, + 0xB5E8, 0x83D4, 0xB5E9, 0x83DF, 0xB5EA, 0x865B, 0xB5EB, 0x86DF, + 0xB5EC, 0x86D9, 0xB5ED, 0x86ED, 0xB5EE, 0x86D4, 0xB5EF, 0x86DB, + 0xB5F0, 0x86E4, 0xB5F1, 0x86D0, 0xB5F2, 0x86DE, 0xB5F3, 0x8857, + 0xB5F4, 0x88C1, 0xB5F5, 0x88C2, 0xB5F6, 0x88B1, 0xB5F7, 0x8983, + 0xB5F8, 0x8996, 0xB5F9, 0x8A3B, 0xB5FA, 0x8A60, 0xB5FB, 0x8A55, + 0xB5FC, 0x8A5E, 0xB5FD, 0x8A3C, 0xB5FE, 0x8A41, 0xB640, 0x8A54, + 0xB641, 0x8A5B, 0xB642, 0x8A50, 0xB643, 0x8A46, 0xB644, 0x8A34, + 0xB645, 0x8A3A, 0xB646, 0x8A36, 0xB647, 0x8A56, 0xB648, 0x8C61, + 0xB649, 0x8C82, 0xB64A, 0x8CAF, 0xB64B, 0x8CBC, 0xB64C, 0x8CB3, + 0xB64D, 0x8CBD, 0xB64E, 0x8CC1, 0xB64F, 0x8CBB, 0xB650, 0x8CC0, + 0xB651, 0x8CB4, 0xB652, 0x8CB7, 0xB653, 0x8CB6, 0xB654, 0x8CBF, + 0xB655, 0x8CB8, 0xB656, 0x8D8A, 0xB657, 0x8D85, 0xB658, 0x8D81, + 0xB659, 0x8DCE, 0xB65A, 0x8DDD, 0xB65B, 0x8DCB, 0xB65C, 0x8DDA, + 0xB65D, 0x8DD1, 0xB65E, 0x8DCC, 0xB65F, 0x8DDB, 0xB660, 0x8DC6, + 0xB661, 0x8EFB, 0xB662, 0x8EF8, 0xB663, 0x8EFC, 0xB664, 0x8F9C, + 0xB665, 0x902E, 0xB666, 0x9035, 0xB667, 0x9031, 0xB668, 0x9038, + 0xB669, 0x9032, 0xB66A, 0x9036, 0xB66B, 0x9102, 0xB66C, 0x90F5, + 0xB66D, 0x9109, 0xB66E, 0x90FE, 0xB66F, 0x9163, 0xB670, 0x9165, + 0xB671, 0x91CF, 0xB672, 0x9214, 0xB673, 0x9215, 0xB674, 0x9223, + 0xB675, 0x9209, 0xB676, 0x921E, 0xB677, 0x920D, 0xB678, 0x9210, + 0xB679, 0x9207, 0xB67A, 0x9211, 0xB67B, 0x9594, 0xB67C, 0x958F, + 0xB67D, 0x958B, 0xB67E, 0x9591, 0xB6A1, 0x9593, 0xB6A2, 0x9592, + 0xB6A3, 0x958E, 0xB6A4, 0x968A, 0xB6A5, 0x968E, 0xB6A6, 0x968B, + 0xB6A7, 0x967D, 0xB6A8, 0x9685, 0xB6A9, 0x9686, 0xB6AA, 0x968D, + 0xB6AB, 0x9672, 0xB6AC, 0x9684, 0xB6AD, 0x96C1, 0xB6AE, 0x96C5, + 0xB6AF, 0x96C4, 0xB6B0, 0x96C6, 0xB6B1, 0x96C7, 0xB6B2, 0x96EF, + 0xB6B3, 0x96F2, 0xB6B4, 0x97CC, 0xB6B5, 0x9805, 0xB6B6, 0x9806, + 0xB6B7, 0x9808, 0xB6B8, 0x98E7, 0xB6B9, 0x98EA, 0xB6BA, 0x98EF, + 0xB6BB, 0x98E9, 0xB6BC, 0x98F2, 0xB6BD, 0x98ED, 0xB6BE, 0x99AE, + 0xB6BF, 0x99AD, 0xB6C0, 0x9EC3, 0xB6C1, 0x9ECD, 0xB6C2, 0x9ED1, + 0xB6C3, 0x4E82, 0xB6C4, 0x50AD, 0xB6C5, 0x50B5, 0xB6C6, 0x50B2, + 0xB6C7, 0x50B3, 0xB6C8, 0x50C5, 0xB6C9, 0x50BE, 0xB6CA, 0x50AC, + 0xB6CB, 0x50B7, 0xB6CC, 0x50BB, 0xB6CD, 0x50AF, 0xB6CE, 0x50C7, + 0xB6CF, 0x527F, 0xB6D0, 0x5277, 0xB6D1, 0x527D, 0xB6D2, 0x52DF, + 0xB6D3, 0x52E6, 0xB6D4, 0x52E4, 0xB6D5, 0x52E2, 0xB6D6, 0x52E3, + 0xB6D7, 0x532F, 0xB6D8, 0x55DF, 0xB6D9, 0x55E8, 0xB6DA, 0x55D3, + 0xB6DB, 0x55E6, 0xB6DC, 0x55CE, 0xB6DD, 0x55DC, 0xB6DE, 0x55C7, + 0xB6DF, 0x55D1, 0xB6E0, 0x55E3, 0xB6E1, 0x55E4, 0xB6E2, 0x55EF, + 0xB6E3, 0x55DA, 0xB6E4, 0x55E1, 0xB6E5, 0x55C5, 0xB6E6, 0x55C6, + 0xB6E7, 0x55E5, 0xB6E8, 0x55C9, 0xB6E9, 0x5712, 0xB6EA, 0x5713, + 0xB6EB, 0x585E, 0xB6EC, 0x5851, 0xB6ED, 0x5858, 0xB6EE, 0x5857, + 0xB6EF, 0x585A, 0xB6F0, 0x5854, 0xB6F1, 0x586B, 0xB6F2, 0x584C, + 0xB6F3, 0x586D, 0xB6F4, 0x584A, 0xB6F5, 0x5862, 0xB6F6, 0x5852, + 0xB6F7, 0x584B, 0xB6F8, 0x5967, 0xB6F9, 0x5AC1, 0xB6FA, 0x5AC9, + 0xB6FB, 0x5ACC, 0xB6FC, 0x5ABE, 0xB6FD, 0x5ABD, 0xB6FE, 0x5ABC, + 0xB740, 0x5AB3, 0xB741, 0x5AC2, 0xB742, 0x5AB2, 0xB743, 0x5D69, + 0xB744, 0x5D6F, 0xB745, 0x5E4C, 0xB746, 0x5E79, 0xB747, 0x5EC9, + 0xB748, 0x5EC8, 0xB749, 0x5F12, 0xB74A, 0x5F59, 0xB74B, 0x5FAC, + 0xB74C, 0x5FAE, 0xB74D, 0x611A, 0xB74E, 0x610F, 0xB74F, 0x6148, + 0xB750, 0x611F, 0xB751, 0x60F3, 0xB752, 0x611B, 0xB753, 0x60F9, + 0xB754, 0x6101, 0xB755, 0x6108, 0xB756, 0x614E, 0xB757, 0x614C, + 0xB758, 0x6144, 0xB759, 0x614D, 0xB75A, 0x613E, 0xB75B, 0x6134, + 0xB75C, 0x6127, 0xB75D, 0x610D, 0xB75E, 0x6106, 0xB75F, 0x6137, + 0xB760, 0x6221, 0xB761, 0x6222, 0xB762, 0x6413, 0xB763, 0x643E, + 0xB764, 0x641E, 0xB765, 0x642A, 0xB766, 0x642D, 0xB767, 0x643D, + 0xB768, 0x642C, 0xB769, 0x640F, 0xB76A, 0x641C, 0xB76B, 0x6414, + 0xB76C, 0x640D, 0xB76D, 0x6436, 0xB76E, 0x6416, 0xB76F, 0x6417, + 0xB770, 0x6406, 0xB771, 0x656C, 0xB772, 0x659F, 0xB773, 0x65B0, + 0xB774, 0x6697, 0xB775, 0x6689, 0xB776, 0x6687, 0xB777, 0x6688, + 0xB778, 0x6696, 0xB779, 0x6684, 0xB77A, 0x6698, 0xB77B, 0x668D, + 0xB77C, 0x6703, 0xB77D, 0x6994, 0xB77E, 0x696D, 0xB7A1, 0x695A, + 0xB7A2, 0x6977, 0xB7A3, 0x6960, 0xB7A4, 0x6954, 0xB7A5, 0x6975, + 0xB7A6, 0x6930, 0xB7A7, 0x6982, 0xB7A8, 0x694A, 0xB7A9, 0x6968, + 0xB7AA, 0x696B, 0xB7AB, 0x695E, 0xB7AC, 0x6953, 0xB7AD, 0x6979, + 0xB7AE, 0x6986, 0xB7AF, 0x695D, 0xB7B0, 0x6963, 0xB7B1, 0x695B, + 0xB7B2, 0x6B47, 0xB7B3, 0x6B72, 0xB7B4, 0x6BC0, 0xB7B5, 0x6BBF, + 0xB7B6, 0x6BD3, 0xB7B7, 0x6BFD, 0xB7B8, 0x6EA2, 0xB7B9, 0x6EAF, + 0xB7BA, 0x6ED3, 0xB7BB, 0x6EB6, 0xB7BC, 0x6EC2, 0xB7BD, 0x6E90, + 0xB7BE, 0x6E9D, 0xB7BF, 0x6EC7, 0xB7C0, 0x6EC5, 0xB7C1, 0x6EA5, + 0xB7C2, 0x6E98, 0xB7C3, 0x6EBC, 0xB7C4, 0x6EBA, 0xB7C5, 0x6EAB, + 0xB7C6, 0x6ED1, 0xB7C7, 0x6E96, 0xB7C8, 0x6E9C, 0xB7C9, 0x6EC4, + 0xB7CA, 0x6ED4, 0xB7CB, 0x6EAA, 0xB7CC, 0x6EA7, 0xB7CD, 0x6EB4, + 0xB7CE, 0x714E, 0xB7CF, 0x7159, 0xB7D0, 0x7169, 0xB7D1, 0x7164, + 0xB7D2, 0x7149, 0xB7D3, 0x7167, 0xB7D4, 0x715C, 0xB7D5, 0x716C, + 0xB7D6, 0x7166, 0xB7D7, 0x714C, 0xB7D8, 0x7165, 0xB7D9, 0x715E, + 0xB7DA, 0x7146, 0xB7DB, 0x7168, 0xB7DC, 0x7156, 0xB7DD, 0x723A, + 0xB7DE, 0x7252, 0xB7DF, 0x7337, 0xB7E0, 0x7345, 0xB7E1, 0x733F, + 0xB7E2, 0x733E, 0xB7E3, 0x746F, 0xB7E4, 0x745A, 0xB7E5, 0x7455, + 0xB7E6, 0x745F, 0xB7E7, 0x745E, 0xB7E8, 0x7441, 0xB7E9, 0x743F, + 0xB7EA, 0x7459, 0xB7EB, 0x745B, 0xB7EC, 0x745C, 0xB7ED, 0x7576, + 0xB7EE, 0x7578, 0xB7EF, 0x7600, 0xB7F0, 0x75F0, 0xB7F1, 0x7601, + 0xB7F2, 0x75F2, 0xB7F3, 0x75F1, 0xB7F4, 0x75FA, 0xB7F5, 0x75FF, + 0xB7F6, 0x75F4, 0xB7F7, 0x75F3, 0xB7F8, 0x76DE, 0xB7F9, 0x76DF, + 0xB7FA, 0x775B, 0xB7FB, 0x776B, 0xB7FC, 0x7766, 0xB7FD, 0x775E, + 0xB7FE, 0x7763, 0xB840, 0x7779, 0xB841, 0x776A, 0xB842, 0x776C, + 0xB843, 0x775C, 0xB844, 0x7765, 0xB845, 0x7768, 0xB846, 0x7762, + 0xB847, 0x77EE, 0xB848, 0x788E, 0xB849, 0x78B0, 0xB84A, 0x7897, + 0xB84B, 0x7898, 0xB84C, 0x788C, 0xB84D, 0x7889, 0xB84E, 0x787C, + 0xB84F, 0x7891, 0xB850, 0x7893, 0xB851, 0x787F, 0xB852, 0x797A, + 0xB853, 0x797F, 0xB854, 0x7981, 0xB855, 0x842C, 0xB856, 0x79BD, + 0xB857, 0x7A1C, 0xB858, 0x7A1A, 0xB859, 0x7A20, 0xB85A, 0x7A14, + 0xB85B, 0x7A1F, 0xB85C, 0x7A1E, 0xB85D, 0x7A9F, 0xB85E, 0x7AA0, + 0xB85F, 0x7B77, 0xB860, 0x7BC0, 0xB861, 0x7B60, 0xB862, 0x7B6E, + 0xB863, 0x7B67, 0xB864, 0x7CB1, 0xB865, 0x7CB3, 0xB866, 0x7CB5, + 0xB867, 0x7D93, 0xB868, 0x7D79, 0xB869, 0x7D91, 0xB86A, 0x7D81, + 0xB86B, 0x7D8F, 0xB86C, 0x7D5B, 0xB86D, 0x7F6E, 0xB86E, 0x7F69, + 0xB86F, 0x7F6A, 0xB870, 0x7F72, 0xB871, 0x7FA9, 0xB872, 0x7FA8, + 0xB873, 0x7FA4, 0xB874, 0x8056, 0xB875, 0x8058, 0xB876, 0x8086, + 0xB877, 0x8084, 0xB878, 0x8171, 0xB879, 0x8170, 0xB87A, 0x8178, + 0xB87B, 0x8165, 0xB87C, 0x816E, 0xB87D, 0x8173, 0xB87E, 0x816B, + 0xB8A1, 0x8179, 0xB8A2, 0x817A, 0xB8A3, 0x8166, 0xB8A4, 0x8205, + 0xB8A5, 0x8247, 0xB8A6, 0x8482, 0xB8A7, 0x8477, 0xB8A8, 0x843D, + 0xB8A9, 0x8431, 0xB8AA, 0x8475, 0xB8AB, 0x8466, 0xB8AC, 0x846B, + 0xB8AD, 0x8449, 0xB8AE, 0x846C, 0xB8AF, 0x845B, 0xB8B0, 0x843C, + 0xB8B1, 0x8435, 0xB8B2, 0x8461, 0xB8B3, 0x8463, 0xB8B4, 0x8469, + 0xB8B5, 0x846D, 0xB8B6, 0x8446, 0xB8B7, 0x865E, 0xB8B8, 0x865C, + 0xB8B9, 0x865F, 0xB8BA, 0x86F9, 0xB8BB, 0x8713, 0xB8BC, 0x8708, + 0xB8BD, 0x8707, 0xB8BE, 0x8700, 0xB8BF, 0x86FE, 0xB8C0, 0x86FB, + 0xB8C1, 0x8702, 0xB8C2, 0x8703, 0xB8C3, 0x8706, 0xB8C4, 0x870A, + 0xB8C5, 0x8859, 0xB8C6, 0x88DF, 0xB8C7, 0x88D4, 0xB8C8, 0x88D9, + 0xB8C9, 0x88DC, 0xB8CA, 0x88D8, 0xB8CB, 0x88DD, 0xB8CC, 0x88E1, + 0xB8CD, 0x88CA, 0xB8CE, 0x88D5, 0xB8CF, 0x88D2, 0xB8D0, 0x899C, + 0xB8D1, 0x89E3, 0xB8D2, 0x8A6B, 0xB8D3, 0x8A72, 0xB8D4, 0x8A73, + 0xB8D5, 0x8A66, 0xB8D6, 0x8A69, 0xB8D7, 0x8A70, 0xB8D8, 0x8A87, + 0xB8D9, 0x8A7C, 0xB8DA, 0x8A63, 0xB8DB, 0x8AA0, 0xB8DC, 0x8A71, + 0xB8DD, 0x8A85, 0xB8DE, 0x8A6D, 0xB8DF, 0x8A62, 0xB8E0, 0x8A6E, + 0xB8E1, 0x8A6C, 0xB8E2, 0x8A79, 0xB8E3, 0x8A7B, 0xB8E4, 0x8A3E, + 0xB8E5, 0x8A68, 0xB8E6, 0x8C62, 0xB8E7, 0x8C8A, 0xB8E8, 0x8C89, + 0xB8E9, 0x8CCA, 0xB8EA, 0x8CC7, 0xB8EB, 0x8CC8, 0xB8EC, 0x8CC4, + 0xB8ED, 0x8CB2, 0xB8EE, 0x8CC3, 0xB8EF, 0x8CC2, 0xB8F0, 0x8CC5, + 0xB8F1, 0x8DE1, 0xB8F2, 0x8DDF, 0xB8F3, 0x8DE8, 0xB8F4, 0x8DEF, + 0xB8F5, 0x8DF3, 0xB8F6, 0x8DFA, 0xB8F7, 0x8DEA, 0xB8F8, 0x8DE4, + 0xB8F9, 0x8DE6, 0xB8FA, 0x8EB2, 0xB8FB, 0x8F03, 0xB8FC, 0x8F09, + 0xB8FD, 0x8EFE, 0xB8FE, 0x8F0A, 0xB940, 0x8F9F, 0xB941, 0x8FB2, + 0xB942, 0x904B, 0xB943, 0x904A, 0xB944, 0x9053, 0xB945, 0x9042, + 0xB946, 0x9054, 0xB947, 0x903C, 0xB948, 0x9055, 0xB949, 0x9050, + 0xB94A, 0x9047, 0xB94B, 0x904F, 0xB94C, 0x904E, 0xB94D, 0x904D, + 0xB94E, 0x9051, 0xB94F, 0x903E, 0xB950, 0x9041, 0xB951, 0x9112, + 0xB952, 0x9117, 0xB953, 0x916C, 0xB954, 0x916A, 0xB955, 0x9169, + 0xB956, 0x91C9, 0xB957, 0x9237, 0xB958, 0x9257, 0xB959, 0x9238, + 0xB95A, 0x923D, 0xB95B, 0x9240, 0xB95C, 0x923E, 0xB95D, 0x925B, + 0xB95E, 0x924B, 0xB95F, 0x9264, 0xB960, 0x9251, 0xB961, 0x9234, + 0xB962, 0x9249, 0xB963, 0x924D, 0xB964, 0x9245, 0xB965, 0x9239, + 0xB966, 0x923F, 0xB967, 0x925A, 0xB968, 0x9598, 0xB969, 0x9698, + 0xB96A, 0x9694, 0xB96B, 0x9695, 0xB96C, 0x96CD, 0xB96D, 0x96CB, + 0xB96E, 0x96C9, 0xB96F, 0x96CA, 0xB970, 0x96F7, 0xB971, 0x96FB, + 0xB972, 0x96F9, 0xB973, 0x96F6, 0xB974, 0x9756, 0xB975, 0x9774, + 0xB976, 0x9776, 0xB977, 0x9810, 0xB978, 0x9811, 0xB979, 0x9813, + 0xB97A, 0x980A, 0xB97B, 0x9812, 0xB97C, 0x980C, 0xB97D, 0x98FC, + 0xB97E, 0x98F4, 0xB9A1, 0x98FD, 0xB9A2, 0x98FE, 0xB9A3, 0x99B3, + 0xB9A4, 0x99B1, 0xB9A5, 0x99B4, 0xB9A6, 0x9AE1, 0xB9A7, 0x9CE9, + 0xB9A8, 0x9E82, 0xB9A9, 0x9F0E, 0xB9AA, 0x9F13, 0xB9AB, 0x9F20, + 0xB9AC, 0x50E7, 0xB9AD, 0x50EE, 0xB9AE, 0x50E5, 0xB9AF, 0x50D6, + 0xB9B0, 0x50ED, 0xB9B1, 0x50DA, 0xB9B2, 0x50D5, 0xB9B3, 0x50CF, + 0xB9B4, 0x50D1, 0xB9B5, 0x50F1, 0xB9B6, 0x50CE, 0xB9B7, 0x50E9, + 0xB9B8, 0x5162, 0xB9B9, 0x51F3, 0xB9BA, 0x5283, 0xB9BB, 0x5282, + 0xB9BC, 0x5331, 0xB9BD, 0x53AD, 0xB9BE, 0x55FE, 0xB9BF, 0x5600, + 0xB9C0, 0x561B, 0xB9C1, 0x5617, 0xB9C2, 0x55FD, 0xB9C3, 0x5614, + 0xB9C4, 0x5606, 0xB9C5, 0x5609, 0xB9C6, 0x560D, 0xB9C7, 0x560E, + 0xB9C8, 0x55F7, 0xB9C9, 0x5616, 0xB9CA, 0x561F, 0xB9CB, 0x5608, + 0xB9CC, 0x5610, 0xB9CD, 0x55F6, 0xB9CE, 0x5718, 0xB9CF, 0x5716, + 0xB9D0, 0x5875, 0xB9D1, 0x587E, 0xB9D2, 0x5883, 0xB9D3, 0x5893, + 0xB9D4, 0x588A, 0xB9D5, 0x5879, 0xB9D6, 0x5885, 0xB9D7, 0x587D, + 0xB9D8, 0x58FD, 0xB9D9, 0x5925, 0xB9DA, 0x5922, 0xB9DB, 0x5924, + 0xB9DC, 0x596A, 0xB9DD, 0x5969, 0xB9DE, 0x5AE1, 0xB9DF, 0x5AE6, + 0xB9E0, 0x5AE9, 0xB9E1, 0x5AD7, 0xB9E2, 0x5AD6, 0xB9E3, 0x5AD8, + 0xB9E4, 0x5AE3, 0xB9E5, 0x5B75, 0xB9E6, 0x5BDE, 0xB9E7, 0x5BE7, + 0xB9E8, 0x5BE1, 0xB9E9, 0x5BE5, 0xB9EA, 0x5BE6, 0xB9EB, 0x5BE8, + 0xB9EC, 0x5BE2, 0xB9ED, 0x5BE4, 0xB9EE, 0x5BDF, 0xB9EF, 0x5C0D, + 0xB9F0, 0x5C62, 0xB9F1, 0x5D84, 0xB9F2, 0x5D87, 0xB9F3, 0x5E5B, + 0xB9F4, 0x5E63, 0xB9F5, 0x5E55, 0xB9F6, 0x5E57, 0xB9F7, 0x5E54, + 0xB9F8, 0x5ED3, 0xB9F9, 0x5ED6, 0xB9FA, 0x5F0A, 0xB9FB, 0x5F46, + 0xB9FC, 0x5F70, 0xB9FD, 0x5FB9, 0xB9FE, 0x6147, 0xBA40, 0x613F, + 0xBA41, 0x614B, 0xBA42, 0x6177, 0xBA43, 0x6162, 0xBA44, 0x6163, + 0xBA45, 0x615F, 0xBA46, 0x615A, 0xBA47, 0x6158, 0xBA48, 0x6175, + 0xBA49, 0x622A, 0xBA4A, 0x6487, 0xBA4B, 0x6458, 0xBA4C, 0x6454, + 0xBA4D, 0x64A4, 0xBA4E, 0x6478, 0xBA4F, 0x645F, 0xBA50, 0x647A, + 0xBA51, 0x6451, 0xBA52, 0x6467, 0xBA53, 0x6434, 0xBA54, 0x646D, + 0xBA55, 0x647B, 0xBA56, 0x6572, 0xBA57, 0x65A1, 0xBA58, 0x65D7, + 0xBA59, 0x65D6, 0xBA5A, 0x66A2, 0xBA5B, 0x66A8, 0xBA5C, 0x669D, + 0xBA5D, 0x699C, 0xBA5E, 0x69A8, 0xBA5F, 0x6995, 0xBA60, 0x69C1, + 0xBA61, 0x69AE, 0xBA62, 0x69D3, 0xBA63, 0x69CB, 0xBA64, 0x699B, + 0xBA65, 0x69B7, 0xBA66, 0x69BB, 0xBA67, 0x69AB, 0xBA68, 0x69B4, + 0xBA69, 0x69D0, 0xBA6A, 0x69CD, 0xBA6B, 0x69AD, 0xBA6C, 0x69CC, + 0xBA6D, 0x69A6, 0xBA6E, 0x69C3, 0xBA6F, 0x69A3, 0xBA70, 0x6B49, + 0xBA71, 0x6B4C, 0xBA72, 0x6C33, 0xBA73, 0x6F33, 0xBA74, 0x6F14, + 0xBA75, 0x6EFE, 0xBA76, 0x6F13, 0xBA77, 0x6EF4, 0xBA78, 0x6F29, + 0xBA79, 0x6F3E, 0xBA7A, 0x6F20, 0xBA7B, 0x6F2C, 0xBA7C, 0x6F0F, + 0xBA7D, 0x6F02, 0xBA7E, 0x6F22, 0xBAA1, 0x6EFF, 0xBAA2, 0x6EEF, + 0xBAA3, 0x6F06, 0xBAA4, 0x6F31, 0xBAA5, 0x6F38, 0xBAA6, 0x6F32, + 0xBAA7, 0x6F23, 0xBAA8, 0x6F15, 0xBAA9, 0x6F2B, 0xBAAA, 0x6F2F, + 0xBAAB, 0x6F88, 0xBAAC, 0x6F2A, 0xBAAD, 0x6EEC, 0xBAAE, 0x6F01, + 0xBAAF, 0x6EF2, 0xBAB0, 0x6ECC, 0xBAB1, 0x6EF7, 0xBAB2, 0x7194, + 0xBAB3, 0x7199, 0xBAB4, 0x717D, 0xBAB5, 0x718A, 0xBAB6, 0x7184, + 0xBAB7, 0x7192, 0xBAB8, 0x723E, 0xBAB9, 0x7292, 0xBABA, 0x7296, + 0xBABB, 0x7344, 0xBABC, 0x7350, 0xBABD, 0x7464, 0xBABE, 0x7463, + 0xBABF, 0x746A, 0xBAC0, 0x7470, 0xBAC1, 0x746D, 0xBAC2, 0x7504, + 0xBAC3, 0x7591, 0xBAC4, 0x7627, 0xBAC5, 0x760D, 0xBAC6, 0x760B, + 0xBAC7, 0x7609, 0xBAC8, 0x7613, 0xBAC9, 0x76E1, 0xBACA, 0x76E3, + 0xBACB, 0x7784, 0xBACC, 0x777D, 0xBACD, 0x777F, 0xBACE, 0x7761, + 0xBACF, 0x78C1, 0xBAD0, 0x789F, 0xBAD1, 0x78A7, 0xBAD2, 0x78B3, + 0xBAD3, 0x78A9, 0xBAD4, 0x78A3, 0xBAD5, 0x798E, 0xBAD6, 0x798F, + 0xBAD7, 0x798D, 0xBAD8, 0x7A2E, 0xBAD9, 0x7A31, 0xBADA, 0x7AAA, + 0xBADB, 0x7AA9, 0xBADC, 0x7AED, 0xBADD, 0x7AEF, 0xBADE, 0x7BA1, + 0xBADF, 0x7B95, 0xBAE0, 0x7B8B, 0xBAE1, 0x7B75, 0xBAE2, 0x7B97, + 0xBAE3, 0x7B9D, 0xBAE4, 0x7B94, 0xBAE5, 0x7B8F, 0xBAE6, 0x7BB8, + 0xBAE7, 0x7B87, 0xBAE8, 0x7B84, 0xBAE9, 0x7CB9, 0xBAEA, 0x7CBD, + 0xBAEB, 0x7CBE, 0xBAEC, 0x7DBB, 0xBAED, 0x7DB0, 0xBAEE, 0x7D9C, + 0xBAEF, 0x7DBD, 0xBAF0, 0x7DBE, 0xBAF1, 0x7DA0, 0xBAF2, 0x7DCA, + 0xBAF3, 0x7DB4, 0xBAF4, 0x7DB2, 0xBAF5, 0x7DB1, 0xBAF6, 0x7DBA, + 0xBAF7, 0x7DA2, 0xBAF8, 0x7DBF, 0xBAF9, 0x7DB5, 0xBAFA, 0x7DB8, + 0xBAFB, 0x7DAD, 0xBAFC, 0x7DD2, 0xBAFD, 0x7DC7, 0xBAFE, 0x7DAC, + 0xBB40, 0x7F70, 0xBB41, 0x7FE0, 0xBB42, 0x7FE1, 0xBB43, 0x7FDF, + 0xBB44, 0x805E, 0xBB45, 0x805A, 0xBB46, 0x8087, 0xBB47, 0x8150, + 0xBB48, 0x8180, 0xBB49, 0x818F, 0xBB4A, 0x8188, 0xBB4B, 0x818A, + 0xBB4C, 0x817F, 0xBB4D, 0x8182, 0xBB4E, 0x81E7, 0xBB4F, 0x81FA, + 0xBB50, 0x8207, 0xBB51, 0x8214, 0xBB52, 0x821E, 0xBB53, 0x824B, + 0xBB54, 0x84C9, 0xBB55, 0x84BF, 0xBB56, 0x84C6, 0xBB57, 0x84C4, + 0xBB58, 0x8499, 0xBB59, 0x849E, 0xBB5A, 0x84B2, 0xBB5B, 0x849C, + 0xBB5C, 0x84CB, 0xBB5D, 0x84B8, 0xBB5E, 0x84C0, 0xBB5F, 0x84D3, + 0xBB60, 0x8490, 0xBB61, 0x84BC, 0xBB62, 0x84D1, 0xBB63, 0x84CA, + 0xBB64, 0x873F, 0xBB65, 0x871C, 0xBB66, 0x873B, 0xBB67, 0x8722, + 0xBB68, 0x8725, 0xBB69, 0x8734, 0xBB6A, 0x8718, 0xBB6B, 0x8755, + 0xBB6C, 0x8737, 0xBB6D, 0x8729, 0xBB6E, 0x88F3, 0xBB6F, 0x8902, + 0xBB70, 0x88F4, 0xBB71, 0x88F9, 0xBB72, 0x88F8, 0xBB73, 0x88FD, + 0xBB74, 0x88E8, 0xBB75, 0x891A, 0xBB76, 0x88EF, 0xBB77, 0x8AA6, + 0xBB78, 0x8A8C, 0xBB79, 0x8A9E, 0xBB7A, 0x8AA3, 0xBB7B, 0x8A8D, + 0xBB7C, 0x8AA1, 0xBB7D, 0x8A93, 0xBB7E, 0x8AA4, 0xBBA1, 0x8AAA, + 0xBBA2, 0x8AA5, 0xBBA3, 0x8AA8, 0xBBA4, 0x8A98, 0xBBA5, 0x8A91, + 0xBBA6, 0x8A9A, 0xBBA7, 0x8AA7, 0xBBA8, 0x8C6A, 0xBBA9, 0x8C8D, + 0xBBAA, 0x8C8C, 0xBBAB, 0x8CD3, 0xBBAC, 0x8CD1, 0xBBAD, 0x8CD2, + 0xBBAE, 0x8D6B, 0xBBAF, 0x8D99, 0xBBB0, 0x8D95, 0xBBB1, 0x8DFC, + 0xBBB2, 0x8F14, 0xBBB3, 0x8F12, 0xBBB4, 0x8F15, 0xBBB5, 0x8F13, + 0xBBB6, 0x8FA3, 0xBBB7, 0x9060, 0xBBB8, 0x9058, 0xBBB9, 0x905C, + 0xBBBA, 0x9063, 0xBBBB, 0x9059, 0xBBBC, 0x905E, 0xBBBD, 0x9062, + 0xBBBE, 0x905D, 0xBBBF, 0x905B, 0xBBC0, 0x9119, 0xBBC1, 0x9118, + 0xBBC2, 0x911E, 0xBBC3, 0x9175, 0xBBC4, 0x9178, 0xBBC5, 0x9177, + 0xBBC6, 0x9174, 0xBBC7, 0x9278, 0xBBC8, 0x9280, 0xBBC9, 0x9285, + 0xBBCA, 0x9298, 0xBBCB, 0x9296, 0xBBCC, 0x927B, 0xBBCD, 0x9293, + 0xBBCE, 0x929C, 0xBBCF, 0x92A8, 0xBBD0, 0x927C, 0xBBD1, 0x9291, + 0xBBD2, 0x95A1, 0xBBD3, 0x95A8, 0xBBD4, 0x95A9, 0xBBD5, 0x95A3, + 0xBBD6, 0x95A5, 0xBBD7, 0x95A4, 0xBBD8, 0x9699, 0xBBD9, 0x969C, + 0xBBDA, 0x969B, 0xBBDB, 0x96CC, 0xBBDC, 0x96D2, 0xBBDD, 0x9700, + 0xBBDE, 0x977C, 0xBBDF, 0x9785, 0xBBE0, 0x97F6, 0xBBE1, 0x9817, + 0xBBE2, 0x9818, 0xBBE3, 0x98AF, 0xBBE4, 0x98B1, 0xBBE5, 0x9903, + 0xBBE6, 0x9905, 0xBBE7, 0x990C, 0xBBE8, 0x9909, 0xBBE9, 0x99C1, + 0xBBEA, 0x9AAF, 0xBBEB, 0x9AB0, 0xBBEC, 0x9AE6, 0xBBED, 0x9B41, + 0xBBEE, 0x9B42, 0xBBEF, 0x9CF4, 0xBBF0, 0x9CF6, 0xBBF1, 0x9CF3, + 0xBBF2, 0x9EBC, 0xBBF3, 0x9F3B, 0xBBF4, 0x9F4A, 0xBBF5, 0x5104, + 0xBBF6, 0x5100, 0xBBF7, 0x50FB, 0xBBF8, 0x50F5, 0xBBF9, 0x50F9, + 0xBBFA, 0x5102, 0xBBFB, 0x5108, 0xBBFC, 0x5109, 0xBBFD, 0x5105, + 0xBBFE, 0x51DC, 0xBC40, 0x5287, 0xBC41, 0x5288, 0xBC42, 0x5289, + 0xBC43, 0x528D, 0xBC44, 0x528A, 0xBC45, 0x52F0, 0xBC46, 0x53B2, + 0xBC47, 0x562E, 0xBC48, 0x563B, 0xBC49, 0x5639, 0xBC4A, 0x5632, + 0xBC4B, 0x563F, 0xBC4C, 0x5634, 0xBC4D, 0x5629, 0xBC4E, 0x5653, + 0xBC4F, 0x564E, 0xBC50, 0x5657, 0xBC51, 0x5674, 0xBC52, 0x5636, + 0xBC53, 0x562F, 0xBC54, 0x5630, 0xBC55, 0x5880, 0xBC56, 0x589F, + 0xBC57, 0x589E, 0xBC58, 0x58B3, 0xBC59, 0x589C, 0xBC5A, 0x58AE, + 0xBC5B, 0x58A9, 0xBC5C, 0x58A6, 0xBC5D, 0x596D, 0xBC5E, 0x5B09, + 0xBC5F, 0x5AFB, 0xBC60, 0x5B0B, 0xBC61, 0x5AF5, 0xBC62, 0x5B0C, + 0xBC63, 0x5B08, 0xBC64, 0x5BEE, 0xBC65, 0x5BEC, 0xBC66, 0x5BE9, + 0xBC67, 0x5BEB, 0xBC68, 0x5C64, 0xBC69, 0x5C65, 0xBC6A, 0x5D9D, + 0xBC6B, 0x5D94, 0xBC6C, 0x5E62, 0xBC6D, 0x5E5F, 0xBC6E, 0x5E61, + 0xBC6F, 0x5EE2, 0xBC70, 0x5EDA, 0xBC71, 0x5EDF, 0xBC72, 0x5EDD, + 0xBC73, 0x5EE3, 0xBC74, 0x5EE0, 0xBC75, 0x5F48, 0xBC76, 0x5F71, + 0xBC77, 0x5FB7, 0xBC78, 0x5FB5, 0xBC79, 0x6176, 0xBC7A, 0x6167, + 0xBC7B, 0x616E, 0xBC7C, 0x615D, 0xBC7D, 0x6155, 0xBC7E, 0x6182, + 0xBCA1, 0x617C, 0xBCA2, 0x6170, 0xBCA3, 0x616B, 0xBCA4, 0x617E, + 0xBCA5, 0x61A7, 0xBCA6, 0x6190, 0xBCA7, 0x61AB, 0xBCA8, 0x618E, + 0xBCA9, 0x61AC, 0xBCAA, 0x619A, 0xBCAB, 0x61A4, 0xBCAC, 0x6194, + 0xBCAD, 0x61AE, 0xBCAE, 0x622E, 0xBCAF, 0x6469, 0xBCB0, 0x646F, + 0xBCB1, 0x6479, 0xBCB2, 0x649E, 0xBCB3, 0x64B2, 0xBCB4, 0x6488, + 0xBCB5, 0x6490, 0xBCB6, 0x64B0, 0xBCB7, 0x64A5, 0xBCB8, 0x6493, + 0xBCB9, 0x6495, 0xBCBA, 0x64A9, 0xBCBB, 0x6492, 0xBCBC, 0x64AE, + 0xBCBD, 0x64AD, 0xBCBE, 0x64AB, 0xBCBF, 0x649A, 0xBCC0, 0x64AC, + 0xBCC1, 0x6499, 0xBCC2, 0x64A2, 0xBCC3, 0x64B3, 0xBCC4, 0x6575, + 0xBCC5, 0x6577, 0xBCC6, 0x6578, 0xBCC7, 0x66AE, 0xBCC8, 0x66AB, + 0xBCC9, 0x66B4, 0xBCCA, 0x66B1, 0xBCCB, 0x6A23, 0xBCCC, 0x6A1F, + 0xBCCD, 0x69E8, 0xBCCE, 0x6A01, 0xBCCF, 0x6A1E, 0xBCD0, 0x6A19, + 0xBCD1, 0x69FD, 0xBCD2, 0x6A21, 0xBCD3, 0x6A13, 0xBCD4, 0x6A0A, + 0xBCD5, 0x69F3, 0xBCD6, 0x6A02, 0xBCD7, 0x6A05, 0xBCD8, 0x69ED, + 0xBCD9, 0x6A11, 0xBCDA, 0x6B50, 0xBCDB, 0x6B4E, 0xBCDC, 0x6BA4, + 0xBCDD, 0x6BC5, 0xBCDE, 0x6BC6, 0xBCDF, 0x6F3F, 0xBCE0, 0x6F7C, + 0xBCE1, 0x6F84, 0xBCE2, 0x6F51, 0xBCE3, 0x6F66, 0xBCE4, 0x6F54, + 0xBCE5, 0x6F86, 0xBCE6, 0x6F6D, 0xBCE7, 0x6F5B, 0xBCE8, 0x6F78, + 0xBCE9, 0x6F6E, 0xBCEA, 0x6F8E, 0xBCEB, 0x6F7A, 0xBCEC, 0x6F70, + 0xBCED, 0x6F64, 0xBCEE, 0x6F97, 0xBCEF, 0x6F58, 0xBCF0, 0x6ED5, + 0xBCF1, 0x6F6F, 0xBCF2, 0x6F60, 0xBCF3, 0x6F5F, 0xBCF4, 0x719F, + 0xBCF5, 0x71AC, 0xBCF6, 0x71B1, 0xBCF7, 0x71A8, 0xBCF8, 0x7256, + 0xBCF9, 0x729B, 0xBCFA, 0x734E, 0xBCFB, 0x7357, 0xBCFC, 0x7469, + 0xBCFD, 0x748B, 0xBCFE, 0x7483, 0xBD40, 0x747E, 0xBD41, 0x7480, + 0xBD42, 0x757F, 0xBD43, 0x7620, 0xBD44, 0x7629, 0xBD45, 0x761F, + 0xBD46, 0x7624, 0xBD47, 0x7626, 0xBD48, 0x7621, 0xBD49, 0x7622, + 0xBD4A, 0x769A, 0xBD4B, 0x76BA, 0xBD4C, 0x76E4, 0xBD4D, 0x778E, + 0xBD4E, 0x7787, 0xBD4F, 0x778C, 0xBD50, 0x7791, 0xBD51, 0x778B, + 0xBD52, 0x78CB, 0xBD53, 0x78C5, 0xBD54, 0x78BA, 0xBD55, 0x78CA, + 0xBD56, 0x78BE, 0xBD57, 0x78D5, 0xBD58, 0x78BC, 0xBD59, 0x78D0, + 0xBD5A, 0x7A3F, 0xBD5B, 0x7A3C, 0xBD5C, 0x7A40, 0xBD5D, 0x7A3D, + 0xBD5E, 0x7A37, 0xBD5F, 0x7A3B, 0xBD60, 0x7AAF, 0xBD61, 0x7AAE, + 0xBD62, 0x7BAD, 0xBD63, 0x7BB1, 0xBD64, 0x7BC4, 0xBD65, 0x7BB4, + 0xBD66, 0x7BC6, 0xBD67, 0x7BC7, 0xBD68, 0x7BC1, 0xBD69, 0x7BA0, + 0xBD6A, 0x7BCC, 0xBD6B, 0x7CCA, 0xBD6C, 0x7DE0, 0xBD6D, 0x7DF4, + 0xBD6E, 0x7DEF, 0xBD6F, 0x7DFB, 0xBD70, 0x7DD8, 0xBD71, 0x7DEC, + 0xBD72, 0x7DDD, 0xBD73, 0x7DE8, 0xBD74, 0x7DE3, 0xBD75, 0x7DDA, + 0xBD76, 0x7DDE, 0xBD77, 0x7DE9, 0xBD78, 0x7D9E, 0xBD79, 0x7DD9, + 0xBD7A, 0x7DF2, 0xBD7B, 0x7DF9, 0xBD7C, 0x7F75, 0xBD7D, 0x7F77, + 0xBD7E, 0x7FAF, 0xBDA1, 0x7FE9, 0xBDA2, 0x8026, 0xBDA3, 0x819B, + 0xBDA4, 0x819C, 0xBDA5, 0x819D, 0xBDA6, 0x81A0, 0xBDA7, 0x819A, + 0xBDA8, 0x8198, 0xBDA9, 0x8517, 0xBDAA, 0x853D, 0xBDAB, 0x851A, + 0xBDAC, 0x84EE, 0xBDAD, 0x852C, 0xBDAE, 0x852D, 0xBDAF, 0x8513, + 0xBDB0, 0x8511, 0xBDB1, 0x8523, 0xBDB2, 0x8521, 0xBDB3, 0x8514, + 0xBDB4, 0x84EC, 0xBDB5, 0x8525, 0xBDB6, 0x84FF, 0xBDB7, 0x8506, + 0xBDB8, 0x8782, 0xBDB9, 0x8774, 0xBDBA, 0x8776, 0xBDBB, 0x8760, + 0xBDBC, 0x8766, 0xBDBD, 0x8778, 0xBDBE, 0x8768, 0xBDBF, 0x8759, + 0xBDC0, 0x8757, 0xBDC1, 0x874C, 0xBDC2, 0x8753, 0xBDC3, 0x885B, + 0xBDC4, 0x885D, 0xBDC5, 0x8910, 0xBDC6, 0x8907, 0xBDC7, 0x8912, + 0xBDC8, 0x8913, 0xBDC9, 0x8915, 0xBDCA, 0x890A, 0xBDCB, 0x8ABC, + 0xBDCC, 0x8AD2, 0xBDCD, 0x8AC7, 0xBDCE, 0x8AC4, 0xBDCF, 0x8A95, + 0xBDD0, 0x8ACB, 0xBDD1, 0x8AF8, 0xBDD2, 0x8AB2, 0xBDD3, 0x8AC9, + 0xBDD4, 0x8AC2, 0xBDD5, 0x8ABF, 0xBDD6, 0x8AB0, 0xBDD7, 0x8AD6, + 0xBDD8, 0x8ACD, 0xBDD9, 0x8AB6, 0xBDDA, 0x8AB9, 0xBDDB, 0x8ADB, + 0xBDDC, 0x8C4C, 0xBDDD, 0x8C4E, 0xBDDE, 0x8C6C, 0xBDDF, 0x8CE0, + 0xBDE0, 0x8CDE, 0xBDE1, 0x8CE6, 0xBDE2, 0x8CE4, 0xBDE3, 0x8CEC, + 0xBDE4, 0x8CED, 0xBDE5, 0x8CE2, 0xBDE6, 0x8CE3, 0xBDE7, 0x8CDC, + 0xBDE8, 0x8CEA, 0xBDE9, 0x8CE1, 0xBDEA, 0x8D6D, 0xBDEB, 0x8D9F, + 0xBDEC, 0x8DA3, 0xBDED, 0x8E2B, 0xBDEE, 0x8E10, 0xBDEF, 0x8E1D, + 0xBDF0, 0x8E22, 0xBDF1, 0x8E0F, 0xBDF2, 0x8E29, 0xBDF3, 0x8E1F, + 0xBDF4, 0x8E21, 0xBDF5, 0x8E1E, 0xBDF6, 0x8EBA, 0xBDF7, 0x8F1D, + 0xBDF8, 0x8F1B, 0xBDF9, 0x8F1F, 0xBDFA, 0x8F29, 0xBDFB, 0x8F26, + 0xBDFC, 0x8F2A, 0xBDFD, 0x8F1C, 0xBDFE, 0x8F1E, 0xBE40, 0x8F25, + 0xBE41, 0x9069, 0xBE42, 0x906E, 0xBE43, 0x9068, 0xBE44, 0x906D, + 0xBE45, 0x9077, 0xBE46, 0x9130, 0xBE47, 0x912D, 0xBE48, 0x9127, + 0xBE49, 0x9131, 0xBE4A, 0x9187, 0xBE4B, 0x9189, 0xBE4C, 0x918B, + 0xBE4D, 0x9183, 0xBE4E, 0x92C5, 0xBE4F, 0x92BB, 0xBE50, 0x92B7, + 0xBE51, 0x92EA, 0xBE52, 0x92AC, 0xBE53, 0x92E4, 0xBE54, 0x92C1, + 0xBE55, 0x92B3, 0xBE56, 0x92BC, 0xBE57, 0x92D2, 0xBE58, 0x92C7, + 0xBE59, 0x92F0, 0xBE5A, 0x92B2, 0xBE5B, 0x95AD, 0xBE5C, 0x95B1, + 0xBE5D, 0x9704, 0xBE5E, 0x9706, 0xBE5F, 0x9707, 0xBE60, 0x9709, + 0xBE61, 0x9760, 0xBE62, 0x978D, 0xBE63, 0x978B, 0xBE64, 0x978F, + 0xBE65, 0x9821, 0xBE66, 0x982B, 0xBE67, 0x981C, 0xBE68, 0x98B3, + 0xBE69, 0x990A, 0xBE6A, 0x9913, 0xBE6B, 0x9912, 0xBE6C, 0x9918, + 0xBE6D, 0x99DD, 0xBE6E, 0x99D0, 0xBE6F, 0x99DF, 0xBE70, 0x99DB, + 0xBE71, 0x99D1, 0xBE72, 0x99D5, 0xBE73, 0x99D2, 0xBE74, 0x99D9, + 0xBE75, 0x9AB7, 0xBE76, 0x9AEE, 0xBE77, 0x9AEF, 0xBE78, 0x9B27, + 0xBE79, 0x9B45, 0xBE7A, 0x9B44, 0xBE7B, 0x9B77, 0xBE7C, 0x9B6F, + 0xBE7D, 0x9D06, 0xBE7E, 0x9D09, 0xBEA1, 0x9D03, 0xBEA2, 0x9EA9, + 0xBEA3, 0x9EBE, 0xBEA4, 0x9ECE, 0xBEA5, 0x58A8, 0xBEA6, 0x9F52, + 0xBEA7, 0x5112, 0xBEA8, 0x5118, 0xBEA9, 0x5114, 0xBEAA, 0x5110, + 0xBEAB, 0x5115, 0xBEAC, 0x5180, 0xBEAD, 0x51AA, 0xBEAE, 0x51DD, + 0xBEAF, 0x5291, 0xBEB0, 0x5293, 0xBEB1, 0x52F3, 0xBEB2, 0x5659, + 0xBEB3, 0x566B, 0xBEB4, 0x5679, 0xBEB5, 0x5669, 0xBEB6, 0x5664, + 0xBEB7, 0x5678, 0xBEB8, 0x566A, 0xBEB9, 0x5668, 0xBEBA, 0x5665, + 0xBEBB, 0x5671, 0xBEBC, 0x566F, 0xBEBD, 0x566C, 0xBEBE, 0x5662, + 0xBEBF, 0x5676, 0xBEC0, 0x58C1, 0xBEC1, 0x58BE, 0xBEC2, 0x58C7, + 0xBEC3, 0x58C5, 0xBEC4, 0x596E, 0xBEC5, 0x5B1D, 0xBEC6, 0x5B34, + 0xBEC7, 0x5B78, 0xBEC8, 0x5BF0, 0xBEC9, 0x5C0E, 0xBECA, 0x5F4A, + 0xBECB, 0x61B2, 0xBECC, 0x6191, 0xBECD, 0x61A9, 0xBECE, 0x618A, + 0xBECF, 0x61CD, 0xBED0, 0x61B6, 0xBED1, 0x61BE, 0xBED2, 0x61CA, + 0xBED3, 0x61C8, 0xBED4, 0x6230, 0xBED5, 0x64C5, 0xBED6, 0x64C1, + 0xBED7, 0x64CB, 0xBED8, 0x64BB, 0xBED9, 0x64BC, 0xBEDA, 0x64DA, + 0xBEDB, 0x64C4, 0xBEDC, 0x64C7, 0xBEDD, 0x64C2, 0xBEDE, 0x64CD, + 0xBEDF, 0x64BF, 0xBEE0, 0x64D2, 0xBEE1, 0x64D4, 0xBEE2, 0x64BE, + 0xBEE3, 0x6574, 0xBEE4, 0x66C6, 0xBEE5, 0x66C9, 0xBEE6, 0x66B9, + 0xBEE7, 0x66C4, 0xBEE8, 0x66C7, 0xBEE9, 0x66B8, 0xBEEA, 0x6A3D, + 0xBEEB, 0x6A38, 0xBEEC, 0x6A3A, 0xBEED, 0x6A59, 0xBEEE, 0x6A6B, + 0xBEEF, 0x6A58, 0xBEF0, 0x6A39, 0xBEF1, 0x6A44, 0xBEF2, 0x6A62, + 0xBEF3, 0x6A61, 0xBEF4, 0x6A4B, 0xBEF5, 0x6A47, 0xBEF6, 0x6A35, + 0xBEF7, 0x6A5F, 0xBEF8, 0x6A48, 0xBEF9, 0x6B59, 0xBEFA, 0x6B77, + 0xBEFB, 0x6C05, 0xBEFC, 0x6FC2, 0xBEFD, 0x6FB1, 0xBEFE, 0x6FA1, + 0xBF40, 0x6FC3, 0xBF41, 0x6FA4, 0xBF42, 0x6FC1, 0xBF43, 0x6FA7, + 0xBF44, 0x6FB3, 0xBF45, 0x6FC0, 0xBF46, 0x6FB9, 0xBF47, 0x6FB6, + 0xBF48, 0x6FA6, 0xBF49, 0x6FA0, 0xBF4A, 0x6FB4, 0xBF4B, 0x71BE, + 0xBF4C, 0x71C9, 0xBF4D, 0x71D0, 0xBF4E, 0x71D2, 0xBF4F, 0x71C8, + 0xBF50, 0x71D5, 0xBF51, 0x71B9, 0xBF52, 0x71CE, 0xBF53, 0x71D9, + 0xBF54, 0x71DC, 0xBF55, 0x71C3, 0xBF56, 0x71C4, 0xBF57, 0x7368, + 0xBF58, 0x749C, 0xBF59, 0x74A3, 0xBF5A, 0x7498, 0xBF5B, 0x749F, + 0xBF5C, 0x749E, 0xBF5D, 0x74E2, 0xBF5E, 0x750C, 0xBF5F, 0x750D, + 0xBF60, 0x7634, 0xBF61, 0x7638, 0xBF62, 0x763A, 0xBF63, 0x76E7, + 0xBF64, 0x76E5, 0xBF65, 0x77A0, 0xBF66, 0x779E, 0xBF67, 0x779F, + 0xBF68, 0x77A5, 0xBF69, 0x78E8, 0xBF6A, 0x78DA, 0xBF6B, 0x78EC, + 0xBF6C, 0x78E7, 0xBF6D, 0x79A6, 0xBF6E, 0x7A4D, 0xBF6F, 0x7A4E, + 0xBF70, 0x7A46, 0xBF71, 0x7A4C, 0xBF72, 0x7A4B, 0xBF73, 0x7ABA, + 0xBF74, 0x7BD9, 0xBF75, 0x7C11, 0xBF76, 0x7BC9, 0xBF77, 0x7BE4, + 0xBF78, 0x7BDB, 0xBF79, 0x7BE1, 0xBF7A, 0x7BE9, 0xBF7B, 0x7BE6, + 0xBF7C, 0x7CD5, 0xBF7D, 0x7CD6, 0xBF7E, 0x7E0A, 0xBFA1, 0x7E11, + 0xBFA2, 0x7E08, 0xBFA3, 0x7E1B, 0xBFA4, 0x7E23, 0xBFA5, 0x7E1E, + 0xBFA6, 0x7E1D, 0xBFA7, 0x7E09, 0xBFA8, 0x7E10, 0xBFA9, 0x7F79, + 0xBFAA, 0x7FB2, 0xBFAB, 0x7FF0, 0xBFAC, 0x7FF1, 0xBFAD, 0x7FEE, + 0xBFAE, 0x8028, 0xBFAF, 0x81B3, 0xBFB0, 0x81A9, 0xBFB1, 0x81A8, + 0xBFB2, 0x81FB, 0xBFB3, 0x8208, 0xBFB4, 0x8258, 0xBFB5, 0x8259, + 0xBFB6, 0x854A, 0xBFB7, 0x8559, 0xBFB8, 0x8548, 0xBFB9, 0x8568, + 0xBFBA, 0x8569, 0xBFBB, 0x8543, 0xBFBC, 0x8549, 0xBFBD, 0x856D, + 0xBFBE, 0x856A, 0xBFBF, 0x855E, 0xBFC0, 0x8783, 0xBFC1, 0x879F, + 0xBFC2, 0x879E, 0xBFC3, 0x87A2, 0xBFC4, 0x878D, 0xBFC5, 0x8861, + 0xBFC6, 0x892A, 0xBFC7, 0x8932, 0xBFC8, 0x8925, 0xBFC9, 0x892B, + 0xBFCA, 0x8921, 0xBFCB, 0x89AA, 0xBFCC, 0x89A6, 0xBFCD, 0x8AE6, + 0xBFCE, 0x8AFA, 0xBFCF, 0x8AEB, 0xBFD0, 0x8AF1, 0xBFD1, 0x8B00, + 0xBFD2, 0x8ADC, 0xBFD3, 0x8AE7, 0xBFD4, 0x8AEE, 0xBFD5, 0x8AFE, + 0xBFD6, 0x8B01, 0xBFD7, 0x8B02, 0xBFD8, 0x8AF7, 0xBFD9, 0x8AED, + 0xBFDA, 0x8AF3, 0xBFDB, 0x8AF6, 0xBFDC, 0x8AFC, 0xBFDD, 0x8C6B, + 0xBFDE, 0x8C6D, 0xBFDF, 0x8C93, 0xBFE0, 0x8CF4, 0xBFE1, 0x8E44, + 0xBFE2, 0x8E31, 0xBFE3, 0x8E34, 0xBFE4, 0x8E42, 0xBFE5, 0x8E39, + 0xBFE6, 0x8E35, 0xBFE7, 0x8F3B, 0xBFE8, 0x8F2F, 0xBFE9, 0x8F38, + 0xBFEA, 0x8F33, 0xBFEB, 0x8FA8, 0xBFEC, 0x8FA6, 0xBFED, 0x9075, + 0xBFEE, 0x9074, 0xBFEF, 0x9078, 0xBFF0, 0x9072, 0xBFF1, 0x907C, + 0xBFF2, 0x907A, 0xBFF3, 0x9134, 0xBFF4, 0x9192, 0xBFF5, 0x9320, + 0xBFF6, 0x9336, 0xBFF7, 0x92F8, 0xBFF8, 0x9333, 0xBFF9, 0x932F, + 0xBFFA, 0x9322, 0xBFFB, 0x92FC, 0xBFFC, 0x932B, 0xBFFD, 0x9304, + 0xBFFE, 0x931A, 0xC040, 0x9310, 0xC041, 0x9326, 0xC042, 0x9321, + 0xC043, 0x9315, 0xC044, 0x932E, 0xC045, 0x9319, 0xC046, 0x95BB, + 0xC047, 0x96A7, 0xC048, 0x96A8, 0xC049, 0x96AA, 0xC04A, 0x96D5, + 0xC04B, 0x970E, 0xC04C, 0x9711, 0xC04D, 0x9716, 0xC04E, 0x970D, + 0xC04F, 0x9713, 0xC050, 0x970F, 0xC051, 0x975B, 0xC052, 0x975C, + 0xC053, 0x9766, 0xC054, 0x9798, 0xC055, 0x9830, 0xC056, 0x9838, + 0xC057, 0x983B, 0xC058, 0x9837, 0xC059, 0x982D, 0xC05A, 0x9839, + 0xC05B, 0x9824, 0xC05C, 0x9910, 0xC05D, 0x9928, 0xC05E, 0x991E, + 0xC05F, 0x991B, 0xC060, 0x9921, 0xC061, 0x991A, 0xC062, 0x99ED, + 0xC063, 0x99E2, 0xC064, 0x99F1, 0xC065, 0x9AB8, 0xC066, 0x9ABC, + 0xC067, 0x9AFB, 0xC068, 0x9AED, 0xC069, 0x9B28, 0xC06A, 0x9B91, + 0xC06B, 0x9D15, 0xC06C, 0x9D23, 0xC06D, 0x9D26, 0xC06E, 0x9D28, + 0xC06F, 0x9D12, 0xC070, 0x9D1B, 0xC071, 0x9ED8, 0xC072, 0x9ED4, + 0xC073, 0x9F8D, 0xC074, 0x9F9C, 0xC075, 0x512A, 0xC076, 0x511F, + 0xC077, 0x5121, 0xC078, 0x5132, 0xC079, 0x52F5, 0xC07A, 0x568E, + 0xC07B, 0x5680, 0xC07C, 0x5690, 0xC07D, 0x5685, 0xC07E, 0x5687, + 0xC0A1, 0x568F, 0xC0A2, 0x58D5, 0xC0A3, 0x58D3, 0xC0A4, 0x58D1, + 0xC0A5, 0x58CE, 0xC0A6, 0x5B30, 0xC0A7, 0x5B2A, 0xC0A8, 0x5B24, + 0xC0A9, 0x5B7A, 0xC0AA, 0x5C37, 0xC0AB, 0x5C68, 0xC0AC, 0x5DBC, + 0xC0AD, 0x5DBA, 0xC0AE, 0x5DBD, 0xC0AF, 0x5DB8, 0xC0B0, 0x5E6B, + 0xC0B1, 0x5F4C, 0xC0B2, 0x5FBD, 0xC0B3, 0x61C9, 0xC0B4, 0x61C2, + 0xC0B5, 0x61C7, 0xC0B6, 0x61E6, 0xC0B7, 0x61CB, 0xC0B8, 0x6232, + 0xC0B9, 0x6234, 0xC0BA, 0x64CE, 0xC0BB, 0x64CA, 0xC0BC, 0x64D8, + 0xC0BD, 0x64E0, 0xC0BE, 0x64F0, 0xC0BF, 0x64E6, 0xC0C0, 0x64EC, + 0xC0C1, 0x64F1, 0xC0C2, 0x64E2, 0xC0C3, 0x64ED, 0xC0C4, 0x6582, + 0xC0C5, 0x6583, 0xC0C6, 0x66D9, 0xC0C7, 0x66D6, 0xC0C8, 0x6A80, + 0xC0C9, 0x6A94, 0xC0CA, 0x6A84, 0xC0CB, 0x6AA2, 0xC0CC, 0x6A9C, + 0xC0CD, 0x6ADB, 0xC0CE, 0x6AA3, 0xC0CF, 0x6A7E, 0xC0D0, 0x6A97, + 0xC0D1, 0x6A90, 0xC0D2, 0x6AA0, 0xC0D3, 0x6B5C, 0xC0D4, 0x6BAE, + 0xC0D5, 0x6BDA, 0xC0D6, 0x6C08, 0xC0D7, 0x6FD8, 0xC0D8, 0x6FF1, + 0xC0D9, 0x6FDF, 0xC0DA, 0x6FE0, 0xC0DB, 0x6FDB, 0xC0DC, 0x6FE4, + 0xC0DD, 0x6FEB, 0xC0DE, 0x6FEF, 0xC0DF, 0x6F80, 0xC0E0, 0x6FEC, + 0xC0E1, 0x6FE1, 0xC0E2, 0x6FE9, 0xC0E3, 0x6FD5, 0xC0E4, 0x6FEE, + 0xC0E5, 0x6FF0, 0xC0E6, 0x71E7, 0xC0E7, 0x71DF, 0xC0E8, 0x71EE, + 0xC0E9, 0x71E6, 0xC0EA, 0x71E5, 0xC0EB, 0x71ED, 0xC0EC, 0x71EC, + 0xC0ED, 0x71F4, 0xC0EE, 0x71E0, 0xC0EF, 0x7235, 0xC0F0, 0x7246, + 0xC0F1, 0x7370, 0xC0F2, 0x7372, 0xC0F3, 0x74A9, 0xC0F4, 0x74B0, + 0xC0F5, 0x74A6, 0xC0F6, 0x74A8, 0xC0F7, 0x7646, 0xC0F8, 0x7642, + 0xC0F9, 0x764C, 0xC0FA, 0x76EA, 0xC0FB, 0x77B3, 0xC0FC, 0x77AA, + 0xC0FD, 0x77B0, 0xC0FE, 0x77AC, 0xC140, 0x77A7, 0xC141, 0x77AD, + 0xC142, 0x77EF, 0xC143, 0x78F7, 0xC144, 0x78FA, 0xC145, 0x78F4, + 0xC146, 0x78EF, 0xC147, 0x7901, 0xC148, 0x79A7, 0xC149, 0x79AA, + 0xC14A, 0x7A57, 0xC14B, 0x7ABF, 0xC14C, 0x7C07, 0xC14D, 0x7C0D, + 0xC14E, 0x7BFE, 0xC14F, 0x7BF7, 0xC150, 0x7C0C, 0xC151, 0x7BE0, + 0xC152, 0x7CE0, 0xC153, 0x7CDC, 0xC154, 0x7CDE, 0xC155, 0x7CE2, + 0xC156, 0x7CDF, 0xC157, 0x7CD9, 0xC158, 0x7CDD, 0xC159, 0x7E2E, + 0xC15A, 0x7E3E, 0xC15B, 0x7E46, 0xC15C, 0x7E37, 0xC15D, 0x7E32, + 0xC15E, 0x7E43, 0xC15F, 0x7E2B, 0xC160, 0x7E3D, 0xC161, 0x7E31, + 0xC162, 0x7E45, 0xC163, 0x7E41, 0xC164, 0x7E34, 0xC165, 0x7E39, + 0xC166, 0x7E48, 0xC167, 0x7E35, 0xC168, 0x7E3F, 0xC169, 0x7E2F, + 0xC16A, 0x7F44, 0xC16B, 0x7FF3, 0xC16C, 0x7FFC, 0xC16D, 0x8071, + 0xC16E, 0x8072, 0xC16F, 0x8070, 0xC170, 0x806F, 0xC171, 0x8073, + 0xC172, 0x81C6, 0xC173, 0x81C3, 0xC174, 0x81BA, 0xC175, 0x81C2, + 0xC176, 0x81C0, 0xC177, 0x81BF, 0xC178, 0x81BD, 0xC179, 0x81C9, + 0xC17A, 0x81BE, 0xC17B, 0x81E8, 0xC17C, 0x8209, 0xC17D, 0x8271, + 0xC17E, 0x85AA, 0xC1A1, 0x8584, 0xC1A2, 0x857E, 0xC1A3, 0x859C, + 0xC1A4, 0x8591, 0xC1A5, 0x8594, 0xC1A6, 0x85AF, 0xC1A7, 0x859B, + 0xC1A8, 0x8587, 0xC1A9, 0x85A8, 0xC1AA, 0x858A, 0xC1AB, 0x8667, + 0xC1AC, 0x87C0, 0xC1AD, 0x87D1, 0xC1AE, 0x87B3, 0xC1AF, 0x87D2, + 0xC1B0, 0x87C6, 0xC1B1, 0x87AB, 0xC1B2, 0x87BB, 0xC1B3, 0x87BA, + 0xC1B4, 0x87C8, 0xC1B5, 0x87CB, 0xC1B6, 0x893B, 0xC1B7, 0x8936, + 0xC1B8, 0x8944, 0xC1B9, 0x8938, 0xC1BA, 0x893D, 0xC1BB, 0x89AC, + 0xC1BC, 0x8B0E, 0xC1BD, 0x8B17, 0xC1BE, 0x8B19, 0xC1BF, 0x8B1B, + 0xC1C0, 0x8B0A, 0xC1C1, 0x8B20, 0xC1C2, 0x8B1D, 0xC1C3, 0x8B04, + 0xC1C4, 0x8B10, 0xC1C5, 0x8C41, 0xC1C6, 0x8C3F, 0xC1C7, 0x8C73, + 0xC1C8, 0x8CFA, 0xC1C9, 0x8CFD, 0xC1CA, 0x8CFC, 0xC1CB, 0x8CF8, + 0xC1CC, 0x8CFB, 0xC1CD, 0x8DA8, 0xC1CE, 0x8E49, 0xC1CF, 0x8E4B, + 0xC1D0, 0x8E48, 0xC1D1, 0x8E4A, 0xC1D2, 0x8F44, 0xC1D3, 0x8F3E, + 0xC1D4, 0x8F42, 0xC1D5, 0x8F45, 0xC1D6, 0x8F3F, 0xC1D7, 0x907F, + 0xC1D8, 0x907D, 0xC1D9, 0x9084, 0xC1DA, 0x9081, 0xC1DB, 0x9082, + 0xC1DC, 0x9080, 0xC1DD, 0x9139, 0xC1DE, 0x91A3, 0xC1DF, 0x919E, + 0xC1E0, 0x919C, 0xC1E1, 0x934D, 0xC1E2, 0x9382, 0xC1E3, 0x9328, + 0xC1E4, 0x9375, 0xC1E5, 0x934A, 0xC1E6, 0x9365, 0xC1E7, 0x934B, + 0xC1E8, 0x9318, 0xC1E9, 0x937E, 0xC1EA, 0x936C, 0xC1EB, 0x935B, + 0xC1EC, 0x9370, 0xC1ED, 0x935A, 0xC1EE, 0x9354, 0xC1EF, 0x95CA, + 0xC1F0, 0x95CB, 0xC1F1, 0x95CC, 0xC1F2, 0x95C8, 0xC1F3, 0x95C6, + 0xC1F4, 0x96B1, 0xC1F5, 0x96B8, 0xC1F6, 0x96D6, 0xC1F7, 0x971C, + 0xC1F8, 0x971E, 0xC1F9, 0x97A0, 0xC1FA, 0x97D3, 0xC1FB, 0x9846, + 0xC1FC, 0x98B6, 0xC1FD, 0x9935, 0xC1FE, 0x9A01, 0xC240, 0x99FF, + 0xC241, 0x9BAE, 0xC242, 0x9BAB, 0xC243, 0x9BAA, 0xC244, 0x9BAD, + 0xC245, 0x9D3B, 0xC246, 0x9D3F, 0xC247, 0x9E8B, 0xC248, 0x9ECF, + 0xC249, 0x9EDE, 0xC24A, 0x9EDC, 0xC24B, 0x9EDD, 0xC24C, 0x9EDB, + 0xC24D, 0x9F3E, 0xC24E, 0x9F4B, 0xC24F, 0x53E2, 0xC250, 0x5695, + 0xC251, 0x56AE, 0xC252, 0x58D9, 0xC253, 0x58D8, 0xC254, 0x5B38, + 0xC255, 0x5F5D, 0xC256, 0x61E3, 0xC257, 0x6233, 0xC258, 0x64F4, + 0xC259, 0x64F2, 0xC25A, 0x64FE, 0xC25B, 0x6506, 0xC25C, 0x64FA, + 0xC25D, 0x64FB, 0xC25E, 0x64F7, 0xC25F, 0x65B7, 0xC260, 0x66DC, + 0xC261, 0x6726, 0xC262, 0x6AB3, 0xC263, 0x6AAC, 0xC264, 0x6AC3, + 0xC265, 0x6ABB, 0xC266, 0x6AB8, 0xC267, 0x6AC2, 0xC268, 0x6AAE, + 0xC269, 0x6AAF, 0xC26A, 0x6B5F, 0xC26B, 0x6B78, 0xC26C, 0x6BAF, + 0xC26D, 0x7009, 0xC26E, 0x700B, 0xC26F, 0x6FFE, 0xC270, 0x7006, + 0xC271, 0x6FFA, 0xC272, 0x7011, 0xC273, 0x700F, 0xC274, 0x71FB, + 0xC275, 0x71FC, 0xC276, 0x71FE, 0xC277, 0x71F8, 0xC278, 0x7377, + 0xC279, 0x7375, 0xC27A, 0x74A7, 0xC27B, 0x74BF, 0xC27C, 0x7515, + 0xC27D, 0x7656, 0xC27E, 0x7658, 0xC2A1, 0x7652, 0xC2A2, 0x77BD, + 0xC2A3, 0x77BF, 0xC2A4, 0x77BB, 0xC2A5, 0x77BC, 0xC2A6, 0x790E, + 0xC2A7, 0x79AE, 0xC2A8, 0x7A61, 0xC2A9, 0x7A62, 0xC2AA, 0x7A60, + 0xC2AB, 0x7AC4, 0xC2AC, 0x7AC5, 0xC2AD, 0x7C2B, 0xC2AE, 0x7C27, + 0xC2AF, 0x7C2A, 0xC2B0, 0x7C1E, 0xC2B1, 0x7C23, 0xC2B2, 0x7C21, + 0xC2B3, 0x7CE7, 0xC2B4, 0x7E54, 0xC2B5, 0x7E55, 0xC2B6, 0x7E5E, + 0xC2B7, 0x7E5A, 0xC2B8, 0x7E61, 0xC2B9, 0x7E52, 0xC2BA, 0x7E59, + 0xC2BB, 0x7F48, 0xC2BC, 0x7FF9, 0xC2BD, 0x7FFB, 0xC2BE, 0x8077, + 0xC2BF, 0x8076, 0xC2C0, 0x81CD, 0xC2C1, 0x81CF, 0xC2C2, 0x820A, + 0xC2C3, 0x85CF, 0xC2C4, 0x85A9, 0xC2C5, 0x85CD, 0xC2C6, 0x85D0, + 0xC2C7, 0x85C9, 0xC2C8, 0x85B0, 0xC2C9, 0x85BA, 0xC2CA, 0x85B9, + 0xC2CB, 0x85A6, 0xC2CC, 0x87EF, 0xC2CD, 0x87EC, 0xC2CE, 0x87F2, + 0xC2CF, 0x87E0, 0xC2D0, 0x8986, 0xC2D1, 0x89B2, 0xC2D2, 0x89F4, + 0xC2D3, 0x8B28, 0xC2D4, 0x8B39, 0xC2D5, 0x8B2C, 0xC2D6, 0x8B2B, + 0xC2D7, 0x8C50, 0xC2D8, 0x8D05, 0xC2D9, 0x8E59, 0xC2DA, 0x8E63, + 0xC2DB, 0x8E66, 0xC2DC, 0x8E64, 0xC2DD, 0x8E5F, 0xC2DE, 0x8E55, + 0xC2DF, 0x8EC0, 0xC2E0, 0x8F49, 0xC2E1, 0x8F4D, 0xC2E2, 0x9087, + 0xC2E3, 0x9083, 0xC2E4, 0x9088, 0xC2E5, 0x91AB, 0xC2E6, 0x91AC, + 0xC2E7, 0x91D0, 0xC2E8, 0x9394, 0xC2E9, 0x938A, 0xC2EA, 0x9396, + 0xC2EB, 0x93A2, 0xC2EC, 0x93B3, 0xC2ED, 0x93AE, 0xC2EE, 0x93AC, + 0xC2EF, 0x93B0, 0xC2F0, 0x9398, 0xC2F1, 0x939A, 0xC2F2, 0x9397, + 0xC2F3, 0x95D4, 0xC2F4, 0x95D6, 0xC2F5, 0x95D0, 0xC2F6, 0x95D5, + 0xC2F7, 0x96E2, 0xC2F8, 0x96DC, 0xC2F9, 0x96D9, 0xC2FA, 0x96DB, + 0xC2FB, 0x96DE, 0xC2FC, 0x9724, 0xC2FD, 0x97A3, 0xC2FE, 0x97A6, + 0xC340, 0x97AD, 0xC341, 0x97F9, 0xC342, 0x984D, 0xC343, 0x984F, + 0xC344, 0x984C, 0xC345, 0x984E, 0xC346, 0x9853, 0xC347, 0x98BA, + 0xC348, 0x993E, 0xC349, 0x993F, 0xC34A, 0x993D, 0xC34B, 0x992E, + 0xC34C, 0x99A5, 0xC34D, 0x9A0E, 0xC34E, 0x9AC1, 0xC34F, 0x9B03, + 0xC350, 0x9B06, 0xC351, 0x9B4F, 0xC352, 0x9B4E, 0xC353, 0x9B4D, + 0xC354, 0x9BCA, 0xC355, 0x9BC9, 0xC356, 0x9BFD, 0xC357, 0x9BC8, + 0xC358, 0x9BC0, 0xC359, 0x9D51, 0xC35A, 0x9D5D, 0xC35B, 0x9D60, + 0xC35C, 0x9EE0, 0xC35D, 0x9F15, 0xC35E, 0x9F2C, 0xC35F, 0x5133, + 0xC360, 0x56A5, 0xC361, 0x58DE, 0xC362, 0x58DF, 0xC363, 0x58E2, + 0xC364, 0x5BF5, 0xC365, 0x9F90, 0xC366, 0x5EEC, 0xC367, 0x61F2, + 0xC368, 0x61F7, 0xC369, 0x61F6, 0xC36A, 0x61F5, 0xC36B, 0x6500, + 0xC36C, 0x650F, 0xC36D, 0x66E0, 0xC36E, 0x66DD, 0xC36F, 0x6AE5, + 0xC370, 0x6ADD, 0xC371, 0x6ADA, 0xC372, 0x6AD3, 0xC373, 0x701B, + 0xC374, 0x701F, 0xC375, 0x7028, 0xC376, 0x701A, 0xC377, 0x701D, + 0xC378, 0x7015, 0xC379, 0x7018, 0xC37A, 0x7206, 0xC37B, 0x720D, + 0xC37C, 0x7258, 0xC37D, 0x72A2, 0xC37E, 0x7378, 0xC3A1, 0x737A, + 0xC3A2, 0x74BD, 0xC3A3, 0x74CA, 0xC3A4, 0x74E3, 0xC3A5, 0x7587, + 0xC3A6, 0x7586, 0xC3A7, 0x765F, 0xC3A8, 0x7661, 0xC3A9, 0x77C7, + 0xC3AA, 0x7919, 0xC3AB, 0x79B1, 0xC3AC, 0x7A6B, 0xC3AD, 0x7A69, + 0xC3AE, 0x7C3E, 0xC3AF, 0x7C3F, 0xC3B0, 0x7C38, 0xC3B1, 0x7C3D, + 0xC3B2, 0x7C37, 0xC3B3, 0x7C40, 0xC3B4, 0x7E6B, 0xC3B5, 0x7E6D, + 0xC3B6, 0x7E79, 0xC3B7, 0x7E69, 0xC3B8, 0x7E6A, 0xC3B9, 0x7F85, + 0xC3BA, 0x7E73, 0xC3BB, 0x7FB6, 0xC3BC, 0x7FB9, 0xC3BD, 0x7FB8, + 0xC3BE, 0x81D8, 0xC3BF, 0x85E9, 0xC3C0, 0x85DD, 0xC3C1, 0x85EA, + 0xC3C2, 0x85D5, 0xC3C3, 0x85E4, 0xC3C4, 0x85E5, 0xC3C5, 0x85F7, + 0xC3C6, 0x87FB, 0xC3C7, 0x8805, 0xC3C8, 0x880D, 0xC3C9, 0x87F9, + 0xC3CA, 0x87FE, 0xC3CB, 0x8960, 0xC3CC, 0x895F, 0xC3CD, 0x8956, + 0xC3CE, 0x895E, 0xC3CF, 0x8B41, 0xC3D0, 0x8B5C, 0xC3D1, 0x8B58, + 0xC3D2, 0x8B49, 0xC3D3, 0x8B5A, 0xC3D4, 0x8B4E, 0xC3D5, 0x8B4F, + 0xC3D6, 0x8B46, 0xC3D7, 0x8B59, 0xC3D8, 0x8D08, 0xC3D9, 0x8D0A, + 0xC3DA, 0x8E7C, 0xC3DB, 0x8E72, 0xC3DC, 0x8E87, 0xC3DD, 0x8E76, + 0xC3DE, 0x8E6C, 0xC3DF, 0x8E7A, 0xC3E0, 0x8E74, 0xC3E1, 0x8F54, + 0xC3E2, 0x8F4E, 0xC3E3, 0x8FAD, 0xC3E4, 0x908A, 0xC3E5, 0x908B, + 0xC3E6, 0x91B1, 0xC3E7, 0x91AE, 0xC3E8, 0x93E1, 0xC3E9, 0x93D1, + 0xC3EA, 0x93DF, 0xC3EB, 0x93C3, 0xC3EC, 0x93C8, 0xC3ED, 0x93DC, + 0xC3EE, 0x93DD, 0xC3EF, 0x93D6, 0xC3F0, 0x93E2, 0xC3F1, 0x93CD, + 0xC3F2, 0x93D8, 0xC3F3, 0x93E4, 0xC3F4, 0x93D7, 0xC3F5, 0x93E8, + 0xC3F6, 0x95DC, 0xC3F7, 0x96B4, 0xC3F8, 0x96E3, 0xC3F9, 0x972A, + 0xC3FA, 0x9727, 0xC3FB, 0x9761, 0xC3FC, 0x97DC, 0xC3FD, 0x97FB, + 0xC3FE, 0x985E, 0xC440, 0x9858, 0xC441, 0x985B, 0xC442, 0x98BC, + 0xC443, 0x9945, 0xC444, 0x9949, 0xC445, 0x9A16, 0xC446, 0x9A19, + 0xC447, 0x9B0D, 0xC448, 0x9BE8, 0xC449, 0x9BE7, 0xC44A, 0x9BD6, + 0xC44B, 0x9BDB, 0xC44C, 0x9D89, 0xC44D, 0x9D61, 0xC44E, 0x9D72, + 0xC44F, 0x9D6A, 0xC450, 0x9D6C, 0xC451, 0x9E92, 0xC452, 0x9E97, + 0xC453, 0x9E93, 0xC454, 0x9EB4, 0xC455, 0x52F8, 0xC456, 0x56A8, + 0xC457, 0x56B7, 0xC458, 0x56B6, 0xC459, 0x56B4, 0xC45A, 0x56BC, + 0xC45B, 0x58E4, 0xC45C, 0x5B40, 0xC45D, 0x5B43, 0xC45E, 0x5B7D, + 0xC45F, 0x5BF6, 0xC460, 0x5DC9, 0xC461, 0x61F8, 0xC462, 0x61FA, + 0xC463, 0x6518, 0xC464, 0x6514, 0xC465, 0x6519, 0xC466, 0x66E6, + 0xC467, 0x6727, 0xC468, 0x6AEC, 0xC469, 0x703E, 0xC46A, 0x7030, + 0xC46B, 0x7032, 0xC46C, 0x7210, 0xC46D, 0x737B, 0xC46E, 0x74CF, + 0xC46F, 0x7662, 0xC470, 0x7665, 0xC471, 0x7926, 0xC472, 0x792A, + 0xC473, 0x792C, 0xC474, 0x792B, 0xC475, 0x7AC7, 0xC476, 0x7AF6, + 0xC477, 0x7C4C, 0xC478, 0x7C43, 0xC479, 0x7C4D, 0xC47A, 0x7CEF, + 0xC47B, 0x7CF0, 0xC47C, 0x8FAE, 0xC47D, 0x7E7D, 0xC47E, 0x7E7C, + 0xC4A1, 0x7E82, 0xC4A2, 0x7F4C, 0xC4A3, 0x8000, 0xC4A4, 0x81DA, + 0xC4A5, 0x8266, 0xC4A6, 0x85FB, 0xC4A7, 0x85F9, 0xC4A8, 0x8611, + 0xC4A9, 0x85FA, 0xC4AA, 0x8606, 0xC4AB, 0x860B, 0xC4AC, 0x8607, + 0xC4AD, 0x860A, 0xC4AE, 0x8814, 0xC4AF, 0x8815, 0xC4B0, 0x8964, + 0xC4B1, 0x89BA, 0xC4B2, 0x89F8, 0xC4B3, 0x8B70, 0xC4B4, 0x8B6C, + 0xC4B5, 0x8B66, 0xC4B6, 0x8B6F, 0xC4B7, 0x8B5F, 0xC4B8, 0x8B6B, + 0xC4B9, 0x8D0F, 0xC4BA, 0x8D0D, 0xC4BB, 0x8E89, 0xC4BC, 0x8E81, + 0xC4BD, 0x8E85, 0xC4BE, 0x8E82, 0xC4BF, 0x91B4, 0xC4C0, 0x91CB, + 0xC4C1, 0x9418, 0xC4C2, 0x9403, 0xC4C3, 0x93FD, 0xC4C4, 0x95E1, + 0xC4C5, 0x9730, 0xC4C6, 0x98C4, 0xC4C7, 0x9952, 0xC4C8, 0x9951, + 0xC4C9, 0x99A8, 0xC4CA, 0x9A2B, 0xC4CB, 0x9A30, 0xC4CC, 0x9A37, + 0xC4CD, 0x9A35, 0xC4CE, 0x9C13, 0xC4CF, 0x9C0D, 0xC4D0, 0x9E79, + 0xC4D1, 0x9EB5, 0xC4D2, 0x9EE8, 0xC4D3, 0x9F2F, 0xC4D4, 0x9F5F, + 0xC4D5, 0x9F63, 0xC4D6, 0x9F61, 0xC4D7, 0x5137, 0xC4D8, 0x5138, + 0xC4D9, 0x56C1, 0xC4DA, 0x56C0, 0xC4DB, 0x56C2, 0xC4DC, 0x5914, + 0xC4DD, 0x5C6C, 0xC4DE, 0x5DCD, 0xC4DF, 0x61FC, 0xC4E0, 0x61FE, + 0xC4E1, 0x651D, 0xC4E2, 0x651C, 0xC4E3, 0x6595, 0xC4E4, 0x66E9, + 0xC4E5, 0x6AFB, 0xC4E6, 0x6B04, 0xC4E7, 0x6AFA, 0xC4E8, 0x6BB2, + 0xC4E9, 0x704C, 0xC4EA, 0x721B, 0xC4EB, 0x72A7, 0xC4EC, 0x74D6, + 0xC4ED, 0x74D4, 0xC4EE, 0x7669, 0xC4EF, 0x77D3, 0xC4F0, 0x7C50, + 0xC4F1, 0x7E8F, 0xC4F2, 0x7E8C, 0xC4F3, 0x7FBC, 0xC4F4, 0x8617, + 0xC4F5, 0x862D, 0xC4F6, 0x861A, 0xC4F7, 0x8823, 0xC4F8, 0x8822, + 0xC4F9, 0x8821, 0xC4FA, 0x881F, 0xC4FB, 0x896A, 0xC4FC, 0x896C, + 0xC4FD, 0x89BD, 0xC4FE, 0x8B74, 0xC540, 0x8B77, 0xC541, 0x8B7D, + 0xC542, 0x8D13, 0xC543, 0x8E8A, 0xC544, 0x8E8D, 0xC545, 0x8E8B, + 0xC546, 0x8F5F, 0xC547, 0x8FAF, 0xC548, 0x91BA, 0xC549, 0x942E, + 0xC54A, 0x9433, 0xC54B, 0x9435, 0xC54C, 0x943A, 0xC54D, 0x9438, + 0xC54E, 0x9432, 0xC54F, 0x942B, 0xC550, 0x95E2, 0xC551, 0x9738, + 0xC552, 0x9739, 0xC553, 0x9732, 0xC554, 0x97FF, 0xC555, 0x9867, + 0xC556, 0x9865, 0xC557, 0x9957, 0xC558, 0x9A45, 0xC559, 0x9A43, + 0xC55A, 0x9A40, 0xC55B, 0x9A3E, 0xC55C, 0x9ACF, 0xC55D, 0x9B54, + 0xC55E, 0x9B51, 0xC55F, 0x9C2D, 0xC560, 0x9C25, 0xC561, 0x9DAF, + 0xC562, 0x9DB4, 0xC563, 0x9DC2, 0xC564, 0x9DB8, 0xC565, 0x9E9D, + 0xC566, 0x9EEF, 0xC567, 0x9F19, 0xC568, 0x9F5C, 0xC569, 0x9F66, + 0xC56A, 0x9F67, 0xC56B, 0x513C, 0xC56C, 0x513B, 0xC56D, 0x56C8, + 0xC56E, 0x56CA, 0xC56F, 0x56C9, 0xC570, 0x5B7F, 0xC571, 0x5DD4, + 0xC572, 0x5DD2, 0xC573, 0x5F4E, 0xC574, 0x61FF, 0xC575, 0x6524, + 0xC576, 0x6B0A, 0xC577, 0x6B61, 0xC578, 0x7051, 0xC579, 0x7058, + 0xC57A, 0x7380, 0xC57B, 0x74E4, 0xC57C, 0x758A, 0xC57D, 0x766E, + 0xC57E, 0x766C, 0xC5A1, 0x79B3, 0xC5A2, 0x7C60, 0xC5A3, 0x7C5F, + 0xC5A4, 0x807E, 0xC5A5, 0x807D, 0xC5A6, 0x81DF, 0xC5A7, 0x8972, + 0xC5A8, 0x896F, 0xC5A9, 0x89FC, 0xC5AA, 0x8B80, 0xC5AB, 0x8D16, + 0xC5AC, 0x8D17, 0xC5AD, 0x8E91, 0xC5AE, 0x8E93, 0xC5AF, 0x8F61, + 0xC5B0, 0x9148, 0xC5B1, 0x9444, 0xC5B2, 0x9451, 0xC5B3, 0x9452, + 0xC5B4, 0x973D, 0xC5B5, 0x973E, 0xC5B6, 0x97C3, 0xC5B7, 0x97C1, + 0xC5B8, 0x986B, 0xC5B9, 0x9955, 0xC5BA, 0x9A55, 0xC5BB, 0x9A4D, + 0xC5BC, 0x9AD2, 0xC5BD, 0x9B1A, 0xC5BE, 0x9C49, 0xC5BF, 0x9C31, + 0xC5C0, 0x9C3E, 0xC5C1, 0x9C3B, 0xC5C2, 0x9DD3, 0xC5C3, 0x9DD7, + 0xC5C4, 0x9F34, 0xC5C5, 0x9F6C, 0xC5C6, 0x9F6A, 0xC5C7, 0x9F94, + 0xC5C8, 0x56CC, 0xC5C9, 0x5DD6, 0xC5CA, 0x6200, 0xC5CB, 0x6523, + 0xC5CC, 0x652B, 0xC5CD, 0x652A, 0xC5CE, 0x66EC, 0xC5CF, 0x6B10, + 0xC5D0, 0x74DA, 0xC5D1, 0x7ACA, 0xC5D2, 0x7C64, 0xC5D3, 0x7C63, + 0xC5D4, 0x7C65, 0xC5D5, 0x7E93, 0xC5D6, 0x7E96, 0xC5D7, 0x7E94, + 0xC5D8, 0x81E2, 0xC5D9, 0x8638, 0xC5DA, 0x863F, 0xC5DB, 0x8831, + 0xC5DC, 0x8B8A, 0xC5DD, 0x9090, 0xC5DE, 0x908F, 0xC5DF, 0x9463, + 0xC5E0, 0x9460, 0xC5E1, 0x9464, 0xC5E2, 0x9768, 0xC5E3, 0x986F, + 0xC5E4, 0x995C, 0xC5E5, 0x9A5A, 0xC5E6, 0x9A5B, 0xC5E7, 0x9A57, + 0xC5E8, 0x9AD3, 0xC5E9, 0x9AD4, 0xC5EA, 0x9AD1, 0xC5EB, 0x9C54, + 0xC5EC, 0x9C57, 0xC5ED, 0x9C56, 0xC5EE, 0x9DE5, 0xC5EF, 0x9E9F, + 0xC5F0, 0x9EF4, 0xC5F1, 0x56D1, 0xC5F2, 0x58E9, 0xC5F3, 0x652C, + 0xC5F4, 0x705E, 0xC5F5, 0x7671, 0xC5F6, 0x7672, 0xC5F7, 0x77D7, + 0xC5F8, 0x7F50, 0xC5F9, 0x7F88, 0xC5FA, 0x8836, 0xC5FB, 0x8839, + 0xC5FC, 0x8862, 0xC5FD, 0x8B93, 0xC5FE, 0x8B92, 0xC640, 0x8B96, + 0xC641, 0x8277, 0xC642, 0x8D1B, 0xC643, 0x91C0, 0xC644, 0x946A, + 0xC645, 0x9742, 0xC646, 0x9748, 0xC647, 0x9744, 0xC648, 0x97C6, + 0xC649, 0x9870, 0xC64A, 0x9A5F, 0xC64B, 0x9B22, 0xC64C, 0x9B58, + 0xC64D, 0x9C5F, 0xC64E, 0x9DF9, 0xC64F, 0x9DFA, 0xC650, 0x9E7C, + 0xC651, 0x9E7D, 0xC652, 0x9F07, 0xC653, 0x9F77, 0xC654, 0x9F72, + 0xC655, 0x5EF3, 0xC656, 0x6B16, 0xC657, 0x7063, 0xC658, 0x7C6C, + 0xC659, 0x7C6E, 0xC65A, 0x883B, 0xC65B, 0x89C0, 0xC65C, 0x8EA1, + 0xC65D, 0x91C1, 0xC65E, 0x9472, 0xC65F, 0x9470, 0xC660, 0x9871, + 0xC661, 0x995E, 0xC662, 0x9AD6, 0xC663, 0x9B23, 0xC664, 0x9ECC, + 0xC665, 0x7064, 0xC666, 0x77DA, 0xC667, 0x8B9A, 0xC668, 0x9477, + 0xC669, 0x97C9, 0xC66A, 0x9A62, 0xC66B, 0x9A65, 0xC66C, 0x7E9C, + 0xC66D, 0x8B9C, 0xC66E, 0x8EAA, 0xC66F, 0x91C5, 0xC670, 0x947D, + 0xC671, 0x947E, 0xC672, 0x947C, 0xC673, 0x9C77, 0xC674, 0x9C78, + 0xC675, 0x9EF7, 0xC676, 0x8C54, 0xC677, 0x947F, 0xC678, 0x9E1A, + 0xC679, 0x7228, 0xC67A, 0x9A6A, 0xC67B, 0x9B31, 0xC67C, 0x9E1B, + 0xC67D, 0x9E1E, 0xC67E, 0x7C72, 0xC940, 0x4E42, 0xC941, 0x4E5C, + 0xC942, 0x51F5, 0xC943, 0x531A, 0xC944, 0x5382, 0xC945, 0x4E07, + 0xC946, 0x4E0C, 0xC947, 0x4E47, 0xC948, 0x4E8D, 0xC949, 0x56D7, + 0xC94A, 0xFA0C, 0xC94B, 0x5C6E, 0xC94C, 0x5F73, 0xC94D, 0x4E0F, + 0xC94E, 0x5187, 0xC94F, 0x4E0E, 0xC950, 0x4E2E, 0xC951, 0x4E93, + 0xC952, 0x4EC2, 0xC953, 0x4EC9, 0xC954, 0x4EC8, 0xC955, 0x5198, + 0xC956, 0x52FC, 0xC957, 0x536C, 0xC958, 0x53B9, 0xC959, 0x5720, + 0xC95A, 0x5903, 0xC95B, 0x592C, 0xC95C, 0x5C10, 0xC95D, 0x5DFF, + 0xC95E, 0x65E1, 0xC95F, 0x6BB3, 0xC960, 0x6BCC, 0xC961, 0x6C14, + 0xC962, 0x723F, 0xC963, 0x4E31, 0xC964, 0x4E3C, 0xC965, 0x4EE8, + 0xC966, 0x4EDC, 0xC967, 0x4EE9, 0xC968, 0x4EE1, 0xC969, 0x4EDD, + 0xC96A, 0x4EDA, 0xC96B, 0x520C, 0xC96C, 0x531C, 0xC96D, 0x534C, + 0xC96E, 0x5722, 0xC96F, 0x5723, 0xC970, 0x5917, 0xC971, 0x592F, + 0xC972, 0x5B81, 0xC973, 0x5B84, 0xC974, 0x5C12, 0xC975, 0x5C3B, + 0xC976, 0x5C74, 0xC977, 0x5C73, 0xC978, 0x5E04, 0xC979, 0x5E80, + 0xC97A, 0x5E82, 0xC97B, 0x5FC9, 0xC97C, 0x6209, 0xC97D, 0x6250, + 0xC97E, 0x6C15, 0xC9A1, 0x6C36, 0xC9A2, 0x6C43, 0xC9A3, 0x6C3F, + 0xC9A4, 0x6C3B, 0xC9A5, 0x72AE, 0xC9A6, 0x72B0, 0xC9A7, 0x738A, + 0xC9A8, 0x79B8, 0xC9A9, 0x808A, 0xC9AA, 0x961E, 0xC9AB, 0x4F0E, + 0xC9AC, 0x4F18, 0xC9AD, 0x4F2C, 0xC9AE, 0x4EF5, 0xC9AF, 0x4F14, + 0xC9B0, 0x4EF1, 0xC9B1, 0x4F00, 0xC9B2, 0x4EF7, 0xC9B3, 0x4F08, + 0xC9B4, 0x4F1D, 0xC9B5, 0x4F02, 0xC9B6, 0x4F05, 0xC9B7, 0x4F22, + 0xC9B8, 0x4F13, 0xC9B9, 0x4F04, 0xC9BA, 0x4EF4, 0xC9BB, 0x4F12, + 0xC9BC, 0x51B1, 0xC9BD, 0x5213, 0xC9BE, 0x5209, 0xC9BF, 0x5210, + 0xC9C0, 0x52A6, 0xC9C1, 0x5322, 0xC9C2, 0x531F, 0xC9C3, 0x534D, + 0xC9C4, 0x538A, 0xC9C5, 0x5407, 0xC9C6, 0x56E1, 0xC9C7, 0x56DF, + 0xC9C8, 0x572E, 0xC9C9, 0x572A, 0xC9CA, 0x5734, 0xC9CB, 0x593C, + 0xC9CC, 0x5980, 0xC9CD, 0x597C, 0xC9CE, 0x5985, 0xC9CF, 0x597B, + 0xC9D0, 0x597E, 0xC9D1, 0x5977, 0xC9D2, 0x597F, 0xC9D3, 0x5B56, + 0xC9D4, 0x5C15, 0xC9D5, 0x5C25, 0xC9D6, 0x5C7C, 0xC9D7, 0x5C7A, + 0xC9D8, 0x5C7B, 0xC9D9, 0x5C7E, 0xC9DA, 0x5DDF, 0xC9DB, 0x5E75, + 0xC9DC, 0x5E84, 0xC9DD, 0x5F02, 0xC9DE, 0x5F1A, 0xC9DF, 0x5F74, + 0xC9E0, 0x5FD5, 0xC9E1, 0x5FD4, 0xC9E2, 0x5FCF, 0xC9E3, 0x625C, + 0xC9E4, 0x625E, 0xC9E5, 0x6264, 0xC9E6, 0x6261, 0xC9E7, 0x6266, + 0xC9E8, 0x6262, 0xC9E9, 0x6259, 0xC9EA, 0x6260, 0xC9EB, 0x625A, + 0xC9EC, 0x6265, 0xC9ED, 0x65EF, 0xC9EE, 0x65EE, 0xC9EF, 0x673E, + 0xC9F0, 0x6739, 0xC9F1, 0x6738, 0xC9F2, 0x673B, 0xC9F3, 0x673A, + 0xC9F4, 0x673F, 0xC9F5, 0x673C, 0xC9F6, 0x6733, 0xC9F7, 0x6C18, + 0xC9F8, 0x6C46, 0xC9F9, 0x6C52, 0xC9FA, 0x6C5C, 0xC9FB, 0x6C4F, + 0xC9FC, 0x6C4A, 0xC9FD, 0x6C54, 0xC9FE, 0x6C4B, 0xCA40, 0x6C4C, + 0xCA41, 0x7071, 0xCA42, 0x725E, 0xCA43, 0x72B4, 0xCA44, 0x72B5, + 0xCA45, 0x738E, 0xCA46, 0x752A, 0xCA47, 0x767F, 0xCA48, 0x7A75, + 0xCA49, 0x7F51, 0xCA4A, 0x8278, 0xCA4B, 0x827C, 0xCA4C, 0x8280, + 0xCA4D, 0x827D, 0xCA4E, 0x827F, 0xCA4F, 0x864D, 0xCA50, 0x897E, + 0xCA51, 0x9099, 0xCA52, 0x9097, 0xCA53, 0x9098, 0xCA54, 0x909B, + 0xCA55, 0x9094, 0xCA56, 0x9622, 0xCA57, 0x9624, 0xCA58, 0x9620, + 0xCA59, 0x9623, 0xCA5A, 0x4F56, 0xCA5B, 0x4F3B, 0xCA5C, 0x4F62, + 0xCA5D, 0x4F49, 0xCA5E, 0x4F53, 0xCA5F, 0x4F64, 0xCA60, 0x4F3E, + 0xCA61, 0x4F67, 0xCA62, 0x4F52, 0xCA63, 0x4F5F, 0xCA64, 0x4F41, + 0xCA65, 0x4F58, 0xCA66, 0x4F2D, 0xCA67, 0x4F33, 0xCA68, 0x4F3F, + 0xCA69, 0x4F61, 0xCA6A, 0x518F, 0xCA6B, 0x51B9, 0xCA6C, 0x521C, + 0xCA6D, 0x521E, 0xCA6E, 0x5221, 0xCA6F, 0x52AD, 0xCA70, 0x52AE, + 0xCA71, 0x5309, 0xCA72, 0x5363, 0xCA73, 0x5372, 0xCA74, 0x538E, + 0xCA75, 0x538F, 0xCA76, 0x5430, 0xCA77, 0x5437, 0xCA78, 0x542A, + 0xCA79, 0x5454, 0xCA7A, 0x5445, 0xCA7B, 0x5419, 0xCA7C, 0x541C, + 0xCA7D, 0x5425, 0xCA7E, 0x5418, 0xCAA1, 0x543D, 0xCAA2, 0x544F, + 0xCAA3, 0x5441, 0xCAA4, 0x5428, 0xCAA5, 0x5424, 0xCAA6, 0x5447, + 0xCAA7, 0x56EE, 0xCAA8, 0x56E7, 0xCAA9, 0x56E5, 0xCAAA, 0x5741, + 0xCAAB, 0x5745, 0xCAAC, 0x574C, 0xCAAD, 0x5749, 0xCAAE, 0x574B, + 0xCAAF, 0x5752, 0xCAB0, 0x5906, 0xCAB1, 0x5940, 0xCAB2, 0x59A6, + 0xCAB3, 0x5998, 0xCAB4, 0x59A0, 0xCAB5, 0x5997, 0xCAB6, 0x598E, + 0xCAB7, 0x59A2, 0xCAB8, 0x5990, 0xCAB9, 0x598F, 0xCABA, 0x59A7, + 0xCABB, 0x59A1, 0xCABC, 0x5B8E, 0xCABD, 0x5B92, 0xCABE, 0x5C28, + 0xCABF, 0x5C2A, 0xCAC0, 0x5C8D, 0xCAC1, 0x5C8F, 0xCAC2, 0x5C88, + 0xCAC3, 0x5C8B, 0xCAC4, 0x5C89, 0xCAC5, 0x5C92, 0xCAC6, 0x5C8A, + 0xCAC7, 0x5C86, 0xCAC8, 0x5C93, 0xCAC9, 0x5C95, 0xCACA, 0x5DE0, + 0xCACB, 0x5E0A, 0xCACC, 0x5E0E, 0xCACD, 0x5E8B, 0xCACE, 0x5E89, + 0xCACF, 0x5E8C, 0xCAD0, 0x5E88, 0xCAD1, 0x5E8D, 0xCAD2, 0x5F05, + 0xCAD3, 0x5F1D, 0xCAD4, 0x5F78, 0xCAD5, 0x5F76, 0xCAD6, 0x5FD2, + 0xCAD7, 0x5FD1, 0xCAD8, 0x5FD0, 0xCAD9, 0x5FED, 0xCADA, 0x5FE8, + 0xCADB, 0x5FEE, 0xCADC, 0x5FF3, 0xCADD, 0x5FE1, 0xCADE, 0x5FE4, + 0xCADF, 0x5FE3, 0xCAE0, 0x5FFA, 0xCAE1, 0x5FEF, 0xCAE2, 0x5FF7, + 0xCAE3, 0x5FFB, 0xCAE4, 0x6000, 0xCAE5, 0x5FF4, 0xCAE6, 0x623A, + 0xCAE7, 0x6283, 0xCAE8, 0x628C, 0xCAE9, 0x628E, 0xCAEA, 0x628F, + 0xCAEB, 0x6294, 0xCAEC, 0x6287, 0xCAED, 0x6271, 0xCAEE, 0x627B, + 0xCAEF, 0x627A, 0xCAF0, 0x6270, 0xCAF1, 0x6281, 0xCAF2, 0x6288, + 0xCAF3, 0x6277, 0xCAF4, 0x627D, 0xCAF5, 0x6272, 0xCAF6, 0x6274, + 0xCAF7, 0x6537, 0xCAF8, 0x65F0, 0xCAF9, 0x65F4, 0xCAFA, 0x65F3, + 0xCAFB, 0x65F2, 0xCAFC, 0x65F5, 0xCAFD, 0x6745, 0xCAFE, 0x6747, + 0xCB40, 0x6759, 0xCB41, 0x6755, 0xCB42, 0x674C, 0xCB43, 0x6748, + 0xCB44, 0x675D, 0xCB45, 0x674D, 0xCB46, 0x675A, 0xCB47, 0x674B, + 0xCB48, 0x6BD0, 0xCB49, 0x6C19, 0xCB4A, 0x6C1A, 0xCB4B, 0x6C78, + 0xCB4C, 0x6C67, 0xCB4D, 0x6C6B, 0xCB4E, 0x6C84, 0xCB4F, 0x6C8B, + 0xCB50, 0x6C8F, 0xCB51, 0x6C71, 0xCB52, 0x6C6F, 0xCB53, 0x6C69, + 0xCB54, 0x6C9A, 0xCB55, 0x6C6D, 0xCB56, 0x6C87, 0xCB57, 0x6C95, + 0xCB58, 0x6C9C, 0xCB59, 0x6C66, 0xCB5A, 0x6C73, 0xCB5B, 0x6C65, + 0xCB5C, 0x6C7B, 0xCB5D, 0x6C8E, 0xCB5E, 0x7074, 0xCB5F, 0x707A, + 0xCB60, 0x7263, 0xCB61, 0x72BF, 0xCB62, 0x72BD, 0xCB63, 0x72C3, + 0xCB64, 0x72C6, 0xCB65, 0x72C1, 0xCB66, 0x72BA, 0xCB67, 0x72C5, + 0xCB68, 0x7395, 0xCB69, 0x7397, 0xCB6A, 0x7393, 0xCB6B, 0x7394, + 0xCB6C, 0x7392, 0xCB6D, 0x753A, 0xCB6E, 0x7539, 0xCB6F, 0x7594, + 0xCB70, 0x7595, 0xCB71, 0x7681, 0xCB72, 0x793D, 0xCB73, 0x8034, + 0xCB74, 0x8095, 0xCB75, 0x8099, 0xCB76, 0x8090, 0xCB77, 0x8092, + 0xCB78, 0x809C, 0xCB79, 0x8290, 0xCB7A, 0x828F, 0xCB7B, 0x8285, + 0xCB7C, 0x828E, 0xCB7D, 0x8291, 0xCB7E, 0x8293, 0xCBA1, 0x828A, + 0xCBA2, 0x8283, 0xCBA3, 0x8284, 0xCBA4, 0x8C78, 0xCBA5, 0x8FC9, + 0xCBA6, 0x8FBF, 0xCBA7, 0x909F, 0xCBA8, 0x90A1, 0xCBA9, 0x90A5, + 0xCBAA, 0x909E, 0xCBAB, 0x90A7, 0xCBAC, 0x90A0, 0xCBAD, 0x9630, + 0xCBAE, 0x9628, 0xCBAF, 0x962F, 0xCBB0, 0x962D, 0xCBB1, 0x4E33, + 0xCBB2, 0x4F98, 0xCBB3, 0x4F7C, 0xCBB4, 0x4F85, 0xCBB5, 0x4F7D, + 0xCBB6, 0x4F80, 0xCBB7, 0x4F87, 0xCBB8, 0x4F76, 0xCBB9, 0x4F74, + 0xCBBA, 0x4F89, 0xCBBB, 0x4F84, 0xCBBC, 0x4F77, 0xCBBD, 0x4F4C, + 0xCBBE, 0x4F97, 0xCBBF, 0x4F6A, 0xCBC0, 0x4F9A, 0xCBC1, 0x4F79, + 0xCBC2, 0x4F81, 0xCBC3, 0x4F78, 0xCBC4, 0x4F90, 0xCBC5, 0x4F9C, + 0xCBC6, 0x4F94, 0xCBC7, 0x4F9E, 0xCBC8, 0x4F92, 0xCBC9, 0x4F82, + 0xCBCA, 0x4F95, 0xCBCB, 0x4F6B, 0xCBCC, 0x4F6E, 0xCBCD, 0x519E, + 0xCBCE, 0x51BC, 0xCBCF, 0x51BE, 0xCBD0, 0x5235, 0xCBD1, 0x5232, + 0xCBD2, 0x5233, 0xCBD3, 0x5246, 0xCBD4, 0x5231, 0xCBD5, 0x52BC, + 0xCBD6, 0x530A, 0xCBD7, 0x530B, 0xCBD8, 0x533C, 0xCBD9, 0x5392, + 0xCBDA, 0x5394, 0xCBDB, 0x5487, 0xCBDC, 0x547F, 0xCBDD, 0x5481, + 0xCBDE, 0x5491, 0xCBDF, 0x5482, 0xCBE0, 0x5488, 0xCBE1, 0x546B, + 0xCBE2, 0x547A, 0xCBE3, 0x547E, 0xCBE4, 0x5465, 0xCBE5, 0x546C, + 0xCBE6, 0x5474, 0xCBE7, 0x5466, 0xCBE8, 0x548D, 0xCBE9, 0x546F, + 0xCBEA, 0x5461, 0xCBEB, 0x5460, 0xCBEC, 0x5498, 0xCBED, 0x5463, + 0xCBEE, 0x5467, 0xCBEF, 0x5464, 0xCBF0, 0x56F7, 0xCBF1, 0x56F9, + 0xCBF2, 0x576F, 0xCBF3, 0x5772, 0xCBF4, 0x576D, 0xCBF5, 0x576B, + 0xCBF6, 0x5771, 0xCBF7, 0x5770, 0xCBF8, 0x5776, 0xCBF9, 0x5780, + 0xCBFA, 0x5775, 0xCBFB, 0x577B, 0xCBFC, 0x5773, 0xCBFD, 0x5774, + 0xCBFE, 0x5762, 0xCC40, 0x5768, 0xCC41, 0x577D, 0xCC42, 0x590C, + 0xCC43, 0x5945, 0xCC44, 0x59B5, 0xCC45, 0x59BA, 0xCC46, 0x59CF, + 0xCC47, 0x59CE, 0xCC48, 0x59B2, 0xCC49, 0x59CC, 0xCC4A, 0x59C1, + 0xCC4B, 0x59B6, 0xCC4C, 0x59BC, 0xCC4D, 0x59C3, 0xCC4E, 0x59D6, + 0xCC4F, 0x59B1, 0xCC50, 0x59BD, 0xCC51, 0x59C0, 0xCC52, 0x59C8, + 0xCC53, 0x59B4, 0xCC54, 0x59C7, 0xCC55, 0x5B62, 0xCC56, 0x5B65, + 0xCC57, 0x5B93, 0xCC58, 0x5B95, 0xCC59, 0x5C44, 0xCC5A, 0x5C47, + 0xCC5B, 0x5CAE, 0xCC5C, 0x5CA4, 0xCC5D, 0x5CA0, 0xCC5E, 0x5CB5, + 0xCC5F, 0x5CAF, 0xCC60, 0x5CA8, 0xCC61, 0x5CAC, 0xCC62, 0x5C9F, + 0xCC63, 0x5CA3, 0xCC64, 0x5CAD, 0xCC65, 0x5CA2, 0xCC66, 0x5CAA, + 0xCC67, 0x5CA7, 0xCC68, 0x5C9D, 0xCC69, 0x5CA5, 0xCC6A, 0x5CB6, + 0xCC6B, 0x5CB0, 0xCC6C, 0x5CA6, 0xCC6D, 0x5E17, 0xCC6E, 0x5E14, + 0xCC6F, 0x5E19, 0xCC70, 0x5F28, 0xCC71, 0x5F22, 0xCC72, 0x5F23, + 0xCC73, 0x5F24, 0xCC74, 0x5F54, 0xCC75, 0x5F82, 0xCC76, 0x5F7E, + 0xCC77, 0x5F7D, 0xCC78, 0x5FDE, 0xCC79, 0x5FE5, 0xCC7A, 0x602D, + 0xCC7B, 0x6026, 0xCC7C, 0x6019, 0xCC7D, 0x6032, 0xCC7E, 0x600B, + 0xCCA1, 0x6034, 0xCCA2, 0x600A, 0xCCA3, 0x6017, 0xCCA4, 0x6033, + 0xCCA5, 0x601A, 0xCCA6, 0x601E, 0xCCA7, 0x602C, 0xCCA8, 0x6022, + 0xCCA9, 0x600D, 0xCCAA, 0x6010, 0xCCAB, 0x602E, 0xCCAC, 0x6013, + 0xCCAD, 0x6011, 0xCCAE, 0x600C, 0xCCAF, 0x6009, 0xCCB0, 0x601C, + 0xCCB1, 0x6214, 0xCCB2, 0x623D, 0xCCB3, 0x62AD, 0xCCB4, 0x62B4, + 0xCCB5, 0x62D1, 0xCCB6, 0x62BE, 0xCCB7, 0x62AA, 0xCCB8, 0x62B6, + 0xCCB9, 0x62CA, 0xCCBA, 0x62AE, 0xCCBB, 0x62B3, 0xCCBC, 0x62AF, + 0xCCBD, 0x62BB, 0xCCBE, 0x62A9, 0xCCBF, 0x62B0, 0xCCC0, 0x62B8, + 0xCCC1, 0x653D, 0xCCC2, 0x65A8, 0xCCC3, 0x65BB, 0xCCC4, 0x6609, + 0xCCC5, 0x65FC, 0xCCC6, 0x6604, 0xCCC7, 0x6612, 0xCCC8, 0x6608, + 0xCCC9, 0x65FB, 0xCCCA, 0x6603, 0xCCCB, 0x660B, 0xCCCC, 0x660D, + 0xCCCD, 0x6605, 0xCCCE, 0x65FD, 0xCCCF, 0x6611, 0xCCD0, 0x6610, + 0xCCD1, 0x66F6, 0xCCD2, 0x670A, 0xCCD3, 0x6785, 0xCCD4, 0x676C, + 0xCCD5, 0x678E, 0xCCD6, 0x6792, 0xCCD7, 0x6776, 0xCCD8, 0x677B, + 0xCCD9, 0x6798, 0xCCDA, 0x6786, 0xCCDB, 0x6784, 0xCCDC, 0x6774, + 0xCCDD, 0x678D, 0xCCDE, 0x678C, 0xCCDF, 0x677A, 0xCCE0, 0x679F, + 0xCCE1, 0x6791, 0xCCE2, 0x6799, 0xCCE3, 0x6783, 0xCCE4, 0x677D, + 0xCCE5, 0x6781, 0xCCE6, 0x6778, 0xCCE7, 0x6779, 0xCCE8, 0x6794, + 0xCCE9, 0x6B25, 0xCCEA, 0x6B80, 0xCCEB, 0x6B7E, 0xCCEC, 0x6BDE, + 0xCCED, 0x6C1D, 0xCCEE, 0x6C93, 0xCCEF, 0x6CEC, 0xCCF0, 0x6CEB, + 0xCCF1, 0x6CEE, 0xCCF2, 0x6CD9, 0xCCF3, 0x6CB6, 0xCCF4, 0x6CD4, + 0xCCF5, 0x6CAD, 0xCCF6, 0x6CE7, 0xCCF7, 0x6CB7, 0xCCF8, 0x6CD0, + 0xCCF9, 0x6CC2, 0xCCFA, 0x6CBA, 0xCCFB, 0x6CC3, 0xCCFC, 0x6CC6, + 0xCCFD, 0x6CED, 0xCCFE, 0x6CF2, 0xCD40, 0x6CD2, 0xCD41, 0x6CDD, + 0xCD42, 0x6CB4, 0xCD43, 0x6C8A, 0xCD44, 0x6C9D, 0xCD45, 0x6C80, + 0xCD46, 0x6CDE, 0xCD47, 0x6CC0, 0xCD48, 0x6D30, 0xCD49, 0x6CCD, + 0xCD4A, 0x6CC7, 0xCD4B, 0x6CB0, 0xCD4C, 0x6CF9, 0xCD4D, 0x6CCF, + 0xCD4E, 0x6CE9, 0xCD4F, 0x6CD1, 0xCD50, 0x7094, 0xCD51, 0x7098, + 0xCD52, 0x7085, 0xCD53, 0x7093, 0xCD54, 0x7086, 0xCD55, 0x7084, + 0xCD56, 0x7091, 0xCD57, 0x7096, 0xCD58, 0x7082, 0xCD59, 0x709A, + 0xCD5A, 0x7083, 0xCD5B, 0x726A, 0xCD5C, 0x72D6, 0xCD5D, 0x72CB, + 0xCD5E, 0x72D8, 0xCD5F, 0x72C9, 0xCD60, 0x72DC, 0xCD61, 0x72D2, + 0xCD62, 0x72D4, 0xCD63, 0x72DA, 0xCD64, 0x72CC, 0xCD65, 0x72D1, + 0xCD66, 0x73A4, 0xCD67, 0x73A1, 0xCD68, 0x73AD, 0xCD69, 0x73A6, + 0xCD6A, 0x73A2, 0xCD6B, 0x73A0, 0xCD6C, 0x73AC, 0xCD6D, 0x739D, + 0xCD6E, 0x74DD, 0xCD6F, 0x74E8, 0xCD70, 0x753F, 0xCD71, 0x7540, + 0xCD72, 0x753E, 0xCD73, 0x758C, 0xCD74, 0x7598, 0xCD75, 0x76AF, + 0xCD76, 0x76F3, 0xCD77, 0x76F1, 0xCD78, 0x76F0, 0xCD79, 0x76F5, + 0xCD7A, 0x77F8, 0xCD7B, 0x77FC, 0xCD7C, 0x77F9, 0xCD7D, 0x77FB, + 0xCD7E, 0x77FA, 0xCDA1, 0x77F7, 0xCDA2, 0x7942, 0xCDA3, 0x793F, + 0xCDA4, 0x79C5, 0xCDA5, 0x7A78, 0xCDA6, 0x7A7B, 0xCDA7, 0x7AFB, + 0xCDA8, 0x7C75, 0xCDA9, 0x7CFD, 0xCDAA, 0x8035, 0xCDAB, 0x808F, + 0xCDAC, 0x80AE, 0xCDAD, 0x80A3, 0xCDAE, 0x80B8, 0xCDAF, 0x80B5, + 0xCDB0, 0x80AD, 0xCDB1, 0x8220, 0xCDB2, 0x82A0, 0xCDB3, 0x82C0, + 0xCDB4, 0x82AB, 0xCDB5, 0x829A, 0xCDB6, 0x8298, 0xCDB7, 0x829B, + 0xCDB8, 0x82B5, 0xCDB9, 0x82A7, 0xCDBA, 0x82AE, 0xCDBB, 0x82BC, + 0xCDBC, 0x829E, 0xCDBD, 0x82BA, 0xCDBE, 0x82B4, 0xCDBF, 0x82A8, + 0xCDC0, 0x82A1, 0xCDC1, 0x82A9, 0xCDC2, 0x82C2, 0xCDC3, 0x82A4, + 0xCDC4, 0x82C3, 0xCDC5, 0x82B6, 0xCDC6, 0x82A2, 0xCDC7, 0x8670, + 0xCDC8, 0x866F, 0xCDC9, 0x866D, 0xCDCA, 0x866E, 0xCDCB, 0x8C56, + 0xCDCC, 0x8FD2, 0xCDCD, 0x8FCB, 0xCDCE, 0x8FD3, 0xCDCF, 0x8FCD, + 0xCDD0, 0x8FD6, 0xCDD1, 0x8FD5, 0xCDD2, 0x8FD7, 0xCDD3, 0x90B2, + 0xCDD4, 0x90B4, 0xCDD5, 0x90AF, 0xCDD6, 0x90B3, 0xCDD7, 0x90B0, + 0xCDD8, 0x9639, 0xCDD9, 0x963D, 0xCDDA, 0x963C, 0xCDDB, 0x963A, + 0xCDDC, 0x9643, 0xCDDD, 0x4FCD, 0xCDDE, 0x4FC5, 0xCDDF, 0x4FD3, + 0xCDE0, 0x4FB2, 0xCDE1, 0x4FC9, 0xCDE2, 0x4FCB, 0xCDE3, 0x4FC1, + 0xCDE4, 0x4FD4, 0xCDE5, 0x4FDC, 0xCDE6, 0x4FD9, 0xCDE7, 0x4FBB, + 0xCDE8, 0x4FB3, 0xCDE9, 0x4FDB, 0xCDEA, 0x4FC7, 0xCDEB, 0x4FD6, + 0xCDEC, 0x4FBA, 0xCDED, 0x4FC0, 0xCDEE, 0x4FB9, 0xCDEF, 0x4FEC, + 0xCDF0, 0x5244, 0xCDF1, 0x5249, 0xCDF2, 0x52C0, 0xCDF3, 0x52C2, + 0xCDF4, 0x533D, 0xCDF5, 0x537C, 0xCDF6, 0x5397, 0xCDF7, 0x5396, + 0xCDF8, 0x5399, 0xCDF9, 0x5398, 0xCDFA, 0x54BA, 0xCDFB, 0x54A1, + 0xCDFC, 0x54AD, 0xCDFD, 0x54A5, 0xCDFE, 0x54CF, 0xCE40, 0x54C3, + 0xCE41, 0x830D, 0xCE42, 0x54B7, 0xCE43, 0x54AE, 0xCE44, 0x54D6, + 0xCE45, 0x54B6, 0xCE46, 0x54C5, 0xCE47, 0x54C6, 0xCE48, 0x54A0, + 0xCE49, 0x5470, 0xCE4A, 0x54BC, 0xCE4B, 0x54A2, 0xCE4C, 0x54BE, + 0xCE4D, 0x5472, 0xCE4E, 0x54DE, 0xCE4F, 0x54B0, 0xCE50, 0x57B5, + 0xCE51, 0x579E, 0xCE52, 0x579F, 0xCE53, 0x57A4, 0xCE54, 0x578C, + 0xCE55, 0x5797, 0xCE56, 0x579D, 0xCE57, 0x579B, 0xCE58, 0x5794, + 0xCE59, 0x5798, 0xCE5A, 0x578F, 0xCE5B, 0x5799, 0xCE5C, 0x57A5, + 0xCE5D, 0x579A, 0xCE5E, 0x5795, 0xCE5F, 0x58F4, 0xCE60, 0x590D, + 0xCE61, 0x5953, 0xCE62, 0x59E1, 0xCE63, 0x59DE, 0xCE64, 0x59EE, + 0xCE65, 0x5A00, 0xCE66, 0x59F1, 0xCE67, 0x59DD, 0xCE68, 0x59FA, + 0xCE69, 0x59FD, 0xCE6A, 0x59FC, 0xCE6B, 0x59F6, 0xCE6C, 0x59E4, + 0xCE6D, 0x59F2, 0xCE6E, 0x59F7, 0xCE6F, 0x59DB, 0xCE70, 0x59E9, + 0xCE71, 0x59F3, 0xCE72, 0x59F5, 0xCE73, 0x59E0, 0xCE74, 0x59FE, + 0xCE75, 0x59F4, 0xCE76, 0x59ED, 0xCE77, 0x5BA8, 0xCE78, 0x5C4C, + 0xCE79, 0x5CD0, 0xCE7A, 0x5CD8, 0xCE7B, 0x5CCC, 0xCE7C, 0x5CD7, + 0xCE7D, 0x5CCB, 0xCE7E, 0x5CDB, 0xCEA1, 0x5CDE, 0xCEA2, 0x5CDA, + 0xCEA3, 0x5CC9, 0xCEA4, 0x5CC7, 0xCEA5, 0x5CCA, 0xCEA6, 0x5CD6, + 0xCEA7, 0x5CD3, 0xCEA8, 0x5CD4, 0xCEA9, 0x5CCF, 0xCEAA, 0x5CC8, + 0xCEAB, 0x5CC6, 0xCEAC, 0x5CCE, 0xCEAD, 0x5CDF, 0xCEAE, 0x5CF8, + 0xCEAF, 0x5DF9, 0xCEB0, 0x5E21, 0xCEB1, 0x5E22, 0xCEB2, 0x5E23, + 0xCEB3, 0x5E20, 0xCEB4, 0x5E24, 0xCEB5, 0x5EB0, 0xCEB6, 0x5EA4, + 0xCEB7, 0x5EA2, 0xCEB8, 0x5E9B, 0xCEB9, 0x5EA3, 0xCEBA, 0x5EA5, + 0xCEBB, 0x5F07, 0xCEBC, 0x5F2E, 0xCEBD, 0x5F56, 0xCEBE, 0x5F86, + 0xCEBF, 0x6037, 0xCEC0, 0x6039, 0xCEC1, 0x6054, 0xCEC2, 0x6072, + 0xCEC3, 0x605E, 0xCEC4, 0x6045, 0xCEC5, 0x6053, 0xCEC6, 0x6047, + 0xCEC7, 0x6049, 0xCEC8, 0x605B, 0xCEC9, 0x604C, 0xCECA, 0x6040, + 0xCECB, 0x6042, 0xCECC, 0x605F, 0xCECD, 0x6024, 0xCECE, 0x6044, + 0xCECF, 0x6058, 0xCED0, 0x6066, 0xCED1, 0x606E, 0xCED2, 0x6242, + 0xCED3, 0x6243, 0xCED4, 0x62CF, 0xCED5, 0x630D, 0xCED6, 0x630B, + 0xCED7, 0x62F5, 0xCED8, 0x630E, 0xCED9, 0x6303, 0xCEDA, 0x62EB, + 0xCEDB, 0x62F9, 0xCEDC, 0x630F, 0xCEDD, 0x630C, 0xCEDE, 0x62F8, + 0xCEDF, 0x62F6, 0xCEE0, 0x6300, 0xCEE1, 0x6313, 0xCEE2, 0x6314, + 0xCEE3, 0x62FA, 0xCEE4, 0x6315, 0xCEE5, 0x62FB, 0xCEE6, 0x62F0, + 0xCEE7, 0x6541, 0xCEE8, 0x6543, 0xCEE9, 0x65AA, 0xCEEA, 0x65BF, + 0xCEEB, 0x6636, 0xCEEC, 0x6621, 0xCEED, 0x6632, 0xCEEE, 0x6635, + 0xCEEF, 0x661C, 0xCEF0, 0x6626, 0xCEF1, 0x6622, 0xCEF2, 0x6633, + 0xCEF3, 0x662B, 0xCEF4, 0x663A, 0xCEF5, 0x661D, 0xCEF6, 0x6634, + 0xCEF7, 0x6639, 0xCEF8, 0x662E, 0xCEF9, 0x670F, 0xCEFA, 0x6710, + 0xCEFB, 0x67C1, 0xCEFC, 0x67F2, 0xCEFD, 0x67C8, 0xCEFE, 0x67BA, + 0xCF40, 0x67DC, 0xCF41, 0x67BB, 0xCF42, 0x67F8, 0xCF43, 0x67D8, + 0xCF44, 0x67C0, 0xCF45, 0x67B7, 0xCF46, 0x67C5, 0xCF47, 0x67EB, + 0xCF48, 0x67E4, 0xCF49, 0x67DF, 0xCF4A, 0x67B5, 0xCF4B, 0x67CD, + 0xCF4C, 0x67B3, 0xCF4D, 0x67F7, 0xCF4E, 0x67F6, 0xCF4F, 0x67EE, + 0xCF50, 0x67E3, 0xCF51, 0x67C2, 0xCF52, 0x67B9, 0xCF53, 0x67CE, + 0xCF54, 0x67E7, 0xCF55, 0x67F0, 0xCF56, 0x67B2, 0xCF57, 0x67FC, + 0xCF58, 0x67C6, 0xCF59, 0x67ED, 0xCF5A, 0x67CC, 0xCF5B, 0x67AE, + 0xCF5C, 0x67E6, 0xCF5D, 0x67DB, 0xCF5E, 0x67FA, 0xCF5F, 0x67C9, + 0xCF60, 0x67CA, 0xCF61, 0x67C3, 0xCF62, 0x67EA, 0xCF63, 0x67CB, + 0xCF64, 0x6B28, 0xCF65, 0x6B82, 0xCF66, 0x6B84, 0xCF67, 0x6BB6, + 0xCF68, 0x6BD6, 0xCF69, 0x6BD8, 0xCF6A, 0x6BE0, 0xCF6B, 0x6C20, + 0xCF6C, 0x6C21, 0xCF6D, 0x6D28, 0xCF6E, 0x6D34, 0xCF6F, 0x6D2D, + 0xCF70, 0x6D1F, 0xCF71, 0x6D3C, 0xCF72, 0x6D3F, 0xCF73, 0x6D12, + 0xCF74, 0x6D0A, 0xCF75, 0x6CDA, 0xCF76, 0x6D33, 0xCF77, 0x6D04, + 0xCF78, 0x6D19, 0xCF79, 0x6D3A, 0xCF7A, 0x6D1A, 0xCF7B, 0x6D11, + 0xCF7C, 0x6D00, 0xCF7D, 0x6D1D, 0xCF7E, 0x6D42, 0xCFA1, 0x6D01, + 0xCFA2, 0x6D18, 0xCFA3, 0x6D37, 0xCFA4, 0x6D03, 0xCFA5, 0x6D0F, + 0xCFA6, 0x6D40, 0xCFA7, 0x6D07, 0xCFA8, 0x6D20, 0xCFA9, 0x6D2C, + 0xCFAA, 0x6D08, 0xCFAB, 0x6D22, 0xCFAC, 0x6D09, 0xCFAD, 0x6D10, + 0xCFAE, 0x70B7, 0xCFAF, 0x709F, 0xCFB0, 0x70BE, 0xCFB1, 0x70B1, + 0xCFB2, 0x70B0, 0xCFB3, 0x70A1, 0xCFB4, 0x70B4, 0xCFB5, 0x70B5, + 0xCFB6, 0x70A9, 0xCFB7, 0x7241, 0xCFB8, 0x7249, 0xCFB9, 0x724A, + 0xCFBA, 0x726C, 0xCFBB, 0x7270, 0xCFBC, 0x7273, 0xCFBD, 0x726E, + 0xCFBE, 0x72CA, 0xCFBF, 0x72E4, 0xCFC0, 0x72E8, 0xCFC1, 0x72EB, + 0xCFC2, 0x72DF, 0xCFC3, 0x72EA, 0xCFC4, 0x72E6, 0xCFC5, 0x72E3, + 0xCFC6, 0x7385, 0xCFC7, 0x73CC, 0xCFC8, 0x73C2, 0xCFC9, 0x73C8, + 0xCFCA, 0x73C5, 0xCFCB, 0x73B9, 0xCFCC, 0x73B6, 0xCFCD, 0x73B5, + 0xCFCE, 0x73B4, 0xCFCF, 0x73EB, 0xCFD0, 0x73BF, 0xCFD1, 0x73C7, + 0xCFD2, 0x73BE, 0xCFD3, 0x73C3, 0xCFD4, 0x73C6, 0xCFD5, 0x73B8, + 0xCFD6, 0x73CB, 0xCFD7, 0x74EC, 0xCFD8, 0x74EE, 0xCFD9, 0x752E, + 0xCFDA, 0x7547, 0xCFDB, 0x7548, 0xCFDC, 0x75A7, 0xCFDD, 0x75AA, + 0xCFDE, 0x7679, 0xCFDF, 0x76C4, 0xCFE0, 0x7708, 0xCFE1, 0x7703, + 0xCFE2, 0x7704, 0xCFE3, 0x7705, 0xCFE4, 0x770A, 0xCFE5, 0x76F7, + 0xCFE6, 0x76FB, 0xCFE7, 0x76FA, 0xCFE8, 0x77E7, 0xCFE9, 0x77E8, + 0xCFEA, 0x7806, 0xCFEB, 0x7811, 0xCFEC, 0x7812, 0xCFED, 0x7805, + 0xCFEE, 0x7810, 0xCFEF, 0x780F, 0xCFF0, 0x780E, 0xCFF1, 0x7809, + 0xCFF2, 0x7803, 0xCFF3, 0x7813, 0xCFF4, 0x794A, 0xCFF5, 0x794C, + 0xCFF6, 0x794B, 0xCFF7, 0x7945, 0xCFF8, 0x7944, 0xCFF9, 0x79D5, + 0xCFFA, 0x79CD, 0xCFFB, 0x79CF, 0xCFFC, 0x79D6, 0xCFFD, 0x79CE, + 0xCFFE, 0x7A80, 0xD040, 0x7A7E, 0xD041, 0x7AD1, 0xD042, 0x7B00, + 0xD043, 0x7B01, 0xD044, 0x7C7A, 0xD045, 0x7C78, 0xD046, 0x7C79, + 0xD047, 0x7C7F, 0xD048, 0x7C80, 0xD049, 0x7C81, 0xD04A, 0x7D03, + 0xD04B, 0x7D08, 0xD04C, 0x7D01, 0xD04D, 0x7F58, 0xD04E, 0x7F91, + 0xD04F, 0x7F8D, 0xD050, 0x7FBE, 0xD051, 0x8007, 0xD052, 0x800E, + 0xD053, 0x800F, 0xD054, 0x8014, 0xD055, 0x8037, 0xD056, 0x80D8, + 0xD057, 0x80C7, 0xD058, 0x80E0, 0xD059, 0x80D1, 0xD05A, 0x80C8, + 0xD05B, 0x80C2, 0xD05C, 0x80D0, 0xD05D, 0x80C5, 0xD05E, 0x80E3, + 0xD05F, 0x80D9, 0xD060, 0x80DC, 0xD061, 0x80CA, 0xD062, 0x80D5, + 0xD063, 0x80C9, 0xD064, 0x80CF, 0xD065, 0x80D7, 0xD066, 0x80E6, + 0xD067, 0x80CD, 0xD068, 0x81FF, 0xD069, 0x8221, 0xD06A, 0x8294, + 0xD06B, 0x82D9, 0xD06C, 0x82FE, 0xD06D, 0x82F9, 0xD06E, 0x8307, + 0xD06F, 0x82E8, 0xD070, 0x8300, 0xD071, 0x82D5, 0xD072, 0x833A, + 0xD073, 0x82EB, 0xD074, 0x82D6, 0xD075, 0x82F4, 0xD076, 0x82EC, + 0xD077, 0x82E1, 0xD078, 0x82F2, 0xD079, 0x82F5, 0xD07A, 0x830C, + 0xD07B, 0x82FB, 0xD07C, 0x82F6, 0xD07D, 0x82F0, 0xD07E, 0x82EA, + 0xD0A1, 0x82E4, 0xD0A2, 0x82E0, 0xD0A3, 0x82FA, 0xD0A4, 0x82F3, + 0xD0A5, 0x82ED, 0xD0A6, 0x8677, 0xD0A7, 0x8674, 0xD0A8, 0x867C, + 0xD0A9, 0x8673, 0xD0AA, 0x8841, 0xD0AB, 0x884E, 0xD0AC, 0x8867, + 0xD0AD, 0x886A, 0xD0AE, 0x8869, 0xD0AF, 0x89D3, 0xD0B0, 0x8A04, + 0xD0B1, 0x8A07, 0xD0B2, 0x8D72, 0xD0B3, 0x8FE3, 0xD0B4, 0x8FE1, + 0xD0B5, 0x8FEE, 0xD0B6, 0x8FE0, 0xD0B7, 0x90F1, 0xD0B8, 0x90BD, + 0xD0B9, 0x90BF, 0xD0BA, 0x90D5, 0xD0BB, 0x90C5, 0xD0BC, 0x90BE, + 0xD0BD, 0x90C7, 0xD0BE, 0x90CB, 0xD0BF, 0x90C8, 0xD0C0, 0x91D4, + 0xD0C1, 0x91D3, 0xD0C2, 0x9654, 0xD0C3, 0x964F, 0xD0C4, 0x9651, + 0xD0C5, 0x9653, 0xD0C6, 0x964A, 0xD0C7, 0x964E, 0xD0C8, 0x501E, + 0xD0C9, 0x5005, 0xD0CA, 0x5007, 0xD0CB, 0x5013, 0xD0CC, 0x5022, + 0xD0CD, 0x5030, 0xD0CE, 0x501B, 0xD0CF, 0x4FF5, 0xD0D0, 0x4FF4, + 0xD0D1, 0x5033, 0xD0D2, 0x5037, 0xD0D3, 0x502C, 0xD0D4, 0x4FF6, + 0xD0D5, 0x4FF7, 0xD0D6, 0x5017, 0xD0D7, 0x501C, 0xD0D8, 0x5020, + 0xD0D9, 0x5027, 0xD0DA, 0x5035, 0xD0DB, 0x502F, 0xD0DC, 0x5031, + 0xD0DD, 0x500E, 0xD0DE, 0x515A, 0xD0DF, 0x5194, 0xD0E0, 0x5193, + 0xD0E1, 0x51CA, 0xD0E2, 0x51C4, 0xD0E3, 0x51C5, 0xD0E4, 0x51C8, + 0xD0E5, 0x51CE, 0xD0E6, 0x5261, 0xD0E7, 0x525A, 0xD0E8, 0x5252, + 0xD0E9, 0x525E, 0xD0EA, 0x525F, 0xD0EB, 0x5255, 0xD0EC, 0x5262, + 0xD0ED, 0x52CD, 0xD0EE, 0x530E, 0xD0EF, 0x539E, 0xD0F0, 0x5526, + 0xD0F1, 0x54E2, 0xD0F2, 0x5517, 0xD0F3, 0x5512, 0xD0F4, 0x54E7, + 0xD0F5, 0x54F3, 0xD0F6, 0x54E4, 0xD0F7, 0x551A, 0xD0F8, 0x54FF, + 0xD0F9, 0x5504, 0xD0FA, 0x5508, 0xD0FB, 0x54EB, 0xD0FC, 0x5511, + 0xD0FD, 0x5505, 0xD0FE, 0x54F1, 0xD140, 0x550A, 0xD141, 0x54FB, + 0xD142, 0x54F7, 0xD143, 0x54F8, 0xD144, 0x54E0, 0xD145, 0x550E, + 0xD146, 0x5503, 0xD147, 0x550B, 0xD148, 0x5701, 0xD149, 0x5702, + 0xD14A, 0x57CC, 0xD14B, 0x5832, 0xD14C, 0x57D5, 0xD14D, 0x57D2, + 0xD14E, 0x57BA, 0xD14F, 0x57C6, 0xD150, 0x57BD, 0xD151, 0x57BC, + 0xD152, 0x57B8, 0xD153, 0x57B6, 0xD154, 0x57BF, 0xD155, 0x57C7, + 0xD156, 0x57D0, 0xD157, 0x57B9, 0xD158, 0x57C1, 0xD159, 0x590E, + 0xD15A, 0x594A, 0xD15B, 0x5A19, 0xD15C, 0x5A16, 0xD15D, 0x5A2D, + 0xD15E, 0x5A2E, 0xD15F, 0x5A15, 0xD160, 0x5A0F, 0xD161, 0x5A17, + 0xD162, 0x5A0A, 0xD163, 0x5A1E, 0xD164, 0x5A33, 0xD165, 0x5B6C, + 0xD166, 0x5BA7, 0xD167, 0x5BAD, 0xD168, 0x5BAC, 0xD169, 0x5C03, + 0xD16A, 0x5C56, 0xD16B, 0x5C54, 0xD16C, 0x5CEC, 0xD16D, 0x5CFF, + 0xD16E, 0x5CEE, 0xD16F, 0x5CF1, 0xD170, 0x5CF7, 0xD171, 0x5D00, + 0xD172, 0x5CF9, 0xD173, 0x5E29, 0xD174, 0x5E28, 0xD175, 0x5EA8, + 0xD176, 0x5EAE, 0xD177, 0x5EAA, 0xD178, 0x5EAC, 0xD179, 0x5F33, + 0xD17A, 0x5F30, 0xD17B, 0x5F67, 0xD17C, 0x605D, 0xD17D, 0x605A, + 0xD17E, 0x6067, 0xD1A1, 0x6041, 0xD1A2, 0x60A2, 0xD1A3, 0x6088, + 0xD1A4, 0x6080, 0xD1A5, 0x6092, 0xD1A6, 0x6081, 0xD1A7, 0x609D, + 0xD1A8, 0x6083, 0xD1A9, 0x6095, 0xD1AA, 0x609B, 0xD1AB, 0x6097, + 0xD1AC, 0x6087, 0xD1AD, 0x609C, 0xD1AE, 0x608E, 0xD1AF, 0x6219, + 0xD1B0, 0x6246, 0xD1B1, 0x62F2, 0xD1B2, 0x6310, 0xD1B3, 0x6356, + 0xD1B4, 0x632C, 0xD1B5, 0x6344, 0xD1B6, 0x6345, 0xD1B7, 0x6336, + 0xD1B8, 0x6343, 0xD1B9, 0x63E4, 0xD1BA, 0x6339, 0xD1BB, 0x634B, + 0xD1BC, 0x634A, 0xD1BD, 0x633C, 0xD1BE, 0x6329, 0xD1BF, 0x6341, + 0xD1C0, 0x6334, 0xD1C1, 0x6358, 0xD1C2, 0x6354, 0xD1C3, 0x6359, + 0xD1C4, 0x632D, 0xD1C5, 0x6347, 0xD1C6, 0x6333, 0xD1C7, 0x635A, + 0xD1C8, 0x6351, 0xD1C9, 0x6338, 0xD1CA, 0x6357, 0xD1CB, 0x6340, + 0xD1CC, 0x6348, 0xD1CD, 0x654A, 0xD1CE, 0x6546, 0xD1CF, 0x65C6, + 0xD1D0, 0x65C3, 0xD1D1, 0x65C4, 0xD1D2, 0x65C2, 0xD1D3, 0x664A, + 0xD1D4, 0x665F, 0xD1D5, 0x6647, 0xD1D6, 0x6651, 0xD1D7, 0x6712, + 0xD1D8, 0x6713, 0xD1D9, 0x681F, 0xD1DA, 0x681A, 0xD1DB, 0x6849, + 0xD1DC, 0x6832, 0xD1DD, 0x6833, 0xD1DE, 0x683B, 0xD1DF, 0x684B, + 0xD1E0, 0x684F, 0xD1E1, 0x6816, 0xD1E2, 0x6831, 0xD1E3, 0x681C, + 0xD1E4, 0x6835, 0xD1E5, 0x682B, 0xD1E6, 0x682D, 0xD1E7, 0x682F, + 0xD1E8, 0x684E, 0xD1E9, 0x6844, 0xD1EA, 0x6834, 0xD1EB, 0x681D, + 0xD1EC, 0x6812, 0xD1ED, 0x6814, 0xD1EE, 0x6826, 0xD1EF, 0x6828, + 0xD1F0, 0x682E, 0xD1F1, 0x684D, 0xD1F2, 0x683A, 0xD1F3, 0x6825, + 0xD1F4, 0x6820, 0xD1F5, 0x6B2C, 0xD1F6, 0x6B2F, 0xD1F7, 0x6B2D, + 0xD1F8, 0x6B31, 0xD1F9, 0x6B34, 0xD1FA, 0x6B6D, 0xD1FB, 0x8082, + 0xD1FC, 0x6B88, 0xD1FD, 0x6BE6, 0xD1FE, 0x6BE4, 0xD240, 0x6BE8, + 0xD241, 0x6BE3, 0xD242, 0x6BE2, 0xD243, 0x6BE7, 0xD244, 0x6C25, + 0xD245, 0x6D7A, 0xD246, 0x6D63, 0xD247, 0x6D64, 0xD248, 0x6D76, + 0xD249, 0x6D0D, 0xD24A, 0x6D61, 0xD24B, 0x6D92, 0xD24C, 0x6D58, + 0xD24D, 0x6D62, 0xD24E, 0x6D6D, 0xD24F, 0x6D6F, 0xD250, 0x6D91, + 0xD251, 0x6D8D, 0xD252, 0x6DEF, 0xD253, 0x6D7F, 0xD254, 0x6D86, + 0xD255, 0x6D5E, 0xD256, 0x6D67, 0xD257, 0x6D60, 0xD258, 0x6D97, + 0xD259, 0x6D70, 0xD25A, 0x6D7C, 0xD25B, 0x6D5F, 0xD25C, 0x6D82, + 0xD25D, 0x6D98, 0xD25E, 0x6D2F, 0xD25F, 0x6D68, 0xD260, 0x6D8B, + 0xD261, 0x6D7E, 0xD262, 0x6D80, 0xD263, 0x6D84, 0xD264, 0x6D16, + 0xD265, 0x6D83, 0xD266, 0x6D7B, 0xD267, 0x6D7D, 0xD268, 0x6D75, + 0xD269, 0x6D90, 0xD26A, 0x70DC, 0xD26B, 0x70D3, 0xD26C, 0x70D1, + 0xD26D, 0x70DD, 0xD26E, 0x70CB, 0xD26F, 0x7F39, 0xD270, 0x70E2, + 0xD271, 0x70D7, 0xD272, 0x70D2, 0xD273, 0x70DE, 0xD274, 0x70E0, + 0xD275, 0x70D4, 0xD276, 0x70CD, 0xD277, 0x70C5, 0xD278, 0x70C6, + 0xD279, 0x70C7, 0xD27A, 0x70DA, 0xD27B, 0x70CE, 0xD27C, 0x70E1, + 0xD27D, 0x7242, 0xD27E, 0x7278, 0xD2A1, 0x7277, 0xD2A2, 0x7276, + 0xD2A3, 0x7300, 0xD2A4, 0x72FA, 0xD2A5, 0x72F4, 0xD2A6, 0x72FE, + 0xD2A7, 0x72F6, 0xD2A8, 0x72F3, 0xD2A9, 0x72FB, 0xD2AA, 0x7301, + 0xD2AB, 0x73D3, 0xD2AC, 0x73D9, 0xD2AD, 0x73E5, 0xD2AE, 0x73D6, + 0xD2AF, 0x73BC, 0xD2B0, 0x73E7, 0xD2B1, 0x73E3, 0xD2B2, 0x73E9, + 0xD2B3, 0x73DC, 0xD2B4, 0x73D2, 0xD2B5, 0x73DB, 0xD2B6, 0x73D4, + 0xD2B7, 0x73DD, 0xD2B8, 0x73DA, 0xD2B9, 0x73D7, 0xD2BA, 0x73D8, + 0xD2BB, 0x73E8, 0xD2BC, 0x74DE, 0xD2BD, 0x74DF, 0xD2BE, 0x74F4, + 0xD2BF, 0x74F5, 0xD2C0, 0x7521, 0xD2C1, 0x755B, 0xD2C2, 0x755F, + 0xD2C3, 0x75B0, 0xD2C4, 0x75C1, 0xD2C5, 0x75BB, 0xD2C6, 0x75C4, + 0xD2C7, 0x75C0, 0xD2C8, 0x75BF, 0xD2C9, 0x75B6, 0xD2CA, 0x75BA, + 0xD2CB, 0x768A, 0xD2CC, 0x76C9, 0xD2CD, 0x771D, 0xD2CE, 0x771B, + 0xD2CF, 0x7710, 0xD2D0, 0x7713, 0xD2D1, 0x7712, 0xD2D2, 0x7723, + 0xD2D3, 0x7711, 0xD2D4, 0x7715, 0xD2D5, 0x7719, 0xD2D6, 0x771A, + 0xD2D7, 0x7722, 0xD2D8, 0x7727, 0xD2D9, 0x7823, 0xD2DA, 0x782C, + 0xD2DB, 0x7822, 0xD2DC, 0x7835, 0xD2DD, 0x782F, 0xD2DE, 0x7828, + 0xD2DF, 0x782E, 0xD2E0, 0x782B, 0xD2E1, 0x7821, 0xD2E2, 0x7829, + 0xD2E3, 0x7833, 0xD2E4, 0x782A, 0xD2E5, 0x7831, 0xD2E6, 0x7954, + 0xD2E7, 0x795B, 0xD2E8, 0x794F, 0xD2E9, 0x795C, 0xD2EA, 0x7953, + 0xD2EB, 0x7952, 0xD2EC, 0x7951, 0xD2ED, 0x79EB, 0xD2EE, 0x79EC, + 0xD2EF, 0x79E0, 0xD2F0, 0x79EE, 0xD2F1, 0x79ED, 0xD2F2, 0x79EA, + 0xD2F3, 0x79DC, 0xD2F4, 0x79DE, 0xD2F5, 0x79DD, 0xD2F6, 0x7A86, + 0xD2F7, 0x7A89, 0xD2F8, 0x7A85, 0xD2F9, 0x7A8B, 0xD2FA, 0x7A8C, + 0xD2FB, 0x7A8A, 0xD2FC, 0x7A87, 0xD2FD, 0x7AD8, 0xD2FE, 0x7B10, + 0xD340, 0x7B04, 0xD341, 0x7B13, 0xD342, 0x7B05, 0xD343, 0x7B0F, + 0xD344, 0x7B08, 0xD345, 0x7B0A, 0xD346, 0x7B0E, 0xD347, 0x7B09, + 0xD348, 0x7B12, 0xD349, 0x7C84, 0xD34A, 0x7C91, 0xD34B, 0x7C8A, + 0xD34C, 0x7C8C, 0xD34D, 0x7C88, 0xD34E, 0x7C8D, 0xD34F, 0x7C85, + 0xD350, 0x7D1E, 0xD351, 0x7D1D, 0xD352, 0x7D11, 0xD353, 0x7D0E, + 0xD354, 0x7D18, 0xD355, 0x7D16, 0xD356, 0x7D13, 0xD357, 0x7D1F, + 0xD358, 0x7D12, 0xD359, 0x7D0F, 0xD35A, 0x7D0C, 0xD35B, 0x7F5C, + 0xD35C, 0x7F61, 0xD35D, 0x7F5E, 0xD35E, 0x7F60, 0xD35F, 0x7F5D, + 0xD360, 0x7F5B, 0xD361, 0x7F96, 0xD362, 0x7F92, 0xD363, 0x7FC3, + 0xD364, 0x7FC2, 0xD365, 0x7FC0, 0xD366, 0x8016, 0xD367, 0x803E, + 0xD368, 0x8039, 0xD369, 0x80FA, 0xD36A, 0x80F2, 0xD36B, 0x80F9, + 0xD36C, 0x80F5, 0xD36D, 0x8101, 0xD36E, 0x80FB, 0xD36F, 0x8100, + 0xD370, 0x8201, 0xD371, 0x822F, 0xD372, 0x8225, 0xD373, 0x8333, + 0xD374, 0x832D, 0xD375, 0x8344, 0xD376, 0x8319, 0xD377, 0x8351, + 0xD378, 0x8325, 0xD379, 0x8356, 0xD37A, 0x833F, 0xD37B, 0x8341, + 0xD37C, 0x8326, 0xD37D, 0x831C, 0xD37E, 0x8322, 0xD3A1, 0x8342, + 0xD3A2, 0x834E, 0xD3A3, 0x831B, 0xD3A4, 0x832A, 0xD3A5, 0x8308, + 0xD3A6, 0x833C, 0xD3A7, 0x834D, 0xD3A8, 0x8316, 0xD3A9, 0x8324, + 0xD3AA, 0x8320, 0xD3AB, 0x8337, 0xD3AC, 0x832F, 0xD3AD, 0x8329, + 0xD3AE, 0x8347, 0xD3AF, 0x8345, 0xD3B0, 0x834C, 0xD3B1, 0x8353, + 0xD3B2, 0x831E, 0xD3B3, 0x832C, 0xD3B4, 0x834B, 0xD3B5, 0x8327, + 0xD3B6, 0x8348, 0xD3B7, 0x8653, 0xD3B8, 0x8652, 0xD3B9, 0x86A2, + 0xD3BA, 0x86A8, 0xD3BB, 0x8696, 0xD3BC, 0x868D, 0xD3BD, 0x8691, + 0xD3BE, 0x869E, 0xD3BF, 0x8687, 0xD3C0, 0x8697, 0xD3C1, 0x8686, + 0xD3C2, 0x868B, 0xD3C3, 0x869A, 0xD3C4, 0x8685, 0xD3C5, 0x86A5, + 0xD3C6, 0x8699, 0xD3C7, 0x86A1, 0xD3C8, 0x86A7, 0xD3C9, 0x8695, + 0xD3CA, 0x8698, 0xD3CB, 0x868E, 0xD3CC, 0x869D, 0xD3CD, 0x8690, + 0xD3CE, 0x8694, 0xD3CF, 0x8843, 0xD3D0, 0x8844, 0xD3D1, 0x886D, + 0xD3D2, 0x8875, 0xD3D3, 0x8876, 0xD3D4, 0x8872, 0xD3D5, 0x8880, + 0xD3D6, 0x8871, 0xD3D7, 0x887F, 0xD3D8, 0x886F, 0xD3D9, 0x8883, + 0xD3DA, 0x887E, 0xD3DB, 0x8874, 0xD3DC, 0x887C, 0xD3DD, 0x8A12, + 0xD3DE, 0x8C47, 0xD3DF, 0x8C57, 0xD3E0, 0x8C7B, 0xD3E1, 0x8CA4, + 0xD3E2, 0x8CA3, 0xD3E3, 0x8D76, 0xD3E4, 0x8D78, 0xD3E5, 0x8DB5, + 0xD3E6, 0x8DB7, 0xD3E7, 0x8DB6, 0xD3E8, 0x8ED1, 0xD3E9, 0x8ED3, + 0xD3EA, 0x8FFE, 0xD3EB, 0x8FF5, 0xD3EC, 0x9002, 0xD3ED, 0x8FFF, + 0xD3EE, 0x8FFB, 0xD3EF, 0x9004, 0xD3F0, 0x8FFC, 0xD3F1, 0x8FF6, + 0xD3F2, 0x90D6, 0xD3F3, 0x90E0, 0xD3F4, 0x90D9, 0xD3F5, 0x90DA, + 0xD3F6, 0x90E3, 0xD3F7, 0x90DF, 0xD3F8, 0x90E5, 0xD3F9, 0x90D8, + 0xD3FA, 0x90DB, 0xD3FB, 0x90D7, 0xD3FC, 0x90DC, 0xD3FD, 0x90E4, + 0xD3FE, 0x9150, 0xD440, 0x914E, 0xD441, 0x914F, 0xD442, 0x91D5, + 0xD443, 0x91E2, 0xD444, 0x91DA, 0xD445, 0x965C, 0xD446, 0x965F, + 0xD447, 0x96BC, 0xD448, 0x98E3, 0xD449, 0x9ADF, 0xD44A, 0x9B2F, + 0xD44B, 0x4E7F, 0xD44C, 0x5070, 0xD44D, 0x506A, 0xD44E, 0x5061, + 0xD44F, 0x505E, 0xD450, 0x5060, 0xD451, 0x5053, 0xD452, 0x504B, + 0xD453, 0x505D, 0xD454, 0x5072, 0xD455, 0x5048, 0xD456, 0x504D, + 0xD457, 0x5041, 0xD458, 0x505B, 0xD459, 0x504A, 0xD45A, 0x5062, + 0xD45B, 0x5015, 0xD45C, 0x5045, 0xD45D, 0x505F, 0xD45E, 0x5069, + 0xD45F, 0x506B, 0xD460, 0x5063, 0xD461, 0x5064, 0xD462, 0x5046, + 0xD463, 0x5040, 0xD464, 0x506E, 0xD465, 0x5073, 0xD466, 0x5057, + 0xD467, 0x5051, 0xD468, 0x51D0, 0xD469, 0x526B, 0xD46A, 0x526D, + 0xD46B, 0x526C, 0xD46C, 0x526E, 0xD46D, 0x52D6, 0xD46E, 0x52D3, + 0xD46F, 0x532D, 0xD470, 0x539C, 0xD471, 0x5575, 0xD472, 0x5576, + 0xD473, 0x553C, 0xD474, 0x554D, 0xD475, 0x5550, 0xD476, 0x5534, + 0xD477, 0x552A, 0xD478, 0x5551, 0xD479, 0x5562, 0xD47A, 0x5536, + 0xD47B, 0x5535, 0xD47C, 0x5530, 0xD47D, 0x5552, 0xD47E, 0x5545, + 0xD4A1, 0x550C, 0xD4A2, 0x5532, 0xD4A3, 0x5565, 0xD4A4, 0x554E, + 0xD4A5, 0x5539, 0xD4A6, 0x5548, 0xD4A7, 0x552D, 0xD4A8, 0x553B, + 0xD4A9, 0x5540, 0xD4AA, 0x554B, 0xD4AB, 0x570A, 0xD4AC, 0x5707, + 0xD4AD, 0x57FB, 0xD4AE, 0x5814, 0xD4AF, 0x57E2, 0xD4B0, 0x57F6, + 0xD4B1, 0x57DC, 0xD4B2, 0x57F4, 0xD4B3, 0x5800, 0xD4B4, 0x57ED, + 0xD4B5, 0x57FD, 0xD4B6, 0x5808, 0xD4B7, 0x57F8, 0xD4B8, 0x580B, + 0xD4B9, 0x57F3, 0xD4BA, 0x57CF, 0xD4BB, 0x5807, 0xD4BC, 0x57EE, + 0xD4BD, 0x57E3, 0xD4BE, 0x57F2, 0xD4BF, 0x57E5, 0xD4C0, 0x57EC, + 0xD4C1, 0x57E1, 0xD4C2, 0x580E, 0xD4C3, 0x57FC, 0xD4C4, 0x5810, + 0xD4C5, 0x57E7, 0xD4C6, 0x5801, 0xD4C7, 0x580C, 0xD4C8, 0x57F1, + 0xD4C9, 0x57E9, 0xD4CA, 0x57F0, 0xD4CB, 0x580D, 0xD4CC, 0x5804, + 0xD4CD, 0x595C, 0xD4CE, 0x5A60, 0xD4CF, 0x5A58, 0xD4D0, 0x5A55, + 0xD4D1, 0x5A67, 0xD4D2, 0x5A5E, 0xD4D3, 0x5A38, 0xD4D4, 0x5A35, + 0xD4D5, 0x5A6D, 0xD4D6, 0x5A50, 0xD4D7, 0x5A5F, 0xD4D8, 0x5A65, + 0xD4D9, 0x5A6C, 0xD4DA, 0x5A53, 0xD4DB, 0x5A64, 0xD4DC, 0x5A57, + 0xD4DD, 0x5A43, 0xD4DE, 0x5A5D, 0xD4DF, 0x5A52, 0xD4E0, 0x5A44, + 0xD4E1, 0x5A5B, 0xD4E2, 0x5A48, 0xD4E3, 0x5A8E, 0xD4E4, 0x5A3E, + 0xD4E5, 0x5A4D, 0xD4E6, 0x5A39, 0xD4E7, 0x5A4C, 0xD4E8, 0x5A70, + 0xD4E9, 0x5A69, 0xD4EA, 0x5A47, 0xD4EB, 0x5A51, 0xD4EC, 0x5A56, + 0xD4ED, 0x5A42, 0xD4EE, 0x5A5C, 0xD4EF, 0x5B72, 0xD4F0, 0x5B6E, + 0xD4F1, 0x5BC1, 0xD4F2, 0x5BC0, 0xD4F3, 0x5C59, 0xD4F4, 0x5D1E, + 0xD4F5, 0x5D0B, 0xD4F6, 0x5D1D, 0xD4F7, 0x5D1A, 0xD4F8, 0x5D20, + 0xD4F9, 0x5D0C, 0xD4FA, 0x5D28, 0xD4FB, 0x5D0D, 0xD4FC, 0x5D26, + 0xD4FD, 0x5D25, 0xD4FE, 0x5D0F, 0xD540, 0x5D30, 0xD541, 0x5D12, + 0xD542, 0x5D23, 0xD543, 0x5D1F, 0xD544, 0x5D2E, 0xD545, 0x5E3E, + 0xD546, 0x5E34, 0xD547, 0x5EB1, 0xD548, 0x5EB4, 0xD549, 0x5EB9, + 0xD54A, 0x5EB2, 0xD54B, 0x5EB3, 0xD54C, 0x5F36, 0xD54D, 0x5F38, + 0xD54E, 0x5F9B, 0xD54F, 0x5F96, 0xD550, 0x5F9F, 0xD551, 0x608A, + 0xD552, 0x6090, 0xD553, 0x6086, 0xD554, 0x60BE, 0xD555, 0x60B0, + 0xD556, 0x60BA, 0xD557, 0x60D3, 0xD558, 0x60D4, 0xD559, 0x60CF, + 0xD55A, 0x60E4, 0xD55B, 0x60D9, 0xD55C, 0x60DD, 0xD55D, 0x60C8, + 0xD55E, 0x60B1, 0xD55F, 0x60DB, 0xD560, 0x60B7, 0xD561, 0x60CA, + 0xD562, 0x60BF, 0xD563, 0x60C3, 0xD564, 0x60CD, 0xD565, 0x60C0, + 0xD566, 0x6332, 0xD567, 0x6365, 0xD568, 0x638A, 0xD569, 0x6382, + 0xD56A, 0x637D, 0xD56B, 0x63BD, 0xD56C, 0x639E, 0xD56D, 0x63AD, + 0xD56E, 0x639D, 0xD56F, 0x6397, 0xD570, 0x63AB, 0xD571, 0x638E, + 0xD572, 0x636F, 0xD573, 0x6387, 0xD574, 0x6390, 0xD575, 0x636E, + 0xD576, 0x63AF, 0xD577, 0x6375, 0xD578, 0x639C, 0xD579, 0x636D, + 0xD57A, 0x63AE, 0xD57B, 0x637C, 0xD57C, 0x63A4, 0xD57D, 0x633B, + 0xD57E, 0x639F, 0xD5A1, 0x6378, 0xD5A2, 0x6385, 0xD5A3, 0x6381, + 0xD5A4, 0x6391, 0xD5A5, 0x638D, 0xD5A6, 0x6370, 0xD5A7, 0x6553, + 0xD5A8, 0x65CD, 0xD5A9, 0x6665, 0xD5AA, 0x6661, 0xD5AB, 0x665B, + 0xD5AC, 0x6659, 0xD5AD, 0x665C, 0xD5AE, 0x6662, 0xD5AF, 0x6718, + 0xD5B0, 0x6879, 0xD5B1, 0x6887, 0xD5B2, 0x6890, 0xD5B3, 0x689C, + 0xD5B4, 0x686D, 0xD5B5, 0x686E, 0xD5B6, 0x68AE, 0xD5B7, 0x68AB, + 0xD5B8, 0x6956, 0xD5B9, 0x686F, 0xD5BA, 0x68A3, 0xD5BB, 0x68AC, + 0xD5BC, 0x68A9, 0xD5BD, 0x6875, 0xD5BE, 0x6874, 0xD5BF, 0x68B2, + 0xD5C0, 0x688F, 0xD5C1, 0x6877, 0xD5C2, 0x6892, 0xD5C3, 0x687C, + 0xD5C4, 0x686B, 0xD5C5, 0x6872, 0xD5C6, 0x68AA, 0xD5C7, 0x6880, + 0xD5C8, 0x6871, 0xD5C9, 0x687E, 0xD5CA, 0x689B, 0xD5CB, 0x6896, + 0xD5CC, 0x688B, 0xD5CD, 0x68A0, 0xD5CE, 0x6889, 0xD5CF, 0x68A4, + 0xD5D0, 0x6878, 0xD5D1, 0x687B, 0xD5D2, 0x6891, 0xD5D3, 0x688C, + 0xD5D4, 0x688A, 0xD5D5, 0x687D, 0xD5D6, 0x6B36, 0xD5D7, 0x6B33, + 0xD5D8, 0x6B37, 0xD5D9, 0x6B38, 0xD5DA, 0x6B91, 0xD5DB, 0x6B8F, + 0xD5DC, 0x6B8D, 0xD5DD, 0x6B8E, 0xD5DE, 0x6B8C, 0xD5DF, 0x6C2A, + 0xD5E0, 0x6DC0, 0xD5E1, 0x6DAB, 0xD5E2, 0x6DB4, 0xD5E3, 0x6DB3, + 0xD5E4, 0x6E74, 0xD5E5, 0x6DAC, 0xD5E6, 0x6DE9, 0xD5E7, 0x6DE2, + 0xD5E8, 0x6DB7, 0xD5E9, 0x6DF6, 0xD5EA, 0x6DD4, 0xD5EB, 0x6E00, + 0xD5EC, 0x6DC8, 0xD5ED, 0x6DE0, 0xD5EE, 0x6DDF, 0xD5EF, 0x6DD6, + 0xD5F0, 0x6DBE, 0xD5F1, 0x6DE5, 0xD5F2, 0x6DDC, 0xD5F3, 0x6DDD, + 0xD5F4, 0x6DDB, 0xD5F5, 0x6DF4, 0xD5F6, 0x6DCA, 0xD5F7, 0x6DBD, + 0xD5F8, 0x6DED, 0xD5F9, 0x6DF0, 0xD5FA, 0x6DBA, 0xD5FB, 0x6DD5, + 0xD5FC, 0x6DC2, 0xD5FD, 0x6DCF, 0xD5FE, 0x6DC9, 0xD640, 0x6DD0, + 0xD641, 0x6DF2, 0xD642, 0x6DD3, 0xD643, 0x6DFD, 0xD644, 0x6DD7, + 0xD645, 0x6DCD, 0xD646, 0x6DE3, 0xD647, 0x6DBB, 0xD648, 0x70FA, + 0xD649, 0x710D, 0xD64A, 0x70F7, 0xD64B, 0x7117, 0xD64C, 0x70F4, + 0xD64D, 0x710C, 0xD64E, 0x70F0, 0xD64F, 0x7104, 0xD650, 0x70F3, + 0xD651, 0x7110, 0xD652, 0x70FC, 0xD653, 0x70FF, 0xD654, 0x7106, + 0xD655, 0x7113, 0xD656, 0x7100, 0xD657, 0x70F8, 0xD658, 0x70F6, + 0xD659, 0x710B, 0xD65A, 0x7102, 0xD65B, 0x710E, 0xD65C, 0x727E, + 0xD65D, 0x727B, 0xD65E, 0x727C, 0xD65F, 0x727F, 0xD660, 0x731D, + 0xD661, 0x7317, 0xD662, 0x7307, 0xD663, 0x7311, 0xD664, 0x7318, + 0xD665, 0x730A, 0xD666, 0x7308, 0xD667, 0x72FF, 0xD668, 0x730F, + 0xD669, 0x731E, 0xD66A, 0x7388, 0xD66B, 0x73F6, 0xD66C, 0x73F8, + 0xD66D, 0x73F5, 0xD66E, 0x7404, 0xD66F, 0x7401, 0xD670, 0x73FD, + 0xD671, 0x7407, 0xD672, 0x7400, 0xD673, 0x73FA, 0xD674, 0x73FC, + 0xD675, 0x73FF, 0xD676, 0x740C, 0xD677, 0x740B, 0xD678, 0x73F4, + 0xD679, 0x7408, 0xD67A, 0x7564, 0xD67B, 0x7563, 0xD67C, 0x75CE, + 0xD67D, 0x75D2, 0xD67E, 0x75CF, 0xD6A1, 0x75CB, 0xD6A2, 0x75CC, + 0xD6A3, 0x75D1, 0xD6A4, 0x75D0, 0xD6A5, 0x768F, 0xD6A6, 0x7689, + 0xD6A7, 0x76D3, 0xD6A8, 0x7739, 0xD6A9, 0x772F, 0xD6AA, 0x772D, + 0xD6AB, 0x7731, 0xD6AC, 0x7732, 0xD6AD, 0x7734, 0xD6AE, 0x7733, + 0xD6AF, 0x773D, 0xD6B0, 0x7725, 0xD6B1, 0x773B, 0xD6B2, 0x7735, + 0xD6B3, 0x7848, 0xD6B4, 0x7852, 0xD6B5, 0x7849, 0xD6B6, 0x784D, + 0xD6B7, 0x784A, 0xD6B8, 0x784C, 0xD6B9, 0x7826, 0xD6BA, 0x7845, + 0xD6BB, 0x7850, 0xD6BC, 0x7964, 0xD6BD, 0x7967, 0xD6BE, 0x7969, + 0xD6BF, 0x796A, 0xD6C0, 0x7963, 0xD6C1, 0x796B, 0xD6C2, 0x7961, + 0xD6C3, 0x79BB, 0xD6C4, 0x79FA, 0xD6C5, 0x79F8, 0xD6C6, 0x79F6, + 0xD6C7, 0x79F7, 0xD6C8, 0x7A8F, 0xD6C9, 0x7A94, 0xD6CA, 0x7A90, + 0xD6CB, 0x7B35, 0xD6CC, 0x7B47, 0xD6CD, 0x7B34, 0xD6CE, 0x7B25, + 0xD6CF, 0x7B30, 0xD6D0, 0x7B22, 0xD6D1, 0x7B24, 0xD6D2, 0x7B33, + 0xD6D3, 0x7B18, 0xD6D4, 0x7B2A, 0xD6D5, 0x7B1D, 0xD6D6, 0x7B31, + 0xD6D7, 0x7B2B, 0xD6D8, 0x7B2D, 0xD6D9, 0x7B2F, 0xD6DA, 0x7B32, + 0xD6DB, 0x7B38, 0xD6DC, 0x7B1A, 0xD6DD, 0x7B23, 0xD6DE, 0x7C94, + 0xD6DF, 0x7C98, 0xD6E0, 0x7C96, 0xD6E1, 0x7CA3, 0xD6E2, 0x7D35, + 0xD6E3, 0x7D3D, 0xD6E4, 0x7D38, 0xD6E5, 0x7D36, 0xD6E6, 0x7D3A, + 0xD6E7, 0x7D45, 0xD6E8, 0x7D2C, 0xD6E9, 0x7D29, 0xD6EA, 0x7D41, + 0xD6EB, 0x7D47, 0xD6EC, 0x7D3E, 0xD6ED, 0x7D3F, 0xD6EE, 0x7D4A, + 0xD6EF, 0x7D3B, 0xD6F0, 0x7D28, 0xD6F1, 0x7F63, 0xD6F2, 0x7F95, + 0xD6F3, 0x7F9C, 0xD6F4, 0x7F9D, 0xD6F5, 0x7F9B, 0xD6F6, 0x7FCA, + 0xD6F7, 0x7FCB, 0xD6F8, 0x7FCD, 0xD6F9, 0x7FD0, 0xD6FA, 0x7FD1, + 0xD6FB, 0x7FC7, 0xD6FC, 0x7FCF, 0xD6FD, 0x7FC9, 0xD6FE, 0x801F, + 0xD740, 0x801E, 0xD741, 0x801B, 0xD742, 0x8047, 0xD743, 0x8043, + 0xD744, 0x8048, 0xD745, 0x8118, 0xD746, 0x8125, 0xD747, 0x8119, + 0xD748, 0x811B, 0xD749, 0x812D, 0xD74A, 0x811F, 0xD74B, 0x812C, + 0xD74C, 0x811E, 0xD74D, 0x8121, 0xD74E, 0x8115, 0xD74F, 0x8127, + 0xD750, 0x811D, 0xD751, 0x8122, 0xD752, 0x8211, 0xD753, 0x8238, + 0xD754, 0x8233, 0xD755, 0x823A, 0xD756, 0x8234, 0xD757, 0x8232, + 0xD758, 0x8274, 0xD759, 0x8390, 0xD75A, 0x83A3, 0xD75B, 0x83A8, + 0xD75C, 0x838D, 0xD75D, 0x837A, 0xD75E, 0x8373, 0xD75F, 0x83A4, + 0xD760, 0x8374, 0xD761, 0x838F, 0xD762, 0x8381, 0xD763, 0x8395, + 0xD764, 0x8399, 0xD765, 0x8375, 0xD766, 0x8394, 0xD767, 0x83A9, + 0xD768, 0x837D, 0xD769, 0x8383, 0xD76A, 0x838C, 0xD76B, 0x839D, + 0xD76C, 0x839B, 0xD76D, 0x83AA, 0xD76E, 0x838B, 0xD76F, 0x837E, + 0xD770, 0x83A5, 0xD771, 0x83AF, 0xD772, 0x8388, 0xD773, 0x8397, + 0xD774, 0x83B0, 0xD775, 0x837F, 0xD776, 0x83A6, 0xD777, 0x8387, + 0xD778, 0x83AE, 0xD779, 0x8376, 0xD77A, 0x839A, 0xD77B, 0x8659, + 0xD77C, 0x8656, 0xD77D, 0x86BF, 0xD77E, 0x86B7, 0xD7A1, 0x86C2, + 0xD7A2, 0x86C1, 0xD7A3, 0x86C5, 0xD7A4, 0x86BA, 0xD7A5, 0x86B0, + 0xD7A6, 0x86C8, 0xD7A7, 0x86B9, 0xD7A8, 0x86B3, 0xD7A9, 0x86B8, + 0xD7AA, 0x86CC, 0xD7AB, 0x86B4, 0xD7AC, 0x86BB, 0xD7AD, 0x86BC, + 0xD7AE, 0x86C3, 0xD7AF, 0x86BD, 0xD7B0, 0x86BE, 0xD7B1, 0x8852, + 0xD7B2, 0x8889, 0xD7B3, 0x8895, 0xD7B4, 0x88A8, 0xD7B5, 0x88A2, + 0xD7B6, 0x88AA, 0xD7B7, 0x889A, 0xD7B8, 0x8891, 0xD7B9, 0x88A1, + 0xD7BA, 0x889F, 0xD7BB, 0x8898, 0xD7BC, 0x88A7, 0xD7BD, 0x8899, + 0xD7BE, 0x889B, 0xD7BF, 0x8897, 0xD7C0, 0x88A4, 0xD7C1, 0x88AC, + 0xD7C2, 0x888C, 0xD7C3, 0x8893, 0xD7C4, 0x888E, 0xD7C5, 0x8982, + 0xD7C6, 0x89D6, 0xD7C7, 0x89D9, 0xD7C8, 0x89D5, 0xD7C9, 0x8A30, + 0xD7CA, 0x8A27, 0xD7CB, 0x8A2C, 0xD7CC, 0x8A1E, 0xD7CD, 0x8C39, + 0xD7CE, 0x8C3B, 0xD7CF, 0x8C5C, 0xD7D0, 0x8C5D, 0xD7D1, 0x8C7D, + 0xD7D2, 0x8CA5, 0xD7D3, 0x8D7D, 0xD7D4, 0x8D7B, 0xD7D5, 0x8D79, + 0xD7D6, 0x8DBC, 0xD7D7, 0x8DC2, 0xD7D8, 0x8DB9, 0xD7D9, 0x8DBF, + 0xD7DA, 0x8DC1, 0xD7DB, 0x8ED8, 0xD7DC, 0x8EDE, 0xD7DD, 0x8EDD, + 0xD7DE, 0x8EDC, 0xD7DF, 0x8ED7, 0xD7E0, 0x8EE0, 0xD7E1, 0x8EE1, + 0xD7E2, 0x9024, 0xD7E3, 0x900B, 0xD7E4, 0x9011, 0xD7E5, 0x901C, + 0xD7E6, 0x900C, 0xD7E7, 0x9021, 0xD7E8, 0x90EF, 0xD7E9, 0x90EA, + 0xD7EA, 0x90F0, 0xD7EB, 0x90F4, 0xD7EC, 0x90F2, 0xD7ED, 0x90F3, + 0xD7EE, 0x90D4, 0xD7EF, 0x90EB, 0xD7F0, 0x90EC, 0xD7F1, 0x90E9, + 0xD7F2, 0x9156, 0xD7F3, 0x9158, 0xD7F4, 0x915A, 0xD7F5, 0x9153, + 0xD7F6, 0x9155, 0xD7F7, 0x91EC, 0xD7F8, 0x91F4, 0xD7F9, 0x91F1, + 0xD7FA, 0x91F3, 0xD7FB, 0x91F8, 0xD7FC, 0x91E4, 0xD7FD, 0x91F9, + 0xD7FE, 0x91EA, 0xD840, 0x91EB, 0xD841, 0x91F7, 0xD842, 0x91E8, + 0xD843, 0x91EE, 0xD844, 0x957A, 0xD845, 0x9586, 0xD846, 0x9588, + 0xD847, 0x967C, 0xD848, 0x966D, 0xD849, 0x966B, 0xD84A, 0x9671, + 0xD84B, 0x966F, 0xD84C, 0x96BF, 0xD84D, 0x976A, 0xD84E, 0x9804, + 0xD84F, 0x98E5, 0xD850, 0x9997, 0xD851, 0x509B, 0xD852, 0x5095, + 0xD853, 0x5094, 0xD854, 0x509E, 0xD855, 0x508B, 0xD856, 0x50A3, + 0xD857, 0x5083, 0xD858, 0x508C, 0xD859, 0x508E, 0xD85A, 0x509D, + 0xD85B, 0x5068, 0xD85C, 0x509C, 0xD85D, 0x5092, 0xD85E, 0x5082, + 0xD85F, 0x5087, 0xD860, 0x515F, 0xD861, 0x51D4, 0xD862, 0x5312, + 0xD863, 0x5311, 0xD864, 0x53A4, 0xD865, 0x53A7, 0xD866, 0x5591, + 0xD867, 0x55A8, 0xD868, 0x55A5, 0xD869, 0x55AD, 0xD86A, 0x5577, + 0xD86B, 0x5645, 0xD86C, 0x55A2, 0xD86D, 0x5593, 0xD86E, 0x5588, + 0xD86F, 0x558F, 0xD870, 0x55B5, 0xD871, 0x5581, 0xD872, 0x55A3, + 0xD873, 0x5592, 0xD874, 0x55A4, 0xD875, 0x557D, 0xD876, 0x558C, + 0xD877, 0x55A6, 0xD878, 0x557F, 0xD879, 0x5595, 0xD87A, 0x55A1, + 0xD87B, 0x558E, 0xD87C, 0x570C, 0xD87D, 0x5829, 0xD87E, 0x5837, + 0xD8A1, 0x5819, 0xD8A2, 0x581E, 0xD8A3, 0x5827, 0xD8A4, 0x5823, + 0xD8A5, 0x5828, 0xD8A6, 0x57F5, 0xD8A7, 0x5848, 0xD8A8, 0x5825, + 0xD8A9, 0x581C, 0xD8AA, 0x581B, 0xD8AB, 0x5833, 0xD8AC, 0x583F, + 0xD8AD, 0x5836, 0xD8AE, 0x582E, 0xD8AF, 0x5839, 0xD8B0, 0x5838, + 0xD8B1, 0x582D, 0xD8B2, 0x582C, 0xD8B3, 0x583B, 0xD8B4, 0x5961, + 0xD8B5, 0x5AAF, 0xD8B6, 0x5A94, 0xD8B7, 0x5A9F, 0xD8B8, 0x5A7A, + 0xD8B9, 0x5AA2, 0xD8BA, 0x5A9E, 0xD8BB, 0x5A78, 0xD8BC, 0x5AA6, + 0xD8BD, 0x5A7C, 0xD8BE, 0x5AA5, 0xD8BF, 0x5AAC, 0xD8C0, 0x5A95, + 0xD8C1, 0x5AAE, 0xD8C2, 0x5A37, 0xD8C3, 0x5A84, 0xD8C4, 0x5A8A, + 0xD8C5, 0x5A97, 0xD8C6, 0x5A83, 0xD8C7, 0x5A8B, 0xD8C8, 0x5AA9, + 0xD8C9, 0x5A7B, 0xD8CA, 0x5A7D, 0xD8CB, 0x5A8C, 0xD8CC, 0x5A9C, + 0xD8CD, 0x5A8F, 0xD8CE, 0x5A93, 0xD8CF, 0x5A9D, 0xD8D0, 0x5BEA, + 0xD8D1, 0x5BCD, 0xD8D2, 0x5BCB, 0xD8D3, 0x5BD4, 0xD8D4, 0x5BD1, + 0xD8D5, 0x5BCA, 0xD8D6, 0x5BCE, 0xD8D7, 0x5C0C, 0xD8D8, 0x5C30, + 0xD8D9, 0x5D37, 0xD8DA, 0x5D43, 0xD8DB, 0x5D6B, 0xD8DC, 0x5D41, + 0xD8DD, 0x5D4B, 0xD8DE, 0x5D3F, 0xD8DF, 0x5D35, 0xD8E0, 0x5D51, + 0xD8E1, 0x5D4E, 0xD8E2, 0x5D55, 0xD8E3, 0x5D33, 0xD8E4, 0x5D3A, + 0xD8E5, 0x5D52, 0xD8E6, 0x5D3D, 0xD8E7, 0x5D31, 0xD8E8, 0x5D59, + 0xD8E9, 0x5D42, 0xD8EA, 0x5D39, 0xD8EB, 0x5D49, 0xD8EC, 0x5D38, + 0xD8ED, 0x5D3C, 0xD8EE, 0x5D32, 0xD8EF, 0x5D36, 0xD8F0, 0x5D40, + 0xD8F1, 0x5D45, 0xD8F2, 0x5E44, 0xD8F3, 0x5E41, 0xD8F4, 0x5F58, + 0xD8F5, 0x5FA6, 0xD8F6, 0x5FA5, 0xD8F7, 0x5FAB, 0xD8F8, 0x60C9, + 0xD8F9, 0x60B9, 0xD8FA, 0x60CC, 0xD8FB, 0x60E2, 0xD8FC, 0x60CE, + 0xD8FD, 0x60C4, 0xD8FE, 0x6114, 0xD940, 0x60F2, 0xD941, 0x610A, + 0xD942, 0x6116, 0xD943, 0x6105, 0xD944, 0x60F5, 0xD945, 0x6113, + 0xD946, 0x60F8, 0xD947, 0x60FC, 0xD948, 0x60FE, 0xD949, 0x60C1, + 0xD94A, 0x6103, 0xD94B, 0x6118, 0xD94C, 0x611D, 0xD94D, 0x6110, + 0xD94E, 0x60FF, 0xD94F, 0x6104, 0xD950, 0x610B, 0xD951, 0x624A, + 0xD952, 0x6394, 0xD953, 0x63B1, 0xD954, 0x63B0, 0xD955, 0x63CE, + 0xD956, 0x63E5, 0xD957, 0x63E8, 0xD958, 0x63EF, 0xD959, 0x63C3, + 0xD95A, 0x649D, 0xD95B, 0x63F3, 0xD95C, 0x63CA, 0xD95D, 0x63E0, + 0xD95E, 0x63F6, 0xD95F, 0x63D5, 0xD960, 0x63F2, 0xD961, 0x63F5, + 0xD962, 0x6461, 0xD963, 0x63DF, 0xD964, 0x63BE, 0xD965, 0x63DD, + 0xD966, 0x63DC, 0xD967, 0x63C4, 0xD968, 0x63D8, 0xD969, 0x63D3, + 0xD96A, 0x63C2, 0xD96B, 0x63C7, 0xD96C, 0x63CC, 0xD96D, 0x63CB, + 0xD96E, 0x63C8, 0xD96F, 0x63F0, 0xD970, 0x63D7, 0xD971, 0x63D9, + 0xD972, 0x6532, 0xD973, 0x6567, 0xD974, 0x656A, 0xD975, 0x6564, + 0xD976, 0x655C, 0xD977, 0x6568, 0xD978, 0x6565, 0xD979, 0x658C, + 0xD97A, 0x659D, 0xD97B, 0x659E, 0xD97C, 0x65AE, 0xD97D, 0x65D0, + 0xD97E, 0x65D2, 0xD9A1, 0x667C, 0xD9A2, 0x666C, 0xD9A3, 0x667B, + 0xD9A4, 0x6680, 0xD9A5, 0x6671, 0xD9A6, 0x6679, 0xD9A7, 0x666A, + 0xD9A8, 0x6672, 0xD9A9, 0x6701, 0xD9AA, 0x690C, 0xD9AB, 0x68D3, + 0xD9AC, 0x6904, 0xD9AD, 0x68DC, 0xD9AE, 0x692A, 0xD9AF, 0x68EC, + 0xD9B0, 0x68EA, 0xD9B1, 0x68F1, 0xD9B2, 0x690F, 0xD9B3, 0x68D6, + 0xD9B4, 0x68F7, 0xD9B5, 0x68EB, 0xD9B6, 0x68E4, 0xD9B7, 0x68F6, + 0xD9B8, 0x6913, 0xD9B9, 0x6910, 0xD9BA, 0x68F3, 0xD9BB, 0x68E1, + 0xD9BC, 0x6907, 0xD9BD, 0x68CC, 0xD9BE, 0x6908, 0xD9BF, 0x6970, + 0xD9C0, 0x68B4, 0xD9C1, 0x6911, 0xD9C2, 0x68EF, 0xD9C3, 0x68C6, + 0xD9C4, 0x6914, 0xD9C5, 0x68F8, 0xD9C6, 0x68D0, 0xD9C7, 0x68FD, + 0xD9C8, 0x68FC, 0xD9C9, 0x68E8, 0xD9CA, 0x690B, 0xD9CB, 0x690A, + 0xD9CC, 0x6917, 0xD9CD, 0x68CE, 0xD9CE, 0x68C8, 0xD9CF, 0x68DD, + 0xD9D0, 0x68DE, 0xD9D1, 0x68E6, 0xD9D2, 0x68F4, 0xD9D3, 0x68D1, + 0xD9D4, 0x6906, 0xD9D5, 0x68D4, 0xD9D6, 0x68E9, 0xD9D7, 0x6915, + 0xD9D8, 0x6925, 0xD9D9, 0x68C7, 0xD9DA, 0x6B39, 0xD9DB, 0x6B3B, + 0xD9DC, 0x6B3F, 0xD9DD, 0x6B3C, 0xD9DE, 0x6B94, 0xD9DF, 0x6B97, + 0xD9E0, 0x6B99, 0xD9E1, 0x6B95, 0xD9E2, 0x6BBD, 0xD9E3, 0x6BF0, + 0xD9E4, 0x6BF2, 0xD9E5, 0x6BF3, 0xD9E6, 0x6C30, 0xD9E7, 0x6DFC, + 0xD9E8, 0x6E46, 0xD9E9, 0x6E47, 0xD9EA, 0x6E1F, 0xD9EB, 0x6E49, + 0xD9EC, 0x6E88, 0xD9ED, 0x6E3C, 0xD9EE, 0x6E3D, 0xD9EF, 0x6E45, + 0xD9F0, 0x6E62, 0xD9F1, 0x6E2B, 0xD9F2, 0x6E3F, 0xD9F3, 0x6E41, + 0xD9F4, 0x6E5D, 0xD9F5, 0x6E73, 0xD9F6, 0x6E1C, 0xD9F7, 0x6E33, + 0xD9F8, 0x6E4B, 0xD9F9, 0x6E40, 0xD9FA, 0x6E51, 0xD9FB, 0x6E3B, + 0xD9FC, 0x6E03, 0xD9FD, 0x6E2E, 0xD9FE, 0x6E5E, 0xDA40, 0x6E68, + 0xDA41, 0x6E5C, 0xDA42, 0x6E61, 0xDA43, 0x6E31, 0xDA44, 0x6E28, + 0xDA45, 0x6E60, 0xDA46, 0x6E71, 0xDA47, 0x6E6B, 0xDA48, 0x6E39, + 0xDA49, 0x6E22, 0xDA4A, 0x6E30, 0xDA4B, 0x6E53, 0xDA4C, 0x6E65, + 0xDA4D, 0x6E27, 0xDA4E, 0x6E78, 0xDA4F, 0x6E64, 0xDA50, 0x6E77, + 0xDA51, 0x6E55, 0xDA52, 0x6E79, 0xDA53, 0x6E52, 0xDA54, 0x6E66, + 0xDA55, 0x6E35, 0xDA56, 0x6E36, 0xDA57, 0x6E5A, 0xDA58, 0x7120, + 0xDA59, 0x711E, 0xDA5A, 0x712F, 0xDA5B, 0x70FB, 0xDA5C, 0x712E, + 0xDA5D, 0x7131, 0xDA5E, 0x7123, 0xDA5F, 0x7125, 0xDA60, 0x7122, + 0xDA61, 0x7132, 0xDA62, 0x711F, 0xDA63, 0x7128, 0xDA64, 0x713A, + 0xDA65, 0x711B, 0xDA66, 0x724B, 0xDA67, 0x725A, 0xDA68, 0x7288, + 0xDA69, 0x7289, 0xDA6A, 0x7286, 0xDA6B, 0x7285, 0xDA6C, 0x728B, + 0xDA6D, 0x7312, 0xDA6E, 0x730B, 0xDA6F, 0x7330, 0xDA70, 0x7322, + 0xDA71, 0x7331, 0xDA72, 0x7333, 0xDA73, 0x7327, 0xDA74, 0x7332, + 0xDA75, 0x732D, 0xDA76, 0x7326, 0xDA77, 0x7323, 0xDA78, 0x7335, + 0xDA79, 0x730C, 0xDA7A, 0x742E, 0xDA7B, 0x742C, 0xDA7C, 0x7430, + 0xDA7D, 0x742B, 0xDA7E, 0x7416, 0xDAA1, 0x741A, 0xDAA2, 0x7421, + 0xDAA3, 0x742D, 0xDAA4, 0x7431, 0xDAA5, 0x7424, 0xDAA6, 0x7423, + 0xDAA7, 0x741D, 0xDAA8, 0x7429, 0xDAA9, 0x7420, 0xDAAA, 0x7432, + 0xDAAB, 0x74FB, 0xDAAC, 0x752F, 0xDAAD, 0x756F, 0xDAAE, 0x756C, + 0xDAAF, 0x75E7, 0xDAB0, 0x75DA, 0xDAB1, 0x75E1, 0xDAB2, 0x75E6, + 0xDAB3, 0x75DD, 0xDAB4, 0x75DF, 0xDAB5, 0x75E4, 0xDAB6, 0x75D7, + 0xDAB7, 0x7695, 0xDAB8, 0x7692, 0xDAB9, 0x76DA, 0xDABA, 0x7746, + 0xDABB, 0x7747, 0xDABC, 0x7744, 0xDABD, 0x774D, 0xDABE, 0x7745, + 0xDABF, 0x774A, 0xDAC0, 0x774E, 0xDAC1, 0x774B, 0xDAC2, 0x774C, + 0xDAC3, 0x77DE, 0xDAC4, 0x77EC, 0xDAC5, 0x7860, 0xDAC6, 0x7864, + 0xDAC7, 0x7865, 0xDAC8, 0x785C, 0xDAC9, 0x786D, 0xDACA, 0x7871, + 0xDACB, 0x786A, 0xDACC, 0x786E, 0xDACD, 0x7870, 0xDACE, 0x7869, + 0xDACF, 0x7868, 0xDAD0, 0x785E, 0xDAD1, 0x7862, 0xDAD2, 0x7974, + 0xDAD3, 0x7973, 0xDAD4, 0x7972, 0xDAD5, 0x7970, 0xDAD6, 0x7A02, + 0xDAD7, 0x7A0A, 0xDAD8, 0x7A03, 0xDAD9, 0x7A0C, 0xDADA, 0x7A04, + 0xDADB, 0x7A99, 0xDADC, 0x7AE6, 0xDADD, 0x7AE4, 0xDADE, 0x7B4A, + 0xDADF, 0x7B3B, 0xDAE0, 0x7B44, 0xDAE1, 0x7B48, 0xDAE2, 0x7B4C, + 0xDAE3, 0x7B4E, 0xDAE4, 0x7B40, 0xDAE5, 0x7B58, 0xDAE6, 0x7B45, + 0xDAE7, 0x7CA2, 0xDAE8, 0x7C9E, 0xDAE9, 0x7CA8, 0xDAEA, 0x7CA1, + 0xDAEB, 0x7D58, 0xDAEC, 0x7D6F, 0xDAED, 0x7D63, 0xDAEE, 0x7D53, + 0xDAEF, 0x7D56, 0xDAF0, 0x7D67, 0xDAF1, 0x7D6A, 0xDAF2, 0x7D4F, + 0xDAF3, 0x7D6D, 0xDAF4, 0x7D5C, 0xDAF5, 0x7D6B, 0xDAF6, 0x7D52, + 0xDAF7, 0x7D54, 0xDAF8, 0x7D69, 0xDAF9, 0x7D51, 0xDAFA, 0x7D5F, + 0xDAFB, 0x7D4E, 0xDAFC, 0x7F3E, 0xDAFD, 0x7F3F, 0xDAFE, 0x7F65, + 0xDB40, 0x7F66, 0xDB41, 0x7FA2, 0xDB42, 0x7FA0, 0xDB43, 0x7FA1, + 0xDB44, 0x7FD7, 0xDB45, 0x8051, 0xDB46, 0x804F, 0xDB47, 0x8050, + 0xDB48, 0x80FE, 0xDB49, 0x80D4, 0xDB4A, 0x8143, 0xDB4B, 0x814A, + 0xDB4C, 0x8152, 0xDB4D, 0x814F, 0xDB4E, 0x8147, 0xDB4F, 0x813D, + 0xDB50, 0x814D, 0xDB51, 0x813A, 0xDB52, 0x81E6, 0xDB53, 0x81EE, + 0xDB54, 0x81F7, 0xDB55, 0x81F8, 0xDB56, 0x81F9, 0xDB57, 0x8204, + 0xDB58, 0x823C, 0xDB59, 0x823D, 0xDB5A, 0x823F, 0xDB5B, 0x8275, + 0xDB5C, 0x833B, 0xDB5D, 0x83CF, 0xDB5E, 0x83F9, 0xDB5F, 0x8423, + 0xDB60, 0x83C0, 0xDB61, 0x83E8, 0xDB62, 0x8412, 0xDB63, 0x83E7, + 0xDB64, 0x83E4, 0xDB65, 0x83FC, 0xDB66, 0x83F6, 0xDB67, 0x8410, + 0xDB68, 0x83C6, 0xDB69, 0x83C8, 0xDB6A, 0x83EB, 0xDB6B, 0x83E3, + 0xDB6C, 0x83BF, 0xDB6D, 0x8401, 0xDB6E, 0x83DD, 0xDB6F, 0x83E5, + 0xDB70, 0x83D8, 0xDB71, 0x83FF, 0xDB72, 0x83E1, 0xDB73, 0x83CB, + 0xDB74, 0x83CE, 0xDB75, 0x83D6, 0xDB76, 0x83F5, 0xDB77, 0x83C9, + 0xDB78, 0x8409, 0xDB79, 0x840F, 0xDB7A, 0x83DE, 0xDB7B, 0x8411, + 0xDB7C, 0x8406, 0xDB7D, 0x83C2, 0xDB7E, 0x83F3, 0xDBA1, 0x83D5, + 0xDBA2, 0x83FA, 0xDBA3, 0x83C7, 0xDBA4, 0x83D1, 0xDBA5, 0x83EA, + 0xDBA6, 0x8413, 0xDBA7, 0x83C3, 0xDBA8, 0x83EC, 0xDBA9, 0x83EE, + 0xDBAA, 0x83C4, 0xDBAB, 0x83FB, 0xDBAC, 0x83D7, 0xDBAD, 0x83E2, + 0xDBAE, 0x841B, 0xDBAF, 0x83DB, 0xDBB0, 0x83FE, 0xDBB1, 0x86D8, + 0xDBB2, 0x86E2, 0xDBB3, 0x86E6, 0xDBB4, 0x86D3, 0xDBB5, 0x86E3, + 0xDBB6, 0x86DA, 0xDBB7, 0x86EA, 0xDBB8, 0x86DD, 0xDBB9, 0x86EB, + 0xDBBA, 0x86DC, 0xDBBB, 0x86EC, 0xDBBC, 0x86E9, 0xDBBD, 0x86D7, + 0xDBBE, 0x86E8, 0xDBBF, 0x86D1, 0xDBC0, 0x8848, 0xDBC1, 0x8856, + 0xDBC2, 0x8855, 0xDBC3, 0x88BA, 0xDBC4, 0x88D7, 0xDBC5, 0x88B9, + 0xDBC6, 0x88B8, 0xDBC7, 0x88C0, 0xDBC8, 0x88BE, 0xDBC9, 0x88B6, + 0xDBCA, 0x88BC, 0xDBCB, 0x88B7, 0xDBCC, 0x88BD, 0xDBCD, 0x88B2, + 0xDBCE, 0x8901, 0xDBCF, 0x88C9, 0xDBD0, 0x8995, 0xDBD1, 0x8998, + 0xDBD2, 0x8997, 0xDBD3, 0x89DD, 0xDBD4, 0x89DA, 0xDBD5, 0x89DB, + 0xDBD6, 0x8A4E, 0xDBD7, 0x8A4D, 0xDBD8, 0x8A39, 0xDBD9, 0x8A59, + 0xDBDA, 0x8A40, 0xDBDB, 0x8A57, 0xDBDC, 0x8A58, 0xDBDD, 0x8A44, + 0xDBDE, 0x8A45, 0xDBDF, 0x8A52, 0xDBE0, 0x8A48, 0xDBE1, 0x8A51, + 0xDBE2, 0x8A4A, 0xDBE3, 0x8A4C, 0xDBE4, 0x8A4F, 0xDBE5, 0x8C5F, + 0xDBE6, 0x8C81, 0xDBE7, 0x8C80, 0xDBE8, 0x8CBA, 0xDBE9, 0x8CBE, + 0xDBEA, 0x8CB0, 0xDBEB, 0x8CB9, 0xDBEC, 0x8CB5, 0xDBED, 0x8D84, + 0xDBEE, 0x8D80, 0xDBEF, 0x8D89, 0xDBF0, 0x8DD8, 0xDBF1, 0x8DD3, + 0xDBF2, 0x8DCD, 0xDBF3, 0x8DC7, 0xDBF4, 0x8DD6, 0xDBF5, 0x8DDC, + 0xDBF6, 0x8DCF, 0xDBF7, 0x8DD5, 0xDBF8, 0x8DD9, 0xDBF9, 0x8DC8, + 0xDBFA, 0x8DD7, 0xDBFB, 0x8DC5, 0xDBFC, 0x8EEF, 0xDBFD, 0x8EF7, + 0xDBFE, 0x8EFA, 0xDC40, 0x8EF9, 0xDC41, 0x8EE6, 0xDC42, 0x8EEE, + 0xDC43, 0x8EE5, 0xDC44, 0x8EF5, 0xDC45, 0x8EE7, 0xDC46, 0x8EE8, + 0xDC47, 0x8EF6, 0xDC48, 0x8EEB, 0xDC49, 0x8EF1, 0xDC4A, 0x8EEC, + 0xDC4B, 0x8EF4, 0xDC4C, 0x8EE9, 0xDC4D, 0x902D, 0xDC4E, 0x9034, + 0xDC4F, 0x902F, 0xDC50, 0x9106, 0xDC51, 0x912C, 0xDC52, 0x9104, + 0xDC53, 0x90FF, 0xDC54, 0x90FC, 0xDC55, 0x9108, 0xDC56, 0x90F9, + 0xDC57, 0x90FB, 0xDC58, 0x9101, 0xDC59, 0x9100, 0xDC5A, 0x9107, + 0xDC5B, 0x9105, 0xDC5C, 0x9103, 0xDC5D, 0x9161, 0xDC5E, 0x9164, + 0xDC5F, 0x915F, 0xDC60, 0x9162, 0xDC61, 0x9160, 0xDC62, 0x9201, + 0xDC63, 0x920A, 0xDC64, 0x9225, 0xDC65, 0x9203, 0xDC66, 0x921A, + 0xDC67, 0x9226, 0xDC68, 0x920F, 0xDC69, 0x920C, 0xDC6A, 0x9200, + 0xDC6B, 0x9212, 0xDC6C, 0x91FF, 0xDC6D, 0x91FD, 0xDC6E, 0x9206, + 0xDC6F, 0x9204, 0xDC70, 0x9227, 0xDC71, 0x9202, 0xDC72, 0x921C, + 0xDC73, 0x9224, 0xDC74, 0x9219, 0xDC75, 0x9217, 0xDC76, 0x9205, + 0xDC77, 0x9216, 0xDC78, 0x957B, 0xDC79, 0x958D, 0xDC7A, 0x958C, + 0xDC7B, 0x9590, 0xDC7C, 0x9687, 0xDC7D, 0x967E, 0xDC7E, 0x9688, + 0xDCA1, 0x9689, 0xDCA2, 0x9683, 0xDCA3, 0x9680, 0xDCA4, 0x96C2, + 0xDCA5, 0x96C8, 0xDCA6, 0x96C3, 0xDCA7, 0x96F1, 0xDCA8, 0x96F0, + 0xDCA9, 0x976C, 0xDCAA, 0x9770, 0xDCAB, 0x976E, 0xDCAC, 0x9807, + 0xDCAD, 0x98A9, 0xDCAE, 0x98EB, 0xDCAF, 0x9CE6, 0xDCB0, 0x9EF9, + 0xDCB1, 0x4E83, 0xDCB2, 0x4E84, 0xDCB3, 0x4EB6, 0xDCB4, 0x50BD, + 0xDCB5, 0x50BF, 0xDCB6, 0x50C6, 0xDCB7, 0x50AE, 0xDCB8, 0x50C4, + 0xDCB9, 0x50CA, 0xDCBA, 0x50B4, 0xDCBB, 0x50C8, 0xDCBC, 0x50C2, + 0xDCBD, 0x50B0, 0xDCBE, 0x50C1, 0xDCBF, 0x50BA, 0xDCC0, 0x50B1, + 0xDCC1, 0x50CB, 0xDCC2, 0x50C9, 0xDCC3, 0x50B6, 0xDCC4, 0x50B8, + 0xDCC5, 0x51D7, 0xDCC6, 0x527A, 0xDCC7, 0x5278, 0xDCC8, 0x527B, + 0xDCC9, 0x527C, 0xDCCA, 0x55C3, 0xDCCB, 0x55DB, 0xDCCC, 0x55CC, + 0xDCCD, 0x55D0, 0xDCCE, 0x55CB, 0xDCCF, 0x55CA, 0xDCD0, 0x55DD, + 0xDCD1, 0x55C0, 0xDCD2, 0x55D4, 0xDCD3, 0x55C4, 0xDCD4, 0x55E9, + 0xDCD5, 0x55BF, 0xDCD6, 0x55D2, 0xDCD7, 0x558D, 0xDCD8, 0x55CF, + 0xDCD9, 0x55D5, 0xDCDA, 0x55E2, 0xDCDB, 0x55D6, 0xDCDC, 0x55C8, + 0xDCDD, 0x55F2, 0xDCDE, 0x55CD, 0xDCDF, 0x55D9, 0xDCE0, 0x55C2, + 0xDCE1, 0x5714, 0xDCE2, 0x5853, 0xDCE3, 0x5868, 0xDCE4, 0x5864, + 0xDCE5, 0x584F, 0xDCE6, 0x584D, 0xDCE7, 0x5849, 0xDCE8, 0x586F, + 0xDCE9, 0x5855, 0xDCEA, 0x584E, 0xDCEB, 0x585D, 0xDCEC, 0x5859, + 0xDCED, 0x5865, 0xDCEE, 0x585B, 0xDCEF, 0x583D, 0xDCF0, 0x5863, + 0xDCF1, 0x5871, 0xDCF2, 0x58FC, 0xDCF3, 0x5AC7, 0xDCF4, 0x5AC4, + 0xDCF5, 0x5ACB, 0xDCF6, 0x5ABA, 0xDCF7, 0x5AB8, 0xDCF8, 0x5AB1, + 0xDCF9, 0x5AB5, 0xDCFA, 0x5AB0, 0xDCFB, 0x5ABF, 0xDCFC, 0x5AC8, + 0xDCFD, 0x5ABB, 0xDCFE, 0x5AC6, 0xDD40, 0x5AB7, 0xDD41, 0x5AC0, + 0xDD42, 0x5ACA, 0xDD43, 0x5AB4, 0xDD44, 0x5AB6, 0xDD45, 0x5ACD, + 0xDD46, 0x5AB9, 0xDD47, 0x5A90, 0xDD48, 0x5BD6, 0xDD49, 0x5BD8, + 0xDD4A, 0x5BD9, 0xDD4B, 0x5C1F, 0xDD4C, 0x5C33, 0xDD4D, 0x5D71, + 0xDD4E, 0x5D63, 0xDD4F, 0x5D4A, 0xDD50, 0x5D65, 0xDD51, 0x5D72, + 0xDD52, 0x5D6C, 0xDD53, 0x5D5E, 0xDD54, 0x5D68, 0xDD55, 0x5D67, + 0xDD56, 0x5D62, 0xDD57, 0x5DF0, 0xDD58, 0x5E4F, 0xDD59, 0x5E4E, + 0xDD5A, 0x5E4A, 0xDD5B, 0x5E4D, 0xDD5C, 0x5E4B, 0xDD5D, 0x5EC5, + 0xDD5E, 0x5ECC, 0xDD5F, 0x5EC6, 0xDD60, 0x5ECB, 0xDD61, 0x5EC7, + 0xDD62, 0x5F40, 0xDD63, 0x5FAF, 0xDD64, 0x5FAD, 0xDD65, 0x60F7, + 0xDD66, 0x6149, 0xDD67, 0x614A, 0xDD68, 0x612B, 0xDD69, 0x6145, + 0xDD6A, 0x6136, 0xDD6B, 0x6132, 0xDD6C, 0x612E, 0xDD6D, 0x6146, + 0xDD6E, 0x612F, 0xDD6F, 0x614F, 0xDD70, 0x6129, 0xDD71, 0x6140, + 0xDD72, 0x6220, 0xDD73, 0x9168, 0xDD74, 0x6223, 0xDD75, 0x6225, + 0xDD76, 0x6224, 0xDD77, 0x63C5, 0xDD78, 0x63F1, 0xDD79, 0x63EB, + 0xDD7A, 0x6410, 0xDD7B, 0x6412, 0xDD7C, 0x6409, 0xDD7D, 0x6420, + 0xDD7E, 0x6424, 0xDDA1, 0x6433, 0xDDA2, 0x6443, 0xDDA3, 0x641F, + 0xDDA4, 0x6415, 0xDDA5, 0x6418, 0xDDA6, 0x6439, 0xDDA7, 0x6437, + 0xDDA8, 0x6422, 0xDDA9, 0x6423, 0xDDAA, 0x640C, 0xDDAB, 0x6426, + 0xDDAC, 0x6430, 0xDDAD, 0x6428, 0xDDAE, 0x6441, 0xDDAF, 0x6435, + 0xDDB0, 0x642F, 0xDDB1, 0x640A, 0xDDB2, 0x641A, 0xDDB3, 0x6440, + 0xDDB4, 0x6425, 0xDDB5, 0x6427, 0xDDB6, 0x640B, 0xDDB7, 0x63E7, + 0xDDB8, 0x641B, 0xDDB9, 0x642E, 0xDDBA, 0x6421, 0xDDBB, 0x640E, + 0xDDBC, 0x656F, 0xDDBD, 0x6592, 0xDDBE, 0x65D3, 0xDDBF, 0x6686, + 0xDDC0, 0x668C, 0xDDC1, 0x6695, 0xDDC2, 0x6690, 0xDDC3, 0x668B, + 0xDDC4, 0x668A, 0xDDC5, 0x6699, 0xDDC6, 0x6694, 0xDDC7, 0x6678, + 0xDDC8, 0x6720, 0xDDC9, 0x6966, 0xDDCA, 0x695F, 0xDDCB, 0x6938, + 0xDDCC, 0x694E, 0xDDCD, 0x6962, 0xDDCE, 0x6971, 0xDDCF, 0x693F, + 0xDDD0, 0x6945, 0xDDD1, 0x696A, 0xDDD2, 0x6939, 0xDDD3, 0x6942, + 0xDDD4, 0x6957, 0xDDD5, 0x6959, 0xDDD6, 0x697A, 0xDDD7, 0x6948, + 0xDDD8, 0x6949, 0xDDD9, 0x6935, 0xDDDA, 0x696C, 0xDDDB, 0x6933, + 0xDDDC, 0x693D, 0xDDDD, 0x6965, 0xDDDE, 0x68F0, 0xDDDF, 0x6978, + 0xDDE0, 0x6934, 0xDDE1, 0x6969, 0xDDE2, 0x6940, 0xDDE3, 0x696F, + 0xDDE4, 0x6944, 0xDDE5, 0x6976, 0xDDE6, 0x6958, 0xDDE7, 0x6941, + 0xDDE8, 0x6974, 0xDDE9, 0x694C, 0xDDEA, 0x693B, 0xDDEB, 0x694B, + 0xDDEC, 0x6937, 0xDDED, 0x695C, 0xDDEE, 0x694F, 0xDDEF, 0x6951, + 0xDDF0, 0x6932, 0xDDF1, 0x6952, 0xDDF2, 0x692F, 0xDDF3, 0x697B, + 0xDDF4, 0x693C, 0xDDF5, 0x6B46, 0xDDF6, 0x6B45, 0xDDF7, 0x6B43, + 0xDDF8, 0x6B42, 0xDDF9, 0x6B48, 0xDDFA, 0x6B41, 0xDDFB, 0x6B9B, + 0xDDFC, 0xFA0D, 0xDDFD, 0x6BFB, 0xDDFE, 0x6BFC, 0xDE40, 0x6BF9, + 0xDE41, 0x6BF7, 0xDE42, 0x6BF8, 0xDE43, 0x6E9B, 0xDE44, 0x6ED6, + 0xDE45, 0x6EC8, 0xDE46, 0x6E8F, 0xDE47, 0x6EC0, 0xDE48, 0x6E9F, + 0xDE49, 0x6E93, 0xDE4A, 0x6E94, 0xDE4B, 0x6EA0, 0xDE4C, 0x6EB1, + 0xDE4D, 0x6EB9, 0xDE4E, 0x6EC6, 0xDE4F, 0x6ED2, 0xDE50, 0x6EBD, + 0xDE51, 0x6EC1, 0xDE52, 0x6E9E, 0xDE53, 0x6EC9, 0xDE54, 0x6EB7, + 0xDE55, 0x6EB0, 0xDE56, 0x6ECD, 0xDE57, 0x6EA6, 0xDE58, 0x6ECF, + 0xDE59, 0x6EB2, 0xDE5A, 0x6EBE, 0xDE5B, 0x6EC3, 0xDE5C, 0x6EDC, + 0xDE5D, 0x6ED8, 0xDE5E, 0x6E99, 0xDE5F, 0x6E92, 0xDE60, 0x6E8E, + 0xDE61, 0x6E8D, 0xDE62, 0x6EA4, 0xDE63, 0x6EA1, 0xDE64, 0x6EBF, + 0xDE65, 0x6EB3, 0xDE66, 0x6ED0, 0xDE67, 0x6ECA, 0xDE68, 0x6E97, + 0xDE69, 0x6EAE, 0xDE6A, 0x6EA3, 0xDE6B, 0x7147, 0xDE6C, 0x7154, + 0xDE6D, 0x7152, 0xDE6E, 0x7163, 0xDE6F, 0x7160, 0xDE70, 0x7141, + 0xDE71, 0x715D, 0xDE72, 0x7162, 0xDE73, 0x7172, 0xDE74, 0x7178, + 0xDE75, 0x716A, 0xDE76, 0x7161, 0xDE77, 0x7142, 0xDE78, 0x7158, + 0xDE79, 0x7143, 0xDE7A, 0x714B, 0xDE7B, 0x7170, 0xDE7C, 0x715F, + 0xDE7D, 0x7150, 0xDE7E, 0x7153, 0xDEA1, 0x7144, 0xDEA2, 0x714D, + 0xDEA3, 0x715A, 0xDEA4, 0x724F, 0xDEA5, 0x728D, 0xDEA6, 0x728C, + 0xDEA7, 0x7291, 0xDEA8, 0x7290, 0xDEA9, 0x728E, 0xDEAA, 0x733C, + 0xDEAB, 0x7342, 0xDEAC, 0x733B, 0xDEAD, 0x733A, 0xDEAE, 0x7340, + 0xDEAF, 0x734A, 0xDEB0, 0x7349, 0xDEB1, 0x7444, 0xDEB2, 0x744A, + 0xDEB3, 0x744B, 0xDEB4, 0x7452, 0xDEB5, 0x7451, 0xDEB6, 0x7457, + 0xDEB7, 0x7440, 0xDEB8, 0x744F, 0xDEB9, 0x7450, 0xDEBA, 0x744E, + 0xDEBB, 0x7442, 0xDEBC, 0x7446, 0xDEBD, 0x744D, 0xDEBE, 0x7454, + 0xDEBF, 0x74E1, 0xDEC0, 0x74FF, 0xDEC1, 0x74FE, 0xDEC2, 0x74FD, + 0xDEC3, 0x751D, 0xDEC4, 0x7579, 0xDEC5, 0x7577, 0xDEC6, 0x6983, + 0xDEC7, 0x75EF, 0xDEC8, 0x760F, 0xDEC9, 0x7603, 0xDECA, 0x75F7, + 0xDECB, 0x75FE, 0xDECC, 0x75FC, 0xDECD, 0x75F9, 0xDECE, 0x75F8, + 0xDECF, 0x7610, 0xDED0, 0x75FB, 0xDED1, 0x75F6, 0xDED2, 0x75ED, + 0xDED3, 0x75F5, 0xDED4, 0x75FD, 0xDED5, 0x7699, 0xDED6, 0x76B5, + 0xDED7, 0x76DD, 0xDED8, 0x7755, 0xDED9, 0x775F, 0xDEDA, 0x7760, + 0xDEDB, 0x7752, 0xDEDC, 0x7756, 0xDEDD, 0x775A, 0xDEDE, 0x7769, + 0xDEDF, 0x7767, 0xDEE0, 0x7754, 0xDEE1, 0x7759, 0xDEE2, 0x776D, + 0xDEE3, 0x77E0, 0xDEE4, 0x7887, 0xDEE5, 0x789A, 0xDEE6, 0x7894, + 0xDEE7, 0x788F, 0xDEE8, 0x7884, 0xDEE9, 0x7895, 0xDEEA, 0x7885, + 0xDEEB, 0x7886, 0xDEEC, 0x78A1, 0xDEED, 0x7883, 0xDEEE, 0x7879, + 0xDEEF, 0x7899, 0xDEF0, 0x7880, 0xDEF1, 0x7896, 0xDEF2, 0x787B, + 0xDEF3, 0x797C, 0xDEF4, 0x7982, 0xDEF5, 0x797D, 0xDEF6, 0x7979, + 0xDEF7, 0x7A11, 0xDEF8, 0x7A18, 0xDEF9, 0x7A19, 0xDEFA, 0x7A12, + 0xDEFB, 0x7A17, 0xDEFC, 0x7A15, 0xDEFD, 0x7A22, 0xDEFE, 0x7A13, + 0xDF40, 0x7A1B, 0xDF41, 0x7A10, 0xDF42, 0x7AA3, 0xDF43, 0x7AA2, + 0xDF44, 0x7A9E, 0xDF45, 0x7AEB, 0xDF46, 0x7B66, 0xDF47, 0x7B64, + 0xDF48, 0x7B6D, 0xDF49, 0x7B74, 0xDF4A, 0x7B69, 0xDF4B, 0x7B72, + 0xDF4C, 0x7B65, 0xDF4D, 0x7B73, 0xDF4E, 0x7B71, 0xDF4F, 0x7B70, + 0xDF50, 0x7B61, 0xDF51, 0x7B78, 0xDF52, 0x7B76, 0xDF53, 0x7B63, + 0xDF54, 0x7CB2, 0xDF55, 0x7CB4, 0xDF56, 0x7CAF, 0xDF57, 0x7D88, + 0xDF58, 0x7D86, 0xDF59, 0x7D80, 0xDF5A, 0x7D8D, 0xDF5B, 0x7D7F, + 0xDF5C, 0x7D85, 0xDF5D, 0x7D7A, 0xDF5E, 0x7D8E, 0xDF5F, 0x7D7B, + 0xDF60, 0x7D83, 0xDF61, 0x7D7C, 0xDF62, 0x7D8C, 0xDF63, 0x7D94, + 0xDF64, 0x7D84, 0xDF65, 0x7D7D, 0xDF66, 0x7D92, 0xDF67, 0x7F6D, + 0xDF68, 0x7F6B, 0xDF69, 0x7F67, 0xDF6A, 0x7F68, 0xDF6B, 0x7F6C, + 0xDF6C, 0x7FA6, 0xDF6D, 0x7FA5, 0xDF6E, 0x7FA7, 0xDF6F, 0x7FDB, + 0xDF70, 0x7FDC, 0xDF71, 0x8021, 0xDF72, 0x8164, 0xDF73, 0x8160, + 0xDF74, 0x8177, 0xDF75, 0x815C, 0xDF76, 0x8169, 0xDF77, 0x815B, + 0xDF78, 0x8162, 0xDF79, 0x8172, 0xDF7A, 0x6721, 0xDF7B, 0x815E, + 0xDF7C, 0x8176, 0xDF7D, 0x8167, 0xDF7E, 0x816F, 0xDFA1, 0x8144, + 0xDFA2, 0x8161, 0xDFA3, 0x821D, 0xDFA4, 0x8249, 0xDFA5, 0x8244, + 0xDFA6, 0x8240, 0xDFA7, 0x8242, 0xDFA8, 0x8245, 0xDFA9, 0x84F1, + 0xDFAA, 0x843F, 0xDFAB, 0x8456, 0xDFAC, 0x8476, 0xDFAD, 0x8479, + 0xDFAE, 0x848F, 0xDFAF, 0x848D, 0xDFB0, 0x8465, 0xDFB1, 0x8451, + 0xDFB2, 0x8440, 0xDFB3, 0x8486, 0xDFB4, 0x8467, 0xDFB5, 0x8430, + 0xDFB6, 0x844D, 0xDFB7, 0x847D, 0xDFB8, 0x845A, 0xDFB9, 0x8459, + 0xDFBA, 0x8474, 0xDFBB, 0x8473, 0xDFBC, 0x845D, 0xDFBD, 0x8507, + 0xDFBE, 0x845E, 0xDFBF, 0x8437, 0xDFC0, 0x843A, 0xDFC1, 0x8434, + 0xDFC2, 0x847A, 0xDFC3, 0x8443, 0xDFC4, 0x8478, 0xDFC5, 0x8432, + 0xDFC6, 0x8445, 0xDFC7, 0x8429, 0xDFC8, 0x83D9, 0xDFC9, 0x844B, + 0xDFCA, 0x842F, 0xDFCB, 0x8442, 0xDFCC, 0x842D, 0xDFCD, 0x845F, + 0xDFCE, 0x8470, 0xDFCF, 0x8439, 0xDFD0, 0x844E, 0xDFD1, 0x844C, + 0xDFD2, 0x8452, 0xDFD3, 0x846F, 0xDFD4, 0x84C5, 0xDFD5, 0x848E, + 0xDFD6, 0x843B, 0xDFD7, 0x8447, 0xDFD8, 0x8436, 0xDFD9, 0x8433, + 0xDFDA, 0x8468, 0xDFDB, 0x847E, 0xDFDC, 0x8444, 0xDFDD, 0x842B, + 0xDFDE, 0x8460, 0xDFDF, 0x8454, 0xDFE0, 0x846E, 0xDFE1, 0x8450, + 0xDFE2, 0x870B, 0xDFE3, 0x8704, 0xDFE4, 0x86F7, 0xDFE5, 0x870C, + 0xDFE6, 0x86FA, 0xDFE7, 0x86D6, 0xDFE8, 0x86F5, 0xDFE9, 0x874D, + 0xDFEA, 0x86F8, 0xDFEB, 0x870E, 0xDFEC, 0x8709, 0xDFED, 0x8701, + 0xDFEE, 0x86F6, 0xDFEF, 0x870D, 0xDFF0, 0x8705, 0xDFF1, 0x88D6, + 0xDFF2, 0x88CB, 0xDFF3, 0x88CD, 0xDFF4, 0x88CE, 0xDFF5, 0x88DE, + 0xDFF6, 0x88DB, 0xDFF7, 0x88DA, 0xDFF8, 0x88CC, 0xDFF9, 0x88D0, + 0xDFFA, 0x8985, 0xDFFB, 0x899B, 0xDFFC, 0x89DF, 0xDFFD, 0x89E5, + 0xDFFE, 0x89E4, 0xE040, 0x89E1, 0xE041, 0x89E0, 0xE042, 0x89E2, + 0xE043, 0x89DC, 0xE044, 0x89E6, 0xE045, 0x8A76, 0xE046, 0x8A86, + 0xE047, 0x8A7F, 0xE048, 0x8A61, 0xE049, 0x8A3F, 0xE04A, 0x8A77, + 0xE04B, 0x8A82, 0xE04C, 0x8A84, 0xE04D, 0x8A75, 0xE04E, 0x8A83, + 0xE04F, 0x8A81, 0xE050, 0x8A74, 0xE051, 0x8A7A, 0xE052, 0x8C3C, + 0xE053, 0x8C4B, 0xE054, 0x8C4A, 0xE055, 0x8C65, 0xE056, 0x8C64, + 0xE057, 0x8C66, 0xE058, 0x8C86, 0xE059, 0x8C84, 0xE05A, 0x8C85, + 0xE05B, 0x8CCC, 0xE05C, 0x8D68, 0xE05D, 0x8D69, 0xE05E, 0x8D91, + 0xE05F, 0x8D8C, 0xE060, 0x8D8E, 0xE061, 0x8D8F, 0xE062, 0x8D8D, + 0xE063, 0x8D93, 0xE064, 0x8D94, 0xE065, 0x8D90, 0xE066, 0x8D92, + 0xE067, 0x8DF0, 0xE068, 0x8DE0, 0xE069, 0x8DEC, 0xE06A, 0x8DF1, + 0xE06B, 0x8DEE, 0xE06C, 0x8DD0, 0xE06D, 0x8DE9, 0xE06E, 0x8DE3, + 0xE06F, 0x8DE2, 0xE070, 0x8DE7, 0xE071, 0x8DF2, 0xE072, 0x8DEB, + 0xE073, 0x8DF4, 0xE074, 0x8F06, 0xE075, 0x8EFF, 0xE076, 0x8F01, + 0xE077, 0x8F00, 0xE078, 0x8F05, 0xE079, 0x8F07, 0xE07A, 0x8F08, + 0xE07B, 0x8F02, 0xE07C, 0x8F0B, 0xE07D, 0x9052, 0xE07E, 0x903F, + 0xE0A1, 0x9044, 0xE0A2, 0x9049, 0xE0A3, 0x903D, 0xE0A4, 0x9110, + 0xE0A5, 0x910D, 0xE0A6, 0x910F, 0xE0A7, 0x9111, 0xE0A8, 0x9116, + 0xE0A9, 0x9114, 0xE0AA, 0x910B, 0xE0AB, 0x910E, 0xE0AC, 0x916E, + 0xE0AD, 0x916F, 0xE0AE, 0x9248, 0xE0AF, 0x9252, 0xE0B0, 0x9230, + 0xE0B1, 0x923A, 0xE0B2, 0x9266, 0xE0B3, 0x9233, 0xE0B4, 0x9265, + 0xE0B5, 0x925E, 0xE0B6, 0x9283, 0xE0B7, 0x922E, 0xE0B8, 0x924A, + 0xE0B9, 0x9246, 0xE0BA, 0x926D, 0xE0BB, 0x926C, 0xE0BC, 0x924F, + 0xE0BD, 0x9260, 0xE0BE, 0x9267, 0xE0BF, 0x926F, 0xE0C0, 0x9236, + 0xE0C1, 0x9261, 0xE0C2, 0x9270, 0xE0C3, 0x9231, 0xE0C4, 0x9254, + 0xE0C5, 0x9263, 0xE0C6, 0x9250, 0xE0C7, 0x9272, 0xE0C8, 0x924E, + 0xE0C9, 0x9253, 0xE0CA, 0x924C, 0xE0CB, 0x9256, 0xE0CC, 0x9232, + 0xE0CD, 0x959F, 0xE0CE, 0x959C, 0xE0CF, 0x959E, 0xE0D0, 0x959B, + 0xE0D1, 0x9692, 0xE0D2, 0x9693, 0xE0D3, 0x9691, 0xE0D4, 0x9697, + 0xE0D5, 0x96CE, 0xE0D6, 0x96FA, 0xE0D7, 0x96FD, 0xE0D8, 0x96F8, + 0xE0D9, 0x96F5, 0xE0DA, 0x9773, 0xE0DB, 0x9777, 0xE0DC, 0x9778, + 0xE0DD, 0x9772, 0xE0DE, 0x980F, 0xE0DF, 0x980D, 0xE0E0, 0x980E, + 0xE0E1, 0x98AC, 0xE0E2, 0x98F6, 0xE0E3, 0x98F9, 0xE0E4, 0x99AF, + 0xE0E5, 0x99B2, 0xE0E6, 0x99B0, 0xE0E7, 0x99B5, 0xE0E8, 0x9AAD, + 0xE0E9, 0x9AAB, 0xE0EA, 0x9B5B, 0xE0EB, 0x9CEA, 0xE0EC, 0x9CED, + 0xE0ED, 0x9CE7, 0xE0EE, 0x9E80, 0xE0EF, 0x9EFD, 0xE0F0, 0x50E6, + 0xE0F1, 0x50D4, 0xE0F2, 0x50D7, 0xE0F3, 0x50E8, 0xE0F4, 0x50F3, + 0xE0F5, 0x50DB, 0xE0F6, 0x50EA, 0xE0F7, 0x50DD, 0xE0F8, 0x50E4, + 0xE0F9, 0x50D3, 0xE0FA, 0x50EC, 0xE0FB, 0x50F0, 0xE0FC, 0x50EF, + 0xE0FD, 0x50E3, 0xE0FE, 0x50E0, 0xE140, 0x51D8, 0xE141, 0x5280, + 0xE142, 0x5281, 0xE143, 0x52E9, 0xE144, 0x52EB, 0xE145, 0x5330, + 0xE146, 0x53AC, 0xE147, 0x5627, 0xE148, 0x5615, 0xE149, 0x560C, + 0xE14A, 0x5612, 0xE14B, 0x55FC, 0xE14C, 0x560F, 0xE14D, 0x561C, + 0xE14E, 0x5601, 0xE14F, 0x5613, 0xE150, 0x5602, 0xE151, 0x55FA, + 0xE152, 0x561D, 0xE153, 0x5604, 0xE154, 0x55FF, 0xE155, 0x55F9, + 0xE156, 0x5889, 0xE157, 0x587C, 0xE158, 0x5890, 0xE159, 0x5898, + 0xE15A, 0x5886, 0xE15B, 0x5881, 0xE15C, 0x587F, 0xE15D, 0x5874, + 0xE15E, 0x588B, 0xE15F, 0x587A, 0xE160, 0x5887, 0xE161, 0x5891, + 0xE162, 0x588E, 0xE163, 0x5876, 0xE164, 0x5882, 0xE165, 0x5888, + 0xE166, 0x587B, 0xE167, 0x5894, 0xE168, 0x588F, 0xE169, 0x58FE, + 0xE16A, 0x596B, 0xE16B, 0x5ADC, 0xE16C, 0x5AEE, 0xE16D, 0x5AE5, + 0xE16E, 0x5AD5, 0xE16F, 0x5AEA, 0xE170, 0x5ADA, 0xE171, 0x5AED, + 0xE172, 0x5AEB, 0xE173, 0x5AF3, 0xE174, 0x5AE2, 0xE175, 0x5AE0, + 0xE176, 0x5ADB, 0xE177, 0x5AEC, 0xE178, 0x5ADE, 0xE179, 0x5ADD, + 0xE17A, 0x5AD9, 0xE17B, 0x5AE8, 0xE17C, 0x5ADF, 0xE17D, 0x5B77, + 0xE17E, 0x5BE0, 0xE1A1, 0x5BE3, 0xE1A2, 0x5C63, 0xE1A3, 0x5D82, + 0xE1A4, 0x5D80, 0xE1A5, 0x5D7D, 0xE1A6, 0x5D86, 0xE1A7, 0x5D7A, + 0xE1A8, 0x5D81, 0xE1A9, 0x5D77, 0xE1AA, 0x5D8A, 0xE1AB, 0x5D89, + 0xE1AC, 0x5D88, 0xE1AD, 0x5D7E, 0xE1AE, 0x5D7C, 0xE1AF, 0x5D8D, + 0xE1B0, 0x5D79, 0xE1B1, 0x5D7F, 0xE1B2, 0x5E58, 0xE1B3, 0x5E59, + 0xE1B4, 0x5E53, 0xE1B5, 0x5ED8, 0xE1B6, 0x5ED1, 0xE1B7, 0x5ED7, + 0xE1B8, 0x5ECE, 0xE1B9, 0x5EDC, 0xE1BA, 0x5ED5, 0xE1BB, 0x5ED9, + 0xE1BC, 0x5ED2, 0xE1BD, 0x5ED4, 0xE1BE, 0x5F44, 0xE1BF, 0x5F43, + 0xE1C0, 0x5F6F, 0xE1C1, 0x5FB6, 0xE1C2, 0x612C, 0xE1C3, 0x6128, + 0xE1C4, 0x6141, 0xE1C5, 0x615E, 0xE1C6, 0x6171, 0xE1C7, 0x6173, + 0xE1C8, 0x6152, 0xE1C9, 0x6153, 0xE1CA, 0x6172, 0xE1CB, 0x616C, + 0xE1CC, 0x6180, 0xE1CD, 0x6174, 0xE1CE, 0x6154, 0xE1CF, 0x617A, + 0xE1D0, 0x615B, 0xE1D1, 0x6165, 0xE1D2, 0x613B, 0xE1D3, 0x616A, + 0xE1D4, 0x6161, 0xE1D5, 0x6156, 0xE1D6, 0x6229, 0xE1D7, 0x6227, + 0xE1D8, 0x622B, 0xE1D9, 0x642B, 0xE1DA, 0x644D, 0xE1DB, 0x645B, + 0xE1DC, 0x645D, 0xE1DD, 0x6474, 0xE1DE, 0x6476, 0xE1DF, 0x6472, + 0xE1E0, 0x6473, 0xE1E1, 0x647D, 0xE1E2, 0x6475, 0xE1E3, 0x6466, + 0xE1E4, 0x64A6, 0xE1E5, 0x644E, 0xE1E6, 0x6482, 0xE1E7, 0x645E, + 0xE1E8, 0x645C, 0xE1E9, 0x644B, 0xE1EA, 0x6453, 0xE1EB, 0x6460, + 0xE1EC, 0x6450, 0xE1ED, 0x647F, 0xE1EE, 0x643F, 0xE1EF, 0x646C, + 0xE1F0, 0x646B, 0xE1F1, 0x6459, 0xE1F2, 0x6465, 0xE1F3, 0x6477, + 0xE1F4, 0x6573, 0xE1F5, 0x65A0, 0xE1F6, 0x66A1, 0xE1F7, 0x66A0, + 0xE1F8, 0x669F, 0xE1F9, 0x6705, 0xE1FA, 0x6704, 0xE1FB, 0x6722, + 0xE1FC, 0x69B1, 0xE1FD, 0x69B6, 0xE1FE, 0x69C9, 0xE240, 0x69A0, + 0xE241, 0x69CE, 0xE242, 0x6996, 0xE243, 0x69B0, 0xE244, 0x69AC, + 0xE245, 0x69BC, 0xE246, 0x6991, 0xE247, 0x6999, 0xE248, 0x698E, + 0xE249, 0x69A7, 0xE24A, 0x698D, 0xE24B, 0x69A9, 0xE24C, 0x69BE, + 0xE24D, 0x69AF, 0xE24E, 0x69BF, 0xE24F, 0x69C4, 0xE250, 0x69BD, + 0xE251, 0x69A4, 0xE252, 0x69D4, 0xE253, 0x69B9, 0xE254, 0x69CA, + 0xE255, 0x699A, 0xE256, 0x69CF, 0xE257, 0x69B3, 0xE258, 0x6993, + 0xE259, 0x69AA, 0xE25A, 0x69A1, 0xE25B, 0x699E, 0xE25C, 0x69D9, + 0xE25D, 0x6997, 0xE25E, 0x6990, 0xE25F, 0x69C2, 0xE260, 0x69B5, + 0xE261, 0x69A5, 0xE262, 0x69C6, 0xE263, 0x6B4A, 0xE264, 0x6B4D, + 0xE265, 0x6B4B, 0xE266, 0x6B9E, 0xE267, 0x6B9F, 0xE268, 0x6BA0, + 0xE269, 0x6BC3, 0xE26A, 0x6BC4, 0xE26B, 0x6BFE, 0xE26C, 0x6ECE, + 0xE26D, 0x6EF5, 0xE26E, 0x6EF1, 0xE26F, 0x6F03, 0xE270, 0x6F25, + 0xE271, 0x6EF8, 0xE272, 0x6F37, 0xE273, 0x6EFB, 0xE274, 0x6F2E, + 0xE275, 0x6F09, 0xE276, 0x6F4E, 0xE277, 0x6F19, 0xE278, 0x6F1A, + 0xE279, 0x6F27, 0xE27A, 0x6F18, 0xE27B, 0x6F3B, 0xE27C, 0x6F12, + 0xE27D, 0x6EED, 0xE27E, 0x6F0A, 0xE2A1, 0x6F36, 0xE2A2, 0x6F73, + 0xE2A3, 0x6EF9, 0xE2A4, 0x6EEE, 0xE2A5, 0x6F2D, 0xE2A6, 0x6F40, + 0xE2A7, 0x6F30, 0xE2A8, 0x6F3C, 0xE2A9, 0x6F35, 0xE2AA, 0x6EEB, + 0xE2AB, 0x6F07, 0xE2AC, 0x6F0E, 0xE2AD, 0x6F43, 0xE2AE, 0x6F05, + 0xE2AF, 0x6EFD, 0xE2B0, 0x6EF6, 0xE2B1, 0x6F39, 0xE2B2, 0x6F1C, + 0xE2B3, 0x6EFC, 0xE2B4, 0x6F3A, 0xE2B5, 0x6F1F, 0xE2B6, 0x6F0D, + 0xE2B7, 0x6F1E, 0xE2B8, 0x6F08, 0xE2B9, 0x6F21, 0xE2BA, 0x7187, + 0xE2BB, 0x7190, 0xE2BC, 0x7189, 0xE2BD, 0x7180, 0xE2BE, 0x7185, + 0xE2BF, 0x7182, 0xE2C0, 0x718F, 0xE2C1, 0x717B, 0xE2C2, 0x7186, + 0xE2C3, 0x7181, 0xE2C4, 0x7197, 0xE2C5, 0x7244, 0xE2C6, 0x7253, + 0xE2C7, 0x7297, 0xE2C8, 0x7295, 0xE2C9, 0x7293, 0xE2CA, 0x7343, + 0xE2CB, 0x734D, 0xE2CC, 0x7351, 0xE2CD, 0x734C, 0xE2CE, 0x7462, + 0xE2CF, 0x7473, 0xE2D0, 0x7471, 0xE2D1, 0x7475, 0xE2D2, 0x7472, + 0xE2D3, 0x7467, 0xE2D4, 0x746E, 0xE2D5, 0x7500, 0xE2D6, 0x7502, + 0xE2D7, 0x7503, 0xE2D8, 0x757D, 0xE2D9, 0x7590, 0xE2DA, 0x7616, + 0xE2DB, 0x7608, 0xE2DC, 0x760C, 0xE2DD, 0x7615, 0xE2DE, 0x7611, + 0xE2DF, 0x760A, 0xE2E0, 0x7614, 0xE2E1, 0x76B8, 0xE2E2, 0x7781, + 0xE2E3, 0x777C, 0xE2E4, 0x7785, 0xE2E5, 0x7782, 0xE2E6, 0x776E, + 0xE2E7, 0x7780, 0xE2E8, 0x776F, 0xE2E9, 0x777E, 0xE2EA, 0x7783, + 0xE2EB, 0x78B2, 0xE2EC, 0x78AA, 0xE2ED, 0x78B4, 0xE2EE, 0x78AD, + 0xE2EF, 0x78A8, 0xE2F0, 0x787E, 0xE2F1, 0x78AB, 0xE2F2, 0x789E, + 0xE2F3, 0x78A5, 0xE2F4, 0x78A0, 0xE2F5, 0x78AC, 0xE2F6, 0x78A2, + 0xE2F7, 0x78A4, 0xE2F8, 0x7998, 0xE2F9, 0x798A, 0xE2FA, 0x798B, + 0xE2FB, 0x7996, 0xE2FC, 0x7995, 0xE2FD, 0x7994, 0xE2FE, 0x7993, + 0xE340, 0x7997, 0xE341, 0x7988, 0xE342, 0x7992, 0xE343, 0x7990, + 0xE344, 0x7A2B, 0xE345, 0x7A4A, 0xE346, 0x7A30, 0xE347, 0x7A2F, + 0xE348, 0x7A28, 0xE349, 0x7A26, 0xE34A, 0x7AA8, 0xE34B, 0x7AAB, + 0xE34C, 0x7AAC, 0xE34D, 0x7AEE, 0xE34E, 0x7B88, 0xE34F, 0x7B9C, + 0xE350, 0x7B8A, 0xE351, 0x7B91, 0xE352, 0x7B90, 0xE353, 0x7B96, + 0xE354, 0x7B8D, 0xE355, 0x7B8C, 0xE356, 0x7B9B, 0xE357, 0x7B8E, + 0xE358, 0x7B85, 0xE359, 0x7B98, 0xE35A, 0x5284, 0xE35B, 0x7B99, + 0xE35C, 0x7BA4, 0xE35D, 0x7B82, 0xE35E, 0x7CBB, 0xE35F, 0x7CBF, + 0xE360, 0x7CBC, 0xE361, 0x7CBA, 0xE362, 0x7DA7, 0xE363, 0x7DB7, + 0xE364, 0x7DC2, 0xE365, 0x7DA3, 0xE366, 0x7DAA, 0xE367, 0x7DC1, + 0xE368, 0x7DC0, 0xE369, 0x7DC5, 0xE36A, 0x7D9D, 0xE36B, 0x7DCE, + 0xE36C, 0x7DC4, 0xE36D, 0x7DC6, 0xE36E, 0x7DCB, 0xE36F, 0x7DCC, + 0xE370, 0x7DAF, 0xE371, 0x7DB9, 0xE372, 0x7D96, 0xE373, 0x7DBC, + 0xE374, 0x7D9F, 0xE375, 0x7DA6, 0xE376, 0x7DAE, 0xE377, 0x7DA9, + 0xE378, 0x7DA1, 0xE379, 0x7DC9, 0xE37A, 0x7F73, 0xE37B, 0x7FE2, + 0xE37C, 0x7FE3, 0xE37D, 0x7FE5, 0xE37E, 0x7FDE, 0xE3A1, 0x8024, + 0xE3A2, 0x805D, 0xE3A3, 0x805C, 0xE3A4, 0x8189, 0xE3A5, 0x8186, + 0xE3A6, 0x8183, 0xE3A7, 0x8187, 0xE3A8, 0x818D, 0xE3A9, 0x818C, + 0xE3AA, 0x818B, 0xE3AB, 0x8215, 0xE3AC, 0x8497, 0xE3AD, 0x84A4, + 0xE3AE, 0x84A1, 0xE3AF, 0x849F, 0xE3B0, 0x84BA, 0xE3B1, 0x84CE, + 0xE3B2, 0x84C2, 0xE3B3, 0x84AC, 0xE3B4, 0x84AE, 0xE3B5, 0x84AB, + 0xE3B6, 0x84B9, 0xE3B7, 0x84B4, 0xE3B8, 0x84C1, 0xE3B9, 0x84CD, + 0xE3BA, 0x84AA, 0xE3BB, 0x849A, 0xE3BC, 0x84B1, 0xE3BD, 0x84D0, + 0xE3BE, 0x849D, 0xE3BF, 0x84A7, 0xE3C0, 0x84BB, 0xE3C1, 0x84A2, + 0xE3C2, 0x8494, 0xE3C3, 0x84C7, 0xE3C4, 0x84CC, 0xE3C5, 0x849B, + 0xE3C6, 0x84A9, 0xE3C7, 0x84AF, 0xE3C8, 0x84A8, 0xE3C9, 0x84D6, + 0xE3CA, 0x8498, 0xE3CB, 0x84B6, 0xE3CC, 0x84CF, 0xE3CD, 0x84A0, + 0xE3CE, 0x84D7, 0xE3CF, 0x84D4, 0xE3D0, 0x84D2, 0xE3D1, 0x84DB, + 0xE3D2, 0x84B0, 0xE3D3, 0x8491, 0xE3D4, 0x8661, 0xE3D5, 0x8733, + 0xE3D6, 0x8723, 0xE3D7, 0x8728, 0xE3D8, 0x876B, 0xE3D9, 0x8740, + 0xE3DA, 0x872E, 0xE3DB, 0x871E, 0xE3DC, 0x8721, 0xE3DD, 0x8719, + 0xE3DE, 0x871B, 0xE3DF, 0x8743, 0xE3E0, 0x872C, 0xE3E1, 0x8741, + 0xE3E2, 0x873E, 0xE3E3, 0x8746, 0xE3E4, 0x8720, 0xE3E5, 0x8732, + 0xE3E6, 0x872A, 0xE3E7, 0x872D, 0xE3E8, 0x873C, 0xE3E9, 0x8712, + 0xE3EA, 0x873A, 0xE3EB, 0x8731, 0xE3EC, 0x8735, 0xE3ED, 0x8742, + 0xE3EE, 0x8726, 0xE3EF, 0x8727, 0xE3F0, 0x8738, 0xE3F1, 0x8724, + 0xE3F2, 0x871A, 0xE3F3, 0x8730, 0xE3F4, 0x8711, 0xE3F5, 0x88F7, + 0xE3F6, 0x88E7, 0xE3F7, 0x88F1, 0xE3F8, 0x88F2, 0xE3F9, 0x88FA, + 0xE3FA, 0x88FE, 0xE3FB, 0x88EE, 0xE3FC, 0x88FC, 0xE3FD, 0x88F6, + 0xE3FE, 0x88FB, 0xE440, 0x88F0, 0xE441, 0x88EC, 0xE442, 0x88EB, + 0xE443, 0x899D, 0xE444, 0x89A1, 0xE445, 0x899F, 0xE446, 0x899E, + 0xE447, 0x89E9, 0xE448, 0x89EB, 0xE449, 0x89E8, 0xE44A, 0x8AAB, + 0xE44B, 0x8A99, 0xE44C, 0x8A8B, 0xE44D, 0x8A92, 0xE44E, 0x8A8F, + 0xE44F, 0x8A96, 0xE450, 0x8C3D, 0xE451, 0x8C68, 0xE452, 0x8C69, + 0xE453, 0x8CD5, 0xE454, 0x8CCF, 0xE455, 0x8CD7, 0xE456, 0x8D96, + 0xE457, 0x8E09, 0xE458, 0x8E02, 0xE459, 0x8DFF, 0xE45A, 0x8E0D, + 0xE45B, 0x8DFD, 0xE45C, 0x8E0A, 0xE45D, 0x8E03, 0xE45E, 0x8E07, + 0xE45F, 0x8E06, 0xE460, 0x8E05, 0xE461, 0x8DFE, 0xE462, 0x8E00, + 0xE463, 0x8E04, 0xE464, 0x8F10, 0xE465, 0x8F11, 0xE466, 0x8F0E, + 0xE467, 0x8F0D, 0xE468, 0x9123, 0xE469, 0x911C, 0xE46A, 0x9120, + 0xE46B, 0x9122, 0xE46C, 0x911F, 0xE46D, 0x911D, 0xE46E, 0x911A, + 0xE46F, 0x9124, 0xE470, 0x9121, 0xE471, 0x911B, 0xE472, 0x917A, + 0xE473, 0x9172, 0xE474, 0x9179, 0xE475, 0x9173, 0xE476, 0x92A5, + 0xE477, 0x92A4, 0xE478, 0x9276, 0xE479, 0x929B, 0xE47A, 0x927A, + 0xE47B, 0x92A0, 0xE47C, 0x9294, 0xE47D, 0x92AA, 0xE47E, 0x928D, + 0xE4A1, 0x92A6, 0xE4A2, 0x929A, 0xE4A3, 0x92AB, 0xE4A4, 0x9279, + 0xE4A5, 0x9297, 0xE4A6, 0x927F, 0xE4A7, 0x92A3, 0xE4A8, 0x92EE, + 0xE4A9, 0x928E, 0xE4AA, 0x9282, 0xE4AB, 0x9295, 0xE4AC, 0x92A2, + 0xE4AD, 0x927D, 0xE4AE, 0x9288, 0xE4AF, 0x92A1, 0xE4B0, 0x928A, + 0xE4B1, 0x9286, 0xE4B2, 0x928C, 0xE4B3, 0x9299, 0xE4B4, 0x92A7, + 0xE4B5, 0x927E, 0xE4B6, 0x9287, 0xE4B7, 0x92A9, 0xE4B8, 0x929D, + 0xE4B9, 0x928B, 0xE4BA, 0x922D, 0xE4BB, 0x969E, 0xE4BC, 0x96A1, + 0xE4BD, 0x96FF, 0xE4BE, 0x9758, 0xE4BF, 0x977D, 0xE4C0, 0x977A, + 0xE4C1, 0x977E, 0xE4C2, 0x9783, 0xE4C3, 0x9780, 0xE4C4, 0x9782, + 0xE4C5, 0x977B, 0xE4C6, 0x9784, 0xE4C7, 0x9781, 0xE4C8, 0x977F, + 0xE4C9, 0x97CE, 0xE4CA, 0x97CD, 0xE4CB, 0x9816, 0xE4CC, 0x98AD, + 0xE4CD, 0x98AE, 0xE4CE, 0x9902, 0xE4CF, 0x9900, 0xE4D0, 0x9907, + 0xE4D1, 0x999D, 0xE4D2, 0x999C, 0xE4D3, 0x99C3, 0xE4D4, 0x99B9, + 0xE4D5, 0x99BB, 0xE4D6, 0x99BA, 0xE4D7, 0x99C2, 0xE4D8, 0x99BD, + 0xE4D9, 0x99C7, 0xE4DA, 0x9AB1, 0xE4DB, 0x9AE3, 0xE4DC, 0x9AE7, + 0xE4DD, 0x9B3E, 0xE4DE, 0x9B3F, 0xE4DF, 0x9B60, 0xE4E0, 0x9B61, + 0xE4E1, 0x9B5F, 0xE4E2, 0x9CF1, 0xE4E3, 0x9CF2, 0xE4E4, 0x9CF5, + 0xE4E5, 0x9EA7, 0xE4E6, 0x50FF, 0xE4E7, 0x5103, 0xE4E8, 0x5130, + 0xE4E9, 0x50F8, 0xE4EA, 0x5106, 0xE4EB, 0x5107, 0xE4EC, 0x50F6, + 0xE4ED, 0x50FE, 0xE4EE, 0x510B, 0xE4EF, 0x510C, 0xE4F0, 0x50FD, + 0xE4F1, 0x510A, 0xE4F2, 0x528B, 0xE4F3, 0x528C, 0xE4F4, 0x52F1, + 0xE4F5, 0x52EF, 0xE4F6, 0x5648, 0xE4F7, 0x5642, 0xE4F8, 0x564C, + 0xE4F9, 0x5635, 0xE4FA, 0x5641, 0xE4FB, 0x564A, 0xE4FC, 0x5649, + 0xE4FD, 0x5646, 0xE4FE, 0x5658, 0xE540, 0x565A, 0xE541, 0x5640, + 0xE542, 0x5633, 0xE543, 0x563D, 0xE544, 0x562C, 0xE545, 0x563E, + 0xE546, 0x5638, 0xE547, 0x562A, 0xE548, 0x563A, 0xE549, 0x571A, + 0xE54A, 0x58AB, 0xE54B, 0x589D, 0xE54C, 0x58B1, 0xE54D, 0x58A0, + 0xE54E, 0x58A3, 0xE54F, 0x58AF, 0xE550, 0x58AC, 0xE551, 0x58A5, + 0xE552, 0x58A1, 0xE553, 0x58FF, 0xE554, 0x5AFF, 0xE555, 0x5AF4, + 0xE556, 0x5AFD, 0xE557, 0x5AF7, 0xE558, 0x5AF6, 0xE559, 0x5B03, + 0xE55A, 0x5AF8, 0xE55B, 0x5B02, 0xE55C, 0x5AF9, 0xE55D, 0x5B01, + 0xE55E, 0x5B07, 0xE55F, 0x5B05, 0xE560, 0x5B0F, 0xE561, 0x5C67, + 0xE562, 0x5D99, 0xE563, 0x5D97, 0xE564, 0x5D9F, 0xE565, 0x5D92, + 0xE566, 0x5DA2, 0xE567, 0x5D93, 0xE568, 0x5D95, 0xE569, 0x5DA0, + 0xE56A, 0x5D9C, 0xE56B, 0x5DA1, 0xE56C, 0x5D9A, 0xE56D, 0x5D9E, + 0xE56E, 0x5E69, 0xE56F, 0x5E5D, 0xE570, 0x5E60, 0xE571, 0x5E5C, + 0xE572, 0x7DF3, 0xE573, 0x5EDB, 0xE574, 0x5EDE, 0xE575, 0x5EE1, + 0xE576, 0x5F49, 0xE577, 0x5FB2, 0xE578, 0x618B, 0xE579, 0x6183, + 0xE57A, 0x6179, 0xE57B, 0x61B1, 0xE57C, 0x61B0, 0xE57D, 0x61A2, + 0xE57E, 0x6189, 0xE5A1, 0x619B, 0xE5A2, 0x6193, 0xE5A3, 0x61AF, + 0xE5A4, 0x61AD, 0xE5A5, 0x619F, 0xE5A6, 0x6192, 0xE5A7, 0x61AA, + 0xE5A8, 0x61A1, 0xE5A9, 0x618D, 0xE5AA, 0x6166, 0xE5AB, 0x61B3, + 0xE5AC, 0x622D, 0xE5AD, 0x646E, 0xE5AE, 0x6470, 0xE5AF, 0x6496, + 0xE5B0, 0x64A0, 0xE5B1, 0x6485, 0xE5B2, 0x6497, 0xE5B3, 0x649C, + 0xE5B4, 0x648F, 0xE5B5, 0x648B, 0xE5B6, 0x648A, 0xE5B7, 0x648C, + 0xE5B8, 0x64A3, 0xE5B9, 0x649F, 0xE5BA, 0x6468, 0xE5BB, 0x64B1, + 0xE5BC, 0x6498, 0xE5BD, 0x6576, 0xE5BE, 0x657A, 0xE5BF, 0x6579, + 0xE5C0, 0x657B, 0xE5C1, 0x65B2, 0xE5C2, 0x65B3, 0xE5C3, 0x66B5, + 0xE5C4, 0x66B0, 0xE5C5, 0x66A9, 0xE5C6, 0x66B2, 0xE5C7, 0x66B7, + 0xE5C8, 0x66AA, 0xE5C9, 0x66AF, 0xE5CA, 0x6A00, 0xE5CB, 0x6A06, + 0xE5CC, 0x6A17, 0xE5CD, 0x69E5, 0xE5CE, 0x69F8, 0xE5CF, 0x6A15, + 0xE5D0, 0x69F1, 0xE5D1, 0x69E4, 0xE5D2, 0x6A20, 0xE5D3, 0x69FF, + 0xE5D4, 0x69EC, 0xE5D5, 0x69E2, 0xE5D6, 0x6A1B, 0xE5D7, 0x6A1D, + 0xE5D8, 0x69FE, 0xE5D9, 0x6A27, 0xE5DA, 0x69F2, 0xE5DB, 0x69EE, + 0xE5DC, 0x6A14, 0xE5DD, 0x69F7, 0xE5DE, 0x69E7, 0xE5DF, 0x6A40, + 0xE5E0, 0x6A08, 0xE5E1, 0x69E6, 0xE5E2, 0x69FB, 0xE5E3, 0x6A0D, + 0xE5E4, 0x69FC, 0xE5E5, 0x69EB, 0xE5E6, 0x6A09, 0xE5E7, 0x6A04, + 0xE5E8, 0x6A18, 0xE5E9, 0x6A25, 0xE5EA, 0x6A0F, 0xE5EB, 0x69F6, + 0xE5EC, 0x6A26, 0xE5ED, 0x6A07, 0xE5EE, 0x69F4, 0xE5EF, 0x6A16, + 0xE5F0, 0x6B51, 0xE5F1, 0x6BA5, 0xE5F2, 0x6BA3, 0xE5F3, 0x6BA2, + 0xE5F4, 0x6BA6, 0xE5F5, 0x6C01, 0xE5F6, 0x6C00, 0xE5F7, 0x6BFF, + 0xE5F8, 0x6C02, 0xE5F9, 0x6F41, 0xE5FA, 0x6F26, 0xE5FB, 0x6F7E, + 0xE5FC, 0x6F87, 0xE5FD, 0x6FC6, 0xE5FE, 0x6F92, 0xE640, 0x6F8D, + 0xE641, 0x6F89, 0xE642, 0x6F8C, 0xE643, 0x6F62, 0xE644, 0x6F4F, + 0xE645, 0x6F85, 0xE646, 0x6F5A, 0xE647, 0x6F96, 0xE648, 0x6F76, + 0xE649, 0x6F6C, 0xE64A, 0x6F82, 0xE64B, 0x6F55, 0xE64C, 0x6F72, + 0xE64D, 0x6F52, 0xE64E, 0x6F50, 0xE64F, 0x6F57, 0xE650, 0x6F94, + 0xE651, 0x6F93, 0xE652, 0x6F5D, 0xE653, 0x6F00, 0xE654, 0x6F61, + 0xE655, 0x6F6B, 0xE656, 0x6F7D, 0xE657, 0x6F67, 0xE658, 0x6F90, + 0xE659, 0x6F53, 0xE65A, 0x6F8B, 0xE65B, 0x6F69, 0xE65C, 0x6F7F, + 0xE65D, 0x6F95, 0xE65E, 0x6F63, 0xE65F, 0x6F77, 0xE660, 0x6F6A, + 0xE661, 0x6F7B, 0xE662, 0x71B2, 0xE663, 0x71AF, 0xE664, 0x719B, + 0xE665, 0x71B0, 0xE666, 0x71A0, 0xE667, 0x719A, 0xE668, 0x71A9, + 0xE669, 0x71B5, 0xE66A, 0x719D, 0xE66B, 0x71A5, 0xE66C, 0x719E, + 0xE66D, 0x71A4, 0xE66E, 0x71A1, 0xE66F, 0x71AA, 0xE670, 0x719C, + 0xE671, 0x71A7, 0xE672, 0x71B3, 0xE673, 0x7298, 0xE674, 0x729A, + 0xE675, 0x7358, 0xE676, 0x7352, 0xE677, 0x735E, 0xE678, 0x735F, + 0xE679, 0x7360, 0xE67A, 0x735D, 0xE67B, 0x735B, 0xE67C, 0x7361, + 0xE67D, 0x735A, 0xE67E, 0x7359, 0xE6A1, 0x7362, 0xE6A2, 0x7487, + 0xE6A3, 0x7489, 0xE6A4, 0x748A, 0xE6A5, 0x7486, 0xE6A6, 0x7481, + 0xE6A7, 0x747D, 0xE6A8, 0x7485, 0xE6A9, 0x7488, 0xE6AA, 0x747C, + 0xE6AB, 0x7479, 0xE6AC, 0x7508, 0xE6AD, 0x7507, 0xE6AE, 0x757E, + 0xE6AF, 0x7625, 0xE6B0, 0x761E, 0xE6B1, 0x7619, 0xE6B2, 0x761D, + 0xE6B3, 0x761C, 0xE6B4, 0x7623, 0xE6B5, 0x761A, 0xE6B6, 0x7628, + 0xE6B7, 0x761B, 0xE6B8, 0x769C, 0xE6B9, 0x769D, 0xE6BA, 0x769E, + 0xE6BB, 0x769B, 0xE6BC, 0x778D, 0xE6BD, 0x778F, 0xE6BE, 0x7789, + 0xE6BF, 0x7788, 0xE6C0, 0x78CD, 0xE6C1, 0x78BB, 0xE6C2, 0x78CF, + 0xE6C3, 0x78CC, 0xE6C4, 0x78D1, 0xE6C5, 0x78CE, 0xE6C6, 0x78D4, + 0xE6C7, 0x78C8, 0xE6C8, 0x78C3, 0xE6C9, 0x78C4, 0xE6CA, 0x78C9, + 0xE6CB, 0x799A, 0xE6CC, 0x79A1, 0xE6CD, 0x79A0, 0xE6CE, 0x799C, + 0xE6CF, 0x79A2, 0xE6D0, 0x799B, 0xE6D1, 0x6B76, 0xE6D2, 0x7A39, + 0xE6D3, 0x7AB2, 0xE6D4, 0x7AB4, 0xE6D5, 0x7AB3, 0xE6D6, 0x7BB7, + 0xE6D7, 0x7BCB, 0xE6D8, 0x7BBE, 0xE6D9, 0x7BAC, 0xE6DA, 0x7BCE, + 0xE6DB, 0x7BAF, 0xE6DC, 0x7BB9, 0xE6DD, 0x7BCA, 0xE6DE, 0x7BB5, + 0xE6DF, 0x7CC5, 0xE6E0, 0x7CC8, 0xE6E1, 0x7CCC, 0xE6E2, 0x7CCB, + 0xE6E3, 0x7DF7, 0xE6E4, 0x7DDB, 0xE6E5, 0x7DEA, 0xE6E6, 0x7DE7, + 0xE6E7, 0x7DD7, 0xE6E8, 0x7DE1, 0xE6E9, 0x7E03, 0xE6EA, 0x7DFA, + 0xE6EB, 0x7DE6, 0xE6EC, 0x7DF6, 0xE6ED, 0x7DF1, 0xE6EE, 0x7DF0, + 0xE6EF, 0x7DEE, 0xE6F0, 0x7DDF, 0xE6F1, 0x7F76, 0xE6F2, 0x7FAC, + 0xE6F3, 0x7FB0, 0xE6F4, 0x7FAD, 0xE6F5, 0x7FED, 0xE6F6, 0x7FEB, + 0xE6F7, 0x7FEA, 0xE6F8, 0x7FEC, 0xE6F9, 0x7FE6, 0xE6FA, 0x7FE8, + 0xE6FB, 0x8064, 0xE6FC, 0x8067, 0xE6FD, 0x81A3, 0xE6FE, 0x819F, + 0xE740, 0x819E, 0xE741, 0x8195, 0xE742, 0x81A2, 0xE743, 0x8199, + 0xE744, 0x8197, 0xE745, 0x8216, 0xE746, 0x824F, 0xE747, 0x8253, + 0xE748, 0x8252, 0xE749, 0x8250, 0xE74A, 0x824E, 0xE74B, 0x8251, + 0xE74C, 0x8524, 0xE74D, 0x853B, 0xE74E, 0x850F, 0xE74F, 0x8500, + 0xE750, 0x8529, 0xE751, 0x850E, 0xE752, 0x8509, 0xE753, 0x850D, + 0xE754, 0x851F, 0xE755, 0x850A, 0xE756, 0x8527, 0xE757, 0x851C, + 0xE758, 0x84FB, 0xE759, 0x852B, 0xE75A, 0x84FA, 0xE75B, 0x8508, + 0xE75C, 0x850C, 0xE75D, 0x84F4, 0xE75E, 0x852A, 0xE75F, 0x84F2, + 0xE760, 0x8515, 0xE761, 0x84F7, 0xE762, 0x84EB, 0xE763, 0x84F3, + 0xE764, 0x84FC, 0xE765, 0x8512, 0xE766, 0x84EA, 0xE767, 0x84E9, + 0xE768, 0x8516, 0xE769, 0x84FE, 0xE76A, 0x8528, 0xE76B, 0x851D, + 0xE76C, 0x852E, 0xE76D, 0x8502, 0xE76E, 0x84FD, 0xE76F, 0x851E, + 0xE770, 0x84F6, 0xE771, 0x8531, 0xE772, 0x8526, 0xE773, 0x84E7, + 0xE774, 0x84E8, 0xE775, 0x84F0, 0xE776, 0x84EF, 0xE777, 0x84F9, + 0xE778, 0x8518, 0xE779, 0x8520, 0xE77A, 0x8530, 0xE77B, 0x850B, + 0xE77C, 0x8519, 0xE77D, 0x852F, 0xE77E, 0x8662, 0xE7A1, 0x8756, + 0xE7A2, 0x8763, 0xE7A3, 0x8764, 0xE7A4, 0x8777, 0xE7A5, 0x87E1, + 0xE7A6, 0x8773, 0xE7A7, 0x8758, 0xE7A8, 0x8754, 0xE7A9, 0x875B, + 0xE7AA, 0x8752, 0xE7AB, 0x8761, 0xE7AC, 0x875A, 0xE7AD, 0x8751, + 0xE7AE, 0x875E, 0xE7AF, 0x876D, 0xE7B0, 0x876A, 0xE7B1, 0x8750, + 0xE7B2, 0x874E, 0xE7B3, 0x875F, 0xE7B4, 0x875D, 0xE7B5, 0x876F, + 0xE7B6, 0x876C, 0xE7B7, 0x877A, 0xE7B8, 0x876E, 0xE7B9, 0x875C, + 0xE7BA, 0x8765, 0xE7BB, 0x874F, 0xE7BC, 0x877B, 0xE7BD, 0x8775, + 0xE7BE, 0x8762, 0xE7BF, 0x8767, 0xE7C0, 0x8769, 0xE7C1, 0x885A, + 0xE7C2, 0x8905, 0xE7C3, 0x890C, 0xE7C4, 0x8914, 0xE7C5, 0x890B, + 0xE7C6, 0x8917, 0xE7C7, 0x8918, 0xE7C8, 0x8919, 0xE7C9, 0x8906, + 0xE7CA, 0x8916, 0xE7CB, 0x8911, 0xE7CC, 0x890E, 0xE7CD, 0x8909, + 0xE7CE, 0x89A2, 0xE7CF, 0x89A4, 0xE7D0, 0x89A3, 0xE7D1, 0x89ED, + 0xE7D2, 0x89F0, 0xE7D3, 0x89EC, 0xE7D4, 0x8ACF, 0xE7D5, 0x8AC6, + 0xE7D6, 0x8AB8, 0xE7D7, 0x8AD3, 0xE7D8, 0x8AD1, 0xE7D9, 0x8AD4, + 0xE7DA, 0x8AD5, 0xE7DB, 0x8ABB, 0xE7DC, 0x8AD7, 0xE7DD, 0x8ABE, + 0xE7DE, 0x8AC0, 0xE7DF, 0x8AC5, 0xE7E0, 0x8AD8, 0xE7E1, 0x8AC3, + 0xE7E2, 0x8ABA, 0xE7E3, 0x8ABD, 0xE7E4, 0x8AD9, 0xE7E5, 0x8C3E, + 0xE7E6, 0x8C4D, 0xE7E7, 0x8C8F, 0xE7E8, 0x8CE5, 0xE7E9, 0x8CDF, + 0xE7EA, 0x8CD9, 0xE7EB, 0x8CE8, 0xE7EC, 0x8CDA, 0xE7ED, 0x8CDD, + 0xE7EE, 0x8CE7, 0xE7EF, 0x8DA0, 0xE7F0, 0x8D9C, 0xE7F1, 0x8DA1, + 0xE7F2, 0x8D9B, 0xE7F3, 0x8E20, 0xE7F4, 0x8E23, 0xE7F5, 0x8E25, + 0xE7F6, 0x8E24, 0xE7F7, 0x8E2E, 0xE7F8, 0x8E15, 0xE7F9, 0x8E1B, + 0xE7FA, 0x8E16, 0xE7FB, 0x8E11, 0xE7FC, 0x8E19, 0xE7FD, 0x8E26, + 0xE7FE, 0x8E27, 0xE840, 0x8E14, 0xE841, 0x8E12, 0xE842, 0x8E18, + 0xE843, 0x8E13, 0xE844, 0x8E1C, 0xE845, 0x8E17, 0xE846, 0x8E1A, + 0xE847, 0x8F2C, 0xE848, 0x8F24, 0xE849, 0x8F18, 0xE84A, 0x8F1A, + 0xE84B, 0x8F20, 0xE84C, 0x8F23, 0xE84D, 0x8F16, 0xE84E, 0x8F17, + 0xE84F, 0x9073, 0xE850, 0x9070, 0xE851, 0x906F, 0xE852, 0x9067, + 0xE853, 0x906B, 0xE854, 0x912F, 0xE855, 0x912B, 0xE856, 0x9129, + 0xE857, 0x912A, 0xE858, 0x9132, 0xE859, 0x9126, 0xE85A, 0x912E, + 0xE85B, 0x9185, 0xE85C, 0x9186, 0xE85D, 0x918A, 0xE85E, 0x9181, + 0xE85F, 0x9182, 0xE860, 0x9184, 0xE861, 0x9180, 0xE862, 0x92D0, + 0xE863, 0x92C3, 0xE864, 0x92C4, 0xE865, 0x92C0, 0xE866, 0x92D9, + 0xE867, 0x92B6, 0xE868, 0x92CF, 0xE869, 0x92F1, 0xE86A, 0x92DF, + 0xE86B, 0x92D8, 0xE86C, 0x92E9, 0xE86D, 0x92D7, 0xE86E, 0x92DD, + 0xE86F, 0x92CC, 0xE870, 0x92EF, 0xE871, 0x92C2, 0xE872, 0x92E8, + 0xE873, 0x92CA, 0xE874, 0x92C8, 0xE875, 0x92CE, 0xE876, 0x92E6, + 0xE877, 0x92CD, 0xE878, 0x92D5, 0xE879, 0x92C9, 0xE87A, 0x92E0, + 0xE87B, 0x92DE, 0xE87C, 0x92E7, 0xE87D, 0x92D1, 0xE87E, 0x92D3, + 0xE8A1, 0x92B5, 0xE8A2, 0x92E1, 0xE8A3, 0x92C6, 0xE8A4, 0x92B4, + 0xE8A5, 0x957C, 0xE8A6, 0x95AC, 0xE8A7, 0x95AB, 0xE8A8, 0x95AE, + 0xE8A9, 0x95B0, 0xE8AA, 0x96A4, 0xE8AB, 0x96A2, 0xE8AC, 0x96D3, + 0xE8AD, 0x9705, 0xE8AE, 0x9708, 0xE8AF, 0x9702, 0xE8B0, 0x975A, + 0xE8B1, 0x978A, 0xE8B2, 0x978E, 0xE8B3, 0x9788, 0xE8B4, 0x97D0, + 0xE8B5, 0x97CF, 0xE8B6, 0x981E, 0xE8B7, 0x981D, 0xE8B8, 0x9826, + 0xE8B9, 0x9829, 0xE8BA, 0x9828, 0xE8BB, 0x9820, 0xE8BC, 0x981B, + 0xE8BD, 0x9827, 0xE8BE, 0x98B2, 0xE8BF, 0x9908, 0xE8C0, 0x98FA, + 0xE8C1, 0x9911, 0xE8C2, 0x9914, 0xE8C3, 0x9916, 0xE8C4, 0x9917, + 0xE8C5, 0x9915, 0xE8C6, 0x99DC, 0xE8C7, 0x99CD, 0xE8C8, 0x99CF, + 0xE8C9, 0x99D3, 0xE8CA, 0x99D4, 0xE8CB, 0x99CE, 0xE8CC, 0x99C9, + 0xE8CD, 0x99D6, 0xE8CE, 0x99D8, 0xE8CF, 0x99CB, 0xE8D0, 0x99D7, + 0xE8D1, 0x99CC, 0xE8D2, 0x9AB3, 0xE8D3, 0x9AEC, 0xE8D4, 0x9AEB, + 0xE8D5, 0x9AF3, 0xE8D6, 0x9AF2, 0xE8D7, 0x9AF1, 0xE8D8, 0x9B46, + 0xE8D9, 0x9B43, 0xE8DA, 0x9B67, 0xE8DB, 0x9B74, 0xE8DC, 0x9B71, + 0xE8DD, 0x9B66, 0xE8DE, 0x9B76, 0xE8DF, 0x9B75, 0xE8E0, 0x9B70, + 0xE8E1, 0x9B68, 0xE8E2, 0x9B64, 0xE8E3, 0x9B6C, 0xE8E4, 0x9CFC, + 0xE8E5, 0x9CFA, 0xE8E6, 0x9CFD, 0xE8E7, 0x9CFF, 0xE8E8, 0x9CF7, + 0xE8E9, 0x9D07, 0xE8EA, 0x9D00, 0xE8EB, 0x9CF9, 0xE8EC, 0x9CFB, + 0xE8ED, 0x9D08, 0xE8EE, 0x9D05, 0xE8EF, 0x9D04, 0xE8F0, 0x9E83, + 0xE8F1, 0x9ED3, 0xE8F2, 0x9F0F, 0xE8F3, 0x9F10, 0xE8F4, 0x511C, + 0xE8F5, 0x5113, 0xE8F6, 0x5117, 0xE8F7, 0x511A, 0xE8F8, 0x5111, + 0xE8F9, 0x51DE, 0xE8FA, 0x5334, 0xE8FB, 0x53E1, 0xE8FC, 0x5670, + 0xE8FD, 0x5660, 0xE8FE, 0x566E, 0xE940, 0x5673, 0xE941, 0x5666, + 0xE942, 0x5663, 0xE943, 0x566D, 0xE944, 0x5672, 0xE945, 0x565E, + 0xE946, 0x5677, 0xE947, 0x571C, 0xE948, 0x571B, 0xE949, 0x58C8, + 0xE94A, 0x58BD, 0xE94B, 0x58C9, 0xE94C, 0x58BF, 0xE94D, 0x58BA, + 0xE94E, 0x58C2, 0xE94F, 0x58BC, 0xE950, 0x58C6, 0xE951, 0x5B17, + 0xE952, 0x5B19, 0xE953, 0x5B1B, 0xE954, 0x5B21, 0xE955, 0x5B14, + 0xE956, 0x5B13, 0xE957, 0x5B10, 0xE958, 0x5B16, 0xE959, 0x5B28, + 0xE95A, 0x5B1A, 0xE95B, 0x5B20, 0xE95C, 0x5B1E, 0xE95D, 0x5BEF, + 0xE95E, 0x5DAC, 0xE95F, 0x5DB1, 0xE960, 0x5DA9, 0xE961, 0x5DA7, + 0xE962, 0x5DB5, 0xE963, 0x5DB0, 0xE964, 0x5DAE, 0xE965, 0x5DAA, + 0xE966, 0x5DA8, 0xE967, 0x5DB2, 0xE968, 0x5DAD, 0xE969, 0x5DAF, + 0xE96A, 0x5DB4, 0xE96B, 0x5E67, 0xE96C, 0x5E68, 0xE96D, 0x5E66, + 0xE96E, 0x5E6F, 0xE96F, 0x5EE9, 0xE970, 0x5EE7, 0xE971, 0x5EE6, + 0xE972, 0x5EE8, 0xE973, 0x5EE5, 0xE974, 0x5F4B, 0xE975, 0x5FBC, + 0xE976, 0x619D, 0xE977, 0x61A8, 0xE978, 0x6196, 0xE979, 0x61C5, + 0xE97A, 0x61B4, 0xE97B, 0x61C6, 0xE97C, 0x61C1, 0xE97D, 0x61CC, + 0xE97E, 0x61BA, 0xE9A1, 0x61BF, 0xE9A2, 0x61B8, 0xE9A3, 0x618C, + 0xE9A4, 0x64D7, 0xE9A5, 0x64D6, 0xE9A6, 0x64D0, 0xE9A7, 0x64CF, + 0xE9A8, 0x64C9, 0xE9A9, 0x64BD, 0xE9AA, 0x6489, 0xE9AB, 0x64C3, + 0xE9AC, 0x64DB, 0xE9AD, 0x64F3, 0xE9AE, 0x64D9, 0xE9AF, 0x6533, + 0xE9B0, 0x657F, 0xE9B1, 0x657C, 0xE9B2, 0x65A2, 0xE9B3, 0x66C8, + 0xE9B4, 0x66BE, 0xE9B5, 0x66C0, 0xE9B6, 0x66CA, 0xE9B7, 0x66CB, + 0xE9B8, 0x66CF, 0xE9B9, 0x66BD, 0xE9BA, 0x66BB, 0xE9BB, 0x66BA, + 0xE9BC, 0x66CC, 0xE9BD, 0x6723, 0xE9BE, 0x6A34, 0xE9BF, 0x6A66, + 0xE9C0, 0x6A49, 0xE9C1, 0x6A67, 0xE9C2, 0x6A32, 0xE9C3, 0x6A68, + 0xE9C4, 0x6A3E, 0xE9C5, 0x6A5D, 0xE9C6, 0x6A6D, 0xE9C7, 0x6A76, + 0xE9C8, 0x6A5B, 0xE9C9, 0x6A51, 0xE9CA, 0x6A28, 0xE9CB, 0x6A5A, + 0xE9CC, 0x6A3B, 0xE9CD, 0x6A3F, 0xE9CE, 0x6A41, 0xE9CF, 0x6A6A, + 0xE9D0, 0x6A64, 0xE9D1, 0x6A50, 0xE9D2, 0x6A4F, 0xE9D3, 0x6A54, + 0xE9D4, 0x6A6F, 0xE9D5, 0x6A69, 0xE9D6, 0x6A60, 0xE9D7, 0x6A3C, + 0xE9D8, 0x6A5E, 0xE9D9, 0x6A56, 0xE9DA, 0x6A55, 0xE9DB, 0x6A4D, + 0xE9DC, 0x6A4E, 0xE9DD, 0x6A46, 0xE9DE, 0x6B55, 0xE9DF, 0x6B54, + 0xE9E0, 0x6B56, 0xE9E1, 0x6BA7, 0xE9E2, 0x6BAA, 0xE9E3, 0x6BAB, + 0xE9E4, 0x6BC8, 0xE9E5, 0x6BC7, 0xE9E6, 0x6C04, 0xE9E7, 0x6C03, + 0xE9E8, 0x6C06, 0xE9E9, 0x6FAD, 0xE9EA, 0x6FCB, 0xE9EB, 0x6FA3, + 0xE9EC, 0x6FC7, 0xE9ED, 0x6FBC, 0xE9EE, 0x6FCE, 0xE9EF, 0x6FC8, + 0xE9F0, 0x6F5E, 0xE9F1, 0x6FC4, 0xE9F2, 0x6FBD, 0xE9F3, 0x6F9E, + 0xE9F4, 0x6FCA, 0xE9F5, 0x6FA8, 0xE9F6, 0x7004, 0xE9F7, 0x6FA5, + 0xE9F8, 0x6FAE, 0xE9F9, 0x6FBA, 0xE9FA, 0x6FAC, 0xE9FB, 0x6FAA, + 0xE9FC, 0x6FCF, 0xE9FD, 0x6FBF, 0xE9FE, 0x6FB8, 0xEA40, 0x6FA2, + 0xEA41, 0x6FC9, 0xEA42, 0x6FAB, 0xEA43, 0x6FCD, 0xEA44, 0x6FAF, + 0xEA45, 0x6FB2, 0xEA46, 0x6FB0, 0xEA47, 0x71C5, 0xEA48, 0x71C2, + 0xEA49, 0x71BF, 0xEA4A, 0x71B8, 0xEA4B, 0x71D6, 0xEA4C, 0x71C0, + 0xEA4D, 0x71C1, 0xEA4E, 0x71CB, 0xEA4F, 0x71D4, 0xEA50, 0x71CA, + 0xEA51, 0x71C7, 0xEA52, 0x71CF, 0xEA53, 0x71BD, 0xEA54, 0x71D8, + 0xEA55, 0x71BC, 0xEA56, 0x71C6, 0xEA57, 0x71DA, 0xEA58, 0x71DB, + 0xEA59, 0x729D, 0xEA5A, 0x729E, 0xEA5B, 0x7369, 0xEA5C, 0x7366, + 0xEA5D, 0x7367, 0xEA5E, 0x736C, 0xEA5F, 0x7365, 0xEA60, 0x736B, + 0xEA61, 0x736A, 0xEA62, 0x747F, 0xEA63, 0x749A, 0xEA64, 0x74A0, + 0xEA65, 0x7494, 0xEA66, 0x7492, 0xEA67, 0x7495, 0xEA68, 0x74A1, + 0xEA69, 0x750B, 0xEA6A, 0x7580, 0xEA6B, 0x762F, 0xEA6C, 0x762D, + 0xEA6D, 0x7631, 0xEA6E, 0x763D, 0xEA6F, 0x7633, 0xEA70, 0x763C, + 0xEA71, 0x7635, 0xEA72, 0x7632, 0xEA73, 0x7630, 0xEA74, 0x76BB, + 0xEA75, 0x76E6, 0xEA76, 0x779A, 0xEA77, 0x779D, 0xEA78, 0x77A1, + 0xEA79, 0x779C, 0xEA7A, 0x779B, 0xEA7B, 0x77A2, 0xEA7C, 0x77A3, + 0xEA7D, 0x7795, 0xEA7E, 0x7799, 0xEAA1, 0x7797, 0xEAA2, 0x78DD, + 0xEAA3, 0x78E9, 0xEAA4, 0x78E5, 0xEAA5, 0x78EA, 0xEAA6, 0x78DE, + 0xEAA7, 0x78E3, 0xEAA8, 0x78DB, 0xEAA9, 0x78E1, 0xEAAA, 0x78E2, + 0xEAAB, 0x78ED, 0xEAAC, 0x78DF, 0xEAAD, 0x78E0, 0xEAAE, 0x79A4, + 0xEAAF, 0x7A44, 0xEAB0, 0x7A48, 0xEAB1, 0x7A47, 0xEAB2, 0x7AB6, + 0xEAB3, 0x7AB8, 0xEAB4, 0x7AB5, 0xEAB5, 0x7AB1, 0xEAB6, 0x7AB7, + 0xEAB7, 0x7BDE, 0xEAB8, 0x7BE3, 0xEAB9, 0x7BE7, 0xEABA, 0x7BDD, + 0xEABB, 0x7BD5, 0xEABC, 0x7BE5, 0xEABD, 0x7BDA, 0xEABE, 0x7BE8, + 0xEABF, 0x7BF9, 0xEAC0, 0x7BD4, 0xEAC1, 0x7BEA, 0xEAC2, 0x7BE2, + 0xEAC3, 0x7BDC, 0xEAC4, 0x7BEB, 0xEAC5, 0x7BD8, 0xEAC6, 0x7BDF, + 0xEAC7, 0x7CD2, 0xEAC8, 0x7CD4, 0xEAC9, 0x7CD7, 0xEACA, 0x7CD0, + 0xEACB, 0x7CD1, 0xEACC, 0x7E12, 0xEACD, 0x7E21, 0xEACE, 0x7E17, + 0xEACF, 0x7E0C, 0xEAD0, 0x7E1F, 0xEAD1, 0x7E20, 0xEAD2, 0x7E13, + 0xEAD3, 0x7E0E, 0xEAD4, 0x7E1C, 0xEAD5, 0x7E15, 0xEAD6, 0x7E1A, + 0xEAD7, 0x7E22, 0xEAD8, 0x7E0B, 0xEAD9, 0x7E0F, 0xEADA, 0x7E16, + 0xEADB, 0x7E0D, 0xEADC, 0x7E14, 0xEADD, 0x7E25, 0xEADE, 0x7E24, + 0xEADF, 0x7F43, 0xEAE0, 0x7F7B, 0xEAE1, 0x7F7C, 0xEAE2, 0x7F7A, + 0xEAE3, 0x7FB1, 0xEAE4, 0x7FEF, 0xEAE5, 0x802A, 0xEAE6, 0x8029, + 0xEAE7, 0x806C, 0xEAE8, 0x81B1, 0xEAE9, 0x81A6, 0xEAEA, 0x81AE, + 0xEAEB, 0x81B9, 0xEAEC, 0x81B5, 0xEAED, 0x81AB, 0xEAEE, 0x81B0, + 0xEAEF, 0x81AC, 0xEAF0, 0x81B4, 0xEAF1, 0x81B2, 0xEAF2, 0x81B7, + 0xEAF3, 0x81A7, 0xEAF4, 0x81F2, 0xEAF5, 0x8255, 0xEAF6, 0x8256, + 0xEAF7, 0x8257, 0xEAF8, 0x8556, 0xEAF9, 0x8545, 0xEAFA, 0x856B, + 0xEAFB, 0x854D, 0xEAFC, 0x8553, 0xEAFD, 0x8561, 0xEAFE, 0x8558, + 0xEB40, 0x8540, 0xEB41, 0x8546, 0xEB42, 0x8564, 0xEB43, 0x8541, + 0xEB44, 0x8562, 0xEB45, 0x8544, 0xEB46, 0x8551, 0xEB47, 0x8547, + 0xEB48, 0x8563, 0xEB49, 0x853E, 0xEB4A, 0x855B, 0xEB4B, 0x8571, + 0xEB4C, 0x854E, 0xEB4D, 0x856E, 0xEB4E, 0x8575, 0xEB4F, 0x8555, + 0xEB50, 0x8567, 0xEB51, 0x8560, 0xEB52, 0x858C, 0xEB53, 0x8566, + 0xEB54, 0x855D, 0xEB55, 0x8554, 0xEB56, 0x8565, 0xEB57, 0x856C, + 0xEB58, 0x8663, 0xEB59, 0x8665, 0xEB5A, 0x8664, 0xEB5B, 0x879B, + 0xEB5C, 0x878F, 0xEB5D, 0x8797, 0xEB5E, 0x8793, 0xEB5F, 0x8792, + 0xEB60, 0x8788, 0xEB61, 0x8781, 0xEB62, 0x8796, 0xEB63, 0x8798, + 0xEB64, 0x8779, 0xEB65, 0x8787, 0xEB66, 0x87A3, 0xEB67, 0x8785, + 0xEB68, 0x8790, 0xEB69, 0x8791, 0xEB6A, 0x879D, 0xEB6B, 0x8784, + 0xEB6C, 0x8794, 0xEB6D, 0x879C, 0xEB6E, 0x879A, 0xEB6F, 0x8789, + 0xEB70, 0x891E, 0xEB71, 0x8926, 0xEB72, 0x8930, 0xEB73, 0x892D, + 0xEB74, 0x892E, 0xEB75, 0x8927, 0xEB76, 0x8931, 0xEB77, 0x8922, + 0xEB78, 0x8929, 0xEB79, 0x8923, 0xEB7A, 0x892F, 0xEB7B, 0x892C, + 0xEB7C, 0x891F, 0xEB7D, 0x89F1, 0xEB7E, 0x8AE0, 0xEBA1, 0x8AE2, + 0xEBA2, 0x8AF2, 0xEBA3, 0x8AF4, 0xEBA4, 0x8AF5, 0xEBA5, 0x8ADD, + 0xEBA6, 0x8B14, 0xEBA7, 0x8AE4, 0xEBA8, 0x8ADF, 0xEBA9, 0x8AF0, + 0xEBAA, 0x8AC8, 0xEBAB, 0x8ADE, 0xEBAC, 0x8AE1, 0xEBAD, 0x8AE8, + 0xEBAE, 0x8AFF, 0xEBAF, 0x8AEF, 0xEBB0, 0x8AFB, 0xEBB1, 0x8C91, + 0xEBB2, 0x8C92, 0xEBB3, 0x8C90, 0xEBB4, 0x8CF5, 0xEBB5, 0x8CEE, + 0xEBB6, 0x8CF1, 0xEBB7, 0x8CF0, 0xEBB8, 0x8CF3, 0xEBB9, 0x8D6C, + 0xEBBA, 0x8D6E, 0xEBBB, 0x8DA5, 0xEBBC, 0x8DA7, 0xEBBD, 0x8E33, + 0xEBBE, 0x8E3E, 0xEBBF, 0x8E38, 0xEBC0, 0x8E40, 0xEBC1, 0x8E45, + 0xEBC2, 0x8E36, 0xEBC3, 0x8E3C, 0xEBC4, 0x8E3D, 0xEBC5, 0x8E41, + 0xEBC6, 0x8E30, 0xEBC7, 0x8E3F, 0xEBC8, 0x8EBD, 0xEBC9, 0x8F36, + 0xEBCA, 0x8F2E, 0xEBCB, 0x8F35, 0xEBCC, 0x8F32, 0xEBCD, 0x8F39, + 0xEBCE, 0x8F37, 0xEBCF, 0x8F34, 0xEBD0, 0x9076, 0xEBD1, 0x9079, + 0xEBD2, 0x907B, 0xEBD3, 0x9086, 0xEBD4, 0x90FA, 0xEBD5, 0x9133, + 0xEBD6, 0x9135, 0xEBD7, 0x9136, 0xEBD8, 0x9193, 0xEBD9, 0x9190, + 0xEBDA, 0x9191, 0xEBDB, 0x918D, 0xEBDC, 0x918F, 0xEBDD, 0x9327, + 0xEBDE, 0x931E, 0xEBDF, 0x9308, 0xEBE0, 0x931F, 0xEBE1, 0x9306, + 0xEBE2, 0x930F, 0xEBE3, 0x937A, 0xEBE4, 0x9338, 0xEBE5, 0x933C, + 0xEBE6, 0x931B, 0xEBE7, 0x9323, 0xEBE8, 0x9312, 0xEBE9, 0x9301, + 0xEBEA, 0x9346, 0xEBEB, 0x932D, 0xEBEC, 0x930E, 0xEBED, 0x930D, + 0xEBEE, 0x92CB, 0xEBEF, 0x931D, 0xEBF0, 0x92FA, 0xEBF1, 0x9325, + 0xEBF2, 0x9313, 0xEBF3, 0x92F9, 0xEBF4, 0x92F7, 0xEBF5, 0x9334, + 0xEBF6, 0x9302, 0xEBF7, 0x9324, 0xEBF8, 0x92FF, 0xEBF9, 0x9329, + 0xEBFA, 0x9339, 0xEBFB, 0x9335, 0xEBFC, 0x932A, 0xEBFD, 0x9314, + 0xEBFE, 0x930C, 0xEC40, 0x930B, 0xEC41, 0x92FE, 0xEC42, 0x9309, + 0xEC43, 0x9300, 0xEC44, 0x92FB, 0xEC45, 0x9316, 0xEC46, 0x95BC, + 0xEC47, 0x95CD, 0xEC48, 0x95BE, 0xEC49, 0x95B9, 0xEC4A, 0x95BA, + 0xEC4B, 0x95B6, 0xEC4C, 0x95BF, 0xEC4D, 0x95B5, 0xEC4E, 0x95BD, + 0xEC4F, 0x96A9, 0xEC50, 0x96D4, 0xEC51, 0x970B, 0xEC52, 0x9712, + 0xEC53, 0x9710, 0xEC54, 0x9799, 0xEC55, 0x9797, 0xEC56, 0x9794, + 0xEC57, 0x97F0, 0xEC58, 0x97F8, 0xEC59, 0x9835, 0xEC5A, 0x982F, + 0xEC5B, 0x9832, 0xEC5C, 0x9924, 0xEC5D, 0x991F, 0xEC5E, 0x9927, + 0xEC5F, 0x9929, 0xEC60, 0x999E, 0xEC61, 0x99EE, 0xEC62, 0x99EC, + 0xEC63, 0x99E5, 0xEC64, 0x99E4, 0xEC65, 0x99F0, 0xEC66, 0x99E3, + 0xEC67, 0x99EA, 0xEC68, 0x99E9, 0xEC69, 0x99E7, 0xEC6A, 0x9AB9, + 0xEC6B, 0x9ABF, 0xEC6C, 0x9AB4, 0xEC6D, 0x9ABB, 0xEC6E, 0x9AF6, + 0xEC6F, 0x9AFA, 0xEC70, 0x9AF9, 0xEC71, 0x9AF7, 0xEC72, 0x9B33, + 0xEC73, 0x9B80, 0xEC74, 0x9B85, 0xEC75, 0x9B87, 0xEC76, 0x9B7C, + 0xEC77, 0x9B7E, 0xEC78, 0x9B7B, 0xEC79, 0x9B82, 0xEC7A, 0x9B93, + 0xEC7B, 0x9B92, 0xEC7C, 0x9B90, 0xEC7D, 0x9B7A, 0xEC7E, 0x9B95, + 0xECA1, 0x9B7D, 0xECA2, 0x9B88, 0xECA3, 0x9D25, 0xECA4, 0x9D17, + 0xECA5, 0x9D20, 0xECA6, 0x9D1E, 0xECA7, 0x9D14, 0xECA8, 0x9D29, + 0xECA9, 0x9D1D, 0xECAA, 0x9D18, 0xECAB, 0x9D22, 0xECAC, 0x9D10, + 0xECAD, 0x9D19, 0xECAE, 0x9D1F, 0xECAF, 0x9E88, 0xECB0, 0x9E86, + 0xECB1, 0x9E87, 0xECB2, 0x9EAE, 0xECB3, 0x9EAD, 0xECB4, 0x9ED5, + 0xECB5, 0x9ED6, 0xECB6, 0x9EFA, 0xECB7, 0x9F12, 0xECB8, 0x9F3D, + 0xECB9, 0x5126, 0xECBA, 0x5125, 0xECBB, 0x5122, 0xECBC, 0x5124, + 0xECBD, 0x5120, 0xECBE, 0x5129, 0xECBF, 0x52F4, 0xECC0, 0x5693, + 0xECC1, 0x568C, 0xECC2, 0x568D, 0xECC3, 0x5686, 0xECC4, 0x5684, + 0xECC5, 0x5683, 0xECC6, 0x567E, 0xECC7, 0x5682, 0xECC8, 0x567F, + 0xECC9, 0x5681, 0xECCA, 0x58D6, 0xECCB, 0x58D4, 0xECCC, 0x58CF, + 0xECCD, 0x58D2, 0xECCE, 0x5B2D, 0xECCF, 0x5B25, 0xECD0, 0x5B32, + 0xECD1, 0x5B23, 0xECD2, 0x5B2C, 0xECD3, 0x5B27, 0xECD4, 0x5B26, + 0xECD5, 0x5B2F, 0xECD6, 0x5B2E, 0xECD7, 0x5B7B, 0xECD8, 0x5BF1, + 0xECD9, 0x5BF2, 0xECDA, 0x5DB7, 0xECDB, 0x5E6C, 0xECDC, 0x5E6A, + 0xECDD, 0x5FBE, 0xECDE, 0x5FBB, 0xECDF, 0x61C3, 0xECE0, 0x61B5, + 0xECE1, 0x61BC, 0xECE2, 0x61E7, 0xECE3, 0x61E0, 0xECE4, 0x61E5, + 0xECE5, 0x61E4, 0xECE6, 0x61E8, 0xECE7, 0x61DE, 0xECE8, 0x64EF, + 0xECE9, 0x64E9, 0xECEA, 0x64E3, 0xECEB, 0x64EB, 0xECEC, 0x64E4, + 0xECED, 0x64E8, 0xECEE, 0x6581, 0xECEF, 0x6580, 0xECF0, 0x65B6, + 0xECF1, 0x65DA, 0xECF2, 0x66D2, 0xECF3, 0x6A8D, 0xECF4, 0x6A96, + 0xECF5, 0x6A81, 0xECF6, 0x6AA5, 0xECF7, 0x6A89, 0xECF8, 0x6A9F, + 0xECF9, 0x6A9B, 0xECFA, 0x6AA1, 0xECFB, 0x6A9E, 0xECFC, 0x6A87, + 0xECFD, 0x6A93, 0xECFE, 0x6A8E, 0xED40, 0x6A95, 0xED41, 0x6A83, + 0xED42, 0x6AA8, 0xED43, 0x6AA4, 0xED44, 0x6A91, 0xED45, 0x6A7F, + 0xED46, 0x6AA6, 0xED47, 0x6A9A, 0xED48, 0x6A85, 0xED49, 0x6A8C, + 0xED4A, 0x6A92, 0xED4B, 0x6B5B, 0xED4C, 0x6BAD, 0xED4D, 0x6C09, + 0xED4E, 0x6FCC, 0xED4F, 0x6FA9, 0xED50, 0x6FF4, 0xED51, 0x6FD4, + 0xED52, 0x6FE3, 0xED53, 0x6FDC, 0xED54, 0x6FED, 0xED55, 0x6FE7, + 0xED56, 0x6FE6, 0xED57, 0x6FDE, 0xED58, 0x6FF2, 0xED59, 0x6FDD, + 0xED5A, 0x6FE2, 0xED5B, 0x6FE8, 0xED5C, 0x71E1, 0xED5D, 0x71F1, + 0xED5E, 0x71E8, 0xED5F, 0x71F2, 0xED60, 0x71E4, 0xED61, 0x71F0, + 0xED62, 0x71E2, 0xED63, 0x7373, 0xED64, 0x736E, 0xED65, 0x736F, + 0xED66, 0x7497, 0xED67, 0x74B2, 0xED68, 0x74AB, 0xED69, 0x7490, + 0xED6A, 0x74AA, 0xED6B, 0x74AD, 0xED6C, 0x74B1, 0xED6D, 0x74A5, + 0xED6E, 0x74AF, 0xED6F, 0x7510, 0xED70, 0x7511, 0xED71, 0x7512, + 0xED72, 0x750F, 0xED73, 0x7584, 0xED74, 0x7643, 0xED75, 0x7648, + 0xED76, 0x7649, 0xED77, 0x7647, 0xED78, 0x76A4, 0xED79, 0x76E9, + 0xED7A, 0x77B5, 0xED7B, 0x77AB, 0xED7C, 0x77B2, 0xED7D, 0x77B7, + 0xED7E, 0x77B6, 0xEDA1, 0x77B4, 0xEDA2, 0x77B1, 0xEDA3, 0x77A8, + 0xEDA4, 0x77F0, 0xEDA5, 0x78F3, 0xEDA6, 0x78FD, 0xEDA7, 0x7902, + 0xEDA8, 0x78FB, 0xEDA9, 0x78FC, 0xEDAA, 0x78F2, 0xEDAB, 0x7905, + 0xEDAC, 0x78F9, 0xEDAD, 0x78FE, 0xEDAE, 0x7904, 0xEDAF, 0x79AB, + 0xEDB0, 0x79A8, 0xEDB1, 0x7A5C, 0xEDB2, 0x7A5B, 0xEDB3, 0x7A56, + 0xEDB4, 0x7A58, 0xEDB5, 0x7A54, 0xEDB6, 0x7A5A, 0xEDB7, 0x7ABE, + 0xEDB8, 0x7AC0, 0xEDB9, 0x7AC1, 0xEDBA, 0x7C05, 0xEDBB, 0x7C0F, + 0xEDBC, 0x7BF2, 0xEDBD, 0x7C00, 0xEDBE, 0x7BFF, 0xEDBF, 0x7BFB, + 0xEDC0, 0x7C0E, 0xEDC1, 0x7BF4, 0xEDC2, 0x7C0B, 0xEDC3, 0x7BF3, + 0xEDC4, 0x7C02, 0xEDC5, 0x7C09, 0xEDC6, 0x7C03, 0xEDC7, 0x7C01, + 0xEDC8, 0x7BF8, 0xEDC9, 0x7BFD, 0xEDCA, 0x7C06, 0xEDCB, 0x7BF0, + 0xEDCC, 0x7BF1, 0xEDCD, 0x7C10, 0xEDCE, 0x7C0A, 0xEDCF, 0x7CE8, + 0xEDD0, 0x7E2D, 0xEDD1, 0x7E3C, 0xEDD2, 0x7E42, 0xEDD3, 0x7E33, + 0xEDD4, 0x9848, 0xEDD5, 0x7E38, 0xEDD6, 0x7E2A, 0xEDD7, 0x7E49, + 0xEDD8, 0x7E40, 0xEDD9, 0x7E47, 0xEDDA, 0x7E29, 0xEDDB, 0x7E4C, + 0xEDDC, 0x7E30, 0xEDDD, 0x7E3B, 0xEDDE, 0x7E36, 0xEDDF, 0x7E44, + 0xEDE0, 0x7E3A, 0xEDE1, 0x7F45, 0xEDE2, 0x7F7F, 0xEDE3, 0x7F7E, + 0xEDE4, 0x7F7D, 0xEDE5, 0x7FF4, 0xEDE6, 0x7FF2, 0xEDE7, 0x802C, + 0xEDE8, 0x81BB, 0xEDE9, 0x81C4, 0xEDEA, 0x81CC, 0xEDEB, 0x81CA, + 0xEDEC, 0x81C5, 0xEDED, 0x81C7, 0xEDEE, 0x81BC, 0xEDEF, 0x81E9, + 0xEDF0, 0x825B, 0xEDF1, 0x825A, 0xEDF2, 0x825C, 0xEDF3, 0x8583, + 0xEDF4, 0x8580, 0xEDF5, 0x858F, 0xEDF6, 0x85A7, 0xEDF7, 0x8595, + 0xEDF8, 0x85A0, 0xEDF9, 0x858B, 0xEDFA, 0x85A3, 0xEDFB, 0x857B, + 0xEDFC, 0x85A4, 0xEDFD, 0x859A, 0xEDFE, 0x859E, 0xEE40, 0x8577, + 0xEE41, 0x857C, 0xEE42, 0x8589, 0xEE43, 0x85A1, 0xEE44, 0x857A, + 0xEE45, 0x8578, 0xEE46, 0x8557, 0xEE47, 0x858E, 0xEE48, 0x8596, + 0xEE49, 0x8586, 0xEE4A, 0x858D, 0xEE4B, 0x8599, 0xEE4C, 0x859D, + 0xEE4D, 0x8581, 0xEE4E, 0x85A2, 0xEE4F, 0x8582, 0xEE50, 0x8588, + 0xEE51, 0x8585, 0xEE52, 0x8579, 0xEE53, 0x8576, 0xEE54, 0x8598, + 0xEE55, 0x8590, 0xEE56, 0x859F, 0xEE57, 0x8668, 0xEE58, 0x87BE, + 0xEE59, 0x87AA, 0xEE5A, 0x87AD, 0xEE5B, 0x87C5, 0xEE5C, 0x87B0, + 0xEE5D, 0x87AC, 0xEE5E, 0x87B9, 0xEE5F, 0x87B5, 0xEE60, 0x87BC, + 0xEE61, 0x87AE, 0xEE62, 0x87C9, 0xEE63, 0x87C3, 0xEE64, 0x87C2, + 0xEE65, 0x87CC, 0xEE66, 0x87B7, 0xEE67, 0x87AF, 0xEE68, 0x87C4, + 0xEE69, 0x87CA, 0xEE6A, 0x87B4, 0xEE6B, 0x87B6, 0xEE6C, 0x87BF, + 0xEE6D, 0x87B8, 0xEE6E, 0x87BD, 0xEE6F, 0x87DE, 0xEE70, 0x87B2, + 0xEE71, 0x8935, 0xEE72, 0x8933, 0xEE73, 0x893C, 0xEE74, 0x893E, + 0xEE75, 0x8941, 0xEE76, 0x8952, 0xEE77, 0x8937, 0xEE78, 0x8942, + 0xEE79, 0x89AD, 0xEE7A, 0x89AF, 0xEE7B, 0x89AE, 0xEE7C, 0x89F2, + 0xEE7D, 0x89F3, 0xEE7E, 0x8B1E, 0xEEA1, 0x8B18, 0xEEA2, 0x8B16, + 0xEEA3, 0x8B11, 0xEEA4, 0x8B05, 0xEEA5, 0x8B0B, 0xEEA6, 0x8B22, + 0xEEA7, 0x8B0F, 0xEEA8, 0x8B12, 0xEEA9, 0x8B15, 0xEEAA, 0x8B07, + 0xEEAB, 0x8B0D, 0xEEAC, 0x8B08, 0xEEAD, 0x8B06, 0xEEAE, 0x8B1C, + 0xEEAF, 0x8B13, 0xEEB0, 0x8B1A, 0xEEB1, 0x8C4F, 0xEEB2, 0x8C70, + 0xEEB3, 0x8C72, 0xEEB4, 0x8C71, 0xEEB5, 0x8C6F, 0xEEB6, 0x8C95, + 0xEEB7, 0x8C94, 0xEEB8, 0x8CF9, 0xEEB9, 0x8D6F, 0xEEBA, 0x8E4E, + 0xEEBB, 0x8E4D, 0xEEBC, 0x8E53, 0xEEBD, 0x8E50, 0xEEBE, 0x8E4C, + 0xEEBF, 0x8E47, 0xEEC0, 0x8F43, 0xEEC1, 0x8F40, 0xEEC2, 0x9085, + 0xEEC3, 0x907E, 0xEEC4, 0x9138, 0xEEC5, 0x919A, 0xEEC6, 0x91A2, + 0xEEC7, 0x919B, 0xEEC8, 0x9199, 0xEEC9, 0x919F, 0xEECA, 0x91A1, + 0xEECB, 0x919D, 0xEECC, 0x91A0, 0xEECD, 0x93A1, 0xEECE, 0x9383, + 0xEECF, 0x93AF, 0xEED0, 0x9364, 0xEED1, 0x9356, 0xEED2, 0x9347, + 0xEED3, 0x937C, 0xEED4, 0x9358, 0xEED5, 0x935C, 0xEED6, 0x9376, + 0xEED7, 0x9349, 0xEED8, 0x9350, 0xEED9, 0x9351, 0xEEDA, 0x9360, + 0xEEDB, 0x936D, 0xEEDC, 0x938F, 0xEEDD, 0x934C, 0xEEDE, 0x936A, + 0xEEDF, 0x9379, 0xEEE0, 0x9357, 0xEEE1, 0x9355, 0xEEE2, 0x9352, + 0xEEE3, 0x934F, 0xEEE4, 0x9371, 0xEEE5, 0x9377, 0xEEE6, 0x937B, + 0xEEE7, 0x9361, 0xEEE8, 0x935E, 0xEEE9, 0x9363, 0xEEEA, 0x9367, + 0xEEEB, 0x9380, 0xEEEC, 0x934E, 0xEEED, 0x9359, 0xEEEE, 0x95C7, + 0xEEEF, 0x95C0, 0xEEF0, 0x95C9, 0xEEF1, 0x95C3, 0xEEF2, 0x95C5, + 0xEEF3, 0x95B7, 0xEEF4, 0x96AE, 0xEEF5, 0x96B0, 0xEEF6, 0x96AC, + 0xEEF7, 0x9720, 0xEEF8, 0x971F, 0xEEF9, 0x9718, 0xEEFA, 0x971D, + 0xEEFB, 0x9719, 0xEEFC, 0x979A, 0xEEFD, 0x97A1, 0xEEFE, 0x979C, + 0xEF40, 0x979E, 0xEF41, 0x979D, 0xEF42, 0x97D5, 0xEF43, 0x97D4, + 0xEF44, 0x97F1, 0xEF45, 0x9841, 0xEF46, 0x9844, 0xEF47, 0x984A, + 0xEF48, 0x9849, 0xEF49, 0x9845, 0xEF4A, 0x9843, 0xEF4B, 0x9925, + 0xEF4C, 0x992B, 0xEF4D, 0x992C, 0xEF4E, 0x992A, 0xEF4F, 0x9933, + 0xEF50, 0x9932, 0xEF51, 0x992F, 0xEF52, 0x992D, 0xEF53, 0x9931, + 0xEF54, 0x9930, 0xEF55, 0x9998, 0xEF56, 0x99A3, 0xEF57, 0x99A1, + 0xEF58, 0x9A02, 0xEF59, 0x99FA, 0xEF5A, 0x99F4, 0xEF5B, 0x99F7, + 0xEF5C, 0x99F9, 0xEF5D, 0x99F8, 0xEF5E, 0x99F6, 0xEF5F, 0x99FB, + 0xEF60, 0x99FD, 0xEF61, 0x99FE, 0xEF62, 0x99FC, 0xEF63, 0x9A03, + 0xEF64, 0x9ABE, 0xEF65, 0x9AFE, 0xEF66, 0x9AFD, 0xEF67, 0x9B01, + 0xEF68, 0x9AFC, 0xEF69, 0x9B48, 0xEF6A, 0x9B9A, 0xEF6B, 0x9BA8, + 0xEF6C, 0x9B9E, 0xEF6D, 0x9B9B, 0xEF6E, 0x9BA6, 0xEF6F, 0x9BA1, + 0xEF70, 0x9BA5, 0xEF71, 0x9BA4, 0xEF72, 0x9B86, 0xEF73, 0x9BA2, + 0xEF74, 0x9BA0, 0xEF75, 0x9BAF, 0xEF76, 0x9D33, 0xEF77, 0x9D41, + 0xEF78, 0x9D67, 0xEF79, 0x9D36, 0xEF7A, 0x9D2E, 0xEF7B, 0x9D2F, + 0xEF7C, 0x9D31, 0xEF7D, 0x9D38, 0xEF7E, 0x9D30, 0xEFA1, 0x9D45, + 0xEFA2, 0x9D42, 0xEFA3, 0x9D43, 0xEFA4, 0x9D3E, 0xEFA5, 0x9D37, + 0xEFA6, 0x9D40, 0xEFA7, 0x9D3D, 0xEFA8, 0x7FF5, 0xEFA9, 0x9D2D, + 0xEFAA, 0x9E8A, 0xEFAB, 0x9E89, 0xEFAC, 0x9E8D, 0xEFAD, 0x9EB0, + 0xEFAE, 0x9EC8, 0xEFAF, 0x9EDA, 0xEFB0, 0x9EFB, 0xEFB1, 0x9EFF, + 0xEFB2, 0x9F24, 0xEFB3, 0x9F23, 0xEFB4, 0x9F22, 0xEFB5, 0x9F54, + 0xEFB6, 0x9FA0, 0xEFB7, 0x5131, 0xEFB8, 0x512D, 0xEFB9, 0x512E, + 0xEFBA, 0x5698, 0xEFBB, 0x569C, 0xEFBC, 0x5697, 0xEFBD, 0x569A, + 0xEFBE, 0x569D, 0xEFBF, 0x5699, 0xEFC0, 0x5970, 0xEFC1, 0x5B3C, + 0xEFC2, 0x5C69, 0xEFC3, 0x5C6A, 0xEFC4, 0x5DC0, 0xEFC5, 0x5E6D, + 0xEFC6, 0x5E6E, 0xEFC7, 0x61D8, 0xEFC8, 0x61DF, 0xEFC9, 0x61ED, + 0xEFCA, 0x61EE, 0xEFCB, 0x61F1, 0xEFCC, 0x61EA, 0xEFCD, 0x61F0, + 0xEFCE, 0x61EB, 0xEFCF, 0x61D6, 0xEFD0, 0x61E9, 0xEFD1, 0x64FF, + 0xEFD2, 0x6504, 0xEFD3, 0x64FD, 0xEFD4, 0x64F8, 0xEFD5, 0x6501, + 0xEFD6, 0x6503, 0xEFD7, 0x64FC, 0xEFD8, 0x6594, 0xEFD9, 0x65DB, + 0xEFDA, 0x66DA, 0xEFDB, 0x66DB, 0xEFDC, 0x66D8, 0xEFDD, 0x6AC5, + 0xEFDE, 0x6AB9, 0xEFDF, 0x6ABD, 0xEFE0, 0x6AE1, 0xEFE1, 0x6AC6, + 0xEFE2, 0x6ABA, 0xEFE3, 0x6AB6, 0xEFE4, 0x6AB7, 0xEFE5, 0x6AC7, + 0xEFE6, 0x6AB4, 0xEFE7, 0x6AAD, 0xEFE8, 0x6B5E, 0xEFE9, 0x6BC9, + 0xEFEA, 0x6C0B, 0xEFEB, 0x7007, 0xEFEC, 0x700C, 0xEFED, 0x700D, + 0xEFEE, 0x7001, 0xEFEF, 0x7005, 0xEFF0, 0x7014, 0xEFF1, 0x700E, + 0xEFF2, 0x6FFF, 0xEFF3, 0x7000, 0xEFF4, 0x6FFB, 0xEFF5, 0x7026, + 0xEFF6, 0x6FFC, 0xEFF7, 0x6FF7, 0xEFF8, 0x700A, 0xEFF9, 0x7201, + 0xEFFA, 0x71FF, 0xEFFB, 0x71F9, 0xEFFC, 0x7203, 0xEFFD, 0x71FD, + 0xEFFE, 0x7376, 0xF040, 0x74B8, 0xF041, 0x74C0, 0xF042, 0x74B5, + 0xF043, 0x74C1, 0xF044, 0x74BE, 0xF045, 0x74B6, 0xF046, 0x74BB, + 0xF047, 0x74C2, 0xF048, 0x7514, 0xF049, 0x7513, 0xF04A, 0x765C, + 0xF04B, 0x7664, 0xF04C, 0x7659, 0xF04D, 0x7650, 0xF04E, 0x7653, + 0xF04F, 0x7657, 0xF050, 0x765A, 0xF051, 0x76A6, 0xF052, 0x76BD, + 0xF053, 0x76EC, 0xF054, 0x77C2, 0xF055, 0x77BA, 0xF056, 0x78FF, + 0xF057, 0x790C, 0xF058, 0x7913, 0xF059, 0x7914, 0xF05A, 0x7909, + 0xF05B, 0x7910, 0xF05C, 0x7912, 0xF05D, 0x7911, 0xF05E, 0x79AD, + 0xF05F, 0x79AC, 0xF060, 0x7A5F, 0xF061, 0x7C1C, 0xF062, 0x7C29, + 0xF063, 0x7C19, 0xF064, 0x7C20, 0xF065, 0x7C1F, 0xF066, 0x7C2D, + 0xF067, 0x7C1D, 0xF068, 0x7C26, 0xF069, 0x7C28, 0xF06A, 0x7C22, + 0xF06B, 0x7C25, 0xF06C, 0x7C30, 0xF06D, 0x7E5C, 0xF06E, 0x7E50, + 0xF06F, 0x7E56, 0xF070, 0x7E63, 0xF071, 0x7E58, 0xF072, 0x7E62, + 0xF073, 0x7E5F, 0xF074, 0x7E51, 0xF075, 0x7E60, 0xF076, 0x7E57, + 0xF077, 0x7E53, 0xF078, 0x7FB5, 0xF079, 0x7FB3, 0xF07A, 0x7FF7, + 0xF07B, 0x7FF8, 0xF07C, 0x8075, 0xF07D, 0x81D1, 0xF07E, 0x81D2, + 0xF0A1, 0x81D0, 0xF0A2, 0x825F, 0xF0A3, 0x825E, 0xF0A4, 0x85B4, + 0xF0A5, 0x85C6, 0xF0A6, 0x85C0, 0xF0A7, 0x85C3, 0xF0A8, 0x85C2, + 0xF0A9, 0x85B3, 0xF0AA, 0x85B5, 0xF0AB, 0x85BD, 0xF0AC, 0x85C7, + 0xF0AD, 0x85C4, 0xF0AE, 0x85BF, 0xF0AF, 0x85CB, 0xF0B0, 0x85CE, + 0xF0B1, 0x85C8, 0xF0B2, 0x85C5, 0xF0B3, 0x85B1, 0xF0B4, 0x85B6, + 0xF0B5, 0x85D2, 0xF0B6, 0x8624, 0xF0B7, 0x85B8, 0xF0B8, 0x85B7, + 0xF0B9, 0x85BE, 0xF0BA, 0x8669, 0xF0BB, 0x87E7, 0xF0BC, 0x87E6, + 0xF0BD, 0x87E2, 0xF0BE, 0x87DB, 0xF0BF, 0x87EB, 0xF0C0, 0x87EA, + 0xF0C1, 0x87E5, 0xF0C2, 0x87DF, 0xF0C3, 0x87F3, 0xF0C4, 0x87E4, + 0xF0C5, 0x87D4, 0xF0C6, 0x87DC, 0xF0C7, 0x87D3, 0xF0C8, 0x87ED, + 0xF0C9, 0x87D8, 0xF0CA, 0x87E3, 0xF0CB, 0x87A4, 0xF0CC, 0x87D7, + 0xF0CD, 0x87D9, 0xF0CE, 0x8801, 0xF0CF, 0x87F4, 0xF0D0, 0x87E8, + 0xF0D1, 0x87DD, 0xF0D2, 0x8953, 0xF0D3, 0x894B, 0xF0D4, 0x894F, + 0xF0D5, 0x894C, 0xF0D6, 0x8946, 0xF0D7, 0x8950, 0xF0D8, 0x8951, + 0xF0D9, 0x8949, 0xF0DA, 0x8B2A, 0xF0DB, 0x8B27, 0xF0DC, 0x8B23, + 0xF0DD, 0x8B33, 0xF0DE, 0x8B30, 0xF0DF, 0x8B35, 0xF0E0, 0x8B47, + 0xF0E1, 0x8B2F, 0xF0E2, 0x8B3C, 0xF0E3, 0x8B3E, 0xF0E4, 0x8B31, + 0xF0E5, 0x8B25, 0xF0E6, 0x8B37, 0xF0E7, 0x8B26, 0xF0E8, 0x8B36, + 0xF0E9, 0x8B2E, 0xF0EA, 0x8B24, 0xF0EB, 0x8B3B, 0xF0EC, 0x8B3D, + 0xF0ED, 0x8B3A, 0xF0EE, 0x8C42, 0xF0EF, 0x8C75, 0xF0F0, 0x8C99, + 0xF0F1, 0x8C98, 0xF0F2, 0x8C97, 0xF0F3, 0x8CFE, 0xF0F4, 0x8D04, + 0xF0F5, 0x8D02, 0xF0F6, 0x8D00, 0xF0F7, 0x8E5C, 0xF0F8, 0x8E62, + 0xF0F9, 0x8E60, 0xF0FA, 0x8E57, 0xF0FB, 0x8E56, 0xF0FC, 0x8E5E, + 0xF0FD, 0x8E65, 0xF0FE, 0x8E67, 0xF140, 0x8E5B, 0xF141, 0x8E5A, + 0xF142, 0x8E61, 0xF143, 0x8E5D, 0xF144, 0x8E69, 0xF145, 0x8E54, + 0xF146, 0x8F46, 0xF147, 0x8F47, 0xF148, 0x8F48, 0xF149, 0x8F4B, + 0xF14A, 0x9128, 0xF14B, 0x913A, 0xF14C, 0x913B, 0xF14D, 0x913E, + 0xF14E, 0x91A8, 0xF14F, 0x91A5, 0xF150, 0x91A7, 0xF151, 0x91AF, + 0xF152, 0x91AA, 0xF153, 0x93B5, 0xF154, 0x938C, 0xF155, 0x9392, + 0xF156, 0x93B7, 0xF157, 0x939B, 0xF158, 0x939D, 0xF159, 0x9389, + 0xF15A, 0x93A7, 0xF15B, 0x938E, 0xF15C, 0x93AA, 0xF15D, 0x939E, + 0xF15E, 0x93A6, 0xF15F, 0x9395, 0xF160, 0x9388, 0xF161, 0x9399, + 0xF162, 0x939F, 0xF163, 0x938D, 0xF164, 0x93B1, 0xF165, 0x9391, + 0xF166, 0x93B2, 0xF167, 0x93A4, 0xF168, 0x93A8, 0xF169, 0x93B4, + 0xF16A, 0x93A3, 0xF16B, 0x93A5, 0xF16C, 0x95D2, 0xF16D, 0x95D3, + 0xF16E, 0x95D1, 0xF16F, 0x96B3, 0xF170, 0x96D7, 0xF171, 0x96DA, + 0xF172, 0x5DC2, 0xF173, 0x96DF, 0xF174, 0x96D8, 0xF175, 0x96DD, + 0xF176, 0x9723, 0xF177, 0x9722, 0xF178, 0x9725, 0xF179, 0x97AC, + 0xF17A, 0x97AE, 0xF17B, 0x97A8, 0xF17C, 0x97AB, 0xF17D, 0x97A4, + 0xF17E, 0x97AA, 0xF1A1, 0x97A2, 0xF1A2, 0x97A5, 0xF1A3, 0x97D7, + 0xF1A4, 0x97D9, 0xF1A5, 0x97D6, 0xF1A6, 0x97D8, 0xF1A7, 0x97FA, + 0xF1A8, 0x9850, 0xF1A9, 0x9851, 0xF1AA, 0x9852, 0xF1AB, 0x98B8, + 0xF1AC, 0x9941, 0xF1AD, 0x993C, 0xF1AE, 0x993A, 0xF1AF, 0x9A0F, + 0xF1B0, 0x9A0B, 0xF1B1, 0x9A09, 0xF1B2, 0x9A0D, 0xF1B3, 0x9A04, + 0xF1B4, 0x9A11, 0xF1B5, 0x9A0A, 0xF1B6, 0x9A05, 0xF1B7, 0x9A07, + 0xF1B8, 0x9A06, 0xF1B9, 0x9AC0, 0xF1BA, 0x9ADC, 0xF1BB, 0x9B08, + 0xF1BC, 0x9B04, 0xF1BD, 0x9B05, 0xF1BE, 0x9B29, 0xF1BF, 0x9B35, + 0xF1C0, 0x9B4A, 0xF1C1, 0x9B4C, 0xF1C2, 0x9B4B, 0xF1C3, 0x9BC7, + 0xF1C4, 0x9BC6, 0xF1C5, 0x9BC3, 0xF1C6, 0x9BBF, 0xF1C7, 0x9BC1, + 0xF1C8, 0x9BB5, 0xF1C9, 0x9BB8, 0xF1CA, 0x9BD3, 0xF1CB, 0x9BB6, + 0xF1CC, 0x9BC4, 0xF1CD, 0x9BB9, 0xF1CE, 0x9BBD, 0xF1CF, 0x9D5C, + 0xF1D0, 0x9D53, 0xF1D1, 0x9D4F, 0xF1D2, 0x9D4A, 0xF1D3, 0x9D5B, + 0xF1D4, 0x9D4B, 0xF1D5, 0x9D59, 0xF1D6, 0x9D56, 0xF1D7, 0x9D4C, + 0xF1D8, 0x9D57, 0xF1D9, 0x9D52, 0xF1DA, 0x9D54, 0xF1DB, 0x9D5F, + 0xF1DC, 0x9D58, 0xF1DD, 0x9D5A, 0xF1DE, 0x9E8E, 0xF1DF, 0x9E8C, + 0xF1E0, 0x9EDF, 0xF1E1, 0x9F01, 0xF1E2, 0x9F00, 0xF1E3, 0x9F16, + 0xF1E4, 0x9F25, 0xF1E5, 0x9F2B, 0xF1E6, 0x9F2A, 0xF1E7, 0x9F29, + 0xF1E8, 0x9F28, 0xF1E9, 0x9F4C, 0xF1EA, 0x9F55, 0xF1EB, 0x5134, + 0xF1EC, 0x5135, 0xF1ED, 0x5296, 0xF1EE, 0x52F7, 0xF1EF, 0x53B4, + 0xF1F0, 0x56AB, 0xF1F1, 0x56AD, 0xF1F2, 0x56A6, 0xF1F3, 0x56A7, + 0xF1F4, 0x56AA, 0xF1F5, 0x56AC, 0xF1F6, 0x58DA, 0xF1F7, 0x58DD, + 0xF1F8, 0x58DB, 0xF1F9, 0x5912, 0xF1FA, 0x5B3D, 0xF1FB, 0x5B3E, + 0xF1FC, 0x5B3F, 0xF1FD, 0x5DC3, 0xF1FE, 0x5E70, 0xF240, 0x5FBF, + 0xF241, 0x61FB, 0xF242, 0x6507, 0xF243, 0x6510, 0xF244, 0x650D, + 0xF245, 0x6509, 0xF246, 0x650C, 0xF247, 0x650E, 0xF248, 0x6584, + 0xF249, 0x65DE, 0xF24A, 0x65DD, 0xF24B, 0x66DE, 0xF24C, 0x6AE7, + 0xF24D, 0x6AE0, 0xF24E, 0x6ACC, 0xF24F, 0x6AD1, 0xF250, 0x6AD9, + 0xF251, 0x6ACB, 0xF252, 0x6ADF, 0xF253, 0x6ADC, 0xF254, 0x6AD0, + 0xF255, 0x6AEB, 0xF256, 0x6ACF, 0xF257, 0x6ACD, 0xF258, 0x6ADE, + 0xF259, 0x6B60, 0xF25A, 0x6BB0, 0xF25B, 0x6C0C, 0xF25C, 0x7019, + 0xF25D, 0x7027, 0xF25E, 0x7020, 0xF25F, 0x7016, 0xF260, 0x702B, + 0xF261, 0x7021, 0xF262, 0x7022, 0xF263, 0x7023, 0xF264, 0x7029, + 0xF265, 0x7017, 0xF266, 0x7024, 0xF267, 0x701C, 0xF268, 0x702A, + 0xF269, 0x720C, 0xF26A, 0x720A, 0xF26B, 0x7207, 0xF26C, 0x7202, + 0xF26D, 0x7205, 0xF26E, 0x72A5, 0xF26F, 0x72A6, 0xF270, 0x72A4, + 0xF271, 0x72A3, 0xF272, 0x72A1, 0xF273, 0x74CB, 0xF274, 0x74C5, + 0xF275, 0x74B7, 0xF276, 0x74C3, 0xF277, 0x7516, 0xF278, 0x7660, + 0xF279, 0x77C9, 0xF27A, 0x77CA, 0xF27B, 0x77C4, 0xF27C, 0x77F1, + 0xF27D, 0x791D, 0xF27E, 0x791B, 0xF2A1, 0x7921, 0xF2A2, 0x791C, + 0xF2A3, 0x7917, 0xF2A4, 0x791E, 0xF2A5, 0x79B0, 0xF2A6, 0x7A67, + 0xF2A7, 0x7A68, 0xF2A8, 0x7C33, 0xF2A9, 0x7C3C, 0xF2AA, 0x7C39, + 0xF2AB, 0x7C2C, 0xF2AC, 0x7C3B, 0xF2AD, 0x7CEC, 0xF2AE, 0x7CEA, + 0xF2AF, 0x7E76, 0xF2B0, 0x7E75, 0xF2B1, 0x7E78, 0xF2B2, 0x7E70, + 0xF2B3, 0x7E77, 0xF2B4, 0x7E6F, 0xF2B5, 0x7E7A, 0xF2B6, 0x7E72, + 0xF2B7, 0x7E74, 0xF2B8, 0x7E68, 0xF2B9, 0x7F4B, 0xF2BA, 0x7F4A, + 0xF2BB, 0x7F83, 0xF2BC, 0x7F86, 0xF2BD, 0x7FB7, 0xF2BE, 0x7FFD, + 0xF2BF, 0x7FFE, 0xF2C0, 0x8078, 0xF2C1, 0x81D7, 0xF2C2, 0x81D5, + 0xF2C3, 0x8264, 0xF2C4, 0x8261, 0xF2C5, 0x8263, 0xF2C6, 0x85EB, + 0xF2C7, 0x85F1, 0xF2C8, 0x85ED, 0xF2C9, 0x85D9, 0xF2CA, 0x85E1, + 0xF2CB, 0x85E8, 0xF2CC, 0x85DA, 0xF2CD, 0x85D7, 0xF2CE, 0x85EC, + 0xF2CF, 0x85F2, 0xF2D0, 0x85F8, 0xF2D1, 0x85D8, 0xF2D2, 0x85DF, + 0xF2D3, 0x85E3, 0xF2D4, 0x85DC, 0xF2D5, 0x85D1, 0xF2D6, 0x85F0, + 0xF2D7, 0x85E6, 0xF2D8, 0x85EF, 0xF2D9, 0x85DE, 0xF2DA, 0x85E2, + 0xF2DB, 0x8800, 0xF2DC, 0x87FA, 0xF2DD, 0x8803, 0xF2DE, 0x87F6, + 0xF2DF, 0x87F7, 0xF2E0, 0x8809, 0xF2E1, 0x880C, 0xF2E2, 0x880B, + 0xF2E3, 0x8806, 0xF2E4, 0x87FC, 0xF2E5, 0x8808, 0xF2E6, 0x87FF, + 0xF2E7, 0x880A, 0xF2E8, 0x8802, 0xF2E9, 0x8962, 0xF2EA, 0x895A, + 0xF2EB, 0x895B, 0xF2EC, 0x8957, 0xF2ED, 0x8961, 0xF2EE, 0x895C, + 0xF2EF, 0x8958, 0xF2F0, 0x895D, 0xF2F1, 0x8959, 0xF2F2, 0x8988, + 0xF2F3, 0x89B7, 0xF2F4, 0x89B6, 0xF2F5, 0x89F6, 0xF2F6, 0x8B50, + 0xF2F7, 0x8B48, 0xF2F8, 0x8B4A, 0xF2F9, 0x8B40, 0xF2FA, 0x8B53, + 0xF2FB, 0x8B56, 0xF2FC, 0x8B54, 0xF2FD, 0x8B4B, 0xF2FE, 0x8B55, + 0xF340, 0x8B51, 0xF341, 0x8B42, 0xF342, 0x8B52, 0xF343, 0x8B57, + 0xF344, 0x8C43, 0xF345, 0x8C77, 0xF346, 0x8C76, 0xF347, 0x8C9A, + 0xF348, 0x8D06, 0xF349, 0x8D07, 0xF34A, 0x8D09, 0xF34B, 0x8DAC, + 0xF34C, 0x8DAA, 0xF34D, 0x8DAD, 0xF34E, 0x8DAB, 0xF34F, 0x8E6D, + 0xF350, 0x8E78, 0xF351, 0x8E73, 0xF352, 0x8E6A, 0xF353, 0x8E6F, + 0xF354, 0x8E7B, 0xF355, 0x8EC2, 0xF356, 0x8F52, 0xF357, 0x8F51, + 0xF358, 0x8F4F, 0xF359, 0x8F50, 0xF35A, 0x8F53, 0xF35B, 0x8FB4, + 0xF35C, 0x9140, 0xF35D, 0x913F, 0xF35E, 0x91B0, 0xF35F, 0x91AD, + 0xF360, 0x93DE, 0xF361, 0x93C7, 0xF362, 0x93CF, 0xF363, 0x93C2, + 0xF364, 0x93DA, 0xF365, 0x93D0, 0xF366, 0x93F9, 0xF367, 0x93EC, + 0xF368, 0x93CC, 0xF369, 0x93D9, 0xF36A, 0x93A9, 0xF36B, 0x93E6, + 0xF36C, 0x93CA, 0xF36D, 0x93D4, 0xF36E, 0x93EE, 0xF36F, 0x93E3, + 0xF370, 0x93D5, 0xF371, 0x93C4, 0xF372, 0x93CE, 0xF373, 0x93C0, + 0xF374, 0x93D2, 0xF375, 0x93E7, 0xF376, 0x957D, 0xF377, 0x95DA, + 0xF378, 0x95DB, 0xF379, 0x96E1, 0xF37A, 0x9729, 0xF37B, 0x972B, + 0xF37C, 0x972C, 0xF37D, 0x9728, 0xF37E, 0x9726, 0xF3A1, 0x97B3, + 0xF3A2, 0x97B7, 0xF3A3, 0x97B6, 0xF3A4, 0x97DD, 0xF3A5, 0x97DE, + 0xF3A6, 0x97DF, 0xF3A7, 0x985C, 0xF3A8, 0x9859, 0xF3A9, 0x985D, + 0xF3AA, 0x9857, 0xF3AB, 0x98BF, 0xF3AC, 0x98BD, 0xF3AD, 0x98BB, + 0xF3AE, 0x98BE, 0xF3AF, 0x9948, 0xF3B0, 0x9947, 0xF3B1, 0x9943, + 0xF3B2, 0x99A6, 0xF3B3, 0x99A7, 0xF3B4, 0x9A1A, 0xF3B5, 0x9A15, + 0xF3B6, 0x9A25, 0xF3B7, 0x9A1D, 0xF3B8, 0x9A24, 0xF3B9, 0x9A1B, + 0xF3BA, 0x9A22, 0xF3BB, 0x9A20, 0xF3BC, 0x9A27, 0xF3BD, 0x9A23, + 0xF3BE, 0x9A1E, 0xF3BF, 0x9A1C, 0xF3C0, 0x9A14, 0xF3C1, 0x9AC2, + 0xF3C2, 0x9B0B, 0xF3C3, 0x9B0A, 0xF3C4, 0x9B0E, 0xF3C5, 0x9B0C, + 0xF3C6, 0x9B37, 0xF3C7, 0x9BEA, 0xF3C8, 0x9BEB, 0xF3C9, 0x9BE0, + 0xF3CA, 0x9BDE, 0xF3CB, 0x9BE4, 0xF3CC, 0x9BE6, 0xF3CD, 0x9BE2, + 0xF3CE, 0x9BF0, 0xF3CF, 0x9BD4, 0xF3D0, 0x9BD7, 0xF3D1, 0x9BEC, + 0xF3D2, 0x9BDC, 0xF3D3, 0x9BD9, 0xF3D4, 0x9BE5, 0xF3D5, 0x9BD5, + 0xF3D6, 0x9BE1, 0xF3D7, 0x9BDA, 0xF3D8, 0x9D77, 0xF3D9, 0x9D81, + 0xF3DA, 0x9D8A, 0xF3DB, 0x9D84, 0xF3DC, 0x9D88, 0xF3DD, 0x9D71, + 0xF3DE, 0x9D80, 0xF3DF, 0x9D78, 0xF3E0, 0x9D86, 0xF3E1, 0x9D8B, + 0xF3E2, 0x9D8C, 0xF3E3, 0x9D7D, 0xF3E4, 0x9D6B, 0xF3E5, 0x9D74, + 0xF3E6, 0x9D75, 0xF3E7, 0x9D70, 0xF3E8, 0x9D69, 0xF3E9, 0x9D85, + 0xF3EA, 0x9D73, 0xF3EB, 0x9D7B, 0xF3EC, 0x9D82, 0xF3ED, 0x9D6F, + 0xF3EE, 0x9D79, 0xF3EF, 0x9D7F, 0xF3F0, 0x9D87, 0xF3F1, 0x9D68, + 0xF3F2, 0x9E94, 0xF3F3, 0x9E91, 0xF3F4, 0x9EC0, 0xF3F5, 0x9EFC, + 0xF3F6, 0x9F2D, 0xF3F7, 0x9F40, 0xF3F8, 0x9F41, 0xF3F9, 0x9F4D, + 0xF3FA, 0x9F56, 0xF3FB, 0x9F57, 0xF3FC, 0x9F58, 0xF3FD, 0x5337, + 0xF3FE, 0x56B2, 0xF440, 0x56B5, 0xF441, 0x56B3, 0xF442, 0x58E3, + 0xF443, 0x5B45, 0xF444, 0x5DC6, 0xF445, 0x5DC7, 0xF446, 0x5EEE, + 0xF447, 0x5EEF, 0xF448, 0x5FC0, 0xF449, 0x5FC1, 0xF44A, 0x61F9, + 0xF44B, 0x6517, 0xF44C, 0x6516, 0xF44D, 0x6515, 0xF44E, 0x6513, + 0xF44F, 0x65DF, 0xF450, 0x66E8, 0xF451, 0x66E3, 0xF452, 0x66E4, + 0xF453, 0x6AF3, 0xF454, 0x6AF0, 0xF455, 0x6AEA, 0xF456, 0x6AE8, + 0xF457, 0x6AF9, 0xF458, 0x6AF1, 0xF459, 0x6AEE, 0xF45A, 0x6AEF, + 0xF45B, 0x703C, 0xF45C, 0x7035, 0xF45D, 0x702F, 0xF45E, 0x7037, + 0xF45F, 0x7034, 0xF460, 0x7031, 0xF461, 0x7042, 0xF462, 0x7038, + 0xF463, 0x703F, 0xF464, 0x703A, 0xF465, 0x7039, 0xF466, 0x7040, + 0xF467, 0x703B, 0xF468, 0x7033, 0xF469, 0x7041, 0xF46A, 0x7213, + 0xF46B, 0x7214, 0xF46C, 0x72A8, 0xF46D, 0x737D, 0xF46E, 0x737C, + 0xF46F, 0x74BA, 0xF470, 0x76AB, 0xF471, 0x76AA, 0xF472, 0x76BE, + 0xF473, 0x76ED, 0xF474, 0x77CC, 0xF475, 0x77CE, 0xF476, 0x77CF, + 0xF477, 0x77CD, 0xF478, 0x77F2, 0xF479, 0x7925, 0xF47A, 0x7923, + 0xF47B, 0x7927, 0xF47C, 0x7928, 0xF47D, 0x7924, 0xF47E, 0x7929, + 0xF4A1, 0x79B2, 0xF4A2, 0x7A6E, 0xF4A3, 0x7A6C, 0xF4A4, 0x7A6D, + 0xF4A5, 0x7AF7, 0xF4A6, 0x7C49, 0xF4A7, 0x7C48, 0xF4A8, 0x7C4A, + 0xF4A9, 0x7C47, 0xF4AA, 0x7C45, 0xF4AB, 0x7CEE, 0xF4AC, 0x7E7B, + 0xF4AD, 0x7E7E, 0xF4AE, 0x7E81, 0xF4AF, 0x7E80, 0xF4B0, 0x7FBA, + 0xF4B1, 0x7FFF, 0xF4B2, 0x8079, 0xF4B3, 0x81DB, 0xF4B4, 0x81D9, + 0xF4B5, 0x820B, 0xF4B6, 0x8268, 0xF4B7, 0x8269, 0xF4B8, 0x8622, + 0xF4B9, 0x85FF, 0xF4BA, 0x8601, 0xF4BB, 0x85FE, 0xF4BC, 0x861B, + 0xF4BD, 0x8600, 0xF4BE, 0x85F6, 0xF4BF, 0x8604, 0xF4C0, 0x8609, + 0xF4C1, 0x8605, 0xF4C2, 0x860C, 0xF4C3, 0x85FD, 0xF4C4, 0x8819, + 0xF4C5, 0x8810, 0xF4C6, 0x8811, 0xF4C7, 0x8817, 0xF4C8, 0x8813, + 0xF4C9, 0x8816, 0xF4CA, 0x8963, 0xF4CB, 0x8966, 0xF4CC, 0x89B9, + 0xF4CD, 0x89F7, 0xF4CE, 0x8B60, 0xF4CF, 0x8B6A, 0xF4D0, 0x8B5D, + 0xF4D1, 0x8B68, 0xF4D2, 0x8B63, 0xF4D3, 0x8B65, 0xF4D4, 0x8B67, + 0xF4D5, 0x8B6D, 0xF4D6, 0x8DAE, 0xF4D7, 0x8E86, 0xF4D8, 0x8E88, + 0xF4D9, 0x8E84, 0xF4DA, 0x8F59, 0xF4DB, 0x8F56, 0xF4DC, 0x8F57, + 0xF4DD, 0x8F55, 0xF4DE, 0x8F58, 0xF4DF, 0x8F5A, 0xF4E0, 0x908D, + 0xF4E1, 0x9143, 0xF4E2, 0x9141, 0xF4E3, 0x91B7, 0xF4E4, 0x91B5, + 0xF4E5, 0x91B2, 0xF4E6, 0x91B3, 0xF4E7, 0x940B, 0xF4E8, 0x9413, + 0xF4E9, 0x93FB, 0xF4EA, 0x9420, 0xF4EB, 0x940F, 0xF4EC, 0x9414, + 0xF4ED, 0x93FE, 0xF4EE, 0x9415, 0xF4EF, 0x9410, 0xF4F0, 0x9428, + 0xF4F1, 0x9419, 0xF4F2, 0x940D, 0xF4F3, 0x93F5, 0xF4F4, 0x9400, + 0xF4F5, 0x93F7, 0xF4F6, 0x9407, 0xF4F7, 0x940E, 0xF4F8, 0x9416, + 0xF4F9, 0x9412, 0xF4FA, 0x93FA, 0xF4FB, 0x9409, 0xF4FC, 0x93F8, + 0xF4FD, 0x940A, 0xF4FE, 0x93FF, 0xF540, 0x93FC, 0xF541, 0x940C, + 0xF542, 0x93F6, 0xF543, 0x9411, 0xF544, 0x9406, 0xF545, 0x95DE, + 0xF546, 0x95E0, 0xF547, 0x95DF, 0xF548, 0x972E, 0xF549, 0x972F, + 0xF54A, 0x97B9, 0xF54B, 0x97BB, 0xF54C, 0x97FD, 0xF54D, 0x97FE, + 0xF54E, 0x9860, 0xF54F, 0x9862, 0xF550, 0x9863, 0xF551, 0x985F, + 0xF552, 0x98C1, 0xF553, 0x98C2, 0xF554, 0x9950, 0xF555, 0x994E, + 0xF556, 0x9959, 0xF557, 0x994C, 0xF558, 0x994B, 0xF559, 0x9953, + 0xF55A, 0x9A32, 0xF55B, 0x9A34, 0xF55C, 0x9A31, 0xF55D, 0x9A2C, + 0xF55E, 0x9A2A, 0xF55F, 0x9A36, 0xF560, 0x9A29, 0xF561, 0x9A2E, + 0xF562, 0x9A38, 0xF563, 0x9A2D, 0xF564, 0x9AC7, 0xF565, 0x9ACA, + 0xF566, 0x9AC6, 0xF567, 0x9B10, 0xF568, 0x9B12, 0xF569, 0x9B11, + 0xF56A, 0x9C0B, 0xF56B, 0x9C08, 0xF56C, 0x9BF7, 0xF56D, 0x9C05, + 0xF56E, 0x9C12, 0xF56F, 0x9BF8, 0xF570, 0x9C40, 0xF571, 0x9C07, + 0xF572, 0x9C0E, 0xF573, 0x9C06, 0xF574, 0x9C17, 0xF575, 0x9C14, + 0xF576, 0x9C09, 0xF577, 0x9D9F, 0xF578, 0x9D99, 0xF579, 0x9DA4, + 0xF57A, 0x9D9D, 0xF57B, 0x9D92, 0xF57C, 0x9D98, 0xF57D, 0x9D90, + 0xF57E, 0x9D9B, 0xF5A1, 0x9DA0, 0xF5A2, 0x9D94, 0xF5A3, 0x9D9C, + 0xF5A4, 0x9DAA, 0xF5A5, 0x9D97, 0xF5A6, 0x9DA1, 0xF5A7, 0x9D9A, + 0xF5A8, 0x9DA2, 0xF5A9, 0x9DA8, 0xF5AA, 0x9D9E, 0xF5AB, 0x9DA3, + 0xF5AC, 0x9DBF, 0xF5AD, 0x9DA9, 0xF5AE, 0x9D96, 0xF5AF, 0x9DA6, + 0xF5B0, 0x9DA7, 0xF5B1, 0x9E99, 0xF5B2, 0x9E9B, 0xF5B3, 0x9E9A, + 0xF5B4, 0x9EE5, 0xF5B5, 0x9EE4, 0xF5B6, 0x9EE7, 0xF5B7, 0x9EE6, + 0xF5B8, 0x9F30, 0xF5B9, 0x9F2E, 0xF5BA, 0x9F5B, 0xF5BB, 0x9F60, + 0xF5BC, 0x9F5E, 0xF5BD, 0x9F5D, 0xF5BE, 0x9F59, 0xF5BF, 0x9F91, + 0xF5C0, 0x513A, 0xF5C1, 0x5139, 0xF5C2, 0x5298, 0xF5C3, 0x5297, + 0xF5C4, 0x56C3, 0xF5C5, 0x56BD, 0xF5C6, 0x56BE, 0xF5C7, 0x5B48, + 0xF5C8, 0x5B47, 0xF5C9, 0x5DCB, 0xF5CA, 0x5DCF, 0xF5CB, 0x5EF1, + 0xF5CC, 0x61FD, 0xF5CD, 0x651B, 0xF5CE, 0x6B02, 0xF5CF, 0x6AFC, + 0xF5D0, 0x6B03, 0xF5D1, 0x6AF8, 0xF5D2, 0x6B00, 0xF5D3, 0x7043, + 0xF5D4, 0x7044, 0xF5D5, 0x704A, 0xF5D6, 0x7048, 0xF5D7, 0x7049, + 0xF5D8, 0x7045, 0xF5D9, 0x7046, 0xF5DA, 0x721D, 0xF5DB, 0x721A, + 0xF5DC, 0x7219, 0xF5DD, 0x737E, 0xF5DE, 0x7517, 0xF5DF, 0x766A, + 0xF5E0, 0x77D0, 0xF5E1, 0x792D, 0xF5E2, 0x7931, 0xF5E3, 0x792F, + 0xF5E4, 0x7C54, 0xF5E5, 0x7C53, 0xF5E6, 0x7CF2, 0xF5E7, 0x7E8A, + 0xF5E8, 0x7E87, 0xF5E9, 0x7E88, 0xF5EA, 0x7E8B, 0xF5EB, 0x7E86, + 0xF5EC, 0x7E8D, 0xF5ED, 0x7F4D, 0xF5EE, 0x7FBB, 0xF5EF, 0x8030, + 0xF5F0, 0x81DD, 0xF5F1, 0x8618, 0xF5F2, 0x862A, 0xF5F3, 0x8626, + 0xF5F4, 0x861F, 0xF5F5, 0x8623, 0xF5F6, 0x861C, 0xF5F7, 0x8619, + 0xF5F8, 0x8627, 0xF5F9, 0x862E, 0xF5FA, 0x8621, 0xF5FB, 0x8620, + 0xF5FC, 0x8629, 0xF5FD, 0x861E, 0xF5FE, 0x8625, 0xF640, 0x8829, + 0xF641, 0x881D, 0xF642, 0x881B, 0xF643, 0x8820, 0xF644, 0x8824, + 0xF645, 0x881C, 0xF646, 0x882B, 0xF647, 0x884A, 0xF648, 0x896D, + 0xF649, 0x8969, 0xF64A, 0x896E, 0xF64B, 0x896B, 0xF64C, 0x89FA, + 0xF64D, 0x8B79, 0xF64E, 0x8B78, 0xF64F, 0x8B45, 0xF650, 0x8B7A, + 0xF651, 0x8B7B, 0xF652, 0x8D10, 0xF653, 0x8D14, 0xF654, 0x8DAF, + 0xF655, 0x8E8E, 0xF656, 0x8E8C, 0xF657, 0x8F5E, 0xF658, 0x8F5B, + 0xF659, 0x8F5D, 0xF65A, 0x9146, 0xF65B, 0x9144, 0xF65C, 0x9145, + 0xF65D, 0x91B9, 0xF65E, 0x943F, 0xF65F, 0x943B, 0xF660, 0x9436, + 0xF661, 0x9429, 0xF662, 0x943D, 0xF663, 0x943C, 0xF664, 0x9430, + 0xF665, 0x9439, 0xF666, 0x942A, 0xF667, 0x9437, 0xF668, 0x942C, + 0xF669, 0x9440, 0xF66A, 0x9431, 0xF66B, 0x95E5, 0xF66C, 0x95E4, + 0xF66D, 0x95E3, 0xF66E, 0x9735, 0xF66F, 0x973A, 0xF670, 0x97BF, + 0xF671, 0x97E1, 0xF672, 0x9864, 0xF673, 0x98C9, 0xF674, 0x98C6, + 0xF675, 0x98C0, 0xF676, 0x9958, 0xF677, 0x9956, 0xF678, 0x9A39, + 0xF679, 0x9A3D, 0xF67A, 0x9A46, 0xF67B, 0x9A44, 0xF67C, 0x9A42, + 0xF67D, 0x9A41, 0xF67E, 0x9A3A, 0xF6A1, 0x9A3F, 0xF6A2, 0x9ACD, + 0xF6A3, 0x9B15, 0xF6A4, 0x9B17, 0xF6A5, 0x9B18, 0xF6A6, 0x9B16, + 0xF6A7, 0x9B3A, 0xF6A8, 0x9B52, 0xF6A9, 0x9C2B, 0xF6AA, 0x9C1D, + 0xF6AB, 0x9C1C, 0xF6AC, 0x9C2C, 0xF6AD, 0x9C23, 0xF6AE, 0x9C28, + 0xF6AF, 0x9C29, 0xF6B0, 0x9C24, 0xF6B1, 0x9C21, 0xF6B2, 0x9DB7, + 0xF6B3, 0x9DB6, 0xF6B4, 0x9DBC, 0xF6B5, 0x9DC1, 0xF6B6, 0x9DC7, + 0xF6B7, 0x9DCA, 0xF6B8, 0x9DCF, 0xF6B9, 0x9DBE, 0xF6BA, 0x9DC5, + 0xF6BB, 0x9DC3, 0xF6BC, 0x9DBB, 0xF6BD, 0x9DB5, 0xF6BE, 0x9DCE, + 0xF6BF, 0x9DB9, 0xF6C0, 0x9DBA, 0xF6C1, 0x9DAC, 0xF6C2, 0x9DC8, + 0xF6C3, 0x9DB1, 0xF6C4, 0x9DAD, 0xF6C5, 0x9DCC, 0xF6C6, 0x9DB3, + 0xF6C7, 0x9DCD, 0xF6C8, 0x9DB2, 0xF6C9, 0x9E7A, 0xF6CA, 0x9E9C, + 0xF6CB, 0x9EEB, 0xF6CC, 0x9EEE, 0xF6CD, 0x9EED, 0xF6CE, 0x9F1B, + 0xF6CF, 0x9F18, 0xF6D0, 0x9F1A, 0xF6D1, 0x9F31, 0xF6D2, 0x9F4E, + 0xF6D3, 0x9F65, 0xF6D4, 0x9F64, 0xF6D5, 0x9F92, 0xF6D6, 0x4EB9, + 0xF6D7, 0x56C6, 0xF6D8, 0x56C5, 0xF6D9, 0x56CB, 0xF6DA, 0x5971, + 0xF6DB, 0x5B4B, 0xF6DC, 0x5B4C, 0xF6DD, 0x5DD5, 0xF6DE, 0x5DD1, + 0xF6DF, 0x5EF2, 0xF6E0, 0x6521, 0xF6E1, 0x6520, 0xF6E2, 0x6526, + 0xF6E3, 0x6522, 0xF6E4, 0x6B0B, 0xF6E5, 0x6B08, 0xF6E6, 0x6B09, + 0xF6E7, 0x6C0D, 0xF6E8, 0x7055, 0xF6E9, 0x7056, 0xF6EA, 0x7057, + 0xF6EB, 0x7052, 0xF6EC, 0x721E, 0xF6ED, 0x721F, 0xF6EE, 0x72A9, + 0xF6EF, 0x737F, 0xF6F0, 0x74D8, 0xF6F1, 0x74D5, 0xF6F2, 0x74D9, + 0xF6F3, 0x74D7, 0xF6F4, 0x766D, 0xF6F5, 0x76AD, 0xF6F6, 0x7935, + 0xF6F7, 0x79B4, 0xF6F8, 0x7A70, 0xF6F9, 0x7A71, 0xF6FA, 0x7C57, + 0xF6FB, 0x7C5C, 0xF6FC, 0x7C59, 0xF6FD, 0x7C5B, 0xF6FE, 0x7C5A, + 0xF740, 0x7CF4, 0xF741, 0x7CF1, 0xF742, 0x7E91, 0xF743, 0x7F4F, + 0xF744, 0x7F87, 0xF745, 0x81DE, 0xF746, 0x826B, 0xF747, 0x8634, + 0xF748, 0x8635, 0xF749, 0x8633, 0xF74A, 0x862C, 0xF74B, 0x8632, + 0xF74C, 0x8636, 0xF74D, 0x882C, 0xF74E, 0x8828, 0xF74F, 0x8826, + 0xF750, 0x882A, 0xF751, 0x8825, 0xF752, 0x8971, 0xF753, 0x89BF, + 0xF754, 0x89BE, 0xF755, 0x89FB, 0xF756, 0x8B7E, 0xF757, 0x8B84, + 0xF758, 0x8B82, 0xF759, 0x8B86, 0xF75A, 0x8B85, 0xF75B, 0x8B7F, + 0xF75C, 0x8D15, 0xF75D, 0x8E95, 0xF75E, 0x8E94, 0xF75F, 0x8E9A, + 0xF760, 0x8E92, 0xF761, 0x8E90, 0xF762, 0x8E96, 0xF763, 0x8E97, + 0xF764, 0x8F60, 0xF765, 0x8F62, 0xF766, 0x9147, 0xF767, 0x944C, + 0xF768, 0x9450, 0xF769, 0x944A, 0xF76A, 0x944B, 0xF76B, 0x944F, + 0xF76C, 0x9447, 0xF76D, 0x9445, 0xF76E, 0x9448, 0xF76F, 0x9449, + 0xF770, 0x9446, 0xF771, 0x973F, 0xF772, 0x97E3, 0xF773, 0x986A, + 0xF774, 0x9869, 0xF775, 0x98CB, 0xF776, 0x9954, 0xF777, 0x995B, + 0xF778, 0x9A4E, 0xF779, 0x9A53, 0xF77A, 0x9A54, 0xF77B, 0x9A4C, + 0xF77C, 0x9A4F, 0xF77D, 0x9A48, 0xF77E, 0x9A4A, 0xF7A1, 0x9A49, + 0xF7A2, 0x9A52, 0xF7A3, 0x9A50, 0xF7A4, 0x9AD0, 0xF7A5, 0x9B19, + 0xF7A6, 0x9B2B, 0xF7A7, 0x9B3B, 0xF7A8, 0x9B56, 0xF7A9, 0x9B55, + 0xF7AA, 0x9C46, 0xF7AB, 0x9C48, 0xF7AC, 0x9C3F, 0xF7AD, 0x9C44, + 0xF7AE, 0x9C39, 0xF7AF, 0x9C33, 0xF7B0, 0x9C41, 0xF7B1, 0x9C3C, + 0xF7B2, 0x9C37, 0xF7B3, 0x9C34, 0xF7B4, 0x9C32, 0xF7B5, 0x9C3D, + 0xF7B6, 0x9C36, 0xF7B7, 0x9DDB, 0xF7B8, 0x9DD2, 0xF7B9, 0x9DDE, + 0xF7BA, 0x9DDA, 0xF7BB, 0x9DCB, 0xF7BC, 0x9DD0, 0xF7BD, 0x9DDC, + 0xF7BE, 0x9DD1, 0xF7BF, 0x9DDF, 0xF7C0, 0x9DE9, 0xF7C1, 0x9DD9, + 0xF7C2, 0x9DD8, 0xF7C3, 0x9DD6, 0xF7C4, 0x9DF5, 0xF7C5, 0x9DD5, + 0xF7C6, 0x9DDD, 0xF7C7, 0x9EB6, 0xF7C8, 0x9EF0, 0xF7C9, 0x9F35, + 0xF7CA, 0x9F33, 0xF7CB, 0x9F32, 0xF7CC, 0x9F42, 0xF7CD, 0x9F6B, + 0xF7CE, 0x9F95, 0xF7CF, 0x9FA2, 0xF7D0, 0x513D, 0xF7D1, 0x5299, + 0xF7D2, 0x58E8, 0xF7D3, 0x58E7, 0xF7D4, 0x5972, 0xF7D5, 0x5B4D, + 0xF7D6, 0x5DD8, 0xF7D7, 0x882F, 0xF7D8, 0x5F4F, 0xF7D9, 0x6201, + 0xF7DA, 0x6203, 0xF7DB, 0x6204, 0xF7DC, 0x6529, 0xF7DD, 0x6525, + 0xF7DE, 0x6596, 0xF7DF, 0x66EB, 0xF7E0, 0x6B11, 0xF7E1, 0x6B12, + 0xF7E2, 0x6B0F, 0xF7E3, 0x6BCA, 0xF7E4, 0x705B, 0xF7E5, 0x705A, + 0xF7E6, 0x7222, 0xF7E7, 0x7382, 0xF7E8, 0x7381, 0xF7E9, 0x7383, + 0xF7EA, 0x7670, 0xF7EB, 0x77D4, 0xF7EC, 0x7C67, 0xF7ED, 0x7C66, + 0xF7EE, 0x7E95, 0xF7EF, 0x826C, 0xF7F0, 0x863A, 0xF7F1, 0x8640, + 0xF7F2, 0x8639, 0xF7F3, 0x863C, 0xF7F4, 0x8631, 0xF7F5, 0x863B, + 0xF7F6, 0x863E, 0xF7F7, 0x8830, 0xF7F8, 0x8832, 0xF7F9, 0x882E, + 0xF7FA, 0x8833, 0xF7FB, 0x8976, 0xF7FC, 0x8974, 0xF7FD, 0x8973, + 0xF7FE, 0x89FE, 0xF840, 0x8B8C, 0xF841, 0x8B8E, 0xF842, 0x8B8B, + 0xF843, 0x8B88, 0xF844, 0x8C45, 0xF845, 0x8D19, 0xF846, 0x8E98, + 0xF847, 0x8F64, 0xF848, 0x8F63, 0xF849, 0x91BC, 0xF84A, 0x9462, + 0xF84B, 0x9455, 0xF84C, 0x945D, 0xF84D, 0x9457, 0xF84E, 0x945E, + 0xF84F, 0x97C4, 0xF850, 0x97C5, 0xF851, 0x9800, 0xF852, 0x9A56, + 0xF853, 0x9A59, 0xF854, 0x9B1E, 0xF855, 0x9B1F, 0xF856, 0x9B20, + 0xF857, 0x9C52, 0xF858, 0x9C58, 0xF859, 0x9C50, 0xF85A, 0x9C4A, + 0xF85B, 0x9C4D, 0xF85C, 0x9C4B, 0xF85D, 0x9C55, 0xF85E, 0x9C59, + 0xF85F, 0x9C4C, 0xF860, 0x9C4E, 0xF861, 0x9DFB, 0xF862, 0x9DF7, + 0xF863, 0x9DEF, 0xF864, 0x9DE3, 0xF865, 0x9DEB, 0xF866, 0x9DF8, + 0xF867, 0x9DE4, 0xF868, 0x9DF6, 0xF869, 0x9DE1, 0xF86A, 0x9DEE, + 0xF86B, 0x9DE6, 0xF86C, 0x9DF2, 0xF86D, 0x9DF0, 0xF86E, 0x9DE2, + 0xF86F, 0x9DEC, 0xF870, 0x9DF4, 0xF871, 0x9DF3, 0xF872, 0x9DE8, + 0xF873, 0x9DED, 0xF874, 0x9EC2, 0xF875, 0x9ED0, 0xF876, 0x9EF2, + 0xF877, 0x9EF3, 0xF878, 0x9F06, 0xF879, 0x9F1C, 0xF87A, 0x9F38, + 0xF87B, 0x9F37, 0xF87C, 0x9F36, 0xF87D, 0x9F43, 0xF87E, 0x9F4F, + 0xF8A1, 0x9F71, 0xF8A2, 0x9F70, 0xF8A3, 0x9F6E, 0xF8A4, 0x9F6F, + 0xF8A5, 0x56D3, 0xF8A6, 0x56CD, 0xF8A7, 0x5B4E, 0xF8A8, 0x5C6D, + 0xF8A9, 0x652D, 0xF8AA, 0x66ED, 0xF8AB, 0x66EE, 0xF8AC, 0x6B13, + 0xF8AD, 0x705F, 0xF8AE, 0x7061, 0xF8AF, 0x705D, 0xF8B0, 0x7060, + 0xF8B1, 0x7223, 0xF8B2, 0x74DB, 0xF8B3, 0x74E5, 0xF8B4, 0x77D5, + 0xF8B5, 0x7938, 0xF8B6, 0x79B7, 0xF8B7, 0x79B6, 0xF8B8, 0x7C6A, + 0xF8B9, 0x7E97, 0xF8BA, 0x7F89, 0xF8BB, 0x826D, 0xF8BC, 0x8643, + 0xF8BD, 0x8838, 0xF8BE, 0x8837, 0xF8BF, 0x8835, 0xF8C0, 0x884B, + 0xF8C1, 0x8B94, 0xF8C2, 0x8B95, 0xF8C3, 0x8E9E, 0xF8C4, 0x8E9F, + 0xF8C5, 0x8EA0, 0xF8C6, 0x8E9D, 0xF8C7, 0x91BE, 0xF8C8, 0x91BD, + 0xF8C9, 0x91C2, 0xF8CA, 0x946B, 0xF8CB, 0x9468, 0xF8CC, 0x9469, + 0xF8CD, 0x96E5, 0xF8CE, 0x9746, 0xF8CF, 0x9743, 0xF8D0, 0x9747, + 0xF8D1, 0x97C7, 0xF8D2, 0x97E5, 0xF8D3, 0x9A5E, 0xF8D4, 0x9AD5, + 0xF8D5, 0x9B59, 0xF8D6, 0x9C63, 0xF8D7, 0x9C67, 0xF8D8, 0x9C66, + 0xF8D9, 0x9C62, 0xF8DA, 0x9C5E, 0xF8DB, 0x9C60, 0xF8DC, 0x9E02, + 0xF8DD, 0x9DFE, 0xF8DE, 0x9E07, 0xF8DF, 0x9E03, 0xF8E0, 0x9E06, + 0xF8E1, 0x9E05, 0xF8E2, 0x9E00, 0xF8E3, 0x9E01, 0xF8E4, 0x9E09, + 0xF8E5, 0x9DFF, 0xF8E6, 0x9DFD, 0xF8E7, 0x9E04, 0xF8E8, 0x9EA0, + 0xF8E9, 0x9F1E, 0xF8EA, 0x9F46, 0xF8EB, 0x9F74, 0xF8EC, 0x9F75, + 0xF8ED, 0x9F76, 0xF8EE, 0x56D4, 0xF8EF, 0x652E, 0xF8F0, 0x65B8, + 0xF8F1, 0x6B18, 0xF8F2, 0x6B19, 0xF8F3, 0x6B17, 0xF8F4, 0x6B1A, + 0xF8F5, 0x7062, 0xF8F6, 0x7226, 0xF8F7, 0x72AA, 0xF8F8, 0x77D8, + 0xF8F9, 0x77D9, 0xF8FA, 0x7939, 0xF8FB, 0x7C69, 0xF8FC, 0x7C6B, + 0xF8FD, 0x7CF6, 0xF8FE, 0x7E9A, 0xF940, 0x7E98, 0xF941, 0x7E9B, + 0xF942, 0x7E99, 0xF943, 0x81E0, 0xF944, 0x81E1, 0xF945, 0x8646, + 0xF946, 0x8647, 0xF947, 0x8648, 0xF948, 0x8979, 0xF949, 0x897A, + 0xF94A, 0x897C, 0xF94B, 0x897B, 0xF94C, 0x89FF, 0xF94D, 0x8B98, + 0xF94E, 0x8B99, 0xF94F, 0x8EA5, 0xF950, 0x8EA4, 0xF951, 0x8EA3, + 0xF952, 0x946E, 0xF953, 0x946D, 0xF954, 0x946F, 0xF955, 0x9471, + 0xF956, 0x9473, 0xF957, 0x9749, 0xF958, 0x9872, 0xF959, 0x995F, + 0xF95A, 0x9C68, 0xF95B, 0x9C6E, 0xF95C, 0x9C6D, 0xF95D, 0x9E0B, + 0xF95E, 0x9E0D, 0xF95F, 0x9E10, 0xF960, 0x9E0F, 0xF961, 0x9E12, + 0xF962, 0x9E11, 0xF963, 0x9EA1, 0xF964, 0x9EF5, 0xF965, 0x9F09, + 0xF966, 0x9F47, 0xF967, 0x9F78, 0xF968, 0x9F7B, 0xF969, 0x9F7A, + 0xF96A, 0x9F79, 0xF96B, 0x571E, 0xF96C, 0x7066, 0xF96D, 0x7C6F, + 0xF96E, 0x883C, 0xF96F, 0x8DB2, 0xF970, 0x8EA6, 0xF971, 0x91C3, + 0xF972, 0x9474, 0xF973, 0x9478, 0xF974, 0x9476, 0xF975, 0x9475, + 0xF976, 0x9A60, 0xF977, 0x9C74, 0xF978, 0x9C73, 0xF979, 0x9C71, + 0xF97A, 0x9C75, 0xF97B, 0x9E14, 0xF97C, 0x9E13, 0xF97D, 0x9EF6, + 0xF97E, 0x9F0A, 0xF9A1, 0x9FA4, 0xF9A2, 0x7068, 0xF9A3, 0x7065, + 0xF9A4, 0x7CF7, 0xF9A5, 0x866A, 0xF9A6, 0x883E, 0xF9A7, 0x883D, + 0xF9A8, 0x883F, 0xF9A9, 0x8B9E, 0xF9AA, 0x8C9C, 0xF9AB, 0x8EA9, + 0xF9AC, 0x8EC9, 0xF9AD, 0x974B, 0xF9AE, 0x9873, 0xF9AF, 0x9874, + 0xF9B0, 0x98CC, 0xF9B1, 0x9961, 0xF9B2, 0x99AB, 0xF9B3, 0x9A64, + 0xF9B4, 0x9A66, 0xF9B5, 0x9A67, 0xF9B6, 0x9B24, 0xF9B7, 0x9E15, + 0xF9B8, 0x9E17, 0xF9B9, 0x9F48, 0xF9BA, 0x6207, 0xF9BB, 0x6B1E, + 0xF9BC, 0x7227, 0xF9BD, 0x864C, 0xF9BE, 0x8EA8, 0xF9BF, 0x9482, + 0xF9C0, 0x9480, 0xF9C1, 0x9481, 0xF9C2, 0x9A69, 0xF9C3, 0x9A68, + 0xF9C4, 0x9B2E, 0xF9C5, 0x9E19, 0xF9C6, 0x7229, 0xF9C7, 0x864B, + 0xF9C8, 0x8B9F, 0xF9C9, 0x9483, 0xF9CA, 0x9C79, 0xF9CB, 0x9EB7, + 0xF9CC, 0x7675, 0xF9CD, 0x9A6B, 0xF9CE, 0x9C7A, 0xF9CF, 0x9E1D, + 0xF9D0, 0x7069, 0xF9D1, 0x706A, 0xF9D2, 0x9EA4, 0xF9D3, 0x9F7E, + 0xF9D4, 0x9F49, 0xF9D5, 0x9F98, 0xF9D6, 0x7881, 0xF9D7, 0x92B9, + 0xF9D8, 0x88CF, 0xF9D9, 0x58BB, 0xF9DA, 0x6052, 0xF9DB, 0x7CA7, + 0xF9DC, 0x5AFA, 0xF9DD, 0x2554, 0xF9DE, 0x2566, 0xF9DF, 0x2557, + 0xF9E0, 0x2560, 0xF9E1, 0x256C, 0xF9E2, 0x2563, 0xF9E3, 0x255A, + 0xF9E4, 0x2569, 0xF9E5, 0x255D, 0xF9E6, 0x2552, 0xF9E7, 0x2564, + 0xF9E8, 0x2555, 0xF9E9, 0x255E, 0xF9EA, 0x256A, 0xF9EB, 0x2561, + 0xF9EC, 0x2558, 0xF9ED, 0x2567, 0xF9EE, 0x255B, 0xF9EF, 0x2553, + 0xF9F0, 0x2565, 0xF9F1, 0x2556, 0xF9F2, 0x255F, 0xF9F3, 0x256B, + 0xF9F4, 0x2562, 0xF9F5, 0x2559, 0xF9F6, 0x2568, 0xF9F7, 0x255C, + 0xF9F8, 0x2551, 0xF9F9, 0x2550, 0xF9FA, 0x256D, 0xF9FB, 0x256E, + 0xF9FC, 0x2570, 0xF9FD, 0x256F, 0xF9FE, 0x2593, 0, 0 +}; + + + +WCHAR ff_convert ( /* Converted code, 0 means conversion error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +) +{ + const WCHAR *p; + WCHAR c; + int i, n, li, hi; + + + if (chr < 0x80) { /* ASCII */ + c = chr; + } else { + if (dir) { /* OEM code to unicode */ + p = oem2uni; + hi = sizeof oem2uni / 4 - 1; + } else { /* Unicode to OEM code */ + p = uni2oem; + hi = sizeof uni2oem / 4 - 1; + } + li = 0; + for (n = 16; n; n--) { + i = li + (hi - li) / 2; + if (chr == p[i * 2]) break; + if (chr > p[i * 2]) + li = i; + else + hi = i; + } + c = n ? p[i * 2 + 1] : 0; + } + + return c; +} + + + + +WCHAR ff_wtoupper ( + WCHAR chr /* Unicode character to be upper converted */ +) +{ + static const WCHAR lower[] = { /* Lower case characters to be converted */ + /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, + /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E, + /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217, + /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB, + /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9, + /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586, + /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9, + /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A + }; + static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D, + 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216, + 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8, + 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556, + 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A + }; + UINT i, n, hi, li; + + + if (chr < 0x80) { /* ASCII characters (acceleration) */ + if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20; + + } else { /* Extended characters */ + n = 12; li = 0; hi = sizeof lower / sizeof lower[0]; + do { + i = li + (hi - li) / 2; + if (chr == lower[i]) break; + if (chr > lower[i]) li = i; else hi = i; + } while (--n); + if (n) chr = upper[i]; + } + + return chr; +} + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c new file mode 100644 index 0000000..f0c479c --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c @@ -0,0 +1,348 @@ +/*------------------------------------------------------------------------*/ +/* Unicode - Local code bidirectional converter (C)ChaN, 2015 */ +/* (SBCS code pages) */ +/*------------------------------------------------------------------------*/ +/* 437 U.S. +/ 720 Arabic +/ 737 Greek +/ 771 KBL +/ 775 Baltic +/ 850 Latin 1 +/ 852 Latin 2 +/ 855 Cyrillic +/ 857 Turkish +/ 860 Portuguese +/ 861 Icelandic +/ 862 Hebrew +/ 863 Canadian French +/ 864 Arabic +/ 865 Nordic +/ 866 Russian +/ 869 Greek 2 +*/ + +#include "ff.h" + + +#if _CODE_PAGE == 437 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 720 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */ + 0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9, 0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, + 0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0x0650, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 737 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, + 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, + 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD, 0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E, + 0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 771 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP771(0x80-0xFF) to Unicode conversion table */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x0104, 0x0105, 0x010C, 0x010D, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0118, 0x0119, 0x0116, 0x0117, 0x012E, 0x012F, 0x0160, 0x0161, 0x0172, 0x0173, 0x016A, 0x016B, 0x017D, 0x017E, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 775 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */ + 0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107, 0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4, + 0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6, 0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118, 0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D, + 0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B, 0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144, 0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019, + 0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E, 0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 850 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 852 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7, 0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106, + 0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A, 0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E, 0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A, 0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE, 0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, 0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4, + 0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 855 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + 0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C, 0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A, + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, 0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E, 0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580, + 0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116, + 0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D, 0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 857 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4, + 0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580, + 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000, 0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4, + 0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 860 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP860(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E3, 0x00E0, 0x00C1, 0x00E7, 0x00EA, 0x00CA, 0x00E8, 0x00CD, 0x00D4, 0x00EC, 0x00C3, 0x00C2, + 0x00C9, 0x00C0, 0x00C8, 0x00F4, 0x00F5, 0x00F2, 0x00DA, 0x00F9, 0x00CC, 0x00D5, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x20A7, 0x00D3, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00D2, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 861 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP861(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00D0, 0x00F0, 0x00DE, 0x00C4, 0x00C5, + 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00FE, 0x00FB, 0x00DD, 0x00FD, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00C1, 0x00CD, 0x00D3, 0x00DA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 862 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */ + 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, + 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 863 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP863(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00C2, 0x00E0, 0x00B6, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x2017, 0x00C0, + 0x00C9, 0x00C8, 0x00CA, 0x00F4, 0x00CB, 0x00CF, 0x00FB, 0x00F9, 0x00A4, 0x00D4, 0x00DC, 0x00A2, 0x00A3, 0x00D9, 0x00DB, 0x0192, + 0x00A6, 0x00B4, 0x00F3, 0x00FA, 0x00A8, 0x00BB, 0x00B3, 0x00AF, 0x00CE, 0x3210, 0x00AC, 0x00BD, 0x00BC, 0x00BE, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2219, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 864 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP864(0x80-0xFF) to Unicode conversion table */ + 0x00B0, 0x00B7, 0x2219, 0x221A, 0x2592, 0x2500, 0x2502, 0x253C, 0x2524, 0x252C, 0x251C, 0x2534, 0x2510, 0x250C, 0x2514, 0x2518, + 0x03B2, 0x221E, 0x03C6, 0x00B1, 0x00BD, 0x00BC, 0x2248, 0x00AB, 0x00BB, 0xFEF7, 0xFEF8, 0x0000, 0x0000, 0xFEFB, 0xFEFC, 0x0000, + 0x00A0, 0x00AD, 0xFE82, 0x00A3, 0x00A4, 0xFE84, 0x0000, 0x20AC, 0xFE8E, 0xFE8F, 0xFE95, 0xFE99, 0x060C, 0xFE9D, 0xFEA1, 0xFEA5, + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, 0x0668, 0x0669, 0xFED1, 0x061B, 0xFEB1, 0xFEB5, 0xFEB9, 0x061F, + 0x00A2, 0xFE80, 0xFE81, 0xFE83, 0xFE85, 0xFECA, 0xFE8B, 0xFE8D, 0xFE91, 0xFE93, 0xFE97, 0xFE9B, 0xFE9F, 0xFEA3, 0xFEA7, 0xFEA9, + 0xFEAB, 0xFEAD, 0xFEAF, 0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, 0xFEC1, 0xFEC5, 0xFECB, 0xFECF, 0x00A6, 0x00AC, 0x00F7, 0x00D7, 0xFEC9, + 0x0640, 0xFED3, 0xFED7, 0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, 0xFEEB, 0xFEED, 0xFEEF, 0xFEF3, 0xFEBD, 0xFECC, 0xFECE, 0xFECD, 0xFEE1, + 0xFE7D, 0x0651, 0xFEE5, 0xFEE9, 0xFEEC, 0xFEF0, 0xFEF2, 0xFED0, 0xFED5, 0xFEF5, 0xFEF6, 0xFEDD, 0xFED9, 0xFEF1, 0x25A0, 0x0000 +}; + +#elif _CODE_PAGE == 865 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP865(0x80-0xFF) to Unicode conversion table */ + 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5, + 0x00C5, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x20A7, 0x0192, + 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00A4, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x2558, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4, 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229, + 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 866 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E, 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0 +}; + +#elif _CODE_PAGE == 869 +#define _TBLDEF 1 +static +const WCHAR Tbl[] = { /* CP869(0x80-0xFF) to Unicode conversion table */ + 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x00B7, 0x0386, 0x00B7, 0x00B7, 0x00AC, 0x00A6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, + 0x038A, 0x03AA, 0x038C, 0x00B7, 0x00B7, 0x038E, 0x03AB, 0x00A9, 0x038F, 0x00B2, 0x00B3, 0x03AC, 0x00A3, 0x03AD, 0x03AE, 0x03AF, + 0x03CA, 0x0390, 0x03CC, 0x03CD, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x00BD, 0x0398, 0x0399, 0x00AB, 0x00BB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039A, 0x039B, 0x039C, 0x039D, 0x2563, 0x2551, 0x2557, 0x255D, 0x039E, 0x039F, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0A30, 0x03A1, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x03A3, + 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x2518, 0x250C, 0x2588, 0x2584, 0x03B4, 0x03B5, 0x2580, + 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x0384, + 0x00AD, 0x00B1, 0x03C5, 0x03C6, 0x03C7, 0x00A7, 0x03C8, 0x0385, 0x00B0, 0x00A8, 0x03C9, 0x03CB, 0x03B0, 0x03CE, 0x25A0, 0x00A0 +}; + +#endif + + +#if !_TBLDEF || !_USE_LFN +#error This file is not needed at current configuration. Remove from the project. +#endif + + + + +WCHAR ff_convert ( /* Converted character, Returns zero on error */ + WCHAR chr, /* Character code to be converted */ + UINT dir /* 0: Unicode to OEM code, 1: OEM code to Unicode */ +) +{ + WCHAR c; + + + if (chr < 0x80) { /* ASCII */ + c = chr; + + } else { + if (dir) { /* OEM code to Unicode */ + c = (chr >= 0x100) ? 0 : Tbl[chr - 0x80]; + + } else { /* Unicode to OEM code */ + for (c = 0; c < 0x80; c++) { + if (chr == Tbl[c]) break; + } + c = (c + 0x80) & 0xFF; + } + } + + return c; +} + + + + +WCHAR ff_wtoupper ( /* Returns upper converted character */ + WCHAR chr /* Unicode character to be upper converted */ +) +{ + static const WCHAR lower[] = { /* Lower case characters to be converted */ + /* Latin Supplement */ 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, + /* Latin Extended-A */ 0x101,0x103,0x105,0x107,0x109,0x10B,0x10D,0x10F,0x111,0x113,0x115,0x117,0x119,0x11B,0x11D,0x11F,0x121,0x123,0x125,0x127,0x129,0x12B,0x12D,0x12F,0x131,0x133,0x135,0x137,0x13A,0x13C,0x13E,0x140,0x142,0x144,0x146,0x148,0x14B,0x14D,0x14F,0x151,0x153,0x155,0x157,0x159,0x15B,0x15D,0x15F,0x161,0x163,0x165,0x167,0x169,0x16B,0x16D,0x16F,0x171,0x173,0x175,0x177,0x17A,0x17C,0x17E, + /* Latin Extended-B */ 0x183,0x185,0x188,0x18C,0x192,0x199,0x1A1,0x1A3,0x1A8,0x1AD,0x1B0,0x1B4,0x1B6,0x1B9,0x1BD,0x1C6,0x1C9,0x1CC,0x1CE,0x1D0,0x1D2,0x1D4,0x1D6,0x1D8,0x1DA,0x1DC,0x1DD,0x1DF,0x1E1,0x1E3,0x1E5,0x1E7,0x1E9,0x1EB,0x1ED,0x1EF,0x1F3,0x1F5,0x1FB,0x1FD,0x1FF,0x201,0x203,0x205,0x207,0x209,0x20B,0x20D,0x20F,0x211,0x213,0x215,0x217, + /* Greek, Coptic */ 0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF,0x3C0,0x3C1,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0x3CC,0x3CD,0x3CE,0x3E3,0x3E5,0x3E7,0x3E9,0x3EB, + /* Cyrillic */ 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F,0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45E,0x45F,0x461,0x463,0x465,0x467,0x469,0x46B,0x46D,0x46F,0x471,0x473,0x475,0x477,0x479,0x47B,0x47D,0x47F,0x481,0x491,0x493,0x495,0x497,0x499,0x49B,0x49D,0x49F,0x4A1,0x4A3,0x4A5,0x4A7,0x4A9,0x4AB,0x4AD,0x4AF,0x4B1,0x4B3,0x4B5,0x4B7,0x4B9,0x4BB,0x4BD,0x4BF,0x4C2,0x4C4,0x4C8,0x4D1,0x4D3,0x4D5,0x4D7,0x4D9,0x4DB,0x4DD,0x4DF,0x4E1,0x4E3,0x4E5,0x4E7,0x4E9,0x4EB,0x4ED,0x4EF,0x4F1,0x4F3,0x4F5,0x4F9, + /* Armenian */ 0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F,0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F,0x580,0x581,0x582,0x583,0x584,0x585,0x586, + /* Latin Extended Additional */ 0x1E01,0x1E03,0x1E05,0x1E07,0x1E09,0x1E0B,0x1E0D,0x1E0F,0x1E11,0x1E13,0x1E15,0x1E17,0x1E19,0x1E1B,0x1E1D,0x1E1F,0x1E21,0x1E23,0x1E25,0x1E27,0x1E29,0x1E2B,0x1E2D,0x1E2F,0x1E31,0x1E33,0x1E35,0x1E37,0x1E39,0x1E3B,0x1E3D,0x1E3F,0x1E41,0x1E43,0x1E45,0x1E47,0x1E49,0x1E4B,0x1E4D,0x1E4F,0x1E51,0x1E53,0x1E55,0x1E57,0x1E59,0x1E5B,0x1E5D,0x1E5F,0x1E61,0x1E63,0x1E65,0x1E67,0x1E69,0x1E6B,0x1E6D,0x1E6F,0x1E71,0x1E73,0x1E75,0x1E77,0x1E79,0x1E7B,0x1E7D,0x1E7F,0x1E81,0x1E83,0x1E85,0x1E87,0x1E89,0x1E8B,0x1E8D,0x1E8F,0x1E91,0x1E93,0x1E95,0x1E97,0x1E99,0x1E9B,0x1E9D,0x1E9F,0x1EA1,0x1EA3,0x1EA5,0x1EA7,0x1EA9,0x1EAB,0x1EAD,0x1EAF,0x1EB1,0x1EB3,0x1EB5,0x1EB7,0x1EB9,0x1EBB,0x1EBD,0x1EBF,0x1EC1,0x1EC3,0x1EC5,0x1EC7,0x1EC9,0x1ECB,0x1ECD,0x1ECF,0x1ED1,0x1ED3,0x1ED5,0x1ED7,0x1ED9,0x1EDB,0x1EDD,0x1EDF,0x1EE1,0x1EE3,0x1EE5,0x1EE7,0x1EE9,0x1EEB,0x1EED,0x1EEF,0x1EF1,0x1EF3,0x1EF5,0x1EF7,0x1EF9, + /* Number forms */ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + /* Full-width */ 0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F,0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A + }; + static const WCHAR upper[] = { /* Upper case characters correspond to lower[] */ + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0x100,0x102,0x104,0x106,0x108,0x10A,0x10C,0x10E,0x110,0x112,0x114,0x116,0x118,0x11A,0x11C,0x11E,0x120,0x122,0x124,0x126,0x128,0x12A,0x12C,0x12E,0x130,0x132,0x134,0x136,0x139,0x13B,0x13D,0x13F,0x141,0x143,0x145,0x147,0x14A,0x14C,0x14E,0x150,0x152,0x154,0x156,0x158,0x15A,0x15C,0x15E,0x160,0x162,0x164,0x166,0x168,0x16A,0x16C,0x16E,0x170,0x172,0x174,0x176,0x179,0x17B,0x17D, + 0x182,0x184,0x187,0x18B,0x191,0x198,0x1A0,0x1A2,0x1A7,0x1AC,0x1AF,0x1B3,0x1B5,0x1B8,0x1BC,0x1C4,0x1C7,0x1CA,0x1CD,0x1CF,0x1D1,0x1D3,0x1D5,0x1D7,0x1D9,0x1DB,0x18E,0x1DE,0x1E0,0x1E2,0x1E4,0x1E6,0x1E8,0x1EA,0x1EC,0x1EE,0x1F1,0x1F4,0x1FA,0x1FC,0x1FE,0x200,0x202,0x204,0x206,0x208,0x20A,0x20C,0x20E,0x210,0x212,0x214,0x216, + 0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F,0x3A0,0x3A1,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0x3E2,0x3E4,0x3E6,0x3E8,0x3EA, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F,0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40E,0x40F,0x460,0x462,0x464,0x466,0x468,0x46A,0x46C,0x46E,0x470,0x472,0x474,0x476,0x478,0x47A,0x47C,0x47E,0x480,0x490,0x492,0x494,0x496,0x498,0x49A,0x49C,0x49E,0x4A0,0x4A2,0x4A4,0x4A6,0x4A8,0x4AA,0x4AC,0x4AE,0x4B0,0x4B2,0x4B4,0x4B6,0x4B8,0x4BA,0x4BC,0x4BE,0x4C1,0x4C3,0x5C7,0x4D0,0x4D2,0x4D4,0x4D6,0x4D8,0x4DA,0x4DC,0x4DE,0x4E0,0x4E2,0x4E4,0x4E6,0x4E8,0x4EA,0x4EC,0x4EE,0x4F0,0x4F2,0x4F4,0x4F8, + 0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F,0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F,0x550,0x551,0x552,0x553,0x554,0x555,0x556, + 0x1E00,0x1E02,0x1E04,0x1E06,0x1E08,0x1E0A,0x1E0C,0x1E0E,0x1E10,0x1E12,0x1E14,0x1E16,0x1E18,0x1E1A,0x1E1C,0x1E1E,0x1E20,0x1E22,0x1E24,0x1E26,0x1E28,0x1E2A,0x1E2C,0x1E2E,0x1E30,0x1E32,0x1E34,0x1E36,0x1E38,0x1E3A,0x1E3C,0x1E3E,0x1E40,0x1E42,0x1E44,0x1E46,0x1E48,0x1E4A,0x1E4C,0x1E4E,0x1E50,0x1E52,0x1E54,0x1E56,0x1E58,0x1E5A,0x1E5C,0x1E5E,0x1E60,0x1E62,0x1E64,0x1E66,0x1E68,0x1E6A,0x1E6C,0x1E6E,0x1E70,0x1E72,0x1E74,0x1E76,0x1E78,0x1E7A,0x1E7C,0x1E7E,0x1E80,0x1E82,0x1E84,0x1E86,0x1E88,0x1E8A,0x1E8C,0x1E8E,0x1E90,0x1E92,0x1E94,0x1E96,0x1E98,0x1E9A,0x1E9C,0x1E9E,0x1EA0,0x1EA2,0x1EA4,0x1EA6,0x1EA8,0x1EAA,0x1EAC,0x1EAE,0x1EB0,0x1EB2,0x1EB4,0x1EB6,0x1EB8,0x1EBA,0x1EBC,0x1EBE,0x1EC0,0x1EC2,0x1EC4,0x1EC6,0x1EC8,0x1ECA,0x1ECC,0x1ECE,0x1ED0,0x1ED2,0x1ED4,0x1ED6,0x1ED8,0x1EDA,0x1EDC,0x1EDE,0x1EE0,0x1EE2,0x1EE4,0x1EE6,0x1EE8,0x1EEA,0x1EEC,0x1EEE,0x1EF0,0x1EF2,0x1EF4,0x1EF6,0x1EF8, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F,0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A + }; + UINT i, n, hi, li; + + + if (chr < 0x80) { /* ASCII characters (acceleration) */ + if (chr >= 0x61 && chr <= 0x7A) chr -= 0x20; + + } else { /* Non ASCII characters (table search) */ + n = 12; li = 0; hi = sizeof lower / sizeof lower[0]; + do { + i = li + (hi - li) / 2; + if (chr == lower[i]) break; + if (chr > lower[i]) li = i; else hi = i; + } while (--n); + if (n) chr = upper[i]; + } + + return chr; +} + diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/syncobj.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/syncobj.c new file mode 100644 index 0000000..cb4d0a5 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/syncobj.c @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------*/ +/* Sample code of OS dependent synchronization object controls */ +/* for FatFs R0.07a (C)ChaN, 2009 */ +/*------------------------------------------------------------------------*/ + +#include // Win32 +//#include // uC/OS-II + +#include "ff.h" + +#if _FS_REENTRANT + +/*------------------------------------------------------------------------*/ +/* Create a Synchronization Object for a Volume +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount function to create a new +/ synchronization object, such as semaphore and mutex. When a FALSE is +/ returned, the f_mount function fails with FR_INT_ERR. +*/ + +BOOL ff_cre_syncobj ( /* TRUE:Function succeeded, FALSE:Could not create due to any error */ + BYTE vol, /* Corresponding logical drive being processed */ + _SYNC_t *sobj /* Pointer to return the created sync object */ +) +{ + BOOL ret; + + *sobj = CreateMutex(NULL, FALSE, NULL); // Win32 + ret = (*sobj != INVALID_HANDLE_VALUE) ? TRUE : FALSE; // + +// *sobj = VolumeSemId[vol]; // uITRON (give a static created sync object) +// ret = TRUE; // The initial value of the semaphore must be 1. + +// *sobj = OSMutexCreate(0, &err); // uC/OS-II +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; // + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Delete a Synchronization Object */ +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount function to delete a synchronization +/ object that created with ff_cre_syncobj function. When a FALSE is +/ returned, the f_mount function fails with FR_INT_ERR. +*/ + +BOOL ff_del_syncobj ( /* TRUE:Function succeeded, FALSE:Could not delete due to any error */ + _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ +) +{ + BOOL ret; + + ret = CloseHandle(sobj); // Win32 + +// ret = TRUE; // uITRON (nothing to do) + +// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); // uC/OS-II +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; // + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Request Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on entering file functions to lock the volume. +/ When a FALSE is returned, the file function fails with FR_TIMEOUT. +*/ + +BOOL ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */ + _SYNC_t sobj /* Sync object to wait */ +) +{ + BOOL ret; + + ret = (WaitForSingleObject(sobj, _TIMEOUT) == WAIT_OBJECT_0) ? TRUE : FALSE; // Win32 + +// ret = (wai_sem(sobj) == E_OK) ? TRUE : FALSE; // uITRON + +// OSMutexPend(sobj, _TIMEOUT, &err)); // uC/OS-II +// ret = (err == OS_NO_ERR) ? TRUE : FALSE; // + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Release Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on leaving file functions to unlock the volume. +*/ + +void ff_rel_grant ( + _SYNC_t sobj /* Sync object to be signaled */ +) +{ + ReleaseMutex(sobj); // Win32 + +// sig_sem(sobj); // uITRON + +// OSMutexPost(sobj); // uC/OS-II +} + + +#else + +#error This file is not needed in this configuration. + +#endif diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/syscall.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/syscall.c new file mode 100644 index 0000000..2de4175 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/syscall.c @@ -0,0 +1,151 @@ +/*------------------------------------------------------------------------*/ +/* Sample code of OS dependent controls for FatFs */ +/* (C)ChaN, 2014 */ +/*------------------------------------------------------------------------*/ + + +#include "ff.h" + + +#if _FS_REENTRANT +/*------------------------------------------------------------------------*/ +/* Create a Synchronization Object +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount() function to create a new +/ synchronization object, such as semaphore and mutex. When a 0 is returned, +/ the f_mount() function fails with FR_INT_ERR. +*/ + +int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */ + BYTE vol, /* Corresponding logical drive being processed */ + _SYNC_t *sobj /* Pointer to return the created sync object */ +) +{ + int ret; + + + *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */ + ret = (int)(*sobj != INVALID_HANDLE_VALUE); + +// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */ +// ret = 1; /* The initial value of the semaphore must be 1. */ + +// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */ +// ret = (int)(err == OS_NO_ERR); + +// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */ +// ret = (int)(*sobj != NULL); + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Delete a Synchronization Object */ +/*------------------------------------------------------------------------*/ +/* This function is called in f_mount() function to delete a synchronization +/ object that created with ff_cre_syncobj function. When a 0 is returned, +/ the f_mount() function fails with FR_INT_ERR. +*/ + +int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */ + _SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ +) +{ + int ret; + + + ret = CloseHandle(sobj); /* Win32 */ + +// ret = 1; /* uITRON (nothing to do) */ + +// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */ +// ret = (int)(err == OS_NO_ERR); + +// vSemaphoreDelete(sobj); /* FreeRTOS */ +// ret = 1; + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Request Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on entering file functions to lock the volume. +/ When a 0 is returned, the file function fails with FR_TIMEOUT. +*/ + +int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */ + _SYNC_t sobj /* Sync object to wait */ +) +{ + int ret; + + ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */ + +// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */ + +// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */ +// ret = (int)(err == OS_NO_ERR); + +// ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */ + + return ret; +} + + + +/*------------------------------------------------------------------------*/ +/* Release Grant to Access the Volume */ +/*------------------------------------------------------------------------*/ +/* This function is called on leaving file functions to unlock the volume. +*/ + +void ff_rel_grant ( + _SYNC_t sobj /* Sync object to be signaled */ +) +{ + ReleaseMutex(sobj); /* Win32 */ + +// sig_sem(sobj); /* uITRON */ + +// OSMutexPost(sobj); /* uC/OS-II */ + +// xSemaphoreGive(sobj); /* FreeRTOS */ +} + +#endif + + + + +#if _USE_LFN == 3 /* LFN with a working buffer on the heap */ +/*------------------------------------------------------------------------*/ +/* Allocate a memory block */ +/*------------------------------------------------------------------------*/ +/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE. +*/ + +void* ff_memalloc ( /* Returns pointer to the allocated memory block */ + UINT msize /* Number of bytes to allocate */ +) +{ + return malloc(msize); /* Allocate a new memory block with POSIX API */ +} + + +/*------------------------------------------------------------------------*/ +/* Free a memory block */ +/*------------------------------------------------------------------------*/ + +void ff_memfree ( + void* mblock /* Pointer to the memory block to free */ +) +{ + free(mblock); /* Discard the memory block with POSIX API */ +} + +#endif diff --git a/USDK/component/common/file_system/fatfs/r0.10c/src/option/unicode.c b/USDK/component/common/file_system/fatfs/r0.10c/src/option/unicode.c new file mode 100644 index 0000000..a306600 --- /dev/null +++ b/USDK/component/common/file_system/fatfs/r0.10c/src/option/unicode.c @@ -0,0 +1,17 @@ +#include "ff.h" + +#if _USE_LFN != 0 + +#if _CODE_PAGE == 932 /* Japanese Shift_JIS */ +#include "cc932.c" +#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */ +#include "cc936.c" +#elif _CODE_PAGE == 949 /* Korean */ +#include "cc949.c" +#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */ +#include "cc950.c" +#else /* Single Byte Character-Set */ +#include "ccsbcs.c" +#endif + +#endif diff --git a/USDK/component/common/mbed/api/error.h b/USDK/component/common/mbed/api/error.h new file mode 100644 index 0000000..3a40358 --- /dev/null +++ b/USDK/component/common/mbed/api/error.h @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ERROR_H +#define MBED_ERROR_H + +/** To generate a fatal compile-time error, you can use the pre-processor #error directive. + * + * @code + * #error "That shouldn't have happened!" + * @endcode + * + * If the compiler evaluates this line, it will report the error and stop the compile. + * + * For example, you could use this to check some user-defined compile-time variables: + * + * @code + * #define NUM_PORTS 7 + * #if (NUM_PORTS > 4) + * #error "NUM_PORTS must be less than 4" + * #endif + * @endcode + * + * Reporting Run-Time Errors: + * To generate a fatal run-time error, you can use the mbed error() function. + * + * @code + * error("That shouldn't have happened!"); + * @endcode + * + * If the mbed running the program executes this function, it will print the + * message via the USB serial port, and then die with the blue lights of death! + * + * The message can use printf-style formatting, so you can report variables in the + * message too. For example, you could use this to check a run-time condition: + * + * @code + * if(x >= 5) { + * error("expected x to be less than 5, but got %d", x); + * } + * #endcode + */ + +#ifdef __cplusplus +extern "C" { +#endif + +void error(const char* format, ...); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/api/mbed_assert.h b/USDK/component/common/mbed/api/mbed_assert.h new file mode 100644 index 0000000..1bcfb09 --- /dev/null +++ b/USDK/component/common/mbed/api/mbed_assert.h @@ -0,0 +1,50 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ASSERT_H +#define MBED_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Internal mbed assert function which is invoked when MBED_ASSERT macro failes. + * This function is active only if NDEBUG is not defined prior to including this + * assert header file. + * In case of MBED_ASSERT failing condition, the assertation message is printed + * to stderr and mbed_die() is called. + * @param expr Expresion to be checked. + * @param file File where assertation failed. + * @param line Failing assertation line number. + */ +void mbed_assert_internal(const char *expr, const char *file, int line); + +#ifdef __cplusplus +} +#endif + +#ifdef NDEBUG +#define MBED_ASSERT(expr) ((void)0) + +#else +#define MBED_ASSERT(expr) \ +do { \ + if (!(expr)) { \ + mbed_assert_internal(#expr, __FILE__, __LINE__); \ + } \ +} while (0) +#endif + +#endif diff --git a/USDK/component/common/mbed/api/rtc_time.h b/USDK/component/common/mbed/api/rtc_time.h new file mode 100644 index 0000000..59ab8fd --- /dev/null +++ b/USDK/component/common/mbed/api/rtc_time.h @@ -0,0 +1,74 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Implementation of the C time.h functions + * + * Provides mechanisms to set and read the current time, based + * on the microcontroller Real-Time Clock (RTC), plus some + * standard C manipulation and formating functions. + * + * Example: + * @code + * #include "mbed.h" + * + * int main() { + * set_time(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 + * + * while(1) { + * time_t seconds = time(NULL); + * + * printf("Time as seconds since January 1, 1970 = %d\n", seconds); + * + * printf("Time as a basic string = %s", ctime(&seconds)); + * + * char buffer[32]; + * strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds)); + * printf("Time as a custom formatted string = %s", buffer); + * + * wait(1); + * } + * } + * @endcode + */ + +/** Set the current time + * + * Initialises and sets the time of the microcontroller Real-Time Clock (RTC) + * to the time represented by the number of seconds since January 1, 1970 + * (the UNIX timestamp). + * + * @param t Number of seconds since January 1, 1970 (the UNIX timestamp) + * + * Example: + * @code + * #include "mbed.h" + * + * int main() { + * set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37 + * } + * @endcode + */ +void set_time(time_t t); + +#ifdef __cplusplus +} +#endif diff --git a/USDK/component/common/mbed/api/wait_api.h b/USDK/component/common/mbed/api/wait_api.h new file mode 100644 index 0000000..03c2714 --- /dev/null +++ b/USDK/component/common/mbed/api/wait_api.h @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_WAIT_API_H +#define MBED_WAIT_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic wait functions. + * + * These provide simple NOP type wait capabilities. + * + * Example: + * @code + * #include "mbed.h" + * + * DigitalOut heartbeat(LED1); + * + * int main() { + * while (1) { + * heartbeat = 1; + * wait(0.5); + * heartbeat = 0; + * wait(0.5); + * } + * } + */ + +/** Waits for a number of seconds, with microsecond resolution (within + * the accuracy of single precision floating point). + * + * @param s number of seconds to wait + */ +void wait(float s); + +/** Waits a number of milliseconds. + * + * @param ms the whole number of milliseconds to wait + */ +void wait_ms(int ms); + +/** Waits a number of microseconds. + * + * @param us the whole number of microseconds to wait + */ +void wait_us(int us); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/common/us_ticker_api.c b/USDK/component/common/mbed/common/us_ticker_api.c new file mode 100644 index 0000000..8218b9c --- /dev/null +++ b/USDK/component/common/mbed/common/us_ticker_api.c @@ -0,0 +1,118 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include "us_ticker_api.h" +#include "cmsis.h" + +static ticker_event_handler event_handler; +static ticker_event_t *head = NULL; + +void us_ticker_set_handler(ticker_event_handler handler) { + us_ticker_init(); + + event_handler = handler; +} + +void us_ticker_irq_handler(void) { + us_ticker_clear_interrupt(); + + /* Go through all the pending TimerEvents */ + while (1) { + if (head == NULL) { + // There are no more TimerEvents left, so disable matches. + us_ticker_disable_interrupt(); + return; + } + + if ((int)(head->timestamp - us_ticker_read()) <= 0) { + // This event was in the past: + // point to the following one and execute its handler + ticker_event_t *p = head; + head = head->next; + if (event_handler != NULL) { + event_handler(p->id); // NOTE: the handler can set new events + } + /* Note: We continue back to examining the head because calling the + * event handler may have altered the chain of pending events. */ + } else { + // This event and the following ones in the list are in the future: + // set it as next interrupt and return + us_ticker_set_interrupt(head->timestamp); + return; + } + } +} + +void us_ticker_insert_event(ticker_event_t *obj, timestamp_t timestamp, uint32_t id) { + /* disable interrupts for the duration of the function */ + __disable_irq(); + + // initialise our data + obj->timestamp = timestamp; + obj->id = id; + + /* Go through the list until we either reach the end, or find + an element this should come before (which is possibly the + head). */ + ticker_event_t *prev = NULL, *p = head; + while (p != NULL) { + /* check if we come before p */ + if ((int)(timestamp - p->timestamp) <= 0) { + break; + } + /* go to the next element */ + prev = p; + p = p->next; + } + /* if prev is NULL we're at the head */ + if (prev == NULL) { + head = obj; + us_ticker_set_interrupt(timestamp); + } else { + prev->next = obj; + } + /* if we're at the end p will be NULL, which is correct */ + obj->next = p; + + __enable_irq(); +} + +void us_ticker_remove_event(ticker_event_t *obj) { + __disable_irq(); + + // remove this object from the list + if (head == obj) { + // first in the list, so just drop me + head = obj->next; + if (head == NULL) { + us_ticker_disable_interrupt(); + } else { + us_ticker_set_interrupt(head->timestamp); + } + } else { + // find the object before me, then drop me + ticker_event_t* p = head; + while (p != NULL) { + if (p->next == obj) { + p->next = obj->next; + break; + } + p = p->next; + } + } + + __enable_irq(); +} diff --git a/USDK/component/common/mbed/common/wait_api.c b/USDK/component/common/mbed/common/wait_api.c new file mode 100644 index 0000000..b89e548 --- /dev/null +++ b/USDK/component/common/mbed/common/wait_api.c @@ -0,0 +1,112 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "wait_api.h" +#include "us_ticker_api.h" + +#include "platform_autoconf.h" + +#define WAIT_US_USE_CYCCNT + +#ifdef WAIT_US_USE_CYCCNT +//#include "core_cm3.h" +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ +#endif + +void wait(float s) { // До 1073741 секунд? 298 часов +// wait_us((int)(s * 1000000.0f)); + vTaskDelay((int)(s * 1000.0f)); +} + +void wait_ms(int ms) { // До 1073741 секунд? 298 часов + if(ms > 0) vTaskDelay(ms); +// wait_us(ms * 1000); +} + + +void wait_us(int us) { // До 2.147483648 секунды! + uint32_t start; +#ifdef WAIT_US_USE_CYCCNT + if(us < 1) return; + if (us < 327) { // G-timer resolution is ~31 us (1/32K), use DWT->CYCCNT... + if(!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) { // уже включен? + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // открыть доступ + DWT->CYCCNT = 0; // обнулить и запустить + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // запустить счет + } + start = DWT->CYCCNT + us * (PLATFORM_CLOCK / 1000000ul); + while ((int32_t)(start - DWT->CYCCNT) > 0); + } + else +#endif + { + start = us_ticker_read(); // G-timer resolution is ~31 us (1/32K), and is a countdown timer + while ((us_ticker_read() - start) < (uint32_t)us); + } +} diff --git a/USDK/component/common/mbed/hal/analogin_api.h b/USDK/component/common/mbed/hal/analogin_api.h new file mode 100644 index 0000000..57d25eb --- /dev/null +++ b/USDK/component/common/mbed/hal/analogin_api.h @@ -0,0 +1,39 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ANALOGIN_API_H +#define MBED_ANALOGIN_API_H + +#include "device.h" + +#if DEVICE_ANALOGIN + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct analogin_s analogin_t; // 444 bytes! + +void analogin_init (analogin_t *obj, PinName pin); +float analogin_read (analogin_t *obj); +uint16_t analogin_read_u16(analogin_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/analogout_api.h b/USDK/component/common/mbed/hal/analogout_api.h new file mode 100644 index 0000000..97a2013 --- /dev/null +++ b/USDK/component/common/mbed/hal/analogout_api.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ANALOGOUT_API_H +#define MBED_ANALOGOUT_API_H + +#include "device.h" + +#if DEVICE_ANALOGOUT + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct dac_s dac_t; + +void analogout_init (dac_t *obj, PinName pin); +void analogout_free (dac_t *obj); +void analogout_write (dac_t *obj, float value); +void analogout_write_u16(dac_t *obj, uint16_t value); +float analogout_read (dac_t *obj); +uint16_t analogout_read_u16 (dac_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/can_api.h b/USDK/component/common/mbed/hal/can_api.h new file mode 100644 index 0000000..48bc104 --- /dev/null +++ b/USDK/component/common/mbed/hal/can_api.h @@ -0,0 +1,80 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_CAN_API_H +#define MBED_CAN_API_H + +#include "device.h" + +#if DEVICE_CAN + +#include "PinNames.h" +#include "PeripheralNames.h" +#include "can_helper.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IRQ_RX, + IRQ_TX, + IRQ_ERROR, + IRQ_OVERRUN, + IRQ_WAKEUP, + IRQ_PASSIVE, + IRQ_ARB, + IRQ_BUS, + IRQ_READY +} CanIrqType; + + +typedef enum { + MODE_RESET, + MODE_NORMAL, + MODE_SILENT, + MODE_TEST_GLOBAL, + MODE_TEST_LOCAL, + MODE_TEST_SILENT +} CanMode; + +typedef void (*can_irq_handler)(uint32_t id, CanIrqType type); + +typedef struct can_s can_t; + +void can_init (can_t *obj, PinName rd, PinName td); +void can_free (can_t *obj); +int can_frequency(can_t *obj, int hz); + +void can_irq_init (can_t *obj, can_irq_handler handler, uint32_t id); +void can_irq_free (can_t *obj); +void can_irq_set (can_t *obj, CanIrqType irq, uint32_t enable); + +int can_write (can_t *obj, CAN_Message, int cc); +int can_read (can_t *obj, CAN_Message *msg, int handle); +int can_mode (can_t *obj, CanMode mode); +int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle); +void can_reset (can_t *obj); +unsigned char can_rderror (can_t *obj); +unsigned char can_tderror (can_t *obj); +void can_monitor (can_t *obj, int silent); + +#ifdef __cplusplus +}; +#endif + +#endif // MBED_CAN_API_H + +#endif diff --git a/USDK/component/common/mbed/hal/ethernet_api.h b/USDK/component/common/mbed/hal/ethernet_api.h new file mode 100644 index 0000000..4cae77e --- /dev/null +++ b/USDK/component/common/mbed/hal/ethernet_api.h @@ -0,0 +1,63 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_ETHERNET_API_H +#define MBED_ETHERNET_API_H + +#include "device.h" + +#if DEVICE_ETHERNET + +#ifdef __cplusplus +extern "C" { +#endif + +// Connection constants + +int ethernet_init(void); +void ethernet_free(void); + +// write size bytes from data to ethernet buffer +// return num bytes written +// or -1 if size is too big +int ethernet_write(const char *data, int size); + +// send ethernet write buffer, returning the packet size sent +int ethernet_send(void); + +// recieve from ethernet buffer, returning packet size, or 0 if no packet +int ethernet_receive(void); + +// read size bytes in to data, return actual num bytes read (0..size) +// if data == NULL, throw the bytes away +int ethernet_read(char *data, int size); + +// get the ethernet address +void ethernet_address(char *mac); + +// see if the link is up +int ethernet_link(void); + +// force link settings +void ethernet_set_link(int speed, int duplex); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + diff --git a/USDK/component/common/mbed/hal/gpio_api.h b/USDK/component/common/mbed/hal/gpio_api.h new file mode 100644 index 0000000..e4cf7fd --- /dev/null +++ b/USDK/component/common/mbed/hal/gpio_api.h @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_API_H +#define MBED_GPIO_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Set the given pin as GPIO + * @param pin The pin to be set as GPIO + * @return The GPIO port mask for this pin + **/ +uint32_t gpio_set(PinName pin); + +/* GPIO object */ +void gpio_init(gpio_t *obj, PinName pin); + +void gpio_mode (gpio_t *obj, PinMode mode); +void gpio_dir (gpio_t *obj, PinDirection direction); + +void gpio_write(gpio_t *obj, int value); +int gpio_read (gpio_t *obj); + +// the following set of functions are generic and are implemented in the common gpio.c file +void gpio_init_in(gpio_t* gpio, PinName pin); +void gpio_init_in_ex(gpio_t* gpio, PinName pin, PinMode mode); +void gpio_init_out(gpio_t* gpio, PinName pin); +void gpio_init_out_ex(gpio_t* gpio, PinName pin, int value); +void gpio_init_inout(gpio_t* gpio, PinName pin, PinDirection direction, PinMode mode, int value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/gpio_irq_api.h b/USDK/component/common/mbed/hal/gpio_irq_api.h new file mode 100644 index 0000000..ccdb30c --- /dev/null +++ b/USDK/component/common/mbed/hal/gpio_irq_api.h @@ -0,0 +1,47 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_IRQ_API_H +#define MBED_GPIO_IRQ_API_H + +#include "device.h" + +#if DEVICE_INTERRUPTIN + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IRQ_NONE, + IRQ_RISE, + IRQ_FALL +} gpio_irq_event; + +typedef void (*gpio_irq_handler)(uint32_t id, gpio_irq_event event); + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id); +void gpio_irq_free(gpio_irq_t *obj); +void gpio_irq_set (gpio_irq_t *obj, gpio_irq_event event, uint32_t enable); +void gpio_irq_enable(gpio_irq_t *obj); +void gpio_irq_disable(gpio_irq_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/i2c_api.h b/USDK/component/common/mbed/hal/i2c_api.h new file mode 100644 index 0000000..af48602 --- /dev/null +++ b/USDK/component/common/mbed/hal/i2c_api.h @@ -0,0 +1,59 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_I2C_API_H +#define MBED_I2C_API_H + +#include "device.h" + +#if DEVICE_I2C + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct i2c_s i2c_t; + +enum { + I2C_ERROR_NO_SLAVE = -1, + I2C_ERROR_BUS_BUSY = -2 +}; + +void i2c_init (i2c_t *obj, PinName sda, PinName scl); +void i2c_frequency (i2c_t *obj, int hz); +int i2c_start (i2c_t *obj); +int i2c_stop (i2c_t *obj); +int i2c_read (i2c_t *obj, int address, char *data, int length, int stop); +int i2c_write (i2c_t *obj, int address, const char *data, int length, int stop); +void i2c_reset (i2c_t *obj); +int i2c_byte_read (i2c_t *obj, int last); +int i2c_byte_write (i2c_t *obj, int data); + + +#if DEVICE_I2CSLAVE +void i2c_slave_mode (i2c_t *obj, int enable_slave); +int i2c_slave_receive(i2c_t *obj); +int i2c_slave_read (i2c_t *obj, char *data, int length); +int i2c_slave_write (i2c_t *obj, const char *data, int length); +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/pinmap.h b/USDK/component/common/mbed/hal/pinmap.h new file mode 100644 index 0000000..653d5fe --- /dev/null +++ b/USDK/component/common/mbed/hal/pinmap.h @@ -0,0 +1,43 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PINMAP_H +#define MBED_PINMAP_H + +#include "PinNames.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + int peripheral; + int function; +} PinMap; + +void pin_function(PinName pin, int function); +void pin_mode (PinName pin, PinMode mode); + +uint32_t pinmap_peripheral(PinName pin, const PinMap* map); +uint32_t pinmap_merge (uint32_t a, uint32_t b); +void pinmap_pinout (PinName pin, const PinMap *map); +uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/port_api.h b/USDK/component/common/mbed/hal/port_api.h new file mode 100644 index 0000000..f687cfe --- /dev/null +++ b/USDK/component/common/mbed/hal/port_api.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTMAP_H +#define MBED_PORTMAP_H + +#include "device.h" + +#if DEVICE_PORTIN || DEVICE_PORTOUT + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct port_s port_t; + +PinName port_pin(PortName port, int pin_n); + +void port_init (port_t *obj, PortName port, int mask, PinDirection dir); +void port_mode (port_t *obj, PinMode mode); +void port_dir (port_t *obj, PinDirection dir); +void port_write(port_t *obj, int value); +int port_read (port_t *obj); + +#ifdef __cplusplus +} +#endif +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/pwmout_api.h b/USDK/component/common/mbed/hal/pwmout_api.h new file mode 100644 index 0000000..5e94363 --- /dev/null +++ b/USDK/component/common/mbed/hal/pwmout_api.h @@ -0,0 +1,49 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PWMOUT_API_H +#define MBED_PWMOUT_API_H + +#include "device.h" + +#if DEVICE_PWMOUT + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct pwmout_s pwmout_t; + +int pwmout_init (pwmout_t* obj, PinName pin); // != 0 - error +void pwmout_free (pwmout_t* obj); + +//void pwmout_write (pwmout_t* obj, float percent); +//float pwmout_read (pwmout_t* obj); + +//void pwmout_period (pwmout_t* obj, float seconds); +//void pwmout_period_ms (pwmout_t* obj, int ms); +void pwmout_period_us (pwmout_t* obj, uint32_t us); + +//void pwmout_pulsewidth (pwmout_t* obj, float seconds); +//void pwmout_pulsewidth_ms(pwmout_t* obj, uint32_t ms); +void pwmout_pulsewidth_us(pwmout_t* obj, uint32_t us); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/rtc_api.h b/USDK/component/common/mbed/hal/rtc_api.h new file mode 100644 index 0000000..663f888 --- /dev/null +++ b/USDK/component/common/mbed/hal/rtc_api.h @@ -0,0 +1,42 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_RTC_API_H +#define MBED_RTC_API_H + +#include "device.h" + +#if DEVICE_RTC + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void rtc_init(void); +void rtc_free(void); +int rtc_isenabled(void); + +time_t rtc_read(void); +void rtc_write(time_t t); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/serial_api.h b/USDK/component/common/mbed/hal/serial_api.h new file mode 100644 index 0000000..2b0f0c4 --- /dev/null +++ b/USDK/component/common/mbed/hal/serial_api.h @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SERIAL_API_H +#define MBED_SERIAL_API_H + +#include "device.h" + +#if DEVICE_SERIAL + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ParityNone = 0, + ParityOdd = 1, + ParityEven = 2, + ParityForced1 = 3, + ParityForced0 = 4 +} SerialParity; + +typedef enum { + RxIrq, + TxIrq +} SerialIrq; + +typedef enum { + FlowControlNone, + FlowControlRTS, + FlowControlCTS, + FlowControlRTSCTS +} FlowControl; + +typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event); + +typedef struct serial_s serial_t; + +void serial_init (serial_t *obj, PinName tx, PinName rx); +void serial_free (serial_t *obj); +void serial_baud (serial_t *obj, int baudrate); +void serial_format (serial_t *obj, int data_bits, SerialParity parity, int stop_bits); + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id); +void serial_irq_set (serial_t *obj, SerialIrq irq, uint32_t enable); + +int serial_getc (serial_t *obj); +void serial_putc (serial_t *obj, int c); +int serial_readable (serial_t *obj); +int serial_writable (serial_t *obj); +void serial_clear (serial_t *obj); + +void serial_break_set (serial_t *obj); +void serial_break_clear(serial_t *obj); + +void serial_pinout_tx(PinName tx); + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/sleep_api.h b/USDK/component/common/mbed/hal/sleep_api.h new file mode 100644 index 0000000..c8cf3b6 --- /dev/null +++ b/USDK/component/common/mbed/hal/sleep_api.h @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SLEEP_API_H +#define MBED_SLEEP_API_H + +#include "device.h" + +#if DEVICE_SLEEP + +#ifdef __cplusplus +extern "C" { +#endif + +/** Send the microcontroller to sleep + * + * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the + * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates + * dynamic power used by the processor, memory systems and buses. The processor, peripheral and + * memory state are maintained, and the peripherals continue to work and can generate interrupts. + * + * The processor can be woken up by any internal peripheral interrupt or external pin interrupt. + * + * @note + * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. + * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be + * able to access the LocalFileSystem + */ +void sleep(void); + +/** Send the microcontroller to deep sleep + * + * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode + * has the same sleep features as sleep plus it powers down peripherals and clocks. All state + * is still maintained. + * + * The processor can only be woken up by an external interrupt on a pin or a watchdog timer. + * + * @note + * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. + * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be + * able to access the LocalFileSystem + */ +void deepsleep(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/spi_api.h b/USDK/component/common/mbed/hal/spi_api.h new file mode 100644 index 0000000..7553dc1 --- /dev/null +++ b/USDK/component/common/mbed/hal/spi_api.h @@ -0,0 +1,45 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SPI_API_H +#define MBED_SPI_API_H + +#include "device.h" + +#if DEVICE_SPI + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct spi_s spi_t; + +void spi_init (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel); +void spi_free (spi_t *obj); +void spi_format (spi_t *obj, int bits, int mode, int slave); +void spi_frequency (spi_t *obj, int hz); +int spi_master_write (spi_t *obj, int value); +int spi_slave_receive(spi_t *obj); +int spi_slave_read (spi_t *obj); +void spi_slave_write (spi_t *obj, int value); +int spi_busy (spi_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal/us_ticker_api.h b/USDK/component/common/mbed/hal/us_ticker_api.h new file mode 100644 index 0000000..ea62d7c --- /dev/null +++ b/USDK/component/common/mbed/hal/us_ticker_api.h @@ -0,0 +1,51 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_US_TICKER_API_H +#define MBED_US_TICKER_API_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint64_t timestamp_t; + +uint32_t us_ticker_read(void); + +typedef void (*ticker_event_handler)(uint32_t id); +void us_ticker_set_handler(ticker_event_handler handler); + +typedef struct ticker_event_s { + timestamp_t timestamp; + uint32_t id; + struct ticker_event_s *next; +} ticker_event_t; + +void us_ticker_init(void); +void us_ticker_set_interrupt(timestamp_t timestamp); +void us_ticker_disable_interrupt(void); +void us_ticker_clear_interrupt(void); +void us_ticker_irq_handler(void); + +void us_ticker_insert_event(ticker_event_t *obj, timestamp_t timestamp, uint32_t id); +void us_ticker_remove_event(ticker_event_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/dma_api.h b/USDK/component/common/mbed/hal_ext/dma_api.h new file mode 100644 index 0000000..1bf3a0e --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/dma_api.h @@ -0,0 +1,44 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GDMA_API_H +#define MBED_GDMA_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct gdma_s { + HAL_GDMA_OBJ gdma_obj; + uint8_t gdma_allocated; +}; + +typedef struct gdma_s gdma_t; + +typedef void (*dma_irq_handler)(uint32_t id); + +void dma_memcpy_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id); +void dma_memcpy_deinit(gdma_t *dma_obj); +void dma_memcpy(gdma_t *dma_obj, void *dst, void* src, uint32_t len); +void dma_memcpy_aggr_init(gdma_t * dma_obj, dma_irq_handler handler, uint32_t id); +void dma_memcpy_aggr(gdma_t * dma_obj, PHAL_GDMA_BLOCK block_info); + +#ifdef __cplusplus +} +#endif + +#endif // end of "#define MBED_GDMA_API_H" diff --git a/USDK/component/common/mbed/hal_ext/efuse_api.h b/USDK/component/common/mbed/hal_ext/efuse_api.h new file mode 100644 index 0000000..26e28dd --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/efuse_api.h @@ -0,0 +1,31 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#ifndef MBED_EXT_EFUSE_API_EXT_H +#define MBED_EXT_EFUSE_API_EXT_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int efuse_get_remaining_length(void); +void efuse_mtp_read(uint8_t * data); +int efuse_mtp_write(uint8_t *data, uint8_t len); +int efuse_otp_read(u8 address, u8 len, u8 *buf); +int efuse_otp_write(u8 address, u8 len, u8 *buf); +int efuse_disable_jtag(void); + +#ifdef __cplusplus +} +#endif + +#endif // MBED_EXT_EFUSE_API_EXT_H diff --git a/USDK/component/common/mbed/hal_ext/ethernet_ex_api.h b/USDK/component/common/mbed/hal_ext/ethernet_ex_api.h new file mode 100644 index 0000000..27c3205 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/ethernet_ex_api.h @@ -0,0 +1,48 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ETHERNET_EX_API_H +#define ETHERNET_EX_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#define ETH_TX_DESC_SIZE 20 // 20 Bytes +#define ETH_RX_DESC_SIZE 16 // 16 Bytes +#define ETH_PKT_BUF_SIZE 1536 + + +typedef void (*ethernet_callback)(uint32_t event, uint32_t data); + +void ethernet_irq_hook(ethernet_callback callback); +/* Set the numbers of Tx/Rx descriptor */ +void ethernet_set_descnum(uint8_t txdescCnt, uint8_t rxdescCnt); +/* Set the start address of Tx/Rx descriptor and packet buffer */ +void ethernet_trx_pre_setting(uint8_t *TxDescAddr, uint8_t *RxDescAddr, uint8_t *pTxPktBuf, uint8_t *pRxPktBuf); + + + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef ETHERNET_EX_API_H + diff --git a/USDK/component/common/mbed/hal_ext/ex_api.h b/USDK/component/common/mbed/hal_ext/ex_api.h new file mode 100644 index 0000000..8a4fe79 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/ex_api.h @@ -0,0 +1,49 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef EX_API_H +#define EX_API_H + +#include "device.h" +#include "serial_api.h" +#include "spi_api.h" +#include "dma_api.h" +#include "flash_api.h" +#include "flash_eep.h" +#include "gpio_ex_api.h" +#include "gpio_irq_ex_api.h" +#include "i2c_ex_api.h" +#include "i2s_api.h" +#include "nfc_api.h" +#include "serial_ex_api.h" +#include "sleep_ex_api.h" +#include "spi_ex_api.h" +#include "sys_api.h" +#include "wdt_api.h" +#include "ethernet_ex_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/USDK/component/common/mbed/hal_ext/flash_api.h b/USDK/component/common/mbed/hal_ext/flash_api.h new file mode 100644 index 0000000..00ab5d2 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/flash_api.h @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#ifndef MBED_EXT_FLASH_API_EXT_H +#define MBED_EXT_FLASH_API_EXT_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct flash_s flash_t; + +/** + * global data structure + */ +extern flash_t flashobj; +extern bool fspic_isinit; + +enum { + FLASH_COMPLETE = 0, + FLASH_ERROR_2 = 1, +}; + +void flash_turnon (void); +void flash_init (flash_t *obj); +void flash_erase_sector (flash_t *obj, uint32_t address); +void flash_erase_block (flash_t *obj, uint32_t address); +int flash_read_word (flash_t *obj, uint32_t address, uint32_t * data); +int flash_write_word (flash_t *obj, uint32_t address, uint32_t data); +int flash_stream_read (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data); +int flash_stream_write (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data); +void flash_write_protect (flash_t *obj, uint32_t protect); +int flash_get_status (flash_t * obj); +int flash_set_status (flash_t * obj, uint32_t data); +void flash_reset_status (flash_t * obj); +int flash_burst_write (flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data); +int flash_burst_read (flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data); +int flash_set_extend_addr (flash_t * obj, uint32_t data); +int flash_get_extend_addr (flash_t * obj); +unsigned int flash_get_size (flash_t *obj); +int flash_otp_read (flash_t *obj, uint32_t address, uint32_t Length, uint8_t * data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/flash_eep.h b/USDK/component/common/mbed/hal_ext/flash_eep.h new file mode 100644 index 0000000..18604ca --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/flash_eep.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * FileName: flash_eep.h + * Description: FLASH + * Alternate SDK + * Author: PV` + * (c) PV` 2015 +*******************************************************************************/ +#ifndef __FLASH_EEP_H_ +#define __FLASH_EEP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +//----------------------------------------------------------------------------- +#ifndef FLASH_SECTOR_SIZE + #define FLASH_SECTOR_SIZE 4096 +#endif +#define FLASH_SECTORS 256 // 1 Mbytes +#define FLASH_CHIP_SIZE (FLASH_SECTORS * FLASH_SECTOR_SIZE) +#define FMEMORY_SCFG_BANK_SIZE FLASH_SECTOR_SIZE // размер сектора, 4096 bytes +#define FMEMORY_SCFG_BANKS 2 // кол-во секторов для работы 2... +#define FMEMORY_SCFG_BASE_ADDR (FLASH_CHIP_SIZE - (FMEMORY_SCFG_BANKS*FMEMORY_SCFG_BANK_SIZE)) // = 0xFE000 +//----------------------------------------------------------------------------- +#define FLASH_EEP_ATTR +//----------------------------------------------------------------------------- +enum eFMEMORY_ERRORS { + FMEM_NOT_FOUND = -1, // -1 - не найден + FMEM_FLASH_ERR = -2, // -2 - flash rd/wr/erase error + FMEM_ERROR = -3, // -3 - error + FMEM_OVR_ERR = -4, // -4 - переполнение FMEMORY_SCFG_BANK_SIZE + FMEM_MEM_ERR = -5 // -5 - heap alloc error +}; +//----------------------------------------------------------------------------- +// extern QueueHandle_t flash_mutex; +signed short flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize) FLASH_EEP_ATTR; // возврат: размер объекта последнего сохранения, -1 - не найден, -2 - error +bool flash_write_cfg(void *ptr, unsigned short id, unsigned short size) FLASH_EEP_ATTR; +//----------------------------------------------------------------------------- +#ifndef USE_FLASH_EEP +#define USE_FLASH_EEP 1 +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* __FLASH_EEP_H_ */ diff --git a/USDK/component/common/mbed/hal_ext/gpio_ex_api.h b/USDK/component/common/mbed/hal_ext/gpio_ex_api.h new file mode 100644 index 0000000..52b0bd3 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/gpio_ex_api.h @@ -0,0 +1,36 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_API_H +#define MBED_GPIO_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* GPIO object */ +void gpio_direct_write(gpio_t *obj, BOOL value) ; +void gpio_pull_ctrl(gpio_t *obj, PinMode pull_type); +void gpio_deinit(gpio_t *obj, PinName pin); +void gpio_change_dir(gpio_t *obj, PinDirection direction); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/gpio_irq_ex_api.h b/USDK/component/common/mbed/hal_ext/gpio_irq_ex_api.h new file mode 100644 index 0000000..2fcee20 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/gpio_irq_ex_api.h @@ -0,0 +1,40 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_IRQ_EX_API_H +#define MBED_GPIO_IRQ_EX_API_H + +#include "device.h" + +#if DEVICE_INTERRUPTIN + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IRQ_LOW = 3, + IRQ_HIGH =4 +} gpio_irq_event_ex; + +void gpio_irq_deinit(gpio_irq_t *obj); +void gpio_irq_pull_ctrl(gpio_irq_t *obj, PinMode pull_type); +#ifdef __cplusplus +} +#endif + +#endif // end of "#if DEVICE_INTERRUPTIN" + +#endif // end of #ifndef MBED_GPIO_IRQ_EX_API_H \ No newline at end of file diff --git a/USDK/component/common/mbed/hal_ext/i2c_ex_api.h b/USDK/component/common/mbed/hal_ext/i2c_ex_api.h new file mode 100644 index 0000000..90fa1fa --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/i2c_ex_api.h @@ -0,0 +1,46 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef I2C_EX_API_H +#define I2C_EX_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + I2C_TX_COMPLETE = 0, + I2C_RX_COMPLETE = 1, + I2C_RD_REQ_COMMAND = 2, + I2C_ERR_OCCURRED = 3, +}I2CCallback; + +void i2c_set_user_callback(i2c_t *obj, I2CCallback i2ccb, void(*i2c_callback)(void *)); +void i2c_clear_user_callback(i2c_t *obj, I2CCallback i2ccb); +int i2c_enable_control(i2c_t *obj, int enable); + +void i2c_restart_enable(i2c_t *obj); +void i2c_restart_disable(i2c_t *obj); + + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/USDK/component/common/mbed/hal_ext/i2s_api.h b/USDK/component/common/mbed/hal_ext/i2s_api.h new file mode 100644 index 0000000..8533af3 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/i2s_api.h @@ -0,0 +1,76 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2015, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#ifndef MBED_EXT_I2S_API_EXT_H +#define MBED_EXT_I2S_API_EXT_H + +#include "device.h" +#include "rtl8195a.h" +#include "hal_i2s.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + SR_8KHZ = I2S_SR_8KHZ, + SR_16KHZ = I2S_SR_16KHZ, + SR_24KHZ = I2S_SR_24KHZ, + SR_32KHZ = I2S_SR_32KHZ, + SR_48KHZ = I2S_SR_48KHZ, + SR_96KHZ = I2S_SR_96KHZ, + SR_7p35KHZ = I2S_SR_7p35KHZ, + SR_11p02KHZ = I2S_SR_11p02KHZ, + SR_22p05KHZ = I2S_SR_22p05KHZ, + SR_29p4KHZ = I2S_SR_29p4KHZ, + SR_44p1KHZ = I2S_SR_44p1KHZ, + SR_88p2KHZ = I2S_SR_88p2KHZ +}; + +enum { + CH_STEREO = I2S_CH_STEREO, + CH_MONO = I2S_CH_MONO +}; + +enum { + WL_16b = I2S_WL_16, + WL_24b = I2S_WL_24 +}; + +enum { + I2S_DIR_RX = I2S_ONLY_RX, // Rx Only + I2S_DIR_TX = I2S_ONLY_TX, // Tx Only + I2S_DIR_TXRX = I2S_TXRX // Tx & Rx (BiDirection) +}; + +typedef void (*i2s_irq_handler)(uint32_t id, char *pbuf); + +typedef struct i2s_s i2s_t; + +void i2s_init(i2s_t *obj, PinName sck, PinName ws, PinName sd); +void i2s_set_dma_buffer(i2s_t *obj, char *tx_buf, char *rx_buf, + uint32_t page_num, uint32_t page_size); +void i2s_tx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id); +void i2s_rx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id); +void i2s_set_direction(i2s_t *obj, int trx_type); +void i2s_set_param(i2s_t *obj, int channel_num, int rate, int word_len); +void i2s_deinit(i2s_t *obj); +int* i2s_get_tx_page(i2s_t *obj); +void i2s_send_page(i2s_t *obj, uint32_t *pbuf); +void i2s_recv_page(i2s_t *obj); +void i2s_enable(i2s_t *obj); +void i2s_disable(i2s_t *obj); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/USDK/component/common/mbed/hal_ext/log_uart_api.h b/USDK/component/common/mbed/hal_ext/log_uart_api.h new file mode 100644 index 0000000..c1edeef --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/log_uart_api.h @@ -0,0 +1,66 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LOG_UART_API_H +#define LOG_UART_API_H + +#include "device.h" +#include "serial_api.h" +#include "hal_log_uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*loguart_irq_handler)(uint32_t id, LOG_UART_INT_ID event); + +typedef struct log_uart_s log_uart_t; + +int32_t log_uart_init (log_uart_t *obj, int baudrate, int data_bits, SerialParity parity, int stop_bits); +void log_uart_free(log_uart_t *obj); +void log_uart_baud(log_uart_t *obj, int baudrate); +void log_uart_format(log_uart_t *obj, int data_bits, SerialParity parity, int stop_bits); +void log_uart_irq_handler(log_uart_t *obj, loguart_irq_handler handler, uint32_t id); +void log_uart_irq_set(log_uart_t *obj, LOG_UART_INT_ID irq, uint32_t enable); +char log_uart_getc(log_uart_t *obj); +void log_uart_putc(log_uart_t *obj, char c); +int log_uart_readable(log_uart_t *obj); +int log_uart_writable(log_uart_t *obj); +void log_uart_clear(log_uart_t *obj); +void log_uart_clear_tx(log_uart_t *obj); +void log_uart_clear_rx(log_uart_t *obj); +void log_uart_break_set(log_uart_t *obj); +void log_uart_break_clear(log_uart_t *obj); +void log_uart_tx_comp_handler(log_uart_t *obj, void *handler, uint32_t id); +void log_uart_rx_comp_handler(log_uart_t *obj, void *handler, uint32_t id); +void log_uart_line_status_handler(log_uart_t *obj, void *handler, uint32_t id); +int32_t log_uart_recv (log_uart_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms); +int32_t log_uart_send (log_uart_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms); +int32_t log_uart_recv_stream (log_uart_t *obj, char *prxbuf, uint32_t len); +int32_t log_uart_send_stream (log_uart_t *obj, char *ptxbuf, uint32_t len); +int32_t log_uart_recv_stream_timeout (log_uart_t *obj, char *prxbuf, uint32_t len, + uint32_t timeout_ms, void *force_cs); +int32_t log_uart_send_stream_abort (log_uart_t *obj); +int32_t log_uart_recv_stream_abort (log_uart_t *obj); +void log_uart_disable (log_uart_t *obj); +void log_uart_enable (log_uart_t *obj); +uint8_t log_uart_raed_lsr(log_uart_t *obj); +uint8_t log_uart_raed_msr(log_uart_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif // end of "#ifndef LOG_UART_API_H" diff --git a/USDK/component/common/mbed/hal_ext/nfc_api.h b/USDK/component/common/mbed/hal_ext/nfc_api.h new file mode 100644 index 0000000..d282568 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/nfc_api.h @@ -0,0 +1,70 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_NFC_API_H +#define MBED_NFC_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFCTAGLENGTH 36 // maximum 36*4=144 bytes +#define NFC_MAX_CACHE_PAGE_NUM 36 // maximum 36*4=144 bytes + +typedef enum _NFC_STATUS_ { + NFC_OK = 0, + NFC_ERROR = -1 +}NFC_STATUS, *PNFC_STATUS; + +typedef enum _NFC_PWR_STATUS_ { + NFC_PWR_DISABLE = 0, + NFC_PWR_RUNNING = 1, + NFC_PWR_SLEEP0 = 2, + NFC_PWR_SLEEP1 = 3, + NFC_PWR_DOWN = 4, + NFC_PWR_ERROR = -1 +}NFC_PWR_STATUS, *PNFC_PWR_STATUS; + +typedef enum _NFC_EVENT_ { + NFC_EV_READER_PRESENT = (1<<0), + NFC_EV_READ = (1<<1), + NFC_EV_WRITE = (1<<2), + NFC_EV_ERR = (1<<3), + NFC_EV_CACHE_READ = (1<<4) +}NFC_EVENT, *PNFC_EVENT; + +typedef struct nfctag_s nfctag_t; + +typedef void (*nfc_read_cb)(void *arg, void *buf, unsigned int page); +typedef void(*nfc_write_cb)(void *arg, unsigned int page, uint32_t pgdat); +typedef void(*nfc_event_cb)(void *arg, unsigned int event); +typedef void(*nfc_cache_read_cb)(void *arg, void *buf, unsigned int page); + +int nfc_init(nfctag_t *obj, uint32_t *pg_init_val); +void nfc_read(nfctag_t *obj, nfc_read_cb handler, void *arg); +void nfc_write(nfctag_t *obj, nfc_write_cb handler, void *arg); +void nfc_event(nfctag_t *obj, nfc_event_cb handler, void *arg, unsigned int event_mask); +int nfc_power(nfctag_t *obj, int pwr_mode, int wake_event); +int nfc_cache_write(nfctag_t *obj, uint32_t *tbuf, unsigned int spage, unsigned int pg_num); +int nfc_cache_raed(nfctag_t *obj, nfc_cache_read_cb handler, void *arg, unsigned int start_pg); +int nfc_status(nfctag_t *obj); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/serial_ex_api.h b/USDK/component/common/mbed/hal_ext/serial_ex_api.h new file mode 100644 index 0000000..967ef44 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/serial_ex_api.h @@ -0,0 +1,60 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SERIAL_EX_API_H +#define MBED_SERIAL_EX_API_H + +#include "device.h" + +#if DEVICE_SERIAL + +#ifdef __cplusplus +extern "C" { +#endif + +// Define RX FIFO Level: RX interrupt trigger, RTS de-assert trigger +typedef enum { + FifoLv1Byte=0, // 1-byte + FifoLvQuarter=1, // 4-byte + FifoLvHalf=2, // 8-byte + FifoLvFull=3 // 14-byte +} SerialFifoLevel; + +void serial_clear_tx(serial_t *obj); +void serial_clear_rx(serial_t *obj); +void serial_send_comp_handler(serial_t *obj, void *handler, uint32_t id); +void serial_recv_comp_handler(serial_t *obj, void *handler, uint32_t id); +int32_t serial_recv_blocked (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms); +int32_t serial_send_blocked (serial_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms); +int32_t serial_recv_stream (serial_t *obj, char *prxbuf, uint32_t len); +int32_t serial_send_stream (serial_t *obj, char *ptxbuf, uint32_t len); +int32_t serial_recv_stream_dma (serial_t *obj, char *prxbuf, uint32_t len); +int32_t serial_send_stream_dma (serial_t *obj, char *ptxbuf, uint32_t len); +int32_t serial_send_stream_abort (serial_t *obj); +int32_t serial_recv_stream_abort (serial_t *obj); +void serial_disable (serial_t *obj); +void serial_enable (serial_t *obj); +int32_t serial_recv_stream_timeout (serial_t *obj, char *prxbuf, uint32_t \ + len, uint32_t timeout_ms, void *force_cs); +int32_t serial_recv_stream_dma_timeout (serial_t *obj, char *prxbuf, \ + uint32_t len, uint32_t timeout_ms, void *force_cs); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif // #ifndef MBED_SERIAL_EX_API_H diff --git a/USDK/component/common/mbed/hal_ext/sleep_ex_api.h b/USDK/component/common/mbed/hal_ext/sleep_ex_api.h new file mode 100644 index 0000000..9d47acf --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/sleep_ex_api.h @@ -0,0 +1,98 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SLEEP_EX_API_H +#define MBED_SLEEP_EX_API_H + +#include "device.h" + +#if DEVICE_SLEEP + +#ifdef __cplusplus +extern "C" { +#endif + +/* Sleep Eake Up event, the User application also + need to config the peripheral to trigger wake up event */ +#define SLEEP_WAKEUP_BY_STIMER (SLP_STIMER) // wake up by system timer +#define SLEEP_WAKEUP_BY_GTIMER (SLP_GTIMER) // wake up by General purpose timer timeout +#define SLEEP_WAKEUP_BY_GPIO_INT (SLP_GPIO) // wake up by GPIO Port A[7:0] Interrupt +#define SLEEP_WAKEUP_BY_WLAN (SLP_WL) // wake up by WLan event +#define SLEEP_WAKEUP_BY_NFC (SLP_NFC) // wake up by NFC event +#define SLEEP_WAKEUP_BY_SDIO (SLP_SDIO) // wake up by SDIO event +#define SLEEP_WAKEUP_BY_USB (SLP_USB) // wake up by USB event + +// Deep Standby Wakeup event +#define STANDBY_WAKEUP_BY_STIMER (BIT0) // wake up by system timer +#define STANDBY_WAKEUP_BY_NFC (BIT1) // wake up by NFC event +//#define SLEEP_WAKEUP_BY_DS_TIMER (BIT2) // The timer to wakeup from Deep Sleep timer +// Do not modify these definition, or need to modify the code also. +#define STANDBY_WAKEUP_BY_PA5 (BIT4) // GPIO Port A[5] +#define STANDBY_WAKEUP_BY_PC7 (BIT5) // GPIO Port C[7] +#define STANDBY_WAKEUP_BY_PD5 (BIT6) // GPIO Port D[5] +#define STANDBY_WAKEUP_BY_PE3 (BIT7) // GPIO Port E[3] + +// Deep Sleep Wakeup event +#define DSLEEP_WAKEUP_BY_TIMER (DS_TIMER33) +#define DSLEEP_WAKEUP_BY_GPIO (DS_GPIO) // GPIO Port B[1] + +typedef struct _SLEEP_WKUP_EVENT_ { + u8 wakeup_event; // Wake up event: Timer, NFC, GPIO + u8 gpio_option; // GPIO Wakeup setting: [3:0]: Pin 3~0 enable, [7:4]: pin3~0 active high/low + u32 timer_duration; // the sleep duration and then wakeup +} SLEEP_WAKEUP_EVENT, *PSLEEP_WAKEUP_EVENT; +/** Send the microcontroller to sleep + * + * The processor is setup ready for sleep, and sent to sleep using __WFI(). In this mode, the + * system clock to the core is stopped until a reset or an interrupt occurs. This eliminates + * dynamic power used by the processor, memory systems and buses. The processor, peripheral and + * memory state are maintained, and the peripherals continue to work and can generate interrupts. + * + * The processor can be woken up by any internal peripheral interrupt or external pin interrupt. + * + * @note + * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. + * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be + * able to access the LocalFileSystem + */ +void sleep_ex(uint32_t wakeup_event, uint32_t sleep_duration); +void sleep_ex_selective(uint32_t wakeup_event, uint32_t sleep_duration, uint32_t clk_sourec_enable, uint32_t sdr_enable); + +void standby_wakeup_event_add(uint32_t wakeup_event, uint32_t sleep_duration_ms, uint32_t gpio_active); +void standby_wakeup_event_del(uint32_t wakeup_event); +void deepstandby_ex(void); + +/** Send the microcontroller to deep sleep + * + * This processor is setup ready for deep sleep, and sent to sleep using __WFI(). This mode + * has the same sleep features as sleep plus it powers down peripherals and clocks. All state + * is still maintained. + * + * The processor can only be woken up by an external interrupt on a pin or a timer. + * + * @note + * The mbed interface semihosting is disconnected as part of going to sleep, and can not be restored. + * Flash re-programming and the USB serial port will remain active, but the mbed program will no longer be + * able to access the LocalFileSystem + */ +void deepsleep_ex(uint32_t wakeup_event, uint32_t sleep_duration); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/spdio_api.h b/USDK/component/common/mbed/hal_ext/spdio_api.h new file mode 100644 index 0000000..c83b032 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/spdio_api.h @@ -0,0 +1,115 @@ +#ifndef __SPDIO_API_H__ +#define __SPDIO_API_H__ + +#include + +#define SPDIO_API_DBG + +#ifdef SPDIO_API_DBG +#define SPDIO_API_PRINTK(fmt, args...) printf(fmt"\r\n",## args) +#define _SPDIO_API_PRINTK(fmt, args...) printf(fmt,## args) +#else +#define SPDIO_API_PRINTK(fmt, args...) +#define _SPDIO_API_PRINTK(fmt, args...) +#endif + +#define SPDIO_DMA_ALIGN_4 4 +#define SPDIO_RX_BUFSZ_ALIGN(x) ((((x-1)>>6)+1)<<6) //alignement to 64 + +#define SPDIO_RXDESC_SZ 24 + +/*Don't modify this enum table*/ +enum spdio_rx_data_t{ + SPDIO_RX_DATA_NULL = 0x00, + SPDIO_RX_DATA_ETH = 0x83, //an ethernet packet received + SPDIO_RX_DATA_ATCMD = 0x11, //an AT command packet received + SPDIO_RX_DATA_USER = 0x41, //defined by user +}; + +enum spdio_tx_data_t{ + SPDIO_TX_DATA_NULL = 0x00, + SPDIO_TX_DATA_ETH = 0x82, //an ethernet packet sent + SPDIO_TX_DATA_ATCMDRSP = 0x10, //an AT command response packet sent + SPDIO_TX_DATA_USER = 0x40, // defined by user +}; + +struct spdio_buf_t{ + void *priv; //priv data from user + u32 buf_allocated; //The spdio buffer allocated address + u16 size_allocated; //The actual allocated size + u32 buf_addr; //The spdio buffer physical address, it must be 4-bytes aligned + u16 buf_size; + u8 type; //The type of the data which this buffer carries, spdio_rx_data_t and spdio_tx_data_t + u8 reserved; +}; + +struct spdio_t { + void *priv; //not used by user + u32 tx_bd_num; //for spdio send data to host, 2 bd for one packet, so this value must be rounded to 2 + u32 rx_bd_num; //for spdio receive data from host + u32 rx_bd_bufsz; //buffer size = desired packet length + 24(spdio header info), must be rounded to 64 + struct spdio_buf_t *rx_buf; //buffer array for spdio receive assigned by user, rx_bd_bufsz * rx_bd_num + + /** + *@brief: rx_done_cb: pointer to callback function defined by user, + called by spdio when one packet receive done + *@param priv: a pointer to spdio_t structure which is used to initilize spdio interface + *@param pbuf: a pointer to spdio_buf_t structure which is spdio receive buffer + *@param pdata: the actual received packet payload + *@param size: the actual payload length + *@param type: the received packet type, spdio_rx_data_t + *@retval: SUCCESS or FAIL + */ + char (*rx_done_cb)(void *priv, void* pbuf, u8 *pdata, u16 size, u8 type); + + /** + *@brief: tx_done_cb: pointer to callback function defined by user, + called by spdio when one packet sent done + *@param priv: a pointer to spdio_t structure which is used to initilize spdio interface + *@param pbuf: a pointer to spdio_buf_t structure which carries the transmit packet + *@retval: SUCCESS or FAIL + */ + char (*tx_done_cb)(void *priv, void* pbuf); +}; + +/** + * @brief Gets example setting for spdio obj. + * @param obj: a pointer to an spdio_t structure which will be initialized with an example settings + * @retval None + */ +void spdio_structinit(struct spdio_t *obj); + +/** + * @brief Initialize spdio interface. + * @param obj, a pointer to a spdio_t structure which should be initialized by user, + * and which will be used to initialize spdio interface + * obj->tx_bd_num: spdio write bd number, needs 2 bd for one transaction + * obj->rx_bd_num: spdio read bd number + * obj->rx_bd_bufsz: spdio read buffer size + * obj->rx_buf: spdio read buffer array + * @retval None + */ +void spdio_init(struct spdio_t *obj); + +/** + * @brief Deinitialize spdio interface. + * @param obj: a pointer to spdio_t structure which is already initialized + * @retval None + */ +void spdio_deinit(struct spdio_t *obj); + +/** + * @brief spdio write function. + * @param obj: a pointer to spdio_t structure which is already initialized + * @param pbuf: a pointer to spdio_buf_t structure which carries the payload + * @retval SUCCESS or FAIL + */ +s8 spdio_tx(struct spdio_t *obj, struct spdio_buf_t *pbuf); + +/** + * @brief an obj which will be used to initialize sdio interface + * so it must be initialized before calling HalSdioInit(); + */ +extern struct spdio_t *g_spdio_priv; + +#endif //#ifndef __SPDIO_API_H__ \ No newline at end of file diff --git a/USDK/component/common/mbed/hal_ext/spi_ex_api.h b/USDK/component/common/mbed/hal_ext/spi_ex_api.h new file mode 100644 index 0000000..55616fa --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/spi_ex_api.h @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SPI_EXT_API_H +#define MBED_SPI_EXT_API_H + +#include "device.h" + +#if DEVICE_SPI + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPI_DMA_RX_EN (1<<0) +#define SPI_DMA_TX_EN (1<<1) + +enum { + SPI_SCLK_IDLE_LOW=0, // the SCLK is Low when SPI is inactive + SPI_SCLK_IDLE_HIGH=2 // the SCLK is High when SPI is inactive +}; + +// SPI Master mode: for continuous transfer, how the CS toggle: +enum { + SPI_CS_TOGGLE_EVERY_FRAME=0, // let SCPH=0 then the CS toggle every frame + SPI_CS_TOGGLE_START_STOP=1 // let SCPH=1 the CS toggle at start and stop +}; + +enum { + SPI_SCLK_TOGGLE_MIDDLE=0, // Serial Clk toggle at middle of 1st data bit and latch data at 1st Clk edge + SPI_SCLK_TOGGLE_START=1 // Serial Clk toggle at start of 1st data bit and latch data at 2nd Clk edge +}; + +typedef enum { + CS_0 = 0, + CS_1 = 1, + CS_2 = 2, + CS_3 = 3, + CS_4 = 4, + CS_5 = 5, + CS_6 = 6, + CS_7 = 7 +}ChipSelect; + + +#define SPI_STATE_READY 0x00 +#define SPI_STATE_RX_BUSY (1<<1) +#define SPI_STATE_TX_BUSY (1<<2) + +typedef enum { + SpiRxIrq, + SpiTxIrq +} SpiIrq; + +typedef void (*spi_irq_handler)(uint32_t id, SpiIrq event); + +void spi_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id); +void spi_bus_tx_done_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id); +int32_t spi_slave_read_stream(spi_t *obj, char *rx_buffer, uint32_t length); +int32_t spi_slave_write_stream(spi_t *obj, char *tx_buffer, uint32_t length); +int32_t spi_master_read_stream(spi_t *obj, char *rx_buffer, uint32_t length); +int32_t spi_master_write_stream(spi_t *obj, char *tx_buffer, uint32_t length); +int32_t spi_master_write_read_stream(spi_t *obj, char *tx_buffer, + char *rx_buffer, uint32_t length); +int32_t spi_slave_read_stream_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms); + +#ifdef CONFIG_GDMA_EN +int32_t spi_slave_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length); +int32_t spi_slave_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length); +int32_t spi_master_write_read_stream_dma(spi_t * obj, char * tx_buffer, char * rx_buffer, uint32_t length); +int32_t spi_master_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length); +int32_t spi_master_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length); +int32_t spi_slave_read_stream_dma_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/USDK/component/common/mbed/hal_ext/sys_api.h b/USDK/component/common/mbed/hal_ext/sys_api.h new file mode 100644 index 0000000..46fbabb --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/sys_api.h @@ -0,0 +1,52 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_SYS_API_H +#define MBED_SYS_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Turn off the JTAG function + * + * @return None + * + */ +void sys_jtag_off(void); +void sys_clear_ota_signature(void); +void sys_recover_ota_signature(void); +void sys_log_uart_on(void); +void sys_log_uart_off(void); +void sys_adc_calibration(u8 write, u16 *offset, u16 *gain); +u8 sys_is_sdram_power_on(void); +void sys_sdram_off(void); + +/** + * @brief system software reset + * + * @return None + * + */ +void sys_reset(void); + +#ifdef __cplusplus +} +#endif + +#endif // MBED_SYS_API_H diff --git a/USDK/component/common/mbed/hal_ext/wdt_api.h b/USDK/component/common/mbed/hal_ext/wdt_api.h new file mode 100644 index 0000000..7531c34 --- /dev/null +++ b/USDK/component/common/mbed/hal_ext/wdt_api.h @@ -0,0 +1,61 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_WATCHDOG_API_H +#define MBED_WATCHDOG_API_H + +#include "device.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*wdt_irq_handler)(uint32_t id); + +/** Initial the watch dog time setting + * + * This function will initial and enable the watchdog timer with a given timeout value. + * When the watchdog timer timeout event is triggered, the system will be reset. User also can + * register a callback function to handle the watchdog timer timeout event. + */ +void watchdog_init(uint32_t timeout_ms); + +/** Start the watchdog counting + * + * This function will active the watchdog timer down counting. When the watchdog timer count down + * to 0, a callback function will be called or the system will be reset. + */ +void watchdog_start(void); + +/** Stop the watchdog counting + * + * This function will stop the watchdog timer down counting. If a user application aware a + * procedure may takes too long and cause the watchdog timer timeout, the application use this + * function to stop the watchdog timer to prevent the watchdog timer timeout. + */ +void watchdog_stop(void); + +/** Refresh the watchdog counting + * + * This function will reload the watchdog timer counting value. Usually a application do the watchdog + * timer reflash in the main loop to prevent the watchdog timer timeout. + */ +void watchdog_refresh(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/targets/cmsis/rtl8195a b/USDK/component/common/mbed/targets/cmsis/rtl8195a new file mode 100644 index 0000000..c9c1d60 --- /dev/null +++ b/USDK/component/common/mbed/targets/cmsis/rtl8195a @@ -0,0 +1,14 @@ +/* mbed Microcontroller Library - CMSIS + * Copyright (C) 2009-2011 ARM Limited. All rights reserved. + * + * A generic CMSIS include header, pulling in RTL8195A specifics + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include +#include + +#endif + diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/PeripheralNames.h b/USDK/component/common/mbed/targets/hal/rtl8195a/PeripheralNames.h new file mode 100644 index 0000000..cc899e7 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/PeripheralNames.h @@ -0,0 +1,100 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PERIPHERALNAMES_H +#define MBED_PERIPHERALNAMES_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +typedef enum { + UART_1 = (int)USART1_BASE, + UART_2 = (int)USART2_BASE, + UART_3 = (int)USART3_BASE, + UART_4 = (int)UART4_BASE, + UART_5 = (int)UART5_BASE, + UART_6 = (int)USART6_BASE +} UARTName; + +typedef enum { + ADC0_0 = 0, + ADC0_1, + ADC0_2, + ADC0_3, + ADC0_4, + ADC0_5, + ADC0_6, + ADC0_7, + ADC0_8, + ADC0_9, + ADC0_10, + ADC0_11, + ADC0_12, + ADC0_13, + ADC0_14, + ADC0_15 +} ADCName; + +typedef enum { + DAC_0 = 0, + DAC_1 +} DACName; + +typedef enum { + SPI_1 = (int)SPI1_BASE, + SPI_2 = (int)SPI2_BASE, + SPI_3 = (int)SPI3_BASE, +} SPIName; + +typedef enum { + I2C_1 = (int)I2C1_BASE, + I2C_2 = (int)I2C2_BASE, + I2C_3 = (int)I2C3_BASE +} I2CName; + +typedef enum { + PWM_1 = 1, + PWM_2, + PWM_3, + PWM_4, + PWM_5, + PWM_6 +} PWMName; + +typedef enum { + CAN_1 = (int)CAN1_BASE, + CAN_2 = (int)CAN2_BASE +} CANName; +#endif + +#define STDIO_UART_TX PA_6 +#define STDIO_UART_RX PA_7 +#define STDIO_UART UART0 + +typedef enum { + DAC_0 = 0, + DAC_1 +} DACName; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/PinNames.h b/USDK/component/common/mbed/targets/hal/rtl8195a/PinNames.h new file mode 100644 index 0000000..f374c42 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/PinNames.h @@ -0,0 +1,215 @@ + +#ifndef _PINNAMES_H_ +#define _PINNAMES_H_ + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PORT_A = 0, + PORT_B = 1, + PORT_C = 2, + PORT_D = 3, + PORT_E = 4, + PORT_F = 5, + PORT_G = 6, + PORT_H = 7, + PORT_I = 8, + PORT_J = 9, + PORT_K = 10, + + PORT_V = 11, + PORT_U = 12, + PORT_MAX +} GPIO_PORT; + +#define RTL_PIN_PERI(FUN, IDX, SEL) ((int)(((FUN) << 8) | ((IDX)<<4) | (SEL))) +#define RTL_PIN_FUNC(FUN, SEL) ((int)(((FUN) << 7) | (SEL))) +#define RTL_GET_PERI_SEL(peri) ((int)((peri)&0x0F)) +#define RTL_GET_PERI_IDX(peri) ((int)(((peri) >> 4)&0x0F)) + +typedef enum { + PIN_INPUT=0, + PIN_OUTPUT +} PinDirection; + +typedef enum { + PA_0 = (PORT_A<<4|0), + PA_1 = (PORT_A<<4|1), + PA_2 = (PORT_A<<4|2), + PA_3 = (PORT_A<<4|3), + PA_4 = (PORT_A<<4|4), + PA_5 = (PORT_A<<4|5), + PA_6 = (PORT_A<<4|6), + PA_7 = (PORT_A<<4|7), + + PB_0 = (PORT_B<<4|0), + PB_1 = (PORT_B<<4|1), + PB_2 = (PORT_B<<4|2), + PB_3 = (PORT_B<<4|3), + PB_4 = (PORT_B<<4|4), + PB_5 = (PORT_B<<4|5), + PB_6 = (PORT_B<<4|6), + PB_7 = (PORT_B<<4|7), + + PC_0 = (PORT_C<<4|0), + PC_1 = (PORT_C<<4|1), + PC_2 = (PORT_C<<4|2), + PC_3 = (PORT_C<<4|3), + PC_4 = (PORT_C<<4|4), + PC_5 = (PORT_C<<4|5), + PC_6 = (PORT_C<<4|6), + PC_7 = (PORT_C<<4|7), + PC_8 = (PORT_C<<4|8), + PC_9 = (PORT_C<<4|9), + + PD_0 = (PORT_D<<4|0), + PD_1 = (PORT_D<<4|1), + PD_2 = (PORT_D<<4|2), + PD_3 = (PORT_D<<4|3), + PD_4 = (PORT_D<<4|4), + PD_5 = (PORT_D<<4|5), + PD_6 = (PORT_D<<4|6), + PD_7 = (PORT_D<<4|7), + PD_8 = (PORT_D<<4|8), + PD_9 = (PORT_D<<4|9), + + PE_0 = (PORT_E<<4|0), + PE_1 = (PORT_E<<4|1), + PE_2 = (PORT_E<<4|2), + PE_3 = (PORT_E<<4|3), + PE_4 = (PORT_E<<4|4), + PE_5 = (PORT_E<<4|5), + PE_6 = (PORT_E<<4|6), + PE_7 = (PORT_E<<4|7), + PE_8 = (PORT_E<<4|8), + PE_9 = (PORT_E<<4|9), + PE_A = (PORT_E<<4|10), + + PF_0 = (PORT_F<<4|0), + PF_1 = (PORT_F<<4|1), + PF_2 = (PORT_F<<4|2), + PF_3 = (PORT_F<<4|3), + PF_4 = (PORT_F<<4|4), + PF_5 = (PORT_F<<4|5), +// PF_6 = (PORT_F<<4|6), +// PF_7 = (PORT_F<<4|7), + + PG_0 = (PORT_G<<4|0), + PG_1 = (PORT_G<<4|1), + PG_2 = (PORT_G<<4|2), + PG_3 = (PORT_G<<4|3), + PG_4 = (PORT_G<<4|4), + PG_5 = (PORT_G<<4|5), + PG_6 = (PORT_G<<4|6), + PG_7 = (PORT_G<<4|7), + + PH_0 = (PORT_H<<4|0), + PH_1 = (PORT_H<<4|1), + PH_2 = (PORT_H<<4|2), + PH_3 = (PORT_H<<4|3), + PH_4 = (PORT_H<<4|4), + PH_5 = (PORT_H<<4|5), + PH_6 = (PORT_H<<4|6), + PH_7 = (PORT_H<<4|7), + + PI_0 = (PORT_I<<4|0), + PI_1 = (PORT_I<<4|1), + PI_2 = (PORT_I<<4|2), + PI_3 = (PORT_I<<4|3), + PI_4 = (PORT_I<<4|4), + PI_5 = (PORT_I<<4|5), + PI_6 = (PORT_I<<4|6), + PI_7 = (PORT_I<<4|7), + + PJ_0 = (PORT_J<<4|0), + PJ_1 = (PORT_J<<4|1), + PJ_2 = (PORT_J<<4|2), + PJ_3 = (PORT_J<<4|3), + PJ_4 = (PORT_J<<4|4), + PJ_5 = (PORT_J<<4|5), + PJ_6 = (PORT_J<<4|6), +// PJ_7 = (PORT_J<<4|7), + + PK_0 = (PORT_K<<4|0), + PK_1 = (PORT_K<<4|1), + PK_2 = (PORT_K<<4|2), + PK_3 = (PORT_K<<4|3), + PK_4 = (PORT_K<<4|4), + PK_5 = (PORT_K<<4|5), + PK_6 = (PORT_K<<4|6), +// PK_7 = (PORT_K<<4|7), + + AD_1 = (PORT_V<<4|1), + AD_2 = (PORT_V<<4|2), + AD_3 = (PORT_V<<4|3), + + DA_0 = (PORT_U<<4|0), + DA_1 = (PORT_U<<4|1), + // Arduino connector namings +/* + A0 = PA_0, + A1 = PA_1, + A2 = PA_4, + A3 = PB_0, + A4 = PC_1, + A5 = PC_0, + D0 = PA_3, + D1 = PA_2, + D2 = PA_10, + D3 = PB_3, + D4 = PB_5, + D5 = PB_4, + D6 = PB_10, + D7 = PA_8, + D8 = PA_9, + D9 = PC_7, + D10 = PB_6, + D11 = PA_7, + D12 = PA_6, + D13 = PA_5, + D14 = PB_9, + D15 = PB_8, + + + // Generic signals namings + LED1 = PB_4, + LED2 = PB_5, + LED3 = PB_6, + LED4 = PB_7, + USER_BUTTON = PA_3, + SERIAL_TX = PA_7, + SERIAL_RX = PA_6, + USBTX = PA_7, + USBRX = PA_6, + I2C_SCL = PC_5, + I2C_SDA = PC_4, + SPI_MOSI = PC_2, + SPI_MISO = PC_3, + SPI_SCK = PC_1, + SPI_CS = PC_0, + PWM_OUT = PD_4, +*/ + // Not connected + NC = (uint32_t)0xFFFFFFFF +} PinName; + +typedef enum { + PullNone = 0, + PullUp = 1, + PullDown = 2, + OpenDrain = 3, + PullDefault = PullNone +} PinMode; + +#define PORT_NUM(pin) (((uint32_t)(pin) >> 4) & 0xF) +#define PIN_NUM(pin) ((uint32_t)(pin) & 0xF) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/PortNames.h b/USDK/component/common/mbed/targets/hal/rtl8195a/PortNames.h new file mode 100644 index 0000000..29a5324 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/PortNames.h @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_PORTNAMES_H +#define MBED_PORTNAMES_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PortA = 0, + PortB = 1, + PortC = 2, + PortD = 3, + PortE = 4, + PortF = 5, + PortG = 6, + PortH = 7, + PortI = 8 +} PortName; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/analogin_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/analogin_api.c new file mode 100644 index 0000000..09b6cf6 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/analogin_api.c @@ -0,0 +1,205 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "objects.h" +#include "PinNames.h" +#include "hal_adc.h" +#include "analogin_api.h" + + + +#if CONFIG_ADC_EN +//#include "cmsis.h" +#include "pinmap.h" + + +extern u32 ConfigDebugErr; +extern u32 ConfigDebuginfo; + + +void analogin_init (analogin_t *obj, PinName pin){ + + uint32_t adc_idx; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_USERCB_ADPT pSalADCUserCBAdpt = NULL; + PSAL_ADC_HND pSalADCHND = NULL; + + HAL_ADC_INIT_DAT HalADCInitDataTmp; + PHAL_ADC_INIT_DAT pHalADCInitDataTmp = &HalADCInitDataTmp; + +// ConfigDebugErr &= (~(_DBG_ADC_|_DBG_GDMA_)); +// ConfigDebugInfo&= (~(_DBG_ADC_|_DBG_GDMA_)); + + adc_idx = pin & 0x0F; + + /* Get I2C device handler */ + pSalADCMngtAdpt = &(obj->SalADCMngtAdpt); + pSalADCUserCBAdpt = (PSAL_ADC_USERCB_ADPT)&(obj->SalADCUserCBAdpt); + + /*To assign the rest pointers*/ + pSalADCMngtAdpt->pSalHndPriv = &(obj->SalADCHndPriv); + pSalADCMngtAdpt->pSalHndPriv->ppSalADCHnd = (void**)&(pSalADCMngtAdpt->pSalHndPriv); + + /* To assign the default (ROM) HAL OP initialization function */ + pSalADCMngtAdpt->pHalOpInit = &HalADCOpInit; + + /* To assign the default (ROM) HAL GDMA OP initialization function */ + pSalADCMngtAdpt->pHalGdmaOpInit = &HalGdmaOpInit; + + /* To assign the default (ROM) SAL interrupt function */ + pSalADCMngtAdpt->pSalIrqFunc = &ADCISRHandle; + + /* To assign the default (ROM) SAL DMA TX interrupt function */ + pSalADCMngtAdpt->pSalDMAIrqFunc = &ADCGDMAISRHandle; + + /* To backup user config first */ + _memcpy(pHalADCInitDataTmp, &(obj->HalADCInitData), sizeof(HAL_ADC_INIT_DAT)); + + + pSalADCMngtAdpt->pHalInitDat = &(obj->HalADCInitData); + pSalADCMngtAdpt->pHalOp = &(obj->HalADCOp); + pSalADCMngtAdpt->pIrqHnd = &(obj->ADCIrqHandleDat); + pSalADCMngtAdpt->pHalGdmaAdp = &(obj->HalADCGdmaAdpt); + pSalADCMngtAdpt->pHalGdmaOp = &(obj->HalADCGdmaOp); + pSalADCMngtAdpt->pIrqGdmaHnd = &(obj->ADCGdmaIrqHandleDat); + pSalADCMngtAdpt->pUserCB = &(obj->SalADCUserCB); + + /* Assign the private SAL handle to public SAL handle */ + pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); + + /* Assign the internal HAL initial data pointer to the SAL handle */ + pSalADCHND->pInitDat = pSalADCMngtAdpt->pHalInitDat; + + /* Assign the internal user callback pointer to the SAL handle */ + pSalADCHND->pUserCB = pSalADCMngtAdpt->pUserCB; + + /*To assign user callback pointers*/ + pSalADCMngtAdpt->pUserCB->pTXCB = pSalADCUserCBAdpt; + pSalADCMngtAdpt->pUserCB->pTXCCB = (pSalADCUserCBAdpt+1); + pSalADCMngtAdpt->pUserCB->pRXCB = (pSalADCUserCBAdpt+2); + pSalADCMngtAdpt->pUserCB->pRXCCB = (pSalADCUserCBAdpt+3); + pSalADCMngtAdpt->pUserCB->pRDREQCB = (pSalADCUserCBAdpt+4); + pSalADCMngtAdpt->pUserCB->pERRCB = (pSalADCUserCBAdpt+5); + pSalADCMngtAdpt->pUserCB->pDMATXCB = (pSalADCUserCBAdpt+6); + pSalADCMngtAdpt->pUserCB->pDMATXCCB = (pSalADCUserCBAdpt+7); + pSalADCMngtAdpt->pUserCB->pDMARXCB = (pSalADCUserCBAdpt+8); + pSalADCMngtAdpt->pUserCB->pDMARXCCB = (pSalADCUserCBAdpt+9); + + /* Set ADC Device Number */ + pSalADCHND->DevNum = adc_idx; + + /* Load ADC default value */ + RtkADCLoadDefault(pSalADCHND); + + /* Assign ADC Pin Mux */ + pSalADCHND->PinMux = 0; + pSalADCHND->OpType = ADC_RDREG_TYPE; + + /* Load user setting */ + if (pHalADCInitDataTmp->ADCEndian != ADC_DATA_ENDIAN_LITTLE){ + pSalADCHND->pInitDat->ADCEndian = pHalADCInitDataTmp->ADCEndian; + } + + if (pHalADCInitDataTmp->ADCAudioEn != ADC_FEATURE_DISABLED){ + pSalADCHND->pInitDat->ADCAudioEn = pHalADCInitDataTmp->ADCAudioEn; + } + + /* Init ADC now */ + pSalADCHND->pInitDat->ADCBurstSz = 8; + pSalADCHND->pInitDat->ADCOneShotTD = 8; + RtkADCInit(pSalADCHND); +} + +float analogin_read(analogin_t *obj){ + float value; + union { + unsigned int ui[2]; + unsigned short us[4]; + } adata; + PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv); + RtkADCReceiveBuf(p, &adata.ui); + return (float)(adata.us[p->DevNum]) / (float)(0xCE80); +/* + uint32_t AnaloginTmp[2] = {0,0}; + uint32_t AnaloginDatMsk = 0xFFFF; + uint8_t AnaloginIdx = 0; + uint32_t AnalogDat = 0; + + uint32_t AnalogDatFull = 0; + + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_HND pSalADCHND = NULL; + + pSalADCMngtAdpt = &(obj->SalADCMngtAdpt); + pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); + AnaloginIdx = pSalADCHND->DevNum; + RtkADCReceiveBuf(pSalADCHND,&AnaloginTmp[0]); + + AnaloginDatMsk = (u32)(AnaloginDatMsk<<((u32)(16*(AnaloginIdx&0x01)))); + AnalogDat = AnaloginTmp[(AnaloginIdx/2)]; + AnalogDat = (AnalogDat & AnaloginDatMsk); + AnalogDat = (AnalogDat>>((u32)(16*(AnaloginIdx&0x01)))); + + AnalogDatFull = 0xCE80; + + value = (float)(AnalogDat) / (float)(AnalogDatFull); + + return (float)value; +*/ +} + +uint16_t analogin_read_u16(analogin_t *obj){ + union { + unsigned int ui[2]; + unsigned short us[4]; + } adata; + PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv); + RtkADCRxManualRotate(p, &adata.ui); + return adata.us[p->DevNum]; +/* + uint32_t AnaloginTmp[2] = {0,0}; + uint32_t AnaloginDatMsk = 0xFFFF; + uint8_t AnaloginIdx = 0; + uint32_t AnalogDat = 0; + + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_HND pSalADCHND = NULL; + + pSalADCMngtAdpt = &(obj->SalADCMngtAdpt); + pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); + AnaloginIdx = pSalADCHND->DevNum; + RtkADCRxManualRotate(pSalADCHND,&AnaloginTmp[0]); + + + //DBG_8195A("[0]:%08x, %08x\n", AnaloginTmp[0], AnaloginTmp[1] ); + AnaloginDatMsk = (u32)(AnaloginDatMsk<<((u32)(16*(AnaloginIdx&0x01)))); + AnalogDat = AnaloginTmp[(AnaloginIdx/2)]; + AnalogDat = (AnalogDat & AnaloginDatMsk); + AnalogDat = (AnalogDat>>((u32)(16*(AnaloginIdx&0x01)))); + return (uint16_t)AnalogDat; +*/ + +} + + +void analogin_deinit(analogin_t *obj){ +/* + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_HND pSalADCHND = NULL; + + pSalADCMngtAdpt = &(obj->SalADCMngtAdpt); + p = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); */ + + PSAL_ADC_HND p = &((&(obj->SalADCMngtAdpt))->pSalHndPriv->SalADCHndPriv); + + /* To deinit analogin */ + RtkADCDeInit(p); +} +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/device.h b/USDK/component/common/mbed/targets/hal/rtl8195a/device.h new file mode 100644 index 0000000..2034d0b --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/device.h @@ -0,0 +1,48 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_DEVICE_H +#define MBED_DEVICE_H + +#define DEVICE_PORTIN 1 +#define DEVICE_PORTOUT 1 +#define DEVICE_PORTINOUT 1 + +#define DEVICE_INTERRUPTIN 1 + +#define DEVICE_ANALOGIN 1 +#define DEVICE_ANALOGOUT 1 + +#define DEVICE_SERIAL 1 + +#define DEVICE_I2C 1 +#define DEVICE_I2CSLAVE 1 + +#define DEVICE_SPI 1 +#define DEVICE_SPISLAVE 1 + +#define DEVICE_CAN 0 + +#define DEVICE_RTC 1 + +#define DEVICE_ETHERNET 1 + +#define DEVICE_PWMOUT 1 + +#define DEVICE_SLEEP 1 + +#include "objects.h" + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/dma_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/dma_api.c new file mode 100644 index 0000000..4446ccb --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/dma_api.c @@ -0,0 +1,89 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "dma_api.h" +#include "cmsis.h" + +extern BOOL HalGdmaMemCpyInit(PHAL_GDMA_OBJ pHalGdmaObj); +extern VOID HalGdmaMemCpyDeInit(PHAL_GDMA_OBJ pHalGdmaObj); +extern VOID* HalGdmaMemCpy(PHAL_GDMA_OBJ pHalGdmaObj, void* pDest, void* pSrc, u32 len); +extern VOID HalGdmaMemAggr(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock); +extern BOOL HalGdmaMemCpyAggrInit(PHAL_GDMA_OBJ pHalGdmaObj); + +/** + * @brief Initial the GDMA + * + * @param dma_obj: the GDMA object + * handler: the callback function for a DMA transfer complete. + * id: the argument of the callback function. + * @return None + * + */ +void dma_memcpy_aggr_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id) +{ + dma_obj->gdma_obj.GdmaIrqHandle.IrqFun = (IRQ_FUN)handler; + dma_obj->gdma_obj.GdmaIrqHandle.Data = (u32)id; + dma_obj->gdma_allocated = HalGdmaMemCpyAggrInit(&(dma_obj->gdma_obj)); +} + + +void dma_memcpy_init(gdma_t *dma_obj, dma_irq_handler handler, uint32_t id) +{ + dma_obj->gdma_obj.GdmaIrqHandle.IrqFun = (IRQ_FUN)handler; + dma_obj->gdma_obj.GdmaIrqHandle.Data = (u32)id; + dma_obj->gdma_allocated = HalGdmaMemCpyInit(&(dma_obj->gdma_obj)); +} + +/** + * @brief De-Initial the GDMA + * + * @param dma_obj: the GDMA object + * @return None + * + */ +void dma_memcpy_deinit(gdma_t *dma_obj) +{ + if (dma_obj->gdma_allocated) { + HalGdmaMemCpyDeInit(&(dma_obj->gdma_obj)); + } +} + +/** + * @brief To do a memory copy by DMA + * + * @param None + * @return None + * + */ +void dma_memcpy(gdma_t *dma_obj, void *dst, void* src, uint32_t len) +{ +#if 0 + if (!dma_obj->gdma_allocated) { + dma_irq_handler handler; + + _memcpy(dst, src, len); + handler = dma_obj->GdmaIrqHandle.IrqFun; + handler(dma_obj->GdmaIrqHandle.Data); + } +#endif + HalGdmaMemCpy(&(dma_obj->gdma_obj), dst, src, len); +} + +void dma_memcpy_aggr(gdma_t *dma_obj, PHAL_GDMA_BLOCK block_info) +{ + HalGdmaMemAggr(&(dma_obj->gdma_obj), block_info); +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/efuse_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/efuse_api.c new file mode 100644 index 0000000..f2345ae --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/efuse_api.c @@ -0,0 +1,155 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "rtl8195a.h" + +#ifdef CONFIG_EFUSE_EN +/* in hal_efuse.h +extern VOID ReadEfuseContant1(OUT u8 *pContant); +extern u8 WriteEfuseContant1(IN u8 CodeWordNum, IN u8 WordEnable, IN u8 *pContant); +extern VOID ReadEOTPContant(OUT u8 *pContant); +extern VOID WriteEOTPContant(IN u8 *pContant); +extern u8 GetRemainingEfuseLength(void); +extern VOID HALJtagOff(VOID); +*/ + +/** + * @brief get remaining efuse length + * @retval remaining efuse length + */ +int efuse_get_remaining_length(void) +{ + return GetRemainingEfuseLength(); +} + + +/** + * @brief Read efuse contant of specified user + * @param data: Specified the address to save the readback data. + */ +void efuse_mtp_read(uint8_t * data) +{ + ReadEfuseContant1(data); + return; +} + +/** + * @brief Write user's contant to efuse + * @param *data: Specified the data to be programmed. + * @param len: Specifies the data length of programmed data. + * @retval status: Success:0~32 or Failure: -1. + */ +int efuse_mtp_write(uint8_t *data, uint8_t len) +{ + + u8 len_low, len_high, word_enable = 0; + + if( (len & 0x01) == 1) + len += 1; + + if(len > 32){ + return -1; + } + if(len == 0){ + return 0; + } + + len_low = len & 0x07; + len_high = (len >> 3) & 0x07; + + if(len_low == 0) + word_enable = 0; + else if(len_low == 2) + word_enable = 1; + else if(len_low == 4) + word_enable = 3; + else if(len_low == 6) + word_enable = 7; + + switch (len_high){ + case 0: + WriteEfuseContant1(0, word_enable, data); + break; + + case 1: + WriteEfuseContant1(0, 0xf, data); + WriteEfuseContant1(1, word_enable, data+8); + break; + + case 2: + WriteEfuseContant1(0, 0xf, data); + WriteEfuseContant1(1, 0xf, data+8); + WriteEfuseContant1(2, word_enable, data+8); + break; + + case 3: + WriteEfuseContant1(0, 0xf, data); + WriteEfuseContant1(1, 0xf, data+8); + WriteEfuseContant1(2, 0xf, data+16); + WriteEfuseContant1(3, word_enable, data+24); + break; + + case 4: + WriteEfuseContant1(0, 0xf, data); + WriteEfuseContant1(1, 0xf, data+8); + WriteEfuseContant1(2, 0xf, data+16); + WriteEfuseContant1(3, 0xf, data+24); + } + return len; +} + + +/** + * @brief Read efuse OTP contant + * @param address: Specifies the offset of the OTP. + * @param len: Specifies the length of readback data. + * @param buf: Specified the address to save the readback data. + */ +int efuse_otp_read(u8 address, u8 len, u8 *buf) +{ + u8 content[32]; // the OTP max length is 32 + + if((address+len) > 32) + return -1; + ReadEOTPContant(content); + _memcpy(buf, content+address, len); + return 0; +} + + +/** + * @brief Write user's contant to OTP efuse + * @param address: Specifies the offset of the programmed OTP. + * @param len: Specifies the data length of programmed data. + * @param *buf: Specified the data to be programmed. + * @retval status: Success:0 or Failure: -1. + */ +int efuse_otp_write(u8 address, u8 len, u8 *buf) +{ + u8 content[32]; // the OTP max length is 32 + + if((address+len) > 32) + return -1; + _memset(content, 0xFF, 32); + _memcpy(content+address, buf, len); + WriteEOTPContant(content); + return 0; +} + + +/** + * @brief Disable jtag + */ +int efuse_disable_jtag(void) +{ + HALJtagOff(); + return 0; +} +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/ethernet_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/ethernet_api.c new file mode 100644 index 0000000..18bf0fc --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/ethernet_api.c @@ -0,0 +1,104 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "ethernet_api.h" +#include "ethernet_ex_api.h" +#include "hal_mii.h" + +#if DEVICE_ETHERNET + +#if CONFIG_MII_EN + +extern HAL_ETHER_ADAPTER HalEtherAdp; + + + +void ethernet_irq_hook(ethernet_callback callback) +{ + HalEtherAdp.CallBack = callback; +} + + +void ethernet_set_descnum(uint8_t txdescCnt, uint8_t rxdescCnt) +{ + HalEtherAdp.tx_desc_num = txdescCnt; + HalEtherAdp.rx_desc_num = rxdescCnt; +} + +void ethernet_trx_pre_setting(uint8_t *TxDescAddr, uint8_t *RxDescAddr, uint8_t *pTxPktBuf, uint8_t *pRxPktBuf) +{ + HalEtherAdp.TxDescAddr = TxDescAddr; + HalEtherAdp.RxDescAddr = RxDescAddr; + HalEtherAdp.pTxPktBuf = pTxPktBuf; + HalEtherAdp.pRxPktBuf = pRxPktBuf; +} + + +int ethernet_init(void) +{ + return HalMiiInit(); +} + + +void ethernet_free(void) +{ + HalMiiDeInit(); +} + + +int ethernet_write(const char *data, int size) +{ + return HalMiiWriteData(data, size); +} + + +int ethernet_send(void) +{ + return HalMiiSendPacket(); +} + + +int ethernet_receive(void) +{ + return HalMiiReceivePacket(); +} + + +int ethernet_read(char *data, int size) +{ + return HalMiiReadData((u8*)data, size); +} + + +void ethernet_address(char *mac) +{ + HalMiiGetMacAddress((u8*)mac); +} + + +int ethernet_link(void) +{ + int ret; + + + ret = HalMiiGetLinkStatus(); + + return ret; +} + + +void ethernet_set_link(int speed, int duplex) +{ + HalMiiForceLink(speed, duplex); +} + +#endif // #if CONFIG_MII_EN +#endif // #if DEVICE_ETHERNET + diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/flash_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/flash_api.c new file mode 100644 index 0000000..6a8d455 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/flash_api.c @@ -0,0 +1,635 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "objects.h" +#include "PinNames.h" + +#include "pinmap.h" + +#include "rtl8195a.h" +#include "hal_spi_flash.h" +#include "hal_platform.h" +#include "rtl8195a_spi_flash.h" +#include "hal_api.h" +#include "flash_api.h" + +extern u32 ConfigDebugInfo; +extern SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // SpicMaxMode = 3, CPU_CLK_TYPE_NO = 6 ! + +_LONG_CALL_ +extern VOID SpicWaitBusyDoneRtl8195A(VOID); + +bool fspic_isinit = 0; +flash_t flashobj; + +/** + * global data structure + */ +//flash_t flash; +/** + * @brief Control the flash chip write protect enable/disable + * @param protect: 1/0: protect/unprotect + * @retval none + */ +void flash_write_protect(flash_t *obj, uint32_t protect) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + SpicWriteProtectFlashRtl8195A(protect); + SpicDisableRtl8195A(); +} + +/** + * @brief Init Flash + * @param obj: address of the flash object + * @retval none + */ +void flash_init(flash_t *obj) { + //SPIC_INIT_PARA spic_init_para; + + // Init SPI Flash Controller +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("Initial Spi Flash Controller\n"); +#endif + u8 flmode; + SPI_FLASH_PIN_FCTRL(ON); +#if 0 + if (SpicFlashInitRtl8195A(SpicQuadBitMode)) { + flmode = SpicQuadBitMode; + fspic_isinit = 1; + } + else +#endif + if (SpicFlashInitRtl8195A(SpicDualBitMode)) { // SpicFlashInitRtl8195A(SpicQuadBitMode) + flmode = SpicDualBitMode; + fspic_isinit = 1; + } else if (SpicFlashInitRtl8195A(SpicOneBitMode)) { + flmode = SpicOneBitMode; + fspic_isinit = 1; + } else { + DBG_8195A("SPI Init Fail!\n"); // DBG_SPIF_ERR? + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3) | 0xf); +// flmode = SpicOneBitMode; + return; + } + u8 curclk = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) + >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; + flashobj.SpicInitPara = SpicInitParaAllClk[flmode][curclk]; + flashobj.SpicInitPara.Mode.CpuClk = curclk; + flashobj.SpicInitPara.Mode.BitMode = flmode; + +#if CONFIG_DEBUG_LOG > 3 + DBG_SPIF_INFO("Flash ID: %02x%02x%02x\n", flashobj.SpicInitPara.id[0], flashobj.SpicInitPara.id[1], flashobj.SpicInitPara.id[2]); + DBG_SPIF_INFO("Flash Mode: 0x%02x; BaudRate:%d; RdDummyCyle:%d; DelayLine:%d\n", + flashobj.SpicInitPara.Mode.BitMode, flashobj.SpicInitPara.BaudRate, flashobj.SpicInitPara.RdDummyCyle, flashobj.SpicInitPara.DelayLine); + DBG_SPIF_INFO("Flash Size: %d bytes\n", flash_get_size(obj)); +#endif +} + +void flash_turnon(void) { + SPI_FLASH_PIN_FCTRL(ON); + SpicWaitBusyDoneRtl8195A(); +} + +/** + * @brief Erase flash sector + * @param address: Specifies the starting address to be erased. + * @retval none + */ +void flash_erase_sector(flash_t *obj, uint32_t address) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); + SpicDisableRtl8195A(); +} + +void flash_erase_block(flash_t *obj, uint32_t address) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); + SpicDisableRtl8195A(); +} + +/** + * @brief Read a word from specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be read. + * @param data: Specified the address to save the readback data. + * @retval status: Success:1 or Failure: Others. + */ +int flash_read_word(flash_t *obj, uint32_t address, uint32_t * data) { + + flash_turnon(); + if (fspic_isinit == 0) + flash_init(&flashobj); + // Wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + *data = HAL_READ32(SPI_FLASH_BASE, address); + SpicDisableRtl8195A(); + + return 1; +} + +/** + * @brief Write a word to specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be programmed. + * @param data: Specified the data to be programmed. + * @retval status: Success:1 or Failure: Others. + */ +int flash_write_word(flash_t *obj, uint32_t address, uint32_t data) { + u8 flashtype = 0; + + flash_turnon(); + if (fspic_isinit == 0) + flash_init(&flashobj); + + flashtype = flashobj.SpicInitPara.flashtype; + + //Write word + HAL_WRITE32(SPI_FLASH_BASE, address, data); + + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + SpicDisableRtl8195A(); + return 1; +} + +/** + * @brief Read a stream of data from specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be read. + * @param len: Specifies the length of the data to read. + * @param data: Specified the address to save the readback data. + * @retval status: Success:1 or Failure: Others. + */ +int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len, + uint8_t * data) { + u32 offset_to_align; + u32 i; + u32 read_word; + uint8_t *ptr; + uint8_t *pbuf; + + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + // Wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + offset_to_align = address & 0x03; + pbuf = data; + if (offset_to_align != 0) { + // the start address is not 4-bytes aligned + read_word = HAL_READ32(SPI_FLASH_BASE, (address - offset_to_align)); + ptr = (uint8_t*) &read_word + offset_to_align; + offset_to_align = 4 - offset_to_align; + for (i = 0; i < offset_to_align; i++) { + *pbuf = *(ptr + i); + pbuf++; + len--; + if (len == 0) { + break; + } + } + } + + address = (((address - 1) >> 2) + 1) << 2; // address = next 4-bytes aligned + + ptr = (uint8_t*) &read_word; + if ((u32) pbuf & 0x03) { + while (len >= 4) { + read_word = HAL_READ32(SPI_FLASH_BASE, address); + for (i = 0; i < 4; i++) { + *pbuf = *(ptr + i); + pbuf++; + } + address += 4; + len -= 4; + } + } else { + while (len >= 4) { + *((u32 *) pbuf) = HAL_READ32(SPI_FLASH_BASE, address); + pbuf += 4; + address += 4; + len -= 4; + } + } + + if (len > 0) { + read_word = HAL_READ32(SPI_FLASH_BASE, address); + for (i = 0; i < len; i++) { + *pbuf = *(ptr + i); + pbuf++; + } + } + + SpicDisableRtl8195A(); + return 1; +} + +/** + * @brief Write a stream of data to specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be read. + * @param len: Specifies the length of the data to write. + * @param data: Specified the pointer of the data to be written. + * @retval status: Success:1 or Failure: Others. + */ +int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, + uint8_t * data) { + u32 offset_to_align; + u32 align_addr; + u32 i; + u32 write_word; + uint8_t *ptr; + uint8_t *pbuf; + u8 flashtype = 0; + + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + flashtype = flashobj.SpicInitPara.flashtype; + offset_to_align = address & 0x03; + pbuf = data; + if (offset_to_align != 0) { + // the start address is not 4-bytes aligned + align_addr = (address - offset_to_align); + write_word = HAL_READ32(SPI_FLASH_BASE, align_addr); + ptr = (uint8_t*) &write_word + offset_to_align; + offset_to_align = 4 - offset_to_align; + for (i = 0; i < offset_to_align; i++) { + *(ptr + i) = *pbuf; + pbuf++; + len--; + if (len == 0) { + break; + } + } + //Write word + HAL_WRITE32(SPI_FLASH_BASE, align_addr, write_word); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + } + + address = (((address - 1) >> 2) + 1) << 2; // address = next 4-bytes aligned + + if ((u32) pbuf & 0x03) { + while (len >= 4) { + write_word = (u32) (*pbuf) | ((u32) (*(pbuf + 1)) << 8) + | ((u32) (*(pbuf + 2)) << 16) | ((u32) (*(pbuf + 3)) << 24); + //Write word + HAL_WRITE32(SPI_FLASH_BASE, address, write_word); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + pbuf += 4; + address += 4; + len -= 4; + } + } else { + while (len >= 4) { + //Write word + HAL_WRITE32(SPI_FLASH_BASE, address, (u32)*((u32 *)pbuf)); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + pbuf += 4; + address += 4; + len -= 4; + } + } + + if (len > 0) { + write_word = HAL_READ32(SPI_FLASH_BASE, address); + ptr = (uint8_t*) &write_word; + for (i = 0; i < len; i++) { + *(ptr + i) = *pbuf; + pbuf++; + } + //Write word + HAL_WRITE32(SPI_FLASH_BASE, address, write_word); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + } + + SpicDisableRtl8195A(); + return 1; +} + +/* + Function Description: + This function performans the same functionality as the function flash_stream_write. + It enhances write performance by reducing overheads. + Users can use either of functions depending on their needs. + + * @brief Write a stream of data to specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be read. + * @param Length: Specifies the length of the data to write. + * @param data: Specified the pointer of the data to be written. + * @retval status: Success:1 or Failure: Others. + + */ + +int flash_burst_write(flash_t *obj, uint32_t address, uint32_t Length, + uint8_t * data) { + + u32 OccuSize; + u32 ProgramSize; + u32 PageSize; + u8 flashtype = 0; + + PageSize = 256; + + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + flashtype = flashobj.SpicInitPara.flashtype; + + OccuSize = address & 0xFF; + if ((Length >= PageSize) || ((Length + OccuSize) >= PageSize)) + ProgramSize = PageSize - OccuSize; + else + ProgramSize = Length; + + flashobj.Length = Length; + while (Length > 0) { + if (OccuSize) { + SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, + &(flashobj.Length)); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + address += ProgramSize; + data += ProgramSize; + Length -= ProgramSize; + OccuSize = 0; + } else { + while ((flashobj.Length) >= PageSize) { + SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, + &(flashobj.Length)); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + address += PageSize; + data += PageSize; + Length -= PageSize; + } + flashobj.Length = Length; + if ((flashobj.Length) > 0) { + SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, + &(flashobj.Length)); + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // Wait flash busy done (wip=0) + if (flashtype == FLASH_MICRON) { + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + } else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + + break; + } + } + flashobj.Length = Length; + } + + SpicDisableRtl8195A(); + return 1; + +} +/** + * @brief Read a stream of data from specified address + * @param obj: Specifies the parameter of flash object. + * @param address: Specifies the address to be read. + * @param len: Specifies the length of the data to read. + * @param data: Specified the address to save the readback data. + * @retval status: Success:1 or Failure: Others. + */ + +int flash_burst_read(flash_t *obj, uint32_t address, uint32_t Length, + uint8_t * data) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + // Wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + SpicUserReadRtl8195A(Length, address, data, + flashobj.SpicInitPara.Mode.BitMode); + SpicDisableRtl8195A(); + return 1; +} + +int flash_get_status(flash_t *obj) { + u8 Status = 0; + + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + Status = SpicGetFlashStatusRefinedRtl8195A(flashobj.SpicInitPara); + + SpicDisableRtl8195A(); + return Status; +} + +/* + Function Description: + Please refer to the datatsheet of flash for more details of the content of status register. + The block protected area and the corresponding control bits are provided in the flash datasheet. + + * @brief Set Status register to enable desired operation + * @param obj: Specifies the parameter of flash object. + * @param data: Specifies which bit users like to set + ex: if users want to set the third bit, data = 0x8. + + */ +int flash_set_status(flash_t *obj, uint32_t data) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara); + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + DBG_8195A("Status Register After Setting= %x\n", + flash_get_status(&flashobj)); + SpicDisableRtl8195A(); + return 1; +} + +/* + Function Description: + This function aims to reset the status register, please make sure the operation is appropriate. + */ +void flash_reset_status(flash_t *obj) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + SpicSetFlashStatusRefinedRtl8195A(0, flashobj.SpicInitPara); + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + SpicDisableRtl8195A(); +} +/* + Function Description: + This function is only for Micron 512Mbit flash to access beyond 128Mbit by switching between four 128 Mbit area. + Please refer to flash datasheet for more information about memory mapping. + */ + +int flash_set_extend_addr(flash_t *obj, uint32_t data) { + flash_turnon(); + + if (fspic_isinit == 0) + flash_init(&flashobj); + + SpicSetExtendAddrRtl8195A(data, flashobj.SpicInitPara); + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + DBG_8195A("Extended Address Register After Setting = %x\n", + flash_get_extend_addr(&flashobj)); + SpicDisableRtl8195A(); + return 1; +} + +int flash_get_extend_addr(flash_t *obj) { + u8 Status = 0; + + flash_turnon(); + if (fspic_isinit == 0) + flash_init(&flashobj); + Status = SpicGetExtendAddrRtl8195A(flashobj.SpicInitPara); + + SpicDisableRtl8195A(); + return Status; + +} + +/* + * Return Flash size in bytes + * = 0 - unknown flash + */ +unsigned int flash_get_size(flash_t *obj) { + unsigned int flashchip_size = 0; + if (fspic_isinit == 0) { + flash_turnon(); + flash_init(&flashobj); + SpicDisableRtl8195A(); + if (fspic_isinit == 0) + return flashchip_size; + } + if (flashobj.SpicInitPara.id[2] > 0x11 + && flashobj.SpicInitPara.id[2] < 0x20) { + flashchip_size = 1 << (flashobj.SpicInitPara.id[2]); // Flash size in bytes + } else + flashchip_size = 1024 * 1024; // default 1 mbytes? + return flashchip_size; +} + +/* + * Read Flash OTP data + */ +int flash_otp_read(flash_t *obj, uint32_t address, uint32_t Length, + uint8_t * data) { + int ret = 1; + flash_turnon(); + if (fspic_isinit == 0) + flash_init(&flashobj); + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + switch (flashobj.SpicInitPara.flashtype) { + case FLASH_MXIC_4IO: + case FLASH_MXIC: // Only 512 bits +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("MXIC: Only 512 bits!\n"); +#endif + SpicTxCmdWithDataRtl8195A(FLASH_CMD_ENSO, 0, 0, flashobj.SpicInitPara); // enter secured OTP + SpicUserReadRtl8195A(Length, address, data, + flashobj.SpicInitPara.Mode.BitMode); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_EXSO, 0, 0, flashobj.SpicInitPara); // exit secured OTP + break; + case FLASH_EON: // OTP sector is mapping to sector 1023 +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("EON: OTP sector is mapping to sector 1023!\n"); +#endif + SpicTxCmdWithDataRtl8195A(FLASH_CMD_EOTPM, 0, 0, flashobj.SpicInitPara); // enter secured OTP + SpicUserReadRtl8195A(Length, address, data, + flashobj.SpicInitPara.Mode.BitMode); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_WRDI, 0, 0, flashobj.SpicInitPara); // exit secured OTP + break; + case FLASH_MICRON: // (4Bh) READ OTP ARRAY +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("MICRON: @TODO !\n"); +#endif + // FLASH_CMD_ROTPA + ret = 0; + break; + default: + DBG_8195A("Flash type?"); + ret = 0; + } + SpicDisableRtl8195A(); + return ret; +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/flash_eep.c b/USDK/component/common/mbed/targets/hal/rtl8195a/flash_eep.c new file mode 100644 index 0000000..2342fd1 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/flash_eep.c @@ -0,0 +1,521 @@ +/* + * flash_eep.c + * + * Created on: 19/01/2015 + * Port RTL87xx: 15/10/16 + * Author: pvvx + */ + +#include +//#include +//#include +#include +#include +#include "device_lock.h" +#include "flash_api.h" +#include "flash_eep.h" + +//----------------------------------------------------------------------------- +#ifdef CONFIG_DEBUG_LOG +#define DEBUGSOO CONFIG_DEBUG_LOG +#else +#define DEBUGSOO 0 +#endif + +#define mMIN(a, b) ((a < b)? a : b) +#define align(a) ((a + 3) & 0xFFFFFFFC) + +typedef union // заголовок объекта сохранения feep +{ + struct { + unsigned short size; + unsigned short id; + } __attribute__((packed)) n; + unsigned int x; +} __attribute__((packed)) fobj_head; + +#define fobj_head_size 4 +#define fobj_x_free 0xffffffff +#define MAX_FOBJ_SIZE 512 // максимальный размер сохраняемых объeктов +#define FMEM_ERROR_MAX 5 +//----------------------------------------------------------------------------- +flash_t flash; +//QueueHandle_t flash_mutex; +//----------------------------------------------------------------------------- + + +/*------------------------------------------------------------------------------------- + Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) +--------------------------------------------------------------------------------------*/ +void FLASH_EEP_ATTR copy_align4_to_align1(unsigned char * pd, void * ps, unsigned int len) +{ + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; + unsigned int *p = (unsigned int *)((unsigned int)ps & (~3)); + unsigned int xlen = (unsigned int)ps & 3; + // unsigned int size = len; + + if(xlen) { + tmp.ud = *p++; + while (len) { + len--; + *pd++ = tmp.uc[xlen++]; + if(xlen & 4) break; + } + } + xlen = len >> 2; + while(xlen) { + tmp.ud = *p++; + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + } + if(len & 3) { + tmp.ud = *p; + pd[0] = tmp.uc[0]; + if(len & 2) { + pd[1] = tmp.uc[1]; + if(len & 1) { + pd[2] = tmp.uc[2]; + } + } + } + // return size; +} +/*------------------------------------------------------------------------------------ + Копирует данные из области align(1) (ram) в область align(4) (flash, registers) +--------------------------------------------------------------------------------------*/ +void FLASH_EEP_ATTR copy_align1_to_align4(void * pd, unsigned char * ps, unsigned int len) +{ + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; + unsigned int *p = (unsigned int *)(((unsigned int)pd) & (~3)); + unsigned int xlen = (unsigned int)pd & 3; +// unsigned int size = len; + if(xlen) { + tmp.ud = *p; + while (len) { + len--; + tmp.uc[xlen++] = *ps++; + if(xlen & 4) break; + } + *p++ = tmp.ud; + } + xlen = len >> 2; + while(xlen) { + tmp.uc[0] = *ps++; + tmp.uc[1] = *ps++; + tmp.uc[2] = *ps++; + tmp.uc[3] = *ps++; + *p++ = tmp.ud; + xlen--; + } + if(len & 3) { + tmp.ud = *p; + tmp.uc[0] = ps[0]; + if(len & 2) { + tmp.uc[1] = ps[1]; + if(len & 1) { + tmp.uc[2] = ps[2]; + } + } + *p = tmp.ud; + } +// return size; +} +/*------------------------------------------------------------------------------------ + Запись байта в область align(4) (flash, registers) +--------------------------------------------------------------------------------------*/ +void FLASH_EEP_ATTR write_align4_chr(unsigned char *pd, unsigned char c) +{ + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; + unsigned int *p = (unsigned int *)((unsigned int)pd & (~3)); + unsigned int xlen = (unsigned int)pd & 3; + tmp.ud = *p; + tmp.uc[xlen] = c; + *p = tmp.ud; +} +/*------------------------------------------------------------------------------------ + Чтение байта из области align(4) (flash, registers) +--------------------------------------------------------------------------------------*/ +unsigned char FLASH_EEP_ATTR get_align4_chr(const unsigned char *ps) +{ + return (*((unsigned int *)((unsigned int)ps & (~3))))>>(((unsigned int)ps & 3) << 3); +} +/*------------------------------------------------------------------------------------ + Сравнение данных в области align(4) (flash, registers, ...) с областью align(1) (ram) +--------------------------------------------------------------------------------------*/ +int FLASH_EEP_ATTR cmp_align1_align4(unsigned char * pd, void * ps, unsigned int len) +{ + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; + unsigned int *p = (unsigned int *)((unsigned int)ps & (~3)); + unsigned int xlen = (unsigned int)ps & 3; + if(xlen) { + tmp.ud = *p++; + while (len) { + len--; + if(*pd++ != tmp.uc[xlen++]) return 1; + if(xlen & 4) break; + } + } + xlen = len >> 2; + while(xlen) { + tmp.uc[0] = *pd++; + tmp.uc[1] = *pd++; + tmp.uc[2] = *pd++; + tmp.uc[3] = *pd++; + if(*p++ != tmp.ud) return 1; + xlen--; + } + if(len & 3) { + tmp.ud = *p; + if(pd[0] != tmp.uc[0]) return 1; + if(len & 2) { + if(pd[1] != tmp.uc[1]) return 1; + if(len & 1) { + if(pd[2] != tmp.uc[2]) return 1; + } + } + } + return 0; +} + +//----------------------------------------------------------------------------- +LOCAL void _fwrite_word(unsigned int addr, unsigned int dw) +{ + //Write word + HAL_WRITE32(SPI_FLASH_BASE, addr, dw); + + // Wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + // Wait flash busy done (wip=0) + if(flashobj.SpicInitPara.flashtype == FLASH_MICRON) + SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); + else + SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); +} +//----------------------------------------------------------------------------- +// FunctionName : get_addr_bscfg +// Опции: +// false - поиск текушего сегмента +// true - поиск нового сегмента для записи (pack) +// Returns : новый адрес сегмента для записи +// ret < FMEM_ERROR_MAX - ошибка +//----------------------------------------------------------------------------- +LOCAL FLASH_EEP_ATTR unsigned int get_addr_bscfg(bool flg) +{ + unsigned int x1 = (flg)? 0 : 0xFFFFFFFF, x2; + unsigned int faddr = FMEMORY_SCFG_BASE_ADDR; + unsigned int reta = FMEMORY_SCFG_BASE_ADDR; + do { + x2 = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &x2, 4)) return -(FMEM_FLASH_ERR); + if(flg) { // поиск нового сегмента для записи (pack) + if(x2 > x1 || x2 == 0xFFFFFFFF) { + x1 = x2; + reta = faddr; // новый адрес сегмента для записи + } + } + else if(x2 < x1) { // поиск текушего сегмента + x1 = x2; + reta = faddr; // новый адрес сегмента для записи + }; + faddr += FMEMORY_SCFG_BANK_SIZE; + } while(faddr < (FMEMORY_SCFG_BASE_ADDR + FMEMORY_SCFG_BANKS * FMEMORY_SCFG_BANK_SIZE)); + + if((!flg)&&(x1 == 0xFFFFFFFF)&&(reta == FMEMORY_SCFG_BASE_ADDR)) { + _fwrite_word(reta, --x1); // if(flash_write(reta, &x1, 4)) return -(FMEM_FLASH_ERR); + } +#if DEBUGSOO > 3 + DBG_FEEP_INFO("base seg: %p [%d]\n", reta, x2); +#endif + return reta; +} +//----------------------------------------------------------------------------- +// FunctionName : get_addr_fobj +// Опции: +// false - Поиск последней записи объекта по id и size +// true - Поиск присуствия записи объекта по id и size +// Returns : адрес записи данных объекта +// 0 - не найден +// ret < FMEM_ERROR_MAX - ошибка +//----------------------------------------------------------------------------- +LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj(unsigned int base, fobj_head *obj, bool flg) +{ +// if(base == 0) return 0; + fobj_head fobj; + unsigned int faddr = base + 4; + unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size); + unsigned int reta = 0; + do { + fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); + if(fobj.x == fobj_x_free) break; + if(fobj.n.size <= MAX_FOBJ_SIZE) { + if(fobj.n.id == obj->n.id) { + if(flg) { + return faddr; + } + obj->n.size = fobj.n.size; + reta = faddr; + } + faddr += align(fobj.n.size + fobj_head_size); + } + else faddr += align(MAX_FOBJ_SIZE + fobj_head_size); + } + while(faddr < fend); + return reta; +} +//----------------------------------------------------------------------------- +// FunctionName : get_addr_fend +// Поиск последнего адреса в сегменте для записи объекта +// Returns : адрес для записи объекта +// ret < FMEM_ERROR_MAX - ошибка +// ret = 0 - не влезет, на pack +//----------------------------------------------------------------------------- +LOCAL FLASH_EEP_ATTR unsigned int get_addr_fobj_save(unsigned int base, fobj_head obj) +{ + fobj_head fobj; + unsigned int faddr = base + 4; + unsigned int fend = base + FMEMORY_SCFG_BANK_SIZE - align(obj.n.size + fobj_head_size); + do { + fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); // if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); + if(fobj.x == fobj_x_free) { + if(faddr < fend) { + return faddr; + } + return 0; // не влезет, на pack + } + if(fobj.n.size <= MAX_FOBJ_SIZE) { + faddr += align(fobj.n.size + fobj_head_size); + } + else faddr += align(MAX_FOBJ_SIZE + fobj_head_size); + } + while(faddr < fend); + return 0; // не влезет, на pack +} +//============================================================================= +// FunctionName : pack_cfg_fmem +// Returns : адрес для записи объекта +//----------------------------------------------------------------------------- +LOCAL FLASH_EEP_ATTR unsigned int pack_cfg_fmem(fobj_head obj) +{ + fobj_head fobj; + unsigned int fnewseg = get_addr_bscfg(true); // поиск нового сегмента для записи (pack) + if(fnewseg < FMEM_ERROR_MAX) return fnewseg; // error + unsigned int foldseg = get_addr_bscfg(false); // поиск текушего сегмента + if(foldseg < FMEM_ERROR_MAX) return fnewseg; // error + unsigned int faddr = foldseg; + unsigned int rdaddr, wraddr; + unsigned short len; + unsigned int * pbuf = (unsigned int *) malloc(align(MAX_FOBJ_SIZE + fobj_head_size) >> 2); + if(pbuf == NULL) { +#if DEBUGSOO > 1 + DBG_FEEP_ERR("pack malloc error!\n"); +#endif + return -(FMEM_MEM_ERR); + } +#if DEBUGSOO > 3 + DBG_FEEP_INFO("repack base to new seg: %p\n", fnewseg); +#endif + SpicSectorEraseFlashRtl8195A(fnewseg); // if(flash_erase_sector(fnewseg)) return -(FMEM_FLASH_ERR); + faddr += 4; + wraddr = fnewseg + 4; + do { + fobj.x = HAL_READ32(SPI_FLASH_BASE, faddr); //if(flash_read(faddr, &fobj, fobj_head_size)) return -(FMEM_FLASH_ERR); // последовательное чтение id из старого сегмента + if(fobj.x == fobj_x_free) break; + if(fobj.n.size > MAX_FOBJ_SIZE) len = align(MAX_FOBJ_SIZE + fobj_head_size); + else len = align(fobj.n.size + fobj_head_size); + if(fobj.n.id != obj.n.id && fobj.n.size <= MAX_FOBJ_SIZE) { // объект валидный + if(get_addr_fobj(fnewseg, &fobj, true) == 0) { // найдем, сохранили ли мы его уже? нет + rdaddr = get_addr_fobj(foldseg, &fobj, false); // найдем последнее сохранение объекта в старом сенгменте, size изменен + if(rdaddr < FMEM_ERROR_MAX) return rdaddr; // ??? + if(wraddr + len >= fnewseg + FMEMORY_SCFG_BANK_SIZE) { +#if DEBUGSOO > 1 + DBG_FEEP_ERR("pack segment overflow!\n"); +#endif + return -(FMEM_OVR_ERR); + }; +#if 0 + copy_align4_to_align1((uint8 *)pbuf, rdaddr, len); +#else + SpicUserReadFourByteRtl8195A(len, rdaddr, (unsigned int *)pbuf, flashobj.SpicInitPara.Mode.BitMode); +#endif + int i = 0; + int size4b = len >> 2; + // перепишем данные obj в новый сектор + while(size4b--) { + _fwrite_word(wraddr, pbuf[i++]); // if(flash_write(wraddr, &pbuf[i++], 4)) return -(FMEM_FLASH_ERR); + }; + }; + }; + faddr += len; + } while(faddr < (foldseg + FMEMORY_SCFG_BANK_SIZE - align(fobj_head_size+1))); + free(pbuf); + // обратный счетчик стираний/записей секторов как id + _fwrite_word(fnewseg, HAL_READ32(SPI_FLASH_BASE, foldseg) - 1); // if(flash_write(fnewseg, &foldseg + SPI_FLASH_BASE, 4)) return -(FMEM_FLASH_ERR); +#if DEBUGSOO > 3 + DBG_FEEP_INFO("free: %d\n", FMEMORY_SCFG_BANK_SIZE - (faddr & (FMEMORY_SCFG_BANK_SIZE-1))); +#endif + return get_addr_fobj_save(fnewseg, obj); // адрес для записи объекта; +} +//----------------------------------------------------------------------------- +LOCAL signed short FLASH_EEP_ATTR _flash_write_cfg(void *ptr, unsigned short id, unsigned short size) +{ + fobj_head fobj; + fobj.n.id = id; + fobj.n.size = size; + bool retb = false; + unsigned int faddr = get_addr_bscfg(false); + + if(faddr >= FMEM_ERROR_MAX) { + unsigned int xfaddr = get_addr_fobj(faddr, &fobj, false); + if(xfaddr > FMEM_ERROR_MAX && size == fobj.n.size) { + if(size == 0 + || cmp_align1_align4(ptr, (void *)SPI_FLASH_BASE + xfaddr + fobj_head_size, size) == 0) { +#if DEBUGSOO > 3 + DBG_FEEP_INFO("write obj is identical, id: %04x [%d]\n", id, size); +#endif + return size; // уже записано то-же самое + } +#if DEBUGSOO > 100 + else { + int i; + uint8 * p = (uint8 *)(SPI_FLASH_BASE + xfaddr + fobj_head_size); + uint8 * r = (uint8 *) ptr; + for(i=0; i < size; i+=8) { + DBG_8195A("buf[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n", + i, r[i], r[i+1], r[i+2], r[i+3], r[i+4], r[i+5], r[i+6], r[i+7]); + DBG_8195A("obj[%d]\t%02X %02X %02X %02X %02X %02X %02X %02X\n", + i, p[i], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7]); + } + } +#endif + } + } +#if DEBUGSOO > 2 + DBG_FEEP_INFO("write obj id: %04x [%d]\n", id, size); +#endif + fobj.n.size = size; + faddr = get_addr_fobj_save(faddr, fobj); + if(faddr == 0) { + faddr = pack_cfg_fmem(fobj); + if(faddr == 0) return FMEM_NOT_FOUND; + } + else if(faddr < FMEM_ERROR_MAX) return - faddr - 1; // error + +#if DEBUGSOO > 3 + DBG_FEEP_INFO("write obj to faddr %p\n", faddr); +#endif + _fwrite_word(faddr, fobj.x); // if(flash_write(faddr, &fobj.x, 4)) return FMEM_FLASH_ERR; + faddr+=4; + union { + unsigned char uc[4]; + unsigned int ud; + }tmp; +#if 0 + u32 len = (size + 3) & (~3); + if(len) SpicUserProgramRtl8195A((u8 *)ptr, 1, faddr, len); +#else + u32 len = (size + 3) >> 2; + uint8 * ps = ptr; + while(len--) { + tmp.uc[0] = *ps++; + tmp.uc[1] = *ps++; + tmp.uc[2] = *ps++; + tmp.uc[3] = *ps++; + _fwrite_word(faddr, tmp.ud); // if(flash_write(faddr, &tmp.ud, 4)) return FMEM_FLASH_ERR; + faddr += 4; + } +#endif + return size; +} +//============================================================================= +//- Сохранить объект в flash -------------------------------------------------- +// Returns : false/true +//----------------------------------------------------------------------------- +bool FLASH_EEP_ATTR flash_write_cfg(void *ptr, unsigned short id, unsigned short size) +{ + if(size > MAX_FOBJ_SIZE) return false; + bool retb = false; + device_mutex_lock(RT_DEV_LOCK_FLASH); + // SPIC Init + flash_turnon(); + if(fspic_isinit == 0) flash_init(&flashobj); + if(_flash_write_cfg(ptr, id, size) >= 0) { +#if DEBUGSOO > 3 + DBG_FEEP_INFO("saved ok\n"); +#endif + retb = true; + } + SpicDisableRtl8195A(); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + return retb; +} +//============================================================================= +//- Прочитать объект из flash ------------------------------------------------- +// Параметры: +// prt - указатель, куда сохранить +// id - идентификатор искомого объекта +// maxsize - сколько байт сохранить максимум из найденного объекта, по ptr +// Returns: +// -3 - error +// -2 - flash rd/wr/clr error +// -1 - не найден +// 0..MAX_FOBJ_SIZE - ok, сохраненный размер объекта +//----------------------------------------------------------------------------- +signed short FLASH_EEP_ATTR flash_read_cfg(void *ptr, unsigned short id, unsigned short maxsize) +{ + signed short rets = FMEM_ERROR; + if (maxsize <= MAX_FOBJ_SIZE) { + device_mutex_lock(RT_DEV_LOCK_FLASH); + fobj_head fobj; + fobj.n.id = id; + fobj.n.size = 0; +#if DEBUGSOO > 2 + DBG_FEEP_INFO("read obj id: %04x[%d]\n", id, maxsize); +#endif + // SPIC Init + flash_turnon(); + if(fspic_isinit == 0) flash_init(&flashobj); + unsigned int faddr = get_addr_bscfg(false); + if(faddr >= FMEM_ERROR_MAX) { + faddr = get_addr_fobj(faddr, &fobj, false); + if(faddr >= FMEM_ERROR_MAX) { +#if 0 + if(maxsize != 0 && ptr != NULL) + copy_align4_to_align1(ptr, SPI_FLASH_BASE + faddr + fobj_head_size, mMIN(fobj.n.size, maxsize)); +#else + if(maxsize != 0 && ptr != NULL) + SpicUserReadRtl8195A(mMIN(fobj.n.size, maxsize), faddr + fobj_head_size, ptr, flashobj.SpicInitPara.Mode.BitMode); +#endif +#if DEBUGSOO > 3 + DBG_FEEP_INFO("read ok, faddr: %p, size: %d\n", faddr, fobj.n.size); +#endif + rets = fobj.n.size; + } + else { +#if DEBUGSOO > 3 + DBG_FEEP_INFO("obj not found\n"); +#endif + rets = -faddr-1; + } + } + else rets = -faddr-1; + SpicDisableRtl8195A(); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + } + return rets; +} +//============================================================================= diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_api.c new file mode 100644 index 0000000..a664876 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_api.c @@ -0,0 +1,242 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include "pinmap.h" + +#if CONFIG_GPIO_EN + +#include "hal_gpio.h" +#include "gpio_api.h" + +// convert Mbed pin mode to HAL Pin Mode +const u8 GPIO_InPinMode[] = { + DIN_PULL_NONE, // PullNone + DIN_PULL_HIGH, // PullUp + DIN_PULL_LOW, // PullDown + DIN_PULL_NONE // OpenDrain +}; + +const u8 GPIO_SWPORT_DR_TBL[] = { + GPIO_PORTA_DR, + GPIO_PORTB_DR, + GPIO_PORTC_DR +}; + +const u8 GPIO_EXT_PORT_TBL[] = { + GPIO_EXT_PORTA, + GPIO_EXT_PORTB, + GPIO_EXT_PORTC +}; + +const u8 GPIO_SWPORT_DDR_TBL[] = { + GPIO_PORTA_DDR, + GPIO_PORTB_DDR, + GPIO_PORTC_DDR +}; + +#if 0 +void gpio_set_hal_pin_mode(gpio_t *obj) +{ + if (obj->direction == PIN_OUTPUT) { + switch (obj->mode) { + case PullNone: + case PullDown: + case PullUp: + obj->hal_pin.pin_mode = DOUT_PUSH_PULL; + break; + + case OpenDrain: + obj->hal_pin.pin_mode = DOUT_OPEN_DRAIN; + break; + + default: + obj->hal_pin.pin_mode = DOUT_PUSH_PULL; + break; + } + } + else { + switch (obj->mode) { + case PullNone: + case OpenDrain: + obj->hal_pin.pin_mode = DIN_PULL_NONE; + break; + + case PullDown: + obj->hal_pin.pin_mode = DIN_PULL_LOW; + break; + + case PullUp: + obj->hal_pin.pin_mode = DIN_PULL_HIGH; + break; + + default: + obj->hal_pin.pin_mode = DIN_PULL_NONE; + break; + } + } +} +#endif +void gpio_set_hal_pin_mode(gpio_t *obj) +{ + uint32_t mode; + + mode = obj->mode; + if (obj->direction == PIN_OUTPUT) { + if (mode == OpenDrain) { + obj->hal_pin.pin_mode = DOUT_OPEN_DRAIN; + } else { + obj->hal_pin.pin_mode = DOUT_PUSH_PULL; + } + } else { + if (mode < 4) { + obj->hal_pin.pin_mode = GPIO_InPinMode[mode]; + } else { + obj->hal_pin.pin_mode = DIN_PULL_NONE; + } + } +} + +uint32_t gpio_set(PinName pin) +{ + u32 ip_pin; + + //MBED_ASSERT(pin != (PinName)NC); + DBG_ASSERT(pin != (PinName)NC); + pin_function(pin, 0); + ip_pin = HAL_GPIO_GetPinName((u32)pin); + + return ip_pin; +} + +void gpio_init(gpio_t *obj, PinName pin) +{ + uint32_t pin_name; + + if (pin == (PinName)NC) + return; + + obj->pin = pin; + obj->mode = PullNone; + obj->direction = PIN_INPUT; + pin_name = gpio_set(pin); // get the IP pin name + obj->hal_pin.pin_name = pin_name; + obj->hal_pin.pin_mode = DIN_PULL_NONE; + obj->hal_port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name); + obj->hal_pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name); + HAL_GPIO_Init(&obj->hal_pin); +} + +void gpio_mode(gpio_t *obj, PinMode mode) +{ + obj->mode = mode; + gpio_set_hal_pin_mode(obj); + HAL_GPIO_Init(&obj->hal_pin); +} + +// Initial the Pin direction +void gpio_dir(gpio_t *obj, PinDirection direction) { +// DBG_ASSERT(obj->pin != (PinName)NC); + obj->direction = direction; + gpio_set_hal_pin_mode(obj); + HAL_GPIO_Init(&obj->hal_pin); +} + +// Change the pin direction directly +void gpio_change_dir(gpio_t *obj, PinDirection direction) { + uint32_t reg_value; + uint8_t port_num; + uint8_t pin_num; + + obj->direction = direction; + gpio_set_hal_pin_mode(obj); + port_num = obj->hal_port_num; + pin_num = obj->hal_pin_num; + + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DDR_TBL[port_num]); + if (direction) { + // Out + reg_value |= (1 << pin_num); + } else { + // In + reg_value &= ~(1 << pin_num); + } + HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DDR_TBL[port_num], reg_value); +} + +void gpio_write(gpio_t *obj, int value) +{ + HAL_GPIO_PIN *hal_pin=&obj->hal_pin; + volatile uint32_t reg_value; + uint8_t port_num; + uint8_t pin_num; + + if (hal_pin->pin_mode != DOUT_OPEN_DRAIN) { + port_num = obj->hal_port_num; + pin_num = obj->hal_pin_num; + + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num]); + reg_value &= ~(1 << pin_num); + reg_value |= ((value&0x01)<< pin_num); + HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num], reg_value); + } else { + HAL_GPIO_WritePin(&obj->hal_pin, value); + } +} + +int gpio_read(gpio_t *obj) { + volatile uint32_t reg_value; + uint8_t port_num; + uint8_t pin_num; +// HAL_GPIO_PIN_STATE pin_status; + HAL_GPIO_PIN_MODE pin_mode; + + port_num = obj->hal_port_num; + pin_num = obj->hal_pin_num; + pin_mode = obj->hal_pin.pin_mode; + + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_EXT_PORT_TBL[port_num]); + if (pin_mode != DOUT_OPEN_DRAIN) { + return ((reg_value >> pin_num) & 0x01); + } else { + return (!((reg_value >> pin_num) & 0x01)); + } + +// return pin_status; +} + +// This API only works for non-Open-Drain pin +void gpio_direct_write(gpio_t *obj, BOOL value) +{ + uint8_t port_num; + uint8_t pin_num; + uint32_t reg_value; + + port_num = obj->hal_port_num; + pin_num = obj->hal_pin_num; + + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num]); + reg_value &= ~(1 << pin_num); + reg_value |= (value<< pin_num); + HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[port_num], reg_value); +} + +void gpio_pull_ctrl(gpio_t *obj, PinMode pull_type) +{ +// obj->mode = pull_type; +// gpio_set_hal_pin_mode(obj); + HAL_GPIO_PullCtrl((u32) obj->pin, (u32)pull_type); +} + + +void gpio_deinit(gpio_t *obj) { + HAL_GPIO_DeInit(&obj->hal_pin); +} + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_irq_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_irq_api.c new file mode 100644 index 0000000..8926572 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_irq_api.c @@ -0,0 +1,145 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include "pinmap.h" + +//static uint32_t channel_ids[32] = {0}; + +//static gpio_irq_handler irq_handler; + +#if CONFIG_GPIO_EN +#include "gpio_irq_api.h" +#include "gpio_irq_ex_api.h" + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) +{ + uint32_t pin_name; + + if (pin == NC) return -1; + + obj->pin = pin; + pin_name = HAL_GPIO_GetPinName((u32)pin);; // get the IP pin name + obj->hal_pin.pin_name = pin_name; + obj->hal_pin.pin_mode = INT_FALLING; // default use Falling trigger + obj->hal_port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name); + obj->hal_pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name); + HAL_GPIO_Irq_Init(&obj->hal_pin); + HAL_GPIO_UserRegIrq(&obj->hal_pin, (VOID*) handler, (VOID*) id); + + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) +{ + HAL_GPIO_UserUnRegIrq(&obj->hal_pin); + HAL_GPIO_DeInit(&obj->hal_pin); +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) +{ + switch((uint32_t)event) { + case IRQ_RISE: + obj->hal_pin.pin_mode = INT_RISING; + break; + + case IRQ_FALL: + obj->hal_pin.pin_mode = INT_FALLING; + break; + + case IRQ_LOW: + obj->hal_pin.pin_mode = INT_LOW; + break; + + case IRQ_HIGH: + obj->hal_pin.pin_mode = INT_HIGH; + break; + + case IRQ_NONE: + // ? + break; + + default: + break; + } +// HAL_GPIO_Irq_Init(&obj->hal_pin); + HAL_GPIO_Init_8195a(&obj->hal_pin); + + HAL_GPIO_IntCtrl(&obj->hal_pin, enable); +} + +void gpio_irq_enable(gpio_irq_t *obj) +{ + HAL_GPIO_UnMaskIrq(&obj->hal_pin); +} + +void gpio_irq_disable(gpio_irq_t *obj) +{ + HAL_GPIO_MaskIrq(&obj->hal_pin); +} + +void gpio_irq_deinit(gpio_irq_t *obj) +{ + HAL_GPIO_DeInit(&obj->hal_pin); +} + +void gpio_irq_pull_ctrl(gpio_irq_t *obj, PinMode pull_type) +{ + HAL_GPIO_PullCtrl((u32) obj->pin, (u32)pull_type); +} + +void gpio_irq_set_event(gpio_irq_t *obj, gpio_irq_event event) +{ + uint32_t reg_value; + uint32_t level_edge; + uint32_t polarity; + uint8_t pin_num; + + pin_num = obj->hal_pin_num & 0x1f; // Max 31 + + switch (event) { + case IRQ_LOW: + level_edge = 0; // level trigger + polarity = 0; // active low + break; + + case IRQ_HIGH: + level_edge = 0; // level trigger + polarity = 1; // active high + break; + + case IRQ_FALL: + level_edge = 1; // edge trigger + polarity = 0; // active low + break; + + case IRQ_RISE: + level_edge = 1; // edge trigger + polarity = 1; // active high + break; + + default: + DBG_GPIO_ERR("Unknow Interrupt Trigger Type(%d)\n", event); + return; + } + + // Config Level or Edge trigger + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_INT_TYPE); + reg_value &= ~(1 << pin_num); + reg_value |= (level_edge << pin_num); + HAL_WRITE32(GPIO_REG_BASE, GPIO_INT_TYPE, reg_value); + + // Config Low active or Gigh active + reg_value = HAL_READ32(GPIO_REG_BASE, GPIO_INT_POLARITY); + reg_value &= ~(1 << pin_num); + reg_value |= (polarity << pin_num); + HAL_WRITE32(GPIO_REG_BASE, GPIO_INT_POLARITY, reg_value); +} + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_object.h b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_object.h new file mode 100644 index 0000000..63820cf --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/gpio_object.h @@ -0,0 +1,39 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_GPIO_OBJECT_H +#define MBED_GPIO_OBJECT_H + +#include "mbed_assert.h" + +#include "basic_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PinName pin; + uint32_t mask; + + uint32_t reg_out_offset; + uint32_t reg_dir_offset; +} gpio_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/i2c_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/i2c_api.c new file mode 100644 index 0000000..6d1ed3e --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/i2c_api.c @@ -0,0 +1,780 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +//#include "mbed_assert.h" +#include "objects.h" +#include "PinNames.h" +//#include +#include "hal_i2c.h" +#include "i2c_api.h" +#include "ex_api.h" + + +#if CONFIG_I2C_EN + +//#include "cmsis.h" +#include "pinmap.h" + + +static const PinMap PinMap_I2C_SDA[] = { + {PD_4, RTL_PIN_PERI(I2C0, 0, S0), RTL_PIN_FUNC(I2C0, S0)}, + {PH_1, RTL_PIN_PERI(I2C0, 0, S1), RTL_PIN_FUNC(I2C0, S1)}, + {PC_8, RTL_PIN_PERI(I2C0, 0, S2), RTL_PIN_FUNC(I2C0, S2)}, + {PE_7, RTL_PIN_PERI(I2C0, 0, S3), RTL_PIN_FUNC(I2C0, S3)}, + + {PC_4, RTL_PIN_PERI(I2C1, 1, S0), RTL_PIN_FUNC(I2C1, S0)}, + {PH_3, RTL_PIN_PERI(I2C1, 1, S1), RTL_PIN_FUNC(I2C1, S1)}, + {PD_7, RTL_PIN_PERI(I2C1, 1, S2), RTL_PIN_FUNC(I2C1, S2)}, + + {PB_7, RTL_PIN_PERI(I2C2, 2, S0), RTL_PIN_FUNC(I2C2, S0)}, + {PE_1, RTL_PIN_PERI(I2C2, 2, S1), RTL_PIN_FUNC(I2C2, S1)}, + {PC_7, RTL_PIN_PERI(I2C2, 2, S2), RTL_PIN_FUNC(I2C2, S2)}, + + {PB_3, RTL_PIN_PERI(I2C3, 3, S0), RTL_PIN_FUNC(I2C3, S0)}, + {PE_3, RTL_PIN_PERI(I2C3, 3, S1), RTL_PIN_FUNC(I2C3, S1)}, + {PE_5, RTL_PIN_PERI(I2C3, 3, S2), RTL_PIN_FUNC(I2C3, S2)}, + {PD_9, RTL_PIN_PERI(I2C3, 3, S3), RTL_PIN_FUNC(I2C3, S3)}, + + {NC, NC, 0} +}; + +static const PinMap PinMap_I2C_SCL[] = { + {PD_5, RTL_PIN_PERI(I2C0, 0, S0), RTL_PIN_FUNC(I2C0, S0)}, + {PH_0, RTL_PIN_PERI(I2C0, 0, S1), RTL_PIN_FUNC(I2C0, S1)}, + {PC_9, RTL_PIN_PERI(I2C0, 0, S2), RTL_PIN_FUNC(I2C0, S2)}, + {PE_6, RTL_PIN_PERI(I2C0, 0, S3), RTL_PIN_FUNC(I2C0, S3)}, + + {PC_5, RTL_PIN_PERI(I2C1, 1, S0), RTL_PIN_FUNC(I2C1, S0)}, + {PH_2, RTL_PIN_PERI(I2C1, 1, S1), RTL_PIN_FUNC(I2C1, S1)}, + {PD_6, RTL_PIN_PERI(I2C1, 1, S2), RTL_PIN_FUNC(I2C1, S2)}, + + {PB_6, RTL_PIN_PERI(I2C2, 2, S0), RTL_PIN_FUNC(I2C2, S0)}, + {PE_0, RTL_PIN_PERI(I2C2, 2, S1), RTL_PIN_FUNC(I2C2, S1)}, + {PC_6, RTL_PIN_PERI(I2C2, 2, S2), RTL_PIN_FUNC(I2C2, S2)}, + + {PB_2, RTL_PIN_PERI(I2C3, 3, S0), RTL_PIN_FUNC(I2C3, S0)}, + {PE_2, RTL_PIN_PERI(I2C3, 3, S1), RTL_PIN_FUNC(I2C3, S1)}, + {PE_4, RTL_PIN_PERI(I2C3, 3, S2), RTL_PIN_FUNC(I2C3, S2)}, + {PD_8, RTL_PIN_PERI(I2C3, 3, S3), RTL_PIN_FUNC(I2C3, S3)}, + + {NC, NC, 0} +}; + +static uint16_t i2c_target_addr[4]; +static SAL_I2C_TRANSFER_BUF i2ctxtranbuf[4]; +static SAL_I2C_TRANSFER_BUF i2crxtranbuf[4]; +extern u32 ConfigDebugErr; +extern u32 ConfigDebuginfo; +void i2c_init(i2c_t *obj, PinName sda, PinName scl) { + + uint32_t i2c_sel; + uint32_t i2c_idx; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_USERCB_ADPT pSalI2CUserCBAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + + // Determine the I2C to use + uint32_t i2c_sda = (uint32_t)pinmap_peripheral(sda, PinMap_I2C_SDA); + uint32_t i2c_scl = (uint32_t)pinmap_peripheral(scl, PinMap_I2C_SCL); + ConfigDebugErr &= (~(_DBG_I2C_|_DBG_GDMA_)); + ConfigDebugInfo&= (~(_DBG_I2C_|_DBG_GDMA_)); + i2c_sel = (uint32_t)pinmap_merge(i2c_sda, i2c_scl); + i2c_idx = RTL_GET_PERI_IDX(i2c_sel); + if (unlikely(i2c_idx == NC)) { + DBG_8195A("%s: Cannot find matched port i2c\n", __FUNCTION__); + return; + } + + //DBG_8195A("i2c_sel:%x\n",i2c_sel); + //DBG_8195A("i2c_idx:%x\n",i2c_idx); + + /* Get I2C device handler */ + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&(obj->SalI2CUserCBAdpt); + + + + /*To assign the rest pointers*/ + pSalI2CMngtAdpt->MstRDCmdCnt = 0; + pSalI2CMngtAdpt->InnerTimeOut = 2000; // inner time-out count, 2000 ms + pSalI2CMngtAdpt->pSalHndPriv = &(obj->SalI2CHndPriv); + pSalI2CMngtAdpt->pSalHndPriv->ppSalI2CHnd = (void**)&(pSalI2CMngtAdpt->pSalHndPriv); + + /* To assign the default (ROM) HAL OP initialization function */ +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_Patch; +#elif defined(CONFIG_CHIP_E_CUT) + pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_V04; +#endif + /* To assign the default (ROM) HAL GDMA OP initialization function */ + pSalI2CMngtAdpt->pHalGdmaOpInit = HalGdmaOpInit; + + /* To assign the default (ROM) SAL interrupt function */ +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_Patch; +#elif defined(CONFIG_CHIP_E_CUT) + pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_V04; +#endif + + /* To assign the default (ROM) SAL DMA TX interrupt function */ + pSalI2CMngtAdpt->pSalDMATxIrqFunc = I2CTXGDMAISRHandle; + + /* To assign the default (ROM) SAL DMA RX interrupt function */ + pSalI2CMngtAdpt->pSalDMARxIrqFunc = I2CRXGDMAISRHandle; + + pSalI2CMngtAdpt->pHalInitDat = &(obj->HalI2CInitData); + pSalI2CMngtAdpt->pHalOp = &(obj->HalI2COp); + pSalI2CMngtAdpt->pIrqHnd = &(obj->I2CIrqHandleDat); + pSalI2CMngtAdpt->pHalTxGdmaAdp = &(obj->HalI2CTxGdmaAdpt); + pSalI2CMngtAdpt->pHalRxGdmaAdp = &(obj->HalI2CRxGdmaAdpt); + pSalI2CMngtAdpt->pHalGdmaOp = &(obj->HalI2CGdmaOp); + pSalI2CMngtAdpt->pIrqTxGdmaHnd = &(obj->I2CTxGdmaIrqHandleDat); + pSalI2CMngtAdpt->pIrqRxGdmaHnd = &(obj->I2CRxGdmaIrqHandleDat); + pSalI2CMngtAdpt->pUserCB = &(obj->SalI2CUserCB); + pSalI2CMngtAdpt->pDMAConf = &(obj->SalI2CDmaUserDef); + + /* Assign the private SAL handle to public SAL handle */ + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + /* Assign the internal HAL initial data pointer to the SAL handle */ + pSalI2CHND->pInitDat = pSalI2CMngtAdpt->pHalInitDat; + + /* Assign the internal user callback pointer to the SAL handle */ + pSalI2CHND->pUserCB = pSalI2CMngtAdpt->pUserCB; + + /* Assign the internal user define DMA configuration to the SAL handle */ + pSalI2CHND->pDMAConf = pSalI2CMngtAdpt->pDMAConf; + + /*To assign user callback pointers*/ + pSalI2CMngtAdpt->pUserCB->pTXCB = pSalI2CUserCBAdpt; + pSalI2CMngtAdpt->pUserCB->pTXCCB = (pSalI2CUserCBAdpt+1); + pSalI2CMngtAdpt->pUserCB->pRXCB = (pSalI2CUserCBAdpt+2); + pSalI2CMngtAdpt->pUserCB->pRXCCB = (pSalI2CUserCBAdpt+3); + pSalI2CMngtAdpt->pUserCB->pRDREQCB = (pSalI2CUserCBAdpt+4); + pSalI2CMngtAdpt->pUserCB->pERRCB = (pSalI2CUserCBAdpt+5); + pSalI2CMngtAdpt->pUserCB->pDMATXCB = (pSalI2CUserCBAdpt+6); + pSalI2CMngtAdpt->pUserCB->pDMATXCCB = (pSalI2CUserCBAdpt+7); + pSalI2CMngtAdpt->pUserCB->pDMARXCB = (pSalI2CUserCBAdpt+8); + pSalI2CMngtAdpt->pUserCB->pDMARXCCB = (pSalI2CUserCBAdpt+9); + pSalI2CMngtAdpt->pUserCB->pGENCALLCB= (pSalI2CUserCBAdpt+10); + + /* Set I2C Device Number */ + pSalI2CHND->DevNum = i2c_idx; + + /* Load I2C default value */ + RtkI2CLoadDefault(pSalI2CHND); + + /* Assign I2C Pin Mux */ + pSalI2CHND->PinMux = RTL_GET_PERI_SEL(i2c_sel); + pSalI2CHND->OpType = I2C_INTR_TYPE; + pSalI2CHND->I2CMaster = I2C_MASTER_MODE; + pSalI2CHND->I2CSpdMod = I2C_SS_MODE; + pSalI2CHND->I2CClk = 100; + pSalI2CHND->I2CAckAddr = 0; + pSalI2CHND->TimeOut = 300; + pSalI2CHND->AddRtyTimeOut = 3000; + pSalI2CHND->I2CExd |= (I2C_EXD_MTR_ADDR_RTY); + + pSalI2CMngtAdpt->InnerTimeOut = pSalI2CHND->TimeOut; + + /* Deinit I2C first */ + //i2c_reset(obj); + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); +} + +void i2c_frequency(i2c_t *obj, int hz) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + uint16_t i2c_default_clk = (uint16_t) pSalI2CHND->I2CClk; + uint16_t i2c_user_clk = (uint16_t) (hz/1000); + + if (i2c_default_clk != i2c_user_clk) { + /* Deinit I2C first */ + i2c_reset(obj); + if (i2c_user_clk <= 100) { + pSalI2CHND->I2CSpdMod = I2C_SS_MODE; + } + else if ((i2c_user_clk > 100) && (i2c_user_clk <= 400)) { + pSalI2CHND->I2CSpdMod = I2C_FS_MODE; + } + else if (i2c_user_clk > 400) { + pSalI2CHND->I2CSpdMod = I2C_HS_MODE; + } + else { + pSalI2CHND->I2CSpdMod = I2C_SS_MODE; + } + + /* Load the user defined I2C clock */ + pSalI2CHND->I2CClk = i2c_user_clk; + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); + } +} + +inline int i2c_start(i2c_t *obj) { + return 0; +} + +inline int i2c_stop(i2c_t *obj) { + return 0; +} + +// extern u32 HalDelayUs(IN u32 us); + +int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + u32 I2CInTOTcnt = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + if (i2c_target_addr[pSalI2CHND->DevNum] != address) { + /* Deinit I2C first */ + i2c_reset(obj); + + /* Load the user defined I2C target slave address */ + i2c_target_addr[pSalI2CHND->DevNum] = address; + pSalI2CHND->I2CAckAddr = address; + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); + } + + /* Check if the it's the last byte or not */ + pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS); + if (!stop) { + pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS; + } + + pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pRXBuf->DataLen = length; + pSalI2CHND->pRXBuf->TargetAddr= pSalI2CHND->I2CAckAddr; + pSalI2CHND->pRXBuf->RegAddr = 0; + pSalI2CHND->pRXBuf->pDataBuf = (u8 *)data; + + if (RtkI2CReceive(pSalI2CHND) != HAL_OK) { + length = length - pSalI2CHND->pRXBuf->DataLen; + return ((int)length); + } + else { + //DBG_8195A(">\n"); + /* Calculate user time out parameters */ + I2CInTOTcnt = 300; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + while((pSalI2CHND->DevSts != I2C_STS_IDLE) && + (pSalI2CHND->DevSts != I2C_STS_ERROR) && + (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + + /* DeInit I2C, Init I2C */ + //RtkI2CDeInit(pSalI2CHND); + //HalDelayUs(1000); + //RtkI2CInit(pSalI2CHND); + + return ((int)(length)); + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + /* DeInit I2C, Init I2C */ + //RtkI2CDeInit(pSalI2CHND); + + //RtkI2CInit(pSalI2CHND); + + return ((int)(length)); + } + } + } + //DBG_8195A("<\n"); + if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT) + return ((int)(length - pSalI2CHND->pRXBuf->DataLen)); + else + return ((int)(length)); + } +} + +int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + u32 I2CInTOTcnt = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + if (i2c_target_addr[pSalI2CHND->DevNum] != address) { + /* Deinit I2C first */ + i2c_reset(obj); + + /* Load the user defined I2C target slave address */ + i2c_target_addr[pSalI2CHND->DevNum] = address; + pSalI2CHND->I2CAckAddr = address; + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); + } + + /* Check if the it's the last byte or not */ + pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS); + if (!stop) { + pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS; + } + + pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pTXBuf->DataLen = length; + pSalI2CHND->pTXBuf->TargetAddr= pSalI2CHND->I2CAckAddr; + pSalI2CHND->pTXBuf->RegAddr = 0; + pSalI2CHND->pTXBuf->pDataBuf = (u8 *)data; + + if (RtkI2CSend(pSalI2CHND) != HAL_OK) { + length = length - pSalI2CHND->pTXBuf->DataLen; + return ((int)length); + } + else { + //DBG_8195A("(\n"); + /* Calculate user time out parameters */ + I2CInTOTcnt = 300; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + while((pSalI2CHND->DevSts != I2C_STS_IDLE) && + (pSalI2CHND->DevSts != I2C_STS_ERROR) && + (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + /* DeInit I2C, Init I2C */ + //RtkI2CDeInit(pSalI2CHND); + + //RtkI2CInit(pSalI2CHND); + return ((int)(length)); + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + /* DeInit I2C, Init I2C */ + //RtkI2CDeInit(pSalI2CHND); + + //RtkI2CInit(pSalI2CHND); + return ((int)(length)); + } + } + } + + if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT) + return ((int)(length - pSalI2CHND->pTXBuf->DataLen)); + else + return ((int)(length)); + } +} + +int i2c_byte_read(i2c_t *obj, int last) { + uint8_t i2cdatlocal; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + /* Check if the it's the last byte or not */ + pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS); + if (!last) { + pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS; + } + + pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pRXBuf->DataLen = 1; + pSalI2CHND->pRXBuf->TargetAddr= pSalI2CHND->I2CAckAddr; + pSalI2CHND->pRXBuf->RegAddr = 0; + pSalI2CHND->pRXBuf->pDataBuf = &i2cdatlocal; + RtkI2CReceive(pSalI2CHND); + + return (int)i2cdatlocal; +} + +int i2c_byte_write(i2c_t *obj, int data) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + pSalI2CHND->I2CExd &= (~I2C_EXD_MTR_HOLD_BUS); + pSalI2CHND->I2CExd |= I2C_EXD_MTR_HOLD_BUS; + + pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pTXBuf->DataLen = 1; + pSalI2CHND->pTXBuf->TargetAddr= pSalI2CHND->I2CAckAddr; + pSalI2CHND->pTXBuf->RegAddr = 0; + pSalI2CHND->pTXBuf->pDataBuf = (unsigned char*)&data; + + if (RtkI2CSend(pSalI2CHND) != HAL_OK) { + return 0; + } + + return 1; +} + +void i2c_reset(i2c_t *obj) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + /* Deinit I2C directly */ + RtkI2CDeInitForPS(pSalI2CHND); +} + +void i2c_restart_enable(i2c_t *obj) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + uint32_t i2clocaltmp; + uint8_t i2cen; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + i2cen = pSalI2CHND->pInitDat->I2CEn; + + if (i2cen == I2C_ENABLE) { + pSalI2CHND->pInitDat->I2CEn = I2C_DISABLE; + pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat); + } + + i2clocaltmp = HalI2CRead32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON); + i2clocaltmp |= BIT_IC_CON_IC_RESTART_EN; + HalI2CWrite32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON, i2clocaltmp); + + if (i2cen == I2C_ENABLE) { + pSalI2CHND->pInitDat->I2CEn = I2C_ENABLE; + pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat); + } + + pSalI2CHND->pInitDat->I2CReSTR = I2C_ENABLE; + +} + +void i2c_restart_disable(i2c_t *obj) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + uint32_t i2clocaltmp; + uint8_t i2cen; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + i2cen = pSalI2CHND->pInitDat->I2CEn; + + if (i2cen == I2C_ENABLE) { + pSalI2CHND->pInitDat->I2CEn = I2C_DISABLE; + pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat); + } + + i2clocaltmp = HalI2CRead32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON); + i2clocaltmp &= (~BIT_IC_CON_IC_RESTART_EN); + HalI2CWrite32(pSalI2CHND->DevNum, REG_DW_I2C_IC_CON, i2clocaltmp); + + if (i2cen == I2C_ENABLE) { + pSalI2CHND->pInitDat->I2CEn = I2C_ENABLE; + pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat); + } + + pSalI2CHND->pInitDat->I2CReSTR = I2C_DISABLE; + +} + +void i2c_set_user_callback(i2c_t *obj, I2CCallback i2ccb, void(*i2c_callback)(void *)) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + if ((i2ccb >= I2C_TX_COMPLETE) && (i2ccb <= I2C_ERR_OCCURRED)) { + switch (i2ccb) { + case I2C_TX_COMPLETE: + pSalI2CHND->pUserCB->pTXCCB->USERCB = i2c_callback; + break; + case I2C_RX_COMPLETE: + pSalI2CHND->pUserCB->pRXCCB->USERCB = i2c_callback; + break; + case I2C_RD_REQ_COMMAND: + pSalI2CHND->pUserCB->pRDREQCB->USERCB = i2c_callback; + break; + case I2C_ERR_OCCURRED: + pSalI2CHND->pUserCB->pERRCB->USERCB = i2c_callback; + break; + default: + break; + } + } +} + + +void i2c_clear_user_callback(i2c_t *obj, I2CCallback i2ccb) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + if ((i2ccb >= I2C_TX_COMPLETE) && (i2ccb <= I2C_ERR_OCCURRED)) { + switch (i2ccb) { + case I2C_TX_COMPLETE: + pSalI2CHND->pUserCB->pTXCCB = NULL; + break; + case I2C_RX_COMPLETE: + pSalI2CHND->pUserCB->pRXCCB = NULL; + break; + case I2C_ERR_OCCURRED: + pSalI2CHND->pUserCB->pERRCB = NULL; + break; + default: + break; + } + } +} + +int i2c_enable_control(i2c_t *obj, int enable) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + pSalI2CHND->pInitDat->I2CEn = enable; + + pSalI2CMngtAdpt->pHalOp->HalI2CEnable(pSalI2CHND->pInitDat); +} + +#if DEVICE_I2CSLAVE + +void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + uint16_t i2c_default_addr = (uint16_t) pSalI2CHND->I2CAckAddr; + uint16_t i2c_user_addr = (uint16_t) address; + + if (i2c_default_addr != i2c_user_addr) { + /* Deinit I2C first */ + i2c_reset(obj); + + /* Load the user defined I2C clock */ + pSalI2CHND->I2CAckAddr = i2c_user_addr; + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); + } +} + +void i2c_slave_mode(i2c_t *obj, int enable_slave) { + + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + /* Deinit I2C first */ + i2c_reset(obj); + + /* Load the user defined I2C clock */ + pSalI2CHND->I2CMaster = I2C_MASTER_MODE; + if (enable_slave) + pSalI2CHND->I2CMaster = I2C_SLAVE_MODE; + + /* Init I2C now */ + RtkI2CInitForPS(pSalI2CHND); +} + +// See I2CSlave.h +#define NoData 0 // the slave has not been addressed +#define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter) +#define WriteGeneral 2 // the master is writing to all slave +#define WriteAddressed 3 // the master is writing to this slave (slave = receiver) + +int i2c_slave_receive(i2c_t *obj) { + + int i2cslvrevsts = NoData; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + i2cslvrevsts = RtkSalI2CSts(pSalI2CHND); + return i2cslvrevsts; +} + +int i2c_slave_read(i2c_t *obj, char *data, int length) { + + u32 I2CInTOTcnt = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + + //uint8_t i2cdatlocal; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + pSalI2CHND->pRXBuf = &i2crxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pRXBuf->DataLen = length; + pSalI2CHND->pRXBuf->pDataBuf = (u8 *)data; + + if (RtkI2CReceive(pSalI2CHND) != HAL_OK) { + return 0; //error + } + else { + /* Calculate user time out parameters */ + I2CInTOTcnt = 300; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + while((pSalI2CHND->DevSts != I2C_STS_IDLE) && + (pSalI2CHND->DevSts != I2C_STS_ERROR) && + (pSalI2CHND->DevSts != I2C_STS_TIMEOUT)) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + return ((int)(length)); + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + return ((int)(length)); + } + } + } + + if (pSalI2CHND->DevSts != I2C_STS_TIMEOUT) + return ((int)(length - pSalI2CHND->pTXBuf->DataLen)); + else + return ((int)(length)); + } +} + +int i2c_slave_write(i2c_t *obj, const char *data, int length) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + pSalI2CHND->pTXBuf = &i2ctxtranbuf[pSalI2CHND->DevNum]; + pSalI2CHND->pTXBuf->DataLen = length; + //obj->i2c->pTXBuf->TargetAddr= obj->i2c->I2CAckAddr; + //obj->i2c->pTXBuf->RegAddr = 0; + pSalI2CHND->pTXBuf->pDataBuf = (u8 *)data; + + if (RtkI2CSend(pSalI2CHND) != HAL_OK) { + return 0; //error + } + + return 1; +} + +/** \brief Description of i2c_slave_set_for_rd_req + * + * i2c_slave_set_for_rd_req is used to set/clear i2c slave RD_REQ interrupt mask. + * If RD_REQ interrupt is set, slave could invoke read request callback when it gets + * a read command from other i2c master. + * + * \param i2c_t *obj : i2c object + * \param int set : set or clear for read request. Once it's set, i2c would invoke read request callback when a + * read command is sent to it. + * \return result + */ +int i2c_slave_set_for_rd_req(i2c_t *obj, int set) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; + u32 I2CLocalTemp; + + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + + if (set) { + I2CLocalTemp |= BIT_IC_INTR_MASK_M_RD_REQ; + } else { + I2CLocalTemp &= (~BIT_IC_INTR_MASK_M_RD_REQ); + } + + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + return 1; +} + +/** \brief Description of i2c_slave_set_for_data_nak + * + * i2c_slave_set_for_data_nak is used to set/clear i2c slave NAK or ACK data part in transfer. + * + * \param i2c_t *obj : i2c object + * \param int set : set or clear for data NAK. + * \return result + */ +int i2c_slave_set_for_data_nak(i2c_t *obj, int set_nak) { + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; + u32 I2CLocalTemp; + + pSalI2CMngtAdpt = &(obj->SalI2CMngtAdpt); + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS); + + //if (set_nak) { + while (BIT_IC_STATUS_SLV_ACTIVITY & I2CLocalTemp) { + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS); + } + //} + + HAL_I2C_WRITE32(pSalI2CHND->DevNum, REG_DW_I2C_IC_SLV_DATA_NACK_ONLY, set_nak); +} + +#endif // CONFIG_I2C_SLAVE_EN + +#endif // CONFIG_I2C_EN + diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/i2s_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/i2s_api.c new file mode 100644 index 0000000..cc83b8a --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/i2s_api.c @@ -0,0 +1,247 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2015, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include "i2s_api.h" +#include "pinmap.h" + +#if CONFIG_I2S_EN +static const PinMap PinMap_I2S_TX[] = { + {PE_2, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710 + {PH_2, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)}, + {PD_2, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)}, + {PC_7, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)}, + {PC_2, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710 + {PD_6, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)}, + {PE_6, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_I2S_RX[] = { + {PH_5, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)}, + {PC_5, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)}, //+RTL8710 + {PC_4, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710 + {PD_3, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)}, + {PE_8, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S1)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_I2S_CLK[] = { + {PE_1, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710 + {PH_1, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)}, + {PD_1, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)}, + {PC_8, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)}, + {PC_1, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710 + {PD_5, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)}, + {PE_5, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_I2S_WS[] = { + {PE_0, RTL_PIN_PERI(I2S0, 0, S0), RTL_PIN_FUNC(I2S0, S0)}, //+RTL8710 + {PH_0, RTL_PIN_PERI(I2S0, 0, S1), RTL_PIN_FUNC(I2S0, S1)}, + {PD_0, RTL_PIN_PERI(I2S0, 0, S2), RTL_PIN_FUNC(I2S0, S2)}, + {PC_9, RTL_PIN_PERI(I2S0, 0, S3), RTL_PIN_FUNC(I2S0, S3)}, + {PC_0, RTL_PIN_PERI(I2S1, 1, S0), RTL_PIN_FUNC(I2S1, S0)}, //+RTL8710 + {PD_4, RTL_PIN_PERI(I2S1, 1, S1), RTL_PIN_FUNC(I2S1, S1)}, + {PE_4, RTL_PIN_PERI(I2S1, 1, S2), RTL_PIN_FUNC(I2S1, S2)}, //+RTL8710 + {NC, NC, 0} +}; + +static const HAL_I2S_DEF_SETTING I2SDefaultSetting = { + .I2SMaster = I2S_MASTER_MODE, //I2S Function Mode + .DevSts = I2S_STS_UNINITIAL, //I2S device status + .I2SChNum = I2S_CH_STEREO, //I2S Channel number mono or stereo + .I2SPageNum = I2S_4PAGE, //I2S Page number 2~4 + .I2STRxAct = I2S_TXRX, //I2S tx rx act, tx only or rx only or tx+rx + .I2SWordLen = I2S_WL_16, //I2S Word length 16bit or 24bit + .I2SPageSize = (768/4)-1, //I2S Page size 1~4096 word + .I2SRate = I2S_SR_48KHZ, //I2S sample rate 8k ~ 96khz + + .I2STxIntrMSK = I2S_TX_INT_PAGE0_OK|I2S_TX_INT_PAGE1_OK| \ + I2S_TX_INT_PAGE2_OK|I2S_TX_INT_PAGE3_OK, /*I2S Tx Interrupt Mask*/ + .I2SRxIntrMSK = I2S_RX_INT_PAGE0_OK|I2S_RX_INT_PAGE1_OK| \ + I2S_RX_INT_PAGE2_OK|I2S_RX_INT_PAGE3_OK /*I2S Rx Interrupt Mask*/ +}; + +void i2s_init(i2s_t *obj, PinName sck, PinName ws, PinName sd) +{ + uint32_t i2s_sck, i2s_ws, i2s_tx, i2s_rx; + uint32_t i2s_sel;; + uint8_t i2s_idx; + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + HAL_Status ret; + + // Determine the UART to use (UART0, UART1, or UART3) + i2s_sck = pinmap_peripheral(sck, PinMap_I2S_CLK); + i2s_ws = pinmap_peripheral(ws, PinMap_I2S_WS); + i2s_tx = pinmap_find_peripheral(sd, PinMap_I2S_TX); + i2s_rx = pinmap_find_peripheral(sd, PinMap_I2S_RX); + + i2s_sel = pinmap_merge(i2s_sck, i2s_ws); + if (unlikely(i2s_sel == NC)) { + DBG_I2S_ERR("%s: Cannot find matched I2S for given pin\n", __FUNCTION__); + return; + } + + if( (i2s_sel != i2s_tx) && (i2s_sel != i2s_rx)){ + DBG_I2S_ERR("%s: Cannot find matched I2S for given pin\n", __FUNCTION__); + return; + } + + i2s_idx = RTL_GET_PERI_IDX(i2s_sel); + + pI2SAdapter->DevNum = i2s_idx; + pI2SAdapter->PinMux = RTL_GET_PERI_SEL(i2s_sel);; + DBG_I2S_INFO("%s: Use I2S%d Sel%d\r\n", __FUNCTION__, pI2SAdapter->DevNum, pI2SAdapter->PinMux); + + pI2SAdapter->pInitDat = &obj->InitDat; + RtkI2SLoadDefault(pI2SAdapter, (VOID*)&I2SDefaultSetting); + + // Load user defined parameters + pI2SAdapter->pInitDat->I2SChNum = obj->channel_num; + pI2SAdapter->pInitDat->I2SRate = obj->sampling_rate; + pI2SAdapter->pInitDat->I2SWordLen = obj->word_length; + pI2SAdapter->pInitDat->I2STRxAct = obj->direction; + + //RtkI2SInit(pI2SAdapter); + ret = HalI2SInit(pI2SAdapter); + + if(ret != HAL_OK){ + DBG_I2S_ERR("%s: HalI2SInit is failure\n", __FUNCTION__); + } + +} + +void i2s_set_dma_buffer(i2s_t *obj, char *tx_buf, char *rx_buf, + uint32_t page_num, uint32_t page_size) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + u32 i; + + if ((page_num < 2) || (page_num > 4) || (page_size < 8)) { + DBG_I2S_INFO("%s: PageNum(%d) valid value is 2~4; PageSize(%d must > 8)\r\n", \ + __FUNCTION__, page_num, page_size); + return; + } + + pI2SAdapter->pInitDat->I2SPageNum = page_num - 1; + pI2SAdapter->pInitDat->I2SPageSize = page_size/4 - 1; // unit is 4-bytes + + pI2SAdapter->pInitDat->I2STxData = (u8*)tx_buf; + pI2SAdapter->pInitDat->I2SRxData = (u8*)rx_buf; + HalI2SSetDMABuf(pI2SAdapter->pInitDat); + + for (i=0;iTxPageList[i] = (uint32_t*)(tx_buf + ((page_size) * i)); + pI2SAdapter->RxPageList[i] = (uint32_t*)(rx_buf + ((page_size) * i)); + } +} + +void i2s_tx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + pI2SAdapter->UserCB.TxCCB = handler; + pI2SAdapter->UserCB.TxCBId = id; +} + +void i2s_rx_irq_handler(i2s_t *obj, i2s_irq_handler handler, uint32_t id) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + pI2SAdapter->UserCB.RxCCB = handler; + pI2SAdapter->UserCB.RxCBId = id; +} + +void i2s_set_direction(i2s_t *obj, int trx_type) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + obj->direction = trx_type; + pI2SAdapter->pInitDat->I2STRxAct = trx_type; + HalI2SSetDirection(pI2SAdapter->pInitDat); +} + +void i2s_set_param(i2s_t *obj, int channel_num, int rate, int word_len) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + obj->channel_num = channel_num; + obj->sampling_rate = rate; + obj->word_length = word_len; + pI2SAdapter->pInitDat->I2SChNum = channel_num; + pI2SAdapter->pInitDat->I2SRate = rate; + pI2SAdapter->pInitDat->I2SWordLen = word_len; + HalI2SSetChNum(pI2SAdapter->pInitDat); + HalI2SSetRate(pI2SAdapter->pInitDat); + HalI2SSetWordLen(pI2SAdapter->pInitDat); +} + +void i2s_deinit(i2s_t *obj) +{ + //RtkI2SDeInit((VOID*)&obj->I2SAdapter); + HalI2SDeInit((VOID*)&obj->I2SAdapter); +} + +int* i2s_get_tx_page(i2s_t *obj) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + u8 page_idx; + + page_idx = HalI2SGetTxPage((VOID*)pI2SAdapter->pInitDat); + if (page_idx <= pI2SAdapter->pInitDat->I2SPageNum) { + return ((int*)pI2SAdapter->TxPageList[page_idx]); + } else { + return NULL; + } +} + +void i2s_send_page(i2s_t *obj, uint32_t *pbuf) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + u32 page_num, i; + + page_num = pI2SAdapter->pInitDat->I2SPageNum + 1; + for (i=0;iTxPageList[i] == pbuf) { + HalI2SPageSend(pI2SAdapter->pInitDat, i); + break; // break the for loop + } + } + + if (i == page_num) { + DBG_I2S_ERR("i2s_send_page: the pbuf(0x%x) is not a DMA buffer\r\n", pbuf); + } +} + +void i2s_recv_page(i2s_t *obj) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + HalI2SPageRecv(pI2SAdapter->pInitDat); +} + +void i2s_enable(i2s_t *obj) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + //RtkI2SEnable(pI2SAdapter); + HalI2SEnable(pI2SAdapter); +} + +void i2s_disable(i2s_t *obj) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) &obj->I2SAdapter; + + //RtkI2SDisable(pI2SAdapter); + HalI2SDisable(pI2SAdapter); +} + +#endif // end of "#if CONFIG_I2S_EN" diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c new file mode 100644 index 0000000..fc284a7 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c @@ -0,0 +1,510 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "objects.h" +#include "log_uart_api.h" + + +#include + +const u32 log_uart_support_rate[] = { + UART_BAUD_RATE_2400, UART_BAUD_RATE_4800, UART_BAUD_RATE_9600, + UART_BAUD_RATE_19200, UART_BAUD_RATE_38400, UART_BAUD_RATE_57600, + UART_BAUD_RATE_115200, UART_BAUD_RATE_921600, UART_BAUD_RATE_1152000, + + 0xFFFFFFFF +}; + +extern HAL_TIMER_OP HalTimerOp; + +extern u32 ConfigDebugErr; +extern u32 ConfigDebugWarn; +extern u32 ConfigDebugInfo; +extern u32 CfgSysDebugErr; +extern u32 CfgSysDebugInfo; +extern u32 CfgSysDebugWarn; + +extern HAL_Status RuartIsTimeout (u32 StartCount, u32 TimeoutCnt); +extern u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter); +extern VOID HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter); +extern VOID HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter); +extern VOID HalLogUartIrqHandle(VOID * Data); + +int32_t log_uart_init (log_uart_t *obj, int baudrate, int data_bits, SerialParity parity, int stop_bits) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter; + int i; + + _memset((void*)obj, 0, sizeof(log_uart_t)); + pUartAdapter = &obj->log_hal_uart; + // Check Baud rate + for (i=0; log_uart_support_rate[i]!=0xFFFFFF; i++) { + if (log_uart_support_rate[i] == baudrate) { + break; + } + } + + if (log_uart_support_rate[i]== 0xFFFFFF) { + DBG_UART_ERR("log_uart_init: Not support Baud Rate %d\n", baudrate); + return -1; + } + + // check word width + if ((data_bits < 5) || (data_bits > 8)) { + DBG_UART_ERR("log_uart_init: Not support Word Width %d\n", data_bits); + return -1; + } + + //4 Inital Log uart + pUartAdapter->BaudRate = baudrate; + pUartAdapter->DataLength = data_bits-5; + pUartAdapter->FIFOControl = FCR_FIFO_EN | FCR_TX_TRIG_HF | FCR_RX_TRIG_HF; + // only enable Rx linstatus at initial, + // Tx & Rx interrupt will be enabled @ transfer start time + pUartAdapter->IntEnReg = IER_ELSI; + switch (parity) { + case ParityNone: + pUartAdapter->Parity = LCR_PARITY_NONE; + break; + + case ParityOdd: + pUartAdapter->Parity = LCR_PARITY_ODD; + break; + + case ParityEven: + pUartAdapter->Parity = LCR_PARITY_EVEN; + break; + + default: + DBG_UART_ERR("log_uart_init: Not support parity type %d\n", parity); + return -1; + } + + if (stop_bits > 1) { + // if width is 5 bits, stop bit will be 1.5 bit + pUartAdapter->Stop = LCR_STOP_2B; + } else { + pUartAdapter->Stop = LCR_STOP_1B; + } + + //4 Initial Log Uart + HalLogUartInitSetting(pUartAdapter); + + // disable all debug message + ConfigDebugErr = 0; + ConfigDebugWarn = 0; + ConfigDebugInfo = 0; + CfgSysDebugErr = 0; + CfgSysDebugInfo = 0; + CfgSysDebugWarn = 0; + + return 0; +} + +void log_uart_free(log_uart_t *obj) +{ + LOG_UART_ADAPTER UartAdapter; + + // Recover the Log UART for debug message printing + //4 Release log uart reset and clock + LOC_UART_FCTRL(OFF); + LOC_UART_FCTRL(ON); + ACTCK_LOG_UART_CCTRL(ON); + + //4 Inital Log uart + UartAdapter.BaudRate = DEFAULT_BAUDRATE; + UartAdapter.DataLength = UART_DATA_LEN_8BIT; + UartAdapter.FIFOControl = 0xC1; + UartAdapter.IntEnReg = 0x00; + UartAdapter.Parity = UART_PARITY_DISABLE; + UartAdapter.Stop = UART_STOP_1BIT; + + // un_register current IRQ first + InterruptUnRegister(&(obj->log_hal_uart.IrqHandle)); + + //4 Initial Log Uart + HalLogUartInit(UartAdapter); +} + +void log_uart_baud(log_uart_t *obj, int baudrate) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter; + int i; + + pUartAdapter = &obj->log_hal_uart; + // Check Baud rate + for (i=0; log_uart_support_rate[i]!=0xFFFFFFFF; i++) { + if (log_uart_support_rate[i] == baudrate) { + break; + } + } + + if (log_uart_support_rate[i]== 0xFFFFFF) { + DBG_UART_ERR("log_uart_baud: Not support Baud Rate %d\n", baudrate); + return; + } + + pUartAdapter->BaudRate = baudrate; + HalLogUartSetBaudRate(pUartAdapter); +} + +void log_uart_format(log_uart_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter; + + pUartAdapter = &obj->log_hal_uart; + + // check word width + if ((data_bits < 5) || (data_bits > 8)) { + DBG_UART_ERR("log_uart_format: Not support Word Width %d\n", data_bits); + return; + } + + //4 Inital Log uart + pUartAdapter->DataLength = data_bits - 5; + switch (parity) { + case ParityNone: + pUartAdapter->Parity = LCR_PARITY_NONE; + break; + + case ParityOdd: + pUartAdapter->Parity = LCR_PARITY_ODD; + break; + + case ParityEven: + pUartAdapter->Parity = LCR_PARITY_EVEN; + break; + + default: + DBG_UART_ERR("log_uart_format: Not support parity type %d\n", parity); + return; + } + + if (stop_bits > 1) { + // if width is 5 bits, stop bit will be 1.5 bit + pUartAdapter->Stop = LCR_STOP_2B; + } else { + pUartAdapter->Stop = LCR_STOP_1B; + } + + HalLogUartSetLineCtrl(pUartAdapter); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ +void log_uart_irq_handler(log_uart_t *obj, loguart_irq_handler handler, uint32_t id) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter; + + pUartAdapter = &(obj->log_hal_uart); + pUartAdapter->api_irq_handler = handler; + pUartAdapter->api_irq_id = id; +} + +void log_uart_irq_set(log_uart_t *obj, LOG_UART_INT_ID irq, uint32_t enable) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter; + u8 int_en=0; + + pUartAdapter = &(obj->log_hal_uart); + + switch (irq) { + case IIR_RX_RDY: + int_en = IER_ERBFI; + break; + + case IIR_THR_EMPTY: + int_en = IER_ETBEI; + break; + + case IIR_RX_LINE_STATUS: + int_en = IER_ELSI; + break; + + case IIR_MODEM_STATUS: + int_en = IER_EDSSI; + break; + + default: + DBG_UART_WARN("log_uart_irq_set: Unknown Irq Id\n"); + return; + } + + if (enable) { + pUartAdapter->IntEnReg |= int_en; + } else { + // disable + pUartAdapter->IntEnReg &= (~int_en); + } + HalLogUartSetIntEn(pUartAdapter); +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ + +char log_uart_getc(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + while (!log_uart_readable(obj)); + return (char)(HAL_UART_READ32(UART_REV_BUF_OFF) & 0xFF); +} + +void log_uart_putc(log_uart_t *obj, char c) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + while (!log_uart_writable(obj)); + HAL_UART_WRITE8(UART_TRAN_HOLD_OFF, c); +} + +int log_uart_readable(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + volatile u8 line_status; + + line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF); + + if (line_status & LSR_DR) { + return 1; + } else { + return 0; + } +} + +int log_uart_writable(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + volatile u8 line_status; + + line_status = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF); + if (line_status & LSR_THRE) { + return 1; + } else { + return 0; + } +} + +void log_uart_clear(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + HalLogUartRstFIFO(pUartAdapter, (LOG_UART_RST_TX_FIFO|LOG_UART_RST_TX_FIFO)); + pUartAdapter->TxCount = 0; + pUartAdapter->RxCount = 0; +} + +void log_uart_clear_tx(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_TX_FIFO); + pUartAdapter->TxCount = 0; +} + +void log_uart_clear_rx(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + HalLogUartRstFIFO(pUartAdapter, LOG_UART_RST_RX_FIFO); + pUartAdapter->RxCount = 0; +} + +void log_uart_break_set(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + u32 RegValue; + + RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF); + RegValue |= LCR_BC; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue); +} + +void log_uart_break_clear(log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + u32 RegValue; + + RegValue = HAL_UART_READ32(UART_LINE_CTL_REG_OFF); + RegValue &= ~LCR_BC; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RegValue); +} + +void log_uart_tx_comp_handler(log_uart_t *obj, void *handler, uint32_t id) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=(PHAL_LOG_UART_ADAPTER)&(obj->log_hal_uart); + + pUartAdapter->TxCompCallback = (void(*)(void*))handler; + pUartAdapter->TxCompCbPara = (void*)id; +} + +void log_uart_rx_comp_handler(log_uart_t *obj, void *handler, uint32_t id) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + + pUartAdapter->RxCompCallback = (void(*)(void*))handler; + pUartAdapter->RxCompCbPara = (void*)id; +} + +void log_uart_line_status_handler(log_uart_t *obj, void *handler, uint32_t id) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + + pUartAdapter->LineStatusCallback = (void(*)(void*, u8))handler; + pUartAdapter->LineStatusCbPara = (void*)id; +} + +// Blocked(busy wait) receive, return received bytes count +int32_t log_uart_recv (log_uart_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + ret = (int)HalLogUartRecv(pUartAdapter, prxbuf, len, timeout_ms); + return (ret); +} + +// Blocked(busy wait) send, return transmitted bytes count +int32_t log_uart_send (log_uart_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + ret = (int)HalLogUartSend(pUartAdapter, ptxbuf, len, timeout_ms); + return (ret); +} + +// Interrupt mode(no wait) receive, return HAL function result +int32_t log_uart_recv_stream (log_uart_t *obj, char *prxbuf, uint32_t len) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len); + return (ret); +} + +// Interrupt Mode(no wait) send, return HAL function result +int32_t log_uart_send_stream (log_uart_t *obj, char *ptxbuf, uint32_t len) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + ret = (int)HalLogUartIntSend(pUartAdapter, (u8*)ptxbuf, len); + return (ret); +} + +// Interrupt mode(no wait) receive with timeout +// return the byte count received before timeout, or error(<0) +int32_t log_uart_recv_stream_timeout (log_uart_t *obj, char *prxbuf, uint32_t len, + uint32_t timeout_ms, void *force_cs) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + uint32_t TimeoutCount=0, StartCount; + int ret; + void (*task_yield)(void); + + task_yield = NULL; + ret = (int)HalLogUartIntRecv(pUartAdapter, (u8*)prxbuf, len); + + if ((ret == HAL_OK) && (timeout_ms > 0)) { + TimeoutCount = (timeout_ms*1000/TIMER_TICK_US); + StartCount = HalTimerOp.HalTimerReadCount(1); + task_yield = (void (*)(void))force_cs; + while (pUartAdapter->RxCount > 0) { + if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) { + HalLogUartAbortIntRecv(pUartAdapter); + break; + } + if (NULL != task_yield) { + task_yield(); + } + } + return (len - pUartAdapter->RxCount); + } else { + return (-ret); + } +} + +// Abort Interrupt Mode TX and return how many bytes data has been sent +int32_t log_uart_send_stream_abort (log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + HalLogUartAbortIntSend(pUartAdapter); + + ret = (u32)pUartAdapter->pTxBuf - (u32)pUartAdapter->pTxStartAddr; + return (ret); +} + +// Abort Interrupt Mode RX and return how many bytes data has been received +int32_t log_uart_recv_stream_abort (log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + int ret; + + HalLogUartAbortIntRecv(pUartAdapter); + + ret = (u32)pUartAdapter->pRxBuf - (u32)pUartAdapter->pRxStartAddr; + return (ret); +} + +void log_uart_disable (log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + + HalLogUartDisable(pUartAdapter); +} + +void log_uart_enable (log_uart_t *obj) +{ + HAL_LOG_UART_ADAPTER *pUartAdapter=&(obj->log_hal_uart); + + HalLogUartEnable(pUartAdapter); +} + +// to read Line-Status register +// Bit 0: RX Data Ready +// Bit 1: Overrun Error +// Bit 2: Parity Error +// Bit 3: Framing Error +// Bit 4: Break Interrupt (received data input is held in 0 state for a longer than a full word tx time) +// Bit 5: TX FIFO empty (THR empty) +// Bit 6: TX FIFO empty (THR & TSR both empty) +// Bit 7: Receiver FIFO Error (parity error, framing error or break indication) +uint8_t log_uart_raed_lsr(log_uart_t *obj) +{ + uint8_t LineStatus; + + LineStatus = HAL_UART_READ8(UART_LINE_STATUS_REG_OFF); + + return LineStatus; +} + +// to read Modem-Status register +// Bit 0: DCTS, The CTS line has changed its state +// Bit 1: DDSR, The DSR line has changed its state +// Bit 2: TERI, RI line has changed its state from low to high state +// Bit 3: DDCD, DCD line has changed its state +// Bit 4: Complement of the CTS input +// Bit 5: Complement of the DSR input +// Bit 6: Complement of the RI input +// Bit 7: Complement of the DCD input +uint8_t log_uart_raed_msr(log_uart_t *obj) +{ + uint8_t RegValue; + + RegValue = HAL_UART_READ8(UART_MODEM_STATUS_REG_OFF); + return RegValue; +} + diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/nfc_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/nfc_api.c new file mode 100644 index 0000000..87aa22d --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/nfc_api.c @@ -0,0 +1,243 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include "pinmap.h" + +#if CONFIG_NFC_NORMAL + +#include "nfc_api.h" + +/** + * @brief The NFC tag write callback function wrapper + * + * @return None + * + */ +void nfc_tagwrite_callback(PNFC_ADAPTER pNFCAdp, uint32_t page, uint32_t wr_data) +{ + nfctag_t *obj; + nfc_write_cb handler; + + obj = pNFCAdp->nfc_obj; + + handler = (nfc_write_cb)obj->nfc_wr_cb; + if (NULL != handler) { + handler(obj->wr_cb_arg, page, wr_data); + } +} + +/** + * @brief The NFC tag read callback function wrapper + * + * @return None + * + */ +void nfc_event_callback(PNFC_ADAPTER pNFCAdp, uint32_t event) +{ + nfctag_t *obj; + nfc_event_cb handler; + + obj = pNFCAdp->nfc_obj; + + handler = (nfc_event_cb)obj->nfc_ev_cb; + if (NULL != handler) { + if (obj->event_mask & event) { + handler(obj->ev_cb_arg, event); + } + } +} + +/** + * @brief The NFC tag read callback function wrapper + * + * @return None + * + */ +void nfc_tagread_callback(PNFC_ADAPTER pNFCAdp, uint32_t page) +{ + // notify upper layer when read tag page 0 only + if (0 == page) { + nfc_event_callback(pNFCAdp, NFC_EV_READ); + } +} + + +/** + * @brief The NFC cache read done callback function wrapper + * + * @return None + * + */ +void nfc_cache_read_callback(PNFC_ADAPTER pNFCAdp, uint32_t start_pg, uint32_t *pbuf) +{ + nfctag_t *obj; + nfc_write_cb handler; + + obj = pNFCAdp->nfc_obj; + + handler = (nfc_write_cb)obj->nfc_cache_rd_cb; + if (NULL != handler) { + handler(obj->cache_read_cb_arg, start_pg, (uint32_t)pbuf); + } +} + +/** + * @brief To initial NFC tag hardware and resource + * + * @return The result + * + */ +int nfc_init(nfctag_t *obj, uint32_t *pg_init_val) +{ + _memset((void *)obj, 0, sizeof(nfctag_t)); + HalNFCDmemInit(pg_init_val, NFCTAGLENGTH); + HalNFCInit(&(obj->NFCAdapter)); + HalNFCFwDownload(); + obj->NFCAdapter.nfc_obj = obj; + obj->pwr_status = NFC_PWR_RUNNING; + + return NFC_OK; +} + +/** + * @brief To free NFC tag hardware and resource + * + * @return The result + * + */ +int nfc_free(nfctag_t *obj) +{ + HalNFCDeinit(&(obj->NFCAdapter)); + return NFC_OK; +} + +/** + * @brief To register the callback function for NFC read occurred + * + * @return None + * + */ +void nfc_read(nfctag_t *obj, nfc_read_cb handler, void *arg) +{ + obj->nfc_rd_cb = (void *)handler; + obj->rd_cb_arg = arg; +} + +/** + * @brief To register the callback function for NFC write occurred + * + * @return None + * + */ +void nfc_write(nfctag_t *obj, nfc_write_cb handler, void *arg) +{ + obj->nfc_wr_cb = (void *)handler; + obj->wr_cb_arg = arg; +} + +/** + * @brief To register the callback function for NFC events occurred + * and the event mask + * + * @return None + * + */ +void nfc_event(nfctag_t *obj, nfc_event_cb handler, void *arg, unsigned int event_mask) +{ + obj->nfc_ev_cb = (void *)handler; + obj->ev_cb_arg = arg; + obj->event_mask = event_mask; +} + +/** + * @brief To set a new power mode to the NFC device + * + * @return The result + * + */ +int nfc_power(nfctag_t *obj, int pwr_mode, int wake_event) +{ + // TODO: + + return NFC_OK; +} + + +/** + * @brief to update the NFC read cache. The data in the NFC read cache + * buffer will be transmitted out when NFC read occurred + * + * @return The result + * + */ +int nfc_cache_write(nfctag_t *obj, uint32_t *tbuf, unsigned int spage, unsigned int pg_num) +{ + u8 remain_pg; + u8 pg_offset=0; + u8 i; + + if ((spage+pg_num) > NFC_MAX_CACHE_PAGE_NUM) { + return NFC_ERROR; + } + + remain_pg = pg_num; + while (remain_pg > 0) { + if (remain_pg >= 4) { + A2NWriteCatch (&obj->NFCAdapter, (spage+pg_offset), 4, (u32*)(&tbuf[pg_offset])); + remain_pg -= 4; + pg_offset += 4; + } + else { + for(i=0;iNFCAdapter, (spage+pg_offset), 1, (u32*)(&tbuf[pg_offset])); + pg_offset++; + } + remain_pg = 0; + } + } + + return NFC_OK; +} + +/** + * @brief To get current NFC status + * + * @return The result + * + */ +int nfc_cache_raed(nfctag_t *obj, nfc_cache_read_cb handler, + void *arg, unsigned int start_pg) +{ + if (start_pg > NFC_MAX_CACHE_PAGE_NUM) { + return NFC_ERROR; + } + + obj->nfc_cache_rd_cb = (void *)handler; + obj->cache_read_cb_arg = arg; + + A2NReadCatch(&(obj->NFCAdapter), (u8)start_pg); + + return NFC_OK; +} + +/** + * @brief to read back the NFC read cache. + * + * @return The result + * + */ +int nfc_status(nfctag_t *obj) +{ + // TODO: + + return (obj->pwr_status); +} + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/objects.h b/USDK/component/common/mbed/targets/hal/rtl8195a/objects.h new file mode 100644 index 0000000..4bae9ea --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/objects.h @@ -0,0 +1,207 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MBED_OBJECTS_H +#define MBED_OBJECTS_H + +#include "cmsis.h" +#include "PortNames.h" +#include "PeripheralNames.h" +#include "PinNames.h" +#include "platform_autoconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_GPIO_EN +struct gpio_irq_s { + PinName pin; + uint32_t event; + HAL_GPIO_PIN hal_pin; + uint8_t hal_port_num; + uint8_t hal_pin_num; +}; + +typedef struct gpio_irq_s gpio_irq_t; + +struct gpio_s { + PinName pin; + PinMode mode; + PinDirection direction; + HAL_GPIO_PIN hal_pin; + uint8_t hal_port_num; + uint8_t hal_pin_num; +}; + +typedef struct gpio_s gpio_t; + +struct port_s { + PortName port; + uint32_t mask; + PinDirection direction; + uint8_t *pin_def; +}; +#endif // end of "#ifdef CONFIG_GPIO_EN" + +#ifdef CONFIG_UART_EN +struct serial_s { + HAL_RUART_OP hal_uart_op; + HAL_RUART_ADAPTER hal_uart_adp; +#ifdef CONFIG_GDMA_EN + UART_DMA_CONFIG uart_gdma_cfg; + HAL_GDMA_ADAPTER uart_gdma_adp_tx; + HAL_GDMA_ADAPTER uart_gdma_adp_rx; + UART_DMA_MULTIBLK gdma_multiblk_list_tx; + UART_DMA_MULTIBLK gdma_multiblk_list_rx; +#endif + uint32_t tx_len; + uint32_t rx_len; +}; +#endif // end of "#ifdef CONFIG_UART_EN" + +struct log_uart_s { + HAL_LOG_UART_ADAPTER log_hal_uart; +}; + +#ifdef CONFIG_SPI_COM_EN + +#endif + +#ifdef CONFIG_PWM_EN +struct pwmout_s { + uint8_t pwm_idx; + uint8_t pin_sel; + uint32_t period; + uint32_t pulse; + HAL_PWM_ADAPTER pwm_hal_adp; +}; +#endif + +#ifdef CONFIG_I2C_EN +struct i2c_s { + SAL_I2C_MNGT_ADPT SalI2CMngtAdpt; + SAL_I2C_HND_PRIV SalI2CHndPriv; + HAL_I2C_INIT_DAT HalI2CInitData; + HAL_I2C_OP HalI2COp; + IRQ_HANDLE I2CIrqHandleDat; + HAL_GDMA_ADAPTER HalI2CTxGdmaAdpt; + HAL_GDMA_ADAPTER HalI2CRxGdmaAdpt; + HAL_GDMA_OP HalI2CGdmaOp; + IRQ_HANDLE I2CTxGdmaIrqHandleDat; + IRQ_HANDLE I2CRxGdmaIrqHandleDat; + SAL_I2C_USER_CB SalI2CUserCB; + SAL_I2C_USERCB_ADPT SalI2CUserCBAdpt[SAL_USER_CB_NUM]; + SAL_I2C_DMA_USER_DEF SalI2CDmaUserDef; +}; +#endif + + +struct flash_s +{ + SPIC_INIT_PARA SpicInitPara; + u32 Length; +}; + + + +#ifdef CONFIG_ADC_EN +struct analogin_s { + SAL_ADC_MNGT_ADPT SalADCMngtAdpt; + SAL_ADC_HND_PRIV SalADCHndPriv; + HAL_ADC_INIT_DAT HalADCInitData; + HAL_ADC_OP HalADCOp; + IRQ_HANDLE ADCIrqHandleDat; + HAL_GDMA_ADAPTER HalADCGdmaAdpt; + HAL_GDMA_OP HalADCGdmaOp; + IRQ_HANDLE ADCGdmaIrqHandleDat; + SAL_ADC_USER_CB SalADCUserCB; + SAL_ADC_USERCB_ADPT SalADCUserCBAdpt[SAL_ADC_USER_CB_NUM]; +}; +#endif + +#if 0 +struct i2c_s { + I2C_Type *i2c; +}; + +struct spi_s { + SPI_Type *spi; +}; + +#endif + +#ifdef CONFIG_NFC_EN +struct nfctag_s { + NFC_ADAPTER NFCAdapter; + void *nfc_rd_cb; // read callback function + void *rd_cb_arg; + void *nfc_wr_cb; // write callback function + void *wr_cb_arg; + void *nfc_ev_cb; // event callback function + void *ev_cb_arg; + void *nfc_cache_rd_cb; // cache read callback function + void *cache_read_cb_arg; + unsigned int event_mask; + int pwr_status; +}; +#endif + +#ifdef CONFIG_TIMER_EN +struct gtimer_s { + TIMER_ADAPTER hal_gtimer_adp; + void *handler; + u32 hid; + u8 timer_id; + u8 is_periodcal; +}; +#endif + +#ifdef CONFIG_I2S_EN +struct i2s_s { + HAL_I2S_ADAPTER I2SAdapter; + HAL_I2S_INIT_DAT InitDat; + u8 sampling_rate; + u8 channel_num; + u8 word_length; + u8 direction; +}; + +#endif + +#ifdef CONFIG_DAC_EN +/** \file objects.h + * \brief A Documented file. + * + * A documented file. +*/ + +/** \struct dac_s objects.h "rtl8195a/objects.h" + * \brief This is a dac_s structure. + * + * For analogout APIs, a pointer to dac_s is used as an input paras. + * A DAC initial data structure is the major element of dac_s. + */ +struct dac_s { + HAL_DAC_INIT_DAT DACpara; +}; +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap.c b/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap.c new file mode 100644 index 0000000..c0dfdf0 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap.c @@ -0,0 +1,34 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +//#include "mbed_assert.h" +#include "objects.h" +#include "pinmap.h" +//#include "error.h" + +/** + * Configure pin enable and function + */ +void pin_function(PinName pin, int function) +{ + // MBED_ASSERT(pin != (PinName)NC); + //1 Our HAL API cannot support to configure the pin function by this way + /* the pin function (pin mux) is depends on each IP On/Off and priority, so we cannot + set the pin function directly */ +} + +/** + * Configure pin pull-up/pull-down + */ +void pin_mode(PinName pin, PinMode mode) +{ +// MBED_ASSERT(pin != (PinName)NC); + HAL_GPIO_PullCtrl((u32)pin, (u32)mode); + +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap_common.c b/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap_common.c new file mode 100644 index 0000000..1a1001a --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/pinmap_common.c @@ -0,0 +1,73 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "basic_types.h" +#include "diag.h" +#include "pinmap.h" +//#include "error.h" + +__weak void pinmap_pinout(PinName pin, const PinMap *map) { +#if 0 + if (pin == NC) + return; + + while (map->pin != NC) { + if (map->pin == pin) { + pin_function(pin, map->function); + + pin_mode(pin, PullNone); + return; + } + map++; + } + DBG_GPIO_ERR("%s: could not pinout\n", __FUNCTION__); +#endif +} + +__weak uint32_t pinmap_merge(uint32_t a, uint32_t b) { + // both are the same (inc both NC) + if (a == b) + return a; + + // one (or both) is not connected + if (a == (uint32_t)NC) + return b; + if (b == (uint32_t)NC) + return a; + + // mis-match error case + DBG_GPIO_ERR("%s: pinmap mis-match\n", __FUNCTION__); + return (uint32_t)NC; +} + +__weak uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) { + while (map->pin != NC) { + if (map->pin == pin) + return map->peripheral; + map++; + } + return (uint32_t)NC; +} + +__weak uint32_t pinmap_peripheral(PinName pin, const PinMap* map) { + uint32_t peripheral = (uint32_t)NC; + + if (pin == (PinName)NC) + return (uint32_t)NC; + peripheral = pinmap_find_peripheral(pin, map); + if ((uint32_t)NC == peripheral) // no mapping available + DBG_GPIO_ERR("%s: pinmap not found for peripheral\n", __FUNCTION__); + return peripheral; +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/port_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/port_api.c new file mode 100644 index 0000000..5457cab --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/port_api.c @@ -0,0 +1,212 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include "port_api.h" +#include "pinmap.h" +#include "gpio_api.h" +#include "PinNames.h" +//#include "mbed_error.h" + +#if CONFIG_GPIO_EN + +#if DEVICE_PORTIN || DEVICE_PORTOUT + +#define GPIO_PORT_NUM 3 +#define GPIO_PORT_WIDTH 32 +#define GPIO_PORT_WIDTH_MAX 32 + +const u8 Default_Port_PinDef[GPIO_PORT_NUM][GPIO_PORT_WIDTH+1] = { + // Port 0 has these pin: + {PA_0, PA_1, PB_3, PB_4, + PB_6, PB_7, PC_1, PC_3, + PC_4, PC_5, PC_6, PC_7, + PC_8, PC_9, PD_1, PD_3, + PD_4, PD_5, PD_6, PD_7, + PD_9, PE_1, PE_2, PE_3, + PE_5, PE_6, PE_7, PE_8, + PG_3, PH_1, PH_3, PH_5, + 0xFF}, + + // Port 1 + {PA_2, PA_3, PA_4, PA_5, + PA_6, PA_7, PB_0, PB_1, + PB_2, PB_5, PC_0, PC_2, + PD_0, PD_2, PD_8, PE_0, + PE_4, PE_9, PE_A, PF_0, + PF_1, PF_2, PF_3, PF_4, + PF_5, PG_0, PG_1, PG_2, + PG_4, PG_5, PG_6, PG_7, + 0xFF}, + + // Port 2 + {PH_0, PH_2, PH_4, PH_6, + PH_7, PI_0, PI_1, PI_2, + PI_3, PI_4, PI_5, PI_6, + PI_7, PJ_0, PJ_1, PJ_2, + PJ_3, PJ_4, PJ_5, PJ_6, + PK_0, PK_1, PK_2, PK_3, + PK_4, PK_5, PK_6, + 0xFF} + +}; + +extern const u8 GPIO_SWPORT_DR_TBL[]; +extern const u8 GPIO_EXT_PORT_TBL[]; + +extern VOID HAL_GPIO_Init(HAL_GPIO_PIN *GPIO_Pin); +extern u32 HAL_GPIO_GetPinName(u32 chip_pin); + +// high nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, ...) +// low nibble = pin number +PinName port_pin(PortName port, int pin_n) { + return (PinName)(pin_n + (port << 4)); +} + +void port_init(port_t *obj, PortName port, int mask, PinDirection dir) +{ + u32 i; + + if (port >= GPIO_PORT_NUM) { + DBG_GPIO_ERR("port_init: Invalid port num(%d), max port num is %d\r\n", \ + port, (GPIO_PORT_NUM-1)); + } + + // Fill PORT object structure for future use + obj->port = port; + obj->mask = mask; + obj->direction = dir; + + if (obj->pin_def == NULL) { + DBG_GPIO_ERR("Port Define Table isn't assigned\n"); + obj->pin_def = (uint8_t*)&Default_Port_PinDef[port][0]; + } + + i=0; + while (obj->pin_def[i] != 0xff) { + i++; + if (i == GPIO_PORT_WIDTH_MAX) { + break; + } + } + + obj->mask &= ((1<direction = dir; + for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins + if (obj->pin_def[i] == 0xff) { + // end of table + break; + } + if (obj->mask & (1 << i)) { // If the pin is used + + GPIO_Pin.pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name + + if (dir == PIN_OUTPUT) { + GPIO_Pin.pin_mode = DOUT_PUSH_PULL; + } else { // PIN_INPUT + GPIO_Pin.pin_mode = DIN_PULL_NONE; + } + HAL_GPIO_Init(&GPIO_Pin); + } + } +} + +void port_mode(port_t *obj, PinMode mode) +{ + uint32_t i; + + for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins + if (obj->pin_def[i] == 0xff) { + // end of table + break; + } + if (obj->mask & (1 << i)) { // If the pin is used + pin_mode(obj->pin_def[i], mode); + } + } +} + +void port_write(port_t *obj, int value) +{ + uint32_t i; + uint32_t pin_name; + uint8_t port_num; + uint8_t pin_num; + uint32_t hal_port[3]; + uint8_t port_changed[3]; + + for (i=0;i<3;i++) { + hal_port[i] = HAL_READ32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[i]); + port_changed[i] = 0; + } + + for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins + if (obj->pin_def[i] == 0xff) { + // end of table + break; + } + if (obj->mask & (1 << i)) { // If the pin is used + pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name + port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name); + hal_port[port_num] &= ~(1 << pin_num); + hal_port[port_num] |= (((value>>i) & 0x01)<< pin_num); + port_changed[port_num] = 1; + } + } + + for (i=0;i<3;i++) { + if (port_changed[i]) { + HAL_WRITE32(GPIO_REG_BASE, GPIO_SWPORT_DR_TBL[i], hal_port[i]); + } + } + +} + +int port_read(port_t *obj) +{ + int value=0; + u32 i; + uint32_t pin_name; + uint8_t port_num; + uint8_t pin_num; + uint32_t hal_port[3]; + + for (i=0;i<3;i++) { + hal_port[i] = HAL_READ32(GPIO_REG_BASE, GPIO_EXT_PORT_TBL[i]); + } + + for (i = 0; i < GPIO_PORT_WIDTH_MAX; i++) { // Process all pins + if (obj->pin_def[i] == 0xff) { + // end of table + break; + } + if (obj->mask & (1 << i)) { // If the pin is used + pin_name = HAL_GPIO_GetPinName(obj->pin_def[i]); // get the IP pin name + port_num = HAL_GPIO_GET_PORT_BY_NAME(pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(pin_name); + if (hal_port[port_num] & (1< + +#if DEVICE_PWMOUT + +#ifdef CONFIG_PWM_EN +#include "pwmout_api.h" +#include "objects.h" + +extern u32 gTimerRecord; + +const PinMap PinMap_PWM[] = { + {PB_4, RTL_PIN_PERI(PWM0, 0, S0), RTL_PIN_FUNC(PWM0, S0)}, + {PB_5, RTL_PIN_PERI(PWM1, 1, S0), RTL_PIN_FUNC(PWM1, S0)}, + {PB_6, RTL_PIN_PERI(PWM2, 2, S0), RTL_PIN_FUNC(PWM2, S0)}, + {PB_7, RTL_PIN_PERI(PWM3, 3, S0), RTL_PIN_FUNC(PWM3, S0)}, + + {PC_0, RTL_PIN_PERI(PWM0, 0, S1), RTL_PIN_FUNC(PWM0, S1)}, + {PC_1, RTL_PIN_PERI(PWM1, 1, S1), RTL_PIN_FUNC(PWM1, S1)}, + {PC_2, RTL_PIN_PERI(PWM2, 2, S1), RTL_PIN_FUNC(PWM2, S1)}, + {PC_3, RTL_PIN_PERI(PWM3, 3, S1), RTL_PIN_FUNC(PWM3, S1)}, + + {PD_3, RTL_PIN_PERI(PWM0, 0, S2), RTL_PIN_FUNC(PWM0, S2)}, + {PD_4, RTL_PIN_PERI(PWM1, 1, S2), RTL_PIN_FUNC(PWM1, S2)}, + {PD_5, RTL_PIN_PERI(PWM2, 2, S2), RTL_PIN_FUNC(PWM2, S2)}, + {PD_6, RTL_PIN_PERI(PWM3, 3, S2), RTL_PIN_FUNC(PWM3, S2)}, + + {PE_0, RTL_PIN_PERI(PWM0, 0, S3), RTL_PIN_FUNC(PWM0, S3)}, + {PE_1, RTL_PIN_PERI(PWM1, 1, S3), RTL_PIN_FUNC(PWM1, S3)}, + {PE_2, RTL_PIN_PERI(PWM2, 2, S3), RTL_PIN_FUNC(PWM2, S3)}, + {PE_3, RTL_PIN_PERI(PWM3, 3, S3), RTL_PIN_FUNC(PWM3, S3)}, + + {NC, NC, 0} +}; + +int pwmout_init(pwmout_t* obj, PinName pin) +{ + uint32_t peripheral; + u32 pwm_idx; + u32 pin_sel; + + DBG_PWM_INFO("%s: Init PWM for pin(0x%x)\n", __FUNCTION__, pin); + + // Get the peripheral name from the pin and assign it to the object + peripheral = pinmap_peripheral(pin, PinMap_PWM); + + if (unlikely(peripheral == NC)) { + DBG_PWM_ERR("%s: Cannot find matched pwm for this pin(0x%x)\n", __FUNCTION__, pin); + return -1; + } + + pwm_idx = RTL_GET_PERI_IDX(peripheral); + pin_sel = RTL_GET_PERI_SEL(peripheral); + + obj->pwm_idx = pwm_idx; + obj->pin_sel = pin_sel; + obj->period = 0; + obj->pulse = 0; + rtl_memset((void *)&obj->pwm_hal_adp, 0, sizeof(HAL_PWM_ADAPTER)); + if (HAL_OK != HAL_Pwm_Init(&obj->pwm_hal_adp, pwm_idx, pin_sel)) { + DBG_PWM_ERR("pwmout_init Err!\n"); + return -1; + } +// pwmout_period_us(obj, 20000); // 20 ms per default +// HAL_Pwm_Enable(&obj->pwm_hal_adp); + return 0; +} + +void pwmout_free(pwmout_t* obj) +{ + HAL_Pwm_Disable(&obj->pwm_hal_adp); + gTimerRecord &= ~(1 << obj->pwm_hal_adp.gtimer_id); +} + +void pwmout_period_us(pwmout_t* obj, uint32_t us) +{ + obj->period = us; + HAL_Pwm_SetDuty(&obj->pwm_hal_adp, us, obj->pulse); +} + +void pwmout_pulsewidth_us(pwmout_t* obj, uint32_t us) +{ + obj->pulse = us; + if(us > obj->period) obj->period = us; + HAL_Pwm_SetDuty(&obj->pwm_hal_adp, obj->period, us); +} + +#endif // #ifdef CONFIG_PWM_EN +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/rtc_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/rtc_api.c new file mode 100644 index 0000000..bfdf1b1 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/rtc_api.c @@ -0,0 +1,120 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2015, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + *******************************************************************************/ +#include "rtc_api.h" + +#if DEVICE_RTC +#include +#include "timer_api.h" // software-RTC: use a g-timer for the tick of the RTC + +#define SW_RTC_TIMER_ID TIMER4 + +static gtimer_t sw_rtc; +static struct tm rtc_timeinfo; +static int sw_rtc_en=0; + +const static u8 dim[14] = { + 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28 }; + +static inline bool is_leap_year(unsigned int year) +{ + return (!(year % 4) && (year % 100)) || !(year % 400); +} + + +static u8 days_in_month (u8 month, u8 year) +{ + u8 ret = dim [ month - 1 ]; + if (ret == 0) + ret = is_leap_year (year) ? 29 : 28; + return ret; +} + +void sw_rtc_tick_handler(uint32_t id) +{ + if(++rtc_timeinfo.tm_sec > 59) { // Increment seconds, check for overflow + rtc_timeinfo.tm_sec = 0; // Reset seconds + if(++rtc_timeinfo.tm_min > 59) { // Increment minutes, check for overflow + rtc_timeinfo.tm_min = 0; // Reset minutes + if(++rtc_timeinfo.tm_hour > 23) { // Increment hours, check for overflow + rtc_timeinfo.tm_hour = 0; // Reset hours + ++rtc_timeinfo.tm_yday; // Increment day of year + if(++rtc_timeinfo.tm_wday > 6) // Increment day of week, check for overflow + rtc_timeinfo.tm_wday = 0; // Reset day of week + // Increment day of month, check for overflow + if(++rtc_timeinfo.tm_mday > + days_in_month(rtc_timeinfo.tm_mon, rtc_timeinfo.tm_year + 1900)) { + rtc_timeinfo.tm_mday = 1; // Reset day of month + if(++rtc_timeinfo.tm_mon > 11) { // Increment month, check for overflow + rtc_timeinfo.tm_mon = 0; // Reset month + rtc_timeinfo.tm_yday = 0; // Reset day of year + ++rtc_timeinfo.tm_year; // Increment year + } // - year + } // - month + } // - day + } // - hour + } +} + +void rtc_init(void) +{ + // Initial a periodical timer + gtimer_init(&sw_rtc, SW_RTC_TIMER_ID); + // Tick every 1 sec + gtimer_start_periodical(&sw_rtc, 1000000, (void*)sw_rtc_tick_handler, (uint32_t)&sw_rtc); + sw_rtc_en = 1; +} + +void rtc_free(void) +{ + sw_rtc_en = 0; + gtimer_stop(&sw_rtc); + gtimer_deinit(&sw_rtc); +} + +int rtc_isenabled(void) +{ + return(sw_rtc_en); +} + +time_t rtc_read(void) +{ + time_t t; + + // Convert to timestamp + t = mktime(&rtc_timeinfo); + + return t; +} + +void rtc_write(time_t t) +{ + // Convert the time in to a tm + struct tm *timeinfo = localtime(&t); + + if (timeinfo == NULL) { + // Error + return; + } + + gtimer_stop(&sw_rtc); + + // Set the RTC + rtc_timeinfo.tm_sec = timeinfo->tm_sec; + rtc_timeinfo.tm_min = timeinfo->tm_min; + rtc_timeinfo.tm_hour = timeinfo->tm_hour; + rtc_timeinfo.tm_mday = timeinfo->tm_mday; + rtc_timeinfo.tm_wday = timeinfo->tm_wday; + rtc_timeinfo.tm_yday = timeinfo->tm_yday; + rtc_timeinfo.tm_mon = timeinfo->tm_mon; + rtc_timeinfo.tm_year = timeinfo->tm_year; + + gtimer_start(&sw_rtc); +} + +#endif // endof "#if DEVICE_RTC" diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/serial_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/serial_api.c new file mode 100644 index 0000000..af21347 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/serial_api.c @@ -0,0 +1,800 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "objects.h" +//#include "mbed_assert.h" +#include "serial_api.h" +#include "serial_ex_api.h" + +#if CONFIG_UART_EN + +//#include "cmsis.h" +#include "pinmap.h" +#include + +static const PinMap PinMap_UART_TX[] = { + {PC_3, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)}, + {PE_0, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)}, + {PA_7, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)}, // None RTL8710AF + {PD_3, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)}, // None RTL8710AF, RTL8711AM + {PE_4, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)}, + {PB_5, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)}, // None RTL8710AF, RTL8711AM + {PA_4, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)}, // None RTL8711AM + {PC_9, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)}, // None RTL8710AF, RTL8711AM + {PD_7, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)}, // None RTL8710AF, RTL8711AM + {NC, NC, 0} +}; + +static const PinMap PinMap_UART_RX[] = { + {PC_0, RTL_PIN_PERI(UART0, 0, S0), RTL_PIN_FUNC(UART0, S0)}, // No Interrupt Source? + {PE_3, RTL_PIN_PERI(UART0, 0, S1), RTL_PIN_FUNC(UART0, S1)}, + {PA_6, RTL_PIN_PERI(UART0, 0, S2), RTL_PIN_FUNC(UART0, S2)}, // None RTL8710AF, // No Interrupt Source? + {PD_0, RTL_PIN_PERI(UART1, 1, S0), RTL_PIN_FUNC(UART1, S0)}, // None RTL8710AF, RTL8711AM + {PE_7, RTL_PIN_PERI(UART1, 1, S1), RTL_PIN_FUNC(UART1, S1)}, // None RTL8710AF, RTL8711AM + {PB_4, RTL_PIN_PERI(UART1, 1, S2), RTL_PIN_FUNC(UART1, S2)}, // None RTL8710AF, RTL8711AM + {PA_0, RTL_PIN_PERI(UART2, 2, S0), RTL_PIN_FUNC(UART2, S0)}, // None RTL8711AM + {PC_6, RTL_PIN_PERI(UART2, 2, S1), RTL_PIN_FUNC(UART2, S1)}, // None RTL8710AF, RTL8711AM + {PD_4, RTL_PIN_PERI(UART2, 2, S2), RTL_PIN_FUNC(UART2, S2)}, // None RTL8710AF, RTL8711AM + {NC, NC, 0} +}; + +#define UART_NUM (3) +#define SERIAL_TX_IRQ_EN 0x01 +#define SERIAL_RX_IRQ_EN 0x02 +#define SERIAL_TX_DMA_EN 0x01 +#define SERIAL_RX_DMA_EN 0x02 + +static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0}; // , 0 + +static uart_irq_handler irq_handler[UART_NUM]; +static uint32_t serial_irq_en[UART_NUM] = {0, 0, 0}; // , 0 + +#ifdef CONFIG_GDMA_EN +static uint32_t serial_dma_en[UART_NUM] = {0, 0, 0}; // , 0 +static HAL_GDMA_OP UartGdmaOp; +#endif + +#ifdef CONFIG_MBED_ENABLED +int stdio_uart_inited = 0; +serial_t stdio_uart; +#endif + +static void SerialTxDoneCallBack(VOID *pAdapter); +static void SerialRxDoneCallBack(VOID *pAdapter); + +void serial_init(serial_t *obj, PinName tx, PinName rx) +{ + uint32_t uart_tx, uart_rx; + uint32_t uart_sel; + uint8_t uart_idx; + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter; +#ifdef CONFIG_GDMA_EN + PUART_DMA_CONFIG pHalRuartDmaCfg; + PHAL_GDMA_OP pHalGdmaOp=&UartGdmaOp; +#endif + + // Determine the UART to use (UART0, UART1, or UART3) + uart_tx = pinmap_peripheral(tx, PinMap_UART_TX); + uart_rx = pinmap_peripheral(rx, PinMap_UART_RX); + + uart_sel = pinmap_merge(uart_tx, uart_rx); + uart_idx = RTL_GET_PERI_IDX(uart_sel); + if (unlikely(uart_idx == (uint8_t)NC)) { + DBG_UART_ERR("%s: Cannot find matched UART\n", __FUNCTION__); + return; + } + + pHalRuartOp = &(obj->hal_uart_op); + pHalRuartAdapter = &(obj->hal_uart_adp); + + if ((NULL == pHalRuartOp) || (NULL == pHalRuartAdapter)) { + DBG_UART_ERR("%s: Allocate Adapter Failed\n", __FUNCTION__); + return; + } + + HalRuartOpInit((VOID*)pHalRuartOp); + +#ifdef CONFIG_GDMA_EN + HalGdmaOpInit((VOID*)pHalGdmaOp); + pHalRuartDmaCfg = &obj->uart_gdma_cfg; + pHalRuartDmaCfg->pHalGdmaOp = pHalGdmaOp; + pHalRuartDmaCfg->pTxHalGdmaAdapter = &obj->uart_gdma_adp_tx; + pHalRuartDmaCfg->pRxHalGdmaAdapter = &obj->uart_gdma_adp_rx; + pHalRuartDmaCfg->pTxDmaBlkList = &obj->gdma_multiblk_list_tx; + pHalRuartDmaCfg->pRxDmaBlkList = &obj->gdma_multiblk_list_rx; + _memset((void*)(pHalRuartDmaCfg->pTxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER)); + _memset((void*)(pHalRuartDmaCfg->pRxHalGdmaAdapter), 0, sizeof(HAL_GDMA_ADAPTER)); + _memset((void*)(pHalRuartDmaCfg->pTxDmaBlkList), 0, sizeof(UART_DMA_MULTIBLK)); + _memset((void*)(pHalRuartDmaCfg->pRxDmaBlkList), 0, sizeof(UART_DMA_MULTIBLK)); +#endif + + pHalRuartOp->HalRuartAdapterLoadDef(pHalRuartAdapter, uart_idx); + pHalRuartAdapter->PinmuxSelect = RTL_GET_PERI_SEL(uart_sel); + pHalRuartAdapter->BaudRate = 9600; + pHalRuartAdapter->IrqHandle.Priority = 6; + + // Configure the UART pins + // TODO: +// pinmap_pinout(tx, PinMap_UART_TX); +// pinmap_pinout(rx, PinMap_UART_RX); +// pin_mode(tx, PullUp); +// pin_mode(rx, PullUp); + + if (HalRuartInit(pHalRuartAdapter) != HAL_OK) { + DBG_UART_ERR("serial_init Err!\n"); + return; + } + pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter); + pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter); + +#ifdef CONFIG_MBED_ENABLED + // For stdio management + if (uart_idx == STDIO_UART) { + stdio_uart_inited = 1; + memcpy(&stdio_uart, obj, sizeof(serial_t)); + } +#endif +} + +void serial_free(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; +#ifdef CONFIG_GDMA_EN + u8 uart_idx; + PUART_DMA_CONFIG pHalRuartDmaCfg; +#endif + + pHalRuartAdapter = &(obj->hal_uart_adp); + + HalRuartDeInit(pHalRuartAdapter); + +#ifdef CONFIG_GDMA_EN + uart_idx = pHalRuartAdapter->UartIndex; + pHalRuartDmaCfg = &obj->uart_gdma_cfg; + if (serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN) { + HalRuartRxGdmaDeInit(pHalRuartDmaCfg); + serial_dma_en[uart_idx] &= ~SERIAL_RX_DMA_EN; + } + + if (serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN) { + HalRuartTxGdmaDeInit(pHalRuartDmaCfg); + serial_dma_en[uart_idx] &= ~SERIAL_TX_DMA_EN; + } +#endif +} + +void serial_baud(serial_t *obj, int baudrate) { + PHAL_RUART_ADAPTER pHalRuartAdapter; + //PHAL_RUART_OP pHalRuartOp; + + pHalRuartAdapter = &(obj->hal_uart_adp); + //pHalRuartOp = &(obj->hal_uart_op); + + pHalRuartAdapter->BaudRate = baudrate; +// HalRuartInit(pHalRuartAdapter); + HalRuartSetBaudRate((VOID*)pHalRuartAdapter); +} + +void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + //PHAL_RUART_OP pHalRuartOp; + + pHalRuartAdapter = &(obj->hal_uart_adp); + //pHalRuartOp = &(obj->hal_uart_op); + + if (data_bits == 8) { + pHalRuartAdapter->WordLen = RUART_WLS_8BITS; + } else { + pHalRuartAdapter->WordLen = RUART_WLS_7BITS; + } + + + switch (parity) { + case ParityOdd: + case ParityForced0: + pHalRuartAdapter->Parity = RUART_PARITY_ENABLE; + pHalRuartAdapter->ParityType = RUART_ODD_PARITY; + break; + case ParityEven: + case ParityForced1: + pHalRuartAdapter->Parity = RUART_PARITY_ENABLE; + pHalRuartAdapter->ParityType = RUART_EVEN_PARITY; + break; + default: // ParityNone + pHalRuartAdapter->Parity = RUART_PARITY_DISABLE; + break; + } + + if (stop_bits == 2) { + pHalRuartAdapter->StopBit = RUART_STOP_BIT_2; + } else { + pHalRuartAdapter->StopBit = RUART_STOP_BIT_1; + } + + HalRuartInit(pHalRuartAdapter); +} + +/****************************************************************************** + * INTERRUPTS HANDLING + ******************************************************************************/ + +static void SerialTxDoneCallBack(VOID *pAdapter) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = pAdapter; + u8 uart_idx = pHalRuartAdapter->UartIndex; + + // Mask UART TX FIFO empty + pHalRuartAdapter->Interrupts &= ~RUART_IER_ETBEI; + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + + if (irq_handler[uart_idx] != NULL) { + irq_handler[uart_idx](serial_irq_ids[uart_idx], TxIrq); + } +} + +static void SerialRxDoneCallBack(VOID *pAdapter) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = pAdapter; + u8 uart_idx = pHalRuartAdapter->UartIndex; + + if (irq_handler[uart_idx] != NULL) { + irq_handler[uart_idx](serial_irq_ids[uart_idx], RxIrq); + } +} + +void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; +// PHAL_RUART_OP pHalRuartOp; + u8 uart_idx; + + pHalRuartAdapter = &(obj->hal_uart_adp); +// pHalRuartOp = &(obj->hal_uart_op); + + uart_idx = pHalRuartAdapter->UartIndex; + + irq_handler[uart_idx] = handler; + serial_irq_ids[uart_idx] = id; + + pHalRuartAdapter->TxTDCallback = SerialTxDoneCallBack; + pHalRuartAdapter->TxTDCbPara = (void*)pHalRuartAdapter; + pHalRuartAdapter->RxDRCallback = SerialRxDoneCallBack; + pHalRuartAdapter->RxDRCbPara = (void*)pHalRuartAdapter; + +// pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter); +// pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter); +} + + +void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + PHAL_RUART_OP pHalRuartOp; + u8 uart_idx; + + pHalRuartAdapter = &(obj->hal_uart_adp); + pHalRuartOp = &(obj->hal_uart_op); + uart_idx = pHalRuartAdapter->UartIndex; + + if (enable) { + if (irq == RxIrq) { + pHalRuartAdapter->Interrupts |= RUART_IER_ERBI | RUART_IER_ELSI; + serial_irq_en[uart_idx] |= SERIAL_RX_IRQ_EN; + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + } + else { + serial_irq_en[uart_idx] |= SERIAL_TX_IRQ_EN; + } + pHalRuartOp->HalRuartRegIrq(pHalRuartAdapter); + pHalRuartOp->HalRuartIntEnable(pHalRuartAdapter); + } + else { // disable + if (irq == RxIrq) { + pHalRuartAdapter->Interrupts &= ~(RUART_IER_ERBI | RUART_IER_ELSI); + serial_irq_en[uart_idx] &= ~SERIAL_RX_IRQ_EN; + } + else { + pHalRuartAdapter->Interrupts &= ~RUART_IER_ETBEI; + serial_irq_en[uart_idx] &= ~SERIAL_TX_IRQ_EN; + } + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + if (pHalRuartAdapter->Interrupts == 0) { + InterruptUnRegister(&pHalRuartAdapter->IrqHandle); + InterruptDis(&pHalRuartAdapter->IrqHandle); + } + } +} + +/****************************************************************************** + * READ/WRITE + ******************************************************************************/ + +int serial_getc(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + + while (!serial_readable(obj)); + return (int)((HAL_RUART_READ32(uart_idx, RUART_REV_BUF_REG_OFF)) & 0xFF); +} + +void serial_putc(serial_t *obj, int c) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + + while (!serial_writable(obj)); + HAL_RUART_WRITE32(uart_idx, RUART_TRAN_HOLD_REG_OFF, (c & 0xFF)); + + if (serial_irq_en[uart_idx] & SERIAL_TX_IRQ_EN) { + // UnMask TX FIFO empty IRQ + pHalRuartAdapter->Interrupts |= RUART_IER_ETBEI; + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + } +} + +int serial_readable(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + + if ((HAL_RUART_READ32(uart_idx, RUART_LINE_STATUS_REG_OFF)) & RUART_LINE_STATUS_REG_DR) { + return 1; + } + else { + return 0; + } +} + +int serial_writable(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + + if (HAL_RUART_READ32(uart_idx, RUART_LINE_STATUS_REG_OFF) & + (RUART_LINE_STATUS_REG_THRE)) { + return 1; + } + else { + return 0; + } +} + +void serial_clear(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + HalRuartResetTRxFifo((VOID *)pHalRuartAdapter); +} + +void serial_clear_tx(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + HalRuartResetTxFifo((VOID *)pHalRuartAdapter); +} + +void serial_clear_rx(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + HalRuartResetRxFifo((VOID *)pHalRuartAdapter); +} + +void serial_pinout_tx(PinName tx) +{ + pinmap_pinout(tx, PinMap_UART_TX); +} + +void serial_break_set(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + u32 RegValue; + + RegValue = HAL_RUART_READ32(uart_idx, RUART_LINE_CTL_REG_OFF); + RegValue |= BIT_UART_LCR_BREAK_CTRL; + HAL_RUART_WRITE32(uart_idx, RUART_LINE_CTL_REG_OFF, RegValue); +} + +void serial_break_clear(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + u32 RegValue; + + RegValue = HAL_RUART_READ32(uart_idx, RUART_LINE_CTL_REG_OFF); + RegValue &= ~(BIT_UART_LCR_BREAK_CTRL); + HAL_RUART_WRITE32(uart_idx, RUART_LINE_CTL_REG_OFF, RegValue); +} + +void serial_send_comp_handler(serial_t *obj, void *handler, uint32_t id) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + pHalRuartAdapter->TxCompCallback = (void(*)(void*))handler; + pHalRuartAdapter->TxCompCbPara = (void*)id; +} + +void serial_recv_comp_handler(serial_t *obj, void *handler, uint32_t id) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + pHalRuartAdapter->RxCompCallback = (void(*)(void*))handler; + pHalRuartAdapter->RxCompCbPara = (void*)id; +} + +void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + // Our UART cannot specify the RTS/CTS pin seprately, so the ignore the rxflow, txflow pin + // We just use the hardware auto flow control, so cannot do flow-control single direction only + pHalRuartAdapter = &(obj->hal_uart_adp); + + // RTS low active + // RTS_pin = autoflow_en ? (~rts | (RX_FIFO_Level_Trigger)) : ~rts + switch(type) { + case FlowControlRTSCTS: + pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE; + pHalRuartAdapter->RTSCtrl = 1; + break; + + case FlowControlRTS: // to indicate peer that it's ready for RX + // It seems cannot only enable RTS + pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE; + pHalRuartAdapter->RTSCtrl = 1; + break; + + case FlowControlCTS: // to check is the peer ready for RX: if can start TX ? + // need to check CTS before TX + pHalRuartAdapter->FlowControl = AUTOFLOW_ENABLE; + pHalRuartAdapter->RTSCtrl = 1; + break; + + case FlowControlNone: + default: + pHalRuartAdapter->FlowControl = AUTOFLOW_DISABLE; + pHalRuartAdapter->RTSCtrl = 1; // RTS pin allways Low, peer can send data + break; + + } + + HalRuartFlowCtrl((VOID *)pHalRuartAdapter); +} + +// Blocked(busy wait) receive, return received bytes count +int32_t serial_recv_blocked (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + obj->rx_len = len; + HalRuartEnterCritical(pHalRuartAdapter); + ret = pHalRuartOp->HalRuartRecv(pHalRuartAdapter, (u8*)prxbuf, len, timeout_ms); + HalRuartExitCritical(pHalRuartAdapter); + + return (ret); +} + +// Blocked(busy wait) send, return transmitted bytes count +int32_t serial_send_blocked (serial_t *obj, char *ptxbuf, uint32_t len, uint32_t timeout_ms) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + obj->tx_len = len; + ret = pHalRuartOp->HalRuartSend(pHalRuartAdapter, (u8*)ptxbuf, len, timeout_ms); + return (ret); +} + +int32_t serial_recv_stream (serial_t *obj, char *prxbuf, uint32_t len) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + obj->rx_len = len; + ret = pHalRuartOp->HalRuartIntRecv(pHalRuartAdapter, (u8*)prxbuf, len); + return (ret); +} + +int32_t serial_send_stream (serial_t *obj, char *ptxbuf, uint32_t len) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + obj->tx_len = len; + HalRuartEnterCritical(pHalRuartAdapter); + ret = pHalRuartOp->HalRuartIntSend(pHalRuartAdapter, (u8*)ptxbuf, len); + HalRuartExitCritical(pHalRuartAdapter); + return (ret); +} + +#ifdef CONFIG_GDMA_EN + +int32_t serial_recv_stream_dma (serial_t *obj, char *prxbuf, uint32_t len) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + int32_t ret; + + pHalRuartOp = &(obj->hal_uart_op); + if ((serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN)==0) { + PUART_DMA_CONFIG pHalRuartDmaCfg; + + pHalRuartDmaCfg = &obj->uart_gdma_cfg; + if (HAL_OK == HalRuartRxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) { + serial_dma_en[uart_idx] |= SERIAL_RX_DMA_EN; + } + else { + return HAL_BUSY; + } + } + + obj->rx_len = len; + HalRuartEnterCritical(pHalRuartAdapter); + ret = HalRuartDmaRecv(pHalRuartAdapter, (u8*)prxbuf, len); + HalRuartExitCritical(pHalRuartAdapter); + return (ret); +} + +int32_t serial_send_stream_dma (serial_t *obj, char *ptxbuf, uint32_t len) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + int32_t ret; + + pHalRuartOp = &(obj->hal_uart_op); + + if ((serial_dma_en[uart_idx] & SERIAL_TX_DMA_EN)==0) { + PUART_DMA_CONFIG pHalRuartDmaCfg; + + pHalRuartDmaCfg = &obj->uart_gdma_cfg; + if (HAL_OK == HalRuartTxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) { + serial_dma_en[uart_idx] |= SERIAL_TX_DMA_EN; + } + else { + return HAL_BUSY; + } + } + obj->tx_len = len; + HalRuartEnterCritical(pHalRuartAdapter); + ret = HalRuartDmaSend(pHalRuartAdapter, (u8*)ptxbuf, len); + HalRuartExitCritical(pHalRuartAdapter); + return (ret); +} + +int32_t serial_recv_stream_dma_timeout (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms, void *force_cs) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + u8 uart_idx = pHalRuartAdapter->UartIndex; + uint32_t TimeoutCount=0, StartCount; + int ret; + void (*task_yield)(void); + + pHalRuartOp = &(obj->hal_uart_op); + if ((serial_dma_en[uart_idx] & SERIAL_RX_DMA_EN)==0) { + PUART_DMA_CONFIG pHalRuartDmaCfg; + + pHalRuartDmaCfg = &obj->uart_gdma_cfg; + if (HAL_OK == HalRuartRxGdmaInit(pHalRuartAdapter, pHalRuartDmaCfg, 0)) { + serial_dma_en[uart_idx] |= SERIAL_RX_DMA_EN; + } + else { + return HAL_BUSY; + } + } + HalRuartEnterCritical(pHalRuartAdapter); + ret = HalRuartDmaRecv(pHalRuartAdapter, (u8*)prxbuf, len); + HalRuartExitCritical(pHalRuartAdapter); + + if ((ret == HAL_OK) && (timeout_ms > 0)) { + TimeoutCount = (timeout_ms*1000/TIMER_TICK_US); + StartCount = HalTimerOp.HalTimerReadCount(1); + task_yield = (void (*)(void))force_cs; + pHalRuartAdapter->Status = HAL_UART_STATUS_OK; + while (pHalRuartAdapter->State & HAL_UART_STATE_BUSY_RX) { + if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) { + ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter); + ret = pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter); + pHalRuartAdapter->Status = HAL_UART_STATUS_TIMEOUT; + break; + } + if (NULL != task_yield) { + task_yield(); + } + } + if (pHalRuartAdapter->Status == HAL_UART_STATUS_TIMEOUT) { + return (len - pHalRuartAdapter->RxCount); + } else { + return len; + } + } else { + return (-ret); + } +} + + +#endif // end of "#ifdef CONFIG_GDMA_EN" + +int32_t serial_send_stream_abort (serial_t *obj) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + + HalRuartEnterCritical(pHalRuartAdapter); + ret = pHalRuartOp->HalRuartStopSend((VOID*)pHalRuartAdapter); + HalRuartExitCritical(pHalRuartAdapter); + if (HAL_OK != ret) { + return -ret; + } + HalRuartResetTxFifo((VOID*)pHalRuartAdapter); + + ret = obj->tx_len - pHalRuartAdapter->TxCount; + + return (ret); +} + +int32_t serial_recv_stream_abort (serial_t *obj) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + int ret; + + pHalRuartOp = &(obj->hal_uart_op); + + HalRuartEnterCritical(pHalRuartAdapter); + ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter); + HalRuartExitCritical(pHalRuartAdapter); + if (HAL_OK != ret) { + return -ret; + } + +// pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter); + + ret = obj->rx_len - pHalRuartAdapter->RxCount; + return (ret); +} + +void serial_disable (serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + + HalRuartDisable((VOID*)pHalRuartAdapter); +} + +void serial_enable (serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + + HalRuartEnable((VOID*)pHalRuartAdapter); +} + +// return the byte count received before timeout, or error(<0) +int32_t serial_recv_stream_timeout (serial_t *obj, char *prxbuf, uint32_t len, uint32_t timeout_ms, void *force_cs) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)&(obj->hal_uart_adp); + uint32_t TimeoutCount=0, StartCount; + int ret; + void (*task_yield)(void); + + task_yield = NULL; + pHalRuartOp = &(obj->hal_uart_op); + HalRuartEnterCritical(pHalRuartAdapter); + ret = pHalRuartOp->HalRuartIntRecv(pHalRuartAdapter, (u8*)prxbuf, len); + HalRuartExitCritical(pHalRuartAdapter); + if ((ret == HAL_OK) && (timeout_ms > 0)) { + TimeoutCount = (timeout_ms*1000/TIMER_TICK_US); + StartCount = HalTimerOp.HalTimerReadCount(1); + task_yield = (void (*)(void))force_cs; + while (pHalRuartAdapter->State & HAL_UART_STATE_BUSY_RX) { + if (HAL_TIMEOUT == RuartIsTimeout(StartCount, TimeoutCount)) { + ret = pHalRuartOp->HalRuartStopRecv((VOID*)pHalRuartAdapter); + ret = pHalRuartOp->HalRuartResetRxFifo((VOID*)pHalRuartAdapter); + pHalRuartAdapter->Status = HAL_UART_STATUS_TIMEOUT; + break; + } + if (NULL != task_yield) { + task_yield(); + } + } + return (len - pHalRuartAdapter->RxCount); + } else { + return (-ret); + } +} + +// to hook lock/unlock function for multiple-thread application +void serial_hook_lock(serial_t *obj, void *lock, void *unlock, uint32_t id) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + + pHalRuartAdapter = &(obj->hal_uart_adp); + pHalRuartAdapter->EnterCritical = (void (*)(void))lock; + pHalRuartAdapter->ExitCritical = (void (*)(void))unlock; +} + +// to read Line-Status register +// Bit 0: RX Data Ready +// Bit 1: Overrun Error +// Bit 2: Parity Error +// Bit 3: Framing Error +// Bit 4: Break Interrupt (received data input is held in 0 state for a longer than a full word tx time) +// Bit 5: TX FIFO empty (THR empty) +// Bit 6: TX FIFO empty (THR & TSR both empty) +// Bit 7: RX Error (parity error, framing error or break indication) +uint8_t serial_raed_lsr(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + uint8_t RegValue; + + pHalRuartAdapter = &(obj->hal_uart_adp); + RegValue = HAL_RUART_READ8(pHalRuartAdapter->UartIndex, RUART_LINE_STATUS_REG_OFF); + return RegValue; +} + +// to read Modem-Status register +// Bit 0: DCTS, The CTS line has changed its state +// Bit 1: DDSR, The DSR line has changed its state +// Bit 2: TERI, RI line has changed its state from low to high state +// Bit 3: DDCD, DCD line has changed its state +// Bit 4: Complement of the CTS input +// Bit 5: Complement of the DSR input +// Bit 6: Complement of the RI input +// Bit 7: Complement of the DCD input +uint8_t serial_raed_msr(serial_t *obj) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + uint8_t RegValue; + + pHalRuartAdapter = &(obj->hal_uart_adp); + RegValue = HAL_RUART_READ8(pHalRuartAdapter->UartIndex, RUART_MODEM_STATUS_REG_OFF); + return RegValue; +} + +// to set the RX FIFO level to trigger RX interrupt/RTS de-assert +// FifoLv: +// 0: 1-Byte +// 1: 4-Byte +// 2: 8-Byte +// 3: 14-Byte +void serial_rx_fifo_level(serial_t *obj, SerialFifoLevel FifoLv) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter; + uint8_t RegValue; + + pHalRuartAdapter = &(obj->hal_uart_adp); + RegValue = (RUART_FIFO_CTL_REG_DMA_ENABLE | RUART_FIFO_CTL_REG_FIFO_ENABLE) | (((uint8_t)FifoLv&0x03) << 6); + HAL_RUART_WRITE8(pHalRuartAdapter->UartIndex, RUART_FIFO_CTL_REG_OFF, RegValue); +} + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/sleep.c b/USDK/component/common/mbed/targets/hal/rtl8195a/sleep.c new file mode 100644 index 0000000..d629573 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/sleep.c @@ -0,0 +1,290 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "sleep_ex_api.h" +#include "cmsis.h" + +extern VOID SleepCG(u8 Option, u32 SDuration, u8 ClkSourceEn, u8 SDREn); +extern VOID DeepStandby(u8 Option, u32 SDuration, u8 GpioOption); +extern VOID DeepSleep(u8 Option, u32 SDuration); + +SLEEP_WAKEUP_EVENT DStandbyWakeupEvent={0}; + +/** + * @brief To make the system entering the Clock Gated power saving. + * This function just make the system to enter the clock gated + * power saving mode and pending on wake up event waitting. + * The user application need to configure the peripheral to + * generate system wake up event, like GPIO interrupt + * , G-Timer timeout, etc. befor entering power saving mode. + * + * @param wakeup_event: A bit map of wake up event. Available event: + * SLEEP_WAKEUP_BY_STIMER + * SLEEP_WAKEUP_BY_GTIMER + * SLEEP_WAKEUP_BY_GPIO_INT + * SLEEP_WAKEUP_BY_WLAN + * SLEEP_WAKEUP_BY_NFC + * SLEEP_WAKEUP_BY_SDIO + * SLEEP_WAKEUP_BY_USB + * sleep_duration: the system sleep duration in ms, only valid + * for SLEEP_WAKEUP_BY_STIMER wake up event. + * + * @retval None + */ +void sleep_ex(uint32_t wakeup_event, uint32_t sleep_duration) +{ + u8 wake_ev=0; + + wake_ev = wakeup_event & 0xff; + + if (sleep_duration == 0) { + wake_ev &= ~SLP_STIMER; + } + + if (wake_ev == 0) { + // error: No wakeup event, skip the entering sleep mode + return; + } + SleepCG(wake_ev, sleep_duration, 0, 0); // same as old configuration: SCLK off & SDR no power off +} + + +/** + * @brief To make the system entering the Clock Gated power saving. + * This function just make the system to enter the clock gated + * power saving mode and pending on wake up event waitting. + * The user application need to configure the peripheral to + * generate system wake up event, like GPIO interrupt + * , G-Timer timeout, etc. befor entering power saving mode. + * + * @param wakeup_event: A bit map of wake up event. Available event: + * SLEEP_WAKEUP_BY_STIMER + * SLEEP_WAKEUP_BY_GTIMER + * SLEEP_WAKEUP_BY_GPIO_INT + * SLEEP_WAKEUP_BY_WLAN + * SLEEP_WAKEUP_BY_NFC + * SLEEP_WAKEUP_BY_SDIO + * SLEEP_WAKEUP_BY_USB + * sleep_duration: the system sleep duration in ms, only valid + * for SLEEP_WAKEUP_BY_STIMER wake up event. + * clk_sourec_enable: the option for SCLK on(1)/off(0) + * sdr_enable: the option for turn off the SDR controller (1:off, 0:on) + * + * @retval None + */ +void sleep_ex_selective(uint32_t wakeup_event, uint32_t sleep_duration, uint32_t clk_sourec_enable, uint32_t sdr_enable) +{ + u8 wake_ev=0; + u8 sdr_en=0; + u8 clk_source_en=0; + + wake_ev = wakeup_event & 0xff; + sdr_en = sdr_enable & 0xff; + clk_source_en = clk_sourec_enable & 0xff; + + if (sleep_duration == 0) { + wake_ev &= ~SLP_STIMER; + } + + if (wake_ev == 0) { + // error: No wakeup event, skip the entering sleep mode + return; + } + SleepCG(wake_ev, sleep_duration, clk_source_en, sdr_en); +} + + +/** + * @brief To add a wake up event to wake up the system from the + * deep standby power saving mode. + * + * @param wakeup_event: A bit map of wake up event. Available event: + * STANDBY_WAKEUP_BY_STIMER + * STANDBY_WAKEUP_BY_NFC + * STANDBY_WAKEUP_BY_PA5 (GPIO) + * STANDBY_WAKEUP_BY_PC7 (GPIO) + * STANDBY_WAKEUP_BY_PD5 (GPIO) + * STANDBY_WAKEUP_BY_PE3 (GPIO) + * sleep_duration_ms: the system sleep duration in ms, only valid + * for STANDBY_WAKEUP_BY_STIMER wake up event. + * gpio_active: for a GPIO pin to wake up the system by + * goes high(1) or low(0) + * + * @retval None + */ +void standby_wakeup_event_add(uint32_t wakeup_event, uint32_t sleep_duration_ms, uint32_t gpio_active) +{ + u32 i; + u8 gpio_event; + u8 gpio_en; + u8 gpio_act; + + if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) { + DStandbyWakeupEvent.wakeup_event |= DSTBY_STIMER; + DStandbyWakeupEvent.timer_duration = sleep_duration_ms; + } + +#if 0 + if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) { + DStandbyWakeupEvent.wakeup_event |= DSTBY_TIMER33; + // TODO: Sleep Duration ? + } +#endif + + if (wakeup_event & STANDBY_WAKEUP_BY_NFC) { + DStandbyWakeupEvent.wakeup_event |= DSTBY_NFC; + } + + gpio_event = STANDBY_WAKEUP_BY_PA5; + gpio_en = BIT0; + gpio_act = BIT4; + // Loop 4 to check 4 GPIO wake up event + for (i=0;i<4;i++) { + if (wakeup_event & gpio_event) { + DStandbyWakeupEvent.wakeup_event |= DSTBY_GPIO; + DStandbyWakeupEvent.gpio_option |= gpio_en; + if (gpio_active) { + // Active High + DStandbyWakeupEvent.gpio_option |= gpio_act; + } + else { + // Active Low + DStandbyWakeupEvent.gpio_option &= ~gpio_act; + } + } + gpio_event = gpio_event << 1; + gpio_en = gpio_en << 1; + gpio_act = gpio_act << 1; + } +} + +/** + * @brief To delete a wake up event for wakeing up the system from the + * deep standby power saving mode. + * + * @param wakeup_event: A bit map of wake up event. Available event: + * STANDBY_WAKEUP_BY_STIMER + * STANDBY_WAKEUP_BY_NFC + * STANDBY_WAKEUP_BY_PA5 (GPIO) + * STANDBY_WAKEUP_BY_PC7 (GPIO) + * STANDBY_WAKEUP_BY_PD5 (GPIO) + * STANDBY_WAKEUP_BY_PE3 (GPIO) + * @retval None + */ +void standby_wakeup_event_del(uint32_t wakeup_event) +{ + if (wakeup_event & STANDBY_WAKEUP_BY_STIMER) { + DStandbyWakeupEvent.wakeup_event &= ~DSTBY_STIMER; + } + +#if 0 + if (wakeup_event & STANDBY_WAKEUP_BY_DS_TIMER) { + DStandbyWakeupEvent.wakeup_event &= ~DSTBY_TIMER33; + } +#endif + + if (wakeup_event & STANDBY_WAKEUP_BY_NFC) { + DStandbyWakeupEvent.wakeup_event &= ~DSTBY_NFC; + } + + if (wakeup_event & STANDBY_WAKEUP_BY_PA5) { + DStandbyWakeupEvent.gpio_option &= ~BIT0; + } + + if (wakeup_event & STANDBY_WAKEUP_BY_PC7) { + DStandbyWakeupEvent.gpio_option &= ~BIT1; + } + + if (wakeup_event & STANDBY_WAKEUP_BY_PD5) { + DStandbyWakeupEvent.gpio_option &= ~BIT2; + } + + if (wakeup_event & STANDBY_WAKEUP_BY_PE3) { + DStandbyWakeupEvent.gpio_option &= ~BIT3; + } + + if ((DStandbyWakeupEvent.gpio_option & 0x0f) == 0) { + // All GPIO wake up pin are disabled + DStandbyWakeupEvent.wakeup_event &= ~DSTBY_GPIO; + } +} + +/** + * @brief To make the system entering the Deep Standby power saving. + * The CPU, memory and part fo peripheral power is off when + * entering deep standby power saving mode. The program needs + * to be reload from the flash at system resume. + * + * @retval None + */ +void deepstandby_ex(void) +{ + if ((DStandbyWakeupEvent.wakeup_event & (DSTBY_STIMER|DSTBY_NFC|DSTBY_GPIO)) == 0) { + // error: no wakeup event was added, so skip the entering standby power saving + return; + } + + DeepStandby(DStandbyWakeupEvent.wakeup_event, + DStandbyWakeupEvent.timer_duration, DStandbyWakeupEvent.gpio_option); +} + +/** + * @brief To make the system entering the Deep Sleep power saving mode. + * The CPU, memory and peripheral power is off when entering + * deep sleep power saving mode. The program needs to be reload + * and all peripheral needs be re-configure when system resume. + * + * @param wakeup_event: A bit map of wake up event. Available event: + * DSLEEP_WAKEUP_BY_TIMER + * DSLEEP_WAKEUP_BY_GPIO + * sleep_duration: the system sleep duration in ms, only valid + * for DSLEEP_WAKEUP_BY_TIMER wake up event. + * + * @retval None + */ +void deepsleep_ex(uint32_t wakeup_event, uint32_t sleep_duration) +{ + u8 wake_ev=0; + + if ((wakeup_event & DSLEEP_WAKEUP_BY_TIMER) && (sleep_duration > 0)) { + // wake up by timeout + wake_ev |= DS_TIMER33; + } + + if (wakeup_event & DSLEEP_WAKEUP_BY_GPIO) { + // wake up by GPIO pin goes high + wake_ev |= DS_GPIO; + } + + if (wake_ev == 0) { + // error: No wake up event, skip entering deep sleep mode + return; + } + DeepSleep (wake_ev, sleep_duration); +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/spdio_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/spdio_api.c new file mode 100644 index 0000000..2a432c3 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/spdio_api.c @@ -0,0 +1,87 @@ +#include +#include "hal_sdio.h" + +#if 0 // - HalSdioRegisterTxCallback(spdio_rx_done_cb, (void *)obj); // ?????????? HalSdioRegisterRxDoneCallback(spdio_tx_done_cb, (void *)obj); // ????????? + +struct spdio_t *g_spdio_priv = NULL; + +s8 spdio_rx_done_cb(void *padapter, u8 *data, u16 offset, u16 pktsize, u8 type){ + struct spdio_buf_t *buf = (struct spdio_buf_t *)data; + struct spdio_t *obj = (struct spdio_t *)padapter; + + if(obj) + return obj->rx_done_cb(obj, buf, (u8 *)(buf->buf_addr+offset), pktsize, type); + else + SPDIO_API_PRINTK("spdio rx done callback function is null!"); + return SUCCESS; +} + +s8 spdio_tx_done_cb(void *padapter, u8 *data, u16 offset, u16 pktsize, u8 type){ + struct spdio_t *obj = (struct spdio_t *)padapter; + struct spdio_buf_t *buf = (struct spdio_buf_t *)data; + if(obj) + return obj->tx_done_cb(obj, buf); + else + SPDIO_API_PRINTK("spdio tx done callback function is null!"); + return SUCCESS; +} + + +s8 spdio_tx(struct spdio_t *obj, struct spdio_buf_t *pbuf){ +extern s8 HalSdioRxCallback(PHAL_SDIO_ADAPTER pSDIODev, VOID *pData, u16 Offset, u16 PktSize, u8 CmdType); + return HalSdioRxCallback((u8 *)pbuf, 0, pbuf->buf_size, pbuf->type); // ????????? +} + +void spdio_structinit(struct spdio_t *obj){ + obj->rx_bd_bufsz = SPDIO_RX_BUFSZ_ALIGN(2048+24); //extra 24 bytes for sdio header + obj->rx_bd_num = 24; + obj->tx_bd_num = 24; + obj->priv = NULL; + obj->rx_buf = NULL; + obj->rx_done_cb = NULL; + obj->tx_done_cb = NULL; +} + +///////// Add pvvx, no ... +void HalSdioRegisterRxCallback(char (*rx_done_cb)(void *priv, void* pbuf, u8 *pdata, u16 size, u8 type), void *obj) +{ + struct spdio_t * sp = (struct spdio_t *) obj; + sp->rx_done_cb = rx_done_cb; +} + +void HalSdioRegisterTxDoneCallback(char (*tx_done_cb)(void *priv, void* pbuf), void *obj) +{ + struct spdio_t * sp = (struct spdio_t *) obj; + sp->tx_done_cb = tx_done_cb; +} +/////// + +void spdio_init(struct spdio_t *obj) +{ + if(obj == NULL){ + SPDIO_API_PRINTK("spdio obj is NULL, spdio init failed!"); + return; + } + if((obj->rx_bd_num == 0) ||(obj->rx_bd_bufsz == 0) || (obj->rx_bd_bufsz%64) + ||(obj->tx_bd_num == 0) ||(obj->tx_bd_num%2)||(obj->rx_buf == NULL)) + { + SPDIO_API_PRINTK("spdio obj resource isn't correctly inited, spdio init failed!"); + return; + } + g_spdio_priv = obj; + HalSdioInit(); + HalSdioRegisterRxCallback(spdio_rx_done_cb, (void *)obj); // ?????????? + HalSdioRegisterTxDoneCallback(spdio_tx_done_cb, (void *)obj); // ????????? +} + +void spdio_deinit(struct spdio_t *obj) +{ + if(obj == NULL){ + SPDIO_API_PRINTK("spdio obj is NULL, spdio deinit failed"); + return; + } + HalSdioDeInit(); + g_spdio_priv = NULL; +} + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/spi_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/spi_api.c new file mode 100644 index 0000000..85471cd --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/spi_api.c @@ -0,0 +1,968 @@ + +#include "objects.h" +#include "spi_api.h" +#include "spi_ex_api.h" +#include "PinNames.h" +#include "pinmap.h" +#include "hal_ssi.h" + +extern u32 SystemGetCpuClk(VOID); +extern VOID HAL_GPIO_PullCtrl(u32 pin, u32 mode); + +void spi_tx_done_callback(VOID *obj); +void spi_rx_done_callback(VOID *obj); +void spi_bus_tx_done_callback(VOID *obj); + +#ifdef CONFIG_GDMA_EN +HAL_GDMA_OP SpiGdmaOp; +#endif + +uint8_t SPI0_IS_AS_SLAVE = 0; + +//TODO: Load default Setting: It should be loaded from external setting file. +extern const DW_SSI_DEFAULT_SETTING SpiDefaultSetting; + +static const PinMap PinMap_SSI_MOSI[] = { + {PE_2, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)}, + {PC_2, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)}, + {PA_1, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)}, + {PB_6, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)}, + {PD_6, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)}, + {PG_2, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)}, + {PE_6, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)}, + {PD_2, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)}, + {NC, NC, 0} +}; + +static const PinMap PinMap_SSI_MISO[] = { + {PE_3, RTL_PIN_PERI(SPI0, 0, S0), RTL_PIN_FUNC(SPI0, S0)}, + {PC_3, RTL_PIN_PERI(SPI0, 0, S1), RTL_PIN_FUNC(SPI0, S1)}, + {PA_0, RTL_PIN_PERI(SPI1, 1, S0), RTL_PIN_FUNC(SPI1, S0)}, + {PB_7, RTL_PIN_PERI(SPI1, 1, S1), RTL_PIN_FUNC(SPI1, S1)}, + {PD_7, RTL_PIN_PERI(SPI1, 1, S2), RTL_PIN_FUNC(SPI1, S2)}, + {PG_3, RTL_PIN_PERI(SPI2, 2, S0), RTL_PIN_FUNC(SPI2, S0)}, + {PE_7, RTL_PIN_PERI(SPI2, 2, S1), RTL_PIN_FUNC(SPI2, S1)}, + {PD_3, RTL_PIN_PERI(SPI2, 2, S2), RTL_PIN_FUNC(SPI2, S2)}, + {NC, NC, 0} +}; + + +void spi_init (spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + SSI_DBG_ENTRANCE("spi_init()\n"); + + uint32_t ssi_mosi, ssi_miso, ssi_peri; + uint8_t ssi_idx, ssi_pinmux; + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + + _memset((void*)obj, 0, sizeof(spi_t)); + obj->state = 0; + uint32_t SystemClock = SystemGetCpuClk(); + uint32_t MaxSsiFreq = (SystemClock >> 2) >> 1; + + /* SsiClockDivider doesn't support odd number */ + + DBG_SSI_INFO("SystemClock: %d\n", SystemClock); + DBG_SSI_INFO("MaxSsiFreq : %d\n", MaxSsiFreq); + + ssi_mosi = pinmap_peripheral(mosi, PinMap_SSI_MOSI); + ssi_miso = pinmap_peripheral(miso, PinMap_SSI_MISO); + //DBG_SSI_INFO("ssi_mosi: %d, ssi_miso: %d\n", ssi_mosi, ssi_miso); + + ssi_peri = pinmap_merge(ssi_mosi, ssi_miso); + if (unlikely(ssi_peri == NC)) { + DBG_SSI_ERR("spi_init(): Cannot find matched SSI index.\n"); + return; + } + obj->sclk = (u8)sclk; + ssi_idx = RTL_GET_PERI_IDX(ssi_peri); + ssi_pinmux = RTL_GET_PERI_SEL(ssi_peri); + DBG_SSI_INFO("ssi_peri: %d, ssi_idx: %d, ssi_pinmux: %d\n", ssi_peri, ssi_idx, ssi_pinmux); + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + pHalSsiAdaptor->Index = ssi_idx; + pHalSsiAdaptor->PinmuxSelect = ssi_pinmux; + +#if 0 + // XXX: Only for test + if ((ssi_idx == 0) && (SPI0_IS_AS_SLAVE == 1)) { + //DBG_SSI_INFO("SSI%d will be as slave. (spi0_is_slave: %d)\n", index, spi0_is_slave); + pHalSsiAdaptor->Role = SSI_SLAVE; + } + else +#endif + { + //DBG_SSI_INFO("SSI%d will be as master. (spi0_is_slave: %d)\n", index, spi0_is_slave); + pHalSsiAdaptor->Role = SSI_MASTER; + } + + HalSsiOpInit((VOID*)pHalSsiOp); + + pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role); + + /* Pinmux workaround */ + if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOC)) { + EEPROM_PIN_CTRL(OFF); + } + + if ((ssi_idx == 0) && (ssi_pinmux == SSI0_MUX_TO_GPIOE)) { + DBG_SSI_WARN(ANSI_COLOR_MAGENTA"SPI0 Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET); + } + + + //pHalSsiOp->HalSsiPinmuxEnable(pHalSsiAdaptor); + + + //TODO: Implement default setting structure. + pHalSsiOp->HalSsiLoadSetting(pHalSsiAdaptor, (void*)&SpiDefaultSetting); + pHalSsiAdaptor->DefaultRxThresholdLevel = SpiDefaultSetting.RxThresholdLevel; + + //pHalSsiOp->HalSsiInit(pHalSsiAdaptor); + if(HalSsiInit(pHalSsiAdaptor) != HAL_OK){ + DBG_SSI_ERR(ANSI_COLOR_RED"spi_init(): SPI %x init fails.\n"ANSI_COLOR_RESET,pHalSsiAdaptor->Index); + return; + } + + pHalSsiAdaptor->TxCompCallback = spi_tx_done_callback; + pHalSsiAdaptor->TxCompCbPara = (void*)obj; + pHalSsiAdaptor->RxCompCallback = spi_rx_done_callback; + pHalSsiAdaptor->RxCompCbPara = (void*)obj; + pHalSsiAdaptor->TxIdleCallback = spi_bus_tx_done_callback; + pHalSsiAdaptor->TxIdleCbPara = (void*)obj; + +#ifdef CONFIG_GDMA_EN + HalGdmaOpInit((VOID*)&SpiGdmaOp); + pHalSsiAdaptor->DmaConfig.pHalGdmaOp = &SpiGdmaOp; + pHalSsiAdaptor->DmaConfig.pRxHalGdmaAdapter = &obj->spi_gdma_adp_rx; + pHalSsiAdaptor->DmaConfig.pTxHalGdmaAdapter = &obj->spi_gdma_adp_tx; + obj->dma_en = 0; + pHalSsiAdaptor->HaveTxChannel = 0; + pHalSsiAdaptor->HaveRxChannel = 0; +#endif +} + +void spi_free (spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + //PHAL_SSI_OP pHalSsiOp; + + + pHalSsiAdaptor = &obj->spi_adp; + //pHalSsiOp = &obj->spi_op; + + //pHalSsiOp->HalSsiInterruptDisable(pHalSsiAdaptor); + //pHalSsiOp->HalSsiDisable(pHalSsiAdaptor); + //pHalSsiOp->HalSsiPinmuxDisable(pHalSsiAdaptor); + HalSsiDeInit(pHalSsiAdaptor); + + SPI0_MULTI_CS_CTRL(OFF); + +#ifdef CONFIG_GDMA_EN + if (obj->dma_en & SPI_DMA_RX_EN) { + HalSsiRxGdmaDeInit(pHalSsiAdaptor); + } + + if (obj->dma_en & SPI_DMA_TX_EN) { + HalSsiTxGdmaDeInit(pHalSsiAdaptor); + } + obj->dma_en = 0; +#endif +} + +void spi_format (spi_t *obj, int bits, int mode, int slave) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + pHalSsiAdaptor->DataFrameSize = (bits - 1); + + /* + * mode | POL PHA + * -----+-------- + * 0 | 0 0 + * 1 | 0 1 + * 2 | 1 0 + * 3 | 1 1 + * + * SCPOL_INACTIVE_IS_LOW = 0, + * SCPOL_INACTIVE_IS_HIGH = 1 + * + * SCPH_TOGGLES_IN_MIDDLE = 0, + * SCPH_TOGGLES_AT_START = 1 + */ + switch (mode) + { + case 0: + pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW; + pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE; + break; + case 1: + pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_LOW; + pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START; + break; + case 2: + pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH; + pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_IN_MIDDLE; + break; + case 3: + pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH; + pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START; + break; + default: // same as 3 + pHalSsiAdaptor->SclkPolarity = SCPOL_INACTIVE_IS_HIGH; + pHalSsiAdaptor->SclkPhase = SCPH_TOGGLES_AT_START; + break; + } + + if (slave == 1) { + if (pHalSsiAdaptor->Index == 0) { + pHalSsiAdaptor->Role = SSI_SLAVE; + pHalSsiAdaptor->SlaveOutputEnable = SLV_TXD_ENABLE; // <-- Slave only + SPI0_IS_AS_SLAVE = 1; + DBG_SSI_INFO("SPI0 is as slave\n"); + } + else { + DBG_SSI_ERR("The SPI%d cannot work as Slave mode, only SPI0 does.\r\n", pHalSsiAdaptor->Index); + pHalSsiAdaptor->Role = SSI_MASTER; + } + } + else { + pHalSsiAdaptor->Role = SSI_MASTER; + } + pHalSsiOp->HalSsiSetDeviceRole(pHalSsiAdaptor, pHalSsiAdaptor->Role); + +#ifdef CONFIG_GPIO_EN + if (pHalSsiAdaptor->Role == SSI_SLAVE) { + if (pHalSsiAdaptor->SclkPolarity == SCPOL_INACTIVE_IS_LOW) { + HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullDown); + } + else { + HAL_GPIO_PullCtrl((u32)obj->sclk, hal_PullUp); + } + } +#endif + HalSsiSetFormat(pHalSsiAdaptor); +} + +void spi_frequency (spi_t *obj, int hz) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + + pHalSsiAdaptor = &obj->spi_adp; + HalSsiSetSclk(pHalSsiAdaptor, (u32)hz); +} + +void spi_slave_select(spi_t *obj, ChipSelect slaveindex) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + u8 Index; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + Index = pHalSsiAdaptor->Index; + + if((pHalSsiAdaptor->Role == SSI_MASTER) && (Index == 0)){ + pHalSsiOp->HalSsiSetSlaveEnableRegister((VOID*)pHalSsiAdaptor,slaveindex); + if(slaveindex != CS_0){ + SPI0_MULTI_CS_CTRL(ON); + } + } + else{ + DBG_SSI_ERR("Only SPI 0 master mode supports slave selection.\n"); + } +} + + +void spi_slave_select_bypin(spi_t *obj, PinName pinname) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + u8 Index; + u8 slaveindex = 8; + u8 pinmux; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + Index = pHalSsiAdaptor->Index; + pinmux = pHalSsiAdaptor->PinmuxSelect; + + if((pHalSsiAdaptor->Role == SSI_MASTER) && (Index == 0)){ + if(pinmux == S0){ + switch (pinname){ + case PE_0: + slaveindex = CS_0; + break; + case PE_4: + slaveindex = CS_1; + break; + case PE_5: + slaveindex = CS_2; + break; + case PE_6: + slaveindex = CS_3; + break; + case PE_7: + slaveindex = CS_4; + break; + case PE_8: + slaveindex = CS_5; + break; + case PE_9: + slaveindex = CS_6; + break; + case PE_A: + slaveindex = CS_7; + break; + default: + slaveindex = 8; + } + } + + if(pinmux == S1){ + switch (pinname){ + case PC_0: + slaveindex = CS_0; + break; + case PC_4: + slaveindex = CS_1; + break; + case PC_5: + slaveindex = CS_2; + break; + case PC_6: + slaveindex = CS_3; + break; + case PC_7: + slaveindex = CS_4; + break; + case PC_8: + slaveindex = CS_5; + break; + case PC_9: + slaveindex = CS_6; + break; + default: + slaveindex = 8; + } + } + + if(slaveindex != 8){ + pHalSsiOp->HalSsiSetSlaveEnableRegister((VOID*)pHalSsiAdaptor,slaveindex); + if(slaveindex != CS_0){ + SPI0_MULTI_CS_CTRL(ON); + } + } + else + DBG_SSI_ERR("Wrong Chip Select Pin.\n"); + + } + else{ + DBG_SSI_ERR("Only SPI 0 master mode supports slave selection.\n"); + } +} + + +static inline void ssi_write (spi_t *obj, int value) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + while (!pHalSsiOp->HalSsiWriteable(pHalSsiAdaptor)); + pHalSsiOp->HalSsiWrite((VOID*)pHalSsiAdaptor, value); +} + +static inline int ssi_read(spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + while (!pHalSsiOp->HalSsiReadable(pHalSsiAdaptor)); + return (int)pHalSsiOp->HalSsiRead(pHalSsiAdaptor); +} + +int spi_master_write (spi_t *obj, int value) +{ + ssi_write(obj, value); + return ssi_read(obj); +} + +int spi_slave_receive (spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int Readable; + int Busy; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + Readable = pHalSsiOp->HalSsiReadable(pHalSsiAdaptor); + Busy = (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor); + return ((Readable && !Busy) ? 1 : 0); +} + +int spi_slave_read (spi_t *obj) +{ + return ssi_read(obj); +} + +void spi_slave_write (spi_t *obj, int value) +{ + ssi_write(obj, value); +} + +int spi_busy (spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + return (int)pHalSsiOp->HalSsiBusy(pHalSsiAdaptor); +} + +void spi_flush_rx_fifo (spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + u32 rx_fifo_level; + u32 i; + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + while(pHalSsiOp->HalSsiReadable(pHalSsiAdaptor)){ + rx_fifo_level = pHalSsiOp->HalSsiGetRxFifoLevel(pHalSsiAdaptor); + for(i=0;iHalSsiRead(pHalSsiAdaptor); + } + } +} + +// Slave mode read a sequence of data by interrupt mode +int32_t spi_slave_read_stream(spi_t *obj, char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_slave_read_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + //DBG_SSI_INFO("rx_buffer addr: %X, length: %d\n", rx_buffer, length); + obj->state |= SPI_STATE_RX_BUSY; + if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + + return ret; +} + +// Slave mode write a sequence of data by interrupt mode +int32_t spi_slave_write_stream(spi_t *obj, char *tx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_TX_BUSY) { + DBG_SSI_WARN("spi_slave_write_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + obj->state |= SPI_STATE_TX_BUSY; + if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_TX_BUSY; + } + return ret; +} + +// Master mode read a sequence of data by interrupt mode +// The length unit is byte, for both 16-bits and 8-bits mode +int32_t spi_master_read_stream(spi_t *obj, char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_master_read_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + // wait bus idle + while(pHalSsiOp->HalSsiBusy(pHalSsiAdaptor)); + + obj->state |= SPI_STATE_RX_BUSY; + if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) == HAL_OK) { + /* as Master mode, it need to push data to TX FIFO to generate clock out + then the slave can transmit data out */ + // send some dummy data out + if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, NULL, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + } + else { + obj->state &= ~SPI_STATE_RX_BUSY; + } + + return ret; +} + +// Master mode write a sequence of data by interrupt mode +// The length unit is byte, for both 16-bits and 8-bits mode +int32_t spi_master_write_stream(spi_t *obj, char *tx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_TX_BUSY) { + DBG_SSI_WARN("spi_master_write_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + obj->state |= SPI_STATE_TX_BUSY; + /* as Master mode, sending data will receive data at sametime, so we need to + drop those received dummy data */ + if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_TX_BUSY; + } + return ret; +} + +// Master mode write a sequence of data by interrupt mode +// The length unit is byte, for both 16-bits and 8-bits mode +int32_t spi_master_write_read_stream(spi_t *obj, char *tx_buffer, + char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & (SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY)) { + DBG_SSI_WARN("spi_master_write_and_read_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + // wait bus idle + while(pHalSsiOp->HalSsiBusy(pHalSsiAdaptor)); + + obj->state |= SPI_STATE_RX_BUSY; + /* as Master mode, sending data will receive data at sametime */ + if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) == HAL_OK) { + obj->state |= SPI_STATE_TX_BUSY; + if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) { + obj->state &= ~(SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY); + // Disable RX IRQ + pHalSsiAdaptor->InterruptMask &= ~(BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM); + pHalSsiOp->HalSsiSetInterruptMask((VOID*)pHalSsiAdaptor); + } + } + else { + obj->state &= ~(SPI_STATE_RX_BUSY); + } + + return ret; +} + +int32_t spi_slave_read_stream_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int ret,timeout = 0; + uint32_t StartCount, TimeoutCount = 0; + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_slave_read_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + obj->state |= SPI_STATE_RX_BUSY; + HalSsiEnterCritical(pHalSsiAdaptor); + if ((ret=pHalSsiOp->HalSsiReadInterrupt(pHalSsiAdaptor, rx_buffer, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + HalSsiExitCritical(pHalSsiAdaptor); + + if ((ret == HAL_OK) && (timeout_ms > 0)) { + TimeoutCount = (timeout_ms*1000/TIMER_TICK_US); + StartCount = HalTimerOp.HalTimerReadCount(1); + while (obj->state & SPI_STATE_RX_BUSY) { + if (HAL_TIMEOUT == HalSsiTimeout(StartCount, TimeoutCount)) { + ret = HalSsiStopRecv(pHalSsiAdaptor); + obj->state &= ~ SPI_STATE_RX_BUSY; + timeout = 1; + DBG_SSI_INFO("Slave is timeout\n"); + break; + } + } + if ((pHalSsiAdaptor->DataFrameSize + 1) > 8){ + pHalSsiAdaptor->RxLength <<= 1; + } + + if(timeout) + return (length - pHalSsiAdaptor->RxLength); + else + return length; + } + else { + return (-ret); + } +} + +// Bus Idle: Real TX done, TX FIFO empty and bus shift all data out already +void spi_bus_tx_done_callback(VOID *obj) +{ + spi_t *spi_obj = (spi_t *)obj; + spi_irq_handler handler; + + if (spi_obj->bus_tx_done_handler) { + handler = (spi_irq_handler)spi_obj->bus_tx_done_handler; + handler(spi_obj->bus_tx_done_irq_id, 0); + } +} + +void spi_tx_done_callback(VOID *obj) +{ + spi_t *spi_obj = (spi_t *)obj; + spi_irq_handler handler; + + if (spi_obj->state & SPI_STATE_TX_BUSY) { + spi_obj->state &= ~SPI_STATE_TX_BUSY; + if (spi_obj->irq_handler) { + handler = (spi_irq_handler)spi_obj->irq_handler; + handler(spi_obj->irq_id, SpiTxIrq); + } + } +} + +void spi_rx_done_callback(VOID *obj) +{ + spi_t *spi_obj = (spi_t *)obj; + spi_irq_handler handler; + + spi_obj->state &= ~SPI_STATE_RX_BUSY; + if (spi_obj->irq_handler) { + handler = (spi_irq_handler)spi_obj->irq_handler; + handler(spi_obj->irq_id, SpiRxIrq); + } +} + +void spi_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id) +{ + obj->irq_handler = (u32)handler; + obj->irq_id = (u32)id; +} + +void spi_bus_tx_done_irq_hook(spi_t *obj, spi_irq_handler handler, uint32_t id) +{ + obj->bus_tx_done_handler = (u32)handler; + obj->bus_tx_done_irq_id = (u32)id; +} + +void spi_enable(spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter; + pHalSsiAdapter = &obj->spi_adp; + + HalSsiEnable((VOID*)pHalSsiAdapter); +} + +void spi_disable(spi_t *obj) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter; + pHalSsiAdapter = &obj->spi_adp; + + HalSsiDisable((VOID*)pHalSsiAdapter); + +} +#ifdef CONFIG_GDMA_EN +int32_t spi_slave_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_slave_read_stream_dma: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + if ((obj->dma_en & SPI_DMA_RX_EN)==0) { + if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_RX_EN; + } + else { + return HAL_BUSY; + } + } + + obj->state |= SPI_STATE_RX_BUSY; + ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length); + if (ret != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + return (ret); +} + +int32_t spi_slave_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_TX_BUSY) { + DBG_SSI_WARN("spi_slave_write_stream_dma: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + if ((obj->dma_en & SPI_DMA_TX_EN)==0) { + if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_TX_EN; + } + else { + return HAL_BUSY; + } + } + obj->state |= SPI_STATE_TX_BUSY; + ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length); + if (ret != HAL_OK) { + obj->state &= ~SPI_STATE_TX_BUSY; + } + return (ret); +} + +int32_t spi_master_write_read_stream_dma(spi_t *obj, char *tx_buffer, + char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & (SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY)) { + DBG_SSI_WARN("spi_master_write_and_read_stream: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + if ((obj->dma_en & SPI_DMA_TX_EN)==0) { + if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_TX_EN; + } + else { + return HAL_BUSY; + } + } + + if ((obj->dma_en & SPI_DMA_RX_EN)==0) { + if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_RX_EN; + } + else { + return HAL_BUSY; + } + } + + obj->state |= SPI_STATE_RX_BUSY; + /* as Master mode, sending data will receive data at sametime */ + if ((ret=HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length)) == HAL_OK) { + obj->state |= SPI_STATE_TX_BUSY; + if ((ret=HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length)) != HAL_OK) { + obj->state &= ~(SPI_STATE_RX_BUSY|SPI_STATE_TX_BUSY); + } + } + else { + obj->state &= ~(SPI_STATE_RX_BUSY); + } + + return ret; +} + +int32_t spi_master_read_stream_dma(spi_t *obj, char *rx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_master_read_stream_dma: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + if ((obj->dma_en & SPI_DMA_RX_EN)==0) { + if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_RX_EN; + } + else { + return HAL_BUSY; + } + } + + obj->state |= SPI_STATE_RX_BUSY; + ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length); + if (ret != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + + // for master mode, we need to send data to generate clock out + if (obj->dma_en & SPI_DMA_TX_EN) { + // TX DMA is on already, so use DMA to TX data + // Make the GDMA to use the rx_buffer too + ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) rx_buffer, length); + if (ret != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + } + else { + // TX DMA isn't enabled, so we just use Interrupt mode to TX dummy data + if ((ret=pHalSsiOp->HalSsiWriteInterrupt(pHalSsiAdaptor, NULL, length)) != HAL_OK) { + obj->state &= ~SPI_STATE_RX_BUSY; + } + } + + return ret; +} + +int32_t spi_master_write_stream_dma(spi_t *obj, char *tx_buffer, uint32_t length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int32_t ret; + + if (obj->state & SPI_STATE_TX_BUSY) { + DBG_SSI_WARN("spi_master_write_stream_dma: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + if ((obj->dma_en & SPI_DMA_TX_EN)==0) { + if (HAL_OK == HalSsiTxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_TX_EN; + } + else { + return HAL_BUSY; + } + } + + obj->state |= SPI_STATE_TX_BUSY; + ret = HalSsiDmaSend(pHalSsiAdaptor, (u8 *) tx_buffer, length); + if (ret != HAL_OK) { + obj->state &= ~SPI_STATE_TX_BUSY; + } + + return ret; +} + +int32_t spi_slave_read_stream_dma_timeout(spi_t *obj, char *rx_buffer, uint32_t length, uint32_t timeout_ms) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor; + PHAL_SSI_OP pHalSsiOp; + int ret,timeout = 0; + uint32_t StartCount, TimeoutCount = 0; + + + if (obj->state & SPI_STATE_RX_BUSY) { + DBG_SSI_WARN("spi_slave_read_stream_dma: state(0x%x) is not ready\r\n", + obj->state); + return HAL_BUSY; + } + + pHalSsiAdaptor = &obj->spi_adp; + pHalSsiOp = &obj->spi_op; + + if ((obj->dma_en & SPI_DMA_RX_EN)==0) { + if (HAL_OK == HalSsiRxGdmaInit(pHalSsiOp, pHalSsiAdaptor)) { + obj->dma_en |= SPI_DMA_RX_EN; + } + else { + return HAL_BUSY; + } + } + + obj->state |= SPI_STATE_RX_BUSY; + HalSsiEnterCritical(pHalSsiAdaptor); + ret = HalSsiDmaRecv(pHalSsiAdaptor, (u8 *) rx_buffer, length); + HalSsiExitCritical(pHalSsiAdaptor); + + if ((ret == HAL_OK) && (timeout_ms > 0)) { + TimeoutCount = (timeout_ms*1000/TIMER_TICK_US); + StartCount = HalTimerOp.HalTimerReadCount(1); + while (obj->state & SPI_STATE_RX_BUSY) { + if (HAL_TIMEOUT == HalSsiTimeout(StartCount, TimeoutCount)) { + ret = HalSsiStopRecv(pHalSsiAdaptor); + obj->state &= ~ SPI_STATE_RX_BUSY; + timeout = 1; + DBG_SSI_INFO("Slave is timeout\n"); + break; + } + } + + if(timeout) + return (length - pHalSsiAdaptor->RxLength); + else + return length; + + } + else { + obj->state &= ~ SPI_STATE_RX_BUSY; + return (-ret); + } +} + +#endif // end of "#ifdef CONFIG_GDMA_EN" diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/sys_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/sys_api.c new file mode 100644 index 0000000..85b152a --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/sys_api.c @@ -0,0 +1,230 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "sys_api.h" +#include "flash_api.h" +#include "osdep_api.h" +#include "device_lock.h" + +#define OTA_Signature "81958711" +#define OTA_Clear "00000000" +#define OTA_Signature_len 8 +#define OTA_Signature_offset 8 +#define OTA_valid_offset 0x100000 +#define printf DiagPrintf + +#if !defined(__ICCARM__) +#define memcmp(dst, src, sz) _memcmp(dst, src, sz) +#define memset(dst, val, sz) _memset(dst, val, sz) +#define memcpy(dst, src, sz) _memcpy(dst, src, sz) +#endif // #if !defined(__ICCARM__) + +extern VOID HalJtagPinOff(VOID); + +extern void HalInitLogUart(void); +extern void HalDeinitLogUart(void); + +#ifdef CONFIG_SDR_EN +//#if defined ( __ICCARM__ ) +extern u8 IsSdrPowerOn(); +//#endif +#endif +/** + * @brief Turn off the JTAG function + * + * @return None + * + */ +void sys_jtag_off(void) +{ + HalJtagPinOff(); +} + +void sys_clear_ota_signature(void) +{ + flash_t flash; + u32 ota_offset=0xFFFFFFFF, part1_offset, part2_offset; + u8 signature[OTA_Signature_len+1]; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset); + part1_offset = (part1_offset&0xFFFF) * 1024; + flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature); + if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){ + ota_offset = part1_offset; + } + + flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset); + flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature); + if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){ + ota_offset = part2_offset; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("OTA offset = 0x%08X\n", ota_offset); + + if(ota_offset < OTA_valid_offset){ + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature); + signature[OTA_Signature_len] = '\0'; + printf("Signature = %s\n", signature); + if(!memcmp((char const*)signature, OTA_Signature, OTA_Signature_len)){ + memcpy((char*)signature, OTA_Clear, OTA_Signature_len); + flash_stream_write(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature); + flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature); + signature[OTA_Signature_len] = '\0'; + printf("Signature = %s\n", signature); + printf("Clear OTA signature success.\n"); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + } + +} + +void sys_recover_ota_signature(void) +{ + flash_t flash; + u32 ota_offset=0xFFFFFFFF, part1_offset, part2_offset; + u8 signature[OTA_Signature_len+1]; + u8* pbuf; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, 0x18, 4, (u8*)&part1_offset); + part1_offset = (part1_offset&0xFFFF) * 1024; + flash_stream_read(&flash, part1_offset+OTA_Signature_offset, OTA_Signature_len, signature); + if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){ + ota_offset = part1_offset; + } + + flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, 4, (u8*)&part2_offset); + flash_stream_read(&flash, part2_offset+OTA_Signature_offset, OTA_Signature_len, signature); + if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){ + ota_offset = part2_offset; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("OTA offset = 0x%08X\n", ota_offset); + + if(ota_offset < OTA_valid_offset){ + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature); + signature[OTA_Signature_len] = '\0'; + printf("Signature = %s\n", signature); + if(!memcmp((char const*)signature, OTA_Clear, OTA_Signature_len)){ + // backup + pbuf = RtlMalloc(FLASH_SECTOR_SIZE); + if(!pbuf) return; + flash_stream_read(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf); + memcpy((char*)pbuf+OTA_Signature_offset, OTA_Signature, OTA_Signature_len); + flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE); + flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf); + // Write + flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf); + flash_erase_sector(&flash, ota_offset); + flash_stream_write(&flash, ota_offset, FLASH_SECTOR_SIZE, pbuf); + flash_stream_read(&flash, ota_offset+OTA_Signature_offset, OTA_Signature_len, signature); + signature[OTA_Signature_len] = '\0'; + printf("Signature = %s\n", signature); + RtlMfree(pbuf, FLASH_SECTOR_SIZE); + printf("Recover OTA signature success.\n"); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + } + +} + +void sys_log_uart_on(void) +{ + HalInitLogUart(); +} + +void sys_log_uart_off(void) +{ + HalDeinitLogUart(); +} + +void sys_adc_calibration(u8 write, u16 *offset, u16 *gain) +{ +extern flash_t flash; + if(write){ + // backup + u8 *pbuf = RtlMalloc(FLASH_SECTOR_SIZE); + if(!pbuf) return; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf); + memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET, offset, 2); + memcpy((char*)pbuf+FLASH_ADC_PARA_OFFSET+2, gain, 2); + flash_erase_sector(&flash, FLASH_RESERVED_DATA_BASE); + flash_stream_write(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf); + // Write +// flash_stream_read(&flash, FLASH_RESERVED_DATA_BASE, FLASH_SECTOR_SIZE, pbuf); + flash_erase_sector(&flash, FLASH_SYSTEM_DATA_ADDR); + flash_stream_write(&flash, FLASH_SYSTEM_DATA_ADDR, FLASH_SECTOR_SIZE, pbuf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + RtlMfree(pbuf, FLASH_SECTOR_SIZE); + printf("Store ADC calibration success.\n"); + } + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, FLASH_ADC_PARA_BASE, 2, (u8*)offset); + flash_stream_read(&flash, FLASH_ADC_PARA_BASE+2, 2, (u8*)gain); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + printf("ADC offset = 0x%04X, gain = 0x%04X.\n", *offset, *gain); +} + +/** + * @brief system software reset + * + * @return None + * + */ +void sys_reset(void) +{ + // Set processor clock to default before system reset + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); + HalDelayUs(100*1000); + + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ +} + +u8 sys_is_sdram_power_on(void) +{ +#ifdef CONFIG_SDR_EN +// u8 ison = 0; + +//#if defined ( __ICCARM__ ) + return IsSdrPowerOn(); +//#endif + +// return ison; +#else + return 0; +#endif +} + +void sys_sdram_off(void) +{ +#ifdef CONFIG_SDR_EN +//#if defined ( __ICCARM__ ) + if (IsSdrPowerOn()) { + SdrPowerOff(); + } +//#endif +#endif +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.c new file mode 100644 index 0000000..836649a --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.c @@ -0,0 +1,156 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ + +#include "objects.h" +//#include +#include "timer_api.h" +//#include "PeripheralNames.h" + +#if CONFIG_TIMER_EN + +extern HAL_TIMER_OP HalTimerOp; + +extern HAL_Status HalTimerInitRtl8195a_Patch( + IN VOID *Data +); + +static void gtimer_timeout_handler (uint32_t tid) +{ + gtimer_t *obj = (gtimer_t *)tid; + gtimer_irq_handler handler; + u8 timer_id = obj->hal_gtimer_adp.TimerId; + + if (obj->handler != NULL) { + handler = (gtimer_irq_handler)obj->handler; + handler(obj->hid); + } + + if (!obj->is_periodcal) { + gtimer_stop(obj); + } + + if(timer_id < 2) { + // Timer0 | Timer1: clear ISR here + // Timer 2~7 ISR will be cleared in HAL + HalTimerClearIsr(timer_id); + } +} + +void gtimer_init (gtimer_t *obj, uint32_t tid) +{ + PTIMER_ADAPTER pTimerAdapter = &(obj->hal_gtimer_adp); + + if ((tid == 1) || (tid == 6) || (tid == 7)) { + DBG_TIMER_ERR("gtimer_init: This timer is reserved for HAL driver\r\n", tid); + return; + } + + if (tid > GTIMER_MAX) { + DBG_TIMER_ERR("gtimer_init: Invalid TimerId=%d\r\n", tid); + return; + } + + pTimerAdapter->IrqDis = 0; // Enable Irq @ initial + pTimerAdapter->IrqHandle.IrqFun = (IRQ_FUN) gtimer_timeout_handler; + if(tid == 0) { + pTimerAdapter->IrqHandle.IrqNum = TIMER0_IRQ; + } else if(tid == 1) { + pTimerAdapter->IrqHandle.IrqNum = TIMER1_IRQ; + } else { + pTimerAdapter->IrqHandle.IrqNum = TIMER2_7_IRQ; + } + pTimerAdapter->IrqHandle.Priority = 0; + pTimerAdapter->IrqHandle.Data = (u32)obj; + pTimerAdapter->TimerId = (u8)tid; + pTimerAdapter->TimerIrqPriority = 0; + pTimerAdapter->TimerLoadValueUs = 0xFFFFFFFF; // Just a whatever value + pTimerAdapter->TimerMode = USER_DEFINED; + + HalTimerInit ((VOID*) pTimerAdapter); +// gtimer_stop(obj); // HAL Initial will let the timer started, just stop it after initial +} + +void gtimer_deinit (gtimer_t *obj) +{ + PTIMER_ADAPTER pTimerAdapter = &(obj->hal_gtimer_adp); + + HalTimerDeInit((void*)pTimerAdapter); +} + +uint32_t gtimer_read_tick (gtimer_t *obj) +{ + PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp; + + return (HalTimerOp.HalTimerReadCount(pTimerAdapter->TimerId)); +} + +uint64_t gtimer_read_us (gtimer_t *obj) +{ + uint64_t time_us; + + time_us = gtimer_read_tick(obj)*1000000/32768; + + return (time_us); +} + +void gtimer_reload (gtimer_t *obj, uint32_t duration_us) +{ + PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp; + + HalTimerReLoad(pTimerAdapter->TimerId, duration_us); +} + + +void gtimer_start (gtimer_t *obj) +{ + PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp; + u8 TimerId = pTimerAdapter->TimerId; + + HalTimerEnable(TimerId); +#if 0 + HalTimerOp.HalTimerEn(pTimerAdapter->TimerId); + + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF), + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) | (BIT0)); +#endif +} + +void gtimer_start_one_shout (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid) +{ + obj->is_periodcal = _FALSE; + obj->handler = handler; + obj->hid = hid; + gtimer_reload(obj, duration_us); + gtimer_start(obj); +} + +void gtimer_start_periodical (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid) +{ + obj->is_periodcal = _TRUE; + obj->handler = handler; + obj->hid = hid; + if (duration_us > GTIMER_TICK_US) { + // reload will takes extra 1 tick + duration_us -= GTIMER_TICK_US; + } + gtimer_reload(obj, duration_us); + gtimer_start(obj); +} + +void gtimer_stop (gtimer_t *obj) +{ + PTIMER_ADAPTER pTimerAdapter = &obj->hal_gtimer_adp; + +// obj->handler = NULL; +// HalTimerOp.HalTimerDis(pTimerAdapter->TimerId); + HalTimerDisable(pTimerAdapter->TimerId); +} + +#endif // end of "#if CONFIG_TIMER_EN" diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.h b/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.h new file mode 100644 index 0000000..e36d485 --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/timer_api.h @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright (c) 2014, Realtek Semiconductor Corp. +* All rights reserved. +* +* This module is a confidential and proprietary property of RealTek and +* possession or use of this module requires written permission of RealTek. +*******************************************************************************/ +#ifndef MBED_EXT_TIMER_API_EXT_H +#define MBED_EXT_TIMER_API_EXT_H + +#include "device.h" +//#include "rtl8195a.h" + +typedef void (*gtimer_irq_handler)(uint32_t id); + +typedef struct gtimer_s gtimer_t; +enum { + TIMER0 = 2, // GTimer 2, share with PWM_3 + TIMER1 = 3, // GTimer 3, share with PWM_0 + TIMER2 = 4, // GTimer 4, share with PWM_1 + TIMER3 = 5, // GTimer 5, share with PWM_2 + TIMER4 = 0, // GTimer 0, share with software-RTC functions + + GTIMER_MAX = 5 +}; + +void gtimer_init (gtimer_t *obj, uint32_t tid); +void gtimer_deinit (gtimer_t *obj); +uint32_t gtimer_read_tick (gtimer_t *obj); +uint64_t gtimer_read_us (gtimer_t *obj); +void gtimer_reload (gtimer_t *obj, uint32_t duration_us); +void gtimer_start (gtimer_t *obj); +void gtimer_start_one_shout (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid); +void gtimer_start_periodical (gtimer_t *obj, uint32_t duration_us, void* handler, uint32_t hid); +void gtimer_stop (gtimer_t *obj); + +#endif diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/us_ticker.c b/USDK/component/common/mbed/targets/hal/rtl8195a/us_ticker.c new file mode 100644 index 0000000..b41dfbc --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/us_ticker.c @@ -0,0 +1,137 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek Semiconductor Corp. + * All rights reserved. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + ******************************************************************************* + */ +#include "objects.h" +#include +#include "us_ticker_api.h" +#include "PeripheralNames.h" + +#define TICK_READ_FROM_CPU 0 // 1: read tick from CPU, 0: read tick from G-Timer +#define SYS_TIM_ID 1 // the G-Timer ID for System +#define APP_TIM_ID 6 // the G-Timer ID for Application + +static int us_ticker_inited = 0; +static TIMER_ADAPTER Timer6Adapter; + +extern HAL_TIMER_OP HalTimerOp; +/* +VOID _us_ticker_irq_handler(IN VOID *Data) +{ + us_ticker_irq_handler(); +} +*/ +void us_ticker_init(void) +{ + + if (us_ticker_inited) return; + us_ticker_inited = 1; + + // Initial a G-Timer + Timer6Adapter.IrqDis = 1; // Disable Irq + Timer6Adapter.IrqHandle.IrqFun = (IRQ_FUN) us_ticker_irq_handler; + Timer6Adapter.IrqHandle.IrqNum = TIMER2_7_IRQ; + Timer6Adapter.IrqHandle.Priority = 10; + Timer6Adapter.IrqHandle.Data = (u32)NULL; + Timer6Adapter.TimerId = APP_TIM_ID; + Timer6Adapter.TimerIrqPriority = 0; + Timer6Adapter.TimerLoadValueUs = 1; + Timer6Adapter.TimerMode = FREE_RUN_MODE; // Countdown Free Run + + HalTimerOp.HalTimerInit((VOID*) &Timer6Adapter); + + DBG_TIMER_INFO("%s: Timer_Id=%d\n", __FUNCTION__, APP_TIM_ID); +} + +#if (!TICK_READ_FROM_CPU) || !defined(PLATFORM_FREERTOS) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +uint32_t us_ticker_read() +{ + uint32_t tick_cnt; + uint32_t ticks_125ms; + uint32_t ticks_remain; + uint64_t us_tick; + + //1 Our G-timer resolution is ~31 us (1/32K), and is a countdown timer +// if (!us_ticker_inited) { +// us_ticker_init(); +// } + tick_cnt = HalTimerOp.HalTimerReadCount(SYS_TIM_ID); + tick_cnt = 0xffffffff - tick_cnt; // it's a down counter + ticks_125ms = tick_cnt/(GTIMER_CLK_HZ/8); + ticks_remain = tick_cnt - (ticks_125ms*(GTIMER_CLK_HZ/8)); + us_tick = ticks_125ms * 125000; + us_tick += (ticks_remain * 1000000)/GTIMER_CLK_HZ; + return ((uint32_t)us_tick); +} +#else +// if the system tick didn't be initialed, call delay function may got system hang +#define OS_CLOCK (200000000UL/6*5) // PLATFORM_CLOCK // CPU clock = 166.66 MHz +#define OS_TICK 1000 // OS ticks 1000/sec +#define OS_TRV ((uint32_t)(((double)OS_CLOCK*(double)OS_TICK)/1E6)-1) +#define NVIC_ST_CTRL (*((volatile uint32_t *)0xE000E010)) +#define NVIC_ST_RELOAD (*((volatile uint32_t *)0xE000E014)) +#define NVIC_ST_CURRENT (*((volatile uint32_t *)0xE000E018)) + +extern uint32_t xTaskGetTickCount( void ); + +uint32_t us_ticker_read() +{ + uint32_t tick_cnt; + uint32_t us_tick, ms; + static uint32_t last_us_tick=0; + + ms = xTaskGetTickCount(); + us_tick = (uint32_t)(ms*1000); + + tick_cnt = OS_TRV - NVIC_ST_CURRENT; + us_tick += (uint32_t)((tick_cnt*1000)/(OS_TRV+1) ); + + if ( (last_us_tick > us_tick) && (last_us_tick < 0xFFFFFC00) ) { + us_tick += 1000; + } + last_us_tick = us_tick; + return us_tick; + +} + +#endif + +void us_ticker_set_interrupt(timestamp_t timestamp) +{ + uint32_t cur_time_us; + uint32_t time_def; + + cur_time_us = us_ticker_read(); + if ((uint32_t)timestamp >= cur_time_us) { + time_def = (uint32_t)timestamp - cur_time_us; + } + else { + time_def = 0xffffffff - cur_time_us + (uint32_t)timestamp; + } + + if (time_def < TIMER_TICK_US) { + time_def = TIMER_TICK_US; // at least 1 tick + } + + Timer6Adapter.IrqDis = 0; // Enable Irq + Timer6Adapter.TimerLoadValueUs = time_def; + Timer6Adapter.TimerMode = USER_DEFINED; // Countdown Free Run + + HalTimerOp.HalTimerInit((VOID*) &Timer6Adapter); +} + +void us_ticker_disable_interrupt(void) +{ + HalTimerOp.HalTimerDis((u32)Timer6Adapter.TimerId); +} + +void us_ticker_clear_interrupt(void) +{ + HalTimerOp.HalTimerIrqClear((u32)Timer6Adapter.TimerId); +} diff --git a/USDK/component/common/mbed/targets/hal/rtl8195a/wdt_api.c b/USDK/component/common/mbed/targets/hal/rtl8195a/wdt_api.c new file mode 100644 index 0000000..eaca62c --- /dev/null +++ b/USDK/component/common/mbed/targets/hal/rtl8195a/wdt_api.c @@ -0,0 +1,94 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, Realtek + * All rights reserved. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis.h" +#include "wdt_api.h" + +extern VOID WDGInitial(u32 Period); +extern VOID WDGStart(VOID); +extern VOID WDGStop(VOID); +extern VOID WDGRefresh(VOID); +extern VOID WDGIrqInitial(VOID); +extern VOID WDGIrqCallBackReg(VOID *CallBack, u32 Id); + +/** + * @brief Initial the watch dog time setting + * + * @param timeout_ms: the watch-dog timer timeout value, in ms. + * default action of timeout is to reset the whole system. + * @return None + * + */ +void watchdog_init(uint32_t timeout_ms) +{ + WDGInitial(timeout_ms); +} + +/** + * @brief Start the watchdog counting + * + * @param None + * @return None + * + */ +void watchdog_start(void) +{ + WDGStart(); +} + +/** + * @brief Stop the watchdog counting + * + * @param None + * @return None + * + */ +void watchdog_stop(void) +{ + WDGStop(); +} + +/** + * @brief Refresh the watchdog counting to prevent WDT timeout + * + * @param None + * @return None + * + */ +void watchdog_refresh(void) +{ + WDGRefresh(); +} + +/** + * @brief Switch the watchdog timer to interrupt mode and + * register a watchdog timer timeout interrupt handler. + * The interrupt handler will be called when the watch-dog + * timer is timeout. + * + * @param handler: the callback function for WDT timeout interrupt. + * id: the parameter for the callback function + * @return None + * + */ +void watchdog_irq_init(wdt_irq_handler handler, uint32_t id) +{ + WDGIrqCallBackReg((VOID*)handler, (u32)id); + WDGIrqInitial(); +} + + diff --git a/USDK/component/common/media/codec/aac/aac.h b/USDK/component/common/media/codec/aac/aac.h new file mode 100644 index 0000000..995bc0e --- /dev/null +++ b/USDK/component/common/media/codec/aac/aac.h @@ -0,0 +1,42 @@ +#ifndef _AAC_H +#define _AAC_H + +#include "dlist.h" //list management +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" + +#define AAC_DEBUG 1 + +#if AAC_DEBUG +#define AAC_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define AAC_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define AAC_PRINTF(fmt, args...) +#define AAC_ERROR(fmt, args...) +#endif + +struct rtp_au_hdr +{ + u32 au_size; //contain AU size in octets(header length included) +#if 0 + u16 au_index; + u16 au_index_delta; + u16 cts_flag; + u16 cts_delta; + u16 dts_flag; + u16 dts_delta; + u16 rap_flag; + u16 stream_state; +#endif + u32 au_header_len; //record AU header size in octets +}; + +struct rtp_aac_obj +{ + u16 au_headers_len; //contain AU header size in octet (we will translate it into bit-wise count before sending) + u8 au_header_num; //contain AU header number +// struct rtp_au_hdr *au_hdr; +}; + +#endif /*_AAC_H*/ \ No newline at end of file diff --git a/USDK/component/common/media/codec/avcodec.h b/USDK/component/common/media/codec/avcodec.h new file mode 100644 index 0000000..377d03a --- /dev/null +++ b/USDK/component/common/media/codec/avcodec.h @@ -0,0 +1,139 @@ +#ifndef _AV_CODEC_H_ +#define _AV_CODEC_H_ + +/* Is this the place to include different codec header for rtp usage?*/ + + +struct codec_info +{ + int codec_id; + const char codec_name[8]; + u8 pt; + u32 clock_rate; + u8 audio_channels; + void *priv; +}; + +/* media type list -- range from 0-255 stored in 1 BYTE*/ +#define AVMEDIA_TYPE_VIDEO 0 +#define AVMEDIA_TYPE_AUDIO 1 +#define AVMEDIA_TYPE_SUBTITLE 2 +#define AVMEDIA_TYPE_UNKNOWN 255 + +/*codec id list -- id must match its placing order (starting from 0) in av_codec_tables*/ + +#define AV_CODEC_ID_MJPEG 0 +#define AV_CODEC_ID_H264 1 +#define AV_CODEC_ID_PCMU 2 +#define AV_CODEC_ID_PCMA 3 +#define AV_CODEC_ID_MP4A_LATM 4 +#define AV_CODEC_ID_MP4V_ES 5 +#define AV_CODEC_ID_UNKNOWN -1 + +/*rtp payload type mapping and standard rtp payload type table -- range from 0-255 in 1 BYTE*/ +#define RTP_PT_PCMU 0 +#define RTP_PT_GSM 3 +#define RTP_PT_G723 4 +#define RTP_PT_DVI4_R8000 5 +#define RTP_PT_DVI4_R16000 6 +#define RTP_PT_LPC 7 +#define RTP_PT_PCMA 8 +#define RTP_PT_G722 9 +#define RTP_PT_L16_C2 10 +#define RTP_PT_L16_C1 11 +#define RTP_PT_QCELP 12 +#define RTP_PT_CN 13 +#define RTP_PT_MPA 14 +#define RTP_PT_G728 15 +#define RTP_PT_DVI4_R11025 16 +#define RTP_PT_DVI4_R22050 17 +#define RTP_PT_G719 18 +#define RTP_PT_CELB 25 +#define RTP_PT_JPEG 26 +#define RTP_PT_NV 28 +#define RTP_PT_H261 31 +#define RTP_PT_MPV 32 +#define RTP_PT_MP2T 33 +#define RTP_PT_H263 34 +#define RTP_PT_RTCP_BASE 72 +#define RTP_PT_DYN_BASE 96 +#define RTP_PT_UNKNOWN 255 +/* AAC PROFILE */ +#define AV_PROFILE_AAC_MAIN 0 +#define AV_PROFILE_AAC_LOW 1 +#define AV_PROFILE_AAC_SSR 2 +#define AV_PROFILE_AAC_LTP 3 +#define AV_PROFILE_AAC_HE 4 +#define AV_PROFILE_AAC_HE_V2 28 +#define AV_PROFILE_AAC_LD 22 +#define AV_PROFILE_AAC_ELD 38 +#define AV_PROFILE_MPEG2_AAC_LOW 128 +#define AV_PROFILE_MPEG2_AAC_HE 131 + +#if 0 +/* MPEG4 VIDEO PROFILE */ +#define AV_PROFILE_MPEG4_SIMPLE 0 +#define AV_PROFILE_MPEG4_SIMPLE_SCALABLE 1 +#define AV_PROFILE_MPEG4_CORE 2 +#define AV_PROFILE_MPEG4_MAIN 3 +#define AV_PROFILE_MPEG4_N_BIT 4 +#define AV_PROFILE_MPEG4_SCALABLE_TEXTURE 5 +#define AV_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6 +#define AV_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7 +#define AV_PROFILE_MPEG4_HYBRID 8 +#define AV_PROFILE_MPEG4_ADVANCED_REAL_TIME 9 +#define AV_PROFILE_MPEG4_CORE_SCALABLE 10 +#define AV_PROFILE_MPEG4_ADVANCED_CODING 11 +#define AV_PROFILE_MPEG4_ADVANCED_CORE 12 +#define AV_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13 +#define AV_PROFILE_MPEG4_SIMPLE_STUDIO 14 +#define AV_PROFILE_MPEG4_ADVANCED_SIMPLE 15 +/* DTS */ +#define AV_PROFILE_DTS 20 +#define AV_PROFILE_DTS_ES 30 +#define AV_PROFILE_DTS_96_24 40 +#define AV_PROFILE_DTS_HD_HRA 50 +#define AV_PROFILE_DTS_HD_MA 60 +#define AV_PROFILE_DTS_EXPRESS 70 +/* MPEG2 */ +#define AV_PROFILE_MPEG2_422 0 +#define AV_PROFILE_MPEG2_HIGH 1 +#define AV_PROFILE_MPEG2_SS 2 +#define AV_PROFILE_MPEG2_SNR_SCALABLE 3 +#define AV_PROFILE_MPEG2_MAIN 4 +#define AV_PROFILE_MPEG2_SIMPLE 5 +/* H264 */ +#define AV_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag +#define AV_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag + +#define AV_PROFILE_H264_BASELINE 66 +#define AV_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED) +#define AV_PROFILE_H264_MAIN 77 +#define AV_PROFILE_H264_EXTENDED 88 +#define AV_PROFILE_H264_HIGH 100 +#define AV_PROFILE_H264_HIGH_10 110 +#define AV_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA) +#define AV_PROFILE_H264_HIGH_422 122 +#define AV_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA) +#define AV_PROFILE_H264_HIGH_444 144 +#define AV_PROFILE_H264_HIGH_444_PREDICTIVE 244 +#define AV_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA) +#define AV_PROFILE_H264_CAVLC_444 44 +#endif + +/*av codec tables*/ +//#include "section_config.h" +//SDRAM_DATA_SECTION +static const struct codec_info av_codec_tables[] = { + {AV_CODEC_ID_MJPEG, "MJPEG", RTP_PT_JPEG, 90000, 0, 0}, + {AV_CODEC_ID_H264, "H264", RTP_PT_DYN_BASE, 90000, 0, 0}, + {AV_CODEC_ID_PCMU, "PCMU", RTP_PT_PCMU, 8000, 1, 0}, + {AV_CODEC_ID_PCMA, "PCMA", RTP_PT_PCMA, 8000, 1, 0}, + {AV_CODEC_ID_MP4A_LATM, "MP4A", RTP_PT_DYN_BASE, 16000, 2, 0}, + {AV_CODEC_ID_MP4V_ES, "MP4V", RTP_PT_DYN_BASE, 90000, 0, 0}, +}; +#define AVCODEC_SIZE 6 + +void get_codec_by_id(struct codec_info *c, int id); + +#endif //_AV_CODEC_H_ \ No newline at end of file diff --git a/USDK/component/common/media/codec/g711/g711.h b/USDK/component/common/media/codec/g711/g711.h new file mode 100644 index 0000000..a64a9ff --- /dev/null +++ b/USDK/component/common/media/codec/g711/g711.h @@ -0,0 +1,27 @@ + +#ifndef _G711_H +#define _G711_H + +#include "dlist.h" //list management +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" + +#define G711_DEBUG 1 + +#if G711_DEBUG +#define G711_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define G711_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define G711_PRINTF(fmt, args...) +#define G711_ERROR(fmt, args...) +#endif + + +//struct rtp_g711_obj { +//}; + + +/*for debug purpose*/ + +#endif /*_G711_H*/ \ No newline at end of file diff --git a/USDK/component/common/media/codec/h264/h264.h b/USDK/component/common/media/codec/h264/h264.h new file mode 100644 index 0000000..c0093fc --- /dev/null +++ b/USDK/component/common/media/codec/h264/h264.h @@ -0,0 +1,75 @@ +#ifndef _H264_H +#define _H264_H + +#include "dlist.h" //list management +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" + +#define H264_DEBUG 0 + +#if H264_DEBUG +#define H264_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define H264_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define H264_PRINTF(fmt, args...) +#define H264_ERROR(fmt, args...) +#endif + +#define MAX_NUM_NAL_PER_FRM 4 + +struct rtp_nal_obj +{ + u8 start_code_len; + unsigned char nal_header; + u8 is_fu_start; + u8 is_fu_end; + u8 must_not_drop; + u8 do_not_send; + int offset; +}; + +struct rtp_h264_obj +{ + int num_nal; + struct rtp_nal_obj nal_obj[MAX_NUM_NAL_PER_FRM]; +}; + +#endif /*_H264_H*/ + +#if 0 + +#ifndef _H264_H +#define _H264_H + +#include "dlist.h" //list management +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" + +#define H264_DEBUG 0 + +#if H264_DEBUG +#define H264_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define H264_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define H264_PRINTF(fmt, args...) +#define H264_ERROR(fmt, args...) +#endif + +/* in favor of rtp fragmentation */ +struct rtp_h264_obj +{ + u8 start_code_len; + unsigned char nal_header; + u8 is_fu_start; + u8 is_fu_end; + u8 must_not_drop; +}; + + +/********************************h264 over rtp******************************/ + + +#endif /*_H264_H*/ +#endif \ No newline at end of file diff --git a/USDK/component/common/media/codec/mjpeg/mjpeg.h b/USDK/component/common/media/codec/mjpeg/mjpeg.h new file mode 100644 index 0000000..c6b0595 --- /dev/null +++ b/USDK/component/common/media/codec/mjpeg/mjpeg.h @@ -0,0 +1,62 @@ + +#ifndef _MJPEG_H +#define _MJPEG_H + +#include "dlist.h" //list management +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" + +#define MJPEG_DEBUG 0 + +#if MJPEG_DEBUG +#define MJPEG_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define MJPEG_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define MJPEG_PRINTF(fmt, args...) +#define MJPEG_ERROR(fmt, args...) +#endif + +struct jpeghdr { + unsigned int tspec:8; /* type-specific field */ + unsigned int off:24; /* fragment byte offset */ + u8 type; /* id of jpeg decoder params */ + u8 q; /* quantization factor (or table id) */ + u8 width; /* frame width in 8 pixel blocks */ + u8 height; /* frame height in 8 pixel blocks */ +}; + +struct jpeghdr_rst { + u16 dri; /*restart interval*/ + unsigned int f:1; /*restart first bit flag*/ + unsigned int l:1; /*restart last bit flag*/ + unsigned int count:14; /*restart count*/ +}; + + +struct jpeghdr_qtable { + u8 mbz; + u8 precision; + u16 length; +}; + +#define RTP_JPEG_RESTART 0x40 +#define USE_EXPLICIT_DQT 128 +#define USE_IMPLICIT_DQT 0 + +struct rtp_jpeg_obj +{ + struct jpeghdr jpghdr; + struct jpeghdr_rst rsthdr; + struct jpeghdr_qtable qtable; + u8 lqt[64*2]; /* Luma Quantizer table */ + u8 cqt[64*2]; /* Croma Quantizer table */ + int hdr_len; + int frame_offset; +}; + +/*for debug purpose*/ +void dumpJpegHeader(struct jpeghdr *jpghdr); +void dumpRstDeader(struct jpeghdr_rst *rsthdr); + +#endif /*_MJPEG_H*/ \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_common.h b/USDK/component/common/media/framework/mmf_common.h new file mode 100644 index 0000000..2b426f5 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_common.h @@ -0,0 +1,89 @@ +#ifndef _EXCHBUF_H +#define _EXCHBUF_H +#include "cmsis_os.h" +#include "errno.h" + +/*service task state*/ +#define S_STOP 0x00 +#define S_RUN 0x01 +#define S_FROZEN 0X02 + +#define CMD_SET_HEIGHT 0x00 +#define CMD_SET_WIDTH 0x01 +#define CMD_SET_BITRATE 0x02 +#define CMD_SET_FRAMERATE 0x03 +#define CMD_SET_CPZRATIO 0x04 +#define CMD_SET_FRAMETYPE 0x05 +#define CMD_SET_SAMPLERATE 0x06 +#define CMD_SET_CHANNEL 0x07 +#define CMD_SET_CODEC 0x08 +#define CMD_SET_STREAMNUM 0x09 +#define CMD_SET_SPS 0x0a +#define CMD_SET_PPS 0x0b +#define CMD_SET_LEVEL 0x0c +#define CMD_SET_APPLY 0x1f +#define CMD_SET_STREAMMING 0x20 +#define CMD_SET_INPUT_QUEUE 0x21 +#define CMD_SET_OUTPUT_QUEUE 0x22 +#define CMD_SET_PRIV_BUF 0x23 +#define CMD_SET_TASK_ON 0x24 +#define CMD_SET_TASK_FROZEN 0x25 +#define CMD_SET_TASK_OFF 0x26 +#define CMD_SELECT_CHANNEL 0x30 +#define CMD_SET_CB_START 0x40 +#define CMD_SET_CB_STOP 0x41 +#define CMD_SET_CB_PAUSE 0x42 +#define CMD_SET_CB_CUSTOMCMD 0x43 +#define CMD_FLUSH 0x50 +#define CMD_SET_FLAG 0X51 +#define CMD_GET_STREAM_READY 0x52 +#define CMD_GET_STREAM_STATUS 0x53 + +/*mp4 storage*/ +#define CMD_SET_ST_PERIOD 0X60 +#define CMD_SET_ST_TOTAL 0X61 +#define CMD_SET_ST_TYPE 0X62 +#define CMD_SET_ST_FILENAME 0x63 +#define CMD_SET_ST_START 0x64 +/*mp4 storage*/ +#define STORAGE_ALL 0 +#define STORAGE_VIDEO 1 +#define STORAGE_AUDIO 2 + +/*exchange buffer state*/ +#define STAT_INIT 0 +#define STAT_USED 1 +#define STAT_READY 2 +#define STAT_RESERVED 3 + +#define TIME_SYNC_EN 0 +#define TIME_SYNC_DIS 1 + +#define FMT_V_MJPG 0x00 +#define FMT_V_H264 0x01 +#define FMT_V_MP4V_ES 0x02 +#define FMT_A_PCMU 0x10 +#define FMT_A_PCMA 0x11 +#define FMT_A_MP4A_LATM 0x12 +#define FMT_AV_UNKNOWN 0xFF + +#define MFT_CMD 0 +#define MFT_DATA 1 +typedef struct _exch_buf{ + //_list node; // linking node + uint32_t type; // CMD, or DATA + uint32_t cmd; // command + uint32_t arg; // command arg + + uint8_t* data; // + uint32_t index; + uint32_t len; + uint32_t timestamp; // 0: not set + uint32_t codec_fmt; // FMT_V_xx or FMT_A_xx + + uint32_t state; + void* priv; // private use +}exch_buf_t; + +typedef int (*mmf_cb_t)(void*); +#endif diff --git a/USDK/component/common/media/framework/mmf_sink.h b/USDK/component/common/media/framework/mmf_sink.h new file mode 100644 index 0000000..19ede8c --- /dev/null +++ b/USDK/component/common/media/framework/mmf_sink.h @@ -0,0 +1,30 @@ +#ifndef _STREAM_H +#define _STREAM_H +#include "cmsis_os.h" +#include "mmf_common.h" + +typedef struct _media_sink_module{ + void* (*create)(void); + void (*destroy)(void*); + int (*set_param)(void*, int, int); + int (*handle)(void*, void*); +}msink_module_t; + +typedef struct _media_sink_context{ + xQueueHandle input_qid; + xQueueHandle output_qid; + int state; + xTaskHandle hdl_task; + + void* drv_priv; // private data for module + msink_module_t *sink; +}msink_context; + +void mmf_sink_close(msink_context* ctx); +msink_context* mmf_sink_open(msink_module_t *sink); +int mmf_sink_ctrl(msink_context* ctx, int cmd, int arg); +int mmf_sink_put_frame(msink_context* ctx, exch_buf_t* exbuf); + +// must be here +#include "mmf_sink_modules/mmf_sink_list.h" +#endif diff --git a/USDK/component/common/media/framework/mmf_sink_modules/mmf_sink_list.h b/USDK/component/common/media/framework/mmf_sink_modules/mmf_sink_list.h new file mode 100644 index 0000000..4c5da42 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_sink_modules/mmf_sink_list.h @@ -0,0 +1,10 @@ +#ifndef _STREAM_MODULES_H +#define _STREAM_MODULES_H +#include "../mmf_sink.h" + +//list all avaliable modules here +extern msink_module_t rtsp_module; +extern msink_module_t rtsp2_module; +extern msink_module_t i2s_sink_module; +extern msink_module_t mp4_module; +#endif \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source.h b/USDK/component/common/media/framework/mmf_source.h new file mode 100644 index 0000000..ed5c877 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source.h @@ -0,0 +1,32 @@ +#ifndef _MEDIA_H +#define _MEDIA_H +#include "cmsis_os.h" +#include "mmf_common.h" + +typedef struct _media_source_module{ + void* (*create)(void); + void (*destroy)(void*); + int (*set_param)(void*, int, int); + int (*handle)(void*, void*); // input output will cast to exch_buf_t +}msrc_module_t; + + + +typedef struct _media_source_context{ + xQueueHandle input_qid; + xQueueHandle output_qid; + int state; + xTaskHandle hdl_task; + + void* drv_priv; + msrc_module_t* source; +}msrc_context; + +void mmf_source_close(msrc_context* ctx); +msrc_context* mmf_source_open(msrc_module_t* source); +int mmf_source_ctrl(msrc_context* ctx, int cmd, int arg); +int mmf_source_get_frame(msrc_context* ctx, exch_buf_t *exbuf); + +// must be here +#include "mmf_source_modules/mmf_source_list.h" +#endif diff --git a/USDK/component/common/media/framework/mmf_source_modules/driver/geo/patch_uvc_geo.h b/USDK/component/common/media/framework/mmf_source_modules/driver/geo/patch_uvc_geo.h new file mode 100644 index 0000000..db4db07 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/driver/geo/patch_uvc_geo.h @@ -0,0 +1,1414 @@ +#ifndef _PATCH_UVC_GEO_H_ +#define _PATCH_UVC_GEO_H_ + +#include "videodev2.h" + +#define be32_to_cpu(x) ((((x) >> 24) & 0xff) | \ + (((x) >> 8) & 0xff00) | \ + (((x) << 8) & 0xff0000) | \ + (((x) << 24) & 0xff000000)) +#define be24_to_cpu(a) \ + ((((a)>>16)&0xFF) | \ + ((a)&0xFF00) | \ + (((a)<<16)&0xFF0000)) +#define be16_to_cpu(x) ((((x) >> 8) & 0xff) | \ + (((x) << 8) & 0xff00)) + +//#define BUFFER_COUNT 8 +#define V4L2_CID_PRIV_EXT_BASE (0x04000000) +#define V4L2_CID_XU_BASE (V4L2_CID_PRIVATE_BASE|V4L2_CID_PRIV_EXT_BASE) + +#define V4L2_CID_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 0) +#define V4L2_CID_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 1) +#define V4L2_CID_XU_PICTURE_CODING (V4L2_CID_XU_BASE + 2) +#define V4L2_CID_XU_RESOLUTION (V4L2_CID_XU_BASE + 3) +#define V4L2_CID_XU_RESOLUTION2 (V4L2_CID_XU_BASE + 4) +#define V4L2_CID_XU_GOP_STRUCTURE (V4L2_CID_XU_BASE + 5) +#define V4L2_CID_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 6) +#define V4L2_CID_XU_FRAME_RATE (V4L2_CID_XU_BASE + 7) +#define V4L2_CID_XU_BITRATE (V4L2_CID_XU_BASE + 8) +#define V4L2_CID_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 9) +#define V4L2_CID_XU_GET_VERSION (V4L2_CID_XU_BASE + 10) +#define V4L2_CID_XU_MAX_NAL (V4L2_CID_XU_BASE + 11) + +#define V4L2_CID_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 30) +#define V4L2_CID_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 31) +#define V4L2_CID_XU_AV_MUX_ENABLE (V4L2_CID_XU_BASE + 32) +#define V4L2_CID_XU_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 33) + +//mux channel xu's +//mux1 h264 +#define V4L2_CID_MUX_CH1_XU_RESOLUTION (V4L2_CID_XU_BASE + 0) +#define V4L2_CID_MUX_CH1_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 1) +#define V4L2_CID_MUX_CH1_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 2) +#define V4L2_CID_MUX_CH1_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 3) +#define V4L2_CID_MUX_CH1_XU_ZOOM (V4L2_CID_XU_BASE + 4) +#define V4L2_CID_MUX_CH1_XU_BITRATE (V4L2_CID_XU_BASE + 5) +#define V4L2_CID_MUX_CH1_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 6) +#define V4L2_CID_MUX_CH1_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 7) +#define V4L2_CID_MUX_CH1_XU_CHCOUNT (V4L2_CID_XU_BASE + 8) +#define V4L2_CID_MUX_CH1_XU_CHTYPE (V4L2_CID_XU_BASE + 9) +#define V4L2_CID_MUX_CH1_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 10) +#define V4L2_CID_MUX_CH1_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 11) +#define V4L2_CID_MUX_CH1_XU_AVC_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 12) +#define V4L2_CID_MUX_CH1_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 13) +#define V4L2_CID_MUX_CH1_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 14) +#define V4L2_CID_MUX_CH1_XU_VFLIP (V4L2_CID_XU_BASE + 15) +#define V4L2_CID_MUX_CH1_XU_AUDIO_BITRATE (V4L2_CID_XU_BASE + 16) + +//mux2 h264/mjpeg +#define V4L2_CID_MUX_CH2_XU_RESOLUTION (V4L2_CID_XU_BASE + 17) +#define V4L2_CID_MUX_CH2_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 18) +#define V4L2_CID_MUX_CH2_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 19) +#define V4L2_CID_MUX_CH2_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 20) +#define V4L2_CID_MUX_CH2_XU_ZOOM (V4L2_CID_XU_BASE + 21) +#define V4L2_CID_MUX_CH2_XU_BITRATE (V4L2_CID_XU_BASE + 22) +#define V4L2_CID_MUX_CH2_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 23) +#define V4L2_CID_MUX_CH2_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 24) +#define V4L2_CID_MUX_CH2_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 25) +#define V4L2_CID_MUX_CH2_XU_CHTYPE (V4L2_CID_XU_BASE + 26) +#define V4L2_CID_MUX_CH2_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 27) +#define V4L2_CID_MUX_CH2_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 28) +#define V4L2_CID_MUX_CH2_XU_AVC_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 29) +#define V4L2_CID_MUX_CH2_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 30) + +//mux3 h264/mjpeg +#define V4L2_CID_MUX_CH3_XU_RESOLUTION (V4L2_CID_XU_BASE + 33) +#define V4L2_CID_MUX_CH3_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 34) +#define V4L2_CID_MUX_CH3_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 35) +#define V4L2_CID_MUX_CH3_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 36) +#define V4L2_CID_MUX_CH3_XU_ZOOM (V4L2_CID_XU_BASE + 37) +#define V4L2_CID_MUX_CH3_XU_BITRATE (V4L2_CID_XU_BASE + 38) +#define V4L2_CID_MUX_CH3_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 39) +#define V4L2_CID_MUX_CH3_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 40) +#define V4L2_CID_MUX_CH3_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 41) +#define V4L2_CID_MUX_CH3_XU_CHTYPE (V4L2_CID_XU_BASE + 42) +#define V4L2_CID_MUX_CH3_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 43) +#define V4L2_CID_MUX_CH3_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 44) +#define V4L2_CID_MUX_CH3_XU_AVC_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 45) +#define V4L2_CID_MUX_CH3_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 46) + +//mux4 h264/mjpeg +#define V4L2_CID_MUX_CH4_XU_RESOLUTION (V4L2_CID_XU_BASE + 47) +#define V4L2_CID_MUX_CH4_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 48) +#define V4L2_CID_MUX_CH4_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 49) +#define V4L2_CID_MUX_CH4_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 50) +#define V4L2_CID_MUX_CH4_XU_ZOOM (V4L2_CID_XU_BASE + 51) +#define V4L2_CID_MUX_CH4_XU_BITRATE (V4L2_CID_XU_BASE + 52) +#define V4L2_CID_MUX_CH4_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 53) +#define V4L2_CID_MUX_CH4_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 54) +#define V4L2_CID_MUX_CH4_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 55) +#define V4L2_CID_MUX_CH4_XU_CHTYPE (V4L2_CID_XU_BASE + 56) +#define V4L2_CID_MUX_CH4_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 57) +#define V4L2_CID_MUX_CH4_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 58) +#define V4L2_CID_MUX_CH4_XU_AVC_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 59) +#define V4L2_CID_MUX_CH4_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 60) + +//mux5 +#define V4L2_CID_MUX_CH5_XU_RESOLUTION (V4L2_CID_XU_BASE + 62) +#define V4L2_CID_MUX_CH5_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 63) +#define V4L2_CID_MUX_CH5_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 64) +#define V4L2_CID_MUX_CH5_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 65) +#define V4L2_CID_MUX_CH5_XU_ZOOM (V4L2_CID_XU_BASE + 66) +#define V4L2_CID_MUX_CH5_XU_BITRATE (V4L2_CID_XU_BASE + 67) +#define V4L2_CID_MUX_CH5_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 68) +#define V4L2_CID_MUX_CH5_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 69) +#define V4L2_CID_MUX_CH5_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 70) +#define V4L2_CID_MUX_CH5_XU_CHTYPE (V4L2_CID_XU_BASE + 71) +#define V4L2_CID_MUX_CH5_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 72) +#define V4L2_CID_MUX_CH5_XU_AVC_PROFILE (V4L2_CID_XU_BASE + 73) +#define V4L2_CID_MUX_CH5_XU_AVC_MAX_FRAME_SIZE (V4L2_CID_XU_BASE + 74) +#define V4L2_CID_MUX_CH5_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 75) +//mux6 +#define V4L2_CID_MUX_CH6_XU_RESOLUTION (V4L2_CID_XU_BASE + 78) +#define V4L2_CID_MUX_CH6_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 79) +#define V4L2_CID_MUX_CH6_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 80) +#define V4L2_CID_MUX_CH6_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 81) +#define V4L2_CID_MUX_CH6_XU_ZOOM (V4L2_CID_XU_BASE + 82) +#define V4L2_CID_MUX_CH6_XU_BITRATE (V4L2_CID_XU_BASE + 83) +#define V4L2_CID_MUX_CH6_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 84) +#define V4L2_CID_MUX_CH6_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 85) +#define V4L2_CID_MUX_CH6_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 86) +#define V4L2_CID_MUX_CH6_XU_CHTYPE (V4L2_CID_XU_BASE + 87) +#define V4L2_CID_MUX_CH6_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 88) +#define V4L2_CID_MUX_CH6_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 89) + +//mux7 +#define V4L2_CID_MUX_CH7_XU_RESOLUTION (V4L2_CID_XU_BASE + 95) +#define V4L2_CID_MUX_CH7_XU_FRAMEINTRVL (V4L2_CID_XU_BASE + 96) +#define V4L2_CID_MUX_CH7_XU_PIC_TIMING_ENABLE (V4L2_CID_XU_BASE + 97) +#define V4L2_CID_MUX_CH7_XU_GOP_HIERARCHY_LEVEL (V4L2_CID_XU_BASE + 98) +#define V4L2_CID_MUX_CH7_XU_ZOOM (V4L2_CID_XU_BASE + 99) +#define V4L2_CID_MUX_CH7_XU_BITRATE (V4L2_CID_XU_BASE + 100) +#define V4L2_CID_MUX_CH7_XU_FORCE_I_FRAME (V4L2_CID_XU_BASE + 101) +#define V4L2_CID_MUX_CH7_XU_VUI_ENABLE (V4L2_CID_XU_BASE + 102) +#define V4L2_CID_MUX_CH7_XU_COMPRESSION_Q (V4L2_CID_XU_BASE + 103) +#define V4L2_CID_MUX_CH7_XU_CHTYPE (V4L2_CID_XU_BASE + 104) +#define V4L2_CID_MUX_CH7_XU_GOP_LENGTH (V4L2_CID_XU_BASE + 105) +#define V4L2_CID_MUX_CH7_XU_AVC_LEVEL (V4L2_CID_XU_BASE + 106) + +//common mux xu +#define V4L2_CID_MUX_XU_START_CHANNEL (V4L2_CID_XU_BASE + 107) +#define V4L2_CID_MUX_XU_STOP_CHANNEL (V4L2_CID_XU_BASE + 108) + +#define V4L2_CID_PU_XU_ANF_ENABLE (V4L2_CID_XU_BASE + 110) +#define V4L2_CID_PU_XU_NF_STRENGTH (V4L2_CID_XU_BASE + 111) +// Following are new define for Condor ISP API's +#define V4L2_CID_PU_XU_SINTER_MODE (V4L2_CID_XU_BASE + 112) +#define V4L2_CID_PU_XU_SINTER_MIN_NRSTR (V4L2_CID_XU_BASE + 113) +#define V4L2_CID_PU_XU_SINTER_MAX_NRSTR (V4L2_CID_XU_BASE + 114) +#define V4L2_CID_PU_XU_SINTER_MIN_THR (V4L2_CID_XU_BASE + 115) +#define V4L2_CID_PU_XU_SINTER_MAX_THR (V4L2_CID_XU_BASE + 116) +#define V4L2_CID_PU_XU_SINTER_TRIGPT (V4L2_CID_XU_BASE + 117) + + + +#define V4L2_CID_PU_XU_TF_STRENGTH (V4L2_CID_XU_BASE + 118) +#define V4L2_CID_PU_XU_ADAPTIVE_WDR_ENABLE (V4L2_CID_XU_BASE + 119) +#define V4L2_CID_PU_XU_WDR_STRENGTH (V4L2_CID_XU_BASE + 120) +#define V4L2_CID_PU_XU_AUTO_EXPOSURE (V4L2_CID_XU_BASE + 121) +#define V4L2_CID_PU_XU_EXPOSURE_TIME (V4L2_CID_XU_BASE + 122) +#define V4L2_CID_PU_XU_AUTO_WHITE_BAL (V4L2_CID_XU_BASE + 123) +#define V4L2_CID_PU_XU_WHITE_BAL_TEMP (V4L2_CID_XU_BASE + 124) +#define V4L2_CID_PU_XU_VFLIP (V4L2_CID_XU_BASE + 125) +#define V4L2_CID_PU_XU_HFLIP (V4L2_CID_XU_BASE + 126) +#define V4L2_CID_PU_XU_WB_ZONE_SEL_ENABLE (V4L2_CID_XU_BASE + 127) +#define V4L2_CID_PU_XU_WB_ZONE_SEL (V4L2_CID_XU_BASE + 128) +#define V4L2_CID_PU_XU_EXP_ZONE_SEL_ENABLE (V4L2_CID_XU_BASE + 129) +#define V4L2_CID_PU_XU_EXP_ZONE_SEL (V4L2_CID_XU_BASE + 130) +#define V4L2_CID_PU_XU_MAX_ANALOG_GAIN (V4L2_CID_XU_BASE + 131) +#define V4L2_CID_PU_XU_HISTO_EQ (V4L2_CID_XU_BASE + 132) +#define V4L2_CID_PU_XU_SHARPEN_FILTER (V4L2_CID_XU_BASE + 133) +#define V4L2_CID_PU_XU_GAIN_MULTIPLIER (V4L2_CID_XU_BASE + 134) +#define V4L2_CID_PU_XU_CROP_CHANNEL (V4L2_CID_XU_BASE + 135) +#define V4L2_CID_PU_XU_CROP_ENABLE (V4L2_CID_XU_BASE + 136) +#define V4L2_CID_PU_XU_CROP_WIDTH (V4L2_CID_XU_BASE + 137) +#define V4L2_CID_PU_XU_CROP_HEIGHT (V4L2_CID_XU_BASE + 138) +#define V4L2_CID_PU_XU_CROP_X (V4L2_CID_XU_BASE + 139) +#define V4L2_CID_PU_XU_CROP_Y (V4L2_CID_XU_BASE + 140) +#define V4L2_CID_PU_XU_EXP_MIN_FR_RATE (V4L2_CID_XU_BASE + 141) +#define V4L2_CID_PU_XU_SATURATION_MODE (V4L2_CID_XU_BASE + 142) +#define V4L2_CID_PU_XU_BRIGHTNESS_MODE (V4L2_CID_XU_BASE + 143) +#define V4L2_CID_PU_XU_CONTRAST_MODE (V4L2_CID_XU_BASE + 144) + +//dewarp xu's +#define V4L2_CID_MUX_CH1_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 150) +#define V4L2_CID_MUX_CH2_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 158) +#define V4L2_CID_MUX_CH3_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 161) +#define V4L2_CID_MUX_CH4_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 164) +#define V4L2_CID_MUX_CH5_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 167) +#define V4L2_CID_MUX_CH6_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 170) +#define V4L2_CID_MUX_CH7_XU_DEWRP_CHANNEL (V4L2_CID_XU_BASE + 173) +#define V4L2_CID_MUX_CH1_XU_CROP_CHANNEL (V4L2_CID_XU_BASE + 174) +//dewarp xu end + +#define V4L2_CID_PU_XU_DEWARP_CHANNEL (V4L2_CID_XU_BASE + 176) +#define V4L2_CID_PU_XU_DEWARP_PANEL (V4L2_CID_XU_BASE + 177) +#define V4L2_CID_PU_XU_DEWARP_MODE (V4L2_CID_XU_BASE + 178) +#define V4L2_CID_PU_XU_DEWARP_PARAM0 (V4L2_CID_XU_BASE + 179) +#define V4L2_CID_PU_XU_DEWARP_PARAM1 (V4L2_CID_XU_BASE + 180) +#define V4L2_CID_PU_XU_DEWARP_PARAM2 (V4L2_CID_XU_BASE + 181) +#define V4L2_CID_PU_XU_DEWARP_PARAM3 (V4L2_CID_XU_BASE + 182) +#define V4L2_CID_PU_XU_DEWARP_PARAM4 (V4L2_CID_XU_BASE + 183) +#define V4L2_CID_PU_XU_DEWARP_PARAM5 (V4L2_CID_XU_BASE + 184) +#define V4L2_CID_PU_XU_DEWARP_PARAM6 (V4L2_CID_XU_BASE + 185) +#define V4L2_CID_PU_XU_DEWARP_PARAM7 (V4L2_CID_XU_BASE + 186) +#define V4L2_CID_PU_XU_DEWARP_PARAM8 (V4L2_CID_XU_BASE + 187) +#define V4L2_CID_PU_XU_DEWARP_PARAM9 (V4L2_CID_XU_BASE + 188) +//dewarp xu end + +#define V4L2_CID_PU_XU_COMPOSITOR_CHANNEL (V4L2_CID_XU_BASE + 189) +#define V4L2_CID_PU_XU_COMPOSITOR_PANEL_ID (V4L2_CID_XU_BASE + 190) +#define V4L2_CID_PU_XU_COMPOSITOR_MODE (V4L2_CID_XU_BASE + 191) +#define V4L2_CID_PU_XU_COMPOSITOR_PARAM0 (V4L2_CID_XU_BASE + 192) +#define V4L2_CID_PU_XU_COMPOSITOR_PARAM1 (V4L2_CID_XU_BASE + 193) +#define V4L2_CID_PU_XU_COMPOSITOR_PARAM2 (V4L2_CID_XU_BASE + 194) +#define V4L2_CID_PU_XU_COMPOSITOR_PARAM3 (V4L2_CID_XU_BASE + 195) +#define V4L2_CID_PU_XU_COMPOSITOR_PARAM4 (V4L2_CID_XU_BASE + 196) + +#define V4L2_CID_PU_XU_CONFIG_PARAM0 (V4L2_CID_XU_BASE + 197) +#define V4L2_CID_PU_XU_CONFIG_PARAM1 (V4L2_CID_XU_BASE + 198) +#define V4L2_CID_PU_XU_CONFIG_PARAM2 (V4L2_CID_XU_BASE + 199) +#define V4L2_CID_PU_XU_CONFIG_PARAM3 (V4L2_CID_XU_BASE + 200) +#define V4L2_CID_PU_XU_CONFIG_PARAM4 (V4L2_CID_XU_BASE + 201) +#define V4L2_CID_PU_XU_CONFIG_PARAM5 (V4L2_CID_XU_BASE + 202) +#define V4L2_CID_PU_XU_CONFIG_PARAM6 (V4L2_CID_XU_BASE + 203) +#define V4L2_CID_PU_XU_CONFIG_PARAM7 (V4L2_CID_XU_BASE + 204) + +#define V4L2_CID_MUX_CH1_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 205) +#define V4L2_CID_MUX_CH2_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 206) +#define V4L2_CID_MUX_CH3_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 207) +#define V4L2_CID_MUX_CH4_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 208) +#define V4L2_CID_MUX_CH5_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 209) +#define V4L2_CID_MUX_CH6_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 210) +#define V4L2_CID_MUX_CH7_XU_VBR_MIN_BITRATE (V4L2_CID_XU_BASE + 211) +#define V4L2_CID_XU_END (V4L2_CID_XU_BASE + 212) + +/* GUIDs */ +/* {303B461D-BC63-44c3-8230-6741CAEB5D77} */ +#define GUID_VIDCAP_EXT \ + {0x1d, 0x46, 0x3b, 0x30, 0x63, 0xbc, 0xc3, 0x44,\ + 0x82, 0x30, 0x67, 0x41, 0xca, 0xeb, 0x5d, 0x77} +/* {6DF18A70-C113-428e-88C5-4AFF0E286AAA} */ +#define GUID_VIDENC_EXT \ + {0x70, 0x8a, 0xf1, 0x6d, 0x13, 0xc1, 0x8e, 0x42,\ + 0x88, 0xc5, 0x4a, 0xff, 0x0e, 0x28, 0x6a, 0xaa} +/* {ba2b92d9-26f2-4294-ae42-06dd684debe4} */ +#define AVC_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xba, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX1_XU_GUID AVC_XU_GUID +#define MUX2_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xbb, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX3_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xbc, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX4_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xbd, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX5_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xbe, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX6_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xbf, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} +#define MUX7_XU_GUID \ + {0xd9, 0x92, 0x2b, 0xc0, 0xf2, 0x26, 0x94, 0x42,\ + 0x42, 0xae, 0xe4, 0xeb, 0x4d, 0x68, 0xdd, 0x06} + +#define PU_XU_GUID \ + {0x12, 0xcd, 0x5d, 0xdf, 0x5f, 0x7d, 0xba, 0x4b,\ + 0xbb, 0x6d, 0x4b, 0x62, 0x5a, 0xdd, 0x52, 0x72} + + +#define V4L2_CID_DIGITIAL_MULTIPLIER (V4L2_CID_CAMERA_CLASS_BASE+32) + +// framerate in 100 nsec units //TBD correctly +#define FRI(x) ((float)10000000/x) //TBD +#define FRR(x) ((float)10000000/(x+0.0)) + +/** Image Name Length */ +#define IH_NMLEN 32 + +enum MUX_XU_CTRL { + //for all video channels + MUX_XU_RESOLUTION = 1, + MUX_XU_FRAMEINTRVL, + MUX_XU_PIC_TIMING_ENABLE, + MUX_XU_GOP_HIERARCHY_LEVEL, + MUX_XU_ZOOM, + + //for H264 based channels only + MUX_XU_BITRATE, + MUX_XU_FORCE_I_FRAME, + MUX_XU_VUI_ENABLE, + MUX_XU_AVC_LEVEL, + + //for MJPEG channel only + MUX_XU_COMPRESSION_Q, + + MUX_XU_CHCOUNT, + MUX_XU_CHTYPE, + MUX_XU_GOP_LENGTH, + MUX_XU_AVC_PROFILE, + MUX_XU_AVC_MAX_FRAME_SIZE, + MUX_XU_START_CHANNEL, + MUX_XU_STOP_CHANNEL, + MUX_XU_HFLIP, + MUX_XU_VFLIP, + + //Audio bitrate + MUX_XU_AUDIO_BITRATE, + + //dewarp xu's + MUX_XU_DEWRP_CHANNEL, + + // vbr params for avc + MUX_XU_VBR_MIN_BITRATE, + MUX_XU_VBR_SETTLING_TIME, //Not used + + MUX_XU_NUM_CTRLS, +}; + +/* Controls in the XU */ +enum PU_XU_CTRL { + PU_XU_ANF_ENABLE = 1, + PU_XU_NF_STRENGTH, + PU_XU_TF_STRENGTH, + PU_XU_SINTER, + PU_XU_ADAPTIVE_WDR_ENABLE, + PU_XU_WDR_STRENGTH, + PU_XU_AE_ENABLE, + PU_XU_EXPOSURE_TIME, + PU_XU_AWB_ENABLE, + PU_XU_WB_TEMPERATURE, + PU_XU_VFLIP, + PU_XU_HFLIP, + PU_XU_WB_ZONE_SEL_ENABLE, + PU_XU_WB_ZONE_SEL, + PU_XU_EXP_ZONE_SEL_ENABLE, + PU_XU_EXP_ZONE_SEL, + PU_XU_MAX_ANALOG_GAIN, + PU_XU_HISTO_EQ, + PU_XU_SHARPEN_FILTER, + PU_XU_GAIN_MULTIPLIER, + PU_XU_CROP, + PU_XU_EXP_MIN_FR_RATE, + PU_XU_DEWARP_PARAMS1, + PU_XU_DEWARP_PARAMS2, + PU_XU_COMPOSITOR_PARAMS, + PU_XU_CONFIG_PARAMS, + PU_XU_SATURATION_MODE, + PU_XU_BRIGHTNESS_MODE, + PU_XU_CONTRAST_MODE, + PU_XU_MVMT_QUERY, + PU_XU_SENSOR_FRAMERATE, + PU_XU_AEROI, +}; + +typedef enum { + /** Success (no error) */ + MXCAM_OK = 0, + /** Started EEPROM FW Upgrade */ + MXCAM_STAT_EEPROM_FW_UPGRADE_START,//1 + /** Completed EEPROM FW Upgrade */ + MXCAM_STAT_EEPROM_FW_UPGRADE_COMPLETE,//2 + /** Started SNOR FW Upgrade */ + MXCAM_STAT_SNOR_FW_UPGRADE_START,//3 + /** Completed SNOR FW Upgrade */ + MXCAM_STAT_SNOR_FW_UPGRADE_COMPLETE,//4 + /** Completed FW Upgrade */ + MXCAM_STAT_FW_UPGRADE_COMPLETE,//5 + /** EEPROM Erase in progress */ + MXCAM_STAT_EEPROM_ERASE_IN_PROG,//6 + /** EEPROM config save in progress */ + MXCAM_STAT_EEPROM_SAVE_IN_PROG,//7 + /** ERR numbers starts here */ + MXCAM_ERR_FAIL = 128, + /** FW Image is corrupted */ + MXCAM_ERR_FW_IMAGE_CORRUPTED,//129 + /** SNOR FW upgrade failed */ + MXCAM_ERR_FW_SNOR_FAILED,//130 + /** Unsupported Flash memory */ + MXCAM_ERR_FW_UNSUPPORTED_FLASH_MEMORY,//131 + /** Erase size exceeds MAX_VEND_SIZE */ + MXCAM_ERR_ERASE_SIZE,//132 + /** Unknown area to erase */ + MXCAM_ERR_ERASE_UNKNOWN_AREA,//133 + /** Unknown area to save */ + MXCAM_ERR_SAVE_UNKNOWN_AREA,//134 + /** Not enough memory to save new key on memory */ + MXCAM_ERR_SETKEY_OVER_FLOW_NO_MEM,//135 + /** Unknown area to set key */ + MXCAM_ERR_SETKEY_UNKNOWN_AREA,//136 + /** Unknown area to remove key */ + MXCAM_ERR_REMOVE_KEY_UNKNOWN_AREA,//137 + /** Unknown area to get key */ + MXCAM_ERR_GETVALUE_UNKNOWN_AREA,//138 + /** Value not found for given key */ + MXCAM_ERR_GETVLAUE_KEY_NOT_FOUND,//139 + /** Failed to read TCW from flash */ + MXCAM_ERR_TCW_FLASH_READ,//140 + /** Failed to write TCW on flash */ + MXCAM_ERR_TCW_FLASH_WRITE,//141 + /** Failed to allocate memory on camera*/ + MXCAM_ERR_MEMORY_ALLOC,//142 + /** Vendor area is not initialized */ + MXCAM_ERR_VEND_AREA_NOT_INIT,//143 + /** Json syntax error */ + MXCAM_ERR_VEND_ERR_JSON_SYNTAX_ERR, //144 + MXCAM_ERR_SETKEY_UNSUPPORTED, //145 + /** Ispcfg syntax error */ + MXCAM_ERR_VEND_ERR_ISPCFG_SYNTAX_ERR, //146 + //Don't change the above values + /** Unknown area to get config size */ + MXCAM_ERR_GET_CFG_SIZE_UNKNOWN_AREA = 150, + /** Invalid parameter(s) */ + MXCAM_ERR_INVALID_PARAM,//151 + /** Not a valid device */ + MXCAM_ERR_INVALID_DEVICE,//152 + /** Failed to send image */ + MXCAM_ERR_IMAGE_SEND_FAILED,//153 + /** File not found */ + MXCAM_ERR_FILE_NOT_FOUND,//154 + /** Not enough memory */ + MXCAM_ERR_NOT_ENOUGH_MEMORY,//155 + /** Not a valid image */ + MXCAM_ERR_NOT_VALID_IMAGE,//156 + /** vid and pid already registered */ + MXCAM_ERR_VID_PID_ALREADY_REGISTERED,//157 + /** device not found */ + MXCAM_ERR_DEVICE_NOT_FOUND,//158 + /** vendor area not initialized*/ + MXCAM_ERR_UNINITIALIZED_VENDOR_MEMORY,//159 + /** feature not supported*/ + MXCAM_ERR_FEATURE_NOT_SUPPORTED,//160 + /** i2c read error */ + MXCAM_ERR_I2C_READ = 180, + /** i2c write error */ + MXCAM_ERR_I2C_WRITE, + /** spi read-write error */ + MXCAM_ERR_SPI_RW, + /** Invalid bootloader used */ + MXCAM_ERR_INVALID_BOOTLOADER, + /** PWMLED is active **/ + MXCAM_ERR_PWMLED_ACTIVE +} MXCAM_STAT_ERR; + +typedef enum { + RUNNING_FW_HEADER = 0, + SNOR_FW_HEADER, + BOOTLOADER_HEADER, + UNDEFINED, +} IMG_HDR_TYPE; + +typedef struct image_header { + /** Image Header Magic Number 0x27051956 */ + uint32_t ih_magic; + /** Image Header CRC Checksum */ + uint32_t ih_hcrc; + /** Image Creation Timestamp in in ctime format*/ + uint32_t ih_time; + /** Image Data Size */ + uint32_t ih_size; + /** Data Load Address */ + uint32_t ih_load; + /** Entry Point Address */ + uint32_t ih_ep; + /** Image Data CRC Check sum */ + uint32_t ih_dcrc; + /** Operating System */ + uint8_t ih_os; + /** CPU architecture */ + uint8_t ih_arch; + /** Image Type */ + uint8_t ih_type; + /** Compression Type */ + uint8_t ih_comp; + /** Image Name */ + uint8_t ih_name[IH_NMLEN]; +} image_header_t; + + +#define QMED_BOX_TYPE 0x716d6564 +#define QMED_MAJOR_MEDIA_TYPE_AAC 0x1 +#define QMED_MAJOR_MEDIA_TYPE_H264 0x2 +#define QMED_MAJOR_MEDIA_TYPE_PCM 0x3 +#define QMED_MAJOR_MEDIA_TYPE_MP2 0x6 +#define QMED_MAJOR_MEDIA_TYPE_JPEG 0x7 +#define QMED_MAJOR_MEDIA_TYPE_Q711 0x9 +#define QMED_MAJOR_MEDIA_TYPE_Q728 0xa +#define QMED_MAJOR_MEDIA_TYPE_Q722 0xb +#define QMED_MAJOR_MEDIA_TYPE_Q726 0xc +#define QMED_MAJOR_MEDIA_TYPE_QOPUS 0xd +#define QMED_MAJOR_MEDIA_TYPE_MAX 0xe + +#define QMED_MINOR_MEDIA_TYPE_Q711_ALAW 0x0 +#define QMED_MINOR_MEDIA_TYPE_Q711_ULAW 0x1 +#define QMED_MINOR_MEDIA_TYPE_Q726_ITU_BYTE_ORDER 0x0 +#define QMED_MINOR_MEDIA_TYPE_Q726_IETF_BYTE_ORDER 0x1 + +#define QMED_VERSION (A) ((A >> 24) && 0xff) + +#define QMED_SHA_SIZE 8 + +/** enum of video format used in a particular channel */ +typedef enum { + FIRST_VID_FORMAT = 0, + /** H264 in elementary stream format */ + VID_FORMAT_H264_RAW = 0, + /** H264 in transport stream format */ + VID_FORMAT_H264_TS = 1, + /** MJPEG in elmentary stream format */ + VID_FORMAT_MJPEG_RAW = 2, + /** YUV stream in YUY2 format */ + VID_FORMAT_YUY2_RAW = 3, + /** YUV stream in NV12 format */ + VID_FORMAT_NV12_RAW = 4, + /** Luma stream format */ + VID_FORMAT_GREY_RAW = 5, + /** H264 and AAC in transport stream format */ + VID_FORMAT_H264_AAC_TS = 6, + /** mux data */ + VID_FORMAT_MUX = 7, + + VID_FORMAT_AAC_RAW = 8, + /** total number of video formats supported */ + NUM_VID_FORMAT +} video_format_t; + +/** enum to indicate the H264 profile used for encoding */ +typedef enum { + /** baseline profile */ + PROFILE_BASELINE = 0, + /** main profile */ + PROFILE_MAIN = 1, + /** high profile */ + PROFILE_HIGH = 2, + /** number of h264 profiles supported */ + NUM_PROFILE +} video_profile_t; + +/** enum to turn on/off video flip */ +typedef enum { + /** turn off flip */ + FLIP_OFF = 0, + /** trun on flip */ + FLIP_ON = 1, + /** number of flip mode supported */ + NUM_FLIP +} video_flip_t; + +/** enum to set the sensor exposure mode */ +typedef enum { + /** auto exposure */ + EXP_AUTO = 0, + /** manual exposure */ + EXP_MANUAL = 1, + /** number of exposure mode supported */ + NUM_EXP +} exp_set_t; + +typedef enum { + SATURATION_AUTO = 0, + SATURATION_MANUAL = 1, + NUM_SATURATION +} saturation_mode_t; + +typedef enum { + BRIGHTNESS_AUTO = 0, + BRIGHTNESS_MANUAL = 1, + NUM_BRIGHTNESS +} brightness_mode_t; + +typedef enum { + CONTRAST_AUTO = 0, + CONTRAST_MANUAL = 1, + NUM_CONTRAST +} contrast_mode_t; + +/** enum to set the white balance mode in the sensor */ +typedef enum { + /** auto mode */ + WB_MODE_AUTO = 0, + /** manual mode */ + WB_MODE_MANUAL = 1, + /** number of white balance modes supported */ + NUM_WB +}white_balance_mode_t; + +/** enum to set power line frequency mode */ +typedef enum { + /** disable power line frequency */ + PWR_LINE_FREQ_MODE_DISABLE = 0, + /** 50Hz power line frequency */ + PWR_LINE_FREQ_MODE_50HZ = 1, + /** 60Hz power line frequency */ + PWR_LINE_FREQ_MODE_60HZ = 2 +}pwr_line_freq_mode_t; + + +/** Structure containing the information regarding an encoding channel */ +typedef struct +{ + /** format of the video used in the channel */ + video_format_t format; + + /** width of the video in the channel */ + uint16_t width; + + /** height of the video in the channel */ + uint16_t height; + + /** frame Rate of the video in the channel */ + uint32_t framerate; + + /** GOP size of video to be used in the channel, applicable only for + VID_FORMAT_H264_RAW, + VID_FORMAT_H264_TS, + VID_FORMAT_H264_AAC_TS */ + uint32_t goplen; + + /** H264 profile used for encoding in the channel, applicable only for + VID_FORMAT_H264_RAW, + VID_FORMAT_H264_TS, + VID_FORMAT_H264_AAC_TS */ + video_profile_t profile; + + /** bitrate of the video in the channel */ + uint32_t bitrate; + + /** compression quality in terms of the QP factor set for the video + on this channel, applicable only for VID_FORMAT_MJPEG_RAW */ + uint32_t compression_quality; +} video_channel_info_t; + +typedef struct{ + unsigned int v : 8; + unsigned int f : 24; +}QMedFlags; + +typedef struct { + unsigned int boxSize; + unsigned int boxType; + union { + unsigned int value; + QMedFlags field; + } boxFlags; + unsigned int majorMediaType; + unsigned int minorMediaType; +} QMedStruct; + + +typedef struct +{ + unsigned long version; + unsigned long width; + unsigned long height; + unsigned long sampleTicks; + unsigned long motionCounter; + unsigned long motionBitmapSize; +} QMedH264Struct; + +typedef struct { + char *qmedExt; + unsigned int total_len; +}metadata_t; + +typedef struct { + unsigned int hashSize; + unsigned int hashPayload[QMED_SHA_SIZE]; +}QMedVer1InfoStruct; + + + +/** Video Information structure used for processing the video data received +from the camera in the callback function */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +typedef struct { + /** format of the video frame received */ + video_format_t format; + + /** video frame timestamp in terms of ticks of 90kHz clock, where each tick + corresponds to 1/(90 * 1000) sec or 1/90 ms */ + uint64_t ts; +#if 0 + /** motion vector statistics information of the video frame, + only in case of + VID_FORMAT_YUY2_RAW, + VID_FORMAT_NV12_RAW + VID_FORMAT_GREY_RAW */ + motion_stat_t stats; +#endif + /** physical buffer index of the video frame dequeued by the V4L. + This needs to be used by MXUVC application to queue back the video frame + after processing, in the mxuvc_video_cb_buf_done() function described + later */ + int buf_index; +#if 0 + /** TBD */ + pme_info_t pme; + /** TBD */ + rectangle_info_t rect; + /** TBD */ +#endif + metadata_t metadata; + +}/*__attribute__((packed))*/video_info_t; +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +typedef void (*mxuvc_video_cb_t)(unsigned char *buffer, unsigned int size, + video_info_t info, void *user_data); + +struct uvc_xu_data { + __u8 entity[16]; /* Extension unit GUID */ + __u8 selector; /* UVC control selector */ + __u8 size; /* V4L2 control size (in bits) */ + __u8 offset; /* V4L2 control offset (in bits) */ + __u32 id; /* V4L2 control identifier */ + __u8 name[32]; /* V4L2 control name */ +}; + +//static unsigned int buffer_count = BUFFER_COUNT; +static unsigned int mux_channel_count = 1; //minimum mux channel count has to be one else CH1 init logic will fail. +static int videoInit=0; //Flag indicating if video is initialized +#if 0 +struct buffer_info { + void *start; + size_t length; +}; +#endif +static struct video_stream { + int fd; + int enabled; + int started; + + /* V4l2 buffer/settings */ + //struct buffer_info *buffers; + //unsigned int n_buffers; + int n_buffers; + struct v4l2_format fmt; + + /* Callback */ + mxuvc_video_cb_t cb; + void *cb_user_data; + + /* Current stream format settings. + * Those settings are cached in order to populate the SECS + * StreamFormat with the current values when doing a StreamFormatProbe */ + video_format_t cur_vfmt; + uint16_t cur_width; + uint16_t cur_height; + uint32_t cur_bitrate; + uint32_t cur_framerate; + + /* Captured frame count */ + unsigned int frame_count; + + /* AAC muxing enabled ? */ + unsigned int mux_aac_ts; + + /* SECS */ + //unsigned int secs_supported; /* SECS mode supported but not enabled */ + //unsigned int secs_enabled; /* SECS mode enabled */ + +} *video_stream; + +typedef struct { + int fd; + int enabled; + int started; + int waiting; + int ref_count; + /* V4l2 buffer/settings */ + //struct buffer_info *buffers; + unsigned int n_buffers; + void *priv; +}mux_stream_t; + +/** enum to indicate the video channel number */ +typedef enum channel { + FIRST_VID_CHANNEL = 0, + /** channels for ip camera */ + /** video channel1 */ + CH1 = 0, + /** video channel2 */ + CH2 = 1, + /** video channel3 */ + CH3 = 2, + /** video channel4 */ + CH4 = 3, + /** video channel5 */ + CH5 = 4, + /** video channel6 */ + CH6 = 5, + /** video channel7 */ + CH7 = 6, + /** number of mux channels in ip camera */ + NUM_MUX_VID_CHANNELS = CH7+1, + /** video channel for RAW stream */ + CH_RAW = NUM_MUX_VID_CHANNELS, + /** total number of video channels in ip camera */ + NUM_IPCAM_VID_CHANNELS +} video_channel_t; + +int channel_init(video_channel_t ch); + +/** + * @brief This API is used to initialize the Linux video interface on the Host + * system. + * + * @return 0 on Success, -1 on Failure + */ + +int mxuvc_video_init(); + +/** + * @brief This API is used to free all the memory allocated by the MXUVC. + * This function automatically calls @ref mxuvc_video_stop if the video + * has not been stopped yet, it is therefore not necessary to explicitly call + * @ref mxuvc_video_stop before calling @ref mxuvc_video_deinit. + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_deinit(); + + +/** + * @brief This API is used to start the capture of video data from the specified + * channel in the camera. + * + * @param[in] ch video channel on which the video capture needs to be started + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_start(video_channel_t ch); + +/** + * @brief This API is used to stop the capture of video data from a channel in + * the camera. + * + * @param[in] ch video channel on which the video capture needs to be stopped + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_stop(video_channel_t ch); + +/** + * @brief This API is used to get the number of video channels supported by the + * GEO Camera. The number of video channels supported by the camera is configuration + * dependent. + * + * @param[out] count number of video channels supported. This parameter is returned + * from the camera based on the configuration in which it is running. + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_channel_count(uint32_t *count); + +/** + * @brief This API gets the information regarding the video parameters set on the + * channel in the Camera. + * + * @param[in] ch video channel from which the information is needed + * @param[out] info pointer to the video channel information structure returned + * from the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_channel_info(video_channel_t ch, video_channel_info_t *info); + +/** + * @brief This API is used to force an I frame in the specified video channel. + * Applicable only for VID_FORMAT_H264_RAW, VID_FORMAT_H264_TS, VID_FORMAT_H264_AAC_TS. + * + * @param[in] ch video channel on which I frame needs to be forced + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_force_iframe(video_channel_t ch); + +/** + * @brief This API is used to get the format of the video data on the specified channel. + * + * @param[in] ch video channel on which the format is queried + * @param[out] fmt pointer to receive the format of the video + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_format(video_channel_t ch, video_format_t *fmt); + +/** + * @brief This API is used to set the resolution of the video data on the specified channel. + * + * @param[in] ch video channel on which the resolution is to set + * @param[in] width width of the video in the specified channel + * @param[in] height height of the video in the specified channel + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_resolution(video_channel_t ch, uint16_t width, uint16_t height); + +/** + * @brief This API is used to get the resolution of the video data on the specified channel. + * + * @param[in] ch video channel on which the resolution is queried + * @param[out] width pointer to receive the width of the video + * @param[out] height pointer to receive the height of the video + * + * @return 0 on Success, -1 on Failure + */ + int mxuvc_video_get_resolution(video_channel_t ch, uint16_t *width, uint16_t *height); + +/** + * @brief This api is used to set the frame rate on the video channel specified. + * Typical Range: 1 to 30. + * + * Not applicable for VID_FORMAT_YUY2_RAW,VID_FORMAT_NV12_RAW,VID_FORMAT_GREY_RAW. + * + * @param[in] ch video channel for which framerate is to set + * @param[in] framerate framerate to set on the channel + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_framerate(video_channel_t ch, uint32_t framerate); + +/** + * @brief This api is used to get the frame rate on the video channel specified. + * + * Not applicable for VID_FORMAT_YUY2_RAW,VID_FORMAT_NV12_RAW,VID_FORMAT_GREY_RAW. + * + * @param[in] ch video channel for which framerate is to get + * @param[out] framerate pointer to receive the framerate + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_framerate(video_channel_t ch, uint32_t *framerate); + +/** + * @brief This api is used to set GOP length on the video channel specified. + * Typical Range: 0 to Max Integer (2147483647). + * + * Applicable only for VID_FORMAT_H264_RAW, VID_FORMAT_H264_TS, VID_FORMAT_H264_AAC_TS. + * + * @param[in] ch video channel for which GOP length is to set + * @param[in] value GOP length to set on the channel + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_goplen(video_channel_t ch, uint32_t value); + +/** + * @brief This api is used to get GOP length on the video channel specified. + * + * Applicable only for VID_FORMAT_H264_RAW, VID_FORMAT_H264_TS, VID_FORMAT_H264_AAC_TS. + * + * @param[in] ch video channel for which GOP length is to get + * @param[out] value pointer to receive the GOP length + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_goplen(video_channel_t ch, uint32_t *value); + +/** + * @brief This api is used to set bitrate on the video channel specified. + * Typical Range: 100000 (100 kbps) to 2000000 (2 Mbps) + * + * Not applicable for VID_FORMAT_YUY2_RAW,VID_FORMAT_NV12_RAW,VID_FORMAT_GREY_RAW. + * + * @param[in] ch video channel for which bitrate is to set + * @param[in] value bitrate to set on the channel + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_bitrate(video_channel_t ch, uint32_t value); + +/** + * @brief This api is used to get bitrate on the video channel specified. + * + * Not applicable for VID_FORMAT_YUY2_RAW,VID_FORMAT_NV12_RAW,VID_FORMAT_GREY_RAW. + * + * @param[in] ch video channel for which bitrate is to get + * @param[out] value pointer to receive the bitrate + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_bitrate(video_channel_t ch, uint32_t *value); + +/** + * @brief This api is used to set vertical flip of the given video channel. + * + * Values: 1 Enable, 0 Disable + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_flip_vertical(video_channel_t ch, video_flip_t value); + +/** + * @brief This api is used to get vertical flip status of the given video channel. + * + * Values: 1 Enable, 0 Disable + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter value updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_flip_vertical(video_channel_t ch, video_flip_t *value); + +/** + * @brief This api is used to set horizontal flip of the given video channel. + * + * Values: 1 Enable, 0 Disable + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_flip_horizontal(video_channel_t ch, video_flip_t value); + +/** + * @brief This api is used to get horizontal flip status of the given video channel. + * + * Values: 1 Enable, 0 Disable + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter value updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_flip_horizontal(video_channel_t ch, video_flip_t *value); + +/** + * @brief This api is used to set image contrast of the given video channel. + * + * Typical Range: 0 to 200 + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_contrast(video_channel_t ch, uint16_t value); + +/** + * @brief This api is used to get image contrast of the given video channel. + * + * Typical Range: 0 to 200 + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter value updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_contrast(video_channel_t ch, uint16_t *value); + +/** + * @brief This api is used to set image brightness of the given video channel. + * + * Typical Range: -255 to 255 + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_brightness(video_channel_t ch, int16_t value); + +/** + * @brief This api is used to get image brightness of the given video channel. + * + * Typical Range: -255 to 255 + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_brightness(video_channel_t ch, int16_t *value); + +/** + * @brief This api is used to set image saturation of the given video channel. + * + * Typical Range: 0 to 200 + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_saturation(video_channel_t ch, uint16_t value); + +/** + * @brief This api is used to get image saturation of the given video channel. + * + * Typical Range: 0 to 200 + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_saturation(video_channel_t ch, uint16_t *value); + +/** + * @brief This api is used to set image gain of the given video channel. + * + * Typical Range: 1 to 100 + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_gain(video_channel_t ch, uint16_t value); + +/** + * @brief This api is used to get image gain of the given video channel. + * + * Typical Range: 1 to 100 + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_gain(video_channel_t ch, uint16_t *value); + +/** + * @brief This api is used to set image sharpness of the given video channel. + * + * Typical Range: 1 to 100 + * + * @param[in] ch video channel on which the parameter is set + * @param[in] value value to be set in the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_sharpness(video_channel_t ch, uint16_t value); + +/** + * @brief This api is used to get image sharpness of the given video channel. + * + * Typical Range: 1 to 100 + * + * @param[in] ch video channel on which the parameter is set + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_sharpness(video_channel_t ch, uint16_t *value); + +/** + * @brief This api is used to set the exposure mode (auto or manual) and + * the exposure time in the manual mode. + * + * @param[in] ch video channel on which the parameter is set + * @param[in] sel selects to exposure mode (Auto or Manual) + * @param[in] value exposure time value in the Manual mode - Range 0 to 255 + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_exp(video_channel_t ch, exp_set_t sel, uint16_t value); + +/** + * @brief This api is used to get the exposure mode (auto or manual) and + * the exposure time in the manual mode. + * + * @param[in] ch video channel on which the parameter is set + * @param[out] sel selects to exposure mode (Auto or Manual) + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_exp(video_channel_t ch, exp_set_t *sel, uint16_t *value); + +/** + * @brief This api is used to set the white balance mode (auto or manual) and + * the white balance temperature in Kelvin (works in auto mode only). + * + * @param[in] ch video channel on which the parameter is set + * @param[in] sel selects to white balance mode (Auto or Manual) + * @param[in] value white balance temperature in either Mode - Range 2000 to 8000 + * if 0 is passed, no change will be done + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_wb(video_channel_t ch, white_balance_mode_t sel, uint16_t value); + +/** + * @brief This api is used to get the white balance mode (auto or manual) and + * the white balance temperature in the manual mode. + * + * @param[in] ch video channel on which the parameter is set + * @param[out] sel selects to white balance mode (Auto or Manual) + * @param[out] value pointer to parameter updated by the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_wb(video_channel_t ch, white_balance_mode_t *sel, uint16_t *value); + +/** + * @brief This API is used to select the power line frequency of the operating region. + * Sensor exposure value under the auto-exposure algorithm will be adjusted to avoid + * flickering caused by power level oscillation. + * 0 disables this function, and the values of 1 and 2 represents 50 and 60Hz power + * line frequency respectively. + * + * @param[in] ch video channel on which the parameter is set + * @param[in] mode value indicating power line frequency mode + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_set_pwr_line_freq(video_channel_t ch,pwr_line_freq_mode_t mode); + +/** + * @brief This api is used to get the status of power line frequency of the operating + * region. + * + * @param[in] ch video channel on which the parameter is set + * @param[out] mode pointer to parameter updated by the camera + * 0 \u2013 disable, 1 \u2013 50Hz, 2 \u2013 60Hz + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_video_get_pwr_line_freq(video_channel_t ch,pwr_line_freq_mode_t *mode); + +int mxuvc_video_set_format(video_channel_t ch, video_format_t fmt); +int mxuvc_video_set_brightness_mode(video_channel_t ch, brightness_mode_t mode); +int mxuvc_video_get_brightness_mode(video_channel_t ch, brightness_mode_t *mode); +int mxuvc_video_set_contrast_mode(video_channel_t ch, contrast_mode_t mode); +int mxuvc_video_get_contrast_mode(video_channel_t ch, contrast_mode_t *mode); +int mxuvc_video_set_saturation_mode(video_channel_t ch, saturation_mode_t mode); +int mxuvc_video_get_saturation_mode(video_channel_t ch, saturation_mode_t *mode); + + +/** + * @brief This API is used to set the microphone gain. + * This will work only when AGC is off. + * + * @param[in] volume microphone gain level. Range is from 0 to 100 without any units. + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_audio_set_volume(int volume); + +/** + * @brief This API is used to mute or unmute the micro phone. + * It will mute or unmute all the audio input channels. + * + * @param[in] bMute microphone mute value. 0 - unmute, 1 - mute + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_audio_set_mic_mute(int bMute); + +/** + * @brief This API is used to mute or unmute only the left microphone + * in case of stereo. This will work only when ASP is off (in JSON). + * + * @param[in] bMute microphone mute value. 0 - unmute, 1 - mute + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_audio_set_left_mic_mute(int bMute); + +/** + * @brief This API is used to mute or unmute only the right microphone + * in case of stereo. This will work only when ASP is off (in JSON). + * + * @param[in] bMute microphone mute value. 0 - unmute, 1 - mute + * + * @return 0 on Success, -1 on Failure + */ +int mxuvc_audio_set_right_mic_mute(int bMute); + +/** + * @brief This API resets the camera + * + * @return 0 on Success, -1 on Failure + */ +int mxcam_reset(void); + +/** + * @brief This API gets VALUE for given KEY from camera's volatile memory + * + * @param[in] keyname KEY + * @param[out] value Value returned by camera for the given key + * + * @return 0 on Success, -1 on Failure + */ +int mxcam_get_value(const char* keyname, char** value); + +/** + * @brief This API frees the resource allocated by mxcam_get_value + * + * @param[in] value_mem: pointer to a memory,allocated by mxcam_get_value + * + * @return MXCAM_OK upon Success or following on Failure: + * MXCAM_ERR_INVALID_PARAM - if value_mem is NULL + * MXCAM_ERR_GETVALUE_UNKNOWN_AREA - Unknown area to get value + * MXCAM_ERR_GETVLAUE_KEY_NOT_FOUND - Value not found for given KEY + */ +int mxcam_free_get_value_mem(char* value_mem); + +/** + * @brief This API adds/modifies a KEY=VALUE pair on camera's volatile memory + * + * @param[in] keyname :KEY + * @param[in] value :VALUE + * + * @return 0 upon Success or following on Failure: + * MXCAM_ERR_INVALID_PARAM - if any one of the following condition meet + * - keyname is NULL + * - value is NULL + * MXCAM_ERR_SETKEY_OVER_FLOW_NO_MEM - Not enough memory to save new + * key on memory + * MXCAM_ERR_SETKEY_UNKNOWN_AREA - Unkown area to set key + */ + +int mxcam_set_key(const char* keyname, const char* value); + +/** + * @brief This API check the json syntax + * + * @param[in] ispcfg: ISP config file name + * + * @return MXCAM_OK upon Success or following on Failure: + * MXCAM_ERR_FILE_NOT_FOUND - if given ispcfg file is not found + * MXCAM_ERR_VEND_ERR_ISPCFG_SYNTAX_ERR - if syntax is wrong + */ +int mxcam_check_ispcfg_syntax(const char *ispcfg); + +/** + * @brief This API stores given ISP configuration binary on camera's non volatile memory. + * + * @param[in] ispcfg: ISP config file name + * + * @return 0 on Success, -1 on Failure + */ +int mxcam_write_ispcfg(const char *ispcfgfile); + +/** + * @brief This API saves the given JSON on camera persistent storage memory + * + * @param[in] jsonfile: JSON file name + * + * @return MXCAM_OK upon Success or following on Failure: + * MXCAM_ERR_INVALID_PARAM - if invalid JSON is provided + */ +int mxcam_save_eeprom_config(const char *jsonfile); + +/** + * @brief This API does QCC read operation in camera + * + * @param[in] bid: qcc block id + * @param[in] addr: qcc register address + * @param[in] length: length of the register + * @param[out] value : return value + * + * @return MXCAM_OK upon Success or following on Failure: + * MXCAM_ERR_INVALID_PARAM - length is not 1, 2 or 4 + * MXCAM_ERR_INVALID_DEVICE - Device not booted completely + */ +int mxcam_qcc_read(uint16_t bid, uint16_t addr, uint16_t length, uint32_t *value); + +/** + * @brief This API reads 64 bytes flash image header. This image header carries + * camera information such as firmware version, etc. + * + * @param[in] header :pointer to image_header_t structure + * @param[in] hdr_type : possible value of this field is + * 0, for running fw image header + * 1, if fw image hdr need to be read from sno + * 2, for bootloader header + * + * @return MXCAM_OK upon Success or following on Failure: + * MXCAM_ERR_INVALID_PARAM - if header is NULL + */ +int mxcam_read_flash_image_header(image_header_t *header, IMG_HDR_TYPE hdr_type); + +/** + * @brief TBD. + * + * @param[in] TBD + * + * @return 0 on Success, -1 on Failure + */ +int mxcam_rw_gpio (int gpio_no, int value, int gpio_write, int *status); + + +void get_adts_header(int size, unsigned char *adtsHeader); + +#endif /* _PATCH_UVC_GEO_H_ */ \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source_modules/mmf_source_i2s_file.h b/USDK/component/common/media/framework/mmf_source_modules/mmf_source_i2s_file.h new file mode 100644 index 0000000..02352e0 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/mmf_source_i2s_file.h @@ -0,0 +1,35 @@ +#ifndef MMF_SOURCE_I2S_FILE_H +#define MMF_SOURCE_I2S_FILE_H + +#include "mmf_source.h" +#include "FreeRTOS.h" +#include "task.h" +//#include "example_rtsp_server_i2s.h" +#include "rtsp/rtsp_api.h" +#include "sockets.h" +#include "lwip/netif.h" + +#include "i2s_api.h" +#include "alc5651.c" +#include "g711_codec.h" +#include "gpio_api.h" // mbed +#include "gpio_irq_api.h" + +#include +#include "platform_opts.h" +#include "dlist.h" +#include "basic_types.h" +#include "osdep_service.h" + +#define I2S_DMA_PAGE_SIZE 320 // 2 ~ 4096 +#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4 +#define RECV_PAGE_NUM I2S_DMA_PAGE_NUM + +#define G711_FSIZE 160 +#define I2S_MODE_SWITCH PE_5 + +#define I2S_SCLK_PIN PC_1 +#define I2S_WS_PIN PC_0 +#define I2S_SD_PIN PC_2 + +#endif /* MMF_SOURCE_I2S_FILE_H */ \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source_modules/mmf_source_list.h b/USDK/component/common/media/framework/mmf_source_modules/mmf_source_list.h new file mode 100644 index 0000000..2a010ac --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/mmf_source_list.h @@ -0,0 +1,14 @@ +#ifndef _MEDIA_MODULES_H +#define _MEDIA_MODULES_H +#include "../mmf_source.h" + +//list all avaliable modules here +extern msrc_module_t uvc_module; +extern msrc_module_t geo_module; +extern msrc_module_t mjpgf_module; +extern msrc_module_t h264f_module; +extern msrc_module_t aacf_module; +extern msrc_module_t pcmuf_module; +extern msrc_module_t i2s_module; +extern msrc_module_t rtp_src_module; +#endif \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source_modules/sample_aac.h b/USDK/component/common/media/framework/mmf_source_modules/sample_aac.h new file mode 100644 index 0000000..32de003 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/sample_aac.h @@ -0,0 +1,3200 @@ +#ifndef _SAMPLE_AAC_H_ +#define _SAMPLE_AAC_H_ + +#include "section_config.h" +SDRAM_DATA_SECTION static const unsigned char aac_sample[]={ +0xff,0xf1,0x50,0x80,0x04,0x3f,0xfc,0xde,0x04,0x00,0x00,0x6c,0x69,0x62,0x66,0x61,0x61,0x63,0x20,0x31,0x2e,0x32,0x38,0x00,0x00,0x42,0x00,0x93,0x20,0x04,0x32,0x00,0x47 +,0xff,0xf1,0x50,0x80,0x02,0x1f,0xfc,0x21,0x20,0x49,0x90,0x02,0x19,0x00,0x23,0x80,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x4c,0xfe,0xf7,0xfc,0xdb,0xf3,0x25,0xca +,0x97,0x2e,0x19,0x85,0x6d,0x7d,0x00,0x30,0x8f,0xb9,0x3f,0xf4,0xe0,0xf3,0x68,0xfc,0x5e,0x50,0x11,0x9f,0x83,0xc3,0xf3,0x6d,0xf2,0xf5,0xb5,0xae,0x04,0xe1,0xbb,0x2e +,0xb7,0x8f,0xcd,0xb2,0xfb,0x80,0x2f,0x37,0x93,0xcf,0xe4,0xfb,0xf7,0xdf,0x79,0x00,0xcc,0xf0,0xbc,0x7e,0xb3,0x66,0xaf,0x27,0x96,0x00,0x0b,0x39,0x3d,0x57,0xa8,0xef +,0xfb,0x4d,0xfe,0x8f,0x8b,0x71,0xc6,0xea,0x79,0x7e,0x5d,0xe0,0x00,0xb9,0xa4,0x7a,0x4d,0xdb,0x3e,0xfb,0x63,0x93,0xbe,0x5c,0xaf,0x36,0xa6,0xd0,0x00,0x30,0x6a,0x6e +,0xe5,0xee,0xf5,0xb6,0x39,0x3b,0x4e,0x57,0xa9,0xdd,0xb3,0xf8,0xc0,0x00,0x07,0x13,0x89,0xc4,0xe2,0x71,0x23,0x77,0x74,0xe8,0x39,0xfd,0x07,0xac,0xf4,0xde,0x17,0xd6 +,0xfd,0x2f,0xba,0xf8,0x7e,0x37,0x75,0xf5,0x9e,0x9b,0x8f,0xe7,0x9d,0x0f,0x45,0xe1,0x3a,0x4d,0x9e,0xd2,0x00,0x00,0x19,0xd7,0x23,0x0e,0x37,0x69,0xc0,0xe1,0x74,0x76 +,0xbf,0xb5,0x7d,0x8e,0x1d,0x8f,0x37,0x67,0xfa,0x78,0x76,0x5c,0x17,0xb1,0xf0,0xfb,0x5c,0xb8,0x94,0x00,0x00,0x4e,0xb4,0x47,0x3f,0xa7,0xe1,0xf3,0xe7,0xf1,0xf3,0xfa +,0x7e,0xce,0x5c,0xb9,0x7f,0x17,0xcf,0xe7,0xf1,0xe7,0xc3,0xe1,0xf2,0xe3,0xcf,0x80,0x00,0x00,0x04,0xd4,0x03,0xc0,0x78,0x3c,0xc1,0xe0,0x73,0x00,0xe6,0xf0,0x81,0xe1 +,0xf3,0xf8,0x60,0x95,0x92,0xee,0x4b,0xa9,0x20,0x9c,0x81,0x6b,0x18,0xbf,0x8c,0x00,0x71,0xf4,0xfe,0xef,0xf4,0xbf,0xcb,0x6b,0xfc,0x4f,0x4b,0xf1,0xbe,0x8c,0x09,0xb7 +,0x0b,0xe0,0xfa,0x2f,0x43,0xc4,0xef,0x3b,0x00,0x39,0x7d,0x5f,0xf6,0x72,0xf9,0xfa,0x9f,0x79,0xd1,0xd6,0xec,0x03,0xac,0xc7,0xed,0xfd,0xb7,0xda,0xfb,0x7f,0x73,0xed +,0x7d,0xa0,0x35,0xf3,0x7c,0x17,0x74,0xe4,0xf7,0xdf,0x15,0xf3,0x1e,0x68,0x00,0x15,0xc8,0xe4,0x63,0xee,0xbf,0xc7,0xc6,0xf7,0x9d,0xff,0x6f,0xe1,0x7c,0xae,0x6f,0xb0 +,0xe2,0x67,0xe5,0xbf,0x58,0x00,0x3d,0x06,0xcd,0xcf,0xb3,0xf4,0x15,0x1f,0x7b,0xe6,0x63,0x7c,0xcc,0xbf,0x9f,0x85,0x20,0x00,0x1f,0x34,0x00,0x00,0x00,0x00,0x3d,0xa1 +,0xed,0x00,0x00,0x00,0x70,0xff,0xf1,0x50,0x80,0x35,0x5f,0xfc,0x21,0x6a,0xcf,0x3b,0xfd,0xdf,0xff,0xff,0xa9,0x60,0xa1,0x0c,0x28,0x72,0x0a,0x0d,0xc2,0xa1,0x60,0xa8 +,0xd0,0x2a,0x67,0x0c,0x05,0x42,0x81,0x80,0xb0,0x54,0x86,0x11,0x12,0x57,0x19,0x72,0xfb,0xfb,0xfb,0xdc,0xaa,0xe3,0xb5,0xee,0x73,0xd7,0x77,0x57,0x53,0xbd,0x73,0x32 +,0x49,0x27,0x15,0xff,0xdf,0xe8,0x76,0x8e,0xac,0xf9,0x67,0x21,0xfc,0xaf,0xe6,0x7b,0x6d,0x6b,0xca,0xf9,0x3f,0x45,0x2b,0x0f,0x6c,0x33,0xc2,0xf0,0xf8,0xe9,0x47,0x51 +,0xe4,0x7e,0xce,0x41,0xe7,0x6c,0x6c,0x0e,0x4e,0xa9,0x6c,0xe0,0x22,0x8e,0x16,0xe1,0xc9,0xc3,0xe0,0x71,0xe7,0xc9,0xcf,0xd1,0x47,0x01,0x8e,0xf7,0xa2,0x7a,0xfd,0x94 +,0xe8,0xe4,0x9f,0x92,0x0e,0x26,0x9d,0x3d,0xdb,0xe7,0xcd,0x00,0xf1,0xf2,0x1e,0x03,0xcb,0xc7,0x97,0x9f,0xc9,0xc9,0xc0,0x3c,0x8f,0x3f,0x1f,0x17,0x8f,0x88,0x07,0x97 +,0x97,0x90,0x78,0x78,0xf9,0xf9,0x0f,0x27,0xde,0x79,0xef,0xb5,0x10,0x0e,0x74,0x2e,0x82,0xa2,0x65,0xfc,0x18,0x70,0x18,0x78,0x34,0xf4,0x79,0x7d,0x5e,0x02,0x7c,0x7c +,0xb8,0x1e,0x1c,0xbe,0x9e,0x1f,0xfb,0xfc,0xf7,0xcc,0xff,0xef,0x6f,0xfd,0xbf,0xdb,0xfb,0x53,0x9d,0x0b,0xd7,0x98,0x81,0xcc,0x3c,0xcb,0x30,0x3b,0xc7,0x06,0x61,0xe5 +,0xe2,0x34,0xdb,0x45,0xa1,0x45,0xb7,0xf2,0x00,0xf3,0x38,0x81,0xe1,0xe4,0x78,0xf3,0xe0,0x0f,0x10,0xf0,0x79,0x0f,0x33,0xc4,0x78,0x00,0x8d,0xb8,0x78,0x00,0x44,0xbc +,0x67,0xed,0xf7,0x50,0x26,0x02,0x60,0x28,0xa0,0x28,0x16,0x12,0x05,0x84,0x83,0x61,0x20,0x58,0x44,0x14,0x0a,0x89,0xc2,0xa1,0x71,0x28,0x9c,0x42,0x20,0x08,0x90,0x02 +,0x23,0x71,0x08,0x80,0x29,0xe7,0xed,0xfa,0xfa,0x90,0x35,0xcf,0xe3,0xc5,0x77,0xf1,0xf6,0xfb,0xfe,0x62,0xe7,0x1f,0xfe,0x49,0x4c,0x53,0x9f,0xff,0x8b,0xff,0x6f,0xb8 +,0xd1,0x35,0xfd,0x12,0xbf,0x97,0x87,0x5f,0xf9,0xb7,0xdb,0xc5,0x39,0xa7,0xe2,0x79,0x97,0x6a,0x32,0x6f,0xc5,0x1b,0x55,0x1d,0xb9,0x43,0x7e,0xa4,0x98,0x7e,0xae,0xfb +,0x04,0x72,0x78,0xf1,0xe4,0x6d,0x0f,0xf8,0xe7,0xed,0x3c,0x1e,0x91,0x1c,0xd1,0x83,0xdb,0x7b,0x7f,0xc2,0x3a,0x7e,0x07,0xae,0x76,0x8f,0xb7,0xc5,0xea,0xf1,0xf5,0xf8 +,0x17,0xe4,0xf4,0xc3,0xc7,0x6f,0x00,0x7d,0xf3,0xca,0xf3,0x8f,0xed,0x00,0x15,0xac,0x04,0x8c,0xf3,0x1a,0x41,0x60,0xe4,0x16,0x04,0x00,0x28,0xa0,0x00,0xb8,0x11,0x00 +,0x00,0xbd,0x3f,0x49,0xcf,0xe0,0x39,0xe0,0x03,0x9f,0x99,0x00,0x00,0x23,0xc0,0xff,0xf1,0x50,0x80,0x38,0x3f,0xfc,0x21,0x0a,0xcb,0xff,0xfd,0x7f,0xff,0xff,0xa9,0x40 +,0xb0,0x50,0x6a,0x14,0x1a,0x85,0x04,0xa1,0x40,0x98,0x50,0x8c,0x15,0x1b,0x8d,0x42,0xe1,0x10,0xb8,0x54,0x2e,0x18,0x0a,0x05,0x42,0xc1,0x51,0x38,0x54,0x42,0x27,0x5e +,0x3c,0xeb,0x77,0x27,0x6a,0xf3,0xde,0xb7,0x5a,0xae,0xe6,0xb3,0x3a,0xcd,0xeb,0x8f,0x1c,0x94,0x4f,0x6d,0xba,0xff,0xf4,0xfa,0x1a,0x13,0x4a,0x7f,0x13,0x59,0x7c,0xad +,0xd9,0xd9,0xf2,0xdd,0xc9,0xd1,0xa2,0x50,0x73,0x6e,0xbe,0xb4,0xf1,0xe7,0x34,0xdf,0xfb,0xc7,0xf6,0x4a,0xf9,0xe2,0xfc,0x3e,0x63,0xfe,0x4f,0x9c,0x77,0xb6,0xa5,0xba +,0x82,0xd7,0x1e,0x67,0xcb,0x8a,0x7c,0xfc,0x6d,0x2b,0xee,0xae,0x47,0x31,0xbb,0x99,0xe1,0x36,0xbd,0x65,0x94,0x8b,0x09,0xf2,0xc3,0xc9,0xdb,0x16,0xe5,0xc8,0xe0,0x70 +,0xe5,0xcb,0x98,0xb3,0xc8,0x87,0x90,0x2d,0x92,0xb6,0xec,0xe7,0x03,0x70,0x5f,0x85,0x41,0x2e,0x7e,0x5c,0x78,0xbc,0xfe,0xf7,0x07,0xdc,0x6c,0xe6,0xd4,0x68,0x1b,0x39 +,0xfe,0x0b,0xc2,0xdf,0xc5,0xce,0x7a,0x17,0xda,0x81,0x17,0x8e,0xfb,0xd0,0x61,0x7e,0x33,0x3f,0xfc,0x3f,0xe9,0xff,0xdb,0xe0,0x7f,0xf0,0xba,0xdf,0x6b,0xfc,0x0e,0x3c +,0xbe,0x67,0x22,0x3a,0xb8,0x4a,0xac,0x78,0x6c,0xc1,0xfa,0x8a,0x80,0xcb,0x3c,0x31,0xcc,0xf8,0x7c,0x0e,0x03,0x9f,0xc8,0xe5,0xc3,0xe0,0xfd,0x57,0x5b,0xbb,0x51,0x42 +,0x6f,0xa9,0xd2,0xf0,0x00,0x1c,0xc1,0xcb,0x98,0xae,0x6e,0x20,0x79,0x8f,0x13,0xc0,0x02,0x20,0x2c,0x02,0x92,0x82,0xc2,0x40,0xb0,0x50,0x2c,0x14,0x12,0x89,0x04,0xa1 +,0x20,0xa0,0x5c,0x30,0x14,0x0b,0x0d,0xc2,0x81,0x20,0xb8,0x4c,0x22,0x55,0x09,0x04,0xc4,0x21,0x30,0x89,0x00,0x2d,0x15,0xaa,0x68,0xcf,0xdf,0xf6,0xf8,0xf5,0xd7,0xcf +,0x5e,0xbf,0xf7,0xff,0xe1,0xe6,0xf7,0xf7,0xff,0x9e,0x26,0xfb,0xff,0x5f,0x9e,0x2f,0xfe,0xff,0xa7,0xdb,0x7f,0xe3,0xfd,0x07,0x34,0x31,0x56,0xfe,0xaa,0x7e,0x2d,0x77 +,0x3d,0x2f,0xae,0x8f,0xa4,0x7f,0xa7,0xe4,0xe0,0xf9,0x3e,0xa5,0xeb,0x6b,0x5f,0x71,0xcb,0xcb,0xd7,0xbb,0x73,0xed,0x65,0x87,0xc0,0xef,0x3a,0x17,0x98,0x86,0x7d,0x6f +,0xda,0xf3,0x0f,0xef,0x79,0xf2,0x60,0x2a,0x24,0xd7,0xcc,0xb6,0x18,0xff,0xa9,0x43,0xa7,0x9b,0x8d,0x70,0xf7,0xa8,0xab,0x6a,0xa3,0x4f,0xba,0x25,0x64,0x58,0x74,0x54 +,0xf4,0xf9,0x87,0xf1,0x41,0xaf,0x58,0x09,0x24,0x9c,0xc2,0xa9,0x08,0x0a,0x80,0xd4,0x00,0x04,0xfa,0xfe,0xbd,0xdd,0x52,0x60,0x40,0x02,0xde,0x5f,0xc8,0x78,0x7f,0x8c +,0x80,0x2a,0x00,0x07,0x81,0x9e,0xc0,0xaf,0x8b,0xe1,0x01,0x26,0xf0,0x01,0x41,0xc0,0xff,0xf1,0x50,0x80,0x3a,0x3f,0xfc,0x21,0x0a,0xcf,0xfb,0xff,0xff,0xff,0xff,0xaa +,0x61,0x21,0x08,0x28,0x15,0x0a,0x09,0x42,0x83,0x30,0xa8,0x50,0x4c,0x15,0x0a,0x05,0x46,0x61,0x50,0xa0,0x54,0x2e,0x15,0x0b,0x85,0x87,0x01,0x51,0xb8,0x44,0x6f,0xae +,0xfd,0xa3,0xd6,0xb8,0xf5,0xae,0x78,0xe7,0x86,0x33,0x77,0x57,0xba,0x8a,0x9c,0x77,0x58,0x95,0x17,0xd7,0xb7,0xfb,0xfd,0x0d,0x53,0x6c,0x7e,0x27,0xc6,0xf7,0xde,0xc3 +,0xfb,0xca,0x1c,0x3c,0x5e,0xb2,0x77,0xa3,0xad,0xe5,0x05,0xd4,0xd6,0xbd,0x47,0x27,0x7f,0xb1,0x97,0x3f,0x57,0x67,0xe0,0x7a,0xe9,0xd3,0xdb,0x6b,0x9b,0x84,0xc0,0x01 +,0xe1,0xf1,0xff,0x79,0xc3,0x1b,0x09,0xf5,0xf2,0x1c,0xb8,0x7c,0x9f,0x0f,0x97,0x00,0xe3,0x2e,0x08,0x73,0x70,0x78,0x1f,0x0d,0xfe,0xfb,0xfc,0x5f,0x07,0xc0,0xf8,0x03 +,0x9b,0xff,0x9b,0x2f,0xfd,0xfb,0xbf,0x53,0x03,0x99,0xcf,0xe4,0xf9,0x9c,0xc0,0x5f,0x98,0x0f,0x38,0xf0,0x17,0xf6,0x1e,0x11,0xe7,0xf7,0x9b,0x7a,0x76,0xb6,0xbc,0x21 +,0xd7,0x78,0x7c,0xdb,0x53,0x56,0x29,0xf0,0xaa,0xfb,0x7f,0x01,0x68,0x5f,0x65,0xa1,0x81,0x67,0xd5,0xcf,0xbb,0x00,0xbf,0xc3,0x8e,0x00,0x01,0x86,0x01,0x55,0x16,0x85 +,0x41,0x45,0x14,0x5f,0x76,0x7e,0x40,0xa9,0xea,0x4f,0xbf,0xdf,0x8e,0xf1,0x36,0xc4,0xcf,0x51,0xdc,0xcc,0x3c,0x5f,0x17,0xcf,0x9f,0xc7,0x83,0x98,0x90,0x87,0x27,0x0e +,0x3c,0xb8,0x9c,0xf8,0x73,0x70,0xe8,0xfa,0x43,0xe4,0x39,0x73,0x03,0x9d,0xe6,0x2c,0x05,0x2d,0x48,0xc0,0x5c,0x05,0xc0,0x51,0x40,0x58,0xa6,0x14,0x0b,0x05,0x44,0x81 +,0x50,0xa0,0x58,0x28,0x16,0x0c,0x85,0x43,0x01,0x50,0xb0,0x50,0x2a,0x11,0x0a,0x04,0x46,0x01,0x11,0x18,0x5c,0x32,0x21,0x0a,0x88,0x44,0x02,0x75,0xda,0xea,0xef,0x7c +,0x65,0x6b,0x6f,0x3c,0x7d,0xbf,0x7f,0xe9,0xf5,0xf3,0xed,0xe7,0xaf,0xcf,0xfc,0xfe,0xba,0xc9,0xfd,0xbf,0xf8,0xe2,0xff,0xf3,0xf3,0xff,0xf6,0x78,0xff,0xdc,0x74,0x85 +,0x97,0x6f,0xae,0xad,0x17,0x5f,0xc7,0x9c,0x7f,0x1f,0xff,0x2e,0x56,0x3c,0x79,0x1f,0x0f,0xc1,0x7f,0xb7,0xc1,0xf6,0xbf,0xef,0xed,0x68,0xbf,0x51,0xaf,0x71,0x90,0xb7 +,0x7f,0xcf,0xa5,0x80,0x2b,0x5c,0xbf,0xcd,0xec,0x1b,0x8c,0x07,0x74,0x8e,0xcf,0x52,0x47,0x64,0xd9,0x49,0x7f,0x05,0x1d,0x2b,0xd0,0xbd,0x1b,0xe9,0xb8,0x03,0xef,0x9e +,0x27,0x83,0x4b,0xa7,0x10,0xff,0xd6,0xe1,0xfb,0x22,0x17,0x2d,0x40,0x10,0x54,0x80,0x50,0x07,0xb9,0xe4,0xc3,0xbd,0xf5,0xfb,0x8c,0x55,0xa5,0xb7,0x11,0x8e,0x2d,0x9b +,0x77,0xb6,0x36,0xed,0xdb,0xbb,0x7f,0x13,0xdb,0x1b,0x0f,0xc8,0x67,0x58,0x00,0x17,0x00,0x00,0x07,0x2f,0x1e,0x5c,0xbe,0x01,0xf1,0x1c,0x38,0x87,0xcb,0xe6,0x0a,0x00 +,0xe0,0xff,0xf1,0x50,0x80,0x38,0x5f,0xfc,0x21,0x2a,0xcb,0x4f,0xcf,0x7f,0xff,0xff,0xa6,0x41,0x30,0x54,0x28,0x45,0x0a,0x21,0x46,0x81,0x60,0xa8,0x58,0x2e,0x19,0x0a +,0x89,0xc4,0xa1,0x70,0xb0,0xe0,0x2a,0x23,0x0a,0x88,0x44,0x35,0x37,0x7d,0x66,0xdb,0xe3,0x9d,0x55,0x5e,0xf2,0x9d,0x61,0x92,0xef,0xba,0xc4,0xcd,0x2b,0xad,0x7f,0x8f +,0xb8,0xfa,0x27,0xd4,0x17,0x77,0xbd,0xe2,0x6b,0x1f,0xf7,0x74,0x0e,0x86,0x9a,0xeb,0x87,0xeb,0x5d,0x0d,0xa8,0x72,0x97,0xe0,0x7f,0x7a,0x21,0xa2,0xf3,0xbb,0xff,0x65 +,0x38,0x72,0x70,0xe4,0x3a,0x39,0xfc,0x7c,0x9c,0xcc,0xff,0xf0,0xff,0x2c,0x2d,0x14,0x4e,0x01,0xc4,0xf2,0xf0,0x1d,0x41,0x24,0x46,0xbe,0x6a,0xaa,0x31,0x55,0xcf,0xe4 +,0xb0,0x2d,0xf2,0xac,0x30,0x68,0xdc,0xb9,0x3e,0x23,0x89,0xc5,0xcc,0x2a,0xbc,0xc9,0x7b,0x7d,0xb0,0x0a,0xa8,0x87,0x91,0xe5,0x01,0x1d,0xf0,0xce,0x67,0x3b,0x2c,0x4f +,0x0a,0x27,0xd9,0xe5,0xe7,0xe6,0x1b,0xcd,0xad,0x9d,0x6f,0x13,0xc0,0x37,0x50,0x17,0xd1,0x95,0x18,0xe3,0x6d,0xa5,0x87,0xca,0xea,0xa6,0xb2,0x4f,0xd5,0x67,0x8e,0x29 +,0x49,0x61,0x88,0x51,0x14,0x12,0x21,0x4e,0x76,0x80,0x7f,0x0b,0xc3,0x14,0xee,0x94,0x2e,0x28,0x89,0xd8,0x5d,0xa0,0x9c,0x56,0x94,0xef,0x35,0x03,0xb8,0x7d,0x44,0x5b +,0xb9,0xad,0x47,0x97,0x98,0xf3,0x9e,0xff,0xa6,0xb8,0xc9,0xc8,0x1f,0xff,0xae,0xef,0xfc,0x13,0xfc,0x4e,0xf1,0xec,0x7a,0xcf,0x20,0x0f,0xc5,0xbd,0x80,0x06,0x80,0x0a +,0x01,0x49,0x01,0x61,0x22,0x58,0x50,0x17,0x0a,0x85,0xc2,0xc1,0x70,0xb0,0x90,0x2e,0x16,0x0b,0x84,0x42,0x62,0x11,0xa8,0x4c,0x52,0x11,0x09,0x84,0x42,0xe1,0x11,0xb5 +,0xbf,0xbf,0xab,0xdf,0x99,0x93,0x93,0x7e,0xdd,0x77,0xd7,0xe7,0x5d,0xfb,0x52,0xbe,0xbc,0x7d,0x7d,0x7b,0x3f,0xa7,0xda,0xf3,0xfd,0x2b,0xe7,0xbf,0xfc,0xf5,0xd0,0xf7 +,0x64,0x17,0x5d,0x3e,0x5f,0xc9,0xff,0xfb,0xf8,0x4f,0xd4,0xbf,0xd7,0xfe,0x8f,0x1f,0xd7,0xc8,0x7f,0x25,0xa8,0x51,0xfd,0x10,0xfc,0xe7,0x22,0x33,0xe3,0x0e,0xa1,0xe5 +,0x37,0xf5,0x77,0xf8,0x80,0xc2,0x59,0x9f,0x4f,0x8a,0xaf,0x0a,0x04,0x19,0xd4,0xfa,0x9e,0x6d,0x6d,0xfc,0xee,0xe3,0xc7,0xfa,0x7f,0x4e,0x00,0x62,0xfe,0xe9,0x55,0x9e +,0x75,0x82,0xaa,0xe9,0xb5,0x0c,0x22,0x03,0xf4,0x47,0xdd,0x1f,0xe0,0x3e,0x6f,0xed,0xfe,0xae,0xe8,0x18,0x01,0xfc,0xff,0x41,0xfd,0x00,0x70,0x08,0x81,0x18,0xac,0x00 +,0x04,0x7d,0x7c,0xaf,0x8d,0xfd,0xcd,0x10,0x09,0xbc,0x97,0x35,0x78,0x57,0xbf,0x33,0xcc,0x03,0x68,0x00,0x1e,0x08,0xbc,0x64,0x1b,0x1e,0xa8,0xdc,0x01,0xc6,0x60,0x02 +,0x22,0x60,0x70,0xff,0xf1,0x50,0x80,0x3d,0x7f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x15,0x18,0x6c,0x60,0xb2,0x84,0xc5,0x4a,0xef,0x25,0x4a,0xaa,0x9c,0x08,0x50,0xdc,0x16 +,0x2b,0xf9,0x8e,0x4f,0x00,0x39,0x9b,0x0e,0x6b,0x19,0xec,0xa5,0x24,0x66,0x83,0x12,0x26,0xa4,0xb4,0x10,0xf7,0xcd,0x11,0xbc,0xaa,0x4e,0x33,0xe8,0x90,0x28,0x75,0x48 +,0xa5,0x28,0x82,0xa8,0xd2,0x8e,0x24,0x60,0x39,0x98,0x73,0x99,0xdf,0x56,0xe0,0x33,0xc5,0x94,0xf1,0x09,0x36,0x32,0x6c,0xa5,0xfd,0xd6,0x68,0x97,0x8c,0x8e,0xdf,0x01 +,0x93,0x53,0x44,0x26,0x9d,0x39,0x04,0xde,0x1e,0xa2,0x54,0x53,0xd8,0x48,0x85,0x09,0x10,0xd5,0xa0,0x76,0xc9,0x4d,0x55,0x54,0x14,0xfd,0xa1,0xf9,0xdb,0x43,0x3c,0x87 +,0x29,0xb1,0x50,0xb7,0xd1,0x56,0x3f,0x03,0x8c,0x71,0xa9,0x6a,0x91,0x12,0x7a,0xec,0x54,0xb9,0x14,0x62,0x4b,0xe1,0xfb,0xc5,0xb0,0xa7,0x44,0xb5,0x96,0x72,0x97,0x39 +,0x99,0x10,0x11,0x05,0x86,0x8c,0x07,0x48,0x21,0xa2,0x43,0xc0,0xae,0x51,0xd4,0xb3,0x8d,0xd3,0xc8,0x51,0x85,0xbe,0x61,0xac,0x63,0x01,0x37,0x9f,0x31,0xc1,0x11,0x42 +,0x1a,0x30,0x44,0x68,0xc5,0xd9,0x56,0x25,0x82,0x83,0x53,0x3c,0x92,0x53,0x13,0x51,0x1a,0x4c,0x25,0x90,0x94,0x91,0x0d,0xc9,0x84,0x95,0x49,0xbe,0x25,0x51,0x5a,0x68 +,0x80,0x80,0x04,0x69,0x92,0x23,0xab,0x1f,0xe2,0x58,0x41,0x93,0x89,0x98,0x29,0xf8,0x84,0x32,0x77,0xdf,0x2d,0xe0,0x9d,0x08,0xed,0x01,0xa5,0x45,0x80,0x66,0x8b,0x1c +,0x02,0xe4,0x00,0x04,0xfc,0xb1,0xd7,0x90,0xc4,0xce,0x03,0xb3,0x3d,0x79,0x0a,0xe1,0xc3,0x90,0x76,0xc6,0xa0,0x2e,0xe3,0x90,0x46,0x3b,0xf4,0x09,0xe5,0xb0,0x97,0x85 +,0x46,0x1b,0x17,0x2a,0x5c,0x99,0x52,0x53,0x17,0x7e,0x7b,0xf8,0xd8,0xaa,0x22,0xb8,0xd7,0xde,0xe9,0xbb,0x46,0xec,0xe5,0xf9,0xe1,0xe9,0x84,0x1d,0x63,0xdd,0xba,0x52 +,0xb0,0x3f,0xe1,0x0f,0x16,0x2e,0x07,0xa1,0x94,0x71,0x04,0xef,0xa4,0xbc,0x06,0xac,0x00,0xc0,0x9d,0x29,0x22,0xa6,0xa9,0x25,0x45,0x4c,0x1a,0xcc,0xda,0x54,0x19,0xc1 +,0xc8,0xa4,0x09,0x58,0x8d,0xa5,0x8e,0xcd,0xfc,0x36,0xcd,0x4e,0xe1,0x48,0xbb,0x90,0x51,0x9d,0x42,0x35,0x72,0x61,0x03,0x18,0xf9,0x3d,0xe2,0x65,0x33,0x9a,0xdd,0xb6 +,0x6c,0x9b,0x7a,0x5e,0x23,0xd6,0xe8,0x71,0xc1,0x0d,0x29,0x46,0xa5,0x2c,0xf6,0xd8,0x14,0xf4,0xac,0x23,0x76,0x80,0x7e,0xbd,0x23,0xb6,0xdb,0x83,0xf5,0x9b,0x03,0x79 +,0x78,0x07,0x2a,0x19,0x8c,0x8a,0xe0,0x8e,0xdc,0xc7,0xa8,0x32,0xea,0x53,0xd7,0xfa,0xac,0xf0,0xc3,0xcd,0x18,0x80,0x00,0x00,0x00,0x59,0x97,0x57,0x3d,0x70,0xf9,0x3b +,0x73,0xf2,0xfd,0x3d,0x01,0xe9,0x01,0xf1,0xe0,0x38,0x32,0x1d,0x94,0x07,0x67,0x01,0xc0,0x90,0xea,0xb0,0x92,0xf5,0xf1,0x02,0x00,0x08,0x1e,0x34,0xa9,0xfc,0x99,0xfc +,0x40,0x74,0x48,0x12,0x00,0x00,0x00,0x02,0x78,0xc8,0x3d,0x9d,0xb2,0x0e,0xff,0xf1,0x50,0x80,0x38,0x1f,0xfc,0x21,0x6a,0xcf,0xff,0xff,0xdf,0xff,0xf6,0xad,0x40,0xa8 +,0x58,0x90,0x24,0x0c,0x06,0x42,0xc2,0x42,0xa8,0x98,0x2a,0x24,0x0b,0x09,0x42,0x61,0x50,0x98,0x54,0x26,0x15,0x09,0x05,0x04,0xa1,0x31,0x09,0x1a,0xf5,0x4f,0x6f,0x7f +,0x6c,0x67,0x1e,0x77,0x7b,0xcf,0x3d,0xe4,0x91,0x4f,0x35,0xdd,0xb8,0xdf,0x26,0xaf,0x8b,0xe7,0xf9,0xd0,0xfc,0x5b,0xe7,0xe7,0x5e,0x3f,0x6d,0x7e,0x1f,0x02,0x47,0xb3 +,0xe7,0x45,0xfa,0xa8,0x7f,0xe7,0xd6,0x32,0x9c,0x5c,0x74,0xe5,0xa8,0xd9,0x33,0xd5,0xb1,0x73,0xbe,0x0a,0x1a,0x1f,0x83,0xbf,0xf7,0x6c,0x63,0x81,0xbf,0x76,0xff,0x8d +,0xc2,0x6d,0xda,0x20,0x54,0x3e,0x35,0x2e,0x9a,0x5f,0x77,0x29,0x5b,0x80,0xce,0xd7,0x54,0x4c,0xb6,0x35,0x90,0x80,0x97,0x52,0x41,0x31,0x2e,0x83,0x83,0x13,0x1f,0x3e +,0x29,0x00,0x1f,0xfa,0x78,0x5e,0xa1,0x94,0x99,0xc6,0xde,0xb9,0x37,0x58,0x6e,0x54,0xf5,0x52,0xab,0x22,0x82,0x79,0xd3,0x91,0xeb,0x55,0x3e,0x51,0xc2,0x46,0x76,0xb9 +,0x95,0x04,0x2e,0x41,0x46,0xc8,0x19,0x41,0xfd,0x9a,0x17,0x31,0x0e,0x5b,0xf7,0x22,0xd7,0x46,0xf3,0x0d,0x44,0x4c,0x7c,0xce,0xbb,0x5c,0x05,0x3d,0xd8,0x13,0x3b,0x82 +,0x00,0x17,0x52,0xf0,0x95,0x82,0xe0,0x17,0x02,0x8d,0x86,0xa2,0x42,0x30,0x50,0x4c,0x24,0x0b,0x8a,0x02,0x82,0x61,0x40,0x58,0x4e,0x13,0x0b,0x95,0x42,0x21,0x20,0xb8 +,0x44,0x2e,0x11,0x0a,0x85,0x02,0x21,0x30,0xaf,0xea,0xf1,0xde,0xbb,0xeb,0x9a,0xad,0xf9,0xdd,0xa5,0x6b,0xdf,0xdb,0xba,0xe3,0xe3,0xe6,0x38,0x78,0xf3,0x59,0xfa,0xfc +,0xfd,0x7f,0x6f,0xfd,0xfe,0x70,0x7f,0x9e,0x1b,0x79,0xec,0x67,0x63,0xab,0x82,0xff,0xe1,0xf7,0x4d,0x0c,0x3c,0xc9,0x7e,0xa9,0xdd,0xfe,0x27,0x1d,0xda,0xb5,0x7a,0x87 +,0xf1,0xed,0xea,0xb4,0x2f,0x97,0x88,0x9e,0x63,0xc5,0xd7,0x28,0x07,0x12,0x9a,0x05,0xfb,0x16,0x92,0xdb,0x10,0x89,0xb3,0x17,0x73,0x7e,0xe5,0xb3,0x60,0xfb,0x3c,0xfa +,0x67,0xe2,0xf1,0xa9,0x6e,0x2b,0x98,0xee,0x0e,0xe3,0x0a,0x38,0x9c,0xad,0xb7,0xc3,0x90,0x5e,0x32,0x05,0x76,0x24,0xe5,0x17,0xd8,0xd8,0x1b,0x8f,0xfe,0x3b,0xc4,0x56 +,0x5d,0x90,0x7b,0xff,0xb6,0x79,0xbf,0xb4,0xcb,0x2a,0xed,0xf1,0xb0,0x3c,0x99,0x16,0xe2,0x79,0xc0,0x00,0x1f,0x69,0x73,0x41,0xeb,0x20,0x18,0x0e,0x41,0xef,0x3c,0xfc +,0x5e,0x64,0xbb,0x2f,0xd6,0x25,0xe6,0xa8,0x2d,0x09,0xf0,0xb3,0xb5,0x8a,0xa9,0xa7,0x64,0x0a,0x81,0x40,0xf6,0xc0,0x00,0x10,0xee,0x3b,0x2a,0xb8,0x71,0x53,0x93,0x8f +,0x5f,0x0d,0xff,0x57,0xe0,0x00,0xa0,0xf3,0xe2,0x09,0xaa,0x1f,0x96,0x07,0xff,0xf1,0x50,0x80,0x35,0xdf,0xfc,0x21,0x0a,0xcb,0xff,0xff,0xdf,0xff,0xfc,0xa9,0x40,0xa8 +,0x58,0x30,0x14,0x0a,0x86,0x04,0x81,0x80,0xc8,0x5c,0x26,0x17,0x0a,0x04,0xc2,0xc1,0x40,0xa8,0x58,0x4a,0x14,0x0b,0x05,0x48,0x61,0x51,0x18,0x54,0x46,0x12,0x12,0x84 +,0x4a,0xe3,0xf4,0x9f,0x59,0xf3,0xed,0xe5,0xfa,0x4f,0xbf,0x8b,0xaa,0xf3,0xde,0x24,0x8c,0xf6,0xd9,0xc7,0x3a,0xce,0xe9,0xf7,0xe6,0x3f,0xeb,0x07,0x60,0xe8,0xb7,0x56 +,0xa4,0x3c,0x37,0x80,0x5c,0xce,0x90,0x7c,0x8c,0x8d,0x97,0xe8,0xe1,0x5a,0x7e,0xcf,0xfe,0x78,0xdd,0xdb,0xde,0xb5,0xc7,0xfd,0xc9,0xc1,0xba,0x6f,0xff,0xe6,0xea,0x7e +,0xc3,0x87,0x35,0xbe,0xc6,0xa9,0xc4,0x2b,0xf8,0xa2,0x26,0x63,0xef,0x47,0x61,0x16,0xd7,0xec,0xe7,0xe9,0x54,0xe2,0x7d,0x08,0x80,0xdc,0x27,0x7c,0xa1,0xe7,0xbb,0xbc +,0x27,0xe1,0x48,0xef,0x50,0xf3,0x01,0xc0,0x72,0x07,0x91,0xc4,0x7a,0xe7,0xf8,0xfb,0x87,0xc0,0x03,0x98,0x70,0x78,0x03,0xc4,0x02,0xaf,0x76,0xe3,0xc2,0xf4,0x00,0x1c +,0x00,0xb2,0xc7,0x08,0x0e,0x17,0x7e,0xca,0xde,0xf7,0xec,0x51,0x3f,0xa1,0x4c,0xe9,0xde,0x27,0x6e,0x68,0xc0,0xb3,0x18,0x78,0x80,0x00,0x9e,0x8a,0xd3,0xf3,0xa5,0xe5 +,0x18,0xa2,0x4c,0xbe,0xa1,0x76,0x35,0xa0,0xc2,0x02,0x9a,0x82,0x81,0x50,0xa0,0x58,0x48,0x16,0x0a,0x05,0x86,0x82,0x60,0xb8,0x58,0x44,0x17,0x09,0x05,0xc4,0xa2,0x71 +,0x08,0x5c,0x22,0x25,0x0b,0x85,0x46,0x26,0x30,0xaf,0xe1,0xf5,0xfd,0xb8,0xea,0xfe,0xce,0x39,0x45,0x3f,0x1f,0x6f,0x3f,0x3d,0x19,0xe6,0xfb,0xeb,0x5f,0x3c,0x73,0xb9 +,0xfe,0xff,0x6e,0x39,0xf8,0xf1,0xec,0x35,0x83,0xff,0xa4,0xba,0x39,0x22,0x6a,0xd0,0x9d,0x0b,0x81,0xff,0x0e,0xce,0xcf,0xea,0xab,0x65,0x2a,0xa3,0x57,0xf4,0xde,0xd3 +,0x71,0xfe,0xbb,0xce,0x80,0x97,0xc0,0xda,0x6b,0x09,0xec,0x1c,0xa8,0xab,0x88,0x3d,0xd5,0x57,0x94,0xf3,0x9e,0x1d,0x97,0xfd,0xf1,0xe7,0xe7,0xe1,0xa5,0xd9,0x79,0x07 +,0x99,0x79,0x7b,0x69,0x5f,0x85,0xc9,0xf8,0xf8,0xbd,0x0d,0xc4,0x56,0xbf,0x36,0xbf,0xbc,0x6f,0x8e,0x38,0xb9,0x00,0xf6,0x83,0x27,0x2c,0x5f,0x0c,0x59,0x20,0xac,0x3b +,0xde,0xd4,0x10,0x3d,0x3a,0x38,0x5c,0x19,0x30,0xf9,0x8a,0x3c,0x00,0x7b,0x7d,0x70,0x0b,0x8a,0x03,0xcc,0xf2,0x1e,0x3e,0x01,0x3c,0x0e,0x0f,0x37,0x13,0x9f,0x63,0x87 +,0xc3,0x9f,0x3e,0x85,0x47,0x1f,0x1b,0x79,0x71,0x2a,0x00,0x4b,0xc7,0x19,0xa5,0x40,0x06,0x68,0x82,0xd5,0xbe,0x10,0x0d,0xca,0x87,0xfe,0x80,0x1c,0xff,0xf1,0x50,0x80 +,0x35,0x9f,0xfc,0x21,0x0a,0xc9,0xff,0xff,0xff,0xff,0xfc,0xab,0x41,0x30,0x4c,0x28,0x27,0x0b,0x05,0x43,0x02,0x60,0xa8,0x5c,0x2a,0x17,0x12,0x05,0xc2,0xc1,0x80,0xa0 +,0x54,0x26,0x14,0x12,0x90,0x42,0xa2,0x31,0x28,0x4c,0x2a,0x13,0x10,0x8d,0xf1,0xfa,0x4f,0xbf,0xf8,0xff,0xf8,0xbd,0xb5,0xaf,0xb5,0xfe,0xbf,0x9f,0x6f,0x0e,0x37,0x55 +,0x7a,0xca,0x5d,0xe7,0x1c,0x77,0x7d,0xe5,0x6b,0xaa,0x7c,0x7f,0xcf,0xc0,0xde,0xf8,0x6a,0xfd,0xbf,0xa3,0xdc,0x34,0x93,0xfc,0x55,0x71,0x74,0x31,0xfa,0xff,0x00,0x81 +,0xc2,0x7b,0xfe,0x0f,0x1b,0x86,0xef,0x3d,0xb8,0xf4,0x3c,0x89,0x9b,0x5f,0x85,0xda,0x78,0x34,0xbd,0xfd,0x21,0x12,0xf6,0x94,0x19,0xac,0x9c,0xe3,0x99,0x78,0x6e,0x3f +,0x3d,0x39,0x08,0xcd,0x79,0xf6,0x3e,0xaf,0xef,0xff,0x8d,0x13,0xf2,0x34,0x76,0x7f,0xca,0x50,0xf4,0xbc,0x73,0xed,0x3e,0x9d,0x75,0x6b,0xbc,0xe2,0x2c,0x01,0xe3,0xc4 +,0x70,0x37,0x01,0xe5,0x8d,0x5b,0x88,0x3c,0x41,0x09,0xba,0x05,0x9d,0x83,0xc8,0x01,0xcc,0x00,0x3c,0x3c,0xc3,0xd6,0x1e,0xd3,0xd7,0x29,0xee,0x34,0x7f,0xe1,0xd5,0x76 +,0xba,0xf1,0xad,0xca,0x22,0xa9,0x5f,0xe3,0xf9,0xbf,0x77,0xdc,0x0f,0x08,0x02,0x80,0x09,0x9e,0xc5,0x45,0x49,0xf7,0x49,0x58,0x17,0x01,0x00,0x14,0xf0,0x16,0x0a,0x05 +,0x82,0x82,0x21,0xb0,0x60,0x2c,0x34,0x0a,0x85,0x04,0xa1,0x61,0xa8,0x5c,0x6a,0x13,0x0b,0x85,0x42,0x61,0x10,0x98,0x44,0x26,0x11,0x12,0x85,0xc4,0x23,0x71,0xfa,0xfe +,0xcf,0xf3,0xf9,0xae,0xab,0xf3,0x75,0x6f,0xc6,0xf3,0xc6,0x5e,0x69,0x29,0xe7,0xbb,0xfd,0x7d,0x71,0xdf,0x7a,0xf3,0xeb,0x86,0xb5,0x63,0xd1,0xa7,0xa7,0x2e,0x1f,0x69 +,0xfc,0x2f,0xf3,0x3f,0x5f,0x8f,0x88,0xfd,0xf5,0xeb,0xbb,0x17,0x97,0x29,0xe2,0x79,0x75,0xfb,0x4b,0x49,0x74,0xff,0xff,0xd8,0x7b,0xe1,0x68,0xbc,0x23,0xbb,0x54,0x1d +,0x47,0x83,0xc2,0xf7,0xc7,0x61,0xf3,0x0d,0x9c,0x13,0x88,0x85,0x55,0x51,0xdc,0x59,0x51,0xe2,0xf0,0xf3,0xe3,0x7b,0x6c,0xe8,0xe9,0x77,0xed,0x20,0x5a,0x79,0x9d,0x3e +,0xd0,0xdf,0xbb,0xc0,0x37,0xfb,0xf8,0x3f,0xf3,0xd1,0xf6,0x60,0xa1,0xe6,0x1a,0x7f,0xfd,0x82,0xe7,0x87,0xce,0x1e,0x5f,0x04,0x01,0x20,0xf1,0x78,0x79,0xf9,0x00,0xf0 +,0x7d,0x04,0x47,0x3f,0xeb,0x40,0x48,0x73,0xfd,0x55,0x7b,0x94,0x7f,0x87,0xfc,0xba,0xa5,0x0b,0x63,0x40,0x1f,0x94,0x44,0xf8,0x01,0xe6,0x00,0x00,0x1e,0x60,0x00,0x79 +,0x42,0xce,0xc0,0x2e,0x56,0x26,0x50,0x38,0xff,0xf1,0x50,0x80,0x36,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xfd,0xff,0xff,0xfc,0xa9,0x50,0xa0,0x58,0x48,0x28,0x11,0x05,0xc3 +,0x21,0x70,0xc0,0x5c,0x28,0x16,0x0b,0x85,0x02,0xe1,0x60,0xc0,0x58,0x28,0x16,0x0a,0x85,0xc2,0xa1,0x30,0xa0,0x48,0x26,0x21,0x09,0x85,0x44,0x61,0x50,0x88,0x4c,0x42 +,0x26,0xbd,0xe7,0xc7,0x7f,0x3f,0xcf,0xfa,0x7f,0xd3,0xb9,0xfa,0xfd,0xb8,0xcd,0xdc,0xca,0xb9,0x45,0xab,0x3c,0xba,0xf9,0x49,0xc7,0x5d,0xd7,0xff,0xaf,0xd0,0xf1,0x68 +,0xa3,0xfc,0x37,0x1f,0x91,0x6d,0x0b,0xfa,0x7b,0x36,0x3c,0x9f,0x33,0xdb,0x76,0x86,0xff,0xa1,0xde,0x4d,0xcc,0x45,0x76,0xeb,0x9a,0xb9,0xb4,0xa8,0x1b,0xfb,0x11,0xd4 +,0x3e,0xff,0xdd,0x6a,0x2a,0x28,0xbb,0xf1,0x40,0xc5,0x21,0x77,0xd6,0xa5,0x31,0xeb,0x10,0xbe,0xf4,0x47,0xa0,0x7e,0xeb,0x3a,0xd0,0x81,0xac,0xc5,0x06,0xd3,0x86,0xbe +,0xc5,0x3e,0x57,0x8c,0xae,0x22,0x3c,0x6e,0xe3,0x0c,0x33,0xee,0xeb,0xf9,0xa8,0x0e,0x5f,0xc8,0x57,0xf9,0xb7,0x28,0x8f,0x74,0xc8,0x4f,0xd4,0xb2,0x58,0x6a,0x58,0xd9 +,0x02,0xaf,0x07,0xfe,0x9f,0x5b,0xd7,0x3d,0x70,0xff,0xd6,0x29,0x49,0x40,0x12,0xee,0x76,0x1f,0xbe,0x40,0xe2,0x95,0xc9,0xae,0x2e,0x4c,0xf2,0x38,0x84,0x59,0xe7,0x8e +,0xe5,0x80,0x07,0x90,0x00,0xa5,0xc4,0x81,0xeb,0x1d,0xcf,0x70,0xee,0x96,0x01,0x78,0x81,0x46,0xc2,0x50,0xa0,0x58,0x24,0x15,0x0a,0x0a,0x04,0xc4,0x40,0xa8,0x58,0xce +,0x12,0x0b,0x85,0x02,0xe2,0x12,0x28,0x44,0x4e,0x11,0x32,0xff,0x1a,0xfd,0x3e,0x3b,0xbf,0xd7,0xfa,0x7a,0xbb,0xdb,0xdb,0x9d,0xc6,0x49,0xaf,0x3e,0xfe,0xdd,0xbc,0xdf +,0xfe,0xdf,0xf8,0xf7,0xe3,0xfc,0x7f,0x5b,0xe2,0xab,0xfc,0x74,0x3e,0x2f,0xba,0x3a,0x5f,0x98,0xd0,0x9d,0x4e,0xfd,0x53,0xdc,0x41,0xd4,0xf9,0x11,0x22,0xf6,0x17,0xee +,0xeb,0xa3,0x61,0x68,0xc2,0x6e,0xad,0x12,0x65,0xa5,0x7e,0xc8,0xc1,0xcf,0xe8,0xbb,0x9d,0x5e,0x16,0x47,0x72,0x87,0x2e,0x3c,0xaf,0xd5,0xbf,0x88,0x9c,0xb8,0x74,0x4e +,0x76,0xc8,0x5e,0x60,0x0e,0x65,0x39,0x9f,0x2e,0x56,0x87,0x1a,0xa1,0x93,0xb5,0xfb,0xbc,0xe0,0x26,0x7e,0x7c,0xaf,0x22,0x1b,0x37,0xf3,0xdf,0xef,0xb7,0xf3,0xd4,0x4e +,0xf6,0xa2,0x0f,0x29,0xd1,0xce,0x07,0x5b,0xe2,0xe9,0x9b,0xa7,0xa4,0x08,0xc0,0xa7,0xc3,0xd1,0x7d,0xff,0x96,0x80,0x88,0x12,0x1f,0x84,0x0c,0xe1,0x6a,0x6b,0xc9,0xaf +,0xd2,0x0a,0x4b,0xf0,0xf0,0x00,0x35,0x2e,0x4c,0x1e,0xd0,0xb9,0xc0,0x9c,0x0a,0x00,0x39,0xc4,0x13,0xbd,0x3a,0xc4,0x00,0x4c,0x50,0x0e,0xff,0xf1,0x50,0x80,0x38,0xbf +,0xfc,0x21,0x0a,0xcb,0xff,0xfe,0xff,0xff,0xff,0xaa,0x41,0x30,0xd0,0x30,0x24,0x0c,0x06,0x42,0xe1,0x40,0xb0,0x50,0x2e,0x24,0x0a,0x85,0x03,0x01,0x60,0xa0,0x94,0x2c +,0x15,0x13,0x05,0x02,0xa3,0x20,0x98,0x54,0x26,0x51,0x13,0xe3,0xf3,0x5f,0x7e,0x7e,0x7e,0xbf,0xe7,0xfd,0x7d,0x5f,0x1c,0xfc,0x78,0x8a,0xc4,0x0b,0xa1,0xd3,0xc5,0xd5 +,0xcd,0x5d,0xff,0xeb,0xf4,0x3a,0x07,0x21,0xe7,0x2d,0x9f,0x4e,0xda,0x7f,0xae,0xa5,0xf4,0x6e,0xa4,0xeb,0x06,0x7f,0x4f,0xa1,0x69,0x2e,0x9a,0x9d,0xcc,0x7c,0xf4,0x3b +,0xe6,0x8f,0x57,0xff,0xef,0x26,0xc8,0x2d,0xd9,0xf2,0xf5,0x73,0x9f,0xe5,0x8e,0x03,0xf2,0x1f,0xd2,0xac,0x51,0x39,0xa1,0x70,0xaa,0x5b,0xba,0xdc,0x14,0xb5,0x5e,0xd5 +,0x54,0x33,0xe8,0x53,0x84,0x4d,0xbd,0x15,0xf4,0x7b,0xe3,0x36,0x8b,0xc4,0x86,0xc8,0x76,0xf8,0x30,0xcf,0x94,0x9c,0x39,0x7c,0x39,0x2b,0xbb,0xb5,0xc4,0xcf,0x3f,0x65 +,0x87,0x94,0xce,0x4e,0x09,0x6a,0x73,0xc8,0x84,0x1f,0xd1,0x83,0xc1,0xb2,0xd5,0xeb,0x5c,0x2e,0x3d,0x57,0x79,0xc6,0x99,0xa8,0xaa,0x00,0x03,0x87,0x98,0x0f,0x3e,0x3c +,0x0e,0x60,0x30,0x33,0x4f,0xc9,0x2b,0x3c,0x26,0x8a,0x1e,0x2a,0x95,0x31,0x38,0xf5,0xcd,0xb5,0x59,0x5e,0xdd,0xf5,0x8f,0xdc,0xe2,0x7a,0xf9,0xa5,0x05,0x4f,0x5c,0x7f +,0x24,0x77,0xbb,0xab,0x77,0x91,0x7b,0x75,0x41,0x30,0x12,0x01,0x4d,0x01,0x61,0x10,0x58,0x28,0x15,0x1b,0x06,0x02,0xc3,0x50,0xa0,0x54,0x2c,0x37,0x0b,0x0d,0x42,0xc1 +,0x20,0xb9,0x04,0x2e,0x15,0x0b,0x84,0x42,0xe1,0x11,0xa8,0x40,0x22,0x13,0x8f,0x8f,0x0f,0xe7,0xc3,0xaf,0xee,0x49,0xd6,0xf7,0x92,0xe9,0xab,0xe7,0xef,0xbf,0x1e,0x5c +,0x73,0xeb,0x5f,0xf9,0xff,0xf4,0xff,0xd7,0xf3,0xeb,0x7f,0xfe,0xa3,0xcd,0x62,0x8d,0xfb,0xe5,0xfd,0x96,0xbe,0x30,0xe8,0x77,0x75,0xbb,0xbd,0xdd,0x75,0x23,0x83,0x67 +,0x59,0x0a,0xe5,0x97,0x87,0x3d,0xfe,0x60,0x71,0xe5,0xe1,0xdd,0xef,0xef,0x27,0x1f,0x3f,0x0a,0x83,0x3b,0x3b,0xe5,0xd9,0xb4,0x35,0x95,0x33,0xce,0x1c,0x8e,0x9e,0x77 +,0x82,0x33,0x7c,0xae,0xef,0x0a,0xef,0x9e,0xdf,0xb1,0x05,0x55,0x5f,0x20,0x88,0xf0,0xd9,0xb1,0x11,0xcb,0xe9,0xef,0xfc,0x71,0x49,0x20,0xb6,0xaf,0x7f,0x36,0x1e,0xc6 +,0x05,0x69,0x35,0xdc,0x7e,0xe1,0x4f,0x58,0x01,0xbc,0x3a,0x7b,0x2f,0x2f,0x85,0x40,0x7b,0x60,0x00,0x3c,0x9e,0x5e,0xc4,0x00,0xe1,0x79,0x44,0x0b,0x0f,0x6c,0x4d,0x0e +,0x07,0x90,0xf2,0xae,0x0f,0x8f,0x00,0x1d,0x01,0xed,0xf4,0x82,0x00,0x48,0xe8,0x74,0x00,0xf2,0x00,0x12,0x19,0x81,0x05,0x64,0x83,0x9f,0x89,0xcc,0x00,0x5c,0x07,0xff +,0xf1,0x50,0x80,0x3c,0x9f,0xfc,0x21,0x0a,0xcb,0xff,0xff,0xff,0xff,0xfb,0xa3,0x50,0xa0,0x5c,0x2c,0x12,0x0a,0x06,0x04,0x81,0x70,0xc8,0x5c,0x2a,0x17,0x0a,0x05,0x84 +,0x81,0x60,0xc0,0x58,0x28,0x35,0x0b,0x85,0x44,0xc1,0x50,0x98,0x54,0x28,0x25,0x0a,0x09,0x42,0x41,0x50,0x88,0xd5,0xf6,0xaf,0xfc,0xbf,0x8f,0xcf,0xf8,0xf7,0x9d,0xcf +,0xaf,0x5e,0x7b,0x54,0xc6,0xaa,0xa3,0x8d,0xe6,0x9a,0xde,0xf5,0x4f,0x3e,0x3a,0xfd,0x7f,0xf6,0xe8,0x38,0x73,0x7a,0xef,0xfa,0xf6,0x76,0x6e,0x8b,0xf0,0xf9,0x97,0xfa +,0x23,0xed,0x7a,0x6e,0x9a,0x11,0xbb,0xd5,0x7c,0x0e,0x98,0xf7,0x72,0xd9,0x3d,0xbf,0x4a,0x85,0x52,0x0b,0xdd,0xae,0xf5,0xc1,0xae,0x10,0xb0,0x27,0x71,0xde,0x10,0x4e +,0xa0,0xf4,0x49,0x23,0x35,0x1d,0xb7,0x6b,0xf2,0xbe,0x03,0xef,0x51,0xed,0x01,0xf6,0x3d,0x6d,0x57,0xbd,0x71,0x72,0x83,0x9f,0xc2,0xb6,0x41,0xa9,0x38,0x61,0xf0,0x74 +,0xb7,0x54,0x8e,0x2d,0x0c,0x7d,0xd8,0x80,0x70,0xe0,0xae,0x4e,0x69,0x0d,0x10,0x63,0x48,0xf9,0xa5,0x07,0x7b,0x70,0x11,0xf0,0xb3,0x9a,0x5e,0x37,0xae,0xe8,0xfd,0xa7 +,0xda,0xa8,0x74,0xc0,0x1e,0x65,0x14,0x78,0xd8,0xfd,0xb8,0x6d,0x4f,0x3f,0x14,0x55,0xec,0xb9,0x80,0x87,0x39,0xab,0x9a,0xdf,0x8c,0x14,0xe4,0xf9,0x14,0x8f,0xe7,0xb0 +,0xf2,0x5e,0xc0,0x4e,0xf1,0x9d,0x95,0xd4,0xfe,0x40,0x00,0x16,0xbf,0x47,0xe6,0x04,0x71,0x8e,0x6e,0x40,0x72,0x2c,0x00,0x14,0x28,0x02,0x92,0x02,0xc1,0x30,0xb0,0x54 +,0x28,0x25,0x0b,0x0a,0x02,0xc1,0x80,0xb0,0xd0,0x2c,0x35,0x0b,0x05,0x42,0xc1,0x71,0x28,0x44,0x2e,0x11,0x0b,0x89,0x44,0xe1,0x10,0xb8,0x44,0x4a,0x11,0x10,0x04,0xff +,0x4f,0xe9,0xfe,0xdf,0xd7,0xe3,0x3e,0x66,0x7f,0x3f,0xa5,0x4b,0xca,0x88,0x95,0xc6,0xe7,0xc7,0xcf,0xe3,0xde,0xb7,0x5e,0x78,0xf1,0xff,0x3f,0xd1,0xc7,0xfe,0xe3,0xf0 +,0x1f,0xa5,0xbf,0x5d,0xf7,0x6e,0xd6,0xa9,0xe3,0xdd,0xca,0xfc,0xfc,0xfa,0x6a,0x0b,0x66,0x5f,0xfb,0x59,0x94,0x50,0xdb,0xf7,0xbd,0x95,0xa6,0x34,0x59,0xe8,0x0a,0x2a +,0x4f,0x1f,0xff,0xfe,0xca,0x38,0x5f,0xdd,0x8d,0x52,0x75,0xef,0xb5,0x2f,0xb6,0x84,0xec,0xa2,0xde,0xbe,0x3f,0x27,0x5b,0x88,0x8d,0xdb,0xeb,0x12,0xf7,0x91,0xe1,0xe5 +,0x69,0x74,0x70,0xe1,0x69,0x15,0x00,0xcb,0x7b,0x50,0x56,0x37,0x32,0x67,0x19,0xcf,0xd7,0xf9,0x17,0x61,0xe6,0xfe,0x23,0xcb,0x06,0x4c,0x34,0xfc,0xc0,0xdf,0xe5,0xe8 +,0x9f,0xe4,0xe7,0x14,0xf8,0x60,0x01,0x0e,0x37,0x96,0x07,0x05,0x01,0xd2,0x47,0x97,0xce,0x00,0xe5,0xcf,0x97,0xc8,0x51,0xcd,0xc3,0x97,0x19,0x72,0x3a,0x97,0xe7,0xe5 +,0xce,0x75,0xc7,0xcb,0xc0,0x0e,0x72,0x9e,0xe2,0xc0,0x89,0x28,0xc9,0x6d,0x28,0x9f,0x6e,0x1d,0x0d,0xa9,0x30,0x80,0xad,0x70,0xe5,0xe8,0x88,0x7a,0xa9,0x00,0x41,0x2e +,0xe0,0x04,0x07,0xff,0xf1,0x50,0x80,0x3a,0x9f,0xfc,0x21,0x0a,0xcb,0xff,0xf5,0xff,0xf5,0xfc,0xa6,0x50,0xa0,0x60,0x4e,0x14,0x0c,0x05,0x86,0xe2,0x40,0xb0,0x50,0x2a +,0x17,0x0b,0x05,0xc3,0x01,0x40,0xa8,0x98,0x6a,0x33,0x12,0x84,0x82,0xa1,0x30,0x88,0x54,0x22,0x15,0x08,0x91,0xaf,0x5e,0x3e,0x2b,0xdf,0x5e,0xdd,0x7e,0xda,0xe3,0xbd +,0x54,0xe3,0xbc,0x9a,0xca,0x8b,0xaa,0xd5,0x4d,0xe9,0x9a,0xf6,0xe7,0x7f,0xfb,0xfe,0xfd,0x07,0x7e,0xe4,0x8e,0xab,0x57,0x61,0xed,0x5e,0xb8,0x5f,0x6b,0xf9,0xd9,0xf4 +,0x2f,0x7f,0xdf,0xfd,0x55,0xa6,0x5b,0xd9,0x96,0xf4,0xcb,0xbb,0x42,0xf2,0xce,0x57,0xf4,0xc6,0xd0,0x7a,0xfa,0x30,0xa6,0x87,0xb7,0x46,0x53,0x3e,0x41,0xf3,0x1e,0x84 +,0x4e,0xe5,0x1f,0x1e,0xff,0x32,0x7e,0xbe,0x8d,0xd3,0x97,0x0f,0x0a,0x73,0xe7,0xd4,0xd3,0xa7,0x48,0x1d,0xd2,0x5f,0x6b,0xb2,0x90,0x90,0x0e,0xff,0x8b,0x2a,0x1c,0x8d +,0x39,0xcd,0xe8,0x09,0x0b,0xe5,0x3a,0x71,0xb5,0xbe,0x0e,0x5c,0x2a,0x8a,0xb7,0x67,0x55,0x3b,0xfd,0xda,0xa6,0xca,0xf5,0x75,0x7e,0x13,0x8b,0xa7,0xb9,0xee,0x3f,0xc0 +,0x79,0xd4,0xba,0x24,0x0e,0xee,0xc7,0xf8,0x47,0xc7,0x94,0xf0,0x1c,0x41,0x3a,0x7a,0xfc,0x7d,0x94,0xd8,0x03,0xe4,0x73,0xfb,0x81,0x05,0xa5,0xdf,0xdb,0xff,0x76,0xf1 +,0x34,0x6f,0xf1,0xe4,0x28,0x59,0x59,0x1c,0x78,0xb9,0x02,0xb3,0x04,0x1e,0x60,0x10,0xe9,0x72,0x52,0xd0,0x5c,0x14,0x00,0xb0,0x14,0xd0,0x16,0x0a,0x85,0x08,0xc3,0x80 +,0x98,0x54,0x2c,0x38,0x13,0x05,0x42,0xe1,0x60,0x90,0x5c,0x22,0x15,0x09,0x05,0x42,0xe1,0x20,0xb8,0x94,0x66,0x15,0x08,0x88,0xc2,0x23,0x5f,0xdf,0x35,0xeb,0xcc,0xfd +,0x32,0x7d,0xfb,0xe6,0x6e,0xea,0xe9,0x7f,0x5f,0x3f,0x7f,0x5c,0x67,0x7e,0xde,0xab,0x8e,0xfc,0xee,0xbf,0x1e,0x1f,0xed,0xae,0x06,0x84,0xb1,0xdc,0xeb,0xdd,0x39,0x8f +,0xfa,0xb7,0xe6,0xe3,0xdc,0x3f,0x6b,0xf5,0xa7,0x7e,0x4f,0xa4,0xd2,0xdf,0x4a,0xc5,0xeb,0xa3,0x6d,0xa9,0x4f,0x76,0x59,0x01,0xe1,0x83,0xc5,0x2d,0xd2,0x2f,0xc4,0xf7 +,0xb6,0xf0,0x0e,0x1c,0x6f,0x8f,0x57,0xa5,0xd2,0x8e,0x07,0x6f,0xe0,0x81,0xc1,0xab,0xe3,0x78,0x70,0xd9,0x90,0x35,0xd3,0xbb,0xa7,0xd6,0xe9,0xe6,0x09,0x7b,0xb0,0xa7 +,0xe6,0xf2,0x15,0x57,0x21,0x27,0x2f,0xdc,0x00,0x25,0x6f,0xc3,0x77,0xa6,0xff,0x7e,0x1a,0xbd,0x57,0x44,0x00,0x30,0x93,0xa4,0xe4,0x93,0x97,0xbf,0x6f,0x90,0x1e,0x4d +,0x82,0xcf,0x0f,0xc2,0xe8,0xf0,0xc7,0x40,0x03,0x8b,0x9f,0xb9,0xe4,0x07,0xa9,0xf0,0x1c,0x98,0xe3,0xec,0xf1,0x36,0x01,0xe7,0x13,0x3e,0x20,0x7f,0x21,0xff,0x1f,0xd6 +,0x38,0xbc,0xdc,0xce,0x7c,0x87,0x88,0xa4,0x81,0xbc,0x67,0xf9,0xe7,0x3b,0x81,0xdf,0x77,0x20,0x00,0x40,0x14,0x03,0x80,0xff,0xf1,0x50,0x80,0x3b,0x5f,0xfc,0x21,0x0a +,0xcb,0xff,0xfb,0xff,0xfe,0xf8,0xa2,0x41,0x40,0xd8,0x30,0x25,0x0b,0x06,0x02,0xc1,0x51,0xa0,0xd8,0x68,0x36,0x12,0x89,0x04,0x61,0x50,0x98,0x54,0x26,0x15,0x09,0x88 +,0x42,0x62,0x11,0x3e,0x77,0xcf,0xc6,0xf7,0x3e,0x35,0xf6,0xe2,0xa7,0x15,0x39,0xde,0x5d,0xed,0xaa,0x8a,0xb7,0x5b,0xab,0xc8,0x5f,0xfe,0xbf,0x7f,0x23,0xa8,0xe7,0xc6 +,0xe4,0xef,0xec,0xf4,0x36,0x7a,0x0c,0xdc,0xad,0x1c,0xef,0xa9,0x2f,0xcf,0xd5,0x60,0x2b,0x54,0xcb,0xcf,0xfb,0xa7,0x45,0xcf,0xa3,0x91,0xcf,0x0d,0x78,0x87,0x4e,0xff +,0xff,0xbe,0x89,0x1b,0x7f,0x55,0x00,0x1d,0x79,0x69,0xb5,0x35,0x98,0x31,0x79,0x7c,0xe4,0x5c,0xf6,0xfd,0x6d,0x4b,0xf3,0x8d,0x21,0xbb,0xfd,0xaf,0xe2,0x0c,0x1a,0xb5 +,0x40,0x44,0x29,0x93,0x8a,0x21,0x9c,0x6a,0x43,0xae,0x98,0xb0,0x3e,0xcc,0x9d,0xdb,0x47,0x4b,0x5c,0x10,0x3e,0x28,0xe3,0xc3,0x32,0xf8,0x1c,0x3f,0x97,0x75,0xf6,0x2d +,0x12,0xef,0x58,0xf7,0x6b,0xdd,0x67,0x96,0xaa,0xfe,0x2e,0xb7,0x50,0xcb,0xed,0x13,0x2d,0xc9,0x03,0x9f,0x9c,0x73,0x0f,0xc8,0x0f,0xff,0xa9,0xc9,0x69,0x65,0xc6,0x0a +,0x49,0xde,0x7b,0x18,0x00,0xb9,0xc4,0xa5,0xc4,0x8d,0x17,0x7f,0xbe,0x0a,0xa4,0x97,0x77,0x72,0xf9,0x4f,0x45,0xf1,0xc1,0xed,0x89,0x51,0x17,0x70,0x04,0x40,0x4c,0x05 +,0x2c,0x05,0x82,0x62,0x41,0x30,0x50,0x4c,0x24,0x0b,0x09,0x02,0xc3,0x71,0xb0,0x88,0x4c,0x14,0x0b,0x85,0x82,0xe1,0x51,0x38,0xd4,0x8e,0x11,0x19,0xfe,0x9f,0xb4,0x4e +,0x2b,0xd5,0x4d,0x65,0x15,0xed,0xeb,0xcf,0x7f,0xe7,0xed,0x7f,0x3f,0xbf,0xe7,0x26,0xb7,0xd3,0xb7,0x17,0xef,0xf8,0xb9,0xa1,0xd1,0x27,0xeb,0x4f,0xea,0xbf,0x87,0xad +,0x7e,0xe2,0x3c,0xbf,0xcf,0xbd,0x70,0xa2,0x69,0xbd,0x39,0x7c,0xa7,0xf1,0x70,0x9a,0x0a,0x17,0x1e,0xcf,0xeb,0xdf,0x0b,0x0b,0xfc,0x92,0xfd,0x2d,0xd7,0x5a,0x1d,0x7c +,0xbf,0xae,0xbf,0x67,0x2c,0x98,0xf3,0xfc,0x67,0x4a,0xd9,0x3b,0x8c,0xc0,0x15,0x75,0x79,0x07,0x9f,0x2d,0x17,0x04,0x00,0x4b,0x8a,0xff,0x5f,0xb3,0x1f,0x4e,0x00,0x76 +,0x05,0xe1,0x5f,0x55,0x21,0xcb,0xbe,0xfa,0xa8,0xfc,0x77,0x28,0x46,0xf1,0xfc,0x04,0x07,0x31,0xce,0xed,0x7e,0xf2,0x5f,0x95,0xe0,0x7c,0xb1,0xa9,0xfe,0xd2,0x80,0x01 +,0xbb,0x9b,0x86,0xde,0xf2,0x37,0x37,0xb4,0x34,0x19,0x5d,0xff,0x1a,0x1e,0x6a,0x80,0xe3,0x3d,0x2e,0x03,0x9b,0x97,0x30,0x21,0xfd,0xa8,0x03,0xcd,0x71,0x47,0x68,0xf8 +,0xd3,0x36,0x2b,0xcf,0xe6,0x0f,0x7d,0xe4,0x8e,0x99,0xb0,0x03,0xcd,0xf0,0xe0,0xe4,0xb3,0x97,0xe1,0xe8,0x52,0x95,0x37,0xa9,0x03,0xc8,0x00,0xa9,0xf3,0xe6,0xb8,0xe4 +,0xae,0x3d,0x8b,0xdc,0x1c,0xc0,0x3c,0xa2,0xc7,0x48,0x90,0x07,0x03,0x39,0xf3,0x80,0x1c,0xff,0xf1,0x50,0x80,0x3a,0xdf,0xfc,0x21,0x0a,0xcb,0xff,0x79,0xfe,0xff,0xd8 +,0xa2,0x41,0x40,0x98,0x28,0x18,0x13,0x05,0x02,0xc1,0x40,0xb0,0x50,0x6c,0x15,0x0b,0x09,0x06,0xc2,0x80,0xa8,0x98,0x28,0x23,0x0a,0x84,0xc2,0xa1,0x32,0x88,0x80,0x2e +,0xf3,0xed,0xd4,0xf8,0xfd,0xbc,0xf5,0xeb,0x55,0xad,0x56,0xf1,0x96,0x95,0x2a,0x5e,0x1a,0x65,0x94,0xe3,0xfe,0xff,0xc8,0xd6,0xfa,0xbe,0x0d,0x45,0x3d,0xcc,0xdb,0x7f +,0x51,0x6f,0x65,0xc2,0xc3,0xd5,0x1e,0x20,0xf7,0x7a,0x7a,0xb5,0xee,0xdb,0x5f,0x6d,0x03,0x36,0x90,0xf8,0xa6,0x62,0x7f,0xf9,0xf0,0x43,0x5e,0xe7,0x3d,0xf4,0x85,0xa1 +,0xcf,0xe1,0x56,0x50,0xdd,0x73,0x49,0xb2,0x6f,0x1f,0x3a,0xe6,0x48,0xfd,0x3d,0x17,0xe8,0xf0,0x96,0xf2,0xa5,0xe7,0x90,0x1c,0x86,0x2a,0x49,0x80,0x40,0xfc,0x76,0x42 +,0x94,0xa6,0xfc,0x51,0xdc,0x32,0x4e,0xa2,0x22,0xe9,0xcd,0xc6,0x74,0xe3,0xe2,0xe0,0x10,0x72,0xd4,0xd7,0xd6,0xb1,0xd9,0x50,0x23,0x8c,0x12,0x93,0x39,0x26,0xe9,0xda +,0x6c,0x3b,0x3d,0x20,0x04,0x4c,0xbe,0x6f,0xcc,0x70,0xaa,0x2d,0xfb,0x6f,0x4c,0xfc,0xb7,0x23,0x87,0x73,0x27,0x00,0x68,0xad,0x78,0xf7,0x74,0xb8,0x84,0xda,0x35,0x2e +,0x61,0x5c,0xb2,0x1e,0xe6,0xb7,0x7d,0x5b,0xce,0x92,0xa7,0x70,0xf7,0x6c,0x77,0xb4,0x6a,0x1e,0xed,0xfa,0x21,0xdc,0x77,0x81,0x00,0x12,0x02,0x9d,0x86,0xa2,0x20,0xa0 +,0x54,0x28,0x16,0x13,0x85,0x46,0x82,0x80,0xb8,0x58,0x2e,0x15,0x09,0x85,0x44,0xe1,0x60,0xb8,0x58,0x2a,0x37,0x0a,0x91,0xc2,0xa1,0x30,0x88,0xd9,0xc7,0xc5,0xe7,0x3c +,0x6b,0xf3,0x8f,0xc7,0xcd,0xd6,0xeb,0xae,0x7a,0xe7,0xfc,0x7e,0x93,0x79,0xc6,0x55,0xea,0x72,0x4d,0x38,0xf3,0x9d,0x0f,0xc4,0xf9,0xf6,0x7c,0xa5,0x78,0x74,0xbf,0x9a +,0xff,0xb9,0xd5,0xa7,0xb2,0xdf,0x34,0xd7,0x7f,0x6e,0x5b,0xde,0xc2,0x73,0xc3,0xe4,0xe5,0xc1,0xcb,0xf7,0xa4,0xbd,0xef,0xc8,0x43,0xa7,0xa6,0xfb,0xfa,0x4e,0x68,0x1e +,0x60,0xe9,0x68,0x77,0x5a,0x1f,0x88,0xe3,0xcb,0xd2,0xe1,0xf3,0x3c,0x91,0xab,0x58,0x8f,0x0e,0x6a,0x47,0x84,0x4f,0xa5,0x0b,0xd6,0xf7,0xb8,0xe0,0x7e,0x2c,0x2b,0x5f +,0x99,0xaf,0xd5,0x6f,0x34,0x00,0xd7,0x26,0x47,0x69,0x01,0x03,0x91,0xe3,0xea,0x78,0xd6,0xfb,0x3d,0xf9,0x05,0x69,0x55,0x19,0x88,0x29,0xf6,0xbb,0x53,0xb7,0x3e,0xd9 +,0x9b,0xf0,0x47,0x47,0xc5,0xf2,0x71,0x5c,0x1f,0x5f,0x81,0xc4,0x03,0x87,0x81,0x7e,0x60,0x1c,0xcf,0x08,0x01,0xc0,0x1c,0xb9,0x25,0x5c,0xb8,0x73,0x2b,0x87,0x17,0x2f +,0x87,0x2f,0x00,0x73,0xf9,0x72,0x1e,0x7c,0x87,0x3e,0x61,0xcd,0x3c,0x1c,0x79,0xbc,0xb9,0xf1,0x00,0x19,0xa8,0x4c,0x7d,0xc0,0xb0,0x1e,0x1e,0x1e,0x26,0x18,0x43,0xbc +,0x05,0x8c,0x44,0xa0,0x03,0x10,0x1c,0xff,0xf1,0x50,0x80,0x3a,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0x7f,0xfc,0xaa,0x41,0x30,0x60,0x4c,0x44,0x0a,0x85,0x04,0x61 +,0x51,0x21,0x8c,0x28,0x17,0x0a,0x05,0x42,0x84,0x20,0xa8,0x48,0x46,0x11,0x09,0x8c,0x46,0xd5,0x7d,0x9a,0x55,0xf9,0xda,0xd7,0xc7,0xac,0x4a,0xb6,0x4c,0x8a,0xb4,0x24 +,0xad,0x66,0xbf,0x5f,0xf7,0xfd,0x47,0x61,0xa2,0xfe,0x1f,0x8e,0xff,0x23,0xd0,0x9d,0xef,0xe1,0x1b,0x6f,0xeb,0xf0,0xc7,0xf8,0x9e,0x1c,0xdc,0xfa,0x00,0x41,0x5f,0xca +,0x7f,0xdd,0x1c,0x38,0x0f,0x58,0x9f,0x33,0xd9,0xb4,0xd1,0xde,0x23,0xa5,0x7c,0x4f,0xfe,0x8a,0xab,0x6f,0xec,0xf4,0xd7,0x3d,0xaf,0x57,0x85,0x3b,0xdf,0xf3,0x7f,0x0d +,0xb9,0xf8,0x83,0x19,0xa2,0x6d,0x7c,0x6e,0x47,0x7f,0x92,0xc0,0x3e,0x85,0x37,0x5e,0x2b,0xad,0x6a,0x9d,0x57,0x06,0xbc,0x5b,0xc4,0xdf,0x7d,0x24,0xe5,0x4f,0xf2,0x0b +,0x31,0xd6,0x32,0xfa,0x1d,0x6d,0x91,0x1b,0xb3,0xec,0x15,0x6a,0x4c,0xd6,0x13,0x67,0xef,0xd2,0x14,0x6e,0x33,0x10,0x9a,0x61,0xcd,0xb5,0x40,0xac,0xec,0x0e,0x9f,0xd1 +,0xaf,0x3a,0xbf,0x8f,0x62,0x6c,0xdc,0x00,0x64,0x69,0x6d,0x83,0xdf,0x5e,0x4a,0xfd,0x6b,0x10,0xf5,0xbd,0x72,0xe5,0xb0,0x8f,0x3d,0x2e,0x27,0xe2,0x16,0x8d,0x40,0x26 +,0x20,0x02,0x8d,0x82,0x89,0x61,0xa0,0x58,0x2a,0x14,0x0b,0x09,0x44,0xc1,0x20,0xb0,0x54,0x4e,0x16,0x1a,0x05,0xc2,0xa5,0x70,0xa8,0x84,0x6d,0xdf,0xb7,0x3c,0x73,0xa9 +,0xeb,0x1c,0x73,0x73,0x0e,0x39,0xaf,0xaf,0x9d,0x54,0xe6,0xea,0xb5,0xc7,0x35,0x79,0x7a,0x7e,0xed,0x0e,0x34,0x7f,0x41,0xd7,0xff,0x75,0xe5,0x3c,0x93,0x9c,0xf5,0x5c +,0xf3,0x90,0xf1,0xa2,0xdc,0xaa,0x79,0x39,0x81,0xd9,0xd3,0xff,0xd7,0xfa,0xfa,0xf9,0x72,0xb7,0xc7,0xc4,0xff,0xe3,0xe5,0x72,0x1b,0xb8,0xcd,0xc6,0xfd,0xd6,0xec,0x03 +,0xaa,0xf1,0x73,0x8f,0x3f,0x15,0xbe,0xeb,0x83,0x65,0x16,0xf5,0xde,0x0a,0x4f,0x87,0x66,0x65,0x41,0xdb,0x7e,0x01,0x7f,0x88,0x1e,0xaf,0xfd,0x6e,0x7e,0x17,0x13,0xf7 +,0xb9,0x51,0xf1,0xf1,0xf6,0xd2,0xd8,0x6f,0x27,0xef,0xd6,0x40,0xa2,0xaa,0x83,0x1e,0x1d,0x99,0xf0,0xd1,0xc8,0x66,0xe3,0xf1,0xec,0x0e,0x21,0x06,0x59,0xe6,0x97,0x8b +,0x77,0x3f,0x08,0xb2,0xec,0x2c,0xce,0xa0,0x04,0xf4,0x7f,0x47,0xca,0x75,0x37,0x66,0x9b,0xfb,0x1b,0x04,0x37,0xce,0xcd,0xe7,0x81,0xcd,0xd3,0xbf,0x68,0x00,0x79,0x78 +,0xf8,0x03,0x9b,0x5f,0x1e,0xf9,0x57,0x0f,0x97,0xd2,0x7c,0x9e,0x35,0xc3,0xb7,0x93,0x8c,0x4e,0xc3,0x8f,0x3e,0xd7,0x13,0x97,0x2e,0x00,0x38,0x7b,0xeb,0x9b,0xc6,0x3e +,0x16,0x88,0x01,0xcc,0x01,0xe1,0xa0,0x0f,0x00,0x53,0x8f,0x30,0xf0,0xf7,0x80,0x03,0x30,0x05,0x4a,0xcd,0xd6,0xc0,0x70,0xff,0xf1,0x50,0x80,0x3c,0x1f,0xfc,0x21,0x0a +,0xcf,0xfe,0xdf,0xff,0x76,0xfc,0xa8,0x40,0xa8,0x5c,0x34,0x24,0x0a,0x89,0x0a,0x41,0x30,0xa0,0x4c,0x28,0x32,0x0a,0x09,0x84,0x81,0x70,0xa8,0x50,0x24,0x14,0x09,0x84 +,0x44,0xa1,0x20,0x89,0x0c,0x22,0x21,0xfa,0x7b,0x71,0xe3,0x8d,0x62,0xb8,0xcd,0x65,0xf7,0x7b,0xab,0x99,0x49,0x7b,0xd5,0x4a,0x88,0x95,0x5e,0x7f,0x9f,0x81,0xbc,0x3a +,0x9d,0xdd,0xdf,0xae,0xd6,0x4e,0xec,0x1f,0x27,0x76,0xa4,0xea,0x39,0x54,0x06,0x39,0x0f,0x2f,0x57,0xcf,0x27,0xfe,0xb6,0x8f,0x5b,0xfc,0x5a,0xf3,0xd3,0xc6,0xb7,0x1c +,0xb7,0x9e,0x22,0x13,0xeb,0xf8,0xf3,0xbd,0xcb,0xa8,0xb5,0x8e,0x45,0x7f,0x1e,0x37,0x29,0x7a,0x21,0xc4,0x05,0x00,0x81,0xc7,0x1c,0xfd,0x46,0xc5,0xbf,0xbc,0xf3,0x01 +,0xba,0x16,0x59,0xe6,0xbc,0xef,0x3c,0x2e,0xbf,0x51,0xcd,0x52,0xe3,0x13,0xc0,0x5b,0x27,0x20,0x4d,0x6e,0x87,0x61,0x8b,0x26,0x5a,0x5d,0xd1,0x9b,0xa4,0xb9,0xe0,0xe4 +,0x17,0xf0,0x60,0xba,0xce,0xec,0x75,0x47,0x2a,0xbe,0xf1,0xdf,0x9c,0x0c,0xba,0x46,0x9a,0xdf,0x8e,0xec,0x28,0xb1,0xf5,0x20,0xac,0x0a,0xb0,0xbd,0x51,0x52,0x33,0x39 +,0x82,0x3e,0xfa,0x54,0xfb,0xa6,0x20,0x7a,0xdd,0xc8,0x04,0x04,0xee,0x24,0x05,0x33,0x0d,0x02,0xa2,0x40,0x98,0x54,0x28,0x16,0x22,0x05,0x82,0xa1,0x20,0xa0,0xd4,0x48 +,0x16,0x0a,0x06,0x04,0x81,0x80,0xa8,0x5c,0x2a,0x64,0x0b,0x84,0xc2,0x21,0x30,0xb8,0xef,0xf9,0xe6,0xef,0xf3,0x37,0x9c,0x39,0xd5,0xe7,0x57,0xef,0x74,0xc9,0x5c,0x72 +,0x95,0x3a,0xe7,0x2d,0xac,0xf3,0xac,0xe0,0x26,0xd9,0x7b,0xba,0xa3,0x9e,0xf7,0x1d,0xfc,0xbb,0xf3,0xbe,0xa7,0xef,0xbf,0xb4,0xd5,0x32,0x2e,0x87,0x18,0xdc,0x5b,0x69 +,0x92,0xae,0x55,0xf8,0x7d,0x94,0xa2,0x70,0xf0,0xe0,0x7b,0xcd,0xdd,0x25,0x7e,0x87,0xfa,0xfe,0x21,0xc5,0x49,0xc1,0xfc,0x47,0xab,0x83,0x87,0x3e,0xc3,0x87,0x17,0xc3 +,0x9e,0xf7,0xf8,0xc2,0xfb,0x3e,0xe1,0xe8,0x00,0x63,0xc2,0x80,0x9f,0xd1,0xd7,0x86,0xb5,0xf0,0x3f,0xfa,0xff,0x63,0x67,0xff,0xcd,0xcf,0xbe,0xe7,0x3f,0x41,0x99,0x75 +,0xeb,0xf5,0xff,0xd4,0xea,0x4c,0x3c,0xe6,0x26,0xb9,0xe7,0xde,0x65,0x9f,0xff,0x3d,0xaf,0x31,0xf0,0x3f,0x89,0x97,0xb5,0xbb,0xf4,0x34,0xc7,0x7c,0xcf,0x98,0x84,0x9c +,0x11,0xa8,0xd7,0x5c,0x9d,0x5c,0x4f,0x9c,0xfc,0xd6,0xe6,0x5e,0xca,0xe5,0x68,0xce,0xf6,0x9e,0xed,0xfe,0x97,0x6e,0xd0,0x97,0x10,0xfa,0xbc,0x40,0xaa,0xf2,0xed,0x43 +,0xdf,0xe5,0x2c,0x34,0xe0,0xe4,0xf9,0x38,0xf0,0xe4,0x17,0xf2,0xe9,0x8d,0x73,0xee,0xed,0xe0,0x3b,0x8b,0x13,0xf0,0x7c,0x0d,0x53,0xe6,0x1c,0xe2,0xbb,0xe8,0x27,0x9b +,0x9e,0x03,0x8f,0x5f,0x31,0x83,0xc2,0x00,0xb0,0x40,0x03,0xcc,0x3d,0x68,0x40,0x1f,0x84,0x12,0x89,0xdf,0xda,0x03,0x80,0xff,0xf1,0x50,0x80,0x3c,0x3f,0xfc,0x21,0x0a +,0xcf,0xff,0xff,0xff,0xfb,0xec,0xa8,0x20,0xa0,0x5c,0x34,0x18,0x0a,0x0d,0xc2,0xc1,0x70,0xa8,0x50,0x44,0x14,0x0a,0x88,0xc8,0xa1,0x60,0xc8,0x58,0x4e,0x16,0x0a,0x09 +,0x42,0x61,0x20,0xa0,0x54,0x26,0x11,0x09,0x88,0x46,0xdf,0x3c,0xfc,0x7f,0xed,0xff,0xc6,0x67,0xb6,0x6f,0xce,0xe5,0xe6,0xb6,0xdd,0xcd,0xd2,0xd5,0x2a,0xdb,0x97,0xd7 +,0x32,0x7d,0x6b,0x43,0xfd,0xdb,0x47,0x72,0x56,0xe5,0xed,0xbf,0xe3,0xff,0x93,0x47,0xf6,0xe2,0xd7,0xd8,0x8f,0xe2,0x64,0x56,0xef,0xa8,0x7b,0x2c,0xff,0x4b,0xdc,0xa6 +,0xd7,0xef,0xe8,0xf3,0x80,0xff,0xdf,0xfe,0x0f,0xd5,0xbd,0x6d,0xd3,0xf5,0x7f,0xe0,0xf1,0x9e,0xcf,0x93,0x99,0xd5,0x02,0x58,0x1b,0xd3,0x8b,0x05,0xe3,0x4a,0x18,0x71 +,0xbd,0xab,0x63,0x3b,0x72,0x57,0x31,0xe4,0x90,0x98,0x8f,0x10,0x04,0xae,0x7a,0x2d,0x5f,0xd7,0xa8,0x8b,0xd9,0x75,0x7b,0xba,0xc2,0xb1,0xa8,0x63,0xb8,0xc0,0x14,0xff +,0x34,0x15,0xaf,0x36,0x51,0xf4,0xc0,0xff,0xb0,0xf7,0x47,0xa3,0xe8,0x84,0x1a,0x7f,0x25,0xef,0x39,0x21,0x74,0x09,0xee,0xe4,0xce,0xee,0x31,0x77,0x87,0x22,0x5c,0x4c +,0xa9,0xfa,0xd5,0x82,0x1d,0xe6,0xfb,0x33,0xdb,0xca,0x03,0x67,0x1c,0x1c,0x9c,0x58,0xc3,0xf9,0x69,0xd7,0xee,0x01,0xf9,0x3e,0xb8,0x4b,0xdd,0x89,0x48,0xab,0x60,0x58 +,0x4a,0x82,0xc0,0x53,0xb0,0x5c,0x48,0x15,0x0a,0x09,0x84,0x81,0x60,0x90,0x58,0x28,0x16,0x0a,0x09,0xc2,0x61,0x70,0x90,0x9c,0x2a,0x26,0x0a,0x89,0x82,0xa1,0x71,0x28 +,0x5c,0x26,0x17,0x0a,0x8c,0x46,0x61,0x27,0xb5,0xf1,0xf9,0xdf,0xeb,0xf9,0xaf,0xaf,0x51,0x5e,0x7b,0xf8,0xf9,0xe3,0xaf,0x98,0xac,0xaa,0x6b,0x5b,0xd5,0xf8,0xb5,0xf5 +,0x37,0xec,0x28,0xd7,0x5d,0xf7,0x7d,0x3d,0xaf,0x17,0x41,0xe8,0x45,0xaf,0x92,0xea,0xea,0xbc,0x8a,0x5f,0xdf,0xb8,0xa3,0x79,0xbb,0xbf,0xea,0xa9,0x36,0xf3,0xd5,0x5b +,0xce,0xef,0x43,0x9e,0xbc,0xa1,0xff,0xbf,0xe4,0x17,0xe6,0xf8,0xc5,0x35,0x7f,0x0e,0xdb,0x8d,0x6d,0xba,0x2b,0xc6,0xf3,0x35,0xcf,0x37,0x8e,0x5e,0x0b,0x1e,0x10,0xe5 +,0x7e,0xf0,0x06,0x26,0x81,0x64,0xba,0x28,0x32,0x97,0x8b,0xcb,0xea,0xe5,0x67,0xd7,0xf0,0xf9,0x2c,0x57,0x27,0xcb,0x87,0x47,0x7f,0x6f,0x8a,0xbf,0x39,0x40,0xb7,0x47 +,0x10,0x5c,0xa8,0xe3,0xc7,0xbb,0xe3,0xf0,0x7c,0x79,0xf1,0xa7,0x3e,0x25,0x34,0x23,0x91,0xa3,0xbe,0xba,0xbf,0x0f,0x6f,0x46,0xd0,0x1e,0x4f,0xbe,0x07,0x30,0x2b,0xe8 +,0x38,0x0f,0xa8,0xfb,0x80,0x00,0xf3,0xef,0xe5,0xcb,0x9b,0x24,0x76,0x14,0xd6,0xfd,0xf6,0xf7,0x23,0x95,0xbb,0x77,0x9b,0x6b,0x68,0x39,0x9e,0x3b,0xf3,0xf2,0xe7,0xe0 +,0x0e,0xb1,0x47,0x0f,0x9f,0x03,0xc0,0x1e,0x00,0x1e,0x6f,0x03,0xc0,0x0d,0x02,0x32,0x26,0x27,0x08,0x8a,0x55,0xee,0x80,0xe0,0xff,0xf1,0x50,0x80,0x3b,0x9f,0xfc,0x21 +,0x0a,0xcf,0xfd,0xff,0xff,0xff,0xf8,0xa9,0x41,0x30,0x64,0x44,0x14,0x13,0x85,0x02,0xc2,0x42,0x10,0x50,0x46,0x14,0x0a,0x89,0x82,0x83,0x20,0xb8,0x54,0x2e,0x14,0x0a +,0x84,0xc2,0x41,0x31,0x08,0x4c,0x42,0x34,0xf5,0x8f,0xfd,0xff,0xbf,0x77,0x2a,0x6a,0x99,0x15,0x37,0xc3,0x99,0x97,0x51,0x7b,0xe2,0x6f,0x54,0xe2,0xbf,0xef,0x5f,0x03 +,0xc8,0xe6,0xcb,0xba,0x7d,0x3b,0xe9,0x67,0x7f,0xc8,0xff,0xa9,0xf8,0x0d,0x84,0xe4,0x4e,0xff,0x4c,0x23,0x76,0xbe,0xcd,0x4b,0x2f,0x64,0x3f,0x40,0xab,0x8e,0xde,0x29 +,0x54,0x8e,0x7d,0xfe,0xb8,0xff,0x8b,0xeb,0x2e,0xfc,0x74,0x0b,0xb9,0xcb,0x80,0xe1,0xcc,0x73,0xe3,0xc3,0x99,0x0e,0x6b,0xb5,0xc4,0x05,0x33,0x97,0x1d,0x41,0xfa,0xa9 +,0x2f,0x23,0xe7,0x52,0x6c,0x35,0xbb,0xa9,0xcd,0x0d,0x70,0xe8,0x7f,0x13,0xfb,0x78,0xf9,0xf9,0x33,0x9d,0x1a,0x56,0x71,0xf5,0x3a,0xfb,0xc3,0x3c,0x4c,0xd4,0x43,0xb2 +,0xb9,0x7b,0x3c,0x56,0xc3,0x1f,0x5b,0x6c,0xee,0x8b,0xaa,0x46,0x96,0x7b,0xce,0xfd,0x8b,0x0a,0x55,0xd0,0x47,0x26,0x92,0x35,0x0b,0x28,0x7b,0xae,0x6d,0xb8,0x3a,0xff +,0x83,0xa0,0x1f,0xec,0x65,0xbe,0xb2,0xed,0x64,0xe1,0xf3,0xdc,0x3b,0x82,0xb5,0x8c,0xd3,0x55,0x3d,0x1f,0x5e,0x63,0xb8,0x0e,0xea,0xb7,0xf0,0x48,0x01,0x50,0x40,0x0a +,0x54,0x0b,0x09,0x02,0x41,0x50,0xa0,0x58,0x24,0x14,0x33,0x05,0x0a,0x41,0x71,0x28,0x5c,0x2c,0x47,0x08,0x85,0x42,0xe1,0x51,0xb8,0x54,0x42,0x35,0x3f,0x5c,0xf3,0xfa +,0x6f,0xf9,0xfe,0x3a,0xaf,0x6f,0xd2,0x65,0xbd,0xb3,0xd7,0xd7,0x89,0xe7,0xe7,0x25,0x2f,0xe3,0xde,0xf7,0x24,0xb7,0xd5,0x74,0x3f,0xcc,0x7e,0x4e,0xc8,0xe4,0xbc,0x7b +,0x5b,0x50,0xf0,0xfc,0x73,0x6e,0xdb,0xa2,0x7c,0xe1,0x7c,0x4f,0x8a,0x7e,0xf7,0xb6,0xf8,0x0e,0xf9,0xaf,0x92,0xd5,0xfe,0x5f,0x96,0xfd,0xfb,0xfb,0x65,0xf3,0x8f,0x5c +,0x70,0xa0,0x2b,0x7f,0xdc,0x7d,0xbe,0xed,0xe1,0x07,0x9c,0x76,0x3d,0xa6,0xbb,0xc9,0xb5,0xce,0x04,0x39,0x63,0x2b,0x0e,0x87,0x81,0xd3,0xbb,0x7e,0xdd,0xe4,0x14,0x0b +,0x73,0xc7,0x1a,0x39,0xde,0x14,0x63,0x45,0xa1,0x6d,0x45,0x7e,0x5d,0x3f,0x20,0x83,0x70,0xe3,0xaa,0xac,0xe9,0xcb,0xc8,0x24,0xf0,0xd4,0x21,0x57,0x80,0x76,0xdd,0x80 +,0x72,0xa0,0x82,0xde,0x7b,0x7a,0xa6,0xcd,0x7d,0xdc,0x0d,0x2e,0xb2,0x00,0xa3,0x2e,0x28,0x06,0x7c,0x7e,0xf1,0xd9,0xf6,0xf8,0xf3,0x79,0x50,0x01,0xbf,0x6b,0xe2,0x6d +,0xdd,0xf0,0xbd,0x51,0xb0,0xf8,0x76,0xf6,0xc0,0xfb,0x3e,0xf8,0xe5,0x43,0x9f,0x1f,0x27,0xa3,0xab,0x33,0xba,0xec,0xaa,0xee,0x17,0xc7,0xcb,0x8a,0x7c,0x3d,0xe3,0x7f +,0x30,0xda,0x6e,0x71,0x84,0xb9,0x83,0xcc,0x00,0xf1,0xf0,0x79,0x82,0x2f,0x10,0x2a,0x04,0x25,0x40,0x38,0xff,0xf1,0x50,0x80,0x3d,0xdf,0xfc,0x21,0x0a,0xc9,0xdf,0xdf +,0xbf,0xff,0xf8,0xa6,0x20,0xa0,0x58,0x30,0x24,0x0b,0x05,0x04,0x61,0x60,0xa8,0x50,0x8a,0x14,0x0a,0x8d,0x82,0xa1,0x60,0xb8,0x50,0x4a,0x16,0x0a,0x05,0x82,0x61,0x50 +,0x98,0x50,0x4a,0x13,0x18,0x8d,0xef,0x2a,0xbf,0xf3,0xff,0x5c,0xf3,0x7e,0xa6,0xb9,0xd6,0x2a,0xea,0x97,0xcc,0x52,0x53,0x46,0x49,0x34,0xfc,0x7f,0xeb,0xec,0x3e,0x3f +,0xaf,0xc6,0xe2,0x3b,0x2f,0x38,0x5a,0x10,0xb9,0x69,0xaf,0xf6,0xff,0x0b,0x7a,0x3b,0xfa,0x29,0x77,0xf4,0x29,0x8f,0x99,0x7f,0xb3,0x89,0x10,0xfc,0xc3,0x83,0xb7,0xf6 +,0x3d,0xf5,0x9d,0xae,0x48,0x3e,0x5c,0x91,0xc3,0x8f,0x0f,0x9b,0x8c,0x01,0x75,0xc2,0x9d,0xe7,0xc9,0xc4,0xe6,0xf2,0xb7,0xb0,0xf0,0xa4,0x6b,0xbe,0xab,0xdb,0xb4,0x88 +,0x72,0xfd,0x5e,0xf7,0xc6,0x1f,0xf5,0x7f,0xe5,0xff,0x7f,0x41,0xfb,0x17,0x5e,0x33,0xe8,0x00,0xf9,0x1f,0x27,0x15,0x72,0xce,0x3a,0xfa,0x60,0x2f,0x89,0x1e,0x54,0x3f +,0xdb,0x64,0xf1,0x8a,0xbc,0xfe,0x8b,0x73,0xe6,0x5e,0x57,0xf2,0x6e,0xc7,0x4c,0xe2,0x14,0x3c,0x18,0xf0,0x80,0x0b,0x5d,0xef,0xf7,0xd8,0x34,0x9f,0xbe,0xe3,0xf0,0x70 +,0x39,0x2d,0x73,0xc4,0x43,0xb9,0xf0,0xdd,0xff,0xd6,0xf6,0x74,0xeb,0x1e,0xe8,0x7b,0x74,0xd4,0x63,0xd6,0x6f,0x1d,0xe1,0x6e,0x53,0x25,0x54,0x13,0x8b,0xd3,0x9a,0xac +,0x87,0x7f,0xcc,0x7c,0xf9,0x01,0x67,0x7e,0xcd,0x34,0x03,0xdc,0x13,0x8c,0x00,0xb8,0x50,0x0a,0x86,0x0a,0x05,0x82,0x41,0x40,0x90,0x50,0x46,0x15,0x0a,0x09,0x42,0x81 +,0x62,0x10,0x5c,0x30,0x16,0x0b,0x85,0x82,0xa4,0x60,0xa9,0x58,0x28,0x25,0x10,0x91,0x2f,0xfd,0xfc,0x79,0xfe,0xf5,0xbf,0xaf,0x57,0xe7,0xde,0xb2,0xdf,0xe9,0xfb,0x73 +,0x3c,0xf3,0x1b,0xf3,0xe9,0x7a,0x99,0xbc,0x74,0xe3,0x5f,0xed,0xc0,0xd5,0x67,0xcc,0x38,0x1f,0xbf,0x61,0xc7,0x9c,0xe9,0x0f,0xd1,0xf1,0x71,0xcd,0x7c,0x43,0x70,0xf1 +,0x1f,0xf8,0x1f,0xdb,0x65,0x07,0xb7,0xc4,0xcc,0xf8,0xd1,0x42,0x73,0xab,0x9d,0xa0,0x4c,0xe6,0x3c,0xbe,0x6d,0x88,0x04,0x4f,0xd1,0x81,0xf0,0xe1,0x6d,0x35,0xf1,0x03 +,0x99,0xf2,0x94,0xa3,0x8f,0xf1,0x0b,0x89,0x92,0x12,0xfd,0x27,0x8b,0x7b,0xa1,0xe0,0xe7,0x9b,0xcc,0x56,0xf9,0x71,0xe0,0x38,0xfc,0x79,0x1d,0xe0,0x0c,0x7e,0xec,0xdc +,0xf9,0xf0,0xa5,0x02,0xbb,0xf2,0x0f,0x85,0x53,0x08,0x3c,0x3e,0x55,0xd7,0x7e,0x37,0xbe,0x03,0x8f,0x35,0xb9,0xf0,0xe5,0xe1,0xef,0x9b,0x79,0x80,0x25,0xc8,0xf0,0x7e +,0x3a,0x48,0x4d,0x44,0x98,0xf4,0xf4,0xc0,0xe0,0x1c,0x83,0xa5,0xdd,0xc7,0x98,0x53,0x95,0x64,0x14,0xcd,0x30,0x09,0xa0,0x49,0x77,0xf6,0x3e,0x7d,0xdc,0x46,0xa7,0x27 +,0xfc,0x2f,0xce,0xd5,0xff,0x6a,0x4d,0x01,0xea,0xf1,0x38,0xfd,0x3a,0x0e,0x6e,0xff,0x94,0x04,0x03,0x91,0x03,0x8b,0xef,0xf0,0x05,0xe7,0xfb,0x41,0xb7,0x48,0x04,0x81 +,0x70,0x38,0xff,0xf1,0x50,0x80,0x3a,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xff,0xff,0xa8,0x60,0xa0,0x58,0x4e,0x14,0x0b,0x05,0x0a,0x61,0x41,0x30,0x50,0x6a,0x14 +,0x0a,0x89,0xc2,0xa1,0x61,0x40,0x58,0x28,0x15,0x29,0x94,0x44,0x01,0x6e,0xf3,0x7d,0x52,0x4d,0xdf,0x1c,0xee,0x21,0xce,0xaf,0x6a,0x97,0x8b,0xa9,0x33,0x52,0x3a,0xfd +,0x7f,0xee,0x07,0x9f,0xd0,0xb8,0x1c,0x9f,0x3f,0x6e,0x78,0xbb,0x73,0xe2,0xfc,0x3f,0xe9,0x7f,0x8e,0x13,0xd1,0xf9,0x2f,0x97,0xb7,0x91,0xca,0x74,0xc6,0x90,0xaf,0xa8 +,0x8b,0xbb,0xff,0x67,0x9b,0xac,0x7f,0xd7,0xe4,0x79,0x1f,0xf8,0x71,0x72,0x39,0x0f,0xeb,0xff,0xa7,0xf1,0x78,0xf0,0x72,0xe0,0x71,0x1e,0x5e,0x1e,0x7e,0x4d,0x1d,0xed +,0x5e,0x63,0x7e,0xd7,0x0f,0x90,0xe5,0xf6,0xff,0x5f,0x85,0xe0,0x1d,0x89,0xb7,0x4e,0xde,0x02,0x1c,0xbc,0x70,0xce,0xfa,0xd2,0xab,0x52,0xa3,0xf3,0x68,0xd9,0x54,0x27 +,0x79,0xf6,0x5f,0x79,0x88,0x1c,0x57,0x60,0x00,0x00,0xa5,0xd4,0xb6,0x32,0x96,0x1f,0xb8,0x8a,0xdf,0x2b,0x7d,0x7f,0x47,0xdf,0x70,0xfb,0xb8,0x02,0xbb,0x3e,0x1f,0x70 +,0x73,0xe2,0x1c,0x39,0xfc,0xed,0xc3,0x98,0x71,0xe2,0x72,0x79,0x73,0xe0,0x1c,0x56,0x39,0x73,0x79,0xf3,0xf7,0x70,0x2e,0xd4,0x83,0xa7,0x8b,0x8b,0x92,0x51,0xdc,0xf5 +,0xbd,0xa0,0x49,0xdc,0x9f,0xb7,0xff,0x58,0x1f,0xbb,0xed,0x13,0x50,0x1c,0xf7,0xc1,0x8a,0x1d,0xc0,0x13,0x04,0x00,0x53,0x30,0xd0,0x8a,0x32,0x0a,0x0d,0x84,0xa1,0x40 +,0x90,0x8c,0x24,0x13,0x0b,0x84,0x44,0x42,0x70,0xb0,0x5c,0x4a,0x17,0x0a,0x85,0xc2,0xa1,0x70,0xa8,0x84,0x65,0x4f,0xd7,0xf3,0x56,0xbe,0xbd,0x65,0x2b,0x3f,0x75,0x6d +,0xd7,0xcf,0xb5,0x6e,0xbb,0xae,0xb3,0xad,0xf3,0x77,0x97,0x3f,0x5f,0xfb,0xf4,0x13,0x8a,0x79,0xb5,0x57,0xff,0xd7,0xab,0xf8,0x4f,0xf0,0xfd,0xef,0x49,0xc7,0xd9,0xad +,0xe6,0xe8,0x8f,0xa8,0x7f,0xbf,0xe2,0x61,0xda,0xaf,0xba,0xbb,0x2f,0xf9,0x3e,0x3c,0xfe,0xd7,0xc4,0xbf,0x19,0x8f,0x49,0x1f,0x3d,0x2e,0x6f,0xc0,0xd9,0x43,0xd0,0xca +,0x6f,0x0d,0xd1,0x1c,0xdc,0xfd,0xb8,0x4a,0xad,0x95,0x45,0xbb,0xe5,0x23,0x8e,0xc9,0x7e,0xa7,0xab,0x4d,0x00,0x75,0x69,0x39,0xbc,0x3f,0x0e,0x67,0x6b,0x93,0xce,0xdc +,0x0e,0x79,0x3d,0x01,0x7e,0x17,0xf7,0x86,0x76,0x80,0x76,0x8b,0xaf,0x6b,0xb7,0x97,0x4f,0x10,0x00,0xf3,0x06,0xf7,0x37,0x9c,0x0b,0x7e,0xe0,0x45,0x6c,0x00,0xe9,0xe7 +,0x1d,0x1e,0xd3,0x8f,0x87,0x02,0xfc,0x4f,0x37,0x87,0xdb,0xcf,0xef,0xf1,0x6a,0x76,0x6a,0x6d,0xe9,0x07,0x94,0xde,0x72,0x54,0x79,0x47,0xd7,0xc4,0x9a,0x8b,0x74,0xc6 +,0xff,0x0e,0x3a,0x41,0x43,0xc8,0x07,0x94,0x93,0x3c,0x81,0xc0,0x3c,0xcf,0x3e,0x1e,0x3c,0x82,0xc2,0x20,0x16,0x03,0x80,0xff,0xf1,0x50,0x80,0x3b,0xff,0xfc,0x21,0x2a +,0xcf,0xfb,0xed,0xff,0xef,0xff,0xa4,0x40,0xb0,0x50,0x30,0x24,0x2b,0x05,0x04,0xa1,0x60,0xa0,0x98,0x28,0x25,0x11,0x85,0x82,0xe1,0x61,0x20,0x54,0x28,0x25,0x22,0x04 +,0xc8,0x23,0x7d,0x94,0x38,0x98,0xc9,0x33,0x4d,0xea,0x97,0x59,0x31,0x25,0x5a,0x92,0xa4,0x9a,0xe3,0xf9,0xf6,0x1c,0x94,0x78,0x7e,0x54,0x7c,0xbc,0xe7,0xbf,0xef,0xfe +,0x0f,0x93,0xfb,0xff,0xe3,0xf7,0xc2,0x9f,0xe1,0x38,0x5f,0xbb,0xfd,0x81,0xf1,0xdd,0x70,0xb6,0xfb,0x28,0xf3,0x0f,0x84,0x02,0x7d,0x68,0xa2,0x41,0x71,0x3d,0xa7,0xb9 +,0xe0,0xfb,0xfc,0x1b,0x99,0xc7,0xfa,0xfc,0xbc,0xf9,0x68,0x81,0xfe,0xbf,0xfe,0x62,0xcb,0xf9,0x51,0x35,0x61,0x43,0x96,0xf3,0x70,0xd6,0xf7,0xbb,0x83,0x81,0xd1,0xa9 +,0xe5,0xff,0x7f,0x91,0x44,0xca,0xa5,0xe0,0x66,0x77,0x98,0x07,0x2e,0x7d,0x37,0x59,0x37,0x5f,0xdf,0xfb,0x96,0xe7,0xd9,0xcd,0x3c,0x33,0xf7,0x72,0x44,0x54,0xe8,0x59 +,0x7b,0x36,0x5d,0x8a,0x8e,0x1c,0xa7,0xfd,0x3f,0x75,0xc6,0xcf,0x25,0xf2,0xb5,0xa6,0xdc,0x93,0x5c,0x5c,0x0b,0x72,0x0c,0x1c,0xea,0xa6,0xee,0xe7,0x8a,0xe0,0x6e,0xa0 +,0xe7,0x35,0x26,0x27,0x99,0xbf,0x98,0x77,0x2e,0xea,0xa5,0x7a,0xe1,0x5d,0x97,0x91,0xd3,0xf3,0xc3,0x41,0xeb,0x9f,0xb3,0xe4,0xbd,0xd8,0xf7,0x1d,0xd4,0xf5,0xff,0xe8 +,0xc9,0xbc,0x10,0xef,0x96,0x92,0xa2,0x00,0x22,0x02,0x95,0x86,0x81,0x20,0xa0,0x94,0x28,0x23,0x0a,0x11,0xc2,0xc2,0x41,0x38,0x48,0x4a,0x14,0x0a,0x95,0x82,0xa1,0x70 +,0x98,0x50,0x2a,0x33,0x0a,0x84,0x46,0xf1,0xaa,0xf6,0xee,0xb5,0xbb,0x62,0x6e,0xef,0x9d,0x6a,0x97,0xe3,0xaa,0xee,0x4a,0xaf,0x35,0x3b,0x92,0xd7,0xaf,0xf3,0x62,0xce +,0xee,0xb6,0xe3,0x3e,0x9d,0xf9,0xff,0xfc,0xd5,0xbd,0x0d,0x03,0xd8,0xff,0xc7,0x7f,0x63,0xa0,0x71,0xbd,0x5f,0xe5,0x7d,0xab,0xe8,0xff,0xf3,0xaf,0xc7,0x2d,0xb9,0x3e +,0xfb,0x67,0x9f,0xc8,0xef,0xf3,0xfd,0xd6,0xa7,0x9f,0x66,0xa3,0x07,0x73,0xb7,0xb3,0xab,0xed,0xf6,0xbb,0xb0,0xde,0x6b,0xf1,0xf5,0xf9,0x92,0xce,0xcb,0x4f,0xfd,0x53 +,0x7c,0xa9,0x33,0x3e,0xde,0xd9,0x38,0xd8,0xf4,0xf6,0x3a,0x3a,0xfe,0xbe,0x1e,0x3e,0x7c,0xde,0x7c,0xc1,0xef,0xf2,0x93,0xd7,0x69,0xe7,0xee,0x99,0xd5,0xbc,0xb9,0x39 +,0xff,0x8e,0x0e,0x3c,0xf9,0x7d,0xdc,0x37,0x42,0xac,0x2c,0xb7,0x0a,0x03,0xe6,0x16,0xd5,0x68,0x25,0x20,0x79,0xcf,0x00,0x6a,0xe1,0x20,0x79,0x00,0xdd,0xb7,0x7e,0xf3 +,0x3f,0x17,0xf4,0x3e,0x49,0xc1,0xbd,0x7b,0xbb,0xb7,0xf9,0xac,0xf4,0x7f,0xb6,0xb8,0x3e,0x13,0xf6,0xf9,0x72,0x2e,0x77,0xd2,0x6a,0x6f,0x3b,0xc1,0xf6,0x39,0x9e,0x24 +,0x15,0xc2,0x5c,0x2d,0xc1,0x20,0xef,0x7f,0xea,0xfb,0x63,0xbc,0x24,0x01,0xe1,0xe2,0x0f,0xc6,0xc0,0x4c,0x2a,0x07,0xff,0xf1,0x50,0x80,0x3b,0xbf,0xfc,0x21,0x4c,0xfe +,0xff,0xfd,0x44,0x26,0xe1,0x09,0x91,0x28,0x5a,0xa2,0x4e,0x86,0xfc,0x87,0xb3,0x17,0xe6,0x55,0xdd,0x44,0xd0,0xb1,0xfb,0xf2,0xac,0x2d,0x35,0x65,0x55,0xa0,0x0d,0xdb +,0x52,0x88,0x21,0x08,0xb7,0x39,0xd1,0xc8,0xff,0x7e,0x1d,0x7d,0xc9,0x4d,0x2f,0x9b,0x49,0xc7,0xe9,0xf9,0xab,0xb7,0xd3,0x85,0x1d,0x97,0x8f,0x3e,0xfc,0xad,0x9f,0x5d +,0xce,0xb8,0x7c,0x59,0x04,0x3b,0xa4,0xbc,0xaa,0x67,0xec,0x5f,0x44,0xd3,0xca,0xe7,0x8f,0x39,0x47,0xa5,0x12,0x15,0xce,0xe1,0xa2,0xa2,0x89,0x66,0x9d,0x24,0x1b,0xa8 +,0x7b,0x8f,0xeb,0x6f,0x92,0x99,0x46,0x8c,0xd2,0x41,0x90,0xaf,0x82,0x39,0xe6,0x1b,0x49,0xa1,0x81,0xe7,0xc9,0x4e,0xb2,0x16,0x3b,0xac,0xba,0x94,0x1a,0x82,0x98,0xc4 +,0x90,0x16,0x20,0x98,0x11,0xe0,0x98,0x43,0x40,0xa9,0xc2,0xc0,0x24,0xb7,0x2a,0x43,0xac,0x22,0x11,0xe8,0x90,0x40,0xd1,0x02,0x86,0x31,0xb0,0xde,0x08,0x88,0x10,0x88 +,0x27,0x12,0x41,0x01,0x16,0xc1,0xd9,0x47,0xc6,0x0f,0xfa,0x76,0xd5,0xaf,0xd2,0x79,0x30,0xa3,0x35,0xa9,0x2c,0xa1,0xba,0x3d,0xc3,0xef,0xf1,0x38,0xb9,0x7b,0x14,0xf6 +,0xd1,0x6e,0x60,0xf8,0xbc,0x5f,0xca,0x8b,0x6d,0x7e,0xb7,0x65,0x0f,0x51,0x1b,0x93,0xc6,0x32,0x0c,0xc3,0x91,0x01,0xfa,0x58,0xa0,0x86,0xca,0x0b,0x14,0x2c,0xcc,0xaa +,0x91,0x52,0x53,0xa1,0x9d,0x2d,0x90,0x94,0x54,0xdb,0xbc,0x68,0x4a,0x2c,0x66,0xc3,0x26,0x0d,0xe9,0xcd,0xdf,0x41,0xfc,0x08,0xd3,0xb0,0xba,0xd4,0xc8,0x24,0x98,0xc5 +,0x49,0x92,0x51,0x56,0x37,0xa1,0x69,0x9a,0xf3,0xd5,0x6f,0xf7,0xbb,0x3b,0x66,0xed,0x2c,0xbf,0x8c,0xbb,0x27,0xc3,0xf5,0x67,0x4e,0xb9,0xab,0xea,0xcb,0x6e,0x8a,0xc5 +,0xab,0x2d,0x9c,0x71,0xd9,0x67,0x63,0x49,0x86,0xf2,0x35,0x69,0x2c,0x94,0x0b,0xbe,0x79,0xc1,0x56,0xcc,0xce,0x24,0x88,0xe1,0x75,0x41,0x30,0x1e,0xa8,0xc3,0x09,0xd9 +,0x19,0xb6,0x3e,0xbc,0xe5,0xa6,0xf6,0x9e,0x6a,0xf4,0x4b,0x89,0xcd,0x5a,0x5a,0xbc,0x67,0xa4,0x78,0x17,0x82,0x7f,0xdd,0xfd,0x13,0xee,0x01,0xff,0x77,0xc8,0x03,0xf8 +,0x5d,0x2f,0x45,0xea,0x42,0xb6,0x0e,0x2d,0xf1,0xfe,0x5a,0x62,0x73,0x93,0xad,0x0f,0x7c,0x53,0x7a,0x2c,0xf2,0xdc,0xdb,0x2d,0x01,0x1b,0x58,0x2b,0x98,0x2d,0x7b,0xaf +,0x35,0x19,0x8e,0xaa,0xcd,0x55,0x0e,0x77,0xac,0x5a,0xf6,0x0a,0xd7,0x4b,0x89,0x96,0x29,0xbd,0xa9,0x59,0xaa,0x5d,0xb8,0x4a,0x03,0x13,0xde,0xae,0x2e,0xe2,0xb5,0xc2 +,0x38,0x88,0x19,0x13,0x78,0x9d,0x42,0x02,0x84,0x50,0x91,0x8b,0x22,0x89,0xf4,0xa1,0x08,0x0a,0x58,0x60,0x14,0x56,0x04,0x40,0x72,0x39,0x48,0x54,0x06,0x70,0x0e,0xa2 +,0xc5,0x86,0xe7,0x64,0xe4,0x6d,0x1e,0xab,0xca,0x39,0x3e,0xc4,0xf5,0xfe,0xac,0x6d,0xf4,0x13,0x80,0xff,0xf1,0x50,0x80,0x34,0x1f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x65 +,0x18,0x2c,0x90,0xb1,0x46,0x44,0x49,0x96,0xa4,0x85,0xab,0x5e,0x46,0x32,0x1b,0x26,0xbf,0x5b,0x08,0x65,0x9a,0x0b,0xed,0xa0,0x87,0x08,0x5e,0xdb,0xd4,0x91,0x5a,0x66 +,0xc9,0x90,0xb2,0x41,0xc4,0xff,0x6e,0xa9,0x10,0xd9,0xbb,0x64,0xc1,0xa3,0x73,0x3c,0xb1,0xe9,0xdb,0x25,0xfb,0xb0,0x74,0xc3,0x90,0x02,0x53,0x4c,0xa2,0xf6,0x48,0xff +,0xe2,0x01,0x15,0xaa,0xfb,0x0e,0xef,0xee,0x5b,0xea,0xda,0xd1,0x6b,0x33,0x6a,0x68,0x58,0x04,0x57,0x8b,0xc0,0x82,0x79,0x5c,0xe9,0x86,0xbc,0x93,0xe2,0xd8,0xa5,0xeb +,0x91,0x3f,0x27,0x63,0x01,0x8d,0x25,0x09,0x5f,0xd4,0xfb,0x06,0x5f,0x92,0x23,0x86,0x85,0xc3,0x19,0xb2,0xdb,0xe1,0x68,0x5d,0x3c,0x97,0x89,0x6c,0x40,0x29,0x91,0x72 +,0x01,0x2f,0x36,0x4f,0x49,0x54,0xb1,0xa1,0xd5,0x3d,0x5a,0xfb,0x16,0x64,0x24,0xf5,0xa4,0x82,0x8f,0x20,0x32,0xaf,0x15,0xf1,0xeb,0x51,0xcd,0x1c,0x30,0xed,0x12,0x26 +,0x83,0x91,0x15,0x30,0x91,0x6a,0xa8,0xf3,0x40,0x2e,0x2e,0x03,0xcd,0x8d,0x61,0x43,0x05,0x9c,0x16,0x48,0x54,0xa2,0x32,0x94,0x46,0xaa,0x66,0x82,0x7a,0x79,0x1d,0xeb +,0xa4,0x30,0x7a,0xf2,0xf0,0x2d,0xb6,0x31,0xda,0x99,0x47,0xa3,0xd5,0xc3,0xba,0xfe,0xcf,0xd7,0xbf,0x3d,0x3b,0xb6,0x0c,0xb4,0xf6,0xfa,0x7e,0x91,0x47,0xc7,0xf9,0x9b +,0x7d,0x41,0x26,0xbf,0x4d,0x5f,0x5e,0x5c,0xf8,0xf5,0x94,0xde,0x96,0xf6,0x76,0xf6,0x2d,0xeb,0xf9,0xd3,0xc2,0xb1,0x4c,0x6c,0x8a,0x51,0x8d,0x02,0x64,0xc8,0x9a,0x28 +,0xbf,0x24,0x29,0x8c,0x48,0x6a,0xd7,0xb9,0x72,0xcb,0x6c,0xd7,0x70,0x91,0x46,0xa8,0xe2,0xd2,0x55,0x3f,0x5f,0x96,0xcd,0x33,0xdd,0x61,0xe9,0xd0,0x42,0x4a,0x8e,0xe4 +,0x8e,0x26,0xed,0xe0,0x32,0xb5,0x78,0x8d,0xd3,0x1c,0xdd,0xbc,0x80,0x00,0xc7,0x83,0xd2,0xc2,0xcd,0x9e,0xba,0x3d,0x32,0x4c,0x22,0xe9,0x6f,0xbd,0x7b,0xbc,0x67,0x1d +,0xf9,0xc5,0xee,0x29,0x58,0xca,0xa9,0xa9,0x6a,0xd8,0xcc,0x5c,0x3a,0xb6,0xe3,0xa4,0xc6,0x38,0xd3,0x5b,0xa3,0xa3,0x4e,0x89,0x8b,0x4c,0xc1,0x0f,0x6c,0xf6,0x57,0xb5 +,0xf9,0xc5,0xb6,0x0a,0x75,0xa1,0xb2,0x0d,0xaf,0xa1,0xee,0x53,0x68,0x9a,0x46,0xb2,0x8f,0x04,0x82,0x1f,0x88,0xd7,0xcc,0x9e,0x0f,0x59,0x36,0x00,0xd9,0x65,0xad,0x9a +,0xce,0x8f,0xa5,0x56,0x87,0xb5,0x3b,0x4d,0xe1,0xaf,0xbf,0x2b,0xda,0x19,0xbb,0x33,0x57,0x11,0xc0,0xff,0xf1,0x50,0x80,0x31,0x7f,0xfc,0x21,0x6a,0xcf,0xef,0xff,0xcf +,0xff,0xef,0xb4,0x81,0x30,0x50,0x6a,0x12,0x0c,0x09,0x82,0xe1,0x20,0xa0,0x98,0x28,0x43,0x0a,0x04,0x82,0x83,0x30,0x90,0x84,0x66,0x11,0x53,0xdb,0xc7,0x5e,0x3c,0xf5 +,0xeb,0x8f,0x9f,0x3c,0xf5,0x19,0x51,0x75,0x31,0xaa,0xa4,0x25,0xed,0x22,0x71,0xa9,0xc0,0x95,0xf8,0x67,0x13,0x6f,0x1f,0xe8,0x5f,0xcb,0x69,0xa7,0x7f,0xe6,0x47,0x8b +,0xa2,0x2f,0x29,0x09,0x33,0xf2,0xfb,0x7f,0x4d,0x9b,0x38,0xfd,0x1f,0xcb,0xba,0xd4,0x87,0xb7,0x27,0xad,0x72,0x1b,0xf8,0x8b,0xf6,0x79,0x6d,0xe5,0x5f,0xd2,0xd6,0x5e +,0x96,0xbb,0x4d,0x74,0xd7,0x37,0x18,0xde,0x92,0xc5,0x7b,0xdc,0xa6,0xfe,0x54,0x81,0xb3,0x5b,0xca,0xad,0xc7,0xca,0xdb,0x1c,0xdd,0x43,0xcc,0x6a,0x9a,0x3a,0xe1,0x6f +,0x4a,0x28,0x48,0xb3,0x49,0x26,0xaf,0x54,0xf8,0xd2,0x7d,0x84,0x9d,0x52,0x8e,0xe9,0x0f,0x0e,0x89,0xad,0x5a,0x74,0x43,0x32,0xfa,0xa7,0x7b,0xa1,0x75,0x48,0xaf,0x3b +,0x24,0xa2,0x8a,0x2f,0x34,0xd7,0x41,0x47,0xa8,0x35,0xc8,0x00,0x90,0x02,0xba,0xa8,0x05,0x1a,0x05,0x42,0x81,0x62,0xa0,0x48,0x28,0x16,0x0c,0x05,0x02,0xc2,0x41,0x30 +,0x50,0x6c,0x25,0x12,0x05,0x46,0x61,0x51,0x88,0x54,0x22,0x15,0x09,0x88,0x46,0xfb,0x6a,0xaa,0x57,0xc7,0x3a,0xe7,0x15,0x35,0x99,0xac,0x9c,0xcb,0xb5,0x4d,0x2b,0x4d +,0x56,0x2f,0x9b,0xbb,0xd0,0xed,0xdf,0x6e,0x9a,0x3e,0x15,0xea,0xed,0x47,0xee,0xd5,0x77,0x1a,0xf0,0xd3,0x7c,0x8a,0x87,0x2f,0x31,0x65,0x78,0x8d,0xf8,0xdd,0x96,0xdd +,0xc8,0xae,0x55,0xf7,0x7c,0x33,0xb7,0xfb,0x26,0xaa,0xfc,0xaf,0xb4,0xd8,0xea,0x93,0xf0,0x1c,0x63,0xa7,0xe7,0x9c,0x97,0x7b,0xe4,0x3f,0x34,0xfd,0xe7,0x18,0x2d,0xf7 +,0x56,0xda,0x18,0xb8,0xb5,0x14,0x06,0x37,0xbd,0xb0,0xfd,0xda,0x23,0x92,0x7a,0xed,0x4e,0xf2,0x63,0x87,0x34,0xab,0xf1,0x3a,0x5b,0x9d,0x99,0xe5,0x4e,0x05,0x7c,0x2a +,0x1c,0xfc,0xcf,0x04,0x1c,0x40,0x55,0x38,0x73,0x50,0x38,0x47,0x73,0x9e,0x7a,0xc7,0x8f,0x37,0xe4,0xf2,0x80,0x58,0x2d,0xe7,0x72,0x0e,0x00,0xb5,0x01,0xeb,0xd8,0x04 +,0x4c,0x76,0xb5,0x96,0x0f,0x2f,0x39,0xaf,0x0e,0xa3,0x90,0xa3,0xbb,0xc4,0x01,0xdc,0x49,0xfe,0x20,0xd7,0xce,0x3b,0xa5,0x2c,0x54,0x5c,0x28,0xbc,0x80,0xe0,0xff,0xf1 +,0x50,0x80,0x34,0x3f,0xfc,0x21,0x0a,0xcf,0xcf,0xfe,0x7f,0xe6,0xff,0xb5,0x62,0x18,0x48,0x48,0x16,0x1c,0x05,0x84,0x81,0x50,0xa0,0x58,0x28,0x43,0x0a,0x14,0x84,0x21 +,0x30,0x88,0x48,0x26,0x11,0x09,0x84,0x46,0x61,0x11,0x38,0xd7,0x6f,0xbf,0x73,0x7d,0xf1,0xbf,0x8e,0x54,0xbd,0x73,0x08,0x50,0x6a,0x97,0xbe,0x34,0x75,0xc5,0x8f,0x46 +,0x96,0xd1,0x77,0x3d,0xb7,0xff,0x8f,0xd7,0xcb,0x95,0x3f,0xdf,0xfd,0x4f,0x10,0x54,0x58,0x64,0xeb,0x3e,0xc1,0xf3,0xb5,0xd3,0x88,0xf3,0x40,0xde,0xff,0x14,0x81,0x7b +,0xc1,0x3a,0x19,0xef,0xd1,0x1e,0xff,0x89,0xaa,0xb9,0x23,0x23,0x78,0x4a,0x77,0xfa,0x40,0x73,0x32,0xfe,0x05,0xf9,0xc5,0x32,0xfe,0xdd,0xb0,0xea,0xa6,0x57,0x7c,0x16 +,0x83,0xd6,0x27,0x47,0xf2,0x99,0xa5,0xe5,0xb1,0x2e,0x72,0xde,0x92,0xab,0x0d,0x34,0xa8,0x56,0x2a,0xf6,0x47,0xce,0x4a,0xd5,0x3a,0xfa,0x2b,0xe7,0x74,0x9c,0x69,0x0d +,0xed,0x2a,0x58,0xd3,0xf1,0xe1,0x7b,0x5e,0x35,0xf2,0x28,0xc4,0xad,0x54,0x50,0x85,0x2d,0x47,0xb1,0xac,0x05,0x2c,0x4f,0xcc,0xf3,0x72,0x15,0x12,0xb8,0xa7,0x51,0xb8 +,0x5c,0x81,0x77,0xac,0x3d,0xd1,0x62,0x40,0xa8,0x13,0xc8,0x36,0x22,0x85,0x06,0xc1,0x40,0xa8,0x58,0x48,0x26,0x0a,0x85,0x04,0xa4,0x70,0xa8,0xd8,0x2a,0x23,0x0b,0x84 +,0x44,0x61,0x11,0x18,0x44,0x4f,0xe3,0x5b,0xbc,0xaf,0x6f,0x3d,0xf7,0x55,0x6a,0x54,0x6f,0x51,0x32,0x5d,0x32,0x71,0x8f,0x6b,0xee,0xa4,0xeb,0xc8,0xf0,0x7f,0xdf,0xfe +,0xbf,0x78,0xaf,0xe3,0x52,0x97,0xc9,0xd3,0xe4,0xe9,0xff,0xf2,0x73,0x8a,0xac,0x8d,0x3f,0xfc,0xfe,0x58,0xe7,0xf1,0x66,0x05,0xce,0xae,0x15,0x8f,0xbb,0xab,0x7a,0xfd +,0x5f,0xe1,0xac,0xfe,0x9a,0x2f,0x38,0x72,0xea,0xf9,0x02,0x3b,0xbd,0x6d,0xc8,0xba,0xff,0x6f,0x64,0xeb,0x70,0x5f,0xd7,0xc3,0x8b,0x93,0x8f,0x0e,0x28,0x7d,0x28,0x87 +,0x09,0xa1,0xc5,0x7c,0x17,0xf0,0xae,0xba,0xae,0xbd,0x5a,0xcf,0x26,0xa9,0x69,0x8f,0x83,0xd0,0xe6,0x0b,0x25,0xc9,0xdb,0xc7,0x82,0xb8,0xc8,0xb4,0xf2,0x93,0x84,0x73 +,0x59,0x2e,0x35,0x4c,0xf7,0x92,0x07,0xce,0x04,0x08,0xe0,0xb8,0xa8,0xf8,0xfd,0x96,0x70,0xc6,0xb8,0x4d,0xaf,0xdf,0xc5,0x60,0x1c,0xdd,0xef,0x71,0x57,0xe6,0xec,0x1b +,0x37,0x3c,0x8a,0xdb,0xbd,0xb0,0x12,0x0e,0x76,0x44,0x89,0x67,0x1f,0xb9,0x12,0x7d,0x8b,0x78,0xa0,0x4f,0x66,0xe8,0x29,0x33,0xdc,0xa1,0xdf,0x0e,0xc0,0x58,0x0e,0xff +,0xf1,0x50,0x80,0x33,0x1f,0xfc,0x21,0x0a,0xcf,0xd7,0xff,0xbf,0xcf,0xd7,0xb1,0x30,0xa8,0x58,0x28,0x16,0x0a,0x05,0x42,0x41,0x81,0x38,0x60,0x28,0x25,0x12,0x09,0x84 +,0xa1,0x40,0xa8,0x58,0x28,0x22,0x12,0x04,0x86,0x22,0x32,0x09,0x53,0x2a,0xfa,0xdf,0x1c,0xfa,0xf3,0xbb,0xbb,0xef,0xaa,0xc9,0x75,0x79,0x30,0x4a,0x97,0xbf,0xaa,0xbd +,0xe5,0xfc,0x57,0x43,0xf3,0xef,0x6b,0xfa,0x7e,0x11,0xc9,0x74,0xc3,0xab,0xc4,0x7a,0x7c,0xe3,0xfc,0x30,0x70,0x2b,0x4a,0x07,0xa0,0xf5,0x3a,0x3f,0x5a,0x63,0xdd,0xe2 +,0x9e,0x0f,0x3f,0x2d,0xa8,0x6c,0xe2,0x86,0x4a,0x7a,0xcc,0xcd,0x2a,0x78,0x12,0x0f,0xb5,0x65,0x7e,0x0e,0xb2,0x7e,0x06,0x84,0x6a,0x86,0x87,0xc7,0xa9,0xe9,0xfb,0xba +,0xf9,0x26,0x76,0x3c,0xb3,0x20,0x13,0xa7,0x52,0xa7,0xa2,0xf8,0x8e,0x7d,0x3d,0xde,0xa1,0x36,0x62,0x19,0xed,0x55,0x68,0x08,0x8d,0x6a,0x7c,0xe2,0x58,0xb5,0x06,0xc7 +,0xc6,0xe5,0x9d,0x15,0xe3,0xbd,0x62,0xcf,0xc6,0x35,0xd2,0xc0,0x5a,0xb0,0xac,0x22,0x1f,0x5a,0x15,0x7a,0x34,0xcf,0x5e,0xc0,0x26,0x3d,0x65,0x22,0xc9,0x09,0x19,0xa4 +,0x2e,0x2c,0x00,0x08,0x91,0x02,0xa5,0x06,0xc3,0x50,0xa0,0xd4,0x2e,0x15,0x0b,0x05,0x02,0xa3,0x41,0x30,0x50,0x4e,0x15,0x2b,0x85,0x82,0x42,0x30,0xb8,0x4c,0x2a,0x13 +,0x08,0x84,0xc2,0x23,0x77,0xac,0xe3,0xbe,0xb7,0xaa,0xbe,0x53,0xe3,0xdf,0x8d,0xee,0x55,0xd6,0xa5,0x65,0xb7,0x2a,0x71,0x75,0x7c,0xd5,0xfb,0x34,0x36,0x5f,0xd3,0x71 +,0xed,0xd1,0x4e,0xae,0x02,0xf5,0x68,0x6d,0x71,0xa9,0x7d,0x07,0x16,0x77,0xea,0x79,0x3e,0x74,0x47,0xc2,0xfd,0xdc,0x9e,0xbf,0x30,0x79,0x3e,0x5e,0x07,0x0f,0xbc,0xf8 +,0x9f,0xe8,0xff,0xbf,0xfd,0xeb,0x24,0xde,0x1c,0xe8,0xb3,0xb3,0xfb,0xa7,0xad,0xff,0xf8,0x75,0xbf,0xb5,0xf0,0x77,0x15,0xb1,0xbc,0xf1,0x1e,0x60,0x1c,0xcf,0x1e,0x5c +,0x62,0x1c,0x3e,0xb8,0x38,0x50,0xe2,0xef,0xf1,0x73,0xf2,0x3c,0x00,0x3e,0x40,0x7d,0x5c,0x9c,0x4d,0xfc,0xb9,0x8e,0x4e,0x91,0xb6,0xfa,0xae,0x43,0x77,0x7f,0xa2,0x8b +,0xe9,0xce,0xda,0x2d,0xbe,0x50,0xbf,0x1c,0xed,0xa1,0xc8,0x17,0xf4,0xa3,0xb5,0xc3,0xa1,0x38,0x92,0xfd,0x45,0x1e,0xb3,0xbc,0x7b,0xe0,0x07,0x85,0xb6,0x00,0x7b,0xaf +,0x18,0x1c,0x9e,0xe0,0x00,0xbc,0xca,0xfc,0x1a,0xa1,0x09,0x94,0x68,0xff,0xfe,0xa0,0x2a,0x2a,0x01,0xb4,0x75,0x03,0x80,0xff,0xf1,0x50,0x80,0x32,0x1f,0xfc,0x21,0x0a +,0xcf,0xff,0xeb,0x7e,0xff,0xd9,0xb2,0x40,0xb8,0x58,0x88,0x12,0x0c,0x05,0xc6,0xc1,0x40,0xa8,0x5c,0x24,0x14,0x11,0x05,0x02,0x41,0x41,0x10,0x50,0x2a,0x12,0x20,0x8c +,0xc2,0x21,0x30,0x89,0x8c,0x3e,0xfc,0xde,0xfc,0x75,0xbf,0xaf,0x1e,0xde,0x92,0x9d,0x77,0x74,0x4a,0x4c,0x9c,0x67,0xb7,0x7f,0x1e,0x97,0x3e,0xfa,0x1c,0x5d,0xdb,0x5f +,0xab,0x78,0xdb,0xa7,0x8c,0xde,0x07,0xdc,0x3e,0x3f,0x50,0xec,0x91,0x51,0x57,0xf8,0x5f,0x10,0xfb,0xdf,0xdc,0xf8,0xff,0x0b,0x75,0x79,0x6d,0x1e,0x3c,0xff,0xe5,0xb1 +,0x9e,0x45,0xbc,0x9d,0xb7,0x6f,0x85,0xcf,0x73,0x95,0x57,0x90,0x7f,0x3a,0xf9,0x6f,0x52,0xe4,0x24,0x1d,0x44,0x83,0x97,0x33,0x3e,0x6e,0xc8,0x7e,0xa2,0x2f,0xbe,0x28 +,0xba,0x20,0xa9,0x50,0xf9,0x1a,0x61,0x67,0xde,0x75,0x2e,0x99,0xa5,0x64,0x15,0x04,0x24,0x8a,0xf4,0x90,0xe9,0xa1,0x78,0x2b,0x62,0x76,0xd6,0x49,0xba,0x57,0x81,0x49 +,0x2b,0x79,0xfa,0x30,0x2d,0xa4,0x85,0xac,0x0f,0x58,0x08,0x20,0x52,0xa8,0xd6,0xc0,0xb8,0x5e,0x08,0x80,0x58,0x12,0x02,0xa1,0x46,0x81,0x60,0xa0,0x58,0x28,0x25,0x09 +,0x05,0xc3,0x01,0x40,0xa8,0x98,0x28,0x16,0x12,0x04,0xc2,0x82,0x51,0x30,0x54,0x68,0x12,0x19,0x8d,0x42,0x21,0x31,0x08,0x9d,0xde,0x4d,0x55,0xf3,0xc7,0xc7,0xe9,0xfb +,0xfe,0x95,0x37,0xaa,0xab,0xd6,0xd7,0x39,0x91,0x96,0x71,0x52,0xf9,0xb9,0xd7,0xb0,0x75,0x3d,0xaf,0x57,0xea,0x7b,0x6d,0xd4,0x43,0xaf,0x41,0xf3,0x1f,0x02,0xfd,0x07 +,0xab,0xd0,0x29,0x25,0x0c,0xfc,0x77,0xee,0x6e,0xfc,0xf9,0x39,0x4d,0x7b,0x73,0xff,0x3b,0xf3,0x7c,0x28,0xfa,0x55,0x78,0x27,0xf9,0x38,0xde,0xbf,0x27,0xff,0x14,0xf1 +,0x7f,0x7d,0x9f,0xe4,0xb5,0x89,0x07,0x5f,0xd0,0x3c,0xc8,0xfd,0x7a,0xe2,0x38,0x6d,0xc0,0x87,0x9a,0x4e,0x3c,0x0d,0x2d,0x50,0x2f,0xed,0x90,0x88,0x81,0xd2,0xfa,0x69 +,0x5c,0x5b,0x7c,0x6c,0x1c,0x5c,0x79,0x35,0xcc,0x52,0x38,0x52,0x91,0x79,0x41,0xb4,0x80,0x8b,0x5d,0x0e,0xf1,0xe3,0x07,0x91,0xae,0xe5,0x49,0x6b,0xeb,0xb5,0x64,0x7b +,0x9b,0x5c,0x1e,0x5a,0x8d,0x1a,0xc7,0x88,0xee,0x05,0xbc,0x52,0x03,0xff,0x6f,0xfe,0xbe,0xf2,0xe0,0x00,0x04,0xf8,0x5a,0x3a,0xad,0x2b,0x40,0xf8,0x74,0x6b,0x14,0x3b +,0xee,0xe8,0xbc,0x02,0x4d,0xc0,0x38,0xff,0xf1,0x50,0x80,0x31,0x5f,0xfc,0x21,0x0a,0xcf,0xef,0xf5,0xbe,0xce,0xe3,0xb0,0x40,0xb1,0x08,0x28,0x26,0x13,0x89,0x04,0xa1 +,0x40,0x90,0x54,0x28,0x35,0x0a,0x09,0x44,0x62,0x51,0x18,0x48,0x22,0x23,0x10,0x84,0xc2,0x25,0x6e,0x63,0xe3,0x9f,0x3e,0x3b,0xf3,0xce,0xb5,0xbe,0xb9,0x54,0x6b,0x96 +,0xa9,0x11,0x55,0x2f,0x5c,0xf5,0x54,0xf6,0xf2,0x34,0xca,0x7e,0x36,0x97,0x9d,0x1f,0xf1,0xe1,0xd1,0xbb,0x18,0xf6,0x79,0x07,0xb3,0x29,0x1e,0x5e,0xa2,0xf7,0xde,0x4f +,0xf5,0xdf,0xd7,0x67,0x7f,0x37,0x94,0x78,0xf0,0x1d,0x65,0xa3,0xec,0xbc,0x2d,0xa9,0x78,0x7e,0x16,0x49,0xe0,0x39,0x1f,0xed,0x3d,0x8c,0x27,0x7c,0xcb,0x31,0xa9,0xda +,0x73,0x8e,0x30,0xa4,0xdd,0x73,0x3a,0x10,0x73,0xfb,0x27,0x92,0x56,0x0a,0xff,0xe9,0xfd,0x9b,0x80,0x9f,0x8c,0x19,0xf1,0x07,0x75,0x87,0x17,0x00,0xe6,0xff,0x4c,0x67 +,0xfb,0x71,0x0c,0x9c,0xd6,0x25,0x2c,0x6c,0x9e,0xcb,0xb4,0x5e,0x9a,0x12,0x4e,0x50,0xfd,0xca,0xab,0x20,0x36,0x07,0xae,0xf9,0x4c,0x88,0x0a,0xf7,0xb6,0x20,0x0a,0x40 +,0x24,0xb8,0xdc,0xb0,0x44,0x0a,0x00,0xaa,0x20,0xa8,0xc8,0x28,0x16,0x12,0x04,0x82,0xc1,0x41,0xb0,0x90,0x2a,0x36,0x09,0x85,0x44,0x22,0x70,0xa8,0x44,0x2a,0x16,0x08 +,0x8c,0xc2,0x21,0x32,0x08,0xdc,0xf1,0xcf,0xe3,0xf3,0x9f,0xab,0xd5,0x67,0xc7,0x75,0xbe,0xa8,0xdd,0xd7,0x1c,0x3d,0xe7,0xb7,0xbd,0x5a,0x4f,0x8e,0x75,0xe9,0xfb,0xef +,0x81,0xd2,0xf0,0x78,0xfb,0xdb,0xf7,0xa3,0xf7,0x6e,0xab,0x94,0x6b,0xd8,0x70,0x61,0xdf,0xf7,0x59,0xe8,0x25,0xf8,0xd0,0xf2,0x12,0xaf,0xe2,0x21,0xc5,0x6a,0x44,0x4b +,0xed,0xe6,0xf0,0xed,0x78,0x9c,0x7c,0x28,0x24,0x2c,0x47,0xaf,0xbf,0xdf,0xff,0x8e,0xe1,0xcf,0x90,0xe5,0xc0,0x78,0x94,0x79,0xdd,0x2a,0xd9,0xfb,0x92,0x8e,0xfd,0xfc +,0xb6,0xdf,0xab,0x7c,0x91,0xbf,0x92,0x38,0xf3,0x23,0xe1,0xc4,0x05,0x3f,0x4d,0xc4,0xb8,0x39,0x22,0x1c,0x39,0xf8,0x72,0xec,0xc2,0x86,0xfd,0x8e,0xa1,0xc8,0x92,0x81 +,0x05,0xda,0xfb,0x32,0x55,0x4a,0x52,0xe5,0xfc,0x15,0x78,0xa7,0x2c,0xca,0x2b,0xd7,0xb7,0xef,0x7a,0xe7,0x7c,0x08,0x97,0x9d,0xe1,0x11,0xdc,0xd3,0x12,0x56,0x7f,0x5f +,0x8e,0xcd,0x65,0x9f,0x66,0xac,0x4e,0xf2,0xb2,0x99,0x87,0x7c,0x94,0xa8,0x12,0xb0,0x0e,0xff,0xf1,0x50,0x80,0x32,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xff,0x6c,0xc7,0xc7 +,0xb3,0x50,0xb0,0x8c,0x2c,0x25,0x0a,0x05,0x82,0xe2,0x61,0x20,0x5c,0x28,0x22,0x0a,0x08,0x82,0x61,0x20,0xa0,0x4c,0x28,0x12,0x12,0x84,0xc6,0x21,0x30,0x88,0x4c,0x42 +,0x66,0x5d,0x3e,0x3d,0x7f,0xdf,0xfa,0x7b,0xf1,0x93,0xcf,0xad,0x5d,0x55,0xf3,0xc6,0x35,0xb2,0x5a,0xf3,0x5b,0xf8,0xf0,0x6b,0xab,0x81,0xe6,0xdd,0x4d,0xf4,0xfd,0x49 +,0xfe,0x3d,0xaa,0xea,0xe2,0x1c,0xba,0xfb,0xfb,0xf0,0xa4,0x53,0x2f,0xb0,0x27,0xcd,0xfc,0x7a,0xde,0x1c,0x43,0xa3,0x37,0xdb,0x23,0xd9,0x05,0x9f,0xe4,0xbf,0x3f,0x02 +,0x45,0x7f,0xe1,0xed,0xe0,0xd3,0xe6,0x5b,0xab,0x33,0x1a,0xc0,0xfa,0xf5,0x19,0x7f,0xf2,0x7d,0x17,0x83,0x00,0xe9,0xa4,0xa8,0xd4,0x47,0xc6,0xf2,0x45,0xc3,0x2d,0xcd +,0x98,0x5d,0x2f,0x5a,0xe7,0x83,0x0e,0xe4,0x13,0x82,0x59,0x7d,0xb1,0x9a,0x40,0x8f,0x7c,0xee,0xa9,0x6d,0x33,0xfa,0x28,0x80,0xa7,0xba,0xb2,0x7e,0x40,0x3b,0xc2,0xe8 +,0xac,0x3d,0x66,0xc0,0x44,0x45,0x16,0x58,0x97,0x89,0x50,0x28,0x16,0x14,0x54,0x05,0x5a,0x89,0x04,0xc1,0x41,0x10,0x50,0x2a,0x12,0x0b,0x85,0x02,0xc1,0x30,0xb8,0x50 +,0x2c,0x14,0x0b,0x05,0x44,0xc1,0x51,0x20,0x58,0x2a,0x11,0x0a,0x85,0x82,0x61,0x20,0x99,0x14,0x26,0x11,0x23,0x3f,0x1f,0xa6,0xb5,0xe3,0xf9,0xfd,0x2b,0xeb,0xdf,0xae +,0x75,0xdc,0x9b,0xad,0x33,0x55,0x51,0xf1,0xf3,0x9a,0x6a,0x56,0x4b,0xe7,0xf1,0x5c,0x07,0x17,0x4f,0x30,0xdd,0x07,0x8f,0x55,0xd0,0x3a,0x39,0x77,0xcd,0xf2,0xcb,0x0b +,0xed,0x7d,0xd3,0xbc,0x89,0x4f,0xf4,0xee,0xc6,0x37,0xbd,0x7e,0x37,0x29,0xd0,0xd5,0xa4,0x4d,0xf9,0xb2,0x55,0x92,0xce,0x4f,0x8c,0x38,0x71,0x71,0x4b,0x84,0x71,0x89 +,0x6e,0x8e,0x09,0x51,0xb8,0x71,0x38,0x8e,0x4d,0x9f,0x21,0xc5,0x53,0xfc,0x09,0xa6,0x96,0xa7,0xbc,0x45,0x01,0xa4,0xbe,0xd1,0x82,0xb7,0x30,0x9e,0x77,0xce,0x38,0x2e +,0x95,0xe0,0x71,0xe1,0xc7,0x9f,0x07,0x2e,0x47,0x2e,0x7d,0x9e,0x45,0xd8,0x54,0xa0,0x10,0x8b,0xbc,0xd9,0x01,0x0c,0xf7,0x5f,0xa9,0xf6,0xcf,0x44,0x74,0xa1,0xc3,0x56 +,0xb4,0xa1,0xff,0x0f,0xbe,0x58,0x7b,0xb6,0x1d,0xc2,0x4f,0x75,0x7e,0xfb,0xd9,0x50,0x7b,0x97,0xb3,0x93,0x9d,0x81,0xce,0xc2,0xff,0xb6,0xfc,0xa7,0x4f,0xa5,0x82,0xe1 +,0xac,0x17,0x50,0x30,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2f,0xdf,0xfc,0x21,0x0a,0xcf,0xe7,0xff,0xf7,0xcf,0x5a,0xaf,0x30,0xb1,0x48,0x4e,0x34,0x09,0x85,0x02,0xa1,0x41 +,0x10,0x58,0x2a,0x12,0x32,0x04,0x84,0x28,0x30,0x89,0x5d,0xca,0xaf,0xfe,0xdf,0xfa,0x75,0xe3,0x9e,0x0b,0x52,0xae,0xf7,0x2a,0xf2,0x52,0x40,0x38,0xbd,0xf1,0xc4,0x83 +,0xfc,0x6f,0xe2,0x5e,0xaf,0x72,0x73,0xe1,0xd4,0xda,0xb0,0x79,0x7c,0x27,0x6b,0x0a,0x45,0xc2,0x47,0xf4,0x7d,0x62,0x1f,0x32,0x36,0x29,0xc5,0xef,0x7d,0x1b,0xe3,0xd6 +,0xc8,0x22,0xcb,0x7a,0x24,0x6a,0xbc,0x72,0xef,0x5b,0x7b,0x4e,0x56,0x2e,0xe8,0x5d,0x51,0xd4,0xcf,0x4f,0xbf,0x53,0x8a,0xc5,0xb5,0xa5,0x99,0x1a,0xdf,0xcb,0xab,0x84 +,0x6c,0x87,0xa4,0x50,0xc7,0xe0,0xc0,0x1e,0x6f,0xc8,0x9f,0x9f,0x47,0x2b,0x2c,0xe9,0x29,0x4a,0x28,0xa8,0x9d,0x18,0xe1,0x8a,0xba,0x92,0xd1,0x74,0xc8,0x10,0xdf,0x78 +,0x91,0x72,0x8a,0x95,0x8b,0x1c,0xc2,0x82,0x83,0xf7,0x15,0x50,0x4a,0x40,0x46,0xa2,0xd7,0x00,0x5e,0x1c,0x00,0xaa,0x20,0xb0,0x50,0x2c,0x14,0x12,0x85,0x82,0xa1,0x40 +,0xa8,0x50,0x8a,0x44,0x0a,0x89,0x02,0xc1,0x40,0xa9,0x18,0x4a,0x12,0x09,0x84,0x42,0xa1,0x31,0x28,0x4c,0x42,0x26,0x4a,0x4d,0xf9,0xf6,0xfb,0x0a,0x2a,0xf3,0x85,0x6e +,0x10,0xc7,0x19,0x75,0x5d,0x54,0x99,0xe7,0x43,0xe6,0x3b,0xf8,0xeb,0x70,0xd3,0xdb,0x7b,0xe9,0xe2,0x7c,0xdd,0x9b,0x95,0x71,0xff,0x37,0x7b,0x97,0xf9,0xbd,0xcd,0xe3 +,0x9d,0x7a,0xbc,0x8e,0x1c,0xd7,0xf0,0xe7,0xcb,0xe4,0xa6,0xb9,0xba,0x51,0xb3,0xe5,0xe1,0x9c,0xde,0x27,0x3e,0x43,0x87,0x0c,0xff,0xd4,0x3b,0x93,0x02,0x38,0xf6,0x6f +,0x0b,0x8a,0x85,0x77,0x38,0xff,0x9f,0xc2,0x5b,0xbb,0x3b,0x3e,0x7b,0xd1,0x5c,0xb9,0x47,0x5e,0x02,0xb9,0x10,0x77,0xaa,0xf8,0x13,0xc8,0xb7,0x2e,0x26,0x0a,0x31,0xde +,0x6a,0xbd,0x54,0x0a,0xb0,0x44,0xed,0x6d,0x02,0x15,0x92,0x1d,0x8f,0x2a,0x28,0x1a,0x68,0x83,0x8f,0x3a,0xa5,0x48,0xd2,0x02,0xc9,0x37,0xcf,0x1b,0x31,0x07,0xb5,0xf7 +,0x51,0x97,0xb7,0xee,0x9d,0x90,0x4c,0xcf,0x24,0x16,0xda,0x15,0xf7,0x02,0x60,0x77,0xff,0xff,0x3c,0x41,0xcc,0x39,0xc0,0x9f,0xb6,0xd9,0x08,0x07,0xbb,0xff,0xa0,0xb8 +,0x98,0x63,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0x1f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0x7f,0x4f,0xf7,0xb3,0x62,0x40,0x54,0x28,0x26,0x1a,0x05,0xc2,0x41,0x50,0xa0,0xcc +,0x28,0x25,0x11,0x05,0x42,0x82,0x20,0x8b,0xd4,0x67,0xb4,0xe3,0xc7,0x8e,0x8b,0xd7,0x33,0x25,0xd2,0x66,0xb1,0x04,0xad,0x6d,0xab,0xaf,0xbf,0xcf,0xc7,0x40,0xf9,0x36 +,0xfe,0x53,0xf5,0x8f,0x88,0x9f,0x63,0x8c,0xf5,0x05,0xdd,0xa9,0xf6,0x08,0xc7,0x39,0x80,0xf1,0x8d,0xe9,0xd7,0x13,0x52,0xca,0x01,0xd4,0x69,0xd8,0x69,0x7c,0x1f,0x54 +,0x75,0x37,0xac,0xf4,0x5f,0x64,0x6a,0x3b,0xd0,0x5b,0xad,0x12,0xb4,0xc6,0xda,0xf0,0xa4,0xa9,0x71,0xe0,0xf6,0x64,0x21,0x78,0xf4,0x74,0x0e,0x35,0x54,0x3d,0xb0,0xf8 +,0x96,0x0c,0x49,0xa5,0x5c,0xea,0xf3,0xa4,0xe7,0xc9,0x43,0xd4,0xf1,0x29,0x24,0x69,0x3b,0x4c,0x56,0xfd,0xf9,0x95,0x24,0xdf,0xa6,0xa2,0x34,0x4c,0x5f,0x70,0xe8,0xcb +,0x72,0xa2,0x09,0x4e,0x88,0x01,0x00,0xa2,0xe0,0x27,0x1b,0x01,0x20,0x44,0x05,0x3a,0x85,0x02,0xa1,0x40,0x90,0x54,0x2c,0x24,0x0a,0x85,0x02,0x41,0x41,0x18,0x58,0x24 +,0x14,0x09,0x85,0x08,0x61,0x50,0xa0,0x54,0x28,0x15,0x0a,0x05,0x82,0x22,0x30,0xa8,0x44,0x66,0x11,0x09,0x84,0x44,0xf5,0xd7,0x7e,0x7e,0x3f,0xa7,0xf8,0xf9,0xde,0xb5 +,0xe1,0xae,0x7e,0xbd,0xe7,0x3a,0x99,0x7d,0x78,0xbc,0xe3,0x96,0xa3,0x58,0x95,0xe5,0x7a,0x0f,0x2d,0x7c,0xe8,0xe3,0xd7,0xbb,0x57,0xdd,0xa6,0xed,0x6f,0xf0,0x78,0xfc +,0x41,0xf9,0x1b,0xd5,0x8b,0xd1,0xcf,0xfd,0xbc,0xb8,0x9a,0x1e,0x0f,0xfb,0x3d,0xf1,0x6f,0xfc,0x59,0xf2,0x9e,0x1b,0xcc,0xf7,0xfb,0x2d,0xbe,0x7f,0x67,0x87,0xef,0x75 +,0xdc,0x89,0x88,0x34,0x3f,0x8d,0xfe,0x00,0x10,0xf2,0x1c,0xbf,0x85,0x85,0x1f,0x09,0xcc,0x71,0xe0,0x16,0xd7,0xc3,0x28,0x45,0xb4,0xa7,0x64,0x3c,0x4e,0x4e,0x21,0x96 +,0x47,0xa6,0xa1,0x77,0xfb,0x5f,0x39,0xb2,0x6d,0x89,0x48,0x21,0x8b,0x88,0xa0,0x0c,0xf7,0xad,0x23,0xd6,0x9f,0x21,0xec,0x84,0xed,0xc2,0x2d,0x65,0xbb,0xcb,0xf0,0x02 +,0xbd,0x60,0x05,0xef,0x58,0x23,0x0b,0x58,0x35,0x7c,0xe7,0x28,0x45,0x62,0x90,0x8b,0xd7,0x9a,0x76,0xa8,0x14,0x78,0x97,0x01,0x50,0x66,0x03,0x80,0xff,0xf1,0x50,0x80 +,0x2e,0x1f,0xfc,0x21,0x0a,0xcf,0xe7,0xff,0xaf,0xcf,0xf7,0xb1,0x61,0xa0,0x58,0x4a,0x12,0x12,0x09,0x42,0x81,0x21,0x20,0x54,0x28,0x32,0x1a,0x84,0x82,0x81,0x50,0x90 +,0x8c,0x24,0x11,0x63,0xbd,0x5f,0x7f,0x7d,0xf1,0xdd,0x22,0x25,0x54,0xa5,0x49,0x57,0x36,0xe3,0x14,0x6a,0xa5,0xfd,0xfe,0xdf,0xaf,0x41,0x38,0x1f,0xab,0x7c,0xff,0x2d +,0xfd,0x71,0xd0,0x6e,0xf8,0x3d,0x79,0xce,0x86,0xf2,0x70,0x75,0x63,0xf7,0x28,0xfa,0xf1,0xcb,0xbc,0x4c,0xe3,0x6e,0x12,0x98,0x88,0xd9,0xd2,0x72,0x7a,0x13,0x43,0x91 +,0xb6,0x93,0xdb,0x33,0xd7,0x4b,0x4f,0x7b,0x95,0xb6,0xb4,0xb7,0x93,0x05,0xa3,0x07,0x92,0xfd,0xfe,0xd7,0x99,0x56,0xe1,0x52,0x63,0x1f,0x33,0x36,0x6a,0xc0,0x62,0x20 +,0x39,0x5f,0x6f,0x65,0x17,0xb0,0x58,0x8f,0xda,0x5b,0x0f,0xb8,0x6d,0x12,0x55,0x4f,0xa8,0xa6,0x78,0x5c,0x12,0xbe,0x07,0xa2,0xf0,0x82,0x37,0x30,0x08,0xad,0x71,0xd1 +,0x65,0xe9,0x0a,0x09,0xae,0x80,0xe2,0x54,0x9d,0x56,0x21,0x74,0x01,0x60,0x50,0x0a,0xb2,0x0a,0x05,0x42,0x81,0x50,0x90,0x5c,0x28,0x12,0x0a,0x85,0x04,0x41,0x40,0xb0 +,0x50,0xca,0x14,0x0a,0x94,0x42,0xa1,0x40,0x98,0x94,0x26,0x11,0x11,0x84,0x42,0xa1,0x30,0x88,0x9b,0x95,0xfe,0x9f,0xd7,0x7c,0x2a,0xdc,0x7a,0xd6,0x54,0x37,0xad,0xf1 +,0xc5,0x2b,0xcf,0xdb,0x3c,0xdd,0x2a,0xea,0x71,0xc6,0xb4,0x3c,0x38,0x8b,0xa3,0xba,0xe2,0xd2,0xec,0xfa,0x3e,0xfe,0x93,0x1e,0x47,0x6f,0x59,0xe8,0x07,0xf3,0x4e,0x06 +,0x27,0xf1,0x0c,0x82,0x79,0x2f,0x25,0xcf,0xf2,0x67,0x7a,0xfe,0xe7,0xdd,0xee,0x6b,0xe5,0xa2,0x75,0xab,0xa6,0x9c,0x14,0xe0,0xf9,0xdf,0x2c,0xb9,0x5d,0x3f,0x24,0x71 +,0x07,0x11,0xe6,0x00,0x39,0x3e,0xa0,0xe2,0x3c,0x79,0x00,0x73,0x03,0x93,0x9c,0xb8,0x56,0x01,0x37,0x3d,0xef,0x1e,0x35,0x27,0x2f,0x77,0xdd,0xcb,0xa1,0x81,0xeb,0xcc +,0xec,0x4a,0x3c,0x1b,0xc5,0x3f,0xce,0xf5,0xda,0xe3,0xdd,0x55,0x88,0x8e,0x0e,0x68,0x0a,0x51,0xeb,0x9f,0x5a,0x1b,0x01,0x5c,0x93,0xac,0x02,0x33,0xba,0xbd,0xce,0x22 +,0x77,0x80,0x90,0xf1,0x00,0x00,0x7a,0xe0,0x98,0x2c,0x03,0x80,0xff,0xf1,0x50,0x80,0x30,0x7f,0xfc,0x21,0x0a,0xcf,0xff,0xf7,0xf5,0xdf,0xfd,0xb3,0x61,0xa8,0x58,0x24 +,0x15,0x19,0x05,0x44,0x81,0x20,0xa0,0x54,0x28,0x32,0x0a,0x05,0x42,0x43,0x50,0x98,0x54,0x28,0x13,0x09,0x09,0x02,0x44,0x11,0x98,0x44,0x4c,0xb5,0x7e,0x3d,0x71,0x4c +,0xae,0x33,0x1c,0x76,0xad,0x2a,0xa4,0x94,0x64,0x54,0x44,0x9d,0x7f,0xdf,0x41,0x3a,0xcf,0xd3,0x6f,0x0f,0x27,0x39,0xa9,0x75,0xf0,0x3a,0xe5,0xb3,0xd6,0xcb,0xd1,0x36 +,0x8d,0x8b,0xc3,0x6e,0xab,0x9f,0x69,0x67,0x35,0x09,0xaf,0xb9,0x22,0xe8,0x92,0xf4,0xee,0xd3,0xec,0xa4,0xbd,0xc5,0xa9,0xd8,0xb5,0xdb,0xed,0xe3,0x9c,0x64,0x7c,0xf4 +,0x63,0xea,0x5d,0x21,0x32,0x8e,0x49,0xa7,0xfd,0x4b,0x89,0x77,0x28,0x4d,0x35,0x70,0xa1,0xe1,0xad,0x52,0x92,0xbd,0x9e,0xec,0xab,0xc4,0x97,0xa5,0x23,0xc6,0x93,0xf0 +,0x98,0xf4,0x62,0x7d,0xa4,0x7e,0x96,0x07,0x11,0x81,0xfa,0x8f,0xac,0x15,0x50,0x05,0xe9,0x7a,0xb0,0xef,0xda,0x3b,0x82,0xf0,0x5d,0x18,0x10,0xa1,0x15,0x22,0x2e,0xc5 +,0x54,0xba,0x82,0xba,0x69,0x1f,0x9a,0x1c,0xf3,0x2b,0x50,0xa2,0x8b,0xa3,0xee,0x12,0x02,0x92,0x04,0x00,0xa7,0x40,0xa8,0x90,0x4a,0x14,0x19,0x05,0x42,0x41,0x50,0xb0 +,0x48,0x28,0x11,0x0a,0x85,0x02,0xa3,0x40,0xb0,0x54,0x2e,0x25,0x13,0x85,0x42,0x61,0x12,0x18,0x44,0x2a,0x13,0x08,0x8d,0xef,0xc5,0x2f,0x7d,0x6f,0x4d,0xde,0x6b,0x9f +,0x8f,0x7c,0xe2,0x66,0x57,0x9f,0x1f,0x1e,0x2f,0x73,0x5f,0x55,0xdf,0xb7,0xcd,0x7c,0x67,0x5e,0xdf,0x43,0xd1,0x78,0x3b,0xf4,0x3f,0x1a,0xf1,0x74,0x6f,0x27,0xba,0x8e +,0xd1,0xe7,0xf6,0xf3,0x5f,0xba,0x14,0xb8,0x1d,0x8d,0x7e,0x75,0xde,0xe7,0x24,0xf5,0xbd,0x70,0x6b,0xef,0x27,0x02,0x07,0x8f,0x27,0x23,0x97,0x3b,0xb7,0x73,0x67,0x2a +,0xc1,0xe4,0xd8,0xe0,0x17,0xb0,0x62,0xf1,0xe0,0x38,0x8d,0x02,0xf9,0xb6,0x47,0x81,0x3b,0x10,0x0f,0x20,0x0e,0x6e,0x12,0x2a,0x38,0x39,0x0e,0x0f,0x1e,0x01,0x03,0x79 +,0xbb,0x51,0x3b,0xc6,0xed,0xda,0xd1,0xea,0xf9,0x22,0x0b,0x25,0xc8,0xae,0x1f,0xb4,0x77,0xd0,0x46,0x34,0x90,0x2b,0x70,0x17,0x44,0x56,0xe0,0x49,0xf9,0x71,0xbe,0x80 +,0xb9,0x3e,0xf6,0x62,0x00,0x07,0x89,0xdc,0x01,0x32,0x80,0x11,0x11,0xb8,0x1c,0xff,0xf1,0x50,0x80,0x2f,0x7f,0xfc,0x21,0x2a,0xcf,0xeb,0xb7,0xff,0xdf,0xfc,0xb5,0x40 +,0xb0,0x5c,0x2c,0x22,0x0a,0x04,0x84,0x81,0x50,0xa0,0x48,0x26,0x12,0x1a,0x85,0x02,0xa1,0x40,0xa8,0xd0,0x6a,0x11,0x09,0x84,0x82,0x21,0x21,0x08,0x48,0x22,0x12,0x11 +,0x88,0x44,0xa9,0xd6,0xf8,0xe7,0xcf,0x77,0x52,0x71,0xce,0xf8,0xda,0x54,0xd6,0x55,0x2e,0xa5,0x55,0x2e,0x95,0x7c,0x4f,0xc6,0x0d,0x7e,0x3e,0xb7,0x9b,0xb6,0x81,0xd9 +,0xf3,0xd3,0xfd,0x9d,0x1d,0x97,0x59,0xcc,0x9f,0x14,0x77,0x3b,0xbd,0xaf,0x0f,0xa7,0xa9,0x73,0xb5,0x76,0xe5,0x57,0x64,0xce,0xf1,0x5e,0x08,0x79,0x34,0x65,0xd8,0xc3 +,0x9c,0x78,0xaa,0x46,0xad,0xca,0xc2,0x9d,0x53,0x76,0x14,0x9b,0xad,0xba,0xdc,0xbb,0x9f,0x24,0xc7,0x01,0x2b,0x11,0x08,0x36,0x72,0x5a,0x12,0x73,0xe7,0x19,0xca,0x48 +,0xf9,0x8b,0x9f,0x51,0x65,0xed,0x31,0x49,0xbd,0xbb,0x5b,0x1d,0x22,0xdc,0x64,0x36,0x92,0x8c,0x1f,0x56,0x0d,0xc4,0x56,0x34,0x39,0xc6,0xf1,0xeb,0xa4,0x4b,0x99,0x7e +,0x81,0x8a,0x81,0xae,0xba,0xa3,0x0d,0x66,0xba,0x7b,0x6d,0x84,0xf2,0x82,0x0c,0x26,0x81,0x58,0xf5,0xe4,0x3d,0x83,0xd6,0x97,0xba,0x0d,0x20,0x13,0x02,0xac,0x82,0xc1 +,0x20,0xa0,0x54,0x28,0x16,0x11,0x09,0x04,0xe1,0x20,0xa0,0x88,0x2a,0x24,0x0a,0x89,0x02,0xa1,0x30,0xa8,0x5c,0x2a,0x27,0x0a,0x88,0x48,0xa1,0x13,0x33,0x58,0xeb,0xf3 +,0xf1,0xb9,0x79,0x4e,0x39,0xfa,0xfb,0x45,0xd5,0x5e,0xb7,0x19,0x52,0xe7,0xe1,0xbd,0xf1,0xdf,0x4e,0xfe,0x06,0xa2,0xe1,0xd3,0xb8,0xbd,0x5b,0x32,0x75,0xf5,0x47,0xc7 +,0x95,0x3e,0xc3,0xee,0x72,0xd3,0xb1,0x8f,0xaf,0xa5,0x6e,0xf1,0x3f,0x98,0x8f,0x07,0x53,0x97,0x5c,0xab,0x93,0x87,0x3e,0xaa,0xcf,0xcb,0xf1,0x1c,0xb9,0xb9,0x2b,0x9b +,0x8b,0xba,0x2d,0xfb,0x1f,0x7a,0x29,0xe6,0xe6,0x12,0xee,0xbb,0x01,0xe6,0x23,0x93,0x90,0x1d,0x3e,0x78,0x90,0x70,0xe3,0xe2,0x05,0xb8,0x04,0xf3,0x45,0xf1,0x70,0x0d +,0xd2,0xdb,0x2e,0x43,0x69,0x7b,0xb5,0x3b,0xd9,0x39,0x9c,0x28,0xe6,0x26,0x01,0x30,0x1c,0x9c,0x5c,0xae,0x33,0x40,0xf8,0x80,0x33,0x5c,0x01,0x33,0xcc,0x00,0x00,0xa4 +,0xcb,0x04,0xa2,0x0b,0x81,0x00,0x16,0xb8,0x2c,0x07,0xff,0xf1,0x50,0x80,0x2d,0x7f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x63,0x24,0xe4,0xd2,0x68,0x2a,0x53,0xc8,0xec,0x9f +,0xb9,0x7a,0xfa,0x7e,0x78,0x50,0xef,0xc5,0xbd,0x7f,0x2e,0x32,0x97,0x51,0xb3,0xe7,0xa3,0x74,0xbf,0x4e,0xa5,0x5d,0x36,0xeb,0xd4,0x1c,0x65,0x0f,0xf8,0x35,0xd4,0xdd +,0xf5,0x2d,0x5d,0x17,0xa0,0x07,0xc6,0x8d,0x6b,0x2f,0xf5,0x7f,0xa3,0x2e,0x38,0x6b,0x88,0x38,0x60,0xef,0x66,0x84,0x57,0x75,0xd7,0xa5,0x1f,0xc7,0x79,0x25,0x5a,0xf4 +,0x67,0xe5,0xdb,0x06,0x66,0xbf,0xd2,0x52,0xe7,0x89,0x9a,0x9a,0x19,0xa8,0xf4,0xeb,0x14,0x8a,0x51,0x38,0xa7,0x55,0x20,0xad,0x2b,0xb1,0x99,0x1f,0xad,0x1b,0x2b,0xea +,0xc9,0xd7,0x46,0xf2,0x16,0x48,0x5b,0x63,0x74,0xe9,0x7c,0x79,0xee,0x2f,0x8f,0x3d,0x6b,0xb9,0xd3,0x4c,0xf9,0x9c,0x63,0xef,0x9f,0xe8,0xeb,0x8e,0x14,0x2b,0xa6,0x34 +,0xbb,0xe8,0xc7,0x96,0x1b,0x57,0x8b,0xad,0xf1,0x77,0xfb,0xeb,0x93,0x0f,0x8c,0xfc,0x1e,0xe7,0xdd,0x7b,0x30,0xc5,0xf7,0x32,0xf7,0x47,0x60,0x08,0x44,0x63,0xa1,0xc4 +,0x1f,0x0c,0x5c,0x86,0x12,0x11,0x21,0x12,0x95,0x8a,0x16,0x88,0xcd,0x09,0x6b,0x0a,0xba,0x9e,0x77,0xc0,0xc7,0x5d,0x92,0xc9,0x6c,0xf6,0x77,0x63,0x46,0x1d,0x36,0x25 +,0x5f,0x48,0xf2,0x7c,0xf1,0x9f,0x4c,0xf4,0xa3,0xfd,0x06,0x9c,0x2f,0xe5,0xaa,0x86,0xdf,0x45,0xa8,0x85,0x21,0x73,0xa4,0x12,0x2c,0x87,0x0e,0x89,0xd9,0x5d,0x4f,0xda +,0xed,0xb5,0xed,0x2a,0xeb,0xdf,0x78,0xef,0xbd,0xe1,0xa6,0xa0,0x9d,0x7c,0x0e,0x0c,0x6a,0x23,0xc8,0xdc,0xf8,0x6f,0xb4,0xca,0xca,0x0f,0xa2,0x6a,0x39,0xdf,0x23,0xbe +,0xad,0x37,0xd5,0xca,0x6d,0x36,0xdc,0x8b,0x6a,0x3e,0x30,0x1f,0xa8,0xe7,0xf8,0x2a,0x3c,0xf8,0x8f,0x5b,0xc4,0xf7,0x3e,0x22,0x77,0x89,0xf5,0xc2,0x5a,0x8d,0xb8,0x03 +,0x41,0xab,0x86,0xb4,0x68,0xbe,0x89,0xf7,0xcb,0x1a,0xa8,0x38,0x95,0x5c,0xd1,0xfb,0xd1,0xdd,0xce,0xda,0x75,0x89,0x4d,0xc0,0x00,0x17,0xe8,0x10,0xf0,0x72,0x5a,0x0f +,0x6a,0x6d,0x9e,0xcc,0xf7,0x4b,0x1a,0x05,0x93,0xc3,0x77,0xa2,0x15,0xdf,0xe5,0x88,0x20,0x00,0x40,0x20,0x70,0xff,0xf1,0x50,0x80,0x2c,0x9f,0xfc,0x21,0x6a,0xcf,0xff +,0xef,0xe7,0xbf,0xff,0xae,0x61,0x20,0x8c,0x2a,0x14,0x13,0x09,0x44,0xc1,0x41,0x28,0x50,0x84,0x25,0x08,0x84,0x82,0x21,0x20,0x8c,0x1f,0x6e,0x37,0xae,0x37,0x77,0xef +,0xd5,0x7c,0x7b,0xc2,0x12,0xab,0x59,0x25,0x55,0xa1,0x75,0x57,0x13,0xe3,0xa0,0x3c,0x7b,0x27,0xe3,0x5f,0x01,0xff,0x13,0xb3,0xc2,0xe5,0xcd,0xfa,0xef,0x3f,0x16,0xb0 +,0xcb,0xf1,0xf5,0xb2,0x27,0x68,0x33,0x50,0xad,0xc1,0xbe,0x88,0xb9,0xec,0xee,0xba,0x35,0xe1,0xb1,0x73,0x74,0xda,0xc7,0x6b,0xa9,0xf3,0x8d,0xc9,0x85,0x46,0xbd,0x6f +,0x3c,0x48,0x22,0xdf,0xcd,0x6a,0xb0,0xd6,0xc1,0x87,0xfa,0x78,0x97,0x7b,0x5c,0xfc,0x6b,0xc7,0x93,0xae,0xf4,0xe9,0xc8,0x94,0x1e,0x26,0x24,0xca,0x0a,0x6e,0x55,0xd7 +,0x1c,0x2b,0x42,0xcc,0x49,0x95,0x80,0x59,0x3a,0x2d,0x13,0x00,0x69,0x48,0xa3,0x62,0x11,0x05,0xc3,0x10,0x12,0xb1,0x11,0x70,0x12,0x17,0x02,0xb0,0x84,0x82,0x60,0xa0 +,0x54,0x28,0x35,0x0a,0x05,0x42,0x41,0x40,0x90,0x90,0x2a,0x23,0x0a,0x09,0x44,0x61,0x50,0x88,0x50,0x26,0x11,0x09,0x84,0x42,0xa1,0x30,0x88,0x4c,0x6a,0x13,0x08,0x89 +,0xac,0x54,0xce,0xb9,0xf3,0x9e,0x3a,0xeb,0xe7,0xe3,0x7d,0xca,0x95,0x52,0xe4,0xbf,0x1c,0x49,0xbb,0xc7,0x19,0xae,0xb7,0xae,0x06,0xad,0x1e,0x56,0x80,0x5e,0x3a,0x09 +,0xf0,0xda,0x38,0x0f,0x1f,0x92,0x5d,0x86,0xbb,0x97,0x96,0x25,0xab,0xf7,0x33,0x1b,0x27,0x8a,0x36,0x19,0x7b,0x87,0x2e,0x5c,0x1c,0x5c,0x7e,0x0e,0xd3,0xf5,0x3e,0x99 +,0xef,0xd1,0xff,0x5c,0x7c,0x07,0xf6,0x79,0x92,0x69,0xd6,0x23,0xc3,0x87,0x89,0x3e,0xea,0x88,0xf9,0x01,0xe6,0x9f,0xee,0x93,0xe4,0x71,0x1c,0xd2,0x71,0xad,0xae,0x08 +,0x4d,0x99,0x1b,0x8a,0xeb,0x84,0x5d,0xc9,0x7f,0x86,0x6b,0xde,0x70,0xb3,0xc4,0x7a,0xd4,0x10,0x3b,0xfb,0x9f,0xf1,0x70,0x14,0x75,0x79,0xd5,0x26,0x0e,0xfe,0xc4,0x27 +,0x34,0x48,0x70,0xa4,0x88,0xd4,0xf7,0x48,0x90,0x23,0xfc,0x19,0x29,0xab,0xee,0x03,0xcc,0x00,0x07,0xae,0x09,0x82,0x6c,0x00,0x38,0xff,0xf1,0x50,0x80,0x2b,0xdf,0xfc +,0x21,0x0a,0xcf,0xef,0xff,0xee,0xff,0xff,0xb0,0x61,0x28,0x50,0x2a,0x12,0x0a,0x84,0x82,0xc1,0x50,0x98,0x5c,0x2a,0x14,0x0a,0x89,0x02,0xa1,0x20,0xa8,0x48,0xc2,0x12 +,0x10,0xb9,0xe2,0xd5,0xed,0x9a,0x7c,0xfb,0x77,0xd6,0x2b,0x3a,0xce,0x33,0x24,0xa2,0x54,0xe3,0x72,0xaf,0x2b,0xa9,0x5a,0xfa,0xe8,0x5b,0xcb,0x70,0xf5,0xbe,0xec,0xf1 +,0xb1,0xc3,0xd8,0x7c,0xff,0x73,0xe1,0xd6,0x4e,0xf5,0x9e,0xe5,0xed,0x97,0xf1,0xca,0xbc,0xb2,0x74,0x0e,0xfa,0xa2,0x9c,0xc6,0xe9,0xd7,0x97,0x03,0x92,0x5f,0x82,0x2c +,0x8d,0x2a,0x6b,0x69,0x09,0x3c,0x33,0x49,0xc3,0x9a,0x03,0x3e,0x07,0x1d,0x08,0xb5,0xd9,0x86,0x91,0xbc,0xe4,0xd9,0x03,0x3c,0xb2,0x65,0x55,0x2d,0x96,0x5c,0x95,0x8c +,0x7b,0x93,0x1d,0xe4,0x85,0xe7,0x72,0xbe,0x04,0x84,0xcf,0x05,0xae,0x45,0x3a,0x60,0x09,0x2f,0x0d,0x20,0xd6,0x82,0xec,0xe2,0x61,0x59,0x81,0x44,0x42,0x11,0x00,0x12 +,0x22,0x02,0xa4,0x82,0x83,0x50,0x90,0x58,0x4a,0x12,0x0a,0x04,0xc2,0x82,0x50,0x98,0x94,0x28,0x25,0x13,0x05,0x46,0x81,0x50,0x88,0x54,0x26,0x51,0x09,0x84,0x46,0x61 +,0x11,0x3b,0xe2,0xb3,0xf7,0xfe,0x9f,0xed,0xf9,0x9c,0xba,0xaa,0x9b,0xc6,0x6a,0xaa,0xeb,0x5c,0xeb,0xdb,0x78,0x54,0x6b,0x26,0xb8,0x74,0x38,0xf2,0x9d,0x09,0xb9,0x38 +,0x64,0x1f,0xbf,0x7a,0x3a,0xf7,0x7a,0xaf,0xdf,0xf3,0xdd,0xcd,0x4b,0xba,0x5f,0xc2,0xd7,0xe0,0x3e,0xbd,0xdc,0xe7,0x1c,0x58,0x7d,0xcb,0xa4,0xec,0xd8,0x3c,0x5f,0xc5 +,0xc1,0xf1,0x89,0x9c,0xf1,0x31,0xc6,0xf3,0x3b,0x42,0xc7,0xcb,0x89,0x0b,0xe5,0xc9,0xd8,0xb2,0x78,0x1e,0x40,0x38,0x7a,0x5d,0x11,0x19,0xeb,0x3a,0x29,0x8e,0x7d,0x93 +,0xc8,0x4a,0xa5,0x3b,0xc2,0xc7,0x05,0x80,0x07,0x96,0x03,0xc4,0x3f,0xf7,0xea,0x69,0x68,0xca,0xc7,0xda,0x42,0x1e,0x01,0x7b,0xc4,0x25,0xdd,0xde,0xe9,0x66,0x43,0x24 +,0x5e,0xb9,0x58,0x06,0xcf,0x6d,0x3d,0x98,0x21,0x52,0x13,0x11,0xb5,0xe2,0x09,0xc4,0x58,0x0e,0xe0,0x04,0x51,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2b,0x5f,0xfc,0x21,0x0a +,0xcf,0xee,0xff,0xed,0xfe,0xea,0xb0,0x62,0x18,0x48,0x2a,0x12,0x0b,0x05,0x42,0x41,0x70,0x90,0x98,0x2a,0x16,0x09,0x05,0x82,0xa1,0x21,0xa0,0x48,0x42,0x12,0x10,0x94 +,0xc2,0x28,0x78,0xe3,0x99,0xed,0x93,0x6d,0x73,0xad,0xae,0xa5,0xcc,0x94,0x44,0xa9,0x5c,0x54,0xb5,0x63,0x8f,0x6e,0x3f,0x02,0xdd,0x52,0xee,0x3e,0x3b,0xdf,0xf8,0x32 +,0xbb,0xfb,0x8f,0x97,0xd8,0x67,0x7a,0xeb,0xc3,0xeb,0x83,0x47,0xd3,0xb0,0x90,0x7d,0xdc,0x86,0xd9,0x04,0xe7,0x64,0x22,0x3c,0x04,0xc5,0xc2,0x4b,0x34,0x3f,0x5c,0x08 +,0xb9,0x32,0x83,0xd0,0xe2,0x3a,0x63,0x27,0x51,0x1d,0xf9,0x92,0xc5,0x31,0x74,0x2a,0xc9,0x76,0x7a,0x93,0x88,0xbc,0xd3,0xb9,0xc5,0x5e,0x6a,0x74,0x2e,0x4a,0x5d,0x69 +,0x42,0x6c,0xcc,0x72,0x1a,0x05,0x51,0x1d,0x7b,0x81,0x57,0x81,0x67,0xaf,0xe1,0x02,0xc0,0x82,0xc1,0x00,0x89,0xd4,0x09,0x17,0x18,0x44,0x01,0x10,0xb0,0x2d,0x20,0x29 +,0xd4,0x2c,0x12,0x0a,0x04,0x84,0xe2,0x21,0x20,0x54,0x2c,0x14,0x11,0x85,0x0a,0xa1,0x60,0xa8,0x4c,0x2a,0x13,0x22,0x84,0x42,0x68,0x11,0xbb,0x7e,0x3f,0x6f,0xd7,0xf8 +,0xfd,0x7e,0x7c,0xfa,0x9e,0xde,0xab,0xe3,0xc5,0x51,0xaa,0x2b,0x53,0x2f,0x5c,0xdb,0x35,0xbf,0x6a,0x5d,0xf9,0x0e,0xd3,0xd9,0xeb,0xd5,0xff,0x7c,0x9e,0x3f,0x9d,0xae +,0x5e,0x93,0x9c,0x4e,0x1f,0x9f,0x1b,0x2f,0x4f,0x18,0x9e,0xd9,0x9f,0xb1,0x77,0x57,0xa7,0xff,0x55,0x45,0xfe,0x77,0x50,0xf4,0x6f,0x7e,0x7e,0xe6,0x78,0x08,0xe1,0x4e +,0x3c,0xcc,0xe8,0x74,0xf0,0x41,0x5f,0x5a,0xa9,0xc7,0x9b,0xcc,0x3f,0xed,0xd5,0xa6,0xae,0x8e,0xfc,0x4d,0xfa,0x3b,0xaf,0x6a,0xf5,0xcb,0x7c,0xd0,0xfd,0x94,0xfd,0x79 +,0xe8,0x6b,0x80,0xf5,0xfd,0xf8,0x00,0xfb,0xc3,0xb6,0x81,0xb6,0xfc,0xd0,0x35,0x7b,0xfe,0x28,0x78,0x2f,0x7e,0xbc,0xfd,0x6c,0xf5,0x0f,0x0c,0x1e,0x8f,0xd6,0xbf,0xbd +,0x8c,0xdc,0x55,0x22,0xf1,0xc1,0x3f,0x70,0x0f,0x70,0x24,0x20,0x2a,0x05,0x49,0x80,0xe0,0xff,0xf1,0x50,0x80,0x2c,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xfe,0x7e,0xfe +,0xb5,0x61,0x20,0x8c,0x28,0x12,0x0a,0x04,0x82,0xa1,0x40,0xb0,0x50,0x4a,0x14,0x0a,0x84,0x92,0x22,0x20,0x89,0x4c,0x22,0x86,0x5e,0x69,0xaa,0xeb,0xed,0xf1,0xe3,0x8a +,0xdf,0x9d,0x92,0xa5,0x48,0x95,0x56,0xbd,0x6f,0xae,0x51,0xc5,0x79,0xf6,0x17,0x7a,0x36,0x65,0xfa,0xf7,0xc5,0xff,0x49,0xc3,0xff,0xf7,0xce,0x6f,0x6a,0xff,0x98,0x82 +,0x5e,0x6a,0x3a,0xf3,0xc3,0xa5,0xf4,0xa6,0x3b,0xc3,0x0c,0xb9,0xf5,0x6c,0x46,0xbc,0x24,0x2c,0xf5,0x78,0x41,0x8c,0x77,0xf5,0xc0,0x3a,0xb0,0x95,0x26,0x83,0x49,0xcd +,0x74,0x4b,0x48,0x57,0x16,0x6d,0x6a,0x5a,0x14,0xad,0x78,0x69,0x84,0xca,0xf8,0x8e,0xef,0x24,0x4a,0x08,0x4f,0x11,0xae,0xc5,0x2f,0x1d,0x5b,0x05,0x6b,0x47,0x3e,0xb1 +,0x00,0xb9,0xf6,0xd0,0xf0,0x00,0x48,0x90,0xb4,0x61,0x42,0x23,0x58,0x25,0x06,0x60,0x39,0x80,0x9c,0x2a,0x17,0x01,0x50,0x14,0xc4,0x24,0x0a,0x85,0x06,0xa1,0x20,0xa0 +,0x54,0x28,0x55,0x12,0x04,0xc2,0x81,0x50,0x88,0x54,0x42,0x15,0x0b,0x05,0x44,0x61,0x51,0xb8,0x4c,0x22,0x13,0x08,0x88,0xc2,0x22,0x3b,0x9b,0x95,0xe7,0x9f,0xc7,0xe8 +,0x38,0x8c,0xc5,0x3e,0x3c,0x67,0xb7,0x8a,0xd5,0x95,0x72,0x6f,0xab,0xf5,0xf1,0x5d,0x07,0xaa,0xd6,0x1e,0x97,0x36,0xe3,0xfa,0x4b,0xd4,0xff,0xf6,0xdf,0x15,0x5f,0x4f +,0xae,0xfc,0x4e,0x43,0xe8,0xed,0xde,0x95,0x05,0x6e,0x23,0xb3,0x9f,0x07,0x2e,0x2f,0x0b,0x69,0xb8,0xff,0xdf,0xf0,0x7a,0xfe,0x49,0xfe,0xae,0xbd,0x3e,0x1c,0x09,0x8d +,0xdd,0xb8,0xf0,0x1c,0x78,0x9c,0xb9,0x8e,0x16,0xe5,0x6b,0xcd,0x7a,0x51,0xe8,0xf9,0x5a,0x78,0x53,0x83,0xa0,0xd7,0x40,0x8c,0x1b,0xed,0x04,0x30,0x47,0x23,0x80,0xbf +,0x0e,0xc1,0xf7,0xb9,0x00,0x87,0x2a,0x1f,0xfa,0x3d,0x72,0x44,0x40,0x09,0x7b,0x49,0x45,0x47,0x17,0x18,0x01,0xc4,0x92,0xab,0xc8,0x4a,0x83,0xc2,0x84,0x80,0x0e,0xf9 +,0x20,0x11,0xb2,0x11,0x99,0xdd,0x2c,0x24,0x07,0xea,0x0c,0x6a,0x7b,0x80,0x50,0x14,0x9c,0x40,0xe0,0xff,0xf1,0x50,0x80,0x27,0xdf,0xfc,0x21,0x0a,0xcf,0xce,0xff,0xff +,0xff,0xef,0xb7,0x62,0x18,0x48,0x68,0x36,0x0a,0x09,0x42,0xc1,0x50,0x91,0x44,0x44,0x11,0x91,0x72,0xb4,0xac,0xe3,0x13,0x29,0x22,0xe9,0x26,0x4e,0x36,0x91,0x77,0x4b +,0xc5,0xcf,0x3a,0x16,0xfb,0xb9,0x6a,0xfb,0x41,0xe8,0xfe,0x1e,0x9e,0x3a,0x78,0x87,0x8f,0xb6,0x62,0x6c,0x3e,0xd5,0x6e,0x50,0x6d,0xff,0x8e,0x9b,0xe7,0x02,0x33,0xf3 +,0x39,0x8d,0xc1,0x4e,0x7d,0x1a,0xa0,0xe7,0xc6,0x6a,0x1e,0xa3,0x0f,0x71,0xeb,0xa6,0x2e,0x0b,0x14,0xa6,0x85,0xc8,0xe1,0x8a,0x77,0x11,0xf2,0xda,0xe8,0xe7,0x35,0xaf +,0x1b,0xf6,0x4b,0x2a,0x48,0x2c,0x98,0x21,0xf3,0x65,0x2a,0x90,0x91,0x40,0xaa,0xa4,0x56,0x5d,0x50,0x66,0x90,0x28,0x11,0x2e,0x2e,0x13,0xb0,0xb8,0x2e,0x56,0x60,0x28 +,0x08,0x00,0x9a,0x20,0xa0,0x4c,0x28,0x36,0x11,0x05,0x04,0xa1,0x30,0xa8,0xc8,0x28,0x25,0x0a,0x09,0x42,0x62,0x50,0xa0,0x4c,0x2a,0x13,0x18,0x84,0xc8,0x23,0x30,0x88 +,0x9f,0xf4,0xeb,0xd7,0x9f,0x0f,0xbd,0xf7,0xdc,0xba,0xd6,0xef,0x77,0x52,0xba,0xbc,0xdd,0x6a,0xae,0x61,0xc6,0x3a,0xef,0x56,0xe8,0x5b,0xa6,0xff,0x49,0xf1,0xdf,0xa2 +,0x7e,0x35,0xfa,0xfb,0xc7,0x4f,0x38,0xd6,0x43,0xaa,0xde,0x16,0xfd,0x75,0x6b,0xd8,0x74,0xcb,0xcf,0x29,0xf2,0xab,0xee,0x78,0x95,0xff,0xdb,0x8d,0x64,0xe5,0x39,0x77 +,0x3f,0x93,0xfe,0xf7,0x83,0xc2,0xf4,0xa0,0xe0,0xe6,0x40,0xf1,0x83,0x4b,0xdd,0x39,0xb9,0x27,0x8f,0x12,0x6b,0x68,0xcb,0x4f,0x62,0xed,0x1d,0x36,0xb3,0xd6,0x91,0xc8 +,0xbe,0x9e,0x34,0x3b,0x9d,0xd0,0x6a,0x7e,0xe4,0xe0,0x56,0x42,0x18,0xfe,0x02,0xfb,0x3a,0x14,0xa4,0xba,0x20,0x5e,0x76,0xf3,0xe4,0x5e,0xba,0x80,0x3d,0x07,0x0a,0x67 +,0xbb,0x21,0xed,0xe2,0x0a,0x85,0xaf,0x68,0xae,0xdc,0x0a,0xf7,0x2c,0x04,0x00,0x4c,0x07,0xff,0xf1,0x50,0x80,0x2a,0x9f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xdd,0xbf +,0xb7,0x60,0xb8,0x58,0x48,0x12,0x0a,0x84,0x82,0x82,0x51,0x10,0x50,0x2a,0x24,0x09,0x05,0x04,0x41,0x50,0x91,0x46,0x09,0xa6,0xfe,0xbb,0x99,0x9d,0x26,0x62,0xe5,0x5d +,0x71,0xdc,0xa9,0x09,0x13,0x2f,0x5b,0xd4,0x5f,0x5e,0x47,0xc8,0xab,0xbb,0xf2,0x47,0x34,0xe3,0xfb,0x9c,0xff,0x9c,0xe3,0x6e,0xf5,0x2a,0xf9,0xa9,0xa2,0xdf,0x1e,0xdf +,0xb5,0x89,0xf7,0xad,0xe9,0xb3,0x1f,0x31,0x70,0x48,0x57,0x1d,0x9e,0x14,0x36,0x17,0x35,0xa0,0x88,0x8f,0x19,0x65,0x0e,0x41,0x64,0x34,0x36,0xab,0x3b,0x89,0xb6,0x82 +,0x35,0x2e,0x70,0x09,0x8e,0x0e,0x18,0x0a,0x4a,0xb1,0xc6,0x91,0x15,0xd3,0xb2,0x08,0x97,0x29,0xca,0xe2,0xe4,0x84,0x5a,0xea,0x62,0xb4,0x51,0x81,0x62,0x16,0xac,0x01 +,0x2b,0x0a,0xa8,0x08,0x09,0xdc,0x09,0x84,0xa4,0xa0,0x26,0x02,0x60,0x27,0x94,0x28,0x16,0x12,0x84,0x82,0x83,0x50,0xb0,0x50,0x2a,0x17,0x0a,0x0d,0x42,0x81,0x50,0xa0 +,0x54,0x86,0x15,0x09,0x89,0x42,0x61,0x11,0x18,0x84,0x26,0x11,0x09,0x84,0x48,0xfe,0xbc,0x63,0xdb,0xe7,0xcd,0x7b,0x7d,0xaa,0xb5,0xbb,0xaa,0x93,0x35,0x50,0x89,0x52 +,0x52,0xf7,0x2e,0xeb,0xce,0x70,0x1d,0xdf,0x3e,0xd0,0x5b,0xd1,0xd3,0xd9,0xc4,0x3d,0x2e,0xe1,0xf0,0xe0,0xec,0x41,0x9f,0x67,0xd3,0xf5,0x8e,0xd5,0xbf,0xa3,0xf1,0x7c +,0x4f,0x1b,0x8a,0xc9,0xf7,0x75,0xca,0x3f,0xff,0x98,0xdb,0x9c,0xb9,0x3a,0x0f,0x2d,0xf3,0xe5,0xc9,0xc3,0xa8,0x7c,0x9c,0xa3,0x47,0x01,0xc5,0xc9,0x41,0xca,0x39,0x71 +,0x82,0x76,0x97,0xf9,0x5e,0xc2,0x8a,0xee,0x4c,0x8e,0x71,0xfa,0xad,0x0e,0xe4,0x62,0xf6,0xaf,0xfd,0x43,0x03,0x8f,0x22,0x79,0xa8,0x78,0xaa,0x1d,0xf6,0x8d,0x65,0xff +,0x91,0x5d,0x3c,0x03,0xa4,0x4f,0x74,0x78,0x9f,0x04,0x77,0xcf,0x4b,0x23,0x6a,0xfe,0x29,0x22,0xd5,0x1e,0xeb,0xdc,0x4a,0xc5,0x23,0x21,0x17,0x7a,0x0b,0xa0,0xa1,0x55 +,0x00,0x01,0x14,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2b,0xdf,0xfc,0x21,0x0a,0xcf,0xdf,0xbf,0xaf,0xef,0xdf,0xb5,0x60,0xa0,0x4c,0x48,0x12,0x0a,0x85,0x02,0xa1,0x40,0xb0 +,0x54,0x28,0x13,0x0a,0x85,0x82,0x81,0x22,0x28,0x88,0x62,0x13,0x09,0x04,0x42,0x41,0x13,0x18,0x44,0xa4,0x95,0xd6,0xfa,0xde,0xee,0xa4,0xc9,0x2a,0xae,0xae,0x60,0xd6 +,0x45,0x75,0x8e,0x2b,0xaa,0xe6,0xff,0x5f,0x23,0xef,0xcf,0xeb,0xdf,0xc5,0xfd,0x46,0x96,0xa5,0xf1,0xfc,0x8f,0x16,0xcb,0xb2,0x02,0x18,0x8f,0x65,0xcd,0x86,0x9f,0x07 +,0xeb,0xb2,0x38,0x1b,0x78,0x08,0x2f,0xbd,0xae,0x8e,0xbe,0x0a,0xf2,0x93,0x9f,0xe9,0x5f,0x42,0x10,0xc9,0x53,0x6a,0xf7,0x85,0xa9,0x8f,0x89,0xfa,0xdd,0x53,0x28,0x0c +,0x9b,0x39,0xe3,0xea,0xbd,0x4b,0x4b,0xd1,0xc6,0x24,0x00,0x9a,0x91,0x48,0x82,0x13,0x46,0x12,0x0b,0xc2,0xab,0x10,0xb4,0x53,0x3b,0x25,0x8b,0x85,0xf9,0x4c,0xbc,0xd9 +,0x05,0x77,0x8c,0x61,0x49,0x40,0x02,0x4b,0x87,0xb8,0x22,0xb8,0x00,0xbc,0xed,0x50,0x0b,0x81,0x10,0x28,0x88,0x2c,0x14,0x09,0x85,0x42,0x81,0x50,0xa0,0x4c,0x28,0x16 +,0x0a,0x09,0x42,0x41,0x41,0x28,0xd0,0x2a,0x14,0x0a,0x94,0xc2,0xa3,0x32,0x89,0x9f,0xa7,0x9f,0x5c,0x5f,0x3f,0x1c,0xce,0x55,0x72,0x4d,0xe7,0x5e,0x3a,0xe7,0x8a,0x93 +,0x26,0xbd,0x79,0x66,0xa4,0xe6,0x75,0x9f,0x7d,0x0a,0xd3,0xb7,0xf2,0x7f,0xa9,0x76,0xf6,0x0f,0x86,0xf7,0xfa,0x8f,0xf7,0xec,0x20,0x93,0x6c,0x0c,0xfb,0x01,0x8c,0x57 +,0x91,0x9e,0x9b,0xa2,0xbd,0x35,0x1c,0xfe,0xe7,0x2e,0x0e,0x48,0xf9,0x48,0xfb,0x9c,0xd7,0x7c,0x28,0xe0,0x0f,0x2f,0x6f,0x2a,0x81,0x67,0x99,0xe4,0x01,0xe6,0x79,0x8f +,0x13,0x90,0x1c,0xd6,0x3e,0xb1,0x31,0x71,0x0e,0x0e,0x2e,0x40,0x1f,0x6f,0xdd,0x3b,0xdc,0x5e,0x2c,0x28,0x00,0xb4,0xb1,0x71,0x76,0x99,0x87,0x27,0x2f,0x9b,0xcc,0x08 +,0x0a,0x8a,0x7d,0x6d,0x4a,0xfd,0xdd,0x4d,0x20,0xf7,0xc3,0xeb,0xc3,0xbd,0x2e,0xe0,0x77,0xe2,0x4d,0x49,0x48,0x94,0x23,0x68,0x2f,0x14,0xc0,0x53,0x92,0x6d,0xd4,0x00 +,0x50,0x80,0x0e,0xff,0xf1,0x50,0x80,0x2c,0x3f,0xfc,0x21,0x0a,0xcf,0x7f,0xdd,0xff,0xbd,0xdc,0xaf,0x40,0xb0,0x54,0x28,0x15,0x1a,0x09,0x82,0xa1,0x30,0xa8,0x50,0x4c +,0x12,0x12,0x85,0x02,0xa1,0x40,0x90,0x8c,0x24,0x21,0x11,0x04,0x42,0x41,0x30,0x90,0x45,0x00,0x17,0xab,0x93,0xf5,0xfd,0x3d,0xbb,0xeb,0xd5,0xf1,0xcb,0x71,0x79,0xa9 +,0x8d,0x64,0xa2,0x3c,0xf6,0xd5,0xfd,0xfe,0xc9,0xff,0xe6,0x38,0xc3,0x7d,0x9f,0x4f,0x81,0xd4,0x72,0x77,0x6d,0x1c,0x45,0xf7,0x7d,0xb8,0x25,0xf9,0x97,0x1e,0x85,0xcf +,0x5f,0xe2,0xa3,0xe4,0x26,0xbb,0x76,0x7e,0xbc,0xf4,0x1b,0xb7,0x44,0x89,0xbc,0x3d,0x6e,0x4f,0x2d,0x97,0xaa,0xc3,0x11,0xe0,0x6d,0x22,0x9a,0xe4,0x3b,0xc7,0x8d,0x20 +,0x4c,0x50,0x69,0xa9,0xbd,0x30,0x58,0x5c,0x5f,0x5a,0xce,0x91,0x2f,0xfb,0x66,0xfb,0x5c,0x86,0x2d,0xa0,0x89,0xc8,0xd1,0x28,0xce,0x5e,0x40,0x62,0x43,0x20,0x88,0xc7 +,0xba,0x64,0x18,0xa3,0x20,0xd6,0x9d,0x15,0xb2,0xec,0x2a,0x4c,0x22,0x91,0x9a,0x00,0x10,0x01,0x7a,0x0b,0xd0,0x88,0x2b,0x11,0x70,0x15,0x84,0x15,0x0b,0x09,0x02,0x41 +,0x41,0x10,0x50,0x2a,0x24,0x0a,0x85,0x04,0x61,0x40,0xa9,0x10,0x46,0x14,0x0a,0x89,0x02,0x62,0x10,0x98,0x44,0x66,0x15,0x09,0x84,0x48,0xcf,0x8f,0xcf,0xc6,0xbe,0x7c +,0xd6,0x4a,0xca,0x2c,0x9c,0x73,0x4d,0x54,0xac,0xf6,0xd7,0x8f,0x6f,0xcf,0xe3,0xd5,0xf0,0xcd,0x79,0xd0,0xca,0xf6,0x51,0xdf,0xef,0x93,0x74,0x8b,0xcb,0xed,0xbd,0x37 +,0xff,0xc8,0x2d,0xf9,0x22,0xdd,0x5e,0x7f,0x4b,0x41,0xc3,0xdc,0x89,0xff,0x0f,0x7f,0xe4,0xd7,0x7a,0x5f,0x8d,0xb9,0x21,0xdf,0xc6,0x5c,0x45,0x5f,0x8f,0x27,0x27,0x11 +,0xe6,0x4d,0x17,0xb5,0x7c,0xbb,0x35,0xf6,0x87,0x7b,0xff,0x52,0xdb,0xd3,0x62,0xbe,0xab,0x62,0xe7,0x81,0xf0,0x1c,0x94,0x13,0x23,0x82,0xde,0xae,0xf8,0xc1,0x4c,0xaa +,0x0f,0x58,0x04,0x3b,0x91,0x84,0x48,0xa6,0x0f,0x58,0xbe,0xac,0xb5,0x54,0x13,0x40,0xc6,0x11,0x53,0xbc,0xc3,0x00,0x07,0x98,0x00,0x0f,0x73,0xdd,0x13,0xb9,0x34,0x44 +,0x81,0x60,0x2c,0x07,0xff,0xf1,0x50,0x80,0x29,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xf7,0xff,0xfc,0xb4,0x60,0xb8,0x4c,0x2a,0x22,0x0a,0x85,0x02,0x42,0x50,0xa0,0xd4 +,0x2e,0x14,0x09,0x85,0x02,0x41,0x11,0x10,0x44,0xa4,0x11,0x59,0x84,0x44,0xc5,0xea,0xf3,0xaf,0x01,0xaa,0xa9,0x2f,0x7c,0x72,0x97,0xb8,0x6a,0xf3,0x8c,0xab,0xae,0x2e +,0xb5,0xff,0xbf,0x00,0xb9,0x3b,0xef,0xe0,0xf9,0x3b,0xcf,0x3c,0xb7,0x9c,0xdc,0x7c,0x8b,0x4f,0xc3,0x53,0xdc,0xc3,0xbc,0xbf,0x0c,0xaf,0xca,0x88,0xbf,0xc4,0x21,0x4f +,0x69,0x8f,0x6f,0xdb,0xeb,0xe6,0x46,0x5c,0xc4,0xf4,0xe3,0x49,0x72,0xa5,0x3d,0x5e,0x54,0x78,0x21,0x2c,0x54,0x96,0xfb,0x2f,0xc6,0x4a,0x6b,0x74,0xe7,0x3b,0xa3,0xa4 +,0xc4,0x1f,0x8c,0x4c,0x99,0x9d,0x18,0xcd,0x40,0x2e,0xac,0xa2,0x29,0x20,0x50,0xa8,0x46,0x81,0x10,0x40,0x2c,0x26,0x40,0x40,0x98,0x92,0x24,0x41,0xdc,0x00,0x88,0x0a +,0x01,0x48,0x41,0x41,0x18,0x54,0x28,0x15,0x0a,0x0d,0x42,0x81,0x50,0xa0,0x54,0x2c,0x13,0x0a,0x85,0x06,0xa1,0x41,0x28,0x88,0x26,0x15,0x09,0x94,0x46,0x61,0x12,0xbe +,0x65,0x4b,0xcb,0xa9,0x95,0x2b,0x5d,0xf5,0x99,0x75,0x15,0x6a,0xea,0xf3,0x2f,0x59,0x89,0x75,0x3e,0x33,0xa1,0x77,0xe8,0x3a,0x3f,0xeb,0xbb,0x9b,0xdb,0xe3,0xce,0x78 +,0x9f,0xf0,0x7e,0x8a,0x3b,0x2f,0x3d,0xc3,0x8c,0xff,0xac,0x8b,0xeb,0x35,0x84,0xe3,0x6f,0x83,0xcc,0xf1,0x9e,0xbc,0xf9,0xa7,0xd1,0xbf,0xc9,0xea,0x98,0x2e,0x9f,0x60 +,0x77,0xaf,0xb2,0x57,0x34,0x15,0x2e,0xf3,0xc2,0xe2,0xd3,0x68,0x07,0x1b,0x71,0xc6,0x47,0xc0,0xc4,0x71,0x24,0xf2,0xe3,0xcc,0x40,0xc7,0x75,0xdf,0xee,0x48,0x28,0xf6 +,0x81,0xfe,0xb8,0x19,0x9f,0xb3,0x1a,0x17,0x7b,0x9d,0xf1,0x0f,0x76,0x71,0x1d,0xf9,0x89,0xa5,0xaa,0xf0,0x02,0x1d,0xd6,0x62,0x8a,0x9a,0x0e,0x94,0xbc,0xda,0x45,0xc8 +,0xd0,0xf4,0x04,0xea,0xa5,0x51,0x5e,0x02,0x22,0x40,0x2c,0x04,0x40,0xe0,0xff,0xf1,0x50,0x80,0x2a,0x3f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xaf,0x7f,0xfd,0xb3,0x30,0xb8 +,0x58,0x28,0x25,0x0a,0x08,0xc2,0x81,0x70,0x90,0x4c,0x24,0x24,0x09,0x05,0x04,0x42,0x50,0x91,0x06,0x2d,0xda,0xfa,0x6e,0xf2,0x15,0x52,0x65,0xee,0xf5,0xdd,0xc1,0x14 +,0xeb,0x99,0x6d,0x54,0x9f,0xe3,0xa1,0xf9,0xc7,0x79,0xb4,0xf8,0xde,0xed,0xc9,0xe4,0x75,0x5f,0xe1,0xdb,0x7c,0x88,0x4b,0x1b,0xcf,0xbd,0x0d,0xaf,0x2f,0x27,0xe1,0x2a +,0xa3,0xc3,0xbd,0x97,0x4c,0xb4,0x18,0xed,0xe5,0x83,0xfd,0xbc,0xac,0xab,0x72,0x5f,0x63,0x22,0x5b,0x9e,0xf4,0x81,0xa3,0x63,0xce,0x41,0x5f,0x6b,0x12,0x7c,0xfe,0xe3 +,0x5c,0xa3,0x83,0x01,0xae,0xf2,0xe7,0xc2,0x56,0x8b,0xbb,0x40,0xfd,0xf0,0xdf,0xa8,0xe8,0xa9,0x72,0xb2,0xce,0x32,0xde,0xc7,0xec,0x66,0x15,0xa4,0x2f,0x30,0x8c,0xa9 +,0x20,0x05,0xd6,0x2d,0xa0,0x82,0x28,0x96,0x5d,0xfb,0x2c,0x04,0x65,0x70,0x09,0x88,0x81,0x48,0x41,0x40,0x98,0x90,0x24,0x16,0x09,0x0d,0x42,0x81,0x30,0xb8,0x50,0x2a +,0x11,0x0a,0x05,0x42,0x81,0x60,0xa8,0x58,0x28,0x13,0x08,0x85,0x46,0x63,0x11,0x18,0x84,0x86,0x11,0x13,0xf3,0xed,0xef,0xc7,0x1e,0xb8,0xa4,0xe7,0x54,0x7d,0x7d,0xa1 +,0x7b,0xbe,0x38,0xf1,0x53,0xcf,0x33,0x13,0xae,0xed,0xed,0xbf,0x8e,0x85,0x5c,0xaf,0xfc,0x7f,0xa2,0xe0,0xbd,0x07,0xa7,0x76,0x4d,0x1f,0x90,0xda,0x78,0x67,0xfd,0x6a +,0x3c,0xcd,0xa2,0xcf,0x39,0xe6,0x66,0xfa,0xfa,0x5b,0xb1,0x33,0xf6,0xcb,0xa1,0x0e,0xac,0x6c,0x83,0xcb,0x44,0x57,0xcd,0x76,0x11,0x71,0x47,0xac,0x51,0x8b,0x53,0x63 +,0xc5,0x4e,0xec,0x26,0x61,0x85,0xdc,0xd1,0x39,0xb4,0x83,0xef,0xe0,0xa1,0xb7,0xc3,0x8a,0x28,0xe5,0xa8,0x8a,0x20,0xba,0xad,0xee,0x07,0x7a,0x9b,0x27,0xaf,0x42,0x21 +,0x0f,0x75,0x67,0x2c,0x36,0x0a,0xa3,0xa2,0x14,0x07,0x5a,0xfd,0x91,0xde,0x03,0x82,0x7b,0xf2,0xd8,0xac,0x48,0x81,0xb5,0x35,0x80,0x3d,0xd0,0x24,0xa0,0x28,0x07,0xff +,0xf1,0x50,0x80,0x2b,0xdf,0xfc,0x21,0x0a,0xcf,0xdf,0xaf,0xf7,0xfe,0xff,0xb5,0x50,0xb0,0x8c,0x28,0x12,0x0a,0x85,0x02,0xa1,0x40,0xb8,0x50,0x2a,0x13,0x0a,0x10,0x82 +,0x81,0x24,0x88,0x88,0x22,0x33,0x08,0x9d,0x9a,0x3c,0xe5,0xee,0xf7,0x7c,0xfb,0x78,0x99,0xac,0xd2,0xa5,0x5b,0x24,0x2a,0xa5,0xfb,0x78,0xb4,0xd7,0x9d,0x07,0xbc,0xfc +,0xb4,0xf1,0xfd,0x0e,0x8c,0x99,0xc3,0xb1,0x70,0xd1,0x1e,0x86,0xce,0xca,0xd5,0x7d,0x79,0xf6,0xb3,0x07,0xd3,0xa9,0xf4,0xfe,0xaf,0xa7,0xc3,0xcd,0x6e,0x8e,0xe6,0xf5 +,0xd1,0xcc,0x8b,0x0f,0x32,0xc5,0xdb,0x97,0x73,0xd0,0x8f,0x23,0xc4,0x9e,0x6e,0x08,0x40,0x33,0xec,0x5b,0xa6,0x60,0x23,0x15,0x11,0x02,0x75,0xb5,0x6b,0x23,0xa1,0xf4 +,0x48,0xa9,0xd2,0x46,0x99,0x2f,0x44,0x10,0xd9,0x4e,0xd3,0x79,0x10,0x33,0x18,0xbe,0x59,0xf7,0xcc,0x5f,0x3a,0x2e,0x9e,0x59,0xaa,0x41,0xe4,0x80,0x14,0xef,0x37,0x89 +,0xdc,0x45,0xd0,0x22,0xad,0x04,0xea,0x26,0x23,0x94,0x00,0x23,0x10,0x14,0x44,0x14,0x0b,0x05,0x42,0xc2,0x50,0xa0,0x48,0x28,0x12,0x0a,0x05,0x42,0x82,0x60,0xa0,0x94 +,0x28,0x15,0x09,0x85,0x04,0xa4,0x30,0xa8,0x84,0x2a,0x13,0x08,0x85,0x42,0x21,0x30,0x88,0x8c,0x22,0x27,0xe5,0xbf,0x6e,0x67,0x9d,0xf3,0x75,0x93,0x24,0xa3,0x54,0x5d +,0x71,0xb7,0x1a,0x8e,0xef,0x3d,0xb3,0xbf,0x6d,0xf5,0x07,0x6f,0xe9,0xb9,0x2f,0xb8,0x9a,0x34,0x9b,0xbf,0x6d,0xff,0x6d,0xe6,0xfc,0xea,0xda,0xd1,0xc7,0xfa,0xbb,0x6e +,0x9f,0x92,0x25,0x8d,0x26,0xdb,0x47,0xb7,0xec,0xf5,0x6f,0xfb,0x5a,0x87,0x3e,0xdf,0xf1,0xbd,0xd3,0x90,0xee,0xf5,0x45,0x7f,0xcc,0xee,0xb6,0x0b,0x7a,0xbc,0x65,0xf1 +,0x7f,0x07,0xf3,0x45,0xad,0xcb,0xe1,0x62,0x88,0xe0,0xaf,0x88,0x94,0xbc,0xc3,0x90,0xe3,0x00,0x1c,0x9a,0x3d,0xf3,0xf0,0xce,0xf8,0xe2,0x78,0x81,0xc0,0x00,0x03,0xcc +,0x56,0x60,0x03,0xc0,0x00,0xf5,0xe9,0x1b,0x17,0x9c,0x81,0xe2,0x00,0x2c,0xb0,0x65,0x1d,0xe0,0x15,0x24,0x9a,0xe0,0x11,0xf7,0x00,0x09,0x08,0x81,0xc0,0xff,0xf1,0x50 +,0x80,0x2d,0xdf,0xfc,0x21,0x0a,0xcf,0xef,0xfd,0xff,0x7e,0xff,0xb3,0x70,0xb0,0x90,0x2c,0x22,0x0a,0x85,0x04,0xa1,0x41,0x10,0x54,0x28,0x16,0x0b,0x85,0x02,0x43,0x30 +,0x90,0x90,0x24,0x21,0x09,0x04,0x42,0x61,0x11,0x90,0x44,0xed,0xdd,0x4d,0x57,0xc7,0xbd,0xe4,0xab,0xac,0xbd,0x6e,0x4c,0xba,0x91,0x96,0xaf,0x3b,0xe5,0x77,0x0e,0x3c +,0xf0,0x1d,0x99,0x7b,0x17,0x8f,0xfa,0x4f,0xb3,0x52,0xfd,0xdf,0x2e,0x8f,0xd8,0x76,0x1c,0x6e,0xf9,0x83,0xbb,0x8a,0x61,0xeb,0x38,0x6b,0xd8,0xe5,0x0d,0x83,0xd8,0xa0 +,0x55,0xb7,0xca,0xc5,0x58,0xc8,0xa7,0x7e,0x75,0x2b,0xb3,0x4a,0xbe,0xfa,0xb4,0x79,0xb0,0xa5,0xc5,0x27,0x6d,0x16,0x2f,0xaa,0xc5,0x25,0x90,0x9c,0xd7,0x9d,0x82,0xb2 +,0x43,0xec,0x47,0x68,0x18,0xdd,0x6e,0xbc,0xe2,0x81,0x5d,0x7e,0x38,0x0e,0x30,0xa5,0x9f,0xb9,0x10,0x0f,0xe8,0x46,0xab,0x3a,0x51,0x76,0xca,0x98,0x1d,0x94,0x7a,0xa5 +,0xd7,0x7b,0xeb,0xdd,0x98,0xa4,0xc4,0x8b,0x11,0x8c,0xd7,0xa8,0x42,0x72,0x6c,0x39,0x40,0x02,0x00,0x5c,0x0a,0x22,0x0b,0x05,0x02,0x61,0x50,0xa0,0x58,0x44,0x15,0x0a +,0x08,0xc2,0xa1,0x41,0xa8,0x58,0x28,0x25,0x0a,0x05,0x42,0x81,0x21,0x28,0x4c,0x2a,0x11,0x09,0x89,0x42,0x41,0x30,0x88,0x4c,0x22,0x57,0xed,0xd7,0x8f,0xc7,0x3e,0x3f +,0x5f,0x55,0x59,0x72,0xb2,0x26,0x49,0x25,0x28,0xeb,0xad,0xb7,0xdf,0xdf,0x59,0xe2,0xfe,0x2b,0xa1,0xc2,0x38,0x7d,0x53,0xf5,0x6e,0xbe,0xe6,0x3c,0xff,0xaa,0xb3,0x75 +,0xbd,0x57,0x79,0xc7,0x03,0x6f,0x9b,0xa7,0x85,0x72,0x0e,0x81,0xdd,0x6a,0xae,0xb8,0x94,0xf3,0x7c,0xc6,0xe2,0x60,0x35,0x84,0xc3,0xe1,0x7e,0x6f,0xb7,0x14,0x8e,0x17 +,0x47,0xca,0xa2,0xf8,0x97,0xaa,0xdc,0x9c,0x1c,0x41,0xdb,0x73,0xbf,0xd2,0x9d,0xcb,0x93,0xf4,0x1f,0x1d,0x71,0xd4,0x95,0xe1,0x3c,0x53,0xc4,0x82,0x07,0x31,0xdb,0xdf +,0xd7,0x1e,0x63,0x80,0x14,0x02,0xd5,0x3b,0xdd,0xd0,0x77,0xcf,0xf1,0xdd,0x05,0x4e,0x2e,0xc3,0xde,0x92,0xf8,0x50,0xb0,0x82,0xaa,0xbf,0x58,0x03,0x41,0x20,0x03,0xbf +,0x1b,0x98,0x6e,0x50,0xb0,0xa1,0x50,0x2a,0x02,0x60,0x70,0xff,0xf1,0x50,0x80,0x29,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xde,0xff,0xdf,0xae,0x63,0x20,0x54,0x28,0x25 +,0x0a,0x10,0xc2,0x41,0x41,0x11,0x10,0x26,0x12,0x08,0x8c,0xc2,0x21,0x31,0x08,0x8c,0x42,0x67,0xa9,0x5a,0xe7,0xe2,0xb7,0x32,0xe4,0x6f,0x5b,0x25,0x48,0xc9,0xc5,0x71 +,0x5a,0xce,0xe7,0x17,0xd7,0xbc,0x7e,0x3c,0x83,0xee,0xcb,0xbb,0xb0,0xdb,0xf5,0x47,0xf1,0xf4,0x7d,0x51,0xc1,0xac,0xb6,0xaf,0x12,0xa6,0xe0,0xc4,0x7a,0x56,0x68,0x03 +,0xde,0x77,0xff,0x09,0xd6,0x7a,0x31,0xb7,0xd0,0x3b,0x3b,0x93,0x26,0xbe,0xe6,0x67,0x7a,0x8e,0x58,0x8d,0xb9,0x22,0x21,0xdd,0x66,0xaa,0xb5,0xa4,0x7e,0x29,0x3f,0x92 +,0xe7,0x94,0x61,0xbf,0x85,0x6c,0xb5,0xb5,0x75,0x8a,0xce,0xc4,0xd1,0x87,0xad,0xdd,0x04,0x88,0x12,0x4c,0x7c,0x31,0x75,0x84,0x5d,0xd8,0x4c,0x70,0x62,0x23,0x3e,0x30 +,0x21,0xee,0x14,0x00,0x77,0x44,0x01,0xcc,0x04,0xc6,0x01,0x45,0x94,0x88,0x2c,0x10,0x01,0x58,0x84,0x51,0x10,0x90,0x4a,0x24,0x2a,0x85,0x06,0xc1,0x40,0xa8,0x8c,0x2a +,0x53,0x12,0x84,0xc2,0xa1,0x13,0xb1,0x9d,0x77,0xfa,0xfd,0xb8,0x2f,0xc4,0x95,0x52,0x8c,0xe0,0x9b,0xea,0x67,0x09,0x95,0xe7,0xdb,0xfa,0xea,0x79,0xd7,0x91,0xe4,0xe9 +,0xef,0x98,0x7c,0x0b,0xc9,0xf2,0x45,0xe9,0xb6,0x76,0x3e,0x6e,0x3c,0x87,0x9f,0x97,0xba,0xf3,0xfb,0xa5,0xb9,0x2f,0x43,0xe9,0xa9,0xef,0xb6,0x9f,0x2b,0xef,0x1d,0xe8 +,0xf8,0x7e,0x0f,0x31,0xac,0x5b,0xb1,0x36,0x11,0x3d,0x5c,0x95,0xc3,0x63,0xb3,0xd5,0x7f,0x9b,0x9a,0x29,0xc8,0xe3,0xb7,0x29,0xe4,0x09,0xfa,0xff,0xfa,0xc9,0xec,0x5d +,0x4d,0xcf,0x78,0x38,0x23,0x8c,0xf2,0x6d,0x00,0x03,0xef,0xe5,0x12,0x1c,0x39,0x83,0x98,0xe1,0x41,0xc0,0x0e,0x27,0xa8,0x3e,0x10,0xf5,0xde,0xb0,0xee,0x80,0xf9,0xf8 +,0x00,0x91,0xc1,0xee,0x4c,0x00,0x79,0x00,0x6c,0x03,0x59,0x72,0x16,0x17,0x4a,0x11,0x23,0x59,0xdc,0x2e,0x05,0x40,0x80,0x0e,0xff,0xf1,0x50,0x80,0x28,0xff,0xfc,0x21 +,0x0a,0xcf,0xed,0xbf,0x4f,0xff,0xbf,0xb2,0x30,0xb0,0x50,0x2c,0x25,0x09,0x09,0x02,0x41,0x51,0x10,0x54,0x24,0x13,0x09,0x09,0x04,0x42,0x50,0x91,0x05,0x06,0x21,0x33 +,0xbd,0x46,0xfa,0xbe,0x7d,0xbd,0xfa,0x93,0x75,0x55,0x7b,0xe3,0x7a,0x99,0x24,0xa8,0xeb,0x3b,0xbe,0xa6,0x2e,0xfc,0xfb,0x0f,0xcc,0xf9,0xe6,0xe5,0xd1,0xb7,0x8d,0xbf +,0x63,0x36,0xad,0x8f,0x37,0xdc,0xac,0xa5,0xdd,0x74,0xd1,0xf2,0xb6,0x66,0x7b,0x59,0xf9,0xe1,0x97,0x67,0x2f,0x42,0x5a,0x00,0x34,0x3c,0x8b,0x11,0x4b,0x7c,0xd7,0xdf +,0xad,0xbb,0x94,0x02,0xa2,0xc5,0xd0,0x3c,0x5c,0x67,0x72,0xd4,0x65,0x25,0x56,0x43,0x61,0xc5,0x27,0x4c,0x31,0xaa,0x0e,0x18,0xae,0x22,0xf3,0x54,0x47,0x42,0x75,0xb1 +,0x21,0x6b,0x27,0x78,0x10,0x41,0x3a,0x23,0x98,0x84,0x45,0x6e,0x82,0x70,0xf7,0x01,0xe1,0x81,0x30,0x5a,0xf3,0x40,0x01,0x58,0x88,0x61,0x48,0x2e,0x02,0x00,0x55,0x28 +,0x58,0x68,0x16,0x12,0x90,0x82,0xc1,0x41,0x28,0x4c,0x48,0x16,0x0a,0x0c,0x84,0xa1,0x32,0x10,0x4c,0xa2,0x43,0x08,0x89,0xcf,0x1e,0x35,0xb9,0xed,0xe2,0xb5,0x36,0xd6 +,0x15,0x29,0x0b,0xba,0x95,0x5c,0x55,0xa6,0xaf,0xdf,0x5f,0x5c,0xd8,0x75,0x8e,0x98,0xe7,0xcd,0x3b,0x3f,0xa2,0x1f,0xdd,0xe5,0xd2,0x76,0xfb,0xa2,0x0d,0xc6,0x69,0xb9 +,0x00,0xb6,0x7c,0xf5,0xef,0x35,0x57,0xca,0xd9,0xec,0xbf,0x88,0x34,0x97,0x29,0x0d,0xf3,0xb2,0x55,0x48,0xa7,0x77,0xd6,0x68,0x58,0xf3,0xe8,0x0d,0xf6,0xef,0xc7,0x3d +,0x86,0x86,0xff,0xf3,0x49,0x31,0x07,0x18,0xa3,0x8a,0x1f,0x88,0x20,0xb0,0xf7,0x7f,0x7c,0x4f,0xb9,0xb5,0x8d,0x5d,0x85,0x92,0x9f,0xcc,0x2a,0x69,0x4e,0x2b,0xc4,0xf2 +,0x16,0xbc,0xfd,0xcd,0xdf,0x8a,0x41,0x07,0x78,0x90,0x3d,0x64,0xe0,0xef,0x9d,0xee,0xe0,0x00,0xee,0x90,0x06,0xf3,0x28,0x2c,0x4c,0x77,0xc0,0x26,0x08,0x00,0xe0,0xff +,0xf1,0x50,0x80,0x2a,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0xd7,0xff,0xbf,0xfe,0xb5,0x50,0xb0,0x90,0x2c,0x25,0x12,0x05,0x46,0x41,0x40,0x90,0x50,0x24,0x14,0x09,0x05,0x02 +,0x41,0x50,0x90,0x44,0x44,0x11,0x51,0x84,0x4c,0x5d,0x53,0xe3,0x37,0xae,0xf5,0x45,0x4b,0xa9,0x79,0x52,0x4a,0x82,0x6b,0xba,0xe3,0xf1,0xf6,0xe2,0x4f,0xc6,0xc3,0xd9 +,0xcb,0x87,0x6a,0x7f,0xab,0xd5,0x7f,0xb4,0x5d,0x2e,0xed,0xdf,0x83,0xe9,0x33,0x27,0x8f,0x8e,0x4f,0xa7,0xb5,0xa6,0xde,0xef,0x96,0x64,0xae,0xf6,0x9d,0x8d,0xc6,0x75 +,0xb1,0xbd,0x39,0x58,0xce,0xa2,0xd3,0x13,0x83,0xb9,0x0d,0xb6,0xb8,0x17,0xa5,0x2b,0x6b,0xb0,0xc2,0xfa,0xe5,0x9e,0xa2,0x92,0x9e,0x5a,0xa1,0x55,0xd1,0xef,0xca,0x84 +,0x22,0x82,0x98,0xbb,0x8e,0x51,0x51,0x0f,0x5c,0xc9,0xa9,0x11,0x12,0xaa,0xa3,0xbd,0x86,0xd1,0x85,0x3a,0x8b,0x50,0xb8,0x3b,0xa0,0x2a,0xb8,0x88,0xb8,0x49,0x20,0x0a +,0x72,0x04,0x44,0xe8,0x02,0xa5,0x42,0x81,0x50,0x98,0x58,0x2a,0x17,0x0b,0x05,0x04,0x41,0x50,0x90,0x50,0x8c,0x14,0x29,0x05,0x42,0x41,0x31,0x28,0x4c,0x82,0x15,0x09 +,0x88,0x42,0x61,0x12,0x33,0x75,0x38,0xf1,0xfa,0xfe,0x7d,0xbb,0xf8,0xf7,0xab,0xaa,0x5d,0x17,0x57,0x57,0x55,0xe6,0xad,0xd6,0x67,0x7f,0xbf,0x3e,0x3e,0x9a,0x0e,0x1c +,0xd7,0xbd,0xfc,0x14,0xdf,0xe9,0x3b,0x3d,0x19,0xe8,0x6e,0xeb,0xeb,0xe3,0x2e,0x0e,0xde,0xdf,0x27,0x8f,0xf9,0x0c,0x71,0xfd,0xf3,0xf2,0x89,0x45,0x92,0x35,0x95,0xdf +,0x08,0x32,0x0c,0xf7,0xe1,0x03,0x7d,0x50,0x7f,0xbc,0x33,0x22,0x42,0x7d,0x76,0x97,0x32,0xea,0xf2,0xee,0x4a,0x17,0x74,0x9d,0x09,0x5c,0x30,0x70,0x6a,0xd7,0xb8,0x8c +,0x68,0xf5,0x5f,0x71,0x0b,0x1d,0x45,0xc7,0xad,0xc4,0x97,0x7c,0x1f,0xe8,0xd4,0xff,0xd4,0xef,0xae,0x1d,0xd3,0xba,0xef,0x77,0x47,0x72,0xcb,0x16,0x00,0x0f,0x30,0x1c +,0x61,0xfc,0x91,0x38,0x12,0x7b,0xa0,0x26,0x1f,0xfa,0x82,0x61,0x48,0x85,0xc1,0x00,0xb5,0x80,0x70,0xff,0xf1,0x50,0x80,0x2b,0x3f,0xfc,0x21,0x0a,0xcf,0xef,0x3a,0xdf +,0xfd,0xe8,0xb4,0x40,0xb0,0x90,0x2c,0x15,0x11,0x04,0xc2,0x41,0x50,0xa0,0x48,0x6c,0x13,0x0a,0x05,0x44,0x82,0x21,0x08,0x48,0x22,0x53,0x08,0x90,0xc2,0x26,0x54,0x99 +,0x3c,0xd7,0x7e,0x79,0xbb,0xde,0xb9,0xeb,0x95,0xdf,0x32,0x21,0x2e,0xb8,0xde,0x67,0xe2,0xb9,0xf8,0xe7,0xeb,0xae,0x87,0x03,0xca,0x4d,0x6f,0xb9,0xf1,0xa7,0xfa,0x1d +,0xde,0x3f,0xa7,0xa7,0xee,0x82,0x5e,0x0f,0x1a,0xf9,0xeb,0xe4,0x7d,0xc8,0x26,0xfa,0x04,0xde,0x65,0x9d,0x3e,0xc4,0xca,0x8d,0x3a,0x2b,0xfb,0x9e,0x0e,0xd7,0x47,0xad +,0x3d,0x4a,0x3f,0xab,0x3c,0x9d,0xf8,0x9a,0xcd,0x1c,0xaa,0xb0,0xad,0x04,0xd4,0xa6,0xe7,0x9e,0x76,0xd8,0x8b,0x47,0x56,0xac,0xcc,0xb6,0x8f,0xcd,0xb4,0x80,0xb5,0x8d +,0xb8,0x1f,0xe7,0x00,0xd2,0x91,0x0d,0xa8,0xa6,0x5d,0x28,0xc4,0x8d,0x59,0x44,0xc1,0xe8,0xc0,0x7e,0x20,0x26,0x00,0xa4,0x02,0x00,0x14,0x04,0xa6,0x05,0x4a,0x84,0x82 +,0x82,0x60,0xb8,0x54,0x2c,0x12,0x0a,0x05,0x42,0xc1,0x50,0xa0,0x54,0x28,0x56,0x0a,0x08,0x84,0x62,0x50,0x90,0x4c,0x22,0x13,0x08,0x84,0xc4,0xa1,0x30,0x89,0x9e,0xdf +,0x9a,0xeb,0xd3,0xef,0xeb,0xff,0x3f,0xff,0x0a,0x92,0x6e,0xb4,0xa9,0x5a,0xde,0xad,0x32,0x57,0xb7,0x1f,0x3d,0x66,0xfe,0xff,0xb7,0xfa,0x73,0x3a,0x0e,0xb9,0x7b,0x8e +,0x3d,0x56,0xaf,0x31,0xf6,0x6a,0xbf,0x7f,0x73,0xf3,0xa5,0x0d,0xc9,0xeb,0x71,0xf4,0xd7,0x48,0x27,0xcd,0xba,0xf8,0xbc,0x5e,0xf6,0xbc,0x51,0xaf,0xdb,0x6a,0xfc,0x79 +,0x97,0x4e,0x73,0x59,0x3a,0x06,0xb6,0x54,0xfe,0xe9,0xbc,0x28,0x78,0x94,0xb3,0xe9,0x80,0x91,0x7a,0x66,0xa4,0xe5,0x1f,0x4f,0xda,0x8a,0x30,0xfa,0xf9,0x22,0xe2,0x39 +,0x9c,0x40,0x3d,0x40,0x39,0x8f,0xeb,0xd5,0x99,0x3c,0x24,0x46,0x32,0x5f,0x8c,0x1e,0xb0,0x00,0x4d,0x10,0xf7,0x3d,0x60,0xf7,0x40,0x07,0x8f,0x00,0x0e,0xe6,0x20,0x00 +,0x92,0xe4,0x8d,0x36,0x0a,0x2e,0x10,0x08,0x00,0xa4,0x00,0xe0,0xff,0xf1,0x50,0x80,0x29,0xdf,0xfc,0x21,0x0a,0xcf,0x6b,0xfb,0xfe,0xff,0xb4,0xb3,0x50,0xb0,0x88,0x2c +,0x17,0x0a,0x05,0x82,0x81,0x60,0xa8,0x50,0x24,0x24,0x11,0x11,0x02,0x42,0x30,0x90,0x45,0x46,0x11,0x3b,0x72,0xf6,0xf8,0x78,0xfb,0xfb,0xd6,0x95,0x7b,0x95,0x38,0xe5 +,0xac,0x93,0x52,0xa5,0x6a,0xab,0x5c,0x7b,0xdf,0xd7,0x8f,0x8f,0x21,0xec,0x2f,0x4f,0x22,0xfd,0xf1,0xdf,0xdb,0x3b,0x32,0xe5,0xb2,0x8f,0x3f,0x6c,0x9b,0x45,0x98,0x68 +,0xec,0x8b,0xd7,0x3c,0xbe,0xe4,0x7a,0x37,0x4b,0x76,0xff,0x5a,0x7c,0xb6,0x62,0x8f,0x2f,0x6b,0x21,0x7b,0xd1,0xec,0x1c,0x97,0xe6,0xd1,0xc7,0x13,0x3d,0x97,0xcc,0x2c +,0xe9,0x59,0x7d,0xb2,0x48,0x55,0x12,0xf3,0x58,0xb6,0xb2,0x05,0x7b,0x29,0x95,0x74,0x80,0xb5,0x6d,0xb1,0x02,0x51,0xb0,0x4e,0x08,0x85,0x22,0xe0,0x1d,0xe8,0x85,0x00 +,0x26,0x35,0x94,0x54,0x01,0x50,0x5c,0x12,0x00,0x88,0x14,0x4a,0x24,0x0b,0x05,0x02,0xa1,0x60,0xa0,0x94,0x48,0x12,0x12,0x05,0x42,0x81,0x30,0xa0,0x94,0x28,0x12,0x0a +,0x84,0xc4,0xa1,0x10,0x98,0x44,0x46,0x11,0x11,0x85,0x42,0x27,0x7e,0x6b,0x9e,0xab,0x3d,0xbc,0x7d,0x7b,0xcf,0x6f,0x79,0x9a,0x55,0x46,0x5f,0x59,0x9a,0x98,0xf6,0xe7 +,0x9e,0xaf,0xc6,0xa5,0x7e,0xfe,0xba,0x0e,0x0e,0xfe,0x4f,0xec,0x9f,0x5c,0x7c,0xc9,0xaf,0x97,0xf7,0x0f,0x87,0xb1,0x51,0xd0,0xbf,0x06,0x86,0xf5,0x68,0x2b,0xb2,0xf3 +,0x75,0x52,0x6e,0xe7,0xc5,0xf6,0x49,0xb9,0xed,0x2e,0x26,0xae,0x7f,0xed,0x55,0xba,0xe4,0x0c,0xdc,0x70,0x8d,0xc6,0xb7,0x17,0x76,0xe2,0x88,0x13,0xfe,0x4f,0x0f,0xec +,0xe1,0x51,0x77,0x39,0x55,0x97,0x3e,0x76,0x75,0x27,0x9a,0x1b,0x3d,0xc7,0x83,0x35,0x50,0x43,0xb6,0xda,0x7a,0xd6,0x36,0x4a,0x40,0xf7,0x7f,0xdf,0x85,0x3d,0x02,0xeb +,0xc2,0x3e,0x14,0x0e,0xfc,0x18,0x00,0x3e,0xa0,0x04,0xe0,0xad,0x18,0x00,0xb5,0xe6,0x0c,0xeb,0x14,0xad,0x84,0x28,0x00,0x28,0x5c,0x07,0xff,0xf1,0x50,0x80,0x29,0x3f +,0xfc,0x21,0x0a,0xcf,0xef,0xfd,0xff,0xfb,0xfc,0xb5,0x40,0xb8,0x58,0x28,0x16,0x11,0x05,0x82,0xa1,0x20,0xa8,0x48,0x28,0x12,0x1a,0x04,0x82,0xa1,0x20,0x88,0x50,0x24 +,0x11,0x09,0x04,0x64,0xae,0x2b,0x77,0xc7,0xc7,0xed,0xe7,0xbd,0x6b,0x32,0x44,0xa8,0x4a,0x5c,0x99,0x24,0xaa,0xba,0xd5,0x55,0xff,0x36,0x3a,0x2b,0xb5,0xf1,0x6f,0xf4 +,0x4d,0xef,0xf1,0x77,0x47,0x77,0xcc,0xf7,0xd0,0x5f,0xd9,0xde,0xa0,0xd3,0x7c,0xdf,0x07,0xbf,0x25,0xee,0x6b,0xdb,0x99,0x5e,0x53,0x7b,0x37,0xad,0xe6,0x6c,0x9e,0x3d +,0x94,0x96,0xb4,0x60,0xcd,0x1c,0xa6,0xa3,0xdd,0xc4,0x69,0xb9,0x66,0x81,0x48,0x5e,0xf2,0x83,0xb2,0xe5,0xd1,0x57,0x90,0x40,0x92,0x39,0x7a,0xda,0x3c,0x22,0x16,0x59 +,0x25,0xee,0x55,0x2b,0x12,0x6b,0x02,0x33,0x88,0x28,0x28,0x88,0x26,0x90,0x2a,0x2a,0x15,0x08,0x4c,0xba,0x60,0x02,0xe5,0xc0,0xaa,0x50,0xa0,0x8c,0x28,0x17,0x0b,0x04 +,0x84,0x81,0x50,0xa0,0x88,0x28,0x12,0x0a,0x05,0x82,0x41,0x40,0x90,0x54,0x48,0x15,0x09,0x85,0x44,0x21,0x30,0x88,0x8c,0x22,0x53,0x08,0x91,0xbc,0x9a,0xde,0x7b,0x77 +,0xd6,0xea,0x46,0x5e,0xe6,0x5d,0xc2,0xf2,0xdd,0x67,0x37,0xbd,0x56,0xb7,0xe5,0xe7,0x9f,0x21,0xd3,0xc3,0x7f,0x9f,0xf5,0x7d,0x87,0x9c,0x7e,0x7f,0xa7,0xfb,0x59,0xfc +,0x57,0x1b,0xdf,0x7c,0x23,0x90,0x7c,0x5d,0xdc,0x24,0xd5,0xd3,0x07,0xe0,0x10,0xe6,0x2f,0x7e,0x1f,0xaf,0xc1,0xa4,0x1d,0xad,0x4f,0xc3,0xc1,0xde,0x3a,0x13,0x7b,0xec +,0x0e,0x10,0x70,0xbd,0x95,0xab,0x4b,0xaa,0xa9,0x5c,0x89,0xc7,0xdd,0xa1,0xdd,0x06,0xe8,0x27,0xbc,0xcd,0xa2,0xc1,0x2d,0x36,0xfb,0xca,0x2e,0xf0,0x21,0x25,0x20,0xac +,0x4a,0x4f,0xe6,0x8a,0x40,0x7e,0x45,0x95,0x42,0xe8,0x4e,0xa5,0xe5,0xc6,0x64,0x12,0xc8,0x4a,0x34,0x11,0x2d,0x64,0xfd,0x60,0x8c,0xfb,0xe0,0x2d,0x30,0x4c,0x17,0x01 +,0x7b,0x81,0xc0,0xff,0xf1,0x50,0x80,0x26,0xdf,0xfc,0x21,0x0a,0xcf,0xfd,0xff,0x9f,0x3f,0xf4,0xb4,0x50,0xb0,0x88,0x2e,0x24,0x12,0x84,0x82,0x81,0x50,0x91,0x50,0x24 +,0x61,0x9a,0x65,0xd6,0xf5,0xd7,0x3a,0x5d,0x55,0x6b,0x6a,0xeb,0x71,0x15,0x75,0xfb,0xf8,0xa5,0xf2,0xeb,0x76,0xcd,0x7e,0x2c,0x3e,0x17,0xe9,0xd8,0x7f,0xa9,0xee,0x3b +,0xd8,0xdf,0x36,0xce,0xf3,0x59,0xf8,0xb8,0x38,0x19,0xd4,0x6e,0xc6,0xa4,0x42,0xbf,0xfc,0xd4,0x36,0xdf,0x3e,0xc5,0x29,0xa5,0x11,0xac,0x25,0x75,0x30,0xec,0xc4,0xc9 +,0x44,0x4c,0x5d,0x37,0x5e,0xc4,0xa7,0x2c,0x39,0x2f,0xfa,0x08,0x5e,0x91,0x88,0x9e,0x1b,0x84,0x17,0x10,0x03,0xd0,0x08,0x0b,0x88,0x26,0x12,0x84,0x2e,0x45,0x2e,0x20 +,0xe6,0x48,0x50,0x88,0x01,0x31,0x32,0xd0,0x38,0x00,0xc7,0x79,0x48,0x01,0x04,0x80,0x52,0x10,0x54,0x28,0x13,0x0a,0x05,0x48,0xc2,0x50,0xa1,0x14,0x48,0x52,0x09,0x8d +,0x42,0x41,0x30,0x88,0x4c,0x22,0x43,0x08,0x99,0xef,0xbb,0xfd,0xff,0x4a,0xff,0x6f,0xe3,0xbe,0x2a,0x2a,0xb5,0x59,0x37,0xad,0x6f,0x5e,0x77,0x5e,0x3a,0xdf,0x96,0xe9 +,0xed,0xba,0xaf,0xe7,0x5f,0x71,0x13,0xd5,0xff,0xbf,0xf0,0xba,0x9f,0x81,0xf2,0xf9,0x3c,0x5c,0x97,0x40,0x91,0xfb,0x4c,0x37,0xc4,0x0f,0x74,0x8d,0xfa,0x3e,0x17,0x8d +,0xcb,0x89,0x68,0xf2,0xed,0x7e,0x13,0xfb,0x14,0x2d,0x08,0xdf,0x26,0xfb,0x2f,0xdf,0x73,0xf3,0x91,0xc9,0x27,0x69,0xee,0xe3,0xcd,0xd2,0x97,0x7a,0xef,0x67,0xef,0x54 +,0xfa,0xdf,0x44,0x1f,0x56,0xbb,0xde,0x71,0x0e,0x1c,0x80,0x13,0x45,0x1d,0x84,0x20,0xa9,0x48,0xfe,0x5c,0xa9,0x5c,0xa9,0x46,0xc3,0xba,0x30,0x88,0x2f,0x05,0x5b,0xfe +,0xb8,0x44,0x2e,0x93,0x09,0x7e,0x85,0x2d,0x41,0xdc,0x88,0x02,0xd3,0x8c,0x57,0x2b,0x13,0x48,0xd6,0x08,0x85,0xa8,0x05,0xc0,0x70,0xff,0xf1,0x50,0x80,0x27,0x7f,0xfc +,0x21,0x2a,0xcf,0xff,0xef,0xff,0xff,0xb8,0xb4,0x62,0xb8,0x48,0x4a,0x14,0x19,0x09,0x02,0x43,0x40,0x98,0x48,0x28,0x12,0x08,0x98,0xc2,0x26,0x30,0x89,0x95,0x35,0xe3 +,0xaf,0x3b,0xde,0x6b,0x5b,0xbc,0xd6,0x54,0xbc,0x97,0x4e,0x37,0x1f,0x19,0x99,0x0f,0x3b,0x8a,0xfb,0xc0,0x7d,0xc7,0xab,0x71,0x46,0xeb,0xbc,0xbd,0xec,0x59,0x37,0x43 +,0x80,0xfb,0x79,0xb2,0xfd,0xe7,0x2a,0x2a,0xbf,0xd3,0x13,0x53,0x3c,0x71,0x8a,0x6d,0x1d,0x45,0x95,0x9f,0x07,0x96,0x38,0xcf,0x52,0xef,0x8b,0x9a,0xcf,0x52,0x33,0x5e +,0x96,0x47,0x43,0xb0,0xde,0x8e,0x7e,0xc2,0x79,0xda,0x05,0xf1,0x59,0x5e,0xab,0xa2,0xf7,0x00,0x98,0x30,0xc8,0xac,0x40,0xa6,0xa8,0x85,0x0d,0x24,0xcb,0x20,0x40,0x4c +,0x00,0xee,0x88,0x0b,0x48,0x00,0x0b,0x09,0x81,0x75,0x42,0xa0,0x52,0xa8,0x50,0x2c,0x14,0x0b,0x09,0x42,0x82,0x50,0xa1,0x94,0x28,0x26,0x0a,0x05,0x42,0x81,0x20,0xa0 +,0x54,0x26,0x15,0x09,0x94,0x42,0x63,0x13,0x3b,0xac,0x92,0xb5,0x9e,0x7d,0x4b,0xd9,0x74,0xab,0xcd,0x17,0x73,0x77,0x53,0x8e,0x6e,0xb2,0x3a,0xcf,0xc7,0x41,0xd7,0xf9 +,0x4e,0x4f,0xf8,0xd4,0xef,0xf4,0x8b,0xb7,0xca,0xd8,0x9d,0x5b,0x17,0x52,0x53,0x8c,0xfe,0x47,0x99,0xee,0x67,0x3c,0x4f,0x48,0x67,0xf6,0x1f,0x09,0x9e,0xca,0xbf,0xfa +,0xfe,0x74,0xfa,0x01,0xc7,0x85,0x68,0xb4,0x76,0x38,0x9c,0x21,0xc5,0x3c,0xfa,0x81,0x04,0xd8,0x4d,0x25,0xcd,0x7a,0xbb,0x2c,0x25,0x61,0x37,0x0f,0x99,0x04,0x92,0xf5 +,0xec,0x83,0xc9,0x74,0x40,0x77,0x76,0x96,0x91,0x0b,0xd0,0xe0,0xee,0x95,0x91,0xee,0xbf,0x5d,0x37,0xa1,0xbc,0x59,0xc0,0xf0,0x82,0x85,0xe5,0xa2,0xa7,0xae,0x10,0xb9 +,0xee,0xa0,0x45,0x9a,0x1e,0xe8,0x20,0x72,0xcb,0x25,0xa8,0x22,0xee,0x05,0xa1,0x60,0x04,0x42,0xe0,0x70,0xff,0xf1,0x50,0x80,0x28,0x9f,0xfc,0x21,0x4c,0xfe,0xff,0xfd +,0x74,0x16,0x28,0xd5,0x19,0x18,0xe2,0xa2,0x48,0xb9,0xc0,0x96,0xa5,0x44,0x42,0x2e,0x0b,0x7d,0xa5,0x76,0xbe,0xfb,0x45,0xe8,0xaf,0x50,0xd5,0x25,0x16,0x8c,0xa5,0x4d +,0xf4,0x06,0x52,0x6a,0x9f,0x73,0xd4,0xfa,0x24,0x07,0xd0,0xd5,0x1f,0xf2,0x80,0xb4,0xa1,0x14,0x9c,0x95,0x28,0x5f,0x0b,0xdd,0x16,0x3c,0x18,0xd6,0xa1,0xfc,0x4c,0xa9 +,0x8b,0x5c,0x47,0x29,0xae,0xbd,0xeb,0x3e,0x5b,0x8e,0x88,0xbe,0xca,0xaa,0x1a,0xba,0x08,0x99,0x06,0xe7,0xbe,0xba,0xb8,0x77,0x4b,0x2c,0x6c,0x4d,0x90,0x84,0xdb,0x89 +,0x7c,0x8e,0xad,0x73,0x4b,0x68,0x8c,0x16,0x2e,0xa6,0x8b,0x7f,0x6e,0x57,0xfb,0x4d,0x5c,0x52,0x9d,0x95,0x91,0xef,0x91,0x05,0xc7,0x66,0x04,0x39,0xc6,0x57,0x0b,0x9a +,0x62,0x51,0x78,0xaf,0x40,0x45,0x7a,0x00,0x03,0x08,0xb8,0xa8,0x80,0xd0,0x28,0x9a,0x21,0x62,0x88,0x89,0xa1,0x2a,0x55,0xd5,0xc8,0x9d,0x0c,0x6f,0x92,0xe8,0x9a,0x09 +,0x6c,0x6f,0xce,0xf3,0xa3,0xe0,0x56,0x3f,0x74,0xc2,0xb5,0xdd,0xbb,0x76,0xdc,0x79,0x4d,0x65,0x3c,0xeb,0x93,0xae,0x5b,0xa1,0xa7,0xfc,0x9f,0x3f,0xaf,0x61,0xa7,0x64 +,0x61,0x2e,0x05,0x50,0x6a,0xba,0x5d,0x3d,0x95,0x6d,0xfc,0x7f,0x9f,0xb2,0xd0,0xf0,0xb9,0x3e,0xd0,0x42,0x4b,0x61,0xc3,0x8d,0x23,0x9c,0x0d,0xc2,0xa2,0x55,0xda,0x11 +,0x64,0xee,0x52,0x01,0xb9,0xb5,0x47,0x85,0x65,0xb1,0xd9,0x98,0xdc,0xbe,0xe4,0xdf,0xdc,0x37,0xaa,0xdc,0x9b,0x3b,0x98,0x65,0xe3,0x67,0x51,0x8c,0x1b,0x63,0x2d,0x95 +,0xe5,0x59,0x67,0x05,0x0a,0x5a,0x4e,0x13,0x77,0x7d,0x0b,0xce,0x75,0x0a,0xe3,0x40,0x35,0x23,0x37,0xea,0xa7,0x7f,0xaa,0x29,0x58,0x4a,0x91,0x9c,0xfc,0x7a,0xc3,0x52 +,0x14,0x82,0xb6,0xa3,0xc0,0x2d,0x86,0x99,0x60,0xb1,0x33,0x21,0x7a,0x02,0xa3,0x18,0x98,0x98,0xe0,0x46,0xc2,0x91,0xb3,0x80,0xff,0xf1,0x50,0x80,0x29,0x5f,0xfc,0x21 +,0x6a,0xcf,0xff,0xff,0xff,0xff,0xfe,0xb8,0x61,0xa0,0x58,0x44,0x14,0x12,0x85,0x02,0xc2,0x21,0x20,0xd8,0x24,0x41,0x09,0x04,0x42,0x41,0x14,0x18,0x44,0xe9,0x75,0xc6 +,0x4e,0x3c,0x55,0xf1,0xcc,0xbd,0xc9,0x37,0xa9,0x57,0x4b,0xa9,0x32,0x0e,0xb2,0x6b,0x73,0xef,0xc0,0xb7,0xc9,0xd9,0x59,0xf3,0xd6,0x4b,0xbf,0x51,0x79,0x6b,0x4d,0x85 +,0xe1,0xc9,0x48,0x9a,0x16,0xfd,0xa1,0x49,0xdd,0xc7,0xc1,0xdd,0x45,0x8a,0xbf,0x21,0x47,0x3f,0x09,0x9c,0xf8,0x0a,0x79,0x23,0xfd,0xe6,0x92,0x39,0x62,0xea,0x67,0x3d +,0xca,0xcf,0xfd,0x4d,0x66,0xa1,0x90,0xe0,0x52,0x30,0xa6,0xfa,0x82,0x0c,0x69,0xc2,0xd8,0x51,0x96,0x35,0x09,0xb2,0x91,0x99,0x64,0xb8,0x20,0x9d,0x08,0x41,0x49,0x0a +,0x1c,0x05,0x6a,0x28,0x0a,0xdd,0x20,0x1f,0x04,0x25,0x50,0x4d,0x44,0x6c,0x80,0x0c,0x40,0x10,0x90,0x40,0x05,0x40,0x9e,0x41,0x30,0x50,0x4c,0x14,0x0a,0x85,0x04,0x41 +,0x41,0x10,0x54,0x28,0x26,0x0a,0x85,0x04,0x61,0x40,0xa8,0x4c,0x2a,0x13,0x1a,0x84,0xc2,0x26,0x30,0x89,0x5f,0xd6,0xe7,0x37,0x9d,0x6e,0x6b,0x79,0xd6,0xe3,0x25,0x56 +,0xaa,0x47,0x5b,0x99,0xc7,0x32,0xbd,0xb3,0x54,0xa6,0x83,0xeb,0x1b,0xce,0x87,0xd8,0xbe,0x97,0xb5,0xb5,0xcb,0xdd,0xcd,0x76,0x0e,0xd8,0x39,0xaf,0x2d,0xeb,0xb7,0x6a +,0xf7,0x73,0x87,0x0e,0x0c,0x99,0xcf,0xfe,0x5c,0x2a,0x1b,0x24,0x0f,0x91,0xd1,0xc5,0xb0,0x1b,0xe0,0x7d,0x20,0x3d,0xff,0xff,0x77,0xe8,0xaa,0xa3,0xcb,0x0d,0x21,0x6f +,0x8d,0xf2,0x38,0xe9,0xe7,0x30,0xee,0xc8,0x0e,0x1d,0x35,0xf1,0x52,0xe7,0x7f,0x06,0x87,0xc2,0xf5,0xe6,0x95,0xc3,0xea,0xd6,0xba,0x8d,0x38,0x09,0x44,0x01,0x22,0x1f +,0x0e,0x18,0x94,0x64,0x83,0x8c,0x21,0x09,0x94,0x8f,0x5b,0x9f,0x9b,0x44,0x94,0x00,0x38,0x81,0x75,0x00,0x7b,0xb8,0xc8,0xa5,0x00,0x99,0x22,0x22,0xb0,0x00,0x9a,0x91 +,0x03,0x80,0xff,0xf1,0x50,0x80,0x29,0x9f,0xfc,0x21,0x0a,0xcf,0xcf,0x7f,0xfe,0xff,0xff,0xb7,0x61,0x20,0x58,0x28,0x35,0x0a,0x09,0x44,0xc1,0x20,0xa8,0x58,0x28,0x12 +,0x0a,0x04,0x82,0xa1,0x21,0x08,0x48,0x62,0xa3,0x08,0x94,0xd4,0xac,0xf3,0xaf,0x0d,0x73,0x9c,0x5d,0x65,0x97,0x50,0x55,0xac,0x65,0x6a,0x75,0xbe,0x1e,0xdc,0x0d,0xb7 +,0x27,0x9f,0xf4,0x1b,0x5b,0x62,0xd0,0x9e,0x93,0xaf,0xc9,0xf1,0xba,0xce,0x70,0xd7,0xb2,0x9d,0xf9,0x03,0xdd,0x29,0x8f,0x4e,0xb5,0x22,0x3b,0xdf,0x43,0xd4,0x9c,0xac +,0xda,0x7a,0xa3,0x53,0x9c,0xad,0xcf,0xbd,0x72,0xd2,0x94,0xea,0x5b,0xeb,0xda,0x32,0xbe,0x7b,0x12,0x66,0x1d,0x44,0xc4,0x25,0x6e,0x12,0x8a,0x66,0x79,0x0f,0xa7,0x0d +,0xcc,0x6e,0x45,0xd2,0x09,0x51,0x36,0xb8,0x42,0x21,0x54,0x28,0x32,0xc4,0x9d,0xef,0x7b,0xad,0x34,0x97,0x0e,0x84,0x82,0x24,0x51,0xf5,0x80,0x0b,0x89,0xa2,0x0a,0x2f +,0x70,0x02,0x24,0x00,0x54,0x10,0x50,0x8c,0x25,0x0a,0x14,0x82,0x85,0x60,0x90,0x50,0x46,0x15,0x09,0x85,0x02,0x61,0x50,0x98,0x44,0x26,0x15,0x08,0x84,0xc2,0x23,0x30 +,0x89,0x1b,0xe6,0xfc,0xfb,0xcf,0xc7,0xe7,0xf5,0xfc,0xd4,0xce,0xb2,0x32,0x54,0xb9,0x4c,0xe3,0x55,0xbb,0xf6,0xfb,0x75,0x8f,0xa8,0xa4,0x0f,0x6b,0x7d,0x35,0xc9,0x7f +,0xea,0xef,0x54,0xf7,0xbd,0x7b,0x4f,0x81,0xd3,0x93,0xfb,0x67,0x6c,0x2b,0xed,0x7f,0xff,0x2c,0x3d,0x2e,0x85,0x17,0xa6,0x27,0x2e,0x5f,0x51,0x93,0x1b,0x7c,0xbc,0x68 +,0x24,0x0d,0x7f,0xdf,0x7d,0x83,0x9e,0xb2,0xee,0x97,0x7a,0x1d,0xed,0x3b,0xe5,0xf8,0xc4,0xa4,0xe8,0xa6,0x77,0x2f,0x8f,0xfc,0x2e,0xe7,0x3a,0x93,0x53,0xce,0x8f,0x1e +,0x74,0x77,0x01,0xe6,0xa0,0x2e,0xf5,0xe8,0x07,0xd6,0x49,0xd8,0xff,0xd7,0xc6,0x91,0x60,0x79,0x80,0x16,0xfd,0xa1,0x29,0x72,0x0b,0x9d,0xd5,0x2b,0x57,0x52,0x02,0x1d +,0x21,0x3a,0xb1,0x04,0xcf,0x5e,0x40,0x05,0xe6,0x04,0x80,0x88,0x58,0x07,0xff,0xf1,0x50,0x80,0x27,0x7f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xfd,0xfd,0xb7,0x40,0xb0 +,0x50,0x4c,0x14,0x0a,0x85,0x06,0xe1,0x50,0xb8,0x48,0x28,0x15,0x12,0x08,0x88,0x21,0x20,0x88,0x88,0x22,0xf5,0xa6,0x4f,0x6d,0xf3,0xe7,0x6a,0xd6,0xbd,0xfd,0xb6,0x45 +,0x49,0x2a,0xc8,0xa2,0xf2,0xfa,0x3f,0x1f,0x03,0xf5,0xaf,0x7b,0xfe,0x8b,0x50,0x69,0x3f,0x95,0x38,0x6b,0x4d,0xbb,0xc7,0xed,0x6a,0x1a,0x4f,0x8c,0xe5,0xdf,0xce,0x3d +,0xfc,0xb7,0x5e,0xf5,0xf8,0xad,0xdc,0xab,0xfd,0x57,0x9d,0x57,0x2e,0x54,0xa3,0xfe,0x9e,0x3c,0x56,0x31,0x0d,0x5c,0x73,0xbf,0x4f,0x2d,0xf4,0x9f,0x47,0xf5,0x08,0x96 +,0x68,0xab,0xd9,0x96,0x8e,0xb7,0xaa,0xe3,0x18,0x5a,0xce,0x17,0x9c,0xa8,0x60,0x82,0x3d,0x0a,0x6f,0xbd,0xd6,0xdb,0x29,0xef,0x49,0x61,0x24,0x30,0xd6,0x0b,0x07,0x02 +,0x82,0xf1,0x80,0x8c,0x00,0x14,0x54,0x54,0x74,0x58,0x5d,0x59,0xcc,0xbc,0xc1,0x75,0x45,0xc0,0x4c,0x05,0x21,0x05,0x44,0xc1,0x40,0xb0,0x90,0x4c,0x32,0x0a,0x1c,0x82 +,0x83,0x51,0x99,0x14,0x26,0x51,0x33,0xc4,0xe6,0xaf,0x9f,0x6f,0x1e,0x79,0xa5,0xcc,0x22,0xa3,0x52,0x67,0x57,0xbb,0xcd,0x78,0xf3,0x75,0xf8,0xfe,0xbc,0x79,0xe7,0xf7 +,0x10,0x75,0x39,0xb9,0x47,0xfb,0x39,0x19,0xed,0xe7,0x1b,0x51,0x69,0xe9,0x00,0x79,0x99,0x69,0xdb,0xef,0xa2,0x4c,0x8d,0xed,0x8a,0x7d,0xfe,0x87,0xec,0xfc,0xaf,0xa2 +,0x74,0xfb,0xfd,0x1b,0xb2,0xef,0x3e,0x57,0x83,0xbd,0xe4,0x50,0x76,0xac,0x72,0x48,0x17,0x46,0x25,0xcd,0x4f,0x74,0xa5,0x67,0x91,0x72,0x9e,0x50,0x41,0xc4,0x64,0x92 +,0x5c,0x34,0x25,0xf9,0x20,0x3c,0x40,0x9d,0x45,0xbd,0xcf,0x5e,0x60,0x1e,0x70,0x02,0x00,0x0f,0x58,0xf7,0x0f,0x62,0x00,0x77,0x83,0xba,0x00,0x78,0x31,0x1f,0x31,0x24 +,0x80,0xba,0x40,0x09,0x84,0x22,0x15,0x88,0x1c,0xff,0xf1,0x50,0x80,0x28,0x5f,0xfc,0x21,0x0a,0xcf,0xfb,0xef,0xfd,0xff,0xff,0xb3,0x61,0x20,0x98,0x28,0x12,0x0a,0x05 +,0x82,0x81,0x51,0x38,0x50,0x2a,0x24,0x0b,0x05,0x04,0x47,0x13,0x98,0x45,0x0a,0x92,0x93,0x5c,0xcb,0xdb,0x8b,0xf5,0xc6,0xf5,0x9c,0x55,0x2e,0xa4,0xbb,0xa9,0x52,0x71 +,0xb8,0x4f,0xdf,0xa0,0x5a,0x74,0xcd,0xff,0xe3,0xf9,0x4f,0xc3,0xfd,0xd3,0xf9,0xbd,0xf1,0x8e,0x4d,0xe8,0xcc,0xba,0x4e,0xa9,0x79,0x0a,0xea,0x5d,0xb4,0xf9,0x78,0x88 +,0x3c,0xcc,0x43,0x71,0x19,0xf9,0xd5,0xae,0x79,0xe4,0x62,0x5b,0xc9,0xb2,0x17,0x92,0x8e,0xe3,0xf4,0x2b,0xd0,0x2b,0xf8,0xc5,0x43,0x89,0xbe,0x60,0x6d,0xeb,0xa4,0xcd +,0x9b,0x39,0x0b,0xc6,0x7c,0x10,0x21,0x7a,0xa5,0xa6,0x34,0x20,0x95,0x90,0xba,0xe4,0xc4,0xea,0x5c,0x49,0x28,0x89,0x9a,0x16,0x13,0x7b,0xa2,0xc0,0x23,0x72,0xb2,0x21 +,0x70,0x55,0x34,0xc2,0x74,0x50,0xa9,0xc8,0x00,0x24,0x88,0x15,0x4a,0x14,0x0a,0x85,0x86,0x81,0x20,0xa1,0x58,0x6a,0x14,0x0a,0x85,0x02,0xa1,0x60,0xa8,0x50,0x2a,0x12 +,0x09,0x9c,0x46,0x64,0x11,0xb2,0xf7,0x59,0xc5,0xf8,0xfc,0x7a,0xdd,0xd1,0x74,0x5d,0x5e,0x5e,0xf8,0xad,0x4b,0x4e,0x7f,0x5a,0xa6,0xab,0xac,0xf2,0x1c,0x38,0x67,0x31 +,0xd1,0xa9,0xb6,0x27,0x1c,0xf8,0xfe,0x2f,0x26,0xd5,0xb0,0x73,0x6f,0xc0,0xfc,0xa6,0x5d,0xc6,0xed,0xc8,0xa5,0x14,0xd4,0xe3,0xea,0x99,0x53,0xee,0x79,0x46,0x3d,0x0a +,0xe4,0xef,0x2b,0x70,0x8a,0x7b,0xd1,0xc1,0xc9,0x48,0x50,0xa0,0x70,0x3b,0x24,0xf2,0x1f,0x3a,0xab,0x9e,0x69,0x4d,0x71,0x8e,0x44,0x72,0xb3,0xab,0x4e,0x53,0xb7,0xb0 +,0x34,0x7f,0x72,0x53,0x5a,0x17,0xae,0x5f,0x81,0x34,0x47,0x75,0x2b,0xbb,0x94,0x7b,0x80,0x7b,0xb7,0xab,0xdd,0x44,0x3e,0x08,0x99,0x1b,0xd8,0x05,0xe6,0x00,0x3d,0x60 +,0x1d,0xf0,0x03,0xd6,0x07,0xac,0x0b,0x00,0x08,0xa4,0x07,0xff,0xf1,0x50,0x80,0x27,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0x6d,0xff,0xfd,0xb1,0x50,0xb8,0x50,0x44,0x44 +,0x2a,0x85,0x02,0xe1,0x10,0x98,0x48,0x86,0x12,0x18,0x94,0xc2,0x24,0x30,0x89,0x9d,0xa3,0x88,0xf1,0xd5,0xf8,0xb9,0xae,0xfc,0xf3,0x79,0xa9,0x8b,0xcb,0xe2,0xaa,0x71 +,0xb1,0xd7,0x75,0xd6,0x7f,0x8f,0xf0,0x1e,0x8f,0x23,0xff,0xdf,0xfa,0xbf,0x9d,0xbe,0x1c,0xfa,0x03,0x93,0x78,0xb7,0x3a,0xfe,0x18,0xb7,0xda,0xfe,0x0d,0x21,0xea,0x3b +,0x9d,0x33,0xf5,0x79,0x7f,0xd1,0xd4,0x9a,0xf4,0x8f,0x9d,0xb8,0x2d,0x3d,0xd4,0xd9,0x0f,0xd4,0x39,0x45,0x27,0x25,0xc3,0x01,0xd4,0xb6,0x8e,0xa9,0xa3,0x70,0x65,0x9a +,0x74,0x82,0x1a,0xac,0x27,0x9a,0xe9,0xd5,0x34,0x2e,0x48,0x25,0x69,0x22,0x5f,0xba,0xf7,0x02,0x64,0x48,0x53,0x60,0x02,0x5e,0x71,0x2a,0x21,0x2b,0xd4,0x07,0xec,0x5d +,0x60,0x24,0x09,0x01,0x55,0x17,0x01,0x20,0x22,0x05,0x11,0x05,0x02,0xc2,0x40,0xa8,0x50,0x64,0x14,0x0b,0x05,0x06,0xc1,0x21,0x20,0x58,0x2a,0x14,0x09,0x05,0x02,0x43 +,0x30,0x88,0x8c,0xe2,0x67,0xbc,0xf7,0xd4,0xe7,0xdb,0x9e,0x1d,0xdc,0xa5,0x5b,0x9e,0x1b,0xd2,0xb5,0x79,0x7c,0x4c,0xd4,0x95,0xaf,0xa7,0xd7,0xcf,0xee,0x30,0xe2,0x15 +,0xf5,0xf3,0xbf,0xc9,0xee,0x7c,0xf7,0xb5,0xdb,0x3a,0xb5,0x55,0xac,0x47,0xf4,0x6f,0x5a,0xd5,0xe5,0x9a,0xa2,0x68,0xd2,0x0f,0x2f,0xff,0x77,0x9c,0x57,0x7c,0xea,0x91 +,0xea,0xa8,0xa6,0xb6,0x6a,0xbd,0xcc,0x76,0x3e,0xd6,0xc5,0xfa,0xed,0x5e,0x17,0xd0,0x64,0x4f,0x73,0xec,0x54,0xca,0x60,0x5e,0x5c,0xfe,0x37,0x31,0xf7,0x81,0x25,0xf7 +,0x96,0xcd,0xe4,0x5a,0x34,0x96,0xbe,0x4d,0x4b,0x68,0x98,0x0b,0x77,0x83,0xd6,0x07,0x7a,0x34,0x20,0x04,0xcf,0x73,0xd7,0x01,0xdd,0x7b,0x80,0x01,0xdc,0x2c,0x00,0x10 +,0x88,0x09,0x80,0x0b,0x04,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x28,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xff,0xff,0xae,0x70,0xa0,0x98,0x48,0x26,0x12,0x05,0x44,0xc1 +,0x41,0x30,0x54,0x28,0x42,0x18,0x84,0x82,0x31,0x7b,0xc9,0x75,0xed,0x3e,0x7a,0xdd,0xed,0xf5,0xf6,0xe3,0x24,0x45,0x6a,0x93,0x48,0x2a,0xf5,0x93,0x35,0xfb,0xe8,0x3b +,0x2f,0xd7,0x34,0xa5,0xda,0xf6,0x17,0x87,0xa0,0xdf,0x6f,0x02,0xd6,0x9f,0x49,0x7c,0x51,0xc8,0xa9,0xed,0x4f,0xc5,0xb5,0xfe,0x9f,0xff,0x18,0x7d,0x00,0x5c,0x2e,0xf9 +,0x17,0x86,0xbe,0xe0,0x4d,0x4e,0x28,0xd5,0x45,0x56,0xef,0xdb,0x95,0x47,0x7d,0x08,0x49,0x74,0xf9,0x25,0x7d,0x65,0x15,0xc4,0xad,0xa3,0x03,0x42,0xea,0x31,0xfc,0xd4 +,0x84,0x76,0x28,0xb4,0xe8,0x62,0x90,0x56,0xea,0x2a,0x89,0xbd,0x25,0xc1,0x61,0x2b,0x40,0x34,0x94,0x70,0x05,0xc5,0x82,0x21,0x81,0x58,0x00,0x2e,0x30,0x0b,0xa6,0xa5 +,0x63,0x7b,0x00,0x15,0x58,0x05,0x4a,0x04,0x82,0xa1,0x40,0xb8,0x54,0x2c,0x14,0x0a,0x85,0x04,0xc1,0x50,0xb0,0x50,0x2c,0x15,0x0a,0x11,0x42,0x62,0x20,0xa8,0x8c,0x22 +,0x33,0x10,0x88,0xc2,0x21,0x31,0x09,0x1c,0x7b,0xba,0xf1,0x5f,0x5e,0x2d,0x59,0x19,0x75,0x51,0x77,0x55,0x7d,0x6e,0xa9,0xd4,0xe7,0xf5,0xf1,0xbf,0xa6,0x7e,0xbe,0xbc +,0x8d,0xf3,0x9d,0xe3,0xa6,0x1e,0x5f,0xc8,0x9e,0xcf,0xfa,0x7d,0x4e,0x2d,0xbb,0x7b,0x78,0x29,0x1d,0xd7,0xd2,0x32,0x3d,0x53,0x6f,0x7b,0xd5,0x16,0x9e,0xc7,0x5c,0x57 +,0x48,0xf3,0x4d,0x5f,0x26,0x92,0xdc,0xee,0x18,0xd7,0xd6,0xcb,0x5c,0xbc,0x6e,0xe3,0xf8,0x14,0x25,0xf5,0xa7,0xd6,0x22,0x57,0x5f,0x26,0xb8,0x83,0x2e,0x60,0x02,0x7c +,0xef,0x2f,0x5f,0xde,0x84,0xf5,0x5f,0x11,0x29,0x53,0x3c,0x03,0x15,0xec,0xec,0xbc,0x93,0x7b,0xa0,0xf5,0xc2,0xf1,0x11,0xc8,0x9c,0x40,0x7b,0xa4,0x81,0x10,0xd1,0x0f +,0x70,0x07,0xae,0x00,0x0a,0x02,0xc0,0x11,0x11,0x03,0x80,0xff,0xf1,0x50,0x80,0x27,0xbf,0xfc,0x21,0x0a,0xcf,0xed,0xff,0xef,0xff,0xff,0xb4,0x50,0xb0,0x50,0x4c,0x14 +,0x0a,0x85,0x02,0x42,0x30,0xa8,0x90,0x4e,0x12,0x0b,0x04,0x88,0xa1,0x21,0x0a,0x8c,0x22,0x75,0x49,0x55,0xfa,0xfa,0xef,0xd9,0x9b,0xd6,0x67,0x18,0x97,0x29,0x24,0x3a +,0xcc,0x9b,0xbe,0xaa,0xad,0x3e,0xfc,0x07,0xb7,0xce,0xdc,0x0f,0x22,0xfa,0x16,0x8e,0xe8,0x79,0x5f,0xaa,0xbf,0xf4,0x3c,0x76,0x95,0x7d,0x55,0xb2,0xf9,0x97,0x7b,0x47 +,0x7e,0x89,0xff,0x70,0x7c,0x95,0xd3,0x7d,0xcb,0x2e,0x3d,0xb4,0xcd,0xb1,0x52,0x38,0x69,0xbf,0x56,0xea,0x8b,0x56,0xa5,0xb0,0x4e,0xc5,0xe6,0x83,0xc6,0xb5,0xda,0x63 +,0x48,0x26,0x95,0xe7,0x9e,0x1c,0xa8,0x21,0x01,0x11,0x84,0x19,0x50,0x91,0x15,0xd4,0x29,0x74,0x48,0x89,0xca,0x96,0x6b,0xc0,0x04,0x5e,0xb8,0x42,0x82,0x05,0x01,0x11 +,0xcd,0x00,0x48,0xb9,0xcd,0x50,0x02,0xa4,0x00,0x53,0x10,0x50,0x8c,0x15,0x0a,0x08,0xc2,0xa1,0x40,0xa9,0x08,0x4a,0x24,0x09,0x05,0x02,0x41,0x51,0x98,0xc4,0x46,0x21 +,0x11,0x84,0x4c,0xf0,0xcb,0x67,0x5b,0xdf,0xc7,0x88,0xba,0xc2,0xf0,0x9c,0x56,0x82,0xb8,0x9f,0x55,0xcf,0xaf,0xdf,0xdf,0xef,0xbe,0x86,0xcd,0xcb,0xa3,0xfc,0x33,0xfd +,0xda,0x8d,0xf4,0x7c,0xb3,0x42,0x7f,0x0b,0xd5,0xc6,0xdb,0x57,0xa1,0xd2,0xeb,0x7c,0x9c,0xba,0x2b,0x93,0xdd,0xe4,0x73,0xd1,0xef,0xf3,0xfb,0xee,0xdc,0x3e,0x2e,0x7b +,0xf7,0xca,0xee,0xaf,0x3b,0xa5,0xab,0xa7,0x4e,0x3e,0x81,0x2e,0xcb,0xa2,0x63,0xce,0xdb,0xae,0xd9,0x2a,0xd7,0x32,0x56,0x82,0xba,0x93,0x3c,0xcb,0x58,0xa9,0x69,0x3f +,0x66,0x42,0x44,0xbb,0xfe,0xb9,0xeb,0xf1,0x42,0x26,0x39,0xd8,0x65,0x85,0x6f,0x11,0x4a,0x57,0xf6,0xc5,0x83,0xd7,0x08,0x00,0x52,0xc0,0x00,0xee,0x11,0x16,0x22,0x00 +,0x88,0xaa,0xa0,0x01,0x68,0x1d,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x27,0x3f,0xfc,0x21,0x0a,0xcf,0x67,0xff,0xdf,0xff,0xfe,0xb4,0x62,0x98,0x48,0x2c,0x24,0x0a,0x85,0x02 +,0xa1,0x40,0xa8,0x58,0x28,0x25,0x09,0x05,0x02,0x43,0x14,0x98,0x44,0x26,0x11,0x3a,0xa7,0x9f,0x5d,0x6b,0xcf,0xed,0xab,0xdb,0xaa,0xf1,0xe7,0x69,0x78,0xd2,0x54,0x6b +,0x2b,0x8d,0x7a,0xf6,0xc5,0xe5,0xfe,0x3e,0x01,0xf1,0xb3,0x89,0xf5,0xf3,0xaf,0x8d,0xbf,0xe0,0xc0,0x79,0x68,0x8e,0x25,0xe5,0x94,0x74,0xe7,0x0f,0xab,0xb5,0x5c,0x4f +,0xb9,0x83,0x7a,0x82,0x15,0xd1,0x7c,0x2a,0xc4,0xbe,0x26,0x95,0x83,0x96,0x1d,0xe2,0x76,0x6d,0xbe,0x0c,0x34,0x11,0xdd,0x66,0xa0,0x44,0xe3,0xed,0x9a,0xdc,0xe1,0x18 +,0xa3,0x0a,0x59,0x0a,0xf7,0x22,0x9c,0x27,0x37,0xfc,0x02,0x53,0xbd,0xd5,0x0a,0x55,0x6a,0x94,0x19,0x69,0xd1,0x28,0x83,0xd6,0x0c,0x72,0x84,0xee,0xd2,0x1d,0xd0,0x10 +,0x46,0x48,0x84,0x56,0x09,0x00,0x5c,0xd3,0x30,0x04,0xc9,0x2a,0x05,0x29,0x09,0x02,0xe1,0x40,0xb0,0x50,0xea,0x12,0x0a,0x05,0x42,0x41,0x41,0x28,0x50,0x2a,0x12,0x18 +,0x8c,0xc2,0x21,0x30,0x89,0x4c,0x22,0x57,0xbe,0x6f,0xac,0xc9,0xfa,0xfc,0xfd,0xff,0x4b,0xcb,0x8c,0xa9,0x7b,0xd2,0xea,0xdf,0x7c,0xf5,0xed,0xe3,0xf5,0xbe,0x7b,0xe3 +,0x73,0xa8,0x12,0xec,0xe0,0x3d,0x6b,0xdf,0xb6,0x0f,0xe8,0x79,0xee,0xa9,0xf1,0x8e,0x77,0xdb,0x6f,0x07,0x73,0xae,0xf8,0xb5,0x0a,0xf9,0xf6,0xc9,0x51,0xf3,0x23,0xf9 +,0xbb,0xf1,0x83,0x46,0xf9,0xc7,0xe1,0xf9,0xa8,0xa1,0x02,0x74,0x0c,0xac,0x53,0x81,0x70,0x21,0x55,0x5e,0x93,0xae,0x23,0x6e,0xe9,0x5a,0xd4,0x15,0xdd,0x1e,0xac,0x0f +,0x6c,0xe9,0x15,0x84,0xc0,0x3d,0xc5,0x88,0x57,0x40,0x7b,0xbe,0xe8,0x09,0x1a,0x80,0xca,0x5d,0x30,0x01,0x31,0x70,0x98,0x1d,0xe2,0x00,0x16,0x02,0x40,0x0b,0x84,0x80 +,0x70,0xff,0xf1,0x50,0x80,0x29,0x1f,0xfc,0x21,0x0a,0xcf,0xad,0xff,0xff,0xff,0xfd,0xb0,0x61,0x20,0x4c,0x28,0x15,0x09,0x05,0x42,0x41,0x60,0xa8,0x48,0x2e,0x14,0x09 +,0x05,0x42,0x61,0x50,0x91,0xc5,0x26,0x11,0x19,0x88,0x46,0xf0,0xbd,0x73,0xe7,0x37,0xfe,0x9f,0xd7,0x5b,0x97,0xce,0xa9,0x25,0xe4,0xab,0x5e,0x7e,0xbe,0xb2,0x9c,0x73 +,0xc6,0x7b,0x65,0x7d,0xf8,0x03,0xec,0xec,0xbb,0xea,0x3f,0x99,0xf8,0xdf,0xa8,0xfb,0x9f,0xda,0x39,0xfd,0x56,0x4d,0xde,0xbf,0x4f,0x1e,0x34,0x5a,0xee,0xf5,0xf0,0x2b +,0xef,0xe2,0x5e,0x15,0x8f,0x1e,0x11,0xc4,0x7e,0x58,0x7b,0x2c,0x87,0x5a,0x05,0x69,0xe9,0x7c,0x8b,0xa0,0xd0,0x1a,0x75,0x23,0x0b,0x1e,0x95,0x2b,0x6e,0xe6,0x0e,0x1f +,0xe3,0x82,0x56,0x21,0x80,0x52,0x01,0x01,0x6b,0x84,0x49,0xa7,0x4b,0x84,0xf3,0xb7,0x88,0xd4,0xb8,0x3e,0xdc,0x16,0xb9,0x5b,0x24,0x37,0x88,0x23,0x32,0x80,0x3b,0xa7 +,0xaf,0xeb,0x01,0x10,0x2e,0x5c,0x20,0x05,0x21,0x09,0x02,0x62,0x60,0xb8,0x58,0x28,0x16,0x0a,0x04,0x82,0x83,0x50,0xa0,0x54,0x28,0x16,0x0a,0x04,0x82,0xa2,0x40,0x88 +,0x48,0x26,0x21,0x09,0x88,0x46,0x61,0x13,0xbe,0x59,0x52,0xbf,0x7f,0xd2,0x71,0xb4,0x62,0x4c,0xb4,0xd6,0x5e,0x79,0x9f,0x1f,0x69,0xdf,0xea,0xef,0x99,0xf5,0xaf,0xb7 +,0x9f,0x61,0x0f,0xb6,0xbb,0xff,0x1f,0xe8,0x78,0xa3,0xb2,0xdf,0x66,0xdd,0xcc,0xfb,0x1a,0x3a,0x7f,0xda,0xf2,0xff,0xa2,0x19,0xe2,0xf5,0x5c,0x3d,0x88,0xb9,0xf1,0x3f +,0xa8,0xc7,0x02,0xbf,0x71,0x22,0x72,0x60,0x94,0x53,0xfa,0x1e,0x7d,0x76,0x4b,0xd1,0x3b,0xf0,0x89,0x22,0x95,0xf0,0x40,0xe5,0x8f,0x66,0xe8,0x5a,0x4d,0x0d,0x31,0x4b +,0x08,0xc7,0xa0,0xee,0x58,0x3d,0xdf,0x5c,0x02,0x88,0x4b,0xbd,0x7f,0x74,0x20,0xa1,0xed,0x49,0x46,0x77,0x13,0x0d,0x00,0x04,0x40,0xef,0x10,0xa5,0x00,0x4a,0xa2,0xea +,0x01,0x30,0x10,0xd9,0x10,0x02,0xc5,0x40,0x70,0xff,0xf1,0x50,0x80,0x26,0x5f,0xfc,0x21,0x0a,0xcf,0xe7,0xfb,0xff,0xff,0xff,0xb1,0x61,0xa0,0x94,0x48,0x35,0x09,0x05 +,0xc2,0x82,0x50,0xa1,0x08,0x42,0x23,0x08,0xc9,0xcd,0xaa,0x71,0xf1,0xfc,0x75,0x4c,0xd4,0xe5,0x24,0xb2,0x52,0xef,0x35,0x6c,0xdc,0x69,0xdf,0x1c,0x7e,0x3c,0x84,0xfb +,0xfd,0xdc,0xfa,0xbe,0x1b,0xfb,0x8f,0x69,0xcf,0xb3,0xd8,0x7b,0x9f,0xd5,0xb3,0x63,0xe8,0xf1,0x76,0xf7,0x26,0xab,0x74,0xbe,0xef,0x04,0x4f,0xe4,0xd6,0xe1,0xe2,0xa0 +,0x97,0x9e,0xf6,0x91,0xaa,0x3c,0x26,0x84,0xcc,0x3f,0xe1,0xb0,0x63,0xef,0x3a,0x5f,0x5b,0xf0,0xab,0xe3,0xaf,0x29,0x28,0xa5,0x1c,0x8d,0xb6,0xb0,0x84,0x22,0xa4,0xa9 +,0x90,0x52,0xc2,0x43,0x48,0x06,0x58,0x06,0xf8,0x91,0x13,0x9a,0x29,0xc1,0x2b,0xc4,0x18,0xe1,0x60,0x16,0xa4,0x33,0x07,0x69,0x45,0x50,0x0b,0x58,0xa2,0x23,0x08,0x17 +,0x0a,0x01,0x46,0x42,0x60,0xa0,0x94,0x2e,0x14,0x12,0x8d,0x06,0xa1,0x40,0xa8,0x50,0x8a,0x12,0x11,0x84,0x82,0x66,0x11,0x18,0x44,0x66,0x11,0x1a,0xbd,0xf9,0xd5,0x56 +,0xaf,0x7a,0xcc,0x82,0xf2,0x12,0xa4,0x9a,0xe9,0xcd,0xb6,0xe3,0x23,0xab,0xbd,0x08,0x1c,0x4d,0x1f,0x03,0xff,0x7f,0xc4,0xf1,0xfb,0x4f,0x8d,0xf7,0xbe,0x74,0xe7,0xee +,0x9a,0x7d,0x10,0xda,0x5d,0x2a,0x27,0xed,0xaf,0x0e,0x17,0xc3,0xd5,0xfb,0xd1,0x47,0xf6,0x26,0x4d,0xc1,0x16,0x82,0x34,0xdd,0xa9,0x3d,0xe9,0x8b,0x17,0xf0,0xdc,0x1c +,0xce,0xab,0xf2,0x6f,0x32,0xf5,0x5a,0x7d,0x3b,0xfc,0xfd,0xd3,0x31,0x28,0xe7,0xb8,0xb7,0xb3,0x8d,0xc1,0xdc,0x07,0xbb,0xee,0x48,0xf7,0x25,0xf5,0xa6,0x80,0x07,0x9a +,0x82,0x67,0xdb,0x41,0x02,0x58,0xd6,0x0b,0x96,0x9d,0x3d,0xcb,0x01,0x79,0x02,0x44,0xc2,0x77,0x5c,0x1e,0xb0,0x05,0xc0,0x02,0x24,0x40,0xe0,0xff,0xf1,0x50,0x80,0x25 +,0x1f,0xfc,0x21,0x0a,0xcf,0x5f,0xee,0xff,0xff,0xbc,0xb2,0x61,0x21,0x08,0x2a,0x14,0x13,0x84,0x82,0xa1,0x40,0x98,0x54,0x28,0x42,0x38,0xc1,0xcc,0xf3,0xeb,0x89,0x32 +,0xe9,0xbe,0x35,0xef,0xd6,0x5a,0x56,0xb1,0x69,0x61,0x7c,0xd7,0xeb,0xef,0x17,0xf1,0xd0,0x2d,0x9e,0x81,0xfc,0xc6,0xe9,0xfe,0xce,0x3f,0xd2,0xe3,0xc2,0xe9,0xae,0xde +,0xa1,0xfe,0xee,0xd3,0xf9,0xba,0x88,0x7f,0x18,0xfb,0x7c,0x0f,0x19,0x83,0xdc,0x87,0x01,0xbf,0x9a,0xa9,0xc2,0xd9,0x52,0x62,0xa5,0xb6,0xa2,0x23,0x4e,0xa4,0xa9,0x8f +,0x29,0x61,0x7d,0x4b,0x68,0x92,0x09,0xf3,0x1c,0xa9,0x14,0x26,0xbb,0xb0,0xa8,0x2d,0x23,0xa1,0x41,0x82,0x2a,0x29,0x61,0x5b,0xa8,0x80,0x0c,0x56,0x05,0x53,0x02,0x77 +,0x54,0x49,0xaa,0x91,0x01,0x19,0x10,0x02,0x85,0x80,0x6b,0x16,0x23,0x41,0x70,0x20,0x02,0xb4,0x82,0x82,0x70,0xb0,0x94,0x28,0x35,0x09,0x05,0x46,0x82,0x20,0xa0,0xd4 +,0x44,0x23,0x08,0x84,0xc2,0x22,0x30,0x89,0x4c,0x22,0x65,0x5f,0x7f,0x8f,0xd3,0x5e,0xdd,0xaf,0x9d,0x65,0x53,0x82,0xa4,0xc7,0x0f,0x3c,0xcb,0xa9,0x5f,0x19,0xdb,0xeb +,0x3d,0xb7,0xc0,0xe3,0xe3,0x70,0x9e,0xbd,0x47,0xb3,0xd6,0x8e,0xee,0x77,0xf9,0x9e,0xef,0x2e,0x2f,0xde,0x6f,0x7b,0xad,0xda,0xda,0x78,0xf8,0xb4,0x99,0x48,0x35,0xfb +,0x3e,0x52,0xf7,0xbe,0x82,0xf8,0xbe,0x2c,0x75,0xbb,0x3e,0x14,0x75,0xd3,0x50,0xeb,0xda,0x08,0xe6,0xce,0x4a,0x5e,0x17,0xfd,0xd6,0xad,0xf3,0xdd,0x92,0x89,0x1b,0xb0 +,0x7b,0x8b,0xdc,0x14,0xb5,0x20,0x5c,0xba,0xc0,0x7b,0xf0,0x10,0x85,0x4b,0x8e,0x60,0x8d,0xe2,0x22,0x00,0x54,0x3b,0xf4,0x0a,0x2d,0x32,0xe2,0x20,0x04,0xc1,0x40,0x02 +,0x08,0x00,0xe0,0xff,0xf1,0x50,0x80,0x29,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0xfa,0xec,0xff,0xfc,0xb0,0x61,0x20,0x98,0x4a,0x14,0x0b,0x05,0x02,0xa1,0x40,0xb8,0x50,0x2c +,0x15,0x0a,0x05,0x44,0x82,0x20,0x98,0x44,0x24,0x23,0x08,0x88,0xc2,0x27,0x30,0x89,0x5d,0xb8,0xaa,0xeb,0x8f,0xb6,0x97,0xbd,0x6b,0xd7,0x5c,0xaf,0xae,0x6b,0x4a,0x9a +,0xbf,0x3e,0xaa,0xeb,0x2b,0x5e,0x73,0x7d,0x7d,0xf4,0x39,0x0f,0x6d,0x1f,0xbb,0xf9,0xb7,0x03,0xfa,0x23,0xb3,0xe4,0x5c,0x5b,0x89,0xfb,0x2d,0x2c,0x71,0x63,0xc1,0x8e +,0x9c,0x43,0x2d,0x5b,0xbf,0xa6,0x53,0x27,0x2f,0xe0,0xe7,0xa5,0xfd,0xed,0x72,0xb7,0x28,0x92,0x15,0xf8,0xb9,0x75,0x54,0x86,0x7f,0xea,0xe5,0x26,0xc7,0x58,0xe5,0xc5 +,0xf9,0x12,0x34,0x3e,0x6b,0x0c,0x69,0xb6,0x9d,0xeb,0x51,0x35,0x16,0x42,0xcd,0xf5,0x92,0x40,0xf5,0xef,0x50,0x49,0x22,0xe8,0x84,0x84,0xc4,0xe8,0x8c,0xc9,0x22,0x60 +,0xb0,0x39,0x11,0xb1,0x00,0x7a,0xc0,0xa0,0xb8,0x02,0x87,0x2b,0x00,0x64,0x0a,0x81,0x54,0xa1,0x20,0xb8,0x50,0x4a,0x24,0x23,0x05,0x06,0x41,0x40,0xa8,0x50,0x44,0x14 +,0x11,0x05,0x02,0x42,0x30,0x88,0x4c,0x42,0x13,0x08,0x94,0xc2,0x24,0x75,0xef,0x57,0x7d,0xf1,0x91,0xbb,0x19,0x0d,0x12,0xf7,0x3d,0xb7,0xa9,0xbe,0xa7,0x79,0xfa,0xcf +,0x1d,0x7b,0x7b,0x68,0x39,0x60,0xf3,0xfe,0x77,0xc8,0xe8,0x3d,0xdd,0xa6,0xc7,0xdd,0xf2,0x5e,0xe6,0x0a,0x3a,0x73,0x7e,0x55,0xd7,0x69,0xef,0x1c,0xbf,0x67,0x67,0xe8 +,0xba,0x1f,0x62,0xf9,0xbb,0xf5,0xe4,0xe1,0xdc,0x5b,0x44,0xc6,0x4d,0xe7,0xdc,0xb0,0xa7,0x07,0x5f,0x67,0x2a,0xdd,0x4d,0x1f,0x04,0x13,0x8c,0xf4,0x56,0xb0,0xa1,0xef +,0x1c,0x69,0x4e,0xb5,0x53,0x79,0xed,0x3b,0xe8,0x90,0x29,0x6a,0x3f,0x2c,0x17,0xf7,0x57,0x05,0xd7,0x52,0xa7,0xba,0x40,0x00,0x81,0x26,0x9a,0x00,0x94,0x17,0x11,0x08 +,0x44,0x00,0xf4,0x60,0x14,0x00,0x50,0xb0,0x13,0x03,0x80,0xff,0xf1,0x50,0x80,0x26,0xbf,0xfc,0x21,0x0a,0xcf,0x4f,0x7e,0xff,0xff,0xff,0xae,0x60,0xa0,0x58,0x2a,0x14 +,0x0a,0x84,0x82,0xc3,0x51,0x38,0x50,0x2a,0x16,0x0a,0x85,0x06,0x44,0x10,0x90,0x44,0x46,0x11,0x39,0x88,0x4a,0xf7,0xbe,0x33,0x7e,0x5c,0xeb,0x09,0x39,0xbb,0xcb,0x8a +,0x5c,0xad,0x71,0xbc,0x55,0xd5,0x7c,0x56,0x54,0xfd,0xf8,0x0f,0xe3,0xff,0xd9,0xf9,0xbc,0xf7,0xbf,0x04,0xa7,0xcb,0x89,0x1f,0x2f,0xca,0x8c,0x43,0xdb,0x6f,0x6e,0x7a +,0xca,0x7c,0xd7,0x5e,0xd4,0x48,0xe2,0x8b,0x4f,0xcd,0x78,0x3f,0x8b,0x8b,0xf1,0x29,0xdb,0xe9,0x17,0x73,0x54,0x4e,0xb2,0xe6,0x32,0xe7,0x65,0xd0,0x87,0x23,0x89,0x7c +,0x2a,0x23,0x0f,0x5a,0xa8,0xde,0xca,0x5f,0xb0,0xa4,0x0f,0x58,0x52,0xe9,0xa3,0x65,0xe7,0x8e,0x20,0x52,0x65,0xae,0xc0,0x8c,0xbb,0x05,0x67,0x0b,0x4f,0x85,0xa8,0xb3 +,0x1a,0xd7,0x55,0xec,0x80,0x03,0xbb,0xe0,0x00,0x4d,0x30,0x01,0x9d,0x7b,0x00,0x4c,0x55,0x30,0x2b,0x08,0x4c,0x35,0x0b,0x85,0x06,0xa1,0x41,0x28,0x50,0x26,0x14,0x21 +,0x05,0x42,0x41,0x41,0x09,0xcc,0x42,0x96,0xbd,0x6f,0xef,0xe3,0x3a,0xc8,0xde,0x93,0x11,0x48,0xba,0xbb,0xaf,0xd7,0xed,0x4f,0x64,0x71,0xc7,0xed,0x7f,0x7a,0xb1,0xca +,0xb7,0xd3,0xcf,0x5f,0x43,0xf8,0x1e,0x5e,0x79,0xa3,0x74,0xbf,0xc1,0x31,0xb1,0x8e,0xa3,0xbc,0x73,0x70,0x94,0x3d,0x57,0xca,0xcb,0x0d,0x76,0xc7,0x12,0xf0,0xe7,0xeb +,0xbd,0x49,0xf7,0x83,0x76,0xf4,0x7a,0x6d,0xcf,0x4d,0x07,0xa7,0xec,0x71,0x24,0xb2,0xa3,0xc4,0xf5,0x4c,0x70,0x50,0x7c,0x70,0xe1,0x61,0xd0,0x9f,0x29,0x5a,0xb6,0xa4 +,0xa8,0x12,0x59,0x78,0xcc,0xb1,0xfb,0xbb,0x96,0x0b,0x1c,0xcf,0x58,0x0e,0xe0,0x00,0xb8,0x08,0x80,0xb8,0x17,0x02,0x21,0x24,0xc6,0x6b,0x84,0xc0,0xb0,0x20,0x03,0x80 +,0xff,0xf1,0x50,0x80,0x26,0x1f,0xfc,0x21,0x0a,0xcf,0xaf,0x7b,0xdf,0xf7,0xfd,0xb4,0x62,0x20,0x54,0x24,0x15,0x0a,0x09,0x48,0x41,0x50,0xa0,0x54,0x24,0x41,0x09,0x08 +,0x42,0x41,0x18,0x29,0xac,0xd6,0xb3,0x9e,0x2b,0x12,0xfb,0xd4,0x89,0x57,0x96,0x9a,0x54,0xc7,0x19,0x56,0xbd,0xcf,0xc7,0x40,0x78,0xd7,0xed,0x7f,0x69,0xed,0xff,0x6f +,0x82,0x47,0xbb,0x68,0xe6,0x9f,0x4c,0x2b,0x6b,0xf0,0x3e,0xc7,0xc8,0xa5,0x6a,0xff,0xd8,0x6d,0x9f,0x2f,0x93,0xa9,0x0f,0x29,0xc2,0xf4,0xb6,0xae,0xa6,0x47,0xee,0x32 +,0xdb,0x9b,0xb8,0xb6,0xd2,0x42,0xd0,0x85,0xcb,0x5b,0x39,0xde,0xcf,0xc7,0x78,0x5b,0x21,0x6c,0x21,0x41,0x6b,0x9d,0x47,0x47,0x05,0xcc,0x42,0xbc,0x21,0x1a,0xa6,0xad +,0x52,0x48,0x08,0xc8,0x07,0x51,0xc4,0x20,0x17,0x2c,0x59,0x58,0x05,0xfb,0xc0,0x03,0x30,0x50,0x88,0x5c,0x0b,0x80,0xa0,0x51,0x18,0x58,0x6a,0x16,0x0a,0x10,0x82,0xa1 +,0x40,0xa8,0x50,0x4a,0x16,0x0a,0x04,0x84,0x81,0x20,0x99,0x44,0x46,0x11,0x31,0x88,0x44,0xfb,0x78,0xbb,0xd7,0xaf,0x8f,0x5c,0x56,0xf8,0xa9,0x36,0x95,0x29,0x75,0xd5 +,0x75,0x79,0xbe,0x1c,0xe3,0x53,0xeb,0x17,0xd0,0x72,0x70,0xfc,0xdf,0x28,0x1e,0x5c,0x51,0xf6,0xed,0x8e,0xcb,0x8d,0xfe,0xe4,0x3b,0x69,0xf9,0xab,0xd9,0x77,0x2f,0x57 +,0x34,0xaf,0xcc,0xe0,0x4f,0xb9,0xf8,0x40,0x91,0x9f,0x47,0x63,0x2b,0x20,0x76,0xaf,0x65,0x8d,0x6b,0xd8,0xe6,0xd3,0x35,0x5e,0x78,0xf4,0x3c,0xb2,0xc7,0xca,0xbd,0xa3 +,0xcc,0x66,0x7f,0x12,0xeb,0x16,0x1e,0x63,0x8f,0xc5,0x7a,0x30,0x3d,0x72,0x9d,0xd0,0x83,0xd1,0xa7,0x12,0xbc,0xc1,0x8c,0x3b,0x82,0x00,0x4e,0x1f,0x50,0xa6,0xd4,0x43 +,0xc2,0x16,0x2c,0x21,0x12,0x21,0x62,0xc0,0x07,0xb8,0x0f,0x58,0x02,0x22,0xe0,0x38,0xff,0xf1,0x50,0x80,0x26,0xbf,0xfc,0x21,0x0a,0xcf,0xaf,0xfe,0xee,0xff,0xfc,0xb3 +,0x60,0xb8,0x50,0x84,0x13,0x0a,0x84,0x82,0xa1,0x41,0x28,0x4c,0x2a,0x12,0x0a,0x05,0x42,0x43,0x40,0x90,0x44,0x24,0x11,0x8b,0x35,0x57,0x73,0xdb,0xf6,0xeb,0x65,0xb9 +,0xd2,0xa5,0xaa,0xd1,0x3a,0xdf,0x19,0xbd,0x64,0x5d,0xe5,0xff,0x8a,0x05,0xe7,0x76,0xdd,0x0f,0x5e,0x7d,0x57,0x74,0xc3,0xf5,0x5e,0xd6,0x4f,0xb8,0x17,0xe1,0x17,0xf7 +,0x6e,0x47,0x27,0xee,0xfd,0x7e,0x04,0xf9,0xee,0xe8,0x4c,0xbe,0xdc,0xc5,0xd2,0x8e,0x66,0x7f,0xf4,0x19,0x47,0x57,0x5f,0xb5,0x0e,0x3d,0x5b,0x9c,0xc6,0x49,0xa3,0xbb +,0x62,0xe8,0x7e,0x82,0x0b,0xd3,0x9b,0x62,0x8b,0x56,0x35,0x58,0x5d,0x69,0x98,0x11,0x2e,0x15,0x12,0x10,0x71,0x2e,0xa9,0x70,0x2f,0x40,0x16,0x48,0x58,0xb0,0x98,0x48 +,0x98,0x75,0x92,0x80,0x22,0xb0,0x26,0xb0,0x49,0x40,0x90,0x0a,0x44,0x12,0x85,0x04,0xc1,0x50,0xa0,0x48,0x2a,0x14,0x0a,0x89,0x04,0xc1,0x43,0x90,0x8c,0x4a,0x13,0x20 +,0x8c,0xc4,0x26,0x7a,0xca,0xad,0x6f,0xcf,0x9f,0x79,0x53,0x2a,0xad,0x97,0x57,0x49,0xed,0xcf,0x55,0x0d,0xa7,0x4e,0x75,0x5f,0x5f,0x1c,0x0e,0xdb,0x42,0xbc,0xfe,0x6d +,0xf5,0xdf,0x49,0x3d,0x1d,0xaf,0x33,0x80,0x77,0xbb,0x6b,0xf5,0x65,0xc5,0xb7,0x15,0xd5,0xc7,0xb9,0x41,0x4a,0xaf,0xaf,0xf4,0x42,0xde,0xef,0xf0,0xb3,0xec,0x8f,0xe9 +,0x9b,0xb0,0x75,0xa1,0x1e,0x0c,0x7e,0x3f,0xb9,0x11,0x63,0xfa,0xa9,0x79,0x2b,0x3b,0x54,0x64,0xc4,0x8b,0xdd,0x7a,0xe3,0x4f,0xc4,0xfa,0xe0,0x0f,0x00,0x20,0x51,0xeb +,0x50,0x0e,0xd7,0xdd,0x0b,0x8e,0xf0,0x83,0xbc,0x27,0x04,0x50,0xdb,0xb1,0x05,0xe5,0x50,0x3b,0x46,0xee,0xe8,0x08,0x0f,0x74,0x50,0x16,0x42,0x73,0x14,0xa8,0x2d,0x54 +,0x80,0x58,0x0b,0x00,0xe0,0xff,0xf1,0x50,0x80,0x25,0x7f,0xfc,0x21,0x2a,0xcf,0xeb,0xfe,0xfe,0xdf,0xfc,0xaf,0x43,0x10,0x50,0x44,0x17,0x0a,0x05,0x82,0x82,0x60,0xa0 +,0x54,0x48,0x12,0x28,0x84,0xc2,0x21,0x31,0x09,0x8c,0x42,0x56,0x62,0xf7,0xe5,0xbf,0x3e,0xaf,0x7c,0x56,0xfa,0xaa,0xbb,0xc2,0x44,0xe9,0xb4,0xb6,0xfa,0x9b,0xbb,0xfd +,0x7c,0x8e,0xd3,0xfc,0xdf,0x34,0xfa,0x26,0x88,0xf8,0xbc,0x9d,0xb7,0x8f,0x07,0x8a,0x3e,0xd7,0x4c,0x83,0xbb,0x4e,0xe8,0x60,0xee,0x90,0xb3,0x87,0x52,0x37,0xf4,0xfe +,0x3e,0x82,0xab,0xf7,0x52,0xaf,0x58,0xf4,0xe4,0x1d,0x3f,0x7e,0xe5,0x3d,0x54,0x0a,0xcc,0x28,0xb2,0x8b,0x43,0x05,0x97,0x95,0xba,0x51,0xa2,0x29,0x75,0x94,0xf0,0xd8 +,0xbd,0x2b,0xd8,0x58,0xef,0xc0,0x77,0x01,0x31,0x52,0xc9,0xa5,0x02,0x5c,0xc1,0x10,0xa0,0xaa,0x02,0x53,0x05,0x91,0xc6,0xf7,0x14,0x00,0x3d,0x73,0x20,0x00,0x68,0x30 +,0x29,0x60,0x11,0x09,0x81,0x56,0x41,0x42,0xa8,0x58,0x44,0x24,0x23,0x05,0x08,0x41,0x40,0x90,0x94,0x26,0x12,0x09,0x88,0x5c,0xae,0x5c,0x6e,0xbf,0x1f,0xa6,0xbe,0x3d +,0xef,0x25,0x5b,0x25,0x5a,0xf4,0xe7,0xda,0xf2,0xf5,0xdd,0x5e,0x71,0xac,0xe0,0xe8,0x7d,0xb5,0x87,0xcc,0x7e,0x85,0xc9,0xb7,0xb7,0xce,0x5d,0x3e,0xb2,0xe4,0xa8,0x7a +,0x44,0x7d,0x78,0xc3,0x3c,0x30,0xee,0xcf,0x86,0xc5,0x05,0x7d,0x27,0x8c,0x59,0xbf,0x70,0x5b,0x97,0x48,0x3b,0x79,0xc3,0x6f,0x0a,0xcd,0x77,0x9d,0xc4,0xd3,0x5f,0xca +,0x11,0xf6,0x41,0x28,0xe0,0xe0,0x5d,0xbe,0x08,0xee,0x18,0x7e,0x96,0x3e,0x0f,0xc8,0x07,0xae,0x52,0x0b,0x17,0x9d,0xc3,0x68,0x39,0x20,0x5d,0x98,0x0b,0xce,0x05,0x05 +,0x5d,0x04,0x88,0x94,0x12,0x4c,0x05,0x00,0xb8,0x02,0x20,0x14,0x00,0x26,0x88,0x0e,0xff,0xf1,0x50,0x80,0x25,0x3f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x74,0x16,0x49,0x0c +,0x8c,0x6a,0xb4,0x92,0x49,0x7a,0x09,0xbe,0xb4,0x32,0x22,0xc9,0x0d,0x7a,0x1d,0x37,0xb6,0x08,0xed,0x5c,0xcd,0x76,0xcd,0x3b,0xda,0xd9,0xf0,0x73,0xa4,0xa0,0x25,0xd9 +,0x56,0xcc,0x38,0x30,0x9c,0xe8,0x07,0x21,0x3e,0xbd,0xe7,0xa9,0x03,0x68,0xf5,0xe6,0x68,0x2f,0x5f,0xf6,0x3a,0xac,0x39,0x6b,0x81,0x4a,0xd9,0x3d,0x0e,0xaa,0xff,0x79 +,0x4a,0xe2,0xea,0x12,0xf7,0x8e,0x40,0xaa,0x2e,0xde,0x9f,0x89,0x01,0xaa,0x6e,0xf4,0x1e,0xb2,0x9a,0xca,0xec,0x6f,0xba,0x3c,0x95,0x8a,0x18,0x21,0xb0,0x14,0xfe,0x9c +,0x7c,0xd7,0xe5,0xf0,0x54,0x14,0x0a,0x86,0x79,0x43,0x12,0x16,0xa0,0x84,0x82,0x20,0x6e,0x24,0x90,0xa4,0x40,0x17,0x04,0xc4,0x4b,0x80,0xb8,0xa8,0x60,0x29,0x60,0xb3 +,0x46,0x48,0x5a,0x52,0xd6,0x5b,0x81,0xd6,0x2e,0x74,0x87,0x10,0xfa,0xc1,0x1b,0xc5,0x6d,0x60,0x45,0x00,0x86,0x6b,0x14,0xdd,0xcf,0x5a,0x6c,0xc6,0xf2,0x9f,0x25,0x6e +,0xae,0x33,0xc4,0x76,0xf6,0x06,0x17,0x94,0x95,0x93,0x77,0x09,0x24,0xb9,0x36,0x77,0x16,0xe2,0x69,0xec,0x91,0x26,0x91,0x04,0xc3,0x4f,0xf4,0x4e,0x81,0x0f,0xc5,0x60 +,0xf8,0xfd,0xfe,0x97,0x8c,0x35,0x36,0xa6,0xe9,0xf9,0x86,0xde,0x1d,0xcf,0x6d,0x6e,0x95,0xb0,0x03,0xfb,0xc5,0xb3,0xbd,0x1b,0x52,0x6b,0x28,0x09,0x24,0xaf,0x89,0x60 +,0x3f,0x52,0x31,0x8d,0xf8,0x3e,0xd3,0x52,0xd4,0x83,0x85,0x1b,0x7d,0xa0,0x87,0x6d,0xc4,0x8c,0x93,0xcf,0xec,0x76,0x5e,0x30,0x09,0x47,0x43,0x36,0x1e,0xbe,0xc5,0x69 +,0xda,0xd0,0x54,0x69,0xa4,0xa4,0x1f,0x2d,0x04,0xe9,0xf8,0x1d,0x29,0x28,0x94,0x00,0x2e,0x79,0x93,0x4e,0x04,0x02,0x62,0xe4,0xc7,0xff,0xf1,0x50,0x80,0x27,0x5f,0xfc +,0x21,0x6a,0xcf,0xfb,0x7f,0xff,0xdf,0xfe,0xb7,0x61,0x20,0xd8,0x24,0x14,0x1a,0x85,0x82,0x81,0x21,0x28,0x49,0x02,0xb3,0x08,0x84,0xc2,0x25,0x67,0x9a,0xf3,0xeb,0x8c +,0x75,0xdd,0x4b,0xa0,0x8d,0x64,0x94,0x4a,0x5e,0xb1,0xed,0xcf,0x5e,0x26,0xbf,0x01,0x97,0x57,0x6f,0x2f,0xf9,0x1c,0xab,0x5a,0xe9,0x3c,0xdc,0xa7,0x65,0xe2,0x9e,0x45 +,0x21,0x1f,0x0c,0x3f,0xd5,0xaf,0xe7,0xf0,0x5a,0xaf,0x04,0x8e,0xee,0xb1,0x86,0xe3,0x59,0xa3,0x91,0xa6,0xd4,0xd2,0x53,0x25,0xe2,0x1b,0x16,0xf9,0x94,0x9b,0xde,0xb6 +,0xae,0xa8,0xf7,0xa9,0x6a,0xc5,0x4d,0x37,0xaf,0xd1,0x72,0x10,0x2d,0x68,0xc7,0x25,0xac,0x80,0x2e,0x9d,0xd3,0x11,0xa8,0x82,0x8a,0x14,0x2c,0x99,0x33,0x1d,0x09,0x1d +,0xf0,0x5c,0x11,0x7a,0xe0,0x06,0x50,0x58,0x02,0x65,0x05,0x80,0x5c,0x0a,0x95,0x13,0x11,0x04,0x61,0x41,0x30,0x50,0x46,0x14,0x13,0x09,0x02,0xa1,0x40,0x98,0x54,0x26 +,0x25,0x09,0x88,0x82,0x22,0x30,0x88,0x4c,0x22,0x13,0x08,0x8c,0xc2,0x22,0x6e,0xf9,0x57,0x99,0xe2,0x5e,0xf4,0x4c,0xa9,0x74,0xbb,0xa6,0xab,0x8f,0x9f,0xaf,0x1e,0x7c +,0x75,0xaa,0xd7,0x89,0xe6,0xfa,0x0f,0x37,0xc0,0xf5,0xcf,0xc3,0x61,0x6c,0x2d,0xbb,0x97,0xff,0x0b,0x71,0xee,0xae,0xef,0x41,0x97,0xf6,0x17,0x34,0x8f,0xbd,0xfe,0x3a +,0x7b,0x9a,0xd7,0xd7,0xa5,0x62,0x7a,0x89,0xf4,0x68,0xd4,0xa6,0x67,0x5f,0xfd,0x38,0x71,0x70,0xe1,0x2e,0xee,0x7e,0x74,0xed,0x4f,0xfe,0xaa,0x20,0x5d,0xb9,0xb0,0xfa +,0x4d,0xcf,0x5e,0xee,0xe0,0x00,0xf3,0xe0,0x3b,0x9d,0xf0,0xde,0xbb,0xc2,0xb6,0x9c,0x74,0xf0,0xa5,0x13,0x90,0x99,0x4a,0x9a,0xe9,0x19,0x03,0xba,0xb5,0x48,0x49,0x58 +,0x1e,0xe4,0x41,0x8c,0x0f,0x70,0x01,0x20,0x44,0x17,0x55,0x72,0x93,0xb7,0x70,0x00,0xb8,0x20,0x07,0xff,0xf1,0x50,0x80,0x26,0xbf,0xfc,0x21,0x0a,0xcf,0x3d,0x7f,0x7f +,0xfd,0xfe,0xb6,0x61,0x28,0x50,0x2a,0x34,0x0b,0x04,0x82,0x84,0x30,0xa0,0xc9,0x02,0xa3,0x08,0x8c,0xc2,0x22,0x38,0xe3,0xb7,0x0c,0xd6,0x73,0xad,0x39,0xb9,0xb5,0xab +,0x59,0x2c,0x42,0xb5,0x5e,0x7b,0x6b,0x8f,0xc7,0xd0,0xfc,0xe3,0xd2,0xb7,0x7e,0xbc,0xf4,0x3a,0x8e,0x9f,0xf6,0xf0,0x1b,0xbd,0x1a,0xb2,0x7f,0xd7,0x4b,0xc0,0xaf,0xe1 +,0x5f,0xe0,0x73,0x2e,0xab,0xb5,0xa3,0xb3,0x5a,0x87,0x77,0x17,0xed,0x37,0xf3,0xbf,0x48,0xad,0x2c,0x32,0x53,0xcf,0xe3,0xf4,0x9c,0x39,0x88,0x28,0x34,0x22,0xc0,0x98 +,0xca,0xf3,0x95,0x65,0x4b,0x7f,0x35,0xe7,0xa4,0x9f,0x49,0xdc,0xb7,0xe5,0x72,0x3f,0x92,0x2b,0x4d,0x7f,0x40,0x4d,0x26,0x41,0xdc,0xe8,0x9d,0xe6,0xb9,0x40,0x41,0x21 +,0x32,0xf4,0x0e,0xe8,0x56,0xa0,0x95,0x00,0xbc,0x13,0x03,0xdc,0x01,0x40,0x22,0x05,0x5a,0x0d,0x82,0x81,0x20,0xa8,0x50,0x2a,0x16,0x0a,0x08,0x82,0x81,0x20,0xa0,0x54 +,0x2c,0x14,0x21,0x84,0x82,0x62,0x10,0x98,0x44,0x86,0x21,0x4b,0x73,0x77,0x2d,0xaf,0x5e,0x7c,0x59,0x5a,0xaa,0xae,0x2a,0xaa,0xf5,0xf5,0xeb,0xd9,0xaf,0xdb,0xe3,0xd3 +,0xf5,0xab,0x9e,0x3c,0xd7,0x43,0x94,0xef,0x9d,0x1f,0xdd,0x7f,0xfa,0xbf,0x8e,0xbe,0x57,0xc5,0xc8,0x74,0x14,0x21,0x3c,0x73,0xab,0x8f,0xc7,0x65,0xf2,0xed,0x19,0xb5 +,0xab,0x1e,0xed,0x0d,0x04,0x4f,0xe8,0x5c,0x27,0xa8,0x41,0xb8,0xdf,0x57,0x0f,0x65,0x07,0x14,0xbb,0xd2,0xa7,0xff,0x29,0x4b,0xfa,0x13,0x6d,0x5d,0xf4,0x76,0x20,0x8c +,0x8f,0xd1,0x04,0x26,0x7a,0x3e,0xfc,0x40,0x33,0xa5,0x08,0x86,0x72,0x23,0x4f,0x34,0x95,0x61,0x3d,0x60,0x14,0xb3,0xfb,0x2a,0x88,0x06,0xa0,0x04,0x91,0x00,0x04,0xec +,0x02,0x6a,0x82,0x20,0x2c,0x02,0x00,0x38,0xff,0xf1,0x50,0x80,0x28,0x7f,0xfc,0x21,0x0a,0xcf,0xdd,0x72,0x6f,0xff,0xfd,0xb5,0x61,0x20,0x58,0x2a,0x12,0x0a,0x0c,0x82 +,0xa1,0x41,0x18,0x48,0x28,0x15,0x0a,0x05,0x82,0x41,0x10,0x90,0x50,0x22,0x12,0x08,0xc9,0x33,0xef,0xeb,0xae,0x6f,0x35,0x5b,0x97,0x55,0x75,0x53,0x8a,0xc9,0x6a,0x88 +,0xa6,0xa6,0xf5,0x25,0xd7,0xfc,0xff,0x81,0x4f,0xeb,0xb2,0x9f,0xff,0x5c,0x64,0xf0,0x7f,0x7c,0xad,0x6d,0xb9,0xb9,0xf7,0x40,0xdf,0xf3,0xc4,0xb4,0x65,0x3d,0xa4,0x7c +,0x39,0x9d,0x0b,0x47,0x91,0xef,0x43,0xdd,0xdd,0x41,0x3b,0x97,0xb1,0x38,0xbf,0x43,0xdd,0xec,0x5c,0xde,0xa9,0x2c,0x5a,0xe7,0xa2,0xb0,0x1a,0xd3,0x3a,0x9c,0xbd,0x31 +,0x70,0x36,0x52,0xda,0xad,0x1b,0x94,0x29,0xb3,0x8a,0x25,0x36,0x4d,0x05,0xa8,0x47,0x35,0x18,0xa4,0x5c,0x50,0x31,0x4a,0x05,0xac,0x4d,0x46,0x19,0x0a,0x89,0x52,0x99 +,0x14,0x03,0x00,0x2f,0x88,0xc2,0x05,0x42,0x80,0xac,0xc5,0xc0,0x22,0x05,0x6a,0x11,0x82,0xe1,0x40,0xa8,0x50,0x2c,0x14,0x19,0x05,0x02,0x41,0x41,0xa8,0x48,0x48,0x15 +,0x09,0x84,0x42,0x61,0x11,0x18,0x84,0xe6,0x11,0x21,0x36,0xce,0x3a,0xe7,0x35,0xcd,0xaf,0x69,0x92,0x4a,0xd6,0xab,0xcf,0xbf,0xfb,0xff,0x14,0xfd,0x7e,0xde,0x73,0x7f +,0xed,0xfb,0x77,0x7f,0xef,0xf0,0x3c,0x1e,0xef,0x5e,0x7f,0xdf,0xc5,0x3b,0x77,0x2b,0x70,0xd8,0xf9,0x16,0xdf,0x87,0x32,0xd9,0x49,0xef,0x2f,0x4d,0x67,0x30,0xfe,0xeb +,0xed,0x74,0x8e,0xfb,0xd9,0x78,0x3a,0x30,0x7f,0x3b,0xdc,0x3c,0x9d,0x8e,0x7e,0xb7,0xfa,0x9f,0x95,0xdc,0xaa,0xbf,0x44,0xc4,0xe2,0xa9,0xb4,0xeb,0xde,0xab,0x77,0xfd +,0xa1,0x8c,0xf5,0x81,0x3f,0x56,0xda,0xd8,0xa6,0x70,0xf8,0x6f,0x58,0x0d,0xb0,0x77,0x84,0x8e,0x80,0x12,0x95,0x41,0x39,0x84,0xc1,0x10,0xbe,0xab,0x5a,0xb2,0xda,0x50 +,0x01,0xdd,0x09,0x85,0xcc,0xc4,0x82,0x20,0x17,0x03,0x80,0xff,0xf1,0x50,0x80,0x2a,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0xde,0xda,0xff,0xfc,0xb1,0x61,0xa0,0x58,0x28,0x15 +,0x0a,0x14,0xc2,0x81,0x20,0xa0,0x4c,0x28,0x16,0x09,0x09,0x42,0x81,0x50,0x90,0x44,0x24,0x11,0x21,0x88,0x54,0xdd,0x6a,0xbc,0xf3,0xed,0xee,0xd5,0x4a,0x54,0xbd,0xcb +,0x25,0x25,0xd2,0xf8,0x73,0x69,0x9a,0x3f,0xef,0x62,0xcf,0x67,0x9c,0xb8,0x4b,0xfb,0x7e,0x25,0xe8,0xb9,0xef,0x1b,0xff,0x17,0xea,0x34,0xcf,0xdb,0x21,0xf4,0xab,0x72 +,0x3a,0xbc,0x2b,0xfc,0xb0,0xaa,0x7a,0x7c,0x5e,0xce,0xef,0x9d,0x0c,0xa2,0x8c,0xed,0xae,0x2b,0x97,0x48,0xb8,0x77,0x15,0x95,0x4e,0xd5,0x18,0xb4,0xf7,0x21,0x09,0x2a +,0x51,0xcb,0x53,0xeb,0x12,0x4f,0x6a,0x3d,0x89,0x99,0x3b,0x74,0x65,0xa2,0xee,0x72,0x8a,0xf6,0xe2,0x0b,0x29,0x96,0x67,0x7a,0x21,0x17,0xba,0x16,0x09,0xc6,0x62,0x62 +,0xd7,0xd1,0x57,0x69,0x17,0x82,0x3d,0x40,0x95,0xc0,0x4a,0x45,0x3b,0xe1,0x0b,0xe1,0xad,0x6d,0x05,0x01,0x48,0x87,0x98,0x05,0x52,0x09,0x84,0x84,0x20,0xb0,0x48,0x2e +,0x14,0x0b,0x05,0x10,0xa1,0x40,0x90,0x4c,0x28,0x13,0x28,0x84,0xc2,0x24,0x31,0x08,0xc9,0xe3,0x55,0x5f,0x17,0xee,0x56,0xab,0x13,0x2e,0x2a,0x2d,0xae,0xbb,0xe2,0x7f +,0xe5,0xff,0x8f,0xf3,0xff,0x1e,0x7d,0xbb,0x79,0xff,0xdb,0xa1,0xad,0x34,0x1a,0x72,0x1e,0xfe,0x71,0xcc,0x3a,0x26,0xf9,0x0f,0x31,0xbb,0xc2,0xae,0xfb,0xde,0x56,0x74 +,0x8b,0x49,0x7b,0x13,0x84,0x6f,0x24,0xbe,0x9b,0xf2,0xbf,0x7b,0xbe,0xfc,0xd0,0x36,0xbc,0xbf,0xc5,0xb5,0x14,0xff,0x13,0xc9,0xbe,0x3f,0x76,0xfa,0xbb,0xce,0xcb,0x8a +,0xca,0xe8,0x54,0xc4,0xea,0xaf,0xff,0x13,0x35,0xe7,0xe4,0x8d,0x4b,0x68,0xcf,0xef,0xea,0x27,0x4f,0xb9,0xde,0xad,0x08,0xfb,0xa2,0x49,0x7a,0xcb,0x49,0x59,0xf9,0xa0 +,0x77,0x40,0x77,0x00,0x58,0x1d,0xe2,0x20,0x2d,0x3f,0xa6,0x3a,0x30,0x80,0xb9,0x2f,0x2d,0x93,0x0e,0xe0,0x01,0xeb,0x95,0x00,0x11,0x11,0x01,0xc0,0xff,0xf1,0x50,0x80 +,0x25,0xff,0xfc,0x21,0x0a,0xcf,0xbf,0xdf,0xff,0xff,0xff,0xb4,0x61,0xa0,0x58,0x2a,0x14,0x0a,0x85,0x04,0xa1,0x41,0x10,0x94,0x24,0x24,0x11,0x05,0x42,0x42,0x11,0x10 +,0x45,0x66,0x11,0x23,0x58,0xeb,0xbf,0x6c,0xcd,0x6e,0x15,0x50,0x5d,0xe2,0xd5,0x2e,0xac,0x7c,0x7d,0xb8,0xbe,0x37,0x5f,0xfe,0x5d,0x06,0xfd,0x76,0xdf,0xc3,0x8f,0xed +,0xf1,0xe5,0xf9,0x3d,0x07,0x57,0x65,0xaf,0x7e,0xb2,0xb6,0x3c,0x57,0xb1,0xf4,0x7a,0x77,0x45,0xe7,0xb3,0xb2,0x5f,0x88,0x3c,0x3a,0x91,0x09,0xce,0x79,0x57,0xd3,0x45 +,0xf1,0x72,0x5b,0xa2,0x0e,0x97,0xda,0xa2,0xdb,0x44,0x06,0xfd,0xf0,0x5d,0x16,0x70,0x79,0xfb,0x6c,0x2b,0x54,0xad,0xe9,0xb2,0x70,0x54,0x23,0x54,0xb1,0xbb,0xf5,0xb8 +,0x9c,0x2a,0xbd,0x00,0x21,0x5e,0x60,0x9c,0x6e,0x01,0x20,0x59,0xf6,0x51,0x72,0xee,0xa0,0x1d,0xf0,0x26,0x04,0x1e,0x48,0x02,0x60,0x28,0x02,0xad,0x44,0x81,0x61,0xa0 +,0x48,0x2a,0x14,0x23,0x05,0x04,0x41,0x41,0xa8,0x50,0x42,0x14,0x09,0x85,0x42,0x30,0x5e,0xf9,0xce,0xb3,0xa7,0x7a,0xa9,0x5c,0x73,0x55,0x75,0x25,0x5d,0xdc,0xcb,0x9f +,0x7e,0x3f,0x7f,0xeb,0x7d,0xf5,0xed,0xdd,0x75,0xfe,0x90,0x39,0xf1,0x6f,0xdc,0xed,0xf5,0x5b,0xc4,0x7a,0x37,0x37,0x43,0x90,0xee,0xd5,0x33,0xe7,0x3a,0xe6,0x97,0xa2 +,0x05,0x3d,0x3f,0x2f,0x4c,0xab,0x6f,0x3f,0xdb,0xba,0x11,0xaf,0xed,0xcd,0x34,0xde,0x48,0xf5,0xf3,0x6b,0x1c,0x7e,0x24,0x34,0x34,0x92,0xaf,0x0a,0xe4,0x95,0xbc,0x71 +,0xf6,0x56,0x29,0x5e,0x42,0x6a,0x56,0x80,0x08,0xf1,0x40,0xac,0x3d,0x05,0x6f,0x49,0xea,0x2a,0xa7,0x44,0xab,0x5b,0x00,0x05,0xab,0x70,0x00,0x4c,0x80,0x98,0x05,0xc0 +,0x54,0x5c,0x05,0x40,0x04,0x17,0x00,0x48,0x13,0x01,0xc0,0xff,0xf1,0x50,0x80,0x27,0x3f,0xfc,0x21,0x0a,0xcf,0x3f,0x5e,0xff,0xff,0xfc,0xb4,0x61,0xa0,0x58,0x2a,0x14 +,0x0a,0x85,0x02,0x41,0x30,0x90,0x4c,0x24,0x33,0x0a,0x05,0x42,0x82,0x21,0x88,0x48,0x22,0xb3,0x08,0x94,0x26,0x79,0xd7,0x71,0x75,0x97,0x9d,0x73,0x9a,0xad,0x6f,0x49 +,0x56,0x4c,0x8b,0xc7,0xb7,0x36,0xfe,0x78,0x05,0xfa,0xd7,0xcf,0x84,0xbf,0x19,0xd2,0x5f,0x93,0xa9,0xee,0x73,0x1e,0x5e,0x46,0x79,0xa9,0xaf,0x90,0xf6,0xd5,0x9a,0x5c +,0x3e,0x9e,0x23,0x6d,0x9f,0xdc,0xfd,0x93,0x9d,0x17,0x32,0xdc,0x95,0xcd,0x33,0x91,0x4a,0x78,0xd3,0x9b,0xbb,0x89,0x4a,0x67,0x1f,0x83,0x66,0xb2,0xaa,0x10,0x73,0x45 +,0xfb,0x51,0x48,0x4d,0xa9,0x49,0x88,0x77,0x92,0x2d,0xa8,0x90,0x13,0xb5,0xee,0x99,0x79,0x82,0xec,0x5a,0x2a,0x05,0x3b,0x00,0x86,0x88,0x88,0x22,0x94,0x2f,0x60,0xef +,0x40,0x04,0xa0,0x11,0x05,0x55,0x2a,0xb8,0x01,0xb6,0x90,0x02,0x70,0x82,0x81,0x60,0xa0,0xd4,0x26,0x12,0x0a,0x05,0x42,0xc1,0x40,0xb0,0x50,0x4a,0x14,0x1a,0x84,0x86 +,0x81,0x10,0xa8,0x44,0x26,0x31,0x21,0x88,0x4c,0xfe,0xce,0x75,0x53,0xeb,0xd5,0x37,0xd7,0x3c,0x6f,0x5b,0x35,0x52,0xb8,0xce,0xaa,0x75,0x5f,0x8b,0x7f,0x4e,0x93,0xf7 +,0xaf,0xb7,0xb7,0x91,0x6f,0x6e,0xdc,0x3f,0x9f,0xff,0xeb,0xa3,0x5e,0xef,0xd7,0xf3,0xf7,0x1f,0x15,0x54,0xe0,0xfa,0x7f,0x29,0xa7,0xff,0xa0,0x75,0xe3,0x2b,0xe9,0x3c +,0x96,0x3a,0x1a,0x7f,0x60,0xae,0x5b,0x9a,0xef,0xbc,0x59,0x60,0xd6,0xe0,0xe9,0x76,0x4f,0x8c,0xf8,0xc5,0x8a,0xea,0x10,0x50,0xbe,0x05,0xac,0x1e,0x5e,0x91,0x4f,0x9c +,0xc3,0x98,0x3c,0x66,0xd4,0xf0,0xc8,0x0f,0x5f,0x66,0xce,0xf8,0x0e,0xf0,0x40,0x48,0x04,0x40,0x01,0x9e,0xa1,0x20,0x0f,0x5c,0x03,0xba,0x88,0x11,0x00,0x13,0x10,0x17 +,0x01,0x31,0x50,0x1c,0xff,0xf1,0x50,0x80,0x27,0x7f,0xfc,0x21,0x0a,0xcf,0x6f,0xf2,0xff,0xfe,0xfe,0xb4,0x70,0xb0,0x90,0x2c,0x25,0x09,0x05,0x0a,0xa1,0x20,0xa0,0x94 +,0x44,0x14,0x09,0x85,0x42,0x41,0x30,0x8c,0x95,0x23,0x3e,0xb9,0xe6,0xe5,0xe4,0xbf,0x1a,0x99,0xa9,0x55,0x71,0x6a,0x8b,0x67,0xd7,0xba,0xfd,0xbb,0x9f,0x5f,0x01,0xe4 +,0xea,0xb0,0x79,0x7c,0xbf,0x4e,0xaf,0xaa,0xf6,0xbd,0xbb,0x1d,0x11,0xce,0x8c,0xec,0x0c,0xf9,0x35,0xba,0x0e,0x7d,0xc5,0xb8,0x79,0x2d,0xf2,0xae,0x83,0x92,0x3f,0x0f +,0x16,0xd4,0xea,0x9e,0xcc,0xdf,0xb3,0xc3,0x9b,0x8e,0x38,0xe8,0xb4,0x95,0xea,0xb9,0x7a,0xbe,0x04,0x1a,0x1a,0xe7,0x4a,0xdd,0xc4,0xba,0x7f,0x84,0xcb,0x8d,0x0a,0xd0 +,0x85,0x01,0xf9,0x38,0xc6,0x80,0x10,0x9c,0x40,0x68,0x94,0xe5,0xb6,0xf0,0xa8,0x05,0x44,0xc3,0xf2,0x89,0xf2,0x00,0x5a,0xe1,0x50,0x89,0x52,0xa9,0xa6,0x04,0xc0,0xec +,0x02,0xa1,0x42,0x41,0x40,0xb0,0x90,0x2c,0x12,0x0a,0x85,0x02,0xa1,0x31,0x20,0x54,0x28,0x12,0x0a,0x10,0x82,0xa1,0x40,0x90,0x44,0x26,0x11,0x09,0x84,0x44,0x61,0x15 +,0xb5,0xcf,0xdb,0xcd,0x6f,0xfc,0x7c,0xce,0x67,0x5e,0x38,0xf1,0xac,0xab,0x5c,0xbc,0xbd,0x57,0x5d,0x2b,0xad,0xfe,0xda,0xff,0x1f,0xd7,0xe2,0xe6,0x68,0x3e,0x7b,0xff +,0x9b,0xc7,0xab,0xdb,0x77,0x33,0x1e,0x5e,0x3c,0x9d,0xc7,0xc9,0x15,0x5f,0xe3,0x7f,0xc2,0xaf,0x30,0x87,0xce,0x21,0xfe,0xae,0x7b,0xe5,0x67,0xd2,0xaf,0x77,0x7d,0x10 +,0x8f,0x95,0xdb,0xdc,0xaf,0x5f,0x6b,0x47,0xd7,0x17,0x76,0x4c,0x79,0xc4,0xd5,0x6c,0xf8,0x2c,0x27,0xd3,0x9d,0x27,0x80,0xde,0x93,0x5d,0x96,0x52,0x5d,0xe8,0x2b,0x3d +,0xd4,0xb0,0xf3,0x41,0x55,0x80,0x26,0x5c,0xf7,0x40,0x40,0x05,0x80,0x46,0xe5,0xdd,0xc5,0x0c,0x40,0x2b,0x68,0x82,0x68,0x80,0x15,0x09,0x80,0x0a,0x0a,0x00,0xe0,0xff +,0xf1,0x50,0x80,0x28,0xbf,0xfc,0x21,0x0a,0xcf,0xef,0xf7,0xff,0xff,0xfc,0xb3,0x50,0xa0,0x8c,0x2c,0x17,0x0a,0x09,0x42,0xc1,0x42,0x28,0x90,0x64,0x24,0x11,0x85,0x42 +,0x27,0x30,0x8a,0x95,0x93,0xaf,0x1f,0x1d,0xdf,0x33,0xaa,0xdc,0xa8,0xbb,0xca,0x89,0x2e,0x8e,0x33,0xdb,0xdf,0x59,0x72,0x5e,0x7c,0x68,0x3c,0xff,0x1d,0xf4,0x2f,0xcc +,0xea,0xf7,0x7a,0x97,0x57,0xc1,0xf4,0x37,0x29,0x0e,0x6d,0xe3,0xab,0xb3,0xc3,0xad,0x4c,0xeb,0x6f,0xcf,0xc5,0x48,0xf8,0xd8,0x7f,0xb1,0xbe,0xd5,0x0a,0x90,0xba,0x27 +,0x91,0x3c,0xc5,0x46,0x2d,0xf8,0x14,0x2b,0xce,0x5f,0x16,0xd4,0xba,0x8f,0x16,0xe1,0x71,0x8a,0xac,0xda,0x56,0xaf,0xa5,0x14,0x08,0x70,0xbb,0x42,0xa4,0x03,0x3f,0x32 +,0x07,0x61,0x65,0xe5,0x50,0x58,0x0e,0xe4,0x96,0x5c,0x26,0x44,0x09,0xa2,0x2c,0x88,0x2c,0x24,0x4d,0x10,0x48,0x0e,0xc5,0xcb,0x0a,0x81,0x70,0x15,0x6a,0x22,0x0a,0x0d +,0x84,0x81,0x60,0xb8,0x58,0x2a,0x24,0x1b,0x05,0x42,0x81,0x51,0x20,0x4c,0x44,0x13,0x08,0x84,0xc4,0x22,0x30,0x88,0xcc,0x22,0x33,0x08,0x88,0xfa,0xfd,0xb5,0x37,0xf8 +,0xf1,0x97,0x92,0xb8,0xf9,0xe3,0x2e,0x12,0xf3,0x3c,0xa5,0x1e,0x7b,0x8e,0xbb,0xfa,0xf9,0xeb,0x8e,0x03,0xa3,0xcd,0x9b,0xe0,0xdf,0x8b,0xe8,0x6d,0xec,0xdf,0x47,0x76 +,0x7c,0xbc,0x62,0x90,0xb9,0x2f,0x14,0x74,0xfa,0xe7,0x4b,0x37,0xbf,0xb0,0xfe,0xfb,0xfe,0x88,0x26,0xa8,0x17,0x92,0x7a,0x91,0xd2,0xcd,0xdf,0x1b,0x6e,0xbb,0xf0,0xdc +,0xba,0xd1,0x7c,0xcc,0xfe,0x6b,0xd0,0xc9,0xe9,0xec,0xfb,0xfa,0xed,0x04,0x7b,0x9c,0x27,0x05,0xa5,0x7d,0x81,0xf9,0xbe,0xe4,0xdc,0xd4,0x45,0x57,0xf2,0x26,0xbb,0xda +,0x7b,0x08,0x06,0xea,0x36,0x24,0x17,0xb7,0xaa,0x33,0x7a,0xe0,0x1a,0xc5,0x5a,0x49,0x49,0xb6,0x01,0x5a,0x56,0x67,0x7f,0xba,0x09,0x89,0x40,0x58,0x00,0x3a,0x81,0xeb +,0x17,0x00,0x98,0x1c,0xff,0xf1,0x50,0x80,0x25,0xdf,0xfc,0x21,0x0a,0xcf,0xeb,0x7e,0xff,0xff,0xff,0xb1,0x61,0x20,0x54,0x2c,0x25,0x1b,0x06,0x02,0x85,0x21,0x20,0x48 +,0xc2,0xf3,0x08,0x89,0xd9,0xd7,0x3c,0x6f,0x59,0x89,0xad,0xea,0x85,0x84,0xb8,0xcd,0x46,0x5e,0x56,0xa5,0x75,0xf5,0x05,0xbd,0x7f,0xd2,0x7c,0x95,0xef,0x2f,0x77,0xa9 +,0x1c,0x9d,0x1d,0x82,0xfc,0xe8,0x82,0x13,0xf3,0x41,0x3c,0x2f,0x5f,0xdc,0xcd,0x4b,0xed,0x9b,0x3c,0xd7,0xfb,0x72,0xc5,0x5e,0x79,0xd6,0x9c,0x2b,0x23,0xb4,0x99,0xe2 +,0xfa,0x4d,0xb0,0x78,0x12,0xa8,0x35,0x2e,0x9d,0xc4,0xa2,0xc6,0xec,0x77,0xc4,0xef,0x05,0x5c,0x3a,0x10,0x3b,0xc1,0x30,0x8c,0x21,0x42,0xb2,0xb4,0xd7,0x19,0xd0,0x00 +,0x33,0xcc,0x9a,0x0b,0x26,0x17,0x82,0x14,0xb1,0x14,0xa1,0x09,0x81,0x70,0xb4,0x13,0x0b,0x84,0xc5,0xcf,0x5c,0x00,0x92,0xf2,0xb8,0x15,0x2a,0x14,0x12,0x85,0x02,0xa1 +,0x70,0xa0,0xdc,0x2a,0x14,0x11,0x05,0x82,0x84,0x20,0xa9,0x4c,0x2e,0x13,0x10,0x88,0xc4,0x29,0x65,0x53,0x2b,0x8d,0x4e,0xea,0xee,0x78,0xba,0xba,0x89,0x74,0xe2,0xe9 +,0xed,0xea,0x4e,0x5f,0x59,0xba,0xf8,0xc0,0x74,0xf6,0x3c,0x85,0xf5,0x7d,0xcb,0xf2,0x3b,0x1e,0x57,0xb4,0xfe,0x87,0xb5,0xb5,0xfc,0x15,0x92,0x7b,0x29,0x3e,0xcf,0x86 +,0x84,0xed,0x63,0x11,0xf7,0x1d,0xcb,0xd3,0x06,0xe8,0x67,0x5b,0xe2,0x25,0x3b,0xa4,0xfd,0xe9,0x87,0x4f,0x3e,0x62,0x6e,0x9a,0x8d,0x79,0xb8,0xa9,0x8a,0x84,0x79,0xe0 +,0xe3,0x03,0x93,0x90,0x47,0x65,0x2c,0xda,0x67,0xee,0xc4,0x1e,0x68,0x01,0xe3,0x07,0x70,0xbf,0xf8,0x80,0x4c,0x54,0x2d,0x72,0x08,0x97,0x3d,0xd1,0xee,0xdf,0xd7,0x2e +,0x27,0x35,0xeb,0x04,0xec,0x15,0x02,0x00,0x11,0xa0,0x2c,0x24,0x01,0x40,0x40,0x17,0x03,0x80,0xff,0xf1,0x50,0x80,0x27,0x9f,0xfc,0x21,0x0a,0xcf,0x6f,0x7b,0xbf,0xff +,0xff,0xb0,0x40,0xb0,0x88,0x2c,0x17,0x0a,0x85,0x04,0xc1,0x70,0xa8,0x5c,0x28,0x35,0x0a,0x15,0x42,0x41,0x30,0x90,0x46,0x2e,0xe5,0xf9,0xfb,0x7d,0xf7,0xcf,0xb7,0xba +,0xe5,0xf3,0x2d,0x29,0xaa,0x95,0x66,0x98,0x93,0xbd,0x71,0xbb,0x9f,0x8e,0x87,0x8d,0x36,0x97,0xe3,0xa6,0x8e,0xfe,0xdc,0xee,0xf1,0xba,0x8a,0x7d,0x1e,0xd5,0x56,0x7c +,0x8f,0x81,0xe3,0x46,0x7b,0xfe,0x3b,0x47,0xff,0x66,0x9e,0x6c,0x6c,0x9c,0x66,0xcd,0xcf,0xdf,0x5e,0xb3,0x5d,0xfb,0xbc,0xfa,0xaf,0x8e,0xa6,0x6e,0xc1,0xdb,0x82,0x1a +,0x4a,0x0c,0x8b,0x3e,0x3f,0x88,0x82,0x54,0x13,0x22,0xca,0xbe,0xfd,0xb3,0xe9,0x5e,0x11,0x60,0x95,0xca,0x32,0x4b,0x98,0x16,0xa9,0x0a,0x19,0x0b,0x81,0x35,0x17,0xb1 +,0x42,0x40,0x95,0x12,0x98,0xac,0xaa,0x94,0x88,0x80,0x5f,0x51,0x14,0x05,0x0c,0x21,0x28,0xab,0x00,0x13,0x04,0x40,0xab,0x50,0xa0,0x98,0x28,0x26,0x0a,0x89,0x02,0xe1 +,0x44,0x30,0x50,0x2a,0x14,0x09,0x0c,0xc4,0x21,0x30,0x89,0x8c,0x22,0x13,0x08,0x91,0x39,0xdc,0xd7,0x3f,0x1c,0xfb,0x7b,0xd5,0xa7,0x32,0xe9,0xac,0xb9,0x53,0x5d,0x75 +,0xdf,0x70,0xaf,0x8a,0xf8,0xe6,0x6b,0x9e,0x03,0x8e,0xc7,0xd0,0xad,0xf3,0xff,0xbb,0xf8,0x47,0xd8,0xf2,0xe9,0x7e,0x97,0xb7,0xb3,0xa5,0xee,0x1b,0xfb,0x77,0xd8,0x26 +,0x6b,0xa8,0xfb,0x37,0x71,0xb6,0x74,0x7e,0x6c,0xb0,0x83,0x9c,0x35,0x01,0xb7,0x81,0xa4,0x5a,0x07,0xfa,0x7e,0x78,0xe6,0xdc,0x0c,0xfb,0xd5,0xaf,0xd0,0xf8,0x76,0xfe +,0xd8,0xd8,0x23,0x49,0xe8,0x63,0x18,0xac,0xbf,0x7f,0x8c,0x7e,0xd4,0x05,0x84,0x8f,0x71,0xa8,0x05,0x73,0x8e,0x67,0x68,0x09,0x55,0x49,0x22,0x2c,0xbe,0x90,0x08,0x1d +,0xe4,0x00,0x3d,0x71,0x50,0x07,0x78,0x14,0x00,0x02,0xd2,0x01,0x40,0x1c,0xff,0xf1,0x50,0x80,0x28,0x5f,0xfc,0x21,0x0a,0xcf,0xeb,0xf7,0x7f,0xff,0xfd,0xb5,0x50,0xb8 +,0x58,0x26,0x16,0x11,0x05,0x44,0x81,0x60,0xa0,0x5c,0x28,0x12,0x0b,0x05,0x02,0x41,0x40,0x90,0x54,0x24,0x21,0x09,0x04,0x64,0x24,0xcf,0xaf,0x5a,0xf3,0xf6,0xba,0x9d +,0x7a,0xd2,0x3e,0x3d,0xe4,0x95,0x22,0xd5,0x2a,0x6a,0xae,0xb3,0xee,0xf6,0x0f,0x6f,0x72,0x8d,0x5f,0x9c,0xa3,0x96,0xd2,0xe7,0x7a,0xbd,0xaf,0xa1,0xfa,0xc9,0x8e,0x7e +,0x8e,0x79,0x63,0xa5,0x4d,0xb0,0xbd,0xf4,0x1a,0x72,0x66,0x7d,0x0b,0xe5,0xbe,0x44,0xbd,0xf2,0xd9,0xc1,0x4b,0x45,0xd1,0x7c,0x36,0xfc,0xac,0x4f,0xb7,0x56,0xa0,0xc7 +,0xe2,0x2a,0xfe,0xce,0x51,0x56,0xf1,0x92,0xbe,0xb5,0xb8,0xa5,0x48,0xe1,0x9a,0xd4,0xe8,0x84,0xb4,0x4c,0x66,0x52,0x02,0x37,0x17,0x34,0x25,0x03,0xf2,0x26,0x4a,0x84 +,0x01,0x5c,0x85,0xc2,0x40,0x91,0xc5,0x50,0x54,0xc4,0x88,0x88,0x30,0x05,0xc0,0x41,0x50,0x98,0x14,0x44,0x15,0x0a,0x05,0x84,0xe1,0x50,0xa0,0x54,0x4e,0x15,0x0a,0x05 +,0x42,0x41,0x41,0x28,0x50,0x2c,0x14,0x11,0x0d,0x42,0x61,0x50,0x98,0x84,0x26,0x11,0x09,0x84,0x52,0xf9,0xdd,0x55,0xe7,0xb6,0x4d,0xa5,0x4e,0x6e,0x29,0x2c,0xe2,0x6a +,0x6d,0xad,0xf1,0xaf,0x13,0xef,0xf6,0x9e,0xd9,0xf7,0x10,0xf7,0xb7,0x6e,0x67,0xc4,0xfb,0x73,0xe8,0xe0,0x3a,0x9d,0x4f,0x50,0xaa,0xe6,0xe7,0xc8,0x86,0xa7,0xf5,0xca +,0xb8,0xfd,0x3b,0xaf,0x9c,0xf6,0x9b,0x1f,0x4a,0x39,0xb8,0x9a,0x67,0xc3,0x68,0xc7,0x68,0xaa,0x5f,0x2f,0xb3,0x86,0xa6,0x8b,0x47,0xc7,0x5d,0x8f,0xbf,0x21,0x9b,0x2f +,0x8b,0xed,0x04,0xe2,0x38,0x4a,0xc4,0x09,0xfe,0xc8,0x5b,0xc4,0x05,0xf7,0x47,0xba,0x2d,0xdc,0x3b,0xe4,0x59,0x24,0x48,0x77,0x51,0x05,0x27,0x55,0xc1,0xdc,0x90,0x02 +,0x37,0x12,0x91,0x01,0x61,0x50,0x58,0x8d,0x80,0x21,0x40,0x68,0x04,0x40,0x2e,0x07,0xff,0xf1,0x50,0x80,0x27,0x7f,0xfc,0x21,0x0a,0xcf,0xaf,0xf7,0xdd,0xff,0xff,0xb0 +,0x50,0xa0,0x98,0x4e,0x12,0x0b,0x0d,0x42,0x83,0x50,0xb0,0x4c,0x28,0x13,0x09,0x05,0x42,0x81,0x50,0x8d,0x1c,0xd4,0x6f,0xe2,0xae,0xb9,0xd4,0xcd,0x73,0xd7,0x31,0xad +,0xcb,0x2d,0x28,0xad,0x12,0x2b,0x5f,0x5f,0x01,0xf2,0xff,0x2f,0xf9,0xdf,0x8f,0x13,0xef,0x5e,0xa7,0xc7,0x88,0xb7,0x2f,0xc9,0xbd,0x35,0xc5,0x85,0x73,0x3e,0xba,0x4e +,0xf4,0xae,0xe2,0x46,0xfc,0x3b,0x1e,0x11,0xbf,0x9e,0xa5,0x11,0xfb,0xa6,0x8e,0xb9,0xa1,0x1e,0xa6,0xf0,0x73,0x72,0x0d,0xbc,0x2e,0x8d,0xa8,0xfe,0x8e,0x5e,0xd8,0xc0 +,0x33,0x2d,0x25,0xeb,0x7b,0x10,0xda,0x40,0xad,0xd2,0xa1,0x1d,0xa8,0x09,0x46,0xd3,0x5a,0x22,0x35,0x12,0x40,0x29,0x50,0x67,0x54,0x14,0x8a,0x25,0x88,0x50,0xc8,0x0b +,0x10,0x09,0x4e,0xc1,0x29,0x8e,0x40,0x0a,0x06,0x30,0x2a,0x50,0x8a,0x17,0x0b,0x04,0x82,0x81,0x61,0x20,0x98,0x48,0x16,0x0a,0x09,0x82,0x83,0x22,0x08,0x54,0x26,0x11 +,0x09,0x88,0x4a,0x61,0x12,0x37,0x4a,0xd7,0x7d,0x4e,0x3d,0x56,0xab,0xaf,0x17,0x59,0x75,0x24,0x2e,0xfc,0xef,0x34,0xdc,0x5f,0x59,0xbf,0x8c,0xe8,0x6f,0x7c,0x0e,0x9f +,0xd5,0x2f,0xb7,0xb6,0x3f,0x6e,0x4f,0x1a,0xde,0x7d,0x54,0x98,0x7d,0xb7,0x4a,0x7d,0x5d,0x5d,0x86,0x48,0x8f,0x67,0x2f,0xc5,0x1d,0x20,0xa7,0x5e,0xa2,0xf7,0xae,0xe8 +,0xd0,0xea,0x68,0xf4,0x28,0x78,0x6f,0xdc,0x48,0x78,0x8e,0x81,0x4e,0x2f,0x5f,0xaa,0x65,0x3b,0xd2,0xe9,0xbd,0x7a,0xa3,0x52,0xd4,0x9c,0x0d,0xa7,0x5b,0x12,0xc1,0x5e +,0xa5,0x5f,0x6d,0x29,0x10,0x39,0x8e,0x61,0xc1,0x7e,0xed,0xd2,0x12,0x9c,0x92,0x29,0x30,0x77,0x42,0x8f,0xb5,0x0b,0x42,0xe0,0x4e,0x8a,0xa9,0x45,0x02,0xf2,0xa0,0x40 +,0x04,0xde,0xe0,0x39,0x96,0x01,0x50,0x08,0x84,0x40,0xe0,0xff,0xf1,0x50,0x80,0x28,0x3f,0xfc,0x21,0x0a,0xcf,0xeb,0xf4,0x7f,0xff,0xfc,0xad,0x60,0xb8,0x50,0x2c,0x35 +,0x0a,0x05,0x42,0x82,0x60,0xa0,0x88,0x2c,0x14,0x13,0x05,0x02,0x41,0x51,0x90,0x54,0x23,0x17,0xbc,0x99,0xc7,0xd7,0xbe,0x5d,0x2a,0x4a,0xd5,0x66,0x96,0x6f,0xcf,0x3a +,0xd6,0xee,0xaa,0x56,0xab,0x8c,0x57,0xe3,0xc8,0x2f,0xeb,0xd6,0x7e,0x70,0x79,0x27,0xeb,0xde,0xce,0x9f,0xa3,0x78,0x38,0x8f,0xd6,0x35,0x51,0x22,0xf0,0x1d,0xf6,0x1e +,0xb5,0x35,0x7f,0x8a,0xb4,0x30,0x5b,0xbf,0x49,0xcb,0xff,0xec,0xe0,0x93,0x23,0x05,0xef,0x6e,0xaa,0x96,0xeb,0x3e,0x6c,0x4c,0x8a,0x45,0xad,0xdb,0x28,0x9a,0x0e,0xd4 +,0xbe,0x24,0xe4,0xe4,0x46,0xc4,0xa0,0xd5,0xd3,0x15,0xd8,0x2e,0xd3,0x20,0x84,0xb9,0x1c,0xc2,0xf4,0x96,0x78,0x00,0x5d,0x6d,0x82,0x91,0x55,0x05,0x23,0x20,0x48,0x85 +,0x2a,0x11,0xb2,0xc1,0x65,0x88,0x04,0xae,0x92,0x11,0x08,0x85,0x52,0xe6,0x02,0xa0,0x1b,0x80,0xa9,0x60,0xa8,0x50,0x2c,0x25,0x0b,0x85,0x04,0xa1,0x60,0xa0,0x58,0x48 +,0x56,0x09,0x05,0x42,0x82,0x21,0x28,0x4c,0x82,0x23,0x08,0x84,0xc2,0x27,0x37,0xbb,0x67,0x9c,0xbe,0x6b,0x86,0xc4,0x5a,0x2b,0x55,0xc5,0x9b,0x9d,0x78,0xe3,0x88,0xe3 +,0xae,0x7a,0x09,0xcf,0xe0,0xd5,0x9b,0xed,0xd0,0x5e,0xa3,0xb2,0xf2,0xb5,0x5f,0x37,0x41,0x3b,0xf4,0x07,0xfe,0x13,0xdc,0x1a,0xf7,0x9a,0x37,0x33,0xd8,0xf8,0xf0,0x8e +,0x77,0xc8,0x4c,0xfc,0x4f,0x77,0x31,0xc4,0x4a,0x15,0xe5,0xdd,0x6a,0x1f,0xef,0x12,0x79,0x4b,0xb5,0x34,0xe1,0xf5,0xd2,0x8b,0xb4,0xa9,0x5f,0x22,0x7c,0x77,0xf2,0xf3 +,0x45,0xe6,0x89,0x0c,0x32,0x29,0xc6,0x64,0xff,0xea,0x44,0x0f,0x15,0xb6,0xab,0xc4,0x02,0xde,0x84,0x09,0xd0,0x84,0x83,0xb9,0x37,0x74,0x00,0xcb,0x79,0xae,0x3b,0x97 +,0x02,0xc0,0x0a,0x14,0x54,0x08,0x80,0x05,0x41,0x01,0x20,0x1c,0xff,0xf1,0x50,0x80,0x28,0xbf,0xfc,0x21,0x0a,0xcf,0xed,0x7d,0x7f,0xff,0xdd,0xb3,0x41,0xb0,0x60,0x2e +,0x14,0x12,0x85,0x02,0xc1,0x50,0xb0,0x50,0x26,0x16,0x0a,0x05,0x82,0xa1,0x60,0xa0,0x48,0x62,0x23,0x08,0xc1,0x57,0x9f,0x1f,0x9f,0xbf,0x8e,0xbe,0xff,0xd5,0x57,0xad +,0xf1,0x55,0x5c,0x65,0xa4,0x95,0xd7,0x30,0x25,0xf3,0xd2,0xfc,0xfd,0x0f,0x9c,0xfe,0xbb,0xfc,0x5b,0xf9,0xa1,0xaa,0xef,0xe7,0x88,0xf0,0xbf,0x16,0xba,0xd2,0xe6,0x76 +,0xf3,0xea,0x4e,0x7d,0xd4,0x6e,0xa7,0x9e,0x3b,0xf1,0x32,0xe8,0xad,0x32,0xa1,0x86,0xbf,0xaa,0x17,0x76,0x9c,0x84,0x8c,0x54,0xbf,0x1f,0x35,0x0d,0xd5,0xe0,0xd0,0xb9 +,0xc8,0x97,0x38,0xa3,0x67,0x35,0xe8,0x8d,0x61,0x77,0xaf,0x27,0x0d,0xe3,0x4a,0xd9,0x09,0xca,0x77,0x17,0x99,0x72,0x0b,0x0e,0xc1,0x14,0x08,0x96,0x81,0x10,0xa1,0x0a +,0x31,0x04,0x45,0x86,0x02,0xf1,0x00,0x16,0xbb,0x90,0x04,0x42,0x50,0x58,0x00,0xb1,0x10,0x15,0x2a,0x14,0x0a,0x85,0x02,0xe2,0x61,0x20,0x4c,0x2a,0x16,0x0a,0x05,0x42 +,0x81,0x60,0xa0,0x98,0x48,0x12,0x12,0x04,0x82,0x21,0x31,0x0b,0xd5,0xbc,0xfa,0xf7,0xae,0xb2,0x96,0x95,0xce,0x85,0xd5,0xa2,0xf5,0x53,0x15,0x69,0xc2,0xbc,0xab,0xd8 +,0x3a,0xb6,0x67,0xd7,0xf4,0x77,0x61,0xe6,0x17,0x7b,0x6e,0xf8,0xcf,0xf8,0x7d,0x76,0xe3,0xcd,0x5a,0xe1,0x3f,0x6f,0xfa,0x70,0x8f,0x83,0xdf,0xb3,0x64,0x5a,0x43,0x8e +,0xc9,0xf9,0x7f,0x7f,0x9c,0x94,0x09,0x99,0x87,0x54,0xa9,0x42,0x3f,0x46,0xee,0xde,0xc6,0xe9,0xfb,0x6e,0x25,0xe7,0x38,0x8a,0x1c,0x1e,0x8b,0xd7,0xba,0xad,0x5c,0x1d +,0xb8,0xb5,0x68,0x87,0x1f,0x70,0xfe,0x14,0xc3,0x5a,0xf5,0x11,0xee,0x45,0x25,0xe6,0xb5,0xe9,0x2d,0x56,0x9f,0xd4,0x06,0x3b,0x28,0x2a,0x8b,0x4d,0xae,0x8b,0x65,0x2f +,0x1a,0xd9,0x4a,0xd2,0x40,0xad,0x11,0x05,0x40,0x2d,0x42,0x00,0x88,0x00,0x44,0x50,0x0e,0xff,0xf1,0x50,0x80,0x27,0x5f,0xfc,0x21,0x2a,0xcf,0xbd,0xfb,0xbf,0xff,0xa7 +,0xb1,0x61,0xa0,0x98,0x28,0x26,0x09,0x05,0x42,0x61,0x60,0x90,0x4c,0x28,0x42,0x30,0x94,0xc2,0x2c,0x73,0xf1,0xce,0xbd,0x5d,0xdf,0x9e,0xeb,0x38,0x6d,0xac,0x25,0xab +,0x41,0xe7,0x7e,0xdf,0x3e,0xd6,0xe7,0xad,0x7b,0xff,0x9e,0x83,0x71,0xfc,0xdb,0xce,0x8d,0x63,0xfe,0x4a,0x7e,0xbf,0x30,0xfa,0x06,0xa3,0xf1,0xe7,0xe2,0xa7,0xe7,0x8a +,0x9f,0x0a,0x13,0xf5,0xf9,0xfa,0xf8,0x7e,0x77,0x62,0x0a,0xe2,0x79,0x7a,0x38,0xf4,0x6f,0x05,0x7a,0x43,0xf7,0x67,0x52,0x7a,0x16,0x77,0x6b,0xba,0xf5,0xa6,0x77,0x16 +,0x8d,0x0e,0xdd,0x09,0x46,0x88,0xff,0xf4,0x46,0xfa,0xc9,0x6e,0x6a,0x70,0xa5,0xef,0x14,0x79,0x40,0x38,0x00,0xef,0xc0,0x45,0x31,0x22,0xb7,0x51,0x54,0x40,0x99,0x20 +,0x16,0x00,0xb0,0x2e,0xaa,0xc0,0x54,0x06,0xa4,0x40,0x14,0x08,0x81,0x58,0x82,0x62,0x28,0x58,0x48,0x15,0x0b,0x04,0x82,0x81,0x50,0xa0,0x98,0x48,0x32,0x0a,0x84,0x84 +,0x61,0x12,0x18,0x44,0xc6,0x11,0x21,0x97,0xcf,0xd7,0x8f,0xbf,0xca,0xd7,0xde,0xb6,0xbb,0xe5,0x71,0x2e,0x7b,0x5d,0x66,0x6a,0x55,0xfb,0xf5,0x7e,0xff,0xe9,0xaf,0x23 +,0x40,0x6d,0x0f,0xae,0xfd,0xf3,0xfa,0x3e,0x37,0xbd,0x9a,0x6f,0xd2,0x7f,0xe8,0xeb,0x47,0xc3,0xc0,0x96,0x3c,0x21,0xdc,0x3d,0x1c,0xbb,0x5e,0x8f,0x8d,0xd8,0xec,0xa9 +,0x51,0xc2,0xef,0xdd,0x7d,0xb0,0xe1,0xbe,0x74,0xbc,0xa7,0xc0,0xfe,0xab,0x57,0xaf,0xa8,0x0b,0x1e,0x3a,0xb8,0x5c,0xd5,0xe1,0xd0,0xbe,0x4d,0x12,0x8f,0x08,0x93,0x12 +,0xd7,0x45,0x86,0x77,0xd5,0x61,0xfe,0x00,0x06,0x7d,0x05,0x89,0x68,0x42,0xc0,0x8d,0x08,0x9e,0xe0,0x4c,0xbc,0xe0,0x11,0x42,0xc0,0x98,0x27,0x70,0x5b,0x05,0x20,0xaa +,0xc4,0xc7,0x70,0x00,0x8a,0xd4,0x4c,0x00,0x22,0x5c,0x0e,0xff,0xf1,0x50,0x80,0x29,0x5f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x6c,0x16,0x6a,0x50,0x99,0x52,0x64,0x5b,0x88 +,0xb4,0x89,0x7a,0x09,0x49,0x26,0xe9,0x73,0x5f,0xfc,0x6a,0x7b,0x4a,0xed,0x7b,0x1b,0x4e,0x66,0x1a,0x9a,0x67,0x66,0xa0,0xed,0x9a,0x96,0xcb,0x65,0x95,0xde,0xd5,0x31 +,0x0b,0x32,0x12,0xbb,0x65,0xed,0xc4,0x4a,0x91,0x19,0xf1,0x40,0xb4,0xcb,0x5e,0x03,0x57,0x66,0x15,0xc6,0xa5,0xc6,0xed,0xe1,0x8e,0x1e,0x7e,0x6d,0x72,0x19,0x56,0x51 +,0xbc,0x29,0x33,0x63,0xf1,0xed,0x1d,0xfd,0x53,0x61,0xa2,0xaa,0xce,0x32,0x85,0xf8,0x5f,0xcd,0xfa,0x7f,0xdc,0xdf,0x89,0xa8,0x58,0x6c,0x00,0xb4,0x17,0x0a,0xc5,0xfd +,0x20,0xa9,0x78,0x22,0x80,0x4b,0xfb,0x87,0x23,0x43,0x2b,0xf4,0xa1,0x9d,0x11,0xa6,0x28,0xc8,0x97,0x2e,0x5b,0x61,0x4e,0x80,0x11,0x8c,0x80,0x8c,0x2f,0x0c,0x14,0x00 +,0x44,0x44,0x20,0x26,0x73,0x10,0xa9,0x47,0x05,0xaa,0x94,0x44,0x45,0x2d,0x92,0xec,0x97,0xa1,0x4a,0xce,0x8e,0xd2,0x2e,0x63,0x15,0x72,0xd8,0x66,0x65,0x22,0x4c,0x1e +,0xdf,0xd4,0x9f,0xab,0x23,0x4f,0x77,0x83,0xbc,0x3d,0xf1,0x17,0x4d,0x24,0xc5,0xfb,0xf6,0xf2,0xf0,0xba,0xbe,0x0d,0x66,0xc3,0xbb,0x0d,0xfe,0xed,0x18,0xeb,0xbe,0x7a +,0x76,0x73,0x78,0xdb,0x64,0x07,0xd0,0xd0,0x43,0x1e,0x07,0xd1,0x64,0x7d,0xf3,0xdf,0x7a,0xbc,0xa5,0xa6,0x24,0x30,0xa2,0x10,0x06,0x66,0x24,0x1b,0x94,0x48,0x25,0x08 +,0xa3,0x0e,0x3a,0xbd,0x22,0x46,0xe6,0xb1,0x19,0xba,0x65,0xc7,0x73,0x9a,0x75,0xf4,0xfd,0x13,0xc2,0xd6,0x4d,0x75,0x30,0x65,0x1c,0xee,0xf6,0xab,0xbc,0x54,0x5f,0x4a +,0xaa,0x6a,0x55,0xe2,0xf5,0x8a,0xe5,0x8e,0x28,0x70,0x62,0x08,0x6c,0x7b,0xbe,0x7d,0xf1,0x59,0x10,0x80,0x20,0x02,0x80,0x81,0x38,0x45,0x52,0x01,0x15,0x77,0xda,0xc5 +,0xa2,0xe4,0x50,0xe7,0x28,0x40,0xe8,0x8f,0x18,0x04,0x51,0x0c,0x62,0xa3,0x50,0xd4,0x02,0xbd,0x08,0xcc,0xe0,0xff,0xf1,0x50,0x80,0x29,0x9f,0xfc,0x21,0x6a,0xcf,0xff +,0xbb,0xff,0xff,0xfe,0xb6,0x80,0xb1,0x14,0x2c,0x14,0x11,0x05,0x42,0x83,0x20,0xa8,0x90,0x84,0x61,0x49,0x88,0x4a,0x55,0xeb,0xbf,0x35,0x57,0xa9,0xcd,0xe4,0xcd,0x62 +,0xea,0x54,0xcb,0x90,0x99,0x69,0xc4,0xc3,0xe3,0xc8,0x83,0x5d,0xdf,0x4e,0xac,0x23,0xa6,0x97,0x7f,0x5e,0xb5,0xd4,0x5b,0x67,0xa6,0x1c,0x95,0x39,0x6a,0x5d,0x3f,0xb0 +,0x89,0xf4,0xc7,0x9c,0xf1,0x3c,0xf7,0xbd,0xe3,0x7c,0x7d,0x2e,0x02,0x22,0x85,0x3e,0xbf,0x04,0x1b,0x1f,0x9b,0x27,0xae,0x3a,0x84,0xd5,0xad,0x3c,0xd4,0xc4,0x74,0x60 +,0x88,0x11,0x0c,0x1b,0xcd,0x68,0xb5,0xa4,0xab,0xa6,0x26,0x1a,0x5d,0xa9,0xbe,0xf0,0xba,0xb4,0x9c,0xb0,0x17,0x73,0x56,0x2a,0xc2,0xdd,0xcb,0xce,0xc9,0x15,0x13,0x0b +,0x71,0x85,0x49,0x0c,0xfa,0x13,0x66,0x44,0x7b,0xc0,0x00,0xee,0x97,0x28,0x0e,0x04,0x14,0x12,0x5c,0x05,0x09,0x00,0xa8,0x64,0x21,0xdc,0x2c,0x14,0x0a,0x85,0x06,0xa3 +,0x30,0xa8,0x4c,0x2a,0x23,0x08,0x84,0xc8,0x22,0x30,0x89,0x1b,0xaa,0x8a,0xeb,0x69,0x7d,0xfe,0x3d,0xea,0xa3,0x35,0x57,0x15,0xc3,0x1c,0x61,0xc6,0xf8,0xbc,0xc7,0x41 +,0xa9,0x2e,0xe5,0xb2,0xab,0xb9,0xbe,0xeb,0xfc,0xdc,0x35,0xf5,0x47,0x67,0xac,0xbe,0xd3,0xd0,0xc2,0xfe,0x69,0xc7,0xbf,0x57,0xf9,0x68,0x38,0x76,0xdc,0xf3,0xd6,0xd7 +,0xa2,0xfd,0xbf,0xd8,0x9f,0x5b,0x47,0x5f,0xcc,0xe3,0xfc,0x7f,0xb8,0xf9,0x1d,0x1f,0xbc,0x57,0x33,0xaf,0xdf,0xfa,0xdc,0x39,0x07,0x08,0xf3,0x9e,0xda,0x31,0x2f,0x2f +,0x84,0xcf,0x58,0x3b,0x9e,0x65,0xff,0x84,0x73,0xf1,0xa0,0x50,0xf3,0x50,0xaf,0x2a,0x22,0xaa,0x84,0xf1,0x2a,0xce,0x96,0x88,0x0e,0x64,0x16,0xef,0xb6,0x42,0x14,0xb2 +,0x29,0x16,0x42,0x34,0xfe,0xdb,0xe6,0x45,0x20,0x0e,0xe1,0x37,0x76,0xa1,0x68,0xaa,0x16,0x0a,0x90,0x57,0xbc,0x80,0x08,0x41,0x28,0xa5,0xe8,0x00,0xbc,0xe2,0x42,0x60 +,0x70,0xff,0xf1,0x50,0x80,0x2c,0x7f,0xfc,0x21,0x0a,0xcf,0xff,0xbf,0xf9,0xff,0xfd,0xb5,0x62,0xc0,0x90,0x24,0x15,0x0a,0x09,0x82,0x82,0x50,0x98,0x50,0x24,0x24,0x09 +,0x05,0x42,0x45,0x13,0x98,0x44,0xea,0x8e,0xbb,0x9f,0x5e,0x2a,0x2b,0x52,0x8a,0x75,0xdd,0xe2,0xea,0xca,0xbc,0xd6,0xfc,0xb2,0x9a,0xf6,0xfa,0x1a,0xea,0xee,0xe7,0xed +,0x69,0xb8,0xf4,0x11,0x69,0xb3,0x15,0xb3,0x7f,0xdd,0xff,0xe4,0xe5,0xc1,0x9e,0x99,0x17,0x36,0xab,0xd9,0xf3,0x2a,0xb3,0xf1,0x2d,0xfa,0xef,0xce,0xc7,0x8f,0x94,0xd4 +,0xa7,0x4f,0xa6,0x04,0xfc,0xad,0xae,0x5d,0x1c,0x6a,0xdd,0x02,0x75,0xf2,0x7a,0xde,0xfa,0xf8,0xad,0x2e,0xcc,0x98,0x56,0xfa,0x0e,0xc9,0x20,0xc0,0x9d,0x0c,0xb5,0x47 +,0x63,0xe1,0x7a,0xc8,0x86,0x57,0xa6,0x85,0xb8,0x51,0x53,0x56,0xc1,0x55,0xe3,0xb7,0x05,0x52,0x4e,0x2c,0x44,0xf7,0xd4,0x82,0x0d,0xb1,0xba,0xbe,0xb0,0x08,0x65,0x0d +,0xf5,0x0a,0x88,0x24,0xba,0x30,0xa0,0x8a,0x2a,0xc8,0x05,0xc2,0x80,0x29,0x88,0x2c,0x34,0x0b,0x09,0x02,0xa1,0x40,0xb0,0x90,0x6c,0x24,0x0a,0x85,0x82,0x81,0x60,0xa8 +,0x90,0x2c,0x15,0x09,0x85,0x42,0x61,0x10,0x99,0x04,0x26,0x11,0x33,0x3b,0x4d,0x73,0xfe,0x9f,0x9a,0xbe,0x65,0x04,0x12,0xf9,0x79,0x95,0x35,0xdc,0xb9,0xc7,0x3d,0x7b +,0xfd,0x73,0xc4,0x1b,0xb9,0x6e,0xec,0xa3,0xaa,0x8f,0xb9,0x55,0xd9,0xaa,0xdf,0xca,0x76,0x36,0xb4,0x4b,0xf6,0x79,0xa1,0x07,0xa7,0xd9,0x7f,0x37,0xea,0xf5,0xea,0xbb +,0x7c,0x08,0xd3,0x5a,0xaf,0xf9,0x18,0xfd,0x63,0xd0,0xec,0x73,0xe2,0xf9,0xfe,0x2e,0x33,0xee,0x83,0x89,0xb9,0x8a,0xf3,0x20,0xa2,0xd3,0xf2,0x39,0x70,0x9e,0xd9,0xbe +,0x76,0xe4,0x72,0x13,0xa7,0xf8,0x14,0x27,0x20,0xf2,0x52,0x74,0x11,0x69,0xab,0xcf,0x9b,0x90,0xa1,0xdf,0x38,0x8f,0x72,0x2b,0x90,0x38,0xa9,0xc0,0xc7,0x4f,0xfd,0xaa +,0xd4,0xa0,0xec,0x27,0xde,0x2f,0x18,0x55,0xff,0xa9,0x75,0xde,0xbf,0x78,0x3d,0x77,0xba,0x3d,0x70,0x90,0x22,0x3f,0x22,0x80,0x59,0x61,0x5a,0x07,0x52,0xc1,0x72,0xd4 +,0x02,0xe0,0xa0,0x0e,0xff,0xf1,0x50,0x80,0x2b,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0x7f,0xfb,0xff,0xff,0xb5,0x62,0xb8,0x90,0xc4,0x14,0x21,0x05,0x04,0x43,0x50,0x90,0xc4 +,0xa6,0x11,0x11,0x84,0x4c,0x93,0x3d,0xbd,0x49,0xed,0x39,0xf3,0xea,0x45,0x33,0x53,0x2a,0xc9,0x57,0x72,0xaa,0xf7,0x3d,0xb9,0x95,0x5f,0x8f,0x61,0xbf,0xdb,0xca,0x4d +,0xa3,0x8f,0xbf,0xec,0xb3,0xdc,0x7a,0x97,0x97,0xb9,0x72,0xd2,0x9b,0xf7,0x88,0x55,0x5a,0xbb,0x7f,0xf3,0x75,0x31,0xd1,0x73,0xe0,0xca,0x72,0x32,0xb4,0x3a,0xa6,0xe0 +,0x67,0x95,0xe2,0xae,0xdc,0x6e,0x6b,0xbc,0x60,0xc7,0xb9,0xa9,0x12,0xc8,0xbf,0x2f,0xe1,0x2e,0x73,0x64,0x26,0x54,0x75,0xa2,0xb3,0x88,0x79,0x5b,0x02,0x2b,0x37,0x24 +,0x29,0x28,0xc3,0x65,0xa5,0x49,0x18,0x20,0xd7,0x74,0x61,0x67,0x45,0xe8,0xb1,0xb3,0x52,0x01,0x3a,0x62,0x1d,0xf7,0xb8,0x32,0xcd,0x71,0x29,0xa4,0x03,0xd6,0x90,0x5c +,0x17,0x57,0xc4,0x0c,0xc0,0x42,0x32,0x00,0x14,0x11,0x02,0x68,0x82,0xc2,0x50,0xb0,0x94,0x48,0x26,0x12,0x09,0x82,0x81,0x60,0xa0,0xd8,0x2a,0x14,0x0a,0x85,0x02,0x61 +,0x51,0x18,0x94,0x62,0x33,0x08,0x8c,0xc2,0x22,0x7e,0x9e,0x2b,0xae,0xee,0x7d,0xfd,0xf3,0x9e,0x25,0x33,0x8d,0xeb,0x2f,0x2f,0x3a,0xdf,0xb7,0x77,0x1c,0x6a,0x7e,0x7c +,0xe6,0x4f,0x67,0x42,0x7e,0x5c,0xb7,0xb7,0xf4,0x37,0x09,0x39,0xbe,0xd7,0x6e,0xc3,0xcd,0xc7,0x4d,0x29,0xe0,0x8b,0xf5,0x87,0xe3,0xda,0x74,0xcf,0x41,0xa9,0x2b,0x7f +,0xe2,0x3b,0xea,0x6b,0x9c,0x6f,0xca,0x45,0x77,0xf8,0xde,0xdd,0x9f,0xda,0x41,0x6f,0x61,0x47,0x2e,0x1c,0xc8,0x70,0xff,0x7f,0x92,0x3d,0xe7,0x97,0x99,0xcc,0xc6,0x29 +,0xf5,0x9d,0x6e,0x48,0x5e,0xf6,0x9d,0xc5,0xdd,0x1c,0x45,0x45,0x71,0x07,0x90,0x02,0xbb,0xee,0xfb,0xdc,0x09,0xcb,0xb8,0xfb,0x65,0x81,0xc9,0xe5,0x02,0x8a,0xf0,0x02 +,0xf8,0x01,0xe2,0x00,0x00,0x5a,0xea,0x58,0x4c,0x85,0xa0,0x89,0x00,0x77,0x84,0xc1,0xbe,0x85,0x07,0x40,0x8d,0x59,0xa4,0xee,0x80,0x2e,0x98,0xb0,0x1c,0xff,0xf1,0x50 +,0x80,0x2d,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xbb,0xef,0xff,0xff,0xb3,0x60,0xc0,0x5c,0x28,0x15,0x0c,0x05,0x82,0x84,0x50,0xa0,0x8c,0x28,0x16,0x0a,0x08,0x82,0x81,0x21 +,0x28,0x44,0x26,0x22,0x08,0x8c,0x82,0x22,0x30,0x8a,0x19,0x79,0xac,0x9c,0x5d,0x55,0x34,0xe6,0xb8,0xa4,0xbc,0xb9,0x42,0x1b,0xd7,0x1d,0xfb,0x6e,0x55,0xfd,0x58,0x7d +,0x10,0xe8,0x7c,0xaf,0xd6,0x7e,0xc1,0xba,0x9f,0x1e,0x7f,0xe7,0xe4,0xdc,0xd3,0xcc,0x3f,0xf6,0x0c,0x7f,0x35,0x96,0x95,0xfd,0x05,0x34,0x5d,0x10,0xdf,0x2b,0xfa,0x74 +,0xef,0x69,0x1c,0xa9,0xfd,0x61,0xe5,0xe4,0x23,0xc8,0x7b,0xaf,0x73,0x1b,0xc7,0x27,0x72,0xaa,0x34,0xb3,0x25,0x91,0xc3,0xe7,0x76,0xce,0xd4,0xaf,0x9c,0x6d,0x4a,0xec +,0xdd,0x09,0x81,0x3e,0x8c,0x85,0x28,0xb4,0xd6,0xe6,0x1e,0x50,0xbc,0x1c,0xa4,0x2b,0x69,0xc2,0x08,0x11,0xdb,0x2e,0x31,0x56,0x6b,0x8b,0x90,0xbd,0x80,0xfb,0x44,0x6d +,0x91,0x18,0x29,0x58,0x90,0x21,0x6c,0x20,0x26,0x12,0x94,0x80,0x94,0x98,0xc0,0x02,0xa8,0x01,0x46,0x41,0x50,0xb0,0xd0,0x2c,0x14,0x1b,0x09,0x04,0xc1,0x40,0xb0,0x90 +,0x8e,0x16,0x0a,0x05,0x44,0x21,0x32,0x08,0x4c,0x22,0x23,0x08,0x84,0xc2,0x21,0x30,0x88,0x9e,0x93,0x8d,0xf3,0xe7,0x32,0xf6,0xd6,0x56,0x71,0x52,0xaf,0x2d,0xc7,0x3f +,0xaf,0xce,0xb3,0x89,0xbf,0xbe,0xf9,0xe7,0x8e,0x7d,0x9c,0x0e,0x77,0x82,0xef,0xd9,0xa1,0x79,0xff,0xca,0xf5,0xd1,0xfe,0xde,0x67,0xfe,0xf6,0xb6,0x9d,0x5c,0x4c,0x3a +,0x78,0x3a,0xbf,0xe4,0x7f,0x33,0xd1,0x84,0x07,0xed,0x7b,0x46,0xd9,0x4d,0x09,0x4d,0xa1,0xf4,0x6f,0x33,0xf1,0x27,0xf9,0xd7,0xf5,0xb5,0x7f,0x83,0x57,0x09,0xf2,0xc2 +,0x7a,0xd4,0xb3,0x5c,0x3a,0xae,0xf6,0x75,0x28,0xb4,0x35,0x88,0x8c,0x84,0x9c,0x5f,0xf6,0x11,0x55,0xcd,0xc9,0xc7,0xcd,0x60,0xe3,0xc7,0xa9,0xb3,0x80,0x18,0x11,0x3f +,0xb2,0x14,0xee,0x8f,0xfd,0x02,0x63,0xd7,0xbd,0x27,0x10,0x3b,0xe7,0xaf,0x50,0x90,0xf7,0x08,0xfb,0x71,0x79,0x01,0x30,0x91,0xdc,0x04,0x14,0x23,0x64,0x9e,0xe0,0x22 +,0x72,0x13,0x9b,0xdd,0x00,0x89,0x42,0xd5,0x03,0x80,0xff,0xf1,0x50,0x80,0x2a,0xff,0xfc,0x21,0x0a,0xcf,0xff,0xfe,0xbf,0xbf,0xff,0xb2,0x40,0xa8,0x98,0x4e,0x18,0x0a +,0x04,0x82,0x82,0x50,0xa0,0x48,0x28,0x15,0x09,0x05,0x0a,0x61,0x21,0x88,0x54,0x24,0x11,0x73,0x72,0x35,0xeb,0xdb,0xad,0xaa,0xb8,0xee,0xf2,0xea,0x48,0xab,0x3a,0xe6 +,0x54,0x5b,0x9f,0x6d,0xc9,0x9f,0xcc,0x1f,0x31,0x7f,0x5f,0xb5,0xb0,0x7f,0x09,0x3f,0x5b,0xa6,0x2e,0x77,0xf4,0xd8,0xf8,0x7b,0x3c,0x8e,0x1e,0xe1,0x5e,0x8a,0xf7,0x6a +,0x37,0xe1,0xb7,0x6f,0x2d,0x29,0x85,0x4d,0xeb,0x00,0x3e,0x60,0xe8,0x30,0xd2,0x83,0x74,0x66,0x6a,0x52,0x3f,0x8b,0xd1,0x57,0xa0,0xae,0xb3,0xac,0xc7,0x6f,0x04,0xe0 +,0x16,0xd6,0xd7,0x18,0xa0,0x7a,0x80,0x01,0x41,0x08,0x0f,0xd8,0xb4,0xd9,0x8d,0xf4,0x48,0x5a,0xb7,0x4c,0x26,0xaa,0xb1,0x48,0x0f,0x54,0x4e,0x0a,0x80,0x51,0x18,0x84 +,0xe7,0x28,0x50,0x08,0x48,0x09,0x69,0x08,0x8b,0x54,0x0b,0x80,0xb8,0x13,0x88,0x12,0x0b,0x09,0x42,0x81,0x60,0xa0,0x48,0x28,0x26,0x12,0x05,0x82,0x83,0x80,0xb0,0x50 +,0x2c,0x14,0x19,0x85,0x42,0x81,0x50,0x98,0xc4,0x26,0x25,0x08,0x9d,0xeb,0xdd,0x75,0x5a,0xff,0x4f,0xe9,0x84,0x5e,0xef,0x70,0xb9,0x5a,0x9f,0xcf,0xf6,0xe2,0x5f,0x7a +,0xbd,0x75,0xb8,0xba,0xd0,0xf2,0x3c,0xf8,0xf2,0xf0,0x8f,0x83,0xfd,0xf4,0x6e,0xf4,0x5d,0xf1,0x38,0x6e,0x02,0xf6,0x3d,0xd6,0x86,0x8b,0xf9,0x52,0x7d,0xce,0x63,0xa6 +,0x85,0x72,0xdf,0xdc,0x5c,0xff,0x49,0xfe,0xa5,0x88,0x1c,0x6a,0x6f,0x66,0xaa,0xda,0x37,0x38,0x7e,0x2f,0x45,0x03,0xa0,0xdd,0xd8,0x22,0x8e,0x7c,0xee,0xce,0x87,0xb9 +,0x54,0xed,0x07,0x55,0xbc,0xd7,0x7a,0xd3,0xf5,0x3f,0x1a,0x08,0xaf,0x09,0xe1,0x02,0x49,0x1d,0xe4,0x94,0xef,0x41,0x9f,0x5c,0x4f,0x28,0x25,0x1f,0x00,0x81,0xfb,0xeb +,0xf7,0x78,0x13,0x4c,0x1e,0xe2,0xaa,0x60,0xb3,0x2d,0x6f,0x84,0x51,0x6c,0x7d,0xc3,0xfc,0x60,0x00,0x07,0x90,0x02,0x53,0x02,0x20,0x28,0x2c,0x0a,0x00,0x98,0x04,0x40 +,0xe0,0xff,0xf1,0x50,0x80,0x2a,0x7f,0xfc,0x21,0x0a,0xcf,0xfd,0xff,0xff,0xff,0xfc,0xb3,0x30,0xb0,0x5c,0x28,0x16,0x0b,0x89,0x04,0x41,0x60,0xa8,0x50,0x44,0x13,0x0a +,0x08,0x82,0x61,0x21,0x20,0x48,0x43,0x25,0x6b,0x9b,0xe3,0xd7,0x9e,0x9d,0xc9,0x97,0x55,0x2e,0xf2,0x92,0xd5,0x72,0xab,0x8a,0xba,0xa8,0xa8,0xfb,0xe8,0x7e,0x68,0xfd +,0xbe,0x1b,0xf8,0xdc,0x11,0xfd,0xff,0xdb,0x7a,0xf7,0x47,0x76,0x0b,0x1e,0xef,0x61,0xca,0xa6,0xaf,0xe5,0xd5,0x3f,0x10,0xfc,0xb4,0xb9,0x46,0x3a,0x47,0xb4,0xb6,0x9b +,0xa1,0xf1,0x97,0x47,0x99,0xfd,0x60,0x79,0xce,0xd7,0x13,0x67,0x55,0x02,0xad,0xe7,0x50,0x2b,0xaa,0xe7,0x5b,0x4f,0x83,0x5a,0x59,0x6f,0x2a,0x47,0xb5,0x69,0x35,0xef +,0x15,0xd0,0xce,0x82,0x11,0x14,0x8b,0xb0,0x68,0x55,0x26,0x44,0x50,0x2e,0x25,0x62,0xac,0xe0,0x99,0x28,0x2b,0xdc,0x14,0xc7,0x59,0xaa,0x09,0xa8,0x88,0x48,0x89,0x38 +,0xa8,0xa8,0x05,0x82,0x20,0x28,0x94,0x28,0x16,0x32,0x85,0x88,0xa1,0x61,0x20,0x58,0x48,0x16,0x12,0x89,0x02,0x61,0x51,0x98,0xc4,0x26,0x21,0x09,0x8c,0x48,0xf1,0xbb +,0xcd,0x67,0xb6,0xfb,0xb3,0x8e,0x66,0x5d,0x24,0x84,0x9c,0x55,0x26,0xfa,0x6f,0xce,0x4f,0x35,0x5c,0x07,0x4f,0xcd,0x6a,0xf7,0xf8,0x67,0x4e,0xc5,0xdc,0x3c,0xf6,0x51 +,0xef,0x47,0x70,0x69,0x96,0xb7,0x4a,0xbd,0x40,0xde,0x46,0x78,0xd2,0x8b,0x68,0xdf,0x71,0xed,0x4d,0xbb,0xec,0xf3,0x8d,0x1e,0x88,0x4e,0xe7,0xbc,0x95,0xfe,0xc4,0x5f +,0xf0,0xc2,0x41,0xff,0xda,0x26,0xd7,0x6d,0xe6,0x69,0x7a,0xb9,0x73,0x7b,0x62,0xdc,0xd8,0x74,0xf3,0xbe,0xd7,0x47,0x02,0x1b,0x65,0x0f,0x4b,0x9a,0x1d,0xe3,0x9c,0x3e +,0x68,0x72,0x1d,0x40,0xf9,0x39,0x8f,0x93,0x92,0x50,0x79,0x50,0x1f,0x87,0x94,0x85,0xe4,0xaa,0x9e,0xeb,0x00,0xce,0xef,0xa9,0x09,0x2a,0x9d,0x64,0x77,0xfd,0x60,0xf3 +,0x21,0xeb,0x12,0x5f,0xa9,0x70,0x1d,0xe0,0x17,0xee,0x00,0xee,0x48,0x01,0xc1,0x50,0x24,0x13,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2b,0xff,0xfc,0x21,0x0a,0xcf,0xfd,0xfb +,0xff,0xff,0xff,0xb2,0x70,0xb0,0xdc,0x30,0x16,0x09,0x85,0x06,0xa1,0x41,0xb0,0x50,0x84,0x24,0x0a,0x84,0x82,0x61,0x20,0x8c,0x15,0x75,0x27,0x8f,0xab,0xcd,0xdc,0xce +,0x37,0xbd,0x44,0x49,0x9a,0xcb,0x97,0x54,0xb8,0x2a,0x3e,0xbc,0x87,0x83,0xcf,0xf1,0xed,0xba,0x3d,0xdd,0xaa,0x0e,0xaf,0xfd,0xcf,0xf8,0x1d,0x8f,0x35,0xe8,0xbc,0x47 +,0xc6,0x1a,0x13,0xae,0xca,0xf8,0x23,0xbc,0x92,0xe0,0xa9,0xa6,0xb8,0xe0,0xdd,0xc7,0x83,0xee,0xf2,0xe3,0x0d,0x1b,0xf6,0xb7,0x46,0x68,0x20,0xae,0x4c,0xa8,0xf9,0x4d +,0x44,0x33,0x38,0xf1,0x98,0x8c,0x2a,0xc1,0xf7,0xfd,0x36,0x3a,0x7a,0x8b,0x67,0xca,0x90,0x1f,0xc7,0xfe,0x51,0xbf,0x75,0xf8,0xa4,0x9d,0xec,0x52,0x25,0x6f,0x44,0xea +,0x37,0x09,0xa2,0xb9,0x32,0x53,0x1d,0x63,0x6c,0x2b,0xa5,0x21,0x4a,0xdc,0x94,0x10,0xad,0x01,0x1b,0x88,0xab,0x12,0x2a,0x90,0xc4,0x05,0x73,0x2a,0x05,0x40,0xa0,0x09 +,0xb4,0x0b,0x0d,0xc2,0xa1,0x42,0x32,0x90,0x2c,0x14,0x0b,0x05,0x02,0x41,0x50,0x88,0x4c,0x62,0x13,0x08,0x84,0xc2,0x21,0x30,0x89,0x9f,0xa7,0x7a,0x85,0xfe,0xbf,0xdb +,0x8c,0x94,0x4a,0xbc,0x5d,0x5d,0x35,0xf1,0xe2,0x6b,0xbd,0x73,0xe7,0x8c,0xe7,0xe2,0xa5,0xf9,0x1c,0x0d,0x3a,0xb8,0xf2,0x5e,0x6f,0x3b,0xdd,0xac,0xf7,0x2d,0xeb,0xf9 +,0x81,0xdc,0x6e,0xb0,0xfd,0x1f,0x67,0x5a,0x69,0xa4,0x4b,0x70,0x2f,0x4a,0x33,0xd6,0xc3,0xf4,0x4a,0xac,0x7c,0xe5,0xa3,0xb7,0xb1,0x4a,0xb0,0xc6,0xf4,0xd1,0x0d,0x97 +,0x8d,0xfe,0x8f,0xb2,0x7a,0xb0,0x85,0x24,0x12,0xd4,0x9d,0x57,0x94,0x7e,0x14,0x8e,0x92,0xd0,0x86,0x7a,0xe2,0xc9,0x76,0xee,0xbf,0xd3,0xaa,0xdc,0x17,0x52,0xf9,0x2b +,0xb9,0x09,0xa6,0x80,0xa6,0x5e,0xfa,0x34,0xf1,0x24,0xd2,0x77,0x27,0xdd,0x0e,0xfb,0xdc,0x77,0x8e,0xb8,0x0a,0x94,0x77,0x1f,0xb3,0x52,0xd7,0x13,0xef,0x80,0x77,0xfb +,0xe3,0xbc,0x65,0x07,0x72,0x00,0x58,0x5e,0x8b,0x81,0x74,0x81,0x14,0x56,0x01,0x11,0x90,0xa8,0x1c,0xff,0xf1,0x50,0x80,0x2d,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0xbf,0xff +,0xff,0xfe,0xb0,0x80,0xb0,0xdc,0x30,0x35,0x0a,0x05,0x42,0x41,0x30,0x90,0x50,0x2a,0x14,0x29,0x05,0x02,0x43,0x10,0x98,0x44,0x26,0x15,0x08,0x84,0xc2,0x21,0x30,0x88 +,0x4c,0x22,0x13,0x08,0x91,0x95,0xaa,0xe3,0xd7,0xe3,0x92,0xf2,0x52,0xf7,0x79,0x75,0xaa,0x95,0x7a,0xb7,0x1f,0x3c,0x35,0xe3,0xca,0x65,0x7f,0xa0,0x2b,0x4d,0xfa,0xc3 +,0xcd,0x6c,0xbf,0x7f,0x0c,0x3d,0x2d,0x6e,0x6e,0x85,0x1e,0xb7,0x6d,0x3f,0x25,0xec,0xe2,0xfe,0xef,0xa3,0xed,0x67,0xca,0x37,0xe2,0x5f,0xf2,0x51,0x6a,0x50,0x7e,0xb7 +,0x2d,0x2d,0xcb,0xb9,0x80,0x2a,0xf9,0xdd,0x1e,0x8b,0x2e,0xf0,0xe1,0x50,0x59,0x6e,0xae,0x30,0xd7,0x85,0xc5,0x51,0xea,0xee,0x0d,0x30,0xeb,0x7d,0x31,0x49,0x5b,0x7b +,0xb6,0x5d,0x5c,0x16,0xe6,0x09,0xfe,0xe8,0x03,0xc4,0x00,0x77,0xd8,0x9c,0xca,0xbc,0x64,0x49,0x88,0xca,0x65,0x44,0x8f,0x70,0xb2,0x79,0x80,0xef,0x06,0x90,0x88,0x77 +,0x02,0x21,0x18,0x2f,0xe0,0x00,0x0b,0x89,0x81,0x52,0x81,0x62,0x20,0x58,0x26,0x14,0x1b,0x05,0x04,0xc7,0x40,0xb0,0x90,0x66,0x25,0x08,0x88,0xc2,0x21,0x30,0x88,0x8c +,0x22,0x56,0xb9,0x95,0x79,0xc4,0xcc,0xbc,0x95,0x57,0x52,0x8e,0x32,0x27,0x5c,0xf9,0xd6,0xbb,0xef,0x8e,0x3f,0x5f,0xe3,0xfc,0x57,0xdb,0x8f,0xb8,0xfd,0x31,0xfd,0xbe +,0xd6,0xfe,0x5e,0xde,0x3f,0x44,0xd5,0xab,0xf4,0xdf,0xed,0xfd,0xe7,0xf9,0xff,0x22,0xb0,0x7e,0xfe,0x39,0xaa,0xbf,0x33,0xd3,0xaa,0x68,0xca,0xc9,0xf6,0xca,0x1c,0xe5 +,0xb7,0x98,0x51,0xce,0x8a,0xf2,0x3e,0x77,0x91,0x1e,0x35,0x5b,0xc6,0x4c,0xb8,0x27,0x0a,0x83,0xfa,0x4d,0x9c,0x07,0xd9,0xce,0x5b,0xc8,0x28,0xb7,0xb3,0xbe,0x20,0xc8 +,0x8e,0xe0,0xc9,0x0d,0x8d,0xef,0x5e,0xbf,0x63,0x3d,0x93,0x27,0xb3,0x69,0x05,0x0a,0xcf,0xde,0x87,0xaf,0x6f,0x77,0xfa,0x0b,0xf0,0x9f,0xfa,0x83,0xc9,0xc4,0x00,0xd3 +,0x3b,0x83,0x18,0x17,0x7b,0xaa,0x58,0x47,0xac,0x42,0xa3,0xbc,0x2a,0x04,0xac,0xf2,0x02,0x5e,0xe8,0x44,0x80,0x00,0x14,0x04,0x4a,0x80,0xb0,0x0e,0xff,0xf1,0x50,0x80 +,0x2e,0x3f,0xfc,0x21,0x0a,0xcf,0xdd,0x77,0xf7,0x7f,0xfe,0xac,0x41,0x30,0x50,0x2e,0x16,0x0c,0x09,0x02,0xa1,0x40,0x98,0x50,0x44,0x15,0x12,0x05,0x82,0x81,0x20,0xa0 +,0x48,0x68,0x12,0x09,0x84,0x42,0x62,0x12,0x98,0x44,0xce,0x77,0xad,0xff,0x3f,0xdb,0xef,0x97,0x88,0xdf,0x9d,0xd4,0x53,0x5c,0xdc,0xaf,0x6e,0x7a,0x9e,0x08,0xe9,0xdc +,0xbf,0x8e,0x86,0x87,0xe3,0x3b,0xe3,0xee,0xbd,0xf1,0xb6,0x21,0xe7,0x73,0x23,0xec,0xdd,0x6e,0x5d,0x49,0xfa,0xcd,0x94,0xa7,0x3f,0x3b,0xed,0xf2,0xf4,0x94,0xae,0xff +,0x0e,0x45,0x39,0xa2,0xde,0x2a,0x0b,0x66,0x8d,0xf5,0x55,0xe7,0xae,0xbe,0x7e,0x26,0xc1,0x7e,0x02,0xd4,0x43,0x77,0x76,0xde,0x88,0x6a,0xcf,0xe2,0x8c,0xad,0x9f,0xdc +,0xbf,0x68,0x81,0x94,0x3d,0x2b,0xed,0x3b,0x83,0xdd,0xe9,0x6c,0x24,0x04,0x09,0xbb,0xaa,0xfb,0xa0,0x6b,0x44,0x69,0xef,0x3b,0x8a,0xc0,0x2d,0xdb,0x4b,0x40,0x2d,0xdc +,0x15,0xb7,0xee,0x3b,0xe2,0x50,0xa8,0xb0,0xac,0x02,0x30,0x6f,0x05,0x82,0xa0,0x17,0x5c,0x05,0x3a,0x05,0x84,0x81,0x61,0xa0,0x98,0x50,0x14,0x13,0x06,0x02,0x81,0x60 +,0xa0,0x58,0x48,0x36,0x0a,0x84,0x82,0xa7,0x31,0x09,0xdc,0x7b,0xeb,0x37,0xd7,0xd7,0xaf,0x1d,0x73,0x74,0xcd,0x2a,0x52,0xea,0x4c,0xbe,0xb5,0xdf,0x1b,0xeb,0xc4,0xeb +,0x7f,0x13,0xe7,0xaf,0x61,0xd1,0x6a,0xdb,0xd6,0xff,0x8c,0xde,0xcf,0xf3,0xe1,0xd7,0xe4,0x78,0xeb,0xef,0x5e,0x0d,0x58,0x90,0x5f,0xaf,0xb1,0xf8,0xbf,0xc2,0xaf,0xcc +,0x1e,0xe4,0x33,0x58,0x3f,0x6f,0xfa,0x09,0xb8,0xa8,0x4b,0xdd,0xfc,0xef,0xdf,0x6d,0x0a,0x74,0xc9,0x31,0x5d,0x43,0x8f,0x12,0xdb,0x35,0x85,0x2d,0xe7,0x8a,0x0c,0xe3 +,0x78,0x38,0x37,0x5b,0xbd,0xf7,0x59,0xf0,0x07,0x42,0xbc,0x2a,0x17,0x13,0xed,0xe7,0xcf,0xb1,0x26,0xcf,0x53,0x4d,0xd4,0x56,0xe3,0x5c,0x9d,0x0e,0x3c,0xeb,0xfc,0x69 +,0xcc,0x58,0xe6,0x1c,0x83,0x80,0x1e,0x61,0xc9,0x6f,0xb0,0x00,0x00,0x01,0xcf,0xc1,0xe9,0x9b,0x20,0xb9,0x00,0xf3,0x00,0x08,0x5c,0x2d,0xde,0xef,0x02,0xd1,0x48,0x33 +,0x1a,0x46,0xd1,0x40,0x10,0x01,0x5a,0x3b,0x80,0x35,0xa4,0x03,0x80,0xff,0xf1,0x50,0x80,0x30,0x1f,0xfc,0x21,0x0a,0xcf,0xfd,0xbf,0xdf,0xff,0xbc,0xb0,0x60,0xc0,0x58 +,0x4e,0x15,0x0c,0x09,0x04,0xc2,0x50,0xa0,0xd4,0x28,0x22,0x13,0x05,0x42,0x41,0x30,0xa8,0x48,0x2a,0x11,0x09,0x84,0x4e,0x61,0x10,0x98,0x44,0x6d,0xcb,0xcd,0x78,0xfd +,0x7c,0x7b,0x77,0x9a,0x55,0x49,0x45,0x25,0xd3,0xcf,0x8d,0x60,0xa4,0xe3,0x2f,0xf9,0xdf,0x00,0x7c,0x51,0xcd,0xf5,0x74,0xea,0x93,0xb5,0x3e,0x21,0xe4,0xee,0x50,0xe1 +,0xf9,0xc8,0xf0,0x34,0x23,0x4f,0x04,0x7b,0x9e,0xbd,0xc2,0xb7,0x67,0xe2,0xf8,0xae,0xfe,0x6a,0x05,0x76,0x2f,0x87,0x76,0x59,0xfa,0x6b,0xd5,0xf3,0x4c,0xa8,0xcf,0x57 +,0x26,0x46,0xd7,0xc7,0xe2,0xa3,0x6e,0x75,0x8f,0xe6,0x7f,0x3d,0xd6,0x4f,0xe0,0xb9,0xfb,0x26,0xab,0x4d,0xaa,0xf7,0xb3,0x16,0x32,0x60,0x3c,0x02,0x08,0x40,0xfc,0x9b +,0xeb,0xfd,0x68,0x93,0xdd,0x8d,0xf3,0x22,0x75,0xc1,0x09,0x14,0x56,0xd2,0x71,0x70,0xf3,0x0e,0xff,0x0d,0xb2,0x22,0xc1,0xa6,0x16,0x50,0x4b,0x2d,0x96,0x3d,0x57,0x62 +,0xb3,0xfc,0x35,0x09,0xc6,0x8d,0x6b,0xa0,0xa3,0xd6,0x89,0x04,0xd7,0x28,0x00,0xba,0x40,0x53,0x20,0x58,0x48,0x15,0x0b,0x09,0x02,0xa1,0x61,0x38,0x54,0x2c,0x24,0x0b +,0x0d,0xc2,0xc1,0x40,0xa8,0x58,0x2e,0x23,0x0b,0x84,0x44,0xa2,0x30,0x88,0x8c,0x2e,0x11,0x33,0x79,0x22,0xba,0xe3,0xd6,0xb9,0xd7,0xb7,0xe6,0x45,0x4a,0x91,0xac,0xd7 +,0x11,0x2b,0x77,0x59,0x7f,0x16,0xe7,0xdb,0xe8,0x7e,0x79,0x74,0xfb,0xe3,0xff,0xaf,0xd6,0x9f,0x6f,0x1d,0x9a,0xcd,0xd6,0x7a,0x4a,0x4e,0x57,0x53,0x0f,0xb3,0x47,0x0f +,0x3d,0xa2,0x8b,0xbd,0x74,0x73,0xfe,0xb8,0x61,0xbd,0x94,0x39,0xcd,0x68,0x49,0xeb,0x1e,0x98,0x9b,0xcc,0xdd,0xf0,0xf3,0xac,0x13,0x57,0xeb,0x16,0x2f,0x77,0xb1,0xff +,0x77,0xfa,0x23,0xa7,0x84,0xbe,0x3d,0xc3,0x09,0xda,0x6a,0xad,0xbc,0x7d,0xfe,0x4e,0x0c,0x39,0xf6,0xf4,0x81,0x5e,0x36,0x96,0x92,0xcd,0xbf,0xfa,0xd3,0xee,0x7f,0x88 +,0x0b,0x51,0x3e,0x68,0x61,0x89,0xd9,0x39,0xfa,0x04,0x93,0x43,0xd2,0xc8,0x00,0x00,0x07,0x93,0xbb,0x51,0xde,0x09,0xe0,0x58,0x85,0x81,0x2f,0x82,0xff,0xfd,0x09,0xbb +,0x30,0x00,0x0e,0x80,0x5c,0x00,0x11,0x0c,0x21,0x70,0x09,0x01,0xc0,0xff,0xf1,0x50,0x80,0x30,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xff,0x78,0xb0,0x70,0xb2,0x9c +,0x28,0x15,0x0a,0x05,0x82,0xa1,0x40,0xa8,0x50,0x6e,0x14,0x19,0x04,0x42,0xa1,0x31,0x90,0x4c,0x22,0x12,0x09,0x84,0x42,0x61,0x12,0x37,0xab,0xef,0xcf,0x3a,0xf3,0xef +,0xc6,0x70,0xee,0xe5,0x5e,0x4a,0xad,0x43,0x5a,0x6e,0xb3,0x5b,0x71,0xf1,0xbf,0x1f,0xf3,0xad,0x08,0xee,0xf5,0x7b,0x28,0xfb,0xfa,0x26,0xfb,0xce,0x5e,0xe8,0xfa,0xfd +,0x2a,0x8e,0xbe,0xa3,0xa7,0x63,0x04,0x4b,0xd0,0xd6,0xe4,0x51,0xcf,0xc5,0xcc,0xf7,0x86,0xf5,0x8b,0xd7,0x9c,0x3f,0x15,0x67,0x51,0xeb,0xf1,0x8a,0x42,0x6e,0x65,0xa5 +,0x88,0x6a,0x32,0x61,0xa3,0x51,0xed,0x99,0x61,0xf0,0xf0,0x9d,0xa5,0xff,0x10,0x2b,0x95,0xf6,0x5d,0xd5,0x04,0xe6,0x5c,0x9b,0x9d,0xea,0xf0,0xca,0x7e,0xeb,0x89,0x85 +,0x5d,0x6e,0xdb,0xac,0xf0,0x14,0x55,0x40,0x63,0xf7,0x3b,0xa0,0xf3,0x99,0x20,0xef,0x02,0x16,0xae,0xcf,0x74,0x94,0x8c,0x68,0x20,0xa0,0xf7,0x78,0xe0,0x72,0x5b,0xcb +,0xa0,0x96,0x00,0x57,0x8e,0x2c,0xee,0xd4,0x15,0xa8,0x16,0x01,0xdf,0x5f,0xc8,0x5c,0x09,0x00,0x2b,0x44,0x40,0xa6,0x40,0xb1,0x14,0x2c,0x25,0x0a,0x05,0x82,0xe1,0x60 +,0xa0,0x58,0x48,0x16,0x14,0x05,0x82,0x81,0x60,0xa0,0x58,0x2a,0x13,0x0a,0x8c,0x4a,0x41,0x10,0x98,0x44,0xa9,0xca,0xdd,0xeb,0xcf,0x75,0x17,0x8c,0xd6,0x25,0x5d,0x5e +,0xa6,0x6b,0x5d,0x26,0xbf,0x6f,0x1f,0xbf,0xc5,0xf3,0xbe,0x83,0xfc,0xda,0xf6,0xfb,0x08,0xf6,0xbf,0xe3,0xe2,0xd9,0xb9,0x38,0xf7,0xbe,0xaa,0x74,0x57,0xc5,0x58,0xfc +,0x23,0xb3,0x9f,0x2f,0xfd,0x75,0xdf,0xf1,0x43,0xc1,0x7b,0x58,0x7d,0x3f,0x85,0xdd,0x57,0x02,0xa8,0x29,0xfb,0x6a,0x3a,0xaa,0x30,0xf4,0x4d,0xa6,0x02,0xb3,0xd0,0x6f +,0xbb,0x5c,0xed,0x3f,0xd4,0x8e,0x14,0x89,0xac,0x8e,0xab,0xba,0xbd,0x21,0xd1,0xf3,0x05,0xc1,0xf8,0xa2,0x25,0xa0,0x14,0x39,0x7c,0x4f,0x77,0xcc,0x0e,0xe3,0xb9,0xfe +,0x33,0x35,0x76,0x8a,0x99,0x7d,0xc4,0x8e,0x27,0x1e,0x20,0xfa,0x56,0x90,0x00,0x86,0x10,0x22,0x14,0x24,0x2f,0x30,0x30,0x0a,0xa9,0xb3,0xa1,0xaa,0x0c,0xd1,0x6d,0x1c +,0xcf,0x1b,0xe2,0x00,0x7a,0xe0,0x13,0x04,0x80,0x40,0x20,0x56,0x84,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x2e,0x9f,0xfc,0x21,0x0a,0xcf,0xdf,0x5d,0xfe,0xff,0xfe,0xb1,0x70 +,0xc0,0x58,0x28,0x17,0x09,0x86,0x02,0x82,0x50,0xa1,0x58,0x28,0x16,0x0a,0x11,0x42,0x81,0x30,0x91,0x4c,0x42,0x13,0x08,0x8c,0xc4,0x24,0x57,0x9e,0xf3,0xef,0xf3,0xed +,0x7e,0x2e,0xea,0xf9,0x94,0x89,0x95,0xa4,0x43,0x55,0x9d,0x78,0xb9,0xec,0xcf,0x8f,0x80,0xae,0xec,0x8e,0xb7,0xf7,0xdf,0xff,0xee,0xbd,0xbf,0xe1,0xa5,0xaa,0xf8,0x4f +,0xc0,0xfe,0xe7,0xc9,0x8f,0x7e,0x3a,0x1f,0x0b,0x9f,0x73,0x68,0x35,0x1f,0x96,0x5f,0x44,0x2f,0x93,0x61,0xca,0xa9,0xc4,0x4e,0xff,0xe2,0x3c,0xb0,0x4f,0x8d,0x3d,0xdd +,0xc7,0xde,0xaf,0x96,0xa8,0xfb,0x07,0xdf,0xef,0xff,0x3a,0x13,0x8f,0x09,0x53,0xcb,0xda,0xaa,0x7c,0xc7,0xbf,0x92,0x18,0x7e,0xd7,0xb7,0x70,0xe3,0xe5,0x1e,0x3d,0x76 +,0xc6,0xab,0x6a,0x48,0x67,0x84,0xa7,0x97,0xec,0x5c,0xb8,0xc8,0x63,0x00,0xf6,0xdd,0x90,0xee,0x2c,0x42,0x8a,0xfc,0x14,0xa3,0x59,0x56,0x11,0x4f,0xbe,0xf6,0x22,0x16 +,0xfc,0xd1,0xe8,0xb6,0x9a,0xba,0xc3,0x22,0xf8,0xfd,0xf0,0x00,0x1e,0x6c,0x05,0xfb,0xab,0xb4,0x00,0x50,0x48,0x05,0xc0,0x4e,0x20,0x58,0x48,0x16,0x0a,0x05,0x82,0xa1 +,0x41,0x30,0x64,0x2c,0x34,0x0b,0x11,0x04,0xc1,0x41,0x18,0x48,0x22,0x35,0x10,0x8c,0xc2,0x27,0x7e,0x95,0x46,0x75,0xfa,0xff,0x13,0x7c,0x72,0xe3,0x6a,0x49,0x2a,0x7d +,0x7d,0xbf,0x5d,0x71,0xe9,0xc3,0x33,0xce,0x5f,0x8d,0x71,0x43,0x58,0xed,0x5d,0xe5,0xa9,0xdf,0x87,0xf3,0x53,0x6d,0x7b,0x38,0xa7,0xe9,0x2e,0x0d,0xa9,0x75,0x97,0xa9 +,0x2d,0x57,0x77,0x5d,0xee,0x29,0x2f,0x6d,0x17,0xff,0x63,0x40,0x3c,0xd4,0xf1,0x19,0xaa,0xea,0x5a,0x3d,0xc7,0x33,0x36,0x43,0x56,0x61,0xc4,0xbe,0x8b,0xf2,0x20,0x6d +,0x75,0xa4,0x8e,0xf7,0x6c,0x4b,0xa5,0x1e,0xa2,0x06,0x03,0x11,0x47,0xfd,0xa9,0x34,0x80,0x0e,0xd5,0xe7,0xd6,0x87,0x77,0x4f,0xed,0x66,0xcb,0x7e,0xfe,0x8a,0xad,0x4e +,0x8a,0xab,0x6a,0xc5,0x84,0x09,0x9e,0x40,0x00,0x78,0x89,0x00,0x01,0x5b,0x09,0x8b,0x84,0x12,0x09,0x88,0xf7,0x7b,0x08,0x05,0xc0,0x80,0x00,0x5e,0xa2,0x00,0x01,0x1c +,0x52,0x03,0x80,0xff,0xf1,0x50,0x80,0x2e,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xff,0xfc,0xb2,0x70,0xb0,0xe0,0x2c,0x24,0x2b,0x05,0x10,0xc2,0x40,0xb0,0x48,0x46 +,0x31,0x09,0x84,0x46,0x61,0x11,0x18,0xc4,0x49,0x5a,0xcd,0x77,0xed,0x4a,0x9a,0xe6,0xb5,0xb4,0x8a,0x5a,0x2f,0x8a,0xdf,0xd7,0xcd,0xd5,0xd3,0xca,0x7e,0x3c,0x87,0xae +,0xdf,0xbf,0xe3,0x97,0xdc,0xf7,0xfb,0xf9,0x77,0xf3,0xff,0x7c,0x9e,0x23,0xb4,0xf1,0xee,0xed,0x37,0x2c,0x21,0xe0,0x69,0x74,0x76,0xbd,0xd2,0x9f,0x96,0x05,0x0b,0xfb +,0x80,0x67,0x3b,0xef,0x34,0xd0,0x24,0xdc,0x7f,0x3e,0x86,0x57,0x9c,0xc4,0x57,0xaa,0xe1,0xa2,0x90,0x6e,0xd9,0x05,0x0a,0x55,0xb7,0x44,0x1f,0x25,0x6a,0x3b,0xef,0x45 +,0x24,0x50,0xf6,0x4a,0xb0,0xb1,0x83,0x36,0xa9,0xc5,0x77,0xa7,0x62,0x6b,0x78,0xb0,0x21,0xde,0xba,0x1d,0xfa,0xce,0xa4,0xd7,0x9c,0x55,0xb5,0x07,0xba,0x1a,0x3b,0x96 +,0x48,0x42,0x6c,0xd2,0x8d,0xd8,0x0b,0xdd,0x55,0xd1,0xef,0x18,0x43,0xb1,0x48,0x05,0x28,0x07,0xac,0x0e,0xe8,0xee,0x58,0x01,0x10,0x80,0x0a,0x86,0x42,0x09,0x43,0x01 +,0x62,0x28,0x58,0x48,0x16,0x0a,0x05,0x82,0xa1,0x40,0xa8,0x84,0x26,0x15,0x08,0x85,0x42,0x63,0x50,0x98,0x84,0x46,0x11,0x13,0xdb,0xd6,0x5d,0xef,0x55,0x4c,0xbd,0x77 +,0x74,0x11,0x75,0xc4,0xfa,0xf7,0xe2,0xfd,0x54,0xbc,0xe2,0xb8,0xbd,0xea,0x04,0xdd,0xbe,0xff,0x17,0xdd,0x55,0xff,0x87,0xe5,0x57,0x53,0xf0,0xe6,0x3b,0xf7,0xc5,0xe6 +,0x81,0x6a,0xd7,0xe3,0x81,0x7b,0xf6,0x4f,0x1a,0x35,0xe7,0x5c,0x5e,0x73,0xf6,0x7c,0x2b,0xe2,0xf7,0xe1,0xf8,0xbc,0xef,0xbb,0xe9,0x34,0xe5,0x4f,0x67,0xf1,0xcf,0xff +,0x92,0xa6,0x3f,0x54,0xab,0xca,0x9f,0xe2,0xbd,0xb5,0x5c,0x38,0x5f,0x38,0x5e,0x1f,0x32,0x59,0xe7,0xcf,0x84,0xfc,0xb7,0xd3,0xa7,0xdb,0xaa,0xb8,0x41,0xc0,0x78,0x9f +,0x74,0x80,0xe2,0x10,0x94,0x51,0xee,0x1d,0xd7,0xae,0x00,0x01,0xe5,0xda,0x40,0x07,0x17,0xa8,0x01,0x52,0xb0,0x83,0xb8,0x77,0x4f,0x69,0x2c,0x05,0xfd,0x63,0xdc,0x07 +,0x31,0x01,0xe0,0x7b,0x83,0xd6,0x1d,0xf0,0x3b,0xc0,0xbd,0x41,0x02,0xef,0x5c,0x06,0xd0,0xd2,0x6d,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a,0xcf,0xff +,0xeb,0xff,0xff,0xbf,0xb1,0x70,0xb0,0x5c,0x2c,0x27,0x0c,0x05,0x44,0x82,0x50,0x90,0x50,0x2a,0x14,0x39,0x05,0x02,0x42,0x10,0x98,0x44,0x46,0x11,0x39,0x84,0x48,0xce +,0x37,0x9d,0x7a,0xf8,0xa6,0xaa,0x37,0x37,0xc6,0x48,0xcb,0x71,0x5d,0x66,0xfa,0xca,0x57,0x1d,0xf1,0xf1,0xea,0xfc,0xe8,0x3d,0x79,0xbd,0x1d,0xec,0x75,0xed,0xd3,0xa2 +,0xfe,0xbf,0x3a,0x53,0xb3,0xa9,0xd4,0x79,0xf7,0xf7,0x4f,0x6f,0x2f,0x1d,0x25,0x7b,0x9b,0xd9,0x5b,0x90,0xfd,0x8b,0x63,0x3d,0xeb,0xf0,0x81,0xa9,0x71,0x3e,0xd0,0xd1 +,0x01,0x16,0xfc,0xc4,0xea,0x6d,0x11,0x27,0x82,0x3f,0xdf,0x1e,0x74,0x95,0x8d,0x82,0x70,0xb7,0x41,0x8f,0x3b,0xf1,0xc7,0x54,0xbd,0x37,0x29,0x5a,0xd3,0xe0,0x94,0x69 +,0x29,0xcb,0x1e,0xb0,0x93,0x9a,0x18,0xf4,0xbb,0xf0,0x40,0x4b,0xd6,0x06,0xcb,0x50,0x4a,0x02,0xda,0xaa,0x44,0x5a,0x77,0x05,0xe5,0x08,0x22,0x42,0xdb,0x0a,0x44,0x36 +,0x0e,0xe0,0x17,0xa8,0x4c,0x58,0x48,0x05,0x40,0x54,0x32,0x10,0x4c,0x34,0x0b,0x05,0x02,0xc1,0x70,0xb0,0x90,0x2c,0x14,0x0a,0x89,0x02,0xa2,0x33,0x28,0x4c,0xc2,0x26 +,0xb9,0x5d,0x6f,0xe3,0x69,0xcd,0xd6,0x5d,0x4a,0xa8,0x91,0x77,0x75,0xa7,0x73,0x8e,0x4b,0x75,0x75,0xc0,0xd8,0x5a,0x0b,0xbc,0x47,0xc3,0x68,0xeb,0xae,0x4e,0xde,0xaa +,0xfa,0x2f,0xf0,0x7b,0x6a,0x0a,0xb0,0x2b,0x7d,0x94,0x05,0x3e,0xff,0xe8,0x14,0x7b,0x2b,0x3e,0x3a,0x4f,0xff,0x1a,0xb9,0xed,0x08,0xd0,0xe6,0xee,0xf0,0x57,0x77,0x0a +,0xd2,0xeb,0x65,0xd1,0xae,0xfa,0x3f,0xb1,0xfe,0xdf,0xfa,0x95,0x7c,0x93,0x6b,0xa6,0x54,0xe0,0x3f,0x74,0x43,0xa4,0x5e,0x5f,0x57,0xa9,0xcb,0x87,0x67,0x2e,0x1c,0xaa +,0x9c,0x4e,0x71,0x63,0xd6,0x56,0xf5,0xc9,0xcc,0x43,0x4a,0xe1,0x87,0x33,0x80,0x50,0x44,0x26,0xf6,0x7e,0xf6,0x41,0xee,0xbf,0x64,0xf6,0xa3,0xba,0x27,0xf1,0x9d,0x4f +,0xc5,0x54,0x96,0xd7,0xad,0x2a,0xd1,0xa2,0x29,0xdd,0x7a,0xfd,0xc0,0xe3,0x3a,0xc2,0xc3,0x8c,0x4f,0xaf,0x42,0xb9,0x78,0x04,0xfd,0x9b,0xd6,0x83,0xa9,0xfa,0x94,0x43 +,0xd6,0xef,0x10,0xef,0x84,0x41,0xdc,0x07,0x7c,0x85,0x80,0xc0,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0x6f,0xff,0xff,0xef,0xad,0x70,0xc0 +,0x58,0x30,0x16,0x22,0x08,0xc2,0xa1,0x41,0x30,0x54,0x2c,0x14,0x0a,0x89,0x04,0x43,0x11,0x10,0x45,0x4a,0x11,0x23,0xd7,0x5c,0xeb,0x9d,0x7b,0x4c,0xbc,0x65,0x24,0xcd +,0x66,0xb2,0x5c,0x57,0x19,0x31,0x21,0x63,0xf9,0xd0,0x9f,0x5e,0xff,0x8e,0x7e,0x63,0xd2,0x37,0xaa,0xbf,0xf3,0x1f,0x2f,0xb5,0xbf,0x65,0xcf,0xbf,0x3c,0xf4,0x2a,0xea +,0xfe,0x23,0x4a,0x03,0xd5,0x1a,0x89,0xcb,0xae,0xd4,0x8b,0x4f,0x07,0xb3,0x9d,0xe7,0xc1,0xcd,0xd6,0x8f,0x66,0x66,0xcc,0xe8,0x1c,0x7e,0xe7,0xa9,0xf3,0x2c,0x7b,0x7f +,0x90,0x77,0xfc,0x93,0x84,0x51,0x60,0xe1,0x2e,0x7a,0x27,0xa1,0x1f,0x2e,0xc6,0x84,0xd4,0xa2,0x1c,0x12,0x97,0xc2,0x0d,0x02,0x37,0x4a,0x9c,0x96,0xb2,0x52,0x77,0x51 +,0x58,0x22,0xee,0xd1,0x7c,0x82,0x19,0x17,0x2b,0xbf,0x9d,0x95,0x52,0xf1,0x03,0x5d,0x24,0x26,0xb2,0xac,0xe9,0x82,0x40,0x79,0x84,0x1a,0x23,0x00,0x40,0xa4,0x4a,0x50 +,0x08,0x80,0xa7,0x64,0x20,0x98,0x30,0x15,0x13,0x05,0x02,0xc3,0x40,0xb0,0x50,0x4c,0x15,0x19,0x8d,0x42,0x41,0x10,0x98,0x48,0x26,0x11,0x09,0x85,0x42,0x61,0x11,0x99 +,0x78,0xce,0xb5,0xcc,0xe7,0x52,0xaa,0x8b,0xac,0xb9,0x76,0xe2,0x95,0xb9,0x7b,0xbc,0xd5,0xbe,0x96,0x3d,0x45,0x8f,0x2f,0x4d,0xfd,0x87,0xac,0xae,0xd7,0x27,0xe8,0xf8 +,0x7e,0x23,0xe5,0x93,0x3f,0xbc,0x57,0xbc,0xae,0x97,0x3f,0x07,0x3b,0xfe,0x39,0x6f,0x52,0x5d,0x11,0xbf,0x52,0x1c,0xb3,0x6b,0xeb,0xab,0x8c,0xc7,0xea,0xd5,0xcd,0x2c +,0xf3,0xff,0x3d,0xd4,0x88,0x65,0x53,0xe9,0xf8,0x13,0x7d,0x7f,0x5d,0xe3,0x25,0xff,0xe6,0x0e,0x7d,0x65,0x31,0x5a,0x93,0x80,0x79,0xee,0x79,0x61,0x4d,0xcc,0x08,0xf9 +,0xa5,0xc4,0x39,0x86,0xef,0x92,0x5f,0xba,0x3d,0x63,0xfa,0x63,0xd1,0x9f,0x52,0x07,0xac,0x65,0x1c,0x0a,0x73,0x4a,0x6d,0x7b,0xb5,0xa9,0x82,0x45,0xa4,0x6d,0xad,0xee +,0x81,0x7e,0xfc,0x6d,0x28,0x67,0x14,0xb1,0x2f,0x76,0x04,0xda,0xbf,0xd6,0x55,0x86,0xd9,0xbb,0x55,0xb9,0x9d,0xee,0x92,0xef,0xbc,0x00,0x03,0xc4,0xf4,0x70,0xd3,0x00 +,0x54,0x08,0x2a,0xcc,0x03,0x80,0xff,0xf1,0x50,0x80,0x2d,0xff,0xfc,0x21,0x2a,0xcf,0xff,0xff,0x9d,0xd4,0x1e,0xaf,0x62,0x40,0x98,0x48,0x13,0x0a,0x89,0x82,0x84,0x61 +,0x20,0x94,0x28,0x22,0x11,0x84,0x4c,0x61,0x14,0xbb,0xd6,0xf5,0x4f,0x8c,0xe7,0x57,0x7c,0x89,0x51,0x08,0xf6,0xdf,0xb5,0x77,0xe7,0xde,0xf9,0x95,0x34,0xe3,0xf7,0xd8 +,0xcf,0xc7,0x46,0xef,0x5e,0x5d,0x3c,0x80,0xf2,0x3a,0x45,0x8f,0x93,0xe8,0x3c,0x83,0xf8,0x13,0x8f,0x90,0xbf,0x30,0xa7,0x9d,0x9d,0x20,0x3e,0xd9,0xd3,0x73,0x1d,0xdf +,0xbf,0xdf,0x75,0xc0,0x1d,0x0d,0xbd,0x8d,0xc0,0x8b,0xf0,0x6c,0xd1,0xe0,0xd3,0xab,0xca,0xb9,0x43,0x2b,0xe4,0x4c,0x20,0x11,0xbf,0x3d,0xa9,0x88,0xb6,0xf7,0x45,0x57 +,0x8a,0x6d,0x99,0x9e,0x88,0x8c,0x56,0xaa,0x52,0xde,0x0f,0xf0,0x0c,0xf1,0x80,0xc6,0x2a,0xa2,0x9b,0x80,0xc7,0x7d,0xa5,0x9d,0xf0,0xba,0xa3,0x3d,0xe1,0x90,0x07,0xeb +,0x2e,0xe7,0xfc,0xbd,0xcd,0x4b,0xc1,0x10,0x22,0xa4,0xd7,0x67,0xb8,0x27,0x30,0x55,0x20,0x50,0x0a,0x84,0x13,0x15,0x06,0xc1,0x50,0xa0,0x58,0xf0,0x14,0x2a,0x84,0xc2 +,0xa1,0x30,0x88,0x4c,0x22,0x15,0x11,0x8c,0x44,0x61,0x11,0x26,0x2b,0x59,0x77,0x37,0x55,0x75,0x37,0x12,0xa4,0x5b,0xac,0xd5,0x64,0xce,0xb2,0xaf,0x75,0x3f,0x0d,0x0f +,0x8c,0xff,0xcb,0xe3,0x2e,0xd9,0x76,0xcf,0x7f,0x3b,0xba,0xbf,0xa9,0xe9,0xbf,0xd8,0x55,0x76,0xe1,0xf1,0x97,0x87,0xdf,0xff,0x99,0x6d,0xb9,0x23,0x5d,0xe1,0x2c,0x5b +,0x2f,0xeb,0x66,0x53,0x5f,0x9d,0x37,0x7c,0x36,0x5f,0xae,0x7a,0x27,0x92,0x7a,0x4b,0xb1,0x67,0xa8,0xa0,0x69,0xe3,0x02,0xb3,0x93,0x78,0xc8,0x7f,0xd7,0xfe,0x8f,0xf4 +,0xcd,0xee,0x6f,0x7b,0x77,0x6f,0xd5,0x37,0xfa,0x0d,0x5b,0x4d,0x9f,0x70,0x96,0xaf,0xe9,0xab,0xbd,0x5e,0x40,0xe0,0xf7,0x70,0x2d,0x5f,0x2a,0xd7,0x99,0xe1,0xab,0x04 +,0x87,0xed,0xbd,0x72,0x44,0x72,0x63,0x5e,0x83,0xb6,0x8b,0x61,0x2f,0x12,0x91,0xaa,0x13,0xbd,0x05,0x05,0xc3,0xc0,0x03,0xed,0x00,0xa0,0x39,0xf8,0xdd,0xf6,0xa3,0xb8 +,0xa9,0x7e,0xf1,0x29,0x0c,0x6a,0x76,0x86,0xd9,0xf1,0xbb,0xf1,0xc0,0x0e,0xe1,0xde,0x0a,0xdc,0x16,0x03,0x80,0xff,0xf1,0x50,0x80,0x33,0x7f,0xfc,0x21,0x4c,0xfe,0xff +,0xfd,0x54,0x36,0x6a,0x8d,0x09,0x32,0xd2,0x5d,0x49,0x75,0x38,0x1c,0x2a,0xe6,0x3f,0xdd,0xc4,0x7f,0x86,0xa2,0x36,0xe7,0xec,0x63,0xe7,0xd5,0x7d,0x43,0x29,0x1b,0xe5 +,0xc4,0x09,0x65,0x68,0x9f,0xa0,0xfd,0x2c,0x4b,0xeb,0x0b,0x44,0x09,0x91,0xb4,0x0c,0xd6,0x2c,0x10,0x09,0xa6,0x0a,0x1b,0x94,0x53,0x3f,0x37,0xf9,0x7e,0x05,0x7b,0xdd +,0xd6,0xc1,0x90,0xb4,0xd3,0x94,0x98,0x4c,0x04,0xa2,0x33,0x97,0x19,0xc1,0x89,0x4c,0x0a,0xe2,0x50,0x06,0xa3,0x3c,0x3c,0x2b,0x77,0xc1,0x5f,0x2b,0x5a,0x63,0x82,0xc1 +,0x95,0xce,0xf3,0x53,0xf3,0xfb,0xfe,0x18,0x9c,0xcd,0x76,0xf0,0xf9,0x9c,0xc1,0x2a,0x18,0xb6,0x2f,0x57,0xfc,0x69,0xa8,0xcd,0xaf,0x86,0x18,0xb4,0x52,0xb5,0xd5,0x33 +,0xdb,0x7f,0xd2,0x1d,0x5f,0xf9,0xf7,0xeb,0x34,0x74,0x73,0x14,0xab,0x42,0xd5,0x11,0xd9,0x71,0x53,0x8e,0x9d,0x07,0x8f,0xf0,0x48,0xca,0x4c,0xdc,0xe6,0x42,0xd7,0x10 +,0x95,0xb3,0x6a,0xf3,0xdb,0xd5,0xd9,0x09,0x60,0x54,0x80,0x8d,0x4b,0xd0,0xc1,0x43,0xd5,0xaa,0x42,0x05,0x28,0x63,0x89,0x41,0x11,0xa2,0x33,0x29,0x55,0x6b,0x94,0x74 +,0x0b,0x7e,0xae,0x97,0xc3,0x8d,0x3a,0x2c,0xbc,0x42,0xa2,0xbe,0xce,0x5f,0x9c,0xb7,0xee,0xb5,0x72,0x2c,0x58,0xa1,0x60,0xfc,0xbb,0xab,0xd1,0xe5,0x27,0xbf,0x00,0x72 +,0xb2,0x98,0x1f,0x92,0xc1,0x82,0x26,0x2a,0xf5,0xda,0xfc,0xea,0xc6,0xb0,0x93,0x1a,0x7a,0x7a,0xd1,0x3d,0x26,0xb6,0xc0,0xaa,0x86,0xa6,0xae,0xf9,0xfc,0xd8,0xc9,0x85 +,0x3f,0x51,0x1d,0x77,0x7a,0xa7,0x99,0x07,0x3e,0xd2,0x2c,0xae,0x21,0x5f,0x52,0xbf,0x1d,0x8f,0x86,0x72,0xf1,0xbb,0x3c,0xba,0x2f,0x7b,0x76,0xb5,0x10,0xe4,0x40,0x23 +,0x30,0x56,0x50,0x55,0xc4,0xfb,0xaa,0x39,0x9e,0x75,0x52,0xa8,0x5e,0xcd,0x23,0x01,0x00,0xf7,0x32,0xa4,0x18,0x20,0x14,0xa7,0x71,0x22,0x89,0x8f,0x14,0x56,0xa8,0x45 +,0xda,0x61,0x06,0x2f,0x5a,0xa8,0xa3,0xdf,0x7c,0xbf,0x87,0xe1,0x92,0x69,0x3e,0xd0,0xf7,0x2a,0xea,0xd0,0x76,0xe1,0x79,0x96,0x2c,0x1e,0x39,0x65,0xd2,0xe7,0x4a,0x78 +,0x2e,0x0a,0x2c,0xc1,0x54,0xf6,0x8d,0xed,0xe6,0xa5,0x1b,0x77,0xd7,0x5d,0x23,0xd4,0xa8,0xbc,0x98,0xd5,0x93,0x74,0xfa,0x3e,0xf9,0xbe,0xc1,0xc5,0x47,0x8e,0x28,0x30 +,0x7f,0xad,0xb4,0x9d,0x56,0x81,0x61,0xb4,0xd5,0x68,0xdc,0xb8,0xad,0x8b,0x58,0xe0,0xff,0xf1,0x50,0x80,0x30,0x9f,0xfc,0x21,0x6a,0xcf,0xfd,0xbf,0xff,0xff,0xff,0xb3 +,0x81,0xb0,0x8c,0x2c,0x15,0x0a,0x05,0x82,0x81,0x61,0xb8,0x58,0x48,0x25,0x0b,0x05,0x0a,0x42,0x17,0xb3,0x89,0x9e,0x7b,0xeb,0x9b,0x9c,0xaf,0x76,0xd5,0x5a,0x6e,0x55 +,0xd2,0xce,0x29,0x57,0x4a,0xd3,0xce,0x86,0xa7,0xc5,0xa6,0xc6,0xd5,0xbf,0xcd,0xb9,0xc7,0xe6,0x38,0x23,0xa3,0x56,0x6c,0x9b,0x79,0xd0,0xc0,0xaf,0xff,0x80,0xfe,0xb4 +,0xd5,0xb5,0x9b,0xe1,0x68,0x9c,0x59,0x08,0xbe,0xf7,0x8a,0x66,0x7b,0x0f,0x8e,0x09,0xb8,0xf5,0x4d,0xcd,0xa1,0xba,0x0f,0x0f,0x8f,0x1d,0xc8,0xc3,0x48,0x1a,0xd9,0x23 +,0xd2,0xbd,0x98,0xb6,0xce,0x74,0xfd,0x08,0x83,0x90,0xb3,0x5b,0x67,0x4e,0xa6,0xf8,0x98,0x82,0x9c,0xfc,0xdf,0xd5,0x4c,0xcb,0xe9,0xe8,0x65,0xc6,0x8a,0x31,0xcf,0x28 +,0x4a,0x85,0x74,0x50,0xed,0x7a,0x89,0x6a,0x65,0x22,0xa6,0x65,0x8a,0x42,0x75,0x99,0x69,0x8e,0x59,0x44,0x13,0xb9,0xf3,0x0e,0x96,0x05,0x66,0xad,0x96,0x14,0x81,0x10 +,0x8e,0x00,0x02,0x82,0xe0,0x51,0x20,0x48,0x2c,0x44,0x0b,0x04,0x82,0xc5,0x80,0xb0,0x60,0x2c,0x15,0x0a,0x05,0x42,0xc1,0x51,0x38,0x54,0x4e,0x13,0x1a,0x04,0xc4,0xa1 +,0x31,0x88,0x8c,0x22,0x23,0xd6,0xe7,0x19,0xc7,0xdf,0xfa,0xc9,0x5a,0xef,0x58,0xbc,0xbb,0xc5,0xf1,0xb9,0xd7,0x35,0x96,0x5d,0xdc,0xe7,0x57,0xc0,0xe7,0xbe,0xe7,0xfb +,0xee,0xf0,0xf7,0xe6,0xbd,0x7f,0xfd,0x37,0x37,0x2a,0xb4,0x36,0xa5,0x9d,0x69,0x3d,0x35,0x5f,0x97,0x3d,0x7a,0xed,0x6d,0x58,0x05,0x87,0x63,0x76,0x4a,0x7e,0x02,0x88 +,0xef,0xbf,0x29,0x69,0xb5,0xfc,0x5c,0x98,0xff,0x07,0xfd,0xda,0x97,0x1c,0xb8,0xfd,0xc7,0x5f,0x21,0x44,0xb4,0xcb,0xa2,0x6f,0xee,0x72,0xe6,0xe7,0x59,0xf9,0xbc,0xd4 +,0xe5,0xd5,0x78,0x70,0x44,0x8a,0xcc,0x3c,0x6f,0x17,0x6a,0x2b,0xde,0xe6,0xe4,0xca,0xec,0xf1,0xb6,0x00,0x39,0xb4,0x3e,0x47,0x82,0x22,0x4e,0xe4,0x9c,0x1f,0x81,0x3c +,0x68,0x3e,0x0a,0xcf,0x0b,0x1f,0x5e,0x6a,0xbb,0x2d,0xb9,0x94,0x83,0x8b,0xd1,0xbd,0x72,0xf1,0xd2,0xb5,0x24,0x5f,0x2d,0x02,0xfc,0xb7,0x3f,0x94,0x0a,0x54,0xfa,0xd2 +,0x35,0x8b,0xff,0xf1,0x65,0xc5,0xaa,0x58,0x4d,0x33,0x35,0x5e,0xeb,0x28,0x29,0x18,0x02,0x50,0x03,0x80,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x0a,0xcf,0xf7,0xbf +,0xff,0xff,0xfe,0xb4,0x61,0x40,0x58,0x46,0x14,0x1b,0x0a,0x04,0xc1,0x80,0xb0,0x50,0x4c,0x14,0x12,0x85,0x08,0x43,0x11,0x98,0x85,0x27,0x5b,0x92,0xba,0x73,0x29,0xc7 +,0x7a,0xab,0xab,0xbd,0x9a,0xc1,0xa3,0x8c,0x9b,0x9f,0x1e,0xad,0xf5,0xc0,0xf9,0x7d,0x7d,0xdf,0xbe,0x92,0x14,0xf4,0x2f,0x1f,0xcd,0xfd,0xcb,0x8e,0x7f,0xfc,0xf0,0x2a +,0x07,0x6a,0xac,0xe8,0xea,0x02,0x0d,0x12,0xd3,0x99,0xbf,0xaa,0xf2,0xd7,0xba,0x0d,0xcd,0x72,0xad,0x3c,0x2b,0x6c,0xaf,0x4c,0x80,0xa5,0x0f,0xbf,0x3f,0x10,0xec,0xf3 +,0xb9,0xd2,0x7d,0xd3,0x6c,0xed,0x59,0xf8,0xe3,0x78,0xc1,0x40,0xf8,0x7b,0x6f,0x0b,0x9d,0xdb,0x6e,0xa9,0x6e,0x62,0x98,0x23,0x46,0xf6,0xf9,0x63,0x3f,0xc3,0x81,0x56 +,0x07,0x1a,0x5a,0xc9,0x26,0x8e,0x91,0xd3,0x09,0xa7,0x28,0xda,0xf4,0x92,0xb9,0x57,0x9c,0xb7,0x45,0x34,0x4d,0x23,0xbc,0x4f,0xbd,0x08,0x9d,0x3f,0x50,0x19,0x30,0xac +,0x4c,0x65,0xa0,0x02,0x77,0x44,0x2b,0x3b,0xa6,0xb8,0x82,0xe9,0x04,0xc0,0x5c,0x0a,0x94,0x0b,0x11,0x02,0xc3,0x71,0x31,0x54,0x2c,0x34,0x0a,0x90,0xc2,0xa1,0x10,0xb8 +,0x4c,0x2a,0x13,0x28,0x9d,0xed,0xe1,0xbf,0xaf,0x9a,0xf8,0xdd,0x5e,0x7e,0x3f,0x6b,0x54,0xa2,0x5d,0x7b,0x77,0xed,0xb3,0x7a,0xbd,0xeb,0x9f,0x8b,0xce,0x7c,0xc1,0xff +,0xff,0x90,0xfe,0x06,0xaf,0x47,0x76,0x9d,0x53,0xeb,0xb7,0x5f,0xd3,0xf1,0xbb,0xb2,0x36,0xfa,0xda,0x56,0xc2,0xf5,0x79,0x34,0xd5,0x90,0xb6,0xbd,0x78,0xec,0xd5,0x67 +,0x29,0x32,0x47,0xc3,0xe3,0x8f,0x6d,0xc8,0x19,0xd3,0x85,0x2e,0x01,0xc7,0x30,0xc7,0x20,0xe5,0xee,0xff,0xf2,0xfb,0xf3,0x97,0x2e,0x4f,0x95,0xfc,0xfa,0x0e,0x2a,0xe3 +,0xc1,0xc3,0xc7,0x8f,0x8f,0x00,0x7c,0xf9,0x1c,0x87,0x15,0x4e,0x9d,0xe3,0x1e,0x55,0xe2,0x1c,0xc9,0x7b,0xa2,0x39,0xbb,0x98,0x20,0x01,0xdc,0x3d,0xc3,0xbf,0xda,0x00 +,0x3c,0xf9,0x70,0x69,0xf7,0xd2,0x84,0x47,0x74,0xff,0x10,0x25,0x77,0x76,0xd5,0xfd,0xaf,0xfe,0x4b,0x02,0x3f,0xfa,0xc0,0x63,0xad,0x08,0x64,0x04,0xe2,0xbd,0xa0,0x00 +,0xda,0x43,0xb4,0x2a,0x01,0x64,0x4a,0x58,0x0e,0xff,0xf1,0x50,0x80,0x30,0xdf,0xfc,0x21,0x0a,0xcf,0xbf,0xfb,0xff,0xe7,0xfd,0xb2,0x60,0xc0,0x58,0x48,0x36,0x13,0x85 +,0x02,0xe1,0x61,0x38,0x58,0x4a,0x14,0x48,0x84,0x82,0x61,0x50,0x89,0x8c,0x22,0x13,0x10,0x89,0x57,0x5d,0x6d,0xaf,0x8f,0xd3,0x8e,0x78,0xcc,0xd4,0x92,0x84,0xa4,0xa9 +,0xa9,0xcc,0x54,0xbf,0x3d,0xfb,0x56,0xbc,0x8d,0x1d,0xd2,0xb4,0x5d,0xe7,0xdb,0x2f,0xd2,0x3f,0xfe,0x7e,0x8b,0x53,0x78,0x7e,0x3b,0xc8,0xfb,0x8e,0xa2,0xaa,0x7f,0x09 +,0x1d,0x7b,0x8b,0x68,0x53,0xf8,0xb3,0x01,0xea,0xb8,0xb7,0xd0,0x51,0xf5,0xfb,0xc9,0xea,0xfe,0x46,0x9f,0x2b,0x45,0x9f,0xf6,0x82,0xf6,0xbb,0x35,0xc9,0xfe,0x0d,0xc7 +,0x04,0x7a,0x10,0xe1,0xa2,0xe5,0xc3,0x80,0xe6,0x42,0xeb,0x47,0x00,0x92,0xd2,0x75,0xd5,0xcf,0x5c,0xfc,0x40,0x82,0x44,0x30,0x8f,0x63,0xe3,0xda,0xa9,0x81,0x37,0x74 +,0x65,0x1b,0x12,0xdb,0x7a,0x07,0x10,0x4f,0x0e,0x62,0xe4,0x89,0xe8,0xe9,0xc1,0x97,0x0a,0x26,0x56,0x84,0xb4,0xa6,0x9e,0xf8,0x20,0xbd,0xa8,0x8f,0xf1,0x9a,0x70,0x94 +,0xd1,0x6d,0xad,0x16,0x8c,0xeb,0x07,0x74,0x3f,0x27,0xb9,0x5d,0xde,0xe8,0xdc,0x7b,0x81,0xdd,0x3d,0x74,0x00,0x88,0xa8,0xa8,0x14,0x28,0x12,0x0b,0x0a,0x02,0xc2,0x41 +,0x30,0x50,0x30,0x16,0x1a,0x06,0x02,0xc2,0x50,0xa0,0x94,0x28,0x15,0x11,0x84,0x42,0x62,0x51,0x18,0xc5,0x0e,0x77,0x9c,0xfc,0x72,0xf3,0xe2,0x1e,0xde,0xf3,0x9b,0x91 +,0x74,0xae,0x2b,0xea,0x7a,0xad,0xf1,0x9c,0x7b,0x2f,0x24,0xde,0x87,0x42,0xf9,0x97,0x67,0x0c,0x69,0x68,0x8b,0x77,0x15,0xd3,0x3f,0x9d,0xe0,0x5f,0x7e,0xe0,0x80,0x13 +,0xf8,0x9c,0xbf,0x29,0x5d,0x89,0xbb,0xa2,0x4c,0x9d,0x4f,0xdc,0xf0,0xf2,0xdf,0x7a,0x2d,0x97,0x98,0xe7,0xcc,0xb5,0x1d,0xf5,0xe3,0xc3,0xe0,0x70,0xd9,0xfe,0x5d,0x87 +,0xba,0xc7,0x1c,0xff,0x37,0xc4,0x38,0x5f,0x6b,0xf3,0xbf,0xea,0xbb,0x96,0x1c,0x63,0xc6,0x9d,0x2e,0x0e,0x5c,0x9c,0x89,0xa3,0xee,0x1f,0xee,0x7b,0x8a,0x24,0x2b,0xc1 +,0xb7,0xe2,0x9a,0xa7,0xd6,0xf7,0xa2,0x22,0x39,0xf2,0x00,0x78,0x8f,0x80,0x38,0x66,0xce,0x01,0xe0,0xbd,0xd4,0x26,0xa4,0x69,0x59,0x55,0xf5,0xa7,0xad,0xdd,0xef,0x8a +,0x48,0x04,0xc2,0xa8,0xaa,0x00,0x44,0x50,0x00,0x20,0x08,0xa6,0xb5,0x40,0xe0,0xff,0xf1,0x50,0x80,0x2e,0xdf,0xfc,0x21,0x0a,0xcf,0xbf,0xbf,0xff,0xf7,0xfc,0xb0,0x60 +,0xc0,0x98,0x48,0x16,0x22,0x05,0x82,0xe1,0x60,0xc0,0x58,0x28,0x25,0x12,0x05,0x42,0x84,0x21,0x08,0x48,0x22,0x13,0x18,0xa5,0x9c,0x73,0xe7,0x2a,0xef,0x99,0x4e,0xbd +,0xf8,0x55,0xc9,0x31,0x6c,0xd5,0x26,0xa4,0xde,0x71,0xf5,0xee,0x9f,0xbe,0x84,0x9b,0x60,0xe7,0xeb,0x2e,0xbf,0x18,0xe9,0x8d,0x25,0x1e,0x8e,0x15,0xea,0x4e,0x2b,0xf7 +,0xee,0x44,0xe7,0x1f,0xf7,0x6b,0xd6,0x89,0xba,0xfd,0xff,0xbf,0x64,0x54,0x2b,0xd6,0xd7,0x8f,0x40,0xd9,0x35,0x51,0x6e,0x1f,0xcf,0xfc,0xa4,0x77,0x7b,0x15,0x19,0xd0 +,0xfc,0x7d,0x3d,0x2b,0xaa,0xe8,0xf0,0x76,0x32,0x2c,0xaf,0x48,0xff,0x0d,0x34,0x0d,0xf7,0x27,0x6d,0x65,0x27,0x4d,0x15,0x37,0x87,0xa6,0x0c,0xbc,0xf6,0xd6,0xb5,0x35 +,0x24,0x82,0x86,0x0d,0xd1,0xbe,0xb5,0xef,0x24,0x32,0x55,0xa1,0xf2,0x82,0xeb,0x43,0xbf,0xc6,0x0f,0x76,0x2e,0xfc,0x81,0x74,0x9d,0xd9,0x19,0x30,0x6c,0x9d,0x47,0x69 +,0x3b,0x2b,0x48,0x4c,0x80,0x5c,0x02,0x01,0xd5,0x10,0xd5,0x4e,0xca,0x80,0xa2,0x81,0x10,0x29,0x94,0x26,0x14,0x14,0x05,0x84,0x61,0x50,0xa0,0x58,0x30,0x25,0x0b,0x11 +,0x02,0xa1,0x40,0xb0,0x54,0x26,0x14,0x0a,0x90,0x42,0x61,0x51,0x18,0x45,0x2e,0x7e,0xff,0x9d,0xf9,0x5e,0xbc,0x0a,0x9c,0x7a,0xb5,0xd4,0x95,0x5d,0x13,0xeb,0xd3,0x8e +,0x79,0xff,0xaf,0xbf,0x5b,0xf6,0xf9,0xfd,0x74,0x1e,0x7f,0x99,0xfc,0x77,0xc4,0xe8,0xf4,0xd7,0x7b,0x68,0xff,0x0b,0xcf,0x42,0x97,0xe3,0x69,0xac,0x25,0xe9,0x74,0x47 +,0x81,0x97,0x2b,0xf9,0x5d,0xbd,0xea,0x3a,0x4f,0x8d,0xdf,0xb6,0x09,0x2d,0xbe,0xd9,0xaa,0x8f,0x23,0xff,0xe7,0xab,0xfb,0x6a,0xdc,0x1e,0xdf,0x8d,0xf4,0x72,0x9b,0x88 +,0x55,0x41,0x50,0xf8,0xfd,0xe3,0x89,0xfe,0x0f,0xff,0x70,0xf6,0xb1,0x1e,0xf7,0x05,0x8b,0xe6,0xe4,0x07,0x89,0xe1,0xc7,0x85,0x12,0x04,0xd5,0x0c,0xcf,0x13,0x91,0xec +,0x02,0xf9,0x50,0xc7,0x80,0x07,0x7c,0x3d,0x73,0xd0,0x15,0x61,0x63,0xc4,0x00,0x03,0xd6,0x77,0xc9,0x97,0xc3,0xaa,0xf6,0x32,0x00,0x0d,0x01,0x00,0x0a,0x82,0xa9,0x80 +,0xb0,0x00,0xba,0xa0,0x38,0xff,0xf1,0x50,0x80,0x30,0x7f,0xfc,0x21,0x0a,0xcf,0xbe,0xb7,0xdf,0xff,0xfd,0xb1,0x60,0xb8,0x60,0x48,0x15,0x0b,0x05,0x02,0xc3,0x80,0xb0 +,0xd0,0x2c,0x14,0x0a,0x85,0x82,0x85,0x20,0x98,0x44,0x24,0x11,0x31,0x84,0x42,0x61,0x10,0x98,0x84,0x4a,0xf3,0xeb,0x8b,0x46,0xe5,0x4e,0xbc,0x5d,0x4d,0x6e,0x29,0xa5 +,0xa8,0xbc,0x4e,0x33,0xdb,0xd7,0x9a,0xfb,0xff,0xea,0x17,0xf6,0x7e,0x17,0x3a,0x56,0x86,0x1f,0xf3,0xbe,0xed,0x15,0x7f,0x9d,0xbd,0xfd,0x8a,0x72,0x73,0x51,0x2b,0xc6 +,0x80,0xdf,0xef,0x74,0x6e,0x5e,0x7f,0xe4,0xe6,0x1e,0x3b,0xba,0x1f,0x96,0x60,0x96,0x2f,0xa2,0xbd,0x92,0xe8,0xae,0x4b,0x30,0x3a,0x7a,0x59,0x03,0xf8,0x00,0xf7,0x7a +,0xbb,0xd6,0x9d,0xe7,0x27,0x86,0x00,0x53,0xd2,0x61,0xbb,0x28,0x2e,0x0a,0xed,0xea,0x93,0x99,0x4d,0x35,0xfe,0x4e,0x0c,0xb7,0xc1,0x56,0x88,0xc8,0x3a,0xa3,0xab,0x9d +,0xed,0x3d,0xea,0x84,0xb8,0xae,0x9a,0x9f,0x8c,0x5b,0xd7,0xd8,0x94,0x09,0x9c,0xb6,0x63,0x52,0x2a,0x2d,0xa1,0x35,0x0f,0x56,0x23,0xc4,0x1f,0x22,0x2a,0xac,0x17,0x77 +,0xe0,0x06,0x74,0x53,0x51,0xdd,0x77,0x0e,0xe9,0xdf,0x54,0x16,0xd9,0x12,0x85,0x80,0x4e,0x90,0x50,0x4c,0x18,0x0b,0x11,0x42,0xc3,0x40,0xa8,0x58,0x8a,0x14,0x0b,0x85 +,0x02,0xc1,0x50,0x98,0x54,0x46,0x15,0x09,0x89,0x42,0x62,0x10,0x98,0x44,0x26,0x11,0x23,0xf3,0x97,0xeb,0xdb,0x7e,0xcf,0x04,0x95,0x89,0xc5,0x55,0x5a,0x5d,0x69,0xe7 +,0x37,0xd7,0x73,0xe3,0xd7,0x9d,0xf5,0xcf,0xfe,0xbf,0x03,0xdf,0x4c,0xfd,0x0a,0x9d,0x57,0x7a,0x23,0xe5,0x57,0x2e,0x34,0x17,0x3f,0x40,0x34,0xdd,0x7e,0x37,0x97,0x39 +,0x5b,0xf1,0x1d,0x8f,0xf6,0x75,0xe5,0xe0,0x6a,0x3f,0xdb,0xf8,0xf6,0x8d,0x8d,0x9f,0x0b,0x15,0xc9,0x05,0x07,0xeb,0xf4,0xa7,0xe0,0xe7,0xf8,0xdc,0xb4,0xb9,0xde,0xe3 +,0x7d,0x5e,0xec,0x48,0xfe,0xff,0x1f,0x7c,0xc2,0xde,0xbb,0x67,0x1d,0xe4,0xdc,0x0b,0x70,0xeb,0xe0,0x8e,0xfb,0xba,0x77,0xe2,0xfe,0x4f,0x98,0x00,0x79,0x94,0x39,0x5d +,0xbd,0x1f,0x56,0x5c,0x00,0xf3,0x03,0xd7,0x7a,0xe1,0xdd,0x3d,0xd8,0xa4,0x00,0x0f,0x20,0x58,0x91,0xee,0x89,0x8e,0xe8,0x09,0x2e,0x9f,0xae,0x29,0x10,0x0e,0xf0,0x20 +,0x89,0x02,0x89,0x80,0x11,0x2e,0x03,0x80,0xff,0xf1,0x50,0x80,0x2d,0xff,0xfc,0x21,0x0a,0xcf,0xbf,0xad,0xff,0xff,0xfc,0xae,0x70,0xc0,0x58,0x30,0x15,0x0b,0x05,0x04 +,0xc2,0x41,0x30,0x50,0x6c,0x44,0x11,0x05,0x04,0x42,0x40,0x88,0x88,0x26,0x21,0x53,0x99,0x5e,0x77,0x2d,0xce,0xa5,0x37,0xa1,0x22,0x65,0xc5,0xe5,0x5f,0x9c,0xc9,0x92 +,0xf2,0xeb,0xfd,0xf8,0x0f,0x4d,0x27,0xf1,0xee,0x8e,0xf2,0x4f,0x08,0xed,0xfd,0x37,0xf9,0x29,0xe7,0xda,0x3a,0x9f,0x72,0x02,0xfe,0xda,0xa7,0x65,0x1f,0x5d,0x0e,0xf8 +,0x9e,0xf7,0xe1,0xfd,0x12,0x5e,0x01,0x13,0x85,0x4c,0xfd,0xdb,0xe9,0x6b,0x5e,0x5d,0xd6,0x1a,0xab,0xd6,0xe2,0x3e,0x5f,0xf6,0xe2,0x62,0x8f,0x09,0x97,0x78,0x37,0xd6 +,0xea,0xde,0xe0,0x84,0x33,0xd1,0xb0,0xc5,0xf5,0x23,0x4c,0x77,0x49,0x77,0xa4,0x29,0x16,0x76,0x92,0x51,0x5e,0x39,0xcf,0x96,0x94,0x72,0x14,0x87,0xe8,0x8c,0x8b,0xcc +,0x64,0xa9,0x69,0x8c,0xf7,0x50,0x77,0x4e,0xe9,0x25,0x41,0x9a,0x51,0xb0,0x8a,0x94,0xb2,0x26,0x97,0xc6,0x93,0xa4,0x93,0x1c,0x16,0x76,0x0b,0xc5,0x45,0x5f,0xd0,0x15 +,0xa5,0xe9,0x74,0xc0,0x50,0x2a,0x04,0xe9,0x09,0x02,0xc1,0x80,0xa0,0x58,0x48,0x16,0x1a,0x05,0x8e,0x81,0x60,0xa8,0x50,0x66,0x15,0x11,0x89,0x42,0x24,0x30,0x89,0x95 +,0xfa,0x6b,0xc7,0xc7,0x8e,0xaf,0xc2,0x5e,0xbb,0x94,0x25,0x6a,0x93,0x57,0x24,0xd4,0xf7,0x3a,0xfd,0xfb,0xea,0xbd,0xb8,0x1b,0x35,0x7e,0xcb,0xca,0x7f,0x0a,0x5f,0xca +,0xe9,0xb2,0x38,0xff,0x37,0xa2,0x0b,0xd5,0xac,0x6a,0x23,0xed,0xfe,0xcf,0x56,0x9b,0xae,0xdb,0xe6,0x98,0x49,0x02,0x6f,0xcb,0x6f,0xe0,0x34,0x75,0x74,0x58,0x02,0xee +,0xf0,0x2b,0x28,0x5b,0x74,0x1d,0xf4,0x7a,0x1f,0xec,0xfd,0xed,0xe8,0x18,0x8e,0xcc,0x25,0xbd,0x3b,0x6b,0xe4,0x69,0xcf,0xbf,0xc8,0x6b,0xdb,0xe3,0xf7,0xab,0xee,0x7e +,0xc7,0x33,0x7c,0x9a,0x6b,0x8a,0xf7,0x34,0xfe,0x70,0xa0,0x0b,0x93,0x93,0xc1,0xc5,0x5e,0x00,0xe0,0x3b,0xc0,0x77,0x98,0x4e,0xfa,0x40,0x0f,0x10,0x00,0x9a,0x50,0xae +,0x3b,0x5d,0x01,0xdc,0xe2,0xa9,0x0b,0x20,0xb7,0x74,0x41,0xee,0x16,0x00,0x4c,0x14,0x00,0xa0,0x02,0x53,0x2a,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0x1f,0xfc,0x21,0x0a +,0xcf,0xbe,0xce,0xef,0xff,0x7c,0xae,0x60,0xc0,0x58,0x48,0x13,0x0b,0x05,0x02,0xc2,0x51,0x31,0x10,0x2c,0x14,0x2a,0x85,0x02,0x43,0x40,0x90,0xc4,0x26,0x25,0x08,0x84 +,0xc4,0x21,0x30,0x88,0x9c,0xdc,0xe3,0x9d,0x67,0x5e,0xfd,0x54,0xbe,0xf5,0x5c,0x72,0xd3,0x35,0x91,0x48,0x6a,0x47,0x3f,0x8a,0xef,0x8f,0xd6,0xc6,0x1f,0xc5,0x9f,0x4b +,0xef,0xb7,0xfb,0x9b,0xf5,0x7f,0xcc,0xb7,0x2f,0x9c,0xee,0xfd,0x7c,0x51,0xf1,0xae,0xe9,0xe6,0xfc,0x81,0x74,0x40,0x3e,0x1b,0x71,0x1d,0x8a,0xec,0x9a,0xfc,0x8e,0x56 +,0x70,0xbc,0xc5,0xbe,0xcf,0xa9,0x62,0x02,0xfd,0x7a,0x88,0x2f,0x24,0x38,0x1e,0xc2,0x7e,0xab,0x0f,0xaf,0x5e,0x04,0x84,0x46,0xb0,0xf7,0x67,0x5f,0xc4,0x3d,0x31,0x5b +,0xbe,0xd5,0x4d,0xce,0x46,0x67,0x1b,0x0a,0x97,0x6c,0x92,0x16,0x2a,0x74,0x09,0xee,0xc9,0x51,0xce,0xf2,0xb5,0x8a,0xcf,0x5d,0xca,0x40,0xa5,0xfc,0x14,0xb9,0x30,0xea +,0x38,0x37,0x61,0xfb,0x99,0xa3,0x81,0x6b,0xc2,0x64,0xbc,0x4c,0x68,0xac,0xa1,0xdf,0x44,0x00,0x1e,0x32,0xad,0x92,0xde,0x20,0x7a,0xc0,0x77,0xc3,0xbb,0x44,0xc4,0xe5 +,0xeb,0x80,0xa8,0x09,0x00,0xa7,0x50,0xb0,0xe0,0x4c,0x24,0x0b,0x0d,0x44,0xe1,0x61,0xc0,0x50,0x4c,0x17,0x0b,0x05,0x46,0x22,0x30,0x88,0x8c,0x82,0x76,0xd9,0xbf,0xe7 +,0xed,0xc5,0xf6,0x92,0x63,0x2e,0xa0,0xd2,0xeb,0xf1,0x3d,0x79,0x9e,0xf1,0xbf,0x8e,0x09,0xbf,0xe4,0x3e,0x47,0xa7,0x6a,0x75,0x5d,0x93,0xde,0xef,0xd9,0x70,0xa3,0x7b +,0x7f,0xdf,0xa4,0x56,0x60,0xf5,0xce,0x45,0xf4,0x3d,0xfd,0x8f,0x9c,0xeb,0xd0,0xc0,0x05,0xba,0xb2,0xe1,0xe9,0xb8,0xdb,0xd5,0x2d,0x61,0x84,0x82,0xe0,0x16,0x83,0xc9 +,0xaf,0xe1,0x18,0xfc,0xe7,0x11,0x67,0x6b,0xe3,0xd8,0xcb,0xdc,0xe5,0xa6,0x61,0xd5,0xcd,0x34,0x14,0x52,0x00,0x37,0x70,0xf1,0x99,0xe4,0xe8,0x1c,0x63,0x8a,0x39,0x25 +,0x16,0x39,0xef,0x8c,0xf2,0x00,0x14,0xf8,0x60,0xc5,0x60,0xef,0x01,0xdd,0x26,0x9d,0xce,0xd0,0x03,0xb9,0xeb,0x97,0x2a,0x77,0xbd,0xc0,0xf5,0x80,0xee,0x7b,0xae,0xe7 +,0xf8,0xc0,0x07,0x00,0x19,0xa2,0x00,0x0a,0x85,0xc1,0x0d,0x34,0x0a,0x48,0x0e,0xff,0xf1,0x50,0x80,0x31,0x7f,0xfc,0x21,0x0a,0xcf,0xe6,0xdb,0xff,0xff,0xfc,0xae,0x40 +,0xc0,0xd8,0x28,0x36,0x12,0x05,0x42,0xc2,0x40,0xb8,0x58,0x28,0x16,0x0a,0x05,0x84,0x81,0x60,0xa0,0x54,0x24,0x43,0x10,0x88,0xc2,0x22,0x30,0x88,0x4c,0x22,0x37,0x35 +,0xa4,0xb9,0x3b,0xb9,0x57,0x97,0x92,0xe9,0x12,0xa6,0x45,0x75,0x5c,0xcd,0x64,0xe3,0x3d,0xbc,0x7f,0xcf,0xb0,0xf9,0x87,0x8e,0xba,0xc7,0x49,0x9d,0x37,0xf1,0xc3,0xfe +,0xbe,0x35,0xaa,0xeb,0xdf,0xea,0x2f,0x37,0xff,0x62,0x3f,0xa1,0x8f,0x6c,0x22,0xc6,0x9d,0x5b,0xa8,0xe9,0x1d,0x94,0xff,0x01,0x5d,0x1f,0xfb,0xb6,0x5f,0x55,0x0e,0x65 +,0x37,0xc6,0x22,0x24,0x13,0x3e,0xe4,0xb0,0x6e,0x0f,0xd4,0x27,0x81,0x48,0xbb,0x01,0x6e,0xf8,0x59,0x89,0x28,0x3f,0xb5,0x0c,0xa1,0x32,0x68,0xe8,0x56,0x7d,0xa3,0x09 +,0x1e,0x6e,0xdf,0x59,0xe9,0x5e,0x0f,0x60,0x79,0x4e,0xce,0xf4,0xd7,0xbd,0x64,0xc4,0xf2,0x17,0x56,0x47,0xc1,0x6b,0x1c,0xdd,0x17,0xb0,0xe1,0x25,0x3b,0xdf,0x85,0xdb +,0x1c,0x67,0xb7,0x32,0xde,0x05,0x8d,0x3a,0x4d,0xee,0x17,0x8f,0x0c,0xd4,0x77,0xfd,0x96,0x33,0x4e,0x9e,0x62,0xe0,0xbc,0xa2,0x92,0xb1,0x81,0xeb,0x08,0xae,0x57,0x30 +,0x4c,0x08,0x4c,0x0a,0x85,0x09,0x86,0x06,0xc2,0x80,0xb0,0x54,0x2c,0x15,0x0a,0x09,0x8a,0x82,0x60,0xa0,0x9c,0x42,0x43,0x0a,0x84,0xc2,0x22,0x30,0x90,0x4c,0x22,0x13 +,0x10,0x89,0x5c,0xdd,0x71,0xba,0xfd,0x7d,0x55,0xe3,0x25,0x55,0xa6,0x47,0x57,0xd5,0x7b,0x6f,0xd5,0xef,0x8b,0xf5,0x9a,0xf8,0xdc,0x96,0x1f,0x3f,0xe0,0x8f,0x97,0x9d +,0x48,0xae,0xfd,0xbc,0xdf,0xf4,0x96,0x7f,0x8d,0xff,0x30,0x4d,0xad,0x5c,0x5f,0x1a,0xbf,0xf7,0xf4,0x6f,0xb5,0xea,0x92,0xf3,0x98,0x34,0x54,0x96,0x79,0x53,0x1b,0x53 +,0x9d,0x42,0x5c,0xaa,0x74,0xfc,0x70,0xdf,0xd5,0x20,0xfb,0xa7,0x6f,0xd2,0x71,0x7b,0x4e,0xb4,0x96,0x6e,0x17,0xdd,0xed,0x7b,0x7e,0xd7,0xf4,0xbe,0x87,0x99,0x07,0x93 +,0x98,0x90,0x89,0x1e,0x58,0x48,0x4b,0x75,0x64,0x9b,0x4e,0xfe,0xa1,0x1b,0x27,0xac,0xc6,0x15,0x1e,0xb3,0xbe,0x7a,0xfe,0x7c,0x00,0x00,0xb7,0x70,0x3d,0xa8,0x38,0x22 +,0xb8,0x2d,0x5f,0x5e,0x64,0xef,0x38,0x02,0x24,0x27,0x78,0x83,0xbf,0x60,0x58,0xbc,0x00,0x0e,0xe0,0x77,0x82,0x61,0x0a,0xaf,0x40,0x38,0xff,0xf1,0x50,0x80,0x34,0x1f +,0xfc,0x21,0x0a,0xcf,0xf5,0x5f,0xbf,0x7f,0xf7,0xb0,0x61,0xc0,0x68,0x28,0x16,0x12,0x85,0x06,0xa1,0x40,0xa8,0x90,0xac,0x24,0x0b,0x05,0x02,0x41,0x50,0x98,0x48,0x26 +,0x12,0x09,0x84,0x84,0x21,0x30,0x88,0x4c,0x22,0x46,0x29,0xe7,0x7f,0xaf,0xed,0xc5,0xb6,0xb6,0x35,0x85,0x21,0x25,0x71,0xdf,0xb7,0xa4,0xeb,0x7e,0x78,0xf9,0xfa,0xe0 +,0x2f,0x6e,0xf9,0x6a,0xff,0x38,0xbe,0x0f,0x08,0x9f,0x8f,0xe9,0x4b,0xf4,0x7d,0x8d,0x06,0xdf,0x39,0x97,0x6a,0x74,0x7c,0x1a,0xf9,0x17,0xe6,0xbd,0xbe,0x30,0xf9,0xa6 +,0x5c,0xc3,0x8d,0x74,0xff,0x87,0x16,0xc4,0xdd,0x26,0xb7,0xe7,0x6c,0x0e,0x6f,0x5d,0x42,0x62,0x42,0xfe,0xd2,0x01,0x3a,0xc7,0x58,0x85,0xdf,0x93,0x4d,0x3a,0x41,0x82 +,0x1e,0xf3,0x1f,0x78,0x26,0x5d,0xa5,0x44,0x8e,0x6d,0x77,0xd3,0xc5,0x4a,0x3a,0x37,0x98,0x65,0x5f,0xf6,0xdb,0x45,0x21,0xa3,0x6f,0xd1,0xba,0x18,0xa8,0x87,0x95,0xa1 +,0xed,0x3f,0x63,0xb8,0x88,0x96,0x8e,0xe5,0x86,0xcd,0x0e,0xe5,0x95,0xb8,0xe0,0x82,0x40,0xd0,0xc8,0xc1,0xb8,0xa8,0xea,0x3c,0xa7,0xcd,0x3e,0x85,0xcb,0x3d,0x6f,0x65 +,0xdd,0x9a,0x42,0x15,0x16,0xf5,0x80,0x13,0x5a,0xd9,0x00,0x17,0x0b,0x01,0x50,0xc1,0x40,0xc0,0x58,0x4e,0x16,0x1c,0x05,0x83,0x01,0x61,0x28,0x50,0x2c,0x15,0x0b,0x05 +,0xc2,0xc1,0x40,0xa8,0x50,0x2a,0x23,0x0b,0x84,0x46,0xa1,0x32,0x88,0x54,0x42,0x37,0xb7,0xd9,0x5f,0x7f,0xb4,0xfd,0xff,0x8d,0x66,0xb7,0xaa,0xdf,0x18,0xa9,0x75,0x2e +,0xf9,0xff,0x19,0x5b,0xee,0xb5,0x4f,0x2e,0x7a,0xad,0x03,0xd1,0xf4,0xe5,0x69,0x7e,0xb6,0xcf,0xe1,0xe0,0x26,0xda,0x5d,0x7a,0x68,0xd0,0x07,0x6e,0xc7,0x47,0xcf,0x2f +,0x44,0x19,0x73,0x48,0xd6,0x3b,0xfb,0xd7,0xe3,0xfe,0xcf,0xfe,0x78,0x7f,0x12,0xd1,0xe2,0x7b,0xb9,0x73,0x92,0xf0,0x71,0xfb,0x6e,0x7c,0xbd,0xed,0xf4,0x78,0x60,0x01 +,0x8f,0xbb,0xfd,0x5b,0xca,0xef,0x7d,0x30,0xf3,0xf1,0x0f,0xdb,0x7f,0x0b,0xff,0xfe,0xe5,0xf7,0xf3,0x8e,0x65,0xd7,0x9f,0x34,0x28,0xf6,0xfd,0xe3,0x87,0xb7,0x7f,0x8d +,0xff,0xbf,0xba,0xdd,0xb4,0xf2,0xf2,0xb6,0x72,0xb6,0xb6,0xb7,0x2d,0x31,0xd2,0x3c,0x04,0x49,0xc8,0x5b,0x68,0x78,0x1e,0x20,0x03,0x4d,0x77,0xb9,0xeb,0x15,0x7e,0xff +,0x82,0x98,0x3d,0xce,0xfb,0xd7,0x0e,0xe9,0xeb,0x9e,0xb0,0x20,0x0d,0xa0,0x3c,0x40,0x0f,0x30,0x02,0x40,0x55,0x5a,0x05,0x4b,0x48,0x0e,0xff,0xf1,0x50,0x80,0x32,0x1f +,0xfc,0x21,0x0a,0xcf,0xfb,0xfb,0xff,0x7f,0xff,0xb0,0x40,0xc0,0x58,0x30,0x16,0x3a,0x05,0x44,0xc1,0x40,0xb0,0x50,0x4c,0x37,0x0b,0x05,0x44,0x81,0x30,0x90,0xcc,0x22 +,0x22,0x08,0xa1,0xce,0xb7,0xe7,0xdb,0xed,0xc7,0x3a,0xbd,0xf1,0x53,0x75,0x22,0x2a,0x55,0xaf,0x72,0xf8,0xce,0xe5,0xc9,0x6a,0xfa,0xe8,0x7d,0x0b,0x43,0x53,0xfa,0xd6 +,0x8f,0x53,0xff,0x74,0xa3,0x9f,0x0b,0xcb,0xf5,0xed,0x3d,0x46,0xd0,0x3c,0x36,0xbe,0x01,0xcf,0xc2,0xfd,0xfc,0x6d,0x02,0xfc,0xff,0x91,0x96,0x9d,0xba,0x8b,0x58,0xde +,0xe4,0x33,0x72,0x6e,0x74,0x5c,0xee,0x87,0x26,0x31,0xd8,0xa6,0x2c,0x85,0xa9,0x4e,0x23,0xb7,0xd6,0xbd,0x80,0xca,0x2b,0x10,0xa0,0x5b,0x5f,0x74,0x52,0x69,0xee,0x9a +,0x77,0x11,0x5f,0x3a,0xa9,0x2b,0x61,0x6b,0x3c,0xe1,0x92,0xdb,0xaf,0x37,0xb3,0x7b,0x55,0xe0,0xd3,0x1e,0x0b,0x71,0x8f,0xe6,0x58,0xcc,0xb3,0xf4,0x90,0x90,0x13,0xc3 +,0x55,0x03,0x90,0x57,0xb4,0x8c,0x35,0xe5,0x2b,0xe1,0x8d,0x65,0xdd,0x70,0x3b,0x03,0x65,0x32,0xc2,0xea,0xba,0xa0,0xb4,0x6c,0x19,0x81,0xce,0xae,0xe4,0x25,0x48,0xd5 +,0x65,0x6e,0x00,0x59,0x40,0x2a,0x98,0x90,0x14,0x0b,0x1d,0x02,0xe1,0x60,0xa0,0x58,0x6e,0x14,0x0a,0x85,0x82,0xa2,0x20,0xa8,0x44,0x2a,0x13,0x0a,0x84,0xd0,0x23,0x7e +,0xbf,0xa5,0x4f,0x6f,0x7f,0x3e,0xbd,0xb7,0x29,0x79,0x52,0x54,0xc8,0xd3,0xdb,0xe7,0xf1,0xce,0xf8,0xe6,0xea,0xea,0x5d,0xf1,0xcf,0xd0,0x5e,0xed,0x5b,0x3a,0x8b,0xc7 +,0x6e,0xac,0xaf,0xcd,0xa7,0xed,0xe1,0xdf,0xdd,0xcf,0xe8,0xbb,0xaf,0xa4,0x46,0x97,0xf8,0xb7,0x74,0x17,0x3b,0xfc,0x17,0xac,0x96,0x75,0x07,0x2f,0xf9,0x3f,0xeb,0xae +,0xdb,0x3b,0xa8,0x00,0x0c,0x3c,0x52,0x9e,0x65,0xb0,0x82,0xdf,0xbf,0x5f,0x49,0xfd,0x57,0xaa,0x7f,0xf2,0xf3,0xeb,0xa7,0xa4,0xe4,0x17,0x97,0x2b,0xe8,0xa0,0xea,0x3c +,0xfd,0xde,0x29,0x3b,0xd9,0xf2,0x07,0x0f,0x0f,0x13,0x82,0x4e,0x93,0x98,0x81,0xf6,0xef,0xe0,0xf9,0x76,0xf2,0xe1,0x11,0x29,0x55,0xc0,0x7a,0x6c,0x13,0x36,0x7d,0x50 +,0xf7,0xaf,0xc1,0x0e,0x07,0x90,0x03,0xfa,0xa0,0xbf,0x72,0x7d,0xe2,0x67,0x79,0xeb,0x2c,0x77,0x2a,0x99,0x33,0xf2,0x1e,0xe0,0xff,0xfd,0x8f,0x5f,0xb8,0x0a,0x54,0x1e +,0xb8,0xef,0x01,0x62,0xa0,0x54,0xba,0x13,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0xbf,0xfc,0x21,0x0a,0xcf,0xef,0xff,0x7e,0x7f,0xff,0xab,0x61,0xc0,0x8c,0x28,0x16,0x11 +,0x85,0x0a,0xc2,0x70,0xb0,0x50,0x6a,0x16,0x0a,0x85,0x02,0x63,0x11,0x98,0x85,0x2f,0x7b,0x57,0x15,0xd7,0x8e,0x12,0x72,0xb5,0x25,0xe5,0xe2,0x6a,0xeb,0x2e,0xb5,0x3c +,0x35,0x1a,0xaf,0xd7,0x81,0xf7,0xf6,0x7f,0xfd,0x1e,0xfe,0x72,0x79,0x5e,0x91,0xbf,0x39,0xf2,0x5a,0xf9,0xfa,0xcf,0xf4,0x69,0xf5,0x00,0x3f,0x07,0xd3,0x72,0xfd,0x4e +,0x1d,0xca,0x81,0x3f,0x4e,0x90,0x3b,0x88,0x77,0xf8,0x31,0x29,0x6e,0x00,0xd7,0x51,0x47,0xe0,0x39,0x75,0x54,0x7d,0x64,0xf2,0xff,0x40,0x6d,0xfa,0xa6,0xec,0xe6,0x5c +,0x5c,0x60,0x51,0x98,0x38,0xa3,0x75,0x79,0xf5,0x16,0x92,0xe5,0x5a,0x32,0xcc,0xbe,0x51,0x0a,0x77,0x83,0xeb,0x1e,0xbb,0xf0,0x14,0x30,0xa5,0x4b,0x65,0x81,0x59,0xa9 +,0x5b,0xd6,0x94,0x56,0xb6,0xb9,0x29,0xf7,0xb2,0xa0,0x5c,0x09,0x3b,0xae,0xa8,0x64,0xa7,0x42,0x7f,0x8a,0xd6,0xba,0xd5,0x26,0xa5,0xe7,0x10,0xbd,0xa8,0x2d,0xe7,0xd0 +,0xde,0x20,0x14,0x46,0xe0,0x04,0x51,0x02,0x99,0x87,0x01,0x60,0xc0,0x58,0x66,0x15,0x0a,0x05,0x8f,0x01,0x61,0x38,0x54,0xe6,0x35,0x09,0x84,0x42,0x62,0x10,0x98,0x84 +,0x4d,0xf9,0xf7,0x9f,0x5f,0xc7,0xb5,0x6a,0xb3,0x8e,0x61,0x4a,0x8d,0x66,0x9a,0xe7,0x8f,0x3c,0xca,0xe3,0xc7,0x3e,0xd3,0xcf,0x3a,0xd4,0x1a,0x52,0x8d,0x15,0x7c,0x73 +,0x17,0xe7,0x12,0xbc,0x7d,0xbf,0x34,0xeb,0xed,0x4f,0xf0,0x67,0xf2,0xe2,0xe8,0x1f,0xcf,0x02,0x4d,0xe6,0xd0,0x1b,0x4e,0xeb,0x07,0x7f,0xde,0xa8,0x9b,0x9a,0x56,0x91 +,0xf5,0xce,0x84,0xa6,0x44,0x93,0x1d,0x44,0xca,0x19,0xc8,0xad,0x54,0x5a,0x7d,0x72,0x15,0xf4,0x7d,0x8b,0x1b,0x42,0xa8,0x8e,0xc7,0x6b,0x9d,0xbd,0xd4,0x70,0xe0,0xe7 +,0xf0,0x71,0xe1,0xe6,0x02,0xb8,0x0e,0x7c,0xad,0xc4,0x79,0x90,0x5c,0xc6,0x40,0xe1,0xe3,0xc8,0xe3,0xf3,0xe4,0xee,0xe3,0xc5,0xc0,0x7c,0xc3,0x88,0x1e,0x04,0x00,0x5a +,0x97,0xef,0x07,0xbb,0xde,0x17,0x7e,0x4b,0xba,0x00,0x03,0xcc,0x0d,0x8b,0x4e,0x4f,0x77,0xc4,0x5e,0x32,0x4d,0xeb,0x83,0xdc,0x7a,0x27,0x78,0xab,0x60,0x02,0xcf,0x64 +,0x3b,0x82,0x00,0x0b,0xc5,0x10,0x38,0xff,0xf1,0x50,0x80,0x2f,0xbf,0xfc,0x21,0x0a,0xcf,0xfe,0xfb,0xff,0xcf,0xff,0xac,0x60,0xc0,0x58,0x30,0x24,0x13,0x09,0x42,0x83 +,0x50,0xa0,0x98,0x2a,0x16,0x0a,0x85,0x04,0xc1,0x40,0x90,0x50,0x26,0x15,0x09,0x04,0xc2,0xa1,0x31,0x0a,0x9f,0x33,0xeb,0xe7,0xab,0x9c,0xcb,0x69,0xca,0xb5,0x37,0xc7 +,0x37,0xbb,0xb8,0x75,0xac,0x73,0x94,0xe1,0x73,0xdb,0xc8,0xe7,0xfe,0xe7,0xc5,0xcf,0xf5,0x47,0xb6,0xf3,0x87,0xcb,0x3e,0xec,0xfb,0xf4,0x27,0x83,0x79,0x15,0xb7,0x79 +,0xdd,0xbb,0x1e,0x94,0x4e,0xe0,0x87,0xee,0xe7,0x2f,0xa3,0x89,0xbe,0x7a,0xe6,0x1e,0xa0,0x78,0x46,0xe6,0xa3,0xed,0xa6,0x43,0xcb,0xac,0x6f,0x7e,0xa9,0x6e,0xa0,0x63 +,0x21,0x5f,0xed,0xd4,0xb9,0x6f,0x0e,0xcf,0xb5,0xfe,0x6f,0x61,0x3f,0x9a,0x22,0xcb,0x9e,0xa5,0x1b,0xca,0x51,0x5a,0xdd,0xf2,0x46,0xd3,0x55,0x14,0x71,0x82,0x4c,0x8f +,0x5b,0xdf,0x48,0x07,0x80,0x01,0xde,0x02,0xa0,0xee,0xd8,0x25,0x1e,0x62,0x30,0x6c,0x65,0x82,0xab,0x61,0x84,0xa7,0x72,0x2a,0x49,0xb0,0xb8,0x9c,0x0a,0x0b,0x96,0x97 +,0x12,0xb1,0x36,0xd8,0x50,0x04,0xc0,0x52,0xa8,0x58,0x30,0x26,0x2a,0x05,0x84,0x81,0x62,0xa0,0x9c,0x2c,0x15,0x23,0x84,0xc4,0xe1,0x51,0x08,0x4c,0x62,0x13,0x10,0x91 +,0xcb,0x75,0xd7,0x3d,0x77,0xfc,0xfe,0x99,0xc5,0x4c,0xab,0xa8,0xae,0xb2,0xe7,0xb3,0x73,0xc7,0xc5,0x57,0x37,0xdf,0x9e,0x39,0xfc,0x6e,0xc7,0xa9,0x67,0x5e,0x1d,0x16 +,0x68,0x7b,0x74,0xf1,0xde,0x9e,0x6d,0x5a,0xfa,0xaf,0xfc,0xc1,0xd1,0xec,0xd3,0x94,0x49,0xdb,0xc7,0x79,0x9d,0x45,0xa6,0x93,0xb3,0x9e,0xfd,0x8b,0x5c,0xf2,0x45,0x3b +,0x3f,0x5f,0x6b,0x9c,0xea,0xf7,0x3f,0xef,0xf8,0x3f,0xfb,0x3c,0xbf,0xfe,0x5b,0xb4,0x5d,0x6f,0x99,0x8d,0x13,0x97,0x21,0xb5,0x1e,0xd9,0x79,0x59,0xbc,0x2b,0x50,0x8c +,0xfa,0x11,0xcd,0x4e,0x7c,0xa4,0x07,0x8f,0x01,0xc0,0xf3,0x80,0x09,0x25,0xef,0x5e,0xbf,0xf2,0x40,0x01,0x21,0x7e,0x40,0xb9,0xe1,0xca,0x09,0x73,0x39,0x00,0x01,0xe6 +,0x69,0xda,0x0e,0xf8,0x7e,0x47,0xae,0x8a,0x5d,0xda,0xd1,0x77,0x7f,0xdc,0x29,0x44,0xab,0x07,0xb1,0x1a,0x48,0xef,0x54,0x77,0xc7,0xb8,0x8a,0xc5,0x90,0x15,0x28,0x09 +,0x8a,0x1c,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x30,0x3f,0xfc,0x21,0x0a,0xcf,0xfd,0xdf,0xff,0xff,0xfd,0xb0,0x60,0xc1,0x10,0x2c,0x34,0x13,0x05,0x02,0xc1,0x43,0xa8,0x58 +,0x4a,0x12,0x12,0x05,0x42,0x61,0x13,0x18,0x44,0xca,0xcd,0x73,0xf1,0xdf,0x9f,0x1e,0xd9,0x57,0x55,0x9d,0x72,0x5a,0xab,0x54,0xd7,0x53,0x9c,0xa6,0x38,0x4a,0xfc,0x6a +,0xc1,0xfc,0xe0,0xd1,0x97,0xa6,0xa8,0xec,0xfc,0xe7,0xfc,0x4e,0x33,0x27,0x2d,0x25,0xcd,0x78,0xf8,0x9d,0x76,0x92,0xf4,0x46,0xf7,0xd7,0x50,0x6d,0x7e,0x06,0xef,0xf7 +,0x5f,0x15,0x36,0x91,0x12,0x63,0x91,0xfa,0x06,0xfd,0x46,0xba,0x14,0xd4,0xbe,0xd7,0x7c,0xbc,0x26,0xe1,0xaf,0x40,0x9b,0x0c,0x12,0x3c,0xc6,0xc2,0x00,0x96,0xe8,0x88 +,0x95,0x5e,0xbd,0x52,0x32,0xff,0x5a,0x51,0xe3,0x28,0xe5,0x5f,0xac,0x76,0xf7,0xbe,0xa5,0xcb,0x8c,0xcf,0x41,0x41,0x21,0x61,0x43,0xd7,0x2d,0x48,0x51,0x7c,0xd8,0x58 +,0x98,0xec,0x33,0x69,0xc0,0xcf,0x0a,0x9c,0xa1,0x8b,0xa3,0x3e,0xc4,0x16,0x56,0xd9,0x75,0x1a,0xa9,0x4a,0x87,0x99,0x94,0xae,0x55,0xef,0xa5,0xd7,0xd7,0x15,0x55,0x84 +,0xda,0x67,0xb1,0x0a,0x80,0x9d,0x40,0xb0,0x09,0xe2,0x0b,0x0e,0x02,0x81,0x80,0xa0,0x58,0x88,0x36,0x1a,0x06,0x02,0xc1,0x50,0xa0,0x54,0x62,0x15,0x19,0x85,0x46,0x23 +,0x50,0x88,0x54,0x22,0x37,0xe5,0x95,0xe7,0xc7,0x9d,0xd7,0x9f,0x1d,0x6e,0xaa,0xd5,0x5a,0x99,0x35,0x3d,0xbd,0x71,0xdc,0x57,0x92,0xd7,0x47,0x91,0xe3,0xa6,0xfe,0xde +,0xff,0x25,0x24,0xe8,0x7f,0xde,0xbd,0x2f,0xcf,0x74,0x28,0xf4,0xf8,0x04,0xb7,0x6b,0x73,0xea,0xff,0x81,0xfe,0xef,0x93,0xed,0x7a,0x07,0xf1,0x96,0xd3,0xd2,0xbf,0xd5 +,0xe9,0x71,0x4b,0x94,0x6c,0x0f,0x84,0xfc,0x1f,0xfc,0xe2,0x2b,0xbf,0x0c,0x12,0xad,0xee,0xe7,0x45,0xe9,0xcf,0xfa,0x9c,0x4e,0xc9,0xbf,0xd5,0xbd,0x78,0x35,0xf7,0x38 +,0xf1,0x3a,0xb9,0xc7,0x9f,0x08,0x17,0xc0,0x78,0x3e,0xf0,0x0e,0x72,0x62,0x58,0x00,0xf2,0xe5,0xc3,0x82,0x4f,0x30,0xf1,0x00,0x0f,0xbc,0x79,0xbc,0xf9,0x19,0x25,0xdd +,0xef,0xaa,0x66,0x9c,0x50,0x21,0xc8,0x5b,0xba,0x98,0x6c,0x44,0x00,0x03,0xc0,0x14,0x81,0x52,0x68,0x5c,0x00,0xa5,0x8a,0x0f,0x30,0x0a,0xd8,0x00,0xf3,0x00,0x0b,0x10 +,0x02,0xe4,0x14,0xd8,0x07,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x0a,0xcf,0xe7,0x77,0xfd,0xdf,0xfc,0xaa,0x81,0x30,0x60,0x48,0x36,0x12,0x05,0x82,0x82,0x60,0xa0 +,0xd8,0x28,0x45,0x18,0x84,0xc6,0xa1,0x31,0x28,0x44,0x46,0x11,0x33,0xed,0xaa,0x7d,0x78,0xeb,0xd6,0xba,0xef,0x5c,0xbd,0xb9,0x55,0x35,0x8b,0xbd,0xf9,0xba,0x98,0xd7 +,0xaa,0xf8,0xe6,0xd3,0xfd,0xbf,0x50,0x9f,0x65,0x9b,0x99,0xe4,0xbd,0x0f,0xd7,0x3a,0xfe,0xbf,0xd1,0x1b,0xee,0xa1,0xe0,0xff,0x8a,0x01,0xfc,0xb4,0x07,0x0f,0xc8,0xb5 +,0x19,0xa0,0x57,0xda,0x4b,0xc2,0xe3,0xd4,0x04,0x04,0x69,0x06,0xe2,0x0c,0x95,0x73,0xa3,0x9a,0xbd,0x1e,0xc1,0xbe,0xf3,0x06,0x79,0xa5,0xdf,0x81,0x01,0x55,0x2f,0xe7 +,0x53,0x65,0x5f,0x1e,0x19,0xcc,0x1b,0xfe,0xd6,0x80,0xfa,0x75,0x62,0x1f,0x69,0x55,0xf8,0x3d,0xc7,0x78,0xbe,0xaf,0xa1,0xee,0x81,0xee,0x3d,0xc0,0xa0,0x00,0x3c,0xa3 +,0xde,0x80,0x8b,0xbc,0x3d,0xd0,0x00,0x3c,0xc2,0xea,0x5a,0x93,0xbc,0x0b,0xce,0xec,0x3f,0x14,0x1d,0xe0,0x96,0x48,0x8a,0x9d,0x81,0x42,0x3a,0xac,0x32,0xc0,0x09,0x80 +,0xa0,0x0a,0x76,0x24,0x05,0x83,0x01,0x61,0xa0,0x58,0x2a,0x16,0x2a,0x05,0xc4,0x81,0x70,0xaa,0x0c,0x22,0x25,0x09,0x85,0x42,0x64,0x11,0x37,0x9d,0x73,0xc7,0x8d,0x5c +,0x95,0x2b,0x32,0x4a,0xba,0x6a,0xbc,0xf7,0xed,0xcf,0x1e,0xbe,0x39,0xf3,0xaf,0x77,0x9e,0x6e,0xaf,0x5c,0x01,0xd9,0x2e,0xeb,0xbd,0xde,0xdb,0x60,0xd0,0xfa,0x7b,0xa3 +,0x78,0xe3,0xdd,0xe9,0x76,0xd1,0xc8,0x37,0x34,0x64,0xee,0x78,0x72,0xe6,0xb2,0xef,0xbb,0xf1,0x72,0xd2,0x7c,0x39,0x6a,0xec,0xa2,0xab,0x4f,0x56,0xde,0x62,0xdf,0xd9 +,0xe3,0x5f,0x7a,0x57,0x44,0x3c,0x8b,0x78,0x1d,0x6d,0x11,0xf0,0xfd,0x2e,0x05,0xa1,0x3e,0x16,0xc8,0x57,0x9f,0x18,0xe1,0xc5,0xc9,0x73,0x8b,0x91,0xdc,0x49,0xc5,0xcf +,0xef,0xe7,0xc0,0x48,0x00,0xf2,0x00,0x3c,0xb9,0x71,0xae,0x0f,0x10,0x01,0xf0,0x87,0x01,0x50,0x1c,0xba,0x1e,0xb0,0x00,0x1d,0xc7,0x74,0x77,0x00,0xa4,0x80,0x79,0xce +,0x4e,0x1d,0xe0,0x03,0xf2,0x5d,0xf0,0x1e,0x20,0x00,0x7a,0xdd,0xc0,0x3b,0xa0,0x1f,0x00,0x1d,0xee,0xe9,0xff,0xb0,0x0a,0x02,0x00,0x70,0xff,0xf1,0x50,0x80,0x2d,0xff +,0xfc,0x21,0x0a,0xcf,0xe8,0xef,0xff,0xff,0xfc,0xac,0x81,0x30,0x60,0x4a,0x14,0x23,0x05,0x04,0xc2,0x40,0xb0,0x54,0x48,0x55,0x09,0x05,0x02,0x64,0x12,0x18,0x44,0xef +,0x5c,0x55,0x70,0x2e,0xb8,0xca,0xdb,0x55,0x2b,0x5c,0xd4,0xe3,0x2f,0x5c,0x29,0xcd,0xd5,0x93,0x2f,0xfe,0xff,0x43,0x0f,0xfc,0xdd,0xb7,0xd9,0x22,0x5d,0x5d,0xc0,0x9e +,0xbf,0xdf,0x7e,0x4b,0xf1,0xda,0x51,0x38,0x22,0xf8,0x81,0x7c,0xfa,0x81,0x36,0xc3,0x9e,0xc8,0xd7,0xf7,0x9e,0xec,0x79,0x0c,0x76,0x3e,0x2d,0xa3,0xdf,0x7c,0xa0,0xbd +,0x79,0xac,0xfc,0x1a,0xfe,0x4a,0xf7,0x0f,0x74,0xff,0xc2,0xbf,0xf3,0xe9,0x13,0x71,0x2e,0x29,0x98,0x77,0x9d,0xef,0xb8,0xdc,0xc4,0x91,0xa7,0xa9,0x1e,0x5b,0x63,0xda +,0xc9,0x06,0x29,0xe6,0xd0,0x78,0x66,0x93,0xfc,0x41,0x77,0xb7,0x80,0x20,0x1a,0xc8,0xfb,0xeb,0xbb,0x05,0x44,0xcd,0x3e,0x30,0x73,0xf7,0x2a,0xb5,0x56,0x88,0x0f,0x73 +,0x30,0xc1,0x1a,0x11,0xb4,0x85,0x94,0x73,0x04,0xe9,0x60,0x40,0xaa,0x00,0x16,0x36,0x81,0x50,0x81,0x62,0x20,0x60,0x2c,0x18,0x0b,0x05,0x06,0xc1,0x40,0xb0,0x50,0x2c +,0x15,0x0b,0x09,0x04,0xe1,0x51,0x38,0x4c,0x2a,0x13,0x12,0x84,0xc6,0x22,0x31,0x09,0x15,0xbe,0x37,0xed,0xef,0xe7,0xd5,0xf1,0xbd,0x5f,0x8d,0x64,0x52,0x4e,0x2b,0x5d +,0x6e,0xd3,0x23,0x7e,0xde,0xb8,0xbd,0xfb,0x67,0x43,0xea,0xfb,0xf7,0xe5,0xaf,0xc7,0x9f,0xea,0xaf,0x8c,0xa5,0xac,0xec,0xa7,0x46,0x87,0x79,0xff,0x9b,0x47,0xf5,0x7f +,0x5d,0xfb,0xc0,0xc2,0xaa,0x8d,0xdf,0xd0,0x35,0xd5,0xf7,0x6d,0xe3,0xff,0x67,0xfe,0x57,0xfc,0x96,0xfb,0xd1,0xf1,0xef,0xea,0xe0,0x33,0xd2,0x38,0x79,0x44,0xaf,0x9b +,0x8e,0x1f,0xee,0x2d,0xd6,0xfb,0xfe,0x7f,0xec,0xff,0x35,0x9a,0x9e,0x51,0xce,0x78,0xf0,0xe2,0xe2,0x07,0x82,0x78,0x80,0xf2,0x00,0x03,0xd6,0x5f,0xd8,0x9e,0x20,0x0e +,0x47,0xbb,0xdd,0x04,0x43,0xff,0x53,0xbb,0x30,0xf1,0xa0,0x07,0x20,0xb9,0xdd,0x07,0x73,0xfd,0x50,0xb9,0xdd,0x84,0x4a,0xd8,0x2e,0x95,0xe0,0x0e,0xf0,0xf5,0xe4,0x77 +,0xc1,0x12,0x6b,0x18,0x00,0x58,0x05,0x40,0x70,0xff,0xf1,0x50,0x80,0x2c,0x5f,0xfc,0x21,0x2a,0xcf,0xff,0x6a,0x7f,0xff,0xbc,0xae,0x80,0xb0,0x50,0x30,0x26,0x0a,0x05 +,0x84,0x82,0x50,0xa3,0x08,0x4a,0x11,0x11,0x88,0x58,0xf5,0xd3,0xbf,0x87,0x1e,0x2f,0x4d,0xd2,0xb8,0xde,0x5d,0xc8,0x5c,0xb6,0xb6,0xab,0x6f,0x51,0x2b,0xae,0x84,0xbd +,0x5f,0xab,0xc7,0xfa,0x21,0x3e,0x0f,0xa0,0x5f,0x55,0x7e,0x1d,0x9b,0x34,0x2e,0xe1,0xa8,0x29,0x54,0x7c,0xc1,0x3f,0x66,0x33,0xbf,0xff,0xed,0x37,0xe0,0x79,0x07,0x20 +,0xef,0xce,0xf9,0x3f,0xa6,0xf9,0xb7,0x0d,0xd4,0x7f,0x65,0xb0,0x33,0x3d,0x59,0xa5,0xff,0x62,0x85,0xdc,0xfc,0x01,0xd4,0xbb,0xfa,0xb9,0x57,0xae,0x53,0x2f,0xe2,0xf3 +,0x99,0x7a,0xa3,0x1f,0x52,0x10,0x50,0xb3,0x2f,0x47,0x89,0x6c,0xe9,0xed,0x27,0xdf,0x04,0x91,0x45,0x47,0x9c,0x8c,0x49,0xd8,0x52,0xcb,0xd0,0x08,0xe2,0x15,0x4a,0xe2 +,0xe7,0x32,0xaa,0xa3,0x41,0x10,0x48,0x1c,0x05,0x51,0x04,0xee,0x00,0x08,0x24,0x05,0x3b,0x05,0x42,0x81,0x61,0x20,0x5c,0x28,0x16,0x0a,0x05,0x83,0x01,0x65,0x20,0x58 +,0x2a,0x13,0x09,0x04,0xc2,0xa1,0x11,0x18,0x44,0x26,0x21,0x42,0x77,0xc7,0x37,0x4e,0x13,0xc5,0xde,0x4e,0x78,0xdc,0x8b,0x5d,0xde,0x4e,0xb9,0xbc,0xd3,0x35,0x51,0xad +,0x79,0x05,0xad,0xf7,0x7f,0x4c,0xe7,0x4f,0xea,0xef,0xf5,0x3c,0x5f,0xff,0xdb,0x28,0xe6,0xed,0xbc,0x8a,0x99,0xdf,0xd0,0xd6,0x9d,0xd6,0xf2,0xfb,0xba,0xf5,0xf5,0x22 +,0x1d,0x9d,0xfd,0x9c,0x7f,0x8a,0x36,0x15,0xef,0x9f,0x6c,0x65,0x5c,0xf3,0xf4,0x6e,0x5e,0xaf,0xd6,0x90,0x7c,0x2d,0xb7,0x8a,0x94,0x9c,0xd2,0xf0,0xa6,0xfb,0xfa,0x37 +,0x9f,0xe2,0xd8,0xe9,0x54,0xbd,0x4c,0x13,0x99,0x74,0xaf,0xe3,0x75,0xf1,0x2f,0x4b,0xef,0xbb,0xd3,0x54,0x45,0x27,0xcc,0x0b,0x3c,0x2e,0x1a,0xfa,0xa1,0xc1,0xa2,0xa1 +,0xb1,0x14,0x84,0xa3,0x35,0x08,0xa3,0xa3,0x33,0x9f,0xae,0x5a,0x00,0xb7,0x1b,0x5d,0xa5,0xdc,0x1d,0xd5,0x2d,0xdd,0xba,0x60,0x70,0xb2,0xf6,0x40,0x95,0xc0,0xb1,0xa2 +,0xb8,0x01,0x40,0xcf,0x50,0x25,0x12,0x80,0xb1,0x70,0x38,0xff,0xf1,0x50,0x80,0x34,0x5f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x5d,0x18,0x2d,0x10,0xa9,0x42,0x44,0x53,0x82 +,0x2e,0xe5,0x6a,0xc3,0xc1,0xb3,0x5c,0x98,0xd7,0xaa,0x08,0x5e,0x05,0x6d,0x8a,0xd1,0xd7,0xd4,0xf0,0x0c,0xde,0x86,0x3b,0x8a,0xc1,0xee,0x51,0x96,0x28,0xc9,0xc1,0x1a +,0x02,0x2d,0x92,0x6d,0xba,0xa3,0xb6,0xa9,0x06,0xfe,0xbe,0xbd,0x19,0x53,0x25,0x65,0x4e,0x6d,0xdf,0xfd,0x7c,0xf9,0x90,0x40,0xee,0xa2,0x83,0x63,0xb2,0x8e,0xb9,0x34 +,0xd0,0x55,0x96,0x13,0xde,0x10,0xa8,0x85,0x11,0x36,0xfb,0x2d,0xf2,0x6b,0xbb,0x84,0xb5,0xd1,0x41,0x08,0x04,0xb3,0x84,0x90,0x57,0x22,0x0c,0x12,0x67,0xd5,0x08,0xf0 +,0xbe,0x7b,0xc7,0x7b,0x9d,0x17,0xc5,0xc6,0x16,0x1e,0x7c,0x17,0x02,0xfa,0xbc,0x3a,0x2a,0x6f,0x19,0x9d,0x22,0x97,0x55,0x57,0x18,0x5b,0xda,0xee,0xbd,0x99,0x73,0x7d +,0x2d,0x18,0x53,0x6f,0x7c,0x02,0x1b,0x94,0x9c,0x7a,0xde,0x39,0x40,0x30,0x5f,0x91,0xbc,0x37,0x10,0x7e,0x1e,0x13,0x19,0x24,0x05,0x81,0xf0,0x2c,0x59,0xa9,0x24,0x76 +,0xc7,0x65,0x23,0x68,0xc6,0xc2,0x02,0xc2,0x31,0x31,0xc0,0xc7,0x32,0x7a,0x04,0x0a,0x0a,0x30,0x59,0xc1,0x62,0x88,0xd0,0x94,0xa2,0xe2,0x5b,0x42,0x0b,0x1d,0x14,0x3f +,0x3e,0xac,0x16,0x49,0x20,0x22,0xdc,0xde,0x86,0x73,0xc8,0x1f,0xa8,0x28,0x2d,0xb7,0x38,0x75,0xc5,0x75,0x4f,0xba,0xaa,0x4e,0x0e,0x5f,0xc7,0x5f,0x7f,0x9f,0xfe,0xea +,0xf0,0x97,0xdf,0x87,0xe2,0x9f,0xbf,0x96,0x7f,0xb7,0xfc,0x7e,0x5d,0x55,0xcf,0xe9,0xea,0xcb,0xfb,0xf7,0x2f,0xc7,0x5f,0x20,0x4e,0x12,0xff,0x27,0xe4,0xf3,0x75,0x78 +,0xa8,0xf3,0x9f,0x5f,0x72,0xa0,0x48,0x5b,0xd1,0x0a,0x3c,0xf3,0x18,0x68,0xa0,0x1a,0xfc,0xc4,0x92,0x41,0x07,0xdb,0x13,0x28,0x04,0xab,0x62,0xd2,0x62,0x26,0x23,0x9a +,0xd2,0x29,0xd3,0x35,0xf0,0x0d,0x32,0x03,0x8d,0xb7,0x53,0x66,0x75,0x23,0xdb,0x7d,0xe4,0xd9,0x63,0xd5,0x92,0xd9,0xaf,0xfe,0x93,0x9c,0xe8,0x9e,0x6f,0xe6,0x54,0xf8 +,0x8e,0x89,0x01,0xb8,0x13,0x48,0x55,0xc6,0xcd,0x30,0x2d,0x7b,0x2f,0x3d,0x9b,0x69,0xda,0xaf,0xd3,0xc3,0x4c,0x24,0xa3,0x5a,0x4f,0x95,0xec,0x9a,0x04,0x2c,0xf2,0xda +,0x4d,0xbd,0x29,0x7a,0x87,0xbb,0x2e,0x4e,0x9c,0xb9,0xd7,0xbd,0xef,0x9a,0x2d,0x2b,0x4d,0xb0,0xda,0xee,0x64,0xc1,0x6c,0x36,0xda,0x9d,0xb1,0x4d,0xcc,0x92,0x63,0x1d +,0x4f,0x9d,0x4f,0x1d,0x4c,0x75,0xf0,0x88,0xad,0x5f,0x92,0xd5,0x38,0xff,0xf1,0x50,0x80,0x32,0x9f,0xfc,0x21,0x6a,0xcf,0xff,0x7f,0xff,0xf6,0xfe,0xb4,0x61,0x40,0x58 +,0x30,0x16,0x12,0x09,0x84,0x81,0x61,0x20,0x98,0x68,0x16,0x0a,0x09,0x82,0xa2,0x20,0xa0,0x48,0x26,0x21,0x09,0x85,0x42,0x21,0x30,0x88,0x4c,0x22,0x25,0x08,0x89,0x17 +,0x57,0x2f,0x73,0x8a,0xef,0x55,0xae,0x3c,0x66,0xaa,0x5d,0x03,0x57,0xd7,0x7c,0x7a,0xd3,0x8e,0x6b,0xce,0xb4,0x3e,0x7f,0xc7,0xbb,0xfb,0xd6,0xa6,0x3d,0xa8,0xea,0xba +,0xfc,0x28,0xe7,0xf0,0x5f,0x91,0x17,0x87,0x0b,0xac,0x4d,0x2c,0x8f,0xc2,0x31,0x1d,0x4e,0xa5,0xd0,0xbe,0x0f,0x6f,0xce,0x62,0x0f,0xb7,0xc6,0xa1,0x71,0x03,0x7a,0xf3 +,0xff,0x63,0xab,0xfc,0xa9,0xaf,0x09,0x81,0x54,0x7e,0xe8,0x6b,0xdf,0x94,0x50,0xdd,0x1b,0xf4,0x9f,0x59,0x4e,0xa2,0x40,0x0d,0x2d,0x78,0xe2,0x32,0xac,0xab,0x7e,0x53 +,0x17,0x1b,0x66,0x5b,0xe3,0x4d,0x77,0x8a,0xab,0x5c,0x47,0xc9,0xeb,0x2e,0x0e,0x3c,0xce,0xfa,0x83,0x33,0x2e,0xaf,0x9f,0x4a,0xab,0xbd,0xcf,0x0d,0xaa,0x18,0x20,0x58 +,0x3b,0xaf,0x5c,0x20,0x03,0xc8,0x05,0x69,0xae,0x24,0x2c,0x97,0x7d,0xb0,0x72,0x85,0x90,0x1f,0x5e,0x00,0x84,0xf8,0x0d,0x0b,0x80,0x3c,0xc0,0x00,0x09,0xe0,0x88,0x14 +,0xc6,0x16,0x0c,0x05,0x8c,0x81,0x63,0x28,0x58,0x50,0x16,0x12,0x05,0xc2,0xa4,0x10,0xa8,0xc4,0x66,0x25,0x09,0x88,0x46,0xe6,0x26,0xef,0x5c,0xdb,0x7a,0x55,0x6b,0x68 +,0xba,0xe2,0xaa,0xef,0x5b,0xbc,0xb1,0x5e,0x79,0xd4,0xcf,0xa1,0xfa,0x39,0x35,0x21,0xe2,0xfd,0x6d,0x6f,0xbf,0xcf,0x0d,0x3b,0xac,0xee,0xea,0x3f,0x8d,0xe6,0xb4,0x76 +,0xfe,0x53,0xf1,0x77,0x96,0x75,0x4c,0x38,0x6f,0x97,0xdb,0x3d,0x55,0x51,0xaf,0x3a,0x9f,0x08,0xe7,0xe7,0x6c,0x7a,0xcb,0x10,0xf3,0x48,0x1c,0xbb,0x00,0x80,0x9f,0x7f +,0x53,0x7f,0x85,0xb5,0x20,0x2d,0x18,0x73,0x77,0x40,0xfb,0x9f,0xc1,0x29,0x7e,0xda,0x22,0xae,0xab,0xce,0xda,0x79,0x68,0x38,0xf9,0x02,0x5e,0x7c,0xbd,0xae,0x5e,0x1c +,0x51,0xc4,0x38,0x6c,0xbb,0x73,0xf0,0x67,0x20,0xe1,0x82,0x8f,0xe1,0x01,0xf3,0x07,0x1e,0x61,0xc8,0x03,0x9f,0x92,0xf1,0x21,0x3e,0xd6,0x2c,0xaa,0x88,0x05,0x7b,0x61 +,0xaa,0x17,0x25,0x61,0xd8,0xed,0xf9,0x44,0x3d,0x60,0xff,0xd8,0x7d,0x7b,0xd6,0x77,0x47,0x88,0x02,0x00,0xf5,0xa4,0x01,0xeb,0x20,0x2b,0x62,0x22,0x11,0x16,0x57,0x40 +,0x1c,0xff,0xf1,0x50,0x80,0x33,0x1f,0xfc,0x21,0x0a,0xcf,0xeb,0xeb,0xff,0xff,0xff,0xb4,0x80,0xb0,0x9c,0x30,0x17,0x0a,0x05,0x42,0x81,0x60,0xa0,0x58,0x48,0x17,0x0a +,0x84,0x82,0x61,0x60,0xb8,0x58,0x28,0x35,0x0a,0x04,0x82,0x81,0x30,0x90,0x54,0x26,0x21,0x11,0x04,0x44,0x61,0x12,0x3a,0xbf,0x1c,0x6f,0xef,0xdf,0x5f,0x3a,0x66,0xaa +,0x29,0x52,0xf2,0x5d,0x22,0xb8,0xbc,0xaa,0xcd,0x3c,0xe3,0xdb,0xc8,0xbd,0xdd,0x7f,0x9f,0xd7,0x67,0x57,0xde,0x8f,0xa4,0xfb,0x8f,0xd3,0x7a,0x1f,0x0a,0x9b,0x97,0x5f +,0xf1,0xbd,0xb4,0x25,0xea,0xde,0x53,0xd1,0xe9,0xbb,0x2a,0x5f,0x5f,0x81,0xf1,0xfc,0xff,0xc0,0xf3,0x02,0x78,0xc6,0xef,0xe3,0xd0,0xf6,0xfb,0x02,0x0b,0x07,0x7e,0x7c +,0xcc,0xb0,0xdd,0xf3,0xf2,0x7a,0x7c,0x90,0x16,0xbd,0xfa,0xa5,0xea,0x75,0xa3,0x3a,0xf7,0x78,0x00,0x99,0xde,0x91,0x8c,0x10,0xa6,0xa9,0xdf,0x3e,0x73,0xd8,0x86,0xdb +,0xe3,0xa9,0xd4,0xfa,0x5e,0x8c,0x29,0x63,0x81,0xc7,0x34,0x66,0xb0,0x54,0x73,0xe0,0x73,0x70,0x5a,0x3d,0x9e,0xe0,0x0f,0x76,0xef,0xad,0x05,0x61,0x4e,0x33,0x4a,0xf5 +,0xc8,0xbb,0x46,0xb0,0xbb,0xce,0x74,0x3d,0xbf,0xa4,0x92,0x40,0x5b,0x85,0x42,0xdd,0xf0,0x2e,0x38,0x8e,0x99,0x31,0x80,0xb8,0x10,0x02,0x7d,0x02,0xc2,0x80,0xb0,0x60 +,0x4c,0x54,0x0b,0x12,0x02,0xc2,0x41,0x28,0x50,0x2a,0x23,0x0b,0x85,0x42,0x21,0x31,0x08,0x54,0x26,0x31,0x33,0xf3,0x4e,0xbb,0xce,0x33,0xef,0xf3,0xf1,0x5e,0x2a,0xa4 +,0x56,0xa6,0x35,0x4f,0xac,0xd7,0x5f,0xb7,0xd7,0xe9,0xa9,0x2f,0xcc,0xde,0xac,0x75,0x0b,0xe7,0xd5,0xf2,0xd0,0xc3,0x87,0xcf,0xf1,0x87,0xf1,0x7e,0x8e,0x5c,0xa6,0xaf +,0x97,0x96,0x61,0xac,0x8d,0x39,0xf2,0x24,0xde,0x8c,0xc0,0xb8,0x9d,0x1d,0xef,0x3f,0x3b,0x28,0xf8,0x12,0xab,0x9a,0x49,0x10,0xba,0xf7,0xb3,0x4a,0xcf,0x7f,0xa7,0x63 +,0x85,0xdf,0x6f,0xf5,0x7f,0x43,0xec,0xfd,0xbd,0xae,0x6d,0x4f,0x7f,0x82,0xba,0xbb,0xdd,0xe1,0x79,0x76,0x3e,0x5c,0xd5,0x2f,0x30,0xf3,0xe3,0xc4,0x76,0xd8,0xfe,0x2d +,0xcf,0xfb,0x17,0x94,0x90,0x02,0x47,0x88,0x00,0x3a,0x29,0x11,0xda,0xe1,0x4b,0xfa,0x4f,0xf8,0x1f,0xe7,0x00,0x09,0x5a,0xb5,0xca,0xf5,0x92,0xab,0x6e,0x4e,0x0b,0xa8 +,0xfa,0x9b,0x1f,0xfe,0x97,0x76,0x4f,0x58,0x4b,0xd7,0x09,0x38,0x56,0xf6,0x09,0x04,0xc1,0x88,0x24,0xc6,0x08,0x81,0x49,0xd8,0x0e,0xff,0xf1,0x50,0x80,0x32,0xff,0xfc +,0x21,0x0a,0xcf,0xfa,0x7f,0xff,0xff,0xff,0xb3,0x62,0x40,0x58,0x28,0x36,0x0c,0x05,0x84,0xa1,0x80,0xb0,0x48,0x2c,0x15,0x0b,0x05,0x04,0xa1,0x40,0xb0,0x50,0x46,0x12 +,0x12,0x84,0xc2,0x21,0x20,0x98,0xc4,0x66,0x11,0x12,0xf5,0xcc,0xe0,0x95,0x97,0x5d,0x77,0x5c,0x6e,0xf1,0xaa,0x55,0xc6,0x3e,0x1d,0xb5,0x9c,0x73,0xfa,0xfd,0xaf,0xdb +,0xd8,0x7d,0xfd,0xd8,0xf6,0xf9,0x7e,0xff,0xf2,0x82,0xf5,0x5f,0xc1,0x7c,0xe3,0xe3,0xdf,0x8f,0xd1,0x6e,0xe0,0x06,0x3e,0xa4,0xaa,0xdd,0xe3,0xc2,0x8f,0x4e,0x21,0xe3 +,0x58,0x41,0xd7,0x44,0x37,0xff,0x3d,0xdf,0x8e,0x35,0x39,0x93,0x1e,0x1e,0xaf,0x7f,0x99,0x08,0x33,0x0e,0xd5,0x9a,0xc4,0x0b,0xc0,0xce,0x2e,0xbf,0xfb,0xc9,0x15,0x7a +,0x07,0xb7,0xd8,0x0a,0x8c,0x01,0x92,0xed,0x00,0x74,0xce,0x40,0xce,0x6b,0x0a,0xde,0x28,0x8d,0xc3,0xfd,0x59,0xaf,0x1d,0x1e,0xeb,0xbb,0xa7,0x12,0xac,0xff,0x28,0xd5 +,0x64,0x55,0xeb,0x6d,0x8e,0xc7,0x90,0x79,0xa2,0xc0,0x1f,0x6d,0xee,0x80,0x4a,0x3c,0x30,0x4f,0x30,0x25,0xb1,0x05,0x12,0xd2,0x50,0xf5,0xea,0x5b,0xd1,0x5c,0xb9,0x21 +,0xff,0xa9,0x95,0xa8,0x52,0x10,0x02,0x37,0x8a,0x02,0x53,0xfa,0xe0,0x02,0xc1,0x50,0x28,0x90,0x2c,0x27,0x0b,0x09,0xc2,0x81,0x80,0xa0,0x58,0x28,0x25,0x0a,0x05,0x82 +,0x81,0x70,0xb0,0x60,0x28,0x16,0x0a,0x85,0x04,0xa1,0x70,0x89,0x14,0x26,0x15,0x09,0x85,0x42,0x61,0x50,0x89,0x5e,0x3b,0xfc,0x7b,0xcc,0xd7,0x8f,0x8e,0xe4,0x52,0x29 +,0x22,0x56,0xb5,0xe5,0xaa,0xfb,0x6b,0x1c,0x6f,0xd8,0x92,0xc6,0xb4,0x2f,0x7d,0x5e,0xcf,0x69,0x57,0xbf,0xc4,0xfb,0xd7,0x35,0xe9,0x9f,0xff,0xce,0xaa,0x7f,0x54,0x7c +,0x7f,0xf7,0x7f,0x1c,0xfc,0xd7,0xc5,0xd3,0x3d,0x27,0xc2,0x0d,0x6f,0xf6,0xfd,0xb7,0x8a,0xcf,0xd1,0xd9,0xce,0xda,0x18,0x51,0xd4,0x6c,0x2f,0xd2,0xfb,0xee,0xbd,0xc0 +,0x7f,0x6f,0xed,0xe9,0x2e,0xa0,0x2c,0x02,0xaf,0xe9,0xf1,0x7c,0x46,0xff,0x15,0xfe,0xcc,0x7c,0xba,0x98,0xf5,0x7b,0xff,0x10,0xf5,0xc3,0xc5,0xc0,0x9e,0x61,0xb8,0x16 +,0xaf,0x3a,0x4a,0xed,0x81,0x6b,0xcc,0x4b,0x44,0x0b,0x00,0x45,0xc3,0x9f,0x3f,0xb8,0x00,0x00,0xee,0x3b,0x84,0x90,0x3e,0xa2,0x43,0xbe,0xf7,0x45,0x40,0xf0,0x00,0x1d +,0xf1,0xdf,0x00,0x79,0x00,0x17,0x10,0x44,0x12,0x95,0x80,0xa0,0x14,0x95,0x00,0xe0,0xff,0xf1,0x50,0x80,0x30,0xff,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xff,0xfb,0xb1 +,0x61,0xc0,0x58,0x30,0x14,0x0b,0x05,0x42,0x81,0x70,0xa0,0x58,0x2a,0x14,0x13,0x05,0x02,0xc1,0x50,0xc0,0x50,0x2c,0x27,0x0a,0x08,0x86,0x27,0x30,0x89,0x55,0x5c,0x5f +,0x7a,0x95,0x4f,0x3e,0x38,0x54,0xdc,0x24,0xa9,0x22,0xa4,0x95,0x52,0x67,0xb6,0xeb,0xef,0x2c,0x2f,0xfc,0xff,0x2c,0xd9,0xee,0xd2,0x07,0xb7,0xfe,0xf9,0xe3,0xd6,0x43 +,0xbb,0xee,0x7f,0x03,0xf6,0x6b,0x25,0xfe,0x6a,0xa7,0xee,0x93,0xc1,0xd1,0x5f,0x69,0x27,0xee,0x6a,0x03,0x37,0xe7,0xfb,0x8e,0x3d,0xee,0xb8,0x97,0x15,0x93,0xf7,0xff +,0x59,0xc8,0x17,0xcd,0x09,0xf4,0x5c,0x87,0xc3,0x4a,0x45,0xb6,0x48,0xc6,0x0a,0xcc,0x4f,0xe7,0xa0,0x0c,0x42,0x48,0xbc,0x39,0x3e,0xdd,0xc5,0xa4,0x26,0x2d,0xba,0xa6 +,0x74,0x89,0x75,0xe6,0x59,0xca,0xd9,0xcf,0x62,0x15,0xc8,0x08,0x97,0xc7,0xcd,0xf0,0xbe,0xee,0x90,0x0c,0x8f,0x5b,0x56,0x0a,0xad,0xb7,0x4c,0x16,0xa3,0x9a,0xd3,0x19 +,0x31,0xc6,0x34,0xb5,0x0e,0x57,0xb4,0x86,0x3a,0xb2,0x51,0x45,0x6d,0x71,0x2b,0xd2,0xd7,0x09,0x7b,0x81,0xc5,0x5a,0x50,0x94,0x8a,0x8a,0x84,0x81,0x10,0xb8,0x14,0xec +,0x14,0x0c,0x05,0x85,0x01,0x60,0xa0,0x98,0xc8,0x26,0x2b,0x89,0x04,0xa5,0x30,0xa8,0x4c,0x6a,0x11,0x31,0xce,0xb3,0x3d,0xb7,0xf8,0xf1,0xe1,0x29,0x6d,0xc9,0x5c,0x50 +,0xd3,0x5a,0xe7,0x7e,0xdb,0x65,0xf9,0x97,0x95,0xa0,0x9c,0xff,0xf8,0x1b,0x4d,0xf1,0xcf,0x4c,0xdd,0x14,0x3d,0xb6,0xff,0xb3,0x98,0xe9,0xfd,0x7f,0x1a,0x00,0x7e,0x05 +,0x6c,0xb5,0x6f,0xa5,0x77,0x5b,0x65,0x9a,0xa2,0x7a,0xbe,0x4b,0xc8,0x7f,0x99,0xa7,0x26,0xe6,0x7f,0xa5,0xbc,0x6c,0x1c,0x9b,0xb6,0xff,0x13,0xb2,0x99,0xf9,0xaa,0xac +,0xbe,0xbf,0x0c,0xa6,0xf2,0x0b,0x81,0x39,0x58,0x79,0x35,0xa4,0xab,0x6e,0xd9,0xce,0x8d,0xdd,0xaf,0xa3,0xde,0x7f,0x1d,0x6e,0x9f,0xaa,0xf7,0x78,0xa7,0xf9,0x5e,0xdc +,0xc1,0xe1,0xf7,0x01,0xf1,0x79,0x9c,0xa4,0x3c,0x80,0x0e,0x67,0x99,0xa0,0x00,0x03,0x93,0x90,0x3e,0x7a,0x75,0x5b,0xbc,0xc0,0x01,0xe0,0x00,0x0f,0xfd,0x7e,0xe9,0xeb +,0x1d,0xc1,0x90,0xf5,0x9e,0xc6,0xd5,0xe6,0x3a,0x01,0xf3,0x02,0x42,0x62,0x40,0x01,0x62,0xd0,0x02,0xe4,0x47,0x00,0x1c,0xff,0xf1,0x50,0x80,0x32,0x3f,0xfc,0x21,0x0a +,0xcf,0xaf,0xff,0xff,0xfd,0x7d,0xb0,0x81,0x30,0xdc,0x2a,0x16,0x12,0x06,0x42,0x81,0x61,0xa0,0x98,0x48,0x17,0x0a,0x05,0x82,0xa2,0x40,0x90,0xc4,0x2a,0x11,0x09,0x84 +,0x44,0x61,0x11,0x18,0x44,0x26,0x11,0x13,0x2b,0x8e,0x3d,0xfd,0xb5,0xea,0x67,0x9d,0x97,0x55,0x2a,0xea,0x17,0x92,0x57,0xc7,0x7a,0xef,0xa9,0xcc,0xbd,0xfd,0x5f,0xd0 +,0x2f,0x49,0x9d,0x7f,0x67,0xeb,0xf6,0xd5,0xe5,0xf4,0x7a,0xa3,0xbc,0x7a,0xb4,0xae,0x87,0xf9,0x36,0x78,0x5f,0x81,0xd3,0xda,0x5b,0xdf,0xa4,0x38,0x6b,0x2a,0x07,0x5d +,0xf5,0xdd,0xde,0xdb,0xe5,0xaa,0xa1,0x60,0x51,0xdf,0x41,0xb7,0xcc,0x7c,0x12,0xd5,0x63,0xcd,0xbb,0x70,0xd4,0x98,0x0e,0x55,0x2a,0x0a,0x95,0xa7,0x1e,0x08,0xdb,0xa2 +,0x9d,0x37,0xc4,0x45,0xa8,0x9f,0x4d,0x49,0xac,0xe7,0x37,0x86,0x32,0x64,0x0c,0x9b,0xad,0x08,0x3b,0x20,0xcc,0xe0,0xb9,0x3c,0xfa,0x92,0xeb,0x8a,0x63,0xc8,0x00,0x36 +,0xea,0x20,0xa2,0x44,0x1f,0x94,0xf7,0x2a,0xb5,0x13,0xad,0x96,0x48,0xef,0x51,0x5f,0x5c,0x53,0x75,0x8b,0x91,0xb0,0xfd,0xa2,0x9c,0x28,0x1d,0xfb,0x26,0x29,0x2e,0xe3 +,0xd7,0x00,0x94,0xc2,0x60,0x54,0xb0,0x50,0x2c,0x28,0x0b,0x06,0x02,0xc2,0x40,0xb8,0x54,0x2c,0x14,0x0b,0x05,0x02,0xc4,0x41,0xb0,0x50,0x2a,0x53,0x1a,0x84,0xc2,0xa1 +,0x30,0xa8,0x44,0xaf,0x3f,0x6b,0xdf,0x9e,0xfe,0xbc,0x7d,0xfd,0xef,0xbb,0xcb,0xa2,0xa2,0x49,0x77,0x5d,0x4f,0x3f,0x68,0x77,0xaf,0x8e,0x32,0xa7,0x01,0x35,0xfe,0x26 +,0xaf,0xbf,0x56,0xd8,0xdf,0xaf,0x9f,0xdd,0xd0,0x87,0x55,0x5b,0x0f,0xb1,0xef,0xe3,0x44,0xe1,0xf1,0x72,0x1a,0xb7,0xff,0x51,0xf8,0x64,0xd1,0x57,0x0d,0xc3,0xaf,0xf8 +,0x8a,0x0f,0x54,0x35,0xaf,0x6c,0x53,0x26,0xb3,0x72,0xf9,0x0f,0x90,0xd8,0x23,0x47,0xf4,0x15,0x75,0x9f,0xe4,0xe4,0x3c,0xb7,0xaf,0xea,0x7c,0x1a,0x2a,0x1c,0x84,0x44 +,0xd7,0xd7,0xe0,0x97,0xe9,0xbc,0x07,0xe1,0x67,0x24,0x74,0xf1,0x8a,0x1e,0x4e,0x61,0xcc,0xa2,0x93,0xc5,0x56,0x73,0x93,0x87,0x98,0x00,0x3c,0x5e,0x60,0x05,0x0e,0x50 +,0xf0,0xbd,0x8f,0xfe,0xd3,0x10,0xef,0x1d,0xc0,0x01,0xe9,0x40,0x0f,0x5d,0x23,0x57,0xd7,0xe0,0x15,0xcc,0xe0,0x46,0x25,0x3f,0xaf,0xb2,0xab,0x87,0x88,0x00,0x50,0x37 +,0x8a,0x85,0x44,0xc0,0x65,0x04,0xc0,0x70,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a,0xcf,0xef,0xf5,0xff,0xff,0xfe,0xae,0x81,0x30,0x60,0x68,0x16,0x0b,0x85,0x03 +,0x21,0x41,0x30,0x90,0x4e,0x14,0x0c,0x05,0x02,0xc1,0x41,0x28,0x50,0x24,0x31,0x09,0x8c,0x46,0x61,0x11,0x18,0x84,0x4e,0xed,0xd7,0x8f,0x8e,0x65,0x6f,0xe3,0xbb,0xac +,0xba,0x99,0x35,0x49,0x2a,0x2b,0xa4,0xaa,0x6b,0x99,0xe5,0xf5,0xa0,0x8e,0xc3,0x45,0x1f,0xd7,0xcf,0x57,0x0c,0x8d,0x2f,0x30,0xdf,0xee,0x4d,0x7d,0xab,0x76,0xf8,0xe6 +,0x85,0xb6,0xaa,0xfe,0x2e,0xd7,0xc5,0xd0,0xbb,0xc8,0x47,0x66,0xf4,0xbb,0xbf,0x1f,0xf5,0x63,0x08,0x55,0xef,0x77,0x65,0x5e,0x8c,0xe3,0x51,0x1e,0x6a,0xbf,0x7c,0x54 +,0xf0,0x78,0x04,0x4a,0x3f,0xbf,0xc0,0xa5,0x2c,0xf6,0xc2,0x12,0xf0,0x66,0xff,0x3a,0xd2,0x2e,0xd5,0xfb,0xba,0x5a,0x9c,0x32,0x70,0xc3,0x9a,0x50,0x89,0xfb,0xf2,0x36 +,0x18,0x23,0xff,0xed,0x43,0x02,0x56,0x64,0xfc,0x32,0x5a,0x3b,0x0e,0xf8,0x7d,0x60,0x82,0xda,0x2b,0x96,0xef,0xdf,0xb8,0xa9,0x59,0xac,0x2b,0x56,0x19,0x22,0xab,0xa2 +,0x25,0xd1,0xf5,0xcf,0x28,0x5c,0x28,0xa2,0x56,0x88,0x77,0x8e,0xe0,0x01,0x50,0xa0,0x0a,0x36,0x1c,0x05,0x82,0xe1,0x80,0xb0,0x54,0x28,0x26,0x22,0x0a,0x02,0xc3,0x40 +,0xb0,0x90,0x4a,0x23,0x08,0x98,0xc4,0x23,0x30,0x88,0x9e,0x9b,0xe3,0x75,0xf1,0xb5,0x54,0x4d,0xcc,0x92,0x12,0x4b,0x93,0xe2,0xea,0xaa,0xb9,0x7d,0xf9,0xbe,0xb3,0xc8 +,0x2d,0x7c,0x79,0xf6,0xfb,0xb4,0x70,0x6c,0xa7,0xbf,0x9f,0xc0,0x15,0x6e,0xfb,0x9f,0xef,0xfd,0x4f,0xb9,0xfe,0xce,0xc0,0x33,0xfd,0x5b,0xbc,0xdb,0x1e,0xe9,0x28,0x4f +,0xe2,0x8f,0xfd,0xb7,0xde,0x11,0xef,0x2a,0x94,0xa8,0x4b,0x35,0xac,0x78,0xd9,0xe6,0x0b,0x02,0x65,0x6d,0x7b,0x05,0x80,0x8b,0xb3,0xea,0x2a,0xcf,0xba,0x71,0x04,0xb4 +,0x2f,0x24,0xa0,0x15,0xf4,0x17,0xf7,0xbf,0x19,0x8f,0x8a,0x8b,0xbd,0xed,0xf0,0xf5,0xdc,0x00,0xe3,0xf1,0xaf,0x11,0xad,0xf2,0x39,0x1c,0x87,0xbb,0xf9,0x61,0x2a,0x5a +,0x60,0x25,0x54,0x49,0xf3,0x05,0xe3,0x20,0x2c,0x58,0xd4,0x2c,0x6a,0x03,0xbc,0xee,0x9e,0xbb,0xba,0x17,0x88,0x09,0x24,0xa2,0x01,0x23,0xb9,0x01,0x30,0x6d,0x05,0x00 +,0xe0,0xff,0xf1,0x50,0x80,0x2f,0x1f,0xfc,0x21,0x0a,0xcf,0x7f,0xfd,0xff,0xff,0xfc,0xac,0x81,0x30,0x60,0x2c,0x18,0x0a,0x05,0x84,0x81,0x70,0xa0,0x58,0x28,0x26,0x1a +,0x05,0xc2,0xc1,0x40,0xb0,0x54,0x48,0x12,0x10,0x88,0xca,0x41,0x31,0x09,0x5e,0xba,0xe4,0xf6,0xcc,0x57,0xc7,0x32,0x73,0xae,0x75,0x93,0x8d,0xde,0x5d,0x43,0xcd,0x4c +,0xbf,0x17,0xd6,0xe4,0xfd,0xfe,0x81,0xb6,0x1d,0xf9,0xfe,0xbc,0xf3,0xdf,0xe1,0xb7,0x5a,0x0d,0x2c,0x5b,0x7a,0x8f,0xfd,0xdf,0xe7,0x4b,0xe2,0xad,0xc5,0xfd,0x6f,0xce +,0x63,0xe1,0xe9,0xef,0x4b,0x5f,0x94,0x24,0x72,0xf4,0x9c,0xd3,0xa8,0x47,0x10,0x67,0x5f,0xe4,0x44,0xcd,0xd4,0x30,0xc1,0xe8,0x15,0x4f,0xfd,0xb7,0x4f,0x6c,0xe6,0x20 +,0x2c,0x70,0x6f,0x31,0x35,0xea,0x88,0xe7,0x5f,0x47,0x05,0x2c,0x99,0x6e,0x43,0x8a,0xa9,0x39,0x64,0x2a,0xb4,0x82,0x04,0xb2,0x6e,0xa2,0x6f,0x55,0x55,0xc1,0xe4,0xc8 +,0x9a,0x89,0xfb,0xfe,0xf0,0x07,0x76,0xb1,0x05,0xdd,0xc1,0x79,0x9d,0xfb,0x03,0xba,0x4f,0xbe,0x23,0x1a,0x50,0xd2,0x88,0xc4,0x4b,0xd0,0xc1,0x84,0x3d,0xd6,0xdb,0x48 +,0x17,0x84,0xc1,0x99,0x60,0x58,0x05,0x80,0x54,0xb0,0xe0,0x2c,0x55,0x0b,0x06,0x02,0x81,0x60,0xa0,0x58,0x50,0x16,0x1a,0x05,0x82,0x81,0x50,0xa0,0x54,0x26,0x11,0x0b +,0x84,0x4c,0xa1,0x13,0x0c,0x89,0x2b,0xe3,0xdd,0x25,0x56,0xb6,0xa9,0x2a,0xed,0x35,0xc4,0xd5,0x49,0x2b,0xc7,0x95,0x32,0xc5,0xfc,0xd3,0xae,0xbf,0xd4,0x3a,0xfe,0xae +,0x5d,0x7c,0xbd,0x49,0x76,0xff,0xc1,0x7b,0xde,0x27,0x7d,0x5a,0xb8,0x4e,0x57,0xff,0x3d,0x5b,0xfa,0xa1,0x2f,0xfe,0x6b,0x85,0xf9,0x9e,0x75,0x11,0x73,0xb3,0x51,0xb5 +,0x7d,0xf7,0x40,0x7b,0xcb,0x50,0xdf,0x57,0x3c,0xc6,0xfd,0xe7,0xdd,0xc6,0xf9,0xac,0xd0,0x3f,0x32,0xfe,0xdf,0x84,0xba,0x68,0xba,0x60,0x6e,0x7c,0xd3,0xf8,0xd8,0xf7 +,0xfc,0x2d,0x27,0x93,0xa5,0x3f,0x36,0xdb,0x9e,0x1c,0xfb,0xc0,0x74,0x4f,0x02,0x53,0xdd,0xd2,0x7f,0xfe,0xfd,0x70,0xa2,0xb0,0x68,0x79,0x40,0x00,0x0f,0x8a,0x45,0xe0 +,0x15,0x15,0x42,0x41,0x62,0x64,0x01,0x60,0x1e,0x40,0x78,0x00,0x04,0x2e,0x02,0xa0,0xba,0x60,0x82,0xe0,0x46,0x20,0x84,0x00,0xe0,0xff,0xf1,0x50,0x80,0x30,0x5f,0xfc +,0x21,0x0a,0xcf,0x7f,0x3d,0xff,0xff,0xfc,0xac,0x80,0xb8,0x50,0x30,0x16,0x0c,0x05,0x82,0x81,0x60,0xa0,0x60,0x2e,0x14,0x0b,0x0d,0x43,0x01,0x61,0x38,0x58,0x2a,0x14 +,0x0a,0x85,0x02,0x42,0x14,0x18,0x44,0xcf,0x17,0xbb,0xcf,0x35,0x9c,0x73,0x72,0xf2,0x37,0x69,0x15,0x21,0xaa,0xbd,0xa4,0xce,0xb2,0x55,0xfd,0x70,0x1b,0xd2,0x7c,0xa7 +,0xe7,0x39,0xc5,0x72,0xc7,0xa6,0x2d,0x8f,0xa3,0xf4,0x47,0xc2,0xf6,0x05,0x01,0xde,0xab,0x14,0x7a,0xfe,0x41,0xc9,0x0d,0x7f,0x40,0xec,0xe3,0xca,0x2f,0xef,0x4f,0x5d +,0xe3,0x10,0x27,0x96,0x07,0x84,0x5a,0x3d,0x52,0x94,0x0b,0x4e,0x75,0x5e,0x5f,0x5b,0x59,0x02,0x4a,0x9d,0xfd,0xde,0x16,0x90,0x56,0x87,0x64,0x03,0xc2,0x56,0xef,0xbf +,0xd1,0x1a,0xa4,0x99,0xf8,0x25,0x5a,0x6c,0x6b,0xb4,0xda,0x89,0x44,0xfd,0xc7,0x45,0x77,0x4e,0xf9,0x57,0x95,0x2b,0xa0,0xbc,0x32,0xf4,0xb7,0x35,0x46,0xae,0x39,0xef +,0x78,0x0a,0xed,0xb5,0x38,0xd2,0x07,0xc8,0xd5,0x5d,0x04,0x22,0xa2,0x5c,0xb8,0xa5,0xa4,0x10,0x77,0xc3,0xec,0x14,0x5e,0x95,0x2d,0x52,0x30,0x20,0x47,0xd8,0x02,0xe0 +,0x58,0x0a,0x86,0x24,0x05,0x82,0x81,0x61,0x20,0x58,0x50,0x16,0x0a,0x05,0x82,0x81,0x61,0xa0,0x98,0x2a,0x14,0x0a,0x94,0xca,0x23,0x31,0x08,0xd5,0x3c,0x6b,0x3a,0xd7 +,0x7c,0x77,0x52,0xf2,0x6b,0x32,0xeb,0x59,0xac,0xd5,0xcd,0xf5,0xb9,0x72,0x7b,0x57,0xcf,0x99,0x7f,0xe2,0xc2,0x6d,0xd1,0x7e,0xfd,0xde,0x6f,0xdf,0xbf,0x17,0xeb,0x5f +,0xdc,0x68,0xe7,0xa4,0xb7,0xbf,0xf6,0x4b,0x6d,0xee,0xca,0xea,0x1f,0x77,0xe8,0xc7,0xe2,0x5a,0xaa,0xfc,0x47,0xee,0x52,0xd0,0xfb,0x76,0x3d,0x9f,0xd5,0xef,0x66,0x0b +,0x98,0x25,0xaf,0x59,0xe9,0x94,0x26,0x93,0x5b,0xa7,0xd6,0xd6,0x6c,0xbf,0x79,0xe3,0x91,0x63,0x5f,0xc5,0xd9,0x38,0xf9,0xcd,0xb8,0x11,0xd7,0xce,0xbd,0xbd,0xe2,0xbc +,0x7e,0x0e,0x1c,0xb9,0x2f,0x98,0x12,0x07,0xd7,0xe2,0x02,0x3c,0xc7,0x03,0xb3,0x89,0x64,0xb0,0x80,0xe2,0x70,0xe2,0x0e,0x22,0x73,0xb7,0x03,0xd6,0x33,0x22,0x4f,0xdd +,0xe2,0xdb,0x0b,0x77,0x43,0xb8,0xef,0x9e,0x38,0x1f,0xc8,0x01,0x99,0x5b,0x82,0x92,0x1a,0x64,0x03,0xba,0x3b,0xe0,0x08,0x81,0x40,0x54,0x0e,0xff,0xf1,0x50,0x80,0x31 +,0xff,0xfc,0x21,0x0a,0xcf,0xea,0xff,0xff,0xff,0xfc,0xad,0x81,0x30,0x90,0x2e,0x14,0x0b,0x0d,0x08,0xc1,0x41,0x30,0x50,0x2c,0x14,0x21,0x0d,0x42,0x61,0x50,0x98,0x44 +,0x26,0x21,0x11,0x88,0x42,0x62,0x11,0x3c,0x5e,0x49,0xc3,0xdb,0xe6,0xcb,0xda,0xe9,0x52,0xae,0xa5,0xd6,0xb8,0x6e,0xaa,0xeb,0x3a,0x7c,0x7b,0xf9,0xf3,0xd0,0xc3,0xd7 +,0xdd,0xcc,0xfd,0xea,0xff,0xad,0xff,0x3f,0xdf,0x39,0x82,0xef,0x3d,0x5c,0x07,0xc6,0xe4,0xbf,0x12,0x03,0xeb,0x7a,0xaf,0x88,0xd6,0xf2,0xb9,0x8f,0x23,0xd5,0x9a,0x50 +,0xcf,0x40,0x1b,0x55,0xaa,0xfe,0x67,0x77,0x6d,0xc1,0xc6,0x26,0xea,0xc7,0x7e,0xff,0x47,0x00,0xe3,0xcb,0x28,0xeb,0x2a,0x0d,0x82,0x8f,0xf1,0x5a,0xd0,0x2a,0xc7,0x27 +,0xf6,0xbe,0x2b,0xc9,0xd0,0x68,0xb9,0x17,0x2b,0x87,0x1c,0x31,0x70,0x4f,0x1b,0x0f,0x31,0x03,0xd6,0x38,0xbc,0x40,0x04,0x3f,0x6a,0x45,0xf1,0x4a,0xdd,0x6f,0x22,0x53 +,0xb6,0xd5,0x94,0xda,0xcd,0xef,0x41,0xa2,0xf3,0x76,0xc7,0x13,0x56,0xb3,0x2e,0x39,0xd1,0xb9,0xbc,0xfc,0x90,0x7f,0xed,0xee,0x81,0x35,0x80,0x5d,0xdf,0x80,0x77,0xbb +,0x97,0x01,0x10,0x90,0x14,0xe8,0x26,0x0c,0x05,0x84,0xe1,0x30,0xb0,0xe0,0x2c,0x17,0x0a,0x85,0x82,0x82,0x80,0xb0,0x94,0x28,0x25,0x0a,0x05,0x44,0x61,0x70,0xa8,0x50 +,0x26,0x35,0x08,0x90,0xc2,0x22,0x33,0x69,0x9e,0x7b,0xeb,0xbb,0xe3,0x9b,0xe7,0x59,0xac,0x48,0x91,0xa7,0x9f,0x59,0x38,0xae,0xba,0xa7,0x7a,0xff,0xdf,0xe0,0x7f,0xab +,0xe0,0x7b,0x3c,0xfd,0xf4,0x7c,0xcb,0xf8,0xaf,0xbe,0xaf,0xf0,0x7f,0x63,0xc0,0xbd,0xfe,0xde,0x55,0xf4,0x58,0x59,0xa7,0x2f,0x0f,0x57,0x7d,0xae,0x8f,0x93,0x83,0xae +,0xdd,0xd5,0xf2,0xff,0xd1,0xf3,0xb9,0xff,0x5c,0x4f,0x50,0x27,0x8c,0x36,0x3b,0x6f,0xdd,0xdb,0x46,0x6d,0x0b,0xb5,0xcb,0xb4,0xe3,0xf2,0xe5,0xe3,0x76,0xd9,0xe9,0xdf +,0x5f,0x8f,0xbe,0x7e,0x4a,0x17,0x0a,0xea,0xc8,0xe2,0x5e,0x35,0xf9,0x3e,0x3d,0x45,0x13,0x7c,0x57,0xdd,0x49,0xb4,0xb9,0x1c,0x9c,0x43,0xc2,0x81,0xeb,0x80,0x00,0x79 +,0x92,0x73,0x07,0x0c,0x94,0x92,0x3e,0x0d,0x8e,0xa8,0x2f,0x43,0xe5,0x6f,0xdc,0x25,0xdd,0x07,0xac,0xef,0x3d,0xa7,0x70,0x77,0x80,0x00,0x1e,0x31,0x98,0x00,0x56,0x93 +,0x05,0x85,0x52,0x80,0x1e,0xb8,0xb0,0x05,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x32,0xff,0xfc,0x21,0x0a,0xcf,0xff,0xef,0xff,0xff,0xfc,0xae,0x80,0xb1,0x20,0x28,0x26,0x0a +,0x05,0x88,0xe1,0x60,0xa8,0x58,0x28,0x16,0x12,0x11,0x42,0x81,0x20,0xa8,0x4c,0x24,0x11,0x09,0x04,0x46,0x63,0x12,0x37,0x2b,0x5b,0xf6,0xae,0x6d,0x32,0xe9,0xac,0x53 +,0x55,0x2e,0xf6,0xe3,0x15,0x52,0x9d,0x27,0x37,0xfa,0xf9,0x03,0xeb,0x7f,0xcf,0xd7,0xd7,0x7f,0xf9,0x25,0x1f,0xfb,0x32,0x1f,0xeb,0x7b,0xcf,0xe2,0xff,0xc5,0x77,0x24 +,0xcd,0xda,0x82,0xd8,0x97,0x28,0xd2,0x0f,0x1d,0xce,0x51,0x37,0xd1,0xde,0xfd,0xe7,0x3f,0xd3,0x48,0x6f,0x60,0x06,0xa8,0xdb,0xbd,0x40,0x58,0x0c,0x32,0xd4,0x8d,0xd0 +,0x03,0x9f,0x0b,0xa5,0x86,0x94,0xe1,0xd1,0x46,0x2b,0xa7,0x18,0x2f,0x3e,0xf4,0xda,0x6c,0xb5,0x85,0xf0,0x71,0xe6,0x0d,0x55,0xc2,0xf7,0x2f,0xd8,0xa7,0x34,0x67,0xd3 +,0x18,0x2a,0xc1,0xc1,0xc5,0xce,0xba,0x48,0xc8,0xf1,0xa2,0x33,0x19,0x0c,0xe0,0xfc,0xa1,0x9a,0x17,0x2e,0xb2,0x62,0xa5,0x04,0xc7,0x9e,0xcd,0x77,0xac,0xd6,0xc4,0xa5 +,0xe9,0x82,0xf7,0x5b,0x14,0x5a,0x2d,0x11,0xeb,0x1f,0xb2,0x05,0x2d,0x3f,0xfd,0x22,0x81,0xde,0xe5,0x94,0xd9,0x35,0xc2,0x00,0x94,0x40,0x9e,0x50,0xb0,0x60,0x2c,0x37 +,0x0b,0x05,0x44,0xc1,0x70,0xa8,0x58,0x8e,0x15,0x0c,0x05,0x04,0xc1,0x53,0x18,0x94,0x26,0x35,0x09,0x85,0x42,0x61,0x10,0x98,0x44,0x4f,0xce,0x55,0xe4,0xe3,0x7c,0x6d +,0x33,0x3c,0xf3,0x75,0x49,0x2d,0x9a,0xd2,0x63,0x49,0x7b,0xeb,0x9c,0xe3,0xff,0xc7,0xd8,0x3e,0x73,0xeb,0x7f,0xc7,0xa3,0x97,0x3f,0x57,0xc6,0x9f,0x6a,0x17,0xbf,0xee +,0x78,0x2a,0xab,0x51,0xfd,0xf8,0x97,0xd7,0xcf,0xff,0x82,0x53,0xaa,0x6b,0x36,0xfe,0xb8,0xa2,0x00,0xf4,0xb7,0xd3,0x1b,0x2f,0xa5,0xfd,0x1f,0x1e,0x10,0xc7,0x5e,0x17 +,0xca,0x7f,0xe0,0x3d,0x9f,0xfd,0x9c,0xe3,0xa3,0x8e,0xd0,0xf3,0xf2,0x98,0x86,0xb0,0x0e,0x9e,0xf1,0xc7,0x8f,0xaf,0x31,0xdb,0xfd,0x08,0x99,0x5f,0x2c,0x63,0x85,0x2d +,0x0e,0x09,0x15,0xd9,0xcf,0x95,0xb9,0x9e,0x00,0x86,0xdc,0x43,0xcb,0x9f,0x10,0x03,0xdd,0x1d,0xf3,0xdd,0x8c,0x3d,0xc5,0x75,0x53,0x8e,0x14,0xa2,0xc7,0x15,0x58,0xb3 +,0xb8,0xee,0x03,0xdc,0x5f,0xd7,0x7b,0xa1,0xeb,0x00,0x01,0xe2,0x7a,0xfd,0xd0,0x00,0x00,0xf3,0x7a,0xdd,0xf0,0xf7,0x16,0x82,0xb5,0xbe,0x13,0xd6,0x54,0x2e,0x01,0x40 +,0x38,0xff,0xf1,0x50,0x80,0x30,0xff,0xfc,0x21,0x2a,0xcf,0xfb,0xff,0x6e,0xff,0xbc,0xb1,0x63,0x20,0x58,0x28,0x16,0x4a,0x05,0x82,0x84,0x50,0xa0,0x8c,0x42,0x13,0x10 +,0x91,0x42,0x61,0x11,0x18,0x44,0x4a,0x97,0x33,0xce,0x32,0x17,0xbb,0x94,0xdd,0xe9,0x9c,0x55,0x7b,0x65,0x19,0x2a,0xbe,0x2b,0x99,0xd7,0xd7,0x91,0xf3,0xf3,0x7a,0xfe +,0x5a,0x7f,0xdf,0xa7,0xb7,0xbb,0x77,0xda,0x4f,0xea,0x05,0xd9,0xf8,0xaf,0x5c,0xed,0x2e,0xa1,0xf8,0x3a,0x3b,0x87,0x89,0x75,0x4a,0x15,0x7d,0xd1,0x2f,0xf6,0x4b,0x70 +,0x55,0xac,0x17,0xb2,0x70,0x18,0xbb,0xf3,0x40,0x5a,0x65,0xbb,0x89,0x73,0xea,0xd4,0x7e,0xcf,0xb4,0xd0,0x00,0x7e,0x49,0xcb,0x77,0xf3,0x7c,0x84,0x77,0xed,0x8b,0x77 +,0xda,0x7a,0x24,0xf0,0xc3,0x3a,0xc7,0x7a,0x57,0x24,0x38,0x5b,0x09,0xf9,0x6d,0xd2,0x0c,0x7c,0xf8,0xed,0x14,0x9e,0x3f,0xfd,0xe1,0xfb,0x45,0x95,0x5e,0x29,0x5d,0x42 +,0xff,0xba,0x8d,0xbd,0xf4,0x20,0x87,0x39,0x0f,0xf3,0x5a,0x08,0xdb,0x2c,0xb1,0x3d,0x8f,0x4c,0x93,0x16,0x7e,0x28,0xd4,0x00,0x78,0x87,0xa0,0x00,0x9d,0x29,0x61,0x73 +,0x67,0x72,0x41,0x7f,0x80,0x08,0x05,0x80,0x53,0x28,0x50,0x2c,0x74,0x14,0x05,0x82,0x82,0x63,0x20,0x58,0x48,0x25,0x11,0x89,0x46,0x63,0x40,0x88,0x4c,0x22,0x47,0x3b +,0xeb,0x75,0xd5,0x73,0xf5,0xe1,0xae,0x75,0x94,0x95,0x2a,0x6a,0xae,0xb8,0xba,0xea,0x56,0x6e,0xb9,0xfe,0x76,0xd7,0xdf,0xf5,0x0f,0x67,0xeb,0x5b,0x3d,0x1e,0x1e,0xff +,0xaf,0xaf,0xd5,0xb7,0xcf,0x3d,0xdd,0x5e,0x56,0xd4,0x5f,0xb7,0xd1,0xfa,0x45,0x92,0x71,0xe0,0x19,0x7f,0x5a,0xfd,0xd7,0xfe,0x3e,0x4f,0x5d,0x79,0xac,0xdc,0x3a,0x3f +,0x4d,0x91,0x45,0x58,0xf1,0xa0,0xf1,0x8b,0xbe,0x1a,0x68,0x9a,0xda,0x13,0xb5,0x5e,0xea,0x35,0x2f,0x35,0x0f,0xe6,0xc0,0xdf,0xaf,0x31,0x46,0xd2,0x14,0x33,0x07,0xbe +,0x42,0xf8,0xf4,0xf2,0xd4,0xf7,0x0c,0x45,0xb2,0xd5,0x57,0xf0,0x3d,0xf7,0xc7,0x51,0xdc,0x3e,0x2e,0x64,0x3c,0x83,0xd2,0x2d,0xe1,0x7f,0x28,0x1f,0xb3,0xf8,0x36,0x60 +,0x79,0x00,0x00,0xb0,0x0f,0x00,0x78,0x80,0x00,0x05,0xfb,0xf6,0xf7,0x69,0x6f,0x24,0x1f,0x1b,0x10,0x84,0xe1,0xc5,0xa6,0xb8,0x33,0x2c,0x1f,0xda,0x05,0xa0,0xa0,0x7a +,0xcb,0x91,0x00,0x72,0x22,0x02,0x20,0x38,0xff,0xf1,0x50,0x80,0x30,0x1f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x3d,0x18,0x4d,0x10,0xa9,0x22,0x29,0x72,0x2e,0x4a,0xbb,0x83 +,0xa0,0xca,0x6c,0x00,0xce,0x34,0x03,0xf8,0x38,0x7d,0xb8,0xd5,0xc2,0x13,0x55,0x70,0xb5,0xd9,0xc9,0x6e,0xe7,0xbf,0x45,0x36,0x0a,0xa1,0xbb,0x62,0xd9,0x06,0xd0,0xac +,0x75,0x50,0xd1,0x8e,0xd2,0x7f,0xaa,0x5a,0x02,0x91,0x1e,0xbc,0x28,0x4e,0x2c,0x77,0xdb,0x84,0x89,0x7f,0x1f,0x12,0xc0,0x0b,0x29,0x9d,0xc2,0x70,0x97,0x7c,0xbc,0xb8 +,0x76,0x4c,0x76,0x8c,0xad,0x2b,0x2d,0xf2,0xc9,0xe4,0x59,0x51,0x9c,0xc7,0x65,0xce,0x94,0xdc,0x8b,0x40,0x02,0x51,0x7c,0xe1,0x0e,0x8c,0x00,0x2f,0x17,0xd4,0x32,0xd8 +,0xe0,0x6f,0x06,0x2c,0x41,0x47,0x42,0x07,0x0c,0x0f,0x8a,0x51,0x39,0x30,0x60,0xc5,0x71,0x55,0x6d,0xe4,0x21,0xf1,0x88,0xad,0xc0,0x44,0x42,0x96,0x9c,0x5a,0x73,0x4b +,0x69,0x30,0xb3,0x3b,0x66,0xaf,0xdf,0xd5,0xf6,0x45,0xed,0x91,0x00,0x23,0x59,0xa9,0xb0,0x9d,0x72,0x75,0x2d,0x14,0xa5,0x40,0xd6,0x6b,0x8f,0x1e,0x5c,0xef,0x54,0x88 +,0xae,0x94,0xce,0xb3,0xac,0xa9,0x2c,0x75,0x2d,0x90,0x58,0xfb,0xc0,0xc7,0x11,0x30,0x38,0x72,0x28,0xa0,0xb2,0x82,0xc9,0x0a,0x93,0x22,0xd7,0x55,0x27,0x1c,0x7b,0x78 +,0xaf,0x61,0x67,0x3a,0xf7,0x37,0x7a,0x86,0x5f,0xa1,0x73,0x89,0xa8,0xa9,0xea,0x6b,0xb9,0x71,0x3d,0x9e,0xcb,0x35,0x74,0x4c,0x64,0xaa,0x9c,0xf1,0xaf,0xe5,0x4f,0xed +,0xd9,0xb3,0x4e,0xed,0x3f,0xb6,0x1f,0x3c,0xe3,0xa6,0x55,0xfa,0x6d,0xfd,0x55,0x55,0xf6,0xd3,0xce,0x65,0xbc,0x09,0x35,0x1c,0x8e,0xf5,0x2b,0x59,0x7c,0x78,0xd1,0xc7 +,0xe9,0xe4,0xfe,0x7e,0xab,0xdd,0x35,0x7b,0xf2,0x9e,0x6e,0xb7,0x22,0xdd,0xd9,0x03,0xfd,0xdc,0x21,0x0b,0x80,0xdb,0x3a,0x63,0xd7,0xe1,0x28,0xd5,0x5e,0x0d,0xd2,0xd9 +,0xaf,0xfd,0x37,0x3f,0xd0,0x7b,0xf5,0x84,0x7b,0x3e,0x97,0x5a,0x2f,0x52,0xef,0xfe,0x80,0x85,0x6f,0x7d,0x0d,0xbe,0x23,0xa8,0x71,0x12,0x34,0x28,0x73,0x92,0x9e,0xfa +,0x10,0xb0,0x00,0x4d,0xe7,0x12,0x6a,0xf4,0x9e,0xfd,0x38,0xef,0x73,0x91,0x88,0x90,0x31,0x9f,0x36,0x1d,0x5b,0xb7,0x10,0x0b,0x6d,0x46,0xc8,0x49,0xda,0x2c,0xd1,0x08 +,0x00,0x08,0x04,0x09,0xc8,0xf5,0xfa,0x0e,0xff,0xf1,0x50,0x80,0x31,0x1f,0xfc,0x21,0x6a,0xcf,0xdf,0xf7,0xfb,0xff,0xf7,0xaa,0x81,0x30,0x90,0x44,0x15,0x0b,0x05,0x42 +,0x81,0x60,0xa0,0x98,0x48,0x16,0x12,0x09,0x82,0x82,0x60,0xa8,0x50,0x26,0x15,0x09,0x0c,0x44,0x63,0x51,0x18,0x44,0x6f,0xb6,0xae,0x7c,0x57,0x8c,0x9a,0x55,0x65,0x7b +,0x77,0xad,0xc4,0x5c,0xab,0xad,0xd8,0xeb,0x2e,0x71,0xce,0xff,0x7e,0x82,0xb3,0xfb,0x0b,0x5e,0xde,0x3e,0xe2,0xfd,0x27,0xf0,0x3f,0x0f,0xbf,0xc0,0xbd,0x4f,0x7f,0xeb +,0x5c,0x90,0x44,0x13,0xbb,0xd1,0x9c,0x63,0xde,0x97,0xd9,0xf3,0xe1,0x71,0xe8,0x48,0x39,0xee,0xb1,0x54,0x75,0xa2,0x50,0xa9,0xc9,0x03,0xff,0x1a,0x9c,0x3b,0x7b,0xd1 +,0x52,0x42,0xbc,0x37,0x11,0x56,0xa0,0xaf,0x7c,0x27,0xb4,0xe0,0x69,0xbf,0x6d,0x06,0xf0,0x20,0x2f,0x22,0x5b,0xb6,0x9d,0x62,0xac,0xb1,0x31,0x4f,0x77,0x3b,0xc6,0x5f +,0xdb,0x95,0x65,0x53,0x75,0x48,0xea,0xd9,0x71,0xca,0xb0,0x47,0xb0,0xe5,0xd8,0x3c,0x08,0x85,0xcf,0x9e,0xfb,0xa2,0x12,0xa9,0x1d,0x3e,0x58,0xcb,0x42,0xf2,0x7c,0xe6 +,0x0f,0xfd,0x04,0x2e,0x8c,0x9d,0xf0,0xef,0x1e,0xe1,0xe2,0x00,0x03,0xc0,0x00,0x02,0x61,0xdf,0xb3,0xa4,0x5c,0x42,0xe0,0xb0,0x0a,0x54,0x0b,0x06,0x04,0xc1,0x80,0xb8 +,0x50,0x2c,0x14,0x13,0x0d,0x03,0x01,0x62,0x20,0x58,0x28,0x16,0x0a,0x05,0x48,0x22,0x31,0x88,0x4c,0x22,0x43,0x08,0x89,0xe2,0x56,0x2e,0x71,0x97,0x98,0x95,0x52,0xa5 +,0x5a,0x25,0xf9,0x9d,0x57,0x84,0xe3,0xc7,0x17,0xaf,0x19,0xf1,0x63,0xc5,0x9f,0x90,0xb4,0xf9,0x87,0xf2,0x53,0xd3,0x57,0x9d,0xf3,0xcd,0x95,0x6b,0x8d,0xdb,0xe6,0xfa +,0x2d,0x3a,0xaa,0xab,0xa2,0xec,0x7b,0x13,0xfa,0x60,0xe7,0xfb,0xcf,0x96,0x81,0xf6,0xd7,0xd5,0x9d,0x1b,0xad,0x9a,0x8b,0x7c,0x35,0xd0,0xd8,0x5d,0x04,0x9a,0xbf,0x33 +,0xa5,0xbf,0xa1,0xec,0xe9,0x23,0x10,0xdb,0x78,0xdf,0xd3,0x7d,0xf3,0xa6,0x5e,0x5a,0x46,0xf3,0x42,0x39,0x78,0x0e,0x7f,0xef,0xbf,0xc4,0xe3,0x8f,0xc4,0xe8,0xa7,0x6c +,0xa6,0x87,0x2e,0x43,0x87,0x78,0x0b,0x3d,0x80,0x0f,0x2f,0x20,0x17,0x06,0x68,0x8a,0x7e,0x60,0xc8,0xef,0x68,0x1f,0x96,0x1e,0xb8,0x4a,0x63,0xb8,0x5a,0xa1,0xdd,0xf5 +,0x80,0x01,0xb7,0x4c,0x40,0xbc,0xc0,0x98,0x2e,0x4f,0xba,0x58,0x16,0x09,0x00,0xe0,0xff,0xf1,0x50,0x80,0x33,0xff,0xfc,0x21,0x0a,0xcf,0x4b,0xf7,0xff,0xff,0xbc,0xaf +,0x70,0xc0,0x58,0x30,0x14,0x13,0x05,0x06,0xc2,0x50,0xb1,0x10,0x4c,0x24,0x0a,0x85,0x04,0xa1,0x40,0xa8,0x50,0x24,0x15,0x09,0x85,0x42,0x42,0x30,0x88,0x4c,0x42,0x46 +,0xd7,0x3a,0xe6,0xea,0x55,0xca,0xca,0xba,0x22,0xf2,0x12,0x65,0xca,0xc7,0x1f,0x1e,0x33,0xef,0xf3,0xfb,0x83,0xe0,0x50,0xe6,0xfd,0xfb,0xba,0x28,0x7f,0x41,0xd5,0x3a +,0x0b,0xf4,0xff,0x50,0xf8,0xb4,0x9a,0x6a,0x0e,0x24,0x8f,0xe0,0xe6,0x7e,0x48,0x7f,0xa8,0x98,0xfc,0xe4,0xf3,0xab,0x6f,0x7e,0x89,0xa3,0x78,0x3d,0x17,0x3e,0x87,0x32 +,0xd8,0x3a,0x8a,0x28,0x40,0x2d,0x5e,0x19,0x93,0xfe,0x02,0xb9,0x78,0x2f,0x8a,0x03,0x38,0xee,0x5d,0xc7,0xed,0x4f,0xad,0x8f,0x16,0x6f,0x86,0x6e,0x5e,0xe9,0xaa,0x68 +,0xdb,0x22,0x25,0x8a,0xb2,0x8f,0xab,0xba,0x96,0xac,0x4a,0xff,0x77,0xd5,0xe3,0xd0,0x7a,0xfc,0x94,0x25,0x9e,0xc6,0xe2,0x9b,0xf2,0x40,0x45,0x32,0xe2,0x70,0x23,0x19 +,0xfc,0xab,0xcc,0xbb,0xd3,0x4a,0xb7,0x1b,0x0b,0xbb,0x48,0x1c,0xc1,0xae,0xd0,0xe3,0x44,0xf5,0xa6,0x0f,0x76,0x0f,0x0a,0x80,0x4d,0x57,0xce,0xbb,0xa0,0x09,0x51,0xde +,0x17,0x05,0xbb,0x2b,0x22,0x53,0x01,0x50,0x2a,0x14,0x2c,0x24,0x0b,0x09,0x02,0xc1,0x80,0xb0,0x50,0x50,0x14,0x0a,0x85,0x85,0x01,0x50,0xb0,0x50,0x4a,0x14,0x0a,0x85 +,0xc2,0xa1,0x10,0xb8,0x54,0x66,0x25,0x1b,0x84,0x4a,0xcd,0x57,0x6d,0x7c,0x7e,0x7f,0x57,0xbd,0x4b,0x6d,0x78,0x96,0xaf,0x3b,0xfc,0x6f,0x6d,0xa7,0x0f,0x7f,0xaf,0xdf +,0xd7,0xdb,0xfc,0x68,0x3e,0xfe,0x39,0x17,0xbf,0xff,0xaf,0x93,0x6f,0xf9,0x67,0xfb,0x71,0xfe,0x74,0x08,0x74,0x2e,0x5e,0xde,0xe5,0xf3,0xb2,0xca,0xd1,0x8f,0xf1,0x1e +,0x27,0xc5,0xf3,0xe3,0xc2,0xa4,0xa2,0x17,0xb6,0x7a,0x8d,0x00,0x0c,0xf4,0x67,0x0f,0x85,0x3f,0x21,0xe7,0x5d,0x5c,0xb8,0x72,0x7f,0xe7,0xf4,0x7f,0x53,0xe6,0x09,0xff +,0xfb,0xe7,0xca,0x5f,0x67,0x20,0x47,0xb3,0x93,0xf5,0x9f,0x93,0xd7,0x6b,0x9f,0x14,0xf0,0xe4,0xdb,0xdb,0xa8,0x80,0x39,0x1e,0x17,0x67,0xda,0x6d,0xd2,0x20,0x00,0x3c +,0x83,0xc4,0x00,0x39,0x00,0x3c,0x3c,0x80,0x07,0x07,0x23,0x8b,0x98,0xe2,0x7b,0x9d,0xe7,0xb8,0x1d,0xcf,0xe4,0x87,0x80,0x3c,0x40,0x01,0xe2,0x00,0x38,0x80,0xe4,0x44 +,0x1c,0x7c,0x19,0x24,0x00,0x48,0x01,0x3b,0x83,0x3d,0x10,0x08,0x01,0x60,0x1c,0xff,0xf1,0x50,0x80,0x30,0x5f,0xfc,0x21,0x2a,0xcf,0xf7,0xfc,0xff,0xff,0xff,0xaf,0x60 +,0xc0,0xd0,0x2c,0x14,0x13,0x05,0x42,0xc1,0x42,0x30,0x50,0x30,0x16,0x0a,0x05,0x82,0x86,0x21,0x19,0x54,0x24,0x13,0x11,0x04,0x48,0xc5,0xba,0x8e,0x6a,0xe6,0x79,0xed +,0x48,0x49,0x52,0x55,0x38,0x94,0xae,0xbd,0x71,0x79,0x4f,0xfd,0xb4,0x33,0xf6,0xea,0x28,0xf5,0xf0,0xf4,0x01,0xfd,0x47,0x81,0xf3,0x0d,0x87,0xda,0x7e,0x0f,0xa4,0x44 +,0x7d,0x68,0xef,0x63,0xa0,0xfe,0xf2,0xdf,0x55,0xdd,0xa8,0xf3,0x8f,0x87,0xed,0x71,0xb9,0x86,0x78,0x03,0xa4,0x8f,0xd6,0xef,0xda,0xe9,0x8e,0xec,0x74,0xbd,0xf5,0x02 +,0xb9,0x2f,0x79,0xfb,0x67,0x6b,0xa3,0x73,0xeb,0x8a,0xfa,0x5f,0x1a,0xe2,0x05,0xb1,0xec,0x22,0xea,0xbe,0x43,0xb9,0xd9,0x9d,0x09,0x26,0xa1,0xd7,0x7a,0xa8,0x5c,0x98 +,0xf4,0x5d,0x03,0x95,0x42,0x8e,0xf8,0x22,0x81,0xcf,0xfe,0x5d,0x4f,0x75,0x48,0x0f,0x7a,0x0f,0xa9,0x46,0xe3,0xc2,0x7f,0xfe,0x7d,0xd3,0xc5,0x1e,0xe7,0xb2,0xcb,0xde +,0xf4,0x40,0x16,0x1e,0x02,0x4e,0xad,0x00,0x86,0x55,0x08,0x22,0x9b,0xb8,0x0e,0xf9,0x23,0x89,0xdc,0x4d,0x29,0x29,0x59,0x4a,0xa0,0x50,0xe5,0x30,0x6d,0x04,0xc0,0xa5 +,0x40,0xb0,0xa0,0x2c,0x18,0x0b,0x0d,0x02,0xa1,0x60,0xc0,0x58,0x28,0x36,0x0a,0x05,0x42,0xc2,0x41,0x98,0x54,0x42,0x17,0x08,0xb5,0xe3,0xdb,0xdd,0x7a,0xf1,0xe6,0xea +,0xb2,0x64,0x64,0x84,0xa9,0xa9,0x7f,0x5b,0x99,0x7b,0x46,0xbc,0xfb,0x7d,0xbd,0x83,0xe6,0x13,0xf5,0x76,0xfe,0xbb,0xc8,0x7b,0xfe,0xba,0x39,0x7a,0x6b,0x93,0xe5,0xee +,0x97,0x49,0x67,0xf3,0x87,0x88,0x1c,0xb0,0x11,0xad,0x14,0x3d,0x9b,0x7f,0x6b,0xb6,0x7c,0x0f,0x41,0x7e,0x4b,0xe8,0x7a,0xdb,0x7c,0xbb,0x87,0xe2,0x3c,0x8b,0xf5,0xf6 +,0x78,0x3f,0xdf,0x8b,0x54,0xf7,0x87,0xd4,0xef,0xc3,0x86,0x06,0xb4,0x72,0xed,0x43,0xcd,0xc0,0xff,0x65,0xf9,0x2e,0x97,0xdc,0xf3,0xd7,0xfd,0x8e,0xeb,0x51,0xfa,0xff +,0x9e,0xc7,0xbc,0xf4,0x08,0x1c,0x8b,0xbf,0x0a,0x1e,0x21,0xc5,0xc0,0x26,0x25,0x49,0x27,0xc8,0x00,0x00,0x96,0x94,0x78,0x52,0xc4,0xe0,0x8c,0x97,0x88,0x1f,0x88,0xa5 +,0x92,0xa8,0x01,0xf1,0x0a,0x58,0x5a,0x00,0x13,0x05,0x00,0x18,0x00,0x08,0x08,0x81,0xc0,0xff,0xf1,0x50,0x80,0x31,0xbf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x4d,0x16,0xa9 +,0x0c,0x89,0x71,0x33,0x4b,0x33,0x5e,0x45,0xcc,0xe1,0x8a,0xcb,0x19,0x76,0xa6,0x94,0x17,0x93,0x77,0x0d,0x8d,0xf3,0xaa,0xc5,0xd2,0x54,0xaf,0xec,0xa7,0xdb,0x6e,0x7e +,0x0b,0x8f,0x65,0x20,0x3d,0xeb,0x4c,0xdb,0x5e,0x9d,0x97,0xf2,0x2d,0xb4,0x1e,0x3c,0x32,0xe1,0x0f,0x67,0x74,0xb9,0x61,0xe6,0x26,0xc4,0x74,0x16,0x1d,0x7c,0x94,0x5c +,0x80,0x7d,0x77,0x50,0xa1,0x24,0x28,0xc4,0xb8,0x9a,0x05,0x09,0xc1,0x56,0x6a,0xaa,0x90,0xc6,0x6c,0x5e,0x74,0x6d,0xcd,0x06,0x8b,0xd3,0x5f,0x0e,0x3a,0x5e,0x9c,0x35 +,0xb5,0xde,0x7d,0x5c,0xdf,0xfe,0x18,0x15,0xb3,0x7f,0xf7,0xbb,0x41,0x36,0x6f,0x0d,0x6f,0x7d,0x99,0x1a,0xbe,0x9f,0x22,0x16,0x90,0x34,0xbc,0xaa,0x21,0x39,0xd9,0x39 +,0xbb,0x29,0x66,0x74,0xc6,0xfb,0x3c,0x80,0xd8,0xae,0x07,0x26,0xf5,0x1d,0x9b,0xae,0x27,0x56,0x38,0x65,0xe7,0x0f,0xdb,0x5b,0x87,0x57,0x3d,0x99,0x59,0xe7,0x67,0xb1 +,0xc0,0x85,0x17,0x82,0x9b,0x0e,0xae,0x0f,0xb2,0xf1,0xbf,0xfb,0xa8,0xa0,0x34,0x94,0x12,0xc8,0x52,0x67,0x40,0x10,0x11,0x14,0x34,0x61,0xb3,0x46,0x28,0x99,0x72,0xf8 +,0xac,0xd7,0x41,0xb4,0xa2,0x25,0x61,0x07,0xd5,0x39,0x15,0x3b,0xf4,0xd7,0x1c,0x93,0x7b,0x34,0x93,0x1a,0x8a,0xcb,0x2c,0x45,0xcc,0x86,0xd6,0x6e,0xe0,0xec,0x52,0x88 +,0x59,0x18,0xc0,0xbc,0x88,0xa1,0xa4,0x2a,0x14,0xa2,0x97,0x29,0xbd,0x96,0x24,0xbd,0x02,0x35,0xb3,0xcb,0x62,0x4e,0x1c,0x69,0x39,0x49,0xa5,0xa6,0x8b,0xb4,0xc9,0x9f +,0x67,0x77,0x1e,0x8d,0x22,0x65,0x8f,0x67,0x0a,0x86,0x66,0xee,0xc1,0x6a,0xd1,0x85,0xc1,0x59,0x85,0x9e,0x4a,0x9e,0x4f,0xaa,0x6e,0xa3,0xdd,0xbb,0x26,0x9c,0x1a,0x70 +,0x61,0xaa,0x42,0x91,0x52,0xfc,0x8a,0x82,0xe2,0xa8,0x4a,0x68,0x5a,0xab,0x5b,0x08,0x6a,0x8e,0x28,0xa2,0x7e,0xaa,0x59,0xd5,0xf5,0x82,0xae,0x93,0xe5,0x29,0x3e,0x96 +,0x95,0xb4,0x1e,0x3a,0x0f,0xe6,0xb0,0xa8,0xc4,0xbc,0x42,0x5f,0xcc,0x30,0xb8,0x80,0x16,0x88,0x01,0x4d,0x4d,0x1e,0x0a,0x99,0x1d,0x75,0x06,0x57,0x2d,0xda,0xb6,0x54 +,0x53,0x0a,0xcd,0xa9,0xb0,0xab,0x8d,0xe2,0xbc,0x15,0xcc,0xff,0x37,0x9c,0xe6,0xd9,0x81,0xa2,0xad,0x31,0x02,0x60,0x31,0x7b,0x60,0x04,0x99,0x86,0x3a,0x9c,0xff,0xf1 +,0x50,0x80,0x33,0x9f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x55,0x18,0x2d,0x11,0x99,0x14,0xd4,0x84,0x92,0xba,0x0a,0xdc,0x7c,0x24,0x76,0xd2,0x57,0x9f,0x39,0xd8,0xc1,0xd5 +,0x84,0xd6,0x51,0xba,0x2e,0x3b,0x79,0xe1,0x60,0x57,0xd2,0x2e,0x52,0xa3,0xc4,0x94,0xb8,0xdd,0x5d,0xdb,0x77,0xd4,0xea,0x5c,0xac,0xe1,0x5d,0x3a,0x6e,0xb7,0x9d,0x89 +,0x5f,0x2d,0x35,0x3e,0xd5,0xe7,0x35,0xee,0xbc,0xbf,0x0d,0x5e,0x84,0xb5,0x16,0xe8,0x89,0x42,0x1e,0x7d,0x53,0x34,0x5f,0xb2,0xaa,0xa2,0xdb,0x11,0x5e,0xe0,0x90,0x44 +,0x68,0xea,0xda,0x87,0x35,0xa8,0x34,0xb8,0x73,0xed,0xc3,0xf0,0xda,0xe7,0x67,0xf8,0xef,0x12,0x0a,0xee,0xaf,0x7a,0xd8,0xaf,0xe0,0xbc,0x9f,0xcf,0xbf,0xf2,0x54,0xf4 +,0x05,0x87,0x55,0xaa,0x5d,0x4b,0x4c,0xb8,0x1f,0x1a,0xc7,0x46,0x57,0x0b,0xf7,0x71,0xdb,0x61,0xb3,0x2c,0xed,0x4b,0xe8,0xe3,0xde,0x5b,0x95,0x91,0xe5,0x47,0x82,0x6b +,0x4a,0x09,0xf3,0xeb,0xb6,0xeb,0x3a,0x1d,0x69,0xe7,0x54,0xd4,0xee,0xba,0x0d,0xaf,0xe7,0x26,0x7f,0xf2,0xc4,0x6d,0x7b,0x17,0xab,0x41,0x9c,0x06,0x38,0x90,0x12,0x98 +,0x89,0x1e,0x47,0x4d,0x45,0x0c,0x26,0x30,0xd8,0xa9,0x42,0x64,0x49,0x94,0x12,0xe4,0x92,0xc4,0xeb,0x5b,0xc2,0xb0,0xe7,0x5d,0x70,0xaa,0xfd,0x8f,0x18,0xff,0x54,0xfc +,0x74,0x10,0xb3,0xc1,0x18,0xbb,0xf3,0x8e,0xfe,0xeb,0x63,0x1f,0x3a,0x28,0xf1,0xbf,0x3f,0x07,0xfe,0xee,0xab,0xa4,0x9b,0x7c,0x65,0xab,0xc7,0xae,0xec,0x50,0x2d,0xdb +,0x1a,0xd4,0x29,0xba,0x0d,0xab,0x31,0x69,0x6d,0x2a,0xa5,0x00,0x82,0xd5,0x29,0x74,0x18,0xb5,0xa9,0xd1,0x36,0x51,0x54,0x70,0x90,0x77,0x8a,0x53,0x62,0x34,0x24,0x30 +,0x37,0x88,0x31,0x1a,0xf0,0x10,0x4d,0xd1,0x12,0xc4,0xb8,0xd5,0xef,0x54,0x36,0x02,0xe8,0x86,0x49,0x0f,0x80,0x24,0xb2,0x0c,0xb4,0x50,0x93,0xc6,0x84,0xce,0x49,0x46 +,0xb2,0xa8,0x52,0x60,0x4c,0xa5,0x4b,0xea,0xdc,0x47,0x4d,0x11,0x9a,0x9d,0xed,0x1f,0x2d,0xe2,0xb7,0x96,0x3e,0xf2,0xaf,0x94,0xd8,0x66,0x42,0x26,0x36,0xef,0x25,0xbe +,0x67,0xe4,0x2b,0x51,0xc7,0x97,0x8c,0xf9,0xf7,0x08,0x98,0x65,0x96,0xaf,0xc5,0x19,0xb6,0x55,0xf7,0x1e,0x07,0x58,0xca,0x4b,0xad,0x79,0xdf,0xc7,0x19,0xb8,0x4f,0x09 +,0xa2,0xa8,0x03,0x45,0xaf,0x8f,0x86,0x9f,0xbf,0x86,0x72,0xa1,0xa3,0x53,0xb5,0x21,0xdc,0xa1,0xd2,0xaa,0x76,0x23,0x08,0xc1,0x13,0x80,0xff,0xf1,0x50,0x80,0x31,0x1f +,0xfc,0x21,0x6a,0xcf,0xdf,0xff,0xbf,0xff,0xfe,0xb3,0x61,0x40,0x58,0x48,0x16,0x12,0x85,0x04,0xa1,0x41,0x30,0x90,0x4a,0x14,0x1a,0x89,0x04,0xa1,0x21,0x98,0x44,0x26 +,0x11,0x11,0x84,0x46,0x61,0x11,0x94,0xea,0x6e,0xe6,0x6b,0x77,0x75,0xbd,0x61,0x5a,0xab,0x55,0xe2,0xef,0x38,0xf1,0x5e,0x52,0x71,0xe3,0xe3,0x43,0xcb,0x97,0xd3,0x7f +,0xba,0x57,0xfc,0x9b,0xd7,0x3f,0xd2,0x8b,0x9b,0x6f,0xf7,0xb4,0x17,0xe6,0x3d,0xb5,0xc5,0xf2,0xd6,0x9b,0x81,0x8f,0x13,0xd8,0x6c,0x5c,0xea,0x90,0xce,0x7e,0x9f,0xa1 +,0xea,0x31,0x91,0xf4,0xf6,0xf6,0x1e,0x6e,0xe2,0x37,0xa3,0x74,0x44,0xd0,0x03,0xf2,0xac,0x38,0xfd,0xe4,0x6e,0xfb,0xf3,0x77,0x69,0xdf,0xb7,0x2c,0x3e,0x8a,0x9a,0x83 +,0x42,0xed,0xa3,0xf6,0x62,0x60,0x6e,0x57,0x2b,0x9a,0x4f,0x8b,0xad,0x75,0xf6,0xa2,0x90,0x8e,0xde,0xa1,0x18,0x9c,0x2c,0xa2,0x62,0x9d,0x9b,0x64,0xbb,0xc2,0xb1,0x59 +,0xb1,0xfb,0x24,0x28,0xb9,0xdc,0xde,0x4b,0x34,0x2d,0xdc,0xde,0x8c,0x37,0x66,0xfb,0x50,0x3d,0xdc,0x94,0x59,0xbc,0x46,0xd1,0xb0,0x5d,0xa9,0xb5,0x30,0x1d,0xf8,0x33 +,0x40,0x0a,0x02,0x60,0x2a,0x19,0x28,0x16,0x22,0x05,0x86,0xe1,0x80,0xb0,0xdc,0x2a,0x17,0x0a,0x84,0xc2,0xa3,0x32,0x08,0x4c,0x62,0x13,0x08,0x89,0xbb,0x9c,0xe7,0x17 +,0xbb,0x55,0xe2,0xae,0xaf,0x1a,0xaf,0x3d,0xe8,0xe3,0xb9,0x25,0x4f,0x3e,0x26,0x79,0xde,0xbc,0x8e,0x0f,0xbb,0xc3,0x8f,0x3b,0x7f,0xcf,0x84,0xbf,0x0e,0xb7,0xf0,0xdd +,0x5f,0xaa,0x6f,0xd0,0xcd,0xd1,0xd3,0x69,0x9f,0xd5,0x68,0xe7,0x77,0x56,0x77,0x27,0xdc,0x79,0x17,0x63,0x57,0x46,0x27,0x46,0xee,0xff,0xa6,0x30,0x74,0x21,0xe2,0x6b +,0x69,0x2e,0x4e,0x68,0x59,0x7b,0x8e,0x34,0x51,0x7d,0x14,0xd2,0x09,0xac,0x15,0xbb,0xe9,0xa8,0x00,0x4a,0xc9,0x4a,0xea,0x95,0xd9,0x77,0x7f,0x09,0xbc,0x2b,0x8d,0x01 +,0xbd,0x3b,0x7c,0x83,0xc4,0x07,0x98,0xfd,0x8f,0x5c,0x77,0x02,0x8b,0x9f,0x10,0x22,0x20,0x84,0x72,0x38,0xf0,0x24,0xf3,0x02,0x07,0x97,0xb8,0x77,0x5f,0xa8,0x0f,0x71 +,0xeb,0xc0,0x77,0x1e,0xe7,0xe5,0x85,0xbd,0x6f,0x58,0x08,0x07,0x2a,0x84,0xbd,0x71,0xeb,0x43,0xd7,0x88,0x83,0x6d,0xe0,0x28,0x0b,0xa5,0xeb,0x6c,0x13,0x05,0x42,0x0e +,0x80,0x70,0xff,0xf1,0x50,0x80,0x31,0xff,0xfc,0x21,0x0a,0xcf,0xf7,0xfb,0xff,0xff,0xfe,0xb3,0x82,0x30,0x90,0x2c,0x24,0x0b,0x85,0x44,0x81,0x50,0xb0,0x50,0x2e,0x16 +,0x0a,0x0d,0x42,0x81,0x51,0x20,0x4c,0x24,0x13,0x11,0x04,0xc2,0x22,0x30,0xa8,0x84,0xa8,0xad,0x4a,0xf3,0xe3,0xce,0x65,0xde,0xde,0xde,0xa2,0x61,0x6a,0xd6,0xf8,0x9b +,0xbc,0xab,0xf8,0x6e,0x9f,0x1e,0xc3,0x92,0xdf,0x1e,0xaf,0xb5,0x2b,0x60,0xad,0x10,0x5e,0x8f,0xde,0xf3,0x8f,0x49,0x7f,0xb3,0xb7,0x36,0x72,0xd3,0xe1,0xef,0x8d,0x39 +,0xb6,0x92,0xf6,0x4d,0x36,0x8d,0xe3,0xd5,0xef,0x3e,0x93,0x4c,0x66,0xb0,0xbe,0xb0,0x2d,0x33,0x5c,0x6e,0xf0,0x06,0xbf,0x50,0xac,0x81,0xf8,0xfb,0x18,0x23,0xb5,0x8e +,0x35,0xdf,0x89,0xe3,0x18,0x97,0xa7,0x94,0x98,0xaf,0xe0,0x9a,0x86,0x60,0x67,0xf0,0xb0,0x02,0x9b,0xa7,0x47,0xd5,0x1a,0xfe,0x3f,0x82,0x19,0x54,0xf5,0x87,0x7c,0x72 +,0x60,0x70,0x1e,0xb1,0x5d,0x2a,0x7b,0xa8,0xdf,0xa3,0xa5,0x80,0x8c,0x85,0x76,0x82,0xb7,0xef,0xd8,0x57,0xf8,0xec,0x76,0x9e,0x2a,0x45,0x68,0xc5,0x9f,0xbc,0x1a,0x9e +,0x40,0x00,0x1e,0x00,0x00,0x04,0x6a,0xcc,0x40,0x42,0x8e,0x25,0xa0,0x01,0x25,0xc0,0x54,0x30,0xe0,0x2c,0x28,0x0b,0x15,0x04,0xc1,0x40,0xc0,0x58,0xaa,0x37,0x08,0x85 +,0x42,0x21,0x70,0x98,0x54,0x46,0x15,0x10,0x88,0xc6,0x22,0x62,0x66,0x9c,0xff,0xcf,0xf1,0xba,0xd2,0xa8,0x8a,0xe3,0x72,0x79,0xd7,0x3f,0x1e,0x39,0xaa,0x75,0x5e,0xd5 +,0xcc,0x7b,0x50,0xdb,0x76,0xfd,0x78,0xfe,0xbb,0xed,0xfc,0x31,0xe5,0x70,0x7c,0x79,0xf9,0xbf,0x97,0x7d,0xfd,0x2e,0xb6,0xae,0xe8,0x0d,0xff,0x6c,0xd8,0xff,0x63,0xe5 +,0x73,0xa6,0xdb,0x7f,0xfe,0x68,0x23,0xbd,0xde,0x6b,0xfb,0xaa,0x4c,0xaa,0x92,0xb0,0xd1,0x45,0x1a,0x25,0xf4,0x4f,0x34,0xe3,0x68,0xae,0xf1,0xc0,0x39,0xd2,0x62,0x49 +,0x6f,0x1e,0xd7,0xdf,0xc0,0xe0,0xe4,0x79,0xf9,0x8f,0xbf,0xac,0xe4,0x79,0x38,0x00,0x3b,0xf8,0xc9,0x82,0x25,0xf0,0x87,0xaf,0x88,0xe4,0x14,0xea,0x50,0x78,0x7b,0x00 +,0xb0,0x1e,0xe7,0xb2,0x1d,0xcb,0x7c,0xc0,0x77,0xf8,0x88,0xe6,0xc5,0x81,0xc4,0xe4,0x22,0xa3,0xff,0xbc,0xff,0xdc,0x80,0xf2,0x79,0x80,0x03,0x80,0x00,0xf3,0xca,0x00 +,0x18,0x00,0xf5,0xaf,0x1c,0x5e,0xec,0x49,0xa2,0xef,0xde,0xa0,0x26,0x11,0xcb,0x88,0x0e,0xff,0xf1,0x50,0x80,0x31,0xff,0xfc,0x21,0x0a,0xcf,0xcf,0xd3,0xff,0x7f,0xfe +,0xaf,0x81,0xb0,0x60,0x26,0x14,0x0b,0x04,0xc2,0x81,0x61,0x20,0x9c,0x2c,0x44,0x0a,0x85,0x82,0x85,0x30,0xa8,0x4c,0x2a,0x13,0x0a,0x84,0xc2,0x41,0x12,0x98,0x44,0x4c +,0xab,0xd4,0xae,0x3b,0xb9,0xb9,0x15,0x2a,0x4d,0x65,0x54,0x95,0xa8,0xae,0x37,0x39,0x5a,0xeb,0xcf,0xfb,0xfc,0x0b,0x2d,0x5e,0x8a,0x2f,0x72,0x3c,0xfe,0xd9,0xe7,0xfc +,0xc6,0xb0,0x2e,0x7f,0xa3,0xe6,0xa7,0xb1,0xc7,0x89,0x1f,0x6e,0xf1,0xb5,0x6e,0x5a,0x2b,0xb9,0xce,0x6f,0xdf,0x75,0xc1,0xc9,0x61,0x69,0x91,0xdd,0xf9,0x96,0x8c,0xe6 +,0x11,0xf5,0x7e,0xfd,0x49,0xe8,0xd3,0xe1,0xb1,0x8c,0xe1,0x51,0x75,0xcf,0x66,0x5a,0xfe,0x87,0x37,0xf9,0x10,0x5f,0x14,0xa0,0x86,0x6b,0xf3,0x1e,0xe4,0xf6,0x48,0x29 +,0xd7,0x91,0x1a,0x31,0x1a,0x61,0x6f,0xd2,0x4e,0x96,0xf4,0x2e,0x4b,0x3a,0x64,0x24,0xd3,0xee,0x1d,0xd2,0xaa,0xa6,0x82,0x2c,0xe6,0x87,0x94,0x07,0xb8,0x1c,0x9c,0x43 +,0x92,0xa0,0x77,0xd3,0x85,0xee,0x87,0x32,0x13,0x6c,0x5b,0x74,0xad,0x5f,0xc6,0x2a,0xcd,0xdb,0x12,0x86,0xba,0x92,0x49,0x6d,0x8d,0xd0,0x13,0x14,0x8d,0x9d,0xfd,0x1e +,0xe8,0x0b,0x82,0x20,0x2a,0x98,0x90,0x27,0x0c,0x05,0x82,0x81,0x61,0x20,0x58,0x28,0x38,0x0b,0x05,0xc2,0xc2,0x50,0xa0,0x94,0x22,0x15,0x13,0x85,0x44,0x21,0x30,0x8a +,0x57,0x9b,0xd6,0x57,0xeb,0xf6,0xf3,0xca,0xf9,0xeb,0xbd,0x6e,0x45,0xcd,0xce,0x3f,0xf2,0xff,0xf0,0xfa,0xad,0xdf,0x1d,0xf9,0x6b,0xeb,0xfd,0x7d,0xbc,0xfb,0x40,0xfc +,0xab,0xd7,0xae,0x9f,0x56,0xfa,0x5d,0xfe,0x61,0x0f,0x8f,0xa3,0x87,0xf0,0x3f,0xbc,0xed,0xa5,0x92,0x6b,0x79,0x7c,0x39,0x56,0xda,0x34,0xff,0xe2,0xfc,0x77,0x38,0xfa +,0xf7,0xd3,0x7e,0xbd,0xcd,0x35,0x5c,0x44,0x29,0x58,0x64,0xac,0x9e,0xbd,0x7b,0x7d,0x2d,0x6f,0x6c,0xa2,0xb6,0xda,0x40,0x08,0x74,0x3f,0xd6,0x11,0xe1,0x3d,0xb1,0xe2 +,0xbe,0x91,0xc3,0xfa,0x17,0x17,0xe0,0x9f,0xe6,0xc4,0xd9,0xe5,0x2e,0x04,0x70,0xe0,0x20,0x18,0xf9,0xbe,0x1f,0x6a,0xe8,0x9f,0x98,0x47,0x90,0x00,0x7a,0xe0,0x00,0x38 +,0xf3,0x6c,0x00,0xe0,0x70,0x00,0x1e,0x49,0xc0,0x22,0x0e,0xff,0x73,0xd7,0x1e,0x20,0x10,0x0b,0xe1,0x00,0x02,0xb5,0x52,0x8b,0x24,0x4c,0x81,0x30,0x02,0x21,0x40,0x1c +,0xff,0xf1,0x50,0x80,0x32,0x7f,0xfc,0x21,0x0a,0xcf,0xf6,0x7b,0x7f,0xe7,0xfe,0xaf,0x80,0xb0,0x60,0x2c,0x64,0x0b,0x05,0x02,0xc4,0x40,0xb0,0x54,0x2c,0x14,0x3a,0x88 +,0xc2,0xa2,0x30,0x88,0x48,0x42,0x13,0x08,0x88,0xc2,0x22,0x55,0x4f,0x3c,0xcb,0xe6,0xf8,0xe5,0x6a,0x93,0x22,0x55,0x5c,0xcd,0x26,0xb8,0xf1,0x95,0x26,0xa9,0xaf,0xff +,0x87,0x60,0x1c,0x9f,0xf3,0xf7,0xdc,0x83,0xe7,0xe4,0xfb,0x8c,0x9d,0xde,0x95,0xc3,0xaf,0xd6,0x9f,0x2b,0x2e,0x68,0x5a,0xa3,0x54,0xe8,0x7a,0x68,0x9a,0xe5,0xe7,0xf2 +,0xa0,0x86,0xd3,0xe4,0x7f,0x28,0xed,0xcb,0xd3,0x10,0x8b,0xe5,0x0f,0x05,0xae,0xe5,0xb8,0xe6,0xe3,0x3e,0x0f,0x38,0xcf,0x87,0xfa,0x74,0x1f,0x94,0x4f,0x73,0xfc,0xdc +,0xb1,0x2d,0x1e,0x85,0xe9,0xcb,0xad,0x13,0x14,0xc3,0x8f,0xad,0xf8,0x0f,0xde,0x34,0x73,0x91,0x8f,0xab,0xe7,0xd7,0x55,0x57,0x65,0xd9,0xf1,0xa2,0xa0,0x88,0xac,0x2d +,0x52,0xe3,0xf0,0xbd,0x42,0x17,0x4d,0xcc,0x72,0x38,0xb8,0x80,0x07,0x90,0x00,0x58,0x52,0x5f,0xe6,0x56,0x51,0x53,0x5e,0xf7,0xe0,0xb4,0xac,0xc9,0xfd,0xcc,0x14,0x88 +,0x89,0x00,0x9e,0x86,0x75,0xa0,0xe8,0xf7,0x81,0x6a,0x99,0x02,0xfb,0x57,0x28,0xb5,0x3b,0xaa,0xa2,0x20,0x01,0x40,0x2a,0x58,0x70,0x16,0x0a,0x89,0x02,0xc1,0x80,0xb0 +,0x60,0x2c,0x14,0x0b,0x0d,0x04,0xc2,0x40,0xb0,0x90,0x26,0x11,0x12,0x84,0xc2,0xe1,0x50,0x88,0xd4,0x22,0x23,0x08,0x90,0x9c,0xcd,0x54,0xaf,0xc7,0xf1,0x7d,0x57,0x32 +,0xad,0xbd,0x11,0xc7,0xd5,0x7a,0xe3,0x7c,0xff,0x8d,0xdf,0x35,0xe7,0xd7,0xc5,0xff,0xdf,0xec,0x07,0xde,0x5e,0xed,0x18,0xe8,0x91,0x4f,0x8f,0xf9,0x3e,0x8f,0xea,0xfc +,0x18,0x7a,0x1f,0x4e,0x8f,0xa3,0xc0,0x16,0xbd,0x36,0x76,0xd7,0xd3,0x7c,0x5f,0xb6,0xe3,0x7d,0xa4,0x59,0x6c,0xdd,0x20,0x7f,0x68,0x4f,0xd9,0x7a,0x7f,0xf9,0xdf,0xf1 +,0xba,0x6b,0xfd,0xdc,0x5e,0xc1,0x5f,0x3a,0xde,0x0d,0xd5,0xf3,0x5d,0x48,0x15,0x9f,0xef,0x0c,0x28,0x20,0xaf,0x59,0xde,0x51,0xa3,0xf6,0xa2,0x2d,0x5f,0x31,0xee,0x9f +,0xf0,0x7b,0xa0,0xdb,0xf2,0x78,0x7c,0x41,0xe5,0xe6,0x07,0x10,0x5f,0xdc,0x8d,0x92,0x72,0xc7,0x74,0x80,0x02,0x79,0x2f,0x9a,0x38,0x10,0xa0,0xcc,0x00,0x11,0xb8,0x1b +,0x60,0x07,0x88,0x02,0x20,0x80,0x05,0x1e,0xef,0xbd,0x0b,0x5d,0x30,0x13,0x10,0x05,0x45,0xe6,0x07,0xff,0xf1,0x50,0x80,0x2e,0x7f,0xfc,0x21,0x0a,0xcf,0xbf,0xef,0xf7 +,0xff,0xfd,0xb2,0x80,0xb0,0xa0,0x2e,0x16,0x12,0x05,0x82,0x82,0x50,0xb0,0x54,0x2e,0x24,0x0b,0x05,0x02,0xa2,0x41,0x90,0xcc,0x22,0x23,0x08,0x90,0xc2,0x27,0x71,0xdb +,0xdb,0x2f,0x95,0xdc,0xa9,0x95,0xad,0xce,0x36,0x95,0x22,0xe6,0x79,0xde,0x4b,0xe3,0x2a,0xa3,0xf1,0xd0,0x1e,0xa7,0x47,0xdf,0xc9,0xfd,0xb7,0xbb,0xfc,0x14,0x68,0xf6 +,0xa7,0xee,0x7d,0x45,0xa8,0x7e,0x5b,0x2f,0x7a,0x7c,0xe5,0x0d,0xb7,0xfd,0x2e,0x4f,0x24,0x2b,0xb3,0x34,0xfa,0x34,0xbe,0x50,0x16,0x5a,0x35,0x27,0xc0,0xb2,0x7b,0x13 +,0x57,0xd8,0xd7,0x05,0x88,0x2a,0xc7,0x05,0x8d,0x22,0x9b,0x4f,0x2d,0x26,0x60,0xf6,0xa7,0xeb,0x45,0x39,0x71,0x64,0x4c,0xd1,0x42,0xbf,0xe7,0x19,0xd6,0xd3,0xdb,0x70 +,0x6b,0x5b,0x94,0xdc,0xcb,0x7b,0x35,0xf5,0x18,0x18,0x3c,0x5e,0xb3,0x02,0x40,0xbc,0x3e,0xc8,0x55,0x2a,0x19,0x68,0xca,0x9a,0x51,0x8a,0xe5,0x89,0xcc,0x0f,0x6e,0x30 +,0xd0,0x39,0x02,0x85,0x62,0x1d,0x03,0xb4,0x2c,0x5e,0xd6,0x90,0xa8,0x0a,0x00,0xa9,0x61,0xc0,0x58,0x4e,0x16,0x12,0x05,0x83,0x01,0x40,0xb1,0xd4,0x4c,0x14,0x12,0x85 +,0xc2,0x61,0x11,0x19,0x14,0x46,0x31,0x21,0x37,0x5c,0x67,0x5e,0x3c,0xe5,0x54,0x15,0x93,0x46,0x5f,0x98,0xdf,0xeb,0xf3,0x5a,0x4e,0x1b,0x6d,0xfb,0xd8,0x3e,0x43,0xe3 +,0xb3,0xfd,0xd1,0xb3,0x9f,0x8f,0xd6,0xc7,0x8b,0xb3,0xb3,0xe2,0x9f,0xb9,0xd7,0x74,0x38,0x46,0x6d,0x7e,0x96,0xfa,0xbe,0x90,0xa6,0xf2,0x97,0xf4,0x44,0xdd,0x95,0x1d +,0x27,0xf7,0xef,0xff,0x4e,0x89,0x65,0xa3,0x7c,0x75,0x02,0x95,0x5f,0x1e,0x7c,0xca,0x5f,0x77,0xd5,0xcd,0xe0,0xe9,0xeb,0xe2,0x90,0x55,0x77,0x39,0xaf,0x0b,0x7c,0x9f +,0x91,0xf6,0xd9,0x6e,0x3b,0x32,0xbf,0x2f,0x41,0x2b,0x89,0xe2,0x2c,0x00,0x1e,0x63,0xbc,0xe2,0xf7,0x0e,0x4a,0x72,0xe1,0xa9,0xae,0x80,0x8f,0xac,0xf4,0x6e,0xf8,0x34 +,0x12,0x47,0xfa,0x8b,0xff,0x80,0x1f,0xcb,0x1f,0xe3,0x1d,0xce,0x60,0x03,0x8b,0x98,0x00,0x3c,0x80,0x77,0x1e,0xb3,0xb8,0x05,0x3d,0xbf,0xb8,0x01,0xb2,0xc7,0x66,0x74 +,0x8a,0x80,0x99,0x69,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2f,0x5f,0xfc,0x21,0x0a,0xcf,0xee,0xf7,0xff,0xff,0xfe,0xb1,0x70,0xb0,0xa0,0x34,0x14,0x13,0x09,0x02,0xc3,0x40 +,0xb0,0x94,0x28,0x16,0x0a,0x05,0x82,0x83,0x21,0x88,0x8c,0xa2,0x13,0x08,0x9c,0xca,0xf3,0xbf,0x8c,0xee,0xfc,0xf7,0x17,0xdf,0xb7,0x88,0xd5,0x25,0x5d,0x55,0xf9,0xe2 +,0xbb,0x9b,0xe3,0x32,0x2f,0xf9,0xe8,0x5f,0xae,0x9f,0x79,0x3f,0xe1,0x5e,0x46,0xa0,0x07,0xd7,0xb4,0xe3,0xfb,0xfa,0x2e,0x81,0xd2,0x84,0x33,0x19,0x70,0xd8,0x77,0x57 +,0xa2,0xbb,0xcc,0x87,0x0e,0x5e,0x79,0xe9,0x49,0xf8,0x1f,0x6b,0x57,0x50,0x47,0xd8,0x83,0x6e,0xaa,0xd2,0xb2,0x18,0x6e,0x46,0x63,0x1e,0xbb,0xe3,0xf5,0xf7,0x65,0x52 +,0xed,0x7b,0xf9,0x52,0xf9,0x36,0xaf,0x6a,0x8e,0xf2,0xda,0xce,0x65,0x1f,0x0e,0x37,0x84,0x3d,0xad,0x3e,0xdd,0x55,0x8d,0xfe,0x9a,0x52,0xaf,0x78,0x0e,0xef,0x7b,0xbe +,0x07,0xac,0x01,0x01,0xde,0x43,0xdc,0x40,0x9d,0x08,0xa9,0x17,0x40,0xf5,0xcd,0x01,0x0b,0x6c,0x69,0x80,0x2f,0x78,0x56,0x7d,0xd7,0x10,0xba,0x89,0xde,0x5d,0x49,0x40 +,0x11,0x05,0x00,0x54,0xa0,0x58,0x8e,0x18,0x0b,0x05,0x45,0x01,0x61,0x20,0x58,0x70,0x14,0x0c,0x05,0x04,0xc2,0x41,0x38,0x4c,0x2a,0x23,0x0a,0x84,0x42,0xa1,0x30,0xa8 +,0x44,0x46,0x11,0x09,0x84,0x44,0xda,0xea,0x6f,0xeb,0xc7,0xeb,0xfb,0x6a,0xa3,0x35,0xbb,0x10,0xe2,0xb8,0xce,0xb1,0xd3,0x9d,0x79,0xaf,0x1c,0x6f,0xd8,0x3f,0xfb,0xea +,0xb2,0x8f,0x9f,0x57,0xcf,0xf9,0x3e,0xd4,0x4e,0xad,0xbd,0xff,0xe5,0xc9,0xa2,0x4d,0x90,0xe9,0x16,0xd7,0x89,0xeb,0xbc,0xff,0xc7,0xb7,0x5b,0x79,0x6e,0xee,0xb0,0xb7 +,0xb5,0x0d,0xfa,0xc6,0xbe,0x40,0x07,0xbb,0x7f,0x6b,0xee,0x83,0x4b,0x38,0xe2,0x0f,0x57,0xcb,0x77,0x08,0x75,0x86,0xef,0xa6,0x73,0x3d,0x4c,0x30,0xe1,0x60,0x2a,0x0a +,0xbb,0x3f,0x67,0xbf,0xae,0xa8,0x18,0x25,0xe3,0x6f,0xf9,0xfb,0x76,0x17,0xd8,0x22,0xcd,0xfd,0x9c,0x43,0xbd,0x47,0xb8,0x57,0x91,0xca,0x11,0xce,0x81,0xe4,0x00,0x07 +,0x7b,0xbc,0x03,0x80,0x00,0x79,0x23,0x00,0x58,0x3c,0x40,0x03,0xbc,0x3b,0x80,0x00,0x79,0x00,0x37,0xa6,0x05,0x00,0x77,0x40,0xb9,0xeb,0x80,0x58,0xb9,0x7a,0x81,0xc0 +,0xff,0xf1,0x50,0x80,0x2d,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0x7f,0xbf,0xff,0xff,0xb1,0x70,0xb0,0x60,0x52,0x14,0x13,0x09,0x02,0xc1,0x40,0xb0,0x50,0x2c,0x14,0x13,0x05 +,0x0a,0x42,0x40,0x98,0x48,0x22,0xf6,0x6b,0x33,0xcd,0x6b,0xbf,0x35,0x57,0x8c,0xd5,0x0b,0x65,0xe8,0x2e,0xae,0x65,0x6a,0x52,0x7d,0x74,0x27,0xd7,0xdb,0xec,0x7b,0xbf +,0x3b,0xea,0xf6,0x8b,0xfc,0xe7,0xef,0x26,0xe7,0xa9,0x75,0x62,0xd2,0x1c,0xc1,0x38,0x8a,0xbf,0x04,0x37,0xbf,0x6a,0xa1,0x54,0xce,0xba,0xbd,0xfa,0x3d,0x70,0xa2,0x34 +,0x09,0xfc,0x8a,0x11,0xd7,0xb4,0xe5,0x71,0xdf,0xef,0xbd,0x50,0xd7,0xc5,0xb9,0xce,0x83,0xb8,0xab,0xb9,0x72,0x5b,0x51,0xce,0xf8,0xfd,0x71,0x25,0xe3,0x35,0x5c,0x3a +,0x85,0x67,0xef,0xe1,0x4b,0x00,0x9b,0x59,0x61,0x5a,0x0a,0x46,0x7b,0xd4,0x2b,0x3a,0xf1,0x6d,0x88,0x8c,0x95,0x98,0x2c,0x3e,0x83,0x14,0xa6,0x06,0xea,0x10,0x99,0xa2 +,0xa0,0x0d,0x50,0x80,0x30,0x82,0x64,0xc5,0xc5,0xcb,0xa0,0x16,0x01,0x60,0x29,0xd8,0x88,0x16,0x1a,0x85,0x02,0xc1,0x80,0xb2,0x10,0x4a,0x17,0x0a,0x09,0x42,0x61,0x50 +,0x98,0x84,0x26,0x11,0x19,0x88,0x4a,0xcd,0xf1,0x9a,0xe7,0xcf,0x31,0xcf,0x14,0xba,0xa8,0xcb,0x97,0x52,0x79,0xe7,0x8e,0x7c,0xef,0x29,0xec,0xdd,0x4e,0x3a,0x1c,0x6d +,0xf7,0xe7,0xc7,0x75,0x3b,0xbf,0x94,0xdd,0x6a,0x79,0x75,0x72,0xfb,0x1a,0x83,0xaa,0xa1,0xbf,0xbc,0x61,0x67,0xcb,0x7e,0xe9,0x2a,0xe5,0x55,0x9d,0xb2,0x44,0xfe,0x9b +,0xd2,0x5e,0xcf,0x33,0x41,0xfb,0x39,0x2d,0x39,0xdd,0x4a,0xcc,0x9a,0x47,0x5e,0xda,0xa7,0x2d,0x05,0xf6,0xaf,0xfc,0x7f,0x01,0xee,0x7e,0xcf,0x91,0x3c,0x39,0x7b,0xb9 +,0xaa,0x7a,0x4d,0xab,0xa7,0x23,0xd4,0xfc,0x2f,0xad,0xfc,0x2b,0x77,0x61,0xdc,0x21,0xfa,0xae,0x39,0x1c,0x29,0xc2,0x09,0xed,0x7c,0x30,0x77,0xd3,0x4e,0xa2,0xf9,0x90 +,0x1d,0xdf,0x5b,0xba,0x2f,0xb2,0x9e,0xdf,0xba,0x84,0x60,0xa8,0xb7,0xae,0xcc,0x5a,0xe8,0x2b,0x2a,0x12,0x33,0xc6,0x92,0x8c,0xa2,0x9a,0x17,0x60,0x03,0xd7,0x77,0x40 +,0x17,0x54,0x8d,0xc2,0xca,0x6e,0x12,0x90,0x5a,0x01,0x39,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2f,0xdf,0xfc,0x21,0x0a,0xcf,0xdf,0x7f,0x7f,0xff,0xff,0xaf,0x40,0xb0,0xe8 +,0x2a,0x14,0x0b,0x05,0x06,0xc1,0x40,0x90,0x58,0x48,0x36,0x0a,0x1c,0x44,0x61,0x11,0x18,0x44,0x66,0x11,0x09,0x84,0x48,0xe6,0xa6,0xff,0xc7,0xda,0xfe,0x3c,0x37,0xd5 +,0x65,0x75,0x95,0x56,0x24,0x45,0xe4,0xe3,0xba,0x7c,0x6e,0x33,0xf1,0x63,0xe5,0xb4,0x75,0xe1,0xf9,0xf8,0xd7,0xa8,0x02,0xf9,0xff,0x9d,0x36,0xf0,0xfd,0x97,0x9a,0x01 +,0xc6,0xe4,0xa3,0xeb,0xc7,0x37,0xfd,0xb9,0x89,0x9d,0x3a,0x0c,0x05,0x79,0x3e,0x57,0x66,0x93,0xfa,0xd0,0x93,0x21,0xad,0xde,0xa6,0xef,0xab,0x8a,0xe9,0xaa,0x18,0xbb +,0xe4,0x8f,0xa9,0x65,0x06,0x8c,0xab,0xe0,0x12,0x67,0xee,0x28,0xf5,0xfc,0xe9,0xf1,0x7a,0x97,0xd4,0xf0,0xf6,0x33,0x58,0xe9,0x5c,0xd3,0x42,0x10,0xc3,0x54,0x90,0xf3 +,0x09,0x4d,0x2a,0xdf,0xb0,0x95,0x24,0x74,0xac,0x92,0x98,0xee,0x0f,0xe4,0x0b,0x69,0x85,0x42,0x5c,0x67,0xcb,0x44,0xd6,0x9d,0x71,0x22,0x07,0xb8,0x04,0xad,0x64,0x3d +,0x68,0x84,0x80,0xd3,0x3d,0x40,0x0b,0x5c,0x44,0x05,0x3b,0x12,0x04,0xc2,0x70,0xa0,0x58,0x4a,0x24,0x0b,0x19,0x08,0xa1,0x40,0xa8,0xcc,0x2a,0x11,0x11,0x88,0x42,0x61 +,0x10,0x98,0x84,0x4a,0xc6,0xb2,0xbf,0xdf,0xfb,0xda,0x93,0x17,0x54,0x90,0x70,0x3c,0xee,0xba,0xcc,0x71,0x9a,0xdc,0xbf,0xa1,0xc3,0x65,0x7e,0x3a,0x3d,0xf9,0xfe,0x91 +,0xd0,0x74,0x4c,0xbe,0xdd,0x1d,0x9e,0x0b,0xfd,0xbf,0x08,0x19,0xe4,0x97,0xb5,0xb8,0x79,0x38,0x78,0x79,0xb8,0x7d,0x4b,0xf7,0x7f,0xa9,0xac,0xb2,0x6e,0x16,0x85,0xf2 +,0x3f,0xc2,0xf5,0xa3,0x23,0xa3,0x95,0xa1,0xbb,0x2e,0xa9,0x33,0x9e,0xeb,0xb4,0xb9,0x7f,0x2b,0xf1,0xaf,0xda,0xdb,0x7f,0xd7,0xfb,0xde,0x83,0xb8,0xff,0xd1,0xa8,0x85 +,0x6a,0x8e,0x7d,0xf5,0x04,0x03,0x7f,0x39,0x21,0x5f,0x27,0x23,0xc7,0x3e,0xa6,0xbe,0x5e,0xdf,0xf2,0xe1,0xc1,0x4d,0xae,0x26,0xcd,0x5b,0x91,0xc8,0xe5,0x43,0xc4,0x1b +,0xad,0x00,0x07,0xe5,0xbb,0xee,0x40,0xe5,0xa0,0x71,0x05,0x61,0xcb,0x74,0x88,0x4a,0x87,0xfc,0x44,0xec,0xee,0x8b,0xff,0x22,0x20,0x04,0xef,0x30,0xef,0xac,0x8a,0x54 +,0x12,0x03,0xdc,0x89,0xee,0x56,0xa0,0xba,0xe2,0x60,0x70,0xff,0xf1,0x50,0x80,0x32,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xfb,0xfe,0x7f,0xff,0xae,0x60,0xb8,0x58,0x30,0x19 +,0x0b,0x04,0x82,0xa1,0x41,0xa8,0x50,0x2c,0x27,0x0a,0x89,0x02,0xc1,0x42,0xa8,0x8c,0x24,0x13,0x10,0x98,0xc2,0x25,0x77,0x35,0xe3,0xda,0xfa,0xf7,0x9c,0x73,0xad,0xf9 +,0xf5,0x71,0x57,0x55,0x2b,0x45,0x79,0xce,0x57,0x89,0xd6,0xd7,0xf5,0xc0,0x4d,0x9e,0x91,0x87,0xeb,0x77,0xd4,0xf5,0x18,0xd4,0x9f,0xf7,0x86,0xd3,0xd4,0xeb,0xb9,0x33 +,0x2f,0x57,0xf4,0x11,0xdb,0x1e,0xa4,0xba,0xc4,0xee,0xf2,0x6d,0x3e,0xb9,0x5f,0xeb,0xac,0x18,0x49,0x4f,0xfb,0x0c,0x9c,0x10,0xcc,0xf7,0x75,0x7f,0x95,0x4d,0xe2,0xb5 +,0xa4,0xce,0x95,0xaf,0x82,0x3b,0x48,0xfc,0xf7,0x02,0x05,0xbc,0xa0,0x45,0x0e,0xfe,0x10,0xae,0x2e,0x30,0x27,0x08,0x8e,0x2e,0x3c,0x9f,0x7e,0xa6,0x76,0x91,0x5c,0xa7 +,0xc7,0x5e,0x4c,0x77,0xdf,0x5f,0x09,0x9a,0x72,0x63,0x9d,0x27,0x92,0xad,0x24,0x73,0x4a,0x81,0xff,0x16,0x82,0x54,0x27,0x7b,0x71,0x2f,0x78,0xe5,0xfa,0xcb,0x76,0xa8 +,0x50,0x45,0x1f,0x40,0x11,0x61,0xc6,0x29,0x19,0x88,0x27,0x63,0xca,0xa8,0x24,0x04,0x80,0xa8,0x61,0xc0,0x58,0xa8,0x16,0x0b,0x85,0x42,0xc2,0x80,0xa0,0x58,0x28,0x16 +,0x0a,0x85,0x02,0xa2,0x70,0xa0,0x5c,0x42,0x13,0x30,0x85,0x42,0x64,0x11,0x2f,0xc5,0xd7,0xd7,0xcf,0xdf,0xc5,0xef,0x7d,0x66,0xb9,0x80,0xb9,0x37,0x6f,0xae,0xf2,0xea +,0xeb,0xac,0xa4,0xdf,0xd5,0x8a,0xb9,0x6e,0x97,0x8f,0x2e,0xf2,0x1d,0xda,0xb4,0xe1,0x67,0xc3,0xd5,0x26,0xb6,0xfe,0x1f,0xa6,0xa8,0xaf,0xc0,0x87,0x9e,0x7b,0xfc,0x9e +,0xc2,0xbd,0x4b,0x85,0x17,0xea,0x38,0x84,0x6f,0x94,0xf0,0x56,0xe0,0x11,0xfa,0xa3,0xef,0x5c,0x17,0xdc,0x83,0xe1,0xb2,0x8a,0xae,0x87,0xc3,0xbf,0xe0,0xf4,0xbf,0x23 +,0xfd,0x77,0xb3,0xaf,0x8f,0xcb,0xe3,0xc4,0x38,0x38,0x72,0x2b,0xcf,0xe7,0xd6,0x79,0xc2,0x9a,0xaf,0x3f,0xd5,0x0c,0x9f,0xe5,0xf0,0x40,0xe4,0xd6,0x9f,0xa6,0xdc,0xdb +,0xbd,0xc8,0xe5,0xfe,0xa8,0xde,0x12,0xf7,0x7a,0xc3,0xff,0xfc,0x9d,0xf1,0xdf,0x45,0xdf,0x3d,0x9f,0x7e,0xce,0xe7,0xf8,0x41,0xf5,0xc9,0xbf,0x4d,0x7e,0xf8,0xfe,0x7a +,0xb4,0x1e,0xbb,0xff,0x67,0x70,0x12,0xad,0x83,0xcc,0x00,0x03,0xba,0x0e,0xe0,0xee,0x7b,0x80,0xef,0x7a,0xe1,0x07,0xa7,0xc6,0xc2,0x42,0x03,0xb8,0x0e,0xff,0xf1,0x50 +,0x80,0x31,0x3f,0xfc,0x21,0x0a,0xcf,0xfb,0xe7,0xf7,0xff,0xfd,0xb1,0x60,0xc1,0x10,0x2c,0x25,0x1b,0x05,0x42,0xc1,0x70,0xb0,0x50,0x4c,0x14,0x2a,0x84,0x84,0xa2,0x32 +,0x88,0x48,0x22,0x33,0x10,0x89,0x79,0x9d,0x75,0xbd,0x76,0xe2,0xa7,0x31,0xd7,0x72,0xba,0xe5,0x12,0xb5,0xe5,0xcc,0xcb,0xf0,0xbe,0x2b,0xad,0xfe,0xbf,0xa8,0x4f,0x1d +,0x43,0xda,0x8b,0x07,0xfd,0x6f,0x95,0x2f,0x83,0xe9,0x31,0xd7,0xf4,0xbd,0xa7,0x63,0xaf,0x81,0xac,0xfd,0x0e,0xe6,0x95,0x94,0xfc,0x55,0x4f,0x3d,0x28,0x7e,0xc0,0x9f +,0xf6,0x9c,0xd3,0xd2,0x0f,0x29,0x48,0xfe,0x8f,0xd4,0xc1,0xf8,0x75,0xde,0x9b,0x60,0xdd,0xd9,0x0c,0xa5,0x4f,0x6f,0x8f,0x5c,0xd1,0x1d,0xd7,0x76,0xb3,0xb5,0x3d,0x7c +,0x23,0xc2,0xe7,0xf9,0x98,0xe4,0x03,0xd3,0xf7,0x37,0xef,0xa2,0xd1,0xd1,0xc6,0x27,0x88,0x00,0xf3,0xe9,0x00,0x4e,0xce,0xe7,0x7b,0xbb,0xfb,0x31,0x28,0x48,0xf7,0xaf +,0x5f,0xb8,0x95,0x90,0x7a,0xfb,0x61,0x69,0x78,0xbd,0xdf,0x66,0xb4,0xef,0x8f,0xad,0xd5,0x33,0x58,0xe7,0xb0,0x32,0xb5,0xa9,0x8d,0x14,0xf9,0x92,0x46,0xd4,0xc9,0x00 +,0x3c,0x61,0x67,0xef,0xbc,0xf4,0x00,0x2d,0x10,0x14,0xa8,0x17,0x0b,0x06,0x02,0xc2,0x41,0x38,0x54,0x2c,0x84,0x0b,0x11,0x04,0xa1,0x70,0x98,0x44,0x26,0x17,0x1a,0x84 +,0x42,0xe1,0x50,0x98,0x54,0x22,0x45,0x6f,0x2e,0x67,0x9c,0xbd,0xd6,0xbb,0xb4,0xa9,0x51,0x7b,0xd6,0xb5,0xc6,0xbe,0x7c,0xd2,0xaf,0x26,0xfa,0x95,0xf1,0xf8,0x1f,0x57 +,0xbe,0xf3,0xd7,0x76,0x86,0x47,0x86,0x1a,0x69,0xfe,0x8b,0xd1,0x3b,0x33,0xdf,0x70,0xd9,0xf2,0xa9,0xad,0xfe,0xfb,0x68,0xeb,0xa3,0x72,0xe8,0xb7,0x0d,0x37,0xdf,0xfa +,0xfa,0x53,0x77,0x5d,0x50,0xcb,0x13,0x5b,0x27,0xa7,0x9c,0xe9,0x1f,0x88,0xcb,0xe1,0xf1,0x83,0x97,0xe9,0x45,0xd9,0x84,0xb0,0x18,0x3f,0x6d,0x01,0x3c,0x93,0xe5,0xd0 +,0x00,0x43,0x9f,0x72,0x39,0xff,0xe1,0x78,0x5f,0xd9,0x25,0x17,0xb9,0xec,0xe3,0xcc,0x7c,0x60,0x38,0x00,0x57,0x92,0xc7,0xb2,0xe6,0x84,0xc3,0xd8,0x27,0xeb,0x3b,0xbd +,0xf0,0xf3,0x80,0x9b,0x31,0xf2,0x00,0x00,0x3c,0xc0,0x20,0x00,0x49,0xe4,0x07,0x88,0x00,0x0f,0x30,0x00,0x00,0x79,0x1e,0xbb,0x8c,0x7b,0x68,0x01,0xe6,0x00,0x18,0x40 +,0x9d,0xc2,0xe0,0x30,0x80,0xe0,0xff,0xf1,0x50,0x80,0x31,0x5f,0xfc,0x21,0x0a,0xcf,0xfe,0x7f,0xff,0xff,0xf9,0xae,0x70,0xb0,0xa0,0x32,0x14,0x1b,0x05,0x04,0xe1,0x40 +,0xb0,0x9c,0x28,0x35,0x0a,0x0d,0x82,0x81,0x50,0x90,0x54,0x26,0x11,0x0a,0x84,0x82,0x62,0x10,0x90,0x54,0x22,0x66,0xcc,0xea,0xb8,0xcd,0x3b,0x8b,0xcb,0x5e,0x5a,0xaa +,0x4a,0xbd,0x6e,0xf7,0xd3,0xc5,0x7e,0x3c,0x5b,0xe1,0xf4,0x2b,0xd7,0xfb,0xf1,0xf9,0xb5,0x2f,0x5b,0xd4,0xe7,0x47,0x7f,0x0f,0xf7,0x3c,0x47,0x99,0x68,0xe2,0x3e,0xae +,0xdb,0x7a,0xee,0x17,0x61,0xce,0x3e,0xc4,0x13,0xec,0xf6,0x2c,0x17,0xa4,0xeb,0x83,0x3d,0x04,0x60,0xbc,0x96,0x2e,0x32,0xf4,0xb1,0xe8,0xfb,0x70,0xdd,0x80,0xba,0x6f +,0xec,0x1b,0xc8,0x24,0xa8,0x32,0x2b,0xc0,0xcb,0xa8,0xd2,0xc5,0x78,0x1a,0x3d,0x6b,0x75,0xca,0xa3,0x8e,0x97,0x07,0x71,0x43,0x16,0xf2,0xe7,0x9c,0xca,0x82,0xfe,0xd2 +,0xef,0x5c,0xbd,0xaf,0x6a,0x59,0x0e,0xb2,0xb4,0x1d,0xe3,0x81,0x21,0x7c,0xb9,0x6b,0x5b,0x2f,0x7d,0x73,0xdc,0x01,0xc6,0x7b,0xd2,0xd6,0x68,0x72,0xcf,0x49,0x2c,0xd0 +,0xa6,0x82,0x3c,0x80,0x01,0x68,0x50,0x89,0x20,0xb4,0x80,0x9c,0xe4,0x22,0x00,0x95,0xd7,0x01,0x3a,0x82,0x61,0xa0,0x58,0x2a,0x14,0x09,0x85,0x83,0x01,0x61,0xc0,0x50 +,0x2c,0x28,0x0a,0x05,0x82,0x81,0x52,0x38,0x54,0x26,0x15,0x08,0x85,0x42,0x61,0x51,0x08,0x8c,0x42,0x37,0xe6,0x73,0x24,0xb9,0x5c,0xce,0x2b,0x12,0xb5,0x95,0x68,0xe2 +,0xb8,0xac,0xbf,0x8f,0x1c,0xf0,0xf6,0xdf,0x73,0xcc,0xe0,0x77,0x3f,0x9d,0xf5,0x55,0xfc,0xdf,0xe1,0x9f,0xf5,0x68,0xfd,0x3d,0xff,0xfc,0xff,0x59,0xbb,0xcb,0x8d,0x11 +,0x42,0x9e,0xea,0xfe,0x24,0xc5,0x6e,0xb2,0xd2,0x13,0xcd,0x77,0xad,0x19,0xf6,0xdf,0xc4,0xf5,0x5d,0x01,0x36,0x1c,0xf9,0xbd,0x41,0xdd,0x33,0x0e,0x86,0xf9,0xe0,0xfc +,0x67,0xe0,0xff,0xd3,0x6c,0x9e,0x0f,0x79,0xd0,0x1c,0xb3,0x9b,0x7a,0x8d,0xf2,0x3f,0x7b,0xe2,0xcb,0x83,0x97,0x18,0x1d,0x7d,0x55,0x47,0x37,0x98,0x38,0x53,0x9b,0x98 +,0xaf,0x20,0x79,0x40,0x07,0x98,0x00,0xe0,0x1e,0xb3,0xb9,0xe2,0xf0,0x1e,0x00,0x03,0x03,0x30,0x0f,0x00,0x80,0x01,0xff,0xfb,0x3d,0xd0,0x03,0xc8,0x3c,0x80,0xf3,0x00 +,0x00,0xad,0xc0,0xb4,0xc2,0x0e,0xf0,0x0f,0xf0,0x82,0x85,0x97,0x2e,0x3b,0x80,0xe0,0xff,0xf1,0x50,0x80,0x30,0xbf,0xfc,0x21,0x0a,0xce,0xe3,0xf7,0x9f,0xff,0xf8,0xac +,0x60,0xc0,0x58,0x30,0x19,0x0a,0x0d,0x44,0x81,0x61,0xa0,0x60,0x28,0x16,0x0a,0x09,0x82,0x61,0x40,0xb0,0x54,0x24,0x15,0x20,0x8c,0xc2,0x29,0x7a,0xf3,0x5e,0x38,0xea +,0x71,0xdc,0xdf,0x5e,0xb5,0xbb,0x8a,0x0b,0x6a,0x71,0x5d,0xd5,0xeb,0xc2,0xf5,0x93,0xee,0xd0,0x6f,0x1a,0x5d,0xff,0xaf,0x7f,0x0b,0xf4,0xfa,0x59,0xd7,0xda,0xfb,0x6b +,0xef,0x78,0x3a,0x81,0xf7,0x90,0xe9,0x92,0xa8,0xe7,0xd1,0x68,0x0d,0x98,0x1b,0x92,0xa3,0x0f,0xfd,0x7d,0xe7,0xb1,0x42,0xe1,0x26,0x21,0xfa,0x56,0xb7,0xc7,0x9d,0x49 +,0x51,0x68,0x04,0x97,0xc8,0x7f,0x12,0xff,0x02,0x5e,0xa2,0x72,0xfc,0x21,0xb3,0x20,0x87,0x48,0xac,0x26,0x23,0xf9,0xa0,0xf8,0xa3,0xf8,0x86,0xde,0x63,0x4a,0x56,0x26 +,0x2f,0x74,0x5f,0x5f,0x10,0xe0,0x27,0xc8,0x00,0xf3,0x00,0x02,0x30,0x38,0xf2,0x4f,0x6d,0x56,0x6d,0xc9,0x96,0xc6,0x5b,0xd6,0x10,0x05,0xe1,0xf6,0xd3,0x94,0xc8,0x5d +,0x2e,0x35,0xbd,0x62,0x67,0x46,0x17,0xa0,0x42,0xf7,0xd1,0x7a,0xcc,0x5e,0x01,0x69,0x4b,0x9d,0xf3,0xa0,0x1c,0x82,0xd6,0x0a,0x81,0x50,0xc1,0x81,0xb0,0x50,0x2c,0x27 +,0x0a,0x09,0x8a,0x81,0x70,0xa0,0x58,0x28,0x25,0x0a,0x05,0x42,0x61,0x50,0x98,0x54,0x22,0x25,0x10,0x84,0xc2,0xa1,0x10,0x98,0xc4,0x6a,0xf1,0xd3,0xcf,0xdb,0xac,0xbd +,0x77,0xa9,0x99,0x72,0xb2,0xcd,0x69,0x57,0xc6,0xbf,0x3f,0x1d,0xfd,0x78,0xe3,0x8e,0xdb,0xf6,0xbd,0x02,0xde,0x2e,0x8d,0x67,0x5f,0xa3,0x67,0xe6,0x4f,0xd7,0x24,0xdb +,0x67,0xe7,0xbc,0x68,0x3f,0x8c,0xd3,0xd2,0x27,0xb0,0xa7,0xdd,0x5f,0xe0,0x6a,0x14,0x4d,0xd7,0x72,0xec,0xac,0x7e,0x89,0xf3,0x9f,0x00,0xad,0x4d,0x82,0x7c,0x5f,0xeb +,0xe1,0xcb,0xd2,0x37,0x59,0xea,0xfe,0xc7,0xf9,0xff,0xd5,0xfd,0x2f,0xfb,0x30,0x3b,0x22,0x6b,0xc1,0xdf,0xf1,0xd7,0x35,0xed,0xd5,0xdd,0x68,0x25,0x8e,0x53,0xfb,0x5d +,0xc7,0x80,0x03,0xa5,0xcd,0xe7,0x98,0x7f,0xfe,0x1e,0xe0,0x1e,0x20,0x05,0x42,0x33,0x9c,0x18,0x14,0xe5,0x39,0x83,0xc4,0x00,0x70,0x05,0x71,0x24,0x90,0x41,0x63,0xd7 +,0x0e,0xe8,0x00,0x0f,0x14,0xc0,0x80,0x7a,0xe1,0xdd,0x0e,0xe0,0x36,0xd3,0xf7,0x54,0x00,0x76,0x08,0x00,0xe0,0xff,0xf1,0x50,0x80,0x30,0x1f,0xfc,0x21,0x0a,0xcf,0xe5 +,0xfe,0x7f,0xff,0xbe,0xb0,0x70,0xc1,0x18,0x48,0x16,0x09,0x05,0x06,0xe1,0x60,0xa0,0xd8,0x28,0x36,0x0a,0x85,0x02,0x41,0x51,0x89,0x14,0x26,0x11,0x43,0x35,0xc7,0xbf +,0x9a,0xeb,0x9d,0x52,0xf9,0xab,0xa9,0x55,0xed,0xcd,0x2a,0xe4,0xf8,0xf4,0xbc,0xfa,0xef,0xbf,0xad,0xd1,0xff,0x95,0x87,0xc7,0x6b,0xa7,0xce,0x8a,0xdf,0x63,0xe9,0x1f +,0x49,0xf1,0x2d,0xbb,0x84,0x7c,0x56,0xfa,0x06,0xf5,0xcb,0xf4,0x51,0x6f,0x57,0x74,0xee,0x63,0x4f,0xe4,0x4b,0x6a,0x3d,0x69,0xbb,0x71,0x3f,0x19,0xd3,0xf4,0x47,0x36 +,0xbd,0xff,0xc3,0xbb,0xf4,0x3b,0x65,0xed,0x4c,0x79,0xb0,0x1f,0xaa,0xc3,0x21,0x74,0x7e,0xb9,0xad,0xee,0x74,0xc6,0x83,0x3a,0x63,0xa0,0xed,0x1c,0x47,0xbe,0xb1,0xf2 +,0x36,0xd4,0x4e,0xa7,0xce,0x61,0x11,0x8c,0x73,0xa2,0x40,0x78,0x80,0x13,0xef,0x1b,0x6f,0xba,0x98,0xa6,0x3b,0xca,0x5d,0xa5,0x04,0xa9,0x27,0x28,0x14,0x2e,0x00,0x07 +,0x98,0x3f,0xf9,0xa3,0x5b,0x5b,0x1b,0xc2,0x88,0x85,0x80,0x74,0x26,0x3a,0xdc,0x27,0xd4,0xa4,0x86,0xe4,0xee,0x02,0xe0,0xa8,0x14,0x68,0x16,0x42,0x85,0x83,0x01,0x62 +,0x20,0x58,0xce,0x15,0x0b,0x85,0x42,0xe1,0x10,0x98,0xd4,0x26,0x25,0x11,0x84,0x4a,0xf7,0x9a,0xc9,0x55,0xae,0xbb,0xa1,0x5a,0xca,0x5a,0xae,0x71,0x5e,0x78,0xfc,0xea +,0xf7,0xfb,0xfe,0x9a,0xc7,0xdf,0x3f,0x13,0xd0,0xe5,0x43,0xfd,0xa7,0xef,0xf5,0xb7,0xae,0x7f,0x0a,0x2e,0xea,0x4f,0x37,0x86,0x9f,0x8b,0x6e,0x5a,0x39,0xe9,0x50,0x5b +,0x16,0x3f,0x64,0x7f,0xe4,0x7c,0xb0,0x2f,0xd2,0xf8,0xa4,0xaf,0xf7,0xcf,0x9e,0x7e,0xfc,0x2c,0xbd,0xf2,0xe1,0x4e,0x76,0xf6,0x07,0x7b,0xee,0xd5,0x7d,0x62,0x51,0xce +,0xcc,0x03,0xb3,0x20,0xaa,0xac,0xc2,0xad,0x38,0x55,0x68,0x0d,0xcd,0x2d,0x6e,0x40,0x6e,0xf5,0x1c,0xde,0x3e,0x0e,0x63,0x83,0x57,0x70,0xb7,0x9c,0x1c,0x40,0xf4,0xf2 +,0xe1,0x07,0x98,0x80,0x0e,0x71,0x98,0x87,0x14,0x2e,0xfb,0x47,0xec,0xdf,0xf9,0x22,0x5d,0xe3,0xbf,0x13,0xbe,0x17,0x9b,0x73,0x03,0x94,0x00,0x7b,0xa1,0xdd,0xee,0x53 +,0xd7,0x00,0x01,0xe6,0x28,0x01,0xe2,0x1f,0xb4,0x7b,0x52,0xb6,0x00,0x50,0xab,0xa8,0x00,0x22,0xb4,0x40,0xe0,0xff,0xf1,0x50,0x80,0x30,0xdf,0xfc,0x21,0x0a,0xcf,0xfc +,0x57,0xfe,0xdf,0x7f,0xad,0x50,0xc1,0x18,0x2a,0x16,0x0a,0x05,0x42,0x81,0x70,0xa0,0x58,0x28,0x16,0x0a,0x09,0x82,0x83,0x60,0xa0,0x54,0x4c,0x13,0x0a,0x84,0xc4,0x28 +,0x31,0x08,0x9e,0x34,0xcf,0x32,0xea,0x6f,0x7d,0x77,0x2b,0xcf,0x27,0x1c,0xa5,0xeb,0x7d,0x4d,0xf1,0xba,0x4a,0xb8,0xf8,0xe7,0xfd,0x38,0x0f,0x68,0xfa,0x7a,0x75,0x5c +,0xfe,0xbe,0x99,0xf8,0x27,0xb0,0x9c,0xf6,0xfe,0x4e,0xaf,0xb0,0xef,0xaf,0x6d,0xef,0x1f,0x26,0xf9,0x3a,0xa6,0xa2,0xdb,0xfd,0xd2,0xba,0x2f,0xb1,0xfb,0x8f,0xde,0x70 +,0x5e,0xab,0xcc,0x1f,0x76,0x56,0x81,0xf1,0x47,0xc7,0xfe,0x1a,0xba,0x8e,0x42,0xee,0xd4,0x8c,0xe4,0x3e,0xde,0x94,0x93,0x3c,0x2f,0x8e,0x73,0x55,0x47,0x7a,0x6d,0xaa +,0x9f,0x19,0x82,0x08,0x05,0xc4,0xc4,0x93,0x94,0xa8,0x7e,0x88,0xb9,0xc9,0xc1,0x6b,0x14,0x32,0xc6,0x9e,0xda,0x29,0xf7,0xb3,0x84,0xe7,0x0d,0xf7,0x4c,0xbc,0xb7,0x38 +,0xa9,0x40,0xdf,0x7a,0x40,0x12,0xb4,0xb0,0x4d,0x0b,0x93,0x38,0x44,0x55,0xc0,0xa9,0x81,0x48,0x44,0x59,0x70,0x7a,0xce,0xe0,0x00,0x80,0xa8,0x0a,0x47,0x0b,0x11,0x42 +,0xc2,0x50,0xb0,0x60,0x4e,0x16,0x2c,0x05,0x82,0x81,0x60,0xa8,0x58,0x4a,0x14,0x0a,0x84,0xc2,0xa1,0x31,0x08,0x8c,0x22,0x87,0x8b,0xca,0xf3,0xcf,0x9f,0x19,0x72,0x6e +,0xf2,0x45,0x5a,0x1a,0xdf,0xb4,0xdd,0xd7,0xc5,0xfd,0xb5,0xe2,0x7c,0x79,0xe3,0x20,0x76,0x36,0x77,0x65,0xfa,0xf3,0x6f,0xcf,0x63,0xc9,0x39,0xe5,0xcb,0xf2,0x7a,0x6c +,0x9d,0x98,0xfb,0x9b,0x0a,0x3d,0xfd,0x57,0x95,0xd2,0x4d,0x4f,0xb4,0x37,0x55,0xcf,0xfa,0x59,0xb2,0xaf,0x1e,0x5f,0x87,0xa7,0x8e,0x10,0xf3,0xda,0xa8,0x1e,0x7a,0xed +,0xd3,0x4f,0x22,0x74,0x80,0xdf,0x0e,0x98,0xe2,0x3c,0x26,0x25,0xe7,0xf2,0xf9,0xa4,0xe1,0x03,0x7b,0x0d,0xc0,0x5a,0xd9,0xcc,0x77,0x8c,0x94,0x1d,0xa1,0x3c,0xdd,0xdc +,0xe7,0xb5,0xc0,0x3e,0xfb,0x43,0xb0,0xe7,0xde,0xe0,0x38,0x03,0xc0,0x1d,0xf7,0x78,0x47,0x80,0x3c,0x40,0x7e,0x58,0x77,0xe5,0xdc,0xf0,0xbc,0xba,0xa5,0x28,0x12,0x44 +,0x2e,0x68,0x48,0xef,0xeb,0x77,0xb2,0xaa,0x50,0x9b,0x86,0x16,0x95,0x69,0x74,0xec,0xaf,0x14,0xa3,0x01,0x51,0x00,0x10,0x00,0x40,0x5c,0x07,0xff,0xf1,0x50,0x80,0x30 +,0x9f,0xfc,0x21,0x2a,0xcf,0xca,0xdb,0x7e,0xff,0xff,0xb0,0x60,0xc0,0x58,0x30,0x26,0x0a,0x85,0x04,0xc1,0x50,0xa0,0x94,0x28,0x16,0x0a,0x05,0x82,0x81,0x60,0xa8,0x4c +,0x2a,0x14,0x1a,0x84,0x46,0x61,0x10,0x98,0x84,0x86,0x11,0x0a,0x84,0x44,0xc8,0x75,0x73,0x9b,0xeb,0xd4,0xc8,0xdf,0xb6,0xf3,0x8a,0x95,0x72,0xaf,0x5b,0xeb,0x24,0xda +,0xd7,0xbf,0x3f,0x5e,0x44,0x79,0x70,0xe7,0x7e,0xfe,0x56,0x7b,0x3f,0x59,0x8d,0x35,0x7c,0x5f,0xec,0xd5,0x1c,0x05,0x5a,0xf5,0xfd,0x83,0x8a,0x78,0xbf,0x08,0xff,0xd6 +,0xaf,0xf1,0x9c,0xe3,0xf5,0x0c,0x9f,0xed,0xfd,0xee,0xf5,0xb8,0xc2,0x6f,0x9f,0x73,0x11,0x81,0x86,0xc2,0xbe,0xef,0x3e,0x8b,0xe4,0x7f,0x87,0xf8,0x17,0xa3,0x87,0x46 +,0x9c,0x0e,0x2b,0x79,0xbb,0x7b,0xa1,0x1e,0xca,0xae,0x2f,0xb0,0x4e,0xf6,0x35,0x7e,0x71,0x52,0x9b,0x69,0xe2,0x63,0xe5,0xde,0xd3,0x62,0xb2,0xf7,0xc8,0xb2,0x36,0xc6 +,0x8f,0x06,0xa8,0x8c,0xfd,0xfe,0x0b,0xb7,0x12,0x58,0x3d,0x78,0x6d,0xc4,0x49,0xeb,0x5c,0x0e,0xde,0x15,0x05,0xf4,0x02,0x49,0x46,0x2d,0xc9,0x8f,0x06,0x60,0x6e,0x88 +,0x29,0xe2,0x00,0x02,0x80,0x20,0x02,0x95,0x83,0x01,0x63,0xa0,0x58,0x88,0x16,0x1a,0x05,0x82,0x84,0x60,0xa8,0x8d,0x02,0x87,0x8c,0xe0,0xdf,0xe3,0xf4,0xf6,0xcd,0xde +,0x5d,0x55,0x91,0x13,0x5b,0xeb,0x38,0x64,0xbd,0xf9,0xed,0xe6,0xe5,0x74,0x13,0x71,0x5a,0x7d,0x9f,0x2f,0xa7,0xb7,0xd2,0x91,0xd2,0x7e,0xbe,0xcf,0x77,0xc3,0x3e,0x8b +,0x6f,0x94,0x23,0xc5,0x73,0x9e,0x63,0xf6,0x27,0x84,0xbc,0x0b,0x50,0xf2,0x6d,0x72,0x9c,0xda,0xa7,0xed,0x2e,0xbb,0xab,0x91,0x23,0xfd,0x3f,0xd7,0xf5,0x6f,0x2d,0x65 +,0x13,0xd5,0xc6,0x74,0xe6,0xf7,0xf6,0x1f,0xbe,0x93,0xdc,0x79,0xcf,0x4f,0x2e,0xa8,0xd6,0x3f,0xeb,0xd8,0xbd,0xbd,0x74,0x22,0x32,0x5e,0x05,0xc2,0x3e,0x75,0x77,0x86 +,0x6c,0x18,0xae,0x4a,0xb9,0xbf,0x35,0x4b,0x27,0xff,0xc1,0x0f,0x07,0x65,0xef,0x6b,0xa4,0x9f,0xdb,0xfb,0x93,0x07,0x7c,0x77,0x67,0xff,0xab,0xf9,0x55,0x6d,0x12,0xbd +,0xc1,0xdd,0xdb,0xee,0x89,0x1e,0xbc,0x57,0x41,0xfb,0x7c,0xae,0xd6,0xac,0x44,0x53,0x54,0xeb,0x14,0xbd,0x6f,0x10,0x94,0x80,0x12,0x40,0x80,0x01,0x50,0x44,0x0e,0xff +,0xf1,0x50,0x80,0x33,0xff,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x44,0x26,0x50,0x58,0xa9,0x44,0x64,0x53,0x44,0xb4,0x49,0xa1,0x47,0x8b,0xdc,0xd0,0x7c,0xde,0x65,0x66,0x87 +,0x39,0x12,0xab,0xff,0x87,0xe3,0xce,0xdb,0xa1,0x24,0x40,0x7a,0x6c,0xf1,0x68,0xd5,0x7d,0x61,0xdf,0xf8,0xb3,0x7d,0x7b,0xb1,0x8b,0xc6,0xca,0x27,0x5d,0xa5,0xea,0x9f +,0x1f,0xfb,0x25,0x7d,0xd4,0x76,0x9c,0xb1,0xaf,0x15,0x92,0x45,0xdf,0x88,0x04,0x80,0xd7,0x00,0x80,0x31,0x81,0x0b,0xd7,0xc9,0xd8,0xdc,0xf0,0x69,0x35,0x08,0xcb,0x34 +,0xd2,0xde,0x67,0x56,0xe3,0x14,0xb8,0x80,0x78,0xc9,0x2e,0x6d,0x18,0x69,0xdb,0x25,0xc2,0xfb,0x21,0x00,0x31,0x11,0xd5,0x7b,0xdf,0xa3,0xd7,0xf5,0x7e,0xec,0xf0,0xb3 +,0x39,0x32,0xbf,0x8c,0x79,0x63,0x27,0x49,0xac,0x3f,0xf3,0xfa,0xcb,0xbd,0xb4,0x5e,0xc8,0xec,0x6e,0x55,0x66,0x2d,0x53,0x60,0xac,0x38,0x0d,0x61,0xa0,0x36,0xde,0x85 +,0xd9,0xf1,0xea,0xa5,0x26,0x05,0xb6,0xab,0xc7,0x73,0x48,0xe0,0xe0,0x87,0xf8,0x78,0xbd,0x5b,0x41,0x14,0x66,0x23,0x99,0x1c,0x11,0xc7,0x18,0xd6,0x1e,0x1d,0x51,0xa4 +,0x00,0x40,0xd8,0x3f,0x11,0xfa,0x0d,0x93,0x39,0x60,0x27,0xe2,0xb2,0x42,0xa5,0x08,0xa2,0x92,0xda,0x2f,0x81,0x26,0x66,0x5d,0x86,0xe6,0x0e,0xea,0xd2,0xb2,0xb7,0x19 +,0x55,0x38,0xa9,0x86,0xcf,0x12,0x0a,0xd8,0xe4,0xd5,0x45,0xa7,0x9e,0x9d,0x45,0x3c,0x34,0xaa,0x76,0xf6,0x90,0x5f,0xc6,0x4a,0xaa,0xd9,0x53,0xa6,0xdd,0x78,0xec,0x25 +,0xcf,0xdb,0x5a,0x3a,0xdf,0x64,0x7e,0xad,0xdf,0x0c,0x82,0x07,0x82,0xfb,0x65,0x8f,0x48,0xd2,0x71,0xed,0x2f,0x46,0x42,0xce,0xa1,0xa5,0x22,0x69,0xe6,0xeb,0x7d,0x33 +,0x38,0x7e,0x2c,0x0b,0xfe,0x9d,0x24,0xce,0x8b,0xb2,0xaf,0x08,0xfa,0x4f,0xaa,0x15,0xba,0xf1,0xb2,0xe9,0x07,0x54,0x61,0x65,0x6d,0x07,0xa0,0x9a,0x2f,0x17,0x0a,0x9e +,0x00,0x03,0xbf,0x2b,0xb3,0xd4,0x16,0x08,0x61,0x83,0x0b,0x6f,0x0e,0xf6,0x56,0xd8,0xe3,0x95,0x7b,0x9d,0xf7,0xe1,0x9a,0x6a,0x53,0x8a,0xbc,0xe5,0x8a,0xda,0x33,0x4a +,0x37,0x16,0xce,0x67,0x56,0xc7,0x0d,0x5b,0x59,0xf8,0xa6,0xaf,0x1e,0x89,0x9a,0xab,0xed,0x3f,0x1f,0x2b,0x6b,0x54,0x6e,0xbe,0x77,0xc9,0x3d,0xd9,0xb3,0xbe,0x94,0xa5 +,0xd3,0x4a,0x67,0x49,0xcd,0x5f,0xba,0xd3,0x69,0xbb,0x86,0x44,0x67,0x9b,0x77,0xf1,0xf2,0xb6,0x44,0xd8,0x3d,0x42,0x70,0x26,0x3c,0x11,0x33,0x40,0xb8,0xe0,0xff,0xf1 +,0x50,0x80,0x34,0xbf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x55,0x18,0x2d,0x50,0x91,0x14,0x65,0x72,0x13,0x52,0xae,0xc6,0x05,0xfc,0xe5,0x9d,0xa5,0x8d,0xb4,0x0d,0x2d,0xf6 +,0xc5,0x55,0x59,0x69,0xf2,0x0b,0x53,0x22,0x94,0x1a,0xc6,0x09,0x3c,0xf9,0xe0,0x79,0x0a,0xdc,0x93,0x28,0xf9,0x43,0xa5,0x50,0x3d,0x75,0x70,0xe3,0xeb,0xf5,0xf0,0xf0 +,0xb7,0x29,0xe4,0x56,0xb6,0xb7,0xa3,0xee,0xdf,0x2a,0x59,0xc7,0x2c,0xaa,0xb6,0x71,0xf6,0x4b,0x7e,0x99,0x11,0x9e,0x8a,0xa9,0xa5,0xaa,0xb3,0x65,0x43,0x10,0x9c,0xdd +,0x6c,0x61,0x2a,0x51,0x36,0xea,0xc4,0x27,0xa4,0xca,0x6a,0xa4,0x9a,0xd7,0x41,0x10,0x58,0x63,0xe1,0x6b,0x26,0x40,0x68,0xd7,0x54,0xb2,0x9c,0x38,0xb4,0x00,0xa7,0xd5 +,0xea,0x0f,0x7f,0x1a,0xad,0x57,0x4b,0x86,0xb8,0x49,0x74,0x93,0x95,0xb3,0xfd,0x04,0x5f,0x21,0x11,0x14,0xf3,0x15,0x7f,0x80,0x71,0x4a,0xdf,0x70,0x68,0xc3,0x96,0xee +,0xe5,0x7e,0x5d,0xd6,0x4f,0x94,0xa7,0xd1,0x7f,0xe3,0x6b,0xc9,0x8e,0x81,0x6d,0x0e,0x03,0x73,0x4d,0x18,0x3a,0x30,0xeb,0xc4,0x54,0x90,0xde,0xd4,0x0d,0xbc,0x24,0x7b +,0xa4,0x60,0x50,0xc4,0x65,0x05,0x8a,0x15,0x28,0x44,0xa1,0x16,0xb2,0xc5,0xde,0x3f,0x01,0x9f,0xf8,0xc5,0xb7,0x99,0x91,0x8b,0x3d,0x2e,0xbf,0x6f,0x0b,0x48,0xb2,0xc6 +,0xce,0x3c,0xed,0x64,0x39,0x7f,0x8c,0x36,0xb2,0x05,0x63,0x71,0x18,0x14,0x62,0x71,0x77,0x97,0x5b,0xb6,0x55,0xd2,0x1a,0xbb,0xf8,0xcd,0x61,0xae,0x1e,0x08,0x24,0xc3 +,0x2e,0xf1,0x30,0x6e,0x98,0xb6,0x66,0x5c,0xba,0x68,0x0c,0xbc,0x26,0xcf,0xc0,0x7e,0x31,0x2c,0xeb,0x59,0x4e,0xf3,0x67,0x81,0xd9,0xbf,0x45,0x31,0xa6,0x25,0x9f,0xae +,0x7f,0x0c,0x39,0x4b,0x29,0x55,0xc6,0x69,0x99,0xd6,0xb9,0x75,0xe2,0x37,0x7d,0x05,0x2c,0x82,0x5c,0x12,0xce,0xb5,0xb0,0x65,0xa8,0x25,0xb8,0x44,0x94,0xa7,0x12,0x4a +,0x96,0xc3,0x80,0x04,0x4d,0x34,0x46,0x91,0xaa,0xad,0x91,0x2c,0x8e,0x40,0x8c,0x14,0x52,0x9c,0x01,0x56,0x8e,0x7b,0x5d,0x40,0x6d,0xe6,0x42,0x75,0xcf,0x92,0xf9,0x40 +,0x95,0x69,0xe5,0x2b,0x9f,0x9a,0x5e,0xb3,0x9c,0xa7,0x2b,0xb2,0xb7,0x96,0x07,0x29,0xc2,0x2f,0x74,0xca,0xbc,0x6a,0x52,0x9c,0xc5,0xbb,0x66,0x36,0x6f,0x51,0x9a,0x66 +,0xdf,0xad,0xdd,0x57,0x2e,0x66,0xca,0xd6,0x55,0xa9,0x69,0x55,0xaa,0xb6,0xf2,0xda,0x5b,0xcb,0xb8,0xbe,0x13,0xf0,0xb9,0xec,0xc6,0x77,0xc8,0x62,0xc6,0x7e,0x19,0x0f +,0x36,0x63,0x80,0xff,0xf1,0x50,0x80,0x32,0x5f,0xfc,0x21,0x6a,0xcf,0xdf,0xff,0xff,0xff,0xfd,0xb5,0x61,0xc0,0x58,0x26,0x15,0x0a,0x06,0x02,0xc1,0x40,0xb0,0x50,0x2c +,0x35,0x0b,0x05,0x04,0xa1,0x41,0x10,0x50,0x84,0x25,0x09,0x05,0x42,0x27,0x30,0x88,0x9e,0xde,0x23,0xf9,0xf9,0xe3,0xd5,0x75,0xbd,0x73,0x69,0x2a,0x5d,0x51,0x71,0xb9 +,0x79,0x2a,0x48,0x38,0xf8,0xe8,0x75,0x7f,0xec,0x3c,0xbf,0xce,0xad,0x39,0x57,0xf6,0xfe,0x9d,0xe7,0xfb,0xa1,0x69,0xbe,0xd2,0x7e,0x1a,0x37,0xbf,0xd1,0xe5,0xf2,0xbe +,0xd8,0x77,0x51,0xd7,0x5f,0x71,0x3e,0xad,0x0c,0xd6,0xf0,0xe7,0xd2,0xfa,0x84,0x57,0xad,0xff,0x57,0xe9,0xb8,0x41,0x7e,0x8b,0x75,0x2e,0x58,0x09,0xe7,0x11,0x9c,0x1d +,0xd2,0x9a,0xaf,0xc7,0xb3,0xc3,0x70,0x36,0xf7,0xfe,0x9b,0x51,0xf5,0x33,0x61,0xb2,0x9e,0x9f,0x61,0x7a,0xa8,0xde,0x0e,0x27,0x45,0x57,0xb2,0xa1,0x9e,0xfb,0x2b,0x8a +,0x70,0x25,0x3e,0x3b,0xb9,0x02,0x99,0x13,0xdf,0x54,0x94,0x18,0x41,0x48,0x4b,0x6c,0x3d,0x84,0x6a,0x89,0x86,0x87,0x5e,0x33,0xbe,0x9a,0x1b,0xeb,0xc0,0xb6,0x9b,0xda +,0x89,0xba,0x91,0xbc,0x23,0xda,0x51,0x1d,0x1c,0x02,0x1f,0x9e,0x17,0x8d,0x34,0xd6,0xfe,0x5d,0x2e,0x20,0xfd,0xf5,0x00,0x84,0x01,0x40,0x15,0x2c,0x38,0x0b,0x11,0x02 +,0x61,0x62,0xa0,0x98,0x68,0x16,0x0a,0x90,0xc2,0xa2,0x10,0x98,0x54,0x26,0x11,0x09,0x85,0x42,0x27,0x67,0x1d,0xa7,0x15,0xc7,0x2c,0x88,0x98,0x59,0x7b,0xbe,0xb2,0xd9 +,0xc6,0xfc,0xf8,0xaf,0x22,0x57,0x91,0x3f,0x55,0x5e,0x4f,0x20,0xf6,0x05,0x61,0xae,0x4f,0x3a,0xfd,0x35,0x57,0xf9,0x5f,0xd3,0xe9,0x9d,0x9a,0xfb,0xb9,0xfe,0x5c,0xbd +,0x5a,0x9e,0xea,0x74,0x52,0x56,0x6e,0xfd,0x8f,0xff,0xae,0xfb,0xfa,0xad,0xeb,0x86,0x7e,0x14,0x65,0x80,0x8f,0xa2,0x3b,0x28,0xe9,0x07,0x41,0x6e,0xcf,0xaf,0xb0,0x25 +,0x0f,0x65,0x02,0x54,0xe1,0x5f,0x15,0xf9,0x3c,0x1e,0x16,0x78,0x0e,0x5c,0xdc,0x38,0x21,0xd1,0xe4,0x47,0x2d,0x72,0x38,0x9d,0x2b,0x2f,0xd6,0x83,0x83,0x97,0x98,0x1c +,0xe3,0x2f,0x17,0x30,0x01,0x67,0x9a,0x1f,0xc4,0xee,0x77,0xf6,0x3d,0x71,0x9a,0x43,0xc4,0x00,0x7e,0xe2,0xe4,0xb3,0x46,0xbc,0x21,0xd4,0x2c,0xee,0x0f,0xca,0x16,0x39 +,0x70,0x4a,0x49,0xec,0xb0,0x03,0x14,0x42,0xab,0x90,0x20,0x8c,0x8e,0x8e,0x00,0xb9,0x5a,0x0e,0x55,0x03,0x80,0xff,0xf1,0x50,0x80,0x2e,0xff,0xfc,0x21,0x0a,0xcd,0x6f +,0xff,0xff,0xff,0xfe,0xb3,0x80,0xb0,0xd0,0xac,0x15,0x0b,0x85,0x82,0x81,0x61,0x20,0xd4,0x28,0x52,0x12,0x84,0x86,0x61,0x15,0xba,0xe6,0xdc,0x57,0x9e,0xfd,0x71,0x96 +,0x99,0xc6,0xee,0x41,0x46,0xb0,0xbc,0x49,0x79,0x72,0x7d,0xff,0x51,0xd8,0xca,0x7f,0x8e,0x9e,0xd2,0xf8,0x7f,0xe1,0xe4,0x72,0xed,0xe7,0x9b,0x7f,0xa9,0xfd,0x4f,0x25 +,0xe3,0xfe,0x0a,0x83,0xf3,0x40,0x1f,0xff,0x1e,0x65,0x6d,0xbe,0xed,0x8e,0xda,0xfb,0xd9,0xf7,0x4f,0xd2,0xef,0x1f,0x6d,0xc3,0xe5,0x0e,0x5e,0xe4,0x5f,0x15,0xac,0x3e +,0x3b,0x3f,0xf4,0x83,0x92,0x36,0x6c,0xc6,0x3e,0xde,0x02,0x93,0x1c,0x26,0xcd,0x7b,0xb2,0x29,0xe9,0xf3,0x46,0x3e,0x1c,0x17,0x17,0x3e,0x36,0xff,0x2e,0x33,0xe7,0x88 +,0x85,0xe1,0x29,0xbe,0x3e,0xf9,0x96,0x72,0xa8,0x85,0x0a,0x80,0xfb,0x8d,0xd7,0xbc,0xc9,0x4b,0x10,0xed,0x22,0x9f,0xe3,0x8e,0xe6,0xad,0x19,0x68,0x67,0xbe,0x58,0xbb +,0xfc,0x98,0xdb,0xaf,0x25,0x6b,0x74,0x71,0x8e,0x52,0x8b,0x48,0x23,0x75,0xa9,0x46,0x89,0xc8,0x1d,0x26,0x13,0x4b,0x1a,0x60,0x28,0x2e,0x02,0x7d,0x07,0x01,0x41,0x38 +,0x50,0x4a,0x16,0x0b,0x85,0x06,0xc1,0x41,0x30,0xd0,0x4a,0x14,0x09,0x84,0x44,0xa2,0x30,0xa8,0x84,0x46,0x21,0x09,0x84,0x42,0x61,0x11,0x3f,0x8e,0x3d,0xf5,0xd7,0x3d +,0x66,0x71,0xde,0xaa,0x54,0xaa,0x6a,0xa2,0xb8,0xfc,0x57,0x8e,0x3b,0xe1,0xe9,0xe7,0x7e,0xdc,0xf0,0xbe,0x87,0xd3,0xff,0x95,0xfd,0x97,0xc3,0xa2,0xf8,0x27,0x36,0x77 +,0x5e,0x97,0xcf,0xfd,0xed,0xc4,0x85,0x11,0x97,0xdd,0xd7,0x60,0x1c,0x07,0xe2,0x74,0x67,0xe0,0xe7,0xed,0x04,0x7f,0xea,0x1b,0x06,0xdd,0xfe,0x42,0xa3,0x78,0x8d,0x0f +,0x61,0x18,0x70,0x2e,0x33,0x5e,0x05,0xe7,0x2f,0xed,0xdd,0xb0,0x77,0x2b,0x05,0x7e,0x0c,0xe1,0x09,0x72,0xff,0x09,0xab,0x4f,0x93,0xff,0xf2,0xb6,0xab,0x76,0xdc,0xf1 +,0x80,0xf3,0x30,0x8f,0x00,0x0e,0x40,0x07,0x8f,0x88,0x00,0xee,0xf9,0x85,0x47,0x88,0x00,0x0f,0x00,0x00,0x2f,0x1b,0xda,0x64,0x2b,0x2b,0x09,0x8f,0x58,0x3e,0x18,0xd2 +,0x00,0x44,0xa8,0x7b,0x89,0xc8,0x07,0x78,0x05,0xc0,0x90,0x0e,0xff,0xf1,0x50,0x80,0x34,0x7f,0xfc,0x21,0x0a,0xcf,0xf7,0xff,0xff,0xf7,0xf4,0xb0,0x60,0xc0,0x58,0x68 +,0x22,0x0b,0x09,0xc3,0x01,0x61,0x20,0x58,0x28,0x15,0x0a,0x05,0x42,0x82,0x60,0xa0,0x58,0x28,0x45,0x09,0x85,0x42,0x42,0x50,0x89,0x14,0x26,0x11,0x12,0xb8,0xdb,0xa6 +,0xb9,0xe6,0x2e,0x55,0x69,0x9a,0xa9,0x29,0x4b,0x79,0xef,0xdb,0xe5,0xf1,0xdd,0xab,0xdb,0xbf,0xdf,0x81,0xee,0xeb,0x8b,0xe3,0xfd,0x7f,0x1b,0x7d,0x5f,0x71,0xdd,0x77 +,0x7f,0xa5,0xdd,0xff,0xa8,0xf6,0x72,0xd5,0x38,0x43,0xf9,0xef,0x5e,0x74,0x56,0x5a,0x8b,0xf1,0xdc,0xb7,0xef,0xc4,0xd3,0x7b,0xf5,0x3f,0xd5,0xad,0xc7,0xe5,0x3e,0xc4 +,0x39,0xf9,0xe2,0x5c,0x47,0x69,0x2e,0x73,0xe1,0x76,0x3e,0xfd,0xe5,0x45,0xde,0xb2,0x20,0x79,0xfa,0x62,0xf3,0x95,0x19,0x7f,0x02,0x30,0x12,0xc3,0xf2,0xc7,0x10,0x3e +,0x98,0x69,0x13,0x81,0x9d,0x8d,0xa8,0x2a,0xf6,0x25,0xb7,0x2b,0xed,0x3f,0xe1,0x94,0x6a,0xfd,0x8a,0xb0,0x79,0x47,0x30,0x52,0xd1,0x6f,0x7d,0x1d,0x1a,0xa3,0xae,0x28 +,0x10,0xf0,0x04,0xc9,0x5b,0x14,0xbe,0xbb,0x2d,0x52,0x70,0xad,0x4b,0x12,0x48,0x07,0x90,0x94,0xee,0x4b,0x84,0x6e,0x4d,0x16,0xce,0xa1,0x1b,0x49,0x7c,0x48,0x15,0xf1 +,0x00,0x00,0xaf,0xb8,0x58,0x48,0x08,0x00,0xa8,0x40,0xc0,0x50,0x2c,0x17,0x0a,0x05,0xc2,0xc1,0x40,0x98,0x58,0x30,0x16,0x1c,0x05,0x8c,0x83,0x51,0x08,0x8c,0x42,0x15 +,0x09,0x85,0x42,0x65,0x11,0xab,0x5e,0x35,0xed,0xea,0xf8,0xee,0x6f,0x8e,0x64,0xd6,0xd4,0xb1,0xae,0x3d,0xab,0xde,0xb8,0x9b,0xd3,0x29,0xcf,0xe3,0x2c,0x7e,0xf9,0x59 +,0x9f,0xca,0x65,0xe9,0x77,0xbb,0x95,0x77,0x1d,0xba,0xff,0x31,0xfa,0x0f,0x67,0x2b,0xc0,0xe9,0x37,0xa6,0x9c,0xa7,0xd3,0xdf,0x56,0xf3,0xdf,0xdf,0x6b,0xf2,0xef,0x9c +,0xc8,0x3c,0x6c,0xf8,0x7d,0x52,0x40,0xa3,0x3a,0x7e,0x4b,0x3a,0x3e,0x7c,0x53,0x9f,0xa6,0x1a,0x37,0xb7,0x65,0x17,0xd1,0x26,0x1c,0x40,0xf8,0xd7,0x17,0x27,0xef,0x7d +,0xe7,0x8f,0x08,0xfe,0xc7,0x67,0xf9,0x89,0x74,0xd7,0xf6,0x32,0xe7,0xf7,0x52,0x6a,0x6c,0xf9,0x41,0xe4,0xae,0x00,0x65,0x80,0x9e,0x2f,0x30,0xbc,0xc7,0xff,0xec,0xef +,0x77,0xd7,0x77,0x3d,0x88,0xf7,0x5c,0xe3,0x2a,0x58,0x03,0xc0,0x78,0x08,0x7b,0x80,0xa7,0xf2,0x47,0x80,0x00,0x1d,0xe0,0xee,0x50,0xa0,0xff,0xdf,0xc0,0x11,0xf5,0xdd +,0xe6,0xf5,0x11,0x0e,0xea,0xb3,0xa5,0x2c,0xbc,0xcb,0x18,0x82,0xe4,0xa8,0x07,0xff,0xf1,0x50,0x80,0x2d,0xdf,0xfc,0x21,0x0a,0xcf,0x7f,0xff,0xff,0xff,0xfc,0xb1,0x81 +,0x30,0xd0,0x8e,0x28,0x0a,0x09,0x8c,0x82,0x60,0xa8,0x58,0x24,0x41,0x09,0x84,0x58,0x71,0x3b,0xeb,0x59,0x5e,0x35,0x5a,0x94,0xba,0xaa,0xd4,0xcb,0xa2,0x2b,0xac,0x2a +,0x6b,0x1a,0x7f,0xe7,0xf8,0x04,0x75,0xe1,0xd3,0x7c,0xb4,0x36,0x8b,0x7d,0x7c,0xb3,0x44,0xf1,0xad,0x5f,0xed,0x5f,0xe8,0x4b,0x23,0xa9,0x3e,0xeb,0x77,0xf8,0x3f,0x38 +,0xff,0x7e,0xdc,0x46,0x2c,0xda,0xc6,0x55,0xf0,0x26,0xd5,0x6a,0x84,0x0c,0xe3,0xc2,0xb0,0xb0,0xfa,0xc4,0xe8,0x8f,0x85,0xe6,0x5c,0xde,0x53,0x61,0xa5,0xc8,0x06,0x74 +,0xa0,0x76,0x6f,0x8f,0x97,0x34,0xe8,0x5b,0x8d,0x2c,0x66,0x67,0x1e,0xc5,0xc7,0x5f,0x36,0x9c,0x93,0x78,0xfa,0x3c,0xfc,0x5f,0xd8,0x0b,0xa8,0xc8,0x1f,0xa8,0x23,0x18 +,0x91,0xa2,0x30,0x96,0x7d,0x3f,0x69,0xe1,0x88,0x6b,0x47,0x05,0xaf,0x69,0xc8,0x91,0xaa,0xd7,0xf3,0x63,0x14,0xe9,0x6d,0x7a,0x87,0x37,0x3a,0xd8,0x89,0x87,0x16,0x1a +,0xee,0xb2,0x64,0x57,0x89,0x1c,0xd1,0xb4,0x81,0xd2,0xa1,0x7a,0xab,0x39,0x82,0x60,0x20,0x02,0xa1,0x87,0x41,0x60,0xa0,0x4c,0x28,0x15,0x0a,0x09,0xc4,0xc1,0x30,0xb8 +,0x58,0x48,0x15,0x0a,0x0d,0x42,0x81,0x70,0xa8,0x84,0x46,0x15,0x08,0x88,0xc4,0x27,0x77,0xc7,0xbf,0x1e,0x7b,0xea,0xdb,0xe5,0x35,0xcd,0xd5,0x59,0x72,0xb5,0x3c,0xea +,0x7c,0xeb,0xc4,0xe9,0xc6,0x99,0xc7,0x3d,0x04,0xde,0x7d,0x49,0xab,0x70,0x28,0xb5,0x73,0x9f,0xcf,0xfd,0xc5,0xd7,0xfb,0xdf,0x1f,0xd5,0x8c,0xc7,0xb4,0x77,0x32,0xa5 +,0xf4,0x3f,0xcc,0xcb,0xd7,0xe7,0x89,0x96,0x36,0x47,0x2a,0x92,0xeb,0xc7,0xe3,0x5e,0x06,0xfb,0x5e,0xba,0xe6,0x8a,0x5c,0xbb,0x9b,0x2c,0xee,0x90,0xee,0x3f,0xc7,0xf4 +,0x1c,0xe7,0xb3,0x2e,0x3d,0xbc,0xc3,0x5b,0xe6,0xc2,0xbf,0x75,0xe6,0xe6,0x10,0x07,0x58,0xf2,0x00,0x79,0x00,0x15,0x25,0xd8,0x05,0xbc,0x34,0x98,0x77,0x35,0xfb,0xbf +,0x30,0x38,0x73,0x01,0x20,0xbd,0xb1,0xc4,0xa7,0x4b,0x0e,0xe2,0xe0,0x14,0x77,0xd5,0x58,0x23,0x00,0x4c,0x16,0x00,0x89,0x00,0x11,0x58,0xb8,0x90,0x1c,0xff,0xf1,0x50 +,0x80,0x2e,0x5f,0xfc,0x21,0x0a,0xcf,0x7f,0xff,0xfd,0xff,0xfc,0xb0,0x63,0x20,0xd8,0x2e,0x19,0x0b,0x05,0x04,0xc1,0x51,0x30,0x5c,0x28,0x62,0x12,0x88,0x42,0x63,0x11 +,0x18,0x44,0xca,0x6b,0x9f,0x8c,0xe3,0x99,0xce,0x71,0x5c,0x73,0xaa,0xcb,0x8a,0xba,0x99,0xad,0x33,0x55,0x2b,0x3e,0x3c,0x0f,0xf3,0xa1,0x8e,0x99,0xbf,0xfa,0xfa,0xbb +,0x38,0xf5,0x68,0xd9,0x67,0x28,0xd5,0xdf,0xea,0xe4,0xff,0x2d,0x37,0x33,0x87,0xe3,0x26,0x3e,0xc9,0xf8,0xe7,0xf1,0x39,0xb0,0x02,0x7e,0x2f,0x1e,0x37,0xcd,0xee,0x89 +,0xe5,0x4e,0xc3,0x69,0x12,0xac,0x7d,0xb9,0xb8,0xc8,0x4b,0xf2,0x8c,0x44,0x0e,0xd0,0x58,0x76,0x81,0x1c,0xb6,0xa8,0xfb,0x7a,0x89,0x86,0xfe,0x7a,0x99,0xb5,0x51,0xdf +,0x3c,0x0a,0x17,0x92,0x6a,0xef,0x83,0x83,0xee,0xe3,0xe6,0x91,0xd4,0xb5,0xaf,0x9a,0x40,0x71,0x41,0xcb,0x81,0x58,0x01,0xf1,0xa9,0x79,0xa4,0x4a,0xfe,0xb2,0x0b,0x97 +,0x9a,0xdd,0xd1,0x67,0x7d,0x59,0x90,0x8c,0x6f,0x24,0x30,0x55,0x31,0x47,0x7f,0xdc,0x1b,0x4a,0x19,0x63,0xae,0x90,0x09,0x63,0x5c,0x50,0xc4,0xbd,0x41,0x3b,0x85,0x80 +,0x53,0x20,0x58,0x50,0x14,0x13,0x05,0x06,0xc1,0x80,0xb0,0x5c,0x2c,0x67,0x0b,0x05,0x02,0xc1,0x50,0xa0,0x54,0x86,0x35,0x09,0x84,0x50,0xe7,0xdb,0xf4,0xd7,0x9e,0x78 +,0xf3,0xcf,0x69,0x8a,0x95,0x2d,0x09,0x9f,0x5b,0x71,0xde,0xa6,0xb9,0xf6,0x45,0x71,0xe3,0x43,0xf3,0x87,0xee,0xa3,0xed,0xf5,0x5e,0xfd,0x63,0x53,0x0f,0x76,0x9c,0xf0 +,0x3f,0x47,0xac,0xed,0xb4,0xcb,0x95,0xe3,0x4c,0xf6,0xc4,0xdf,0xc4,0x73,0x1e,0x68,0x5e,0xae,0x69,0xe0,0x96,0x17,0x28,0xb7,0x1a,0x47,0x50,0xf3,0x92,0x60,0x63,0xed +,0x0b,0x6f,0xa6,0xcf,0x36,0xd0,0x6c,0x98,0x8a,0x27,0x0d,0x6b,0x67,0x2b,0xef,0x39,0x08,0xcf,0x24,0x08,0xda,0x5c,0xbe,0x36,0xa3,0xaa,0xac,0x9f,0xe6,0x78,0x8a,0xaf +,0x6f,0x96,0x0f,0x00,0x02,0xfc,0x5b,0xe2,0x1c,0x87,0x21,0xe6,0x0f,0x00,0x00,0x1a,0x7e,0xb1,0x4a,0x83,0xd6,0x3b,0x8f,0x58,0x42,0x20,0x0f,0x00,0x01,0xdd,0xee,0x28 +,0x08,0x44,0x4c,0x98,0x01,0x40,0x80,0x02,0x4b,0x15,0x09,0x14,0x0a,0x4c,0x0e,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a,0xcf,0x7f,0xbf,0xff,0xff,0xff,0xb1,0x70 +,0xc0,0x58,0x68,0x36,0x0a,0x06,0x03,0x41,0x80,0xa8,0x58,0x68,0x52,0x0a,0x08,0x82,0x81,0x30,0x90,0x4c,0x42,0x23,0x08,0x84,0xc2,0x21,0x30,0x88,0x8c,0x22,0x21,0xa9 +,0x2b,0x8c,0xee,0x65,0xf9,0xed,0x52,0x5a,0x64,0x89,0x79,0x7c,0x73,0x9e,0x7b,0xf6,0xe7,0xaf,0x13,0xcf,0xdf,0xc8,0x77,0x46,0xe7,0x17,0xc4,0x7a,0xba,0xaa,0xe6,0x1f +,0xa7,0xfc,0x51,0x73,0xfe,0x2e,0xe0,0xe2,0x51,0xe0,0xa6,0xd6,0xce,0x0d,0x39,0xbd,0x78,0xa7,0xaa,0x40,0x10,0xf6,0xaa,0xf7,0xbd,0x29,0xaf,0xfd,0x1f,0xf4,0x74,0xfa +,0x87,0xb1,0xd6,0xc0,0xd5,0x6f,0xf7,0xa1,0x5e,0xf0,0x4e,0x61,0xd0,0x7d,0xbd,0x75,0x0e,0x2a,0x6e,0x0e,0x93,0x33,0xae,0x0d,0xea,0xad,0x78,0x64,0x7a,0xdc,0x46,0xf6 +,0xe7,0x14,0xfa,0x1f,0x62,0x94,0x77,0x52,0x40,0xf1,0x2a,0x0e,0x07,0xd8,0xcc,0xb7,0xda,0x84,0x7b,0xab,0x9f,0xb2,0x9a,0x75,0x92,0xe8,0x69,0xc2,0x42,0x20,0x7f,0xbb +,0x05,0xe3,0x5c,0xe7,0x75,0x21,0x12,0xb1,0x1f,0xba,0x02,0xb1,0x06,0xbc,0xe0,0x8d,0x0f,0xf0,0x82,0x00,0x2c,0x02,0xa9,0x42,0xe1,0x60,0xc0,0x58,0x28,0x17,0x0b,0x04 +,0xc2,0x41,0x70,0xc0,0x58,0x6e,0x14,0x0b,0x11,0x02,0xc1,0x41,0x29,0x84,0x2a,0x11,0x09,0x84,0x48,0x61,0x11,0x9c,0x7b,0xf9,0xbf,0x1f,0x7f,0x6f,0x1f,0x35,0x26,0x08 +,0xb3,0x38,0xbb,0x6a,0xf9,0xbd,0x71,0xe3,0xca,0xf9,0xaf,0x6d,0xfd,0x07,0xbd,0xe2,0xf6,0x5f,0xf0,0xcd,0xeb,0x1d,0x1a,0xf2,0x73,0xea,0xfd,0x0e,0x7f,0x05,0xb6,0xd4 +,0x80,0xf5,0xd3,0x37,0x7a,0x2d,0xff,0x63,0x9b,0xa1,0x4b,0xdd,0x37,0x34,0x87,0xea,0x76,0xb6,0x1d,0x94,0xd9,0x43,0xeb,0x7d,0x83,0x46,0x3d,0x48,0x15,0x2c,0x27,0x52 +,0x17,0x54,0x7f,0xfc,0x68,0x0f,0xcf,0xc6,0x05,0xcd,0xba,0xde,0xba,0xa6,0xba,0x8f,0x92,0xa3,0xd8,0x2e,0x49,0xaf,0x1d,0x45,0xa0,0x39,0xf2,0xb1,0xe1,0x00,0x4c,0x16 +,0x38,0x8f,0x13,0xcd,0xc0,0x00,0x3c,0x80,0x01,0xe5,0x20,0x70,0x0e,0x45,0xd3,0xb5,0x13,0x00,0x78,0x80,0x24,0xb8,0x14,0xf7,0x42,0x09,0x08,0x16,0x0e,0xa0,0x18,0x00 +,0x03,0xdd,0x14,0x00,0x2a,0x52,0x80,0x70,0xff,0xf1,0x50,0x80,0x2f,0xbf,0xfc,0x21,0x0a,0xcf,0x6f,0xde,0xff,0xff,0xfc,0xb0,0x60,0xc0,0x58,0x2e,0x16,0x0a,0x15,0x83 +,0x01,0x62,0x20,0x58,0x48,0x52,0x28,0x84,0x82,0x22,0x31,0x08,0x4c,0x22,0x13,0x08,0x84,0xc2,0x22,0x55,0xf5,0xdf,0xb6,0xe9,0x9c,0x77,0xed,0xe1,0x35,0x5b,0xb8,0x24 +,0x4a,0x97,0x4d,0x55,0x71,0xcf,0xc7,0x8b,0xff,0xaf,0x01,0xff,0xf1,0x1e,0x67,0x9e,0x89,0xef,0xfd,0xba,0x74,0xbf,0xe9,0x75,0xcf,0xcd,0x3e,0x8b,0xb9,0x9e,0xc3,0xa1 +,0x4f,0xc5,0xe5,0xd7,0xad,0xf6,0xac,0x96,0xdb,0x28,0x68,0x9b,0x51,0x89,0x0d,0x43,0xa6,0x0e,0x87,0x53,0xfa,0x6b,0xa0,0x53,0x5b,0x95,0xd3,0x67,0xc5,0x6f,0x84,0xae +,0x4b,0xb8,0x0e,0x0d,0x8f,0xb4,0x41,0xaa,0xb6,0x4a,0x53,0xe7,0xd2,0xff,0x1d,0x91,0x0e,0xbd,0x2f,0xaf,0x5b,0x5b,0xe7,0x38,0x26,0x92,0x68,0xf5,0xa7,0x11,0x65,0xa7 +,0x59,0x76,0xe3,0x74,0xcd,0x26,0x23,0x1e,0x8e,0x20,0xd0,0x53,0x86,0x96,0x04,0xa0,0xc9,0x2a,0xca,0x23,0xbf,0xda,0x65,0x1e,0x12,0xd0,0x2c,0x2f,0xf5,0x9a,0x43,0xc1 +,0x88,0x0c,0x0e,0xc0,0x2b,0xdc,0xc2,0x10,0xc2,0xfc,0x2a,0x80,0x22,0x0a,0x00,0x9b,0x50,0xb0,0x60,0x4c,0x27,0x0b,0x05,0x02,0xa1,0x40,0xc0,0x58,0x30,0x17,0x0a,0x85 +,0xc2,0x81,0x62,0x20,0x54,0x28,0x15,0x08,0x84,0xc2,0x21,0x50,0x99,0x04,0x26,0x11,0x3b,0xfa,0xfd,0x7e,0xda,0xbe,0x7f,0x7e,0x6b,0x75,0xe7,0xe7,0x8a,0x64,0x89,0x15 +,0xaf,0xbe,0xee,0x78,0x91,0xe7,0xd7,0xb4,0xbc,0xf3,0xfa,0xfe,0xe1,0xec,0xa3,0xd5,0x59,0xa8,0xea,0xb7,0xce,0x7e,0x30,0xfb,0xcf,0x4e,0xcf,0xf2,0xf8,0x3a,0xcf,0xf7 +,0x96,0xf9,0x1a,0x1e,0x16,0x76,0xbb,0x00,0xf4,0x11,0xf5,0xf3,0xc5,0xe1,0xcf,0x4f,0x1d,0xac,0xf8,0x57,0xc0,0x37,0x09,0x1e,0x63,0xf2,0x68,0x0a,0xbc,0x27,0x09,0x5a +,0x84,0xda,0xc6,0xe4,0xf6,0x19,0xf7,0xbe,0x9b,0xf9,0x2f,0x81,0x8b,0x81,0xcc,0xf9,0x38,0xeb,0x38,0xcc,0x12,0x9d,0xdb,0xc6,0x4e,0x49,0x53,0xf4,0x46,0x07,0x7f,0xbc +,0x09,0x53,0xb8,0x93,0xc8,0x00,0x02,0x27,0xa9,0xa2,0x3d,0xc2,0x37,0x20,0x3d,0xc0,0x53,0xd7,0x2d,0x50,0x02,0x1e,0xec,0x00,0x34,0xb8,0x12,0x04,0x02,0x22,0x40,0x5d +,0x48,0x15,0x00,0xa0,0x1c,0xff,0xf1,0x50,0x80,0x37,0x3f,0xfc,0x21,0x0a,0xcf,0x67,0xf7,0xbd,0xf7,0xef,0xac,0x60,0xc0,0x58,0x28,0x18,0x0b,0x05,0x42,0x81,0x60,0xb8 +,0x54,0x30,0x14,0x0b,0x05,0x02,0xe1,0x61,0xa0,0x58,0x28,0x62,0x1a,0x08,0x46,0x62,0x10,0x98,0x44,0x8e,0x6e,0xf3,0xeb,0xbe,0x39,0xe7,0x59,0xa6,0x57,0x19,0x4b,0xa9 +,0x52,0xc2,0xf2,0x49,0x25,0x75,0xdc,0xff,0xed,0xf7,0x1b,0xf0,0x89,0xcf,0x8f,0xaf,0xc8,0xa1,0xcc,0xf2,0xec,0x7c,0x3f,0x3f,0x87,0x8f,0x7f,0x1d,0x67,0xbd,0xc5,0x03 +,0x5a,0x09,0xf6,0x48,0x3f,0x8d,0x1f,0xd2,0xb8,0xc7,0x17,0xbe,0x60,0x27,0x47,0x77,0x9a,0xf4,0x97,0x70,0x5f,0x4d,0x9c,0x4a,0x69,0xbe,0xdd,0xf7,0xb2,0x9c,0xab,0xda +,0x1a,0x07,0x7f,0x13,0xfe,0x6e,0x17,0x5d,0x9a,0x31,0xc7,0xb4,0x38,0x7f,0xa7,0xc3,0x7d,0xcb,0xd0,0xad,0x65,0xcf,0x4d,0x2b,0xae,0xcd,0x3b,0x76,0xdd,0x58,0x9d,0x45 +,0xc1,0x7c,0xc6,0x2d,0x45,0x67,0xcd,0xeb,0xdd,0x62,0xd2,0x75,0x57,0x12,0x6f,0x3a,0x0f,0x8f,0x3d,0x07,0xc2,0x2a,0xfa,0x1f,0x1a,0xb3,0x55,0x5d,0xa2,0x4d,0x10,0xe6 +,0xe2,0xdb,0x22,0xd5,0xd3,0x9b,0x8b,0x48,0x7c,0x72,0x63,0xb5,0xcb,0xfa,0x47,0x88,0x91,0xa6,0xe7,0xab,0x74,0xea,0x01,0xde,0x41,0xa2,0x6a,0x9c,0xa7,0x10,0x5c,0x02 +,0x20,0x53,0xa0,0x5c,0x2c,0x18,0x0b,0x05,0x03,0x01,0x41,0x18,0x50,0x2c,0x15,0x0b,0x15,0x42,0xc1,0x80,0xa0,0x58,0x28,0x23,0x0a,0x88,0xc4,0xa1,0x31,0x28,0x4c,0x22 +,0x13,0x09,0x04,0x44,0x61,0x10,0x80,0x5b,0xf3,0xef,0x3a,0xf1,0xae,0xb6,0xe7,0xcf,0x77,0x2a,0xae,0xb2,0x24,0x9c,0x55,0x5e,0x25,0x4c,0xd4,0xe7,0x8f,0x3f,0xfe,0x83 +,0xf8,0xcf,0x51,0xfd,0xaf,0x16,0x89,0xbd,0x7f,0xe9,0x36,0xbb,0xe4,0x7f,0x9b,0xfd,0x27,0xaf,0xf6,0xb4,0x72,0x3c,0xbd,0x2a,0xf0,0x72,0xf3,0x5d,0xc2,0xeb,0x2e,0x44 +,0xf0,0x92,0x99,0x83,0x4f,0x8b,0x1f,0x55,0x4f,0xbb,0xf4,0xff,0x42,0x79,0xb8,0x1c,0xe8,0x45,0xfd,0x19,0xaf,0x2b,0xe1,0x3f,0xa1,0x16,0x34,0xeb,0x2b,0xdb,0x58,0x4b +,0xef,0xf5,0xbf,0xb1,0x47,0xe6,0x83,0x8d,0x49,0xe9,0xcb,0xfc,0x19,0xa1,0xe7,0x1f,0xe0,0x41,0xc7,0xed,0xb1,0x69,0x3d,0x50,0x95,0x26,0x50,0xdb,0xd9,0xf8,0x7e,0xc2 +,0xef,0xfe,0xbc,0xc8,0xb8,0x6b,0xa6,0xa8,0x95,0x92,0xcd,0xf1,0x7f,0xc7,0xef,0xfa,0xa5,0xe3,0x37,0xcf,0xb1,0x44,0x96,0x06,0x97,0xc1,0x0b,0x25,0xad,0x35,0x5a,0x03 +,0x4f,0xc8,0x6d,0xcd,0x5b,0x15,0x51,0x34,0x34,0x1e,0x4c,0xeb,0x85,0x6a,0xef,0x17,0x7c,0xad,0x9e,0x28,0xf6,0x44,0x84,0xf6,0xc0,0x77,0x0f,0x74,0x58,0x0e,0xff,0xf1 +,0x50,0x80,0x30,0x9f,0xfc,0x21,0x0a,0xcf,0x7f,0xbb,0xff,0xff,0xfe,0xaf,0x60,0xc0,0x98,0x48,0x17,0x0b,0x05,0x02,0xa2,0x60,0xa0,0x98,0x48,0x16,0x0a,0x15,0x42,0x81 +,0x21,0x88,0x4c,0x24,0x11,0x09,0x84,0x44,0x41,0x10,0x98,0x84,0x60,0x17,0x7c,0x5e,0xfe,0xbd,0x7d,0xfe,0x5f,0x7f,0xb7,0x1d,0xea,0x61,0x79,0xac,0xd5,0x0d,0x4d,0xdd +,0xf7,0x13,0x86,0xeb,0xff,0xe4,0x0f,0xe8,0x2b,0xee,0x75,0x8d,0xb6,0xf8,0xf6,0xf9,0x4e,0xc7,0xbd,0x3e,0x09,0xf7,0x2d,0x8f,0x31,0xac,0x3d,0x47,0x34,0x3f,0x49,0xfb +,0xce,0xb9,0x55,0x1f,0x89,0x3e,0xa0,0xe3,0x5d,0x76,0x20,0x89,0x72,0x4e,0x85,0xd8,0xf7,0xdc,0x00,0xad,0x11,0xa8,0xa8,0xf0,0xf5,0xc6,0x01,0xa7,0xe5,0x37,0xba,0x36 +,0x19,0x9a,0xfa,0x44,0xc9,0x9e,0xfc,0xce,0x97,0xef,0xde,0xfc,0x0a,0x5f,0x1e,0x38,0x2c,0x1c,0x8d,0x7c,0xae,0x2d,0x1d,0x28,0xad,0xe1,0x54,0xf0,0xdf,0xd9,0x05,0x2a +,0xeb,0x12,0xda,0x05,0x61,0x74,0x1d,0x86,0x68,0xc1,0xf9,0x42,0xfe,0x0a,0x6d,0x23,0x04,0x61,0x75,0xce,0x93,0x2f,0xc8,0x90,0x88,0x1b,0xe5,0x0f,0x62,0x60,0xef,0x2c +,0x07,0x76,0xeb,0x24,0x53,0x65,0xa3,0x08,0x8a,0x80,0x9c,0x40,0xb0,0xa0,0x2c,0x44,0x09,0x05,0x8a,0xe1,0x80,0xb1,0x10,0x66,0x31,0x09,0x85,0x42,0x63,0x10,0xa8,0x44 +,0x26,0x11,0x33,0xf8,0x9d,0xf1,0x7b,0xfa,0xf5,0xfc,0xfe,0x99,0x57,0x8c,0xd5,0x12,0x5a,0x7b,0x6b,0xc7,0x59,0xeb,0xae,0x3b,0xde,0xbe,0xb2,0x79,0xff,0xbe,0x86,0x90 +,0x9b,0xbf,0x6c,0x7d,0x09,0x3f,0xd3,0xd2,0xe3,0xee,0xe9,0x47,0xc3,0xbd,0xea,0x2e,0x0b,0x45,0x85,0xfa,0x8e,0x1e,0x51,0x1a,0xf5,0x2f,0x61,0x9c,0xbc,0x4f,0x6e,0x17 +,0xc7,0xa0,0x47,0xb2,0xaa,0x32,0xa8,0x3a,0x18,0x51,0x35,0xf4,0x76,0x90,0xf2,0x42,0xd5,0x92,0x51,0x7e,0xef,0xe8,0x7e,0x1b,0xdf,0xf4,0x7f,0x8d,0xfe,0x97,0xff,0xcd +,0x57,0x7f,0xc5,0x1f,0xfc,0xb4,0x7b,0x8e,0xff,0x0b,0x43,0xda,0xfa,0xe3,0xb2,0xee,0x0f,0x74,0x44,0x7f,0x7c,0xba,0x1e,0xb0,0x79,0x80,0x05,0x9e,0xb0,0xd2,0xbf,0x32 +,0xb3,0x25,0xf9,0x47,0x7d,0xdd,0x0a,0x84,0xf2,0x87,0x10,0x0c,0xc7,0x96,0x35,0x8e,0xf0,0x88,0x27,0xdf,0x94,0x04,0x67,0x90,0x8d,0xc0,0x0b,0xcc,0x55,0x41,0x00,0x0a +,0x81,0xc0,0xff,0xf1,0x50,0x80,0x2e,0x5f,0xfc,0x21,0x0a,0xcf,0x4f,0xff,0xff,0xff,0xff,0xb1,0x81,0x31,0x90,0x4c,0x24,0x13,0x09,0x14,0x41,0x30,0xa8,0x4c,0x22,0x12 +,0x28,0x8c,0xc2,0x23,0x53,0xef,0xeb,0xcf,0x7f,0x1e,0xf6,0xab,0xca,0x92,0x89,0x78,0xbd,0x6f,0x52,0xfb,0x52,0x54,0xfb,0xfd,0xbe,0x39,0xff,0xf4,0xfa,0x0a,0xd2,0x2f +,0xeb,0xeb,0xf2,0xff,0x23,0xb7,0xdb,0xf8,0x61,0xdb,0xc6,0x8f,0x98,0xf0,0x9c,0xa8,0x61,0x8b,0x0f,0xd2,0x67,0x56,0xfd,0x77,0xd5,0xf1,0x32,0x53,0x97,0x78,0x83,0xfd +,0xab,0xe1,0x00,0x1a,0x33,0x5b,0x7d,0xf8,0x37,0x94,0xfd,0xa0,0x03,0xd2,0xee,0xfb,0xff,0xbf,0x3f,0x41,0xe6,0xc8,0x3b,0x08,0x74,0xa9,0x40,0x64,0x9c,0xf2,0xce,0x78 +,0x50,0x16,0xca,0xfb,0x46,0x41,0x99,0xdb,0x53,0x1a,0x07,0x62,0x4c,0xd4,0xbe,0xcf,0x9b,0xb0,0x8e,0x64,0x9c,0xad,0x24,0xfc,0x07,0x78,0xf7,0x27,0xf1,0xbc,0x92,0xfc +,0x07,0x40,0x5e,0xff,0xb1,0x2d,0x02,0x45,0x5c,0xa3,0x91,0x00,0x7d,0x84,0x6b,0x8e,0x45,0xf6,0xe4,0xa2,0x5d,0x90,0x76,0x28,0xde,0xc4,0x27,0x17,0x54,0x52,0xa8,0x2e +,0xc4,0x70,0x97,0xc7,0x30,0xf3,0x64,0x48,0x49,0x69,0x89,0x80,0x48,0x0a,0x66,0x29,0x86,0x02,0xa1,0x40,0xa8,0x5c,0x2c,0x17,0x0a,0x05,0x84,0xa1,0x40,0xb0,0x94,0x2c +,0x14,0x1a,0x88,0x48,0x61,0x50,0x89,0x8c,0x20,0x37,0x7c,0x78,0x9c,0x77,0xf1,0xce,0x99,0x44,0x65,0x5c,0x64,0xe3,0x5e,0x7a,0x6a,0x7e,0xdc,0x7f,0xe7,0xff,0x1c,0xea +,0x4f,0x41,0xb5,0xc7,0x5a,0x7d,0x3e,0x5c,0x2b,0xd1,0xfa,0x90,0x7d,0x0e,0xed,0x3d,0xf2,0x6d,0x6c,0xf2,0x71,0xc4,0xf9,0x27,0xdd,0x6c,0xf1,0xf7,0x9f,0x9d,0x41,0x6f +,0xde,0x93,0x0f,0x82,0x3a,0xfb,0xdf,0x82,0xef,0x9a,0x29,0xa3,0x60,0x09,0xfc,0x6f,0x09,0x0a,0x5c,0x79,0xcf,0x98,0xe3,0x51,0x5f,0x57,0xea,0xff,0x77,0xca,0xc3,0xf2 +,0xfe,0x57,0xac,0xe7,0xb7,0xf4,0xbd,0xb4,0xc7,0xfd,0xdb,0x7a,0xef,0xc1,0x1a,0x14,0x87,0x80,0x01,0x6a,0x89,0x50,0x46,0xd5,0xc1,0x19,0x7a,0x00,0x3d,0xd1,0x08,0xfb +,0xa3,0xbe,0xf2,0x00,0x00,0x02,0xc9,0x50,0x27,0x00,0x90,0x03,0x24,0xc9,0x82,0xc0,0x1d,0xe3,0xb8,0x70,0xff,0xf1,0x50,0x80,0x2e,0x9f,0xfc,0x21,0x0a,0xcf,0xd6,0xeb +,0xfd,0xff,0xfe,0xaf,0x81,0xb1,0x50,0x6c,0x14,0x0b,0x0d,0x04,0xc1,0x41,0x28,0x50,0x44,0x25,0x09,0x84,0x84,0x23,0x30,0x88,0x48,0x22,0x76,0xe6,0x97,0x9e,0x7c,0x65 +,0xea,0x37,0x57,0x43,0x44,0x8e,0x3b,0x43,0x5c,0xd4,0xbb,0x3f,0xef,0xec,0x15,0xa7,0x27,0xe2,0x4f,0xa7,0xe8,0xb6,0x9d,0xfd,0x49,0x1d,0x5a,0x2a,0xf9,0x8f,0xcc,0x39 +,0x7f,0xf4,0xaa,0xfd,0x62,0x1a,0x6c,0x7e,0x95,0x14,0xfc,0xc0,0x97,0x2d,0x4f,0x3f,0x77,0xcc,0x35,0xaf,0x1d,0x04,0xf0,0xd4,0x6c,0x2d,0xc3,0x7a,0x37,0xf8,0xff,0x34 +,0xdf,0x1f,0x4e,0x62,0xa2,0x5b,0xce,0x33,0x04,0x4f,0x70,0x1b,0x1e,0x52,0xbe,0x53,0xde,0xe4,0xb5,0x9f,0xd0,0xe8,0xd5,0xb0,0x2b,0x95,0xd1,0x17,0x7c,0xf7,0xc6,0x4a +,0x19,0x3f,0x41,0xf6,0xa0,0x8c,0x86,0xd7,0x51,0x3b,0x60,0xa6,0x24,0x23,0xe6,0xa9,0x2c,0x78,0x82,0x9e,0x1c,0x48,0xd5,0x3b,0xdb,0xbb,0xdb,0x52,0x75,0xb0,0x84,0x56 +,0x83,0x1a,0xba,0x30,0x74,0xc1,0x4e,0x23,0x02,0xb2,0x75,0x5b,0x53,0x25,0x80,0x8a,0xb6,0x26,0xc9,0x74,0x41,0x70,0x88,0x09,0xa2,0x0b,0x1d,0x02,0xc6,0x40,0xb1,0xd4 +,0x28,0x15,0x19,0x84,0x42,0x61,0x13,0x18,0x44,0x80,0x17,0xf4,0xe3,0x69,0x5d,0x6f,0xf7,0xfe,0x97,0x33,0x2f,0x7a,0x95,0x10,0xd7,0xf9,0xf9,0xfc,0x78,0xf8,0xfd,0x2e +,0xbf,0xcd,0x7e,0xde,0xab,0xef,0xed,0xa1,0xb4,0x7d,0xbc,0xb6,0x59,0xf4,0xf3,0xb4,0x9b,0xe8,0xf4,0xea,0xab,0xe2,0xf9,0xf1,0xe3,0x97,0x87,0x50,0xdc,0x5a,0xc9,0x37 +,0xf0,0xcc,0xf6,0x7b,0xf8,0xf7,0x53,0xcb,0xff,0x6e,0x1b,0x5d,0x9e,0xbe,0x76,0xf0,0xcb,0xea,0x00,0x52,0xe4,0x9f,0x80,0xb7,0xe3,0x78,0x5b,0xe1,0xf7,0xa0,0x6f,0x09 +,0x24,0x94,0x0e,0x9a,0x3b,0xca,0x8b,0x52,0xfb,0x59,0xbe,0xfc,0xe1,0xd7,0xd1,0xf0,0x1c,0x7f,0x5a,0x6b,0x94,0xd3,0xf3,0x26,0x23,0x2e,0x33,0xcd,0xf8,0x38,0x70,0x9e +,0x55,0xbb,0xe8,0x01,0xe2,0x00,0xf3,0x79,0x00,0x08,0xea,0xb0,0x01,0xe0,0x54,0x14,0x87,0x00,0x4a,0x60,0xbf,0x54,0x40,0x00,0xa5,0x6c,0x01,0x0f,0x5a,0x0f,0x58,0x8c +,0x20,0x22,0x82,0x2a,0x84,0x00,0x06,0xd7,0xff,0xf1,0x50,0x80,0x30,0xff,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xff,0xff,0xb1,0x70,0xc0,0x58,0x30,0x16,0x09,0x85,0x05 +,0x02,0x61,0xa0,0x58,0x4a,0x14,0x23,0x05,0x02,0xa1,0x41,0x91,0x04,0xa6,0x11,0x33,0x7d,0x73,0x3a,0xb7,0x8a,0x8e,0xb1,0x5a,0xc5,0x95,0xac,0x81,0x24,0xad,0xbc,0xef +,0x89,0x5f,0x7e,0x04,0xf7,0x22,0xdc,0xff,0x14,0xf8,0xdf,0xb3,0xe9,0xfe,0x0e,0x3f,0xc5,0x81,0xa9,0xef,0xdf,0x9d,0x25,0xfd,0xb2,0xdf,0xd7,0x1a,0x94,0xeb,0xfc,0x6e +,0xa2,0x3d,0x78,0x26,0xe7,0xb1,0x37,0xe9,0x40,0x2e,0x9f,0x19,0xa4,0x3e,0xe7,0xd3,0xf3,0x7f,0xbd,0x40,0xc5,0x0e,0xac,0x88,0x67,0xe4,0x20,0xa1,0xfc,0x42,0x86,0x93 +,0x6b,0xd3,0x14,0xcf,0xc9,0x1b,0xb9,0x5e,0xf5,0x60,0x57,0x7c,0x2a,0x5f,0x88,0x5b,0x71,0xd9,0xa8,0x5a,0x36,0xa6,0x69,0xd6,0x62,0x2b,0xf7,0xe2,0xc0,0x47,0xca,0x95 +,0xa9,0xa5,0x2e,0xf3,0x36,0x9b,0x54,0x65,0xba,0xf6,0x6b,0x9f,0x9b,0x9d,0xe5,0x06,0xc3,0xbc,0xa0,0x5e,0xcd,0x17,0x49,0x87,0x3f,0xb9,0x42,0x38,0x23,0x8a,0xb3,0x7a +,0x34,0x83,0x7a,0xc4,0x98,0xaf,0x11,0x21,0x9e,0xc0,0x8c,0xab,0x09,0x0a,0x80,0x98,0x09,0x95,0x0b,0x05,0x42,0xe1,0x61,0x40,0x98,0x28,0x17,0x0b,0x0d,0x04,0xc4,0x70 +,0xa0,0x54,0x2e,0x15,0x0a,0x05,0x44,0x21,0x50,0x88,0x4c,0x62,0x25,0x09,0x8c,0x46,0xff,0x5e,0xb9,0x4c,0xf8,0xf1,0x15,0xae,0x6d,0x32,0xb5,0x37,0x34,0xae,0x35,0xc6 +,0xef,0xc4,0x9e,0x5b,0xe7,0x86,0xab,0x41,0xc8,0x7e,0x3f,0x5b,0xb8,0x9f,0x9b,0xec,0x88,0x79,0x3d,0xa1,0xb9,0x2f,0xe2,0x37,0x9d,0xd3,0xe7,0x4f,0x00,0x9f,0xb8,0xa8 +,0xbb,0xaa,0xef,0x89,0xff,0xe1,0xf5,0x5f,0x7e,0x82,0xe1,0x4e,0x41,0x97,0xe1,0x27,0xd6,0x3c,0x32,0x90,0x42,0x49,0x7b,0xed,0xa3,0xe3,0xf2,0x20,0x7f,0xaf,0xc0,0xfe +,0xdf,0x90,0x39,0xfc,0xf9,0x3c,0x9e,0x1c,0x2b,0x5d,0xce,0x57,0xb3,0xc0,0x93,0x87,0x39,0xbd,0x7a,0xba,0x5b,0x3b,0xcf,0xb2,0xdd,0x5c,0x39,0x00,0xe7,0xe0,0x00,0x71 +,0x56,0x12,0xd8,0x03,0xc0,0xec,0x01,0xb7,0x49,0x61,0xee,0xd0,0x38,0xbd,0xd9,0x9e,0xb9,0xee,0xcc,0x7b,0x8e,0xf7,0xba,0x01,0xa6,0x51,0x0b,0x8f,0x00,0x00,0x0f,0x5a +,0xa7,0x98,0x77,0x1d,0xe2,0xc5,0xbd,0x60,0x41,0x60,0x17,0x80,0x3b,0x01,0xc0,0xff,0xf1,0x50,0x80,0x30,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xdf,0xff,0xaf,0x62 +,0x98,0x50,0x50,0x26,0x0d,0x06,0x02,0x82,0x60,0xa0,0x54,0x2c,0x14,0x2a,0x85,0x02,0x62,0x10,0x98,0x48,0x22,0x13,0x08,0x90,0xc2,0x25,0x77,0xd6,0xeb,0xca,0x9e,0x3a +,0xe7,0xef,0xdc,0x38,0xed,0x17,0x51,0x6c,0xbc,0xf3,0xbd,0xdd,0x4d,0x2b,0x5d,0x79,0x17,0xf6,0x67,0xae,0x3e,0x95,0x68,0xe5,0xa7,0xf4,0x5c,0x57,0x8a,0xab,0x93,0xda +,0x1f,0xdc,0xe2,0xe8,0x99,0x77,0xad,0xfb,0xb7,0xa5,0x15,0xee,0xeb,0x5f,0xc8,0x93,0xb3,0x42,0x07,0x7d,0xce,0xf2,0xf7,0x6e,0x9f,0xa2,0x90,0x20,0x7c,0xad,0x1d,0xc6 +,0xbd,0x7e,0xa4,0xf1,0x32,0x4b,0x69,0xda,0xc7,0x31,0x3c,0xf7,0xf5,0x91,0xab,0x9c,0xee,0x5b,0xf3,0xab,0xa6,0x43,0x71,0xf1,0xf0,0x4b,0xf1,0x49,0x61,0x4f,0x92,0xeb +,0x36,0x3e,0x6a,0x87,0xd5,0x26,0x0f,0x85,0x32,0x9d,0xed,0x9b,0x08,0x72,0x98,0x92,0x0c,0x4f,0xa2,0x44,0x53,0x3d,0x63,0x24,0x46,0x5f,0xcf,0x1a,0xf5,0x24,0x9c,0x66 +,0x62,0xc7,0xf6,0x25,0x03,0x9b,0x6d,0x5e,0x67,0x15,0x40,0x85,0x09,0x11,0x8a,0x56,0x13,0xfc,0xc0,0x80,0x05,0x40,0xa5,0x50,0xb1,0x90,0x2c,0x24,0x0b,0x05,0x02,0xc2 +,0x80,0xb0,0x50,0x2c,0x67,0x0a,0x85,0x02,0xa2,0x31,0x88,0x8c,0x62,0x67,0x77,0x99,0xc7,0x7e,0xdc,0xea,0xb2,0xf2,0x65,0xaa,0x54,0x91,0x1a,0xbe,0x78,0xae,0xa7,0x75 +,0x7a,0xbb,0xac,0xfa,0x0f,0xbe,0x3f,0x1e,0x4e,0x1a,0xf4,0xe1,0xd5,0xce,0xe7,0xff,0x9c,0x6a,0xed,0xbd,0xab,0xa8,0x39,0xb5,0x43,0x67,0xc3,0xf3,0xbc,0xeb,0xba,0x7a +,0x49,0xba,0xe7,0x4e,0x52,0x4e,0x7e,0xf0,0xc3,0x5f,0x3d,0xfa,0x2f,0xe0,0xb7,0x59,0x6f,0x00,0xae,0xab,0xb4,0x78,0x00,0xf0,0x6a,0x1a,0x6a,0x0e,0x89,0xb5,0x76,0x52 +,0x33,0xd7,0x27,0xe7,0x79,0x98,0x95,0xa1,0x98,0x9e,0xe9,0x0a,0xa2,0xf2,0xc5,0xea,0x4f,0x21,0x43,0xbd,0xcf,0x9e,0x38,0x70,0x0e,0x49,0xeb,0x9f,0xd9,0x65,0x63,0xd6 +,0xe4,0x01,0xe1,0x40,0xe6,0xe2,0xab,0x3f,0x27,0xfc,0x2e,0xff,0xd6,0xc8,0x7a,0x16,0x67,0xba,0x3f,0xfa,0x49,0x90,0x02,0x92,0x8a,0x62,0x93,0x01,0xdd,0xff,0x1c,0xfd +,0x17,0x74,0x9c,0x9d,0xd0,0xee,0x02,0x91,0x2f,0x84,0x02,0xe2,0x24,0xea,0x02,0x01,0x74,0x6e,0x07,0xff,0xf1,0x50,0x80,0x2f,0x7f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xef +,0xff,0xff,0xb0,0x30,0xc0,0x58,0x4e,0x14,0x1c,0x05,0xc2,0xc1,0x80,0xb0,0x50,0x2c,0x14,0x1b,0x05,0x02,0xc1,0x40,0xa8,0x48,0x28,0x15,0x08,0x90,0xc2,0x2c,0x73,0x2b +,0x5f,0x19,0xbb,0xf7,0xeb,0x7f,0x1b,0x83,0x2e,0x52,0x56,0x92,0xa7,0x9e,0x69,0x49,0x15,0xf8,0xbe,0x87,0xea,0x36,0x2c,0x67,0xa3,0xe5,0x8c,0x7b,0x5c,0x4f,0x4b,0xf4 +,0x15,0x76,0x1f,0xd9,0x1d,0xca,0xe2,0x78,0x3c,0x76,0xdd,0xef,0x78,0x75,0x81,0xfb,0x98,0xc8,0xff,0x27,0xd5,0xb9,0x00,0xf3,0xe6,0x93,0x89,0xd4,0x63,0xc6,0xbb,0x34 +,0x1a,0xa1,0x0a,0x12,0x2a,0xfe,0x20,0xad,0x9e,0x53,0xbc,0x30,0xa5,0xdc,0xaf,0x5f,0x6b,0x9f,0xc6,0xe1,0x17,0xec,0x4a,0x18,0x7e,0xcf,0x14,0xcd,0xfe,0xe9,0x1b,0xf4 +,0x11,0xeb,0x38,0x50,0xb6,0x33,0xf3,0x77,0x69,0xdc,0x09,0xdb,0x01,0x23,0xb4,0x13,0x2c,0x88,0x56,0xd4,0xad,0x89,0x22,0x64,0xc1,0x04,0xa2,0x35,0x92,0xaa,0x5b,0x93 +,0x88,0x61,0xb8,0x43,0x02,0x75,0x44,0x54,0x01,0x60,0x54,0x09,0xf4,0x0b,0x11,0xc3,0x01,0x70,0xa0,0x9c,0x2c,0x94,0x0b,0x0d,0xc2,0xa4,0x30,0xa8,0x8c,0x82,0x13,0x0a +,0x84,0x48,0xfb,0x1f,0x5e,0xf5,0xf8,0xfb,0x79,0xe7,0x22,0x97,0x39,0xba,0x35,0x5a,0x5c,0xae,0x37,0x15,0xae,0xbb,0xe3,0x8d,0xcd,0x0f,0xaf,0x55,0xfe,0xfd,0xbd,0x3b +,0xb0,0x4e,0x9e,0x61,0x3d,0xee,0xfa,0xff,0x9c,0xfc,0xb7,0x86,0x9d,0xfc,0x2a,0xb7,0x30,0xa3,0xe5,0x17,0xcb,0xc2,0xdb,0x7d,0x19,0x9f,0x99,0x29,0x4a,0x0e,0xce,0x36 +,0x0d,0xb4,0x27,0x39,0x04,0xfd,0xab,0xe4,0x97,0xd9,0xff,0xd2,0xa4,0xfc,0x3f,0xe4,0xff,0xdb,0x3e,0x1d,0x9f,0x4a,0x44,0x2c,0x38,0x4a,0x24,0xda,0xfa,0x42,0xca,0xd0 +,0x3a,0x0d,0x46,0x7e,0x5e,0x49,0xa3,0xb9,0xc8,0x38,0xa5,0xe5,0x8f,0x68,0x93,0x93,0xaa,0x0b,0x9a,0xaa,0xf8,0x11,0x6a,0xaa,0x2e,0xec,0x1c,0xdd,0xb7,0x1c,0x09,0xf5 +,0xf4,0x5f,0x5d,0xa0,0x03,0xc8,0x28,0x09,0x38,0x64,0xf0,0x0b,0x0e,0xe1,0xef,0xa9,0xfe,0x27,0x78,0xad,0xbd,0x70,0x8a,0x6f,0xd8,0xbb,0x08,0xf5,0xb0,0x85,0x15,0x3d +,0xc0,0x3b,0x83,0xc4,0x00,0x09,0x93,0x2b,0x10,0x04,0x96,0x37,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2d,0xbf,0xfc,0x21,0x2a,0xcf,0xe7,0xff,0xff,0xff,0xf8,0xb0,0x61,0x40 +,0x58,0x30,0x16,0x0a,0x0a,0x04,0x81,0x80,0xa0,0xd8,0x28,0x13,0x0a,0x0c,0xc2,0xa1,0x21,0x20,0x54,0x23,0x07,0x3e,0x7b,0xbf,0x3c,0xdf,0x8b,0xd6,0xfe,0xfe,0x32,0x57 +,0x1b,0xd2,0xae,0xab,0x52,0x4c,0x95,0x26,0xeb,0xf5,0xf7,0x5f,0xde,0xbc,0x8b,0x36,0x7b,0x3b,0xfb,0xcf,0xfb,0xb0,0x83,0xbd,0xd3,0x3d,0x05,0xac,0x01,0xf0,0x76,0xa7 +,0xff,0xe9,0xde,0x0c,0x7a,0xbe,0x27,0xdf,0x6f,0xfd,0xb3,0x45,0x87,0xee,0x11,0x8f,0x2f,0x94,0x3f,0xe2,0x68,0xfd,0xfb,0x90,0x98,0x9a,0x3e,0x81,0xdc,0x9c,0x6e,0xdf +,0xae,0x8f,0xb6,0xaa,0xf4,0x6a,0x6d,0x6b,0x6f,0xed,0x03,0xbb,0x96,0x5b,0xbc,0x7a,0xaa,0xe1,0x12,0x2a,0xc5,0x5c,0x70,0x58,0xc5,0xc2,0xf8,0x90,0x92,0x6e,0x5b,0xd5 +,0xa4,0x64,0xbd,0x29,0x3a,0x55,0x6a,0xb8,0xb2,0xd1,0x2b,0x17,0xd4,0x20,0x74,0xaa,0xd5,0xb1,0x07,0x14,0xef,0x2a,0xc5,0x08,0xad,0x98,0x52,0x60,0x48,0x68,0x30,0xab +,0x25,0xaa,0x2e,0x29,0x50,0x26,0x14,0x02,0x80,0x52,0x20,0x58,0x50,0x16,0x14,0x05,0x06,0xc3,0x40,0xb0,0xd0,0x2c,0x34,0x1a,0x94,0xc2,0x21,0x31,0x89,0x0c,0x42,0x37 +,0x83,0xad,0xf7,0xd2,0x37,0x3a,0xee,0x65,0xe4,0x84,0x9c,0x62,0x6b,0x7e,0x67,0x7c,0x6a,0xb5,0xb2,0xba,0x1f,0x4f,0x9b,0xae,0xcf,0x6e,0x94,0x25,0xd3,0x52,0x21,0xc1 +,0xf9,0xd7,0xf4,0x0f,0xa8,0xd3,0x7d,0xbc,0xb3,0x3c,0xfc,0xf3,0xc7,0xf8,0xbf,0x20,0xc7,0x69,0xf1,0xaf,0x92,0x36,0x6f,0x03,0xe4,0x41,0xfd,0xbf,0xa6,0xc7,0x4e,0xc8 +,0xbd,0xca,0xad,0xf2,0xd9,0x34,0xe8,0x5c,0xc7,0xc7,0x75,0xf9,0x1f,0x8d,0xe6,0xfe,0xd7,0xd1,0xf6,0x5a,0x98,0x9f,0x05,0xa1,0xf5,0xcf,0x7e,0x31,0x77,0xe0,0xb7,0x37 +,0x6e,0xf7,0x5c,0x50,0x1d,0xc3,0x7c,0x94,0xe3,0x68,0x65,0xca,0xb9,0x20,0x31,0xc0,0x4c,0x2b,0xe0,0x26,0x96,0x7b,0xb3,0xf8,0x62,0x5a,0x6d,0x5a,0x50,0xa4,0x1d,0xd1 +,0xdc,0x0b,0x8a,0xda,0xe4,0x7d,0x60,0x77,0x8a,0x0c,0xe0,0x10,0x4c,0x04,0x15,0x77,0xc0,0x3b,0xa4,0x45,0x97,0x10,0x4d,0x40,0xb5,0x40,0xe0,0xff,0xf1,0x50,0x80,0x32 +,0x9f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x44,0x1a,0x30,0x59,0xab,0x36,0x6a,0xae,0x5c,0x95,0x7c,0x08,0x78,0x1f,0xec,0xf3,0x78,0x7d,0x1d,0x1f,0x1f,0x6d,0xe2,0x6a,0x6c +,0xcf,0x6b,0x16,0x8c,0x8d,0x69,0x6a,0xa7,0xfa,0xa3,0x2b,0xaa,0xa9,0x8a,0xdb,0xfc,0x04,0x32,0xd1,0x9c,0x20,0x28,0xc3,0x1d,0x65,0xe8,0xe9,0x31,0x1f,0x59,0x87,0xdf +,0x40,0xec,0x97,0x44,0xd3,0x2f,0x61,0xc9,0x76,0xaf,0xf7,0xba,0x52,0x2a,0x69,0x80,0x8a,0xd2,0x9b,0x6e,0xbb,0x77,0x5e,0x33,0x58,0x09,0x00,0x26,0xf3,0x0c,0xc6,0xe1 +,0x42,0x54,0xb3,0x05,0x45,0x8d,0xf6,0x84,0xfd,0xf2,0x6d,0xd4,0xc5,0x70,0x9c,0x17,0xac,0x5f,0x33,0x42,0x94,0xda,0xa7,0xf8,0xe2,0x7d,0x0a,0x88,0x8b,0xa4,0x5a,0xa6 +,0xe2,0xb1,0xc6,0xaa,0x20,0xae,0x11,0x5b,0xf6,0xe6,0x55,0x48,0x9a,0x52,0x69,0xa0,0x55,0x21,0xa6,0xcb,0xa0,0xb9,0xd5,0x2a,0xfa,0xba,0x66,0x58,0xae,0x84,0x6b,0x6d +,0xb4,0xd4,0xb6,0xc6,0x85,0x34,0x87,0xd7,0x68,0x5f,0x8f,0xd9,0xde,0x04,0x0a,0x83,0x19,0x81,0x6a,0xed,0xe0,0xf1,0x23,0xcf,0x0b,0xc0,0x85,0x0d,0xb1,0x71,0xb3,0xa2 +,0x72,0xc7,0x74,0x50,0x44,0x66,0x88,0x88,0x93,0x24,0xa5,0xdc,0x8d,0x58,0xdf,0xb3,0x11,0x1f,0x47,0x8a,0x36,0xfd,0x85,0x9e,0x5f,0x23,0xe1,0x2a,0xf6,0xaf,0x0d,0x7d +,0x3d,0xc9,0x39,0x6f,0x6c,0x0b,0x21,0xfb,0xa0,0xeb,0x70,0xd7,0xd7,0xb9,0x5b,0xe5,0x50,0x5b,0xd8,0x55,0x4f,0xe8,0xb5,0x43,0x4d,0x0d,0x19,0xdb,0x5b,0x7a,0xec,0xf6 +,0x67,0x9e,0x64,0x58,0xb1,0x70,0x59,0x87,0x09,0x12,0xcf,0xde,0x86,0xb9,0x7b,0xfe,0xfe,0x3f,0x91,0xd3,0x2f,0x2c,0xac,0x89,0x25,0x9a,0xcd,0x33,0x62,0x1b,0xee,0x72 +,0xf4,0xdf,0x83,0x78,0x11,0xad,0xba,0xee,0xb2,0xa2,0xc9,0xa7,0xb8,0x42,0x61,0x32,0x96,0xdc,0xce,0xd3,0x77,0x98,0xa7,0x71,0xad,0x06,0xa8,0xad,0xba,0x9e,0x52,0xee +,0x6f,0x7e,0x83,0x0e,0xaa,0x51,0x55,0xba,0x93,0xfc,0xff,0x0b,0xed,0xff,0x45,0xd1,0xc8,0xe5,0x57,0x36,0x24,0xe9,0xe6,0x73,0x47,0x69,0xe4,0xa5,0xda,0x79,0xfa,0x3e +,0xc8,0xaf,0x89,0xe3,0x82,0xfb,0xcd,0xb2,0x70,0xb9,0x2e,0x1d,0x4a,0x2e,0x66,0x4a,0xec,0x7d,0xd3,0xed,0x5b,0xb1,0x55,0x0b,0x5b,0xa5,0x4a,0x12,0xe9,0x4a,0xd7,0xad +,0xa1,0x1a,0xea,0x86,0x2a,0x14,0x18,0x05,0x2e,0x50,0x44,0x62,0xa9,0xe2,0x0e,0xff,0xf1,0x50,0x80,0x2e,0x1f,0xfc,0x21,0x6a,0xcf,0xef,0xff,0xff,0xff,0xff,0xb5,0x81 +,0x30,0x94,0x28,0x38,0x13,0x09,0x0c,0xa1,0x41,0x28,0x50,0x44,0x41,0x29,0x88,0x50,0x4d,0x6a,0x56,0x39,0xb9,0x2f,0x1c,0x61,0x52,0x2a,0x23,0x55,0xac,0xe3,0x12,0xae +,0xb5,0xae,0x84,0x8e,0x1d,0xae,0xa7,0xfe,0xe8,0xe3,0xc7,0xd8,0xd1,0x7e,0x8f,0xcf,0x1e,0xd2,0xf4,0xc5,0xac,0xae,0xbc,0xb5,0xef,0xcf,0xff,0x2d,0x4d,0xf6,0xa1,0xda +,0x4c,0x7f,0xf5,0xea,0x89,0x7a,0x0e,0xd2,0x2b,0xf0,0xbf,0x1f,0xa4,0x6f,0x8d,0x4c,0x34,0x67,0x2f,0xa6,0xcf,0x63,0x3c,0xd2,0x9d,0xae,0xd0,0x0f,0x9e,0x10,0x2a,0xf5 +,0x59,0xe3,0x99,0xbf,0x1f,0x45,0x59,0xde,0xd1,0x25,0xa5,0x41,0xe1,0xf0,0xc7,0x05,0x39,0x11,0x99,0x5a,0x71,0x9b,0xf8,0x49,0x91,0x34,0x65,0x1a,0x23,0x4e,0x26,0x5a +,0x15,0xa5,0x49,0xdc,0x69,0x89,0x67,0xaf,0x10,0x57,0xd6,0xb1,0xd8,0x49,0x64,0x02,0xb6,0x58,0x15,0x8a,0x2b,0x90,0x66,0x40,0x05,0xee,0x16,0x01,0x40,0x14,0x68,0x17 +,0x0b,0x06,0x02,0x81,0x30,0xb1,0x60,0x28,0x16,0x1a,0x05,0x84,0x81,0x60,0xa0,0x54,0xa2,0x13,0x0a,0x04,0xc8,0x21,0x31,0x88,0x4c,0x42,0x27,0x6e,0x78,0x9d,0xea,0xea +,0xaa,0x49,0x92,0x93,0x2d,0xc5,0x6a,0xb5,0x5c,0xf1,0x97,0x2f,0x72,0xec,0xae,0x87,0x2a,0x79,0xcb,0xc3,0x51,0x13,0xe6,0xbf,0xc2,0x5f,0xfc,0x7e,0x09,0xab,0xa9,0xf9 +,0xdb,0x25,0xad,0x92,0xec,0xcf,0xfc,0xfe,0x79,0x47,0x6c,0xd1,0xbd,0x2f,0xe7,0x4e,0x90,0xaf,0xf8,0xfc,0x9a,0xeb,0x68,0x1e,0xfb,0x7f,0xe3,0xd5,0x52,0xe7,0xff,0x4e +,0xeb,0xfd,0xeb,0xf3,0x0e,0x27,0x47,0xfb,0x3f,0xcf,0xee,0x76,0x8e,0x6e,0x2f,0x85,0xfc,0xbc,0xa2,0xf1,0xf9,0x8b,0x57,0xbf,0xc1,0xc2,0xa0,0x11,0x7e,0x9c,0x4b,0x39 +,0x04,0xb8,0x70,0x72,0x82,0x50,0xb6,0x47,0x85,0xdc,0x77,0x4b,0x72,0x9e,0xe4,0xef,0xe1,0xcd,0xe5,0xd9,0x1f,0xb3,0x27,0x2f,0xfd,0x45,0xb5,0x0f,0x5e,0x76,0x1f,0xfa +,0xc7,0xda,0x2d,0xa7,0xeb,0x24,0x09,0x17,0x46,0x42,0x5d,0xff,0x59,0x43,0xd7,0x5a,0xce,0xf7,0xba,0x02,0x21,0x05,0x0f,0x5c,0x07,0xb8,0x02,0x4a,0x0c,0xa0,0x70,0xff +,0xf1,0x50,0x80,0x30,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0xff,0x7f,0xb1,0x60,0xc0,0x58,0x48,0x36,0x0b,0x89,0x83,0x01,0x40,0xa8,0x98,0x28,0x45,0x11,0x05,0x04 +,0x45,0x10,0x98,0x84,0x46,0x11,0x19,0x84,0x46,0xe7,0xcf,0x3a,0xf3,0xde,0xbb,0xcd,0x67,0x15,0x7b,0xd5,0x26,0x6a,0xa4,0xa4,0xa8,0xeb,0x32,0xe5,0x4a,0xe3,0x7f,0x8e +,0x87,0x99,0x9a,0xe9,0xeb,0xaf,0xf8,0x2f,0x80,0xf3,0x1f,0xd2,0xf0,0x2a,0xfb,0x7f,0x9c,0xa9,0x77,0x9b,0xd0,0xc1,0xcd,0xf9,0x1b,0x5f,0x14,0xf1,0xf5,0xe6,0x5c,0xb8 +,0xd2,0x1c,0x99,0x22,0x70,0xee,0xe7,0x72,0x29,0xd2,0x6c,0xe0,0x15,0x5c,0xa9,0x1d,0xf7,0xef,0xba,0x85,0x61,0xfe,0xf8,0xb5,0x2e,0x19,0x20,0xe2,0xdc,0xb3,0xa7,0xca +,0x12,0xc5,0x6e,0xc7,0xb6,0x73,0x42,0xe4,0xf8,0x1d,0x7e,0xbc,0xfd,0x8d,0x9c,0x29,0xc3,0xda,0x15,0x32,0x9f,0x15,0xfc,0xa5,0xb1,0x23,0x2f,0xe7,0x71,0x5f,0xad,0x13 +,0x1f,0x00,0x19,0xfb,0xda,0x11,0x3c,0xf1,0xad,0xe0,0x2d,0x0b,0xe2,0x54,0x48,0x7e,0xa6,0xe9,0xa1,0x42,0xad,0xe5,0x4a,0xe8,0x88,0x3b,0x8a,0x0a,0x21,0x86,0xe0,0x0b +,0x85,0x40,0xa8,0x40,0xb0,0x50,0x2c,0x74,0x0b,0x06,0x02,0xe1,0x40,0xb1,0xd4,0x28,0x15,0x13,0x85,0x44,0x62,0x51,0x18,0x54,0x42,0x63,0x0b,0x77,0x57,0xe7,0xd6,0xb9 +,0x8a,0x95,0x75,0x5c,0x6e,0x4a,0xd6,0x71,0x9c,0x49,0xb2,0xf9,0x91,0xec,0x8a,0xe8,0x7d,0x66,0x4f,0xef,0xfa,0x7d,0x3e,0x91,0xf4,0xea,0x9c,0xfc,0x2f,0xd3,0x9e,0xad +,0x17,0xec,0x7f,0xae,0x50,0xba,0xff,0xf1,0x9e,0xfd,0x53,0x87,0x7b,0xd3,0xb9,0xff,0xe7,0x97,0xa4,0x6d,0xce,0x9a,0xf9,0xfe,0xb1,0x2a,0x6d,0xb3,0xb9,0x2f,0xfc,0x01 +,0xb7,0x10,0x0c,0x6b,0x04,0xeb,0xd2,0x27,0x6f,0x20,0xaa,0xdc,0x42,0xd8,0x8f,0x03,0xc7,0xc5,0xe1,0xed,0x96,0xfa,0xfb,0xe7,0x7f,0xcc,0x30,0xe4,0xe5,0x5c,0x79,0xa3 +,0x98,0x03,0x6d,0x9e,0x70,0x1e,0xb1,0xc4,0x0f,0x38,0x48,0xe2,0x1e,0xe7,0xff,0xe8,0x54,0x7d,0xa8,0xf5,0xde,0xb7,0x37,0x81,0xcc,0x07,0x00,0x01,0xf4,0x01,0x3b,0x7d +,0x76,0x0f,0x86,0x01,0x30,0xa3,0x80,0xe1,0xe9,0x24,0xa9,0x6a,0x41,0x81,0x7b,0x5a,0x51,0xaa,0x50,0x50,0x02,0xdc,0x85,0x26,0x13,0x98,0x0a,0xce,0x21,0x7e,0xe8,0x1c +,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x0a,0xcf,0xcf,0xfb,0xff,0xff,0xff,0xb4,0x81,0x30,0x50,0x2c,0x15,0x0a,0x0a,0x04,0xe1,0x80,0xa0,0xd8,0x2a,0x14,0x12,0x85 +,0x06,0x46,0x13,0x18,0x44,0xe6,0x9e,0x6a,0xfc,0x6b,0xe7,0xdb,0x77,0x74,0x8a,0xd0,0x54,0x97,0x55,0x2a,0xe3,0x4c,0x2f,0xcf,0xb0,0xf1,0xc5,0x5f,0x9a,0x9a,0x3f,0xfd +,0x1f,0x0f,0x17,0x20,0xde,0x90,0xfd,0x7a,0x01,0xf7,0xd0,0xa3,0x00,0xfe,0x9f,0x57,0xa8,0xb5,0x53,0x1f,0x89,0xba,0xdf,0x47,0x7e,0x6e,0x39,0xf8,0xc7,0xb2,0x7e,0x42 +,0x60,0x0a,0x3b,0x20,0xe1,0x57,0xca,0x5d,0x1b,0xfe,0x33,0x5e,0x45,0x4f,0x66,0x75,0xd3,0x8b,0x44,0x57,0xb3,0xeb,0x07,0x48,0x67,0x0f,0x4b,0x14,0xb7,0xfc,0x84,0xa6 +,0xc2,0x58,0x4f,0xdc,0x14,0x79,0x9e,0x5a,0x54,0xbd,0x12,0x6b,0xdb,0xbe,0xf1,0x50,0xd1,0x55,0x78,0x8c,0x66,0xed,0x9a,0xd8,0x95,0x25,0x34,0xe7,0x5b,0x28,0x42,0xa7 +,0xaf,0x68,0x08,0x05,0x09,0xe3,0x01,0x4a,0x89,0xa2,0x13,0x2d,0x3b,0x80,0x12,0x12,0x02,0x81,0x02,0xc2,0x80,0xa0,0x58,0x30,0x14,0x24,0x05,0x8a,0x82,0x60,0xa8,0x58 +,0x2a,0x37,0x0a,0x88,0xc4,0xa2,0x30,0xa8,0x4c,0x2a,0x13,0x10,0x95,0xf9,0xf6,0xf7,0xe1,0xbf,0xbe,0xdd,0x90,0xbd,0xa2,0x4d,0x73,0xd2,0xa5,0xd2,0xaa,0xbc,0x9b,0xbc +,0xe3,0xd8,0x69,0x54,0xfd,0xbe,0x31,0xa7,0x7b,0x50,0xd3,0xac,0x1d,0x4e,0x8f,0xd8,0x77,0x5c,0xd3,0xe3,0x85,0x80,0x5e,0x90,0x67,0xd9,0x3e,0x85,0x9a,0x7f,0xf1,0x6f +,0x0e,0xfc,0x0c,0xaa,0x0e,0x95,0x7f,0xc3,0x33,0xff,0xdf,0xfb,0x3f,0x09,0xff,0x38,0x70,0xca,0xf5,0xc9,0xc2,0xbe,0x5f,0x3e,0x7a,0x4a,0xfa,0xaa,0x10,0xe0,0x79,0x9c +,0x1e,0x1d,0x4d,0x19,0x4f,0x53,0x8f,0x69,0xc5,0xc1,0xa7,0x2b,0xce,0xa4,0xee,0x03,0x9f,0x20,0x4f,0xc2,0x57,0xef,0x95,0xfc,0x73,0x6a,0xbe,0x07,0xad,0xe2,0x9d,0xc2 +,0xf6,0xf5,0xe7,0xdd,0x07,0x2f,0x07,0xc4,0x48,0x2f,0xc3,0x9f,0xd4,0x71,0x00,0x0f,0xaf,0xf5,0xea,0x13,0xe4,0x4b,0x8d,0x02,0x97,0x47,0xbf,0x74,0x40,0x3c,0x7c,0x00 +,0x7c,0x25,0xd5,0x1e,0xb0,0x81,0x38,0x38,0xe0,0x11,0x24,0xc1,0x52,0x59,0x46,0x62,0xf7,0x28,0x25,0x40,0x38,0xff,0xf1,0x50,0x80,0x2c,0xbf,0xfc,0x21,0x0a,0xcf,0x6f +,0xdf,0x6d,0xff,0xfd,0xae,0x60,0xc0,0x58,0x68,0x15,0x09,0x86,0x08,0xc1,0x40,0xb0,0x90,0x6c,0x12,0x0a,0x18,0x86,0x21,0x30,0x88,0x94,0x42,0x43,0x08,0x89,0xe3,0x4e +,0xa3,0x79,0xbd,0x55,0xa5,0x75,0x55,0x51,0x5c,0x65,0x58,0xe1,0xb9,0xec,0xe6,0x1a,0xe3,0xe8,0x59,0xb6,0x0f,0x4e,0x34,0x6d,0xa3,0x68,0xf6,0xcf,0x87,0xea,0x95,0xd8 +,0x76,0xaa,0xd0,0xa8,0x63,0x30,0x93,0xd3,0x5c,0x9b,0x07,0xad,0xd1,0xbb,0xcd,0xd3,0xdd,0x43,0x96,0x3a,0x8b,0xcf,0xe8,0x33,0xfc,0xef,0x44,0x28,0xca,0x2a,0x4d,0x99 +,0xad,0xcd,0xa2,0x3c,0x79,0x68,0xf2,0xcd,0xaf,0xa2,0x59,0xc6,0xf3,0x39,0x6d,0x11,0x7a,0x42,0x6c,0x5f,0xe6,0x16,0x16,0xb8,0xe7,0xb0,0xba,0xbe,0xae,0x9c,0x55,0x3a +,0x1f,0x80,0x82,0xb4,0xd4,0x68,0x52,0x10,0xfc,0xee,0x2d,0x75,0x87,0x92,0x91,0x80,0x57,0xd7,0x4c,0xa9,0x1c,0x08,0xb0,0x4a,0x84,0xd1,0x88,0xf1,0x00,0x00,0x25,0xe0 +,0x02,0x12,0x28,0x92,0xf6,0x04,0x5a,0x62,0x0b,0x82,0xb4,0x9f,0x78,0x01,0xa8,0x2e,0x02,0xa1,0x85,0x01,0x90,0xb0,0x50,0x2e,0x16,0x0a,0x0d,0x84,0x81,0x61,0x28,0x50 +,0xc6,0x14,0x12,0x84,0xce,0x22,0x30,0x89,0x9e,0x3f,0x9f,0xe9,0xf1,0x3c,0x7f,0x9f,0xe2,0x37,0x75,0x75,0x57,0x53,0x24,0xba,0x71,0xc6,0xef,0x99,0x27,0x11,0x22,0x4e +,0x82,0x6b,0x2f,0x76,0x83,0x97,0xed,0x95,0xac,0xf6,0xb7,0x8f,0xe7,0x2d,0xd3,0x68,0xda,0xb9,0x52,0x5b,0x6f,0x48,0x3f,0x04,0xdc,0xf4,0x3f,0x50,0x92,0xfb,0xe0,0xad +,0xf8,0x3b,0xb5,0xa3,0x3f,0xcb,0x2f,0x43,0xfd,0x8f,0xb9,0xd1,0x39,0x46,0x3d,0x5e,0xf4,0x08,0x97,0xc5,0xf0,0x76,0xbe,0x58,0xa1,0xbd,0x75,0x1e,0x95,0x3f,0xb1,0x05 +,0xe1,0x43,0xb0,0x6b,0x69,0xb3,0xae,0x20,0xfb,0xb1,0x23,0x97,0x33,0x9b,0x2d,0xdd,0xc1,0x1e,0xec,0x95,0x40,0x3e,0xd0,0xee,0x3e,0xe9,0x9c,0x31,0x16,0xff,0x17,0xba +,0x4c,0x10,0x83,0xb8,0x4e,0x47,0xba,0x06,0x30,0x10,0x26,0x7a,0xcb,0x04,0xea,0x04,0xc9,0x82,0xa0,0x56,0x00,0x04,0xcb,0x5e,0xe0,0x70,0xff,0xf1,0x50,0x80,0x2d,0x9f +,0xfc,0x21,0x0a,0xcf,0xcf,0xb7,0xff,0xff,0xfe,0xaf,0x40,0xb0,0x60,0x28,0x26,0x0a,0x0a,0x04,0xe1,0x90,0xa0,0xd8,0x28,0x72,0x0a,0x04,0x88,0xa1,0x30,0x88,0x4c,0x22 +,0xa7,0x7f,0x5e,0x25,0xf5,0x5e,0xee,0x39,0xe2,0xf6,0xe3,0x2a,0xe2,0xa2,0x13,0xa6,0xfa,0xed,0x5c,0x6f,0x55,0x3f,0x5d,0x0f,0x81,0xd7,0xff,0x35,0x2d,0xfe,0xb3,0xf2 +,0xbd,0x83,0xa1,0xb9,0x52,0xb9,0x5d,0x35,0x7b,0x73,0x3b,0xf6,0x2b,0xdf,0x75,0x97,0x19,0xf1,0x47,0x7d,0x7c,0x02,0x9e,0x10,0xdc,0x07,0x2c,0xd2,0x9d,0xad,0xde,0x0b +,0x88,0x0b,0xd0,0x03,0x31,0xe1,0xfd,0xc4,0x95,0x6b,0x7a,0x52,0xf9,0x77,0x78,0x62,0xb3,0x52,0x9e,0x67,0xb5,0xf9,0xc9,0x63,0xc1,0x3c,0xc8,0xf5,0x5c,0xe5,0xbc,0xce +,0x08,0x17,0x0c,0xae,0xba,0x96,0x46,0x6a,0x4c,0x83,0x1f,0x89,0x9b,0x2a,0x14,0x08,0xf7,0xe1,0x09,0x8a,0xf4,0x22,0x81,0xeb,0x2a,0x0a,0x2b,0x3a,0x45,0x54,0x04,0xc1 +,0x1b,0xcd,0x5b,0x02,0xf6,0x07,0x62,0xe1,0x9d,0x00,0x99,0x51,0x20,0x40,0x0b,0x01,0x4a,0x81,0x80,0xb0,0xd0,0x2c,0x24,0x0b,0x11,0x42,0x81,0xa0,0xa0,0x58,0x28,0x16 +,0x11,0x85,0x04,0xa1,0x31,0xa8,0x8c,0x62,0x13,0x08,0x84,0xc2,0x22,0x30,0x88,0xde,0xb8,0xef,0xa9,0xe3,0xf1,0xdc,0xcc,0xce,0x33,0x7c,0x2a,0x24,0xab,0xb9,0xa9,0x8d +,0x4b,0xce,0x37,0xae,0xfa,0xbc,0xb1,0xcd,0xd5,0x9b,0xb9,0xf3,0xd8,0xbc,0x7e,0x48,0xfe,0x3d,0x2a,0xe4,0x5d,0xa3,0x40,0x55,0xf2,0xbe,0xf3,0xfe,0x34,0xeb,0xf4,0x51 +,0x11,0xf6,0x3b,0x6f,0xd4,0x37,0x05,0x01,0x85,0xc9,0xfc,0xd4,0xc4,0xd3,0x9c,0x6a,0x8e,0xe7,0xf1,0x03,0x7e,0x9a,0x9e,0x2f,0xa7,0x65,0x42,0x1f,0xfa,0x7f,0x5a,0xee +,0x5e,0xed,0x70,0xff,0x39,0x77,0x35,0xff,0xe3,0x7a,0xe2,0x98,0xeb,0xae,0x03,0xff,0xb3,0x77,0x87,0x79,0xea,0x90,0xa5,0xfb,0xfd,0xf0,0xb9,0x03,0xb8,0x27,0xb8,0x33 +,0xea,0x2c,0xb0,0x41,0x0e,0xe0,0x3f,0xff,0x00,0x0f,0x75,0x42,0x78,0x00,0x07,0xff,0xed,0xde,0x9f,0x21,0x99,0x20,0x1e,0xe8,0x22,0x29,0x48,0xa6,0xb8,0x7b,0xa7,0x70 +,0x08,0x04,0x82,0xf0,0x03,0x80,0xff,0xf1,0x50,0x80,0x30,0x3f,0xfc,0x21,0x0a,0xcf,0x7f,0xfb,0xfd,0xbf,0x7c,0xae,0x60,0xc0,0x58,0x48,0x26,0x1c,0x0d,0x82,0x81,0x60 +,0xa0,0x58,0x28,0x26,0x09,0x05,0x42,0x83,0x50,0x90,0x94,0x22,0x33,0x08,0x89,0x42,0x24,0x30,0x88,0x9c,0xea,0x9f,0x5c,0xed,0xbb,0xad,0x29,0x2f,0x2e,0xae,0x64,0x25 +,0xdf,0x35,0xc7,0xc7,0xcf,0xb7,0x71,0x5c,0x7f,0xb6,0x82,0x79,0xda,0xff,0xb5,0xfb,0x77,0xd9,0xfc,0x87,0x2a,0x4e,0x3c,0x12,0xff,0xdf,0x3c,0xbd,0xc2,0xc3,0x09,0x97 +,0x2b,0xa7,0x51,0xcf,0xeb,0xde,0xbe,0x4e,0x3e,0x0b,0x57,0x1e,0xff,0x44,0xab,0xc0,0x35,0xa7,0x21,0xaa,0x67,0x7e,0x46,0x12,0xbf,0x04,0x45,0x7b,0xfe,0x7a,0x36,0xed +,0xe6,0xa5,0xde,0x30,0xc2,0x31,0x1a,0xac,0x3c,0xbe,0x25,0x7b,0x81,0x0a,0xbd,0xbe,0x31,0x5b,0xdd,0x87,0x28,0xbe,0x3b,0x56,0x2f,0x4b,0x66,0xbd,0x36,0x08,0xed,0x30 +,0x42,0xd6,0xb4,0xe3,0xae,0xf3,0xd8,0xb5,0x5f,0x06,0x0b,0x9d,0x4b,0x77,0x94,0xb4,0xa3,0x07,0xba,0x17,0x20,0x2d,0xcf,0xea,0x81,0x63,0xc4,0x00,0x16,0x84,0x6c,0x51 +,0x9e,0x42,0x53,0x4b,0xfc,0x02,0xb2,0x07,0xca,0x85,0x7b,0xd5,0x00,0x41,0x20,0x14,0x8a,0x17,0x0b,0x06,0x02,0xc2,0x41,0x30,0x54,0x2c,0x17,0x0a,0x05,0x86,0x81,0x30 +,0xb0,0x50,0x6a,0x14,0x0a,0x85,0x02,0x62,0x50,0x98,0x44,0x66,0x11,0x09,0x84,0x4e,0xfb,0x79,0xf7,0xf3,0xae,0xff,0xf2,0xff,0x8f,0xc7,0xe9,0x29,0xc7,0x8b,0x35,0xcc +,0xd2,0xf9,0xf6,0xb7,0x3f,0xbd,0x71,0xc7,0xfd,0x33,0xf9,0xf6,0xef,0x35,0x34,0x1e,0x99,0xef,0xb2,0xe1,0xeb,0xcc,0x4d,0x9a,0x0f,0xf4,0xbc,0xe0,0xf4,0x77,0x9c,0xdf +,0xf5,0x84,0xd7,0xb7,0xd5,0x7c,0x76,0x29,0xde,0xf7,0xf7,0xdd,0xcf,0xd1,0xb0,0x2f,0xd6,0x1e,0xe7,0xfb,0x67,0xeb,0x16,0xa2,0x67,0xe7,0xce,0xce,0x7b,0xa3,0xfe,0x54 +,0x17,0xfb,0xff,0x44,0x4c,0x0f,0x66,0x33,0x7e,0xb3,0xe0,0x4a,0x73,0xbe,0x28,0xe7,0xc2,0xe4,0xe4,0x44,0xb0,0x02,0x9f,0xaa,0xbb,0xdd,0xee,0x9e,0xba,0x9f,0x0c,0x78 +,0xac,0x40,0x07,0xe6,0x63,0x4a,0xd3,0x69,0x49,0x4c,0x16,0x46,0x00,0x52,0xc0,0x0a,0xbc,0x0b,0xfe,0xb7,0x44,0xc1,0x9b,0x03,0xe1,0x5a,0x0a,0x23,0x00,0x6e,0x00,0x12 +,0x00,0x27,0x70,0x05,0x01,0x20,0x1c,0xff,0xf1,0x50,0x80,0x30,0x3f,0xfc,0x21,0x0a,0xcf,0xef,0xfc,0xff,0xff,0xff,0xb0,0x70,0xc0,0x58,0x88,0x23,0x0c,0x09,0xc2,0xc1 +,0x40,0xb0,0x60,0x2c,0x14,0x0b,0x09,0x02,0x41,0x41,0x18,0x48,0x26,0x12,0x08,0x90,0xc4,0x21,0x31,0x09,0x9c,0xea,0xaf,0xce,0x33,0x9d,0x71,0xde,0xbb,0xf3,0x5c,0x77 +,0xad,0xf1,0x7b,0x95,0xc5,0x5c,0xac,0xd5,0xfa,0xf8,0x6e,0x1f,0x8e,0x83,0xc4,0x6f,0x84,0x3e,0x9f,0x7e,0x99,0x78,0x70,0x4d,0x33,0xa1,0x7f,0x34,0xbd,0x26,0xbe,0x3a +,0xf0,0xb5,0x30,0xf5,0xfb,0x5b,0x84,0xdf,0xd2,0x04,0x50,0xd9,0x7f,0xcd,0x07,0x12,0xe0,0x7b,0x0b,0x96,0xf3,0xfe,0xce,0xff,0x64,0xa2,0x83,0x6d,0x3a,0x22,0xa2,0x0d +,0x41,0xda,0xc9,0x3d,0x19,0x35,0x3d,0x2d,0x73,0x44,0x7a,0xb8,0x52,0xd7,0x8f,0xa5,0x7d,0x37,0xd5,0x36,0xbb,0xd5,0xe4,0xba,0xf8,0xbe,0x1c,0xb6,0x43,0x99,0x73,0x9d +,0x06,0xef,0xf5,0xd7,0x40,0xa4,0x73,0xa8,0xb7,0x0f,0x70,0xb2,0x93,0x4e,0x5c,0x61,0x42,0x87,0x91,0x0b,0xd8,0xf7,0x04,0x8b,0xb3,0x6a,0x17,0xf5,0xc0,0xef,0x85,0x60 +,0x12,0x8c,0xaa,0x50,0xba,0x41,0xcd,0x1a,0x48,0x04,0xc0,0x98,0x14,0xea,0x18,0x0b,0x09,0x02,0xa1,0x80,0xb0,0x4c,0x28,0x16,0x14,0x09,0x84,0xa1,0x62,0x20,0x58,0x2a +,0x34,0x09,0x94,0x44,0x62,0x10,0x98,0x44,0x46,0x11,0x13,0xbd,0x73,0xc7,0x1e,0xbf,0x1e,0xfd,0x78,0xd6,0x15,0x7c,0xf1,0x49,0x2e,0xe6,0xf5,0x75,0x75,0xf1,0x7f,0x37 +,0xf1,0xdf,0x75,0xed,0x34,0x1f,0x23,0x66,0x3f,0x0f,0x66,0xaf,0x83,0xf8,0x95,0xc9,0xfd,0x7e,0x3f,0x37,0xa9,0x3c,0x2f,0x2d,0x7e,0xd9,0x0b,0x37,0x27,0xa5,0x85,0x27 +,0x68,0x8a,0x6e,0x12,0xdb,0xfd,0x6c,0x08,0xe1,0xe2,0xe1,0xd1,0x6c,0xa2,0xdd,0x9b,0xe2,0xda,0x06,0xea,0x76,0xd0,0x92,0x0d,0xbc,0x30,0x14,0x9b,0x94,0x56,0xfa,0x50 +,0x45,0x9d,0xa5,0x50,0xa3,0x9f,0x6f,0x9d,0x81,0xc1,0xc7,0x8c,0x2f,0x80,0x7a,0x39,0x8a,0x05,0x05,0x5e,0x99,0xfc,0x75,0x3b,0xda,0xdd,0xf2,0x9a,0xbf,0xfa,0x43,0x5f +,0xbd,0x0b,0x26,0xdb,0x7b,0xe0,0x77,0x8f,0xb4,0x1e,0xe9,0x32,0xa0,0x93,0x3a,0xbd,0xab,0x6b,0xa6,0xaf,0xbb,0xc0,0x7a,0xc1,0x40,0xa9,0xdf,0x00,0x2f,0x62,0xa9,0xe8 +,0x28,0xca,0x3d,0xd0,0x90,0x09,0x80,0xe0,0xff,0xf1,0x50,0x80,0x2d,0x5f,0xfc,0x21,0x2a,0xcf,0xff,0xff,0xee,0xff,0xfd,0xaf,0x81,0x30,0xd4,0x28,0x26,0x0c,0x06,0x82 +,0x81,0x60,0xa0,0x98,0x28,0x16,0x0a,0x10,0x84,0xa1,0x21,0x18,0x84,0x46,0x31,0x09,0x88,0x4c,0xef,0x8c,0x9d,0x6e,0x57,0x3c,0x4a,0xbd,0xa5,0x70,0x2a,0x6a,0x9a,0xbb +,0xdd,0xc7,0x7c,0x5e,0x46,0xbc,0xfb,0x00,0x6a,0xa6,0x73,0x57,0x4d,0x5d,0xda,0x31,0xfc,0x9a,0x43,0x4d,0xa6,0xc1,0x7f,0xde,0x10,0x07,0x03,0xa6,0xd2,0x09,0x5f,0x83 +,0x1f,0xfc,0x67,0x7b,0xfd,0x4b,0x4c,0xf4,0x19,0x9f,0xfa,0x33,0xbf,0x49,0x42,0x71,0x7f,0xee,0xc9,0xf7,0x58,0x69,0x85,0xbf,0x70,0x49,0xa6,0x7d,0xf8,0x7c,0x3b,0xf7 +,0x78,0xa9,0xbf,0x4d,0x1a,0xc7,0x86,0x68,0xb4,0xa9,0x8c,0x65,0xd0,0x48,0x69,0x3b,0x43,0x8e,0xff,0xaf,0xde,0x10,0x8d,0xbb,0x80,0x94,0x91,0x8c,0x4a,0x4d,0x36,0xbf +,0x5f,0xba,0xb8,0x1e,0xb2,0x80,0xf7,0x50,0x2d,0x33,0x62,0x32,0xa4,0x0e,0xf8,0x77,0x00,0x12,0x58,0x2b,0x12,0x88,0x81,0x28,0xda,0x82,0x42,0x64,0x84,0xc0,0x52,0xa8 +,0x58,0x68,0x16,0x3a,0x05,0x85,0x01,0x40,0xb0,0xd0,0x2c,0x25,0x23,0x84,0xc2,0xa1,0x20,0x88,0x94,0x26,0x11,0x43,0xbb,0xdf,0x58,0xb7,0x7c,0x55,0xe5,0x22,0xb5,0x92 +,0xb5,0x19,0xf1,0xb5,0x71,0x77,0xe3,0xac,0xc9,0xaa,0xf3,0x03,0xdb,0x1f,0xb7,0x97,0x0d,0xfd,0x3f,0xae,0xe9,0x49,0x77,0xfe,0x05,0x3e,0x3e,0x19,0xfb,0x63,0x2e,0x6b +,0xcd,0xbd,0xac,0x7c,0x0f,0x2d,0xf7,0xbd,0xbd,0x98,0x27,0x58,0xb7,0xa1,0xfe,0xb3,0xf9,0x09,0xe3,0x18,0xd4,0x7e,0x9e,0xae,0x2f,0x95,0xa1,0x96,0x82,0x25,0xfd,0x6b +,0xae,0xec,0xb1,0x63,0x3c,0xab,0x6d,0x92,0xfc,0xd5,0xcd,0x74,0x3e,0x8b,0x9e,0x3e,0x1c,0x1d,0xb1,0xe4,0x47,0x2e,0x02,0x3b,0xa7,0x69,0x43,0x90,0xb9,0x3e,0x51,0xc2 +,0x6b,0x98,0x53,0xce,0x50,0x3b,0x8f,0x68,0x9e,0x30,0x30,0xec,0x70,0x84,0x8c,0x02,0x8c,0x46,0xa8,0xdc,0x60,0xe2,0x05,0x2d,0x50,0x00,0x03,0xc0,0x0e,0xf7,0x78,0x06 +,0xe3,0x90,0xab,0x98,0x22,0xa4,0x2c,0x2d,0x38,0xad,0x70,0x27,0x30,0x03,0x9a,0x55,0x03,0x80,0xff,0xf1,0x50,0x80,0x34,0xff,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x3c,0x26 +,0x30,0x59,0x23,0x52,0x28,0xba,0xd1,0xa9,0x52,0xc6,0x74,0xfa,0x8f,0x3e,0x7e,0xbb,0xfe,0x56,0x66,0x93,0xa2,0xdb,0x64,0x54,0x46,0xad,0xa9,0x46,0x40,0xb8,0x63,0xd6 +,0x21,0x86,0xf7,0x35,0xf8,0xcc,0x79,0x31,0xf6,0xff,0xbc,0xfa,0xb1,0xd1,0x4f,0x9a,0xfa,0x7b,0x69,0xca,0xfe,0x2d,0x9c,0x96,0xb0,0x32,0xe1,0xb0,0x23,0x43,0x06,0xb8 +,0xd5,0x0c,0x08,0x4c,0x1c,0xaf,0xca,0x79,0xf4,0xc6,0x72,0x95,0x2b,0x9c,0xf0,0xaf,0x1b,0x2b,0xda,0x07,0xd7,0x70,0xd4,0xb7,0x25,0xa8,0x2a,0x68,0xb5,0xe8,0x8e,0xb5 +,0xf1,0xab,0x52,0x33,0x9f,0x19,0x13,0xa3,0x35,0x76,0x81,0xa5,0xbd,0x00,0x6d,0xdd,0xff,0x69,0xb3,0xff,0x0b,0x55,0x6a,0x16,0x56,0xb6,0x17,0xd2,0xaa,0x92,0xb9,0xab +,0x7f,0x6c,0xc8,0xf5,0x6a,0x78,0xdf,0xa3,0xd4,0xd6,0xb2,0x5b,0x1f,0x3b,0xa4,0x99,0x12,0xd3,0xc1,0x9a,0xf0,0xc9,0x57,0xd3,0x58,0xd0,0x63,0x2b,0x84,0xca,0xd5,0xcf +,0x90,0xa4,0x2a,0x0d,0x2a,0x11,0x44,0xd6,0xac,0xc5,0x1b,0xe8,0x9c,0x69,0x14,0x51,0xe2,0xaf,0x9f,0x0f,0x4a,0x43,0x8c,0x13,0xb9,0xa0,0x40,0x4e,0xc5,0xf3,0x10,0xc8 +,0x61,0xd0,0x64,0x89,0x43,0x46,0x0b,0x18,0x2d,0x10,0x99,0x42,0x65,0x6c,0x92,0xe4,0xeb,0xbb,0x0c,0xd4,0xef,0xa6,0x0a,0x6f,0x84,0x0f,0x36,0x12,0x89,0x9e,0x05,0x9b +,0xd5,0xa3,0x77,0x3a,0x56,0x6c,0x94,0x1a,0x9b,0x46,0x4b,0x55,0xa3,0x0a,0x71,0x6d,0xc7,0xf5,0xea,0xdb,0x1e,0xcf,0xdb,0x4f,0xab,0xc2,0xeb,0x03,0xe4,0x7a,0x8b,0xac +,0x64,0xba,0x81,0x7e,0x42,0x05,0x82,0x4d,0x72,0x79,0x05,0xe9,0x72,0xf2,0x7a,0xf9,0xb2,0xff,0x76,0xed,0xec,0xf8,0x4f,0x46,0x8b,0xe5,0x67,0xbd,0xc4,0x2e,0xce,0xd9 +,0x29,0x98,0x70,0xd5,0x3f,0x8b,0xc5,0xfd,0xf5,0xc7,0x4d,0xad,0x74,0x7d,0xa4,0xa1,0x88,0x32,0x86,0x0f,0x09,0xf4,0x86,0x98,0xad,0x26,0x29,0x13,0xd8,0x1c,0x02,0xcb +,0xcc,0x66,0x35,0x14,0x9c,0x81,0x4c,0x12,0x9e,0x28,0x24,0xcb,0x0a,0x50,0xa1,0xb1,0x60,0xc2,0x14,0x8d,0x61,0x9a,0xb8,0x95,0xff,0x2e,0x37,0x36,0x1c,0x7a,0xd3,0xf8 +,0xf3,0x4d,0x8f,0x1e,0xb5,0xf1,0xb8,0xde,0x2b,0x54,0x4b,0xf0,0x12,0x00,0x13,0xcf,0x4e,0xaf,0x5b,0xa5,0x7b,0x2a,0x6a,0xca,0xfb,0x4f,0x49,0xeb,0x62,0xa7,0xf2,0xb3 +,0xaa,0x28,0xcd,0x5a,0x6b,0xce,0xe3,0x55,0xb0,0xf2,0xc8,0xe0,0x21,0xa2,0x57,0x60,0xa6,0x03,0x83,0xdb,0x1c,0x5e,0x5c,0x84,0x4e,0xff,0xf1,0x50,0x80,0x30,0xbf,0xfc +,0x21,0x6a,0xcf,0xef,0xfd,0x7f,0xfd,0xff,0xb1,0x60,0xc0,0x58,0x88,0x16,0x1c,0x85,0x04,0xc1,0x40,0xb0,0x50,0x8c,0x25,0x0b,0x05,0x02,0xa2,0x21,0x18,0xc5,0x6c,0x9a +,0xc7,0x5c,0xb8,0xef,0x52,0x37,0x74,0xae,0x32,0x53,0x53,0x1f,0x0d,0xee,0x97,0x79,0xaa,0x7d,0x79,0x0f,0xf3,0x4b,0x59,0xf2,0xe2,0xdf,0xad,0x38,0xf9,0x5f,0x7a,0x3f +,0x77,0xd9,0xef,0xd5,0xe9,0xd1,0x7a,0xbf,0xc6,0xf2,0x37,0xee,0x37,0xae,0xd1,0x4d,0x21,0xf2,0x9e,0xcb,0x88,0x51,0xfd,0x93,0x74,0xf4,0x7f,0x7f,0xc6,0x3b,0x0f,0x9b +,0xdb,0xfc,0xaf,0x41,0xa0,0x52,0xfb,0xf9,0x7c,0x19,0x06,0xa4,0x13,0x5f,0xdf,0xce,0x73,0xa3,0xa2,0xd1,0xcc,0x50,0x95,0x79,0x0a,0x5f,0xf2,0x28,0xb5,0xdc,0x95,0xe8 +,0x9b,0x39,0x4d,0xdd,0x97,0x9f,0x0e,0x4b,0x39,0x96,0xa2,0xf6,0x5b,0x2e,0x56,0x6f,0xae,0x22,0x7a,0x70,0x99,0xee,0x10,0x1e,0xea,0x69,0x9e,0xb9,0x42,0x2e,0x56,0xb4 +,0xea,0x51,0x77,0xa4,0x94,0xa9,0xf0,0xc1,0x24,0x5a,0x2d,0xb0,0x9c,0x20,0x58,0xed,0xdd,0x52,0xc8,0x2e,0x56,0x42,0xf2,0xc8,0x1b,0x4a,0x54,0xb8,0x05,0x40,0x9e,0x40 +,0xb0,0x50,0x2c,0x38,0x0b,0x19,0x42,0x81,0x60,0xa8,0x58,0x50,0x15,0x0b,0x05,0x44,0x81,0x51,0x18,0x54,0x86,0x11,0x09,0x90,0x42,0x61,0x11,0xbf,0xaf,0x1c,0xeb,0x2b +,0xe3,0xbe,0xb9,0xad,0x6e,0xa5,0xf3,0xc7,0x7c,0x55,0xcc,0xd6,0xab,0x8d,0xce,0xb9,0x64,0x8c,0xea,0xbc,0xd8,0xe0,0xa9,0xfc,0x7f,0xcc,0xfe,0x09,0xbf,0x5d,0xd5,0x07 +,0x51,0xe4,0x93,0xd3,0x03,0xcf,0xd4,0x36,0xc9,0x4b,0x63,0xc7,0xa5,0xf0,0x3d,0xb9,0xf9,0xb8,0x1f,0xde,0x5f,0x57,0x40,0x73,0xf3,0x63,0x56,0xce,0x9e,0xa3,0x6f,0x91 +,0x08,0x4e,0x4d,0xee,0x6b,0x32,0x0d,0xe1,0x3c,0x3e,0x03,0x05,0xef,0xd9,0x44,0xb6,0x1c,0xfe,0xfe,0x2e,0x2a,0xe1,0x36,0xdf,0xbf,0x96,0x5f,0x0b,0xfe,0xe4,0xfe,0x5d +,0xa9,0xe2,0x37,0x1c,0x4f,0x1e,0x47,0x10,0x77,0xfc,0x12,0x8f,0xf5,0x15,0x58,0x03,0xde,0x00,0x91,0x43,0xcb,0xee,0x04,0xbc,0x41,0xcc,0x2c,0x79,0xd8,0x00,0x24,0xee +,0xfa,0xc1,0x4e,0x53,0x90,0x4e,0x54,0xf7,0x47,0x75,0x5f,0x5a,0x03,0xba,0x2c,0x0b,0x7a,0xc3,0xa2,0x65,0x43,0xdc,0x02,0x24,0x6e,0x26,0x09,0xe9,0x01,0xc0,0xff,0xf1 +,0x50,0x80,0x30,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0xdf,0xfe,0x7f,0xff,0xaf,0x60,0xc0,0x9c,0x2c,0x17,0x0a,0x05,0x87,0x21,0x40,0xb0,0x50,0x4e,0x14,0x0b,0x05,0x02,0xc2 +,0x40,0xb0,0x5c,0x2a,0x11,0x0a,0x84,0xc8,0x41,0x15,0xbb,0xf3,0x8a,0xf6,0xee,0x75,0xef,0xc6,0xf5,0x79,0x32,0x6f,0x57,0xbe,0x32,0x5c,0x8e,0x3d,0x0a,0xb7,0xd7,0x37 +,0xe6,0xc4,0x6d,0x87,0x9b,0xbb,0x42,0x7b,0x8f,0xc4,0xfd,0xf4,0xf5,0x23,0xaf,0xcb,0x45,0x1f,0xf3,0xe0,0x62,0xe7,0x82,0xe1,0x09,0x76,0xcd,0xcd,0xfa,0xff,0x27,0x91 +,0x6a,0x79,0xd4,0x27,0x56,0x93,0xc7,0xac,0xa5,0x87,0xf0,0x7f,0x84,0x4f,0x2a,0x5c,0x46,0xd0,0x50,0xdb,0xbf,0x59,0xa3,0xe2,0xd0,0x0e,0x5a,0x18,0x98,0x88,0x87,0xb7 +,0x55,0x39,0xb2,0xe4,0xfb,0xf0,0xea,0x51,0xec,0xf5,0x56,0xc5,0xed,0x0b,0xf6,0x25,0x22,0x1e,0xfe,0x5c,0x5e,0xeb,0xd9,0xbb,0x71,0xcc,0xa8,0x87,0x72,0x3b,0x8f,0x74 +,0x04,0x31,0x6c,0x12,0x8a,0x2d,0x74,0xc6,0x4e,0xe7,0xa3,0x87,0x51,0x96,0x3a,0xda,0xd6,0x82,0x6a,0xc2,0x5a,0x2f,0x3c,0x51,0x14,0xd8,0x9b,0x44,0x53,0x02,0x28,0x93 +,0x20,0x10,0x90,0x4c,0x08,0x80,0xa6,0x40,0xb1,0x1c,0x2c,0x14,0x0b,0x09,0x44,0xc1,0x80,0xb0,0x90,0x2c,0x54,0x12,0x85,0xc2,0xa1,0x70,0x88,0x54,0x26,0x15,0x18,0x85 +,0x42,0x61,0x50,0x89,0x5b,0xbd,0xde,0x67,0x19,0xc6,0xe5,0x63,0x54,0x99,0x2e,0xa3,0x54,0xfd,0x7e,0x6e,0xe9,0xaa,0xdf,0x15,0x7a,0xde,0x87,0x0f,0x7f,0xaf,0x7c,0x55 +,0xf4,0xe1,0xf2,0xf6,0x69,0xbe,0x9f,0x38,0xee,0x4e,0x03,0xfd,0x7c,0x2d,0xe2,0xe7,0xe2,0x83,0xf3,0x5a,0x21,0xef,0x18,0xcb,0x66,0xdd,0x7a,0xb2,0x0f,0x8a,0x72,0x5b +,0xfc,0x50,0x53,0x59,0x10,0xfc,0x33,0xa3,0x96,0x3e,0xab,0xc6,0xb9,0xc0,0xbb,0x96,0xab,0xf8,0x6a,0x2a,0x4c,0x8b,0xb7,0xe1,0xc8,0x22,0xf5,0x7e,0x5f,0x7c,0xe9,0xf2 +,0xaf,0xdd,0xdf,0x3a,0xe4,0xe2,0x54,0x87,0x99,0xd0,0x0e,0x7f,0x11,0xcf,0x8b,0x90,0x1e,0xb6,0xd6,0xf3,0x73,0x72,0xd1,0xc8,0xb8,0xe1,0xc0,0xf2,0x04,0x0e,0xef,0x98 +,0xf7,0x01,0xe0,0x00,0x00,0x01,0xc8,0xf3,0x00,0x1c,0x0f,0x10,0x10,0xc4,0x83,0xcc,0x00,0x00,0x7b,0xbd,0xe0,0x01,0xe0,0x00,0x89,0x61,0x51,0x02,0x09,0x81,0x51,0x03 +,0x50,0x1c,0xff,0xf1,0x50,0x80,0x2f,0x9f,0xfc,0x21,0x0a,0xcf,0xef,0x7f,0xf7,0xff,0xff,0xb0,0x61,0xc0,0x58,0x48,0x16,0x1c,0x85,0x02,0xe1,0x41,0x30,0x50,0x2c,0x14 +,0x0b,0x05,0x04,0xc1,0x50,0xa0,0x54,0x26,0x22,0x09,0x84,0x82,0x22,0x30,0x88,0x48,0x22,0x13,0x08,0x84,0xc2,0x23,0x32,0x35,0x7f,0x1f,0x9b,0xdd,0xf1,0xb5,0xd5,0x4a +,0xae,0x32,0x2e,0x5f,0x3d,0x76,0xae,0xb9,0x3d,0xb3,0xce,0x7e,0xb0,0x17,0x6e,0xdb,0x3f,0x96,0x3f,0x5b,0x2e,0xfe,0xc5,0xf1,0x64,0xd7,0xea,0x41,0xea,0xf9,0x56,0x76 +,0xdb,0x75,0xce,0x31,0xe4,0x7d,0x08,0x2b,0xc5,0xd1,0x4b,0xc4,0x4f,0xbd,0xde,0x28,0x93,0x96,0xc6,0x7f,0xc1,0xeb,0x68,0x23,0xc5,0x1e,0x0f,0x57,0xf7,0x7e,0xce,0x6e +,0x0d,0xde,0x68,0x84,0xee,0xa2,0xd1,0x28,0x4c,0xa7,0xbb,0xf4,0x08,0xdd,0xcf,0x2f,0x98,0x60,0xdc,0x51,0x8b,0xf1,0xde,0xda,0x59,0x9e,0x7f,0xb8,0xfe,0x5f,0xae,0x0b +,0x53,0x99,0xdc,0xc1,0x52,0xee,0x0f,0x71,0x31,0xe7,0xdc,0x62,0x40,0xa7,0xf3,0xbf,0x12,0x91,0xa0,0xdb,0x4e,0x30,0xf1,0x13,0xf7,0xef,0x70,0x89,0x3d,0xb3,0xc5,0x18 +,0x4e,0xf4,0xc0,0xc9,0x64,0x11,0xb2,0xd0,0x99,0x43,0xd6,0x39,0x82,0x11,0xf7,0x45,0x00,0x52,0xc5,0xe0,0x02,0x20,0x4d,0xa8,0x58,0x4e,0x14,0x0c,0x09,0x8e,0x81,0x30 +,0xa0,0x58,0xc8,0x15,0x11,0x84,0x42,0xa2,0x12,0x18,0x84,0xef,0xe9,0x7b,0xbc,0x7d,0xfe,0x7f,0x7f,0xce,0xf8,0xaa,0xb5,0x25,0x45,0x75,0x73,0xce,0xf7,0xe6,0x63,0x7b +,0xe2,0xf8,0x4a,0xf2,0x3a,0x17,0xe9,0xa7,0x47,0x75,0x3f,0xd4,0x74,0x43,0x3e,0xc7,0xe3,0xf7,0xf5,0xb5,0x5d,0xff,0xb1,0x15,0x5a,0x2c,0x6f,0xa0,0x5b,0x77,0x52,0xf1 +,0xe6,0x9a,0x07,0xfd,0xff,0xad,0xfd,0x77,0x40,0xdd,0x65,0xed,0x5a,0xa8,0x3e,0xab,0x86,0x1d,0x07,0xbd,0xe1,0xac,0xd8,0x41,0xc5,0xe2,0xb1,0x24,0xf7,0xa0,0x6b,0xa8 +,0x24,0xde,0x67,0x10,0x77,0xcf,0xfe,0xd7,0x4b,0xfe,0x7e,0x0e,0xc0,0xf9,0x94,0x16,0x75,0xf8,0x83,0xbf,0xef,0x90,0x8c,0xa0,0xa0,0x0f,0x10,0x0e,0x67,0x80,0x28,0x12 +,0xb5,0x42,0x79,0x13,0xb8,0x02,0x54,0x05,0xae,0x40,0x57,0xbd,0x58,0x29,0x73,0xd7,0x08,0x54,0x88,0xb9,0x50,0x9d,0xc2,0xe0,0x09,0x00,0x90,0x12,0x03,0x80,0xff,0xf1 +,0x50,0x80,0x2e,0x7f,0xfc,0x21,0x0a,0xcf,0xef,0xaf,0xef,0xff,0xec,0xae,0x70,0xc0,0x58,0x30,0x27,0x0a,0x04,0xc2,0x81,0x81,0x20,0xd8,0x48,0x26,0x12,0x05,0x84,0x81 +,0x22,0x28,0x45,0x06,0x31,0x1b,0xb6,0x95,0xe7,0x8f,0xb7,0x5d,0xf1,0x78,0xab,0xa1,0xad,0xea,0xb8,0xda,0xf1,0x74,0xba,0xbb,0xba,0xe7,0xfe,0x78,0x0f,0x4d,0x83,0xf0 +,0xf3,0x38,0xf5,0x59,0xe1,0xef,0x67,0x7e,0xfe,0x2f,0xf0,0x8f,0xb1,0xe0,0xb0,0x5b,0xbb,0x4e,0x5d,0xdc,0x6c,0x56,0xff,0x1b,0xf0,0xd0,0x79,0x69,0x13,0x11,0xa0,0xe3 +,0xe4,0xfb,0xd0,0x6c,0x91,0xc4,0x5b,0xb4,0x48,0xcf,0x4b,0x79,0x64,0xb9,0x9c,0xe6,0x28,0x68,0xa7,0xc6,0x60,0x45,0xb1,0x73,0xd0,0x2b,0xc5,0x29,0xa3,0x8d,0xac,0x32 +,0x30,0x68,0x5e,0xa3,0xc1,0x09,0xf8,0xa5,0x28,0x86,0x62,0x9b,0x00,0xd2,0x6b,0xb8,0x6b,0xd3,0x93,0x29,0x4a,0x20,0x66,0xc3,0x90,0xb5,0x18,0x51,0x84,0xfd,0xca,0xe7 +,0x95,0x81,0x3b,0x77,0xd8,0x1f,0xa4,0xb0,0x21,0xd1,0x10,0x1d,0x4e,0x2f,0x3b,0x4c,0xa0,0x77,0xc1,0x07,0x78,0x0e,0xf1,0x5c,0x48,0x05,0x80,0x54,0x20,0x58,0x28,0x16 +,0x1b,0x85,0x88,0xe1,0x80,0xb0,0xd0,0x2c,0x35,0x0b,0x09,0x44,0x81,0x50,0x98,0x44,0x26,0x35,0x09,0x85,0x42,0x61,0x10,0x98,0x44,0xac,0xc9,0xc7,0x39,0xe7,0x9f,0xbf +,0xda,0x64,0xad,0x55,0xe1,0x17,0x6b,0xd6,0xb3,0x77,0xac,0xe3,0x7c,0xf1,0xaf,0x3f,0x77,0x03,0xf3,0xfa,0xed,0xfe,0x85,0xee,0xd2,0xbd,0xdd,0x09,0xee,0x0f,0xdf,0xb2 +,0x0f,0x67,0x62,0xd7,0x6b,0x52,0x3d,0x59,0x65,0xfe,0xb7,0xb5,0x9c,0xb7,0x84,0xd4,0x6b,0xae,0x8d,0x4d,0xf6,0x7d,0x7c,0x9a,0x92,0xc6,0x0e,0x21,0xc9,0x9c,0xf0,0xed +,0xd9,0xc4,0xd9,0xe1,0x7e,0x33,0xc2,0xfb,0x04,0x25,0x14,0xd6,0x78,0xf5,0xd1,0x40,0x80,0x41,0xf0,0xe5,0x6e,0xca,0xd4,0x38,0xaa,0x1f,0x03,0x9f,0xe3,0x85,0x5a,0x35 +,0x2a,0xac,0x5e,0xbc,0x47,0xac,0x1f,0xfa,0x18,0x4c,0xdd,0x2e,0x51,0x72,0x7e,0xe5,0xbb,0xe4,0xcf,0xdf,0x3b,0xe3,0xba,0x00,0x3c,0x40,0x3d,0xc1,0x60,0x00,0xf2,0x00 +,0x43,0xb9,0x01,0x1a,0x4e,0xa7,0x78,0xf7,0x4a,0x02,0xa0,0x4c,0xa8,0x04,0xc0,0xa8,0x0e,0xff,0xf1,0x50,0x80,0x30,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xfe,0xbd,0xff,0x3c +,0xaf,0x82,0x30,0x60,0x2a,0x16,0x12,0x05,0x42,0xc1,0x40,0xb0,0x90,0x2c,0x14,0x0a,0x85,0x06,0x42,0x40,0x90,0xcc,0x6a,0x23,0x08,0x84,0xc2,0x27,0x72,0xeb,0xc5,0xdf +,0x9f,0x1e,0xdc,0xae,0xb1,0x2a,0x4c,0xb4,0xbc,0xba,0xea,0xbc,0xd3,0xbf,0xbf,0xad,0xe6,0xaa,0x7f,0x88,0x15,0xc9,0xf1,0x55,0xea,0xc9,0x1e,0x9b,0xe3,0xb7,0xf0,0x79 +,0xeb,0xab,0x5f,0x71,0xe9,0x4f,0xaa,0x55,0x41,0xaf,0x0d,0xd3,0xcf,0xbd,0x17,0x5f,0x03,0xa1,0xbe,0x09,0x13,0x1f,0x12,0xd0,0x5f,0x84,0x4d,0xde,0xf4,0xcb,0xb3,0xb6 +,0x25,0xac,0xbe,0x07,0xdd,0xf9,0x1c,0xdb,0xa9,0x22,0xbf,0xee,0x78,0x9b,0xd9,0xe8,0xde,0x5f,0x2f,0x72,0x19,0xf0,0xa9,0xdb,0xd1,0x85,0xad,0x44,0x11,0xe4,0x27,0xf8 +,0x46,0x7e,0xc3,0xa3,0x49,0x58,0xa3,0xde,0xbb,0xea,0x16,0xbc,0x4f,0x5c,0x9d,0x03,0xcc,0x00,0x00,0x00,0x78,0x8c,0xde,0xc9,0x09,0x86,0x59,0x80,0x7f,0xe9,0x17,0xa2 +,0x45,0x13,0x0b,0xce,0x70,0x02,0xe4,0x11,0x4e,0x94,0x5e,0x63,0x8a,0xe6,0xe4,0x40,0x52,0x31,0x60,0x2e,0x15,0x0b,0x05,0x03,0x01,0x62,0x20,0x58,0x2e,0x16,0x0a,0x05 +,0x82,0x81,0x50,0xa0,0x54,0x28,0x15,0x08,0x84,0xc2,0xa2,0x70,0x88,0x4c,0x22,0x15,0x28,0x8d,0xef,0xc6,0xf8,0xe6,0x6b,0x7d,0x63,0x64,0xcb,0x54,0x92,0xe6,0xf8,0xfc +,0x7b,0xd5,0xcf,0x8f,0xb7,0x9f,0x5a,0xe0,0xfb,0xdd,0x02,0xfd,0x6f,0xdb,0xf8,0xaf,0x2e,0x9a,0x36,0x74,0x4c,0xf0,0x1f,0x4f,0x09,0xfe,0xbb,0xab,0x6d,0xc1,0x55,0xaf +,0xf5,0x84,0xdf,0xa1,0xf3,0x94,0x96,0x70,0x4d,0x25,0xff,0x5e,0xc7,0x6f,0x7f,0x78,0x43,0x67,0x54,0xf1,0xea,0x3d,0x74,0x06,0xaf,0xea,0x5f,0xde,0xf2,0xb9,0x71,0x7b +,0x29,0x3f,0xb6,0x68,0xef,0xf8,0x68,0x1b,0xe1,0x4e,0x4e,0x8e,0x5b,0xaf,0xfb,0x88,0x2d,0xe7,0xa3,0x54,0xea,0x73,0x0f,0xd1,0x3a,0x03,0x2e,0x61,0xce,0x5c,0x78,0x44 +,0x47,0x07,0x68,0xf2,0x86,0x08,0x8f,0x75,0xee,0x02,0xc7,0x98,0x1e,0x7e,0x21,0xc0,0x1c,0x6c,0x1e,0x70,0x09,0x00,0xb5,0x40,0x3b,0xbd,0xf9,0x02,0x2a,0x40,0x03,0x8f +,0x98,0x0f,0x00,0x2c,0x03,0xc8,0x00,0x3c,0xc0,0x00,0x00,0x3c,0x80,0xbc,0xee,0x05,0xc2,0x80,0x38,0xff,0xf1,0x50,0x80,0x2e,0xdf,0xfc,0x21,0x2a,0xcf,0xff,0x7f,0xff +,0xff,0xfd,0xb0,0x70,0xc0,0x98,0x30,0x24,0x23,0x05,0x08,0xc1,0x40,0xb0,0x50,0xa4,0x25,0x09,0x08,0xc2,0x21,0x30,0x88,0x4c,0x42,0x33,0x08,0x95,0x93,0xaf,0x57,0xc6 +,0x55,0x8b,0xaa,0x82,0x49,0x57,0x7b,0xbf,0x3c,0xf1,0x97,0x55,0x37,0xd7,0x3c,0x6f,0xf7,0xe8,0x57,0xda,0xf1,0x52,0xd2,0x1b,0xc7,0x85,0x76,0x93,0x86,0x5f,0xeb,0xbf +,0x2e,0xf8,0xe6,0xd1,0xe7,0x98,0x0f,0xf8,0xfd,0x8f,0xe2,0xbf,0xb3,0x7b,0xe6,0xfe,0x78,0x46,0xd2,0x48,0xe7,0x3b,0xc3,0xf1,0x26,0xa1,0x3c,0x2f,0x86,0x53,0xf2,0x51 +,0xfb,0xc4,0x75,0xfb,0x7a,0xbc,0x3a,0xd5,0x83,0xf7,0x2b,0xdd,0xfc,0x3a,0xdb,0xcb,0xb3,0xc5,0xee,0xbc,0x94,0xcf,0x3b,0x25,0x84,0xac,0xcd,0x04,0x1b,0x73,0x49,0xda +,0x81,0xb0,0xfd,0xc2,0x56,0x57,0xf8,0x4f,0x00,0x59,0x3f,0x72,0x20,0x5b,0xb0,0x80,0x20,0xee,0x03,0xc2,0x31,0x96,0x15,0xf1,0xe6,0x0a,0xa7,0x60,0xa9,0xdc,0x09,0xa9 +,0x6e,0xc0,0x49,0x80,0x2a,0x89,0x42,0x40,0x12,0x02,0x69,0xc2,0xc2,0x80,0xb0,0x90,0x2c,0x24,0x0b,0x06,0x02,0xc8,0x40,0xa8,0x50,0x4a,0x14,0x0a,0x84,0xc2,0x21,0x30 +,0xa8,0x4c,0x22,0x33,0x10,0x88,0xc4,0x22,0x7f,0x78,0xba,0xcf,0x6f,0x1c,0x56,0xee,0xf0,0xab,0xdd,0xde,0x4e,0x2a,0x71,0xed,0xdb,0x9f,0xfd,0xbf,0x8f,0xce,0xb5,0xf1 +,0x7e,0xa7,0xef,0xe0,0x3c,0x92,0x79,0x2e,0xf0,0xd4,0xa1,0x7f,0xdf,0xbe,0x7f,0xe7,0xb0,0xe7,0xe4,0x1e,0x3f,0xfa,0x91,0xd4,0x6f,0xda,0x68,0xa5,0x2d,0xf1,0x47,0x64 +,0x1f,0xbe,0x58,0x5d,0xab,0x2b,0xa5,0x7b,0xa9,0x53,0xcf,0xd1,0x84,0x83,0x97,0xc6,0xa0,0xbf,0x1b,0xad,0xe9,0x68,0xf2,0x2f,0xbe,0xf7,0x2b,0xf8,0x6e,0x7e,0x95,0x6d +,0x40,0xfa,0x17,0xa8,0x83,0x5d,0x95,0xcb,0x90,0x47,0x83,0x83,0x91,0x16,0x31,0x59,0xee,0x12,0xa3,0x72,0x9a,0xb9,0x57,0x52,0x1a,0x9d,0xcf,0xcb,0x03,0x8c,0xa4,0x1e +,0xe7,0x78,0x5c,0x71,0x39,0x1e,0x00,0x1e,0x95,0xf6,0x67,0x7b,0xbb,0x19,0x44,0x00,0x4e,0xf3,0xc8,0x59,0x91,0xa7,0xce,0xac,0x07,0x70,0x13,0x0b,0x84,0xa8,0x03,0xbe +,0xf7,0x01,0xdf,0x77,0xc3,0x30,0x08,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2d,0x3f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x55,0x18,0x2d,0x10,0xa9,0x32,0x44,0x49,0x95,0xda,0x5f +,0x15,0x7b,0xe3,0xa1,0x27,0xa9,0x3e,0x9a,0x96,0xa6,0xad,0x6b,0xb8,0x5a,0xb0,0xea,0x72,0x10,0x25,0xde,0xea,0x98,0x58,0x60,0x6e,0x30,0x48,0x76,0x8e,0xa3,0x5b,0x83 +,0x5d,0x1e,0xae,0xa7,0xd1,0xc3,0xaa,0xea,0xf2,0xa2,0x62,0x93,0x2c,0x28,0xa3,0x09,0xf1,0xca,0x8c,0x28,0xa0,0x64,0xd0,0x11,0x42,0x2c,0xda,0x4d,0xd0,0x4f,0x39,0x56 +,0xc9,0x02,0x89,0x6a,0x60,0x88,0x62,0x6a,0xa0,0x00,0x49,0x9b,0x74,0xd9,0x26,0x01,0x52,0x50,0x46,0x06,0x8d,0x25,0xa9,0xc4,0xa2,0x43,0x4a,0xf9,0xca,0x7e,0xa4,0xec +,0x01,0xaa,0xdb,0xe1,0x18,0x94,0xac,0x22,0xf9,0x18,0x6d,0xdf,0x13,0xbf,0x39,0xb5,0x52,0x8d,0xec,0x13,0x96,0x09,0xfc,0x92,0xdd,0xc8,0x2e,0xc9,0xf6,0xcb,0x31,0x04 +,0x4a,0xfb,0x02,0x58,0x3d,0x7e,0xf4,0xd2,0xc1,0x48,0xb6,0x79,0x8c,0x8a,0x20,0xd1,0x04,0x20,0x99,0xe2,0x23,0x14,0xc0,0x28,0x28,0x43,0xdc,0x14,0x00,0x28,0x61,0x34 +,0x52,0x84,0xc8,0xb4,0xa4,0x9c,0x6b,0x5c,0xf5,0xa1,0x67,0xe1,0xdc,0x5d,0x4a,0xe4,0x7e,0x85,0xd9,0xc1,0x06,0x91,0x39,0xcd,0x67,0xbc,0x55,0x45,0x21,0xe3,0x51,0xca +,0xe9,0xcf,0x85,0xbd,0xb0,0x29,0x91,0xa7,0xf5,0xaf,0xff,0x4e,0xf3,0x6c,0xfc,0xf8,0xf0,0xa3,0xfd,0xe9,0xaf,0x0c,0xe9,0xed,0xc7,0x6e,0x5e,0xdb,0x75,0x6b,0xf1,0xd9 +,0x37,0x87,0x77,0x1c,0xeb,0xef,0x1a,0xb2,0xf5,0x77,0x77,0x97,0xd2,0x6f,0x34,0x69,0xaf,0x57,0x96,0xc2,0x0b,0x2a,0x93,0x7d,0x72,0x51,0xed,0x23,0x0e,0x56,0x50,0xe7 +,0x28,0xcb,0xa9,0x10,0x3a,0xb0,0xf2,0x4f,0x79,0x87,0x0d,0xe2,0x7a,0x32,0x77,0x51,0xeb,0xb3,0xee,0xd1,0xae,0xf8,0xd5,0x75,0x55,0xe3,0x96,0x39,0x62,0xc6,0x32,0x45 +,0x58,0x75,0x6f,0x0d,0x3d,0x3d,0xfb,0x19,0xa5,0x98,0x00,0x21,0xcc,0x53,0xfe,0x37,0xd7,0xf2,0x6b,0x18,0xdb,0x54,0x6b,0xa6,0x28,0xc6,0x5b,0xa3,0x8b,0xd9,0x19,0x6c +,0x40,0x89,0x10,0x66,0x20,0x60,0x26,0x97,0xa8,0x98,0xb8,0x00,0x2b,0x00,0x28,0x97,0x7c,0xee,0xff,0xf1,0x50,0x80,0x31,0x3f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x54,0x26 +,0x8a,0x8d,0x09,0x32,0x69,0x24,0x9a,0x4e,0x06,0x71,0x7c,0xcc,0xdb,0xa0,0xf5,0x31,0xda,0x95,0xea,0x5c,0x70,0x38,0xb5,0xf9,0x99,0x34,0xda,0x4a,0xa6,0x55,0x55,0x3c +,0x47,0xb5,0xfb,0xd5,0x92,0xb3,0xb7,0xca,0x29,0xaf,0x07,0x90,0xbe,0x2f,0xf6,0xc4,0xfa,0xb0,0x93,0xac,0x2e,0x83,0xad,0xc6,0x2e,0xdd,0xb3,0xbb,0x31,0xc7,0x35,0xaa +,0x80,0x1b,0x15,0xe3,0x0d,0x74,0xdd,0x52,0xb8,0x90,0x5e,0x52,0x9c,0x4c,0x48,0x2d,0x2b,0xd0,0x85,0x1e,0x8e,0x38,0x6d,0x83,0xb0,0x67,0x96,0x9b,0x60,0xb3,0x64,0x84 +,0x35,0x58,0xd7,0x8e,0xfe,0xff,0x07,0x67,0xc3,0xbe,0x70,0xae,0xe9,0x21,0x2b,0xc8,0x82,0xa0,0xf4,0x67,0xa6,0x7d,0xb7,0xb8,0xb8,0x88,0x5a,0x13,0xbc,0xb4,0x21,0x28 +,0x59,0xaf,0x47,0xfd,0xfe,0xd5,0xe5,0xb5,0xe6,0xbb,0x2b,0xb5,0x70,0x25,0xb4,0x9c,0x2b,0x38,0xd1,0x4a,0xf7,0xa9,0x4d,0x90,0xa6,0x0a,0x30,0x97,0x22,0xa5,0xc4,0xa2 +,0x74,0x9a,0x40,0x16,0x14,0x14,0x1b,0x81,0x6a,0x8f,0x40,0x50,0xc3,0x65,0x05,0x92,0x21,0x48,0x24,0x92,0x5d,0x8c,0xcc,0x69,0xd4,0x36,0xdd,0x5e,0xc6,0x5f,0x1e,0xf1 +,0x34,0x50,0xe7,0xb3,0xa6,0xbf,0xa8,0x2b,0x25,0x88,0x27,0x5c,0xc7,0xb7,0xbe,0x92,0x54,0x2f,0x41,0x86,0x26,0x35,0x0c,0x69,0xec,0x3f,0x92,0xb9,0x98,0x50,0x26,0x2e +,0x89,0x7f,0xb9,0xff,0xca,0xaf,0xd0,0x3d,0x99,0xdb,0xee,0xd5,0x5d,0x7a,0xaf,0x8b,0xbb,0xb7,0x58,0x3c,0x79,0xe3,0x26,0xbc,0xf2,0xff,0xc7,0x45,0x38,0x10,0x3a,0x0f +,0x8c,0x22,0x4e,0x18,0x8a,0x08,0x51,0x45,0xf3,0xa9,0x2c,0x94,0xbc,0x78,0x52,0xbc,0xd4,0x08,0x44,0x12,0x36,0x20,0x09,0xd6,0x10,0xf8,0xb9,0x94,0xca,0xaf,0x5c,0xbb +,0xc6,0x33,0x9b,0x2f,0x1b,0x10,0x84,0xc0,0xc4,0x96,0x80,0x03,0x32,0x07,0x0b,0x2c,0x25,0xd0,0x4a,0x6a,0xd4,0x5f,0x24,0xd7,0xd6,0x70,0xad,0xa8,0x97,0x1f,0xae,0x6c +,0x51,0xc5,0x1f,0xff,0x1a,0x50,0xfa,0x67,0x68,0xea,0x64,0x3e,0xfb,0x54,0xe1,0xed,0x1e,0x13,0x6c,0x5a,0xeb,0x47,0x63,0x07,0xdd,0x83,0x94,0xce,0x49,0x8a,0x97,0xcf +,0xda,0xb3,0x49,0x53,0xe2,0xae,0x35,0x7d,0x4b,0xfb,0x27,0x7b,0x32,0x99,0x41,0x03,0xf7,0x89,0xd7,0x01,0xe8,0x1b,0xb3,0x44,0x89,0x9e,0x07,0xff,0xf1,0x50,0x80,0x2f +,0x9f,0xfc,0x21,0x6a,0xcf,0xfb,0xf7,0xff,0xff,0xff,0xb5,0x80,0xb1,0x50,0x2e,0x16,0x2a,0x09,0x82,0x83,0x60,0x90,0x50,0x4a,0x14,0x11,0x08,0x48,0x64,0x13,0xbe,0x3d +,0xf8,0xcd,0x54,0xcb,0xcb,0xdf,0x0a,0x95,0x25,0x49,0x7c,0xdd,0xd5,0x69,0x2e,0x66,0xb6,0xa9,0x7e,0xd6,0x11,0xec,0xbf,0x8e,0xef,0x56,0x8f,0x89,0xfe,0x06,0x35,0x7f +,0xb5,0xd8,0x6a,0xb5,0xfd,0xff,0xc3,0x25,0xd2,0x84,0x6a,0x4a,0xff,0x9f,0x88,0xbf,0x88,0xee,0x61,0xb6,0xf3,0x64,0xef,0x36,0xee,0x31,0xa3,0xb4,0xd1,0xae,0x0c,0x7c +,0x72,0x21,0x7b,0xde,0xf9,0x7e,0xe3,0x15,0xaa,0x58,0xfb,0x3d,0xd6,0x5b,0xa8,0x79,0x15,0x4e,0x40,0x1d,0xdf,0x85,0x68,0xf1,0x8a,0x37,0xea,0xc4,0x43,0x47,0x70,0xa5 +,0x6c,0x8c,0xe1,0x93,0x34,0xd6,0xd9,0x35,0x3f,0x55,0xad,0x8e,0xb3,0x91,0x5b,0xaf,0xb5,0xa1,0xa6,0x2a,0x97,0x8c,0xc3,0xd7,0x24,0x93,0xcc,0x07,0xb6,0x10,0x04,0xbd +,0x70,0x90,0x6d,0x50,0x5d,0x71,0x51,0x69,0xa3,0x88,0x0b,0xbf,0x70,0x13,0x09,0x80,0xa3,0x50,0xa0,0xd8,0x30,0x16,0x0a,0x05,0x86,0x82,0x61,0x98,0x58,0xa8,0x13,0x0a +,0x90,0xc2,0xa2,0x30,0x88,0x4c,0x22,0x13,0x28,0x8d,0xe8,0xd7,0x77,0xfb,0xff,0x1e,0x7b,0x44,0xc5,0xe2,0xd5,0x22,0x45,0x4b,0xd6,0xf8,0x64,0xba,0xdf,0x9f,0x21,0xee +,0xfd,0x67,0xff,0x2f,0xff,0xfe,0x5f,0x76,0x68,0x6a,0xd3,0xf2,0x5d,0x37,0x71,0xd9,0xff,0xb0,0x02,0xff,0xbb,0xe3,0x3e,0xbf,0x86,0xb3,0xf3,0xbf,0x27,0x0e,0x1a,0x34 +,0xd6,0x5f,0xac,0xff,0x16,0x70,0xf3,0xf9,0x8b,0xb9,0x2c,0x35,0x99,0x47,0x3d,0x1e,0x05,0xf4,0x9c,0x22,0x6a,0x8a,0xab,0x6d,0xe2,0xf1,0x7f,0x1f,0xfa,0x1f,0xdd,0xbc +,0x2f,0xf1,0x3f,0x55,0xf9,0x3e,0xcb,0xcf,0xfd,0x55,0xbe,0x6e,0x8b,0x3c,0xc3,0x9b,0x8f,0x1e,0x2e,0x79,0x87,0x03,0xbf,0xb9,0x17,0xcc,0x92,0xf8,0x76,0x9d,0x28,0xeb +,0x69,0xfe,0x19,0xfb,0xa7,0x16,0x98,0x8e,0xb4,0x22,0xa0,0x5d,0xdc,0x51,0x53,0xc5,0x10,0x56,0x9f,0xff,0xe0,0x29,0xdd,0x88,0xaa,0x17,0xef,0xbb,0xce,0xf8,0xe5,0x8c +,0x06,0x9b,0xbe,0x07,0xbb,0x1a,0x0f,0x77,0x18,0x20,0xf5,0xc0,0xb0,0x7e,0xe1,0x78,0xde,0x2d,0x60,0x10,0x85,0x66,0x07,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a +,0xcf,0xdf,0xff,0xff,0xff,0x7f,0xb3,0x81,0x31,0x10,0x2c,0x38,0x0b,0x86,0x02,0x82,0x60,0xa0,0x98,0x28,0x12,0x0a,0x85,0x06,0x43,0x17,0xb3,0xce,0x17,0xbe,0x2b,0x26 +,0x71,0x55,0xd6,0x55,0x4b,0xc9,0x52,0x2a,0x4b,0xbc,0xaf,0xbf,0xbc,0x89,0xe7,0x81,0xc8,0x37,0x8a,0x5c,0x6d,0xd9,0xbf,0xd2,0x7c,0x53,0xfd,0x8d,0xaf,0xa9,0x5b,0xcf +,0xb2,0x52,0xc7,0xa7,0x4f,0x39,0xc5,0xe4,0x5f,0xe6,0xfe,0x2e,0xba,0x07,0xdb,0x90,0xb6,0x5c,0xdb,0xc8,0x15,0xba,0x6b,0xd8,0x95,0xaa,0x73,0x60,0x1a,0x5e,0xdc,0xa9 +,0xf7,0xd9,0x1b,0xc5,0x5f,0xf2,0x97,0xdb,0xba,0x1e,0x5f,0xa1,0x34,0xac,0xc1,0x69,0x15,0xee,0x6c,0x8a,0x7f,0x11,0x2b,0x3b,0x50,0x5f,0x33,0x5a,0x02,0x35,0x44,0xc5 +,0x7f,0xc9,0x5b,0xc2,0xd1,0x9e,0x0d,0x64,0xef,0x3e,0x0a,0xba,0xe3,0x3a,0x67,0xbc,0xd2,0x21,0xad,0x76,0xb1,0x44,0x36,0xb5,0xf3,0xe7,0x44,0x4b,0x91,0x01,0x08,0x52 +,0x3c,0x01,0x48,0xcd,0x0b,0xd8,0x8c,0x15,0x50,0x92,0x95,0x4c,0x00,0xb4,0x40,0x50,0xa0,0x58,0xc8,0x26,0x13,0x85,0x8a,0x81,0x61,0x40,0x54,0x26,0x15,0x30,0x84,0xc2 +,0xa1,0x32,0x08,0x8c,0x22,0x47,0xcf,0x5e,0x2e,0xa2,0x52,0x8e,0xb9,0xe3,0x9a,0x45,0xc0,0xe9,0x5c,0xeb,0x2e,0xaa,0xfe,0x3b,0xf6,0xdf,0x03,0x4c,0x49,0xcf,0x8d,0x1c +,0xbd,0xfa,0xb6,0xf9,0x9a,0xfe,0x3f,0x04,0xf8,0x27,0x73,0x7e,0x27,0xc8,0xf5,0x29,0xea,0xaa,0xb7,0xed,0x44,0xb7,0x0f,0xc3,0xd4,0x7b,0x0b,0x3f,0x8b,0xa5,0x80,0x3a +,0x7f,0x77,0xeb,0xff,0x4f,0x5e,0x77,0xe3,0x17,0x87,0x77,0xb7,0x21,0xbc,0x68,0x3f,0x9d,0x02,0xfe,0x0e,0x1d,0xff,0x33,0xa7,0xf7,0x7f,0x55,0xef,0x4f,0x97,0xd9,0xe4 +,0x05,0x52,0xaf,0xc5,0x71,0xc3,0x9f,0x3f,0x9b,0xe6,0x98,0x8b,0x01,0xc4,0xf1,0xe7,0xc0,0x75,0x5b,0x3d,0x9c,0xce,0x20,0x07,0xcf,0x89,0xcc,0x85,0xa3,0xc5,0x29,0x88 +,0xbd,0xab,0xdd,0x74,0x69,0xce,0xca,0x62,0x24,0x5f,0x78,0x85,0x55,0x87,0xd7,0x6e,0x93,0x9f,0xaa,0x27,0x07,0xac,0x5a,0xd3,0xef,0x77,0xfb,0xe0,0x6b,0x42,0x12,0x47 +,0xb7,0x44,0x01,0x47,0x74,0x26,0x89,0x38,0x26,0x15,0xb0,0x55,0x42,0x51,0x03,0x80,0xff,0xf1,0x50,0x80,0x31,0x5f,0xfc,0x21,0x0a,0xcf,0xcf,0xfe,0x7f,0xdf,0x7f,0xb2 +,0x63,0x28,0x50,0x26,0x18,0x0b,0x85,0x03,0x01,0x20,0xa0,0x58,0x28,0x32,0x0a,0x11,0xc2,0x44,0x10,0x90,0x44,0x24,0x11,0x53,0x3c,0xf7,0xed,0xeb,0x5e,0x7d,0x7c,0x7d +,0xb5,0xbf,0x2d,0xdb,0x2e,0xea,0x57,0x1b,0x44,0x2a,0xfe,0xb5,0xfa,0x4e,0x32,0xbf,0x5b,0x1f,0x0b,0x32,0xf1,0xe3,0xd7,0x1e,0x89,0x37,0xf1,0xad,0xeb,0xfe,0x87,0xfa +,0xd2,0xba,0x1f,0xb2,0xc7,0x7f,0x31,0xfc,0xb3,0xa0,0xee,0x89,0xf8,0xdf,0xbe,0x5e,0xfd,0x71,0x72,0xde,0x79,0x5f,0xf2,0x27,0xd0,0x6e,0xfa,0x98,0x0b,0x1d,0xff,0x64 +,0x3a,0xe9,0x49,0x7d,0xc1,0x98,0x5b,0xc5,0xec,0x49,0x19,0x96,0x57,0xe9,0x51,0xda,0xc1,0x72,0x84,0xfa,0xe5,0x63,0x8e,0x50,0xfc,0x47,0xa6,0xf6,0x53,0x10,0xb9,0xcb +,0xb0,0x74,0xc1,0x69,0x1f,0x4d,0x1d,0xb3,0x88,0xc0,0x8a,0xd9,0x47,0xa6,0xbf,0x91,0x50,0x1b,0x93,0x86,0x5b,0x46,0xfe,0xd4,0xec,0x27,0x43,0x21,0x50,0x2b,0x32,0x22 +,0x15,0xa3,0xdd,0x84,0x0c,0xe2,0x41,0x02,0xb1,0x1a,0x57,0x5c,0x0a,0x8a,0x00,0x9d,0x20,0xa0,0x98,0x2e,0x16,0x0a,0x09,0x88,0xa1,0x41,0x30,0x50,0x2c,0x14,0x0c,0x05 +,0x82,0x84,0x50,0xb8,0x4c,0x4a,0x13,0x0a,0x8c,0x42,0xa1,0x30,0x88,0x4c,0x22,0x47,0xed,0xa7,0x3b,0xbe,0xb2,0x66,0x95,0x55,0x51,0x5a,0x13,0x46,0xbd,0x71,0x3a,0xef +,0xdb,0xed,0xd7,0x9e,0x77,0xf1,0x5c,0x0e,0x3f,0xf8,0x7e,0x33,0xb7,0x67,0xb5,0x1d,0xbd,0xdf,0xd1,0xbe,0x19,0xc6,0xdb,0x7c,0x3d,0x4d,0x1c,0x38,0x4f,0x6c,0xf7,0xd7 +,0xe6,0xfe,0x27,0xab,0xeb,0x7f,0xfa,0xf2,0x9e,0xf5,0xfa,0xcf,0xf1,0x30,0xe1,0x44,0xd6,0x51,0xd3,0x7f,0x39,0xb7,0xcd,0xd6,0xc5,0x69,0x47,0xfd,0x02,0xd7,0x80,0x7f +,0xb7,0xfe,0xe7,0xc7,0xfd,0xdf,0xd2,0x5e,0x7f,0xed,0x7f,0x9a,0x7f,0x77,0xdd,0xfe,0xb5,0x8f,0x6b,0xec,0xcf,0xab,0xc8,0x2f,0x82,0x52,0x02,0xf8,0x1e,0x05,0xbf,0xc2 +,0xff,0xbd,0x28,0xfd,0xa7,0x70,0xba,0xce,0x2a,0xe5,0x8e,0x84,0x5b,0x44,0x22,0x83,0xc6,0x71,0x9f,0x48,0x05,0xcf,0x2e,0x80,0x01,0xe3,0x09,0x45,0x3c,0xe3,0x85,0x8a +,0xca,0xc2,0xe2,0x05,0x13,0xcc,0x42,0xcb,0x71,0x22,0x3d,0xd8,0x51,0x70,0x5c,0x77,0x93,0x26,0x73,0x2d,0x70,0x05,0x91,0x0d,0xc0,0x70,0xff,0xf1,0x50,0x80,0x2d,0xdf +,0xfc,0x21,0x0a,0xcf,0xe5,0xdb,0xfd,0x7f,0xfc,0xb3,0x60,0xb8,0x58,0x88,0x36,0x0b,0x86,0x03,0x21,0x44,0x10,0x50,0x64,0x31,0x39,0x84,0x4e,0xad,0x67,0xdf,0xd6,0xb5 +,0xef,0xfb,0xfe,0x93,0x7d,0x5e,0xd2,0x4c,0xa9,0x79,0x17,0x1a,0xca,0xbb,0xbd,0xc2,0x7b,0x79,0x0f,0xf8,0xf5,0xea,0x3d,0xd4,0xfb,0xfe,0xa6,0xfa,0x38,0xf6,0x98,0xfc +,0xc6,0x1e,0x6f,0xed,0xd7,0x59,0x20,0x5e,0x85,0x7f,0x37,0x8f,0xde,0x4b,0xb7,0xcf,0x79,0x64,0x3e,0x42,0x04,0x3a,0xb4,0x18,0x24,0xce,0xdb,0xd8,0xe2,0x43,0x6b,0x83 +,0x83,0xe8,0xc3,0xfc,0xed,0xea,0x46,0xb8,0x2b,0x18,0xa2,0x53,0x8e,0x27,0x41,0xd2,0x69,0x55,0x56,0x5d,0x16,0x79,0xf9,0xdb,0xab,0xa9,0x69,0x98,0x0f,0xf6,0x44,0x93 +,0x1f,0xc7,0x46,0x8c,0xc5,0xf9,0xca,0x6d,0x71,0x68,0xea,0x5a,0x04,0x62,0xb3,0x2d,0x0a,0x4b,0x08,0xde,0xb4,0xc5,0xa6,0x55,0xdc,0xb2,0x95,0x97,0xbe,0x08,0x17,0x28 +,0x66,0x26,0x09,0x8b,0x8b,0x8a,0x55,0x30,0x20,0x02,0xa0,0x51,0x10,0x50,0x4c,0x38,0x0b,0x09,0x04,0xe1,0x60,0xa0,0x98,0x68,0x65,0x0a,0x05,0x42,0xc1,0x30,0xa8,0x4c +,0x22,0x13,0x10,0x84,0xc6,0x25,0x6f,0xdb,0xfa,0xb5,0xcc,0xe3,0x7e,0x7b,0xba,0x8d,0xf0,0xa2,0xae,0x67,0x1c,0xfc,0x64,0xe7,0x5a,0xe7,0x8b,0x75,0xbe,0x9c,0x0d,0x9d +,0xcf,0xc1,0x7b,0x29,0xf4,0xdb,0xd8,0x49,0xe9,0x57,0xb1,0x78,0x7f,0xd1,0xe2,0x7f,0xf4,0xe6,0xc5,0xde,0x54,0xbc,0x57,0xfd,0x3a,0x5b,0x74,0xfb,0x23,0xc8,0xdd,0xfa +,0xa8,0xfd,0xce,0xcf,0xa8,0xc1,0xa6,0xb2,0xff,0x2f,0x6c,0xcf,0xce,0x3d,0x60,0x5c,0xbb,0xfb,0x43,0xff,0xcd,0xfd,0x9c,0x79,0xae,0xfb,0x6f,0x21,0xcb,0xfe,0x8f,0x5f +,0x29,0xa9,0xc4,0x72,0xae,0x11,0xcd,0xe0,0x49,0xc7,0xaf,0x89,0xef,0x40,0x38,0x76,0x78,0x99,0x00,0x25,0x63,0x86,0xe6,0xe4,0x63,0xee,0x1e,0xb8,0x1c,0x15,0xdc,0x80 +,0x9e,0x0f,0x16,0x67,0xad,0xdc,0x23,0x81,0x6b,0x52,0xe1,0xaa,0xef,0x77,0x70,0xbd,0x60,0x7b,0xa8,0x59,0x43,0x3a,0xbe,0xe7,0x7c,0x1e,0xb8,0x0f,0x77,0xdd,0x02,0x00 +,0x49,0x54,0xc4,0x6a,0x00,0x50,0x22,0x07,0xff,0xf1,0x50,0x80,0x30,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0x5d,0xff,0xfc,0xb1,0x61,0xc0,0x5c,0x2c,0x14,0x0b,0x0e,0x02 +,0xc1,0x81,0x30,0x90,0x2c,0x14,0x32,0x88,0x82,0x21,0x20,0x88,0x4c,0x42,0x23,0x08,0x84,0xc2,0x21,0x30,0x89,0x03,0xf1,0xef,0xac,0xce,0xbc,0x1e,0x79,0x22,0x54,0xab +,0x95,0x78,0x74,0xdd,0x5e,0xfc,0xe7,0x14,0xff,0x4f,0x22,0xdf,0x2f,0x67,0xaf,0xe9,0xd2,0x0d,0x4f,0xaf,0x27,0xa7,0xb4,0x2f,0x66,0xaa,0x39,0xf6,0xf4,0x0c,0xb8,0x2a +,0x3b,0xfa,0x84,0x7c,0xce,0xfe,0x68,0xd6,0x8c,0x85,0xa5,0x6e,0xd3,0x78,0x6c,0x20,0x5e,0x28,0x52,0x12,0x7d,0x82,0xbf,0xfb,0x79,0xf6,0xc0,0x3f,0x50,0x6e,0x63,0x4c +,0xa7,0xb3,0x62,0x10,0x36,0xbf,0x02,0xe2,0x2a,0x06,0x71,0x9d,0x8f,0x19,0x9e,0x15,0x71,0xed,0xc6,0xc4,0x27,0x52,0xc7,0x96,0x77,0x71,0xc9,0xf5,0xee,0xab,0xbd,0xea +,0x9a,0x87,0x90,0x8f,0xa6,0x27,0xe6,0xa4,0x63,0x6e,0xea,0xf1,0x81,0x4a,0x11,0x9c,0x7e,0xc5,0x04,0x7c,0x44,0x77,0x3a,0x9a,0x3a,0x97,0x1d,0xf8,0x46,0xd2,0x4a,0x92 +,0xb4,0x24,0x3e,0xc5,0x61,0xf6,0x54,0x1d,0xf9,0xfb,0xa0,0xc0,0x11,0x20,0xd0,0x02,0xe0,0x54,0x09,0x94,0x0b,0x05,0x02,0xc2,0x70,0xb0,0x50,0x4c,0xe4,0x0a,0x85,0x02 +,0xa2,0x10,0xa8,0x4c,0x2a,0x11,0x0a,0x84,0x42,0xa1,0x13,0xbf,0xb4,0xef,0xeb,0xde,0xfa,0xee,0xea,0xa5,0x6b,0x99,0xaa,0xe7,0x55,0xaa,0x8b,0xd7,0xeb,0xef,0x5b,0xdf +,0xc7,0x1c,0xfc,0x3d,0xbb,0xfd,0x3e,0xf0,0x71,0xcd,0xf2,0x7c,0x9b,0x1e,0xcf,0x6d,0x9d,0xec,0x17,0x57,0xe5,0x3f,0x83,0x6e,0xfe,0xa5,0x3b,0x27,0x6b,0xfc,0x86,0xdd +,0xf6,0xfb,0xc2,0x5e,0x0c,0x13,0x68,0xec,0xab,0x31,0x62,0xd1,0x8f,0xdb,0x30,0x9c,0x0f,0x6a,0x00,0x63,0x34,0x07,0x5f,0x28,0xf5,0xb9,0xf5,0x70,0x02,0x3e,0xb3,0x3a +,0x75,0x92,0x8f,0x29,0x8a,0xc3,0x10,0xf2,0xff,0xcb,0x43,0x3f,0x9d,0xbe,0x2e,0x67,0x18,0x17,0xfd,0x19,0xfd,0xfe,0xe7,0x66,0xa5,0x38,0x97,0xc6,0xb9,0x58,0x78,0x99 +,0x2b,0xc4,0xe6,0x46,0x00,0x1e,0x00,0x0f,0x58,0x77,0x47,0x35,0x82,0x4e,0x32,0x5f,0x64,0x31,0xd0,0xf8,0xf8,0x00,0x00,0x01,0x8c,0x03,0xc4,0x01,0x00,0x50,0x01,0x50 +,0x05,0x05,0x69,0x34,0x00,0xb5,0x05,0x40,0x70,0xff,0xf1,0x50,0x80,0x2c,0x3f,0xfc,0x21,0x0a,0xcf,0xcd,0xfc,0xff,0xff,0xfd,0xae,0x80,0xb8,0x58,0x6a,0x14,0x0b,0x0d +,0xc2,0x81,0x90,0xa1,0x18,0x28,0x15,0x0a,0x14,0x82,0x81,0x20,0x98,0x84,0x26,0x31,0x4b,0x9a,0xbf,0x39,0x27,0xaf,0xc7,0xcd,0x35,0xc7,0x77,0x9d,0x64,0xc8,0x92,0xa5 +,0xcc,0xd4,0xa6,0x4e,0x2a,0x3f,0xcf,0x03,0x0f,0x8b,0xed,0x47,0x1e,0xa7,0xf3,0xf4,0x57,0x6f,0x1a,0x5f,0xbf,0xac,0x6f,0xfc,0xfe,0x7c,0xd4,0xe8,0xef,0xc3,0x5d,0x7a +,0x76,0x1d,0x3f,0x45,0xea,0x7d,0x1d,0x80,0x2c,0x2b,0xd0,0x18,0xab,0x49,0xdb,0xeb,0x45,0xf9,0xa5,0x72,0xc4,0x78,0xef,0xbc,0xfb,0x2d,0x96,0x44,0xa4,0xf3,0xdf,0x81 +,0x7b,0xe2,0xb6,0xf6,0x1b,0x2e,0x57,0x79,0xc9,0xec,0xb1,0x7d,0x93,0x9c,0xcf,0x54,0x49,0x69,0xaf,0x63,0xa1,0xcf,0x26,0x07,0x14,0xaf,0xbb,0x78,0x24,0xef,0x92,0xa4 +,0x58,0x5d,0x92,0xde,0x54,0x3d,0xdc,0x11,0x16,0x2f,0xf5,0x87,0xa2,0x5d,0x21,0x0b,0xc1,0x30,0xd9,0xe0,0x04,0xaf,0x6a,0x56,0x75,0xa0,0x12,0x60,0x00,0xfb,0x04,0xde +,0xf0,0x60,0x01,0x30,0x13,0xaa,0x14,0x0b,0x15,0x06,0xc1,0x80,0xb0,0xdc,0x28,0x26,0x2a,0x09,0x44,0x61,0x10,0xa8,0x4c,0xa2,0x87,0xdb,0x9c,0x94,0xea,0xae,0xb7,0x2b +,0xcf,0x8b,0x65,0x69,0x75,0x25,0xeb,0xf1,0xef,0x94,0x6b,0x8f,0x6d,0x73,0x39,0xcf,0xd4,0x3b,0x3f,0x76,0xfa,0x79,0x6d,0xd9,0xb7,0xd9,0x22,0x75,0xeb,0xed,0x59,0xc0 +,0x73,0xea,0x0b,0x48,0x54,0x1c,0xea,0x2c,0xe1,0x1e,0xc3,0x4e,0xfe,0x06,0x5f,0xf3,0xdc,0x45,0x47,0x8f,0xb5,0x47,0xfd,0x17,0xcc,0x1e,0x23,0x78,0xf4,0x6a,0x67,0x20 +,0xe4,0x52,0x70,0xd9,0x32,0x1c,0xa1,0x9f,0x6a,0x32,0x47,0x0d,0x0e,0x04,0x87,0xe8,0x6e,0x1f,0x7e,0xc7,0x86,0x7c,0xfc,0x14,0xfb,0xbd,0x5c,0xf1,0x64,0xe6,0x6e,0x04 +,0x0f,0x52,0xe0,0xf7,0x7f,0xf5,0x8a,0xf0,0x70,0x00,0x01,0xe0,0x03,0xff,0xee,0x1e,0xe8,0x21,0xdc,0x1e,0xb0,0xee,0x9d,0xd1,0xde,0x01,0xee,0x05,0xe6,0x98,0xb0,0x17 +,0x2a,0x04,0xc0,0x05,0xe6,0x00,0x50,0x16,0x03,0x80,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a,0xcf,0xcf,0xe7,0xfe,0xff,0xfc,0xb1,0x70,0xb0,0xdc,0x2c,0x14,0x0b +,0x05,0x02,0xc1,0x70,0xa8,0x5c,0x2c,0x64,0x21,0x05,0x42,0x41,0x50,0x90,0x4c,0x62,0x23,0x10,0x88,0xc2,0x21,0x30,0x88,0xd9,0xc5,0xf3,0x5f,0x13,0xed,0xfa,0xfd,0x8e +,0x2a,0xa7,0x5d,0xde,0x44,0x4b,0xab,0x6b,0x75,0xe5,0xde,0xb5,0x9e,0xdf,0x3f,0xe7,0x41,0xe0,0xf7,0xf7,0x7a,0xf5,0x7a,0x3d,0xfd,0xe5,0xfd,0x28,0xe8,0x77,0x77,0xfe +,0xb7,0x77,0xe7,0xf9,0x22,0xdf,0x1b,0x7c,0xd7,0xf8,0xfc,0xc6,0x78,0xec,0xe8,0xe3,0x7f,0xb9,0x0e,0x05,0x38,0xa0,0xc5,0x7a,0xc3,0xb3,0xf5,0x41,0x5e,0x47,0xe0,0xdb +,0xc9,0xc6,0x7b,0x9a,0x8f,0xc2,0x25,0x5e,0xb7,0xb0,0x4c,0x5d,0xfc,0x86,0xfd,0xb3,0x75,0xd4,0x3f,0xaf,0x6a,0xaa,0x9d,0x2e,0x74,0xe0,0xfc,0x19,0x6a,0x8b,0xfd,0x0e +,0x64,0xfd,0x68,0x2c,0x43,0x98,0xfa,0x0a,0x4f,0xb4,0xcb,0x75,0x8c,0x7e,0x8e,0x42,0x84,0x67,0x66,0x84,0xf2,0x27,0xbf,0x51,0x96,0x1e,0xe0,0x80,0x07,0x9a,0x77,0x02 +,0x1d,0x51,0xd0,0x14,0x3b,0xc0,0x24,0xc4,0x0f,0x70,0x04,0xef,0x10,0x04,0xc5,0xc0,0x51,0x20,0x4c,0x2c,0x27,0x0b,0x06,0x02,0xc1,0x41,0x30,0xa0,0x28,0x16,0x3a,0x05 +,0x82,0x83,0x50,0x98,0x94,0x22,0x33,0x08,0x84,0xc2,0x21,0x30,0x89,0x5e,0xf2,0xa9,0x9f,0x7f,0x5c,0x6f,0x2f,0x35,0xce,0xaf,0x65,0xd5,0xd4,0x9a,0xbe,0x2e,0xf3,0x7f +,0x5f,0xa7,0xee,0xf5,0xf1,0xe2,0x58,0xe8,0xff,0xa5,0xe0,0x3b,0xa9,0xf6,0xe6,0x4d,0x88,0xf8,0xfc,0xdd,0xff,0x9f,0xf1,0xfe,0xce,0x41,0xaa,0xf2,0xcd,0x4a,0xd3,0x0f +,0xeb,0x9f,0x5e,0xef,0x19,0x0f,0x6d,0x14,0xd2,0x41,0x67,0xcb,0xec,0x53,0xc4,0xd6,0xed,0xeb,0xda,0x82,0xf7,0x8d,0x92,0xf5,0x5b,0xa2,0xac,0x6a,0x10,0xfb,0xda,0x40 +,0x56,0xa3,0x6d,0x15,0x25,0x57,0x8c,0xe9,0xe7,0xf6,0xfd,0xf1,0x25,0x9b,0xc7,0xba,0xaa,0x9e,0xe7,0x8c,0xba,0x87,0xe0,0xe6,0xf9,0x0a,0xe6,0x3b,0xbd,0xfe,0xf5,0x0e +,0xeb,0xbe,0x00,0x00,0xf1,0x52,0xa5,0x85,0x82,0xcc,0x62,0xec,0xc1,0x37,0x70,0x06,0xde,0xa7,0x7c,0x92,0x53,0x2a,0x07,0x7c,0x04,0xaa,0x00,0x11,0x4e,0xe0,0x31,0x85 +,0x99,0x40,0x70,0xff,0xf1,0x50,0x80,0x2e,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0xef,0xfc,0xff,0xff,0xb0,0x62,0x40,0x50,0x2a,0x16,0x12,0x05,0xc2,0x81,0x80,0xa0,0xd8,0x28 +,0x32,0x12,0x09,0x44,0x81,0x20,0x88,0x4c,0x42,0xc7,0x37,0xd7,0x8e,0xb7,0xc7,0x7e,0x7b,0x99,0xc2,0xba,0xef,0x4a,0xd6,0xee,0xa2,0x5e,0xa7,0x2a,0x2e,0xd2,0xbf,0x7b +,0x0d,0xeb,0xfc,0xef,0xb3,0xb7,0x7f,0xeb,0xbc,0x1d,0xdd,0xf1,0x4e,0xed,0x35,0x7c,0xb7,0xec,0xca,0xeb,0x7e,0x76,0xb5,0xf2,0x63,0xf8,0x9a,0xdb,0xfd,0x9e,0x0e,0xe9 +,0xe8,0x21,0x17,0x3d,0x15,0xdb,0xee,0x1f,0x77,0xf7,0x69,0xde,0xfc,0xac,0xbf,0xa3,0xfd,0x32,0x1a,0x47,0x69,0x71,0x92,0x54,0xba,0x55,0xb6,0xc6,0x95,0xb4,0x3e,0xfd +,0xb7,0x4a,0xf4,0x35,0xac,0x4a,0x6d,0x0d,0xbc,0xb4,0x6e,0x75,0x70,0x21,0x03,0xd8,0xe5,0xe6,0xbb,0x89,0x69,0x87,0xb8,0xf7,0x23,0xae,0xfc,0xbe,0xe2,0x2d,0xd6,0x13 +,0xce,0x4a,0x98,0xb9,0x8a,0x36,0xb7,0x26,0x67,0xb0,0x9d,0x04,0xa9,0x4a,0x58,0xbd,0x13,0x35,0xc1,0x40,0xa3,0xce,0x04,0xc5,0x2e,0x85,0x6c,0x0b,0x80,0x98,0x0a,0x76 +,0x24,0x05,0xc2,0x82,0x30,0xa8,0x58,0x2e,0x14,0x13,0x15,0x02,0xc3,0x51,0x20,0x8c,0x4a,0x13,0x18,0x85,0x42,0x61,0x13,0xab,0x32,0x45,0xd6,0xb9,0xab,0xab,0xca,0x88 +,0xba,0x93,0x25,0xdf,0x9e,0x6f,0x79,0xf1,0xcf,0x9a,0xd6,0x5c,0xb0,0x5c,0xb7,0xd5,0xd0,0x79,0x4f,0xdf,0x4f,0xc2,0x7f,0xff,0xfa,0x8f,0xea,0x3a,0xdd,0x6a,0x34,0xf5 +,0x74,0xfa,0x3d,0x97,0xdc,0xbe,0x12,0x09,0x5d,0xe9,0xba,0x34,0x9d,0x3b,0xc6,0x5d,0xb6,0x68,0x5b,0xee,0x9f,0x28,0xa5,0xb5,0xd3,0xe8,0xe8,0x0f,0xda,0xc0,0xe0,0x1d +,0x51,0xcb,0x5d,0x35,0x50,0x60,0xef,0xce,0x57,0x0a,0x5e,0x27,0x30,0xf7,0xfc,0x4b,0xec,0x70,0xb9,0xf8,0xf2,0x1c,0xff,0x49,0x9c,0xd4,0x7a,0xbe,0x1c,0xfd,0x6e,0x47 +,0xfe,0xd2,0x3d,0x5b,0xbf,0x2f,0x7c,0xee,0x3c,0xd5,0x1e,0x29,0x67,0x98,0x00,0x92,0x3f,0x6c,0x1d,0xc0,0x3d,0xcf,0x5c,0x3e,0xb7,0x34,0xc8,0xb0,0x74,0x41,0x70,0x03 +,0xc8,0x05,0x47,0xb8,0x01,0x65,0xaa,0x09,0xa2,0xb0,0x5c,0x16,0x85,0x6c,0x02,0x17,0x04,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2f,0x9f,0xfc,0x21,0x0a,0xcf,0xdf,0xfe,0xdd +,0xff,0xff,0xae,0x63,0x28,0x50,0x70,0x16,0x0b,0x85,0x0a,0xc1,0x20,0xa0,0x48,0x28,0x25,0x09,0x08,0x60,0xed,0x35,0xbd,0x5f,0x7e,0x7c,0x5e,0x5f,0x5b,0xd7,0x32,0x54 +,0x88,0x45,0x6b,0x23,0x5b,0xba,0xd4,0xcf,0xae,0x83,0xec,0xf9,0xdd,0x3f,0xde,0xaf,0x77,0x90,0xfd,0xa2,0xf4,0x7f,0x0b,0xe2,0xdb,0x97,0x60,0x71,0x9b,0x89,0x95,0x27 +,0xf4,0x6d,0x00,0xfa,0x36,0xd1,0xf6,0xd6,0x74,0xd9,0x3f,0xf6,0x16,0xd1,0x1b,0x37,0x71,0xd3,0x40,0xd1,0x9f,0x4a,0x3b,0xac,0x39,0xff,0xa9,0x75,0x69,0x29,0x59,0xaf +,0xf1,0xf8,0x0b,0xeb,0x8a,0xbe,0x69,0xbf,0xd4,0x45,0x59,0xfd,0x5a,0x36,0xd3,0x8a,0x97,0xdb,0x73,0x77,0x75,0xd7,0x7b,0xbb,0x46,0xfb,0x6f,0x36,0x5d,0x96,0xa6,0xe4 +,0x06,0x8a,0xbf,0x3a,0x06,0xe8,0xce,0x94,0x8d,0x32,0x26,0xa9,0x5b,0x34,0x46,0x49,0x93,0x2d,0x62,0xd5,0x8e,0xe2,0xaa,0x2e,0x4a,0xe2,0xe8,0x46,0x16,0x09,0x76,0x82 +,0x10,0x92,0xed,0xeb,0xcf,0x80,0x09,0x09,0x00,0xa6,0x41,0xb1,0x90,0x2c,0x64,0x0b,0x05,0x02,0xc1,0x50,0xb0,0x54,0xe6,0x15,0x09,0x84,0x82,0x61,0x50,0x98,0x44,0x46 +,0x21,0x1b,0x9c,0xd6,0x1e,0xde,0x38,0xda,0xaa,0xea,0x2a,0x65,0xc8,0x74,0x8a,0xe5,0x77,0x31,0xc5,0x79,0x68,0x72,0x3f,0x83,0xff,0xc3,0x3f,0x9f,0xc0,0xbd,0x17,0xd1 +,0xdd,0x37,0x77,0xe1,0x35,0x0f,0x54,0x0b,0xf1,0x8e,0x6a,0x65,0xed,0xaf,0xb6,0xe9,0x57,0xb4,0x29,0x22,0xa7,0x3f,0xb7,0xb9,0xfc,0xe7,0x96,0x80,0xb6,0xc9,0xe9,0xfe +,0x27,0xfd,0xef,0x1e,0xfb,0x68,0x9b,0xe4,0x74,0xfc,0x3a,0x83,0x20,0x1a,0xb1,0xbf,0xdf,0xcb,0x9f,0xcc,0xea,0x8e,0x7f,0x5b,0xe6,0x9e,0x7d,0x0b,0x93,0x93,0xe1,0xcb +,0x8b,0x89,0xc3,0x97,0xcf,0x98,0xe7,0xc0,0x27,0x8d,0xb8,0xa5,0xb5,0xf3,0x1c,0x7c,0x40,0x73,0x71,0x0e,0x47,0x10,0xff,0xd0,0x1e,0x6c,0x1d,0x64,0x1c,0xba,0x9c,0x4f +,0xc6,0x27,0x46,0x7d,0x08,0x9b,0xd6,0xa3,0xa4,0xd1,0x19,0xe0,0xe8,0x4d,0xc1,0x58,0xf1,0x16,0xe2,0x24,0x84,0x20,0x77,0x7c,0xc9,0xa5,0x3a,0x54,0x92,0x50,0x94,0x5c +,0x11,0xb1,0xdd,0x4f,0xbb,0xdd,0x23,0x25,0x44,0x00,0x2e,0x49,0x48,0x81,0xc0,0xff,0xf1,0x50,0x80,0x2f,0x7f,0xfc,0x21,0x0a,0xcf,0xdf,0xee,0xff,0xf7,0xfb,0xae,0x70 +,0xc0,0x58,0x68,0x15,0x0a,0x05,0x84,0xe1,0x50,0xc0,0x50,0x4c,0x14,0x09,0x04,0xc2,0x41,0x42,0x28,0x44,0x26,0x11,0x11,0x84,0x44,0x61,0x12,0x18,0x44,0xae,0xea,0xed +,0x27,0x3f,0x1e,0xa6,0x5c,0xb9,0x5a,0xdb,0x55,0x53,0x54,0x75,0xcf,0xb7,0x7c,0xea,0xba,0x56,0x7c,0x6b,0x80,0xf8,0x3c,0x85,0x65,0xdb,0x67,0xbb,0xe2,0xdf,0x15,0x7c +,0xf9,0xb6,0xca,0xf7,0xfe,0xbe,0x6c,0x23,0xd5,0x2f,0x11,0x1b,0x74,0xf6,0x8e,0xfc,0xe7,0xe5,0x6a,0xdb,0xa8,0x96,0x97,0x79,0x47,0xdb,0xb3,0xf1,0x3a,0x46,0xb7,0xfd +,0xbc,0x85,0x6a,0x15,0x5b,0xf9,0xb8,0xe8,0x74,0x67,0xbd,0x8f,0xe1,0x6f,0x08,0xce,0xca,0xe8,0x94,0xba,0x7d,0x47,0xda,0x91,0xa4,0x3e,0x04,0x2d,0xc7,0x92,0x3f,0xb2 +,0xd1,0x1d,0xf1,0xf3,0x8d,0x1b,0x0f,0x60,0x1b,0xeb,0x39,0x5d,0x76,0x49,0x80,0x3e,0x64,0xb9,0x44,0xe1,0xfc,0xc4,0x61,0x54,0x1a,0x4a,0x6a,0xa2,0xec,0x41,0x20,0x07 +,0xba,0x9e,0x41,0x25,0x45,0x2c,0x64,0x00,0x11,0x14,0x01,0x38,0xa1,0x62,0x20,0x58,0x2a,0x14,0x0b,0x0a,0x02,0xc2,0x50,0xb0,0xe0,0x28,0x45,0x19,0x91,0x44,0x62,0x10 +,0x98,0x84,0x26,0x25,0x08,0x89,0xfc,0x32,0xef,0x7a,0xab,0x6e,0x26,0x5d,0x54,0x4a,0xbb,0x25,0xea,0xb9,0xeb,0x7b,0xbb,0xe2,0xb2,0x7b,0x40,0xed,0xe7,0x66,0xea,0x7d +,0x9b,0xe6,0xe7,0xfd,0x20,0xfd,0x8f,0xb7,0xf4,0xb7,0xf0,0xe9,0x50,0x46,0x61,0xa0,0x58,0xc7,0x5d,0x1f,0x00,0x8c,0x7f,0xa7,0x59,0xdd,0x52,0x52,0x81,0x37,0x80,0x50 +,0x9e,0x37,0xf1,0x88,0x8f,0x88,0xc6,0x57,0xdc,0xff,0xfa,0x74,0x7e,0xeb,0x99,0xf3,0x03,0xbe,0x9f,0xce,0xbb,0x45,0xf8,0x1b,0xef,0xd2,0x9c,0xf9,0x8e,0x7c,0x3e,0x1d +,0xe3,0x8f,0x31,0xcb,0xcf,0x33,0xc6,0x38,0x94,0xb9,0x7b,0x7f,0x0b,0xe0,0x38,0x1a,0x4f,0xa0,0xf7,0xe1,0x31,0x39,0xbc,0x8f,0xac,0xff,0xde,0xf5,0x83,0x88,0x0e,0x24 +,0xd1,0xcf,0x93,0x80,0x05,0xb8,0x39,0x11,0xfd,0xf0,0xfd,0xe5,0x1d,0xf2,0xf7,0x86,0x1b,0x26,0xc9,0x73,0x49,0x1f,0x75,0x98,0x3b,0xc5,0xe2,0x03,0xdd,0xf6,0x60,0xbd +,0xc7,0xae,0x1e,0x00,0x00,0x40,0x4c,0x9c,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x2d,0x3f,0xfc,0x21,0x0a,0xcf,0xdf,0xff,0x9f,0xeb,0xff,0xb1,0x60,0xa0,0x60,0x2c,0x17,0x0b +,0x15,0xc6,0x82,0x70,0xa1,0x48,0x28,0x25,0x09,0x88,0x44,0x62,0x16,0x15,0xc7,0x2e,0x19,0xed,0xf3,0xd7,0x7c,0x7b,0x7b,0xf1,0xcd,0x89,0x1d,0x56,0x57,0x1a,0xed,0x51 +,0x75,0x75,0x7f,0x78,0x0f,0x77,0xf4,0xd2,0xbb,0xf3,0x7b,0x3d,0xb6,0x81,0x3e,0xb1,0xdf,0xa3,0x9e,0xef,0x9f,0xef,0x64,0xc3,0xc1,0xd5,0x0f,0xf6,0xe3,0xb0,0xe9,0xaf +,0xe3,0x65,0x5e,0x65,0xf7,0xd5,0xb6,0x7e,0x4b,0x87,0x36,0x20,0x93,0x0d,0xb7,0xcd,0xa3,0xfb,0x4e,0xcf,0xc7,0x1e,0xe6,0x28,0x95,0x6d,0xdc,0x5f,0x99,0x3e,0x1e,0x7b +,0x75,0xf6,0xd4,0xc0,0xd4,0xaf,0x71,0x2a,0xc9,0x19,0x69,0xfe,0xfe,0x2c,0x7f,0x09,0x8a,0x23,0xa9,0x8d,0x2f,0x4a,0xe3,0x81,0x33,0xd1,0x81,0x59,0x17,0x5e,0xe5,0x30 +,0x61,0x52,0x56,0x40,0xba,0xa1,0x9e,0xcc,0x15,0x4d,0x39,0x9b,0x01,0xbd,0x68,0x05,0xac,0xa2,0x27,0x2a,0x4d,0x6a,0x81,0x8d,0x00,0x08,0x0b,0x01,0x4c,0xa1,0x60,0xa0 +,0x58,0xc6,0x16,0x0a,0x05,0x87,0x03,0x60,0xa0,0x98,0x28,0x25,0x0b,0x85,0x44,0x64,0x10,0x98,0xc4,0xec,0xac,0xd6,0x67,0xc7,0x8b,0x51,0x2b,0x5c,0xdc,0xe7,0x57,0x93 +,0x52,0xb5,0x7e,0xbe,0x2a,0xa5,0x7b,0x4f,0x1c,0x6b,0x7e,0x43,0xec,0xfa,0x1f,0xfb,0x5b,0xc9,0xf8,0xbf,0xdd,0x54,0x9d,0xf2,0xf2,0xe3,0x7f,0xe6,0x27,0x30,0xeb,0xff +,0xed,0xac,0xd3,0x97,0x29,0x6a,0x26,0xf0,0x4e,0x43,0x52,0x19,0x8b,0x22,0x89,0x6a,0xf1,0x6c,0x9b,0x8e,0x52,0x87,0x3a,0xd5,0xea,0x64,0xa3,0xe2,0x6a,0xcd,0x0f,0xf5 +,0x14,0x03,0x51,0xeb,0xed,0x50,0xe3,0xd5,0xf5,0x16,0x6f,0xef,0x53,0x99,0x6d,0xfa,0x9b,0x4e,0x2e,0xd3,0x9f,0x0e,0x3b,0xbb,0xca,0x40,0x5d,0x1c,0xe9,0x25,0xf3,0x88 +,0xae,0x67,0x34,0x5d,0x42,0x90,0x8f,0xc1,0x4f,0xd7,0x0e,0xff,0x70,0xef,0x16,0xef,0x4f,0x94,0x6c,0x03,0xf2,0x10,0x32,0xd4,0x43,0xb8,0xa7,0xae,0x00,0x7a,0xfd,0xeb +,0x7e,0xdc,0x83,0xbf,0x20,0x61,0x04,0x90,0x12,0x81,0x31,0x52,0x81,0x64,0x50,0x01,0x54,0x40,0x70,0xff,0xf1,0x50,0x80,0x2b,0x1f,0xfc,0x21,0x0a,0xcf,0xdf,0xdf,0xff +,0x7f,0xfe,0xb1,0x70,0xc0,0x5c,0x2c,0x17,0x0a,0x89,0x02,0xc1,0x40,0xb8,0x58,0x2e,0x16,0x0a,0x05,0x82,0x84,0x21,0x20,0x94,0x46,0x21,0x7b,0x73,0xef,0xf3,0x38,0xaa +,0xbe,0x66,0x6a,0x56,0xaa,0xf7,0x38,0xdc,0x71,0x90,0xb5,0x51,0xc5,0xe4,0xe3,0xea,0x83,0xcf,0xa9,0x4e,0x3b,0xce,0x5e,0xcf,0x6d,0xec,0x3d,0x7c,0xed,0x79,0x7e,0x57 +,0xf2,0x61,0x5c,0x58,0xa8,0xaa,0xfc,0x69,0x70,0xd5,0x4f,0xd2,0x84,0xd3,0xed,0x30,0xff,0x57,0xa7,0xaf,0x3f,0x29,0x97,0x70,0x46,0x6d,0x8d,0x65,0x7c,0x38,0xcd,0xc2 +,0x7c,0x16,0x07,0x9d,0x9e,0x06,0xf3,0x79,0x6c,0x24,0xac,0xe3,0xc2,0x08,0x2e,0x5d,0x55,0x2d,0x48,0x6d,0x6a,0xf1,0x78,0x28,0x3d,0xe3,0x23,0xad,0xcd,0x3a,0x2e,0x30 +,0xc4,0xe7,0x13,0x8e,0x82,0x16,0x56,0xe3,0xba,0x64,0xac,0x56,0x40,0xc9,0x78,0x8a,0x56,0xc4,0x05,0xaa,0x05,0xcc,0x6d,0xc0,0xac,0x40,0xa1,0x55,0x80,0x76,0x17,0x01 +,0x00,0x15,0x0c,0x48,0x0a,0x05,0x82,0x81,0x60,0xa0,0x54,0x2c,0x34,0x13,0x06,0x02,0x82,0x60,0xa0,0x58,0x28,0x43,0x20,0x84,0xc8,0x27,0x6f,0xae,0xe5,0x35,0x4d,0x72 +,0xb6,0x5e,0x0b,0x2e,0xa7,0x1a,0x5f,0x77,0x0e,0xba,0xe4,0x9e,0x43,0x6c,0xf7,0xd9,0x86,0xff,0x3b,0xf7,0x87,0xfd,0x45,0xfd,0xbc,0xdc,0xf9,0x7d,0x27,0xd9,0xe5,0x0b +,0x03,0xdf,0xa4,0xf9,0x27,0x65,0xac,0xfa,0x36,0x5f,0xa8,0xff,0xc8,0xe5,0xfd,0x80,0x92,0x67,0xba,0x08,0xa7,0x7f,0xee,0x7a,0x6f,0xee,0xdf,0x50,0xfa,0x38,0x2e,0xa3 +,0xba,0xa3,0xbb,0x7e,0x2f,0xc3,0x7d,0xf7,0x8d,0xb0,0xb1,0x49,0x1c,0x5e,0x36,0xc2,0x3f,0xc3,0xf7,0xf4,0xfd,0x6b,0xe1,0x1d,0x06,0xc6,0x48,0x30,0x06,0x34,0xc5,0x8f +,0xe4,0xd2,0xf7,0x17,0x1f,0x92,0x3c,0x44,0x7d,0x6e,0xe8,0x83,0xbd,0x21,0xee,0x0b,0x26,0x8b,0x23,0x04,0xfd,0x6a,0x05,0xce,0xe6,0x60,0x14,0x25,0xdc,0x27,0xee,0x26 +,0x0a,0x80,0x15,0x01,0x00,0x28,0x04,0x05,0x00,0x54,0x07,0xff,0xf1,0x50,0x80,0x30,0x1f,0xfc,0x21,0x0a,0xcf,0xd5,0x7b,0xff,0xdf,0xf4,0xaf,0x62,0x38,0x50,0x2a,0x16 +,0x1b,0x85,0x82,0xe1,0x42,0xb0,0x50,0x8a,0x22,0x18,0x85,0x42,0x22,0x30,0xa8,0x44,0x26,0x11,0x09,0x88,0x48,0xac,0xfb,0xfc,0xfd,0x67,0xb7,0xed,0xe7,0x96,0xef,0x55 +,0xac,0x65,0xc5,0xe6,0xa9,0x6a,0xad,0x75,0xce,0xbb,0xf3,0x3b,0xd7,0xfe,0x5c,0x01,0xf7,0xe5,0xe8,0xcb,0xe3,0xbe,0xcf,0x6d,0xd9,0x3b,0x47,0xb7,0x85,0x9c,0xb9,0xf8 +,0x7b,0x93,0x31,0xdb,0xc2,0xdf,0xe5,0xaf,0xe1,0x6a,0x4d,0x7d,0xe7,0x69,0x9f,0x5f,0x37,0xaf,0xd3,0x57,0xdc,0xb9,0xa0,0x12,0xd3,0xfe,0xc3,0x5e,0x9f,0x6a,0x3f,0x9b +,0x68,0x3e,0xcb,0x13,0x5f,0xc3,0x4d,0x66,0x57,0x1b,0xc1,0xd6,0x9f,0xcd,0x7c,0xf9,0x73,0x2d,0x2a,0x2c,0xf8,0x32,0xd5,0xa7,0x65,0xee,0x06,0x55,0xa4,0x82,0x14,0x87 +,0x3b,0x29,0x2d,0xaf,0xce,0x48,0x42,0x02,0x1a,0xe7,0x25,0x5b,0xfe,0x15,0x0b,0xc5,0x35,0x57,0xef,0xed,0x80,0xf1,0x00,0x8a,0xf1,0x95,0xc0,0xf1,0x88,0x70,0x2e,0x68 +,0x01,0xde,0x00,0xf5,0xca,0x54,0x94,0x4a,0x29,0x62,0xc0,0x26,0x02,0x69,0x42,0x82,0x62,0x20,0x58,0x4e,0x16,0x12,0x0e,0x02,0xc6,0x40,0xa8,0x4c,0x24,0x23,0x0a,0x84 +,0x42,0x62,0x11,0x18,0x44,0x46,0x21,0x1b,0xfa,0x49,0xba,0x6b,0x5e,0xbc,0xf3,0x74,0x99,0x74,0x91,0x5a,0x94,0xb9,0x5c,0x57,0xeb,0xfb,0x75,0xdf,0xe3,0xe3,0xfa,0xd7 +,0xde,0xc7,0x07,0xf2,0x5f,0xd1,0x1f,0xcd,0xf8,0xb7,0xca,0x51,0xe6,0xff,0x7c,0x9b,0x79,0x79,0xbf,0x43,0x90,0x8b,0x2f,0x2d,0x65,0x6c,0x9d,0x5f,0xfd,0xbe,0xf8,0x11 +,0xf0,0x1e,0x3f,0xc5,0x20,0x4b,0xbe,0x6a,0x48,0x3c,0xd2,0xa6,0x80,0x71,0xbf,0x5a,0xcb,0x36,0x91,0x2b,0x8c,0xe9,0x93,0xdf,0xc6,0x1a,0x2f,0xe8,0xf5,0xf1,0xbb,0x64 +,0xa6,0x00,0x71,0xe8,0xee,0xf0,0xdf,0x38,0x72,0x9a,0x8f,0x9d,0x17,0xed,0xbc,0x8f,0x42,0x56,0xc4,0xef,0x75,0x09,0x34,0x83,0x18,0x0c,0xa5,0x5b,0xf6,0xb8,0x36,0xa4 +,0x71,0x14,0x1c,0xc1,0xc1,0x39,0xc5,0xaa,0x33,0xf7,0x7f,0xc6,0x02,0x6f,0x75,0x67,0xaf,0x05,0x64,0x11,0x9d,0xfa,0x48,0x00,0xee,0x16,0x82,0xc9,0x81,0xc5,0x00,0x3c +,0xe3,0xb8,0x00,0x8d,0x65,0x52,0x7b,0xa8,0x04,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2f,0xdf,0xfc,0x21,0x0a,0xcf,0xc7,0xfd,0xe4,0xff,0xfc,0xae,0x60,0xc0,0x58,0x4e,0x14 +,0x0a,0x85,0x04,0x61,0x61,0x38,0x50,0x6c,0x34,0x0a,0x89,0x04,0xa1,0x20,0xa8,0x48,0x26,0x11,0x39,0x88,0x4a,0xee,0xfa,0xef,0x8b,0x76,0x5e,0xf5,0xae,0x75,0xbb,0x46 +,0x4d,0x65,0xba,0xe4,0xc9,0x2f,0x8a,0xdd,0x5f,0xfe,0xe0,0x9d,0xc0,0xce,0xe5,0xd9,0xdb,0x47,0x7d,0x7b,0x9b,0x9f,0xe8,0xbe,0x47,0xfe,0x3f,0xdd,0x05,0x36,0x00,0xe0 +,0xd4,0xfe,0xa8,0xfc,0x6e,0x89,0x01,0xe5,0xbc,0x9f,0x8e,0x99,0x4f,0xdf,0xf4,0x98,0xa5,0x79,0xb7,0x90,0x25,0x0b,0x47,0xa1,0xfb,0xfc,0xce,0x13,0xad,0xf6,0x51,0xd3 +,0x6f,0xa0,0x85,0x8d,0xd1,0x48,0xf5,0x71,0x2b,0xf7,0x57,0x96,0x8a,0xe3,0xac,0xf3,0x60,0xad,0x3c,0xa6,0x97,0xb2,0x1d,0x53,0x66,0x5a,0x0c,0x8f,0x22,0xad,0x1e,0xe0 +,0xeb,0xff,0x8c,0x25,0x35,0x61,0x8d,0xf5,0x81,0xa2,0x79,0x61,0x24,0xab,0xcd,0xde,0x84,0x5b,0xad,0xe5,0x4d,0x09,0xa1,0xbf,0xbd,0x6c,0xe8,0xad,0x04,0x01,0xee,0xfb +,0x80,0xd4,0x6e,0x9c,0x56,0x92,0xd3,0x80,0xe8,0x4e,0xf0,0x05,0x60,0x15,0x26,0x05,0x52,0x05,0x89,0x01,0x70,0xb0,0x50,0x2c,0x14,0x0b,0x05,0x02,0xc4,0x40,0xb0,0x50 +,0x6c,0x14,0x1a,0x88,0xc4,0x22,0x50,0x88,0x54,0x22,0x15,0x10,0x84,0xc2,0x23,0x4c,0xae,0x3c,0x5f,0xf3,0xf9,0xa2,0xea,0xb2,0x4b,0xc2,0x2e,0xa7,0x9d,0xf4,0xeb,0x7e +,0x7c,0x7a,0xf8,0x9d,0x7c,0xfd,0xeb,0xf0,0x35,0x89,0xeb,0x6d,0x47,0xd7,0xaa,0xad,0x1b,0xf1,0xf6,0xbd,0x3c,0x74,0x9b,0x6a,0xdf,0xbd,0x13,0x14,0xff,0x7b,0x5f,0xf3 +,0xd1,0x6e,0x80,0xea,0xa9,0x52,0x26,0x3e,0xd2,0x39,0x77,0x56,0xe5,0x9f,0x7c,0x13,0x43,0xfc,0x0f,0x83,0xf5,0x6f,0x73,0xfd,0xdc,0x4f,0x8b,0xff,0xe9,0xac,0x78,0xe9 +,0x3b,0x27,0x82,0x00,0xde,0xac,0xf7,0x00,0xb2,0x6a,0xd1,0x3e,0x72,0x3c,0xd5,0x7b,0xd8,0x82,0xff,0x31,0xab,0x25,0xec,0xe1,0x53,0xcb,0x9f,0x91,0xc5,0xd7,0xc0,0x80 +,0xaf,0xb6,0x3d,0x7e,0xf3,0xbb,0xee,0x02,0x49,0xaf,0x20,0x94,0x05,0x80,0x0f,0x10,0x20,0x05,0x43,0xc0,0x00,0x1d,0xa6,0xa5,0x47,0x80,0x00,0x00,0x01,0xe4,0x04,0x07 +,0x70,0xf6,0xc0,0x58,0x00,0x94,0x8a,0x81,0xc0,0xff,0xf1,0x50,0x80,0x2b,0xdf,0xfc,0x21,0x0a,0xcf,0x8f,0xe3,0xfe,0xff,0xfc,0xb2,0x70,0xb0,0x60,0x2c,0x15,0x11,0x05 +,0x02,0x41,0x30,0xb8,0x50,0x2e,0x14,0x13,0x84,0x82,0xc1,0x50,0xa1,0x08,0x6a,0x11,0x09,0x94,0x54,0xaa,0xf6,0xb9,0x53,0x75,0x4c,0xbe,0xbc,0x6a,0x54,0xa8,0x45,0xd7 +,0x0b,0x66,0x4a,0x92,0x97,0xfa,0x83,0xc2,0x93,0xec,0x6e,0xd7,0xb3,0x2f,0x83,0x93,0xf3,0xda,0x7d,0xff,0xc7,0xed,0x62,0xb0,0x1f,0x38,0xf9,0xf8,0xfd,0x34,0xcf,0x56 +,0xdf,0x73,0x35,0x9f,0x97,0xe7,0x92,0x1b,0x22,0xf8,0x66,0xaf,0x8b,0x9d,0x80,0x47,0xb2,0x56,0x4e,0x84,0x99,0x5e,0xef,0xd9,0xae,0xde,0xfd,0x78,0xf3,0xaf,0xbd,0x90 +,0xd1,0xd3,0x17,0x0e,0xef,0x13,0x05,0x51,0x33,0x85,0xbd,0xd5,0x2f,0xc2,0xf1,0xc1,0xb1,0xf8,0x92,0xab,0x3b,0xf2,0x88,0x1e,0x01,0x6a,0x85,0x89,0xd7,0xb8,0x7a,0xea +,0xea,0x11,0x38,0xdd,0x79,0x8c,0x0a,0xac,0x4e,0xa3,0x5a,0xfc,0xe6,0x4d,0x2e,0xa0,0x49,0xd4,0x11,0x69,0x2f,0x81,0x8c,0x48,0x51,0x64,0xc2,0x20,0x4f,0x20,0x98,0x90 +,0x16,0x12,0x85,0x02,0xc9,0x41,0x30,0x54,0x24,0x15,0x11,0x85,0x42,0x22,0x30,0xa8,0x8c,0x22,0x13,0x08,0x84,0xc4,0x23,0x7d,0xb7,0x59,0xac,0xfa,0xf4,0xd6,0x4c,0x53 +,0x54,0x81,0xe7,0x7e,0xd7,0xd5,0x7a,0xd4,0xce,0x7a,0xef,0xa7,0x1f,0x5f,0xe4,0x78,0x3d,0x96,0xc4,0xb3,0xdd,0xe1,0xcb,0xf5,0x31,0xb6,0x7f,0x7c,0x36,0x0b,0xda,0x07 +,0xf8,0x78,0x3b,0x7e,0x08,0x5b,0x67,0xc5,0xf8,0x27,0x94,0x69,0x0e,0x50,0x3e,0x94,0xdd,0xf4,0x4a,0x81,0xa1,0x36,0x8b,0xa7,0x2f,0x05,0x29,0x06,0x36,0xcb,0xf9,0x6f +,0x46,0xce,0xaf,0x8c,0xa2,0x5a,0x7e,0x92,0x98,0x54,0x08,0xc7,0x6c,0x45,0xbc,0xdc,0x30,0x8f,0x87,0x45,0xd5,0xe0,0x38,0x96,0x38,0x92,0xc0,0xee,0xe3,0x27,0xff,0xe4 +,0x1e,0x00,0x18,0x19,0x6a,0x03,0x68,0xb8,0x7a,0xc7,0x7b,0xdc,0x00,0x1e,0x60,0x00,0x01,0xe3,0xdd,0x04,0xc5,0x29,0x92,0x20,0x1d,0xc2,0xd4,0x14,0xdc,0x7b,0x97,0x03 +,0xb8,0x58,0x04,0x40,0x14,0xb8,0x0e,0xff,0xf1,0x50,0x80,0x2b,0xff,0xfc,0x21,0x2a,0xcf,0xcd,0xf6,0x3f,0xff,0x7e,0xad,0x62,0x38,0x50,0xb0,0x15,0x0b,0x05,0x05,0x01 +,0x50,0xa0,0x60,0x28,0x42,0x0a,0x04,0x84,0x62,0x10,0x98,0x44,0x46,0x11,0x11,0x84,0x4c,0xda,0x67,0x55,0x52,0x65,0xf3,0xc5,0xf7,0x73,0x1a,0x12,0xe4,0xbc,0xbd,0xce +,0x39,0xf6,0xe6,0xf7,0x73,0xfd,0x20,0x3d,0x29,0xe6,0xa7,0xd5,0xce,0x3b,0xc8,0xd9,0xb4,0xae,0x8f,0xf9,0x57,0x32,0xef,0xb0,0xe0,0x5f,0xa5,0x0a,0xbf,0x5d,0x9f,0xd9 +,0xec,0x79,0x17,0x37,0xea,0x80,0x05,0xdf,0x53,0xe6,0xd7,0xfd,0x3d,0x57,0x72,0x71,0x89,0x63,0xe8,0x1a,0xeb,0x92,0xf8,0x21,0xc4,0x7b,0xfb,0x9c,0xf0,0xe9,0x6f,0x68 +,0xaa,0xad,0xfb,0xd4,0x3e,0xd6,0xf9,0x45,0x45,0xd4,0xed,0x1d,0xd2,0xd8,0x0d,0x30,0x47,0x84,0x29,0xff,0x45,0xb0,0x54,0xef,0x78,0xf4,0x77,0xaa,0x5e,0xf2,0x9d,0x3d +,0x8d,0x12,0xa0,0xd0,0x6d,0x32,0x15,0xb1,0x4d,0x73,0x1d,0xc6,0x91,0x15,0x6d,0x2b,0x40,0xe8,0x00,0x1e,0x56,0x12,0x04,0x2b,0xd3,0x18,0x16,0x0a,0x54,0xc7,0x10,0x02 +,0xe2,0xc0,0x53,0xb0,0x50,0x2c,0x55,0x0b,0x11,0x02,0xc1,0x70,0xb1,0x50,0x24,0x16,0x0a,0x04,0x82,0x81,0x70,0x98,0x44,0x26,0x11,0x6a,0xb9,0xad,0x73,0x3a,0xcd,0xf0 +,0x4c,0xa9,0x51,0xbe,0x25,0x4b,0x6b,0xce,0x4a,0x6b,0x3d,0xfe,0x2f,0xbf,0x87,0x9f,0xa0,0x3c,0xfe,0xe3,0x36,0xad,0x7b,0x76,0x63,0xf5,0xcd,0x7f,0x0f,0x5f,0x33,0x7f +,0x54,0x9a,0x89,0x38,0x03,0xc8,0xaf,0xe7,0x39,0x1e,0xad,0x9d,0xb3,0x7d,0xa8,0x2f,0xcd,0x5a,0xbd,0xf8,0xd5,0x7e,0xb3,0x57,0x7f,0x16,0x81,0x0d,0x94,0x79,0x84,0x7e +,0x29,0xef,0x7d,0x27,0x47,0x4f,0xe2,0x70,0xd6,0x35,0x25,0x04,0x64,0x35,0x16,0x51,0x6a,0xc3,0x71,0xdf,0x6d,0x8b,0xa9,0x3b,0xf0,0x59,0x4a,0x6c,0x4d,0xf6,0x1b,0x0e +,0xfe,0x0e,0xe1,0x40,0x7c,0xe1,0xeb,0x04,0xea,0x04,0xbe,0x22,0x01,0xa4,0x0f,0xf0,0x80,0x1a,0x44,0xd0,0x05,0xd2,0xfa,0xe2,0x70,0x4a,0x21,0x04,0xc3,0x9a,0xe0,0xe0 +,0x00,0x11,0x00,0x45,0x9c,0x0e,0xff,0xf1,0x50,0x80,0x30,0xdf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x4d,0x16,0x30,0x59,0xa9,0x36,0x29,0x24,0x46,0x89,0xa0,0x8b,0x87,0xa3 +,0x2e,0xcc,0x8a,0xbd,0x18,0x2e,0xca,0x77,0x67,0x5f,0xcb,0xa1,0x64,0xfd,0x2e,0xbb,0xb1,0x4e,0xfe,0x5e,0x8f,0xdf,0xbf,0x6f,0x0d,0xd3,0x5f,0x31,0x9e,0x01,0x52,0xdb +,0xd1,0x78,0xdb,0x64,0x63,0x29,0xfb,0x32,0xfd,0x16,0x55,0xee,0xbc,0xb7,0xc1,0xe7,0x23,0x40,0xbc,0x88,0x2a,0x81,0xbb,0xd9,0xd7,0x36,0xcc,0x40,0xea,0x62,0x18,0x22 +,0x08,0x03,0x03,0xb5,0x22,0xd3,0xe5,0x9f,0xd2,0xf6,0x2a,0x2f,0xa0,0xf4,0x4d,0x64,0xe5,0xa5,0x12,0x4a,0x37,0xb7,0xb7,0x5e,0xcf,0xa7,0xe5,0x3d,0xf9,0xbb,0xe3,0x87 +,0x0d,0xee,0xe2,0x13,0xc7,0x3f,0xeb,0xbf,0x9e,0x7b,0x24,0x70,0xf9,0x2d,0x01,0x44,0xe9,0x5b,0x4b,0x87,0x1f,0xfc,0x9f,0xbf,0xf9,0x3c,0x3a,0x2b,0x70,0x46,0x3a,0xa0 +,0x82,0x64,0x23,0x4f,0x69,0xde,0xf2,0xec,0xdc,0xd9,0xde,0x95,0xd6,0x8d,0xe9,0x68,0x54,0x34,0x18,0x29,0x39,0xe7,0xae,0x1b,0x4d,0x52,0xe4,0x02,0x27,0x48,0x9d,0x3d +,0x84,0xae,0x48,0x30,0x14,0x50,0x59,0x41,0x66,0x88,0xd0,0x94,0x65,0xc9,0x6a,0xd7,0x01,0x26,0xf4,0xa4,0x4c,0xb7,0x3e,0x7c,0xc8,0xd4,0x92,0xf5,0x23,0x75,0x49,0xf4 +,0xf3,0xf0,0x1f,0xee,0xf2,0xae,0xcf,0x27,0xa7,0xcf,0x7c,0x69,0xf0,0x9f,0xec,0xdf,0x8e,0x7f,0x8c,0x18,0xb8,0x7d,0x6d,0xcf,0x3b,0x30,0xe0,0x0b,0xc4,0x64,0x7b,0xda +,0x72,0x69,0xd5,0x52,0x9e,0x92,0xda,0x99,0xed,0xc2,0x95,0xe2,0xed,0xb3,0xba,0xa9,0x26,0x2e,0xeb,0x95,0x71,0xa1,0xa1,0xa2,0x38,0xc8,0xa3,0x42,0xd8,0x39,0xbd,0x1a +,0x7b,0x53,0xdf,0x52,0xdf,0x43,0x4b,0x28,0x48,0x86,0x02,0x25,0x30,0x99,0x22,0x4e,0xf2,0x04,0xd1,0xc8,0xf4,0xd3,0xeb,0x20,0xb5,0xd7,0x38,0x13,0x65,0x64,0x2e,0x6b +,0xdb,0xad,0xb5,0x20,0x31,0x43,0x9e,0x6a,0x02,0xea,0xb5,0x52,0xc8,0xb0,0x1c,0x5e,0x5a,0xa8,0x18,0xbb,0xc7,0x68,0x85,0x54,0x4a,0xfc,0x88,0x88,0xeb,0xb4,0x9c,0x01 +,0xb5,0x8a,0xfc,0x0e,0x7f,0xfd,0xdf,0x1f,0xb7,0xe5,0xf4,0xaf,0xb4,0xbd,0xdb,0x1d,0x3e,0xde,0xe4,0x04,0xf9,0x86,0x96,0x2a,0xd7,0x16,0x92,0x9a,0xd8,0xe9,0x5c,0x10 +,0x94,0x75,0x0d,0x42,0xa7,0x6b,0x91,0xb9,0x0b,0x0d,0x84,0x47,0xff,0xf1,0x50,0x80,0x2d,0x9f,0xfc,0x21,0x6a,0xcf,0xbf,0x7f,0xff,0xff,0xfd,0xb6,0x80,0xb0,0xd4,0x2c +,0x14,0x23,0x05,0x42,0x82,0x50,0x90,0x51,0x04,0x41,0x39,0x84,0x42,0x63,0x11,0xbc,0xf7,0xe6,0xf7,0x5e,0xde,0xa2,0xa2,0x5e,0x22,0xd9,0xac,0xa4,0x89,0x78,0x79,0xdf +,0x47,0x7e,0x7f,0x03,0x0f,0x03,0xfe,0xf5,0x7d,0x3b,0xfc,0xf7,0xbe,0x1a,0x8b,0x6b,0xf9,0x9f,0xfb,0x7e,0xe7,0xb1,0x9d,0x75,0x6f,0xeb,0xa4,0xba,0x6d,0x2d,0xbe,0x3b +,0x9d,0x7e,0xde,0x75,0xff,0x43,0xac,0x2e,0x7b,0x7c,0x9e,0xe2,0xef,0x76,0x80,0xdc,0xfb,0x2f,0x5d,0xca,0xa2,0xa0,0xdc,0x84,0xe3,0xe7,0xdb,0x2d,0x87,0x94,0x09,0x37 +,0x8f,0x61,0xdb,0x96,0x3c,0x9f,0x58,0x71,0x5a,0x9a,0xe9,0x3f,0x91,0x24,0xca,0xe2,0x98,0x55,0xf1,0x1d,0x7b,0x4f,0x12,0xb2,0xec,0xd5,0x34,0x57,0x4a,0xd2,0x88,0x9d +,0xe2,0xb4,0xd4,0x6d,0xf0,0x44,0x5e,0x79,0x84,0x52,0x42,0x60,0xf5,0xa0,0x09,0x5a,0xe4,0x43,0xb8,0x01,0xde,0xee,0x00,0xe7,0x49,0xd4,0x00,0x5d,0x50,0x2a,0x50,0x2c +,0x55,0x0b,0x05,0x42,0x81,0x61,0x20,0xd8,0x70,0x14,0x12,0x85,0x04,0xa3,0x30,0x88,0x4c,0x2a,0x21,0x0a,0x88,0xc4,0xa1,0x12,0xb7,0xad,0xba,0xcf,0x6f,0x18,0xdf,0x15 +,0x33,0xae,0x62,0xa2,0xd6,0xbe,0xbb,0xdc,0xfa,0xf7,0xf3,0x8e,0x29,0xa6,0x87,0x1b,0xb7,0xcf,0xe4,0x1e,0x5b,0xbd,0x3b,0x7f,0x54,0xbe,0x3c,0x5f,0xb5,0xbb,0x6c,0x69 +,0x23,0xaa,0xba,0xf3,0xff,0x6f,0xf1,0x35,0xbe,0xa8,0xfd,0xae,0xd3,0xec,0xa1,0x66,0x11,0x7d,0xe5,0x46,0x2d,0x4f,0x56,0xa6,0xb5,0xe3,0xb9,0x2e,0x53,0xf5,0x78,0xb7 +,0xfe,0x79,0xe1,0xfc,0x67,0x87,0xc1,0x1d,0xca,0x7c,0xf7,0xb7,0xfd,0xc4,0xbd,0x35,0xbe,0x77,0x35,0xa3,0xce,0x4e,0xae,0x58,0xc7,0x2a,0x25,0xf2,0x17,0xcd,0x20,0xcf +,0x91,0xee,0x7f,0xe6,0x97,0x0f,0x20,0xc5,0x1b,0x4a,0x7e,0xb4,0xc3,0xae,0xb4,0x08,0x47,0x2e,0x6a,0xb9,0x71,0x24,0x71,0x38,0x0c,0x45,0x00,0x82,0x0e,0x9f,0x11,0xc4 +,0x3c,0xc0,0xb1,0x51,0xc4,0x1d,0xd3,0xf6,0x10,0x35,0x66,0x7b,0x40,0x00,0x59,0x11,0x80,0x05,0x49,0x81,0x02,0x86,0x50,0x1c,0xff,0xf1,0x50,0x80,0x31,0x5f,0xfc,0x21 +,0x0a,0xcf,0xcd,0xff,0xdf,0xff,0xbc,0xb4,0x81,0x30,0x50,0x2a,0x14,0x0b,0x05,0x46,0x83,0x30,0xa1,0x18,0x28,0x12,0x0a,0x04,0x82,0x81,0x20,0xa0,0x48,0x46,0x11,0x11 +,0x0c,0xc4,0x21,0x30,0x89,0x5c,0x4c,0xfa,0xde,0xbd,0x71,0xaf,0x55,0x72,0x97,0xb9,0x52,0xf3,0x5b,0xb2,0x50,0xae,0x35,0xcf,0x58,0xaf,0xbc,0x1d,0x85,0xb7,0x41,0xe4 +,0xf6,0x7d,0x5b,0xd8,0xe4,0xc3,0xcf,0xc5,0xde,0x76,0x75,0x9c,0xdb,0x51,0xfd,0xe7,0xc6,0xee,0xaf,0xfa,0x9f,0x33,0x88,0xf5,0x9e,0x56,0x5a,0x3f,0x4c,0x23,0x0c,0xde +,0xa6,0xa2,0xa0,0x91,0xea,0x7f,0xb4,0xbb,0xfb,0x82,0x6d,0xe8,0x6e,0xa6,0x67,0xf2,0xec,0xb9,0x9d,0xfa,0x98,0x7a,0x49,0xdd,0xe9,0x06,0x0f,0xa5,0x7d,0x62,0x65,0xcf +,0x38,0xe8,0x2f,0xf2,0xda,0xf0,0x8a,0x20,0xe7,0xce,0xd7,0x42,0xd1,0xd3,0x5e,0x56,0xa5,0xa9,0x7b,0xfb,0x66,0x9f,0x5f,0x75,0x46,0x53,0xa6,0x13,0x40,0x85,0x4a,0x39 +,0x27,0xc2,0x9a,0xf3,0x8b,0x92,0x49,0x23,0x4f,0xcd,0xd5,0x45,0x40,0xee,0xbb,0x49,0xd2,0x2c,0x63,0xf8,0x40,0x2b,0x8c,0x2c,0xea,0xb0,0x88,0x32,0x72,0x02,0x82,0x00 +,0x27,0x58,0x48,0x16,0x0a,0x06,0x04,0xc1,0x40,0xb0,0x50,0x2c,0x14,0x0a,0x85,0x02,0xc1,0x50,0xa0,0x98,0x28,0x45,0x13,0x85,0x42,0x21,0x30,0xa8,0x84,0x26,0x15,0x09 +,0x85,0x42,0x21,0x31,0x08,0xdf,0xc7,0x5e,0xbd,0xbd,0x3f,0xf6,0xff,0xa6,0x6a,0xaf,0x15,0x78,0xe3,0x37,0x77,0x77,0xd3,0xe3,0xf3,0x5d,0x7b,0x7f,0x1e,0x71,0xc6,0x6b +,0xe3,0xdb,0x81,0x27,0x76,0xee,0x5f,0xd5,0x34,0xdd,0xfd,0x23,0x3d,0x30,0x69,0x3e,0xb4,0xe8,0xed,0xba,0x38,0x8f,0xde,0xb3,0x0b,0xfb,0xbf,0xe7,0xfe,0x1b,0xb1,0xe3 +,0x3f,0x7d,0x19,0x37,0x1e,0x22,0xf9,0x4f,0x3e,0x6b,0xfb,0xe3,0x3f,0xd3,0xbd,0xdd,0xb3,0x83,0x54,0x21,0x47,0xd6,0x37,0x4e,0xe3,0xab,0xff,0x7d,0xdf,0xc4,0x63,0xc9 +,0x3f,0xb7,0xe9,0x70,0x99,0x5e,0xf6,0xff,0xbf,0xcd,0x0e,0x45,0xb8,0x72,0x78,0x08,0x09,0x79,0xc0,0xa5,0x9e,0xb0,0x00,0x09,0x30,0xbd,0x7f,0xfd,0x65,0x43,0xc2,0x79 +,0x00,0x14,0x00,0x1e,0x40,0x0b,0xd1,0x43,0xff,0xf3,0x81,0x20,0x00,0xf3,0x00,0x3f,0xf5,0x00,0xf3,0x14,0x1e,0x60,0x1a,0xce,0xf8,0x07,0x77,0xb8,0x00,0x58,0x2a,0x24 +,0x03,0x80,0xff,0xf1,0x50,0x80,0x30,0x1f,0xfc,0x21,0x0a,0xcf,0xef,0x7e,0x7f,0xef,0x7c,0xb4,0x62,0x28,0x50,0x4c,0x14,0x1b,0x85,0x42,0x83,0x51,0x38,0x50,0x2a,0x14 +,0x21,0x09,0x02,0x42,0x10,0xa8,0x4c,0x42,0x13,0x08,0x88,0xc2,0x21,0x30,0x88,0x9c,0x73,0xe5,0x52,0xa6,0xb3,0x72,0x71,0xdd,0xb2,0x4a,0xd5,0x19,0x67,0xdf,0x7b,0xdf +,0x1a,0xe5,0xc7,0x3c,0x7f,0xd7,0xd8,0x7e,0xfd,0x7d,0x3c,0xda,0x7b,0xbd,0x38,0xfd,0x0d,0xfb,0x90,0xe9,0x1e,0x7f,0xd8,0x68,0xf3,0xdb,0xf3,0x7b,0x3e,0xe7,0x9c,0x7a +,0xb4,0x76,0xd0,0x3b,0xb3,0xd2,0x33,0x4f,0x9c,0xd6,0xbc,0xdc,0x3e,0x44,0xa7,0x6c,0xfe,0xff,0xa5,0xca,0x39,0xb9,0x6d,0x24,0xba,0x58,0xd5,0x2d,0x91,0xc6,0x60,0xbe +,0xc8,0x6c,0x3d,0xb8,0x61,0xdb,0x6f,0x50,0x72,0xea,0xf8,0x89,0x31,0xd3,0x8c,0x09,0xee,0x53,0x97,0xcd,0x52,0xd3,0x56,0xbf,0xf4,0x8e,0x2c,0x72,0x5c,0xa8,0x5f,0x68 +,0xdb,0x2a,0x02,0x03,0xc4,0x03,0xc0,0x0f,0x70,0x77,0x2b,0xb3,0x3f,0x49,0xe3,0xa4,0xa1,0x58,0x76,0x11,0x98,0xf7,0x43,0xf5,0x9b,0x2a,0xa8,0x8a,0xad,0x4c,0xf1,0xf1 +,0x81,0xdf,0x8a,0xf3,0x41,0xb6,0x7e,0xc2,0xa0,0x02,0xa8,0x80,0xa7,0x62,0xa8,0x50,0x2c,0x14,0x0b,0x05,0x42,0xc4,0x40,0xb0,0xd0,0x4c,0x24,0x0a,0x8c,0x46,0x61,0x11 +,0x18,0x44,0x28,0x11,0x20,0x04,0x44,0xe4,0xbb,0xe7,0xfc,0x7e,0x99,0x7b,0xd5,0x2b,0x2c,0x45,0xdc,0xe3,0xdb,0xfd,0xbf,0xd7,0xf6,0xfd,0x7f,0xcf,0xfe,0x95,0x9f,0xaf +,0xc7,0x8d,0x7f,0xb7,0xb0,0x4e,0xfe,0x7d,0xfc,0x31,0xec,0xb6,0xae,0x7f,0x43,0xf5,0x2d,0x83,0xa0,0xf9,0x54,0xf7,0x75,0xb0,0xaf,0xa2,0x70,0x18,0xb2,0xe0,0xdc,0xf0 +,0x12,0x6a,0xe3,0x7f,0x4b,0x59,0x65,0xde,0xfd,0x52,0xde,0xf3,0x58,0xd6,0x5b,0xeb,0xf0,0xfe,0x57,0xc9,0xfb,0x6f,0xcf,0xee,0xf2,0x77,0xae,0x69,0xb6,0x54,0x24,0x8a +,0xa7,0x2d,0xdb,0xcb,0x7e,0xeb,0xbd,0x47,0xb2,0x89,0x15,0xcb,0xc5,0xc3,0xae,0x24,0xf2,0x02,0x38,0x0f,0x00,0x29,0xef,0x88,0x01,0x89,0x38,0xe0,0x0a,0x7c,0x24,0xbb +,0xaf,0xcb,0xff,0x72,0xa8,0xa0,0x02,0xcd,0xa7,0xcb,0x9d,0xff,0xdb,0xb4,0x3b,0x08,0xcc,0xe4,0xef,0x79,0xda,0xf7,0x37,0x25,0x22,0x00,0x14,0xb0,0x01,0xe6,0x08,0x80 +,0x44,0x0e,0xff,0xf1,0x50,0x80,0x2c,0x5f,0xfc,0x21,0x0a,0x8f,0xe7,0x7e,0xff,0xff,0xff,0x65,0x01,0x62,0x21,0x14,0x28,0x16,0x0a,0x0d,0x84,0x81,0x61,0x20,0xd4,0x24 +,0x24,0x11,0x04,0xc6,0x41,0x30,0x89,0x8c,0x22,0x14,0xdf,0x9d,0xeb,0x8e,0x5e,0x7d,0x24,0xaa,0xd5,0x55,0xca,0x15,0x67,0x17,0x5d,0xeb,0x27,0x17,0xdc,0xe3,0xff,0xc8 +,0x07,0x61,0xdb,0xef,0xf6,0xf9,0xb6,0xe5,0xea,0x2e,0x63,0xe3,0x69,0x3d,0x14,0xec,0xd7,0xbf,0xed,0x80,0xb7,0xc4,0x6f,0xc7,0xf5,0x31,0xf2,0x1c,0xc7,0xd0,0x6e,0x8c +,0x45,0xbc,0x13,0xfd,0xd0,0x7f,0xe2,0x25,0x74,0x52,0xd6,0xa4,0xca,0xe2,0x9c,0xcb,0xa8,0xe7,0xb5,0xdd,0xa5,0x21,0xd4,0x34,0x8b,0xc4,0xd6,0x1e,0x15,0xa6,0x58,0x5a +,0xf7,0x9c,0xde,0x73,0x77,0xd0,0xe8,0xf9,0xe1,0x48,0xe1,0xdd,0x60,0x22,0xf5,0xcc,0x9d,0x24,0xd4,0xb6,0x2c,0xef,0x37,0x35,0x13,0xfd,0x7b,0xd7,0x3d,0x77,0x79,0x14 +,0x3b,0xe3,0xb8,0x72,0x42,0xb3,0xba,0x99,0x8b,0x9e,0xee,0xc5,0x76,0x0a,0x2c,0x20,0x5f,0xdf,0x05,0xa6,0x54,0x40,0x18,0x72,0xd2,0xc1,0x4e,0xd1,0x4c,0x25,0xee,0x80 +,0xb0,0x13,0xec,0x67,0x0b,0x05,0x06,0xc1,0x40,0xb2,0x10,0x2a,0x14,0x0a,0x85,0xc2,0xa1,0x70,0x88,0x54,0x22,0x15,0x08,0xa0,0x02,0x21,0x7f,0x11,0xe7,0xd4,0xfb,0xf3 +,0xb2,0x97,0xbb,0xc6,0xb7,0x72,0xaf,0x4f,0x3f,0xef,0xff,0x17,0x5c,0x6d,0xaf,0xaf,0xfa,0xcb,0xc1,0x26,0xbd,0x1b,0xa4,0xec,0xe7,0x87,0x0a,0xfd,0x63,0x3d,0xcf,0xb3 +,0x96,0xe3,0xe3,0xff,0x4c,0xd3,0xff,0x02,0xa4,0x3e,0x39,0xc8,0x53,0x2e,0x29,0xcd,0xaf,0xf5,0x53,0xce,0x2a,0xe6,0x4f,0x26,0xd7,0xd4,0x0b,0x7e,0x8f,0x10,0xb6,0x69 +,0x0a,0xd0,0x87,0xfd,0x46,0x9e,0x73,0x19,0x79,0x9c,0x93,0xec,0x86,0x4e,0x9a,0xf2,0xe1,0xbd,0xcd,0xe2,0xf5,0xfc,0xaf,0xdf,0x5b,0x35,0xc6,0x3a,0x87,0x9b,0x6e,0xd3 +,0x60,0x3c,0xc2,0xc4,0xf0,0xd1,0xe5,0x00,0x00,0xa6,0xf1,0xe4,0x00,0x16,0x05,0x22,0x1e,0x00,0x00,0x0e,0x05,0xe8,0x80,0xbd,0x40,0xe9,0x00,0x20,0x00,0xb8,0x01,0x72 +,0x8a,0x00,0x13,0x38,0xff,0xf1,0x50,0x80,0x2d,0xdf,0xfc,0x21,0x0a,0x8f,0xfb,0xfe,0xef,0xff,0xff,0x63,0x03,0x60,0xa8,0x90,0x2c,0x14,0x23,0x05,0x02,0xa2,0x40,0xb0 +,0x60,0x28,0x26,0x0a,0x08,0x84,0x81,0x21,0x09,0x8c,0x22,0x43,0x08,0x85,0x37,0xc7,0x5d,0xeb,0x5e,0xb8,0xcb,0xac,0xb4,0xca,0x97,0x37,0xc5,0x08,0x92,0xa5,0x6a,0x91 +,0xc7,0xff,0x88,0x4f,0x49,0xa1,0x43,0x8b,0x31,0xb9,0x7c,0x1e,0x2e,0x5a,0x7a,0xb4,0x3f,0x73,0xb7,0x7f,0x13,0x40,0xff,0x60,0x9b,0xa4,0xff,0x89,0xde,0x33,0xcf,0xcd +,0xcb,0xc9,0x1f,0x03,0xec,0xe4,0x02,0xa3,0x92,0x76,0x81,0x08,0xd6,0xbd,0x50,0xd7,0x3b,0xac,0x3f,0xae,0x14,0x2e,0x50,0x4a,0x7c,0x2f,0x2a,0x36,0x1b,0x5d,0x8f,0x60 +,0xc9,0xf5,0xef,0x5e,0xa3,0xb4,0x5d,0xdf,0x89,0x51,0x42,0x0b,0xd6,0xf4,0x63,0xad,0x76,0x6d,0x0f,0xff,0xc3,0x3c,0x35,0x92,0x4e,0x9d,0x76,0xc6,0x67,0xb4,0x59,0x09 +,0xd7,0x5f,0x69,0x12,0xfd,0xc8,0xd9,0x6f,0x02,0x96,0x89,0x34,0x6b,0xa9,0x61,0x0c,0x99,0xa8,0x36,0xbf,0x9d,0x11,0xb1,0x22,0x52,0xb2,0x65,0x2f,0x3a,0xd0,0x80,0x88 +,0x76,0x80,0xf7,0x41,0x00,0x14,0xac,0x67,0x09,0x85,0x02,0x61,0x40,0xc0,0x50,0x2a,0x14,0x0b,0x05,0x02,0xc3,0x50,0xb0,0x50,0x6a,0x27,0x08,0x84,0xc2,0xa1,0x30,0x88 +,0x54,0x20,0x21,0x08,0x08,0x46,0xf1,0x29,0x75,0x75,0x5a,0xdd,0x6b,0x25,0x54,0x5a,0x97,0x27,0x9f,0xf1,0xff,0x1f,0x1f,0x2e,0xbf,0xfe,0x13,0x20,0x7e,0xed,0xfb,0xbd +,0xb3,0x78,0x49,0xe9,0xaf,0x8a,0x3b,0x3f,0xcd,0x6b,0x3f,0xe3,0xfe,0xfb,0xc1,0x11,0xc1,0xd1,0xfc,0x47,0xd2,0x3f,0xaa,0xb1,0xce,0x34,0x67,0xbe,0x4d,0xa7,0xc1,0x71 +,0xae,0x4b,0x81,0x3b,0x79,0x39,0x45,0xb2,0x9a,0x76,0x58,0x81,0x82,0x1e,0x8b,0xee,0x07,0xa6,0x6b,0x0b,0x9a,0xa8,0xa7,0xe8,0xbe,0xec,0x7f,0xeb,0x97,0x3a,0xed,0x28 +,0xfc,0xa3,0xb0,0xda,0x2c,0x9d,0x38,0x2a,0x27,0x88,0x72,0x38,0x39,0x15,0x03,0xcf,0x6a,0x00,0x06,0x63,0xf7,0xe6,0xfd,0x62,0x5e,0xb8,0x00,0x0f,0x0a,0x77,0xab,0xad +,0xb4,0xe3,0x8d,0x97,0x5b,0xf0,0x95,0x8e,0x2e,0x20,0x1c,0x00,0x24,0x02,0x60,0x13,0x0b,0x0e,0xff,0xf1,0x50,0x80,0x2d,0x7f,0xfc,0x21,0x0a,0xcf,0x3b,0x7e,0xff,0xff +,0xff,0xb0,0x70,0xb1,0x10,0xac,0x17,0x0a,0x05,0x82,0xa1,0x60,0xa0,0x98,0x28,0x42,0x0a,0x04,0x82,0x81,0x20,0xa8,0x44,0x26,0x21,0x09,0x84,0x46,0x62,0x10,0x98,0x44 +,0x4b,0xee,0xfa,0x9b,0x9a,0xcc,0x95,0x5a,0xc9,0x37,0xaa,0xbc,0x96,0xa7,0x5b,0xe3,0x37,0xc6,0x4b,0xd5,0xfa,0xf3,0xff,0xe9,0xf4,0x23,0xed,0x74,0xf7,0x7a,0x7d,0x7f +,0xed,0x7d,0xa7,0xf0,0x4f,0xdf,0x71,0xee,0x41,0xf5,0xae,0x85,0x62,0x5a,0xbb,0xee,0x6b,0xa6,0x37,0x95,0x42,0xe7,0xdc,0xd1,0x29,0x07,0xd2,0xb8,0x5f,0x85,0xde,0x67 +,0xff,0x70,0x7a,0x94,0x8c,0xff,0xac,0x87,0x65,0xc0,0x9e,0x57,0x64,0x70,0x83,0x1e,0x30,0xba,0xae,0x0e,0x6e,0x3f,0xac,0x5a,0xbd,0xe7,0x00,0x27,0x49,0xec,0x92,0x6a +,0x78,0x9e,0xed,0xbd,0x75,0x1c,0x36,0x63,0xf4,0xbe,0x13,0xd4,0x90,0xe0,0xb2,0x92,0xfe,0xfb,0x6c,0x7b,0xbd,0x7f,0x16,0x03,0xd8,0x25,0x48,0x20,0x9f,0xa9,0xd1,0x79 +,0xa3,0x5b,0x83,0xd6,0xf5,0x1a,0x96,0xd9,0x1d,0x00,0x77,0x9d,0xe6,0x36,0x0d,0x7e,0xb8,0x07,0xae,0x04,0x49,0x23,0xc8,0x7a,0xc9,0x89,0x80,0x48,0x0a,0x84,0x0b,0x0a +,0x02,0xc1,0x70,0xb0,0xd0,0x2c,0x63,0x0b,0x0d,0x42,0x82,0x30,0xa0,0x54,0x62,0x35,0x08,0x98,0x06,0x21,0x00,0xb5,0xef,0x17,0x19,0xc6,0xca,0x89,0x4a,0xba,0xb4,0x8d +,0x79,0x75,0xf6,0xf3,0xaf,0xfa,0xff,0xaf,0xfe,0x5c,0x41,0xf3,0x77,0xf3,0xf0,0xcc,0x5e,0x3e,0x3f,0xaf,0x50,0x4f,0x4e,0x83,0xd2,0x3f,0x0e,0xe1,0x6d,0xb4,0x7a,0xc1 +,0xe6,0xd9,0x8c,0xd6,0xf1,0xbe,0xba,0x12,0x73,0xd2,0xba,0x64,0x3f,0xf1,0xf8,0x29,0xd7,0x3a,0x5e,0xf8,0x7c,0x8d,0x52,0xb7,0xa6,0x45,0xe7,0x57,0xc4,0xf9,0x71,0x9f +,0x90,0xfc,0x5f,0xd4,0x5b,0xb2,0xc7,0xf9,0x55,0x7f,0x87,0xe5,0xfb,0xcf,0xd1,0xf1,0x35,0xd4,0xf4,0x7c,0xec,0x42,0x7e,0x07,0x2b,0x0e,0x51,0xcd,0xa1,0xbe,0x00,0xf3 +,0xe0,0x0e,0x45,0xb4,0x41,0x19,0x03,0x9c,0x51,0x80,0x1d,0x39,0x8f,0x48,0x90,0x01,0x4b,0x4d,0x10,0x45,0x70,0x01,0x5b,0x13,0x00,0x04,0x80,0x51,0xc0,0xff,0xf1,0x50 +,0x80,0x2c,0xff,0xfc,0x21,0x2a,0xcf,0xcf,0xfc,0xf7,0xbf,0xfe,0xb2,0x80,0xb8,0x58,0x68,0x25,0x0a,0x09,0x82,0x81,0x61,0x21,0x20,0x28,0x37,0x0a,0x0c,0xc2,0x21,0x20 +,0x89,0xcc,0x22,0x23,0x08,0x8d,0xc7,0x37,0x77,0x9c,0x55,0x52,0xa5,0xe5,0x12,0x49,0x92,0xc4,0x94,0x27,0x5b,0xf6,0xe7,0x7f,0xf9,0xff,0x90,0x86,0xa2,0xfb,0x8f,0x27 +,0x38,0xf4,0x78,0xaf,0x37,0xe5,0xee,0x3c,0x3e,0x80,0xe4,0x18,0x1f,0xfb,0x37,0x7a,0xe3,0x7a,0xed,0x16,0x8a,0x5a,0xbf,0xc7,0xff,0x3f,0x24,0xe8,0xfc,0x8b,0xf0,0x20 +,0xdc,0xd0,0x84,0xea,0x5e,0xb1,0xaf,0xa2,0xf6,0xcd,0x20,0xd6,0xb4,0xe5,0x15,0x1b,0xd0,0xf2,0xc1,0x33,0x3b,0xf0,0x46,0x18,0x7f,0xfd,0xb7,0xd4,0xcc,0x46,0x76,0x7b +,0x28,0x24,0xc4,0xfc,0xe9,0x0e,0xa1,0xea,0xee,0xb8,0x8a,0xeb,0x72,0x35,0x4a,0xe1,0xc4,0x5a,0x29,0xca,0x28,0xdf,0xbd,0xeb,0x2e,0x96,0x5e,0x8d,0xb2,0x2d,0x4f,0x8a +,0x25,0xa2,0x51,0xea,0x99,0x39,0xd0,0x8c,0x03,0x16,0x1a,0x05,0xbb,0xe4,0x65,0x21,0x0e,0x64,0x17,0x01,0xf6,0xa1,0x2a,0xca,0xa0,0xb0,0x04,0xc0,0xa7,0x51,0x30,0xdc +,0x2c,0x24,0x0b,0x09,0x04,0xc3,0x41,0x30,0x90,0x8a,0x14,0x11,0x84,0x46,0x61,0x11,0x98,0x44,0xee,0x72,0xbe,0xbe,0x5f,0x13,0x79,0x57,0xbb,0xde,0xa8,0x59,0x77,0x5a +,0xef,0xf1,0x37,0x7d,0x6b,0xed,0xfe,0xfc,0x7f,0x6d,0x3f,0x10,0x3e,0xbf,0x7b,0x4c,0x9e,0x84,0xc3,0xf5,0xdf,0xc2,0xff,0x1e,0xce,0x7f,0x98,0x1e,0x3b,0x2f,0x6a,0x78 +,0xbf,0xdd,0xfe,0xd0,0x77,0x55,0x30,0xbb,0x88,0x5f,0xef,0xc1,0x47,0x49,0x79,0x3d,0xdf,0xc9,0x7c,0xf7,0xc2,0x8e,0x06,0xaf,0x58,0x51,0xee,0x2f,0xf5,0x7e,0x88,0x77 +,0x83,0xf5,0x96,0x19,0xf6,0xf0,0xbc,0x61,0xaf,0x04,0x31,0x5b,0xdf,0x13,0xa7,0x09,0x71,0xe6,0x57,0xe5,0xa8,0xac,0xb3,0xe5,0xe1,0x55,0xc7,0x1c,0x74,0x79,0xeb,0x9f +,0xbc,0xc6,0xbf,0xf4,0xae,0x20,0x52,0x1a,0x00,0x53,0x98,0x1f,0xcb,0x03,0x6c,0x02,0x90,0x33,0xe8,0x00,0x1d,0xc8,0xc1,0x10,0x00,0x28,0xd1,0x4b,0x00,0x1b,0x65,0x10 +,0x0a,0x80,0xa0,0x1c,0xff,0xf1,0x50,0x80,0x2f,0xbf,0xfc,0x21,0x4c,0xfe,0xfd,0xfd,0x4c,0x36,0x88,0x85,0xb4,0x89,0x0b,0x68,0x79,0x72,0x10,0x22,0x74,0x5f,0x66,0x67 +,0x0c,0x5d,0x94,0x4a,0x79,0xbb,0x5e,0x74,0x01,0x15,0x48,0xc8,0xa6,0x74,0x0b,0x9d,0x1a,0xe1,0xdc,0xb1,0x52,0x7d,0x91,0xd3,0x9f,0x0b,0xed,0x9c,0x98,0xb1,0x74,0x36 +,0x17,0xa3,0xeb,0xb8,0x9d,0x33,0x29,0x66,0x9b,0x12,0xf2,0x53,0x26,0x02,0x29,0xd8,0x92,0x9d,0xa5,0xd5,0x59,0x1e,0xaa,0x74,0xca,0x85,0xf5,0x29,0xea,0x2e,0xa7,0x1f +,0x5a,0x22,0x21,0x08,0x58,0xf7,0x85,0x51,0x94,0x09,0xc5,0x21,0x00,0x24,0xa6,0x22,0xe2,0x0a,0x06,0x42,0x2a,0x25,0xde,0xca,0x50,0x6f,0x84,0xaf,0x31,0x1a,0x09,0x08 +,0xd6,0x6b,0x00,0x1b,0x6e,0x68,0x05,0x4f,0x0e,0x88,0xae,0xb5,0xf7,0xca,0x08,0xae,0x2e,0x97,0xb9,0xf5,0x8c,0xaf,0xe5,0x05,0x7a,0x61,0xae,0xb3,0x51,0xdb,0x59,0xf2 +,0x19,0xae,0xc7,0x28,0x2c,0xbf,0x95,0xe8,0xda,0xa7,0x0c,0xff,0xdd,0x2b,0x44,0x25,0x15,0x33,0x17,0x5b,0x34,0x65,0xa2,0x73,0xf2,0x60,0x9c,0x09,0x84,0x0b,0xe1,0x2f +,0x72,0x33,0x30,0xdc,0x9e,0x62,0x8a,0x1b,0x34,0x62,0x8c,0x95,0x12,0xe5,0xe9,0x62,0x86,0xdf,0xb2,0x94,0xce,0xd1,0x2c,0x37,0x69,0xd0,0xb2,0x58,0x8a,0x6d,0x89,0x47 +,0x3d,0xe9,0xd4,0x99,0x9b,0x3e,0xaa,0xfd,0x4c,0xbd,0x54,0x12,0xa4,0xce,0x4e,0x47,0x1c,0xfb,0x79,0x37,0xcd,0x2e,0x9c,0xdc,0x19,0xb6,0x69,0x93,0xb7,0x70,0x6a,0xaf +,0x5f,0xe8,0xb3,0xf2,0xfd,0xa8,0x1a,0x73,0xc6,0x8f,0x2a,0x72,0xcd,0x16,0xfc,0x3b,0xec,0xdd,0xb2,0xe8,0x10,0xf1,0xee,0x5d,0x34,0xcf,0x83,0xe1,0xe9,0x19,0x80,0xf5 +,0xaf,0x9f,0xbd,0x86,0xbf,0x34,0xee,0x1b,0xd1,0xab,0x6d,0xe2,0x40,0x73,0xd0,0xb6,0x15,0xe9,0x3a,0xbf,0x96,0x81,0x7d,0xa7,0x52,0x73,0x84,0x9e,0xbc,0x7d,0xd9,0xa7 +,0x03,0x33,0x7b,0xed,0xce,0x0b,0x8f,0x72,0x87,0x49,0x6e,0xf4,0xe2,0x49,0x66,0x16,0xd1,0xb5,0xe4,0x81,0x58,0x8d,0x8f,0xb3,0x1d,0x7a,0xe5,0x6c,0x3b,0x1c,0x6d,0xc4 +,0xad,0x56,0xee,0xae,0x55,0x36,0xa5,0xc5,0x5c,0xeb,0x67,0xb8,0x1c,0x8c,0x05,0x0d,0x06,0x63,0xc4,0x9f,0xc2,0x42,0x41,0x03,0x8c,0x71,0x8e,0xec,0x4f,0xde,0x1c,0x43 +,0x80,0xff,0xf1,0x50,0x80,0x2d,0xff,0xfc,0x21,0x6a,0xcf,0xde,0xf7,0x7f,0xdf,0xfe,0xaf,0x40,0xb0,0x90,0x4c,0x24,0x13,0x05,0x04,0xc1,0x40,0xa8,0x60,0x28,0x43,0x0a +,0x08,0x82,0x82,0x20,0x98,0x54,0x22,0x23,0x08,0x9c,0xc4,0x22,0x77,0xac,0x95,0xaa,0x9d,0xf5,0xd7,0x88,0xdf,0x15,0x79,0xc6,0x11,0x10,0xe3,0x99,0xb5,0xd6,0xbd,0xb3 +,0x5a,0x1a,0x87,0xaa,0x7f,0x4b,0x7f,0x5c,0xff,0x9b,0xe1,0x40,0xf7,0x7c,0xab,0xee,0x34,0xfe,0x7f,0xf1,0xed,0x3b,0xef,0x1b,0xd3,0x75,0x89,0xe2,0xeb,0xae,0x2f,0x08 +,0xd3,0x45,0x78,0xf3,0x7c,0x57,0xfa,0xc7,0x0b,0x87,0xd0,0x73,0xe9,0x7f,0xeb,0xfc,0x5f,0x7d,0x4f,0xed,0x0d,0xcc,0x9e,0xa5,0xbf,0x66,0xba,0xcf,0xa3,0xe7,0xee,0x5f +,0x8f,0x6f,0x1a,0x37,0x11,0xe0,0x0d,0x3d,0x65,0x9d,0x5c,0x47,0x00,0xc8,0xe7,0x09,0xb7,0xda,0x7e,0x02,0xbb,0x34,0xe9,0x65,0x89,0x26,0xf2,0x39,0x62,0xc6,0x49,0x8e +,0x1e,0x40,0x7e,0xc8,0xfa,0xd8,0x2c,0x06,0x17,0x6a,0x55,0x75,0xed,0x58,0x2a,0x9c,0xd7,0xbf,0x74,0x6a,0x51,0xae,0xc2,0xb4,0xe5,0x2b,0xe1,0xbf,0x02,0xfc,0xde,0x19 +,0x40,0x3d,0xd0,0x07,0xd7,0x00,0x98,0x17,0x02,0xa1,0x08,0xc3,0x41,0x30,0x60,0x2a,0x14,0x13,0x09,0x42,0x87,0x51,0x18,0x84,0x2a,0x11,0x09,0x90,0x42,0x62,0x12,0xba +,0xfc,0xd7,0xb7,0xe7,0x8e,0x24,0xf5,0xd5,0xe5,0xf8,0xd2,0xaa,0xd2,0x55,0xcf,0x2f,0x57,0x65,0xf1,0x89,0xa9,0xbf,0x61,0xc9,0xf8,0x2f,0xf2,0x7e,0x31,0xbd,0x5f,0xd6 +,0x89,0x36,0xfd,0x2b,0xb0,0xe7,0xd7,0xa6,0x69,0x28,0x22,0xdf,0x66,0x8e,0xe3,0xfd,0x6e,0xe1,0x45,0x6b,0xe1,0xf0,0xe3,0x78,0x73,0x63,0x97,0x09,0x4f,0xcd,0xd4,0x1d +,0xc8,0xef,0xbd,0x7d,0xc8,0x74,0x9f,0x94,0x44,0x68,0xf7,0x86,0xc7,0x2e,0xf4,0xe5,0xf6,0xcf,0x8a,0xbf,0x75,0x67,0x1f,0x16,0xcb,0xc4,0xcb,0x98,0x57,0x64,0x4f,0x17 +,0xb6,0x1e,0xaa,0xb5,0x35,0x7b,0x88,0x8c,0xb8,0x04,0x43,0x5f,0x4f,0x20,0x51,0x51,0xbe,0x9a,0x42,0x28,0x3c,0x58,0x84,0x57,0xb9,0xdd,0x55,0x3b,0xbc,0x42,0xe3,0xbf +,0x70,0x40,0x07,0xb8,0x03,0xba,0x1c,0x80,0xa0,0x12,0x35,0x00,0x54,0x5d,0x00,0x38,0xff,0xf1,0x50,0x80,0x2d,0x3f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0x9f,0xff,0xbf,0xae +,0x81,0x30,0xdc,0x2c,0x24,0x0c,0x06,0x42,0xa1,0x80,0xa8,0x50,0x8a,0x24,0x12,0x85,0x02,0x41,0x30,0x90,0x45,0x26,0x11,0x33,0xb9,0xad,0xd3,0xef,0xeb,0x7a,0x9c,0xdd +,0xd6,0xa9,0xae,0xe4,0x48,0x44,0x94,0xcb,0xf3,0xdc,0x93,0xcf,0x01,0x5a,0x7c,0xd5,0xa7,0x0a,0xfc,0x3e,0x91,0xde,0x1b,0x9f,0x2a,0xf6,0x95,0xeb,0xbe,0x92,0x2e,0xbe +,0x47,0x24,0xbb,0x72,0x83,0xe2,0xe5,0xcb,0x9e,0xf5,0xbf,0xb0,0xbf,0xe4,0x5b,0xbb,0x71,0xba,0xbe,0x6b,0x8b,0xd6,0x60,0xdf,0xa0,0x86,0xaf,0x3e,0x00,0x57,0x51,0x31 +,0x4d,0xe1,0x2e,0xe8,0x30,0x98,0xd7,0xbd,0xeb,0xb8,0xd1,0x0f,0x4f,0x74,0x93,0x69,0xc0,0x62,0x3f,0x64,0xbf,0x85,0x53,0xd4,0x8d,0xe7,0x8e,0x44,0xe3,0x16,0xd8,0xc0 +,0xce,0xe3,0xcb,0xd4,0x19,0x8a,0x4a,0x4c,0x0a,0xa9,0x6b,0x08,0x6c,0xd4,0x55,0x34,0x0d,0xbe,0x4a,0x62,0x82,0x74,0x1e,0xb8,0x0c,0x43,0x10,0xa4,0x46,0x52,0x64,0xce +,0xcb,0x00,0x2e,0x17,0x02,0xa0,0xc2,0xe1,0x62,0x38,0x58,0x2a,0x16,0x0b,0x89,0x82,0x82,0x70,0xb0,0x50,0x4e,0x14,0x12,0x85,0x06,0xa1,0x30,0x88,0x4c,0x42,0x33,0x18 +,0x84,0xc2,0x24,0x6e,0xb5,0x8a,0xe9,0xba,0x55,0xd6,0x5d,0x69,0x92,0x4a,0xbd,0x4e,0x37,0x99,0xf0,0xed,0xbb,0xeb,0x85,0x70,0x3f,0xc5,0xd8,0x07,0xbf,0x5d,0x73,0xfa +,0x3e,0x0e,0xf1,0xf5,0x5f,0xed,0x4f,0xa3,0xe5,0x4d,0x2f,0x7d,0x77,0xfa,0xa7,0xdc,0x1f,0xfd,0x72,0xf1,0xfe,0xb9,0xdd,0x76,0x98,0x8e,0xfa,0x38,0x7f,0x5f,0xfd,0xd7 +,0x22,0xe5,0x77,0xb9,0xbd,0x74,0xfb,0x51,0x59,0x7d,0x6b,0x9f,0x77,0xc2,0xbb,0x72,0x5b,0x43,0xb3,0x94,0x49,0xc7,0x45,0xd6,0x0e,0xf2,0xea,0x7d,0x80,0x8a,0x54,0x09 +,0xbf,0x5f,0x5b,0xf3,0x38,0x6a,0x00,0x72,0xf3,0x81,0xf9,0x3f,0xea,0x46,0x69,0xde,0xc0,0xaf,0xf2,0x0b,0x98,0x7d,0xc4,0xce,0xe9,0xf9,0x93,0x94,0x91,0x0a,0x05,0x17 +,0x82,0xbf,0xb6,0x01,0xee,0xde,0xa4,0xa3,0x2d,0xb1,0xa5,0xf0,0x2c,0x9d,0x67,0x61,0xee,0x00,0x11,0x17,0x00,0x09,0xa9,0xd0,0x07,0xff,0xf1,0x50,0x80,0x2f,0x7f,0xfc +,0x21,0x0a,0xcf,0xff,0xff,0x3f,0xff,0xfc,0xae,0x80,0xb1,0x1c,0x2a,0x14,0x0a,0x85,0x82,0xe1,0x60,0xb8,0x58,0x28,0x16,0x0a,0x19,0x42,0x83,0x20,0x88,0xcc,0x24,0x11 +,0x21,0x84,0x46,0x61,0x11,0x3b,0x9a,0xe6,0x5f,0xe3,0xf3,0x9a,0xac,0xbd,0x14,0xc5,0xdd,0x49,0x50,0xd6,0xe5,0x4a,0xf6,0xed,0x7a,0xf3,0xc0,0x16,0x9f,0xe5,0x48,0xf9 +,0x75,0xcf,0xf4,0x5e,0xf4,0xfb,0xfe,0xaf,0xe2,0x7f,0x27,0xb1,0x65,0x53,0x45,0x9b,0xd1,0xf6,0xb9,0xbb,0x6f,0x90,0x8d,0xf5,0x03,0xc5,0x65,0xf0,0x36,0x9d,0x83,0x8d +,0xe3,0xf6,0x7a,0xe4,0xcc,0xf4,0xbf,0x91,0xff,0x6a,0x23,0xa9,0x00,0xf9,0x15,0x66,0x33,0xec,0x85,0xd3,0x55,0xb6,0x54,0xa2,0x26,0x2f,0xb8,0x49,0x2d,0xe3,0x8f,0x9c +,0xde,0xf0,0xb6,0x72,0x55,0x0f,0x9f,0xff,0x77,0xb3,0x34,0x4d,0x95,0xf3,0xdf,0xd7,0xd5,0x64,0x17,0x9c,0x45,0xbc,0x64,0x91,0xea,0x07,0x81,0x31,0x3c,0x16,0x95,0x43 +,0x2f,0x34,0x46,0x56,0xef,0x7c,0xab,0x18,0x4b,0x54,0x52,0xa7,0x74,0x97,0xae,0x08,0xce,0xf3,0xb9,0xb0,0x62,0xaa,0x60,0x75,0xee,0xcd,0x30,0x26,0x04,0x80,0xa8,0x40 +,0xb0,0x90,0x2c,0x18,0x0b,0x09,0x42,0x81,0x70,0xa0,0x98,0x28,0x16,0x0a,0x05,0x82,0x85,0x50,0xa0,0x54,0x26,0x11,0x09,0x84,0x42,0x61,0x10,0x98,0x44,0x46,0x11,0x0a +,0x84,0x4a,0xab,0xee,0xa4,0xea,0x78,0x93,0x9d,0x5e,0x51,0x2a,0x25,0xce,0x3d,0xbb,0x9b,0xbc,0xe7,0xca,0xef,0x55,0xd5,0x70,0x37,0xdd,0x8a,0x3c,0x3e,0x5b,0xa2,0xde +,0x81,0x93,0xd3,0xf4,0x7f,0x06,0xf5,0xf7,0x35,0x8d,0xe7,0x56,0xfd,0xd3,0x98,0xf6,0xbd,0x49,0xfe,0xce,0x9a,0xb8,0x4d,0x5f,0xd7,0x74,0x5d,0x50,0xbe,0x4e,0x8d,0xa0 +,0xbe,0xdf,0xfe,0x4e,0xc1,0x3f,0xe9,0xfa,0x2e,0xbd,0xf2,0x79,0xe6,0xe7,0xfe,0x1f,0x13,0xad,0xdf,0xb6,0xbf,0x03,0x8c,0xba,0xe3,0xb5,0xcd,0x5f,0x74,0xeb,0xcb,0xdb +,0x42,0x78,0x87,0x73,0x9b,0x88,0x77,0xbf,0xff,0x0c,0xeb,0x62,0x08,0x77,0x0a,0xd2,0x78,0xa2,0x22,0xf5,0xfb,0xd1,0x02,0x2b,0x59,0x52,0xe1,0xf9,0x44,0xd3,0x87,0xb6 +,0xe2,0xc4,0x91,0x3c,0x0b,0x84,0x4a,0x03,0xcc,0x00,0x00,0x1b,0x6a,0x09,0x2e,0x02,0x40,0x11,0x03,0x80,0xff,0xf1,0x50,0x80,0x2e,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xf7 +,0xff,0xff,0xfc,0xae,0x63,0xa0,0x54,0x2c,0x18,0x0b,0x0d,0x43,0x01,0x40,0xb0,0x50,0x2c,0x12,0x0a,0x8d,0x02,0xa1,0x21,0x88,0x4c,0x22,0x93,0x08,0x89,0xde,0xaa,0xb4 +,0xbf,0x3c,0xf2,0xcf,0x39,0xbd,0x29,0x21,0x25,0x48,0xbc,0xab,0xdd,0xdc,0x3c,0xf9,0xe8,0x27,0xab,0x67,0x4c,0xb9,0xeb,0xe5,0xc7,0xf5,0xf3,0x38,0xe1,0xe5,0x3a,0xcb +,0xcb,0xcf,0x50,0x15,0x53,0x97,0xc2,0x07,0xf6,0x97,0x8b,0x71,0x2f,0x7c,0xab,0xc7,0x78,0x46,0x2f,0xad,0x57,0x50,0xa3,0x2f,0x9d,0xbb,0xd8,0x0b,0x20,0xed,0x2a,0xfb +,0x73,0xf5,0x1d,0x8a,0x9d,0x4f,0xbe,0xb9,0x5c,0xc9,0xc1,0x9c,0xa9,0x7d,0x03,0x2d,0xdc,0xb1,0x99,0x2c,0xaa,0xe1,0x31,0xc9,0xac,0x71,0xc4,0x2b,0x09,0x0b,0xcc,0x80 +,0x8f,0x88,0x4a,0x89,0x58,0x67,0xa0,0xb9,0xf4,0xa9,0xc5,0x2b,0x94,0x47,0x6a,0x97,0x8d,0x60,0x5d,0xaa,0x81,0xb2,0x9a,0x6e,0x2f,0x65,0x60,0xf3,0x42,0xd3,0xb2,0xb3 +,0x42,0xd5,0x49,0x48,0xda,0x01,0x25,0x44,0x93,0x51,0x43,0x2d,0xde,0xe8,0x01,0x01,0x10,0x29,0xd0,0x4c,0x38,0x0b,0x05,0x02,0x41,0x60,0xb8,0x58,0x28,0x36,0x0a,0x05 +,0x84,0x81,0x60,0xa0,0x54,0x28,0x12,0x0a,0x05,0x44,0x21,0x51,0x18,0x54,0x22,0x25,0x08,0x9d,0xcd,0x57,0x1c,0xbe,0x2f,0xb7,0x32,0xeb,0x38,0xdd,0xef,0x45,0x4d,0x38 +,0xfa,0xf7,0xe3,0x7a,0x6b,0x35,0x5e,0x7f,0xaf,0xeb,0xdf,0x43,0xab,0xfc,0xb1,0xf9,0x3d,0xf6,0xe8,0xf6,0x66,0x99,0xbc,0xdd,0xaf,0xd2,0xfd,0x5e,0xdd,0xef,0x68,0x82 +,0xef,0xf8,0x5f,0xf8,0x3f,0x3f,0x7f,0x7a,0xe8,0x8d,0xd3,0x45,0xda,0x43,0xb7,0x8d,0x23,0x31,0xc9,0xc9,0xd2,0xea,0x9f,0xf7,0x7a,0x2b,0x9a,0xac,0xfc,0xdd,0x03,0xa2 +,0xec,0xbd,0x87,0xb3,0x8f,0x99,0xcf,0xb3,0x2d,0x27,0xdb,0x7f,0x79,0x35,0xe8,0x3e,0x45,0xe3,0x4f,0x63,0xd6,0x2d,0x5f,0x97,0x71,0xc8,0x56,0xb5,0x0e,0x61,0xe4,0x01 +,0x19,0x4c,0x12,0xf3,0xe4,0x07,0x13,0x98,0x00,0x78,0x03,0xba,0xf5,0x80,0x3c,0xc0,0x00,0x62,0x03,0x48,0x3c,0x40,0x00,0x88,0x02,0xb1,0x0b,0x00,0xc0,0x92,0x4b,0xc4 +,0x26,0x0a,0xa8,0x33,0x80,0xe0,0xff,0xf1,0x50,0x80,0x2a,0x5f,0xfc,0x21,0x0a,0xcf,0xef,0xf3,0xbf,0xff,0xff,0xae,0x71,0x30,0x90,0x2e,0x13,0x0b,0x15,0x44,0x81,0x70 +,0xa0,0x58,0x48,0x12,0x12,0x04,0xc2,0x44,0x14,0x18,0x44,0xcf,0x12,0x6b,0xbe,0x35,0x4d,0xc8,0xf3,0xf3,0xa5,0x71,0x4a,0xba,0xba,0x92,0x55,0x4d,0x64,0xf6,0xf5,0x1c +,0x7c,0x70,0x1f,0x07,0xbb,0x96,0xf2,0x1e,0xef,0x89,0x7b,0x37,0xe6,0xdf,0x6f,0x11,0xb7,0xbf,0xfe,0x2a,0x1a,0x11,0xe9,0x6b,0xeb,0x8f,0x56,0x69,0xd0,0x2e,0xfa,0x73 +,0x69,0xdf,0xfb,0xba,0x70,0x10,0x14,0xa7,0x50,0x29,0x0d,0x0e,0x69,0x9c,0xff,0x0e,0x72,0xdb,0xba,0x80,0x3f,0x05,0xcb,0x3e,0x3b,0x49,0x74,0x6f,0x5a,0x60,0x5c,0xcd +,0x86,0x9a,0x4c,0x86,0xc1,0x86,0x4f,0x5b,0xd4,0xd6,0xae,0xb0,0x31,0xea,0x89,0xb5,0x03,0x1a,0x72,0xe5,0x7a,0x17,0x36,0x64,0x9a,0xc4,0x10,0x2b,0x79,0x49,0x01,0x48 +,0x40,0xad,0x85,0x4a,0x5a,0x91,0x54,0x3d,0x70,0xa0,0x2d,0x7d,0xab,0x02,0x25,0x0b,0x89,0xa8,0x02,0x21,0x40,0x2a,0x14,0x2c,0x24,0x0b,0x0d,0x44,0x81,0x50,0xb1,0x20 +,0x28,0x26,0x0a,0x0d,0x42,0x82,0x31,0x88,0x4c,0x6a,0x13,0x08,0xa5,0x5b,0xdf,0x9e,0xf3,0xf1,0xbc,0x9b,0x89,0xbe,0x39,0x85,0xc4,0xd3,0xcf,0x5e,0xa9,0xd6,0xfb,0xd7 +,0xb4,0xbd,0xeb,0x3a,0x0f,0x8f,0x39,0xaa,0xf5,0xff,0xc7,0xab,0xf5,0xf1,0x49,0xbe,0xef,0x77,0xc5,0xe0,0xf1,0xe4,0xe5,0x52,0xae,0xd2,0xd7,0xc8,0xf5,0x54,0x25,0xae +,0x7a,0x8e,0x1c,0xd2,0xcb,0xe8,0xdf,0x70,0xf9,0x06,0x94,0xf9,0x0e,0xb7,0xae,0x51,0xbf,0x41,0xfc,0x4c,0xe7,0xc7,0x7d,0xa7,0x2c,0xa7,0xb4,0x75,0x75,0xc5,0x12,0xf9 +,0x81,0x9d,0x17,0x11,0xed,0x97,0x47,0x60,0x8f,0xd9,0xfc,0x69,0xce,0x7b,0x71,0x0f,0xed,0xbf,0x0e,0x6f,0x76,0xa2,0x33,0x5a,0x41,0x60,0xef,0x14,0x77,0x8a,0x05,0x95 +,0xee,0x1e,0x00,0x00,0x0f,0xb6,0xee,0x4c,0x49,0x1d,0x21,0x23,0x78,0xa8,0x02,0x40,0x02,0xe4,0xc0,0x0b,0x94,0x01,0x60,0x1c,0xff,0xf1,0x50,0x80,0x2b,0xdf,0xfc,0x21 +,0x0a,0xcf,0x57,0x76,0xbf,0xff,0xff,0xb2,0x60,0xa0,0x58,0x28,0x16,0x0b,0x85,0x04,0xe1,0x60,0xc0,0x58,0x2a,0x14,0x0b,0x0d,0x02,0xc1,0x21,0xa8,0x50,0x46,0x12,0x08 +,0x88,0xc2,0x24,0x30,0x8a,0x14,0xd4,0xef,0x5f,0xbf,0xed,0xac,0xad,0x3c,0xfc,0xdc,0xde,0xae,0xad,0x2f,0x76,0xf8,0xf0,0xab,0x92,0x84,0xfd,0x7d,0x82,0x75,0x7e,0xa4 +,0x9f,0x0f,0xa0,0xfb,0x7d,0x1e,0xa9,0xfe,0xbd,0x0f,0xdb,0x2d,0xf6,0x69,0xc8,0x00,0x94,0x3d,0xde,0xd6,0x3c,0xe3,0x46,0xd0,0xbc,0x23,0xf8,0xf7,0xf5,0x02,0xaa,0xed +,0x0d,0x72,0x89,0x8e,0x40,0x7d,0xa7,0x7d,0xdf,0x4c,0x3c,0x68,0xc7,0xeb,0xc7,0x23,0x1c,0xdd,0x6c,0x92,0xbe,0x64,0x7a,0x05,0x65,0x74,0x1a,0xaf,0xe3,0x5a,0xf6,0x68 +,0xf7,0x26,0xc7,0x81,0xb6,0xf2,0xf8,0xb2,0x10,0xfb,0x4d,0x19,0x92,0x0b,0xfb,0xae,0x73,0x6d,0x2e,0xd3,0x05,0xe9,0x72,0x74,0x72,0x20,0x24,0xa2,0x21,0xfd,0x58,0xa9 +,0x32,0xc1,0xee,0x09,0x20,0x24,0x05,0x13,0x14,0x5c,0xea,0x00,0x04,0x2f,0x60,0x28,0x48,0x2c,0x54,0x0b,0x05,0x42,0xc3,0x41,0xb0,0x50,0x2c,0x34,0x22,0x84,0xc2,0xa2 +,0x32,0x08,0x8c,0x22,0x87,0xaf,0x19,0xf1,0xea,0xf5,0x3c,0xfd,0xaa,0xee,0xfb,0xd6,0x54,0x71,0x4b,0xb7,0x19,0x5a,0xad,0xba,0xdc,0xae,0x8e,0xac,0x7a,0x9f,0xbb,0x64 +,0xbf,0x3e,0x19,0xfb,0xfe,0xe3,0xff,0x46,0xa4,0xf6,0xb8,0xf2,0xf5,0x20,0xd9,0xd7,0x5b,0x65,0xce,0xb4,0x36,0xcb,0xfd,0x8f,0xff,0xfc,0xa6,0xb2,0x93,0x8d,0x3f,0xf4 +,0x0d,0x63,0x76,0xa0,0x1e,0x87,0x80,0x55,0xda,0x72,0xae,0xa6,0xfc,0x6f,0xd8,0x69,0xf1,0xd7,0x9b,0xcf,0xe5,0xfe,0x1a,0xd4,0xd2,0x1e,0xea,0xb7,0x80,0x8b,0x44,0x47 +,0x17,0x0e,0x25,0xad,0xef,0x28,0x00,0xfb,0x78,0x01,0xe4,0x01,0xef,0x26,0x7b,0xa7,0x7a,0x5d,0xc0,0xa9,0xe8,0x99,0xcf,0x75,0xed,0xc2,0x85,0x29,0x2a,0x10,0x14,0x56 +,0x90,0x0f,0xb3,0x81,0x37,0x7b,0x05,0x91,0x01,0x74,0x53,0x98,0x09,0x40,0xb2,0xd0,0xac,0xc2,0x40,0x13,0x03,0x80,0xff,0xf1,0x50,0x80,0x2c,0xdf,0xfc,0x21,0x0a,0xcf +,0xbe,0x68,0xfe,0xff,0xfc,0xab,0x30,0xc0,0x58,0x6e,0x14,0x0a,0x85,0x82,0xa1,0x61,0xa8,0x50,0x2c,0x15,0x0a,0x05,0x82,0x83,0x50,0xa0,0x48,0x62,0x53,0x10,0x94,0xc2 +,0x23,0x7c,0xb5,0x7c,0xf5,0x2b,0x5e,0x33,0x5c,0x3b,0xd6,0x67,0x52,0x45,0x5e,0x4b,0xbd,0x77,0xf1,0x9d,0xcd,0x55,0xf5,0xeb,0xeb,0xd8,0x7f,0x8b,0x4c,0x09,0xfd,0xbb +,0x8f,0x57,0x9f,0xda,0x8e,0x58,0xf2,0xd0,0xdd,0x6e,0x8e,0xab,0x92,0x5f,0xb0,0xab,0xdb,0x47,0xf5,0x1b,0xea,0xb5,0x68,0x32,0x63,0xe8,0x7c,0x29,0x2e,0xd3,0xee,0x8a +,0x38,0x85,0x92,0x56,0xd3,0xa9,0xf7,0x8c,0xbf,0xd7,0xd7,0x5d,0xbc,0xa9,0xe7,0x4a,0x08,0x7f,0x5a,0x2c,0x14,0x8c,0x97,0xa1,0x8b,0x26,0x13,0x81,0xdc,0x31,0xcb,0x5e +,0x49,0xe5,0x7b,0xfb,0x27,0x7f,0x7d,0x07,0x3e,0x91,0x58,0x8b,0x58,0x44,0x73,0x4e,0xe8,0x8a,0xbd,0xd0,0x28,0xf7,0x41,0x65,0x61,0x10,0x44,0xec,0x10,0x8d,0xa2,0x20 +,0x56,0x53,0x16,0x00,0xee,0x41,0x70,0x0b,0x82,0x80,0x54,0xa0,0x98,0xc8,0x26,0x1a,0x85,0x02,0xc1,0x40,0xb0,0xd4,0x2c,0x14,0x0b,0x05,0x02,0xa1,0x40,0x99,0x08,0x26 +,0x31,0x42,0x60,0xcf,0x6f,0x17,0x87,0x59,0x97,0xb9,0x6a,0x8b,0xd7,0x7e,0xd5,0x5c,0x77,0xc6,0xbb,0xad,0x55,0xfd,0x7c,0xff,0xbf,0xb0,0xe3,0x7f,0xcb,0x71,0x9f,0x6b +,0xf2,0xbf,0xb2,0x17,0xd5,0xe9,0x6f,0xe3,0xfc,0xa7,0x5c,0x9a,0x63,0x4a,0x5d,0xfb,0xdf,0x9e,0xba,0x7f,0x3d,0xb9,0x73,0xe4,0xb5,0x7c,0x03,0x4f,0xbd,0xff,0x62,0xc8 +,0x1e,0x59,0x64,0x67,0xf0,0xcd,0xa2,0xf4,0x6e,0x06,0x9e,0xef,0x19,0xfb,0xce,0xf2,0x1b,0xb7,0xa9,0x02,0x4d,0xcb,0xb1,0x4c,0xe4,0xe7,0x05,0xac,0x5a,0x29,0xfb,0x94 +,0x67,0x2d,0x0e,0x32,0xdb,0x95,0x0a,0xf1,0x16,0xb7,0x7f,0x81,0x2e,0xf7,0x7c,0x76,0x87,0x79,0x17,0x17,0x53,0x27,0x84,0x1f,0x68,0x1d,0xd6,0x45,0x2d,0x46,0x0c,0x70 +,0x55,0xee,0x01,0xee,0xaa,0x09,0x4b,0xbd,0xc7,0x08,0xec,0x10,0x08,0x23,0x88,0xa4,0xaa,0x15,0x54,0x8d,0x84,0x80,0xb6,0x00,0x10,0x05,0x80,0x70,0xff,0xf1,0x50,0x80 +,0x2c,0x9f,0xfc,0x21,0x2a,0xcf,0xcf,0xae,0xff,0xfb,0xfd,0xaf,0x81,0x30,0x50,0x2c,0x24,0x0b,0x09,0x04,0xc1,0x70,0xa0,0x58,0x28,0x26,0x12,0x14,0x82,0x61,0x40,0x90 +,0x85,0xcd,0xea,0xaf,0x35,0x33,0xcf,0x69,0x4a,0x93,0x9d,0x5e,0xf5,0x32,0xea,0xe3,0x27,0x18,0x48,0xba,0xfb,0xfc,0x07,0xff,0x5d,0x7d,0xef,0x57,0x1f,0xd1,0x51,0xb7 +,0xba,0x3f,0xde,0x3e,0xff,0x49,0xeb,0x2e,0xeb,0xfb,0x17,0xee,0x32,0xa9,0x78,0x9f,0x6e,0xfa,0xd6,0xf0,0xac,0xb4,0xd7,0x68,0xc6,0xa1,0xd0,0xa2,0x6f,0x49,0xd1,0xca +,0x61,0xd7,0x5f,0xf0,0x9f,0x70,0x41,0xa5,0xe6,0xfe,0x4f,0xc1,0x06,0x9f,0x14,0x5d,0x6c,0xae,0x5d,0xff,0x4f,0xb7,0xee,0xeb,0x7a,0x13,0x27,0xa7,0xe5,0xef,0xed,0xe9 +,0xd9,0x17,0xb4,0xb3,0x7b,0xf7,0x93,0x14,0xc1,0xab,0x88,0x0b,0x31,0x9c,0xef,0x6d,0xd7,0x6c,0x91,0xfa,0xd3,0x31,0x17,0x49,0x25,0xc6,0x0f,0x95,0x01,0x65,0x0b,0xf1 +,0x36,0x98,0x94,0x0d,0xaf,0x92,0x63,0x79,0x41,0xdc,0x6d,0x10,0x5e,0xe7,0xc8,0xbd,0xd6,0x41,0x9c,0x09,0x81,0x00,0x15,0x4c,0x14,0x0b,0x05,0x05,0x01,0x60,0xa1,0x18 +,0x28,0x15,0x0a,0x04,0x82,0xc2,0x40,0xb0,0x50,0x2c,0x15,0x11,0x84,0x42,0xe1,0x30,0x88,0x4c,0x42,0x12,0x09,0x88,0x50,0x5f,0x35,0xcc,0xf6,0x95,0x5b,0xd4,0xdf,0x1b +,0xcb,0xa8,0xb6,0xba,0xe7,0x59,0x38,0xaf,0x7f,0x8d,0x5b,0x5e,0xbc,0xf3,0xe6,0xc6,0xa1,0xe7,0x5b,0xcb,0x53,0x7e,0xe7,0x5e,0x9c,0xfe,0x6d,0x7f,0xcb,0x78,0xd2,0x6f +,0xeb,0xb2,0xf1,0x4d,0xbf,0xd4,0x3e,0x0c,0xef,0xe6,0xdf,0xb9,0x07,0xe5,0xa2,0x1e,0x76,0x4f,0xa4,0x8e,0x4a,0xff,0x11,0xd8,0x53,0xd9,0x32,0x48,0x29,0xcd,0x28,0x70 +,0xf4,0x55,0xc9,0x58,0x84,0x63,0x85,0xeb,0x98,0x70,0x66,0x9c,0xa0,0xfa,0xdf,0xf1,0xc8,0xf9,0x0c,0xf1,0x00,0x79,0x39,0xcb,0x4f,0xb8,0xc9,0x0e,0x9d,0x9c,0x87,0x83 +,0x6a,0xae,0x1b,0x03,0xdd,0x12,0x7d,0xc0,0x4c,0xae,0x95,0xa4,0xe5,0x67,0x78,0x00,0xee,0x85,0x26,0x01,0x9c,0x01,0x42,0x90,0x02,0x60,0x41,0x9c,0x01,0x11,0x70,0x1c +,0xff,0xf1,0x50,0x80,0x2f,0x5f,0xfc,0x21,0x4c,0xfe,0xf7,0xfd,0x5d,0x16,0xca,0x50,0x8b,0x69,0x25,0x48,0xd4,0xd0,0x68,0xae,0xcb,0x32,0x0c,0x6e,0x5c,0xff,0xa3,0x35 +,0x38,0x16,0xa1,0x04,0xf8,0xad,0xbe,0x39,0xe7,0x0d,0x4a,0x4f,0x77,0xde,0x89,0x25,0xfc,0xd4,0x25,0x3b,0xcb,0xa6,0xe2,0x8d,0x9e,0xad,0x3d,0x51,0xe1,0x37,0x52,0xee +,0xca,0x44,0xbd,0x9b,0x29,0x6b,0x3a,0x6f,0x7f,0x10,0xc2,0xeb,0x75,0x35,0x61,0x16,0x4e,0x0e,0x83,0xa4,0x19,0xe6,0xce,0x9a,0x6a,0x87,0xa9,0xd8,0x90,0x4c,0x06,0xdc +,0x4f,0x9a,0x52,0x87,0x92,0x42,0xe4,0x86,0xf5,0xc1,0x5a,0x7c,0xa0,0x0c,0x09,0xd1,0x20,0xa2,0xf8,0x07,0x21,0x6b,0x60,0x8c,0xab,0xe3,0xf0,0xfa,0xe7,0x55,0xc2,0x25 +,0xbd,0x65,0x73,0x7b,0x13,0x15,0x29,0x68,0xc5,0x3e,0xab,0xf8,0xaf,0xb9,0x7b,0x06,0x71,0xc1,0x04,0xa4,0xdf,0x36,0xf0,0x78,0xa9,0x24,0x82,0xc4,0x69,0x78,0xfe,0xbe +,0xba,0xdb,0x3a,0x6a,0xce,0xd0,0xc4,0xae,0x05,0xac,0x4f,0xa5,0xa3,0x08,0x2d,0x89,0xcc,0x50,0x39,0x6d,0xdf,0x1c,0xc2,0x22,0x04,0x04,0x22,0x42,0x04,0x26,0x05,0x1c +,0x16,0x50,0x59,0x23,0x16,0x95,0x57,0x24,0x93,0x50,0x6f,0x1a,0x3f,0x19,0x18,0x6e,0x10,0x83,0x41,0x63,0xb7,0x14,0x1b,0x1c,0x8f,0x95,0xf4,0x63,0xa4,0x4a,0x4c,0xfe +,0x9f,0x83,0xd3,0xf6,0x92,0xcf,0x08,0x66,0xf0,0xea,0xff,0x76,0x59,0xca,0x9c,0x35,0x1c,0xb3,0x5b,0xbf,0xe4,0xf8,0xfb,0x14,0x0a,0xaa,0xea,0xc0,0x32,0x5b,0x7c,0xb6 +,0x7d,0x47,0xb8,0xd2,0x5b,0xba,0x9f,0x01,0xbe,0x1f,0xb6,0x95,0xc2,0x54,0x95,0x2a,0x76,0xa0,0x76,0xf3,0xce,0x21,0xc5,0x5d,0xab,0x3b,0xec,0xb2,0x42,0xc5,0xf3,0x2e +,0x4b,0x6e,0x7e,0x85,0x1d,0x21,0xe2,0x01,0x7f,0x7b,0xf0,0xdb,0x60,0x66,0x8f,0xc3,0x47,0x55,0xd1,0xed,0x91,0x51,0x67,0x38,0xd7,0x76,0xae,0x61,0x9e,0x87,0x68,0x35 +,0x8c,0x2b,0xa6,0x34,0x65,0x96,0xbd,0xcf,0x63,0xae,0xeb,0x0a,0x15,0x8f,0xb8,0x13,0x8d,0x49,0x1b,0xad,0xdf,0xca,0x0a,0x27,0xa9,0xc2,0x91,0xc9,0xe0,0x8d,0xfd,0xec +,0x7c,0x8d,0x50,0x91,0x1a,0xa1,0xed,0x44,0x85,0x51,0xf2,0xa1,0x64,0x49,0x84,0x34,0x93,0x81,0x7e,0x16,0x4e,0x05,0xe0,0x22,0x2e,0x70,0xff,0xf1,0x50,0x80,0x2f,0xbf +,0xfc,0x21,0x6a,0xcf,0x77,0xff,0xff,0xff,0xf7,0xb1,0x61,0x40,0x50,0x2c,0x18,0x0b,0x12,0x02,0x82,0x60,0xa0,0x98,0x28,0x42,0x0a,0x08,0x82,0x81,0x20,0x88,0x48,0x22 +,0x12,0x10,0x84,0xc2,0x23,0x31,0x09,0x1d,0xdf,0x5c,0xaf,0x5d,0xfc,0x7b,0xc7,0x9e,0x56,0xa6,0xb6,0xa9,0x75,0x71,0x88,0x49,0xd3,0x5e,0x3e,0x3a,0x1f,0x14,0xfb,0xcf +,0x99,0x2b,0xff,0xa7,0x17,0xef,0x95,0xa1,0xa4,0xe9,0xf1,0x3c,0xbb,0x34,0x97,0x0a,0x57,0xdb,0xf9,0x56,0xba,0xfd,0xef,0x33,0x43,0xea,0xb8,0xd7,0x42,0x1e,0x28,0x3b +,0x3b,0xb5,0x68,0x22,0xf6,0xe8,0x41,0x5d,0x38,0x27,0x2e,0xcc,0xc1,0xdf,0xfc,0xff,0x69,0x78,0x66,0xa2,0xee,0xc9,0x14,0xaf,0xe6,0x76,0xf4,0x23,0x87,0x8f,0x97,0x4a +,0x92,0xa2,0x95,0xbe,0x68,0x16,0x88,0xa3,0xfd,0x57,0xb6,0x12,0x56,0x8a,0x58,0xb5,0xa7,0x07,0x0a,0x7a,0xc3,0xd2,0xf1,0xc1,0x52,0x31,0x72,0x98,0x37,0x23,0x16,0x84 +,0x96,0x67,0x98,0x6f,0xff,0xab,0xe2,0x32,0x59,0x73,0x8c,0x0b,0xb2,0x38,0x20,0x4e,0x07,0xae,0x24,0x89,0x14,0x47,0x79,0xd4,0x08,0xc5,0x09,0x50,0x22,0x09,0x80,0xa8 +,0x41,0x31,0x54,0x28,0x16,0x0a,0x09,0x82,0xa1,0x40,0xb0,0x54,0x2c,0x14,0x1a,0x85,0x02,0x61,0x51,0x08,0x48,0x26,0x15,0x08,0x88,0xc8,0x21,0x31,0x88,0xd9,0xbd,0xf1 +,0x9c,0x4e,0x74,0xcd,0x4c,0xab,0xa2,0xf2,0x4b,0x71,0xe2,0xe7,0xc6,0xf7,0x46,0x75,0x3b,0xf8,0x9c,0x0f,0xf6,0x6a,0x5d,0x17,0xfd,0x7b,0x67,0xfd,0x7c,0x38,0x7b,0x6d +,0xf6,0xbe,0xab,0xa0,0xf9,0x37,0x87,0xf6,0xff,0xe5,0x68,0x88,0xdd,0xe8,0xe3,0x0d,0x9f,0x8e,0x53,0x78,0x76,0xbe,0xac,0xd1,0x0a,0x6c,0xd8,0xa1,0x5f,0xcd,0xed,0x61 +,0x9e,0x87,0x3f,0xdb,0xf5,0x2f,0xe5,0x7e,0x53,0x83,0x82,0x38,0x1f,0x60,0x53,0xff,0x79,0xfa,0x77,0xc3,0x3c,0x4e,0x77,0x36,0x1e,0x33,0x3c,0x60,0x4e,0x1f,0xa7,0x84 +,0x38,0xa0,0xfd,0x2c,0x40,0xf0,0xef,0x6d,0x79,0x5c,0x27,0xa8,0x5a,0x39,0xa9,0xce,0xca,0xa8,0x12,0xa6,0x30,0x1d,0xdb,0x9f,0xb9,0xf8,0x37,0x70,0x03,0xda,0x3b,0xc5 +,0xdd,0xe3,0xd8,0x84,0x52,0x42,0xe1,0x37,0x70,0xfd,0x97,0x70,0x08,0x7b,0xb1,0x3b,0xc2,0xb1,0x00,0xaa,0xd6,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2d,0x1f,0xfc,0x21,0x0a +,0xcf,0xef,0xff,0x7f,0xff,0xff,0xb4,0x80,0xb1,0x48,0x2e,0x26,0x0c,0x05,0x02,0xa1,0x41,0x90,0x50,0x2c,0x12,0x12,0x85,0x04,0x44,0x30,0x88,0x4c,0x22,0x33,0x10,0x9d +,0x5a,0xe3,0xc5,0x75,0x7d,0xcc,0xea,0xf7,0x61,0xbe,0x23,0x22,0xa7,0x1b,0xba,0xa7,0x9d,0xcb,0xaa,0x7c,0x79,0x1a,0x96,0xf5,0xf9,0x6e,0xe7,0x66,0xff,0x02,0xd5,0x3f +,0xf5,0xe3,0xf8,0x4d,0x0d,0x2b,0x86,0x37,0x6d,0x9d,0x43,0x87,0x3b,0xf9,0x4a,0x2d,0x24,0x4b,0xc0,0x00,0xf5,0xdd,0xdd,0x75,0xa3,0x39,0xba,0x43,0x87,0xeb,0x56,0xaa +,0x38,0xd6,0xe8,0x4c,0x70,0xb6,0xfb,0x72,0x8d,0x4e,0xb2,0x95,0x86,0x47,0xe3,0x1b,0x0f,0xaf,0x5c,0x19,0x82,0x74,0x54,0xe8,0xe0,0x4b,0xbf,0xef,0x7d,0x85,0x42,0x9e +,0xaf,0x96,0x62,0x0c,0x93,0x71,0x81,0xe1,0xc6,0x03,0x78,0xe8,0xb5,0x4e,0x5d,0x20,0xb1,0x2e,0xf5,0x93,0x8b,0xa2,0xae,0xf8,0x7f,0x29,0x73,0xba,0x09,0x45,0x79,0x93 +,0x9a,0xc0,0x80,0x73,0x2c,0xa9,0x02,0xa5,0x28,0x50,0x04,0x80,0x52,0x20,0x58,0x4e,0x16,0x2a,0x05,0x82,0xa1,0x40,0xb8,0x50,0x8c,0x14,0x0b,0x05,0x04,0xa4,0x10,0xa8 +,0x8c,0x4a,0x21,0x09,0x98,0x44,0xf5,0xd7,0xa9,0x4f,0xdf,0xed,0xe7,0x9a,0x46,0x75,0xdb,0x34,0x95,0x17,0xed,0xdf,0x1b,0xcf,0x24,0x64,0xb5,0xf4,0x35,0x94,0x6f,0xcf +,0xcf,0xdf,0x46,0xc9,0x3c,0xba,0x7e,0x1e,0x1a,0xb0,0xd0,0xdd,0x18,0xb8,0xd4,0x79,0x4f,0xdd,0xcf,0x3f,0x67,0x69,0xf3,0x99,0xdb,0xbf,0xc8,0x19,0xa9,0x29,0xfd,0x76 +,0xb7,0x5e,0x03,0x2e,0xfe,0x51,0xa9,0xff,0xf9,0xfb,0xe9,0xae,0x61,0x5a,0x3b,0xba,0xdc,0x7f,0xb7,0xec,0x7c,0x3f,0x43,0x0b,0xc7,0x3d,0xfc,0xca,0x72,0xe2,0xe3,0xca +,0x8e,0xeb,0x3b,0x0e,0x45,0x47,0x0e,0x6e,0x40,0xe4,0xf0,0x5c,0x0b,0x6f,0x94,0xde,0x7c,0x4e,0xb0,0x07,0x9b,0x2b,0x00,0x1e,0xb8,0x3f,0x21,0xf5,0x8d,0x21,0xeb,0x00 +,0xf2,0x01,0x4f,0x19,0x09,0x00,0x9d,0x10,0x0f,0x32,0x40,0x07,0xbb,0xdf,0x3b,0xcf,0x75,0x60,0x4b,0xbf,0x75,0x03,0xdc,0x00,0x7b,0x80,0xeb,0x65,0x08,0xcc,0x0e,0xff +,0xf1,0x50,0x80,0x2e,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0x7f,0xff,0xff,0xfc,0xaf,0x62,0xb8,0x54,0x2c,0x18,0x0a,0x06,0x02,0xc1,0x40,0xb0,0x50,0x2c,0x14,0x0a,0x85,0x02 +,0xa1,0x40,0x90,0x54,0x24,0x14,0x11,0x85,0x42,0x41,0x50,0x98,0x48,0x26,0x25,0x09,0x84,0x4e,0xdc,0xab,0xce,0x2f,0xc7,0x5d,0xdd,0xe6,0xb2,0x6b,0x69,0x15,0x2d,0x33 +,0xe3,0x9f,0x1e,0xd5,0xc6,0xf9,0x26,0xbe,0x38,0x1c,0xef,0xdb,0xeb,0xed,0xe7,0xc6,0xde,0x8d,0xdc,0x4b,0xcd,0x3f,0x8d,0x00,0x79,0x79,0xf7,0x3c,0x66,0xfc,0x09,0xd5 +,0x17,0xe2,0x7f,0x30,0x51,0xa6,0xbc,0x9b,0x34,0xa1,0x8d,0xd1,0x6f,0x06,0xaf,0xd3,0xa6,0x4b,0x35,0xcd,0xcb,0xbd,0x5c,0xb1,0xaa,0x5d,0xee,0xe7,0x7a,0x76,0xe8,0x77 +,0x25,0xaa,0x7d,0xbf,0xee,0xfa,0xaf,0x83,0xd7,0x79,0xa8,0x7a,0x9b,0x7a,0xdc,0x4a,0x7f,0x5c,0x9f,0x2c,0x28,0x45,0x22,0x54,0xb6,0x32,0xf5,0x54,0x6a,0x09,0x72,0x03 +,0xc4,0xff,0x10,0x4b,0x88,0x29,0x8c,0x42,0x2e,0xd5,0xf6,0xc0,0xf5,0xa2,0x3c,0x28,0x23,0x70,0x00,0x1e,0x7d,0xd3,0xb8,0x1a,0xa8,0x74,0x48,0x82,0x85,0x69,0x2f,0x24 +,0x82,0x5c,0xc4,0x93,0x2f,0x84,0x00,0x45,0x40,0x14,0xca,0x13,0x0c,0x09,0x83,0x01,0x40,0xb0,0x94,0x2c,0x44,0x1b,0x09,0x02,0xa1,0x41,0x29,0x9c,0x26,0x41,0x1a,0x84 +,0x4a,0xe5,0x4c,0xe2,0x92,0x6e,0xf1,0x75,0x52,0xb5,0x49,0x2e,0x27,0x9e,0xc7,0xb2,0x6f,0x55,0x5c,0x70,0x1e,0xcf,0xf1,0xc1,0xe3,0xef,0x8a,0x35,0x6a,0x41,0xfe,0xe3 +,0xd9,0xa2,0x5f,0x15,0x1f,0x63,0x0e,0x03,0x1a,0x2f,0x0f,0x83,0xf8,0x05,0xd4,0xe8,0xbf,0x89,0x78,0x7f,0x79,0xf9,0x3f,0xaa,0xf0,0xc5,0xf4,0x5e,0xc8,0xfb,0xef,0xe7 +,0xc4,0x69,0x7e,0xa5,0x7f,0x37,0x1a,0x47,0xf1,0x11,0x81,0xdc,0xa3,0x4a,0x5d,0x63,0x1c,0x59,0x7c,0xa9,0x53,0xf3,0x6b,0xb6,0x68,0x3c,0x9c,0xa8,0xec,0x1c,0xf9,0x70 +,0x1c,0xfc,0xd6,0x02,0x83,0x99,0xc9,0x6e,0x00,0xe5,0xc4,0x72,0x00,0xf3,0x80,0x01,0xde,0xff,0xfd,0x87,0x78,0xf7,0x3b,0xc0,0x77,0x43,0xb8,0xee,0xfa,0xe1,0x5b,0x10 +,0xb8,0x00,0x92,0xef,0x00,0x00,0x02,0x40,0x15,0x0c,0x00,0x13,0x05,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x2c,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xbf,0xff,0xf9,0xaf,0x60 +,0xc0,0x58,0x30,0x16,0x12,0x05,0x86,0xa1,0x40,0x98,0x50,0x8a,0x14,0x21,0x05,0x02,0x43,0x11,0x98,0x44,0x26,0x41,0x3b,0x98,0x1d,0x77,0x67,0x5d,0xe9,0x97,0x51,0x26 +,0x5a,0xa4,0x71,0x8d,0x49,0xba,0x8f,0xdf,0xae,0x81,0xef,0x57,0x4b,0xee,0x7a,0x30,0xfa,0x5b,0xee,0x3f,0xec,0x5d,0xbd,0xc3,0xc1,0xeb,0xfe,0xb2,0xfc,0x67,0xf9,0x3f +,0x89,0x5f,0xe2,0x8a,0xb9,0xab,0x21,0xfb,0xc9,0x1d,0x35,0xe9,0xa8,0x56,0x7d,0x21,0x13,0xcb,0xb0,0x23,0xd2,0x34,0xb7,0x8f,0xd3,0xe7,0x15,0x17,0xf7,0xe0,0x92,0x7c +,0xe6,0x59,0x30,0xfc,0x22,0x96,0xcd,0x7c,0x90,0xb4,0xb1,0xee,0x90,0x8e,0xa4,0xbe,0x94,0x9f,0x3b,0xb5,0x5f,0x06,0x02,0x91,0x61,0x9c,0x17,0xfc,0x3d,0x6d,0xb8,0x04 +,0xab,0x72,0xb3,0xea,0x56,0xa3,0xc2,0x88,0x2b,0xee,0x81,0x0f,0x6a,0xfb,0x50,0x2f,0x09,0x05,0xcc,0x21,0xdd,0x5a,0xde,0x40,0xa0,0x61,0x25,0x00,0x01,0x64,0x00,0x54 +,0xa0,0x54,0x2c,0x17,0x0a,0x05,0x82,0x81,0x61,0x20,0x98,0x2e,0x15,0x13,0x05,0x42,0x86,0x60,0xa9,0x0c,0x62,0x35,0x09,0x84,0x42,0x63,0x11,0xab,0x3a,0xef,0x38,0xe3 +,0xc4,0x8a,0xbc,0xae,0xb7,0x4b,0xa9,0x7a,0x90,0x8e,0x7d,0xb5,0x5c,0xd7,0x52,0x7d,0xbf,0x1f,0x81,0xd1,0x7c,0x96,0xfb,0xfd,0xb7,0xfe,0x9f,0x9a,0x3f,0x7e,0x9e,0x5d +,0x47,0xfb,0x7f,0xec,0xf3,0x49,0xc2,0xcd,0x3b,0x9e,0xbe,0xaf,0xcf,0x8b,0x87,0x56,0x1f,0x3e,0x53,0x5f,0x9f,0x87,0x94,0xb4,0xbf,0x63,0xf0,0x6d,0xa7,0xb5,0xfc,0xe7 +,0xd8,0x35,0xb7,0x10,0xf4,0x47,0xe8,0x5e,0x79,0xcd,0xff,0xed,0xd6,0x84,0x75,0x2e,0xcb,0x5c,0x52,0xde,0xeb,0x4a,0x73,0x83,0x3d,0xb4,0x3b,0x16,0xe7,0xe1,0xc7,0x84 +,0x80,0x1e,0x0e,0xc0,0x03,0xc0,0xf3,0x04,0x3f,0xd3,0x22,0x3b,0xfe,0xb0,0x3d,0x77,0x74,0x1d,0xfb,0x4e,0x14,0xd8,0x8d,0x4b,0x8c,0x40,0x2f,0x20,0x03,0xc0,0x13,0x03 +,0xd7,0xc4,0x1d,0xe4,0x0f,0x5c,0x7f,0xfe,0x40,0x0e,0xfb,0xdd,0x35,0x4f,0xef,0x05,0xca,0x00,0x44,0x0e,0xff,0xf1,0x50,0x80,0x2b,0xbf,0xfc,0x21,0x2a,0xcf,0xee,0xbf +,0xff,0xff,0xf8,0xb0,0x60,0xb8,0x58,0x30,0x16,0x12,0x05,0x84,0x81,0x60,0xa0,0x98,0x28,0x82,0x0a,0x04,0x88,0x62,0x10,0x98,0xc5,0x2d,0xc4,0xae,0xaa,0xa5,0x4a,0x93 +,0x7c,0x50,0x24,0x4a,0xe2,0xf2,0xe4,0xe7,0xf1,0xef,0x9a,0x9d,0x7f,0x8f,0x61,0x1f,0x88,0xf6,0xff,0x23,0xf8,0x8f,0xb6,0x7d,0x9a,0x7f,0xa2,0x8f,0xeb,0xe8,0x9c,0xcc +,0xfc,0xd6,0x17,0xe2,0xb8,0x9e,0xf9,0xa8,0xeb,0x10,0xee,0xe6,0xda,0xcf,0xa1,0x73,0xea,0x3f,0x85,0xe3,0xde,0x0f,0x14,0xf8,0xff,0xa5,0x1f,0xb0,0xb7,0x55,0xe8,0x85 +,0x92,0xe0,0xa9,0xf7,0x44,0x0b,0xcb,0xa7,0xc7,0xdc,0x38,0x96,0xdb,0x9d,0xae,0x87,0xf3,0x87,0xd3,0xe5,0x7b,0x60,0xf4,0xa6,0x59,0xa8,0xea,0x49,0x30,0x45,0x56,0xe8 +,0xf7,0x4e,0xf1,0xdc,0x1d,0xba,0x8a,0xcd,0x03,0xcd,0x00,0x1e,0xbc,0x00,0xf5,0xc2,0x11,0x60,0x54,0x04,0x45,0x6c,0x48,0x18,0x96,0xa8,0x18,0x40,0x08,0x80,0xa8,0x52 +,0xc0,0x54,0xa0,0x98,0x28,0x26,0x0b,0x85,0x02,0xc5,0x40,0xb0,0x50,0x4c,0x34,0x12,0x89,0x02,0x61,0x50,0x88,0x4c,0x22,0x13,0x0a,0x88,0x46,0x61,0x13,0x37,0x97,0x97 +,0x5c,0x66,0xb9,0x9c,0x65,0x52,0x15,0x2d,0x2d,0xe7,0xbf,0xbf,0xcf,0xb5,0x7d,0xff,0xa7,0xdf,0x7d,0x7b,0xce,0xff,0x16,0x3e,0x5f,0xf4,0x7c,0x7b,0xff,0x90,0xff,0x81 +,0xd9,0xeb,0xf6,0xa3,0x92,0x6a,0x4d,0x03,0xb6,0x33,0x2c,0x54,0xfd,0x7e,0x53,0xd0,0xbe,0x0e,0xd1,0xf9,0x05,0x5f,0xdb,0x6a,0x5f,0xe9,0x5e,0xa6,0xaa,0xce,0x47,0x9f +,0x99,0x81,0xca,0xd5,0xb3,0x59,0xd8,0xdd,0x26,0xc5,0xbf,0xfe,0x07,0xee,0xa9,0x73,0x75,0x74,0xa3,0xb1,0x1c,0xbb,0xde,0x41,0xb6,0x74,0x7e,0x4e,0xcd,0x3c,0x3e,0x8b +,0xe7,0x42,0xe6,0x65,0x04,0xb9,0x07,0x36,0x8e,0xf3,0xdb,0x9e,0xba,0xb8,0x01,0x3e,0x2e,0xea,0x6b,0xd0,0x03,0xc8,0x00,0x00,0x0f,0x15,0x84,0x15,0x4a,0x85,0xbf,0xa9 +,0x50,0x01,0xeb,0x00,0x90,0x96,0xd0,0x34,0x26,0x07,0x19,0x5d,0x01,0x60,0x16,0x03,0x80,0xff,0xf1,0x50,0x80,0x29,0xff,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x45,0x18,0x2c +,0xd1,0x9a,0x14,0xb8,0x92,0x4e,0x2a,0x70,0x37,0xc2,0x13,0x38,0xa7,0x46,0x54,0x2d,0x86,0x5e,0xec,0x8d,0x4c,0x59,0xf5,0xfa,0xf4,0x9a,0x4d,0xa7,0xee,0xde,0xbf,0x1e +,0x74,0x38,0x61,0x6d,0x09,0xa7,0xe3,0xb3,0xbe,0xd3,0xb2,0x93,0xdb,0x5f,0x85,0x52,0x5d,0x2d,0x6b,0x45,0x9d,0x3c,0xcc,0x55,0x72,0x81,0xab,0xb2,0xf7,0x68,0x97,0x8b +,0xdf,0x3b,0xba,0xc1,0xa4,0xfd,0x81,0xe1,0x9d,0x17,0xf7,0x9f,0xd8,0xa7,0xe1,0xe8,0xa8,0x53,0xeb,0x42,0xdf,0xd6,0x1f,0x4d,0x7b,0x9c,0x77,0xc2,0xf2,0xe0,0x21,0x7e +,0x24,0xb3,0xfe,0x6b,0xd1,0x1d,0x53,0x22,0xa2,0xef,0xac,0x11,0x5b,0x82,0xff,0xbe,0xa3,0x0b,0x30,0xf7,0xb1,0xb6,0x84,0x15,0x34,0xe2,0xbc,0x54,0x29,0x05,0xbf,0xab +,0xaf,0x2b,0x5d,0xd5,0x7a,0xc6,0x88,0x2e,0x58,0x1f,0x60,0xe4,0x47,0xed,0xba,0xd9,0xde,0x2b,0x97,0x82,0xb0,0x54,0x9c,0x53,0x9a,0x02,0x62,0xe3,0x30,0x88,0x80,0x98 +,0xb9,0x69,0x94,0x70,0x9a,0x21,0x34,0x2d,0x09,0x35,0xd3,0xab,0xc1,0xe3,0xaf,0xb4,0x42,0x54,0xd6,0xeb,0xbd,0x7d,0x63,0xc7,0xf1,0x6f,0x55,0xd6,0x37,0x43,0x17,0x7f +,0x39,0x0b,0x7d,0xab,0x92,0x03,0x15,0xf5,0xe0,0x87,0xc7,0xfe,0x48,0x36,0x59,0xd4,0x3d,0x94,0xf8,0x3f,0x93,0xbb,0x89,0x1c,0xfe,0x3c,0xa9,0xd5,0xe1,0x1e,0x59,0x77 +,0xc8,0xfd,0xfe,0x34,0x69,0xc1,0x65,0xee,0x1c,0x3c,0x65,0x8f,0x0a,0x8e,0x20,0x3b,0x4e,0x51,0xd9,0xb2,0x76,0xc9,0xaf,0xb6,0xae,0x2a,0xd6,0xc2,0x05,0x8b,0x2c,0x57 +,0xce,0x59,0x4c,0x80,0x7b,0xfb,0xd3,0x94,0xfc,0x33,0x9e,0xf6,0xa1,0xa3,0x5d,0xfd,0x0b,0x3a,0x07,0xb3,0x1b,0xa1,0x4f,0xb9,0x38,0x23,0x2f,0x1d,0x8d,0x57,0xab,0x91 +,0x20,0x40,0x11,0x23,0x5d,0x67,0x4b,0xff,0xe9,0x43,0xe3,0x07,0xdc,0x00,0x04,0x20,0xc3,0x39,0x74,0x4b,0x30,0x01,0x10,0x11,0xe0,0x32,0x09,0x80,0x09,0x8b,0x81,0xc0 +,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x44,0x16,0x89,0x45,0x35,0x55,0x72,0xe9,0x9c,0x70,0x28,0x3f,0xfe,0xa4,0xfa,0x48,0x6c,0x59,0x2e,0x7d +,0x29,0xfd,0xa4,0xcf,0xdf,0x87,0xcc,0x49,0xdb,0xe4,0x39,0xeb,0xb2,0xfc,0x25,0xdd,0x5d,0x16,0x59,0xec,0x4d,0x7b,0x7c,0x43,0x4b,0x77,0xe5,0x53,0xfe,0x69,0x67,0xb3 +,0xaa,0x2c,0xbf,0xeb,0x25,0x3e,0xdf,0x44,0xca,0xbf,0x74,0x59,0x16,0x8c,0xef,0x89,0xbb,0xda,0x58,0x0f,0x68,0xcb,0xaa,0xa4,0xfc,0x01,0xcf,0xf7,0xf1,0x4d,0x4a,0x47 +,0x59,0x7d,0x4b,0xf1,0x13,0x03,0x45,0xff,0x05,0x76,0x11,0xc1,0x7d,0x06,0xe4,0xbe,0xf6,0xae,0xa7,0xc5,0xab,0xfd,0x14,0x95,0x30,0xdb,0xab,0x50,0x1d,0x27,0xa0,0x8e +,0xb9,0x25,0x7c,0x22,0x7d,0x7b,0xbd,0x49,0x35,0x18,0xee,0xd4,0xc9,0xde,0x88,0x22,0x24,0x85,0x1e,0xcd,0x49,0x5a,0x3f,0xab,0x64,0x07,0x05,0xa3,0x86,0x07,0x3f,0xbd +,0x65,0x14,0x72,0xc7,0xf8,0x31,0xac,0x9a,0x10,0x3b,0x00,0xbb,0x95,0x44,0xbd,0x81,0x87,0xa5,0x77,0x96,0x70,0xd0,0x8f,0x7b,0xbf,0x09,0xb5,0x23,0x72,0x94,0x8d,0x04 +,0xa2,0x53,0xc2,0x48,0x52,0x04,0x86,0xd0,0xf0,0x14,0x71,0x19,0xaa,0x34,0x25,0x79,0x24,0xd1,0xc7,0xb7,0x02,0x4c,0xf9,0x39,0xdf,0xa4,0xda,0xb9,0x7f,0x0d,0xed,0xe4 +,0x74,0x82,0xca,0x61,0xed,0x39,0x93,0xa6,0x83,0x4f,0xe1,0x46,0xab,0x0c,0xf6,0x46,0x45,0xcc,0x8b,0x84,0x4a,0x8f,0x30,0xb4,0xd3,0xe2,0xcf,0x49,0x1e,0x24,0x1e,0x98 +,0x88,0x31,0x5c,0xac,0xfa,0xa4,0xf1,0x90,0x31,0x09,0xa4,0x39,0x65,0x95,0xd4,0xd7,0x26,0x32,0xeb,0x1b,0xd0,0x36,0x5e,0x72,0x26,0x1a,0xec,0x27,0xc5,0x0e,0x6a,0xa8 +,0x0c,0xea,0x38,0xb6,0x4e,0x0a,0xb7,0x5e,0x58,0x63,0x29,0x19,0x01,0xc4,0xc6,0x7a,0x04,0xad,0xb0,0x4c,0x54,0x09,0xa0,0x4c,0xb5,0x24,0x06,0xee,0x02,0x19,0x93,0x32 +,0x74,0x49,0x12,0x76,0xc9,0xd0,0x3f,0x94,0x95,0x21,0x37,0xbc,0x11,0x3b,0xd9,0x5c,0xa8,0x21,0xc4,0xba,0x74,0x11,0xca,0x74,0x63,0x33,0xa2,0xfb,0xe7,0x45,0x62,0xa1 +,0x8e,0x08,0x77,0x11,0x83,0x0d,0x14,0x8e,0xec,0x00,0x00,0x3d,0xa1,0xaa,0x44,0x00,0x00,0xcc,0x34,0x08,0x0e,0xff,0xf1,0x50,0x80,0x31,0xbf,0xfc,0x21,0x4c,0xfe,0xff +,0xfd,0x45,0x26,0x48,0x58,0xa2,0x54,0x64,0x4a,0x49,0x0a,0x92,0xe0,0xac,0xb9,0x72,0x4d,0x9a,0x2a,0x53,0xa2,0x50,0x1e,0x86,0xbe,0xbc,0x0e,0xf2,0xe8,0x15,0x21,0x9c +,0x08,0x82,0x28,0x30,0xea,0x54,0x36,0x14,0xce,0xcf,0x94,0xc4,0x39,0x73,0x91,0x2f,0xbd,0x74,0x7b,0xb3,0xf5,0xf3,0x35,0xf7,0xcf,0x41,0xe2,0xf7,0x35,0xc8,0xf8,0xf5 +,0x1f,0x4f,0xcb,0x7b,0xed,0x9f,0xec,0xff,0x5f,0xd7,0xdb,0x94,0xc5,0x80,0x0d,0xaa,0xe3,0x3c,0x3b,0x25,0x93,0x39,0x05,0xd7,0x92,0x4d,0x5c,0xc8,0xda,0x16,0x56,0x62 +,0xe0,0x23,0xc9,0x86,0xf1,0x40,0x15,0xaf,0xea,0x7a,0xb8,0x97,0xcf,0xbe,0x41,0x9d,0x40,0xc9,0xc6,0xd5,0x1a,0xcf,0x30,0xd0,0xdc,0x36,0x7f,0xc4,0xcc,0x99,0x80,0x2e +,0xe4,0xe6,0x1e,0x9e,0xb5,0x61,0xd3,0xbc,0xa1,0xd1,0x53,0x32,0x71,0x9b,0x87,0x74,0x76,0xc1,0xbd,0xc8,0xeb,0x9c,0xd4,0x2b,0x51,0x6a,0xa4,0xc2,0xd3,0x06,0x4e,0xfb +,0xa1,0xad,0xfb,0xf2,0x54,0xdf,0xa2,0xda,0x8a,0xc5,0xb1,0x91,0xd6,0x27,0xac,0x7c,0x96,0x24,0x10,0xd8,0x87,0x06,0xb9,0xef,0x51,0xe3,0x5a,0xa5,0x04,0x2c,0x64,0xb1 +,0xcc,0x5b,0xe2,0x7b,0xb4,0x1f,0x94,0x4a,0x28,0x2c,0x61,0x32,0x42,0xa8,0x88,0x93,0x29,0x44,0xb9,0x75,0xad,0x0b,0x36,0x68,0xe7,0x46,0x22,0x80,0x6b,0xe6,0x86,0x6e +,0xf5,0x9d,0xd7,0x4b,0x3e,0x38,0xbf,0xdb,0xf3,0x9e,0xc7,0xae,0xbe,0x9c,0xef,0x4e,0xf9,0x41,0x9a,0x4e,0x91,0x2c,0x36,0xcb,0x5c,0xe0,0x4f,0xad,0x5e,0x24,0xb4,0xe1 +,0x16,0xd8,0x88,0xdc,0x40,0x99,0x9b,0x1d,0x04,0x00,0xcf,0x5e,0xbb,0x5e,0xb9,0x33,0xdf,0xbd,0xfa,0x55,0xdf,0x94,0xf4,0xf6,0x5f,0x3a,0x62,0x93,0x45,0x41,0x49,0x86 +,0x54,0x04,0x8b,0x60,0xfa,0x25,0xdc,0xfe,0x0f,0x15,0x1e,0x9a,0xc5,0xb1,0x1e,0x87,0x78,0x1c,0x41,0xda,0xfe,0xdf,0xc3,0xf5,0x65,0x7e,0x67,0xbe,0xe8,0x9f,0x87,0xeb +,0x07,0x6c,0x1d,0x9a,0x37,0xc8,0xef,0xc1,0xf4,0xe0,0x49,0xf0,0xc1,0x2e,0x2b,0x68,0xc9,0x4e,0xb8,0x3b,0x59,0x1d,0x0d,0x8a,0x71,0x18,0x25,0x70,0xe3,0x24,0x72,0x10 +,0x90,0xcc,0xec,0x0c,0x54,0x6a,0x69,0xb5,0x7a,0x84,0x7a,0x99,0xb3,0x92,0xa6,0x92,0xc7,0x03,0x19,0x55,0x72,0x5f,0xe1,0xb8,0x18,0xc6,0x01,0xee,0x8f,0x70,0x61,0x18 +,0xa8,0x07,0xff,0xf1,0x50,0x80,0x2f,0x5f,0xfc,0x21,0x6a,0xcf,0xff,0xff,0xff,0xff,0xff,0xb0,0x40,0xb0,0x5c,0x2c,0x34,0x0a,0x85,0x82,0xa1,0x60,0xa0,0x60,0x28,0x26 +,0x0a,0x19,0x42,0x81,0x20,0xa8,0x48,0x2a,0x11,0x7b,0xb9,0x25,0x7b,0x77,0xc7,0x37,0x5c,0xea,0x91,0x25,0x8a,0xb5,0x41,0x26,0x4a,0x68,0xf8,0xb1,0xa4,0x57,0xf6,0x78 +,0xed,0xa1,0x7d,0xdd,0xd8,0x7d,0x75,0xe5,0xb4,0x7d,0xaf,0xd1,0xa2,0xfc,0x64,0x90,0xd1,0xd6,0x46,0xfd,0x6a,0x9f,0x89,0xa4,0xb7,0x7d,0x18,0x3e,0x7e,0x87,0xfd,0x7f +,0x71,0x57,0xe0,0x54,0x23,0x8a,0x49,0xe5,0xf6,0x72,0xdf,0xe6,0x7b,0xfb,0xd7,0x5b,0xb7,0x06,0xaf,0xf6,0xc6,0x29,0x48,0x6f,0xa5,0xa9,0xf5,0x64,0x9b,0xae,0x3d,0xc4 +,0x23,0xc6,0x43,0x6d,0x0d,0x70,0xe1,0x37,0x6c,0x95,0x49,0x4f,0x35,0xce,0x08,0xde,0xbe,0x46,0xdb,0x78,0x32,0xd8,0x96,0x2a,0xde,0x54,0xfc,0x47,0x84,0xbb,0xc5,0xe5 +,0x0a,0xed,0xd6,0x46,0xbc,0x26,0xe6,0x32,0x03,0x3e,0x32,0x4d,0x17,0x4a,0x97,0x58,0xd4,0x80,0x9c,0x65,0x1b,0xdb,0xd8,0x06,0x2d,0x9e,0x40,0x50,0x0a,0x00,0xa9,0x40 +,0x98,0x58,0xaa,0x16,0x09,0x05,0x82,0xa1,0x61,0xa0,0x48,0x28,0x16,0x0a,0x11,0x42,0x81,0x51,0x88,0x54,0x46,0x31,0x09,0x84,0x42,0x61,0x11,0x18,0x44,0x4c,0xcb,0xab +,0xde,0xa7,0x5e,0xb5,0xbb,0xa7,0x9f,0x7b,0x25,0x5a,0xeb,0xaa,0xe1,0xcc,0xde,0x6b,0x7e,0x79,0xfb,0xf2,0xe0,0x68,0xbf,0xcd,0xf3,0xc7,0xb6,0x4d,0x56,0xe8,0xeb,0xf6 +,0xd6,0xfb,0xf4,0x27,0xe7,0xe1,0x29,0x87,0xbe,0x78,0x09,0xff,0x94,0x7e,0x13,0x9a,0x49,0xf5,0x5f,0xd1,0xef,0x74,0x71,0xfb,0xdf,0xfd,0x5f,0xfe,0x75,0x70,0x23,0x56 +,0xd9,0xba,0x3f,0xf2,0xbe,0x4f,0x12,0xf0,0x03,0x58,0xfa,0x3e,0xc9,0xf8,0x8d,0x29,0x6f,0x15,0xf9,0x8e,0x6e,0x2e,0x29,0xbd,0xdf,0x24,0xeb,0xc4,0x17,0x57,0xcf,0x9c +,0x79,0xc3,0xe1,0x0e,0xb2,0xe7,0x82,0x6c,0x7d,0xc5,0x01,0xfc,0x74,0x32,0xc8,0x65,0x40,0x3c,0x40,0x40,0x0f,0x10,0x7c,0x07,0xba,0xbb,0xbc,0x0a,0xff,0xc6,0x16,0xef +,0xce,0x08,0x25,0x46,0x46,0x4b,0x52,0x83,0xd6,0x35,0xa1,0x45,0x31,0x77,0x01,0xfc,0x84,0x31,0x1d,0x02,0xd3,0x03,0xbe,0x08,0xa4,0x0f,0xa0,0x0e,0xff,0xf1,0x50,0x80 +,0x2d,0x9f,0xfc,0x21,0x0a,0xcf,0xdf,0xdf,0x5f,0xff,0xfc,0xb0,0x60,0xc0,0x58,0x6a,0x14,0x0b,0x05,0x02,0xc1,0x41,0x38,0x48,0x28,0x18,0x0a,0x85,0xc2,0x82,0x20,0xa8 +,0x50,0x44,0x13,0x0a,0x84,0x82,0x21,0x21,0x08,0x48,0x22,0x23,0x10,0x98,0xe7,0x89,0xbb,0xbe,0x7c,0xf3,0x7b,0xeb,0xb5,0xb8,0xc4,0xa9,0x57,0xae,0x6e,0xb2,0x4a,0x79 +,0x9b,0x55,0xfe,0xfd,0x04,0xff,0x34,0x02,0xe3,0x84,0x79,0xfe,0x96,0x7d,0x0e,0x80,0x9c,0x3f,0x85,0xb8,0xbf,0xf6,0xf4,0x3e,0xa0,0x9d,0x1f,0x5b,0x67,0xb7,0x7f,0xdb +,0xb4,0x6e,0x1c,0xf8,0x4d,0xab,0xf8,0xad,0xa7,0xea,0x89,0xa5,0xff,0x38,0x2e,0xa8,0xcf,0x7f,0x6c,0x72,0xfa,0x62,0xe0,0xa1,0xe1,0x8f,0xe7,0xcf,0xb4,0x56,0xbb,0xe8 +,0x3c,0xe6,0x9f,0x53,0x2c,0xb7,0x99,0xfe,0x7c,0x71,0x94,0xf7,0x30,0x53,0x7b,0x48,0x7b,0xa8,0xa5,0xd0,0x63,0xcb,0xd0,0x12,0x46,0x43,0xf4,0x16,0xf5,0x4c,0x80,0x1c +,0x62,0x8f,0x28,0x7d,0xc0,0xb8,0x15,0x78,0xc3,0xef,0x79,0x90,0xd1,0xab,0x1a,0x77,0xf7,0xd5,0x17,0x70,0x0e,0xe8,0x97,0x74,0x56,0x14,0x50,0xad,0x37,0xc1,0x72,0x23 +,0x64,0x29,0x77,0x54,0xe4,0x04,0xc1,0x00,0x15,0x08,0x26,0x0a,0x85,0x03,0x01,0x60,0xa0,0xd8,0x28,0x17,0x0b,0x05,0x42,0xc1,0x43,0x98,0x94,0x26,0x31,0x1a,0x84,0xc4 +,0x23,0x31,0x08,0xdf,0x5f,0xb3,0x8f,0xcf,0xef,0xcc,0xbe,0x58,0x49,0x8a,0x9a,0xce,0xab,0x35,0xc6,0x7d,0x4e,0x5b,0x70,0xf5,0xe5,0xd7,0x3a,0x1b,0xf7,0x66,0xfc,0xdd +,0x7b,0x9f,0x3e,0x1e,0xea,0xbb,0x7e,0x63,0xfe,0xef,0xb1,0x40,0x7e,0x2a,0xba,0xbb,0x0a,0xd4,0xf6,0x92,0x7d,0x1c,0x5b,0xd6,0xc1,0x3e,0xe6,0x7f,0x5e,0xf3,0xbe,0xc7 +,0xb2,0x3d,0xf6,0x7f,0xf5,0x52,0x5e,0xb0,0x0f,0xe9,0x7f,0xd8,0x76,0xb7,0x57,0x78,0xd7,0x2e,0xa7,0xc1,0x77,0x13,0xd8,0xff,0xe9,0x1c,0x2e,0x05,0xc7,0x94,0x54,0xbe +,0x1d,0xde,0x2c,0xdd,0xff,0x66,0x1d,0xe3,0xba,0x5e,0xc2,0x37,0x02,0xf4,0x8a,0x44,0x80,0x00,0xf0,0x00,0x1e,0xe8,0x3b,0xc1,0x41,0x02,0x76,0x00,0x24,0xbd,0x47,0xae +,0x07,0xb8,0x01,0x70,0x09,0x8b,0x80,0xe0,0xff,0xf1,0x50,0x80,0x2d,0x3f,0xfc,0x21,0x0a,0xcf,0xe7,0xff,0x9f,0xff,0xfc,0xaf,0x62,0xc0,0x50,0x6c,0x13,0x09,0x06,0x02 +,0xc1,0x40,0xb8,0x54,0x30,0x14,0x13,0x05,0x0a,0x41,0x11,0x10,0x44,0x26,0x41,0x29,0x84,0x44,0xe6,0xea,0x55,0xfb,0x7b,0x9a,0xc9,0x92,0x2f,0x25,0x69,0x26,0x21,0xc5 +,0x1c,0xe9,0x33,0xeb,0xfe,0xfc,0x01,0xfc,0xd5,0xee,0xa3,0x6a,0xfb,0x3c,0x3b,0xb3,0x83,0xf2,0x6e,0x0b,0x47,0x71,0x2f,0xe1,0x7e,0xa3,0xc7,0xfc,0xa0,0xeb,0xd7,0xd0 +,0x9c,0x7b,0x9d,0x05,0xab,0xed,0xd9,0x8f,0x55,0x85,0xc3,0xd2,0x04,0x7e,0x36,0xb3,0x49,0xf2,0x21,0xc7,0x74,0x18,0xd4,0x66,0x22,0xb8,0x57,0x3a,0x6f,0x84,0xef,0xb3 +,0xcb,0x77,0xcc,0x91,0x75,0x19,0xee,0x2d,0xaf,0xcc,0xe3,0x1b,0x9d,0xb9,0xa6,0x3c,0x12,0x94,0x56,0xbe,0xee,0x09,0x3b,0xc1,0x55,0x6c,0x1d,0x50,0x6f,0x89,0x2f,0x46 +,0xb4,0x0a,0x5e,0x87,0xcf,0xde,0x60,0x53,0x5e,0x3e,0x81,0xee,0x2f,0x6d,0x91,0x31,0xf2,0x34,0x28,0xf7,0x2b,0x55,0x8d,0x74,0x20,0x85,0xa6,0x2a,0x95,0x15,0x27,0xda +,0x02,0xc1,0xec,0x01,0x1b,0x80,0xa0,0x15,0x08,0x26,0x24,0x05,0x82,0xe1,0x20,0xb0,0x54,0x28,0x16,0x0a,0x05,0x8c,0x85,0x50,0x88,0x54,0x26,0x35,0x18,0x84,0xc2,0x26 +,0x66,0x6b,0x78,0xbe,0x38,0xf5,0x75,0x37,0x57,0x9a,0x52,0x48,0xeb,0xdb,0x79,0x37,0xd5,0x3d,0x7b,0x6b,0xdf,0xcf,0x19,0xa1,0xd5,0x6b,0xe5,0xdb,0xb0,0xee,0xdb,0xaa +,0x9e,0x81,0xef,0xf5,0xfa,0x16,0xde,0x38,0x90,0x7b,0x0d,0xfe,0x5b,0xd7,0xca,0xda,0xc7,0xf5,0x64,0x6b,0xc6,0xfa,0xe1,0x77,0xd3,0x87,0x1b,0x27,0x0b,0xa4,0xb9,0x29 +,0x2d,0x55,0xc0,0x5b,0x7f,0x3b,0xd9,0xb9,0x24,0x1c,0x28,0x83,0x52,0x89,0xc3,0x6f,0x0d,0x27,0x4c,0xaf,0x73,0x5e,0x8f,0xf9,0x99,0xe0,0xbd,0x79,0x4d,0x1f,0xa2,0x6e +,0xa8,0x07,0xdf,0xc8,0xbc,0xfa,0x40,0x1e,0x44,0x00,0x77,0x4f,0x59,0xde,0x3d,0x63,0xbe,0x15,0x3c,0x7f,0x5c,0x00,0x0f,0x30,0x00,0x3c,0x40,0x00,0x3c,0x42,0x98,0xc5 +,0xef,0x43,0xbc,0x02,0x89,0x86,0xb8,0x84,0xa0,0x04,0x89,0xa3,0x70,0xb2,0x01,0x70,0x38,0xff,0xf1,0x50,0x80,0x2d,0x9f,0xfc,0x21,0x0a,0xcf,0xcf,0x6f,0xbf,0xff,0xfc +,0xb2,0x70,0xc0,0x58,0x88,0x16,0x12,0x06,0x02,0x81,0x61,0x20,0x58,0x28,0x17,0x0a,0x14,0x82,0x81,0x21,0x08,0x48,0x26,0x11,0x21,0x88,0x42,0x62,0x12,0x33,0xe3,0xd4 +,0xe1,0x7e,0x2c,0xaf,0x3c,0xc9,0x96,0xcd,0x4d,0xd9,0x2b,0x8a,0x99,0x5e,0x6b,0x2e,0xf7,0xaf,0xf6,0xe0,0x3b,0x35,0x69,0xbc,0x7c,0x34,0xcd,0x67,0xbf,0xb2,0xce,0xd4 +,0xf5,0xe8,0x2d,0x15,0xde,0x02,0x0f,0x68,0x3e,0xfc,0x87,0xed,0xb3,0x51,0x63,0x57,0x35,0xeb,0xdf,0xa0,0xb4,0xdb,0xa6,0xab,0x93,0xeb,0xdc,0x7e,0x28,0x33,0x10,0x8e +,0xe7,0xbc,0x0b,0xd4,0x20,0xfa,0x96,0xc8,0x42,0xfb,0x1e,0x0c,0x2c,0x5c,0x7d,0x92,0xef,0xc8,0x83,0x1d,0x39,0x96,0x26,0xea,0x38,0xcf,0x75,0x5c,0xf1,0x70,0x53,0x6c +,0x31,0xca,0xf6,0x54,0xd1,0x19,0x04,0x83,0xf7,0xef,0x42,0xaa,0x47,0xf9,0x91,0xb5,0x6f,0x45,0x6e,0x85,0xa7,0x27,0x18,0x2f,0x96,0x04,0xbe,0x50,0x39,0x40,0x7b,0xa0 +,0x3c,0xc9,0x24,0x1d,0x56,0x3b,0xf5,0x95,0x04,0xb1,0x81,0xde,0xe2,0x48,0x14,0xb5,0x11,0x20,0x01,0x10,0x28,0x10,0x90,0x34,0x0a,0x85,0x02,0xc1,0x41,0x30,0x90,0x4c +,0x24,0x0b,0x05,0x42,0x81,0x50,0x98,0x54,0x46,0x31,0x19,0x9c,0x46,0xfb,0x56,0x7b,0x7d,0xa5,0xf9,0xe3,0xde,0xa4,0xdd,0xaa,0xe9,0xa9,0xbd,0x38,0x55,0xf2,0x71,0x69 +,0x56,0xef,0xe3,0x81,0xc4,0xbf,0xd5,0xfb,0x6f,0xaf,0x4f,0xd2,0x66,0x41,0xa1,0x0f,0xcc,0x3e,0x87,0x89,0xa9,0xc4,0x7e,0xeb,0xca,0x7c,0xdf,0x8f,0x26,0xd6,0x2e,0x47 +,0xda,0xdf,0x36,0xa6,0x11,0xcd,0xef,0xa1,0xf9,0x8c,0x8e,0x23,0xb2,0xc2,0xfb,0x37,0xf1,0xe8,0x1c,0xbd,0xaf,0x07,0x57,0xf1,0x93,0x5e,0x5f,0x8d,0xf7,0x8d,0x5c,0xed +,0x6d,0xae,0x5b,0x3a,0x6f,0xdf,0x7f,0x88,0xe0,0x13,0xc2,0x78,0x01,0xe4,0x20,0x7b,0xeb,0x07,0x76,0x6b,0x3f,0xf4,0xd0,0x7b,0xa1,0xee,0xc3,0xa1,0x68,0xd9,0xd0,0x9a +,0x3c,0x12,0x42,0x2b,0x4a,0x4e,0xe2,0x21,0xdd,0x04,0x41,0xdf,0x03,0xb8,0x07,0x7f,0xdd,0x13,0xf7,0x6e,0x00,0xee,0x82,0x89,0x20,0x02,0x50,0x22,0x07,0xff,0xf1,0x50 +,0x80,0x2e,0x5f,0xfc,0x21,0x0a,0xcf,0xfb,0xff,0xbf,0xbf,0x77,0xb2,0x70,0xb0,0xe0,0x2e,0x14,0x13,0x09,0xc2,0x81,0x60,0xa0,0x54,0x28,0x72,0x0a,0x85,0x04,0x41,0x50 +,0x88,0x4c,0x42,0x73,0x08,0x90,0xa6,0xb3,0xcf,0x9f,0xb6,0x4e,0x37,0x74,0x4a,0xd5,0xe2,0xf3,0x55,0xed,0xae,0x73,0x2b,0x2f,0x35,0x27,0xb7,0xbf,0xef,0xa0,0xf5,0xe5 +,0xeb,0xe1,0xca,0x4f,0x3a,0x1a,0xbe,0xf6,0xb9,0xc7,0xd3,0x34,0x0f,0x0b,0xfe,0x56,0x28,0x4f,0xe7,0x03,0xf5,0xe3,0xf1,0x4e,0xa3,0x8b,0x94,0xfe,0x57,0xa9,0x09,0xee +,0x60,0x97,0xf7,0x60,0x25,0x3f,0x03,0xf0,0x83,0xef,0x79,0xfe,0x57,0xc6,0x76,0x2c,0xee,0xee,0x9d,0x14,0x4e,0xed,0x0a,0x3a,0xed,0xb2,0xd1,0xfa,0xd7,0x7a,0xab,0x05 +,0xc2,0x78,0x04,0xe8,0x93,0xc2,0xf2,0xbc,0xc4,0x00,0x5f,0x58,0xb3,0xb8,0xb1,0x34,0x8e,0xec,0x6a,0xea,0xba,0xe5,0x65,0x62,0x6c,0x5a,0x8b,0x5f,0x05,0x01,0x57,0x06 +,0x19,0x89,0xcb,0x7d,0x0b,0x4d,0x38,0xa0,0x80,0x69,0xfa,0xe1,0x22,0x02,0x21,0x62,0x49,0x02,0xe1,0x20,0x14,0x04,0x15,0x0b,0x0a,0x02,0xc2,0x40,0xb0,0x94,0x4e,0x16 +,0x13,0x85,0x42,0xe1,0x40,0xb0,0xd0,0x4a,0x14,0x0a,0x8c,0xc2,0xa1,0x31,0x88,0x4c,0xc2,0x27,0x8e,0x73,0xaf,0x5c,0x1a,0xab,0xdd,0x35,0x5b,0x8a,0xb8,0x97,0xae,0x3b +,0xd5,0xf8,0x5e,0xdc,0x55,0xf3,0xd7,0x5d,0x0c,0xde,0xe7,0x44,0xa3,0x78,0xf4,0xbf,0x0b,0xbc,0x17,0xe0,0x47,0xdd,0xc6,0xcf,0xb9,0xc5,0xe8,0x0d,0xbe,0x68,0xa3,0x65 +,0x49,0xef,0xba,0xa1,0xec,0xdb,0x0c,0x7d,0x77,0xeb,0x9a,0xb8,0xf5,0x7c,0x27,0x29,0xef,0x4a,0x46,0xbb,0x8b,0x72,0x36,0x06,0xe1,0x1c,0x67,0x7a,0x24,0x77,0xa1,0x27 +,0xb7,0xc8,0x0f,0xb2,0xf7,0x48,0x26,0xf8,0x39,0x9d,0xee,0x4d,0xf5,0x58,0x77,0x37,0x6c,0x7c,0x12,0xe2,0x0e,0x27,0x90,0x00,0xb5,0x38,0xf9,0x00,0x7a,0xe3,0xd7,0x24 +,0x00,0x78,0x02,0x1e,0xb5,0x54,0x2f,0xe1,0xfb,0x44,0xf1,0x97,0x3b,0xc7,0xd6,0x11,0x47,0x3a,0x38,0xe1,0xee,0x89,0xf7,0xff,0xf6,0x0f,0x5b,0xdc,0xa1,0x2c,0x48,0x07 +,0xaf,0x61,0xde,0x1e,0xfa,0xb1,0x41,0x43,0xdd,0xa9,0x00,0x08,0x15,0x03,0x80,0xff,0xf1,0x50,0x80,0x2e,0xbf,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xbf,0xbc,0xb1,0x70 +,0xb0,0xe0,0x44,0x15,0x0a,0x05,0x82,0x82,0x50,0xa0,0x48,0x2c,0x14,0x19,0x09,0x02,0x43,0x10,0x90,0x44,0x2a,0x21,0x68,0xca,0xf3,0xae,0x69,0x24,0xa5,0x5d,0x0d,0x64 +,0x9d,0x56,0x7d,0xeb,0x9d,0xb2,0xef,0xbb,0x9a,0xbf,0xf1,0xd0,0x7a,0xef,0xf3,0xe1,0x81,0x7f,0x48,0x72,0x3a,0x08,0x6f,0x7c,0x74,0x26,0xa2,0xd0,0x9e,0xee,0x87,0xf4 +,0x1f,0x1d,0xce,0xd2,0xdc,0x7f,0xdb,0x67,0xe6,0x12,0xf5,0x3c,0x92,0x9f,0x62,0x55,0x5c,0x6e,0xce,0x7f,0xb7,0x1f,0x6e,0x3a,0x34,0xe3,0x99,0xe3,0x63,0x3b,0x31,0x85 +,0x5d,0xcb,0x18,0x5d,0xd5,0x8c,0x95,0xd1,0x46,0x2c,0x49,0xd2,0xa9,0x69,0xc8,0xe8,0x40,0x1e,0x20,0x07,0x80,0x00,0x40,0x91,0xcf,0x2d,0xe6,0x14,0x88,0x23,0x00,0xf0 +,0x76,0xb9,0x44,0xe2,0x6f,0x04,0x2b,0xbd,0x16,0x6c,0x08,0xc7,0x5d,0x82,0xab,0x2e,0x90,0x5e,0x52,0x05,0xe8,0x58,0x0e,0x91,0x2a,0x02,0x71,0x02,0xc1,0x40,0xb1,0x50 +,0x4c,0x15,0x0b,0x85,0x82,0x81,0x50,0xb0,0x50,0x6a,0x14,0x0a,0x88,0xc2,0x81,0x50,0x88,0x4c,0x22,0x15,0x09,0x85,0x42,0x63,0x50,0x89,0x9f,0xb5,0xf3,0x2a,0xba,0xac +,0xb9,0xbd,0x73,0xaa,0x54,0x95,0x2a,0x5f,0x5f,0x7f,0xdb,0xf5,0xf7,0xcc,0x8d,0x6e,0xa3,0xf9,0xf6,0xe8,0x7c,0xc3,0x7b,0xf3,0x7f,0x52,0xcd,0xdd,0xa7,0x77,0xc4,0xcf +,0x8f,0x35,0xff,0x7c,0x81,0xce,0xac,0x5b,0xc1,0xb7,0xc9,0xb8,0xf3,0xe5,0x46,0xd3,0xfe,0xfe,0x79,0xf0,0x50,0x1d,0xbc,0x3f,0xf3,0xfc,0x07,0xb7,0x87,0xfe,0xef,0xdd +,0xbf,0xb3,0xff,0xcb,0xdf,0x70,0xe2,0xfa,0xf9,0x7f,0xbf,0xf1,0x2f,0xff,0x93,0xb3,0x9f,0x12,0x3e,0x1f,0x23,0x85,0x71,0xec,0x70,0xaf,0xf3,0xbb,0xff,0xfd,0x11,0x2b +,0xc1,0xf3,0x3e,0x6b,0xef,0x4b,0x99,0x67,0x8a,0x98,0xf6,0x03,0xbc,0x7f,0xec,0x3d,0xdd,0x62,0x45,0x8e,0x40,0xf1,0xb0,0x8a,0xc9,0x4f,0x74,0x25,0xd4,0xa8,0x1c,0xf0 +,0x26,0x21,0x63,0x37,0xef,0x5e,0xf7,0x49,0x80,0x97,0xec,0x83,0xb9,0x9e,0x8b,0x07,0x05,0x2f,0x83,0x82,0x76,0x5a,0x51,0x52,0xcb,0xb3,0x9b,0x17,0xe9,0xc4,0x28,0x15 +,0x08,0x81,0x00,0x38,0xff,0xf1,0x50,0x80,0x29,0x9f,0xfc,0x21,0x2a,0xcf,0xcf,0xb9,0xff,0xff,0x8d,0xb0,0x61,0x28,0x58,0x30,0x24,0x61,0x05,0x02,0x42,0x50,0x90,0x86 +,0x4e,0xf8,0xdd,0x75,0xaa,0xcc,0xeb,0x15,0xc6,0xf8,0xf1,0x6b,0x6a,0x9a,0xa7,0x15,0x4a,0x96,0xee,0x3a,0x9e,0x7e,0x01,0x77,0x4f,0xef,0x7b,0xe3,0xfd,0x87,0xa7,0xf8 +,0x03,0xd2,0xd6,0x1a,0x9b,0x46,0x04,0xfa,0x3b,0xba,0x35,0xfd,0x63,0x99,0x18,0x97,0x9d,0xf8,0xc1,0x1b,0x10,0xb1,0xa0,0xfc,0xaf,0xaf,0xf9,0xd2,0xda,0x3e,0xfd,0xab +,0xf5,0x59,0xcb,0x71,0xb8,0xa7,0xbb,0x8a,0x1b,0x6d,0x7d,0x62,0x85,0x33,0x49,0x6e,0x2d,0x49,0x92,0x61,0xef,0x7e,0x8b,0x66,0x27,0x19,0xa5,0x05,0x03,0x02,0x29,0x60 +,0x41,0x44,0x44,0xac,0x95,0x0c,0x80,0x12,0xc3,0x15,0x49,0x95,0x02,0x91,0x0e,0x18,0x6c,0xa2,0x91,0x80,0xdd,0x59,0x29,0xd0,0x88,0xc0,0x08,0xde,0x4a,0x00,0x99,0x00 +,0x14,0xc8,0x16,0x19,0x85,0x82,0xe1,0x61,0x20,0x54,0x4c,0x14,0x0b,0x05,0x03,0x01,0x40,0xb0,0x50,0x2c,0x14,0x21,0x04,0xc6,0x26,0x31,0x09,0x99,0x94,0xc9,0xd7,0x3a +,0xbc,0x61,0xbb,0x2e,0xae,0x54,0xe3,0xae,0x4a,0xab,0xab,0xca,0xad,0x7d,0xdc,0x0d,0x7b,0xb8,0x78,0x46,0x81,0xfd,0x47,0x66,0x7e,0xdc,0xc7,0x1d,0x45,0xfe,0x4f,0x09 +,0xdb,0xbc,0xe9,0xde,0xf4,0x07,0xd6,0xf7,0x8a,0x1f,0x81,0xfd,0x88,0x1a,0x22,0x24,0x68,0xfe,0x52,0x1b,0xa5,0xba,0xce,0x76,0xa1,0x7f,0xbd,0xf5,0xa8,0x5c,0x94,0x4f +,0x42,0x4e,0x1c,0x58,0x5f,0xda,0xd7,0xef,0x6c,0xda,0x6b,0x07,0xf1,0x38,0x76,0x43,0xf6,0xca,0xb9,0xaa,0xe3,0x9e,0x35,0xeb,0x4a,0xfe,0xe8,0xf7,0x37,0x02,0x7d,0xe8 +,0x7b,0x46,0x48,0xbc,0xb0,0x11,0x72,0x58,0xdd,0x48,0xae,0x4a,0x3a,0x44,0x16,0xbe,0x4e,0x13,0x53,0x02,0x28,0x48,0xb4,0xca,0xc9,0x21,0x2f,0xb2,0x90,0x61,0x1d,0xf9 +,0x56,0xb9,0x44,0x78,0x52,0x88,0x2b,0x56,0x46,0x09,0x05,0x40,0x98,0x08,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2e,0xdf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x54,0x26,0x86,0x54 +,0x9a,0x14,0xe0,0x92,0x43,0x5a,0x08,0xed,0x19,0xf3,0x7e,0x47,0xbc,0xaa,0xfe,0x54,0xea,0x23,0x88,0x96,0xfe,0xb4,0xe6,0x02,0x99,0x40,0xb7,0x53,0x4c,0x82,0x6f,0x27 +,0xa6,0x88,0x92,0x96,0xb9,0xd5,0x0e,0x59,0x93,0x2d,0x92,0xf8,0x52,0xad,0xae,0xa6,0xae,0xbb,0xea,0x2a,0xea,0xdd,0x47,0x90,0x11,0x2b,0x48,0x52,0x7d,0x12,0x12,0x8c +,0x61,0xf9,0x94,0x84,0x1c,0x20,0x2b,0x83,0x08,0x10,0x35,0x0a,0x52,0x80,0x70,0xbf,0x82,0xe7,0xa8,0x72,0x5a,0xe9,0x0b,0xaf,0x07,0x1b,0xee,0x7f,0xe6,0x1f,0xff,0x3f +,0xff,0xd5,0x81,0x20,0x80,0x04,0xb8,0xf4,0xef,0x7e,0xae,0xae,0xfc,0x06,0x85,0xd4,0x2e,0x70,0x0a,0xfe,0x03,0xea,0x1c,0x1f,0xc5,0xcb,0xf7,0x29,0xb3,0x32,0x94,0x49 +,0x69,0xd5,0x23,0xce,0x3b,0x08,0x79,0xcd,0x61,0x7e,0x35,0x9a,0xd2,0x12,0x01,0xc6,0x75,0xef,0x60,0x44,0x4c,0x40,0x40,0x4c,0x5e,0x06,0x18,0x45,0x41,0x09,0xa2,0x15 +,0x28,0x88,0x99,0x4a,0xab,0x97,0x14,0xe8,0x11,0x4c,0x7a,0xe3,0xc5,0xb1,0xda,0x31,0xf8,0xc1,0x60,0x9f,0x98,0x9c,0x56,0x69,0x9d,0x18,0xeb,0xb4,0x80,0x38,0x26,0x1d +,0x94,0xf4,0x37,0x79,0xfc,0x76,0x61,0xca,0x25,0xe5,0xe5,0x2e,0xbe,0xc0,0xd7,0xdd,0xed,0xbb,0x8a,0x78,0xfe,0xdf,0x7b,0x68,0xb6,0xdc,0x65,0xfe,0x3a,0xf5,0x73,0x76 +,0x75,0x6c,0xda,0xe1,0xd8,0x9b,0xfb,0xb0,0xec,0xe4,0x5c,0x9d,0xb8,0x68,0x25,0xa7,0x9d,0xa5,0xdf,0xbb,0x3a,0x26,0xa4,0xe2,0x63,0x47,0x04,0xdb,0x2c,0x20,0xb5,0x20 +,0xed,0x42,0x33,0x73,0xd2,0x36,0x1c,0xb8,0x33,0xb7,0x67,0xaa,0xf1,0x3f,0x25,0xc7,0x10,0xae,0xcd,0xc6,0xf1,0xbb,0x6c,0xb8,0x96,0x2f,0x55,0x31,0xf6,0xf7,0xcf,0x56 +,0xbb,0xa7,0x27,0xe5,0xab,0x7c,0xe8,0xda,0xab,0xcf,0x7a,0xdc,0x67,0xb9,0x6c,0x3a,0x26,0xcd,0x0d,0x7e,0x8e,0xe8,0x1e,0xd6,0x32,0x3a,0x19,0xe4,0x36,0xe0,0x93,0x51 +,0xe2,0x14,0xca,0x16,0x7c,0x18,0x7a,0xfd,0xa1,0xd0,0x60,0xb7,0xdd,0xbb,0x68,0xea,0x81,0x78,0xb8,0x3e,0x2e,0xe9,0x77,0xea,0x93,0xa9,0x3c,0x43,0x18,0xec,0x46,0x11 +,0x8c,0x62,0x1e,0x28,0xd4,0x1c,0xff,0xf1,0x50,0x80,0x2d,0x7f,0xfc,0x21,0x6a,0xcf,0xff,0xff,0xff,0xff,0xff,0xb6,0x80,0xb1,0x10,0x6c,0x24,0x0b,0x05,0x06,0x41,0x40 +,0xb0,0x88,0x48,0x15,0x09,0x05,0x02,0x41,0x50,0x90,0x45,0xee,0x3b,0xd3,0xaa,0xad,0xb8,0x55,0xd3,0x38,0xdd,0xde,0x12,0x10,0x94,0x97,0x77,0x97,0x7c,0x74,0x10,0xd7 +,0xff,0x3a,0xfd,0xb8,0x7b,0xde,0x4f,0x6f,0x2b,0xde,0x79,0xcd,0xbd,0xdd,0x85,0xaa,0x42,0x38,0x09,0x97,0xdf,0x58,0xd2,0x15,0x3c,0x8f,0x03,0xfb,0xbb,0xbf,0xdc,0xe9 +,0x74,0x8a,0xb7,0xfb,0xa4,0x41,0x38,0xf6,0x83,0x0a,0x59,0xe2,0x07,0xdc,0xc9,0x81,0x9c,0x32,0xe0,0xa6,0xe0,0xcd,0xdf,0x86,0xbe,0x4b,0x9e,0x28,0xd0,0xce,0x62,0xc9 +,0x08,0xcf,0x02,0x53,0x2d,0x2f,0xac,0x81,0xd6,0xb4,0x5c,0xa9,0xc2,0x2e,0x6a,0x93,0x62,0x8b,0x8a,0x89,0x16,0xa4,0x63,0x3a,0x41,0x8e,0x63,0x52,0x0a,0xa9,0x5a,0xc7 +,0x89,0x11,0x32,0x87,0x09,0xa6,0x10,0x05,0x26,0xb2,0x00,0x1b,0x02,0x81,0x41,0x60,0x28,0x02,0xa4,0xc2,0x81,0x50,0xb0,0xdc,0x26,0x16,0x0a,0x15,0x82,0x81,0x61,0xa0 +,0x54,0x46,0x15,0x09,0x85,0x42,0x81,0x20,0x98,0x48,0x26,0x45,0x09,0x88,0x4c,0x66,0x4c,0xe2,0x9f,0x7f,0x7a,0x8c,0xbc,0xba,0x8a,0x8b,0xa9,0xbd,0x3a,0xdd,0xeb,0x69 +,0x52,0xf8,0xce,0x07,0xf8,0x7f,0x42,0xfa,0x70,0xf0,0xf4,0x51,0xe1,0x8f,0x62,0xfd,0x56,0x8b,0xf4,0x0e,0x8d,0xe2,0x1f,0xfb,0x73,0x6f,0x03,0xed,0x7f,0xe4,0xec,0xa7 +,0x4d,0x37,0xf8,0x1f,0x80,0x2c,0xc3,0x80,0x8e,0x23,0x6f,0xab,0x3e,0xaa,0xae,0x10,0xf7,0x7f,0x6f,0x41,0xc7,0xe9,0xb7,0x1e,0x4f,0x93,0xa1,0xd2,0xff,0x17,0x7d,0xff +,0xb8,0xe1,0xf2,0xfa,0x39,0x1d,0x5c,0x7c,0x0e,0xfb,0xdf,0x9a,0x5e,0x9a,0xc5,0xba,0x98,0xe7,0xb8,0x74,0xf4,0x20,0xf9,0xe7,0xf2,0x5a,0x42,0xfa,0x8c,0x7e,0xc1,0x27 +,0x27,0xe6,0x68,0x20,0x0c,0xcb,0x6f,0xbb,0x0f,0x75,0x21,0xff,0x43,0x28,0x21,0xdd,0x19,0xbf,0x14,0x15,0x07,0xbf,0x38,0x89,0x0e,0x43,0x62,0x67,0x1c,0x5f,0xc9,0x28 +,0x1d,0xc4,0x69,0x36,0xb9,0xa3,0x11,0x60,0x80,0x85,0x82,0xdb,0x04,0xa4,0x06,0xa0,0x38,0xff,0xf1,0x50,0x80,0x2f,0xff,0xfc,0x21,0x0a,0xcf,0xef,0xb7,0xff,0xff,0xfc +,0xb4,0x60,0xc0,0x58,0x8a,0x14,0x0b,0x05,0xc2,0xa1,0x60,0xa0,0xd8,0x6e,0x14,0x0a,0x85,0x04,0xa1,0x21,0x18,0x48,0x42,0x72,0x0a,0x84,0xc2,0x24,0x57,0x5b,0x74,0xa9 +,0xe3,0xac,0xeb,0x6c,0xad,0x54,0xd6,0xda,0xdb,0x5b,0x97,0x52,0x18,0xfb,0xdf,0x3e,0x6a,0x0d,0x78,0x69,0x68,0x7d,0x5f,0xbe,0x29,0xe1,0xf8,0x27,0x5e,0xd7,0x57,0xcb +,0xbd,0xaf,0x3a,0xea,0x42,0x8f,0x1e,0x7c,0x70,0x8e,0xd7,0x5b,0x46,0x17,0x1b,0x9e,0x3c,0x41,0x30,0x57,0x35,0xf3,0xfa,0x5d,0x05,0x62,0xa5,0xf3,0xf2,0x0e,0x51,0xd3 +,0x29,0x3f,0x67,0x2d,0xba,0xe8,0xe3,0xa0,0x6e,0x7c,0x62,0x75,0x34,0x89,0xbf,0xa7,0xfc,0x65,0x77,0xf5,0x16,0xc1,0xf2,0x79,0xd4,0x9e,0xbb,0x3d,0xfe,0xf2,0x0b,0x9c +,0x8a,0x75,0xb1,0xf4,0x32,0xb5,0xc3,0xde,0xaf,0x51,0xce,0x6d,0x1c,0x18,0x55,0xf1,0xa2,0x90,0x46,0xec,0x5b,0x67,0x05,0x2f,0x54,0x18,0x9f,0x8a,0x15,0x45,0x18,0xbf +,0x2b,0xd0,0x2d,0x34,0x46,0xb4,0xe1,0xe4,0x00,0x00,0xf7,0x40,0xac,0xc2,0xe9,0x00,0x2e,0x9d,0x10,0x01,0x42,0x82,0x60,0xc0,0x50,0x50,0x16,0x1a,0x85,0x02,0xc1,0x20 +,0xa0,0x94,0x28,0x25,0x12,0x04,0xc2,0xa2,0x40,0xa8,0x5c,0x2a,0x33,0x20,0xa1,0x5e,0xb9,0x9a,0xf1,0xe7,0x33,0xcd,0xf8,0xf3,0xe2,0xd5,0x0c,0x85,0x71,0x37,0x35,0x52 +,0xaf,0xcd,0xef,0x5b,0xba,0xfb,0x8f,0x13,0xc6,0xd1,0xfa,0xd0,0x0b,0x52,0xec,0xbd,0xe8,0x36,0xcf,0x36,0xbf,0xa4,0x6b,0xc2,0x5c,0xe8,0xbc,0x97,0xf7,0x06,0x1e,0x3e +,0x8e,0x9f,0xb7,0xfa,0x04,0xf9,0xf6,0x3c,0x5f,0x67,0xed,0x8a,0xfe,0x13,0xdf,0xbf,0x8a,0x9c,0x78,0xfd,0x8a,0x4f,0xff,0x9a,0x5e,0xbe,0x36,0xff,0x1f,0xfb,0xef,0x5c +,0xe5,0xd2,0xf8,0x63,0x8c,0xf2,0x87,0x2e,0x4f,0x9b,0x89,0xfe,0xbe,0x0e,0xda,0xbf,0x67,0x57,0x9b,0x91,0x21,0xe6,0x9d,0xde,0x4f,0x28,0x00,0xe2,0xaa,0x44,0x27,0x81 +,0xc2,0xa6,0x38,0x8a,0x39,0x87,0x20,0x23,0xd6,0x72,0x0d,0xfb,0x04,0xab,0xfe,0xdd,0x27,0x70,0x82,0x7d,0xfc,0xfa,0xf1,0x4d,0xeb,0x83,0xfa,0x83,0xd6,0x82,0x62,0xe0 +,0x58,0xaa,0xe5,0x85,0xc2,0x00,0x30,0x56,0x2a,0x94,0x58,0x44,0x51,0x1b,0x81,0xc0,0xff,0xf1,0x50,0x80,0x32,0x3f,0xfc,0x21,0x0a,0xcf,0x7f,0xef,0x7f,0x7f,0xfb,0xb4 +,0x62,0x18,0x58,0x28,0x26,0x12,0x86,0x02,0x82,0x60,0x90,0x58,0x28,0x15,0x0a,0x09,0x44,0x82,0x50,0xa0,0x48,0x26,0x11,0x31,0x8c,0x4a,0x5d,0x4f,0x3e,0x2e,0xab,0x8e +,0x78,0xad,0xf9,0xe6,0x55,0x69,0x31,0x74,0xd6,0xf5,0x54,0x75,0x89,0xc3,0xad,0x0f,0x3c,0x9c,0xbb,0xbb,0xad,0xfc,0x51,0xfc,0x21,0xdb,0xfe,0xce,0x30,0xff,0xaf,0x29 +,0xfc,0x9c,0xec,0x43,0x57,0xe1,0x2e,0xb3,0xab,0xfc,0x5f,0x80,0xd5,0x1d,0x75,0x97,0x79,0x30,0x15,0x2d,0xaf,0xfe,0xe1,0x7b,0xbf,0x4e,0xa7,0xff,0x45,0x6f,0x82,0x6f +,0xee,0xb8,0x85,0x35,0xc5,0xe0,0xcd,0x88,0x8f,0xe2,0x87,0x44,0x71,0x0a,0x3f,0x44,0xea,0x67,0xc4,0xd2,0x22,0xff,0x2c,0xb2,0xbe,0xc7,0xb9,0x41,0xca,0xa1,0xd7,0x0d +,0x2b,0xac,0xf6,0x9c,0x5f,0x6e,0x13,0xc3,0x65,0xef,0x2c,0x66,0xdb,0xca,0xb4,0xe7,0x4b,0x60,0xa7,0x3d,0x27,0x5d,0x6a,0xc2,0x52,0x64,0xfd,0xdb,0xef,0x12,0x77,0xab +,0x45,0x49,0x16,0x7b,0xa1,0x54,0x9d,0xe4,0x21,0xeb,0x18,0xc9,0x5d,0xb7,0x32,0x81,0x72,0x22,0x65,0x80,0xa0,0x80,0x09,0xf2,0x0a,0x05,0x8a,0x41,0x41,0xb0,0x50,0x4c +,0x24,0x0b,0x09,0x02,0x61,0x41,0x28,0x5c,0x2a,0x26,0x0a,0x84,0xc2,0x81,0x32,0x28,0x44,0x26,0x21,0x09,0x84,0x44,0xfb,0x73,0x57,0x7b,0xe3,0x57,0xce,0xea,0xf2,0x57 +,0x9f,0x0d,0x62,0x45,0x55,0xae,0xaf,0x5b,0xeb,0xcf,0xbc,0xc9,0xd7,0x43,0xbb,0xf4,0x35,0x7b,0xa8,0xf5,0xbf,0xb7,0xdb,0x6e,0x86,0xf9,0xf9,0x3b,0x9f,0x44,0x26,0xe2 +,0x5d,0x55,0xbe,0xa9,0xfa,0x48,0xbc,0xc3,0x55,0xc5,0x37,0x9c,0x80,0x75,0xd4,0x57,0xaa,0x1b,0xcd,0xfb,0x54,0x07,0x55,0x1f,0xef,0xf8,0x6f,0xad,0xfd,0xe3,0xf3,0x7f +,0xf0,0x7d,0x5e,0xdf,0x0f,0xc7,0xf7,0x7d,0x2f,0xe0,0xf3,0x03,0xe7,0xcb,0xee,0x1d,0x43,0xce,0x00,0x7c,0xfd,0x9e,0x3d,0x14,0xe0,0x73,0x36,0xac,0xf5,0x38,0xd9,0x6c +,0x5e,0x94,0x09,0x08,0x39,0x85,0x9c,0x9c,0x27,0x93,0x88,0x77,0xbf,0xc6,0x3f,0xd8,0x0e,0xf7,0x73,0x82,0x41,0x1f,0x54,0xff,0x1f,0xf2,0x3b,0x67,0x06,0x81,0x31,0xfe +,0x0d,0x05,0xfb,0x87,0xbb,0xdd,0x0c,0xae,0xe7,0xb8,0x1e,0x60,0x00,0x46,0x62,0x4a,0x3b,0x83,0xb8,0x48,0x69,0x9e,0xea,0x10,0xe0,0x40,0x87,0xe4,0x00,0x3a,0x09,0x48 +,0x0e,0xff,0xf1,0x50,0x80,0x33,0x9f,0xfc,0x21,0x0a,0xcf,0xdf,0xff,0xde,0xff,0xed,0xb1,0x40,0xc0,0x58,0x28,0x13,0x0a,0x04,0x82,0x81,0x60,0xb8,0x50,0x2e,0x14,0x13 +,0x85,0x02,0xc1,0x40,0xb8,0x48,0x2a,0x14,0x12,0x85,0x04,0x41,0x30,0xa8,0x48,0x22,0x63,0x10,0x95,0xbd,0x63,0xce,0x6b,0x5f,0xa7,0xb7,0x37,0xae,0xf8,0xcb,0xcd,0x31 +,0x75,0x53,0x55,0x44,0xd6,0x5c,0x66,0x9c,0x74,0x3f,0x91,0x47,0x43,0xd8,0x5f,0xf8,0xff,0x0f,0x99,0x7c,0xb8,0x8e,0xff,0x8f,0x7d,0x3d,0x6f,0x1b,0x8b,0x7c,0xbf,0x5f +,0x3d,0xf2,0x7b,0x1f,0x8b,0x2b,0xf0,0x0c,0x36,0x98,0x1a,0x5c,0xdf,0x80,0xf4,0xd0,0x8a,0x7d,0x5b,0x37,0x12,0x71,0x93,0x5b,0x8d,0x25,0x7b,0x03,0x29,0x84,0x44,0xea +,0x06,0x3e,0x26,0xb0,0xed,0x4c,0x33,0xed,0xa2,0x72,0x3a,0x8c,0xd5,0x87,0x01,0x85,0x3f,0xbc,0xb6,0x26,0xf6,0x14,0xe4,0xb8,0x5c,0x13,0x4b,0x13,0x24,0x91,0x8d,0xa3 +,0xdb,0x3b,0xca,0x2d,0x8b,0x1d,0xa5,0x5a,0x74,0xb6,0x2f,0x85,0x6f,0x53,0x6a,0x55,0x88,0x9a,0x65,0x68,0x46,0x6d,0xc8,0x42,0x28,0x8f,0x5d,0x34,0x7b,0xe0,0x41,0xb0 +,0xaa,0xa9,0xa3,0x15,0xa2,0xee,0x00,0x2a,0xa8,0x15,0x4a,0x14,0x0c,0x05,0x83,0x01,0x60,0xa0,0x54,0x28,0x15,0x0a,0x05,0x82,0x81,0x20,0xb8,0x50,0x2a,0x14,0x13,0x05 +,0x02,0xc1,0x40,0xb8,0x50,0x2a,0x16,0x09,0x85,0x44,0x64,0x50,0x98,0xd4,0x22,0x47,0xc7,0xe9,0xa7,0x3e,0x7c,0xf3,0xdf,0x1c,0xdf,0xb7,0xda,0xe6,0xec,0xa9,0x7b,0xbd +,0xf1,0x52,0x54,0x95,0x7c,0x27,0x3e,0xd3,0x80,0xe9,0xd7,0x45,0x78,0xbe,0xd0,0x2d,0x07,0xd3,0x5f,0x2d,0xe8,0x72,0x2f,0x53,0x48,0x85,0x50,0x11,0xa7,0xc7,0xf2,0x95 +,0xa7,0xde,0xa5,0xf9,0x4e,0x5a,0xfa,0x8d,0x47,0xfa,0x28,0xb4,0x1f,0xb7,0xfb,0x4b,0x76,0xca,0x14,0x3f,0xd9,0x80,0x25,0x7e,0x13,0xdb,0x55,0xf5,0x55,0x3f,0xe9,0x3f +,0x6d,0x9a,0xd1,0xbe,0x15,0xc5,0xf3,0x6e,0x5e,0xec,0x5c,0x30,0x25,0xf2,0x47,0x34,0x72,0xf9,0xa2,0xe7,0x50,0xad,0x18,0x00,0xa5,0x5e,0x72,0xfe,0x9d,0x04,0xff,0xc5 +,0x53,0x0a,0xea,0x70,0x59,0x76,0x8d,0xc7,0x30,0xe0,0xc2,0xc9,0x9e,0xea,0x7a,0xbf,0xfe,0xaf,0xad,0xd6,0xf5,0xa6,0xe4,0x9f,0xb7,0xec,0x91,0xf7,0xa3,0xcd,0x46,0x57 +,0xc2,0x2d,0x39,0xa1,0xcf,0x9a,0x5a,0x53,0xbb,0x45,0x90,0x81,0xdc,0x54,0x77,0xc5,0x40,0x1e,0x00,0x08,0xd5,0x72,0x05,0x01,0x28,0x89,0x0a,0x00,0xe0,0xff,0xf1,0x50 +,0x80,0x32,0x5f,0xfc,0x21,0x0a,0xcf,0xef,0xf7,0xdb,0xdf,0xff,0xb1,0x62,0xa0,0x94,0x2c,0x23,0x0b,0x85,0x04,0xe1,0x61,0x28,0x58,0x2a,0x14,0x11,0x05,0x02,0x41,0x40 +,0xa8,0x48,0x22,0x15,0x08,0xb5,0xbf,0x3d,0xcb,0xbd,0x77,0x57,0x97,0x59,0x6d,0x54,0x95,0x91,0x57,0x4b,0x4b,0xa8,0xab,0xbb,0xaf,0x3e,0xc2,0xfd,0x72,0x7a,0x7d,0x79 +,0xf6,0x50,0x3b,0x39,0xe6,0x8d,0x74,0x51,0xcb,0xa2,0x53,0xfe,0x11,0xbf,0xe0,0x1d,0xfd,0x9f,0x79,0xb6,0xfc,0xed,0xb0,0x3a,0xb9,0x0a,0xeb,0x31,0x1e,0x7c,0x7b,0xb4 +,0x71,0x12,0xa8,0x1b,0x9f,0x4b,0x1f,0xe9,0x7d,0xf1,0xb7,0xd0,0xd4,0xdd,0xdb,0x5c,0x7e,0xbc,0xed,0xe1,0x36,0xbf,0x1e,0x6f,0xd5,0x35,0x79,0x37,0xe8,0x0a,0xa0,0x5f +,0xec,0x8c,0xcd,0xe2,0xd2,0x26,0x60,0x4a,0xa5,0xcb,0x5f,0x7b,0x5b,0x9e,0x6b,0x38,0x2a,0x0a,0x69,0x07,0x28,0x46,0xf7,0x70,0x46,0x75,0xa5,0xe9,0x5b,0x34,0xcd,0xfe +,0x86,0x2d,0xd1,0x90,0xdd,0x22,0xd4,0xba,0x11,0xba,0x56,0x59,0x2a,0x25,0x1a,0x92,0x3c,0x83,0xb9,0x3d,0x42,0x73,0x20,0x06,0xa9,0x80,0x16,0x20,0x05,0x52,0x0a,0x02 +,0xc3,0x70,0xa8,0x50,0x46,0x17,0x09,0x85,0x02,0xe1,0x30,0xa8,0x50,0x2e,0x14,0x2b,0x05,0x4a,0x41,0x31,0x88,0x8c,0x42,0x13,0x08,0x8d,0xfb,0xff,0x6f,0x8f,0x13,0x3e +,0x39,0xf8,0xef,0xbd,0x65,0x64,0xad,0x54,0xc4,0xad,0x57,0x19,0xb9,0xa2,0x9d,0x73,0xab,0xaf,0x8e,0x07,0x2b,0xfa,0xfa,0x7a,0x8f,0x46,0x77,0xe9,0xe3,0x5f,0x7e,0xeb +,0x6d,0xdc,0x8b,0xfc,0x6d,0x8b,0xf3,0x79,0x3a,0xfe,0x22,0xff,0x85,0x10,0xff,0x0f,0xe9,0xb1,0xf7,0xc3,0xec,0xba,0x1f,0xfd,0x5d,0x91,0xbf,0x66,0x9f,0x89,0xf8,0xdd +,0xef,0xff,0xff,0xf7,0xe7,0xd9,0xe6,0xe5,0xff,0xf2,0x3c,0x0b,0xdd,0x7f,0x4c,0x4f,0xdc,0x4f,0xec,0xdd,0x5c,0xeb,0x3a,0x55,0x4a,0x37,0x84,0x3e,0x6e,0xfe,0x7c,0x7e +,0x37,0xc7,0x99,0xdc,0xe3,0xc3,0x9b,0x9f,0x97,0x67,0x07,0x04,0x16,0x73,0x5d,0xb9,0x47,0x62,0x52,0x2f,0xd1,0x6e,0x17,0x73,0xcd,0x6e,0x9e,0x5c,0x1c,0x2e,0xac,0xdc +,0x2e,0xd4,0x58,0xf8,0x7a,0xb7,0x3b,0xa3,0x47,0xff,0xcc,0xe4,0x8f,0x96,0x42,0x6e,0xe3,0x6f,0x89,0x5a,0x4d,0x18,0x9c,0xeb,0x4a,0x87,0x7f,0xb9,0x63,0xcd,0x9b,0xf1 +,0xae,0x77,0xdc,0x27,0x57,0x85,0x00,0xad,0x74,0xdc,0x2a,0x24,0x82,0xc0,0x38,0xff,0xf1,0x50,0x80,0x32,0xff,0xfc,0x21,0x0a,0xcf,0xcf,0xff,0xff,0x5f,0xbf,0xb1,0x60 +,0xb8,0x58,0x30,0x16,0x0a,0x0d,0x82,0xe1,0x40,0xa8,0x50,0x30,0x17,0x0a,0x85,0x82,0xa4,0x40,0x90,0x58,0x2a,0x43,0x09,0x08,0xc2,0x21,0x30,0x88,0x4c,0x2a,0x11,0x09 +,0x84,0x48,0x51,0xf1,0xdd,0xce,0xef,0x38,0xa6,0x38,0xdf,0x0d,0xe5,0xc4,0x93,0x9b,0x99,0xc6,0x5f,0x19,0xa9,0xbf,0xe7,0x80,0x9d,0xd5,0xde,0xf9,0x29,0xd2,0x1f,0x2e +,0x3a,0xf3,0x47,0x73,0x79,0xb9,0x79,0x9f,0x6d,0xe4,0x30,0xd7,0xfe,0x70,0x31,0xb8,0x68,0x69,0x7e,0x4c,0x23,0xbd,0xda,0x97,0xb5,0x4b,0xe3,0x1c,0xf8,0x3e,0x1f,0xd5 +,0x5c,0xec,0xf6,0x38,0x9c,0x07,0x0e,0x0b,0xdc,0x31,0xd5,0x1b,0x38,0x2f,0xe7,0xc6,0x1c,0x50,0x4d,0x5e,0x3c,0x35,0x59,0xcb,0x18,0x83,0x97,0x26,0x37,0x54,0x43,0xaf +,0xda,0x9b,0x9c,0x52,0x11,0x0e,0x58,0x71,0x51,0x7c,0x48,0x51,0x18,0xff,0xec,0xaa,0xe7,0x62,0x8e,0xbc,0x10,0x67,0x8e,0x96,0x11,0x1b,0x0b,0x66,0x66,0xaf,0xbb,0x3d +,0x1a,0x21,0xb0,0xa5,0xd4,0x59,0xf6,0xf3,0xac,0xae,0xb5,0x73,0xd4,0xef,0x43,0xe1,0xfa,0xd4,0x00,0x1e,0x20,0x8a,0x8b,0x11,0x1e,0xb7,0xb8,0x09,0x04,0xb6,0x5a,0xa0 +,0x05,0x45,0x00,0xaa,0x40,0xb0,0x60,0x2e,0x14,0x0b,0x06,0x02,0x82,0x50,0x90,0x58,0x28,0x45,0x0b,0x09,0x04,0xa1,0x40,0xa8,0x5c,0x2a,0x73,0x18,0x88,0xc2,0x25,0x37 +,0x75,0x95,0xe5,0x9e,0x7d,0x70,0xdd,0x49,0xb8,0xd6,0x4d,0x6d,0x5a,0xdd,0xb5,0x55,0xf1,0xbc,0xf6,0xf5,0x7f,0xaf,0x03,0xa0,0x6b,0x28,0x35,0x1d,0xfc,0xfe,0x37,0xf0 +,0xba,0x31,0xf8,0x5b,0xf7,0x63,0x9d,0xa8,0x43,0xed,0x49,0xd3,0x7a,0xbb,0x1d,0xab,0x76,0xfe,0xd7,0x55,0x5e,0x3d,0x80,0x4a,0xb8,0x70,0xfd,0x7e,0x2f,0xa6,0xfa,0xcb +,0x91,0x7f,0xf3,0x7f,0xbd,0xaf,0x80,0x71,0xf3,0x1e,0x57,0xef,0x7f,0x1f,0xd1,0xf5,0x0e,0x2e,0x4e,0x7f,0x77,0x18,0xd4,0xd9,0xe5,0x03,0x8f,0x0e,0x0e,0x6b,0x3e,0x12 +,0x80,0xee,0xcf,0x24,0xb9,0xc3,0x87,0xc1,0x5c,0x2c,0xe7,0xc4,0x71,0xbe,0x7c,0xdc,0x81,0x4c,0xfb,0xee,0xb2,0xa5,0x57,0x39,0xe3,0x84,0xf1,0x51,0x7c,0x28,0x84,0xa7 +,0x8e,0x9c,0x81,0xcd,0xcd,0x76,0x14,0xff,0xda,0x27,0x77,0xba,0xb2,0x73,0xb4,0xcb,0xe4,0xef,0x5c,0xb2,0x21,0x05,0x42,0x29,0x3d,0x72,0x22,0x13,0x08,0xd0,0xde,0x96 +,0x7a,0x80,0x0b,0x8b,0x01,0xc0,0xff,0xf1,0x50,0x80,0x32,0x3f,0xfc,0x21,0x0a,0xcf,0x7f,0x07,0xff,0x7f,0xee,0xb1,0x70,0xb0,0x5c,0x30,0x16,0x12,0x09,0x82,0x82,0x60 +,0xa0,0x48,0x2c,0x14,0x0a,0x85,0x04,0xa2,0x40,0x90,0x54,0x48,0x12,0x0a,0x05,0x42,0x61,0x10,0x98,0xc4,0x66,0x11,0x2b,0x25,0x70,0xce,0x3c,0x7b,0x3b,0xe2,0xfb,0xf3 +,0xc8,0x6b,0xbd,0x4a,0xae,0x2a,0xf9,0xe2,0xb5,0xdb,0x8e,0xbb,0xbd,0x7d,0xc1,0xf1,0xba,0xf8,0x78,0xce,0xf8,0x4b,0x5e,0xab,0x7e,0xef,0xfa,0x09,0x7b,0x3f,0xe2,0x7e +,0x3b,0x8f,0x35,0xb1,0xfe,0x18,0xde,0xfe,0x25,0xde,0x8b,0x1e,0xcf,0xf2,0xfd,0x70,0xcf,0x95,0xc7,0x24,0x5b,0x1f,0x0f,0xf3,0xbb,0xe2,0xd7,0x51,0xd2,0xce,0x0a,0xfe +,0xd9,0x1b,0x99,0xff,0x7a,0x9d,0x32,0x97,0xb7,0xb1,0xcd,0x00,0xe9,0xbb,0xb6,0x41,0xaf,0x1e,0x0b,0xc5,0x8b,0xf1,0xfc,0xf6,0x0f,0xe9,0x7a,0x0f,0xcf,0x7a,0xa4,0x2f +,0x3c,0xed,0x93,0x91,0xe7,0xfe,0xc4,0x31,0xad,0x32,0x73,0xf5,0x65,0xae,0x41,0x1e,0xfc,0xaa,0xf6,0x3d,0xba,0x4a,0x3d,0xc1,0xdc,0x2d,0x7b,0x42,0x4e,0x57,0x82,0x36 +,0xc2,0x7f,0x69,0x7e,0xa8,0x03,0xdc,0x40,0x14,0x5d,0x64,0x10,0x80,0x58,0xad,0xd7,0x01,0x61,0x20,0x2a,0x18,0x28,0x16,0x0a,0x09,0x84,0xa1,0x40,0xb0,0x54,0x2c,0x55 +,0x0b,0x85,0x82,0x82,0x56,0x08,0x4c,0x2a,0x13,0x0a,0x88,0x42,0x61,0x11,0x38,0xfb,0x4a,0xe2,0xb8,0xf3,0xf6,0xbd,0xab,0x8e,0x7a,0xad,0xca,0xd5,0x16,0xcd,0x51,0x7f +,0x5e,0xfd,0x56,0xf8,0xe7,0x8f,0xaf,0xb8,0x3e,0x3a,0x3e,0xdf,0x67,0xc8,0x7f,0x9b,0xe6,0xba,0x89,0xcf,0x58,0x6c,0x37,0xb6,0x60,0x2e,0x8e,0xb5,0x4f,0xdd,0xf8,0xd8 +,0x95,0x5f,0xc8,0x7a,0xf5,0x9e,0xb4,0x8f,0xa9,0xc1,0xb6,0x7c,0x2d,0x8d,0x16,0x8e,0xf4,0x2e,0x23,0xff,0x7a,0xfe,0xeb,0xf4,0xdc,0xbc,0x26,0x9c,0x0e,0x1c,0x1f,0x51 +,0xce,0x43,0x83,0x89,0xdb,0xc3,0x84,0x23,0x99,0xf1,0xf8,0xab,0xcc,0x1f,0x77,0x31,0x07,0xdc,0x0f,0x23,0x95,0x11,0x3e,0x1c,0x8c,0xf3,0xe1,0xc9,0x10,0x71,0x07,0xd2 +,0xe3,0x74,0xe2,0xe6,0x1c,0x5b,0x28,0x71,0x07,0x17,0x3b,0x6c,0xf9,0xf0,0xdf,0x27,0x03,0x9c,0x82,0x80,0xb3,0x87,0x33,0x8a,0xda,0x42,0x60,0xee,0x21,0x50,0xf3,0x00 +,0x1d,0xff,0xff,0xec,0x01,0x63,0xdd,0xc8,0x00,0x1e,0x20,0x04,0xe3,0x15,0x91,0xc6,0x7a,0xd5,0x54,0x02,0xe4,0xc0,0xe0,0xff,0xf1,0x50,0x80,0x2f,0x5f,0xfc,0x21,0x0a +,0xcf,0x7e,0xe8,0xfb,0x6f,0xfe,0xb0,0x70,0xb1,0x54,0x30,0x16,0x0a,0x84,0x82,0xc1,0x41,0x30,0x50,0x4e,0x16,0x0b,0x85,0x44,0x61,0x51,0x18,0x48,0x2a,0x12,0x09,0x88 +,0x44,0x61,0x20,0x88,0x4c,0x62,0x13,0x08,0x89,0x95,0xe7,0xc6,0xb8,0xdf,0x8e,0x24,0xba,0xdd,0xdd,0x65,0xc5,0x24,0xce,0x37,0xa9,0xbe,0x2b,0x97,0x5e,0x73,0x9f,0x3c +,0x50,0x78,0x3e,0xce,0x1e,0x71,0x2f,0x3f,0x54,0xa9,0xbf,0xd8,0x06,0x9b,0xf9,0x5f,0xe8,0xfd,0xe7,0x64,0x4d,0x5e,0x87,0x93,0xb8,0x04,0xf6,0x1d,0xa3,0xa8,0x18,0xf8 +,0xed,0x99,0x29,0xbf,0xc7,0x95,0xbe,0x8e,0xe3,0xb6,0xa8,0xf0,0x3e,0x8f,0x02,0xe2,0xbc,0xfe,0x63,0x4f,0x48,0xe5,0x3c,0x48,0xce,0x06,0xb1,0xec,0xa9,0x72,0xb8,0x85 +,0x7b,0x63,0xbe,0xef,0x72,0x5c,0xf8,0xf5,0x21,0xec,0xc4,0x8e,0x11,0xc5,0xc0,0x2c,0x8a,0xbe,0xea,0xcf,0x56,0x3f,0xe5,0x08,0x5e,0xf7,0xf4,0x40,0xf0,0xab,0xd3,0x7c +,0x9b,0x2a,0x3e,0xb5,0x23,0x04,0x76,0x0f,0x04,0x9c,0xa6,0x4c,0x04,0xa0,0x5e,0x9b,0xa7,0x6d,0xd2,0x49,0xf6,0xe0,0x0e,0xf0,0x49,0xdd,0x09,0xdf,0x54,0x41,0xdc,0x10 +,0x01,0x21,0x70,0x2a,0x10,0x2c,0x18,0x13,0x05,0x02,0xa1,0x20,0xa0,0x48,0x28,0x65,0x0a,0x05,0x82,0x81,0x51,0x20,0xd4,0xa6,0x41,0x12,0x84,0xc8,0x22,0x67,0x1f,0xb7 +,0xb6,0xfd,0xbe,0x3f,0x6f,0xaf,0xb6,0xaa,0xf3,0x3d,0xbd,0x49,0x26,0xe2,0x71,0xcf,0x15,0x96,0xe3,0xa7,0x3c,0xf0,0xbd,0x70,0x39,0x41,0xf0,0xad,0xd3,0x7f,0xa4,0x4f +,0x8f,0xfb,0x3b,0xcf,0x79,0x3d,0xfc,0x63,0xf2,0xfe,0x45,0xee,0xd3,0x9a,0xf9,0x14,0xb4,0xb7,0xb4,0x67,0xd9,0x63,0xe2,0xe7,0xc7,0x35,0xd5,0x48,0x54,0xa9,0xf9,0xfe +,0xb9,0xeb,0xc7,0xe4,0xf8,0x03,0xe8,0xe6,0x52,0x97,0xae,0x96,0xac,0xfb,0xa3,0xab,0xd5,0xb1,0x2a,0x9f,0xa3,0xec,0xca,0x39,0x8e,0x6a,0x60,0x78,0x87,0x20,0x27,0x84 +,0xdb,0x80,0x5f,0x99,0xe3,0xc4,0x00,0x39,0x83,0x87,0x80,0x0f,0x10,0x63,0xaf,0xe5,0x14,0x3d,0x87,0x78,0x76,0xbf,0x08,0x84,0x48,0x03,0xbe,0x2c,0x50,0x40,0x58,0x79 +,0x00,0x00,0x7f,0xfd,0x52,0x01,0xee,0x02,0xaf,0x71,0xdc,0x77,0x80,0x50,0x02,0xc0,0x70,0xff,0xf1,0x50,0x80,0x2d,0xff,0xfc,0x21,0x0a,0xcf,0xfe,0xff,0xed,0xef,0xfc +,0xb0,0x62,0xa0,0x58,0x6a,0x14,0x2a,0x90,0xc2,0x82,0x50,0xa0,0x54,0x24,0x24,0x08,0x84,0x84,0x2c,0x66,0xea,0x4e,0x9c,0xcf,0x3c,0xa5,0xe5,0xd2,0xf2,0xa3,0x5c,0xd5 +,0xa4,0x4a,0xa5,0xdd,0xc9,0xd7,0xc0,0x2d,0x7b,0x7b,0xfa,0xfb,0x33,0xfc,0xe3,0xab,0xfa,0xcb,0xf1,0x7f,0xd7,0x53,0x7d,0xc0,0xfe,0x24,0x47,0xf4,0xe8,0xbe,0xc7,0x0f +,0x21,0xe5,0xf7,0x7d,0x6a,0x97,0x67,0x07,0x50,0xe7,0x1d,0x48,0xe4,0x3c,0x7f,0x3a,0x4b,0xc2,0xf9,0x7c,0x4f,0x51,0xd7,0xaf,0x9d,0x63,0xd9,0x66,0x37,0xf9,0x5d,0x28 +,0x5f,0x2c,0xac,0xae,0xae,0x48,0xe4,0x19,0xff,0x51,0x47,0x0d,0x1b,0xe2,0x50,0x48,0x47,0xb5,0x58,0xe3,0x46,0x73,0xad,0x29,0x19,0x2f,0x91,0xe1,0x9c,0xc7,0x0b,0x6e +,0x07,0x88,0xe8,0x5c,0xe1,0x8b,0xe4,0x46,0x74,0x6c,0x25,0xdd,0x68,0x51,0x4d,0x09,0xa3,0xae,0x29,0xb7,0xc2,0xcb,0xb2,0x9a,0x0b,0xa9,0x14,0x55,0x65,0x11,0x26,0x55 +,0x50,0x22,0xb0,0xa8,0x26,0x0b,0x81,0x54,0x82,0x60,0xc0,0x58,0x2a,0x24,0x09,0x05,0x04,0xe1,0x30,0xb8,0x60,0x2c,0x15,0x32,0x05,0xc4,0xa1,0x11,0x18,0x44,0x2a,0x23 +,0x10,0x84,0xc2,0x27,0x57,0xf9,0xff,0xb6,0xa5,0x5f,0xb5,0xfe,0x6d,0xd7,0x88,0xaa,0xbc,0xba,0xe1,0xcf,0xeb,0x5f,0x3f,0x1e,0xfa,0x5e,0x75,0x7e,0xa5,0xaf,0xa1,0xc1 +,0xf1,0x6e,0xaf,0x7e,0x88,0x6f,0xa3,0xe9,0x7a,0x1b,0x74,0x9c,0x4f,0x4e,0x7c,0x0c,0x7a,0x17,0xfc,0xaf,0x4c,0xbe,0x3f,0x8c,0xe5,0x1e,0xdc,0xb9,0xce,0xe1,0xcb,0x9f +,0xcc,0x9e,0x8e,0x8f,0xff,0xb9,0x66,0x0e,0x4e,0x3c,0x1c,0x38,0xb8,0x73,0x3c,0x03,0x87,0x46,0x8b,0xfe,0x17,0xbb,0xde,0x0f,0x38,0x39,0xde,0x7d,0xe0,0x3a,0x8d,0x1e +,0xde,0xce,0xae,0xd9,0x93,0x2e,0x31,0x28,0x14,0xcb,0x6e,0xeb,0xeb,0x4e,0xf5,0x4a,0xe4,0x2a,0x9e,0xc6,0x6e,0xaf,0x82,0xa9,0x29,0x62,0xec,0x81,0xc0,0xe6,0x8f,0x5e +,0x94,0x35,0x13,0x31,0xc5,0xeb,0x95,0x9d,0xad,0x60,0xee,0x87,0xef,0xa0,0x94,0xc0,0x32,0xa7,0x78,0x1d,0xce,0x0b,0x4a,0x65,0xd0,0x63,0x16,0x09,0x05,0x75,0x00,0xe0 +,0xff,0xf1,0x50,0x80,0x2e,0x1f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0x7f,0xd7,0xfc,0xb1,0x60,0xb8,0x60,0x2c,0x34,0x0b,0x05,0x42,0xc1,0x42,0xa8,0x50,0x2c,0x14,0x1a,0x8c +,0x82,0xa1,0x10,0x90,0x84,0xe6,0x11,0x33,0x9d,0x73,0xaf,0x3c,0xfc,0x7e,0x78,0xba,0x4c,0x9a,0xca,0xab,0x52,0x5e,0x4a,0x6b,0x25,0xe5,0x7c,0x73,0xc5,0xda,0xc3,0xef +,0x8e,0xec,0x9d,0x27,0xe3,0x7f,0xe3,0x0e,0x73,0xf2,0xd7,0xd7,0xf7,0x34,0x8e,0x1c,0x05,0x6f,0xed,0xc5,0xcc,0x76,0x42,0xda,0x10,0xef,0x8d,0x28,0x97,0xbc,0xa6,0x0c +,0x5b,0xb8,0x63,0xa5,0x90,0xa7,0xef,0xbd,0xb6,0x9b,0xf4,0xf6,0x58,0x4f,0x1f,0x61,0x13,0x85,0x7a,0x30,0xad,0x9d,0xf9,0xb1,0xed,0x7b,0x04,0x56,0x91,0xe6,0x9a,0x92 +,0xff,0x03,0x06,0x25,0x05,0xa6,0x8f,0x1b,0x9a,0x0a,0xac,0x98,0x4d,0x15,0x4a,0xdd,0x29,0xfc,0x86,0xb5,0x7a,0xfe,0x14,0xef,0x22,0xd7,0x9d,0x5c,0x21,0x62,0x85,0x8f +,0x16,0x31,0x13,0xfb,0xcf,0x3c,0x23,0x90,0x93,0xbe,0x01,0x75,0x60,0xbd,0x97,0x2a,0x2d,0x70,0x0a,0x44,0x2a,0x01,0x30,0x29,0x19,0x2a,0x14,0x32,0x89,0x04,0xc1,0x50 +,0xa0,0x48,0x22,0x55,0x09,0x85,0x02,0x61,0x10,0x98,0x84,0x26,0x11,0x09,0x84,0x46,0xf1,0xb9,0x96,0xf6,0xf5,0xa2,0x4f,0x17,0x78,0x4b,0xeb,0x2e,0x7b,0x4f,0x5e,0xf3 +,0x34,0xea,0xbd,0xb9,0xe7,0x4f,0x6f,0x21,0xf7,0xeb,0xe3,0x36,0xcf,0x40,0xf9,0x26,0xd9,0x76,0x88,0xbb,0x6f,0xad,0x7e,0x4d,0x09,0xad,0xbd,0xde,0x13,0xca,0xe9,0x7d +,0x5e,0x57,0xda,0x7f,0xdf,0xfe,0x8d,0xd7,0xc7,0x83,0x9f,0x1e,0x0f,0x93,0xb7,0xf9,0x3f,0xfe,0xb8,0xc9,0xfb,0xff,0xf3,0x95,0xfc,0xed,0xa8,0x29,0xe1,0xe4,0x1c,0x4a +,0x3c,0x2b,0xf2,0x1b,0x54,0xa7,0xd2,0x3b,0xc8,0xd3,0x55,0xb0,0xf9,0xe8,0x12,0x0f,0xbc,0xb1,0x59,0x32,0xfe,0x77,0xd0,0x45,0xcd,0xf3,0xe7,0xca,0x3a,0x9c,0xe1,0xfb +,0x67,0x0b,0xae,0xfa,0xeb,0xfc,0xa8,0x39,0x10,0xeb,0x65,0xcd,0x4f,0x4e,0x5e,0x50,0xf5,0xfd,0xad,0x6a,0xa7,0xe9,0x77,0x81,0xdf,0x0e,0xff,0xb9,0x41,0xdc,0x0f,0x58 +,0x23,0x2a,0x66,0x32,0x90,0xf8,0x7a,0xe4,0xc1,0x28,0xcf,0x48,0x15,0x88,0x80,0x1c,0xff,0xf1,0x50,0x80,0x2d,0xff,0xfc,0x21,0x0a,0xcf,0xeb,0xed,0x7d,0xff,0xfb,0xb1 +,0x62,0x38,0x50,0x8a,0x14,0x0a,0x85,0x02,0xc2,0x40,0x90,0x58,0x2a,0x14,0x09,0x05,0x02,0xa2,0x40,0xa8,0x48,0x42,0xf7,0x72,0xf2,0xf5,0x4d,0x2b,0x4f,0x16,0xaf,0x3d +,0xdc,0x62,0xea,0x4d,0x65,0xe4,0x38,0xcd,0x6b,0x7f,0x8e,0x07,0x2f,0x2f,0x0f,0xb6,0x1f,0xad,0x3e,0xff,0x6a,0x3f,0xd9,0xa0,0x34,0xef,0x30,0xf7,0x3d,0x08,0x3e,0x46 +,0xf9,0x17,0x4f,0x03,0x1c,0xb4,0x3d,0x88,0x05,0xee,0xdb,0xf1,0x2e,0xc3,0x43,0x5d,0xf4,0x1c,0xd2,0x4d,0xc4,0xa4,0x77,0x6f,0x6c,0xd7,0x52,0xaf,0x4f,0xa2,0x06,0xab +,0x5e,0xc8,0xc4,0xc1,0x7d,0x22,0x8a,0x31,0xc2,0x33,0x56,0x85,0xfa,0xea,0xf1,0x0b,0x59,0x4e,0xc8,0x8a,0x4a,0xdf,0x61,0x25,0xce,0xc8,0xb6,0x73,0xcd,0x2f,0x75,0xd6 +,0x52,0xd5,0x45,0x4c,0xe4,0x9a,0x2a,0x41,0x7c,0x57,0x09,0xb3,0x59,0x31,0x20,0x8e,0xdb,0x89,0xd2,0x11,0x55,0x60,0xb4,0x60,0x0a,0xc0,0x44,0x50,0xa0,0x0a,0xac,0x50 +,0x02,0x20,0x52,0xa8,0x58,0x48,0x16,0x0a,0x05,0x83,0x01,0x70,0x98,0x50,0x6c,0x24,0x13,0x05,0x42,0x81,0x51,0xb8,0x90,0x22,0x13,0x08,0x85,0x42,0x63,0x10,0x99,0xc4 +,0x4d,0xf2,0x57,0x5e,0x7f,0x6f,0x24,0xdc,0xa2,0xf2,0x6b,0x7c,0x3b,0xfd,0xf9,0xd7,0x3b,0xa8,0x9d,0x6e,0xbc,0xef,0x7f,0x5e,0xc1,0xdc,0x7e,0xbe,0x36,0xfc,0x7f,0x72 +,0x7f,0x1f,0x50,0xa1,0xab,0xef,0x2b,0xf4,0x9e,0x5f,0x39,0x5f,0xff,0xdf,0x7f,0xff,0x70,0x8e,0xf7,0xb4,0x35,0xdf,0xdc,0x7f,0xe9,0x9f,0xff,0x0b,0xf3,0x04,0xf0,0xb2 +,0xbe,0xee,0x82,0xe5,0xd9,0xfc,0x17,0x1e,0x1e,0x5c,0x9e,0x23,0xc4,0x3c,0x39,0xf0,0x1c,0x41,0xe6,0x39,0xde,0x43,0xca,0x07,0xfa,0x3d,0xfb,0x69,0x7f,0xdf,0xeb,0x25 +,0xfb,0x1a,0x17,0x1e,0xb4,0xdc,0x2e,0x28,0x70,0xe3,0x61,0xc8,0x11,0xa5,0x21,0x1f,0xde,0xfd,0xf9,0x69,0x6c,0x5e,0x9d,0xc8,0x95,0x4f,0xef,0x9d,0xbf,0x70,0x8f,0xb1 +,0x50,0x4f,0xeb,0x9b,0x16,0x91,0xf9,0x0f,0x58,0x6c,0x3f,0x20,0x2c,0xa1,0x48,0xfd,0x65,0xbe,0x10,0x82,0x6f,0xb7,0x24,0x12,0x97,0xb3,0xa0,0x04,0x45,0x24,0x07,0xff +,0xf1,0x50,0x80,0x2e,0x7f,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xff,0x7f,0xfc,0xb0,0x61,0x40,0x58,0x2e,0x14,0x13,0x0d,0x0c,0x41,0x42,0x28,0x50,0x6a,0x14,0x08,0x85,0x42 +,0x41,0x10,0x98,0x44,0xa6,0x11,0x2b,0x1a,0xdf,0x49,0xdd,0xc5,0xd6,0x6a,0xaa,0x5e,0xed,0x91,0x75,0xc6,0xeb,0xa9,0x92,0xa7,0x5c,0xcd,0x7f,0xbf,0x91,0xcb,0x9e,0xcc +,0x92,0xd5,0x74,0xdd,0xf4,0x1f,0x9b,0xe7,0xf3,0x73,0xfc,0x2f,0x16,0xfa,0xc8,0x2f,0x8b,0xc1,0x85,0xf4,0x9c,0x82,0x4d,0x47,0xde,0xdd,0xd0,0xef,0x7d,0x6e,0x80,0x6d +,0x7c,0xa0,0x5c,0xd6,0x7e,0xf7,0xa5,0xd6,0xb5,0x20,0xa8,0x3b,0x91,0x7c,0x5c,0x5c,0x2b,0x82,0xe8,0x4e,0x3f,0xed,0x67,0x4a,0xd6,0x8c,0xdb,0x1b,0x47,0x73,0xb5,0xb4 +,0x2e,0x9f,0x35,0xb0,0xbb,0xee,0xfd,0xee,0xa4,0x88,0xe4,0x3e,0x08,0x05,0xe9,0x57,0xf1,0x0c,0x98,0x45,0x2c,0x71,0x8d,0xe3,0x7f,0x96,0x22,0xc2,0x3b,0xd8,0xb2,0xb7 +,0x9c,0x13,0xb1,0x2a,0x46,0x75,0x0b,0xc9,0x15,0x0b,0xc1,0xc4,0x15,0x1e,0xb4,0x14,0x05,0xe4,0x4c,0x26,0xb8,0x13,0x02,0x40,0x54,0xb1,0xd0,0x2c,0x15,0x12,0x05,0x42 +,0xc3,0x41,0x28,0x58,0x2a,0x17,0x0a,0x88,0x84,0x61,0x53,0x18,0x94,0x26,0x21,0x29,0xbb,0xad,0x6f,0xcf,0xad,0x6b,0x2f,0x32,0x32,0xe9,0xed,0xdb,0xa9,0xdd,0x49,0xf1 +,0xea,0xb5,0x3c,0xf7,0x54,0x9f,0x1c,0x01,0xdf,0xae,0x99,0x37,0x4f,0xcf,0x7e,0xae,0x8b,0xc1,0xff,0x99,0xd3,0x3b,0xe2,0xec,0x78,0x7f,0xb3,0xc6,0x70,0xe5,0xf3,0xd5 +,0x17,0x9f,0x2e,0x09,0x2f,0xd0,0xa4,0x9b,0xf8,0x06,0xbf,0xdf,0xb8,0xf5,0x5c,0x79,0xfc,0x5c,0xb8,0xf1,0x4a,0xaf,0xc8,0xf9,0x39,0x2f,0xe6,0x94,0x29,0xe6,0xf3,0xf7 +,0x38,0x21,0xcf,0xd2,0x38,0x0f,0xa0,0xcf,0x80,0xba,0x1f,0x51,0x08,0x97,0xfb,0x1e,0xce,0x9f,0xe1,0x3e,0x7e,0x98,0xf9,0x73,0x0e,0x2e,0x67,0x73,0x85,0xb9,0x81,0xc9 +,0xc9,0xc8,0xe4,0x0e,0x61,0x60,0x07,0x91,0x03,0x87,0x78,0x72,0x1b,0xe6,0x07,0x4d,0xa7,0x9b,0x89,0x25,0xe8,0xee,0x01,0x38,0xd4,0xf5,0x80,0x00,0x79,0x94,0x83,0xbc +,0x0a,0x3d,0xd7,0xae,0x49,0xf8,0x2c,0x9f,0x35,0xee,0x1a,0x53,0xc6,0x11,0x26,0x39,0x00,0xe0,0xff,0xf1,0x50,0x80,0x2f,0x3f,0xfc,0x21,0x0a,0xcf,0xfd,0xfa,0xdf,0xb7 +,0xec,0xb1,0x40,0xb0,0xe0,0x28,0x16,0x0a,0x11,0x82,0x81,0x20,0xa0,0x9c,0x28,0x12,0x0a,0x05,0x42,0x81,0x60,0xa8,0x88,0x2a,0x12,0x0a,0x84,0xc6,0x21,0x30,0x88,0x8c +,0x22,0x65,0x65,0xa6,0xaa,0xb8,0xbe,0x6e,0xb2,0x64,0x93,0x59,0x97,0x92,0xd2,0x55,0xe7,0x1b,0xce,0xaa,0xaf,0xcf,0xff,0x8f,0x91,0xf3,0x5e,0xba,0xff,0xdb,0x27,0xfe +,0xf4,0x22,0xfc,0x76,0x81,0xd7,0x1b,0x7f,0x35,0xde,0xfe,0xa5,0xed,0x47,0x3e,0x77,0x87,0x0e,0xbe,0x89,0xda,0x56,0xd8,0x6f,0xd6,0xe1,0x86,0xf2,0x61,0x9d,0xd9,0x33 +,0xde,0x83,0xec,0x9c,0x4e,0x4e,0x3e,0x22,0x6e,0x37,0xe0,0x06,0x98,0x38,0x31,0x1a,0x26,0x38,0x9f,0x1e,0x39,0x98,0x9f,0x13,0xb5,0x15,0xd1,0x00,0xd3,0xf9,0xf4,0xca +,0x2e,0x05,0xd2,0x51,0xe5,0x11,0xcb,0xa3,0x82,0xdb,0x2e,0x02,0x68,0xf8,0x2f,0x5a,0x22,0xe6,0xa3,0xd2,0xf3,0xfc,0x2f,0x42,0x01,0x1b,0xe1,0x27,0xdc,0x07,0x79,0x60 +,0xff,0x85,0x8d,0x54,0xc1,0x17,0x18,0x77,0x02,0xa2,0x59,0xa6,0xa5,0x81,0x7a,0xa8,0x28,0x24,0x2e,0x02,0x80,0x29,0x54,0x2c,0x64,0x0b,0x09,0x02,0xa2,0x61,0x20,0x54 +,0x2c,0x18,0x0a,0x09,0x82,0xa1,0x70,0xa8,0x44,0x2e,0x15,0x13,0x85,0x42,0x62,0x70,0x98,0x44,0x66,0x11,0x23,0xc6,0x6b,0x2e,0xf3,0x2b,0xa2,0xab,0x25,0x24,0xa5,0xf9 +,0xbe,0xea,0xbd,0xaf,0xd5,0x79,0x6b,0x3b,0xd2,0xbf,0x90,0x7b,0xa3,0x9b,0x6e,0x1e,0x37,0x7a,0x7d,0x27,0xc1,0x35,0x37,0x6b,0x5f,0xc7,0x77,0xf6,0x73,0x3e,0x7f,0x17 +,0x00,0x9c,0x9b,0x36,0xb0,0x51,0xfc,0x7d,0x5b,0xe8,0x78,0x0b,0x46,0xd0,0x56,0x87,0x46,0x31,0x43,0x17,0xfd,0xfe,0x37,0xb3,0xdb,0xfd,0x37,0xfc,0xb7,0x9f,0x7e,0x32 +,0x21,0xd0,0xe4,0xf9,0x73,0x70,0x0d,0xc6,0xe7,0x87,0x10,0x4c,0x9d,0xa8,0x29,0xf2,0x9a,0xc7,0x4f,0x98,0x07,0x27,0x10,0x1c,0x9c,0x25,0x6e,0xc3,0xd1,0xc3,0x98,0xe4 +,0x00,0x03,0xcc,0x00,0x13,0xe2,0x7f,0xef,0x1d,0xc7,0x7c,0xf6,0x2a,0x7d,0x7e,0xa8,0xf2,0x80,0x00,0x0f,0xd7,0x9a,0x8b,0x4a,0x70,0x73,0x01,0x75,0x87,0xcd,0xee,0x9e +,0xb0,0x6a,0x1d,0x06,0x52,0x54,0x02,0x25,0xcc,0x40,0x70,0xff,0xf1,0x50,0x80,0x2f,0x5f,0xfc,0x21,0x0a,0xcf,0xff,0xf9,0xff,0xff,0xec,0xaf,0x60,0xc0,0x5c,0x2c,0x24 +,0x1b,0x05,0x02,0xc2,0x40,0xa8,0x50,0x2c,0x15,0x09,0x85,0x02,0xc1,0x50,0xa1,0x08,0x62,0x63,0x08,0x8c,0xc2,0x23,0x00,0xb9,0xf3,0xcd,0x3a,0xae,0x6e,0xef,0x77,0x53 +,0x7e,0x79,0x9a,0xca,0x99,0x72,0x54,0xa5,0xd6,0xb7,0x75,0xec,0xe3,0xff,0xd0,0x27,0x69,0x3b,0x1f,0x96,0xb7,0xe5,0xf8,0xe3,0xff,0xf7,0x4d,0xed,0xfa,0x13,0xe4,0x8a +,0xda,0xcf,0x61,0xaa,0x0e,0xd5,0x59,0xf6,0x53,0x6b,0x43,0xc8,0x4c,0xdc,0x7e,0xea,0xfd,0x0c,0x1e,0xf7,0x3f,0x1c,0x92,0x11,0xa7,0x2f,0x3e,0x72,0xbb,0xce,0xe5,0xba +,0x5f,0xfe,0x98,0xe8,0x16,0x8e,0xf4,0x7a,0xef,0x08,0x34,0x67,0x51,0xf8,0x24,0xcb,0x6e,0x6f,0xb8,0x71,0x63,0xad,0x2f,0x51,0xc8,0xac,0x20,0x9b,0xfc,0x96,0x74,0x84 +,0xce,0xf2,0xb4,0xe5,0x95,0x1f,0xfa,0xb3,0x5a,0x76,0xce,0x9e,0x14,0xd4,0x59,0x06,0x3a,0xc0,0xb4,0xe9,0xce,0x5f,0x05,0x05,0xae,0xba,0x0d,0x04,0xf4,0x2c,0x51,0x5a +,0xab,0x0a,0x6c,0x0e,0xf4,0x80,0xac,0xc0,0x26,0x08,0x01,0x4c,0xa1,0x70,0xb1,0x10,0x2c,0x14,0x13,0x84,0x82,0xa1,0x61,0x28,0x98,0x28,0x15,0x12,0x05,0x48,0x22,0x31 +,0x28,0x44,0x26,0x15,0x10,0x84,0xc2,0x21,0x31,0x88,0x9e,0x2b,0x5b,0xd2,0x73,0xfe,0x9f,0x9f,0x3d,0xef,0x2d,0x4d,0x55,0x49,0x75,0xe6,0xfd,0x4d,0x6b,0xc6,0xbc,0x7f +,0xb7,0xe7,0x25,0x71,0xff,0x5d,0x07,0x9b,0xba,0xaf,0x77,0x46,0x9b,0xd3,0xdb,0x66,0xa6,0xb7,0xaf,0xfe,0x67,0xef,0x7c,0xdb,0x29,0x8d,0x8e,0x5e,0xa4,0x92,0xd7,0xb7 +,0x79,0xd1,0x8f,0x33,0xe0,0xf1,0xe1,0xc6,0x51,0x4e,0x41,0xe6,0xff,0x3f,0xfd,0x8a,0x78,0xbc,0x87,0x8f,0x0e,0x2e,0x11,0x7f,0xf3,0xf2,0x3d,0xce,0x47,0xc7,0x9b,0x98 +,0x1e,0x6e,0x2f,0x9c,0xf8,0x4c,0xc7,0x38,0x91,0xcf,0x98,0xe5,0xc6,0x02,0x1e,0xc9,0x1c,0xc2,0x18,0x5c,0x4f,0x69,0xeb,0x1d,0xe0,0x7b,0xbe,0xb0,0x00,0x79,0x76,0xb9 +,0xef,0xe0,0x01,0x6e,0xf6,0x1f,0x85,0x55,0xf9,0x40,0x00,0x16,0x4b,0x44,0x39,0xa1,0x00,0xb8,0xb9,0x27,0xac,0x6c,0xac,0xb5,0x04,0xbb,0xe0,0x5a,0xaf,0x85,0x35,0xbf +,0x28,0x01,0x50,0x2c,0x07,0xff,0xf1,0x50,0x80,0x2e,0x3f,0xfc,0x21,0x0a,0xcf,0xea,0xff,0xff,0xdf,0xbc,0xac,0x62,0xa1,0x18,0x4a,0x14,0x19,0x09,0x06,0x42,0x41,0x90 +,0x8c,0x22,0x12,0x10,0xb1,0xeb,0x8e,0xf8,0xbd,0x77,0xd6,0x63,0x5b,0x96,0xbc,0xa1,0x15,0x72,0xa2,0x5e,0xf5,0xbf,0xaf,0x08,0xff,0xdb,0x41,0x3c,0xfd,0x7e,0x3e,0xbc +,0xf6,0x7e,0xbf,0x1b,0x37,0x5e,0x2b,0xcf,0xf6,0x4d,0xc5,0xc5,0xef,0x2f,0x82,0x38,0x71,0x4d,0xcb,0x92,0xeb,0x2e,0xe7,0xd9,0xdb,0xf3,0xfa,0xfb,0x61,0xc5,0x19,0x93 +,0xa6,0xf3,0xf4,0xbc,0x02,0x7a,0xf9,0xff,0xe9,0xf5,0xfa,0xf2,0xf0,0x01,0x8c,0xa5,0x09,0xa2,0x2b,0xdb,0x4e,0xe2,0xd1,0xfd,0xf3,0x1e,0xa3,0x96,0xa7,0x3c,0xe9,0xcc +,0xdb,0xe8,0x4b,0xe1,0xf6,0x9a,0x3b,0x29,0x56,0x34,0xe9,0x05,0xc5,0xdd,0x6b,0x09,0xb7,0x86,0x66,0x1a,0xf3,0x1c,0x59,0x78,0x4d,0x8e,0x03,0x14,0xd7,0xa4,0x53,0x42 +,0x09,0x5d,0x34,0xae,0xca,0x70,0x99,0x86,0xf7,0x90,0x5e,0x65,0x10,0x9d,0x01,0x5e,0x32,0x1d,0xc1,0xad,0x62,0x50,0x00,0x81,0x70,0x15,0x0a,0x16,0x2a,0x05,0x84,0x81 +,0x60,0xa0,0x54,0x2c,0x23,0x0a,0x05,0x82,0xa1,0x40,0xa8,0x50,0x4a,0x27,0x0a,0x88,0xc2,0xa2,0x30,0xa8,0x4c,0x22,0x23,0x08,0x85,0x42,0x62,0x11,0x32,0x94,0x75,0xe3 +,0x4b,0x9c,0xcb,0x64,0xad,0x65,0x5b,0x8c,0xe3,0x37,0xc6,0x4e,0xbd,0x7f,0x3f,0x6f,0x6d,0xd4,0xe3,0x41,0xe9,0x8f,0xa7,0x49,0x34,0xdd,0xd7,0xc3,0x65,0x3f,0xa8,0x17 +,0xdb,0xd3,0x57,0xec,0x2a,0x2e,0xb1,0xff,0x6f,0xa8,0xfb,0x8b,0xac,0x7f,0x4b,0x40,0x6e,0xff,0x89,0x6e,0xc7,0xb0,0x89,0x83,0x50,0x4c,0xe5,0xc6,0xdc,0x3a,0x17,0xa3 +,0xca,0x7c,0xab,0x81,0xcf,0x05,0xff,0x07,0xfd,0xd6,0xf5,0x17,0xbf,0x82,0x70,0xe6,0xe4,0x38,0xa3,0x91,0xc5,0xcf,0x98,0x07,0x9f,0x9c,0x7c,0xbc,0xfa,0x80,0x1e,0x00 +,0x03,0xcd,0xdf,0x7a,0xe3,0xbd,0xe1,0xe3,0x86,0xb9,0xa4,0x5f,0x23,0x20,0x02,0x3d,0x69,0x7f,0x48,0xf8,0x1d,0xea,0x81,0xd1,0x67,0x3e,0xd1,0x21,0x50,0x77,0x16,0xd3 +,0xc5,0xb6,0xd3,0x80,0x15,0x1e,0xbf,0xac,0x17,0x03,0xc8,0x00,0x05,0x92,0x3b,0xc4,0x8f,0x58,0x2c,0x01,0x60,0x38,0xff,0xf1,0x50,0x80,0x2c,0x5f,0xfc,0x21,0x2a,0xcf +,0xf7,0xef,0x7f,0xff,0xf2,0xad,0x40,0xb1,0x10,0x4a,0x16,0x0a,0x85,0x02,0xa1,0x42,0x10,0x50,0x24,0x24,0x13,0x85,0x42,0x81,0x10,0x90,0x4c,0x22,0x23,0x08,0xb1,0xe8 +,0x75,0x79,0x53,0x55,0x7b,0xd6,0x52,0xb5,0x97,0xbb,0x86,0xb1,0x2a,0x38,0xf1,0x38,0x8f,0x6d,0x74,0x3e,0x03,0xd9,0x7a,0xff,0x5e,0xaf,0x67,0xed,0xb3,0xe8,0xfc,0xa1 +,0xeb,0xd4,0x3d,0x42,0x1e,0x3f,0x69,0xc6,0x7f,0x5c,0x7c,0x93,0xa0,0x60,0x97,0x9b,0xdf,0xf2,0x43,0xe0,0x71,0x86,0xfe,0xda,0xbb,0x6d,0xed,0xbe,0xc7,0x90,0x0e,0x13 +,0xfc,0x86,0xb1,0xf1,0x39,0x8a,0xba,0xa7,0x4f,0x4e,0xc7,0x3b,0x8c,0xb0,0xec,0x10,0xdf,0x67,0xec,0x8e,0x29,0x26,0x6c,0xcb,0x54,0xbb,0xbb,0x64,0x63,0xa6,0x66,0x9d +,0x98,0x89,0xf3,0xb4,0x94,0x2e,0x8b,0x37,0xed,0x4d,0x3b,0x7a,0xaa,0x0a,0x55,0x6e,0x13,0xc2,0x99,0x00,0x4e,0x51,0x33,0x27,0xe5,0x03,0x5d,0xec,0xbd,0xc8,0xaa,0x0a +,0x13,0x09,0xb5,0x93,0x88,0x03,0x40,0x48,0x05,0x42,0x05,0x8a,0x84,0x60,0xa0,0x98,0x48,0x27,0x12,0x09,0x48,0x81,0x50,0x98,0x54,0x26,0x35,0x10,0x94,0xc4,0x22,0x73 +,0x49,0x24,0xdf,0x9e,0xe7,0x1d,0xe2,0xd3,0x72,0x49,0x2b,0xaa,0xab,0xae,0x39,0xe2,0x6b,0xdf,0xe3,0x9c,0x9e,0xd8,0x38,0x3e,0x5c,0xb7,0x70,0xd3,0x5e,0xbb,0xb4,0x51 +,0xa2,0xfd,0x1f,0xd8,0x7f,0x31,0xc0,0xb5,0xcc,0x01,0xe5,0x96,0xe9,0x88,0xaf,0xeb,0xa3,0xf8,0x95,0xfe,0xf1,0xa8,0x34,0xb1,0x1e,0xee,0x79,0xa2,0x66,0x1e,0x6b,0xad +,0x24,0x9f,0x4c,0xff,0xa9,0xae,0xcf,0xb2,0x77,0x4f,0x3a,0x3a,0xe0,0xe5,0xc3,0x8b,0x9f,0x03,0x90,0xe3,0xc3,0xe7,0xf3,0xf3,0xe2,0xe0,0x41,0x9c,0x8a,0xf3,0x76,0x79 +,0xfd,0x7c,0x9c,0x00,0x1d,0xdf,0xfd,0x82,0x07,0x33,0x93,0x80,0x39,0x7f,0x28,0x73,0xe5,0x40,0x77,0xb8,0xfd,0x93,0x18,0xef,0x02,0x78,0x2d,0x10,0x72,0xd0,0x00,0x01 +,0xe6,0x46,0x00,0xdb,0xf3,0x04,0x5b,0x48,0xa0,0x0d,0xa2,0xe9,0x10,0xa3,0xd7,0x64,0x54,0xf5,0xc8,0x82,0x70,0x03,0x30,0x1c,0xff,0xf1,0x50,0x80,0x2e,0x1f,0xfc,0x21 +,0x4c,0xfe,0xff,0xfd,0x64,0x16,0x28,0x59,0xa9,0x42,0xa4,0x5b,0x83,0x2e,0xcb,0xd7,0x03,0x51,0x5f,0xb2,0xbe,0xb8,0xe1,0xd1,0x60,0xed,0xe4,0xeb,0xb7,0x37,0xf9,0xfc +,0x66,0x35,0x63,0x18,0xcc,0x9d,0x5b,0x0a,0xdc,0x66,0xd2,0x9f,0x84,0xd5,0x1a,0xa3,0xfa,0xc7,0xff,0xef,0x94,0xff,0xe5,0x37,0x35,0xaf,0x4b,0xbe,0x44,0x4a,0xf4,0xc3 +,0xc2,0x8e,0xd3,0x2b,0xf7,0xcd,0xdc,0x98,0x2f,0xe2,0xf9,0x01,0xeb,0x94,0xd2,0x91,0x70,0xf3,0x21,0x0c,0xc0,0xe3,0xa1,0x0c,0x76,0xc4,0x0e,0x93,0x68,0x7a,0xe1,0x72 +,0xcc,0x61,0x22,0xd1,0x26,0xf9,0x5c,0x74,0x7c,0xf7,0xef,0xc6,0xe0,0xa8,0xac,0xd7,0x9e,0x6a,0x65,0xdb,0x47,0x4b,0xfa,0x6e,0xa2,0xb5,0x67,0x2d,0x44,0xa0,0x4d,0xa5 +,0x64,0x0b,0x55,0x6e,0xb4,0xa7,0x0e,0xdb,0x8e,0xce,0x99,0x31,0x8b,0x92,0x6c,0xd3,0x56,0xd3,0x59,0xa6,0x0f,0xcb,0x03,0xd7,0xd1,0x63,0xbd,0x32,0x95,0x2e,0x48,0x81 +,0x22,0xa7,0xb2,0xeb,0x08,0x0b,0x00,0xb4,0xc0,0x44,0xe0,0x28,0x60,0xb1,0x84,0xcd,0x09,0x91,0x69,0x55,0x2d,0x2d,0x34,0x23,0xab,0x5b,0x6f,0x55,0xd2,0x99,0x00,0xd7 +,0xbc,0x00,0x8a,0xca,0x92,0xe8,0xe1,0xa6,0xa6,0x94,0xe9,0xaf,0xeb,0xc5,0x7f,0x36,0xec,0x16,0xec,0x46,0x93,0x84,0x2d,0x61,0x62,0x49,0x12,0xe2,0xa0,0x5b,0x49,0x91 +,0x10,0x8b,0xb8,0x8a,0x42,0x2d,0x31,0xa4,0xc6,0x4f,0x8b,0xe1,0x26,0x1b,0x1a,0xf9,0xf5,0xdb,0xfb,0x5d,0x46,0xa9,0xe3,0xc1,0x11,0xa8,0x9c,0xcb,0x46,0xc1,0x57,0xed +,0x04,0x49,0x11,0xc7,0x59,0xb5,0x04,0xb5,0xe9,0xc9,0xb5,0xc9,0xd8,0x16,0x44,0xc3,0x7d,0xbb,0x80,0xeb,0x14,0x07,0xa5,0x00,0x00,0xc0,0xde,0x2f,0x67,0x33,0xbe,0x91 +,0x8f,0x5f,0x31,0x5f,0xde,0xac,0xc5,0x55,0xd1,0x71,0xf4,0x9d,0x7d,0x5d,0x39,0x0f,0xc3,0xb3,0xd3,0x6c,0x4f,0xef,0xc4,0xfd,0x2c,0xe0,0x4b,0xee,0x57,0x17,0xc9,0x35 +,0x3f,0xcf,0xc5,0xb4,0x8e,0xe7,0xfe,0xd8,0xff,0x53,0x7e,0x87,0xa7,0xa3,0x80,0x70,0x7f,0x93,0xb1,0x87,0xce,0xcd,0x78,0xf3,0x8b,0xf7,0xe0,0xe5,0x61,0x62,0x36,0x23 +,0x63,0x55,0x8b,0x64,0x17,0x2b,0x73,0x80,0xff,0xf1,0x50,0x80,0x2c,0xff,0xfc,0x21,0x6a,0xcf,0xdf,0xff,0xff,0x7f,0xff,0xb6,0x80,0xb1,0x14,0x2c,0x35,0x0a,0x11,0x42 +,0x83,0x60,0xa0,0x48,0x28,0x16,0x0a,0x0c,0x82,0x21,0x20,0x8b,0x97,0x57,0x38,0xac,0xe7,0x83,0x55,0x95,0x74,0x5c,0xc8,0x88,0x8b,0xc9,0x51,0xaf,0x36,0x9c,0x04,0x75 +,0x13,0x7d,0x3d,0xbc,0xbc,0x2e,0xeb,0x47,0x48,0xf3,0x5f,0xbf,0xb5,0xfe,0x2f,0x96,0x5e,0xfd,0x80,0x4f,0xc6,0x21,0xe4,0x77,0x3e,0x89,0xc3,0x7a,0x29,0xe9,0x1c,0xf9 +,0xcd,0xa1,0x27,0x6e,0xdc,0xc8,0x0f,0x74,0x6f,0x06,0x7e,0xae,0xae,0x13,0x79,0x66,0x84,0x61,0xa8,0x08,0xd4,0x3c,0x3d,0x94,0x0f,0x0a,0xe2,0xbc,0xe5,0xdb,0x39,0x4e +,0x96,0x1c,0x63,0xaf,0xab,0xb1,0x8a,0x38,0x67,0xdd,0xce,0x69,0x10,0x3c,0x0a,0x27,0x53,0xc7,0x1c,0xb1,0x42,0x48,0xf0,0x4c,0x91,0x3a,0xce,0x8f,0xde,0x58,0x56,0x45 +,0x34,0xe4,0x25,0x72,0x95,0x76,0x95,0xe4,0x53,0x3c,0xe5,0x3a,0xfd,0x16,0x2b,0x6e,0x40,0x28,0x00,0x54,0x09,0x00,0x44,0x44,0x05,0x42,0x05,0x82,0xa1,0x60,0xa0,0x58 +,0x8a,0x12,0x0a,0x05,0x42,0x81,0x61,0x20,0x98,0x2a,0x14,0x2a,0x89,0x82,0xa3,0x30,0x88,0x4c,0x22,0x23,0x08,0x99,0x3b,0xbd,0xd6,0xba,0xe7,0x86,0xe5,0x62,0xd4,0xab +,0xa9,0x7a,0xcd,0xf1,0x6c,0xf8,0xf1,0xaf,0x17,0xf1,0xbb,0x4d,0x0d,0x09,0x1a,0x7e,0xe5,0xfd,0xbf,0xa9,0xff,0x89,0xf8,0x14,0xe7,0xa9,0xfa,0x5f,0xaa,0xb4,0x01,0x5f +,0xba,0x98,0xfb,0x87,0x93,0xfa,0xae,0x0b,0x6d,0x8b,0x1f,0xed,0x28,0x4b,0xe6,0xbb,0xc8,0x9f,0x5d,0x12,0x4c,0xe7,0xda,0xf5,0xa7,0xfd,0xff,0xc0,0x3d,0x0e,0xb7,0xb6 +,0xb9,0xf8,0x1b,0xe7,0xf5,0xb7,0xdb,0xd2,0xfb,0x6d,0xfc,0x1f,0x13,0xff,0x23,0xda,0x4c,0x14,0xf3,0x39,0x9c,0xb9,0x81,0xf7,0x80,0x0e,0xeb,0xb6,0x0e,0xf9,0x48,0x98 +,0x80,0x70,0xf3,0xe6,0x38,0x50,0x27,0xc7,0x30,0x2e,0xa8,0x48,0x07,0x23,0xc7,0xdc,0x77,0x3d,0xf0,0x05,0xe0,0xb5,0x47,0xaf,0xf2,0x40,0x1d,0x9e,0xb3,0xc4,0x2d,0xdd +,0x8a,0x44,0x78,0xa0,0x16,0x2a,0x54,0x27,0x00,0x00,0xd6,0x44,0xa0,0x50,0x0e,0xff,0xf1,0x50,0x80,0x2b,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xfe,0xff,0xff,0xff,0xb6,0x80 +,0xb0,0xd0,0x2a,0x14,0x0b,0x05,0xc2,0xa1,0x40,0xa8,0x50,0x84,0x14,0x0a,0x84,0x82,0x82,0x22,0x8c,0x1a,0x25,0xb5,0xef,0xe6,0xaa,0xf7,0x2e,0x62,0x46,0x49,0x75,0x02 +,0x55,0xca,0xbe,0x2f,0x8d,0x79,0x1a,0x4b,0xaf,0x6f,0x19,0x3c,0xfe,0xdb,0x7e,0x0a,0xe3,0xdb,0x5b,0xee,0xef,0xeb,0xb5,0xa6,0xa8,0x7a,0x2d,0x96,0x77,0xcf,0xb3,0x81 +,0x52,0xe2,0x1c,0x51,0x1d,0x1c,0x40,0xf3,0xf9,0x94,0x7c,0xf9,0xd9,0x97,0x7d,0x37,0x7a,0xd8,0x7d,0x28,0xa2,0x53,0x58,0xc7,0x91,0x7c,0xf0,0x1d,0xd2,0xf4,0xe4,0x2f +,0x4a,0xef,0x9a,0xb0,0xd2,0xd6,0xf4,0x28,0x4e,0xb0,0xe1,0x49,0xc3,0xb9,0xb3,0x10,0x9a,0x70,0xe5,0x60,0xf3,0x5b,0x8e,0x59,0x24,0xb1,0x1f,0x1e,0x54,0x83,0xb5,0x05 +,0x06,0xf8,0x11,0x88,0x46,0xc5,0x4b,0xa7,0x49,0xb5,0xc0,0x01,0x86,0xe2,0x40,0x80,0x44,0x13,0x48,0x10,0x02,0xa5,0x04,0xe1,0x61,0x20,0x98,0x4a,0x14,0x0b,0x09,0x02 +,0xe1,0x61,0x20,0x58,0x2e,0x15,0x2a,0x04,0xc2,0xa1,0x31,0x28,0x8c,0x2a,0x13,0x20,0x94,0xcd,0x6e,0x5e,0x57,0x5d,0x7a,0xac,0xbd,0xf1,0x99,0x77,0x37,0xc5,0x25,0xeb +,0x71,0x7c,0xf5,0x57,0x5d,0x19,0xe4,0x68,0x3d,0x24,0xf2,0x79,0x15,0xfc,0x3f,0x89,0xce,0x9f,0x9f,0x26,0x78,0x69,0xfd,0x7b,0xbc,0x06,0x9e,0xe1,0x19,0x75,0x2e,0xd1 +,0xe5,0xd8,0xd9,0xcf,0x85,0x94,0x70,0xa1,0xef,0xe7,0x1d,0x97,0xe7,0xea,0xef,0xdc,0x25,0x6b,0xa5,0x3e,0x4d,0x8f,0x97,0x0e,0xdb,0x5b,0xe0,0x78,0x8e,0x97,0x5f,0x08 +,0xef,0x57,0x87,0x8c,0xf4,0x12,0x38,0x70,0xe1,0xc2,0x5c,0x93,0x72,0xcc,0xbf,0x29,0xdb,0x74,0xfe,0xc3,0xd5,0xcf,0x03,0x10,0xf2,0xb7,0x00,0x4f,0x27,0xae,0xfb,0x7b +,0xd0,0x3d,0x66,0x79,0x7f,0xe8,0x3c,0x54,0x90,0xa0,0x39,0xc7,0x88,0x00,0x0e,0xf7,0xae,0x15,0x1d,0xa9,0x3b,0x62,0x68,0x77,0x83,0xdd,0x07,0x73,0xbc,0x3d,0xc2,0xc0 +,0x77,0x08,0x85,0x48,0x16,0x00,0x16,0x5c,0x5c,0x13,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2d,0xbf,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xff,0xf7,0xfc,0xb5,0x60,0xc0,0x58,0x64 +,0x14,0x0b,0x09,0x42,0x81,0x60,0xa0,0x54,0x2c,0x15,0x09,0x05,0x06,0x43,0x41,0x10,0x84,0x24,0x13,0x08,0xb5,0xc5,0xf3,0xe5,0xd9,0x25,0x5e,0x26,0xb7,0xac,0xad,0x64 +,0x92,0xae,0xb8,0xd8,0x95,0x7a,0xbe,0x13,0xc8,0xfb,0xfe,0xb5,0x70,0xcf,0xdb,0xf8,0x2e,0x03,0xa7,0x6e,0x6f,0x47,0xc0,0xbc,0x1d,0x80,0x07,0xf6,0x62,0x35,0x3e,0x21 +,0xfb,0x25,0x8a,0x40,0xbc,0x3f,0xcf,0x69,0xc3,0xeb,0xc7,0xb1,0xe2,0xa5,0x7b,0xbc,0x41,0xbb,0xc6,0xda,0xfc,0x43,0xff,0xb9,0x8e,0xc5,0xea,0xcf,0x7b,0xa8,0x94,0x53 +,0xd1,0xaa,0xac,0xb9,0xec,0xd7,0xda,0x30,0xde,0x7d,0x55,0x31,0x12,0x2b,0xcc,0xca,0xb7,0x34,0xec,0x4d,0xd3,0x04,0xde,0xbf,0x72,0x82,0x96,0x9d,0xf1,0xcb,0x5b,0xd5 +,0x1c,0x09,0x81,0x28,0xd6,0xd7,0xf7,0xf8,0x10,0x5a,0x55,0xd3,0x21,0x38,0x26,0x29,0x36,0x38,0x21,0xf4,0x80,0x50,0x44,0x16,0x2e,0xb1,0x70,0x09,0x48,0x09,0x09,0x80 +,0x9f,0x41,0x30,0x5c,0x26,0x14,0x13,0x05,0xc2,0x81,0x61,0x20,0x98,0x48,0x16,0x1a,0x85,0x82,0x81,0x50,0x98,0x54,0x46,0x15,0x11,0x85,0x42,0x21,0x32,0x09,0x9f,0x9a +,0xd5,0x6e,0xbf,0x7f,0xd3,0xf5,0xf7,0x64,0xaa,0xbc,0x4b,0xaa,0x8b,0xa7,0xb6,0x6b,0xc7,0xc6,0x65,0x5f,0x9a,0xe3,0x77,0xf8,0x1c,0x47,0xe0,0xd1,0xb7,0xb6,0x7e,0x9f +,0xf7,0xdf,0x50,0xd3,0xe6,0xf6,0xef,0x9a,0x21,0xee,0x4a,0x41,0xf6,0x7f,0xf4,0x09,0xeb,0xbc,0x1e,0x8c,0x25,0x15,0x7e,0xa8,0x9b,0xf1,0xd4,0xfa,0x52,0xdc,0x5b,0x04 +,0x3e,0xc3,0x01,0xe3,0xc2,0xf6,0x5d,0xf0,0xc1,0xe7,0x6e,0xe2,0xa4,0xe8,0x02,0xfc,0xd7,0x20,0xc7,0xd9,0xc8,0xaf,0x0a,0xe2,0xc7,0x77,0x9e,0xfa,0x8d,0xdd,0xce,0xee +,0x34,0x83,0x90,0x39,0x39,0x2c,0x9e,0x23,0xdf,0x74,0xa6,0x07,0x72,0x15,0xe4,0x00,0x14,0x00,0xf1,0x70,0x77,0x10,0x2b,0x47,0xce,0x6d,0xde,0x38,0xb0,0x07,0x6a,0x91 +,0x3d,0x71,0x7b,0x1e,0x84,0x7a,0xe4,0x4f,0x75,0x18,0x03,0xde,0xf7,0x40,0x32,0x80,0x4e,0xa2,0xe0,0x30,0x80,0x60,0x16,0x01,0xc0,0xff,0xf1,0x50,0x80,0x2d,0x1f,0xfc +,0x21,0x0a,0xcf,0xff,0xfa,0xde,0xff,0xff,0xb3,0x62,0xa0,0xdc,0x26,0x14,0x0b,0x05,0x03,0x01,0x40,0xb0,0x48,0x28,0x12,0x0a,0x04,0x82,0x81,0x20,0xa0,0x88,0x28,0x11 +,0x19,0x84,0x44,0x61,0x14,0xab,0x5b,0xe3,0xae,0xdd,0xf1,0x7b,0x56,0xaa,0xf2,0x6a,0x95,0x72,0xab,0x53,0x3e,0xfd,0xef,0xe3,0xd3,0x8c,0xb9,0x7e,0x78,0x16,0x7b,0x3e +,0x3d,0x9f,0x45,0xfc,0x3e,0x91,0xec,0x78,0x97,0xd6,0x7d,0xa7,0xe9,0x75,0x3b,0x3d,0x42,0x2c,0x6f,0x57,0xf2,0xce,0xa0,0xfd,0xd2,0xf7,0x27,0x34,0xe3,0x93,0xe4,0x20 +,0x57,0x34,0x7f,0x3e,0xdc,0x55,0x66,0xf2,0xbf,0x55,0x4d,0x34,0x27,0xaf,0xef,0xad,0xc9,0xec,0x29,0x5a,0x7f,0x7e,0x46,0x2b,0xfb,0x0f,0x70,0x6d,0x32,0x9d,0x78,0x4c +,0xbc,0x35,0x8b,0x71,0xa9,0x1d,0x52,0x39,0x4e,0x95,0xac,0x92,0xd9,0x44,0x66,0x07,0x70,0x2b,0x48,0x31,0x4d,0x2b,0x55,0x1a,0x87,0x80,0x02,0x6b,0xc6,0x29,0x50,0xa0 +,0xe8,0x48,0x0c,0x95,0x02,0x53,0x0a,0x00,0x17,0x08,0x01,0x10,0x2a,0x90,0x2c,0x27,0x09,0x85,0x82,0xe1,0x61,0x28,0x50,0x2c,0x15,0x0a,0x05,0x85,0x01,0x50,0xa0,0x54 +,0x4c,0x15,0x0b,0x85,0x02,0xa4,0x10,0xa8,0x8c,0xa2,0x65,0x4a,0x9f,0x1f,0x9e,0xab,0x8d,0xb6,0x94,0xeb,0x92,0x0e,0x37,0xc4,0xeb,0x7b,0xbb,0x94,0xf8,0xbf,0x5c,0x67 +,0x91,0xfe,0xdb,0x79,0xd5,0xd9,0xdb,0xbf,0x4d,0x9e,0xff,0x38,0x79,0x73,0x1e,0xe7,0x5f,0xfd,0x2b,0xc2,0x84,0x4e,0x6f,0x3e,0x5d,0x8f,0xef,0x7f,0x46,0x18,0x77,0x0d +,0xf5,0x04,0xea,0xd3,0x7f,0xfa,0xb2,0xf3,0x54,0xe7,0x7f,0x38,0x73,0xe4,0xf9,0x71,0xaf,0x97,0xcc,0xe6,0x34,0x6f,0xb0,0x88,0x8d,0xcd,0xc7,0xad,0x0f,0x3e,0xe5,0x6d +,0xa3,0x7e,0xd7,0xf1,0xed,0xe3,0x5b,0x60,0xe2,0x3c,0x60,0x31,0xc2,0x62,0xd3,0xea,0xf5,0x69,0x76,0x61,0x64,0x9e,0x2a,0xe1,0xc0,0x25,0xcd,0x6a,0x03,0xc9,0x60,0x00 +,0xfb,0xc3,0x9f,0xcc,0x22,0x28,0x19,0x53,0xd6,0xfd,0xa8,0x50,0x0f,0xca,0x0f,0xe5,0x80,0xf5,0xcb,0x03,0xf6,0xc0,0x80,0x08,0x85,0x02,0xf1,0x02,0xc0,0x11,0x14,0xb0 +,0x1c,0xff,0xf1,0x50,0x80,0x2c,0xbf,0xfc,0x21,0x0a,0xcf,0xff,0xff,0xbf,0xff,0xfc,0xaf,0x80,0xb0,0xd4,0x24,0x14,0x0b,0x09,0x42,0xc1,0x40,0xb0,0x5c,0x2c,0x15,0x0a +,0x04,0x82,0x82,0x50,0x90,0x90,0x24,0x14,0x09,0x04,0x46,0x61,0x11,0x98,0x84,0xed,0xde,0x5e,0xaa,0x6e,0xb5,0x4c,0xd5,0x71,0xdd,0xb5,0x90,0x95,0xa5,0x74,0xe7,0x56 +,0xdc,0xd7,0x9e,0xff,0x7b,0x02,0xd5,0x7f,0xbc,0x3e,0x96,0x7b,0x57,0xda,0xfc,0xef,0x6f,0xec,0xf4,0x27,0x8b,0xc0,0x91,0x34,0x30,0x5b,0x1f,0x64,0x7f,0x26,0x58,0xbc +,0xee,0xa7,0xe4,0xef,0x76,0xde,0x7f,0xd7,0xff,0xb7,0xd3,0xa4,0x47,0xcd,0xea,0xb7,0xff,0x56,0xe1,0x84,0x9e,0x39,0x39,0xf7,0x53,0xed,0x4d,0x1d,0x80,0xce,0x23,0x38 +,0x54,0xcf,0x83,0x7b,0xe7,0x69,0xb1,0x35,0xbe,0x2c,0xef,0x59,0xcd,0x12,0x3e,0x6e,0xc5,0x34,0xb4,0xd6,0x0a,0xc9,0x17,0x18,0xfb,0xb4,0x07,0x85,0x48,0xa8,0x56,0xb8 +,0xb4,0xa5,0x62,0x71,0x44,0xa0,0x3b,0xe0,0x0e,0xe9,0x7a,0x91,0x00,0x9a,0xd1,0x13,0x13,0x09,0x00,0xc0,0x04,0x0a,0xdc,0x05,0x09,0x05,0x8c,0x81,0x70,0xa8,0x90,0x2a +,0x16,0x12,0x05,0xc2,0x82,0x61,0x20,0x94,0x28,0x17,0x09,0x85,0x48,0x63,0x11,0x98,0x44,0xaf,0x9b,0xe7,0x59,0xc3,0xbf,0xae,0x77,0x2f,0x32,0xe9,0x4b,0x47,0x0a,0x97 +,0x2b,0x4e,0x87,0xd7,0xf1,0xf5,0xed,0xd0,0xc8,0x9f,0xae,0x38,0xec,0x6a,0x38,0x0e,0xfd,0x03,0xe3,0xf9,0x9d,0x0f,0x34,0xc1,0xef,0xdd,0x7c,0x1a,0xe9,0x65,0xe3,0xcb +,0xcf,0x54,0xe1,0xd7,0xf6,0x4d,0xdd,0xbb,0xfc,0xff,0xe6,0xf7,0x7b,0x5d,0x6b,0xcb,0x43,0xba,0x8a,0xa4,0xc9,0xfc,0xf4,0xda,0xdc,0x79,0x7f,0xf7,0x61,0xfd,0x87,0x1a +,0xf7,0xba,0x51,0x9c,0x16,0x74,0x2b,0xa7,0x6f,0x45,0x17,0x73,0xe3,0xb7,0xac,0x9f,0x6a,0xa8,0x1d,0xcf,0xe9,0xa0,0x38,0xc7,0x1a,0x5e,0x8e,0x44,0xac,0x45,0x11,0xcd +,0xe1,0xdd,0xba,0xb0,0x02,0x1e,0x40,0x07,0x90,0x97,0x88,0x91,0x7b,0xcd,0xee,0x02,0x76,0xfd,0xf0,0x57,0x28,0x05,0xcd,0x05,0xea,0x44,0x3d,0x60,0x02,0xa6,0xdc,0xc1 +,0x20,0x11,0x2c,0x02,0x80,0x38,0xff,0xf1,0x50,0x80,0x2c,0x7f,0xfc,0x21,0x0a,0xcf,0xef,0xff,0xfe,0xff,0xfc,0xb0,0x70,0xb0,0x90,0x2c,0x13,0x0b,0x0a,0x02,0x82,0x70 +,0xb0,0x5c,0x2a,0x14,0x09,0x05,0x08,0x44,0x41,0x08,0x8c,0x22,0xd7,0x33,0x8c,0xeb,0x9e,0x3d,0xfd,0xb6,0xbc,0xba,0xf3,0xd9,0x15,0xad,0xea,0xb8,0xcf,0xbf,0xbd,0x3c +,0xf7,0x3a,0x23,0xff,0x3b,0x15,0xeb,0x75,0x76,0xfd,0x2c,0xfa,0xa6,0xc4,0xfc,0xf7,0x07,0x8f,0xfd,0xd2,0x57,0x25,0xd0,0xe4,0x7c,0x6b,0x51,0x16,0x8f,0x7f,0xab,0xd8 +,0x78,0xc1,0xc6,0x4d,0xcf,0x7c,0xb5,0x7c,0xf8,0x3a,0x84,0xc8,0xbf,0x4e,0xf9,0xf2,0xdb,0xaa,0x8b,0x45,0x8f,0xdf,0x97,0x15,0xa9,0xa1,0x9e,0x88,0x23,0xf6,0x4f,0xaf +,0x13,0xb7,0x70,0xa7,0x82,0x73,0xf6,0x7b,0xea,0xe4,0xe3,0xcf,0x01,0x06,0x49,0xd5,0x30,0xf5,0xc2,0xad,0x64,0xe3,0xd6,0x01,0x7a,0x0a,0xb9,0xb9,0x56,0xc4,0xc0,0xb2 +,0x53,0x0a,0x17,0xd9,0x69,0x80,0x9a,0x72,0x10,0x05,0x51,0xa0,0x00,0xb0,0x07,0x32,0x60,0x52,0xa0,0x58,0x4e,0x14,0x0a,0x85,0x84,0x81,0x60,0xa8,0x50,0x2a,0x14,0x0b +,0x06,0x02,0x81,0x60,0xa0,0x58,0x28,0x26,0x12,0x05,0x46,0x64,0x10,0x98,0x48,0x22,0x87,0x77,0x89,0x26,0xf4,0xc5,0x24,0xaa,0x84,0x95,0x17,0x1d,0x34,0xf0,0xff,0x4f +,0x1a,0xf7,0xfc,0x7f,0x8f,0xb8,0xfc,0xdd,0x7e,0xcf,0x5d,0x1d,0xb3,0xee,0x8f,0x77,0x29,0x0f,0x9f,0xc5,0xb8,0xb7,0xd1,0xc4,0xfb,0x47,0x75,0xf1,0x7c,0x9f,0xec,0xe7 +,0x3d,0xa7,0x17,0x80,0x9d,0x38,0xc9,0x7f,0xe9,0xb9,0x14,0x2a,0x97,0xe4,0x9a,0x80,0x19,0xe7,0xd0,0xa2,0xa2,0x03,0x3e,0x30,0x02,0xc7,0x9b,0xe6,0x91,0x85,0xca,0x5c +,0xe4,0xa8,0xc4,0x84,0xaa,0x39,0x7e,0xcc,0xc9,0xed,0xe0,0xe5,0x4b,0x9f,0xc5,0xcb,0xe7,0x6a,0x0e,0x18,0xe0,0xa9,0xe1,0x69,0xe6,0xe3,0x65,0xe4,0xe6,0x3c,0x58,0x3b +,0x9a,0x0f,0xff,0xd9,0xdc,0xb8,0x7d,0x7c,0x1d,0xc1,0x39,0xfb,0x80,0x14,0x41,0xcb,0xd7,0xf5,0x80,0x23,0x18,0xc9,0x21,0x42,0xda,0x6d,0x6c,0x51,0x08,0x02,0xe0,0x05 +,0x16,0x42,0xc1,0x10,0x2a,0x40,0x05,0x40,0x70,0xff,0xf1,0x50,0x80,0x2b,0x9f,0xfc,0x21,0x0a,0xcf,0x7e,0xfb,0xef,0xff,0xfd,0xb1,0x62,0x28,0x48,0x2a,0x17,0x0b,0x0d +,0xc4,0x81,0x51,0x20,0x54,0x28,0x12,0x0a,0x0d,0x42,0x81,0x21,0x18,0x45,0xed,0xbf,0x1e,0xfe,0x77,0xde,0xa7,0xdf,0xf6,0xbd,0x61,0x26,0x5d,0xee,0x44,0xf8,0xdd,0x25 +,0x4c,0x9d,0x65,0xf1,0x9f,0xf9,0x7f,0x91,0x7f,0xbb,0x8f,0xdb,0x47,0xeb,0xd5,0x4f,0xb1,0xd4,0xe2,0xf2,0xf5,0xae,0x83,0x4f,0xc5,0x7e,0xff,0xa2,0x56,0x94,0x3c,0xa4 +,0xfe,0x6d,0xe9,0x38,0xf9,0xb7,0x1c,0x98,0x0f,0xcf,0x28,0x9d,0xf1,0xaf,0x25,0x7f,0xea,0xfb,0x03,0xfa,0xe6,0x5a,0xd9,0x15,0x77,0x0d,0x62,0xfc,0xec,0x4b,0x1d,0xad +,0x76,0x64,0xe3,0x0f,0xf9,0x2d,0xb9,0x6f,0x2f,0x43,0xb6,0xb4,0xd0,0xf0,0x7e,0xe5,0x02,0xb3,0xa9,0x37,0x38,0xd8,0x84,0xc5,0x4b,0x7d,0x42,0x64,0xe4,0x45,0x38,0x8a +,0x4d,0x58,0x86,0x06,0xb5,0x76,0x2e,0xb3,0x7a,0xf5,0x13,0x0b,0x8b,0x85,0x53,0x04,0x40,0x7d,0x80,0x1b,0xc2,0x60,0x54,0xa0,0x58,0xca,0x16,0x0a,0x85,0x86,0x81,0x61 +,0x20,0x94,0x2c,0x14,0x0a,0x85,0x82,0x82,0x30,0xa9,0x0c,0x22,0x13,0x10,0x88,0xc2,0x25,0x00,0xb2,0x77,0xf8,0xbf,0xcf,0x15,0xc7,0xaf,0x8f,0x17,0x8a,0xb8,0xc8,0x5a +,0x75,0x95,0xc7,0xb7,0xbc,0xe2,0xef,0xe2,0x73,0x7f,0xee,0x3f,0x47,0x6f,0xeb,0x64,0xfa,0x69,0xf7,0x25,0x1d,0x3f,0x03,0xda,0xe3,0x1e,0x84,0x99,0x97,0xcf,0xe8,0xde +,0x52,0xd8,0xeb,0x7d,0xff,0xc1,0xf3,0xbe,0x2e,0x77,0x7f,0x0d,0x27,0xbf,0x78,0x1f,0xdc,0xda,0xbb,0xef,0x81,0xc2,0xa2,0xf8,0x4e,0x05,0xd0,0xf9,0xd9,0x6e,0xe4,0xf5 +,0xf7,0x57,0x12,0x6a,0x54,0x95,0xca,0x3a,0xdc,0x82,0x71,0xd4,0x17,0xe9,0xc9,0xfd,0x8c,0xbf,0xd7,0xfb,0x66,0xe2,0x04,0xf4,0x24,0xbb,0xed,0x91,0xca,0xec,0x3c,0x41 +,0x36,0x6c,0x72,0xe6,0x35,0x8e,0x64,0x27,0x82,0x16,0x2a,0xb9,0x7f,0x22,0x21,0x10,0xaa,0xa7,0xac,0x62,0x1e,0xc4,0x17,0x15,0xb2,0x92,0x01,0xeb,0x80,0x20,0x00,0x5a +,0x60,0x09,0x82,0x60,0x38,0xff,0xf1,0x50,0x80,0x2b,0x7f,0xfc,0x21,0x2a,0xcf,0x9f,0xf4,0xbe,0xff,0xff,0xb1,0x62,0x28,0x90,0x2c,0x17,0x0a,0x05,0x84,0x81,0x50,0xa0 +,0x58,0x28,0x16,0x12,0x04,0x82,0x82,0x21,0x20,0x46,0x2d,0xbd,0xb7,0xf5,0xcf,0x75,0xe7,0xb9,0x2d,0xcd,0xd2,0x6b,0x24,0xab,0x2f,0x50,0x51,0x35,0x1f,0xfe,0x56,0x3e +,0x57,0xf1,0xf2,0x63,0xee,0xdf,0xe1,0xea,0x74,0x38,0x8b,0xf9,0xfb,0x56,0x98,0xa2,0x74,0xe5,0xa7,0x38,0x1f,0x47,0xbd,0xf3,0xbc,0xb7,0x69,0xb9,0x9d,0xe9,0x8e,0x8e +,0x7a,0x92,0x9d,0xa8,0xba,0x22,0x40,0x3e,0x61,0xb3,0xbf,0x57,0xdd,0x20,0x8c,0x5b,0xcc,0xef,0xab,0x97,0xc1,0x7c,0xd9,0x6e,0xc2,0x35,0x37,0x07,0xf1,0x6f,0x87,0x07 +,0x18,0xb5,0xd4,0xfd,0x33,0x1f,0x94,0x6b,0x39,0xa1,0x7c,0x31,0x29,0x81,0x50,0x6c,0xa1,0x1a,0x04,0xc4,0x68,0x4a,0xc2,0xd5,0x04,0x84,0x6b,0x10,0x15,0x8c,0x66,0x28 +,0x01,0x18,0x86,0xc0,0x0b,0x54,0x09,0x8a,0x81,0x3b,0x00,0xa7,0x50,0xb0,0xd0,0x2c,0x24,0x0a,0x85,0x84,0x81,0x60,0xa0,0x48,0x2a,0x14,0x0b,0x05,0x04,0xc1,0x41,0x30 +,0x50,0x64,0x13,0x10,0x98,0xc4,0x24,0x00,0x9e,0x26,0xb7,0x69,0x57,0xba,0x9a,0xcc,0x85,0xaa,0xeb,0x5b,0xd5,0xd4,0xba,0xba,0x7c,0x4d,0x6f,0x7f,0xfc,0x87,0xad,0xfd +,0xdc,0x6e,0xfa,0x5d,0xfb,0x99,0xf9,0x76,0xa7,0xcf,0xfc,0x1a,0x47,0x4c,0xb5,0x46,0x90,0xfc,0xd6,0xd1,0xc9,0x7f,0x61,0xf7,0x8f,0xd7,0xe2,0x3f,0xab,0x7c,0x7b,0xf0 +,0x94,0x24,0x5f,0xe4,0x9c,0xff,0xf4,0xaf,0x84,0x74,0x1d,0x37,0xcd,0x98,0xed,0x1f,0xd3,0x6c,0xfc,0xef,0x9d,0xee,0x3a,0x87,0x41,0x2f,0xb1,0xd1,0x79,0x18,0x92,0x42 +,0xa6,0xfb,0xe7,0x9b,0xab,0x35,0xdf,0x6a,0x13,0x99,0xda,0x62,0xb8,0xcb,0x3f,0x39,0xb1,0xdd,0x02,0x03,0x0d,0xdb,0xe6,0xb8,0xe0,0x9a,0xde,0xd7,0x05,0x2d,0xa6,0x16 +,0x7e,0x28,0x77,0x44,0x9a,0x13,0x87,0x71,0x2b,0x41,0xa0,0x6b,0x25,0x92,0xb4,0x63,0x82,0xc5,0xe7,0x15,0x43,0xbc,0x03,0xd7,0x01,0x30,0x0a,0x96,0x51,0x50,0x98,0x0e +,0xff,0xf1,0x50,0x80,0x2f,0x1f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x45,0x18,0x2d,0x11,0x11,0x52,0x29,0xa1,0x72,0x2a,0xec,0x61,0x96,0x3f,0xac,0x21,0xc4,0xc3,0xab,0x8a +,0x2f,0x50,0x97,0x12,0x37,0xa1,0x34,0x11,0x1c,0x48,0x47,0x49,0x71,0x60,0x3c,0x14,0xe7,0x24,0x73,0x3b,0x2e,0xb5,0x29,0xf0,0xff,0x54,0xd1,0x0b,0x74,0x99,0xd3,0x25 +,0xd5,0x26,0x77,0x88,0xf5,0xbe,0x65,0x3e,0x0c,0xf2,0xc4,0xe0,0xf7,0x5e,0xf7,0x9e,0xea,0x9e,0x75,0x16,0x69,0x52,0xd1,0x74,0xe7,0x5b,0xd1,0x99,0x2a,0xa8,0x98,0x03 +,0xc8,0x34,0xcb,0x03,0x42,0x75,0xd6,0xc4,0xd5,0x21,0xc3,0xfc,0xcd,0xbd,0x61,0x9e,0xbb,0x71,0xf7,0x35,0x6c,0x99,0x5a,0xa5,0x56,0xad,0xef,0xdd,0xb5,0xfa,0x74,0xbc +,0xe3,0x0a,0x40,0x04,0xc8,0x1c,0xe9,0x6a,0x27,0x0c,0xa3,0x99,0x35,0x99,0x1e,0x5d,0xef,0xcd,0xba,0x46,0x01,0x29,0x2a,0xda,0x4a,0xa6,0xa0,0x27,0x49,0x73,0xc5,0xb7 +,0x14,0xe0,0xb6,0xc6,0x03,0x5a,0x69,0xde,0xd0,0x9e,0x98,0xb6,0x4e,0xdd,0x17,0xa8,0xb8,0xf5,0x0d,0x03,0xc2,0x3d,0x83,0x36,0x01,0xa0,0xa2,0x82,0xc6,0x0b,0x34,0x6a +,0x45,0x0a,0x93,0x44,0xbe,0x82,0x53,0xe6,0x13,0x38,0x3e,0x3b,0x52,0x1f,0x80,0x9d,0xe8,0x32,0xed,0x72,0xf6,0xe7,0xe9,0xbf,0xb3,0xc7,0xd3,0xd7,0x4f,0xd6,0xfc,0xe5 +,0x70,0xd5,0x57,0x52,0x28,0x51,0x89,0xc7,0x52,0x6f,0x61,0x16,0x21,0x9d,0xda,0x9f,0x51,0xdb,0xdd,0x97,0x6a,0x7b,0x0b,0xaf,0x0f,0x7e,0x7e,0x7b,0x66,0x7e,0x9a,0xe7 +,0xea,0xa1,0x69,0x7e,0x78,0x2a,0x48,0x73,0xf0,0x31,0xbd,0xdd,0x4b,0x35,0xbb,0x55,0x95,0x5d,0x3f,0x6a,0x4b,0x2e,0x0b,0x51,0x88,0xac,0xc9,0x2e,0xe8,0x35,0x2f,0x61 +,0xf9,0xa1,0xe9,0x5f,0xcf,0x90,0x61,0x2a,0x91,0xfd,0x8a,0xc2,0xd5,0xdb,0xbf,0x43,0xc9,0x1c,0x4b,0x61,0xa0,0xb2,0x79,0x74,0xfd,0x9d,0x26,0xb2,0x55,0xa0,0x6d,0xdb +,0x4d,0x63,0x62,0xbe,0x14,0xd8,0x35,0x3f,0xdf,0xdb,0x97,0x38,0x9b,0x3c,0xee,0x66,0x80,0xe4,0xa5,0x6a,0xeb,0x83,0x57,0xb9,0x09,0x26,0xe4,0xe0,0x6f,0x77,0x84,0x6d +,0x70,0x41,0x72,0x70,0x9c,0x62,0x4e,0xfa,0x2f,0xa7,0x34,0x71,0xa1,0x34,0x44,0xc4,0x04,0x44,0x44,0x0b,0x54,0xc5,0x13,0x80,0xff,0xf1,0x50,0x80,0x2d,0xdf,0xfc,0x21 +,0x4c,0xfe,0xf7,0xfd,0x4d,0x16,0x28,0x59,0x23,0x22,0x64,0x49,0x96,0xa6,0xf8,0x95,0x2f,0x2f,0x43,0x10,0x46,0x88,0x07,0xe0,0x34,0xb0,0xba,0xc1,0xce,0xc0,0xd2,0x83 +,0x50,0x5f,0xa2,0x99,0x92,0xd5,0xcc,0xf6,0x55,0x32,0xe4,0xf7,0x63,0xd9,0x73,0x3e,0xa7,0xfa,0x93,0xfe,0x5f,0xf4,0x7f,0xc8,0xfb,0xf9,0xb2,0x35,0xf6,0x78,0x15,0x8d +,0xa3,0xab,0x72,0xa9,0xcd,0xc6,0x0a,0x41,0x4a,0x16,0xd5,0x03,0x2b,0x3d,0x7d,0x41,0xfe,0xeb,0x8c,0x2e,0x52,0xfa,0x32,0x99,0x73,0xff,0x5b,0xd1,0x5b,0x05,0x5d,0x77 +,0x23,0x39,0xed,0xa3,0xef,0x2f,0x92,0xa2,0x36,0xd1,0x2b,0xd8,0x87,0x60,0x60,0x3d,0x55,0xac,0x9b,0xf3,0x86,0x56,0x13,0x24,0x00,0x56,0x1d,0x5a,0x0e,0x66,0xce,0x1c +,0x43,0xbf,0x64,0xa7,0x48,0xc1,0x83,0xc3,0x21,0xc3,0xa2,0xb6,0x92,0x3a,0x2b,0xcf,0xd6,0xd3,0x9d,0x6b,0x7f,0x96,0xa4,0xf4,0x8b,0xd2,0x54,0xa4,0xe4,0x52,0x92,0x93 +,0xa0,0x92,0x54,0x77,0x83,0x0d,0x7d,0xc3,0x16,0x91,0x5a,0x94,0x15,0x18,0x28,0x54,0x2a,0x51,0x41,0x6a,0x84,0xca,0x11,0x68,0xcb,0x97,0xe7,0xc4,0xe0,0x2e,0x6f,0xa9 +,0x9e,0xa3,0x1a,0x7b,0x54,0x5a,0x80,0xfa,0x4b,0x09,0xf1,0x75,0xcb,0xf8,0xe9,0xfd,0x95,0xe1,0xf2,0x1a,0xe5,0xd3,0x1b,0x3b,0xfd,0xc5,0xbb,0xc6,0x8d,0xf7,0x49,0x4d +,0x95,0xd0,0xd2,0xed,0x97,0x0b,0x97,0xcf,0xd5,0xd3,0x3e,0xbf,0x8d,0x98,0xeb,0x1f,0xbf,0xee,0x56,0x5a,0x35,0xd9,0x86,0x35,0xc1,0x01,0x7e,0x37,0xe5,0x3d,0xda,0x75 +,0x41,0xf8,0xb0,0xdc,0xe4,0xd4,0x67,0x55,0x43,0xc0,0x64,0x35,0x31,0x3f,0x22,0xa5,0x88,0x15,0x7a,0xe3,0x62,0x41,0x8c,0xed,0x9d,0x3e,0x81,0xe9,0xb3,0x63,0xf1,0xbd +,0x2e,0xf1,0x8f,0xfd,0x8f,0x77,0x7b,0x44,0xd3,0x4d,0x3d,0xb1,0x0d,0x10,0x9d,0x70,0x86,0x94,0x5e,0x41,0xec,0x17,0x15,0x45,0xdd,0xca,0x16,0xac,0x85,0x2e,0x10,0x2f +,0xeb,0xaa,0xbd,0x72,0x54,0xf4,0xf6,0x4b,0xa3,0x3a,0xf9,0xf9,0xec,0x75,0xad,0xfe,0xb7,0xc3,0x78,0xdc,0xb9,0x02,0x25,0xcb,0x93,0xcb,0x62,0x82,0x55,0x29,0x52,0x56 +,0x29,0x62,0x53,0x36,0xd4,0xe0,0xff,0xf1,0x50,0x80,0x2b,0xbf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x44,0x26,0x49,0x0c,0x89,0x34,0xd2,0x42,0x24,0xd0,0xff,0x01,0xd5,0x9f +,0x22,0x3e,0xec,0xbe,0x54,0xfd,0xc3,0x78,0x5b,0xb7,0xaf,0xce,0x84,0xa3,0x34,0x69,0xf7,0xab,0x9f,0x5a,0xac,0x94,0xd4,0x2a,0x69,0x65,0x36,0x72,0x8c,0x26,0x2e,0x72 +,0xf5,0x8e,0xa9,0xb2,0x90,0x78,0x48,0x78,0xb8,0x0c,0x4d,0x90,0x37,0x4b,0x2f,0xe0,0xf5,0xd8,0x0f,0xd7,0x4f,0xe8,0xbd,0x8b,0x52,0xdf,0x6b,0x9b,0xe8,0xe1,0xb0,0xb2 +,0x78,0x2c,0x49,0x00,0x0e,0x9b,0xe2,0xbb,0x8d,0x0e,0x69,0x5a,0x98,0x4c,0x97,0xfc,0x6a,0xde,0x12,0xe2,0x67,0xe8,0xa6,0xb2,0xff,0x71,0x9a,0x3c,0xb6,0xaa,0x40,0xd8 +,0xf3,0x56,0x79,0x5a,0x47,0x09,0xeb,0x34,0xfa,0xf7,0xd4,0x6e,0xea,0x79,0xaf,0xfe,0xeb,0xab,0x52,0xae,0x91,0x76,0xf3,0x11,0x96,0x57,0x2b,0xb6,0x09,0x73,0xb5,0x63 +,0x5d,0xfd,0xb1,0x35,0xdb,0xe9,0x0c,0x91,0xa5,0x63,0x5f,0x0c,0x29,0xd5,0xc2,0xa2,0xca,0x6a,0x2b,0x8e,0x04,0x71,0x1d,0xda,0x91,0xc0,0x47,0x10,0xa8,0xa0,0x14,0x50 +,0x59,0xc1,0x64,0x68,0x49,0x91,0x28,0xa8,0xd6,0xa7,0x1d,0x50,0x93,0x60,0x41,0xff,0x4b,0x0a,0x4c,0xea,0x58,0x86,0xbf,0xd4,0xa1,0x3a,0x6f,0xf7,0x1a,0xde,0xc9,0x38 +,0xd7,0x21,0xf8,0x4f,0x1b,0x3e,0xfd,0x77,0x49,0xe8,0xb3,0x2e,0xec,0x2e,0x2b,0xaa,0xca,0xb9,0xb0,0xeb,0xea,0xcb,0xc2,0xe9,0x25,0xdf,0x47,0x34,0xfc,0xf2,0xa1,0x7d +,0x3a,0x73,0x1a,0x5a,0x0b,0x49,0xe5,0x12,0x39,0x03,0x29,0x51,0xa6,0x4f,0x12,0x47,0x61,0xc8,0xdd,0xbc,0xd0,0x2f,0x6e,0x24,0xb7,0x35,0x14,0x75,0x29,0xc9,0xdf,0x50 +,0x53,0x3f,0x30,0xa0,0xd8,0x16,0xd6,0x5d,0xa0,0xe5,0x3a,0x48,0x16,0x01,0xa0,0x1b,0x3d,0x2e,0x8a,0xf5,0x11,0x59,0x68,0xfd,0xf4,0xf5,0x37,0xab,0x3e,0xf0,0x69,0xc3 +,0x59,0xb9,0xf6,0xb0,0x9f,0xe4,0x9d,0x72,0x44,0x87,0x02,0x79,0xd3,0xc8,0xdb,0xfd,0x74,0xf6,0xca,0x00,0x00,0x22,0xf5,0x68,0xb0,0x80,0x00,0x19,0xf7,0x96,0xc8,0x00 +,0x00,0x00,0x70,0xff,0xf1,0x50,0x80,0x28,0xbf,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x4c,0x16,0x68,0x58,0xaa,0x22,0x28,0xcb,0x8a,0x91,0x25,0xc9,0xe4,0x7d,0x15,0x7b,0x52 +,0xfc,0xf8,0xf7,0x4d,0xf3,0x67,0xc4,0xbf,0x9c,0x5e,0x95,0xfc,0xef,0xb4,0x2c,0x3a,0x66,0xf4,0xd8,0x65,0x2d,0xde,0x33,0x5b,0x56,0x38,0x50,0x76,0x4d,0x3e,0x31,0x34 +,0xfd,0xf8,0x61,0x91,0xd9,0xb4,0x68,0xc5,0x8c,0xa9,0x04,0xa6,0x34,0x7e,0xe3,0xf0,0x9c,0xa2,0xee,0x94,0x08,0x2c,0x18,0x00,0x76,0x12,0x45,0xae,0x40,0x6d,0x91,0x5d +,0x2c,0x2a,0x08,0x3b,0xa8,0x10,0xff,0xca,0xa2,0xca,0xb8,0x77,0x65,0x99,0x82,0xa6,0x57,0x83,0x1a,0xf3,0xae,0x7d,0x7c,0x6b,0x1d,0x9f,0x6e,0xee,0xcb,0x8d,0xd2,0x24 +,0xdd,0xcd,0xaf,0x50,0x52,0x51,0xcf,0xa3,0xec,0xa7,0x84,0xec,0x52,0x81,0xfb,0x09,0x29,0x31,0xce,0x13,0x4c,0x78,0x31,0x68,0x7a,0x73,0x4f,0x1b,0x84,0xd6,0x9a,0xd3 +,0x64,0x9a,0xfc,0x17,0x99,0x02,0x13,0x44,0x8d,0xd0,0x9a,0x02,0x08,0xe1,0x05,0x40,0x00,0x08,0x8c,0xfe,0x29,0x47,0x0d,0x9a,0x13,0x62,0x4c,0xae,0x92,0x6a,0xfe,0xba +,0xab,0x12,0xe6,0x51,0xe3,0xf1,0x31,0x6c,0xe4,0x5e,0xc9,0xe3,0xe4,0x45,0xdb,0x49,0x2d,0xb8,0xe5,0xec,0xd2,0x05,0x54,0xf2,0xe0,0x14,0x63,0x32,0x8c,0x99,0xa1,0x1e +,0x02,0x30,0x48,0xaa,0x69,0x55,0x6f,0x02,0x5e,0x8d,0x74,0x71,0xf2,0xdb,0xdd,0x75,0x6b,0x66,0xf9,0xa6,0xd3,0x27,0x05,0x59,0xa8,0x9b,0xb5,0x5f,0x3d,0x7d,0xb4,0xc0 +,0x63,0xc6,0xa9,0xa4,0x49,0xf1,0x16,0x5e,0xb4,0x99,0x1b,0x45,0x20,0x15,0xa6,0x45,0x45,0x3a,0x1e,0xd3,0x4c,0x31,0x8e,0xc9,0x41,0x6f,0xc6,0x97,0xd5,0x2b,0xe0,0x6a +,0xdc,0xd7,0x33,0xec,0x1d,0x2f,0x9e,0x3d,0xb3,0x4d,0xee,0xbc,0xf1,0xeb,0x0f,0x34,0xcb,0xfe,0x9d,0x2d,0xa4,0x80,0x00,0x00,0x00,0x03,0x48,0xf6,0xc0,0x00,0x02,0x90 +,0x53,0x40,0x00,0x00,0x01,0x11,0xe2,0x9c,0xff,0xf1,0x50,0x80,0x2a,0x5f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x4c,0x16,0x48,0x59,0x21,0x22,0xa4,0xc8,0xa6,0xa5,0x5c,0x48 +,0xb8,0x2b,0xab,0xb7,0x05,0x59,0x97,0x39,0x5f,0x2d,0xb7,0xf9,0x2b,0xc9,0x16,0x89,0xa9,0x68,0xce,0x6c,0x3e,0x92,0xcd,0x82,0x2c,0xbb,0xd6,0x4a,0xe9,0x62,0xe9,0xa4 +,0xf4,0x4a,0x94,0xdf,0xe1,0x1f,0x08,0x8f,0x8f,0xfe,0x63,0xe0,0x5a,0xec,0x7f,0xe3,0x76,0x6f,0xa6,0x57,0xda,0x86,0x2b,0x8d,0xf6,0xa9,0x0c,0xa8,0x23,0x28,0x15,0x0a +,0x00,0x96,0x91,0x5e,0x8c,0x02,0x88,0x85,0xc4,0x46,0x24,0x20,0x67,0xba,0xf7,0xf1,0x7c,0x8d,0x70,0xbe,0x58,0x70,0x1c,0x8e,0x20,0xd8,0xc5,0xda,0x30,0x23,0x1b,0x0f +,0xf4,0x96,0x16,0x45,0x43,0x9c,0xdc,0x03,0x9e,0x49,0x4d,0x97,0x44,0xc1,0x25,0xd6,0x87,0x36,0xae,0x52,0x9c,0xcc,0x8d,0x72,0x6d,0x99,0x99,0x50,0x3d,0x79,0x35,0x85 +,0x9e,0x60,0xd7,0xcd,0x5d,0x6c,0xad,0x71,0xd2,0xe7,0x32,0x24,0xa0,0x42,0x9f,0x68,0x10,0x3a,0xcc,0xc1,0x02,0x41,0x84,0x86,0x82,0x51,0x02,0x17,0x28,0xe8,0xb5,0x42 +,0xa4,0xc8,0x93,0x22,0x57,0x55,0x2e,0xf8,0xea,0xa5,0x04,0x4c,0xd4,0x57,0xdb,0x89,0x44,0x23,0x0c,0x77,0x74,0x30,0x8e,0xe8,0x8d,0x75,0x46,0x1a,0x71,0xd9,0x86,0xed +,0x7d,0x71,0x87,0x66,0xf2,0x7d,0x9d,0xb6,0x5f,0xaa,0xa2,0xf6,0xcf,0x76,0x6f,0x67,0xc3,0x2f,0xa7,0xde,0x9b,0x2b,0xf7,0xf7,0x1f,0x5c,0xd8,0xdb,0xbb,0x33,0xbf,0xaf +,0x56,0x35,0x33,0x99,0x9f,0xf2,0x32,0x60,0xd1,0x35,0x34,0x19,0xb5,0x55,0x33,0x8d,0xa5,0x54,0x82,0x32,0xe7,0x52,0x51,0xba,0x9b,0xc6,0x9a,0x9c,0x20,0xa2,0x42,0xad +,0x76,0x79,0xf4,0x9d,0x21,0x75,0xf9,0x2b,0xec,0xd9,0xd0,0xec,0x61,0xfd,0xfb,0xa8,0x31,0x05,0x8b,0xe4,0x39,0x14,0x52,0x11,0x88,0x00,0x05,0xc1,0x3c,0x6d,0xdf,0xf5 +,0x5e,0x33,0x21,0x90,0xb9,0x72,0xe6,0x92,0xe6,0x92,0x24,0x40,0x3b,0xa9,0xc5,0x32,0x70,0x30,0x8b,0x89,0x8b,0x89,0x8b,0x89,0x8d,0x07,0xff,0xf1,0x50,0x80,0x2b,0x1f +,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x4c,0x16,0x88,0xc8,0x99,0x14,0xd1,0x24,0xb5,0xdd,0x8c,0x56,0xbd,0x16,0xbd,0xe9,0x57,0x67,0xc3,0x3b,0x10,0xaa,0xd4,0x3e,0xf8,0x5f +,0xb8,0x64,0xc7,0x35,0xfc,0x4d,0x64,0xc5,0xd7,0x5e,0x39,0xe7,0x77,0xe2,0xc9,0x0e,0xa7,0xcf,0x0c,0xeb,0x92,0xa0,0x80,0x8c,0x39,0x70,0x1a,0xb2,0x77,0xf0,0x5d,0x0f +,0x96,0x7a,0x11,0xa7,0x53,0x60,0x98,0x38,0x2e,0xa3,0x66,0xe7,0xfc,0xdb,0x88,0x9f,0x45,0xbf,0x7c,0x59,0x0a,0x24,0xbc,0xdc,0x2f,0xa3,0xb7,0xfa,0x36,0xbe,0x7a,0x13 +,0x6e,0x74,0xe5,0xbb,0x5f,0xff,0xa1,0xd2,0xa9,0xf9,0x9b,0x21,0x93,0x92,0x3a,0x7f,0x50,0x2b,0x3a,0xcd,0x3b,0xe4,0x72,0x9c,0x88,0xe5,0xc9,0x70,0x42,0x97,0xea,0x30 +,0x8c,0x5f,0xf7,0x52,0x66,0x20,0x4c,0xc0,0x28,0x5c,0x5d,0xde,0xb4,0xdc,0x13,0x70,0xcf,0xbf,0x25,0x81,0x04,0xe0,0x84,0x13,0x82,0x24,0x0a,0x21,0x5b,0x0c,0xc5,0x62 +,0x6e,0x09,0x8b,0x80,0x99,0xba,0xe5,0x1c,0x16,0xaa,0x4c,0x91,0x32,0x29,0x74,0x8b,0xd3,0xcd,0x40,0x0d,0xfe,0x18,0xed,0x2a,0xe9,0x60,0x29,0x9f,0xd4,0x82,0x2b,0xf9 +,0x52,0xba,0x5b,0x14,0x7f,0x7f,0x73,0xe7,0x2d,0xf4,0x96,0xae,0xec,0x76,0xfa,0x66,0xfc,0x0f,0xbe,0xfb,0x38,0xf6,0x7f,0xfa,0xb5,0x75,0xab,0x78,0x68,0x29,0xbe,0xd3 +,0x7d,0xbb,0x7d,0x55,0x9d,0xb7,0x6f,0x97,0x9d,0x33,0x76,0x7a,0x6b,0xdc,0x57,0xcb,0x45,0xd5,0x55,0xc0,0xf6,0xa4,0xb6,0x4d,0x52,0x2a,0xaa,0x04,0xc3,0xa9,0xef,0x41 +,0x37,0x4d,0xfb,0xbd,0x69,0xde,0xd3,0x04,0xb3,0x54,0x0e,0xbe,0xc8,0xae,0x7c,0x59,0xed,0xe5,0x35,0xe9,0x4e,0x75,0xd0,0xbb,0x2f,0xb2,0x57,0x16,0xfb,0x78,0x6f,0xe1 +,0xbe,0x85,0x61,0xcb,0x74,0x87,0xb2,0x60,0x0f,0x60,0x39,0xad,0xa7,0xd9,0x54,0xce,0x29,0xe6,0x55,0x3e,0x20,0x75,0x34,0x3c,0x49,0x33,0xbc,0x67,0x32,0x19,0x8c,0xa4 +,0x89,0x98,0x0c,0xc6,0x60,0x79,0xc1,0x63,0x22,0xc2,0x23,0x90,0x88,0x88,0xd8,0x22,0x2a,0x38,0xff,0xf1,0x50,0x80,0x25,0x1f,0xfc,0x21,0x4c,0xfe,0xff,0xfd,0x2c,0x98 +,0x2e,0x56,0x1a,0x12,0x64,0x4a,0x4a,0xd2,0xe1,0x70,0x7f,0x2b,0xa5,0xdc,0xb6,0xfe,0x8e,0xf3,0x1c,0x0d,0x6e,0x30,0x18,0xcd,0x67,0xd2,0x94,0x5c,0xe1,0x34,0xd3,0x9c +,0xe7,0x39,0xdd,0x5e,0xde,0x36,0x9f,0xcb,0xd5,0xe9,0xc3,0x4b,0x20,0x3d,0xbd,0xdf,0xc3,0xe8,0xf8,0xfe,0xce,0xac,0x67,0x20,0x7d,0x1f,0x08,0xce,0xbb,0xfd,0x9d,0xe0 +,0x1e,0x9d,0x7c,0x9d,0x3b,0xc7,0x0f,0x87,0xa7,0x72,0xe3,0xcf,0x83,0x39,0x80,0x00,0xc7,0x64,0x74,0x4f,0x54,0xf3,0xcf,0x1a,0xc7,0x0b,0x8e,0xa5,0x40,0x00,0x38,0xbd +,0x4e,0x51,0x7c,0x53,0xa3,0xfd,0x31,0x84,0x0e,0xef,0xa2,0x9c,0x35,0xfa,0xdd,0x8f,0x8c,0x6b,0x5e,0x5b,0xb0,0x00,0xf3,0x57,0x1c,0xb2,0x7c,0xa6,0xfb,0x7d,0x23,0xcc +,0x00,0x24,0x7e,0x36,0x35,0x8b,0x53,0xe9,0xa0,0x00,0x75,0x98,0x89,0xd2,0xa7,0x8e,0x26,0x20,0x00,0x14,0x32,0x5e,0x29,0x32,0x25,0x49,0x91,0x48,0x2e,0xfd,0x93,0x41 +,0xe9,0x11,0xf7,0x3e,0xe9,0xeb,0x3d,0x7f,0xcb,0xba,0x05,0x01,0xc0,0xf4,0x1e,0xb7,0x69,0xe0,0xeb,0xee,0xed,0x79,0x5d,0x50,0x1a,0xdf,0xc5,0xa9,0xea,0xf2,0xf0,0x3a +,0xb7,0x2b,0x20,0x35,0x3d,0x57,0xca,0xcf,0xc2,0xe3,0x72,0xef,0x29,0x03,0x3d,0x3f,0x7d,0xc2,0xf8,0xd8,0x7c,0xae,0x28,0x07,0xf3,0xeb,0xf6,0xbc,0x6b,0xd5,0x5a,0xfa +,0xa7,0x5c,0xfd,0xbe,0x3d,0x97,0x34,0x00,0x0f,0xb9,0xbf,0xaf,0xfb,0x5d,0xc7,0xf7,0x5f,0x13,0xb6,0xe8,0xe0,0x1a,0x1f,0x93,0x1b,0xfc,0x68,0xb8,0x0a,0xc7,0x86,0xe6 +,0x4b,0x6c,0x40,0x20,0x00,0x00,0x00,0x3c,0xc1,0x43,0x39,0xa6,0x00,0x06,0x69,0x31,0xc8,0x00,0x00,0xec,0x2c,0x28,0x31,0x00,0x00,0x0e}; + +static const int aac_sample_size=102075; + + +#endif diff --git a/USDK/component/common/media/framework/mmf_source_modules/sample_h264.h b/USDK/component/common/media/framework/mmf_source_modules/sample_h264.h new file mode 100644 index 0000000..5c169f3 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/sample_h264.h @@ -0,0 +1,34405 @@ +#ifndef SAMPLE_H264_H +#define SAMPLE_H264_H +static unsigned int h264_sample_len = 550338; + +#include "section_config.h" +SDRAM_DATA_SECTION static const unsigned char h264_sample[] = { + 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x0d, 0x9a, 0x74, 0x06, 0xc1, 0xef, 0x37, 0x80, 0x88, + 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x78, 0xa1, 0x55, 0x00, 0x00, 0x00, + 0x01, 0x68, 0xce, 0x3c, 0x80, 0x00, 0x00, 0x00, 0x01, 0x65, 0x88, 0x80, 0x20, 0x00, 0x55, 0xfc, + 0x31, 0xc0, 0x39, 0x47, 0x8a, 0x00, 0x02, 0x0d, 0x5e, 0xfc, 0x57, 0xc7, 0x63, 0x80, 0x00, 0x80, + 0x27, 0xff, 0xff, 0x0b, 0x15, 0xfa, 0xf1, 0xdb, 0xdb, 0xe3, 0xe3, 0xcc, 0x21, 0x45, 0xfa, 0xd5, + 0x78, 0xe6, 0x38, 0x3f, 0xf8, 0x78, 0xf0, 0x52, 0x24, 0x5f, 0xaf, 0x47, 0x67, 0x8a, 0x00, 0xec, + 0x9f, 0x4f, 0x1e, 0x50, 0xbe, 0x1d, 0x09, 0xe6, 0x7f, 0xb6, 0xdb, 0x6d, 0xff, 0x74, 0xd3, 0xff, + 0xf0, 0x02, 0x2f, 0xc1, 0x1d, 0xdf, 0xe2, 0x29, 0x7f, 0xfb, 0x7c, 0x68, 0x81, 0x0f, 0x1e, 0x1f, + 0xed, 0xfc, 0xbe, 0x0e, 0x08, 0x24, 0x18, 0x80, 0xef, 0x7a, 0xd7, 0xff, 0x86, 0x62, 0x3a, 0x09, + 0xbf, 0x7e, 0xfd, 0x78, 0xe9, 0x1c, 0x00, 0x08, 0xdf, 0xff, 0xff, 0xc2, 0xf5, 0xeb, 0xd1, 0xff, + 0xff, 0x87, 0x93, 0xff, 0x1f, 0xe0, 0x82, 0xbf, 0xff, 0x1f, 0xe0, 0x80, 0x8b, 0xff, 0x87, 0xc4, + 0x78, 0x4a, 0xbd, 0xf9, 0x39, 0x3f, 0xff, 0xfe, 0x08, 0x4a, 0xbc, 0x9f, 0xf8, 0x7c, 0x47, 0x87, + 0xef, 0xff, 0xe2, 0x3c, 0x78, 0x52, 0xbd, 0x7f, 0xfc, 0x43, 0x11, 0xe0, 0xa0, 0x8b, 0xd7, 0x8e, + 0xdf, 0xf8, 0x86, 0x23, 0xc1, 0x35, 0x7a, 0xf7, 0xff, 0xf1, 0xfe, 0x0a, 0x2b, 0xd7, 0x8e, 0xc7, + 0xff, 0xf8, 0xfe, 0x24, 0xab, 0xd7, 0xaf, 0xff, 0x8c, 0x7f, 0x0f, 0x0d, 0x17, 0xfc, 0x3e, 0x23, + 0x88, 0xf0, 0xf0, 0xc7, 0xe7, 0x90, 0x37, 0xe1, 0xd8, 0xff, 0x0f, 0xc7, 0x8f, 0x71, 0x7e, 0xbd, + 0x7a, 0xff, 0xff, 0x80, 0x70, 0xb1, 0x45, 0xfa, 0xf1, 0xdb, 0xff, 0x31, 0x18, 0x8f, 0x09, 0xdf, + 0xaf, 0xff, 0xc7, 0x8f, 0x55, 0xeb, 0xd7, 0xaf, 0x47, 0xc9, 0x87, 0xbd, 0xc3, 0xe2, 0x18, 0x07, + 0x09, 0x91, 0xfa, 0xff, 0xf8, 0x80, 0xc4, 0x43, 0x0b, 0xd7, 0xaf, 0x1e, 0x5f, 0xf8, 0x06, 0x23, + 0xc1, 0x15, 0xf8, 0xe9, 0x4f, 0x82, 0x25, 0xb9, 0xe6, 0x47, 0x6f, 0x0e, 0xcf, 0xf7, 0xc3, 0xe2, + 0x01, 0x11, 0xe1, 0xeb, 0xff, 0xf8, 0x06, 0x23, 0xc3, 0xd7, 0xff, 0xf1, 0x1f, 0xe4, 0x27, 0xff, + 0xff, 0xc1, 0x01, 0x57, 0xbf, 0xc3, 0xe0, 0x18, 0x80, 0x61, 0x62, 0x3f, 0x7e, 0x8f, 0xff, 0xc4, + 0x31, 0x1e, 0x08, 0xaf, 0xd1, 0xdf, 0xfc, 0x47, 0x11, 0xe1, 0x2b, 0xf7, 0xef, 0xbe, 0xf0, 0xdf, + 0xbf, 0xf1, 0xfe, 0x26, 0xbd, 0x7a, 0xf7, 0xcf, 0x2d, 0x1f, 0xff, 0xff, 0xc1, 0x20, 0xa5, 0x8b, + 0xf9, 0x57, 0xf8, 0x00, 0x77, 0x27, 0x42, 0x0d, 0xae, 0xaa, 0xa6, 0xc5, 0x3f, 0x93, 0x23, 0x15, + 0xc8, 0x38, 0x0f, 0x0e, 0x8b, 0xd7, 0xac, 0xd9, 0x76, 0x44, 0xb4, 0xf8, 0x62, 0x0f, 0x11, 0xe8, + 0x97, 0x5e, 0xb5, 0x6b, 0x4b, 0xf1, 0x1d, 0x08, 0x42, 0x40, 0x27, 0x68, 0xea, 0xaf, 0x06, 0x8a, + 0x05, 0x80, 0x73, 0x71, 0x87, 0xc2, 0x01, 0xa0, 0xbf, 0x7b, 0xf3, 0xa6, 0xa4, 0xd0, 0x0f, 0xc4, + 0x34, 0x11, 0x99, 0x11, 0x52, 0xaa, 0x71, 0x51, 0x1c, 0x6b, 0x86, 0x86, 0x3e, 0xfb, 0xa4, 0x0d, + 0x38, 0xdc, 0xbc, 0x5b, 0xb9, 0xb9, 0xbf, 0x57, 0x5e, 0x1a, 0x2a, 0xab, 0x89, 0xc7, 0xfa, 0xb5, + 0xf4, 0x70, 0xd9, 0x44, 0xeb, 0x4d, 0x3d, 0xb6, 0xf1, 0xfd, 0x41, 0xee, 0xe3, 0x85, 0x87, 0xaf, + 0x5e, 0x03, 0x45, 0x2c, 0xe4, 0x28, 0x71, 0xe8, 0xc4, 0xf8, 0x69, 0xe4, 0xac, 0xea, 0x1d, 0xf0, + 0xd1, 0x4c, 0x47, 0x11, 0xff, 0xd0, 0x24, 0xaf, 0x47, 0xda, 0xf8, 0x7c, 0x03, 0x00, 0xc8, 0x11, + 0x21, 0x52, 0x75, 0x0e, 0xf8, 0xa9, 0x8f, 0xfc, 0x7e, 0x40, 0x49, 0x5f, 0x95, 0xa8, 0x77, 0xcd, + 0x43, 0x4f, 0x7e, 0x25, 0x1f, 0x8d, 0x05, 0x2a, 0xba, 0xf8, 0x86, 0x01, 0xe3, 0xf4, 0x17, 0x3a, + 0xf5, 0xe3, 0x8c, 0x7e, 0x20, 0x30, 0x0f, 0x1f, 0xa0, 0xbd, 0x7a, 0xfe, 0xff, 0x1e, 0x3f, 0x40, + 0x98, 0x8b, 0xd7, 0x9d, 0x17, 0xdf, 0xff, 0xfa, 0x0b, 0xd7, 0xaf, 0x1c, 0x6f, 0xf1, 0xe3, 0xf4, + 0x0a, 0x08, 0xbd, 0x7b, 0x4e, 0x8b, 0xe9, 0xd7, 0xdf, 0xf8, 0x8f, 0xe8, 0x23, 0xe9, 0x49, 0x8a, + 0x58, 0x96, 0x94, 0xd3, 0x4d, 0x3f, 0xc7, 0x8f, 0xfe, 0x40, 0xb5, 0x7a, 0xf1, 0x1d, 0x11, 0x0b, + 0x43, 0x79, 0x3a, 0x6d, 0xb6, 0xdb, 0x4d, 0x3f, 0xf8, 0xfc, 0x63, 0x41, 0x21, 0x8b, 0xd7, 0xfc, + 0x44, 0x38, 0xc4, 0x42, 0x81, 0x05, 0x7f, 0xc4, 0x71, 0x1f, 0xd1, 0x05, 0xa1, 0xb5, 0xf4, 0x12, + 0x0b, 0xff, 0xff, 0xa0, 0x42, 0x31, 0x79, 0x54, 0xa5, 0x7e, 0x23, 0x88, 0x84, 0x47, 0x21, 0x3e, + 0x23, 0x88, 0xe2, 0x3a, 0x21, 0xd1, 0x03, 0x7e, 0x6f, 0xe3, 0xc7, 0xf4, 0x5a, 0xf5, 0xeb, 0xc7, + 0x6c, 0x61, 0xf1, 0x10, 0xfa, 0x27, 0xc4, 0x7f, 0x11, 0xd1, 0x0a, 0xb2, 0x93, 0x87, 0xf7, 0x0c, + 0x03, 0x41, 0x18, 0xf2, 0x9d, 0x63, 0xa5, 0xff, 0xc7, 0xc6, 0x9d, 0x7a, 0xf5, 0xeb, 0xff, 0x8f, + 0x1f, 0xa2, 0xd7, 0xaf, 0x5e, 0x3b, 0x63, 0x08, 0x44, 0x00, 0x3c, 0x64, 0x0c, 0x75, 0xaf, 0x6e, + 0x3f, 0x88, 0x04, 0x03, 0x41, 0xea, 0xfd, 0xef, 0xf1, 0xfe, 0x34, 0x51, 0xb2, 0x79, 0xc8, 0x93, + 0x95, 0x59, 0xe1, 0xe0, 0xe3, 0x83, 0x4d, 0x3f, 0xef, 0xde, 0x71, 0x8f, 0x0a, 0x1c, 0x59, 0xb2, + 0xbe, 0x2b, 0x77, 0xce, 0xb5, 0xb6, 0xff, 0xfe, 0x90, 0xe1, 0x82, 0x05, 0x37, 0x8a, 0xfb, 0xce, + 0x8c, 0x84, 0xa8, 0xd2, 0xa3, 0x6a, 0x09, 0xf8, 0x09, 0x7d, 0x84, 0x4e, 0x89, 0x78, 0x8f, 0xff, + 0xec, 0x99, 0x17, 0x84, 0xa3, 0xe8, 0x61, 0xb1, 0x5e, 0xfc, 0x57, 0x9d, 0x40, 0xec, 0x7c, 0x8f, + 0xc0, 0x3a, 0x99, 0x42, 0x18, 0xd0, 0x2f, 0x9b, 0x47, 0x62, 0x12, 0xde, 0xf0, 0xe6, 0x14, 0x1e, + 0x3b, 0xbb, 0xff, 0x13, 0x3f, 0x8e, 0x66, 0xbc, 0x44, 0x5a, 0xef, 0xea, 0xde, 0xde, 0x62, 0x5f, + 0x97, 0xb6, 0xaa, 0xdc, 0x38, 0xf3, 0xd2, 0x3b, 0x0c, 0x8b, 0xcb, 0xb5, 0xfd, 0x10, 0x82, 0xb4, + 0x70, 0x7f, 0xff, 0xf4, 0x08, 0x06, 0x2f, 0xff, 0x87, 0x8e, 0x81, 0x0d, 0x7f, 0xfc, 0x3f, 0xa0, + 0xfd, 0x79, 0xd0, 0xda, 0x38, 0x7f, 0x8f, 0xfe, 0x81, 0x30, 0xc5, 0xeb, 0xff, 0x8f, 0x1e, 0x34, + 0x22, 0xbd, 0x7a, 0xf1, 0xda, 0xd7, 0x1f, 0xf8, 0xfd, 0x02, 0x02, 0x2f, 0xe3, 0xfc, 0x78, 0xd0, + 0xba, 0xf5, 0xeb, 0xf8, 0xff, 0xc7, 0xa0, 0x4f, 0x5f, 0xaf, 0xf8, 0xf0, 0xfa, 0x11, 0x5e, 0xbd, + 0x78, 0xec, 0x7f, 0x8c, 0x7f, 0xfa, 0x13, 0x5f, 0xad, 0x7f, 0xff, 0xfd, 0x02, 0x62, 0x2d, 0x6b, + 0xce, 0x8a, 0x00, 0xfe, 0xae, 0xa0, 0x76, 0xb5, 0x0d, 0x3d, 0xff, 0xc2, 0x1c, 0x84, 0xf8, 0x78, + 0x7e, 0x81, 0x21, 0x5f, 0x8e, 0xd4, 0xbf, 0xff, 0x8f, 0x44, 0x8f, 0x18, 0xc6, 0x31, 0x8d, 0x10, + 0xc8, 0x81, 0xf7, 0x91, 0xff, 0xff, 0xfa, 0x11, 0x5e, 0xbd, 0x78, 0xed, 0x12, 0xa7, 0x90, 0xf2, + 0xfc, 0x47, 0xff, 0x40, 0x92, 0xbc, 0x76, 0x89, 0xc6, 0xb2, 0x30, 0xac, 0x91, 0xfc, 0xff, 0xf8, + 0x43, 0xa0, 0x89, 0x72, 0x44, 0x22, 0x36, 0x07, 0x18, 0x80, 0x5c, 0x44, 0x22, 0x38, 0x8e, 0x23, + 0xa0, 0x88, 0xc1, 0xda, 0xd1, 0x01, 0xd5, 0x87, 0x50, 0x7b, 0xd1, 0xe5, 0x21, 0x32, 0x28, 0x3a, + 0xb6, 0x23, 0xf8, 0x7f, 0x44, 0x4a, 0x59, 0x7f, 0x0f, 0x88, 0x85, 0x02, 0x2a, 0xfc, 0xa7, 0xf1, + 0x71, 0xff, 0xf1, 0x90, 0x5d, 0x7a, 0xf5, 0xfc, 0x78, 0xf1, 0xf9, 0x0b, 0x5e, 0xbd, 0x7e, 0x5f, + 0xe3, 0xc7, 0xe4, 0x05, 0x15, 0xeb, 0xca, 0x9f, 0xe3, 0xc7, 0x8d, 0x08, 0xaf, 0x5e, 0xbf, 0xa7, + 0x27, 0xdf, 0xe1, 0xf8, 0x75, 0x15, 0xf7, 0xef, 0x15, 0xc5, 0x7c, 0x45, 0xc4, 0x42, 0x42, 0x48, + 0x60, 0x6e, 0x46, 0xdd, 0x43, 0x0f, 0x0b, 0x86, 0x82, 0xc7, 0x7b, 0xdf, 0xa2, 0x52, 0x8f, 0x1f, + 0xf1, 0xe0, 0x94, 0xab, 0xc7, 0xd7, 0x20, 0x7b, 0xd1, 0x1c, 0x44, 0x21, 0xe1, 0xa0, 0x4b, 0x7e, + 0x3e, 0xfd, 0xbc, 0x31, 0x0c, 0x81, 0x12, 0x0f, 0xbf, 0x94, 0x44, 0x75, 0xb5, 0x02, 0x8b, 0xde, + 0xbd, 0xa6, 0x45, 0x0d, 0xf8, 0x45, 0x59, 0x51, 0x3c, 0xa9, 0x2e, 0xc3, 0x44, 0xaf, 0xaa, 0x88, + 0x5f, 0x6b, 0x57, 0xbe, 0x68, 0x97, 0xf4, 0xa7, 0x12, 0x06, 0xc5, 0x25, 0xe5, 0xcb, 0x81, 0x0c, + 0x2d, 0xef, 0xf8, 0xff, 0x8e, 0x23, 0x90, 0x16, 0x84, 0xd7, 0x9d, 0x09, 0xd7, 0xa7, 0xce, 0xb6, + 0x27, 0x5b, 0x18, 0x8f, 0x1f, 0xe3, 0xa0, 0xc5, 0x7a, 0xf6, 0x27, 0x44, 0x0d, 0xf9, 0x8f, 0xff, + 0xfd, 0x1a, 0xbd, 0x7a, 0xf4, 0x6d, 0x14, 0x92, 0x10, 0x7f, 0xff, 0xe8, 0x22, 0x51, 0xdb, 0xfc, + 0x7e, 0x31, 0xa0, 0x95, 0x7a, 0xff, 0xff, 0xe1, 0x40, 0x94, 0x82, 0xfc, 0x77, 0x7e, 0x20, 0x11, + 0x3c, 0x00, 0x2a, 0x3b, 0x59, 0xbf, 0x03, 0xac, 0x94, 0xee, 0xc4, 0xd8, 0x83, 0x27, 0xe9, 0xaa, + 0x07, 0x00, 0xc3, 0x81, 0x80, 0x69, 0x30, 0xa5, 0x4a, 0x75, 0xc7, 0xd5, 0xfb, 0x11, 0xfd, 0x40, + 0xd7, 0x55, 0x87, 0x61, 0xc7, 0x9d, 0x83, 0xaf, 0x11, 0x00, 0x8f, 0x38, 0x71, 0x2c, 0x95, 0x65, + 0x85, 0x89, 0xee, 0x24, 0x74, 0x43, 0xb8, 0xe2, 0x3e, 0xbf, 0x61, 0x71, 0xab, 0xda, 0x84, 0x5f, + 0x1a, 0xb1, 0xc7, 0x4c, 0x43, 0x87, 0x7c, 0x91, 0x7f, 0xff, 0xd0, 0x2a, 0x89, 0x69, 0x4d, 0x34, + 0xd3, 0xf1, 0x64, 0x1b, 0x10, 0x1a, 0x88, 0x9b, 0x6d, 0xb6, 0xd3, 0x4f, 0x80, 0x62, 0x01, 0xc6, + 0x01, 0x90, 0x12, 0x04, 0x17, 0xf1, 0xf1, 0x2a, 0x42, 0x17, 0x9c, 0x9c, 0x56, 0xa0, 0xea, 0x24, + 0x25, 0x42, 0x2f, 0x02, 0xa8, 0xfc, 0x3c, 0x77, 0x7f, 0x81, 0x04, 0x57, 0xaf, 0xc5, 0xe2, 0x3a, + 0x88, 0x65, 0x0a, 0x02, 0x2b, 0x64, 0x58, 0xff, 0xf9, 0xf8, 0xd9, 0xa4, 0x5c, 0xd8, 0x80, 0xf4, + 0x60, 0x67, 0x5c, 0x1f, 0x7a, 0x76, 0xff, 0xee, 0xef, 0x77, 0xc8, 0x10, 0x11, 0x9b, 0x0d, 0x63, + 0xda, 0x29, 0x57, 0x0a, 0x95, 0xbc, 0x89, 0x15, 0x0f, 0x9a, 0xa4, 0x07, 0xb0, 0xa8, 0x9d, 0x08, + 0x92, 0xa6, 0x8d, 0xbb, 0x74, 0xfb, 0xbe, 0xff, 0xf5, 0x26, 0x6b, 0x06, 0xff, 0x71, 0x24, 0xdc, + 0x1f, 0xe4, 0x4d, 0xc2, 0xe9, 0x6c, 0x98, 0x23, 0xa8, 0xa6, 0x9f, 0xfd, 0xef, 0x73, 0x77, 0xbd, + 0x8e, 0xb9, 0xac, 0xd2, 0xb1, 0xdc, 0x94, 0xe6, 0x3f, 0xce, 0x27, 0xda, 0xc1, 0xd3, 0xd6, 0xf0, + 0xde, 0x89, 0x9b, 0x60, 0xef, 0xfa, 0xd7, 0x84, 0x39, 0x0e, 0x23, 0xb0, 0xb8, 0x56, 0x28, 0xda, + 0xd6, 0xa1, 0x7f, 0xeb, 0x50, 0xd3, 0xcd, 0x71, 0xfe, 0x30, 0xfa, 0x27, 0xc3, 0xf8, 0x8e, 0x88, + 0xd6, 0x45, 0xa5, 0x0f, 0x7b, 0xfe, 0x23, 0x88, 0x85, 0x04, 0x4a, 0x3e, 0xc7, 0x97, 0x11, 0xc4, + 0x74, 0x46, 0xbf, 0xc7, 0xff, 0x41, 0x8a, 0xf5, 0xe3, 0xb7, 0x8f, 0x1e, 0x3c, 0x69, 0xd7, 0xaf, + 0x5e, 0xbf, 0xf8, 0xf1, 0xfa, 0x10, 0x45, 0xeb, 0xf5, 0x56, 0xf1, 0xff, 0xfa, 0x3d, 0x7a, 0xd6, + 0xb5, 0xf4, 0xaa, 0x10, 0x2a, 0x7a, 0x0e, 0xa8, 0x1c, 0x4c, 0xbe, 0x00, 0x1f, 0xf9, 0x4e, 0xfd, + 0xfb, 0xf4, 0x70, 0xff, 0xff, 0x0e, 0x09, 0xef, 0xdf, 0x99, 0xc3, 0xef, 0x0f, 0xa7, 0x63, 0x63, + 0x83, 0x63, 0xf0, 0xff, 0xa0, 0x46, 0x31, 0xfa, 0x3e, 0x25, 0x90, 0x36, 0x93, 0x8a, 0x3f, 0x00, + 0xe1, 0x87, 0xf6, 0x1f, 0xbf, 0xc3, 0x8f, 0x0e, 0x3a, 0x19, 0x7e, 0xfd, 0xff, 0xfe, 0x3f, 0x90, + 0xb7, 0xeb, 0xd7, 0xa7, 0x58, 0xe1, 0xff, 0xc8, 0x08, 0x88, 0xbc, 0x71, 0xef, 0x9e, 0x63, 0xe6, + 0x74, 0x87, 0x05, 0x69, 0x75, 0xca, 0xef, 0xfc, 0x00, 0x22, 0x38, 0xd0, 0xc4, 0x36, 0x19, 0x17, + 0x87, 0x15, 0xbd, 0x7f, 0xad, 0xee, 0x50, 0xcb, 0xc2, 0x71, 0xa6, 0x42, 0x5a, 0x6e, 0x3f, 0xfe, + 0x38, 0x29, 0xaf, 0x5f, 0x91, 0xff, 0xe3, 0xfc, 0x70, 0xc5, 0x7a, 0xf1, 0xc6, 0xff, 0x1f, 0xe3, + 0x41, 0x4a, 0xf5, 0xed, 0x7f, 0xc6, 0x3f, 0x1a, 0x0c, 0x57, 0xaf, 0x1d, 0xbf, 0xfc, 0x60, 0x19, + 0x01, 0x25, 0x7f, 0x60, 0xb4, 0xf0, 0xff, 0x1c, 0x10, 0x4d, 0x5e, 0x92, 0x91, 0xf2, 0x0c, 0xbd, + 0xaa, 0x18, 0xb2, 0x0a, 0xb4, 0xa5, 0xfe, 0x9a, 0x33, 0xa3, 0xc0, 0xcb, 0x40, 0x57, 0x25, 0xf1, + 0xed, 0x7b, 0x7f, 0x4e, 0x73, 0xad, 0x67, 0x3d, 0x77, 0xf3, 0xad, 0xbd, 0xd7, 0xc2, 0xde, 0xd2, + 0xde, 0x0e, 0x82, 0x60, 0x68, 0xef, 0x37, 0x6f, 0x19, 0xef, 0x34, 0xeb, 0x58, 0x9d, 0x7c, 0x96, + 0x93, 0x4f, 0x8d, 0x63, 0xb7, 0xe1, 0x7a, 0xac, 0x60, 0xa4, 0x1f, 0x2f, 0xe9, 0x9b, 0xb7, 0x6f, + 0xfe, 0x75, 0x3f, 0x60, 0xb4, 0xfc, 0x33, 0xa2, 0x20, 0x04, 0x40, 0x6e, 0x5f, 0xdb, 0xfe, 0x3c, + 0x4a, 0x21, 0x90, 0x40, 0xd5, 0xea, 0xba, 0xf6, 0xb5, 0xff, 0xfc, 0x7a, 0x3d, 0x7a, 0xfd, 0x6d, + 0xf9, 0xbf, 0x87, 0xd0, 0x21, 0xaf, 0x6a, 0x1d, 0x9f, 0xed, 0xa8, 0x6c, 0x9f, 0x10, 0xac, 0xc0, + 0x02, 0x1e, 0xbf, 0xab, 0xbf, 0xef, 0x7f, 0xfe, 0x7e, 0x28, 0xb2, 0xac, 0xf7, 0x19, 0x07, 0xdd, + 0xde, 0x40, 0x80, 0x8e, 0x24, 0xe4, 0x2f, 0x53, 0x40, 0x3e, 0xd5, 0x76, 0x81, 0x7c, 0x6a, 0x34, + 0xc3, 0xe5, 0xf7, 0xf0, 0x1c, 0x38, 0xa0, 0x67, 0x15, 0x30, 0x7d, 0xe1, 0xed, 0xb3, 0xdd, 0xc1, + 0x88, 0x9e, 0xfb, 0xfc, 0xc6, 0xcb, 0x38, 0x1f, 0x35, 0xd4, 0xa9, 0xce, 0x12, 0x2b, 0x70, 0x46, + 0x46, 0x6a, 0xe9, 0xf1, 0x22, 0xa4, 0x8a, 0xa9, 0x5b, 0x52, 0xa0, 0x77, 0x63, 0x28, 0x9f, 0xed, + 0xfd, 0xef, 0xef, 0xe1, 0x02, 0x16, 0x3d, 0xe1, 0xce, 0x1c, 0xe3, 0x70, 0xe7, 0xb7, 0x09, 0x15, + 0xdb, 0x85, 0xba, 0xa6, 0x4f, 0x84, 0x72, 0x22, 0x93, 0xdc, 0x8a, 0xdc, 0xbf, 0x50, 0xdf, 0xb8, + 0x18, 0xb5, 0xca, 0x1c, 0x15, 0x11, 0x5d, 0x85, 0xef, 0xb1, 0x97, 0x1f, 0xf9, 0x02, 0xf2, 0xc9, + 0x38, 0x57, 0x09, 0x99, 0x5d, 0x73, 0xec, 0x3f, 0xf8, 0x47, 0xc2, 0xe1, 0x75, 0xe2, 0xfc, 0x1a, + 0xd0, 0x35, 0x2c, 0x47, 0xff, 0xe8, 0x14, 0x95, 0x7a, 0xf1, 0xdb, 0x18, 0x7c, 0x03, 0x00, 0xd1, + 0x20, 0x18, 0x8e, 0x01, 0xc7, 0x20, 0x25, 0x32, 0xf6, 0xc4, 0x71, 0x1c, 0x47, 0x11, 0xd0, 0x44, + 0xa8, 0xec, 0x8a, 0x1f, 0x7b, 0x87, 0xc4, 0x71, 0x1d, 0x10, 0xaa, 0x36, 0xe9, 0xf8, 0x88, 0x7c, + 0x00, 0x68, 0x12, 0x91, 0x7b, 0x5a, 0xca, 0xa0, 0xfa, 0x87, 0x53, 0x7e, 0x95, 0x40, 0xfa, 0x65, + 0x78, 0x7d, 0xd4, 0x06, 0x23, 0x4a, 0xbd, 0x7e, 0xaa, 0xab, 0x95, 0x19, 0x78, 0xf8, 0xfc, 0x69, + 0x75, 0x55, 0xad, 0x7a, 0xf2, 0xa4, 0x4a, 0x84, 0xad, 0x3d, 0x1c, 0x7e, 0xef, 0x8f, 0xff, 0x21, + 0x3e, 0x01, 0xf8, 0xc7, 0x0b, 0x95, 0xfb, 0xf1, 0x14, 0x93, 0xe1, 0xbf, 0x45, 0x4b, 0x4b, 0x6b, + 0x22, 0x83, 0xd6, 0x88, 0x24, 0x07, 0xb4, 0xe5, 0x26, 0x55, 0x16, 0xea, 0xfc, 0x3d, 0x82, 0x03, + 0x5f, 0xd4, 0x47, 0xf1, 0xd4, 0x45, 0x9e, 0xbf, 0x5a, 0xdf, 0x31, 0xc7, 0xf8, 0xe1, 0xe7, 0xaf, + 0x5f, 0x5f, 0x2e, 0x51, 0x9c, 0xe3, 0x8f, 0x20, 0xda, 0xd7, 0x9b, 0xd7, 0x89, 0x38, 0xab, 0x55, + 0xfd, 0x29, 0xe3, 0x08, 0xad, 0xb0, 0x5a, 0x2b, 0xa6, 0x2a, 0x4e, 0xff, 0xff, 0x8c, 0x3e, 0x81, + 0x10, 0x4d, 0x7a, 0x20, 0x5d, 0x1d, 0x69, 0x54, 0x7f, 0xe3, 0xf4, 0x08, 0x08, 0xbf, 0x8f, 0xf1, + 0xfa, 0x0b, 0xd7, 0xaf, 0x1d, 0x8f, 0xff, 0x1f, 0xe3, 0x41, 0x8a, 0xf5, 0xe3, 0xcb, 0xfc, 0x78, + 0xfd, 0x02, 0x8a, 0xf5, 0xe2, 0x2d, 0x3c, 0x7f, 0xfe, 0x83, 0xc5, 0x5f, 0xff, 0xc7, 0xe8, 0x12, + 0x11, 0x7a, 0x3f, 0xc7, 0xff, 0x8d, 0x02, 0x9a, 0xf5, 0xe3, 0xb5, 0xaf, 0x3e, 0xab, 0x1e, 0x6f, + 0xa0, 0x58, 0x10, 0x36, 0x8c, 0xca, 0x9c, 0xf0, 0x09, 0x03, 0xfa, 0x6f, 0xe9, 0xf5, 0x5c, 0x91, + 0x69, 0x9a, 0xa6, 0xfa, 0x13, 0x9e, 0x34, 0xb2, 0xf5, 0x58, 0x26, 0x56, 0xe9, 0x5d, 0xf0, 0xb6, + 0xc3, 0x03, 0xb1, 0x05, 0x8d, 0xe6, 0xfc, 0x43, 0xcb, 0x5a, 0x2a, 0x22, 0xa8, 0x9f, 0x9f, 0xfd, + 0x8d, 0xa9, 0xb1, 0xbe, 0xbb, 0xa4, 0x16, 0x74, 0xd4, 0x6d, 0x6f, 0xb5, 0x89, 0x38, 0x77, 0x69, + 0xf6, 0xfe, 0x7f, 0x9f, 0xb5, 0x87, 0x48, 0x6f, 0x6c, 0xde, 0xb8, 0x02, 0x8b, 0x96, 0xff, 0xe1, + 0xff, 0x8e, 0x81, 0x48, 0x64, 0x5f, 0xaf, 0x1d, 0xbf, 0xf8, 0xe2, 0x3a, 0x09, 0xd7, 0xaf, 0x68, + 0x81, 0xa7, 0x9a, 0x87, 0x7d, 0x1f, 0x8f, 0x1f, 0xa1, 0x04, 0x5e, 0xbd, 0x6a, 0x17, 0x2b, 0xdc, + 0xa4, 0x45, 0xb3, 0x17, 0xf0, 0x96, 0xa1, 0xf0, 0xf1, 0xa1, 0x16, 0x07, 0xc3, 0x5f, 0x20, 0xc9, + 0xac, 0x3d, 0x06, 0xb9, 0x20, 0x2a, 0x00, 0x00, 0x20, 0xe9, 0x75, 0xdd, 0xf2, 0x7b, 0xff, 0xfa, + 0x2c, 0x91, 0x50, 0xf4, 0x6a, 0x70, 0xe1, 0x20, 0xaa, 0xb8, 0xc7, 0xd9, 0xec, 0xb9, 0x7e, 0x5f, + 0x97, 0xf8, 0x45, 0x8b, 0x94, 0x86, 0x1a, 0x54, 0xbf, 0x0f, 0x78, 0xfc, 0xdd, 0x9d, 0x7a, 0x8c, + 0xa2, 0xac, 0x83, 0x22, 0xe4, 0xe4, 0xfb, 0x43, 0x3a, 0xae, 0x17, 0xae, 0xaa, 0x88, 0x60, 0x2e, + 0x37, 0x08, 0x61, 0xbf, 0xf0, 0xff, 0xd8, 0x6b, 0xae, 0xa5, 0x51, 0x9f, 0xc7, 0xc6, 0x21, 0xeb, + 0xe1, 0x86, 0x1f, 0x11, 0xd0, 0x58, 0x2f, 0x8b, 0xd7, 0xa2, 0x13, 0x47, 0x50, 0xd3, 0xc9, 0x53, + 0x5c, 0x43, 0x00, 0xfc, 0x3a, 0x04, 0x45, 0x5e, 0x3b, 0x1f, 0x88, 0x84, 0x43, 0x11, 0xc4, 0x72, + 0x04, 0x67, 0x45, 0x51, 0x1c, 0x47, 0xf1, 0x1d, 0x04, 0x69, 0xd1, 0x51, 0x03, 0x7e, 0x3a, 0xdc, + 0xb5, 0x19, 0x2c, 0xda, 0x20, 0x22, 0x7a, 0x44, 0x24, 0x95, 0x18, 0x2b, 0x27, 0x55, 0xcc, 0x44, + 0xa8, 0xdb, 0x43, 0x9b, 0x8f, 0xef, 0xf1, 0x90, 0xd5, 0xfa, 0xaa, 0xf1, 0xc6, 0xcb, 0xc4, 0xb8, + 0xf2, 0xa5, 0x5e, 0xab, 0xaf, 0x55, 0xda, 0x75, 0x0d, 0xfb, 0xc4, 0xea, 0x09, 0x35, 0x43, 0x44, + 0x92, 0x8e, 0x2f, 0x28, 0xc3, 0xf1, 0xe2, 0xee, 0xfa, 0xd5, 0x57, 0x88, 0x61, 0x58, 0x8b, 0xa6, + 0xe3, 0x83, 0x53, 0xcd, 0xc7, 0x06, 0xfc, 0x0b, 0xf8, 0x68, 0x11, 0x85, 0x2f, 0xa6, 0xdc, 0x7f, + 0x97, 0x0d, 0x08, 0xbf, 0x5e, 0xfe, 0x34, 0xec, 0xa1, 0x97, 0x87, 0x57, 0xe3, 0xfc, 0x3b, 0x04, + 0x7d, 0x63, 0x98, 0xe3, 0x8a, 0x88, 0x90, 0x8c, 0x7f, 0x90, 0x41, 0x05, 0xfa, 0xf5, 0xef, 0x18, + 0xa0, 0x24, 0x5a, 0x4e, 0x3c, 0x3c, 0x8e, 0x9d, 0x34, 0xf6, 0xdb, 0xfc, 0x36, 0xa4, 0x47, 0x20, + 0x28, 0x10, 0xbd, 0xf9, 0x50, 0xb6, 0x25, 0x8b, 0x09, 0x34, 0xf5, 0x2a, 0xa7, 0x25, 0xca, 0x9f, + 0xe3, 0x7f, 0xe8, 0x11, 0xd7, 0x9d, 0x3f, 0xc7, 0x8f, 0xd0, 0x28, 0xaf, 0x5e, 0x75, 0x7f, 0x8f, + 0x1f, 0xa0, 0x4d, 0x5e, 0xbf, 0xff, 0x8f, 0xd0, 0x24, 0xaf, 0xef, 0x1f, 0xfe, 0x34, 0x09, 0xeb, + 0xd7, 0xb5, 0x0e, 0xfb, 0xff, 0x8f, 0xe0, 0x92, 0xbf, 0xde, 0x3f, 0xc7, 0xe8, 0x27, 0x5e, 0xbd, + 0xa8, 0x7d, 0xe8, 0xf4, 0x9f, 0x88, 0xa5, 0x50, 0x70, 0x20, 0x76, 0x5e, 0x5c, 0x92, 0x18, 0x13, + 0x60, 0x52, 0xa6, 0xfc, 0xbf, 0xd3, 0xd3, 0xd2, 0x94, 0x7e, 0x95, 0x65, 0xe1, 0x5e, 0x32, 0x43, + 0x3c, 0x35, 0xee, 0x58, 0x26, 0x7e, 0x5f, 0xa2, 0x68, 0x94, 0x44, 0x44, 0x4d, 0x08, 0xad, 0xf8, + 0x87, 0xcd, 0x91, 0xa3, 0x28, 0xaf, 0xfb, 0x63, 0x14, 0xe1, 0x88, 0xe9, 0x4c, 0x36, 0x73, 0xaf, + 0xdb, 0xaf, 0x18, 0xab, 0x8e, 0x21, 0x88, 0x62, 0x3a, 0x28, 0xd5, 0xeb, 0xd7, 0x8e, 0x94, 0xaa, + 0x3d, 0x9f, 0xe3, 0xc7, 0xf4, 0x09, 0xab, 0xd7, 0xfe, 0xcc, 0x7e, 0xd6, 0x64, 0x10, 0x08, 0x6b, + 0x37, 0x5b, 0x8e, 0x27, 0xdc, 0x6c, 0x4f, 0xd1, 0x1b, 0x04, 0x69, 0x01, 0xe4, 0x60, 0x1e, 0xb5, + 0xef, 0x66, 0x63, 0xfd, 0xb7, 0xe8, 0xc9, 0x35, 0x86, 0xf1, 0x6b, 0xe5, 0xe5, 0x37, 0x64, 0xfd, + 0x37, 0xce, 0xc5, 0x0f, 0xcb, 0xe4, 0x11, 0x94, 0x88, 0x79, 0x61, 0xde, 0xbd, 0x75, 0x5a, 0x91, + 0x1d, 0x5e, 0x51, 0x22, 0x81, 0x17, 0x6a, 0x46, 0xaf, 0xd7, 0xac, 0x2f, 0x58, 0x33, 0x18, 0xd0, + 0x17, 0x7b, 0x79, 0xb5, 0xbe, 0x44, 0x22, 0x09, 0xb3, 0xda, 0x0d, 0x9e, 0x7d, 0xdc, 0xeb, 0xf7, + 0xff, 0xed, 0x57, 0x8f, 0x8c, 0x43, 0x1e, 0x1f, 0x8c, 0x28, 0x2e, 0x17, 0x14, 0xf8, 0xbf, 0x44, + 0x0f, 0x4d, 0x43, 0x4f, 0x35, 0x0e, 0xfb, 0x1f, 0xff, 0xd0, 0x2b, 0x08, 0x8b, 0xf3, 0xa5, 0xb6, + 0xfd, 0x34, 0xc4, 0x21, 0xc0, 0xea, 0xd4, 0x7d, 0xae, 0x20, 0x10, 0x0c, 0x03, 0x10, 0x0a, 0x08, + 0x91, 0x1d, 0xc4, 0x7f, 0x10, 0xc0, 0x34, 0x0a, 0xa9, 0x97, 0xed, 0xb6, 0x2d, 0x43, 0xbe, 0x63, + 0xfa, 0x69, 0xc7, 0xfe, 0x3f, 0x40, 0x82, 0xbc, 0xea, 0x1d, 0xf7, 0x71, 0xff, 0xfd, 0x04, 0xce, + 0xbd, 0x79, 0xd1, 0x03, 0x4f, 0x23, 0xf1, 0xf8, 0xff, 0x0a, 0x19, 0x5f, 0x8b, 0xd7, 0xff, 0x1f, + 0xfa, 0x0c, 0x57, 0xaf, 0x1d, 0xbc, 0x78, 0xff, 0xd3, 0xaf, 0x5e, 0xbd, 0x7f, 0x1e, 0x3f, 0xf4, + 0x5a, 0xf5, 0xeb, 0xc7, 0x63, 0xff, 0xff, 0xf4, 0x08, 0x2b, 0xda, 0xc4, 0x60, 0xea, 0x90, 0xed, + 0x2e, 0x52, 0x5f, 0xf8, 0xbf, 0x0a, 0x04, 0x91, 0x5d, 0xe3, 0xe9, 0xd4, 0x1d, 0x7a, 0x3e, 0x3b, + 0x36, 0x19, 0x7a, 0x29, 0x9c, 0x37, 0xe1, 0x2e, 0x69, 0x91, 0x03, 0xde, 0x6c, 0x38, 0x7f, 0xf2, + 0x02, 0xa3, 0x83, 0x5d, 0xeb, 0xe6, 0x20, 0x80, 0x07, 0x5a, 0x7a, 0x88, 0xd9, 0xc8, 0xbc, 0x24, + 0xde, 0x08, 0x45, 0xa6, 0x84, 0xf3, 0x52, 0x67, 0xde, 0x24, 0xfe, 0x1d, 0x66, 0xb2, 0x00, 0x88, + 0x48, 0x0b, 0x77, 0xc7, 0x18, 0xdf, 0x6d, 0xbf, 0xc6, 0xa2, 0xa2, 0x23, 0x29, 0x74, 0x0b, 0x08, + 0xd6, 0xd0, 0x3a, 0x81, 0x52, 0xfb, 0x69, 0xf3, 0xf8, 0xc7, 0x55, 0xc8, 0x0c, 0x2d, 0x5a, 0x68, + 0x97, 0xb4, 0x1f, 0xe6, 0x69, 0xe9, 0xb7, 0xb7, 0xfc, 0x35, 0x5a, 0x81, 0x60, 0xaa, 0x22, 0x48, + 0x57, 0xd3, 0x4f, 0x6d, 0xb3, 0xb3, 0x86, 0x99, 0x72, 0xaa, 0x75, 0x37, 0x2a, 0xa7, 0x53, 0x7e, + 0x9f, 0x37, 0xca, 0x25, 0x43, 0x13, 0xc8, 0x18, 0xa1, 0x94, 0x75, 0x6e, 0x39, 0x12, 0x49, 0x0c, + 0x7a, 0xd4, 0x30, 0x4f, 0xf5, 0x71, 0x5f, 0xbf, 0xf2, 0x04, 0x6c, 0x4f, 0x86, 0x3c, 0x03, 0xa4, + 0x19, 0xa4, 0x33, 0x59, 0xf1, 0x53, 0x8f, 0x08, 0x71, 0x36, 0x26, 0xde, 0x6c, 0xa2, 0x8a, 0xba, + 0xbe, 0xf4, 0xf4, 0xd2, 0x09, 0xa2, 0x25, 0xea, 0x4f, 0xf5, 0x69, 0x32, 0xc6, 0xb4, 0xd1, 0x6f, + 0xd3, 0xff, 0xe3, 0xf6, 0xdd, 0x4f, 0xe5, 0xb9, 0x5e, 0x37, 0x89, 0x32, 0x2a, 0x7b, 0xd6, 0xb1, + 0x24, 0x0a, 0x81, 0xf4, 0xdc, 0x64, 0x3c, 0x95, 0x41, 0x13, 0xd2, 0x01, 0x52, 0x10, 0x01, 0x8f, + 0x5f, 0x31, 0xff, 0xcf, 0x9f, 0xff, 0xee, 0x54, 0xec, 0xdf, 0x6b, 0x7c, 0x90, 0x95, 0x65, 0xfe, + 0x9d, 0xa8, 0x59, 0xc2, 0x97, 0xf1, 0x88, 0xdb, 0xdf, 0xf6, 0xca, 0x5e, 0xb9, 0x04, 0x14, 0x89, + 0x36, 0x11, 0xef, 0x66, 0xe2, 0xf8, 0xa1, 0x0a, 0xf2, 0x96, 0x45, 0x2f, 0x93, 0xa3, 0xfa, 0xf1, + 0x78, 0x5c, 0xaa, 0x20, 0x43, 0x01, 0x9c, 0x11, 0x53, 0xaf, 0x7f, 0x2f, 0xed, 0x0a, 0xd4, 0x0c, + 0x5a, 0xe1, 0x95, 0xc7, 0xdc, 0xe1, 0xdd, 0x2b, 0xae, 0x32, 0x77, 0xeb, 0x45, 0x3d, 0xf2, 0x1e, + 0x45, 0xf6, 0x50, 0xba, 0x0f, 0x78, 0xba, 0xae, 0xbd, 0x12, 0xe7, 0x47, 0x8e, 0xd8, 0xff, 0xf0, + 0xe8, 0x91, 0x87, 0xc4, 0x71, 0x1d, 0x04, 0x63, 0xb5, 0xad, 0xad, 0xae, 0x30, 0x80, 0x60, 0x18, + 0x06, 0x88, 0xd1, 0x8b, 0xce, 0xa1, 0xb9, 0xfe, 0xdb, 0xff, 0xc3, 0xe8, 0x10, 0x57, 0xf1, 0xff, + 0xfa, 0x0f, 0x1d, 0x7f, 0xf1, 0xff, 0xa1, 0x06, 0x5e, 0xbd, 0x7f, 0x5a, 0xda, 0x87, 0x7d, 0x00, + 0xc4, 0x07, 0x8f, 0xd0, 0x26, 0xaf, 0x5e, 0x25, 0x14, 0x61, 0xd0, 0x3b, 0x4a, 0xa6, 0xf8, 0xe2, + 0x3f, 0xfa, 0x0f, 0x0f, 0x17, 0xff, 0xf8, 0xe2, 0x3a, 0x04, 0x03, 0x17, 0xfc, 0x3c, 0x70, 0x00, + 0xce, 0x2b, 0x7b, 0xf7, 0xe3, 0xb1, 0xb4, 0x25, 0x43, 0x80, 0xca, 0x88, 0xf8, 0x92, 0x42, 0x57, + 0xac, 0x3b, 0x88, 0x92, 0x14, 0x43, 0x68, 0xec, 0xc4, 0x87, 0x59, 0x52, 0xff, 0x88, 0x0f, 0x95, + 0x6b, 0xf5, 0xaa, 0xd5, 0x57, 0xe2, 0x46, 0xbd, 0x34, 0xff, 0xe2, 0x23, 0x0f, 0x02, 0x18, 0xce, + 0xbb, 0xd7, 0xad, 0x2a, 0x09, 0xa8, 0x28, 0x9c, 0xef, 0xdb, 0x6d, 0xb6, 0xff, 0xd9, 0xbb, 0xbc, + 0x78, 0xf1, 0x85, 0x05, 0xaa, 0xb5, 0x17, 0xe8, 0xd5, 0x71, 0xa4, 0x3e, 0x21, 0x15, 0x2a, 0xfb, + 0xef, 0xf5, 0x54, 0x5c, 0xbd, 0xbb, 0x7c, 0x54, 0x42, 0x21, 0x3a, 0x3f, 0x82, 0x2b, 0xf4, 0x65, + 0xf1, 0x01, 0x10, 0xf8, 0x88, 0xd0, 0x25, 0xaf, 0x46, 0xf1, 0xe3, 0xc4, 0x03, 0x1c, 0x80, 0x96, + 0xbe, 0x88, 0xcb, 0xf1, 0x05, 0x11, 0xc3, 0xa0, 0x59, 0x2f, 0x36, 0xe0, 0x29, 0x28, 0x5f, 0xb7, + 0x6f, 0xfe, 0x22, 0x11, 0x8e, 0x0a, 0x8d, 0x3a, 0x5e, 0x9a, 0x65, 0xed, 0xb6, 0xdb, 0x62, 0x65, + 0x65, 0x90, 0x37, 0xce, 0xa1, 0x5b, 0x51, 0xd9, 0x11, 0x54, 0xd4, 0x6a, 0xd7, 0xfd, 0xc7, 0xc6, + 0x81, 0x49, 0x57, 0xaf, 0x3a, 0xad, 0x43, 0x1e, 0x6a, 0x1f, 0x4f, 0xf7, 0xff, 0x1e, 0x3d, 0x02, + 0x7a, 0xfd, 0x6d, 0x40, 0x48, 0xfd, 0x3f, 0x02, 0x68, 0x80, 0x04, 0x9f, 0x77, 0xd9, 0x6f, 0x85, + 0x7c, 0xdf, 0xff, 0xda, 0x52, 0x08, 0x93, 0x4a, 0x02, 0x21, 0xb8, 0xc5, 0x2a, 0x5a, 0xf3, 0x71, + 0x36, 0x33, 0xf8, 0x9c, 0xdf, 0x2d, 0xba, 0xb8, 0xd8, 0x8a, 0x5a, 0xd6, 0x78, 0x5f, 0xf4, 0xd3, + 0x04, 0xf2, 0x22, 0x53, 0x77, 0x5e, 0x63, 0x98, 0xad, 0xd5, 0xe6, 0x62, 0xdb, 0x62, 0x3e, 0x30, + 0x2f, 0xda, 0x0a, 0xaf, 0x5f, 0x5d, 0x7f, 0x5a, 0xfe, 0x44, 0xcd, 0x28, 0x59, 0xa8, 0x20, 0x3b, + 0x9a, 0x3d, 0xb1, 0x3c, 0x36, 0x08, 0xd2, 0x73, 0x6b, 0x13, 0x48, 0x18, 0x8e, 0x2e, 0xd5, 0x7f, + 0xb3, 0x73, 0xfb, 0x78, 0x5c, 0xc6, 0xcb, 0x8c, 0xb9, 0xbd, 0xcc, 0xa7, 0xab, 0x91, 0x7f, 0x7d, + 0x8c, 0x2d, 0x62, 0xf5, 0xaa, 0x86, 0xcf, 0x28, 0x50, 0x01, 0x38, 0x36, 0xc4, 0x8b, 0xe5, 0xf8, + 0xe5, 0x32, 0xac, 0x10, 0x00, 0x2e, 0x26, 0xd0, 0x9d, 0x39, 0xe6, 0xec, 0xff, 0xd1, 0x4e, 0x3f, + 0xc6, 0x5f, 0x65, 0x0a, 0xaa, 0xf7, 0x3d, 0x6a, 0xba, 0x23, 0x62, 0x38, 0xc3, 0xe0, 0x1a, 0x0f, + 0x14, 0x5f, 0xb5, 0xb5, 0x0e, 0x3d, 0x00, 0xc4, 0x43, 0xe2, 0x21, 0x41, 0x1a, 0x3e, 0xd7, 0x8f, + 0xff, 0xe8, 0x3c, 0x11, 0x17, 0xff, 0x18, 0x71, 0x80, 0x15, 0x06, 0x42, 0x8b, 0xea, 0xab, 0xdf, + 0x0f, 0x12, 0x27, 0xf4, 0x34, 0x46, 0xbc, 0x4f, 0x2a, 0x2e, 0xb0, 0x38, 0x63, 0xa9, 0xa6, 0x9a, + 0x7f, 0xbd, 0xdf, 0xe1, 0xf2, 0x0e, 0xb5, 0xab, 0x4d, 0x34, 0x6c, 0x7f, 0x3a, 0x37, 0x6d, 0xbf, + 0xfc, 0x43, 0xe3, 0x9c, 0x17, 0xd7, 0xdf, 0x0d, 0xab, 0xa7, 0xf1, 0x31, 0xa1, 0x33, 0xe3, 0xc1, + 0xd4, 0xca, 0x8e, 0xa1, 0x28, 0xb8, 0x0e, 0x64, 0x3e, 0x77, 0x0d, 0xcf, 0xf6, 0x3b, 0x7f, 0x1e, + 0x3e, 0x34, 0x32, 0xbd, 0x7a, 0xf3, 0xa8, 0x6e, 0x7f, 0xb1, 0xd8, 0xff, 0xf1, 0xff, 0xa0, 0x51, + 0x5e, 0x2f, 0xd1, 0xd9, 0xd4, 0x3b, 0xe4, 0x7d, 0xad, 0xaf, 0x1c, 0x47, 0xff, 0x40, 0x88, 0x22, + 0x2f, 0xc7, 0x06, 0xfe, 0x1f, 0x80, 0x72, 0x84, 0x05, 0x7d, 0xfa, 0xf4, 0x7c, 0xec, 0xc0, 0x0f, + 0x52, 0x6d, 0x50, 0x95, 0x6e, 0x42, 0x37, 0x90, 0x7e, 0x82, 0xf6, 0x95, 0x4d, 0x8b, 0xe8, 0xc0, + 0x15, 0xff, 0x86, 0x3c, 0x80, 0xa2, 0x2e, 0x2f, 0x17, 0x17, 0xe5, 0x59, 0xfe, 0xbf, 0x21, 0x82, + 0x1c, 0x51, 0x7a, 0x5d, 0x69, 0x71, 0x16, 0x86, 0xab, 0xf6, 0xdb, 0x80, 0x78, 0xff, 0xe2, 0x2b, + 0xde, 0xf7, 0x7d, 0x2c, 0x27, 0x81, 0x2b, 0x53, 0xf3, 0xfd, 0x34, 0xff, 0xf4, 0xc8, 0xea, 0x09, + 0xd6, 0xe7, 0x99, 0x32, 0x6a, 0x4c, 0x6a, 0x09, 0xde, 0x9e, 0xac, 0xa4, 0x3f, 0x87, 0xc8, 0x58, + 0xae, 0xf7, 0xef, 0xd1, 0xf8, 0xc7, 0x4b, 0x7f, 0xb0, 0x4b, 0x7e, 0x93, 0x1a, 0x61, 0x93, 0x7e, + 0xc1, 0x1d, 0xf8, 0xec, 0x73, 0x80, 0x7f, 0x0f, 0xd0, 0x20, 0x3b, 0xfc, 0x4b, 0xff, 0x0d, 0x18, + 0xca, 0xba, 0xaa, 0xd7, 0xd1, 0xc7, 0xff, 0x14, 0x3f, 0x90, 0x16, 0x9b, 0xb8, 0xa8, 0x01, 0x9d, + 0xff, 0xe3, 0xf9, 0x7e, 0x17, 0x2e, 0xb5, 0x5d, 0x22, 0x3a, 0x93, 0x0e, 0x9c, 0x43, 0xe0, 0x18, + 0x06, 0x83, 0xc5, 0x5e, 0x75, 0x0e, 0xf8, 0x76, 0xb5, 0xc7, 0xfe, 0x3f, 0x40, 0x82, 0xbd, 0xaf, + 0xe3, 0xff, 0x1a, 0x04, 0xf5, 0xeb, 0xff, 0x0b, 0xe4, 0x4f, 0xba, 0x08, 0x0a, 0xda, 0x13, 0xc8, + 0xf2, 0xcf, 0xc2, 0x95, 0x92, 0x2b, 0x81, 0xe8, 0xc0, 0x3c, 0xd5, 0x35, 0x19, 0xff, 0x47, 0x68, + 0xa1, 0xc2, 0xfb, 0x36, 0x20, 0xd8, 0x6d, 0x8a, 0xaa, 0xf4, 0xd2, 0x97, 0x29, 0x8f, 0x51, 0xe8, + 0xcf, 0x63, 0xff, 0xb0, 0x00, 0xa5, 0x55, 0x2c, 0xe7, 0x73, 0x4b, 0x6d, 0xb2, 0xe5, 0xdc, 0xdf, + 0x71, 0xe5, 0xaa, 0x06, 0x09, 0x82, 0xe1, 0xe5, 0xe4, 0x58, 0xb3, 0x4c, 0xf8, 0xb9, 0xdd, 0xdf, + 0x5e, 0x03, 0x19, 0xdd, 0xe9, 0x5f, 0x73, 0xdb, 0x1b, 0x8c, 0xd6, 0x6b, 0x70, 0xb8, 0x73, 0x87, + 0x38, 0x44, 0x74, 0x9a, 0x7b, 0x7f, 0xdf, 0x00, 0x2d, 0xf2, 0xaf, 0x03, 0xed, 0x4a, 0xfc, 0xb7, + 0x5d, 0xb9, 0x67, 0x0e, 0x56, 0x52, 0x6b, 0xe2, 0x1f, 0x5f, 0x6d, 0xbf, 0x20, 0x7f, 0xbd, 0xda, + 0x1c, 0x97, 0x3e, 0x47, 0x2e, 0xc5, 0x29, 0xd4, 0x1f, 0xed, 0x36, 0xe7, 0x8e, 0x99, 0xdc, 0x57, + 0xff, 0xe4, 0x58, 0xb0, 0x01, 0x35, 0xa3, 0xfc, 0x43, 0x8f, 0xac, 0xdc, 0xbe, 0xbc, 0xd8, 0xa4, + 0xf5, 0xc1, 0x30, 0x65, 0x32, 0x92, 0x6d, 0xad, 0xff, 0xf9, 0x44, 0x70, 0x1e, 0x37, 0x6e, 0x1b, + 0xc7, 0xfd, 0xb9, 0xf5, 0xd1, 0xde, 0xb1, 0xff, 0xf9, 0x43, 0x2b, 0x17, 0x8b, 0xf5, 0xe0, 0xac, + 0x0a, 0x7b, 0xc7, 0xf8, 0xc3, 0xa0, 0xb9, 0x57, 0xaf, 0x4c, 0xa3, 0x0f, 0x88, 0xe2, 0x3a, 0x27, + 0xc7, 0x88, 0x60, 0x1a, 0x04, 0x86, 0x5e, 0xdf, 0x8f, 0x10, 0xc0, 0x34, 0x43, 0xa8, 0x08, 0xf7, + 0x6f, 0xc2, 0xa7, 0xff, 0xc6, 0x3a, 0x08, 0x08, 0xd6, 0xb1, 0x79, 0xb2, 0x6c, 0x81, 0xf3, 0x74, + 0xd3, 0xf3, 0xa8, 0xc3, 0x3e, 0x65, 0xf2, 0x22, 0x0f, 0x22, 0x4a, 0x05, 0x99, 0x36, 0x6e, 0x22, + 0x4c, 0xaa, 0xb5, 0xff, 0xfc, 0x7f, 0x82, 0x41, 0xeb, 0xc3, 0x4c, 0xc4, 0xc4, 0x30, 0x62, 0x4f, + 0xf6, 0xe3, 0x8d, 0x7f, 0x0d, 0x05, 0xaf, 0xd7, 0x8c, 0x29, 0x1b, 0x30, 0x48, 0xad, 0x39, 0x19, + 0xfa, 0x69, 0xfd, 0xc7, 0xf7, 0xf8, 0x61, 0x12, 0x81, 0xdb, 0x2a, 0x3a, 0x2c, 0x45, 0x25, 0xa8, + 0x6f, 0xd8, 0xfe, 0x3f, 0xd0, 0x22, 0xaf, 0x1d, 0xbc, 0x7f, 0xfe, 0x83, 0xc5, 0x5f, 0xff, 0xf0, + 0xe8, 0x91, 0x87, 0xc4, 0x71, 0x1d, 0x11, 0xae, 0x23, 0x88, 0xf1, 0xfd, 0x02, 0x02, 0x2f, 0xe5, + 0xff, 0xc7, 0x44, 0x55, 0xf5, 0x51, 0x7e, 0xbe, 0x8e, 0x3f, 0x8f, 0xc7, 0x8d, 0xaa, 0xaa, 0xaa, + 0xf5, 0xeb, 0xd1, 0xc7, 0x89, 0x40, 0x31, 0xff, 0x3d, 0x57, 0xde, 0xef, 0xa7, 0xd5, 0xc2, 0x01, + 0x80, 0x7e, 0x82, 0xc2, 0x5f, 0xbf, 0x44, 0xa5, 0x10, 0xc7, 0xc7, 0xf2, 0x02, 0x4a, 0xf1, 0xd9, + 0x17, 0xff, 0xe1, 0xa0, 0x53, 0x15, 0xf7, 0xed, 0x88, 0xfe, 0x21, 0x80, 0x68, 0x11, 0x91, 0x7a, + 0x64, 0x5f, 0x88, 0x7f, 0xe1, 0x90, 0x14, 0x95, 0xfb, 0xf4, 0x8b, 0xff, 0xfe, 0x81, 0x58, 0xd1, + 0x5f, 0x47, 0x0f, 0xd3, 0x4f, 0x4b, 0xfc, 0xb8, 0x65, 0xd0, 0x28, 0x0a, 0x3b, 0xef, 0xf9, 0xb7, + 0x1e, 0x1c, 0x31, 0x1d, 0x82, 0x8b, 0xf7, 0xe3, 0x83, 0xbf, 0x8e, 0x23, 0xc7, 0x61, 0x8a, 0xf5, + 0xfb, 0xf1, 0xe3, 0xc7, 0x8e, 0xd5, 0x7a, 0xf5, 0xeb, 0xc7, 0x3f, 0xf8, 0xe2, 0x18, 0x9a, 0xc8, + 0x11, 0x8c, 0x7b, 0xff, 0x77, 0x08, 0x86, 0x81, 0x29, 0x57, 0xf4, 0xeb, 0x47, 0xff, 0xe3, 0x0f, + 0xa2, 0x7f, 0x1f, 0xfa, 0x04, 0xd5, 0xeb, 0xda, 0xff, 0xff, 0xe8, 0x26, 0x55, 0xeb, 0xff, 0xf8, + 0xfd, 0x02, 0x42, 0x2f, 0xe8, 0x5d, 0x18, 0x02, 0x46, 0xee, 0x0f, 0xf8, 0xd9, 0xff, 0xf3, 0xd2, + 0x24, 0xd0, 0x04, 0x5a, 0x7f, 0xd9, 0x8b, 0xe5, 0x21, 0xc9, 0xc9, 0x15, 0xd3, 0x8c, 0x57, 0x79, + 0xf5, 0xdb, 0x97, 0x77, 0x18, 0x88, 0xfe, 0xf7, 0xfb, 0xc7, 0x84, 0x08, 0x88, 0x60, 0x29, 0xf7, + 0x15, 0xdd, 0xed, 0xbb, 0xba, 0xd7, 0xfc, 0x20, 0x94, 0x31, 0xdd, 0x2f, 0x4e, 0xe8, 0x4d, 0x2a, + 0xa7, 0x26, 0x46, 0x92, 0x69, 0x54, 0x08, 0xbc, 0x4b, 0x77, 0xe9, 0x59, 0xa5, 0xbc, 0x28, 0x0a, + 0x96, 0xee, 0xfb, 0x71, 0x5b, 0xf1, 0x74, 0xb9, 0x78, 0x7e, 0x24, 0x34, 0x52, 0xeb, 0x7b, 0x5b, + 0xf2, 0x22, 0xe9, 0x68, 0xa2, 0x00, 0x63, 0x68, 0xa5, 0xa9, 0x3c, 0xb9, 0x0b, 0x57, 0x59, 0x30, + 0xbe, 0xf7, 0xd5, 0xd5, 0xce, 0xd5, 0x0f, 0x81, 0x18, 0xc9, 0xb2, 0x17, 0x2a, 0x39, 0x0f, 0xb4, + 0x19, 0x9b, 0x6e, 0xff, 0x43, 0xdd, 0xe4, 0x31, 0x94, 0x7e, 0xd0, 0x57, 0xaa, 0x8b, 0xf1, 0x7e, + 0xbd, 0xed, 0x6d, 0x6d, 0x6d, 0x67, 0x45, 0x8e, 0xd8, 0xfc, 0xbc, 0x0b, 0xa1, 0x02, 0x15, 0x6b, + 0x5d, 0x78, 0x72, 0x3b, 0xcb, 0xfe, 0x9c, 0x83, 0xc4, 0x8a, 0x6b, 0xaf, 0x8a, 0xf0, 0xc4, 0xc7, + 0x4f, 0xdf, 0xcf, 0xdf, 0xff, 0x87, 0xe1, 0xf9, 0x0b, 0x15, 0xf1, 0x5f, 0x71, 0x5e, 0x34, 0x14, + 0x39, 0xfe, 0xdc, 0x72, 0x1e, 0x88, 0xbd, 0x7a, 0xf5, 0xe2, 0xf4, 0x55, 0xff, 0xf1, 0x1d, 0x84, + 0x44, 0xa3, 0xb8, 0xf8, 0xe2, 0x38, 0x8f, 0x08, 0xc4, 0xb8, 0x89, 0x38, 0x86, 0x01, 0x88, 0xfe, + 0x40, 0x8e, 0x2f, 0xc0, 0x78, 0x16, 0x05, 0x41, 0x91, 0x0e, 0xfb, 0xbe, 0x74, 0x34, 0xc4, 0x10, + 0xa1, 0x8f, 0x0c, 0x15, 0x78, 0x7c, 0x43, 0x00, 0xe0, 0x90, 0x8b, 0xcc, 0x8b, 0x39, 0x0a, 0x1c, + 0x78, 0x47, 0x45, 0x47, 0x96, 0x3b, 0x5a, 0xca, 0xa5, 0x2a, 0x55, 0xb5, 0x99, 0x0d, 0x8e, 0x0d, + 0xfe, 0x3f, 0xf9, 0x46, 0x2f, 0x5e, 0xbd, 0x1c, 0x1b, 0x5f, 0x0f, 0xff, 0xb0, 0x44, 0x34, 0x57, + 0xc7, 0x06, 0x38, 0x62, 0x50, 0xc8, 0xed, 0x3a, 0xd1, 0xd9, 0xd6, 0x8f, 0xb5, 0xff, 0xff, 0xd1, + 0x3e, 0x23, 0xc3, 0x00, 0xd0, 0x20, 0xbf, 0xff, 0xc3, 0x00, 0xd0, 0x54, 0x8f, 0xdf, 0xe1, 0xf0, + 0x00, 0xe1, 0xa5, 0x7f, 0x8a, 0xef, 0xdf, 0xa2, 0x29, 0x61, 0x88, 0xe0, 0x1f, 0xa0, 0x44, 0x51, + 0x5f, 0x44, 0xa5, 0x11, 0xc0, 0x31, 0x1c, 0x47, 0x20, 0x46, 0xcc, 0x03, 0x91, 0x44, 0x0b, 0x8d, + 0x88, 0x10, 0xbd, 0x57, 0x5f, 0x7e, 0x3c, 0x71, 0x1f, 0xd8, 0x58, 0xab, 0xd7, 0xa2, 0x5e, 0x23, + 0xc7, 0x8e, 0x21, 0xc3, 0x35, 0xeb, 0xc0, 0xca, 0x60, 0xcf, 0xc8, 0xbe, 0x26, 0x0a, 0xe1, 0xb0, + 0x89, 0x8a, 0x91, 0x33, 0x94, 0x8e, 0x53, 0xc8, 0x08, 0xf7, 0x3d, 0x52, 0xa4, 0x4a, 0x80, 0x76, + 0xfa, 0x81, 0x26, 0x9b, 0xb8, 0x47, 0x80, 0x0c, 0x00, 0x00, 0x80, 0x87, 0xbf, 0xfe, 0x22, 0x18, + 0xf0, 0xc1, 0xd7, 0xaf, 0x11, 0xd2, 0x7c, 0x37, 0xe1, 0xdb, 0xfb, 0x58, 0x7c, 0x32, 0x07, 0x02, + 0x17, 0x8b, 0x74, 0xf2, 0xcd, 0xeb, 0xf9, 0x5e, 0xf7, 0x63, 0x6e, 0xda, 0x33, 0xe2, 0xb1, 0x0e, + 0x08, 0x1c, 0x6e, 0x07, 0xc6, 0xb1, 0x5a, 0x36, 0x0b, 0x07, 0xf1, 0xc3, 0x8f, 0xd7, 0xf2, 0x7a, + 0x99, 0x4c, 0x4e, 0x7a, 0x09, 0x03, 0x8c, 0x32, 0x1c, 0xbc, 0xdc, 0xda, 0xcd, 0xe7, 0x13, 0xc1, + 0xaa, 0x13, 0x95, 0x8b, 0xb2, 0x1c, 0x9a, 0x6a, 0x70, 0xd8, 0x8a, 0xdf, 0x4c, 0xf9, 0x0a, 0x2b, + 0xe9, 0xa7, 0x1b, 0xa7, 0xb3, 0xbb, 0xfe, 0x05, 0x7e, 0x45, 0xb9, 0x6f, 0xa5, 0x2f, 0x4b, 0x10, + 0xf7, 0x7b, 0x8a, 0x3b, 0x1a, 0xf1, 0xd4, 0xab, 0x5a, 0x0c, 0xd2, 0xf9, 0xe0, 0x5d, 0xed, 0x98, + 0xaf, 0xda, 0x2f, 0xf1, 0x07, 0xa6, 0x6f, 0xe5, 0xcf, 0x17, 0xae, 0x8b, 0x44, 0xf8, 0x22, 0x22, + 0x46, 0x0c, 0xc7, 0x8c, 0x4f, 0x77, 0x76, 0x31, 0x83, 0x72, 0xff, 0xd3, 0xc7, 0x61, 0x91, 0x3d, + 0x75, 0xfe, 0x9d, 0x0f, 0x0c, 0x78, 0x76, 0xb5, 0x89, 0x50, 0x33, 0xaf, 0x09, 0x68, 0x76, 0x35, + 0x08, 0x03, 0xba, 0x51, 0x26, 0x94, 0xd3, 0x4d, 0x3f, 0x39, 0x26, 0xac, 0x59, 0x37, 0xee, 0xff, + 0xc1, 0x59, 0x7a, 0x82, 0x91, 0x27, 0x54, 0xfe, 0x25, 0x43, 0xd5, 0xb3, 0xa3, 0x71, 0xe1, 0xc3, + 0x00, 0xd9, 0x4a, 0xfd, 0xf8, 0xaf, 0x8f, 0xdf, 0x88, 0x63, 0xc4, 0x36, 0x11, 0x9e, 0x3b, 0xff, + 0x88, 0x60, 0x1a, 0x04, 0x37, 0xf8, 0x7f, 0x0c, 0x03, 0x84, 0xca, 0xfd, 0xfc, 0x47, 0x86, 0x01, + 0xfa, 0x0c, 0x08, 0x7f, 0x7b, 0xa6, 0xc0, 0x3f, 0x8f, 0xec, 0x2e, 0x57, 0x15, 0xef, 0xd1, 0x2b, + 0x1f, 0xe0, 0x1f, 0xa2, 0x7f, 0xc0, 0x30, 0x0d, 0x02, 0xa8, 0x84, 0x92, 0x9a, 0x69, 0xa7, 0xe2, + 0x08, 0x48, 0xca, 0x3a, 0x3f, 0x16, 0x87, 0x9c, 0x87, 0x99, 0x44, 0xe4, 0x80, 0x8f, 0x7c, 0xfc, + 0x63, 0xc3, 0xc0, 0x43, 0x18, 0xc8, 0x0a, 0x04, 0x6b, 0x5a, 0xc4, 0x9a, 0x78, 0x7c, 0x00, 0x3e, + 0x82, 0x31, 0x50, 0xff, 0xe3, 0x88, 0xf0, 0x48, 0x2d, 0x78, 0x1c, 0x69, 0x34, 0x6c, 0x70, 0x00, + 0x23, 0x1c, 0x3f, 0xfc, 0x43, 0xe8, 0x10, 0x0c, 0x7f, 0xff, 0x86, 0x01, 0xb0, 0x41, 0x7f, 0xf8, + 0x60, 0x1f, 0xc1, 0x65, 0xf8, 0xe9, 0x5b, 0x6d, 0xb6, 0xff, 0xff, 0x0c, 0x00, 0xb0, 0xc9, 0x9f, + 0xbb, 0xf1, 0x1f, 0xff, 0x80, 0x60, 0x01, 0x20, 0x29, 0xbf, 0x7e, 0x8d, 0xa3, 0x92, 0x7d, 0x63, + 0x8e, 0x22, 0x3c, 0x3e, 0xc3, 0xd7, 0xf8, 0x60, 0x1c, 0x30, 0x0e, 0x17, 0x38, 0xaf, 0xbf, 0x47, + 0xf8, 0x04, 0x0b, 0xfe, 0x91, 0xb7, 0xbb, 0xef, 0xdf, 0xb6, 0x00, 0x10, 0x0f, 0xfc, 0x81, 0x63, + 0xbf, 0x7e, 0x8f, 0xc0, 0x3f, 0xff, 0x84, 0x48, 0x95, 0xe3, 0x88, 0x71, 0xe1, 0xa5, 0x5e, 0xbd, + 0x78, 0xbf, 0x0d, 0x61, 0x47, 0x1f, 0xfe, 0x3c, 0x7a, 0x8b, 0xf5, 0xeb, 0xd7, 0x80, 0x11, 0xc7, + 0xf1, 0x0c, 0x43, 0x10, 0x89, 0x04, 0x11, 0x7a, 0xf5, 0xaa, 0x95, 0x02, 0x5c, 0x42, 0x22, 0x19, + 0x7f, 0x4a, 0xb5, 0x55, 0x55, 0x51, 0x7e, 0xbc, 0x49, 0xa1, 0xdf, 0xc6, 0x3c, 0x3e, 0x83, 0x75, + 0xad, 0xf9, 0x50, 0xd5, 0x0b, 0x62, 0xdf, 0xe7, 0x44, 0x00, 0xec, 0xf7, 0x4e, 0x12, 0x92, 0x2d, + 0x43, 0x4c, 0x54, 0xcd, 0x6d, 0xb4, 0xd3, 0xfc, 0x71, 0x96, 0x45, 0x71, 0xd0, 0x5e, 0x2f, 0xef, + 0x88, 0x8d, 0x0d, 0xa8, 0xf1, 0x8f, 0xc6, 0x38, 0x23, 0x2b, 0xf0, 0x38, 0xd9, 0xb0, 0x00, 0x80, + 0x60, 0x18, 0x88, 0x58, 0x44, 0xa3, 0x01, 0xad, 0x43, 0x7e, 0xff, 0x8c, 0x3f, 0x0e, 0x04, 0x2c, + 0x7d, 0x0f, 0xed, 0x6b, 0xff, 0x6b, 0x3d, 0xa3, 0x22, 0x77, 0x36, 0x73, 0x8e, 0xd6, 0x47, 0x7f, + 0xb6, 0x26, 0xac, 0x1b, 0xb1, 0x57, 0x58, 0x57, 0x36, 0x42, 0x31, 0x40, 0xec, 0xb0, 0xdb, 0x3d, + 0xdb, 0x48, 0x7b, 0xfc, 0x73, 0xa4, 0x20, 0xfa, 0x30, 0x2a, 0x05, 0x84, 0x3e, 0x1a, 0x65, 0xad, + 0xac, 0x9e, 0x70, 0xe5, 0x97, 0x31, 0x5b, 0x50, 0x9d, 0x3d, 0x5c, 0x6d, 0x60, 0x86, 0x63, 0x6f, + 0xf7, 0xcd, 0xce, 0x65, 0xa9, 0xfb, 0xed, 0xe3, 0xd0, 0x03, 0xb3, 0x33, 0x5b, 0xef, 0x73, 0x33, + 0xbb, 0xcb, 0xd5, 0xa7, 0x64, 0x4e, 0xdf, 0xe4, 0xf1, 0x8e, 0xdb, 0xbc, 0xdd, 0xab, 0xdb, 0x7e, + 0xf4, 0xb1, 0x8c, 0xa9, 0x7b, 0x7b, 0x70, 0x11, 0x7e, 0x47, 0x81, 0x60, 0x38, 0xe7, 0x26, 0x27, + 0x01, 0xc5, 0xd9, 0x58, 0x41, 0x69, 0x17, 0x12, 0x35, 0x55, 0x46, 0x20, 0xa7, 0xed, 0xe5, 0xcc, + 0x2e, 0x59, 0x5c, 0xcb, 0xb6, 0xea, 0xb1, 0x43, 0xc7, 0x63, 0x91, 0xb5, 0x52, 0x34, 0x03, 0x5d, + 0x30, 0x1d, 0xa2, 0xb6, 0x0d, 0xb9, 0xe3, 0xdf, 0xb9, 0xbe, 0xee, 0xdb, 0x4a, 0x90, 0x06, 0x2a, + 0x74, 0x61, 0x4c, 0xaf, 0x52, 0xe2, 0x41, 0x50, 0xde, 0x0d, 0xb4, 0xf0, 0x44, 0xf3, 0x41, 0x4d, + 0x33, 0x88, 0xaf, 0xe6, 0xf5, 0xd7, 0xdc, 0x7f, 0x8e, 0x23, 0xa0, 0xb8, 0x6d, 0x7a, 0xf4, 0xc8, + 0xe8, 0x81, 0xbf, 0x09, 0x69, 0x89, 0x16, 0x39, 0x43, 0xe4, 0x0b, 0x78, 0xb8, 0xbf, 0x18, 0x00, + 0x04, 0x63, 0x5c, 0x38, 0x7f, 0x87, 0x04, 0xa5, 0x7e, 0x3b, 0x7f, 0xf8, 0x02, 0x87, 0x04, 0xc6, + 0x5f, 0xbc, 0x4e, 0x01, 0x3e, 0xe2, 0x3a, 0xb8, 0x8d, 0x38, 0xf6, 0x22, 0xe1, 0x2e, 0x8b, 0x7b, + 0xfb, 0xbf, 0x4c, 0xb0, 0xc0, 0x3f, 0x8e, 0x40, 0x52, 0x77, 0xeb, 0xd2, 0x31, 0x2c, 0xc3, 0x95, + 0x26, 0xc0, 0x30, 0x0c, 0x3c, 0x34, 0x0a, 0x4f, 0xbd, 0xfa, 0x3f, 0x86, 0x01, 0xff, 0xa0, 0xf0, + 0xd1, 0x5f, 0x80, 0x65, 0xe1, 0xf9, 0x0a, 0x10, 0x7e, 0xf5, 0xbf, 0x46, 0x98, 0xc4, 0x11, 0xaf, + 0xa6, 0x9e, 0xde, 0x96, 0x75, 0x8e, 0x0d, 0x6b, 0xff, 0x8f, 0x11, 0x1a, 0x04, 0x61, 0x05, 0xe2, + 0x52, 0x71, 0xf1, 0x8c, 0x63, 0x1a, 0x0b, 0x57, 0xaf, 0x47, 0x1f, 0xff, 0x0f, 0x02, 0x08, 0x22, + 0xde, 0xff, 0x77, 0x0d, 0xdf, 0x38, 0x62, 0x3c, 0x30, 0x0d, 0x05, 0xca, 0xfc, 0x57, 0xe8, 0xe6, + 0x72, 0x61, 0xe7, 0x71, 0xff, 0xf0, 0xcf, 0x7e, 0x2b, 0xef, 0xc7, 0x62, 0x29, 0x61, 0x80, 0x60, + 0x18, 0x06, 0x82, 0xd7, 0xef, 0xc7, 0x63, 0xcc, 0x03, 0x00, 0xfe, 0x1a, 0x05, 0x25, 0x7e, 0xfd, + 0x1f, 0x12, 0xa1, 0xa7, 0x87, 0xd8, 0x00, 0x7f, 0xc4, 0x39, 0xaf, 0xdf, 0xaf, 0x1d, 0xa7, 0x98, + 0x04, 0xcd, 0xd3, 0xf1, 0x2d, 0xb8, 0x23, 0xdc, 0xf3, 0x08, 0x21, 0x40, 0x4c, 0xdf, 0xbf, 0x13, + 0x7f, 0x0e, 0x1f, 0xa0, 0x4d, 0x7e, 0xfd, 0x61, 0xbf, 0x1f, 0xa6, 0x71, 0x22, 0xff, 0xc0, 0xb0, + 0xc8, 0x8c, 0x5e, 0x2e, 0xb5, 0x34, 0x10, 0xc4, 0x92, 0x02, 0x9a, 0xaa, 0x71, 0xc6, 0x72, 0x40, + 0x3f, 0xb5, 0x41, 0x50, 0xee, 0xe4, 0x51, 0x86, 0x20, 0x10, 0xe7, 0xd6, 0xbb, 0xdf, 0x8c, 0x06, + 0x9d, 0x1c, 0x04, 0xad, 0xfb, 0xf0, 0xe8, 0xcb, 0x0c, 0x03, 0xf8, 0x68, 0x13, 0x94, 0x57, 0xdf, + 0xb5, 0xe3, 0xe1, 0xf8, 0x68, 0x29, 0x7e, 0xfe, 0xdc, 0xb9, 0x09, 0x7d, 0x17, 0x10, 0xf4, 0xf7, + 0xef, 0xd1, 0xc0, 0x0c, 0xcc, 0xc7, 0xd2, 0xc9, 0xe3, 0x00, 0xff, 0xe1, 0x7a, 0xf5, 0xe6, 0x62, + 0xb9, 0xc8, 0x78, 0x8e, 0x98, 0x88, 0x71, 0x88, 0x87, 0x63, 0x87, 0x02, 0x92, 0x7d, 0x90, 0xde, + 0x0b, 0x1a, 0x40, 0x22, 0x6f, 0x5b, 0xdf, 0xc5, 0x8e, 0x46, 0x2a, 0xe8, 0x0a, 0x6a, 0x65, 0xcd, + 0xc7, 0x95, 0xfc, 0x05, 0x1e, 0x98, 0x04, 0x40, 0x2e, 0xf8, 0x1d, 0xd2, 0x5a, 0xa1, 0xff, 0xae, + 0xa8, 0xd6, 0x47, 0x54, 0x94, 0x56, 0xe0, 0xad, 0x82, 0xcc, 0xf0, 0x4d, 0x7d, 0x4c, 0x74, 0x65, + 0xf6, 0xd5, 0xf8, 0xab, 0xa8, 0x0e, 0xa0, 0x2e, 0xcd, 0xf5, 0x89, 0xdc, 0x80, 0x5b, 0x74, 0x76, + 0x32, 0xc2, 0x0d, 0x5a, 0x6f, 0xc3, 0xed, 0x57, 0x27, 0xdd, 0x9d, 0xb3, 0xc3, 0xbd, 0x3e, 0x65, + 0x6a, 0xca, 0xaf, 0x54, 0x1a, 0xe8, 0xae, 0x08, 0xb1, 0x66, 0xc9, 0xbf, 0x4e, 0xdf, 0xc5, 0x1f, + 0xea, 0xff, 0x60, 0x6e, 0xd2, 0xa5, 0xab, 0x7e, 0xe2, 0x1f, 0xde, 0xcb, 0x7b, 0x77, 0xf6, 0x7e, + 0xce, 0xf4, 0x46, 0x90, 0x18, 0x35, 0x88, 0x58, 0x95, 0x08, 0x6d, 0xf3, 0x30, 0x2a, 0xbb, 0x9e, + 0x34, 0x0d, 0xe7, 0x7c, 0xa2, 0x05, 0x4b, 0x6c, 0x6d, 0x4f, 0x1a, 0x9b, 0x6d, 0xdd, 0x56, 0xee, + 0xb8, 0xc4, 0xb3, 0x64, 0xa0, 0x62, 0x62, 0x34, 0xec, 0x27, 0x30, 0xa4, 0x9b, 0x62, 0xb3, 0xea, + 0x36, 0xde, 0x62, 0xfd, 0xd3, 0xe1, 0xba, 0xb3, 0xbf, 0x04, 0xdf, 0xb6, 0x9b, 0xe9, 0x84, 0x70, + 0x93, 0x65, 0xa1, 0x28, 0x8f, 0xa9, 0xbb, 0xb7, 0xfc, 0xf0, 0x94, 0x8f, 0x7d, 0x52, 0x76, 0x60, + 0xa5, 0x34, 0x4c, 0x0d, 0xa2, 0xdd, 0xbb, 0xdd, 0x3b, 0xf6, 0x3e, 0xf9, 0xa7, 0xcd, 0x3f, 0x90, + 0x50, 0xce, 0xde, 0xab, 0x6f, 0xff, 0xa6, 0x7e, 0xc1, 0x01, 0x4a, 0xc5, 0xdf, 0x1f, 0xfe, 0x3b, + 0x30, 0x45, 0x7a, 0xf5, 0xe2, 0x13, 0xff, 0xc3, 0xf8, 0x70, 0xc5, 0xfb, 0xf1, 0x13, 0xb8, 0x60, + 0x1c, 0x38, 0x64, 0x45, 0x15, 0xf7, 0xef, 0xdf, 0xa3, 0x87, 0xf5, 0xd6, 0x1f, 0xa2, 0xdf, 0xef, + 0x7e, 0x54, 0x45, 0xf2, 0x8e, 0x1f, 0xa0, 0x51, 0x15, 0xf7, 0xe8, 0xfe, 0x1f, 0xfc, 0x78, 0x29, + 0xbf, 0x5e, 0x8f, 0x91, 0x43, 0x7e, 0xc7, 0x49, 0x7c, 0x63, 0x20, 0x28, 0xdf, 0x5e, 0x8e, 0xab, + 0x0d, 0xfb, 0x1c, 0x47, 0xff, 0x87, 0x87, 0x8b, 0xf8, 0x87, 0x1e, 0x1f, 0x90, 0x13, 0x04, 0x17, + 0xbf, 0x87, 0xf1, 0x1f, 0xe4, 0x4b, 0x4b, 0xfc, 0x43, 0xff, 0x04, 0x65, 0x7e, 0x3b, 0x7e, 0x3f, + 0xc0, 0x34, 0x42, 0x3f, 0xfe, 0x3f, 0xd0, 0x46, 0x3b, 0x60, 0x01, 0x0f, 0xfe, 0x82, 0x57, 0xef, + 0xe0, 0x18, 0x07, 0x1c, 0x47, 0x82, 0x4a, 0xf1, 0xda, 0x28, 0x83, 0x68, 0x8b, 0xd7, 0xff, 0xc3, + 0xff, 0x94, 0x63, 0xf7, 0xef, 0xc7, 0x6c, 0x03, 0x00, 0xe3, 0x88, 0x68, 0x32, 0x45, 0xeb, 0xc7, + 0xdf, 0xa8, 0x42, 0x58, 0x60, 0xc4, 0x1b, 0x5d, 0x7d, 0x68, 0x21, 0xf1, 0xf8, 0xff, 0x40, 0xa6, + 0x2f, 0x5a, 0xf4, 0x76, 0x52, 0x40, 0x76, 0x50, 0xc4, 0x92, 0x06, 0xf4, 0x8a, 0xbd, 0xf9, 0x0c, + 0x4b, 0xe8, 0x46, 0xab, 0x55, 0x5a, 0xfe, 0x08, 0x7c, 0x45, 0xf5, 0xff, 0x43, 0xa6, 0xc6, 0x8d, + 0x9d, 0xa5, 0xef, 0x47, 0x7e, 0x9a, 0x6d, 0xb7, 0x50, 0xdc, 0x38, 0x8c, 0x39, 0x01, 0x55, 0x7d, + 0x34, 0xdb, 0x6c, 0xa4, 0x82, 0xaa, 0xa6, 0x2a, 0x94, 0x94, 0x08, 0xbe, 0x50, 0xfa, 0x0d, 0x6b, + 0x55, 0xe8, 0x19, 0x87, 0xf6, 0xed, 0xca, 0x38, 0xfc, 0x3d, 0x06, 0x7b, 0xde, 0xf4, 0xc8, 0xe4, + 0x86, 0x5a, 0x6c, 0x9b, 0x86, 0x01, 0xc3, 0x00, 0xd0, 0x6c, 0x5b, 0xf7, 0xf1, 0x12, 0x97, 0xe9, + 0xa6, 0x72, 0x63, 0x0a, 0x8c, 0x03, 0xff, 0x10, 0x19, 0x02, 0x36, 0x27, 0x64, 0x0c, 0xa7, 0xfb, + 0x47, 0xe3, 0xe1, 0x8f, 0xf4, 0x1f, 0x2b, 0xf8, 0xff, 0xff, 0x20, 0x46, 0xc9, 0x99, 0x03, 0x8f, + 0x09, 0x71, 0x17, 0x12, 0x49, 0xc8, 0x41, 0x03, 0x42, 0x51, 0x00, 0x01, 0x90, 0x76, 0x92, 0x4d, + 0xb2, 0x5f, 0xff, 0xff, 0xfe, 0x2a, 0x70, 0x7a, 0xe4, 0xb3, 0x62, 0x24, 0x77, 0xb0, 0x30, 0xc0, + 0x7e, 0xb2, 0xc5, 0xf1, 0x76, 0x70, 0xaa, 0xbd, 0xb2, 0x4a, 0x5c, 0x88, 0x9c, 0x52, 0x13, 0xd6, + 0xff, 0xc8, 0x37, 0x85, 0x8b, 0xb1, 0x12, 0x66, 0x53, 0x3e, 0x33, 0x77, 0xcd, 0xdb, 0xdc, 0x43, + 0x89, 0x00, 0xce, 0x72, 0x43, 0x7b, 0xc9, 0xbf, 0xff, 0xf9, 0xa9, 0x6b, 0x70, 0x93, 0x90, 0x6d, + 0xc9, 0xb6, 0x71, 0xfd, 0xa9, 0xff, 0x4d, 0x37, 0xb5, 0x49, 0x0d, 0x7f, 0xd7, 0x6d, 0xc2, 0xcd, + 0x46, 0x0f, 0x4e, 0xcb, 0x6c, 0xfe, 0xa6, 0xf6, 0xfc, 0xd9, 0x54, 0x49, 0x56, 0x14, 0x82, 0xd2, + 0xd4, 0x63, 0x6c, 0xd9, 0xbd, 0x4c, 0x52, 0xc4, 0x7f, 0xfa, 0xb1, 0x90, 0xbe, 0xfc, 0xbc, 0xb3, + 0x43, 0x12, 0xfa, 0x71, 0x35, 0xa2, 0x5f, 0x65, 0xa6, 0x7c, 0xab, 0xae, 0xde, 0xe3, 0xf9, 0x00, + 0x06, 0x42, 0x9d, 0xd8, 0xd5, 0x5e, 0x7c, 0xd5, 0x7d, 0x8d, 0x63, 0xc6, 0x3f, 0x61, 0x1f, 0x61, + 0x63, 0x04, 0x01, 0xf9, 0x8d, 0x02, 0x32, 0xbf, 0xad, 0x28, 0x47, 0x35, 0xa5, 0x34, 0xcc, 0x39, + 0x13, 0xed, 0x63, 0xca, 0xca, 0xbf, 0xbc, 0x62, 0x19, 0xe7, 0x8a, 0xb0, 0x40, 0x53, 0x52, 0x7f, + 0x80, 0x7f, 0xfe, 0xc9, 0xff, 0x11, 0xc0, 0x32, 0x04, 0x42, 0x7e, 0x4e, 0x4d, 0x2a, 0x3c, 0x87, + 0xc4, 0xc3, 0x00, 0xc4, 0x71, 0x87, 0xd1, 0x0e, 0x42, 0x87, 0x7c, 0xe7, 0xf8, 0xfc, 0x63, 0x61, + 0x62, 0xaf, 0x5e, 0xf3, 0x46, 0xc7, 0x06, 0x38, 0x3f, 0xc3, 0xff, 0x61, 0xf1, 0x8f, 0xfe, 0x5e, + 0x1f, 0xb0, 0x41, 0x7e, 0x4e, 0xff, 0xc3, 0xff, 0xc8, 0x65, 0xa3, 0xff, 0x8f, 0xfe, 0x83, 0xf5, + 0xff, 0xff, 0x86, 0xc1, 0x0d, 0xfa, 0x5b, 0x79, 0x90, 0xd8, 0xe1, 0xab, 0xfc, 0x47, 0xfd, 0x02, + 0x0a, 0x42, 0x0b, 0xd4, 0x5f, 0x47, 0x78, 0x62, 0x38, 0x8c, 0x05, 0x74, 0x73, 0x2f, 0xc5, 0xeb, + 0x59, 0x10, 0x96, 0xa1, 0x2f, 0xd7, 0xc4, 0x61, 0x7f, 0x55, 0xe8, 0xd1, 0x5f, 0x87, 0x0f, 0xe0, + 0xa0, 0xe2, 0xbe, 0xfd, 0x11, 0x5f, 0xff, 0xc7, 0x40, 0x84, 0xab, 0xf2, 0xe3, 0x91, 0x16, 0x1a, + 0x10, 0x29, 0x7f, 0x55, 0xe8, 0x20, 0x1f, 0xfc, 0x47, 0x11, 0xe0, 0x8c, 0x4b, 0xf4, 0xe7, 0xfe, + 0x23, 0xfc, 0x11, 0x5f, 0xa3, 0x87, 0xff, 0x86, 0x01, 0xc1, 0x05, 0xfc, 0x38, 0xff, 0xf4, 0x11, + 0x8c, 0x82, 0x65, 0x0e, 0x3c, 0x54, 0xd4, 0x37, 0x0c, 0x03, 0xf4, 0x5e, 0x2b, 0x8a, 0xfb, 0xf1, + 0xd8, 0xfc, 0x21, 0xff, 0x11, 0xc8, 0x16, 0xbf, 0x7e, 0xd1, 0x0e, 0x1b, 0xf2, 0x49, 0x9c, 0x38, + 0xf0, 0xfa, 0xbb, 0xc3, 0x4f, 0x09, 0x24, 0xda, 0x9a, 0x47, 0x07, 0x5e, 0x1d, 0xe9, 0x63, 0x08, + 0x3e, 0xed, 0x6a, 0xef, 0x71, 0xe8, 0x20, 0x0f, 0x79, 0xff, 0xea, 0xe5, 0xa3, 0xa9, 0x15, 0xca, + 0x06, 0x44, 0x56, 0xc5, 0x21, 0xdc, 0x43, 0xde, 0xee, 0x9a, 0xf5, 0xef, 0xbd, 0x17, 0x60, 0x4a, + 0xef, 0x17, 0x39, 0x3d, 0xe4, 0x96, 0x5c, 0x97, 0x2b, 0x2e, 0x65, 0xc8, 0xad, 0xc5, 0x65, 0xc3, + 0x9f, 0x97, 0xfb, 0x2d, 0x98, 0x5d, 0x1e, 0xc0, 0xb2, 0xe4, 0xb2, 0x67, 0x22, 0xd8, 0xcb, 0x35, + 0xbc, 0x67, 0x61, 0x0f, 0x15, 0x70, 0xea, 0x36, 0x50, 0x47, 0x02, 0x7f, 0x31, 0xf1, 0xa4, 0x79, + 0x8d, 0xe5, 0x98, 0xd8, 0x14, 0xb5, 0xc8, 0xa7, 0xbe, 0x5a, 0x2d, 0xc4, 0x94, 0x64, 0x4f, 0x26, + 0x03, 0x16, 0x0c, 0x9d, 0xb4, 0x84, 0xd5, 0x8e, 0xbc, 0x68, 0x77, 0x03, 0xde, 0x22, 0x04, 0x61, + 0xbe, 0x93, 0x4e, 0x71, 0xf1, 0x6a, 0xbb, 0x6e, 0x73, 0x81, 0xaa, 0x6d, 0x28, 0x1d, 0x47, 0xac, + 0x6d, 0x12, 0xbf, 0x5c, 0xbd, 0x64, 0xef, 0x1b, 0x98, 0xed, 0x20, 0xb2, 0x9c, 0xa4, 0x72, 0xa9, + 0xa0, 0x5a, 0x0d, 0x47, 0xba, 0xe9, 0x55, 0x64, 0x37, 0x6b, 0x2b, 0x93, 0x1a, 0x38, 0x57, 0x49, + 0xc6, 0x89, 0x6b, 0xde, 0x97, 0xad, 0x3e, 0x4b, 0xcc, 0xdf, 0xd9, 0x82, 0x3a, 0x05, 0x22, 0x6b, + 0xbd, 0xbf, 0xa4, 0x47, 0x00, 0x60, 0x6a, 0xbb, 0xbf, 0xbb, 0x11, 0x38, 0xfa, 0xbe, 0x12, 0x0a, + 0xda, 0x6d, 0xda, 0xeb, 0xe3, 0x88, 0x10, 0x98, 0xfa, 0x0d, 0x98, 0x46, 0xfa, 0xef, 0xfb, 0x8e, + 0x88, 0x9b, 0x7c, 0xd0, 0x50, 0x8d, 0xa6, 0xfb, 0x2f, 0x81, 0xa7, 0x4a, 0x27, 0x4a, 0x11, 0x7b, + 0x65, 0xcb, 0xbe, 0xfe, 0xaa, 0x5e, 0xd8, 0x80, 0x7c, 0xf3, 0xf6, 0x09, 0x0f, 0xbb, 0xd3, 0x2f, + 0xc7, 0x11, 0xfd, 0x82, 0x30, 0xaa, 0xf2, 0x46, 0xbf, 0xc7, 0x8f, 0xec, 0x14, 0x57, 0xaf, 0x47, + 0x62, 0x10, 0xd8, 0xe0, 0xd3, 0x90, 0x60, 0x7d, 0xe3, 0xa7, 0x87, 0xc4, 0x71, 0x1d, 0x12, 0x1c, + 0x38, 0x88, 0x44, 0x74, 0x11, 0xa3, 0xe9, 0x69, 0xc3, 0xef, 0x7f, 0xc4, 0x43, 0xf0, 0x8d, 0x11, + 0x4e, 0x3c, 0x3f, 0x88, 0xe4, 0x27, 0xfc, 0x47, 0xf6, 0x45, 0x87, 0xde, 0xff, 0xff, 0xa0, 0x41, + 0x5e, 0xd7, 0xf1, 0x1c, 0x47, 0xf9, 0x17, 0x4b, 0xff, 0xf8, 0x78, 0x20, 0xaf, 0x5f, 0xf1, 0x0c, + 0xa2, 0x00, 0x7c, 0x62, 0xf5, 0xf5, 0x2e, 0x7a, 0x69, 0x08, 0x24, 0x86, 0x0a, 0xc4, 0x0e, 0x88, + 0x1d, 0xfc, 0xbf, 0xc0, 0x30, 0x04, 0x09, 0x2b, 0xd1, 0xc1, 0x85, 0x94, 0x04, 0x3d, 0x6d, 0xf9, + 0xff, 0xa6, 0x9f, 0x8b, 0x47, 0xa7, 0xe6, 0x62, 0xc3, 0x7e, 0x1d, 0x23, 0xdc, 0x79, 0x46, 0x3c, + 0x74, 0x88, 0xbd, 0x6b, 0x5e, 0xbd, 0x2c, 0x63, 0x20, 0x3d, 0xe0, 0x5f, 0xb7, 0x3f, 0x07, 0x1f, + 0xff, 0xff, 0x00, 0xdc, 0x10, 0x2d, 0xe5, 0xc8, 0xfc, 0x72, 0xe9, 0x77, 0x4d, 0x31, 0x8b, 0x03, + 0x2e, 0x31, 0xcf, 0x87, 0xcf, 0x16, 0x42, 0x1f, 0x04, 0x4d, 0x47, 0xf4, 0xd3, 0x14, 0xa5, 0x25, + 0x1a, 0x9a, 0x6d, 0xb6, 0xdb, 0x78, 0xd5, 0x48, 0xdf, 0x6c, 0xda, 0x7f, 0x53, 0x4d, 0xb6, 0xe0, + 0x18, 0x06, 0x3c, 0x63, 0x40, 0xb3, 0xad, 0xfe, 0xd3, 0x58, 0xb5, 0x2f, 0x5d, 0xb6, 0xfc, 0x5a, + 0x81, 0xf4, 0xce, 0xba, 0x69, 0xfc, 0x38, 0xf8, 0x40, 0x03, 0x41, 0xdb, 0xde, 0xf7, 0x9d, 0x5d, + 0xb6, 0xfc, 0x59, 0x25, 0xa6, 0x5c, 0xda, 0x6d, 0xff, 0xc4, 0x31, 0x1a, 0xbe, 0x83, 0x15, 0xe9, + 0x71, 0xdb, 0x91, 0x7d, 0xc7, 0xf4, 0x08, 0x3b, 0xc2, 0xea, 0x0a, 0x34, 0x47, 0xfa, 0x69, 0xe9, + 0xa6, 0x9a, 0x62, 0x7d, 0xa7, 0x6d, 0xb6, 0xff, 0xf8, 0x61, 0xec, 0x16, 0x9f, 0x77, 0x03, 0x8a, + 0x21, 0xc7, 0x83, 0x8d, 0xd7, 0xc7, 0xc8, 0x00, 0x11, 0x07, 0x69, 0x24, 0xdb, 0x49, 0xff, 0xff, + 0x06, 0x92, 0xe8, 0xf9, 0x11, 0x6e, 0xcf, 0x93, 0x10, 0x46, 0x55, 0x1b, 0xc8, 0xca, 0xa1, 0x7c, + 0x73, 0x1d, 0x98, 0xdf, 0x10, 0xf1, 0x59, 0x88, 0x32, 0x37, 0xb1, 0xf8, 0xbb, 0xd7, 0xbd, 0xfc, + 0x28, 0x2a, 0x2b, 0x2e, 0x76, 0xfb, 0xdf, 0x6b, 0x5d, 0xf6, 0xc0, 0x13, 0x66, 0xc2, 0x8a, 0xfc, + 0xfc, 0x56, 0x54, 0x65, 0x2e, 0x44, 0x4d, 0xdb, 0x03, 0x86, 0x54, 0x61, 0x2e, 0xe4, 0x46, 0x67, + 0x8e, 0x31, 0x95, 0xb5, 0xcb, 0xc7, 0xe5, 0xfa, 0x40, 0x7c, 0xd6, 0xb0, 0xec, 0xcd, 0xcb, 0x24, + 0x04, 0xba, 0xe2, 0x45, 0x35, 0x59, 0x20, 0xaa, 0xda, 0xec, 0xab, 0xd2, 0x32, 0xf3, 0x23, 0x9c, + 0x0a, 0x26, 0xb1, 0x10, 0xe7, 0x41, 0x2b, 0xa6, 0x61, 0xda, 0xf3, 0x51, 0x71, 0x7c, 0xfa, 0xdb, + 0xbd, 0xe0, 0x99, 0xca, 0x44, 0x56, 0xd4, 0x97, 0xa4, 0x91, 0x2e, 0x93, 0x69, 0x3e, 0xf7, 0x4f, + 0xb2, 0xec, 0x18, 0xf6, 0x91, 0x24, 0x5e, 0x90, 0xb8, 0xc2, 0xcf, 0xe6, 0xfd, 0x4a, 0x98, 0xe8, + 0x3f, 0xe1, 0xb0, 0xb5, 0xba, 0xef, 0xbf, 0xc3, 0x10, 0xe1, 0x00, 0xb5, 0xd7, 0xaf, 0x51, 0x75, + 0x5a, 0xf7, 0x80, 0x0e, 0x35, 0x08, 0x06, 0x81, 0x01, 0x7b, 0x94, 0x90, 0x3f, 0xa6, 0x34, 0xc3, + 0xc3, 0x1e, 0xc1, 0x07, 0x7d, 0x00, 0xc9, 0xd0, 0x8e, 0x33, 0x05, 0x4a, 0x64, 0x2f, 0x2a, 0x49, + 0x98, 0xcd, 0xa2, 0xbd, 0xfd, 0xf7, 0xf9, 0x8d, 0x56, 0x35, 0x9a, 0xc5, 0x0c, 0xcb, 0xee, 0x7c, + 0xde, 0xd7, 0xcf, 0xf3, 0x58, 0xd5, 0x58, 0x5f, 0xa7, 0x10, 0xf7, 0x87, 0x07, 0x93, 0x2f, 0xfa, + 0x81, 0x5c, 0x02, 0xc2, 0x21, 0x71, 0xdb, 0x1e, 0x1c, 0x03, 0xf9, 0x12, 0xd3, 0xd2, 0x28, 0x63, + 0xc9, 0x78, 0x87, 0xff, 0xe0, 0x88, 0x68, 0xaf, 0x80, 0xc0, 0x80, 0xd2, 0x2c, 0x26, 0x40, 0x90, + 0x09, 0x1e, 0xb7, 0xe7, 0xff, 0xe2, 0xd8, 0xb6, 0x74, 0x85, 0x19, 0x00, 0x14, 0xf3, 0x5b, 0x7e, + 0x7f, 0xe2, 0x7a, 0x27, 0xbe, 0x29, 0x49, 0x16, 0x96, 0x96, 0xde, 0x78, 0x5e, 0x38, 0x35, 0xad, + 0xad, 0xaf, 0xff, 0xf3, 0x51, 0x86, 0xc3, 0x45, 0xbe, 0x5c, 0x9c, 0x0e, 0x38, 0x28, 0x00, 0x0a, + 0x47, 0x00, 0x02, 0x3e, 0xdb, 0x7f, 0xc3, 0xe0, 0x0b, 0x1a, 0x82, 0x0d, 0x95, 0x7e, 0x9c, 0xa9, + 0xd3, 0x4f, 0xe2, 0x23, 0x51, 0xc6, 0x11, 0xe8, 0x15, 0x41, 0x2a, 0xb1, 0x56, 0xdf, 0xff, 0xfd, + 0xfd, 0x07, 0x49, 0x97, 0x39, 0x71, 0xce, 0x88, 0x9b, 0x6f, 0x16, 0xc5, 0xbc, 0x32, 0xa0, 0x3f, + 0x9c, 0xc0, 0x4d, 0x3f, 0xff, 0xcc, 0xfb, 0x4d, 0x37, 0xfa, 0xbc, 0x5c, 0x7f, 0xee, 0x83, 0x91, + 0x5f, 0x4a, 0x93, 0x80, 0xb8, 0x44, 0x77, 0x5b, 0xad, 0xb1, 0x57, 0xfe, 0x7d, 0xef, 0xe4, 0x11, + 0xcb, 0x8f, 0x72, 0xe5, 0x96, 0xde, 0xf4, 0x68, 0xa8, 0xff, 0xff, 0x47, 0x26, 0xf7, 0xbd, 0xf9, + 0x95, 0x09, 0xa8, 0x3f, 0x20, 0xa6, 0x9e, 0x9a, 0x7f, 0xfc, 0x52, 0xa8, 0x70, 0x62, 0xfa, 0x8f, + 0x8c, 0xfe, 0x40, 0x47, 0xd7, 0xa8, 0x95, 0x1c, 0x69, 0x79, 0x54, 0x1f, 0xd0, 0x2a, 0xa1, 0xc6, + 0x5b, 0xed, 0xff, 0xf5, 0x09, 0xa9, 0x4d, 0xa6, 0x9f, 0xff, 0xed, 0x17, 0x83, 0xae, 0xd7, 0x6d, + 0xbf, 0x9d, 0xfe, 0xf7, 0xf9, 0x04, 0x5e, 0xf7, 0x77, 0xbf, 0x32, 0x4e, 0xa3, 0xab, 0x58, 0xfd, + 0x78, 0xe2, 0x12, 0x04, 0x71, 0x6a, 0x39, 0x80, 0x8c, 0x8b, 0x72, 0x72, 0x0f, 0xdf, 0xd4, 0x38, + 0x3c, 0x39, 0x99, 0x20, 0xab, 0xce, 0x1c, 0xf0, 0xd1, 0x46, 0x0c, 0xed, 0xda, 0x06, 0xe5, 0x3b, + 0x5d, 0xb6, 0xf9, 0x3b, 0xbf, 0x7e, 0xed, 0x24, 0x90, 0xb3, 0x90, 0x87, 0x09, 0x05, 0x52, 0x08, + 0xcf, 0x7d, 0x83, 0xb7, 0x2d, 0x9c, 0xe6, 0x21, 0xca, 0xca, 0x89, 0x2d, 0x8e, 0xdc, 0x54, 0xcc, + 0x57, 0xfa, 0x77, 0x7a, 0x58, 0x1a, 0xdf, 0x90, 0x18, 0x6b, 0xd7, 0x7b, 0xe8, 0xeb, 0xf7, 0xec, + 0xf8, 0x01, 0x16, 0xd1, 0x06, 0xb9, 0xfd, 0xd3, 0x10, 0xfb, 0xf7, 0x4d, 0x3e, 0x93, 0xeb, 0x5e, + 0x51, 0x9c, 0xc3, 0xc5, 0x81, 0x2c, 0xfb, 0xdb, 0x4f, 0x7f, 0x15, 0xb6, 0x21, 0xf7, 0xe4, 0xef, + 0x7b, 0xc5, 0xab, 0x4e, 0x30, 0xb9, 0x8c, 0xa8, 0x7c, 0x35, 0x0e, 0x0f, 0x11, 0x8d, 0x5c, 0x0a, + 0x92, 0x2a, 0x05, 0x8c, 0x35, 0xd8, 0x55, 0x8a, 0x56, 0x7a, 0x79, 0x6d, 0x43, 0xf4, 0x07, 0xf8, + 0xcc, 0x30, 0x0a, 0xde, 0xdf, 0x4f, 0x77, 0x80, 0x4c, 0xe2, 0x8a, 0xb4, 0x77, 0x2b, 0xbe, 0xce, + 0x65, 0x6f, 0x64, 0xa3, 0x5c, 0x77, 0xd7, 0xf1, 0xd4, 0xc2, 0x4f, 0x62, 0xb3, 0xcd, 0xcd, 0x37, + 0x2e, 0x0c, 0x81, 0x87, 0x2f, 0xed, 0xed, 0xb6, 0xd9, 0xd3, 0x20, 0x68, 0xa7, 0xc8, 0xee, 0x3b, + 0xe2, 0xbf, 0x0c, 0x6e, 0x3e, 0x5f, 0x4b, 0xf9, 0x61, 0xb3, 0x4e, 0x52, 0xf1, 0x67, 0xf3, 0x72, + 0xe7, 0xd4, 0x5f, 0xe8, 0x96, 0x70, 0x06, 0x6d, 0x52, 0x7d, 0xe3, 0x6c, 0x2d, 0xf8, 0x3e, 0xb4, + 0x6b, 0x5a, 0xad, 0x7d, 0x54, 0xd9, 0xfa, 0x15, 0x50, 0x81, 0x41, 0x98, 0x54, 0x73, 0x57, 0xf4, + 0x7f, 0x6c, 0xa7, 0xca, 0x8c, 0x12, 0x4c, 0x81, 0x3b, 0x2d, 0xae, 0xb8, 0xe2, 0x94, 0x00, 0xd1, + 0xb6, 0x11, 0xb7, 0xe0, 0x18, 0xf0, 0xec, 0x14, 0x16, 0xfd, 0x3e, 0xb5, 0xf5, 0x9c, 0x31, 0x11, + 0xa0, 0x4d, 0x6c, 0xf6, 0x4f, 0x8a, 0xff, 0xd6, 0x26, 0x38, 0xd6, 0x70, 0xd0, 0xcd, 0xf4, 0xb3, + 0x5b, 0x7f, 0xd5, 0x56, 0x15, 0x58, 0x85, 0x62, 0x73, 0x11, 0x77, 0xdd, 0x2b, 0xed, 0xe3, 0xf5, + 0x55, 0x8a, 0xad, 0x06, 0x68, 0x9a, 0xf9, 0xb0, 0xaa, 0xff, 0xc5, 0x62, 0xe0, 0x16, 0x11, 0x0b, + 0xa3, 0xff, 0x86, 0x01, 0xfc, 0x3e, 0x57, 0xff, 0xff, 0x87, 0x04, 0x37, 0xff, 0xff, 0xf8, 0x22, + 0x1a, 0x2b, 0xe8, 0xe1, 0xff, 0xfe, 0x1c, 0x10, 0x8c, 0x7f, 0xff, 0xee, 0x4e, 0xc7, 0x08, 0x05, + 0x3b, 0xe5, 0xc9, 0x70, 0x3d, 0x0d, 0x46, 0x54, 0x3d, 0x1a, 0x84, 0x22, 0x62, 0x8b, 0xb0, 0xf4, + 0x62, 0x7a, 0x39, 0x17, 0xfc, 0x89, 0xdd, 0xcd, 0xf7, 0x4e, 0x24, 0x92, 0x5c, 0x0e, 0x03, 0xc7, + 0x38, 0x1c, 0xc3, 0x53, 0xf2, 0x2d, 0xfb, 0x62, 0xd5, 0xf9, 0x88, 0x7a, 0x41, 0x90, 0xfa, 0x89, + 0xde, 0x33, 0xf2, 0xd6, 0x58, 0xbf, 0x8c, 0x16, 0xb5, 0xb1, 0xe6, 0xf4, 0x3a, 0x5b, 0x2f, 0x68, + 0xbc, 0x3a, 0x47, 0xd4, 0x95, 0xa8, 0xca, 0x8b, 0x14, 0x63, 0x07, 0xfd, 0x38, 0xfe, 0x75, 0x4f, + 0xde, 0x9a, 0xc7, 0xf2, 0xcb, 0x59, 0x21, 0x6d, 0xdd, 0x5c, 0x19, 0x24, 0x64, 0x33, 0xdb, 0xe9, + 0xff, 0xfe, 0x1f, 0x60, 0x84, 0x32, 0xbd, 0xff, 0xff, 0x87, 0x64, 0x4b, 0x4b, 0x4f, 0xc4, 0x3f, + 0xff, 0x0f, 0x0d, 0x15, 0xf9, 0x71, 0x8f, 0xf0, 0xca, 0x12, 0x2c, 0x75, 0xbf, 0xdd, 0xc5, 0x56, + 0x30, 0xac, 0x07, 0x57, 0xa8, 0x8a, 0x09, 0x11, 0xfb, 0x31, 0xaf, 0x78, 0x04, 0x40, 0x3f, 0x0a, + 0x82, 0x05, 0x39, 0x5d, 0x24, 0xb1, 0x16, 0xbd, 0xff, 0xc3, 0x0e, 0x82, 0xf7, 0x57, 0xbf, 0x22, + 0x71, 0x0e, 0x10, 0x0f, 0xe0, 0x8a, 0xfc, 0x0a, 0x64, 0x4a, 0x20, 0x23, 0xc7, 0x49, 0xe2, 0x49, + 0x03, 0x3b, 0x20, 0xc3, 0xe3, 0x15, 0x7b, 0xff, 0x0f, 0xa0, 0xb0, 0x97, 0xe2, 0xbf, 0x44, 0x5a, + 0xe1, 0xea, 0x21, 0xfa, 0x04, 0x7d, 0xed, 0x8d, 0x7a, 0xbc, 0x0a, 0x22, 0x32, 0x05, 0xb5, 0xd7, + 0x8e, 0x3c, 0x9c, 0x91, 0x1e, 0x95, 0x1c, 0x86, 0x05, 0xb9, 0xf2, 0x47, 0x71, 0xea, 0xf9, 0x4b, + 0xe8, 0x5e, 0xee, 0xf7, 0xbb, 0xdf, 0x1f, 0xe3, 0x1e, 0xb4, 0x12, 0xeb, 0x7f, 0x1f, 0xe3, 0xc6, + 0x12, 0x04, 0x6e, 0x44, 0xa8, 0xad, 0x22, 0x12, 0x42, 0x87, 0x86, 0x70, 0x7c, 0x6a, 0xa3, 0xf1, + 0xe3, 0x48, 0x50, 0x2e, 0xf1, 0x27, 0x8f, 0x2a, 0x69, 0xff, 0xb1, 0x48, 0x99, 0xca, 0x5b, 0xc5, + 0xc6, 0x75, 0x24, 0x15, 0xd1, 0x24, 0x55, 0xb4, 0xb0, 0xe0, 0xf5, 0x96, 0xce, 0x7b, 0x70, 0x0e, + 0x04, 0x81, 0xc3, 0x16, 0x2c, 0x1e, 0xb8, 0x8f, 0x8e, 0x7e, 0x7f, 0x85, 0x70, 0x02, 0x9a, 0xfd, + 0x58, 0x9f, 0xfd, 0xbf, 0xff, 0xdd, 0xb0, 0x77, 0xe1, 0x39, 0xe2, 0x8c, 0x9a, 0x01, 0xb3, 0x40, + 0xfc, 0x88, 0x95, 0xc7, 0x17, 0xab, 0x27, 0xf6, 0xc5, 0x5a, 0x76, 0xec, 0xd2, 0x66, 0xc9, 0x99, + 0x88, 0x02, 0x52, 0xef, 0x6b, 0xda, 0xd1, 0x74, 0x24, 0x8e, 0x04, 0x3d, 0xa4, 0x36, 0x7b, 0xff, + 0x7b, 0xf5, 0xd9, 0x03, 0x68, 0x7b, 0x45, 0x98, 0x93, 0xff, 0x0e, 0x29, 0xe9, 0x78, 0x3e, 0x1e, + 0x59, 0x6b, 0x22, 0x18, 0x85, 0xfc, 0x90, 0xa6, 0x6e, 0xe4, 0xe6, 0x4e, 0xed, 0x84, 0x4a, 0xa4, + 0x17, 0xe0, 0x95, 0x21, 0xfe, 0x6b, 0xc9, 0x15, 0x46, 0xf2, 0xd5, 0xe2, 0xeb, 0xd5, 0xae, 0xe5, + 0xcb, 0x8d, 0xa2, 0xaf, 0x93, 0xf3, 0x85, 0x50, 0xec, 0x81, 0x86, 0x4e, 0xfb, 0x6e, 0x73, 0x24, + 0xb3, 0xed, 0xf4, 0xfc, 0x8e, 0xbf, 0x97, 0xbf, 0x54, 0x59, 0x91, 0xb9, 0xad, 0xc2, 0x0c, 0xd4, + 0xf1, 0xc1, 0x8f, 0x75, 0x1f, 0xb2, 0xe0, 0xa3, 0xf5, 0x7c, 0xd8, 0xa7, 0xe3, 0xd5, 0x9b, 0xbb, + 0x5f, 0xed, 0xe0, 0x90, 0x91, 0xe5, 0x76, 0x6b, 0x35, 0xf5, 0xd6, 0x3b, 0xb1, 0x1e, 0xc3, 0xc2, + 0x12, 0xb1, 0x1e, 0xb5, 0x8b, 0x92, 0x19, 0xfe, 0x59, 0x76, 0x72, 0x08, 0x6f, 0x15, 0x10, 0xd8, + 0x5f, 0xad, 0x7d, 0xba, 0x1a, 0x49, 0x13, 0xe1, 0xcd, 0x73, 0x7d, 0x33, 0xe2, 0xeb, 0xfa, 0x57, + 0x08, 0x41, 0xed, 0x8c, 0xbc, 0x32, 0x69, 0x76, 0x14, 0xef, 0xbd, 0xf2, 0xc8, 0xb9, 0x7e, 0xc3, + 0xc5, 0x7f, 0x97, 0xfd, 0x00, 0x40, 0x62, 0xf9, 0xf9, 0xba, 0x7b, 0xd5, 0xa8, 0x9e, 0x05, 0x51, + 0x81, 0x35, 0x8e, 0x27, 0xff, 0xfb, 0x6d, 0xfe, 0xdc, 0x8b, 0x17, 0xbb, 0x90, 0xf9, 0x0b, 0xed, + 0x3f, 0xaa, 0x8b, 0x9a, 0xd7, 0xe2, 0x6a, 0x6b, 0xc6, 0xa4, 0x6b, 0x97, 0x59, 0x89, 0x7a, 0x36, + 0xb4, 0xb2, 0x2e, 0x2d, 0xff, 0x53, 0xa8, 0x55, 0x56, 0x7e, 0xb3, 0x19, 0xa9, 0x70, 0x99, 0x8d, + 0x7b, 0x77, 0x36, 0x3b, 0x75, 0xbc, 0x43, 0x00, 0x55, 0x4e, 0x16, 0x09, 0x0f, 0x86, 0x05, 0x5a, + 0x24, 0x06, 0x88, 0x82, 0x1a, 0x38, 0x7f, 0xff, 0x87, 0x04, 0x23, 0x1f, 0xfe, 0x4c, 0xe0, 0x1b, + 0x3f, 0x0e, 0x05, 0x12, 0x15, 0xa6, 0x21, 0xc4, 0xcb, 0x1e, 0x12, 0x80, 0x42, 0x83, 0xab, 0x07, + 0x97, 0x88, 0x30, 0xf8, 0x3b, 0x4d, 0xe2, 0x6e, 0xc6, 0x07, 0x0c, 0x87, 0x38, 0x21, 0xcc, 0x19, + 0xd4, 0xb7, 0x92, 0x0a, 0xc4, 0x2b, 0x6f, 0x4e, 0xf4, 0xcb, 0xec, 0x0e, 0x2d, 0x82, 0x1f, 0xb7, + 0xf0, 0x20, 0xc5, 0x08, 0x1b, 0x53, 0x57, 0x53, 0xa4, 0x3d, 0x82, 0xc1, 0xb2, 0x29, 0xd6, 0xb5, + 0x77, 0x8b, 0xf4, 0x83, 0x6f, 0x2e, 0xce, 0x44, 0x3c, 0x7f, 0x85, 0x2d, 0x47, 0x91, 0x8e, 0x99, + 0x3d, 0xfc, 0x4d, 0xa7, 0xb9, 0xbb, 0xda, 0xf5, 0x9e, 0x03, 0x2a, 0xdf, 0xbf, 0x9c, 0xe1, 0xde, + 0x58, 0xc7, 0x7e, 0xab, 0xf3, 0x2b, 0xb3, 0xc5, 0x7c, 0x03, 0x0f, 0x10, 0xd4, 0x77, 0xf0, 0xff, + 0x8b, 0xf5, 0x3a, 0x70, 0xb3, 0xe4, 0xdd, 0x26, 0x93, 0x1b, 0x56, 0xaa, 0xba, 0xdb, 0x48, 0xbe, + 0xc0, 0x92, 0x67, 0x5a, 0x7c, 0xbe, 0xf3, 0xa1, 0x80, 0x67, 0x0a, 0x78, 0xff, 0x65, 0x24, 0x87, + 0x96, 0xb8, 0xb5, 0x6e, 0x09, 0xa4, 0xbe, 0xff, 0x32, 0x09, 0x86, 0xfc, 0x89, 0x68, 0xca, 0x1b, + 0xf2, 0x54, 0x2c, 0x82, 0x00, 0x31, 0xd3, 0x53, 0xcc, 0x29, 0xad, 0x62, 0x4e, 0xf8, 0xb5, 0x05, + 0x55, 0x2c, 0x20, 0x5d, 0x15, 0x62, 0xd8, 0xb7, 0xe1, 0x74, 0x60, 0x48, 0xdc, 0xf3, 0x7f, 0xfe, + 0x9a, 0x61, 0x08, 0x48, 0x77, 0x27, 0x07, 0x37, 0xfe, 0x2b, 0xb8, 0x6e, 0x3e, 0x83, 0x7d, 0x7b, + 0xc4, 0x86, 0xb2, 0x6d, 0x36, 0xb7, 0x5b, 0xbb, 0x6d, 0xc9, 0x70, 0x0e, 0x3f, 0xc2, 0xe2, 0x5f, + 0x8a, 0xf8, 0xc0, 0x57, 0xff, 0xff, 0xa1, 0x1d, 0xfb, 0xde, 0xf7, 0xfd, 0x6a, 0x7a, 0xc2, 0xaa, + 0x82, 0x32, 0x24, 0xa4, 0x80, 0xfe, 0xa2, 0x42, 0x72, 0xd3, 0x3c, 0x49, 0x20, 0x98, 0xfd, 0x98, + 0xa8, 0x76, 0x2d, 0x41, 0xde, 0x84, 0x43, 0xa7, 0xdb, 0x6f, 0xfc, 0x16, 0xe1, 0xfa, 0x04, 0x75, + 0xa5, 0x63, 0xff, 0x10, 0xd5, 0xf4, 0x43, 0x92, 0x14, 0xb2, 0x4a, 0x8a, 0xa1, 0xff, 0xc5, 0x50, + 0x0d, 0xdd, 0xd1, 0x21, 0xc3, 0xab, 0x94, 0x44, 0x24, 0x04, 0x47, 0x15, 0xfc, 0xb0, 0xe3, 0xe0, + 0xb1, 0x01, 0x90, 0x12, 0x5f, 0xc5, 0x8c, 0x20, 0x28, 0x1e, 0x00, 0x52, 0x05, 0xc8, 0xbf, 0x55, + 0xcb, 0x1f, 0xe2, 0x03, 0xf4, 0x08, 0xce, 0xfe, 0x29, 0x91, 0x80, 0x47, 0x4d, 0xa8, 0xf1, 0x53, + 0x91, 0x48, 0x98, 0xe4, 0xdf, 0x51, 0x55, 0xcd, 0x85, 0xf0, 0xa2, 0xab, 0xbc, 0x91, 0x55, 0xc0, + 0xe4, 0x10, 0xe0, 0x64, 0xc2, 0x88, 0xf0, 0xb7, 0x99, 0x4d, 0xdf, 0xf6, 0xfc, 0x25, 0x82, 0x99, + 0x23, 0xf9, 0x72, 0xe1, 0x2c, 0xf1, 0x46, 0xdd, 0xa0, 0xf2, 0x6b, 0xe2, 0x45, 0xef, 0x97, 0x29, + 0xb8, 0xfa, 0xc6, 0xdc, 0xdd, 0xf0, 0x4b, 0x34, 0x05, 0x2c, 0xdb, 0x5a, 0x11, 0x2b, 0x2d, 0xc1, + 0xb7, 0x3f, 0x1e, 0x59, 0x6b, 0xef, 0x68, 0x48, 0x82, 0x40, 0x89, 0xd6, 0x6a, 0x5e, 0xf7, 0xd5, + 0xef, 0xab, 0x65, 0x2c, 0x1a, 0x01, 0xc9, 0xac, 0xe5, 0xde, 0xef, 0xcb, 0xe9, 0x97, 0x6c, 0xd8, + 0xc9, 0xe4, 0xcd, 0x1a, 0x50, 0xce, 0xdc, 0xc5, 0x94, 0x36, 0x78, 0xff, 0x81, 0xd6, 0x4a, 0x4f, + 0x58, 0xe6, 0x80, 0x8d, 0xce, 0x80, 0xea, 0x26, 0x89, 0x86, 0xd1, 0x6f, 0x85, 0x6a, 0x36, 0xfd, + 0xaf, 0xbd, 0xf7, 0x8e, 0xde, 0x8a, 0x67, 0xa5, 0x8e, 0x3d, 0x5e, 0xdc, 0x9f, 0xaf, 0xee, 0x67, + 0xb7, 0x61, 0x95, 0xe3, 0x10, 0xf4, 0x20, 0xa2, 0xe2, 0x39, 0xb5, 0xbf, 0x53, 0x22, 0xa1, 0x2c, + 0xa1, 0x04, 0xb1, 0xdd, 0xbb, 0xbe, 0x31, 0x78, 0xc0, 0x34, 0x16, 0x2c, 0x5d, 0x55, 0x9b, 0xca, + 0xfb, 0xd7, 0x4c, 0x47, 0x11, 0xe1, 0xea, 0xfe, 0x0f, 0x00, 0x89, 0x88, 0x60, 0x29, 0xe5, 0xc3, + 0xe4, 0x26, 0xbb, 0xfb, 0xae, 0x21, 0xec, 0x52, 0xee, 0x4e, 0xc4, 0x19, 0x7a, 0x7d, 0xdd, 0xc5, + 0x7b, 0xf2, 0x6d, 0xf3, 0xf1, 0xd9, 0x8a, 0xdf, 0x7e, 0xfe, 0xf2, 0xe1, 0xec, 0x67, 0xff, 0x3b, + 0x39, 0x61, 0x93, 0x3f, 0x6d, 0xae, 0x59, 0x11, 0x09, 0x10, 0x42, 0x52, 0x01, 0x56, 0x8b, 0xaa, + 0xaa, 0xd7, 0xaa, 0x9b, 0x31, 0xdd, 0xfb, 0xf0, 0x5a, 0xea, 0xf7, 0x2d, 0xcf, 0x4b, 0xd5, 0x7a, + 0xe2, 0x38, 0x89, 0x9f, 0xc0, 0x70, 0xc9, 0x68, 0xd9, 0xba, 0xfd, 0x7d, 0x74, 0xaa, 0x31, 0x22, + 0x51, 0x02, 0x62, 0x77, 0xbf, 0x35, 0xa9, 0xad, 0x7c, 0xf4, 0x42, 0x86, 0x5f, 0x79, 0x79, 0xb2, + 0xfc, 0x62, 0xbe, 0x7d, 0x65, 0x41, 0xb2, 0xe5, 0xcd, 0x97, 0x1e, 0xc1, 0x92, 0x43, 0x14, 0xdb, + 0x6e, 0xda, 0x69, 0xf5, 0x0f, 0x57, 0x98, 0xe3, 0x14, 0x0a, 0x8b, 0x2b, 0x6d, 0xff, 0xd5, 0xed, + 0x88, 0x84, 0x68, 0x84, 0x0e, 0x12, 0xd6, 0x9a, 0x6d, 0x1b, 0x01, 0xb4, 0xa9, 0xe1, 0x17, 0x9c, + 0x7f, 0xc0, 0xc9, 0x11, 0x90, 0xc4, 0xd4, 0x5c, 0x00, 0xfb, 0x70, 0xa3, 0x50, 0xe9, 0x7d, 0x34, + 0xdb, 0xdd, 0x8f, 0xf1, 0xb7, 0xb3, 0xd4, 0xaf, 0xe4, 0x2e, 0x98, 0xb7, 0xdb, 0xf2, 0xa0, 0xea, + 0xe3, 0x77, 0x93, 0x74, 0x4a, 0xff, 0x42, 0x2d, 0x5f, 0x1f, 0x53, 0xfd, 0x9a, 0xda, 0x8e, 0xd8, + 0x3c, 0xa3, 0xb6, 0x3f, 0x07, 0x6c, 0x07, 0xb4, 0x76, 0xdd, 0x41, 0xf7, 0xdb, 0x6f, 0xab, 0x88, + 0x8a, 0x8f, 0x51, 0xd4, 0x9d, 0xd5, 0x6a, 0x9e, 0x33, 0x77, 0x66, 0xfd, 0x46, 0x2f, 0x8e, 0x7a, + 0x7f, 0x2b, 0xd5, 0x8a, 0xfb, 0xbb, 0xeb, 0xbb, 0x58, 0x4a, 0xd0, 0x1d, 0xd2, 0x8c, 0xee, 0x62, + 0x9b, 0x0b, 0x56, 0x0f, 0xd0, 0xde, 0x6d, 0x97, 0x5b, 0xd3, 0xd1, 0xcf, 0x6f, 0x1b, 0xeb, 0x4c, + 0xb2, 0x1d, 0xf4, 0x55, 0x4a, 0x3f, 0xf5, 0x96, 0x45, 0x2d, 0x2a, 0x4e, 0x0a, 0x59, 0x1f, 0x6f, + 0xf8, 0x7e, 0x0f, 0x82, 0xb8, 0x90, 0x79, 0x57, 0xde, 0xef, 0x48, 0x98, 0x30, 0x67, 0x46, 0xc3, + 0x68, 0x87, 0x4e, 0x1d, 0xff, 0x0f, 0x7d, 0xfd, 0x0f, 0xe9, 0x62, 0x1c, 0x5d, 0xe9, 0x4e, 0xaa, + 0x64, 0xda, 0x9f, 0xbf, 0xdf, 0xde, 0xfe, 0xf5, 0xf7, 0x4a, 0x5c, 0x4b, 0x79, 0x72, 0xd2, 0x85, + 0x07, 0x1d, 0x55, 0x4b, 0xed, 0xb7, 0xef, 0x71, 0x7e, 0xf7, 0x7d, 0x50, 0x42, 0x92, 0x45, 0xcb, + 0x97, 0x25, 0xc6, 0xe4, 0x96, 0xe3, 0xa4, 0x88, 0xb5, 0x8a, 0xbf, 0xe3, 0x7b, 0xbf, 0xef, 0xd0, + 0xdd, 0xee, 0x5c, 0x6e, 0x6f, 0xb5, 0xcd, 0x2d, 0x65, 0x8b, 0xd3, 0x4f, 0x8e, 0xff, 0xbf, 0xd1, + 0x7b, 0x97, 0x3d, 0x28, 0xad, 0xdd, 0xcc, 0xa3, 0xff, 0xff, 0x82, 0xd2, 0xaf, 0x10, 0x00, 0x09, + 0x01, 0xd1, 0x96, 0x28, 0x16, 0x28, 0x17, 0xf0, 0xe3, 0xd5, 0xea, 0x0b, 0xa0, 0xef, 0x2e, 0x7b, + 0x91, 0xbd, 0x2f, 0x1e, 0xa3, 0xb3, 0x1f, 0xe9, 0xee, 0x9a, 0x78, 0xb5, 0x01, 0xdb, 0x86, 0x03, + 0x1e, 0x9d, 0xaf, 0x8d, 0x51, 0xdc, 0x85, 0x83, 0xb4, 0xd7, 0xf1, 0x8f, 0x08, 0x3e, 0xae, 0x81, + 0x27, 0x4a, 0x2e, 0xa1, 0x35, 0x0f, 0x7b, 0xff, 0xf4, 0xd3, 0xca, 0x17, 0x5f, 0xff, 0xed, 0xb6, + 0x61, 0x53, 0xfe, 0x65, 0x1b, 0xc8, 0xc9, 0x3a, 0x96, 0x15, 0x09, 0xa8, 0x13, 0x37, 0x3f, 0x37, + 0xfb, 0x6d, 0xff, 0xdf, 0xff, 0xfa, 0x1b, 0x5e, 0xbf, 0x58, 0x82, 0x4b, 0xa6, 0x9b, 0x4d, 0x78, + 0xb4, 0x55, 0x15, 0x0b, 0x74, 0x10, 0xab, 0xf1, 0x6a, 0x9f, 0x74, 0xd3, 0xf2, 0x2c, 0x52, 0xc0, + 0x3b, 0x6e, 0xdf, 0xc7, 0xc4, 0xb8, 0x58, 0xa2, 0x82, 0x1e, 0x24, 0xf5, 0xea, 0x79, 0xe6, 0xe5, + 0x7e, 0x0b, 0x06, 0x51, 0x1c, 0x58, 0xed, 0xef, 0x7b, 0x6d, 0xe5, 0x69, 0x5a, 0x49, 0x92, 0xc6, + 0x9d, 0xb8, 0xca, 0xb3, 0xbb, 0x34, 0xfc, 0x56, 0x06, 0x11, 0xe0, 0x55, 0xe7, 0xe7, 0xef, 0xf5, + 0xae, 0xe5, 0x93, 0x58, 0x99, 0x31, 0x16, 0x8a, 0x4d, 0x6a, 0x42, 0x8a, 0xda, 0xfd, 0xbf, 0x49, + 0xfc, 0x3e, 0x96, 0xc2, 0xad, 0x6a, 0x69, 0x24, 0xed, 0x8a, 0xfd, 0xc6, 0x57, 0x88, 0xde, 0xf8, + 0x53, 0x0c, 0x39, 0x6a, 0xce, 0x21, 0x31, 0xe5, 0xd4, 0x0e, 0xde, 0x64, 0x9f, 0x5b, 0xc2, 0x4c, + 0xe0, 0x09, 0x1f, 0x57, 0xd7, 0xef, 0xeb, 0xfe, 0xf7, 0x97, 0x61, 0xc6, 0xe1, 0x1e, 0x86, 0x08, + 0xbe, 0x6c, 0xa7, 0x8b, 0xeb, 0xfe, 0x21, 0x83, 0x16, 0xd1, 0xb9, 0x72, 0x03, 0x59, 0x65, 0x4d, + 0xd5, 0x8a, 0xbd, 0x37, 0x65, 0xa9, 0x34, 0xbc, 0xb7, 0x8a, 0xc5, 0xc0, 0xd6, 0xf7, 0xab, 0xab, + 0xc2, 0xc5, 0x66, 0x9b, 0x37, 0x50, 0x8b, 0xbe, 0x5e, 0xd5, 0x7d, 0x3e, 0x04, 0xdc, 0xb4, 0xc7, + 0xb4, 0x7b, 0xc5, 0x7d, 0xc7, 0x97, 0xe2, 0xb7, 0xc9, 0x2e, 0x44, 0xdf, 0xf0, 0x1c, 0x80, 0xa4, + 0xf4, 0xb5, 0xff, 0x84, 0x91, 0x00, 0x17, 0xb5, 0x36, 0x81, 0xff, 0xff, 0xab, 0xdb, 0xa5, 0xbf, + 0xdc, 0x34, 0x19, 0x2b, 0x56, 0xa2, 0xff, 0xb0, 0x0e, 0x51, 0x91, 0xcb, 0x76, 0x33, 0x7d, 0x72, + 0xf8, 0x87, 0x1e, 0xf9, 0x11, 0x16, 0x5b, 0xbb, 0x9b, 0xc3, 0x22, 0x2e, 0xee, 0xe2, 0xb7, 0x7a, + 0x55, 0x6b, 0x16, 0xd3, 0xf9, 0x48, 0x5d, 0xee, 0x9b, 0xde, 0xd3, 0xea, 0x98, 0xd0, 0xc0, 0xa7, + 0x91, 0xed, 0x0a, 0x10, 0x09, 0x43, 0x27, 0x62, 0x87, 0x66, 0xb4, 0xdc, 0x88, 0x75, 0x61, 0x7a, + 0x83, 0xb7, 0x56, 0x79, 0x6f, 0x4c, 0x79, 0x75, 0x59, 0x58, 0x21, 0x9b, 0x17, 0x5a, 0xdf, 0x32, + 0x1e, 0x73, 0x95, 0xa9, 0xb1, 0x4d, 0xf5, 0xcb, 0x1e, 0x6c, 0x37, 0x6c, 0x89, 0x20, 0x10, 0x53, + 0x5f, 0xc4, 0x95, 0x2e, 0xf2, 0xe6, 0x8d, 0x9c, 0x20, 0xa0, 0xe5, 0x6d, 0xb3, 0x6c, 0x5f, 0xe3, + 0x06, 0x74, 0x38, 0xda, 0xec, 0x38, 0x8b, 0x0f, 0xf5, 0x52, 0xe3, 0x6d, 0xcb, 0xb3, 0xa3, 0xbb, + 0x3a, 0x33, 0xd2, 0x1f, 0x70, 0x8c, 0x36, 0x18, 0x96, 0xad, 0x77, 0x35, 0x78, 0xa3, 0x3e, 0x5f, + 0x69, 0xf7, 0xce, 0x73, 0x2a, 0x04, 0x27, 0x9a, 0x0e, 0x0c, 0x69, 0xa6, 0xc2, 0xcf, 0xf7, 0xcb, + 0x06, 0xee, 0xbb, 0xdb, 0xee, 0x27, 0xbe, 0xab, 0x5d, 0x5d, 0x60, 0xea, 0xc5, 0xfd, 0x21, 0xac, + 0x9b, 0xf3, 0x75, 0xe5, 0xc0, 0x84, 0x11, 0x80, 0x38, 0x8c, 0x87, 0x37, 0x07, 0x37, 0x2a, 0x0a, + 0x18, 0x5d, 0xdf, 0x70, 0xbc, 0x6e, 0xf1, 0xc2, 0xeb, 0x5c, 0xb9, 0x59, 0x73, 0xaa, 0xdd, 0xc2, + 0x8e, 0x28, 0xfb, 0xb8, 0xa3, 0x0f, 0xff, 0x51, 0x70, 0xdc, 0x1f, 0xee, 0xa5, 0x1d, 0xb1, 0xdf, + 0xbe, 0xcb, 0x69, 0x17, 0x0b, 0x8e, 0x73, 0x9d, 0xf1, 0x05, 0xa1, 0x29, 0x1e, 0x3a, 0x78, 0xee, + 0x9a, 0x7e, 0xee, 0xd8, 0xff, 0x10, 0x5c, 0x5f, 0x6b, 0xdf, 0xba, 0x51, 0x0f, 0x11, 0x93, 0x59, + 0x6b, 0xff, 0xbe, 0xfb, 0xa8, 0xef, 0xa5, 0x26, 0x4b, 0x8b, 0xde, 0xda, 0xfc, 0x43, 0x99, 0x7f, + 0xdf, 0x7d, 0xf2, 0x2b, 0xbb, 0xef, 0x2e, 0x3f, 0x97, 0x2d, 0xc5, 0x66, 0x45, 0x5b, 0xdd, 0xf7, + 0xc4, 0x04, 0x04, 0x96, 0x5c, 0x2e, 0x5b, 0x71, 0xb9, 0xc4, 0x5c, 0x72, 0xdd, 0xe5, 0xf7, 0x37, + 0xb6, 0xda, 0x69, 0xff, 0xdf, 0x75, 0x03, 0xe5, 0x5b, 0xbf, 0x97, 0x3d, 0xbd, 0x6e, 0x26, 0x5f, + 0x4f, 0xfa, 0xbd, 0xee, 0x22, 0x79, 0xc2, 0x6a, 0x5d, 0x9b, 0xcb, 0x94, 0xc2, 0x8a, 0xdd, 0x79, + 0xcd, 0xf6, 0xff, 0xee, 0xaf, 0x79, 0x80, 0x90, 0x74, 0x58, 0xef, 0x9d, 0xee, 0xdb, 0x83, 0xdd, + 0xbb, 0xcf, 0xb8, 0xca, 0xf7, 0x1d, 0xdf, 0x7e, 0x50, 0xa1, 0xdb, 0x66, 0x7f, 0x77, 0x15, 0xf5, + 0x4d, 0x3f, 0xe6, 0xea, 0x3d, 0xcf, 0xf3, 0x42, 0x2e, 0x5c, 0x4e, 0xda, 0x19, 0x5f, 0x8a, 0xf3, + 0x5b, 0xeb, 0xbe, 0xb3, 0x1e, 0x8b, 0xe9, 0x7a, 0xf7, 0xa7, 0x5f, 0xfa, 0x10, 0xff, 0x7b, 0xdf, + 0xbc, 0x1c, 0x11, 0x31, 0x6e, 0xee, 0x20, 0x45, 0x59, 0xc4, 0x9d, 0x12, 0x77, 0x6d, 0xb0, 0x9a, + 0x80, 0x9f, 0xb3, 0xef, 0x7f, 0xf7, 0xc9, 0xf9, 0xff, 0xd3, 0x26, 0x37, 0x5f, 0xb7, 0xeb, 0x1f, + 0xa0, 0xee, 0xe4, 0xc9, 0xa9, 0xa9, 0x16, 0x54, 0xd3, 0xff, 0xd6, 0x4e, 0x40, 0x41, 0x23, 0xd6, + 0x7c, 0xef, 0x36, 0x76, 0xeb, 0x2e, 0x55, 0xb6, 0xff, 0xf0, 0xa0, 0x9b, 0x97, 0x07, 0x54, 0x3b, + 0x57, 0x55, 0x4c, 0x5e, 0xb6, 0xb5, 0xdb, 0x6f, 0x4d, 0x30, 0xba, 0x80, 0xfd, 0x52, 0xbd, 0x5d, + 0x34, 0xdb, 0xff, 0x92, 0x2d, 0x24, 0xbf, 0x1c, 0xdf, 0x13, 0xfa, 0xad, 0x7e, 0xbc, 0xd8, 0xb7, + 0x9b, 0xc7, 0x3f, 0xb6, 0xdd, 0xf5, 0x93, 0xce, 0x2a, 0x26, 0xae, 0x83, 0xbb, 0xef, 0x3e, 0x34, + 0x65, 0xff, 0x4d, 0x3e, 0x31, 0xd0, 0x20, 0x04, 0x63, 0x43, 0xca, 0xb1, 0x5f, 0x79, 0x3a, 0x2c, + 0x13, 0x45, 0x5d, 0xbf, 0xf8, 0x8f, 0xa2, 0x79, 0x0f, 0x88, 0x7a, 0x7b, 0x8a, 0xda, 0x69, 0x2f, + 0xda, 0xbf, 0x8d, 0x55, 0xdd, 0xc4, 0x55, 0x1f, 0x49, 0xae, 0x6c, 0x36, 0x25, 0xab, 0xd8, 0x0e, + 0x3d, 0x41, 0xea, 0xee, 0x88, 0x33, 0xb3, 0x36, 0x36, 0xe5, 0xc2, 0x7c, 0x89, 0xa7, 0x1f, 0x36, + 0x05, 0xc1, 0x0f, 0xdf, 0x49, 0x74, 0xaf, 0x1d, 0x2a, 0x69, 0xff, 0xea, 0x05, 0xe0, 0x00, 0x09, + 0x43, 0xb8, 0xbe, 0x2b, 0xfb, 0x45, 0x4b, 0x6d, 0xff, 0x13, 0xbc, 0x61, 0x83, 0xea, 0xa9, 0xf3, + 0x65, 0xdf, 0x8b, 0x9b, 0x1b, 0x6d, 0x35, 0x29, 0x42, 0x21, 0x80, 0x60, 0x18, 0x02, 0x05, 0x54, + 0x7d, 0x34, 0xff, 0xd8, 0x19, 0x9b, 0x26, 0x68, 0x59, 0x88, 0x3c, 0xd7, 0x76, 0xd9, 0x6b, 0x4f, + 0x03, 0x02, 0x7c, 0x0b, 0xe7, 0xe2, 0x5f, 0x5f, 0xed, 0xe4, 0x05, 0x01, 0x68, 0x61, 0x9e, 0x89, + 0x62, 0xb4, 0xf4, 0xb1, 0x2e, 0x09, 0x59, 0x25, 0xb7, 0x84, 0x9c, 0x01, 0xad, 0x77, 0x87, 0xcf, + 0xf7, 0xbd, 0xb3, 0x74, 0xd9, 0xef, 0xf4, 0x11, 0xa2, 0x50, 0x10, 0xe0, 0xc2, 0xe2, 0x1f, 0x8e, + 0x2b, 0x4f, 0xda, 0xf6, 0xc0, 0x57, 0xec, 0xc5, 0x2c, 0x48, 0x15, 0x17, 0xdf, 0x77, 0x84, 0x60, + 0x9b, 0x7b, 0x30, 0x37, 0xea, 0xa4, 0xdf, 0x7e, 0x58, 0xa7, 0x92, 0x13, 0xc4, 0x8b, 0x1b, 0xbc, + 0x8a, 0x17, 0xad, 0x27, 0x4d, 0x44, 0xae, 0x19, 0x9b, 0xfa, 0xba, 0x49, 0x3b, 0xbf, 0x6f, 0xda, + 0x1c, 0x49, 0x9a, 0x48, 0x45, 0xae, 0xee, 0xfb, 0x77, 0xb2, 0x25, 0xc1, 0x02, 0x5a, 0xde, 0x6a, + 0x7f, 0x10, 0x93, 0x72, 0x94, 0xa8, 0x5f, 0x5d, 0x62, 0xf1, 0x78, 0xb8, 0x95, 0x00, 0x93, 0xf2, + 0x72, 0xf0, 0xee, 0xdf, 0xa1, 0x00, 0xe1, 0xf4, 0x28, 0xab, 0xef, 0xdf, 0xda, 0x19, 0x7f, 0xd9, + 0x8d, 0xbe, 0xed, 0x55, 0x3c, 0xd2, 0xfb, 0x5f, 0xb2, 0x7a, 0x89, 0x02, 0xc7, 0x77, 0xbb, 0xbd, + 0xdf, 0xf2, 0xe2, 0x8b, 0xf9, 0x39, 0x9c, 0x78, 0x63, 0xd8, 0x50, 0xab, 0xef, 0xe5, 0xdb, 0x66, + 0xf6, 0x68, 0x50, 0xd6, 0x37, 0x4e, 0x17, 0xa9, 0x3b, 0xbf, 0xb6, 0xc4, 0xc1, 0x61, 0xc1, 0x94, + 0xde, 0xde, 0x2e, 0x9f, 0xbf, 0x8f, 0xe5, 0x34, 0x49, 0xcd, 0x99, 0x0d, 0x15, 0x21, 0x35, 0x29, + 0xb2, 0xab, 0xd2, 0x68, 0xf1, 0xdb, 0xb2, 0x61, 0x33, 0xa6, 0x5c, 0x4f, 0x15, 0x9b, 0xe9, 0x49, + 0x48, 0x82, 0xd8, 0x57, 0xd9, 0xd5, 0xb6, 0x21, 0x46, 0x70, 0x07, 0xbd, 0xe8, 0xb3, 0x93, 0xb6, + 0x2a, 0xe9, 0x35, 0xa6, 0xdd, 0x1e, 0x8d, 0xe3, 0x94, 0x04, 0x8b, 0x77, 0x3f, 0x84, 0xda, 0x36, + 0xff, 0x55, 0x55, 0x4d, 0x34, 0xd3, 0x0a, 0xe0, 0x6b, 0xaa, 0xcf, 0x6d, 0xb4, 0xd3, 0x6b, 0x4b, + 0xdf, 0xe8, 0xa5, 0x5d, 0x8f, 0x4c, 0xd2, 0x71, 0x0f, 0x9d, 0xa2, 0xe3, 0xf7, 0xc5, 0x91, 0xdc, + 0xfd, 0xf8, 0x80, 0x9c, 0xe8, 0x15, 0x0e, 0x08, 0x99, 0x0c, 0x55, 0xca, 0x02, 0x9d, 0xff, 0xf7, + 0xcd, 0xa4, 0x57, 0xe5, 0x55, 0x36, 0x37, 0x1c, 0xb8, 0x5b, 0xbe, 0x96, 0xf0, 0x38, 0x00, 0x54, + 0xf2, 0x55, 0xba, 0xb1, 0xc4, 0x5e, 0xbf, 0xbf, 0xf0, 0x02, 0xf4, 0x22, 0x2f, 0x7d, 0x72, 0xfd, + 0xd3, 0x37, 0x2f, 0xdf, 0xf4, 0x63, 0x3c, 0x67, 0x5d, 0x5f, 0xc3, 0x8f, 0x22, 0x8f, 0x97, 0x29, + 0xb6, 0x98, 0xa5, 0xe6, 0x74, 0x7b, 0xe1, 0x37, 0x8b, 0x8a, 0x5a, 0xcb, 0xd3, 0x6f, 0x2e, 0x16, + 0xce, 0x73, 0xe5, 0xeb, 0xe2, 0xaf, 0xee, 0xa2, 0x02, 0x1a, 0x0e, 0x84, 0x45, 0x4a, 0x5f, 0xd5, + 0xad, 0x69, 0x9b, 0xc7, 0x96, 0x7e, 0xa6, 0xee, 0x8c, 0x19, 0x9c, 0x8d, 0x6a, 0xbd, 0x49, 0x0e, + 0xb1, 0x9f, 0x5b, 0xfe, 0xcb, 0xaf, 0xad, 0x41, 0xc4, 0x48, 0xbb, 0xfb, 0x74, 0xa0, 0xcb, 0x5d, + 0x27, 0x79, 0x92, 0x15, 0x24, 0x03, 0xb3, 0x4e, 0xbe, 0xff, 0xfa, 0xcd, 0xdb, 0x67, 0x86, 0x1a, + 0x86, 0x37, 0x3a, 0xf7, 0x88, 0x1c, 0x2f, 0x39, 0xfc, 0x4f, 0x1f, 0x99, 0x5b, 0x5e, 0x06, 0xd4, + 0x07, 0x90, 0x85, 0x22, 0x9f, 0x13, 0xac, 0xbc, 0xff, 0xcd, 0xbb, 0x75, 0x5e, 0xd8, 0x9f, 0xa3, + 0x50, 0x20, 0x94, 0x4b, 0x5d, 0x30, 0x75, 0x79, 0xba, 0xdd, 0x31, 0x0e, 0x7b, 0x5d, 0x9e, 0x8f, + 0x18, 0x8d, 0xfd, 0x86, 0xf7, 0x27, 0xad, 0x39, 0x72, 0x3b, 0x69, 0xdb, 0xf9, 0x7f, 0xff, 0x8f, + 0x21, 0x7f, 0xc1, 0xc8, 0x79, 0x7b, 0x51, 0x80, 0x00, 0x20, 0x0a, 0x86, 0x80, 0x54, 0x71, 0xb6, + 0xde, 0xdb, 0x7f, 0xfd, 0xf7, 0xd0, 0x66, 0xed, 0x97, 0x22, 0x10, 0xe7, 0xe7, 0x21, 0x75, 0x47, + 0xa6, 0x9f, 0xfe, 0xdb, 0x63, 0xea, 0x69, 0xff, 0xc7, 0xeb, 0x57, 0xd6, 0x81, 0x6d, 0xfa, 0xa4, + 0x97, 0xe1, 0x75, 0x02, 0x12, 0xde, 0xfc, 0xdf, 0xfe, 0xdb, 0x7c, 0x54, 0xd3, 0xf4, 0xd3, 0x09, + 0xa8, 0x60, 0x4d, 0x0d, 0xb7, 0xb6, 0xdf, 0x5a, 0xfc, 0x78, 0xf5, 0x18, 0x7b, 0xbe, 0x9e, 0x9d, + 0x34, 0xfd, 0xb6, 0xff, 0xfd, 0x7d, 0x0d, 0x9f, 0x19, 0xe7, 0x34, 0xcb, 0x9d, 0x28, 0x3d, 0x2f, + 0x4d, 0x34, 0xff, 0x8d, 0x46, 0x3f, 0xe8, 0x6c, 0xd9, 0xcb, 0xaf, 0x4d, 0x6f, 0x17, 0x0e, 0xdd, + 0xb6, 0xff, 0xe3, 0xc2, 0x39, 0xaf, 0x17, 0xbb, 0x73, 0x71, 0x0e, 0x45, 0x6d, 0xdc, 0xd9, 0x91, + 0x26, 0xd3, 0x6f, 0xfc, 0x2e, 0x30, 0x28, 0xba, 0x44, 0xd6, 0xcf, 0xc5, 0x4d, 0x52, 0xbe, 0xad, + 0x56, 0xa9, 0x25, 0xb6, 0xdf, 0xd5, 0xea, 0xae, 0x23, 0x1d, 0x28, 0x7c, 0xfe, 0x5f, 0x7c, 0x65, + 0x7e, 0x18, 0xf4, 0x80, 0x2a, 0xdb, 0xd3, 0x4f, 0x88, 0x61, 0xbe, 0x01, 0xd1, 0x6a, 0xe4, 0xc9, + 0x69, 0xc5, 0xcf, 0x4b, 0xb5, 0xa5, 0x68, 0x61, 0x59, 0x4d, 0x36, 0x9a, 0xfd, 0x5c, 0x9d, 0xea, + 0xe3, 0x0d, 0x5d, 0x48, 0x5c, 0x6b, 0x85, 0xea, 0xec, 0x89, 0x9a, 0x93, 0xda, 0x5d, 0xda, 0x15, + 0x38, 0xcd, 0xed, 0xff, 0xd4, 0x57, 0x8f, 0xd7, 0xaf, 0xa7, 0x75, 0xd7, 0xb1, 0x6e, 0x92, 0x5e, + 0x13, 0x50, 0x43, 0xf9, 0xbe, 0x7d, 0xb6, 0xfd, 0x34, 0xf4, 0xd3, 0x19, 0x4d, 0xc9, 0x48, 0x2c, + 0x26, 0x00, 0x43, 0x2b, 0xe4, 0xe4, 0xc5, 0x2a, 0xa9, 0xf3, 0xb7, 0xb7, 0xbd, 0xc0, 0xec, 0x80, + 0x62, 0x28, 0x38, 0x0e, 0xfb, 0xf7, 0xf0, 0x63, 0x6a, 0x59, 0x89, 0xad, 0x6c, 0x45, 0xbe, 0x7d, + 0x4b, 0x2f, 0x6c, 0xbf, 0xbe, 0x0d, 0x66, 0x60, 0x83, 0x42, 0x1b, 0x04, 0x47, 0x73, 0xe7, 0x47, + 0x76, 0x64, 0xe1, 0x10, 0xc4, 0x76, 0x7c, 0xdf, 0x4f, 0xdf, 0xbe, 0x1a, 0x08, 0x99, 0xff, 0xb3, + 0x8a, 0x54, 0xe6, 0xc7, 0xa3, 0x77, 0xdb, 0xa3, 0xaf, 0x8b, 0x10, 0x7f, 0x2a, 0x04, 0xa3, 0x78, + 0xad, 0xa1, 0x54, 0x60, 0x06, 0xac, 0x74, 0xa5, 0xf7, 0xd5, 0x55, 0x7f, 0xdb, 0x05, 0x09, 0x08, + 0x46, 0xa8, 0x5c, 0x86, 0x3a, 0x5c, 0xec, 0x5a, 0x6c, 0x62, 0x8e, 0xd4, 0x93, 0xf8, 0x01, 0x11, + 0x65, 0xc5, 0x64, 0x51, 0x47, 0x14, 0x71, 0x5b, 0xbe, 0xd6, 0xfd, 0xf7, 0x94, 0xdc, 0x5c, 0x02, + 0x97, 0xbd, 0x4f, 0x8f, 0xa6, 0x2e, 0x38, 0xb2, 0xaa, 0x9a, 0x1d, 0x51, 0x3c, 0x6d, 0xcf, 0xff, + 0x71, 0xa0, 0x09, 0x11, 0x14, 0x5d, 0x55, 0x6b, 0x11, 0xf9, 0xdf, 0x17, 0xaf, 0xb6, 0x6a, 0x47, + 0xc2, 0x30, 0xb2, 0x09, 0x9c, 0x09, 0xd7, 0xa9, 0x2b, 0xfe, 0x89, 0x42, 0x20, 0xb3, 0x15, 0x84, + 0x4c, 0x5e, 0xc5, 0x79, 0xe8, 0x41, 0xc2, 0x40, 0xa9, 0x73, 0xf4, 0xfb, 0x89, 0x50, 0x16, 0x64, + 0x92, 0xdb, 0xe0, 0x03, 0x22, 0x94, 0x08, 0x08, 0x8a, 0xcf, 0xdf, 0xbd, 0xfb, 0xf9, 0x5a, 0xdb, + 0x14, 0x2d, 0x67, 0x11, 0xcd, 0xe9, 0xa4, 0xba, 0x6a, 0x59, 0xbe, 0x1a, 0x08, 0xa2, 0x4a, 0x16, + 0x53, 0xa4, 0xd1, 0x7d, 0x6c, 0x9b, 0xcd, 0xff, 0xb3, 0x3a, 0x12, 0x2e, 0xdf, 0x71, 0x68, 0xa7, + 0xcc, 0xd0, 0xd1, 0x49, 0x1d, 0xcd, 0x17, 0x7e, 0xfc, 0x73, 0x02, 0x88, 0xd1, 0x88, 0xa9, 0x12, + 0xaf, 0x76, 0x8f, 0xad, 0xd2, 0xe1, 0x60, 0xd4, 0x59, 0x72, 0x6d, 0x7c, 0xb1, 0x8a, 0x53, 0x54, + 0x50, 0x52, 0x0a, 0xb4, 0xff, 0x79, 0xf3, 0xd9, 0x4a, 0x92, 0x04, 0x21, 0x5e, 0xad, 0x51, 0xdd, + 0x9c, 0xf8, 0xfe, 0xd6, 0x5f, 0xbf, 0x1f, 0xc8, 0x82, 0x01, 0x09, 0xca, 0xee, 0xab, 0xbf, 0xbe, + 0xf8, 0xff, 0x21, 0xd1, 0x08, 0xa3, 0x29, 0xa7, 0xbf, 0xcf, 0xb8, 0x0c, 0xc1, 0x0e, 0xbd, 0x12, + 0x88, 0x12, 0x6f, 0xdf, 0x9d, 0x39, 0xca, 0xa6, 0x92, 0x87, 0x06, 0x5c, 0xde, 0xa9, 0x76, 0x5d, + 0x06, 0x05, 0x84, 0x94, 0x2a, 0x97, 0x55, 0x77, 0xcc, 0x21, 0x83, 0xc8, 0xe2, 0xdb, 0x96, 0xea, + 0xd5, 0xc9, 0xc2, 0xf5, 0xa4, 0x17, 0xab, 0x20, 0xef, 0xe9, 0xc3, 0x51, 0x86, 0xe9, 0x87, 0x13, + 0x17, 0x7f, 0xa3, 0xa3, 0x03, 0xac, 0x12, 0x6f, 0x3e, 0x6c, 0xaa, 0x76, 0x84, 0xfc, 0x4b, 0xae, + 0xbe, 0xa6, 0x9f, 0xf6, 0x17, 0xe3, 0x45, 0xb8, 0x06, 0x99, 0x4d, 0x95, 0x56, 0x6f, 0xa6, 0x6f, + 0xdf, 0x6d, 0x3b, 0x9a, 0x1b, 0x92, 0x8b, 0x04, 0xf6, 0x32, 0x78, 0xe5, 0x67, 0x38, 0x2f, 0xfc, + 0x43, 0xf6, 0xcb, 0xcd, 0xf1, 0x6d, 0x3f, 0x6d, 0xff, 0x6b, 0x0b, 0xc6, 0x30, 0x47, 0x10, 0xf4, + 0xeb, 0x77, 0x15, 0xd3, 0x6f, 0x1c, 0x54, 0xa4, 0xfe, 0x65, 0xf1, 0x95, 0x74, 0xd3, 0xfb, 0x32, + 0x9c, 0x8a, 0xe4, 0x80, 0x20, 0xa6, 0x49, 0x3c, 0xd9, 0x36, 0x42, 0xe1, 0x51, 0x27, 0x34, 0xc1, + 0x9d, 0x6e, 0xfc, 0x3c, 0xf6, 0x4f, 0x5f, 0xca, 0xcb, 0x0a, 0x03, 0x22, 0x04, 0xc8, 0xb0, 0xaf, + 0x11, 0xbb, 0xc6, 0xac, 0xee, 0xf1, 0x56, 0x66, 0x3d, 0x2a, 0x68, 0xfc, 0x5c, 0x9f, 0x65, 0x00, + 0x47, 0x00, 0x63, 0x24, 0xa2, 0x79, 0x27, 0xf3, 0x1d, 0x5d, 0x9f, 0x5f, 0xb6, 0xf1, 0xa2, 0x87, + 0x3d, 0xb6, 0xfe, 0xf3, 0x82, 0xce, 0xca, 0xa4, 0xa1, 0x52, 0x1b, 0x0d, 0x82, 0x7c, 0xfe, 0x2a, + 0xce, 0x5b, 0xbe, 0xf7, 0x18, 0xa4, 0x9c, 0xbe, 0x6f, 0xe6, 0xe3, 0x0f, 0x26, 0xfa, 0x56, 0x9a, + 0x9b, 0x9b, 0x39, 0x8d, 0x7f, 0xc5, 0x78, 0x87, 0x23, 0x10, 0x7a, 0xfc, 0xbf, 0xa2, 0xee, 0x95, + 0x1b, 0xfb, 0xc4, 0xc9, 0xf5, 0x75, 0x1d, 0x75, 0x44, 0x58, 0xd2, 0x0f, 0x0f, 0x14, 0xe0, 0x1c, + 0xbb, 0x55, 0x38, 0x73, 0x2d, 0xc4, 0x04, 0x11, 0x44, 0x55, 0xb6, 0xdb, 0x7f, 0x7f, 0xd6, 0x2f, + 0xe2, 0x86, 0xf0, 0xaa, 0xa9, 0xdc, 0x66, 0xe4, 0xfe, 0x5c, 0xc6, 0xe9, 0xa7, 0xfe, 0xb9, 0xd7, + 0xab, 0xe4, 0x0c, 0x56, 0x99, 0x72, 0xfc, 0xde, 0xb5, 0x9a, 0x88, 0xc0, 0x70, 0x42, 0xfd, 0xe9, + 0x1f, 0xcd, 0x5e, 0x13, 0x50, 0xe0, 0x0e, 0xf2, 0x6e, 0xd9, 0x3c, 0x6d, 0xb6, 0x9a, 0x7f, 0xf1, + 0xd9, 0x95, 0x26, 0x2a, 0xef, 0x5f, 0xaa, 0xa5, 0xba, 0x7e, 0xe9, 0xe5, 0xc6, 0xbc, 0x77, 0x90, + 0x9a, 0x80, 0x43, 0x5d, 0x73, 0x6f, 0x4d, 0x34, 0xd3, 0xfd, 0x34, 0xe2, 0xfe, 0x73, 0xee, 0xa8, + 0x26, 0x40, 0x4b, 0xd2, 0xd6, 0x0a, 0xf0, 0xef, 0x78, 0xac, 0xfb, 0xef, 0x5d, 0x38, 0x87, 0xba, + 0x54, 0xad, 0xdb, 0x6f, 0xe6, 0xd3, 0x2e, 0xe2, 0xef, 0xcd, 0x08, 0x2c, 0xbf, 0x72, 0xe0, 0xca, + 0xb7, 0x2d, 0x1b, 0xf7, 0x35, 0x1e, 0xfb, 0xf9, 0x94, 0x8b, 0x8a, 0xe9, 0x5e, 0x2b, 0x9f, 0xdf, + 0xb6, 0x3e, 0xe1, 0xda, 0x4e, 0x8b, 0x47, 0x4b, 0xb5, 0x9b, 0x04, 0xff, 0x6c, 0xbf, 0x06, 0xb4, + 0x32, 0x6a, 0xe0, 0x15, 0x67, 0x8b, 0x8a, 0x06, 0x96, 0x17, 0xad, 0xfa, 0xdf, 0x5e, 0x5c, 0xc4, + 0x0e, 0x25, 0x07, 0x9f, 0x26, 0x33, 0x06, 0xb6, 0xae, 0x63, 0x12, 0x85, 0x39, 0xab, 0x46, 0x4a, + 0xdc, 0xba, 0x52, 0xe1, 0x22, 0xbf, 0x19, 0x5e, 0xa8, 0x8c, 0x86, 0xd5, 0xc4, 0xd8, 0x22, 0x1c, + 0x17, 0x05, 0xa9, 0xb7, 0xdd, 0xaa, 0xab, 0xb5, 0x5b, 0x98, 0xbb, 0x7f, 0x9a, 0xd6, 0xc4, 0xc4, + 0x24, 0x76, 0x62, 0x20, 0x43, 0x9a, 0x43, 0x54, 0x10, 0xe5, 0xbe, 0xdd, 0x62, 0xb5, 0x08, 0x98, + 0x64, 0xc4, 0x38, 0x29, 0x48, 0x25, 0x46, 0x06, 0x6d, 0xf6, 0x0c, 0x52, 0xd2, 0x6b, 0x5a, 0xc7, + 0xd1, 0x66, 0xef, 0xdf, 0x07, 0x22, 0xa5, 0xe8, 0x4b, 0x94, 0x3f, 0x66, 0x04, 0xb0, 0x8e, 0x9e, + 0xac, 0xbd, 0x76, 0x5d, 0x94, 0x55, 0xd1, 0xd8, 0x96, 0x50, 0x97, 0xfa, 0xdd, 0xa2, 0x07, 0xe9, + 0x99, 0xa2, 0x10, 0x10, 0x11, 0x7d, 0x0e, 0x88, 0x70, 0x4f, 0x3a, 0x4c, 0x69, 0xb1, 0xfe, 0x6c, + 0xee, 0xdc, 0x58, 0x90, 0xe4, 0x53, 0x2f, 0xd8, 0x78, 0x5a, 0xdd, 0xe4, 0xe1, 0x49, 0x58, 0x83, + 0x0a, 0xa5, 0xee, 0x96, 0xb6, 0xf7, 0x5e, 0xbd, 0x74, 0xe3, 0x1f, 0x40, 0x86, 0xbe, 0xa6, 0x26, + 0xea, 0xf0, 0x51, 0xde, 0x24, 0x0b, 0x76, 0xaa, 0x92, 0xdb, 0x73, 0x16, 0x73, 0x9f, 0xb1, 0x95, + 0x1a, 0x9a, 0x24, 0xb8, 0xc6, 0x4b, 0xf7, 0xf6, 0x54, 0x9b, 0x05, 0x2a, 0xf1, 0x71, 0x60, 0xa6, + 0xe6, 0x32, 0xb1, 0xbd, 0x2f, 0xe1, 0x29, 0x53, 0x80, 0x51, 0xef, 0x77, 0x7e, 0xee, 0x9d, 0xef, + 0x7e, 0x45, 0x7c, 0x6c, 0x58, 0x00, 0xcc, 0x6b, 0xdd, 0xdc, 0x57, 0x7b, 0xe8, 0xef, 0x62, 0x2d, + 0xb9, 0x3e, 0x45, 0x3e, 0xe7, 0xdf, 0x77, 0x97, 0xdd, 0xe5, 0x70, 0x96, 0x75, 0x02, 0x5c, 0x24, + 0x1c, 0xca, 0xc0, 0xb1, 0x62, 0xb9, 0x4b, 0xba, 0x64, 0xbf, 0xc4, 0xf3, 0x8f, 0x2c, 0x49, 0xf3, + 0x5d, 0xad, 0x09, 0x17, 0xad, 0x40, 0x82, 0x3c, 0x5c, 0x92, 0xc4, 0xd5, 0xba, 0x0b, 0xd9, 0x15, + 0xc7, 0x4f, 0x14, 0x32, 0x9c, 0xe6, 0xa5, 0xb6, 0x4c, 0xd7, 0x11, 0x81, 0xe0, 0x68, 0xb2, 0x3d, + 0x98, 0xf3, 0xea, 0x77, 0x72, 0x12, 0x0c, 0x92, 0x34, 0xcb, 0x02, 0xfe, 0x78, 0x77, 0x8a, 0xad, + 0x73, 0x11, 0xa9, 0xf2, 0x2d, 0x11, 0xf1, 0xc7, 0x13, 0x6e, 0x36, 0x0d, 0x82, 0x5e, 0x48, 0x24, + 0x1c, 0xa4, 0xf4, 0x77, 0x01, 0x90, 0xca, 0x43, 0x88, 0x84, 0x81, 0x62, 0x9e, 0x06, 0xd5, 0xb9, + 0xbf, 0xa3, 0x35, 0x1b, 0x4a, 0x75, 0x08, 0xc8, 0x46, 0x1d, 0x8e, 0xf8, 0x8d, 0xff, 0x6e, 0x98, + 0xb7, 0x4d, 0x3c, 0x51, 0x7f, 0x6d, 0x12, 0x8c, 0x13, 0x62, 0xbc, 0x92, 0x3e, 0xbd, 0x29, 0xc6, + 0x03, 0x80, 0x14, 0x57, 0x85, 0xcb, 0x77, 0xbb, 0xe4, 0xf8, 0x9c, 0xf4, 0xfa, 0xe6, 0x81, 0x0e, + 0xab, 0xed, 0x03, 0x1f, 0x10, 0x3d, 0x12, 0x89, 0x34, 0xc2, 0x6b, 0x9d, 0x23, 0x82, 0x16, 0xdb, + 0xdd, 0xaa, 0xab, 0x50, 0x04, 0xa1, 0x7b, 0x46, 0xc9, 0xe8, 0xb2, 0x88, 0xbb, 0xe9, 0x60, 0xc4, + 0x0e, 0x89, 0x30, 0xb8, 0x9e, 0x6c, 0x93, 0xb4, 0xcf, 0x37, 0x4f, 0x76, 0x73, 0x70, 0x10, 0x04, + 0x6d, 0x79, 0xf8, 0x55, 0x40, 0x84, 0x33, 0x53, 0xe8, 0xfb, 0xa7, 0xbe, 0x9a, 0x7a, 0x69, 0xcd, + 0xa3, 0xa3, 0x8f, 0x57, 0x65, 0x8b, 0xba, 0xdb, 0x1e, 0x56, 0xca, 0xa4, 0xba, 0x76, 0x9d, 0xde, + 0x97, 0xbb, 0xd3, 0x4f, 0xfd, 0x0d, 0xc2, 0xf3, 0x39, 0x01, 0xcc, 0x88, 0x85, 0xf5, 0xb7, 0x2b, + 0x88, 0x79, 0xb1, 0x62, 0xd3, 0xcf, 0xe3, 0x3a, 0xc8, 0xca, 0x67, 0xc0, 0xcc, 0x01, 0xc4, 0x45, + 0x62, 0xbb, 0xbd, 0xb2, 0xe6, 0xb9, 0xfd, 0x55, 0x8b, 0xb4, 0x6e, 0xfd, 0x5b, 0x37, 0x5f, 0xec, + 0x14, 0xcd, 0x9d, 0x2a, 0xe3, 0xa4, 0x59, 0xf9, 0xfd, 0x97, 0x6f, 0x74, 0x07, 0xcf, 0xd9, 0xe9, + 0x8c, 0x2b, 0x34, 0x54, 0xa3, 0x37, 0x18, 0xef, 0x5e, 0x94, 0x4b, 0xbe, 0x21, 0xc1, 0x95, 0x38, + 0x71, 0xbd, 0x64, 0xf2, 0xc8, 0x55, 0x5d, 0x62, 0x75, 0x70, 0x78, 0x43, 0x51, 0x15, 0xa5, 0x6e, + 0xa6, 0x0f, 0x7c, 0x7f, 0xb1, 0x96, 0xf5, 0x9b, 0x9f, 0xd4, 0xee, 0x7f, 0x05, 0xc9, 0x37, 0xbf, + 0xea, 0xea, 0xef, 0x18, 0x01, 0xae, 0xea, 0xb1, 0xd5, 0x6e, 0x47, 0xb7, 0x12, 0x2e, 0x69, 0xbf, + 0xc4, 0x3c, 0x4f, 0x30, 0xc7, 0x52, 0xa6, 0xdb, 0xff, 0xd7, 0xcd, 0xdf, 0xe8, 0x2f, 0x3d, 0xab, + 0x97, 0xbf, 0x76, 0xc1, 0xdb, 0x1c, 0xf8, 0xa3, 0xa1, 0xf6, 0x48, 0x6a, 0x24, 0x7b, 0xbf, 0xee, + 0x5e, 0xad, 0xf8, 0x87, 0xac, 0x6e, 0xcb, 0x6f, 0x8c, 0x02, 0x08, 0x24, 0x01, 0xea, 0x49, 0x50, + 0x06, 0x00, 0x42, 0xbd, 0x2b, 0x70, 0x7f, 0xe5, 0xba, 0xea, 0xcb, 0x89, 0xdf, 0xcd, 0xc8, 0xca, + 0xee, 0x6e, 0xaa, 0x23, 0xfc, 0x88, 0x8a, 0xef, 0xd2, 0x7d, 0xdc, 0xb7, 0x26, 0xa6, 0x2b, 0x83, + 0x32, 0x60, 0x4a, 0x38, 0x3a, 0xd6, 0xe2, 0xf2, 0x08, 0x25, 0xd6, 0xd2, 0xe5, 0xcf, 0x9a, 0x15, + 0x50, 0x42, 0x79, 0xa2, 0xde, 0xdf, 0xdb, 0x57, 0x57, 0x52, 0xee, 0x02, 0xe6, 0xaa, 0x2a, 0xf2, + 0xbc, 0x48, 0x7d, 0xf6, 0x8b, 0xdb, 0x6f, 0xdf, 0xdb, 0xbb, 0x96, 0x01, 0x6a, 0x61, 0x21, 0x65, + 0xc1, 0x5b, 0xfb, 0xcb, 0xaf, 0x8a, 0x6f, 0xe3, 0x1f, 0x82, 0x50, 0xd3, 0x8a, 0xef, 0x6e, 0xde, + 0xf8, 0xa5, 0x19, 0x26, 0x9a, 0x7f, 0x8e, 0x88, 0x4d, 0x20, 0x37, 0xcd, 0xe3, 0xc9, 0x5f, 0xb7, + 0x2f, 0x2e, 0x62, 0xb8, 0xda, 0xdb, 0x6f, 0xe4, 0x41, 0x9d, 0x95, 0xc7, 0x80, 0x25, 0xdf, 0xed, + 0x74, 0x9f, 0x5c, 0x48, 0xa3, 0x08, 0x44, 0x09, 0xdf, 0x7b, 0x91, 0x53, 0xc5, 0x72, 0xed, 0x24, + 0xcb, 0x85, 0xf1, 0x24, 0xe9, 0x38, 0x8e, 0xbd, 0xf7, 0xab, 0xe5, 0xb8, 0x9d, 0x72, 0x6c, 0x65, + 0x4b, 0x95, 0x6b, 0x69, 0x3e, 0x09, 0xd9, 0x6d, 0x25, 0x8b, 0xbd, 0xb6, 0xff, 0xbb, 0x8b, 0xde, + 0xf7, 0x50, 0x11, 0x8a, 0x51, 0x58, 0x87, 0x21, 0x45, 0x65, 0xb9, 0x27, 0x38, 0xb7, 0xb5, 0x9b, + 0xcc, 0x7c, 0x75, 0x5a, 0x39, 0x80, 0x50, 0x58, 0x3a, 0x9f, 0xb3, 0x2d, 0xdd, 0x29, 0x4d, 0x36, + 0xea, 0xd0, 0x87, 0xcb, 0xc4, 0xf5, 0xb6, 0xff, 0xc3, 0x14, 0xe3, 0xf9, 0x33, 0xfd, 0x5a, 0xeb, + 0x77, 0x2d, 0xfe, 0xb3, 0xb6, 0xf7, 0xf9, 0x9a, 0x34, 0xa0, 0x8c, 0x50, 0x17, 0x02, 0x6b, 0x9b, + 0xcf, 0xc6, 0x57, 0x02, 0x8f, 0x25, 0xc9, 0xeb, 0x22, 0xfd, 0x61, 0x22, 0xb5, 0x9e, 0xdc, 0x20, + 0x13, 0xd8, 0x29, 0x40, 0x5b, 0x66, 0xf4, 0x57, 0xc6, 0xc1, 0x54, 0xcc, 0xd8, 0xff, 0xc4, 0xb8, + 0x4f, 0x79, 0x9d, 0x94, 0x05, 0xc8, 0x45, 0xf6, 0xc2, 0xc5, 0x89, 0x6c, 0xf9, 0xdb, 0x9b, 0x93, + 0xfc, 0x3d, 0xeb, 0x44, 0x8f, 0x20, 0x7c, 0x84, 0xd7, 0x6d, 0x96, 0x6a, 0x54, 0x06, 0xb0, 0x7d, + 0x86, 0x69, 0xfd, 0xb9, 0x6f, 0x04, 0xc1, 0x3f, 0x14, 0x41, 0x89, 0xb1, 0x35, 0x4c, 0x73, 0xb1, + 0xd6, 0x85, 0xe9, 0x43, 0x13, 0x41, 0xa1, 0x0e, 0x23, 0x97, 0xfb, 0x74, 0xe6, 0xdf, 0x72, 0x6c, + 0x36, 0xb7, 0x00, 0x21, 0x45, 0xbe, 0xe2, 0xbf, 0xde, 0xe6, 0x33, 0xca, 0x0d, 0x4b, 0x42, 0x83, + 0xfb, 0xd6, 0x9f, 0x82, 0x17, 0x93, 0xd5, 0x7e, 0x2b, 0xd3, 0xac, 0x56, 0xf4, 0xaa, 0x10, 0x02, + 0x94, 0x20, 0x2d, 0x82, 0x5d, 0xf1, 0x03, 0xee, 0x2b, 0xbe, 0xef, 0x47, 0x71, 0xff, 0xc0, 0xb9, + 0x04, 0x5f, 0x14, 0x78, 0xaf, 0x2f, 0xc7, 0xc5, 0xfc, 0x32, 0xe7, 0x02, 0xf4, 0x32, 0xee, 0x5f, + 0x1c, 0xbe, 0x9d, 0xde, 0x15, 0x24, 0x0a, 0xf6, 0x46, 0xbd, 0x6b, 0x7b, 0xfd, 0xe5, 0x21, 0x01, + 0x09, 0x67, 0x72, 0x29, 0x21, 0xc1, 0xa9, 0x48, 0x8a, 0x58, 0xe5, 0x27, 0x2b, 0x7e, 0xf9, 0xb8, + 0x5e, 0xae, 0x6c, 0x85, 0xca, 0xc9, 0x39, 0x5b, 0xaa, 0x52, 0xfe, 0xd3, 0x25, 0x7a, 0xa7, 0xe6, + 0xc5, 0x5f, 0x17, 0xbd, 0xa8, 0xec, 0x7e, 0xe8, 0xcc, 0x21, 0xe3, 0x28, 0x8d, 0x15, 0x2e, 0x6f, + 0x8a, 0xcd, 0xc1, 0xfe, 0xa4, 0x7d, 0xab, 0x8d, 0x64, 0xcc, 0x0e, 0x85, 0x15, 0x15, 0x57, 0x5a, + 0x29, 0x16, 0xd2, 0xf1, 0xb3, 0x27, 0xe3, 0xb9, 0x3f, 0x3a, 0x57, 0xa6, 0x5f, 0x21, 0x4e, 0x23, + 0x69, 0x31, 0x17, 0xcd, 0xd2, 0xf9, 0xbd, 0xfc, 0x95, 0x4c, 0x16, 0xe5, 0x38, 0xa3, 0x73, 0x76, + 0x4e, 0xfc, 0x2e, 0xe4, 0xcb, 0x5e, 0x88, 0x92, 0x3c, 0x1b, 0x00, 0x8e, 0x03, 0x8d, 0xff, 0x1b, + 0x54, 0x8e, 0xdd, 0x36, 0xd3, 0x3d, 0x76, 0xd3, 0xdc, 0xd9, 0x17, 0xfc, 0x45, 0x5c, 0x84, 0x91, + 0xbd, 0xfe, 0xfa, 0x71, 0xd5, 0x6e, 0x7f, 0x04, 0xcb, 0x99, 0x76, 0x13, 0xbb, 0xbe, 0x13, 0xf2, + 0x0a, 0x43, 0x14, 0xc6, 0x22, 0xcb, 0xde, 0xff, 0x7d, 0x6a, 0x31, 0x3a, 0x29, 0x46, 0xdd, 0x8a, + 0x2d, 0xdf, 0x5e, 0xfe, 0x7b, 0xe6, 0xd0, 0x8f, 0xba, 0xeb, 0xde, 0xba, 0xfc, 0x33, 0x9a, 0x6a, + 0xf4, 0x8a, 0x04, 0x62, 0x0d, 0x83, 0x5a, 0x6b, 0xe6, 0xd2, 0x86, 0x2c, 0x94, 0x43, 0x4b, 0xcf, + 0x35, 0xd6, 0xdf, 0xca, 0xf5, 0xe9, 0xdc, 0x21, 0x28, 0x3a, 0x0a, 0x88, 0x48, 0xb0, 0xbf, 0x46, + 0xc1, 0x65, 0xa3, 0x67, 0xdf, 0x58, 0xa9, 0xa0, 0x2a, 0x2a, 0x44, 0xdd, 0xa1, 0x3b, 0x66, 0xc7, + 0xf3, 0xee, 0xad, 0x7c, 0x43, 0x80, 0xf7, 0x83, 0x7b, 0x32, 0x27, 0x1e, 0x02, 0xae, 0xd1, 0x93, + 0xba, 0x6e, 0x5f, 0xc6, 0xfa, 0x6f, 0x52, 0xe6, 0x37, 0x76, 0xff, 0xe3, 0x80, 0xf7, 0xf4, 0xb5, + 0xde, 0xfb, 0xb6, 0x14, 0x57, 0xbe, 0x50, 0xaa, 0x20, 0x03, 0x35, 0x39, 0xdb, 0xf7, 0x3b, 0xaf, + 0xc5, 0xc9, 0xe3, 0x75, 0x78, 0xd2, 0x9c, 0x46, 0x44, 0xf8, 0x56, 0x80, 0x44, 0x11, 0xc2, 0x8a, + 0xdb, 0xf7, 0xaf, 0xe1, 0xd7, 0xb1, 0xb4, 0x2d, 0x9d, 0x29, 0xce, 0xc6, 0x5a, 0xfc, 0xbc, 0xfd, + 0x3a, 0x6f, 0x53, 0x78, 0xfd, 0x38, 0x1a, 0xf8, 0x8e, 0xb7, 0xf9, 0xbb, 0x31, 0xad, 0xdb, 0x4d, + 0xbe, 0xe3, 0x0f, 0xe9, 0xff, 0x46, 0x30, 0x55, 0x41, 0x00, 0xf4, 0x66, 0x2b, 0x69, 0x6c, 0xcf, + 0x3f, 0x5a, 0xcc, 0xdb, 0xc3, 0xc6, 0x62, 0xe1, 0xf2, 0x1b, 0xbb, 0x3d, 0x69, 0xa6, 0x4d, 0xb4, + 0xa9, 0x46, 0x8a, 0xbb, 0x6d, 0xff, 0x82, 0x16, 0x43, 0xd3, 0xa3, 0xdf, 0x50, 0x63, 0x77, 0x8f, + 0xaf, 0xd5, 0xf1, 0x72, 0x9f, 0xc7, 0x86, 0xeb, 0xb0, 0x51, 0x7f, 0x07, 0x6e, 0x6d, 0x52, 0xf3, + 0x4b, 0xcd, 0xb1, 0x06, 0x56, 0xcf, 0x14, 0xa0, 0xf7, 0xcf, 0x82, 0x1f, 0x59, 0x49, 0xad, 0x79, + 0xbb, 0x9b, 0xaa, 0xaa, 0x2c, 0x28, 0xe3, 0x29, 0x8e, 0x11, 0x30, 0x08, 0x26, 0x88, 0xb4, 0x9f, + 0x15, 0xb5, 0x89, 0xfa, 0x6b, 0x17, 0xbc, 0x7d, 0xad, 0x7e, 0x02, 0x14, 0x70, 0xa9, 0x1a, 0xd2, + 0x89, 0x7b, 0xec, 0x6d, 0xe2, 0x1f, 0x07, 0xbe, 0xfe, 0xf8, 0xe9, 0xbc, 0x4c, 0x08, 0x1a, 0xc7, + 0xb4, 0x2a, 0xdd, 0xf7, 0x97, 0xdb, 0xf6, 0xa3, 0x58, 0x97, 0xd0, 0x12, 0xb5, 0xc4, 0x20, 0x14, + 0x63, 0x0a, 0xf7, 0xe9, 0xcb, 0xdd, 0xbe, 0x11, 0xb8, 0x3e, 0xe5, 0xf6, 0x94, 0x86, 0xbf, 0x26, + 0x17, 0x21, 0x40, 0x55, 0xe3, 0xcc, 0xac, 0x73, 0x57, 0x1c, 0x40, 0x79, 0x2d, 0x25, 0xfb, 0x8d, + 0xac, 0x6e, 0xef, 0x6e, 0xc6, 0x20, 0x73, 0x33, 0x8b, 0x6d, 0xff, 0xab, 0xf3, 0x98, 0x85, 0x2b, + 0x22, 0x8e, 0xfa, 0xeb, 0xb6, 0x6c, 0xaf, 0x74, 0xdf, 0x14, 0x5b, 0xf8, 0xe6, 0x08, 0x39, 0x39, + 0x0d, 0x2d, 0xdb, 0x97, 0x31, 0x5e, 0xee, 0x28, 0xc4, 0xe9, 0xed, 0x35, 0x35, 0x57, 0xbc, 0x74, + 0x17, 0xa7, 0xbc, 0x57, 0x15, 0x99, 0xb3, 0x58, 0x85, 0xed, 0x63, 0x0e, 0x4c, 0x43, 0xe1, 0x45, + 0x6b, 0x59, 0x72, 0xde, 0xee, 0xf5, 0xe9, 0xf7, 0x3a, 0x69, 0xfd, 0xd2, 0x68, 0xca, 0xe0, 0x84, + 0x48, 0x68, 0x50, 0x59, 0xbb, 0x65, 0xe3, 0x4d, 0x6d, 0xbf, 0xfa, 0x8c, 0x9a, 0x99, 0x31, 0xe4, + 0x08, 0x1a, 0xc2, 0x6d, 0x95, 0xb8, 0x14, 0x10, 0xc9, 0xd2, 0xe4, 0xbc, 0x22, 0x60, 0xc4, 0x30, + 0xc2, 0x01, 0x19, 0xb0, 0xdf, 0x57, 0x73, 0x6a, 0xf6, 0x66, 0x80, 0xc4, 0x19, 0xae, 0xa0, 0xb5, + 0x9e, 0x5e, 0x2b, 0x96, 0xef, 0x1d, 0x49, 0x8a, 0xda, 0x15, 0xc1, 0x10, 0xbd, 0x96, 0x5e, 0x33, + 0x3d, 0x08, 0x8e, 0x97, 0x7f, 0xbf, 0xb6, 0x8e, 0xec, 0x58, 0x9e, 0x4e, 0x1b, 0x8a, 0xb6, 0x26, + 0xc9, 0x11, 0xb9, 0xfe, 0xb4, 0xd7, 0x8c, 0xa9, 0x36, 0xf5, 0x08, 0xb2, 0x04, 0x80, 0xf7, 0x4b, + 0xfb, 0x7f, 0xfa, 0x25, 0x47, 0xf4, 0xa0, 0x21, 0x19, 0x7d, 0x3b, 0xf4, 0xf4, 0xb8, 0x8c, 0xe3, + 0xcc, 0x1a, 0xbb, 0x5c, 0xf9, 0x4e, 0x9d, 0x91, 0xb4, 0xba, 0xfb, 0x54, 0xe8, 0x79, 0xb0, 0x3e, + 0x68, 0xe6, 0xeb, 0x7e, 0x6c, 0xeb, 0x35, 0x21, 0x71, 0x0d, 0x55, 0x54, 0xf8, 0x4e, 0xfd, 0x29, + 0x61, 0x94, 0x7d, 0x63, 0x84, 0xac, 0xc7, 0x4f, 0xd7, 0x19, 0x5c, 0x91, 0x59, 0xe5, 0x50, 0x64, + 0x04, 0xe4, 0x5b, 0x52, 0xc3, 0x36, 0xde, 0x0e, 0xde, 0xfb, 0xc2, 0xae, 0x00, 0xf5, 0xf7, 0x85, + 0x7b, 0xfa, 0xb2, 0x56, 0x57, 0xb8, 0xff, 0xfe, 0x4f, 0x26, 0xe9, 0x42, 0x37, 0x77, 0x5f, 0x7d, + 0xf2, 0xfe, 0x96, 0xe5, 0x6a, 0xf9, 0x7b, 0xff, 0x2f, 0x15, 0xbd, 0xde, 0x11, 0x70, 0x09, 0x9f, + 0x49, 0xd6, 0x7f, 0xfd, 0x6b, 0x22, 0x27, 0x27, 0xca, 0xd0, 0x88, 0x11, 0xf7, 0x2f, 0x14, 0x69, + 0x6e, 0xf5, 0x7d, 0x6f, 0xc0, 0x8b, 0x20, 0x7b, 0xc5, 0x2b, 0xfa, 0xc7, 0x95, 0xa5, 0x36, 0x4a, + 0xca, 0x89, 0xe3, 0xf6, 0xd8, 0x70, 0xb7, 0x27, 0x6b, 0xe6, 0x9f, 0xac, 0x5e, 0xa8, 0xbe, 0xe2, + 0xd0, 0x2c, 0xd8, 0x40, 0xe4, 0xac, 0x57, 0xad, 0x71, 0x9f, 0xa2, 0x3f, 0x47, 0x73, 0x34, 0xe5, + 0x59, 0x47, 0xb1, 0x9d, 0x24, 0x91, 0x47, 0x2e, 0x63, 0x66, 0x57, 0x24, 0xcb, 0x9d, 0x06, 0xd6, + 0xf1, 0x94, 0xef, 0xd2, 0x69, 0xed, 0xf8, 0xb5, 0x09, 0x2e, 0x9a, 0x74, 0x2b, 0x7f, 0xb5, 0xdd, + 0x47, 0xe0, 0x87, 0x4a, 0x66, 0x2f, 0x59, 0xab, 0xa3, 0x47, 0x67, 0xd9, 0xa6, 0x9b, 0x7e, 0x9c, + 0x86, 0xc2, 0x48, 0x1c, 0xd9, 0xb6, 0xec, 0xc6, 0xfb, 0xf8, 0x87, 0xbc, 0x4b, 0xa3, 0x25, 0x4a, + 0x8e, 0xf9, 0x08, 0x87, 0xff, 0x0f, 0x16, 0xe2, 0xbc, 0x0e, 0xb8, 0x60, 0x62, 0x22, 0x12, 0x04, + 0xfa, 0x58, 0xaf, 0x84, 0x70, 0xfd, 0x56, 0x6c, 0x55, 0xf7, 0x5f, 0x8a, 0xf8, 0x7f, 0x88, 0x1c, + 0xd2, 0x18, 0xd7, 0x9b, 0xfd, 0xe0, 0x18, 0x08, 0xf1, 0x11, 0xa0, 0xfd, 0xa9, 0xb3, 0xa2, 0xa7, + 0x4f, 0x04, 0x44, 0x43, 0x86, 0x53, 0xb5, 0x0a, 0xcd, 0xba, 0xe9, 0xe1, 0x5a, 0x77, 0x1b, 0x62, + 0xf7, 0xf8, 0xdb, 0x7e, 0x08, 0x80, 0x96, 0xf5, 0x24, 0x5f, 0x7b, 0xc4, 0x3e, 0x37, 0x37, 0xb7, + 0xdc, 0x4f, 0x86, 0x00, 0x17, 0x3c, 0x59, 0xad, 0xb0, 0x84, 0x44, 0x6d, 0x3f, 0xb9, 0x8f, 0x78, + 0xed, 0x0a, 0x1a, 0x70, 0xdb, 0xee, 0xb9, 0xab, 0x88, 0x7a, 0x97, 0x38, 0xda, 0x55, 0x3b, 0xfe, + 0xfd, 0xe2, 0x07, 0xa2, 0x69, 0x54, 0xbb, 0x89, 0x31, 0x0e, 0xdf, 0xd3, 0x7d, 0x5b, 0x17, 0xa9, + 0x83, 0xc8, 0x5a, 0xa6, 0x29, 0xc8, 0x0f, 0x58, 0x50, 0x56, 0xbd, 0xb6, 0xa9, 0xd5, 0xb5, 0xdb, + 0xb9, 0x00, 0xea, 0xbf, 0xde, 0x1c, 0x31, 0x2b, 0x18, 0x49, 0x88, 0x1e, 0xe9, 0x9f, 0x9b, 0x4d, + 0xc9, 0x15, 0x77, 0x3f, 0xf1, 0x58, 0xf7, 0xdf, 0xdb, 0xf1, 0x51, 0xfb, 0x2f, 0xe3, 0x90, 0x04, + 0xc5, 0x12, 0x15, 0x93, 0xbb, 0x62, 0xd5, 0xad, 0x92, 0x2b, 0xc7, 0x2f, 0x6f, 0x76, 0xcb, 0xd7, + 0x4d, 0x3f, 0xba, 0xb8, 0x83, 0xde, 0x1e, 0x08, 0x95, 0xdd, 0xea, 0x2b, 0x26, 0x58, 0x97, 0xed, + 0xb5, 0x15, 0xb5, 0x22, 0xf8, 0x55, 0x5e, 0xe4, 0x68, 0x10, 0xd3, 0x93, 0x16, 0x2d, 0xe2, 0x1e, + 0x92, 0x7b, 0xe5, 0x60, 0x2f, 0xab, 0x7b, 0xfa, 0x7d, 0xe9, 0x62, 0x15, 0xb7, 0x6d, 0xff, 0x58, + 0x9e, 0x6d, 0x44, 0xc9, 0xf9, 0x42, 0x47, 0x0f, 0xa2, 0x8b, 0xee, 0x88, 0xfd, 0x77, 0x88, 0x1c, + 0x6e, 0xba, 0x3b, 0xda, 0xd5, 0xc4, 0x54, 0x2b, 0xb4, 0x49, 0xcb, 0xdf, 0xe2, 0xbb, 0x9b, 0x9b, + 0x2b, 0x3e, 0xc0, 0xb4, 0xbb, 0x0f, 0x80, 0xb8, 0xb0, 0x09, 0xa2, 0x55, 0x9d, 0x73, 0x61, 0x34, + 0x2f, 0x5d, 0xde, 0x3a, 0xa3, 0xb9, 0xd1, 0xd4, 0x50, 0xef, 0x38, 0x65, 0x0a, 0xe9, 0x4b, 0x96, + 0xe6, 0xfb, 0x05, 0x1d, 0x5c, 0xe9, 0x72, 0x00, 0x42, 0xe9, 0x9b, 0xf3, 0x65, 0x72, 0x74, 0xed, + 0x9f, 0xd8, 0x5b, 0x4b, 0x5e, 0xf5, 0x6d, 0x45, 0xfb, 0x62, 0x7e, 0xef, 0xc2, 0x3a, 0x02, 0x78, + 0x80, 0xf7, 0x75, 0x97, 0x92, 0x2b, 0xf5, 0x6f, 0xac, 0x89, 0xbd, 0xfc, 0x2a, 0xa6, 0xf3, 0xd7, + 0x11, 0xa7, 0xa6, 0x9f, 0xff, 0xd9, 0x5a, 0x08, 0x2c, 0x45, 0xe0, 0xcb, 0x88, 0xf5, 0x67, 0x76, + 0x35, 0x55, 0x17, 0xb8, 0x3a, 0xbc, 0xdd, 0x6b, 0x5f, 0x88, 0x40, 0xe0, 0x2a, 0x50, 0x8d, 0x3a, + 0xbd, 0xf7, 0xa6, 0x5f, 0x1c, 0xdb, 0x6f, 0x05, 0xff, 0x7f, 0xc0, 0x07, 0x7b, 0xa9, 0x39, 0x17, + 0x22, 0xcb, 0x86, 0xe4, 0x8a, 0xe2, 0x1f, 0xbc, 0x7e, 0x2b, 0x4e, 0x9e, 0x50, 0x9a, 0x80, 0x30, + 0xeb, 0x36, 0xab, 0xff, 0x82, 0x7f, 0xff, 0xf8, 0xa3, 0xed, 0x60, 0xc1, 0xba, 0x28, 0x5e, 0xa2, + 0x1e, 0xb9, 0x45, 0x77, 0xa7, 0x8a, 0xcc, 0xc8, 0xad, 0xda, 0xdf, 0x91, 0x34, 0xc1, 0x34, 0x93, + 0x6c, 0xdc, 0x45, 0xdb, 0xf0, 0x28, 0x9c, 0x93, 0xeb, 0x18, 0x98, 0xb0, 0x0b, 0xd7, 0xc2, 0xe6, + 0x59, 0xe0, 0xc4, 0xfb, 0xe5, 0xb8, 0x31, 0x37, 0xb5, 0xbc, 0x30, 0x2a, 0x7f, 0x5e, 0xd3, 0x5c, + 0xfb, 0x7f, 0x10, 0xf0, 0xb0, 0x98, 0x6b, 0x2a, 0x9f, 0x7f, 0x5f, 0xc3, 0x5e, 0x92, 0xc7, 0x55, + 0x5c, 0xbf, 0x7d, 0xd3, 0xbd, 0x30, 0x5e, 0x5d, 0x54, 0x74, 0x3a, 0x98, 0x0b, 0xe8, 0x40, 0xc1, + 0x5c, 0x9e, 0xd1, 0x72, 0x69, 0x3e, 0x88, 0x12, 0x20, 0x44, 0xd0, 0x40, 0x2c, 0xa5, 0xf3, 0x75, + 0xfa, 0x95, 0x2b, 0x52, 0x3b, 0x2e, 0x00, 0xa8, 0x23, 0xa0, 0x22, 0x20, 0xf9, 0xdb, 0xf1, 0xd8, + 0x04, 0x60, 0x91, 0xc2, 0x46, 0x67, 0x4d, 0xe7, 0xff, 0x7a, 0x69, 0xf0, 0xc0, 0x34, 0x11, 0x04, + 0x63, 0xa9, 0x02, 0x45, 0x4d, 0x7a, 0x7d, 0x0c, 0x3e, 0x23, 0x88, 0xae, 0x89, 0xb7, 0xbf, 0x5f, + 0xab, 0xe8, 0x93, 0x5a, 0xc1, 0x07, 0x1d, 0x1b, 0xb5, 0xdf, 0xa4, 0xef, 0x50, 0xaa, 0x20, 0x2f, + 0xa1, 0xbf, 0xfb, 0xcf, 0xdb, 0xdb, 0x6c, 0xc8, 0xab, 0x45, 0x45, 0xa8, 0xce, 0x69, 0x89, 0x02, + 0xb4, 0xbd, 0x2c, 0x2a, 0xca, 0x0c, 0x6d, 0x57, 0xfd, 0x6b, 0xef, 0x13, 0x80, 0xa2, 0xea, 0x9e, + 0xbc, 0x2b, 0x80, 0x10, 0xaf, 0x45, 0x37, 0x1b, 0xb3, 0xff, 0xb7, 0xb6, 0xdd, 0xf7, 0x27, 0xb8, + 0xb6, 0x0e, 0x0b, 0x7d, 0x16, 0xf7, 0x2f, 0xfe, 0x6c, 0x53, 0x67, 0x69, 0xf0, 0xc4, 0xa5, 0x72, + 0x95, 0xe2, 0x91, 0xb8, 0xba, 0x8b, 0x8b, 0xad, 0x6a, 0xd2, 0xae, 0x2f, 0xca, 0xdf, 0xc2, 0x91, + 0x4b, 0xd6, 0x2e, 0xbd, 0x56, 0xba, 0xe7, 0x57, 0x76, 0xf8, 0x26, 0x31, 0x44, 0x69, 0xbd, 0x58, + 0x9e, 0x4d, 0xed, 0xa7, 0xfd, 0x98, 0x88, 0x80, 0x8c, 0xcd, 0x83, 0x5a, 0x5c, 0x71, 0x74, 0x48, + 0x9b, 0xf7, 0x1a, 0xc3, 0xf3, 0x63, 0x67, 0x43, 0xdf, 0x96, 0x01, 0x4e, 0xbf, 0x1e, 0x7f, 0xbe, + 0xfa, 0x57, 0x1d, 0xca, 0x60, 0x26, 0x30, 0x87, 0x39, 0xd8, 0x27, 0x29, 0x23, 0xed, 0xe4, 0x8f, + 0x3f, 0xe3, 0x82, 0xe7, 0xbf, 0x1c, 0x5f, 0x36, 0xef, 0x78, 0x40, 0x90, 0x24, 0x39, 0x46, 0x83, + 0xff, 0xec, 0xe9, 0xdb, 0x4d, 0x39, 0x5a, 0x48, 0xeb, 0x00, 0xe0, 0x0d, 0x79, 0x71, 0xfd, 0xdf, + 0x4d, 0x3b, 0xf7, 0xca, 0x98, 0x34, 0x89, 0x09, 0x73, 0x62, 0xe7, 0xc3, 0xff, 0x7e, 0xd6, 0x22, + 0x50, 0x06, 0x7d, 0x7d, 0x77, 0xf5, 0xf2, 0x86, 0x5a, 0xc8, 0xf2, 0x78, 0x50, 0x97, 0xf7, 0xd8, + 0x9b, 0x80, 0x64, 0x5f, 0x05, 0x3e, 0x5f, 0x15, 0xf7, 0xc1, 0x63, 0x60, 0x83, 0x6d, 0xec, 0xc5, + 0xcf, 0xdf, 0xbf, 0x5f, 0xff, 0x18, 0x2d, 0xb1, 0x6b, 0xd7, 0xe2, 0xf4, 0xbf, 0xe9, 0x45, 0x13, + 0xc0, 0x24, 0x05, 0x04, 0x5e, 0xbf, 0xbf, 0x30, 0xb1, 0xa5, 0x11, 0x78, 0x40, 0x65, 0xb2, 0xe3, + 0x7f, 0x4c, 0x65, 0x75, 0xb8, 0x2d, 0x84, 0xa4, 0xd4, 0xa1, 0xf7, 0x86, 0xc3, 0xe7, 0xdf, 0x56, + 0x89, 0x05, 0x98, 0x0a, 0xd9, 0x22, 0x76, 0xdb, 0x4f, 0x2f, 0x15, 0xc5, 0x6e, 0xf1, 0xe6, 0x65, + 0x4b, 0x9f, 0xf2, 0x24, 0x44, 0x83, 0x9b, 0x9b, 0xc0, 0x9f, 0x5d, 0x3a, 0x5c, 0x38, 0x3d, 0x59, + 0x30, 0xe0, 0xb5, 0x83, 0x30, 0x5a, 0x66, 0xef, 0xff, 0x27, 0x6b, 0xad, 0xcc, 0x21, 0x91, 0x10, + 0xcc, 0x3b, 0x21, 0x2f, 0xcb, 0xdb, 0x64, 0x5b, 0x4c, 0x57, 0xef, 0xae, 0x84, 0x56, 0xc5, 0x44, + 0x68, 0xc0, 0xcd, 0x5f, 0x2e, 0xae, 0xed, 0xe3, 0x55, 0xea, 0xe5, 0x64, 0xa1, 0x08, 0xc0, 0xf4, + 0x30, 0xad, 0xee, 0xb7, 0xb8, 0xca, 0xdd, 0xe9, 0x6e, 0x88, 0x43, 0xac, 0x06, 0x3b, 0x6e, 0xa2, + 0x3c, 0xfb, 0x5e, 0xd0, 0xee, 0x4f, 0x96, 0xad, 0x7f, 0xf1, 0xf1, 0x8d, 0x28, 0xe4, 0x43, 0x12, + 0x7f, 0x07, 0x5d, 0x6d, 0x8d, 0x33, 0x32, 0x15, 0x56, 0x3b, 0x4c, 0xcc, 0xaa, 0xb5, 0xf9, 0x3a, + 0x71, 0xd4, 0x17, 0xd0, 0xda, 0x22, 0xfa, 0x4d, 0x71, 0x03, 0x9d, 0xdb, 0xb6, 0xdf, 0xf2, 0xac, + 0x2c, 0x1a, 0x95, 0x3d, 0x46, 0xe0, 0xda, 0xc4, 0xa7, 0xa7, 0xc5, 0x6e, 0xe1, 0xbf, 0x3d, 0x62, + 0xa4, 0xf6, 0xff, 0x3a, 0xc4, 0x61, 0x98, 0x05, 0x48, 0x8a, 0xf5, 0xdf, 0x59, 0x9d, 0xb2, 0x39, + 0xa3, 0x6c, 0x79, 0x7d, 0x88, 0x45, 0x98, 0xa7, 0x30, 0x0c, 0x52, 0x8a, 0x38, 0xa5, 0xdc, 0xff, + 0x26, 0x1f, 0xc3, 0x96, 0x38, 0xbe, 0x3e, 0xdc, 0x59, 0x9e, 0x46, 0xff, 0x56, 0xfe, 0xb1, 0x4d, + 0x7a, 0x58, 0x87, 0x90, 0xfd, 0xa0, 0x1f, 0xb4, 0x4c, 0x90, 0x77, 0x59, 0xbb, 0x4d, 0xb3, 0xfd, + 0x64, 0xc9, 0x93, 0x2f, 0x84, 0xa6, 0x21, 0xa2, 0x85, 0xb6, 0xb7, 0xbb, 0x6d, 0xfa, 0x76, 0xeb, + 0xbe, 0x4e, 0xc2, 0x8a, 0xd0, 0x04, 0xb2, 0x85, 0x29, 0x7c, 0xbf, 0xaa, 0x69, 0xbb, 0xc5, 0x5e, + 0xe4, 0xb0, 0x88, 0x41, 0xb2, 0x34, 0x10, 0xeb, 0x5c, 0x9a, 0xdc, 0x6d, 0x54, 0xda, 0xba, 0x75, + 0x97, 0xe7, 0xb4, 0x04, 0x46, 0x86, 0x7c, 0x72, 0x04, 0x3a, 0x6d, 0xad, 0x55, 0x55, 0xdc, 0xab, + 0xbf, 0xf8, 0x26, 0x6c, 0x6e, 0xa7, 0xb4, 0x41, 0x22, 0x5e, 0x6f, 0xcd, 0xdb, 0x8b, 0x9b, 0xbc, + 0x80, 0xb6, 0x53, 0x46, 0x16, 0xc9, 0x2d, 0x64, 0x22, 0xa6, 0xdc, 0xdb, 0x9b, 0xe3, 0xed, 0xcd, + 0xd2, 0xa8, 0x57, 0x00, 0xb1, 0xac, 0xd3, 0xb7, 0xef, 0x7a, 0xe5, 0x86, 0x9c, 0xc1, 0xe5, 0x2d, + 0x1a, 0xd6, 0x91, 0x0d, 0xce, 0x97, 0x17, 0x4e, 0x5c, 0x4a, 0xd2, 0x7b, 0xb6, 0x6f, 0xaa, 0xaf, + 0xf6, 0x69, 0xce, 0xec, 0xcd, 0x70, 0xc9, 0x19, 0x37, 0x81, 0x88, 0xd3, 0xa7, 0x62, 0x1c, 0x75, + 0x2a, 0xf9, 0x7b, 0xdc, 0x34, 0xf5, 0x23, 0x3a, 0xbe, 0x6f, 0xf3, 0xff, 0xf6, 0x93, 0x7c, 0xe5, + 0x77, 0xcb, 0x9b, 0x58, 0x81, 0xf7, 0xd9, 0xb3, 0x6c, 0x3e, 0xdb, 0x8c, 0x8a, 0xde, 0x5e, 0xdf, + 0x7e, 0x21, 0xef, 0xdd, 0x18, 0x2a, 0x01, 0xd6, 0x05, 0x86, 0x1a, 0x12, 0xaf, 0xee, 0xfb, 0xef, + 0x14, 0x71, 0xcd, 0x00, 0x12, 0x51, 0x54, 0x03, 0x40, 0x09, 0x0e, 0x31, 0x13, 0x77, 0xdc, 0xac, + 0x9e, 0x5b, 0x99, 0xb3, 0x5c, 0xe0, 0x92, 0x21, 0x88, 0xd8, 0x5c, 0x6a, 0xf9, 0xf5, 0xef, 0xbf, + 0x71, 0x34, 0x18, 0x5b, 0xb0, 0x53, 0x72, 0xf4, 0xfd, 0x6d, 0x8f, 0xd2, 0xff, 0x57, 0x20, 0x66, + 0x4f, 0xdd, 0x7e, 0xf5, 0xd3, 0xda, 0x89, 0x42, 0x09, 0xd7, 0x7e, 0xa5, 0xf7, 0x08, 0xe0, 0x89, + 0xdc, 0xec, 0x7f, 0xbb, 0xff, 0x85, 0x11, 0xeb, 0x17, 0xde, 0x24, 0x0c, 0x56, 0xb3, 0xe7, 0x89, + 0xd6, 0x3a, 0x2c, 0xf0, 0xfb, 0x04, 0x73, 0x33, 0x53, 0x33, 0xfd, 0xdd, 0xe2, 0xf9, 0x78, 0x95, + 0x05, 0xa2, 0x47, 0xc4, 0xff, 0x72, 0xe5, 0xeb, 0x12, 0xdf, 0x50, 0x94, 0x30, 0x6b, 0x7d, 0xfd, + 0x6a, 0xb1, 0x7b, 0xf1, 0x7d, 0xc8, 0x6c, 0x6c, 0x41, 0xa5, 0xaa, 0xcd, 0x92, 0xa6, 0xc4, 0xfc, + 0xdf, 0x73, 0xbb, 0x45, 0xfc, 0xa5, 0xd2, 0xbb, 0x0f, 0xe6, 0xae, 0xd5, 0x53, 0xc5, 0xd5, 0x5f, + 0xef, 0x5a, 0x40, 0x02, 0x20, 0x3d, 0x05, 0xaf, 0xef, 0xb1, 0x0a, 0xa8, 0x1a, 0xbc, 0xa0, 0xfe, + 0xf7, 0x7b, 0xd1, 0x22, 0x44, 0x89, 0xbc, 0x08, 0x53, 0xa2, 0x61, 0xa1, 0x35, 0x26, 0xb5, 0x92, + 0x2b, 0x6c, 0xdf, 0xf3, 0x81, 0xcc, 0xa9, 0x50, 0x0e, 0x23, 0x4c, 0xbb, 0x8a, 0xfb, 0xbf, 0xd8, + 0x52, 0xa3, 0x5a, 0x4c, 0x44, 0x2c, 0xb2, 0x73, 0xe7, 0x3f, 0xbd, 0xf1, 0xf8, 0xf2, 0x51, 0x40, + 0xa6, 0x5a, 0xfd, 0xd3, 0x37, 0xe9, 0xdb, 0xc3, 0x0f, 0x2e, 0x23, 0x82, 0x98, 0xaf, 0xdb, 0xef, + 0xae, 0xab, 0x63, 0x13, 0xa0, 0xc1, 0x53, 0xc9, 0x21, 0x0e, 0x56, 0x7b, 0x08, 0xb1, 0x0e, 0x3f, + 0xdf, 0x6c, 0xa5, 0x9a, 0x66, 0x49, 0x4c, 0x9a, 0x6c, 0xaf, 0x5d, 0xef, 0x9e, 0x02, 0x5c, 0x0b, + 0x73, 0xdd, 0x8f, 0x78, 0x25, 0x5d, 0x17, 0x76, 0x28, 0xb4, 0xa8, 0x4e, 0x4f, 0xc4, 0x11, 0x77, + 0xdd, 0xdc, 0x57, 0x15, 0xbf, 0xee, 0xee, 0x57, 0xbc, 0x1d, 0x9a, 0xcb, 0x91, 0x0e, 0x3f, 0xbd, + 0xb8, 0xad, 0xb1, 0xe5, 0x73, 0xfc, 0x7d, 0xb3, 0x34, 0x8b, 0x6c, 0xfd, 0xa2, 0x75, 0xe2, 0xfe, + 0xb5, 0xab, 0x70, 0x0f, 0xc8, 0x89, 0x35, 0xa3, 0xa8, 0xba, 0xab, 0x51, 0x3c, 0x8b, 0xa7, 0x5c, + 0x5c, 0x90, 0xc7, 0x76, 0xaa, 0xbc, 0xea, 0x92, 0x9a, 0x58, 0x7f, 0x7f, 0x32, 0x1b, 0x25, 0x43, + 0x4d, 0x10, 0xe2, 0x6e, 0xeb, 0x6f, 0x23, 0xad, 0xf7, 0x65, 0x70, 0x89, 0x91, 0x9c, 0x62, 0xc8, + 0x5e, 0xaa, 0xef, 0xd1, 0xec, 0xcf, 0x46, 0x0f, 0xbf, 0xc5, 0x7d, 0xd3, 0xca, 0xc7, 0x37, 0x07, + 0x44, 0xbe, 0xd8, 0xaa, 0xbd, 0x3f, 0xb9, 0xc2, 0x8c, 0x60, 0x73, 0x69, 0xcc, 0x57, 0x71, 0x5b, + 0x7b, 0xed, 0x09, 0xf2, 0x6e, 0x4e, 0xe7, 0x39, 0x32, 0xc9, 0xcf, 0x41, 0x5a, 0xb9, 0xbe, 0x17, + 0x2b, 0x50, 0xea, 0xed, 0xd8, 0xd9, 0x27, 0xd7, 0x1a, 0x83, 0x4d, 0xbf, 0xdc, 0xf1, 0x1c, 0x17, + 0x0d, 0x2a, 0x23, 0xfe, 0x7d, 0x8f, 0x2d, 0x7e, 0xf1, 0x6d, 0x80, 0x3a, 0x8b, 0xc3, 0x98, 0x99, + 0x3a, 0xcd, 0x9f, 0x68, 0x4f, 0x22, 0xe2, 0xb8, 0x81, 0xed, 0x65, 0xee, 0x3b, 0x53, 0x4d, 0xb6, + 0xfe, 0xae, 0x6a, 0x77, 0x27, 0xb3, 0xb8, 0x4d, 0x06, 0x31, 0xe5, 0x93, 0x95, 0xd6, 0x97, 0xb3, + 0xaa, 0x83, 0x8b, 0xe4, 0xfb, 0x9a, 0x5c, 0x71, 0x66, 0x2a, 0xe3, 0xcb, 0xd5, 0xc6, 0x57, 0x13, + 0xf5, 0xee, 0x70, 0x5f, 0x8d, 0xfe, 0x82, 0xf6, 0xb5, 0x7b, 0xe3, 0xf6, 0xa1, 0x76, 0x06, 0x51, + 0x1f, 0x9f, 0x32, 0x60, 0xae, 0x27, 0x0d, 0xb4, 0xb1, 0x5e, 0x95, 0xa8, 0x13, 0x1f, 0xed, 0xff, + 0x2b, 0xb0, 0x23, 0x98, 0x46, 0xda, 0xcb, 0x97, 0x38, 0x70, 0xb5, 0xbb, 0x23, 0x10, 0xf7, 0xec, + 0xcc, 0xe5, 0xc8, 0x51, 0x5e, 0x31, 0xcb, 0xc3, 0xd1, 0xc4, 0x40, 0x1a, 0xac, 0xaf, 0x6e, 0x36, + 0x26, 0xc0, 0x9e, 0x6c, 0x75, 0xb1, 0xef, 0x49, 0xd2, 0x04, 0x00, 0x85, 0x53, 0x7d, 0x70, 0x6b, + 0x55, 0x59, 0x7d, 0xb9, 0x71, 0x39, 0xf1, 0x5c, 0xfd, 0x36, 0xc7, 0xbe, 0xfd, 0x2d, 0xb2, 0xb2, + 0xf9, 0xb2, 0x07, 0x06, 0x84, 0x79, 0x14, 0x67, 0x05, 0xaf, 0x37, 0x73, 0x21, 0xba, 0x9b, 0xf4, + 0xf0, 0x1f, 0xff, 0xb6, 0x99, 0x6c, 0xc4, 0x04, 0x9c, 0xa8, 0x4d, 0x04, 0x01, 0x26, 0xce, 0xf1, + 0xb6, 0xdc, 0x2f, 0x58, 0xdd, 0x37, 0x07, 0x6e, 0x59, 0xa2, 0xda, 0x93, 0xb7, 0xdf, 0xf5, 0x41, + 0xb3, 0xda, 0x60, 0x8d, 0x64, 0xba, 0xd3, 0xcd, 0xe6, 0xe9, 0x76, 0xe6, 0xe1, 0xe7, 0x2a, 0x87, + 0x3c, 0x59, 0xc2, 0x10, 0x4e, 0x29, 0xa1, 0xb9, 0x89, 0x67, 0x27, 0x3e, 0xc2, 0xba, 0xdb, 0xef, + 0x7f, 0x73, 0x71, 0xa9, 0x5e, 0xff, 0xd8, 0xdb, 0x69, 0x4e, 0xe2, 0x20, 0xd6, 0x51, 0x42, 0xb5, + 0xcf, 0x82, 0xfb, 0x7a, 0xaf, 0x7b, 0x1e, 0x8c, 0x4e, 0x20, 0x44, 0x54, 0xb4, 0x33, 0x7c, 0x9e, + 0x5b, 0x37, 0xbe, 0xd1, 0xff, 0x17, 0x18, 0xab, 0x57, 0x20, 0x67, 0xa6, 0x81, 0x31, 0x1a, 0xc1, + 0xdb, 0x2b, 0x10, 0x50, 0x57, 0xd6, 0x9d, 0xa6, 0xc7, 0x94, 0xd7, 0xc3, 0x08, 0x85, 0x5d, 0x5d, + 0x52, 0xf7, 0x17, 0xd6, 0xdf, 0xb6, 0x93, 0x69, 0xc5, 0x85, 0x1c, 0x19, 0xa3, 0x4b, 0x5b, 0x8a, + 0xb7, 0xcc, 0xc5, 0x78, 0xba, 0xa7, 0x10, 0xf0, 0xa6, 0x34, 0x05, 0xf0, 0xab, 0xd3, 0xc7, 0xfe, + 0xe3, 0x72, 0x27, 0x25, 0xab, 0xdc, 0x28, 0xea, 0x57, 0x39, 0xc4, 0x9c, 0xfa, 0xf6, 0x70, 0xe7, + 0x1e, 0x21, 0xc8, 0xac, 0x22, 0xa5, 0x1e, 0xd6, 0xe7, 0x2f, 0x91, 0x7d, 0x3d, 0xa4, 0xdf, 0xde, + 0x21, 0xe6, 0x8c, 0x15, 0xda, 0x5f, 0xde, 0x36, 0xbc, 0x56, 0xee, 0xef, 0x78, 0xad, 0xdf, 0x27, + 0xfe, 0x44, 0xfe, 0x4e, 0x54, 0xef, 0x7b, 0xbb, 0xbd, 0xdd, 0xdc, 0x57, 0x7c, 0x18, 0xd2, 0x18, + 0x4b, 0x6b, 0x42, 0x1c, 0xc9, 0xfa, 0x15, 0xea, 0xcc, 0xef, 0xc7, 0x96, 0x31, 0x32, 0xe7, 0xcb, + 0xbf, 0x7e, 0x22, 0x16, 0x5a, 0x88, 0x19, 0x33, 0x8f, 0x4c, 0x56, 0x5e, 0xfe, 0xfb, 0xe6, 0xed, + 0xfd, 0xac, 0x70, 0x18, 0x7f, 0x60, 0xa2, 0xdf, 0xa6, 0x9b, 0x6e, 0xe0, 0xa7, 0x06, 0xd9, 0x8b, + 0x42, 0x20, 0x56, 0x69, 0x51, 0x62, 0x1f, 0xc5, 0x0b, 0x60, 0x45, 0x7f, 0x6a, 0x5a, 0x2c, 0x9f, + 0xad, 0x5e, 0xdd, 0x59, 0x09, 0xe0, 0x4a, 0x32, 0xc7, 0x00, 0xdb, 0x7b, 0x7f, 0xd7, 0x79, 0x78, + 0xbd, 0x67, 0x87, 0x82, 0x7a, 0xed, 0x56, 0xab, 0xe2, 0xf1, 0x28, 0x81, 0x28, 0xd9, 0x74, 0xea, + 0xa0, 0xb5, 0x1c, 0x7e, 0x92, 0x02, 0x0a, 0x74, 0xf7, 0x07, 0xb8, 0xc3, 0xd8, 0xc4, 0x52, 0x28, + 0xa7, 0x58, 0xbf, 0xd7, 0xba, 0xe6, 0x22, 0x54, 0x01, 0x5e, 0xfd, 0xf1, 0x9f, 0x29, 0x56, 0x64, + 0x1d, 0xb9, 0x02, 0x5a, 0xd6, 0xdd, 0x61, 0x0c, 0xf8, 0xf5, 0xa2, 0x65, 0x37, 0x2f, 0xea, 0x95, + 0x0d, 0xca, 0xcf, 0x4d, 0x3d, 0xbf, 0x1f, 0x1e, 0x9e, 0x66, 0x16, 0x5c, 0xc7, 0x24, 0x62, 0x35, + 0x4f, 0x46, 0xc6, 0x3f, 0x88, 0xff, 0xe8, 0x13, 0xd5, 0x75, 0x63, 0x33, 0x18, 0xf7, 0x00, 0x20, + 0xb5, 0x55, 0xe7, 0xef, 0xeb, 0x2d, 0x7f, 0xff, 0x08, 0xb8, 0x03, 0xee, 0xa7, 0xd5, 0x6a, 0xbb, + 0xee, 0xf5, 0xac, 0xde, 0x20, 0xa9, 0x01, 0x11, 0x4c, 0x23, 0x2f, 0xd7, 0xdf, 0xfa, 0x8c, 0x24, + 0x3f, 0x6e, 0xff, 0x77, 0x76, 0xae, 0xbc, 0x4e, 0x00, 0x6f, 0xe7, 0x5b, 0xe7, 0x9f, 0xab, 0x8b, + 0x97, 0x97, 0xd1, 0xc9, 0xbd, 0xde, 0x2b, 0x78, 0xaf, 0x50, 0x8e, 0x11, 0x0f, 0xb6, 0x7b, 0x7b, + 0x7f, 0xe2, 0x70, 0x19, 0x32, 0xeb, 0xcb, 0xe5, 0x2f, 0xb5, 0xb7, 0x1d, 0x19, 0xdf, 0xef, 0x79, + 0x7b, 0xbb, 0x72, 0xa0, 0x5e, 0xec, 0x1e, 0xcc, 0xcd, 0x68, 0x5a, 0xef, 0xd5, 0xb6, 0xf7, 0xb7, + 0x59, 0xbf, 0xc2, 0x12, 0x26, 0x82, 0x35, 0xdd, 0xb5, 0x5e, 0xb5, 0xaf, 0xef, 0x8e, 0x38, 0x43, + 0x1b, 0x0b, 0x89, 0x5a, 0xd6, 0xb6, 0xc4, 0xc2, 0xc0, 0x72, 0x11, 0x40, 0x1e, 0x13, 0x21, 0xb3, + 0xb6, 0x8a, 0xf4, 0x3c, 0xe9, 0xfd, 0x45, 0x12, 0x68, 0x97, 0x03, 0x8a, 0x24, 0xc1, 0x13, 0x33, + 0x57, 0xdd, 0xde, 0xcb, 0x1d, 0xc5, 0xcb, 0x60, 0xf9, 0x74, 0x21, 0x45, 0xe1, 0xb0, 0xa2, 0xf8, + 0xb8, 0xb8, 0x88, 0xf0, 0x08, 0x36, 0x63, 0xa4, 0x5e, 0x96, 0xdc, 0x6d, 0xdb, 0x2f, 0xbb, 0x88, + 0xa9, 0x7b, 0x88, 0x95, 0x63, 0x46, 0x38, 0x56, 0xb8, 0x87, 0x12, 0xc6, 0xd4, 0xbf, 0xcb, 0xf6, + 0x2d, 0xb7, 0xfd, 0xc3, 0x76, 0x8c, 0x63, 0x13, 0x14, 0xb2, 0x66, 0x5b, 0xfb, 0xdb, 0x7f, 0x39, + 0xcc, 0x96, 0xf9, 0x0b, 0x52, 0x74, 0xa2, 0x8d, 0xcb, 0xdf, 0xdb, 0xce, 0x1c, 0xac, 0xe7, 0xb7, + 0xab, 0x52, 0xfa, 0xf4, 0xe9, 0xbe, 0x38, 0xbd, 0xfe, 0xdd, 0x2a, 0xe2, 0x49, 0xe5, 0xee, 0xff, + 0x4e, 0x4d, 0x8b, 0xab, 0xd7, 0x21, 0xf4, 0xa3, 0x11, 0x7c, 0x57, 0xbf, 0x7c, 0xb2, 0xc7, 0xc0, + 0x3f, 0x20, 0x22, 0x3a, 0x54, 0xa3, 0xbf, 0x89, 0x4d, 0xc6, 0x08, 0x03, 0x76, 0xd1, 0x05, 0xcd, + 0x84, 0xed, 0xc8, 0x5e, 0xec, 0xe6, 0x27, 0x82, 0x79, 0x50, 0x68, 0xe3, 0x6a, 0x90, 0x2d, 0x54, + 0xe8, 0xee, 0xe5, 0x4a, 0xbd, 0xbd, 0xb4, 0xd4, 0xd9, 0x12, 0x79, 0xfc, 0x9d, 0x43, 0xdc, 0xde, + 0xca, 0x57, 0xba, 0x94, 0xe7, 0x5e, 0x07, 0x1d, 0x2b, 0xbb, 0x8a, 0x34, 0x7e, 0xa8, 0xb3, 0x85, + 0x10, 0xe3, 0x75, 0x9f, 0x71, 0xaa, 0xa9, 0xa6, 0xdb, 0x6d, 0xb7, 0xc7, 0x7c, 0xc3, 0x58, 0x8d, + 0x53, 0x25, 0x5c, 0xdb, 0xbb, 0x44, 0xc7, 0xe9, 0x7e, 0x4d, 0x57, 0x64, 0xf1, 0x58, 0x2b, 0xa0, + 0xaa, 0x9a, 0xbb, 0x94, 0x92, 0x8a, 0xdd, 0xbc, 0xb6, 0x6c, 0xba, 0x9e, 0x24, 0x69, 0x29, 0x69, + 0xf1, 0xba, 0xdb, 0x7f, 0xdd, 0x0b, 0x46, 0xbe, 0x71, 0x01, 0xef, 0xed, 0x7a, 0x85, 0x15, 0xd2, + 0x85, 0x05, 0x62, 0xa5, 0x5d, 0xbf, 0x87, 0xa5, 0x59, 0x9a, 0xc4, 0x75, 0xa7, 0xfb, 0xe2, 0x07, + 0x1e, 0xf8, 0xbb, 0x3a, 0x69, 0xff, 0x2e, 0x45, 0x51, 0xe1, 0xa9, 0xff, 0xf2, 0x7e, 0xb9, 0xbe, + 0x4b, 0xd5, 0x2b, 0xa0, 0x6c, 0x7d, 0x5b, 0xa7, 0xb7, 0x4a, 0x3b, 0xa8, 0x3d, 0xf7, 0xef, 0xec, + 0x83, 0x4c, 0xac, 0xca, 0x50, 0xd4, 0xbf, 0xdb, 0x83, 0xef, 0xcb, 0xdb, 0x5f, 0x16, 0xa1, 0x2c, + 0x06, 0x2c, 0x00, 0x03, 0x4b, 0xdd, 0xe5, 0x62, 0xdb, 0x7d, 0xef, 0x97, 0xec, 0x19, 0xc2, 0x2c, + 0x04, 0xbe, 0xe2, 0x7f, 0x94, 0x8f, 0x9f, 0x97, 0xa6, 0xdf, 0xb6, 0xf7, 0xfd, 0x81, 0xa1, 0x53, + 0x66, 0xf9, 0x22, 0x15, 0xb8, 0x86, 0x22, 0x3f, 0x76, 0x42, 0x16, 0x4b, 0xf5, 0x88, 0xba, 0x7c, + 0x35, 0xea, 0x8c, 0xeb, 0x2a, 0xd0, 0x4f, 0xd4, 0x73, 0x60, 0xb3, 0x05, 0x99, 0xad, 0x14, 0xd9, + 0x8a, 0xd2, 0x1b, 0xab, 0xdf, 0xa7, 0x0a, 0x2a, 0x97, 0x02, 0x6e, 0xde, 0x1e, 0xd7, 0x76, 0xd3, + 0x7f, 0x4f, 0x7b, 0xdc, 0x7f, 0xfb, 0xff, 0xf5, 0x22, 0x3d, 0xdc, 0x56, 0x2b, 0xbe, 0xfe, 0xf9, + 0x1a, 0xe2, 0x43, 0xe0, 0x24, 0xfb, 0x35, 0x87, 0x4d, 0x7b, 0xb8, 0x0f, 0x33, 0x2e, 0x0d, 0x9a, + 0xa2, 0x96, 0x96, 0x00, 0x88, 0x12, 0xdd, 0x7b, 0xed, 0x6b, 0x13, 0x13, 0x35, 0xb9, 0x31, 0xdc, + 0xb4, 0xe1, 0xdd, 0x2a, 0xe5, 0xf7, 0xef, 0xf4, 0xd6, 0x09, 0x59, 0x1e, 0xef, 0xf2, 0x85, 0xbf, + 0xd4, 0x55, 0xb3, 0xbd, 0xfa, 0x76, 0xfa, 0x7e, 0x45, 0xc9, 0x9d, 0x99, 0xa7, 0xb9, 0x05, 0xf4, + 0xcb, 0xf9, 0x7d, 0xdf, 0x96, 0xe3, 0x59, 0x68, 0x65, 0x61, 0xf3, 0xbb, 0x79, 0x51, 0x0e, 0x1a, + 0x80, 0x70, 0xee, 0x51, 0xd5, 0x32, 0xbf, 0xa9, 0x7c, 0x67, 0xdf, 0x17, 0xbe, 0x4d, 0x8e, 0x00, + 0x98, 0x68, 0x55, 0xba, 0x66, 0xeb, 0xef, 0xc2, 0x0a, 0x04, 0x79, 0xa7, 0xe7, 0x79, 0xa0, 0x78, + 0x1a, 0x0f, 0x83, 0xbb, 0xbd, 0xf7, 0xce, 0x04, 0x9e, 0x1f, 0x60, 0x90, 0xca, 0xdf, 0xac, 0x47, + 0xd6, 0x01, 0xc2, 0x4d, 0x1e, 0xba, 0xf7, 0xe5, 0x8a, 0x72, 0x43, 0xf9, 0x17, 0xe5, 0xc0, 0x2c, + 0x85, 0x13, 0xae, 0xb3, 0x76, 0xd6, 0x11, 0x24, 0x04, 0xbd, 0x27, 0x3a, 0xac, 0xba, 0xd6, 0xca, + 0xcb, 0xe4, 0xb8, 0xe9, 0x1e, 0x14, 0x4b, 0xae, 0xad, 0xeb, 0x33, 0x0f, 0xef, 0x88, 0x05, 0x84, + 0xa0, 0x1e, 0x34, 0x09, 0x4e, 0xbc, 0xe9, 0xc4, 0xa4, 0x05, 0x12, 0x09, 0x74, 0x13, 0xaa, 0xe2, + 0xe9, 0xd4, 0x7b, 0x82, 0x3f, 0x27, 0xe3, 0xab, 0xaf, 0xff, 0xf1, 0x0f, 0x87, 0xe8, 0x13, 0x9a, + 0x9f, 0x7e, 0x00, 0x55, 0x0c, 0x0b, 0x1e, 0xca, 0x57, 0x7f, 0x7a, 0x6f, 0x4d, 0xf1, 0x1c, 0x44, + 0x36, 0xca, 0x59, 0xef, 0xdb, 0xf7, 0xbf, 0x7e, 0xc4, 0xd2, 0x22, 0x85, 0x89, 0x88, 0x33, 0x56, + 0xf6, 0xaf, 0x2f, 0xfb, 0xf0, 0x27, 0x16, 0x6b, 0x9e, 0xed, 0x13, 0x88, 0x73, 0x74, 0xb7, 0x10, + 0xe3, 0x88, 0x1c, 0x6e, 0x58, 0xbb, 0xca, 0xa0, 0x80, 0x15, 0xc3, 0xfd, 0xc4, 0x8a, 0xc2, 0xa3, + 0x78, 0xc8, 0x0a, 0x6e, 0xfd, 0xe2, 0xba, 0xd9, 0xb0, 0x6f, 0x22, 0x66, 0x0c, 0x2f, 0xef, 0xdd, + 0xe2, 0x5c, 0x3d, 0x34, 0x7d, 0x87, 0x0f, 0xa1, 0xe2, 0x0d, 0x96, 0xde, 0xab, 0xb7, 0xe9, 0x4b, + 0x9c, 0x40, 0x4b, 0x7c, 0x79, 0xc5, 0xfb, 0xdd, 0xf7, 0xec, 0xe4, 0x25, 0x70, 0x09, 0x89, 0xc6, + 0xc2, 0x45, 0xc5, 0x65, 0xcd, 0x3c, 0x46, 0x28, 0x9a, 0xfa, 0x1a, 0x4a, 0x45, 0xfb, 0xfb, 0xbf, + 0x0e, 0x89, 0x00, 0x4a, 0x54, 0x14, 0x9d, 0x36, 0xd6, 0x9b, 0xef, 0x37, 0xb8, 0x04, 0xb3, 0xcc, + 0x3f, 0x9c, 0x21, 0x41, 0x4a, 0x61, 0x06, 0x3f, 0xcd, 0xc2, 0x7c, 0x97, 0x2a, 0xaf, 0x2a, 0xbb, + 0xcc, 0x58, 0x7c, 0x5f, 0xfa, 0x6d, 0xa7, 0xf1, 0x6c, 0x4a, 0xf6, 0xeb, 0x4d, 0xfa, 0x69, 0xfe, + 0x32, 0x8d, 0x3e, 0x8d, 0xb7, 0xde, 0xe9, 0x9b, 0xe4, 0x5e, 0xd4, 0x00, 0x64, 0x04, 0x44, 0x0f, + 0x43, 0x89, 0x46, 0xfe, 0x9e, 0xab, 0x04, 0x11, 0x3c, 0x3f, 0xfc, 0x81, 0xbc, 0xb0, 0x91, 0x78, + 0xbb, 0xf1, 0x0b, 0x0e, 0x61, 0xde, 0xc4, 0x5e, 0xba, 0xfd, 0x02, 0x50, 0xf0, 0xa5, 0xa7, 0xb6, + 0xdb, 0xdb, 0x27, 0x2f, 0x7b, 0x2c, 0xeb, 0x5d, 0xfe, 0x18, 0x00, 0x2c, 0x3e, 0x17, 0xef, 0xc5, + 0x65, 0xcd, 0x60, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x01, 0x00, 0xb0, 0x5a, 0x50, 0x8d, 0x04, + 0x75, 0x71, 0x30, 0x50, 0x22, 0xb7, 0xad, 0x5c, 0xe2, 0x20, 0x92, 0xef, 0xbb, 0xe0, 0xba, 0xee, + 0xef, 0x5a, 0xb7, 0xd0, 0x8c, 0xae, 0x24, 0x33, 0xf8, 0xbe, 0x87, 0xc5, 0xe1, 0x19, 0x62, 0x04, + 0x2a, 0x3b, 0xc4, 0x89, 0x58, 0xb8, 0x9c, 0x25, 0x84, 0x67, 0xe8, 0x63, 0x7c, 0xd5, 0x5f, 0x88, + 0x2c, 0xf8, 0xf5, 0xe2, 0x01, 0x30, 0x9d, 0x56, 0xb5, 0x47, 0x7c, 0x42, 0x9d, 0x3e, 0xbc, 0x8b, + 0xd0, 0xc9, 0x57, 0x43, 0xeb, 0x88, 0x0c, 0x22, 0xf1, 0x8a, 0xf3, 0xd5, 0x34, 0xd3, 0x4f, 0xf8, + 0x62, 0xf0, 0xc2, 0x27, 0x5c, 0x40, 0x85, 0xea, 0x88, 0x82, 0x2d, 0xef, 0xde, 0x21, 0x17, 0xaf, + 0x08, 0x5e, 0x21, 0x7b, 0xc4, 0xaf, 0x7d, 0x7a, 0xfa, 0xe5, 0x36, 0x11, 0xae, 0xb1, 0x7d, 0x62, + 0xe2, 0x04, 0xcb, 0xd6, 0x24, 0x5e, 0x89, 0xd5, 0xd5, 0xac, 0x72, 0x97, 0x22, 0xf9, 0x04, 0x3a, + 0xd2, 0xf4, 0x57, 0x3e, 0x22, 0x92, 0x5e, 0xef, 0xc2, 0x24, 0xad, 0x7c, 0x4e, 0x77, 0xf8, 0xbd, + 0x5d, 0xde, 0xff, 0x09, 0xd5, 0x7d, 0xdf, 0xc4, 0x55, 0x7b, 0x4d, 0x7c, 0x11, 0x88, 0x9b, 0x57, + 0x30, 0xbe, 0x51, 0x3a, 0xaf, 0x11, 0x36, 0x26, 0x68, 0x20, 0xd6, 0x21, 0x1e, 0x28, 0x8e, 0xb1, + 0x7d, 0xd5, 0x56, 0xfa, 0x95, 0x11, 0x71, 0x0b, 0x94, 0x9d, 0x6a, 0xba, 0xd7, 0xd6, 0xb1, 0x6a, + 0x59, 0x57, 0xd4, 0x89, 0xe1, 0x0f, 0xaf, 0xbe, 0xa9, 0x17, 0xaf, 0x22, 0xc4, 0x55, 0xb1, 0xca, + 0x62, 0x0c, 0x72, 0xb8, 0x23, 0x36, 0xee, 0xdc, 0x40, 0x47, 0xc4, 0x21, 0x68, 0x0b, 0x51, 0x34, + 0x4d, 0x5f, 0x52, 0x27, 0xc1, 0x11, 0x15, 0xd6, 0xf5, 0x88, 0x47, 0x4a, 0xb8, 0x95, 0x63, 0xea, + 0xc7, 0xd5, 0x8f, 0xab, 0x9f, 0x57, 0x97, 0x8b, 0x08, 0x22, 0xd6, 0x6b, 0xbf, 0x96, 0x7a, 0x0d, + 0xea, 0xb6, 0x4b, 0xc4, 0x09, 0xf8, 0x60, 0x7e, 0xab, 0xaa, 0x95, 0x67, 0x4c, 0xb4, 0xf7, 0xd6, + 0xbe, 0xb4, 0x8b, 0x88, 0xfa, 0xe4, 0x8b, 0xd7, 0x24, 0x5e, 0xb1, 0x32, 0xf0, 0x4e, 0x2a, 0xef, + 0x74, 0x4a, 0xce, 0x2f, 0x82, 0xd1, 0x1a, 0xac, 0xf0, 0x7a, 0x65, 0x0d, 0xf2, 0x90, 0xb9, 0xfc, + 0x27, 0xc9, 0x24, 0xe4, 0x36, 0xce, 0x70, 0x86, 0x5c, 0x33, 0x15, 0x88, 0xc3, 0x08, 0x26, 0x7c, + 0xff, 0xd3, 0x4f, 0x4d, 0x38, 0x99, 0x2c, 0x10, 0x49, 0x13, 0xbe, 0x8a, 0xcf, 0xa2, 0x48, 0xf9, + 0xba, 0x2c, 0x52, 0x75, 0x8b, 0xeb, 0x49, 0xf2, 0x04, 0x2c, 0x19, 0x69, 0xf8, 0x26, 0xbf, 0xfc, + 0x99, 0x73, 0x0b, 0xe0, 0xb8, 0x85, 0xde, 0x43, 0x1d, 0xd8, 0x7a, 0x3b, 0x49, 0x88, 0xae, 0x61, + 0x7b, 0xba, 0xe0, 0x88, 0x66, 0xd9, 0xf5, 0xcf, 0x82, 0x83, 0x32, 0xa6, 0xe7, 0x9e, 0x93, 0xe5, + 0x5c, 0xd9, 0x63, 0x49, 0x74, 0x17, 0xe6, 0x45, 0xc1, 0x04, 0xbd, 0x62, 0xb8, 0x8a, 0x24, 0x55, + 0xd5, 0xca, 0x89, 0x10, 0x8b, 0x5e, 0x25, 0x14, 0x01, 0x53, 0xc4, 0xeb, 0xa3, 0x4b, 0xe0, 0xa4, + 0x53, 0x1d, 0xea, 0xb9, 0x7b, 0x56, 0x89, 0xfe, 0x87, 0xa5, 0x44, 0xe8, 0x95, 0x37, 0x04, 0x43, + 0x9d, 0x26, 0x66, 0x8c, 0x1f, 0x2c, 0xbe, 0xef, 0xe0, 0x8a, 0x8a, 0x37, 0x48, 0x36, 0x1e, 0x08, + 0xc9, 0x54, 0x95, 0x9e, 0x21, 0x05, 0xd1, 0xc6, 0x5e, 0x83, 0x12, 0xae, 0x41, 0xa3, 0xff, 0xff, + 0x94, 0x62, 0xed, 0xae, 0x82, 0xe9, 0x57, 0xab, 0x92, 0x44, 0xd6, 0x2f, 0x08, 0x78, 0x85, 0xff, + 0xd6, 0x2f, 0x12, 0x88, 0x54, 0xf0, 0x82, 0xbf, 0x84, 0x15, 0xfe, 0xac, 0x49, 0xd6, 0x2f, 0x08, + 0xaf, 0x22, 0xc2, 0x02, 0x2c, 0x7b, 0x17, 0x1d, 0x2b, 0x6d, 0xb6, 0xdf, 0xa8, 0x9a, 0x10, 0xde, + 0x0a, 0x14, 0x7d, 0xf5, 0x8b, 0x88, 0xd7, 0x04, 0x97, 0xbd, 0xbe, 0x51, 0x57, 0x9f, 0x7d, 0x0b, + 0x18, 0xa5, 0x62, 0x17, 0x2b, 0xe5, 0xbb, 0xe7, 0xe0, 0xb8, 0x72, 0x0c, 0xb1, 0x5d, 0x9b, 0x6d, + 0x15, 0xe6, 0x15, 0x72, 0x9d, 0x54, 0x8a, 0x24, 0xbc, 0x16, 0x8c, 0x4f, 0x7b, 0x55, 0x17, 0x27, + 0xd8, 0xf7, 0x6f, 0xf4, 0x6e, 0xfa, 0x10, 0x91, 0xbc, 0x47, 0xd0, 0x75, 0xef, 0x10, 0x84, 0x39, + 0xf5, 0x78, 0x43, 0x9c, 0xaa, 0xaa, 0xab, 0xfe, 0x89, 0x55, 0xce, 0x5e, 0xaa, 0x64, 0xff, 0xf8, + 0x21, 0x10, 0xb5, 0x7e, 0xf1, 0x0e, 0xba, 0x5e, 0x5b, 0xdd, 0xbf, 0x0a, 0x92, 0x6c, 0xd6, 0x96, + 0xae, 0x5f, 0xfa, 0xc4, 0xaf, 0x7c, 0x11, 0x9f, 0x77, 0x2a, 0x5f, 0x58, 0xa4, 0xe4, 0xaa, 0xfc, + 0x20, 0xb5, 0xf5, 0x8e, 0x57, 0x28, 0x42, 0xac, 0x6b, 0xe0, 0xbb, 0x63, 0x9d, 0xb9, 0x9b, 0x71, + 0xc4, 0xd7, 0x04, 0x81, 0x1a, 0xaf, 0xdf, 0x04, 0x61, 0x2e, 0x66, 0xf7, 0xc1, 0x28, 0x9d, 0xd3, + 0x75, 0xab, 0xd7, 0x14, 0x2a, 0x88, 0xbf, 0xaa, 0xfd, 0x05, 0x59, 0x78, 0x42, 0xf1, 0x32, 0xf4, + 0x71, 0xda, 0x27, 0x82, 0x21, 0x1b, 0xbc, 0x4c, 0xbd, 0x53, 0xaf, 0x58, 0xab, 0x82, 0x3e, 0xd1, + 0xb3, 0x63, 0xc4, 0x2c, 0xb8, 0x8f, 0xc4, 0x93, 0x69, 0xa6, 0x9a, 0xf8, 0x82, 0x15, 0xea, 0xbc, + 0x4f, 0xd5, 0xdf, 0x54, 0xef, 0xce, 0x56, 0xfb, 0x6d, 0xb6, 0xdf, 0xa2, 0x33, 0xe8, 0x8e, 0xf8, + 0x22, 0x2a, 0xad, 0xcc, 0x2f, 0x12, 0xb9, 0x7d, 0x6b, 0xe6, 0xea, 0xab, 0xa2, 0xc5, 0x27, 0x21, + 0x14, 0x3c, 0xc8, 0xf3, 0xe1, 0xf1, 0x96, 0x48, 0x3e, 0x9e, 0xf7, 0x6b, 0x97, 0xd1, 0xdd, 0x7c, + 0xc4, 0xaa, 0x6b, 0x86, 0x37, 0xd5, 0x20, 0xf9, 0x0a, 0xb5, 0xa8, 0x81, 0x17, 0x89, 0x9b, 0x12, + 0x20, 0x4a, 0x55, 0x69, 0x57, 0x13, 0x89, 0xa1, 0x88, 0x7c, 0x71, 0xbe, 0x89, 0x97, 0xc5, 0x99, + 0x55, 0xdd, 0xef, 0xf0, 0x51, 0x2e, 0x75, 0x55, 0x56, 0x71, 0x10, 0x4b, 0xda, 0x6a, 0xd5, 0x58, + 0x3e, 0xa9, 0x91, 0xb0, 0xca, 0x8e, 0xf5, 0xf0, 0x55, 0x7b, 0xf5, 0x55, 0x55, 0x58, 0xa5, 0xc3, + 0x12, 0x73, 0x12, 0xaa, 0x92, 0xe3, 0xc4, 0x29, 0x21, 0xcb, 0x1a, 0x34, 0x3b, 0x45, 0x6d, 0x7e, + 0x09, 0xf5, 0x49, 0x2d, 0x34, 0xdf, 0xe0, 0x8b, 0xb3, 0x35, 0x37, 0xf8, 0x4c, 0x94, 0x89, 0x3a, + 0x4e, 0xee, 0xeb, 0x82, 0xad, 0x25, 0x2b, 0x28, 0xd7, 0xaa, 0xaa, 0xa4, 0x7c, 0x45, 0x61, 0x0b, + 0xe8, 0x27, 0x17, 0xd1, 0xbb, 0xeb, 0x7f, 0x82, 0x29, 0xbf, 0xef, 0xa1, 0xe0, 0x3a, 0xfa, 0x10, + 0x4a, 0xba, 0x26, 0x1f, 0x45, 0xa9, 0x31, 0x35, 0x84, 0x2b, 0xa2, 0xc5, 0xf4, 0x49, 0x8f, 0x82, + 0x1a, 0xd6, 0xca, 0xc2, 0x08, 0xee, 0x3d, 0xdd, 0xdd, 0xfd, 0x62, 0x3f, 0xe8, 0x91, 0x57, 0x45, + 0x47, 0x4b, 0xe8, 0xc8, 0xdf, 0xd6, 0xae, 0x20, 0x45, 0x62, 0x7c, 0x45, 0xf4, 0x72, 0x27, 0xd1, + 0x2b, 0xc4, 0x18, 0x94, 0x73, 0x31, 0xe0, 0x98, 0x55, 0xe6, 0x92, 0x7e, 0xfc, 0xe7, 0xc4, 0xe9, + 0x24, 0x92, 0x6d, 0x7e, 0x08, 0xaa, 0x95, 0xf2, 0xbe, 0x2b, 0x4e, 0xdb, 0x5b, 0x46, 0xe8, 0x22, + 0x3b, 0x4b, 0xd1, 0x08, 0x05, 0x4e, 0x26, 0x8b, 0xdf, 0x44, 0xea, 0xea, 0x2a, 0x66, 0x0e, 0x10, + 0x45, 0x7f, 0x12, 0x8a, 0x00, 0x52, 0x9d, 0x6b, 0xac, 0xaf, 0x12, 0xae, 0x56, 0x11, 0x9b, 0xaa, + 0x46, 0xfa, 0x34, 0x67, 0x08, 0x6b, 0xa8, 0xc5, 0x2b, 0xae, 0xbe, 0x8a, 0x3b, 0x57, 0x20, 0x41, + 0x63, 0x5f, 0xa3, 0x6b, 0xe2, 0x0b, 0x75, 0xee, 0xc7, 0xe6, 0xbb, 0xfe, 0x27, 0x74, 0xf4, 0xe9, + 0x79, 0xaa, 0x6c, 0x4a, 0x7c, 0xc7, 0x55, 0x55, 0xf3, 0x0c, 0x43, 0x6d, 0xbf, 0x82, 0x31, 0x78, + 0x36, 0x4b, 0xf7, 0x84, 0x6b, 0x94, 0x4a, 0xaf, 0xe0, 0x84, 0x8e, 0xf8, 0xa2, 0xbe, 0x09, 0xcb, + 0x7b, 0xde, 0xe9, 0xab, 0xab, 0x56, 0x19, 0x47, 0xd7, 0xd1, 0x91, 0xbb, 0xeb, 0xac, 0x59, 0x31, + 0xf3, 0xaf, 0x5a, 0xfa, 0x3a, 0x3b, 0xf5, 0x47, 0x7e, 0x09, 0x04, 0x2a, 0xfd, 0xf0, 0x49, 0x55, + 0x55, 0x32, 0x7d, 0x09, 0x8a, 0x4c, 0x31, 0x7d, 0x11, 0xc9, 0x3a, 0x3a, 0x46, 0xfa, 0x23, 0xfc, + 0x12, 0x12, 0xaa, 0xa4, 0x6f, 0x82, 0x2d, 0x6b, 0xe7, 0xc1, 0x15, 0xa6, 0x95, 0x75, 0xe2, 0x51, + 0x3b, 0xe0, 0x97, 0xb4, 0xd5, 0x6b, 0xdf, 0x51, 0xf7, 0xc1, 0x11, 0x49, 0xeb, 0xb4, 0x9c, 0x14, + 0x04, 0x1d, 0x96, 0x3d, 0x09, 0x6d, 0x5a, 0xc4, 0x09, 0xdf, 0x05, 0x7c, 0xbe, 0x7b, 0x07, 0xea, + 0xc6, 0x83, 0x33, 0x32, 0x4f, 0x89, 0xa7, 0x97, 0xe9, 0x19, 0x8f, 0x17, 0xbd, 0xf0, 0x8f, 0xcf, + 0x97, 0xe1, 0x0d, 0xd2, 0xa4, 0x96, 0x6b, 0xdf, 0xc2, 0x07, 0x66, 0xb7, 0x58, 0xda, 0xf5, 0x7f, + 0x9b, 0x79, 0xf3, 0xc4, 0x88, 0x63, 0x1d, 0xb5, 0xae, 0xa1, 0x01, 0x28, 0x2b, 0x5f, 0x58, 0x3e, + 0x8e, 0x03, 0x40, 0x6a, 0xc4, 0x21, 0x08, 0xef, 0xd5, 0x32, 0x5d, 0x5a, 0xb0, 0x8c, 0xd8, 0x9f, + 0x0c, 0x7d, 0x5c, 0xfa, 0xb7, 0x0c, 0x84, 0x15, 0xae, 0x24, 0x21, 0x27, 0x2f, 0x77, 0xe2, 0x4c, + 0x7c, 0x65, 0xa1, 0x4b, 0x41, 0x62, 0x24, 0x11, 0xaa, 0xfa, 0xc5, 0xf0, 0x49, 0xdd, 0xdb, 0xea, + 0x9d, 0x1a, 0x23, 0xf4, 0x7a, 0xfa, 0x2e, 0x5f, 0x41, 0x4e, 0xf8, 0x2c, 0x32, 0x46, 0x86, 0xd5, + 0x6c, 0x71, 0xdc, 0x96, 0xce, 0x30, 0xf0, 0xec, 0x98, 0x30, 0x62, 0xc0, 0xc0, 0x79, 0xbc, 0x3a, + 0x34, 0xbb, 0x93, 0xca, 0x5b, 0x5f, 0x6e, 0x7b, 0xf8, 0xbd, 0x2b, 0xa7, 0xbf, 0x8c, 0xd8, 0xea, + 0x6a, 0xd1, 0x83, 0xab, 0x27, 0x2e, 0x75, 0x50, 0xb3, 0xdf, 0x89, 0x94, 0x6d, 0x0c, 0x70, 0xd9, + 0xd1, 0x54, 0xdc, 0x8b, 0xc4, 0x89, 0xb2, 0x42, 0xd0, 0xde, 0x38, 0x4b, 0xe4, 0x2a, 0xea, 0x66, + 0x3c, 0xc3, 0x2b, 0x5f, 0x45, 0xee, 0x23, 0xf4, 0x13, 0xae, 0x24, 0x4c, 0xf8, 0x66, 0x3a, 0x27, + 0xe2, 0x01, 0x11, 0x35, 0x54, 0x8b, 0xc9, 0x55, 0xfc, 0x11, 0xf7, 0x79, 0x7d, 0x11, 0xbe, 0xad, + 0x78, 0x8f, 0x9c, 0xa9, 0x3e, 0xa4, 0xff, 0xab, 0xbe, 0xa9, 0x2b, 0x12, 0x8e, 0xc7, 0x89, 0x59, + 0x8b, 0xea, 0xca, 0xe1, 0x3a, 0xaf, 0xbb, 0xf8, 0x24, 0x14, 0xe4, 0x8f, 0xdf, 0x04, 0x7a, 0x6d, + 0xac, 0xab, 0x82, 0xd1, 0x52, 0x3f, 0x54, 0xe6, 0xb8, 0xab, 0x82, 0x2c, 0xf9, 0xbb, 0xe0, 0x86, + 0xdd, 0x89, 0xaf, 0x7c, 0x12, 0x9e, 0x9d, 0xab, 0xd5, 0xeb, 0x90, 0xa9, 0x32, 0x6b, 0xe0, 0x84, + 0x71, 0x99, 0xad, 0xbe, 0x8a, 0x92, 0xa2, 0x68, 0x26, 0xef, 0xab, 0x7d, 0x11, 0xfe, 0xad, 0xf4, + 0x57, 0xfa, 0x2b, 0xdc, 0x21, 0x54, 0xd2, 0x0f, 0x5a, 0x34, 0xfd, 0xdd, 0xdf, 0xd5, 0x93, 0xf4, + 0x29, 0xfe, 0x08, 0xaa, 0xaa, 0xad, 0x7d, 0x5a, 0x48, 0x46, 0x8f, 0xd2, 0x75, 0x67, 0x0c, 0xeb, + 0x04, 0x05, 0xea, 0xbc, 0x48, 0x48, 0xb7, 0x77, 0xa4, 0xef, 0xc4, 0xdc, 0x48, 0x84, 0x6d, 0x7d, + 0x0c, 0x6a, 0xe0, 0xa4, 0x89, 0x14, 0xde, 0x93, 0x0a, 0x73, 0x83, 0xe6, 0x3b, 0x7a, 0xf8, 0x40, + 0x99, 0x0d, 0x13, 0xbf, 0x32, 0xe1, 0x86, 0xb8, 0x5f, 0x57, 0x1f, 0x82, 0x63, 0xd4, 0x67, 0xcd, + 0xcb, 0xb7, 0x76, 0x0f, 0x88, 0x1e, 0x4e, 0x4e, 0xf2, 0xea, 0xae, 0xf9, 0x86, 0x4b, 0x17, 0xdf, + 0x41, 0x37, 0x9e, 0x23, 0xf5, 0x45, 0x2b, 0xd5, 0x88, 0xae, 0x08, 0xc5, 0x5e, 0xa9, 0x1f, 0x82, + 0x3e, 0xef, 0x93, 0xaf, 0x5f, 0x7c, 0xe2, 0x55, 0xb6, 0xdb, 0x6f, 0xfd, 0x11, 0x2f, 0x89, 0x05, + 0x1d, 0x55, 0x57, 0x1d, 0x2f, 0x82, 0x43, 0x6a, 0xa3, 0x54, 0xf9, 0xeb, 0x3f, 0xa7, 0xeb, 0xa8, + 0xef, 0x3c, 0x10, 0x1e, 0x0c, 0x20, 0x68, 0x61, 0x42, 0x96, 0x2d, 0x9f, 0x6a, 0xf2, 0x62, 0x56, + 0xbc, 0x41, 0x2a, 0xba, 0xeb, 0x5e, 0x23, 0xe5, 0xe5, 0xc5, 0xf3, 0x62, 0xeb, 0xf2, 0x11, 0x34, + 0x4d, 0x34, 0xbb, 0xea, 0x97, 0x82, 0x83, 0x37, 0x33, 0x64, 0xf4, 0xcf, 0x0c, 0xef, 0x82, 0x8a, + 0x4f, 0x03, 0x49, 0x63, 0x06, 0x23, 0xc8, 0xa3, 0xe0, 0x84, 0xa9, 0x5b, 0x4e, 0x2f, 0xa2, 0xf5, + 0x70, 0x97, 0x69, 0xad, 0xb3, 0xef, 0xb2, 0xaa, 0xfe, 0x26, 0xef, 0xd6, 0xeb, 0x89, 0x21, 0x12, + 0xa7, 0x44, 0xdb, 0x7f, 0x90, 0x66, 0x99, 0x66, 0x2b, 0x82, 0x40, 0x9d, 0xef, 0x17, 0xcf, 0x5c, + 0x5b, 0xf8, 0x9e, 0x24, 0xcf, 0x7b, 0xcb, 0x84, 0xc5, 0x88, 0x05, 0x87, 0x26, 0x7c, 0x6b, 0xde, + 0xd3, 0x53, 0x8f, 0x39, 0xba, 0xd3, 0x4d, 0xb7, 0xfe, 0x09, 0xf5, 0xad, 0x6a, 0x91, 0x78, 0xbe, + 0x92, 0x57, 0x7f, 0x96, 0xef, 0xfa, 0x23, 0x1f, 0x56, 0x3e, 0xea, 0xba, 0xe2, 0x2d, 0x35, 0xb4, + 0xd6, 0xf9, 0x2e, 0xff, 0xa9, 0x45, 0xf0, 0x85, 0xdf, 0x4b, 0x57, 0x7f, 0xc4, 0x74, 0x92, 0xd2, + 0x4b, 0xc1, 0x77, 0x55, 0x5d, 0xa9, 0x7c, 0x14, 0x67, 0xf4, 0xa6, 0xaf, 0x17, 0xc2, 0x44, 0x2d, + 0x24, 0xd1, 0xac, 0x9d, 0x3a, 0x7e, 0x09, 0x34, 0xe9, 0xb0, 0xf1, 0xc7, 0xe4, 0xd4, 0x92, 0xab, + 0x7b, 0xf9, 0x2d, 0xaf, 0xe0, 0xa0, 0x62, 0x23, 0xb0, 0x80, 0xf1, 0xf5, 0x7f, 0xee, 0xf8, 0xe2, + 0xe4, 0xbc, 0xa6, 0xaa, 0x5b, 0x61, 0xdf, 0xc1, 0x19, 0x42, 0x5d, 0xb8, 0xd6, 0x0e, 0x8c, 0x1b, + 0xbe, 0x08, 0xeb, 0x9b, 0xf5, 0x73, 0x09, 0x6d, 0x36, 0x5f, 0x1d, 0x76, 0xbb, 0xab, 0x9f, 0xa2, + 0x64, 0xcb, 0xc1, 0x35, 0xaa, 0x9a, 0x35, 0xb6, 0xf2, 0x72, 0x0a, 0x26, 0x0b, 0xd2, 0xf4, 0x47, + 0x7c, 0x11, 0xea, 0x95, 0xc8, 0x8e, 0x09, 0x0b, 0x2f, 0xdf, 0xec, 0x9a, 0xb8, 0x9e, 0x0a, 0x42, + 0x29, 0x2b, 0xc6, 0x34, 0xfb, 0xbe, 0x74, 0xae, 0x08, 0xb7, 0x55, 0x63, 0xe6, 0xaa, 0xeb, 0x9b, + 0x9b, 0x0d, 0x9e, 0x08, 0xee, 0xfc, 0xa9, 0xf0, 0x44, 0x75, 0x5c, 0xa9, 0x5d, 0x11, 0xe4, 0xc4, + 0x88, 0xec, 0xcf, 0x69, 0x24, 0xfb, 0x7d, 0xf1, 0x20, 0x93, 0xbb, 0xa3, 0xbf, 0x52, 0x27, 0xd6, + 0x77, 0xc1, 0x20, 0xca, 0x69, 0x26, 0xea, 0xe2, 0x89, 0x9b, 0xdb, 0xb5, 0xf6, 0x5d, 0x5f, 0xca, + 0x7a, 0x74, 0xfc, 0x59, 0x9d, 0x53, 0xd2, 0xa5, 0xe1, 0x69, 0xa4, 0x6a, 0xb2, 0xb9, 0xb1, 0xb6, + 0x61, 0x46, 0x7c, 0xf8, 0x9f, 0xec, 0x8f, 0x7f, 0x89, 0xb6, 0x89, 0xba, 0xc2, 0xf8, 0x9d, 0xaf, + 0xd8, 0xbc, 0xb9, 0xf0, 0x87, 0x77, 0x5d, 0xa6, 0xae, 0xfe, 0x12, 0xa0, 0x32, 0x88, 0x0a, 0x03, + 0x68, 0x80, 0xdd, 0xfc, 0x4d, 0xf3, 0x16, 0xf7, 0xf2, 0x5d, 0xd5, 0x57, 0x05, 0x06, 0xb4, 0xad, + 0x34, 0xd5, 0xa2, 0x27, 0xc1, 0x11, 0x15, 0x7a, 0xf8, 0x2e, 0x32, 0xe4, 0x82, 0xea, 0x90, 0x3c, + 0x58, 0x9c, 0x7a, 0xdd, 0x56, 0xaf, 0x8a, 0xd2, 0xa6, 0xd5, 0x8d, 0xfc, 0x17, 0x1a, 0xca, 0xfc, + 0xb8, 0x74, 0xf8, 0x27, 0x3c, 0xd9, 0xd8, 0xef, 0xaf, 0x85, 0x2f, 0x73, 0xe5, 0x36, 0x9d, 0x0e, + 0x8e, 0xed, 0x67, 0xef, 0xf0, 0x58, 0x47, 0xcd, 0x99, 0xb3, 0x49, 0x2b, 0x85, 0xd0, 0x4d, 0x2a, + 0x5c, 0x12, 0x08, 0x69, 0xa6, 0x9a, 0xc3, 0xeb, 0x2f, 0x8b, 0x33, 0x4d, 0x6d, 0x6f, 0xe0, 0xa3, + 0x97, 0x12, 0xd2, 0x4a, 0x2f, 0x8e, 0x13, 0xbb, 0xee, 0xee, 0xee, 0xeb, 0x96, 0xab, 0xf1, 0x2b, + 0xff, 0x12, 0x09, 0x3a, 0xae, 0x0b, 0xf0, 0x4d, 0xdd, 0xea, 0xbf, 0x7c, 0x10, 0xdd, 0xf6, 0x3e, + 0xea, 0xa5, 0xc6, 0xe2, 0xe0, 0x8b, 0xbb, 0xf7, 0xcd, 0xbd, 0xd7, 0x47, 0x89, 0x16, 0x20, 0x4a, + 0x8e, 0x3b, 0xc2, 0x1f, 0x5e, 0xf9, 0x88, 0xb5, 0xf9, 0x05, 0x2b, 0x3a, 0x7e, 0x09, 0x7b, 0x49, + 0xad, 0x52, 0xe4, 0x5e, 0x2a, 0xaf, 0x2e, 0x27, 0x6f, 0xf6, 0x23, 0x56, 0xd7, 0x20, 0xda, 0xdf, + 0xc2, 0x43, 0x39, 0xf5, 0xd2, 0x6b, 0xe0, 0x84, 0xa8, 0xf7, 0xe7, 0x48, 0x0b, 0x82, 0x22, 0xcf, + 0x9a, 0x54, 0xb8, 0x81, 0x2d, 0x35, 0xd6, 0xfe, 0xee, 0xef, 0xf0, 0x9e, 0xb6, 0x4a, 0xaf, 0x5d, + 0xf7, 0x4f, 0xcd, 0xad, 0x7c, 0x50, 0x8d, 0xb3, 0x7a, 0xb5, 0x5c, 0x20, 0x7a, 0x45, 0xcd, 0xab, + 0x48, 0xdd, 0xf5, 0xc5, 0xcb, 0x9f, 0x4d, 0xfd, 0x8e, 0xcd, 0xff, 0x04, 0x85, 0xa5, 0x5d, 0x30, + 0xf8, 0x25, 0x2e, 0xd3, 0x5a, 0x6e, 0xc5, 0x71, 0x44, 0xb4, 0x94, 0xb0, 0xbf, 0xc2, 0x77, 0xd1, + 0xaa, 0xb4, 0xbe, 0xc9, 0xcf, 0x9e, 0x69, 0x6d, 0x7f, 0x2d, 0xa4, 0xbf, 0x21, 0x55, 0x7f, 0x52, + 0x9c, 0xae, 0x08, 0x6f, 0xa5, 0x05, 0x71, 0x74, 0x92, 0x7a, 0x49, 0x65, 0xe8, 0xa6, 0x4f, 0xa9, + 0x93, 0xeb, 0x5f, 0x2f, 0x55, 0x5d, 0x72, 0x93, 0x12, 0x72, 0x89, 0x34, 0xb6, 0xd8, 0xb6, 0x2d, + 0xfc, 0x5a, 0x8f, 0x75, 0x63, 0xd4, 0xd8, 0x2b, 0x77, 0xb7, 0xfe, 0x17, 0xab, 0x76, 0xb6, 0x92, + 0xc3, 0x2e, 0xb6, 0xcc, 0xff, 0x66, 0xd9, 0x3f, 0x8b, 0x2f, 0x3e, 0x2b, 0x59, 0xb7, 0xc9, 0x4f, + 0x4b, 0xca, 0x22, 0x6c, 0xfc, 0x79, 0xe4, 0xf7, 0xc5, 0x7b, 0x76, 0xfc, 0x55, 0xaa, 0x77, 0x7f, + 0xc1, 0x19, 0x39, 0x98, 0x8b, 0xe0, 0x8e, 0xdd, 0xbe, 0xc5, 0x76, 0x35, 0xb4, 0xff, 0x04, 0xe4, + 0x7b, 0xe7, 0xdd, 0xcf, 0xab, 0x97, 0xd1, 0x1e, 0xba, 0x12, 0xff, 0x30, 0xaa, 0xd1, 0xf8, 0x50, + 0xab, 0x64, 0x93, 0x4b, 0xcd, 0xb6, 0xde, 0x9b, 0xb9, 0xc4, 0x41, 0x41, 0xd9, 0x9f, 0x28, 0xef, + 0x74, 0xab, 0xc1, 0x55, 0xa6, 0xac, 0x23, 0x61, 0xb1, 0x99, 0xb3, 0x7a, 0xb1, 0xf0, 0x84, 0xb6, + 0x9d, 0x9d, 0x39, 0x7b, 0x9f, 0x2a, 0xf1, 0x12, 0x92, 0x5b, 0xaf, 0x82, 0x21, 0x54, 0x55, 0x4a, + 0x1e, 0x0a, 0xba, 0x49, 0x2d, 0x2d, 0xc7, 0x35, 0xdb, 0xe0, 0xa2, 0xda, 0xf2, 0x6b, 0xec, 0x7d, + 0x17, 0x2f, 0x82, 0x18, 0xda, 0xfe, 0x0f, 0x9a, 0xb2, 0x69, 0x7f, 0x96, 0x92, 0x5f, 0xc2, 0x3b, + 0xbd, 0x24, 0xbb, 0xd3, 0xf0, 0x43, 0x49, 0x2f, 0x0f, 0x82, 0x22, 0xa6, 0x97, 0x5f, 0x04, 0x34, + 0x92, 0x4b, 0x55, 0xcd, 0x27, 0x4f, 0xf0, 0x9d, 0xea, 0x6d, 0x77, 0xd7, 0x5c, 0xbe, 0x12, 0xa5, + 0xb4, 0x8f, 0x26, 0x7a, 0xd5, 0x71, 0x36, 0x9a, 0xab, 0x6b, 0x4d, 0x71, 0x16, 0x9a, 0xda, 0xda, + 0xf1, 0x25, 0x49, 0x24, 0x92, 0x77, 0x6b, 0xef, 0x6d, 0xeb, 0x82, 0x2d, 0x6a, 0xe7, 0xcd, 0x69, + 0x52, 0x2e, 0x78, 0xcd, 0x5f, 0x4d, 0x36, 0x92, 0x4a, 0x24, 0x9a, 0xa5, 0xf0, 0x47, 0x5d, 0x53, + 0x2f, 0x04, 0x91, 0x76, 0xb4, 0x6a, 0xbc, 0x79, 0x9d, 0xba, 0xd6, 0xae, 0xed, 0x27, 0xe0, 0x92, + 0x78, 0x76, 0x7c, 0xda, 0x53, 0xe7, 0x96, 0x97, 0x48, 0x9d, 0xd7, 0x5f, 0x13, 0x5c, 0x22, 0x56, + 0xd6, 0xab, 0x56, 0xad, 0x4f, 0x9e, 0x13, 0xea, 0xa9, 0xd3, 0x4d, 0x73, 0x11, 0xdf, 0xf2, 0x9c, + 0xfb, 0x5b, 0xe4, 0xc9, 0xb7, 0xf2, 0x08, 0x6d, 0xff, 0x14, 0x25, 0x5d, 0xf6, 0x92, 0x1c, 0xdf, + 0x82, 0x42, 0x26, 0xe9, 0xb6, 0xff, 0x21, 0xe7, 0xc2, 0x52, 0xfc, 0x23, 0x3d, 0xb5, 0x7c, 0xf9, + 0xb3, 0x25, 0xc5, 0xe1, 0x2f, 0x17, 0x47, 0x76, 0x7e, 0x6d, 0x6e, 0xb8, 0x22, 0x14, 0x94, 0xb9, + 0xf3, 0xe0, 0x88, 0xa9, 0x24, 0xe9, 0x45, 0xf0, 0x5d, 0xd2, 0x49, 0xbd, 0xd2, 0xfc, 0x11, 0x53, + 0xe7, 0xcd, 0x57, 0x04, 0x36, 0xd3, 0xdc, 0xae, 0x5e, 0x7c, 0x6b, 0xc1, 0x3d, 0x37, 0xa4, 0x9d, + 0xad, 0xcf, 0xb2, 0xde, 0x2b, 0x5c, 0x25, 0xda, 0x69, 0x2d, 0xfd, 0x11, 0xcf, 0x9f, 0x52, 0x69, + 0x37, 0xf5, 0x88, 0x04, 0x95, 0x93, 0xc4, 0xeb, 0xf8, 0x2e, 0xb4, 0xd7, 0x75, 0xf7, 0xc1, 0x45, + 0x6b, 0x6e, 0xdf, 0xbe, 0x6a, 0x49, 0x7e, 0x49, 0xec, 0xf7, 0xf8, 0x21, 0xd3, 0x3d, 0x38, 0xab, + 0x82, 0x2c, 0xfb, 0xd5, 0x44, 0x6b, 0x82, 0x42, 0x69, 0x24, 0x60, 0x7c, 0xd6, 0x6c, 0xe7, 0xfe, + 0x1c, 0xa6, 0x9d, 0x35, 0x1a, 0x4b, 0xe8, 0xff, 0xe0, 0x8f, 0x36, 0xef, 0x5c, 0x22, 0x54, 0xe9, + 0xe9, 0x5a, 0x49, 0x2d, 0x44, 0x7e, 0x4d, 0x2b, 0x7e, 0x20, 0xb2, 0xf6, 0xbd, 0xd3, 0xf7, 0x48, + 0xb8, 0x93, 0x73, 0xcb, 0x9d, 0x43, 0x12, 0x7a, 0x67, 0x82, 0xd2, 0x4d, 0xd3, 0xed, 0xb5, 0x6f, + 0x94, 0xea, 0xae, 0xfe, 0xef, 0x7a, 0xe3, 0xab, 0x77, 0xdd, 0xc9, 0x2b, 0xd7, 0x2f, 0x57, 0xf0, + 0x90, 0xab, 0xbb, 0x6d, 0xed, 0xf9, 0x4e, 0x91, 0xf3, 0xf1, 0x85, 0x55, 0x24, 0x3b, 0x4f, 0x99, + 0x23, 0xb6, 0xab, 0x95, 0x19, 0x37, 0xf8, 0x40, 0x9c, 0xb9, 0x49, 0xa8, 0x9f, 0x7a, 0x6f, 0xe0, + 0xa3, 0x3e, 0x74, 0x9b, 0x67, 0x7f, 0x84, 0xe9, 0x4b, 0xaa, 0x6d, 0xcb, 0x9e, 0x20, 0xaa, 0x68, + 0x96, 0x16, 0x92, 0x4d, 0x35, 0xe2, 0x77, 0xba, 0xee, 0xb8, 0x27, 0x19, 0x7a, 0x77, 0x56, 0xea, + 0xb8, 0x21, 0x3a, 0xed, 0xea, 0xf8, 0x27, 0xa6, 0xfd, 0xba, 0x58, 0x7c, 0x11, 0xe9, 0xa5, 0x9c, + 0xf8, 0x25, 0xac, 0xda, 0x58, 0xdb, 0x6b, 0x3b, 0xe4, 0xee, 0xdf, 0x84, 0x2d, 0xe7, 0xd6, 0xdd, + 0x9e, 0x32, 0xad, 0xdf, 0x04, 0x24, 0xab, 0x4d, 0x77, 0xdd, 0x24, 0x8f, 0xff, 0x05, 0x3d, 0x24, + 0xd2, 0x44, 0x7c, 0x7e, 0xe3, 0x6b, 0x59, 0x85, 0xf1, 0xd7, 0xe7, 0xdc, 0xd9, 0x7d, 0xd2, 0xf1, + 0x56, 0xb4, 0xf6, 0xd3, 0xf0, 0x5b, 0x69, 0xa4, 0x92, 0x2e, 0x6f, 0x39, 0xf0, 0x5b, 0x76, 0xed, + 0xa6, 0xda, 0x6d, 0x98, 0x5f, 0x05, 0x75, 0x4d, 0x2c, 0xfd, 0x2b, 0x55, 0xf0, 0x55, 0xe0, 0x9a, + 0x92, 0x49, 0x25, 0x4d, 0x22, 0x6a, 0x55, 0xe3, 0xea, 0xba, 0xdb, 0x68, 0xfe, 0x5b, 0x2f, 0xf0, + 0x8e, 0xa9, 0x24, 0x5c, 0x3f, 0xda, 0xcd, 0xad, 0xc6, 0xb8, 0x29, 0x2a, 0x49, 0xcb, 0xee, 0xee, + 0x93, 0x36, 0x5f, 0x15, 0xf0, 0x95, 0x28, 0xca, 0xee, 0x5d, 0xfc, 0x14, 0x76, 0xdb, 0x7a, 0x7e, + 0xf9, 0x89, 0x1d, 0xab, 0x43, 0xf0, 0xb9, 0x69, 0x53, 0x54, 0xcd, 0xf3, 0x0a, 0x3f, 0xaf, 0x4f, + 0xfe, 0x12, 0x8f, 0x2c, 0xf5, 0x5a, 0x0b, 0x11, 0xf9, 0x29, 0xba, 0x75, 0xcb, 0xdb, 0x6f, 0xca, + 0x5d, 0x34, 0xfc, 0x54, 0xf9, 0x69, 0xad, 0x5f, 0x11, 0x05, 0x1b, 0xcd, 0x84, 0xcd, 0x5e, 0xf8, + 0x4f, 0x89, 0x36, 0xed, 0xdb, 0xf1, 0xd4, 0xe9, 0xb1, 0xed, 0xac, 0x43, 0xef, 0xee, 0x9d, 0x3f, + 0x92, 0x92, 0xd2, 0x58, 0x85, 0x7b, 0xe0, 0xb4, 0xcd, 0x52, 0x6a, 0xe9, 0xbf, 0x7d, 0x9c, 0xb7, + 0xfe, 0x3b, 0x9f, 0xab, 0x45, 0xcd, 0xd1, 0x3f, 0xc2, 0x37, 0x61, 0x9b, 0x6e, 0x39, 0x39, 0xad, + 0xdb, 0x74, 0x0d, 0xfc, 0x71, 0x5a, 0x79, 0x9a, 0x96, 0xa9, 0xa3, 0x7f, 0xc2, 0x64, 0x6a, 0xd3, + 0x2d, 0xdf, 0xc6, 0x53, 0xdd, 0x3a, 0x71, 0xef, 0xd4, 0xf3, 0x50, 0xf4, 0xdd, 0xf1, 0xf5, 0x5a, + 0xc9, 0x05, 0x89, 0x75, 0xf0, 0x48, 0x32, 0xc8, 0x99, 0xb7, 0xc2, 0x42, 0x56, 0xbd, 0x23, 0xff, + 0x25, 0x6f, 0xf2, 0x69, 0xdf, 0xca, 0x4c, 0xbd, 0xaf, 0x08, 0x69, 0x2b, 0x55, 0x6b, 0x6e, 0xfe, + 0x12, 0x2e, 0xac, 0x7a, 0xb7, 0xe0, 0x9b, 0xa4, 0x92, 0xa6, 0xdb, 0x55, 0xf0, 0x4f, 0x8b, 0x4a, + 0xd5, 0xad, 0x7c, 0xb6, 0xb6, 0xfc, 0x29, 0x96, 0x99, 0x68, 0x5a, 0x2c, 0xe4, 0x83, 0xee, 0xfd, + 0xf5, 0xef, 0xbc, 0x91, 0x4f, 0xf3, 0x5e, 0x93, 0x1f, 0x88, 0x21, 0x77, 0xd3, 0xa5, 0xee, 0x99, + 0xff, 0xe0, 0x92, 0x5e, 0xde, 0xc7, 0xcb, 0x49, 0xd2, 0xf8, 0x26, 0x39, 0x34, 0xba, 0x4d, 0x6e, + 0xb5, 0xd2, 0x6f, 0x82, 0xb2, 0x65, 0xdb, 0xd3, 0x4b, 0x9a, 0x49, 0x8f, 0x84, 0xf7, 0x56, 0xb6, + 0x8d, 0x9e, 0x09, 0xe9, 0x52, 0xd2, 0xbd, 0x7c, 0x23, 0x6d, 0x32, 0xe4, 0x52, 0xe5, 0xef, 0x6b, + 0xcb, 0x4b, 0x6f, 0xc1, 0x3f, 0x74, 0x94, 0x9a, 0xdf, 0xdf, 0x17, 0x2e, 0xdb, 0xd3, 0x96, 0x5e, + 0x19, 0xcd, 0x04, 0xe0, 0x6c, 0xa9, 0xc4, 0x12, 0x0b, 0xfe, 0xb8, 0x2a, 0x12, 0xe8, 0xb2, 0x7f, + 0x75, 0xbd, 0x70, 0x99, 0x9b, 0xd3, 0x7d, 0x57, 0x04, 0x26, 0xa4, 0x86, 0x95, 0xbe, 0x2c, 0x5d, + 0xdf, 0x2e, 0x25, 0x7e, 0x4a, 0x6b, 0xf8, 0x42, 0xdc, 0xf5, 0x5b, 0xd7, 0xe0, 0xba, 0xda, 0x69, + 0x27, 0x4d, 0x34, 0xeb, 0xe2, 0x24, 0xc6, 0x61, 0x35, 0xba, 0xa4, 0xc8, 0xd9, 0x9e, 0x22, 0x92, + 0x51, 0x24, 0xdd, 0xbf, 0x8a, 0xbe, 0xac, 0x7a, 0xf9, 0x89, 0x97, 0x1d, 0xf3, 0x51, 0x65, 0xbf, + 0x08, 0x95, 0x23, 0x59, 0x2e, 0x2e, 0x4a, 0xec, 0x97, 0xc9, 0x24, 0x58, 0x66, 0x48, 0xe4, 0x9e, + 0x5d, 0x2a, 0x5e, 0x23, 0xb4, 0xd3, 0x44, 0x14, 0x6b, 0xf1, 0x97, 0xbb, 0xb5, 0x1a, 0xc4, 0x2a, + 0x64, 0x87, 0x54, 0x6b, 0xce, 0xbf, 0x13, 0x75, 0x44, 0xc9, 0x32, 0xff, 0xc4, 0x71, 0x1f, 0xb2, + 0xaa, 0xeb, 0x90, 0x44, 0xdf, 0xf0, 0x42, 0x6d, 0xa6, 0xc8, 0x91, 0x87, 0x87, 0x04, 0xd5, 0x3a, + 0xe6, 0xed, 0xff, 0x8f, 0xa7, 0x7a, 0x45, 0xc7, 0xda, 0x6f, 0xf2, 0x5b, 0xcb, 0xfc, 0x34, 0x44, + 0xdf, 0x56, 0xdb, 0x6d, 0xbf, 0xf1, 0x5b, 0x2b, 0xdd, 0x3f, 0x86, 0xfc, 0xb8, 0xab, 0x4d, 0x3f, + 0xf0, 0x51, 0x7b, 0xf9, 0x73, 0x2f, 0x8e, 0x2d, 0xe9, 0x9f, 0x53, 0xe9, 0x97, 0xc5, 0x7e, 0x30, + 0x93, 0x5b, 0xbb, 0xe9, 0x4b, 0x9b, 0xbf, 0x88, 0x3a, 0x69, 0xfb, 0x49, 0xf8, 0x46, 0xd9, 0x74, + 0xfa, 0xfd, 0xdb, 0x3e, 0xd5, 0x7e, 0x17, 0x97, 0xc8, 0xe2, 0xf6, 0xda, 0xd6, 0xea, 0xff, 0xe1, + 0x3d, 0x3a, 0x67, 0xff, 0xc2, 0x5c, 0xbf, 0xcf, 0x9e, 0x0b, 0xef, 0xbc, 0x99, 0x4d, 0x55, 0xd5, + 0xff, 0xc3, 0x86, 0xa5, 0x4b, 0x2a, 0xb7, 0x6f, 0xfc, 0x4e, 0x92, 0x49, 0x3b, 0x6d, 0xfc, 0x4e, + 0xda, 0x49, 0x8c, 0xd4, 0xe6, 0xb5, 0x8a, 0x35, 0xc1, 0x0f, 0x76, 0x93, 0x2f, 0x57, 0x3e, 0xf7, + 0x7f, 0x82, 0x4b, 0x69, 0xf1, 0xcf, 0x82, 0x73, 0x37, 0x0a, 0xad, 0x25, 0xb1, 0xf2, 0x52, 0x48, + 0xb9, 0x17, 0xa3, 0xe5, 0xf0, 0xa0, 0x9c, 0xd2, 0xad, 0x67, 0xfa, 0xaa, 0xdd, 0x3f, 0x11, 0x04, + 0x44, 0x26, 0x6b, 0xdf, 0x26, 0xd2, 0x6f, 0xe4, 0xea, 0xeb, 0xa2, 0x25, 0xfb, 0x29, 0x74, 0xac, + 0xdb, 0xf3, 0x69, 0xd3, 0xf2, 0x6c, 0x6e, 0x66, 0x3d, 0xd7, 0x35, 0xc5, 0x6e, 0xba, 0x74, 0xfd, + 0xe9, 0xdd, 0x70, 0x9f, 0x69, 0xb6, 0xeb, 0xf1, 0xfb, 0x76, 0xf5, 0x4c, 0xd7, 0x57, 0x88, 0x96, + 0xad, 0xfe, 0x27, 0x57, 0x97, 0x1d, 0xdf, 0xc2, 0x37, 0xbe, 0xe4, 0x87, 0x6e, 0xdf, 0x92, 0x93, + 0x93, 0xd5, 0xe1, 0x0c, 0x5a, 0x59, 0x7f, 0x1b, 0x92, 0x2f, 0x25, 0xee, 0xfe, 0x24, 0xef, 0x6e, + 0xab, 0xf8, 0x22, 0xa6, 0x5f, 0xa7, 0xf8, 0xba, 0x69, 0x97, 0xb2, 0x28, 0x9a, 0xcd, 0x0f, 0x7b, + 0xdf, 0xc4, 0x55, 0xa9, 0xb1, 0x2e, 0xd7, 0x82, 0x21, 0xc3, 0x35, 0x7d, 0x2b, 0xf0, 0x59, 0xba, + 0x53, 0x30, 0x5c, 0x61, 0xdb, 0xfb, 0x5f, 0x55, 0xc1, 0x81, 0xdb, 0xa4, 0xb6, 0x96, 0xad, 0xd5, + 0x7f, 0xcb, 0xce, 0xdf, 0x82, 0x4a, 0x5b, 0x71, 0x7c, 0xb2, 0xe7, 0xf8, 0xfa, 0x6d, 0xd2, 0xa4, + 0x38, 0xbf, 0x27, 0xf8, 0x8f, 0x3e, 0x35, 0xd2, 0xf0, 0x57, 0x7b, 0xee, 0xdd, 0xdf, 0x6f, 0x10, + 0xcb, 0x43, 0x52, 0x31, 0xe6, 0x22, 0x26, 0x36, 0xd7, 0xc1, 0x1f, 0x4d, 0x62, 0xfa, 0xe4, 0xab, + 0xc1, 0x17, 0x9b, 0x25, 0xf1, 0x74, 0xe9, 0x56, 0xdf, 0xcd, 0x4c, 0xf9, 0x6b, 0xc1, 0x0e, 0xaf, + 0x8b, 0xe6, 0xa6, 0xd7, 0xe2, 0x3a, 0x6f, 0x74, 0x9b, 0x5d, 0xe9, 0x5b, 0x7c, 0x15, 0x99, 0x84, + 0x5a, 0xb5, 0xa7, 0xa5, 0x2f, 0xe0, 0xf9, 0x79, 0x76, 0xf1, 0x15, 0xd0, 0xba, 0xf8, 0xcb, 0x7a, + 0xdc, 0xd9, 0x55, 0xed, 0x3b, 0x2a, 0xfe, 0x53, 0x5d, 0xdf, 0xc4, 0x4f, 0xfd, 0xbb, 0x78, 0x89, + 0x77, 0x4b, 0xe2, 0xe8, 0x6a, 0x87, 0xd5, 0x78, 0x90, 0x49, 0xdd, 0xde, 0xf8, 0x8d, 0x5b, 0x69, + 0xa6, 0xad, 0x7b, 0x2b, 0x4d, 0x7e, 0x4e, 0x68, 0xfc, 0x23, 0xa6, 0x95, 0xa2, 0xb0, 0x95, 0x50, + 0x69, 0x5f, 0xc2, 0x56, 0xed, 0x2a, 0xa6, 0xdf, 0xd1, 0x59, 0xf1, 0x5b, 0x76, 0xd2, 0x96, 0x7f, + 0x04, 0x73, 0x49, 0x26, 0x8f, 0x87, 0xbc, 0x48, 0x4b, 0x55, 0xd6, 0x9a, 0x0c, 0x88, 0x7c, 0xd5, + 0xbf, 0xc2, 0x25, 0xa6, 0xdd, 0x4d, 0x96, 0xae, 0xff, 0x12, 0x43, 0xed, 0x92, 0xc7, 0x70, 0xcb, + 0xf2, 0x52, 0xba, 0x4f, 0x10, 0xee, 0xff, 0xa1, 0x8e, 0xfa, 0x3e, 0xbe, 0x2e, 0xdd, 0x5f, 0x57, + 0xf0, 0xe5, 0x21, 0xb5, 0x7b, 0x7b, 0xb2, 0x7f, 0xf8, 0xbc, 0x5b, 0xa5, 0x6b, 0xe1, 0x3e, 0xa9, + 0xbe, 0xbe, 0x4b, 0x1a, 0x1d, 0x7c, 0x66, 0xd5, 0x23, 0xe3, 0x5d, 0xdd, 0x6c, 0x76, 0x36, 0xbc, + 0x15, 0xd0, 0xd7, 0x9b, 0x53, 0xdd, 0xfc, 0xdf, 0x05, 0xfb, 0x4b, 0x97, 0x12, 0x8d, 0x73, 0xf2, + 0xff, 0xf3, 0xd5, 0x37, 0xdb, 0xf2, 0x73, 0x53, 0xd4, 0x9c, 0xb7, 0xc8, 0xcf, 0x82, 0x3d, 0xa9, + 0xb6, 0xbe, 0x0a, 0xf4, 0xd3, 0xd0, 0xd3, 0x7b, 0x4d, 0x9b, 0xe5, 0xf3, 0x76, 0x87, 0x4d, 0xcb, + 0x82, 0x52, 0x67, 0xf9, 0xf1, 0xaf, 0x63, 0xe0, 0xb6, 0x58, 0x27, 0xae, 0x94, 0xbe, 0x2c, 0x4d, + 0x24, 0x92, 0x26, 0x93, 0x59, 0xac, 0xdf, 0x04, 0xc3, 0x2f, 0x22, 0x4a, 0xa4, 0xbe, 0xf9, 0x06, + 0xb5, 0x55, 0xf1, 0x15, 0xd5, 0x34, 0xff, 0x17, 0x74, 0xe9, 0xb4, 0xd6, 0xf9, 0x6d, 0x35, 0xf8, + 0x8b, 0xea, 0xfb, 0xae, 0x6d, 0xab, 0x5c, 0x49, 0xb7, 0x5f, 0x84, 0x2d, 0xed, 0xf3, 0xea, 0x6f, + 0xfc, 0x23, 0xe4, 0xe5, 0x64, 0x8c, 0x91, 0x86, 0x30, 0x6d, 0xdf, 0xbf, 0x11, 0xb6, 0xdc, 0xbe, + 0xff, 0x79, 0xa1, 0xf8, 0x4f, 0x61, 0xbb, 0x1a, 0xe9, 0xe2, 0x3f, 0x65, 0xb7, 0x6f, 0xc2, 0x54, + 0x1a, 0x6d, 0xb0, 0xd3, 0x6d, 0x36, 0xdf, 0x26, 0xad, 0x9b, 0xf8, 0xea, 0xaf, 0x0a, 0x70, 0xed, + 0x8b, 0xd5, 0x7c, 0x20, 0x23, 0xa2, 0x5d, 0xd2, 0xa7, 0x4d, 0x72, 0x12, 0xab, 0x27, 0x05, 0x25, + 0x6e, 0x96, 0x5e, 0x9c, 0x7a, 0x22, 0xec, 0xf5, 0xd7, 0xab, 0x82, 0x1b, 0x69, 0xd2, 0xea, 0xee, + 0xde, 0x9f, 0x9a, 0xef, 0x97, 0x82, 0x1d, 0xdd, 0xea, 0xb9, 0x69, 0xdf, 0xeb, 0x32, 0x4e, 0xed, + 0xed, 0xae, 0x0a, 0xa6, 0x93, 0xd5, 0x2b, 0x69, 0xcb, 0xe9, 0x91, 0xbe, 0x88, 0xff, 0x08, 0x15, + 0xad, 0x3e, 0x4d, 0x7d, 0xd7, 0x04, 0x62, 0x9e, 0xf9, 0xdf, 0x28, 0xf5, 0xaf, 0xdd, 0x6b, 0xf2, + 0xcd, 0xba, 0x7e, 0x59, 0xf1, 0xff, 0x11, 0xa6, 0xdd, 0x6b, 0x5d, 0x12, 0xab, 0x98, 0xad, 0x29, + 0x3f, 0xe1, 0x29, 0xfb, 0xb7, 0x7d, 0x7d, 0xeb, 0x6d, 0x72, 0x69, 0xaa, 0x7e, 0xcb, 0x37, 0x9b, + 0xf9, 0x69, 0xd5, 0xfd, 0xdb, 0x33, 0x07, 0xf2, 0x58, 0x81, 0x35, 0xc2, 0x02, 0xb9, 0x79, 0x7f, + 0xde, 0xdb, 0xc4, 0x31, 0x2e, 0xff, 0x8e, 0x25, 0xaa, 0xd2, 0xb4, 0xf4, 0x4d, 0x2e, 0x0b, 0x4c, + 0xe9, 0x6a, 0xb5, 0x9f, 0xec, 0xf7, 0x6e, 0xb8, 0xbb, 0xbe, 0xe9, 0x53, 0xf1, 0x17, 0x9e, 0x17, + 0xd2, 0x5c, 0x11, 0x93, 0x55, 0x63, 0xe2, 0xca, 0x7e, 0xa7, 0x67, 0x55, 0xfc, 0x74, 0xf9, 0xe9, + 0xa5, 0x6a, 0x7d, 0xfc, 0x26, 0x4a, 0xb7, 0xb5, 0x49, 0x70, 0x57, 0xcb, 0xa8, 0xe9, 0x37, 0x36, + 0xda, 0x47, 0xdf, 0x5a, 0xf8, 0x24, 0x2c, 0xfd, 0x0e, 0x8e, 0x0f, 0x82, 0xcb, 0x1c, 0xec, 0x24, + 0x5c, 0xdb, 0x1b, 0xeb, 0x5f, 0x04, 0xb4, 0x9c, 0xd9, 0xd3, 0x58, 0x01, 0xfe, 0x32, 0xe9, 0x29, + 0xf1, 0xb3, 0x6f, 0x26, 0x41, 0xca, 0xcd, 0x94, 0xcc, 0xf8, 0x9d, 0xd3, 0x3f, 0x4f, 0xda, 0xf1, + 0x36, 0x44, 0xc4, 0xfc, 0xcc, 0x37, 0xe3, 0xed, 0xa6, 0xda, 0x6d, 0x65, 0xe9, 0x6f, 0xf2, 0x8a, + 0xb5, 0x4f, 0xd9, 0x69, 0x25, 0xf2, 0xdd, 0xad, 0x72, 0x65, 0xcf, 0xc2, 0xb6, 0x98, 0xce, 0x63, + 0x5d, 0x35, 0x9f, 0xdb, 0xf2, 0x72, 0x89, 0x6d, 0x36, 0xd3, 0x7c, 0x22, 0x76, 0xd0, 0xdb, 0xd3, + 0x27, 0x63, 0x24, 0xfa, 0xd3, 0x5c, 0x7d, 0xbb, 0x76, 0x9a, 0xd2, 0xcf, 0x05, 0xca, 0x67, 0xbb, + 0xf9, 0x7a, 0x91, 0x8f, 0x67, 0xd5, 0xd7, 0x09, 0xdd, 0xbb, 0x6b, 0x5f, 0x8b, 0x31, 0xba, 0x7a, + 0x69, 0xa6, 0x9f, 0x94, 0xab, 0x37, 0xf9, 0x69, 0xea, 0xb9, 0x85, 0x3a, 0x7a, 0xe1, 0x2d, 0x6b, + 0xa4, 0x97, 0x82, 0xdf, 0x27, 0x77, 0xc9, 0x49, 0xc1, 0x38, 0x9a, 0x55, 0x5a, 0xd3, 0xfc, 0xa4, + 0xda, 0x6b, 0xc3, 0xc4, 0xdd, 0xe3, 0x74, 0xf5, 0x54, 0x85, 0x23, 0x2d, 0x65, 0xaf, 0xfa, 0x92, + 0xae, 0x51, 0x64, 0xef, 0x7f, 0x66, 0x97, 0x58, 0xea, 0xf0, 0x45, 0xaa, 0x6b, 0xaf, 0x82, 0x2b, + 0x1e, 0xb5, 0xe2, 0x30, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x02, 0x01, 0x30, 0x22, 0x97, 0x38, + 0x44, 0x75, 0x5d, 0xdd, 0xff, 0x12, 0x21, 0x18, 0x73, 0x1c, 0x78, 0x40, 0x23, 0xc4, 0x88, 0x0c, + 0x55, 0xa7, 0x68, 0xad, 0x6a, 0xa3, 0x63, 0x1c, 0x5b, 0x16, 0xff, 0xc3, 0x96, 0x9a, 0x69, 0xa6, + 0x7d, 0x34, 0xdb, 0x6f, 0xc2, 0xf4, 0xd3, 0x2f, 0x8d, 0x34, 0xd3, 0x4d, 0xf8, 0xb6, 0x2d, 0xe2, + 0xac, 0x55, 0xfa, 0x14, 0xc9, 0xf0, 0x8f, 0xfe, 0x2c, 0x2f, 0xb4, 0xd6, 0xd3, 0x46, 0xe8, 0x40, + 0xf2, 0x9f, 0xa8, 0x9d, 0x26, 0xe1, 0x9b, 0xba, 0xaa, 0xa6, 0x9a, 0x69, 0xfa, 0xe4, 0xb4, 0xd3, + 0x4d, 0x7b, 0xb4, 0xd3, 0x4d, 0x71, 0x1e, 0x24, 0x97, 0x75, 0x52, 0x61, 0x09, 0xb1, 0x0a, 0x3c, + 0xa4, 0xc4, 0xfc, 0x58, 0xc6, 0x9a, 0x68, 0xfb, 0x6a, 0xd7, 0x87, 0xea, 0xb5, 0xd2, 0x26, 0x69, + 0x24, 0xca, 0x69, 0xa6, 0x9f, 0xf8, 0x24, 0xbe, 0xf1, 0x71, 0x14, 0x26, 0xe7, 0x88, 0x65, 0x68, + 0xd9, 0xf8, 0x66, 0x78, 0x27, 0x4c, 0x62, 0x92, 0x6b, 0x37, 0xff, 0x0e, 0x04, 0x0d, 0xa6, 0xda, + 0xa0, 0x1f, 0xd1, 0x9f, 0xcd, 0xfc, 0x31, 0x16, 0xd6, 0xdb, 0x50, 0xd3, 0x29, 0x1f, 0x8c, 0x8a, + 0x29, 0xcb, 0xdd, 0xbc, 0xaf, 0x9c, 0x7f, 0x01, 0xdf, 0x6d, 0xb6, 0xdb, 0xf4, 0x5f, 0xfc, 0x11, + 0x4f, 0x87, 0xc3, 0x63, 0xb0, 0x04, 0x52, 0x61, 0x04, 0x42, 0xa2, 0xaf, 0x25, 0xdd, 0xdf, 0xd6, + 0x2f, 0xaf, 0x2a, 0xf5, 0x2a, 0xcf, 0x82, 0x3e, 0x35, 0xea, 0x8a, 0x9f, 0x39, 0x47, 0x6b, 0x4d, + 0x36, 0xdf, 0xfa, 0x95, 0x7f, 0x52, 0xaf, 0xeb, 0xdf, 0x52, 0xa7, 0xd4, 0xab, 0xf9, 0xe3, 0xb5, + 0xa6, 0x9b, 0x6f, 0xfd, 0x7b, 0xeb, 0xd7, 0xd7, 0x39, 0xf4, 0x3d, 0x3a, 0x27, 0x54, 0xeb, 0xd0, + 0xe4, 0xe9, 0x73, 0xc7, 0x95, 0x34, 0xd3, 0x4f, 0xfc, 0xf1, 0xe5, 0x4d, 0x34, 0xd3, 0xf2, 0x61, + 0x85, 0x4a, 0xb1, 0x1f, 0x9e, 0x3c, 0xa9, 0xa6, 0x9a, 0x7f, 0xe8, 0x9c, 0x8b, 0xd5, 0x22, 0xf5, + 0x48, 0xbd, 0x52, 0x2c, 0x48, 0x95, 0x63, 0xc4, 0xac, 0x5f, 0x05, 0x42, 0x24, 0xa6, 0xd5, 0x6e, + 0xee, 0xe5, 0x2f, 0x82, 0x52, 0xb5, 0x74, 0x89, 0x91, 0x63, 0x2a, 0xc7, 0xc1, 0x77, 0x89, 0x24, + 0x92, 0xdb, 0xc4, 0x2f, 0xcf, 0x12, 0xce, 0x9d, 0x37, 0x9d, 0xef, 0x85, 0x44, 0x69, 0x25, 0xd2, + 0xab, 0xd3, 0xcb, 0xff, 0xc1, 0x81, 0xad, 0x25, 0x1a, 0x9c, 0xf5, 0x32, 0xfe, 0xaf, 0x51, 0x9c, + 0xc3, 0x5a, 0x69, 0xa6, 0x97, 0x11, 0xb5, 0x69, 0xa6, 0x9a, 0x6a, 0x14, 0xcf, 0x14, 0x12, 0x09, + 0x04, 0x82, 0xd0, 0x48, 0x2f, 0xff, 0x58, 0xaa, 0x27, 0xc4, 0xe5, 0xeb, 0x17, 0xcf, 0x54, 0xd3, + 0x4d, 0x3f, 0xf3, 0xd5, 0x34, 0xd3, 0x4f, 0xfc, 0x2b, 0x7d, 0x5d, 0xf4, 0x05, 0xa6, 0x9a, 0x69, + 0xfa, 0xe7, 0x28, 0xe9, 0x3a, 0x6d, 0xb6, 0x9a, 0xf2, 0x73, 0xc7, 0xd4, 0xd3, 0x4d, 0x3f, 0xf5, + 0xaf, 0xad, 0x63, 0xd7, 0x54, 0x12, 0x0b, 0xff, 0x04, 0xf3, 0xf9, 0xfc, 0xdc, 0x5c, 0xdc, 0xbe, + 0xaf, 0xa2, 0x72, 0x2f, 0x52, 0xa7, 0xd7, 0xbc, 0x42, 0x91, 0x58, 0x71, 0x40, 0xe2, 0x8d, 0xae, + 0xdb, 0x7b, 0x6d, 0xff, 0x88, 0xe8, 0x41, 0x48, 0xba, 0x5d, 0xf6, 0xdb, 0xf1, 0xb5, 0x75, 0x75, + 0x57, 0x74, 0x92, 0x49, 0x25, 0x57, 0x75, 0xf6, 0xdb, 0x6d, 0xbe, 0x21, 0x11, 0x1a, 0xfd, 0x15, + 0xfc, 0x4d, 0x75, 0xd7, 0xc1, 0x55, 0x34, 0xe9, 0xd3, 0x37, 0x76, 0xad, 0xa9, 0x79, 0x13, 0xc4, + 0x02, 0xae, 0x3b, 0xeb, 0x76, 0xf7, 0x4e, 0x99, 0x93, 0xe1, 0xab, 0xab, 0xab, 0x2f, 0x6e, 0xff, + 0xe1, 0x5a, 0x4d, 0xe9, 0xa7, 0x68, 0xb2, 0xdc, 0xcc, 0x3b, 0x98, 0xff, 0x16, 0x31, 0x36, 0xa9, + 0x55, 0xeb, 0x9c, 0x26, 0x8f, 0x3e, 0x9a, 0x69, 0xa7, 0xe7, 0xa3, 0xcf, 0xa6, 0x9a, 0x69, 0xf9, + 0xe8, 0xf3, 0xe9, 0xa6, 0x9a, 0x7e, 0x88, 0x8e, 0x9f, 0x54, 0x76, 0x4e, 0x6b, 0xab, 0xaf, 0x82, + 0x81, 0xc4, 0xef, 0x46, 0x37, 0x44, 0x9b, 0x71, 0x25, 0xcd, 0x3e, 0xf8, 0x20, 0xd6, 0xa9, 0x72, + 0xa3, 0xa9, 0x0c, 0x5d, 0x8b, 0x86, 0x51, 0xb6, 0x8d, 0xc9, 0xcd, 0x45, 0xc3, 0x43, 0xf7, 0x74, + 0x46, 0x5f, 0x8a, 0xb6, 0xd7, 0x41, 0x14, 0x8b, 0x11, 0x41, 0x01, 0xb4, 0x45, 0xe0, 0x9a, 0xe7, + 0xa6, 0x7a, 0x7a, 0xf8, 0x23, 0xb4, 0xd2, 0xa9, 0x91, 0x17, 0xae, 0x5f, 0x05, 0x35, 0xdd, 0x57, + 0x77, 0x5e, 0x5f, 0x04, 0x96, 0x9a, 0x69, 0xa1, 0xe5, 0xf0, 0xc0, 0xa7, 0xdd, 0x31, 0xd8, 0xab, + 0x9c, 0xbf, 0xb9, 0xff, 0x82, 0x01, 0x19, 0xe6, 0xca, 0x33, 0x5d, 0x37, 0x49, 0xd2, 0xa6, 0xf9, + 0xcb, 0x1e, 0xf1, 0x37, 0xff, 0x04, 0xe4, 0xd9, 0x13, 0x43, 0xff, 0x53, 0x66, 0x7d, 0xf0, 0x41, + 0x67, 0x6d, 0xae, 0x34, 0xad, 0x91, 0x05, 0x2f, 0x54, 0x92, 0xbf, 0xfb, 0x0b, 0x9e, 0x5a, 0xca, + 0xa4, 0xd8, 0x89, 0xf1, 0x1f, 0x16, 0x46, 0x9a, 0x69, 0xa6, 0xad, 0x50, 0x78, 0x90, 0xb0, 0xb1, + 0x6e, 0xd3, 0x53, 0xeb, 0x55, 0x37, 0x6b, 0x3e, 0xe3, 0x15, 0x29, 0xa7, 0xff, 0x11, 0xe2, 0x64, + 0xe4, 0x2a, 0x74, 0xd8, 0xf1, 0x15, 0x47, 0x9c, 0x4f, 0xe0, 0x8e, 0x31, 0x4d, 0x45, 0x3d, 0x1e, + 0xf8, 0x22, 0x21, 0xfc, 0xfe, 0xcf, 0x87, 0x85, 0x29, 0x59, 0x5e, 0xad, 0xe9, 0x35, 0xfb, 0xea, + 0x6f, 0x6f, 0xca, 0x2c, 0x9e, 0x79, 0x2a, 0xc4, 0x57, 0x45, 0x16, 0x33, 0x89, 0x3a, 0x8f, 0x2f, + 0xa8, 0xda, 0x71, 0x10, 0xf0, 0x40, 0x96, 0xf4, 0x63, 0x5a, 0x19, 0x8a, 0x29, 0x14, 0xf2, 0xec, + 0x18, 0xe2, 0x63, 0xf7, 0xed, 0x4b, 0xbe, 0x36, 0xc8, 0xb6, 0xad, 0x2f, 0x8c, 0x1f, 0xe3, 0xf3, + 0x40, 0xd6, 0x8b, 0xdb, 0xc7, 0xf9, 0x1b, 0xa4, 0x0d, 0xd9, 0xe8, 0xb9, 0xcb, 0x7b, 0x7f, 0xfc, + 0x69, 0x05, 0xc7, 0x14, 0x43, 0x93, 0xc4, 0xf2, 0x4c, 0xa9, 0xce, 0x6f, 0x86, 0x75, 0x47, 0xac, + 0x87, 0x7d, 0xb3, 0x55, 0x39, 0xc4, 0x41, 0x19, 0xf8, 0xa3, 0x06, 0x2d, 0x7b, 0xe8, 0x6e, 0xb8, + 0x81, 0x3c, 0x40, 0x9f, 0x92, 0x7e, 0x81, 0xeb, 0x8a, 0x92, 0x8a, 0xd3, 0x4e, 0xed, 0x35, 0xe0, + 0x90, 0xdc, 0x28, 0xf9, 0xbe, 0x34, 0x42, 0xaf, 0x9b, 0x34, 0x4b, 0xfe, 0xf9, 0xdb, 0x4e, 0xa1, + 0x77, 0x9d, 0x9a, 0x8c, 0xd9, 0xb6, 0xdc, 0x36, 0x8f, 0xc2, 0x86, 0xc7, 0xf0, 0xfc, 0x2e, 0x37, + 0x26, 0x8c, 0xcb, 0x29, 0x33, 0x4a, 0x41, 0x7c, 0x15, 0x53, 0x34, 0x6f, 0x8a, 0x37, 0xd5, 0xd5, + 0x8f, 0x82, 0x9d, 0x25, 0xce, 0xab, 0xa3, 0x81, 0x87, 0xc3, 0xb1, 0xd3, 0x4d, 0x0d, 0x61, 0xc3, + 0x08, 0x1b, 0xd5, 0x3d, 0xf2, 0xd4, 0xc2, 0x57, 0xe4, 0xef, 0xfa, 0x0b, 0x8b, 0xc3, 0x0f, 0xad, + 0x57, 0x57, 0xf0, 0x8c, 0xdc, 0x14, 0x77, 0x7d, 0xdc, 0x79, 0x57, 0x08, 0xd6, 0x4a, 0x5d, 0xc9, + 0x46, 0x53, 0x75, 0x5f, 0x44, 0xe6, 0x5e, 0x15, 0xe6, 0xc6, 0xb6, 0x9a, 0x4c, 0x93, 0x4d, 0x34, + 0xff, 0xcf, 0x7a, 0x69, 0xa6, 0x9f, 0xfa, 0x2f, 0x32, 0xe2, 0x17, 0x2e, 0x10, 0xc9, 0xcd, 0x57, + 0x57, 0xe2, 0x05, 0xc9, 0x42, 0x53, 0x92, 0x84, 0xa7, 0xe2, 0x48, 0xe9, 0xe9, 0xd3, 0xf9, 0xeb, + 0xe9, 0xa6, 0x9a, 0x7e, 0x79, 0x17, 0x77, 0x77, 0xff, 0x04, 0xb5, 0x26, 0xf5, 0xa7, 0x4e, 0x6f, + 0x85, 0x84, 0x57, 0x64, 0xf2, 0x7b, 0xb1, 0x2f, 0xa7, 0xf2, 0xf4, 0x2e, 0xbc, 0x44, 0xbc, 0x2a, + 0x39, 0x27, 0xe6, 0x68, 0xea, 0x18, 0xda, 0x56, 0x45, 0xf7, 0x0c, 0xc5, 0xc7, 0xb8, 0xaf, 0xf1, + 0xb5, 0x52, 0xdb, 0xc2, 0xb5, 0xdc, 0xce, 0xa4, 0x84, 0x4f, 0x97, 0xe8, 0x7e, 0xb4, 0xdb, 0x6a, + 0xf0, 0x59, 0x0c, 0x6d, 0x72, 0x29, 0xec, 0xfe, 0x65, 0x26, 0xa6, 0x22, 0x14, 0xbb, 0x09, 0x5b, + 0x05, 0xee, 0xc3, 0x81, 0xc7, 0x5b, 0xc4, 0xa3, 0x73, 0x1b, 0xa6, 0xec, 0x5f, 0xe5, 0x3f, 0x83, + 0xb3, 0x71, 0x30, 0x4c, 0x4d, 0xd9, 0x67, 0x69, 0xb1, 0x3a, 0x63, 0xd2, 0xc4, 0xfe, 0x37, 0x1a, + 0xc5, 0x51, 0xdc, 0xc6, 0xce, 0xe8, 0x99, 0x85, 0x2a, 0x3f, 0x5d, 0x27, 0x46, 0x28, 0xd3, 0x52, + 0x71, 0x8e, 0x4f, 0xff, 0x0a, 0x5d, 0x2a, 0x71, 0xdd, 0x35, 0x12, 0x8d, 0x18, 0xd2, 0x3e, 0xd2, + 0xae, 0xab, 0xaf, 0x82, 0x91, 0x6e, 0x8b, 0x2a, 0xd4, 0xf0, 0xe7, 0xdd, 0x56, 0x7f, 0x82, 0x01, + 0x95, 0x8d, 0xe7, 0x6e, 0xd5, 0x49, 0xa9, 0x6b, 0x94, 0xe3, 0xed, 0xb9, 0x3f, 0x82, 0xbb, 0x0d, + 0x67, 0x5d, 0x55, 0x55, 0x57, 0x02, 0xd3, 0xd8, 0x5d, 0xa6, 0x9a, 0x6b, 0xd5, 0x1d, 0x3e, 0xad, + 0x5d, 0x62, 0xfa, 0xc5, 0x5d, 0x78, 0xef, 0xc1, 0x3d, 0xa6, 0x9a, 0x6b, 0x55, 0x8b, 0x0e, 0x22, + 0x00, 0x87, 0xfc, 0xfc, 0xff, 0x4d, 0x3d, 0x84, 0xc2, 0x6d, 0xb1, 0x3a, 0x53, 0x4f, 0xdb, 0x6f, + 0xd6, 0x8e, 0xfd, 0x51, 0xaa, 0x51, 0x12, 0x5a, 0x9b, 0x2f, 0x86, 0x2d, 0x34, 0xd3, 0x4d, 0x34, + 0xd3, 0x5d, 0xf4, 0xd3, 0x4d, 0x3f, 0x5e, 0x9b, 0xaa, 0x37, 0xf2, 0xd3, 0x4d, 0x34, 0xf8, 0x93, + 0xe2, 0xbb, 0xbb, 0xff, 0x82, 0x22, 0xbb, 0x4e, 0xd1, 0xf7, 0xc1, 0x09, 0x1a, 0xb4, 0xd3, 0x3e, + 0x09, 0xfc, 0xb8, 0x9e, 0x9e, 0x23, 0x6b, 0xcc, 0x22, 0xea, 0xbe, 0x09, 0x45, 0xbb, 0xbb, 0x9e, + 0x87, 0xa5, 0xfd, 0xf1, 0x77, 0x72, 0xd1, 0xb4, 0x77, 0x6d, 0x1b, 0x4f, 0x51, 0x1d, 0x2f, 0x97, + 0xbb, 0xac, 0x45, 0x62, 0x7c, 0x47, 0xc3, 0xc1, 0x0a, 0xac, 0xf3, 0xcc, 0xc8, 0x3b, 0xf8, 0x5d, + 0xcb, 0x1a, 0xf1, 0xae, 0xbc, 0x77, 0xbc, 0x66, 0x74, 0x94, 0xd9, 0x7f, 0x4e, 0x58, 0x19, 0x0f, + 0x5f, 0x0a, 0x57, 0xe3, 0x26, 0x72, 0x24, 0x73, 0x0d, 0x17, 0x59, 0xbf, 0x83, 0x4b, 0x54, 0x9d, + 0xc4, 0x79, 0xdd, 0xdc, 0x5d, 0x87, 0x82, 0xc1, 0x3a, 0xad, 0x49, 0xe7, 0x55, 0x72, 0x4e, 0x08, + 0x0d, 0x8e, 0x1c, 0x56, 0x57, 0x59, 0xf7, 0x5f, 0x63, 0x17, 0xbf, 0x3f, 0xb7, 0xe1, 0x43, 0x65, + 0xc5, 0x2a, 0xe6, 0x76, 0x4d, 0x25, 0x3c, 0x7a, 0xed, 0xa9, 0x56, 0x7c, 0x50, 0xf5, 0xb6, 0x6e, + 0xdd, 0x76, 0xfc, 0x22, 0x6a, 0xae, 0xab, 0x91, 0xec, 0x9e, 0xab, 0xc1, 0x48, 0x85, 0xc6, 0x26, + 0xd9, 0x2b, 0xb2, 0x5a, 0x9a, 0xe7, 0x2f, 0xa0, 0xb9, 0xd3, 0xe0, 0x8e, 0xee, 0xaa, 0xff, 0x53, + 0xa2, 0xaf, 0x0a, 0x9d, 0xa6, 0xb6, 0x9a, 0xd1, 0xcf, 0xdb, 0x6d, 0xb6, 0xd7, 0x44, 0x7f, 0xa2, + 0x39, 0xf5, 0x47, 0x66, 0xc4, 0x97, 0x25, 0x11, 0xb2, 0x98, 0x8c, 0x81, 0xe2, 0x40, 0x6b, 0x68, + 0xcd, 0xbf, 0xff, 0x8a, 0xea, 0x7f, 0xd4, 0x20, 0x24, 0x5d, 0x24, 0xb2, 0x67, 0xf2, 0xd2, 0x4a, + 0x92, 0xe8, 0xa0, 0x34, 0x06, 0xfa, 0x25, 0x62, 0xc9, 0x0f, 0x78, 0xe8, 0x9f, 0x39, 0x4a, 0x94, + 0xd6, 0x5f, 0xfc, 0x49, 0x84, 0x6a, 0xbe, 0x27, 0xc6, 0xda, 0x2d, 0x81, 0x8d, 0x57, 0xe0, 0x8f, + 0x3e, 0xd8, 0xbc, 0x7c, 0x10, 0x91, 0xa4, 0xd7, 0x24, 0x7e, 0x0a, 0xf6, 0x9f, 0xaa, 0x8f, 0xe9, + 0xd5, 0x73, 0xe7, 0xcc, 0x73, 0xe3, 0xff, 0x86, 0x0f, 0xb4, 0xd6, 0xd3, 0x4a, 0x9a, 0x69, 0xa7, + 0xfe, 0x18, 0xed, 0x35, 0xb4, 0xd2, 0xa6, 0x9a, 0x69, 0xff, 0x86, 0x3b, 0x4d, 0x6d, 0x34, 0xa9, + 0xa6, 0x9a, 0x7f, 0xe0, 0xa3, 0xb4, 0xd6, 0xd3, 0x43, 0xb5, 0x07, 0xb0, 0x59, 0xe4, 0x61, 0x6c, + 0x2d, 0x84, 0xc2, 0xd8, 0x4c, 0x2f, 0x04, 0x0c, 0x0e, 0xf2, 0x69, 0xa6, 0x9b, 0x6d, 0xb6, 0xdc, + 0x38, 0x49, 0x87, 0xbf, 0xff, 0x41, 0x20, 0xb8, 0xd5, 0x68, 0x2e, 0xc2, 0x61, 0x78, 0x26, 0xa4, + 0x97, 0xa4, 0x95, 0x7c, 0x14, 0x72, 0xe1, 0x73, 0x2e, 0x17, 0x3b, 0xe0, 0x97, 0xaa, 0xea, 0xaf, + 0xf0, 0xa0, 0x40, 0xbd, 0xa9, 0x30, 0xfa, 0x84, 0xdf, 0xce, 0x69, 0xb6, 0x98, 0x78, 0x68, 0x54, + 0x38, 0xa7, 0x3e, 0x14, 0xb3, 0xb8, 0xb8, 0x97, 0x05, 0x6d, 0xef, 0x4e, 0xbc, 0x56, 0x9b, 0x9e, + 0xf1, 0x21, 0x09, 0xcb, 0x1d, 0x9d, 0x24, 0xf9, 0x3c, 0x2a, 0xdf, 0xc1, 0x38, 0x57, 0x1e, 0xf2, + 0xef, 0x78, 0xf7, 0x97, 0x79, 0xfe, 0x11, 0x9e, 0x9c, 0xf4, 0xf6, 0xaf, 0xf0, 0x48, 0x6b, 0x4a, + 0xd7, 0xfe, 0x14, 0x08, 0x5b, 0x9a, 0x5a, 0x9e, 0x0a, 0xc6, 0x93, 0x7e, 0x9b, 0xce, 0x3c, 0x48, + 0x91, 0xb3, 0x1c, 0x1c, 0x68, 0xca, 0x39, 0xf8, 0x46, 0xde, 0x6f, 0x36, 0x2a, 0xe5, 0x43, 0x6c, + 0x5d, 0x8f, 0x2b, 0xe0, 0xbc, 0x54, 0xd7, 0x8c, 0x6d, 0xa2, 0x14, 0xcd, 0x56, 0x72, 0xfd, 0x32, + 0x7f, 0xc1, 0x08, 0x55, 0x7c, 0xcf, 0xbc, 0x8e, 0xc9, 0xce, 0x71, 0xe5, 0x4d, 0x34, 0xd3, 0xf7, + 0x89, 0x57, 0xf1, 0x3e, 0x11, 0x31, 0x32, 0x50, 0x94, 0x11, 0xc5, 0x17, 0x97, 0x39, 0x71, 0xf4, + 0x23, 0x2a, 0xef, 0xbb, 0xf8, 0x24, 0x29, 0xf2, 0x6c, 0x17, 0x67, 0xc3, 0x17, 0x71, 0xc6, 0x8e, + 0xa6, 0xc7, 0x64, 0x8b, 0x7f, 0x9b, 0x53, 0xf0, 0x47, 0x51, 0x7f, 0xaf, 0x82, 0x51, 0x0d, 0x34, + 0xd3, 0x5b, 0x4d, 0x38, 0xf2, 0x4b, 0x8a, 0xeb, 0xec, 0xb3, 0xd1, 0x9f, 0xea, 0xe7, 0xcf, 0x5f, + 0x4d, 0x34, 0xd3, 0xf5, 0x6f, 0x94, 0xaa, 0xe4, 0xf1, 0xfa, 0x26, 0x37, 0xc2, 0xc4, 0x6a, 0x6d, + 0x75, 0x3e, 0x2d, 0x5d, 0xf5, 0x4d, 0x35, 0x5d, 0x1e, 0x39, 0xf0, 0x47, 0x5a, 0xfe, 0x5f, 0x58, + 0xbc, 0x45, 0x72, 0xda, 0x69, 0xa6, 0xb1, 0x22, 0x48, 0x4d, 0xb2, 0x7f, 0xc2, 0x82, 0xb7, 0x11, + 0xea, 0xab, 0x44, 0x64, 0x8d, 0x7c, 0xdc, 0x63, 0x37, 0x73, 0x2f, 0x4b, 0x1e, 0x8a, 0xcf, 0x0a, + 0x12, 0x2b, 0xce, 0x92, 0xf3, 0x57, 0x37, 0x15, 0x88, 0x68, 0x5b, 0x25, 0x6e, 0x25, 0x07, 0xc1, + 0x51, 0xf5, 0x54, 0x90, 0xcd, 0x8f, 0x61, 0xb6, 0x69, 0xe4, 0xdc, 0xf7, 0xc1, 0x59, 0xa0, 0x5c, + 0xd1, 0x6d, 0x8f, 0x89, 0xef, 0x37, 0xcf, 0x5f, 0x18, 0x55, 0xcd, 0xf9, 0xf5, 0x74, 0x87, 0x96, + 0xd5, 0x08, 0x79, 0xdb, 0xc1, 0x49, 0xba, 0xa9, 0xf3, 0xbb, 0x64, 0xde, 0x71, 0x81, 0xf8, 0x80, + 0xfb, 0x4d, 0x6d, 0x35, 0xac, 0x40, 0x6c, 0x24, 0x7d, 0x74, 0xcf, 0xa5, 0xad, 0xd5, 0x7d, 0x70, + 0xfd, 0xab, 0x5b, 0xbb, 0xba, 0xad, 0x53, 0xbb, 0xff, 0x10, 0x61, 0x6c, 0xf5, 0xf0, 0x85, 0xdd, + 0x55, 0xa6, 0xb7, 0x75, 0x5e, 0x23, 0xea, 0x38, 0xde, 0x20, 0x97, 0x7c, 0xa1, 0xa4, 0x13, 0x01, + 0x2e, 0x02, 0x83, 0x3f, 0x8f, 0xc4, 0x48, 0x49, 0xa4, 0xdf, 0xe3, 0x80, 0x01, 0x1b, 0xe0, 0x90, + 0x20, 0xee, 0xaa, 0x3a, 0x5f, 0x31, 0x8f, 0x8d, 0x34, 0xd7, 0x86, 0xa6, 0xc3, 0x65, 0xa7, 0x7d, + 0x34, 0xd3, 0x4f, 0xc1, 0x0c, 0xd8, 0xd7, 0xe2, 0xd7, 0xe0, 0xb8, 0xba, 0xb4, 0x8d, 0xa4, 0x92, + 0x49, 0xbe, 0x16, 0xb5, 0x55, 0x49, 0x2b, 0xaf, 0xa6, 0x9b, 0x6d, 0xf9, 0xeb, 0xed, 0xb6, 0xdb, + 0x7e, 0x09, 0x79, 0x70, 0xb9, 0xa4, 0x93, 0x7c, 0x2b, 0xd2, 0x4b, 0x49, 0x25, 0xf6, 0xdb, 0x6d, + 0xbf, 0x1b, 0x69, 0xae, 0xe4, 0xc6, 0xe2, 0xab, 0xbc, 0xcb, 0xba, 0xfb, 0x6d, 0xb6, 0xdf, 0x11, + 0x5c, 0x15, 0xf4, 0xd3, 0x74, 0xf5, 0x75, 0x72, 0xe7, 0xd9, 0x49, 0x84, 0xc2, 0xe3, 0x73, 0xc3, + 0x64, 0x75, 0x75, 0x54, 0xd3, 0x6d, 0xbf, 0xf3, 0x98, 0xc9, 0xf6, 0xdc, 0xdf, 0xf1, 0x05, 0x69, + 0xa6, 0x9a, 0x69, 0xa6, 0x9a, 0xe2, 0x2f, 0xa2, 0x99, 0x2f, 0x82, 0x28, 0xff, 0x97, 0xfb, 0xe2, + 0xf1, 0x00, 0xb0, 0x53, 0xcd, 0xf4, 0x57, 0x84, 0x6a, 0x2f, 0x87, 0x88, 0x05, 0x22, 0x25, 0xe6, + 0xd6, 0x65, 0x18, 0xe5, 0x44, 0xad, 0xca, 0xaa, 0xea, 0xe7, 0xc6, 0xea, 0x7e, 0x3e, 0xb5, 0x66, + 0xc4, 0x38, 0x76, 0x07, 0x55, 0x15, 0xd6, 0x4c, 0xb1, 0x2c, 0x5a, 0x8b, 0x57, 0x2f, 0xa7, 0xfe, + 0x10, 0x85, 0xf0, 0x8d, 0x31, 0x73, 0x4a, 0x63, 0xf5, 0x65, 0xbf, 0x66, 0x79, 0x07, 0xab, 0x22, + 0xfc, 0x29, 0x5c, 0xd4, 0xc1, 0xdb, 0x05, 0x56, 0x94, 0x9e, 0xb1, 0x1b, 0x74, 0x77, 0xf8, 0x29, + 0x24, 0xdc, 0xd9, 0x15, 0x59, 0xb1, 0xcb, 0xc6, 0x17, 0xd7, 0xc1, 0x61, 0xd4, 0xdd, 0x39, 0xad, + 0xb6, 0x91, 0x43, 0xd8, 0x70, 0x7f, 0xf0, 0x4c, 0x23, 0x6f, 0xd1, 0x23, 0x7e, 0x49, 0xaf, 0xa0, + 0xca, 0x01, 0xf8, 0x99, 0x38, 0x24, 0x23, 0x4d, 0x34, 0xd7, 0x7c, 0x61, 0xb5, 0x55, 0x5a, 0x9f, + 0x1d, 0x8f, 0xca, 0xb5, 0x5f, 0x05, 0x1d, 0x24, 0xb4, 0x8b, 0x8d, 0xf0, 0x59, 0xb0, 0xc3, 0xdb, + 0xba, 0xad, 0xa6, 0xab, 0x9b, 0x32, 0xac, 0x42, 0x3b, 0xbf, 0xe2, 0x47, 0x92, 0xeb, 0xd4, 0x5e, + 0xb5, 0x78, 0x8f, 0x13, 0x37, 0x04, 0x45, 0x69, 0xa3, 0x65, 0x5f, 0xf8, 0x21, 0xb4, 0xd3, 0x4d, + 0x3f, 0x88, 0x57, 0xf8, 0x64, 0xe4, 0xc2, 0x66, 0x64, 0x3a, 0x32, 0xe9, 0x77, 0xfd, 0x5f, 0xe7, + 0x8f, 0x3d, 0x34, 0xd3, 0x4f, 0xfd, 0x12, 0x39, 0xf0, 0xc7, 0x55, 0xd5, 0x40, 0x68, 0x07, 0xf6, + 0xdb, 0x6d, 0xbf, 0x45, 0x62, 0xf8, 0x27, 0x32, 0x74, 0xd5, 0xba, 0xdf, 0xc4, 0x2f, 0x71, 0x3b, + 0xe8, 0xa4, 0x4a, 0xeb, 0x5f, 0x52, 0x27, 0x88, 0xae, 0xa4, 0x4f, 0x86, 0x8d, 0xa9, 0xa9, 0x17, + 0x52, 0x7f, 0xf1, 0x82, 0x99, 0x15, 0x9b, 0x7a, 0x4b, 0xd4, 0x94, 0xd0, 0x93, 0xc6, 0xf7, 0xf1, + 0x32, 0x6c, 0x71, 0x97, 0xa5, 0xb7, 0xf0, 0x41, 0x63, 0x7d, 0x6d, 0x2b, 0x7b, 0x75, 0x49, 0x5b, + 0x6d, 0xb6, 0xff, 0xc6, 0xe6, 0x93, 0x28, 0xa2, 0x88, 0x4c, 0xb3, 0x55, 0x93, 0x3a, 0x49, 0x3a, + 0xdb, 0x6d, 0xb7, 0xf8, 0x88, 0xd2, 0xec, 0xc7, 0x38, 0x75, 0x3e, 0x2d, 0x49, 0x8c, 0xde, 0xb4, + 0xaa, 0xdb, 0x6d, 0xb7, 0xfe, 0x36, 0x36, 0xb4, 0xa4, 0xbd, 0x30, 0xdb, 0xb8, 0x7c, 0x22, 0x3c, + 0x9a, 0xc9, 0x7d, 0x4f, 0xfb, 0x98, 0x24, 0x55, 0xb6, 0xdb, 0x6f, 0xfc, 0x14, 0x8c, 0x3d, 0xef, + 0xfb, 0x99, 0x1d, 0x5c, 0xd0, 0x99, 0x2e, 0xd7, 0xc4, 0x85, 0x6a, 0x68, 0xd9, 0x53, 0xea, 0x6e, + 0x17, 0x21, 0xfd, 0x5d, 0x5d, 0x72, 0xc9, 0xd3, 0x67, 0xff, 0x0c, 0x9d, 0x77, 0xaa, 0xe9, 0xbf, + 0x2c, 0x25, 0x86, 0x27, 0xf0, 0x41, 0x6e, 0xbe, 0x35, 0x44, 0xf7, 0x8a, 0x23, 0xbf, 0xd6, 0x25, + 0x14, 0x03, 0x80, 0x1f, 0x51, 0x8a, 0x7d, 0x1b, 0xab, 0x9f, 0xd4, 0xe5, 0xee, 0xdc, 0xdd, 0x7d, + 0x16, 0x3c, 0xc2, 0xd0, 0x46, 0x38, 0x00, 0x11, 0xab, 0x9c, 0x50, 0xf5, 0x55, 0x55, 0xf8, 0xb6, + 0x2e, 0x38, 0x00, 0x11, 0xbc, 0x4f, 0xce, 0x39, 0x1d, 0x3e, 0xdb, 0x6d, 0xb6, 0x6e, 0x1a, 0x22, + 0x49, 0x24, 0x92, 0xfb, 0x6d, 0xb6, 0xda, 0xe7, 0x2b, 0x9f, 0x93, 0xd7, 0xce, 0x65, 0x77, 0x77, + 0xfc, 0x47, 0xe7, 0x8f, 0x32, 0xee, 0xef, 0xeb, 0x82, 0x82, 0xbb, 0xee, 0xf8, 0xb1, 0x80, 0xdf, + 0x04, 0x64, 0xd5, 0x47, 0x6e, 0x22, 0x7f, 0x53, 0x4d, 0x34, 0xff, 0xd7, 0x5f, 0x47, 0x01, 0xaa, + 0xe0, 0x9c, 0x20, 0xda, 0x1c, 0x6e, 0xe1, 0xd9, 0x39, 0x50, 0xdb, 0x54, 0x7f, 0xe1, 0x43, 0x24, + 0xdc, 0x8a, 0x35, 0x98, 0xe5, 0xbc, 0x21, 0xdb, 0x42, 0x37, 0xb6, 0x7e, 0x14, 0x58, 0x8d, 0xf0, + 0x56, 0x55, 0x27, 0x5d, 0xab, 0xb4, 0x46, 0x0f, 0xe1, 0x6e, 0x7c, 0x16, 0xd2, 0x6d, 0xe9, 0xbb, + 0x69, 0x11, 0x1d, 0x78, 0x2b, 0xf2, 0x62, 0x59, 0x7b, 0xa4, 0x0f, 0xb0, 0x9b, 0xb9, 0xf0, 0x51, + 0x26, 0x7d, 0x10, 0xf7, 0x9c, 0xf8, 0xc3, 0xb9, 0x61, 0x65, 0xb4, 0x59, 0x6d, 0xed, 0xbb, 0x4d, + 0xb5, 0xe1, 0x11, 0x82, 0x79, 0x1a, 0x38, 0x2c, 0xb9, 0xa6, 0x9b, 0xb9, 0xfc, 0x63, 0x0a, 0xaf, + 0x78, 0xe1, 0x6a, 0xbd, 0x55, 0x54, 0xd9, 0x85, 0x7c, 0xe2, 0x55, 0x34, 0xd3, 0x11, 0x33, 0xeb, + 0xa9, 0xd2, 0xb8, 0x5f, 0x4e, 0x9d, 0x3a, 0x6b, 0xef, 0x6e, 0xf8, 0x8b, 0x2a, 0xef, 0xe0, 0x8e, + 0xdb, 0x6d, 0xb6, 0xff, 0x56, 0xfa, 0xeb, 0xe6, 0x22, 0x65, 0xff, 0xb2, 0xa6, 0x9a, 0x69, 0xae, + 0xbd, 0x5c, 0xf0, 0x42, 0x56, 0x9a, 0x36, 0xbb, 0x7f, 0xd6, 0x91, 0x7a, 0x9d, 0x5f, 0x46, 0x8b, + 0xc4, 0xa8, 0xe3, 0x7c, 0xe2, 0x47, 0x90, 0x16, 0x9a, 0x69, 0xa7, 0xe5, 0xe8, 0x80, 0x1c, 0x5c, + 0x2e, 0x08, 0x64, 0xc1, 0x8f, 0x74, 0xe9, 0x72, 0x14, 0x98, 0x4c, 0x2e, 0x37, 0x3d, 0x91, 0x24, + 0xa2, 0x4b, 0xd1, 0xd3, 0xb5, 0xce, 0x65, 0x9f, 0x9f, 0xff, 0xea, 0x89, 0x7f, 0x57, 0x1e, 0x72, + 0x71, 0x8a, 0x4d, 0x34, 0xd3, 0xfc, 0x4c, 0x10, 0xf7, 0x71, 0xdb, 0xe2, 0x26, 0xc3, 0x61, 0x28, + 0xca, 0x34, 0xd4, 0x34, 0x7e, 0x08, 0xad, 0x0f, 0x2e, 0x73, 0x7c, 0xdd, 0xdf, 0xcf, 0xeb, 0xbb, + 0xbf, 0xbe, 0x08, 0x85, 0x19, 0x95, 0x29, 0x93, 0x32, 0xa5, 0x33, 0x87, 0xc6, 0x92, 0xca, 0xc6, + 0x33, 0x72, 0x8e, 0xfd, 0x07, 0xf7, 0x7b, 0x5f, 0x23, 0x3e, 0x7b, 0xdf, 0x3e, 0x99, 0xb4, 0xc2, + 0x7d, 0xc3, 0xe6, 0xde, 0x1a, 0x2e, 0xba, 0x73, 0xff, 0xf1, 0xbc, 0x3b, 0x96, 0x77, 0x63, 0x75, + 0x86, 0xc6, 0xb0, 0x3e, 0x59, 0xcb, 0x02, 0x64, 0x47, 0x3e, 0xb5, 0xe9, 0xae, 0xe3, 0x07, 0x20, + 0xa7, 0xe6, 0xdc, 0xfd, 0x5d, 0x7c, 0x16, 0xd2, 0x26, 0xb5, 0xb4, 0x19, 0x56, 0x27, 0x9d, 0x98, + 0xf8, 0x52, 0xdf, 0xb6, 0x4c, 0x9b, 0xc9, 0x8f, 0xd2, 0x52, 0x38, 0xd4, 0xe3, 0x01, 0x72, 0x8d, + 0x2b, 0x20, 0x89, 0x16, 0x5f, 0x19, 0xd5, 0x34, 0xdf, 0xe6, 0xd6, 0x7b, 0x22, 0xeb, 0x6d, 0xae, + 0xa5, 0xe6, 0x3f, 0x6a, 0xf0, 0x81, 0xe5, 0x2a, 0x18, 0xc4, 0x63, 0xea, 0x0d, 0x8a, 0x68, 0x9e, + 0x7e, 0x3e, 0x58, 0xc6, 0x6d, 0x6f, 0x6e, 0x99, 0x6e, 0xaa, 0x92, 0xba, 0x34, 0x36, 0x3f, 0x08, + 0x08, 0x5c, 0x70, 0xae, 0xb5, 0x8d, 0x65, 0x3a, 0xc7, 0x16, 0xeb, 0xa0, 0xad, 0x7d, 0x4a, 0x0a, + 0xe2, 0xe9, 0x24, 0x92, 0x5a, 0x49, 0x78, 0x72, 0x9a, 0x74, 0xd7, 0xdd, 0xdd, 0xfc, 0x2d, 0x49, + 0x2d, 0xdf, 0x5f, 0x6d, 0xb6, 0xdb, 0x51, 0x10, 0x51, 0xab, 0xe5, 0x62, 0xef, 0x5c, 0xe2, 0x52, + 0x2f, 0x18, 0x97, 0x1f, 0xc4, 0xd0, 0x84, 0xdf, 0x38, 0x4d, 0x22, 0xf2, 0xe9, 0x77, 0x37, 0x38, + 0x48, 0xab, 0x93, 0x49, 0xbf, 0xe1, 0x8a, 0xf1, 0xc7, 0xc4, 0x02, 0x1a, 0xa9, 0x18, 0x94, 0x77, + 0xea, 0x63, 0x1f, 0x3d, 0x7d, 0xb6, 0xdb, 0x6d, 0x74, 0x5a, 0xae, 0xa0, 0x2c, 0x05, 0xf9, 0x48, + 0xd3, 0x56, 0x96, 0x26, 0x4e, 0x52, 0x55, 0xb5, 0xf0, 0x49, 0xe2, 0xb6, 0x38, 0x88, 0x23, 0xbb, + 0xf5, 0xf0, 0xde, 0x4c, 0xd5, 0x55, 0x3f, 0xf9, 0x0e, 0x92, 0x49, 0x24, 0xf0, 0x87, 0x11, 0x04, + 0x3c, 0xcc, 0x51, 0xd7, 0xd6, 0xdf, 0x51, 0xf0, 0x09, 0xf4, 0x5c, 0xbe, 0x09, 0xc2, 0x8d, 0xe5, + 0xc8, 0x65, 0xd3, 0x69, 0x78, 0xc1, 0x97, 0xc6, 0x99, 0xa3, 0x66, 0x87, 0xe1, 0x2a, 0x8b, 0x28, + 0x12, 0xb1, 0x2f, 0x72, 0x67, 0x19, 0xa5, 0xe9, 0xf2, 0x8c, 0x47, 0xfa, 0x4b, 0x72, 0x9a, 0x63, + 0xcd, 0xaf, 0xcb, 0x04, 0xdf, 0xfc, 0x64, 0x25, 0xb5, 0x96, 0xd2, 0x76, 0x4e, 0x8a, 0xca, 0x68, + 0x9d, 0xe2, 0x78, 0xeb, 0x7d, 0x65, 0xcd, 0xce, 0xfd, 0x1b, 0x0c, 0x31, 0xc8, 0xaf, 0xde, 0x48, + 0xfe, 0xdc, 0x8f, 0x59, 0x1f, 0x9a, 0x5c, 0x40, 0x2e, 0xbb, 0x1d, 0x8f, 0x3f, 0x4e, 0xe7, 0xc7, + 0xdc, 0xa1, 0xb9, 0xc3, 0x4a, 0x3a, 0xc1, 0x78, 0x3a, 0xe4, 0x29, 0xa5, 0x09, 0xd4, 0xf6, 0x23, + 0x9b, 0x7c, 0x6e, 0x06, 0x26, 0x67, 0xe9, 0xc5, 0xae, 0xfc, 0x29, 0x33, 0xfb, 0x7a, 0xd0, 0xe8, + 0x4e, 0xbc, 0x6b, 0x31, 0xd5, 0x19, 0x75, 0x2d, 0xa2, 0x48, 0xdb, 0x64, 0xbf, 0x36, 0x25, 0xf7, + 0xc4, 0x09, 0xa5, 0x09, 0x6d, 0x5b, 0x7b, 0xf8, 0x48, 0xad, 0x9e, 0x5a, 0xd8, 0xfe, 0x3c, 0x65, + 0x6a, 0x2f, 0x1a, 0xa0, 0x59, 0x96, 0xc4, 0xcb, 0x7f, 0x29, 0x47, 0x4f, 0xab, 0x25, 0xca, 0x74, + 0x7c, 0xe1, 0x11, 0xcd, 0x44, 0x2e, 0x88, 0x5f, 0xfd, 0x45, 0x88, 0x05, 0xfa, 0x91, 0x91, 0xac, + 0x42, 0x9d, 0x67, 0x08, 0x88, 0xae, 0xad, 0x71, 0x15, 0x46, 0xb1, 0x3c, 0xe5, 0x01, 0xa0, 0x27, + 0xd3, 0x4d, 0x34, 0xe3, 0xc8, 0x3e, 0x21, 0x28, 0x62, 0xe8, 0xd5, 0xcd, 0x55, 0xcc, 0x16, 0x71, + 0x21, 0xab, 0xe5, 0xfc, 0xb1, 0x08, 0x21, 0x97, 0xc5, 0x99, 0x53, 0x51, 0x84, 0xcb, 0x5a, 0xaf, + 0xaf, 0x7c, 0x77, 0x9b, 0x1a, 0x6b, 0x13, 0xe7, 0xc5, 0xea, 0xff, 0x82, 0x5b, 0xae, 0xa4, 0xaf, + 0x2e, 0x3f, 0xc4, 0x76, 0xd5, 0x6b, 0x51, 0x1a, 0xea, 0x95, 0x2e, 0x71, 0x24, 0x4b, 0x6d, 0xb6, + 0xdf, 0xfa, 0xf8, 0xf9, 0xe3, 0xd8, 0xaa, 0xaa, 0xff, 0x96, 0x4c, 0x48, 0x98, 0xcc, 0xc2, 0x1e, + 0x26, 0xac, 0xae, 0x16, 0xcf, 0x9a, 0x93, 0x0b, 0x96, 0x4d, 0x93, 0xa6, 0xcf, 0xfe, 0x1c, 0x15, + 0x18, 0x32, 0x26, 0xb0, 0x86, 0xdc, 0xbd, 0x3f, 0xf0, 0xad, 0x87, 0x8c, 0x9c, 0x08, 0xe5, 0x79, + 0x5f, 0x95, 0x1d, 0x57, 0xfc, 0x69, 0xad, 0xb7, 0x4b, 0xb6, 0xd3, 0xad, 0x36, 0x46, 0x10, 0x24, + 0x40, 0xf6, 0xad, 0x53, 0x2d, 0x0f, 0x0d, 0xb1, 0xcc, 0x78, 0x50, 0x98, 0x2e, 0xf0, 0x6f, 0x66, + 0x06, 0xb1, 0x50, 0xda, 0x6b, 0xa6, 0x78, 0x50, 0xd9, 0x9e, 0xa9, 0xc7, 0xc6, 0xcb, 0xbe, 0xa9, + 0xae, 0x99, 0xed, 0x77, 0xdb, 0xdd, 0x9f, 0x55, 0x55, 0xf1, 0x94, 0x34, 0x34, 0x8a, 0xd9, 0xed, + 0xec, 0xba, 0x0f, 0xbd, 0xf1, 0x3f, 0x89, 0xbd, 0xb3, 0xf7, 0xee, 0x22, 0x09, 0x71, 0xd5, 0xfc, + 0x65, 0x16, 0x27, 0x97, 0xdb, 0x67, 0x14, 0x41, 0x95, 0x6a, 0xaf, 0xdd, 0xa6, 0x3e, 0xce, 0xf3, + 0xea, 0xaf, 0x1f, 0x8f, 0x97, 0x9b, 0x6d, 0x1b, 0x5a, 0x76, 0xd4, 0x4f, 0x1f, 0xe3, 0x0b, 0x2f, + 0x4f, 0x3f, 0x94, 0x8f, 0x13, 0xe3, 0xb4, 0xd4, 0xdb, 0xf8, 0xc1, 0xcf, 0x94, 0xf6, 0x54, 0x44, + 0xed, 0xae, 0x5e, 0xcc, 0xbf, 0x94, 0xa0, 0x6b, 0x54, 0x6a, 0x3c, 0xb1, 0x71, 0x12, 0x05, 0x65, + 0xf2, 0xff, 0x52, 0x77, 0xc1, 0x11, 0x1c, 0xf8, 0xb2, 0xde, 0x25, 0x5f, 0xea, 0xff, 0x57, 0xf9, + 0xce, 0x8e, 0xfd, 0xdd, 0xdd, 0xf5, 0x4b, 0x2f, 0x3d, 0x1e, 0xfa, 0xaa, 0xa9, 0xb9, 0x8d, 0x69, + 0x4d, 0xf8, 0x80, 0x50, 0x46, 0x6b, 0xcf, 0x44, 0x9a, 0x69, 0xbe, 0x18, 0xea, 0xaa, 0xbb, 0xfc, + 0x9e, 0x9f, 0xce, 0x75, 0xf7, 0x77, 0x7f, 0x54, 0x79, 0xf0, 0x4c, 0x6b, 0x76, 0xea, 0xb4, 0x71, + 0x93, 0xa3, 0x94, 0x1f, 0x56, 0xf1, 0x3f, 0x05, 0x71, 0x7c, 0x56, 0xee, 0xaa, 0xee, 0xaa, 0x91, + 0xf8, 0x23, 0xbb, 0xaa, 0xa3, 0xd3, 0xf3, 0x84, 0x4b, 0xcc, 0xf0, 0x9e, 0x1f, 0xe0, 0x90, 0x24, + 0x83, 0x49, 0x53, 0xd7, 0xc1, 0x48, 0xce, 0x2d, 0x2c, 0x1d, 0x77, 0x4a, 0x0f, 0x8e, 0xa4, 0xaa, + 0x4e, 0x4d, 0xe6, 0x8a, 0x09, 0x9a, 0xaa, 0x17, 0xc6, 0x92, 0x44, 0xa3, 0x51, 0x84, 0xd3, 0x38, + 0x10, 0xb2, 0x25, 0xa7, 0x19, 0x1b, 0x47, 0xf7, 0x5d, 0x75, 0xfe, 0x37, 0x74, 0x18, 0xfd, 0xdd, + 0x5d, 0x7e, 0x14, 0x23, 0x37, 0x21, 0x96, 0x26, 0x5c, 0x3f, 0x84, 0xb9, 0x26, 0xf1, 0x65, 0x4b, + 0xfb, 0x27, 0x24, 0xf2, 0xfe, 0x76, 0x94, 0x6e, 0x5f, 0x07, 0xa0, 0x7e, 0x71, 0xe1, 0xd3, 0x92, + 0xdf, 0x16, 0x50, 0x9c, 0x31, 0xc0, 0xca, 0x2b, 0x06, 0x25, 0xe3, 0x2e, 0x2a, 0xc7, 0x25, 0xf7, + 0xce, 0xb8, 0xdf, 0xea, 0xa9, 0xfc, 0x76, 0x5c, 0x4f, 0x76, 0x3f, 0x93, 0xfa, 0x49, 0x78, 0xc1, + 0x2b, 0x55, 0xad, 0x72, 0xe2, 0x6a, 0x92, 0x6f, 0xe2, 0x4e, 0x95, 0x2a, 0x49, 0x24, 0x97, 0x12, + 0x09, 0x69, 0x96, 0x62, 0x1f, 0x9a, 0x84, 0xcc, 0x97, 0xc5, 0x08, 0x6a, 0xd5, 0x37, 0x2f, 0xbf, + 0x1e, 0x48, 0xee, 0x7d, 0x8c, 0xda, 0xf9, 0xbf, 0x8e, 0x10, 0xcc, 0x94, 0xd2, 0x2b, 0x64, 0x9c, + 0x4d, 0x5c, 0xbb, 0xe0, 0x8c, 0xf8, 0x8f, 0x54, 0x8b, 0xd0, 0x55, 0xe2, 0x79, 0xe8, 0xf3, 0xe9, + 0xa6, 0x9a, 0x62, 0xfa, 0x19, 0x17, 0xcf, 0xb9, 0x4e, 0x63, 0x14, 0xff, 0xce, 0x25, 0x53, 0x4d, + 0xb6, 0xff, 0xcf, 0x8b, 0xea, 0xaa, 0xbe, 0x1b, 0x22, 0xae, 0xad, 0xb6, 0xdb, 0x7f, 0xe0, 0xa0, + 0x8e, 0xff, 0x26, 0x39, 0xf5, 0x7f, 0x08, 0x1e, 0x22, 0x0d, 0x51, 0x13, 0x22, 0x26, 0x58, 0x54, + 0x2f, 0xf5, 0xef, 0x86, 0xaf, 0xae, 0x54, 0xd2, 0x39, 0x8b, 0xcd, 0x0a, 0xb6, 0xd3, 0xe2, 0x67, + 0xa5, 0x45, 0xd2, 0xec, 0x45, 0xd7, 0xf8, 0x24, 0xaa, 0xbb, 0xa4, 0x5c, 0x42, 0x8e, 0x38, 0xf9, + 0xef, 0x6d, 0xb4, 0xd3, 0xff, 0x0d, 0xd2, 0x4b, 0x52, 0xea, 0x51, 0xa6, 0xd3, 0x4d, 0xb7, 0xe1, + 0x62, 0x2a, 0xe5, 0xc2, 0xe3, 0xf2, 0x93, 0x49, 0xbf, 0xfc, 0xd7, 0x76, 0x6c, 0xfc, 0x3d, 0x77, + 0xdd, 0xf7, 0x53, 0xe6, 0x74, 0xa7, 0x37, 0x6f, 0xfc, 0xe7, 0xc3, 0x6d, 0x99, 0xeb, 0xfe, 0xa5, + 0x99, 0x78, 0x60, 0xd8, 0xcd, 0xbb, 0x5a, 0x4b, 0x46, 0x8c, 0xf4, 0x9e, 0x86, 0xa7, 0xe3, 0x37, + 0x26, 0xc6, 0x5c, 0x56, 0xe6, 0xee, 0xcb, 0xe7, 0xcf, 0x05, 0x92, 0x69, 0x1f, 0x18, 0xbb, 0x9f, + 0x5a, 0xd1, 0x9e, 0xde, 0xcc, 0xbe, 0x30, 0xd3, 0x7b, 0xbd, 0x4d, 0xe2, 0x63, 0xae, 0xc3, 0x33, + 0x9b, 0x3c, 0x65, 0x88, 0x42, 0xc8, 0xea, 0x0d, 0xcb, 0x26, 0x65, 0x11, 0x59, 0x52, 0xc7, 0x03, + 0x14, 0xdb, 0x14, 0x88, 0x75, 0x15, 0x2c, 0x35, 0x78, 0x25, 0x29, 0x69, 0x8f, 0xb5, 0x36, 0x7b, + 0x3b, 0xcb, 0xc4, 0x8a, 0x29, 0x30, 0x9a, 0xb1, 0xd3, 0x92, 0x7e, 0x10, 0xdb, 0xbd, 0xf7, 0x5b, + 0xfc, 0x5f, 0x3b, 0x0e, 0xdd, 0x92, 0x2e, 0x24, 0x24, 0x55, 0xa3, 0xd2, 0x4d, 0xd7, 0x08, 0xed, + 0xa7, 0x4d, 0x32, 0x78, 0xc9, 0xcb, 0xd9, 0xdb, 0xfc, 0x41, 0xa1, 0xb5, 0x68, 0xdf, 0xe4, 0xc5, + 0xf0, 0x58, 0x28, 0x63, 0xbc, 0xde, 0x95, 0x56, 0x4d, 0xad, 0xd6, 0xe2, 0x20, 0x9a, 0xf5, 0xb5, + 0x64, 0xaa, 0xb7, 0x30, 0xb3, 0xa6, 0x5e, 0x26, 0x5c, 0x45, 0xf4, 0x13, 0xef, 0x82, 0x8b, 0x36, + 0x69, 0x24, 0x92, 0x49, 0x24, 0x2b, 0x11, 0x3c, 0x51, 0x95, 0x55, 0x5a, 0xa7, 0xf2, 0x95, 0xdd, + 0xdf, 0xc1, 0x85, 0xdf, 0xc7, 0x1a, 0x16, 0x34, 0x0e, 0xf9, 0x6b, 0xa6, 0x9f, 0xf8, 0x28, 0x27, + 0x69, 0x64, 0xfc, 0xbe, 0x23, 0x36, 0x64, 0xc4, 0x97, 0xe0, 0xc3, 0xa4, 0x91, 0xb1, 0xaa, 0x4c, + 0x9e, 0x8f, 0xa7, 0xfe, 0x2f, 0x4a, 0x93, 0xbf, 0xe2, 0x09, 0xa4, 0x92, 0x49, 0x17, 0x1b, 0x9e, + 0x11, 0xea, 0xa9, 0x25, 0x49, 0x24, 0x92, 0x4b, 0xc2, 0x33, 0x63, 0x5a, 0xed, 0x34, 0xd3, 0x5f, + 0x04, 0xfd, 0xdd, 0xa3, 0x62, 0x51, 0x67, 0xae, 0x23, 0xa4, 0x91, 0xf1, 0xf9, 0xfc, 0x45, 0xa6, + 0x9d, 0xda, 0xd7, 0xc7, 0xdd, 0xf6, 0x0d, 0x83, 0x69, 0xa5, 0x5f, 0xc7, 0xd2, 0x49, 0xa6, 0x92, + 0x49, 0xa6, 0x92, 0x4b, 0xf0, 0x8f, 0x49, 0x29, 0x73, 0x89, 0x2f, 0xd6, 0xff, 0x09, 0xf4, 0x92, + 0xa4, 0xdb, 0x7e, 0x1d, 0xa2, 0x4a, 0xa9, 0xd6, 0x89, 0xa2, 0xfe, 0xb6, 0xc7, 0x3f, 0xff, 0x82, + 0x63, 0x2a, 0x69, 0x24, 0x5d, 0xf6, 0xf8, 0x58, 0xb6, 0x66, 0x96, 0x51, 0x93, 0x3b, 0x18, 0xb9, + 0xbe, 0xb7, 0x7f, 0x18, 0x59, 0xb7, 0x6f, 0xa7, 0x4e, 0x9e, 0x7e, 0xfe, 0x13, 0x8b, 0x44, 0xce, + 0x92, 0x93, 0x7c, 0x28, 0x32, 0x3e, 0x27, 0x06, 0xc9, 0xfa, 0x2c, 0xc8, 0x9b, 0x90, 0x15, 0xcd, + 0xc0, 0xe4, 0x07, 0xd8, 0x44, 0xec, 0x41, 0xf8, 0x3f, 0x1c, 0x09, 0x8b, 0xed, 0x1b, 0xf3, 0x3e, + 0x14, 0x29, 0x3e, 0xa3, 0xba, 0x77, 0x28, 0xa5, 0x69, 0x9d, 0x5e, 0xca, 0xb0, 0xb1, 0x46, 0xf3, + 0xc1, 0x65, 0x4c, 0x27, 0x51, 0xe3, 0x0d, 0x0d, 0x49, 0x7f, 0x7c, 0x49, 0x52, 0x3f, 0xbb, 0x15, + 0xc8, 0x46, 0x0e, 0xd9, 0x64, 0x8f, 0x89, 0x08, 0x6a, 0x6f, 0x25, 0xac, 0xad, 0x64, 0xb5, 0xe2, + 0x7c, 0x40, 0x40, 0x4c, 0xde, 0xdb, 0x6d, 0xa9, 0xf4, 0x90, 0xda, 0x5e, 0x32, 0x7f, 0xcb, 0x13, + 0xc1, 0x13, 0x22, 0xf8, 0x17, 0x1a, 0x92, 0xcb, 0x75, 0xb0, 0xd3, 0xc5, 0x88, 0x96, 0xa6, 0xfe, + 0x22, 0x2b, 0xcd, 0xf6, 0xd7, 0x11, 0x24, 0x8c, 0x26, 0x86, 0x9e, 0x24, 0x40, 0xac, 0xd9, 0xbd, + 0xfe, 0x14, 0x15, 0x67, 0xdb, 0x51, 0xa5, 0xee, 0xb8, 0x96, 0xb0, 0x9f, 0x0a, 0x10, 0x9e, 0x4c, + 0x11, 0xa6, 0x68, 0x16, 0x55, 0x2e, 0x5b, 0x31, 0xd8, 0xca, 0x33, 0x19, 0x9d, 0xf0, 0x87, 0x2e, + 0x3b, 0xb3, 0x95, 0x4a, 0x6c, 0xf9, 0x42, 0xe9, 0x52, 0x48, 0xbc, 0x14, 0x04, 0x29, 0x4b, 0x86, + 0x8b, 0xec, 0x8c, 0x6f, 0x8d, 0x23, 0x8f, 0x6a, 0xf1, 0xa6, 0x7d, 0x4e, 0x15, 0x9d, 0xb1, 0xba, + 0x1e, 0x23, 0x35, 0x52, 0x57, 0x49, 0x2a, 0x1e, 0x3c, 0xeb, 0xe4, 0xbf, 0xf0, 0xfe, 0xdc, 0x92, + 0xa3, 0x7c, 0x36, 0xc9, 0x9d, 0xc5, 0xc3, 0x9b, 0x1a, 0xff, 0x0c, 0x4d, 0x83, 0x43, 0x0b, 0x83, + 0xdc, 0x91, 0xe0, 0xa7, 0x19, 0xc2, 0x9e, 0xf1, 0x1c, 0x3a, 0x13, 0x3e, 0xaf, 0x55, 0x77, 0x49, + 0x22, 0xe4, 0x40, 0x2d, 0x4d, 0x34, 0xd3, 0xff, 0x14, 0x43, 0x6f, 0x26, 0x4b, 0x85, 0xcf, 0x04, + 0x64, 0x55, 0xec, 0x7c, 0x11, 0x14, 0xb9, 0xdc, 0xf9, 0x24, 0xc4, 0xbf, 0x44, 0x67, 0xd5, 0x9f, + 0x12, 0x71, 0x59, 0x73, 0xdd, 0xfd, 0x15, 0x3a, 0xf0, 0x44, 0x44, 0x92, 0x9b, 0xc4, 0xaf, 0xc1, + 0x2d, 0x24, 0xa5, 0x49, 0x8c, 0xce, 0x95, 0x78, 0xf2, 0x24, 0x96, 0x92, 0x49, 0x24, 0xee, 0xef, + 0xe3, 0xa2, 0xd0, 0xb5, 0xe9, 0x24, 0xf7, 0xf8, 0x9e, 0x92, 0x4e, 0xee, 0xeb, 0x9a, 0xee, 0xee, + 0xba, 0xf7, 0xc2, 0x82, 0x39, 0xf6, 0x4d, 0x6b, 0x87, 0xb8, 0xb0, 0xa3, 0x4b, 0xf7, 0xc1, 0x26, + 0xd3, 0x62, 0x7c, 0xa6, 0xf8, 0x7c, 0x93, 0xe4, 0x7a, 0xb6, 0xe8, 0xe2, 0xd9, 0x2a, 0x6e, 0x7d, + 0xd5, 0xd7, 0xc1, 0x49, 0x76, 0xd3, 0x56, 0xab, 0x9b, 0x13, 0x9b, 0xe0, 0xa8, 0xf4, 0xe9, 0xed, + 0xb6, 0xdd, 0xbb, 0x68, 0xa3, 0xe3, 0x0c, 0x9d, 0x3a, 0x6a, 0xa8, 0x7f, 0x5a, 0x7a, 0x6e, 0x71, + 0x05, 0x0e, 0x87, 0xe3, 0x67, 0xd2, 0x19, 0xd5, 0x55, 0xf9, 0x06, 0x26, 0x1d, 0x17, 0x7a, 0x49, + 0x11, 0x5a, 0x0f, 0x71, 0xae, 0x9c, 0x3c, 0xf5, 0x7a, 0xf1, 0x21, 0xd2, 0x3b, 0x19, 0x08, 0xf0, + 0xe1, 0xf2, 0x33, 0xf2, 0x8f, 0x6d, 0xd9, 0xab, 0x68, 0x6b, 0xe9, 0xad, 0xf8, 0x80, 0xa4, 0xfa, + 0x0c, 0x96, 0x12, 0xdb, 0x59, 0x83, 0x19, 0xc5, 0x1e, 0xd5, 0xed, 0x67, 0xd8, 0xef, 0x10, 0x51, + 0x69, 0xbe, 0xd7, 0x8c, 0xed, 0x35, 0x3e, 0xb5, 0x5d, 0xa6, 0xe7, 0x8d, 0x26, 0x99, 0x78, 0x43, + 0x1d, 0xe5, 0xa6, 0xdd, 0x4d, 0xa4, 0xff, 0x8f, 0xba, 0x24, 0x4c, 0x8b, 0x04, 0xee, 0x34, 0x70, + 0x8f, 0x1a, 0x5e, 0x26, 0x11, 0xbb, 0xf6, 0xdb, 0x8a, 0xfe, 0x26, 0x33, 0x3e, 0x76, 0xb7, 0x4f, + 0x4d, 0xef, 0xc4, 0x44, 0x56, 0xb7, 0xd5, 0x70, 0x57, 0x49, 0x27, 0x77, 0xb4, 0xaf, 0xa5, 0x2f, + 0x8d, 0xb5, 0xd2, 0x9b, 0xdd, 0x59, 0xb3, 0x67, 0xb4, 0xfa, 0xbd, 0xdf, 0xfc, 0x16, 0x99, 0x4d, + 0x43, 0x7f, 0x68, 0x94, 0x29, 0x7c, 0x26, 0x6e, 0x68, 0x14, 0xc8, 0xc4, 0x64, 0xeb, 0xe0, 0xa0, + 0x4a, 0xc7, 0x31, 0x53, 0xbd, 0xd1, 0x50, 0xf8, 0x5e, 0x7c, 0x64, 0x92, 0x23, 0xb1, 0x93, 0x12, + 0x58, 0xf2, 0x22, 0xa8, 0xbe, 0xee, 0xef, 0xe3, 0x4c, 0x66, 0x63, 0xac, 0xcc, 0xa5, 0x51, 0x5e, + 0x5f, 0x13, 0xf3, 0xd9, 0xba, 0x36, 0x2a, 0x16, 0x2f, 0xfe, 0x34, 0xe3, 0xfe, 0xa6, 0xf8, 0xd5, + 0xcf, 0x83, 0xb9, 0xc4, 0x6f, 0xd5, 0xc7, 0xef, 0xab, 0x52, 0x2f, 0x36, 0xa2, 0x8f, 0xfc, 0x17, + 0xe7, 0x9c, 0x8c, 0x9a, 0xd9, 0xe8, 0xd6, 0x5d, 0x47, 0x7b, 0xfc, 0x69, 0x19, 0x8e, 0xe2, 0x94, + 0x25, 0xb3, 0x10, 0x7a, 0x39, 0xa5, 0x99, 0xb4, 0xa8, 0x95, 0xfe, 0xe3, 0xff, 0x84, 0x2e, 0xe5, + 0xfb, 0x44, 0x04, 0x67, 0x75, 0xc7, 0x37, 0xf9, 0xc2, 0x6a, 0x9a, 0x69, 0xa6, 0x9a, 0x69, 0xa7, + 0xe7, 0xaa, 0x69, 0xa6, 0x9a, 0x69, 0xa6, 0x9f, 0x86, 0x04, 0x3b, 0xbb, 0xa4, 0x97, 0xdc, 0x7b, + 0xf4, 0xff, 0xc1, 0x1d, 0xa6, 0x9a, 0x6b, 0x5f, 0x0e, 0x1b, 0x97, 0xce, 0x76, 0x63, 0x12, 0xbe, + 0x1c, 0x50, 0x35, 0x94, 0xb6, 0xdb, 0x7b, 0x6d, 0x9b, 0x5d, 0xbd, 0xda, 0xed, 0xc4, 0x02, 0x2a, + 0xc8, 0x3a, 0xb4, 0x1d, 0x5a, 0x3f, 0xd1, 0xfe, 0xa6, 0x98, 0xab, 0x15, 0x6f, 0x83, 0x03, 0xe9, + 0x24, 0x92, 0x5a, 0xa6, 0x9a, 0x69, 0xff, 0xab, 0x7d, 0x48, 0x31, 0xf5, 0xaf, 0x9e, 0xa9, 0xa6, + 0x9a, 0x7f, 0xe7, 0xaa, 0x69, 0xa6, 0x9f, 0xf8, 0x73, 0xa4, 0x92, 0xa6, 0x9a, 0x69, 0xff, 0x82, + 0x8e, 0x92, 0x5a, 0x49, 0x55, 0x73, 0x5f, 0x5f, 0x42, 0x44, 0xc9, 0xf0, 0x43, 0x1f, 0xf5, 0xfe, + 0x45, 0xe0, 0x88, 0x96, 0xe7, 0xd8, 0xc7, 0xd1, 0xc7, 0x1b, 0xe6, 0x33, 0x6d, 0xb6, 0xdf, 0x86, + 0x05, 0x1f, 0x0d, 0x09, 0x52, 0xb7, 0xcb, 0xd3, 0x7e, 0x7e, 0xdd, 0x7e, 0x2e, 0x4d, 0x3e, 0x54, + 0xcd, 0x74, 0xf2, 0xff, 0x05, 0x79, 0xaa, 0x4a, 0x2d, 0xe8, 0xb9, 0x4b, 0x4c, 0xfe, 0x5f, 0x0a, + 0x08, 0xe4, 0x95, 0x35, 0xb6, 0xc6, 0x29, 0x20, 0xad, 0xa8, 0xa7, 0xf3, 0xdf, 0x1a, 0x27, 0x4e, + 0x9d, 0x3a, 0x67, 0xfb, 0x97, 0xdd, 0xbf, 0x7e, 0xae, 0xbe, 0x3c, 0xa7, 0xfd, 0xf6, 0xd2, 0xcf, + 0xdf, 0xc2, 0x82, 0x95, 0x0f, 0x85, 0x15, 0x0b, 0x32, 0x12, 0xbe, 0x43, 0x13, 0x32, 0xe8, 0x01, + 0xd6, 0x1c, 0xc2, 0xb7, 0xee, 0x51, 0x7c, 0x29, 0xc6, 0xaf, 0x63, 0x74, 0x9c, 0x57, 0x4d, 0x27, + 0x77, 0x7b, 0xe1, 0xf0, 0xa1, 0x5b, 0x07, 0xec, 0xdc, 0xf8, 0x5d, 0x85, 0x51, 0x71, 0xb1, 0x76, + 0xd2, 0x5f, 0x8b, 0xbd, 0x14, 0xfc, 0x4d, 0x36, 0xfb, 0xcd, 0x1c, 0x4f, 0xe2, 0x05, 0x9c, 0x85, + 0xb6, 0xcf, 0xb6, 0x9f, 0x88, 0x8f, 0x9f, 0x2a, 0xb5, 0xda, 0x1b, 0xba, 0xd0, 0xb3, 0xc6, 0xff, + 0x89, 0x92, 0x48, 0xa5, 0x3a, 0xa9, 0xfc, 0x28, 0x62, 0xfa, 0x6f, 0xb9, 0x7d, 0xaa, 0xab, 0x35, + 0x54, 0x2b, 0x3e, 0x24, 0xaf, 0xaf, 0xe5, 0x3f, 0x26, 0xf7, 0xf1, 0x86, 0xdd, 0xdb, 0x6f, 0x4d, + 0xeb, 0x6d, 0x11, 0xe3, 0xe3, 0x0b, 0xcf, 0xa9, 0x6a, 0x9f, 0xbb, 0xf8, 0xaf, 0xf0, 0x50, 0x50, + 0x6e, 0xdc, 0x38, 0xa9, 0x25, 0x2f, 0x3c, 0x9f, 0x19, 0xda, 0x69, 0x31, 0x0f, 0x21, 0x76, 0x90, + 0x4f, 0x9d, 0x4d, 0x16, 0x9e, 0x97, 0x12, 0x0a, 0x49, 0x76, 0xae, 0x53, 0x19, 0x79, 0x30, 0xd8, + 0xc9, 0x33, 0x0a, 0x9f, 0x05, 0x43, 0x1d, 0x43, 0xf4, 0xb6, 0xe8, 0xe6, 0x2c, 0xbd, 0x14, 0x5f, + 0x63, 0xe3, 0x4a, 0x92, 0xda, 0x55, 0x69, 0xa0, 0x93, 0x6c, 0x33, 0x25, 0xd9, 0x1e, 0x24, 0x94, + 0xfa, 0xda, 0x3f, 0xf8, 0x23, 0x2d, 0x24, 0x92, 0xef, 0x82, 0x82, 0x6d, 0x34, 0xe5, 0x60, 0xdd, + 0x8c, 0xcb, 0xe3, 0x68, 0x91, 0xcd, 0x43, 0xc1, 0xbd, 0xe8, 0x15, 0x5c, 0x6b, 0x6b, 0x49, 0x42, + 0x6d, 0x50, 0xcf, 0x8e, 0x51, 0x9a, 0xcb, 0x35, 0x7f, 0xff, 0x1b, 0x92, 0x75, 0x3a, 0x26, 0xa5, + 0xb6, 0xf6, 0x7a, 0xbc, 0x99, 0x04, 0xc6, 0x75, 0x64, 0xff, 0x96, 0x4e, 0xb5, 0x59, 0xd5, 0xfe, + 0x0b, 0x08, 0xac, 0xb8, 0x68, 0xd1, 0x1f, 0x4b, 0x43, 0xef, 0xc3, 0xe1, 0xd9, 0x20, 0x9a, 0x34, + 0x76, 0x34, 0x64, 0x9b, 0xb5, 0xfb, 0xc7, 0x19, 0x75, 0xbf, 0xf0, 0x53, 0x64, 0x8d, 0x8e, 0x64, + 0x1f, 0xb4, 0xde, 0xb1, 0x56, 0x3e, 0x34, 0xad, 0x2a, 0xa5, 0xa4, 0x93, 0x93, 0x69, 0xc4, 0x6a, + 0x9a, 0x1c, 0x32, 0x4f, 0x19, 0x28, 0xef, 0xfe, 0x0a, 0x6d, 0x35, 0xaa, 0xbb, 0xba, 0x66, 0xd7, + 0xcf, 0xb8, 0x8b, 0xaa, 0xd2, 0xf3, 0x6d, 0xcf, 0x9e, 0x0b, 0xaf, 0xa4, 0xd9, 0x36, 0x5f, 0x02, + 0xaf, 0x04, 0x9d, 0xde, 0xf5, 0xce, 0x5e, 0xa6, 0x99, 0x0d, 0x40, 0xbf, 0xc1, 0x7d, 0xeb, 0x52, + 0xe7, 0x54, 0xd3, 0x3e, 0xbf, 0x7f, 0xc3, 0x97, 0x97, 0x12, 0x59, 0xb5, 0x04, 0xd3, 0x5f, 0xe1, + 0xca, 0x8b, 0xdf, 0x54, 0xc5, 0xb8, 0x11, 0x0c, 0x7f, 0xcb, 0xdd, 0x2f, 0x17, 0x77, 0xeb, 0x37, + 0xf3, 0xd5, 0xb4, 0xc8, 0x62, 0xc3, 0x5f, 0xe1, 0xcb, 0xbe, 0xa0, 0xff, 0xc6, 0xae, 0x46, 0x9a, + 0xff, 0x04, 0x97, 0x7a, 0xbd, 0x73, 0xea, 0xdb, 0x63, 0x72, 0x34, 0xcf, 0xf0, 0xc9, 0xca, 0x11, + 0x02, 0xa0, 0xf9, 0xa4, 0x0d, 0x00, 0xd5, 0x0e, 0x8a, 0xaf, 0xfa, 0x95, 0x3e, 0xbd, 0x8f, 0x50, + 0xf7, 0x83, 0xed, 0x91, 0x69, 0x03, 0x1f, 0xbf, 0xc3, 0x97, 0x63, 0x73, 0x76, 0x7f, 0xb6, 0x2a, + 0xfc, 0x3c, 0x63, 0xc1, 0x51, 0x97, 0x8a, 0xa3, 0xeb, 0xf2, 0x69, 0x49, 0xb0, 0x7e, 0x9a, 0xa7, + 0xe4, 0x2a, 0x7c, 0x9f, 0xc1, 0x54, 0x97, 0xd4, 0xef, 0x3d, 0xb3, 0xe7, 0x3b, 0xe0, 0xac, 0x41, + 0xd8, 0x83, 0x1a, 0xa4, 0xb5, 0xb1, 0x95, 0x99, 0x5b, 0x73, 0xdf, 0x04, 0xe7, 0x63, 0xcf, 0xda, + 0xa8, 0xdb, 0x57, 0x78, 0x90, 0x86, 0xed, 0x1a, 0x84, 0xbf, 0x46, 0xd4, 0x63, 0x2a, 0xfc, 0x69, + 0x10, 0xea, 0x4d, 0xbd, 0x4d, 0xe2, 0x62, 0x6d, 0x88, 0x7b, 0x0c, 0xc5, 0x0b, 0xc6, 0xc3, 0xea, + 0xad, 0xf8, 0x4f, 0xba, 0x9b, 0x29, 0x7c, 0x71, 0xc7, 0x2b, 0x9c, 0x9b, 0x2f, 0x2e, 0x29, 0x5b, + 0x1a, 0x6c, 0x7e, 0x0a, 0x0e, 0xbb, 0x9f, 0xb6, 0xff, 0x59, 0x2f, 0x12, 0x12, 0x9f, 0x3a, 0x74, + 0xcc, 0xcf, 0x82, 0x4d, 0xc9, 0x8c, 0xc6, 0xf8, 0x46, 0xe6, 0xc7, 0xb4, 0xde, 0x3b, 0xa7, 0x26, + 0x78, 0x40, 0x44, 0x7b, 0xa5, 0x7f, 0xd2, 0x8c, 0xaf, 0x82, 0x6d, 0x2a, 0x76, 0xeb, 0xb9, 0xf0, + 0x80, 0xd3, 0x31, 0x19, 0x98, 0x8c, 0xec, 0x46, 0x76, 0x23, 0x57, 0x75, 0xf2, 0x92, 0xd5, 0x3f, + 0x08, 0x0a, 0x76, 0xda, 0x6d, 0x5b, 0x5a, 0x63, 0xea, 0xee, 0x97, 0x84, 0x4a, 0x5c, 0xdf, 0x72, + 0xc2, 0xdb, 0x8a, 0xfe, 0x2c, 0xe8, 0x26, 0x12, 0x21, 0xb8, 0xd7, 0xdf, 0xc1, 0x2d, 0x14, 0xb7, + 0xe4, 0xc4, 0xeb, 0xc6, 0x46, 0x55, 0xe4, 0x9b, 0x94, 0x18, 0x61, 0x91, 0xdb, 0x41, 0xdb, 0xc8, + 0x65, 0x11, 0x48, 0xfb, 0x5e, 0x30, 0x85, 0x61, 0xaa, 0x9a, 0x79, 0x59, 0x4c, 0x97, 0x17, 0x94, + 0x93, 0x1d, 0x38, 0xf8, 0x44, 0x51, 0x20, 0x7f, 0xab, 0x18, 0xae, 0xe6, 0xc9, 0x66, 0xb2, 0x5e, + 0x37, 0x0f, 0x2a, 0x91, 0x28, 0xb8, 0x9d, 0x1c, 0x63, 0x9b, 0x1b, 0x63, 0x5f, 0xfc, 0x6a, 0x08, + 0x86, 0x48, 0xad, 0x51, 0xeb, 0xfc, 0x3d, 0xa8, 0xf4, 0x2f, 0xbb, 0x8f, 0x2e, 0x69, 0x2a, 0x46, + 0xff, 0xfc, 0x15, 0x95, 0xd5, 0x75, 0x9e, 0xd6, 0xf9, 0xf4, 0xa9, 0x24, 0xd5, 0x22, 0xf0, 0x4b, + 0xd1, 0x0e, 0xfd, 0xb9, 0x76, 0xe5, 0x22, 0xf0, 0xa6, 0xad, 0xa4, 0xb5, 0xd9, 0xdd, 0xa4, 0xb6, + 0x3e, 0x32, 0x4d, 0x48, 0x9f, 0x74, 0x8b, 0xed, 0xf4, 0x3d, 0x1f, 0xcb, 0x94, 0xfc, 0x15, 0xe9, + 0xa4, 0x9e, 0x99, 0xb1, 0xda, 0x5c, 0x4a, 0xe4, 0x51, 0xf0, 0x4f, 0xe7, 0xc6, 0xb1, 0x85, 0x8a, + 0x2f, 0x85, 0x0a, 0x1e, 0x46, 0xe9, 0x79, 0xe6, 0x5d, 0xe5, 0xfd, 0xb5, 0xc5, 0xf1, 0x74, 0xde, + 0x87, 0x8b, 0xfc, 0x29, 0x66, 0x7a, 0xa7, 0x59, 0xe7, 0x17, 0x4e, 0x5c, 0x2e, 0x27, 0x8e, 0x6b, + 0xe0, 0x9f, 0x3d, 0x0f, 0x9a, 0x4f, 0x6c, 0xc9, 0xf0, 0x4d, 0x3d, 0x7b, 0xbe, 0x65, 0xfc, 0x23, + 0xbd, 0xea, 0xc1, 0x8f, 0x32, 0x2d, 0x1b, 0x48, 0x70, 0xfc, 0x15, 0xea, 0x6f, 0xab, 0xe8, 0x6a, + 0x7e, 0xa7, 0xc9, 0x93, 0x37, 0x20, 0x47, 0xc6, 0xea, 0x4f, 0xaa, 0x6d, 0x2b, 0xb5, 0x1d, 0x76, + 0xe4, 0xb4, 0x75, 0x6e, 0xb6, 0xdb, 0xff, 0x05, 0xde, 0x6c, 0xc9, 0x5e, 0x5f, 0x0a, 0x76, 0xcd, + 0xda, 0x7a, 0xbb, 0x92, 0x87, 0xd1, 0xaa, 0xd9, 0x3f, 0x2f, 0x85, 0x2e, 0xa8, 0xd1, 0xb4, 0xd7, + 0xd5, 0x23, 0x69, 0xf6, 0x3a, 0xcc, 0x9f, 0x1b, 0x36, 0x1b, 0x09, 0x8c, 0xcb, 0x44, 0xf7, 0xbd, + 0x74, 0x93, 0xdc, 0xb4, 0xd2, 0xbf, 0xf8, 0x28, 0xb4, 0x9e, 0x5d, 0x59, 0x26, 0x64, 0xf8, 0x82, + 0x9f, 0x15, 0xa7, 0x2e, 0x3a, 0xb5, 0xfc, 0x16, 0x5d, 0x27, 0x78, 0xb4, 0x95, 0xf6, 0xb3, 0x9f, + 0x0a, 0x53, 0xbb, 0xbe, 0xbb, 0x47, 0xc5, 0xea, 0x99, 0x78, 0x2b, 0x9b, 0x93, 0xbb, 0xb3, 0xa6, + 0x5c, 0xc1, 0xfd, 0xe5, 0xf4, 0x56, 0xf8, 0x24, 0xa6, 0x5d, 0x4f, 0x4c, 0xbc, 0x13, 0xda, 0x2e, + 0x25, 0xde, 0xa9, 0x97, 0x82, 0xcc, 0x8c, 0x3e, 0x6f, 0xad, 0x9a, 0xab, 0xdc, 0xf8, 0x7a, 0x3b, + 0x5c, 0x57, 0x77, 0xcf, 0x94, 0x91, 0xe1, 0x2e, 0xb3, 0x53, 0xff, 0xc3, 0xa6, 0xe5, 0x8a, 0x55, + 0x35, 0xb9, 0x36, 0xba, 0x99, 0x29, 0x26, 0xc8, 0xb1, 0x5f, 0xa7, 0xf8, 0xca, 0xb4, 0x92, 0x4d, + 0x37, 0x97, 0xc6, 0x98, 0xfa, 0xb4, 0xf8, 0x54, 0x48, 0xdd, 0x2f, 0x08, 0x45, 0x67, 0xcb, 0x43, + 0xf9, 0xb3, 0x7b, 0x36, 0x6c, 0xd9, 0xf8, 0xfa, 0x49, 0x5e, 0xb4, 0xd1, 0xa3, 0xa5, 0x36, 0xf8, + 0x50, 0x44, 0x9f, 0xdb, 0x8a, 0x5d, 0xaa, 0xc2, 0xd5, 0x4e, 0xff, 0x0a, 0x0d, 0x69, 0x34, 0xcd, + 0xae, 0xd7, 0x6c, 0x6b, 0x56, 0x5c, 0x7f, 0xba, 0x49, 0x7e, 0x10, 0x9b, 0x25, 0xdb, 0xcd, 0x37, + 0x2e, 0x0b, 0x6d, 0x63, 0xf0, 0xa1, 0x0f, 0x65, 0xe9, 0x19, 0x85, 0x6e, 0x35, 0x15, 0x72, 0x5d, + 0x94, 0xf2, 0x63, 0x7c, 0x16, 0x5e, 0xf7, 0x45, 0x4d, 0x95, 0x5a, 0xeb, 0xe1, 0x0b, 0xad, 0x34, + 0xcb, 0xd2, 0xdb, 0x6d, 0xb6, 0xf8, 0x9f, 0x11, 0xe2, 0x42, 0x22, 0x53, 0xb9, 0x35, 0x55, 0xde, + 0x5f, 0x4f, 0xc1, 0x48, 0x83, 0x67, 0xda, 0x6d, 0x53, 0x74, 0xdc, 0xb7, 0x89, 0x1e, 0x7f, 0x27, + 0xbe, 0xdf, 0x6a, 0x92, 0x58, 0x88, 0x27, 0xea, 0xb7, 0xbc, 0xbe, 0x13, 0x2b, 0x1a, 0xaa, 0x97, + 0x97, 0xa6, 0xdf, 0xe0, 0xa0, 0xcf, 0xae, 0x7d, 0x9d, 0xe3, 0x79, 0xbb, 0xe3, 0x0c, 0xea, 0x6c, + 0xf3, 0xbe, 0x91, 0x3d, 0x6a, 0x73, 0xae, 0xef, 0xe2, 0x42, 0x02, 0x59, 0x27, 0x1d, 0xc0, 0x3b, + 0x98, 0xc0, 0x98, 0x43, 0x71, 0x93, 0x1c, 0x6e, 0x9e, 0x9a, 0xf0, 0xa1, 0x07, 0xe5, 0xb6, 0xd9, + 0x55, 0x11, 0x63, 0x49, 0x99, 0xf8, 0xe4, 0x6b, 0x0c, 0xb5, 0xbc, 0xef, 0x8c, 0x39, 0x0c, 0x75, + 0x1c, 0xea, 0x4e, 0x38, 0xba, 0xea, 0x5b, 0x5a, 0x49, 0x32, 0xf1, 0x96, 0x62, 0xac, 0xc3, 0xaa, + 0x5a, 0x87, 0xd4, 0xe1, 0xd7, 0xf9, 0xfb, 0xea, 0x15, 0x40, 0xef, 0x6f, 0xbc, 0x44, 0xbb, 0x6c, + 0x65, 0xcf, 0x21, 0x26, 0xff, 0x9c, 0x42, 0x96, 0xa9, 0x75, 0xbb, 0xbf, 0xf8, 0x5a, 0x5d, 0x67, + 0xf3, 0x3d, 0xcd, 0x13, 0x35, 0x48, 0x29, 0xff, 0x82, 0xa3, 0xba, 0x49, 0x97, 0x5d, 0xd9, 0x7a, + 0x52, 0xe3, 0xb9, 0xf0, 0xec, 0x9a, 0x5d, 0x25, 0x5b, 0x53, 0x46, 0xf6, 0x19, 0x17, 0x26, 0xa4, + 0xf5, 0x37, 0x3f, 0x37, 0x7f, 0xff, 0x0b, 0x49, 0xdb, 0x95, 0xe6, 0xfb, 0x74, 0xe8, 0xb1, 0x6d, + 0xb1, 0xaf, 0xfc, 0x14, 0xf6, 0x43, 0x79, 0xd3, 0xaa, 0x9b, 0xbb, 0x71, 0xb9, 0xf0, 0x4f, 0x9d, + 0x86, 0xe8, 0xd5, 0x52, 0x94, 0x1f, 0x1d, 0x6d, 0xb6, 0xdb, 0xa8, 0x9c, 0x9d, 0x9d, 0x34, 0xad, + 0x78, 0x27, 0xba, 0xbd, 0x6b, 0x2d, 0xf0, 0x41, 0xce, 0xca, 0x1d, 0xa6, 0xb9, 0xb5, 0x3a, 0xd5, + 0xb6, 0xd3, 0x4f, 0xfc, 0x49, 0x65, 0xcb, 0x78, 0xbf, 0xc6, 0xdb, 0x64, 0xb7, 0x6a, 0x89, 0x9a, + 0x63, 0x4b, 0x95, 0x99, 0x23, 0x11, 0xea, 0xaa, 0xab, 0xfe, 0x1f, 0x93, 0x97, 0x72, 0x43, 0x36, + 0xdd, 0xf8, 0xe5, 0x36, 0xdb, 0x4f, 0xfc, 0x15, 0x90, 0x99, 0xf7, 0x2e, 0x5a, 0xc6, 0x59, 0x29, + 0x65, 0xdf, 0x0b, 0x66, 0x5f, 0x18, 0x5a, 0x5b, 0x9f, 0x6d, 0xb4, 0xd3, 0xf0, 0x41, 0x9f, 0x09, + 0x8c, 0xcb, 0xab, 0x51, 0x44, 0xcd, 0x9b, 0x9f, 0x6d, 0xb4, 0xd3, 0xf0, 0x5f, 0x69, 0xac, 0x99, + 0x8c, 0xdc, 0xa9, 0x4d, 0x34, 0x92, 0xff, 0x17, 0x58, 0xc7, 0x99, 0x66, 0xf6, 0xeb, 0xf8, 0x52, + 0xcd, 0x9a, 0xa9, 0xed, 0xf7, 0x33, 0x2e, 0x7a, 0xd6, 0x2f, 0x8c, 0xa4, 0x95, 0x21, 0x74, 0xda, + 0xb5, 0x69, 0xa6, 0xe5, 0xd4, 0xbc, 0x21, 0x67, 0x49, 0x22, 0xe3, 0x32, 0xaa, 0x89, 0xf1, 0xbf, + 0x84, 0xb6, 0xa6, 0xe9, 0x25, 0x10, 0xe7, 0x82, 0x6e, 0xef, 0x3e, 0x26, 0xef, 0x5f, 0x19, 0xd5, + 0x21, 0xbc, 0xbb, 0xb4, 0x7c, 0xb5, 0xa4, 0x99, 0x73, 0xc1, 0x2d, 0x33, 0xe2, 0x7c, 0x36, 0xcb, + 0x9d, 0x7c, 0x13, 0x74, 0xce, 0xee, 0x6c, 0x8b, 0xe3, 0x49, 0xba, 0x48, 0xd4, 0x69, 0x7c, 0x6f, + 0xd7, 0x4d, 0x99, 0x65, 0xab, 0x71, 0xb5, 0xff, 0xc2, 0x9d, 0x99, 0xa8, 0xdb, 0x56, 0x8d, 0x9d, + 0x3b, 0x9e, 0xae, 0xaf, 0xd7, 0xc4, 0x72, 0x59, 0x2f, 0x49, 0x2f, 0x04, 0xd6, 0x8d, 0x56, 0xfb, + 0x69, 0xd2, 0x7c, 0x29, 0x65, 0x19, 0x36, 0x5f, 0x74, 0x4f, 0x74, 0xee, 0xd9, 0x13, 0xe0, 0xb0, + 0xb6, 0xa6, 0xe9, 0xb4, 0x9d, 0xbd, 0xb9, 0xaf, 0x85, 0x36, 0xaf, 0x6a, 0xaf, 0x73, 0xf3, 0x6a, + 0xef, 0xc7, 0x1c, 0xef, 0x8c, 0x10, 0x9b, 0xc7, 0x28, 0x5d, 0x4a, 0xaf, 0x1d, 0x39, 0xbb, 0xcf, + 0x89, 0x1a, 0xda, 0x1b, 0x7a, 0xe7, 0xe5, 0x63, 0xc7, 0x99, 0x6d, 0xb6, 0xda, 0xa5, 0x9f, 0x3f, + 0x18, 0x7a, 0xd5, 0x2a, 0x51, 0x25, 0xb4, 0xd9, 0x16, 0x09, 0x12, 0xf4, 0xbc, 0x45, 0x34, 0xd3, + 0x4c, 0x9a, 0xb0, 0x64, 0xde, 0x24, 0x29, 0x1f, 0xff, 0xe8, 0xd6, 0x65, 0x09, 0xa7, 0x4c, 0xde, + 0xc2, 0x97, 0x88, 0x0a, 0x67, 0xdb, 0x67, 0xc7, 0xa8, 0xfd, 0xad, 0xa2, 0xfd, 0xbc, 0xbd, 0xfe, + 0x13, 0xdd, 0x5a, 0xcb, 0x89, 0x7b, 0xb7, 0x6f, 0xe0, 0x94, 0x89, 0xb6, 0x9e, 0xf7, 0x67, 0x89, + 0x45, 0x4f, 0xe2, 0x4b, 0xdd, 0xfc, 0x7d, 0x24, 0xbc, 0x65, 0x7e, 0x4f, 0xf0, 0x88, 0x87, 0x8a, + 0x58, 0x4c, 0xc3, 0xc2, 0x27, 0x7f, 0x6e, 0xab, 0xa7, 0x82, 0xa3, 0xd8, 0x22, 0x3c, 0x32, 0xf9, + 0x60, 0x89, 0xf1, 0x65, 0x49, 0x12, 0x23, 0xef, 0x8c, 0x2f, 0x32, 0x1c, 0x68, 0xa1, 0x70, 0x38, + 0x8a, 0x28, 0x1f, 0x6a, 0x21, 0x2c, 0x32, 0xd2, 0x94, 0x5e, 0x24, 0x71, 0x34, 0xe7, 0x20, 0x92, + 0x0d, 0xdd, 0x84, 0xc4, 0xb7, 0xf1, 0x9b, 0x26, 0x10, 0xcc, 0x8e, 0x5c, 0xbb, 0xb2, 0x2f, 0xc4, + 0xfe, 0x22, 0x48, 0x9e, 0x44, 0xab, 0x89, 0x89, 0x2d, 0x47, 0xa3, 0x7d, 0x53, 0x27, 0xf0, 0x49, + 0x49, 0xbe, 0xbe, 0x10, 0xc4, 0x3a, 0x9d, 0xd5, 0xf9, 0xff, 0xc6, 0x8c, 0x5a, 0xba, 0x44, 0x87, + 0x2e, 0xf2, 0x1d, 0xe9, 0xe9, 0x76, 0xb1, 0x84, 0xda, 0x7a, 0x47, 0xf8, 0xc2, 0xe7, 0xd6, 0xda, + 0x3e, 0xeb, 0xcc, 0xe1, 0x2d, 0x9a, 0x7c, 0x8d, 0xba, 0x9f, 0xc1, 0x4f, 0xb4, 0x91, 0xf7, 0xdb, + 0x43, 0x95, 0x81, 0x6a, 0x7c, 0x71, 0x5a, 0x3e, 0x2d, 0x4d, 0x1b, 0xa7, 0xa4, 0x93, 0x5f, 0x0a, + 0x6a, 0x49, 0x07, 0x4d, 0xb4, 0x45, 0xe6, 0xee, 0x3d, 0x4a, 0x98, 0xe8, 0xcb, 0x27, 0x45, 0x37, + 0xc2, 0x96, 0x37, 0x8d, 0xbb, 0x6b, 0x6a, 0xd6, 0x1b, 0x44, 0x6c, 0x6e, 0x62, 0xf8, 0xc2, 0x1b, + 0x76, 0xad, 0x29, 0x1f, 0xe7, 0x97, 0xa6, 0xe3, 0x58, 0xf0, 0xfd, 0xab, 0xcc, 0xfb, 0xa2, 0xc6, + 0xb3, 0x7f, 0xcd, 0x91, 0xe3, 0x5f, 0xf8, 0xf2, 0xda, 0x6c, 0xd8, 0xa6, 0xcf, 0x93, 0x0b, 0xbe, + 0x08, 0x89, 0x97, 0x8d, 0x2f, 0xbe, 0x14, 0xc4, 0x33, 0xac, 0x7c, 0x34, 0x6d, 0x0e, 0xae, 0xe4, + 0xd4, 0xb9, 0x5c, 0x5f, 0x04, 0xb6, 0xd0, 0xb4, 0xd9, 0x97, 0x12, 0xfd, 0xf1, 0x44, 0x7d, 0x5d, + 0x5d, 0xb4, 0xbf, 0x76, 0x6d, 0xaf, 0x82, 0x9d, 0xa5, 0xdc, 0xbb, 0xdd, 0xfa, 0xf8, 0x9d, 0x5d, + 0x26, 0xed, 0x9b, 0x7d, 0xe1, 0xc3, 0xbf, 0x82, 0x2d, 0x2a, 0x51, 0x7c, 0x17, 0x69, 0xd3, 0xb4, + 0xfa, 0xf9, 0x77, 0x7f, 0x82, 0x19, 0x37, 0x7d, 0x7c, 0x69, 0x69, 0x0c, 0xad, 0x74, 0x9b, 0x2f, + 0x8d, 0xde, 0x6f, 0x1f, 0x17, 0xdb, 0x6d, 0xb6, 0xfc, 0x17, 0x6e, 0x92, 0x49, 0x5a, 0xb1, 0xf0, + 0xf1, 0xcf, 0x43, 0xd1, 0xaa, 0x8d, 0x46, 0x75, 0x67, 0xc1, 0xb5, 0xc5, 0x3c, 0xb7, 0x37, 0x5f, + 0xf0, 0x4b, 0xb6, 0x9f, 0x26, 0xb9, 0x91, 0xd7, 0x8c, 0x36, 0xac, 0xdb, 0xa4, 0x6e, 0xcd, 0xf5, + 0xe7, 0xc9, 0xfa, 0x3f, 0xcd, 0x65, 0x71, 0x95, 0xf0, 0xee, 0x9a, 0x55, 0x3c, 0x93, 0x63, 0xdd, + 0x6f, 0x95, 0x30, 0x89, 0x9c, 0xfd, 0xb4, 0xab, 0x96, 0xeb, 0x5f, 0x0e, 0xda, 0xf6, 0xb4, 0xa5, + 0xf6, 0x93, 0x6f, 0x5f, 0xd5, 0x55, 0x7c, 0x94, 0x53, 0xc1, 0x17, 0x82, 0x12, 0xbb, 0xfb, 0x3e, + 0x12, 0x25, 0x39, 0x7b, 0xbf, 0xe0, 0x94, 0xc9, 0x22, 0xd0, 0xea, 0xa9, 0x65, 0xf1, 0xc2, 0xe2, + 0xc6, 0x95, 0x9a, 0x7f, 0xdf, 0x88, 0xc3, 0xe1, 0x18, 0xea, 0xbf, 0x36, 0xa9, 0xcc, 0xc2, 0xb1, + 0xff, 0x09, 0xd6, 0xa9, 0x32, 0xbd, 0x9f, 0x26, 0x65, 0x3f, 0x05, 0xb3, 0xe3, 0xb5, 0xb6, 0xde, + 0xbe, 0x3a, 0xc6, 0x25, 0x83, 0x77, 0x12, 0xe6, 0xf7, 0x7f, 0x08, 0x5b, 0x4d, 0xb4, 0x2d, 0xd3, + 0x92, 0x49, 0x52, 0xc4, 0x08, 0x16, 0x53, 0x06, 0x02, 0x40, 0xc0, 0x60, 0x11, 0x79, 0x19, 0xc1, + 0xfc, 0x61, 0x09, 0xb7, 0x26, 0xd2, 0x4b, 0x76, 0xb2, 0xf5, 0x6f, 0xf0, 0x57, 0x76, 0x97, 0x1b, + 0xfb, 0xb4, 0x99, 0x2f, 0xf8, 0x80, 0x84, 0xdf, 0xd5, 0x7d, 0xdf, 0xc5, 0x13, 0x8d, 0xe0, 0x92, + 0xa8, 0x4b, 0x0f, 0xc2, 0x19, 0x7e, 0xd1, 0xb7, 0xa3, 0x6e, 0x5b, 0x39, 0xbf, 0x08, 0x9c, 0xba, + 0xdc, 0x7a, 0x92, 0x37, 0x7f, 0xad, 0x3d, 0x5d, 0x4e, 0x63, 0xe8, 0x3b, 0x7c, 0x14, 0x61, 0x5b, + 0x15, 0x57, 0x2e, 0x75, 0xf0, 0xa5, 0x84, 0x08, 0xde, 0x64, 0x25, 0xd2, 0xa6, 0x37, 0x96, 0x91, + 0xc4, 0x0d, 0x21, 0xd1, 0xd8, 0xe1, 0x01, 0x2a, 0x18, 0x1b, 0xe3, 0x40, 0xe9, 0xbe, 0x14, 0x2d, + 0x0c, 0x78, 0x75, 0x0d, 0xce, 0x38, 0xce, 0x53, 0x13, 0xd6, 0x04, 0xe3, 0x18, 0x99, 0xdb, 0xf3, + 0xdd, 0x1a, 0x77, 0xe1, 0x22, 0x32, 0x49, 0x14, 0xf0, 0x5a, 0xda, 0xe2, 0x4b, 0x41, 0x1e, 0xc7, + 0x23, 0x68, 0x5e, 0x10, 0x2e, 0x5c, 0x2e, 0x3e, 0x87, 0x3f, 0xd2, 0xf1, 0xf4, 0xde, 0xd6, 0x4c, + 0xa3, 0xd5, 0x7c, 0x41, 0x15, 0x55, 0x6d, 0x4d, 0xfc, 0x3c, 0x33, 0x24, 0x92, 0xfa, 0x66, 0xc2, + 0xc6, 0x05, 0x27, 0x52, 0xaa, 0x19, 0x49, 0x91, 0xbf, 0xbf, 0xdf, 0xf0, 0xf8, 0x96, 0xda, 0xcc, + 0xca, 0x7b, 0xc6, 0x06, 0x44, 0x99, 0xad, 0x92, 0xff, 0xff, 0x8d, 0xa4, 0x5e, 0x94, 0xb6, 0x4d, + 0xb5, 0xa1, 0xc8, 0xca, 0xaf, 0xea, 0x64, 0xe9, 0xb3, 0xff, 0x82, 0xc8, 0xd7, 0x43, 0xe6, 0x9d, + 0x36, 0x93, 0x4e, 0x90, 0xa1, 0x3e, 0x1f, 0x24, 0x71, 0xb9, 0xdf, 0x43, 0xbb, 0x77, 0x33, 0x2a, + 0xee, 0xef, 0xfe, 0x0a, 0xaa, 0xec, 0x6e, 0xde, 0xe5, 0xb7, 0x88, 0x9f, 0xd7, 0xc6, 0x94, 0xec, + 0x37, 0x28, 0xfd, 0x23, 0xb7, 0x22, 0x95, 0xba, 0x8e, 0x65, 0x26, 0xda, 0x3b, 0x8b, 0xb7, 0xff, + 0x0a, 0x77, 0x71, 0xca, 0xd6, 0xfd, 0xed, 0xa9, 0xb7, 0x54, 0xe8, 0xcf, 0xab, 0x11, 0xdf, 0xf0, + 0x41, 0x66, 0xcd, 0xe5, 0x61, 0x8d, 0x4d, 0x73, 0x25, 0x10, 0xd7, 0x55, 0x92, 0xaf, 0x4d, 0x34, + 0xd3, 0xf0, 0xf5, 0x27, 0x54, 0xb3, 0x74, 0x9f, 0x4a, 0x6e, 0xa5, 0x36, 0xa8, 0x93, 0x7f, 0xa6, + 0x9a, 0x69, 0xf8, 0x52, 0x33, 0xe8, 0xa4, 0xd8, 0x92, 0x4d, 0xb6, 0xda, 0x7b, 0x49, 0x69, 0x25, + 0x1f, 0xe3, 0x34, 0xa4, 0xd6, 0x9b, 0xd2, 0xa4, 0xd3, 0x4c, 0x93, 0x42, 0x7f, 0x04, 0x16, 0xd3, + 0xa6, 0xfa, 0x6e, 0xff, 0xbe, 0x9a, 0x69, 0xa7, 0xe1, 0x4b, 0xb2, 0x73, 0xf4, 0xcf, 0x73, 0x97, + 0xd6, 0x4d, 0x6e, 0x95, 0x9a, 0x9a, 0x33, 0x1f, 0xe0, 0x84, 0x9d, 0xd5, 0x8f, 0x82, 0xbb, 0x5b, + 0x74, 0xd5, 0xa4, 0x92, 0xb4, 0xc7, 0xc6, 0x52, 0x75, 0xad, 0x2e, 0x92, 0x4d, 0x1e, 0x7f, 0x8d, + 0xbe, 0x6e, 0x6e, 0x96, 0x4d, 0xb1, 0xbb, 0x49, 0xf2, 0xef, 0x32, 0x93, 0xac, 0x7f, 0xe0, 0x9c, + 0xe9, 0x24, 0x91, 0x9a, 0x9b, 0xb9, 0x32, 0x27, 0x7c, 0x10, 0x10, 0xad, 0x93, 0x6c, 0x90, 0xd2, + 0x3c, 0x37, 0x4d, 0x9c, 0x55, 0x5a, 0xff, 0x85, 0x2c, 0xb5, 0x2e, 0xe6, 0xb7, 0x73, 0x35, 0x2d, + 0x8e, 0xbe, 0x1f, 0xb7, 0x74, 0x92, 0x43, 0x48, 0xac, 0xab, 0x3e, 0xb7, 0x6c, 0xff, 0xfc, 0x18, + 0x5b, 0x67, 0x2f, 0xcf, 0x8c, 0xdf, 0x6d, 0xe9, 0xff, 0x82, 0xad, 0x34, 0x8f, 0x03, 0x34, 0x6e, + 0xc5, 0x1a, 0x8a, 0xcd, 0xdb, 0xf7, 0xf8, 0x29, 0xbe, 0x8f, 0xbd, 0x1c, 0x66, 0x8c, 0xf0, 0x7b, + 0x7c, 0xbe, 0x2f, 0x59, 0xb9, 0x1e, 0x69, 0x55, 0x07, 0xe1, 0xd9, 0xe0, 0x91, 0x9b, 0x51, 0x34, + 0xad, 0xc7, 0x6a, 0xad, 0x32, 0xde, 0xf1, 0xb1, 0xcb, 0xb8, 0xc2, 0xc4, 0xff, 0xf0, 0x5f, 0xdd, + 0xdb, 0xb6, 0xb2, 0xfa, 0xaa, 0xaf, 0x85, 0x04, 0x9c, 0x41, 0x60, 0x6f, 0x62, 0x91, 0x84, 0x11, + 0xe1, 0x87, 0x40, 0xde, 0x20, 0xd6, 0x58, 0x53, 0xa6, 0xdf, 0x08, 0x91, 0x92, 0x24, 0x4d, 0x9b, + 0xfe, 0xef, 0xe1, 0x4c, 0xda, 0x79, 0x73, 0xf4, 0xb7, 0x43, 0x75, 0xdd, 0x3d, 0x7c, 0x29, 0x7d, + 0xc1, 0x8d, 0x83, 0xb0, 0x7c, 0x57, 0x52, 0xdc, 0xfb, 0xb3, 0x57, 0x77, 0xc2, 0x22, 0x1b, 0xb2, + 0x79, 0x51, 0x13, 0x1d, 0xe5, 0x4f, 0x98, 0xfe, 0xc5, 0xac, 0x74, 0xfc, 0x16, 0xe9, 0xdd, 0xe6, + 0xc4, 0xd8, 0xf1, 0x00, 0x93, 0x55, 0xf7, 0xc1, 0x4d, 0x24, 0x8f, 0xdb, 0x92, 0x36, 0x94, 0x71, + 0xa6, 0xf9, 0x7c, 0x27, 0x63, 0x2d, 0x66, 0x0e, 0x0f, 0x4d, 0x3f, 0x05, 0x9a, 0x49, 0x53, 0x3f, + 0xfa, 0x49, 0x3f, 0xc1, 0x5d, 0xdf, 0x55, 0xa7, 0x63, 0x5c, 0x5f, 0x05, 0x77, 0xdb, 0x6f, 0x2f, + 0x11, 0xc2, 0x64, 0xb3, 0x08, 0x98, 0xe2, 0x10, 0x18, 0xc5, 0x8a, 0x77, 0xe2, 0xb6, 0x9a, 0x3e, + 0x3d, 0xcb, 0x9e, 0x33, 0x7b, 0x6b, 0xf3, 0xf8, 0xde, 0x4e, 0x8f, 0xa4, 0x78, 0xfe, 0x14, 0x29, + 0xf3, 0xbc, 0x55, 0x25, 0x08, 0xe9, 0x7c, 0xb8, 0x98, 0xda, 0xbf, 0xaf, 0x8c, 0x3d, 0xf0, 0xa5, + 0x99, 0x03, 0xe5, 0x9a, 0xdf, 0x15, 0x6f, 0xd9, 0x16, 0xd3, 0x88, 0x98, 0xc7, 0xc6, 0x5d, 0xad, + 0xe4, 0xee, 0xd7, 0xc9, 0x14, 0xa2, 0xe7, 0xab, 0x64, 0xec, 0x41, 0x43, 0xa5, 0xe1, 0x4c, 0x2d, + 0x0c, 0x9d, 0x01, 0xa3, 0x60, 0x82, 0xa8, 0x61, 0xc5, 0x16, 0xc4, 0xb9, 0x84, 0x11, 0xe8, 0x74, + 0xdc, 0x44, 0x29, 0xf6, 0x74, 0x8c, 0x8c, 0x72, 0x0e, 0x1a, 0xbd, 0x8c, 0x69, 0x36, 0x22, 0xe2, + 0xe4, 0x2c, 0xcd, 0xf1, 0x96, 0xfe, 0xa7, 0xb9, 0x70, 0xba, 0xb3, 0xe2, 0x2f, 0x49, 0x12, 0x2f, + 0x17, 0x1c, 0x93, 0xb7, 0x51, 0x75, 0x55, 0xc4, 0x16, 0x5d, 0x93, 0x37, 0x7f, 0x84, 0x29, 0xdb, + 0x69, 0xdb, 0x15, 0xe0, 0xd7, 0xf7, 0xf2, 0x08, 0xa3, 0x5f, 0x85, 0x8c, 0x86, 0xe3, 0x86, 0xce, + 0x47, 0x2e, 0x6b, 0xc6, 0x8e, 0x12, 0x33, 0x2e, 0xfd, 0x98, 0x34, 0xe5, 0xff, 0x18, 0x25, 0xba, + 0xbb, 0xa7, 0x49, 0xa7, 0x48, 0xbb, 0xa5, 0xf0, 0xc7, 0x73, 0x4a, 0x6d, 0x4f, 0x53, 0xf3, 0xeb, + 0xd7, 0xfe, 0x0a, 0xb6, 0xd2, 0x6c, 0x66, 0xaa, 0x3d, 0x22, 0xeb, 0x34, 0xba, 0xcd, 0x83, 0xe0, + 0xb0, 0x99, 0xfd, 0xb7, 0xcb, 0xdb, 0xbe, 0x74, 0xf8, 0xca, 0x49, 0x74, 0xd3, 0x4d, 0xba, 0x4e, + 0x9a, 0x2b, 0x7e, 0x0b, 0x26, 0xce, 0x5c, 0x59, 0xfb, 0x1b, 0x71, 0xba, 0x8c, 0xdf, 0x11, 0x8b, + 0x97, 0x75, 0x25, 0xf0, 0xf1, 0x6c, 0xdc, 0xb8, 0xce, 0xcc, 0xb4, 0x6e, 0xc7, 0x12, 0x9f, 0xab, + 0xaf, 0xfb, 0x23, 0x56, 0xfe, 0x30, 0xed, 0xdc, 0x9c, 0xf9, 0xed, 0x13, 0x3f, 0x26, 0xfe, 0x09, + 0x2d, 0x14, 0xcd, 0x28, 0xbe, 0x36, 0x5d, 0x71, 0xf3, 0xbd, 0xd9, 0xad, 0xe2, 0xc6, 0xab, 0xaa, + 0x93, 0x4e, 0x71, 0x59, 0x4f, 0x04, 0xff, 0xc6, 0x69, 0x35, 0x6c, 0xdc, 0xfb, 0xb4, 0x5f, 0xea, + 0x6d, 0x7f, 0xf0, 0xa5, 0x62, 0xd5, 0x53, 0x43, 0x47, 0x1f, 0x72, 0x6c, 0xe7, 0x32, 0xd8, 0xd2, + 0x47, 0x09, 0x8f, 0x85, 0x3b, 0xb7, 0x4d, 0x52, 0x8a, 0xd4, 0x9b, 0xe4, 0x47, 0x5e, 0x1e, 0x35, + 0x4b, 0xf4, 0xdd, 0xb5, 0x49, 0x52, 0xaf, 0xa6, 0x9a, 0x69, 0xf8, 0x29, 0xa5, 0x75, 0x9e, 0x19, + 0x76, 0x24, 0x8b, 0xb3, 0x1f, 0x15, 0x39, 0x8a, 0x95, 0xef, 0x73, 0xb3, 0xe2, 0xbb, 0x22, 0x6e, + 0x89, 0xfc, 0x10, 0x5b, 0x3f, 0xda, 0x48, 0xde, 0x27, 0x2e, 0x49, 0xb2, 0x93, 0xc6, 0xbf, 0xf0, + 0xfc, 0xd8, 0xd5, 0x24, 0xed, 0xee, 0xa4, 0xd9, 0x7a, 0xa6, 0xb5, 0xff, 0x05, 0x74, 0x98, 0x57, + 0x49, 0x26, 0xfd, 0xf5, 0x35, 0xf1, 0xd3, 0xd0, 0xcf, 0x4a, 0x93, 0x9a, 0x2f, 0x6d, 0xb5, 0xf8, + 0x30, 0x31, 0x77, 0xd2, 0x1f, 0x36, 0xc7, 0xf7, 0xcc, 0x3a, 0x3c, 0x7c, 0xf7, 0x7f, 0x85, 0x25, + 0xee, 0xd6, 0xdc, 0xfd, 0xb7, 0xe5, 0x99, 0x37, 0x71, 0xe1, 0x43, 0xb7, 0x84, 0x3a, 0xad, 0x63, + 0x6d, 0xf9, 0x51, 0xa7, 0x49, 0x37, 0x44, 0xd4, 0xbe, 0x13, 0x13, 0x48, 0xc6, 0x2d, 0x35, 0xcf, + 0xbe, 0x30, 0x93, 0x7f, 0xb6, 0x6f, 0x24, 0x59, 0x7b, 0x75, 0xf0, 0x5d, 0x76, 0xfd, 0xef, 0xaf, + 0x85, 0x29, 0xc7, 0x69, 0xdb, 0xc7, 0xe3, 0x37, 0xc1, 0x13, 0x4e, 0x7c, 0xab, 0x5f, 0x1e, 0x69, + 0xdd, 0xb1, 0x74, 0xe4, 0x82, 0x4d, 0x4b, 0x33, 0x18, 0x89, 0x65, 0xc6, 0x9b, 0xc7, 0x7f, 0xe2, + 0xce, 0x90, 0xd2, 0xe2, 0xc5, 0xeb, 0xe3, 0xb3, 0x6c, 0x9e, 0x70, 0x76, 0x3c, 0x9d, 0xaf, 0x1f, + 0x4d, 0x8c, 0xbf, 0x56, 0xb3, 0x30, 0x39, 0x51, 0xd8, 0x7b, 0x1e, 0x3b, 0x52, 0x79, 0x74, 0xa9, + 0xc6, 0xb7, 0xf1, 0x38, 0xb6, 0x9b, 0x1a, 0xa7, 0xf8, 0x4f, 0x2f, 0xa7, 0x63, 0x23, 0x2e, 0x6f, + 0x82, 0xaa, 0xde, 0x96, 0x5f, 0xb5, 0x69, 0xdf, 0x08, 0xe5, 0x82, 0x7a, 0x47, 0xc3, 0xfa, 0xb3, + 0xe3, 0x57, 0xe1, 0x2b, 0xa9, 0xf9, 0xfb, 0xbd, 0xb4, 0x33, 0xe7, 0x84, 0x6c, 0xd9, 0xb3, 0x66, + 0xc8, 0xbb, 0x39, 0xa8, 0x11, 0x99, 0x73, 0x35, 0xf8, 0x2c, 0x2a, 0x6d, 0x42, 0x54, 0xab, 0x0c, + 0xce, 0xc9, 0xb5, 0xba, 0xcd, 0xc5, 0x3f, 0xc3, 0x2b, 0x9f, 0x53, 0xf7, 0xc1, 0x5d, 0x03, 0x45, + 0x7a, 0xf3, 0x9f, 0x34, 0xe2, 0xc7, 0x0d, 0x89, 0xaf, 0xc2, 0x67, 0xe1, 0x4c, 0x99, 0x6f, 0x44, + 0x4d, 0x6e, 0xe7, 0xcc, 0xa7, 0x34, 0x95, 0xca, 0x8e, 0xb8, 0x90, 0x55, 0x2d, 0x5a, 0xcc, 0x69, + 0xe9, 0x14, 0xce, 0xa8, 0x8d, 0xb3, 0xdf, 0x9e, 0xc6, 0xfc, 0x56, 0x73, 0xef, 0x52, 0x27, 0x28, + 0x2c, 0xae, 0x4b, 0xbe, 0x3a, 0xee, 0xd3, 0x4c, 0x8b, 0x93, 0xe1, 0xa9, 0xb3, 0x67, 0xe1, 0x1b, + 0xc5, 0x6e, 0xd4, 0x98, 0xa4, 0xf1, 0xc9, 0x3b, 0xe1, 0x3b, 0xdf, 0x2f, 0x97, 0xae, 0x1e, 0x18, + 0x96, 0x92, 0xb0, 0xc4, 0x60, 0x5d, 0xa4, 0x44, 0x93, 0x70, 0x08, 0x71, 0x81, 0x7f, 0x6f, 0x1f, + 0xfc, 0x2f, 0x27, 0x1c, 0xce, 0xcd, 0x4b, 0x3f, 0x76, 0x7f, 0x97, 0xbf, 0x87, 0x4f, 0x55, 0x34, + 0xeb, 0x25, 0x34, 0x69, 0x0a, 0x9a, 0x55, 0xb7, 0x6f, 0x09, 0x7e, 0xc8, 0x91, 0xff, 0x0a, 0x6e, + 0x86, 0x67, 0xbe, 0x8b, 0xb6, 0xd6, 0x68, 0xd3, 0xa8, 0xbf, 0xcf, 0x0b, 0x1c, 0x5f, 0x04, 0x14, + 0x96, 0xd9, 0x9e, 0xd5, 0x76, 0xa9, 0x3a, 0xdb, 0x2f, 0xff, 0xc3, 0xd8, 0xff, 0xdf, 0xf2, 0xe2, + 0x75, 0x31, 0x99, 0x86, 0x26, 0x8b, 0x23, 0x46, 0x17, 0xf8, 0x2b, 0xb5, 0x8f, 0x6e, 0xd1, 0x61, + 0xb4, 0xe3, 0x1f, 0x0a, 0x5f, 0x52, 0x6a, 0x5b, 0xe5, 0xed, 0xcb, 0xd8, 0xdf, 0xee, 0x7c, 0x3f, + 0x6e, 0xd7, 0xa1, 0xa9, 0x62, 0x5e, 0xf8, 0xc2, 0x27, 0x3a, 0x21, 0x18, 0x7f, 0x82, 0x1b, 0x7b, + 0xdc, 0xf9, 0x4b, 0x56, 0x9b, 0xf0, 0xa1, 0x2f, 0x74, 0xad, 0x34, 0xdd, 0xb4, 0xe4, 0xa6, 0xef, + 0x8c, 0xc1, 0xe6, 0xf9, 0xb1, 0xb5, 0xa8, 0xb9, 0xde, 0x97, 0x93, 0xcd, 0xfc, 0x14, 0x53, 0xcd, + 0x86, 0xd5, 0xcb, 0xb4, 0xab, 0xc1, 0x2d, 0x3a, 0x79, 0x99, 0x43, 0x73, 0x04, 0x6f, 0x84, 0x3b, + 0x4d, 0x22, 0x68, 0xb9, 0x13, 0x19, 0x19, 0xfc, 0x44, 0xfe, 0xb6, 0xcd, 0xd3, 0xc6, 0xfe, 0x3a, + 0x46, 0x18, 0xfd, 0x91, 0x7e, 0x78, 0x34, 0x5f, 0x7e, 0x0a, 0x24, 0xb9, 0x7a, 0x74, 0xad, 0x33, + 0xe1, 0x49, 0x17, 0x8d, 0xf7, 0xa6, 0x37, 0xaf, 0xa4, 0xda, 0x4d, 0x34, 0x77, 0x1f, 0x05, 0xb6, + 0xf6, 0xed, 0xb6, 0xdc, 0x81, 0x1f, 0x04, 0x16, 0xdc, 0xfd, 0x6d, 0x0a, 0xc4, 0xac, 0x4f, 0x8b, + 0x69, 0xe4, 0xad, 0x55, 0x57, 0xfc, 0x28, 0x22, 0xf7, 0x63, 0x6d, 0x31, 0x8c, 0x47, 0xb6, 0x89, + 0x8c, 0x15, 0x04, 0xe7, 0xf8, 0x47, 0x9b, 0x9a, 0x32, 0x46, 0x9c, 0xf4, 0xbc, 0x13, 0xed, 0xa6, + 0x7e, 0x48, 0x46, 0x5f, 0xf9, 0xf0, 0x56, 0x5e, 0x34, 0xac, 0xc9, 0x8d, 0xbb, 0x4d, 0xda, 0x97, + 0xc2, 0x85, 0xb6, 0xe8, 0x79, 0xb6, 0x82, 0x48, 0xa6, 0x30, 0xb2, 0xf9, 0x7a, 0x7f, 0x12, 0x42, + 0xa9, 0x2d, 0x94, 0x7e, 0x0b, 0x08, 0x9d, 0x3a, 0x65, 0x8a, 0x6d, 0xf3, 0x99, 0xd6, 0xf8, 0xe2, + 0xa2, 0xa6, 0x37, 0x2d, 0xa3, 0xe5, 0xe6, 0xd6, 0xf4, 0xff, 0x0a, 0x49, 0xb4, 0xe9, 0xb3, 0x53, + 0x6f, 0x36, 0x9b, 0x4d, 0xb1, 0xe9, 0xb2, 0x36, 0xcc, 0x71, 0x16, 0x23, 0xbb, 0x5e, 0x0a, 0xfb, + 0x6a, 0x2e, 0x2e, 0xb8, 0xf2, 0xb6, 0x79, 0xfd, 0xf0, 0x5d, 0x57, 0x5b, 0x87, 0x69, 0x8e, 0x5e, + 0xff, 0x05, 0x65, 0xb1, 0x88, 0xb3, 0x47, 0x34, 0x94, 0xdf, 0x5b, 0x6c, 0x7c, 0xb6, 0x33, 0x35, + 0x8d, 0xec, 0x78, 0xba, 0x6a, 0xd6, 0xad, 0xb7, 0xc4, 0x88, 0x2b, 0xbb, 0xdd, 0xb4, 0x27, 0xe2, + 0x04, 0xfc, 0x74, 0xff, 0x1e, 0x5a, 0x8b, 0xee, 0xa6, 0x8f, 0x73, 0x3e, 0x7c, 0x64, 0xb2, 0x97, + 0xc6, 0x15, 0x12, 0xf9, 0x39, 0xf3, 0x9a, 0x3e, 0x32, 0x46, 0x71, 0xb3, 0x85, 0x63, 0xd1, 0xbb, + 0xe5, 0x93, 0x45, 0x89, 0x23, 0xed, 0x99, 0x9f, 0x09, 0xc7, 0x0d, 0xe8, 0xfa, 0x9e, 0x46, 0xf7, + 0x49, 0xd1, 0x64, 0x3c, 0x15, 0xcf, 0x04, 0xf2, 0x61, 0x33, 0xa2, 0x56, 0x4c, 0x9d, 0xf0, 0x8d, + 0xbd, 0xb7, 0x2e, 0x4b, 0x94, 0x55, 0xf1, 0x5c, 0x57, 0x61, 0xa4, 0xda, 0x03, 0xf7, 0x45, 0x7f, + 0x84, 0xe4, 0xb6, 0x63, 0x0e, 0xd3, 0x4b, 0xf0, 0x89, 0xd7, 0xac, 0xb3, 0x45, 0x41, 0xa6, 0x9a, + 0x69, 0xf8, 0xb2, 0x12, 0x3a, 0xd1, 0x3d, 0x7e, 0x5b, 0x6d, 0xb5, 0xf0, 0x5a, 0x66, 0xfb, 0x73, + 0x36, 0xc6, 0x46, 0xf1, 0x21, 0x01, 0x6f, 0x7b, 0xb9, 0x68, 0xdb, 0x2d, 0x0b, 0x4d, 0x7c, 0x24, + 0x43, 0xf7, 0x40, 0xdb, 0x0a, 0xa4, 0x93, 0x73, 0xc6, 0x8c, 0x4c, 0x68, 0xce, 0x68, 0xdd, 0x57, + 0x7e, 0xa4, 0xb4, 0x86, 0x97, 0xd2, 0x44, 0x9b, 0x92, 0xb2, 0xc5, 0x2c, 0x7f, 0xc2, 0x02, 0x50, + 0xed, 0x29, 0x58, 0xda, 0xcb, 0x1b, 0x19, 0xfb, 0x1f, 0xe3, 0x6d, 0xaf, 0x4c, 0xec, 0xec, 0x69, + 0x53, 0x75, 0xd9, 0xa8, 0xb5, 0xb2, 0x8a, 0x97, 0xf8, 0x48, 0x91, 0xb5, 0xdb, 0x19, 0x72, 0x87, + 0xe3, 0x77, 0x3f, 0xb5, 0x53, 0x1a, 0x1b, 0xa5, 0x9d, 0x8c, 0xef, 0x4e, 0x2b, 0xdd, 0xff, 0xc1, + 0x51, 0x49, 0x5f, 0x48, 0x8f, 0x7b, 0x5a, 0xcb, 0x34, 0xac, 0xb3, 0xa1, 0xd1, 0x95, 0x3e, 0x14, + 0xc2, 0xba, 0x39, 0xa5, 0x4f, 0x7b, 0x87, 0x51, 0xb9, 0x0a, 0xbb, 0x8c, 0xc6, 0x3e, 0x42, 0x36, + 0xad, 0xfc, 0x15, 0x4f, 0xee, 0xd2, 0xae, 0xd3, 0x5b, 0x1f, 0x09, 0xd5, 0xb6, 0x37, 0x35, 0x75, + 0xf1, 0xa5, 0x6d, 0x36, 0xd5, 0x92, 0x46, 0xed, 0xda, 0x4d, 0x37, 0xaa, 0x45, 0x8e, 0x71, 0x44, + 0x68, 0x3e, 0x1f, 0xe1, 0xdc, 0x1d, 0xac, 0x26, 0xee, 0x9e, 0xad, 0x1a, 0x5d, 0x57, 0x8d, 0x3f, + 0xf1, 0x99, 0x22, 0x6c, 0xe3, 0x59, 0x68, 0xef, 0x69, 0xd3, 0xfc, 0x3f, 0x83, 0x88, 0x89, 0x2d, + 0xcc, 0x2b, 0xa8, 0xef, 0x63, 0xe5, 0xdc, 0xca, 0xba, 0x6b, 0x2c, 0x25, 0x87, 0xf8, 0x6e, 0x6d, + 0xd2, 0xc5, 0x75, 0x6f, 0x67, 0xff, 0x19, 0x74, 0x8e, 0xf5, 0x6a, 0xd3, 0x2a, 0xec, 0x75, 0xa4, + 0x5d, 0x74, 0xaf, 0xe0, 0xb2, 0xad, 0x8e, 0xd2, 0xcf, 0x96, 0x8b, 0x8f, 0x61, 0xac, 0x51, 0xa9, + 0xa1, 0x4b, 0xe3, 0x79, 0x78, 0x7b, 0xd8, 0xe6, 0x7e, 0x9c, 0x1a, 0xc1, 0xa6, 0xd9, 0x98, 0xb1, + 0xac, 0x5f, 0xff, 0x0f, 0x93, 0x6d, 0xaa, 0xad, 0xda, 0xa7, 0x82, 0xe5, 0xf4, 0xff, 0xc7, 0xda, + 0x72, 0xf6, 0xc2, 0x4e, 0x86, 0xed, 0x36, 0x2c, 0x5c, 0x7e, 0x4b, 0xbf, 0xe0, 0xa8, 0xb5, 0x5b, + 0x78, 0xf2, 0xad, 0x6b, 0x50, 0xed, 0x31, 0xdf, 0x1a, 0x2b, 0x69, 0x0c, 0x31, 0xbd, 0xb9, 0x2d, + 0x3d, 0x37, 0x7a, 0x16, 0xa5, 0xe4, 0xd7, 0x52, 0xa7, 0x06, 0x3c, 0x80, 0xaa, 0xe7, 0xfc, 0x61, + 0x67, 0xda, 0x6e, 0x8a, 0x68, 0xda, 0x77, 0xcd, 0x08, 0xa9, 0xf8, 0xf8, 0xed, 0x2e, 0xa2, 0xe6, + 0xf4, 0xf1, 0x95, 0x8b, 0xc1, 0x10, 0x92, 0xe4, 0x46, 0xc8, 0xc5, 0x68, 0x53, 0xf0, 0x4c, 0x32, + 0x81, 0xc3, 0xb7, 0x1d, 0xed, 0xaf, 0x0f, 0x84, 0x06, 0x9f, 0xa4, 0xe5, 0xfa, 0x9a, 0xb5, 0xa7, + 0xe1, 0x3c, 0xfa, 0xca, 0xa6, 0x8a, 0xcd, 0x0f, 0xc1, 0x4d, 0xa3, 0x6b, 0x4e, 0xd7, 0x7a, 0xef, + 0xfd, 0x7a, 0xf8, 0x29, 0xd4, 0x25, 0xcb, 0x4e, 0xde, 0x33, 0x69, 0xe5, 0x12, 0x65, 0x91, 0x2c, + 0x35, 0x85, 0x20, 0x3a, 0xcf, 0x2c, 0xde, 0xf2, 0xc1, 0x93, 0x5f, 0xb2, 0x8d, 0xb7, 0xc1, 0x75, + 0xef, 0xab, 0x57, 0x7c, 0x75, 0xdb, 0xc7, 0xb0, 0xe6, 0x1c, 0x8b, 0x55, 0x55, 0xf1, 0x16, 0x64, + 0x74, 0xc7, 0x2a, 0x77, 0x9a, 0xfc, 0x7e, 0x3e, 0xd2, 0xb9, 0xf3, 0x3e, 0x3b, 0x5f, 0x1f, 0xd2, + 0x52, 0xeb, 0x2f, 0x37, 0xb7, 0x6f, 0x88, 0x04, 0x33, 0xe3, 0xc7, 0x6f, 0x84, 0x2e, 0x33, 0xe7, + 0x8b, 0x3f, 0x2f, 0xac, 0xf9, 0xc4, 0x8a, 0xaa, 0xad, 0x56, 0xbe, 0x32, 0xca, 0xaa, 0x21, 0xd8, + 0x7e, 0xbb, 0x0c, 0xaf, 0x91, 0x2c, 0x6c, 0x71, 0xb1, 0xf8, 0x46, 0xb9, 0x9e, 0xad, 0xe9, 0x32, + 0x4c, 0x9f, 0x51, 0x22, 0x46, 0x14, 0x31, 0x75, 0xdd, 0xdf, 0x50, 0xa2, 0xd1, 0xd7, 0x5c, 0x8c, + 0xf8, 0xad, 0x06, 0x48, 0x69, 0xbf, 0xe3, 0xc8, 0xdb, 0x56, 0x45, 0xd7, 0x64, 0x72, 0xac, 0xd7, + 0xe2, 0xb5, 0xb6, 0x9d, 0x12, 0x2f, 0x25, 0xb6, 0xf5, 0xc1, 0x51, 0x28, 0x6d, 0x32, 0xc6, 0x57, + 0xd2, 0xa5, 0x5f, 0x08, 0xef, 0x6d, 0xcb, 0x89, 0xee, 0x95, 0xaf, 0x09, 0x93, 0x76, 0xdd, 0xb9, + 0xbf, 0x8c, 0x3a, 0xd4, 0x7d, 0x76, 0x3b, 0xdb, 0xbf, 0x22, 0x84, 0x7c, 0x8d, 0xe4, 0x3f, 0xa5, + 0xe2, 0x22, 0xba, 0x95, 0x92, 0xeb, 0xb1, 0x7f, 0x0a, 0x11, 0xb9, 0x8d, 0x21, 0xa1, 0xd1, 0xe9, + 0x27, 0x97, 0xd3, 0xc6, 0x73, 0x94, 0x63, 0x6c, 0xbe, 0x0b, 0xb2, 0xbe, 0x4d, 0xaa, 0x5c, 0x3e, + 0x14, 0x2a, 0x49, 0xdd, 0xdb, 0xd6, 0xda, 0x67, 0xc4, 0xa3, 0x74, 0x1f, 0xb6, 0xdd, 0x30, 0x3e, + 0x14, 0xb6, 0x35, 0x35, 0xd7, 0x55, 0x06, 0xd8, 0x2d, 0xdd, 0xd2, 0x6e, 0x0e, 0x53, 0x48, 0x6d, + 0x19, 0x78, 0xcb, 0xf7, 0x1d, 0x5a, 0xb2, 0x61, 0xf2, 0xa6, 0xe4, 0x49, 0xd1, 0x91, 0x97, 0x33, + 0xe1, 0x4a, 0xaf, 0x1b, 0xaa, 0x8d, 0xd8, 0xe6, 0x09, 0xa9, 0x33, 0x5c, 0x7d, 0xbf, 0x6e, 0x03, + 0xfc, 0x33, 0x7c, 0x29, 0x4a, 0xce, 0xdf, 0x4d, 0xb6, 0xad, 0xe9, 0x27, 0x76, 0xcc, 0xdf, 0x08, + 0x46, 0xae, 0x33, 0xe7, 0x72, 0x76, 0x93, 0x54, 0xdf, 0xe3, 0x29, 0x2b, 0xd5, 0x74, 0xc5, 0x77, + 0xdd, 0xfc, 0x65, 0xb6, 0x87, 0xb3, 0x88, 0xed, 0x6b, 0x62, 0x8d, 0x91, 0xae, 0xb9, 0xfe, 0xed, + 0xf8, 0x77, 0xcb, 0x94, 0xe2, 0x76, 0x3b, 0x23, 0x65, 0x58, 0x64, 0xa4, 0xb4, 0xff, 0x19, 0x69, + 0x4e, 0xc5, 0x19, 0xb1, 0x8d, 0x0d, 0x4a, 0xc7, 0xe8, 0xde, 0xf9, 0x2b, 0xa6, 0xde, 0x7f, 0xe1, + 0x4a, 0x6a, 0x9e, 0x9a, 0x51, 0xca, 0x6e, 0x66, 0x7a, 0x3b, 0x23, 0xa4, 0x71, 0xe3, 0x2f, 0x84, + 0x2e, 0x38, 0x48, 0x65, 0x65, 0x15, 0xec, 0x49, 0x07, 0xc9, 0x67, 0xc2, 0x97, 0x6a, 0xa6, 0x89, + 0x3f, 0xc9, 0x22, 0x6e, 0xc6, 0x7f, 0x7e, 0x40, 0xf0, 0x85, 0x37, 0xf4, 0xd7, 0xad, 0x55, 0xd5, + 0x3c, 0xb1, 0xf1, 0xb3, 0x31, 0x5d, 0xb3, 0xb5, 0x8c, 0xb5, 0x8d, 0x0c, 0xac, 0x5c, 0x1c, 0x67, + 0xde, 0xfb, 0xb6, 0xbf, 0xe1, 0x4c, 0x19, 0x5e, 0x32, 0xb2, 0x5d, 0x5b, 0x4a, 0xb6, 0xb1, 0x46, + 0x56, 0x5e, 0xd3, 0x30, 0x56, 0x57, 0x55, 0x06, 0x46, 0xf8, 0x24, 0xb6, 0xd1, 0x77, 0xc3, 0xe3, + 0x2a, 0x8a, 0xc6, 0x19, 0xd5, 0x69, 0x5c, 0xf9, 0x68, 0xad, 0x2a, 0x63, 0x8b, 0xe1, 0x49, 0x9a, + 0xd2, 0x47, 0x69, 0xb1, 0x6a, 0x92, 0xb1, 0x54, 0xa1, 0x87, 0xea, 0x58, 0xe5, 0x55, 0xf1, 0xa2, + 0xb9, 0xbe, 0xa5, 0x65, 0x57, 0x77, 0xeb, 0x45, 0xee, 0x62, 0x8e, 0xfa, 0x25, 0x3c, 0xff, 0xc4, + 0x1e, 0x39, 0x19, 0xf9, 0x73, 0xc2, 0x9d, 0xcb, 0x96, 0x8d, 0xe2, 0x9f, 0x55, 0x9b, 0x97, 0xa6, + 0xdc, 0xcc, 0xf8, 0x21, 0xde, 0x96, 0x77, 0xc5, 0x53, 0x7e, 0x9c, 0xbf, 0xc1, 0x48, 0x82, 0xf3, + 0x30, 0x95, 0x0d, 0x11, 0x3a, 0x5c, 0x67, 0x5b, 0x1d, 0x17, 0xc2, 0x63, 0xdc, 0xdc, 0xcd, 0xe3, + 0x59, 0x6b, 0x84, 0x2a, 0xd3, 0x64, 0xc5, 0x7e, 0xed, 0xd3, 0x5e, 0x24, 0x15, 0xeb, 0x52, 0x0c, + 0x61, 0xe9, 0xc3, 0x6a, 0x9d, 0xfe, 0x0b, 0x36, 0x94, 0xac, 0x4a, 0xbb, 0xcf, 0x96, 0x8e, 0x9f, + 0x05, 0xdb, 0x4f, 0xb4, 0x7c, 0xaa, 0x2f, 0x82, 0x22, 0x3b, 0xa1, 0xa1, 0xc5, 0xe2, 0x41, 0x5d, + 0x8d, 0x8d, 0x8c, 0x7a, 0x9a, 0xd8, 0xce, 0xce, 0xad, 0x7f, 0xe2, 0xca, 0xf3, 0xfe, 0xa6, 0xdf, + 0x11, 0x2f, 0xd3, 0x32, 0xfb, 0x19, 0xf8, 0x27, 0xd6, 0xdb, 0x69, 0x9f, 0xe7, 0x51, 0xe2, 0x42, + 0x73, 0xf0, 0xe5, 0x72, 0xb1, 0xf7, 0x24, 0x75, 0xf0, 0x44, 0x56, 0x9a, 0x69, 0xa6, 0x3e, 0x3a, + 0x3a, 0xa7, 0xb9, 0x1f, 0x5a, 0x67, 0xd8, 0xcf, 0x44, 0x3f, 0xc6, 0x50, 0xd5, 0x0e, 0x18, 0x74, + 0x2c, 0xb8, 0xe7, 0xb9, 0x00, 0xcd, 0x1c, 0xcc, 0xc7, 0x7d, 0x3f, 0x19, 0xda, 0x36, 0x55, 0xcb, + 0xd2, 0x49, 0x24, 0x9d, 0xbd, 0x3f, 0xc7, 0xd3, 0xc7, 0xcb, 0x89, 0x26, 0x9a, 0x69, 0xf8, 0x4a, + 0x5f, 0x4c, 0xcc, 0xd4, 0x55, 0x1c, 0x8f, 0x8c, 0x22, 0x5b, 0x4a, 0x5c, 0x97, 0x13, 0x4e, 0x9a, + 0x51, 0x6a, 0x26, 0x2b, 0x6e, 0x76, 0x2f, 0x63, 0xf0, 0x89, 0x9e, 0xe3, 0x2b, 0x95, 0x85, 0x26, + 0xf1, 0xfc, 0x65, 0xf6, 0xa9, 0x5a, 0xc9, 0xb2, 0x3d, 0xb9, 0xaf, 0xe3, 0x29, 0xea, 0xfd, 0xb8, + 0xf6, 0x66, 0x93, 0x61, 0x9f, 0xbf, 0x88, 0x98, 0x4a, 0xe6, 0xfc, 0x40, 0x82, 0x3e, 0xab, 0xbf, + 0x82, 0xac, 0xf0, 0x6f, 0x77, 0x77, 0xac, 0xde, 0x56, 0x95, 0x78, 0x78, 0xcc, 0x27, 0x54, 0x5b, + 0x97, 0x03, 0x0d, 0x2a, 0x19, 0x09, 0xae, 0xda, 0xc2, 0x08, 0xfa, 0x4b, 0xbe, 0x8b, 0xfc, 0x16, + 0x1d, 0x37, 0xf2, 0x6a, 0xb5, 0x77, 0xf7, 0x5a, 0x6d, 0xe5, 0xf0, 0xa5, 0xdb, 0x14, 0x45, 0xef, + 0x7e, 0x49, 0x96, 0xdf, 0xbc, 0xc4, 0x96, 0xfc, 0x1f, 0x1d, 0x26, 0xda, 0x78, 0x36, 0x49, 0x0d, + 0x65, 0x4c, 0xb4, 0xbf, 0x1b, 0x63, 0x6a, 0x8d, 0x0e, 0x8e, 0x33, 0xb6, 0x33, 0x47, 0xe9, 0xb5, + 0x5b, 0x9f, 0xbf, 0xff, 0x96, 0xea, 0xeb, 0xe0, 0x98, 0x9a, 0x66, 0xe9, 0x44, 0x92, 0x5d, 0xf0, + 0x5c, 0x5d, 0xb4, 0x92, 0x4b, 0x8b, 0xe1, 0x1b, 0x2d, 0x57, 0x43, 0x6e, 0x9b, 0x7e, 0x16, 0x23, + 0xeb, 0x1a, 0xa2, 0x1e, 0xe4, 0x9e, 0x34, 0xd3, 0xff, 0x19, 0x49, 0xfa, 0xb0, 0x69, 0xe6, 0xc6, + 0xcc, 0xc7, 0xad, 0xfe, 0x4b, 0xb3, 0xb6, 0xf8, 0xf8, 0x47, 0x2f, 0xa7, 0x37, 0x6e, 0x1d, 0x5d, + 0x2f, 0x05, 0x65, 0xda, 0x6d, 0xa2, 0x33, 0xc7, 0x7d, 0xf2, 0x31, 0x1f, 0x06, 0x15, 0x7d, 0x3d, + 0xb4, 0xe9, 0xdb, 0xbf, 0xf8, 0xbb, 0x56, 0x9a, 0x2f, 0x5b, 0x5f, 0x05, 0x52, 0xbe, 0xcf, 0x2f, + 0xb2, 0x73, 0x7a, 0x07, 0xe5, 0xf0, 0x4d, 0x56, 0xd5, 0x52, 0x1b, 0x56, 0x3c, 0x97, 0xc3, 0x36, + 0xb4, 0x95, 0xb5, 0x6d, 0xff, 0xc2, 0x15, 0xbd, 0xbb, 0x76, 0x34, 0x8c, 0xdf, 0xc2, 0x82, 0xb8, + 0xd9, 0x8a, 0x2c, 0xba, 0x74, 0xd7, 0x50, 0xac, 0xfd, 0x55, 0x9f, 0x0a, 0x16, 0xf3, 0x58, 0x71, + 0x59, 0x0a, 0xc7, 0xe8, 0xdc, 0xb6, 0x86, 0xd2, 0xfb, 0x89, 0xdc, 0xbe, 0x3e, 0x94, 0xb7, 0xb7, + 0x27, 0xda, 0x74, 0xe9, 0xf8, 0x40, 0xf1, 0x95, 0xb3, 0x57, 0x4e, 0xe6, 0xef, 0xf8, 0xc3, 0x5a, + 0xa7, 0x64, 0x51, 0x82, 0xed, 0xa6, 0x9e, 0xb5, 0x10, 0xda, 0xfc, 0x15, 0x4a, 0x41, 0x6a, 0xb8, + 0x0b, 0xd3, 0x51, 0xbc, 0xee, 0x8e, 0x59, 0x57, 0x84, 0x4e, 0xcd, 0x5e, 0xb5, 0x6d, 0x3f, 0xc2, + 0x94, 0xf3, 0xb3, 0x57, 0x9f, 0xef, 0xbd, 0xd9, 0xf2, 0x1c, 0x75, 0x53, 0x23, 0xe2, 0xf2, 0x12, + 0xf7, 0xf1, 0x7a, 0x4d, 0xa7, 0x4e, 0x58, 0x79, 0x29, 0xd3, 0xf1, 0x22, 0xcf, 0xb1, 0xb9, 0x50, + 0x21, 0x87, 0x7a, 0x82, 0x0d, 0xf1, 0xbc, 0x78, 0x83, 0xf8, 0xd6, 0x95, 0xe8, 0x6e, 0x86, 0xfe, + 0x2c, 0xb2, 0x66, 0x98, 0xfd, 0xdf, 0xe1, 0x1a, 0xb4, 0xed, 0x4a, 0x6d, 0xa6, 0x65, 0x2f, 0x44, + 0xac, 0xf4, 0x86, 0x99, 0xc4, 0x85, 0x2c, 0x6e, 0xc7, 0xae, 0xdf, 0x33, 0x1f, 0x42, 0x4d, 0xce, + 0x8c, 0xfc, 0x11, 0x50, 0xdb, 0x8a, 0xb3, 0xa7, 0x88, 0x08, 0x17, 0x4d, 0x3b, 0xad, 0xd5, 0xd7, + 0xc7, 0xc4, 0xd8, 0x2b, 0x06, 0x61, 0xac, 0x39, 0x69, 0xd5, 0x5d, 0xfc, 0x7e, 0x8d, 0xd5, 0xdf, + 0x6d, 0xb6, 0xdb, 0xe2, 0x02, 0x26, 0x97, 0xbe, 0xc6, 0x66, 0x0c, 0xc3, 0x98, 0xac, 0xde, 0xba, + 0xfc, 0x49, 0x4b, 0x74, 0xf5, 0xce, 0xa7, 0xe1, 0x1a, 0x69, 0xa6, 0x99, 0x14, 0x7e, 0x5c, 0xf0, + 0x91, 0xaf, 0x36, 0xbb, 0x7f, 0xc6, 0x11, 0x5e, 0xfb, 0x27, 0xd2, 0x4d, 0x3c, 0x9b, 0xe3, 0x2d, + 0x35, 0xb4, 0xd1, 0xf2, 0xa9, 0x31, 0x2f, 0x5a, 0xf8, 0x42, 0x92, 0x55, 0x54, 0xd7, 0x26, 0xa4, + 0xcd, 0xf1, 0x9b, 0x6f, 0x9d, 0xed, 0xfd, 0xdc, 0xdd, 0x2c, 0xff, 0xcd, 0xe2, 0xbf, 0x04, 0xc5, + 0x77, 0xc5, 0x93, 0x21, 0x8f, 0x53, 0x3c, 0x9c, 0x4c, 0x66, 0x4c, 0xa5, 0xab, 0xd3, 0x57, 0x67, + 0xaf, 0x8c, 0x2b, 0xea, 0xf6, 0xa9, 0xe9, 0xa6, 0xc2, 0x69, 0xaf, 0x18, 0x44, 0xcb, 0xf7, 0x3f, + 0xbb, 0xe9, 0xd2, 0xf8, 0x25, 0x25, 0x69, 0x6c, 0x8a, 0xaf, 0x97, 0xc3, 0xbc, 0x9e, 0x9c, 0x38, + 0xad, 0xe8, 0x6e, 0x66, 0x6a, 0x53, 0x52, 0x35, 0xa7, 0xfe, 0x3c, 0x4c, 0x99, 0xea, 0x37, 0x49, + 0x6b, 0x39, 0x58, 0x4d, 0x70, 0xf1, 0x13, 0x2b, 0x12, 0xb1, 0x15, 0xfe, 0xdd, 0xba, 0xa7, 0x08, + 0xbe, 0x7f, 0xc4, 0xdc, 0xd8, 0x56, 0x1c, 0xc5, 0x0e, 0x56, 0x7c, 0x5e, 0x3b, 0x44, 0x3e, 0xa3, + 0x30, 0xd3, 0x3f, 0x96, 0x8d, 0x2b, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x03, 0x01, 0xb0, + 0x2e, 0xbd, 0x8f, 0xd2, 0x49, 0x71, 0xc4, 0x37, 0x62, 0xfc, 0x8a, 0x6a, 0x22, 0xc4, 0x8b, 0xd0, + 0xfc, 0xc7, 0xe6, 0xfe, 0x18, 0x10, 0xd5, 0x15, 0x4f, 0x9e, 0xb9, 0x1e, 0x7f, 0x15, 0x62, 0xaf, + 0xc1, 0x1d, 0xde, 0x57, 0x33, 0xe0, 0x8e, 0xef, 0x7c, 0x9d, 0x78, 0xd1, 0x12, 0xa8, 0x56, 0x28, + 0xb7, 0xb7, 0xb6, 0x76, 0x57, 0x64, 0xef, 0xde, 0xf1, 0x5f, 0xd7, 0x18, 0x11, 0xda, 0x6b, 0x69, + 0xad, 0xa6, 0xb6, 0x9a, 0x5c, 0xc5, 0xc7, 0x93, 0x1a, 0xe2, 0xcc, 0xd3, 0x5b, 0x4d, 0x6f, 0x11, + 0x5c, 0x38, 0x27, 0x1a, 0xf2, 0xaf, 0x15, 0x39, 0xb4, 0xdb, 0xfc, 0x41, 0x49, 0xc4, 0x93, 0xe7, + 0x20, 0xe9, 0x53, 0x4d, 0x34, 0xfd, 0xf1, 0x65, 0xda, 0x6b, 0x69, 0xaf, 0x0c, 0x17, 0x1a, 0xf2, + 0xaf, 0x6a, 0xbc, 0xab, 0xc9, 0x97, 0xe5, 0xd2, 0xef, 0x13, 0xe2, 0x02, 0x42, 0x29, 0xa4, 0xfa, + 0x49, 0x71, 0x07, 0xaa, 0x69, 0x90, 0xcb, 0x0c, 0xf9, 0x78, 0xfa, 0x75, 0x6b, 0x69, 0xad, 0xa6, + 0xb8, 0x90, 0x43, 0x69, 0xa2, 0x5b, 0x2c, 0x70, 0x1b, 0xf7, 0x88, 0xf1, 0x24, 0x9b, 0x1d, 0x87, + 0xc7, 0xe2, 0xe6, 0x17, 0x1a, 0xa5, 0x55, 0x38, 0x8a, 0xe2, 0x05, 0x6d, 0x35, 0xb4, 0xd7, 0x8b, + 0xb4, 0xd6, 0xd3, 0x59, 0x39, 0xe3, 0xa5, 0x4d, 0x34, 0xd3, 0xf5, 0x89, 0xae, 0x2c, 0xd8, 0x3e, + 0xa0, 0x3e, 0xa2, 0x06, 0x81, 0x8f, 0xa8, 0x3e, 0xa7, 0x87, 0x0c, 0x33, 0xf6, 0xc2, 0x6a, 0x5f, + 0x4d, 0x34, 0xd3, 0xc4, 0xc2, 0xfd, 0xa3, 0x62, 0x36, 0x5f, 0xbb, 0xf8, 0xb6, 0x2d, 0xf8, 0x7b, + 0x56, 0x76, 0x6e, 0xa1, 0xe9, 0x4d, 0x9d, 0x34, 0x94, 0x9a, 0x30, 0xa9, 0xc7, 0xfe, 0x16, 0x13, + 0xcf, 0x49, 0x97, 0xfa, 0x74, 0xcd, 0x26, 0xff, 0xf4, 0x57, 0x3e, 0x0b, 0xa7, 0x1e, 0xda, 0xb4, + 0xd6, 0x74, 0xf8, 0x54, 0x20, 0x6c, 0xae, 0xad, 0x29, 0x35, 0xf5, 0xca, 0x6a, 0x8d, 0xfa, 0xb3, + 0xbf, 0xc1, 0x37, 0x37, 0x77, 0x41, 0x9e, 0x5b, 0xfc, 0xe3, 0xc7, 0x6a, 0x69, 0xa6, 0x9f, 0xf9, + 0xe3, 0x83, 0xfe, 0x9a, 0x69, 0xa6, 0x5e, 0xb9, 0x32, 0x5d, 0x4a, 0x9f, 0x3c, 0x76, 0x64, 0xd5, + 0x4d, 0xb7, 0xfe, 0xa6, 0x59, 0xf0, 0x47, 0xe4, 0xa6, 0x5f, 0x16, 0x5d, 0x24, 0xb4, 0x92, 0xf0, + 0xad, 0xa6, 0xb6, 0x9a, 0xca, 0xbf, 0xb6, 0xda, 0x69, 0xf8, 0x76, 0xd3, 0x5b, 0x4d, 0x6d, 0x35, + 0x95, 0x7f, 0x6d, 0xb4, 0xd3, 0xf3, 0xfa, 0x9a, 0x6d, 0xb7, 0xfe, 0x15, 0xb4, 0xd6, 0xd3, 0x58, + 0xf2, 0xfe, 0x99, 0x7f, 0x82, 0xfd, 0x55, 0x6d, 0x35, 0x95, 0x7f, 0x6e, 0xb8, 0xd3, 0x5c, 0xf1, + 0xda, 0xdb, 0x6d, 0xb7, 0xfe, 0x78, 0xed, 0xae, 0xb6, 0xdb, 0xfc, 0x4f, 0x1e, 0xb1, 0x00, 0x27, + 0x45, 0x42, 0x26, 0x44, 0x4c, 0x88, 0x99, 0x3a, 0x67, 0x36, 0x9b, 0x7c, 0x2d, 0x6e, 0xdd, 0xbb, + 0x71, 0x19, 0x64, 0xdd, 0xba, 0xdb, 0xff, 0x38, 0xb4, 0xeb, 0xc6, 0x65, 0xa9, 0x97, 0xeb, 0xa1, + 0x89, 0xd7, 0x11, 0xf3, 0x8d, 0x4e, 0xbc, 0x72, 0x5a, 0xc9, 0x7f, 0xe8, 0x52, 0x75, 0xe1, 0x2e, + 0x2b, 0xc5, 0xf3, 0x75, 0x4a, 0xbc, 0x14, 0xe9, 0x53, 0xc2, 0xaa, 0xf1, 0x36, 0x37, 0xf8, 0x4b, + 0x8a, 0xf1, 0x7f, 0xce, 0x41, 0xd9, 0xd2, 0x69, 0xa6, 0x9f, 0xfa, 0xa7, 0x5e, 0xae, 0x7d, 0x69, + 0xd7, 0xaa, 0x55, 0xeb, 0x17, 0xc2, 0xa2, 0x36, 0x99, 0x9b, 0x1b, 0x57, 0x78, 0xb5, 0x55, 0xb7, + 0xfe, 0x1e, 0x28, 0x74, 0x62, 0x43, 0xbf, 0xae, 0x1b, 0xf3, 0x6e, 0x53, 0x4d, 0x34, 0xf9, 0x10, + 0x8e, 0xa7, 0xff, 0xc1, 0x3c, 0x98, 0x91, 0xa2, 0xdc, 0x25, 0x32, 0x62, 0x48, 0xff, 0x86, 0xac, + 0x64, 0xeb, 0x23, 0x55, 0x9f, 0x6d, 0xb3, 0xf7, 0xef, 0x89, 0x3c, 0xbb, 0x37, 0x36, 0x6b, 0x9d, + 0xfe, 0x11, 0x33, 0xba, 0xa9, 0x7d, 0x34, 0xd3, 0x4d, 0x34, 0xfc, 0x65, 0x24, 0x92, 0x48, 0x98, + 0x5c, 0x66, 0x37, 0x12, 0x49, 0x24, 0xa2, 0x89, 0x24, 0xbc, 0x6e, 0x57, 0x9b, 0x03, 0xb3, 0x70, + 0x5f, 0xa4, 0x97, 0x6e, 0xee, 0xf5, 0x4c, 0x99, 0x9b, 0x9b, 0x9b, 0x27, 0xc6, 0x88, 0xa8, 0xd1, + 0x1e, 0xc5, 0xdd, 0xa7, 0x8f, 0x6b, 0x4c, 0x9d, 0x72, 0xf6, 0x3f, 0xf0, 0x46, 0x26, 0xa3, 0xdf, + 0xa3, 0x72, 0xb1, 0x33, 0xf1, 0xe7, 0xda, 0x6b, 0x69, 0xad, 0xa6, 0xbc, 0x65, 0xaa, 0xb6, 0x9a, + 0xda, 0x6b, 0x69, 0xaf, 0xc7, 0x5a, 0x6b, 0x69, 0xad, 0xa6, 0xbe, 0x20, 0x47, 0x49, 0x2d, 0x24, + 0x97, 0x04, 0xa4, 0x25, 0x92, 0xf2, 0x10, 0x48, 0x41, 0xc6, 0x0a, 0x7d, 0x44, 0xa4, 0xae, 0x13, + 0x3e, 0xd3, 0x5b, 0x4d, 0x71, 0x18, 0xf4, 0x2e, 0x95, 0x7e, 0x15, 0xcb, 0x25, 0xcb, 0x27, 0x38, + 0xc1, 0xe5, 0x4d, 0x34, 0xd3, 0xf7, 0xc7, 0x4d, 0x99, 0xf0, 0xd8, 0x6c, 0xcd, 0x91, 0x7d, 0x75, + 0x4e, 0x9f, 0x19, 0x69, 0xad, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0xf1, 0x16, 0x9a, 0xda, 0x6b, 0xf5, + 0x22, 0x7d, 0x6a, 0xba, 0xd5, 0x73, 0xc5, 0x00, 0x0b, 0x48, 0xba, 0x9c, 0x7f, 0xe3, 0x7b, 0x4d, + 0x6d, 0x35, 0xb4, 0xd6, 0xd3, 0x5f, 0x3e, 0x9a, 0x6d, 0xb7, 0xe0, 0xa6, 0xd3, 0x5b, 0x4d, 0x6d, + 0x35, 0x99, 0x3e, 0x0b, 0x6d, 0x35, 0xb4, 0xd6, 0x3b, 0x7c, 0x12, 0xf6, 0x9a, 0xda, 0x68, 0xe8, + 0x65, 0x7a, 0x26, 0x5c, 0x23, 0x1f, 0x8a, 0xb8, 0xab, 0x97, 0x24, 0xc9, 0x72, 0x4c, 0xc4, 0x09, + 0x05, 0x5d, 0x22, 0xe9, 0x44, 0x07, 0xd5, 0x69, 0xbb, 0xfc, 0x10, 0xcd, 0x4b, 0xa9, 0x7b, 0xe7, + 0x28, 0xea, 0xbb, 0xbb, 0xff, 0x8a, 0x23, 0x59, 0x28, 0x5e, 0xce, 0x5f, 0xf8, 0x23, 0xa7, 0x4e, + 0x54, 0xf8, 0x6a, 0x6e, 0xfe, 0x6e, 0xfe, 0x8f, 0x7d, 0x55, 0x57, 0xc1, 0x6e, 0xd3, 0x54, 0x96, + 0xdb, 0xbe, 0x1d, 0x14, 0x85, 0x9f, 0x3d, 0x49, 0xd6, 0x54, 0xff, 0xcb, 0x4b, 0xd5, 0x3f, 0x97, + 0x9c, 0x7a, 0x3c, 0xfa, 0x69, 0xa6, 0x9f, 0x9e, 0x8f, 0xfa, 0x69, 0xa6, 0x9f, 0x8a, 0xdd, 0x77, + 0x5b, 0xe1, 0x1e, 0xd3, 0x5b, 0x4d, 0x1b, 0xbf, 0xbb, 0xbf, 0xf8, 0xd1, 0xdb, 0xb8, 0x6a, 0x99, + 0xa2, 0xa6, 0x74, 0x83, 0xe3, 0x5e, 0x56, 0x58, 0xac, 0x51, 0xa8, 0x5a, 0xa4, 0x0b, 0x24, 0xf3, + 0x56, 0x2a, 0x64, 0x31, 0xb6, 0x5a, 0x4f, 0x82, 0xca, 0xd6, 0xf1, 0x05, 0x46, 0x0d, 0xca, 0x19, + 0x6a, 0x15, 0x1f, 0xe7, 0x7c, 0xa3, 0xf2, 0x2f, 0xc3, 0x38, 0x4b, 0x89, 0x3f, 0x98, 0x5b, 0x6c, + 0x1b, 0xb9, 0xda, 0x9a, 0x6d, 0xb4, 0xb9, 0xc6, 0xa4, 0x5e, 0x37, 0x2d, 0x5c, 0xbf, 0xf0, 0x54, + 0x31, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0x89, 0xd7, 0x83, 0x0b, 0x07, 0x49, 0x26, 0xb4, 0x88, 0x91, + 0x6c, 0x5b, 0xff, 0xc1, 0x45, 0x03, 0x40, 0xcf, 0x8f, 0xc6, 0x9a, 0xe5, 0x47, 0x5e, 0x0a, 0x2d, + 0x34, 0xd3, 0x4d, 0x34, 0xd3, 0x59, 0x7c, 0x29, 0xa5, 0x26, 0x4b, 0x99, 0xb3, 0x7e, 0x5a, 0x6a, + 0xd6, 0x5f, 0x3c, 0x74, 0xad, 0xb6, 0xdb, 0x7f, 0xe1, 0x81, 0x55, 0x6b, 0xb6, 0x1c, 0x95, 0xe9, + 0xcf, 0x03, 0xb5, 0xd3, 0xe9, 0x6b, 0xf8, 0x7c, 0x43, 0xba, 0xa9, 0x4d, 0x7b, 0x4c, 0xd0, 0x34, + 0x4d, 0xa7, 0x5f, 0x92, 0xcf, 0x7f, 0x85, 0x09, 0x69, 0x90, 0xa9, 0x63, 0x4b, 0x61, 0xef, 0xbf, + 0x52, 0x4c, 0xa9, 0x17, 0x8d, 0xb3, 0x2d, 0x09, 0x44, 0x58, 0x91, 0x08, 0x50, 0x72, 0xba, 0xcc, + 0xb0, 0xdc, 0x71, 0x92, 0x9e, 0x07, 0x24, 0xa5, 0xfe, 0x4e, 0x20, 0x32, 0xd3, 0x5b, 0x4d, 0x67, + 0xc4, 0x78, 0x8e, 0x22, 0x22, 0xd3, 0x5b, 0x4d, 0x7e, 0x63, 0x4a, 0x48, 0x5d, 0xd8, 0xb8, 0x46, + 0xa8, 0x1b, 0x52, 0x53, 0x2e, 0x29, 0x29, 0xfc, 0x15, 0xeb, 0x2d, 0x2a, 0x5b, 0xf5, 0x5f, 0x2b, + 0x88, 0x12, 0x92, 0x5e, 0x92, 0x44, 0xe3, 0x89, 0x4e, 0x9d, 0xb9, 0x59, 0x6d, 0x33, 0x76, 0x31, + 0xe1, 0x8d, 0x89, 0xa3, 0xaa, 0xb1, 0x34, 0x5b, 0x47, 0x4f, 0xa6, 0x9a, 0x69, 0xf8, 0x4a, 0x75, + 0x43, 0xe9, 0xac, 0x4f, 0x5d, 0xb4, 0xab, 0xf8, 0x57, 0x1e, 0x3b, 0x76, 0xfa, 0x3a, 0xb1, 0xbb, + 0x1b, 0xaa, 0xaa, 0xf8, 0x22, 0x24, 0xde, 0x6f, 0xe7, 0xc1, 0x00, 0xaa, 0xba, 0x6a, 0xaa, 0xa6, + 0x92, 0x98, 0xce, 0xea, 0xa9, 0xb8, 0x3f, 0xff, 0xe5, 0x16, 0xf6, 0x8e, 0x2b, 0x4c, 0xda, 0xe1, + 0x12, 0xe9, 0x25, 0xa4, 0x96, 0x92, 0x5e, 0x1d, 0x93, 0x39, 0x68, 0x2e, 0x4c, 0xab, 0xc9, 0x4a, + 0x90, 0xc9, 0x0c, 0xa7, 0x1f, 0xf8, 0x2e, 0xb4, 0xd6, 0xd3, 0x5a, 0x41, 0xe2, 0x04, 0x74, 0x92, + 0xd2, 0x4b, 0x88, 0x11, 0xd2, 0x4b, 0x49, 0x2f, 0x17, 0x69, 0xad, 0xa6, 0xbf, 0x1b, 0xda, 0x6b, + 0x69, 0xad, 0xa6, 0xb6, 0x9a, 0x1d, 0x2a, 0x69, 0xa6, 0x9f, 0xf8, 0x28, 0xb4, 0xd6, 0xd3, 0x59, + 0x13, 0xe1, 0xa0, 0x80, 0xb9, 0xb0, 0x44, 0x40, 0x50, 0x5c, 0xcd, 0x88, 0xfc, 0xda, 0x8f, 0xf5, + 0x7f, 0x8d, 0xd5, 0xa9, 0x85, 0xce, 0x68, 0xbd, 0xb0, 0x56, 0x5b, 0x88, 0xb2, 0x69, 0x33, 0x9b, + 0xd9, 0x89, 0xb7, 0xef, 0x76, 0x7e, 0x34, 0x9a, 0xcd, 0xf7, 0xa2, 0xcc, 0x5c, 0x92, 0x19, 0xc3, + 0x4f, 0xc2, 0xd3, 0x37, 0x6b, 0x92, 0x3f, 0xda, 0x8b, 0x65, 0xa4, 0x2c, 0xf7, 0xf8, 0x50, 0xea, + 0xb2, 0xab, 0x5b, 0x62, 0x5e, 0xa9, 0x31, 0xad, 0x69, 0x43, 0xd0, 0xd3, 0xb4, 0xdc, 0x38, 0x6a, + 0x86, 0x3e, 0xe8, 0xab, 0xc7, 0x31, 0xfe, 0x0a, 0x04, 0x2a, 0x64, 0x31, 0x76, 0x12, 0x68, 0x1b, + 0x08, 0x60, 0x92, 0xaf, 0x1a, 0x62, 0xec, 0x77, 0xd4, 0xeb, 0xf7, 0xa6, 0xda, 0xbe, 0x6c, 0xba, + 0xe3, 0x2c, 0x87, 0x3b, 0x69, 0x2b, 0x0d, 0xb6, 0xff, 0xc1, 0x4d, 0xf6, 0xea, 0x4b, 0xa2, 0xf3, + 0x9d, 0x08, 0xb4, 0x4c, 0xfb, 0x56, 0xac, 0x93, 0x3e, 0x08, 0x23, 0x3f, 0x8b, 0x1b, 0xfe, 0xa4, + 0xe7, 0xd3, 0x46, 0xbf, 0xf0, 0xeb, 0xd7, 0xf8, 0xe7, 0x78, 0x99, 0x59, 0x5d, 0xaa, 0x16, 0x6b, + 0xa7, 0xd5, 0x2b, 0x1f, 0xfc, 0x28, 0x19, 0xda, 0x6b, 0x69, 0xa1, 0x46, 0x28, 0xc4, 0xb8, 0x7b, + 0x9b, 0x4d, 0x25, 0x1f, 0x04, 0xb6, 0x9a, 0xda, 0x6b, 0xaa, 0xe8, 0x8f, 0x27, 0x18, 0x53, 0xff, + 0x6c, 0xfe, 0xb6, 0xcd, 0xdb, 0xfc, 0x4f, 0xae, 0x8c, 0xff, 0x0a, 0x72, 0xe1, 0x73, 0x2e, 0x17, + 0x0e, 0x41, 0x79, 0x07, 0x79, 0x05, 0xe4, 0x1c, 0x46, 0x45, 0x5c, 0x48, 0x28, 0xe7, 0x20, 0x9c, + 0x83, 0x9c, 0x82, 0x72, 0x0b, 0xfc, 0x54, 0xb9, 0xe4, 0xcf, 0xc1, 0x7f, 0x36, 0x1b, 0x1a, 0x9b, + 0x1a, 0xea, 0x69, 0xa6, 0x9f, 0xf9, 0x67, 0xc3, 0xe1, 0xb1, 0xd9, 0xe0, 0x83, 0x92, 0x99, 0x72, + 0x5a, 0x79, 0x71, 0x1d, 0xfb, 0x6d, 0xb6, 0xdf, 0xa2, 0x9e, 0x55, 0xeb, 0x94, 0xbc, 0xd2, 0xf2, + 0x72, 0xf6, 0x7f, 0x17, 0xd2, 0x4b, 0x49, 0x2f, 0x64, 0x1c, 0xcb, 0xa9, 0x3f, 0x05, 0x76, 0x95, + 0xa3, 0x61, 0xf1, 0xf8, 0x7c, 0x7e, 0x1f, 0x55, 0x7d, 0x6e, 0xcd, 0x7c, 0xf2, 0x08, 0xaf, 0xea, + 0xb5, 0xf0, 0xd6, 0x75, 0x9a, 0xc4, 0xf1, 0x60, 0x2f, 0x1c, 0x5f, 0xfc, 0x2c, 0x21, 0x62, 0x45, + 0x7a, 0x45, 0x96, 0x9a, 0x12, 0x73, 0xe6, 0xf5, 0xf8, 0x81, 0xed, 0x35, 0xb4, 0xd6, 0xf8, 0x42, + 0xd3, 0x5b, 0x4d, 0x6d, 0x35, 0xf1, 0x27, 0x20, 0xfa, 0x9a, 0x69, 0xa7, 0xfe, 0x58, 0xac, 0x56, + 0x2b, 0x15, 0xf1, 0x02, 0xcb, 0xa4, 0x96, 0x92, 0x5e, 0x33, 0xb4, 0xd5, 0xb6, 0x97, 0x69, 0xad, + 0xa6, 0xb8, 0x80, 0x97, 0x49, 0x2d, 0x24, 0xbc, 0x23, 0x1f, 0x8d, 0xfb, 0x4d, 0x6d, 0x35, 0xf8, + 0x21, 0x09, 0x1f, 0x63, 0xce, 0x9f, 0x1b, 0x1e, 0xf4, 0x74, 0x04, 0x31, 0x2b, 0x77, 0x1b, 0xcf, + 0x0b, 0xbb, 0xc4, 0x08, 0x49, 0xb6, 0x89, 0x5b, 0xdf, 0x91, 0x9c, 0xb7, 0x59, 0x14, 0x3a, 0xad, + 0xa6, 0x83, 0x32, 0x7e, 0x09, 0xc8, 0xa8, 0xfe, 0x59, 0xf7, 0xc3, 0xf6, 0x94, 0x9e, 0x55, 0x5c, + 0x92, 0x98, 0xbc, 0x72, 0xf6, 0xd2, 0xfa, 0x76, 0xe6, 0xff, 0x28, 0x5f, 0x49, 0x25, 0xc2, 0x76, + 0x9a, 0xda, 0x6b, 0xe2, 0x02, 0x7d, 0x24, 0xb4, 0x92, 0xf3, 0x19, 0xa2, 0x41, 0x14, 0x1f, 0x87, + 0x82, 0x4d, 0x34, 0x58, 0xf0, 0x8a, 0xd9, 0x0a, 0x8c, 0x4e, 0x5a, 0x99, 0xa7, 0x1a, 0x5f, 0xcd, + 0xcd, 0xff, 0x11, 0x75, 0x1f, 0x09, 0x8d, 0x98, 0xea, 0x4f, 0xe1, 0x51, 0xb4, 0x28, 0xdc, 0x75, + 0x36, 0x48, 0xb9, 0x54, 0x2e, 0x29, 0xfa, 0x69, 0xa6, 0x9f, 0x98, 0x60, 0x4c, 0xfb, 0xb5, 0x5c, + 0x02, 0x27, 0xef, 0x82, 0x5b, 0x0a, 0xa2, 0xd6, 0x40, 0x77, 0xee, 0xe7, 0xaa, 0xe1, 0xe0, 0xbb, + 0x55, 0x6d, 0x35, 0xb4, 0xd6, 0x8f, 0x3e, 0xdb, 0x6d, 0xb7, 0xe3, 0x7b, 0x4d, 0x5b, 0x69, 0x76, + 0x9a, 0xda, 0x69, 0xbf, 0x76, 0xcf, 0xf8, 0x8f, 0x82, 0x7b, 0x4d, 0x74, 0xe9, 0xc5, 0xf3, 0xe2, + 0xa6, 0x9b, 0x6d, 0xff, 0x9e, 0xa9, 0xa6, 0x73, 0x2f, 0x33, 0xfe, 0x18, 0xa4, 0x96, 0x92, 0x49, + 0x25, 0xea, 0x69, 0xd6, 0xdf, 0xf8, 0x30, 0xb4, 0x7c, 0xf3, 0xe1, 0xf2, 0x2a, 0x69, 0xb6, 0xdb, + 0x6d, 0x9c, 0xcb, 0xcc, 0xae, 0x73, 0x52, 0x2f, 0x36, 0x9b, 0x75, 0xc1, 0x27, 0x55, 0x7f, 0x9e, + 0x44, 0x93, 0x49, 0xbf, 0xfb, 0xbb, 0xaa, 0xf9, 0x0b, 0x8d, 0x79, 0x57, 0xbc, 0xf1, 0xda, 0x9a, + 0x69, 0xa7, 0xfe, 0xa3, 0xb7, 0xc4, 0xcf, 0xfb, 0xa0, 0x71, 0x79, 0x79, 0x36, 0xa3, 0xd4, 0xf5, + 0x8b, 0xe1, 0x9c, 0x98, 0x5c, 0x6e, 0x45, 0xc7, 0xae, 0xc7, 0xfe, 0x08, 0xae, 0xcc, 0xd9, 0x6f, + 0x82, 0x28, 0x87, 0x9f, 0x0d, 0x8e, 0xc2, 0x21, 0x67, 0xd4, 0xaa, 0xf8, 0x60, 0x52, 0x21, 0x94, + 0x3f, 0x76, 0x93, 0x97, 0xd6, 0xa6, 0xfe, 0x15, 0x17, 0xc9, 0x99, 0x31, 0x21, 0xda, 0x9a, 0x69, + 0xa7, 0xfe, 0x2e, 0x4c, 0x26, 0x64, 0xc2, 0x66, 0xa2, 0x04, 0x2a, 0x38, 0x32, 0xf5, 0xab, 0xe0, + 0x9c, 0x20, 0xa2, 0xfa, 0x8b, 0x5b, 0x45, 0x43, 0x86, 0xd4, 0x31, 0xbc, 0xb9, 0x8f, 0x12, 0x36, + 0x51, 0x63, 0x08, 0x77, 0xf8, 0x07, 0xd2, 0x7e, 0x4a, 0x7f, 0xaa, 0x85, 0x2f, 0x37, 0xe3, 0x17, + 0xaa, 0x4e, 0xe9, 0xc6, 0x29, 0xb2, 0x02, 0xb7, 0x7d, 0x5b, 0x46, 0xbe, 0x14, 0xe2, 0xe3, 0xb9, + 0x3a, 0x88, 0xba, 0xcd, 0x61, 0x92, 0xaa, 0xad, 0x8d, 0x8a, 0x37, 0x73, 0xb8, 0xe6, 0x9f, 0xe6, + 0x33, 0xe0, 0xb0, 0x4a, 0xae, 0x6c, 0xb9, 0x2d, 0x57, 0x7f, 0x82, 0xd1, 0x6d, 0x35, 0xb4, 0xd7, + 0x15, 0x70, 0x95, 0xa6, 0xb6, 0x9a, 0xfc, 0x68, 0x41, 0x55, 0x55, 0x90, 0x42, 0xc4, 0xec, 0x2c, + 0xbb, 0x6d, 0xb5, 0x44, 0xb2, 0xc5, 0x0e, 0x34, 0xf7, 0x51, 0x93, 0x9e, 0x6a, 0x35, 0xff, 0x1c, + 0x67, 0x68, 0x75, 0x59, 0x43, 0x5f, 0x39, 0xd3, 0xda, 0x96, 0xd5, 0x34, 0xd0, 0x7e, 0x14, 0x1e, + 0x9b, 0x26, 0xea, 0xe6, 0x51, 0x31, 0x59, 0xbb, 0xfd, 0xae, 0xa2, 0xd9, 0x57, 0x84, 0x4c, 0x7d, + 0x26, 0xcf, 0xa6, 0xce, 0x7d, 0xa3, 0x36, 0xd7, 0xe1, 0x91, 0x03, 0x75, 0xc1, 0x6d, 0x2f, 0x8e, + 0x76, 0xa3, 0xbf, 0x41, 0x72, 0x27, 0xc1, 0x44, 0xd8, 0x6c, 0x3e, 0x3f, 0x1a, 0x6b, 0xbf, 0xd4, + 0x88, 0xcb, 0xc2, 0xa7, 0x07, 0x5d, 0x07, 0x5d, 0x31, 0xd7, 0x41, 0xd7, 0x4c, 0x88, 0x7c, 0x9a, + 0x4d, 0xce, 0x69, 0xe6, 0x8e, 0x69, 0xe6, 0x97, 0x0d, 0x11, 0xa1, 0xd5, 0xc6, 0xff, 0x6c, 0xfa, + 0xdd, 0x7e, 0x88, 0x8e, 0x9f, 0x56, 0x9b, 0x96, 0x4a, 0x59, 0xca, 0x1c, 0x24, 0x07, 0x13, 0xf9, + 0x6d, 0xb6, 0xf6, 0xdb, 0xff, 0x18, 0xa4, 0x86, 0x48, 0x66, 0xe9, 0xa7, 0x9b, 0x9e, 0x3e, 0xaa, + 0xaa, 0xfa, 0xe7, 0x28, 0x10, 0x3a, 0x5b, 0x0a, 0xb0, 0x81, 0x98, 0x43, 0x58, 0xff, 0x05, 0x82, + 0x16, 0xab, 0xa3, 0x13, 0xe5, 0xac, 0xe8, 0xfe, 0xf8, 0x20, 0xe1, 0xe5, 0x39, 0x65, 0x1b, 0x4c, + 0xd5, 0xd9, 0x46, 0x51, 0x78, 0xc5, 0x55, 0x49, 0x9f, 0xe0, 0xba, 0xab, 0x2b, 0x93, 0x0b, 0x82, + 0xf9, 0x17, 0x87, 0x88, 0x9a, 0x12, 0x66, 0x9a, 0x76, 0x55, 0x33, 0xec, 0xbc, 0x76, 0xf9, 0xb9, + 0x7b, 0x69, 0xf8, 0xde, 0xcd, 0x4d, 0x8d, 0x1f, 0xca, 0x9a, 0x69, 0xa6, 0xab, 0x26, 0x7c, 0x76, + 0xd3, 0x4c, 0xdf, 0xfc, 0x14, 0x56, 0x6a, 0x0b, 0xac, 0x94, 0x47, 0xff, 0x8b, 0x39, 0x2c, 0x97, + 0xc9, 0x64, 0xbf, 0xc5, 0xc9, 0x64, 0xbc, 0x96, 0x4b, 0xfc, 0x5c, 0x96, 0x4b, 0xc9, 0x64, 0xbf, + 0xc3, 0x12, 0x59, 0x2f, 0x25, 0x92, 0xf0, 0x12, 0x02, 0xd3, 0x4d, 0x34, 0xff, 0xde, 0xe4, 0xc9, + 0x5d, 0x7b, 0xe0, 0x8a, 0x42, 0x09, 0x08, 0x3d, 0x32, 0xf0, 0xc7, 0x31, 0x23, 0x12, 0xcc, 0x48, + 0xc4, 0xbb, 0xe6, 0x34, 0x63, 0x49, 0xc7, 0xe7, 0x80, 0x08, 0xed, 0x34, 0xd3, 0x4d, 0xb6, 0xdb, + 0x6f, 0xc1, 0x58, 0x41, 0x7d, 0x55, 0xbd, 0x88, 0x53, 0x98, 0xaf, 0xa0, 0x33, 0xd7, 0x2f, 0x85, + 0x26, 0x4f, 0xa1, 0x8f, 0xac, 0x57, 0x1b, 0xc4, 0x0d, 0xf0, 0x73, 0x12, 0xf6, 0xa8, 0xdb, 0xe1, + 0x0b, 0x10, 0x0e, 0x42, 0xb5, 0x4f, 0x37, 0x93, 0x16, 0xd3, 0x28, 0xfc, 0xe1, 0x57, 0xfa, 0x69, + 0xa6, 0x9f, 0x86, 0x72, 0x61, 0x31, 0x98, 0xbe, 0x9a, 0x64, 0x32, 0xc3, 0x3e, 0x09, 0x0c, 0x6e, + 0x8b, 0xe3, 0x15, 0xe1, 0xd0, 0x82, 0xb2, 0xe7, 0xee, 0xb6, 0xa9, 0x60, 0xc7, 0xa8, 0x8f, 0xad, + 0x1b, 0xba, 0xd7, 0xc1, 0x58, 0x97, 0x2a, 0xd7, 0x67, 0x47, 0x0a, 0x68, 0xc4, 0xfb, 0x62, 0x7d, + 0xde, 0xbe, 0x3f, 0x55, 0xe3, 0x92, 0xfa, 0x8b, 0x43, 0x9f, 0x68, 0x60, 0x7c, 0x14, 0x8a, 0xac, + 0x94, 0xa9, 0xde, 0x7d, 0xfb, 0x61, 0x99, 0x25, 0x5a, 0xf8, 0x26, 0x0a, 0xb0, 0x35, 0x7e, 0xd4, + 0x4d, 0xf2, 0xd5, 0xc4, 0x1d, 0xaa, 0xb6, 0x9a, 0xcb, 0xc1, 0x05, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, + 0x7f, 0xb6, 0xda, 0x69, 0xbe, 0x2e, 0xd3, 0x5b, 0x4d, 0x7e, 0x22, 0xd3, 0x5b, 0x4d, 0x6f, 0x10, + 0x27, 0xa4, 0x96, 0x92, 0x5e, 0x3a, 0xd1, 0xf6, 0xdb, 0x4d, 0x6d, 0x35, 0xf8, 0xac, 0x29, 0x51, + 0x85, 0xf0, 0xa5, 0x46, 0x17, 0xf1, 0x5c, 0xb9, 0xcb, 0x97, 0xc6, 0x88, 0x49, 0x24, 0x84, 0x38, + 0xef, 0x6e, 0xb2, 0xee, 0xaa, 0xee, 0x3a, 0x5f, 0x6d, 0xb6, 0xdb, 0xf0, 0xc5, 0x57, 0x7a, 0xaa, + 0xa6, 0x9a, 0x69, 0xb6, 0xdb, 0x6d, 0xf8, 0x20, 0xbe, 0xef, 0x5d, 0xd5, 0x72, 0x74, 0xee, 0xef, + 0xfe, 0x1e, 0x2a, 0x45, 0x20, 0xa5, 0xa4, 0x95, 0x2b, 0x56, 0x92, 0x3f, 0x55, 0x4f, 0xe1, 0x8b, + 0x46, 0xc6, 0xf6, 0x8f, 0x8d, 0x63, 0xd5, 0x54, 0xdb, 0xff, 0x82, 0x09, 0x49, 0x14, 0x94, 0xa4, + 0x8f, 0xdb, 0x2e, 0xbb, 0x8b, 0xf3, 0x07, 0x6c, 0x55, 0x4d, 0xdd, 0xff, 0xc1, 0x38, 0x8c, 0xe4, + 0x4e, 0x45, 0xaa, 0x9a, 0x69, 0x2a, 0xf0, 0x85, 0xa6, 0xbb, 0x06, 0xc1, 0xb4, 0xd0, 0xff, 0xbf, + 0xe2, 0x0a, 0x53, 0x55, 0xcf, 0x51, 0xfa, 0xef, 0xf8, 0x27, 0xd3, 0x74, 0xda, 0x68, 0x4f, 0x2a, + 0x4c, 0xbc, 0x12, 0xcf, 0x87, 0xc9, 0xea, 0xa9, 0xa6, 0x93, 0x0f, 0x87, 0xbb, 0x4d, 0x5d, 0x5d, + 0xa6, 0xb6, 0xfb, 0xa6, 0x9a, 0x7e, 0x52, 0x97, 0x93, 0xb4, 0xf5, 0x1e, 0x1a, 0x23, 0x4a, 0xb3, + 0x88, 0x25, 0x6e, 0x9d, 0x33, 0x72, 0x63, 0x75, 0x78, 0xd2, 0x5a, 0xa6, 0xd3, 0x4d, 0x1b, 0x0d, + 0xb1, 0xb4, 0xad, 0x3b, 0x07, 0x16, 0x30, 0x09, 0x92, 0x19, 0x3e, 0xd3, 0x61, 0xbf, 0xf0, 0xb9, + 0x6f, 0x57, 0x7b, 0xaa, 0x69, 0xc6, 0x9b, 0x6d, 0xb6, 0xdf, 0x82, 0x9e, 0xee, 0xaa, 0xab, 0x8f, + 0x79, 0x77, 0x84, 0xcb, 0x3e, 0xa3, 0xb1, 0xd3, 0xe1, 0x8a, 0xaa, 0xae, 0xaa, 0x74, 0x93, 0x49, + 0xbf, 0xf1, 0x1f, 0x0c, 0x94, 0xf8, 0x7c, 0x36, 0x3b, 0x07, 0x95, 0x34, 0xd3, 0x4f, 0xd7, 0x34, + 0xd8, 0x6c, 0x36, 0x3b, 0x17, 0x1e, 0x64, 0x79, 0x69, 0x2f, 0xa0, 0xf9, 0x69, 0xe1, 0x41, 0x54, + 0x3a, 0xa4, 0x48, 0x38, 0x31, 0x37, 0x48, 0x89, 0x4c, 0xdf, 0x43, 0x67, 0x8f, 0x56, 0xa4, 0x74, + 0x7b, 0xe0, 0xac, 0x95, 0x66, 0x74, 0x7d, 0x8d, 0xe8, 0xa3, 0x15, 0x6c, 0xcd, 0x33, 0x5c, 0x58, + 0x5d, 0xa6, 0xb6, 0x9a, 0xfc, 0x30, 0x10, 0xa5, 0x68, 0x70, 0x67, 0xe3, 0x9b, 0xb0, 0x66, 0xe4, + 0xdb, 0x5f, 0xf0, 0xa1, 0x81, 0x13, 0xdd, 0xb9, 0x78, 0xcd, 0xc2, 0xca, 0x58, 0xee, 0x44, 0x4c, + 0x6b, 0xdb, 0xe0, 0x90, 0xa3, 0xd3, 0x2b, 0xde, 0xb5, 0x3f, 0x09, 0x7c, 0x3a, 0x63, 0xe3, 0xb0, + 0x83, 0xf7, 0xab, 0x87, 0x1c, 0x6f, 0xa6, 0xb8, 0xfe, 0xff, 0x92, 0x83, 0x1d, 0xfb, 0x0b, 0xb4, + 0x82, 0xd2, 0x0b, 0xb3, 0x37, 0x0a, 0x89, 0x07, 0x5d, 0x01, 0xd7, 0x4c, 0x1d, 0x74, 0x07, 0x5d, + 0x32, 0x24, 0x9a, 0x4d, 0xff, 0xc1, 0x20, 0xa6, 0x8f, 0xb1, 0xe5, 0xaf, 0x94, 0x45, 0x35, 0xd3, + 0x5f, 0x85, 0x6a, 0x8d, 0xba, 0x55, 0x4a, 0x14, 0x9f, 0x3f, 0xff, 0x04, 0xdb, 0x43, 0x8a, 0xed, + 0x6f, 0x8f, 0x4c, 0xfc, 0x20, 0x2e, 0x4c, 0xe4, 0xcc, 0x84, 0xb3, 0xe7, 0x84, 0xe6, 0xc3, 0x66, + 0x6c, 0x36, 0x6f, 0x8a, 0x9b, 0x0d, 0x99, 0x49, 0x14, 0x96, 0xf9, 0x0a, 0xd3, 0x5b, 0xe1, 0xc9, + 0xb0, 0xd8, 0x7c, 0x7e, 0x0e, 0x4a, 0xdb, 0x6d, 0xb7, 0xfe, 0x08, 0x04, 0x3b, 0xaa, 0xb4, 0xd5, + 0x4d, 0x23, 0x46, 0xe6, 0xeb, 0xe9, 0xa6, 0x9a, 0x7e, 0x0a, 0x6a, 0x5a, 0x35, 0x7e, 0x5a, 0x26, + 0xb6, 0xa9, 0xdf, 0x82, 0x5c, 0x72, 0xcb, 0xda, 0xfa, 0xa8, 0x3a, 0x36, 0x3f, 0xfc, 0x32, 0x56, + 0x8f, 0x88, 0x1b, 0xed, 0xbe, 0x6e, 0xdf, 0xe2, 0x79, 0xc8, 0x27, 0x20, 0xe9, 0x13, 0x3c, 0x9a, + 0x64, 0xc6, 0x67, 0xab, 0x57, 0x08, 0xd3, 0x4c, 0x84, 0x2c, 0x21, 0x2e, 0x17, 0x09, 0x8c, 0xc6, + 0xe3, 0x71, 0x98, 0xcc, 0xf0, 0x4b, 0x6c, 0xdf, 0xa4, 0x96, 0x99, 0xf9, 0x29, 0xa4, 0x4d, 0xfc, + 0x17, 0x10, 0x9d, 0xbd, 0x6d, 0xd5, 0xd5, 0x95, 0xc3, 0xa5, 0x17, 0xee, 0xd7, 0x69, 0xb5, 0xda, + 0x6e, 0x7e, 0x6e, 0xfe, 0xab, 0x6e, 0xbf, 0xe1, 0xd3, 0x1b, 0x0f, 0x8e, 0xc7, 0xe3, 0x4d, 0x54, + 0xd2, 0x77, 0x54, 0xf2, 0xf9, 0xff, 0xe0, 0x8c, 0xa2, 0xfc, 0x02, 0x5f, 0x11, 0x3d, 0x0f, 0x4c, + 0xf4, 0x3d, 0x3f, 0x08, 0x16, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0xe2, 0x02, 0x7b, 0x69, 0x25, 0xa4, + 0x97, 0xa9, 0x53, 0xe3, 0x2d, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x7e, 0x33, 0xb4, 0xd5, 0xb6, + 0x97, 0x69, 0xad, 0xa6, 0xbc, 0x12, 0x5a, 0x6b, 0x8b, 0xe0, 0x80, 0x55, 0xab, 0xe8, 0x67, 0x6a, + 0x09, 0x3c, 0xd0, 0x18, 0xa6, 0x5a, 0x96, 0x9e, 0xe7, 0xfe, 0x34, 0x40, 0xce, 0x9f, 0xa1, 0xb3, + 0x87, 0x97, 0x22, 0xf6, 0x1b, 0x37, 0xd3, 0xc3, 0x4a, 0x83, 0x95, 0x61, 0x53, 0x85, 0x18, 0xe9, + 0xff, 0xe0, 0xb3, 0x6c, 0xdb, 0x59, 0x22, 0xad, 0x61, 0xb8, 0xd8, 0x39, 0x1e, 0xf5, 0xdb, 0x4a, + 0x1e, 0x36, 0x04, 0x1d, 0x43, 0xde, 0x7b, 0xdc, 0x18, 0x55, 0xbf, 0xab, 0x4f, 0x44, 0x7d, 0x5f, + 0x9d, 0x18, 0xf1, 0xaa, 0xc3, 0x84, 0xab, 0x4d, 0x36, 0xdf, 0xf8, 0x53, 0x9f, 0x8d, 0x69, 0xb0, + 0x82, 0x22, 0x41, 0xa3, 0x7c, 0x56, 0x8e, 0x28, 0x0e, 0xf5, 0xf0, 0x40, 0x44, 0x47, 0x9b, 0x1f, + 0x25, 0x1a, 0xad, 0x65, 0x7b, 0x64, 0x79, 0x3c, 0xbd, 0xff, 0xff, 0x05, 0x67, 0x7d, 0xe5, 0xe9, + 0x93, 0x19, 0xab, 0x56, 0x21, 0xbc, 0x72, 0x30, 0x2c, 0xf0, 0xf8, 0x64, 0x41, 0xf5, 0x84, 0xe5, + 0x1c, 0x61, 0xf2, 0x50, 0x94, 0xfc, 0x60, 0x64, 0xa4, 0x8a, 0x49, 0x03, 0x80, 0xd2, 0x4b, 0xd2, + 0x4b, 0x49, 0x27, 0xc2, 0x16, 0x9a, 0xda, 0x6b, 0x69, 0xaf, 0xc6, 0x76, 0x9a, 0xda, 0x6b, 0x69, + 0xad, 0xa6, 0xbc, 0xe4, 0x1d, 0xa9, 0xa6, 0x9a, 0x7f, 0xe1, 0x53, 0x34, 0xd3, 0x4d, 0x34, 0xd3, + 0x4d, 0x57, 0x52, 0x7f, 0xf0, 0x57, 0xda, 0x69, 0x24, 0xb4, 0x8b, 0x8f, 0xff, 0xe1, 0x6a, 0xae, + 0xd1, 0xb2, 0xb1, 0x54, 0x14, 0xd4, 0x1b, 0xd7, 0xeb, 0x82, 0x13, 0x93, 0x93, 0x93, 0xc6, 0xef, + 0xad, 0x7c, 0x36, 0x44, 0xd3, 0x4d, 0x32, 0x90, 0x1b, 0x97, 0xa6, 0xdb, 0x6d, 0xb7, 0xe1, 0x62, + 0xcf, 0x86, 0xc7, 0x63, 0x55, 0x34, 0xd4, 0xa9, 0xa6, 0x9a, 0x7f, 0xe1, 0x02, 0xb4, 0xd6, 0xd3, + 0x5b, 0x4d, 0x7e, 0x23, 0xa4, 0x96, 0x92, 0x5e, 0x10, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x6b, 0x88, + 0xb4, 0xd6, 0xd3, 0x5a, 0xc4, 0x57, 0x0b, 0x10, 0x5f, 0x9f, 0x0f, 0x8e, 0xc7, 0x60, 0xec, 0x76, + 0xaa, 0xaa, 0x9a, 0x69, 0xa7, 0xe1, 0xa9, 0xfb, 0xb9, 0xfb, 0xba, 0x3b, 0xf5, 0x55, 0x5f, 0x05, + 0x32, 0xff, 0x26, 0x13, 0x26, 0x24, 0x4a, 0x12, 0x9a, 0x03, 0x8f, 0x9c, 0xe8, 0xe3, 0xf3, 0xf2, + 0xf3, 0x63, 0x3f, 0x82, 0xaa, 0x4b, 0x6e, 0x9d, 0x3a, 0x74, 0xdf, 0xe0, 0xae, 0x9e, 0x9d, 0x3a, + 0x74, 0xea, 0xd3, 0xfc, 0xe4, 0x1e, 0x72, 0x9a, 0x69, 0xa7, 0xfe, 0x2f, 0x9f, 0x0f, 0x99, 0xf0, + 0xf9, 0xe8, 0xa8, 0xf2, 0xf8, 0x70, 0xcd, 0x19, 0x89, 0x98, 0x47, 0x7e, 0xe3, 0xea, 0xf7, 0xea, + 0x31, 0xaf, 0x86, 0x66, 0x5f, 0x43, 0x40, 0xec, 0xaa, 0xd7, 0xfd, 0x14, 0xe9, 0x5c, 0x31, 0xd2, + 0x4b, 0x49, 0x2a, 0xa6, 0x9b, 0x6d, 0xff, 0xa9, 0xd3, 0xe6, 0xe9, 0x25, 0xe1, 0x5b, 0x4d, 0x6d, + 0x35, 0xa8, 0xb6, 0x2d, 0xff, 0xe3, 0x6d, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x6a, 0x2d, 0x8b, + 0x6b, 0xff, 0x04, 0xe6, 0x3e, 0x65, 0x38, 0xcd, 0x3e, 0x34, 0x46, 0x19, 0x43, 0x17, 0xc2, 0x82, + 0x86, 0xcc, 0x40, 0xe8, 0x6c, 0x66, 0x6d, 0x74, 0xac, 0xde, 0x95, 0x22, 0xe1, 0x35, 0xb8, 0x73, + 0xbe, 0x36, 0xda, 0xb7, 0x73, 0x0d, 0x64, 0xec, 0x79, 0x62, 0x33, 0x7a, 0x37, 0x32, 0x25, 0xdd, + 0xa3, 0xb8, 0xb6, 0xdb, 0x6d, 0xff, 0x85, 0x34, 0x9f, 0xad, 0x8e, 0x25, 0xda, 0x24, 0x7f, 0x0e, + 0xf9, 0x83, 0xc6, 0xd5, 0xdc, 0x4f, 0x1d, 0xcb, 0xe9, 0x49, 0x97, 0x85, 0x31, 0x66, 0x67, 0xa8, + 0xe6, 0x50, 0x3e, 0x4c, 0x4b, 0x26, 0x75, 0xf1, 0xc5, 0x4d, 0xb1, 0xab, 0x99, 0x52, 0x6d, 0x37, + 0xc9, 0xfe, 0x0b, 0x23, 0xfe, 0xa1, 0x3d, 0xaf, 0x5e, 0xe8, 0x99, 0x67, 0x96, 0x3e, 0x75, 0xe1, + 0x41, 0x95, 0x12, 0x75, 0x2f, 0x56, 0x9d, 0x80, 0xe9, 0xdc, 0x92, 0xa6, 0x8c, 0x84, 0x45, 0x46, + 0x8e, 0xff, 0x28, 0x56, 0xd1, 0xb2, 0xa5, 0xc4, 0x17, 0x69, 0xad, 0xa6, 0xbc, 0x65, 0xa6, 0xb6, + 0x9a, 0xda, 0x6b, 0x69, 0xaf, 0xc5, 0xda, 0x6b, 0x69, 0xaf, 0xc6, 0xda, 0x6b, 0x69, 0xad, 0xa6, + 0xb6, 0x9a, 0xc8, 0x91, 0x89, 0x6a, 0x25, 0xff, 0xf8, 0x20, 0x11, 0x6e, 0x6e, 0xd9, 0xf5, 0xba, + 0xde, 0xb6, 0xdb, 0x3d, 0x95, 0x55, 0xff, 0x39, 0xd4, 0x0f, 0x52, 0xc7, 0xff, 0xc1, 0x1e, 0x75, + 0xe7, 0x5f, 0x2f, 0x85, 0xe8, 0x53, 0xfe, 0x4f, 0x2a, 0x50, 0x4a, 0x9a, 0x6a, 0xaa, 0xa4, 0xe1, + 0xbb, 0xe9, 0x0e, 0xdf, 0x77, 0x77, 0x5d, 0x7b, 0xeb, 0x1e, 0xf8, 0x48, 0xb8, 0xaf, 0x17, 0xf8, + 0x9c, 0x42, 0xcd, 0xc4, 0x5a, 0x6b, 0x69, 0xaf, 0xc1, 0x45, 0x24, 0xb4, 0x92, 0xd1, 0xc0, 0x1a, + 0x0d, 0xa1, 0x3f, 0xfc, 0x6a, 0x5a, 0xa9, 0x7f, 0x3a, 0x47, 0xe5, 0xaf, 0x97, 0xff, 0xe2, 0xcc, + 0x92, 0x5a, 0x49, 0x78, 0x98, 0xa2, 0x69, 0x25, 0xa4, 0x97, 0x96, 0x4c, 0x26, 0x37, 0x1b, 0x9e, + 0x5e, 0x92, 0x5e, 0x1a, 0xb4, 0xd6, 0xff, 0x27, 0x65, 0x43, 0xf0, 0x44, 0x45, 0x4f, 0x6f, 0xab, + 0x7c, 0x35, 0x27, 0x2f, 0x27, 0x6f, 0x14, 0x03, 0xd4, 0xd3, 0x4d, 0x35, 0x55, 0x5f, 0x0c, 0x59, + 0x29, 0xb2, 0x2a, 0x69, 0x55, 0x34, 0xd3, 0x4f, 0xfc, 0x61, 0x74, 0x92, 0xd2, 0x49, 0x83, 0x60, + 0xd2, 0x49, 0x83, 0x60, 0xd2, 0x4b, 0xc3, 0x84, 0x31, 0x04, 0xc4, 0x1e, 0xa9, 0xa6, 0x99, 0x3f, + 0xf8, 0x28, 0x9b, 0x3c, 0xf7, 0x68, 0xa9, 0xf0, 0x51, 0xda, 0x68, 0xf4, 0x3d, 0x38, 0x3b, 0x57, + 0xc1, 0x00, 0xa1, 0x9a, 0x3f, 0x34, 0x27, 0x7d, 0x08, 0x56, 0x1a, 0xa6, 0x3d, 0x86, 0xb8, 0xbd, + 0xe2, 0xb8, 0xaf, 0xc2, 0x26, 0x54, 0xdf, 0x9a, 0xa5, 0x66, 0x7f, 0x1a, 0x25, 0xb7, 0xe0, 0xa8, + 0xbb, 0xd6, 0x39, 0x46, 0xc6, 0x5e, 0x1e, 0xac, 0x7e, 0x32, 0x3b, 0x72, 0xa7, 0xc6, 0x43, 0xbf, + 0x57, 0x63, 0x74, 0x3b, 0x3d, 0x4d, 0x16, 0x17, 0x15, 0xb7, 0x6c, 0x3e, 0xad, 0x78, 0x52, 0x9a, + 0x45, 0xde, 0xb1, 0x75, 0x37, 0x74, 0x2b, 0x34, 0x7d, 0xb7, 0xf8, 0xcc, 0x59, 0xb2, 0x4d, 0xa6, + 0xb3, 0x75, 0xc5, 0xfc, 0x28, 0x7e, 0x58, 0x31, 0x9f, 0x13, 0xb3, 0x61, 0x9b, 0xec, 0x5a, 0xb6, + 0x9b, 0xe1, 0x41, 0x91, 0xbb, 0xaf, 0x54, 0x18, 0xe1, 0x82, 0x08, 0xf7, 0x55, 0x4b, 0x5a, 0x46, + 0xdd, 0xb5, 0xb6, 0xad, 0xf2, 0x8b, 0x35, 0xa2, 0x51, 0x34, 0xf4, 0x0f, 0x1a, 0x89, 0x71, 0x63, + 0x5a, 0x6b, 0x69, 0xaf, 0xcc, 0x4c, 0xd8, 0x6c, 0xf0, 0xe9, 0x37, 0x77, 0x7d, 0xca, 0xcf, 0x83, + 0x54, 0x89, 0x9f, 0xe1, 0x0b, 0x4d, 0x67, 0xa1, 0xe9, 0x9e, 0x87, 0xa7, 0xe0, 0x9b, 0x26, 0x9b, + 0x3d, 0xda, 0x5d, 0x7c, 0x51, 0x4a, 0xa2, 0x55, 0x12, 0x28, 0x91, 0x47, 0xc7, 0x94, 0xbe, 0x88, + 0x9a, 0xb1, 0x0a, 0x9e, 0x9d, 0x3a, 0x7e, 0x15, 0xb7, 0x6e, 0xdd, 0xbb, 0xfc, 0x5d, 0x45, 0xd7, + 0xc1, 0x6e, 0x9a, 0x43, 0x2b, 0xa4, 0x93, 0x7d, 0x75, 0xf0, 0xb9, 0x09, 0xcb, 0xc9, 0xdb, 0xf4, + 0xd3, 0x7f, 0xbb, 0xbb, 0xbe, 0x7f, 0x5d, 0xdd, 0xfd, 0x75, 0x6f, 0x9c, 0xf4, 0xe9, 0xb6, 0xdb, + 0x6f, 0xfc, 0x2f, 0x69, 0xad, 0xa6, 0x84, 0xa4, 0x4f, 0x48, 0x91, 0x0f, 0xfa, 0x69, 0xa6, 0x9f, + 0x82, 0xf1, 0x0e, 0xed, 0x1f, 0x15, 0x79, 0x12, 0x9a, 0x62, 0x26, 0x4e, 0x99, 0xff, 0x5f, 0xc9, + 0xc5, 0x89, 0xd2, 0x4b, 0x49, 0x2f, 0x04, 0x9c, 0xf6, 0xd1, 0x5b, 0xe6, 0x20, 0xaf, 0xfa, 0xb4, + 0x9c, 0x91, 0x5f, 0xf4, 0x74, 0x5f, 0xf0, 0x89, 0x1b, 0xb7, 0xda, 0x69, 0xb9, 0xf5, 0xaf, 0x0b, + 0xda, 0x3e, 0xdb, 0x68, 0xfb, 0x6d, 0x4f, 0xd8, 0x53, 0xf4, 0xc9, 0xeb, 0xe1, 0x58, 0xfa, 0xd5, + 0x5d, 0xa6, 0xb7, 0xf8, 0x8f, 0x27, 0x2f, 0x9f, 0x0e, 0x10, 0xfa, 0x7d, 0x3e, 0xbf, 0x5c, 0x26, + 0x99, 0x3c, 0x69, 0xa6, 0x5e, 0xdf, 0xe1, 0x5b, 0x4d, 0x09, 0xe5, 0x47, 0xd3, 0xeb, 0xf5, 0xfa, + 0x55, 0xfc, 0x9d, 0x9e, 0x67, 0xc2, 0xb7, 0xe3, 0xf3, 0xbc, 0x88, 0x1d, 0xb6, 0x2b, 0x1a, 0xb9, + 0xfb, 0xde, 0x5d, 0x2e, 0xf8, 0x2d, 0x21, 0x68, 0xda, 0x2c, 0xaa, 0xbb, 0xe5, 0xf0, 0xad, 0xa6, + 0x95, 0x5b, 0x5c, 0xa4, 0xc8, 0xd8, 0xec, 0x97, 0x72, 0xe9, 0xff, 0x82, 0x0d, 0x5d, 0xea, 0xd3, + 0xa4, 0x33, 0xef, 0x94, 0x62, 0x48, 0x15, 0x6d, 0xb6, 0xdd, 0x6d, 0xf8, 0x22, 0x2b, 0x46, 0xd4, + 0xdd, 0xbc, 0xeb, 0x88, 0x09, 0x97, 0x49, 0x2d, 0x24, 0xa1, 0xc5, 0x0d, 0x32, 0xdf, 0xfb, 0x4d, + 0x6d, 0x34, 0xba, 0x69, 0xff, 0x8a, 0x08, 0x35, 0x46, 0x55, 0x12, 0xa8, 0x1b, 0x4c, 0x15, 0x42, + 0xb4, 0xc7, 0x8d, 0x24, 0x42, 0xa2, 0x37, 0x90, 0x3e, 0xf5, 0xe7, 0xed, 0xf0, 0x59, 0x59, 0x0e, + 0xdc, 0x21, 0x16, 0xb4, 0x03, 0x15, 0xfb, 0x0f, 0x97, 0x5d, 0xf9, 0xe3, 0x6b, 0x74, 0xd0, 0x47, + 0x4d, 0x32, 0x79, 0x94, 0x1e, 0x11, 0x88, 0x24, 0x6b, 0x1c, 0x4e, 0x6a, 0x3e, 0xb6, 0x18, 0xc3, + 0xa0, 0xae, 0xcb, 0x1a, 0xe3, 0xc9, 0xac, 0xe1, 0xfc, 0x21, 0x41, 0xa6, 0x56, 0x1b, 0x97, 0xd1, + 0x97, 0x9f, 0xb6, 0x5b, 0x33, 0x3e, 0x14, 0xa4, 0x96, 0x4c, 0xcd, 0x93, 0xc5, 0xb7, 0xf8, 0xa9, + 0x02, 0xba, 0xa6, 0x04, 0x6a, 0xb2, 0xbc, 0xaa, 0xb9, 0x77, 0x7c, 0x29, 0x4a, 0x6e, 0x59, 0x4b, + 0x88, 0x9b, 0x31, 0x3d, 0xa7, 0xf9, 0xce, 0x9f, 0x5f, 0x65, 0xb5, 0x35, 0x4f, 0x5f, 0x92, 0xf8, + 0xc7, 0xf8, 0x50, 0xe3, 0x11, 0x0b, 0x12, 0x09, 0xdc, 0x17, 0xbb, 0xb3, 0xc3, 0xe3, 0x0c, 0xf2, + 0x12, 0xf4, 0xaa, 0x31, 0xe6, 0xeb, 0x2b, 0xd9, 0xf1, 0x9d, 0xde, 0x3e, 0x92, 0xa0, 0x41, 0x6b, + 0xed, 0x52, 0x73, 0x34, 0xca, 0x94, 0x20, 0xf0, 0x56, 0x23, 0x8a, 0x26, 0x05, 0x89, 0x86, 0xe5, + 0x10, 0x3a, 0x95, 0x56, 0x99, 0xf1, 0x3f, 0x41, 0x51, 0xf7, 0xc1, 0x34, 0xfb, 0x53, 0xe8, 0xc2, + 0xfc, 0x55, 0x5f, 0x27, 0x49, 0x2f, 0x09, 0x73, 0xe9, 0x34, 0xd8, 0x6c, 0xfc, 0xe7, 0x6f, 0x93, + 0x93, 0xc9, 0xfc, 0x2c, 0x6b, 0x67, 0x63, 0x3a, 0x83, 0xa8, 0xd1, 0xdf, 0xca, 0xca, 0xf8, 0x83, + 0xa4, 0x96, 0x92, 0x5a, 0xe7, 0x33, 0x3e, 0xee, 0xf3, 0xf3, 0xcc, 0x87, 0x69, 0xa6, 0x9a, 0x6d, + 0xb6, 0xdb, 0x7e, 0x17, 0xcb, 0x2d, 0x22, 0x13, 0x4b, 0x1d, 0xb5, 0xd3, 0x37, 0xaf, 0xfc, 0x33, + 0x1d, 0x4c, 0x7f, 0xd4, 0xc6, 0x70, 0xc2, 0xff, 0xd6, 0x05, 0x4f, 0x82, 0xa2, 0xa4, 0x96, 0x92, + 0xdb, 0x49, 0x6d, 0xd5, 0x70, 0x97, 0x69, 0xad, 0xa6, 0xbd, 0x11, 0x20, 0xf9, 0x8a, 0x81, 0xa0, + 0x62, 0xd0, 0xb4, 0x5e, 0x08, 0x04, 0x29, 0x99, 0x5c, 0xd8, 0x36, 0x9a, 0x37, 0x56, 0xbe, 0xaa, + 0xba, 0x2c, 0x7f, 0x52, 0x7f, 0xc2, 0x92, 0xe2, 0x49, 0x24, 0x92, 0x49, 0x24, 0xb5, 0x57, 0xbc, + 0xca, 0x3e, 0x0a, 0xa9, 0x24, 0xaa, 0x92, 0x4b, 0x67, 0x49, 0x21, 0xf8, 0xf8, 0x26, 0xde, 0xeb, + 0x55, 0x82, 0xb8, 0xf1, 0x29, 0x25, 0xa4, 0x96, 0x92, 0x5b, 0xe1, 0x88, 0xe5, 0x8f, 0xd3, 0xa6, + 0x8e, 0x5f, 0x77, 0x77, 0xf4, 0x4b, 0x7c, 0xf1, 0xda, 0x5e, 0x99, 0x7c, 0x7f, 0xe7, 0x38, 0xe9, + 0x5b, 0x6d, 0xb6, 0xff, 0xc2, 0xe1, 0x43, 0x6b, 0x54, 0x46, 0x53, 0x03, 0xb4, 0x6d, 0x24, 0xb6, + 0xe6, 0x4f, 0x4f, 0xfc, 0x69, 0x9e, 0x8e, 0x3b, 0xd7, 0x04, 0x6d, 0x6a, 0xc1, 0x22, 0xa1, 0xf2, + 0x7a, 0x32, 0xd8, 0xd9, 0x81, 0x5d, 0x0d, 0xd6, 0xe9, 0x0c, 0xb6, 0xdd, 0x0c, 0x3e, 0x5a, 0x69, + 0x8d, 0x8f, 0x24, 0xa6, 0x6a, 0xc9, 0x53, 0xf7, 0x0e, 0xaa, 0xa1, 0xf5, 0xe3, 0x69, 0x5a, 0x2b, + 0x67, 0x45, 0x5c, 0xe9, 0x17, 0xab, 0xfa, 0x7a, 0x23, 0xbc, 0x67, 0x6e, 0x9e, 0x09, 0x38, 0xce, + 0x58, 0xd7, 0x94, 0x39, 0x90, 0x33, 0x31, 0xf1, 0x4a, 0x0d, 0xf4, 0x7c, 0x18, 0xed, 0x26, 0x7d, + 0xe8, 0x86, 0xba, 0x92, 0x8d, 0x3c, 0x6d, 0xdb, 0x4b, 0x57, 0xde, 0x33, 0x38, 0x3a, 0xaa, 0xd9, + 0x87, 0xf4, 0xa3, 0xbc, 0x6e, 0x11, 0x7a, 0xbc, 0x56, 0xff, 0xf8, 0xdc, 0xe7, 0x8a, 0xd2, 0x19, + 0xbd, 0xfb, 0x58, 0x30, 0x41, 0x54, 0x5a, 0x73, 0x44, 0xf0, 0xb5, 0x6c, 0xf6, 0x58, 0x71, 0x90, + 0xfe, 0xe8, 0x01, 0xb3, 0xda, 0xf7, 0xb5, 0x56, 0x7a, 0xee, 0x7e, 0x0e, 0xfd, 0xc7, 0x7f, 0xe3, + 0x78, 0x85, 0x81, 0xc2, 0x2f, 0x70, 0xec, 0x6b, 0x71, 0xee, 0x47, 0xae, 0x2e, 0xab, 0x32, 0x24, + 0x6d, 0xef, 0x94, 0x76, 0xe3, 0xcb, 0x37, 0x3b, 0x0b, 0xf0, 0x56, 0x24, 0x6b, 0xe6, 0x8a, 0xbb, + 0x71, 0x09, 0xe8, 0x68, 0xd6, 0xd0, 0x3e, 0x6e, 0x97, 0xd4, 0x99, 0xf0, 0xb1, 0xa9, 0x2a, 0xf1, + 0x85, 0x7b, 0x56, 0x28, 0xed, 0x51, 0xc6, 0x73, 0xad, 0xb2, 0x31, 0xf8, 0x27, 0x18, 0x77, 0x59, + 0x99, 0xf2, 0x18, 0xa5, 0x3d, 0xf0, 0x91, 0x55, 0x55, 0x70, 0xa4, 0x78, 0x2c, 0x63, 0xce, 0x11, + 0x53, 0xbe, 0x77, 0xfd, 0x75, 0x4e, 0xfd, 0x5c, 0xfa, 0x91, 0x65, 0xf3, 0xdb, 0xee, 0xee, 0xe3, + 0xf9, 0xe3, 0xa5, 0x6d, 0xb6, 0xdb, 0xff, 0x05, 0x04, 0x91, 0x79, 0x58, 0x2d, 0x17, 0x74, 0x58, + 0xfc, 0x65, 0x9b, 0x36, 0x94, 0xf4, 0x3d, 0x29, 0xd3, 0x55, 0xf4, 0x65, 0xa7, 0x84, 0x3c, 0x4e, + 0x8a, 0xef, 0xf5, 0x5f, 0x05, 0xd7, 0x7d, 0xaa, 0x8b, 0x8e, 0xc8, 0xbc, 0x12, 0xdc, 0xf8, 0xbd, + 0x76, 0x9a, 0x7f, 0x82, 0x7d, 0x5e, 0x92, 0x49, 0x24, 0xff, 0x13, 0x6d, 0x71, 0x5f, 0xf1, 0x77, + 0x77, 0x75, 0x57, 0x7f, 0x05, 0x11, 0xaf, 0x2a, 0xf4, 0x51, 0x43, 0x8b, 0xab, 0xfc, 0x17, 0x5d, + 0xf0, 0xba, 0xaa, 0xae, 0xed, 0xf1, 0x74, 0x92, 0x49, 0x24, 0x92, 0x49, 0x2f, 0x05, 0xd4, 0x92, + 0x49, 0x24, 0x92, 0xc5, 0x77, 0xce, 0x25, 0x3a, 0xfa, 0x65, 0x32, 0x3f, 0x33, 0xe7, 0xf0, 0xf7, + 0x4d, 0x36, 0xdb, 0xff, 0x3d, 0x1e, 0x7d, 0x34, 0xd3, 0x4f, 0xcd, 0x49, 0x6d, 0xae, 0x7a, 0x0d, + 0xfe, 0xab, 0x5f, 0x7b, 0x76, 0xfc, 0x31, 0x39, 0x07, 0x10, 0xe6, 0x6a, 0x4e, 0x34, 0x23, 0x6d, + 0x56, 0x04, 0xc3, 0x16, 0x1d, 0xff, 0x0e, 0x0a, 0x76, 0x65, 0x38, 0xba, 0x64, 0xe2, 0x6a, 0x69, + 0xd1, 0xaf, 0xf8, 0xd8, 0xab, 0x0e, 0x3a, 0xc3, 0x62, 0xaf, 0x9a, 0xf7, 0x76, 0x13, 0x0b, 0x1f, + 0xc9, 0x2c, 0x56, 0x21, 0x13, 0x55, 0x90, 0x7d, 0x8f, 0x78, 0xbc, 0xb3, 0x2a, 0x30, 0x7c, 0x5b, + 0xb7, 0xe0, 0xa8, 0xd1, 0x1e, 0x7f, 0x56, 0xbe, 0x5c, 0x3d, 0xc2, 0x34, 0x91, 0x35, 0x51, 0xde, + 0x3c, 0x69, 0x3f, 0x64, 0x85, 0x42, 0xfd, 0xf9, 0x72, 0x06, 0xeb, 0x87, 0x51, 0x73, 0xa8, 0x6a, + 0xa9, 0xbe, 0x31, 0xad, 0x28, 0x69, 0xf8, 0x7e, 0x75, 0x14, 0x71, 0x32, 0x0b, 0x35, 0x37, 0x17, + 0x57, 0x52, 0x5a, 0xbc, 0x57, 0x7f, 0xf8, 0x76, 0xc5, 0x2c, 0x5e, 0x3f, 0xbe, 0xcb, 0x1d, 0x3f, + 0x43, 0xa1, 0x95, 0xa4, 0x9d, 0x7b, 0xb7, 0xfe, 0x14, 0xac, 0x7d, 0x26, 0xcb, 0x2d, 0x5d, 0x51, + 0x20, 0xa8, 0x91, 0x75, 0x9d, 0x07, 0xa5, 0x69, 0x27, 0x6a, 0xff, 0x05, 0x27, 0x70, 0xc4, 0x2d, + 0x32, 0x57, 0x2a, 0xbd, 0x6d, 0x55, 0x4e, 0x91, 0x78, 0xce, 0xf5, 0x7d, 0x33, 0x6d, 0x5b, 0x47, + 0xc2, 0xfa, 0xbc, 0x61, 0x5d, 0xd0, 0x9e, 0x12, 0x33, 0x25, 0xe3, 0x36, 0x97, 0xb7, 0xbb, 0xff, + 0x8f, 0x1d, 0xcc, 0x4c, 0x31, 0xe8, 0xe2, 0x7b, 0x98, 0x1c, 0xb9, 0x55, 0x10, 0x4f, 0xf9, 0x4a, + 0xca, 0x33, 0x50, 0xcd, 0xc4, 0x2e, 0x0c, 0x02, 0x6d, 0xdb, 0xb4, 0xd6, 0x7e, 0xfa, 0xb2, 0x56, + 0x5e, 0x08, 0x26, 0xc9, 0xf0, 0xf8, 0xd3, 0x5d, 0x55, 0x68, 0xff, 0xa6, 0x9a, 0x69, 0xf9, 0xc8, + 0x8e, 0xfd, 0x34, 0xd3, 0x4f, 0xcf, 0x47, 0x7e, 0x9a, 0x69, 0xa7, 0xe7, 0x2b, 0xfd, 0xb6, 0xdb, + 0x6c, 0x9d, 0x52, 0xc5, 0xf0, 0xe5, 0xb3, 0xd6, 0xdb, 0x1f, 0x4d, 0x39, 0xa1, 0xe0, 0xb0, 0xd8, + 0xef, 0xab, 0x40, 0xca, 0x49, 0xe7, 0x3f, 0xd1, 0xff, 0x04, 0xd9, 0xba, 0xf7, 0x6a, 0x03, 0xa5, + 0x4b, 0x9c, 0x4a, 0x38, 0x9f, 0x4d, 0x34, 0xd3, 0xf3, 0x88, 0x45, 0x3f, 0xaa, 0xa9, 0x39, 0xce, + 0xa6, 0x52, 0xc8, 0x71, 0x26, 0x17, 0xfa, 0xb7, 0xc7, 0x73, 0x92, 0x39, 0x26, 0x9a, 0xe6, 0xda, + 0x93, 0xf8, 0x2b, 0x93, 0x59, 0xa4, 0xd6, 0x69, 0xb1, 0xd8, 0x7c, 0x7e, 0x1b, 0x0d, 0x8f, 0xc7, + 0xe2, 0x2f, 0xf8, 0x6e, 0x6c, 0x36, 0x3f, 0x1f, 0x88, 0xeb, 0xea, 0xaa, 0xaf, 0x97, 0xb4, 0xd7, + 0x84, 0x8b, 0x26, 0x2f, 0x75, 0xbe, 0x84, 0xb9, 0xf0, 0xe0, 0xe6, 0x87, 0x4d, 0xa7, 0x10, 0x48, + 0xad, 0xb7, 0xc8, 0x75, 0x5e, 0xdf, 0xfe, 0x30, 0x61, 0x21, 0x8e, 0x9e, 0x2d, 0x8f, 0xad, 0x90, + 0xfe, 0x4d, 0xf8, 0x53, 0xd4, 0xf2, 0x74, 0xee, 0x7e, 0xc2, 0x0a, 0x0b, 0x61, 0x88, 0xe7, 0x93, + 0xa1, 0x37, 0xc1, 0x49, 0x0d, 0x11, 0xa7, 0x22, 0x22, 0x87, 0x19, 0x97, 0x77, 0x70, 0x71, 0x73, + 0x0d, 0x96, 0xbe, 0x3c, 0xb9, 0x3b, 0x64, 0x9a, 0x86, 0x3c, 0x69, 0x25, 0xbd, 0x21, 0x33, 0xb0, + 0x53, 0x7d, 0x73, 0x88, 0x52, 0x21, 0xd0, 0xc1, 0xbd, 0x2d, 0x08, 0x8c, 0xfd, 0xe9, 0x4e, 0x8a, + 0xb7, 0x6e, 0xdb, 0x89, 0x69, 0xb6, 0x9f, 0x8c, 0x39, 0xfc, 0x30, 0x69, 0xb5, 0x3c, 0xdd, 0xc5, + 0xf2, 0xfd, 0x4a, 0xf1, 0x5f, 0x0f, 0xd2, 0xd8, 0xa9, 0x2a, 0x74, 0xfc, 0x29, 0x34, 0xb7, 0x8c, + 0x1c, 0x7a, 0x37, 0x36, 0xb7, 0x1c, 0xcc, 0xea, 0xa7, 0xef, 0x84, 0x44, 0xad, 0x66, 0x85, 0xbd, + 0xd1, 0x0d, 0x31, 0x22, 0xaf, 0xc7, 0x1e, 0x84, 0x9a, 0x67, 0xd2, 0xeb, 0xb5, 0x9a, 0xfe, 0xee, + 0x7e, 0xef, 0xea, 0xff, 0x1c, 0x20, 0x71, 0x56, 0x2b, 0xb5, 0xdb, 0xbd, 0xc9, 0xac, 0xd3, 0x6b, + 0xb7, 0xc7, 0x91, 0xa9, 0x24, 0xd3, 0x0c, 0xfe, 0x3a, 0xaa, 0xa3, 0x0a, 0xef, 0xe3, 0x44, 0x34, + 0xc9, 0x3d, 0x6e, 0x69, 0x28, 0x5f, 0x63, 0xba, 0xab, 0xbb, 0xba, 0x8d, 0xa9, 0x7f, 0x56, 0xa6, + 0xff, 0xe0, 0xa0, 0xe4, 0xf9, 0x27, 0xdd, 0xdc, 0x79, 0xc2, 0xaf, 0xf5, 0x55, 0x50, 0x9f, 0x04, + 0x83, 0x1a, 0x68, 0xf1, 0xeb, 0xe1, 0x6b, 0x6a, 0xdb, 0x6e, 0xe8, 0xd1, 0x91, 0x3e, 0x92, 0x4d, + 0x35, 0xe1, 0xbe, 0xef, 0x13, 0xaa, 0x46, 0xab, 0xb3, 0xd7, 0x0d, 0x1d, 0x49, 0xbc, 0x5d, 0xb3, + 0x7f, 0xf0, 0xe4, 0xe4, 0x8e, 0x48, 0xb8, 0xdc, 0x38, 0xb8, 0xe1, 0xa1, 0x57, 0x7f, 0x9c, 0xc6, + 0x59, 0xf9, 0xf5, 0xb6, 0x9a, 0xf3, 0xcc, 0x85, 0x6a, 0x8c, 0x38, 0x68, 0xba, 0x61, 0xad, 0x0c, + 0xfe, 0x79, 0xd0, 0xca, 0x4d, 0x33, 0xeb, 0xf5, 0xa6, 0x9d, 0xae, 0xdf, 0x0c, 0x75, 0x57, 0x77, + 0x7f, 0xea, 0x68, 0xb5, 0x0a, 0xaf, 0xf0, 0xb5, 0xea, 0xa9, 0x24, 0x91, 0x72, 0x0d, 0xdb, 0x76, + 0xe4, 0x34, 0x97, 0x85, 0x6e, 0xea, 0xb6, 0xad, 0x65, 0xf4, 0x12, 0x4d, 0x97, 0x7c, 0x3d, 0xaa, + 0xa6, 0x9a, 0xaa, 0xa6, 0x9a, 0x49, 0x24, 0x92, 0xca, 0x9a, 0x64, 0x34, 0xc3, 0x49, 0x25, 0x12, + 0x5e, 0x1f, 0xdd, 0xaa, 0x92, 0x8c, 0xa4, 0x59, 0x68, 0x5a, 0x17, 0x21, 0x8d, 0x50, 0xf2, 0x92, + 0x4f, 0xd7, 0xe8, 0xab, 0x15, 0x69, 0x25, 0xe0, 0x92, 0xcd, 0x9b, 0x36, 0x69, 0x57, 0x8d, 0xbb, + 0xfa, 0xa9, 0x09, 0x10, 0x97, 0x53, 0xe6, 0x5f, 0xe4, 0x49, 0x36, 0x92, 0x5f, 0xe0, 0xc3, 0xaa, + 0x88, 0x78, 0xee, 0x7d, 0x7c, 0xfa, 0x7d, 0x2e, 0xb7, 0x71, 0x10, 0xc5, 0xf4, 0x66, 0x7b, 0x7d, + 0xb3, 0xae, 0x64, 0xe2, 0x0b, 0x13, 0x1a, 0x31, 0xa1, 0x6c, 0xbb, 0x6d, 0xb8, 0x92, 0xf0, 0xd9, + 0x1d, 0xfb, 0x92, 0x67, 0x5f, 0xf0, 0x46, 0x7c, 0xa4, 0x12, 0xee, 0x5f, 0x34, 0x56, 0x1e, 0x7e, + 0x1e, 0xbb, 0xa1, 0x2f, 0x08, 0x98, 0x92, 0xf4, 0x43, 0xf9, 0xa3, 0xc7, 0xcd, 0x62, 0x8a, 0xb7, + 0x98, 0xc5, 0x18, 0xd3, 0x67, 0x82, 0xd8, 0xfa, 0xd6, 0xec, 0x9d, 0x75, 0x75, 0x23, 0x0f, 0xc1, + 0x55, 0x29, 0xec, 0x3d, 0xee, 0x0c, 0x92, 0x78, 0x48, 0x5d, 0x7c, 0x69, 0x8d, 0x47, 0xb9, 0xcc, + 0x2e, 0xb9, 0x4a, 0x77, 0xce, 0xf4, 0x96, 0xa3, 0xd7, 0x71, 0xed, 0xbd, 0x3f, 0x19, 0x87, 0x54, + 0xf4, 0xb8, 0x1b, 0xf8, 0xf0, 0xfe, 0xf6, 0x0e, 0x5d, 0x6f, 0x7d, 0xd5, 0x3d, 0x4d, 0x79, 0x1a, + 0xb0, 0xf5, 0x9a, 0x85, 0x71, 0x51, 0xa5, 0xe3, 0x0a, 0x88, 0x73, 0xaf, 0x92, 0x76, 0x6f, 0x3d, + 0x25, 0x14, 0x69, 0x36, 0x57, 0xd3, 0xa7, 0xe3, 0x0a, 0xea, 0xa5, 0x8b, 0x43, 0x2d, 0x30, 0x79, + 0x17, 0x11, 0xca, 0xf4, 0x6a, 0xc5, 0xd0, 0x5f, 0x12, 0x10, 0xf6, 0x37, 0x7a, 0xf4, 0x6d, 0x19, + 0x85, 0x5f, 0xe3, 0x2f, 0x9f, 0xd5, 0x5e, 0xf6, 0x4a, 0xde, 0x11, 0xf5, 0xa7, 0x67, 0x8c, 0x29, + 0x68, 0x5a, 0x16, 0x8d, 0xa6, 0x4e, 0x9a, 0x96, 0x86, 0x98, 0x92, 0xbe, 0x39, 0xf8, 0x9b, 0x0b, + 0xf8, 0xb8, 0x96, 0x0e, 0x21, 0xe4, 0xce, 0x0f, 0xcf, 0xeb, 0xaf, 0xc2, 0x57, 0xee, 0x56, 0x3f, + 0xc6, 0x1a, 0x86, 0x74, 0xac, 0x71, 0xc4, 0x54, 0xac, 0x9c, 0x7d, 0x49, 0x94, 0xe3, 0xaf, 0xf1, + 0xe2, 0xa6, 0x69, 0x8b, 0xa0, 0xd2, 0x22, 0x37, 0x63, 0x6d, 0x9b, 0x2f, 0xc3, 0xfc, 0xfc, 0xfd, + 0x78, 0xe1, 0xf1, 0xb3, 0x34, 0xae, 0xbc, 0x97, 0xe6, 0xfd, 0xb1, 0x3c, 0x38, 0x13, 0x4d, 0x34, + 0xd3, 0x1d, 0xa9, 0xa6, 0x9a, 0x7f, 0xe7, 0xa9, 0x36, 0x2b, 0xc7, 0x0f, 0xc4, 0xf1, 0x66, 0x7b, + 0xd9, 0xe4, 0xa7, 0x82, 0x42, 0xb6, 0x6e, 0xfe, 0x5f, 0x05, 0xba, 0xbb, 0xec, 0x18, 0xd7, 0x85, + 0x0c, 0x77, 0xe0, 0xa0, 0x8a, 0xbd, 0x29, 0x34, 0x76, 0xf8, 0x30, 0x9e, 0xd9, 0xb5, 0x5a, 0xd7, + 0x27, 0x6d, 0xb1, 0x57, 0xf9, 0xe8, 0xed, 0xdb, 0x1f, 0xff, 0x05, 0x14, 0xd9, 0xa7, 0x49, 0x24, + 0x92, 0x2b, 0xdf, 0x1a, 0x44, 0x92, 0xd5, 0x74, 0x8b, 0x89, 0x44, 0x92, 0x49, 0x24, 0x44, 0xfe, + 0xba, 0xd3, 0x4f, 0xd6, 0xbe, 0x12, 0xe9, 0x24, 0xd3, 0x4d, 0x7c, 0x29, 0x7d, 0x36, 0xb6, 0x9a, + 0x69, 0xad, 0x6f, 0x2a, 0x7c, 0x29, 0xd2, 0x49, 0x69, 0x25, 0xbb, 0xb4, 0xd3, 0x4d, 0x65, 0xf1, + 0x96, 0x9a, 0xae, 0x92, 0x4d, 0x34, 0xd3, 0x4d, 0x34, 0xd3, 0x5e, 0x0a, 0xfa, 0x49, 0x1f, 0x2a, + 0xa9, 0xa6, 0x9a, 0x69, 0xac, 0xbe, 0x0a, 0xad, 0x35, 0x54, 0x92, 0xd2, 0x49, 0x56, 0x2a, 0xe0, + 0xa3, 0x4d, 0x7b, 0x4d, 0x31, 0xf1, 0x77, 0x7f, 0x55, 0xf1, 0x55, 0x5d, 0x27, 0x55, 0xf0, 0xf5, + 0x54, 0x4f, 0xd2, 0x7c, 0xf4, 0x49, 0xa6, 0x4e, 0x4b, 0x79, 0x4d, 0xd3, 0x77, 0xf0, 0x60, 0x68, + 0x63, 0xda, 0x65, 0x80, 0xd6, 0x2c, 0x7d, 0x6d, 0xab, 0x7f, 0xe1, 0x42, 0x8f, 0xdc, 0x87, 0x99, + 0xb5, 0x75, 0xbb, 0xa3, 0x96, 0x55, 0x6e, 0x79, 0x71, 0xbe, 0x42, 0xb4, 0xdd, 0x97, 0x8c, 0xa3, + 0xa4, 0x95, 0x26, 0xcd, 0xd2, 0x49, 0x71, 0xa6, 0xd6, 0x3f, 0xc6, 0x8c, 0xb2, 0x64, 0x98, 0xc4, + 0x63, 0xb2, 0x5b, 0xa6, 0xfe, 0xf8, 0x31, 0x9d, 0x1e, 0x8c, 0x05, 0xf1, 0x1b, 0x23, 0xea, 0xd1, + 0xbb, 0x22, 0x37, 0xf2, 0xcc, 0x1b, 0xf4, 0xf1, 0xa5, 0x80, 0xd3, 0xba, 0x85, 0x88, 0x7b, 0xd6, + 0xbe, 0x25, 0xe3, 0x55, 0x71, 0x7d, 0xd1, 0x23, 0x05, 0xc0, 0xad, 0xf8, 0x38, 0x81, 0x52, 0xb9, + 0xbe, 0xf6, 0xd5, 0x69, 0xcb, 0xd9, 0xf8, 0xd2, 0xa3, 0x77, 0x65, 0x4e, 0x5e, 0x9b, 0x51, 0x52, + 0x10, 0xbc, 0x85, 0x57, 0x4c, 0xc7, 0xe5, 0x55, 0x55, 0xff, 0x27, 0x54, 0xfc, 0x61, 0xde, 0x2d, + 0x9d, 0x55, 0xf4, 0x6f, 0x35, 0x59, 0xf8, 0xfc, 0xec, 0xa7, 0xd5, 0xb4, 0xd5, 0xcb, 0xb1, 0xf8, + 0x2b, 0xe7, 0x81, 0x3d, 0x70, 0xdc, 0x7b, 0x35, 0x3f, 0x26, 0x22, 0x88, 0xb8, 0x3b, 0x7c, 0x29, + 0x22, 0x46, 0x3e, 0xa7, 0xb8, 0xfc, 0xbd, 0x46, 0x8c, 0x95, 0x2b, 0x18, 0xdd, 0x37, 0x48, 0xbc, + 0x65, 0x0c, 0xad, 0xd9, 0x2a, 0x7b, 0xcb, 0xd1, 0x2f, 0xf0, 0x81, 0x56, 0xe2, 0xb4, 0x36, 0x34, + 0x36, 0x32, 0xb0, 0x86, 0xd6, 0x20, 0xfc, 0x47, 0x10, 0xd0, 0xb4, 0x0d, 0x65, 0x98, 0x41, 0x7e, + 0x2a, 0xf7, 0x85, 0xc6, 0x2e, 0x68, 0x2e, 0xb8, 0xa6, 0xeb, 0xff, 0x8d, 0x21, 0x66, 0x3b, 0xa3, + 0x67, 0x53, 0x6a, 0xfb, 0x55, 0x5a, 0xad, 0x9e, 0xdd, 0xb1, 0x57, 0xfe, 0x0a, 0x23, 0x51, 0x1e, + 0x31, 0x95, 0x54, 0x62, 0x1a, 0x59, 0xb8, 0x5c, 0xf4, 0x93, 0x19, 0x5d, 0x25, 0xac, 0x89, 0xb3, + 0x4d, 0xdf, 0x7f, 0x8c, 0x21, 0x37, 0x03, 0x1d, 0xca, 0x93, 0xf6, 0x31, 0xfb, 0xbd, 0x26, 0x19, + 0xaf, 0xfe, 0x36, 0x93, 0x22, 0xe7, 0xcd, 0x5c, 0x9a, 0x82, 0x2c, 0x7f, 0x15, 0x7f, 0xdf, 0x7d, + 0x31, 0x6e, 0x9f, 0x87, 0xe9, 0x5a, 0xc8, 0xe9, 0x9d, 0xed, 0x8f, 0x1b, 0x9e, 0xba, 0xae, 0xfc, + 0x96, 0x68, 0xe5, 0xe6, 0xe2, 0x39, 0x02, 0x65, 0xc6, 0xe1, 0x31, 0x99, 0xe5, 0x22, 0x49, 0x0d, + 0x69, 0x3e, 0x34, 0x8f, 0x79, 0x70, 0xb8, 0xd5, 0x5a, 0x49, 0x69, 0xb4, 0xf6, 0xdb, 0x6d, 0xbf, + 0xf0, 0x52, 0x55, 0x72, 0x64, 0x54, 0x92, 0x48, 0x62, 0x9f, 0x47, 0x4f, 0x85, 0x2a, 0xdb, 0x6d, + 0xe9, 0x25, 0x18, 0xf7, 0x89, 0x5d, 0xd0, 0x1b, 0xe0, 0xb4, 0x8b, 0x55, 0x49, 0x2d, 0x1d, 0xf8, + 0x53, 0x2f, 0x5e, 0xdd, 0xea, 0xd0, 0x97, 0xd6, 0xd3, 0x5a, 0x75, 0xe8, 0xe9, 0xd7, 0x82, 0x52, + 0xb4, 0xd6, 0x92, 0x44, 0x22, 0xd2, 0x0a, 0x45, 0xe1, 0xd2, 0x17, 0x4b, 0xb9, 0x74, 0xfc, 0xdf, + 0x93, 0xfc, 0x5f, 0x3f, 0x3f, 0x7b, 0xf0, 0xd7, 0x35, 0x9a, 0xca, 0xdf, 0x4d, 0x34, 0xd3, 0xf0, + 0x54, 0x45, 0x5a, 0x6c, 0xd5, 0x5d, 0xd2, 0x49, 0x24, 0x88, 0x9f, 0x05, 0x57, 0x2f, 0xdd, 0x57, + 0xd5, 0x65, 0x55, 0x54, 0x8a, 0xf8, 0x53, 0x4d, 0x9b, 0xb9, 0xa8, 0xea, 0x4c, 0xa4, 0x92, 0x49, + 0x13, 0x0e, 0xe7, 0x22, 0xbe, 0x0a, 0x6c, 0xcb, 0x8d, 0x50, 0x76, 0xec, 0x1b, 0x07, 0xda, 0x69, + 0x2a, 0xf1, 0x15, 0x5e, 0x5a, 0x57, 0xc2, 0x25, 0xca, 0x41, 0x29, 0x07, 0x72, 0x90, 0x5a, 0xdf, + 0x87, 0xcf, 0x0f, 0x72, 0x90, 0x4a, 0x41, 0x77, 0xe5, 0x61, 0x46, 0xaa, 0x2a, 0x33, 0x21, 0xd9, + 0xd2, 0xa9, 0x3b, 0x3b, 0xb9, 0xfb, 0xff, 0x82, 0x01, 0x83, 0x2d, 0x2d, 0x26, 0xc2, 0x6d, 0x26, + 0x59, 0x0f, 0x0e, 0xcd, 0xd5, 0x65, 0xf4, 0x91, 0xbd, 0x3c, 0x63, 0x46, 0x3f, 0xc3, 0xb1, 0xcc, + 0xf6, 0x99, 0xb4, 0xba, 0xda, 0x3e, 0xca, 0x31, 0xdf, 0xff, 0x0a, 0x12, 0xc6, 0xea, 0x69, 0x70, + 0x8d, 0xd2, 0x5a, 0x93, 0x1f, 0x90, 0xbe, 0xf8, 0xc2, 0xb9, 0x36, 0x16, 0x6b, 0xb7, 0x63, 0x89, + 0x71, 0xe5, 0xe5, 0xfc, 0x2c, 0x77, 0xbd, 0xdd, 0xdd, 0xee, 0xee, 0xff, 0xe1, 0x43, 0x38, 0xd6, + 0x7e, 0x21, 0xac, 0x8d, 0x05, 0x59, 0x34, 0x5f, 0xbf, 0x0f, 0x62, 0x57, 0x3a, 0x88, 0xb7, 0xe3, + 0x68, 0x0c, 0x38, 0x38, 0xd3, 0x4c, 0x25, 0xac, 0x1a, 0x8c, 0xf9, 0x75, 0x2a, 0x94, 0xd2, 0x6e, + 0xb2, 0x54, 0x93, 0x65, 0xff, 0xfc, 0x69, 0x35, 0x43, 0x39, 0xf5, 0x49, 0x61, 0xbb, 0x72, 0x33, + 0x17, 0xda, 0x55, 0xf2, 0xe4, 0x5f, 0x8d, 0xa0, 0xc7, 0xcc, 0xd5, 0xc4, 0x62, 0xed, 0x26, 0xbd, + 0x5f, 0x23, 0x9f, 0xe3, 0xfb, 0x9f, 0x23, 0x4b, 0xaf, 0xf5, 0x55, 0x5f, 0xf1, 0x82, 0xce, 0xa6, + 0xad, 0xbb, 0xb4, 0xd5, 0x4d, 0xa6, 0xda, 0xaa, 0xaf, 0x12, 0x2f, 0xa9, 0xbc, 0x73, 0x88, 0xcc, + 0xe2, 0x23, 0xb3, 0x32, 0xd5, 0x4a, 0xa2, 0x1d, 0xd8, 0x92, 0x80, 0xf2, 0xd3, 0xf1, 0xf3, 0x46, + 0xbb, 0x8d, 0xdf, 0x88, 0xc1, 0x75, 0xfd, 0xb4, 0x41, 0x86, 0x9a, 0xfd, 0xfb, 0x1f, 0xe1, 0x39, + 0x6e, 0xdb, 0xdd, 0xaf, 0x88, 0xa7, 0xa6, 0xdb, 0x72, 0x7f, 0x96, 0x46, 0x24, 0x60, 0x9f, 0xc2, + 0x36, 0x9a, 0x69, 0xab, 0x73, 0x63, 0xe7, 0xe0, 0xb2, 0x91, 0x32, 0xa5, 0xa9, 0xbf, 0x96, 0xab, + 0xdf, 0x1b, 0xdd, 0x1d, 0x58, 0x93, 0x2d, 0x8d, 0xee, 0xac, 0xc4, 0x4f, 0x4b, 0x3d, 0x20, 0xbc, + 0x82, 0x75, 0xd3, 0x74, 0xd3, 0xff, 0x1a, 0x62, 0x61, 0xfc, 0xc6, 0x3c, 0x5e, 0x10, 0xa5, 0x00, + 0xab, 0xe3, 0xbe, 0x1f, 0xe5, 0xbb, 0xe4, 0x84, 0xdd, 0x63, 0xa6, 0x5e, 0xdf, 0xe3, 0x4c, 0x9b, + 0x34, 0x72, 0x1f, 0x32, 0xd7, 0x37, 0x6c, 0x7f, 0x66, 0x5e, 0xf6, 0x5d, 0x64, 0x64, 0xfb, 0xbe, + 0x5b, 0x6e, 0x9f, 0x86, 0xc4, 0xd5, 0x1a, 0x9c, 0x55, 0x22, 0xfb, 0x76, 0xd5, 0xf0, 0x55, 0x77, + 0x77, 0xa6, 0x78, 0xf7, 0x42, 0x43, 0xc4, 0xf8, 0xd3, 0x64, 0x81, 0xe4, 0x92, 0x1b, 0xe1, 0xc4, + 0xe7, 0xb1, 0xda, 0xbb, 0x69, 0x43, 0xb3, 0x55, 0xc8, 0xff, 0xf0, 0xa1, 0xd0, 0x31, 0x91, 0xd3, + 0xe9, 0xa2, 0x2d, 0x71, 0xc3, 0x14, 0x38, 0x34, 0x1c, 0x63, 0x43, 0x1e, 0x09, 0x3f, 0xc6, 0xd8, + 0xd5, 0xb3, 0x29, 0xea, 0x33, 0xd0, 0x6e, 0x18, 0xaa, 0x91, 0x34, 0xba, 0xa9, 0xe2, 0xe7, 0xb5, + 0x97, 0x5c, 0x2a, 0xa0, 0xdb, 0x0e, 0xf3, 0x69, 0x7f, 0x8d, 0x22, 0x75, 0xd4, 0x5d, 0x8e, 0xc9, + 0xb7, 0x0a, 0x1b, 0x6c, 0xe1, 0xb1, 0xb3, 0x43, 0x87, 0xfa, 0x75, 0xd7, 0xc2, 0xd4, 0x69, 0x19, + 0x37, 0xf6, 0x46, 0x83, 0x63, 0x14, 0x85, 0x61, 0x84, 0x95, 0x8d, 0xe9, 0x49, 0x6e, 0xaf, 0x86, + 0x05, 0xb4, 0xd3, 0x4d, 0x2a, 0xaa, 0x94, 0x23, 0x69, 0x48, 0x63, 0xfe, 0x18, 0xbb, 0xee, 0xfe, + 0xb8, 0xdc, 0xb6, 0x99, 0xff, 0x0c, 0x19, 0x56, 0x95, 0x53, 0xc5, 0x69, 0xa5, 0x12, 0x2e, 0x3f, + 0xff, 0x17, 0xd2, 0x4b, 0x49, 0x2f, 0x0f, 0x09, 0x5a, 0x49, 0x69, 0x24, 0xaa, 0xee, 0xa9, 0xa6, + 0x9a, 0x7f, 0xe3, 0x72, 0xa9, 0x24, 0x4a, 0x12, 0x91, 0x44, 0x4c, 0x6e, 0x33, 0x1b, 0x91, 0x25, + 0x12, 0x4a, 0x9a, 0x69, 0xa7, 0xfe, 0x14, 0xb2, 0x8c, 0xa7, 0x5f, 0xe5, 0xcb, 0xe9, 0x25, 0xaa, + 0x7e, 0x5f, 0x0a, 0x6d, 0x5e, 0x7a, 0x0a, 0xcf, 0x6b, 0xfc, 0xbb, 0xae, 0x93, 0xd1, 0xb5, 0xe0, + 0xb3, 0x76, 0x6c, 0xf2, 0xd1, 0x1b, 0xba, 0x34, 0x69, 0x57, 0x82, 0xb9, 0xe8, 0x6a, 0x73, 0x66, + 0xa6, 0xad, 0x34, 0x6c, 0xb9, 0xf0, 0x45, 0xd5, 0x73, 0x9f, 0x04, 0x56, 0x9a, 0x9f, 0x33, 0x9f, + 0x04, 0xd5, 0x5b, 0x72, 0xe3, 0x30, 0x98, 0x77, 0x33, 0x9f, 0x0a, 0x5d, 0xdd, 0xd2, 0x49, 0x24, + 0x9d, 0xf7, 0x7c, 0x7c, 0x59, 0xf0, 0x45, 0xdd, 0xdc, 0xf8, 0x2b, 0xad, 0x67, 0xc6, 0x8d, 0x87, + 0xf1, 0xa7, 0xa9, 0xa7, 0x3e, 0x08, 0x4e, 0x7d, 0xfd, 0xf0, 0x4d, 0x8f, 0x7b, 0x1a, 0x06, 0xe9, + 0x13, 0x3b, 0xe1, 0xd2, 0x23, 0x25, 0x3e, 0x4a, 0x4f, 0x46, 0x7c, 0x48, 0xda, 0x29, 0xa6, 0xeb, + 0xff, 0x47, 0xaf, 0xa3, 0x15, 0x3e, 0x1e, 0x15, 0x15, 0xa4, 0x3c, 0xaf, 0xad, 0x0f, 0x28, 0x84, + 0x66, 0x6a, 0xab, 0xc7, 0x31, 0xef, 0x96, 0x8a, 0x30, 0xef, 0xf6, 0xbc, 0x29, 0xc9, 0xdd, 0x90, + 0xcd, 0xca, 0xdc, 0x67, 0xd1, 0xa3, 0x0e, 0x83, 0x7d, 0x76, 0x1e, 0x32, 0xa6, 0x25, 0xbf, 0x21, + 0xb3, 0xbc, 0x9b, 0x1d, 0x36, 0xd8, 0x63, 0x3f, 0xb6, 0xff, 0x85, 0x44, 0x36, 0x3e, 0x72, 0x9b, + 0xd8, 0xe3, 0x57, 0x5c, 0xc3, 0xfd, 0xd5, 0xd7, 0xc1, 0x58, 0x93, 0x7b, 0xbf, 0x49, 0xaa, 0x6c, + 0x6d, 0xb7, 0xc6, 0x16, 0x92, 0x49, 0x20, 0x92, 0x69, 0x84, 0x9a, 0x69, 0xa6, 0x4d, 0xe1, 0x27, + 0xe3, 0x45, 0x4b, 0x1e, 0xb5, 0xf1, 0xe3, 0x86, 0x70, 0x29, 0x90, 0x25, 0x5a, 0x17, 0x19, 0xec, + 0x55, 0x1b, 0xbf, 0xc1, 0xf7, 0xf1, 0x18, 0x43, 0xb1, 0x83, 0x38, 0x81, 0xc7, 0x49, 0x2f, 0x05, + 0xc5, 0xac, 0xbe, 0x4d, 0x78, 0x9c, 0x78, 0x52, 0xea, 0x94, 0x57, 0x6d, 0x82, 0xe8, 0x9e, 0xbb, + 0x9b, 0x5b, 0x79, 0xbb, 0x51, 0x7c, 0x60, 0x9a, 0x63, 0x94, 0x49, 0x98, 0xdd, 0xf5, 0xab, 0x4e, + 0x87, 0x15, 0xbf, 0x82, 0x99, 0xf2, 0xa6, 0xb1, 0xaf, 0xdd, 0x75, 0x37, 0x0a, 0xf9, 0xe4, 0x89, + 0xf1, 0xf4, 0x32, 0xb1, 0x43, 0x4d, 0xec, 0x4e, 0xc4, 0x97, 0x11, 0x08, 0x47, 0x0d, 0x8e, 0xc6, + 0xd3, 0xed, 0x1b, 0x32, 0xb5, 0xaf, 0x04, 0x24, 0xb6, 0x9d, 0xdf, 0x08, 0x95, 0x52, 0x27, 0x39, + 0xe7, 0x7d, 0xa7, 0x26, 0x76, 0xfe, 0x2b, 0xba, 0x6b, 0x5f, 0x8b, 0x35, 0xed, 0x1e, 0xd8, 0x4f, + 0x32, 0xca, 0x78, 0xc2, 0xdd, 0xa6, 0xb5, 0x56, 0xca, 0xdf, 0x8d, 0x6a, 0xfe, 0xda, 0xc2, 0xf1, + 0x85, 0x09, 0xd4, 0xee, 0xb9, 0x7e, 0x62, 0xc8, 0xeb, 0x5b, 0x22, 0xfa, 0x99, 0xdb, 0x85, 0xfd, + 0x3b, 0x26, 0x50, 0xfd, 0x37, 0x1f, 0xf2, 0xff, 0x78, 0x52, 0xea, 0x2e, 0xb3, 0x0e, 0x1b, 0x4d, + 0x14, 0x78, 0xa5, 0x78, 0xc4, 0x57, 0x14, 0x69, 0xf6, 0xfc, 0x54, 0xfb, 0x86, 0xeb, 0x75, 0xb2, + 0xde, 0xc0, 0x08, 0x80, 0xdf, 0x0f, 0x92, 0xda, 0xe3, 0x12, 0x53, 0xce, 0x71, 0x98, 0x3b, 0xd1, + 0xf4, 0x2d, 0x35, 0xf6, 0xcf, 0xbf, 0x8c, 0x18, 0xcf, 0xd4, 0xda, 0x93, 0x2d, 0xc4, 0x17, 0x77, + 0x7f, 0x33, 0x7c, 0x3c, 0x5d, 0xb5, 0xcb, 0x42, 0xd1, 0x2b, 0xed, 0xb5, 0x36, 0x7f, 0x82, 0x92, + 0xd2, 0x46, 0x8f, 0x3e, 0x17, 0x6a, 0xdb, 0x76, 0xf8, 0x54, 0x8e, 0xf1, 0xd8, 0xc0, 0x7d, 0xeb, + 0x18, 0xda, 0xc6, 0x11, 0x56, 0xae, 0x1c, 0x77, 0x3f, 0xe3, 0x70, 0x6d, 0x63, 0x31, 0xa4, 0x37, + 0x8e, 0x8a, 0x18, 0xee, 0x8a, 0x9b, 0x98, 0xc8, 0xbb, 0x65, 0xf4, 0xfd, 0x5b, 0xe5, 0x55, 0xbf, + 0x87, 0x68, 0xdc, 0x95, 0xb8, 0xdd, 0x96, 0x35, 0x17, 0xe5, 0x58, 0x48, 0xcc, 0x5b, 0x47, 0xa4, + 0x0b, 0xfc, 0x69, 0x12, 0x7b, 0x0d, 0xef, 0x86, 0xca, 0xfd, 0x22, 0x45, 0xe5, 0x38, 0xff, 0xa9, + 0xb6, 0x32, 0xf3, 0x56, 0x2f, 0xf0, 0xfd, 0x27, 0x52, 0xc8, 0x7e, 0x22, 0xb7, 0xce, 0x9a, 0x29, + 0xac, 0x38, 0x8e, 0x72, 0xd2, 0x4a, 0xa9, 0x9f, 0xa7, 0xf8, 0x7e, 0x47, 0x3c, 0x88, 0xc6, 0x1c, + 0xe6, 0x42, 0x3a, 0xe7, 0xca, 0x93, 0xaf, 0xf2, 0x78, 0xab, 0xf0, 0x50, 0x5b, 0xad, 0xb7, 0x3d, + 0x78, 0xbe, 0x1e, 0xaa, 0x9f, 0x1f, 0x8d, 0x35, 0xd9, 0xb3, 0x66, 0x7a, 0x4a, 0x4c, 0x97, 0x7f, + 0xe0, 0xbf, 0x77, 0xb3, 0x32, 0x27, 0x5b, 0xa9, 0x34, 0xd2, 0x5b, 0x00, 0x61, 0x50, 0xbf, 0xc6, + 0xda, 0x79, 0xe0, 0xef, 0x74, 0xf2, 0xfb, 0x34, 0x92, 0x2c, 0xd6, 0x25, 0xb2, 0xd8, 0x4b, 0xe5, + 0xff, 0x8d, 0x9a, 0xd6, 0xf9, 0xf7, 0xd2, 0x5c, 0x9e, 0xcf, 0x7e, 0x9c, 0xfe, 0xab, 0x62, 0xbc, + 0xd5, 0x09, 0xe6, 0xbf, 0x11, 0x0f, 0xf6, 0x63, 0xc6, 0xbd, 0x24, 0xb4, 0x92, 0x51, 0x29, 0xa1, + 0x29, 0xaa, 0x15, 0x0b, 0xf8, 0x44, 0x69, 0x77, 0x77, 0x77, 0x7d, 0x57, 0x2e, 0x17, 0x04, 0x00, + 0x02, 0x80, 0xe9, 0x15, 0x42, 0xa8, 0x1b, 0xa5, 0x95, 0xd2, 0xff, 0xc1, 0x1c, 0xfc, 0xd9, 0x54, + 0xe9, 0x57, 0x85, 0x37, 0x77, 0xbd, 0x6d, 0xd3, 0x36, 0x47, 0x51, 0xb5, 0x2a, 0xf0, 0x47, 0x3e, + 0x1f, 0x3c, 0x4a, 0xbd, 0x60, 0x55, 0x88, 0x9e, 0xff, 0x6d, 0xb6, 0xdb, 0xf0, 0xdd, 0xdf, 0xcf, + 0x16, 0xc5, 0xb4, 0x12, 0x0b, 0xfc, 0x14, 0x55, 0x7b, 0xa4, 0xb1, 0xfc, 0x48, 0x6e, 0x4c, 0xb7, + 0x22, 0x04, 0x54, 0xe9, 0x8b, 0x7f, 0xe1, 0xcb, 0x4d, 0x2d, 0x22, 0x4d, 0x32, 0x9a, 0x69, 0xaf, + 0xf0, 0xb5, 0x55, 0x55, 0x57, 0x7f, 0xb6, 0xdb, 0x6d, 0xf8, 0x2e, 0xbc, 0xea, 0xbb, 0xe1, 0xc4, + 0x50, 0xc4, 0xf5, 0x7b, 0x6d, 0xb6, 0xdf, 0xf8, 0x40, 0x6a, 0xe3, 0xa0, 0x7e, 0x64, 0x86, 0x8b, + 0x42, 0x80, 0x3f, 0x9b, 0x6d, 0xb6, 0xfc, 0x16, 0x77, 0x7d, 0xdf, 0x77, 0x4a, 0xbd, 0x7c, 0x7d, + 0x47, 0x6f, 0x85, 0xe8, 0xc9, 0x45, 0x7b, 0x0d, 0x34, 0xd9, 0x63, 0x46, 0x45, 0x92, 0x74, 0x10, + 0xcc, 0x4b, 0x4c, 0xff, 0x8d, 0x35, 0x04, 0x76, 0xf1, 0x89, 0xd1, 0x99, 0x9f, 0x0c, 0xb7, 0x6b, + 0x4f, 0xfa, 0xc3, 0x77, 0xb2, 0xb7, 0xbf, 0xf8, 0x50, 0xaf, 0x39, 0x10, 0x6d, 0xa9, 0x53, 0x8d, + 0x98, 0xd2, 0x84, 0xcc, 0x91, 0x6c, 0x5b, 0x24, 0x5d, 0x5f, 0xbe, 0x14, 0xed, 0x2a, 0x59, 0x2a, + 0xd6, 0xca, 0x14, 0x79, 0xb4, 0x65, 0x21, 0xb6, 0xf6, 0x7c, 0x14, 0x88, 0x76, 0xe9, 0x21, 0xc7, + 0x15, 0xbd, 0x89, 0x93, 0x96, 0xd2, 0x3f, 0x18, 0x73, 0xfb, 0x2d, 0xed, 0xb1, 0xa1, 0xba, 0x74, + 0xcb, 0xee, 0xfe, 0x12, 0x9f, 0xc3, 0xa4, 0x81, 0xcb, 0x44, 0xbc, 0x69, 0x0c, 0xa2, 0x37, 0xac, + 0xe8, 0x2f, 0x64, 0x4c, 0x51, 0x90, 0xf5, 0x5e, 0x90, 0xf5, 0xe8, 0x95, 0x56, 0x9f, 0xf8, 0x29, + 0xdd, 0x26, 0x52, 0xc1, 0x3d, 0xd3, 0xa6, 0x60, 0x7c, 0x61, 0xd5, 0x26, 0xa7, 0xcf, 0x49, 0xd5, + 0x52, 0x4b, 0xf0, 0xa1, 0xce, 0xa4, 0xc4, 0x73, 0x73, 0xde, 0xde, 0xba, 0xc4, 0xbe, 0x46, 0x18, + 0xe0, 0xd4, 0x7a, 0x0f, 0x2b, 0x09, 0xdf, 0x8c, 0xf3, 0x52, 0x72, 0x55, 0x2b, 0x0b, 0x68, 0xd6, + 0x35, 0xb7, 0x54, 0xba, 0x17, 0xc6, 0x55, 0xe0, 0xa3, 0x93, 0x31, 0xdb, 0x95, 0x7b, 0x78, 0x91, + 0x5d, 0x34, 0xe5, 0xa3, 0x03, 0xfc, 0x15, 0x08, 0xdd, 0x92, 0x96, 0x48, 0xe2, 0x4d, 0x3f, 0x2f, + 0x84, 0x3c, 0xb9, 0x26, 0x22, 0xc5, 0xcb, 0xd3, 0x8f, 0xcc, 0x35, 0xd5, 0x5f, 0xc5, 0x11, 0x53, + 0x23, 0x1d, 0xd3, 0x6f, 0xc1, 0x50, 0xaa, 0xd1, 0x67, 0xc6, 0xc9, 0xdf, 0xb3, 0xcf, 0x2a, 0x2c, + 0xf8, 0x50, 0xb1, 0xc5, 0x86, 0xd8, 0xb6, 0xb5, 0xc7, 0x24, 0x6c, 0x9f, 0xdc, 0x6a, 0x29, 0x85, + 0xf0, 0x4c, 0x7d, 0x5d, 0xb0, 0xda, 0x2d, 0x45, 0x44, 0x2e, 0xb4, 0x70, 0x90, 0x0e, 0xbe, 0x10, + 0xaf, 0x6a, 0xe8, 0xbc, 0x62, 0xb4, 0x7c, 0xb2, 0x54, 0x3a, 0xd9, 0x46, 0xea, 0x12, 0xa3, 0xe3, + 0x6a, 0x46, 0x5f, 0x19, 0x0d, 0x8b, 0x30, 0xe5, 0x42, 0x0d, 0x70, 0x8f, 0x74, 0xde, 0xd8, 0x35, + 0xed, 0x38, 0xb6, 0xe8, 0x6f, 0x31, 0xb3, 0x98, 0xb4, 0x83, 0xe3, 0x09, 0x3d, 0x2c, 0x0e, 0x5c, + 0x62, 0x66, 0x22, 0xc9, 0x1a, 0x1d, 0x7c, 0xdf, 0x4e, 0xfc, 0x3c, 0x2a, 0x6f, 0x70, 0xe6, 0xe2, + 0xe9, 0x2a, 0x8f, 0x1c, 0x19, 0x4a, 0xc2, 0x63, 0x2c, 0x7f, 0x7f, 0xe0, 0xbe, 0x5a, 0xa2, 0xdc, + 0x47, 0x1a, 0x21, 0xda, 0xed, 0xa5, 0xd7, 0x90, 0xbf, 0xc2, 0x9b, 0x49, 0x33, 0x97, 0xbd, 0x23, + 0xdc, 0x4d, 0xbd, 0xe7, 0x99, 0xcb, 0xe1, 0x42, 0xec, 0xfc, 0x69, 0x9a, 0xaf, 0x9a, 0x69, 0x7d, + 0xd5, 0x9e, 0xbe, 0x37, 0x36, 0x1e, 0x11, 0x9e, 0xbc, 0xb8, 0xcc, 0x52, 0xac, 0xfb, 0x75, 0xd5, + 0xa4, 0xb4, 0xc5, 0xb4, 0xff, 0xc5, 0xd9, 0x9e, 0x8d, 0xe6, 0xa9, 0xe6, 0xbf, 0x84, 0xef, 0xa5, + 0x4d, 0x7e, 0x12, 0xd2, 0x3d, 0xbe, 0x6d, 0xa1, 0xb7, 0xf1, 0x96, 0x6c, 0xf7, 0x7c, 0xd9, 0xdc, + 0xb1, 0xde, 0xba, 0xf8, 0x68, 0xad, 0x57, 0xab, 0x69, 0xa6, 0x9f, 0xf8, 0xeb, 0x2a, 0xca, 0xbc, + 0x20, 0x6b, 0xef, 0x74, 0x52, 0x3e, 0x6c, 0x66, 0xdf, 0x24, 0xff, 0x4d, 0x3f, 0x19, 0x1c, 0x9d, + 0x6e, 0x65, 0xb7, 0x59, 0xb5, 0xb5, 0x59, 0x9c, 0xfa, 0x76, 0x1d, 0xfd, 0xda, 0xf0, 0x55, 0xcf, + 0x4e, 0xfa, 0x3e, 0x87, 0x8b, 0xaf, 0x69, 0xa4, 0x8b, 0xcf, 0x2a, 0x7c, 0x2b, 0x96, 0x4b, 0x97, + 0xfe, 0x0a, 0xad, 0x32, 0x68, 0xd1, 0x1e, 0x55, 0x6a, 0xed, 0xcd, 0x36, 0xd8, 0x3b, 0x9f, 0x09, + 0xdd, 0x9e, 0x8c, 0x96, 0x5a, 0x2d, 0x68, 0xf0, 0x41, 0x69, 0xa2, 0x77, 0x46, 0x93, 0x89, 0x38, + 0x94, 0xc2, 0xa0, 0xcb, 0x58, 0xbe, 0x9a, 0x69, 0xa7, 0xe0, 0xae, 0xad, 0x4b, 0x54, 0xcc, 0x4b, + 0xe6, 0xd2, 0x27, 0xc1, 0x05, 0x36, 0xcd, 0xaf, 0xd4, 0x66, 0xd8, 0x70, 0xea, 0xd2, 0xb9, 0xc5, + 0x58, 0xab, 0xff, 0x0c, 0x6d, 0x4f, 0xbb, 0x31, 0xde, 0x62, 0xea, 0xd3, 0x5f, 0xe3, 0x2b, 0x9a, + 0x59, 0x23, 0xa5, 0xb5, 0xa4, 0xd9, 0x29, 0xe0, 0xa0, 0xa6, 0xa8, 0xff, 0xd4, 0x72, 0xae, 0x6e, + 0x3e, 0xfd, 0xf0, 0xa5, 0xd0, 0xee, 0x8c, 0xb4, 0x67, 0x4c, 0x9a, 0xdf, 0xbb, 0x70, 0xe7, 0x1f, + 0x8f, 0x20, 0x99, 0x1d, 0x78, 0xcb, 0x33, 0xc7, 0x2e, 0x97, 0x4f, 0xaf, 0xd3, 0xd1, 0x61, 0x8c, + 0xe9, 0xbe, 0x37, 0x9f, 0x82, 0xda, 0xaa, 0xaa, 0xbe, 0xed, 0xf0, 0x57, 0xa7, 0x4c, 0x90, 0x5e, + 0xa7, 0x7a, 0x1a, 0x9e, 0x51, 0xc5, 0xf1, 0x93, 0x63, 0xb0, 0xf8, 0xa9, 0x5d, 0x1f, 0x19, 0xc1, + 0x7b, 0xfb, 0x3b, 0xbe, 0xa0, 0xef, 0x4e, 0x17, 0x8d, 0x8d, 0x2c, 0xbb, 0xbb, 0x13, 0xc7, 0xa6, + 0xf7, 0x23, 0xe3, 0x43, 0x61, 0x37, 0x1c, 0xa6, 0x9a, 0x69, 0xff, 0x8d, 0xb1, 0x29, 0xd9, 0xb4, + 0x92, 0x77, 0xa9, 0xa2, 0x51, 0x94, 0x77, 0x61, 0x2e, 0x26, 0x5f, 0x97, 0x4b, 0xbe, 0x14, 0x32, + 0x51, 0x99, 0x79, 0x92, 0xf3, 0x47, 0x26, 0x5b, 0x6f, 0x53, 0xc0, 0xdd, 0xf0, 0xa4, 0xcc, 0x52, + 0xcb, 0xed, 0x4f, 0x87, 0x84, 0x2a, 0x4d, 0x52, 0xb6, 0x66, 0xf1, 0x20, 0xab, 0x13, 0xbd, 0x0b, + 0x8a, 0xa8, 0xd9, 0x97, 0x13, 0x75, 0x49, 0x7c, 0x14, 0xd7, 0x69, 0xa4, 0x6c, 0x72, 0x4c, 0xdc, + 0xf9, 0xbb, 0xc4, 0x82, 0xb1, 0x1e, 0x79, 0x9e, 0x8b, 0xcc, 0x9a, 0x8e, 0x0d, 0x2b, 0x37, 0x3e, + 0x14, 0x1b, 0x2a, 0xa4, 0x2b, 0xe3, 0x68, 0x57, 0xa4, 0x9e, 0x91, 0x37, 0x35, 0xf1, 0x9d, 0x53, + 0x1f, 0x55, 0xd6, 0x26, 0x8e, 0x9d, 0x39, 0xda, 0x7d, 0x73, 0x7c, 0x3a, 0x47, 0x62, 0x7b, 0x79, + 0x65, 0x34, 0x87, 0x53, 0x0e, 0x6c, 0x1e, 0xbe, 0x6e, 0xff, 0x85, 0x23, 0xf9, 0xc7, 0x5a, 0x63, + 0xff, 0xfc, 0xfc, 0xe4, 0x1d, 0xd9, 0x53, 0x97, 0xc7, 0x5f, 0x6e, 0xf6, 0xdc, 0xec, 0x3b, 0x99, + 0xf0, 0x99, 0x72, 0x12, 0x21, 0x24, 0x32, 0xe9, 0x18, 0x7d, 0x7c, 0x64, 0xbd, 0xfd, 0x24, 0xee, + 0x9f, 0x6c, 0x9a, 0xdd, 0xf8, 0xc2, 0xbb, 0xad, 0xda, 0x3b, 0x10, 0xe2, 0xa4, 0x88, 0xec, 0x6f, + 0x61, 0xfc, 0x15, 0x08, 0x6e, 0x9d, 0x38, 0x63, 0x72, 0x8e, 0x8e, 0x76, 0x1d, 0xfe, 0x14, 0x39, + 0xb1, 0xa8, 0x51, 0xef, 0xb8, 0x87, 0x35, 0x5e, 0x7d, 0x43, 0xb4, 0x81, 0xac, 0x73, 0xe0, 0xaf, + 0x1b, 0xca, 0x19, 0xe1, 0x06, 0xc9, 0x14, 0x6a, 0x2e, 0x64, 0x10, 0x1d, 0x5c, 0x29, 0x76, 0x9c, + 0xcc, 0x17, 0xa1, 0x53, 0xc8, 0xda, 0xc8, 0xdd, 0x7c, 0x1e, 0x86, 0x7e, 0xa6, 0xc3, 0xfc, 0x28, + 0x22, 0xb6, 0xf4, 0xf6, 0x6a, 0xd8, 0xfe, 0x38, 0x34, 0x34, 0x97, 0xd9, 0xf0, 0xa0, 0x95, 0xa7, + 0x15, 0xf7, 0xab, 0x70, 0xa5, 0x38, 0x34, 0x4d, 0xc5, 0x65, 0x6a, 0x4a, 0xd3, 0x01, 0xc5, 0xb5, + 0x68, 0x4b, 0xda, 0x25, 0xfe, 0x14, 0x25, 0x09, 0x9a, 0xec, 0x35, 0x9e, 0xda, 0x44, 0xd3, 0xee, + 0xe7, 0xd4, 0xb5, 0x16, 0x07, 0xce, 0x22, 0x30, 0x49, 0x0d, 0x44, 0xa8, 0xd0, 0xe3, 0x64, 0x27, + 0x87, 0x4d, 0x3f, 0x24, 0xa2, 0x44, 0xd3, 0xa9, 0x18, 0x8d, 0x73, 0xca, 0x07, 0xaf, 0x8e, 0x22, + 0x08, 0x94, 0x96, 0x4f, 0x2d, 0x1e, 0x18, 0xac, 0xb6, 0x5a, 0x16, 0xf1, 0x31, 0x85, 0xae, 0xb9, + 0xfa, 0x4e, 0xfc, 0xa8, 0x27, 0x70, 0xb1, 0x8a, 0x15, 0x7c, 0x2c, 0x09, 0xf7, 0x32, 0x9f, 0x82, + 0xb3, 0x34, 0xdb, 0xd5, 0xcd, 0xfc, 0xcf, 0x74, 0xc3, 0xe3, 0x44, 0x28, 0xba, 0xd3, 0x36, 0x45, + 0x5a, 0x49, 0x37, 0x5a, 0xa8, 0xd4, 0xd9, 0x1d, 0x3e, 0xe9, 0xbd, 0x3f, 0x0f, 0x69, 0xcf, 0x04, + 0x66, 0xaf, 0x18, 0xd2, 0xbd, 0x73, 0x7f, 0x8e, 0x1c, 0x75, 0x7f, 0xf0, 0x56, 0x73, 0xce, 0xa1, + 0x0f, 0x6e, 0xa4, 0xdf, 0x11, 0x30, 0x9b, 0x5f, 0x5f, 0x17, 0xcd, 0x16, 0x47, 0xcd, 0x5f, 0x0d, + 0xc1, 0xd9, 0xa3, 0x95, 0x1c, 0xed, 0x1a, 0xb9, 0x60, 0xed, 0x87, 0xf8, 0x7e, 0x68, 0xb6, 0x95, + 0xa6, 0x9a, 0x68, 0xb9, 0xaa, 0x47, 0x13, 0x73, 0x71, 0xf7, 0x67, 0xff, 0x19, 0x50, 0xe3, 0xfb, + 0xc6, 0xd8, 0x27, 0xcd, 0x21, 0xfe, 0xb3, 0x8a, 0x66, 0xd1, 0x78, 0xb9, 0xe1, 0x7c, 0x91, 0x33, + 0x66, 0x97, 0xc2, 0x93, 0xf7, 0xb7, 0xa6, 0x9c, 0xfb, 0x6f, 0x43, 0xbe, 0x5f, 0x19, 0x5b, 0x48, + 0xb8, 0xc6, 0x56, 0xc5, 0x04, 0x9d, 0x06, 0xdb, 0x7a, 0x21, 0xa9, 0xaf, 0x18, 0x55, 0xd0, 0xd1, + 0x9b, 0x96, 0x27, 0xf1, 0xb4, 0x36, 0x4d, 0x45, 0x9a, 0xf9, 0x63, 0xf1, 0x58, 0xd4, 0x13, 0x6a, + 0xe8, 0xd6, 0xd1, 0x33, 0xc2, 0x9d, 0x93, 0x9f, 0x51, 0x2e, 0x1c, 0xab, 0x19, 0xe9, 0xb5, 0x4d, + 0x9b, 0xbb, 0x9f, 0x0d, 0x93, 0x21, 0x05, 0x6a, 0xcd, 0x66, 0xc5, 0x17, 0xf8, 0x63, 0x97, 0x1b, + 0xd4, 0xae, 0x5c, 0xba, 0xdf, 0xf8, 0x4a, 0x7c, 0xf5, 0xbe, 0xd9, 0xf8, 0x7e, 0xf6, 0xd5, 0x12, + 0xd8, 0x39, 0xa8, 0x96, 0xbe, 0xdb, 0x69, 0xa7, 0xe0, 0x92, 0xc7, 0x8c, 0x5b, 0x17, 0xc1, 0x5d, + 0xdf, 0x2e, 0xdb, 0x52, 0xd6, 0x9a, 0x34, 0x79, 0x7c, 0x6e, 0xa9, 0x57, 0x60, 0xd2, 0xb7, 0x19, + 0xe7, 0x4f, 0x27, 0x56, 0xdb, 0x4d, 0x3f, 0xf0, 0x4b, 0xc6, 0xda, 0x15, 0xb4, 0x2c, 0xae, 0xf2, + 0xef, 0x41, 0xf0, 0xce, 0xe3, 0xb7, 0x57, 0x05, 0x7d, 0x04, 0xda, 0xff, 0xc6, 0xda, 0x6b, 0x7e, + 0x17, 0x9a, 0xb1, 0xd1, 0x24, 0x59, 0x46, 0x9b, 0x37, 0x2a, 0xcb, 0x0c, 0x90, 0xcd, 0x55, 0x7f, + 0x85, 0x78, 0x9a, 0x54, 0x70, 0xe5, 0xd6, 0xa0, 0x8a, 0x66, 0x2d, 0xff, 0x87, 0xaa, 0x9b, 0x27, + 0x8c, 0xac, 0x51, 0x97, 0x76, 0x9a, 0xd5, 0xdc, 0xbd, 0xff, 0xfc, 0x3b, 0xf1, 0xa4, 0x57, 0xea, + 0x32, 0xb5, 0xf7, 0x31, 0x44, 0x93, 0x67, 0x49, 0x4d, 0x14, 0xd4, 0x51, 0x7f, 0x82, 0x02, 0x36, + 0x4d, 0xab, 0x3d, 0x92, 0xc9, 0x65, 0xc2, 0xe6, 0x31, 0xe7, 0x05, 0x34, 0xd6, 0x97, 0xf8, 0x47, + 0x2f, 0x1d, 0xd6, 0x25, 0x4a, 0xaf, 0x6d, 0x3f, 0x19, 0xaa, 0xae, 0x99, 0xeb, 0x6c, 0xf5, 0x35, + 0x6b, 0x8e, 0x7f, 0x6f, 0xc6, 0xe7, 0xc8, 0x6e, 0xaf, 0xbe, 0xd3, 0x2b, 0x56, 0x4e, 0x96, 0x62, + 0x43, 0x8f, 0xf6, 0xdc, 0xdd, 0x7c, 0x21, 0x54, 0x4c, 0xae, 0xcd, 0xb4, 0x4e, 0xda, 0x7f, 0x1e, + 0x52, 0xd8, 0xc5, 0xa9, 0x44, 0xfc, 0x79, 0x0f, 0x97, 0xcb, 0xfc, 0x10, 0xf4, 0xdb, 0xd9, 0xf0, + 0xe8, 0x85, 0x1a, 0x54, 0xdc, 0x41, 0x9c, 0x0d, 0xb1, 0x85, 0x8a, 0x34, 0x06, 0xcf, 0x8a, 0xe2, + 0xb7, 0xf1, 0x83, 0x6c, 0x4a, 0x46, 0x25, 0xa9, 0x5a, 0x1b, 0xe8, 0x6a, 0x9f, 0x8f, 0x33, 0x66, + 0xff, 0x63, 0x7c, 0xd8, 0xd7, 0x87, 0x4e, 0x35, 0x00, 0x84, 0xd3, 0x1e, 0xa7, 0x7c, 0x4d, 0x3b, + 0x99, 0x96, 0x9f, 0x6a, 0xbf, 0xe0, 0x96, 0xab, 0x94, 0x3a, 0xd8, 0xa1, 0xb5, 0x51, 0x11, 0x47, + 0x0a, 0x44, 0xf8, 0x2a, 0xb0, 0x79, 0xda, 0x47, 0x15, 0x93, 0xb0, 0xc6, 0xd1, 0x8e, 0x40, 0x5c, + 0xd5, 0x5a, 0x33, 0x26, 0x3e, 0x0b, 0x88, 0x2b, 0x15, 0xb4, 0x7c, 0x6a, 0xd3, 0x47, 0x5f, 0xc6, + 0x1d, 0x3b, 0x6a, 0x9a, 0x6d, 0xb6, 0xef, 0x72, 0xe3, 0x33, 0xf8, 0x8b, 0x43, 0xea, 0xd3, 0xf5, + 0xdb, 0x53, 0xb4, 0xfe, 0x78, 0x2c, 0x32, 0x4d, 0xed, 0x35, 0xea, 0x99, 0x67, 0xf8, 0xc2, 0xc3, + 0x49, 0x34, 0xd9, 0xbb, 0xb2, 0x0c, 0x5c, 0x47, 0x2b, 0x4d, 0x99, 0xaa, 0xb8, 0xca, 0x06, 0x81, + 0xa4, 0x95, 0xee, 0xef, 0x19, 0x56, 0x9e, 0x37, 0xf0, 0x52, 0x22, 0xdb, 0xf7, 0xbf, 0x69, 0x95, + 0xcf, 0x2f, 0xc1, 0x11, 0xcb, 0x2b, 0x77, 0xf8, 0xe2, 0x86, 0xae, 0xab, 0x04, 0x08, 0x7f, 0x0e, + 0x06, 0x08, 0x6a, 0x0c, 0xb8, 0x58, 0xfd, 0x24, 0x5c, 0x6c, 0xcb, 0xc6, 0x12, 0x0d, 0x42, 0x55, + 0x1d, 0xa3, 0x5a, 0x94, 0x7a, 0xe2, 0x9d, 0x1d, 0xa3, 0x9c, 0x6d, 0x1c, 0xe9, 0x35, 0xf0, 0xa5, + 0x98, 0xa3, 0x93, 0x7b, 0x48, 0x6a, 0xa9, 0x73, 0x65, 0xcf, 0x6e, 0x4a, 0xe4, 0x75, 0x7c, 0x66, + 0x98, 0x71, 0x72, 0x04, 0x10, 0x14, 0x94, 0xe2, 0x07, 0xc3, 0xbd, 0x5d, 0xcd, 0xdc, 0x91, 0x73, + 0xb4, 0x3f, 0x18, 0x5c, 0x94, 0x75, 0x20, 0x4a, 0x19, 0x7f, 0x4c, 0x8c, 0x39, 0x8a, 0x54, 0xbc, + 0x29, 0x4d, 0x3e, 0xee, 0x6e, 0xba, 0x6f, 0xd3, 0x17, 0x27, 0xc5, 0x5d, 0x8f, 0x2b, 0xe8, 0x7f, + 0x0f, 0x0c, 0xd5, 0x36, 0x95, 0x5d, 0xd6, 0x6d, 0x64, 0x1b, 0x99, 0x95, 0xe9, 0x6e, 0x1a, 0xcb, + 0x7f, 0xe1, 0xf2, 0xf3, 0xb1, 0xc2, 0x7c, 0xee, 0x6a, 0xc6, 0x65, 0x2e, 0x00, 0x45, 0x94, 0xc7, + 0xb2, 0x22, 0x9a, 0xdf, 0x3e, 0x1f, 0xf8, 0x27, 0xa2, 0x5a, 0x09, 0x62, 0x5f, 0x91, 0x67, 0xc2, + 0x25, 0x31, 0x0b, 0x47, 0xb7, 0xf1, 0xea, 0x3f, 0xb9, 0x88, 0x3d, 0xd8, 0xdf, 0xc6, 0xd1, 0x90, + 0x9b, 0x18, 0x74, 0x5b, 0x0c, 0x9e, 0x4f, 0x6f, 0x95, 0x84, 0xf9, 0xcb, 0x56, 0x44, 0xff, 0xe0, + 0xaa, 0x5c, 0x8a, 0x8d, 0x23, 0x36, 0x5e, 0xda, 0xb6, 0x32, 0xbc, 0x76, 0xf8, 0x68, 0x88, 0x66, + 0xe9, 0x51, 0xc1, 0x4e, 0x99, 0x6b, 0xfe, 0x14, 0xb2, 0x69, 0x94, 0x86, 0xb5, 0xba, 0xd1, 0x26, + 0x78, 0xb4, 0xe9, 0x31, 0xf0, 0x58, 0x54, 0xa1, 0x2a, 0xa4, 0x92, 0xaa, 0xec, 0xec, 0x74, 0x76, + 0x7c, 0x69, 0x25, 0x9a, 0x35, 0x9d, 0x06, 0xda, 0xc2, 0xd1, 0x5c, 0x9d, 0x23, 0x65, 0x5e, 0xb9, + 0xf9, 0xbf, 0xf8, 0x53, 0x49, 0x9b, 0x34, 0xf3, 0xd5, 0x9a, 0x49, 0x79, 0x37, 0x7f, 0x82, 0x1b, + 0xda, 0xe7, 0xf8, 0x78, 0x91, 0x25, 0x9a, 0x06, 0x35, 0xe5, 0x63, 0x4a, 0xfd, 0x34, 0xd3, 0x4f, + 0xc2, 0x95, 0xf7, 0xdd, 0x5e, 0xfa, 0x53, 0xd2, 0x2b, 0x0d, 0xd9, 0x31, 0xd5, 0x2b, 0x3f, 0x7c, + 0x29, 0xa7, 0xab, 0x33, 0xde, 0x5c, 0x8a, 0xb6, 0xc3, 0x4f, 0x9b, 0xf6, 0xa3, 0x7c, 0x29, 0x1e, + 0xf3, 0xef, 0x5c, 0x94, 0xed, 0x21, 0xb1, 0xd2, 0xbe, 0x6f, 0x8c, 0xcf, 0xed, 0xa3, 0x86, 0xf7, + 0x76, 0x39, 0x74, 0x69, 0x4d, 0xcf, 0xff, 0x1b, 0xed, 0xa4, 0x94, 0x77, 0x1d, 0x9c, 0x94, 0x75, + 0xba, 0xd9, 0xf5, 0xf6, 0xdb, 0x6d, 0xbf, 0x05, 0x13, 0x92, 0x39, 0x2c, 0x79, 0xa1, 0xe4, 0xab, + 0xaf, 0x2f, 0x82, 0xdc, 0xbe, 0x4e, 0x72, 0x47, 0x25, 0x8e, 0xfb, 0xdf, 0x1b, 0x9f, 0xa7, 0x5a, + 0xde, 0xce, 0x93, 0x67, 0xdc, 0xf4, 0x56, 0x7b, 0x6d, 0xb6, 0xdf, 0x86, 0xca, 0x69, 0x67, 0x82, + 0xe2, 0x1e, 0x23, 0xff, 0xc6, 0x4d, 0x44, 0x9e, 0x5e, 0x79, 0xed, 0xc9, 0xf6, 0x51, 0xbc, 0xfc, + 0x10, 0x1f, 0x2d, 0x0b, 0x42, 0xd8, 0x69, 0x1d, 0x6c, 0xf3, 0xea, 0xe6, 0x7d, 0x97, 0x5b, 0x6d, + 0xb6, 0xfc, 0x3f, 0x92, 0x0d, 0x33, 0x07, 0x79, 0x77, 0x17, 0x55, 0xbd, 0x00, 0xc5, 0x95, 0x5a, + 0xa1, 0x57, 0x56, 0xde, 0xdc, 0xdc, 0xfd, 0xdd, 0xff, 0xc1, 0x81, 0x8a, 0x42, 0xfb, 0x4e, 0x9a, + 0x77, 0x6a, 0xd7, 0x77, 0x76, 0xdb, 0xad, 0xbf, 0x1b, 0xd2, 0x49, 0x34, 0xea, 0xef, 0x91, 0xcd, + 0xcd, 0xbe, 0xdb, 0x6d, 0xb7, 0xe1, 0x4b, 0x6d, 0x52, 0x2c, 0x6b, 0xa7, 0x23, 0x35, 0x1a, 0x36, + 0xc4, 0x75, 0xa3, 0x46, 0xe6, 0x7c, 0x3b, 0xba, 0x69, 0x9b, 0x71, 0xbf, 0x8d, 0xbe, 0xb9, 0x43, + 0xb6, 0xff, 0xe1, 0x4d, 0xa1, 0x0f, 0x53, 0x93, 0xa2, 0xcb, 0xcb, 0x05, 0x78, 0x1e, 0xbd, 0x6b, + 0x57, 0xd8, 0x4c, 0xf8, 0x2a, 0x2d, 0xa6, 0xa7, 0xd7, 0x72, 0x10, 0x58, 0xd6, 0x3d, 0x8c, 0xdd, + 0xfc, 0x48, 0x2e, 0x22, 0x49, 0x65, 0x50, 0x4c, 0xdd, 0x3f, 0x89, 0x0a, 0x19, 0x10, 0x6d, 0xc6, + 0x6e, 0xdf, 0xdb, 0x8e, 0xba, 0x88, 0x78, 0xad, 0x6a, 0xfd, 0xf1, 0xc2, 0xdb, 0xb6, 0xa8, 0x2b, + 0x49, 0x32, 0x7b, 0xf8, 0xe9, 0xb1, 0xac, 0x9b, 0xd5, 0xb4, 0xda, 0xbf, 0xe1, 0x0e, 0xe6, 0xd4, + 0xe3, 0x7c, 0x8c, 0xb5, 0xf8, 0x2c, 0x98, 0x9a, 0x76, 0x1d, 0x91, 0xf2, 0xb3, 0xd2, 0xf3, 0xe1, + 0x7b, 0xe1, 0x4b, 0x63, 0xc3, 0x08, 0xfa, 0xd6, 0xc3, 0x7c, 0x9f, 0x08, 0x58, 0xcf, 0x9a, 0x7e, + 0x46, 0x56, 0x32, 0x32, 0xff, 0x1b, 0x32, 0xe4, 0x51, 0xb1, 0xbf, 0xc1, 0xed, 0xba, 0x5b, 0xa0, + 0xda, 0x1a, 0x79, 0x44, 0xbe, 0xaa, 0xab, 0xe1, 0x02, 0xb1, 0xbe, 0x35, 0x72, 0x0d, 0x95, 0x5d, + 0x09, 0xbb, 0x2b, 0x0f, 0xc2, 0x04, 0x54, 0xae, 0xe5, 0x67, 0x23, 0x14, 0x3f, 0x8c, 0x99, 0xab, + 0x27, 0x27, 0xab, 0x4c, 0x98, 0xcd, 0x93, 0x75, 0x5f, 0x05, 0x3d, 0xdd, 0xaa, 0xb1, 0x5d, 0xee, + 0xfb, 0xa4, 0xdf, 0xe3, 0x08, 0x9e, 0x9a, 0xcb, 0xfa, 0x4d, 0x16, 0x16, 0xcf, 0x5f, 0xc6, 0x63, + 0xb2, 0xaf, 0xf4, 0x9b, 0x93, 0xf1, 0xfc, 0xa3, 0x1d, 0xf2, 0x24, 0x14, 0x49, 0x18, 0xc7, 0xc2, + 0x87, 0x1d, 0x88, 0x86, 0x97, 0x5d, 0x25, 0x74, 0x18, 0x68, 0xad, 0xfb, 0x41, 0xaa, 0x84, 0x2c, + 0x1f, 0x05, 0xc2, 0xef, 0x17, 0xa1, 0x0c, 0xc4, 0x57, 0x80, 0xb7, 0xc2, 0x91, 0x76, 0x40, 0x62, + 0xa7, 0x70, 0xb3, 0x33, 0x3d, 0x59, 0xb6, 0x5a, 0x25, 0x89, 0x50, 0x98, 0xd1, 0x26, 0xc1, 0x04, + 0x89, 0xf0, 0xa4, 0xcb, 0xa3, 0xa5, 0x48, 0x25, 0xe0, 0x97, 0x24, 0x92, 0x16, 0xdd, 0x39, 0xa5, + 0x0e, 0xd1, 0xcc, 0xcf, 0xb6, 0x8d, 0xfb, 0xac, 0xb7, 0x76, 0xd9, 0x69, 0x5b, 0xb0, 0x89, 0xf0, + 0xa1, 0x61, 0x06, 0x1b, 0xa4, 0xb9, 0x1f, 0x4a, 0xea, 0x2c, 0x8d, 0xd3, 0xc4, 0xe3, 0xd0, 0x50, + 0x75, 0x34, 0x7b, 0x84, 0xdb, 0x5b, 0x88, 0xc7, 0xc2, 0x84, 0xa4, 0x67, 0xc2, 0x53, 0x42, 0xfb, + 0x84, 0x37, 0x78, 0xf6, 0xb8, 0xeb, 0x5c, 0xd0, 0xf9, 0x55, 0x50, 0xc9, 0xb9, 0x31, 0xf1, 0x98, + 0x6e, 0x61, 0xd1, 0xad, 0xc7, 0xfc, 0xed, 0xed, 0x9b, 0x84, 0xb0, 0xf7, 0x52, 0xe6, 0x2d, 0xb4, + 0xfc, 0x26, 0x5b, 0x25, 0xf4, 0xa5, 0xc3, 0x7f, 0x1d, 0xb7, 0x4f, 0x33, 0xca, 0xed, 0x26, 0xfc, + 0x61, 0x1b, 0x6f, 0x6d, 0x26, 0x4d, 0xc5, 0x6d, 0x9b, 0x6e, 0x6d, 0x2e, 0xfe, 0x34, 0x62, 0x54, + 0x3b, 0x49, 0x26, 0x83, 0x9f, 0xba, 0x19, 0x3c, 0xd1, 0xb5, 0x0e, 0x56, 0x30, 0x63, 0xbc, 0xcb, + 0x04, 0xf7, 0x2f, 0xf0, 0xa0, 0x95, 0x44, 0xd1, 0x25, 0xbb, 0x65, 0xeb, 0xd2, 0xe5, 0x61, 0xfe, + 0x11, 0xcb, 0x0a, 0x26, 0x93, 0xa8, 0x6d, 0x09, 0xb6, 0xe7, 0xe1, 0x0c, 0xdd, 0x17, 0x24, 0xd2, + 0xae, 0xec, 0x93, 0xf0, 0xa1, 0x23, 0xb8, 0x3c, 0xbc, 0xb8, 0x58, 0xf9, 0x6c, 0xcd, 0x83, 0x93, + 0xb5, 0xbb, 0xcb, 0xe3, 0x63, 0xb3, 0x51, 0xd5, 0x46, 0x5a, 0x96, 0x97, 0x0c, 0xb2, 0x5e, 0x3b, + 0x4d, 0xcf, 0x2c, 0x97, 0xe4, 0x18, 0x7b, 0x26, 0x7f, 0xe0, 0x98, 0xb4, 0xe5, 0x8c, 0xb1, 0x8e, + 0xc3, 0xbf, 0xc3, 0xbc, 0x77, 0xfb, 0x8a, 0xa6, 0x83, 0xac, 0xf5, 0x6c, 0x57, 0x15, 0xff, 0x87, + 0xe4, 0x8f, 0x0a, 0xd3, 0x4a, 0xd2, 0x28, 0xfa, 0x0e, 0x2c, 0x6f, 0xa1, 0xbf, 0xfe, 0x33, 0xcd, + 0x53, 0xc1, 0x74, 0x9b, 0xd5, 0x2b, 0x26, 0xd9, 0x78, 0x20, 0xee, 0xe5, 0x44, 0x8e, 0xb8, 0xdf, + 0x95, 0xfa, 0x9d, 0x36, 0x93, 0xa6, 0x9f, 0xfc, 0x6d, 0xdb, 0xf5, 0x73, 0xc3, 0x4c, 0xe4, 0x25, + 0x51, 0x05, 0x5b, 0x6c, 0x54, 0xde, 0xda, 0x69, 0xa6, 0x9f, 0x85, 0x35, 0x2e, 0x6b, 0x51, 0xd3, + 0x8b, 0x5a, 0x5c, 0xba, 0x94, 0x64, 0x07, 0xc3, 0x33, 0xcd, 0xc7, 0xf1, 0x54, 0x89, 0x91, 0xe2, + 0x78, 0x2f, 0xc7, 0xf8, 0x44, 0x99, 0xf1, 0x92, 0x49, 0x17, 0x56, 0x7f, 0x4a, 0x24, 0xbc, 0x16, + 0x6d, 0x13, 0xed, 0xea, 0x9b, 0xb5, 0x3d, 0xf0, 0xa4, 0xec, 0x41, 0xcb, 0xb4, 0x8d, 0x58, 0x9f, + 0xb9, 0x67, 0x73, 0x7f, 0x82, 0x1d, 0x35, 0x2c, 0x62, 0xf8, 0xd3, 0x95, 0x86, 0xf9, 0x99, 0x43, + 0x63, 0x83, 0x52, 0x5e, 0x0d, 0xdf, 0x6f, 0x6b, 0x1f, 0x8d, 0x57, 0xb6, 0xdb, 0x6d, 0xf8, 0xc2, + 0x73, 0x41, 0x92, 0xef, 0x4c, 0x76, 0xe5, 0x34, 0x92, 0x6b, 0xe1, 0xeb, 0x51, 0xb5, 0x98, 0xc6, + 0xf3, 0xf6, 0x74, 0xff, 0x79, 0x57, 0xff, 0x19, 0x95, 0x42, 0xdb, 0xdb, 0xad, 0xf3, 0x6e, 0x96, + 0xc8, 0xa5, 0x22, 0xf0, 0xa5, 0xf3, 0xe0, 0x33, 0x48, 0x7f, 0xfd, 0x22, 0x69, 0xaa, 0xab, 0x5e, + 0x37, 0xc7, 0xf2, 0xf8, 0x2c, 0xb4, 0x85, 0x66, 0x77, 0xc2, 0x5c, 0x1e, 0xbb, 0x99, 0xac, 0x72, + 0x7f, 0x1e, 0x7c, 0x29, 0xd5, 0x4f, 0x22, 0x51, 0xa4, 0x6b, 0x8f, 0xbb, 0x98, 0x85, 0xc4, 0x18, + 0x51, 0x44, 0x8b, 0xc3, 0xd4, 0x0c, 0x84, 0x14, 0x99, 0x8f, 0x8e, 0xa5, 0x61, 0x0e, 0x35, 0x6c, + 0xde, 0xbf, 0xe3, 0x66, 0xd8, 0xe8, 0x21, 0xa8, 0xfe, 0x94, 0x78, 0x79, 0x39, 0x05, 0xc5, 0x9d, + 0x74, 0x3a, 0x3c, 0x21, 0x94, 0xaf, 0xcb, 0x8f, 0x9c, 0x63, 0x06, 0x68, 0xd3, 0x67, 0xe3, 0xf7, + 0x77, 0x52, 0x62, 0x5e, 0xef, 0xe1, 0x41, 0x2a, 0x24, 0x53, 0xe1, 0xd8, 0x45, 0xc2, 0x39, 0x44, + 0x04, 0xa2, 0x02, 0xc1, 0x03, 0x44, 0xe9, 0xaf, 0x56, 0xfc, 0xf8, 0xdf, 0x05, 0x24, 0xad, 0x4f, + 0xae, 0x84, 0x6a, 0x74, 0x69, 0x3d, 0xb2, 0x5e, 0x20, 0x29, 0x32, 0x8c, 0xba, 0x27, 0xbc, 0xb2, + 0x95, 0x9b, 0x6c, 0x6e, 0x3b, 0x7c, 0x29, 0x6e, 0xd6, 0x21, 0xc8, 0x56, 0x38, 0x18, 0x8e, 0x06, + 0xaa, 0xc7, 0xf2, 0x0e, 0x3c, 0xcc, 0xbf, 0xc2, 0x86, 0x74, 0x17, 0x50, 0xff, 0x3f, 0xd9, 0x98, + 0x32, 0x61, 0xa0, 0xe3, 0x8c, 0x65, 0x70, 0xc2, 0xd3, 0x24, 0x99, 0x13, 0x71, 0x92, 0x2f, 0x0a, + 0x09, 0xa1, 0xc9, 0x8a, 0xb6, 0xe7, 0x62, 0xbd, 0x0d, 0xef, 0x4a, 0xbc, 0x15, 0xe6, 0xa4, 0x99, + 0xca, 0xa2, 0x53, 0x28, 0x6e, 0xe5, 0x45, 0x5e, 0x14, 0x95, 0x88, 0xca, 0xc2, 0xc8, 0xd1, 0x8b, + 0x2d, 0xa3, 0x19, 0x86, 0xe6, 0x13, 0xbe, 0xa3, 0xb9, 0xc9, 0xfb, 0xe0, 0x82, 0x34, 0x99, 0x2d, + 0x6f, 0x62, 0x0d, 0x0d, 0x8e, 0x0c, 0x72, 0xb9, 0xef, 0x99, 0xf4, 0xd3, 0x4d, 0x3f, 0x04, 0x14, + 0x11, 0xb0, 0x83, 0xd2, 0x49, 0x54, 0xf2, 0x63, 0xd8, 0xfb, 0xe9, 0x4f, 0xdb, 0xf0, 0x55, 0xbb, + 0x77, 0x5d, 0x79, 0xac, 0x64, 0xc2, 0x51, 0x94, 0xca, 0xbf, 0x82, 0x2a, 0x19, 0x98, 0x43, 0xc8, + 0x8d, 0xf0, 0x47, 0x74, 0x36, 0x32, 0xb0, 0x9d, 0x78, 0x92, 0x2a, 0xac, 0xb9, 0x6d, 0x7c, 0x23, + 0xa1, 0xbe, 0xd9, 0x63, 0xb5, 0x4c, 0xb5, 0xf1, 0x91, 0xe9, 0xad, 0x7c, 0xd6, 0x82, 0x4d, 0x31, + 0xfc, 0xb1, 0xdc, 0x8f, 0xe1, 0x45, 0x06, 0xe3, 0x5b, 0xf0, 0xa1, 0x6b, 0xdd, 0xed, 0x98, 0xcc, + 0x75, 0x9b, 0x60, 0xdc, 0x1b, 0x4e, 0xb8, 0x3a, 0x77, 0x88, 0x85, 0x38, 0x70, 0x58, 0xc5, 0xb7, + 0xf6, 0x60, 0xe5, 0x87, 0x41, 0xe8, 0xd0, 0x6c, 0x46, 0xac, 0x84, 0x18, 0xb7, 0x59, 0x01, 0x92, + 0xc6, 0x23, 0x1f, 0x08, 0xd0, 0x70, 0x0c, 0x78, 0x65, 0x79, 0xad, 0xf3, 0x62, 0xa0, 0x84, 0x2d, + 0xc9, 0x70, 0x42, 0xab, 0xab, 0xc6, 0x4b, 0xd1, 0xbc, 0x73, 0x07, 0x38, 0x38, 0xd0, 0xc6, 0x3d, + 0xb4, 0xec, 0x51, 0x8e, 0x1d, 0x1c, 0xd6, 0x92, 0xc1, 0x78, 0x62, 0xce, 0x50, 0xa2, 0x8c, 0x28, + 0x64, 0xf0, 0x55, 0x7b, 0x0b, 0xad, 0xd5, 0x08, 0xe8, 0xeb, 0xfa, 0xb3, 0x72, 0xe1, 0x84, 0xd2, + 0xe8, 0x36, 0x74, 0x6a, 0x7c, 0x98, 0xf8, 0x46, 0x6c, 0x51, 0xd5, 0x1c, 0x9d, 0xa7, 0xfa, 0x6c, + 0xc3, 0x28, 0xf6, 0x82, 0xdf, 0x51, 0xf8, 0xcb, 0x3c, 0x6c, 0x83, 0x3e, 0x25, 0xfb, 0x25, 0x1b, + 0xa5, 0xab, 0x9a, 0xbf, 0x84, 0x25, 0x6a, 0x19, 0x3c, 0xd3, 0x5f, 0x1b, 0xa8, 0xf7, 0x3c, 0x20, + 0x54, 0x51, 0xa5, 0xae, 0x75, 0x34, 0x9a, 0xfe, 0x32, 0x7b, 0xbd, 0x4f, 0xf7, 0x6f, 0x9f, 0x9f, + 0x1f, 0xf8, 0x48, 0x41, 0x11, 0x1e, 0x54, 0x4d, 0x2f, 0xe3, 0x4c, 0x30, 0x82, 0x26, 0x08, 0x0c, + 0x24, 0xdb, 0xee, 0x57, 0xcf, 0x48, 0x69, 0x31, 0x46, 0x70, 0x41, 0x3b, 0x72, 0xcf, 0xa4, 0x4a, + 0xb6, 0x17, 0xf8, 0x50, 0x4e, 0xa3, 0x8f, 0xdd, 0x46, 0x69, 0xcd, 0x3d, 0xaf, 0x6d, 0x09, 0xe4, + 0xda, 0xa1, 0xf6, 0x37, 0xcb, 0xe0, 0xbb, 0xa5, 0x4a, 0xc6, 0x6a, 0xbe, 0xb5, 0xf1, 0xb1, 0x8a, + 0xd7, 0x26, 0xb1, 0x94, 0xca, 0x6a, 0x03, 0x49, 0xac, 0xc0, 0x75, 0x4b, 0xe8, 0xf8, 0x5b, 0xfc, + 0xad, 0x5b, 0x15, 0x7f, 0xe3, 0x08, 0xd2, 0x66, 0xcd, 0x8c, 0xad, 0x45, 0x55, 0x24, 0x4c, 0x8b, + 0x0a, 0x69, 0x22, 0xf0, 0x59, 0x9e, 0x8d, 0x66, 0xc5, 0xb4, 0x4f, 0xa5, 0x17, 0xc3, 0xf6, 0x7b, + 0xd0, 0xd8, 0xd2, 0x65, 0x26, 0x25, 0x12, 0xa6, 0x5f, 0xff, 0x8d, 0xe5, 0xcc, 0x4d, 0xf1, 0xe6, + 0x55, 0x48, 0x9b, 0x1a, 0xf6, 0xc5, 0xbf, 0xf0, 0x81, 0x52, 0x39, 0x0e, 0x96, 0xe1, 0xec, 0x63, + 0x0e, 0xe4, 0x27, 0xe0, 0xb4, 0x8a, 0xb1, 0x5a, 0xdf, 0xaf, 0x97, 0xc2, 0x27, 0x63, 0x3c, 0x30, + 0xcb, 0x7b, 0x53, 0x56, 0x6a, 0x95, 0xd4, 0xde, 0x39, 0x71, 0xbe, 0xfc, 0x29, 0xda, 0x68, 0xb9, + 0x7b, 0xc1, 0xd0, 0xce, 0xc1, 0x69, 0xc9, 0x08, 0x31, 0x7c, 0x66, 0x3e, 0x32, 0x7d, 0xb7, 0x99, + 0x28, 0xcd, 0xde, 0x59, 0x50, 0xde, 0xe8, 0xe3, 0xf0, 0x53, 0xb8, 0x0d, 0x3d, 0xbb, 0xc9, 0x5a, + 0xd7, 0xaf, 0x8d, 0xe4, 0xea, 0x88, 0xfa, 0x46, 0xd6, 0xe5, 0x10, 0x2c, 0xa1, 0x5b, 0x0e, 0x1b, + 0xb4, 0x31, 0x6d, 0xb6, 0xdb, 0xff, 0x0b, 0x4f, 0x06, 0x65, 0x2f, 0xad, 0x57, 0xd3, 0x4d, 0x34, + 0xfc, 0x11, 0x19, 0xa6, 0x6d, 0xb1, 0x92, 0x6f, 0x82, 0xeb, 0xeb, 0xd7, 0x2c, 0x6d, 0xac, 0x4c, + 0xfc, 0x15, 0x76, 0x90, 0xc3, 0xad, 0xd9, 0x29, 0xb8, 0x6f, 0xcc, 0xfb, 0x8d, 0xf0, 0xec, 0xb5, + 0x07, 0xfe, 0x97, 0x51, 0x35, 0xad, 0x5b, 0x2e, 0xb3, 0x6a, 0xb2, 0x74, 0xff, 0xc3, 0xfb, 0xa2, + 0x4c, 0x7b, 0x13, 0xe5, 0xe5, 0xfd, 0x6e, 0x99, 0x7f, 0xf8, 0x2f, 0xd3, 0x24, 0x1d, 0xa7, 0x72, + 0x45, 0x96, 0xdf, 0x6d, 0xb6, 0xdb, 0xf0, 0xef, 0x66, 0x79, 0x65, 0xa2, 0x54, 0xb6, 0x47, 0xc5, + 0x6c, 0x55, 0xb7, 0x6d, 0xb6, 0xdb, 0xf1, 0xbd, 0xb2, 0xd2, 0x66, 0xa2, 0xdf, 0x34, 0x99, 0x34, + 0x76, 0x1d, 0xec, 0x22, 0xd0, 0x53, 0xaa, 0xa6, 0x9a, 0x69, 0xf8, 0xd3, 0x5c, 0x6f, 0x3d, 0x20, + 0xc3, 0x5c, 0x8e, 0xde, 0xbc, 0xeb, 0x52, 0xbc, 0xba, 0x66, 0x0d, 0x2e, 0x63, 0xf6, 0xf3, 0xb1, + 0xe6, 0xc0, 0xd0, 0x18, 0x47, 0xcb, 0xcd, 0x7f, 0x89, 0xfc, 0x9a, 0x5c, 0xeb, 0x1f, 0xb9, 0xe0, + 0xb0, 0xe2, 0x39, 0x93, 0x23, 0x92, 0x21, 0x8e, 0x60, 0x6f, 0x8d, 0x9c, 0x9b, 0xbf, 0xc6, 0x09, + 0x8e, 0xdd, 0x64, 0x65, 0xda, 0x82, 0x9b, 0xd7, 0xb6, 0x5b, 0x5c, 0xb6, 0x1f, 0x6a, 0xd9, 0x91, + 0xb6, 0x9e, 0x30, 0x8d, 0x1d, 0x52, 0x51, 0x38, 0xac, 0x56, 0x58, 0x2b, 0xce, 0x87, 0x43, 0x1b, + 0x33, 0x99, 0x47, 0xf0, 0xfc, 0xec, 0xf9, 0x58, 0x1d, 0x55, 0x8a, 0xed, 0x76, 0xd1, 0xb5, 0x47, + 0xef, 0xaa, 0xaa, 0xf8, 0x2b, 0xb3, 0x67, 0x37, 0x97, 0xb1, 0xd9, 0x88, 0x77, 0xef, 0x85, 0x0d, + 0x4b, 0xec, 0x5b, 0x1f, 0xe9, 0x52, 0x26, 0x5f, 0x48, 0xb9, 0x30, 0x7c, 0x14, 0xd4, 0xbd, 0x25, + 0x2b, 0x67, 0x63, 0x92, 0x12, 0x64, 0xee, 0x7a, 0xcc, 0x2a, 0x7c, 0x15, 0x1f, 0x33, 0x2c, 0x6b, + 0x46, 0x5c, 0xd0, 0xd0, 0x31, 0xbb, 0xbb, 0x7c, 0x76, 0x56, 0x36, 0x1b, 0x7c, 0xbe, 0x1e, 0xde, + 0x06, 0x61, 0x45, 0xde, 0x24, 0x75, 0xac, 0x7e, 0x42, 0x2f, 0x99, 0x86, 0x1b, 0x1b, 0xf8, 0xcf, + 0x22, 0xfc, 0x9c, 0xb8, 0x45, 0x4d, 0xa2, 0xe9, 0xd3, 0xf1, 0xf1, 0xd4, 0xd7, 0xb1, 0x3e, 0x92, + 0x42, 0x38, 0x77, 0x05, 0xff, 0x05, 0x72, 0x32, 0xc6, 0xc6, 0x5e, 0xc1, 0x79, 0x78, 0xba, 0x91, + 0x92, 0xec, 0x59, 0x67, 0xf8, 0x52, 0xb2, 0x23, 0xd6, 0x55, 0x1f, 0xf7, 0x6c, 0xea, 0xe3, 0x2d, + 0xfd, 0xa6, 0xc9, 0x1d, 0xf8, 0x46, 0xe3, 0xa6, 0x0c, 0x6b, 0x9c, 0x82, 0xc5, 0x5d, 0x48, 0xcb, + 0x1f, 0xc2, 0x16, 0xe4, 0x7e, 0xe2, 0x9b, 0xd4, 0x75, 0x4c, 0xcb, 0x24, 0x55, 0x8c, 0x5b, 0xe3, + 0x21, 0x98, 0xd9, 0x8e, 0x8e, 0x46, 0x7b, 0xac, 0xe7, 0x6f, 0xd7, 0xe2, 0x88, 0x8a, 0x3c, 0xf3, + 0x0e, 0xeb, 0xc5, 0x19, 0x08, 0xc5, 0xdb, 0x64, 0xc5, 0xa5, 0xf0, 0xa1, 0x72, 0xbc, 0xcc, 0x2f, + 0xb0, 0x3b, 0x0a, 0xd4, 0xc7, 0x03, 0xfe, 0x71, 0x57, 0x1a, 0x1a, 0xc6, 0x01, 0x89, 0x70, 0x6e, + 0x0d, 0x9c, 0x32, 0xd0, 0xd2, 0x23, 0x7c, 0x29, 0x28, 0xaa, 0xe1, 0xda, 0xd1, 0x01, 0x78, 0xab, + 0x98, 0xdc, 0x89, 0xf9, 0x58, 0x43, 0x24, 0x59, 0xb6, 0xdc, 0x01, 0x6f, 0x85, 0x24, 0xa1, 0x36, + 0xa8, 0xae, 0x63, 0xab, 0xf1, 0x66, 0xe0, 0x1b, 0x86, 0x0d, 0x3b, 0x6a, 0x4a, 0x24, 0x5e, 0x32, + 0x88, 0x79, 0x49, 0x05, 0x84, 0x45, 0xa4, 0x4b, 0x68, 0x91, 0xa3, 0x3a, 0xe4, 0x0b, 0xbf, 0xb6, + 0x10, 0xdc, 0xcf, 0xaf, 0x8d, 0x63, 0xf7, 0xf3, 0xf8, 0x52, 0x57, 0x96, 0x9e, 0x64, 0x83, 0x7b, + 0xdc, 0xd2, 0xaf, 0xe3, 0x95, 0xab, 0xa1, 0x74, 0xf8, 0x33, 0x41, 0xf9, 0x88, 0x63, 0x73, 0xba, + 0x0f, 0x84, 0x00, 0x5f, 0x09, 0x5a, 0x41, 0x89, 0xc6, 0xf2, 0xb3, 0x3f, 0xaf, 0xc7, 0x71, 0x5b, + 0x95, 0xfa, 0xa6, 0x94, 0xd9, 0x4b, 0xc6, 0x45, 0x53, 0x29, 0x98, 0x6a, 0xb6, 0xaa, 0xb8, 0xc5, + 0x6c, 0xa3, 0xea, 0x32, 0xed, 0xfc, 0x21, 0x92, 0xea, 0x6c, 0x60, 0x8b, 0x52, 0x82, 0x8d, 0x45, + 0xa5, 0x3f, 0x19, 0xad, 0x5b, 0x6d, 0xb6, 0xcb, 0x87, 0x38, 0x94, 0x5e, 0x7c, 0xf7, 0x53, 0x10, + 0x55, 0xc4, 0x1f, 0x0b, 0x8c, 0xa3, 0x43, 0x1f, 0xfa, 0x81, 0x92, 0x8f, 0x7a, 0xfe, 0x21, 0xf3, + 0x53, 0xc6, 0xd9, 0x1f, 0xae, 0xce, 0x2d, 0x99, 0xbe, 0xa4, 0xc3, 0xa2, 0xc5, 0x31, 0xe9, 0xa1, + 0xa7, 0xa8, 0xc9, 0x58, 0xd8, 0x26, 0x77, 0x2a, 0x52, 0x3f, 0xc6, 0x1c, 0xd3, 0x41, 0x20, 0x4c, + 0xe2, 0x86, 0xc1, 0x8f, 0x47, 0x20, 0x9a, 0x7b, 0xdb, 0x69, 0xf8, 0x26, 0xb1, 0xaf, 0x74, 0x35, + 0x3c, 0xfa, 0x19, 0x98, 0xaf, 0x85, 0x35, 0x36, 0xe5, 0x20, 0xb8, 0xfb, 0x27, 0xa4, 0x79, 0x95, + 0x59, 0x66, 0x65, 0x0c, 0x51, 0x7c, 0x16, 0xdb, 0xdb, 0x48, 0xb8, 0x3d, 0x76, 0x29, 0x3a, 0xf0, + 0xbd, 0x91, 0x9a, 0x9b, 0x35, 0x27, 0x46, 0x68, 0x7c, 0xc4, 0x69, 0x10, 0xd3, 0xfc, 0x6c, 0xd7, + 0xb7, 0x74, 0xe4, 0xdd, 0x52, 0x99, 0x98, 0x3a, 0x22, 0xc7, 0x9c, 0x57, 0x15, 0xff, 0x85, 0x29, + 0x37, 0x5d, 0x35, 0xfa, 0x16, 0x95, 0xae, 0x76, 0xbb, 0x2d, 0x36, 0x3e, 0x0b, 0x79, 0x70, 0xb8, + 0x58, 0xea, 0xf8, 0xf8, 0xd2, 0xf6, 0xdd, 0x3b, 0xfc, 0xaa, 0x4c, 0xd6, 0x3b, 0xae, 0xe2, 0x08, + 0x7a, 0x8c, 0xd5, 0x16, 0xd5, 0x16, 0xaa, 0xb5, 0xff, 0x0b, 0x13, 0x27, 0x1c, 0xce, 0x8d, 0x8c, + 0xb1, 0xf3, 0x2e, 0xec, 0x91, 0x7f, 0x8d, 0xb6, 0x5d, 0xc9, 0xba, 0x2c, 0xb5, 0xb7, 0xaa, 0x55, + 0x4d, 0x34, 0xd3, 0xff, 0x19, 0x27, 0x1b, 0xa2, 0x27, 0x78, 0xda, 0xf3, 0xc6, 0x5e, 0x9b, 0x5f, + 0xc3, 0xdd, 0x4a, 0xc2, 0x0d, 0x57, 0x3b, 0x2b, 0x25, 0x2a, 0xfa, 0x68, 0xb7, 0x9a, 0x2d, 0xff, + 0xe3, 0x76, 0x5d, 0x93, 0x5b, 0x5d, 0xa9, 0xb5, 0x3c, 0xac, 0x2e, 0x4d, 0xa6, 0x53, 0x4b, 0x17, + 0x66, 0x2f, 0xfe, 0x0b, 0x39, 0xb6, 0xe6, 0x34, 0x7d, 0x8c, 0xac, 0x1a, 0xf8, 0x62, 0x92, 0x56, + 0x95, 0xa5, 0x55, 0x4d, 0x34, 0xd3, 0xff, 0x04, 0xbb, 0x56, 0xf4, 0x3a, 0xeb, 0xe1, 0x9e, 0x4d, + 0x93, 0x45, 0x9d, 0x76, 0xe6, 0xff, 0xe0, 0xae, 0x95, 0x29, 0x0c, 0x47, 0x2a, 0xf0, 0x6c, 0x65, + 0x66, 0x8e, 0x9d, 0x78, 0x52, 0xcd, 0x9a, 0x67, 0xc1, 0xe4, 0x6e, 0xb7, 0x2a, 0x89, 0xe6, 0x9c, + 0x45, 0xc2, 0x64, 0x4e, 0x7c, 0x66, 0x2c, 0x73, 0x3a, 0x34, 0x8b, 0xa4, 0x6d, 0x28, 0x92, 0x9a, + 0x19, 0x25, 0x7f, 0x04, 0x02, 0x1e, 0x2d, 0xa3, 0x72, 0x33, 0x66, 0xd2, 0x98, 0xb3, 0xeb, 0x37, + 0x46, 0xc4, 0xff, 0xc3, 0x31, 0xe3, 0xbb, 0x6d, 0x5b, 0xde, 0x99, 0x56, 0x53, 0x17, 0x8e, 0xbf, + 0xc1, 0x49, 0x53, 0xff, 0xc1, 0x4d, 0xa7, 0xe3, 0x6e, 0xcb, 0x37, 0x9b, 0xc5, 0x3c, 0x18, 0xf8, + 0x50, 0xb5, 0xb6, 0xd7, 0xf9, 0x30, 0xf5, 0xd7, 0x3e, 0x6e, 0xf1, 0x21, 0x22, 0xe2, 0xf0, 0x85, + 0xf3, 0x16, 0x6c, 0xb6, 0xd8, 0xf8, 0xf2, 0x96, 0x5c, 0xd8, 0xd1, 0x49, 0xd0, 0x91, 0x29, 0x83, + 0x97, 0x32, 0xab, 0x72, 0xbf, 0x18, 0x46, 0x47, 0x2d, 0x76, 0x36, 0x90, 0x9a, 0xd2, 0x4b, 0x5a, + 0xf8, 0x2a, 0x28, 0xe5, 0xd5, 0xaa, 0xb2, 0x00, 0xbf, 0x29, 0x7a, 0xd3, 0x7b, 0x7e, 0xf8, 0x2b, + 0xed, 0x34, 0xef, 0x74, 0xd5, 0x1e, 0x4a, 0xbc, 0x16, 0x08, 0x5d, 0xdd, 0x34, 0x39, 0xf9, 0x66, + 0xa4, 0xcc, 0x95, 0x78, 0x89, 0xb1, 0x65, 0x75, 0x51, 0x7f, 0x19, 0x59, 0x4e, 0x5a, 0xd3, 0x37, + 0x17, 0x55, 0x99, 0x8c, 0xd9, 0xf0, 0xa1, 0x76, 0x93, 0x69, 0x5a, 0x5d, 0xd2, 0x63, 0x37, 0xdc, + 0xf8, 0xfb, 0x4d, 0x2a, 0xb4, 0xeb, 0x13, 0xea, 0xab, 0xe4, 0x9b, 0x1a, 0x5f, 0x8c, 0x2d, 0xab, + 0x8c, 0xc7, 0xa7, 0x55, 0xba, 0xef, 0x21, 0x2d, 0x57, 0xc2, 0x26, 0x9d, 0x82, 0xe7, 0x60, 0x65, + 0x5f, 0x5d, 0x63, 0xfe, 0x14, 0x2a, 0xf5, 0x5d, 0xd3, 0xd0, 0xb3, 0xb1, 0xbb, 0x4d, 0xdb, 0x4c, + 0x6e, 0x7c, 0x29, 0x7b, 0x9e, 0xab, 0xcd, 0x06, 0xaa, 0x12, 0xe5, 0xdb, 0x91, 0x3e, 0x33, 0x3c, + 0x4e, 0x41, 0x76, 0xea, 0x86, 0xda, 0xf2, 0xad, 0x18, 0x5a, 0x22, 0xae, 0xb4, 0xcd, 0x17, 0x64, + 0x1a, 0xe4, 0xd8, 0xfc, 0x7f, 0x42, 0xec, 0xc4, 0xff, 0xe1, 0xae, 0x8a, 0xc6, 0x8e, 0xd1, 0x69, + 0xb0, 0xea, 0xb1, 0xac, 0xb8, 0xc6, 0x05, 0xe0, 0xa8, 0xa6, 0xce, 0x03, 0xd3, 0x44, 0x1c, 0xa3, + 0x85, 0xc2, 0x0e, 0x7c, 0xc3, 0x04, 0x0e, 0xda, 0xcd, 0x07, 0x68, 0x0d, 0xf4, 0x01, 0x52, 0x7f, + 0x8c, 0xa2, 0xae, 0x33, 0x37, 0x6f, 0xed, 0x88, 0xbb, 0xe9, 0x2b, 0x50, 0xe7, 0xe6, 0x93, 0xf0, + 0xa4, 0x99, 0x9c, 0xe4, 0x90, 0x21, 0x21, 0xc8, 0xdc, 0x33, 0xa8, 0x29, 0xe3, 0x46, 0x6f, 0x25, + 0xce, 0x5c, 0x64, 0x72, 0xe3, 0xba, 0x99, 0xf1, 0x94, 0x6d, 0x72, 0xb8, 0x61, 0x4a, 0x8e, 0xbf, + 0xf3, 0x92, 0xed, 0x35, 0x63, 0x16, 0x55, 0x5c, 0x4d, 0xc9, 0x23, 0xdf, 0x01, 0x9f, 0x78, 0xcb, + 0x7c, 0x6f, 0x62, 0xcb, 0xed, 0x61, 0x4f, 0x26, 0x52, 0x26, 0xfa, 0x68, 0xad, 0x2c, 0x4c, 0x85, + 0x18, 0x52, 0x65, 0x04, 0x8f, 0x7f, 0xc2, 0x84, 0xc4, 0x7a, 0xcc, 0x6a, 0x98, 0x8f, 0xe1, 0xbe, + 0x5d, 0x3d, 0x31, 0x72, 0x01, 0xdf, 0x19, 0xbb, 0x66, 0xe5, 0x20, 0x93, 0x67, 0x78, 0x3c, 0xbc, + 0x9c, 0x28, 0x2a, 0x91, 0x1f, 0x12, 0x11, 0x33, 0x71, 0x21, 0xed, 0xed, 0x55, 0x33, 0x75, 0xc6, + 0x1d, 0xa6, 0x99, 0xa9, 0x1a, 0x38, 0x30, 0xad, 0xce, 0x21, 0x0e, 0xcd, 0x1e, 0x21, 0xc2, 0xd3, + 0xc3, 0xc3, 0x1d, 0x9c, 0x4c, 0x72, 0xf7, 0x91, 0xbb, 0xae, 0x66, 0x28, 0x8f, 0x59, 0x4c, 0x3b, + 0x4f, 0x2f, 0xfc, 0x68, 0x9d, 0xa2, 0xa0, 0xd8, 0xd9, 0x1d, 0x88, 0xab, 0x44, 0x65, 0x13, 0xb5, + 0x75, 0x3c, 0x04, 0xbf, 0x6d, 0x34, 0xd3, 0x4f, 0xc6, 0xd8, 0xa3, 0x37, 0xc7, 0xa9, 0x53, 0x53, + 0x85, 0x51, 0xab, 0xd1, 0x9e, 0xa7, 0x63, 0x3a, 0x2a, 0x2d, 0x0d, 0x3a, 0xff, 0xf0, 0xa1, 0x2b, + 0x0a, 0x35, 0x8e, 0x5d, 0x55, 0x75, 0xbf, 0x73, 0x46, 0x6f, 0x70, 0x65, 0x5f, 0xa3, 0xce, 0xd2, + 0xb2, 0xcf, 0x85, 0x31, 0x96, 0x30, 0xa4, 0x7e, 0x8e, 0x43, 0xec, 0xcd, 0xbd, 0x8e, 0xe8, 0xa7, + 0xe3, 0x4a, 0x6c, 0x46, 0x23, 0x2e, 0x48, 0x47, 0xee, 0x33, 0x09, 0x91, 0x45, 0x56, 0x9a, 0x84, + 0xfe, 0xb8, 0x94, 0xc8, 0x94, 0xcf, 0xf8, 0xda, 0xba, 0xb6, 0x71, 0x9a, 0x16, 0x54, 0x7b, 0xf5, + 0xb7, 0x43, 0x2b, 0x52, 0x73, 0x4a, 0x3e, 0xed, 0xb7, 0xfe, 0x34, 0x91, 0xe4, 0xc1, 0x9a, 0xf5, + 0xf6, 0xe5, 0xd7, 0x6b, 0x37, 0xc6, 0xcd, 0x9d, 0xd3, 0x7c, 0x9b, 0xff, 0x82, 0xbb, 0x26, 0x98, + 0x8b, 0x63, 0x32, 0x37, 0xbb, 0xd7, 0xc1, 0x6d, 0xa7, 0x4c, 0x8a, 0x8e, 0xcb, 0x38, 0x45, 0xcd, + 0x8f, 0x82, 0x02, 0x8c, 0xd2, 0x69, 0x4c, 0xc1, 0x18, 0x39, 0x46, 0xb2, 0xd8, 0xa5, 0x6e, 0x76, + 0x3b, 0x24, 0x18, 0xa5, 0xbf, 0xfc, 0x21, 0x8f, 0xd9, 0xd1, 0x86, 0x55, 0x54, 0xf1, 0xe3, 0x8b, + 0x4d, 0x54, 0x6c, 0xf0, 0x8d, 0x0f, 0x3e, 0x31, 0xa4, 0xf8, 0x2b, 0xc2, 0x28, 0xab, 0x26, 0xf8, + 0xcb, 0x77, 0x29, 0x62, 0xbd, 0xd9, 0xb0, 0x7b, 0x6c, 0x65, 0x6a, 0x17, 0xe3, 0x34, 0xa5, 0xeb, + 0x19, 0x7a, 0x72, 0x49, 0x79, 0x2f, 0x8e, 0xaf, 0x8e, 0x9e, 0x27, 0xfe, 0x0d, 0x95, 0x2c, 0x6d, + 0xa6, 0xa7, 0xe1, 0xd9, 0x6b, 0xb6, 0x99, 0xda, 0xfc, 0x62, 0xa5, 0x75, 0xb6, 0x43, 0x15, 0x8d, + 0x49, 0x07, 0x41, 0x15, 0x2f, 0xf0, 0xe6, 0x9b, 0x64, 0xf9, 0x55, 0x92, 0x25, 0xff, 0x0a, 0x12, + 0x49, 0x50, 0xd4, 0xdd, 0x26, 0x78, 0xdc, 0xe6, 0xf2, 0xc2, 0x7d, 0xaf, 0x86, 0x25, 0x83, 0xea, + 0xdd, 0x2e, 0x57, 0xba, 0xff, 0x83, 0x0a, 0x7a, 0x67, 0x64, 0x6e, 0x83, 0xf5, 0x31, 0xa5, 0x03, + 0xd3, 0x4d, 0x34, 0xff, 0xc6, 0x94, 0xe4, 0xa7, 0xa1, 0xb2, 0x32, 0x87, 0x44, 0x33, 0xbb, 0x20, + 0xec, 0xc5, 0xd1, 0xf1, 0x94, 0x39, 0x1e, 0x4a, 0xe9, 0x19, 0x5d, 0xe5, 0x87, 0x8d, 0x15, 0xb5, + 0x32, 0xb7, 0x87, 0xf6, 0xd1, 0x91, 0x2f, 0x94, 0xc3, 0x90, 0x3e, 0x93, 0xed, 0x0f, 0x52, 0x5b, + 0xff, 0xfc, 0x28, 0x54, 0x90, 0x76, 0xad, 0xd2, 0x8c, 0xdd, 0xd2, 0x73, 0x33, 0x53, 0x27, 0xf8, + 0x24, 0x93, 0x4b, 0x9d, 0x78, 0x90, 0xa0, 0x92, 0x68, 0xff, 0x93, 0x8c, 0xdd, 0xe8, 0x44, 0xf2, + 0xc5, 0xfc, 0x94, 0x6b, 0x9b, 0xc0, 0x34, 0x8f, 0x88, 0x1a, 0x31, 0x61, 0xc2, 0x87, 0x18, 0xe4, + 0x72, 0x72, 0xdb, 0xa4, 0x9e, 0xe3, 0x10, 0x6e, 0xf9, 0x92, 0x87, 0x3b, 0xd8, 0x1b, 0xa6, 0xf5, + 0xff, 0x8c, 0x1b, 0x56, 0xf9, 0xb0, 0x8c, 0x6f, 0x81, 0x0d, 0x40, 0xd9, 0x8c, 0x79, 0xe3, 0x5f, + 0xe0, 0xa7, 0x52, 0x23, 0x0c, 0x1d, 0xa7, 0x26, 0x42, 0xc7, 0x69, 0x5b, 0x47, 0xf8, 0x52, 0xf2, + 0x7e, 0x3c, 0x9f, 0xc6, 0xd3, 0x1a, 0xee, 0x3b, 0xac, 0x64, 0xbc, 0x48, 0x4a, 0x2e, 0x48, 0x12, + 0x9d, 0x59, 0xaf, 0x84, 0x3b, 0xa1, 0xee, 0x86, 0x66, 0x24, 0x62, 0x87, 0x88, 0x82, 0xcd, 0xa6, + 0xbb, 0x47, 0xc4, 0x88, 0xf4, 0x6a, 0x88, 0xea, 0x0d, 0x51, 0x5f, 0x8e, 0x9f, 0x99, 0x5b, 0x5c, + 0x01, 0x59, 0x15, 0xf1, 0xb7, 0x1b, 0x7e, 0x3f, 0x49, 0xaa, 0x06, 0xdb, 0x1a, 0x1b, 0x19, 0x58, + 0x63, 0x6b, 0x1e, 0x3e, 0xab, 0x7d, 0xdd, 0xe7, 0x20, 0xbf, 0x84, 0x23, 0x5c, 0xab, 0x98, 0x4a, + 0xb6, 0x36, 0x42, 0xe4, 0x79, 0xf6, 0xaa, 0xab, 0xf0, 0xa6, 0x72, 0x15, 0xba, 0x86, 0x76, 0xd3, + 0xb1, 0x0d, 0xb4, 0x33, 0xb0, 0x37, 0x47, 0xb1, 0x07, 0x46, 0xdf, 0x19, 0xec, 0x9c, 0xd8, 0x86, + 0xb9, 0x29, 0x7d, 0x4c, 0xfd, 0x43, 0xaa, 0xf3, 0x1a, 0xe1, 0x3f, 0x84, 0x27, 0xa7, 0x6e, 0xa4, + 0xec, 0xf2, 0x89, 0x14, 0x4b, 0xf1, 0xd3, 0x5b, 0x30, 0x60, 0xdd, 0x14, 0x0c, 0x3f, 0xc4, 0x3c, + 0x9b, 0x65, 0x4f, 0x5c, 0x08, 0x0b, 0x80, 0x01, 0x43, 0xfc, 0x7d, 0x81, 0xb4, 0x49, 0x74, 0x6b, + 0x81, 0xf9, 0xf1, 0xa5, 0x35, 0xb1, 0xae, 0xc2, 0x73, 0xe3, 0xaa, 0x66, 0xd4, 0xb7, 0x2b, 0x10, + 0xfd, 0xd9, 0x99, 0x2f, 0x0f, 0x8f, 0x84, 0x4a, 0xec, 0xd2, 0x0b, 0xa2, 0x9e, 0xd3, 0x1d, 0xb1, + 0x43, 0x63, 0x1f, 0x84, 0x74, 0x9c, 0x78, 0x36, 0xde, 0xe9, 0x15, 0x43, 0x10, 0x1f, 0x48, 0x28, + 0xa8, 0x89, 0xc9, 0xdb, 0xfc, 0x61, 0x18, 0x69, 0x66, 0x2a, 0x86, 0xc7, 0xba, 0x94, 0x6e, 0xf1, + 0x9d, 0x27, 0xa7, 0xa6, 0xfe, 0x32, 0xd8, 0xbe, 0x2f, 0x35, 0x0a, 0xf7, 0x62, 0x17, 0x9a, 0x1c, + 0xfd, 0x3f, 0x1f, 0x27, 0x6f, 0x8e, 0x37, 0x2d, 0x79, 0x0e, 0x29, 0x7b, 0xf1, 0x22, 0x42, 0x77, + 0x5e, 0x6a, 0x52, 0x4b, 0xc1, 0x69, 0x0d, 0xbc, 0x9b, 0x92, 0x09, 0xeb, 0xe3, 0x34, 0xcf, 0x01, + 0xff, 0x75, 0x5d, 0xfb, 0x28, 0xd3, 0xed, 0xb5, 0xe1, 0x42, 0x36, 0xb4, 0x5b, 0x6d, 0x28, 0x7a, + 0xa1, 0x18, 0x7f, 0xda, 0xb4, 0x59, 0x3e, 0x3c, 0xe7, 0xd3, 0x90, 0xe7, 0x21, 0x69, 0xaf, 0x3d, + 0x69, 0x78, 0xca, 0x5b, 0x6c, 0xee, 0x75, 0x5a, 0x91, 0x04, 0x91, 0x35, 0x5d, 0xfc, 0x3c, 0x4c, + 0xf8, 0xd8, 0xc6, 0x14, 0xe5, 0x1a, 0x37, 0x21, 0x65, 0x29, 0x57, 0x03, 0xe9, 0x36, 0x1d, 0xe4, + 0x99, 0x7d, 0x3f, 0x05, 0x10, 0xdb, 0x5e, 0x56, 0xad, 0x06, 0x35, 0x9b, 0xf7, 0x4e, 0x0f, 0x8c, + 0x2a, 0x92, 0x09, 0x42, 0xb6, 0x87, 0x50, 0x90, 0x2b, 0x50, 0x67, 0x21, 0x91, 0x9a, 0xfa, 0xdb, + 0xf1, 0xb9, 0x18, 0xb1, 0xd7, 0x41, 0xb5, 0x94, 0xd6, 0x0d, 0x19, 0xae, 0xd2, 0x99, 0x9e, 0x0b, + 0xd1, 0x0f, 0xbb, 0x6d, 0xb6, 0xdb, 0x7e, 0x37, 0x0e, 0xab, 0x79, 0xda, 0xb1, 0xc2, 0x42, 0x0b, + 0x48, 0x60, 0xc7, 0x68, 0x86, 0xb6, 0x8d, 0x62, 0x3b, 0x6b, 0x52, 0xf2, 0xfa, 0xeb, 0xff, 0x1d, + 0xe5, 0xcb, 0x79, 0x8a, 0x5a, 0xc0, 0xfd, 0x29, 0x51, 0xf8, 0xcb, 0x69, 0x58, 0xaa, 0xd0, 0x75, + 0x48, 0x76, 0x49, 0x1f, 0xa4, 0xe6, 0x19, 0xbf, 0x87, 0x66, 0x56, 0x55, 0xd4, 0xd2, 0x64, 0xa2, + 0x4b, 0x57, 0x95, 0x86, 0xd7, 0xc4, 0xa6, 0x44, 0xa6, 0x7f, 0x7e, 0xf8, 0xb0, 0x7e, 0x36, 0xca, + 0x83, 0x39, 0x05, 0xa4, 0x28, 0x0c, 0x67, 0x45, 0xb7, 0x58, 0xbe, 0x3c, 0x84, 0xc5, 0x55, 0x7d, + 0xb5, 0x16, 0xc9, 0xa7, 0xf5, 0x7f, 0x82, 0x0b, 0x36, 0x3a, 0x71, 0xe1, 0xdf, 0x96, 0xf7, 0x56, + 0x37, 0xe2, 0xfd, 0x34, 0xd3, 0x4f, 0xc6, 0xca, 0xc5, 0x1c, 0x69, 0x21, 0xdc, 0x8c, 0x44, 0x30, + 0x9a, 0xd5, 0x1a, 0xba, 0x53, 0x8e, 0xa9, 0x9b, 0xad, 0x69, 0xa6, 0x9a, 0x7e, 0x37, 0x3c, 0x56, + 0x35, 0xf9, 0x3d, 0x65, 0x44, 0x46, 0xaf, 0x1e, 0x5d, 0x78, 0x5b, 0x88, 0xdf, 0x13, 0xff, 0xfc, + 0x66, 0x2d, 0xa2, 0x08, 0xd7, 0x2e, 0x39, 0x5b, 0x5f, 0x05, 0xc3, 0x68, 0x92, 0x74, 0xbc, 0x6c, + 0x39, 0x51, 0x63, 0x87, 0x9f, 0x9a, 0x04, 0xda, 0x15, 0x1b, 0x47, 0xca, 0xdd, 0x05, 0x56, 0x7b, + 0xea, 0x27, 0xc9, 0x07, 0xc7, 0xc2, 0x37, 0xb1, 0xa2, 0xac, 0xd1, 0x0c, 0x61, 0x3a, 0x3f, 0x05, + 0x36, 0x94, 0x33, 0xaf, 0x29, 0x9a, 0x17, 0x59, 0x99, 0xd1, 0x0d, 0x51, 0x17, 0x73, 0xfc, 0x3d, + 0x4a, 0xd1, 0x2d, 0x35, 0x68, 0xfb, 0xdf, 0xb1, 0x75, 0x45, 0xfe, 0x36, 0xd1, 0xb0, 0x8f, 0x66, + 0xbf, 0x50, 0x86, 0x43, 0x19, 0xfb, 0xc7, 0x99, 0x73, 0xd2, 0x40, 0xd1, 0x93, 0xbf, 0xfc, 0x29, + 0x43, 0x0e, 0x55, 0x35, 0xb1, 0x30, 0x62, 0xc2, 0xc6, 0xf2, 0x51, 0x45, 0xb4, 0x9a, 0x34, 0xb8, + 0xcf, 0x84, 0x3b, 0x7e, 0x2f, 0x87, 0x74, 0x36, 0xbf, 0xda, 0x53, 0x65, 0x1d, 0x06, 0xbd, 0xc5, + 0xb1, 0x6f, 0xfc, 0x2a, 0x29, 0xda, 0xea, 0xc0, 0xcb, 0x70, 0x38, 0x24, 0xfd, 0x11, 0x56, 0xff, + 0x1a, 0x77, 0x26, 0xda, 0xe8, 0x1c, 0x64, 0x4a, 0x33, 0x35, 0xb4, 0x78, 0x6d, 0xc6, 0x93, 0x26, + 0x99, 0x0b, 0x47, 0x7b, 0x7f, 0xf0, 0xce, 0x37, 0x2f, 0x5a, 0x76, 0xef, 0x7f, 0xf0, 0x41, 0x93, + 0x65, 0xc5, 0x4f, 0x4b, 0x4b, 0x15, 0x55, 0x57, 0xfc, 0x14, 0xe2, 0x26, 0x45, 0x14, 0x58, 0xca, + 0xb8, 0xca, 0xe3, 0xcb, 0xe1, 0xe1, 0x09, 0x39, 0x0c, 0x1e, 0x63, 0xc3, 0xee, 0x17, 0x43, 0x8e, + 0x5d, 0x6e, 0x69, 0x2d, 0x49, 0xff, 0xf1, 0x83, 0xd6, 0x31, 0xb1, 0x93, 0x77, 0xe4, 0x7a, 0x51, + 0x33, 0x66, 0x6d, 0xf8, 0x29, 0xe6, 0x4e, 0x9b, 0xdb, 0xac, 0x99, 0x8d, 0x9f, 0x19, 0x98, 0x82, + 0xfb, 0x7f, 0x4c, 0xf7, 0x13, 0x81, 0xbc, 0x19, 0xbd, 0x9f, 0x0a, 0x54, 0xca, 0x8b, 0x2e, 0x7c, + 0x4e, 0x27, 0x08, 0x0a, 0x06, 0x91, 0xf4, 0x15, 0x93, 0x96, 0x8f, 0xf0, 0x55, 0x6c, 0x62, 0xc6, + 0xb5, 0x33, 0x16, 0xf7, 0x6e, 0x5a, 0xa7, 0x41, 0xc4, 0x01, 0x7c, 0x16, 0x75, 0x3e, 0x3b, 0x71, + 0xf5, 0x4e, 0x8d, 0x8c, 0x57, 0x56, 0xf1, 0x7c, 0x61, 0x23, 0x9b, 0x5a, 0x43, 0x43, 0x3e, 0x3f, + 0x19, 0xc7, 0x0c, 0xe3, 0x9f, 0x2f, 0xe0, 0xb3, 0x55, 0x56, 0x36, 0x35, 0xad, 0xab, 0x7c, 0x69, + 0x43, 0xea, 0x95, 0x51, 0xec, 0xac, 0x19, 0xaa, 0x8e, 0x02, 0x1e, 0xc6, 0x2b, 0x0a, 0xb5, 0x51, + 0xac, 0x4c, 0xb5, 0x55, 0x12, 0xfa, 0x69, 0xa6, 0x9f, 0x8d, 0xc1, 0xf9, 0x14, 0x5b, 0x96, 0x31, + 0x5d, 0xd1, 0x27, 0x5d, 0xd7, 0xd3, 0x4d, 0x34, 0xfc, 0x29, 0x23, 0xe8, 0xd5, 0x63, 0x34, 0xea, + 0xbf, 0x63, 0x15, 0x1c, 0xaa, 0x1e, 0x52, 0x2f, 0x0a, 0x6c, 0xa2, 0x29, 0xc9, 0x55, 0x9d, 0x0d, + 0x0c, 0xac, 0x1d, 0x2b, 0x14, 0xf3, 0xaf, 0xe1, 0x49, 0xeb, 0x01, 0xc5, 0x65, 0xad, 0x2b, 0x1e, + 0x26, 0x71, 0x01, 0x5c, 0x7e, 0xda, 0x2d, 0xa3, 0xd9, 0x5b, 0x42, 0xd1, 0xe3, 0x96, 0xde, 0xc1, + 0xd4, 0x7c, 0x15, 0x94, 0xf7, 0x02, 0x25, 0xea, 0x47, 0xb8, 0xed, 0x42, 0x7e, 0x6e, 0xc3, 0x65, + 0x0e, 0x56, 0x18, 0xf8, 0xcb, 0x33, 0xd0, 0x8c, 0x57, 0xb5, 0x69, 0x42, 0x4a, 0xf4, 0xcc, 0x28, + 0xde, 0xce, 0xf6, 0x4a, 0xa3, 0xc6, 0x74, 0x29, 0x57, 0x3c, 0x48, 0x89, 0xc9, 0x4b, 0x5a, 0x29, + 0xb3, 0xa7, 0x5b, 0xd7, 0xf1, 0x59, 0x99, 0x63, 0x89, 0x2b, 0x9b, 0x7c, 0x21, 0xcf, 0xe7, 0xe6, + 0xd8, 0x9d, 0xae, 0xd3, 0xe1, 0xf1, 0xd8, 0xec, 0xf0, 0x85, 0xb6, 0xdb, 0x6e, 0xca, 0xce, 0xd6, + 0xe9, 0xf8, 0xc2, 0x5d, 0x27, 0xc9, 0x34, 0xad, 0x5f, 0xb9, 0xa8, 0xfa, 0x78, 0x47, 0x74, 0x32, + 0xfd, 0xdd, 0x9e, 0x7a, 0x07, 0xd5, 0x6f, 0x1f, 0xaa, 0xab, 0x8f, 0x26, 0xa7, 0xb1, 0x83, 0xbb, + 0x11, 0x5f, 0x8e, 0x36, 0xd1, 0x4c, 0xc4, 0x98, 0xcc, 0xe8, 0x65, 0xb9, 0xfe, 0x37, 0x2d, 0x14, + 0x5e, 0x0b, 0xbb, 0x1a, 0x47, 0x6b, 0x64, 0x79, 0xf2, 0xa7, 0x7c, 0x14, 0xdd, 0xfc, 0xbe, 0xab, + 0x09, 0xb6, 0xaa, 0x72, 0xb0, 0xed, 0x3c, 0x9f, 0x18, 0x24, 0xae, 0x67, 0x4c, 0xd4, 0x66, 0xce, + 0x9b, 0x31, 0x2d, 0x1f, 0x47, 0xb8, 0x86, 0x6f, 0x7f, 0x0a, 0x10, 0x95, 0x30, 0x7c, 0xad, 0x77, + 0x7d, 0xe8, 0x50, 0xcd, 0xdb, 0x65, 0xa3, 0x0c, 0x65, 0x96, 0xae, 0x90, 0x6f, 0xed, 0x61, 0x2b, + 0xf1, 0x98, 0xe1, 0xa9, 0xe1, 0xed, 0x36, 0x93, 0xba, 0xbb, 0xce, 0x9a, 0x7e, 0x34, 0xd1, 0xa6, + 0x11, 0xee, 0xb4, 0xb4, 0xeb, 0x43, 0x59, 0x58, 0x2d, 0xb9, 0x52, 0x73, 0x34, 0x36, 0xd1, 0x9d, + 0x4f, 0xf8, 0x7c, 0xe6, 0x63, 0xe9, 0x25, 0x53, 0x52, 0x65, 0xd5, 0xb6, 0xeb, 0x6d, 0x34, 0xd3, + 0x4f, 0xc3, 0xd8, 0xfe, 0x84, 0xec, 0x53, 0x4d, 0x9d, 0x72, 0xa5, 0x9d, 0x97, 0xcb, 0xe9, 0xa6, + 0x9a, 0x7e, 0x36, 0xc9, 0xcc, 0x06, 0x85, 0x19, 0x75, 0xaf, 0xad, 0xbf, 0x3a, 0xeb, 0x6d, 0xb8, + 0x33, 0x30, 0xd2, 0xca, 0xaa, 0x9a, 0x6d, 0xb6, 0x9a, 0x69, 0xa7, 0xe3, 0x74, 0x34, 0x92, 0xba, + 0xbb, 0x44, 0xa3, 0xd6, 0xe9, 0xc9, 0x4b, 0xd3, 0xa5, 0x4d, 0x34, 0xd3, 0xf1, 0xb3, 0xd2, 0x9d, + 0x6d, 0xae, 0xd5, 0xfb, 0x4b, 0x6d, 0xb6, 0xdb, 0xba, 0x4d, 0xd7, 0xcb, 0xc9, 0xdb, 0xd9, 0xfc, + 0x3c, 0x4b, 0x71, 0xbc, 0xb4, 0x86, 0xf6, 0x30, 0xb7, 0x5b, 0x6c, 0x9b, 0x5f, 0x4d, 0x38, 0xd3, + 0xf0, 0x58, 0x53, 0xe1, 0xf1, 0x28, 0xa4, 0xbd, 0x43, 0x42, 0x86, 0x8f, 0xef, 0x8d, 0xb6, 0xdc, + 0x73, 0x0a, 0x5a, 0xb2, 0x39, 0x14, 0xea, 0x10, 0x63, 0xa9, 0x85, 0xb6, 0x16, 0x64, 0xf5, 0xd6, + 0x34, 0xd3, 0x4d, 0xb6, 0xdb, 0x6f, 0xc1, 0x49, 0x11, 0x4d, 0x96, 0xb2, 0x77, 0x83, 0x24, 0xeb, + 0xf0, 0xf8, 0xd9, 0x22, 0xde, 0xcc, 0xcd, 0x0c, 0xd4, 0x8e, 0xac, 0x33, 0xbc, 0xb5, 0x82, 0xb3, + 0xe4, 0xd5, 0x1a, 0xf5, 0x4d, 0xa7, 0xfe, 0x1f, 0xe3, 0xab, 0x84, 0x6f, 0x1e, 0x5a, 0x9e, 0x85, + 0xf0, 0xd7, 0xe5, 0xaa, 0xac, 0x93, 0xfb, 0x8f, 0xfc, 0x74, 0x9a, 0x59, 0xa5, 0xb8, 0xd4, 0x1f, + 0x51, 0xe6, 0xd9, 0x7e, 0x08, 0x0b, 0xae, 0x65, 0x06, 0x80, 0xe5, 0xe4, 0x3a, 0x95, 0x5d, 0xa7, + 0xb4, 0x2d, 0x38, 0x8f, 0x8a, 0xbb, 0x75, 0xa6, 0x9f, 0x87, 0x6c, 0x57, 0x28, 0x69, 0xe9, 0xb7, + 0x93, 0x10, 0xeb, 0x8b, 0xea, 0xaa, 0xbe, 0x1e, 0x99, 0x9d, 0x75, 0xda, 0xda, 0xb2, 0x3e, 0xdb, + 0x4d, 0xb5, 0x15, 0x28, 0xa9, 0x7f, 0xc2, 0xf5, 0x23, 0x0c, 0x71, 0xca, 0x91, 0x8d, 0x6d, 0x3a, + 0xd9, 0xe2, 0xdb, 0xe3, 0xfe, 0x3e, 0x84, 0x38, 0x84, 0x55, 0x4f, 0xd3, 0x3c, 0x94, 0x2c, 0x69, + 0x53, 0x95, 0x93, 0x30, 0xd6, 0x3c, 0x75, 0x1e, 0xe5, 0x6a, 0xe4, 0xd6, 0xb5, 0xcd, 0x63, 0x2b, + 0x2b, 0xb3, 0x83, 0xf0, 0x41, 0x44, 0x6d, 0x2e, 0xd4, 0x63, 0xe9, 0xb1, 0xa7, 0x94, 0x9d, 0xb5, + 0x55, 0x17, 0xff, 0x8d, 0x14, 0x78, 0x25, 0xb2, 0x2b, 0x4f, 0xab, 0x6b, 0xa6, 0x73, 0x2f, 0x4d, + 0xe9, 0x1c, 0xdc, 0xf9, 0x4d, 0x6a, 0x2b, 0x23, 0x1f, 0xe0, 0xb0, 0xb3, 0x35, 0x8f, 0x8c, 0x5d, + 0xf1, 0xb3, 0xa7, 0x5f, 0x05, 0x7b, 0x4d, 0x73, 0x7d, 0xd3, 0x8b, 0x65, 0xf8, 0x50, 0xf9, 0x36, + 0x4c, 0x07, 0xd8, 0x4c, 0x3b, 0x95, 0x2c, 0xbf, 0xcd, 0xe3, 0x7c, 0x10, 0x18, 0x70, 0xb1, 0x60, + 0xc3, 0x4e, 0x82, 0x4b, 0xa4, 0x86, 0xc1, 0x82, 0x3f, 0xbb, 0xb6, 0x12, 0x20, 0x0b, 0x14, 0x9e, + 0x9c, 0xfe, 0xdf, 0x87, 0xe1, 0x9b, 0x35, 0xc7, 0x54, 0xdf, 0x51, 0x2a, 0xbe, 0xd8, 0xf3, 0xc3, + 0x97, 0x9b, 0xa9, 0x39, 0x3b, 0x3b, 0x3f, 0x8f, 0x3d, 0xe7, 0x61, 0x4b, 0x19, 0xac, 0x60, 0xca, + 0x06, 0xf4, 0xae, 0x4b, 0xe1, 0x4c, 0xce, 0xca, 0xb7, 0xbe, 0xf6, 0x31, 0xd1, 0x82, 0xb0, 0xdd, + 0xd2, 0xdf, 0xe1, 0x43, 0xdd, 0x11, 0x7b, 0x8f, 0x5d, 0xe3, 0x8f, 0x4e, 0x67, 0xed, 0xa6, 0x9f, + 0xe1, 0x02, 0x69, 0x2d, 0x5d, 0xee, 0x36, 0xd5, 0x0d, 0x6b, 0xf0, 0x8c, 0xec, 0x41, 0xa1, 0xaa, + 0x4a, 0xc4, 0x84, 0x33, 0x79, 0xb8, 0xf6, 0xb0, 0x63, 0xe3, 0xb5, 0x4d, 0xcd, 0x8a, 0xf2, 0xee, + 0xfe, 0xfe, 0x38, 0xaf, 0xcb, 0xe4, 0x67, 0x23, 0x32, 0x25, 0x22, 0xe4, 0x4a, 0xd4, 0x1e, 0x30, + 0xcc, 0x91, 0x36, 0x86, 0x42, 0x4b, 0x19, 0xd9, 0x0e, 0xd4, 0x45, 0x58, 0xf6, 0x58, 0xcc, 0x75, + 0xc6, 0xdf, 0x85, 0x0e, 0xbb, 0x94, 0x47, 0xdc, 0x0f, 0x20, 0xbd, 0x98, 0x6c, 0xb2, 0x66, 0x5e, + 0x0c, 0xf7, 0x53, 0x9e, 0x59, 0xda, 0x0f, 0x64, 0x89, 0xf0, 0xa1, 0x35, 0x79, 0x5b, 0x06, 0x3b, + 0x61, 0xb4, 0xa6, 0xf7, 0xb6, 0xae, 0x7e, 0xd8, 0x91, 0x3e, 0x11, 0xb3, 0xbb, 0x8d, 0xa0, 0xf4, + 0x21, 0xe4, 0x57, 0xd2, 0xe0, 0xbc, 0x21, 0xbb, 0x99, 0x9a, 0x37, 0x39, 0x1c, 0x32, 0x55, 0xd9, + 0xef, 0xc5, 0x9c, 0xda, 0x6d, 0x76, 0xbb, 0x4d, 0xcf, 0xdd, 0xdf, 0xfc, 0x21, 0x2b, 0x2f, 0x65, + 0x0d, 0xec, 0xdb, 0xf7, 0xea, 0xbe, 0x32, 0x30, 0x8a, 0xfa, 0xb1, 0x43, 0xd4, 0x55, 0x57, 0x34, + 0x99, 0x9c, 0x31, 0x52, 0x36, 0x32, 0xe6, 0x71, 0x11, 0x86, 0x63, 0x7b, 0xcd, 0x47, 0x51, 0xfc, + 0xdf, 0x0d, 0xc7, 0x5d, 0x1b, 0xd9, 0xf1, 0xc9, 0xf8, 0x91, 0xc5, 0x6d, 0x7c, 0x97, 0xa1, 0x68, + 0xd7, 0xc5, 0xcc, 0xa8, 0x8c, 0xa7, 0x1d, 0x36, 0x44, 0x21, 0xf1, 0x86, 0x4d, 0x34, 0xd3, 0x76, + 0x48, 0x91, 0x63, 0x79, 0x46, 0x66, 0x7d, 0x3f, 0x08, 0x12, 0x5f, 0x68, 0x6b, 0x11, 0xe2, 0x24, + 0x13, 0x49, 0xb3, 0x17, 0xda, 0xe9, 0xf8, 0xde, 0x6c, 0x69, 0x2e, 0xf1, 0x1a, 0x89, 0xc4, 0xb6, + 0xf5, 0x6d, 0xb6, 0xdb, 0xff, 0x09, 0x5b, 0x1b, 0xc9, 0x25, 0xd7, 0x95, 0xa3, 0x7f, 0xc2, 0x5e, + 0x76, 0xb6, 0x99, 0xa3, 0xf8, 0x99, 0x3f, 0x4c, 0x9e, 0x32, 0x78, 0xfc, 0x61, 0x51, 0x34, 0xd5, + 0x8c, 0x7f, 0xcb, 0xf3, 0xae, 0xb4, 0xe5, 0x92, 0xb6, 0x7b, 0x4a, 0x3f, 0x08, 0x6d, 0x95, 0x91, + 0xaf, 0xd2, 0x4d, 0x31, 0xbe, 0xaf, 0xc7, 0x56, 0x98, 0x9c, 0x24, 0xbf, 0x6f, 0x1a, 0x93, 0xbb, + 0x3c, 0x65, 0x9b, 0x49, 0xba, 0xd3, 0x2f, 0x49, 0xf6, 0xb9, 0x58, 0xf0, 0xa1, 0x24, 0xd4, 0xf5, + 0x54, 0xe1, 0x15, 0x0e, 0xaa, 0x74, 0xb1, 0xd6, 0x87, 0x2f, 0x84, 0x24, 0xcf, 0x99, 0x59, 0x22, + 0xa7, 0x0e, 0x62, 0xaf, 0xf1, 0x82, 0x53, 0xa7, 0x23, 0xfa, 0x69, 0x9f, 0x93, 0xbb, 0xa4, 0x95, + 0x22, 0xc3, 0xc1, 0x07, 0x8a, 0xf4, 0xc3, 0xd4, 0xfa, 0x3b, 0x9f, 0xca, 0xa6, 0x9a, 0x69, 0xff, + 0x82, 0xb2, 0x1a, 0x1e, 0x98, 0xce, 0x49, 0xd6, 0xec, 0x6f, 0x6e, 0x5f, 0x05, 0x95, 0x6e, 0xda, + 0x95, 0x85, 0x72, 0xe3, 0x14, 0xa3, 0x83, 0x63, 0x23, 0x7c, 0x29, 0x2b, 0x0c, 0x70, 0x6c, 0x67, + 0xc9, 0xca, 0x94, 0xac, 0x42, 0xf9, 0x18, 0x63, 0x2a, 0x7c, 0x10, 0xdb, 0x56, 0xd6, 0x72, 0xc0, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x04, 0x02, 0x30, 0x3a, 0xbc, 0x2a, 0x3f, 0x07, 0x5d, 0x01, + 0xd7, 0x41, 0x8a, 0x7d, 0x32, 0xfc, 0xba, 0x5d, 0x5c, 0x61, 0x39, 0x6a, 0x84, 0x32, 0x98, 0x62, + 0xed, 0x50, 0x85, 0x91, 0x72, 0xa8, 0x4f, 0x8f, 0xe0, 0x8c, 0xf1, 0xa4, 0xc5, 0x52, 0x60, 0x05, + 0xbe, 0x08, 0xc4, 0x37, 0x31, 0x5e, 0x4e, 0xbc, 0x37, 0x26, 0x13, 0x0b, 0x8d, 0xcc, 0xcb, 0x09, + 0x84, 0x2d, 0x8b, 0x65, 0x31, 0x69, 0x89, 0xcc, 0x5e, 0x63, 0xe0, 0x8e, 0x4f, 0x93, 0xe5, 0xf1, + 0xa2, 0x83, 0x6a, 0x6b, 0x7d, 0x6a, 0xf0, 0x71, 0xa6, 0x9a, 0x65, 0x5e, 0x0d, 0x0a, 0x9a, 0x65, + 0xed, 0xe9, 0xfe, 0x86, 0xb5, 0x5c, 0x60, 0x4f, 0x1a, 0xf2, 0xaf, 0x6a, 0xbc, 0xab, 0xde, 0x35, + 0xe5, 0x5e, 0xf5, 0x5e, 0x55, 0xe2, 0x71, 0x70, 0x75, 0xd0, 0x1d, 0x74, 0xc1, 0xd7, 0x40, 0x75, + 0xd3, 0x37, 0x05, 0xf1, 0x8a, 0x6a, 0x29, 0xe3, 0xbe, 0x5b, 0xe2, 0xa7, 0x36, 0x9b, 0x7d, 0x73, + 0xc7, 0x09, 0x45, 0xb1, 0x6c, 0x5b, 0x16, 0xff, 0xcb, 0x1f, 0xf2, 0xff, 0x7b, 0xe1, 0xfe, 0x35, + 0xe5, 0x5e, 0xf1, 0xaf, 0x2a, 0xf6, 0xab, 0xca, 0xbc, 0x54, 0x65, 0x9b, 0x4d, 0xb9, 0x74, 0xba, + 0xf8, 0x4b, 0x07, 0x5b, 0x00, 0xeb, 0xa1, 0xb5, 0xa3, 0x07, 0x5d, 0x01, 0xd7, 0x45, 0xdc, 0x65, + 0x31, 0xa9, 0x4c, 0x6f, 0x9a, 0x31, 0x4d, 0x45, 0x3f, 0x0b, 0x70, 0x86, 0x91, 0xf1, 0xaf, 0x2a, + 0xf1, 0x51, 0x96, 0x6d, 0x36, 0xe5, 0xd2, 0xe9, 0x31, 0x22, 0x88, 0x3f, 0x8f, 0x8c, 0x6b, 0x01, + 0xf2, 0xf3, 0x17, 0x1d, 0xf2, 0xdf, 0x3e, 0x2e, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x3a, 0xe8, 0x0e, + 0xba, 0x64, 0xe4, 0xe3, 0xbe, 0x5b, 0xef, 0x2c, 0x7f, 0xcb, 0xfd, 0xef, 0x86, 0x04, 0x20, 0x68, + 0x19, 0x49, 0x34, 0x90, 0xb4, 0x2d, 0x3e, 0xdf, 0x6b, 0xec, 0x32, 0xc3, 0x31, 0xc7, 0xe0, 0x80, + 0xdb, 0x4d, 0x2b, 0x07, 0xac, 0xc4, 0xad, 0xa5, 0x4b, 0x52, 0x31, 0xfe, 0x14, 0x95, 0xb0, 0x7b, + 0x4d, 0x2a, 0x3a, 0x34, 0x6a, 0xcd, 0x2a, 0xa8, 0xc5, 0x9d, 0xf8, 0x52, 0x6a, 0x53, 0x34, 0x9d, + 0x4b, 0x76, 0xe8, 0xcd, 0x4f, 0x3e, 0x1f, 0xe4, 0xaf, 0xc6, 0x89, 0xa8, 0x75, 0xd5, 0x7c, 0x9e, + 0x44, 0x6b, 0xd1, 0x33, 0x26, 0x5c, 0xcb, 0xd1, 0x6d, 0xa4, 0x5d, 0x1f, 0x0d, 0xff, 0xcf, 0xa7, + 0xef, 0x8f, 0x85, 0x4a, 0x53, 0x17, 0x0f, 0xc9, 0x91, 0x96, 0x8d, 0xcf, 0xbb, 0x63, 0x69, 0xaf, + 0xc1, 0x74, 0x65, 0x0b, 0x42, 0xae, 0x60, 0xeb, 0xa0, 0x3a, 0xe9, 0x88, 0xb4, 0xf8, 0x78, 0x21, + 0x2d, 0xa7, 0x07, 0x0e, 0xa4, 0x77, 0xcd, 0xaa, 0x7a, 0x69, 0x7f, 0x85, 0xb8, 0xf2, 0x7d, 0x54, + 0x6c, 0x78, 0x6e, 0xfe, 0xa9, 0x53, 0xdd, 0xaf, 0xf1, 0x83, 0xea, 0xab, 0xaa, 0xad, 0xb6, 0x0c, + 0xc4, 0x1a, 0x89, 0x9f, 0xe0, 0x96, 0xd3, 0x5b, 0x4d, 0x6e, 0x7c, 0xf4, 0x71, 0x3e, 0xdb, 0x6d, + 0xb6, 0x4e, 0xb9, 0x32, 0xf1, 0xbd, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0x69, 0xa5, 0x11, 0x32, 0x22, + 0x65, 0x38, 0xff, 0xc1, 0x5d, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0x13, 0xa7, 0xc1, 0x5f, 0x49, 0x2d, + 0x24, 0xb4, 0x92, 0x4c, 0xbc, 0x17, 0x6a, 0xab, 0x69, 0xac, 0xc8, 0x74, 0xf8, 0x27, 0xa7, 0x2d, + 0x3b, 0x4d, 0x65, 0xf0, 0x50, 0x5c, 0x77, 0xcb, 0x7d, 0xad, 0xf2, 0xdf, 0x25, 0x5e, 0x1e, 0x8f, + 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xe3, 0x54, 0xaa, 0xa0, 0x96, 0x9c, 0x55, 0x8a, 0xbf, 0xf0, + 0xed, 0x7f, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc4, 0xb4, 0xe2, 0xac, 0x55, + 0xff, 0x82, 0x8e, 0x3a, 0xd0, 0xb5, 0xa3, 0x5a, 0xd0, 0xb5, 0xa1, 0x2a, 0xf0, 0xf5, 0x7f, 0x97, + 0xfb, 0xd7, 0xf9, 0x7f, 0xbf, 0x8d, 0x50, 0x43, 0xa2, 0xb3, 0x9a, 0x79, 0xa1, 0x56, 0x5a, 0xf3, + 0x69, 0x65, 0xe0, 0xbe, 0x3f, 0xe5, 0xfe, 0xf1, 0xff, 0x2f, 0xf7, 0x89, 0x69, 0xc5, 0x58, 0xab, + 0xff, 0x54, 0xab, 0xcf, 0x22, 0x2a, 0xfc, 0xda, 0x6d, 0xf3, 0xc8, 0x8a, 0xbf, 0x36, 0x9b, 0x7c, + 0xf4, 0xab, 0xf3, 0x69, 0xb5, 0x70, 0xb4, 0x7e, 0x9a, 0xfa, 0x6b, 0xe9, 0xaf, 0xa6, 0x83, 0x33, + 0xfa, 0x64, 0xb6, 0xea, 0xe1, 0xa8, 0xff, 0x97, 0xfb, 0xc8, 0x8e, 0x89, 0xac, 0xdf, 0xfc, 0xf4, + 0x45, 0xaf, 0x16, 0x85, 0xaf, 0xd5, 0x3a, 0x5c, 0x37, 0xe3, 0x54, 0x22, 0x11, 0x6b, 0xc5, 0x84, + 0x2c, 0x2f, 0xc2, 0x99, 0xa0, 0x58, 0x79, 0xa1, 0x96, 0x1e, 0x68, 0x16, 0x1a, 0x75, 0xe7, 0xa5, + 0x5f, 0x9b, 0x4d, 0xbe, 0x7a, 0x55, 0xf9, 0xb4, 0xdb, 0xe1, 0xc8, 0xcb, 0x42, 0x96, 0x8f, 0x4a, + 0xbf, 0x36, 0x9b, 0x7c, 0xf4, 0xab, 0xf3, 0x69, 0xb7, 0xcf, 0x4a, 0xbf, 0x36, 0x9b, 0x7c, 0xf4, + 0x4b, 0x5f, 0x8b, 0x42, 0xd7, 0x87, 0xf3, 0x36, 0x3b, 0x43, 0x41, 0x45, 0x2f, 0x7e, 0x66, 0x32, + 0xca, 0xbf, 0x36, 0x9b, 0x7c, 0x6e, 0x68, 0x16, 0x1e, 0x68, 0x72, 0xc3, 0xcd, 0x02, 0xc3, 0x4e, + 0xbc, 0xda, 0x6d, 0xfe, 0x09, 0x08, 0xd3, 0x5a, 0x75, 0xe0, 0xa2, 0xd3, 0x5b, 0x4d, 0x69, 0xd7, + 0x8d, 0xed, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x39, 0xf4, 0xd3, 0x6d, 0xbf, 0x05, 0xb6, 0x9a, + 0xda, 0x6b, 0xa7, 0x5e, 0x08, 0xb4, 0x0c, 0x84, 0x98, 0x49, 0x2a, 0xf0, 0x4b, 0x69, 0xa8, 0x0d, + 0x03, 0x69, 0xa4, 0x0d, 0x03, 0x1e, 0x5f, 0x10, 0x23, 0x96, 0xb9, 0xdb, 0x47, 0xe1, 0x52, 0xba, + 0x19, 0x0a, 0xaf, 0xf9, 0xc9, 0x55, 0x1a, 0x45, 0x4a, 0x0a, 0x53, 0x4d, 0xcf, 0xcf, 0xcf, 0x7f, + 0x83, 0x09, 0x08, 0xc5, 0xe4, 0xa4, 0xc4, 0x14, 0x77, 0xed, 0x8a, 0xba, 0xdb, 0xf1, 0xb3, 0x0c, + 0x36, 0x09, 0xa2, 0xb3, 0x53, 0xfd, 0xc7, 0x8f, 0x21, 0x06, 0x42, 0x31, 0xd1, 0x56, 0x2a, 0xd3, + 0x4d, 0xd0, 0x45, 0x33, 0x5f, 0x94, 0xf8, 0xc2, 0xf3, 0xbf, 0xc4, 0x18, 0xb9, 0x79, 0x30, 0x98, + 0x5c, 0x6e, 0x79, 0x24, 0x21, 0x61, 0x09, 0x08, 0x58, 0x43, 0xe3, 0x65, 0xc6, 0xe4, 0x07, 0x01, + 0xa2, 0x04, 0x9f, 0x02, 0x60, 0x66, 0x3f, 0x89, 0xae, 0x92, 0x44, 0xc6, 0x63, 0x31, 0x98, 0x9d, + 0x8d, 0x43, 0xba, 0x1f, 0xfc, 0x68, 0x8c, 0x96, 0x27, 0x30, 0x82, 0x6d, 0xac, 0x63, 0x1a, 0xb9, + 0xfa, 0xbd, 0x67, 0x66, 0xc7, 0x0d, 0x8c, 0xf3, 0x38, 0x12, 0x96, 0x28, 0xe7, 0xc3, 0x62, 0x5b, + 0x1d, 0x51, 0xa9, 0x95, 0x17, 0x93, 0x3e, 0x3b, 0xa7, 0x6c, 0x12, 0x3a, 0x0f, 0x79, 0xf8, 0x68, + 0xe3, 0x2d, 0x0a, 0x5a, 0x3c, 0x93, 0xaf, 0x3e, 0x9f, 0x75, 0xc3, 0x7e, 0x35, 0xe4, 0xcb, 0xf2, + 0xe9, 0x77, 0xc6, 0xc1, 0xd7, 0x40, 0x75, 0xd3, 0x1d, 0x74, 0x1d, 0x74, 0xc1, 0xd7, 0x40, 0x75, + 0xd3, 0x07, 0x5d, 0x01, 0xd7, 0x4c, 0x88, 0xe8, 0x9a, 0x4d, 0xcf, 0xa7, 0xdf, 0xe1, 0xd8, 0xeb, + 0xa0, 0xeb, 0xa6, 0x3a, 0xe8, 0x3a, 0xe9, 0x83, 0xae, 0x80, 0xeb, 0xa6, 0x44, 0x93, 0x49, 0xbf, + 0xf8, 0xfe, 0x0e, 0xba, 0x03, 0xae, 0x9c, 0x1d, 0x74, 0x07, 0x5d, 0x31, 0xaf, 0x7e, 0x16, 0x8f, + 0xfb, 0xe3, 0xfe, 0xf9, 0x11, 0xd1, 0x35, 0x9b, 0x9f, 0x4f, 0xbf, 0xa2, 0x1d, 0x3e, 0x15, 0xb4, + 0xd3, 0x34, 0x9a, 0xab, 0x52, 0x19, 0x3a, 0x64, 0xdb, 0x1f, 0xae, 0x1f, 0x3e, 0x35, 0xe5, 0x5e, + 0xf1, 0xaf, 0x2a, 0xf6, 0xab, 0xca, 0xbc, 0x54, 0x65, 0x9b, 0x4d, 0xb9, 0x74, 0xbb, 0xef, 0x8d, + 0x79, 0x57, 0xa3, 0xd1, 0x69, 0x57, 0xe1, 0x5c, 0xb2, 0x5c, 0xbf, 0x24, 0x31, 0x4c, 0xd0, 0x53, + 0x32, 0x71, 0xa6, 0xe4, 0xa6, 0x35, 0xe6, 0x57, 0x8c, 0xa9, 0x25, 0x7e, 0x99, 0x7e, 0x16, 0x65, + 0xeb, 0x88, 0xcf, 0x86, 0xcf, 0x3e, 0x7c, 0x31, 0x1e, 0x68, 0x5c, 0xd1, 0xeb, 0x9a, 0x17, 0x34, + 0x79, 0x91, 0xd7, 0x9b, 0x4d, 0xbf, 0xaa, 0x22, 0xd3, 0xe3, 0x60, 0xeb, 0xa0, 0x3a, 0xe9, 0x83, + 0xae, 0x80, 0xeb, 0xa6, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x3a, 0xe8, 0x0e, 0xba, 0x64, 0x47, 0x44, + 0xd2, 0x6e, 0x7d, 0x7e, 0xfe, 0x22, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x3a, 0xe8, 0x0e, 0xba, 0x7e, + 0xa2, 0xab, 0xe7, 0x8c, 0xa5, 0x04, 0x82, 0x26, 0xb3, 0x7e, 0x75, 0xf9, 0xe3, 0x29, 0x41, 0x20, + 0x89, 0xac, 0xdf, 0xf5, 0x2a, 0x7c, 0xdc, 0x75, 0xa1, 0x6b, 0x47, 0xa8, 0x21, 0xbe, 0x1d, 0x83, + 0xae, 0x83, 0xae, 0x98, 0xeb, 0xa0, 0xeb, 0xa6, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x8a, 0x47, 0x5e, + 0x6d, 0x76, 0xfe, 0x0b, 0xe0, 0xeb, 0xa0, 0x3a, 0xe9, 0x83, 0xae, 0x80, 0xeb, 0xa6, 0x09, 0x19, + 0xd7, 0x9b, 0x4d, 0xbf, 0x86, 0xf8, 0xd7, 0xb1, 0x16, 0x87, 0x4a, 0x09, 0x04, 0x22, 0x66, 0x33, + 0x6c, 0xba, 0x5d, 0xf0, 0xa1, 0x1a, 0x69, 0x24, 0x9a, 0x69, 0x24, 0x9a, 0x69, 0x83, 0x60, 0xda, + 0x69, 0x83, 0x60, 0xf2, 0xf9, 0x24, 0xdf, 0xe1, 0x4a, 0x4d, 0xb9, 0x08, 0xd0, 0x31, 0x86, 0x4a, + 0xdc, 0x11, 0xe5, 0x7e, 0x37, 0x68, 0xfa, 0x11, 0xea, 0x84, 0x77, 0xe0, 0x87, 0x1c, 0x4c, 0xf4, + 0xf8, 0xed, 0xf0, 0xe1, 0x47, 0xe9, 0xbd, 0x9a, 0x65, 0xf9, 0x74, 0xbb, 0xe1, 0x22, 0x6d, 0x18, + 0xad, 0x3a, 0x7e, 0x14, 0xd3, 0x8c, 0x2b, 0x47, 0x9f, 0xc7, 0x35, 0x8e, 0x40, 0x75, 0x2f, 0xb5, + 0xbe, 0x2a, 0x57, 0x1b, 0xa4, 0x6d, 0x7a, 0x95, 0x47, 0xce, 0x55, 0x5a, 0xb5, 0xa8, 0x5f, 0xbb, + 0xee, 0x2e, 0xe2, 0xfe, 0x14, 0x15, 0xd6, 0xd4, 0x98, 0x9d, 0x3a, 0xcd, 0xc3, 0x8a, 0xdf, 0x76, + 0x3e, 0x1b, 0x08, 0xe3, 0xad, 0x0b, 0x5a, 0x0c, 0x8e, 0xf2, 0xe9, 0x74, 0xfb, 0x93, 0x4b, 0xc3, + 0x51, 0xff, 0x2f, 0xf7, 0x91, 0x24, 0xd2, 0x6f, 0xfe, 0x36, 0xf8, 0x05, 0x1b, 0x95, 0x54, 0xc6, + 0x55, 0x42, 0xe7, 0x81, 0x23, 0x72, 0xaa, 0x98, 0xca, 0xa8, 0x5d, 0x2a, 0xfc, 0xda, 0x6d, 0xf3, + 0xd2, 0xaf, 0xcd, 0xa6, 0xdf, 0x3d, 0x2a, 0xfc, 0xda, 0x6d, 0x5c, 0x68, 0x41, 0xa6, 0x9a, 0x68, + 0x2f, 0x4c, 0xe4, 0xf4, 0xce, 0xc6, 0x10, 0x2d, 0xa0, 0x03, 0xbe, 0x44, 0x99, 0xf0, 0x4c, 0x77, + 0xb0, 0x38, 0xff, 0x82, 0xaf, 0xc0, 0x67, 0x86, 0x80, 0x43, 0xcd, 0xc6, 0x2e, 0x9f, 0xaa, 0x33, + 0x9a, 0x41, 0xab, 0xff, 0x86, 0x2b, 0x21, 0x08, 0x64, 0x19, 0x10, 0xc6, 0xa7, 0xf8, 0x7c, 0x83, + 0x8c, 0x7e, 0xa6, 0x60, 0x0a, 0x4d, 0xc0, 0xc6, 0x4b, 0x16, 0x75, 0xc6, 0xab, 0xa5, 0xf9, 0x47, + 0xe3, 0x00, 0xd7, 0x7e, 0x1a, 0x8c, 0x79, 0x47, 0x97, 0x34, 0x2e, 0x68, 0x00, 0x51, 0xaa, 0xf1, + 0x54, 0x2a, 0xb8, 0xf7, 0xc3, 0x00, 0x28, 0x1e, 0x88, 0x99, 0x3a, 0x64, 0x44, 0xc9, 0xd3, 0x3e, + 0xb8, 0x7a, 0x3a, 0xe8, 0x3a, 0xe9, 0x8e, 0xba, 0x0e, 0xba, 0x60, 0xeb, 0xa0, 0x3a, 0xe9, 0x87, + 0xa8, 0x8b, 0x49, 0x33, 0x6d, 0x8a, 0xa2, 0xd5, 0xf8, 0xde, 0x25, 0xa0, 0x3a, 0xe8, 0x3b, 0xef, + 0xe3, 0xfe, 0xe3, 0xae, 0x9c, 0x4a, 0x47, 0x42, 0xd0, 0xb5, 0x9b, 0x4d, 0xbf, 0x82, 0x38, 0x3d, + 0xd0, 0x1e, 0xe9, 0x89, 0x68, 0x45, 0xaf, 0x3c, 0x46, 0x47, 0x46, 0xd3, 0x6a, 0x0a, 0x04, 0x6d, + 0x36, 0xfe, 0x1e, 0x97, 0x3f, 0x2e, 0x4f, 0x43, 0x63, 0xe8, 0x23, 0x23, 0xa3, 0x69, 0xb6, 0x05, + 0x02, 0x36, 0x9b, 0x7f, 0x54, 0xbf, 0x0e, 0x8a, 0xac, 0x57, 0xb8, 0xae, 0xd1, 0xfe, 0xb3, 0x59, + 0xab, 0x3f, 0xe0, 0x80, 0x41, 0xe9, 0xcb, 0x01, 0xd1, 0x51, 0x4a, 0x05, 0x59, 0xaa, 0x26, 0x63, + 0x2a, 0x54, 0xba, 0x65, 0x4b, 0xff, 0x0b, 0x13, 0x4c, 0x94, 0xc7, 0xf6, 0x9d, 0x28, 0x3e, 0x2a, + 0xc5, 0x5f, 0xe3, 0x64, 0xdb, 0x64, 0x2e, 0x35, 0x08, 0x5d, 0x71, 0x55, 0xc6, 0x51, 0xe3, 0x96, + 0x2e, 0x40, 0xb1, 0x8c, 0x6a, 0x33, 0x8d, 0xf6, 0x84, 0xd2, 0xb7, 0x1f, 0x89, 0x0b, 0xf0, 0x7e, + 0xa0, 0xfd, 0x7c, 0x5f, 0xbe, 0x15, 0x8f, 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc8, 0x92, 0x69, + 0x37, 0xf5, 0xd4, 0xe9, 0x2f, 0x3c, 0xa9, 0xcd, 0xa6, 0xdf, 0x5c, 0x44, 0x7f, 0xcb, 0xfd, 0xeb, + 0xfc, 0xbf, 0xdf, 0xe2, 0x09, 0xd2, 0x4b, 0x49, 0x2f, 0x1f, 0x69, 0xad, 0xa3, 0xed, 0xb9, 0xc8, + 0xda, 0xf1, 0xf6, 0x53, 0x96, 0x85, 0xc3, 0x5b, 0x08, 0x2e, 0xcd, 0x22, 0xe7, 0x87, 0xf9, 0xf0, + 0xb4, 0xe7, 0xcb, 0x45, 0x25, 0xa8, 0xf9, 0xe5, 0xb6, 0xd3, 0x4f, 0xfc, 0x82, 0x46, 0x29, 0xff, + 0x11, 0x18, 0xf2, 0x8f, 0x7f, 0x18, 0xf2, 0x8f, 0x13, 0x86, 0x89, 0x07, 0x5b, 0x19, 0x29, 0x21, + 0x24, 0x3f, 0xe1, 0x0c, 0x75, 0x31, 0x5a, 0x98, 0x8f, 0x6c, 0x51, 0xc1, 0xed, 0x88, 0xf3, 0xbf, + 0x82, 0x38, 0x3b, 0xb1, 0x1d, 0x6c, 0x52, 0x2f, 0x24, 0x1d, 0x6c, 0x41, 0xd6, 0xc7, 0xce, 0x4e, + 0x36, 0xc5, 0xd8, 0xc5, 0xd8, 0xdd, 0x8d, 0x13, 0xf8, 0x54, 0x55, 0xa9, 0x5e, 0x9b, 0x4a, 0xde, + 0x15, 0x44, 0xa5, 0x33, 0x41, 0x3f, 0xfc, 0x68, 0xbf, 0x1a, 0xf7, 0xb4, 0xd6, 0x86, 0x65, 0x77, + 0xb4, 0xd6, 0xbb, 0x9b, 0x61, 0x7f, 0x8c, 0xed, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x78, 0x44, + 0xb8, 0x3a, 0xe8, 0x0e, 0xba, 0x60, 0xeb, 0xa0, 0x3a, 0xe9, 0x83, 0xae, 0x80, 0xeb, 0xa7, 0x86, + 0x32, 0xe6, 0x4c, 0x88, 0xd0, 0x94, 0x4c, 0xbf, 0x2e, 0x97, 0x7c, 0x18, 0x41, 0xd7, 0x40, 0x75, + 0xd3, 0x07, 0x5d, 0x01, 0xd7, 0x4c, 0x88, 0x2c, 0xa2, 0x69, 0x37, 0x3e, 0x9f, 0x7f, 0x85, 0x78, + 0x3a, 0xe8, 0x0e, 0xba, 0x60, 0xeb, 0xa0, 0x3a, 0xe8, 0x64, 0xe5, 0xd2, 0xef, 0xf8, 0x8f, 0x07, + 0x5d, 0x01, 0xd7, 0x4e, 0x0e, 0xba, 0x03, 0xae, 0x9e, 0x18, 0x83, 0xae, 0x80, 0xeb, 0xa6, 0x0e, + 0xba, 0x03, 0xae, 0x99, 0x12, 0x4d, 0x26, 0xff, 0xe7, 0xa6, 0x5f, 0x97, 0x4b, 0xbe, 0x18, 0x83, + 0xae, 0x80, 0xeb, 0xa6, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x7e, 0x9e, 0x4d, 0x4b, 0x34, 0x2e, 0x87, + 0xc6, 0x84, 0x00, 0xab, 0xae, 0x5b, 0x81, 0x93, 0xcb, 0xa7, 0xd9, 0x59, 0x67, 0x6a, 0xe3, 0x27, + 0x62, 0xaf, 0xeb, 0xe7, 0x4f, 0xb8, 0x1f, 0xaa, 0x8f, 0xe3, 0x5f, 0x1c, 0x87, 0xcc, 0xd7, 0x48, + 0xa1, 0x75, 0x0d, 0x19, 0x8e, 0x2f, 0xe3, 0xed, 0x98, 0xc3, 0x92, 0x68, 0x38, 0x33, 0x0d, 0x0d, + 0x1f, 0x85, 0xce, 0xe1, 0x78, 0x29, 0x45, 0x12, 0x0e, 0xb6, 0x58, 0x1c, 0x55, 0x8e, 0x37, 0x3e, + 0x18, 0x6c, 0x07, 0x7d, 0xc7, 0xe3, 0x7a, 0xf7, 0xdc, 0x72, 0x53, 0xdc, 0x0a, 0x3e, 0x06, 0xe5, + 0xa9, 0xe1, 0x23, 0x49, 0xd2, 0xa2, 0x72, 0x44, 0x36, 0x34, 0xe6, 0xb5, 0xb4, 0x88, 0x01, 0xc1, + 0x80, 0x2b, 0x2f, 0xa6, 0x4e, 0xca, 0x69, 0xa6, 0xac, 0x26, 0x40, 0x9a, 0xa6, 0xb3, 0xf4, 0x25, + 0x9d, 0xea, 0xfe, 0x03, 0xbd, 0x0f, 0x8f, 0xc3, 0xe4, 0xd0, 0xeb, 0x0e, 0xb7, 0x73, 0x9a, 0x0d, + 0xfa, 0xcf, 0x71, 0x65, 0x4d, 0x1f, 0x7c, 0x37, 0x38, 0xd7, 0xe9, 0xf0, 0xd6, 0x31, 0x67, 0xc1, + 0x01, 0xeb, 0x52, 0x1a, 0x0b, 0xbc, 0x11, 0xf1, 0xe1, 0x5a, 0xc3, 0x5a, 0x9c, 0xb5, 0xc5, 0x9a, + 0x8b, 0x75, 0x5a, 0x7e, 0x08, 0x06, 0xb4, 0xd6, 0x27, 0x8d, 0x4d, 0xa6, 0xb3, 0xb4, 0xff, 0xd9, + 0x7b, 0xe1, 0x29, 0xc4, 0x44, 0xed, 0x03, 0x80, 0xf4, 0x92, 0xf1, 0xf2, 0x92, 0x29, 0x28, 0x0e, + 0x03, 0xd2, 0x4b, 0x49, 0x2f, 0x0a, 0x52, 0x4a, 0xdc, 0xb4, 0xda, 0x6a, 0xdb, 0x46, 0xcd, 0xcf, + 0x87, 0x8c, 0xd3, 0x4a, 0xba, 0xaa, 0xde, 0x1e, 0x63, 0xd2, 0x6f, 0xdb, 0x6c, 0x18, 0xfd, 0xe1, + 0xe1, 0x0d, 0x34, 0xaa, 0xd4, 0x93, 0x62, 0x3b, 0x10, 0x54, 0x0e, 0x0c, 0xa8, 0x8a, 0x7d, 0xd4, + 0x8e, 0x45, 0x6e, 0xfe, 0x1d, 0x32, 0x23, 0x4a, 0x52, 0x79, 0xf5, 0x08, 0x84, 0x76, 0x90, 0x46, + 0x86, 0x35, 0xf9, 0x6f, 0x4f, 0xc2, 0x92, 0x93, 0xdd, 0x1b, 0x32, 0x1a, 0x2e, 0xc0, 0xa4, 0x91, + 0x4e, 0x37, 0xd7, 0xa9, 0xa3, 0x1f, 0xe3, 0x6b, 0x7d, 0x42, 0x7e, 0xea, 0x35, 0xcd, 0xd2, 0x35, + 0xae, 0x88, 0x70, 0xde, 0xce, 0x76, 0x8b, 0x2c, 0x58, 0xf9, 0x3b, 0xb7, 0xf0, 0xf5, 0xa1, 0xa8, + 0x35, 0x43, 0x2a, 0xfd, 0xa0, 0xa3, 0xaa, 0xaa, 0xab, 0x13, 0x83, 0xaa, 0xae, 0x5a, 0x1f, 0xf8, + 0xd0, 0xce, 0x35, 0xe5, 0x5e, 0xd5, 0x79, 0x57, 0xbc, 0x75, 0xa1, 0x6b, 0x47, 0xaa, 0xf2, 0xaf, + 0x15, 0x05, 0x9f, 0x9b, 0x4d, 0xb9, 0x74, 0xbb, 0xe1, 0x58, 0xff, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, + 0xbc, 0x11, 0x9d, 0x06, 0x3c, 0xcd, 0x64, 0x33, 0xe9, 0xf7, 0xf8, 0xc2, 0x76, 0x9a, 0xda, 0x6b, + 0x69, 0xad, 0xa6, 0xbc, 0x2d, 0x69, 0xad, 0xa6, 0xb7, 0xfb, 0x6d, 0xa6, 0x9b, 0xe7, 0x3a, 0x55, + 0xf9, 0xb4, 0xdb, 0xe0, 0xbf, 0x3f, 0x9b, 0x9f, 0xcd, 0xe9, 0x57, 0xe6, 0xd3, 0x6a, 0xe0, 0x80, + 0x43, 0x4d, 0x6d, 0x35, 0xb4, 0xd6, 0xff, 0x6d, 0xb4, 0xd3, 0xf5, 0xe5, 0x5e, 0x37, 0xa4, 0x96, + 0x92, 0x4d, 0x35, 0xb4, 0xd6, 0xff, 0x6d, 0xb4, 0xd3, 0xf0, 0x84, 0x99, 0xe4, 0xc2, 0x61, 0x88, + 0x35, 0x72, 0xd3, 0xc3, 0x1b, 0x46, 0x21, 0xc7, 0x16, 0xae, 0xbe, 0x25, 0x32, 0x25, 0x32, 0xdd, + 0x7e, 0x15, 0xb4, 0xd3, 0x07, 0x69, 0xad, 0x7c, 0x4a, 0x64, 0x4a, 0x66, 0xba, 0xfc, 0x7c, 0x84, + 0x19, 0xb2, 0x4c, 0xf9, 0x73, 0xf4, 0x51, 0xac, 0x3c, 0xfe, 0x78, 0xe9, 0x4d, 0xa6, 0xd6, 0x9a, + 0x69, 0xaf, 0xf0, 0xe1, 0x63, 0x29, 0x8a, 0x94, 0xc0, 0xe0, 0x94, 0x55, 0x8a, 0xb2, 0xd6, 0x2a, + 0xfc, 0xdc, 0x24, 0x21, 0xa1, 0xea, 0xda, 0x5c, 0xce, 0x9d, 0x3f, 0x06, 0x16, 0x90, 0x9f, 0x1a, + 0x43, 0x9d, 0x73, 0xe7, 0xaa, 0xcd, 0xdb, 0xff, 0x0a, 0x5b, 0xb7, 0x6e, 0xdd, 0x7d, 0x3e, 0x6e, + 0xdb, 0x62, 0x55, 0x22, 0x2d, 0x19, 0xf8, 0x56, 0xd9, 0xcf, 0xb7, 0xa3, 0x18, 0x38, 0xa0, 0x74, + 0x46, 0x17, 0xf1, 0xda, 0x2d, 0xa7, 0x85, 0x04, 0x65, 0x60, 0x3f, 0x70, 0x7e, 0x2f, 0x47, 0x74, + 0xcf, 0x08, 0xf4, 0xfb, 0xe1, 0x51, 0xe3, 0xfe, 0x5f, 0xef, 0x5f, 0xe5, 0xfe, 0xf2, 0x24, 0x9a, + 0x4d, 0xfd, 0x71, 0x84, 0xda, 0x6b, 0x69, 0xad, 0xa6, 0xb6, 0x9a, 0xf0, 0x85, 0xa6, 0xb6, 0x9a, + 0xda, 0x6b, 0xf1, 0x76, 0x9a, 0xda, 0x6b, 0xf1, 0x1d, 0x24, 0xb4, 0x92, 0xf1, 0x65, 0xc7, 0x7c, + 0xb7, 0xda, 0xdf, 0x2d, 0xf7, 0x8c, 0xe3, 0x5e, 0x55, 0xe8, 0xd5, 0x15, 0x78, 0xc5, 0x48, 0xf5, + 0x5e, 0x55, 0xef, 0x55, 0xe5, 0x5e, 0xf0, 0x97, 0x1d, 0xf2, 0xdf, 0x6b, 0x7c, 0xb7, 0xde, 0x18, + 0x8f, 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc8, 0x90, 0xa6, 0x5f, 0xff, 0x88, 0x87, 0x82, 0x4d, + 0x79, 0x14, 0xe4, 0xc9, 0x1b, 0x32, 0xc5, 0x35, 0x0a, 0xe6, 0x46, 0x6f, 0xb2, 0x37, 0x6f, 0x72, + 0x8d, 0xe7, 0x46, 0xb0, 0x91, 0x9a, 0x31, 0x3b, 0xb5, 0x44, 0x14, 0xff, 0x10, 0x63, 0x71, 0x8b, + 0x11, 0x0a, 0x6a, 0x2e, 0x68, 0xdd, 0x66, 0xbe, 0xd5, 0xe2, 0x92, 0xc3, 0x2c, 0x4c, 0x14, 0x22, + 0x40, 0x03, 0x08, 0xdf, 0x99, 0x9d, 0x9f, 0x29, 0x84, 0xec, 0xf4, 0x40, 0x62, 0xab, 0x81, 0x34, + 0xf0, 0x4d, 0xa3, 0x5b, 0xd0, 0xf0, 0xe3, 0xaf, 0x0b, 0xce, 0x8e, 0x0c, 0xe7, 0x8d, 0x25, 0x6d, + 0xaf, 0x71, 0x0f, 0x7d, 0x60, 0xf0, 0xc5, 0xc8, 0x35, 0xc3, 0x09, 0x54, 0x73, 0x7d, 0x71, 0xd5, + 0x99, 0x50, 0xe2, 0x19, 0x5c, 0xb1, 0xed, 0x7b, 0x6a, 0x6f, 0xf8, 0x29, 0xb2, 0xd1, 0xb7, 0xa8, + 0xb8, 0xba, 0x68, 0x73, 0x43, 0x92, 0x24, 0x1f, 0x12, 0x17, 0x1f, 0xa6, 0xbe, 0x9f, 0x1d, 0xf2, + 0xdf, 0x78, 0x66, 0x3f, 0xe5, 0xfe, 0xf2, 0x24, 0x9a, 0x4d, 0xff, 0xc1, 0x84, 0x7f, 0xcb, 0xfd, + 0xe3, 0xfe, 0x5f, 0xef, 0x22, 0x49, 0xa4, 0xdf, 0xfc, 0x27, 0xc7, 0x7c, 0xb7, 0xd8, 0xef, 0x96, + 0xfb, 0xc6, 0x1b, 0x69, 0xad, 0xa6, 0xba, 0x9a, 0x0c, 0x31, 0x94, 0x75, 0x87, 0x1d, 0x8f, 0x1a, + 0x12, 0x52, 0x30, 0xec, 0x34, 0x7b, 0xba, 0x44, 0xe6, 0xcb, 0x61, 0xb6, 0x29, 0x63, 0x43, 0x86, + 0x65, 0xc9, 0x1a, 0xce, 0x1c, 0x52, 0x8f, 0xff, 0xf0, 0x5b, 0x40, 0xea, 0x5b, 0x84, 0x79, 0xd3, + 0xd2, 0xaf, 0x1a, 0x34, 0x25, 0xd3, 0x6b, 0xab, 0xa2, 0x98, 0xa9, 0xa6, 0xe8, 0xe0, 0x00, 0x9f, + 0x79, 0xf5, 0xfa, 0xaf, 0xdf, 0xd3, 0x4d, 0x34, 0xff, 0xc2, 0x83, 0x26, 0x65, 0xc9, 0x0e, 0x51, + 0x66, 0xcd, 0xa1, 0x82, 0xf1, 0x61, 0xb3, 0x65, 0x1d, 0x7c, 0x3b, 0x43, 0x1c, 0x62, 0x42, 0xf0, + 0x1b, 0x8e, 0xec, 0xea, 0x67, 0xf3, 0xe7, 0x69, 0x8f, 0x97, 0xc9, 0x5a, 0xe1, 0xe0, 0xb8, 0xeb, + 0xa0, 0xeb, 0xa6, 0x3a, 0xe8, 0x3a, 0xe9, 0x83, 0xae, 0x80, 0xeb, 0xa6, 0x44, 0x93, 0x59, 0xbf, + 0xf9, 0xe5, 0x40, 0x1f, 0x9b, 0x4d, 0xbe, 0xb8, 0x5e, 0x0e, 0xba, 0x03, 0xae, 0x9c, 0x1d, 0x6c, + 0x41, 0xd6, 0xc0, 0x7a, 0x80, 0x4a, 0x44, 0xdb, 0x7f, 0xe0, 0x8e, 0x3f, 0x4d, 0x7d, 0x32, 0xa7, + 0xc2, 0xdc, 0x4b, 0x85, 0x20, 0xe3, 0xad, 0x0b, 0x5a, 0x04, 0x5a, 0x2a, 0x15, 0x42, 0xab, 0xcd, + 0xa6, 0xdf, 0x0e, 0x70, 0x75, 0xd0, 0x1d, 0x74, 0x2a, 0x1b, 0x5e, 0x53, 0x4d, 0x35, 0x5d, 0x7e, + 0x09, 0xa0, 0xeb, 0xa1, 0xc9, 0x63, 0xcd, 0x0e, 0x20, 0xf2, 0xa5, 0x74, 0x6a, 0xae, 0x19, 0xcb, + 0x49, 0xc8, 0x2f, 0xf6, 0xdb, 0x6d, 0xbf, 0x1d, 0x69, 0xae, 0xd1, 0x88, 0x6a, 0x69, 0xaf, 0xc6, + 0x64, 0xd8, 0x7c, 0x7e, 0x0f, 0x2d, 0x5d, 0xaa, 0xb1, 0xe5, 0xab, 0xf8, 0x7c, 0xbb, 0x4d, 0x6d, + 0x35, 0xb4, 0xd2, 0x64, 0xb2, 0x74, 0xd3, 0x11, 0x32, 0x9c, 0x6b, 0x85, 0x36, 0x92, 0xb4, 0xd5, + 0x22, 0xe2, 0x5e, 0x81, 0x9b, 0x06, 0x8a, 0x7c, 0x4e, 0xc4, 0x90, 0xea, 0x60, 0xd7, 0xbb, 0x65, + 0xe1, 0x7b, 0x10, 0xea, 0x4b, 0x16, 0xdd, 0xba, 0xfb, 0x89, 0x58, 0x73, 0xd6, 0x3c, 0x10, 0xf8, + 0x8a, 0x92, 0x29, 0x8b, 0xe1, 0xb9, 0xed, 0xa4, 0xea, 0x9a, 0x73, 0x9d, 0xff, 0x05, 0xf9, 0x48, + 0x32, 0x90, 0x69, 0xd3, 0x26, 0xfe, 0xe5, 0xdf, 0xd4, 0x55, 0x1e, 0x3c, 0x2f, 0xa6, 0x91, 0x08, + 0x69, 0xd3, 0x13, 0xa2, 0x21, 0x13, 0x22, 0xda, 0x09, 0x05, 0xff, 0x8d, 0x14, 0x39, 0x48, 0x28, + 0xd0, 0x95, 0x33, 0x78, 0xca, 0xc7, 0x65, 0x50, 0x6d, 0x76, 0xc7, 0x54, 0xcd, 0x44, 0xf6, 0x3f, + 0xf1, 0x22, 0xd8, 0x33, 0x51, 0x2e, 0xa6, 0x9a, 0x6b, 0xc2, 0xb4, 0x92, 0xd2, 0x4b, 0x51, 0x13, + 0x22, 0x26, 0x53, 0x8f, 0xfc, 0xdd, 0x24, 0xbc, 0x27, 0xd2, 0x4b, 0x49, 0x2f, 0x1d, 0x69, 0xad, + 0xa6, 0xb6, 0x9a, 0xfc, 0x67, 0x69, 0xab, 0x6d, 0x2e, 0xd3, 0x5b, 0x4d, 0x78, 0x4b, 0xed, 0x35, + 0xb4, 0xd2, 0xe0, 0xaf, 0x55, 0x5b, 0x4d, 0x6d, 0x35, 0xd5, 0x44, 0xc4, 0x72, 0x92, 0x29, 0x26, + 0xf6, 0x97, 0x12, 0x34, 0x21, 0xaf, 0xd3, 0x72, 0xf7, 0x28, 0xa1, 0x96, 0x61, 0x5e, 0x55, 0x55, + 0xa0, 0x26, 0x8a, 0xa5, 0x1f, 0xff, 0x34, 0xef, 0xe3, 0x63, 0x23, 0x8c, 0xdb, 0x7b, 0xc1, 0xc0, + 0x6e, 0x96, 0xd4, 0x86, 0x34, 0xc3, 0xea, 0x90, 0xa8, 0x7b, 0xc4, 0x1a, 0x36, 0x1b, 0xad, 0xc5, + 0xff, 0xe3, 0x6f, 0xeb, 0x6b, 0x6d, 0x6b, 0x43, 0x00, 0x14, 0xee, 0x46, 0xeb, 0x72, 0xe5, 0xbc, + 0xb6, 0x5b, 0x10, 0xf7, 0xec, 0x12, 0xcc, 0x4f, 0x2a, 0x62, 0xda, 0xa7, 0x97, 0xaf, 0x86, 0xc4, + 0xac, 0xeb, 0x50, 0x30, 0x61, 0x3f, 0xdb, 0x6c, 0xf5, 0xaf, 0xc1, 0x78, 0xb0, 0x75, 0xd0, 0x1d, + 0x74, 0xc1, 0xd7, 0x40, 0x75, 0xd3, 0x22, 0x53, 0x26, 0xff, 0xe1, 0xcc, 0x6a, 0x9d, 0x32, 0xfc, + 0xba, 0x5d, 0xf0, 0x5f, 0x1d, 0x74, 0x1d, 0x74, 0xc7, 0x5d, 0x01, 0xd7, 0x4c, 0x89, 0x26, 0x93, + 0x7f, 0xf0, 0x40, 0x10, 0x33, 0x68, 0xca, 0x81, 0x15, 0xab, 0x24, 0x18, 0xe0, 0xe8, 0x68, 0xf1, + 0x31, 0xa4, 0x2c, 0x85, 0x38, 0x02, 0xd5, 0x4d, 0x4b, 0xff, 0xc2, 0x86, 0xd9, 0xa8, 0xb6, 0x13, + 0x1d, 0x43, 0x31, 0x94, 0x3d, 0x8b, 0x38, 0xa2, 0xeb, 0xdc, 0x44, 0xfb, 0x9f, 0x1a, 0x3d, 0x20, + 0xfb, 0x54, 0xf6, 0x4d, 0xf3, 0xaa, 0x3a, 0xa6, 0x8e, 0xab, 0x6b, 0x0a, 0x69, 0xa6, 0x9f, 0xf8, + 0x5c, 0xcb, 0x37, 0x0f, 0xb4, 0xcf, 0x53, 0x90, 0x6c, 0xc8, 0xab, 0xdd, 0xdd, 0xfc, 0x68, 0x84, + 0x41, 0x9d, 0x7c, 0xc9, 0xca, 0x36, 0x62, 0x8e, 0x9b, 0x0d, 0x89, 0x50, 0x6e, 0xc4, 0x87, 0x69, + 0xa9, 0xdd, 0x6a, 0x7a, 0x7f, 0x6f, 0xfe, 0x70, 0xb8, 0x94, 0x8a, 0xbf, 0x36, 0x9b, 0x7c, 0x2f, + 0xc6, 0x29, 0x8e, 0xba, 0x03, 0xae, 0x99, 0xd7, 0xf9, 0xf4, 0xda, 0xed, 0xf0, 0x43, 0xc7, 0x7c, + 0xb7, 0xc2, 0x52, 0x11, 0x49, 0x73, 0xd2, 0xaf, 0xcf, 0xa7, 0xdf, 0x0d, 0x47, 0xfc, 0xf7, 0x63, + 0xb4, 0x22, 0x49, 0xac, 0xdf, 0xf1, 0x30, 0xf7, 0xd8, 0xef, 0xb5, 0xbe, 0x5b, 0xef, 0x1d, 0xf2, + 0xdf, 0x22, 0x0e, 0xbd, 0x04, 0x53, 0x42, 0xac, 0xf7, 0x7c, 0x6f, 0xd6, 0xf9, 0x6f, 0xb5, 0xbe, + 0x5b, 0xef, 0x5b, 0xe5, 0xbe, 0xf5, 0xbe, 0x5b, 0xe4, 0x7f, 0xda, 0x6a, 0xa8, 0xd3, 0xf0, 0xff, + 0x5b, 0xe5, 0xbe, 0xf5, 0xbe, 0x5b, 0xed, 0x6f, 0x96, 0xf9, 0x3a, 0xf6, 0x8d, 0xbf, 0x8d, 0x8f, + 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc7, 0xfc, 0xbf, 0xde, 0xbf, 0xcb, 0xfd, 0xe4, 0x49, 0x34, + 0x9b, 0xe2, 0x53, 0x42, 0x53, 0x5e, 0x37, 0xc6, 0xbc, 0xab, 0xda, 0xaf, 0x2a, 0xf7, 0x8d, 0x79, + 0x57, 0xbd, 0x57, 0x95, 0x79, 0x32, 0xfc, 0x0e, 0xfc, 0xb0, 0xef, 0xcb, 0xf3, 0x95, 0x7f, 0x1d, + 0x66, 0x81, 0xd6, 0x6b, 0xc3, 0x84, 0x1f, 0xf2, 0xff, 0x6a, 0xa8, 0x44, 0x93, 0x49, 0xbe, 0x25, + 0x34, 0x25, 0x35, 0xe0, 0x82, 0x31, 0xef, 0xf1, 0xaf, 0x2a, 0xd1, 0x8c, 0x7b, 0xa5, 0x5f, 0x9f, + 0x4f, 0xbe, 0x37, 0x8d, 0x79, 0x57, 0xb5, 0x5e, 0x55, 0xef, 0x1a, 0xf2, 0xaf, 0x7a, 0xaf, 0x63, + 0x92, 0x64, 0x9a, 0x69, 0x8b, 0x78, 0x1d, 0xf9, 0x61, 0xdf, 0x97, 0xc4, 0x05, 0x7a, 0xdf, 0x2d, + 0xf6, 0xb7, 0xcb, 0x7c, 0x9d, 0x79, 0xb4, 0xdb, 0xfc, 0xf5, 0xfe, 0x25, 0x34, 0x25, 0x35, 0xe1, + 0x88, 0xff, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, 0xbc, 0x89, 0x26, 0x93, 0x7c, 0x4a, 0x68, 0x4a, 0x6b, + 0xcf, 0x4e, 0xbc, 0xfa, 0x7d, 0xeb, 0x85, 0x23, 0x2d, 0x0a, 0x5a, 0x3d, 0x4b, 0x47, 0xf1, 0xff, + 0x2f, 0xf1, 0x08, 0x43, 0x5f, 0x93, 0x47, 0xe5, 0xa4, 0xe1, 0x78, 0xc5, 0x35, 0x14, 0xd4, 0x53, + 0x51, 0x4d, 0x27, 0xcb, 0x03, 0xd6, 0x0b, 0x03, 0xd6, 0x17, 0x5e, 0xf8, 0xd3, 0x5e, 0xd1, 0xfb, + 0x6f, 0xef, 0xed, 0xb6, 0x7a, 0xed, 0x2a, 0xfe, 0x7d, 0x7d, 0x45, 0xbd, 0xf5, 0xa1, 0xaf, 0x8d, + 0xe9, 0x0d, 0x46, 0xa4, 0x95, 0x75, 0x69, 0x50, 0x98, 0x4f, 0xc3, 0x0a, 0x9c, 0xc7, 0xd6, 0x9a, + 0x7e, 0x36, 0x5c, 0x2e, 0x17, 0x1b, 0x90, 0x76, 0xd6, 0xd6, 0x21, 0x13, 0x59, 0x02, 0x6b, 0x9b, + 0xb3, 0x48, 0x42, 0xc2, 0x18, 0x70, 0x7f, 0xdb, 0xe7, 0x31, 0x73, 0xb0, 0x76, 0x2f, 0xc3, 0xa4, + 0xf5, 0x25, 0x2d, 0x5e, 0x22, 0xdf, 0xdb, 0xb3, 0x8b, 0x7f, 0xe1, 0x5b, 0x35, 0xe4, 0x16, 0x5a, + 0xcf, 0x9a, 0xa9, 0xc6, 0x99, 0x59, 0x2e, 0x7e, 0xde, 0x39, 0xc9, 0x23, 0x55, 0xfc, 0x8b, 0xe1, + 0x88, 0xef, 0x54, 0xa6, 0x35, 0x72, 0xc3, 0x91, 0xf1, 0xf1, 0xdf, 0xeb, 0x69, 0x54, 0x92, 0x5e, + 0x14, 0x39, 0xe8, 0x7a, 0x41, 0x97, 0x27, 0xc3, 0xe3, 0xc8, 0x39, 0xf0, 0xe4, 0x11, 0x1a, 0x75, + 0x1c, 0x82, 0x45, 0x9f, 0x09, 0xe6, 0xc6, 0xa0, 0x3b, 0x46, 0xcf, 0xd7, 0xbe, 0x0a, 0x29, 0x25, + 0xa4, 0x92, 0x49, 0x0f, 0x95, 0x7a, 0x8e, 0xdf, 0x19, 0x69, 0xa6, 0x0d, 0x83, 0x6a, 0xa6, 0x0d, + 0x83, 0x49, 0x2d, 0x24, 0xbf, 0x1a, 0x38, 0x16, 0x2e, 0xe0, 0xc9, 0x64, 0xc3, 0x35, 0xc8, 0x34, + 0x2d, 0x80, 0x2f, 0xf2, 0x0d, 0x2f, 0x1f, 0x9b, 0x9a, 0x39, 0x92, 0x10, 0x1d, 0x65, 0x4e, 0x10, + 0x0b, 0x2d, 0x4a, 0xcc, 0x63, 0x8c, 0xa3, 0x7b, 0x90, 0xec, 0x64, 0x1b, 0x6d, 0x18, 0xff, 0x1e, + 0x91, 0xde, 0x3b, 0x5f, 0x1b, 0xbb, 0x22, 0xcb, 0x19, 0x46, 0x38, 0x15, 0xb6, 0x21, 0x71, 0xc2, + 0xea, 0x1c, 0x29, 0x17, 0xe0, 0x99, 0x43, 0x52, 0xab, 0xdc, 0x81, 0xc0, 0x41, 0x35, 0x5f, 0xe5, + 0xbe, 0x6a, 0xa0, 0x95, 0x3c, 0x60, 0x6b, 0xf9, 0xbe, 0x7f, 0xfc, 0x28, 0x42, 0xcc, 0x3d, 0x64, + 0x25, 0x34, 0xc1, 0x49, 0x59, 0x54, 0xc6, 0xc5, 0x4a, 0x9a, 0x98, 0xf9, 0xce, 0x93, 0x67, 0x2e, + 0xdf, 0xe1, 0xc0, 0xb8, 0xcb, 0x43, 0x48, 0x3c, 0xcd, 0x90, 0xd1, 0x77, 0xff, 0x04, 0x18, 0xff, + 0xbc, 0x7f, 0xdf, 0x31, 0x04, 0x68, 0x82, 0xfc, 0x32, 0x11, 0x6b, 0x2e, 0x97, 0x45, 0x51, 0x6a, + 0xfc, 0x3e, 0x68, 0x92, 0xe9, 0x1b, 0x2a, 0x32, 0xa4, 0xda, 0xf5, 0xa9, 0x03, 0xbc, 0xd3, 0x41, + 0x00, 0x3f, 0x7d, 0x6c, 0x4d, 0x39, 0x77, 0xc1, 0x50, 0x41, 0x26, 0x3a, 0x71, 0xd4, 0xd4, 0x34, + 0xe0, 0xae, 0x8e, 0x6b, 0x50, 0x26, 0x7e, 0x14, 0x12, 0xaf, 0x55, 0xc2, 0xe0, 0xf1, 0x4b, 0x8f, + 0xad, 0xb5, 0x95, 0x79, 0x39, 0x8e, 0x8e, 0xc6, 0xb4, 0x00, 0xf8, 0x20, 0xb5, 0x73, 0xb5, 0x65, + 0x66, 0x49, 0xc1, 0xb2, 0x23, 0x97, 0xdb, 0x6d, 0xb6, 0xfc, 0x3a, 0x29, 0x12, 0xbf, 0x1c, 0xa4, + 0x3e, 0xdd, 0x94, 0xa9, 0x9c, 0x9d, 0x06, 0xec, 0x87, 0xbe, 0x7e, 0x7f, 0xff, 0x85, 0x42, 0xa4, + 0xa8, 0x21, 0x15, 0xf6, 0xd2, 0x13, 0xf9, 0x57, 0x13, 0xec, 0x64, 0xf5, 0x7b, 0xba, 0xe1, 0x53, + 0x8f, 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc8, 0x8e, 0x89, 0xa4, 0xdc, 0xfa, 0xfd, 0xfc, 0x37, + 0xc7, 0x5a, 0x16, 0xb4, 0x19, 0x39, 0x74, 0xbb, 0xef, 0x88, 0x8c, 0xb4, 0x29, 0x68, 0xf5, 0x2d, + 0x0a, 0x5a, 0x3f, 0xc1, 0x05, 0x7f, 0x97, 0xfb, 0xc7, 0xfc, 0xbf, 0xde, 0xbf, 0xcb, 0xfd, 0xe5, + 0x4e, 0x6d, 0x36, 0xff, 0x8c, 0x25, 0x55, 0x75, 0x55, 0xd4, 0xd6, 0xd3, 0x5f, 0x8c, 0xc5, 0x17, + 0x14, 0x5a, 0x49, 0x6d, 0x35, 0xf8, 0xbb, 0x4d, 0x6d, 0x35, 0xf8, 0x54, 0xab, 0xfc, 0xbf, 0xde, + 0xbf, 0xcb, 0xfd, 0xe4, 0x47, 0x44, 0xd2, 0x6e, 0xfd, 0x7e, 0xfe, 0x11, 0x23, 0x4d, 0x6d, 0x35, + 0xb4, 0xd7, 0xe3, 0x2d, 0x35, 0xb5, 0x56, 0xd3, 0x5b, 0x4d, 0x7e, 0x27, 0xd2, 0x4b, 0x49, 0x2f, + 0x1d, 0xab, 0xb7, 0x53, 0x5b, 0x4d, 0x7e, 0x24, 0xa7, 0x81, 0x21, 0x9e, 0x04, 0x87, 0xe3, 0x23, + 0x1e, 0xfe, 0x34, 0xd1, 0x8c, 0x7b, 0xfc, 0x69, 0xa3, 0x7c, 0x10, 0x08, 0x26, 0x13, 0x09, 0x8c, + 0xc2, 0xe1, 0x71, 0x98, 0xcc, 0x6e, 0x37, 0x19, 0x8c, 0xc1, 0xe5, 0x4d, 0x34, 0xd3, 0xff, 0x08, + 0x7c, 0xa4, 0x14, 0x9f, 0x8f, 0xca, 0x9d, 0x86, 0xc6, 0x9f, 0x8f, 0xcf, 0x04, 0x13, 0x10, 0x75, + 0x68, 0xf9, 0x55, 0x4d, 0x1b, 0x0f, 0x95, 0x11, 0x11, 0x31, 0xb1, 0x9c, 0xeb, 0xce, 0xa6, 0x99, + 0x0c, 0xb0, 0xcf, 0x86, 0xcb, 0x9b, 0x29, 0x7f, 0x33, 0x26, 0x31, 0x9f, 0x1b, 0xc6, 0xd6, 0x26, + 0xe3, 0x6b, 0x13, 0x08, 0x3b, 0x1b, 0x06, 0xd2, 0x1e, 0x1b, 0x45, 0x42, 0xf5, 0xfc, 0x42, 0x6b, + 0xc3, 0x19, 0x15, 0x14, 0x97, 0x92, 0x94, 0x8b, 0xd0, 0x4d, 0x31, 0x3a, 0x64, 0xbb, 0xf1, 0x02, + 0x18, 0x30, 0xf3, 0x0e, 0x0c, 0x41, 0x71, 0x0b, 0xb0, 0xda, 0xf2, 0x0a, 0x66, 0x1c, 0x78, 0x2f, + 0xb6, 0x3a, 0xcd, 0xbc, 0xf4, 0x3d, 0x35, 0xf6, 0xa9, 0xaf, 0x82, 0x72, 0xcd, 0x94, 0x0d, 0x3a, + 0x49, 0x37, 0xc3, 0x58, 0xa6, 0xf4, 0xbf, 0x1f, 0x88, 0x7d, 0x13, 0x46, 0xbb, 0xbc, 0x3f, 0x31, + 0x0b, 0x88, 0x47, 0x55, 0xda, 0xed, 0x6e, 0x9b, 0x72, 0x62, 0x5a, 0x51, 0xf6, 0xe3, 0x72, 0xef, + 0xc3, 0xd6, 0x9a, 0xcd, 0xa6, 0xd2, 0xf6, 0x72, 0xf6, 0x10, 0x9b, 0x5d, 0xab, 0xf2, 0x98, 0x94, + 0xc6, 0xfc, 0x14, 0x97, 0x69, 0xad, 0xa6, 0xb9, 0x29, 0x9d, 0xf0, 0xd1, 0x1a, 0x1f, 0x64, 0x5e, + 0xc2, 0x2a, 0x3f, 0x4f, 0xff, 0xc3, 0x84, 0xd5, 0xae, 0x41, 0xa3, 0x77, 0x43, 0x41, 0x14, 0xd3, + 0x5b, 0xe1, 0x12, 0xc8, 0x41, 0x94, 0x82, 0x62, 0x0d, 0xc4, 0x19, 0x88, 0x3c, 0xc4, 0x1f, 0x1b, + 0x60, 0xd8, 0x37, 0x10, 0x5c, 0x41, 0x39, 0x04, 0xe4, 0x17, 0x90, 0x5e, 0x41, 0x6a, 0xaf, 0x41, + 0xd0, 0x67, 0x24, 0xf2, 0x5f, 0x2d, 0xb6, 0xdb, 0x7f, 0xe3, 0x6d, 0x1c, 0x83, 0x53, 0xc8, 0x36, + 0x9a, 0x6a, 0x4c, 0x2e, 0x45, 0x97, 0x25, 0xc1, 0xf1, 0xe5, 0x34, 0xd3, 0x4d, 0xb6, 0xdb, 0x6f, + 0xc6, 0x7b, 0x4d, 0x6d, 0x34, 0xdc, 0x6e, 0x37, 0x1b, 0x94, 0x1b, 0x06, 0xf2, 0x0b, 0xc8, 0x3e, + 0x28, 0xb8, 0xef, 0xa2, 0xe9, 0x25, 0xe1, 0x19, 0xb5, 0xa4, 0xed, 0x35, 0xb4, 0xd7, 0xe3, 0x25, + 0x24, 0x52, 0x4c, 0xe0, 0x3e, 0x6b, 0x4b, 0x49, 0x2d, 0x24, 0xbc, 0x4f, 0x69, 0xad, 0xa6, 0xb1, + 0x22, 0x55, 0x3a, 0xe2, 0x42, 0xa6, 0x53, 0xbc, 0xc4, 0x12, 0xff, 0x03, 0x2f, 0x88, 0x4e, 0xea, + 0xf0, 0x34, 0xea, 0xa3, 0xde, 0xb4, 0xe8, 0xff, 0x85, 0x45, 0x59, 0x4a, 0x46, 0x14, 0x30, 0x49, + 0xd4, 0x0e, 0x6d, 0x0f, 0x5c, 0x3f, 0xfa, 0xaf, 0xe6, 0xc1, 0x1d, 0x23, 0x51, 0x8e, 0x34, 0x5e, + 0x34, 0x91, 0x51, 0xa7, 0x4a, 0xb5, 0xbc, 0x3d, 0x31, 0x95, 0xe5, 0x21, 0x55, 0xa5, 0x4a, 0xfb, + 0x92, 0x0e, 0xef, 0xe1, 0x10, 0xae, 0xd3, 0x5b, 0x58, 0x6b, 0x69, 0xa8, 0x71, 0x42, 0x67, 0xa4, + 0x7d, 0x6f, 0xef, 0x2c, 0x0f, 0xa7, 0xde, 0x7d, 0x7e, 0xf5, 0x26, 0xb2, 0xf9, 0xa1, 0xf8, 0x20, + 0x1c, 0x0f, 0x98, 0x64, 0xe8, 0x35, 0x39, 0x9a, 0x1b, 0x18, 0xdb, 0xce, 0xa0, 0x7b, 0x44, 0x77, + 0xfc, 0x57, 0x15, 0xf8, 0xd3, 0x47, 0xcf, 0x23, 0xa6, 0x75, 0x3e, 0x30, 0xab, 0x34, 0x7d, 0x1b, + 0x9e, 0x5f, 0x14, 0xa5, 0xdd, 0xdf, 0xfc, 0x26, 0x58, 0xcf, 0xbb, 0x4c, 0x0c, 0x72, 0x18, 0xe9, + 0x4c, 0x39, 0x6d, 0xdf, 0x0a, 0x1a, 0xc3, 0x72, 0x86, 0x02, 0x53, 0x2e, 0x34, 0xbc, 0x77, 0xf8, + 0x6f, 0x34, 0x47, 0xf5, 0x2a, 0xae, 0x4e, 0xfc, 0x22, 0x17, 0x07, 0xc4, 0x48, 0x42, 0x81, 0xe2, + 0x3f, 0x12, 0x5a, 0x49, 0x62, 0x66, 0xed, 0x35, 0xe2, 0xed, 0x35, 0xb4, 0xd6, 0x5e, 0x0b, 0xad, + 0x35, 0xc3, 0xf9, 0x6f, 0x5f, 0x1a, 0x29, 0xa6, 0x9a, 0x6b, 0x1f, 0xf2, 0xff, 0x48, 0xf4, 0xc9, + 0x61, 0x2c, 0xa3, 0x29, 0x55, 0x50, 0x58, 0x4b, 0x14, 0x62, 0x17, 0xff, 0x1b, 0xd6, 0xb8, 0x28, + 0x32, 0x55, 0x28, 0x9d, 0x47, 0x94, 0x7b, 0xd4, 0x79, 0x47, 0xbe, 0x17, 0xee, 0xee, 0xfe, 0x0b, + 0x2e, 0xea, 0xbd, 0x34, 0xda, 0xc6, 0x94, 0xf7, 0xc1, 0x18, 0xb4, 0xb1, 0x24, 0x01, 0xdf, 0x09, + 0x74, 0x92, 0xda, 0x6b, 0xc6, 0x5a, 0x69, 0x24, 0x9a, 0x69, 0x2b, 0x4d, 0x24, 0xcd, 0x03, 0x35, + 0x10, 0x3f, 0xc2, 0x36, 0x9a, 0xda, 0x6b, 0x69, 0xaf, 0xc4, 0xf4, 0x92, 0xd2, 0x4b, 0xc2, 0x36, + 0x9a, 0xda, 0x6b, 0x69, 0xae, 0x1c, 0x53, 0x10, 0x72, 0xe9, 0x77, 0x6c, 0xbb, 0xcb, 0xa5, 0xdc, + 0xba, 0x5d, 0x2a, 0x1c, 0x03, 0xcd, 0xa6, 0xdf, 0xf1, 0x05, 0x19, 0x68, 0x42, 0xcb, 0x7e, 0x7f, + 0x2f, 0xf7, 0x93, 0x8a, 0x10, 0x6c, 0x76, 0x1f, 0x1f, 0x87, 0xab, 0xea, 0x6f, 0xf8, 0x76, 0xad, + 0x61, 0x42, 0x1a, 0x5e, 0xa3, 0x5d, 0x74, 0xcb, 0xfb, 0xbb, 0xfa, 0x47, 0xea, 0xcc, 0x36, 0x4f, + 0x87, 0x79, 0x88, 0x26, 0x20, 0xa1, 0x1d, 0xad, 0x54, 0xd6, 0xb5, 0x56, 0x0a, 0x63, 0xbf, 0xdb, + 0x2d, 0x2b, 0xf0, 0xa9, 0x5a, 0x43, 0xa8, 0xfe, 0xe8, 0x18, 0x4c, 0xe9, 0xf9, 0xd0, 0xa0, 0x37, + 0x6f, 0xff, 0x34, 0x65, 0x62, 0xfe, 0x2a, 0x25, 0xc0, 0xe8, 0x2a, 0xc2, 0x8c, 0xb1, 0xa4, 0x97, + 0xe0, 0x87, 0x53, 0x49, 0x24, 0x8f, 0xbe, 0x08, 0x64, 0x3e, 0xc9, 0x1a, 0x48, 0xb7, 0xe0, 0xab, + 0xa4, 0x95, 0x10, 0x65, 0x85, 0x2a, 0xf1, 0xdf, 0x26, 0x5e, 0x1f, 0x24, 0x07, 0x2f, 0x27, 0x5d, + 0xd8, 0x7d, 0x27, 0x2f, 0x67, 0x6f, 0x41, 0xb5, 0x53, 0x5b, 0x97, 0xbd, 0xae, 0x72, 0xa9, 0x9c, + 0xd7, 0x11, 0xcf, 0x77, 0xf8, 0x58, 0xc6, 0x21, 0x31, 0x09, 0x88, 0x5c, 0x42, 0xd4, 0x2b, 0x2d, + 0x9a, 0x97, 0xff, 0xe5, 0x2e, 0x30, 0xbf, 0x88, 0xed, 0x35, 0xb4, 0x7c, 0xf0, 0xf9, 0x41, 0xd7, + 0x41, 0xd7, 0x4e, 0x0e, 0xba, 0x03, 0xae, 0x98, 0x3a, 0xe8, 0x0e, 0xba, 0x64, 0x49, 0x34, 0x9b, + 0xff, 0x84, 0xf8, 0x3a, 0xe8, 0x0e, 0xf4, 0xc1, 0xd7, 0x40, 0x75, 0xd3, 0xc1, 0x47, 0x19, 0x68, + 0x52, 0xd1, 0xa9, 0x68, 0x52, 0xd0, 0x25, 0xa7, 0xc6, 0xc1, 0xd7, 0x41, 0xd7, 0x4c, 0x75, 0xd0, + 0x75, 0xd3, 0x07, 0x5d, 0x01, 0xd7, 0x4e, 0x0e, 0xba, 0x03, 0xae, 0x99, 0x12, 0x4d, 0x26, 0xff, + 0xc4, 0x02, 0xcf, 0x1a, 0x68, 0xc7, 0x7c, 0xb7, 0xdd, 0x6f, 0x96, 0xf8, 0x4b, 0x4f, 0x10, 0x08, + 0x23, 0x1e, 0x51, 0xef, 0xd5, 0x78, 0x9e, 0xa0, 0xeb, 0xa0, 0x96, 0x99, 0xb0, 0x4e, 0x9b, 0x31, + 0x3d, 0xab, 0xfc, 0x16, 0x0a, 0x90, 0x93, 0x12, 0xac, 0x0f, 0x76, 0xe7, 0x8c, 0x0e, 0x13, 0x8c, + 0x5c, 0x6a, 0x2f, 0xbe, 0x17, 0x10, 0xd8, 0x66, 0xf4, 0x46, 0x65, 0x76, 0xbf, 0xdd, 0x64, 0x41, + 0x1f, 0xf1, 0x5b, 0xbb, 0xf8, 0x2a, 0xef, 0x52, 0xbd, 0xca, 0xdd, 0x5d, 0x43, 0x26, 0x59, 0x96, + 0x18, 0x37, 0xbb, 0x0d, 0x31, 0xf0, 0xfd, 0x07, 0x43, 0x94, 0x11, 0x17, 0x0d, 0x18, 0xa9, 0x89, + 0x4d, 0xcb, 0x96, 0x16, 0x2f, 0xc5, 0x46, 0x54, 0xef, 0x8a, 0x43, 0xce, 0x4d, 0xa6, 0xdc, 0xdc, + 0x1d, 0xf8, 0xb7, 0xf8, 0xde, 0x3f, 0xbe, 0xdb, 0x43, 0x5f, 0x4d, 0x1b, 0x98, 0x73, 0x1a, 0x36, + 0x6d, 0xe9, 0x69, 0x32, 0xd1, 0xf5, 0xba, 0xd3, 0x4d, 0x34, 0xfc, 0x3e, 0x42, 0x33, 0x55, 0x30, + 0x63, 0x44, 0x13, 0xd4, 0xa5, 0x61, 0x2b, 0x36, 0xdb, 0x39, 0x7c, 0x1d, 0xfe, 0xce, 0x9f, 0x85, + 0x0e, 0x68, 0xa9, 0x9b, 0xd5, 0x11, 0x5a, 0x92, 0xd4, 0xd3, 0x41, 0xd4, 0x63, 0xdb, 0x07, 0x95, + 0x5c, 0xee, 0xba, 0x19, 0xca, 0x47, 0x77, 0xc7, 0x08, 0x76, 0x1d, 0x18, 0x45, 0x8a, 0xfc, 0x5d, + 0x16, 0xf7, 0x3f, 0x32, 0xf4, 0x5a, 0x9d, 0x74, 0xff, 0x16, 0x19, 0xc1, 0xd7, 0x40, 0x75, 0xd3, + 0x07, 0x5d, 0x01, 0xd7, 0x4f, 0x0a, 0xe3, 0xfe, 0xeb, 0xfd, 0xf4, 0xab, 0xf3, 0x69, 0xb7, 0xc3, + 0x1c, 0x75, 0xa1, 0x6b, 0x46, 0xb5, 0xa1, 0x6b, 0x41, 0x93, 0x97, 0x4b, 0xbf, 0xe1, 0xf8, 0x3a, + 0xe8, 0x0e, 0xba, 0x60, 0xeb, 0xa0, 0x3a, 0xe9, 0xc1, 0xd7, 0x40, 0x75, 0xd3, 0x22, 0x49, 0xa4, + 0xdf, 0xfe, 0x79, 0x53, 0x9b, 0x4d, 0xbf, 0xe3, 0x88, 0xd3, 0x5b, 0x4d, 0x6d, 0x35, 0xf8, 0x28, + 0x31, 0xc8, 0x4e, 0x42, 0x72, 0x17, 0x90, 0x93, 0x09, 0x8e, 0xb7, 0x5d, 0x7c, 0x6f, 0x96, 0x9b, + 0xbe, 0x52, 0x45, 0x24, 0xf6, 0x92, 0x29, 0x2e, 0x3b, 0x4e, 0x43, 0x22, 0x26, 0x5b, 0x6d, 0xb6, + 0xfc, 0x16, 0x5a, 0x1d, 0x8d, 0xb8, 0xac, 0x6e, 0xc9, 0x88, 0x2f, 0x20, 0xba, 0xf5, 0x8f, 0x0f, + 0xab, 0x83, 0x03, 0xf3, 0x28, 0x4e, 0x4d, 0x48, 0x84, 0x75, 0x89, 0x58, 0x45, 0x7f, 0xe0, 0x82, + 0xd3, 0xaa, 0x4e, 0xea, 0xe3, 0xbe, 0x8b, 0x49, 0x2a, 0xa6, 0x9a, 0x49, 0xff, 0x84, 0x08, 0xcf, + 0x1c, 0x65, 0xe7, 0x2b, 0x45, 0x44, 0x72, 0xa7, 0xbe, 0x5b, 0xf0, 0x54, 0x53, 0xe7, 0xb4, 0xd6, + 0xd3, 0x58, 0xbd, 0xb0, 0xe6, 0x03, 0x1b, 0xe7, 0xa0, 0xfa, 0xfd, 0xeb, 0x6d, 0xb6, 0xcf, 0xa7, + 0xdd, 0xfa, 0xfd, 0xc0, 0xe3, 0x69, 0x34, 0x9a, 0xff, 0xf8, 0x8e, 0x7a, 0x1e, 0x99, 0xe8, 0x7a, + 0x78, 0x7c, 0xa0, 0xeb, 0xa0, 0xeb, 0xa7, 0x07, 0x5d, 0x01, 0xd7, 0x4c, 0x1d, 0x74, 0x07, 0x5d, + 0x32, 0x24, 0x9a, 0x4d, 0xff, 0xc4, 0x46, 0x5a, 0x14, 0xb4, 0x7a, 0x96, 0x85, 0x2d, 0x1f, 0xe1, + 0x58, 0xeb, 0xa0, 0xeb, 0xa6, 0x3a, 0xe8, 0x3a, 0xe9, 0x91, 0x24, 0xd6, 0x6f, 0xfe, 0x72, 0x99, + 0x39, 0x74, 0xbb, 0xef, 0xb1, 0x18, 0xc2, 0xeb, 0x86, 0x3a, 0x49, 0x09, 0x73, 0x53, 0x4f, 0xf6, + 0xdb, 0x6d, 0xbf, 0x47, 0x63, 0xe1, 0xe8, 0xc7, 0x8c, 0x14, 0x8d, 0x55, 0x31, 0xda, 0x6b, 0x69, + 0x5b, 0x4a, 0xda, 0x11, 0x0e, 0xc9, 0xa4, 0xdd, 0xa0, 0x63, 0xe4, 0x6d, 0x64, 0x7c, 0x3f, 0x51, + 0x4d, 0x45, 0x35, 0x14, 0xd4, 0x53, 0x18, 0xa6, 0x63, 0x48, 0x55, 0xe4, 0x77, 0xee, 0xd3, 0x6a, + 0xc9, 0x6e, 0x35, 0xe8, 0x88, 0xe9, 0xf1, 0x16, 0x9a, 0xda, 0x6b, 0xf3, 0x95, 0x10, 0xeb, 0xca, + 0x68, 0xa6, 0x85, 0x59, 0x6b, 0x7c, 0x16, 0x1a, 0x81, 0xba, 0xe3, 0x48, 0x9b, 0x4c, 0x61, 0xff, + 0xd7, 0x73, 0xe0, 0xc3, 0xa6, 0xd1, 0xb7, 0x49, 0x2d, 0x55, 0xd5, 0xff, 0xcf, 0x57, 0x71, 0x2b, + 0x17, 0xfe, 0x27, 0x6e, 0xdd, 0xbb, 0x7e, 0x14, 0xd8, 0x8e, 0xa1, 0x6a, 0x76, 0xd2, 0x4d, 0x60, + 0x48, 0x19, 0xa8, 0xba, 0x5b, 0x76, 0x36, 0x95, 0x30, 0x99, 0xfa, 0x28, 0x8b, 0x4f, 0x82, 0x88, + 0xcb, 0x42, 0x96, 0x8f, 0x52, 0xd0, 0xa5, 0xa3, 0xc8, 0x9f, 0x17, 0xe0, 0xeb, 0xa0, 0x3a, 0xe9, + 0x83, 0xae, 0x80, 0xeb, 0xa7, 0xa8, 0x8b, 0x4f, 0x86, 0x3c, 0x77, 0xd8, 0xeb, 0xa0, 0x3a, 0xe8, + 0x44, 0x93, 0x49, 0xbf, 0xf1, 0x21, 0x58, 0xcb, 0x42, 0x96, 0x85, 0xfe, 0x5f, 0xe5, 0x2d, 0x0a, + 0x5a, 0x17, 0xf9, 0x7f, 0x84, 0x5a, 0x3a, 0x26, 0x93, 0x73, 0xe9, 0xf7, 0xe2, 0x42, 0x9f, 0x5f, + 0xe5, 0xfe, 0xf5, 0xfe, 0x5f, 0xe5, 0x1e, 0x51, 0xe5, 0xfe, 0x5f, 0xe5, 0x1e, 0x51, 0xe5, 0xfe, + 0x5f, 0xe1, 0x04, 0xd3, 0xe0, 0xa8, 0xdf, 0x12, 0x47, 0x21, 0x7e, 0xd6, 0xe1, 0x8a, 0x36, 0x8c, + 0x2d, 0xc0, 0x85, 0x4d, 0xf0, 0xe8, 0xaf, 0x23, 0x9b, 0x65, 0x33, 0x09, 0xaf, 0x18, 0x88, 0x77, + 0x56, 0x1f, 0x7d, 0xcf, 0x4e, 0xe2, 0xaf, 0xfc, 0x29, 0x8f, 0x58, 0x1c, 0x4c, 0x33, 0xbe, 0xaa, + 0xf2, 0xea, 0x2d, 0xe8, 0x32, 0xe1, 0x54, 0x39, 0x77, 0xb1, 0x06, 0xff, 0x04, 0xb7, 0xdf, 0x68, + 0x21, 0xc4, 0x56, 0xf2, 0xc9, 0xc7, 0x77, 0xc3, 0xb4, 0x58, 0x9d, 0x9c, 0xca, 0xa6, 0x6b, 0xa9, + 0x51, 0x86, 0x0a, 0x34, 0x4a, 0x12, 0x89, 0xdf, 0x4c, 0x5b, 0x27, 0xe9, 0x93, 0xc7, 0xe3, 0x4a, + 0xd8, 0x21, 0xe9, 0x34, 0x39, 0x70, 0x64, 0xc2, 0xf3, 0xda, 0xa2, 0xbb, 0x92, 0xb1, 0x86, 0x13, + 0xd3, 0xa0, 0x77, 0x33, 0x42, 0x49, 0x24, 0xd3, 0x4d, 0x3f, 0x1b, 0x4c, 0x93, 0x4b, 0x8d, 0xf4, + 0xa1, 0x39, 0x1d, 0xb0, 0x55, 0x4c, 0x62, 0x36, 0xbc, 0xf7, 0x3b, 0x5e, 0x66, 0x1a, 0x94, 0xc2, + 0xfc, 0x69, 0xa6, 0x9f, 0x84, 0x46, 0x63, 0x23, 0xa2, 0x32, 0x36, 0x71, 0x8c, 0xe6, 0x96, 0xb9, + 0x15, 0x7c, 0x60, 0x55, 0xb5, 0x1a, 0xa3, 0x07, 0xd4, 0xd6, 0x99, 0x48, 0x32, 0x90, 0xb4, 0xd7, + 0xf1, 0x9a, 0xaa, 0xea, 0xab, 0x69, 0xad, 0xa6, 0xbf, 0x39, 0x4a, 0x8c, 0xb3, 0x69, 0xb7, 0x2e, + 0x97, 0x61, 0xcd, 0x28, 0xcb, 0x3f, 0x5f, 0xa6, 0xd7, 0x6b, 0xf5, 0xfa, 0xed, 0x76, 0x9f, 0x5f, + 0xbb, 0xf5, 0xfb, 0x88, 0xb4, 0x93, 0x59, 0xbf, 0xe1, 0x85, 0x0c, 0x65, 0x93, 0x26, 0xf2, 0x69, + 0x37, 0xff, 0x1c, 0x00, 0x6c, 0x38, 0xa1, 0xf6, 0x58, 0xfa, 0x7d, 0xcf, 0xa7, 0xdf, 0xfc, 0x89, + 0x26, 0xb3, 0x7f, 0xf0, 0x5a, 0x21, 0xa6, 0x0e, 0xd4, 0xf4, 0xf0, 0xf8, 0x2a, 0x3d, 0x06, 0xfa, + 0x2f, 0xa7, 0x4d, 0x32, 0x74, 0xe3, 0x20, 0xbe, 0x15, 0xd7, 0x8f, 0xd1, 0x6f, 0x9b, 0xd7, 0xd3, + 0x17, 0x5f, 0xab, 0x66, 0xfe, 0x1d, 0xb5, 0x56, 0xed, 0xf1, 0xaa, 0x71, 0xc0, 0x1a, 0x4d, 0x25, + 0x7f, 0x7c, 0x12, 0xea, 0x6b, 0x69, 0xaf, 0x2f, 0x82, 0x0a, 0x79, 0x35, 0x21, 0x0f, 0xcf, 0x41, + 0x0f, 0xf8, 0xe3, 0x4d, 0xdb, 0x6d, 0xbf, 0xf5, 0xd2, 0xbf, 0x0a, 0xf6, 0x9a, 0xda, 0x68, 0x76, + 0xfb, 0x6d, 0x9c, 0xfb, 0x77, 0xcf, 0x88, 0xec, 0x1d, 0xb4, 0x1d, 0xb5, 0xba, 0xfd, 0xf1, 0x85, + 0x9a, 0x05, 0x87, 0x9a, 0x19, 0x61, 0xe6, 0x81, 0x61, 0x9f, 0x9e, 0x44, 0x93, 0x49, 0xbf, 0xf8, + 0x88, 0xff, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, 0xbf, 0xc3, 0x11, 0x8f, 0x28, 0xf7, 0xa8, 0xf2, 0x8f, + 0x79, 0x12, 0x4d, 0x26, 0xff, 0xf3, 0xd2, 0x2f, 0x26, 0x93, 0x75, 0xc3, 0x11, 0x8f, 0x28, 0xf7, + 0xa8, 0xf2, 0x8f, 0x79, 0x12, 0x4d, 0x26, 0xff, 0xe0, 0x83, 0x83, 0xae, 0x80, 0xeb, 0xa7, 0x44, + 0x35, 0xec, 0x75, 0xd0, 0x1d, 0x74, 0x4c, 0xbf, 0x2e, 0x97, 0x57, 0x0e, 0xc6, 0x29, 0xf1, 0x8a, + 0x6a, 0x29, 0xe0, 0xeb, 0xa0, 0x3a, 0xe8, 0xe7, 0xcf, 0x09, 0x74, 0xbb, 0xe1, 0x78, 0x3a, 0xe8, + 0x3a, 0xe9, 0xc6, 0xa9, 0x55, 0x43, 0x44, 0x71, 0x96, 0x12, 0xc0, 0x86, 0x89, 0x99, 0xa1, 0xe3, + 0x4c, 0xd3, 0x58, 0xfa, 0xac, 0x48, 0x8b, 0x5c, 0xb5, 0x45, 0x1f, 0xf5, 0x5f, 0xdf, 0x93, 0xa7, + 0x3f, 0x0b, 0x74, 0xda, 0x33, 0x3b, 0x4d, 0x37, 0xd5, 0x55, 0x7d, 0x62, 0xf8, 0x42, 0x2f, 0xcd, + 0x87, 0xc3, 0x46, 0x83, 0x68, 0x0e, 0xfa, 0x41, 0x88, 0x2c, 0xdf, 0x0c, 0x17, 0x83, 0xae, 0x80, + 0xeb, 0xa6, 0x0e, 0xba, 0x03, 0xae, 0x84, 0x49, 0x34, 0x9b, 0xff, 0x8c, 0x23, 0x55, 0x24, 0x95, + 0x4f, 0xc4, 0xa5, 0x83, 0x60, 0xe2, 0x2e, 0xed, 0x35, 0xe1, 0x4b, 0x53, 0x90, 0x4e, 0x41, 0xce, + 0x41, 0x0f, 0x30, 0xe6, 0x6c, 0x36, 0x54, 0xfb, 0xea, 0x52, 0xa7, 0xc1, 0x6d, 0xaa, 0xb6, 0x9a, + 0xce, 0x97, 0xc1, 0x68, 0xad, 0xdf, 0x77, 0x32, 0x1e, 0xf8, 0xc3, 0x69, 0xa7, 0x53, 0xbe, 0x98, + 0xad, 0x23, 0x90, 0x60, 0xa2, 0x0f, 0x29, 0xb1, 0xf4, 0xce, 0xcb, 0x78, 0x50, 0xa1, 0x4b, 0x64, + 0xa1, 0xae, 0x1d, 0xc6, 0xe3, 0x17, 0xaa, 0x07, 0x8d, 0x22, 0x93, 0xb6, 0x96, 0x66, 0x07, 0x50, + 0x31, 0xf0, 0x41, 0x3c, 0x03, 0x3b, 0xa1, 0x3d, 0xcd, 0x3d, 0x96, 0x55, 0x25, 0xca, 0xd9, 0x77, + 0x2f, 0x6f, 0xff, 0x0e, 0xdd, 0x09, 0xde, 0xdc, 0xac, 0x8d, 0xba, 0xb7, 0x28, 0x17, 0xa2, 0xa5, + 0xb3, 0xff, 0xc1, 0x04, 0xba, 0xa5, 0xd8, 0x8f, 0xf4, 0xda, 0x66, 0x31, 0x1c, 0xc8, 0xb1, 0x4d, + 0x34, 0xd3, 0xff, 0x05, 0x67, 0x62, 0x43, 0x19, 0xb6, 0x37, 0xa8, 0x61, 0x8e, 0x87, 0x39, 0x0b, + 0x14, 0x80, 0xb3, 0x1f, 0x18, 0x31, 0x0d, 0x06, 0x78, 0xe8, 0xc9, 0x05, 0x4a, 0x43, 0x17, 0xc2, + 0xb1, 0x63, 0xd2, 0x0d, 0xa4, 0xd3, 0xd3, 0xa2, 0x43, 0xf1, 0x62, 0xc7, 0x0e, 0x2d, 0x64, 0xc8, + 0xde, 0x36, 0x0c, 0x04, 0x57, 0xfe, 0x09, 0xc6, 0xe3, 0x14, 0xd6, 0x35, 0x5a, 0xd1, 0xe4, 0x4f, + 0x82, 0x0f, 0x1a, 0xa0, 0xeb, 0xa0, 0x3a, 0xe9, 0x83, 0xae, 0x87, 0xb4, 0xe2, 0x93, 0x59, 0xbf, + 0xf8, 0x29, 0x27, 0x12, 0x5a, 0x49, 0x72, 0x92, 0x36, 0x15, 0x3e, 0x1a, 0x21, 0xb0, 0xd9, 0xaa, + 0xb2, 0x37, 0xfd, 0x70, 0xb6, 0xc9, 0x83, 0x3e, 0xcd, 0x88, 0x1b, 0xf0, 0xed, 0x71, 0x8d, 0x5b, + 0xff, 0xc4, 0x96, 0xdd, 0xbb, 0x76, 0xfc, 0x3c, 0x58, 0x3d, 0xb1, 0xc1, 0xd6, 0xc4, 0x1d, 0x6c, + 0x41, 0xd6, 0xc4, 0x1d, 0x6c, 0x26, 0x7f, 0x33, 0xcb, 0xb4, 0x7e, 0x15, 0x83, 0xad, 0x88, 0xeb, + 0x62, 0x0e, 0xb6, 0x20, 0xeb, 0x62, 0x97, 0xf3, 0x3e, 0x67, 0xf8, 0x2f, 0xc1, 0xd6, 0xc0, 0x3a, + 0xe8, 0xf7, 0x60, 0xeb, 0xa0, 0x3a, 0xe8, 0x8b, 0xbf, 0x2c, 0x0b, 0xbf, 0xa8, 0x14, 0xe0, 0x37, + 0xc1, 0x49, 0x29, 0xd3, 0xe3, 0xbe, 0xd2, 0x1d, 0xf3, 0x5f, 0x5a, 0xc7, 0x93, 0x04, 0x80, 0x62, + 0x02, 0xea, 0xde, 0x7d, 0x3e, 0x89, 0x4c, 0x9e, 0x99, 0xf3, 0xdb, 0xed, 0xb7, 0x5b, 0x7e, 0x73, + 0xa2, 0x2d, 0x78, 0xb6, 0x2d, 0xfe, 0x17, 0x8f, 0xf9, 0x7f, 0xbc, 0x6b, 0xca, 0xbd, 0xe2, 0x52, + 0x3a, 0x15, 0x08, 0x54, 0x2f, 0xfc, 0x70, 0x8e, 0xd0, 0xf2, 0x9b, 0x0d, 0x90, 0x1c, 0x6f, 0xc7, + 0xe2, 0x07, 0xf8, 0x62, 0x18, 0xca, 0x61, 0x28, 0xf4, 0xe9, 0xc7, 0x7d, 0x34, 0x10, 0x2f, 0xe8, + 0x24, 0x79, 0xb6, 0xd3, 0x4c, 0x9c, 0x30, 0x27, 0x1d, 0xf2, 0xdf, 0x6b, 0x7c, 0xb7, 0xc9, 0x97, + 0xe5, 0xd2, 0xef, 0x85, 0xe3, 0x14, 0xfe, 0x1c, 0xc7, 0x2b, 0xfc, 0x02, 0xd0, 0xb3, 0x12, 0x5a, + 0x17, 0xff, 0x09, 0x13, 0x49, 0x2e, 0x24, 0xbc, 0x12, 0xf4, 0x92, 0xd2, 0x1d, 0xf3, 0x7c, 0x6c, + 0x84, 0xb1, 0xd2, 0x4b, 0x49, 0x2d, 0x24, 0xb6, 0xfd, 0x84, 0x43, 0x27, 0x4c, 0xf1, 0x22, 0xb4, + 0xe9, 0xb4, 0x3f, 0xef, 0xe1, 0x62, 0x8c, 0x53, 0x51, 0x4d, 0x45, 0x35, 0x14, 0xd3, 0x2f, 0xcb, + 0xa5, 0xdf, 0x64, 0xad, 0xa7, 0xf3, 0x9d, 0x03, 0xaf, 0xf1, 0x8e, 0xf1, 0x8e, 0xf1, 0x44, 0x07, + 0x5b, 0x10, 0x75, 0xb1, 0x07, 0x5b, 0x14, 0x7f, 0x1b, 0xe3, 0x54, 0x07, 0x5d, 0x20, 0xff, 0x8d, + 0x50, 0x1d, 0x74, 0x43, 0xe8, 0x08, 0xfd, 0x28, 0xa9, 0x78, 0x56, 0x77, 0x03, 0xae, 0x80, 0xeb, + 0x63, 0x07, 0x5d, 0x01, 0xd7, 0x4c, 0xe6, 0x7c, 0x92, 0xe6, 0x7f, 0x8e, 0x27, 0x69, 0xad, 0xa6, + 0xb8, 0xd7, 0xbc, 0x16, 0xe7, 0x2a, 0x72, 0xb8, 0x51, 0x5f, 0x95, 0x67, 0xc1, 0x04, 0xe5, 0x71, + 0xb7, 0x43, 0x4a, 0xe9, 0x25, 0xd2, 0x48, 0xc8, 0xc8, 0x87, 0x65, 0x7a, 0x1f, 0xf8, 0x29, 0x26, + 0x42, 0x24, 0x23, 0x94, 0x82, 0x52, 0x09, 0x71, 0xb8, 0xcc, 0x66, 0x65, 0xf0, 0xaf, 0x2e, 0x17, + 0x10, 0x9e, 0xaa, 0x90, 0xc8, 0x6b, 0x50, 0x6f, 0x3f, 0xe1, 0xda, 0xf5, 0xfa, 0x45, 0xc9, 0x30, + 0x9b, 0x8c, 0x28, 0xe0, 0xd8, 0x44, 0xd6, 0xeb, 0xff, 0x0a, 0x97, 0x49, 0x20, 0xc0, 0xc3, 0x82, + 0xc6, 0x4e, 0x28, 0x45, 0x8c, 0x10, 0xa0, 0x0d, 0x4c, 0xd1, 0x49, 0xd1, 0xff, 0x09, 0x97, 0x07, + 0x5d, 0x01, 0xd7, 0x4c, 0x1d, 0x74, 0x07, 0x5d, 0x3c, 0xf1, 0x2d, 0x38, 0xaa, 0x15, 0x5f, 0xe1, + 0x70, 0x85, 0xee, 0x9b, 0x69, 0xb6, 0xbe, 0xee, 0xef, 0xe3, 0x49, 0x10, 0x79, 0xdd, 0x15, 0x63, + 0xd4, 0xbd, 0x0e, 0x18, 0xfe, 0x8d, 0xa4, 0x11, 0x0d, 0xa7, 0x8b, 0xc6, 0x53, 0x71, 0xc4, 0x67, + 0x72, 0x06, 0x3c, 0x4e, 0xfb, 0x10, 0xa1, 0x55, 0x6d, 0x98, 0x44, 0x6f, 0x8f, 0x91, 0x1b, 0x5c, + 0x35, 0x35, 0x7c, 0x6f, 0x36, 0xd1, 0xa4, 0x56, 0xfd, 0x13, 0x6c, 0xad, 0x50, 0xaf, 0xee, 0x44, + 0x4f, 0x99, 0x2d, 0x4a, 0x3b, 0x72, 0x0c, 0xcf, 0x1e, 0xe1, 0xaa, 0xad, 0xc8, 0x5a, 0xa1, 0x17, + 0xff, 0x8c, 0x94, 0xf1, 0xb6, 0x3b, 0x74, 0xb9, 0x63, 0x4c, 0x77, 0x26, 0xa1, 0x70, 0x60, 0xe5, + 0x95, 0xf5, 0x55, 0xed, 0xdf, 0xfc, 0x6f, 0x74, 0x93, 0x52, 0x67, 0x64, 0x57, 0xd2, 0x21, 0x33, + 0xcc, 0x42, 0xd6, 0x38, 0x95, 0xf5, 0x55, 0x5d, 0xf2, 0xbf, 0xe3, 0x72, 0x47, 0xcc, 0xe6, 0xf4, + 0x81, 0x4f, 0x52, 0xa0, 0xad, 0xb3, 0x19, 0x21, 0xbc, 0x83, 0xc7, 0x3e, 0xdd, 0x35, 0xf0, 0xa1, + 0xf0, 0xc3, 0x4c, 0xe4, 0xb1, 0xca, 0x93, 0x6d, 0xe8, 0xa5, 0x1f, 0x86, 0xc5, 0xee, 0x51, 0x8a, + 0xba, 0xc6, 0xce, 0x93, 0x3e, 0x32, 0x81, 0xad, 0x7a, 0x1a, 0x19, 0xc5, 0x46, 0xac, 0x27, 0xa5, + 0x11, 0x0c, 0x4e, 0x1b, 0xc0, 0x69, 0xf0, 0x91, 0xfe, 0x4c, 0xf0, 0x80, 0x8d, 0xba, 0xa1, 0x1d, + 0x12, 0xd6, 0xe9, 0xdb, 0x09, 0xd9, 0x64, 0x61, 0x12, 0xe7, 0x0a, 0x8d, 0xd6, 0x11, 0x60, 0xc2, + 0x6c, 0x3f, 0xc3, 0x3a, 0x92, 0x1c, 0x11, 0xc5, 0x96, 0x6c, 0x07, 0xef, 0x8c, 0xa5, 0x16, 0x92, + 0x5b, 0x4d, 0x6d, 0x34, 0x6d, 0xfc, 0x47, 0x49, 0x29, 0xf4, 0x66, 0x73, 0xf3, 0x9d, 0x7f, 0x27, + 0x38, 0x5f, 0xc5, 0x9b, 0x32, 0x86, 0xc9, 0xfb, 0x7e, 0x20, 0xe3, 0xbe, 0x5b, 0xef, 0x5b, 0xe5, + 0xbe, 0xf5, 0xc1, 0x29, 0x8e, 0xbe, 0xc5, 0x2c, 0xba, 0x31, 0x45, 0xe7, 0x29, 0xd1, 0x11, 0xf4, + 0xfb, 0x93, 0x59, 0xbf, 0x9e, 0xa0, 0xea, 0x34, 0x0e, 0xa3, 0x5f, 0xf1, 0x28, 0x83, 0x83, 0x7c, + 0x6e, 0xe9, 0x0e, 0x54, 0x91, 0x40, 0x06, 0x2f, 0xa4, 0x32, 0xb2, 0x86, 0x0d, 0x70, 0x97, 0xdb, + 0x41, 0x89, 0x4c, 0xbe, 0xbe, 0x08, 0x74, 0xe9, 0xb4, 0x62, 0x33, 0xf3, 0xca, 0x22, 0x74, 0x31, + 0x24, 0x6a, 0x16, 0x3f, 0x5d, 0xf1, 0x96, 0x88, 0x0f, 0xc3, 0xc5, 0x51, 0xe5, 0x1e, 0xf5, 0x1e, + 0x30, 0x52, 0x35, 0x54, 0x18, 0xf1, 0x82, 0x91, 0xaa, 0xa0, 0x27, 0x3a, 0x26, 0x86, 0x1e, 0xb6, + 0x07, 0xd7, 0xee, 0xb8, 0x4b, 0x8d, 0x79, 0x57, 0xb1, 0xaf, 0x2a, 0xf7, 0x82, 0xb2, 0x24, 0x97, + 0xcf, 0xb6, 0x9a, 0x4e, 0x80, 0x4f, 0x98, 0xa3, 0x2d, 0x0a, 0x5a, 0x16, 0xb4, 0x2d, 0x68, 0xf2, + 0xd4, 0xb4, 0x29, 0x68, 0x1e, 0x89, 0x0f, 0x44, 0x89, 0xc6, 0x88, 0x17, 0x43, 0xb6, 0x7c, 0x2a, + 0xa7, 0xe3, 0xb4, 0xe4, 0x31, 0xca, 0xab, 0x92, 0x2d, 0x30, 0xf4, 0xc6, 0x21, 0x38, 0xfc, 0x31, + 0x77, 0x79, 0x3b, 0x93, 0xc8, 0xa6, 0x54, 0x99, 0x99, 0x27, 0x8f, 0xfe, 0x1e, 0xe5, 0xc2, 0xe6, + 0x5c, 0x26, 0x92, 0xdd, 0x76, 0xc7, 0x65, 0x69, 0xa6, 0x9a, 0x7f, 0xe3, 0x6d, 0xc2, 0x66, 0xbf, + 0x52, 0x4b, 0xb7, 0x36, 0xe1, 0x71, 0x24, 0xb9, 0x0a, 0x9a, 0x24, 0x93, 0xf5, 0xc3, 0xc2, 0x46, + 0x3c, 0xa3, 0xde, 0xa3, 0xca, 0x3d, 0xe3, 0x1e, 0x51, 0xef, 0x22, 0x3a, 0x26, 0xb3, 0x73, 0xe9, + 0xf7, 0x5c, 0x13, 0xc6, 0x29, 0xa8, 0xa6, 0xa2, 0x9a, 0x8a, 0x69, 0x97, 0x8d, 0x8c, 0x51, 0x52, + 0x63, 0x54, 0x98, 0x51, 0xe5, 0x1e, 0xf3, 0x06, 0x03, 0x92, 0x18, 0xed, 0x2b, 0x68, 0xbe, 0x25, + 0x60, 0x45, 0x81, 0x2b, 0x07, 0x58, 0xf0, 0xb1, 0x22, 0x33, 0x34, 0xf4, 0xf4, 0xed, 0xfa, 0xaa, + 0xae, 0x8e, 0x44, 0xf8, 0x27, 0x0a, 0x43, 0x6a, 0x8f, 0x91, 0x31, 0x94, 0xf6, 0x50, 0xd1, 0x8f, + 0xc6, 0x9b, 0xda, 0xbb, 0xaa, 0xc2, 0xb0, 0x97, 0x94, 0x54, 0x26, 0x34, 0xf7, 0xdb, 0x6e, 0xa5, + 0x99, 0x0e, 0x0d, 0xdb, 0x20, 0x10, 0x5f, 0xef, 0xcf, 0xbe, 0x36, 0x3d, 0x38, 0xf2, 0x95, 0x7f, + 0xdf, 0xb8, 0x48, 0xb2, 0xa7, 0xe3, 0x76, 0x91, 0x47, 0x09, 0x7b, 0xbe, 0x6e, 0xf5, 0x1b, 0x4c, + 0xe5, 0x65, 0xe5, 0x07, 0x0b, 0x19, 0x08, 0x04, 0x51, 0xab, 0x10, 0x08, 0x82, 0xb1, 0x84, 0x7f, + 0x34, 0x8d, 0x33, 0x72, 0xf7, 0x29, 0xc9, 0xbf, 0xf8, 0xdc, 0x32, 0x3f, 0xae, 0xd9, 0x69, 0xfc, + 0x99, 0xc7, 0x31, 0xf2, 0x98, 0x8d, 0x40, 0x20, 0x54, 0xd8, 0xe7, 0x74, 0x05, 0xa7, 0x9b, 0xaa, + 0xaf, 0x85, 0x2b, 0x44, 0x42, 0x81, 0xf5, 0x52, 0xf1, 0x8b, 0x94, 0x1e, 0x06, 0xbb, 0x87, 0xc1, + 0x34, 0x7b, 0x43, 0x96, 0x45, 0x8a, 0x35, 0xd7, 0x10, 0xab, 0x0c, 0x05, 0xc1, 0xb6, 0x9f, 0x29, + 0x7a, 0x28, 0x3c, 0x15, 0xd8, 0x41, 0x4e, 0xaa, 0x34, 0x61, 0xbc, 0x3d, 0x29, 0x38, 0x87, 0x5b, + 0x0e, 0x11, 0xad, 0x33, 0xa0, 0x06, 0x3e, 0x26, 0x31, 0x99, 0xba, 0x6f, 0xf1, 0xa2, 0x57, 0x8c, + 0x91, 0x23, 0x58, 0x7b, 0xb7, 0xb0, 0xe6, 0xf9, 0x3a, 0x3d, 0xd9, 0xbb, 0x3e, 0x27, 0xd4, 0x4e, + 0x0e, 0x87, 0x8c, 0x29, 0x15, 0x3a, 0x06, 0xd4, 0x0a, 0x03, 0x56, 0x28, 0x7c, 0xa2, 0x69, 0x15, + 0x05, 0x8a, 0xa4, 0xbf, 0x05, 0x43, 0x1b, 0x55, 0x27, 0x77, 0x3b, 0x05, 0xd7, 0x27, 0x1d, 0x33, + 0x65, 0x19, 0x2f, 0x94, 0xaa, 0x8e, 0x98, 0x89, 0x65, 0xf6, 0x91, 0x5c, 0x2e, 0x13, 0x18, 0xa6, + 0xa2, 0x9a, 0x8a, 0x6a, 0x29, 0x92, 0x92, 0x19, 0x21, 0xff, 0x0e, 0xdc, 0x7f, 0xc3, 0xf4, 0xd7, + 0xf9, 0x7f, 0xbd, 0x7d, 0x35, 0xf4, 0xce, 0xce, 0xc9, 0xf2, 0x7f, 0xf0, 0x41, 0x18, 0x62, 0xa5, + 0xa1, 0x47, 0xbc, 0x6b, 0xca, 0xbd, 0xd5, 0x7b, 0x3a, 0x17, 0x4d, 0xa6, 0xde, 0x6d, 0x0d, 0x3c, + 0x5d, 0xfc, 0x3b, 0x54, 0xd0, 0xa9, 0xa3, 0xc9, 0x76, 0x3e, 0x31, 0x4f, 0x89, 0x48, 0x47, 0x5f, + 0x1a, 0x72, 0xef, 0x8b, 0xf1, 0xdf, 0x0f, 0x26, 0x3e, 0xb8, 0x22, 0x82, 0xff, 0xbe, 0x82, 0x9b, + 0xe1, 0x68, 0xff, 0xaf, 0x1d, 0xa0, 0xc7, 0x9c, 0xce, 0x3b, 0x44, 0xbf, 0x91, 0xf2, 0x3c, 0x47, + 0x06, 0x11, 0x8f, 0x7f, 0x8d, 0x51, 0x37, 0xe5, 0x84, 0xb0, 0x27, 0x05, 0xfc, 0x77, 0xcb, 0x7d, + 0x8e, 0xf9, 0x6f, 0x93, 0x2f, 0xcb, 0xa5, 0xdf, 0x04, 0x06, 0x6a, 0xa6, 0x8e, 0x45, 0xb3, 0x22, + 0x6f, 0xcf, 0x93, 0x63, 0x7d, 0x32, 0x78, 0xe3, 0xf1, 0xb0, 0x89, 0xea, 0x4c, 0x25, 0x8d, 0xc2, + 0xfc, 0xcb, 0x65, 0xbb, 0x8b, 0xe9, 0x1e, 0x9a, 0xf9, 0x0c, 0x90, 0xcc, 0x71, 0xf8, 0x53, 0x56, + 0xfc, 0x1d, 0x5f, 0x2f, 0x66, 0x44, 0x92, 0x49, 0x59, 0x71, 0xb8, 0xff, 0x1b, 0x54, 0xa2, 0x8a, + 0xfb, 0x4d, 0x54, 0xd2, 0x06, 0xd1, 0xf2, 0xa1, 0xf3, 0xa5, 0x55, 0x5f, 0xf0, 0xec, 0xd9, 0x3e, + 0x60, 0xab, 0x24, 0xfa, 0xf3, 0xb9, 0xfe, 0x23, 0xc9, 0xd5, 0x6c, 0x4f, 0x82, 0x5b, 0x75, 0xba, + 0x5d, 0x6e, 0x92, 0x03, 0x2a, 0xa1, 0x6b, 0x7f, 0x85, 0x79, 0xf3, 0x36, 0x9b, 0x49, 0xac, 0xd5, + 0xf3, 0xe9, 0xf5, 0x85, 0x42, 0xf1, 0x73, 0x10, 0x4c, 0x41, 0x31, 0x05, 0xc4, 0x12, 0xe1, 0x71, + 0x98, 0xcc, 0xf0, 0xf5, 0x24, 0xb4, 0xa9, 0x17, 0x4f, 0x70, 0x2a, 0x6f, 0xf4, 0xc9, 0xdb, 0xaf, + 0xc1, 0x75, 0x8a, 0x12, 0xc3, 0x76, 0x5c, 0x2e, 0x13, 0x19, 0x8d, 0xf3, 0xd7, 0xce, 0x62, 0x73, + 0x13, 0x98, 0xbc, 0xc7, 0xcf, 0xc2, 0xdb, 0x6d, 0xb7, 0xfe, 0x19, 0x12, 0x31, 0x4d, 0x45, 0x34, + 0xe3, 0xe1, 0xe7, 0x9a, 0x6b, 0xf9, 0xe8, 0x7b, 0x7e, 0x4d, 0xa6, 0x4d, 0xf0, 0xcc, 0x7f, 0xcb, + 0xfd, 0xe5, 0x47, 0x59, 0xb4, 0xdb, 0xfe, 0x2f, 0x0f, 0x63, 0x3a, 0x8f, 0x18, 0x29, 0x1a, 0xaa, + 0x79, 0x7d, 0x6f, 0xbf, 0x3d, 0xc7, 0x91, 0xfc, 0x8f, 0xf0, 0xb6, 0x35, 0x4a, 0xaa, 0x55, 0x52, + 0xaa, 0x89, 0x97, 0xe5, 0xd2, 0xef, 0x82, 0x08, 0xd7, 0xbe, 0x31, 0xef, 0xe3, 0x2d, 0x1f, 0x05, + 0x7e, 0x48, 0x50, 0xf9, 0xbb, 0xe1, 0x71, 0x5c, 0x76, 0x34, 0xd8, 0xb8, 0x58, 0x8d, 0x1c, 0x14, + 0x26, 0xa6, 0x19, 0x4c, 0x59, 0x34, 0xd7, 0xf8, 0xd8, 0xc1, 0xc6, 0x00, 0xb9, 0xaa, 0xf6, 0xce, + 0xe4, 0x1c, 0xbf, 0x85, 0x5d, 0xbe, 0x52, 0x9f, 0x11, 0xac, 0x23, 0xf5, 0xff, 0x1a, 0x65, 0x0d, + 0xfb, 0xda, 0x42, 0x4a, 0xf2, 0xd5, 0x8f, 0x43, 0x13, 0x61, 0x1e, 0x24, 0x1c, 0x4a, 0xe0, 0x44, + 0x6d, 0xf3, 0x4a, 0xec, 0x0d, 0x28, 0x18, 0x9e, 0xa9, 0xc3, 0x6d, 0x30, 0xfb, 0xe1, 0xfd, 0x36, + 0x9f, 0x8d, 0x22, 0xc1, 0xa6, 0x81, 0x40, 0x34, 0x6b, 0xdc, 0xeb, 0x73, 0x3f, 0x5a, 0xe8, 0xd8, + 0x42, 0xdb, 0xc8, 0x68, 0xb5, 0x7f, 0xca, 0x7f, 0xf1, 0xb8, 0x47, 0xa9, 0xd9, 0xcf, 0x5e, 0x9b, + 0x2a, 0x8e, 0x1a, 0x3a, 0xa1, 0xb6, 0xb7, 0x3b, 0x17, 0xfe, 0x14, 0x8e, 0xee, 0x8a, 0xcc, 0xbb, + 0x99, 0x54, 0x4f, 0x48, 0x71, 0x94, 0x5e, 0x3e, 0xc1, 0xcd, 0xb1, 0xf3, 0x97, 0xc6, 0xf4, 0xc0, + 0x9f, 0x86, 0x76, 0xc4, 0x17, 0xd2, 0x0d, 0x35, 0xe5, 0xff, 0xe9, 0xcd, 0xe5, 0x84, 0x82, 0xe7, + 0x58, 0x49, 0x14, 0xc7, 0xbd, 0xbe, 0x2a, 0x9a, 0xfc, 0x28, 0x74, 0x0b, 0x49, 0x4e, 0xaa, 0x6c, + 0x5c, 0x34, 0x77, 0xad, 0xb6, 0xa9, 0x97, 0xad, 0xb3, 0xe3, 0xeb, 0x4d, 0x39, 0x7d, 0x83, 0x3b, + 0x1c, 0xbf, 0xc1, 0x51, 0x5a, 0x23, 0x0c, 0x94, 0x63, 0x1d, 0x15, 0xcd, 0x21, 0x86, 0x75, 0xff, + 0xbe, 0x34, 0x72, 0x81, 0xa4, 0x3d, 0xac, 0x25, 0xac, 0xd1, 0x1a, 0x83, 0x4d, 0x67, 0x72, 0xa6, + 0x63, 0xb1, 0xcb, 0xdb, 0x57, 0x24, 0xc9, 0x25, 0xf7, 0xcb, 0xfc, 0x2c, 0x5a, 0x97, 0x74, 0xb8, + 0x0b, 0x61, 0x8b, 0x0a, 0x9d, 0x45, 0xe2, 0xfe, 0xb8, 0x30, 0x09, 0x8e, 0xb6, 0x20, 0xeb, 0x62, + 0x0e, 0xba, 0x03, 0xae, 0x98, 0x8b, 0xa2, 0xa5, 0x8a, 0x97, 0xfc, 0x5c, 0x1d, 0x74, 0x07, 0x5d, + 0x30, 0x75, 0xd0, 0x1d, 0x74, 0xfc, 0x59, 0x1a, 0x6b, 0x69, 0xaf, 0xc2, 0x16, 0xaa, 0xcf, 0x6d, + 0x27, 0x69, 0xaf, 0xce, 0x54, 0x40, 0xd5, 0xe9, 0xa6, 0x4d, 0x66, 0xbe, 0x6c, 0x76, 0x95, 0xb4, + 0xf5, 0x44, 0xb9, 0x07, 0xad, 0x10, 0x40, 0xbe, 0xee, 0xee, 0x7e, 0x2b, 0xc6, 0xa8, 0xc7, 0xbf, + 0xc3, 0x66, 0x16, 0xa6, 0xc3, 0xe2, 0x3b, 0x4d, 0x53, 0x8b, 0x63, 0xee, 0x9c, 0x7e, 0x1f, 0x9f, + 0x47, 0xd0, 0xd1, 0x3f, 0x43, 0xd9, 0x16, 0xe7, 0xbb, 0x74, 0xe9, 0xb9, 0xfc, 0x9c, 0xb4, 0xa4, + 0xf8, 0x5a, 0xdb, 0x13, 0x66, 0x5c, 0x90, 0xe7, 0xd6, 0xf9, 0x3a, 0x64, 0x66, 0x32, 0x73, 0x9f, + 0x0c, 0x77, 0x54, 0x4a, 0x75, 0xff, 0x0b, 0xf8, 0xed, 0x2b, 0x69, 0xcc, 0xaf, 0xf2, 0xc0, 0xbb, + 0xf8, 0x2d, 0x83, 0xbd, 0x07, 0x5d, 0x38, 0x30, 0x75, 0xd3, 0x25, 0xf5, 0x61, 0xe7, 0x9e, 0x9e, + 0x19, 0xe1, 0xff, 0x65, 0x1a, 0x4c, 0x6a, 0x93, 0x1c, 0xeb, 0xf0, 0x41, 0x18, 0xa7, 0xf0, 0x75, + 0xd0, 0x1d, 0x74, 0xc6, 0x5a, 0x14, 0xb4, 0x19, 0x19, 0x63, 0x72, 0xda, 0x6b, 0x2e, 0x97, 0x7c, + 0x17, 0xea, 0x9f, 0x23, 0x0b, 0x8c, 0x79, 0x4f, 0x28, 0x5c, 0x94, 0x90, 0xb2, 0x1f, 0xf0, 0xad, + 0x73, 0x42, 0xe6, 0x8f, 0x5c, 0xd0, 0xb9, 0xa3, 0xd3, 0x7e, 0x58, 0x4b, 0x0f, 0x3d, 0x37, 0xe4, + 0x84, 0x90, 0xf5, 0x73, 0xe0, 0x9c, 0xde, 0x79, 0x1d, 0x67, 0x50, 0x25, 0xf6, 0xa3, 0xa0, 0x8a, + 0x2f, 0x8d, 0x19, 0x1e, 0xb0, 0x83, 0x54, 0xf9, 0x85, 0x03, 0x72, 0xbd, 0x6e, 0x44, 0x4d, 0x33, + 0xd6, 0x07, 0xb3, 0x3b, 0x30, 0x5d, 0xb8, 0x8c, 0x05, 0x93, 0xc5, 0x6e, 0xd9, 0xfb, 0xff, 0x8d, + 0x87, 0xeb, 0x46, 0xf9, 0x50, 0x6a, 0x7c, 0x51, 0x6a, 0xbf, 0x74, 0xde, 0x4d, 0xe5, 0xda, 0x64, + 0xc3, 0xcb, 0x81, 0x08, 0xdf, 0x6d, 0xba, 0xdb, 0xf1, 0xa4, 0xe6, 0xaa, 0x04, 0x55, 0x06, 0xa9, + 0x6d, 0x4b, 0x02, 0xc6, 0x3f, 0x98, 0xef, 0x4d, 0x76, 0x6c, 0x06, 0xd6, 0xd5, 0x66, 0x7d, 0x27, + 0x6a, 0x16, 0xd0, 0x5f, 0x36, 0x02, 0xa5, 0x08, 0xa9, 0x8c, 0x68, 0x4d, 0xd3, 0xfe, 0x34, 0x99, + 0x6d, 0x73, 0x55, 0x17, 0x4b, 0x71, 0xa7, 0xb2, 0xec, 0x4b, 0x11, 0x6e, 0xd8, 0x74, 0x92, 0xf0, + 0xec, 0x0c, 0x81, 0x33, 0xd4, 0xfb, 0xf1, 0xe5, 0x8e, 0xa5, 0xe7, 0x08, 0x2a, 0xdc, 0xf6, 0x87, + 0x0d, 0xbe, 0x1d, 0x3b, 0x8c, 0x60, 0x19, 0xbe, 0x7e, 0xe9, 0x81, 0x80, 0xa0, 0x8c, 0xa1, 0x6c, + 0x73, 0x5f, 0x85, 0x1b, 0xc8, 0xbc, 0x83, 0x93, 0x15, 0xeb, 0x76, 0xe7, 0x96, 0x57, 0xc3, 0xd8, + 0x32, 0x2b, 0xae, 0xb0, 0xfd, 0x94, 0xec, 0x58, 0x84, 0xc6, 0x33, 0xb5, 0xaa, 0x9e, 0xaa, 0xab, + 0xfe, 0x20, 0x4d, 0x7d, 0x23, 0xe7, 0xf8, 0x83, 0x8d, 0x26, 0x19, 0xfd, 0x26, 0x4c, 0x99, 0x78, + 0x29, 0xb9, 0x58, 0x39, 0xa5, 0xf9, 0x1a, 0xb0, 0x1c, 0x4e, 0x42, 0x5a, 0x32, 0x12, 0x3f, 0xe2, + 0x23, 0xcc, 0xd3, 0x71, 0xd4, 0xc9, 0x73, 0xa2, 0x76, 0x8e, 0xa9, 0xf9, 0xe3, 0x0c, 0xf9, 0x79, + 0x3d, 0xaa, 0x1b, 0x0d, 0x60, 0xf9, 0x0e, 0xa3, 0xe6, 0x41, 0xb6, 0x4a, 0x86, 0x87, 0x8d, 0x11, + 0x43, 0x60, 0x74, 0x95, 0x86, 0xd9, 0x44, 0x19, 0x6c, 0x3c, 0xb0, 0x52, 0x7c, 0xbb, 0x83, 0x5b, + 0x37, 0xcb, 0xf2, 0xff, 0x05, 0x07, 0x2c, 0x8a, 0x41, 0x26, 0xc6, 0x54, 0xef, 0xbf, 0xce, 0x15, + 0x3d, 0x34, 0x26, 0x87, 0xc4, 0x70, 0xde, 0x35, 0x4a, 0xaa, 0x25, 0xfc, 0xd0, 0x9a, 0x02, 0xf8, + 0x2f, 0x18, 0x7c, 0xea, 0x89, 0xb3, 0x7a, 0xf9, 0x39, 0x3b, 0x3b, 0x3f, 0x87, 0xf2, 0xe7, 0x9a, + 0xcd, 0x79, 0x2c, 0x97, 0xd4, 0xd3, 0x39, 0x97, 0x99, 0x76, 0xbb, 0x59, 0xac, 0xdf, 0x04, 0x7b, + 0xd6, 0x15, 0x70, 0x5e, 0x71, 0x3c, 0x43, 0xb7, 0x6e, 0xd8, 0xb1, 0x2d, 0xdb, 0x1d, 0x87, 0xff, + 0x50, 0x1e, 0xf8, 0x70, 0xd8, 0xdb, 0x6b, 0x49, 0x74, 0x5a, 0x16, 0x81, 0xd8, 0xc8, 0xec, 0x67, + 0xfc, 0xf7, 0xb9, 0x94, 0x63, 0xf0, 0xdf, 0xe7, 0xaf, 0xcb, 0xa5, 0xdf, 0xc1, 0x47, 0x2e, 0x17, + 0x09, 0x89, 0x33, 0x22, 0x7f, 0x9e, 0xbe, 0x2c, 0x2d, 0xaf, 0x0a, 0xcd, 0x86, 0xc6, 0x9f, 0x8d, + 0x6a, 0xe5, 0x49, 0x22, 0x6b, 0x0c, 0xa4, 0x53, 0x49, 0x57, 0xe7, 0xaf, 0x9f, 0x4f, 0xaf, 0xd7, + 0xef, 0x86, 0x66, 0xc3, 0x61, 0xf1, 0xf8, 0xa6, 0xd3, 0x6f, 0xfe, 0x18, 0xe7, 0x24, 0x72, 0x41, + 0xcc, 0xa4, 0x8c, 0xa4, 0x99, 0x57, 0x19, 0x4e, 0x7c, 0xe6, 0x4e, 0x65, 0x28, 0xbc, 0x35, 0xcb, + 0x89, 0x64, 0xeb, 0xdb, 0x6c, 0xc6, 0xa8, 0x5e, 0x18, 0x9f, 0xb6, 0x5d, 0x6e, 0x96, 0x5f, 0x07, + 0xb6, 0x5d, 0xff, 0x82, 0x19, 0x6f, 0xe7, 0x3e, 0x1c, 0x23, 0x77, 0x3e, 0xe3, 0x3e, 0x2a, 0x8b, + 0x57, 0xe1, 0xb3, 0xa5, 0xac, 0x84, 0x72, 0xab, 0x76, 0xff, 0xcd, 0x49, 0x03, 0x48, 0x32, 0xa4, + 0xfc, 0x10, 0x1a, 0x8c, 0x86, 0x3b, 0x31, 0xf1, 0x8b, 0x3d, 0x06, 0xdc, 0x9b, 0x14, 0xd5, 0x97, + 0xff, 0xc6, 0xcd, 0xba, 0x6d, 0x1a, 0x89, 0xd7, 0xdc, 0x3a, 0xd5, 0xe1, 0xd1, 0xc6, 0xf9, 0xd1, + 0x35, 0x5b, 0xf5, 0xf5, 0x95, 0x5f, 0x0a, 0x61, 0xdd, 0x26, 0x15, 0x09, 0xd0, 0x8a, 0x10, 0xc9, + 0xca, 0xee, 0x6b, 0xb3, 0xd5, 0xd1, 0x5e, 0xd3, 0x46, 0xfa, 0x8e, 0xaf, 0x85, 0x0c, 0x3f, 0x9b, + 0x22, 0xa9, 0x25, 0xba, 0xda, 0x30, 0xc6, 0x8f, 0x61, 0xea, 0xf6, 0x10, 0xf4, 0xe7, 0xe7, 0xf8, + 0x7f, 0x2b, 0x2c, 0x6d, 0x66, 0x5d, 0x0f, 0xd2, 0x71, 0x94, 0x38, 0x48, 0x98, 0xe0, 0xd1, 0xe1, + 0xaf, 0x8a, 0xf1, 0x5f, 0xc2, 0x85, 0x39, 0x59, 0xca, 0x99, 0x89, 0x7b, 0x2d, 0x9d, 0xec, 0x47, + 0x5d, 0x55, 0x9d, 0xbe, 0x0b, 0x0a, 0x82, 0x9a, 0xcd, 0x69, 0xb4, 0xe3, 0xf0, 0xd7, 0xe5, 0xd4, + 0xeb, 0xc6, 0x4e, 0x44, 0xf5, 0xa2, 0xc9, 0xd6, 0x4f, 0x56, 0x49, 0x31, 0xec, 0xd7, 0xc4, 0x50, + 0x32, 0x90, 0x4b, 0x50, 0xef, 0x8f, 0x88, 0xb9, 0xe1, 0x12, 0xa7, 0x21, 0x1d, 0x8e, 0x7c, 0x69, + 0x92, 0xe3, 0xb5, 0xc8, 0xbc, 0x65, 0x24, 0x22, 0xe3, 0x59, 0x7e, 0x3f, 0x17, 0xa1, 0x16, 0xe8, + 0x0e, 0x11, 0xb3, 0x9e, 0x9c, 0x00, 0x62, 0x49, 0x8a, 0x98, 0xab, 0xc4, 0x5d, 0xad, 0x8b, 0xb5, + 0xda, 0xcf, 0x45, 0x04, 0x6f, 0xe3, 0xcd, 0xa0, 0x86, 0xc6, 0x21, 0xf9, 0x9e, 0x75, 0xde, 0x01, + 0xdc, 0xcc, 0xfe, 0x34, 0x57, 0x11, 0xbb, 0x78, 0x77, 0x5e, 0x3b, 0xc9, 0x2c, 0x68, 0x3b, 0xa4, + 0x5d, 0x35, 0xc4, 0xb6, 0x72, 0x9a, 0x9b, 0x9b, 0x9b, 0xbb, 0xff, 0x8b, 0xb1, 0x1c, 0x54, 0x7e, + 0xdd, 0x8d, 0xb9, 0x12, 0xf8, 0x6c, 0x2f, 0x89, 0x49, 0x09, 0x49, 0x1d, 0x27, 0xd3, 0xef, 0xe2, + 0x39, 0x88, 0x65, 0x46, 0x54, 0x72, 0xaf, 0x2b, 0xe7, 0xa9, 0x0d, 0xab, 0x46, 0x77, 0x89, 0xe1, + 0xe3, 0x1f, 0xbf, 0xbf, 0xbf, 0x9f, 0x9b, 0xbf, 0xbb, 0x9f, 0xd2, 0x39, 0xa7, 0xee, 0x53, 0xe9, + 0xb8, 0xed, 0xeb, 0xff, 0x82, 0x82, 0xa4, 0x93, 0xc9, 0xb8, 0x8b, 0x47, 0x54, 0xce, 0xdd, 0xcb, + 0xe1, 0x5b, 0x4d, 0x34, 0xd1, 0x22, 0x5c, 0x76, 0x3b, 0x38, 0xfb, 0x45, 0xaa, 0x09, 0xbd, 0x31, + 0x6c, 0x55, 0xb7, 0xe1, 0x52, 0x03, 0x59, 0xa0, 0xab, 0x34, 0x79, 0x56, 0x68, 0x2a, 0xcd, 0x1f, + 0x56, 0x9a, 0xa9, 0xa2, 0xe9, 0x77, 0xf8, 0x7f, 0x3b, 0x45, 0xcc, 0xb8, 0x91, 0xef, 0xd4, 0xc6, + 0x2a, 0x17, 0xff, 0xc3, 0xfa, 0x45, 0x20, 0xb4, 0x82, 0x4c, 0x66, 0x14, 0x82, 0xd2, 0x09, 0xc9, + 0x0f, 0x34, 0xc7, 0x01, 0xc0, 0xcb, 0xe3, 0x11, 0x0a, 0x22, 0x3f, 0xc1, 0x3e, 0xaa, 0x4d, 0x24, + 0x99, 0xab, 0x4d, 0x15, 0x7c, 0x69, 0x37, 0x76, 0x6c, 0xd1, 0xa3, 0xdd, 0x7b, 0xba, 0xa5, 0x13, + 0x4d, 0x7f, 0x87, 0xfa, 0x4e, 0xcd, 0x99, 0x32, 0x59, 0xb3, 0x55, 0xaa, 0x49, 0x34, 0xd7, 0xf8, + 0x7e, 0x3f, 0xe5, 0xfe, 0x51, 0xe8, 0xb5, 0xab, 0xba, 0xb5, 0xe2, 0x5d, 0x2e, 0xbb, 0x5d, 0xbf, + 0xe0, 0x8f, 0x9a, 0x2e, 0x8a, 0x3e, 0x16, 0xdd, 0x51, 0x9b, 0x2a, 0x69, 0xac, 0xa9, 0x44, 0xd3, + 0x5f, 0xe0, 0xbb, 0x31, 0x05, 0x73, 0x10, 0x6c, 0x19, 0xc8, 0x31, 0x7c, 0x3b, 0xa9, 0x48, 0x3b, + 0xa4, 0x4c, 0x8a, 0x72, 0x0b, 0xd0, 0x79, 0x52, 0x49, 0xa6, 0xbf, 0xc1, 0x5e, 0x83, 0x79, 0x05, + 0x72, 0x51, 0x7a, 0xb5, 0x8c, 0x7c, 0x29, 0x55, 0x55, 0x77, 0x77, 0x66, 0xcd, 0x24, 0xb6, 0x9a, + 0x16, 0x80, 0x2f, 0xc2, 0x9d, 0x21, 0xff, 0x14, 0x76, 0x8d, 0xf4, 0x3d, 0x3e, 0x7a, 0x2c, 0xfc, + 0x91, 0x7a, 0x95, 0x11, 0x78, 0x2f, 0xe4, 0xf1, 0x9f, 0x45, 0x75, 0x4c, 0x9d, 0x36, 0x25, 0xff, + 0x1b, 0x60, 0xed, 0xe5, 0x2e, 0x1c, 0xc5, 0xe9, 0x30, 0x62, 0xcd, 0x86, 0xce, 0x42, 0x0b, 0x1b, + 0x54, 0x7d, 0x2a, 0x18, 0x12, 0xf3, 0x63, 0x24, 0x9a, 0x46, 0x36, 0xbe, 0x2f, 0x82, 0xf3, 0x0e, + 0x67, 0xa3, 0xed, 0x5d, 0x16, 0xbe, 0xef, 0x96, 0xdc, 0xfc, 0x57, 0x8c, 0x5f, 0xc6, 0x96, 0x1a, + 0x6b, 0x06, 0x8b, 0xe0, 0x54, 0x9d, 0x1a, 0xc2, 0x8d, 0x8f, 0x63, 0xbb, 0xdf, 0x59, 0x3f, 0xa7, + 0xfc, 0x61, 0x42, 0x46, 0x6a, 0x74, 0xde, 0xfa, 0xac, 0x61, 0xc9, 0x77, 0x36, 0x6d, 0x6f, 0x6f, + 0xc6, 0x74, 0x13, 0x83, 0xff, 0x1e, 0x87, 0xe5, 0xa4, 0x3c, 0xb8, 0xc8, 0x31, 0xf9, 0x17, 0x9e, + 0x5f, 0xe3, 0x46, 0x6c, 0xe4, 0x20, 0xdd, 0x27, 0x03, 0xb1, 0x92, 0x1e, 0x64, 0x8e, 0x6e, 0x86, + 0xe0, 0xd1, 0x80, 0xfb, 0xe9, 0x78, 0xc8, 0xe5, 0x07, 0x44, 0x04, 0xb0, 0xcf, 0xf8, 0x41, 0xd1, + 0x9a, 0x22, 0xbf, 0xdf, 0xe1, 0xd2, 0xd4, 0x3e, 0xf8, 0x86, 0xb0, 0x5e, 0xa2, 0x0c, 0x96, 0xad, + 0xeb, 0xf8, 0x04, 0x39, 0x23, 0x4b, 0xac, 0x10, 0x84, 0xb9, 0x46, 0xca, 0x7c, 0xd8, 0x7e, 0xcc, + 0x94, 0x61, 0xb1, 0x27, 0x8d, 0x2e, 0xc3, 0x47, 0x65, 0x35, 0xec, 0x0e, 0x0d, 0xb3, 0x87, 0xe4, + 0x61, 0x8e, 0x0d, 0xbe, 0xef, 0x6f, 0xe3, 0x2d, 0xf0, 0xe6, 0x94, 0xd2, 0xcb, 0x06, 0x55, 0xb2, + 0xac, 0x32, 0x10, 0x61, 0xf8, 0xc3, 0xcb, 0x06, 0xfa, 0x53, 0x39, 0x1e, 0x99, 0xeb, 0xcb, 0x46, + 0x63, 0x0d, 0x7b, 0x4f, 0xc2, 0x38, 0xaa, 0x68, 0xd2, 0x9d, 0x40, 0x5d, 0x52, 0xde, 0x91, 0xd2, + 0xbc, 0xd7, 0x85, 0x23, 0x32, 0xde, 0x72, 0x84, 0xc3, 0x8d, 0x8e, 0xf3, 0x92, 0x22, 0x55, 0xe7, + 0x8a, 0xb8, 0x40, 0x70, 0xee, 0xe8, 0x7c, 0x89, 0xf0, 0x95, 0xf5, 0xd6, 0x82, 0x43, 0x5f, 0x1f, + 0x6a, 0x86, 0x56, 0x95, 0x16, 0xdb, 0xcc, 0xb9, 0x19, 0xf1, 0x85, 0x2e, 0x13, 0x59, 0x8c, 0xd5, + 0xa8, 0x6a, 0x10, 0x96, 0xa1, 0xb1, 0x51, 0x99, 0xa2, 0x73, 0x34, 0x5b, 0x76, 0xfc, 0x7f, 0x68, + 0xc4, 0x15, 0xae, 0x18, 0x0c, 0x65, 0xf6, 0xbd, 0x9f, 0x59, 0xbf, 0xe1, 0x91, 0x8c, 0xc1, 0xa3, + 0x75, 0xb9, 0x7b, 0x69, 0xcb, 0x54, 0xcb, 0xd3, 0x8f, 0xc6, 0x92, 0xb3, 0x19, 0x54, 0x99, 0x93, + 0xa4, 0x6e, 0x4d, 0xfc, 0x23, 0xf1, 0x56, 0x98, 0x3f, 0xfe, 0x14, 0xa5, 0x6d, 0xbd, 0xdd, 0x83, + 0x1c, 0x90, 0xf1, 0x96, 0x92, 0x7d, 0xd3, 0xeb, 0xe6, 0x0b, 0x9f, 0x39, 0x78, 0x60, 0x20, 0x8e, + 0x9b, 0x26, 0x9d, 0x13, 0x0b, 0xa8, 0x43, 0x49, 0x45, 0xd5, 0x50, 0x3f, 0xf3, 0x91, 0x57, 0x99, + 0x46, 0xc5, 0x49, 0x5b, 0x22, 0x62, 0xda, 0x62, 0xdf, 0x8d, 0xa1, 0xd0, 0x67, 0xa9, 0xf2, 0xad, + 0x5e, 0xfa, 0x38, 0xd2, 0xfc, 0xf6, 0x9c, 0xbc, 0xd0, 0x93, 0xff, 0x05, 0x7c, 0x22, 0xf3, 0xb1, + 0xa7, 0x29, 0x7b, 0xe7, 0x9d, 0xf7, 0x70, 0x26, 0xeb, 0x1a, 0x2b, 0xdb, 0x69, 0xc6, 0x22, 0x3b, + 0x09, 0x90, 0xfb, 0x5f, 0xc6, 0x10, 0xa4, 0x25, 0xd1, 0xf5, 0xfb, 0x00, 0xd7, 0xaa, 0xe5, 0x7e, + 0xe4, 0x32, 0x3f, 0x8c, 0x99, 0xfc, 0x18, 0x13, 0x37, 0x37, 0xcf, 0x87, 0xc1, 0xad, 0x1f, 0x44, + 0x77, 0xe9, 0xa6, 0x9a, 0x7e, 0x0c, 0x0b, 0x26, 0x58, 0x36, 0xed, 0xd1, 0xe7, 0xd3, 0x4d, 0x34, + 0xfc, 0x7c, 0x67, 0xdf, 0x3d, 0x79, 0x88, 0x25, 0xc2, 0x63, 0x33, 0xc3, 0x84, 0x48, 0xb8, 0xf1, + 0xb7, 0xd5, 0x55, 0x7c, 0x13, 0x69, 0x26, 0x9d, 0x94, 0x83, 0x68, 0xf7, 0xc6, 0x9c, 0xbb, 0xb0, + 0x69, 0x25, 0xed, 0x35, 0xb4, 0xd2, 0x75, 0x88, 0x99, 0x11, 0x33, 0xfe, 0x15, 0x28, 0xeb, 0xa0, + 0xeb, 0xa6, 0x3a, 0xe8, 0x3a, 0xe9, 0x99, 0x09, 0x4b, 0x26, 0x93, 0x7f, 0xc2, 0xa4, 0x29, 0x5c, + 0xe4, 0x12, 0x95, 0xca, 0xa1, 0x8c, 0x79, 0x53, 0x8e, 0x34, 0xff, 0xd4, 0xa0, 0x67, 0xe0, 0xa4, + 0x99, 0x2c, 0x96, 0x52, 0x09, 0x48, 0x3c, 0x98, 0xcc, 0x2e, 0x37, 0x12, 0x2f, 0x05, 0x32, 0x10, + 0xa0, 0x69, 0xa6, 0x8a, 0x91, 0x48, 0x2d, 0x20, 0xd3, 0xa6, 0xdf, 0x05, 0xd2, 0x5b, 0x2f, 0x94, + 0x85, 0xbb, 0x6d, 0xf0, 0x55, 0x25, 0xf2, 0x10, 0x48, 0x41, 0xf1, 0xdf, 0x6e, 0x7c, 0x45, 0xe4, + 0x17, 0x90, 0x7e, 0x6c, 0x3e, 0x79, 0x4a, 0x92, 0x42, 0x1c, 0xfc, 0x65, 0x24, 0xb1, 0x2e, 0x09, + 0x73, 0x69, 0xad, 0x23, 0xf9, 0x37, 0xc6, 0x8c, 0xaf, 0x52, 0xbc, 0xe9, 0x1a, 0xaf, 0x1c, 0xe8, + 0x0e, 0x9a, 0x53, 0x2d, 0x54, 0x81, 0xc3, 0x3b, 0x99, 0x93, 0x6e, 0x6a, 0xa6, 0x38, 0x48, 0xf1, + 0xfe, 0xf1, 0xba, 0x32, 0x48, 0xb8, 0xf3, 0x3c, 0xbd, 0x4d, 0x49, 0xad, 0xe3, 0x0e, 0x53, 0xca, + 0xe7, 0x54, 0x21, 0xfc, 0xfe, 0x97, 0xf1, 0xa4, 0x84, 0xcc, 0x66, 0xee, 0xc2, 0x69, 0x23, 0x4b, + 0x4a, 0x36, 0xeb, 0x6c, 0x51, 0x40, 0xf3, 0x30, 0xab, 0x6a, 0xff, 0xc4, 0x8d, 0x2d, 0xc4, 0x30, + 0xcf, 0x47, 0xd1, 0xd7, 0xe7, 0x08, 0xb3, 0xae, 0x79, 0x33, 0x19, 0x40, 0xeb, 0xe2, 0xb8, 0xad, + 0xbf, 0x1a, 0x7c, 0xaa, 0x32, 0xa8, 0x36, 0xbd, 0x55, 0xbd, 0x50, 0xb9, 0x78, 0xb8, 0xb9, 0xb5, + 0xea, 0xaa, 0xa2, 0x47, 0x7e, 0xaa, 0xab, 0xc4, 0x85, 0x0c, 0x7c, 0x35, 0x7f, 0x37, 0x1f, 0x66, + 0x0e, 0xeb, 0x04, 0x2a, 0x29, 0x2d, 0xf6, 0x33, 0x22, 0x81, 0x76, 0x28, 0x7d, 0x9b, 0x2e, 0x47, + 0x8c, 0x27, 0xa0, 0xab, 0x1b, 0xfc, 0x51, 0xdf, 0x8d, 0x95, 0x04, 0x59, 0x92, 0x52, 0xce, 0xbe, + 0x1c, 0x83, 0x74, 0x3b, 0x7e, 0x8f, 0x60, 0x74, 0x14, 0x82, 0x58, 0x94, 0x72, 0xed, 0x72, 0x29, + 0xc7, 0x97, 0xf1, 0xcc, 0x34, 0x9d, 0x4c, 0xf8, 0xec, 0xe2, 0xf5, 0xcb, 0xc8, 0xac, 0x7c, 0xf6, + 0x34, 0xbf, 0x8d, 0x23, 0x04, 0x07, 0x6c, 0xc3, 0xdb, 0x61, 0x81, 0x84, 0x2d, 0xb9, 0xb0, 0xe6, + 0xd6, 0xd3, 0xd4, 0xcf, 0xac, 0xdf, 0x43, 0x38, 0x2b, 0x95, 0xdb, 0x26, 0x7e, 0x36, 0xb0, 0xa0, + 0x80, 0x6b, 0x4a, 0xd5, 0x43, 0x7b, 0x0c, 0xad, 0xe7, 0x3d, 0x2b, 0x4b, 0x6c, 0x1e, 0x95, 0xec, + 0xac, 0x6b, 0xee, 0xee, 0xfe, 0x0b, 0x85, 0xa6, 0x04, 0x0b, 0x89, 0x20, 0xe4, 0x5b, 0x3d, 0xcc, + 0xf8, 0x7c, 0x7f, 0x84, 0xe4, 0x25, 0x90, 0x82, 0x42, 0x08, 0xcb, 0x35, 0xc0, 0xb2, 0xf1, 0x01, + 0xfc, 0x23, 0x20, 0x8a, 0xe0, 0x43, 0x8d, 0xc4, 0xb2, 0xb7, 0x6a, 0x5e, 0x3d, 0x70, 0xf9, 0x4f, + 0x27, 0xc7, 0x56, 0x18, 0x22, 0xf9, 0x78, 0x77, 0xcb, 0x81, 0xe2, 0x66, 0xb1, 0x93, 0x54, 0x34, + 0x02, 0xb3, 0x70, 0xdb, 0x46, 0xd3, 0xc7, 0xdf, 0x8e, 0xf5, 0x3b, 0x1b, 0x6e, 0xbb, 0x6b, 0x7f, + 0x08, 0xcc, 0xd6, 0x69, 0x9a, 0xcd, 0x22, 0xa6, 0x9b, 0x16, 0x2a, 0x2f, 0x66, 0x17, 0xb3, 0x3c, + 0x7f, 0x4c, 0x8c, 0x31, 0x96, 0x8f, 0x27, 0x2e, 0xe5, 0xd0, 0xd8, 0xca, 0x1c, 0x1f, 0x84, 0x29, + 0x22, 0x8d, 0x3d, 0x24, 0xa9, 0xa4, 0xda, 0x5e, 0x18, 0xb0, 0x36, 0x33, 0x10, 0x6a, 0xb7, 0x6c, + 0x76, 0xae, 0xab, 0xfe, 0x14, 0xa3, 0x8d, 0x30, 0xce, 0x53, 0x95, 0xec, 0x9f, 0xa9, 0xb4, 0xb6, + 0x71, 0xc8, 0xd8, 0x1d, 0x78, 0xd3, 0x36, 0x79, 0x6d, 0x03, 0x1a, 0x80, 0x27, 0xab, 0x52, 0x86, + 0xcb, 0xe9, 0x1c, 0x92, 0x97, 0x29, 0xba, 0xfa, 0x7d, 0x4f, 0x76, 0xad, 0xf8, 0x78, 0xcc, 0xf9, + 0x20, 0xc1, 0xa4, 0x71, 0x01, 0xc2, 0xd4, 0x2a, 0x99, 0x87, 0x4c, 0x72, 0xb7, 0x37, 0x6e, 0x6a, + 0x27, 0x1f, 0x8c, 0x12, 0xef, 0xbb, 0xe1, 0xd3, 0x3e, 0x2a, 0xbe, 0x5f, 0x4e, 0xc6, 0xfc, 0x3b, + 0x5d, 0xbe, 0x1a, 0xa6, 0x93, 0x34, 0x33, 0x8c, 0xb6, 0x43, 0xb3, 0x2a, 0xff, 0x0f, 0x19, 0x23, + 0x37, 0xa4, 0x5c, 0x9a, 0x23, 0x31, 0xbb, 0xce, 0x26, 0xef, 0xea, 0xaa, 0x4f, 0xe3, 0x4f, 0x41, + 0x90, 0x93, 0x28, 0x47, 0x8f, 0x27, 0x50, 0x2a, 0x36, 0x6e, 0x05, 0x8f, 0x25, 0xa2, 0x84, 0x53, + 0x22, 0x94, 0x43, 0x5f, 0x27, 0xea, 0x22, 0xb2, 0x75, 0x0c, 0xa5, 0xb0, 0xff, 0x0f, 0x69, 0x27, + 0x5a, 0x4b, 0x46, 0xf1, 0x24, 0x0c, 0x69, 0x8f, 0xa4, 0x36, 0x68, 0xd3, 0xd5, 0x72, 0xae, 0xcd, + 0xb3, 0x8b, 0x4d, 0x34, 0xd3, 0xf1, 0xa4, 0x54, 0xe6, 0xc6, 0xf6, 0x2a, 0x79, 0x05, 0x85, 0xa6, + 0xd8, 0xd9, 0xdc, 0x1d, 0x9c, 0x6d, 0x70, 0x9a, 0xd9, 0x9f, 0x2b, 0xff, 0x1b, 0xc6, 0x35, 0x81, + 0x66, 0xc3, 0x66, 0x76, 0x5a, 0x6d, 0x52, 0x24, 0x5b, 0x24, 0xea, 0x53, 0x1c, 0x65, 0xa7, 0xbe, + 0x09, 0x05, 0x94, 0x82, 0x52, 0x09, 0xc8, 0x2f, 0x20, 0xb1, 0xf3, 0xf5, 0xfc, 0xda, 0x6d, 0xf3, + 0x99, 0x8b, 0x08, 0xd8, 0x1d, 0x75, 0xcd, 0xdf, 0xf5, 0x9b, 0xe1, 0x31, 0x25, 0xc4, 0x0f, 0x97, + 0x0b, 0x84, 0xc6, 0x67, 0x96, 0x42, 0x12, 0x10, 0xb0, 0x85, 0x84, 0x3e, 0x09, 0x25, 0x21, 0x40, + 0xd0, 0x4d, 0x65, 0xf0, 0xfc, 0xd8, 0x7f, 0x6c, 0x7d, 0x96, 0xc2, 0x23, 0x0c, 0xc7, 0xd9, 0x2e, + 0x67, 0xa8, 0x66, 0x65, 0x1f, 0x4d, 0x36, 0xdb, 0xf1, 0x9c, 0xf6, 0x7b, 0x6a, 0x5b, 0x66, 0xbd, + 0x14, 0x1d, 0xec, 0xea, 0xa8, 0xf6, 0xfb, 0xf1, 0xb6, 0xdb, 0x88, 0xba, 0x4f, 0xf4, 0xdb, 0x71, + 0xe7, 0xdb, 0x67, 0x21, 0x1f, 0x3a, 0x4d, 0x34, 0xd3, 0x27, 0x8b, 0xf3, 0xf3, 0x9f, 0x4d, 0x31, + 0x29, 0x93, 0xd3, 0x3e, 0x15, 0xe2, 0xc1, 0x8b, 0x07, 0x9f, 0x1a, 0xce, 0x7d, 0x34, 0xcf, 0x4c, + 0x9e, 0x99, 0xf0, 0xfc, 0xb8, 0x5c, 0x66, 0x33, 0x0a, 0x42, 0xd2, 0x12, 0x90, 0xbb, 0xa6, 0xdc, + 0x06, 0x81, 0xe7, 0x3e, 0x9a, 0x67, 0xa6, 0x4f, 0x4c, 0xf8, 0x7e, 0x4c, 0x26, 0x13, 0x19, 0x8c, + 0xc6, 0x64, 0x07, 0x01, 0x93, 0x09, 0x90, 0x1c, 0x06, 0x3b, 0x87, 0xa6, 0x9c, 0x69, 0xf8, 0x30, + 0x90, 0x82, 0x42, 0x0e, 0x99, 0x7a, 0x6d, 0xee, 0x7d, 0x34, 0xd3, 0x4f, 0xc1, 0x84, 0xbf, 0x2f, + 0x21, 0x0c, 0xd8, 0x42, 0x0e, 0xe7, 0xd3, 0x4d, 0x34, 0xfc, 0x30, 0x71, 0xcd, 0x3e, 0x23, 0xc4, + 0x3c, 0x47, 0x9c, 0xf1, 0xd9, 0xd1, 0x0d, 0x10, 0xd1, 0x0d, 0x30, 0xd1, 0xb4, 0xdb, 0xfc, 0x2d, + 0xbc, 0x1d, 0x6c, 0x03, 0xdd, 0x2e, 0x02, 0x8e, 0xf2, 0x6d, 0xbf, 0x4f, 0xbf, 0xe0, 0x94, 0x99, + 0x28, 0x95, 0x76, 0xce, 0x55, 0xc7, 0x9c, 0xe3, 0xe5, 0x45, 0x34, 0x53, 0x45, 0x34, 0xd3, 0x59, + 0xb4, 0xdb, 0xe8, 0xc5, 0x4f, 0x82, 0x01, 0x4e, 0xe3, 0x83, 0xf7, 0x28, 0x48, 0xcc, 0x84, 0xf1, + 0xa4, 0xab, 0xb8, 0x66, 0x9e, 0x30, 0xd0, 0xc4, 0x20, 0x6e, 0xeb, 0x7f, 0xf8, 0x52, 0x91, 0x69, + 0xaf, 0xf7, 0xac, 0xb5, 0x63, 0x53, 0x5d, 0x4f, 0x3d, 0x36, 0x34, 0x6e, 0xca, 0x78, 0xfe, 0x43, + 0xf7, 0x18, 0xd1, 0x74, 0x02, 0x7c, 0x14, 0xc9, 0x7e, 0x20, 0xe8, 0x3e, 0x66, 0xf2, 0x73, 0xeb, + 0x67, 0x5c, 0xaf, 0x72, 0xa3, 0x73, 0x2a, 0xd7, 0xe9, 0x57, 0x84, 0x04, 0x33, 0x26, 0x0e, 0x3d, + 0x47, 0xeb, 0x9b, 0xab, 0x63, 0x4b, 0x17, 0x87, 0xc4, 0x8b, 0x93, 0x8b, 0xb3, 0xac, 0x86, 0x30, + 0x8a, 0x0c, 0x2c, 0x55, 0x8a, 0x09, 0x4d, 0x47, 0x79, 0x20, 0x93, 0xf7, 0x3c, 0x2f, 0x89, 0x12, + 0x30, 0xb2, 0x10, 0x64, 0x20, 0x90, 0xbd, 0x4b, 0x40, 0xc1, 0xe8, 0xd7, 0xb6, 0x0f, 0x51, 0xd4, + 0xf5, 0x16, 0x31, 0x58, 0xa3, 0xe2, 0x06, 0x8a, 0x9a, 0xb2, 0x78, 0xe2, 0x15, 0x99, 0x0a, 0x33, + 0x11, 0xfc, 0x0b, 0xee, 0x05, 0x64, 0x74, 0x44, 0x41, 0xa1, 0xca, 0xf2, 0xa0, 0x87, 0x74, 0x5d, + 0x7c, 0x5a, 0xfc, 0xf1, 0x52, 0xac, 0xff, 0xfc, 0x6c, 0x0c, 0xaa, 0x30, 0xc2, 0xd1, 0x26, 0xec, + 0xb0, 0x30, 0x16, 0x58, 0xce, 0x96, 0x7b, 0xf5, 0x51, 0x1e, 0xd6, 0x5f, 0x57, 0x6f, 0xaf, 0xd4, + 0xbf, 0xf1, 0xa5, 0x2c, 0xdc, 0xc1, 0xd6, 0x71, 0x93, 0x4a, 0x9b, 0x90, 0x0c, 0xe5, 0x80, 0x99, + 0xfd, 0x69, 0x9c, 0x41, 0x8e, 0xd7, 0xa6, 0x9e, 0xcb, 0x71, 0xc5, 0x2b, 0xc7, 0x2f, 0x4e, 0x6a, + 0xdf, 0x12, 0x14, 0xb3, 0x1c, 0x30, 0x59, 0x8c, 0xc6, 0x08, 0x0b, 0x04, 0x07, 0xa8, 0x64, 0xb3, + 0xcc, 0x8d, 0x37, 0xd5, 0x9e, 0x34, 0xe0, 0x1d, 0xb8, 0x98, 0x29, 0x12, 0x41, 0x92, 0xf6, 0x3c, + 0xea, 0x82, 0x7f, 0xb2, 0x23, 0x22, 0xe1, 0xec, 0x38, 0xb8, 0x9a, 0xf7, 0xc6, 0x65, 0xab, 0x0e, + 0xb5, 0xe9, 0x4c, 0xa4, 0x1a, 0x17, 0x4d, 0xa6, 0xd2, 0x3e, 0x98, 0x83, 0x5e, 0x5d, 0xf1, 0x9a, + 0xa6, 0x22, 0xea, 0xa1, 0xe1, 0xba, 0x94, 0x4d, 0x95, 0x4b, 0x51, 0xff, 0x0b, 0x90, 0x77, 0x27, + 0xc3, 0x2b, 0xc7, 0xef, 0xec, 0xda, 0x3a, 0xbb, 0xbb, 0xff, 0x8c, 0x2c, 0x4d, 0x44, 0xf5, 0x4a, + 0x50, 0xb1, 0xd6, 0x2c, 0x55, 0x15, 0x4c, 0xd6, 0x2e, 0x4c, 0x26, 0x78, 0xed, 0x6d, 0x1f, 0xee, + 0x9e, 0xdd, 0xff, 0xe3, 0x4d, 0x2f, 0x97, 0xea, 0xfb, 0x45, 0x61, 0xe4, 0x23, 0x97, 0x36, 0xd2, + 0xaa, 0xaa, 0xbf, 0xe1, 0x32, 0xe4, 0xa2, 0x2c, 0xa5, 0xd9, 0xb2, 0xf8, 0x44, 0xa7, 0x16, 0x69, + 0x0e, 0x31, 0xe4, 0x4b, 0xc4, 0xb5, 0xf3, 0xec, 0xb5, 0x29, 0xc8, 0x0f, 0xc6, 0x7b, 0x4e, 0xc1, + 0xb8, 0xa9, 0xd0, 0xf6, 0xe1, 0xb6, 0x6f, 0x6e, 0xa4, 0xc3, 0x4b, 0x33, 0xf1, 0xc4, 0x52, 0x10, + 0x93, 0xbe, 0x98, 0x20, 0xd0, 0xd5, 0x6c, 0x7a, 0xa8, 0xa6, 0x97, 0x02, 0x69, 0xae, 0x22, 0xf8, + 0x50, 0x66, 0xcc, 0x2d, 0x4a, 0x99, 0x83, 0xc6, 0xb2, 0x69, 0xac, 0x94, 0x5b, 0x32, 0x8e, 0x19, + 0x94, 0x3c, 0x30, 0x56, 0x31, 0xd1, 0xb2, 0x46, 0xdb, 0x6f, 0xf6, 0xea, 0x4f, 0xe3, 0x4b, 0xba, + 0xe5, 0xa1, 0xa0, 0x8f, 0x72, 0x4b, 0xaf, 0x4c, 0xb1, 0x6c, 0x5b, 0xff, 0x04, 0x04, 0x42, 0xb6, + 0x78, 0xd5, 0xfc, 0xf2, 0x53, 0xd1, 0x51, 0xa1, 0xd5, 0xa6, 0xd1, 0xb4, 0xba, 0x73, 0xbe, 0x0a, + 0xae, 0x72, 0x0a, 0xe8, 0x45, 0x16, 0x86, 0x19, 0x5d, 0x47, 0x02, 0x59, 0x84, 0x88, 0x2f, 0x8d, + 0xd6, 0xd2, 0xa3, 0xf0, 0xf0, 0xdd, 0xb0, 0x1f, 0xd9, 0x26, 0xd9, 0x89, 0xb0, 0x70, 0x63, 0xad, + 0xac, 0xfe, 0x5e, 0x9f, 0x87, 0x49, 0x6d, 0x36, 0xf3, 0xea, 0xd9, 0x3d, 0xbc, 0x8a, 0xf6, 0xdd, + 0x4e, 0x88, 0x96, 0xd2, 0xa9, 0xdf, 0xf0, 0xef, 0x46, 0x5d, 0xb1, 0xef, 0x3a, 0x33, 0x19, 0xc9, + 0xd0, 0x74, 0x9f, 0x1a, 0x09, 0x86, 0xda, 0x69, 0xdb, 0x4f, 0xe3, 0x71, 0x71, 0xa3, 0x33, 0xbf, + 0x57, 0x9f, 0x55, 0x72, 0xcf, 0x9e, 0x6d, 0x6a, 0x03, 0x35, 0xe2, 0xc7, 0x19, 0xc2, 0x69, 0xc3, + 0xd1, 0x55, 0x1f, 0x85, 0x8a, 0xd9, 0xf5, 0x2d, 0xd7, 0xaa, 0xe4, 0xc6, 0xd6, 0xc5, 0xff, 0x0d, + 0xcf, 0x36, 0x6c, 0xcb, 0xb5, 0x48, 0x9d, 0xe6, 0x68, 0x49, 0x24, 0xd3, 0x5e, 0x37, 0x32, 0x14, + 0x92, 0x3a, 0xca, 0xaa, 0x84, 0xce, 0x95, 0x4a, 0xe1, 0x6d, 0x9a, 0x2f, 0xef, 0x25, 0x5b, 0x93, + 0xf4, 0xd3, 0x4d, 0x3f, 0x19, 0x9e, 0x29, 0xee, 0x3f, 0xb2, 0x11, 0x8a, 0x79, 0xcf, 0x27, 0xc2, + 0x9d, 0x2f, 0x87, 0xba, 0x66, 0x96, 0x69, 0x64, 0xd1, 0xdc, 0xa9, 0xf5, 0x76, 0xae, 0x96, 0xd4, + 0x7f, 0xe4, 0xe3, 0xde, 0x5d, 0xef, 0x0f, 0x95, 0xdf, 0x55, 0x49, 0x25, 0x5d, 0x4f, 0x22, 0xc9, + 0x74, 0x72, 0xc8, 0xe6, 0xdb, 0x49, 0x2f, 0x04, 0x17, 0x75, 0x5a, 0x26, 0xd9, 0x0a, 0xa1, 0xdd, + 0x16, 0x4e, 0xd2, 0x68, 0xc2, 0xb3, 0x2a, 0x6d, 0xb6, 0xdb, 0xf0, 0xfc, 0xf8, 0xd5, 0x4d, 0x46, + 0x92, 0x6d, 0x64, 0xf8, 0xb5, 0x1f, 0x08, 0x62, 0xd3, 0x16, 0xdb, 0x6d, 0xbf, 0x0f, 0xd4, 0xbd, + 0xd7, 0x49, 0x26, 0x8d, 0x85, 0xa5, 0x62, 0xc4, 0xb7, 0xa4, 0x49, 0xb6, 0xdb, 0x6d, 0xf8, 0x7e, + 0xaa, 0xab, 0xd5, 0x52, 0x48, 0x9e, 0x28, 0x3e, 0xdb, 0x6d, 0xb7, 0xe1, 0x8a, 0xac, 0xd0, 0xcb, + 0xcc, 0xd7, 0x22, 0x7a, 0x5d, 0x8d, 0x47, 0x30, 0xd7, 0xfa, 0xbf, 0xc1, 0x24, 0x73, 0xd1, 0x78, + 0xff, 0x04, 0x9d, 0xdf, 0x7f, 0x12, 0x1c, 0xaa, 0xe2, 0x00, 0x04, 0x2a, 0x71, 0x6c, 0x5b, 0xff, + 0x3d, 0x45, 0xb1, 0x6d, 0x04, 0x82, 0xff, 0x05, 0xf1, 0x5a, 0xed, 0x34, 0x2b, 0x68, 0xa3, 0xda, + 0x68, 0xef, 0xfd, 0x73, 0x95, 0x71, 0x68, 0x5a, 0xff, 0x04, 0x33, 0xe1, 0xf3, 0xf1, 0xf0, 0xdc, + 0xf8, 0x7c, 0x69, 0xd8, 0x64, 0xb3, 0x99, 0x8d, 0x7f, 0x82, 0x0b, 0x31, 0xe4, 0x27, 0xcf, 0xdb, + 0x3f, 0x77, 0x2b, 0xd8, 0x3d, 0xa4, 0x74, 0x90, 0xe0, 0x79, 0xf3, 0x25, 0x49, 0x47, 0xb1, 0x79, + 0xcf, 0x1a, 0x67, 0xa5, 0xa6, 0xa9, 0x07, 0xeb, 0xbd, 0x1a, 0x33, 0xf7, 0x90, 0x7e, 0x9b, 0x24, + 0x58, 0xfd, 0x54, 0x61, 0xd5, 0x63, 0xdf, 0xff, 0x1a, 0x51, 0xe3, 0x44, 0x3c, 0x78, 0xd9, 0xa3, + 0x53, 0x8a, 0x31, 0x9a, 0x9c, 0x67, 0x47, 0x68, 0xdc, 0x36, 0xa7, 0x05, 0xbe, 0xaa, 0xab, 0xe3, + 0x6a, 0x9c, 0xe1, 0xbc, 0x94, 0x31, 0xfc, 0x9d, 0x71, 0x57, 0x48, 0xec, 0x36, 0x94, 0x75, 0xb1, + 0x5f, 0x47, 0xb1, 0x78, 0xbc, 0x57, 0x15, 0xf1, 0x23, 0xc4, 0x2d, 0xb9, 0x4b, 0x36, 0xec, 0xd6, + 0x49, 0x5c, 0x9b, 0xc2, 0x03, 0x4e, 0xc7, 0xb9, 0x81, 0xe5, 0x92, 0xce, 0x49, 0x49, 0x75, 0x6f, + 0x67, 0x19, 0x72, 0x2b, 0x46, 0x8c, 0xd0, 0x5a, 0xff, 0x8c, 0x28, 0xe7, 0x67, 0x70, 0xd8, 0x35, + 0x76, 0x16, 0x10, 0x9a, 0xb8, 0x87, 0x0d, 0x22, 0x90, 0x43, 0x9a, 0x77, 0x61, 0xb0, 0x41, 0x69, + 0x88, 0xcb, 0x05, 0x53, 0x78, 0xd1, 0x03, 0x2a, 0xf8, 0x3d, 0xe1, 0xe7, 0x8f, 0x7b, 0x0e, 0xda, + 0xa4, 0x79, 0xf2, 0xa2, 0x68, 0x07, 0x27, 0xc7, 0x7e, 0xe3, 0x1e, 0x51, 0x40, 0x4d, 0x44, 0xe8, + 0xc5, 0xd9, 0x16, 0x2f, 0x3c, 0x48, 0xdc, 0xc1, 0xe9, 0xa6, 0xd2, 0x0c, 0xf6, 0x73, 0x4d, 0xfe, + 0x53, 0xa3, 0x6b, 0xb8, 0xf9, 0x6e, 0xeb, 0xc4, 0x0d, 0x38, 0xbb, 0x26, 0x28, 0x84, 0xbd, 0x96, + 0x31, 0x9e, 0xe6, 0x60, 0xa5, 0x72, 0x8b, 0x91, 0xab, 0xad, 0x47, 0x28, 0xe3, 0xaa, 0x63, 0x3e, + 0x3e, 0xab, 0x5c, 0x4c, 0x3a, 0x74, 0xeb, 0x4d, 0xc4, 0xd7, 0xa6, 0x5b, 0xa3, 0xe1, 0x8e, 0x28, + 0xd2, 0x53, 0x2e, 0x27, 0x2a, 0x63, 0x1e, 0x26, 0x89, 0x7b, 0x2b, 0x3f, 0xdb, 0x78, 0x88, 0xc2, + 0x16, 0xdc, 0x56, 0x2b, 0x15, 0xb8, 0xac, 0x40, 0xa8, 0x15, 0x8a, 0xc5, 0x62, 0xba, 0x4d, 0xa1, + 0x71, 0x21, 0x42, 0xcf, 0xf4, 0xe9, 0xc7, 0xbb, 0x7d, 0x4d, 0x40, 0x7f, 0xa4, 0xcd, 0x03, 0x6f, + 0x84, 0x66, 0xd7, 0xee, 0x14, 0x5a, 0x3d, 0x04, 0x48, 0x26, 0x81, 0x75, 0xb1, 0xf8, 0x2c, 0x10, + 0xd0, 0xd1, 0x83, 0xd5, 0x9c, 0xf2, 0x56, 0x73, 0xb9, 0x11, 0x7c, 0x53, 0xaf, 0xe0, 0xa7, 0x3a, + 0x3b, 0x76, 0xac, 0x86, 0x26, 0x73, 0xa2, 0x8f, 0x98, 0x6b, 0xaa, 0xbf, 0x84, 0x48, 0x19, 0x53, + 0x5b, 0x15, 0x26, 0x9b, 0x69, 0xbc, 0x66, 0xf2, 0xaa, 0xf1, 0xa2, 0x9f, 0x71, 0x22, 0xa0, 0xda, + 0x13, 0xdd, 0x0f, 0xce, 0x13, 0x22, 0x5b, 0x7a, 0x4b, 0x86, 0x4c, 0x09, 0x7e, 0xd9, 0xa1, 0xc3, + 0x00, 0xed, 0x49, 0xd6, 0x6d, 0xbb, 0xf8, 0x50, 0xad, 0x82, 0x36, 0x5b, 0x44, 0x28, 0x27, 0xcd, + 0x36, 0x18, 0xb2, 0xd8, 0x20, 0xe8, 0xec, 0x93, 0xd0, 0x15, 0xf1, 0x87, 0xca, 0xb9, 0x3b, 0x93, + 0x55, 0xf6, 0x1b, 0x8f, 0xa0, 0x2a, 0x41, 0xcf, 0xef, 0x00, 0x29, 0x9b, 0xc6, 0xef, 0xe3, 0x27, + 0x89, 0xbe, 0x7b, 0x54, 0x13, 0xa5, 0xc5, 0x5d, 0x4c, 0xf4, 0x51, 0xf8, 0x41, 0xd5, 0x28, 0x49, + 0x71, 0x7a, 0x17, 0x8c, 0x8e, 0xbe, 0xde, 0x89, 0x41, 0x0d, 0x81, 0xd0, 0x97, 0x27, 0x35, 0x47, + 0x16, 0xa6, 0x65, 0x0e, 0xb2, 0x35, 0x68, 0x6f, 0x08, 0x02, 0xbb, 0x0b, 0xc2, 0x04, 0x6a, 0x62, + 0x10, 0xc2, 0xea, 0xb5, 0x98, 0x34, 0x8a, 0x6e, 0x4e, 0x91, 0x0e, 0x09, 0x17, 0x8d, 0x15, 0x3b, + 0x92, 0xfa, 0x18, 0x37, 0x73, 0x65, 0xda, 0x5b, 0x0c, 0xc7, 0xa8, 0xbf, 0x4e, 0x2d, 0xf8, 0x76, + 0x7e, 0xda, 0x69, 0xd9, 0xb7, 0x17, 0x2d, 0x9f, 0xf1, 0xec, 0x1e, 0x5b, 0x1d, 0x1a, 0x1f, 0xe0, + 0x82, 0xca, 0x15, 0xa3, 0xac, 0x9c, 0xf7, 0xb4, 0x9a, 0x71, 0x41, 0x0d, 0x47, 0xb1, 0x15, 0x97, + 0xb7, 0xfe, 0x34, 0xad, 0x20, 0x86, 0x18, 0xbe, 0x2f, 0xc5, 0xbe, 0x6b, 0x2f, 0x4d, 0xd5, 0xa4, + 0xad, 0xd2, 0xec, 0x71, 0xff, 0x82, 0xfd, 0xd7, 0x40, 0xf1, 0xa4, 0x6b, 0x7c, 0x8f, 0x3e, 0x2d, + 0x8b, 0x7f, 0x87, 0x6d, 0x20, 0xc0, 0x6b, 0x72, 0xc8, 0x42, 0xcc, 0x9a, 0xa1, 0x65, 0x12, 0xb2, + 0xc9, 0xd1, 0xcd, 0x3c, 0xd0, 0xb6, 0x5d, 0xff, 0x8d, 0xb3, 0x67, 0x13, 0x97, 0x19, 0xd3, 0x3c, + 0x36, 0xd2, 0x35, 0x5f, 0x38, 0xf5, 0xfa, 0x69, 0xa6, 0x9f, 0x8d, 0xc3, 0xff, 0xab, 0xb4, 0x5d, + 0xa2, 0xa6, 0x9a, 0x4e, 0xc3, 0xba, 0x9b, 0x1a, 0x1a, 0x07, 0xcf, 0x25, 0x4d, 0x9a, 0xd5, 0x69, + 0xa6, 0x9a, 0x7e, 0x0b, 0xe4, 0xd1, 0xdc, 0x16, 0x5b, 0x3c, 0x6d, 0xa9, 0x77, 0x5c, 0x62, 0x5a, + 0x69, 0xa6, 0x9f, 0x8d, 0x2c, 0x25, 0x7c, 0x89, 0x66, 0x4a, 0x11, 0x1a, 0xc6, 0x8d, 0xa8, 0x3b, + 0xed, 0x9e, 0x07, 0x4b, 0x76, 0x28, 0xe9, 0xa6, 0x9a, 0x7e, 0x08, 0x23, 0x03, 0x06, 0x1e, 0xe3, + 0x49, 0xcd, 0x7c, 0x2d, 0x36, 0xc5, 0xba, 0xa7, 0x1a, 0x49, 0x26, 0x9a, 0x69, 0xf8, 0xdb, 0x27, + 0xe3, 0xdd, 0x46, 0xb6, 0x6a, 0x6a, 0x18, 0x4b, 0x42, 0xca, 0x8e, 0xb6, 0x28, 0x6f, 0x52, 0x85, + 0x6b, 0xe9, 0xa6, 0x9a, 0x7e, 0x1d, 0xbe, 0xcb, 0xd3, 0xee, 0xb8, 0x66, 0xf3, 0x30, 0xbe, 0x9a, + 0x69, 0xa7, 0xe1, 0xb8, 0xff, 0x6f, 0xa1, 0xb1, 0x53, 0x4d, 0xb6, 0xff, 0xc2, 0x94, 0x92, 0x49, + 0x27, 0x77, 0x73, 0xfa, 0xea, 0x6e, 0x99, 0x89, 0x3c, 0x82, 0xff, 0x0b, 0xd8, 0x1e, 0x4d, 0x49, + 0x6e, 0x83, 0xfe, 0x71, 0x18, 0x8e, 0x92, 0x19, 0x81, 0x14, 0xc9, 0xc9, 0x94, 0x92, 0x16, 0x85, + 0xaf, 0x05, 0x98, 0x69, 0x4f, 0x0f, 0xf5, 0xe5, 0x9e, 0xf2, 0xa7, 0x24, 0xc4, 0x66, 0x3b, 0xfc, + 0x35, 0x2d, 0x7a, 0x42, 0x74, 0x3b, 0xc5, 0x58, 0xab, 0x49, 0x24, 0x92, 0xf0, 0xbd, 0xa1, 0xbc, + 0xd8, 0x34, 0x0b, 0x49, 0x64, 0xd8, 0xda, 0x2b, 0x4d, 0x24, 0x97, 0xf8, 0x26, 0xed, 0xa9, 0x67, + 0x16, 0x8d, 0xb2, 0x90, 0x5c, 0xf8, 0x20, 0x86, 0xf7, 0x7a, 0xd6, 0x8a, 0x3a, 0xc7, 0x55, 0xb0, + 0x53, 0x9f, 0xc8, 0xa0, 0xcb, 0xa2, 0x74, 0x4d, 0x26, 0xb3, 0x87, 0xfe, 0x36, 0xca, 0xae, 0x8c, + 0xd8, 0x4d, 0x6d, 0x2c, 0xd0, 0x6f, 0x75, 0x1b, 0xe4, 0x67, 0xa1, 0xca, 0xa6, 0x98, 0xab, 0x15, + 0x78, 0x94, 0xc8, 0x94, 0xcf, 0x85, 0xcb, 0xcf, 0x91, 0xec, 0xcd, 0xae, 0xde, 0x83, 0x34, 0x92, + 0x3b, 0xff, 0xfc, 0x29, 0x8e, 0x51, 0x95, 0x6e, 0xb6, 0xd9, 0x70, 0xf2, 0x93, 0x40, 0xd6, 0x36, + 0x34, 0x82, 0xfe, 0xf2, 0x0d, 0x7d, 0xf1, 0x90, 0xc2, 0x94, 0xe2, 0x68, 0xa5, 0x4a, 0x55, 0xe5, + 0x5e, 0x56, 0xa3, 0x48, 0xe4, 0xbd, 0x34, 0xd9, 0xf8, 0x20, 0x9f, 0x9f, 0x9f, 0xbf, 0x8c, 0xc0, + 0x38, 0xe3, 0x49, 0x49, 0xdf, 0xdc, 0x6f, 0x47, 0xfd, 0xb6, 0xdb, 0x6f, 0xc1, 0x24, 0xab, 0x6c, + 0xe2, 0xf8, 0xc9, 0xc8, 0x4e, 0x42, 0x72, 0x1a, 0x46, 0x20, 0x95, 0x65, 0x0e, 0x86, 0x1a, 0x2a, + 0xa7, 0xaa, 0x6a, 0xa7, 0xaa, 0x8e, 0x36, 0x15, 0x80, 0xfc, 0x3b, 0x97, 0xd3, 0xb7, 0x23, 0x12, + 0x29, 0x62, 0x8f, 0x8e, 0x9f, 0x6d, 0xb6, 0xdb, 0xf0, 0x5d, 0x6d, 0xa4, 0x17, 0x2a, 0x66, 0x49, + 0xe8, 0xa2, 0xf8, 0xd3, 0x31, 0xb8, 0xe4, 0x75, 0x30, 0x3d, 0x94, 0x4e, 0x14, 0x89, 0x87, 0x0c, + 0xfe, 0x07, 0x06, 0x66, 0x1b, 0xa3, 0x45, 0x79, 0x70, 0x72, 0xc5, 0x1f, 0xf8, 0xda, 0x63, 0xa0, + 0x00, 0x9d, 0xd4, 0x8d, 0x0c, 0xce, 0x63, 0x9b, 0x8f, 0x36, 0x8e, 0x72, 0x26, 0x68, 0x42, 0xfb, + 0x6a, 0x20, 0x0b, 0xf5, 0x55, 0x5f, 0x1b, 0x0c, 0xfd, 0x4e, 0x27, 0x4e, 0xa2, 0x49, 0xbd, 0xe7, + 0x0e, 0x7d, 0xdd, 0xec, 0xeb, 0xea, 0xaa, 0xbe, 0x14, 0xe9, 0xd3, 0x72, 0xf4, 0x0d, 0xac, 0x07, + 0xa9, 0xe4, 0x2a, 0x56, 0x3d, 0xb4, 0x37, 0x78, 0x80, 0x56, 0x20, 0xea, 0x56, 0x30, 0xdf, 0x58, + 0xa8, 0x3f, 0x8d, 0x16, 0x9e, 0xf8, 0x1e, 0xa4, 0xa4, 0xeb, 0xc4, 0x94, 0x68, 0xc4, 0x64, 0x75, + 0xb0, 0xb8, 0x91, 0x93, 0xd3, 0xc9, 0x77, 0x24, 0x18, 0xa4, 0x25, 0xef, 0xaa, 0xa9, 0xd8, 0x24, + 0x67, 0x08, 0x2c, 0xc5, 0xfc, 0x1e, 0xf8, 0x81, 0xa4, 0xe3, 0x69, 0x0a, 0xeb, 0xef, 0x52, 0x5e, + 0x23, 0x43, 0xb4, 0x72, 0x4a, 0xab, 0x62, 0x63, 0x9c, 0x98, 0xc9, 0x3a, 0xf2, 0x23, 0xac, 0x9d, + 0xbf, 0xc6, 0xe5, 0x0a, 0x12, 0x15, 0x06, 0xd9, 0xd9, 0xad, 0x9a, 0x18, 0xf7, 0xdf, 0xf6, 0x32, + 0x19, 0x5d, 0x6c, 0xbf, 0x55, 0x5e, 0x24, 0x21, 0x4e, 0xbc, 0xcc, 0x2a, 0x76, 0xb5, 0xbd, 0xf8, + 0x98, 0xc2, 0xb5, 0x53, 0x06, 0xc1, 0xd0, 0xc1, 0xdb, 0xb1, 0x8b, 0xd0, 0xdb, 0xaf, 0x83, 0x10, + 0x20, 0x6b, 0x38, 0x90, 0x59, 0x5a, 0x93, 0x05, 0x59, 0x7d, 0x13, 0xab, 0x8f, 0x7d, 0xb9, 0x4f, + 0xe2, 0x06, 0x14, 0x98, 0xcc, 0x7e, 0x54, 0x91, 0x23, 0x08, 0xfd, 0x34, 0x22, 0x6b, 0x28, 0xae, + 0xda, 0x7e, 0x14, 0x10, 0x72, 0x0f, 0xe2, 0xb8, 0x9b, 0x60, 0xd2, 0x77, 0x76, 0xed, 0xb4, 0x7d, + 0x7f, 0x82, 0xb3, 0xaf, 0x6f, 0x6c, 0x28, 0x74, 0xda, 0x45, 0x02, 0x3b, 0x5c, 0x84, 0x18, 0x7c, + 0x73, 0xe3, 0x2c, 0x56, 0x8e, 0xb8, 0xf2, 0xb3, 0xf8, 0x37, 0xa9, 0x61, 0xd1, 0x17, 0xa4, 0xdf, + 0xf8, 0x4c, 0xa6, 0x5c, 0xbc, 0xf2, 0xac, 0x6e, 0xde, 0x8b, 0xe3, 0x4c, 0x4f, 0x93, 0x93, 0xa4, + 0xf0, 0x40, 0x18, 0x9f, 0x88, 0xb3, 0xaf, 0x5b, 0xb0, 0x68, 0xef, 0xee, 0xef, 0xe0, 0x80, 0xcd, + 0xb6, 0x69, 0x77, 0x48, 0xd3, 0x22, 0x1e, 0x81, 0xb0, 0x33, 0x88, 0x2b, 0x06, 0x10, 0xed, 0x55, + 0x55, 0x77, 0x77, 0xf0, 0x58, 0x24, 0x68, 0x58, 0xae, 0x11, 0xd7, 0x01, 0x02, 0xf3, 0x4c, 0x8c, + 0x85, 0x7c, 0x25, 0x88, 0x28, 0x6b, 0xc8, 0xbb, 0x01, 0x05, 0xfe, 0x14, 0x26, 0xc1, 0x63, 0x27, + 0x78, 0x55, 0x36, 0x88, 0x17, 0x4d, 0xaf, 0x8d, 0xac, 0x42, 0xb7, 0x4d, 0x15, 0xd7, 0x1c, 0x82, + 0xc4, 0x5c, 0xe4, 0x54, 0xfc, 0x20, 0x70, 0x45, 0xf1, 0xd8, 0x4b, 0x2f, 0x17, 0x17, 0xc8, 0xad, + 0x8f, 0xd5, 0x55, 0x26, 0x3b, 0xce, 0x88, 0xc8, 0x06, 0xc0, 0xe0, 0xd0, 0xd1, 0xa7, 0x07, 0x8c, + 0xa2, 0x76, 0x8e, 0xc0, 0x1e, 0x62, 0x4e, 0xe9, 0x31, 0x87, 0x5a, 0xf7, 0xca, 0xfc, 0xa8, 0xff, + 0xcf, 0x5d, 0x5f, 0xe5, 0x32, 0x50, 0xe1, 0x78, 0xca, 0x8f, 0x70, 0x56, 0x0c, 0xb9, 0x40, 0xe0, + 0x6c, 0x18, 0xf4, 0x4c, 0x4c, 0x19, 0xd4, 0x3b, 0xcf, 0x78, 0xc2, 0x3d, 0x5b, 0x67, 0x44, 0xa4, + 0x6a, 0x9c, 0xca, 0x36, 0x50, 0x95, 0x7d, 0xbe, 0x28, 0x06, 0x30, 0xbe, 0x34, 0x44, 0xa5, 0x12, + 0x84, 0x18, 0xd7, 0x1a, 0x56, 0xe2, 0xae, 0xd2, 0xb4, 0xe0, 0xf1, 0x52, 0xd6, 0xe9, 0xbb, 0xf8, + 0x7e, 0xed, 0xd6, 0x0d, 0xb8, 0x29, 0xca, 0xa6, 0xe5, 0xcf, 0x60, 0xb2, 0x6a, 0xfa, 0x69, 0xa6, + 0x9f, 0x87, 0x4e, 0xeb, 0xfb, 0xbe, 0xbb, 0x22, 0xd4, 0xec, 0x36, 0xc2, 0x2d, 0x05, 0x98, 0xa6, + 0x98, 0x9e, 0xc7, 0xfe, 0x0a, 0xae, 0xa3, 0xa9, 0xcc, 0x98, 0xde, 0x0d, 0x2b, 0x21, 0xc5, 0xfa, + 0x1a, 0x74, 0x90, 0x1f, 0xe0, 0xa6, 0xb4, 0xfb, 0x6c, 0x8d, 0x06, 0x63, 0x9f, 0xe6, 0xbc, 0x22, + 0x7f, 0x5d, 0x21, 0x6d, 0xf0, 0xa6, 0x99, 0x66, 0xf4, 0x28, 0x88, 0xa5, 0x1c, 0x06, 0xfa, 0xd0, + 0xca, 0xc3, 0x21, 0xc5, 0x7f, 0x0a, 0x73, 0x09, 0x18, 0xdb, 0x7d, 0x91, 0x96, 0xe1, 0xb2, 0x71, + 0xb8, 0xb3, 0x5f, 0x61, 0x09, 0xdb, 0x90, 0x11, 0xf1, 0xb5, 0x55, 0x50, 0xe3, 0x1f, 0xd1, 0xec, + 0x65, 0x6b, 0xdc, 0xd6, 0x28, 0xc3, 0xec, 0x6a, 0xb6, 0xd6, 0x0d, 0xcf, 0x10, 0xeb, 0x7f, 0xe3, + 0x6e, 0xd3, 0x57, 0xa7, 0x43, 0x57, 0x56, 0x98, 0xdb, 0x1b, 0x4c, 0xc1, 0xe7, 0x3f, 0x55, 0x5f, + 0x0a, 0x53, 0x96, 0x88, 0xdc, 0x9e, 0xea, 0xb6, 0xfa, 0x35, 0xb6, 0xae, 0x84, 0x56, 0x00, 0x14, + 0x04, 0xf8, 0xc2, 0xd9, 0xa6, 0x67, 0xb7, 0x29, 0x9e, 0x3d, 0xc7, 0x95, 0x43, 0xc6, 0xad, 0xba, + 0x09, 0xb7, 0xf6, 0x2f, 0xe3, 0x6c, 0x4a, 0xcc, 0xda, 0x66, 0x43, 0x28, 0xfb, 0xd2, 0x40, 0x0c, + 0xcf, 0xd8, 0x41, 0x75, 0xa1, 0x41, 0x29, 0x9e, 0x77, 0x99, 0xef, 0x7f, 0xf8, 0xda, 0x91, 0xdb, + 0xc0, 0x34, 0x04, 0x4f, 0xf5, 0x13, 0x4e, 0x59, 0xf1, 0x25, 0x92, 0xff, 0x1d, 0x3f, 0x6d, 0xb6, + 0xdb, 0xf1, 0xe4, 0xab, 0xbc, 0xcb, 0xba, 0xaf, 0xe0, 0xae, 0x92, 0x49, 0x17, 0x07, 0x79, 0xee, + 0xcb, 0x84, 0xec, 0xe9, 0xe2, 0xf8, 0x7e, 0xd5, 0x4d, 0x3d, 0x36, 0x34, 0xf4, 0x96, 0x28, 0xb4, + 0x2d, 0x24, 0x97, 0xf8, 0xce, 0x69, 0xdd, 0xd1, 0xa3, 0x66, 0xd8, 0x48, 0xfa, 0xb7, 0xc0, 0xd5, + 0xff, 0x8d, 0x8a, 0x98, 0xa9, 0xf5, 0x54, 0x92, 0x47, 0x69, 0x5a, 0xc7, 0x07, 0x51, 0x18, 0x33, + 0xb8, 0xbe, 0xdb, 0x6d, 0xb7, 0xe1, 0x8b, 0xb7, 0x74, 0x92, 0xa6, 0x23, 0x27, 0xdb, 0x6d, 0xb6, + 0xfc, 0x17, 0xd8, 0xda, 0xac, 0xf9, 0x76, 0x64, 0xa7, 0xdc, 0x72, 0x5b, 0x35, 0xb6, 0xdb, 0x6f, + 0xc3, 0x12, 0x90, 0xa0, 0x68, 0xcc, 0x4a, 0xe4, 0x51, 0x94, 0xa4, 0xd6, 0x98, 0xe9, 0xd7, 0x5b, + 0x6d, 0xf8, 0xda, 0x49, 0x68, 0x27, 0xd3, 0xd3, 0x35, 0x25, 0x20, 0x93, 0x58, 0xc4, 0x49, 0x15, + 0x37, 0x33, 0xb1, 0xf9, 0xb5, 0xa2, 0xd6, 0x2a, 0xfc, 0x3d, 0x2d, 0x1b, 0x4a, 0x74, 0xd9, 0x5e, + 0x46, 0xec, 0x24, 0xa6, 0xad, 0x59, 0xcf, 0x8a, 0xb1, 0x57, 0xf8, 0xd9, 0x33, 0x59, 0xae, 0x81, + 0x96, 0xb0, 0xd3, 0xb0, 0x32, 0x1b, 0xf6, 0xdf, 0x1d, 0xaa, 0x98, 0x67, 0x55, 0xc6, 0xb8, 0xd4, + 0xbf, 0xf0, 0xf6, 0x47, 0x4f, 0x1c, 0x86, 0xd1, 0x2b, 0x18, 0x8d, 0x3f, 0x2e, 0x2d, 0x58, 0x75, + 0xb3, 0x58, 0x45, 0xff, 0xc6, 0xd0, 0xd1, 0xdb, 0x91, 0x86, 0xd1, 0x64, 0x23, 0x83, 0xbd, 0x61, + 0xb9, 0xe8, 0xdf, 0x28, 0x4b, 0xed, 0xb6, 0xdb, 0x7e, 0x1d, 0x22, 0xaf, 0xa9, 0xce, 0x9b, 0xaa, + 0xb4, 0x68, 0x42, 0xf5, 0x47, 0x4f, 0x2f, 0xb6, 0x7d, 0x6e, 0xbf, 0x0c, 0x51, 0xa0, 0x62, 0xcc, + 0x59, 0xee, 0xf3, 0x11, 0x99, 0x4a, 0x65, 0x0e, 0xdb, 0x54, 0x69, 0x8a, 0xb1, 0x57, 0xe0, 0x82, + 0x7f, 0x9f, 0xc6, 0xda, 0x15, 0xb4, 0x43, 0x86, 0xda, 0x92, 0xde, 0xcc, 0x2a, 0xc6, 0x9b, 0x6d, + 0xb6, 0xdb, 0x6d, 0xf8, 0x76, 0x56, 0xd2, 0x3b, 0x76, 0x37, 0x6d, 0x14, 0x1c, 0x8a, 0x89, 0xab, + 0xda, 0x35, 0x3f, 0xc1, 0x4e, 0xa8, 0x34, 0x12, 0x26, 0xc2, 0x8c, 0xb4, 0x93, 0x0c, 0x6f, 0x2d, + 0x5b, 0x6d, 0x8f, 0x87, 0x4a, 0x54, 0x10, 0xa2, 0x3a, 0x48, 0xe8, 0xd0, 0x5d, 0xe8, 0x37, 0x55, + 0x77, 0x77, 0x55, 0x55, 0xf0, 0x57, 0x91, 0xd6, 0xc7, 0xb3, 0xb2, 0xbf, 0xc7, 0x62, 0x15, 0x35, + 0x76, 0x8f, 0x1e, 0xf8, 0x50, 0x44, 0x1b, 0xa1, 0x95, 0x16, 0xd9, 0x8c, 0x5b, 0x23, 0x09, 0x5f, + 0xba, 0x93, 0x34, 0xa5, 0xf0, 0x80, 0xd4, 0x9b, 0x8a, 0x92, 0x4c, 0xca, 0x22, 0xed, 0x7e, 0x28, + 0xb8, 0x90, 0x5a, 0x64, 0x5a, 0xc8, 0x36, 0xd1, 0x55, 0x8b, 0x3b, 0x9d, 0x3e, 0x34, 0xe5, 0x23, + 0xa8, 0x7d, 0xd1, 0x94, 0x9b, 0x48, 0x49, 0x6f, 0x53, 0x85, 0x98, 0xcd, 0x03, 0x06, 0x05, 0xa1, + 0x85, 0x53, 0xc1, 0x8f, 0x83, 0x29, 0x9c, 0x0d, 0x31, 0x89, 0xbf, 0x77, 0x7f, 0x05, 0x75, 0x0e, + 0x96, 0x63, 0x14, 0xab, 0x74, 0x8f, 0x99, 0x0f, 0xfa, 0x07, 0xd5, 0x20, 0xe6, 0x2a, 0x8b, 0x7e, + 0xf8, 0x52, 0xb3, 0x96, 0x18, 0x5e, 0xc7, 0x4e, 0x80, 0x1d, 0x36, 0x5c, 0x01, 0x1b, 0x19, 0x70, + 0x6b, 0x81, 0xd3, 0x60, 0x20, 0x3d, 0xb4, 0x22, 0x00, 0xda, 0xa5, 0x8f, 0x34, 0x86, 0xfd, 0x5e, + 0xeb, 0xf0, 0xf2, 0x20, 0xc2, 0xc7, 0x9f, 0x0a, 0x12, 0x4e, 0xca, 0xf9, 0xc8, 0x6d, 0xa7, 0xba, + 0xf6, 0x55, 0x67, 0xa3, 0x5e, 0xe8, 0x3c, 0xac, 0x23, 0xbc, 0x4c, 0x10, 0x1c, 0x61, 0x32, 0xc5, + 0x29, 0x14, 0x9a, 0xd4, 0x22, 0x60, 0x3e, 0xc3, 0x65, 0x9c, 0xd7, 0x4c, 0x35, 0x7a, 0xd0, 0xa6, + 0x8a, 0xa0, 0x37, 0xfe, 0x5e, 0x9f, 0x12, 0x33, 0x41, 0x8f, 0xfa, 0x8b, 0x7d, 0xf3, 0x31, 0xcf, + 0xd8, 0x04, 0x80, 0x00, 0x19, 0xd7, 0x89, 0x18, 0x67, 0x5b, 0x6c, 0x60, 0x63, 0x63, 0x77, 0x2c, + 0x17, 0x73, 0x98, 0x62, 0x8b, 0xd8, 0xaf, 0xc1, 0x49, 0x51, 0xb3, 0x7e, 0xc7, 0x51, 0x98, 0x82, + 0x6c, 0x5a, 0xa1, 0xbd, 0x6f, 0x8d, 0x05, 0xdf, 0x09, 0xce, 0x64, 0xd2, 0x2e, 0xfa, 0x7a, 0x7e, + 0x3e, 0x4c, 0x26, 0x78, 0xc5, 0xca, 0xcc, 0xca, 0x4d, 0xca, 0x26, 0x51, 0xe1, 0xf1, 0x11, 0x35, + 0x9b, 0x16, 0x09, 0xf7, 0x53, 0x4d, 0x5a, 0x55, 0x55, 0x57, 0x77, 0x7f, 0x0e, 0x9c, 0x27, 0x71, + 0x4f, 0x16, 0x4d, 0x50, 0x96, 0xce, 0x5d, 0x1e, 0xad, 0x62, 0xa8, 0xba, 0x8e, 0xfd, 0xdd, 0xdf, + 0xc6, 0x16, 0x03, 0x56, 0x3a, 0x86, 0xe5, 0xd6, 0x9a, 0x2f, 0x45, 0x68, 0x29, 0x90, 0xde, 0xee, + 0xf4, 0x72, 0xdf, 0x21, 0x80, 0xe9, 0xee, 0x30, 0xc0, 0x07, 0x6a, 0xfc, 0xd3, 0x0c, 0xdb, 0x80, + 0x29, 0x5f, 0x8c, 0x23, 0xdd, 0x01, 0x87, 0x18, 0x29, 0xaa, 0xcc, 0x80, 0x79, 0x2d, 0xe3, 0x0d, + 0x0a, 0x93, 0xdc, 0x6a, 0xa0, 0x42, 0xb2, 0xe4, 0xb0, 0xd4, 0x37, 0x40, 0x7e, 0x14, 0xe3, 0x10, + 0xec, 0x06, 0xbe, 0x1a, 0x28, 0x0e, 0xe7, 0xe7, 0x34, 0x2d, 0xdd, 0x74, 0xc6, 0x86, 0x19, 0x10, + 0xdf, 0xc2, 0x1d, 0xa4, 0xf5, 0x64, 0xa1, 0x1c, 0xee, 0x86, 0x75, 0x3e, 0x3c, 0xac, 0x93, 0x52, + 0xd8, 0x0f, 0x21, 0x05, 0x2a, 0x0d, 0x29, 0x37, 0xe3, 0x3e, 0x4d, 0x4d, 0x0a, 0x08, 0x69, 0x0b, + 0xa5, 0x7a, 0x1c, 0x9a, 0xd7, 0x8c, 0xba, 0xe4, 0xc4, 0x98, 0xf5, 0xae, 0x6d, 0x36, 0xbb, 0x63, + 0x31, 0x0b, 0x9b, 0xf8, 0x30, 0x19, 0x8e, 0x4e, 0xf4, 0x18, 0xd4, 0x21, 0x58, 0x41, 0x51, 0xf2, + 0x1b, 0x8c, 0x71, 0x81, 0xc0, 0xf9, 0x7f, 0x8d, 0x2b, 0x1c, 0x19, 0x8e, 0x50, 0x74, 0x31, 0xe6, + 0x4d, 0xc6, 0x3a, 0x1a, 0x0b, 0x11, 0xcf, 0xca, 0xcd, 0xb1, 0xc6, 0x01, 0x5d, 0x8b, 0x13, 0x8d, + 0xb3, 0xce, 0xf4, 0x9d, 0xed, 0xfc, 0x6c, 0x76, 0xa3, 0xb6, 0xe7, 0x90, 0x9f, 0x6e, 0x66, 0x51, + 0x63, 0x97, 0x09, 0x1d, 0x6f, 0x63, 0x28, 0x7c, 0x25, 0x0a, 0xd5, 0xc8, 0x05, 0x2d, 0x9f, 0x6b, + 0xfe, 0x14, 0x2d, 0xe6, 0x06, 0xad, 0x70, 0xe4, 0xbd, 0x41, 0xd2, 0x44, 0x34, 0x91, 0x0b, 0x21, + 0x49, 0xd9, 0x59, 0x73, 0x83, 0x95, 0x3e, 0x36, 0x99, 0xd1, 0xa2, 0xa7, 0x04, 0xf9, 0x58, 0x3a, + 0x47, 0x55, 0x41, 0x8d, 0xf9, 0xb7, 0x53, 0x4f, 0x90, 0xa6, 0x8d, 0x34, 0x5f, 0xe3, 0x6d, 0x27, + 0xc1, 0x87, 0xf0, 0xc1, 0xa0, 0xd6, 0x3c, 0x1a, 0xdb, 0x95, 0x51, 0x2c, 0xb1, 0xab, 0xb1, 0x94, + 0x40, 0x2f, 0xb6, 0xdb, 0x6d, 0xf8, 0xd2, 0x63, 0xf7, 0x06, 0x6c, 0x78, 0xe5, 0xf1, 0xe9, 0xca, + 0x6a, 0x7a, 0xd4, 0xa6, 0x6b, 0x63, 0x14, 0x7b, 0x1a, 0xb3, 0xa4, 0x7f, 0xfe, 0x37, 0x18, 0x7e, + 0xeb, 0xec, 0x63, 0xa4, 0x7c, 0xa5, 0x53, 0x4d, 0x79, 0x58, 0x6e, 0x31, 0xb0, 0x1e, 0xf9, 0x88, + 0xa9, 0x22, 0xa5, 0xff, 0x0a, 0x16, 0xa6, 0xd8, 0x89, 0x53, 0x12, 0xa1, 0x3d, 0x05, 0x6b, 0x1b, + 0x25, 0xa9, 0xa4, 0xe8, 0xb3, 0xe1, 0x42, 0x23, 0x64, 0xcc, 0x75, 0x6d, 0xfa, 0x35, 0x70, 0x87, + 0x94, 0x7b, 0xb7, 0x33, 0x1e, 0xa3, 0x22, 0x99, 0xaa, 0xba, 0x10, 0x88, 0xbf, 0x8d, 0xb6, 0x3e, + 0x8c, 0xb5, 0xb2, 0x56, 0xd0, 0xd2, 0x0f, 0x56, 0x32, 0x10, 0x58, 0x41, 0x14, 0x3e, 0xb0, 0x9b, + 0x15, 0x7f, 0xe1, 0x4f, 0x64, 0xac, 0xcd, 0x43, 0x51, 0xd4, 0xd5, 0x75, 0x53, 0x23, 0xaf, 0x0f, + 0x90, 0xa4, 0x25, 0x21, 0xad, 0xb2, 0x2e, 0xc7, 0xa5, 0x4d, 0x92, 0x65, 0x4a, 0x6d, 0xa9, 0x3f, + 0xf8, 0x7f, 0x2b, 0x0c, 0x70, 0x79, 0x97, 0x72, 0x46, 0xd8, 0xeb, 0xe9, 0xa6, 0x9a, 0x7e, 0x37, + 0x66, 0xda, 0x6d, 0xaf, 0xa4, 0x93, 0x47, 0x9d, 0xf2, 0x74, 0x23, 0xdb, 0xc4, 0x7c, 0x6d, 0xb6, + 0x9a, 0x7e, 0x09, 0xbc, 0x9b, 0x6b, 0x98, 0xfc, 0x7f, 0x82, 0x0b, 0x1b, 0xb4, 0xd0, 0xed, 0x51, + 0x7d, 0x24, 0x9c, 0xd3, 0x52, 0x71, 0x56, 0x2a, 0xff, 0x05, 0xf7, 0x2f, 0x67, 0x10, 0xe3, 0xf3, + 0xd0, 0xd5, 0x31, 0x6f, 0xff, 0x86, 0x6f, 0xe8, 0x6f, 0x65, 0x8c, 0x45, 0x8e, 0x34, 0xd3, 0x15, + 0x62, 0xaf, 0xf0, 0xc6, 0xd4, 0xf1, 0x9d, 0xcd, 0x3a, 0x77, 0xfb, 0x6d, 0x8b, 0x69, 0xf8, 0x77, + 0x9e, 0x4d, 0x37, 0x5b, 0x6d, 0xe7, 0x36, 0x81, 0xb8, 0xe4, 0xba, 0x93, 0xff, 0x85, 0x0a, 0x35, + 0x35, 0xc1, 0x8c, 0xe4, 0x7d, 0x96, 0x4f, 0x7c, 0x7f, 0xcf, 0xb6, 0x66, 0x27, 0x1f, 0x9c, 0xf8, + 0x76, 0xe7, 0xb0, 0xa0, 0xed, 0x96, 0x39, 0xa4, 0x62, 0x65, 0x26, 0x71, 0xf3, 0x75, 0x33, 0xac, + 0x9b, 0x5d, 0xa9, 0xc6, 0x6d, 0x36, 0xfe, 0x18, 0x39, 0x88, 0x61, 0x8a, 0x7c, 0xc5, 0x05, 0xce, + 0x18, 0xd4, 0xfb, 0xf5, 0x53, 0x18, 0xb8, 0xc7, 0xc6, 0xd3, 0x62, 0x90, 0x95, 0x43, 0x4d, 0xd3, + 0x7b, 0xe1, 0x60, 0x4a, 0xc7, 0x5f, 0x31, 0xd7, 0x9d, 0x71, 0xd7, 0x9d, 0xf1, 0xa6, 0x7d, 0xbb, + 0xea, 0x4e, 0x42, 0x0f, 0x34, 0x33, 0xb2, 0xd9, 0x26, 0x4a, 0xc4, 0xe7, 0x99, 0xe5, 0x24, 0x9a, + 0x6b, 0xfe, 0x36, 0xdf, 0x2e, 0xc7, 0x8c, 0xd5, 0x41, 0xbe, 0xaf, 0xab, 0x49, 0x7b, 0x1b, 0x4c, + 0x64, 0x39, 0xcb, 0xd3, 0x1d, 0xbf, 0xf8, 0xd8, 0x79, 0x4b, 0xad, 0x31, 0x92, 0xf4, 0x32, 0x94, + 0x75, 0x20, 0x33, 0xb9, 0xea, 0x32, 0x67, 0x29, 0xe9, 0x2d, 0x08, 0x54, 0xe9, 0x74, 0x0a, 0x12, + 0xea, 0xa0, 0x4f, 0xb5, 0x49, 0xec, 0x7b, 0x79, 0xfe, 0xa9, 0xc9, 0xfc, 0x29, 0x58, 0xb1, 0xc1, + 0x3a, 0xb1, 0xab, 0x1a, 0xf5, 0x44, 0xac, 0x69, 0xa4, 0xf8, 0x52, 0x3f, 0x79, 0x7b, 0x9f, 0xb6, + 0x87, 0xc4, 0xda, 0xc0, 0xea, 0xbe, 0x8f, 0x0d, 0xf6, 0xc8, 0x1b, 0x1b, 0xd2, 0xfc, 0x3a, 0x5d, + 0x35, 0x4e, 0xa9, 0x10, 0x82, 0xbc, 0x77, 0x2a, 0x36, 0x56, 0xa6, 0x1f, 0x8e, 0xfd, 0x55, 0x57, + 0xc2, 0x84, 0x80, 0xca, 0x41, 0xae, 0xae, 0x5b, 0x46, 0x8c, 0xdd, 0x6b, 0x64, 0x22, 0xbe, 0xbc, + 0x40, 0xd3, 0x31, 0x93, 0x2c, 0x9e, 0x8a, 0xa7, 0x16, 0x77, 0xab, 0x73, 0x8e, 0x17, 0x8a, 0x62, + 0x78, 0xc3, 0xde, 0xef, 0xe3, 0x05, 0xa0, 0x62, 0x0c, 0xdf, 0xd6, 0x1d, 0xbb, 0xbb, 0x33, 0x75, + 0x12, 0xca, 0x84, 0x9e, 0x3a, 0x9b, 0x28, 0x14, 0x57, 0x27, 0x6f, 0xf1, 0x98, 0x48, 0x63, 0xb9, + 0xba, 0x03, 0x9e, 0x71, 0x1b, 0x5c, 0xe3, 0x6a, 0x66, 0x9f, 0xdd, 0xd9, 0x27, 0xc6, 0xb5, 0x86, + 0x7e, 0x11, 0x9c, 0x9a, 0xa3, 0xb1, 0x6e, 0x60, 0xef, 0x92, 0xec, 0x49, 0x82, 0x35, 0x31, 0x38, + 0x2f, 0x0a, 0x5b, 0x42, 0x8c, 0x99, 0xb5, 0x49, 0x92, 0x75, 0x43, 0xbf, 0x70, 0xf7, 0xb7, 0xb4, + 0x81, 0x54, 0xe5, 0xb9, 0x51, 0x81, 0x8a, 0xfd, 0x3f, 0xc3, 0xdd, 0xfb, 0x59, 0xd1, 0x12, 0x4e, + 0x29, 0x56, 0x99, 0x94, 0xa1, 0x37, 0x1f, 0xed, 0xb6, 0x98, 0x89, 0x9f, 0x18, 0x53, 0x85, 0x4b, + 0xec, 0x36, 0xef, 0x29, 0x8e, 0xf2, 0x48, 0x93, 0xea, 0x53, 0x46, 0x28, 0x50, 0x98, 0xbb, 0x80, + 0x28, 0x40, 0xfd, 0x8c, 0xb1, 0x8b, 0x8d, 0xa8, 0x87, 0x2d, 0xd5, 0xe3, 0xe3, 0x3f, 0x33, 0x13, + 0xff, 0x60, 0x48, 0x22, 0x6f, 0x3b, 0x4e, 0xe5, 0x17, 0x6e, 0x24, 0x31, 0xda, 0x34, 0x2d, 0x78, + 0x81, 0x84, 0x74, 0xf3, 0x64, 0x06, 0x81, 0xb5, 0xa2, 0x5c, 0x02, 0x6e, 0x8e, 0x92, 0x5e, 0x33, + 0xb6, 0x94, 0xcd, 0xaf, 0x35, 0x05, 0xcb, 0xd6, 0x5d, 0x39, 0x05, 0xaa, 0x3c, 0x12, 0xec, 0x97, + 0x66, 0xee, 0xef, 0x88, 0xc8, 0xd4, 0xb2, 0x66, 0xdf, 0xc2, 0x24, 0xb4, 0xd3, 0x06, 0x4d, 0xe7, + 0xef, 0xc3, 0xb5, 0xca, 0x3c, 0x16, 0x51, 0x95, 0x83, 0x20, 0xac, 0xac, 0x0f, 0x4d, 0xa8, 0x1e, + 0x6f, 0xe4, 0x8f, 0x95, 0xc0, 0x1f, 0x44, 0x6b, 0x78, 0xaf, 0x8f, 0x39, 0x74, 0xb8, 0xd4, 0x9a, + 0x8a, 0x28, 0xb9, 0x09, 0x3c, 0xae, 0x50, 0x80, 0x28, 0x8c, 0x9d, 0x0b, 0xc6, 0x76, 0x0f, 0x4b, + 0xb9, 0xfb, 0x25, 0xf1, 0xec, 0x2b, 0x61, 0xa2, 0x57, 0x8d, 0x16, 0x0e, 0x45, 0xe3, 0x2c, 0x1e, + 0x37, 0x60, 0x6f, 0x3d, 0x25, 0x43, 0xa7, 0x80, 0x48, 0x95, 0x07, 0xaa, 0x0a, 0x04, 0xe1, 0x03, + 0x56, 0x51, 0xc8, 0x4d, 0x04, 0x09, 0x69, 0x08, 0x3d, 0xa5, 0xcf, 0x1a, 0x50, 0x1b, 0xb8, 0x2d, + 0x06, 0x7f, 0x1c, 0x5c, 0x20, 0xde, 0xf0, 0xb9, 0xa0, 0xc9, 0x48, 0xee, 0x14, 0xc5, 0x57, 0xf1, + 0x6a, 0xde, 0x53, 0xa1, 0x75, 0xff, 0xf4, 0xbc, 0xaa, 0x16, 0x0a, 0x8c, 0x6f, 0x2f, 0xfc, 0x44, + 0x71, 0xbc, 0x7c, 0xc4, 0x26, 0x57, 0x29, 0x39, 0x19, 0x3f, 0x87, 0x98, 0x28, 0x74, 0x1f, 0x63, + 0xc2, 0x3c, 0xdf, 0x39, 0x79, 0xc0, 0xd9, 0x99, 0xb1, 0xf8, 0xc3, 0x84, 0xdd, 0x37, 0xc6, 0x29, + 0xf1, 0x8a, 0x68, 0xe9, 0xbe, 0x52, 0x12, 0x90, 0xfe, 0x32, 0x89, 0x44, 0x0b, 0x46, 0x9d, 0xe5, + 0xdc, 0xef, 0xe7, 0xa2, 0x18, 0x4b, 0x95, 0xdb, 0x1a, 0xf6, 0x3e, 0x52, 0x52, 0xd7, 0xc2, 0x83, + 0x26, 0x68, 0x8f, 0x95, 0xa6, 0xd6, 0x41, 0xa4, 0xd5, 0x71, 0xc3, 0xa3, 0x1d, 0x84, 0x3b, 0x7c, + 0x10, 0x09, 0x69, 0xa1, 0xba, 0xaf, 0x9d, 0x94, 0x70, 0xda, 0x6e, 0x2a, 0x63, 0xbf, 0x6d, 0xb6, + 0xdb, 0xf1, 0xb1, 0xa7, 0x0b, 0x17, 0x8e, 0x26, 0x90, 0x5a, 0x76, 0x33, 0xca, 0xda, 0x1c, 0xe5, + 0x21, 0x6d, 0x7d, 0xb6, 0xdb, 0x6f, 0xc6, 0xdb, 0x08, 0x4e, 0x61, 0x90, 0x43, 0x73, 0x18, 0xe5, + 0x03, 0x6c, 0xe6, 0xa5, 0x05, 0xbe, 0xd3, 0x80, 0xca, 0x27, 0xb1, 0xa4, 0xdb, 0x6d, 0xb6, 0xdf, + 0x82, 0x92, 0x36, 0xf5, 0x21, 0x62, 0xb2, 0x23, 0x4d, 0x4f, 0xad, 0x3f, 0x5d, 0x85, 0x27, 0x75, + 0x5f, 0xe1, 0x4d, 0x64, 0x5a, 0x48, 0xbb, 0xa3, 0x6f, 0x79, 0x5b, 0x0d, 0x98, 0xfd, 0x86, 0xae, + 0x30, 0xe5, 0x46, 0xd6, 0xe7, 0xf8, 0x50, 0xb0, 0x98, 0x54, 0xcf, 0xb4, 0xd8, 0xdc, 0x6a, 0xe9, + 0xbb, 0xb5, 0x8d, 0x1c, 0xd5, 0x7a, 0x0a, 0x0d, 0xec, 0x86, 0x57, 0x5e, 0x8d, 0x97, 0x3c, 0x77, + 0xe3, 0x65, 0xf4, 0xba, 0x69, 0xb1, 0x8c, 0xd9, 0xa3, 0x7d, 0xe5, 0x5d, 0xa8, 0x06, 0xdc, 0x91, + 0x30, 0x52, 0x3e, 0x6e, 0xda, 0xff, 0xc6, 0xd9, 0xbe, 0x6e, 0x57, 0xd2, 0x3c, 0x2e, 0x6c, 0xe6, + 0xd0, 0xb7, 0x9a, 0x6a, 0x7b, 0x3a, 0xf0, 0x9e, 0x48, 0xb4, 0xd2, 0x6d, 0x11, 0x67, 0xfe, 0x36, + 0x4e, 0xcb, 0x2e, 0x45, 0xc6, 0x98, 0xea, 0x26, 0xb3, 0x3c, 0x71, 0xa2, 0x1e, 0x9e, 0x57, 0x77, + 0x98, 0xe9, 0xa6, 0xdb, 0x7e, 0x16, 0xe7, 0xab, 0x1a, 0xc6, 0x8f, 0x66, 0x66, 0x3f, 0x49, 0x53, + 0x16, 0xc5, 0xbf, 0xc1, 0x65, 0x08, 0xee, 0x6b, 0xa0, 0x6c, 0x19, 0xe0, 0x3a, 0x65, 0x49, 0xac, + 0x31, 0xa2, 0xd6, 0x29, 0x3c, 0x6d, 0xf4, 0x4d, 0x8e, 0xa3, 0x36, 0x6f, 0x54, 0x95, 0x45, 0xc1, + 0x3c, 0x16, 0x55, 0xe7, 0xa3, 0xb5, 0x8c, 0xac, 0x84, 0x31, 0x6d, 0xb1, 0xff, 0x0a, 0x62, 0x2b, + 0x23, 0xd7, 0xa0, 0xcf, 0x7b, 0x28, 0x4a, 0x54, 0x6c, 0xf1, 0xa7, 0xa6, 0x8c, 0x20, 0x52, 0xa9, + 0xce, 0x1f, 0x18, 0x43, 0xa8, 0x1a, 0x34, 0xd7, 0x55, 0x6a, 0x72, 0x1a, 0x7b, 0xb6, 0x6e, 0x20, + 0xdb, 0x74, 0x8b, 0xbe, 0x32, 0x3f, 0x63, 0xdd, 0x9b, 0x52, 0x6c, 0xd6, 0x4c, 0xad, 0xe3, 0xfc, + 0x14, 0xd3, 0xb9, 0xa8, 0x64, 0xdd, 0x08, 0xa4, 0x1a, 0xcb, 0xac, 0x6f, 0x8e, 0x97, 0xe1, 0xd9, + 0x35, 0x27, 0xcf, 0xd5, 0x5b, 0x64, 0x37, 0x49, 0x2d, 0x79, 0xa2, 0x82, 0x6d, 0xb6, 0xdb, 0xf0, + 0x40, 0x79, 0x08, 0x25, 0x29, 0x01, 0xb9, 0x28, 0xb0, 0x6c, 0x57, 0x45, 0x4c, 0xf4, 0xfd, 0x5b, + 0x71, 0x6d, 0xdd, 0xdf, 0xc2, 0x84, 0x7f, 0x7f, 0x98, 0x33, 0x0a, 0x37, 0x07, 0x49, 0x0a, 0x9a, + 0x4e, 0x86, 0x3c, 0xe0, 0xe8, 0x06, 0xf8, 0x52, 0xbd, 0xc1, 0xb9, 0x99, 0xf8, 0xd9, 0xcb, 0x06, + 0xb4, 0xe2, 0x9b, 0x4e, 0xfa, 0x53, 0x7d, 0x23, 0x57, 0x7d, 0x7d, 0x29, 0x3f, 0xc6, 0xea, 0xba, + 0x56, 0x34, 0x36, 0x31, 0x97, 0x06, 0xcc, 0xac, 0x40, 0x67, 0x73, 0x59, 0x65, 0xc1, 0xca, 0x78, + 0xb6, 0x2c, 0xa1, 0x7f, 0x87, 0xf7, 0x46, 0xca, 0x40, 0x6f, 0x85, 0x1c, 0xe5, 0xa1, 0xc4, 0x61, + 0x12, 0x45, 0x8f, 0xf7, 0xfe, 0x36, 0x13, 0xb2, 0x72, 0xa6, 0xe7, 0x3e, 0x9b, 0x73, 0x4e, 0xa9, + 0xca, 0x0e, 0xc6, 0xec, 0x0e, 0x34, 0x3c, 0x82, 0xba, 0xd6, 0xb8, 0x52, 0x59, 0x7c, 0x5b, 0xff, + 0x1b, 0x63, 0x23, 0x2d, 0xad, 0x84, 0xf6, 0x40, 0x6d, 0x3a, 0x28, 0xf1, 0xea, 0xd6, 0xce, 0x6c, + 0x68, 0xca, 0x64, 0xad, 0xa4, 0x33, 0x86, 0x50, 0xbf, 0xc1, 0x6e, 0x88, 0xaa, 0xf3, 0x90, 0xa5, + 0x51, 0xda, 0x91, 0x78, 0xdc, 0xaa, 0xc6, 0x52, 0x35, 0x69, 0x85, 0x1a, 0xd6, 0x23, 0xd6, 0xf5, + 0x40, 0x82, 0x75, 0xc9, 0xe5, 0xcc, 0x8a, 0xe5, 0xf7, 0x75, 0x49, 0xc5, 0x87, 0x14, 0x13, 0x52, + 0xc3, 0x1d, 0xa0, 0x79, 0x49, 0x32, 0xa0, 0xac, 0xff, 0x04, 0xde, 0xdb, 0x4e, 0x9e, 0xba, 0x4f, + 0x8d, 0x12, 0x1a, 0xbc, 0x24, 0x36, 0xd8, 0xbc, 0x03, 0xf5, 0x38, 0x64, 0xcd, 0x78, 0x0a, 0x57, + 0x47, 0x28, 0x1d, 0xbd, 0x86, 0xaf, 0x64, 0xe9, 0x1b, 0x14, 0xb2, 0xa0, 0x19, 0xcd, 0x6a, 0x63, + 0x68, 0x41, 0x3b, 0xca, 0x3f, 0xea, 0xaa, 0xbe, 0x11, 0x23, 0x35, 0x36, 0xbd, 0x4e, 0x3c, 0x22, + 0xed, 0x3b, 0x4d, 0xae, 0xdf, 0x0a, 0x63, 0x9b, 0x0e, 0xa4, 0x1a, 0xf7, 0xe7, 0x33, 0x46, 0xc6, + 0x6f, 0x67, 0x7b, 0x35, 0x97, 0x5f, 0x25, 0x59, 0xba, 0x06, 0xdf, 0x04, 0x18, 0xe0, 0xb8, 0x25, + 0x11, 0x5f, 0x04, 0xc6, 0xc5, 0x46, 0xbb, 0xa1, 0x38, 0x60, 0xa3, 0xbf, 0x77, 0x77, 0xf0, 0x56, + 0x67, 0x20, 0xe7, 0x24, 0x10, 0x33, 0x03, 0x1b, 0x38, 0xab, 0xf3, 0xfb, 0xd2, 0x7d, 0xf1, 0x82, + 0x52, 0x52, 0x7f, 0x61, 0x56, 0xe3, 0x71, 0x98, 0xcc, 0x8e, 0x0a, 0x33, 0xa4, 0x98, 0x0d, 0x90, + 0x85, 0xc4, 0x8c, 0xd7, 0xd9, 0x76, 0x45, 0x12, 0x79, 0xe2, 0x7f, 0xbb, 0x19, 0x07, 0x76, 0x7f, + 0x0a, 0x55, 0x96, 0xec, 0xf5, 0xa2, 0x26, 0x67, 0xb5, 0xe3, 0x60, 0xe0, 0xe4, 0x58, 0xd5, 0xd3, + 0x6d, 0x21, 0x8a, 0x1f, 0xf1, 0xb0, 0xd3, 0x22, 0x36, 0x42, 0xd5, 0x5c, 0x58, 0xca, 0x53, 0x4a, + 0x19, 0xb1, 0x2d, 0xaa, 0x15, 0xb7, 0x5b, 0x4b, 0x94, 0x3a, 0x56, 0xdb, 0x6d, 0xb2, 0x18, 0xc9, + 0x0c, 0x67, 0xc1, 0x06, 0x03, 0xc6, 0x50, 0xb6, 0x0d, 0x83, 0x6e, 0x37, 0x23, 0x2b, 0x54, 0x26, + 0xb5, 0xbd, 0xf6, 0x9e, 0xfe, 0x36, 0x6c, 0x76, 0x1b, 0x1d, 0x95, 0x2e, 0xc3, 0x6e, 0xd4, 0x9a, + 0xab, 0x89, 0x94, 0x63, 0x0a, 0xdd, 0x68, 0xef, 0xdb, 0x6d, 0xb6, 0xfc, 0x14, 0x6b, 0x64, 0x90, + 0xd2, 0x41, 0x64, 0xd7, 0x4b, 0xf0, 0x4d, 0x2e, 0xd7, 0x32, 0x81, 0xe4, 0x22, 0x74, 0xa6, 0x57, + 0xb8, 0xb3, 0x5b, 0xe0, 0xb8, 0x8a, 0xbd, 0xa3, 0xe6, 0x45, 0x7c, 0x67, 0x75, 0x9c, 0x84, 0x39, + 0x8f, 0x52, 0x31, 0x05, 0xaa, 0x4c, 0x75, 0x25, 0xad, 0x8f, 0x2c, 0x16, 0xce, 0x16, 0x09, 0xd1, + 0xa1, 0xe3, 0x24, 0x78, 0xfd, 0x57, 0x0e, 0xde, 0x62, 0x59, 0xd3, 0x43, 0x60, 0x59, 0xe8, 0xae, + 0xeb, 0x68, 0x95, 0xbc, 0xbd, 0x8f, 0x04, 0xa5, 0xb6, 0x22, 0x5a, 0xa6, 0x32, 0x93, 0xd2, 0x2f, + 0x0a, 0x5c, 0x8a, 0x6c, 0x54, 0xc8, 0x85, 0x87, 0xb0, 0x13, 0x27, 0x8c, 0x9e, 0x0b, 0x6a, 0x4c, + 0x13, 0x2f, 0x44, 0x4e, 0xbc, 0x25, 0x60, 0x4a, 0xc5, 0x15, 0xa8, 0x36, 0x40, 0x3a, 0xc5, 0xf8, + 0x46, 0x74, 0x9c, 0x41, 0x98, 0x0e, 0xb2, 0x14, 0x7b, 0x67, 0xa7, 0x2f, 0x4d, 0x9f, 0x82, 0xb9, + 0x13, 0x44, 0x64, 0xf3, 0x84, 0x08, 0x4b, 0xae, 0x9c, 0x31, 0xf1, 0xc5, 0xe0, 0xd9, 0x6a, 0x85, + 0x7c, 0x69, 0x4f, 0x8c, 0xab, 0xaa, 0x3a, 0x0c, 0x87, 0x49, 0xd8, 0x38, 0xe3, 0xe0, 0xb8, 0xc3, + 0x85, 0x1c, 0x02, 0x54, 0x82, 0xca, 0xa1, 0xfc, 0x4f, 0x17, 0xaa, 0x07, 0x4c, 0x1f, 0x8b, 0xaa, + 0x2c, 0x68, 0x58, 0x41, 0xfd, 0xd9, 0x26, 0xc2, 0x0b, 0xb7, 0xc4, 0xe8, 0x37, 0x6a, 0x34, 0x6f, + 0xe2, 0x6b, 0xc2, 0x25, 0x4e, 0x9a, 0x8d, 0x84, 0x04, 0x1e, 0x64, 0x5c, 0xbe, 0xf5, 0x0a, 0xd7, + 0x5f, 0x8c, 0xb0, 0x86, 0xe4, 0xde, 0x10, 0x1a, 0x02, 0x1b, 0x5a, 0x98, 0x04, 0x7b, 0x2d, 0x51, + 0x5e, 0xc8, 0xbc, 0x83, 0xf8, 0xd1, 0x18, 0xc7, 0xbc, 0x31, 0xf3, 0x82, 0x25, 0x86, 0x82, 0xd2, + 0x6c, 0x71, 0xec, 0xe9, 0x28, 0x5a, 0xe5, 0x84, 0x2d, 0xcf, 0xfe, 0x34, 0xd0, 0x04, 0x42, 0x8d, + 0x35, 0x54, 0x4d, 0x22, 0x4a, 0xb1, 0x80, 0xe0, 0x4d, 0xe9, 0x52, 0x3b, 0x25, 0x95, 0x0d, 0x1c, + 0xd4, 0x0d, 0xf4, 0xf0, 0xf4, 0xbc, 0x9b, 0x31, 0x8e, 0xf1, 0xa2, 0x51, 0x51, 0x24, 0xcd, 0x06, + 0x51, 0x01, 0xad, 0x0e, 0x39, 0x70, 0x94, 0x1b, 0x4a, 0x53, 0x35, 0xc1, 0xbe, 0x47, 0x6a, 0xb5, + 0xbf, 0xfc, 0x6f, 0x95, 0x29, 0xba, 0xdb, 0x8d, 0xad, 0xbb, 0x4a, 0x1a, 0x7b, 0xa1, 0xb1, 0x99, + 0x2d, 0x4c, 0xca, 0x5f, 0xe1, 0xda, 0x55, 0x34, 0x4d, 0x8e, 0xb1, 0x78, 0x91, 0x3e, 0x63, 0x97, + 0x5d, 0x25, 0x4e, 0x5d, 0x6f, 0xfc, 0x69, 0x20, 0xdc, 0xdb, 0x26, 0x42, 0xbc, 0x8c, 0x95, 0xd4, + 0xcb, 0x48, 0x6c, 0xd8, 0xb1, 0x6b, 0x2a, 0x4e, 0x5e, 0xbe, 0x45, 0xd2, 0x7f, 0x8d, 0xdb, 0xfe, + 0x8d, 0xec, 0xc9, 0x23, 0x46, 0x2d, 0xb4, 0xb1, 0x54, 0x56, 0x5e, 0x5c, 0xff, 0x0f, 0x68, 0x9b, + 0x4c, 0x61, 0x57, 0x34, 0xe5, 0xc4, 0x6e, 0x8b, 0x1b, 0x88, 0x27, 0x51, 0xc5, 0x24, 0xcb, 0x36, + 0x4d, 0x56, 0x9f, 0xe1, 0x4d, 0xba, 0x5a, 0xbf, 0xee, 0x10, 0x21, 0x17, 0x53, 0xc9, 0x6a, 0x51, + 0xa4, 0xc8, 0xb6, 0x9a, 0x90, 0x69, 0xd3, 0x2a, 0x7c, 0x69, 0x76, 0x15, 0x9e, 0x0c, 0xb1, 0x9b, + 0x2e, 0x0d, 0x53, 0xe1, 0x95, 0xbc, 0x2c, 0xac, 0x94, 0xeb, 0x0e, 0xff, 0x82, 0x82, 0x15, 0xe1, + 0xd6, 0xe9, 0x7b, 0x0d, 0x7f, 0x77, 0x00, 0x90, 0x1b, 0xe1, 0xe3, 0xb1, 0x31, 0x4c, 0x8a, 0x54, + 0xdd, 0xe3, 0x39, 0x0f, 0x27, 0x50, 0x77, 0xee, 0x3b, 0x79, 0xff, 0x1b, 0x4e, 0xba, 0xd3, 0x26, + 0xfd, 0x8e, 0xe6, 0x72, 0x8e, 0xbe, 0x3c, 0xa9, 0xc6, 0x9a, 0x7f, 0xe3, 0x38, 0xe0, 0x01, 0x0a, + 0x04, 0xc9, 0x8f, 0x6c, 0x51, 0x80, 0xd7, 0x4d, 0xde, 0x51, 0xd2, 0x29, 0x4a, 0x0e, 0xaf, 0x1b, + 0x95, 0x49, 0xca, 0xc1, 0x3d, 0x96, 0xaa, 0xa1, 0x3b, 0x2f, 0x4a, 0x38, 0x86, 0xca, 0x16, 0xa4, + 0x89, 0xa2, 0x48, 0xba, 0x1f, 0xe3, 0x7a, 0x6c, 0x19, 0x88, 0x4a, 0x10, 0x05, 0xe9, 0x12, 0x4e, + 0x84, 0x0d, 0xa2, 0x07, 0x26, 0x40, 0x16, 0x8f, 0x3e, 0x9a, 0x69, 0xa7, 0xe3, 0x69, 0x32, 0x31, + 0x54, 0x5d, 0x4b, 0x40, 0xc8, 0x4f, 0x1d, 0x70, 0x23, 0x7a, 0x7c, 0xea, 0x7e, 0x6e, 0x7e, 0xef, + 0xfe, 0x34, 0xcc, 0x6a, 0xe3, 0x84, 0x1b, 0x44, 0x94, 0x5c, 0x69, 0xd4, 0x94, 0xff, 0xc1, 0xf7, + 0xda, 0xc3, 0x1b, 0xd6, 0xbb, 0xbb, 0xff, 0x82, 0x08, 0xf5, 0x9a, 0x6a, 0xa1, 0x30, 0x6c, 0x68, + 0x67, 0x61, 0x8c, 0x31, 0xea, 0xd0, 0x3c, 0xfe, 0x2a, 0xad, 0xb6, 0xdb, 0x7f, 0xe1, 0x48, 0xdb, + 0x4d, 0x3a, 0xdd, 0x6e, 0xda, 0x23, 0x91, 0x5c, 0x76, 0x89, 0xd0, 0xdc, 0xf6, 0x3b, 0x2b, 0x22, + 0xf0, 0xa7, 0x60, 0x87, 0xd1, 0xd4, 0xb1, 0x39, 0xa5, 0x12, 0x5a, 0x86, 0xe5, 0x47, 0x9d, 0x0d, + 0x5a, 0x65, 0xae, 0x59, 0x52, 0x35, 0x58, 0x5a, 0xef, 0x87, 0xaf, 0xae, 0xbd, 0x0d, 0xd4, 0x63, + 0x07, 0xef, 0xa5, 0x93, 0x7c, 0x1f, 0x6d, 0xb6, 0xdb, 0xf0, 0xa5, 0x5a, 0x2c, 0xae, 0xbd, 0xd4, + 0xfb, 0x24, 0x37, 0x60, 0xee, 0x57, 0x76, 0x92, 0xae, 0x19, 0xe2, 0x15, 0xb8, 0xf8, 0x7e, 0x1b, + 0x52, 0xb9, 0x88, 0x34, 0x71, 0xcf, 0x46, 0x38, 0x48, 0x67, 0x60, 0x8c, 0x57, 0x13, 0x28, 0xec, + 0xb6, 0xaa, 0xff, 0x0a, 0x6e, 0xa3, 0x12, 0xe1, 0xd3, 0x42, 0x7d, 0x23, 0xa5, 0x56, 0x77, 0x24, + 0xfa, 0x5b, 0x1f, 0x0e, 0x9b, 0x4a, 0xe7, 0x60, 0x74, 0x61, 0x5d, 0x52, 0xb0, 0xde, 0xc1, 0x18, + 0xcf, 0x86, 0x08, 0xd6, 0xc8, 0xe9, 0xb3, 0x06, 0x6d, 0x3c, 0x6f, 0x44, 0x55, 0x35, 0x8c, 0x45, + 0x87, 0x30, 0x46, 0x28, 0xed, 0x8e, 0x55, 0xb3, 0x56, 0x7b, 0x09, 0x7f, 0xb9, 0x3d, 0xcf, 0x82, + 0xb3, 0x90, 0x86, 0x75, 0x62, 0x09, 0xc7, 0x06, 0x26, 0xa3, 0x2c, 0xac, 0x77, 0x89, 0x8c, 0x12, + 0xb9, 0x77, 0x0a, 0x07, 0xf5, 0xb4, 0x11, 0x84, 0x17, 0x3c, 0xf7, 0x03, 0x01, 0x9c, 0xe3, 0x04, + 0xda, 0x8e, 0x9a, 0x91, 0xac, 0x56, 0x4c, 0x9a, 0x3f, 0x0a, 0x11, 0x84, 0x15, 0x2f, 0x14, 0xf1, + 0x8d, 0x8d, 0x9e, 0x16, 0xa7, 0x95, 0x22, 0x51, 0xb6, 0x1d, 0xf0, 0x7d, 0xc8, 0x3e, 0x4b, 0xe3, + 0x75, 0x19, 0x55, 0xf4, 0x75, 0xad, 0x13, 0x25, 0xa2, 0x6d, 0x0e, 0x3b, 0x5d, 0xdd, 0xff, 0xc6, + 0xd0, 0x86, 0xd0, 0x89, 0x57, 0x3b, 0x1e, 0x4a, 0x1f, 0xf5, 0xd0, 0x4b, 0xa3, 0xd0, 0xe8, 0x7b, + 0x21, 0xc6, 0x29, 0x99, 0x07, 0x6d, 0xdd, 0xff, 0xc2, 0x86, 0x94, 0x52, 0x93, 0x6c, 0x5c, 0x66, + 0x1b, 0xf4, 0xf0, 0x54, 0xf9, 0xab, 0xac, 0xd7, 0x3f, 0xa6, 0x98, 0xed, 0xf1, 0x9d, 0xa2, 0x11, + 0xa3, 0xb1, 0x94, 0x02, 0x56, 0x2e, 0x9b, 0x55, 0x2d, 0x26, 0x82, 0x66, 0xe5, 0x4f, 0x1b, 0xf8, + 0xd3, 0xbc, 0x54, 0x68, 0xc4, 0x5d, 0x32, 0xb3, 0xe3, 0x6b, 0x01, 0x94, 0x85, 0x74, 0x0d, 0xbe, + 0x9a, 0xa6, 0x9f, 0x8c, 0xbd, 0x9d, 0x8c, 0x8b, 0xe4, 0x51, 0x18, 0x91, 0x46, 0x67, 0x7b, 0xb6, + 0xbb, 0x53, 0xf8, 0xcd, 0x9f, 0x50, 0xe8, 0xdc, 0xca, 0x69, 0xb2, 0x74, 0x92, 0xd9, 0xb2, 0x1e, + 0x69, 0xfc, 0x21, 0x51, 0x4f, 0xda, 0x93, 0x07, 0x17, 0x8b, 0xe1, 0x09, 0x63, 0x75, 0x26, 0xe6, + 0xe5, 0xd4, 0xd3, 0xc9, 0xbe, 0x10, 0xbd, 0x4d, 0x55, 0x59, 0x99, 0x30, 0x2b, 0x6c, 0x17, 0x2f, + 0xf1, 0x9e, 0x46, 0xa6, 0x14, 0xb1, 0x97, 0x61, 0x67, 0x08, 0xa9, 0x73, 0x9e, 0x5b, 0x12, 0xf2, + 0x75, 0x97, 0x8a, 0xa1, 0x94, 0x02, 0x3a, 0x78, 0x71, 0x1b, 0xa0, 0xec, 0xfc, 0x66, 0x85, 0x6f, + 0xac, 0x6e, 0x6f, 0x95, 0xb5, 0xbb, 0x0c, 0xe4, 0xcf, 0x8f, 0x31, 0x4f, 0xe7, 0x8c, 0x3e, 0x33, + 0x40, 0xa7, 0x97, 0x18, 0xb0, 0xe4, 0x66, 0x44, 0xf2, 0xfc, 0xc9, 0xc2, 0x71, 0xe7, 0xab, 0x34, + 0x25, 0x17, 0x79, 0xe3, 0x4a, 0x48, 0x9d, 0x4a, 0x56, 0xf7, 0x04, 0x3c, 0x0c, 0x09, 0xab, 0x05, + 0xee, 0x78, 0x40, 0x1b, 0x30, 0xce, 0xd4, 0x8c, 0xb4, 0xb8, 0x1c, 0xc7, 0x96, 0xda, 0xb9, 0x3e, + 0x70, 0x34, 0x28, 0x32, 0x2f, 0xf7, 0x57, 0xf8, 0xea, 0xad, 0xc0, 0x1f, 0x50, 0x49, 0xf5, 0xd6, + 0xa1, 0x5c, 0xff, 0xdc, 0x12, 0xb3, 0x26, 0x12, 0xdb, 0x63, 0x73, 0x3e, 0x37, 0x13, 0x6d, 0x73, + 0x35, 0x86, 0x41, 0xa5, 0xc8, 0x2b, 0x37, 0x2e, 0xd7, 0x75, 0x77, 0x48, 0xcf, 0xb7, 0xf7, 0x03, + 0x47, 0x04, 0xa7, 0x22, 0x7f, 0x6f, 0xdb, 0x74, 0xd7, 0xc5, 0xb1, 0x6f, 0xf1, 0x95, 0xe5, 0xbb, + 0x07, 0x75, 0x18, 0x57, 0xce, 0xa6, 0x90, 0xb5, 0xc4, 0x8e, 0x28, 0x09, 0xe4, 0x5d, 0xad, 0x17, + 0x5c, 0x3a, 0xdf, 0x44, 0x4d, 0x7c, 0xf3, 0x77, 0xe3, 0x34, 0x35, 0xc5, 0x91, 0xc2, 0xea, 0xe0, + 0x4a, 0xa6, 0x7c, 0x6e, 0x36, 0x87, 0x06, 0x34, 0xf2, 0x66, 0x84, 0xd8, 0x37, 0xdb, 0x50, 0x40, + 0x1e, 0x80, 0xe0, 0x0f, 0xc6, 0x6a, 0xab, 0xc3, 0x41, 0x18, 0x9b, 0x6c, 0x84, 0x5a, 0xda, 0x76, + 0x75, 0xb7, 0xe3, 0x24, 0xdd, 0xb6, 0x05, 0x13, 0x35, 0xb0, 0xa2, 0x5c, 0xd8, 0x90, 0xeb, 0xc9, + 0xa7, 0xa5, 0x64, 0x9d, 0xae, 0xdf, 0xc6, 0xd2, 0x62, 0x10, 0xb4, 0xdd, 0x6c, 0x53, 0x9c, 0xb9, + 0x3b, 0xb2, 0x36, 0x11, 0x9b, 0x72, 0x60, 0xe6, 0x4a, 0x32, 0x54, 0xd6, 0xbf, 0xe3, 0x23, 0xf9, + 0xd1, 0x54, 0x95, 0xb4, 0x9b, 0xee, 0x90, 0x4e, 0xdb, 0xac, 0x6c, 0x2f, 0xb6, 0x8c, 0x97, 0x84, + 0xf3, 0xf9, 0xf9, 0x10, 0x0e, 0xa1, 0x63, 0xf1, 0x13, 0xe6, 0x7c, 0xc0, 0x63, 0x4c, 0x4c, 0x42, + 0xb5, 0x8f, 0x8d, 0x19, 0x95, 0x2d, 0xee, 0x85, 0x4a, 0x60, 0xc0, 0xbb, 0x79, 0xbd, 0x1d, 0xb5, + 0x46, 0x1f, 0x44, 0xf6, 0x09, 0x69, 0x5f, 0xfe, 0x1b, 0xb0, 0x23, 0x30, 0x43, 0x3c, 0x6b, 0xd4, + 0xda, 0xd2, 0x77, 0x4c, 0xb4, 0xbf, 0x1a, 0x73, 0x94, 0x63, 0xa7, 0x20, 0xb6, 0xaf, 0x83, 0xdb, + 0x87, 0x5c, 0xcc, 0xc5, 0x9d, 0xdd, 0x54, 0x7e, 0xf1, 0x58, 0xcb, 0x71, 0xbe, 0x24, 0xf4, 0xd3, + 0x4d, 0x3f, 0x04, 0x1b, 0x18, 0x75, 0x46, 0xa3, 0x63, 0x23, 0x93, 0x8f, 0x5e, 0xb2, 0x54, 0x2a, + 0x2b, 0x50, 0x39, 0x61, 0x75, 0x64, 0x96, 0xe6, 0x8a, 0x34, 0xd3, 0x4d, 0x3f, 0x04, 0x11, 0xbb, + 0xef, 0x6e, 0x5a, 0xe7, 0x20, 0xa1, 0xa9, 0xba, 0xc6, 0xaf, 0x4f, 0xc2, 0xf8, 0x2f, 0x8c, 0xa4, + 0xe8, 0x7f, 0x82, 0xab, 0xa2, 0xe3, 0x99, 0x3d, 0xa5, 0x19, 0x1c, 0x77, 0xae, 0x1d, 0x17, 0xa2, + 0x33, 0x7c, 0x6c, 0xac, 0x0f, 0xd1, 0xac, 0x2e, 0xad, 0x45, 0x8a, 0x68, 0x95, 0xca, 0x35, 0xc9, + 0x82, 0x2f, 0xf7, 0xf9, 0x47, 0x73, 0xa3, 0x74, 0x9c, 0x19, 0x57, 0x07, 0x78, 0x8e, 0x8f, 0xef, + 0xff, 0x0e, 0xde, 0xcb, 0xaf, 0x2b, 0x2f, 0x24, 0xd7, 0xbe, 0x88, 0xd6, 0x61, 0x32, 0x13, 0x1c, + 0xb2, 0xe4, 0x79, 0x5f, 0x2b, 0xd1, 0x7f, 0x8d, 0xb4, 0xa2, 0xab, 0x68, 0x34, 0x15, 0x54, 0xf7, + 0xbc, 0x65, 0x31, 0xcc, 0x90, 0x71, 0xb0, 0x81, 0x98, 0x1a, 0xf4, 0xc2, 0x9a, 0xa0, 0x27, 0x46, + 0x9b, 0xe9, 0x74, 0xff, 0xc6, 0xcc, 0xc2, 0x1a, 0x71, 0x46, 0xd7, 0xac, 0xf2, 0xcf, 0x79, 0x46, + 0xe0, 0xe1, 0x18, 0xa6, 0x33, 0x91, 0x6c, 0x76, 0x27, 0x58, 0xb6, 0x2d, 0xff, 0x88, 0x2d, 0x5a, + 0x8c, 0xbd, 0x5a, 0xa3, 0x4b, 0xc1, 0x59, 0x2b, 0x4e, 0xc7, 0xc6, 0x13, 0x4c, 0xc9, 0x59, 0x96, + 0xb0, 0x8f, 0x7c, 0x6d, 0xa5, 0x37, 0x11, 0x76, 0x89, 0x0f, 0x98, 0x9a, 0x1a, 0x9b, 0x90, 0xf0, + 0x0d, 0xce, 0x92, 0x61, 0x71, 0x6d, 0xb6, 0xdb, 0x6f, 0xc2, 0x96, 0x39, 0xb5, 0xa4, 0xa3, 0x5b, + 0xcb, 0xe7, 0x43, 0xd0, 0xe4, 0x78, 0x08, 0x80, 0x7f, 0x1b, 0x34, 0x38, 0xd0, 0x93, 0xf7, 0x48, + 0x30, 0xab, 0x31, 0x0a, 0xd4, 0xe8, 0xec, 0x51, 0x8a, 0xa6, 0x83, 0x2b, 0xff, 0x1b, 0x82, 0xda, + 0x74, 0x36, 0x92, 0x57, 0xb8, 0xc2, 0xb3, 0x3b, 0x99, 0x1b, 0x56, 0xdd, 0x3c, 0x97, 0xfe, 0x11, + 0x93, 0x0f, 0x8c, 0x70, 0x73, 0xb1, 0x3b, 0x0e, 0xc8, 0x2a, 0xbe, 0x0a, 0xad, 0x6d, 0xd4, 0xd3, + 0x39, 0x48, 0x63, 0xac, 0x6f, 0xcd, 0xa7, 0x3a, 0x7c, 0x6e, 0x17, 0x3e, 0x16, 0x83, 0xc3, 0xa3, + 0x06, 0xc7, 0x91, 0xcb, 0x9b, 0x10, 0xbb, 0xd0, 0xc0, 0xcf, 0x2c, 0xd4, 0x91, 0x3c, 0x06, 0x71, + 0x4b, 0xfc, 0x10, 0x5d, 0x19, 0x97, 0x07, 0xee, 0xbf, 0x3a, 0x4d, 0x50, 0x93, 0x48, 0x32, 0xf2, + 0x28, 0xeb, 0x52, 0x4f, 0xff, 0x1b, 0x71, 0xa4, 0x48, 0x7b, 0xe8, 0x7a, 0x37, 0x3b, 0x31, 0xab, + 0xcf, 0x61, 0x23, 0xfb, 0xae, 0xc9, 0x62, 0x58, 0x83, 0xf8, 0xb6, 0x3f, 0xe1, 0x4b, 0xfd, 0x77, + 0x9d, 0xe8, 0xa7, 0xec, 0x91, 0xa3, 0x66, 0xe8, 0xe9, 0xf0, 0x57, 0x87, 0x96, 0x51, 0x99, 0xdf, + 0xca, 0xc3, 0x75, 0x88, 0x93, 0x4e, 0x8e, 0x28, 0x4f, 0x87, 0x84, 0x31, 0xa6, 0x9b, 0xdc, 0xb8, + 0x8e, 0x4f, 0x5a, 0x24, 0x11, 0x18, 0xf2, 0xcc, 0xc8, 0xe3, 0xb0, 0x71, 0x58, 0xaf, 0xe3, 0x65, + 0xd3, 0x30, 0xbb, 0x95, 0x46, 0x97, 0x8c, 0x5c, 0x53, 0x9d, 0x1b, 0x76, 0x0f, 0x77, 0xb3, 0x17, + 0x89, 0x93, 0x57, 0x85, 0x44, 0x55, 0x1f, 0xf0, 0xf7, 0x4d, 0x6f, 0x42, 0x49, 0xa6, 0x4c, 0x64, + 0xf2, 0x74, 0xef, 0x6e, 0xaa, 0xab, 0xe1, 0x42, 0x93, 0x3f, 0x0e, 0x90, 0xc1, 0xb0, 0xcb, 0x3e, + 0x5d, 0x5a, 0x0d, 0x0a, 0xa2, 0x7d, 0x54, 0x57, 0xfe, 0x16, 0x2d, 0x1b, 0x18, 0x89, 0x94, 0x60, + 0xa5, 0x58, 0xcc, 0xa0, 0x7f, 0x2f, 0xbb, 0xbb, 0xf8, 0xf2, 0xc6, 0x7b, 0x2b, 0x35, 0x73, 0x5c, + 0x30, 0x60, 0x93, 0x2c, 0x19, 0x30, 0xf7, 0x12, 0x14, 0x26, 0x66, 0xb1, 0xd5, 0x52, 0x48, 0xd5, + 0x65, 0x4c, 0xbb, 0xce, 0xb1, 0x22, 0x2c, 0x4b, 0x3e, 0x0b, 0x0a, 0xf2, 0x19, 0x68, 0xa1, 0x13, + 0x71, 0xaa, 0xd5, 0x21, 0x36, 0x2b, 0xa6, 0xdd, 0x13, 0xd4, 0x34, 0xbc, 0x7c, 0x16, 0x4d, 0x7a, + 0x12, 0x44, 0xeb, 0xa4, 0x72, 0x0d, 0xbc, 0xdf, 0x2f, 0x82, 0xb1, 0x05, 0xc3, 0x52, 0x70, 0x32, + 0x87, 0x1f, 0x83, 0x6a, 0xe3, 0x8b, 0x50, 0x70, 0x53, 0xca, 0xdf, 0x1f, 0xbe, 0x11, 0x83, 0xef, + 0x93, 0xba, 0x41, 0x4a, 0x8c, 0x71, 0xda, 0x28, 0xb9, 0x1e, 0x5c, 0xc4, 0xc6, 0x4c, 0xa2, 0x64, + 0x90, 0x8d, 0x24, 0x35, 0x63, 0x2e, 0x70, 0x8c, 0x3b, 0xc4, 0x7f, 0x0e, 0xe7, 0x72, 0x0f, 0xff, + 0x82, 0xa2, 0x9f, 0x00, 0xef, 0x56, 0x5b, 0xb0, 0xf6, 0xe7, 0x10, 0x28, 0xea, 0xa1, 0x99, 0x88, + 0x34, 0x74, 0xf8, 0x46, 0xdd, 0xb6, 0xc9, 0x8e, 0xfb, 0x79, 0x26, 0x6c, 0xde, 0x43, 0xf8, 0xcb, + 0x4e, 0xc2, 0xfd, 0x9f, 0x56, 0x36, 0x48, 0x5b, 0x3e, 0xaa, 0xd4, 0x7e, 0x20, 0xbb, 0x43, 0xcd, + 0x31, 0xf2, 0xef, 0x85, 0xe3, 0x0d, 0x65, 0xa5, 0x8d, 0xab, 0xa8, 0x6a, 0x91, 0x62, 0xdd, 0x81, + 0xc1, 0x9d, 0x50, 0x28, 0x2c, 0xad, 0xce, 0xd1, 0x4c, 0xc4, 0x4c, 0xc4, 0xc1, 0x61, 0x47, 0x25, + 0xd0, 0x1c, 0x87, 0x33, 0x81, 0x85, 0x72, 0x1c, 0x39, 0xa7, 0x81, 0x5f, 0xd5, 0x23, 0x46, 0xd7, + 0x8e, 0xb4, 0xf7, 0x36, 0x14, 0xdb, 0x46, 0x77, 0xba, 0x31, 0x16, 0xbc, 0x8a, 0xba, 0x96, 0x55, + 0xe3, 0x28, 0x22, 0x52, 0xed, 0x41, 0x5e, 0x63, 0x21, 0xc8, 0x47, 0x68, 0x1d, 0x19, 0x98, 0x64, + 0x6e, 0xcd, 0x48, 0x1c, 0x0f, 0x89, 0x19, 0x00, 0x5b, 0xcd, 0xde, 0x9b, 0x8b, 0x54, 0x62, 0xcf, + 0x5e, 0x0f, 0x8e, 0x9b, 0x0b, 0x82, 0xf2, 0xec, 0xc4, 0x4d, 0xdc, 0xe3, 0x55, 0x3f, 0x18, 0xa5, + 0x58, 0x80, 0xaf, 0x8c, 0xb4, 0x8a, 0xaf, 0x08, 0x15, 0x7d, 0x6b, 0x1d, 0x0e, 0x35, 0x4b, 0x1d, + 0xce, 0x16, 0xc5, 0xc3, 0x0d, 0xb9, 0x80, 0x53, 0xcf, 0x13, 0xe3, 0x2f, 0x75, 0x29, 0x97, 0x5a, + 0x99, 0x36, 0x3a, 0x51, 0x68, 0xcb, 0x82, 0xc1, 0xa3, 0x40, 0x5b, 0x92, 0x35, 0xf8, 0x2b, 0xa8, + 0xc4, 0x74, 0x1e, 0x15, 0xe5, 0xc7, 0x23, 0x06, 0xb2, 0x35, 0xe1, 0x83, 0x26, 0x8c, 0x1d, 0x87, + 0x80, 0xd9, 0xf1, 0x97, 0xaa, 0x84, 0x78, 0x44, 0x62, 0x8c, 0x59, 0x44, 0x8b, 0x1d, 0xb1, 0xa5, + 0x39, 0x37, 0x22, 0x52, 0x5b, 0xbd, 0x74, 0xde, 0x79, 0x16, 0x47, 0xc6, 0x5c, 0xa7, 0x9c, 0x08, + 0x2e, 0xc2, 0x4a, 0x07, 0x62, 0xac, 0x2e, 0xa6, 0xd2, 0x24, 0xd6, 0x40, 0xe5, 0xdd, 0x7b, 0x6f, + 0x84, 0x4a, 0xc3, 0x23, 0x22, 0x6c, 0x42, 0x92, 0x8a, 0x4d, 0xed, 0xa4, 0x18, 0xc7, 0xbf, 0xc2, + 0x04, 0x3c, 0xe2, 0xcb, 0x05, 0xb3, 0x8d, 0x67, 0x63, 0x26, 0xa4, 0xfd, 0x6e, 0x78, 0xc8, 0x3f, + 0x85, 0xef, 0x16, 0x54, 0xb4, 0x0c, 0xb8, 0xc2, 0x2c, 0xc7, 0x35, 0x6c, 0x6b, 0xa2, 0xc5, 0x4c, + 0x54, 0xeb, 0x52, 0x85, 0xe3, 0x4c, 0x7c, 0x15, 0xf2, 0xb1, 0xb6, 0x7b, 0x66, 0x33, 0xea, 0xb7, + 0x4b, 0x69, 0x55, 0x55, 0x57, 0xfc, 0x20, 0x2c, 0xdc, 0xde, 0xba, 0xf2, 0xdb, 0x58, 0xc4, 0xa8, + 0xbc, 0x61, 0x32, 0x51, 0xa0, 0xd6, 0x24, 0xa5, 0x0d, 0x36, 0x25, 0xa8, 0x09, 0x80, 0xa4, 0x0e, + 0x8d, 0xb7, 0xc5, 0x17, 0xf1, 0xa3, 0x29, 0x8e, 0x8c, 0x47, 0x21, 0x5d, 0x5e, 0x79, 0x35, 0xf5, + 0xd5, 0x03, 0x95, 0x4e, 0xcc, 0x20, 0xff, 0x4f, 0x61, 0x7e, 0x59, 0xf3, 0x4f, 0xc1, 0x58, 0x9e, + 0x48, 0x48, 0xc4, 0x31, 0xc4, 0x93, 0x1b, 0x5c, 0x7d, 0x23, 0xc1, 0xf0, 0xec, 0xfa, 0xf6, 0xf4, + 0x49, 0x56, 0xbc, 0xd2, 0x80, 0x1a, 0x65, 0x26, 0x1d, 0x6e, 0x4d, 0x7a, 0xb2, 0x2f, 0x93, 0xaa, + 0xd7, 0xc6, 0x91, 0x22, 0x9a, 0xee, 0x8f, 0xa9, 0xea, 0x10, 0xbb, 0x95, 0xa4, 0xfe, 0xce, 0xb0, + 0x72, 0xd7, 0x14, 0x69, 0x32, 0x14, 0x9d, 0x0f, 0xf1, 0xb6, 0x9a, 0x83, 0x4a, 0x18, 0x54, 0xf3, + 0xb0, 0xc7, 0x34, 0x53, 0xbd, 0x00, 0x1f, 0x55, 0x55, 0xf1, 0x85, 0x6b, 0xf9, 0xb5, 0xe8, 0x35, + 0x37, 0x68, 0x19, 0xaa, 0xea, 0xc7, 0x1e, 0x39, 0x32, 0xff, 0x86, 0xa6, 0xea, 0x4c, 0x85, 0x91, + 0xdf, 0xa6, 0x9a, 0x69, 0xf8, 0x7c, 0x8e, 0x63, 0xce, 0xc2, 0xc8, 0xda, 0x13, 0x75, 0x0d, 0x26, + 0xb0, 0xf8, 0xc7, 0x7d, 0x32, 0xf4, 0xdb, 0xfc, 0x6c, 0x70, 0x63, 0x59, 0x7f, 0x59, 0x88, 0x92, + 0x80, 0xd0, 0x36, 0xbd, 0x27, 0x7c, 0x80, 0x93, 0xc4, 0x3b, 0x22, 0xe9, 0x69, 0xa7, 0x1a, 0x7e, + 0x36, 0xc1, 0x9d, 0x66, 0x71, 0x84, 0x8d, 0x5a, 0x7c, 0x6e, 0x93, 0x3b, 0x96, 0x83, 0xd0, 0xfc, + 0x47, 0x43, 0xb1, 0x34, 0x51, 0x53, 0x45, 0xfe, 0x0b, 0x8a, 0xab, 0xc6, 0x41, 0xf4, 0x11, 0xa9, + 0xc8, 0x48, 0xa5, 0x54, 0x0b, 0x17, 0xc7, 0x6b, 0xf2, 0x62, 0x47, 0x89, 0x39, 0xb5, 0x41, 0x1b, + 0xd0, 0x6a, 0xfc, 0xac, 0xc9, 0xa4, 0x1f, 0x1b, 0x4c, 0xac, 0x40, 0xa2, 0x6b, 0x23, 0x69, 0xb2, + 0x32, 0x0a, 0x0c, 0xc9, 0xc1, 0x13, 0x82, 0xe0, 0x34, 0x07, 0x5d, 0x55, 0xff, 0xc1, 0x04, 0xfe, + 0x7f, 0x61, 0x9d, 0xe4, 0xf5, 0x22, 0xad, 0xb1, 0x4a, 0x25, 0x91, 0x87, 0x0f, 0x49, 0x06, 0xc1, + 0x90, 0x6c, 0x3f, 0xc7, 0x5e, 0x5d, 0x0e, 0x91, 0x98, 0x99, 0x8e, 0x73, 0xa7, 0xdf, 0x04, 0xf6, + 0x51, 0xb8, 0x05, 0x2d, 0x33, 0x2f, 0xcb, 0xe1, 0x49, 0xd5, 0x25, 0xd3, 0x21, 0x4d, 0x83, 0x6c, + 0xe4, 0xd8, 0x51, 0xec, 0xda, 0x03, 0x7c, 0x65, 0xcf, 0x69, 0x0d, 0x55, 0x5e, 0x0f, 0xac, 0x52, + 0xd1, 0x35, 0xa5, 0x75, 0x39, 0x53, 0x95, 0x45, 0x17, 0x87, 0x49, 0x46, 0xf4, 0xb7, 0xe8, 0x86, + 0xe7, 0x77, 0x18, 0x90, 0x5a, 0x71, 0x75, 0x7a, 0x66, 0x87, 0xf8, 0x7b, 0x5c, 0x64, 0x10, 0x5e, + 0xe0, 0x6b, 0xa6, 0x87, 0x6e, 0xd4, 0x8a, 0xc3, 0xd1, 0xb9, 0x68, 0x37, 0x2c, 0x8b, 0xd6, 0xd9, + 0x07, 0xc5, 0xb1, 0xff, 0x05, 0x93, 0x32, 0xd6, 0x0c, 0xcb, 0x58, 0x23, 0x26, 0x7e, 0xaf, 0x6f, + 0xe2, 0xf8, 0xd2, 0xdc, 0x26, 0xc9, 0x3d, 0x6d, 0xb6, 0xd3, 0xcc, 0xf0, 0x69, 0x2b, 0x1a, 0x25, + 0x92, 0x0f, 0x70, 0x8c, 0xa1, 0x51, 0xc1, 0x5e, 0x49, 0xda, 0x23, 0xf6, 0xd9, 0xaf, 0x77, 0xf0, + 0x5e, 0x29, 0x09, 0xcc, 0xb2, 0xd1, 0x30, 0xda, 0xab, 0x72, 0x81, 0xc2, 0x52, 0x7a, 0xea, 0x2f, + 0xf1, 0xa5, 0x09, 0xf2, 0x68, 0x12, 0x98, 0xbc, 0xe2, 0x63, 0x78, 0xa3, 0x7f, 0xfa, 0x1c, 0xb9, + 0xbf, 0xd5, 0x55, 0x7c, 0x14, 0xcf, 0x0b, 0x0f, 0xb6, 0x35, 0x5b, 0xe8, 0xe8, 0x37, 0x23, 0x65, + 0x66, 0xfc, 0x9f, 0x0e, 0x89, 0x18, 0x44, 0x8f, 0xed, 0x1f, 0x65, 0x4c, 0x67, 0x3e, 0xa8, 0x09, + 0xd6, 0xdb, 0x6d, 0xbf, 0xf0, 0xa0, 0xcd, 0x3d, 0xdb, 0xf1, 0x4b, 0x88, 0x3d, 0xc7, 0x93, 0xc9, + 0x15, 0x38, 0xa0, 0x50, 0x62, 0xbc, 0x7c, 0x40, 0xd4, 0x32, 0x90, 0x5b, 0x8d, 0x98, 0xf9, 0x41, + 0x57, 0xc4, 0x85, 0x2f, 0xdb, 0x40, 0x68, 0x36, 0xdb, 0x63, 0x8f, 0xc6, 0xfc, 0xf5, 0xb6, 0xd3, + 0xfc, 0x16, 0x4d, 0xae, 0xdb, 0x45, 0xae, 0xa4, 0x22, 0x63, 0x72, 0x84, 0xfc, 0xd7, 0xc2, 0x14, + 0x0d, 0x46, 0x0b, 0x24, 0x19, 0x22, 0x51, 0xf6, 0x4d, 0xfb, 0x1b, 0x19, 0xd2, 0x1f, 0xc2, 0x97, + 0x00, 0x01, 0x77, 0x2a, 0xf1, 0xe7, 0xbb, 0x48, 0x1b, 0xf0, 0x7f, 0x18, 0x78, 0x26, 0x87, 0xb6, + 0xd9, 0xd9, 0x20, 0x90, 0xf8, 0x77, 0x0e, 0x8c, 0xd1, 0x90, 0xf8, 0xc6, 0xda, 0xce, 0x74, 0xac, + 0xcf, 0x69, 0x7d, 0xb6, 0xdb, 0x6f, 0xc7, 0xcf, 0xe1, 0xd2, 0x09, 0x67, 0x2c, 0x2b, 0x5e, 0xd8, + 0xb8, 0xb8, 0xb8, 0xbf, 0x88, 0xa0, 0x71, 0x86, 0x32, 0x84, 0xd2, 0x11, 0xd7, 0xf0, 0x85, 0xaa, + 0xfc, 0x90, 0x6e, 0xb5, 0x3e, 0xd2, 0x93, 0x3c, 0x23, 0x31, 0xb7, 0x99, 0xaa, 0x1a, 0x03, 0x8d, + 0xe7, 0xed, 0xd5, 0xe3, 0x66, 0x21, 0x2c, 0x11, 0x29, 0x27, 0x6b, 0x7c, 0xe4, 0x34, 0x75, 0x0e, + 0xde, 0xe6, 0xdb, 0xa3, 0xfe, 0xdb, 0x6d, 0xb7, 0xe2, 0xa1, 0xa4, 0xae, 0x6f, 0x7d, 0xc0, 0xc2, + 0x7e, 0x18, 0x26, 0xad, 0x3f, 0x19, 0xd8, 0xc6, 0x1a, 0x20, 0x26, 0x35, 0x50, 0xe2, 0xa1, 0x36, + 0x6d, 0xc6, 0xab, 0x86, 0xea, 0xed, 0x10, 0x83, 0xf8, 0xeb, 0x92, 0xd6, 0xb5, 0xc0, 0xf2, 0x08, + 0x2e, 0xcf, 0xa4, 0xea, 0xca, 0x0b, 0x1e, 0x13, 0x44, 0x08, 0xd1, 0xc3, 0xf1, 0x95, 0xe1, 0x45, + 0xa4, 0x75, 0x5f, 0x5d, 0x0a, 0x06, 0x74, 0x6c, 0x47, 0x43, 0x54, 0x9d, 0x26, 0xbe, 0x12, 0xc3, + 0x6f, 0x8c, 0xab, 0x36, 0x7c, 0xfa, 0xf6, 0xc7, 0x8c, 0xa8, 0xa8, 0xc6, 0xa7, 0x31, 0xed, 0x78, + 0xc2, 0xa0, 0x96, 0xa9, 0xc7, 0xb7, 0x53, 0x05, 0x00, 0xea, 0x2d, 0x2c, 0x33, 0x77, 0xad, 0xc8, + 0xce, 0x52, 0x92, 0xba, 0x8d, 0x6c, 0x24, 0x8c, 0x9f, 0x65, 0xa0, 0x25, 0x69, 0x82, 0xbf, 0xc7, + 0x46, 0x3c, 0xa3, 0xde, 0x67, 0xc5, 0x77, 0xd1, 0xbd, 0x1a, 0x48, 0x4f, 0xc1, 0x16, 0xb5, 0x45, + 0xe3, 0x08, 0xb9, 0x12, 0x9e, 0x84, 0x34, 0xe8, 0x19, 0x8e, 0x48, 0x45, 0xa4, 0x15, 0xd8, 0xe3, + 0x49, 0x3f, 0x19, 0x5c, 0x73, 0xb8, 0xb0, 0x45, 0xc0, 0x2a, 0x27, 0x42, 0xff, 0xa7, 0xdb, 0xba, + 0x33, 0x1b, 0x8c, 0xb5, 0x4a, 0x5f, 0xc5, 0x64, 0x37, 0x9e, 0xe8, 0x82, 0xd9, 0x53, 0x75, 0xb6, + 0xdf, 0x84, 0x6c, 0x0e, 0x62, 0x26, 0x26, 0xc1, 0x9c, 0x91, 0x33, 0xd9, 0xc3, 0xec, 0x71, 0xe1, + 0x42, 0x13, 0x6d, 0xc0, 0x03, 0x09, 0xf4, 0x8b, 0x3c, 0x12, 0x2a, 0x2a, 0x39, 0xe8, 0x1a, 0xbb, + 0x08, 0x27, 0xb8, 0xa1, 0xb3, 0x26, 0x59, 0xef, 0x84, 0x2e, 0x92, 0xff, 0x40, 0xf4, 0x3b, 0x89, + 0x62, 0x82, 0xf4, 0x47, 0x61, 0x0d, 0x6b, 0x67, 0x8d, 0x25, 0x36, 0xcd, 0x8d, 0xe8, 0x9b, 0x8e, + 0x94, 0x48, 0x91, 0x4f, 0xea, 0xaa, 0xab, 0xfe, 0x0b, 0x0e, 0xfa, 0x3e, 0x87, 0xa3, 0xe8, 0xc1, + 0x8f, 0xce, 0x9c, 0xfb, 0xc8, 0x5a, 0x86, 0xf6, 0x60, 0x2c, 0xe3, 0xe3, 0x2b, 0xd8, 0xaa, 0xd2, + 0x7a, 0xc9, 0xd9, 0xec, 0xa9, 0x33, 0x9a, 0x9f, 0x8d, 0x23, 0x35, 0xb7, 0xd9, 0x78, 0x29, 0x43, + 0x63, 0x9c, 0x36, 0x9b, 0x55, 0x83, 0x5b, 0x53, 0xb1, 0x89, 0x1c, 0x19, 0x69, 0x07, 0xe2, 0x95, + 0x31, 0xc3, 0xc1, 0x7a, 0x57, 0xf8, 0xdd, 0x49, 0x39, 0x96, 0x40, 0x90, 0xf5, 0xc5, 0x75, 0x37, + 0x9c, 0xdd, 0xcc, 0x31, 0xb1, 0xb1, 0x90, 0xa3, 0x3a, 0x26, 0x8e, 0x9f, 0xfe, 0x34, 0xad, 0x21, + 0x82, 0xa6, 0x67, 0x9e, 0x2c, 0x0c, 0x70, 0xdb, 0x76, 0x66, 0x3a, 0xfb, 0x5a, 0xb4, 0xaa, 0x0a, + 0xaa, 0x09, 0x01, 0x93, 0x98, 0x9f, 0x8b, 0x28, 0x4d, 0xb6, 0xdb, 0x7e, 0x14, 0xb6, 0x4f, 0x8a, + 0x14, 0x09, 0xfa, 0xd9, 0x55, 0x44, 0xc5, 0x10, 0x98, 0x43, 0x8d, 0x8c, 0x38, 0x4c, 0xd8, 0x0c, + 0x82, 0xf8, 0x2a, 0xa4, 0x56, 0xd4, 0xe6, 0xc0, 0x57, 0x86, 0x5f, 0x8e, 0xcc, 0x1a, 0x46, 0x54, + 0x94, 0x11, 0xd3, 0xe0, 0x83, 0x24, 0xdb, 0xad, 0x91, 0x09, 0xa1, 0xed, 0x59, 0x5e, 0xa5, 0x29, + 0x4a, 0xaa, 0xaa, 0xbf, 0xe1, 0xd8, 0xd4, 0x7b, 0x26, 0xd5, 0x9d, 0xc7, 0xd0, 0x32, 0x7d, 0xf5, + 0xd8, 0xb3, 0x2a, 0xaa, 0xaa, 0xff, 0x85, 0x39, 0x89, 0x1d, 0x6b, 0x5e, 0xdb, 0xd0, 0x68, 0x8d, + 0x5a, 0x89, 0x57, 0x30, 0xc4, 0x55, 0xd6, 0xe4, 0xa7, 0x3a, 0xf8, 0x77, 0x25, 0x94, 0xf5, 0x32, + 0x59, 0x2d, 0x73, 0x42, 0xe6, 0x86, 0x28, 0xe3, 0xab, 0xb5, 0xda, 0x9c, 0x7f, 0xe3, 0x6c, 0x4c, + 0x89, 0x55, 0xc2, 0xa0, 0xd4, 0xce, 0xa0, 0x74, 0xb6, 0x32, 0xc5, 0xb5, 0x34, 0x94, 0x64, 0xe9, + 0x28, 0xc9, 0x49, 0x9d, 0x5f, 0xf1, 0xb5, 0x9c, 0xbb, 0x5a, 0xd5, 0x66, 0xc7, 0x92, 0x45, 0x4e, + 0x7b, 0x2a, 0x4a, 0x8b, 0x98, 0xd6, 0xa6, 0x5a, 0xfa, 0x5a, 0x38, 0x80, 0xb3, 0xd2, 0x6a, 0x7f, + 0xc1, 0x24, 0x79, 0x29, 0xce, 0xf0, 0x7c, 0x10, 0x46, 0x62, 0x5c, 0x9c, 0x07, 0x52, 0x13, 0x64, + 0x54, 0xcf, 0x0e, 0x69, 0xe9, 0x21, 0x9a, 0x8a, 0xd0, 0xee, 0x48, 0x4c, 0xf4, 0xd3, 0x4d, 0x3f, + 0x0a, 0x61, 0xd0, 0xc8, 0xcb, 0x15, 0x3b, 0xf4, 0xd2, 0xdb, 0xbc, 0xcf, 0x95, 0x83, 0xda, 0x0f, + 0xc5, 0xf0, 0x41, 0x8f, 0x61, 0x2a, 0xd0, 0xcc, 0x8d, 0x93, 0x61, 0x48, 0xa1, 0x8b, 0x99, 0xc7, + 0x69, 0xe6, 0x31, 0xa0, 0xf6, 0x90, 0xc9, 0x06, 0x55, 0xf0, 0xf6, 0x06, 0xc4, 0x12, 0x3f, 0xf5, + 0x4d, 0xf2, 0x1e, 0x5e, 0x0d, 0x2b, 0x11, 0x97, 0x51, 0xda, 0x00, 0xed, 0x00, 0xed, 0x64, 0x1d, + 0xac, 0xbf, 0xc6, 0xf6, 0x93, 0x1a, 0x71, 0x79, 0x43, 0xcb, 0x56, 0xa9, 0xc1, 0xb8, 0x43, 0x8d, + 0xdc, 0x4c, 0x81, 0xdd, 0x8e, 0xfe, 0xaa, 0xab, 0xe3, 0x34, 0xaa, 0x39, 0xb6, 0xc9, 0x8c, 0x92, + 0xc6, 0x6e, 0x4c, 0x88, 0xa7, 0xb4, 0x79, 0xc8, 0x57, 0xc6, 0x68, 0x8c, 0xcd, 0x4b, 0x8d, 0xc8, + 0x74, 0x94, 0x8f, 0x93, 0x49, 0xac, 0x7a, 0x3a, 0x7f, 0x0f, 0x51, 0xa5, 0x52, 0x9d, 0x82, 0x2e, + 0xd0, 0x1b, 0x11, 0x2c, 0xac, 0x2b, 0x15, 0xa0, 0x22, 0x97, 0xb7, 0x97, 0xb7, 0xff, 0x82, 0xbd, + 0x11, 0x4b, 0x2c, 0x6c, 0x62, 0xf1, 0xba, 0x8f, 0xa3, 0x8c, 0xc5, 0x6c, 0xab, 0xef, 0x85, 0xc5, + 0x3b, 0x55, 0xa4, 0xa0, 0xb4, 0x63, 0x71, 0xe5, 0x5a, 0x14, 0x5f, 0x8a, 0xdf, 0xe1, 0x42, 0xad, + 0x8f, 0x3b, 0x8a, 0xa4, 0x7d, 0xb3, 0x10, 0x98, 0xc6, 0xa5, 0x06, 0x3d, 0x29, 0xbd, 0xcc, 0x6e, + 0x21, 0xcc, 0x8d, 0x43, 0xc6, 0xc4, 0xd8, 0x59, 0x59, 0x4c, 0x42, 0x46, 0xbf, 0x3a, 0xa9, 0xda, + 0x3c, 0x19, 0xe2, 0x92, 0xa9, 0x8b, 0xe9, 0x93, 0xfe, 0x14, 0x2d, 0x6b, 0xb5, 0xa3, 0xe9, 0x9e, + 0x85, 0xc6, 0xf3, 0xbc, 0xaa, 0x3c, 0x07, 0x64, 0x20, 0xdb, 0x3e, 0x14, 0xec, 0xdf, 0x4a, 0x96, + 0x4d, 0x1a, 0x4d, 0x71, 0x6a, 0xb4, 0x87, 0x4d, 0xf0, 0xa0, 0xa4, 0xd7, 0x88, 0x34, 0x1a, 0x6b, + 0xa7, 0x66, 0x74, 0xd6, 0xf5, 0x45, 0xc4, 0x6e, 0xe1, 0x9f, 0xd3, 0x27, 0x3e, 0x30, 0x7c, 0x61, + 0xb9, 0xb8, 0x51, 0x25, 0xd8, 0xd3, 0x63, 0x44, 0xd2, 0x1f, 0xc2, 0x96, 0x22, 0xf5, 0xa4, 0xf5, + 0x4e, 0xc9, 0x76, 0x4b, 0x04, 0xba, 0x1b, 0xd2, 0x20, 0xcb, 0x86, 0x97, 0xe1, 0x4d, 0x59, 0x95, + 0x44, 0x6d, 0x5a, 0x64, 0x92, 0x8a, 0x60, 0x52, 0xe9, 0xf1, 0xdf, 0x1b, 0x29, 0xd8, 0xf0, 0x24, + 0x43, 0x4e, 0x55, 0xec, 0x65, 0x38, 0xe6, 0xc0, 0x71, 0xdc, 0xd9, 0xa3, 0x5f, 0x9b, 0xd7, 0xe0, + 0x82, 0x7d, 0x4b, 0x8c, 0x6a, 0x24, 0x9a, 0x69, 0x23, 0x7f, 0x4c, 0x79, 0x53, 0x4d, 0x34, 0xff, + 0xc3, 0xda, 0x82, 0xeb, 0x13, 0xf7, 0xec, 0x67, 0xa0, 0xed, 0xaf, 0xf3, 0x90, 0x5d, 0xe4, 0x11, + 0xe4, 0xe9, 0x34, 0xd3, 0x4f, 0xfc, 0x69, 0x0a, 0xc7, 0x19, 0xe4, 0x9f, 0x74, 0x1f, 0x97, 0x0f, + 0x7f, 0x3a, 0x3a, 0x16, 0xc5, 0xb4, 0xd3, 0x15, 0x62, 0xad, 0xb6, 0xfc, 0x29, 0x73, 0x7b, 0x4b, + 0xa3, 0x25, 0x26, 0xb7, 0x3b, 0x39, 0x10, 0xff, 0x84, 0x4a, 0xc4, 0xc4, 0xa3, 0x0f, 0x58, 0xd1, + 0x11, 0xac, 0xf6, 0x36, 0x93, 0x1b, 0x7e, 0x32, 0x3b, 0x33, 0x1c, 0x72, 0x32, 0xfd, 0x62, 0x6a, + 0x94, 0xc5, 0x5b, 0x13, 0x65, 0xc6, 0x6c, 0x4c, 0xdf, 0x1f, 0x8c, 0xac, 0xe9, 0xa5, 0x99, 0x64, + 0xb5, 0x7f, 0x0a, 0x58, 0x66, 0x16, 0x82, 0x6c, 0x0a, 0x43, 0x0b, 0x2f, 0x6d, 0xe7, 0x4e, 0xce, + 0x38, 0x9b, 0x01, 0x36, 0x29, 0x39, 0x08, 0xbf, 0x85, 0x28, 0x16, 0xf1, 0xa1, 0xec, 0xc7, 0x8f, + 0x2d, 0x93, 0x81, 0x03, 0xe9, 0x77, 0x77, 0xb3, 0x9c, 0xe1, 0x3b, 0x7b, 0x1f, 0x06, 0x05, 0x50, + 0xe9, 0x8f, 0xc5, 0x7a, 0x3c, 0xfa, 0x69, 0xa6, 0x9f, 0x84, 0x6d, 0x67, 0x2a, 0x9b, 0x06, 0x3f, + 0x99, 0x32, 0xac, 0xaa, 0x3f, 0x19, 0x32, 0xa6, 0xf7, 0x2a, 0xd2, 0x29, 0x74, 0x22, 0xae, 0x36, + 0x15, 0x1f, 0xd9, 0xb7, 0x3c, 0x8c, 0x8a, 0x1f, 0x90, 0x4f, 0x55, 0xe3, 0xf5, 0x22, 0xc7, 0xb0, + 0x91, 0x62, 0x13, 0xbd, 0x88, 0x77, 0x7d, 0x98, 0x83, 0x97, 0x98, 0x97, 0x84, 0xa9, 0x24, 0x81, + 0xcc, 0x54, 0x79, 0xb3, 0x71, 0x5f, 0x08, 0x52, 0x0c, 0x30, 0x91, 0x08, 0xb7, 0x0e, 0x10, 0x05, + 0x2a, 0x56, 0x82, 0x66, 0xb9, 0xc3, 0xd8, 0xea, 0x17, 0x84, 0x48, 0x49, 0x53, 0x54, 0x88, 0xab, + 0xc6, 0x99, 0x35, 0x9b, 0xe1, 0x1b, 0x0d, 0x33, 0xae, 0xd0, 0xc1, 0x17, 0x35, 0x0b, 0x32, 0x69, + 0x85, 0x9b, 0xe9, 0x7c, 0x67, 0x77, 0x4b, 0x9d, 0x76, 0x2b, 0xd2, 0x63, 0x3c, 0x6c, 0x7e, 0x15, + 0x36, 0x06, 0x34, 0x65, 0x01, 0xc1, 0x1f, 0x29, 0x8a, 0x13, 0x3f, 0x7f, 0xfc, 0x6e, 0x3d, 0xb5, + 0xad, 0xc8, 0xf1, 0xfa, 0xa9, 0x29, 0xcf, 0x93, 0xd0, 0xdd, 0x55, 0x55, 0xff, 0x19, 0x49, 0x86, + 0xc6, 0xd1, 0x5b, 0x8d, 0xde, 0x6b, 0xd6, 0x36, 0x43, 0xd8, 0xd9, 0x90, 0x7f, 0xc6, 0x09, 0x81, + 0xa8, 0xf4, 0x38, 0x0d, 0x84, 0x98, 0x49, 0x84, 0x8c, 0xb5, 0x4e, 0x42, 0x0d, 0x76, 0xb4, 0xfb, + 0xe1, 0xdc, 0x97, 0xc2, 0x84, 0x79, 0xc4, 0x68, 0xb3, 0x1c, 0x09, 0xcf, 0x91, 0xed, 0x37, 0x25, + 0x58, 0x3e, 0x88, 0xfa, 0x78, 0x71, 0x0b, 0x0c, 0x99, 0xd4, 0x41, 0xd1, 0x3f, 0xc7, 0xe1, 0x2c, + 0x1d, 0x5b, 0x67, 0x61, 0xb6, 0xf4, 0xd5, 0xb6, 0x8d, 0xb6, 0xbc, 0x18, 0x1a, 0x08, 0x3a, 0xb5, + 0x97, 0x32, 0x71, 0x44, 0x34, 0x4c, 0xfa, 0x36, 0x49, 0x80, 0xa8, 0x21, 0xc2, 0x7f, 0xf8, 0x2a, + 0x3b, 0xee, 0xb3, 0xb5, 0x8c, 0xa3, 0x53, 0xaf, 0xba, 0x3d, 0x36, 0x66, 0xda, 0x21, 0x78, 0x03, + 0xbe, 0x14, 0xbe, 0x87, 0x52, 0x52, 0x9d, 0x6d, 0x8e, 0x3b, 0x37, 0x60, 0x38, 0xca, 0x7e, 0xf9, + 0x7e, 0x73, 0xe3, 0x21, 0x23, 0x80, 0x13, 0xe0, 0xd8, 0x33, 0xac, 0xe5, 0x1a, 0x06, 0x86, 0x52, + 0x86, 0x29, 0x46, 0x3f, 0x4a, 0x36, 0xbf, 0xf0, 0x8d, 0x98, 0x6d, 0x4b, 0x1d, 0x7e, 0x70, 0x45, + 0x46, 0x75, 0x6d, 0xd3, 0x72, 0x29, 0x71, 0x3f, 0xc1, 0x57, 0x6a, 0xd4, 0x3a, 0xb8, 0xfb, 0xa6, + 0xfd, 0x2a, 0xf8, 0x60, 0x87, 0xe5, 0xef, 0xed, 0xec, 0x68, 0x76, 0x87, 0x73, 0x8a, 0xb1, 0x57, + 0xfe, 0x1d, 0x29, 0x09, 0x0d, 0xb2, 0x32, 0xab, 0x61, 0x22, 0x12, 0xf4, 0x48, 0x18, 0xfa, 0x17, + 0xd6, 0x14, 0x63, 0x05, 0xdf, 0xf8, 0x7b, 0x0e, 0xe8, 0x1d, 0x7a, 0xce, 0x44, 0x67, 0x32, 0x29, + 0xd5, 0x5d, 0xd5, 0x34, 0xdb, 0x6f, 0xc6, 0x93, 0x51, 0xd5, 0xb1, 0x97, 0x58, 0x67, 0x34, 0xa9, + 0x77, 0x2a, 0x19, 0xb8, 0x19, 0x7c, 0xa7, 0x5e, 0x7c, 0x47, 0x3d, 0x17, 0x8a, 0xb1, 0x56, 0xfe, + 0x36, 0x55, 0x03, 0x89, 0x8d, 0xbd, 0xd0, 0x44, 0xa9, 0x3d, 0x2b, 0x1e, 0x46, 0x89, 0xca, 0xc5, + 0x81, 0xbb, 0x42, 0x0c, 0x53, 0x56, 0xe9, 0x13, 0x49, 0xcb, 0xd9, 0xdb, 0xfc, 0x6e, 0xba, 0x4d, + 0x61, 0xcc, 0x06, 0x5e, 0xc2, 0x9a, 0xfc, 0x87, 0x9d, 0x81, 0xae, 0xe1, 0x1b, 0x49, 0x07, 0x55, + 0x64, 0xa2, 0xf1, 0xa7, 0x1a, 0x7e, 0x37, 0xa4, 0x52, 0x91, 0x9d, 0x83, 0x5a, 0x94, 0x0f, 0xf2, + 0x81, 0xc3, 0x64, 0xd8, 0x3f, 0x78, 0xa6, 0x75, 0x3e, 0x24, 0xdc, 0xff, 0x1a, 0x5a, 0xd7, 0x08, + 0x9b, 0xd9, 0x81, 0xb5, 0x6b, 0x52, 0xd1, 0x4b, 0xc6, 0x3d, 0x74, 0xa6, 0xf7, 0x6b, 0x1b, 0xfe, + 0xee, 0xef, 0xe3, 0x7e, 0x5a, 0x31, 0x2c, 0xae, 0x8b, 0x16, 0xdc, 0xb0, 0x57, 0xf6, 0xee, 0x3e, + 0xba, 0x28, 0xb4, 0x74, 0x21, 0xdf, 0xb9, 0x9f, 0xf0, 0xb7, 0x23, 0x25, 0x10, 0x1d, 0xe4, 0x13, + 0x77, 0x90, 0x5e, 0x41, 0x40, 0x69, 0x5e, 0x57, 0xb5, 0xed, 0x7f, 0xf8, 0x2b, 0xa6, 0x52, 0x90, + 0x97, 0xd5, 0xba, 0xc0, 0xd5, 0xc9, 0x99, 0x9b, 0x43, 0x62, 0x40, 0x5f, 0x85, 0xa3, 0xd7, 0x7a, + 0x33, 0x2e, 0x81, 0xab, 0x4f, 0x1d, 0xcd, 0x8a, 0x54, 0xaf, 0x23, 0xca, 0xf6, 0x3f, 0xfc, 0x6d, + 0x85, 0x0c, 0x39, 0x90, 0x1a, 0xd3, 0x6d, 0xb6, 0xa9, 0xea, 0x4d, 0x66, 0xb3, 0x59, 0xb8, 0x68, + 0x4d, 0xad, 0x09, 0xb5, 0xff, 0x0f, 0x62, 0x54, 0xa9, 0x33, 0x1e, 0x95, 0xcc, 0x2d, 0x4c, 0xed, + 0x26, 0xf2, 0x2e, 0xad, 0xb7, 0x59, 0xff, 0xf8, 0x74, 0x51, 0x74, 0xe0, 0xa9, 0x01, 0x01, 0x5e, + 0xc6, 0x85, 0xc3, 0x12, 0x0c, 0xe2, 0x48, 0xe7, 0x9c, 0xe0, 0xd4, 0x51, 0xf4, 0x57, 0x88, 0x73, + 0x7f, 0xf0, 0xf9, 0x4d, 0x36, 0x60, 0x7f, 0xce, 0x38, 0x85, 0xf9, 0x2c, 0x69, 0x3b, 0x0c, 0xcd, + 0x56, 0x9f, 0xd7, 0x7b, 0x75, 0x55, 0x5f, 0x1b, 0x62, 0x61, 0xf3, 0x2f, 0xc2, 0xa5, 0x2e, 0x77, + 0xaa, 0x33, 0x4d, 0x9f, 0xeb, 0xbb, 0xba, 0xaa, 0xaf, 0x86, 0x0f, 0x73, 0x36, 0x29, 0xa9, 0xc4, + 0x95, 0x55, 0xbb, 0xbf, 0xc1, 0x51, 0xac, 0x3e, 0xb6, 0xae, 0xbe, 0x0e, 0x12, 0x57, 0x72, 0x55, + 0x12, 0x93, 0x5c, 0x26, 0x83, 0x37, 0xc1, 0x64, 0x60, 0xee, 0x0e, 0x8c, 0xd2, 0x52, 0xd3, 0x07, + 0xca, 0xc5, 0x67, 0xd7, 0x69, 0xc3, 0xf8, 0xc3, 0xa6, 0x3b, 0x9c, 0xbf, 0x79, 0xf1, 0x08, 0x9d, + 0xcc, 0xb3, 0xb9, 0x98, 0x0c, 0x74, 0x20, 0xf1, 0x7e, 0x1f, 0x9f, 0x0c, 0xce, 0xc5, 0x91, 0x21, + 0x43, 0x01, 0x5b, 0x9a, 0x18, 0x62, 0x76, 0x2a, 0xc6, 0xbd, 0x99, 0xd1, 0xdf, 0xaa, 0xaa, 0xf8, + 0x50, 0xe3, 0x06, 0x09, 0x13, 0x63, 0x86, 0x0a, 0xa4, 0xa6, 0xc2, 0x83, 0x47, 0xd0, 0xf4, 0x7b, + 0xfd, 0xb7, 0x27, 0x7d, 0x3f, 0xc4, 0x90, 0x84, 0x34, 0xa8, 0x31, 0xac, 0xec, 0x5c, 0xbd, 0xec, + 0xf8, 0xc2, 0xe9, 0x0d, 0x78, 0xaf, 0x25, 0x4e, 0x01, 0xde, 0xa8, 0x8a, 0xb7, 0x68, 0x05, 0xb4, + 0x65, 0x15, 0xd0, 0xa4, 0xdd, 0xa7, 0x3e, 0xe6, 0xaf, 0xfc, 0x26, 0x5c, 0x33, 0xbe, 0xf0, 0xf3, + 0xc7, 0x58, 0xc9, 0x8e, 0x6c, 0x75, 0xe5, 0x1a, 0xa1, 0xdd, 0xaa, 0x1d, 0xf6, 0x54, 0xcd, 0xc6, + 0xac, 0xdf, 0x19, 0x24, 0x5f, 0x9e, 0x1e, 0x6b, 0x2b, 0x0e, 0x34, 0x1c, 0x9a, 0x30, 0x1a, 0x2b, + 0xa8, 0xe5, 0x7f, 0x89, 0x33, 0xc7, 0xa0, 0xaa, 0x1e, 0xad, 0xca, 0xf3, 0x28, 0xf8, 0x50, 0xe1, + 0x61, 0x42, 0x2c, 0x19, 0x63, 0x14, 0x60, 0x7e, 0xd0, 0xdc, 0xb8, 0x7f, 0xa1, 0xd1, 0x1b, 0xaa, + 0x70, 0x0e, 0x2a, 0x25, 0x31, 0xc2, 0x4d, 0x83, 0x0c, 0xbc, 0xe1, 0xd3, 0xe1, 0x42, 0x73, 0x70, + 0xcb, 0x2a, 0xf8, 0xd9, 0xc1, 0x8a, 0xdd, 0x09, 0xcb, 0x27, 0xdb, 0x79, 0xd3, 0xe3, 0xec, 0xc7, + 0xc3, 0x66, 0x66, 0xde, 0x67, 0x10, 0x56, 0xba, 0xf9, 0x77, 0x9c, 0xe3, 0x14, 0x7e, 0x33, 0xc9, + 0x44, 0x26, 0x9b, 0xb2, 0xae, 0xd6, 0xe8, 0xf1, 0xc4, 0x06, 0x4b, 0x7a, 0xd1, 0xeb, 0x8c, 0x2e, + 0x31, 0x56, 0x26, 0x93, 0xaf, 0x57, 0x42, 0xbd, 0x24, 0x84, 0x70, 0xee, 0x78, 0xb9, 0xbf, 0xa4, + 0x75, 0xff, 0x05, 0xa4, 0x23, 0x7b, 0x06, 0x55, 0x56, 0xe4, 0x4f, 0x8c, 0x29, 0x58, 0x76, 0xdb, + 0x72, 0xad, 0xc4, 0x16, 0x0c, 0x72, 0xba, 0xac, 0x30, 0x9e, 0x02, 0x26, 0x0c, 0x95, 0x56, 0xe7, + 0x8b, 0x90, 0x85, 0x1b, 0xd7, 0xa8, 0x31, 0x9b, 0x3d, 0x0b, 0xc2, 0x26, 0xc0, 0x93, 0x58, 0x67, + 0x7d, 0x69, 0x31, 0x41, 0xce, 0xda, 0xdc, 0x78, 0xd2, 0x66, 0x89, 0x3d, 0xa3, 0x56, 0x03, 0x83, + 0x62, 0x87, 0x42, 0x91, 0x78, 0x8e, 0x06, 0xed, 0x46, 0x5b, 0x9f, 0xb7, 0xfe, 0x11, 0xc9, 0x74, + 0x96, 0x30, 0x9c, 0xca, 0x63, 0x88, 0x4a, 0x97, 0xc1, 0x5d, 0x63, 0xd8, 0x8b, 0x5d, 0xb7, 0x63, + 0x4d, 0x3e, 0xf8, 0x2b, 0x8f, 0xdd, 0xf1, 0xcc, 0xda, 0xcc, 0xd8, 0xf5, 0xe6, 0x3e, 0x8e, 0x0c, + 0x01, 0x5f, 0x1b, 0xcc, 0xc9, 0x19, 0x56, 0x98, 0x2b, 0x13, 0x58, 0x3b, 0x7e, 0x8e, 0x55, 0xde, + 0x29, 0x2e, 0x2a, 0xaa, 0xab, 0xbb, 0xbf, 0x8c, 0x2b, 0x5c, 0x3b, 0xad, 0x9e, 0x2c, 0xe9, 0x32, + 0x45, 0x38, 0xfe, 0x11, 0x37, 0x1a, 0xf8, 0x25, 0xcc, 0x02, 0x4d, 0xc0, 0x26, 0x6e, 0xcd, 0x26, + 0x80, 0xb0, 0x1b, 0x88, 0x88, 0xb7, 0x07, 0x07, 0x1e, 0xd6, 0xbf, 0xe3, 0x25, 0x50, 0x85, 0x68, + 0xa9, 0x7a, 0x8a, 0xd7, 0xa6, 0x9c, 0x76, 0xe9, 0x4c, 0x6b, 0xf1, 0xa4, 0xb1, 0xc7, 0xa8, 0x35, + 0x01, 0xb4, 0x55, 0x55, 0x79, 0xd9, 0x4d, 0x76, 0x4b, 0x87, 0x02, 0x9a, 0xb2, 0x36, 0xab, 0x0c, + 0x87, 0x68, 0x7f, 0x8d, 0xc9, 0x06, 0x57, 0x2e, 0xf2, 0xdb, 0x85, 0x54, 0x25, 0x68, 0x0e, 0xcd, + 0xec, 0xd5, 0xea, 0x59, 0x3d, 0x4c, 0x7f, 0xe3, 0x04, 0x96, 0x88, 0x72, 0xe8, 0xa8, 0xb7, 0xa5, + 0x36, 0x9f, 0x59, 0x80, 0xee, 0xa8, 0xea, 0x8e, 0xa9, 0xea, 0x9e, 0x4d, 0xc4, 0xdb, 0xb1, 0x78, + 0xfc, 0x6d, 0xc6, 0xdb, 0x34, 0x9b, 0xa6, 0xc6, 0xac, 0x4f, 0xe1, 0x42, 0x71, 0xd1, 0x01, 0x6e, + 0x8d, 0x38, 0x6a, 0xaa, 0xd4, 0x1e, 0x7d, 0x62, 0x33, 0x0f, 0x50, 0xe6, 0x25, 0xf1, 0x92, 0x32, + 0x72, 0x96, 0xa6, 0x61, 0xb7, 0x30, 0x92, 0x59, 0xa0, 0x6d, 0xaa, 0xa6, 0xbc, 0x76, 0xa7, 0xe5, + 0x4e, 0xc8, 0x06, 0x56, 0xc7, 0x08, 0xd1, 0xe9, 0x16, 0x5e, 0x14, 0xb2, 0x88, 0xe8, 0x34, 0xc9, + 0x42, 0x53, 0xa9, 0x29, 0x68, 0x96, 0x4b, 0x7e, 0x3f, 0x05, 0x4c, 0x06, 0xc0, 0x00, 0x00, 0x00, + 0x01, 0x41, 0x9a, 0x05, 0x02, 0xb0, 0x3a, 0x9f, 0x30, 0xb4, 0xe9, 0xfd, 0x1c, 0x02, 0x5f, 0x04, + 0x62, 0x0e, 0xc7, 0xc9, 0xd7, 0xab, 0x3e, 0xb9, 0x43, 0xd8, 0x82, 0x9c, 0x7f, 0xcb, 0xfd, 0xeb, + 0x9b, 0x19, 0x68, 0xfe, 0xf8, 0xeb, 0x42, 0xd6, 0x83, 0x73, 0xca, 0x9c, 0xda, 0x6d, 0xf1, 0x3c, + 0x14, 0x18, 0xb4, 0x2d, 0x39, 0x68, 0x5a, 0x69, 0x52, 0xe0, 0x9c, 0xd7, 0x67, 0xdd, 0xf2, 0xfa, + 0xe7, 0x3e, 0x0b, 0x84, 0xb4, 0xc0, 0x56, 0xed, 0xa5, 0x1f, 0x57, 0x52, 0x25, 0x71, 0x22, 0x9a, + 0x85, 0x26, 0x1b, 0xf2, 0x41, 0x1d, 0x2f, 0x1c, 0x35, 0xa6, 0xb6, 0x9a, 0xdb, 0x60, 0xed, 0x78, + 0x25, 0xb4, 0xd6, 0xd3, 0x5b, 0x92, 0xf5, 0xc9, 0x97, 0x8c, 0xed, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, + 0x4d, 0x78, 0x2b, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, 0x62, 0x74, 0xf8, 0x2b, 0xe9, 0x25, 0xa4, 0x96, + 0x92, 0x49, 0x97, 0x82, 0xeb, 0x4d, 0x6d, 0x35, 0x99, 0x0e, 0x9f, 0x04, 0x9d, 0xa6, 0xb2, 0xfa, + 0x2a, 0x54, 0xfa, 0xa5, 0x5e, 0xa9, 0x8a, 0xea, 0x95, 0x7a, 0x91, 0x3e, 0xa4, 0x49, 0x7a, 0xa7, + 0x4b, 0xaa, 0x74, 0xba, 0x91, 0x3e, 0xa9, 0xd1, 0xfa, 0x96, 0xae, 0x09, 0x08, 0xd3, 0x5a, 0x75, + 0xe0, 0xa2, 0xd3, 0x5b, 0x4d, 0x69, 0xd7, 0x10, 0x15, 0xe9, 0x25, 0xa4, 0x90, 0xe1, 0x2a, 0x69, + 0x8b, 0x62, 0xdf, 0xf8, 0x2d, 0xb4, 0xd6, 0xd3, 0x5d, 0x3a, 0xf5, 0x4a, 0xbc, 0x12, 0xda, 0x69, + 0x03, 0x40, 0xda, 0x69, 0x03, 0x40, 0xc7, 0x95, 0x71, 0x04, 0x74, 0x39, 0xd8, 0x9e, 0x87, 0x63, + 0x3f, 0x54, 0xed, 0x75, 0x70, 0x7e, 0x8e, 0x4a, 0x4e, 0x68, 0x8e, 0x08, 0xe0, 0x87, 0x0e, 0x71, + 0xf4, 0x43, 0xa7, 0xc4, 0x5a, 0x69, 0x9a, 0x4d, 0x35, 0x8b, 0xe1, 0x3c, 0x84, 0x8a, 0x4b, 0x3e, + 0x1f, 0x0d, 0x8e, 0xc5, 0xce, 0x74, 0x4a, 0x5e, 0x2d, 0x8b, 0x79, 0x79, 0xe0, 0x9d, 0x21, 0x91, + 0x61, 0x49, 0xbe, 0x4e, 0xa5, 0x4a, 0xe8, 0x81, 0xfd, 0xbe, 0xa5, 0x4f, 0xa8, 0x8e, 0x0a, 0xe1, + 0x4b, 0x4d, 0x24, 0x93, 0x4d, 0x24, 0x93, 0x4d, 0x30, 0x6c, 0x1b, 0x4d, 0x30, 0x6c, 0x1e, 0x55, + 0xd0, 0xa7, 0xfa, 0x2b, 0xdf, 0x26, 0x2b, 0x8a, 0xd7, 0x52, 0xa4, 0x6f, 0x34, 0x56, 0x25, 0xd8, + 0x3a, 0xbc, 0x3a, 0x8a, 0x00, 0x85, 0xa2, 0x4c, 0xd3, 0xf3, 0xfc, 0xba, 0x5d, 0xae, 0xbf, 0x4a, + 0xbf, 0x36, 0x9b, 0x70, 0x24, 0x02, 0x90, 0xdf, 0x1a, 0x32, 0xac, 0x36, 0xa8, 0x84, 0xcb, 0x67, + 0xf5, 0xfe, 0x04, 0x0f, 0xd4, 0xc9, 0x2f, 0x44, 0x32, 0x22, 0x2f, 0x30, 0x43, 0x77, 0xf4, 0x4e, + 0xfa, 0xf4, 0x77, 0x20, 0x4c, 0xf8, 0x7c, 0xdf, 0x56, 0x42, 0xb0, 0x28, 0x01, 0x44, 0x68, 0x43, + 0x85, 0xf5, 0x41, 0xea, 0x84, 0xad, 0x09, 0x83, 0x52, 0x9e, 0x1e, 0xa5, 0x76, 0x44, 0xfc, 0xce, + 0x70, 0x6f, 0x4b, 0x0c, 0xc8, 0xd2, 0x18, 0xb6, 0x3b, 0xa9, 0xb9, 0x6e, 0x2d, 0xf8, 0x90, 0x42, + 0x14, 0x94, 0x01, 0x6f, 0x0b, 0x25, 0xf1, 0x08, 0x3d, 0x43, 0x00, 0x77, 0xb2, 0xe0, 0xdb, 0x43, + 0x0d, 0xe6, 0x58, 0xe7, 0x81, 0xc3, 0x86, 0x0c, 0xbb, 0x23, 0xd8, 0x5b, 0xbb, 0x79, 0xce, 0x8a, + 0x18, 0xbf, 0x88, 0x08, 0x82, 0xb2, 0x3b, 0x37, 0x20, 0x01, 0xd0, 0x3a, 0x89, 0x59, 0x84, 0xa0, + 0x56, 0xb2, 0xf2, 0xb2, 0x55, 0x3c, 0x78, 0x07, 0x87, 0x14, 0x25, 0x8b, 0x84, 0x01, 0x48, 0x23, + 0x2a, 0xaf, 0xe4, 0xfc, 0x87, 0xbc, 0xc1, 0xd6, 0x06, 0x08, 0xc0, 0x9a, 0x8b, 0xa8, 0xb8, 0xbc, + 0x5e, 0x39, 0x46, 0xe2, 0xca, 0x5e, 0x2b, 0x8a, 0xc4, 0x72, 0x05, 0x15, 0x71, 0xfd, 0x0f, 0xe5, + 0x46, 0xeb, 0xe0, 0x15, 0x84, 0x02, 0x21, 0x40, 0x82, 0xcf, 0x87, 0xb1, 0xef, 0xaa, 0xea, 0xaa, + 0xbc, 0x83, 0x84, 0x42, 0x23, 0xc8, 0x34, 0x01, 0xae, 0x31, 0xac, 0x7d, 0x93, 0x0a, 0x93, 0x80, + 0xe4, 0x39, 0x07, 0x88, 0x00, 0x01, 0xa6, 0x26, 0x00, 0x15, 0x26, 0x54, 0xf0, 0x61, 0xf1, 0x01, + 0x00, 0xa7, 0x68, 0xb5, 0x6b, 0x2c, 0xe2, 0x7c, 0x2c, 0x01, 0x50, 0xea, 0x19, 0x64, 0xf1, 0xe3, + 0x40, 0x70, 0xb4, 0x1a, 0xb6, 0x00, 0xf6, 0x97, 0x4b, 0x0f, 0xda, 0x9e, 0x0c, 0xf1, 0xc1, 0xac, + 0xc1, 0x82, 0x11, 0x23, 0x2d, 0xd0, 0xfc, 0x25, 0x2d, 0xd6, 0x3c, 0x5e, 0x59, 0xa6, 0x58, 0xc5, + 0x65, 0x8c, 0x50, 0x6a, 0x2e, 0xe2, 0x7f, 0x08, 0x83, 0x10, 0x87, 0x51, 0x86, 0x7e, 0xb5, 0x27, + 0x96, 0x61, 0x6a, 0xe0, 0x40, 0x05, 0x30, 0x4b, 0xd0, 0x45, 0x91, 0xd0, 0x40, 0x24, 0x78, 0x43, + 0x26, 0x57, 0x96, 0x3e, 0xd2, 0x85, 0x4a, 0xe7, 0x08, 0x46, 0x45, 0x60, 0x75, 0x00, 0xd4, 0x51, + 0xe1, 0xec, 0x03, 0x51, 0xef, 0x46, 0x88, 0x85, 0xe1, 0xa5, 0x80, 0x3e, 0x2d, 0xfb, 0x1a, 0x22, + 0x0b, 0x45, 0xb2, 0xc1, 0x0c, 0x65, 0xf7, 0x52, 0xfa, 0x96, 0xc5, 0x67, 0x8f, 0x3c, 0x18, 0x4d, + 0xc4, 0xbc, 0xff, 0xf1, 0x24, 0x10, 0x7c, 0xb3, 0x59, 0xcf, 0x05, 0x18, 0x31, 0xe8, 0x2b, 0x5c, + 0x1c, 0x83, 0x0e, 0x10, 0x12, 0x30, 0x20, 0xa7, 0xca, 0xbf, 0x69, 0x57, 0x51, 0x75, 0x13, 0xfe, + 0x32, 0x24, 0x1e, 0x73, 0xcb, 0x19, 0x6c, 0x59, 0x07, 0xd5, 0x8a, 0x90, 0x78, 0x0c, 0x98, 0xf8, + 0x1d, 0x0f, 0xe4, 0xe0, 0x2b, 0x64, 0x8e, 0x18, 0x40, 0x77, 0x32, 0xa1, 0x75, 0xe1, 0x81, 0x91, + 0x23, 0xc1, 0xdb, 0xbf, 0xd6, 0x20, 0x38, 0x14, 0x2a, 0x5f, 0x27, 0xbd, 0xdc, 0xb0, 0x6e, 0xe7, + 0x1f, 0x65, 0x81, 0x83, 0xef, 0xc4, 0x97, 0x8a, 0x33, 0xf0, 0x69, 0x86, 0x46, 0x51, 0x3c, 0x4e, + 0x39, 0x7d, 0xde, 0xaa, 0xb8, 0x90, 0xb1, 0x06, 0x24, 0xb8, 0x44, 0x48, 0xc8, 0x34, 0x1b, 0x4c, + 0xa8, 0x9e, 0x2d, 0xdd, 0x91, 0x72, 0x88, 0x1e, 0x0f, 0x05, 0x41, 0xaa, 0x00, 0xfd, 0x1e, 0x00, + 0x1c, 0x3f, 0x3c, 0xf2, 0x88, 0xd4, 0xa2, 0x4b, 0xe3, 0x08, 0x4a, 0x54, 0x98, 0x00, 0xdc, 0xc9, + 0x42, 0xbd, 0x9e, 0x2e, 0x5e, 0x58, 0x62, 0x9a, 0x85, 0xc7, 0xfc, 0x2a, 0xa8, 0x23, 0xe8, 0x2a, + 0xd0, 0x8f, 0x16, 0x21, 0x76, 0xd1, 0x0b, 0x9b, 0x0b, 0xfc, 0x28, 0x28, 0x3a, 0x86, 0xa5, 0x80, + 0x0f, 0x03, 0xb3, 0x53, 0x24, 0x06, 0x96, 0x35, 0x20, 0x60, 0x6a, 0x4a, 0x3c, 0xb2, 0xbf, 0x55, + 0x77, 0x13, 0x19, 0x91, 0x4e, 0x45, 0xc9, 0x8a, 0xb3, 0x4b, 0x34, 0x47, 0x84, 0xbc, 0xba, 0xb7, + 0x26, 0x28, 0x52, 0xc6, 0xff, 0xc4, 0x89, 0x82, 0x55, 0x2e, 0xda, 0xd0, 0xcd, 0x03, 0xcf, 0x1c, + 0xd6, 0x67, 0xc4, 0x82, 0xaf, 0x2e, 0x60, 0xf7, 0x82, 0x1c, 0x3e, 0x0e, 0xbc, 0xfb, 0xe5, 0x8b, + 0xf0, 0xc0, 0x85, 0x9f, 0xa0, 0x9b, 0x90, 0x8f, 0x44, 0xae, 0x11, 0x0c, 0x10, 0x50, 0xb8, 0xa1, + 0xd7, 0x10, 0x19, 0x05, 0xba, 0xd4, 0x51, 0x8a, 0xc5, 0x62, 0xb7, 0xe2, 0x62, 0x62, 0x1e, 0x5b, + 0xb1, 0x58, 0xa3, 0x8a, 0x0d, 0xbf, 0x7d, 0xdf, 0x88, 0x21, 0x5e, 0xf0, 0x9f, 0x43, 0x5e, 0x15, + 0xeb, 0xa8, 0x98, 0x81, 0x3f, 0x08, 0x85, 0x2d, 0x09, 0xe1, 0x7b, 0x9b, 0xc7, 0xae, 0x2c, 0xcc, + 0x78, 0xf0, 0x3e, 0x01, 0xa9, 0x60, 0x03, 0xc2, 0x22, 0x42, 0x85, 0x15, 0x8a, 0xda, 0x68, 0x56, + 0x25, 0xe5, 0xef, 0xe5, 0x8d, 0x21, 0x46, 0x25, 0xe3, 0xef, 0xce, 0xfc, 0x40, 0x90, 0x9f, 0x7b, + 0xad, 0x7c, 0x43, 0xad, 0x7e, 0x2f, 0xbb, 0xdd, 0xdf, 0xcc, 0x7d, 0xdc, 0x6f, 0x43, 0x75, 0x04, + 0x3d, 0xdd, 0xd5, 0x54, 0x48, 0x81, 0x41, 0x28, 0xa3, 0x8a, 0xcc, 0xc9, 0x6c, 0xcc, 0xdf, 0x10, + 0x0a, 0x4c, 0x2b, 0x2d, 0x8a, 0xc5, 0x19, 0x60, 0xc5, 0x18, 0xac, 0x56, 0xe2, 0xb7, 0x77, 0xf0, + 0x80, 0x88, 0xa3, 0x2c, 0x62, 0xb1, 0x5b, 0x8a, 0x3b, 0xfb, 0x8a, 0xff, 0xad, 0x42, 0xfd, 0x05, + 0x6a, 0x1c, 0xe2, 0x82, 0x90, 0x3e, 0x3d, 0x0b, 0xdf, 0x08, 0xb9, 0xb0, 0xfe, 0x78, 0x98, 0x54, + 0x98, 0xe9, 0xc4, 0x0b, 0x6c, 0x93, 0xee, 0x70, 0x65, 0x12, 0x68, 0x50, 0x6c, 0x20, 0x88, 0xf5, + 0xce, 0x71, 0x55, 0xc5, 0x40, 0xb9, 0x5f, 0x0a, 0x84, 0xac, 0x88, 0x2f, 0xed, 0x64, 0x19, 0x99, + 0x04, 0xb9, 0x65, 0x1c, 0x95, 0xf8, 0x42, 0x85, 0xee, 0x73, 0xec, 0xb5, 0xfc, 0x0a, 0xbc, 0xd5, + 0x7c, 0xb8, 0x0d, 0x79, 0x8e, 0xb5, 0x84, 0x3a, 0x09, 0xa6, 0x82, 0x4e, 0x60, 0xc2, 0xae, 0x6e, + 0xc6, 0xea, 0xa0, 0xbf, 0x94, 0x45, 0xef, 0xe2, 0xf7, 0x15, 0xf7, 0x68, 0x9c, 0x48, 0xb3, 0x7e, + 0xab, 0x83, 0x18, 0x98, 0xc0, 0x82, 0x6f, 0x71, 0x0e, 0x0a, 0x03, 0x38, 0x06, 0x07, 0x8e, 0x3d, + 0xea, 0x5f, 0xf1, 0x03, 0x0a, 0x29, 0x93, 0x59, 0x9a, 0xcb, 0x9b, 0xb8, 0x68, 0xf1, 0x20, 0xf5, + 0x75, 0x35, 0xcd, 0x78, 0x82, 0x95, 0x61, 0x53, 0x39, 0x02, 0x06, 0x38, 0x9e, 0x27, 0xe2, 0x05, + 0x68, 0x73, 0x78, 0x92, 0xc2, 0x96, 0x7c, 0x48, 0x8b, 0x4e, 0x3e, 0xfb, 0xbb, 0xf1, 0x22, 0x48, + 0x4a, 0xd7, 0x13, 0x19, 0xc7, 0x2e, 0x2c, 0xea, 0x23, 0xe6, 0xb5, 0x9d, 0x7c, 0xa2, 0xde, 0xff, + 0x36, 0xb2, 0x62, 0xc4, 0x41, 0x66, 0x27, 0x89, 0x10, 0x52, 0x3b, 0xfc, 0x32, 0x3c, 0xaa, 0xaa, + 0xa2, 0xe2, 0x9a, 0xd7, 0x7f, 0x18, 0x2a, 0xaa, 0xaa, 0x9a, 0xaf, 0x17, 0x17, 0xef, 0x90, 0xf2, + 0x62, 0x5e, 0x27, 0xf2, 0x9d, 0xf7, 0xe2, 0x38, 0x91, 0x30, 0x59, 0x89, 0xf1, 0x1e, 0x21, 0xd5, + 0x72, 0x62, 0x02, 0x57, 0x77, 0x77, 0x77, 0x7f, 0x36, 0xf7, 0xc2, 0x32, 0x5d, 0xdd, 0xf1, 0x18, + 0x2d, 0xe0, 0x84, 0x75, 0xef, 0xdf, 0x43, 0x5e, 0x4e, 0x12, 0xbd, 0xdd, 0x0d, 0xfe, 0x24, 0xdd, + 0x55, 0x72, 0x95, 0xef, 0xc4, 0x88, 0xbc, 0x4c, 0xbc, 0xd7, 0x77, 0x70, 0x4b, 0x88, 0x12, 0x32, + 0xf7, 0xbc, 0x6f, 0xcb, 0x90, 0xf7, 0x7f, 0x98, 0xaf, 0x7f, 0x82, 0x8b, 0xbb, 0xbe, 0xee, 0xfe, + 0x25, 0xdd, 0xdd, 0xfc, 0xb6, 0xe5, 0x65, 0x7d, 0x95, 0xdd, 0xdf, 0x11, 0xe2, 0x7c, 0x4e, 0x7e, + 0xef, 0x77, 0x04, 0x98, 0x8f, 0x12, 0x41, 0x8f, 0x7f, 0x12, 0x12, 0x16, 0xef, 0x7b, 0x96, 0x3e, + 0x22, 0x09, 0x33, 0xfe, 0xfc, 0x44, 0x5e, 0xee, 0xef, 0x77, 0xf5, 0x7f, 0x9a, 0xee, 0xef, 0xc4, + 0x08, 0x2b, 0xbb, 0xbb, 0xbb, 0xba, 0xe6, 0x23, 0xbb, 0xf1, 0x1f, 0x97, 0xaa, 0x84, 0xfa, 0xb7, + 0xd5, 0xe4, 0xea, 0xc5, 0x75, 0x70, 0x7e, 0xaf, 0x15, 0xcd, 0x55, 0x55, 0xf1, 0x1a, 0xd6, 0xf7, + 0xc4, 0x89, 0x05, 0x66, 0x8e, 0x86, 0xf2, 0xa4, 0x7b, 0x4d, 0xde, 0xfc, 0x48, 0x8f, 0x10, 0x41, + 0xae, 0xee, 0x75, 0x1c, 0x40, 0x21, 0x95, 0x8f, 0xcd, 0x5c, 0x93, 0xd1, 0xdd, 0xf1, 0x10, 0x89, + 0x08, 0xca, 0x7b, 0x74, 0xf6, 0xd3, 0xe2, 0x44, 0x71, 0x22, 0x14, 0x76, 0x84, 0x79, 0xbb, 0xb8, + 0xbe, 0x8b, 0xa8, 0x8e, 0x72, 0x2c, 0xbd, 0x36, 0xff, 0xf2, 0x5b, 0x29, 0x0b, 0x28, 0xcb, 0x11, + 0x09, 0x09, 0x4d, 0x6a, 0xf6, 0x32, 0x28, 0xf1, 0x24, 0xbc, 0xec, 0x50, 0x65, 0x86, 0xe2, 0x21, + 0x43, 0x45, 0x7b, 0xbb, 0x8a, 0xf5, 0x58, 0xae, 0xf5, 0xc4, 0x09, 0x2d, 0xee, 0xfc, 0x4f, 0xd9, + 0xdd, 0xc4, 0x2c, 0x5f, 0x8c, 0xbb, 0x6e, 0xdb, 0xa6, 0xe6, 0x67, 0x2f, 0x8f, 0xdc, 0xa3, 0x6f, + 0xa3, 0xc4, 0x7e, 0xe4, 0x52, 0xdb, 0x1b, 0x7e, 0x11, 0xad, 0x6b, 0x5a, 0xa6, 0x56, 0x63, 0xf0, + 0x53, 0xdb, 0x2d, 0xae, 0x4b, 0x4b, 0xaa, 0x68, 0xed, 0xf0, 0x8c, 0xba, 0x4b, 0x1f, 0x4c, 0x67, + 0x31, 0x18, 0x1a, 0x70, 0x0d, 0x11, 0x5d, 0x6e, 0xc3, 0x7d, 0xf9, 0x0a, 0xc9, 0xb4, 0xd8, 0xd7, + 0x54, 0xeb, 0xcb, 0x4e, 0x76, 0x4f, 0xfc, 0xb3, 0xc0, 0x60, 0x47, 0x65, 0xae, 0x26, 0xaa, 0xa2, + 0xe2, 0xb1, 0x58, 0xad, 0xfc, 0xd5, 0x77, 0x57, 0xc9, 0x10, 0xd1, 0xc5, 0x62, 0xb5, 0xd0, 0xa6, + 0x05, 0xe8, 0xb8, 0x4b, 0xd1, 0xd1, 0xd5, 0x72, 0xef, 0x63, 0xf5, 0x38, 0xbe, 0x6a, 0x3d, 0x57, + 0x04, 0x94, 0xdb, 0x4d, 0xb2, 0x27, 0xd7, 0x0f, 0xaa, 0x3d, 0xf5, 0x36, 0x7c, 0x12, 0x59, 0xb3, + 0x46, 0xa8, 0xf2, 0xb8, 0x27, 0x11, 0x3d, 0xd1, 0xaa, 0x2a, 0x28, 0xc5, 0x72, 0x5d, 0xdd, 0xfc, + 0x12, 0x14, 0x6e, 0x49, 0xd2, 0xc7, 0xf2, 0x96, 0xe4, 0x07, 0x6b, 0x10, 0x08, 0xa9, 0xa7, 0x3e, + 0x33, 0xe8, 0xbe, 0x3e, 0xb2, 0xe2, 0x60, 0xa8, 0xc2, 0x38, 0x77, 0x14, 0xbc, 0x94, 0x96, 0x6a, + 0x2e, 0xbf, 0x7c, 0x3b, 0x5a, 0xa8, 0xfa, 0x08, 0xd7, 0xa0, 0x95, 0x75, 0xab, 0x6d, 0x9e, 0x1f, + 0xe2, 0x23, 0x28, 0x6e, 0xec, 0xde, 0xef, 0x2d, 0x2e, 0x73, 0x8b, 0xbc, 0x5b, 0x62, 0x8f, 0x05, + 0x75, 0x10, 0xb2, 0xa5, 0xac, 0xa9, 0xe9, 0x46, 0x7d, 0x92, 0xd1, 0x95, 0x83, 0x32, 0xff, 0x6c, + 0x7c, 0x64, 0x4b, 0xcb, 0xcf, 0xf1, 0x0a, 0x88, 0xac, 0x65, 0x03, 0x59, 0x07, 0xcc, 0x0f, 0x98, + 0x2e, 0x33, 0x9a, 0x74, 0xfe, 0x22, 0x99, 0x3e, 0xa8, 0xf7, 0x5c, 0x15, 0xd6, 0x34, 0x93, 0xd9, + 0x25, 0x79, 0xfd, 0x8e, 0xbe, 0x28, 0xa1, 0xb5, 0xb3, 0x45, 0x16, 0x65, 0xfe, 0x3d, 0x4e, 0xab, + 0xc4, 0xd1, 0x67, 0x23, 0x46, 0x93, 0x14, 0x6f, 0xc7, 0xe4, 0xbb, 0x3c, 0xb1, 0x58, 0xa3, 0x14, + 0x62, 0xbe, 0x20, 0x64, 0x34, 0x42, 0xdd, 0x56, 0x1d, 0xe6, 0x6e, 0x81, 0x06, 0x09, 0x99, 0x34, + 0x7d, 0xda, 0x41, 0x01, 0xb1, 0xa5, 0xa2, 0x9f, 0x5f, 0x29, 0x5d, 0xc5, 0x62, 0xbf, 0x2c, 0xf8, + 0x7c, 0x1e, 0xa9, 0x53, 0x2f, 0x56, 0x7c, 0xb0, 0xfb, 0x00, 0x77, 0x6b, 0x0a, 0x98, 0xf9, 0x7c, + 0xec, 0x2e, 0x6c, 0xf4, 0xdf, 0x65, 0x62, 0xb6, 0xdf, 0x89, 0x27, 0x3d, 0x0b, 0x4f, 0x5d, 0x12, + 0x0f, 0xae, 0x1f, 0x04, 0x84, 0xa6, 0xc6, 0x65, 0xd3, 0x0a, 0xe2, 0x8a, 0xed, 0x30, 0x9e, 0xcd, + 0xfe, 0xb9, 0x7c, 0x11, 0x91, 0xdf, 0x8b, 0xe6, 0xaa, 0xfe, 0xbe, 0x3e, 0x8b, 0x8a, 0xb9, 0x24, + 0x95, 0xa4, 0x97, 0x77, 0x77, 0x7f, 0x59, 0x7c, 0x96, 0xd3, 0x64, 0x75, 0x3e, 0xfb, 0xba, 0xe0, + 0xae, 0x45, 0x47, 0x5a, 0x83, 0x1a, 0x4c, 0xb1, 0xd0, 0x7e, 0x88, 0x89, 0x1d, 0xf0, 0xec, 0x77, + 0x2e, 0x21, 0x84, 0xa6, 0x9a, 0xa8, 0xda, 0x8a, 0xbd, 0xe2, 0xb9, 0x71, 0xef, 0xd7, 0x05, 0x22, + 0xb1, 0xd8, 0xe6, 0xa1, 0x4b, 0x12, 0x4c, 0x0c, 0xb8, 0xc4, 0x89, 0x2b, 0x77, 0xc1, 0x19, 0x68, + 0xcc, 0x46, 0x2d, 0xc7, 0x82, 0x1d, 0xb6, 0xcd, 0xfb, 0xe8, 0x4b, 0xbe, 0x86, 0x31, 0x58, 0x80, + 0x4a, 0x37, 0x1e, 0x13, 0xe8, 0x36, 0x90, 0x8a, 0x7f, 0x7f, 0xae, 0xbe, 0xe9, 0x2f, 0x88, 0x82, + 0x4b, 0x18, 0x53, 0x58, 0xd2, 0x08, 0x01, 0x20, 0x90, 0xfb, 0xa3, 0x63, 0xaf, 0x8e, 0x8c, 0x58, + 0xf5, 0x03, 0x9f, 0xa3, 0x17, 0x81, 0xb5, 0x29, 0xd5, 0x6b, 0xc4, 0xc6, 0x4c, 0x44, 0xe0, 0xb2, + 0xc8, 0x3e, 0xb3, 0xa2, 0x53, 0x0a, 0x2d, 0x88, 0xaf, 0x4c, 0x2d, 0xf8, 0xf8, 0x9c, 0xdf, 0xee, + 0x53, 0xb1, 0x11, 0x8f, 0x1d, 0x95, 0x99, 0x3d, 0xa9, 0x14, 0xe7, 0xe5, 0xa1, 0xa0, 0x3b, 0x93, + 0x8c, 0x86, 0x1b, 0xc8, 0x7f, 0xee, 0x87, 0x48, 0x80, 0x3c, 0x3b, 0xb1, 0xf9, 0xd0, 0x4e, 0x5c, + 0x6c, 0xd9, 0x9f, 0xd0, 0xec, 0xbc, 0x83, 0x69, 0x98, 0x3c, 0x69, 0x98, 0x37, 0xc2, 0x25, 0x40, + 0x6d, 0x5c, 0x74, 0x60, 0xd0, 0x15, 0x68, 0x68, 0x18, 0xf0, 0x48, 0xd5, 0xe5, 0xc1, 0x5a, 0x4b, + 0xcc, 0x40, 0x77, 0x65, 0xb6, 0xdb, 0x5c, 0x90, 0x6b, 0x02, 0xc5, 0xa6, 0x23, 0xb9, 0x8b, 0x02, + 0x6b, 0x94, 0x97, 0x20, 0x8e, 0x5e, 0x16, 0xa3, 0x74, 0x07, 0xb1, 0x96, 0x73, 0xb3, 0xf7, 0x57, + 0xf1, 0x15, 0xa7, 0x4d, 0x8c, 0xbf, 0xf0, 0x45, 0x3b, 0x36, 0xd0, 0xca, 0x9f, 0x53, 0xa7, 0xd4, + 0xe9, 0xf5, 0xef, 0xaf, 0x7d, 0x6a, 0xba, 0xf5, 0x75, 0x83, 0xeb, 0xaf, 0x82, 0x1b, 0xdf, 0x17, + 0xd5, 0x9f, 0x7b, 0x77, 0xf5, 0x2a, 0x7c, 0xd7, 0xdd, 0x77, 0x76, 0x0e, 0xfe, 0xbd, 0xf0, 0x4e, + 0x20, 0xc9, 0x17, 0xbd, 0xe2, 0xf8, 0x23, 0x2a, 0x34, 0x88, 0xa9, 0xb3, 0xcb, 0xeb, 0x17, 0xc1, + 0x21, 0x6b, 0x56, 0x7d, 0x47, 0x9b, 0xe4, 0x14, 0x38, 0x93, 0xbd, 0x96, 0xd7, 0x43, 0xd2, 0xfd, + 0x5d, 0xf0, 0xa4, 0x46, 0xd0, 0x24, 0x31, 0x28, 0x80, 0x8c, 0x4a, 0x58, 0xb2, 0xee, 0x60, 0x00, + 0x31, 0x0d, 0x2a, 0xd4, 0x92, 0x64, 0x65, 0xf4, 0x89, 0x75, 0x4e, 0x97, 0x04, 0x44, 0x7e, 0xcc, + 0xe8, 0x77, 0xe1, 0x42, 0x84, 0xcf, 0x5c, 0x9f, 0x8b, 0x53, 0x15, 0x1f, 0x7b, 0x14, 0x52, 0xcb, + 0x1f, 0x1c, 0x4c, 0x77, 0x17, 0xc4, 0x4b, 0xe8, 0xb9, 0x99, 0x23, 0x2c, 0x70, 0x7e, 0x10, 0x8a, + 0xdc, 0x56, 0x2b, 0x3a, 0x9e, 0x1e, 0x53, 0xde, 0x5f, 0xc1, 0x0d, 0x34, 0xc4, 0x59, 0xa3, 0x22, + 0xfc, 0x40, 0x29, 0xa2, 0x2a, 0x16, 0xd7, 0x92, 0x9a, 0x1a, 0x0a, 0xaf, 0x04, 0xaf, 0x3c, 0x68, + 0xd2, 0x6d, 0x8a, 0xe1, 0x22, 0xb5, 0xa6, 0xc1, 0x9c, 0x7a, 0xd7, 0x84, 0xa9, 0x21, 0x21, 0x14, + 0xe9, 0xc6, 0x5c, 0xa6, 0xa3, 0x37, 0x66, 0xbb, 0xd7, 0x04, 0x66, 0x55, 0x55, 0x77, 0xc2, 0x45, + 0x23, 0x0b, 0xb6, 0xce, 0x86, 0xba, 0xbd, 0xf5, 0x8b, 0xeb, 0x9c, 0xf9, 0x6f, 0xbf, 0x92, 0xf2, + 0x88, 0x0f, 0xc1, 0x0d, 0x22, 0x5a, 0x4e, 0xba, 0xf8, 0x22, 0x9a, 0x87, 0xa3, 0x2e, 0x39, 0x5d, + 0xdd, 0xff, 0x0d, 0x6e, 0xcd, 0x1e, 0x1d, 0x49, 0x9f, 0xe6, 0xda, 0xbf, 0x9c, 0x8b, 0xe4, 0xd2, + 0x6f, 0xe1, 0x22, 0xa0, 0xe5, 0x7c, 0xff, 0x3e, 0x78, 0x23, 0xa9, 0x58, 0x79, 0x69, 0x79, 0x2e, + 0xf9, 0x38, 0x2b, 0x9d, 0x86, 0x48, 0x98, 0xd2, 0x3d, 0x33, 0xb9, 0x23, 0x37, 0xea, 0xe4, 0x24, + 0xa3, 0x21, 0x33, 0x8c, 0xc7, 0xcb, 0x1b, 0xea, 0xf5, 0xc1, 0x50, 0x96, 0x59, 0xd2, 0xca, 0x6d, + 0x95, 0x22, 0xc2, 0x00, 0x7d, 0x7c, 0x17, 0x16, 0x5b, 0x60, 0x79, 0x4b, 0xbe, 0x9f, 0x89, 0x8c, + 0x25, 0x13, 0xa3, 0x36, 0xdf, 0x64, 0xc7, 0x06, 0x75, 0xda, 0xc2, 0x67, 0x66, 0x37, 0xb2, 0xbb, + 0x97, 0xb7, 0x6d, 0x72, 0xca, 0xa4, 0xe7, 0x90, 0x9c, 0xa7, 0xd1, 0x4e, 0x9f, 0x04, 0x24, 0x4c, + 0xfc, 0x75, 0x03, 0xf9, 0xd2, 0xfb, 0x38, 0x3b, 0xe1, 0xee, 0x03, 0xb6, 0x4f, 0x8b, 0x9d, 0xd6, + 0xe9, 0x24, 0x81, 0xa0, 0x7e, 0xe8, 0x8e, 0xb7, 0xe8, 0xc4, 0x4f, 0x94, 0xac, 0x4d, 0x3f, 0xc9, + 0x07, 0x5e, 0x03, 0xaf, 0x0d, 0x8e, 0xc5, 0xd0, 0xa3, 0x17, 0xcb, 0x7b, 0xfd, 0x7b, 0xee, 0x7a, + 0x75, 0xc8, 0x56, 0x20, 0xb3, 0x23, 0xc9, 0x3a, 0x27, 0x57, 0x28, 0x92, 0xb1, 0xfc, 0x27, 0x9d, + 0x89, 0xd8, 0x63, 0x57, 0x7f, 0x44, 0x95, 0xf5, 0xac, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x06, + 0x03, 0x30, 0x2e, 0x89, 0xd0, 0x44, 0xb7, 0xd0, 0x8c, 0x9d, 0x7b, 0xbb, 0xaa, 0xfa, 0xe5, 0x06, + 0x1d, 0x52, 0xa2, 0x75, 0xaa, 0xe8, 0xa4, 0x48, 0x9e, 0xb9, 0x32, 0x5d, 0x4a, 0x9f, 0x54, 0xcb, + 0xd4, 0xcb, 0x3e, 0xb9, 0x43, 0x9d, 0x53, 0xaf, 0x54, 0xe9, 0x75, 0xa7, 0x5e, 0xa9, 0x57, 0xac, + 0x50, 0xcf, 0x53, 0xa4, 0x33, 0xd7, 0xbe, 0xa5, 0x4f, 0xae, 0x15, 0xd7, 0x2a, 0xe8, 0x8f, 0xf4, + 0x57, 0x97, 0xa2, 0x15, 0x23, 0x61, 0x98, 0x70, 0x58, 0xa6, 0x46, 0x14, 0xe7, 0x9f, 0x3e, 0xb5, + 0x4c, 0x4f, 0x46, 0x32, 0x22, 0x2c, 0x44, 0x28, 0x10, 0xda, 0x2a, 0x1d, 0xa6, 0x85, 0x53, 0xa0, + 0xab, 0x97, 0x59, 0x5e, 0xe2, 0x3f, 0x0a, 0x10, 0x77, 0xcd, 0xc2, 0x77, 0x22, 0xc6, 0x14, 0x72, + 0xac, 0xf7, 0x2e, 0xdc, 0xf8, 0x46, 0x1e, 0xb9, 0x36, 0xa4, 0xd5, 0x76, 0x13, 0x67, 0x98, 0x84, + 0x39, 0x42, 0x67, 0xc6, 0x94, 0xd9, 0xea, 0xc8, 0x53, 0x9b, 0x15, 0x40, 0xea, 0xe1, 0xd6, 0x00, + 0x96, 0x1d, 0x21, 0x80, 0x01, 0x0f, 0xb3, 0xe7, 0xda, 0xb4, 0x77, 0x76, 0x67, 0x57, 0x5f, 0x72, + 0x50, 0x3a, 0x62, 0xe1, 0xcd, 0xdb, 0x97, 0x60, 0xe4, 0xb8, 0x60, 0x01, 0xa3, 0xc4, 0x00, 0x11, + 0x16, 0x0c, 0x10, 0x29, 0x65, 0x04, 0x0a, 0x5b, 0x70, 0x78, 0x3d, 0x07, 0x83, 0xdc, 0x18, 0x01, + 0x44, 0x6d, 0x55, 0x55, 0x55, 0x54, 0xd9, 0x22, 0x7d, 0x31, 0xf5, 0xf9, 0x9d, 0xa0, 0x98, 0x5e, + 0x12, 0x9d, 0xf2, 0x59, 0x30, 0x66, 0xd7, 0x04, 0xb4, 0xf1, 0x8f, 0x4d, 0x7e, 0x02, 0xc0, 0x14, + 0x87, 0x86, 0x8b, 0x93, 0x04, 0xe8, 0xea, 0x13, 0x09, 0x9b, 0x8a, 0x69, 0x88, 0xfc, 0x5a, 0x82, + 0xfe, 0x12, 0xfd, 0xe0, 0xd1, 0xa3, 0x7b, 0xdb, 0xe7, 0x68, 0x84, 0x5b, 0x6a, 0x1f, 0xed, 0x73, + 0x80, 0x80, 0x89, 0x88, 0xf9, 0xdf, 0xf0, 0xa2, 0xb0, 0xe2, 0x80, 0x28, 0x3f, 0xf0, 0xdf, 0x85, + 0xd2, 0xee, 0x5d, 0x6e, 0x68, 0x79, 0x75, 0x2f, 0xb8, 0x0a, 0x90, 0x49, 0x40, 0x9f, 0x9b, 0x37, + 0x5a, 0x7c, 0xfc, 0x12, 0x0a, 0x69, 0xd6, 0x4c, 0x31, 0x10, 0x50, 0x23, 0x2c, 0x87, 0x90, 0x91, + 0x8a, 0x6c, 0xe7, 0x60, 0xc3, 0xc2, 0x86, 0xb4, 0xaa, 0xaa, 0xa2, 0x98, 0xba, 0x97, 0x93, 0x05, + 0xd7, 0x4b, 0xbe, 0x09, 0x6b, 0xa7, 0x5d, 0x3e, 0xe2, 0x63, 0x22, 0xbf, 0x3e, 0x4d, 0x4e, 0x38, + 0xe0, 0x36, 0x1f, 0x81, 0xfa, 0x7e, 0x3a, 0x55, 0x96, 0xb4, 0x58, 0x8f, 0x30, 0xe3, 0xc0, 0xbf, + 0x50, 0xbf, 0x17, 0xd0, 0x57, 0x99, 0x1b, 0xaf, 0x83, 0x3a, 0xc2, 0x3c, 0x2e, 0x20, 0x1d, 0x2e, + 0x0e, 0xb1, 0x80, 0x11, 0x41, 0x4c, 0x68, 0x07, 0x81, 0x14, 0x8f, 0x7c, 0xfd, 0xbc, 0x18, 0x2e, + 0x03, 0xa8, 0x89, 0x30, 0x57, 0x41, 0xc5, 0x71, 0x5e, 0x04, 0x80, 0x2c, 0x8d, 0x11, 0xd6, 0x70, + 0x70, 0x99, 0xc1, 0x58, 0xc6, 0x10, 0xa9, 0x0a, 0x58, 0x98, 0x3e, 0x2e, 0x07, 0x81, 0xc3, 0x4e, + 0xac, 0x79, 0x88, 0xb6, 0x72, 0xcc, 0x99, 0xaf, 0xa8, 0xa0, 0x03, 0x92, 0x4e, 0x00, 0x01, 0x00, + 0x59, 0xe2, 0x15, 0xcc, 0x66, 0x74, 0x44, 0x3c, 0x3c, 0x8c, 0xda, 0xeb, 0x7f, 0xff, 0x84, 0x01, + 0x00, 0x52, 0x78, 0xce, 0x07, 0xa5, 0x76, 0x43, 0x06, 0x72, 0x24, 0x3d, 0x42, 0x63, 0x81, 0x29, + 0xec, 0xff, 0x64, 0xc3, 0x0a, 0x8d, 0x5b, 0x84, 0x21, 0x38, 0x0e, 0x42, 0x8a, 0x8b, 0x87, 0x2e, + 0x48, 0x31, 0xe9, 0xe7, 0xb9, 0x04, 0x12, 0x1c, 0x10, 0x24, 0x26, 0x1c, 0x09, 0x21, 0x10, 0xa4, + 0x28, 0x00, 0x54, 0x09, 0x88, 0x33, 0xc0, 0x00, 0xbb, 0x78, 0x56, 0xc5, 0x61, 0x38, 0x50, 0x20, + 0x66, 0x81, 0x00, 0x20, 0x87, 0x1b, 0xc2, 0xb8, 0x17, 0x3c, 0x03, 0xdb, 0x83, 0xfc, 0x80, 0xf0, + 0x08, 0x19, 0x80, 0xc0, 0x55, 0x47, 0x85, 0x10, 0x71, 0x2f, 0x15, 0x98, 0x90, 0x62, 0x36, 0xb2, + 0x1a, 0x86, 0x83, 0x10, 0xb5, 0x55, 0xac, 0x08, 0xd2, 0xc1, 0x4c, 0x0b, 0x13, 0xa2, 0x98, 0x2d, + 0x2c, 0x11, 0x56, 0xc7, 0xd6, 0x6d, 0x7a, 0xaa, 0x21, 0x30, 0x1f, 0x15, 0xb6, 0x86, 0x15, 0x86, + 0x29, 0xa6, 0x7d, 0x7f, 0xc1, 0x40, 0x31, 0x05, 0x62, 0x55, 0x54, 0x5e, 0x47, 0x10, 0x70, 0xc2, + 0x27, 0xa5, 0xdb, 0x17, 0xae, 0x0c, 0xa7, 0x8f, 0xe2, 0x22, 0x45, 0xf3, 0x30, 0x2e, 0x5e, 0x30, + 0x84, 0x77, 0x0b, 0xcc, 0x4b, 0x9a, 0x03, 0x39, 0xad, 0xf8, 0xc0, 0x96, 0x6c, 0xa0, 0x9c, 0xb8, + 0x5b, 0xa5, 0x8d, 0xc5, 0x6e, 0x2b, 0x7f, 0x08, 0x4b, 0xcb, 0xc5, 0x30, 0xb6, 0xa0, 0xa5, 0x58, + 0xc6, 0x66, 0x0d, 0x0f, 0xf0, 0x4a, 0x34, 0x8e, 0x0b, 0xdc, 0x53, 0x79, 0x8d, 0x69, 0x6c, 0x96, + 0x5b, 0x0e, 0x8e, 0x87, 0xe2, 0x66, 0x19, 0x14, 0xc4, 0x9c, 0x50, 0xbe, 0x26, 0x48, 0x13, 0x1c, + 0x82, 0xfd, 0x19, 0xfc, 0xa8, 0xbe, 0x82, 0x35, 0xf5, 0x8a, 0xb8, 0x99, 0xe8, 0x7a, 0x67, 0xa1, + 0xe9, 0xf8, 0x47, 0x3d, 0x33, 0xd0, 0xf4, 0xe7, 0xa6, 0xf9, 0xcb, 0x14, 0x86, 0x48, 0x64, 0xfa, + 0xbe, 0x5f, 0x9f, 0xac, 0x55, 0xcf, 0x47, 0xbe, 0xaa, 0xbf, 0x52, 0x28, 0x7a, 0xb4, 0x54, 0x09, + 0x20, 0xa0, 0x41, 0x8e, 0x68, 0x73, 0x45, 0x95, 0xa8, 0x7f, 0x0b, 0xe0, 0x1a, 0x01, 0x55, 0xf7, + 0xbe, 0x60, 0xc2, 0x1e, 0x19, 0x7c, 0x00, 0x08, 0xc0, 0x51, 0x1a, 0x00, 0x3d, 0xce, 0x5a, 0x6f, + 0x50, 0x18, 0xfd, 0x74, 0x01, 0x19, 0x8b, 0xf7, 0x47, 0x5b, 0x0d, 0xf2, 0x76, 0x6a, 0x3c, 0xc4, + 0x65, 0xe0, 0x15, 0xb8, 0x5c, 0xf3, 0xe2, 0x7f, 0xb9, 0xa9, 0x5c, 0x14, 0x04, 0x06, 0xd6, 0x80, + 0x60, 0x42, 0x92, 0x00, 0x04, 0x2d, 0xce, 0xc1, 0xf5, 0x50, 0x46, 0x9c, 0x2e, 0x01, 0x5f, 0x95, + 0x00, 0x3d, 0x50, 0x10, 0xd6, 0x3c, 0x16, 0xe8, 0xe8, 0xa9, 0x00, 0x00, 0x80, 0x2f, 0x27, 0x0e, + 0x34, 0x2c, 0x26, 0xb6, 0xc3, 0x49, 0x30, 0x35, 0xb1, 0x55, 0x4d, 0x39, 0x34, 0xc7, 0xb5, 0x57, + 0xc9, 0x62, 0x95, 0x47, 0x5f, 0x4e, 0x7d, 0x2f, 0xc3, 0x30, 0xa4, 0xb1, 0xf1, 0x10, 0xa4, 0x29, + 0x2c, 0x85, 0xd0, 0x1a, 0xb9, 0x96, 0xf1, 0xd1, 0x7a, 0xb5, 0x87, 0x40, 0x00, 0xe5, 0x1e, 0x99, + 0xb3, 0x21, 0x00, 0x02, 0xaa, 0x9c, 0x80, 0x26, 0x31, 0x3e, 0x39, 0x54, 0x34, 0x82, 0x59, 0xdd, + 0x1a, 0xac, 0x44, 0x29, 0x34, 0x52, 0xd5, 0x20, 0x49, 0xd5, 0x62, 0xc5, 0xe4, 0x28, 0x97, 0x24, + 0xb2, 0x59, 0x81, 0xd2, 0xe0, 0xea, 0xc6, 0x90, 0x8e, 0x82, 0xe4, 0xce, 0x0a, 0x79, 0x41, 0xc4, + 0x81, 0x28, 0xd5, 0x03, 0xe8, 0xfc, 0x30, 0x0a, 0x42, 0x87, 0x99, 0x5c, 0x64, 0x5e, 0x2e, 0x2e, + 0x29, 0x8b, 0xa4, 0x90, 0x45, 0x99, 0x70, 0xf0, 0xec, 0x85, 0xd6, 0x54, 0xab, 0xf9, 0x46, 0x97, + 0xf9, 0x38, 0xa1, 0xd9, 0x83, 0x2d, 0x44, 0x79, 0x6c, 0x28, 0xa9, 0x63, 0xf1, 0xc6, 0x77, 0x3d, + 0xe5, 0xb3, 0xe7, 0xcb, 0x6e, 0x19, 0x15, 0x85, 0xb5, 0xcc, 0x27, 0x89, 0xff, 0x1c, 0x22, 0x11, + 0xa5, 0xfc, 0x0b, 0xd5, 0xc5, 0x6c, 0x6a, 0xff, 0xe4, 0xdc, 0x41, 0xa8, 0xc7, 0xc4, 0x82, 0x30, + 0xba, 0x49, 0x37, 0x1a, 0xa7, 0x88, 0x53, 0xaf, 0xea, 0x74, 0x54, 0x18, 0xeb, 0xdf, 0x04, 0x26, + 0xbc, 0xf4, 0xc2, 0x4e, 0x8c, 0xc3, 0xd7, 0xa7, 0xc4, 0x21, 0x3d, 0xc0, 0xc2, 0x08, 0x16, 0x95, + 0x60, 0x40, 0x08, 0x05, 0x06, 0x7c, 0xdd, 0x18, 0x27, 0xca, 0xa0, 0x8c, 0x4e, 0x45, 0xe0, 0xd5, + 0x68, 0xa1, 0x9e, 0xbd, 0x79, 0x27, 0xfe, 0x70, 0x84, 0x61, 0x0f, 0x01, 0x96, 0xdd, 0x00, 0x24, + 0x83, 0xc7, 0x90, 0x86, 0x30, 0x1b, 0x07, 0x73, 0x86, 0x40, 0x0a, 0x36, 0xf8, 0x77, 0xf0, 0xf8, + 0xd9, 0x1e, 0xe2, 0x94, 0x4b, 0x0f, 0x8f, 0x18, 0x55, 0x49, 0x2f, 0x12, 0x10, 0x0a, 0x14, 0xd4, + 0xa4, 0x24, 0x6a, 0xd3, 0xe9, 0x84, 0x31, 0x83, 0x3c, 0xdf, 0xe3, 0xe0, 0xe1, 0xee, 0xdd, 0x07, + 0x03, 0x07, 0xfe, 0xce, 0x01, 0x83, 0xb0, 0x1c, 0x84, 0x00, 0x0b, 0x05, 0x83, 0x72, 0x02, 0xaf, + 0xbc, 0x35, 0xd0, 0x0f, 0x12, 0x96, 0x1f, 0x11, 0x7c, 0x40, 0x40, 0x61, 0x89, 0xcf, 0x21, 0x00, + 0x31, 0x1d, 0x4a, 0x19, 0x0b, 0x92, 0xec, 0x7b, 0x42, 0x52, 0x4f, 0x3d, 0x10, 0x46, 0x54, 0x52, + 0x09, 0xce, 0x01, 0x53, 0x3a, 0x70, 0xa0, 0x69, 0x9c, 0x21, 0x49, 0xb0, 0x69, 0x75, 0x00, 0x61, + 0x58, 0x28, 0x82, 0x60, 0xa8, 0xb8, 0xb8, 0x9f, 0x91, 0xdf, 0xf1, 0x82, 0x4c, 0xd1, 0x97, 0x9e, + 0x04, 0x3f, 0x10, 0x5f, 0x1d, 0xfa, 0xe0, 0x9a, 0x7a, 0x1e, 0x9c, 0xf4, 0xf0, 0xf8, 0x50, 0x29, + 0x4d, 0x53, 0x2d, 0xb8, 0xad, 0xd5, 0xd3, 0x15, 0xbc, 0xfc, 0xd1, 0x3d, 0xe2, 0x01, 0x08, 0x98, + 0xd5, 0x75, 0xf3, 0x11, 0x93, 0x0a, 0x02, 0xdd, 0x89, 0x9d, 0x5e, 0x0a, 0x4d, 0xc4, 0xc8, 0x24, + 0x81, 0xe6, 0x05, 0xf8, 0x5c, 0xa8, 0x5f, 0x2c, 0x1c, 0x57, 0xda, 0x2f, 0x8b, 0x0c, 0xb4, 0xd6, + 0xd3, 0x5a, 0xe1, 0x1b, 0x4d, 0x6d, 0x35, 0xb4, 0xd7, 0xe3, 0x2d, 0x35, 0xb4, 0xd6, 0xd3, 0x5b, + 0x4d, 0x7e, 0x27, 0xa4, 0x96, 0x92, 0x5e, 0x3a, 0xd6, 0xdb, 0x4d, 0x6d, 0x35, 0x9b, 0x84, 0xc9, + 0xcf, 0x49, 0xe9, 0xbe, 0xa5, 0x59, 0x7d, 0x19, 0xfe, 0x62, 0xec, 0xcf, 0x41, 0x1c, 0x13, 0x4b, + 0x42, 0xd3, 0x3d, 0x0f, 0x4d, 0xca, 0xe3, 0xf9, 0xe8, 0x7a, 0x67, 0xa1, 0xe8, 0x5a, 0x36, 0x99, + 0x61, 0x88, 0xd1, 0x55, 0x09, 0x84, 0x70, 0xee, 0x00, 0x54, 0x17, 0x9a, 0x20, 0x52, 0xe7, 0x22, + 0x1d, 0x6f, 0x38, 0x30, 0xe0, 0xb8, 0xba, 0xaf, 0x3d, 0x55, 0x7c, 0x63, 0x3f, 0xfe, 0x14, 0x21, + 0x6c, 0x51, 0xc2, 0x04, 0x98, 0x03, 0xb7, 0x0b, 0xf3, 0x1a, 0x82, 0x29, 0xa1, 0xa4, 0x50, 0x2f, + 0x12, 0x80, 0x7a, 0x6f, 0x92, 0x84, 0x04, 0x0f, 0x38, 0x62, 0xcd, 0x90, 0x7f, 0xb7, 0x72, 0x75, + 0x9d, 0xd0, 0xad, 0x86, 0x59, 0x81, 0x32, 0xa2, 0x84, 0xfb, 0x11, 0x3a, 0xc2, 0x22, 0x02, 0x92, + 0x04, 0x28, 0xa7, 0x83, 0x41, 0x50, 0x8f, 0x47, 0x2c, 0x38, 0x05, 0xa2, 0xb0, 0x21, 0x1a, 0x7e, + 0x3b, 0xa4, 0x4f, 0x2c, 0x79, 0x3e, 0xd1, 0xf0, 0x00, 0x23, 0xc9, 0x00, 0x1a, 0x8b, 0x59, 0x60, + 0x65, 0xac, 0x48, 0x07, 0xe7, 0x78, 0x90, 0x57, 0x35, 0x27, 0x80, 0x01, 0x46, 0xc0, 0x1b, 0x34, + 0xe7, 0x2c, 0xb4, 0x01, 0x5a, 0x12, 0xa6, 0x90, 0x0b, 0x58, 0x16, 0x61, 0x50, 0x5b, 0x4a, 0x57, + 0x00, 0x20, 0xf8, 0x81, 0x24, 0xa0, 0xff, 0x14, 0x30, 0x4a, 0x00, 0xd2, 0x32, 0x7f, 0x48, 0x8b, + 0xd6, 0x23, 0x5c, 0x16, 0x15, 0xa5, 0x33, 0x0b, 0x2a, 0xad, 0x66, 0xd5, 0xe2, 0xf8, 0xe3, 0x38, + 0xac, 0xb6, 0x76, 0x2e, 0xf8, 0xae, 0xca, 0xc7, 0xe2, 0x8b, 0x69, 0x6d, 0x46, 0xf3, 0x2c, 0x3f, + 0x1c, 0x68, 0xb8, 0xf1, 0x90, 0x77, 0x16, 0x80, 0xaa, 0x2d, 0x60, 0xfd, 0x5d, 0x83, 0x3e, 0x43, + 0x5e, 0x12, 0x77, 0x1c, 0x2e, 0x20, 0x49, 0x02, 0xf4, 0xda, 0x9f, 0xad, 0x57, 0x42, 0x20, 0xfa, + 0xca, 0x6e, 0x84, 0xa3, 0x86, 0x23, 0x82, 0x33, 0x1e, 0x87, 0xa7, 0x83, 0x8f, 0xa3, 0xa4, 0xbe, + 0xad, 0x7d, 0x53, 0x32, 0x72, 0x55, 0xdd, 0x7d, 0x19, 0x92, 0xf4, 0x24, 0xc9, 0x5d, 0x4c, 0x95, + 0x86, 0x46, 0x8e, 0x13, 0xe7, 0x68, 0x23, 0x87, 0x73, 0x48, 0x9a, 0x28, 0x71, 0xbe, 0x79, 0x24, + 0x50, 0x54, 0xbc, 0x5c, 0x9a, 0x4c, 0x2a, 0x05, 0x65, 0x03, 0xe8, 0x1f, 0x92, 0x83, 0xcb, 0x88, + 0x56, 0xcb, 0xac, 0x6e, 0x9f, 0x88, 0x12, 0x34, 0xce, 0x5c, 0x01, 0x49, 0xb1, 0x00, 0x28, 0x78, + 0xdd, 0xea, 0x63, 0xa1, 0xbf, 0x0e, 0x0a, 0x42, 0x0c, 0xec, 0x88, 0x8c, 0x22, 0x8d, 0xa1, 0xc9, + 0x40, 0x3c, 0x18, 0x27, 0x9a, 0xd1, 0x4b, 0x07, 0x55, 0x30, 0x66, 0x70, 0xec, 0xbe, 0xbf, 0x39, + 0xd8, 0x05, 0x65, 0x99, 0x2f, 0x00, 0x03, 0xaa, 0x32, 0x02, 0x0b, 0x86, 0x10, 0x3d, 0x03, 0xad, + 0xf0, 0x28, 0x09, 0xad, 0xe3, 0x06, 0xe5, 0xfe, 0x10, 0x0a, 0x5e, 0x00, 0x0f, 0x38, 0x02, 0xc1, + 0x30, 0x01, 0x40, 0x78, 0x01, 0x82, 0xe8, 0x84, 0xe0, 0xba, 0xa8, 0xf6, 0x48, 0x13, 0x16, 0x1f, + 0x0a, 0x82, 0x25, 0x00, 0x96, 0x6c, 0x00, 0x04, 0x01, 0x14, 0x78, 0x85, 0x77, 0x22, 0x80, 0x0b, + 0x88, 0xa3, 0xc5, 0x81, 0x06, 0xe3, 0x68, 0x48, 0x1f, 0x50, 0x82, 0x11, 0xb3, 0xa8, 0x00, 0x87, + 0xa7, 0x0e, 0xcd, 0xc4, 0x89, 0x1b, 0xe0, 0xb0, 0x38, 0xcb, 0x4e, 0x1b, 0x02, 0x07, 0xfa, 0x90, + 0xc0, 0x00, 0xf0, 0x5e, 0x0e, 0x71, 0xaa, 0x34, 0x81, 0x62, 0x12, 0x68, 0x38, 0xa0, 0x9c, 0x7f, + 0x04, 0xee, 0xba, 0x01, 0x51, 0x78, 0x00, 0xf9, 0x66, 0x40, 0x79, 0x93, 0x90, 0x02, 0x60, 0x90, + 0x0e, 0x5d, 0xcf, 0xa7, 0xda, 0x49, 0x93, 0x71, 0x30, 0xa7, 0xc7, 0x95, 0x69, 0x82, 0x35, 0x99, + 0x87, 0x63, 0x50, 0xbb, 0xe9, 0x1d, 0xe4, 0x28, 0xa9, 0xc4, 0x79, 0xa1, 0x2a, 0xa5, 0xd4, 0x73, + 0xe3, 0x2d, 0xa9, 0x3f, 0x22, 0xfd, 0x59, 0x19, 0xca, 0x82, 0x5a, 0x41, 0xc1, 0xc1, 0xe5, 0xcb, + 0xff, 0xc5, 0xdf, 0x46, 0xaa, 0x6c, 0x27, 0x0a, 0xf8, 0xe2, 0x2a, 0xa8, 0x58, 0xe8, 0x0e, 0xf1, + 0x79, 0x91, 0xf5, 0x0b, 0x9c, 0x1d, 0x60, 0x3e, 0x4b, 0xac, 0x22, 0x20, 0x36, 0x4b, 0x21, 0x26, + 0xf2, 0x12, 0x07, 0xd7, 0xf1, 0x21, 0xaa, 0x49, 0x7d, 0x6d, 0xb4, 0xd3, 0xf2, 0xf4, 0x33, 0x5f, + 0x5e, 0xae, 0x8e, 0xe8, 0xbe, 0x20, 0x4e, 0x92, 0x5a, 0x49, 0x13, 0xab, 0x17, 0xd1, 0x9c, 0x89, + 0xe8, 0x93, 0x3e, 0x8e, 0x44, 0xbe, 0xa4, 0x49, 0x22, 0x60, 0xa8, 0xdc, 0xf4, 0x4f, 0xb8, 0xc5, + 0xaa, 0xa8, 0x1b, 0xbf, 0xd1, 0x1b, 0xbf, 0x41, 0xc6, 0xe1, 0x00, 0x52, 0x14, 0x14, 0x4f, 0xc6, + 0x21, 0x81, 0xc3, 0x02, 0x1d, 0x28, 0x74, 0xe5, 0x26, 0x00, 0xe2, 0x26, 0xd4, 0xe4, 0xc4, 0xe7, + 0x09, 0x3e, 0x66, 0x1c, 0x0e, 0x1c, 0x0e, 0x67, 0xe2, 0x01, 0x88, 0x53, 0xab, 0x1a, 0xd1, 0xb8, + 0x58, 0xcf, 0xf3, 0x21, 0x0b, 0xe6, 0x2e, 0x89, 0x61, 0x23, 0x95, 0x19, 0x28, 0x2b, 0x13, 0x08, + 0x98, 0xd4, 0x91, 0x6c, 0x7c, 0x6a, 0xb1, 0x21, 0x10, 0xa5, 0xf0, 0x05, 0x86, 0x13, 0xe3, 0xc5, + 0x83, 0x87, 0x0d, 0x01, 0x2a, 0x2f, 0x00, 0x1a, 0x5c, 0x23, 0xb5, 0x2c, 0x19, 0x60, 0x03, 0x0b, + 0x00, 0x34, 0x2c, 0x00, 0x69, 0x45, 0x15, 0xbf, 0xc1, 0x4d, 0xc4, 0xd8, 0xf9, 0x83, 0x74, 0xfd, + 0x05, 0xe0, 0x16, 0x93, 0x80, 0x39, 0x33, 0x0e, 0x0e, 0x16, 0x33, 0x0f, 0x40, 0x5d, 0x32, 0xdf, + 0x3f, 0xc4, 0x08, 0x0a, 0x14, 0x3e, 0x12, 0x8d, 0xd7, 0x1c, 0x1f, 0x1b, 0x0b, 0x51, 0xcf, 0x85, + 0xb2, 0xc5, 0x0c, 0x60, 0x72, 0x7f, 0x10, 0x30, 0x56, 0xa5, 0x74, 0xa3, 0x9f, 0x5f, 0xfe, 0x32, + 0x7e, 0xcb, 0xa3, 0xdb, 0x24, 0x6c, 0x12, 0x02, 0x16, 0x22, 0xb6, 0xc1, 0x65, 0x77, 0x48, 0xe7, + 0x96, 0xb8, 0xfe, 0x3c, 0x62, 0x8b, 0xc5, 0xc6, 0x2c, 0xa8, 0xac, 0x4b, 0x02, 0x42, 0xbb, 0x64, + 0xce, 0x4c, 0x4c, 0x9d, 0x05, 0xc8, 0x2f, 0xae, 0x53, 0xf5, 0xef, 0xab, 0xc2, 0xbc, 0xf1, 0xd5, + 0x77, 0x7f, 0xfa, 0xc5, 0x27, 0x44, 0x2a, 0x7d, 0x4e, 0x95, 0xc2, 0x47, 0xda, 0x6b, 0x69, 0xac, + 0x20, 0x08, 0x45, 0x04, 0xad, 0x9a, 0x0d, 0x65, 0x29, 0x35, 0x0e, 0xd5, 0x0a, 0x10, 0x0d, 0x47, + 0x49, 0x92, 0x90, 0x01, 0xd3, 0x12, 0x08, 0x02, 0x91, 0xeb, 0x4b, 0x06, 0x70, 0x00, 0xf3, 0x80, + 0x18, 0x1c, 0x00, 0xe1, 0x9c, 0x37, 0x24, 0x3a, 0x0f, 0x1c, 0x80, 0x99, 0x13, 0x80, 0x0e, 0x81, + 0x47, 0x7e, 0x0a, 0xa0, 0x6a, 0x4e, 0xdb, 0x02, 0xc9, 0x90, 0x48, 0xc8, 0x58, 0x12, 0x4b, 0x0b, + 0x58, 0x00, 0x08, 0x01, 0x10, 0x75, 0x46, 0xc0, 0x00, 0x40, 0x20, 0x07, 0x7a, 0xd4, 0x71, 0xc3, + 0xa8, 0xa0, 0x08, 0x26, 0x50, 0x6b, 0x08, 0x53, 0x34, 0x8d, 0x46, 0x29, 0xca, 0xf9, 0x4b, 0x2b, + 0x8f, 0x5c, 0xbb, 0xcb, 0xc5, 0xc4, 0xf8, 0xea, 0xe5, 0x0f, 0xc8, 0x91, 0xa1, 0xc0, 0x00, 0x8f, + 0x81, 0x10, 0x8f, 0xd5, 0xbe, 0x36, 0x55, 0xf0, 0x36, 0x46, 0x26, 0x9f, 0xf8, 0x81, 0x21, 0x49, + 0x30, 0x00, 0x15, 0x32, 0x2a, 0x26, 0x80, 0xaa, 0x00, 0x6a, 0x78, 0x3d, 0xd7, 0x43, 0xdb, 0x3c, + 0x00, 0x1e, 0x51, 0x19, 0x82, 0x40, 0x00, 0x68, 0x4e, 0xd2, 0x83, 0x7c, 0x66, 0x84, 0x43, 0xbc, + 0x48, 0x80, 0xa4, 0x3e, 0x25, 0x24, 0xa9, 0xde, 0xce, 0xcc, 0x4a, 0x77, 0x76, 0xf1, 0x12, 0x2e, + 0x58, 0x0f, 0x2e, 0x20, 0x40, 0xc8, 0x81, 0xe7, 0x8f, 0x36, 0xbf, 0x0b, 0x6e, 0x5b, 0x8e, 0x19, + 0x8a, 0x33, 0x2c, 0x00, 0x09, 0xcf, 0x00, 0x02, 0x30, 0xa8, 0xca, 0x03, 0xf6, 0xa5, 0x9f, 0x10, + 0x14, 0x2d, 0xdd, 0x0e, 0x5c, 0x8e, 0xb1, 0xb7, 0x1d, 0x6b, 0x8a, 0xce, 0x71, 0xa7, 0xe2, 0x5f, + 0xb1, 0x8b, 0xd4, 0x98, 0x94, 0x13, 0x1d, 0xaf, 0xac, 0x12, 0xf4, 0x71, 0xd5, 0xf4, 0x66, 0xbe, + 0xb5, 0x2f, 0x27, 0x2d, 0x18, 0xc4, 0x75, 0x6a, 0x88, 0xc4, 0x75, 0x2a, 0xcf, 0x92, 0xe2, 0xb1, + 0x58, 0xaf, 0xd1, 0x32, 0xbe, 0x8a, 0x9d, 0x71, 0x20, 0x86, 0x8c, 0x94, 0x47, 0x0c, 0xf5, 0x60, + 0x48, 0x0a, 0x0e, 0x77, 0xb8, 0x38, 0xeb, 0x52, 0xd8, 0x00, 0x1b, 0x5a, 0x04, 0x1b, 0x62, 0x49, + 0x55, 0x0c, 0x6e, 0x58, 0x3e, 0xb8, 0x4b, 0x02, 0xeb, 0x94, 0x15, 0x42, 0xa4, 0x96, 0xe3, 0x12, + 0x24, 0x28, 0x47, 0xc0, 0x00, 0xbf, 0x16, 0x26, 0x11, 0x02, 0xa4, 0x2a, 0x80, 0x6a, 0x14, 0x1f, + 0x80, 0x02, 0x01, 0xc1, 0x39, 0x09, 0xb0, 0x00, 0x08, 0x0c, 0x87, 0x94, 0x00, 0x07, 0x80, 0x00, + 0x80, 0x78, 0xe5, 0x80, 0x8a, 0x06, 0xe4, 0xaa, 0x60, 0x00, 0x20, 0x03, 0xf2, 0x30, 0x15, 0x28, + 0x00, 0x01, 0x80, 0x0e, 0x6c, 0xf3, 0xc9, 0x4a, 0x1c, 0x05, 0x49, 0x83, 0xed, 0xa4, 0xc6, 0x01, + 0x76, 0x04, 0x94, 0x02, 0xd6, 0x8e, 0x13, 0x95, 0x7d, 0xf0, 0xde, 0x3e, 0x63, 0x16, 0x55, 0xa6, + 0x99, 0xd0, 0x70, 0xc6, 0x88, 0x62, 0x44, 0x05, 0x29, 0xc0, 0x68, 0x00, 0x08, 0x01, 0xd2, 0x16, + 0xc8, 0x0c, 0x01, 0x55, 0xd8, 0x00, 0x08, 0x00, 0xca, 0x55, 0xc0, 0x00, 0x40, 0x0f, 0x8d, 0x40, + 0x85, 0x48, 0xf0, 0x00, 0x3f, 0x1e, 0x36, 0x06, 0xb0, 0xc5, 0x00, 0x01, 0x00, 0x34, 0x87, 0xa1, + 0xc5, 0x96, 0x37, 0x13, 0x40, 0xe4, 0x0f, 0x01, 0xbe, 0x03, 0x8b, 0x90, 0x07, 0xb8, 0x5a, 0x80, + 0x78, 0x0a, 0xc0, 0x78, 0x3b, 0x01, 0xb8, 0x3f, 0x9c, 0x40, 0x64, 0x27, 0x2c, 0x1e, 0xad, 0x06, + 0xf7, 0xe1, 0x11, 0x01, 0x4b, 0xa8, 0xae, 0x2b, 0x7c, 0x42, 0xc3, 0x89, 0x05, 0x41, 0x6c, 0xe3, + 0x04, 0x0a, 0xbd, 0x9d, 0x01, 0x51, 0x40, 0x45, 0xaf, 0xcc, 0x66, 0xc3, 0x78, 0x2a, 0xdd, 0x4a, + 0x8f, 0xc4, 0x46, 0x14, 0x48, 0x38, 0x58, 0x37, 0x15, 0x96, 0xc5, 0x6e, 0x2b, 0x03, 0x40, 0x64, + 0x25, 0x14, 0x60, 0x20, 0x14, 0x56, 0x43, 0x58, 0x74, 0xc5, 0xe6, 0x35, 0x3e, 0xd5, 0x65, 0xe3, + 0x0a, 0x93, 0x95, 0xa5, 0x07, 0x9b, 0x0a, 0x89, 0xca, 0x27, 0x44, 0xe6, 0x01, 0xfd, 0xb3, 0xe6, + 0x5f, 0x9d, 0xfc, 0x7d, 0xdb, 0x4e, 0xee, 0x75, 0x2d, 0xf7, 0xb8, 0xde, 0x86, 0xa5, 0x47, 0xeb, + 0x55, 0xd4, 0xc6, 0xfa, 0xa5, 0x43, 0x78, 0x23, 0x23, 0xde, 0xc7, 0xd5, 0x8f, 0xac, 0x8e, 0x93, + 0x74, 0x5a, 0xac, 0x4f, 0x12, 0x20, 0x50, 0xe6, 0x69, 0xe3, 0x91, 0xd3, 0x83, 0xdb, 0xbf, 0x10, + 0x14, 0x31, 0xc0, 0x0f, 0x7c, 0x07, 0x9c, 0x3c, 0x9d, 0x59, 0x23, 0x9b, 0xd0, 0x4e, 0x03, 0x49, + 0x44, 0x98, 0xfa, 0xfd, 0x70, 0xb1, 0x9e, 0x3c, 0x51, 0x93, 0xb5, 0x1b, 0x36, 0x6d, 0x05, 0x36, + 0xd4, 0x45, 0x4c, 0xe9, 0xa1, 0x68, 0x3d, 0xf3, 0x7c, 0xf1, 0x03, 0x62, 0xd8, 0x46, 0x6b, 0x98, + 0x4b, 0x5e, 0x5b, 0x79, 0x67, 0xd9, 0xae, 0xf5, 0x47, 0x80, 0x32, 0xc1, 0xbc, 0x00, 0xf2, 0xa9, + 0xd2, 0x68, 0x11, 0xed, 0x83, 0xa8, 0x93, 0x9d, 0x89, 0x69, 0x02, 0x14, 0x6f, 0xa8, 0x95, 0xc1, + 0xaa, 0xc4, 0x0f, 0xdd, 0xf4, 0x3f, 0x7c, 0xd3, 0x35, 0x5f, 0xe2, 0x42, 0x95, 0xcd, 0xdf, 0x77, + 0x77, 0x71, 0x5d, 0xfb, 0xe3, 0x3b, 0x4f, 0x09, 0xb8, 0x90, 0xce, 0x3b, 0xc8, 0x3f, 0x4a, 0x7e, + 0x01, 0x84, 0xbf, 0x43, 0x6d, 0x55, 0xba, 0x7f, 0x49, 0x7d, 0xf3, 0xc2, 0x8d, 0x03, 0x5c, 0x60, + 0x58, 0x18, 0x9f, 0xec, 0x0f, 0x5c, 0x4e, 0xc1, 0x06, 0x78, 0x43, 0x4c, 0x29, 0x2f, 0x35, 0x68, + 0xb7, 0x37, 0x41, 0x5a, 0xf2, 0x04, 0x2f, 0x75, 0x9c, 0x9b, 0xc4, 0xf3, 0xc4, 0x89, 0x3d, 0x84, + 0xed, 0xd6, 0x19, 0xd6, 0xb9, 0x04, 0x08, 0x58, 0x9f, 0x05, 0x7e, 0x52, 0x86, 0x98, 0x4b, 0x4a, + 0x35, 0x43, 0xda, 0x3e, 0x82, 0x69, 0xda, 0xea, 0x74, 0xbe, 0xae, 0x02, 0x1c, 0xa6, 0x3b, 0x08, + 0x67, 0x63, 0xf2, 0xdc, 0xf4, 0xd7, 0x54, 0xeb, 0xc9, 0x77, 0xfd, 0x5f, 0xea, 0x95, 0x2e, 0x2b, + 0x9e, 0x9e, 0x76, 0x3d, 0x5a, 0x33, 0x82, 0xb2, 0x47, 0x46, 0x81, 0x7d, 0x42, 0x5f, 0xcb, 0x0b, + 0xbb, 0x9e, 0xf8, 0x2b, 0x21, 0xfd, 0x4e, 0xef, 0x96, 0xdb, 0x06, 0xcc, 0xc0, 0xda, 0x63, 0x96, + 0xb3, 0xcd, 0xff, 0x82, 0xb2, 0x3c, 0xfd, 0xf4, 0x6e, 0x9e, 0xcc, 0xb5, 0x14, 0xd6, 0x3d, 0xe7, + 0x63, 0xfc, 0xb7, 0x7a, 0x97, 0xc1, 0x2e, 0xf7, 0xba, 0x31, 0x24, 0x5b, 0x0f, 0x1d, 0x76, 0xfe, + 0x24, 0x14, 0xc5, 0xe4, 0x0f, 0x55, 0x60, 0xe4, 0x81, 0xd9, 0x65, 0x39, 0x97, 0x58, 0x28, 0x03, + 0x4f, 0x91, 0x62, 0x99, 0x8c, 0xc9, 0xd5, 0x53, 0x2c, 0x45, 0x1d, 0xfe, 0x5b, 0xe5, 0xeb, 0x8f, + 0x15, 0x87, 0x87, 0xb0, 0x9b, 0x92, 0xc6, 0xe3, 0xaa, 0x58, 0xf3, 0x6f, 0x94, 0xaf, 0x2d, 0xb8, + 0xae, 0x82, 0xa9, 0x63, 0x79, 0x8d, 0x3b, 0x13, 0xb0, 0xfa, 0xb2, 0x3f, 0xa0, 0x8b, 0x95, 0xc2, + 0x41, 0xa7, 0xbd, 0xdd, 0xdf, 0xc2, 0x7b, 0x9e, 0x96, 0xef, 0xf8, 0x50, 0x8a, 0xce, 0x64, 0x82, + 0x93, 0xe3, 0x45, 0xb9, 0x0b, 0x81, 0x32, 0xd3, 0xeb, 0x01, 0x20, 0x28, 0xb1, 0xe4, 0xa4, 0x60, + 0xad, 0x5e, 0x04, 0x8e, 0x5c, 0xe7, 0xa8, 0x2b, 0x32, 0x2f, 0x6f, 0x85, 0x09, 0xce, 0x17, 0x62, + 0x42, 0x55, 0x0b, 0x24, 0x3e, 0x9a, 0x68, 0x5e, 0xc1, 0xa8, 0x29, 0x4e, 0x9d, 0x8f, 0x13, 0xa3, + 0x6c, 0xf1, 0x00, 0xa6, 0x2e, 0x9c, 0xca, 0x79, 0x7c, 0xf7, 0xc6, 0x1c, 0x2a, 0x1f, 0x13, 0x9c, + 0x96, 0x00, 0x7a, 0xb0, 0xbc, 0xbd, 0x7d, 0xb9, 0x6b, 0xce, 0xa1, 0xeb, 0x16, 0x7b, 0xb4, 0xbd, + 0x5f, 0x88, 0x8c, 0x12, 0xf7, 0x15, 0xaa, 0xa4, 0xb4, 0xa6, 0x50, 0xc2, 0xca, 0xe2, 0x61, 0x13, + 0x88, 0xf9, 0x98, 0x17, 0x55, 0x55, 0x38, 0xf6, 0x72, 0xcd, 0x9f, 0x11, 0x04, 0xb4, 0x39, 0xd4, + 0x5c, 0xb9, 0x9e, 0x5f, 0x88, 0x10, 0xab, 0xab, 0xd3, 0xf1, 0x44, 0x7c, 0xbd, 0xb8, 0x87, 0xfe, + 0x41, 0x1b, 0xbf, 0x82, 0x33, 0xbc, 0x57, 0x78, 0x53, 0xa1, 0x35, 0x2f, 0x45, 0x38, 0xab, 0xa2, + 0x3d, 0x75, 0x79, 0x7a, 0xbf, 0xd7, 0x2a, 0xea, 0xe7, 0xd1, 0x1c, 0xbe, 0x08, 0xad, 0xb6, 0x9e, + 0x39, 0xf3, 0x52, 0x54, 0x92, 0xf0, 0x55, 0x23, 0x2d, 0x20, 0xae, 0x5e, 0x99, 0x22, 0xa5, 0x54, + 0x4a, 0x3e, 0x92, 0x35, 0x4b, 0xe1, 0x43, 0x56, 0xbd, 0x99, 0x3e, 0xb2, 0xbc, 0x26, 0x1a, 0xc6, + 0x7f, 0x85, 0x30, 0x7b, 0x65, 0x99, 0xcb, 0x23, 0x09, 0x89, 0x63, 0x19, 0xb1, 0x55, 0x1d, 0x04, + 0xb0, 0xbf, 0x52, 0xe3, 0x5a, 0x02, 0xa4, 0x5d, 0xf1, 0xc5, 0x66, 0x2c, 0x65, 0x93, 0xf7, 0x16, + 0xaa, 0xa2, 0x34, 0xfc, 0x10, 0x94, 0x41, 0xa0, 0x8d, 0x0b, 0xcb, 0xdf, 0xc2, 0x02, 0xa2, 0xea, + 0xaa, 0xf6, 0xbc, 0x40, 0x99, 0x28, 0x59, 0xc8, 0x9f, 0x43, 0xc8, 0xc2, 0x3e, 0x20, 0xc5, 0x14, + 0x62, 0xb1, 0x46, 0x20, 0x58, 0xe2, 0x04, 0xee, 0xe5, 0xa3, 0xfb, 0xae, 0x43, 0x3b, 0xbb, 0xf8, + 0xf1, 0x57, 0x4a, 0x7a, 0x3b, 0x8a, 0x3d, 0xdf, 0xc2, 0x1d, 0xd2, 0x12, 0x30, 0x2d, 0xbf, 0x0b, + 0x6f, 0x10, 0xe3, 0x84, 0xfa, 0x1b, 0xdf, 0x45, 0xcb, 0xeb, 0x15, 0xf4, 0x48, 0x71, 0x3d, 0x62, + 0x93, 0x9e, 0xa9, 0x5a, 0x36, 0xff, 0xa3, 0x23, 0xfe, 0x0b, 0x09, 0xbb, 0xbb, 0xbd, 0xe9, 0x70, + 0xfa, 0x2b, 0xd6, 0x20, 0x61, 0x45, 0xa8, 0x96, 0x55, 0xd6, 0x92, 0x4d, 0x03, 0x59, 0x96, 0xc6, + 0x38, 0x98, 0x50, 0x61, 0x3f, 0x26, 0x89, 0x61, 0x7d, 0x90, 0x28, 0x90, 0xe9, 0xcc, 0xdf, 0x80, + 0x48, 0x39, 0x10, 0xe5, 0x03, 0xea, 0x05, 0xbd, 0x03, 0x8c, 0x82, 0x82, 0x0e, 0x4d, 0x27, 0x8f, + 0x87, 0x32, 0x00, 0x8f, 0xe2, 0xa0, 0x8e, 0x30, 0x9d, 0xd5, 0x57, 0xfb, 0xe3, 0x2c, 0x88, 0xb2, + 0x38, 0xe9, 0x7b, 0xaa, 0x42, 0x5c, 0xed, 0xde, 0xc7, 0x4a, 0x61, 0x90, 0xcf, 0x39, 0x17, 0xdd, + 0x07, 0x86, 0x77, 0xf6, 0x6c, 0x9f, 0x18, 0x26, 0xd3, 0x57, 0x73, 0x55, 0x55, 0x07, 0xf7, 0xf4, + 0x90, 0x5f, 0x15, 0x62, 0x7c, 0x6e, 0xb4, 0xbd, 0xbe, 0x24, 0x25, 0x5d, 0x56, 0xdf, 0x88, 0x12, + 0x77, 0xdf, 0x77, 0xf1, 0xfa, 0x4b, 0x27, 0xae, 0xb2, 0x9c, 0xf0, 0x4d, 0x2f, 0x77, 0x70, 0xc5, + 0xa2, 0x01, 0xb0, 0x40, 0x5a, 0x21, 0xef, 0xbb, 0x49, 0x10, 0x41, 0xd7, 0x16, 0x59, 0x58, 0x95, + 0x89, 0xd8, 0x9d, 0x85, 0x13, 0x04, 0xa3, 0x2b, 0x46, 0x77, 0x0b, 0x3d, 0x5f, 0x89, 0x82, 0xa2, + 0x05, 0xab, 0x53, 0x32, 0x73, 0x51, 0xa5, 0x17, 0xdf, 0xe2, 0xe2, 0x58, 0x0a, 0xdc, 0x56, 0xdc, + 0x56, 0x5c, 0x13, 0xd5, 0x88, 0xbe, 0x60, 0x89, 0xd8, 0x9d, 0x8b, 0xea, 0x7b, 0xea, 0x9d, 0x7a, + 0x3a, 0x74, 0xba, 0x21, 0x41, 0x5d, 0x19, 0xbe, 0xad, 0xf4, 0x57, 0x24, 0xe4, 0x14, 0xee, 0xf5, + 0x89, 0x1e, 0x41, 0x0c, 0x05, 0x5b, 0xd7, 0x57, 0x3c, 0x1f, 0xe2, 0x42, 0x85, 0x8e, 0xe0, 0x76, + 0x31, 0xac, 0x36, 0x9a, 0xb4, 0x2b, 0xa8, 0xa6, 0x2e, 0x29, 0x8b, 0xb7, 0x12, 0x20, 0x28, 0x73, + 0x6b, 0xe2, 0x5c, 0x14, 0x62, 0x19, 0x1c, 0xdb, 0x46, 0xc1, 0x07, 0x97, 0x9f, 0xec, 0xc3, 0xcd, + 0x16, 0x7b, 0x8f, 0xf8, 0x50, 0x8f, 0xde, 0x21, 0xe5, 0xc5, 0xc2, 0x03, 0x8b, 0x9e, 0x71, 0x38, + 0x13, 0x27, 0x68, 0x77, 0x4a, 0x20, 0xf8, 0x99, 0xf3, 0xb0, 0x03, 0x92, 0x3f, 0xe1, 0x42, 0x24, + 0x07, 0xbf, 0x87, 0x61, 0xa3, 0xb0, 0x31, 0x89, 0x03, 0x80, 0xf1, 0x60, 0x7a, 0xd7, 0x2d, 0x9d, + 0xf9, 0x76, 0x2b, 0xbd, 0xf2, 0xe2, 0x63, 0x24, 0x80, 0xe8, 0x58, 0xdf, 0xd9, 0xcf, 0x71, 0xf0, + 0x9c, 0xa2, 0xe9, 0x18, 0xf3, 0x62, 0x32, 0xf3, 0xb0, 0xc6, 0x6f, 0x13, 0x1f, 0xe4, 0x25, 0xb2, + 0x38, 0xe4, 0xc9, 0x61, 0x84, 0x8b, 0xb6, 0x92, 0x45, 0x87, 0x2d, 0x40, 0x8e, 0xa6, 0x0f, 0x35, + 0x4a, 0xee, 0xec, 0x9c, 0x4c, 0x26, 0x24, 0x14, 0xa4, 0xce, 0x8c, 0x51, 0xbb, 0xf8, 0x98, 0x47, + 0x55, 0xbd, 0xf2, 0x2e, 0xbe, 0x24, 0x40, 0x9b, 0xcb, 0x8c, 0xdf, 0xfb, 0xf8, 0xfa, 0x56, 0xd4, + 0x7b, 0xb8, 0x4c, 0x31, 0x2c, 0x1c, 0xf2, 0xc9, 0x79, 0xb3, 0x89, 0x79, 0xf1, 0xff, 0x09, 0xdd, + 0xdd, 0xdd, 0xdd, 0xfc, 0xd7, 0xbf, 0x13, 0x13, 0xb5, 0x0d, 0x50, 0xcb, 0xae, 0x22, 0x0b, 0x27, + 0xf3, 0xf7, 0x3e, 0x3e, 0xdd, 0xda, 0x2d, 0xf7, 0xc1, 0x25, 0x6a, 0xaf, 0xc4, 0xc1, 0x69, 0x82, + 0x96, 0x43, 0xd6, 0x6a, 0xef, 0x7e, 0xf8, 0x4c, 0xc1, 0x57, 0xd6, 0x5b, 0x14, 0x62, 0xb1, 0x5b, + 0x8a, 0xfc, 0xa7, 0x77, 0x14, 0x65, 0xce, 0x22, 0x6e, 0xf7, 0xba, 0xe6, 0x08, 0x9f, 0x0f, 0x86, + 0xc7, 0x62, 0xe8, 0x43, 0x1f, 0x5d, 0x4b, 0xd7, 0x2a, 0xe1, 0x29, 0xe8, 0xb9, 0x69, 0xd7, 0x5c, + 0xe7, 0xd7, 0x39, 0xf5, 0xce, 0x7d, 0x7a, 0x7e, 0x09, 0x0a, 0x7c, 0x3e, 0x1b, 0x1d, 0x85, 0x4f, + 0x82, 0x11, 0x4a, 0xb5, 0x1d, 0xe3, 0xc1, 0x34, 0xf0, 0xd2, 0x2b, 0x14, 0xe8, 0xc7, 0x6a, 0xc4, + 0x0c, 0x10, 0xee, 0xee, 0xf7, 0x8a, 0xdd, 0xdd, 0xef, 0x86, 0xc8, 0x24, 0x01, 0x1e, 0x8d, 0x59, + 0xbb, 0xfb, 0xbc, 0x56, 0xa2, 0xb5, 0x79, 0x7b, 0x89, 0x7c, 0x96, 0xc4, 0x1e, 0x4c, 0xad, 0x75, + 0xae, 0x11, 0x12, 0x14, 0x29, 0x38, 0x69, 0x24, 0xa5, 0x01, 0x61, 0xca, 0x42, 0x30, 0x79, 0x75, + 0x9f, 0x6b, 0x05, 0xe4, 0xed, 0x1e, 0xcb, 0x98, 0x1e, 0x3f, 0x11, 0x42, 0x74, 0x46, 0xbe, 0x24, + 0x28, 0x28, 0xb3, 0x9e, 0xe6, 0x80, 0x93, 0x70, 0xd1, 0x58, 0xe5, 0x5c, 0x4b, 0x92, 0x30, 0xd9, + 0x19, 0xa4, 0x69, 0xd0, 0x71, 0xb3, 0x58, 0xd9, 0x58, 0xd5, 0x0f, 0x78, 0x91, 0x13, 0x96, 0xd5, + 0x15, 0x5d, 0x7e, 0x14, 0x28, 0xeb, 0xf6, 0x0e, 0x3f, 0x6f, 0x39, 0x63, 0x39, 0x61, 0xc4, 0x2c, + 0x1f, 0x60, 0x56, 0x5e, 0x60, 0xe6, 0x8b, 0x75, 0x3b, 0xfc, 0x21, 0x79, 0xfb, 0xb5, 0x41, 0xec, + 0x0b, 0x65, 0xb7, 0x8a, 0xc4, 0x34, 0xe2, 0x41, 0x48, 0x9b, 0x9f, 0xee, 0x87, 0x8e, 0x63, 0x64, + 0xa7, 0xb8, 0x98, 0x2c, 0xd5, 0x2e, 0x5e, 0xc7, 0x8a, 0xdc, 0xe9, 0xf3, 0x72, 0x7f, 0xb8, 0xac, + 0x4c, 0xc5, 0x5f, 0x0e, 0x20, 0x14, 0x10, 0xdc, 0x47, 0xac, 0xe3, 0x08, 0x3f, 0x25, 0xe1, 0x03, + 0x87, 0xa3, 0x2d, 0x56, 0x8c, 0x7b, 0xc7, 0x8d, 0x8e, 0xf9, 0x66, 0xc0, 0xaf, 0xcc, 0xc6, 0x66, + 0x26, 0x3a, 0x5c, 0xb1, 0xb6, 0x8a, 0x67, 0xa0, 0xfd, 0x80, 0xa8, 0xfc, 0xec, 0x43, 0xed, 0x70, + 0x3b, 0xfe, 0x1c, 0x6b, 0xf8, 0x50, 0x9a, 0xc9, 0x33, 0x77, 0x19, 0xf6, 0xda, 0x23, 0x46, 0x4a, + 0x12, 0x92, 0xff, 0x05, 0x43, 0x04, 0x3c, 0xb1, 0xee, 0x36, 0xb9, 0x6c, 0x57, 0x15, 0xf7, 0xf8, + 0x28, 0x28, 0xad, 0xc5, 0x6e, 0xf7, 0xeb, 0xe6, 0x2a, 0x6b, 0x50, 0x8f, 0x58, 0x2b, 0xab, 0xfd, + 0x63, 0xc9, 0xd5, 0xef, 0xa2, 0xf8, 0xae, 0x2a, 0xb2, 0xaa, 0xd9, 0xa0, 0x68, 0x47, 0xe0, 0xb8, + 0xc7, 0xbf, 0x4c, 0x6f, 0x7f, 0xab, 0xaf, 0x78, 0x91, 0x86, 0x2d, 0x15, 0xca, 0x2e, 0x36, 0x96, + 0xfc, 0x36, 0x35, 0x2d, 0x4a, 0x94, 0x9e, 0x55, 0x7f, 0x9c, 0x4c, 0x14, 0x89, 0xba, 0x6f, 0x5a, + 0x97, 0x96, 0xdb, 0xcb, 0x6d, 0xc4, 0xc2, 0x85, 0xea, 0x42, 0x0a, 0xb3, 0x97, 0xeb, 0x24, 0x62, + 0x6e, 0xcc, 0x1d, 0xf3, 0xbc, 0x40, 0xc1, 0x4b, 0x95, 0x99, 0x61, 0x98, 0x53, 0xa9, 0x6e, 0xff, + 0xd4, 0xd0, 0xac, 0xa9, 0xa5, 0xac, 0xfc, 0x47, 0x55, 0x13, 0xe4, 0xe5, 0xf1, 0xf8, 0x50, 0xf8, + 0x9b, 0x11, 0x36, 0x37, 0x77, 0x4e, 0xd3, 0x71, 0x58, 0xad, 0xc5, 0x6f, 0xc4, 0x88, 0x05, 0x62, + 0x45, 0x62, 0xb4, 0xc5, 0x18, 0xa0, 0xc5, 0x18, 0xa0, 0x31, 0x20, 0x90, 0x45, 0x1b, 0x96, 0x0c, + 0xfd, 0xfe, 0x10, 0x23, 0x8a, 0xdd, 0xd8, 0xce, 0xcf, 0x3f, 0x3e, 0x78, 0x91, 0x23, 0x0a, 0xef, + 0xb4, 0xf5, 0xcb, 0xf4, 0x9d, 0xf1, 0x1e, 0x27, 0xe2, 0x7e, 0x62, 0xba, 0xab, 0xf9, 0x48, 0x76, + 0x1d, 0xec, 0x5f, 0x82, 0xe1, 0x5a, 0xae, 0xab, 0x5f, 0x29, 0x5e, 0x5c, 0x4b, 0x13, 0xe1, 0x01, + 0x03, 0x04, 0xad, 0x8c, 0x57, 0xe3, 0x94, 0x46, 0xf8, 0xa8, 0x5b, 0x23, 0xa8, 0x39, 0xaa, 0x04, + 0x35, 0xd2, 0xa6, 0x1e, 0xb3, 0xc2, 0x35, 0x7d, 0xbf, 0xb2, 0x15, 0xc3, 0x11, 0x54, 0x79, 0xf1, + 0x0b, 0x0d, 0xf8, 0xcb, 0x36, 0x62, 0x76, 0x4b, 0x04, 0x1e, 0xfa, 0x38, 0x9e, 0x3b, 0x37, 0x63, + 0x6d, 0x1b, 0x33, 0xc2, 0xe3, 0x07, 0xf1, 0xb7, 0x89, 0x7c, 0x4b, 0x8c, 0x76, 0xb3, 0xf9, 0x12, + 0xff, 0x82, 0x88, 0x91, 0x84, 0xb6, 0xf9, 0xfc, 0xc9, 0x09, 0x74, 0x25, 0xcf, 0x9b, 0x96, 0xda, + 0x27, 0x21, 0x55, 0xdd, 0x57, 0x58, 0xbe, 0x4b, 0xba, 0xaa, 0xeb, 0x17, 0xc6, 0x9a, 0xaa, 0x6c, + 0x97, 0xe8, 0x93, 0x55, 0x37, 0x1c, 0x57, 0x79, 0x40, 0xcd, 0xd1, 0x03, 0x2d, 0xff, 0xc7, 0xdd, + 0x2c, 0xfc, 0xfd, 0xf4, 0x95, 0x09, 0x17, 0x82, 0x4c, 0xbd, 0xf7, 0xf8, 0x27, 0xa7, 0x5a, 0x34, + 0x68, 0xd1, 0xbb, 0xc4, 0x0c, 0x10, 0x5b, 0x3c, 0x52, 0x3d, 0x6e, 0x84, 0x5b, 0xc4, 0x2c, 0x0c, + 0xe0, 0xe1, 0x60, 0x56, 0x7c, 0x46, 0xe1, 0xe2, 0x22, 0x06, 0xbf, 0xf6, 0x6e, 0xaa, 0x5e, 0xbc, + 0x40, 0x27, 0xac, 0x6b, 0x6c, 0x5d, 0x2e, 0x5f, 0x05, 0xc4, 0x3f, 0x99, 0xba, 0x6a, 0x9a, 0xa6, + 0xff, 0x25, 0xdc, 0x56, 0x2b, 0xc4, 0x45, 0x6f, 0x74, 0xc5, 0x1a, 0x62, 0x8f, 0x08, 0x02, 0x10, + 0xa1, 0x5e, 0xf1, 0x00, 0x2c, 0x15, 0x74, 0x01, 0x65, 0x5f, 0xda, 0xbb, 0x4b, 0xaa, 0xc9, 0xce, + 0x47, 0x87, 0x13, 0xaf, 0x04, 0x77, 0xdc, 0x9f, 0x84, 0x23, 0x8a, 0x28, 0xc4, 0x34, 0x14, 0x19, + 0xef, 0x2d, 0x8a, 0xcb, 0x62, 0xb7, 0x2d, 0x96, 0x07, 0xb0, 0xe2, 0x50, 0x8e, 0xf8, 0x28, 0x39, + 0xa8, 0xc0, 0x95, 0x72, 0x53, 0x1c, 0xe2, 0x60, 0x86, 0x7f, 0xfb, 0x89, 0x12, 0x12, 0x38, 0x8f, + 0x8c, 0x9d, 0xbc, 0x56, 0x28, 0xcb, 0xcb, 0x6b, 0x90, 0x73, 0xbb, 0xfc, 0x15, 0x89, 0x43, 0xd4, + 0xfb, 0x40, 0xbf, 0xa1, 0xf1, 0xb6, 0x54, 0xc6, 0x86, 0x47, 0x19, 0x74, 0x68, 0xfb, 0x57, 0xfe, + 0x0a, 0x88, 0x82, 0x1e, 0x97, 0xab, 0xcb, 0xa9, 0xdb, 0xc7, 0xdc, 0x4c, 0x24, 0x77, 0x6f, 0x72, + 0xdb, 0x8a, 0xc4, 0xbc, 0xb7, 0xe3, 0x2d, 0x0b, 0x44, 0xb5, 0xd6, 0x59, 0xea, 0x69, 0x1c, 0xad, + 0x18, 0xcf, 0x9d, 0xb4, 0xf0, 0x9f, 0x2b, 0x13, 0xdb, 0x43, 0xfe, 0x1f, 0xd3, 0xc1, 0x55, 0xef, + 0xb6, 0xf1, 0x75, 0xae, 0xbe, 0x3c, 0x63, 0xbd, 0xf7, 0x77, 0x7b, 0xb9, 0x7a, 0x13, 0xf0, 0xbb, + 0xbe, 0xfe, 0xb9, 0xd3, 0xf4, 0x4a, 0x8d, 0xeb, 0xaf, 0x82, 0x39, 0x39, 0x8c, 0xa0, 0xa8, 0x44, + 0xab, 0xb2, 0xe5, 0xa3, 0xf8, 0x24, 0x8b, 0xc5, 0xd6, 0xef, 0x85, 0x05, 0x37, 0x96, 0xdd, 0xf7, + 0x97, 0x99, 0x2d, 0xb1, 0x9c, 0x4a, 0xc1, 0xe3, 0xc4, 0x3d, 0xf0, 0x9b, 0xc4, 0x04, 0x07, 0x8c, + 0xa0, 0xcb, 0x67, 0x62, 0xf5, 0x68, 0x4a, 0xe9, 0xae, 0x36, 0xb2, 0x98, 0x81, 0x20, 0x88, 0x42, + 0x8b, 0xac, 0x89, 0xe2, 0x41, 0x39, 0x45, 0x18, 0xa3, 0x15, 0x8a, 0x37, 0x15, 0x88, 0x54, 0x16, + 0xf9, 0x57, 0x85, 0x28, 0x47, 0x50, 0x9d, 0xa3, 0x2f, 0x4e, 0xe6, 0x5d, 0x3c, 0xe5, 0x41, 0x6d, + 0xc5, 0x63, 0xff, 0x12, 0x11, 0x0a, 0x44, 0x03, 0x82, 0x83, 0x3d, 0xf6, 0xdb, 0xb7, 0x2d, 0x85, + 0x56, 0x22, 0x58, 0x16, 0x0d, 0xad, 0x76, 0x32, 0xec, 0xe7, 0xf8, 0x47, 0x3b, 0x12, 0x8b, 0x8b, + 0xc8, 0x5b, 0x62, 0x2f, 0xaf, 0x10, 0x0a, 0x4a, 0x2b, 0x71, 0x5b, 0x8a, 0xc5, 0x62, 0xb1, 0x5b, + 0xb8, 0xad, 0xdf, 0xc4, 0x02, 0xe9, 0x5c, 0x80, 0x7b, 0xec, 0xeb, 0x50, 0x56, 0xbd, 0xe2, 0x19, + 0x94, 0xf9, 0xf1, 0x02, 0xca, 0xf7, 0x7b, 0xdf, 0x10, 0x20, 0x11, 0x49, 0xe4, 0xfe, 0xf8, 0x4e, + 0xee, 0xaa, 0xee, 0xee, 0xb8, 0x52, 0xed, 0x90, 0x46, 0xcf, 0x82, 0xb9, 0x3e, 0x1d, 0x8c, 0x9e, + 0xec, 0x42, 0x76, 0x1e, 0x85, 0x1f, 0xf1, 0xf2, 0x19, 0x78, 0x80, 0xbc, 0x47, 0x3d, 0x10, 0x14, + 0x1f, 0xc6, 0xc6, 0x32, 0x5a, 0x30, 0x8b, 0x43, 0xda, 0x1e, 0x1f, 0x10, 0x14, 0xe6, 0xdc, 0x72, + 0xe3, 0xf1, 0xe4, 0xf7, 0x37, 0xee, 0xa1, 0xd7, 0x8c, 0x5d, 0x01, 0xd4, 0x19, 0x15, 0x4f, 0xf0, + 0x53, 0xcb, 0xc9, 0xf7, 0x15, 0x8a, 0xde, 0x17, 0x73, 0xa1, 0xc7, 0xe1, 0x39, 0x51, 0x0d, 0x37, + 0x45, 0xab, 0x4e, 0xa4, 0xe6, 0x14, 0xf9, 0x69, 0xe8, 0xa3, 0xe9, 0x3a, 0x2c, 0x55, 0xd5, 0x8f, + 0x82, 0x3b, 0xee, 0xc1, 0x74, 0x67, 0xbe, 0xb5, 0x5d, 0x62, 0x93, 0xad, 0x49, 0xc8, 0x25, 0x8e, + 0x76, 0x4a, 0xcb, 0xe4, 0x23, 0xeb, 0xe0, 0x90, 0x8b, 0x5e, 0xb8, 0x81, 0x20, 0xb0, 0xaa, 0xad, + 0x8b, 0xde, 0x86, 0xdd, 0xbf, 0x5f, 0x11, 0xad, 0x54, 0x98, 0x97, 0xc4, 0x02, 0xa1, 0x13, 0xbb, + 0x7b, 0xbc, 0xbd, 0x32, 0xdb, 0xfc, 0xa2, 0x6a, 0xc2, 0x6f, 0x12, 0x20, 0x15, 0x4f, 0xdd, 0xe7, + 0x82, 0x51, 0x46, 0x98, 0xad, 0xdb, 0x47, 0x78, 0x81, 0x20, 0x9e, 0x9e, 0x5f, 0x72, 0xb3, 0x8e, + 0x6f, 0x12, 0x0b, 0x6a, 0xb5, 0x79, 0x58, 0xff, 0xc4, 0x0f, 0xd1, 0xb1, 0xb1, 0xb1, 0xde, 0xe2, + 0xb7, 0x77, 0x7e, 0x20, 0x17, 0x1c, 0x42, 0x20, 0x25, 0xbb, 0x15, 0x9d, 0x80, 0xab, 0x42, 0x32, + 0xe6, 0x4f, 0xfc, 0x40, 0x52, 0xee, 0x2b, 0x0d, 0x08, 0x4c, 0x05, 0x62, 0xbb, 0x76, 0xb0, 0x7a, + 0x90, 0x8e, 0xf0, 0x03, 0x37, 0x02, 0x7f, 0xd0, 0xaf, 0xa2, 0xfb, 0x89, 0x8f, 0x21, 0x23, 0xad, + 0x0e, 0x4a, 0x21, 0xf9, 0x73, 0xc4, 0xfd, 0x5d, 0xe2, 0x7e, 0x42, 0x37, 0x6f, 0xe2, 0xf6, 0x64, + 0xca, 0x15, 0xc7, 0x63, 0x98, 0x6f, 0xc6, 0x1e, 0x71, 0x05, 0xa1, 0xbe, 0xc6, 0x79, 0x06, 0xd8, + 0x66, 0xcf, 0xdb, 0x8f, 0x18, 0x2c, 0x17, 0xcd, 0x18, 0x43, 0xc2, 0xcd, 0xe1, 0x4b, 0xdd, 0xd0, + 0x41, 0x57, 0xce, 0xc3, 0x17, 0xa4, 0x25, 0x4d, 0x9b, 0xc2, 0xe0, 0x79, 0xd2, 0x17, 0xbf, 0xc6, + 0x6d, 0xc8, 0x91, 0x33, 0x78, 0x7f, 0x4c, 0xe8, 0x5a, 0xf1, 0x2a, 0x79, 0x98, 0x47, 0x5b, 0x70, + 0xa7, 0x19, 0x16, 0xc3, 0xa1, 0xb8, 0x9b, 0x2b, 0x37, 0x81, 0x58, 0x72, 0x20, 0xba, 0xef, 0x04, + 0x25, 0xa1, 0x56, 0xec, 0xb5, 0xb1, 0xf0, 0x81, 0x31, 0xdf, 0x8a, 0x36, 0x3d, 0x3a, 0xce, 0x90, + 0xb6, 0xd0, 0xee, 0x9a, 0x0f, 0xcb, 0x56, 0xb5, 0x38, 0x6a, 0x03, 0xc4, 0x08, 0xbe, 0x1e, 0x18, + 0xef, 0x7c, 0x6d, 0x72, 0xde, 0x25, 0x80, 0xc8, 0x71, 0x93, 0x0e, 0x18, 0x3a, 0x05, 0xe5, 0xe8, + 0xaf, 0xf4, 0x57, 0xfa, 0xbd, 0xf5, 0xcc, 0x7d, 0x5e, 0xba, 0xbc, 0xfd, 0x5e, 0x5e, 0x6e, 0xd9, + 0x59, 0xf0, 0xe9, 0x23, 0x58, 0x3a, 0x48, 0x99, 0xf7, 0x0d, 0x9c, 0x21, 0x0f, 0x5f, 0x16, 0x1c, + 0x24, 0x1d, 0x99, 0x60, 0x85, 0x02, 0xef, 0xd6, 0xad, 0xcf, 0xae, 0x24, 0x5c, 0x2b, 0x32, 0x5e, + 0xa2, 0x70, 0x97, 0xc8, 0x61, 0x0f, 0x5e, 0x6c, 0x19, 0x9c, 0x6b, 0x1e, 0x08, 0xcd, 0x5a, 0xfb, + 0xc4, 0x84, 0x85, 0xb8, 0xad, 0xc5, 0x72, 0x45, 0x1d, 0x78, 0x98, 0xbb, 0xca, 0xc4, 0x43, 0xc5, + 0x6e, 0x2b, 0xf0, 0x57, 0x71, 0x58, 0x95, 0x82, 0xde, 0xda, 0x52, 0xf1, 0x5b, 0xbe, 0x6f, 0x10, + 0x09, 0x23, 0xa8, 0x0b, 0x76, 0x2b, 0xe3, 0xbf, 0x05, 0x37, 0xa6, 0xcd, 0x09, 0xac, 0xb7, 0x5b, + 0x8a, 0xdd, 0xff, 0x51, 0x02, 0x41, 0x2c, 0x56, 0xe2, 0x51, 0x01, 0x2d, 0xc1, 0x36, 0x60, 0xbb, + 0xd9, 0xe5, 0xf8, 0xbb, 0x8e, 0xae, 0x73, 0x76, 0xcb, 0xfd, 0x90, 0x56, 0xef, 0x5c, 0x65, 0xb4, + 0x53, 0xcd, 0x52, 0x89, 0x5d, 0xe6, 0x93, 0xde, 0x00, 0x01, 0xc6, 0x32, 0xfc, 0x61, 0x6d, 0xc6, + 0xbd, 0xd2, 0x64, 0x83, 0xaf, 0xd6, 0xda, 0x23, 0x55, 0xcd, 0x00, 0xed, 0xca, 0xf1, 0x30, 0x86, + 0x3a, 0xf0, 0xc2, 0x4c, 0x6f, 0x18, 0x77, 0x39, 0x8b, 0xb7, 0xc2, 0x34, 0x4f, 0x12, 0x20, 0x8a, + 0x81, 0xd8, 0xf5, 0xed, 0x96, 0x54, 0x1d, 0xfc, 0x23, 0x80, 0x65, 0x18, 0x61, 0xa1, 0xba, 0x4e, + 0xf9, 0x24, 0xbf, 0x20, 0x93, 0xec, 0xa9, 0x36, 0xdf, 0xc2, 0x9e, 0x38, 0xb7, 0x1a, 0xd0, 0x7c, + 0x42, 0x40, 0x3e, 0x99, 0xcc, 0xd8, 0x71, 0xd1, 0x06, 0xfb, 0xb4, 0xb9, 0x4f, 0x84, 0x72, 0x91, + 0x77, 0xc0, 0x63, 0x2d, 0x4a, 0x23, 0xe1, 0x73, 0xb1, 0x8e, 0xe5, 0x9d, 0x93, 0xe3, 0x1a, 0x9a, + 0xcb, 0xd7, 0x51, 0x7c, 0x11, 0x0c, 0xb6, 0xb1, 0xf7, 0xc1, 0x0f, 0xbb, 0xbc, 0x9c, 0xc2, 0x6b, + 0x55, 0x88, 0x0a, 0x11, 0x56, 0xd1, 0x3a, 0xa1, 0x3e, 0x51, 0xa3, 0xaf, 0x01, 0xb6, 0x0c, 0xcc, + 0x5b, 0xc7, 0x71, 0x3f, 0x10, 0x8e, 0xf5, 0x88, 0x77, 0x77, 0x2a, 0x4f, 0x1f, 0x77, 0x77, 0x63, + 0x63, 0x63, 0x63, 0x71, 0x59, 0xd8, 0x6f, 0x58, 0x83, 0x65, 0x66, 0xbe, 0x22, 0x5f, 0x6e, 0x21, + 0xc3, 0xa8, 0x6f, 0x6f, 0x6f, 0xf3, 0x6a, 0xab, 0xe3, 0x37, 0x2e, 0xed, 0xde, 0x72, 0xc6, 0x33, + 0x77, 0xd9, 0x3f, 0x10, 0x33, 0x2e, 0x5d, 0xfe, 0x7b, 0x07, 0x6d, 0xfc, 0x08, 0xea, 0x8d, 0x16, + 0xc3, 0x10, 0x20, 0x61, 0x51, 0x39, 0x20, 0x7b, 0x4c, 0xf0, 0x43, 0x5e, 0x6c, 0x3a, 0xc3, 0x7d, + 0xb7, 0xfb, 0x9c, 0x47, 0xc7, 0x59, 0x40, 0xc7, 0x5f, 0x27, 0x4c, 0x7b, 0xb4, 0xed, 0xa7, 0xe2, + 0x15, 0xfe, 0x32, 0x78, 0x6e, 0xd0, 0xc7, 0x83, 0x6e, 0xab, 0x1a, 0x47, 0x27, 0x56, 0x5e, 0x70, + 0x8a, 0x9a, 0x5e, 0xa2, 0xed, 0xf8, 0xcd, 0x34, 0x4e, 0x7a, 0xfc, 0x0d, 0x7d, 0x65, 0x3e, 0x13, + 0x8d, 0xda, 0xbb, 0xea, 0xff, 0xbd, 0x0e, 0xc3, 0x30, 0x87, 0x88, 0x08, 0xc5, 0xc5, 0xc5, 0xc9, + 0x41, 0xa6, 0x87, 0xd3, 0x67, 0xb3, 0x63, 0x7f, 0x71, 0x58, 0xac, 0xb6, 0x2b, 0xf0, 0x9e, 0x4c, + 0x76, 0xe6, 0xae, 0x4e, 0x1e, 0x18, 0xe2, 0xbd, 0xee, 0x5d, 0x8a, 0xda, 0x91, 0x31, 0xb3, 0xc7, + 0xf3, 0x74, 0x7c, 0x25, 0xea, 0xc8, 0x8e, 0xae, 0xae, 0xae, 0x57, 0x05, 0x42, 0x33, 0x32, 0xdd, + 0x61, 0x7a, 0x12, 0x19, 0x31, 0x32, 0x0b, 0xf1, 0x1b, 0x1f, 0x05, 0x30, 0xff, 0x94, 0x67, 0x60, + 0xf7, 0xf7, 0x7e, 0x6f, 0x22, 0x49, 0xc4, 0x0f, 0x23, 0x0c, 0x20, 0xe5, 0xa3, 0xa9, 0x29, 0xfb, + 0x32, 0x1d, 0x0d, 0x3f, 0x45, 0xee, 0x26, 0x89, 0x5f, 0x04, 0xf6, 0xa5, 0xcc, 0x1f, 0xfb, 0x67, + 0xbe, 0x30, 0x8a, 0xab, 0x55, 0x8b, 0xc8, 0xbd, 0x1c, 0x5d, 0xbe, 0x22, 0xbd, 0xf0, 0x50, 0x5c, + 0xd5, 0xaa, 0xaa, 0xb1, 0x51, 0x02, 0x7e, 0x2c, 0xb5, 0x51, 0x76, 0xc5, 0xeb, 0xe0, 0xa0, 0xc2, + 0xf5, 0x5d, 0xcb, 0x8e, 0x7c, 0x20, 0x55, 0x5d, 0x77, 0xb6, 0xfc, 0x4c, 0x14, 0xc5, 0xe3, 0x0b, + 0xe9, 0xc4, 0xfb, 0x9f, 0xfa, 0xb6, 0xa7, 0x4f, 0x9a, 0xed, 0x8d, 0x84, 0x03, 0x3c, 0x48, 0x8b, + 0x5d, 0xdf, 0xbf, 0x10, 0x2c, 0xae, 0xf9, 0x12, 0x9e, 0xac, 0x96, 0x8e, 0x1f, 0x2c, 0x64, 0xd1, + 0x43, 0x71, 0x67, 0xcb, 0x88, 0x17, 0x44, 0x62, 0x63, 0x06, 0x95, 0xd3, 0x24, 0x15, 0x30, 0x85, + 0x40, 0xe8, 0xc0, 0xb8, 0x92, 0xca, 0xc1, 0xce, 0xb8, 0x42, 0xba, 0x11, 0xc4, 0x04, 0xe5, 0xa7, + 0xb3, 0x7c, 0xfc, 0xa3, 0x1f, 0x71, 0x3d, 0x1d, 0x8f, 0xab, 0x45, 0xf0, 0x52, 0x51, 0x9e, 0xbd, + 0x9c, 0xec, 0x39, 0x63, 0x3c, 0xb3, 0x53, 0x81, 0xdf, 0x82, 0x91, 0x94, 0x4a, 0x23, 0xd9, 0xe1, + 0xf0, 0x6a, 0x94, 0xc3, 0x62, 0x27, 0x27, 0x0f, 0x93, 0xfd, 0x15, 0x38, 0x78, 0x2e, 0xbd, 0xef, + 0x7f, 0xbc, 0x40, 0x29, 0x13, 0xbb, 0xa8, 0x68, 0xe5, 0x3b, 0x76, 0xd2, 0x35, 0xe7, 0x6f, 0xab, + 0xfd, 0x75, 0xc4, 0x08, 0x05, 0x37, 0x77, 0x3d, 0x15, 0x66, 0xf6, 0x97, 0xfc, 0x40, 0x91, 0x1b, + 0x73, 0xa9, 0xa7, 0x4f, 0x12, 0x24, 0x17, 0x6d, 0xcd, 0xd6, 0x92, 0x10, 0xed, 0xc4, 0x09, 0x24, + 0x42, 0xc0, 0xaf, 0xf1, 0xf6, 0xa9, 0x27, 0x39, 0x9d, 0x94, 0x77, 0x9f, 0xce, 0xa2, 0xf8, 0x81, + 0x2e, 0xab, 0x3f, 0x05, 0xb5, 0xd2, 0x37, 0xab, 0xf7, 0xc6, 0x6a, 0x74, 0x98, 0xb8, 0xbf, 0x6d, + 0x3b, 0x1b, 0x64, 0xea, 0xe9, 0x89, 0x8e, 0x83, 0x5a, 0x90, 0x67, 0xac, 0xc3, 0x5c, 0x3a, 0xaa, + 0xdd, 0xe0, 0xdd, 0xe0, 0xfc, 0x55, 0xe7, 0xea, 0xdb, 0x60, 0xce, 0x99, 0x52, 0x99, 0xc4, 0x08, + 0xbe, 0x2c, 0xae, 0x80, 0xd1, 0x4f, 0x53, 0xb0, 0x72, 0x3f, 0x8b, 0xbc, 0xea, 0x1d, 0x55, 0x57, + 0x89, 0xf8, 0x42, 0xf7, 0x3e, 0x3f, 0x7b, 0x97, 0x21, 0x2e, 0x68, 0xac, 0x4b, 0x41, 0x59, 0x6d, + 0x73, 0x08, 0x55, 0x5a, 0xe4, 0xaa, 0xaa, 0x8e, 0xeb, 0xa8, 0x8e, 0xbd, 0xf0, 0x4e, 0x22, 0x2e, + 0x6c, 0x67, 0x17, 0x88, 0x1f, 0x7f, 0x55, 0xd9, 0x6e, 0xef, 0xe0, 0x9c, 0xa8, 0xef, 0xbb, 0x97, + 0x19, 0xf5, 0xcb, 0xe4, 0x14, 0xb5, 0xae, 0x87, 0xb2, 0x48, 0x98, 0x2a, 0xb6, 0xba, 0xc9, 0xf9, + 0xb7, 0xf3, 0xe0, 0x88, 0x96, 0xdb, 0x37, 0xae, 0x22, 0x08, 0x62, 0xeb, 0x2a, 0x8e, 0x7e, 0x08, + 0x8a, 0xdb, 0x1a, 0x1b, 0x71, 0x7c, 0x27, 0x63, 0x3b, 0x07, 0x62, 0x6a, 0x9f, 0xc5, 0x53, 0xb5, + 0xea, 0xfe, 0x14, 0x29, 0x0f, 0x57, 0xcd, 0xc3, 0x52, 0x90, 0xc8, 0xae, 0xc5, 0x74, 0x47, 0x2c, + 0x89, 0x16, 0x49, 0x05, 0x32, 0xd8, 0xb8, 0xc8, 0xef, 0xd4, 0x1d, 0xc7, 0xe2, 0x2a, 0xc5, 0x72, + 0xdb, 0x22, 0x93, 0xa9, 0x8c, 0xdc, 0xa6, 0x77, 0x77, 0x7d, 0x19, 0xd3, 0xf4, 0x5c, 0xaf, 0xad, + 0x7d, 0x62, 0x8e, 0xc4, 0x0e, 0x11, 0x07, 0xfe, 0x2b, 0xb7, 0x77, 0x1c, 0xcc, 0xf7, 0xbf, 0x3f, + 0x31, 0x6e, 0xef, 0xe0, 0x9b, 0xba, 0x1b, 0x77, 0xbd, 0x73, 0x55, 0x0d, 0x4c, 0xc2, 0xe1, 0x23, + 0xaa, 0xaa, 0xaa, 0xaa, 0xfa, 0xeb, 0xe8, 0xe9, 0xfe, 0x42, 0x3b, 0xea, 0x22, 0x5b, 0xbb, 0xbf, + 0x8a, 0x29, 0xd9, 0x43, 0x3b, 0x2d, 0x64, 0x58, 0xe0, 0xd0, 0xc5, 0x8d, 0x70, 0x49, 0x71, 0x5b, + 0xb9, 0xd3, 0xe0, 0x88, 0x8f, 0x6d, 0xb3, 0xa7, 0x88, 0x0a, 0x49, 0x84, 0xce, 0xae, 0xaf, 0x10, + 0xe4, 0x8a, 0x2b, 0xaa, 0xf4, 0xbc, 0xb6, 0xcd, 0xd0, 0x9d, 0xc9, 0x88, 0x14, 0x6e, 0x4c, 0x9b, + 0x09, 0x8c, 0xc1, 0x3c, 0x13, 0xca, 0x90, 0x39, 0x58, 0x76, 0x0b, 0x5b, 0xbd, 0xf0, 0xf9, 0x75, + 0xaa, 0xe6, 0x17, 0x57, 0x7f, 0x46, 0x95, 0xf0, 0x47, 0x3f, 0xbe, 0xb0, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x07, 0x03, 0xb0, 0x22, 0x81, 0xdf, 0x42, 0xea, 0x37, 0xa2, 0x95, 0x3e, 0xa9, 0x97, + 0xa9, 0x96, 0x7d, 0x72, 0x87, 0x3a, 0xa7, 0x5e, 0xa9, 0xd2, 0xeb, 0x4e, 0xbd, 0x52, 0xaf, 0x58, + 0xa1, 0x7e, 0xa3, 0xca, 0x14, 0xea, 0x38, 0xd3, 0xf5, 0xef, 0xa9, 0x53, 0xeb, 0x84, 0x9d, 0x19, + 0xfe, 0x8a, 0xf0, 0x97, 0x47, 0x3d, 0x13, 0xd1, 0x8c, 0x88, 0x89, 0x89, 0xe2, 0x44, 0x98, 0x21, + 0x8b, 0xae, 0x11, 0x13, 0xc2, 0x22, 0x45, 0x13, 0x55, 0xdc, 0x43, 0x0c, 0x22, 0x24, 0x48, 0xd7, + 0x76, 0x72, 0x4a, 0xbf, 0x1a, 0xc4, 0xc1, 0x0f, 0x42, 0xc7, 0x1b, 0x84, 0x62, 0xab, 0x5d, 0xe1, + 0x61, 0xc7, 0x0c, 0x82, 0x82, 0x5f, 0x75, 0x55, 0x54, 0xab, 0x03, 0xc0, 0x21, 0xfa, 0x3d, 0x70, + 0xc0, 0x98, 0x9c, 0x4a, 0x09, 0x3f, 0x13, 0x16, 0x61, 0x5b, 0x8a, 0xcb, 0x47, 0x7f, 0xe4, 0xad, + 0x7e, 0x6d, 0x44, 0xf9, 0x66, 0x33, 0xa0, 0xaf, 0x32, 0x37, 0x5f, 0x00, 0x97, 0x2d, 0xdd, 0x55, + 0x40, 0x92, 0x23, 0x0e, 0x28, 0x3a, 0x23, 0x1f, 0xd3, 0x4f, 0x4d, 0x3f, 0xe2, 0x0e, 0x93, 0x4d, + 0x34, 0xdb, 0x6d, 0xb6, 0xe1, 0xc4, 0x20, 0x02, 0x52, 0x7b, 0x89, 0x3c, 0x7f, 0xdb, 0x6e, 0xd9, + 0x3a, 0x65, 0x1f, 0x82, 0x10, 0x09, 0x83, 0x84, 0x40, 0x6a, 0x36, 0x06, 0xa2, 0x83, 0x16, 0x00, + 0x3b, 0x0a, 0x30, 0x60, 0x35, 0x4a, 0x83, 0x56, 0x1c, 0x50, 0x00, 0x4c, 0x5b, 0xbb, 0xaa, 0x26, + 0x55, 0x6e, 0x89, 0xff, 0x2e, 0xbf, 0x05, 0xd2, 0xa7, 0x03, 0xc7, 0x54, 0xe0, 0x75, 0x51, 0x02, + 0xc3, 0x1a, 0x80, 0x04, 0x83, 0x12, 0xd5, 0xb4, 0x58, 0x2c, 0x40, 0x02, 0x65, 0x34, 0xcf, 0xe9, + 0xfd, 0xc1, 0x08, 0x64, 0x10, 0x08, 0xe5, 0xc0, 0x38, 0x00, 0xa0, 0x32, 0x8b, 0x09, 0x7e, 0xc0, + 0x00, 0x12, 0x36, 0x43, 0xf8, 0x8d, 0xf0, 0xd2, 0x80, 0x0f, 0x83, 0x87, 0x00, 0x55, 0x17, 0xc3, + 0x48, 0xaa, 0x00, 0x01, 0x14, 0x1d, 0x00, 0x92, 0x41, 0x85, 0x6c, 0xa9, 0x88, 0x1d, 0x6e, 0xe2, + 0xd9, 0xb7, 0x02, 0x48, 0x20, 0x08, 0x70, 0x5c, 0x12, 0x24, 0xb6, 0x20, 0x0b, 0x24, 0x60, 0x01, + 0xfb, 0x5c, 0x1b, 0xc9, 0x05, 0xd9, 0xa9, 0xc9, 0xd0, 0x06, 0xe2, 0x30, 0xa3, 0xe0, 0x51, 0x04, + 0x00, 0x8c, 0x4d, 0x0e, 0x25, 0x7e, 0x1f, 0x53, 0xf1, 0x0e, 0xd2, 0xf3, 0x1e, 0x3f, 0x8f, 0x89, + 0x82, 0x40, 0x82, 0xd7, 0xdc, 0x44, 0x4f, 0x55, 0x5a, 0xf1, 0x1f, 0x9b, 0x78, 0xaf, 0x11, 0x1d, + 0x70, 0xa0, 0xa8, 0x51, 0x53, 0xc7, 0x93, 0xab, 0xf3, 0x04, 0xc9, 0xcb, 0xff, 0x10, 0x82, 0xae, + 0x70, 0x86, 0x27, 0xa3, 0x57, 0xd6, 0x28, 0xde, 0x8b, 0x15, 0xf5, 0x8c, 0x3d, 0x5a, 0x27, 0x08, + 0x02, 0x72, 0x3b, 0xea, 0x17, 0x2b, 0x1c, 0x11, 0x3c, 0xb8, 0x31, 0x01, 0x52, 0x34, 0x71, 0x39, + 0xce, 0x03, 0xfe, 0x55, 0x35, 0x05, 0x44, 0x5c, 0x35, 0x80, 0x2e, 0x21, 0x81, 0x64, 0xc0, 0x77, + 0xc7, 0x10, 0x2c, 0x3c, 0x0e, 0x1b, 0x40, 0x12, 0x4b, 0x48, 0x91, 0x89, 0x3a, 0x8f, 0x00, 0xfa, + 0xec, 0x31, 0xe0, 0x3e, 0x14, 0x2f, 0xc1, 0xc4, 0x98, 0x59, 0xb8, 0x76, 0x84, 0x9c, 0xdb, 0xcd, + 0x0b, 0x6d, 0x61, 0xe4, 0x40, 0x02, 0xc7, 0x65, 0x0b, 0x6a, 0xcb, 0x38, 0x39, 0x41, 0x97, 0x3b, + 0x9f, 0x59, 0xc7, 0x37, 0x7e, 0xbb, 0x47, 0x0c, 0xe3, 0x81, 0x9c, 0x79, 0x72, 0x85, 0x28, 0xa0, + 0xa1, 0x9e, 0x0b, 0x89, 0xba, 0x28, 0x0b, 0x2c, 0x05, 0x8d, 0xa1, 0xe6, 0xba, 0xfc, 0x71, 0xf0, + 0xc1, 0x20, 0x16, 0x85, 0xe1, 0x81, 0x30, 0x1a, 0xe0, 0xab, 0x6a, 0x67, 0x1f, 0x72, 0xf3, 0xb8, + 0x39, 0x5c, 0x70, 0xee, 0x28, 0x30, 0xce, 0x01, 0xd3, 0xdd, 0x3d, 0xdd, 0x33, 0xdd, 0x3d, 0xd8, + 0xe3, 0x6c, 0x31, 0x28, 0x00, 0x88, 0x1e, 0x07, 0x10, 0xa4, 0x39, 0x60, 0x2a, 0x0a, 0x32, 0xb0, + 0x3a, 0xd7, 0xb0, 0x0d, 0x56, 0x00, 0x07, 0xf1, 0xcf, 0x2b, 0x35, 0xa1, 0x30, 0xb7, 0x99, 0xa1, + 0x58, 0x43, 0x16, 0x65, 0x89, 0x85, 0x25, 0x8c, 0xf1, 0xc2, 0xc6, 0x5b, 0x7c, 0x09, 0x42, 0xa5, + 0x8c, 0x6f, 0x3e, 0x02, 0xe1, 0x50, 0x7a, 0xc0, 0xfc, 0xf0, 0x78, 0x00, 0x08, 0x04, 0xf0, 0xf3, + 0x00, 0x6a, 0x5b, 0x38, 0x7b, 0x63, 0x75, 0xc4, 0x42, 0x92, 0xdb, 0x49, 0xc1, 0xc1, 0xc1, 0x80, + 0x75, 0x6b, 0x72, 0x75, 0x31, 0x9c, 0xe9, 0x66, 0x70, 0xf2, 0x55, 0x57, 0x55, 0x64, 0x87, 0x23, + 0xc3, 0x9d, 0xe2, 0x4a, 0x3c, 0x67, 0x28, 0x86, 0x10, 0xc7, 0xec, 0x91, 0x31, 0x62, 0x17, 0x55, + 0x4c, 0x9e, 0xd4, 0x48, 0x8f, 0xa2, 0xf5, 0x44, 0x08, 0xfa, 0x16, 0x75, 0xfd, 0x4e, 0x8a, 0x83, + 0x1d, 0x7a, 0x6e, 0x85, 0x74, 0xd8, 0x90, 0x52, 0x75, 0x35, 0x2a, 0x94, 0x5a, 0xaa, 0xa8, 0xbd, + 0x43, 0x12, 0x02, 0xa4, 0x68, 0x40, 0x54, 0x0e, 0xa9, 0x10, 0x82, 0xbe, 0x07, 0xe7, 0x7e, 0x42, + 0x06, 0xfe, 0x4c, 0x91, 0xa7, 0x0f, 0x8e, 0x0f, 0xcc, 0x80, 0x2f, 0xe9, 0xe2, 0x32, 0x50, 0x59, + 0x96, 0x62, 0x86, 0x28, 0x65, 0x99, 0xe6, 0x29, 0x8a, 0x63, 0x8c, 0x83, 0xf6, 0x8d, 0xf8, 0x71, + 0x41, 0x5d, 0x06, 0x22, 0xf1, 0x0a, 0x1b, 0x85, 0x4d, 0xda, 0xd3, 0x1b, 0xbd, 0x44, 0xd3, 0x2a, + 0xe1, 0xce, 0x94, 0xb0, 0xaf, 0xfb, 0x21, 0x44, 0xc0, 0x9a, 0x75, 0x49, 0xbe, 0x1c, 0x44, 0x00, + 0x0f, 0xd5, 0xa3, 0x15, 0x21, 0x81, 0x58, 0x79, 0xf9, 0x49, 0xcb, 0xa1, 0xee, 0x58, 0xd3, 0x49, + 0x18, 0xe6, 0xff, 0x6d, 0x4a, 0x8c, 0xbc, 0xc8, 0x6f, 0x4f, 0xb6, 0xde, 0x1c, 0xc0, 0x02, 0xe6, + 0x1f, 0x60, 0x54, 0xc7, 0x1a, 0x30, 0xb7, 0x0a, 0xbf, 0xec, 0x73, 0x8f, 0x3b, 0x70, 0xa9, 0x96, + 0x78, 0x74, 0x3c, 0x34, 0xe0, 0xbc, 0x0e, 0x61, 0xe9, 0xc9, 0xac, 0x19, 0xdf, 0x35, 0x1b, 0x04, + 0xc8, 0x3d, 0x83, 0x3b, 0x7d, 0x34, 0xf1, 0x01, 0x90, 0xa1, 0xc7, 0x40, 0x01, 0xf3, 0xc0, 0x00, + 0x9e, 0x0e, 0x20, 0x01, 0xf2, 0x70, 0x54, 0x68, 0x38, 0x1e, 0x82, 0x82, 0x00, 0xd4, 0xf6, 0x34, + 0x14, 0x2d, 0x03, 0xa0, 0x03, 0xe3, 0xa7, 0xd3, 0x8e, 0x35, 0xde, 0x19, 0xfc, 0x19, 0xcc, 0xf0, + 0xfa, 0x38, 0xf0, 0x80, 0x60, 0x64, 0x6d, 0xd8, 0x39, 0x02, 0xac, 0x23, 0x53, 0xea, 0x0a, 0xc9, + 0x43, 0xa4, 0x06, 0xa7, 0x72, 0xc7, 0x6d, 0x88, 0xf0, 0x3c, 0x9a, 0xad, 0xe7, 0x38, 0x76, 0x28, + 0x00, 0x00, 0x9a, 0x18, 0x31, 0x04, 0x01, 0x02, 0x32, 0x20, 0x1e, 0x1e, 0xc1, 0x99, 0x03, 0xe9, + 0x60, 0x8f, 0xb8, 0x44, 0xa0, 0xdc, 0x0e, 0x59, 0xa9, 0x28, 0x71, 0xd3, 0x7b, 0x7d, 0x04, 0xf0, + 0xe2, 0x04, 0x84, 0x42, 0x4a, 0x2e, 0x2e, 0xaa, 0xcf, 0x17, 0x5f, 0x88, 0xf9, 0x8e, 0x86, 0xb0, + 0x65, 0xaf, 0x10, 0x38, 0x47, 0x2f, 0x70, 0xa0, 0x38, 0x2c, 0x76, 0xe4, 0xa3, 0x95, 0xfe, 0xc2, + 0x66, 0xe2, 0xcd, 0x7c, 0x57, 0x16, 0x73, 0xd0, 0xf4, 0xcf, 0x43, 0xd3, 0x5c, 0x23, 0x3d, 0x0f, + 0x4c, 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0xe2, 0x17, 0xe2, 0x79, 0xe8, 0x7a, 0x67, 0xa1, 0xe9, 0xe3, + 0xa7, 0xa7, 0x3d, 0x0f, 0x4c, 0xf4, 0x3d, 0x30, 0xaf, 0x44, 0x72, 0x78, 0x12, 0x7e, 0x18, 0x1c, + 0x38, 0x99, 0x52, 0x51, 0xf7, 0xb9, 0xe6, 0xa4, 0x6a, 0xe5, 0x36, 0x5b, 0xbe, 0x18, 0x10, 0x14, + 0xd2, 0x22, 0x6e, 0x25, 0x0a, 0x18, 0x29, 0x45, 0x00, 0x49, 0x33, 0x09, 0x7a, 0xfa, 0xc8, 0xa4, + 0x06, 0x1d, 0xac, 0x40, 0x0d, 0xcf, 0x9d, 0x00, 0x01, 0x03, 0x10, 0xe2, 0x38, 0x35, 0xd5, 0x30, + 0x08, 0x37, 0x43, 0x18, 0x10, 0xc5, 0x68, 0x62, 0xff, 0x80, 0x09, 0x55, 0x50, 0x05, 0xc4, 0x8d, + 0x7c, 0x48, 0xc2, 0x1e, 0x74, 0x38, 0x88, 0x1d, 0x56, 0x19, 0xa2, 0x07, 0xd5, 0x80, 0x04, 0x17, + 0xad, 0xbb, 0x9c, 0x00, 0xc3, 0xb6, 0x7a, 0x61, 0x53, 0xc0, 0x6e, 0x95, 0x38, 0x00, 0x1a, 0x39, + 0x70, 0x3b, 0xe8, 0xc2, 0x60, 0x6a, 0x02, 0x5e, 0x31, 0x97, 0x08, 0xca, 0x15, 0x2b, 0x0f, 0xdb, + 0xae, 0x61, 0xd2, 0x28, 0xf1, 0x22, 0x04, 0x99, 0xef, 0xb7, 0x7e, 0x20, 0x49, 0x8b, 0x77, 0x0a, + 0x00, 0x38, 0xf2, 0x98, 0x4f, 0x15, 0x99, 0xe2, 0x30, 0xe7, 0x41, 0x76, 0x9f, 0x92, 0xaf, 0x53, + 0x75, 0x32, 0x57, 0x53, 0x25, 0x41, 0x88, 0x29, 0x15, 0x25, 0x12, 0x55, 0x3e, 0x3f, 0x2c, 0x3c, + 0x14, 0x86, 0x46, 0x84, 0xbd, 0x20, 0x56, 0x96, 0xb5, 0x6c, 0xb9, 0x04, 0xa0, 0x00, 0x2a, 0xaa, + 0x41, 0xd2, 0x65, 0xdc, 0x65, 0x4b, 0x19, 0x78, 0xa8, 0x45, 0xb9, 0x3f, 0x85, 0x01, 0x60, 0xe9, + 0x65, 0xcf, 0xd7, 0xf1, 0x10, 0xa7, 0xbb, 0xda, 0x2c, 0x63, 0x04, 0x80, 0x1f, 0x3d, 0x93, 0x81, + 0x42, 0x3c, 0x39, 0x54, 0x40, 0x46, 0x98, 0x00, 0x40, 0x9e, 0x3f, 0x8b, 0x14, 0x68, 0x90, 0x17, + 0x1f, 0x95, 0x3e, 0x14, 0x86, 0xb0, 0x65, 0xf1, 0x95, 0x17, 0x28, 0xe6, 0x9b, 0x9a, 0xd1, 0x87, + 0x91, 0xd7, 0x09, 0xc0, 0x37, 0x31, 0x1a, 0x05, 0x7f, 0x1e, 0x0e, 0x72, 0x73, 0x0f, 0x1f, 0x05, + 0x3c, 0x43, 0x89, 0x62, 0x1c, 0x10, 0xe2, 0xfc, 0xb2, 0xf4, 0xf2, 0xfb, 0xee, 0xfe, 0x52, 0xbe, + 0x6c, 0xc4, 0x88, 0x20, 0x87, 0xde, 0xb1, 0x13, 0x74, 0x3f, 0x57, 0xd1, 0xdd, 0x09, 0x75, 0x72, + 0x2b, 0xa2, 0x91, 0x2f, 0xa9, 0x12, 0x58, 0x14, 0x03, 0x21, 0x41, 0x94, 0xa2, 0x8c, 0x56, 0x5c, + 0x12, 0x03, 0x87, 0xb8, 0x0c, 0xb4, 0x03, 0x1c, 0x39, 0x28, 0x2a, 0xdf, 0xb4, 0x11, 0xff, 0x9e, + 0xe0, 0x80, 0x32, 0x14, 0x34, 0x40, 0x5f, 0x96, 0x22, 0xda, 0xbe, 0x49, 0x10, 0x94, 0xe5, 0x30, + 0x43, 0xe6, 0x5d, 0xff, 0xd5, 0x79, 0x70, 0xc0, 0x44, 0x29, 0x70, 0x7c, 0x44, 0xca, 0x61, 0x99, + 0xce, 0xa4, 0x59, 0x93, 0xca, 0x65, 0xe5, 0xbb, 0xb8, 0xac, 0xe9, 0xf0, 0x4b, 0x2f, 0x3f, 0x82, + 0xe5, 0xe5, 0xe5, 0xe2, 0xeb, 0xdf, 0x0a, 0x14, 0x5d, 0x3a, 0x6e, 0xf7, 0xbb, 0xc5, 0x73, 0xc1, + 0xda, 0x12, 0xe8, 0x5f, 0x7d, 0x15, 0xe1, 0x6e, 0xb1, 0x44, 0x73, 0x04, 0x84, 0x2c, 0x1f, 0x8a, + 0x0c, 0x94, 0x15, 0xe1, 0x01, 0x91, 0x71, 0x1c, 0xb9, 0xdc, 0x10, 0x70, 0xe7, 0x31, 0x58, 0xac, + 0xb6, 0x0c, 0x7c, 0xcb, 0x62, 0xb2, 0x80, 0x2d, 0xe1, 0x80, 0x31, 0x07, 0x88, 0x12, 0x14, 0x2a, + 0xab, 0x8a, 0xf7, 0x15, 0x8a, 0x03, 0x10, 0x00, 0xb0, 0x78, 0x00, 0x2c, 0x16, 0x00, 0x04, 0x64, + 0x80, 0xd4, 0x5b, 0x2c, 0x01, 0x9f, 0xd1, 0xc7, 0x89, 0x08, 0x05, 0x21, 0x55, 0x6c, 0xf0, 0x1f, + 0x59, 0x3f, 0xa4, 0x78, 0x00, 0xf2, 0xd9, 0xe0, 0x00, 0xf2, 0xc6, 0x5c, 0xcb, 0x6f, 0x3f, 0xcd, + 0xb8, 0xac, 0x43, 0xf1, 0x30, 0xa5, 0xf7, 0x77, 0x77, 0x49, 0x99, 0x63, 0x10, 0x34, 0x1f, 0x64, + 0x5b, 0x1e, 0xf3, 0x7f, 0x10, 0x2c, 0xa4, 0xf3, 0x63, 0xbb, 0x8a, 0xcf, 0x9e, 0x41, 0x85, 0xf7, + 0x15, 0xf9, 0x45, 0xb7, 0x07, 0x4f, 0xf8, 0x94, 0x34, 0x89, 0x5d, 0x10, 0x76, 0x88, 0xe8, 0xfa, + 0x93, 0xa2, 0x54, 0x39, 0xd5, 0xfe, 0xfb, 0xba, 0x88, 0x8a, 0x09, 0x03, 0x7d, 0x0e, 0x06, 0x8e, + 0x60, 0xf0, 0x70, 0x49, 0xf1, 0x83, 0xab, 0xce, 0x26, 0x30, 0x85, 0x83, 0x3d, 0x89, 0x6c, 0x5c, + 0x0a, 0xac, 0x0b, 0x80, 0x01, 0x08, 0xb8, 0x98, 0x00, 0x02, 0x85, 0xf2, 0x41, 0x30, 0x03, 0xc4, + 0x6a, 0x2e, 0x07, 0x86, 0xc7, 0x00, 0x25, 0xe2, 0x4f, 0x07, 0xd1, 0xac, 0x1a, 0xaa, 0x6c, 0x1a, + 0x50, 0x50, 0x91, 0x81, 0x9d, 0x4d, 0xfe, 0x33, 0x79, 0xa5, 0xbb, 0x0c, 0x48, 0x80, 0xa4, 0x28, + 0x00, 0x05, 0x3d, 0xa4, 0x0f, 0xc9, 0x7c, 0xaa, 0x30, 0x7a, 0x66, 0x50, 0x1e, 0x0e, 0x79, 0x60, + 0x34, 0x82, 0xb0, 0xb0, 0x1a, 0x60, 0xcd, 0x48, 0xde, 0x6e, 0x91, 0xe1, 0xe7, 0xe8, 0x33, 0x0e, + 0x1d, 0xe3, 0xc7, 0x4d, 0xf7, 0x08, 0xc0, 0x54, 0x6f, 0x3d, 0xf7, 0x71, 0x01, 0x10, 0x81, 0x6c, + 0xde, 0xac, 0xf3, 0x2a, 0xf7, 0xf1, 0x03, 0xea, 0xb5, 0xbb, 0x53, 0x0c, 0x10, 0x06, 0x8f, 0xe1, + 0x3f, 0xdb, 0x80, 0x0e, 0x2e, 0x49, 0x10, 0x18, 0xb2, 0xfc, 0x59, 0xc3, 0x78, 0xcb, 0xde, 0x5b, + 0x15, 0xbb, 0x9a, 0x06, 0x52, 0xf0, 0x7b, 0xa7, 0xcb, 0xa5, 0xf8, 0x96, 0x52, 0xdb, 0xfe, 0x5b, + 0xbf, 0xe1, 0x03, 0x0a, 0xee, 0x7e, 0xf6, 0xef, 0x9f, 0xc6, 0x74, 0x15, 0x79, 0xfa, 0xd5, 0x75, + 0x6f, 0xab, 0x11, 0xbd, 0x11, 0x8a, 0xea, 0xc4, 0x4c, 0x4c, 0x82, 0x9c, 0x57, 0x7e, 0x20, 0x61, + 0x8b, 0x19, 0x6e, 0x7c, 0x18, 0xbf, 0x84, 0xac, 0xca, 0x2d, 0xa1, 0x55, 0x2c, 0x2f, 0x35, 0xec, + 0x56, 0x59, 0x3b, 0xaa, 0xac, 0x2f, 0xcf, 0x1c, 0xa6, 0xe5, 0xb8, 0x81, 0x9a, 0x2b, 0xd3, 0x09, + 0x58, 0x67, 0x1f, 0xe5, 0x8b, 0x8f, 0x00, 0x54, 0x50, 0x69, 0x85, 0xcf, 0x96, 0x32, 0x91, 0xd1, + 0xff, 0x43, 0x81, 0xb8, 0x8f, 0x11, 0x8d, 0xe2, 0xce, 0xab, 0x57, 0x87, 0xf5, 0xc7, 0xf8, 0x69, + 0x5b, 0x69, 0x13, 0x66, 0x16, 0x84, 0xd9, 0xdd, 0x9a, 0x3f, 0x8d, 0xb0, 0xe6, 0xa0, 0x3a, 0x0b, + 0x8c, 0x94, 0x9a, 0x64, 0xbc, 0x15, 0xce, 0x72, 0x66, 0xce, 0x31, 0x65, 0xc4, 0x3f, 0x45, 0xe9, + 0x94, 0x04, 0xcb, 0x72, 0x3e, 0x80, 0xce, 0xb5, 0x3a, 0x8b, 0xb3, 0xe5, 0x13, 0x9f, 0x57, 0xc4, + 0x16, 0xee, 0xee, 0xee, 0xfc, 0x40, 0xa1, 0x82, 0xf3, 0x71, 0x4d, 0x45, 0xd5, 0x7c, 0xa5, 0x0a, + 0xab, 0x93, 0x0e, 0x03, 0xf6, 0xa5, 0xe8, 0x22, 0x74, 0xbe, 0xae, 0x02, 0x7d, 0x52, 0x25, 0xd1, + 0x1e, 0x3f, 0x9a, 0x33, 0x82, 0xde, 0x58, 0x71, 0x01, 0x32, 0x55, 0x75, 0x5f, 0x82, 0xe2, 0x3f, + 0x75, 0xa7, 0x7b, 0xe2, 0xab, 0x1b, 0x52, 0x8c, 0x34, 0x9b, 0x9e, 0xf6, 0xbe, 0x22, 0x44, 0x89, + 0xa8, 0xf0, 0xaf, 0x94, 0xfe, 0x53, 0xea, 0xbe, 0x23, 0xf5, 0xc6, 0x08, 0xcb, 0x6e, 0xd0, 0xda, + 0xe4, 0xca, 0x96, 0xdf, 0x78, 0x4f, 0xf9, 0x4a, 0x07, 0xed, 0x72, 0x71, 0xc8, 0x95, 0x51, 0x5d, + 0x05, 0x52, 0xc3, 0xfd, 0x0f, 0x72, 0xb8, 0x23, 0x0f, 0x3d, 0xaf, 0xbf, 0xf0, 0x91, 0x2f, 0x5b, + 0x9f, 0xfe, 0x42, 0x65, 0xcf, 0x88, 0x3b, 0x8a, 0xda, 0xad, 0x7e, 0xaf, 0xf1, 0x62, 0x6b, 0x37, + 0xd3, 0x6f, 0x11, 0x16, 0x75, 0x55, 0xcc, 0xa1, 0x7f, 0x53, 0xd5, 0x88, 0x14, 0x30, 0x9e, 0xde, + 0xb3, 0x7f, 0x1e, 0x23, 0x2c, 0x77, 0x78, 0xa3, 0x77, 0x14, 0x71, 0x5f, 0x82, 0x83, 0x8d, 0xae, + 0x58, 0xc4, 0x39, 0x97, 0x2f, 0x0c, 0xf4, 0x37, 0x28, 0xfe, 0x09, 0x08, 0x2b, 0x78, 0xad, 0x87, + 0x10, 0x12, 0x26, 0x5c, 0x75, 0x16, 0x82, 0x9f, 0xfc, 0x49, 0xb7, 0x2d, 0x2f, 0xc7, 0xd6, 0xaa, + 0xa4, 0xde, 0x95, 0xf8, 0x91, 0xe6, 0xb7, 0xbb, 0xbb, 0x5e, 0x21, 0xfe, 0x10, 0xa8, 0xf2, 0x0a, + 0x5a, 0x63, 0x59, 0x79, 0x51, 0x0e, 0x2e, 0x3d, 0x7a, 0xe8, 0x4b, 0xdf, 0x14, 0x57, 0x7b, 0xad, + 0x2f, 0x12, 0x5a, 0xde, 0xe2, 0x62, 0x02, 0x0a, 0x5f, 0x53, 0xcd, 0x32, 0xbe, 0x2e, 0xee, 0xe2, + 0xbc, 0x56, 0x36, 0xa1, 0x4e, 0x82, 0x39, 0x42, 0x5c, 0x16, 0x0a, 0x7c, 0xb8, 0x8c, 0x9d, 0x5b, + 0x47, 0xbb, 0x78, 0x67, 0xc2, 0x97, 0x2e, 0x1c, 0xf2, 0xd8, 0xa3, 0x15, 0xb9, 0xbd, 0xbb, 0x9f, + 0x9f, 0x3f, 0xdf, 0x79, 0xcd, 0x71, 0x25, 0x77, 0x77, 0x77, 0xf1, 0x22, 0x06, 0x0c, 0x27, 0xe2, + 0x58, 0x3f, 0x83, 0x48, 0x3f, 0x03, 0xa2, 0xae, 0x31, 0x0f, 0x01, 0xcf, 0x07, 0xc1, 0x47, 0x1b, + 0xa5, 0x2c, 0x13, 0xe0, 0xe8, 0x78, 0xec, 0x76, 0x78, 0x52, 0x59, 0xb2, 0x3d, 0xdc, 0xc2, 0x06, + 0x38, 0x6c, 0x13, 0x84, 0xef, 0x26, 0x79, 0xb1, 0xcf, 0x82, 0x83, 0xd3, 0x57, 0xbd, 0xde, 0xa2, + 0x75, 0xd0, 0xbe, 0xac, 0x45, 0x44, 0x08, 0xe2, 0x04, 0x10, 0x41, 0x28, 0x5f, 0x5f, 0x10, 0x67, + 0xbb, 0xee, 0x96, 0x26, 0x2e, 0x2e, 0xb5, 0xd5, 0x7c, 0xa1, 0x5c, 0x77, 0xd8, 0x5f, 0xaa, 0x45, + 0xea, 0x9d, 0x2e, 0xb0, 0x4f, 0xd1, 0x30, 0xf1, 0x00, 0xb0, 0x54, 0xa4, 0x5b, 0x9b, 0x55, 0x59, + 0x31, 0x69, 0x43, 0xc2, 0x9b, 0xdd, 0xde, 0xee, 0xef, 0xbe, 0x97, 0x78, 0x83, 0x11, 0x37, 0x76, + 0xfc, 0x16, 0x17, 0x55, 0x5a, 0xad, 0x6a, 0xfe, 0x20, 0x59, 0xd5, 0x54, 0x98, 0xab, 0xaf, 0x12, + 0x0a, 0x08, 0xa2, 0xe2, 0xe2, 0x98, 0xba, 0x62, 0xe5, 0xe3, 0xb7, 0x13, 0x18, 0x40, 0x3e, 0xf7, + 0x7a, 0xd1, 0x21, 0x42, 0x25, 0x88, 0xbf, 0xd9, 0xee, 0x29, 0xf3, 0xe2, 0x63, 0xe2, 0x8c, 0xf7, + 0x1f, 0x15, 0x96, 0xfb, 0xbb, 0xf8, 0x8a, 0x83, 0xab, 0x6a, 0x15, 0x64, 0xd1, 0x0e, 0x17, 0xc4, + 0xf1, 0x3b, 0xf7, 0xf8, 0x47, 0xc4, 0x08, 0xf8, 0x2d, 0xb8, 0xaf, 0xe6, 0xce, 0xf8, 0xf2, 0x5b, + 0xb8, 0x87, 0x37, 0x71, 0x5b, 0xc7, 0x57, 0xca, 0x77, 0x68, 0xf6, 0x16, 0x18, 0xe8, 0x4f, 0x44, + 0x70, 0x58, 0x62, 0x61, 0x36, 0xed, 0xaa, 0xa7, 0x77, 0xc0, 0x6c, 0x3c, 0x45, 0xdf, 0xb7, 0xa3, + 0xf5, 0xaf, 0x98, 0x43, 0xdf, 0x89, 0x10, 0x38, 0x4b, 0xbb, 0xbd, 0x6b, 0x7b, 0xe1, 0x10, 0x88, + 0xe3, 0xac, 0xa9, 0x31, 0x44, 0x72, 0x2d, 0xfb, 0x7c, 0x40, 0xa1, 0x8b, 0x29, 0x06, 0x07, 0x14, + 0xe7, 0xc5, 0x7e, 0x26, 0x21, 0xc7, 0x2d, 0xb9, 0x6d, 0xdd, 0xf8, 0x91, 0x25, 0x1b, 0xc7, 0x5d, + 0xee, 0xc7, 0x89, 0x84, 0x0a, 0xda, 0xd4, 0xac, 0x46, 0xfd, 0xdf, 0x11, 0x7d, 0xdf, 0x13, 0xf8, + 0x48, 0xee, 0x5e, 0x9d, 0xbb, 0xbd, 0x62, 0x41, 0x21, 0x89, 0xeb, 0xf2, 0xff, 0xcd, 0xb5, 0x26, + 0x78, 0x40, 0xf4, 0x96, 0x8c, 0x97, 0xaa, 0xda, 0xf1, 0x04, 0xb4, 0xd4, 0xf4, 0xf2, 0x10, 0x9f, + 0xaf, 0x8f, 0x18, 0xe2, 0xb9, 0xf1, 0xef, 0xc7, 0x8e, 0xaf, 0xf2, 0x96, 0xee, 0xe1, 0xce, 0x84, + 0xf5, 0x62, 0x14, 0x6d, 0x3c, 0x40, 0x21, 0x34, 0xd9, 0xf7, 0x88, 0x65, 0x35, 0x12, 0xaf, 0x9b, + 0x2b, 0x5a, 0xfc, 0xa2, 0xaf, 0x7e, 0x23, 0xe2, 0x06, 0xaa, 0xaa, 0xb5, 0xb5, 0xe0, 0xa4, 0x44, + 0x5d, 0xb5, 0x7b, 0xdd, 0x36, 0xd3, 0xef, 0xaf, 0x78, 0x81, 0x65, 0xdb, 0x4d, 0xdd, 0xdf, 0x84, + 0x02, 0x07, 0x97, 0xac, 0x6f, 0x15, 0x8a, 0xdd, 0xdd, 0xf8, 0x90, 0x95, 0xde, 0xfb, 0xbf, 0x12, + 0x13, 0xee, 0xe9, 0x2a, 0x49, 0x71, 0x2e, 0xee, 0xee, 0xe2, 0x04, 0x57, 0xfb, 0x23, 0xdf, 0x88, + 0x84, 0x8e, 0xef, 0xb4, 0x97, 0x89, 0x13, 0xc4, 0xc6, 0x6d, 0x39, 0xf1, 0x83, 0x66, 0xdc, 0x89, + 0xae, 0x3b, 0xa5, 0x99, 0x75, 0xe2, 0x04, 0x91, 0x9a, 0x06, 0x7b, 0xa7, 0xd5, 0x7c, 0x78, 0xa8, + 0xaf, 0x15, 0xc5, 0x62, 0x1c, 0x88, 0x7b, 0xfe, 0x08, 0xee, 0xf7, 0xa8, 0x67, 0xa1, 0xf1, 0x5f, + 0x58, 0xbc, 0x4a, 0x11, 0x8a, 0xb1, 0x15, 0xc2, 0x02, 0x13, 0x15, 0xb8, 0x85, 0x88, 0x87, 0xc5, + 0x6f, 0x7f, 0x94, 0x69, 0x3c, 0x72, 0x4f, 0xd5, 0x1d, 0xf1, 0x23, 0x89, 0x4c, 0xfe, 0x5d, 0xef, + 0x5a, 0xa8, 0x88, 0x21, 0xae, 0xac, 0xf1, 0x23, 0x8b, 0x77, 0x7b, 0xbb, 0x8a, 0xc5, 0x62, 0xb1, + 0x5a, 0xc4, 0x09, 0x2b, 0xbb, 0xdf, 0x7f, 0x04, 0xe2, 0x35, 0x55, 0x55, 0x5e, 0xbc, 0x45, 0xf0, + 0x42, 0x7b, 0xdd, 0xfc, 0x48, 0xa2, 0x34, 0xfa, 0xeb, 0xe1, 0x01, 0x38, 0xe2, 0x12, 0xcf, 0x77, + 0x48, 0xb2, 0xc2, 0xe2, 0x04, 0x10, 0x8d, 0x52, 0x4b, 0x11, 0xf8, 0x21, 0xad, 0x7a, 0xf8, 0x22, + 0x14, 0xf7, 0x8b, 0x13, 0xe0, 0x8e, 0xf1, 0x5b, 0x75, 0x3f, 0x42, 0x72, 0x85, 0x78, 0x29, 0x32, + 0xba, 0x6e, 0xed, 0xe9, 0xc9, 0xe3, 0x37, 0x88, 0xf8, 0x4c, 0xf4, 0x6b, 0x55, 0xa5, 0xe0, 0xba, + 0xf3, 0x62, 0xd5, 0x5d, 0xde, 0x20, 0x20, 0x29, 0xdd, 0xcf, 0xd3, 0xb7, 0x2d, 0xbb, 0xed, 0xf1, + 0x22, 0x47, 0xc9, 0x14, 0xac, 0x6b, 0x5f, 0x08, 0x0b, 0x33, 0xef, 0x77, 0xe2, 0x04, 0x82, 0xa2, + 0x91, 0x47, 0x97, 0xdc, 0x1f, 0xf5, 0xd6, 0xfe, 0x24, 0x71, 0x18, 0xf5, 0xa7, 0x2f, 0x6e, 0xde, + 0xfc, 0x4c, 0x75, 0xdd, 0xcf, 0xdd, 0xee, 0xed, 0xcb, 0xac, 0x42, 0x3b, 0xd7, 0x21, 0x95, 0x6b, + 0x89, 0xd6, 0x22, 0xb1, 0x15, 0xc9, 0xab, 0xf8, 0x8a, 0xe4, 0x3e, 0xe2, 0xb7, 0xc1, 0x70, 0xc7, + 0x7d, 0xc2, 0xce, 0x5b, 0x35, 0xf2, 0x97, 0xba, 0x89, 0xee, 0xf7, 0x97, 0xaf, 0x49, 0xd7, 0xa2, + 0x38, 0x5f, 0x17, 0xa9, 0xfb, 0x38, 0x9c, 0x30, 0x0e, 0x4c, 0xb0, 0x83, 0x5f, 0x5f, 0x7d, 0x9d, + 0x56, 0xab, 0x10, 0x3c, 0x62, 0xcf, 0x77, 0xaa, 0xcf, 0xb8, 0x88, 0xa1, 0x2a, 0xb2, 0x65, 0xef, + 0xc4, 0x92, 0xda, 0x74, 0xfc, 0x11, 0xde, 0xee, 0x8e, 0xf1, 0x3f, 0xaa, 0x3b, 0xf0, 0x58, 0x57, + 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x71, 0xf1, 0x3c, 0x40, 0x8f, 0x89, 0xb6, 0xb5, 0xbb, 0xba, + 0xc4, 0x57, 0xfb, 0xd2, 0xa5, 0xee, 0xba, 0xf8, 0x99, 0x04, 0x04, 0x58, 0x19, 0x04, 0x2d, 0x15, + 0x5a, 0xb5, 0xc5, 0xc4, 0xb2, 0xa5, 0xa4, 0xcd, 0x9f, 0x13, 0x27, 0x09, 0x8c, 0x77, 0xbb, 0xdd, + 0xcd, 0xd0, 0x97, 0xfa, 0xbd, 0xf5, 0xcc, 0x7d, 0x5e, 0xba, 0xbc, 0xfd, 0x5e, 0x6e, 0x89, 0x7f, + 0x82, 0x22, 0xbb, 0xde, 0xbe, 0xce, 0xdb, 0x6e, 0xbc, 0x47, 0xfc, 0x4f, 0x88, 0x12, 0x33, 0x55, + 0x55, 0x5f, 0x90, 0x4d, 0xef, 0x89, 0x08, 0x04, 0x4a, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe2, 0xbc, + 0x44, 0x16, 0xdd, 0xdd, 0xde, 0xee, 0xde, 0x20, 0x12, 0x12, 0xeb, 0xef, 0x11, 0xc4, 0x78, 0x99, + 0x6f, 0x76, 0x3e, 0x23, 0xf5, 0xd9, 0x1d, 0xef, 0xe2, 0x4f, 0xa4, 0xf4, 0x9a, 0x60, 0xf8, 0x90, + 0x97, 0x8a, 0xed, 0x2a, 0xf8, 0x4a, 0xd5, 0x2a, 0xd5, 0x4d, 0xca, 0x57, 0x94, 0x82, 0xef, 0x85, + 0x87, 0x1f, 0xdf, 0x76, 0x9c, 0x64, 0x14, 0x73, 0xd0, 0x72, 0x57, 0x86, 0x31, 0x00, 0xae, 0xaa, + 0xab, 0x34, 0xa1, 0x46, 0xe0, 0x97, 0xff, 0x7c, 0x21, 0x77, 0x77, 0x77, 0x15, 0xbb, 0x6b, 0xfb, + 0x2d, 0xef, 0xe5, 0x12, 0xab, 0xfd, 0x7e, 0x24, 0x4f, 0xc4, 0x88, 0xbd, 0xd3, 0xd7, 0x88, 0x04, + 0x45, 0x73, 0xf7, 0xdf, 0x88, 0x12, 0x6b, 0xbb, 0xbf, 0x8e, 0xdb, 0xb6, 0x46, 0x6c, 0x7c, 0xec, + 0x56, 0x5b, 0xe2, 0x04, 0xff, 0x89, 0xfd, 0xd6, 0xab, 0xc4, 0x96, 0xaa, 0xab, 0xfe, 0x24, 0xd8, + 0xcf, 0xae, 0xcc, 0x4c, 0x49, 0x6a, 0x46, 0x78, 0xf3, 0xe2, 0x3c, 0x4f, 0xc2, 0x7e, 0x2e, 0xab, + 0x47, 0xc4, 0xd6, 0x22, 0xb1, 0x17, 0xc8, 0x31, 0xcc, 0xc3, 0xd7, 0xe0, 0x8e, 0x48, 0x5b, 0x59, + 0x45, 0x74, 0x76, 0x44, 0x75, 0x75, 0x75, 0x72, 0xb8, 0x27, 0x11, 0xc1, 0xaa, 0x53, 0x24, 0x4c, + 0x56, 0x09, 0x3e, 0x2d, 0x78, 0x87, 0x0a, 0x0e, 0x59, 0x3a, 0xbf, 0x8e, 0xbb, 0xbf, 0x75, 0x77, + 0x7f, 0x82, 0x22, 0x9b, 0xe6, 0xef, 0xf2, 0x97, 0x0d, 0xda, 0xca, 0x9f, 0x65, 0xad, 0x70, 0x80, + 0x80, 0x46, 0x4a, 0xd6, 0xb8, 0x89, 0x2a, 0xaa, 0x2f, 0xc4, 0x89, 0x23, 0xde, 0xef, 0xe2, 0x65, + 0xd5, 0x57, 0x10, 0x20, 0x11, 0x95, 0x6a, 0xac, 0x71, 0x02, 0x4b, 0x43, 0x43, 0x52, 0x31, 0x89, + 0x92, 0xee, 0xff, 0x77, 0x7b, 0xe2, 0x66, 0xae, 0x8b, 0xeb, 0x10, 0x12, 0x2d, 0x12, 0xee, 0x83, + 0x6b, 0xc9, 0x5d, 0x78, 0x9b, 0xc4, 0x56, 0x23, 0xfe, 0x27, 0xc4, 0x71, 0x02, 0x38, 0x99, 0x35, + 0xaf, 0x82, 0x61, 0x4e, 0xae, 0xdd, 0xee, 0x40, 0x44, 0xf4, 0x76, 0x23, 0x78, 0x29, 0x11, 0x37, + 0x2c, 0x49, 0xf7, 0x0e, 0xff, 0x9b, 0xe1, 0xcf, 0x75, 0xe2, 0x19, 0x57, 0x5f, 0x2d, 0xdd, 0xeb, + 0x84, 0x08, 0xb9, 0x58, 0xc2, 0x81, 0x85, 0x35, 0xa1, 0xc1, 0xdb, 0x93, 0xd0, 0x56, 0x7c, 0x47, + 0xd0, 0xd7, 0xaf, 0x5d, 0x6b, 0x89, 0xbd, 0x55, 0x54, 0x48, 0x8e, 0x20, 0x49, 0xb2, 0xbd, 0x37, + 0x29, 0xc4, 0x5d, 0xdf, 0x78, 0x9a, 0xc4, 0x5e, 0x23, 0xc4, 0xd7, 0x35, 0x6a, 0xbc, 0x4d, 0xf3, + 0x69, 0x23, 0x69, 0x70, 0x44, 0x67, 0xcb, 0x11, 0x70, 0xfa, 0xd4, 0x29, 0xc2, 0x26, 0x9a, 0x0a, + 0xb0, 0xc3, 0xe3, 0x37, 0x56, 0xd9, 0xb7, 0xe2, 0x4b, 0x16, 0xf7, 0xaf, 0x10, 0x5a, 0xd5, 0x7c, + 0xa5, 0x7b, 0xfd, 0x72, 0xf8, 0x44, 0x54, 0xc9, 0xf5, 0x51, 0x79, 0x93, 0xfc, 0xa3, 0xde, 0x36, + 0xb2, 0xbb, 0xd5, 0x6b, 0x11, 0xe2, 0x3c, 0x47, 0xd9, 0x1f, 0x7e, 0x24, 0xa5, 0x5a, 0xf8, 0x87, + 0x41, 0xbd, 0x8d, 0x62, 0x41, 0x71, 0x48, 0xca, 0x6d, 0xcf, 0xd0, 0x9e, 0xfe, 0x21, 0x52, 0xae, + 0x23, 0xc4, 0x93, 0x7b, 0xf1, 0x17, 0x88, 0xe2, 0x35, 0x88, 0x9f, 0x82, 0xa1, 0x95, 0x73, 0x7c, + 0xd0, 0x8b, 0xcd, 0xc6, 0x3a, 0xa1, 0x4e, 0x24, 0x92, 0xf5, 0x11, 0xe6, 0xec, 0x90, 0x1d, 0x95, + 0x2f, 0xc6, 0x15, 0xdf, 0x77, 0x15, 0x9d, 0x8b, 0xdd, 0xef, 0xe2, 0x38, 0x8f, 0xcd, 0x89, 0xc0, + 0x3f, 0xae, 0x1d, 0x0e, 0x20, 0x4c, 0x34, 0x8c, 0xf7, 0x0c, 0x57, 0x3d, 0x1d, 0x6e, 0xd5, 0xff, + 0x94, 0xf5, 0x5f, 0x96, 0xaa, 0xaa, 0xff, 0x89, 0x31, 0x55, 0x55, 0x7f, 0xc4, 0xfc, 0xd7, 0xbb, + 0xf1, 0x26, 0x22, 0x1a, 0x1a, 0x1a, 0x1f, 0x84, 0xaa, 0xaa, 0xb2, 0xb3, 0x2b, 0x3c, 0x44, 0xd8, + 0x8b, 0xc4, 0x18, 0xca, 0xaa, 0xbc, 0x4d, 0xf1, 0x67, 0x77, 0x77, 0x77, 0x77, 0xf2, 0x5d, 0xdd, + 0xf8, 0x8a, 0xe8, 0x98, 0x78, 0x82, 0xc3, 0x63, 0x51, 0xc7, 0x5d, 0x0b, 0xd4, 0x9c, 0xc6, 0x55, + 0x55, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x08, 0x04, 0x30, 0x7a, 0x05, 0xbc, 0xe3, 0xd7, + 0xdb, 0x6d, 0x34, 0xc6, 0x74, 0x39, 0xe3, 0xfa, 0x1b, 0x55, 0xd5, 0xc8, 0x21, 0xea, 0xdf, 0x58, + 0xa1, 0x7e, 0xb9, 0x47, 0x72, 0xd5, 0x55, 0x46, 0xf5, 0xea, 0xeb, 0x84, 0x9d, 0x11, 0xfe, 0x8a, + 0xf0, 0x97, 0x47, 0x3d, 0xc3, 0x01, 0x80, 0x48, 0x3a, 0x27, 0x82, 0x7c, 0x9c, 0x00, 0x08, 0x29, + 0x19, 0xdf, 0x87, 0xc8, 0xaa, 0xaa, 0x79, 0xc2, 0xcc, 0xac, 0x0b, 0x0a, 0x71, 0x15, 0x9c, 0x3c, + 0x3e, 0x00, 0xd4, 0x30, 0x00, 0x25, 0x81, 0xe1, 0x80, 0x0d, 0x04, 0xd3, 0x07, 0x0c, 0xe5, 0xdb, + 0x6d, 0x8a, 0xb1, 0x57, 0x0e, 0x28, 0x04, 0xf8, 0x80, 0xa0, 0x78, 0xf7, 0xe9, 0xa6, 0x2d, 0x8a, + 0x5e, 0xd8, 0x9e, 0xbb, 0x4e, 0x1d, 0x39, 0xdd, 0x33, 0x4e, 0x4d, 0x16, 0xfb, 0x70, 0xe6, 0x00, + 0x1a, 0xaa, 0xf3, 0x82, 0xa5, 0x38, 0x35, 0xfb, 0xfd, 0x22, 0x69, 0x76, 0x7f, 0x52, 0x2e, 0x8f, + 0xfb, 0x78, 0x60, 0xc6, 0x86, 0x73, 0xe0, 0xe7, 0xe5, 0xf8, 0xab, 0x37, 0xc0, 0x82, 0x24, 0x11, + 0x8f, 0xdd, 0xc1, 0x0a, 0x49, 0xd4, 0xa8, 0xe8, 0x91, 0x22, 0x41, 0x40, 0x85, 0xad, 0x2b, 0x8e, + 0xb6, 0x1f, 0xf0, 0xc8, 0x90, 0x50, 0x21, 0x63, 0xb4, 0x85, 0x66, 0x23, 0x7c, 0x2f, 0xc3, 0x22, + 0x45, 0x13, 0x8d, 0x79, 0x47, 0xd4, 0x8a, 0x78, 0x64, 0x22, 0x58, 0xad, 0xfc, 0x22, 0x11, 0x2d, + 0xcf, 0xc3, 0x20, 0xfd, 0x82, 0x58, 0x42, 0x82, 0x35, 0xc3, 0x10, 0xb9, 0x84, 0x9e, 0x56, 0x02, + 0xc8, 0x53, 0x0f, 0x2d, 0x53, 0x38, 0x79, 0x79, 0xc0, 0x0f, 0x02, 0x42, 0x50, 0x70, 0x58, 0x8a, + 0x73, 0x78, 0xae, 0xf0, 0xf4, 0x40, 0x02, 0xec, 0x78, 0xff, 0xa4, 0x02, 0x66, 0x03, 0xd7, 0xe5, + 0x1d, 0x4d, 0xbc, 0x7d, 0xc7, 0xdf, 0x2e, 0xc4, 0x3c, 0xff, 0x28, 0xcb, 0x59, 0x6b, 0x28, 0x3a, + 0xa5, 0x46, 0x5a, 0xcb, 0x16, 0x1a, 0x6e, 0x0c, 0x6d, 0x72, 0xd6, 0x2a, 0xf1, 0x6c, 0x5b, 0x87, + 0xb0, 0x01, 0x9a, 0xd1, 0xe8, 0x1b, 0x0b, 0xef, 0xd9, 0xf6, 0xdb, 0xb7, 0x97, 0xae, 0xe6, 0xfe, + 0x2d, 0x8b, 0x60, 0x63, 0xb0, 0xda, 0xed, 0xb7, 0xf0, 0xe2, 0x28, 0x00, 0x56, 0x31, 0x77, 0x2a, + 0x6b, 0x38, 0xbd, 0x7c, 0x0e, 0xdd, 0xf5, 0x6c, 0xb5, 0x8f, 0xf8, 0xff, 0x8e, 0x2b, 0xbe, 0xba, + 0x69, 0xa9, 0x7c, 0xdc, 0x25, 0x38, 0x54, 0xe0, 0xff, 0xd3, 0x83, 0xb7, 0xf0, 0x3c, 0x80, 0x90, + 0x0a, 0x18, 0x94, 0x05, 0x5b, 0x81, 0x60, 0x6d, 0xa8, 0x74, 0x3b, 0x7b, 0x68, 0xe5, 0x80, 0x65, + 0x80, 0x63, 0xec, 0x2e, 0x8c, 0xe1, 0x2b, 0xa2, 0xc2, 0x2e, 0xa3, 0xf8, 0x44, 0xa2, 0x46, 0xd7, + 0x18, 0x01, 0x38, 0x0f, 0xca, 0xd4, 0xb8, 0x90, 0x48, 0x5d, 0xcd, 0x4e, 0xe2, 0x60, 0xa0, 0xda, + 0x97, 0x23, 0xfa, 0x39, 0x6f, 0xbe, 0x41, 0x19, 0xae, 0x22, 0x23, 0x1e, 0xaa, 0xb5, 0xf0, 0x89, + 0xd4, 0x94, 0xd1, 0xeb, 0xa8, 0x93, 0x98, 0x89, 0x04, 0x17, 0x05, 0x6d, 0x70, 0x80, 0x60, 0x10, + 0x85, 0xcb, 0x6f, 0xa3, 0x8c, 0x21, 0xd7, 0xc0, 0x2c, 0x1c, 0x44, 0x00, 0x21, 0x0a, 0xb9, 0xeb, + 0x5e, 0xf6, 0xdd, 0xff, 0xe9, 0xce, 0x9f, 0x5f, 0xad, 0x8a, 0xb5, 0x35, 0x38, 0xcf, 0xe1, 0xc4, + 0x20, 0x01, 0xe9, 0x07, 0xae, 0xa4, 0x51, 0xd4, 0xf1, 0x16, 0xb1, 0x57, 0x83, 0xb7, 0x1d, 0xb8, + 0x3b, 0x77, 0x7f, 0xf1, 0x19, 0x95, 0x76, 0xef, 0x76, 0xa7, 0x0f, 0x4c, 0x00, 0x4c, 0xd2, 0x87, + 0xe1, 0xa9, 0x1c, 0x0a, 0x22, 0x25, 0x5c, 0x3a, 0xbb, 0xbb, 0xbb, 0x34, 0x7d, 0xc7, 0x57, 0x1c, + 0x57, 0xd3, 0x4d, 0x5d, 0xf0, 0x4c, 0x07, 0x98, 0x6f, 0x5d, 0xb4, 0xd3, 0xf0, 0x16, 0x00, 0x84, + 0x6c, 0xe2, 0x44, 0x97, 0xa1, 0xe0, 0x00, 0x47, 0x8a, 0x23, 0x90, 0x2e, 0x21, 0x0f, 0x43, 0xb0, + 0x00, 0x10, 0x07, 0xcb, 0x0e, 0x03, 0x82, 0xc0, 0xaa, 0x38, 0x2d, 0xa7, 0x80, 0x0c, 0x00, 0xc0, + 0x04, 0xc0, 0x19, 0x00, 0xe2, 0x49, 0x4e, 0x74, 0x3b, 0x4a, 0x4a, 0x0a, 0x94, 0x45, 0x80, 0xc4, + 0xb8, 0x64, 0xc5, 0x6c, 0xdc, 0xde, 0x5e, 0x0f, 0xfa, 0x78, 0x18, 0x43, 0x01, 0x42, 0x87, 0xfa, + 0xaa, 0xc2, 0x21, 0x1f, 0x5a, 0x1d, 0x48, 0x28, 0x02, 0x41, 0xcd, 0x13, 0x9e, 0xab, 0x24, 0x95, + 0x12, 0x00, 0xa4, 0x2a, 0xd9, 0x97, 0x00, 0x01, 0x00, 0x2e, 0x98, 0x00, 0x0a, 0x0c, 0xbc, 0xee, + 0x05, 0x86, 0x05, 0xa1, 0xd5, 0x79, 0x16, 0x02, 0x44, 0x0c, 0x01, 0x43, 0x56, 0x04, 0x00, 0x3a, + 0x71, 0x13, 0x06, 0xb5, 0x4b, 0x4a, 0xf8, 0x00, 0xf7, 0x7f, 0xef, 0xdf, 0x84, 0xc0, 0x03, 0x91, + 0x41, 0xd4, 0x76, 0xc4, 0xc7, 0x41, 0x71, 0xa2, 0x80, 0x94, 0xcc, 0xe0, 0xa7, 0xe2, 0x6b, 0x98, + 0x26, 0x7f, 0x88, 0x7e, 0x24, 0x40, 0x27, 0x08, 0x3d, 0x51, 0x78, 0xbe, 0xfc, 0x44, 0x71, 0x2a, + 0xaa, 0xb5, 0x8b, 0xfc, 0x44, 0xc2, 0xdd, 0xdd, 0xfc, 0x12, 0x6a, 0x62, 0x0a, 0x32, 0x9c, 0x45, + 0xf2, 0x0a, 0x10, 0xe1, 0xee, 0x1f, 0x3c, 0x22, 0x21, 0x05, 0x7a, 0x23, 0x92, 0xee, 0xee, 0xba, + 0xd7, 0xd6, 0x28, 0x6a, 0x19, 0xac, 0xb8, 0x09, 0x90, 0x82, 0xb6, 0x18, 0x50, 0xd1, 0x3c, 0xbf, + 0xfb, 0x6d, 0xe2, 0xac, 0x55, 0x8e, 0xc7, 0xe3, 0x95, 0x62, 0xc3, 0x0a, 0x06, 0xdd, 0x12, 0xf6, + 0xdb, 0xff, 0xe2, 0xc3, 0x88, 0x70, 0x01, 0xe0, 0x50, 0x83, 0xd6, 0xb9, 0x27, 0x24, 0x7b, 0x85, + 0x66, 0xef, 0x6c, 0x71, 0x2e, 0x55, 0x5c, 0x3a, 0xb8, 0xe0, 0xb7, 0xf8, 0x3b, 0x7c, 0x02, 0x04, + 0x0f, 0xd4, 0xdf, 0x97, 0xf8, 0x12, 0x00, 0x44, 0x05, 0x24, 0x80, 0x37, 0x35, 0x31, 0x35, 0x13, + 0x3a, 0x3c, 0xdd, 0x0f, 0x0b, 0x3a, 0x02, 0xe1, 0x7e, 0x61, 0x06, 0xb2, 0x78, 0x1d, 0xca, 0x45, + 0x94, 0xc8, 0x78, 0x1f, 0x9a, 0x13, 0x03, 0xec, 0xe4, 0xea, 0x78, 0x00, 0x11, 0x83, 0xad, 0xc2, + 0xb0, 0x6a, 0x9f, 0x84, 0x00, 0x44, 0x05, 0x3a, 0x50, 0xe3, 0xc6, 0x7d, 0x41, 0x78, 0x91, 0x88, + 0x22, 0x21, 0xc2, 0x5e, 0x08, 0x0b, 0x91, 0x72, 0x25, 0xb2, 0x97, 0x70, 0x00, 0x08, 0x00, 0x82, + 0x88, 0x00, 0x56, 0x96, 0x2c, 0x81, 0x3c, 0x00, 0x67, 0x80, 0x01, 0x15, 0x0f, 0x9c, 0x4a, 0x20, + 0x43, 0x9c, 0x0b, 0x11, 0xd4, 0xa2, 0x96, 0x82, 0x8e, 0x20, 0x82, 0xd3, 0x82, 0x10, 0x4c, 0x55, + 0xf4, 0xcb, 0x4f, 0xd7, 0x00, 0x08, 0x55, 0x35, 0xc0, 0x00, 0x44, 0x05, 0x52, 0xfa, 0xf1, 0x22, + 0xbc, 0x8f, 0xb7, 0x37, 0xf1, 0x02, 0xb5, 0x55, 0x5f, 0x12, 0x20, 0xc1, 0x1b, 0xbb, 0xfa, 0xff, + 0x88, 0x8e, 0x08, 0x72, 0xf1, 0x0f, 0x27, 0x55, 0xf9, 0xcf, 0x9e, 0x20, 0x45, 0x74, 0x19, 0x22, + 0x32, 0x04, 0x9d, 0x10, 0xb6, 0x39, 0x4d, 0x87, 0x4c, 0x42, 0x82, 0x46, 0x29, 0xe6, 0x8c, 0x24, + 0x1a, 0xa6, 0x5d, 0x8e, 0x50, 0x32, 0x9a, 0x03, 0x8d, 0x86, 0x14, 0x0f, 0xe6, 0xbf, 0xfa, 0x69, + 0xe9, 0xa6, 0x74, 0xc3, 0xd1, 0x80, 0x01, 0x65, 0xe9, 0xb0, 0xb2, 0xa9, 0xd5, 0x69, 0xf2, 0xff, + 0xfc, 0xfd, 0x80, 0x77, 0x3b, 0xf9, 0x51, 0xf8, 0xf0, 0x68, 0x54, 0x52, 0x9c, 0xc1, 0xed, 0xdf, + 0x03, 0xff, 0x57, 0x0f, 0xec, 0x0a, 0xbe, 0x27, 0xe2, 0x4f, 0x3d, 0x02, 0x8f, 0x4e, 0x1f, 0x0b, + 0xb3, 0x00, 0x2b, 0x31, 0xf2, 0x20, 0x77, 0xcf, 0x8a, 0x49, 0xe6, 0x5f, 0x46, 0xc4, 0xf5, 0x8a, + 0xf6, 0xa7, 0x19, 0x29, 0xd1, 0x46, 0x09, 0xc6, 0x95, 0x9e, 0x0b, 0x15, 0x96, 0x1a, 0x8c, 0x0a, + 0x06, 0x77, 0xb6, 0x1b, 0x65, 0x00, 0x5c, 0x85, 0xa5, 0x41, 0x5b, 0xd4, 0xf4, 0xbc, 0xfe, 0x5b, + 0x4d, 0x20, 0x2a, 0xbf, 0xb8, 0x02, 0xb3, 0x16, 0x8d, 0x65, 0xf8, 0xae, 0x36, 0xb7, 0xad, 0x78, + 0x81, 0x35, 0x12, 0x10, 0xf1, 0x02, 0xcb, 0xbb, 0xbb, 0xdd, 0x70, 0x88, 0xaa, 0xaa, 0xa8, 0x9e, + 0x09, 0x0c, 0x19, 0x8c, 0xcf, 0x82, 0x5e, 0x82, 0xae, 0x5e, 0x27, 0xc4, 0x58, 0x51, 0x4a, 0x6f, + 0xf6, 0xff, 0xf1, 0xca, 0xe3, 0xb6, 0x1c, 0x44, 0x00, 0x0c, 0x5e, 0xb2, 0x39, 0xe1, 0x3f, 0xef, + 0x9e, 0x1f, 0x13, 0xff, 0x13, 0x84, 0x4e, 0x02, 0x5c, 0x45, 0x62, 0x70, 0x89, 0xc2, 0x21, 0x84, + 0x43, 0x08, 0x5d, 0x8e, 0x00, 0x63, 0xcc, 0x80, 0x8a, 0x97, 0x5e, 0xff, 0xa5, 0x66, 0xa8, 0x3c, + 0xa7, 0x60, 0xcf, 0x3b, 0xcb, 0xd4, 0xe3, 0x09, 0x2c, 0x3f, 0x61, 0xb2, 0x40, 0xea, 0x22, 0x44, + 0x03, 0x1d, 0x48, 0x12, 0x8b, 0xfd, 0x7b, 0x2d, 0x36, 0x44, 0xf0, 0xf5, 0x18, 0x2a, 0x9d, 0xc5, + 0x18, 0x1a, 0xc1, 0xac, 0xfd, 0x3a, 0xf5, 0xac, 0x9c, 0xc5, 0xd4, 0x48, 0x61, 0xe1, 0x23, 0x4f, + 0x98, 0xb9, 0x35, 0x9f, 0xc2, 0x1f, 0x08, 0x43, 0x7d, 0x05, 0xda, 0x3f, 0xa9, 0x52, 0x83, 0x88, + 0xc0, 0x06, 0xa4, 0xd9, 0x23, 0x68, 0x77, 0xe7, 0xff, 0xc5, 0x58, 0x96, 0xb4, 0xc2, 0x69, 0xba, + 0x83, 0xef, 0xf8, 0x21, 0x06, 0x00, 0xb0, 0x53, 0x86, 0x88, 0x95, 0x8d, 0x39, 0x33, 0x47, 0x3e, + 0x8a, 0xce, 0x70, 0x88, 0x0f, 0x4c, 0x85, 0xfc, 0x64, 0xa9, 0xb5, 0xc7, 0x0b, 0x2b, 0x38, 0x40, + 0x1c, 0x85, 0x3c, 0x19, 0x2d, 0x41, 0x3b, 0x0b, 0x25, 0xd8, 0x7c, 0x94, 0x54, 0x8f, 0xae, 0xe2, + 0x30, 0x43, 0x51, 0xfe, 0x26, 0x0d, 0x0a, 0x84, 0xb1, 0x03, 0xd3, 0x9d, 0x09, 0x17, 0x84, 0xa7, + 0x52, 0x38, 0xb0, 0x2a, 0x5d, 0xc2, 0x21, 0x00, 0xa1, 0x11, 0x2d, 0x00, 0x1d, 0x22, 0xaf, 0x0c, + 0xbc, 0x12, 0x70, 0x00, 0x27, 0x2a, 0x1a, 0x23, 0xa5, 0xb3, 0x0a, 0xf6, 0x42, 0x40, 0x05, 0xe1, + 0x83, 0x00, 0x5f, 0x0c, 0x05, 0x7e, 0x0f, 0xe9, 0x5b, 0x64, 0xee, 0x36, 0xe3, 0x96, 0xc8, 0x9e, + 0x20, 0x47, 0x3f, 0x82, 0x79, 0x9a, 0x86, 0xa7, 0x89, 0x97, 0x1e, 0xdc, 0x51, 0xbd, 0xfd, 0x9e, + 0xee, 0xfc, 0x40, 0x81, 0x1c, 0xb0, 0x10, 0xc1, 0x7e, 0x4f, 0x87, 0x88, 0xf8, 0x94, 0x19, 0xe9, + 0xba, 0x15, 0xd1, 0xd8, 0x10, 0x10, 0xd1, 0x12, 0x49, 0xfa, 0x23, 0x90, 0x8e, 0x20, 0x12, 0x13, + 0x6c, 0x57, 0x5c, 0x22, 0x18, 0x18, 0x2b, 0x27, 0x37, 0x13, 0xe7, 0x07, 0x37, 0xb9, 0xb2, 0x98, + 0xac, 0x51, 0xf8, 0x91, 0x01, 0x4d, 0x1d, 0xf6, 0x5b, 0x77, 0x77, 0x27, 0xa9, 0xda, 0xdf, 0x84, + 0x23, 0x32, 0xcc, 0x49, 0xbd, 0xf6, 0x1d, 0x96, 0xf1, 0x59, 0x3b, 0xf0, 0xfd, 0xbf, 0x89, 0xbf, + 0x77, 0xf4, 0x5f, 0xfd, 0x5b, 0xec, 0x62, 0xaa, 0xa8, 0x43, 0xa0, 0xaf, 0x7d, 0x15, 0xe1, 0x6e, + 0xb1, 0x44, 0x44, 0x88, 0x14, 0x12, 0xbd, 0xcb, 0xea, 0x89, 0x39, 0x89, 0x12, 0x30, 0x97, 0xae, + 0x2e, 0x2f, 0x17, 0x50, 0x7d, 0xa0, 0xdd, 0xe3, 0xf6, 0x05, 0xa9, 0xe3, 0x01, 0x02, 0x20, 0x1e, + 0xf6, 0x20, 0x48, 0xc3, 0x89, 0x72, 0xaa, 0xc4, 0x9c, 0x13, 0xc1, 0x73, 0xc0, 0xe1, 0x60, 0x6d, + 0xd3, 0xcf, 0x06, 0x24, 0x3a, 0x38, 0x36, 0x01, 0xaa, 0x96, 0x01, 0x8a, 0x06, 0x78, 0x01, 0xc2, + 0xc0, 0x3c, 0x44, 0x29, 0x2c, 0xf1, 0x43, 0x9b, 0xaa, 0xa8, 0x80, 0x3d, 0x4e, 0x0f, 0x95, 0x89, + 0xe5, 0xbc, 0x4f, 0x11, 0x08, 0xeb, 0x55, 0xaa, 0xd0, 0xdb, 0x1a, 0x95, 0xec, 0xf7, 0xbf, 0x10, + 0x41, 0x9a, 0xaf, 0x10, 0x51, 0x29, 0xc4, 0x7f, 0xd0, 0xf3, 0xa4, 0x57, 0x5d, 0x49, 0xd6, 0xa1, + 0xec, 0x42, 0x8c, 0xa7, 0xc1, 0x38, 0x49, 0x22, 0x50, 0x2b, 0x54, 0xaf, 0x66, 0x65, 0x08, 0x3c, + 0xfc, 0x44, 0x61, 0x0b, 0x0d, 0x90, 0x2f, 0x07, 0xdc, 0xb1, 0xb4, 0x59, 0x98, 0x00, 0x41, 0x8a, + 0x88, 0x80, 0x4f, 0x97, 0x40, 0x16, 0x02, 0x28, 0xce, 0x41, 0x4c, 0x8a, 0x0d, 0xa0, 0xe7, 0x09, + 0x86, 0xb5, 0x28, 0x2e, 0xb4, 0x38, 0x2d, 0x44, 0x4b, 0x0d, 0xe0, 0x18, 0x2f, 0x91, 0xa6, 0x20, + 0x48, 0xc8, 0xf1, 0x03, 0xc0, 0xc3, 0x9e, 0x00, 0xed, 0x72, 0x5a, 0x04, 0xd2, 0xcb, 0x60, 0x5f, + 0x3f, 0xe5, 0x81, 0x9f, 0xe5, 0x80, 0x67, 0xee, 0xc2, 0xd5, 0x05, 0x4a, 0xec, 0x2c, 0xcf, 0xf9, + 0xf1, 0x12, 0xc3, 0x17, 0x10, 0x1f, 0x25, 0xff, 0x89, 0x09, 0xdf, 0x77, 0x01, 0xf0, 0xd2, 0xe4, + 0x01, 0x02, 0x7f, 0x82, 0xd9, 0x68, 0x67, 0xfe, 0x0b, 0x0b, 0x9a, 0x87, 0x07, 0x93, 0xc1, 0xc7, + 0x2f, 0x6d, 0xe4, 0x76, 0xcb, 0x91, 0x77, 0x78, 0x8a, 0xe1, 0x02, 0x2d, 0x49, 0xea, 0xab, 0x93, + 0xc6, 0x74, 0x15, 0x79, 0xfa, 0xd5, 0x75, 0x6f, 0xab, 0x11, 0xfd, 0x58, 0x89, 0x88, 0x13, 0xf0, + 0x88, 0x50, 0x8c, 0xeb, 0xe3, 0x68, 0xa4, 0x40, 0x53, 0xf8, 0x15, 0x49, 0x60, 0xb3, 0xd1, 0x24, + 0xe2, 0xb7, 0x3e, 0x13, 0x63, 0x1a, 0x1b, 0x4b, 0x6c, 0x54, 0x4e, 0x50, 0xf2, 0xb3, 0x96, 0xf1, + 0xdc, 0x98, 0x21, 0x0a, 0x7f, 0x98, 0x10, 0xc8, 0x06, 0x5a, 0x1f, 0xab, 0x77, 0xa7, 0xb1, 0xe9, + 0xa8, 0xf3, 0x4c, 0xa7, 0xee, 0x92, 0xc4, 0x0c, 0xc3, 0x49, 0x37, 0x48, 0x37, 0x76, 0x25, 0x70, + 0xf9, 0xba, 0xb2, 0x86, 0x81, 0xea, 0x1a, 0xbd, 0x47, 0xdc, 0xb7, 0xad, 0x88, 0x84, 0x4a, 0x9b, + 0x0a, 0x76, 0xff, 0x08, 0x44, 0xb1, 0xd0, 0xdd, 0xdf, 0x38, 0x05, 0x14, 0x7a, 0xf0, 0x6a, 0xf4, + 0xc1, 0x29, 0xf9, 0x7b, 0xa5, 0x77, 0x27, 0x6a, 0xd1, 0xb1, 0xb6, 0xce, 0x27, 0x8b, 0xe5, 0x13, + 0xbb, 0xf1, 0x3f, 0x14, 0x21, 0xee, 0xf1, 0x5d, 0xf8, 0x82, 0x94, 0x5e, 0x15, 0x2c, 0x4b, 0xc4, + 0x74, 0x13, 0x70, 0x09, 0x31, 0x08, 0x55, 0x7c, 0x10, 0xd1, 0x45, 0x4b, 0xcb, 0xf0, 0x50, 0x45, + 0x55, 0x55, 0x17, 0x0b, 0x72, 0x1b, 0x13, 0xe5, 0x77, 0xc1, 0x21, 0x9e, 0xe2, 0xb6, 0xf1, 0x02, + 0x6a, 0xba, 0xaf, 0xe1, 0x23, 0xef, 0xcb, 0xbd, 0xf8, 0x98, 0x88, 0x15, 0x53, 0xc7, 0x30, 0x7d, + 0x27, 0x2d, 0xc5, 0x4d, 0x00, 0xcb, 0x16, 0xdf, 0x97, 0xc4, 0xa2, 0xbd, 0xe2, 0x07, 0x8c, 0xc9, + 0x98, 0x9e, 0x46, 0x96, 0x73, 0x7f, 0x88, 0x29, 0x41, 0xd5, 0x91, 0x1c, 0x13, 0xc1, 0x5d, 0x05, + 0x52, 0xc3, 0xfd, 0x0f, 0x73, 0xc4, 0x7d, 0x07, 0x9f, 0xe2, 0x2a, 0xa6, 0xa3, 0xa8, 0xb9, 0xf8, + 0x29, 0x20, 0xbf, 0xc3, 0x60, 0x68, 0xbb, 0x0a, 0x3c, 0x58, 0x5e, 0x7e, 0xff, 0x7c, 0x79, 0x09, + 0x55, 0x6e, 0x2a, 0xcc, 0xb6, 0x48, 0xa9, 0xe0, 0x98, 0x8a, 0x3e, 0x59, 0x39, 0xd1, 0x42, 0xf1, + 0xf8, 0x80, 0x81, 0xc1, 0xbf, 0xc5, 0x3e, 0x41, 0xdc, 0xd5, 0xf9, 0x79, 0xef, 0xb4, 0xd7, 0x11, + 0x58, 0x82, 0x0f, 0x7b, 0x2b, 0xc4, 0x98, 0x65, 0xef, 0xc4, 0x02, 0x71, 0x0b, 0x17, 0x58, 0x8e, + 0x7d, 0xc4, 0xca, 0x72, 0x78, 0xba, 0xe1, 0x1c, 0x31, 0xd0, 0xdc, 0xa3, 0xe2, 0x26, 0x36, 0xd8, + 0x57, 0x4e, 0x27, 0xff, 0x31, 0x1b, 0x26, 0xdb, 0xf0, 0x89, 0x2a, 0xaa, 0xeb, 0x5c, 0x94, 0x17, + 0xf1, 0x98, 0xd5, 0x2d, 0x67, 0x72, 0x2f, 0x9b, 0x20, 0xd9, 0xf4, 0x14, 0xcd, 0x17, 0x62, 0x0f, + 0x89, 0x21, 0xc9, 0x91, 0x7e, 0xaf, 0xe2, 0x45, 0x95, 0x55, 0x56, 0xab, 0xf3, 0x53, 0x44, 0xbf, + 0x2e, 0xb5, 0xe2, 0x2b, 0x10, 0x4a, 0xaa, 0xaf, 0x88, 0x1c, 0xab, 0xae, 0x4c, 0xf2, 0xea, 0xef, + 0xc4, 0x14, 0x2b, 0x8d, 0x7b, 0x04, 0xb1, 0x13, 0x0e, 0xaa, 0xae, 0x26, 0x10, 0xdd, 0xcf, 0x8f, + 0xbe, 0xa6, 0xff, 0x10, 0xe9, 0x5d, 0xde, 0x24, 0x60, 0x8d, 0xdc, 0x28, 0xa9, 0x63, 0x30, 0x01, + 0xd8, 0xe0, 0xf0, 0xd3, 0xce, 0x07, 0x5a, 0xc3, 0xbe, 0x05, 0x90, 0x58, 0x39, 0x05, 0x8d, 0xcf, + 0xc2, 0x93, 0xf0, 0x19, 0xa0, 0x7e, 0xd7, 0x5e, 0xda, 0x3c, 0x78, 0xc2, 0xfc, 0x9b, 0x9a, 0x5e, + 0x5c, 0xef, 0x12, 0x10, 0x3e, 0xff, 0x12, 0xc0, 0xb8, 0x54, 0x66, 0x63, 0x18, 0x75, 0x47, 0xeb, + 0xc4, 0x16, 0xf7, 0xf1, 0x1e, 0x21, 0x8b, 0x74, 0x73, 0x5e, 0x24, 0x48, 0x25, 0xd6, 0x89, 0xf7, + 0xef, 0x11, 0x51, 0x02, 0x2b, 0x90, 0x43, 0xa5, 0x6b, 0x13, 0xf8, 0xb2, 0x0a, 0xf7, 0xdd, 0xc3, + 0x3d, 0x05, 0x52, 0x21, 0x3d, 0x1b, 0x0f, 0x82, 0x71, 0x4a, 0x96, 0xf7, 0xf7, 0xc9, 0x77, 0xfc, + 0xc4, 0x7d, 0xd6, 0x25, 0x0b, 0x2d, 0xf3, 0x19, 0x49, 0x94, 0xf8, 0x80, 0x53, 0x0a, 0x0d, 0xc3, + 0xea, 0x2b, 0x93, 0xb8, 0x31, 0xff, 0x3f, 0x90, 0x6a, 0x14, 0x91, 0xab, 0xbe, 0x14, 0xd9, 0xfe, + 0xe7, 0xb8, 0xf7, 0x8a, 0xdb, 0x7d, 0x37, 0xf1, 0x21, 0x49, 0xc1, 0xc3, 0x33, 0x2e, 0x77, 0x0a, + 0x2d, 0x65, 0x74, 0xba, 0xf4, 0xdf, 0x3e, 0x7d, 0xf2, 0x1e, 0xaf, 0xf7, 0x77, 0xf8, 0x92, 0x6b, + 0x5c, 0x4c, 0x93, 0xc1, 0x94, 0xa6, 0x3c, 0x45, 0xfe, 0x10, 0xfd, 0x5f, 0xe2, 0x88, 0xc1, 0x86, + 0x81, 0x1f, 0xd5, 0x71, 0x30, 0x98, 0x87, 0x62, 0x93, 0x35, 0x36, 0x7e, 0x53, 0xbc, 0x56, 0x5c, + 0xe2, 0x21, 0x7e, 0x84, 0xf4, 0x46, 0x20, 0x11, 0x1a, 0x7b, 0xf0, 0x3b, 0xe2, 0x3c, 0x40, 0x22, + 0xea, 0xbd, 0x5c, 0x95, 0x5a, 0xf8, 0x44, 0xea, 0xbd, 0x5e, 0xb4, 0x8b, 0x9e, 0x3c, 0x62, 0xaa, + 0xae, 0xa2, 0xe2, 0xf4, 0xbc, 0x48, 0xf9, 0x3f, 0x29, 0xeb, 0x5a, 0xeb, 0xc4, 0x05, 0x0e, 0xf7, + 0x57, 0x78, 0xad, 0xdb, 0xb6, 0x46, 0x6f, 0x7e, 0xf1, 0x23, 0xab, 0x5e, 0xad, 0x6e, 0xf8, 0x91, + 0x3f, 0x28, 0x9d, 0x27, 0x51, 0x3b, 0xc4, 0x3b, 0xbb, 0xd7, 0x31, 0x25, 0xcb, 0xae, 0x08, 0x4a, + 0xbb, 0x43, 0xb7, 0x88, 0x29, 0x33, 0xc3, 0xc4, 0x88, 0x18, 0xf7, 0xa5, 0x77, 0xf1, 0x3d, 0xdd, + 0xf7, 0x0f, 0x74, 0x2e, 0x5e, 0x25, 0x91, 0x5d, 0xe5, 0xe6, 0x3d, 0x6b, 0xe0, 0x9c, 0x45, 0xde, + 0xed, 0xed, 0xf2, 0x55, 0x55, 0x78, 0x80, 0x4a, 0x59, 0xbd, 0x53, 0x74, 0xef, 0xf0, 0x4e, 0x24, + 0xfd, 0xfb, 0xdc, 0x7d, 0xf6, 0x47, 0x7b, 0xbc, 0x47, 0x88, 0x64, 0x55, 0xab, 0xe8, 0x9d, 0xe2, + 0x11, 0xfb, 0x89, 0xf1, 0x36, 0x25, 0x99, 0xae, 0x51, 0x9c, 0x40, 0x86, 0x4c, 0x94, 0x5f, 0x34, + 0x97, 0xb3, 0xf1, 0xe3, 0x1d, 0xdd, 0xdd, 0xcb, 0xcf, 0x7b, 0xbf, 0x2f, 0xe0, 0x8e, 0x25, 0xed, + 0xbf, 0x2c, 0x06, 0xa1, 0xce, 0x87, 0xc5, 0xe2, 0x05, 0x88, 0x77, 0xdd, 0xfe, 0x20, 0xbd, 0xdb, + 0x24, 0x47, 0xe4, 0x2d, 0x35, 0x4f, 0x88, 0x04, 0x84, 0x5a, 0xdf, 0xe0, 0x8e, 0xba, 0xf7, 0xcd, + 0x4e, 0x9b, 0xbc, 0x47, 0xfe, 0x8e, 0x54, 0xf9, 0x2e, 0xee, 0xf8, 0x81, 0x1e, 0x23, 0xfe, 0x25, + 0x5f, 0x88, 0x10, 0x89, 0xdc, 0x44, 0xa2, 0x76, 0x9a, 0xc4, 0x89, 0xe2, 0x60, 0x9e, 0xef, 0xb4, + 0xef, 0xef, 0xa2, 0x6b, 0xc4, 0x02, 0x21, 0x42, 0xe2, 0x38, 0x2f, 0xfe, 0x23, 0xa1, 0x3d, 0x0a, + 0xf1, 0x26, 0x12, 0xe4, 0x5e, 0xae, 0x9f, 0x89, 0x10, 0x57, 0x77, 0xbb, 0xeb, 0xbe, 0xaa, 0xb1, + 0x15, 0x89, 0x04, 0x45, 0x77, 0xd1, 0xdf, 0x82, 0xa8, 0xf2, 0x0e, 0x74, 0x3b, 0xa6, 0xf7, 0xef, + 0x82, 0x4b, 0xb7, 0xf7, 0xd9, 0x35, 0x5e, 0x21, 0x1d, 0xfc, 0x4f, 0xd9, 0x95, 0x77, 0x89, 0xf9, + 0x08, 0xfb, 0xf1, 0x25, 0x3b, 0xbd, 0xfd, 0x15, 0x8f, 0xf8, 0x9f, 0x8e, 0xe9, 0x9f, 0xcb, 0xdf, + 0x45, 0x67, 0x23, 0xe2, 0x04, 0x17, 0xaa, 0xff, 0x89, 0xf1, 0x00, 0x9c, 0x67, 0x3c, 0x14, 0xbe, + 0xbf, 0xf8, 0x23, 0x2a, 0xcf, 0x0c, 0xa1, 0xae, 0x17, 0xce, 0xcc, 0x1d, 0x98, 0x1a, 0xca, 0x35, + 0xd4, 0xf5, 0x89, 0x44, 0x06, 0x21, 0x11, 0xf2, 0x62, 0x3c, 0x49, 0x8d, 0x7b, 0xf9, 0x44, 0xbb, + 0xbb, 0xf8, 0xab, 0xbb, 0xbb, 0xbb, 0xbe, 0x26, 0x52, 0xbd, 0xfc, 0x4a, 0xbf, 0xcd, 0x63, 0x43, + 0x3b, 0x10, 0x7c, 0x42, 0xbf, 0xcb, 0x4e, 0xd7, 0xe5, 0xe6, 0x36, 0x6b, 0x9b, 0xde, 0x23, 0xe1, + 0x83, 0x3b, 0xdd, 0xcb, 0xb7, 0x35, 0x8f, 0x76, 0x8b, 0xc3, 0x3c, 0x38, 0x26, 0xdc, 0x15, 0x57, + 0x66, 0xea, 0x05, 0xbe, 0x6d, 0xfc, 0x40, 0x2e, 0x23, 0x8a, 0xd5, 0xeb, 0x51, 0xda, 0xb1, 0x1e, + 0x24, 0xa7, 0xbb, 0xd7, 0x25, 0x37, 0x27, 0xfc, 0x13, 0x08, 0xdd, 0xee, 0xf7, 0xf9, 0x84, 0xbb, + 0xbb, 0xbc, 0x40, 0x24, 0xaa, 0x5f, 0x7d, 0x17, 0xfc, 0x4d, 0xd7, 0x2e, 0x3c, 0x49, 0x4c, 0xee, + 0xf5, 0xc9, 0x5b, 0x2e, 0x26, 0xca, 0xa2, 0x38, 0xb3, 0xc4, 0x7c, 0x4d, 0x6a, 0xbb, 0xbb, 0xe1, + 0x2e, 0xad, 0xa0, 0xaa, 0xd7, 0xf8, 0x9f, 0x11, 0xe2, 0x7c, 0x47, 0x88, 0x04, 0x22, 0x93, 0xac, + 0x6a, 0x08, 0xce, 0x84, 0xb1, 0x19, 0xc5, 0x8a, 0x9b, 0x2a, 0xaf, 0xfb, 0xde, 0xef, 0xb1, 0x6f, + 0xbb, 0xe0, 0x88, 0x8f, 0xbf, 0x7c, 0x17, 0x77, 0x7b, 0x97, 0x2d, 0xfe, 0x8a, 0xfe, 0x21, 0xf9, + 0xbf, 0x84, 0xef, 0x77, 0x9b, 0xea, 0x27, 0x58, 0x97, 0x7b, 0xbe, 0x24, 0x45, 0x62, 0x0d, 0xac, + 0xb4, 0xf0, 0x81, 0x5d, 0x4c, 0x66, 0xba, 0x9a, 0xd2, 0x5c, 0x5f, 0xdd, 0x2b, 0x5e, 0x21, 0x5f, + 0xe5, 0xa1, 0xe4, 0x8f, 0x11, 0xff, 0x13, 0xe2, 0x3c, 0x4f, 0x88, 0xf1, 0x3e, 0x20, 0x83, 0x05, + 0xeb, 0xf1, 0x37, 0xa1, 0xf2, 0xec, 0x29, 0xd0, 0x96, 0x2b, 0x82, 0x41, 0x43, 0x79, 0x93, 0x4c, + 0x13, 0xee, 0x28, 0x58, 0x24, 0xe5, 0x12, 0xb5, 0xf1, 0x1f, 0x09, 0xee, 0x9d, 0xdf, 0xf4, 0x5e, + 0xae, 0x43, 0x3b, 0xdf, 0x12, 0x20, 0x10, 0xd6, 0xa9, 0xbf, 0xd5, 0xfc, 0x4f, 0xcd, 0xaa, 0xd6, + 0x26, 0x5c, 0x49, 0x0e, 0xfb, 0xf1, 0x2f, 0x57, 0xac, 0x47, 0x89, 0xf9, 0xa8, 0xd5, 0x6f, 0x11, + 0xe2, 0x61, 0x8e, 0x09, 0x3c, 0x21, 0x19, 0x2f, 0x78, 0x80, 0x4c, 0x32, 0x5f, 0x77, 0xdc, 0xf5, + 0x62, 0x01, 0x41, 0xea, 0xba, 0xd7, 0xf7, 0xcc, 0x7a, 0xd7, 0xd5, 0xfc, 0x45, 0xc4, 0x6b, 0xfc, + 0xdb, 0xbb, 0xfa, 0xf5, 0xf3, 0x65, 0x65, 0x3f, 0x88, 0xf1, 0x17, 0xcc, 0x57, 0x77, 0x75, 0x88, + 0xbc, 0x41, 0x44, 0x6a, 0xbe, 0x6d, 0xde, 0xfb, 0xaa, 0xd7, 0x88, 0x05, 0xb1, 0x72, 0x7a, 0x6f, + 0xb9, 0x1a, 0x15, 0xe0, 0xb0, 0x44, 0xbd, 0xb1, 0x85, 0xe3, 0xca, 0x17, 0xdc, 0xd9, 0xe6, 0xb8, + 0x89, 0x0b, 0x5a, 0xac, 0x47, 0x88, 0x21, 0x69, 0xaa, 0x7e, 0x30, 0x55, 0x8e, 0x6e, 0x3d, 0x73, + 0xf5, 0xa8, 0x8f, 0xff, 0x14, 0x3d, 0x55, 0x56, 0xaa, 0x2f, 0xc4, 0x4d, 0x12, 0x25, 0x13, 0xab, + 0x13, 0x5c, 0xc2, 0x55, 0x55, 0x4b, 0xcb, 0x77, 0x77, 0x78, 0x8f, 0x11, 0x5e, 0xb9, 0x44, 0x6e, + 0xd9, 0x31, 0x00, 0x88, 0x8a, 0xb5, 0xe8, 0x53, 0x82, 0x62, 0x57, 0xdd, 0xb3, 0x9b, 0xb3, 0x85, + 0x66, 0xce, 0x5e, 0x22, 0xf9, 0xb5, 0xaf, 0xbc, 0xdd, 0x72, 0x61, 0x06, 0x36, 0xab, 0xf6, 0x55, + 0x55, 0x5f, 0x2d, 0x55, 0x57, 0xc9, 0x5d, 0x57, 0x04, 0x5d, 0xdc, 0xe9, 0xe2, 0x0a, 0x6d, 0x55, + 0x62, 0x05, 0x95, 0xf7, 0xaa, 0xaa, 0xe5, 0xbd, 0xbf, 0xb3, 0x91, 0x99, 0x19, 0x97, 0x12, 0x61, + 0xdb, 0xbf, 0x8b, 0xe9, 0x25, 0xbb, 0xf1, 0x1e, 0x26, 0xb9, 0x0b, 0xbb, 0x93, 0x11, 0x7d, 0x1f, + 0x52, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x09, 0x04, 0xb0, 0x52, 0x02, 0x7f, 0x04, 0x82, + 0x6b, 0x52, 0xd8, 0x6c, 0x82, 0x00, 0x08, 0xea, 0x15, 0x91, 0x82, 0x34, 0xdf, 0x07, 0xeb, 0x27, + 0x27, 0x4e, 0x7f, 0x55, 0x51, 0x80, 0x02, 0x86, 0x80, 0x52, 0xf7, 0xf0, 0xdb, 0x80, 0x1c, 0xa3, + 0x62, 0x20, 0x52, 0xeb, 0x76, 0x9b, 0xfb, 0xbc, 0xbf, 0x78, 0x24, 0x64, 0xef, 0xd6, 0x0d, 0x3a, + 0x17, 0x2c, 0x36, 0xc5, 0x02, 0x51, 0x21, 0x5a, 0x2b, 0x5f, 0xff, 0x24, 0xf5, 0xad, 0xef, 0x85, + 0xc9, 0x00, 0x23, 0x96, 0xc2, 0x58, 0xcc, 0x0b, 0x77, 0xe5, 0xef, 0x5a, 0xef, 0x15, 0xc5, 0x8b, + 0x61, 0x38, 0xed, 0x06, 0x02, 0x89, 0xce, 0x49, 0xb2, 0x29, 0x53, 0xc0, 0xf0, 0x19, 0x56, 0xf8, + 0x2a, 0x09, 0x56, 0xa5, 0xe2, 0x00, 0x1f, 0x19, 0xc0, 0xf5, 0x39, 0xeb, 0x18, 0x90, 0xe2, 0x22, + 0xc2, 0xf8, 0x01, 0x57, 0xc5, 0x2c, 0x67, 0x13, 0x3e, 0x5c, 0xfc, 0xbe, 0x2f, 0xad, 0x5d, 0xe1, + 0x91, 0x25, 0x3f, 0x9f, 0xcf, 0x7c, 0x74, 0xfc, 0xf0, 0x80, 0x8e, 0x20, 0x47, 0x08, 0x08, 0xe1, + 0x0c, 0x13, 0x0a, 0x5c, 0x41, 0x38, 0xa4, 0x3c, 0x84, 0x18, 0x8f, 0x0e, 0x46, 0x1b, 0xfd, 0x7f, + 0xf1, 0x54, 0xba, 0xd6, 0xf7, 0xc1, 0x88, 0x0c, 0x81, 0x86, 0x11, 0xe2, 0xb2, 0x72, 0xdb, 0x85, + 0x85, 0x5e, 0xc9, 0xcb, 0x18, 0x3c, 0xb9, 0xc3, 0xc5, 0x6e, 0x5b, 0xc2, 0xee, 0x03, 0x01, 0x6d, + 0x43, 0x5e, 0xbd, 0xdf, 0xef, 0xbf, 0xf4, 0xb8, 0x43, 0xc4, 0x5f, 0x24, 0x57, 0xc1, 0x41, 0xe3, + 0xda, 0x9f, 0xce, 0x8a, 0x6c, 0x8e, 0x99, 0xad, 0x70, 0xc0, 0x16, 0x01, 0x48, 0xc1, 0x01, 0xed, + 0xe2, 0x87, 0xdd, 0xe2, 0x86, 0xa2, 0xea, 0xfc, 0x18, 0x80, 0x90, 0x92, 0x10, 0xdf, 0x36, 0xb5, + 0x05, 0x82, 0x97, 0x80, 0xa9, 0x01, 0xa3, 0x84, 0xdc, 0x0d, 0x77, 0xa7, 0xff, 0xbf, 0xf0, 0x62, + 0x07, 0x01, 0x3b, 0xdd, 0xbb, 0x6a, 0xf0, 0xc7, 0x88, 0xbc, 0x44, 0x16, 0x8a, 0x84, 0x52, 0x84, + 0xd8, 0x40, 0x20, 0xe7, 0x3f, 0xf3, 0x43, 0xf8, 0x21, 0x0c, 0x09, 0x8a, 0xc5, 0x01, 0xb8, 0xaf, + 0x8a, 0x6f, 0x97, 0xaa, 0xbe, 0x4c, 0x5f, 0x05, 0xc2, 0x17, 0x84, 0x02, 0x21, 0x3a, 0xaa, 0xdd, + 0xc5, 0x62, 0xbe, 0x10, 0x13, 0x71, 0x2f, 0x7a, 0xed, 0xc5, 0xd6, 0x23, 0xc4, 0xc1, 0x84, 0x14, + 0x81, 0x43, 0x84, 0x40, 0x90, 0x4d, 0x57, 0x86, 0x03, 0x21, 0x0a, 0x57, 0x15, 0xc5, 0x62, 0xe6, + 0xc1, 0x46, 0x6e, 0xfc, 0xf1, 0x21, 0x81, 0x91, 0x0e, 0x23, 0xf0, 0xa0, 0x32, 0x61, 0xcd, 0xd9, + 0x66, 0x6e, 0xfb, 0x7b, 0xe2, 0x35, 0x89, 0xf1, 0x30, 0x5f, 0x10, 0x0a, 0x45, 0x62, 0xbd, 0x55, + 0x45, 0xf8, 0x80, 0x57, 0x15, 0xbe, 0xaa, 0xa2, 0xe2, 0xe2, 0xe2, 0xe2, 0xfe, 0xf8, 0x9a, 0xca, + 0xaa, 0xa8, 0xba, 0x83, 0x38, 0x44, 0x30, 0x6d, 0x66, 0xfe, 0x32, 0xa2, 0xe2, 0xe2, 0xf4, 0x9c, + 0x43, 0x62, 0xe9, 0xc8, 0x51, 0x50, 0x55, 0x5c, 0x78, 0x00, 0x12, 0xc6, 0x41, 0x12, 0x84, 0x80, + 0x01, 0x5c, 0x14, 0x04, 0x06, 0x6a, 0xd4, 0x5c, 0x5d, 0x54, 0xb0, 0xc9, 0xcf, 0x00, 0xe1, 0x59, + 0x2e, 0xb7, 0xc4, 0x82, 0x0e, 0x20, 0x23, 0xe2, 0x4b, 0x6a, 0xaa, 0x0c, 0x4f, 0x86, 0x94, 0xcc, + 0x48, 0x64, 0x64, 0x53, 0x63, 0x0a, 0xaa, 0x84, 0xc0, 0x01, 0xc8, 0xe0, 0xe1, 0xc0, 0x1e, 0x0c, + 0x75, 0x27, 0x23, 0xb7, 0xb6, 0x49, 0x5d, 0xf0, 0xbc, 0x32, 0x6c, 0x58, 0xb1, 0x00, 0xc4, 0x64, + 0xb0, 0x32, 0xc3, 0x2e, 0xb0, 0xb3, 0x1a, 0xa1, 0x61, 0xb1, 0x83, 0x8f, 0x95, 0x1c, 0x45, 0x42, + 0x62, 0xa5, 0xf2, 0x5e, 0xbe, 0xe2, 0x0f, 0x59, 0xf1, 0x26, 0xc6, 0xa5, 0x05, 0xfa, 0x12, 0xda, + 0xf9, 0x6e, 0xa2, 0xf0, 0x65, 0x89, 0x15, 0xdd, 0x64, 0x85, 0x1f, 0x12, 0x3b, 0x14, 0x0c, 0xd9, + 0x8b, 0xa8, 0xbd, 0xb6, 0xbf, 0x88, 0xf8, 0xa9, 0xcc, 0x1f, 0x4e, 0x27, 0x6b, 0x4b, 0xdc, 0x4b, + 0x0e, 0x0c, 0xb1, 0x1f, 0x83, 0x5f, 0x02, 0x07, 0x27, 0x77, 0xc4, 0xe0, 0xaf, 0x84, 0x77, 0x06, + 0x37, 0x9d, 0x93, 0x43, 0x66, 0x33, 0x31, 0x71, 0x22, 0x38, 0x66, 0x13, 0x88, 0xe2, 0xdd, 0xde, + 0xf8, 0x46, 0x5e, 0xee, 0x0d, 0xa1, 0x9f, 0x13, 0x82, 0x7c, 0x44, 0x21, 0x13, 0x83, 0x7c, 0x47, + 0x13, 0x5e, 0x83, 0x78, 0x9c, 0x1b, 0x44, 0xe0, 0x18, 0x68, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x0a, 0x05, 0x30, 0x52, 0x0d, 0xc0, 0x50, 0x83, 0x03, 0x56, 0x98, 0x50, 0x15, 0xc1, 0x44, 0xbc, + 0xf1, 0xea, 0x0c, 0xe0, 0xc7, 0x8e, 0x8d, 0xcb, 0x84, 0x00, 0xd0, 0x14, 0x18, 0x6e, 0x20, 0x38, + 0x27, 0xce, 0x3c, 0x92, 0xb1, 0xdb, 0x89, 0xf3, 0xbc, 0x4f, 0xb3, 0x4e, 0x79, 0x63, 0x38, 0x07, + 0x9e, 0x0f, 0x14, 0x2f, 0x89, 0x82, 0xb9, 0x60, 0x31, 0x56, 0x24, 0x1c, 0x1d, 0xfd, 0xbb, 0xe1, + 0x72, 0xab, 0x2f, 0xe9, 0x20, 0xcf, 0xa1, 0x7a, 0xe0, 0x61, 0x0c, 0x18, 0x44, 0x4f, 0xc5, 0x3c, + 0x14, 0x46, 0x44, 0x80, 0x1e, 0x70, 0x1e, 0x28, 0x1a, 0x85, 0x8c, 0xb1, 0x9c, 0xf2, 0xd9, 0x25, + 0x49, 0x15, 0x52, 0xa7, 0x00, 0xe1, 0x6d, 0xcb, 0x62, 0xb8, 0x4c, 0x90, 0x05, 0xea, 0x83, 0x50, + 0x77, 0x75, 0xf7, 0x77, 0xf0, 0x68, 0x1b, 0x24, 0x37, 0x4c, 0xf7, 0x57, 0x5f, 0x75, 0xcb, 0x36, + 0xb5, 0xbd, 0xe1, 0x77, 0x03, 0x52, 0xa3, 0x03, 0x0f, 0x7d, 0xef, 0x5a, 0xde, 0xfd, 0x61, 0x32, + 0x40, 0x4e, 0x2c, 0xc8, 0x4f, 0x77, 0x7f, 0xb2, 0xb2, 0xf3, 0x44, 0x04, 0x38, 0x60, 0x47, 0x04, + 0x02, 0x38, 0x40, 0x41, 0x3b, 0xbe, 0x18, 0xc1, 0x50, 0x6f, 0x4f, 0xec, 0xac, 0xbe, 0xcb, 0x5a, + 0xd6, 0xf7, 0x85, 0xdc, 0x02, 0x73, 0xcf, 0x86, 0x7d, 0xef, 0x5a, 0xde, 0xf5, 0xc2, 0x20, 0x84, + 0x13, 0x44, 0x00, 0xf3, 0xde, 0x58, 0x3c, 0xfd, 0x4f, 0xf3, 0xbc, 0xf4, 0x98, 0x43, 0xfc, 0x4e, + 0xe2, 0x70, 0x57, 0xc5, 0x66, 0xf3, 0x79, 0xbd, 0x70, 0x40, 0x18, 0x1d, 0x5b, 0x3e, 0x2b, 0xe3, + 0xaf, 0x04, 0x00, 0x40, 0xb8, 0x43, 0xe2, 0x38, 0x40, 0x4d, 0x44, 0xcd, 0x9a, 0x06, 0xa7, 0x88, + 0xc1, 0x64, 0x44, 0xc5, 0xac, 0xdd, 0x04, 0xd9, 0x8a, 0xc6, 0xbf, 0xff, 0x78, 0x62, 0x4e, 0xf7, + 0x78, 0x2d, 0x86, 0x39, 0xdc, 0x0c, 0x1a, 0xd1, 0x82, 0x0d, 0xf1, 0x7a, 0xaa, 0xad, 0x6a, 0x27, + 0x05, 0xf0, 0x80, 0x63, 0xc4, 0x17, 0xbb, 0x7e, 0x26, 0x24, 0xf5, 0x13, 0xf9, 0xbf, 0x58, 0x40, + 0x97, 0xbf, 0x84, 0x60, 0xc3, 0x08, 0x70, 0xc8, 0x63, 0x84, 0x44, 0x0e, 0x9f, 0x2f, 0xdd, 0xf5, + 0x5c, 0x40, 0x87, 0x48, 0x47, 0x97, 0xd7, 0xe5, 0xbd, 0xef, 0x88, 0xd6, 0xa2, 0x39, 0xe0, 0xbb, + 0x11, 0xe2, 0x41, 0x46, 0xb5, 0xad, 0xfb, 0x84, 0x66, 0xad, 0x7e, 0x2e, 0xb5, 0xf3, 0x62, 0x89, + 0x12, 0x28, 0xab, 0x5a, 0xd6, 0xb1, 0x30, 0x5f, 0x13, 0xe2, 0x21, 0x42, 0x2a, 0xaa, 0xde, 0x6e, + 0xaa, 0xaa, 0x34, 0xc4, 0xb3, 0x3e, 0xc4, 0xf7, 0x88, 0x0a, 0x56, 0x5e, 0xb5, 0x5a, 0xa8, 0xb8, + 0xbe, 0x6a, 0x2f, 0x56, 0x27, 0xe5, 0xda, 0xa8, 0x57, 0xa0, 0x8f, 0x43, 0xb8, 0x91, 0xe1, 0x0a, + 0xa9, 0xbc, 0xac, 0x7a, 0x8f, 0x5c, 0xa7, 0xc2, 0x23, 0x2a, 0xab, 0x91, 0x75, 0xaa, 0xea, 0x99, + 0xbe, 0xb9, 0xb5, 0x3b, 0x37, 0xe4, 0xaa, 0xe0, 0xcb, 0x8a, 0xcb, 0x6b, 0xa9, 0x68, 0xda, 0x78, + 0x9e, 0xaa, 0x8e, 0xa1, 0xf7, 0x83, 0x5c, 0x4d, 0x62, 0x60, 0xd7, 0x88, 0xaa, 0xd5, 0x52, 0x19, + 0x53, 0xdc, 0xe2, 0x60, 0x6a, 0xe5, 0xd5, 0xb8, 0x11, 0x3b, 0xbd, 0xdf, 0x13, 0x83, 0x78, 0x9c, + 0x0d, 0xb1, 0x3f, 0x10, 0xbd, 0x03, 0x6c, 0x4e, 0x01, 0x4f, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, + 0x9a, 0x0b, 0x05, 0xb0, 0x88, 0x35, 0xc1, 0x41, 0x70, 0xbd, 0x4f, 0x39, 0x8c, 0xaa, 0xb5, 0x89, + 0x96, 0x02, 0x60, 0x14, 0xe2, 0x38, 0x33, 0x80, 0x90, 0xf1, 0x30, 0xa0, 0xa9, 0xc6, 0x55, 0xff, + 0x25, 0x00, 0xac, 0xf3, 0xdb, 0xed, 0xf1, 0x75, 0x5f, 0x9c, 0x20, 0x0c, 0x44, 0x97, 0xa6, 0x7e, + 0x22, 0xa5, 0xec, 0xa9, 0x55, 0x6b, 0x80, 0x80, 0xc1, 0x9c, 0x1c, 0xf0, 0xbb, 0x20, 0x3b, 0x32, + 0x8a, 0x8b, 0xc8, 0xc2, 0x2a, 0x2c, 0x8c, 0x48, 0xc1, 0xe4, 0xf0, 0x42, 0x10, 0xbb, 0xcd, 0x69, + 0x65, 0xea, 0x73, 0xf3, 0xfc, 0x6b, 0x0b, 0xfd, 0x06, 0x61, 0xd8, 0x80, 0xed, 0x33, 0xfb, 0xfd, + 0xf1, 0x8e, 0xd7, 0xfc, 0x18, 0x82, 0x00, 0x54, 0x39, 0x31, 0x5a, 0x6e, 0xfb, 0xf1, 0x7e, 0xb8, + 0x40, 0x18, 0x0f, 0xac, 0xe7, 0x7f, 0x2e, 0x44, 0x8f, 0xc4, 0x90, 0x26, 0xd1, 0xe2, 0x44, 0x71, + 0x22, 0x3c, 0x41, 0x82, 0x55, 0x58, 0x2b, 0x84, 0x41, 0x47, 0x10, 0x0a, 0x44, 0x55, 0x55, 0x4b, + 0x3a, 0xf0, 0x34, 0x66, 0xe4, 0xbb, 0xff, 0xf3, 0x6a, 0xb0, 0x50, 0x23, 0xfa, 0x0a, 0xe5, 0x70, + 0x42, 0x0c, 0x48, 0x10, 0x10, 0xf1, 0x2f, 0xf0, 0xcc, 0xa4, 0x14, 0xd3, 0x14, 0x31, 0x6f, 0x02, + 0x85, 0x04, 0xfb, 0xeb, 0xd7, 0xcc, 0x12, 0xaa, 0xdf, 0xfb, 0xe4, 0xf0, 0x59, 0xc1, 0x3d, 0x3b, + 0xb6, 0xed, 0xe5, 0xdc, 0x32, 0x0c, 0x44, 0x5d, 0xde, 0xa2, 0xea, 0x2f, 0x88, 0xde, 0x27, 0xc4, + 0xd7, 0x36, 0x9c, 0xbf, 0xe0, 0xb7, 0x08, 0x0a, 0x17, 0x3a, 0x89, 0xd4, 0x72, 0xb1, 0x89, 0x0c, + 0x09, 0x14, 0xef, 0x7a, 0xd7, 0xc4, 0x9c, 0x1b, 0x48, 0x38, 0xf9, 0xfd, 0xfb, 0x89, 0x90, 0xd9, + 0x33, 0x88, 0x0c, 0xc1, 0x6e, 0x19, 0x26, 0xf2, 0xfc, 0x48, 0x9f, 0x0c, 0xd6, 0x26, 0xb1, 0x1f, + 0x7c, 0xb8, 0xe0, 0xba, 0x27, 0xc4, 0xf8, 0x91, 0x1f, 0x04, 0x30, 0x75, 0x70, 0x66, 0xa6, 0x28, + 0xaf, 0x13, 0xf7, 0xbd, 0xf8, 0x67, 0xc3, 0x30, 0x5d, 0x89, 0x2f, 0x6d, 0x41, 0xa7, 0x14, 0x7b, + 0xdb, 0xb7, 0x3f, 0x7c, 0xc4, 0xd5, 0x7c, 0xc5, 0xad, 0x7c, 0xbc, 0x99, 0xf3, 0x16, 0xab, 0x06, + 0x3c, 0x82, 0xb5, 0x48, 0x0d, 0xb8, 0x98, 0x35, 0xc4, 0xfc, 0x25, 0xda, 0x5b, 0x76, 0xc0, 0xf3, + 0xca, 0x11, 0xcf, 0xe0, 0xdf, 0x94, 0x20, 0xb5, 0x80, 0xa5, 0x88, 0xc0, 0xdb, 0xc1, 0x25, 0x75, + 0xe8, 0x19, 0x71, 0x13, 0xc4, 0x88, 0x80, 0xe3, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x0c, + 0x06, 0x31, 0xa0, 0xaf, 0x61, 0x35, 0x55, 0x52, 0x73, 0x1b, 0x55, 0xc1, 0x00, 0x10, 0x54, 0x6b, + 0x63, 0x65, 0x91, 0x20, 0xd2, 0x04, 0x00, 0x88, 0x27, 0x09, 0x4b, 0xc4, 0x71, 0xbc, 0x9b, 0x70, + 0xbf, 0xa5, 0xc1, 0x40, 0x64, 0x49, 0x06, 0xd7, 0x3c, 0x60, 0x6e, 0xed, 0x7f, 0x2b, 0x25, 0x2d, + 0xe0, 0x20, 0x02, 0x30, 0x69, 0x02, 0x08, 0x60, 0x2e, 0x24, 0x2b, 0x51, 0xcd, 0xf1, 0x1f, 0x12, + 0x58, 0x53, 0xcb, 0x00, 0xe0, 0x4f, 0x06, 0x04, 0x98, 0xbc, 0x53, 0xbc, 0x57, 0x86, 0x43, 0x23, + 0x04, 0x6e, 0xa8, 0x41, 0x9a, 0x84, 0x86, 0x90, 0x64, 0xb9, 0x0b, 0xd4, 0xb0, 0xc4, 0x58, 0xc7, + 0x4f, 0x89, 0x04, 0xc7, 0xee, 0xa2, 0xca, 0x83, 0x17, 0xd2, 0xef, 0x82, 0x30, 0x8a, 0xaa, 0xac, + 0x51, 0x3d, 0x13, 0xa0, 0x9f, 0xab, 0x95, 0xcc, 0x7b, 0xbb, 0xe1, 0x0a, 0x1c, 0x2d, 0x88, 0xdc, + 0x22, 0x05, 0x80, 0x52, 0x30, 0x57, 0xbd, 0x49, 0x8b, 0x97, 0xb5, 0x56, 0xe2, 0x03, 0x22, 0x7a, + 0xa3, 0xcf, 0xdc, 0xf7, 0xf9, 0x02, 0xee, 0xf9, 0xb9, 0x85, 0x4c, 0xc2, 0x4d, 0x49, 0xe6, 0x15, + 0x77, 0x7c, 0x48, 0x8e, 0x20, 0x40, 0xad, 0xe2, 0x8e, 0x7d, 0x3e, 0x60, 0x9f, 0xa0, 0x9f, 0x78, + 0x84, 0x5e, 0xf0, 0x8a, 0xe5, 0x84, 0x14, 0xf5, 0x2a, 0x15, 0x6b, 0xfe, 0x11, 0x04, 0x00, 0x84, + 0x31, 0x77, 0x76, 0xe2, 0x01, 0xc3, 0xa9, 0x7d, 0x23, 0x44, 0xea, 0x23, 0xc4, 0xe0, 0xab, 0x82, + 0x10, 0xdb, 0xbb, 0xba, 0x44, 0xa1, 0x10, 0x42, 0x09, 0xc2, 0x85, 0x49, 0x3e, 0x1e, 0x29, 0xe5, + 0xe7, 0xd2, 0xef, 0x10, 0x30, 0x99, 0xa9, 0x13, 0xe0, 0xf5, 0xcd, 0xd9, 0xea, 0xab, 0xdb, 0x1b, + 0xf6, 0x26, 0x50, 0x9b, 0xbf, 0x78, 0x9f, 0x13, 0xc4, 0xeb, 0x98, 0x28, 0xa2, 0xff, 0xe3, 0x08, + 0x17, 0x3d, 0x0e, 0xb8, 0x26, 0xea, 0xd2, 0x62, 0x11, 0x3b, 0x89, 0x08, 0x82, 0x71, 0x00, 0xff, + 0xd9, 0x79, 0xef, 0x72, 0xc7, 0x7e, 0x3a, 0xf0, 0x8b, 0x11, 0xbb, 0xf0, 0xcd, 0xfb, 0x89, 0x11, + 0xc4, 0xd5, 0xfc, 0x33, 0xc3, 0x21, 0x94, 0x15, 0x78, 0x2a, 0x88, 0x04, 0x18, 0x65, 0x8a, 0x38, + 0xd7, 0xc5, 0xe2, 0xff, 0x5a, 0x88, 0xa8, 0x97, 0xf2, 0x0c, 0xad, 0x7c, 0x49, 0xc8, 0xa2, 0xc5, + 0x16, 0xe7, 0x66, 0xfa, 0x11, 0xdf, 0x63, 0x77, 0x7e, 0x27, 0x88, 0x13, 0x70, 0xc8, 0x66, 0x09, + 0xf9, 0x45, 0xbb, 0xe4, 0x89, 0x08, 0xf1, 0x01, 0x00, 0x80, 0x52, 0xad, 0xeb, 0x55, 0x8b, 0xf1, + 0x21, 0x17, 0xdb, 0x4c, 0x9e, 0xf1, 0x37, 0xc4, 0x86, 0x6b, 0x5a, 0xd4, 0x20, 0x31, 0x63, 0xb4, + 0x33, 0x89, 0x04, 0xc3, 0xaf, 0x7b, 0x4a, 0x4d, 0xef, 0x82, 0xa3, 0x52, 0x79, 0x88, 0xa5, 0xac, + 0xb4, 0x7e, 0xf8, 0x2b, 0xcb, 0x54, 0xf4, 0xd3, 0xa5, 0x37, 0xbb, 0xf8, 0x80, 0x4b, 0x1d, 0xc3, + 0x62, 0x73, 0x96, 0x86, 0xa9, 0x5c, 0xf8, 0x4b, 0x36, 0x49, 0x8e, 0xdd, 0xb7, 0x88, 0x21, 0x85, + 0x7d, 0x8c, 0x41, 0xbf, 0x70, 0x88, 0x46, 0x12, 0xeb, 0x50, 0xcc, 0x44, 0x22, 0x12, 0xbc, 0xf9, + 0xaa, 0xea, 0xcf, 0x88, 0x05, 0x25, 0x74, 0xae, 0xda, 0x1c, 0xd2, 0xcd, 0x6b, 0xef, 0x84, 0x3a, + 0xaa, 0x69, 0xd6, 0x2e, 0x6c, 0x9f, 0x21, 0x95, 0xaa, 0xf8, 0x91, 0x2f, 0x9b, 0xd5, 0x54, 0x4c, + 0x23, 0x84, 0xce, 0xf0, 0xac, 0x47, 0x89, 0x12, 0x0a, 0xc5, 0x5e, 0x5f, 0x49, 0xd0, 0xcd, 0xd8, + 0xe4, 0x8c, 0xb7, 0x84, 0x5d, 0xe9, 0xf8, 0x91, 0xf5, 0x5e, 0x57, 0x7b, 0xfc, 0xc7, 0xb4, 0xbf, + 0x08, 0xd6, 0xb5, 0xd2, 0xa8, 0x5a, 0xb4, 0x81, 0x96, 0x20, 0x22, 0x20, 0x9e, 0x24, 0x36, 0x71, + 0x7a, 0xa2, 0x7f, 0x88, 0x13, 0x49, 0x31, 0xdf, 0x2a, 0xde, 0xfc, 0x61, 0xeb, 0x8b, 0xbb, 0xf6, + 0x8a, 0x23, 0x07, 0xe1, 0x02, 0xaa, 0xe3, 0xcd, 0x07, 0xa4, 0xa2, 0xcd, 0x9c, 0x19, 0x70, 0x99, + 0x15, 0x79, 0xcd, 0x5f, 0xcd, 0x26, 0x75, 0xc5, 0x43, 0x96, 0xbd, 0xf7, 0xd9, 0x18, 0x83, 0x60, + 0xfc, 0xb2, 0x21, 0x97, 0x50, 0x65, 0xca, 0x27, 0x55, 0x58, 0x9a, 0xe2, 0x26, 0xa0, 0xf7, 0xbc, + 0x8b, 0xfc, 0x44, 0x18, 0xf2, 0x11, 0x31, 0xfe, 0xda, 0xee, 0x6b, 0x26, 0x3d, 0xbe, 0x50, 0x8b, + 0xbb, 0xcb, 0xca, 0x10, 0xdd, 0xc0, 0xbd, 0xc9, 0x7d, 0x4b, 0xd9, 0x33, 0x67, 0xca, 0x5d, 0xd4, + 0x4f, 0x04, 0x45, 0x83, 0x37, 0xbb, 0xfc, 0x82, 0x32, 0x62, 0x82, 0x3e, 0x60, 0x8d, 0x6a, 0x6c, + 0x47, 0xca, 0x31, 0xef, 0x58, 0x97, 0x17, 0x1c, 0x5c, 0x93, 0xa1, 0x7d, 0x3c, 0x47, 0x88, 0xc1, + 0x46, 0x22, 0xb8, 0x24, 0x26, 0xee, 0xf2, 0x44, 0xd1, 0x7a, 0x6e, 0x5b, 0x33, 0xde, 0x0a, 0x31, + 0x12, 0x62, 0x01, 0x15, 0xdd, 0xdd, 0xee, 0x24, 0x45, 0xe2, 0x11, 0xde, 0x23, 0x90, 0x25, 0x79, + 0xb0, 0x21, 0xd0, 0x9a, 0x82, 0x1c, 0x44, 0xd1, 0x1f, 0x12, 0x08, 0xc8, 0xf7, 0xd4, 0x1b, 0x62, + 0x61, 0xbe, 0xb5, 0x0d, 0xc4, 0xe0, 0xb3, 0x11, 0xe2, 0x24, 0x89, 0xc1, 0x16, 0x22, 0x2b, 0x10, + 0x8e, 0xf7, 0x11, 0x82, 0xf8, 0x8c, 0xb8, 0x88, 0x8e, 0x8b, 0x50, 0x15, 0x3c, 0xb7, 0x77, 0x71, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x0d, 0x06, 0xb0, 0x4a, 0x0c, 0xf3, 0x0b, 0xe2, 0x79, + 0xe3, 0xb7, 0xbd, 0xef, 0x8b, 0xfd, 0x1f, 0x5f, 0x05, 0x15, 0x5d, 0x57, 0xba, 0x0b, 0xba, 0xb9, + 0x2c, 0x33, 0x0b, 0x84, 0x21, 0x7d, 0xc1, 0x94, 0x09, 0xa8, 0xdc, 0x8c, 0xd4, 0xa7, 0x3d, 0x98, + 0xf6, 0x5a, 0xbf, 0x0c, 0x84, 0x06, 0x1a, 0x55, 0x46, 0x59, 0x18, 0xd1, 0xb7, 0x51, 0xe3, 0x8e, + 0x47, 0xcd, 0xa8, 0x8d, 0x98, 0x46, 0x50, 0xab, 0xbe, 0xe0, 0xcb, 0xae, 0x55, 0x11, 0x42, 0x9f, + 0x89, 0x82, 0xd1, 0x57, 0x71, 0xf4, 0xc3, 0xb9, 0x7b, 0xff, 0x71, 0x30, 0x4d, 0xd7, 0xb1, 0xa2, + 0xbd, 0x65, 0xf4, 0x17, 0xca, 0x27, 0x82, 0x32, 0x3b, 0xbb, 0xa6, 0x40, 0x83, 0x92, 0xee, 0xee, + 0x7e, 0x09, 0x3c, 0xd9, 0xdf, 0x45, 0x3e, 0xae, 0x09, 0xc5, 0x41, 0xaa, 0x59, 0x7d, 0x3b, 0xc1, + 0xc4, 0x41, 0x08, 0xee, 0xe6, 0xd3, 0xde, 0x10, 0x13, 0x76, 0x7c, 0xaa, 0x2d, 0x78, 0x23, 0x0b, + 0xbb, 0xbe, 0xa6, 0xe0, 0x90, 0x53, 0x71, 0xe7, 0xc6, 0xd8, 0x7a, 0x15, 0x17, 0xc1, 0x25, 0xdf, + 0x7f, 0x82, 0x7d, 0xb2, 0xf8, 0x87, 0x68, 0xf7, 0xfe, 0xf0, 0x82, 0x0a, 0xf4, 0x3b, 0xcc, 0x47, + 0x7c, 0x44, 0x31, 0x44, 0xab, 0xe8, 0xb1, 0x63, 0x15, 0x9f, 0x22, 0xe2, 0x41, 0x40, 0x52, 0x5f, + 0xbd, 0xfa, 0xf1, 0x22, 0xe9, 0xee, 0x36, 0xce, 0x95, 0x69, 0xe2, 0x02, 0x33, 0x70, 0x97, 0xbb, + 0xea, 0xab, 0x82, 0x4d, 0x33, 0xe7, 0xdf, 0x75, 0x55, 0x82, 0x8e, 0x82, 0xae, 0xbe, 0x09, 0xc7, + 0x4a, 0x41, 0x5b, 0xd5, 0x3e, 0xe2, 0x04, 0x23, 0x3f, 0x13, 0x28, 0x47, 0x16, 0xe6, 0x89, 0xfc, + 0x50, 0x4b, 0x9b, 0xd9, 0x2f, 0xdd, 0xef, 0xca, 0xec, 0x2f, 0x5a, 0x84, 0x05, 0x22, 0x0d, 0xf8, + 0x2f, 0x88, 0x45, 0x89, 0x57, 0x10, 0xa9, 0x57, 0xaa, 0x55, 0xe0, 0x88, 0x50, 0xc5, 0x74, 0xe1, + 0x1b, 0x96, 0xf0, 0x88, 0x2c, 0x15, 0x2f, 0xa6, 0xee, 0xf7, 0xd5, 0xfc, 0x32, 0x24, 0xe4, 0xa9, + 0x07, 0x23, 0x83, 0xe5, 0x17, 0x30, 0xb5, 0x06, 0xf9, 0xb7, 0xbb, 0xe0, 0x93, 0x69, 0xc1, 0x29, + 0xfd, 0x5b, 0xab, 0xa0, 0x8b, 0xfd, 0x5b, 0xef, 0x7b, 0x82, 0xae, 0x84, 0x17, 0x38, 0x80, 0x50, + 0x13, 0x1c, 0xf6, 0x3a, 0x1a, 0x70, 0xd6, 0x38, 0xe1, 0x01, 0x25, 0x6b, 0x17, 0x9f, 0xda, 0xc4, + 0x9c, 0x12, 0x1d, 0xf7, 0x7f, 0x98, 0xd5, 0x85, 0xb9, 0x79, 0x4c, 0x38, 0x71, 0xf8, 0x21, 0x84, + 0x31, 0xbc, 0xc3, 0xdb, 0xab, 0x5c, 0x22, 0x41, 0x95, 0xd6, 0x56, 0x8f, 0xdd, 0x5d, 0x3a, 0xa6, + 0xc2, 0x35, 0x84, 0x7c, 0x23, 0x05, 0x58, 0x90, 0x54, 0x2d, 0x2b, 0xf9, 0x3a, 0x52, 0xef, 0xff, + 0x12, 0x24, 0x95, 0x2f, 0xbb, 0xd2, 0xf1, 0x84, 0x1c, 0xf4, 0xd3, 0x92, 0xfa, 0x6e, 0x93, 0xbb, + 0x1f, 0xe0, 0x87, 0x3a, 0xee, 0xe9, 0xbd, 0x72, 0xcb, 0x9d, 0x71, 0xc4, 0xe2, 0xb3, 0xe7, 0xbc, + 0x7f, 0x1a, 0xe8, 0x33, 0xdf, 0x5a, 0xac, 0x23, 0xc1, 0x0e, 0x10, 0xeb, 0xd0, 0xcc, 0x44, 0x24, + 0x10, 0x77, 0xeb, 0x6b, 0x10, 0x20, 0x61, 0x46, 0x9a, 0xfd, 0x03, 0x53, 0x52, 0x64, 0x21, 0x46, + 0xaa, 0xba, 0xf5, 0xab, 0xe4, 0xd6, 0x9f, 0xb9, 0xbf, 0xbc, 0x4e, 0x21, 0x60, 0xb3, 0x8a, 0x23, + 0x65, 0x44, 0xde, 0xb6, 0xf8, 0x98, 0xa2, 0x0c, 0x2c, 0xcc, 0x75, 0x3d, 0x2a, 0x51, 0x8c, 0x33, + 0x7e, 0x5d, 0xd1, 0xb1, 0xf9, 0x77, 0xbb, 0xe6, 0x16, 0xba, 0x82, 0xfe, 0xc5, 0xbb, 0xeb, 0x85, + 0x02, 0xd0, 0x76, 0xee, 0xef, 0x47, 0x64, 0x8a, 0x35, 0x6d, 0xe8, 0x29, 0xca, 0xb3, 0x62, 0xb0, + 0x48, 0x78, 0xb9, 0xd4, 0x7c, 0x14, 0xf3, 0x59, 0x8c, 0x6e, 0xa9, 0x5d, 0xe5, 0x1e, 0xf2, 0xb8, + 0x4e, 0xef, 0xea, 0x41, 0x1f, 0x14, 0x5d, 0x56, 0x69, 0xab, 0x30, 0x19, 0xf1, 0x06, 0xb4, 0xd3, + 0x0d, 0xb9, 0x98, 0xae, 0x28, 0xa4, 0x21, 0x79, 0x05, 0xa7, 0xe2, 0x5c, 0xd4, 0xf7, 0x1b, 0x14, + 0x5c, 0x75, 0x88, 0x81, 0x9f, 0x8f, 0x25, 0xee, 0xe8, 0xdb, 0x66, 0x4a, 0x78, 0x10, 0x39, 0x69, + 0x6e, 0x06, 0xf8, 0x9b, 0xad, 0x54, 0x0b, 0x38, 0x8f, 0x08, 0x4d, 0xcc, 0x15, 0x7b, 0xbf, 0x89, + 0x25, 0xde, 0xf7, 0xbe, 0x62, 0x3b, 0xe4, 0xc4, 0x4b, 0xd9, 0x72, 0x5f, 0xc1, 0x38, 0xa5, 0x47, + 0xc9, 0x9c, 0x5f, 0x2c, 0x5f, 0x87, 0x7b, 0x3d, 0x6a, 0xba, 0xbf, 0xe7, 0xe0, 0x90, 0xb5, 0x5b, + 0xf8, 0x88, 0x9c, 0x47, 0xd9, 0xd6, 0xbf, 0x10, 0x44, 0x68, 0xd1, 0xa3, 0x4b, 0x6b, 0xd9, 0x6e, + 0xef, 0xc4, 0x7c, 0x50, 0xe7, 0x6d, 0xde, 0x5f, 0xfa, 0xbc, 0x39, 0xd6, 0x57, 0xe4, 0xc4, 0x5e, + 0x23, 0xc4, 0x82, 0x41, 0xb7, 0xbb, 0xf8, 0x88, 0x98, 0x9f, 0x13, 0xe2, 0x75, 0x88, 0xfa, 0x19, + 0x2f, 0x82, 0x32, 0x92, 0x51, 0x23, 0xf8, 0x41, 0x1e, 0x23, 0xe5, 0x2b, 0xdf, 0xc4, 0xab, 0xcf, + 0x88, 0xf1, 0x1e, 0x22, 0xa2, 0x04, 0x4d, 0xd0, 0xa9, 0x41, 0x8c, 0x45, 0x1f, 0xa0, 0x57, 0xc4, + 0x16, 0xb5, 0x85, 0xfa, 0x2f, 0x4b, 0x88, 0x82, 0x7c, 0x44, 0xfc, 0xb7, 0xdc, 0x1a, 0xf3, 0x5e, + 0xf0, 0xf7, 0x28, 0xec, 0xcc, 0x4d, 0x10, 0x26, 0x09, 0x20, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x0e, 0x07, 0x30, 0x7a, 0x0c, 0xf3, 0x0b, 0xb5, 0x6f, 0x0c, 0x88, 0x04, 0x64, 0x35, 0x34, 0xd3, + 0xf9, 0xf4, 0x2d, 0xce, 0x18, 0x08, 0xa9, 0xba, 0x14, 0xee, 0xee, 0xaa, 0x18, 0xeb, 0x5f, 0x54, + 0xab, 0xd4, 0xab, 0x24, 0xe4, 0xbb, 0xaa, 0xe1, 0x18, 0x27, 0x08, 0x28, 0x40, 0xc4, 0x61, 0xa0, + 0xe9, 0x22, 0x19, 0x84, 0xb4, 0xe2, 0xac, 0xd1, 0x0f, 0x88, 0x85, 0x0c, 0x7d, 0x83, 0x46, 0x9b, + 0x6e, 0x67, 0x66, 0x15, 0xb8, 0x11, 0xf4, 0x2b, 0x65, 0x8b, 0x0d, 0xee, 0x04, 0x38, 0x60, 0x1b, + 0x96, 0xa5, 0x30, 0x48, 0xb2, 0xfb, 0x84, 0x04, 0x82, 0xd0, 0x9a, 0x49, 0x6c, 0xe4, 0xc0, 0x4d, + 0x66, 0x1d, 0xf1, 0x7c, 0x45, 0xdf, 0x77, 0xc3, 0x3d, 0x5b, 0xeb, 0x14, 0x2f, 0xd1, 0xb2, 0xa8, + 0x9a, 0x33, 0x9c, 0x20, 0x0e, 0x07, 0x8e, 0x52, 0xcc, 0xdc, 0xbe, 0x26, 0xdd, 0xb4, 0xf3, 0x7e, + 0x08, 0x0b, 0xbc, 0x4b, 0xfd, 0x06, 0x72, 0x83, 0x0e, 0x89, 0xdf, 0x45, 0x6a, 0x89, 0x90, 0x42, + 0x1a, 0x1c, 0x8c, 0x71, 0x20, 0xac, 0x21, 0x54, 0xdd, 0x8d, 0xf2, 0xaa, 0x8e, 0x3a, 0xbe, 0xf0, + 0xc0, 0x42, 0x5e, 0xdc, 0x4c, 0xe1, 0xa4, 0xb4, 0x57, 0x68, 0x73, 0x2d, 0xfc, 0x40, 0x94, 0x15, + 0x6f, 0x08, 0xc4, 0xf5, 0xe8, 0x26, 0xeb, 0x6a, 0xeb, 0x97, 0xd6, 0xbc, 0x22, 0x08, 0x82, 0x59, + 0xfa, 0xfd, 0xf1, 0x9c, 0x3c, 0xd6, 0x73, 0xdf, 0x10, 0x2c, 0x6d, 0x1f, 0xd0, 0x95, 0xd5, 0xc0, + 0x3c, 0x34, 0xc2, 0xac, 0x13, 0x6d, 0xff, 0xfe, 0x09, 0x1f, 0x3f, 0x41, 0x27, 0xae, 0xaf, 0xe2, + 0x10, 0x4f, 0xa1, 0x8e, 0x88, 0xc4, 0x7f, 0x45, 0x65, 0xe2, 0x41, 0x00, 0xea, 0x74, 0xeb, 0x55, + 0x22, 0x9b, 0x1b, 0xbf, 0xc5, 0x4b, 0xc2, 0x26, 0x4a, 0xe5, 0xd5, 0xa1, 0xa5, 0x4a, 0x51, 0x01, + 0xf6, 0x3d, 0x3c, 0x77, 0xcd, 0xa7, 0x32, 0x97, 0xd7, 0xab, 0x82, 0x11, 0xc8, 0x8f, 0xd0, 0xf7, + 0xf1, 0x10, 0x57, 0xcc, 0x5a, 0xaf, 0xca, 0x2a, 0xee, 0xe2, 0x7a, 0x0b, 0xbf, 0x89, 0x57, 0x81, + 0x8b, 0x98, 0x2d, 0xa9, 0x19, 0x06, 0x9c, 0xa3, 0xf3, 0x74, 0x5e, 0x53, 0x56, 0xbe, 0x2a, 0xbb, + 0x06, 0x9b, 0x74, 0xfe, 0x12, 0xcd, 0xa8, 0xda, 0x64, 0x43, 0x07, 0x6b, 0xe3, 0x39, 0xa8, 0xf9, + 0xa0, 0x92, 0x4e, 0xfe, 0xaa, 0x58, 0x46, 0x82, 0x7d, 0xf5, 0xe8, 0x4f, 0xaf, 0x40, 0x9f, 0xca, + 0x18, 0x7b, 0xc1, 0xbf, 0x2d, 0xda, 0xb0, 0x30, 0x6b, 0xcd, 0xbb, 0x29, 0xf9, 0x2f, 0xb8, 0x2f, + 0xe6, 0x3a, 0xe6, 0xc0, 0x71, 0xdd, 0x6e, 0xc8, 0x0c, 0x9c, 0xc2, 0x75, 0x55, 0xc8, 0x6b, 0x76, + 0xc9, 0xc6, 0x1a, 0xf2, 0xd0, 0xb9, 0x7e, 0x8e, 0xb5, 0xa4, 0xd2, 0x7e, 0xe5, 0xcf, 0x2c, 0x99, + 0xfe, 0x2c, 0xed, 0xac, 0xb1, 0x55, 0xeb, 0x13, 0x5c, 0x40, 0xbd, 0x55, 0x75, 0xc4, 0xfc, 0x41, + 0x6b, 0x55, 0xc4, 0x89, 0xe2, 0x44, 0x7c, 0x86, 0xd9, 0x16, 0x9e, 0x41, 0x1b, 0xa2, 0xf3, 0x78, + 0xbf, 0x94, 0x27, 0x83, 0x75, 0xec, 0x14, 0xf2, 0x05, 0x37, 0x72, 0xf2, 0x8b, 0xd5, 0x4f, 0xc8, + 0x67, 0x63, 0xd7, 0x2c, 0x66, 0x9b, 0x19, 0x82, 0xae, 0x53, 0xee, 0xe7, 0xc4, 0x40, 0xe9, 0xca, + 0x21, 0xf7, 0x01, 0x0d, 0xcc, 0x36, 0xb5, 0x51, 0x15, 0xef, 0xb3, 0xbb, 0xcb, 0x07, 0xc8, 0x4b, + 0xbb, 0xbe, 0xca, 0xee, 0xef, 0xe6, 0xbb, 0xfe, 0x62, 0x6e, 0xfe, 0x0a, 0x0b, 0x7b, 0xbb, 0xbb, + 0xff, 0xe1, 0x3b, 0xdd, 0xee, 0xef, 0xe4, 0x95, 0x89, 0x58, 0x75, 0x88, 0xf9, 0x84, 0x2d, 0x6b, + 0x94, 0xf4, 0xae, 0xba, 0xbf, 0x88, 0x26, 0xee, 0xcb, 0xc7, 0x77, 0x56, 0xac, 0x89, 0x1c, 0xa6, + 0x52, 0xf2, 0xd9, 0x5b, 0x4c, 0x98, 0x8f, 0x93, 0x12, 0xe4, 0xbc, 0x6f, 0x57, 0x23, 0x78, 0x91, + 0x4f, 0x7b, 0xbb, 0xbf, 0x98, 0xb5, 0x6d, 0x7d, 0x89, 0xaa, 0xa9, 0x39, 0x04, 0x3b, 0xbb, 0xf9, + 0x6e, 0xee, 0xfe, 0x8b, 0x55, 0xcd, 0x77, 0x7b, 0xe2, 0x32, 0xfb, 0xdd, 0xef, 0x11, 0xf1, 0x55, + 0xd5, 0xad, 0x3f, 0x2e, 0x95, 0xa2, 0x77, 0xaa, 0xcf, 0xc8, 0x21, 0xef, 0xf2, 0xcd, 0xe3, 0xf8, + 0x8c, 0x2d, 0xc2, 0xf5, 0xc5, 0xd4, 0xd0, 0x22, 0x4d, 0x65, 0xac, 0x54, 0xff, 0xdc, 0x4e, 0x16, + 0x76, 0x9f, 0x16, 0x7a, 0xc7, 0x31, 0x7d, 0xd6, 0x23, 0xc4, 0x78, 0x8f, 0x92, 0xee, 0xee, 0xf9, + 0x2f, 0x77, 0x26, 0x23, 0xe8, 0xaf, 0x5c, 0xb7, 0x53, 0xfa, 0xf8, 0x8f, 0x11, 0xe2, 0x2b, 0x11, + 0xe2, 0x0d, 0x52, 0x66, 0x58, 0x9b, 0x2b, 0xbf, 0xe4, 0xbd, 0xdf, 0xc1, 0x10, 0xe7, 0xbf, 0xa0, + 0x97, 0x10, 0x8a, 0xf7, 0x89, 0x97, 0x11, 0xe2, 0x62, 0x79, 0x6b, 0x6c, 0xd1, 0x0a, 0x72, 0x0c, + 0xaa, 0xcf, 0xc7, 0x8f, 0x5a, 0xeb, 0x5a, 0xd5, 0xe2, 0x2a, 0x20, 0x47, 0xca, 0x64, 0xe9, 0xcb, + 0xcc, 0x7d, 0x54, 0x9c, 0x9d, 0xdf, 0x88, 0xae, 0xee, 0xf8, 0x2f, 0xc4, 0x18, 0x9a, 0xa8, 0x62, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x0f, 0x07, 0xb0, 0x2a, 0x8b, 0xd0, 0x94, 0x8b, 0x11, 0x04, + 0x35, 0xbb, 0xbf, 0x13, 0x5c, 0xa1, 0x2e, 0x5b, 0xba, 0x9b, 0x3c, 0x14, 0x51, 0xc0, 0x1f, 0xbe, + 0xa9, 0xe5, 0xd2, 0x69, 0x53, 0xc7, 0x70, 0x5c, 0xa9, 0xf0, 0xc0, 0x97, 0xaa, 0xf5, 0x59, 0xb0, + 0xd8, 0xe4, 0x46, 0x0d, 0xe1, 0x8f, 0xb7, 0x5b, 0x7e, 0x7c, 0xef, 0xdd, 0x5d, 0x19, 0xa2, 0x44, + 0xc6, 0xc4, 0x78, 0x9b, 0x9b, 0x1d, 0x87, 0xc7, 0xe0, 0x63, 0xa1, 0x15, 0xf5, 0x4c, 0xbd, 0x4c, + 0xb3, 0xeb, 0x95, 0xf2, 0x55, 0x5d, 0xfc, 0x83, 0xae, 0xee, 0xba, 0x1b, 0x14, 0x35, 0xd5, 0xbe, + 0xb1, 0x42, 0xdd, 0x19, 0xcf, 0xaf, 0x49, 0xc1, 0x08, 0x49, 0x85, 0x3c, 0x70, 0xfe, 0x82, 0xf9, + 0x40, 0xcd, 0xd0, 0xae, 0xae, 0xbd, 0x07, 0x5d, 0x11, 0xe0, 0x28, 0x39, 0x36, 0x39, 0x91, 0x78, + 0x40, 0x57, 0x17, 0x9b, 0xab, 0xba, 0xa7, 0xfc, 0xba, 0x75, 0x2f, 0x7e, 0x6a, 0x02, 0xfe, 0x4a, + 0xae, 0x4e, 0xea, 0xb9, 0x3a, 0x0a, 0xf7, 0xd7, 0xa1, 0x3e, 0xbd, 0x0e, 0x73, 0x04, 0x15, 0x57, + 0xe2, 0x4e, 0xd6, 0xd5, 0xba, 0x83, 0x3e, 0x0b, 0x84, 0x2c, 0xd7, 0xb6, 0x71, 0x01, 0xad, 0x22, + 0xf2, 0x6c, 0xea, 0x0d, 0x39, 0x89, 0xbb, 0x7e, 0x6b, 0x77, 0x83, 0x4e, 0x28, 0xf5, 0xb7, 0x6e, + 0xab, 0x94, 0x45, 0xdf, 0xc4, 0xcd, 0xca, 0x7d, 0xdc, 0x17, 0x72, 0x15, 0x3d, 0x44, 0x72, 0x08, + 0x7b, 0xfc, 0xb7, 0xbb, 0x81, 0x93, 0x90, 0xa9, 0xd3, 0x93, 0xb1, 0xbb, 0xba, 0x89, 0xf8, 0x42, + 0xb9, 0x87, 0x38, 0xae, 0xfe, 0x2f, 0x57, 0xe5, 0xc8, 0x2b, 0xe5, 0xbb, 0xe0, 0xc7, 0x11, 0x7c, + 0xc3, 0x75, 0x55, 0xd8, 0x85, 0xa7, 0xf3, 0x6f, 0x7f, 0x13, 0x6f, 0x4b, 0x77, 0x2f, 0x12, 0x25, + 0x6b, 0x5a, 0xcb, 0xc1, 0x15, 0xdf, 0x73, 0xe0, 0xb4, 0x92, 0xa8, 0xf5, 0x35, 0x1e, 0x0a, 0x7b, + 0x20, 0xaf, 0xae, 0x63, 0xbb, 0xfe, 0x42, 0xd5, 0x57, 0xdd, 0x6b, 0xc4, 0xcd, 0x55, 0xd7, 0x46, + 0xae, 0x23, 0x5d, 0x7a, 0xb8, 0x4c, 0x4a, 0xb3, 0xda, 0x6b, 0xf5, 0x6b, 0xe2, 0x47, 0x6a, 0xa3, + 0x14, 0xf5, 0x03, 0x4f, 0x20, 0xf5, 0x55, 0x50, 0x6d, 0xcd, 0x54, 0x75, 0x04, 0x1d, 0x13, 0xbc, + 0x47, 0x88, 0x31, 0xd5, 0x57, 0xc4, 0x56, 0x23, 0xee, 0xed, 0x8a, 0xfe, 0x5b, 0x69, 0xd3, 0x2f, + 0x25, 0xdf, 0x7c, 0xd7, 0x7d, 0x62, 0x01, 0x41, 0x39, 0xe8, 0xfb, 0xd7, 0xcd, 0x56, 0x46, 0xc6, + 0x9a, 0xf2, 0x9e, 0xb5, 0xf0, 0x45, 0xd5, 0x5f, 0xe1, 0x39, 0x4c, 0x4c, 0x2a, 0xd9, 0xac, 0x1d, + 0x41, 0xfb, 0x8e, 0x5c, 0x32, 0x5c, 0x5e, 0x2a, 0xdb, 0xbb, 0xbd, 0xc6, 0xda, 0x3d, 0xd5, 0x57, + 0xe6, 0xbb, 0xbb, 0x93, 0x85, 0xc6, 0x5d, 0x3c, 0xda, 0xbb, 0x5b, 0x0e, 0x29, 0x1f, 0xc1, 0x2f, + 0x43, 0x7f, 0x3f, 0x35, 0x86, 0xc8, 0xa8, 0x14, 0x1b, 0x17, 0x05, 0x3a, 0xba, 0x49, 0x34, 0xd2, + 0x4d, 0xb5, 0xb7, 0xc9, 0x9e, 0x1f, 0x82, 0x39, 0xb7, 0xf5, 0x73, 0x5d, 0xee, 0x5e, 0xc7, 0x6e, + 0xe0, 0xc7, 0x10, 0x85, 0xbd, 0xf2, 0x77, 0x77, 0xd0, 0xca, 0x81, 0x93, 0x11, 0x7c, 0xa5, 0xdd, + 0xc1, 0x76, 0x10, 0x82, 0x6e, 0x63, 0x4d, 0xeb, 0xee, 0xb5, 0x9f, 0x98, 0x7a, 0xea, 0x37, 0x98, + 0x56, 0xe5, 0xcf, 0x35, 0xef, 0x11, 0xd5, 0xfe, 0x5a, 0xea, 0x78, 0x00, 0x00, 0x00, 0x01, 0x41, + 0x9a, 0x10, 0x08, 0x30, 0x36, 0x9f, 0x30, 0xb4, 0xe9, 0xfd, 0x1c, 0x02, 0x5f, 0x42, 0x32, 0x75, + 0xe0, 0x86, 0x7c, 0x8c, 0xd8, 0xec, 0x7f, 0xae, 0x50, 0x94, 0x4c, 0x30, 0x53, 0x61, 0xb0, 0xf8, + 0xfd, 0x6a, 0xd6, 0xa6, 0x54, 0x76, 0xf8, 0x2f, 0x86, 0xf7, 0x1d, 0x97, 0x88, 0x86, 0x08, 0x7b, + 0x1c, 0x33, 0x45, 0x17, 0x86, 0xd4, 0xab, 0xe1, 0x56, 0x89, 0x98, 0x01, 0x39, 0xc2, 0x24, 0x49, + 0x67, 0x25, 0xbe, 0xa4, 0xa9, 0xa5, 0x59, 0xa7, 0x11, 0x0d, 0x89, 0x3f, 0xf1, 0x5a, 0x1d, 0x91, + 0xb7, 0xdc, 0xcf, 0xd1, 0xc2, 0x1c, 0x41, 0xd8, 0x61, 0xed, 0x24, 0x1f, 0x05, 0x6f, 0x7c, 0x26, + 0xd1, 0x85, 0x79, 0xe3, 0x92, 0xa6, 0x9a, 0x69, 0xf9, 0xba, 0x1c, 0x99, 0x13, 0xad, 0x57, 0x45, + 0x22, 0x44, 0xf5, 0xc9, 0x92, 0xeb, 0x5f, 0x54, 0xab, 0xd4, 0xab, 0x3e, 0xb9, 0x5f, 0x24, 0xf8, + 0x7c, 0x36, 0x3b, 0x3c, 0x2e, 0x30, 0xb8, 0xd6, 0x64, 0x04, 0x3a, 0x63, 0x2d, 0x86, 0x53, 0x79, + 0xa9, 0xe3, 0x32, 0x36, 0xd4, 0x89, 0x90, 0xf0, 0xa1, 0xa5, 0x46, 0x21, 0x28, 0x1e, 0xae, 0x0c, + 0x13, 0x36, 0xc8, 0xfa, 0xf0, 0x1d, 0x48, 0xe9, 0x76, 0xc0, 0x66, 0xcc, 0x3a, 0xff, 0x43, 0x4c, + 0x9c, 0xc5, 0x36, 0x7c, 0x15, 0x84, 0xe4, 0x99, 0xa2, 0xcd, 0xe4, 0xce, 0x2f, 0x11, 0x0a, 0xf5, + 0x48, 0xbd, 0x52, 0x25, 0xd6, 0x91, 0x7a, 0xa6, 0x5e, 0xb1, 0x44, 0xf6, 0x31, 0x55, 0x54, 0x57, + 0x20, 0xb7, 0x75, 0x57, 0xd1, 0x1f, 0xeb, 0xd5, 0xc1, 0x51, 0xb7, 0x7b, 0xb7, 0x8b, 0xad, 0x8f, + 0x82, 0x91, 0xcc, 0x63, 0xa5, 0x68, 0x1a, 0x6e, 0x2a, 0xc9, 0x4a, 0x58, 0x7c, 0x21, 0x3a, 0x5e, + 0x69, 0x8d, 0xab, 0x37, 0x8c, 0xd1, 0xd7, 0xa7, 0xfe, 0x83, 0x22, 0x3a, 0x71, 0x01, 0x09, 0x3b, + 0xba, 0xba, 0x93, 0x98, 0x89, 0xd5, 0xd7, 0x45, 0x1e, 0x51, 0x7d, 0x13, 0xab, 0xae, 0x10, 0xc7, + 0x46, 0xef, 0xa2, 0xb5, 0x74, 0x21, 0x95, 0xd8, 0x42, 0xe5, 0xf8, 0xbe, 0x82, 0xfd, 0x01, 0x21, + 0xd6, 0x57, 0xd7, 0x2b, 0xe6, 0x19, 0x42, 0x8d, 0x26, 0x78, 0x86, 0x2a, 0xcd, 0x37, 0xe2, 0x22, + 0x3a, 0x0b, 0xb7, 0xd4, 0xea, 0x82, 0xbe, 0x28, 0x45, 0x65, 0x33, 0x4c, 0xde, 0x32, 0xf0, 0x98, + 0xeb, 0x6f, 0xd3, 0x57, 0xcb, 0x77, 0xd0, 0x85, 0x85, 0x7a, 0x09, 0xb2, 0x18, 0xe4, 0x09, 0x29, + 0xf2, 0x98, 0x23, 0xe8, 0x36, 0xd3, 0xf5, 0x1f, 0x45, 0x70, 0x52, 0x2a, 0x95, 0xd2, 0x9b, 0x18, + 0xac, 0xa5, 0x6c, 0xbe, 0x30, 0x85, 0x32, 0x52, 0x4c, 0x5d, 0x4b, 0x30, 0xe2, 0x18, 0xd4, 0xfa, + 0xef, 0x52, 0xc3, 0x22, 0x3a, 0xb2, 0xee, 0x07, 0xd2, 0xca, 0xce, 0x75, 0xf8, 0x50, 0x99, 0x88, + 0x2f, 0x6a, 0xcd, 0xc6, 0x86, 0xcf, 0x53, 0x98, 0xbd, 0x37, 0x74, 0x24, 0x66, 0x57, 0xc6, 0xd2, + 0x0a, 0x2a, 0xd5, 0xbd, 0x1e, 0xa1, 0xae, 0xad, 0x73, 0xee, 0xb9, 0x29, 0x06, 0x0b, 0x49, 0x4d, + 0xa9, 0xed, 0x9f, 0xfe, 0x23, 0x73, 0x6d, 0x5a, 0x4b, 0xe4, 0xaa, 0xd5, 0x71, 0x24, 0xbd, 0x10, + 0xde, 0x3a, 0xbe, 0x83, 0x3d, 0xf5, 0xe5, 0x5e, 0xa7, 0x45, 0x4f, 0x89, 0x26, 0x5c, 0xe5, 0xc8, + 0x43, 0xa3, 0x8e, 0xd0, 0xc7, 0x30, 0x42, 0x26, 0xcc, 0x67, 0x1e, 0x2c, 0x47, 0x1a, 0xad, 0xaf, + 0x8c, 0x2c, 0x84, 0x16, 0x7b, 0x1b, 0xe6, 0x51, 0x36, 0xdd, 0x75, 0xc7, 0x11, 0x69, 0xda, 0xad, + 0x57, 0xf0, 0x48, 0x7a, 0xd5, 0xe0, 0xc7, 0xa3, 0x77, 0xc8, 0x45, 0xa2, 0x31, 0xb7, 0xd9, 0xc5, + 0x6e, 0xff, 0x09, 0xea, 0x5c, 0x8a, 0x5d, 0xba, 0xe6, 0x11, 0x7b, 0x8c, 0xe8, 0x33, 0xa8, 0x22, + 0xe0, 0x87, 0xbb, 0xe5, 0xf4, 0x12, 0xef, 0x8a, 0x35, 0x39, 0xaa, 0x93, 0xf1, 0x13, 0x83, 0xbe, + 0x10, 0xe3, 0xcd, 0x7c, 0xd5, 0xdf, 0x5e, 0x24, 0x10, 0xd6, 0x3b, 0xdf, 0x7c, 0xd6, 0x11, 0xc6, + 0x12, 0x21, 0x50, 0x58, 0xae, 0xc4, 0xad, 0x60, 0x9f, 0xa1, 0x6c, 0x45, 0x70, 0x88, 0x4a, 0x34, + 0x66, 0x75, 0x3a, 0xaf, 0x90, 0x44, 0xd4, 0x75, 0x3c, 0x45, 0xc2, 0x11, 0xd9, 0x1d, 0xbf, 0x8f, + 0xe2, 0x5f, 0x71, 0xc1, 0xc1, 0xd1, 0xdf, 0x15, 0xdd, 0xdd, 0xf0, 0x30, 0xf4, 0x0b, 0x5c, 0xbe, + 0x2c, 0x3c, 0xcf, 0x55, 0xb5, 0xf0, 0x4a, 0x4b, 0x35, 0x84, 0x9d, 0xd5, 0x52, 0xb1, 0xc7, 0xbf, + 0xc6, 0x12, 0x3b, 0xc6, 0x3d, 0x31, 0x62, 0x7b, 0x11, 0x65, 0x4b, 0x3f, 0x6f, 0xc4, 0x9c, 0x5a, + 0x35, 0xb5, 0x59, 0xb3, 0x76, 0x0f, 0x7b, 0x89, 0x29, 0x51, 0xa3, 0x49, 0x2f, 0x08, 0x95, 0xdf, + 0x77, 0x1b, 0x65, 0x55, 0xee, 0x4c, 0x41, 0x0c, 0xbb, 0x5e, 0x28, 0x43, 0xc5, 0x78, 0xaf, 0xf2, + 0x95, 0xe2, 0xb2, 0xe0, 0x67, 0xa1, 0xf9, 0x46, 0xf2, 0x88, 0x55, 0xdf, 0x2d, 0xcd, 0x81, 0xf9, + 0xf1, 0xd7, 0x17, 0x55, 0xad, 0xaa, 0x5e, 0x09, 0x0d, 0x5b, 0xb1, 0xf1, 0xd8, 0xed, 0x13, 0xeb, + 0xb7, 0x27, 0xff, 0x21, 0x75, 0x5f, 0x45, 0x6f, 0x84, 0xb9, 0xfd, 0xef, 0x58, 0x82, 0x16, 0xb5, + 0x27, 0x10, 0x10, 0x72, 0xdd, 0xcb, 0x8f, 0xbf, 0x8b, 0xde, 0x8f, 0x2d, 0x20, 0x9f, 0x85, 0x0b, + 0x2f, 0x7e, 0xd3, 0x78, 0xad, 0x3b, 0x6a, 0xcb, 0x5f, 0x57, 0xae, 0x63, 0xe9, 0xa5, 0xe0, 0xa4, + 0x67, 0x1e, 0x98, 0xdc, 0x41, 0x27, 0x4d, 0x58, 0xc1, 0x4e, 0xdc, 0x3c, 0x4d, 0x70, 0x46, 0x11, + 0x77, 0xdf, 0xe0, 0xae, 0xab, 0xb0, 0xd6, 0xaa, 0x4c, 0x60, 0xfe, 0xf9, 0x6e, 0xed, 0x3f, 0x9a, + 0xaa, 0xaa, 0xf8, 0x83, 0x2d, 0x65, 0xc6, 0xff, 0x09, 0x88, 0x76, 0x9c, 0xd3, 0xab, 0xaf, 0x89, + 0xdd, 0x94, 0xf5, 0x4f, 0x85, 0xba, 0x1b, 0xab, 0xe0, 0x84, 0x5a, 0x49, 0x34, 0xd2, 0x75, 0xe8, + 0x8c, 0x44, 0x70, 0x49, 0x56, 0xd5, 0xbc, 0x2b, 0x88, 0x1c, 0xb5, 0xaa, 0xaa, 0xf1, 0x00, 0x8a, + 0xee, 0xf7, 0xf1, 0x15, 0xc2, 0x3e, 0x6b, 0xe6, 0xc6, 0x9f, 0x93, 0xf8, 0x29, 0xa0, 0xd8, 0xeb, + 0x6d, 0xeb, 0x8a, 0xd1, 0xf5, 0xc7, 0x88, 0x8b, 0xae, 0xcd, 0xff, 0x11, 0xb3, 0x37, 0xdb, 0x91, + 0x9f, 0x94, 0x4b, 0xdb, 0x55, 0xc5, 0xeb, 0x55, 0xd5, 0x72, 0xd8, 0x1b, 0x03, 0x30, 0x81, 0x92, + 0xf3, 0x55, 0x55, 0x7c, 0x61, 0x0f, 0x82, 0x5c, 0xb9, 0xf8, 0x49, 0xfb, 0xbc, 0xf9, 0xd3, 0x9b, + 0x2b, 0xf0, 0x4e, 0x23, 0x55, 0x6d, 0x77, 0xf8, 0x23, 0x3a, 0x14, 0x65, 0x21, 0xd9, 0x94, 0x31, + 0xd0, 0x9e, 0x88, 0xe1, 0x23, 0x35, 0x5a, 0xd6, 0xfd, 0x71, 0x65, 0xdd, 0xee, 0xe5, 0xfe, 0x28, + 0x54, 0x65, 0x4b, 0x85, 0xb1, 0x03, 0xed, 0xfe, 0x08, 0x79, 0xf5, 0xbd, 0xde, 0x20, 0x11, 0x9d, + 0xf5, 0x7f, 0x97, 0xbb, 0xf8, 0x4c, 0xea, 0xbe, 0xe5, 0xc5, 0xc2, 0x5a, 0xd6, 0xab, 0xf1, 0x15, + 0x55, 0xa5, 0x6b, 0xe2, 0x4c, 0xb5, 0x55, 0x55, 0x5f, 0x31, 0xdd, 0xdd, 0xfc, 0x9a, 0xaa, 0xf9, + 0x8d, 0x39, 0xab, 0xf1, 0x1f, 0x09, 0x89, 0x67, 0x66, 0x6b, 0xaa, 0x5f, 0x7c, 0x96, 0x62, 0x2b, + 0xa1, 0xcd, 0xf0, 0x43, 0xc8, 0xbb, 0xcf, 0x0f, 0x73, 0x09, 0x54, 0xee, 0xbb, 0xbe, 0xef, 0x11, + 0x5c, 0x16, 0x99, 0xf7, 0x54, 0xc9, 0xed, 0xfe, 0x10, 0xbd, 0xef, 0x76, 0xd5, 0x6b, 0xe2, 0xca, + 0xba, 0xb7, 0x6d, 0x3f, 0x62, 0x5b, 0x8b, 0xfd, 0x91, 0xf7, 0xe2, 0x09, 0x77, 0xfd, 0xea, 0xab, + 0xe0, 0x90, 0x9b, 0xbb, 0xfc, 0xb1, 0x5f, 0x34, 0x4c, 0x40, 0x94, 0x6b, 0x19, 0x94, 0x92, 0x57, + 0xc4, 0xc4, 0xdd, 0xdd, 0xea, 0x59, 0xeb, 0xa1, 0xc6, 0x04, 0x3b, 0xd0, 0xf8, 0xbe, 0x41, 0x04, + 0xfe, 0xf9, 0x37, 0xba, 0xe5, 0x28, 0x97, 0xdf, 0xe6, 0xdd, 0xcb, 0xfc, 0x49, 0x15, 0xd5, 0xe5, + 0xff, 0xad, 0x7c, 0x7d, 0x56, 0xa4, 0xfc, 0xcc, 0xc3, 0xef, 0x90, 0x4a, 0xaf, 0x89, 0x90, 0x46, + 0xee, 0x6e, 0x3c, 0xf5, 0x6a, 0xab, 0xa5, 0x5f, 0x8a, 0x25, 0x2a, 0xb5, 0x4b, 0x88, 0x89, 0x13, + 0xcd, 0x94, 0x96, 0xa2, 0x60, 0xb2, 0xfb, 0xa1, 0x39, 0x73, 0x3a, 0x4a, 0x6f, 0xea, 0xe4, 0x1c, + 0xf7, 0x4f, 0xc1, 0x2d, 0xa9, 0x25, 0x3e, 0x1e, 0xf9, 0x4f, 0xd0, 0x9a, 0x85, 0x39, 0x8d, 0x6e, + 0x6f, 0xe1, 0x9b, 0x6f, 0xa8, 0x9c, 0x22, 0xff, 0x5c, 0xa7, 0xaa, 0xfc, 0x11, 0x75, 0x57, 0xf9, + 0x85, 0x5d, 0x36, 0x45, 0xc4, 0x02, 0x71, 0x68, 0x74, 0x37, 0xb1, 0xdf, 0xa6, 0xee, 0xee, 0xef, + 0xe3, 0xcb, 0xbb, 0xbb, 0xbd, 0x69, 0x56, 0x23, 0xc4, 0x02, 0xbb, 0x49, 0x22, 0xbb, 0x1b, 0x4d, + 0xaa, 0x98, 0x63, 0x53, 0x1c, 0x4c, 0x59, 0x1f, 0x43, 0xdd, 0x8d, 0x72, 0xd6, 0x94, 0x9c, 0x50, + 0x8b, 0xbb, 0xde, 0xfe, 0x8b, 0x94, 0x35, 0xc9, 0xad, 0x42, 0x9d, 0x15, 0xf8, 0x99, 0xa8, 0x8e, + 0x92, 0x88, 0xfc, 0xc2, 0x9f, 0x70, 0xd7, 0x31, 0x5b, 0xb7, 0x2e, 0x23, 0xc4, 0x3e, 0xaa, 0x5e, + 0x08, 0x85, 0xee, 0xff, 0xbe, 0x43, 0x3d, 0xeb, 0x88, 0xde, 0xd3, 0xda, 0xae, 0x42, 0xb0, 0xb2, + 0x53, 0xcd, 0x3e, 0x57, 0xe0, 0x9f, 0x55, 0x8c, 0xc6, 0xfd, 0xeb, 0xaf, 0x7c, 0x27, 0xd5, 0x12, + 0xae, 0x5e, 0xb2, 0xf9, 0x46, 0x3d, 0xe3, 0x3a, 0x16, 0xc4, 0x77, 0x10, 0x4b, 0xdd, 0xf5, 0x26, + 0x24, 0xc5, 0xaa, 0xd6, 0x20, 0x11, 0x99, 0x55, 0x55, 0xbc, 0x40, 0x23, 0x3d, 0x6b, 0xef, 0xbf, + 0x2f, 0x5c, 0xbb, 0xbf, 0xdd, 0x3b, 0xd7, 0x37, 0x55, 0x7c, 0x55, 0xac, 0xf5, 0xba, 0x4b, 0xe2, + 0x77, 0x41, 0x26, 0x5c, 0xfa, 0xe0, 0x8a, 0xf4, 0xdd, 0xfe, 0x08, 0xf2, 0x06, 0x37, 0x7b, 0xe4, + 0x3d, 0xdf, 0xee, 0x95, 0xdf, 0x88, 0xf9, 0x2e, 0xfa, 0xe0, 0x88, 0x73, 0xae, 0x71, 0x7c, 0x4d, + 0x64, 0xf3, 0x3e, 0x86, 0x98, 0x53, 0xa1, 0x2e, 0x49, 0xc4, 0x88, 0x77, 0xbd, 0xef, 0xe2, 0xaf, + 0xbb, 0xef, 0xe5, 0x3b, 0xe7, 0x49, 0xe6, 0x3d, 0x53, 0x6d, 0x75, 0xe9, 0x71, 0x05, 0x11, 0xcc, + 0xc1, 0x79, 0x4f, 0x6e, 0xdb, 0xef, 0x25, 0x35, 0xcd, 0x7b, 0xc9, 0x88, 0xff, 0x89, 0x93, 0x98, + 0x52, 0xaa, 0xc2, 0xbc, 0x12, 0x09, 0x5d, 0x5e, 0x5e, 0x24, 0x51, 0x44, 0x0c, 0x2b, 0xcb, 0x17, + 0xfc, 0x24, 0x35, 0x36, 0x48, 0xac, 0x73, 0x31, 0x7c, 0x4d, 0x57, 0xaa, 0xa7, 0xe2, 0x2b, 0x55, + 0xaa, 0xfc, 0x56, 0xb5, 0xc8, 0x41, 0x4d, 0xf3, 0x6a, 0xab, 0xeb, 0xd7, 0x89, 0xf8, 0xeb, 0x9d, + 0x86, 0xed, 0x8e, 0xe7, 0x62, 0x9a, 0xd6, 0x23, 0xc4, 0x5f, 0x2d, 0x75, 0xe2, 0x2b, 0x12, 0x89, + 0x57, 0xc9, 0x55, 0xf8, 0x8f, 0x82, 0x2b, 0xb1, 0xcb, 0xa5, 0x07, 0xd5, 0x80, 0x67, 0x84, 0x85, + 0x66, 0x63, 0x5a, 0xf8, 0xc1, 0xee, 0xda, 0x23, 0x43, 0x9b, 0xb7, 0x3b, 0x6c, 0x48, 0xd7, 0xe6, + 0xad, 0x6b, 0x11, 0x58, 0x8f, 0xa2, 0x3d, 0xf2, 0x14, 0x8a, 0x36, 0x2e, 0x23, 0xe1, 0x32, 0xbd, + 0x09, 0xb2, 0x8d, 0xb1, 0xb1, 0x9d, 0xf8, 0x98, 0xcb, 0x19, 0x99, 0x8e, 0x5d, 0x32, 0x9e, 0x86, + 0xfa, 0xfa, 0x72, 0x30, 0xd6, 0xb9, 0x27, 0x61, 0x8c, 0xec, 0x51, 0xf8, 0x4b, 0xc7, 0x4b, 0x14, + 0xdb, 0x4d, 0xbc, 0x48, 0x97, 0xb1, 0xac, 0x5a, 0x1f, 0x92, 0xef, 0xf1, 0x26, 0x25, 0xee, 0x5c, + 0x4d, 0x72, 0xd6, 0xab, 0xc4, 0x78, 0x8f, 0xb1, 0x0e, 0xb8, 0x4f, 0xa2, 0xc1, 0xf0, 0x90, 0x87, + 0xbd, 0xa8, 0xdd, 0x5f, 0xb2, 0xb9, 0xf3, 0x7c, 0xdb, 0x43, 0x92, 0xbf, 0x13, 0x6c, 0xd4, 0xa6, + 0x14, 0xaf, 0xd7, 0x28, 0x96, 0x33, 0xbd, 0x0e, 0x0f, 0xc8, 0x56, 0x4a, 0x68, 0x42, 0x58, 0x83, + 0x6a, 0xc7, 0xf2, 0xcf, 0xdd, 0xdd, 0xe2, 0x2b, 0x11, 0xe2, 0x17, 0xbe, 0x6a, 0xae, 0xf1, 0x04, + 0x22, 0x1a, 0x1a, 0x1a, 0x1f, 0x10, 0xcb, 0x2f, 0xf8, 0x8a, 0xe2, 0xc5, 0x65, 0xc1, 0x5d, 0xd2, + 0x93, 0x9b, 0x77, 0xf9, 0x6f, 0x77, 0xf2, 0x1d, 0x57, 0xe2, 0x49, 0xc5, 0xfc, 0x47, 0xd1, 0xb5, + 0xf2, 0xd1, 0x42, 0xfa, 0x6b, 0xa1, 0x7a, 0x96, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x11, 0x08, + 0xb0, 0x3e, 0xbc, 0x83, 0xf1, 0x8a, 0x6f, 0xa8, 0x0b, 0x7c, 0x12, 0x18, 0x8a, 0x4d, 0xfc, 0x9d, + 0x78, 0x2e, 0xce, 0xdf, 0x8d, 0x51, 0x18, 0xfd, 0x72, 0xf9, 0xc5, 0x29, 0x61, 0x48, 0xcf, 0xa5, + 0xe1, 0x1e, 0x09, 0x06, 0xb5, 0x60, 0xd3, 0xf0, 0xf0, 0xc6, 0x3c, 0x08, 0x08, 0x21, 0x39, 0xa7, + 0x6a, 0x0d, 0xa1, 0x07, 0x66, 0xd5, 0x41, 0xa4, 0xc7, 0x3f, 0x05, 0x59, 0x12, 0x33, 0x0d, 0x4b, + 0xc7, 0xa6, 0xff, 0x0c, 0x1c, 0x8b, 0xff, 0x8e, 0xbe, 0x57, 0x34, 0x6f, 0xc6, 0x32, 0x28, 0x6f, + 0xff, 0x9e, 0xbe, 0x3f, 0xbf, 0x11, 0xd9, 0x31, 0x96, 0x85, 0x2d, 0x01, 0x3e, 0x88, 0x95, 0x79, + 0x4c, 0x3e, 0xc6, 0xaa, 0xfe, 0x37, 0x3b, 0x74, 0x0c, 0xd8, 0x8f, 0x65, 0x2a, 0xdc, 0x84, 0x12, + 0x10, 0x72, 0x94, 0xc4, 0x66, 0x4b, 0x4c, 0x7f, 0xc3, 0x7c, 0xdf, 0x9c, 0xff, 0x4c, 0x57, 0xe0, + 0xb8, 0x4b, 0x4c, 0x04, 0x89, 0xbb, 0x69, 0x47, 0xd5, 0xd4, 0xe9, 0xf4, 0x33, 0x5f, 0x09, 0x5d, + 0xd5, 0x76, 0x6f, 0xe3, 0x87, 0x8f, 0xf9, 0x7f, 0xbd, 0x7f, 0x97, 0xfb, 0xc7, 0xd8, 0xae, 0x68, + 0xd5, 0x7b, 0xc1, 0x2d, 0x7f, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, 0xbc, 0xcb, 0x25, 0xe1, 0x5e, 0x32, + 0xd0, 0xa5, 0xa3, 0x52, 0xd0, 0xa5, 0xa0, 0x74, 0x89, 0x68, 0xc6, 0x8c, 0x68, 0xba, 0xdd, 0xc5, + 0xa1, 0x6b, 0xc6, 0xf5, 0x5e, 0x55, 0xed, 0x57, 0x95, 0x7b, 0xc6, 0xbc, 0xab, 0xde, 0xab, 0xca, + 0xbc, 0x64, 0xe4, 0xd2, 0x6f, 0xf8, 0x7e, 0x3f, 0xe5, 0xfe, 0xf1, 0xff, 0x2f, 0xf7, 0xaf, 0xf2, + 0xff, 0x78, 0xda, 0x2a, 0xfc, 0xda, 0x6d, 0xf0, 0x57, 0xc7, 0x7c, 0xb7, 0xde, 0x3b, 0xe5, 0xbe, + 0xd6, 0xf9, 0x6f, 0x91, 0x2d, 0x78, 0x30, 0x8f, 0xf9, 0x7f, 0xbc, 0x7f, 0xcb, 0xfd, 0xe2, 0x5a, + 0x11, 0xd7, 0xb6, 0xd9, 0x4d, 0x34, 0xd7, 0x87, 0xb8, 0xd7, 0xb1, 0xda, 0x7f, 0x1a, 0xf2, 0xaf, + 0x0e, 0x94, 0xfa, 0x7d, 0x29, 0xa6, 0x9a, 0xff, 0x45, 0x4a, 0x9f, 0x1a, 0x3a, 0x4c, 0x58, 0x32, + 0x64, 0x4c, 0x82, 0x2a, 0x27, 0xd0, 0xb6, 0x81, 0xa3, 0xac, 0xc5, 0xe5, 0xeb, 0x25, 0x62, 0xe4, + 0x55, 0x6d, 0x65, 0x26, 0x9c, 0x41, 0x5c, 0x7b, 0xa6, 0x79, 0x70, 0x4e, 0x38, 0x0d, 0xc1, 0xec, + 0x8c, 0x27, 0x6f, 0x12, 0x16, 0x73, 0xcc, 0x81, 0x3b, 0xa9, 0xed, 0x32, 0x9b, 0xd7, 0xcf, 0x1a, + 0x20, 0x95, 0xf6, 0xa9, 0x19, 0xa4, 0x07, 0xe8, 0x8f, 0x45, 0xf1, 0x37, 0x35, 0x20, 0x1d, 0xf2, + 0x13, 0xee, 0xff, 0x94, 0x1c, 0x73, 0x4e, 0x10, 0xcc, 0x68, 0xf6, 0xb1, 0x9e, 0x50, 0x51, 0x8b, + 0xec, 0x0b, 0xb1, 0xce, 0x62, 0x23, 0x00, 0x44, 0x68, 0xc5, 0x7c, 0x0f, 0x3c, 0x54, 0x23, 0xd5, + 0xe0, 0xdd, 0xa1, 0x78, 0x28, 0x4e, 0x57, 0x4f, 0xa2, 0x2d, 0x7f, 0xfc, 0x3a, 0x13, 0x6e, 0x7e, + 0xe2, 0x15, 0xad, 0x15, 0xfe, 0x2a, 0x72, 0xba, 0x91, 0xc6, 0x45, 0xe7, 0x04, 0x4e, 0xb8, 0x3f, + 0x40, 0x75, 0x3b, 0xf2, 0x9b, 0xc4, 0x16, 0xe3, 0x73, 0xd7, 0x87, 0x39, 0x67, 0x4d, 0x7f, 0x1b, + 0xea, 0x9a, 0x15, 0x34, 0x6a, 0x9a, 0x15, 0x34, 0x78, 0xef, 0x96, 0xfb, 0xd6, 0xf9, 0x6f, 0x92, + 0xaf, 0xf3, 0x69, 0xb7, 0xce, 0x72, 0x24, 0x7a, 0x5a, 0xe9, 0x7f, 0xfe, 0x79, 0x12, 0xba, 0x5a, + 0xe9, 0x7f, 0xef, 0x9e, 0xa1, 0xc6, 0xbe, 0xfc, 0x33, 0x13, 0xe0, 0xc8, 0xd9, 0xf5, 0xcf, 0x4e, + 0xbc, 0x66, 0x5a, 0x99, 0x7e, 0xb9, 0xe9, 0xd7, 0x8c, 0xcb, 0x53, 0x2f, 0xd7, 0x44, 0x22, 0x7d, + 0x53, 0xa3, 0xf5, 0x2d, 0x5c, 0x31, 0x8f, 0xfb, 0xaf, 0xf2, 0xff, 0x7a, 0x22, 0xd7, 0x8a, 0xa1, + 0x55, 0xc2, 0x0b, 0x10, 0x00, 0x48, 0x92, 0x1a, 0x21, 0xa1, 0x56, 0x5a, 0xff, 0xc2, 0xbc, 0x77, + 0xcb, 0x7d, 0xad, 0xf2, 0xdf, 0x15, 0x15, 0x66, 0xd3, 0x6f, 0xf8, 0x77, 0x1a, 0xa6, 0xaa, 0x8b, + 0xfc, 0xbf, 0xde, 0x3f, 0xe5, 0xfe, 0xf0, 0x4e, 0x22, 0xd1, 0x34, 0x30, 0xf6, 0xd8, 0x0a, 0xa1, + 0x55, 0xfa, 0x22, 0x55, 0xe0, 0x96, 0xd3, 0x48, 0x1a, 0x06, 0xd3, 0x48, 0x1a, 0x06, 0x3c, 0xa2, + 0x7b, 0x14, 0xd3, 0x49, 0x24, 0x2b, 0x90, 0x5b, 0xb1, 0xd8, 0x7c, 0x7e, 0x3e, 0x72, 0x23, 0xbf, + 0x6d, 0xb6, 0xdb, 0xf3, 0xc7, 0x6a, 0x69, 0xa6, 0x9f, 0xf1, 0x3f, 0x1a, 0x67, 0x7e, 0x8d, 0xa8, + 0x18, 0xe3, 0x3e, 0x3e, 0xa7, 0xd9, 0x18, 0x14, 0xcf, 0x8c, 0xbb, 0xc8, 0xa1, 0x2f, 0x1c, 0x9f, + 0xc6, 0x8e, 0x5c, 0x80, 0xf2, 0xc3, 0x30, 0x90, 0xf1, 0x07, 0x40, 0x6e, 0x37, 0xf8, 0x33, 0x21, + 0x5a, 0x25, 0xc4, 0x6a, 0xfa, 0xf7, 0x1a, 0xa9, 0x7c, 0xb3, 0x0d, 0xa9, 0x7f, 0xcf, 0xd1, 0x2b, + 0x1f, 0xf8, 0xdb, 0xe8, 0x12, 0x37, 0xe7, 0xbf, 0xd2, 0x41, 0x80, 0x6a, 0xc5, 0xf5, 0x3f, 0xef, + 0x9c, 0x26, 0x29, 0xb8, 0x64, 0xd3, 0xf3, 0x3b, 0xe3, 0x1f, 0x8f, 0x53, 0xdd, 0x92, 0xe2, 0x72, + 0xdf, 0x09, 0xcd, 0x41, 0x94, 0x9e, 0x91, 0x69, 0xe1, 0xf0, 0xcf, 0xb4, 0xd6, 0xd3, 0x5b, 0x4d, + 0x55, 0x34, 0xe3, 0x4f, 0xfd, 0x72, 0x93, 0xb9, 0xb9, 0xf9, 0xbb, 0xf9, 0x39, 0x88, 0x1a, 0x77, + 0xab, 0x8e, 0x5c, 0xf6, 0x35, 0x73, 0x94, 0x71, 0x2a, 0x69, 0xa6, 0x9f, 0x8b, 0xe8, 0x9d, 0xf5, + 0x32, 0x7d, 0x4e, 0x0a, 0xe1, 0x4b, 0x4d, 0x24, 0x93, 0x4d, 0x24, 0x93, 0x4d, 0x30, 0x6c, 0x1b, + 0x4d, 0x30, 0x6c, 0x1e, 0x55, 0xd0, 0xa7, 0xfa, 0x2b, 0xcb, 0xd4, 0xc9, 0x1b, 0xd1, 0xcf, 0x7c, + 0x14, 0x18, 0xb9, 0xf3, 0x61, 0x89, 0x71, 0x4b, 0xf4, 0x54, 0x8b, 0xdf, 0x71, 0x5f, 0x86, 0x8c, + 0xc7, 0x1c, 0x43, 0x82, 0x2b, 0xdc, 0x57, 0x64, 0xb0, 0xa4, 0x87, 0x10, 0x14, 0x09, 0x31, 0x42, + 0x38, 0x20, 0xfa, 0x9e, 0x12, 0x50, 0x2e, 0xa7, 0x05, 0x35, 0xfe, 0x0e, 0xa9, 0xcf, 0x07, 0xab, + 0x84, 0x0f, 0x95, 0x09, 0xf0, 0xa7, 0xa2, 0xb6, 0xc4, 0x56, 0x8d, 0x07, 0xaf, 0x76, 0xe3, 0x45, + 0xc4, 0x9d, 0x84, 0x74, 0x4e, 0x79, 0x1d, 0xb1, 0xaf, 0xcf, 0xdf, 0x91, 0x41, 0xef, 0x82, 0x20, + 0xa8, 0xcf, 0xa2, 0x6d, 0x2c, 0x8b, 0xae, 0xa6, 0x44, 0x44, 0xe0, 0x90, 0x42, 0x20, 0x40, 0xf3, + 0x33, 0x9a, 0x31, 0xb5, 0x1d, 0x96, 0xe3, 0x7c, 0x16, 0x0a, 0x6a, 0x91, 0x7c, 0x98, 0x10, 0x0f, + 0x5f, 0x71, 0xb0, 0x74, 0x5e, 0xbc, 0x65, 0x2c, 0x56, 0x67, 0xa2, 0x03, 0xa9, 0xb5, 0x29, 0x26, + 0xe2, 0x49, 0xd6, 0x9f, 0x85, 0x29, 0x4a, 0x32, 0x94, 0x74, 0x40, 0x87, 0xaf, 0x29, 0x4c, 0x68, + 0x28, 0x35, 0x9c, 0xe1, 0x18, 0x3b, 0xb9, 0x1a, 0xbd, 0x55, 0xd8, 0xed, 0xf0, 0x5c, 0x15, 0x2d, + 0x62, 0x2a, 0x10, 0xae, 0xb1, 0x5a, 0x67, 0x97, 0x3f, 0x0e, 0xf3, 0x1b, 0x77, 0x13, 0xc1, 0x1d, + 0x77, 0x20, 0x1c, 0x23, 0x94, 0xa4, 0x11, 0x8a, 0xcf, 0xaa, 0x45, 0xe0, 0x86, 0xef, 0x9d, 0x6f, + 0x82, 0xb0, 0xa7, 0x96, 0xb3, 0xc3, 0x9b, 0x10, 0x6a, 0x50, 0x4f, 0xe2, 0x02, 0x57, 0x82, 0x64, + 0x76, 0x28, 0xdb, 0x97, 0xe8, 0x2a, 0xf2, 0x70, 0x48, 0x2b, 0x34, 0x97, 0xbe, 0x61, 0x1c, 0x69, + 0xa3, 0xc2, 0x64, 0xbd, 0xdd, 0xff, 0x04, 0xa5, 0x54, 0xd5, 0x6f, 0x6b, 0xab, 0x88, 0xbb, 0xa4, + 0xfe, 0x93, 0xff, 0x41, 0x3f, 0xf8, 0x95, 0x78, 0xfc, 0x42, 0xfe, 0x17, 0xe8, 0xcc, 0x93, 0x10, + 0x82, 0x8d, 0xf2, 0x8f, 0xdd, 0xdf, 0x36, 0xf7, 0x08, 0x73, 0x5d, 0xdd, 0xc3, 0xdd, 0x17, 0x28, + 0xde, 0xad, 0x05, 0xdd, 0x84, 0x1e, 0xf0, 0xef, 0x41, 0x37, 0x42, 0xf8, 0x93, 0x19, 0x5d, 0x8d, + 0x9f, 0xb1, 0x83, 0x6b, 0x3f, 0x88, 0x13, 0x19, 0x4c, 0x7d, 0x35, 0xd7, 0x14, 0x55, 0xaf, 0x55, + 0x06, 0x3d, 0x1e, 0xaf, 0xb1, 0x13, 0xf9, 0xf9, 0x7a, 0x0a, 0xf7, 0xd7, 0xa1, 0x4e, 0xb5, 0x3f, + 0x57, 0x22, 0xba, 0x29, 0xd2, 0xfa, 0x9d, 0x25, 0xe3, 0x02, 0x06, 0x34, 0xcd, 0x3a, 0x23, 0x85, + 0x09, 0x45, 0x86, 0xd1, 0x85, 0xaf, 0xc7, 0xa0, 0x63, 0xcb, 0xe0, 0xac, 0xb6, 0x06, 0xa5, 0xae, + 0xd0, 0xc1, 0xa6, 0xda, 0x21, 0x90, 0x92, 0x0b, 0x6d, 0x3b, 0xf0, 0x56, 0x4b, 0xb4, 0x72, 0x0b, + 0x3d, 0x31, 0xac, 0xd6, 0xee, 0xbd, 0xf0, 0x4d, 0x55, 0x55, 0x4e, 0xb7, 0xf8, 0x50, 0xee, 0x56, + 0x4a, 0xc4, 0x1a, 0xcb, 0xea, 0xad, 0x37, 0x16, 0x9e, 0xbe, 0x08, 0xc9, 0x55, 0x57, 0xfb, 0x14, + 0xef, 0xac, 0x4f, 0xd0, 0x67, 0xbc, 0x23, 0x19, 0xd1, 0x3b, 0xe8, 0xaf, 0x0f, 0x70, 0x4e, 0x12, + 0x5a, 0xab, 0x67, 0x93, 0x11, 0xa6, 0xa2, 0xbe, 0x0a, 0xc9, 0x9f, 0xa1, 0x6b, 0x5c, 0x84, 0x2f, + 0x35, 0x5f, 0xe3, 0x3e, 0x33, 0x53, 0x4c, 0x1e, 0xd3, 0x4f, 0xa5, 0xef, 0x41, 0xa5, 0xe1, 0x1c, + 0xd8, 0x95, 0x79, 0x6f, 0x92, 0x9f, 0x04, 0x87, 0x36, 0x6a, 0xff, 0x1d, 0x5d, 0xeb, 0x58, 0xc7, + 0x5f, 0x4f, 0x1c, 0x55, 0x55, 0x55, 0xad, 0x57, 0xe2, 0x3c, 0x44, 0x5f, 0x43, 0x75, 0x04, 0x58, + 0x85, 0xcb, 0x0b, 0xb0, 0x90, 0x6a, 0x94, 0xfb, 0x61, 0x3b, 0x1f, 0x2c, 0x11, 0x36, 0x1d, 0xf1, + 0x86, 0x93, 0x25, 0xc7, 0x10, 0x3e, 0xe4, 0x61, 0xe8, 0x41, 0x57, 0x46, 0xc6, 0xbe, 0x1f, 0x51, + 0x0b, 0x58, 0x81, 0xf8, 0xca, 0x25, 0xa0, 0x9b, 0x61, 0xb8, 0x3f, 0xf3, 0xc3, 0x9a, 0xc5, 0x01, + 0x64, 0x30, 0xd1, 0x97, 0xfd, 0x73, 0x63, 0x2d, 0x01, 0x91, 0x59, 0xd2, 0xc4, 0xc2, 0x05, 0x27, + 0x95, 0xb1, 0x22, 0x3a, 0x92, 0x7b, 0xbf, 0x10, 0x13, 0x29, 0x31, 0x4b, 0x49, 0xaa, 0xaa, 0xe1, + 0x31, 0x0b, 0xae, 0x39, 0x4c, 0x27, 0xd0, 0x56, 0xa1, 0x2e, 0xae, 0x44, 0xf2, 0x0e, 0x93, 0x3f, + 0x1e, 0x62, 0x66, 0xb3, 0xf2, 0x9a, 0x85, 0x64, 0x66, 0xab, 0x29, 0x2b, 0x09, 0x1a, 0x7e, 0x3b, + 0x77, 0x5e, 0x6a, 0x93, 0x26, 0xa1, 0xdf, 0xbd, 0x76, 0x98, 0xa7, 0xb4, 0x35, 0x44, 0x45, 0xeb, + 0xea, 0xff, 0x15, 0x28, 0xe3, 0x33, 0x03, 0x9a, 0x08, 0x64, 0xc2, 0x2b, 0x5a, 0xe4, 0x3f, 0x84, + 0x24, 0xce, 0x35, 0x70, 0xc9, 0xd4, 0xce, 0x81, 0xe6, 0x42, 0xfb, 0xbb, 0xe3, 0xf7, 0xbb, 0xe1, + 0x8c, 0xb9, 0x2f, 0xfc, 0xb7, 0xbb, 0x82, 0xee, 0x0b, 0x84, 0xaa, 0xf2, 0xf6, 0x34, 0x7c, 0xc6, + 0x3e, 0x13, 0x22, 0xe8, 0xcf, 0xad, 0x55, 0x72, 0x16, 0x4c, 0xfc, 0x11, 0x4f, 0x7a, 0xdc, 0xfb, + 0x2b, 0xdf, 0xc4, 0x57, 0x14, 0x31, 0xe3, 0xab, 0x78, 0x87, 0xfe, 0x5a, 0x4e, 0xee, 0x2b, 0xa0, + 0xca, 0x68, 0x23, 0xe4, 0x0a, 0x37, 0x1f, 0xe3, 0x08, 0x5c, 0xb4, 0xf9, 0x26, 0xb4, 0xd4, 0xcc, + 0xda, 0xd7, 0xf6, 0x72, 0x7f, 0x3f, 0x10, 0x6b, 0xdf, 0x77, 0x0d, 0x74, 0x13, 0xca, 0x14, 0xe1, + 0x00, 0x85, 0x35, 0x13, 0x66, 0xb5, 0x3f, 0xbf, 0xfc, 0xa7, 0xd5, 0x44, 0x72, 0x08, 0x7b, 0xc1, + 0x57, 0x28, 0xb5, 0xaf, 0xcd, 0x5a, 0xfc, 0x22, 0x31, 0x56, 0xb2, 0xc1, 0x3a, 0xe2, 0xff, 0x8e, + 0xdd, 0x8f, 0x77, 0x75, 0x55, 0x5f, 0x29, 0xdf, 0x72, 0x74, 0x2f, 0xa6, 0xec, 0x75, 0xde, 0x17, + 0xe8, 0x7c, 0xaf, 0xa1, 0x69, 0x17, 0xa2, 0x31, 0x11, 0x13, 0x5c, 0x25, 0xe1, 0x03, 0x2a, 0xad, + 0x6b, 0x55, 0xfc, 0xc6, 0x97, 0xd9, 0x7b, 0x88, 0x7e, 0xec, 0x3f, 0x09, 0x64, 0xc5, 0x9a, 0xaf, + 0xc7, 0xc2, 0x1d, 0x8e, 0x6c, 0xb3, 0x77, 0xdd, 0x36, 0x9b, 0xbe, 0x0b, 0x84, 0xa0, 0xd5, 0x0f, + 0x55, 0xa7, 0xf8, 0x46, 0x14, 0xe3, 0x93, 0x18, 0xaa, 0xeb, 0xaa, 0xf8, 0x8d, 0x53, 0x55, 0x55, + 0x57, 0xc5, 0xea, 0xda, 0xd5, 0x65, 0xe5, 0x10, 0xf7, 0x70, 0xc7, 0x42, 0x7a, 0x2b, 0x98, 0xcd, + 0x6d, 0x78, 0x48, 0x43, 0xdf, 0x7b, 0x93, 0x94, 0xb5, 0xaf, 0x89, 0x2b, 0xdf, 0x5a, 0x8c, 0x89, + 0xf8, 0x82, 0x97, 0x54, 0x61, 0x6e, 0xaf, 0xf5, 0x78, 0xae, 0x42, 0x3e, 0xdf, 0xb2, 0xd5, 0x7e, + 0x4a, 0x5a, 0xf1, 0x26, 0x15, 0x54, 0xbe, 0xc4, 0xbb, 0xfe, 0x08, 0x8b, 0x69, 0x57, 0xbe, 0x10, + 0x11, 0x2f, 0xa7, 0x79, 0x79, 0xfd, 0xfe, 0xfa, 0x1a, 0xff, 0x21, 0x0f, 0x8f, 0xf9, 0xaa, 0xb5, + 0xf7, 0x5a, 0xd7, 0x64, 0x55, 0xdf, 0x29, 0x2e, 0xff, 0x08, 0x1d, 0x75, 0xad, 0x44, 0xf3, 0x02, + 0x4b, 0x88, 0x12, 0x75, 0xa5, 0xd9, 0x8d, 0xbe, 0x78, 0x91, 0xf6, 0x11, 0x2e, 0xc2, 0x21, 0x1c, + 0x4e, 0xd8, 0x51, 0x79, 0x60, 0x7e, 0xe6, 0x23, 0xb7, 0x12, 0xf0, 0x99, 0x11, 0xe0, 0xfa, 0xd4, + 0x94, 0x56, 0x53, 0xc1, 0x10, 0xa7, 0xce, 0x63, 0xaf, 0x82, 0x39, 0x61, 0xd8, 0x86, 0x7a, 0x1f, + 0x15, 0xf5, 0x8b, 0xe8, 0x44, 0x17, 0xc1, 0x2d, 0x55, 0x56, 0x5f, 0xbf, 0xc1, 0x28, 0x8b, 0xbf, + 0x77, 0x77, 0x88, 0x05, 0x83, 0x6b, 0x55, 0x6f, 0x55, 0xdf, 0xe0, 0x8b, 0x2a, 0xed, 0xb5, 0x7d, + 0x7c, 0x84, 0x3b, 0x1b, 0x6f, 0x82, 0x42, 0xcf, 0x92, 0x76, 0xfb, 0xee, 0xbe, 0x13, 0x3a, 0xae, + 0xb2, 0x76, 0x8d, 0xd8, 0xc7, 0xbb, 0xf8, 0xf1, 0x3a, 0x35, 0x44, 0x8d, 0x55, 0x56, 0x31, 0x96, + 0x26, 0x12, 0x22, 0x36, 0xd2, 0xab, 0x2d, 0x1e, 0x26, 0x0a, 0x44, 0x85, 0x62, 0x09, 0xd0, 0xed, + 0x24, 0x1c, 0x86, 0xe7, 0xe8, 0xc7, 0x11, 0xa7, 0xe2, 0x7f, 0x52, 0xdf, 0x04, 0x86, 0xbd, 0xfb, + 0xe0, 0x88, 0x47, 0x1f, 0x8c, 0x7f, 0x96, 0xdd, 0xdb, 0x3f, 0x42, 0x7a, 0xb9, 0x6d, 0xa7, 0x4c, + 0x27, 0xce, 0x61, 0x4b, 0xef, 0x2f, 0xfa, 0xc4, 0x7d, 0x15, 0xbe, 0x08, 0xc4, 0x48, 0xdd, 0xfe, + 0x24, 0x79, 0xfc, 0xfe, 0xf1, 0xd8, 0xcf, 0xc8, 0x6a, 0xd7, 0x13, 0x04, 0x25, 0x77, 0x41, 0xdc, + 0xe2, 0x44, 0x7c, 0x5d, 0xe8, 0x69, 0x1d, 0x86, 0xed, 0xbf, 0x04, 0x64, 0x99, 0x84, 0x5b, 0x12, + 0xf2, 0x55, 0x55, 0x7d, 0x9e, 0x7a, 0x6b, 0x82, 0xe2, 0x3b, 0xbd, 0xb2, 0x40, 0xb5, 0xdf, 0xe0, + 0xa4, 0xad, 0xb4, 0xe3, 0x11, 0x99, 0xd7, 0xe3, 0x70, 0xe3, 0xb8, 0xa8, 0x88, 0xab, 0x7a, 0xc1, + 0xdb, 0x03, 0x79, 0x66, 0x10, 0x71, 0x31, 0x36, 0x92, 0x75, 0x8d, 0x2d, 0xb2, 0x70, 0x4e, 0x33, + 0x72, 0xed, 0x0d, 0x91, 0xab, 0xaf, 0x82, 0x32, 0x96, 0x31, 0xda, 0x44, 0x43, 0x50, 0xd7, 0x35, + 0x0d, 0x86, 0x83, 0x2e, 0x2e, 0x52, 0xe5, 0xbf, 0x88, 0xbb, 0xfa, 0xaf, 0x11, 0x5c, 0xb7, 0xbf, + 0xcd, 0x7d, 0xf8, 0x87, 0x77, 0x45, 0xc4, 0x09, 0x36, 0x7f, 0xf1, 0x1f, 0x04, 0x94, 0xdb, 0x5b, + 0x57, 0x09, 0xdf, 0x7b, 0xbc, 0xbd, 0x12, 0xbe, 0x3c, 0xe3, 0x7d, 0x4d, 0xe9, 0x4b, 0x57, 0x2c, + 0x4d, 0x19, 0x21, 0x26, 0x78, 0x21, 0xf4, 0x4e, 0xdf, 0x08, 0xc6, 0x47, 0x45, 0xe2, 0x07, 0xbd, + 0x0d, 0x85, 0x1d, 0x14, 0x2c, 0xb5, 0xcb, 0x4b, 0x7f, 0x56, 0x7d, 0x96, 0xaa, 0xfc, 0x41, 0x7b, + 0x49, 0x2e, 0x09, 0xc2, 0x1b, 0x6d, 0xd2, 0xbd, 0x4d, 0xd0, 0x96, 0xfa, 0xb4, 0x9d, 0x5a, 0xba, + 0xb4, 0xdd, 0xd7, 0x5f, 0x56, 0x97, 0xad, 0x7c, 0x11, 0x92, 0xed, 0x37, 0xaf, 0x84, 0x8b, 0x5a, + 0xd6, 0xda, 0xe5, 0xd5, 0x7e, 0x6d, 0x57, 0xee, 0xba, 0x92, 0x27, 0xf5, 0xaf, 0x82, 0x63, 0x95, + 0x43, 0xb9, 0x58, 0x7d, 0xff, 0xf9, 0x2e, 0xef, 0xf0, 0x43, 0x4f, 0x4f, 0xbe, 0x08, 0x4c, 0xc6, + 0xc6, 0x66, 0x28, 0xfa, 0xb8, 0xaa, 0x9b, 0x16, 0x6b, 0x4b, 0xc9, 0x6a, 0xd7, 0xcc, 0x5a, 0x23, + 0xa2, 0xa1, 0xf9, 0x2f, 0xda, 0xf5, 0x7f, 0x93, 0x53, 0x79, 0xf0, 0x53, 0x61, 0x36, 0xa8, 0xa4, + 0xaa, 0x7d, 0x57, 0xde, 0x20, 0xba, 0xd5, 0x72, 0xed, 0x1b, 0x22, 0xf2, 0x95, 0xdd, 0x1f, 0xc9, + 0xd5, 0x57, 0x41, 0x0a, 0x8c, 0xe8, 0x5b, 0x91, 0xbc, 0xc2, 0x2f, 0x7f, 0x29, 0x5d, 0x17, 0xe5, + 0x13, 0x7b, 0xf9, 0x89, 0xaa, 0xf1, 0x1f, 0x09, 0xd3, 0xd2, 0x5d, 0x78, 0x82, 0x11, 0x55, 0x22, + 0x62, 0xe0, 0x90, 0xb5, 0x69, 0x1b, 0xf8, 0x81, 0xd9, 0xbc, 0xdd, 0x3c, 0x78, 0xba, 0xd7, 0x09, + 0xd6, 0x39, 0x57, 0xbb, 0xfb, 0xd8, 0xe7, 0xfe, 0x0a, 0xaf, 0x4e, 0xf4, 0x3a, 0xa7, 0x95, 0x3e, + 0x4d, 0xe6, 0xc2, 0x71, 0x54, 0x88, 0x2b, 0x41, 0x66, 0x95, 0x75, 0x6f, 0x82, 0xef, 0x25, 0x6f, + 0x46, 0xde, 0x20, 0x4d, 0x9d, 0xeb, 0xa2, 0xf0, 0x95, 0x6b, 0x5a, 0x9a, 0x8b, 0x82, 0x43, 0xba, + 0xfd, 0xf7, 0x9b, 0xdb, 0x7c, 0xe3, 0x96, 0x3a, 0x83, 0xff, 0x96, 0xde, 0x6c, 0x15, 0xd1, 0xdd, + 0x5d, 0x59, 0x37, 0x56, 0x57, 0x56, 0x2b, 0x82, 0x71, 0x0e, 0xb7, 0xbb, 0xea, 0xbb, 0xd6, 0xbe, + 0x52, 0xde, 0xfe, 0x8a, 0xd7, 0xd1, 0x7b, 0xe8, 0x9d, 0xe2, 0x09, 0x55, 0xaf, 0x12, 0xc8, 0x7f, + 0xb3, 0x31, 0x89, 0x9a, 0xb5, 0xae, 0x5b, 0xa6, 0xf5, 0xd9, 0xf7, 0x75, 0x13, 0x17, 0x56, 0x3e, + 0xb5, 0xf7, 0x2f, 0x9b, 0x5f, 0x88, 0x26, 0xb5, 0xf2, 0x6a, 0xdf, 0xc2, 0x65, 0xa9, 0x4c, 0xc3, + 0x65, 0x97, 0x57, 0x76, 0xe9, 0x36, 0x4c, 0x49, 0xaf, 0x40, 0xcb, 0xd7, 0x66, 0xbd, 0xdf, 0x05, + 0x46, 0x77, 0xa5, 0xee, 0x46, 0x36, 0xe7, 0xfa, 0x89, 0xe8, 0xee, 0x46, 0x75, 0x6f, 0x89, 0x11, + 0x93, 0xb4, 0x31, 0x9c, 0xbf, 0xfe, 0x8b, 0x6a, 0xe4, 0x12, 0xed, 0xa7, 0xe2, 0x04, 0x8c, 0x55, + 0xad, 0x62, 0xfe, 0x61, 0xb7, 0xb9, 0x38, 0x23, 0xa7, 0x76, 0xfb, 0x89, 0xf1, 0x1f, 0x85, 0x0a, + 0x7c, 0x1f, 0x53, 0x51, 0x72, 0xe7, 0xde, 0xfb, 0x5d, 0x57, 0xab, 0x82, 0x83, 0x4b, 0xfb, 0xb1, + 0xfa, 0xb9, 0x2d, 0x1d, 0x93, 0x29, 0xdf, 0x18, 0x52, 0x76, 0x1a, 0xa1, 0xa0, 0x36, 0x40, 0xf9, + 0x98, 0xd0, 0xe6, 0x26, 0xa9, 0xb7, 0x8c, 0xec, 0xcf, 0xbf, 0x92, 0xeb, 0xf9, 0xeb, 0x55, 0x6f, + 0xc2, 0x9c, 0x13, 0x88, 0x85, 0x53, 0x0f, 0xbd, 0xb4, 0x39, 0x4b, 0xc6, 0x5c, 0x81, 0x81, 0x91, + 0x01, 0xf1, 0xb7, 0xa8, 0xed, 0xb5, 0x8e, 0x4d, 0xae, 0x12, 0x1f, 0x6d, 0x7a, 0xab, 0xe6, 0xa6, + 0xf4, 0xde, 0x20, 0x13, 0x19, 0xee, 0xc6, 0xec, 0x6d, 0x5f, 0xec, 0xad, 0xad, 0xbe, 0x21, 0xd0, + 0xcb, 0xad, 0xfe, 0x2f, 0x6d, 0xbd, 0x66, 0xfc, 0x40, 0x25, 0x2e, 0x7f, 0x63, 0x90, 0xed, 0xfe, + 0x69, 0xd7, 0xfc, 0x21, 0xf3, 0x73, 0x51, 0x9a, 0xe3, 0xb3, 0xa5, 0x61, 0xb5, 0x87, 0x7e, 0x31, + 0x4f, 0xbe, 0x62, 0x3e, 0xeb, 0x96, 0xee, 0xee, 0xf9, 0x08, 0x88, 0x92, 0x6b, 0x27, 0x04, 0x84, + 0x63, 0xbd, 0xe1, 0x3e, 0x8a, 0xef, 0xa1, 0x1a, 0xae, 0x63, 0xee, 0xe4, 0xe5, 0x2b, 0xbb, 0xb9, + 0x39, 0x8e, 0x86, 0x66, 0x48, 0xcd, 0x1f, 0x88, 0xa7, 0x91, 0x49, 0xd0, 0x60, 0xd8, 0x7e, 0x13, + 0xab, 0xd6, 0xab, 0xf3, 0x1b, 0x33, 0x2c, 0x7e, 0xcf, 0xcb, 0x9e, 0x53, 0x50, 0xd8, 0xd5, 0x75, + 0xea, 0xe2, 0x4f, 0x4e, 0x33, 0x4f, 0x17, 0x7d, 0xd6, 0xb2, 0x72, 0x8c, 0x77, 0x71, 0x5f, 0x89, + 0x2b, 0xdf, 0x77, 0x77, 0xcb, 0x63, 0x63, 0x7f, 0x98, 0xa9, 0x35, 0x49, 0xf2, 0x1a, 0xb5, 0xf1, + 0x34, 0xe3, 0x8b, 0x93, 0x1b, 0x9f, 0x5d, 0x0b, 0xd4, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x12, 0x09, 0x30, 0x11, 0xa7, 0xc3, 0xa2, 0xe8, 0x82, 0x16, 0x2f, 0x4c, 0x62, 0xed, 0x30, 0xca, + 0x61, 0x6f, 0xbb, 0x80, 0x4a, 0x53, 0x1e, 0xbe, 0x9a, 0x7f, 0x9e, 0x19, 0xe1, 0xf0, 0xe1, 0x78, + 0x69, 0xe0, 0x09, 0x61, 0xe5, 0x29, 0x3f, 0x5f, 0xf0, 0xe1, 0x87, 0xc6, 0x0f, 0x07, 0xc8, 0x8b, + 0x5b, 0x1a, 0x71, 0xa8, 0x13, 0x4d, 0x7f, 0x82, 0x3f, 0x1a, 0xa2, 0x23, 0x7c, 0x17, 0xf1, 0x94, + 0xc7, 0x69, 0xa8, 0xe9, 0x22, 0x31, 0xa7, 0x1a, 0x29, 0xa6, 0x9a, 0x29, 0xa6, 0x9a, 0x13, 0x34, + 0x7c, 0xd7, 0x86, 0xc5, 0x1a, 0x44, 0x92, 0xeb, 0x46, 0x58, 0x65, 0x83, 0xa1, 0xb7, 0x54, 0x23, + 0xc1, 0x80, 0xfc, 0x6b, 0xca, 0xbc, 0x1b, 0xab, 0xd2, 0xa0, 0xc1, 0x3f, 0x95, 0xb5, 0x3e, 0x07, + 0x86, 0x3f, 0x73, 0x3b, 0xf1, 0x2c, 0x02, 0x47, 0xe7, 0x8d, 0x20, 0xd2, 0x63, 0x82, 0x8d, 0x26, + 0x35, 0x49, 0x8f, 0x5f, 0x09, 0x31, 0x68, 0xab, 0x33, 0x99, 0xda, 0x18, 0x49, 0x28, 0xfe, 0x86, + 0xfc, 0x5f, 0x82, 0x33, 0x8c, 0xa6, 0xfd, 0x3c, 0x67, 0x24, 0x3e, 0x85, 0xc1, 0xf1, 0xfc, 0xbe, + 0x1b, 0xf0, 0xfe, 0x73, 0x1d, 0x09, 0x68, 0xfa, 0x7d, 0xf8, 0xaa, 0x15, 0x5e, 0x1e, 0x37, 0x1a, + 0xa3, 0x4d, 0x7c, 0x3a, 0xc5, 0x5c, 0x4f, 0x19, 0xfa, 0xa6, 0x9f, 0x82, 0x88, 0xeb, 0xa6, 0x83, + 0x23, 0xfd, 0x63, 0x1a, 0x10, 0xb0, 0x77, 0xaf, 0xc3, 0xe3, 0x72, 0xd4, 0x61, 0xf3, 0x5a, 0x4c, + 0x22, 0x93, 0x08, 0xc4, 0x3f, 0x9a, 0x4a, 0xf3, 0xa5, 0x56, 0x53, 0xd9, 0x9f, 0x61, 0x3c, 0x91, + 0xf1, 0xa2, 0x47, 0xfc, 0xbc, 0x21, 0x8d, 0xdf, 0x65, 0xd7, 0x8d, 0x0e, 0xb1, 0x8f, 0x43, 0xc7, + 0x68, 0xc9, 0x6a, 0x63, 0x1a, 0xa2, 0xdf, 0x35, 0xc3, 0x2a, 0x45, 0x85, 0x02, 0x26, 0xb3, 0x59, + 0x1a, 0x0d, 0x6b, 0xd4, 0xf8, 0x2f, 0x2c, 0x63, 0xd5, 0x2d, 0x1c, 0x75, 0xa1, 0x23, 0x2c, 0xbf, + 0x05, 0x7f, 0x5a, 0x6b, 0xc3, 0xb8, 0x2a, 0x94, 0x5e, 0x3f, 0xef, 0x8f, 0xfb, 0x88, 0xb4, 0x83, + 0xe3, 0x23, 0xe3, 0x3f, 0xfc, 0x3c, 0x10, 0x4f, 0x9b, 0x5e, 0x9c, 0x27, 0x4c, 0x3d, 0x94, 0xe9, + 0xe5, 0x22, 0x62, 0x0b, 0xc8, 0x8d, 0x37, 0x49, 0xa9, 0x0e, 0x34, 0xe4, 0xcc, 0xc7, 0xa2, 0xde, + 0x18, 0x3e, 0x08, 0x26, 0xc3, 0x61, 0xf1, 0xf8, 0x38, 0xeb, 0x52, 0x1c, 0x06, 0x1f, 0x4a, 0x33, + 0x4b, 0x58, 0xc2, 0x90, 0xdf, 0xcb, 0xa9, 0x79, 0x87, 0x86, 0x31, 0x5f, 0xf9, 0xe6, 0x46, 0x7f, + 0x31, 0xa2, 0x6e, 0x7e, 0x78, 0xda, 0x49, 0x09, 0x4c, 0x8a, 0xbf, 0xf3, 0xd1, 0x14, 0xbf, 0x16, + 0xc5, 0xbf, 0x3c, 0x45, 0x27, 0x15, 0x62, 0xaf, 0xfc, 0x47, 0x8d, 0x7b, 0x55, 0xaa, 0xaf, 0x7a, + 0xa5, 0x4f, 0x87, 0x85, 0x67, 0xc7, 0x1c, 0x0f, 0x30, 0xf5, 0x9b, 0xd1, 0x09, 0xbf, 0x5d, 0x4c, + 0x3c, 0xd0, 0x40, 0x23, 0xa1, 0x15, 0xa3, 0x5f, 0xc7, 0x3b, 0x81, 0x7f, 0x1a, 0x22, 0x9a, 0x42, + 0x12, 0x91, 0x2c, 0xc3, 0x75, 0x05, 0xc9, 0x74, 0x2b, 0x95, 0x1c, 0x7e, 0x24, 0x2d, 0xb0, 0x36, + 0x52, 0xc2, 0xfa, 0x2d, 0x88, 0x41, 0x37, 0xaa, 0x10, 0x88, 0x12, 0x9c, 0x58, 0xd4, 0x00, 0x09, + 0x84, 0x64, 0xf0, 0xa8, 0x08, 0x06, 0x5b, 0x1b, 0xb4, 0xeb, 0x04, 0xd3, 0x04, 0x1e, 0xb2, 0x90, + 0xa7, 0x03, 0x26, 0xa8, 0x8d, 0x89, 0x7c, 0x30, 0x11, 0x22, 0xd9, 0x84, 0x0f, 0xd9, 0xac, 0xa4, + 0x00, 0x04, 0x4e, 0xd2, 0xd8, 0x10, 0xa5, 0xf7, 0xd5, 0xeb, 0xd1, 0x7f, 0x19, 0xce, 0x52, 0x24, + 0x7a, 0x5a, 0xe9, 0x7f, 0xfe, 0x37, 0x5a, 0x30, 0xc6, 0x46, 0x1f, 0xc7, 0x46, 0x1f, 0x8c, 0x8c, + 0x3f, 0x8e, 0x8c, 0x31, 0x91, 0x87, 0xa7, 0x5f, 0x1c, 0x96, 0xb2, 0x5f, 0x9f, 0x86, 0x23, 0xa3, + 0x0f, 0xc6, 0x11, 0xc3, 0x8e, 0x97, 0x96, 0xd6, 0x35, 0x73, 0xfc, 0x66, 0x3a, 0x30, 0xc6, 0x46, + 0x1f, 0xc7, 0x46, 0x1f, 0xe3, 0x23, 0x0f, 0xe3, 0xa3, 0x0c, 0x64, 0x61, 0xef, 0x9e, 0x95, 0x7e, + 0x39, 0x2d, 0x64, 0xb5, 0xc2, 0xf1, 0x96, 0x84, 0x2c, 0xb5, 0x0b, 0x18, 0xf2, 0x0c, 0xb7, 0xa2, + 0x5a, 0xfc, 0x5b, 0x13, 0x33, 0xe3, 0x69, 0x72, 0xc9, 0x72, 0xc8, 0xf2, 0xd6, 0xf2, 0xc9, 0x72, + 0xc9, 0x72, 0xd6, 0xf2, 0xd6, 0xf2, 0xd7, 0x19, 0x6b, 0x8c, 0xb2, 0x16, 0x5a, 0xcb, 0x2d, 0x71, + 0x96, 0xb8, 0xcb, 0x59, 0x65, 0xac, 0xb2, 0xc2, 0x1d, 0x1d, 0x0f, 0x4b, 0x5d, 0x2c, 0xf9, 0x93, + 0xe6, 0x46, 0x65, 0xa9, 0x97, 0xeb, 0xb1, 0x8e, 0x87, 0x9f, 0xaa, 0x76, 0xba, 0xb8, 0x3f, 0x47, + 0x25, 0x3f, 0x04, 0x02, 0x33, 0x17, 0x43, 0xe6, 0xce, 0xad, 0x29, 0x39, 0xfb, 0x37, 0x1a, 0x89, + 0xe2, 0x06, 0x8e, 0xae, 0x45, 0x5e, 0xa9, 0xef, 0x69, 0x11, 0x8c, 0x6a, 0x2a, 0xc1, 0xb9, 0x8f, + 0x67, 0xa0, 0x45, 0x57, 0x04, 0xf5, 0xa4, 0x0e, 0xf0, 0xa3, 0xff, 0xc2, 0xd6, 0x17, 0x23, 0x66, + 0xb5, 0x49, 0xd1, 0x82, 0xbc, 0x74, 0x49, 0x46, 0x88, 0xe5, 0xd2, 0xe1, 0x1a, 0x00, 0x96, 0xae, + 0x36, 0xf5, 0xff, 0x88, 0x0d, 0x86, 0x71, 0xaf, 0x2a, 0xf1, 0x51, 0x56, 0x6d, 0x36, 0xe6, 0xd3, + 0x6f, 0x86, 0x38, 0xd3, 0x42, 0xa6, 0x8d, 0x53, 0x44, 0x05, 0x94, 0xf0, 0x93, 0x3f, 0x6e, 0xf9, + 0xbb, 0xcf, 0x03, 0x4d, 0x7f, 0x86, 0xf5, 0x2a, 0x57, 0x44, 0x1d, 0xbe, 0xa6, 0x4f, 0xa8, 0x8e, + 0x0a, 0xe1, 0x4f, 0x9e, 0x87, 0xa7, 0x9e, 0x87, 0xa1, 0xe8, 0xfa, 0x6f, 0xa3, 0xe9, 0xe5, 0x5d, + 0x0a, 0x7f, 0xa2, 0xbc, 0xbd, 0x4a, 0x97, 0xd8, 0xc6, 0xea, 0x90, 0xae, 0x82, 0x67, 0xbe, 0x8c, + 0x0a, 0x4b, 0xe8, 0xa8, 0x94, 0xbc, 0x4e, 0x91, 0x73, 0xe5, 0xcc, 0x4c, 0x16, 0x92, 0x2c, 0x70, + 0x32, 0xed, 0x13, 0xf9, 0xf8, 0xd4, 0x07, 0x7e, 0x1e, 0x0a, 0x43, 0xe6, 0x12, 0x67, 0xda, 0xd9, + 0x30, 0x40, 0x1e, 0x9a, 0x78, 0xa6, 0x53, 0x81, 0xf5, 0x8f, 0xf8, 0x80, 0x51, 0xa7, 0x29, 0x06, + 0x76, 0x1e, 0x8f, 0x5e, 0x24, 0x10, 0x85, 0x76, 0x5e, 0x34, 0x05, 0x16, 0xba, 0x95, 0x1d, 0x13, + 0x85, 0xc4, 0x6e, 0x34, 0x6c, 0x31, 0x8c, 0xb3, 0x30, 0x80, 0x8b, 0x41, 0x7b, 0xf6, 0xdb, 0x96, + 0x9e, 0x0b, 0x05, 0x73, 0x5e, 0x93, 0xea, 0x48, 0x77, 0xc3, 0xfc, 0x8b, 0xd0, 0xf1, 0x2a, 0xb3, + 0xfa, 0x2d, 0xa7, 0xff, 0x84, 0x65, 0x48, 0x57, 0x1c, 0x7d, 0xc4, 0x2c, 0x91, 0xca, 0x20, 0x24, + 0xcc, 0x00, 0x95, 0x94, 0x72, 0x63, 0xf8, 0x26, 0x0a, 0xb1, 0x26, 0xac, 0x15, 0xc8, 0xcd, 0x65, + 0xbe, 0x3c, 0x77, 0xc2, 0x1d, 0x11, 0x90, 0xa7, 0x21, 0x1e, 0xff, 0x0e, 0x6a, 0x38, 0xd1, 0x9c, + 0x33, 0xf4, 0x63, 0x52, 0xef, 0xc3, 0x55, 0x55, 0xcb, 0x27, 0x4b, 0xf8, 0x49, 0x16, 0x38, 0x4e, + 0x5b, 0x6f, 0xff, 0x05, 0x93, 0xe1, 0xf3, 0xcf, 0x87, 0xcc, 0xf8, 0x7c, 0xac, 0x38, 0xa0, 0x9f, + 0xd2, 0x28, 0xe4, 0xbf, 0x18, 0xb7, 0xff, 0x98, 0x4d, 0x8f, 0x65, 0x72, 0x8b, 0xfc, 0x40, 0x44, + 0x2c, 0x30, 0x84, 0xc6, 0xec, 0x1b, 0xef, 0x76, 0xda, 0xf1, 0xbb, 0x39, 0xe2, 0xfb, 0x38, 0xc1, + 0x4a, 0x5e, 0xc6, 0xa2, 0x83, 0xac, 0x5c, 0x67, 0xb7, 0x57, 0xff, 0x41, 0x5e, 0x75, 0xe5, 0xe3, + 0xbe, 0x5b, 0xe7, 0xc1, 0x08, 0xa7, 0xbe, 0xbe, 0x0a, 0xc4, 0x5e, 0xfc, 0x69, 0xa2, 0xb2, 0xaf, + 0xf1, 0x44, 0x58, 0xbd, 0x55, 0x70, 0x59, 0x5a, 0x99, 0x4f, 0x0e, 0x0a, 0x8e, 0xf5, 0xc9, 0x5f, + 0x6f, 0xf7, 0x74, 0x28, 0xee, 0xaf, 0x41, 0x7f, 0xfd, 0x4e, 0x8e, 0x84, 0xf5, 0xe5, 0x46, 0xc4, + 0x02, 0x5b, 0xbe, 0xef, 0xf1, 0xc6, 0x23, 0xa2, 0x39, 0x1d, 0x88, 0xf8, 0x22, 0x2a, 0xaa, 0x8b, + 0x80, 0xb1, 0x8a, 0xf4, 0x50, 0x1a, 0xe1, 0x11, 0x2a, 0x91, 0x78, 0x5c, 0x25, 0x1b, 0x10, 0x23, + 0xe9, 0x22, 0x98, 0x6d, 0x98, 0xdb, 0x14, 0x18, 0x6c, 0xcf, 0x81, 0xd2, 0xae, 0x7f, 0x85, 0x0c, + 0xbe, 0x90, 0x32, 0x45, 0x12, 0x8d, 0x60, 0xf2, 0x82, 0xd0, 0xb2, 0xf2, 0x55, 0x54, 0x0c, 0xaf, + 0xd7, 0xa3, 0x11, 0x7e, 0xb7, 0x8b, 0x2f, 0x88, 0x05, 0xa3, 0x75, 0x51, 0xf4, 0x2a, 0xce, 0x7a, + 0xc0, 0xf7, 0xf7, 0xef, 0xe2, 0x41, 0x08, 0x97, 0xe5, 0xf3, 0xa5, 0x73, 0x08, 0x37, 0x49, 0xb2, + 0xe7, 0x84, 0x47, 0x13, 0xd5, 0x5d, 0x5f, 0xa8, 0x4c, 0x48, 0x5c, 0x84, 0x99, 0x49, 0xf1, 0x1c, + 0xaa, 0xea, 0xbe, 0x08, 0x47, 0xba, 0x4e, 0x7c, 0x7f, 0x82, 0x71, 0xca, 0xb6, 0x8b, 0x1c, 0x3c, + 0x27, 0xa9, 0xc1, 0x87, 0xbe, 0x08, 0x60, 0x8f, 0x77, 0xc6, 0xf9, 0x71, 0x3b, 0x8f, 0xbe, 0x15, + 0x0b, 0xbc, 0x57, 0xad, 0xe0, 0xe6, 0xd6, 0xbf, 0x89, 0x57, 0xf1, 0x2b, 0xf8, 0x8e, 0x89, 0x5f, + 0x58, 0xa6, 0xc4, 0xa8, 0xed, 0x15, 0xd5, 0x87, 0xab, 0x44, 0xf0, 0x49, 0x77, 0x4c, 0xec, 0xcb, + 0xe1, 0x1e, 0xef, 0x8b, 0xaa, 0xee, 0xba, 0xc5, 0xf5, 0x8b, 0xe0, 0xae, 0xab, 0xdd, 0xa6, 0xb6, + 0x8b, 0x71, 0x78, 0x90, 0xb8, 0x81, 0x38, 0x26, 0xcc, 0x64, 0x3b, 0x6a, 0x67, 0x36, 0xa8, 0xe1, + 0x06, 0x5c, 0xa8, 0xbf, 0xc6, 0x0a, 0x70, 0x60, 0xc1, 0x63, 0x55, 0x51, 0xe9, 0x18, 0xe8, 0x83, + 0x14, 0xcd, 0x18, 0xf5, 0x73, 0x2b, 0x52, 0x7f, 0xc2, 0x85, 0x90, 0xd8, 0xe5, 0x9f, 0x01, 0xd5, + 0x72, 0x61, 0x10, 0x2c, 0x91, 0xa6, 0xaa, 0x95, 0xf0, 0xf1, 0x02, 0x65, 0xcf, 0xf4, 0xd3, 0x3e, + 0xd4, 0x9a, 0x6d, 0x34, 0x22, 0xd0, 0xff, 0xed, 0xb7, 0xc4, 0xf8, 0x90, 0x54, 0x10, 0xdd, 0xe1, + 0x7a, 0x49, 0xb9, 0x4b, 0xa0, 0xed, 0x0e, 0x16, 0x32, 0xf1, 0x8f, 0xf8, 0x29, 0x34, 0x36, 0x51, + 0xde, 0x59, 0xff, 0x2b, 0x11, 0xbf, 0x71, 0x34, 0x3f, 0xbc, 0x48, 0x24, 0x34, 0x06, 0x7b, 0x3b, + 0x9a, 0x23, 0xbe, 0xf6, 0x45, 0xf0, 0xff, 0x05, 0x22, 0x22, 0x06, 0x02, 0x06, 0x89, 0xde, 0x5e, + 0x63, 0xef, 0x4d, 0xda, 0x7f, 0xdf, 0x27, 0xbe, 0x82, 0xe9, 0x57, 0xaa, 0x45, 0xc4, 0x02, 0x2d, + 0xef, 0xff, 0x12, 0x8a, 0x9d, 0x05, 0xfa, 0xf4, 0xdd, 0x0e, 0xe8, 0x8e, 0x08, 0xc4, 0x92, 0x84, + 0xa6, 0x95, 0x78, 0x2c, 0xea, 0xa5, 0xa1, 0x69, 0xb6, 0x8d, 0xa7, 0xdf, 0x5e, 0xf8, 0x28, 0xee, + 0xfb, 0xbe, 0x5f, 0x04, 0xe6, 0x72, 0x41, 0x4c, 0xbb, 0x54, 0xc3, 0x4a, 0x6d, 0x8d, 0x52, 0x0d, + 0xfc, 0x40, 0x50, 0x77, 0x4c, 0x8e, 0x32, 0xe9, 0xb5, 0x38, 0xf5, 0xb1, 0xea, 0x25, 0x9e, 0x03, + 0xe4, 0x60, 0x20, 0x4e, 0xf8, 0x26, 0x29, 0xea, 0x49, 0xaa, 0xc8, 0xe6, 0x78, 0xf7, 0x2d, 0xde, + 0xb1, 0x00, 0x90, 0x6d, 0xb9, 0xb9, 0x85, 0xe2, 0x41, 0x68, 0x41, 0xec, 0x42, 0xc1, 0x6e, 0xcd, + 0xb1, 0x2e, 0x3f, 0xc1, 0x48, 0xb8, 0x72, 0xa1, 0xbd, 0x1d, 0x1b, 0xb1, 0xbb, 0x1d, 0xfa, 0xf8, + 0x24, 0x36, 0xe1, 0x02, 0x7e, 0xa7, 0xf8, 0x29, 0x36, 0xee, 0x33, 0x87, 0x4b, 0x41, 0xe3, 0x9b, + 0x9c, 0x86, 0x01, 0xef, 0xf6, 0x17, 0x67, 0xdd, 0x8c, 0x45, 0x8e, 0x0d, 0x09, 0xf4, 0x67, 0x9b, + 0xab, 0x02, 0x70, 0x4c, 0x5a, 0xd5, 0xef, 0x2d, 0x27, 0x44, 0x72, 0x5e, 0x5e, 0xee, 0x4e, 0x0b, + 0x08, 0xac, 0x50, 0xac, 0x21, 0xd5, 0x58, 0xd8, 0xa8, 0xdf, 0x4b, 0xe2, 0x42, 0x83, 0xb5, 0xd4, + 0x73, 0xfd, 0x9d, 0x63, 0xd5, 0x9f, 0xc4, 0xd8, 0x39, 0x17, 0x28, 0x9b, 0x94, 0x4f, 0x78, 0x80, + 0x57, 0x79, 0xf5, 0x21, 0x48, 0x37, 0x42, 0x23, 0x36, 0xb6, 0x3b, 0xd7, 0x16, 0x58, 0x87, 0xdc, + 0x43, 0x51, 0x7a, 0xc5, 0xf8, 0x90, 0x52, 0x47, 0x79, 0x04, 0x57, 0x67, 0xec, 0x1f, 0x77, 0x6f, + 0xff, 0x9b, 0x9a, 0x2d, 0xf8, 0x9b, 0xa4, 0xe1, 0x23, 0xd9, 0x41, 0x45, 0xa3, 0x4b, 0xbd, 0x42, + 0x22, 0x41, 0x10, 0x5f, 0x2e, 0x17, 0x0e, 0x95, 0xd4, 0xeb, 0x86, 0x7a, 0xb5, 0xf5, 0x4c, 0xc9, + 0xc9, 0x75, 0x77, 0x37, 0x52, 0xa4, 0x9c, 0x28, 0x29, 0xd8, 0x34, 0xf9, 0xf9, 0xc3, 0x89, 0xb0, + 0x63, 0x74, 0xa1, 0xb6, 0x6b, 0xac, 0xb7, 0x58, 0x48, 0xaf, 0x1e, 0x0a, 0x88, 0xb6, 0x73, 0x3a, + 0x3c, 0x3e, 0x09, 0x08, 0x26, 0xd9, 0x32, 0xd3, 0x98, 0x82, 0xff, 0x18, 0x46, 0x30, 0xf0, 0xd7, + 0x01, 0xb0, 0x86, 0x55, 0xb1, 0x7b, 0x88, 0x93, 0xca, 0x63, 0xba, 0x7e, 0x26, 0x81, 0x48, 0x5f, + 0x46, 0xcd, 0x7a, 0x86, 0x90, 0x3e, 0x7f, 0xe2, 0x61, 0x4e, 0xe5, 0x20, 0xb9, 0x91, 0xf1, 0xa7, + 0x2e, 0x8d, 0x4f, 0x8f, 0xfb, 0xe3, 0xa9, 0xb6, 0x30, 0xc9, 0x98, 0xaa, 0xcc, 0x97, 0x90, 0xb9, + 0xed, 0x6b, 0x8c, 0x24, 0x43, 0xc6, 0x54, 0xb6, 0x6a, 0xb2, 0x15, 0xbf, 0xe7, 0x38, 0xbd, 0x4f, + 0x9f, 0x77, 0xf4, 0x19, 0xef, 0xa8, 0xd5, 0x19, 0x7a, 0xc4, 0xc8, 0xbd, 0x0a, 0xaf, 0xae, 0xab, + 0xa3, 0xba, 0x2f, 0x9c, 0xe3, 0xea, 0x69, 0xa6, 0x9f, 0x9f, 0xa2, 0x39, 0x15, 0xd4, 0x89, 0x7d, + 0x48, 0x92, 0x70, 0x48, 0x66, 0x18, 0xf9, 0xb4, 0x10, 0xb4, 0x60, 0xe3, 0x61, 0x7f, 0xfa, 0xf8, + 0x50, 0x46, 0x66, 0x08, 0xa2, 0x57, 0x87, 0x01, 0x50, 0x1a, 0x9a, 0xfb, 0xc7, 0xa0, 0xa0, 0xfd, + 0x11, 0x21, 0x4d, 0xce, 0x26, 0x14, 0x2b, 0x59, 0x2f, 0xc7, 0x50, 0x1c, 0xc5, 0x4b, 0x2d, 0x03, + 0x1a, 0x1d, 0x38, 0x41, 0xaf, 0x1d, 0x1a, 0x11, 0x06, 0x2e, 0x3a, 0xf8, 0x65, 0x4f, 0x85, 0x09, + 0xa7, 0x1c, 0xac, 0x73, 0x10, 0x74, 0x87, 0x4d, 0xc9, 0x53, 0xe8, 0x0d, 0xb4, 0x9d, 0x4d, 0x4b, + 0x6d, 0xf1, 0x13, 0xc9, 0xae, 0x52, 0x14, 0x45, 0xdf, 0xc1, 0x11, 0xe3, 0x11, 0x84, 0x5f, 0x9c, + 0xf8, 0x50, 0x94, 0xd5, 0x69, 0x93, 0x17, 0x1e, 0x5e, 0x74, 0xe9, 0xf7, 0xc1, 0x38, 0xa2, 0xa4, + 0x46, 0x2b, 0x71, 0x5c, 0x6f, 0xb7, 0x3c, 0x4b, 0x0a, 0x8b, 0xb9, 0xe6, 0xff, 0xd4, 0xe9, 0xf4, + 0x5e, 0xfa, 0x9d, 0x24, 0xea, 0x41, 0x44, 0x74, 0x4e, 0xfa, 0x2b, 0xc2, 0xdc, 0x12, 0x4f, 0x87, + 0xc3, 0x63, 0xb2, 0x29, 0x3a, 0x31, 0x92, 0x4e, 0x11, 0x11, 0x06, 0x83, 0x30, 0x04, 0xd7, 0x33, + 0xd5, 0x2d, 0xdc, 0xa9, 0x72, 0x04, 0xc6, 0xb2, 0x9b, 0x76, 0x78, 0xc3, 0x6c, 0x72, 0xc7, 0x05, + 0x51, 0xc4, 0x37, 0x5a, 0x5e, 0xc9, 0x90, 0x4e, 0x56, 0x98, 0x95, 0x78, 0x40, 0x28, 0x41, 0x34, + 0x6a, 0xa7, 0x13, 0x19, 0xcd, 0x90, 0x1a, 0x81, 0xe0, 0xb9, 0x23, 0xac, 0x6b, 0x70, 0x75, 0xb8, + 0x59, 0x68, 0xe7, 0x2a, 0x4d, 0xb9, 0x1f, 0x8c, 0xf8, 0xe6, 0x35, 0x24, 0x2b, 0x24, 0x62, 0x5b, + 0x53, 0x77, 0x78, 0x7e, 0x08, 0x4e, 0xdb, 0x77, 0xee, 0x26, 0x0a, 0xa9, 0x6b, 0x7a, 0x68, 0x36, + 0x63, 0xe6, 0x9a, 0x1e, 0x5f, 0x09, 0x14, 0x9e, 0xab, 0x3d, 0x24, 0xbc, 0x50, 0xce, 0xe8, 0xea, + 0x9a, 0xf8, 0x48, 0x4b, 0xbe, 0x1a, 0xc9, 0xcf, 0xd0, 0xf2, 0x25, 0x74, 0x4a, 0x88, 0xe8, 0xfa, + 0x93, 0xa2, 0x54, 0x67, 0x3d, 0x5b, 0x6d, 0x34, 0xff, 0xd5, 0xbe, 0x6d, 0x5d, 0x44, 0xf4, 0x47, + 0x2b, 0xae, 0x57, 0xd5, 0xfe, 0x8a, 0x7b, 0xeb, 0x97, 0xc5, 0x0e, 0x2b, 0x25, 0xf1, 0x16, 0x08, + 0xc1, 0xe5, 0x42, 0x9c, 0x7f, 0x85, 0x0d, 0xa4, 0x29, 0x04, 0x50, 0xc4, 0xb9, 0x4f, 0x19, 0x22, + 0x2a, 0x10, 0x66, 0xf8, 0x66, 0x69, 0x72, 0x97, 0x63, 0xa0, 0x06, 0x77, 0x5a, 0xec, 0x87, 0xdc, + 0x00, 0xc5, 0x92, 0xcd, 0xc2, 0xe3, 0x56, 0xdc, 0x5e, 0x9c, 0xf8, 0x52, 0x81, 0xfd, 0x63, 0x0d, + 0xc5, 0x3a, 0xb9, 0xa7, 0x3d, 0x3b, 0x18, 0x9c, 0x8c, 0xfd, 0xcc, 0x92, 0x60, 0x2d, 0xd0, 0x52, + 0xc6, 0x0d, 0x98, 0xde, 0x7d, 0x49, 0x43, 0x89, 0x1f, 0x0a, 0xd1, 0x09, 0x2b, 0xd3, 0xe4, 0xbd, + 0x3d, 0x37, 0x7f, 0x84, 0x6a, 0x2f, 0xaa, 0xe3, 0x23, 0xe0, 0xac, 0x1c, 0x20, 0x44, 0xaa, 0xce, + 0xdb, 0x4e, 0x69, 0xba, 0x78, 0x23, 0x2a, 0x7d, 0x76, 0x2b, 0x4b, 0x98, 0x7c, 0x22, 0xf8, 0x2c, + 0x2e, 0x23, 0x95, 0x52, 0x18, 0xb4, 0x30, 0xf7, 0x76, 0x57, 0x09, 0x88, 0x7d, 0xf3, 0xf8, 0xce, + 0x82, 0xa9, 0x51, 0xfa, 0xd5, 0x75, 0x8d, 0xf5, 0x62, 0x37, 0x82, 0x3a, 0xd6, 0xc7, 0xd5, 0x8f, + 0xac, 0x8e, 0x93, 0x75, 0xab, 0xe0, 0x9c, 0x54, 0x2a, 0x5c, 0x06, 0x89, 0x52, 0x2a, 0x16, 0xa4, + 0xc1, 0x30, 0x27, 0x45, 0xdb, 0xd7, 0xc6, 0x08, 0x75, 0x19, 0x18, 0xa3, 0x65, 0x66, 0x0e, 0xb6, + 0x44, 0x9c, 0x8d, 0x07, 0x38, 0x81, 0xca, 0x3c, 0xd2, 0x66, 0x32, 0x46, 0x8e, 0x5e, 0x34, 0x51, + 0xd6, 0xa2, 0xe9, 0x2b, 0x13, 0xf2, 0x47, 0xd2, 0x7d, 0x1e, 0x14, 0xe8, 0x94, 0xc2, 0xdc, 0x99, + 0xbb, 0xa0, 0x86, 0xe8, 0xaf, 0xb0, 0xb8, 0x1d, 0xa9, 0x71, 0x60, 0x72, 0x92, 0x7a, 0xe8, 0x3a, + 0x0f, 0xd3, 0xae, 0x2b, 0x62, 0xcb, 0x55, 0x6e, 0xf7, 0x35, 0xfc, 0xdf, 0x90, 0xed, 0x4b, 0xf9, + 0x57, 0xf1, 0x22, 0xf5, 0xaa, 0xd5, 0x7c, 0x66, 0x0d, 0xf4, 0x71, 0xae, 0x93, 0x91, 0x3c, 0xef, + 0xf7, 0xb5, 0xea, 0x90, 0x5c, 0x3b, 0x57, 0x07, 0x2e, 0xd0, 0x8b, 0x3b, 0x5b, 0x76, 0xee, 0x55, + 0x6b, 0x4d, 0xd3, 0x60, 0x87, 0xc6, 0x46, 0x46, 0xfe, 0x67, 0xea, 0x53, 0x4a, 0x77, 0x45, 0x39, + 0xbf, 0x78, 0xc8, 0xf4, 0x95, 0x91, 0x74, 0x5f, 0xed, 0x65, 0xf5, 0x6d, 0xf4, 0xc5, 0xb9, 0x2a, + 0xc3, 0x5f, 0x82, 0x61, 0x27, 0x06, 0x0f, 0xc3, 0xaa, 0x1e, 0xc2, 0x8c, 0xd9, 0xbd, 0xbe, 0x3c, + 0xad, 0xaf, 0x7b, 0xec, 0xd7, 0xc5, 0x0c, 0x15, 0x8d, 0xaa, 0x23, 0xd8, 0x1e, 0x15, 0x3b, 0xf9, + 0x62, 0xb7, 0x0e, 0x30, 0x06, 0xe3, 0xe8, 0x2e, 0x9d, 0xae, 0xa4, 0x4b, 0xea, 0xe0, 0x25, 0xd5, + 0xfe, 0xa9, 0xd7, 0x90, 0xca, 0xbf, 0xab, 0xfd, 0x53, 0x27, 0xd1, 0x5a, 0x2f, 0x82, 0x83, 0x65, + 0xa4, 0xc6, 0x26, 0x48, 0x69, 0x35, 0x0f, 0xf8, 0x98, 0x29, 0xb8, 0x65, 0x4c, 0x2c, 0x2a, 0x99, + 0x55, 0x3d, 0x66, 0x4e, 0xff, 0x05, 0x3e, 0x30, 0x90, 0x1d, 0x3b, 0xeb, 0x3e, 0xa2, 0x9a, 0x83, + 0x5b, 0xcd, 0x66, 0x2f, 0xb6, 0x46, 0x37, 0x8e, 0x74, 0x05, 0xe9, 0x35, 0xd4, 0xaa, 0xf3, 0x0c, + 0xf0, 0x54, 0x45, 0xa4, 0x3d, 0xb2, 0xbd, 0xd4, 0xa0, 0xd5, 0x55, 0x55, 0x63, 0xfc, 0x15, 0xc9, + 0x87, 0x70, 0xbc, 0x9f, 0xe5, 0x97, 0xaa, 0xe2, 0xbb, 0xe3, 0x4a, 0x39, 0x4b, 0xdd, 0xc5, 0xbe, + 0x39, 0x72, 0xe5, 0xeb, 0x77, 0x12, 0xc1, 0xdb, 0xea, 0x7f, 0x7c, 0x4c, 0x12, 0xca, 0xb3, 0xd0, + 0x77, 0x27, 0x27, 0xf1, 0x51, 0x77, 0xac, 0xd5, 0xb1, 0x7f, 0x84, 0x0a, 0xed, 0xa8, 0xbd, 0x15, + 0x76, 0xe4, 0xca, 0x19, 0x88, 0x3e, 0x26, 0xef, 0xf3, 0x67, 0x8e, 0xad, 0x74, 0x6e, 0xe8, 0x1a, + 0xaa, 0xf8, 0x50, 0x65, 0x87, 0x50, 0xd5, 0xf1, 0x9c, 0xd4, 0x86, 0xb5, 0x52, 0x80, 0xa1, 0x0a, + 0x36, 0x2d, 0xf1, 0x93, 0x0a, 0x96, 0xb8, 0xef, 0xf2, 0xcb, 0x1b, 0x61, 0xe1, 0xe0, 0xff, 0x52, + 0x72, 0x04, 0xcf, 0x87, 0xc3, 0x63, 0xb0, 0xdd, 0x1d, 0x2c, 0x21, 0xd0, 0x86, 0x47, 0xf4, 0x13, + 0x73, 0xe0, 0x90, 0x20, 0x3a, 0x08, 0x97, 0x6a, 0x7c, 0x09, 0x4f, 0x3b, 0x49, 0x57, 0x82, 0xc1, + 0x46, 0x31, 0xb0, 0xf5, 0x58, 0xb6, 0x2f, 0x89, 0x39, 0x7b, 0xf7, 0xc1, 0x2e, 0x03, 0x53, 0xd2, + 0x2d, 0x44, 0x48, 0x2e, 0x7c, 0x69, 0x21, 0xa4, 0x48, 0x05, 0xf7, 0x5c, 0x37, 0x2f, 0x82, 0x13, + 0x1a, 0x02, 0x43, 0x61, 0xf1, 0x13, 0x9a, 0x2e, 0x3a, 0x88, 0x91, 0xc9, 0x7f, 0x36, 0x9e, 0xa5, + 0x32, 0x7f, 0x31, 0xf8, 0x57, 0xae, 0xbf, 0x0a, 0x10, 0x59, 0xcd, 0x09, 0x34, 0xc3, 0xad, 0x37, + 0x10, 0x6b, 0x74, 0x4e, 0xe8, 0x34, 0x26, 0x60, 0x2b, 0x2b, 0x1e, 0xd1, 0x5a, 0x3f, 0x5e, 0x10, + 0x59, 0xc5, 0xbb, 0x4d, 0xc7, 0x8a, 0x7e, 0xfc, 0x5f, 0xbe, 0x30, 0xaf, 0x38, 0x18, 0x1e, 0x64, + 0x15, 0xda, 0xfe, 0xb1, 0x46, 0x9a, 0x1d, 0x9a, 0xba, 0x99, 0xf8, 0xc3, 0x91, 0x8c, 0x8c, 0x45, + 0x77, 0xa1, 0xd7, 0x6c, 0xb9, 0xf8, 0x40, 0xb7, 0x78, 0x7d, 0x54, 0xd6, 0x69, 0xe9, 0xc7, 0x5d, + 0x1f, 0x8e, 0x3d, 0x08, 0xaa, 0xdc, 0x9d, 0xd1, 0x6d, 0x30, 0x63, 0x2b, 0xe0, 0x96, 0x87, 0x3a, + 0xe8, 0xe4, 0xbe, 0x23, 0xe4, 0x18, 0x15, 0x52, 0x38, 0x24, 0xb8, 0x80, 0xa0, 0x8c, 0xe3, 0x8b, + 0x22, 0x4e, 0x1b, 0x12, 0x81, 0x19, 0x61, 0xa7, 0xae, 0x0f, 0x16, 0x13, 0x0e, 0xe3, 0xfc, 0x59, + 0x43, 0x23, 0x59, 0x67, 0xb8, 0x84, 0x54, 0xc6, 0x77, 0xd8, 0x53, 0xa1, 0x75, 0xf5, 0xca, 0x4e, + 0x8b, 0x97, 0xce, 0x45, 0x15, 0x42, 0xa9, 0xa6, 0xbf, 0xd5, 0xeb, 0xab, 0xcb, 0xd5, 0xfe, 0xb9, + 0x57, 0x57, 0x3e, 0x08, 0xc9, 0xaa, 0xb9, 0x5c, 0x12, 0x65, 0x98, 0xf2, 0x34, 0x73, 0x8d, 0x87, + 0x82, 0x2f, 0x8a, 0xac, 0xbe, 0x0a, 0xe2, 0xe9, 0xfa, 0x8b, 0xbb, 0xee, 0x7c, 0x29, 0xaa, 0xb4, + 0x4f, 0x7c, 0x8b, 0xea, 0x34, 0xca, 0xa7, 0x69, 0x6c, 0xa6, 0x52, 0x9d, 0x8c, 0xbe, 0x14, 0x37, + 0xba, 0xf7, 0x5d, 0xfd, 0x07, 0x2d, 0x3e, 0xf8, 0x52, 0xa0, 0xf1, 0x92, 0xa6, 0x36, 0x0f, 0x1c, + 0x44, 0xf4, 0x38, 0x8e, 0xd0, 0x9b, 0x45, 0xe2, 0x3d, 0xe4, 0xfc, 0x9f, 0x82, 0x15, 0x51, 0x45, + 0xc5, 0x49, 0x85, 0x41, 0x2a, 0xa6, 0x17, 0xd6, 0x00, 0x4a, 0x27, 0x14, 0x26, 0x7c, 0x71, 0x65, + 0x4c, 0x41, 0x96, 0x9a, 0x6b, 0x2a, 0xcf, 0xe1, 0x42, 0x9c, 0x91, 0x88, 0x8b, 0xfd, 0x24, 0xaf, + 0x15, 0xba, 0x37, 0x77, 0xf8, 0x8e, 0x55, 0x1d, 0x34, 0x69, 0xf8, 0x4e, 0xf7, 0x8f, 0xc7, 0x3e, + 0x4a, 0x88, 0x85, 0xab, 0xc2, 0x85, 0xe7, 0x61, 0x6b, 0xb2, 0x8c, 0x5d, 0xd4, 0x19, 0x15, 0xf0, + 0x29, 0x17, 0x48, 0x31, 0xa6, 0xe5, 0x5e, 0x08, 0xe4, 0xa2, 0xc8, 0xba, 0x55, 0xe2, 0xea, 0x2e, + 0x91, 0x33, 0x2e, 0x78, 0x81, 0xe4, 0x87, 0x4e, 0x4c, 0x0f, 0x40, 0x63, 0x57, 0x25, 0x91, 0xdb, + 0xf8, 0xc1, 0x96, 0x73, 0xdb, 0x8c, 0x9d, 0xd0, 0x67, 0xf9, 0x5c, 0x63, 0xce, 0x3b, 0xf7, 0x65, + 0xc8, 0x7e, 0x0a, 0xfc, 0xf0, 0x92, 0x3a, 0x12, 0xac, 0x59, 0x56, 0xa8, 0xa7, 0x3c, 0x18, 0x06, + 0x47, 0x92, 0xac, 0x4c, 0x36, 0x13, 0xc1, 0xd5, 0xad, 0x6e, 0xbf, 0x83, 0x5f, 0x18, 0x4b, 0xa3, + 0x77, 0xd1, 0x72, 0xfa, 0xc5, 0x5c, 0x86, 0x29, 0x04, 0xa4, 0x17, 0xcb, 0xd5, 0x89, 0x7a, 0xc5, + 0x27, 0x34, 0xa4, 0x16, 0x9a, 0xf8, 0x6c, 0x8c, 0x6e, 0xd9, 0xa9, 0xfd, 0x34, 0x10, 0xab, 0xff, + 0x1b, 0x4d, 0x45, 0xe8, 0xe3, 0xd3, 0x70, 0x64, 0x74, 0x69, 0x54, 0xb0, 0x43, 0x3c, 0x15, 0x0f, + 0x60, 0xe1, 0xcc, 0xb8, 0xab, 0xff, 0x82, 0xbb, 0xf1, 0x3f, 0xa1, 0xa8, 0xba, 0x93, 0x0b, 0xe6, + 0x7c, 0x51, 0x6f, 0x69, 0x25, 0x55, 0xf1, 0x96, 0xb1, 0x5d, 0xe4, 0xb6, 0x6f, 0x1e, 0x58, 0x47, + 0xb0, 0xed, 0xd7, 0xc2, 0x83, 0x2e, 0x32, 0xc5, 0x83, 0x40, 0xed, 0xac, 0x41, 0x36, 0xb2, 0x03, + 0xf7, 0xa3, 0x22, 0xb2, 0x3a, 0x90, 0x95, 0xc0, 0x3b, 0xd2, 0xdb, 0xb1, 0xc3, 0x8b, 0x21, 0x45, + 0x48, 0x81, 0x8d, 0x9f, 0xc1, 0xf0, 0xa5, 0xab, 0x18, 0x1f, 0xf3, 0x0c, 0xba, 0x57, 0x6e, 0x42, + 0x77, 0xcf, 0xaf, 0xcf, 0x51, 0x2a, 0x70, 0x78, 0xf0, 0xab, 0x25, 0x61, 0xad, 0xa9, 0xb6, 0xd9, + 0x37, 0xce, 0xc1, 0x5e, 0x71, 0x31, 0x27, 0x15, 0xa8, 0x91, 0xca, 0x13, 0xbb, 0x27, 0x52, 0xc8, + 0x3d, 0x86, 0x95, 0xac, 0x00, 0x70, 0xb9, 0x93, 0x09, 0xa9, 0xe1, 0x3e, 0xef, 0x5a, 0xf8, 0x4c, + 0x49, 0xee, 0x4f, 0x76, 0x3f, 0x13, 0x0a, 0x6e, 0xcf, 0x41, 0xe5, 0xc5, 0x17, 0x26, 0x48, 0xb9, + 0xe7, 0x04, 0xcc, 0x62, 0x4a, 0xbc, 0x67, 0x76, 0xcd, 0x44, 0x5c, 0xe5, 0x95, 0x21, 0x2d, 0xcd, + 0x40, 0xff, 0x04, 0xbb, 0xad, 0xee, 0xef, 0xf7, 0x52, 0xf5, 0x17, 0xf1, 0x05, 0x75, 0x3b, 0x6d, + 0xb5, 0x6f, 0xe3, 0xf4, 0x0e, 0x6a, 0x46, 0x7c, 0x8f, 0xdd, 0xf1, 0x31, 0x02, 0x26, 0x3d, 0xf1, + 0x40, 0x59, 0x10, 0x3f, 0xc1, 0x50, 0x89, 0x87, 0x26, 0x49, 0x38, 0x69, 0xa5, 0x98, 0x4e, 0x6a, + 0xca, 0x55, 0x4e, 0x31, 0x7e, 0xc5, 0xbf, 0xc1, 0x5d, 0xe7, 0x8d, 0x0f, 0x42, 0xdb, 0x70, 0x6b, + 0xea, 0xe5, 0x3c, 0xf7, 0x89, 0x58, 0xcb, 0xe1, 0xb0, 0x9e, 0x1d, 0xdd, 0x7a, 0x2c, 0xfe, 0x0c, + 0x65, 0xc2, 0x7d, 0xe9, 0x34, 0xd2, 0xe8, 0xda, 0xae, 0x08, 0x4e, 0x99, 0x7a, 0xc6, 0x9d, 0x7a, + 0x2a, 0x75, 0xe8, 0x8c, 0x7d, 0x4a, 0x0a, 0xe8, 0xcd, 0xf5, 0x6f, 0xa2, 0xb9, 0x7c, 0x12, 0x48, + 0xcb, 0x1c, 0x8a, 0x0e, 0x1f, 0xc1, 0x40, 0xaa, 0x52, 0xd0, 0xc4, 0xba, 0x50, 0xfe, 0x0a, 0x75, + 0xaa, 0xae, 0xaa, 0x15, 0xfa, 0x5f, 0xe1, 0x42, 0x2c, 0x2d, 0x9a, 0xfe, 0x21, 0x82, 0xfc, 0x9f, + 0x71, 0x59, 0xea, 0x91, 0x46, 0x5a, 0xdd, 0xf0, 0x81, 0x69, 0x22, 0xa4, 0xb2, 0xaa, 0xbc, 0xd4, + 0xf0, 0x58, 0x72, 0x57, 0xae, 0x9a, 0xb4, 0xcc, 0xfe, 0x9f, 0x7c, 0x61, 0xb3, 0x50, 0xd6, 0x48, + 0x68, 0xf2, 0x85, 0xbf, 0x35, 0xd2, 0xd8, 0xbb, 0xb2, 0x81, 0x7a, 0x7b, 0x47, 0x30, 0xc3, 0x99, + 0xf8, 0x52, 0x32, 0x99, 0xa3, 0x39, 0x7b, 0x44, 0x73, 0x9d, 0x3d, 0xf2, 0x8e, 0x8d, 0x8b, 0x15, + 0xc7, 0xfc, 0x93, 0x93, 0x63, 0xbc, 0x4d, 0xf1, 0x97, 0xab, 0x9c, 0x3f, 0xa4, 0xca, 0x70, 0x36, + 0xad, 0x8a, 0x3f, 0x4e, 0xbe, 0x14, 0x96, 0x60, 0x33, 0x5a, 0xd9, 0x21, 0xa0, 0x76, 0xa5, 0x7d, + 0xe6, 0x33, 0xcc, 0xe3, 0x1a, 0x2b, 0x59, 0xf4, 0x1f, 0xb1, 0x69, 0xd6, 0x4e, 0xa9, 0x46, 0xf8, + 0x93, 0xdb, 0x21, 0xdb, 0x72, 0x33, 0x5f, 0x12, 0x53, 0xde, 0xe7, 0xb2, 0xe3, 0xd6, 0x7c, 0xab, + 0xc1, 0x46, 0xee, 0xf2, 0xf6, 0xab, 0x7f, 0x8c, 0x28, 0xe1, 0xc2, 0xb4, 0xd3, 0x17, 0x79, 0x32, + 0x17, 0x25, 0x64, 0xd4, 0x9c, 0xee, 0x63, 0x65, 0x5f, 0x19, 0x7c, 0x86, 0x17, 0xa0, 0xd5, 0x96, + 0x42, 0xd8, 0x14, 0x43, 0x91, 0x18, 0xed, 0x3b, 0xe6, 0x88, 0xfe, 0x7f, 0x85, 0x34, 0xa5, 0x82, + 0x05, 0xa6, 0xda, 0x3b, 0x2d, 0x50, 0xc2, 0x07, 0xd6, 0xd4, 0x7b, 0x3d, 0xcd, 0xbe, 0xfb, 0xa9, + 0xb8, 0x9d, 0x3e, 0x23, 0xc4, 0x0b, 0xde, 0xec, 0xce, 0x41, 0x77, 0x90, 0x71, 0x10, 0x48, 0x42, + 0x51, 0x11, 0xad, 0xc6, 0xfb, 0xe0, 0x9a, 0x95, 0x83, 0x69, 0xaa, 0x97, 0xca, 0xb6, 0xbe, 0xe2, + 0x61, 0x4c, 0xc9, 0x32, 0x23, 0x45, 0x21, 0xc9, 0x07, 0x80, 0xf0, 0x9b, 0x69, 0x0f, 0x69, 0xb4, + 0x7c, 0x54, 0xfc, 0x20, 0x2a, 0xd8, 0xc4, 0x54, 0x5b, 0x09, 0x16, 0x56, 0x9e, 0xf0, 0xcb, 0x09, + 0x2d, 0xc5, 0xdf, 0x82, 0x32, 0xd0, 0xd2, 0x19, 0x32, 0xeb, 0xe5, 0x0a, 0xe3, 0x6b, 0x8a, 0xe8, + 0x53, 0x1f, 0x5d, 0x7d, 0x1b, 0x52, 0x74, 0x7c, 0xbe, 0x5a, 0xdd, 0x27, 0xd7, 0x39, 0xf5, 0xce, + 0x7d, 0x73, 0x9f, 0x5e, 0x9f, 0x82, 0x32, 0x9f, 0x9b, 0x9f, 0xbb, 0x95, 0x3e, 0x0b, 0x05, 0x24, + 0xca, 0x45, 0xdc, 0x93, 0x3c, 0x1f, 0xb9, 0x30, 0xc4, 0x91, 0xdf, 0x87, 0x6b, 0x12, 0xb0, 0x6a, + 0xce, 0x4d, 0x5b, 0x29, 0xa8, 0x8f, 0xff, 0xe0, 0xa7, 0xb3, 0x35, 0xd3, 0xd2, 0x79, 0x33, 0x35, + 0xe2, 0x42, 0x82, 0x1d, 0xc5, 0x62, 0x1e, 0x3a, 0x60, 0x77, 0xe7, 0xbe, 0xbb, 0xc2, 0x8a, 0xbe, + 0x0f, 0xf7, 0x5f, 0x7d, 0x09, 0x6f, 0x10, 0x0a, 0x8a, 0xaa, 0x46, 0x26, 0x53, 0x66, 0xaa, 0x4a, + 0x2a, 0xcf, 0x3b, 0xe3, 0x05, 0x3b, 0xc9, 0x3d, 0x5d, 0x0a, 0xf5, 0x9f, 0x58, 0xde, 0x5e, 0x8a, + 0x68, 0x90, 0xf4, 0xd5, 0xe1, 0x83, 0xf9, 0xee, 0x3f, 0x7c, 0x29, 0x0e, 0x0c, 0x50, 0x9d, 0xbb, + 0xaa, 0x29, 0x94, 0xd5, 0x35, 0xd4, 0x99, 0x51, 0x72, 0x30, 0x2f, 0xf7, 0xc1, 0x59, 0xc6, 0x2f, + 0x47, 0x94, 0xe8, 0xc2, 0x02, 0x74, 0x40, 0xe0, 0x9a, 0x18, 0x16, 0x02, 0x51, 0x3d, 0x15, 0x2e, + 0xf8, 0x52, 0x2d, 0xbe, 0xfc, 0xae, 0x5a, 0x17, 0x53, 0x79, 0xa5, 0x32, 0x99, 0x44, 0xe3, 0x25, + 0xbd, 0x7c, 0x61, 0xe2, 0x25, 0xb6, 0x99, 0xbf, 0xa7, 0x0c, 0xd3, 0xe6, 0x65, 0x8d, 0x27, 0xf1, + 0x3a, 0xd5, 0x6e, 0x4b, 0xe2, 0x06, 0x14, 0x44, 0x30, 0x13, 0x28, 0x17, 0x64, 0x06, 0x53, 0x3b, + 0xe4, 0x81, 0xb1, 0x52, 0x7b, 0x62, 0x7f, 0x14, 0x92, 0xcb, 0x88, 0x18, 0x44, 0x34, 0x06, 0x56, + 0x39, 0x52, 0x51, 0x8a, 0x20, 0xed, 0x26, 0xb5, 0x11, 0x00, 0x00, 0xcf, 0x82, 0xb3, 0x17, 0xa9, + 0x79, 0x3a, 0xcd, 0x65, 0xe4, 0xf1, 0xfd, 0xf1, 0x05, 0x55, 0xab, 0x57, 0xae, 0x2c, 0x8b, 0x57, + 0x78, 0x97, 0x8e, 0x47, 0x78, 0xc2, 0xa5, 0x29, 0x1b, 0x6f, 0xd7, 0xcb, 0xdb, 0x57, 0x18, 0xdc, + 0x51, 0xa6, 0x86, 0x08, 0x09, 0x3d, 0xa3, 0x13, 0x1d, 0x9d, 0x25, 0x25, 0xa3, 0x86, 0x8d, 0xe1, + 0x27, 0x9b, 0x4f, 0x14, 0x37, 0x9b, 0xf0, 0xa1, 0x46, 0x7c, 0xa7, 0xcb, 0x7d, 0xb4, 0x82, 0x3d, + 0x90, 0x47, 0x9b, 0x5e, 0x42, 0x49, 0x19, 0xb3, 0x0e, 0x28, 0xdb, 0xa8, 0xf3, 0x68, 0xd8, 0x21, + 0x3d, 0xf0, 0xa1, 0x2f, 0x26, 0xa9, 0x29, 0x93, 0x26, 0x20, 0xb0, 0x6c, 0xcc, 0xb9, 0x4e, 0xbc, + 0x40, 0xa8, 0x60, 0xfe, 0x94, 0xe9, 0xa2, 0x71, 0x2e, 0x5f, 0x89, 0xf1, 0xd3, 0x1c, 0x13, 0xc5, + 0x78, 0x99, 0x8e, 0xb5, 0x84, 0x7a, 0xc1, 0x5d, 0x5b, 0xeb, 0x1a, 0x4e, 0xb1, 0xef, 0xa2, 0xf8, + 0xae, 0x17, 0x9f, 0x91, 0xa1, 0xb4, 0x75, 0xb4, 0xc6, 0xb9, 0x8b, 0x8d, 0x6b, 0x28, 0xab, 0x5f, + 0xf0, 0x91, 0x8d, 0x9a, 0xe9, 0x3f, 0xc1, 0x59, 0x4b, 0x55, 0xf6, 0x92, 0x3e, 0xab, 0xa9, 0x3b, + 0xf1, 0x30, 0xa6, 0x93, 0xbb, 0xe9, 0x17, 0x09, 0x15, 0xbb, 0x7a, 0x88, 0x38, 0x32, 0x67, 0xfc, + 0x48, 0xc1, 0x47, 0x62, 0xcb, 0x6e, 0xf9, 0xb1, 0xcf, 0x13, 0xd6, 0x0f, 0x1f, 0x37, 0xaf, 0x84, + 0x04, 0xd3, 0x27, 0xdb, 0xfc, 0xbf, 0xf8, 0x26, 0x2b, 0xdd, 0xd0, 0x9c, 0xe9, 0x2f, 0xbe, 0x14, + 0x11, 0x2d, 0x99, 0x21, 0xc0, 0xb0, 0x4a, 0x34, 0xd0, 0x82, 0x6c, 0x83, 0x52, 0xd9, 0x98, 0xb7, + 0xf8, 0x37, 0xb3, 0xf7, 0xc7, 0x58, 0xeb, 0xad, 0x55, 0xbf, 0xc2, 0x85, 0x4f, 0x24, 0x08, 0x42, + 0x4f, 0xb2, 0x0d, 0x1e, 0x31, 0x9b, 0x3d, 0x36, 0x44, 0xc3, 0xdf, 0x0a, 0x09, 0x5d, 0x0f, 0x6c, + 0x8a, 0x5e, 0x55, 0x71, 0x3a, 0x15, 0xb3, 0x3d, 0x1f, 0xe1, 0x42, 0x5f, 0x7c, 0xf9, 0x2b, 0x02, + 0x56, 0x21, 0xd1, 0xae, 0x4c, 0x49, 0x6b, 0x77, 0xf8, 0x28, 0xea, 0xaa, 0xc6, 0x6a, 0x7d, 0xc4, + 0x89, 0x17, 0x6d, 0x58, 0xf7, 0x7f, 0xb2, 0x12, 0x13, 0x4b, 0xc1, 0x4d, 0xb5, 0x48, 0x98, 0xc5, + 0x1c, 0x56, 0x5b, 0x4e, 0xfe, 0x20, 0xc3, 0x68, 0xcb, 0x9f, 0x84, 0x88, 0x4c, 0x5b, 0xd6, 0xbe, + 0x3c, 0x66, 0xed, 0x3e, 0xd3, 0xd2, 0x6b, 0xe0, 0xa0, 0xf6, 0xce, 0x4f, 0x93, 0xac, 0xd7, 0x11, + 0x1c, 0x7c, 0xd8, 0x53, 0x16, 0x51, 0xa6, 0xa5, 0x48, 0x9b, 0x65, 0x99, 0xc0, 0xcf, 0x4c, 0x34, + 0x71, 0x4a, 0x78, 0x4f, 0x45, 0x2d, 0x06, 0x6c, 0x46, 0x49, 0x86, 0x0e, 0x2f, 0x0a, 0x40, 0x75, + 0x50, 0xe1, 0x0c, 0x7e, 0x91, 0xa0, 0xb6, 0x72, 0x65, 0xaa, 0x51, 0x99, 0x3c, 0xd0, 0xa2, 0x7e, + 0x74, 0xb9, 0x5f, 0x11, 0x07, 0x31, 0x60, 0x7a, 0xad, 0x48, 0xd2, 0x46, 0x6a, 0xce, 0x48, 0xb6, + 0x9c, 0xab, 0xc6, 0x10, 0x75, 0x60, 0x3d, 0xda, 0xb6, 0x45, 0xc1, 0xad, 0x1a, 0xe4, 0xf3, 0x22, + 0x5b, 0xa6, 0x2a, 0xd2, 0xcf, 0xbc, 0xb4, 0xf0, 0xb8, 0xa1, 0x0d, 0x30, 0x8a, 0xe1, 0x44, 0xdb, + 0x4d, 0xcc, 0x75, 0x7f, 0xf8, 0xda, 0xd5, 0x0c, 0x4d, 0x57, 0x24, 0x44, 0x85, 0xc6, 0xf7, 0x26, + 0xeb, 0x96, 0xab, 0xf8, 0x4b, 0xa1, 0x2e, 0x7c, 0xd4, 0x74, 0x62, 0xcd, 0x71, 0x25, 0x9e, 0xe5, + 0xb4, 0x65, 0xcc, 0x59, 0x8b, 0x35, 0xc9, 0x75, 0x57, 0xf5, 0x83, 0xeb, 0x15, 0x77, 0x75, 0x5f, + 0x82, 0x68, 0xca, 0x63, 0xe7, 0xfc, 0xa9, 0xe2, 0x41, 0x01, 0x87, 0x2b, 0xe2, 0x12, 0xb1, 0x68, + 0x4f, 0x36, 0xb5, 0x50, 0xdc, 0xe3, 0xb0, 0xbb, 0x2d, 0x79, 0x9a, 0xae, 0xff, 0xc4, 0x74, 0x35, + 0xa5, 0x7f, 0x15, 0x66, 0x9b, 0x06, 0xa8, 0xd1, 0xc9, 0x7e, 0x2a, 0x96, 0xae, 0x91, 0x71, 0x9f, + 0xc4, 0x0d, 0x10, 0xfa, 0x4c, 0x66, 0x87, 0x25, 0x86, 0xe5, 0x85, 0xbe, 0x2a, 0xd5, 0xe4, 0x85, + 0x7f, 0xe0, 0x98, 0x6c, 0x98, 0x8f, 0x51, 0x75, 0x37, 0x7f, 0x85, 0x28, 0x6a, 0xb4, 0x26, 0xd3, + 0x15, 0x6f, 0x63, 0x6d, 0x0d, 0x34, 0x37, 0x1a, 0xa7, 0xc2, 0x84, 0x91, 0x0f, 0x58, 0xdf, 0x16, + 0xd5, 0xa6, 0xe4, 0xcf, 0x7b, 0xdb, 0xf1, 0xf0, 0x4f, 0x55, 0xdc, 0xcc, 0x31, 0xd1, 0xff, 0xe0, + 0xab, 0x24, 0x82, 0x47, 0xe1, 0xc6, 0x0c, 0x47, 0xa6, 0x5d, 0xcf, 0x7c, 0x11, 0x15, 0x3b, 0x57, + 0x7f, 0x82, 0xa8, 0x95, 0x8e, 0xdd, 0xdf, 0x9f, 0xdf, 0x9f, 0xe1, 0x43, 0xe6, 0x50, 0xaf, 0x37, + 0x52, 0xf2, 0x51, 0x5d, 0x9a, 0x86, 0xd9, 0x15, 0x31, 0xef, 0x90, 0x55, 0xd5, 0x3f, 0x08, 0x1f, + 0x46, 0xa3, 0x14, 0xd9, 0x0a, 0xaa, 0xf8, 0x85, 0xee, 0x26, 0x8e, 0xf5, 0xc6, 0x0e, 0xca, 0x65, + 0x25, 0xdc, 0x9f, 0x8f, 0x4b, 0x1f, 0x32, 0xdb, 0x47, 0xf1, 0x82, 0x50, 0x44, 0x35, 0x5c, 0x9d, + 0xb7, 0x02, 0x04, 0xdf, 0x70, 0xc1, 0x20, 0xc1, 0x3d, 0xef, 0x0c, 0x3f, 0x04, 0xa4, 0x5e, 0x14, + 0xb2, 0x92, 0x2a, 0xb6, 0x19, 0xe4, 0x85, 0x9f, 0x18, 0x25, 0x31, 0xa6, 0x4b, 0xa1, 0x97, 0x36, + 0x20, 0xc0, 0x27, 0x09, 0xbf, 0x62, 0x16, 0x21, 0x09, 0xfd, 0xd2, 0xf7, 0xca, 0x83, 0x25, 0x3c, + 0x59, 0x0a, 0xc2, 0x4f, 0x00, 0xe5, 0xa3, 0x9e, 0x97, 0xc4, 0x05, 0x0a, 0x7c, 0x7b, 0x01, 0x23, + 0xc0, 0x3b, 0x5e, 0xad, 0xca, 0x1c, 0x08, 0x84, 0xa1, 0xf5, 0x34, 0xa8, 0x91, 0xbf, 0xc1, 0x29, + 0xb4, 0x89, 0x44, 0x76, 0x78, 0xee, 0xf8, 0xc1, 0x0e, 0xee, 0xef, 0xe6, 0x5e, 0xd8, 0x89, 0xf7, + 0x75, 0x69, 0x8d, 0xf8, 0xd9, 0xf0, 0xf9, 0x5c, 0x9e, 0x82, 0xb7, 0x66, 0xf8, 0x29, 0xc9, 0xbc, + 0xc1, 0xea, 0x3c, 0xa4, 0x4a, 0x6a, 0x4b, 0x45, 0xf2, 0x74, 0x27, 0xe1, 0xf5, 0xfb, 0xee, 0x75, + 0x29, 0xcd, 0x53, 0x74, 0x4a, 0x8a, 0xe4, 0xb3, 0x66, 0xcd, 0x9f, 0xab, 0xab, 0x87, 0x25, 0xf4, + 0xc8, 0xce, 0xb7, 0x8a, 0xff, 0xc6, 0xdc, 0x4f, 0x1a, 0x9d, 0x03, 0x29, 0xb9, 0x2e, 0x49, 0x57, + 0x41, 0xe4, 0xe6, 0x86, 0x0b, 0x41, 0xf2, 0xc9, 0x22, 0x12, 0xff, 0xfd, 0x5f, 0xe0, 0xb8, 0xa5, + 0xe8, 0xe4, 0x96, 0x90, 0xf3, 0x5e, 0xf8, 0x2c, 0xd4, 0x6d, 0xa7, 0x17, 0x17, 0x2f, 0x5e, 0x6c, + 0x25, 0x1f, 0xc4, 0x05, 0x05, 0x46, 0x28, 0xdd, 0x9b, 0x1a, 0x6d, 0xa6, 0x98, 0xf9, 0x85, 0x79, + 0x3f, 0x56, 0xd5, 0x7b, 0x5d, 0xf0, 0xa0, 0xf7, 0xa0, 0x99, 0x21, 0xd6, 0xad, 0xa1, 0xb0, 0x12, + 0x26, 0x51, 0xcd, 0x36, 0x7c, 0x51, 0xaa, 0x84, 0x6b, 0x26, 0x4f, 0xe0, 0xb0, 0xac, 0x53, 0xb0, + 0xef, 0x19, 0x18, 0x54, 0xdd, 0xd0, 0x0d, 0x5c, 0xf8, 0x2e, 0x98, 0x30, 0x13, 0x90, 0xe5, 0x7b, + 0xb3, 0xa0, 0x63, 0x01, 0xb8, 0x98, 0x52, 0x4f, 0x58, 0xd6, 0x59, 0x2f, 0xb6, 0x1a, 0x18, 0x8a, + 0x03, 0x4e, 0xef, 0x03, 0xea, 0x06, 0x04, 0x83, 0xb9, 0x30, 0x7d, 0x8c, 0x7c, 0x48, 0x80, 0x4c, + 0x44, 0x39, 0x94, 0x10, 0xcb, 0x94, 0x1c, 0xf8, 0xa3, 0xef, 0x82, 0x43, 0xbd, 0xe5, 0x57, 0x13, + 0x05, 0x33, 0xb1, 0x6e, 0xee, 0x62, 0x65, 0x71, 0xc0, 0x38, 0x03, 0x7f, 0xe2, 0x44, 0x02, 0x23, + 0x1e, 0x54, 0x8b, 0xd8, 0xf8, 0x26, 0xcb, 0xfd, 0x4d, 0x47, 0xf1, 0x20, 0x8f, 0x54, 0xbd, 0xf1, + 0x25, 0x66, 0x4a, 0x13, 0xb2, 0x89, 0xdd, 0x3f, 0x1e, 0x20, 0xff, 0x93, 0xb3, 0x8e, 0x42, 0x5e, + 0xd3, 0x7f, 0x0a, 0x1d, 0xb8, 0x6f, 0x65, 0x78, 0xcc, 0xfa, 0xb5, 0x86, 0x10, 0xf0, 0xe9, 0x86, + 0x93, 0x2f, 0xb9, 0x92, 0x13, 0xfc, 0x28, 0x58, 0x83, 0xf8, 0x75, 0x9c, 0xca, 0x14, 0x36, 0x99, + 0xb8, 0x30, 0x11, 0xe1, 0xac, 0xb1, 0x9a, 0x35, 0xf3, 0x50, 0x39, 0x97, 0x63, 0xe0, 0xac, 0x83, + 0x46, 0x85, 0xa3, 0x09, 0xa6, 0x27, 0xb0, 0x3e, 0xbc, 0xe9, 0xae, 0x2f, 0x21, 0xc0, 0x1b, 0xd9, + 0xb0, 0x34, 0xab, 0xc7, 0x75, 0x38, 0x8f, 0x46, 0x4a, 0x78, 0x6e, 0x11, 0xe6, 0x8a, 0x78, 0x4f, + 0xbd, 0x99, 0x3c, 0xc3, 0x04, 0xb3, 0xf1, 0xe5, 0x1c, 0x84, 0xb4, 0xc5, 0xe6, 0x2d, 0x83, 0xc8, + 0x37, 0xd0, 0x3c, 0xb9, 0xe0, 0x8f, 0x72, 0xe5, 0xa5, 0x4b, 0x87, 0x86, 0x1b, 0x7b, 0xea, 0xc8, + 0x7a, 0xc3, 0xad, 0xd0, 0xbd, 0xcf, 0x20, 0x25, 0xe4, 0xf3, 0x1f, 0xfc, 0xe5, 0x38, 0x42, 0xc8, + 0x30, 0x42, 0x61, 0xa1, 0xc7, 0x1f, 0x93, 0xa2, 0xc5, 0x5d, 0x58, 0xfa, 0xb0, 0x5d, 0x19, 0xef, + 0xa9, 0xc1, 0x37, 0x5a, 0x88, 0xe1, 0xeb, 0xa5, 0xc5, 0x71, 0x5c, 0x32, 0xe4, 0x0b, 0x26, 0x3c, + 0x63, 0x51, 0x85, 0xf1, 0x94, 0x94, 0xbf, 0xf0, 0x4a, 0x57, 0x41, 0x14, 0xf6, 0xed, 0xf7, 0xcb, + 0xb6, 0xc1, 0x98, 0x69, 0xe2, 0x01, 0x38, 0x8e, 0x6c, 0x82, 0xfa, 0xe2, 0xd6, 0x67, 0xf1, 0x02, + 0x04, 0xb6, 0xdc, 0x6d, 0xc7, 0x54, 0xfc, 0xdb, 0xdf, 0xc1, 0x09, 0x60, 0xee, 0xef, 0xc4, 0xc1, + 0x55, 0x57, 0x51, 0x1a, 0x0b, 0x9d, 0xeb, 0x46, 0xac, 0x18, 0xec, 0x77, 0xe3, 0x2a, 0x53, 0x1d, + 0xa1, 0x48, 0xa7, 0xa4, 0x78, 0xde, 0xd1, 0xb7, 0xca, 0xc4, 0xac, 0x65, 0x61, 0xdb, 0xf1, 0x10, + 0x59, 0xc8, 0xd4, 0x19, 0x58, 0x2b, 0x10, 0x7d, 0x46, 0x44, 0x82, 0xb4, 0xab, 0x88, 0x05, 0x9c, + 0xbe, 0x78, 0xe6, 0x70, 0xcd, 0x4a, 0x20, 0x79, 0x57, 0x82, 0xac, 0x8b, 0xe6, 0xea, 0x32, 0x70, + 0xec, 0xca, 0x47, 0xea, 0xac, 0x76, 0x7f, 0x8e, 0xdc, 0xff, 0x1f, 0x4c, 0x77, 0xdd, 0x04, 0x5f, + 0xc4, 0x82, 0x4e, 0x56, 0x0f, 0x9c, 0xad, 0x70, 0x50, 0x6c, 0xb9, 0x8a, 0xc7, 0x7d, 0x8a, 0x6f, + 0x85, 0x22, 0xba, 0x24, 0x0d, 0xdd, 0x37, 0xcd, 0x8b, 0xb3, 0x1e, 0x88, 0xef, 0x8c, 0x3b, 0x4b, + 0xa2, 0x78, 0xd3, 0x84, 0x35, 0x59, 0x4c, 0x68, 0x94, 0x93, 0x61, 0xb6, 0xb6, 0xfc, 0x12, 0xf2, + 0x80, 0x4b, 0x50, 0xce, 0x02, 0x7e, 0x62, 0xd1, 0xda, 0x49, 0x17, 0x85, 0x38, 0x6c, 0x12, 0xa3, + 0xa2, 0xad, 0x51, 0xa6, 0x64, 0xc8, 0x20, 0x70, 0xe5, 0xf8, 0x66, 0x9f, 0x0d, 0xf8, 0x18, 0xdb, + 0x96, 0x31, 0x2d, 0xc2, 0x1d, 0x79, 0xa6, 0x13, 0x69, 0xaf, 0x03, 0xc8, 0x5c, 0xbb, 0x41, 0xd3, + 0x89, 0x85, 0x35, 0x10, 0x5b, 0xb5, 0x02, 0x21, 0xea, 0x5a, 0x4e, 0x72, 0xbc, 0x03, 0xcc, 0x9f, + 0x2b, 0x55, 0x33, 0x0c, 0xd1, 0x8a, 0xfc, 0x40, 0x52, 0x5a, 0x0e, 0x0c, 0xeb, 0x6f, 0xf3, 0x23, + 0x4c, 0xb5, 0xe3, 0x1a, 0xb1, 0xd1, 0x68, 0xd3, 0x8c, 0x61, 0xac, 0x06, 0x6d, 0x7f, 0x82, 0x6d, + 0xdc, 0x67, 0xc3, 0x4d, 0xea, 0x08, 0x4c, 0x48, 0xc8, 0x33, 0xc4, 0x02, 0xb2, 0xb3, 0x39, 0x4a, + 0x44, 0xf9, 0x68, 0xfa, 0x8b, 0x95, 0x3e, 0x2e, 0x5c, 0x6a, 0x03, 0x74, 0xa5, 0xa7, 0xc2, 0x24, + 0x63, 0x65, 0xbe, 0xfb, 0x6a, 0xaa, 0xbe, 0x0c, 0x06, 0x4f, 0x1b, 0x18, 0xde, 0x5f, 0x83, 0x19, + 0x14, 0x51, 0xff, 0x86, 0xc4, 0xa7, 0x2c, 0x58, 0x6a, 0x48, 0xa2, 0x39, 0x8b, 0x61, 0xfe, 0xe9, + 0x25, 0x69, 0xf4, 0x47, 0xfa, 0x2b, 0xfd, 0x5e, 0xfa, 0xc5, 0xf5, 0x7a, 0xe0, 0x8e, 0x87, 0xbb, + 0xc9, 0xc9, 0x4b, 0x69, 0xf5, 0x79, 0x78, 0x24, 0x9e, 0x29, 0x99, 0xab, 0x82, 0x47, 0x7c, 0x3a, + 0x46, 0x93, 0x40, 0x26, 0x6f, 0xeb, 0x59, 0xb1, 0xed, 0xa9, 0x8a, 0x57, 0x9d, 0xc3, 0x85, 0x07, + 0xf8, 0x2d, 0x29, 0xa0, 0x56, 0x7e, 0x38, 0x98, 0xd7, 0xc4, 0x1d, 0x82, 0x4e, 0x44, 0xee, 0x99, + 0x44, 0x08, 0x9a, 0x45, 0xe6, 0xf5, 0x01, 0x01, 0x79, 0x08, 0xe8, 0x3a, 0xe2, 0x63, 0x21, 0xea, + 0x7e, 0xfc, 0x88, 0xb6, 0xcd, 0xb9, 0xf6, 0xdb, 0x1b, 0x42, 0x5c, 0x6e, 0x2d, 0x40, 0x90, 0x52, + 0x9c, 0x48, 0x29, 0xad, 0x57, 0x6e, 0xb4, 0xc1, 0x92, 0x50, 0xd8, 0xd3, 0x37, 0x40, 0xdf, 0xe3, + 0x04, 0x3f, 0xb6, 0x4c, 0xe1, 0xec, 0x26, 0xed, 0x86, 0xfc, 0xb4, 0x8b, 0xe0, 0xd7, 0xf8, 0x25, + 0x12, 0xc7, 0x6c, 0xd3, 0x7d, 0xdb, 0xe6, 0x2c, 0x8a, 0x48, 0xa5, 0x56, 0x31, 0x10, 0x57, 0x6e, + 0x75, 0x29, 0xca, 0x6a, 0x29, 0x18, 0xfd, 0x2e, 0xcf, 0x99, 0xfc, 0x40, 0x27, 0x22, 0xca, 0xd1, + 0xca, 0xa5, 0xc6, 0xa9, 0xe2, 0x41, 0x49, 0x43, 0xd2, 0x46, 0xa2, 0x91, 0xc6, 0xd6, 0x3a, 0x04, + 0xab, 0x0e, 0xd5, 0xb1, 0xa8, 0x7e, 0x24, 0x29, 0xbd, 0x1e, 0xcc, 0xf4, 0x79, 0xe0, 0x99, 0xd8, + 0xff, 0xf8, 0x88, 0x52, 0x65, 0x0a, 0xe6, 0x1a, 0xa3, 0x23, 0x25, 0x12, 0x7b, 0x02, 0x2a, 0x2c, + 0xc4, 0xd6, 0x49, 0xbc, 0xa8, 0xed, 0xe2, 0x41, 0x19, 0x8c, 0xa3, 0xeb, 0xe0, 0xa2, 0xab, 0xf3, + 0x4b, 0xbe, 0x5c, 0x5f, 0xf1, 0x99, 0x58, 0x2c, 0x1f, 0x2a, 0x78, 0x1b, 0xb9, 0x6b, 0x36, 0xda, + 0x74, 0x34, 0x3f, 0x08, 0x95, 0x38, 0x64, 0x49, 0x50, 0xd8, 0xf0, 0xc0, 0x9c, 0x6d, 0x41, 0x76, + 0x6f, 0x9d, 0x49, 0x56, 0x58, 0xc3, 0xb7, 0xc4, 0x02, 0xc8, 0xc5, 0x1e, 0x8b, 0x18, 0xd2, 0x80, + 0x59, 0x04, 0x1e, 0x6b, 0x07, 0xee, 0xad, 0x2b, 0x86, 0x0c, 0xbb, 0xbf, 0x88, 0x0a, 0x6e, 0xd2, + 0x95, 0x24, 0x7c, 0x1b, 0x2b, 0x4c, 0x7b, 0x89, 0x8c, 0x31, 0x23, 0x0c, 0x81, 0xa7, 0x6a, 0x7f, + 0x6e, 0x8c, 0x57, 0x85, 0x2c, 0xe7, 0x61, 0xff, 0x45, 0x6e, 0x18, 0xd4, 0x8c, 0x97, 0xb9, 0xa0, + 0x76, 0x07, 0xc4, 0x05, 0x50, 0x84, 0x2a, 0x2a, 0xf0, 0xa7, 0xd1, 0xb4, 0xcb, 0xba, 0x44, 0x43, + 0xf0, 0x12, 0xc3, 0xa7, 0x31, 0x99, 0x0e, 0xac, 0xa4, 0x0a, 0x1f, 0xc7, 0xc6, 0x62, 0xe8, 0x12, + 0xc6, 0x04, 0x14, 0x67, 0x4d, 0x82, 0x93, 0x39, 0x28, 0x6a, 0x7e, 0x3b, 0x1e, 0x9d, 0x8c, 0x76, + 0x99, 0xc6, 0xb0, 0x1e, 0x8e, 0xa7, 0x5e, 0x20, 0x13, 0x56, 0x38, 0x3f, 0x1a, 0xe4, 0xd6, 0xb9, + 0x77, 0xca, 0x52, 0x41, 0xa6, 0x55, 0xc3, 0xc6, 0xcf, 0xe3, 0x39, 0x52, 0xd0, 0xae, 0xbe, 0xc2, + 0x66, 0x8d, 0x7f, 0xf0, 0x60, 0x29, 0x28, 0xe1, 0x46, 0x5b, 0x3b, 0x39, 0xfa, 0x18, 0x98, 0x1a, + 0x7a, 0x16, 0x6b, 0x4a, 0x6d, 0x53, 0xeb, 0x90, 0x5d, 0x55, 0x5f, 0x25, 0x26, 0xab, 0xeb, 0x52, + 0xf7, 0x3a, 0x92, 0x29, 0xfd, 0x5f, 0xeb, 0xa9, 0xba, 0x33, 0xa5, 0xe0, 0xb4, 0x95, 0x35, 0x27, + 0x6a, 0x92, 0x62, 0x53, 0x1e, 0xf8, 0x52, 0xce, 0xe8, 0x1d, 0x83, 0xa0, 0xe2, 0xbb, 0x71, 0x79, + 0x17, 0x17, 0x7d, 0x9b, 0x78, 0x80, 0x99, 0xd7, 0x17, 0x5b, 0x64, 0x87, 0xe3, 0x04, 0xc6, 0xf2, + 0x3d, 0x1b, 0x9c, 0xd1, 0x9c, 0x88, 0x0e, 0x21, 0x61, 0xb6, 0x36, 0x9a, 0x5f, 0x29, 0x0d, 0x1f, + 0xf1, 0x5b, 0xe7, 0x20, 0xb7, 0x90, 0x83, 0xf1, 0xd4, 0x0d, 0xa8, 0x91, 0xae, 0x6c, 0x3c, 0x95, + 0x2a, 0x4e, 0x33, 0xe4, 0x25, 0x3b, 0x7e, 0x3b, 0x8f, 0x21, 0x6d, 0xae, 0xb7, 0x04, 0xa8, 0x20, + 0x2f, 0xea, 0x72, 0xf0, 0x52, 0x51, 0x94, 0xc3, 0x58, 0xd1, 0xfa, 0xb5, 0x73, 0xd2, 0xc8, 0xbf, + 0x8b, 0x99, 0x46, 0xa5, 0x52, 0xbf, 0xc6, 0x66, 0x52, 0xc7, 0x1b, 0xd9, 0xd5, 0x0d, 0x3b, 0x76, + 0xde, 0xb3, 0x33, 0x7f, 0x05, 0xd7, 0x31, 0x6d, 0x36, 0xef, 0x63, 0xe0, 0xa6, 0xee, 0x48, 0xee, + 0xe8, 0x77, 0x56, 0xd7, 0xbe, 0x0b, 0x3c, 0xbc, 0x56, 0xee, 0xe7, 0xec, 0x55, 0x5c, 0x1a, 0x55, + 0xe1, 0x0b, 0x6d, 0xd1, 0xb7, 0x73, 0xe5, 0x57, 0xf0, 0x81, 0x2e, 0xfd, 0x48, 0x41, 0x53, 0x79, + 0x77, 0xc4, 0xc6, 0x55, 0x7d, 0xb4, 0xc9, 0xd3, 0x75, 0x19, 0xd6, 0x5f, 0xe2, 0x01, 0x61, 0x46, + 0xf2, 0x76, 0x99, 0x31, 0xdb, 0x5b, 0x6c, 0x74, 0xd8, 0x5c, 0xa7, 0xe0, 0xcf, 0x98, 0xdc, 0x7a, + 0xf0, 0x42, 0x47, 0xf8, 0xc2, 0xbc, 0xde, 0x6d, 0xed, 0xe5, 0x32, 0xac, 0xba, 0x21, 0x40, 0xcf, + 0x84, 0x4d, 0xab, 0x1a, 0xae, 0x85, 0xe4, 0x3b, 0xfa, 0xd9, 0x36, 0xb6, 0x26, 0xd3, 0x1b, 0xa0, + 0x90, 0x0b, 0x89, 0x0a, 0x71, 0x8c, 0x2d, 0x84, 0x06, 0x2a, 0xcf, 0xf9, 0x2f, 0x18, 0xc9, 0x45, + 0xc2, 0xd8, 0xc5, 0x1c, 0x30, 0x32, 0x18, 0xf1, 0xb0, 0x32, 0x3b, 0x21, 0x4a, 0xb1, 0x30, 0xa6, + 0xef, 0x71, 0x4c, 0x9c, 0x8c, 0x1f, 0x18, 0x2f, 0x48, 0xfc, 0x57, 0x19, 0xdc, 0xcd, 0xf8, 0xef, + 0xc2, 0x92, 0x33, 0x78, 0x48, 0xf6, 0xc9, 0x33, 0x1f, 0xfd, 0xbc, 0xca, 0x5b, 0x1b, 0xcf, 0x2a, + 0x29, 0x1b, 0x4a, 0x76, 0x5c, 0xad, 0xec, 0x4e, 0xa7, 0x6c, 0xa3, 0x5f, 0x8c, 0x20, 0xbb, 0x4a, + 0x26, 0xc2, 0x9a, 0x99, 0x31, 0xb6, 0x18, 0xec, 0xb9, 0x0d, 0x78, 0x4a, 0xc9, 0x68, 0x1c, 0xd7, + 0x4f, 0xc2, 0x27, 0xa6, 0x8d, 0xea, 0x42, 0x5a, 0xac, 0x8a, 0x3c, 0x16, 0x5b, 0x9a, 0xed, 0x2f, + 0xcf, 0x46, 0xbe, 0xf8, 0xbc, 0xac, 0x4c, 0x85, 0x55, 0x94, 0x63, 0x1e, 0x68, 0xac, 0x56, 0x16, + 0x78, 0xe1, 0x20, 0xf9, 0x23, 0xc9, 0xb1, 0x67, 0x77, 0x10, 0x1a, 0x1c, 0x29, 0x9b, 0x88, 0xe1, + 0xd8, 0x10, 0x58, 0x9f, 0xff, 0xc6, 0xd3, 0x43, 0x76, 0x40, 0x6e, 0xf8, 0x6a, 0xd6, 0x29, 0xa3, + 0x71, 0x41, 0x8e, 0xec, 0x44, 0x61, 0x47, 0x12, 0x35, 0x49, 0x1f, 0x97, 0xa3, 0xe1, 0x5c, 0x11, + 0x52, 0x4a, 0xd3, 0x17, 0xd5, 0x95, 0xd5, 0xd3, 0x75, 0x75, 0x73, 0xdc, 0xa9, 0xba, 0x7f, 0xae, + 0x1e, 0x10, 0xe8, 0x74, 0x3e, 0x21, 0xee, 0x48, 0xe4, 0x2b, 0x6a, 0xa3, 0x83, 0x66, 0x6a, 0x43, + 0xff, 0x11, 0x2c, 0x28, 0x6b, 0xe9, 0x09, 0x3a, 0xfc, 0xda, 0xa7, 0xf1, 0x85, 0x77, 0x77, 0x8c, + 0x4b, 0xcf, 0x8f, 0x31, 0x7a, 0xd6, 0xff, 0x04, 0xdb, 0xdc, 0x57, 0x08, 0x16, 0xd3, 0x2b, 0x18, + 0x28, 0xef, 0xc4, 0x0b, 0xcb, 0x36, 0x57, 0x40, 0x14, 0x7c, 0x40, 0x2b, 0x25, 0x4b, 0x98, 0xc2, + 0x0a, 0xe6, 0xdb, 0x67, 0x23, 0x49, 0x2f, 0xc1, 0x35, 0x75, 0x45, 0xa6, 0x77, 0x1d, 0x3e, 0x0b, + 0x2a, 0xba, 0xcd, 0x46, 0x0d, 0x75, 0x25, 0xf1, 0xfb, 0x57, 0x41, 0x59, 0x6d, 0x12, 0xaa, 0xdf, + 0x45, 0xb4, 0x6e, 0x27, 0x7f, 0x05, 0x66, 0x2d, 0x89, 0x7d, 0xbf, 0x9f, 0x2e, 0xdd, 0xa3, 0xe5, + 0x73, 0x7c, 0x5d, 0x55, 0x56, 0x5f, 0x2b, 0x1e, 0x23, 0x9a, 0x88, 0x6b, 0x4f, 0xe1, 0x3d, 0x0c, + 0xac, 0x41, 0xa6, 0xe9, 0xfd, 0x94, 0xec, 0x3d, 0x83, 0xb0, 0xf6, 0x3c, 0x13, 0xca, 0xcc, 0x6d, + 0xb5, 0x55, 0x91, 0x3e, 0x5e, 0xa2, 0xfe, 0x0b, 0x0a, 0x66, 0x3a, 0xd5, 0x1b, 0x1a, 0x26, 0x1b, + 0x26, 0x8a, 0xaf, 0x8c, 0xb2, 0xb2, 0xc1, 0xe3, 0x57, 0xa2, 0xa5, 0x64, 0xad, 0xcd, 0xcc, 0xc7, + 0xc4, 0x85, 0x3c, 0x7e, 0x3b, 0x81, 0xda, 0x11, 0x68, 0xe7, 0x15, 0x12, 0x1e, 0xf4, 0x0b, 0x8e, + 0x76, 0x54, 0xf8, 0x52, 0xa3, 0x04, 0x77, 0xd0, 0xd6, 0x5e, 0xfc, 0xb0, 0xcc, 0x70, 0xd8, 0xca, + 0x1e, 0x3c, 0xc5, 0x55, 0x21, 0x7a, 0x52, 0xd2, 0x55, 0xc4, 0x09, 0x97, 0xe2, 0xe2, 0xe2, 0xe2, + 0xec, 0x02, 0xbe, 0x5b, 0x61, 0xa5, 0xfa, 0x9a, 0x62, 0x4e, 0x20, 0x15, 0xf5, 0x9c, 0xaa, 0xb2, + 0x63, 0xda, 0x21, 0x08, 0xe0, 0x74, 0xa9, 0x8c, 0x44, 0x55, 0xfc, 0x4d, 0xf6, 0x43, 0xe3, 0x95, + 0x70, 0xe5, 0xbf, 0xc1, 0x5d, 0x13, 0x43, 0x4c, 0xa7, 0xbb, 0x45, 0xc1, 0x59, 0x6c, 0xbd, 0x2a, + 0xf0, 0x91, 0xca, 0xfa, 0x47, 0x43, 0x49, 0x84, 0x32, 0x0b, 0x34, 0x28, 0x7c, 0x40, 0x2c, 0x24, + 0x90, 0x5f, 0x96, 0x48, 0x1a, 0xb9, 0xae, 0x87, 0x7c, 0x65, 0x94, 0xf6, 0x5b, 0xc5, 0xd5, 0xd0, + 0x9d, 0xa7, 0xc4, 0xc2, 0x46, 0x9c, 0x45, 0x85, 0xa7, 0x5f, 0x08, 0x09, 0x6a, 0xed, 0xf1, 0xdf, + 0x34, 0xd4, 0x07, 0xf1, 0x19, 0x08, 0x2a, 0xc2, 0x09, 0x17, 0x15, 0xa8, 0x4c, 0x7e, 0x34, 0x74, + 0x7b, 0x31, 0xbb, 0x88, 0x7c, 0xac, 0x3e, 0xf9, 0x7a, 0x52, 0xa7, 0xaa, 0x0d, 0xc8, 0xb7, 0xe2, + 0x7a, 0x3b, 0x1f, 0x56, 0x9b, 0x9e, 0xb3, 0xf4, 0xff, 0x2f, 0x04, 0x5a, 0xd7, 0xfe, 0x24, 0x28, + 0x22, 0x27, 0xe0, 0xea, 0xa2, 0x0f, 0x44, 0xa3, 0x3b, 0x3e, 0xa8, 0xcc, 0x15, 0x93, 0xb3, 0xbb, + 0xbb, 0xdb, 0xe0, 0x84, 0xaf, 0xbf, 0x57, 0x05, 0xa2, 0x49, 0xc6, 0xdd, 0x0b, 0xec, 0xdf, 0xbe, + 0x0a, 0xc6, 0x6a, 0x92, 0xd8, 0x1a, 0x02, 0x30, 0x92, 0xda, 0x29, 0x6e, 0xa4, 0x19, 0x86, 0x3b, + 0x1f, 0x18, 0x35, 0x0e, 0x66, 0x0b, 0x43, 0x26, 0x66, 0x31, 0xa9, 0x88, 0xe8, 0xd9, 0x31, 0x9f, + 0xc9, 0xef, 0xf8, 0x85, 0x7f, 0xae, 0xbe, 0x09, 0xb9, 0xa9, 0x35, 0x19, 0xa5, 0xef, 0x82, 0xca, + 0xb1, 0x29, 0x94, 0x11, 0x40, 0x9f, 0x17, 0x2f, 0xea, 0xcf, 0xbe, 0x0a, 0xae, 0xb9, 0xbd, 0x54, + 0xdd, 0x66, 0xaf, 0xf0, 0x53, 0x35, 0x3e, 0x66, 0x36, 0x77, 0x73, 0xb2, 0xea, 0x37, 0xc1, 0x31, + 0x48, 0x7a, 0x9c, 0xaa, 0x68, 0x1a, 0x95, 0x3e, 0x62, 0x65, 0x63, 0xe0, 0xb2, 0xaa, 0xe3, 0x70, + 0x13, 0x7a, 0x32, 0xf6, 0x33, 0x26, 0x08, 0xdf, 0x46, 0x54, 0xf8, 0x46, 0x86, 0xe8, 0x7d, 0xee, + 0xe7, 0xc5, 0x2f, 0xf1, 0xf5, 0x32, 0x55, 0x51, 0xed, 0xcd, 0x43, 0xe6, 0x63, 0xc1, 0x76, 0xab, + 0x0b, 0x42, 0x3c, 0x1b, 0x57, 0xa2, 0xee, 0x26, 0x32, 0x46, 0x0b, 0xc7, 0xa9, 0x5b, 0x79, 0x9f, + 0x9d, 0xec, 0x60, 0x7e, 0xc3, 0x14, 0xc2, 0x4e, 0xb4, 0xdb, 0xe2, 0x06, 0x63, 0x33, 0xf4, 0x07, + 0xc7, 0x06, 0x8a, 0xaa, 0x5d, 0x1c, 0xd4, 0xe2, 0x4b, 0x63, 0x49, 0xac, 0x41, 0xf1, 0x03, 0x8b, + 0x8c, 0x90, 0xb4, 0xde, 0xf8, 0xdd, 0x58, 0x07, 0xe0, 0xb6, 0x46, 0x3b, 0x73, 0x42, 0xde, 0x27, + 0xe0, 0x9a, 0x5e, 0xe3, 0x7e, 0x2d, 0xb0, 0x8a, 0x92, 0x31, 0xf5, 0xd2, 0xaf, 0x1f, 0x36, 0xc5, + 0x66, 0x25, 0x08, 0x2b, 0xe5, 0x0e, 0xf0, 0xf5, 0x25, 0x3c, 0x7d, 0xeb, 0xbf, 0x18, 0x3c, 0x66, + 0xa9, 0xd1, 0xcd, 0x45, 0xfc, 0x16, 0x88, 0x7e, 0xfb, 0x6d, 0x1d, 0x3e, 0x11, 0xdd, 0xc4, 0xbe, + 0xf7, 0x2f, 0xae, 0xcf, 0xfc, 0x61, 0x0f, 0xe6, 0x6b, 0xaa, 0xac, 0xae, 0xab, 0x89, 0x10, 0x63, + 0xd9, 0xa4, 0x5a, 0x78, 0xed, 0xde, 0xe9, 0x0a, 0xd1, 0x1e, 0x8c, 0xed, 0xfc, 0x51, 0x19, 0x5e, + 0x76, 0x05, 0x6e, 0x82, 0xf0, 0xc5, 0x25, 0x1d, 0xbb, 0x35, 0x6e, 0x75, 0x85, 0xa1, 0x9d, 0x8f, + 0x2f, 0x39, 0x57, 0xdb, 0x6d, 0x34, 0xfc, 0xf5, 0x75, 0x2f, 0x67, 0xf5, 0xd7, 0xbe, 0xed, 0xa7, + 0x4d, 0x75, 0xd7, 0xcb, 0xa4, 0x5f, 0x97, 0x84, 0xec, 0x6c, 0x6c, 0x6c, 0x73, 0xb2, 0x86, 0xf6, + 0x57, 0x5e, 0xf8, 0x50, 0x56, 0x56, 0x37, 0x44, 0xdd, 0xda, 0x3a, 0x82, 0xa4, 0x84, 0xf4, 0x95, + 0xb7, 0xc3, 0xe5, 0x1a, 0xef, 0xb1, 0xff, 0x2d, 0x23, 0x38, 0x68, 0xae, 0xc3, 0xfb, 0xb2, 0x3b, + 0xa1, 0xf5, 0x2b, 0xca, 0xff, 0xb9, 0x2a, 0x48, 0x23, 0xfc, 0x10, 0x95, 0x6b, 0x67, 0xc1, 0x3f, + 0x69, 0x56, 0xa4, 0x23, 0x1b, 0xe3, 0x85, 0x52, 0x68, 0xa6, 0x36, 0x89, 0x59, 0x8d, 0x5f, 0x6c, + 0xa4, 0x0b, 0xc6, 0x0f, 0x4d, 0x89, 0x81, 0x99, 0x97, 0xe1, 0xf0, 0xb6, 0x4a, 0xe4, 0x78, 0x2d, + 0xa9, 0xec, 0xe5, 0x23, 0x41, 0x00, 0x72, 0xff, 0x05, 0xd9, 0x3e, 0xae, 0x58, 0x0a, 0xed, 0x2f, + 0xc2, 0x1e, 0x4c, 0x1c, 0x36, 0xcd, 0x74, 0x45, 0x9d, 0x82, 0xf0, 0x59, 0xaa, 0xad, 0x47, 0xa8, + 0xa9, 0x53, 0xed, 0xa4, 0x5e, 0x08, 0xbb, 0x49, 0xf7, 0xc1, 0x65, 0xc6, 0x55, 0xa6, 0xfc, 0x37, + 0x89, 0x6b, 0x96, 0x3e, 0xe2, 0x60, 0x84, 0x95, 0xcf, 0xef, 0x82, 0x8a, 0xa9, 0x4e, 0xfb, 0x4d, + 0x37, 0xc2, 0x65, 0x35, 0x0d, 0x8c, 0x0e, 0x54, 0x1d, 0xd8, 0x0e, 0x75, 0x0d, 0xa7, 0x85, 0x26, + 0x10, 0x1e, 0xdb, 0x07, 0x1d, 0x65, 0x08, 0x7a, 0x8f, 0x66, 0x95, 0x1e, 0xda, 0xfb, 0xe0, 0xaa, + 0xde, 0x4f, 0x23, 0x34, 0x53, 0xb2, 0xf4, 0x6f, 0xf0, 0x54, 0x5e, 0x56, 0x1e, 0x0e, 0x93, 0x1c, + 0x43, 0x14, 0xeb, 0x7f, 0x8c, 0x9d, 0x0a, 0xec, 0x09, 0xec, 0x6a, 0x0d, 0xb4, 0x8c, 0xdf, 0x60, + 0xb9, 0x92, 0x8c, 0x1c, 0xf8, 0x21, 0xec, 0x65, 0x67, 0x2f, 0x8c, 0x8f, 0xd7, 0x6e, 0x6d, 0x91, + 0x76, 0xb2, 0x74, 0x33, 0x07, 0xb9, 0x47, 0x1d, 0xef, 0xc4, 0x02, 0xd9, 0x57, 0x23, 0x0c, 0x6d, + 0x72, 0x1b, 0xb4, 0x53, 0x83, 0x83, 0x78, 0x90, 0x9d, 0xaa, 0x38, 0xaf, 0xf0, 0xd3, 0xa1, 0xa7, + 0xe3, 0xeb, 0x5e, 0xee, 0xca, 0xec, 0x5e, 0x2c, 0x8d, 0x34, 0x92, 0x4b, 0x5a, 0xe1, 0x4b, 0x4c, + 0x9d, 0xc9, 0x2f, 0xbb, 0xd4, 0x34, 0xd7, 0x97, 0x92, 0x6f, 0xf1, 0x37, 0x15, 0x8a, 0xc5, 0x77, + 0x7a, 0xe8, 0x43, 0xfc, 0x22, 0x58, 0xdc, 0xe6, 0x12, 0x63, 0xc8, 0x66, 0x7c, 0x54, 0x71, 0xc5, + 0xaf, 0xc2, 0x87, 0x98, 0xdf, 0x4b, 0xe2, 0x78, 0x5f, 0xa9, 0xff, 0x9b, 0xef, 0xf0, 0x5a, 0x46, + 0x93, 0x36, 0x6c, 0x48, 0x1c, 0xf6, 0xf5, 0xc3, 0xe6, 0x92, 0x41, 0x12, 0xec, 0x5f, 0xf5, 0x22, + 0x43, 0x08, 0x09, 0xf1, 0x01, 0x53, 0x2b, 0xa6, 0xcc, 0xca, 0xfd, 0x74, 0x5c, 0xaf, 0x82, 0x7a, + 0x54, 0x92, 0xb6, 0xde, 0xbe, 0x09, 0x36, 0xd0, 0x9b, 0x8a, 0x5e, 0x89, 0xaa, 0xe2, 0x8f, 0x52, + 0xe4, 0x44, 0xfa, 0xb9, 0xba, 0xe2, 0x7c, 0x60, 0xa8, 0x69, 0x55, 0xb9, 0xac, 0x19, 0x78, 0x2d, + 0xa0, 0x01, 0x08, 0x61, 0x72, 0x23, 0x68, 0xa7, 0xe3, 0xca, 0xa5, 0xe9, 0xe8, 0x35, 0x55, 0xc4, + 0xec, 0xd7, 0xea, 0xff, 0x21, 0xc5, 0x6e, 0x2b, 0x7f, 0x14, 0x21, 0x02, 0x5e, 0x43, 0x39, 0x96, + 0x18, 0xab, 0xe7, 0xf8, 0x9a, 0xf2, 0x24, 0x6d, 0x39, 0xc3, 0xaa, 0x7e, 0x13, 0x3d, 0xdd, 0xed, + 0x2f, 0xc1, 0x51, 0x55, 0x50, 0xc8, 0xc1, 0x50, 0x2b, 0x36, 0x39, 0x04, 0x9e, 0x34, 0x91, 0x77, + 0xf8, 0x50, 0xac, 0xfc, 0x5e, 0x91, 0x0c, 0x5a, 0x01, 0x32, 0x82, 0xf3, 0x28, 0x73, 0x13, 0x97, + 0xd3, 0xfc, 0x20, 0x4a, 0x7e, 0xba, 0xba, 0x1b, 0x1a, 0x1b, 0x1f, 0x8b, 0x28, 0x97, 0x1b, 0x76, + 0x69, 0xa0, 0xd0, 0x69, 0xf8, 0x47, 0xa6, 0x9d, 0x33, 0x47, 0x57, 0x75, 0xf1, 0x94, 0x9a, 0xb5, + 0x3e, 0xa7, 0x1a, 0x1a, 0xe4, 0xeb, 0xd0, 0x88, 0xcf, 0xc4, 0x04, 0x4c, 0x9b, 0x69, 0xe0, 0xc8, + 0xca, 0x1c, 0x7c, 0xcc, 0x9d, 0x4f, 0x8e, 0x39, 0x32, 0x5c, 0xb2, 0x90, 0xf0, 0x7a, 0x65, 0x06, + 0x75, 0x29, 0x68, 0xfc, 0x22, 0x48, 0xa8, 0xc7, 0x07, 0x3c, 0x4b, 0xd8, 0xc2, 0xad, 0x1f, 0xc7, + 0x1d, 0xe4, 0x64, 0xf5, 0x03, 0x19, 0xf0, 0x47, 0x43, 0x2b, 0x2a, 0x13, 0x0d, 0x63, 0xe7, 0xc2, + 0x9d, 0xb2, 0xe1, 0x7b, 0x58, 0x6d, 0x29, 0xdb, 0x5d, 0xcd, 0x86, 0xc3, 0xa5, 0x71, 0x36, 0x21, + 0xd4, 0xc7, 0x99, 0x89, 0x98, 0xf2, 0x1c, 0x47, 0x4e, 0xb8, 0xb6, 0xf5, 0xf1, 0x30, 0x81, 0xb4, + 0xe6, 0x65, 0x75, 0x57, 0xba, 0x1f, 0x10, 0x24, 0xb9, 0x7f, 0x3a, 0x8f, 0x10, 0xfa, 0x6d, 0xf8, + 0x44, 0xc4, 0x48, 0x48, 0x18, 0xc7, 0xdd, 0xf6, 0xd3, 0xf0, 0x58, 0x62, 0xd0, 0xb8, 0xe5, 0x8d, + 0xdc, 0xdb, 0xc7, 0xa5, 0x86, 0x58, 0xd7, 0xf7, 0xc5, 0xf7, 0x7b, 0x8a, 0xcb, 0x96, 0xf1, 0x26, + 0xe9, 0x97, 0xf8, 0xc2, 0xb6, 0x5e, 0x8a, 0x96, 0x58, 0x51, 0x24, 0xfc, 0xb9, 0x9f, 0xbf, 0x8c, + 0x2d, 0x22, 0xc2, 0x33, 0x8e, 0x57, 0xb4, 0xa3, 0x6e, 0x17, 0x10, 0x6a, 0x7c, 0x3c, 0x25, 0x60, + 0x76, 0x93, 0x63, 0x3f, 0x8d, 0xcc, 0xf8, 0x42, 0x6c, 0x4e, 0x24, 0x68, 0x1a, 0xda, 0x2c, 0xd6, + 0xa0, 0xc2, 0x3e, 0x20, 0x13, 0x99, 0xb7, 0xe5, 0xea, 0xa3, 0x2b, 0x2f, 0x82, 0x69, 0x33, 0xe6, + 0xd5, 0x66, 0xd8, 0x1e, 0x15, 0xc2, 0xe2, 0xdb, 0x22, 0x99, 0xd4, 0x5d, 0xdc, 0x75, 0x5d, 0xdd, + 0xff, 0xd1, 0xa5, 0x7c, 0x11, 0xc8, 0xca, 0xf5, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x13, + 0x09, 0xb0, 0x3a, 0x8b, 0xd0, 0x94, 0x8b, 0xd5, 0xd0, 0xaf, 0x42, 0x5e, 0x23, 0x96, 0x28, 0x31, + 0x41, 0x8a, 0x0c, 0x50, 0x61, 0x7e, 0x09, 0x06, 0x4f, 0x4f, 0x29, 0xfa, 0x16, 0x64, 0x8b, 0xea, + 0x95, 0x3e, 0x28, 0x62, 0x62, 0x07, 0xc4, 0x03, 0xc5, 0x65, 0xb1, 0x58, 0xaf, 0xc6, 0x88, 0x02, + 0xa8, 0xf7, 0xc0, 0x77, 0x89, 0x47, 0xc0, 0xb0, 0x84, 0x2a, 0x1c, 0xa8, 0x06, 0x71, 0x0a, 0x54, + 0xbe, 0x2a, 0x03, 0xf0, 0x76, 0x07, 0xf9, 0x62, 0xcf, 0x0f, 0x2c, 0xb3, 0x81, 0xe5, 0x29, 0x01, + 0x28, 0xa6, 0x38, 0x8a, 0x88, 0xd1, 0x8d, 0x62, 0xb5, 0xfc, 0xa3, 0xc0, 0x95, 0xa9, 0x12, 0x66, + 0xae, 0x8b, 0x54, 0xda, 0x59, 0xee, 0x87, 0x7b, 0xba, 0x1e, 0x7e, 0xa9, 0xda, 0xea, 0xe0, 0xfd, + 0x1c, 0x94, 0xfc, 0x3c, 0x62, 0x10, 0x57, 0x23, 0x0d, 0x08, 0x02, 0x86, 0xb9, 0x02, 0x07, 0x41, + 0xa4, 0x62, 0xa3, 0x02, 0x84, 0xb9, 0x78, 0x58, 0x50, 0x31, 0x86, 0xef, 0x4c, 0xa3, 0xd7, 0x25, + 0xfc, 0x20, 0x14, 0x08, 0x49, 0x7b, 0x74, 0xb3, 0x70, 0x00, 0x0b, 0xbc, 0x6a, 0xd4, 0xab, 0xd2, + 0x52, 0xaa, 0xa0, 0xc9, 0xed, 0xde, 0x0d, 0xfc, 0x40, 0x9b, 0x82, 0x48, 0xc9, 0x7c, 0xcf, 0x04, + 0x5e, 0x23, 0xd9, 0xa1, 0x5e, 0x82, 0xe5, 0x4a, 0xea, 0x08, 0x6f, 0xa8, 0x8a, 0x4f, 0xa8, 0x4f, + 0x6f, 0xaa, 0x01, 0x3e, 0x89, 0x95, 0x70, 0x43, 0x49, 0xb7, 0x69, 0x1d, 0xfa, 0xf1, 0xd9, 0x39, + 0x74, 0xe9, 0xf8, 0x24, 0xe4, 0x5e, 0x54, 0xae, 0x23, 0x49, 0x00, 0xd3, 0x54, 0x7f, 0x82, 0x11, + 0x4f, 0x63, 0x29, 0x05, 0x88, 0xae, 0x08, 0x02, 0x7c, 0x77, 0xdc, 0x77, 0xd5, 0xb4, 0x36, 0xa4, + 0x61, 0x4c, 0x08, 0xba, 0x2b, 0x8a, 0xff, 0xe1, 0xf3, 0x65, 0xfd, 0xbd, 0xcf, 0x83, 0xdd, 0x34, + 0x2e, 0x32, 0xbd, 0xb6, 0xcf, 0x9f, 0xa2, 0x99, 0x80, 0x4f, 0x83, 0x0c, 0xb8, 0x81, 0xe5, 0xce, + 0x91, 0x79, 0x34, 0x9b, 0xf8, 0x27, 0x24, 0xdf, 0x97, 0x6c, 0x44, 0x23, 0x45, 0x78, 0x50, 0x28, + 0xb4, 0xb1, 0xc3, 0xb5, 0xac, 0x31, 0x1f, 0x40, 0x64, 0xa5, 0x31, 0xa0, 0x90, 0xb3, 0x17, 0x19, + 0xe7, 0x01, 0xa8, 0xb9, 0xb3, 0x01, 0xe9, 0xf4, 0x2c, 0x10, 0x2e, 0x47, 0x78, 0xe2, 0x06, 0xd0, + 0xa7, 0x83, 0x54, 0x1c, 0x2b, 0x78, 0xf1, 0x10, 0x15, 0xc2, 0x73, 0x56, 0x3f, 0xa0, 0x3e, 0xd3, + 0x0a, 0xe0, 0xf2, 0x0a, 0x1e, 0xf0, 0xd9, 0xb7, 0xd3, 0x63, 0x48, 0x24, 0x85, 0x59, 0x09, 0x61, + 0x75, 0xf0, 0x44, 0x15, 0x96, 0xb5, 0x3a, 0x04, 0x3f, 0x11, 0x26, 0x25, 0xd2, 0x4b, 0xf5, 0x2a, + 0x3a, 0x7d, 0x5f, 0xe1, 0x41, 0x17, 0xae, 0xa7, 0x0c, 0xb7, 0x2e, 0x1a, 0x01, 0xe4, 0x52, 0xad, + 0x78, 0x35, 0xb0, 0xf6, 0x1f, 0x1a, 0x2a, 0xcd, 0x82, 0x2c, 0xa8, 0x18, 0xdc, 0x71, 0xd2, 0x08, + 0x4e, 0xba, 0xfe, 0xe7, 0x53, 0xce, 0x20, 0x9f, 0x20, 0x93, 0xcf, 0x07, 0x71, 0xc4, 0x11, 0x95, + 0x99, 0xb5, 0x74, 0xe7, 0xdf, 0x8d, 0x9c, 0x83, 0x27, 0xc8, 0x5e, 0x41, 0x08, 0xe1, 0xc5, 0x70, + 0xc4, 0x5a, 0x55, 0xb3, 0x19, 0x8d, 0xb6, 0x8d, 0x28, 0xa4, 0x28, 0x4d, 0x3f, 0xc5, 0x58, 0x97, + 0x52, 0xfc, 0x6e, 0x93, 0x09, 0xcc, 0x50, 0x40, 0x85, 0xaa, 0xe2, 0x05, 0xe2, 0xa1, 0x8d, 0x4d, + 0x60, 0xc7, 0x5f, 0x0e, 0x20, 0xb8, 0x83, 0x80, 0x89, 0xd2, 0x18, 0x05, 0x41, 0x65, 0xfb, 0x43, + 0xbe, 0xb6, 0x30, 0xbd, 0x3f, 0xd4, 0xf0, 0xcf, 0xa3, 0xde, 0x08, 0x48, 0x3b, 0x9e, 0xcc, 0x57, + 0xf8, 0x58, 0x2b, 0x83, 0x5d, 0x30, 0xbe, 0xc2, 0xa4, 0xc6, 0xb4, 0xde, 0x82, 0x38, 0xc1, 0x4d, + 0x93, 0x9e, 0x56, 0x7d, 0x79, 0xef, 0xc3, 0x91, 0xff, 0x2f, 0xf7, 0x91, 0x24, 0xd2, 0x6f, 0xff, + 0x19, 0x19, 0x68, 0x52, 0xd1, 0xea, 0x5a, 0x14, 0xb4, 0x7a, 0x96, 0x85, 0x2d, 0x1e, 0xa5, 0xa1, + 0x4b, 0x47, 0xbe, 0xa7, 0x48, 0x8e, 0xc9, 0xa4, 0x97, 0x88, 0xb4, 0xd6, 0xd6, 0xdf, 0x97, 0x29, + 0x04, 0xa4, 0x1f, 0xc1, 0x25, 0xab, 0x56, 0x46, 0xe2, 0x02, 0x7d, 0x24, 0xb4, 0x92, 0x3f, 0x14, + 0x42, 0x79, 0x3d, 0x35, 0xfc, 0x10, 0x7e, 0x6e, 0xc7, 0x33, 0xb2, 0xe0, 0x75, 0x70, 0xfc, 0xff, + 0xbc, 0x95, 0xf0, 0x5f, 0x77, 0x2e, 0x6e, 0xf8, 0xf3, 0x0f, 0x2d, 0x78, 0xd3, 0xf0, 0x4a, 0x5d, + 0x24, 0xb4, 0x92, 0x73, 0xe7, 0xd5, 0x34, 0xdb, 0x6f, 0xfd, 0x45, 0x2d, 0xf1, 0xa1, 0x64, 0xd0, + 0xae, 0x47, 0x3d, 0x18, 0xc2, 0x20, 0x4b, 0xbf, 0x2f, 0x8d, 0xfb, 0xd8, 0x9e, 0x2b, 0xc8, 0x39, + 0xf1, 0x44, 0xfd, 0x5f, 0xf8, 0x90, 0xa6, 0x89, 0xc3, 0xe8, 0x97, 0x82, 0x21, 0x4b, 0x82, 0x20, + 0xbe, 0xe3, 0xf2, 0x93, 0xc6, 0x57, 0x80, 0x0d, 0x01, 0xd0, 0x3c, 0xa1, 0x01, 0x5a, 0x90, 0x40, + 0x68, 0x1e, 0x1f, 0x04, 0x21, 0x5c, 0x98, 0x90, 0xb7, 0x15, 0xc8, 0x4c, 0xd6, 0x3b, 0xe5, 0xc1, + 0x01, 0x9f, 0x57, 0xb4, 0x83, 0x39, 0x1c, 0xd3, 0xd2, 0x35, 0x6b, 0x0e, 0xe9, 0x04, 0xa6, 0xd3, + 0x7f, 0x82, 0xc1, 0x1b, 0x96, 0x8e, 0xc1, 0xaa, 0x88, 0xd7, 0x51, 0xcb, 0x18, 0x87, 0x85, 0x08, + 0xce, 0x2d, 0x66, 0x92, 0x9b, 0x15, 0xa6, 0x63, 0x39, 0x08, 0x32, 0xea, 0x67, 0xb8, 0x98, 0x82, + 0x93, 0xb2, 0x12, 0x23, 0x21, 0x3a, 0x64, 0x4a, 0xca, 0xbe, 0xce, 0x30, 0xf8, 0xa2, 0x3d, 0xc2, + 0x8b, 0x24, 0x33, 0x55, 0xd0, 0x7f, 0xbe, 0x78, 0xfb, 0xdd, 0x4d, 0x07, 0xac, 0x57, 0xa6, 0xff, + 0x77, 0xf0, 0x42, 0x17, 0x6e, 0xdc, 0x77, 0xfd, 0x48, 0xa3, 0xe3, 0x3b, 0x4d, 0x6d, 0x35, 0xb4, + 0xd6, 0xd3, 0x5e, 0x26, 0xd3, 0x5b, 0x4d, 0x66, 0xec, 0x87, 0xc3, 0xe1, 0xb1, 0xd9, 0xeb, 0xcc, + 0x8d, 0xc1, 0x2c, 0xd8, 0x6c, 0xdd, 0x86, 0xcf, 0xa2, 0x3a, 0x33, 0x91, 0xf1, 0x22, 0x6b, 0xa3, + 0xa4, 0x5e, 0x17, 0x1d, 0x0d, 0x18, 0xe1, 0xe4, 0x66, 0x88, 0xf4, 0x9e, 0x62, 0xa2, 0xd3, 0x4b, + 0xfd, 0x48, 0xfe, 0x20, 0x13, 0x08, 0xb9, 0xfe, 0xda, 0xef, 0xe2, 0x01, 0x30, 0xdb, 0x9e, 0x5b, + 0x73, 0xca, 0xff, 0x42, 0x48, 0x95, 0xc1, 0x51, 0xa9, 0x1b, 0x3e, 0x6d, 0x2a, 0x08, 0x0e, 0x16, + 0x13, 0x1d, 0xf0, 0x56, 0x10, 0xbb, 0x9f, 0x4a, 0xcc, 0xd6, 0xa6, 0xcc, 0xb0, 0x72, 0xf8, 0x8c, + 0xaa, 0xa8, 0xc2, 0xff, 0xd8, 0xf1, 0x1c, 0xff, 0x08, 0x8e, 0xe5, 0xfc, 0x1f, 0xe0, 0x97, 0x0d, + 0x16, 0xd5, 0x12, 0x37, 0x3f, 0xdc, 0x38, 0x8d, 0x18, 0x8c, 0x6b, 0x9c, 0x9f, 0xe0, 0x88, 0x2f, + 0x7a, 0xcb, 0xea, 0xff, 0x5f, 0xc4, 0x74, 0x4a, 0xfa, 0xc5, 0x37, 0x5a, 0x8a, 0xea, 0xc3, 0xd5, + 0xa2, 0x7a, 0xca, 0xfa, 0xc5, 0xf5, 0x8b, 0xeb, 0x17, 0xc1, 0x38, 0x83, 0xa9, 0x29, 0xc4, 0x78, + 0xff, 0xcf, 0x8e, 0xd2, 0x13, 0x2f, 0xc4, 0x0c, 0x15, 0xd4, 0xca, 0x54, 0x99, 0xe6, 0xa7, 0x31, + 0xd2, 0x43, 0x7f, 0x12, 0x57, 0x90, 0xdd, 0xb7, 0x86, 0x81, 0x82, 0x1b, 0xe2, 0xbb, 0xac, 0xde, + 0xbe, 0xc8, 0xaa, 0xab, 0xe8, 0x7f, 0x57, 0x12, 0x39, 0xdb, 0xf7, 0x8f, 0xe3, 0xf4, 0x17, 0x72, + 0xba, 0xff, 0xe8, 0xa9, 0xd0, 0x47, 0x9c, 0xca, 0xdb, 0x69, 0xa7, 0xe6, 0xe8, 0xbd, 0x37, 0x43, + 0x3a, 0x23, 0xa1, 0x29, 0x97, 0x82, 0x2e, 0xef, 0xdf, 0x5e, 0xf1, 0x0b, 0x9f, 0xc4, 0x9c, 0xdb, + 0xfd, 0x6a, 0x8b, 0x88, 0x08, 0x8e, 0x9b, 0x6c, 0x37, 0x37, 0x63, 0x95, 0x30, 0x20, 0x09, 0x19, + 0xfc, 0x49, 0x50, 0x88, 0x42, 0x65, 0xbb, 0x58, 0x8c, 0x88, 0x88, 0xdf, 0x09, 0x12, 0xab, 0xb6, + 0xc6, 0xbc, 0x4f, 0xcc, 0x5b, 0x93, 0x49, 0x47, 0x1e, 0x38, 0xdb, 0x85, 0x93, 0x21, 0xda, 0x3f, + 0xa7, 0x64, 0xc2, 0x82, 0x88, 0xbd, 0x0d, 0xf9, 0xe2, 0x04, 0xa0, 0xbf, 0x42, 0xdd, 0x5e, 0x6e, + 0x88, 0xc0, 0x98, 0x84, 0x73, 0x52, 0x74, 0x47, 0x22, 0x78, 0x5c, 0x8d, 0x9b, 0xd5, 0x0c, 0xcc, + 0x37, 0x46, 0xa7, 0x66, 0xc6, 0xff, 0xc4, 0x8c, 0x1d, 0x58, 0xa7, 0x53, 0xbc, 0xbc, 0xbe, 0x36, + 0xc4, 0x71, 0x64, 0xbc, 0x8a, 0x45, 0xd4, 0x77, 0x10, 0x26, 0xa5, 0x04, 0x0a, 0xd8, 0x2d, 0xee, + 0xb1, 0x20, 0x9c, 0xea, 0x62, 0x2b, 0xdc, 0x56, 0x21, 0xa1, 0x6f, 0x10, 0xcd, 0x35, 0xf9, 0xb7, + 0x77, 0xf1, 0xdb, 0x8e, 0xe0, 0xe6, 0x17, 0xc1, 0xce, 0x52, 0x6f, 0x66, 0x4e, 0x82, 0xe4, 0x5c, + 0x33, 0xd5, 0xaf, 0xaa, 0x56, 0x4e, 0x4a, 0xba, 0xa9, 0xba, 0x99, 0x24, 0xe0, 0xa0, 0x50, 0xca, + 0x62, 0x75, 0x91, 0x42, 0xef, 0xf1, 0xe4, 0xad, 0x66, 0x31, 0x24, 0x0b, 0xcd, 0xcb, 0xd5, 0x7c, + 0x29, 0x26, 0xb1, 0x78, 0x4a, 0x63, 0x25, 0x2e, 0x06, 0x41, 0xca, 0xd9, 0x01, 0xec, 0x45, 0x0c, + 0x35, 0x4f, 0x54, 0x56, 0x84, 0x12, 0x09, 0xd3, 0x08, 0xcf, 0x53, 0x1f, 0x0a, 0x19, 0x4a, 0x02, + 0x82, 0x3c, 0x3d, 0x82, 0x08, 0xef, 0xd7, 0x59, 0x0f, 0x0e, 0xfe, 0xb5, 0xd4, 0x88, 0x3b, 0x57, + 0x19, 0xb6, 0x89, 0x45, 0xcb, 0xd6, 0xe5, 0xdb, 0xca, 0xc5, 0xfc, 0x20, 0x54, 0x6a, 0x2f, 0x4d, + 0xc9, 0xcb, 0x6e, 0xe7, 0x81, 0xc3, 0x4f, 0x1c, 0x66, 0x92, 0x3b, 0x0a, 0x6e, 0x0c, 0xe9, 0xd2, + 0x92, 0x37, 0x1f, 0x07, 0xff, 0xd0, 0x67, 0xbe, 0xb1, 0x2a, 0xf5, 0x89, 0x51, 0x7a, 0x15, 0x5f, + 0x5d, 0x57, 0x47, 0x74, 0x25, 0xd5, 0xc8, 0x9e, 0xac, 0xfa, 0x29, 0xd2, 0xfa, 0x9d, 0x24, 0xe0, + 0x9c, 0xda, 0x43, 0x46, 0xc2, 0x32, 0xaa, 0x89, 0x93, 0xd6, 0xb8, 0x98, 0xf1, 0x46, 0x85, 0xb7, + 0xf3, 0x88, 0x09, 0x83, 0xf0, 0x18, 0xdf, 0x6f, 0x60, 0xa9, 0x17, 0x19, 0x18, 0x5e, 0xe8, 0xcb, + 0xcb, 0x75, 0xdd, 0x75, 0xda, 0x9a, 0x1e, 0x27, 0xab, 0x64, 0x63, 0xfe, 0x09, 0xcf, 0x59, 0xbd, + 0x0e, 0x45, 0x13, 0x7c, 0x10, 0x91, 0x56, 0x56, 0xbe, 0x30, 0x55, 0xee, 0x2d, 0x78, 0x3f, 0x09, + 0x1b, 0x9c, 0xb9, 0x10, 0xf3, 0x96, 0x24, 0x83, 0x4d, 0x74, 0x17, 0x22, 0x7d, 0x7b, 0xea, 0x74, + 0x93, 0xa9, 0xd2, 0x23, 0xaf, 0x7d, 0x5e, 0x16, 0xeb, 0x14, 0xbd, 0x48, 0x97, 0x13, 0x04, 0xe3, + 0x24, 0xa3, 0x44, 0x22, 0xc1, 0xb1, 0x85, 0xc4, 0x60, 0xb1, 0x96, 0x3e, 0xe2, 0x25, 0x34, 0xaa, + 0x8b, 0xae, 0x0a, 0xab, 0x5b, 0x74, 0x18, 0xbd, 0x6c, 0x97, 0xbe, 0x09, 0xce, 0xf7, 0x10, 0xd1, + 0x03, 0x7d, 0x27, 0xe6, 0x4f, 0xac, 0x5f, 0x18, 0x5a, 0xaa, 0xc5, 0xea, 0xaa, 0x15, 0x15, 0xf6, + 0xcb, 0x9e, 0x3c, 0x54, 0xbf, 0x3d, 0x48, 0xd9, 0x7e, 0x16, 0x55, 0x6d, 0xed, 0xec, 0xf9, 0x4a, + 0xff, 0x2c, 0x7f, 0x41, 0x13, 0xa5, 0x74, 0x4a, 0x88, 0xe8, 0xfa, 0x93, 0xa2, 0x54, 0x6f, 0x56, + 0xf9, 0xba, 0xb8, 0x9e, 0x88, 0xe5, 0x75, 0xca, 0xfa, 0xbf, 0xd1, 0x49, 0x7d, 0x72, 0xf8, 0xa1, + 0x99, 0x18, 0x5d, 0xb3, 0x43, 0xc6, 0x08, 0x53, 0x30, 0x2e, 0x57, 0x50, 0x2a, 0xe3, 0x7f, 0x64, + 0xa5, 0xdb, 0xba, 0xab, 0x2d, 0x0c, 0x7b, 0xf8, 0x52, 0x5b, 0x48, 0xd7, 0x3f, 0x9f, 0x85, 0x9c, + 0x56, 0x56, 0x78, 0x5e, 0x99, 0x71, 0x04, 0x69, 0x41, 0x1d, 0xa2, 0xbb, 0x61, 0xa5, 0xfe, 0xc2, + 0x28, 0x8b, 0xee, 0x33, 0xa6, 0x59, 0xe6, 0x3c, 0x95, 0xf8, 0xca, 0xac, 0xea, 0xb9, 0xad, 0x6b, + 0xf0, 0x8e, 0xef, 0x5d, 0x32, 0x9e, 0x70, 0x5e, 0xa6, 0xdd, 0x4a, 0x3a, 0x5d, 0xf1, 0xa5, 0x49, + 0xde, 0x91, 0x32, 0x90, 0x4a, 0xc1, 0xfc, 0x45, 0xcd, 0x14, 0x15, 0x57, 0xf4, 0x76, 0x35, 0x4c, + 0x20, 0xcb, 0xff, 0x48, 0xbf, 0xc2, 0x05, 0x8d, 0xd4, 0x3c, 0x9a, 0x31, 0x89, 0x99, 0xde, 0x7f, + 0xf1, 0x92, 0x65, 0xac, 0x1d, 0xf9, 0xaa, 0x5a, 0xeb, 0x58, 0xdb, 0xfc, 0x20, 0x21, 0xbc, 0x6d, + 0x72, 0xdc, 0xbe, 0xed, 0xcf, 0xe3, 0x3a, 0x0a, 0xb9, 0x3f, 0x5a, 0xae, 0xb1, 0xbe, 0xac, 0x46, + 0xf0, 0x47, 0x7b, 0xd8, 0xfa, 0xb1, 0xf5, 0x91, 0xe4, 0xdd, 0x6a, 0xf8, 0x22, 0x14, 0xb2, 0xab, + 0xdf, 0x0a, 0x08, 0x3f, 0xce, 0xeb, 0xa1, 0x08, 0x84, 0xb6, 0x92, 0x02, 0xe3, 0x98, 0x9a, 0x7f, + 0x13, 0x7b, 0x52, 0xf6, 0x15, 0x02, 0x22, 0xdf, 0x96, 0xef, 0x8a, 0xe8, 0x7d, 0xb2, 0xec, 0x86, + 0x44, 0x69, 0xaf, 0x99, 0x67, 0xf8, 0x52, 0x6c, 0xf4, 0xb9, 0x19, 0x4d, 0xa4, 0xed, 0xf2, 0x94, + 0x8a, 0x62, 0x01, 0xdb, 0x5b, 0xfd, 0xbc, 0x0a, 0x6a, 0xb2, 0x1c, 0x68, 0x3d, 0xe4, 0xb3, 0xc4, + 0x2e, 0x88, 0xef, 0x3e, 0x3d, 0x5b, 0xe0, 0xae, 0xaa, 0xa2, 0xf5, 0x59, 0xb2, 0x34, 0xd1, 0x3d, + 0xf1, 0x95, 0x00, 0x72, 0xfa, 0xc3, 0xcb, 0x28, 0xf6, 0xf9, 0x05, 0x73, 0xcf, 0x3d, 0xf8, 0x23, + 0x54, 0xab, 0x45, 0xa1, 0x29, 0x6e, 0x51, 0x5f, 0xf5, 0xc9, 0xf9, 0xa8, 0xca, 0xbe, 0x34, 0x53, + 0xa1, 0x1f, 0x6b, 0xe2, 0x64, 0xff, 0x46, 0x9e, 0xa5, 0x9b, 0xfd, 0x8f, 0xfe, 0x98, 0x3d, 0x86, + 0xaa, 0x97, 0xfb, 0x89, 0xef, 0xfa, 0xc2, 0x65, 0x97, 0xde, 0x38, 0x48, 0x44, 0x96, 0xc2, 0x25, + 0x61, 0xd6, 0x18, 0xcd, 0xee, 0x17, 0x90, 0x6d, 0x4e, 0x4f, 0xd5, 0xc7, 0x88, 0x72, 0xf7, 0xc9, + 0x07, 0x9b, 0x15, 0xf5, 0x23, 0x15, 0x99, 0x6d, 0xdf, 0xc2, 0x1d, 0x2a, 0xa6, 0x4a, 0x2b, 0x87, + 0x6d, 0x55, 0xae, 0x4a, 0xae, 0xfa, 0x0b, 0xa7, 0x6b, 0xa9, 0x12, 0xfa, 0xb8, 0x09, 0x75, 0x7f, + 0xaa, 0x74, 0xba, 0x23, 0xfd, 0x52, 0xa7, 0xd5, 0xa2, 0xf8, 0x24, 0x21, 0xa5, 0xff, 0xf5, 0xc3, + 0xe1, 0x42, 0x2b, 0x42, 0xe4, 0xe5, 0xae, 0x64, 0x23, 0xd4, 0xf1, 0x79, 0xb3, 0x6c, 0xe1, 0x80, + 0x21, 0x1b, 0x1d, 0x74, 0x1a, 0x3c, 0xf3, 0xc8, 0xe9, 0xf0, 0xa1, 0x0d, 0x2f, 0xcc, 0xf6, 0xd1, + 0x77, 0x61, 0xca, 0x89, 0xb0, 0xa7, 0x96, 0x36, 0xf3, 0xf1, 0x1c, 0x3b, 0x87, 0x45, 0x27, 0x2f, + 0x82, 0x6c, 0xe6, 0x5e, 0x2f, 0xc1, 0xf4, 0x56, 0x7c, 0x10, 0xe6, 0x4f, 0xf7, 0xf8, 0x26, 0x2a, + 0xfc, 0xab, 0x8f, 0xb2, 0x36, 0x37, 0x88, 0x09, 0x65, 0xa7, 0x55, 0x5c, 0x4c, 0x71, 0x58, 0xd6, + 0xb6, 0x35, 0x52, 0xe3, 0x71, 0xce, 0x48, 0x3e, 0x30, 0x20, 0xff, 0xfb, 0x78, 0x69, 0x80, 0xaf, + 0x3e, 0x12, 0x15, 0x5f, 0xcb, 0x1f, 0xa5, 0x92, 0xb5, 0x16, 0xc5, 0x74, 0x19, 0x4b, 0x08, 0x74, + 0x21, 0x91, 0xfd, 0x04, 0xdc, 0xf8, 0x24, 0x08, 0x21, 0x43, 0x57, 0x09, 0x72, 0xa5, 0x5e, 0x85, + 0x77, 0xd5, 0xcf, 0x85, 0x09, 0x07, 0x68, 0xc1, 0x69, 0xb5, 0x96, 0x01, 0x3d, 0xd8, 0x64, 0x6d, + 0xb6, 0xdf, 0x64, 0x38, 0x81, 0x9d, 0x5f, 0x1e, 0x61, 0xfb, 0x67, 0x59, 0x7c, 0xaa, 0x2c, 0xf8, + 0xc2, 0x14, 0xf5, 0xbd, 0xaf, 0x43, 0xe9, 0x9c, 0x42, 0xfe, 0xe4, 0x48, 0x4e, 0xd1, 0x2f, 0x25, + 0xd0, 0xd1, 0x95, 0xf0, 0xbd, 0x84, 0x93, 0x2c, 0xad, 0x04, 0x8b, 0x8e, 0x98, 0xcf, 0xe2, 0x4a, + 0xd3, 0x85, 0x8a, 0xd5, 0xcd, 0x4f, 0x8a, 0x3d, 0xdd, 0xdd, 0xdd, 0xfc, 0x24, 0x5c, 0xf0, 0x77, + 0x62, 0x2d, 0x2f, 0xd9, 0xdc, 0xee, 0x18, 0x83, 0x16, 0x24, 0x45, 0x62, 0x08, 0x30, 0x4f, 0xb2, + 0x6c, 0x9f, 0xc2, 0x42, 0x39, 0xe8, 0xb6, 0xc9, 0xfc, 0xa5, 0x2e, 0x38, 0xac, 0x2c, 0xf8, 0x29, + 0xd0, 0xda, 0xfa, 0xe5, 0xf0, 0x47, 0xbd, 0x60, 0xae, 0x53, 0xdb, 0xb7, 0xea, 0x3a, 0x55, 0xd1, + 0x9e, 0xba, 0xbc, 0xbd, 0x5f, 0xeb, 0x95, 0x75, 0xce, 0x7d, 0x13, 0x19, 0x5c, 0x12, 0x65, 0x64, + 0x1d, 0xee, 0x9b, 0x0f, 0x05, 0x9a, 0xd9, 0xc2, 0x2a, 0xb8, 0xd2, 0x82, 0xe0, 0x99, 0xab, 0x9e, + 0x09, 0x24, 0xfe, 0x3e, 0xfe, 0xa2, 0xf9, 0x11, 0xe4, 0x8b, 0x3e, 0x14, 0x9e, 0xa2, 0x78, 0x5e, + 0x59, 0x93, 0xe1, 0x98, 0x91, 0x18, 0xe6, 0xb2, 0x6a, 0x69, 0xde, 0x26, 0x14, 0xbe, 0xcb, 0x47, + 0x37, 0xc2, 0xdc, 0x9c, 0xb6, 0xc6, 0x52, 0x08, 0x55, 0x84, 0x3b, 0x96, 0x3a, 0x6f, 0xf0, 0xa1, + 0x9f, 0x1c, 0xd0, 0x8a, 0x8e, 0xe2, 0x7d, 0xd4, 0x98, 0x85, 0x56, 0xa1, 0xff, 0x5c, 0xcd, 0xa0, + 0xa9, 0x64, 0xdf, 0x1b, 0x25, 0xd0, 0x12, 0x0e, 0x53, 0x1e, 0xd2, 0x85, 0x10, 0xca, 0xc3, 0x95, + 0x11, 0x97, 0x87, 0xa6, 0x1f, 0x4c, 0x92, 0x70, 0x64, 0x17, 0xd5, 0xdc, 0xb3, 0x13, 0x28, 0x5f, + 0xf0, 0xd7, 0x7e, 0x65, 0xab, 0x88, 0x4e, 0xe0, 0x19, 0x52, 0xcc, 0x94, 0x18, 0xf8, 0x4c, 0xe5, + 0x17, 0xfb, 0xc7, 0x5b, 0x94, 0x75, 0xf5, 0x5a, 0xf8, 0xe2, 0xc8, 0xc7, 0x85, 0xcb, 0xe2, 0x0e, + 0x65, 0xbb, 0x32, 0x5d, 0xbf, 0x85, 0x0a, 0x5f, 0x11, 0x18, 0x33, 0x90, 0x6d, 0x37, 0x5c, 0x43, + 0xd3, 0x7b, 0xbf, 0xc1, 0x4d, 0xff, 0x7f, 0x9f, 0xda, 0x36, 0x5b, 0x9f, 0xe4, 0xbe, 0x0b, 0x25, + 0xb9, 0x88, 0xf2, 0xa4, 0x4a, 0x1a, 0x5f, 0xb4, 0xf1, 0x92, 0x5f, 0x04, 0x65, 0xd9, 0x8c, 0x12, + 0xbe, 0x65, 0xe0, 0x96, 0x63, 0x2d, 0xec, 0x71, 0xca, 0x44, 0xe5, 0x71, 0x64, 0x3e, 0x72, 0x7a, + 0xbf, 0x82, 0x91, 0x83, 0xaa, 0x58, 0xee, 0x2b, 0x6c, 0xbc, 0xb7, 0x36, 0xfa, 0xf8, 0xbb, 0xbb, + 0xbe, 0x47, 0x3f, 0xa0, 0x9f, 0x42, 0x5d, 0x1b, 0xbe, 0x8b, 0x97, 0xd6, 0x2b, 0xe0, 0x84, 0x89, + 0x5a, 0x6a, 0x1f, 0xd5, 0x83, 0xe8, 0x8c, 0x4b, 0xd6, 0x29, 0x39, 0xb7, 0x7f, 0x82, 0xab, 0x4c, + 0x69, 0x31, 0xb2, 0xa9, 0x4b, 0x13, 0xd1, 0x58, 0x5a, 0x55, 0xe0, 0x90, 0x89, 0x8c, 0xf1, 0x7b, + 0x7f, 0x78, 0x91, 0xa5, 0x50, 0x21, 0x56, 0x26, 0x16, 0x21, 0x4c, 0xeb, 0x5f, 0x8d, 0xfc, 0xd0, + 0x21, 0x21, 0x78, 0xbd, 0x75, 0x3c, 0x26, 0xa4, 0x86, 0xb9, 0x34, 0xd5, 0xfc, 0x68, 0xa9, 0x31, + 0x0e, 0x9b, 0x29, 0x01, 0x05, 0x1c, 0x8a, 0xc1, 0x41, 0x11, 0xf2, 0x0d, 0xe9, 0x00, 0xe3, 0x2b, + 0x43, 0x39, 0x3c, 0x20, 0x7a, 0xd7, 0x6b, 0xb1, 0x66, 0x23, 0x31, 0xbc, 0xe8, 0x35, 0x7a, 0xa7, + 0xa2, 0x36, 0x3f, 0x66, 0xc8, 0x67, 0x2f, 0x1b, 0x44, 0x99, 0x29, 0xf3, 0x02, 0x43, 0x08, 0x49, + 0xfe, 0x76, 0xa6, 0x31, 0xee, 0x18, 0xbc, 0xfa, 0x19, 0x05, 0xb6, 0xe0, 0x90, 0x39, 0x3a, 0xb1, + 0x2f, 0x2f, 0x6d, 0xef, 0x02, 0xf9, 0x4c, 0xbf, 0xac, 0xfb, 0xe0, 0xac, 0xee, 0xa5, 0x9b, 0x10, + 0x3c, 0x44, 0xe9, 0x8e, 0xb6, 0x30, 0x80, 0xe6, 0x34, 0x64, 0x9c, 0x31, 0xdd, 0xc8, 0xd6, 0xb6, + 0x9e, 0xc9, 0x63, 0xe1, 0x2d, 0x66, 0xe3, 0xec, 0xbf, 0xe1, 0x11, 0x22, 0xbe, 0x30, 0x98, 0xf9, + 0x1d, 0xa7, 0xe3, 0x32, 0x74, 0x70, 0xe5, 0x51, 0x8d, 0x7a, 0xa3, 0x42, 0x73, 0xa9, 0xf1, 0x47, + 0x5c, 0x41, 0xf1, 0x35, 0xae, 0xa6, 0x62, 0xa7, 0x54, 0x02, 0x30, 0x70, 0x70, 0x2f, 0x9f, 0x82, + 0x6a, 0x1d, 0x37, 0x89, 0x7b, 0x03, 0x56, 0x66, 0xff, 0x25, 0x55, 0x57, 0x12, 0x21, 0x95, 0xbb, + 0xa5, 0x88, 0x9b, 0xa9, 0xb3, 0xc1, 0x68, 0x89, 0x0b, 0xb5, 0xed, 0x35, 0xaf, 0x8a, 0x11, 0xb3, + 0x22, 0xf2, 0x31, 0xf8, 0x28, 0x9e, 0x0e, 0xe7, 0xed, 0xf7, 0x7f, 0xa0, 0x9d, 0x4d, 0xcc, 0x10, + 0xe6, 0xb1, 0xfd, 0x0b, 0xd7, 0xd6, 0xbe, 0x8e, 0x9d, 0x7a, 0x2a, 0x75, 0xe8, 0x8c, 0x7d, 0x4a, + 0x0f, 0xa2, 0x37, 0xd5, 0xbe, 0xad, 0xf5, 0x72, 0xfa, 0xbf, 0xc1, 0x00, 0x82, 0x90, 0x4d, 0x4a, + 0xe0, 0xc7, 0xc1, 0x7a, 0xc9, 0x91, 0xd1, 0xec, 0x41, 0xfa, 0x26, 0x53, 0xfc, 0x11, 0x55, 0x7f, + 0xfc, 0x28, 0x45, 0x79, 0xe0, 0xb7, 0x0d, 0x61, 0x6a, 0xbf, 0x9e, 0x96, 0xee, 0x3f, 0xe7, 0xac, + 0x29, 0xe7, 0xa8, 0xef, 0x12, 0x0a, 0x8a, 0xf3, 0x2c, 0x95, 0x50, 0xaa, 0x1e, 0x59, 0xff, 0x9b, + 0xa6, 0x72, 0xf8, 0x2d, 0x3a, 0xa8, 0x98, 0x60, 0x33, 0x25, 0x3e, 0xf8, 0x50, 0xc6, 0xeb, 0x24, + 0x20, 0xd3, 0x5a, 0xce, 0x2e, 0x30, 0xb5, 0x38, 0x7f, 0x8d, 0x9d, 0x1e, 0x20, 0xdb, 0xe0, 0x7a, + 0xff, 0x4c, 0x80, 0x2c, 0x7b, 0x8a, 0x3b, 0xd4, 0xb9, 0x9a, 0xa5, 0xe6, 0xd7, 0xad, 0x30, 0x8d, + 0xaf, 0x51, 0xe3, 0x8c, 0xc9, 0x3f, 0x8b, 0x17, 0x10, 0xf1, 0x1a, 0x6f, 0xe2, 0x07, 0x56, 0x2c, + 0x9d, 0xc2, 0xf1, 0xac, 0xde, 0x41, 0x5d, 0x08, 0xd9, 0x9b, 0x7f, 0xc6, 0x5e, 0x38, 0x70, 0xec, + 0x91, 0x05, 0x53, 0xf8, 0xd4, 0xae, 0x3d, 0xc6, 0x40, 0x4c, 0x8d, 0x97, 0xb1, 0x96, 0xbc, 0x42, + 0x3f, 0xa3, 0x5b, 0x83, 0xa8, 0xfc, 0x24, 0x53, 0xf4, 0xb8, 0x32, 0xb4, 0xa1, 0x81, 0xfc, 0x65, + 0x57, 0x37, 0x76, 0x7a, 0xad, 0xb7, 0xe2, 0x62, 0x0a, 0x4b, 0xaa, 0x65, 0x6d, 0x4b, 0x53, 0x62, + 0xa6, 0x58, 0x81, 0x03, 0x39, 0x32, 0x0f, 0x34, 0x46, 0x2e, 0x84, 0x34, 0xeb, 0x5b, 0xcb, 0x0c, + 0xf3, 0x18, 0x00, 0x01, 0x83, 0x66, 0x7e, 0x21, 0x79, 0x38, 0x98, 0x99, 0xd8, 0x9f, 0x26, 0x8d, + 0x8f, 0x88, 0x13, 0xf1, 0xfa, 0x6a, 0xf8, 0xeb, 0x2d, 0x94, 0x51, 0x72, 0x67, 0x82, 0xb2, 0x2d, + 0x55, 0x56, 0x1e, 0x11, 0xe2, 0x74, 0x0f, 0x44, 0x70, 0x0b, 0xbe, 0x14, 0x96, 0x99, 0x89, 0x28, + 0xbc, 0x8b, 0xe8, 0xcf, 0x4a, 0x76, 0x8f, 0x74, 0xfd, 0xf0, 0x4f, 0x71, 0x87, 0xd3, 0xdd, 0xb7, + 0x95, 0x3e, 0x30, 0x53, 0xf1, 0xe1, 0x8d, 0xfb, 0x3c, 0x60, 0xf8, 0xed, 0x2d, 0xe3, 0xdf, 0x0d, + 0xf9, 0xe0, 0x8c, 0xa7, 0xea, 0x94, 0x06, 0xbc, 0x19, 0xdc, 0x86, 0x34, 0x5f, 0x42, 0xd8, 0xfa, + 0xeb, 0xe8, 0xda, 0x93, 0xa3, 0xe5, 0xf0, 0x47, 0x75, 0x56, 0x0e, 0xaf, 0xae, 0x73, 0xeb, 0x9c, + 0xfa, 0xe7, 0x3e, 0x08, 0xed, 0x34, 0x92, 0x43, 0xb4, 0xfd, 0x14, 0xa9, 0xf1, 0x62, 0xb9, 0x98, + 0x4f, 0x1f, 0xc1, 0x27, 0x51, 0xd6, 0xb5, 0xf0, 0x5d, 0x55, 0x5a, 0xd1, 0xdb, 0xe1, 0xe1, 0x09, + 0xbf, 0x7b, 0xbb, 0xdd, 0xd6, 0xea, 0xff, 0xc4, 0x82, 0xb1, 0x39, 0x3e, 0x93, 0xd5, 0x56, 0xdf, + 0x45, 0x4e, 0xfc, 0x40, 0xaa, 0xc8, 0xc9, 0xa9, 0x42, 0x74, 0x60, 0x7e, 0x14, 0x89, 0xc3, 0xc4, + 0xf0, 0x4d, 0x8e, 0x6b, 0x29, 0x6b, 0x5a, 0xf8, 0x50, 0xe6, 0x52, 0x24, 0xd0, 0x78, 0x86, 0x7d, + 0x41, 0x9a, 0xd3, 0xbc, 0x71, 0xe9, 0xb6, 0x16, 0x9b, 0x60, 0x25, 0x98, 0xa1, 0x77, 0xc1, 0x5e, + 0x46, 0xb2, 0x58, 0x92, 0x0c, 0x52, 0x5e, 0x0e, 0x18, 0x77, 0x59, 0xaf, 0x90, 0xeb, 0x7f, 0xac, + 0x5f, 0x29, 0x5b, 0x96, 0x1c, 0x48, 0x91, 0x24, 0xd1, 0x3c, 0x8f, 0x48, 0x78, 0x40, 0x9e, 0x47, + 0x10, 0x24, 0x10, 0x9a, 0x9d, 0x4e, 0xb5, 0xf0, 0x9e, 0xf7, 0x62, 0x21, 0xa2, 0xe7, 0xe5, 0x28, + 0xba, 0xa9, 0xbf, 0x82, 0x62, 0xd5, 0x83, 0x63, 0x12, 0x48, 0x24, 0xd3, 0x02, 0x0b, 0x08, 0xac, + 0x3d, 0xf0, 0x96, 0xc1, 0x8c, 0xbc, 0xa8, 0x04, 0x7c, 0x15, 0x60, 0x54, 0x03, 0x5c, 0x60, 0xe6, + 0x44, 0xf1, 0x82, 0x6b, 0x68, 0x20, 0x71, 0x25, 0xfe, 0x2c, 0x6b, 0xad, 0xbd, 0xf8, 0xef, 0x6f, + 0x82, 0xbe, 0x3a, 0x20, 0x59, 0x63, 0x2c, 0x5d, 0xa4, 0xce, 0x59, 0xce, 0x5a, 0x5e, 0xb1, 0x46, + 0xf3, 0x9e, 0x0c, 0xa6, 0x99, 0x3f, 0xfa, 0xea, 0xdf, 0x58, 0xd2, 0x75, 0x8f, 0x7d, 0x17, 0xc7, + 0xd6, 0x0f, 0x82, 0x2a, 0x51, 0xd1, 0xd1, 0x80, 0xf3, 0xfc, 0x14, 0x98, 0x57, 0x22, 0xeb, 0xcd, + 0x4a, 0xac, 0x67, 0xfc, 0x14, 0x96, 0xd1, 0xad, 0xd8, 0x45, 0x13, 0x06, 0x46, 0xe7, 0x62, 0x3a, + 0xff, 0x05, 0x76, 0x37, 0xe4, 0x66, 0x81, 0xb3, 0x76, 0xdc, 0x68, 0x62, 0x71, 0xdf, 0x12, 0x38, + 0x53, 0xb6, 0x5c, 0xb3, 0xff, 0x96, 0xdc, 0xb6, 0x20, 0x73, 0x88, 0x1c, 0x25, 0x55, 0x5a, 0xad, + 0x48, 0xc4, 0x9b, 0x1d, 0x98, 0x98, 0x24, 0x2b, 0x88, 0x16, 0x27, 0x20, 0xf7, 0xc1, 0x58, 0x85, + 0x93, 0x4b, 0xdc, 0x18, 0x0b, 0x7e, 0xf6, 0xed, 0xb7, 0xcd, 0x29, 0x3a, 0xf1, 0x22, 0x04, 0x95, + 0x8a, 0xe9, 0x1d, 0x8b, 0x3e, 0x5f, 0x82, 0xa1, 0x28, 0x64, 0x50, 0x3e, 0x98, 0x89, 0x8c, 0xdd, + 0x87, 0x60, 0x9b, 0xa3, 0xb3, 0xe8, 0x8f, 0xf0, 0x45, 0xb1, 0x34, 0x57, 0x77, 0xc5, 0xd5, 0x58, + 0x2a, 0x3a, 0xbf, 0x94, 0x98, 0x79, 0x07, 0x47, 0xf5, 0x7a, 0xe1, 0x21, 0x32, 0xe5, 0x2b, 0xdf, + 0xc2, 0x83, 0x15, 0xe2, 0x1c, 0x2d, 0xb7, 0xb9, 0x23, 0x51, 0xfd, 0xb0, 0x99, 0x1c, 0xc7, 0xae, + 0x26, 0x14, 0x39, 0x21, 0x51, 0xd8, 0x28, 0x86, 0x4f, 0x32, 0xcc, 0xef, 0x13, 0x62, 0x6e, 0xc0, + 0x65, 0x20, 0xd9, 0xf1, 0x87, 0xea, 0xd0, 0xde, 0x20, 0x3b, 0xb0, 0x83, 0x51, 0x5c, 0x32, 0x5f, + 0x54, 0x70, 0xc7, 0xe3, 0x23, 0x44, 0x8a, 0x0a, 0xa4, 0x20, 0xee, 0xab, 0x12, 0x90, 0x27, 0x86, + 0x84, 0x82, 0x22, 0x87, 0xaa, 0x56, 0x19, 0xd5, 0x65, 0x2b, 0x77, 0xe0, 0xaa, 0x2a, 0x6c, 0xd9, + 0x89, 0x51, 0x9c, 0xd3, 0x7a, 0x29, 0xc8, 0x4a, 0x4f, 0xf9, 0x5c, 0x24, 0x39, 0xcf, 0x47, 0xb7, + 0xd7, 0xc2, 0xd0, 0xe7, 0x09, 0x53, 0x56, 0x7b, 0x07, 0x73, 0xb0, 0x6a, 0x92, 0x73, 0x31, 0xe2, + 0x3b, 0x13, 0x6a, 0x92, 0xe5, 0xd4, 0xd9, 0xf9, 0x2d, 0x34, 0x92, 0x47, 0xea, 0xe4, 0x9d, 0x17, + 0xbe, 0x4a, 0xbb, 0xaf, 0xa8, 0xf0, 0xfa, 0xc5, 0xf2, 0x56, 0xff, 0x04, 0x3b, 0xba, 0x3e, 0xae, + 0x73, 0x2a, 0x0c, 0xb8, 0x96, 0xee, 0xdf, 0xc2, 0x12, 0x32, 0xde, 0x87, 0x64, 0x9a, 0xd5, 0x3f, + 0x04, 0xd6, 0x79, 0xa4, 0x93, 0xf7, 0x47, 0xfc, 0x21, 0x36, 0x55, 0xbe, 0xcc, 0xd7, 0x76, 0x35, + 0xc4, 0x0c, 0x11, 0x74, 0xe2, 0x6c, 0x28, 0xe3, 0x28, 0xa3, 0x35, 0x3c, 0x37, 0xa8, 0x77, 0x7a, + 0x92, 0xff, 0x04, 0x63, 0x6a, 0xcd, 0x27, 0xf8, 0x28, 0xa1, 0xb1, 0x95, 0x8c, 0xfe, 0xe6, 0xfd, + 0xf0, 0xa4, 0x22, 0x51, 0xd9, 0x08, 0x0d, 0x88, 0xf3, 0xcc, 0x6f, 0x40, 0xa2, 0xcc, 0x56, 0xa2, + 0x32, 0x8f, 0x12, 0x17, 0x34, 0xe1, 0x33, 0x09, 0x92, 0x0a, 0xfa, 0x67, 0xbc, 0x13, 0x6d, 0xa7, + 0x19, 0x95, 0xf8, 0xc2, 0x74, 0xde, 0xa5, 0xc2, 0xf4, 0x3d, 0x9a, 0xc5, 0xaa, 0x99, 0xbf, 0xc4, + 0x88, 0x09, 0xcb, 0x62, 0xb7, 0x72, 0x33, 0xbf, 0x82, 0x82, 0xe4, 0xaa, 0x36, 0xd9, 0x9f, 0x54, + 0xa7, 0xa3, 0xbf, 0x5e, 0xf8, 0x2c, 0x3b, 0x62, 0xea, 0x4f, 0xb1, 0xab, 0x6c, 0x50, 0x56, 0x67, + 0xb8, 0x98, 0xf1, 0x57, 0xbc, 0x4a, 0xa2, 0xee, 0xf7, 0xc4, 0x88, 0x08, 0x1e, 0x28, 0x65, 0xec, + 0x9d, 0xa6, 0xbd, 0x06, 0xe7, 0x23, 0x7e, 0x21, 0x7b, 0xe0, 0x8c, 0xa3, 0x68, 0x1d, 0xdf, 0x07, + 0x77, 0xf1, 0x23, 0x0c, 0xe3, 0xfe, 0x2e, 0x37, 0x3b, 0x47, 0xc5, 0xd5, 0x57, 0x6d, 0x9f, 0x89, + 0x30, 0xf9, 0xb1, 0xf0, 0xba, 0x45, 0x51, 0x76, 0xf8, 0x98, 0xc1, 0x61, 0xba, 0xd4, 0x29, 0x30, + 0x81, 0x1c, 0x17, 0x05, 0x81, 0x83, 0x5b, 0xea, 0x27, 0x87, 0x60, 0x1f, 0x39, 0x10, 0x6b, 0x8c, + 0x64, 0x00, 0x35, 0x11, 0x01, 0xe2, 0xe9, 0xf8, 0x50, 0xca, 0x23, 0xa6, 0x18, 0x9c, 0x35, 0x5c, + 0x97, 0xf2, 0x9d, 0x66, 0xa5, 0x27, 0xc1, 0x10, 0x94, 0x0e, 0xd2, 0xa4, 0xf8, 0xc2, 0x02, 0x11, + 0xa6, 0xc3, 0x67, 0x67, 0x18, 0x2c, 0xa8, 0x5e, 0x97, 0xa3, 0x13, 0xa5, 0x35, 0x83, 0x12, 0x83, + 0x56, 0x38, 0xd9, 0x4a, 0x6a, 0x5a, 0x9a, 0xf0, 0x46, 0x56, 0x04, 0x80, 0x43, 0x0d, 0xd5, 0x44, + 0xff, 0x04, 0x66, 0x6b, 0x56, 0xf8, 0x54, 0x42, 0x77, 0x2f, 0x7d, 0x37, 0xa9, 0xea, 0xa7, 0x5b, + 0x37, 0xfc, 0x37, 0x1b, 0x5e, 0x93, 0x3c, 0xed, 0x78, 0x66, 0x5f, 0xfd, 0x1d, 0x8a, 0xee, 0xdb, + 0x67, 0x67, 0xf5, 0xf8, 0x7d, 0x7e, 0x9b, 0xac, 0x5f, 0x5a, 0xf9, 0x6a, 0xa2, 0xeb, 0xeb, 0x14, + 0x9d, 0x5b, 0xe0, 0x92, 0xda, 0x6d, 0xf3, 0x7d, 0x5a, 0xb9, 0xa8, 0xd1, 0xa3, 0x47, 0xe8, 0x8e, + 0xbe, 0xa7, 0x4f, 0xab, 0xf1, 0x30, 0x52, 0x74, 0xdd, 0xcf, 0xc4, 0x3c, 0xfd, 0xf9, 0x4b, 0x66, + 0xfd, 0xf0, 0x5d, 0x17, 0x1e, 0xf2, 0x97, 0xcd, 0x96, 0x9f, 0xe1, 0x11, 0x43, 0xe6, 0x3d, 0xee, + 0xc1, 0x8f, 0x9a, 0x06, 0x4d, 0x97, 0x6f, 0xe0, 0x84, 0x7a, 0x26, 0x8a, 0x1a, 0xa3, 0x67, 0xc7, + 0x19, 0xb9, 0xaf, 0x6a, 0xb7, 0xb5, 0xe0, 0x90, 0xab, 0x72, 0x90, 0x5c, 0xf8, 0x29, 0xb1, 0xfa, + 0x02, 0x60, 0x6c, 0x64, 0x46, 0xcf, 0x72, 0x33, 0x91, 0x0e, 0xbe, 0x0a, 0xf5, 0x3d, 0x24, 0x8c, + 0x31, 0x50, 0xc1, 0x40, 0xc5, 0x03, 0x92, 0x89, 0xf5, 0x17, 0xce, 0x1f, 0x0a, 0x10, 0x9f, 0x2b, + 0x24, 0xd5, 0x74, 0x27, 0x99, 0xf3, 0xa8, 0x29, 0x1f, 0x9c, 0x4c, 0x13, 0x9c, 0xcc, 0x31, 0x8e, + 0x1c, 0x16, 0x1c, 0x16, 0x21, 0x7f, 0x37, 0x11, 0x05, 0x51, 0x71, 0x1e, 0x79, 0xe5, 0xf1, 0xbd, + 0xf6, 0x0c, 0xdb, 0xff, 0x10, 0x0b, 0x4d, 0x15, 0xa4, 0x5f, 0xaa, 0x4c, 0x71, 0x02, 0x41, 0x15, + 0xb7, 0xf9, 0x56, 0x24, 0x42, 0xf7, 0x12, 0x20, 0x79, 0x6b, 0x55, 0xae, 0xb5, 0xf2, 0x08, 0x46, + 0x88, 0x92, 0x6d, 0xf8, 0x29, 0x38, 0xe0, 0xe4, 0x6a, 0x3a, 0x1e, 0x2e, 0x9a, 0xb2, 0x1b, 0xbe, + 0xda, 0x3b, 0xb8, 0x61, 0x7f, 0x82, 0xd2, 0x96, 0x1d, 0x56, 0x09, 0x26, 0x90, 0xdd, 0x1e, 0x7c, + 0x61, 0x25, 0x48, 0x92, 0x6d, 0x7a, 0xcb, 0xcb, 0xeb, 0x49, 0xe6, 0x10, 0x5d, 0x44, 0x24, 0x86, + 0x3b, 0x21, 0xb4, 0x40, 0xe2, 0x60, 0xa6, 0x7e, 0x9b, 0xe1, 0xb1, 0xaf, 0x2c, 0x0d, 0x82, 0xab, + 0xc7, 0xb3, 0x3e, 0x12, 0xdd, 0xd8, 0x8b, 0x68, 0xd2, 0xf9, 0x6e, 0xe3, 0xd9, 0x47, 0xe5, 0xd6, + 0xab, 0x8f, 0x10, 0xe3, 0xf9, 0x3d, 0xc5, 0x4b, 0x2f, 0xfc, 0x36, 0x52, 0xcd, 0xc4, 0xbd, 0xba, + 0x4c, 0x14, 0xe9, 0x48, 0xa3, 0xf5, 0xd1, 0x4a, 0x9f, 0x3d, 0x4c, 0x69, 0x33, 0x6c, 0x7f, 0xeb, + 0x15, 0x70, 0x45, 0x9e, 0xed, 0x31, 0xf0, 0x45, 0x3b, 0x25, 0x65, 0x8e, 0x0d, 0x87, 0xa2, 0x3f, + 0xd5, 0xef, 0x9e, 0xb8, 0xab, 0x6f, 0xd7, 0x04, 0x94, 0x32, 0x14, 0x43, 0x83, 0x7f, 0xaf, 0xcb, + 0xeb, 0xe3, 0xee, 0xd5, 0x2b, 0xe8, 0xfd, 0xf1, 0x54, 0xa6, 0xc2, 0xe5, 0x58, 0xeb, 0xb2, 0x34, + 0x93, 0x0f, 0xe8, 0x8f, 0xc4, 0x88, 0x0f, 0x14, 0x89, 0x5c, 0xec, 0x4b, 0xbb, 0x8c, 0xf3, 0xde, + 0x1d, 0x69, 0x0c, 0x01, 0xf4, 0xc3, 0xff, 0x10, 0x33, 0x7d, 0xd8, 0xdc, 0x81, 0xbd, 0x37, 0x08, + 0x7c, 0xf8, 0x73, 0x1c, 0x74, 0xcf, 0x4f, 0x11, 0x11, 0x55, 0x55, 0x56, 0x34, 0x7e, 0x20, 0x65, + 0x76, 0x73, 0x51, 0xbd, 0xe8, 0x90, 0xea, 0x9f, 0xc1, 0x51, 0xa8, 0xf7, 0x77, 0x3b, 0x02, 0x5e, + 0xd4, 0x7c, 0x28, 0x9c, 0x23, 0x7c, 0x14, 0x1d, 0x06, 0xc6, 0x99, 0x12, 0x6e, 0xf1, 0x55, 0x4f, + 0xf0, 0x4f, 0xaa, 0xa4, 0xa4, 0xe4, 0xf3, 0xde, 0x20, 0x28, 0x55, 0x8b, 0x9a, 0x8f, 0x30, 0x0b, + 0x95, 0xa4, 0x20, 0xd3, 0x7c, 0x1f, 0x6d, 0xfe, 0x09, 0xa5, 0x87, 0xbe, 0x4d, 0xb7, 0x88, 0x05, + 0x5b, 0xc6, 0xea, 0xa7, 0xa2, 0x20, 0x60, 0x26, 0x51, 0xd0, 0x0d, 0xdf, 0x1b, 0x19, 0x3c, 0xa5, + 0xec, 0x3d, 0x42, 0xc4, 0xc3, 0x14, 0x6c, 0xdb, 0x16, 0x5a, 0x06, 0x91, 0xa2, 0xde, 0xaf, 0x76, + 0xbf, 0xc1, 0x44, 0x86, 0x29, 0x31, 0xc6, 0xf1, 0xfe, 0xf8, 0x28, 0xd8, 0xeb, 0xa2, 0x72, 0x27, + 0xc7, 0x62, 0x2c, 0x30, 0x70, 0x32, 0x30, 0xb3, 0x33, 0x13, 0x47, 0xf0, 0x5b, 0x77, 0xd2, 0x56, + 0x0e, 0x2b, 0xbe, 0x10, 0xb1, 0xe5, 0x61, 0xed, 0x9e, 0x56, 0x1b, 0xf1, 0x02, 0x4c, 0x62, 0xa4, + 0x64, 0x71, 0x03, 0x4f, 0x88, 0x0a, 0x45, 0x62, 0xb7, 0x73, 0x98, 0xa5, 0xb2, 0x3e, 0x5d, 0x4e, + 0xdc, 0xf7, 0xef, 0x8c, 0x3e, 0x11, 0x33, 0xf9, 0x44, 0xda, 0xeb, 0xe7, 0x0f, 0xdd, 0x41, 0xcd, + 0x75, 0x98, 0x59, 0xe1, 0x80, 0xb5, 0xeb, 0x2e, 0x38, 0x60, 0xfe, 0x14, 0xbd, 0x9f, 0x07, 0xf3, + 0x29, 0x05, 0xac, 0x2d, 0x3b, 0xa4, 0x49, 0x30, 0xef, 0x30, 0x0d, 0x14, 0x6c, 0x81, 0xcb, 0xe1, + 0x4c, 0x02, 0xa4, 0xe3, 0x70, 0x69, 0x35, 0x5d, 0x9a, 0x56, 0x02, 0xe3, 0x41, 0x02, 0x5d, 0xe7, + 0xa9, 0x3b, 0xbb, 0xb3, 0x8e, 0x5c, 0x62, 0x10, 0x89, 0xf0, 0xa1, 0x58, 0x13, 0x56, 0x4b, 0x13, + 0x3d, 0x01, 0xd4, 0x67, 0x19, 0xe3, 0x3e, 0xd1, 0x50, 0x75, 0xf8, 0x2f, 0xb3, 0xec, 0x25, 0xe5, + 0xda, 0x1f, 0x6c, 0x06, 0xef, 0x29, 0x6b, 0x9f, 0xe0, 0x90, 0x8c, 0xf5, 0xff, 0x88, 0x05, 0x9c, + 0xd8, 0xa2, 0x69, 0x33, 0x74, 0xf6, 0x7c, 0x13, 0x15, 0xe9, 0xf5, 0x2a, 0x65, 0x4e, 0x26, 0x2e, + 0x58, 0xfb, 0x4c, 0x1b, 0x5e, 0x13, 0x22, 0x1c, 0x2a, 0xd3, 0x2b, 0x12, 0xb1, 0xf0, 0xf0, 0xc4, + 0xcb, 0x69, 0xba, 0x25, 0x1d, 0xca, 0xab, 0x0a, 0x20, 0x81, 0xbd, 0xd5, 0x11, 0x8c, 0x61, 0xb7, + 0x75, 0xfe, 0x1b, 0x13, 0x6b, 0x82, 0xad, 0x9b, 0x1d, 0x46, 0x4b, 0xfc, 0xf5, 0x4d, 0x3a, 0xca, + 0xcf, 0xbe, 0x88, 0xff, 0x04, 0x65, 0x33, 0x28, 0x66, 0x67, 0xbf, 0xd5, 0xef, 0xac, 0x5f, 0x57, + 0xae, 0x09, 0x36, 0xdc, 0xdf, 0x1c, 0x9c, 0x97, 0xdd, 0x70, 0x43, 0xaa, 0xeb, 0xe0, 0x8e, 0x92, + 0x49, 0x33, 0x7b, 0xe0, 0x88, 0x89, 0x25, 0x6a, 0x2a, 0xe3, 0x4a, 0x4a, 0xa3, 0x40, 0xd9, 0xde, + 0x35, 0x41, 0x7e, 0xc6, 0xfc, 0x9f, 0x3f, 0x31, 0xa2, 0x6b, 0x4a, 0xc6, 0x17, 0xf8, 0xd2, 0x50, + 0x9d, 0x15, 0x37, 0x4f, 0xc6, 0x6a, 0x9b, 0x3d, 0x48, 0xee, 0x62, 0xee, 0x60, 0xfe, 0x31, 0x58, + 0xb6, 0x2b, 0x18, 0x82, 0x0a, 0xd3, 0x80, 0xab, 0xd3, 0x08, 0x90, 0xff, 0x10, 0x24, 0x14, 0x16, + 0x46, 0x3c, 0xb9, 0xd7, 0xca, 0x76, 0xed, 0xbf, 0x8f, 0x22, 0xd4, 0x5c, 0x79, 0x72, 0xf3, 0x51, + 0x64, 0x5d, 0x78, 0x81, 0x17, 0x2d, 0x3e, 0x72, 0x2c, 0x37, 0x31, 0xc4, 0x05, 0x38, 0xcd, 0x8b, + 0x0c, 0x8a, 0xe6, 0xe9, 0x15, 0x93, 0xd4, 0xf9, 0xd4, 0x3b, 0x95, 0xec, 0xa6, 0x7e, 0xf8, 0x50, + 0x43, 0xc3, 0x01, 0x7b, 0x12, 0xf2, 0xa8, 0x4a, 0x81, 0x34, 0x48, 0x96, 0xee, 0x7f, 0x9e, 0x90, + 0x5b, 0x1d, 0xef, 0x82, 0xb1, 0x2a, 0xb9, 0x18, 0x18, 0x5e, 0x0a, 0xb4, 0x48, 0x0d, 0x93, 0x7c, + 0xc5, 0x3c, 0x7f, 0x82, 0x39, 0xd4, 0x31, 0x58, 0xb3, 0xfc, 0xa4, 0x4e, 0x1d, 0xac, 0xa7, 0xe0, + 0x8c, 0xac, 0x71, 0xe7, 0x47, 0x0f, 0xe0, 0xbb, 0x26, 0x25, 0xc3, 0xb8, 0x4f, 0x1f, 0xfe, 0x0a, + 0xe3, 0xc8, 0x7d, 0x09, 0xbc, 0xd0, 0xcd, 0xaa, 0xe5, 0x90, 0xfb, 0xe1, 0x43, 0x2d, 0x4d, 0xf1, + 0x94, 0xce, 0x66, 0x1d, 0xe5, 0x53, 0x14, 0x2a, 0x6b, 0xb5, 0xc2, 0xc8, 0x11, 0xf5, 0x3a, 0x7c, + 0x65, 0xee, 0x8c, 0xa6, 0x70, 0x6a, 0xb1, 0xd2, 0xe6, 0x69, 0xbb, 0x3f, 0x0a, 0x4d, 0xd6, 0x01, + 0xb0, 0x2b, 0x69, 0xd9, 0x58, 0xde, 0xd3, 0x5a, 0x7f, 0x10, 0x30, 0xac, 0x68, 0xc3, 0xb6, 0x35, + 0x4e, 0x31, 0x0f, 0x15, 0xa7, 0x0c, 0x29, 0xb1, 0xfa, 0xda, 0x8b, 0xaa, 0xc0, 0xed, 0x2c, 0xb0, + 0x20, 0x4d, 0x5c, 0xbd, 0xab, 0x58, 0x1f, 0xeb, 0xff, 0x84, 0xb9, 0x04, 0x2f, 0xd2, 0x55, 0xf0, + 0x59, 0xa5, 0x08, 0x72, 0x4a, 0xde, 0xfa, 0x10, 0xd0, 0xef, 0x0e, 0xae, 0xb7, 0x30, 0xc8, 0x64, + 0xf8, 0x22, 0xaa, 0x32, 0x48, 0xe3, 0x36, 0x44, 0x25, 0x4d, 0xbb, 0xc7, 0xc6, 0x4f, 0xd0, 0x83, + 0x07, 0xa0, 0x72, 0x82, 0x0d, 0x69, 0x88, 0x20, 0x2c, 0x31, 0x29, 0x8d, 0x87, 0x92, 0x88, 0xfc, + 0x61, 0x78, 0x80, 0x59, 0x7b, 0x06, 0x72, 0x3a, 0xaf, 0x30, 0xc6, 0xaf, 0x35, 0xf5, 0xeb, 0xe1, + 0x4d, 0x51, 0xe1, 0x64, 0x00, 0x04, 0xf8, 0xe2, 0x15, 0xa3, 0x5a, 0x26, 0x9f, 0x5f, 0x04, 0x63, + 0x1d, 0xe2, 0xb9, 0x4d, 0xd0, 0x9a, 0x9b, 0xab, 0xfd, 0x75, 0x11, 0xcf, 0x53, 0xc0, 0x8f, 0x3c, + 0x18, 0xff, 0xf3, 0xea, 0xd9, 0xf7, 0xfa, 0xe1, 0x01, 0x0f, 0xab, 0xbc, 0x64, 0x84, 0x76, 0x18, + 0xf4, 0x7e, 0x27, 0x2a, 0xab, 0x5b, 0x7e, 0x13, 0x3c, 0x5e, 0xc2, 0xbd, 0xfc, 0x20, 0x24, 0xf3, + 0x70, 0x40, 0x4f, 0x17, 0x5c, 0xf4, 0x48, 0x7b, 0xf8, 0x26, 0x22, 0xe9, 0xa9, 0x12, 0x22, 0xcf, + 0x78, 0x92, 0xcb, 0x0c, 0xe3, 0xfc, 0x40, 0xe8, 0x41, 0x46, 0x38, 0x8c, 0x25, 0x56, 0x93, 0xb4, + 0x2d, 0xd8, 0xac, 0x62, 0xb9, 0x69, 0x0b, 0x37, 0x88, 0x14, 0x41, 0x1c, 0x2f, 0x51, 0x79, 0xc3, + 0x72, 0x10, 0x7c, 0x4f, 0x12, 0xf9, 0x3a, 0x82, 0xec, 0x43, 0xfc, 0x12, 0x96, 0xf7, 0x5a, 0x77, + 0xf8, 0x2d, 0x91, 0x9b, 0xc5, 0x6e, 0x2b, 0x12, 0xa4, 0x7f, 0x8a, 0xaa, 0x6d, 0xc8, 0xbd, 0x0c, + 0xcc, 0xf8, 0x2b, 0xb3, 0x97, 0xaa, 0xd4, 0xc3, 0xf0, 0xef, 0xb2, 0x63, 0xeb, 0xdf, 0x13, 0xce, + 0xc5, 0xec, 0xbe, 0xe2, 0x56, 0x0b, 0x62, 0xb1, 0x0b, 0x1e, 0x12, 0x22, 0xc7, 0x95, 0xc6, 0x55, + 0x46, 0x96, 0x57, 0x05, 0x65, 0x4a, 0x63, 0x74, 0x21, 0xd7, 0x24, 0x7a, 0x26, 0xbc, 0x51, 0x08, + 0x68, 0x20, 0x2b, 0x9c, 0xca, 0xbf, 0x88, 0x2a, 0xca, 0xac, 0x17, 0x0f, 0x44, 0xb1, 0xe1, 0x49, + 0xa6, 0x1e, 0xcd, 0x5c, 0x44, 0xea, 0xaa, 0x1a, 0x1b, 0x01, 0x00, 0x48, 0x3e, 0xcc, 0x83, 0xc6, + 0x32, 0x76, 0x30, 0xf2, 0x8e, 0xe9, 0x94, 0xcb, 0xc2, 0xb5, 0x5e, 0x54, 0xf9, 0x60, 0x82, 0x8d, + 0x1f, 0xf6, 0xdb, 0x4d, 0x3c, 0x4c, 0x29, 0x12, 0xc6, 0xf6, 0x43, 0x4a, 0xc7, 0x46, 0x8c, 0xf8, + 0x40, 0x3b, 0x03, 0x30, 0x60, 0xf1, 0x03, 0xba, 0x6f, 0xb2, 0xe4, 0x80, 0xd5, 0x54, 0xd2, 0x2c, + 0xf8, 0xc2, 0x2a, 0xac, 0xf8, 0xca, 0x82, 0x2a, 0x83, 0x9c, 0x97, 0x41, 0x84, 0x89, 0xe6, 0xa7, + 0xc5, 0xd2, 0x5f, 0x2d, 0x3e, 0x43, 0xd8, 0x9d, 0xfd, 0x7b, 0xe6, 0xbb, 0xeb, 0x97, 0x87, 0x53, + 0xd3, 0xf0, 0x44, 0x39, 0x27, 0x7b, 0x3e, 0x09, 0xa5, 0x61, 0x5a, 0x34, 0x43, 0x33, 0x1a, 0xad, + 0x5d, 0xf3, 0x1d, 0x8d, 0x8d, 0x8c, 0x54, 0x64, 0xeb, 0x87, 0xd7, 0x5f, 0x56, 0x2f, 0xab, 0x2b, + 0xab, 0xaf, 0x92, 0x9b, 0x69, 0x9d, 0x97, 0xd5, 0xdf, 0x56, 0x7d, 0x5c, 0xae, 0x61, 0x07, 0x31, + 0x71, 0x5b, 0xf8, 0x25, 0x88, 0x61, 0x5b, 0xdb, 0x47, 0x5d, 0x7c, 0x64, 0x53, 0x17, 0x5d, 0xc4, + 0x9c, 0x6f, 0x17, 0x14, 0xe6, 0xee, 0x84, 0x79, 0xbf, 0x85, 0x0e, 0xef, 0xc5, 0x63, 0x78, 0x60, + 0xcb, 0x6e, 0xde, 0x93, 0x85, 0xdc, 0x92, 0x5a, 0xb5, 0xe2, 0x04, 0xf7, 0xba, 0xc4, 0x15, 0x12, + 0xe3, 0x1a, 0x97, 0xc5, 0x09, 0x4d, 0x6c, 0xd3, 0x3a, 0x94, 0x25, 0xe2, 0xb7, 0xc4, 0x11, 0x72, + 0xd7, 0x96, 0x08, 0xbc, 0x21, 0x45, 0x98, 0xc6, 0xef, 0x75, 0x5f, 0x89, 0x25, 0x65, 0x57, 0xc6, + 0x65, 0xf6, 0x85, 0x6f, 0x12, 0xf4, 0x39, 0x06, 0xc7, 0x31, 0xb3, 0xa0, 0x7c, 0x40, 0x50, 0xca, + 0x42, 0x09, 0xfe, 0x5e, 0xb5, 0x55, 0x5b, 0x35, 0x5c, 0xff, 0xc4, 0x0c, 0xd5, 0x57, 0x54, 0x6a, + 0xba, 0xcc, 0xc2, 0xf8, 0xcb, 0x64, 0x65, 0xbe, 0x3c, 0x8a, 0x66, 0xe5, 0x66, 0x8d, 0x5d, 0x14, + 0xa0, 0xea, 0x63, 0xf1, 0x77, 0x77, 0xbb, 0xbf, 0xd9, 0x50, 0xe8, 0x6d, 0x62, 0x23, 0xbc, 0x9d, + 0xb7, 0xf5, 0x5f, 0x85, 0x2c, 0x73, 0x41, 0x54, 0xdd, 0x7a, 0x4c, 0x9d, 0x2c, 0xc6, 0x2e, 0x7c, + 0x28, 0x50, 0xf9, 0x52, 0x8c, 0xeb, 0x09, 0xa9, 0x95, 0x94, 0x0d, 0x5a, 0xfc, 0x8e, 0xad, 0x0d, + 0x12, 0xd6, 0xe6, 0x57, 0x88, 0x19, 0x46, 0x3e, 0x32, 0x5e, 0x36, 0xd8, 0xb3, 0xd0, 0xea, 0x35, + 0x95, 0x03, 0x28, 0x87, 0x55, 0x29, 0x95, 0xe2, 0x02, 0x9b, 0x9b, 0x0d, 0x1d, 0x7a, 0x78, 0xd8, + 0xe2, 0x17, 0x52, 0x61, 0xec, 0xaa, 0x91, 0x69, 0x40, 0x7a, 0xa5, 0x61, 0xe5, 0x0c, 0x4e, 0x19, + 0x3c, 0x40, 0x52, 0x1f, 0x4a, 0xf1, 0x62, 0x4e, 0x69, 0x24, 0x1f, 0x84, 0x91, 0x04, 0x05, 0x71, + 0xc2, 0x9a, 0xd2, 0x18, 0xc7, 0x30, 0x6a, 0x99, 0x78, 0x26, 0xf3, 0xc0, 0x34, 0xd6, 0x8e, 0x90, + 0xf8, 0xce, 0x34, 0x64, 0xa8, 0x70, 0x26, 0xfd, 0x98, 0xcf, 0x19, 0x96, 0xdb, 0xcf, 0xc1, 0x6d, + 0x87, 0x63, 0x41, 0x31, 0xa1, 0xaa, 0x06, 0x43, 0x17, 0xf8, 0x4b, 0x33, 0x69, 0x92, 0xaa, 0x31, + 0x93, 0x58, 0xf0, 0x55, 0x52, 0x31, 0x72, 0xd8, 0xad, 0xc6, 0xd9, 0x1e, 0x9a, 0x3a, 0x65, 0xe1, + 0x13, 0x98, 0xca, 0x02, 0x90, 0xfc, 0xa7, 0x98, 0x99, 0x3c, 0x3a, 0x97, 0x87, 0xf0, 0x5c, 0x42, + 0x6b, 0x55, 0xa6, 0x93, 0xcc, 0x47, 0xbe, 0x22, 0xda, 0x7b, 0x5b, 0x5e, 0x13, 0x33, 0xea, 0xb5, + 0xbe, 0x34, 0xce, 0x08, 0x8b, 0xb3, 0x53, 0xb5, 0x0e, 0x81, 0x30, 0x7a, 0xea, 0xe5, 0xa1, 0xb7, + 0xa1, 0xee, 0x61, 0xaa, 0x9b, 0x92, 0x07, 0x23, 0x24, 0x62, 0xbf, 0xe8, 0x4c, 0x17, 0xcf, 0x5f, + 0x2b, 0xc8, 0xf2, 0xbd, 0x8f, 0x5d, 0x72, 0xfa, 0x24, 0x55, 0xd5, 0x8f, 0x82, 0x22, 0xc8, 0x45, + 0x2f, 0x17, 0xcd, 0x5d, 0xd7, 0x25, 0x36, 0xd3, 0x6f, 0xde, 0xee, 0xfe, 0xb2, 0x93, 0xab, 0xbe, + 0x4a, 0x69, 0xfe, 0x1d, 0xb3, 0xcb, 0x4d, 0x55, 0x7a, 0x9d, 0x7b, 0x28, 0xce, 0x9f, 0xe2, 0x45, + 0x5b, 0x41, 0x24, 0x83, 0xb3, 0x3a, 0x4f, 0x04, 0x25, 0xd5, 0x7b, 0xc4, 0x8b, 0x97, 0xba, 0x4e, + 0xef, 0x7f, 0x04, 0xc2, 0x58, 0xaa, 0xba, 0x35, 0xe5, 0xf1, 0x00, 0xac, 0x61, 0x4f, 0x87, 0xae, + 0xaa, 0x84, 0x93, 0x62, 0xe3, 0x80, 0xb6, 0xe3, 0xa9, 0x05, 0x79, 0x20, 0x84, 0x72, 0x69, 0xd7, + 0x14, 0xdb, 0x51, 0xef, 0x8b, 0x1a, 0x2b, 0x71, 0x08, 0x80, 0xd9, 0xff, 0xf8, 0x2a, 0xd5, 0x54, + 0x4c, 0x82, 0x2f, 0x99, 0x8b, 0xdd, 0x1c, 0x7c, 0x42, 0xeb, 0x89, 0x10, 0x3b, 0xb1, 0xbb, 0x8d, + 0x98, 0x7c, 0x6e, 0xe2, 0xb1, 0x88, 0xb4, 0x62, 0x39, 0x7c, 0x4c, 0x29, 0xf7, 0x28, 0x00, 0x05, + 0xcf, 0x90, 0x9e, 0x88, 0x56, 0xf6, 0x04, 0x29, 0x2e, 0xd8, 0x82, 0xfd, 0xf0, 0x57, 0x1c, 0xf2, + 0x91, 0x11, 0xce, 0xc6, 0xee, 0x50, 0xc0, 0x4e, 0x92, 0x00, 0xb9, 0x7e, 0x8a, 0xdc, 0x4c, 0x29, + 0x06, 0xa6, 0xb0, 0x35, 0xfa, 0xc4, 0x1b, 0x48, 0x13, 0xdf, 0x5b, 0xe3, 0xe3, 0x46, 0x7b, 0xf4, + 0xf2, 0x2a, 0x32, 0x5d, 0x1b, 0x2f, 0x82, 0xc9, 0x98, 0x53, 0x31, 0x99, 0x89, 0xd9, 0x6c, 0x68, + 0xcb, 0xa3, 0x3c, 0xe3, 0x7d, 0xea, 0xef, 0xc4, 0x02, 0xde, 0x5e, 0xb7, 0x7b, 0xf7, 0x89, 0x1c, + 0x59, 0x1e, 0x34, 0x5d, 0xe3, 0xae, 0x82, 0x4b, 0x41, 0x9d, 0x8e, 0x24, 0x9f, 0x22, 0xe6, 0xa7, + 0x10, 0x3b, 0xa8, 0xd9, 0xb4, 0x69, 0x58, 0xd7, 0x47, 0xe3, 0x3d, 0x4b, 0x83, 0xc9, 0x8b, 0xec, + 0xf2, 0x57, 0x33, 0x1f, 0x10, 0x09, 0x2a, 0x2e, 0x27, 0x87, 0xf1, 0xbc, 0x41, 0x27, 0x11, 0x44, + 0xdb, 0x2f, 0x05, 0x5a, 0x12, 0x36, 0x21, 0x25, 0x8d, 0x91, 0x9d, 0x4b, 0x4c, 0xe4, 0x82, 0x8e, + 0x58, 0xa2, 0x4a, 0xb1, 0x32, 0x63, 0xc5, 0x49, 0xd9, 0x5c, 0x0c, 0x1f, 0x27, 0x7b, 0xf8, 0x4c, + 0xc7, 0x31, 0x35, 0xcd, 0xb2, 0x93, 0xa2, 0xf0, 0x9d, 0x37, 0x28, 0x20, 0x0f, 0x74, 0xaf, 0xbd, + 0x4d, 0x93, 0xe1, 0xeb, 0x06, 0x7c, 0xce, 0x1c, 0x44, 0x75, 0x8e, 0x6a, 0x33, 0xd5, 0x7e, 0x46, + 0x4d, 0x00, 0x53, 0x02, 0x11, 0x90, 0x0e, 0xd3, 0x4e, 0x2a, 0xd1, 0x3f, 0x88, 0x0e, 0xf5, 0x7d, + 0x1d, 0x45, 0x59, 0xd0, 0x50, 0x35, 0x8d, 0x06, 0x7c, 0xee, 0x5e, 0x14, 0xdd, 0xb8, 0xbe, 0x23, + 0xaf, 0x5f, 0x5d, 0x44, 0x75, 0xef, 0x82, 0x01, 0x11, 0x03, 0xc4, 0x3c, 0xaa, 0xd7, 0x83, 0xfe, + 0x33, 0x71, 0x26, 0x98, 0xab, 0xaf, 0x25, 0x4b, 0xdb, 0xff, 0xc1, 0x51, 0xd7, 0x88, 0xf5, 0xb7, + 0x2e, 0x56, 0x69, 0x19, 0x44, 0x8b, 0xab, 0xfc, 0xd5, 0x54, 0x7f, 0x56, 0x7c, 0x11, 0x66, 0xf6, + 0xe3, 0x7c, 0x60, 0x8c, 0xe4, 0x40, 0x62, 0x51, 0x01, 0x72, 0x2c, 0x72, 0x51, 0xa6, 0x49, 0xdb, + 0xdf, 0xf4, 0x2f, 0x14, 0x3d, 0xdd, 0xe8, 0x9d, 0x97, 0xc1, 0x0d, 0x77, 0x77, 0x89, 0x57, 0x71, + 0x02, 0x41, 0x4f, 0x63, 0x55, 0xbc, 0xea, 0x15, 0xf7, 0xf1, 0x20, 0x87, 0x9a, 0x81, 0xc5, 0x5a, + 0xfb, 0xc4, 0xaf, 0x7c, 0x16, 0x90, 0x6a, 0xe7, 0x2a, 0xca, 0x44, 0x88, 0x1f, 0x7c, 0x14, 0xcc, + 0xc5, 0x19, 0xf6, 0x0b, 0xe6, 0x55, 0x55, 0x47, 0x03, 0x40, 0xca, 0x3f, 0xe1, 0x42, 0xd4, 0xa2, + 0x07, 0x8e, 0x0d, 0x03, 0x62, 0x84, 0xc2, 0x06, 0x3d, 0x44, 0x37, 0x31, 0x2a, 0xd2, 0x4f, 0xa8, + 0x6a, 0xdd, 0xf0, 0x4f, 0x3b, 0x07, 0x5e, 0xee, 0x55, 0x02, 0xbb, 0xef, 0x82, 0xc2, 0x8f, 0x3a, + 0x22, 0xc7, 0x8b, 0x17, 0x61, 0xb4, 0xd8, 0xa3, 0x2d, 0xb9, 0x48, 0x2f, 0xf0, 0xa4, 0xba, 0x1d, + 0xf4, 0x3d, 0x53, 0xc1, 0x6a, 0x0a, 0x13, 0xb0, 0xfc, 0x42, 0xa0, 0xb6, 0xfc, 0xa3, 0xa0, 0x1d, + 0x58, 0xf1, 0x02, 0x34, 0x4f, 0xb4, 0x8e, 0x91, 0xe1, 0xe0, 0x9b, 0x6c, 0x6d, 0x06, 0x5c, 0x62, + 0xc6, 0x2c, 0x62, 0xc7, 0x97, 0x88, 0x1f, 0x95, 0x41, 0xff, 0x9e, 0xae, 0xf1, 0xf6, 0x6e, 0xce, + 0x24, 0x64, 0xcc, 0xbb, 0xa9, 0x2d, 0x5b, 0xa0, 0xa3, 0x68, 0x44, 0xe4, 0x57, 0x4b, 0x99, 0xb1, + 0x4a, 0x03, 0xd8, 0x34, 0x82, 0xa6, 0xf2, 0x05, 0x33, 0xf1, 0x1a, 0xc7, 0xc4, 0x3a, 0xb2, 0xfa, + 0x2f, 0x7f, 0x35, 0xdb, 0xb7, 0xc4, 0x84, 0x48, 0xee, 0xe8, 0x6a, 0xac, 0x1b, 0x07, 0x8e, 0xb5, + 0x9c, 0x4c, 0x7d, 0xd1, 0xa0, 0x77, 0x19, 0x36, 0xf7, 0x22, 0xd3, 0xa1, 0x9c, 0x83, 0x41, 0xdf, + 0x11, 0x05, 0x94, 0x04, 0xc6, 0xc9, 0x2a, 0xdc, 0xf4, 0x51, 0x61, 0xb4, 0xa3, 0xe5, 0x5e, 0xed, + 0xbf, 0xe6, 0x35, 0xef, 0xea, 0xf5, 0xc1, 0x08, 0x9a, 0x73, 0xf7, 0xf8, 0x29, 0x23, 0x6a, 0x3a, + 0x70, 0xed, 0x2a, 0xab, 0x2c, 0xa9, 0x48, 0x5a, 0x48, 0x7f, 0x8c, 0x93, 0x04, 0x42, 0x00, 0xf5, + 0xd7, 0x9b, 0x2f, 0x77, 0xf1, 0xa6, 0xd3, 0xd5, 0x36, 0xdd, 0xa4, 0xa4, 0x05, 0x28, 0xa7, 0xd0, + 0xee, 0xe1, 0xcc, 0x57, 0x34, 0x25, 0x6b, 0x34, 0xe4, 0x0a, 0x99, 0x1e, 0x8f, 0xff, 0x47, 0x8b, + 0xeb, 0x9c, 0xbe, 0x0a, 0x29, 0x24, 0xd3, 0x45, 0xfb, 0xd7, 0xd1, 0x22, 0x9f, 0x82, 0x42, 0xde, + 0x9b, 0x5f, 0x24, 0xcf, 0xd0, 0xfc, 0xf5, 0x69, 0xa4, 0x92, 0xf5, 0xc3, 0x96, 0x32, 0xb0, 0xc7, + 0x07, 0x89, 0x35, 0x51, 0x12, 0x34, 0x7f, 0xe0, 0xa4, 0x53, 0x6d, 0x83, 0x8a, 0xad, 0x54, 0xe5, + 0x6d, 0xfa, 0x1c, 0x63, 0xcc, 0xf7, 0xc5, 0x15, 0x55, 0x54, 0xdc, 0xee, 0x2c, 0xf1, 0x2e, 0xef, + 0xf8, 0x48, 0xef, 0x7d, 0x0e, 0xbe, 0x0a, 0x04, 0x2e, 0x6c, 0x39, 0x94, 0x1d, 0x9f, 0x1d, 0xf7, + 0xc4, 0xa1, 0x80, 0xb1, 0xf9, 0x04, 0xbb, 0xbb, 0xf1, 0x00, 0xa6, 0xee, 0xee, 0x44, 0x88, 0x04, + 0xf4, 0x3b, 0x03, 0x38, 0x80, 0xbd, 0xef, 0xe2, 0x01, 0x51, 0xd9, 0x05, 0x16, 0x4e, 0x8d, 0xaa, + 0x2b, 0x8c, 0x30, 0x72, 0xa9, 0xfa, 0x2b, 0xb6, 0xfd, 0x12, 0x7f, 0x8c, 0x22, 0x8d, 0x3d, 0xc1, + 0x06, 0x3d, 0x7a, 0x96, 0x8b, 0x75, 0x63, 0x43, 0x63, 0x43, 0x5c, 0xd7, 0x77, 0x7f, 0x12, 0x5a, + 0x6d, 0xcb, 0xdf, 0xf8, 0x93, 0x4a, 0xe9, 0xba, 0x68, 0x7e, 0x14, 0x3b, 0x4c, 0xcd, 0xcb, 0xe3, + 0x89, 0xb8, 0xa8, 0xc3, 0xc8, 0x4b, 0x87, 0x8c, 0x3c, 0xc7, 0x5e, 0xc0, 0x71, 0xa1, 0xd7, 0xc8, + 0x66, 0xcd, 0xcf, 0xd5, 0x20, 0xe2, 0x14, 0xe8, 0x6a, 0xb8, 0x90, 0x49, 0x55, 0x17, 0x58, 0xae, + 0x26, 0x30, 0x5a, 0x14, 0x8a, 0x2c, 0x65, 0x62, 0x21, 0x19, 0xa2, 0x63, 0x1b, 0x65, 0xd4, 0xb4, + 0x96, 0x8a, 0xb0, 0x76, 0x53, 0xe4, 0x11, 0x05, 0x3f, 0x45, 0xfc, 0x48, 0x44, 0x97, 0xbf, 0x11, + 0x19, 0xd2, 0x39, 0x06, 0x22, 0x1e, 0xc7, 0x1a, 0xbd, 0xf8, 0xdf, 0xe0, 0xa0, 0x42, 0x34, 0xa9, + 0x1e, 0xbb, 0x15, 0xf5, 0x74, 0x52, 0xa7, 0xc4, 0x63, 0x34, 0x7a, 0xad, 0xd8, 0x9f, 0xcc, 0x47, + 0x7f, 0xc2, 0x05, 0x76, 0x13, 0x57, 0x49, 0xed, 0x9e, 0x0f, 0x4b, 0xcc, 0x5a, 0x27, 0xf9, 0xb7, + 0xaf, 0x10, 0x5b, 0xb0, 0x6d, 0x7d, 0x18, 0x8d, 0xf0, 0x5b, 0xb3, 0x49, 0xc8, 0x20, 0x4e, 0xf6, + 0xe3, 0xc3, 0xe7, 0x12, 0xad, 0xa6, 0x9b, 0x7f, 0xe6, 0xdd, 0xdf, 0xd1, 0x25, 0x7d, 0x6b, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x14, 0x0a, 0x30, 0x36, 0x8b, 0xd0, 0x94, 0x8b, 0xd5, 0xd3, 0x62, + 0x4c, 0x37, 0x19, 0x4c, 0x63, 0xa2, 0x60, 0x8c, 0x66, 0x35, 0x1a, 0x90, 0x72, 0x9f, 0x88, 0xa1, + 0x2f, 0x3f, 0x17, 0x21, 0x21, 0x96, 0x8f, 0x71, 0x94, 0xc6, 0x18, 0xe8, 0x66, 0x53, 0xf4, 0x34, + 0xc9, 0x17, 0xd5, 0x2a, 0x71, 0x30, 0xb8, 0xe4, 0x20, 0x40, 0xb5, 0xda, 0x94, 0x3c, 0x2e, 0x3d, + 0x75, 0x3b, 0x01, 0xd8, 0xe9, 0xdc, 0x8c, 0x7e, 0x22, 0x30, 0x46, 0x6e, 0x7b, 0x8e, 0xf4, 0x9b, + 0xb9, 0xe0, 0x59, 0x89, 0x30, 0x92, 0xf6, 0x73, 0x9e, 0xce, 0x73, 0xfc, 0xa3, 0xc7, 0xe9, 0x58, + 0xb0, 0x2b, 0x11, 0x06, 0x1f, 0xe2, 0x2a, 0xa2, 0xe2, 0xf6, 0x6c, 0x4e, 0x5e, 0xa9, 0xd8, 0x42, + 0x24, 0x40, 0x24, 0xbb, 0x5f, 0x1f, 0xe1, 0x00, 0xa0, 0x42, 0x2e, 0xe2, 0x4f, 0xd4, 0x1f, 0x7b, + 0x07, 0x7e, 0xce, 0xd9, 0x7d, 0x09, 0xed, 0x3f, 0xc4, 0xcb, 0x71, 0xf0, 0x84, 0x3f, 0xe2, 0x8d, + 0xc5, 0x18, 0x5f, 0xa0, 0xa8, 0x7f, 0x6f, 0xa9, 0x53, 0xea, 0x23, 0x83, 0xea, 0x80, 0xbf, 0x5c, + 0xab, 0xa2, 0x23, 0xbf, 0x45, 0xe3, 0xb2, 0x72, 0xe9, 0xd3, 0xf5, 0x2a, 0x57, 0x11, 0xa4, 0x80, + 0x69, 0xaa, 0x3f, 0xd0, 0xc6, 0x22, 0xf8, 0x2c, 0x1a, 0x9b, 0x5d, 0xbb, 0xb0, 0x75, 0x39, 0xfe, + 0xfa, 0x29, 0x98, 0xb6, 0xa2, 0x61, 0x72, 0x70, 0x4b, 0xe0, 0xea, 0x96, 0x78, 0x21, 0x8c, 0x73, + 0xba, 0x25, 0xa2, 0x75, 0xf0, 0xa0, 0x51, 0xb4, 0xf9, 0x62, 0x55, 0x1e, 0xc4, 0xe5, 0xf1, 0x79, + 0x48, 0xd9, 0x2f, 0xe2, 0x02, 0x94, 0xc7, 0x45, 0x42, 0x68, 0xbc, 0x60, 0xc7, 0xbc, 0x65, 0xb4, + 0xdd, 0xdb, 0x3f, 0xfb, 0xe8, 0x2e, 0x74, 0x50, 0xf2, 0x52, 0x4b, 0xf5, 0x2a, 0x3a, 0x7d, 0x5f, + 0xe0, 0xb8, 0x55, 0xee, 0x1b, 0x6b, 0x56, 0xa6, 0x29, 0xf3, 0x1c, 0x3e, 0x0a, 0x05, 0x55, 0x55, + 0x55, 0x55, 0x86, 0x26, 0x09, 0xac, 0xe2, 0xb7, 0x77, 0x77, 0xbf, 0xc1, 0x54, 0xf6, 0xd7, 0x2f, + 0x4d, 0xbc, 0x65, 0x4b, 0x67, 0x30, 0xa0, 0x39, 0x7c, 0x10, 0x84, 0xc1, 0x92, 0x56, 0x20, 0x28, + 0x26, 0xac, 0xd8, 0xa5, 0xe8, 0xa7, 0x48, 0x8e, 0xcd, 0xa4, 0x97, 0x88, 0xb4, 0xd6, 0xd6, 0xda, + 0xe0, 0x92, 0xd5, 0xab, 0x22, 0xfa, 0x15, 0x2f, 0x84, 0x45, 0xed, 0x35, 0x43, 0xbe, 0xd3, 0x5e, + 0x13, 0x2e, 0x92, 0x5a, 0x49, 0x1f, 0xa9, 0xef, 0x87, 0x48, 0x32, 0x67, 0xd1, 0xdb, 0xce, 0xb8, + 0xda, 0x77, 0x96, 0xcc, 0xb6, 0xe7, 0x33, 0x3f, 0xe1, 0xdf, 0x3c, 0x8f, 0x8f, 0xce, 0x3b, 0x86, + 0xfe, 0x3c, 0xad, 0xa4, 0xdb, 0x7f, 0xe1, 0x53, 0xe3, 0xbe, 0x5b, 0xed, 0x6f, 0x96, 0xf8, 0xa8, + 0x74, 0xf9, 0x0d, 0x10, 0xd1, 0x35, 0x9b, 0xe1, 0x5c, 0xf8, 0xa9, 0xa1, 0x53, 0x46, 0xa9, 0xa1, + 0x53, 0x42, 0x75, 0xe7, 0xd3, 0xef, 0xe2, 0x41, 0x4c, 0x34, 0x9f, 0x45, 0x3c, 0x4d, 0x0a, 0x9a, + 0x27, 0x24, 0xa9, 0xa1, 0x53, 0x46, 0xb5, 0xa3, 0xd3, 0x87, 0x85, 0x02, 0xc3, 0x68, 0x1a, 0x53, + 0x24, 0x0f, 0xb1, 0x9d, 0xec, 0xa6, 0x2f, 0x34, 0x63, 0xb0, 0x5f, 0xdf, 0x19, 0x1c, 0xe4, 0x08, + 0x8b, 0xf4, 0x40, 0x84, 0x11, 0x69, 0x99, 0x4e, 0xc5, 0x5e, 0x8a, 0x9a, 0x43, 0x83, 0x89, 0xe7, + 0xb8, 0x32, 0xa9, 0xf3, 0x85, 0x71, 0x1f, 0x8e, 0xdd, 0xb9, 0xef, 0x89, 0x22, 0x06, 0x81, 0x9b, + 0x17, 0x2b, 0x55, 0x5b, 0xf0, 0x40, 0x6a, 0xa3, 0xe8, 0x19, 0x61, 0x1e, 0x14, 0xa1, 0x56, 0x44, + 0x65, 0xa0, 0x5e, 0x87, 0x99, 0x3c, 0xe3, 0x0e, 0x91, 0xb7, 0xc6, 0x88, 0x2f, 0xf7, 0x2e, 0x5a, + 0x44, 0x91, 0x42, 0xc2, 0x94, 0x9c, 0x98, 0x96, 0xa0, 0xf9, 0x40, 0xff, 0x2f, 0x06, 0xca, 0x6c, + 0xc5, 0xb4, 0xff, 0xc2, 0x84, 0x15, 0xc7, 0x99, 0x17, 0xc9, 0xfc, 0x14, 0xe5, 0xc9, 0xb0, 0x59, + 0x96, 0x62, 0x63, 0x04, 0x29, 0xb1, 0x2c, 0x20, 0xc4, 0xff, 0x1e, 0x56, 0xa0, 0xf6, 0x65, 0xa6, + 0xf0, 0xc2, 0xe5, 0xef, 0xec, 0x37, 0xef, 0x85, 0x08, 0x16, 0x26, 0x53, 0x3e, 0x09, 0xf7, 0x03, + 0x1a, 0xf6, 0x04, 0x55, 0x0c, 0x70, 0x00, 0x8c, 0xc7, 0x71, 0x60, 0x04, 0xd4, 0x91, 0xc3, 0x91, + 0xb7, 0x23, 0x17, 0xc1, 0x4c, 0x0f, 0x46, 0xa3, 0x1c, 0x35, 0x0f, 0x01, 0xbd, 0x83, 0x77, 0x5f, + 0xb7, 0x37, 0x5d, 0x95, 0xfd, 0xfb, 0xe8, 0x2e, 0x3b, 0x18, 0xaf, 0x52, 0x22, 0x25, 0xc4, 0xcf, + 0x43, 0xd3, 0x3d, 0x0f, 0x4c, 0xdc, 0x22, 0x46, 0x9a, 0xda, 0x6b, 0x69, 0xaf, 0xd7, 0x95, 0x78, + 0xce, 0x92, 0x5a, 0x49, 0x34, 0xd6, 0xd3, 0x5b, 0xe2, 0x2d, 0x34, 0xc1, 0xda, 0x6b, 0x5d, 0x7e, + 0x88, 0xe0, 0xbe, 0xd5, 0xa6, 0xa9, 0xd3, 0x47, 0x4f, 0xa6, 0x9a, 0x69, 0xae, 0x0a, 0xad, 0xdb, + 0xb7, 0x6f, 0x6d, 0xb9, 0x13, 0xeb, 0x87, 0xd0, 0xae, 0xbe, 0x30, 0x5e, 0xd3, 0x5b, 0x4d, 0x6d, + 0x35, 0xb4, 0xd7, 0x84, 0x2d, 0x35, 0xb4, 0xd6, 0xd3, 0x5f, 0x8b, 0xb4, 0xd6, 0xd3, 0x5f, 0x8e, + 0xe9, 0x25, 0xa4, 0x91, 0xb1, 0xd8, 0x7c, 0x7e, 0x2e, 0xa6, 0x2f, 0x87, 0xad, 0x54, 0x92, 0x5a, + 0x49, 0x34, 0xd7, 0xd6, 0xdb, 0x6d, 0xbf, 0xf0, 0x41, 0xd2, 0x26, 0x2a, 0x06, 0xdc, 0x98, 0xcc, + 0x4b, 0xd8, 0x26, 0x6d, 0x61, 0x40, 0xfd, 0xf3, 0x95, 0x3a, 0xf3, 0xf6, 0xff, 0x1a, 0x39, 0xb8, + 0xcd, 0xe2, 0x79, 0x04, 0x76, 0x4a, 0x03, 0x57, 0xcb, 0x5a, 0x69, 0x1a, 0x81, 0x97, 0x4e, 0xc1, + 0x80, 0xa5, 0x09, 0xe8, 0x88, 0xb4, 0xbf, 0xc2, 0x82, 0x0d, 0x1e, 0x64, 0xb8, 0x0b, 0x55, 0x4b, + 0x41, 0xc1, 0x1f, 0x08, 0x34, 0x01, 0xc0, 0x31, 0x9a, 0x21, 0x6e, 0x9c, 0xd0, 0x89, 0x41, 0x3e, + 0x48, 0x61, 0x0b, 0xbe, 0xc1, 0xe7, 0xdb, 0xff, 0x78, 0x80, 0x4c, 0x2d, 0x0f, 0x46, 0x6b, 0x80, + 0x99, 0x36, 0x16, 0x80, 0xc6, 0x40, 0x16, 0x9e, 0x08, 0x45, 0xb0, 0x8d, 0x99, 0xd2, 0xb8, 0xd3, + 0x0c, 0x7a, 0x1e, 0x6c, 0x90, 0xd4, 0x34, 0xec, 0x0c, 0x7a, 0x5d, 0x99, 0x78, 0xee, 0xc0, 0x45, + 0x9c, 0x53, 0xe4, 0x61, 0x2a, 0x74, 0xc2, 0xdb, 0xbf, 0xc4, 0x85, 0x02, 0x16, 0xea, 0x73, 0xe3, + 0x13, 0x9e, 0x2b, 0x38, 0x71, 0x01, 0x8e, 0xdc, 0x8c, 0xb6, 0x70, 0xd0, 0xb1, 0x96, 0x31, 0x23, + 0x90, 0x2f, 0x13, 0x1d, 0x3d, 0x81, 0x60, 0xcb, 0x06, 0x16, 0x78, 0xb6, 0x86, 0xfa, 0x62, 0x15, + 0x1f, 0xf0, 0xa0, 0xf3, 0xcd, 0x16, 0x5d, 0x37, 0x14, 0x53, 0xee, 0xca, 0x62, 0xf6, 0xd3, 0x39, + 0x7d, 0x99, 0xbf, 0xc1, 0x60, 0xeb, 0x93, 0x49, 0x15, 0xdc, 0x2c, 0xe0, 0x16, 0xfc, 0xe0, 0x1d, + 0x1c, 0x02, 0x21, 0x08, 0x2f, 0xcd, 0xc3, 0xfc, 0x14, 0xc3, 0x80, 0xf5, 0x90, 0x1a, 0x8b, 0x00, + 0x91, 0xcb, 0xee, 0x5f, 0x4a, 0xee, 0xbd, 0x7d, 0xff, 0xcc, 0x3c, 0x2a, 0x17, 0x3d, 0x50, 0x36, + 0xa8, 0x19, 0xa9, 0x2f, 0x23, 0x4d, 0x8d, 0x94, 0xcc, 0x0b, 0xfc, 0x13, 0xed, 0x52, 0xb5, 0x48, + 0xe8, 0x77, 0xe1, 0x9a, 0x49, 0x7c, 0x14, 0xaf, 0x6e, 0x99, 0x22, 0xba, 0xb8, 0x37, 0x44, 0xaf, + 0xac, 0x53, 0x75, 0xa9, 0xfa, 0xc5, 0x7c, 0x11, 0x5c, 0xdc, 0xfd, 0xdc, 0x8a, 0x1e, 0xad, 0x27, + 0x58, 0xa5, 0xe0, 0xc3, 0x8f, 0x55, 0x93, 0xb6, 0xc4, 0x30, 0x82, 0x55, 0x52, 0x79, 0xff, 0x04, + 0xbe, 0x7c, 0x97, 0x34, 0xab, 0xc1, 0x55, 0xb8, 0x5c, 0xdb, 0x85, 0xcf, 0x21, 0x22, 0x12, 0x4a, + 0xbc, 0xf1, 0xe5, 0x4d, 0x34, 0xd3, 0xff, 0x58, 0xbe, 0x0b, 0x24, 0xa7, 0x2d, 0x25, 0xa1, 0x69, + 0x92, 0x98, 0xbc, 0x48, 0x78, 0x43, 0x11, 0xba, 0x79, 0x07, 0x31, 0xf1, 0xca, 0xe2, 0xcd, 0x86, + 0x6f, 0x35, 0x5d, 0x45, 0x0a, 0xb7, 0xea, 0xc1, 0x6d, 0x46, 0xa7, 0x5d, 0x16, 0x28, 0xfe, 0x77, + 0xc7, 0xf8, 0x40, 0x28, 0x33, 0xa0, 0xdd, 0x99, 0x98, 0x2f, 0x41, 0x08, 0xc0, 0xe3, 0xcd, 0x92, + 0x75, 0x87, 0x2e, 0xcd, 0xbd, 0x9f, 0x1a, 0x53, 0x6b, 0x7e, 0x63, 0x78, 0x58, 0xb7, 0xa4, 0x27, + 0x68, 0x33, 0x4d, 0x8f, 0xac, 0xd0, 0x20, 0x64, 0x47, 0x6d, 0x3b, 0x7d, 0xc3, 0xc5, 0x7f, 0xf2, + 0x84, 0xf4, 0x93, 0x58, 0x90, 0x58, 0x10, 0x99, 0x87, 0x1a, 0x67, 0xbb, 0x63, 0xc2, 0x0d, 0xe0, + 0x69, 0x88, 0x11, 0x83, 0x98, 0xf8, 0xc3, 0x0d, 0xc0, 0x2c, 0xf1, 0x8a, 0xc6, 0xf2, 0xf6, 0xec, + 0xfb, 0x7b, 0xef, 0xe0, 0x94, 0x78, 0xf2, 0x61, 0x99, 0xe9, 0x3b, 0x8d, 0x53, 0xe2, 0xcd, 0x26, + 0xce, 0x90, 0xf8, 0x2b, 0xa6, 0x02, 0x17, 0x44, 0x18, 0x0e, 0xce, 0x24, 0x14, 0x88, 0x33, 0x04, + 0x37, 0x16, 0x41, 0x72, 0xb4, 0xa5, 0x42, 0xca, 0x93, 0xfe, 0xb2, 0xaf, 0xc8, 0xbd, 0x7c, 0xe1, + 0x77, 0x3e, 0xdc, 0x5b, 0x16, 0xfc, 0x37, 0xc9, 0xea, 0x2a, 0xc5, 0x5f, 0x6c, 0x5b, 0x4f, 0xc1, + 0x16, 0x95, 0xa3, 0xa2, 0xaf, 0x45, 0x4e, 0x82, 0xfd, 0x7b, 0xe8, 0x56, 0x15, 0xdd, 0x5d, 0x5d, + 0x74, 0x66, 0x1e, 0xbd, 0x37, 0x05, 0xc2, 0x72, 0x90, 0xac, 0xf9, 0xa4, 0x0f, 0x05, 0x12, 0x50, + 0x94, 0xc9, 0x42, 0x53, 0x4a, 0xbd, 0x52, 0xaf, 0x04, 0x5c, 0xc4, 0x13, 0x10, 0x7b, 0xe0, 0xb7, + 0x25, 0x39, 0x29, 0xf7, 0xd4, 0xcb, 0xf8, 0x7a, 0x7c, 0xdc, 0x62, 0x81, 0xc2, 0xb2, 0x85, 0xe0, + 0xe6, 0x69, 0x47, 0x0f, 0x3a, 0x8e, 0x2a, 0xca, 0x08, 0x03, 0xa0, 0xa0, 0x71, 0x2c, 0x22, 0x05, + 0x87, 0x0b, 0x6e, 0x1d, 0x83, 0xec, 0x70, 0x80, 0xc0, 0x93, 0xd8, 0xd6, 0x05, 0xd8, 0x0e, 0x25, + 0x18, 0x22, 0x69, 0x28, 0x36, 0x82, 0xcf, 0x82, 0x00, 0x98, 0xf1, 0xba, 0x8c, 0xc8, 0x0e, 0x3c, + 0xb3, 0x4d, 0x7c, 0x89, 0xc8, 0x42, 0x43, 0x6e, 0x08, 0xae, 0xee, 0x5e, 0x23, 0xff, 0xdb, 0xbb, + 0xc4, 0xbd, 0x7d, 0x10, 0x0a, 0xcd, 0xe0, 0x7f, 0xc7, 0x63, 0x6b, 0xd6, 0xb5, 0xc3, 0x81, 0x1c, + 0x7a, 0xab, 0x5d, 0x4d, 0x2f, 0xf0, 0xa0, 0x42, 0xb2, 0xc1, 0xcb, 0x76, 0xe6, 0x22, 0xf5, 0x16, + 0x72, 0x41, 0x6f, 0x7f, 0x7e, 0x69, 0xfc, 0x40, 0xb1, 0x3c, 0xcd, 0x6e, 0xdc, 0xf9, 0x88, 0x86, + 0xe1, 0x56, 0x20, 0xda, 0xee, 0xf3, 0xc1, 0x49, 0xb4, 0xca, 0x41, 0x0f, 0x35, 0x2b, 0x82, 0xeb, + 0x12, 0x88, 0x50, 0x1d, 0x20, 0xe2, 0xf3, 0x11, 0x8e, 0x35, 0xb7, 0x17, 0xf7, 0x89, 0x04, 0x21, + 0x5c, 0x80, 0x3a, 0xd9, 0x71, 0xdf, 0x5d, 0x1c, 0xeb, 0x85, 0x39, 0xcc, 0x8e, 0xfd, 0x55, 0x55, + 0x75, 0x2a, 0xcb, 0xe8, 0xcf, 0xf4, 0x54, 0x78, 0x27, 0x0b, 0x1e, 0x7f, 0x3e, 0x93, 0xf9, 0x7f, + 0xd3, 0xa4, 0xe4, 0xe8, 0x8e, 0x5f, 0x24, 0xf9, 0x36, 0x1b, 0x17, 0x2c, 0xf8, 0x7c, 0xd7, 0x24, + 0xf8, 0x7c, 0x9b, 0x14, 0x48, 0x80, 0xbc, 0xa4, 0x95, 0x81, 0x40, 0x65, 0x26, 0x20, 0x21, 0x2b, + 0x39, 0x04, 0x31, 0xd3, 0x05, 0x59, 0x0c, 0x79, 0x47, 0x0f, 0x75, 0x4b, 0xf8, 0x91, 0x81, 0x2d, + 0x4b, 0x25, 0xa1, 0x59, 0xff, 0xcb, 0x04, 0xd9, 0xdb, 0xf3, 0xa9, 0xc3, 0xd5, 0xa3, 0xbe, 0x67, + 0xc2, 0x01, 0x4b, 0x46, 0x0b, 0xad, 0x42, 0x4a, 0xb5, 0x0e, 0xf7, 0x3b, 0x57, 0x1e, 0x90, 0xaf, + 0x28, 0x93, 0xb9, 0x5c, 0x16, 0x1e, 0x03, 0xc2, 0xcb, 0x86, 0x1f, 0x65, 0xb1, 0xe4, 0xbe, 0x52, + 0xfe, 0xf8, 0x93, 0x04, 0xca, 0xa1, 0xc5, 0x5f, 0x30, 0x2f, 0x2f, 0x11, 0xc1, 0x78, 0x3f, 0x19, + 0x7b, 0x7d, 0xbb, 0xef, 0x2e, 0x40, 0xbe, 0xd2, 0x04, 0xfb, 0x05, 0x3f, 0x06, 0xf2, 0x31, 0x02, + 0x41, 0x4c, 0xd8, 0x12, 0xdc, 0x08, 0x03, 0x77, 0xcc, 0x84, 0xa6, 0xc4, 0x85, 0x86, 0x9b, 0xa1, + 0xfc, 0xde, 0xb1, 0xc8, 0xdf, 0xb9, 0xc6, 0xd2, 0x82, 0xe1, 0x80, 0xbe, 0xdb, 0x5b, 0x4d, 0x11, + 0x2d, 0x8a, 0xbf, 0xfc, 0xb6, 0x9a, 0xfc, 0x37, 0x40, 0xda, 0x9b, 0x9d, 0x17, 0xf5, 0x4d, 0x49, + 0xd1, 0x2a, 0xba, 0x34, 0x1f, 0x59, 0x47, 0xf4, 0x25, 0x25, 0xf5, 0x6b, 0xea, 0x99, 0x93, 0x92, + 0xea, 0xef, 0xe8, 0xcc, 0x97, 0xa1, 0x25, 0x49, 0x22, 0x60, 0xb0, 0x65, 0x83, 0x91, 0xb3, 0x06, + 0x03, 0x0f, 0x5d, 0x48, 0xe4, 0x76, 0xfb, 0xca, 0x25, 0xc7, 0x78, 0x88, 0xc2, 0x37, 0x54, 0xb9, + 0x02, 0x00, 0xf2, 0x15, 0x8b, 0x81, 0x98, 0x02, 0xad, 0x6c, 0x56, 0x10, 0x49, 0x44, 0x5e, 0x4c, + 0xf0, 0xa5, 0x22, 0x68, 0xc8, 0x2e, 0xca, 0x38, 0x62, 0x10, 0x6f, 0xea, 0x04, 0xc2, 0x23, 0x05, + 0xc3, 0xa0, 0x83, 0x80, 0xa1, 0x96, 0x88, 0xd3, 0x84, 0xb8, 0x1c, 0x0e, 0xfd, 0x33, 0xf1, 0xc6, + 0x33, 0xb7, 0x98, 0xb1, 0x37, 0x87, 0x08, 0x81, 0x4d, 0x5b, 0xa6, 0xa2, 0xf0, 0x04, 0x38, 0x34, + 0x3e, 0x58, 0xfe, 0x2e, 0xdb, 0x6d, 0xd5, 0x7f, 0x05, 0x59, 0x98, 0x7a, 0xdd, 0xe6, 0x45, 0xea, + 0xbf, 0x1f, 0x16, 0x51, 0x7b, 0x08, 0x9a, 0x2b, 0x15, 0xd8, 0x1e, 0x83, 0x5f, 0x1c, 0x67, 0x5b, + 0x81, 0xdc, 0x1e, 0x22, 0x03, 0x41, 0x30, 0xf2, 0x6f, 0x2c, 0xe7, 0x1c, 0x98, 0x4c, 0x3f, 0x51, + 0xad, 0x2f, 0xd0, 0x67, 0xbe, 0x09, 0x65, 0x2e, 0x96, 0x91, 0x09, 0x71, 0x2a, 0xf0, 0xae, 0x24, + 0xb4, 0x92, 0xe2, 0x54, 0xdb, 0x69, 0xa7, 0xeb, 0x85, 0xf4, 0xad, 0x52, 0xb5, 0xd6, 0xdb, 0x4d, + 0xfd, 0x72, 0x8a, 0x49, 0x26, 0x9a, 0xf5, 0xaf, 0x9e, 0x7a, 0xe7, 0x87, 0xeb, 0xa3, 0xba, 0x3f, + 0xa3, 0xb1, 0x7d, 0x11, 0xc8, 0x9e, 0x89, 0x33, 0xe8, 0xe7, 0x4b, 0xea, 0x74, 0x93, 0x12, 0x09, + 0xcc, 0xc7, 0x2e, 0x17, 0x91, 0x11, 0xa3, 0xb9, 0x00, 0xd7, 0x4e, 0x5e, 0xad, 0x0f, 0xf1, 0x82, + 0xb8, 0xc1, 0xfc, 0x10, 0xe8, 0x41, 0x1c, 0x08, 0x5a, 0xdf, 0x54, 0x89, 0x99, 0xd3, 0x54, 0x70, + 0x30, 0xc2, 0x47, 0x11, 0x41, 0xf8, 0x50, 0xb0, 0x13, 0xd0, 0x87, 0xd5, 0x7c, 0xe8, 0x60, 0x32, + 0xc8, 0x95, 0xf4, 0x14, 0x74, 0x10, 0x8c, 0x0b, 0x40, 0x94, 0xe4, 0x7c, 0xa1, 0xe1, 0x4e, 0x62, + 0xa7, 0x04, 0x0b, 0xec, 0xb7, 0x02, 0x35, 0x5d, 0x4c, 0xbd, 0x34, 0x60, 0xf4, 0x66, 0xc1, 0xc3, + 0xb1, 0x47, 0x1b, 0xee, 0x2f, 0x74, 0xb4, 0x72, 0x03, 0x8e, 0x71, 0x30, 0x52, 0x67, 0x0d, 0x8c, + 0xab, 0xbb, 0x15, 0x9f, 0xf6, 0x3e, 0xaf, 0xf7, 0xc2, 0x82, 0x4e, 0x84, 0xea, 0xcd, 0xb0, 0x19, + 0xe6, 0x6f, 0x5c, 0x43, 0xde, 0x6a, 0x38, 0x75, 0x69, 0x9f, 0x39, 0x32, 0xc4, 0xc2, 0x84, 0xbb, + 0xd0, 0x6f, 0x77, 0xbc, 0xb9, 0xb4, 0x72, 0x0f, 0x7c, 0x60, 0xa2, 0x31, 0x1e, 0xee, 0xfe, 0x15, + 0x69, 0x89, 0x70, 0xb7, 0x89, 0x60, 0xd6, 0x2f, 0x10, 0x17, 0xc4, 0x09, 0xfa, 0x0b, 0x9d, 0x3e, + 0xbd, 0xf5, 0x22, 0x49, 0xd6, 0x2f, 0xae, 0x53, 0xf5, 0xef, 0xab, 0xc2, 0xdd, 0x62, 0x93, 0xa2, + 0x15, 0x3e, 0xa7, 0x4b, 0xc4, 0x98, 0x43, 0x18, 0x8b, 0x11, 0xac, 0x71, 0x23, 0x0c, 0xee, 0x3b, + 0x48, 0x42, 0x56, 0x0e, 0x07, 0x9e, 0xa4, 0x2d, 0xb4, 0xed, 0x97, 0x87, 0x8e, 0xb0, 0x90, 0x68, + 0x9d, 0x05, 0x06, 0x6b, 0xb6, 0x4c, 0x7f, 0x85, 0x2e, 0x7a, 0x41, 0x7b, 0x78, 0x63, 0x14, 0x02, + 0x1e, 0x0c, 0x78, 0x44, 0xce, 0x7e, 0xd3, 0x4e, 0x29, 0x63, 0x0c, 0x99, 0x41, 0x5f, 0xfe, 0x10, + 0xbe, 0xfe, 0x45, 0x0a, 0x7c, 0x82, 0x71, 0x31, 0x36, 0x2c, 0xf1, 0x31, 0x87, 0x3e, 0x4b, 0x17, + 0x74, 0xa5, 0xa7, 0x19, 0x6c, 0x80, 0xde, 0xd0, 0x3f, 0x82, 0xca, 0xa6, 0x38, 0xab, 0x50, 0x34, + 0x69, 0x99, 0x44, 0x6a, 0x32, 0xa1, 0xd9, 0x24, 0x74, 0xe2, 0x26, 0x2b, 0x53, 0xaf, 0xe2, 0x01, + 0x68, 0xa6, 0xd6, 0x24, 0xb1, 0x55, 0x57, 0xf1, 0x00, 0xa0, 0xa2, 0x3e, 0x16, 0x37, 0x29, 0x3b, + 0xbb, 0xd7, 0xd0, 0x44, 0xe9, 0x5d, 0x12, 0xaf, 0xac, 0x12, 0xf4, 0x71, 0xd5, 0xf4, 0x66, 0xbe, + 0xb5, 0x1b, 0xd5, 0xbe, 0x6b, 0x6d, 0x9f, 0xbb, 0x89, 0xea, 0x55, 0x95, 0xd1, 0x32, 0xbe, 0x8a, + 0x9d, 0x7a, 0x9e, 0xfa, 0x29, 0xd3, 0x89, 0x10, 0x0a, 0x87, 0x3b, 0xec, 0x67, 0x83, 0xe2, 0x05, + 0x84, 0xce, 0x07, 0xc1, 0xe1, 0xf4, 0xbf, 0x1a, 0x20, 0xbc, 0x3b, 0x05, 0x43, 0xfc, 0x60, 0xa2, + 0x4c, 0x74, 0x08, 0x42, 0x07, 0x7c, 0xa2, 0x23, 0x4b, 0x30, 0x60, 0x25, 0x99, 0x31, 0xac, 0xbc, + 0xf8, 0x60, 0x4c, 0x45, 0x8f, 0xda, 0x1c, 0x13, 0x8c, 0x19, 0x23, 0x33, 0xef, 0x61, 0x2e, 0x24, + 0xc5, 0x5d, 0x45, 0xd1, 0x70, 0xe3, 0x93, 0xbd, 0xb1, 0x57, 0xc3, 0xff, 0xfc, 0x29, 0x98, 0x86, + 0xfa, 0x98, 0x37, 0xca, 0xea, 0x99, 0x13, 0xf0, 0x4e, 0xa0, 0x51, 0x21, 0xe8, 0x5c, 0x2d, 0x56, + 0x62, 0x44, 0xa3, 0x85, 0xb0, 0x3f, 0x1e, 0xb0, 0x91, 0xf8, 0x54, 0xb2, 0x0a, 0xab, 0xb8, 0x6e, + 0x1f, 0x04, 0xbb, 0x49, 0xd1, 0xfa, 0xf1, 0x36, 0x05, 0x4a, 0x31, 0xda, 0x99, 0x6f, 0x12, 0x14, + 0x9d, 0xec, 0xc5, 0x85, 0x86, 0x36, 0x32, 0x2b, 0x8d, 0xf8, 0x6d, 0x17, 0xa9, 0x7e, 0xde, 0xdb, + 0xf1, 0x11, 0x92, 0xfa, 0xd2, 0x49, 0x27, 0x36, 0x4b, 0xec, 0x0c, 0x01, 0xed, 0xaf, 0xc0, 0x01, + 0x56, 0xc6, 0xc9, 0x10, 0x7f, 0xb7, 0xa3, 0xec, 0x3a, 0x48, 0x9d, 0xb7, 0x85, 0x0b, 0x77, 0x7d, + 0xdf, 0x78, 0x93, 0x1b, 0x86, 0x46, 0x6b, 0xc3, 0x9e, 0x3d, 0x20, 0xa7, 0xcb, 0x23, 0x9b, 0x6c, + 0xc2, 0x68, 0xf0, 0x52, 0x1e, 0x20, 0x28, 0x53, 0x0c, 0x4b, 0x06, 0xd2, 0x93, 0xa0, 0x23, 0x8a, + 0x74, 0xd2, 0x01, 0x58, 0xac, 0xee, 0x93, 0xd2, 0xe1, 0x66, 0xef, 0x29, 0xfe, 0x3b, 0x35, 0x35, + 0x08, 0xa4, 0xba, 0xd5, 0x15, 0xce, 0xab, 0xe1, 0x01, 0x0e, 0x48, 0xcf, 0x54, 0xdb, 0xae, 0x16, + 0xd3, 0x19, 0xd0, 0x55, 0xc9, 0xfa, 0xd5, 0x75, 0x31, 0xbe, 0xa9, 0x50, 0xde, 0x08, 0xc8, 0xb5, + 0xb1, 0xf5, 0x63, 0xeb, 0x23, 0xa4, 0xdd, 0x16, 0xaf, 0x82, 0x71, 0x90, 0x74, 0x4c, 0x41, 0xd1, + 0x30, 0x35, 0x82, 0x40, 0xaa, 0xa6, 0xc9, 0x1d, 0xff, 0x1a, 0x22, 0x4b, 0xbc, 0xbe, 0x42, 0x66, + 0x00, 0xc0, 0xc2, 0xb3, 0x78, 0x46, 0xa7, 0xcc, 0xa7, 0x81, 0xaf, 0xe0, 0x23, 0x1a, 0xa8, 0xfb, + 0x10, 0x72, 0x69, 0x93, 0xa4, 0xa0, 0xda, 0x6d, 0x65, 0x84, 0x5c, 0x04, 0xad, 0xad, 0x7e, 0x25, + 0xb5, 0x73, 0x39, 0xfa, 0xcb, 0x96, 0xd7, 0xc6, 0xcf, 0x05, 0xf2, 0x87, 0x7c, 0xc2, 0xb8, 0xb6, + 0x7c, 0x1c, 0x4b, 0x5b, 0x41, 0x0b, 0x57, 0xc9, 0x2e, 0x63, 0xe9, 0xf1, 0xc4, 0xc9, 0x01, 0xfe, + 0x8f, 0x5a, 0x74, 0x40, 0x7d, 0x0e, 0xdd, 0x5b, 0x31, 0xc5, 0xf2, 0x4e, 0x33, 0xa9, 0x3f, 0x4c, + 0x8c, 0xe8, 0x7b, 0x5a, 0x9c, 0x46, 0xa6, 0x8f, 0x3e, 0x44, 0xfa, 0x61, 0xf6, 0x49, 0x5a, 0x96, + 0x1f, 0x82, 0x98, 0xb8, 0xb9, 0x78, 0xbb, 0x3f, 0xc5, 0xd6, 0x55, 0xbe, 0x36, 0x26, 0xc0, 0x14, + 0x74, 0xdf, 0xa4, 0xcc, 0xc7, 0x0a, 0x56, 0x4c, 0xde, 0x63, 0x73, 0x51, 0x19, 0x44, 0x54, 0x69, + 0x83, 0x4a, 0xf9, 0x9c, 0xd0, 0x68, 0x32, 0xfa, 0x63, 0x8a, 0xec, 0xbd, 0xa1, 0xa3, 0xa4, 0x17, + 0x75, 0xfa, 0x8c, 0xf4, 0x32, 0x8d, 0xdd, 0xff, 0xbf, 0x7d, 0x64, 0xa7, 0xf8, 0x53, 0x0e, 0x36, + 0x91, 0xd0, 0xb6, 0xe8, 0x95, 0x44, 0x3b, 0x1c, 0xdc, 0xa4, 0x1a, 0x81, 0x2b, 0xc4, 0xe8, 0x02, + 0x70, 0x98, 0xe4, 0xbf, 0x58, 0x55, 0xe6, 0x3f, 0x8f, 0xf3, 0xce, 0x2d, 0x8d, 0x51, 0x9e, 0x77, + 0xc3, 0xf9, 0xec, 0xbf, 0xd6, 0xb4, 0x9f, 0xc4, 0xb1, 0x39, 0x7a, 0x94, 0xe8, 0x31, 0x22, 0x41, + 0x59, 0x5c, 0x4b, 0xdf, 0x3b, 0x19, 0x08, 0x2f, 0x95, 0xef, 0x8c, 0x18, 0xef, 0x19, 0xe3, 0xd8, + 0x0e, 0xd4, 0x5b, 0x26, 0x13, 0x43, 0xdd, 0xdd, 0x4e, 0x3f, 0x84, 0x3d, 0x08, 0xd1, 0xca, 0xef, + 0x70, 0xb0, 0x66, 0x22, 0x33, 0xda, 0xa4, 0x9e, 0xcb, 0xaf, 0xa6, 0xfa, 0x0b, 0xa7, 0x6b, 0xa9, + 0x12, 0xfa, 0xb8, 0x09, 0xf4, 0x44, 0xe9, 0x75, 0x7f, 0xaa, 0x64, 0xfa, 0xb4, 0x5f, 0x04, 0xe6, + 0x77, 0x46, 0x8d, 0x86, 0xa3, 0x59, 0x13, 0x46, 0x09, 0xe3, 0xbf, 0x5c, 0x3e, 0x09, 0x08, 0xc0, + 0x81, 0x4f, 0xac, 0x0a, 0x37, 0x32, 0x9c, 0x11, 0xdf, 0x87, 0x88, 0x73, 0x0e, 0x90, 0x6c, 0x70, + 0x88, 0x5c, 0xb3, 0x55, 0xd4, 0x5d, 0x7d, 0x37, 0xbf, 0x85, 0x22, 0x9b, 0x18, 0x58, 0x0a, 0x9f, + 0xc5, 0x59, 0x53, 0x8e, 0x1d, 0xc7, 0xc3, 0x67, 0xd2, 0x5e, 0xe2, 0x60, 0xa8, 0xa2, 0xbb, 0xb6, + 0x77, 0x3e, 0x54, 0x53, 0x51, 0x4d, 0x7b, 0xe0, 0xa6, 0xcd, 0x21, 0x13, 0xc1, 0x04, 0xe2, 0x59, + 0x08, 0xf2, 0x1a, 0xd5, 0x5f, 0xe8, 0xad, 0xf3, 0x56, 0xbf, 0x05, 0x25, 0x43, 0x2e, 0x5d, 0xc6, + 0xea, 0xb6, 0x98, 0xba, 0xf7, 0xc6, 0x04, 0x35, 0x61, 0x45, 0x3e, 0xb6, 0xe3, 0xe0, 0xf1, 0xbc, + 0x22, 0x70, 0xb2, 0x0a, 0xa4, 0xcf, 0x61, 0x4d, 0x75, 0x19, 0xea, 0xdd, 0x9f, 0x08, 0x7a, 0x50, + 0x54, 0xe1, 0xec, 0xec, 0xd0, 0xd3, 0x16, 0x60, 0x95, 0xa6, 0x28, 0xfd, 0x8a, 0xe8, 0x32, 0x96, + 0x10, 0xe8, 0x43, 0x23, 0xfa, 0x09, 0xb9, 0xe2, 0x50, 0xe1, 0xcf, 0xf1, 0x21, 0x21, 0x8a, 0x7d, + 0x6f, 0xab, 0x79, 0x72, 0xc1, 0x8a, 0xac, 0x4c, 0x17, 0x4d, 0x78, 0x91, 0xcf, 0x84, 0x22, 0xd2, + 0x0b, 0x9f, 0x18, 0x4b, 0x19, 0x0a, 0x92, 0x0a, 0x99, 0x27, 0xfd, 0x98, 0x44, 0xb1, 0xa2, 0x7e, + 0x6f, 0x12, 0x39, 0x29, 0xad, 0xc7, 0x14, 0x53, 0x70, 0x9c, 0x34, 0xef, 0xad, 0xdd, 0xaf, 0xc2, + 0x84, 0x1c, 0x77, 0x4c, 0xc7, 0x7a, 0x1d, 0x85, 0x8e, 0x09, 0x49, 0xcf, 0xdb, 0xc3, 0x4a, 0x7c, + 0x83, 0x3d, 0xad, 0xbd, 0xd9, 0x41, 0x70, 0x3f, 0x52, 0x09, 0x78, 0x66, 0x0f, 0x8d, 0x22, 0x60, + 0xbf, 0x0d, 0xfd, 0x1c, 0x95, 0x54, 0x41, 0xba, 0x67, 0x29, 0xf8, 0x98, 0x50, 0xa1, 0x7b, 0x1b, + 0xd6, 0x30, 0x01, 0xbd, 0xe7, 0xd0, 0xfb, 0x1d, 0x1b, 0xe5, 0xbb, 0x72, 0xe3, 0xe9, 0xb3, 0x63, + 0x88, 0x82, 0xa3, 0xa9, 0x19, 0x27, 0xcb, 0x77, 0x6d, 0x37, 0xb7, 0xdf, 0x65, 0x77, 0x2e, 0x1c, + 0xc0, 0x9c, 0x41, 0x9d, 0x2b, 0x57, 0x3a, 0x83, 0xff, 0x18, 0x22, 0x33, 0x9e, 0x77, 0xc6, 0xd2, + 0x0c, 0xe1, 0x61, 0xc0, 0xeb, 0xa9, 0xbf, 0x93, 0x8e, 0xb1, 0x37, 0x5d, 0x53, 0xbf, 0x05, 0x05, + 0x42, 0x08, 0xe2, 0x39, 0xe5, 0x8f, 0x1d, 0xf6, 0xc0, 0x29, 0xd0, 0xba, 0xfa, 0xe5, 0xf2, 0xeb, + 0x77, 0xd1, 0x72, 0xae, 0x88, 0xf5, 0xd5, 0xe5, 0xea, 0xff, 0x5c, 0xab, 0xab, 0x9f, 0x44, 0x72, + 0xb8, 0x24, 0xf1, 0x27, 0x1f, 0xc4, 0x02, 0x3d, 0xdd, 0xd8, 0x3e, 0x2c, 0xcf, 0x3f, 0xac, 0xc4, + 0x1f, 0x8c, 0x8b, 0x83, 0xda, 0x24, 0xc3, 0x70, 0xb2, 0x85, 0xfc, 0x1e, 0x8c, 0x75, 0xa6, 0x3b, + 0xaa, 0x20, 0x33, 0xa6, 0x33, 0xb6, 0x4c, 0x6e, 0x18, 0xea, 0x1a, 0x82, 0xd4, 0x80, 0xc5, 0xfe, + 0x1f, 0xa0, 0x01, 0xf4, 0xe7, 0x8e, 0x61, 0x74, 0x25, 0xf8, 0x98, 0x2d, 0xdc, 0x9d, 0xbd, 0x76, + 0xbf, 0xf0, 0x55, 0xdd, 0x1b, 0x52, 0xed, 0x14, 0x99, 0x2a, 0x7d, 0x17, 0x95, 0x7a, 0xb9, 0xe2, + 0x3e, 0x30, 0x80, 0xff, 0x99, 0x8a, 0xb4, 0x21, 0xab, 0xba, 0xc6, 0x6d, 0x9d, 0xf8, 0x8b, 0x55, + 0x22, 0x8d, 0xaa, 0x17, 0xc5, 0x0c, 0xbd, 0xdd, 0xff, 0x08, 0x70, 0x64, 0xe5, 0x44, 0x4c, 0xa9, + 0xce, 0x54, 0x7b, 0x95, 0x14, 0x61, 0x91, 0x18, 0x4f, 0xa1, 0xbd, 0xf4, 0x5c, 0xbe, 0xb1, 0x5f, + 0x44, 0x87, 0x13, 0xd6, 0x29, 0x78, 0x28, 0x35, 0xc7, 0x86, 0xc1, 0xe7, 0x07, 0xaa, 0x2f, 0x95, + 0x0d, 0xd1, 0xfc, 0x29, 0x49, 0x8e, 0x68, 0x67, 0xa0, 0x81, 0xeb, 0x53, 0x63, 0x36, 0xd9, 0xc0, + 0xb0, 0xde, 0x70, 0x2c, 0x0e, 0xdf, 0x05, 0x57, 0x6f, 0xaa, 0xd5, 0x6a, 0xbf, 0xf8, 0x48, 0xaa, + 0x4e, 0xaa, 0x39, 0x55, 0x7e, 0x32, 0x6d, 0xc3, 0xa9, 0x7d, 0x34, 0xda, 0xd4, 0x9d, 0xb2, 0xff, + 0x1a, 0x32, 0xf0, 0xdf, 0x58, 0xdc, 0x6f, 0x12, 0x40, 0xd0, 0x63, 0x50, 0x6e, 0x04, 0xe2, 0x4a, + 0x87, 0x6d, 0x88, 0x8f, 0x0a, 0xfe, 0x62, 0xbb, 0x31, 0xa4, 0x97, 0x37, 0x3c, 0x1c, 0xed, 0x98, + 0xff, 0xb7, 0x37, 0xc4, 0xc6, 0x45, 0x18, 0xa8, 0xfa, 0x74, 0x69, 0x0a, 0xd5, 0x72, 0x4e, 0x2b, + 0x22, 0xfb, 0xa4, 0x78, 0x24, 0x13, 0x9c, 0x2c, 0x67, 0xb9, 0xbb, 0xf8, 0x2b, 0x39, 0x7c, 0x59, + 0x3c, 0x24, 0xce, 0x3e, 0x83, 0x2b, 0xe5, 0x1e, 0x9a, 0x88, 0x03, 0x61, 0xf4, 0xdf, 0x49, 0x5f, + 0x89, 0x10, 0x09, 0xfb, 0xbb, 0xbe, 0xfc, 0x47, 0x89, 0x85, 0x04, 0xe6, 0x51, 0x4e, 0xd4, 0x8c, + 0x75, 0xb4, 0x8c, 0xf7, 0xcb, 0x40, 0x63, 0x40, 0xb8, 0x73, 0x14, 0xf7, 0x6b, 0xc1, 0x4d, 0x8c, + 0xd9, 0x43, 0x5a, 0x8b, 0xb1, 0xd0, 0x1b, 0xbc, 0x91, 0x30, 0x44, 0x46, 0xca, 0x57, 0x99, 0x56, + 0x74, 0xf8, 0xc1, 0x07, 0x0b, 0x02, 0x1c, 0xdd, 0xe7, 0xc7, 0x77, 0xed, 0xff, 0x05, 0x7a, 0x8c, + 0xca, 0x88, 0xe7, 0x92, 0xab, 0xb6, 0xe4, 0xf1, 0x80, 0xae, 0x6f, 0x82, 0x30, 0x88, 0xac, 0x56, + 0x2b, 0x15, 0xd4, 0x2b, 0xd1, 0x35, 0x5d, 0x1d, 0x3a, 0xf4, 0x54, 0xeb, 0xd1, 0x18, 0xfa, 0x94, + 0x15, 0xd1, 0x9b, 0xea, 0xdf, 0x45, 0x72, 0xfa, 0xbd, 0x70, 0x5c, 0x32, 0x65, 0x55, 0x6b, 0x7f, + 0x12, 0x33, 0x3f, 0x26, 0xa3, 0x51, 0x99, 0x2b, 0x87, 0xc0, 0xd9, 0x3c, 0x01, 0xaf, 0xe5, 0xfa, + 0x29, 0xe2, 0xd9, 0x23, 0x87, 0xde, 0x5b, 0x7c, 0x38, 0x9f, 0xa1, 0x3d, 0xf0, 0x89, 0x94, 0xd0, + 0x17, 0x3f, 0x1e, 0x65, 0x06, 0xe3, 0xfe, 0x49, 0x56, 0x3f, 0xc1, 0x4d, 0xd0, 0xc6, 0x5f, 0x5a, + 0xd4, 0xa3, 0x19, 0xa7, 0xd5, 0x56, 0xef, 0x77, 0x3e, 0x14, 0x91, 0x21, 0x7e, 0x6e, 0x20, 0xf9, + 0x3a, 0xc1, 0x7a, 0x14, 0xa4, 0xaa, 0x28, 0x7d, 0x89, 0x8b, 0xbe, 0x14, 0x9c, 0x72, 0x0f, 0x89, + 0x03, 0xa5, 0xdf, 0x06, 0xe0, 0x33, 0x95, 0xb6, 0x68, 0x7c, 0x7f, 0xcb, 0xf3, 0xde, 0xe8, 0x7e, + 0x6a, 0x4b, 0xaf, 0x84, 0x0a, 0xfd, 0xc4, 0xbd, 0xb8, 0x72, 0x0e, 0x87, 0x7a, 0xe4, 0x2a, 0xa3, + 0xa5, 0xe2, 0x39, 0x6e, 0xc3, 0x15, 0x66, 0x81, 0x52, 0x32, 0x18, 0x91, 0x20, 0xaf, 0x77, 0xa8, + 0xa0, 0x95, 0x55, 0x54, 0x5d, 0x4f, 0xef, 0x84, 0x37, 0x77, 0x58, 0xbb, 0x45, 0xc7, 0xbe, 0x26, + 0x08, 0xc9, 0xaa, 0xf7, 0xc1, 0x1e, 0x4c, 0x2e, 0x7e, 0xf8, 0xac, 0x34, 0x0e, 0x0b, 0xea, 0xbe, + 0x0a, 0x85, 0x16, 0x37, 0x3e, 0x16, 0xde, 0x25, 0xee, 0x1e, 0x12, 0x04, 0xb1, 0xd4, 0x7c, 0x4e, + 0x1e, 0x52, 0xbb, 0xdb, 0x8b, 0xe8, 0x5b, 0x1f, 0x5d, 0x7d, 0x1b, 0x52, 0x74, 0x7c, 0xbe, 0x5a, + 0xbb, 0xdf, 0x5c, 0xe7, 0xd7, 0x39, 0xf5, 0xce, 0x7d, 0x6a, 0x7e, 0x8a, 0x54, 0xe2, 0x60, 0xb0, + 0x55, 0x55, 0xea, 0x6e, 0xde, 0x2b, 0x72, 0xdd, 0xbe, 0x09, 0x62, 0xea, 0xab, 0x36, 0x5a, 0x6f, + 0x93, 0xa6, 0xfc, 0x48, 0x50, 0x41, 0xcf, 0x2d, 0x96, 0x37, 0x4f, 0x15, 0x8a, 0xc5, 0x1b, 0x9a, + 0xaa, 0x54, 0x56, 0x7e, 0xfc, 0xe5, 0xe2, 0x04, 0x89, 0x5a, 0x9b, 0xe2, 0xff, 0x98, 0xae, 0x45, + 0x0f, 0x3e, 0x14, 0x14, 0xb2, 0xab, 0x1a, 0x6f, 0xc9, 0xa3, 0x1a, 0x25, 0x25, 0x0e, 0x0e, 0x40, + 0x1f, 0x4d, 0x73, 0xdf, 0x1f, 0x77, 0xc2, 0x98, 0x46, 0xf5, 0xca, 0xa8, 0xba, 0xb6, 0xaa, 0xa2, + 0xea, 0xa2, 0xff, 0xe2, 0x61, 0x43, 0xc4, 0x2a, 0x18, 0x6d, 0xef, 0x62, 0xec, 0xe9, 0x0f, 0xfb, + 0x4c, 0x2a, 0xa0, 0xac, 0xf7, 0xef, 0xc4, 0xc1, 0x4e, 0xb5, 0x51, 0x75, 0x57, 0xb4, 0xfd, 0xf1, + 0x07, 0x88, 0x84, 0x6c, 0x1d, 0xd6, 0xb8, 0xf2, 0xee, 0xcf, 0x97, 0x44, 0xc8, 0x25, 0xf3, 0x62, + 0xe0, 0xb4, 0x52, 0xaa, 0x93, 0x15, 0x55, 0x51, 0xbb, 0xe1, 0x1b, 0x73, 0xfd, 0xee, 0xb6, 0x33, + 0x7c, 0x17, 0xc1, 0x71, 0x77, 0x71, 0x58, 0x51, 0xf2, 0x07, 0xbf, 0x13, 0x0a, 0x14, 0x23, 0xc5, + 0x12, 0x66, 0x43, 0x6e, 0x22, 0x3d, 0xab, 0xd2, 0x9a, 0x12, 0x5c, 0xc6, 0xc6, 0x79, 0x26, 0x09, + 0x7f, 0x2a, 0x73, 0x15, 0x2d, 0x1d, 0xf2, 0x59, 0xb3, 0x21, 0x26, 0x12, 0xf2, 0x11, 0x4b, 0xc5, + 0xcd, 0x4f, 0x04, 0xa2, 0x9c, 0xf9, 0x0f, 0x2e, 0x17, 0x1c, 0xf1, 0x84, 0x5f, 0x2d, 0xdd, 0xdc, + 0x29, 0xd1, 0xdb, 0xeb, 0x1a, 0x4e, 0xb1, 0xef, 0xa2, 0xf8, 0xac, 0x48, 0x27, 0xbe, 0x6e, 0xb1, + 0x8b, 0xc7, 0x18, 0xc4, 0x3d, 0x1a, 0x3f, 0xc1, 0x19, 0x56, 0xab, 0x3f, 0xc2, 0x93, 0x50, 0x5d, + 0xa5, 0x49, 0xd9, 0x85, 0x99, 0x33, 0x50, 0x98, 0xbb, 0x30, 0xbc, 0xf7, 0x84, 0x41, 0x58, 0xab, + 0x6b, 0x87, 0x9e, 0x62, 0x5e, 0x82, 0x69, 0x89, 0xc0, 0x39, 0x9f, 0xdd, 0x5d, 0x0d, 0xef, 0x8d, + 0x10, 0x66, 0x0e, 0x1e, 0x6c, 0x38, 0x79, 0x6d, 0xb3, 0xdf, 0x8b, 0x9c, 0x2a, 0x05, 0xc9, 0x84, + 0xf0, 0x3a, 0xfc, 0x75, 0xfd, 0xdf, 0x7b, 0xaf, 0x82, 0x2a, 0x8b, 0xb6, 0xaf, 0x5c, 0x10, 0x8d, + 0x7b, 0x76, 0x7c, 0x12, 0x11, 0xc5, 0x6e, 0xef, 0xf0, 0x47, 0x17, 0x17, 0x55, 0xea, 0xe2, 0x89, + 0x29, 0x97, 0x80, 0xd3, 0xb7, 0xf0, 0x4b, 0xd3, 0x7a, 0xa7, 0x4d, 0xeb, 0x89, 0x13, 0xcb, 0x97, + 0xbf, 0xa1, 0x9d, 0xf0, 0x44, 0x75, 0xba, 0xd5, 0x70, 0x98, 0x90, 0xe2, 0x04, 0xac, 0x34, 0xb4, + 0x55, 0x32, 0x8c, 0xce, 0x7c, 0x7e, 0x21, 0x74, 0xdf, 0x82, 0x42, 0x0b, 0x34, 0x68, 0xd1, 0xfc, + 0xf8, 0xbd, 0x27, 0xd6, 0xcb, 0xc1, 0x50, 0xc8, 0xea, 0xec, 0xb7, 0x15, 0x86, 0x80, 0x57, 0x27, + 0xb9, 0xf8, 0xf8, 0x2b, 0xe8, 0x47, 0xb2, 0x46, 0xc2, 0xb5, 0xb7, 0xe5, 0xcf, 0x7c, 0x15, 0xa1, + 0x2e, 0x84, 0xb9, 0x2f, 0x21, 0x5d, 0x55, 0xfd, 0x70, 0xfa, 0xc5, 0xf2, 0x5e, 0xbf, 0x7a, 0xab, + 0x3f, 0x51, 0xcd, 0xf0, 0xa1, 0xa5, 0xc6, 0x15, 0xde, 0xac, 0xce, 0x41, 0x15, 0xd4, 0xaa, 0xab, + 0x17, 0xc5, 0xf2, 0x7c, 0xd0, 0x58, 0x5e, 0x2a, 0x81, 0xe2, 0x64, 0x47, 0xa5, 0x55, 0xf1, 0x30, + 0x85, 0xee, 0xdc, 0xec, 0x5d, 0xde, 0xfe, 0x20, 0x60, 0x82, 0xf2, 0xdb, 0x97, 0x2b, 0xd7, 0x88, + 0x1f, 0x0a, 0x8d, 0x45, 0xb6, 0x9f, 0xe7, 0xc6, 0x8d, 0x6d, 0x5b, 0xaa, 0xe5, 0x20, 0xdf, 0xe9, + 0xba, 0xaa, 0x0a, 0x7e, 0xb2, 0x43, 0xe3, 0x2b, 0xaa, 0x65, 0x65, 0xe8, 0x98, 0xf7, 0x76, 0xd4, + 0x6a, 0x9e, 0xc9, 0x2d, 0xe4, 0xf6, 0xbb, 0xaa, 0xd7, 0xc1, 0x11, 0x4e, 0xa5, 0x36, 0xd3, 0x6f, + 0x82, 0x4a, 0xad, 0x7b, 0xe0, 0x8c, 0xfb, 0x1a, 0xf7, 0xc4, 0x0a, 0x4d, 0xb6, 0xee, 0xff, 0x98, + 0xeb, 0xaf, 0xa8, 0xed, 0xf4, 0x57, 0xae, 0xc6, 0x3c, 0xf0, 0x7f, 0x62, 0xd1, 0x07, 0x26, 0xff, + 0xfa, 0x35, 0x71, 0x31, 0xe2, 0x4e, 0x45, 0xa2, 0x0c, 0x62, 0xee, 0xa2, 0xe2, 0xe2, 0xe2, 0xfe, + 0x62, 0x5a, 0x6b, 0xe0, 0x86, 0xaa, 0xb7, 0xf1, 0x01, 0x3c, 0x9c, 0xba, 0xc8, 0x26, 0xa8, 0x97, + 0x13, 0x04, 0x42, 0x84, 0x9e, 0xa2, 0xe2, 0xfd, 0xf0, 0x57, 0xb8, 0xed, 0x79, 0x6c, 0x98, 0x7c, + 0x56, 0xa4, 0xfd, 0x31, 0x61, 0xc9, 0xd0, 0x9f, 0x87, 0xd7, 0xe9, 0xfa, 0x25, 0x45, 0xf5, 0x75, + 0x44, 0xc1, 0x1e, 0x5f, 0x2f, 0xef, 0x8d, 0xbb, 0x4c, 0x18, 0xe7, 0x0b, 0x93, 0x97, 0xd0, 0x84, + 0xbf, 0x1b, 0xc7, 0x33, 0x15, 0x10, 0x7f, 0x08, 0x3a, 0xba, 0x06, 0x0b, 0x09, 0x5f, 0xfe, 0x14, + 0xca, 0xaa, 0xaa, 0xa0, 0xb9, 0x65, 0x65, 0xe6, 0xa3, 0xfd, 0x17, 0xbe, 0x0a, 0x6a, 0x4f, 0x59, + 0xaa, 0x6a, 0xa4, 0x20, 0xef, 0xe2, 0x01, 0x70, 0xa4, 0xcf, 0x79, 0x6c, 0xb6, 0xf4, 0xf1, 0xfe, + 0x24, 0x68, 0xac, 0xfc, 0x51, 0xbf, 0xbd, 0x18, 0x95, 0x23, 0x58, 0xf1, 0x44, 0xcb, 0x6a, 0xa2, + 0xea, 0x2f, 0xc4, 0x02, 0xa2, 0x93, 0x94, 0x43, 0x2f, 0xc3, 0xf0, 0x6a, 0x95, 0xfc, 0xfc, 0x07, + 0x84, 0x09, 0xd5, 0x75, 0xd8, 0xd7, 0x9f, 0x0a, 0x6f, 0x5a, 0x03, 0x1b, 0xb9, 0x6c, 0x74, 0x6c, + 0x63, 0xeb, 0x55, 0xd7, 0xc2, 0x99, 0xfd, 0xeb, 0x1e, 0xa2, 0x6c, 0x66, 0x48, 0xba, 0x83, 0xf4, + 0xed, 0x91, 0xc1, 0xf0, 0x52, 0x46, 0x3e, 0xbc, 0xde, 0x6f, 0x37, 0xef, 0x85, 0x0f, 0xc9, 0x62, + 0xf9, 0x38, 0x85, 0x8e, 0xca, 0x41, 0xd7, 0x55, 0xcb, 0xe0, 0x8a, 0xc4, 0xf7, 0xff, 0xc1, 0x11, + 0xaf, 0x6d, 0x8f, 0x84, 0x2a, 0xab, 0x55, 0xdd, 0xef, 0xeb, 0xdf, 0x31, 0x5c, 0x56, 0xe2, 0xbf, + 0x05, 0x82, 0x2e, 0xef, 0x9e, 0x9d, 0xc5, 0x71, 0xcf, 0x82, 0x13, 0xbb, 0xbb, 0x8e, 0x3f, 0xc4, + 0x02, 0x82, 0xe8, 0xde, 0x5a, 0x1e, 0x4e, 0x92, 0x3b, 0xf0, 0x81, 0x1c, 0xb0, 0x64, 0xa8, 0xcb, + 0x74, 0x98, 0xdb, 0x32, 0x24, 0x6a, 0x84, 0x46, 0xf8, 0x28, 0xb2, 0x64, 0xa0, 0x16, 0xa0, 0x49, + 0x33, 0x66, 0x42, 0x6c, 0xf8, 0xc8, 0xef, 0x9a, 0x8a, 0xa5, 0x7e, 0x8b, 0xb9, 0xe5, 0x54, 0x34, + 0x65, 0xa7, 0xf1, 0x31, 0x3b, 0xdd, 0x57, 0xc4, 0x08, 0x04, 0x45, 0x6e, 0x7f, 0x4c, 0xb8, 0x85, + 0xef, 0x8d, 0x15, 0xba, 0x65, 0xdc, 0xb6, 0x7f, 0x2f, 0xec, 0xe5, 0x41, 0x54, 0x1c, 0xd0, 0x15, + 0x58, 0x35, 0x85, 0x69, 0x6a, 0xb7, 0xbf, 0xc1, 0x1e, 0x86, 0x11, 0x3a, 0x73, 0x9e, 0x61, 0x81, + 0x3a, 0x3c, 0x55, 0xd5, 0x8f, 0xab, 0x05, 0xd1, 0x9e, 0x23, 0x92, 0xbb, 0xfa, 0xf4, 0x47, 0x04, + 0xf8, 0x87, 0xc4, 0x2c, 0x3d, 0xbc, 0xb5, 0xf0, 0x5a, 0x7a, 0x1a, 0xf8, 0xc4, 0x67, 0x78, 0x84, + 0x4e, 0xf8, 0x24, 0x21, 0xfe, 0x70, 0x40, 0x3f, 0xf1, 0x03, 0xce, 0xc5, 0x2a, 0xa4, 0x60, 0x5e, + 0x55, 0x54, 0xc6, 0x3f, 0x12, 0x08, 0xfb, 0x6a, 0x7b, 0xe0, 0x88, 0xaa, 0x95, 0xdf, 0xe0, 0xa6, + 0xb5, 0x55, 0xaa, 0x1a, 0xe8, 0x66, 0x5b, 0xe4, 0xb6, 0x6e, 0xf5, 0xe2, 0x44, 0x02, 0xcb, 0xdf, + 0x8c, 0xcb, 0xd0, 0xea, 0xcf, 0xfc, 0x4c, 0x16, 0x77, 0x3f, 0x77, 0x77, 0x7b, 0x2b, 0x17, 0xdf, + 0x05, 0x98, 0xaf, 0x74, 0x3b, 0xd3, 0x60, 0x64, 0xf9, 0x57, 0x5c, 0x2b, 0xb3, 0x49, 0x94, 0xbc, + 0x14, 0x71, 0xbe, 0xdd, 0xef, 0xdf, 0x18, 0x76, 0x91, 0x92, 0x79, 0x64, 0xe3, 0x09, 0x0d, 0x38, + 0xfe, 0x73, 0x1d, 0xf0, 0x85, 0xb1, 0x87, 0x6e, 0xff, 0x82, 0x7b, 0x28, 0x4c, 0x93, 0x3a, 0x47, + 0x83, 0x50, 0x79, 0x0b, 0x89, 0x85, 0x20, 0x33, 0xfe, 0x37, 0xd8, 0x69, 0xbb, 0x47, 0x68, 0xbc, + 0x20, 0x84, 0x36, 0x30, 0x5a, 0x92, 0xb3, 0xa2, 0x02, 0xb3, 0x43, 0x4e, 0x2e, 0x31, 0x83, 0x73, + 0xce, 0x8f, 0xf4, 0x5c, 0xff, 0x05, 0x64, 0x97, 0x1d, 0x76, 0xd0, 0x6c, 0x98, 0xf4, 0x3a, 0xc8, + 0xe4, 0x7d, 0xdf, 0xe0, 0xba, 0xa4, 0x23, 0x0b, 0x7c, 0x2e, 0xc4, 0xb6, 0x7c, 0x11, 0x96, 0xe9, + 0x4a, 0x9e, 0x27, 0xe2, 0x08, 0x76, 0x1c, 0xb4, 0xbd, 0xbb, 0x7e, 0x28, 0x63, 0xbb, 0xdd, 0xdd, + 0xfc, 0xe2, 0x54, 0x7f, 0xdc, 0xa7, 0xe4, 0xe8, 0x8f, 0xf4, 0x57, 0xfa, 0xbd, 0xf5, 0x8b, 0xea, + 0xf5, 0xd5, 0xe7, 0xea, 0xf2, 0xf3, 0x6b, 0x19, 0x5f, 0x04, 0x64, 0x24, 0x4d, 0xeb, 0x9c, 0xbe, + 0x09, 0x0a, 0xaa, 0xbd, 0x57, 0x09, 0x5a, 0x6a, 0x92, 0xaa, 0xaf, 0x12, 0xea, 0xaa, 0xbc, 0x48, + 0x8a, 0xaa, 0xad, 0xef, 0xc4, 0x02, 0x63, 0x5b, 0x9a, 0x15, 0xaf, 0x1d, 0xf8, 0xc1, 0x2d, 0xe9, + 0x93, 0xd9, 0xf9, 0xfd, 0xde, 0x7c, 0xf0, 0x81, 0x5c, 0x56, 0xef, 0x79, 0xc4, 0x05, 0x33, 0x31, + 0x40, 0xfc, 0x48, 0x41, 0x72, 0x2b, 0xa8, 0x81, 0x00, 0x9a, 0x75, 0x85, 0x13, 0xa4, 0xc5, 0xc6, + 0x89, 0x12, 0x8e, 0xf1, 0x22, 0x01, 0x37, 0x3f, 0x3a, 0x12, 0xb1, 0x19, 0x83, 0x0d, 0x19, 0x50, + 0xd4, 0x3c, 0x12, 0x6e, 0xe5, 0x0e, 0x8e, 0xd5, 0xca, 0x64, 0xdd, 0x6b, 0x8b, 0xd2, 0xbd, 0x5b, + 0x5f, 0x29, 0x4e, 0x68, 0x62, 0x13, 0xaa, 0x2c, 0xbc, 0x29, 0x40, 0xec, 0x9f, 0x25, 0xae, 0x35, + 0x72, 0x4e, 0xe3, 0x8c, 0x43, 0x60, 0xad, 0x50, 0x2a, 0x85, 0x6f, 0xe2, 0x01, 0x54, 0xd8, 0xaa, + 0xb2, 0xf9, 0x0e, 0x92, 0x3a, 0xa0, 0x09, 0x57, 0xe2, 0x01, 0x56, 0xde, 0x86, 0xc1, 0xcb, 0xcf, + 0x0a, 0x66, 0x0b, 0x0e, 0xf0, 0xca, 0x9c, 0x4c, 0x29, 0x15, 0xbb, 0xbb, 0x3b, 0x48, 0x9b, 0x8d, + 0x50, 0x2b, 0x2d, 0xd9, 0x68, 0x25, 0x81, 0x6c, 0x76, 0x57, 0xef, 0x7a, 0x03, 0x7f, 0x05, 0x91, + 0x75, 0x17, 0x17, 0x64, 0x38, 0x00, 0x94, 0x15, 0x2d, 0xd6, 0x5b, 0xeb, 0xdc, 0x4c, 0x85, 0x63, + 0xaf, 0x13, 0xf8, 0x83, 0x5d, 0x9c, 0x56, 0xee, 0x2b, 0xe2, 0x02, 0x82, 0x95, 0xd6, 0xb5, 0xa8, + 0xbd, 0x62, 0xe4, 0x48, 0x5e, 0x35, 0x0e, 0x33, 0xa1, 0xaf, 0xf5, 0xd4, 0xfd, 0x60, 0x93, 0x8a, + 0x15, 0xb1, 0x5b, 0x63, 0x23, 0x10, 0xbf, 0xf8, 0xca, 0xaa, 0xa8, 0xad, 0xdd, 0xd5, 0x55, 0x65, + 0xca, 0x2e, 0x20, 0x28, 0x79, 0xe4, 0xdf, 0x2c, 0xb2, 0xf2, 0x40, 0x2d, 0xc9, 0x51, 0xb2, 0xc4, + 0xe4, 0xb0, 0x67, 0x4f, 0x84, 0xc4, 0xb8, 0xac, 0x4a, 0xa1, 0xa4, 0x17, 0xdf, 0xc1, 0x29, 0x15, + 0x54, 0x5c, 0x5c, 0x53, 0x17, 0x52, 0x5e, 0x20, 0x16, 0x43, 0x7e, 0x25, 0xf8, 0xbd, 0x26, 0x5d, + 0xcb, 0xc1, 0xad, 0x74, 0xab, 0xad, 0xba, 0x8e, 0xa2, 0x46, 0x97, 0x78, 0x91, 0x16, 0x37, 0xa0, + 0x31, 0x75, 0x17, 0x5f, 0x19, 0x90, 0x9d, 0xa0, 0xa2, 0x41, 0x27, 0x12, 0x22, 0xb0, 0xa4, 0x4c, + 0x22, 0x03, 0x56, 0x91, 0xe9, 0x15, 0x8b, 0x57, 0x10, 0x10, 0x36, 0x9c, 0x06, 0x9c, 0xc7, 0x19, + 0x6f, 0x6d, 0xae, 0x24, 0x15, 0x1c, 0xbf, 0x2f, 0x66, 0x2b, 0x89, 0x7a, 0x07, 0x76, 0x0d, 0xd1, + 0xc7, 0x89, 0x82, 0xab, 0x8e, 0xd1, 0xcb, 0x67, 0xbe, 0x55, 0xe9, 0xd1, 0x97, 0x96, 0x1a, 0x35, + 0xf8, 0x52, 0xa2, 0xdc, 0xeb, 0x8f, 0xd2, 0x35, 0x69, 0xed, 0xf6, 0x31, 0xbb, 0x31, 0xd1, 0xbd, + 0xa0, 0x76, 0xa9, 0x9e, 0xf1, 0x20, 0xa6, 0xe6, 0x20, 0xf4, 0x31, 0x63, 0x16, 0x30, 0x7e, 0xc9, + 0x71, 0xb6, 0x99, 0xd4, 0xc6, 0xc7, 0xd7, 0xbe, 0x4a, 0x75, 0xbb, 0x7e, 0x48, 0x7b, 0xa1, 0x12, + 0xa3, 0x58, 0x6a, 0x55, 0xc2, 0x93, 0x56, 0x36, 0x34, 0xd2, 0x55, 0x33, 0x10, 0x5c, 0x39, 0x01, + 0x26, 0xa2, 0xce, 0x05, 0x50, 0xc1, 0x23, 0xbe, 0x14, 0xd1, 0x1c, 0xc6, 0x1b, 0x02, 0x66, 0x69, + 0x1b, 0xb7, 0xfb, 0x41, 0xe9, 0x92, 0x66, 0xeb, 0xd6, 0xca, 0x60, 0x93, 0x01, 0x4f, 0xc4, 0xc2, + 0x92, 0x33, 0x7c, 0x62, 0x1c, 0x60, 0x34, 0xdc, 0x10, 0x07, 0x8e, 0xd2, 0x95, 0xef, 0xa3, 0x20, + 0x42, 0x0f, 0x4f, 0x58, 0x93, 0x62, 0xb7, 0x7f, 0x56, 0x7c, 0x27, 0x44, 0x5c, 0x65, 0x49, 0xb2, + 0xf4, 0xef, 0xc6, 0x48, 0xcb, 0x3c, 0x93, 0x65, 0x9c, 0x83, 0xa8, 0xe4, 0x12, 0x30, 0xa4, 0x9a, + 0x8b, 0xfc, 0x61, 0xd9, 0x46, 0x31, 0xd0, 0x83, 0x8c, 0x0d, 0xaa, 0xde, 0xf6, 0xdb, 0x66, 0xf8, + 0x98, 0x22, 0xb5, 0x4e, 0x31, 0xbe, 0x4d, 0xba, 0xe2, 0x04, 0x02, 0x8e, 0x3c, 0xbe, 0x42, 0x25, + 0xc8, 0xab, 0x82, 0x51, 0xd1, 0x5a, 0x4e, 0x5b, 0x37, 0x44, 0x4a, 0xdc, 0xdf, 0xe1, 0x6d, 0xc5, + 0xf4, 0x45, 0x64, 0xc9, 0x9b, 0x14, 0x11, 0x9f, 0x6b, 0x30, 0x18, 0x33, 0xfe, 0x5f, 0x72, 0x40, + 0xbd, 0x1f, 0x0f, 0xae, 0xbe, 0xac, 0x5f, 0x56, 0x57, 0x57, 0x4d, 0xd5, 0xdf, 0x56, 0x7d, 0x5c, + 0xac, 0x48, 0xf1, 0x0f, 0x2b, 0x19, 0xd4, 0x42, 0x71, 0x46, 0x11, 0x82, 0xd1, 0x40, 0x2a, 0x13, + 0x06, 0x94, 0xd5, 0x78, 0x52, 0x0b, 0xdd, 0xc1, 0x1d, 0xf0, 0xfa, 0xb8, 0xb3, 0x5f, 0xac, 0x86, + 0x3e, 0xa7, 0xe1, 0x22, 0xf2, 0xaa, 0x03, 0xaf, 0x89, 0xaa, 0xca, 0xd6, 0xc7, 0xc4, 0x0c, 0x39, + 0x79, 0x78, 0xf2, 0xca, 0x85, 0xe8, 0x34, 0xfb, 0xa9, 0x3f, 0xfc, 0x21, 0xcb, 0x91, 0x2c, 0x08, + 0x6c, 0x34, 0x38, 0x1a, 0x26, 0x6a, 0xaf, 0xff, 0x8a, 0x12, 0x2e, 0xa2, 0xeb, 0xc9, 0x4f, 0x18, + 0x48, 0xfa, 0xae, 0x66, 0x23, 0xcb, 0x12, 0x8a, 0x3b, 0x22, 0xc9, 0x88, 0x2b, 0x10, 0x14, 0x88, + 0xfd, 0x2c, 0xbd, 0xef, 0x66, 0x6a, 0xbf, 0x4b, 0xbe, 0x14, 0xd8, 0xed, 0x2f, 0x20, 0xae, 0xe2, + 0x4a, 0xc9, 0x3c, 0x60, 0x8f, 0xd2, 0xcf, 0x4c, 0x5b, 0xdd, 0x74, 0x67, 0x17, 0x7c, 0x13, 0x98, + 0xca, 0x32, 0x7b, 0xbd, 0xdf, 0xe1, 0x0b, 0xbb, 0xbb, 0xbe, 0xee, 0x53, 0x1b, 0x27, 0x29, 0x45, + 0xd5, 0x45, 0xfd, 0x5c, 0xf8, 0x2e, 0x2a, 0x68, 0x6f, 0x42, 0x63, 0x79, 0x55, 0x5c, 0x29, 0x3a, + 0x56, 0x77, 0x50, 0x81, 0xe1, 0x80, 0xb2, 0x7a, 0x33, 0xa4, 0x7a, 0x50, 0xd4, 0x39, 0xd5, 0x66, + 0x8d, 0x84, 0x16, 0x8a, 0x9f, 0x0a, 0x61, 0x67, 0xe8, 0x99, 0x05, 0x99, 0xc7, 0x26, 0x44, 0xc8, + 0xe9, 0x13, 0xce, 0x30, 0x76, 0xc6, 0xe9, 0x57, 0x85, 0x0a, 0x8c, 0x7e, 0xef, 0x2c, 0x2b, 0xdf, + 0x1d, 0x40, 0x12, 0xd2, 0xbd, 0x9b, 0xb5, 0x22, 0x2b, 0x5a, 0xc4, 0xab, 0xf0, 0x9c, 0xf1, 0x01, + 0x1d, 0x5f, 0x5a, 0xfa, 0x63, 0xb1, 0x9e, 0x26, 0x0b, 0x39, 0xd8, 0x1f, 0x11, 0x04, 0x78, 0x41, + 0xc8, 0x47, 0x1d, 0xce, 0x48, 0x5d, 0x41, 0xdc, 0x1c, 0x23, 0x90, 0xbe, 0x20, 0x47, 0xe2, 0x28, + 0xef, 0xcc, 0x4a, 0x4d, 0x30, 0x7e, 0xa9, 0x56, 0x26, 0x63, 0x8a, 0xc5, 0x62, 0x51, 0x82, 0x58, + 0xf1, 0x10, 0x42, 0x46, 0x48, 0x88, 0xb3, 0xd6, 0xea, 0xe4, 0x30, 0xae, 0xdd, 0xfc, 0x58, 0x9e, + 0x6c, 0xc2, 0xf6, 0x53, 0xc4, 0x0e, 0xca, 0x41, 0x0b, 0x27, 0x0e, 0x5f, 0x60, 0xea, 0xc8, 0x43, + 0xe0, 0xac, 0x77, 0x7b, 0xbd, 0xdd, 0xd1, 0x21, 0x8d, 0xc0, 0x63, 0x7f, 0xa1, 0x30, 0x4b, 0xd7, + 0x2f, 0xa2, 0x45, 0x5d, 0x58, 0xfa, 0x2e, 0x2f, 0x9a, 0xfa, 0xbe, 0xf5, 0x5f, 0xac, 0xa4, 0xea, + 0xef, 0xbb, 0xa4, 0xaf, 0xeb, 0x0f, 0xe0, 0xa4, 0x53, 0x22, 0x68, 0x87, 0x10, 0x80, 0xf1, 0x28, + 0xc9, 0xfd, 0xb8, 0x81, 0xe4, 0xea, 0x89, 0x7e, 0x3b, 0xf0, 0xf1, 0x0a, 0x04, 0xe2, 0x4d, 0xc9, + 0xc9, 0xbb, 0xf4, 0xff, 0xb7, 0x3b, 0x03, 0xd7, 0x6f, 0xa6, 0x4e, 0xce, 0xb1, 0x00, 0xb0, 0x4d, + 0x58, 0xf9, 0x29, 0x1e, 0xf1, 0x79, 0x78, 0xb8, 0xed, 0xf0, 0xa0, 0xcb, 0x2d, 0xb8, 0xaf, 0x56, + 0xf1, 0x5c, 0x56, 0x7e, 0x71, 0x23, 0xdc, 0xde, 0xfa, 0x17, 0xaf, 0x12, 0xba, 0xfa, 0xf7, 0xc1, + 0x1f, 0x43, 0x5e, 0x6f, 0xa3, 0xb7, 0xd4, 0xa8, 0xc9, 0x70, 0xa1, 0x11, 0x1b, 0x0d, 0x9b, 0xbe, + 0x2e, 0xa2, 0x74, 0x64, 0x05, 0x62, 0xb2, 0xd8, 0xaf, 0x2f, 0x82, 0x49, 0xd8, 0x3f, 0x1c, 0x70, + 0xbf, 0xc6, 0xf1, 0x01, 0x48, 0x71, 0xc4, 0xda, 0x61, 0xa6, 0xbd, 0x09, 0x98, 0xee, 0xb0, 0x71, + 0x6e, 0xca, 0xfb, 0x11, 0xdd, 0x91, 0x93, 0x43, 0x4a, 0x40, 0x6b, 0xe8, 0x85, 0x7b, 0x4d, 0xc4, + 0x0b, 0xfc, 0x29, 0x69, 0x04, 0x4a, 0x41, 0x39, 0xa5, 0xcb, 0x99, 0x97, 0x33, 0x6d, 0xc1, 0x95, + 0x95, 0xa1, 0xa9, 0x6d, 0xc2, 0x8e, 0x80, 0xa3, 0x8d, 0x11, 0xd9, 0xfc, 0x40, 0x29, 0xbb, 0x1d, + 0xb9, 0x94, 0x11, 0x46, 0x42, 0x0b, 0x84, 0x07, 0x55, 0x61, 0x67, 0x25, 0x5e, 0x49, 0xe3, 0x9a, + 0x26, 0x8f, 0x10, 0x38, 0xbc, 0xed, 0x36, 0x33, 0x71, 0xff, 0x23, 0xdc, 0xf0, 0xe2, 0x49, 0x6e, + 0xe7, 0x04, 0xfa, 0xb5, 0x70, 0x5d, 0x6b, 0x6a, 0xef, 0x4a, 0xbc, 0xd6, 0x29, 0xa6, 0xdf, 0x8a, + 0xb0, 0x6e, 0xd1, 0xf3, 0x3e, 0x30, 0x7e, 0x30, 0x42, 0x65, 0x33, 0x01, 0xac, 0x56, 0x9f, 0xd9, + 0x26, 0x5a, 0x76, 0x34, 0xbc, 0x57, 0x1e, 0x6f, 0x83, 0xb4, 0x33, 0xb0, 0x5b, 0xf1, 0x24, 0x62, + 0x3f, 0x1f, 0x57, 0xc1, 0xfe, 0xbb, 0x3f, 0xc4, 0x42, 0x27, 0xc6, 0xa9, 0x96, 0xe9, 0xc6, 0x9f, + 0x2b, 0x74, 0xa7, 0x0b, 0xc6, 0x58, 0xc7, 0xcd, 0x4f, 0xd5, 0x71, 0xb8, 0x6b, 0xf2, 0x91, 0x75, + 0xf2, 0xd5, 0x3a, 0xfa, 0x29, 0x92, 0xba, 0x91, 0x3e, 0x08, 0xb3, 0xe3, 0xd5, 0xdf, 0x5e, 0xfa, + 0xd5, 0x75, 0xeb, 0xeb, 0xaf, 0xac, 0x55, 0xcb, 0xb4, 0x7b, 0xfc, 0x5d, 0xb4, 0x34, 0xf7, 0x23, + 0xb2, 0x75, 0xef, 0x8a, 0x14, 0xe7, 0x51, 0x71, 0x2d, 0x26, 0x2f, 0xe0, 0x94, 0xf6, 0xee, 0xea, + 0xab, 0x7f, 0x88, 0xab, 0x2e, 0xab, 0xf0, 0x47, 0x17, 0x8b, 0xab, 0x3e, 0xb1, 0xbe, 0x14, 0x11, + 0x09, 0xc9, 0x93, 0x14, 0x4b, 0x09, 0x1c, 0x3a, 0x6e, 0x00, 0x6c, 0x5d, 0xbd, 0x99, 0xcf, 0x38, + 0x16, 0x2a, 0x5e, 0xb1, 0xdf, 0xe3, 0x07, 0x8f, 0xdc, 0x2d, 0xb4, 0x40, 0x4e, 0x16, 0x15, 0x62, + 0xc6, 0xfe, 0xba, 0xf1, 0x39, 0x43, 0x26, 0x5c, 0x17, 0xe0, 0x86, 0xfa, 0xbb, 0xea, 0xef, 0x82, + 0x6d, 0x0e, 0xee, 0x18, 0x9a, 0x0c, 0x18, 0x1a, 0xdf, 0x89, 0x82, 0xa8, 0xf5, 0x3f, 0x90, 0x84, + 0x6c, 0x82, 0x9c, 0xcc, 0x35, 0xdc, 0x48, 0x80, 0xa4, 0xff, 0xcb, 0x97, 0x4a, 0x87, 0xbf, 0xd3, + 0x8c, 0x3f, 0xf1, 0xaa, 0x2a, 0xc4, 0xc1, 0x09, 0x2b, 0x51, 0xdb, 0xe5, 0x8a, 0xb1, 0x9a, 0x1e, + 0x2d, 0x87, 0xa2, 0xf7, 0xd7, 0xbe, 0x08, 0xe2, 0xb1, 0x58, 0xac, 0xaa, 0x1f, 0xc4, 0x05, 0x0a, + 0xf0, 0x05, 0x69, 0xc4, 0x44, 0x00, 0x07, 0xe0, 0xa8, 0x08, 0x79, 0x0d, 0x4d, 0xd2, 0xf0, 0x6f, + 0xa3, 0xe2, 0xad, 0x39, 0xab, 0x26, 0x6d, 0xff, 0xb5, 0x52, 0x8c, 0x57, 0x12, 0x58, 0xb1, 0xa1, + 0x97, 0x18, 0xb1, 0xe2, 0x61, 0x4e, 0xe5, 0x09, 0xd6, 0xdd, 0x8d, 0x31, 0x16, 0x09, 0x74, 0x18, + 0x4c, 0x3b, 0xd1, 0x99, 0x97, 0xb3, 0xe5, 0xf7, 0x3b, 0x25, 0x65, 0xec, 0xfc, 0x40, 0x29, 0xb8, + 0xea, 0xed, 0x96, 0xb1, 0x58, 0x68, 0x52, 0x42, 0x8c, 0xb6, 0x9e, 0x44, 0x4c, 0x5f, 0x09, 0x11, + 0x56, 0xc6, 0xef, 0xf9, 0x22, 0xb7, 0x77, 0xf0, 0x47, 0xbd, 0x7e, 0x57, 0x04, 0x66, 0x4a, 0xda, + 0xf7, 0x89, 0x05, 0x77, 0x37, 0x3f, 0x93, 0xc6, 0x2c, 0x8c, 0xd3, 0x63, 0x7f, 0x8c, 0xaf, 0x4a, + 0x78, 0x22, 0xc6, 0xee, 0x42, 0x84, 0x7e, 0x25, 0xfa, 0x83, 0x6a, 0xd7, 0x82, 0x21, 0x22, 0x98, + 0xb8, 0xb9, 0x14, 0x3f, 0xd1, 0x1e, 0xb8, 0x23, 0x33, 0x8a, 0xdd, 0xed, 0xf4, 0x78, 0xbe, 0xb9, + 0xcb, 0xeb, 0x5f, 0x44, 0x8a, 0x7e, 0x8a, 0xd2, 0x73, 0xd5, 0x24, 0x9a, 0x6b, 0xd7, 0x56, 0x78, + 0x91, 0x82, 0xa6, 0xef, 0x61, 0xca, 0xd1, 0xc4, 0xc4, 0xfc, 0x14, 0x71, 0xf5, 0x19, 0xa8, 0x1d, + 0xfe, 0xc8, 0xa9, 0x73, 0xf1, 0x65, 0x8b, 0xa6, 0x2e, 0x2e, 0xa6, 0xc9, 0x5c, 0xc7, 0x2f, 0x74, + 0xdf, 0xc1, 0x51, 0xab, 0x56, 0x63, 0x84, 0x94, 0x6a, 0x4b, 0x09, 0x64, 0x45, 0xac, 0x34, 0xb1, + 0xa3, 0xbf, 0x04, 0xb4, 0x09, 0x89, 0xce, 0x1e, 0xda, 0xcb, 0xf6, 0x58, 0xc4, 0xcf, 0xf1, 0x67, + 0x71, 0x58, 0xad, 0xc4, 0xa6, 0x22, 0x8c, 0xb6, 0xfe, 0x08, 0xae, 0x54, 0x83, 0xa1, 0x01, 0x5e, + 0xff, 0x05, 0x07, 0x71, 0x58, 0xac, 0x56, 0x28, 0xdc, 0x56, 0xe9, 0xfe, 0x2c, 0x9a, 0xba, 0x1b, + 0x1a, 0x1b, 0x1e, 0x22, 0xe9, 0xb6, 0x9b, 0x17, 0x10, 0x10, 0xbb, 0xbf, 0x18, 0xa6, 0xba, 0xe2, + 0x26, 0x2b, 0x69, 0xb6, 0x2d, 0xe2, 0x60, 0xa0, 0xd1, 0xd4, 0xc9, 0xd9, 0x57, 0x45, 0xf4, 0xb2, + 0x75, 0x31, 0x8e, 0xde, 0x20, 0xc7, 0x40, 0x53, 0x28, 0x43, 0xf3, 0x19, 0xb8, 0xf8, 0xc1, 0x8f, + 0x13, 0x0a, 0x53, 0xa3, 0x63, 0x63, 0xbb, 0x03, 0x2a, 0x83, 0x77, 0xb3, 0x58, 0xee, 0xce, 0x84, + 0x3a, 0x98, 0x1f, 0xa8, 0x7f, 0x82, 0x2b, 0xa0, 0xf8, 0x21, 0xb2, 0xb1, 0x71, 0x32, 0x1c, 0x5c, + 0x5c, 0x5d, 0x78, 0x91, 0x98, 0x3b, 0x31, 0x9a, 0xb9, 0x62, 0xdd, 0xef, 0x65, 0xcf, 0xc9, 0x2a, + 0x95, 0x3f, 0x95, 0xc9, 0xb6, 0x6a, 0xc7, 0xe1, 0x1a, 0xb0, 0x97, 0x4e, 0x9e, 0xdb, 0x5e, 0x53, + 0x2a, 0xfe, 0x08, 0x4c, 0x78, 0x24, 0x9f, 0xbc, 0x40, 0x2c, 0xac, 0xd8, 0xd1, 0x30, 0x5c, 0x1f, + 0x60, 0xfb, 0x0b, 0xd4, 0xba, 0x16, 0xbb, 0xe1, 0x02, 0x8a, 0xc5, 0x6e, 0x2b, 0x15, 0xb6, 0x2b, + 0xc7, 0xd9, 0x6f, 0xcd, 0xbd, 0xf8, 0x90, 0x54, 0x42, 0xf7, 0xd1, 0x3b, 0xb4, 0xd3, 0xdd, 0xf8, + 0x98, 0x92, 0x8b, 0xb8, 0x82, 0x93, 0x88, 0x99, 0x89, 0x5d, 0x49, 0xf0, 0x58, 0x5c, 0x2e, 0xd2, + 0xd2, 0x44, 0xe7, 0xe9, 0x45, 0x16, 0xea, 0x15, 0x84, 0xff, 0x08, 0xca, 0x22, 0x7c, 0x0d, 0x27, + 0x9f, 0x48, 0x45, 0x85, 0x3e, 0xa2, 0x72, 0x52, 0xfe, 0x58, 0xb9, 0xf0, 0xfe, 0xaf, 0x0b, 0x98, + 0xea, 0x25, 0xe7, 0x21, 0xb2, 0x97, 0xac, 0x56, 0x8b, 0xfe, 0x09, 0xb4, 0x83, 0x5a, 0x88, 0x41, + 0x5c, 0x5e, 0xaf, 0xad, 0x10, 0xb9, 0xab, 0x98, 0x5d, 0xdd, 0xfc, 0x12, 0x1a, 0xee, 0xb2, 0xbe, + 0xb5, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x15, 0x0a, 0xb0, 0x36, 0x8b, 0x13, 0x42, 0x58, + 0xe2, 0x2a, 0xe8, 0x53, 0x86, 0x36, 0x61, 0x15, 0xd2, 0x34, 0x70, 0x60, 0xb4, 0x05, 0x5d, 0x92, + 0x59, 0xf7, 0x00, 0xd0, 0x42, 0xb1, 0x0e, 0xb7, 0x85, 0x66, 0x71, 0xfa, 0x12, 0xf0, 0xfc, 0x4d, + 0x0c, 0xcb, 0x88, 0xc2, 0x3d, 0x0d, 0x4a, 0x9f, 0x04, 0xe3, 0x92, 0x76, 0xc4, 0x2c, 0xba, 0xff, + 0x17, 0x18, 0x20, 0x23, 0x2a, 0x3c, 0x48, 0x50, 0x42, 0x86, 0x74, 0xbc, 0x49, 0x4b, 0x66, 0x11, + 0xa2, 0x47, 0x6b, 0xc9, 0x9d, 0xa1, 0x5a, 0xa7, 0x8c, 0xfc, 0x54, 0x6f, 0x1e, 0x01, 0xc3, 0xb5, + 0x48, 0x0c, 0x10, 0x2b, 0x54, 0xb0, 0x0c, 0xa1, 0xdb, 0xe5, 0x1e, 0xf3, 0x88, 0x47, 0x7c, 0x18, + 0x7f, 0x88, 0xaa, 0xf6, 0x77, 0x2f, 0x54, 0xec, 0x21, 0x08, 0x88, 0x51, 0x83, 0x1c, 0xf1, 0x22, + 0x42, 0x81, 0x08, 0x22, 0x45, 0xa3, 0x0d, 0xb4, 0x31, 0x50, 0xce, 0x27, 0x2c, 0x75, 0xbd, 0xf9, + 0xff, 0x67, 0xc2, 0x95, 0x5a, 0x2a, 0x4b, 0x53, 0x5a, 0x19, 0x63, 0x2d, 0x31, 0x7e, 0x76, 0x51, + 0x0a, 0xd0, 0x7f, 0xd5, 0x40, 0xb9, 0x19, 0xc7, 0x7e, 0x7e, 0xd1, 0x5c, 0xc1, 0x36, 0xca, 0x00, + 0x11, 0x56, 0x4e, 0x1b, 0xa3, 0x7a, 0xf7, 0xd1, 0x4a, 0x9f, 0x51, 0x90, 0x57, 0x44, 0xca, 0xb8, + 0x21, 0xa5, 0x7a, 0x3b, 0xf5, 0x79, 0x39, 0x74, 0xe9, 0xfa, 0x95, 0x2f, 0xa1, 0x8c, 0x45, 0xf0, + 0x58, 0x3d, 0x36, 0xbb, 0x77, 0x60, 0xea, 0x9f, 0x7d, 0x5c, 0xa8, 0x88, 0x21, 0x93, 0x97, 0x93, + 0xb7, 0xa7, 0x1c, 0x48, 0x91, 0x81, 0x44, 0x23, 0x28, 0xaa, 0xe4, 0x1e, 0x45, 0x1c, 0xfd, 0x72, + 0xf5, 0xc4, 0x84, 0x41, 0x56, 0x67, 0xac, 0x5d, 0xc0, 0x80, 0x2d, 0x1b, 0x3e, 0xbe, 0x0a, 0x42, + 0xa9, 0x10, 0x83, 0xd8, 0xa1, 0x92, 0xab, 0x3b, 0x0e, 0x75, 0x0f, 0x25, 0x24, 0xbf, 0x52, 0xa3, + 0xa7, 0xd5, 0xfc, 0x48, 0x24, 0x10, 0xc0, 0x21, 0x9d, 0x7c, 0x08, 0xbe, 0xb9, 0xf3, 0x47, 0x40, + 0x46, 0x64, 0x77, 0x84, 0x61, 0x41, 0x59, 0x8d, 0x90, 0xc4, 0xd8, 0xac, 0x6e, 0xcd, 0xbe, 0xe5, + 0xb1, 0x58, 0x94, 0x20, 0x09, 0x6e, 0x0e, 0x26, 0x09, 0x2f, 0xb3, 0x1d, 0xfc, 0x4c, 0x14, 0x77, + 0x38, 0x85, 0xa1, 0x27, 0xbb, 0x19, 0x4e, 0xe2, 0x61, 0x01, 0xa1, 0x3b, 0x83, 0xcb, 0x1a, 0xb0, + 0x61, 0xd4, 0x71, 0xc2, 0x82, 0x45, 0x15, 0x37, 0xfd, 0xc5, 0x6e, 0xe5, 0xe8, 0x59, 0xd2, 0x23, + 0xb3, 0x67, 0xa1, 0xe9, 0xe2, 0x27, 0xa1, 0xe9, 0x9e, 0x9d, 0x70, 0x49, 0xcf, 0x4b, 0x22, 0xfa, + 0x15, 0x2a, 0xe1, 0x31, 0xfa, 0x49, 0x69, 0x24, 0x7e, 0xa7, 0xbe, 0x89, 0x0d, 0x5d, 0x1c, 0xa9, + 0x5d, 0x69, 0xc3, 0x88, 0x05, 0x41, 0x46, 0x06, 0xb6, 0x17, 0xc8, 0xb8, 0xd0, 0xfa, 0x2f, 0xd5, + 0xca, 0x42, 0x38, 0xff, 0x8a, 0x20, 0xf5, 0x25, 0x74, 0xe7, 0x15, 0x84, 0xfe, 0x70, 0xae, 0x22, + 0xc6, 0x99, 0x23, 0xff, 0x88, 0xb4, 0xd6, 0x3a, 0x00, 0x07, 0xc0, 0x68, 0x1f, 0x9b, 0xa4, 0x97, + 0x82, 0x69, 0x68, 0x5a, 0x48, 0xc1, 0xe8, 0xfa, 0x77, 0x38, 0x46, 0x09, 0x04, 0x66, 0xa0, 0x58, + 0x58, 0xdc, 0xf1, 0x20, 0xa4, 0xd5, 0x4d, 0x76, 0x33, 0xd1, 0x50, 0x39, 0x32, 0x44, 0xbf, 0x16, + 0x23, 0x77, 0x7b, 0xf1, 0x02, 0x47, 0x14, 0x5a, 0x76, 0x83, 0x62, 0x66, 0x2a, 0xe6, 0x82, 0x67, + 0xc5, 0xbd, 0x17, 0xfd, 0x14, 0xba, 0x5e, 0x0a, 0x2c, 0x21, 0xfb, 0x9a, 0x3c, 0xc0, 0x44, 0x51, + 0xcb, 0xe0, 0xba, 0xda, 0xa2, 0x0b, 0x1b, 0xa1, 0x7b, 0xdf, 0xe0, 0x84, 0x2a, 0xdd, 0x63, 0xb1, + 0x8a, 0xf5, 0x22, 0x22, 0x11, 0xc2, 0x24, 0x3d, 0x0f, 0x4c, 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0xfd, + 0x79, 0x57, 0x8c, 0xe7, 0xa1, 0xe9, 0x9e, 0x87, 0xa1, 0xe8, 0xfa, 0x6f, 0xa3, 0xe9, 0x97, 0xaf, + 0xd1, 0x5c, 0x12, 0xce, 0xc4, 0xec, 0x4e, 0xc4, 0xec, 0x48, 0x9f, 0x5c, 0x3e, 0x84, 0x74, 0x9c, + 0x20, 0x34, 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0xcf, 0x43, 0xd3, 0xf1, 0x73, 0xd0, 0xf4, 0xcf, 0x43, + 0xd3, 0xf1, 0x1c, 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0x5d, 0x4c, 0x5f, 0x11, 0xcf, 0x43, 0xd3, 0x3d, + 0x0f, 0x4f, 0x04, 0x75, 0x9d, 0x8a, 0x42, 0x4e, 0x34, 0x53, 0x11, 0x57, 0x96, 0x94, 0x8a, 0x89, + 0x10, 0x56, 0xb1, 0x24, 0x1a, 0xca, 0xc7, 0x21, 0x25, 0x69, 0x80, 0x34, 0xf5, 0x8c, 0x00, 0x41, + 0x1e, 0x9f, 0xf2, 0x22, 0x5b, 0xf7, 0xe8, 0xea, 0x7e, 0x5a, 0x5f, 0x88, 0x18, 0x28, 0x98, 0x11, + 0x01, 0x57, 0x42, 0x50, 0x40, 0x41, 0x26, 0x5f, 0x34, 0x21, 0x34, 0x90, 0x19, 0x2c, 0x10, 0x1e, + 0xb4, 0xe0, 0x42, 0xc7, 0x80, 0x32, 0x73, 0x86, 0x04, 0x03, 0xa2, 0x21, 0x90, 0xa3, 0x80, 0x05, + 0x89, 0x10, 0x38, 0xf7, 0x66, 0xb7, 0x0a, 0xc3, 0xdb, 0xa7, 0x62, 0xf4, 0xa5, 0xfa, 0x1e, 0x74, + 0xa8, 0x66, 0x3f, 0x3e, 0x6c, 0xb3, 0x60, 0x71, 0x4d, 0xb6, 0x34, 0x34, 0x82, 0x76, 0xf1, 0x02, + 0x42, 0x81, 0x4a, 0x1b, 0x9e, 0x48, 0xa8, 0xb7, 0x61, 0x41, 0xe1, 0x6d, 0x1c, 0x1b, 0x88, 0xab, + 0x84, 0x03, 0x2f, 0x77, 0x71, 0x8a, 0x86, 0x11, 0x10, 0x14, 0xba, 0x4b, 0x72, 0x7f, 0x79, 0x05, + 0xcf, 0x3c, 0x57, 0x8c, 0x98, 0x6c, 0x1b, 0x15, 0x49, 0x67, 0x7b, 0x7b, 0xfb, 0x9f, 0x05, 0x42, + 0xea, 0x60, 0x77, 0xa6, 0xa8, 0x6a, 0x5e, 0xb6, 0x5f, 0xc4, 0x88, 0x04, 0xe2, 0x93, 0xc1, 0xb7, + 0x51, 0x52, 0x11, 0xb0, 0x30, 0x21, 0xc0, 0x1a, 0xe4, 0x83, 0x2a, 0x26, 0x0b, 0x18, 0x07, 0x1c, + 0xa7, 0xc7, 0x43, 0xc2, 0x00, 0xa1, 0x83, 0xd3, 0x41, 0xd9, 0x81, 0xb6, 0x4a, 0x9a, 0xcc, 0x6b, + 0xbe, 0xf8, 0xfd, 0xfd, 0x0d, 0xf1, 0x14, 0x15, 0x83, 0xe0, 0x9f, 0x6a, 0x95, 0xaa, 0x47, 0x43, + 0xbf, 0x04, 0x34, 0x92, 0xfc, 0xae, 0xae, 0x0d, 0xd1, 0x2b, 0xeb, 0x14, 0x9c, 0x21, 0xda, 0x6b, + 0x69, 0xad, 0xa6, 0x97, 0x05, 0x14, 0x92, 0x40, 0xd0, 0x34, 0x92, 0x40, 0xd0, 0x3a, 0x9f, 0xac, + 0x55, 0xd4, 0x97, 0xc1, 0x14, 0x6f, 0x1f, 0x15, 0x61, 0xe0, 0x9f, 0x4d, 0x2d, 0x3a, 0x69, 0x12, + 0xe5, 0xb4, 0xd3, 0x4d, 0x78, 0x82, 0xa4, 0x96, 0x92, 0x5f, 0x82, 0x4e, 0x92, 0x43, 0xcb, 0xe1, + 0x3e, 0x92, 0x5a, 0x49, 0x78, 0xeb, 0x4d, 0x6d, 0x35, 0xb4, 0xd7, 0xe3, 0x3b, 0x4d, 0x5b, 0x69, + 0x76, 0x9a, 0xda, 0x6b, 0x88, 0xf8, 0x2b, 0xe3, 0x06, 0x20, 0x3a, 0xed, 0x23, 0x98, 0x30, 0x11, + 0xae, 0x65, 0x7b, 0xe1, 0x4d, 0x22, 0x47, 0x2e, 0x4d, 0x9e, 0x6d, 0x2d, 0x1c, 0xcc, 0xc3, 0x51, + 0xaa, 0x55, 0xe0, 0x8e, 0x92, 0x47, 0x49, 0x1d, 0x24, 0x95, 0x2e, 0x89, 0x17, 0xc1, 0x6e, 0x4a, + 0x72, 0x53, 0x8b, 0xe1, 0x71, 0x0b, 0x63, 0x6b, 0x81, 0x70, 0x8c, 0x68, 0x63, 0x40, 0x02, 0xe1, + 0x68, 0xa9, 0x04, 0x42, 0x67, 0x3d, 0x7d, 0x27, 0x8e, 0xaf, 0x08, 0x0c, 0x15, 0x03, 0xad, 0xea, + 0x63, 0xcb, 0x32, 0x12, 0x3c, 0xf3, 0xc1, 0x52, 0x71, 0xe7, 0xaa, 0x4e, 0xb0, 0xe9, 0x23, 0x8d, + 0x75, 0x5f, 0xc4, 0x82, 0x6c, 0x6e, 0x5b, 0x75, 0xa2, 0x03, 0x68, 0x81, 0xaf, 0x09, 0x55, 0xeb, + 0xc4, 0x87, 0x84, 0xaa, 0xed, 0x94, 0xb4, 0x17, 0x09, 0x20, 0x23, 0x31, 0xbc, 0x22, 0x21, 0xb0, + 0x98, 0x7c, 0x0e, 0xc7, 0x6a, 0x68, 0x57, 0xfc, 0x48, 0xa9, 0xca, 0x14, 0xa9, 0xe6, 0x8b, 0xc1, + 0x58, 0x45, 0x12, 0x01, 0xa3, 0x37, 0x16, 0xba, 0xf0, 0xe4, 0x26, 0xfd, 0xcf, 0x2b, 0x86, 0x0a, + 0xc5, 0xe2, 0x02, 0x84, 0x54, 0xf6, 0xe6, 0x31, 0xbc, 0xe6, 0x2e, 0x8c, 0x82, 0x04, 0x8d, 0x20, + 0x05, 0x06, 0x07, 0x23, 0xfe, 0x24, 0x14, 0x8a, 0x81, 0x35, 0xb2, 0x6b, 0x02, 0x07, 0x81, 0x35, + 0x78, 0x08, 0x47, 0x0c, 0xef, 0xf4, 0x0b, 0x70, 0xc1, 0x09, 0x60, 0x4e, 0x79, 0xb7, 0xc6, 0xb4, + 0x51, 0x07, 0x7b, 0x1d, 0xc2, 0x14, 0x17, 0x3a, 0x7d, 0x5f, 0xea, 0x74, 0x31, 0x5e, 0x72, 0x9d, + 0x08, 0xb5, 0xe2, 0xad, 0xbd, 0x72, 0x61, 0xc5, 0xa8, 0xe1, 0x5e, 0x78, 0xed, 0x15, 0x23, 0xe8, + 0x71, 0x39, 0x8f, 0xfd, 0x0a, 0xc3, 0xeb, 0x2f, 0xb9, 0x79, 0x39, 0x7b, 0x3f, 0xa2, 0x37, 0xd5, + 0x87, 0x82, 0x4b, 0xa8, 0xe2, 0xdf, 0x4b, 0xd1, 0xe2, 0xf8, 0x76, 0xb9, 0x7d, 0xbc, 0x83, 0x41, + 0xf6, 0x8c, 0x69, 0x96, 0x9c, 0x1b, 0x5a, 0xff, 0xaa, 0x55, 0xe0, 0x92, 0x92, 0x49, 0x24, 0x95, + 0x7a, 0xf7, 0xd7, 0xbe, 0x0a, 0x2d, 0x35, 0xb4, 0x1b, 0x5d, 0xae, 0x54, 0x3b, 0xf0, 0x41, 0x2f, + 0x14, 0x1b, 0x41, 0xd4, 0x16, 0xb3, 0x57, 0x29, 0x8e, 0xe5, 0x61, 0xad, 0x3e, 0x64, 0x0c, 0xb9, + 0x1e, 0xfb, 0xc9, 0xfb, 0xbf, 0x0c, 0x05, 0x02, 0x54, 0x03, 0x40, 0x88, 0xca, 0x15, 0x05, 0x02, + 0x02, 0x81, 0x26, 0xae, 0x63, 0x07, 0x98, 0xde, 0x00, 0x02, 0x33, 0x51, 0x46, 0x00, 0x01, 0x42, + 0x04, 0xe6, 0x11, 0x13, 0x98, 0xa2, 0x84, 0x35, 0x27, 0xac, 0x72, 0x78, 0x40, 0x15, 0xdd, 0x82, + 0x98, 0x2a, 0x23, 0xa1, 0x30, 0x34, 0x0e, 0x98, 0xe8, 0xcd, 0xd0, 0xaa, 0xe8, 0x99, 0x51, 0x72, + 0x6a, 0x6f, 0x6e, 0x3b, 0x54, 0x23, 0x0d, 0x04, 0xda, 0x3d, 0xb1, 0x40, 0x63, 0x45, 0x39, 0x59, + 0x1f, 0x9d, 0xff, 0x0a, 0x04, 0xa9, 0xa6, 0xe6, 0xc7, 0x51, 0x50, 0x9f, 0x31, 0x3a, 0x41, 0xb4, + 0x72, 0x09, 0x7c, 0x97, 0xaa, 0x43, 0xb7, 0x89, 0x04, 0xa7, 0x28, 0xe6, 0x35, 0x60, 0x81, 0x36, + 0x03, 0xf4, 0xf7, 0xc3, 0xe2, 0xfa, 0x19, 0xaa, 0x92, 0x5b, 0x01, 0xf8, 0xe1, 0x1c, 0xd8, 0x65, + 0x11, 0x5b, 0xcf, 0x6b, 0x2f, 0x12, 0xf8, 0x98, 0xde, 0x6c, 0x7c, 0x1d, 0xff, 0x05, 0x21, 0x1b, + 0xf0, 0x5a, 0x99, 0x1e, 0xef, 0xa4, 0xd9, 0xff, 0xff, 0x82, 0x21, 0x63, 0xfe, 0x5f, 0xef, 0x4e, + 0xbc, 0xf3, 0xaf, 0xe7, 0xd3, 0xef, 0xe1, 0xce, 0x3b, 0xe5, 0xbe, 0x3a, 0x2a, 0x3e, 0x9f, 0x7f, + 0x2e, 0x24, 0x14, 0x11, 0x24, 0xb4, 0x92, 0xdf, 0xe3, 0x29, 0x25, 0xa4, 0x96, 0x92, 0x5b, 0x4d, + 0x63, 0x78, 0xc9, 0x08, 0x22, 0x24, 0x1a, 0x5c, 0x71, 0x8e, 0x7a, 0x7c, 0xbf, 0xdf, 0xcb, 0x9e, + 0x15, 0xe7, 0x72, 0x4d, 0xce, 0xe4, 0x8a, 0x8e, 0xf8, 0xe2, 0xfb, 0xe8, 0x43, 0xfd, 0x15, 0xc1, + 0x3a, 0x39, 0x79, 0x5d, 0x0a, 0xca, 0xba, 0x3b, 0x9f, 0x11, 0xcf, 0x4c, 0xf4, 0x9e, 0x8b, 0xb9, + 0xff, 0xf8, 0x47, 0x69, 0x3b, 0x4d, 0x6d, 0x35, 0xf9, 0xba, 0x49, 0x78, 0x9e, 0xd3, 0x5b, 0x4d, + 0x38, 0x98, 0x77, 0x0d, 0xb2, 0xfb, 0x54, 0xcf, 0xbc, 0xb9, 0x71, 0x38, 0xf1, 0x1e, 0x1a, 0x53, + 0x91, 0x9a, 0xbb, 0x95, 0x99, 0x7e, 0x24, 0x22, 0x14, 0x09, 0x1e, 0xf2, 0x93, 0xe0, 0x75, 0xf6, + 0xf7, 0xc0, 0x7a, 0x76, 0xa0, 0xb0, 0x19, 0xef, 0x07, 0x5f, 0x2e, 0xc1, 0xd3, 0xee, 0x32, 0x20, + 0x01, 0x60, 0xf1, 0xe7, 0x02, 0x18, 0x09, 0x28, 0xd8, 0x3e, 0xf0, 0xc0, 0x53, 0x45, 0x57, 0xb1, + 0x31, 0x67, 0xf9, 0x5b, 0x13, 0x63, 0xe2, 0xc7, 0xb8, 0x51, 0x5b, 0xd9, 0x51, 0xc0, 0x2c, 0x19, + 0x71, 0x46, 0x83, 0xd3, 0x17, 0x65, 0x8f, 0xd5, 0x89, 0xa9, 0x30, 0xf9, 0xea, 0x26, 0x17, 0x12, + 0x70, 0xc1, 0x4c, 0x34, 0x88, 0x1a, 0xe4, 0x56, 0x8c, 0x3c, 0xc6, 0x1c, 0x07, 0xd1, 0x2e, 0xba, + 0x85, 0x0f, 0xf1, 0x22, 0x06, 0x08, 0x48, 0xa6, 0x3e, 0x87, 0x2c, 0x16, 0xeb, 0x64, 0xdc, 0xe7, + 0x2e, 0xe2, 0xbb, 0x5f, 0x05, 0x87, 0xa7, 0x6b, 0x4d, 0xc2, 0x55, 0x95, 0xe9, 0xa6, 0x2d, 0x10, + 0x16, 0xc3, 0xff, 0x28, 0x84, 0x04, 0x70, 0xc5, 0xaf, 0x87, 0xc4, 0x0c, 0x0a, 0xbc, 0x78, 0x84, + 0xed, 0x99, 0x08, 0xc0, 0x81, 0xc2, 0xf6, 0x9a, 0xda, 0x1c, 0xb3, 0x88, 0xfc, 0xa5, 0x3d, 0x0f, + 0x4f, 0xd4, 0xe8, 0xa8, 0x9c, 0x10, 0x91, 0xa6, 0xba, 0xf8, 0x23, 0x10, 0xe4, 0x77, 0x97, 0xd6, + 0x0f, 0x82, 0x2a, 0xab, 0xbc, 0xbe, 0x51, 0x69, 0x52, 0x4b, 0xc2, 0x5d, 0x24, 0xb6, 0x9a, 0xf1, + 0xd6, 0x9a, 0x49, 0x26, 0x9a, 0x4a, 0xd3, 0x49, 0x33, 0xf0, 0x8d, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, + 0xf1, 0x3d, 0x24, 0xb4, 0x92, 0xf0, 0x8d, 0xa6, 0xb6, 0x9a, 0xda, 0x6b, 0x11, 0xd1, 0xb1, 0x0f, + 0x04, 0x47, 0x29, 0x05, 0x03, 0x1f, 0x42, 0xd1, 0x40, 0xb9, 0xa9, 0x25, 0xf8, 0x21, 0xb4, 0xd2, + 0x49, 0x23, 0xef, 0xaa, 0x2d, 0xf8, 0x21, 0xe9, 0x24, 0x99, 0x7a, 0x21, 0xea, 0xe4, 0xba, 0xbb, + 0xfa, 0xb2, 0xbb, 0x2e, 0xd3, 0x4f, 0xa9, 0x52, 0x48, 0x46, 0x34, 0x42, 0x1b, 0x07, 0x78, 0xad, + 0x22, 0x88, 0x63, 0xa3, 0x89, 0x01, 0xb0, 0xcd, 0x35, 0x79, 0x34, 0x10, 0x05, 0xf0, 0xf1, 0xb2, + 0x8c, 0xf7, 0xf8, 0xd3, 0x54, 0x7c, 0x12, 0xdb, 0xac, 0x12, 0x0d, 0x64, 0x0b, 0x3d, 0xe7, 0xbd, + 0xfd, 0xfd, 0x22, 0x76, 0x12, 0xa0, 0xad, 0x66, 0xab, 0xa3, 0x7f, 0xfc, 0x29, 0x33, 0xe0, 0xc6, + 0x31, 0xe4, 0xb0, 0x40, 0x4d, 0xd4, 0x46, 0x8d, 0x50, 0xc2, 0x90, 0xf1, 0x90, 0xda, 0xda, 0x6a, + 0x31, 0xfa, 0x80, 0x12, 0xf1, 0x90, 0x80, 0x46, 0x84, 0x8a, 0xf1, 0x20, 0xdc, 0x4c, 0x28, 0x61, + 0x47, 0x50, 0xa0, 0xde, 0x60, 0x08, 0x13, 0xc1, 0x0c, 0x05, 0xa8, 0x18, 0x45, 0x91, 0x39, 0x8f, + 0x06, 0x1b, 0x1b, 0x19, 0x28, 0x99, 0x2f, 0x73, 0x37, 0x7c, 0x95, 0x2b, 0x4d, 0x25, 0x17, 0xc2, + 0x93, 0x74, 0x99, 0x0d, 0xc0, 0xcb, 0x87, 0x75, 0x94, 0x46, 0x20, 0x50, 0x96, 0xd8, 0x83, 0x2d, + 0xbf, 0xeb, 0xb9, 0xd8, 0x74, 0xf8, 0xc9, 0xf5, 0x71, 0x3e, 0xcb, 0x62, 0x84, 0xc5, 0x57, 0x4f, + 0x1d, 0xa9, 0x27, 0xe7, 0x82, 0xb3, 0x83, 0xf5, 0x26, 0xc6, 0x92, 0x82, 0x6f, 0x66, 0x18, 0xce, + 0xb9, 0x3b, 0x51, 0x35, 0xa8, 0x59, 0xcb, 0x89, 0x10, 0x0a, 0x44, 0x25, 0x81, 0x7a, 0x78, 0x80, + 0xd3, 0x3c, 0x02, 0x8e, 0x6e, 0x09, 0x03, 0x9a, 0x6b, 0xa1, 0x89, 0xa2, 0xb2, 0x0d, 0x48, 0x38, + 0x02, 0x91, 0xf9, 0x7c, 0x10, 0x86, 0x73, 0x17, 0x9f, 0x1d, 0xfc, 0x44, 0xf8, 0x95, 0x24, 0x9a, + 0x69, 0xff, 0xaa, 0x54, 0xba, 0x94, 0xbe, 0x38, 0x8d, 0x35, 0xb4, 0xd6, 0xd3, 0x5f, 0xa3, 0x57, + 0xc1, 0x17, 0x77, 0xaf, 0xa9, 0x81, 0x5c, 0x12, 0x1d, 0x3d, 0x27, 0x7c, 0xdd, 0x24, 0x97, 0x15, + 0x69, 0xad, 0xa6, 0xb2, 0x85, 0x50, 0xb0, 0xfb, 0x2c, 0x3f, 0x2d, 0x7c, 0xbf, 0x5f, 0x2d, 0x7c, + 0xbf, 0xff, 0x37, 0x16, 0x23, 0x49, 0x26, 0x0e, 0xd3, 0x5e, 0x8a, 0xc7, 0xd5, 0xca, 0xe8, 0x88, + 0xe9, 0xf1, 0x16, 0x9a, 0xda, 0x6b, 0x27, 0x05, 0xf9, 0xc2, 0x01, 0xa6, 0x96, 0x98, 0xe5, 0xc9, + 0x3a, 0xaa, 0xff, 0x84, 0xf4, 0xda, 0xe9, 0x25, 0xe7, 0xab, 0xbd, 0xff, 0xc4, 0xed, 0xdb, 0xb7, + 0x6f, 0xd1, 0x26, 0x7d, 0x1c, 0xe9, 0x7d, 0x4e, 0x92, 0x42, 0x22, 0x01, 0x21, 0x20, 0x3b, 0x5e, + 0xc0, 0x71, 0x05, 0x0a, 0xb9, 0x60, 0x02, 0xe8, 0x08, 0xf1, 0x21, 0x41, 0x90, 0x4d, 0xa5, 0xfa, + 0x66, 0x08, 0x03, 0xaa, 0x4c, 0xea, 0xbd, 0x09, 0xb9, 0xa9, 0x40, 0x72, 0x41, 0xe1, 0xb7, 0x1c, + 0xde, 0x50, 0x00, 0x11, 0xc6, 0xf1, 0x23, 0x4a, 0x4a, 0xf8, 0xf7, 0x1c, 0x1d, 0x56, 0x01, 0xe6, + 0x7f, 0x65, 0xdd, 0x86, 0x93, 0x98, 0x5a, 0x0c, 0xd3, 0xc0, 0x93, 0x41, 0x00, 0x50, 0xdf, 0x81, + 0x2c, 0x98, 0x3a, 0x30, 0x4e, 0xa8, 0x1d, 0xef, 0x8d, 0x69, 0x5e, 0x5d, 0xf1, 0xb4, 0xa1, 0x27, + 0x88, 0xc9, 0xa3, 0x04, 0xae, 0x30, 0x4c, 0x20, 0x80, 0x91, 0x1f, 0x11, 0x24, 0x10, 0x02, 0x75, + 0xe8, 0x36, 0x52, 0xa4, 0x50, 0x98, 0x36, 0xac, 0xc3, 0xc6, 0xc4, 0x63, 0x32, 0x2a, 0x90, 0x7e, + 0x88, 0x9a, 0x2f, 0x49, 0xb9, 0xbb, 0x52, 0x5d, 0xf0, 0x5c, 0x6a, 0xe9, 0x38, 0xad, 0xdc, 0xff, + 0x5f, 0x0a, 0x1c, 0x12, 0xb9, 0x80, 0xde, 0xb3, 0xa1, 0x21, 0xa5, 0xbf, 0x85, 0x22, 0x78, 0x20, + 0x8a, 0xf1, 0x48, 0xb7, 0x04, 0xea, 0xca, 0xb9, 0x5a, 0xd8, 0x03, 0x9a, 0x26, 0xbc, 0x40, 0x52, + 0x3f, 0xee, 0x72, 0x30, 0x4f, 0x1a, 0x0c, 0x9a, 0x1e, 0xa4, 0x99, 0x32, 0x7e, 0x8d, 0x99, 0x1e, + 0x88, 0x09, 0x7a, 0x32, 0x28, 0x55, 0x5d, 0x0c, 0x77, 0x63, 0x80, 0xef, 0x8c, 0x15, 0xd9, 0x38, + 0xe5, 0x69, 0x5a, 0x99, 0xc3, 0x80, 0x17, 0xce, 0x0f, 0x21, 0x51, 0xba, 0xe6, 0xb0, 0xec, 0xf6, + 0xd8, 0xe8, 0xb9, 0xd6, 0x4a, 0xa4, 0x80, 0xdc, 0x25, 0x2b, 0x10, 0x24, 0x2a, 0x11, 0xcc, 0x13, + 0x1d, 0x93, 0xde, 0x66, 0xc3, 0xf4, 0x89, 0x79, 0x12, 0x5e, 0x9f, 0xfe, 0x0b, 0x8a, 0x6a, 0x30, + 0x7b, 0x4d, 0x67, 0x4f, 0x85, 0x69, 0x24, 0x92, 0x49, 0x24, 0x92, 0x5d, 0x6d, 0xb4, 0xd3, 0xff, + 0x04, 0xb2, 0x62, 0x5d, 0x24, 0xb2, 0x27, 0x89, 0x04, 0x54, 0x92, 0xc6, 0xa9, 0x84, 0x16, 0x25, + 0x24, 0x86, 0x88, 0x6b, 0xf5, 0xc1, 0x55, 0x83, 0x8c, 0x2f, 0x4e, 0x9a, 0x68, 0x49, 0xa6, 0x44, + 0xfa, 0x8b, 0xaf, 0x82, 0xeb, 0x4d, 0x63, 0xc8, 0xff, 0xab, 0xe0, 0x96, 0xd3, 0x5b, 0x4d, 0x79, + 0x7c, 0x94, 0xf4, 0xbc, 0xfd, 0x2b, 0x4f, 0x1e, 0xaf, 0xfc, 0x12, 0xf6, 0x9a, 0xda, 0x68, 0x76, + 0xfa, 0xa3, 0xb0, 0xa7, 0x05, 0x36, 0x9a, 0xce, 0xea, 0x5b, 0x49, 0x7b, 0xe0, 0x9b, 0x4d, 0xa4, + 0x2d, 0xa6, 0x8c, 0x9f, 0x58, 0xaf, 0x8f, 0xb4, 0xd2, 0x49, 0x35, 0x49, 0x76, 0x9a, 0xf4, 0x43, + 0x27, 0xd4, 0x89, 0x7c, 0x13, 0xf1, 0x3b, 0x50, 0x19, 0xf8, 0x5a, 0x38, 0x29, 0x1d, 0x34, 0x58, + 0x36, 0xdc, 0x7a, 0x2f, 0x10, 0x14, 0x1d, 0xc7, 0x2c, 0xa4, 0x9b, 0x0f, 0x38, 0x7f, 0x0e, 0xe4, + 0x17, 0x23, 0x02, 0x0a, 0x84, 0xa0, 0x4d, 0x83, 0xab, 0xa4, 0x25, 0xc1, 0x1d, 0xdf, 0x1a, 0x5d, + 0x28, 0x23, 0x7e, 0x2c, 0x82, 0xcf, 0x03, 0x80, 0xdb, 0x97, 0x25, 0x06, 0x87, 0x3a, 0x9c, 0x4e, + 0xec, 0x5b, 0x18, 0x85, 0x81, 0x62, 0x41, 0x00, 0xb8, 0x2f, 0x8c, 0xec, 0x80, 0xdc, 0x4b, 0x84, + 0x54, 0x5c, 0xa1, 0x69, 0x95, 0x61, 0xaf, 0x72, 0x01, 0x0b, 0xed, 0x55, 0x2a, 0x4f, 0x0a, 0x79, + 0x96, 0x77, 0x49, 0x5d, 0x72, 0x87, 0x94, 0x4b, 0x6c, 0x78, 0xd3, 0x60, 0xe9, 0x28, 0x0d, 0x5e, + 0xf9, 0x65, 0xe5, 0xe1, 0x0c, 0xbe, 0x5b, 0xe0, 0xae, 0x2e, 0x4a, 0x24, 0xe8, 0xd8, 0xcf, 0x11, + 0x1e, 0xab, 0x36, 0x3b, 0xe1, 0x1f, 0x37, 0x8a, 0x62, 0x64, 0x12, 0xcd, 0x9d, 0x73, 0x19, 0x58, + 0x58, 0x4e, 0x23, 0x07, 0xc4, 0x95, 0x14, 0x18, 0xec, 0x14, 0x37, 0xbf, 0x34, 0xcd, 0x1f, 0x12, + 0x30, 0x41, 0xa9, 0x2b, 0x44, 0x2b, 0x19, 0xab, 0x8b, 0xea, 0x28, 0x32, 0xaa, 0x92, 0x5d, 0x62, + 0x8e, 0x6c, 0xb5, 0x27, 0x10, 0x58, 0x7c, 0xec, 0x62, 0xe1, 0xf4, 0x2d, 0xb9, 0x88, 0xa0, 0xa9, + 0xd2, 0xba, 0x21, 0x81, 0x5c, 0x67, 0x69, 0xa6, 0x9a, 0x69, 0xad, 0x24, 0xb4, 0x92, 0xf0, 0xee, + 0x1a, 0x49, 0xf9, 0x6e, 0x83, 0xae, 0xdd, 0xe9, 0x60, 0x9a, 0x68, 0x68, 0x22, 0x7f, 0xf1, 0x3b, + 0x76, 0xed, 0xdb, 0x27, 0x47, 0x02, 0x9c, 0x01, 0x7c, 0x10, 0x9a, 0x9d, 0x36, 0xbe, 0xb5, 0x2f, + 0x27, 0x8a, 0xcf, 0xc2, 0x5d, 0x24, 0xb4, 0x92, 0xf0, 0x43, 0xd2, 0x49, 0xbe, 0x11, 0xa4, 0x96, + 0x92, 0x59, 0x15, 0x11, 0x56, 0x23, 0x88, 0xed, 0x35, 0xb4, 0xd7, 0xa9, 0x56, 0x7c, 0x14, 0x74, + 0x92, 0xd2, 0x49, 0x32, 0xf4, 0x4c, 0xaf, 0xa2, 0xa0, 0x1b, 0xe1, 0x9e, 0x92, 0x47, 0xaf, 0x1d, + 0xc7, 0xfc, 0x42, 0x28, 0x8b, 0x4e, 0x22, 0x09, 0xc5, 0x39, 0x54, 0x2a, 0x4a, 0xa2, 0xa2, 0x18, + 0xe8, 0x5c, 0x5c, 0x71, 0x0b, 0xf7, 0xc2, 0x82, 0xad, 0xb4, 0x3d, 0x51, 0x01, 0x83, 0x1e, 0x95, + 0xaa, 0xaa, 0xc2, 0xd4, 0xb5, 0x06, 0x02, 0x19, 0xd9, 0x23, 0x65, 0x54, 0xb7, 0xb0, 0xa2, 0x20, + 0x49, 0xc2, 0x19, 0x40, 0x4a, 0x37, 0x96, 0xc2, 0x13, 0x8d, 0x33, 0xe3, 0xa7, 0xf5, 0x8f, 0x5b, + 0x63, 0x6f, 0xf0, 0xc6, 0x1c, 0x48, 0xdd, 0x75, 0x1e, 0x8b, 0xd8, 0xfe, 0x18, 0x85, 0xc0, 0xd6, + 0x39, 0x12, 0x97, 0x73, 0x45, 0xc5, 0x10, 0xec, 0x62, 0x50, 0x18, 0x36, 0x43, 0x48, 0x51, 0xa9, + 0x24, 0x81, 0x9f, 0x93, 0x61, 0x1e, 0x56, 0xb1, 0x3f, 0x16, 0x08, 0x1d, 0x95, 0xa1, 0x9e, 0x30, + 0x73, 0x1f, 0xd1, 0x83, 0x7a, 0x0e, 0x24, 0x29, 0x3b, 0xea, 0xca, 0xa6, 0xac, 0x7c, 0xcb, 0x6b, + 0xc1, 0x50, 0xb6, 0xac, 0x99, 0x78, 0xd4, 0x13, 0x14, 0xe8, 0xed, 0xe2, 0x46, 0x57, 0xfa, 0xeb, + 0xbc, 0x4e, 0x16, 0x4e, 0x07, 0x58, 0xaa, 0x03, 0xc8, 0x94, 0x20, 0x13, 0xcc, 0x40, 0x41, 0x1e, + 0x16, 0x5f, 0x36, 0xc0, 0x38, 0xe8, 0x4e, 0xe4, 0x57, 0xaf, 0x24, 0xcd, 0x86, 0xbc, 0x61, 0x9d, + 0xee, 0x24, 0x16, 0x66, 0x71, 0x1b, 0xcc, 0x19, 0x1e, 0x79, 0x38, 0x0d, 0x6a, 0x72, 0x6c, 0xe0, + 0x83, 0x68, 0x10, 0x11, 0xa0, 0xf9, 0x4c, 0x6c, 0x36, 0x3a, 0xdd, 0x39, 0x7c, 0x28, 0x71, 0x27, + 0x22, 0x01, 0xc4, 0x78, 0xa3, 0xcc, 0x40, 0x58, 0x5a, 0xc5, 0xcd, 0x97, 0x3a, 0xd3, 0x1c, 0xf5, + 0x79, 0xc2, 0xf3, 0x62, 0x72, 0x4c, 0x4b, 0xfc, 0x29, 0xb2, 0x36, 0x4b, 0x26, 0x27, 0xca, 0xa4, + 0xa9, 0xa1, 0xa9, 0x48, 0xbf, 0xc2, 0x82, 0x29, 0x23, 0x05, 0x60, 0xe5, 0xc7, 0x43, 0x27, 0x4a, + 0xa9, 0xb3, 0xa9, 0x48, 0xe9, 0xdf, 0x15, 0x92, 0x78, 0xd2, 0x1b, 0x78, 0x9f, 0xa0, 0xa9, 0xaf, + 0x9e, 0xac, 0x8b, 0x14, 0x15, 0x7e, 0xf8, 0xca, 0x49, 0x69, 0x25, 0xb4, 0xd6, 0xd3, 0x5f, 0x8f, + 0xe9, 0x24, 0x91, 0xc1, 0xe7, 0x07, 0xe3, 0xeb, 0xf5, 0xdf, 0x9f, 0xbe, 0xa9, 0x91, 0xfa, 0x8f, + 0xbe, 0x3b, 0x74, 0xa9, 0x07, 0x90, 0x81, 0x25, 0xe9, 0x1c, 0x4b, 0xc1, 0x0d, 0xf7, 0x4d, 0xa3, + 0x12, 0x7c, 0xf4, 0xaa, 0x31, 0x26, 0x7c, 0xdc, 0x27, 0x49, 0x2d, 0xa6, 0x93, 0x9f, 0x82, 0x32, + 0x3d, 0xec, 0x7d, 0x52, 0xbf, 0x3e, 0x47, 0x9f, 0x6d, 0xb6, 0xdb, 0x37, 0x04, 0xc5, 0x49, 0x0a, + 0x9d, 0x3a, 0x75, 0x5c, 0xe5, 0x3a, 0x4f, 0xa7, 0xdf, 0xf1, 0x30, 0xb8, 0xc8, 0x39, 0x1f, 0x83, + 0x48, 0x68, 0x26, 0xc8, 0xf5, 0xc3, 0x06, 0x10, 0xbf, 0x61, 0xde, 0x77, 0xe6, 0x84, 0xf2, 0xf1, + 0xa2, 0x89, 0xda, 0x1c, 0xf2, 0x55, 0x49, 0x15, 0x67, 0x5e, 0x34, 0x56, 0xf7, 0xfa, 0x64, 0xb2, + 0xec, 0xc7, 0x14, 0xe8, 0x22, 0x84, 0x3c, 0x65, 0xb7, 0x4a, 0x15, 0x86, 0x37, 0xd2, 0x25, 0x42, + 0xae, 0x8f, 0x3e, 0x0d, 0xc7, 0x1c, 0x0d, 0xa8, 0x2b, 0x4e, 0x5e, 0x0f, 0xac, 0x8a, 0xc5, 0xe2, + 0xda, 0x11, 0x6b, 0xe1, 0x42, 0x0e, 0x38, 0x7d, 0x79, 0xfb, 0x1a, 0xca, 0x91, 0xdd, 0x9c, 0x90, + 0xd2, 0x4d, 0x8a, 0x6c, 0x5b, 0x1d, 0xa0, 0x60, 0x30, 0xa3, 0x31, 0xa3, 0x5d, 0x3c, 0x91, 0x49, + 0xc3, 0x6c, 0xcf, 0x7c, 0x82, 0xbb, 0xed, 0xca, 0x59, 0xb6, 0xa8, 0x20, 0x30, 0xca, 0xb6, 0x3b, + 0x02, 0xef, 0x42, 0xa0, 0x6a, 0xaa, 0x36, 0x3e, 0x0a, 0x2b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0xc7, + 0x3e, 0x30, 0xae, 0xe7, 0x46, 0x0e, 0x0d, 0x6e, 0x8c, 0x70, 0xd2, 0x7a, 0x53, 0x8e, 0x40, 0x53, + 0x19, 0x4f, 0xbf, 0xf6, 0x19, 0x01, 0x4a, 0x1b, 0x38, 0x82, 0x7f, 0x6d, 0x32, 0x35, 0x08, 0x6b, + 0x15, 0x4f, 0x18, 0x0d, 0x79, 0x85, 0x62, 0x0f, 0x49, 0x49, 0x8c, 0x29, 0xa0, 0x9d, 0x2f, 0x0f, + 0xdb, 0x44, 0x33, 0x97, 0x6f, 0x07, 0xb7, 0x6b, 0x34, 0xb6, 0x6c, 0x23, 0xb0, 0x17, 0xe2, 0xb6, + 0xa3, 0xd9, 0x17, 0x8f, 0xce, 0xe1, 0x2a, 0xaf, 0xf3, 0x29, 0xbd, 0x8b, 0x6d, 0x18, 0x47, 0x1c, + 0xa6, 0x0f, 0xbf, 0x3b, 0xe2, 0x58, 0x25, 0x7f, 0xbb, 0x50, 0xc0, 0x69, 0x94, 0x66, 0xe2, 0x61, + 0xf3, 0x3e, 0x0f, 0xe9, 0x07, 0xff, 0xe3, 0x8e, 0xf0, 0xc0, 0x5c, 0x1b, 0x4e, 0x8e, 0xf5, 0x46, + 0x71, 0x82, 0xb4, 0xf0, 0xa6, 0x17, 0x11, 0x0a, 0x16, 0x26, 0xc1, 0xbb, 0x18, 0x8e, 0xe3, 0x63, + 0x59, 0x24, 0x24, 0x45, 0x47, 0x29, 0x1e, 0xf1, 0x00, 0xb0, 0x50, 0x26, 0x6f, 0xb6, 0xe9, 0x2c, + 0xcd, 0xbc, 0x6d, 0x35, 0x7b, 0x36, 0xaf, 0xc4, 0xc5, 0xc3, 0x3c, 0x65, 0x52, 0x1a, 0xb3, 0xca, + 0x2a, 0xb9, 0x5b, 0xb2, 0x57, 0xd0, 0x55, 0x3b, 0xf5, 0x4a, 0x7d, 0x48, 0x97, 0xd5, 0xc0, 0x4b, + 0x82, 0x32, 0x73, 0xd1, 0xfe, 0x08, 0xf7, 0x77, 0x4e, 0xbc, 0x84, 0x77, 0xfd, 0x5f, 0xea, 0x95, + 0x3e, 0x8a, 0xdf, 0x57, 0x89, 0xe8, 0xbd, 0xc4, 0x89, 0x04, 0x86, 0xa3, 0x32, 0x0a, 0xdb, 0xe0, + 0x88, 0x87, 0x60, 0xf6, 0x21, 0xa1, 0x6f, 0x02, 0x31, 0xe2, 0x42, 0x84, 0x66, 0x28, 0x5a, 0x9d, + 0xfb, 0xd4, 0x9c, 0xb5, 0x5b, 0xd2, 0x71, 0x2c, 0x03, 0x09, 0x02, 0xbc, 0x61, 0xbf, 0x81, 0x71, + 0xc9, 0x41, 0x51, 0x59, 0xe3, 0x68, 0xfe, 0x26, 0x08, 0xaa, 0xf6, 0x20, 0x52, 0x35, 0x70, 0x3e, + 0xeb, 0xb4, 0xf0, 0xec, 0x2c, 0xe3, 0x0b, 0x0c, 0xd8, 0x5b, 0xb9, 0xe9, 0xe1, 0x28, 0xf9, 0x9c, + 0x13, 0x97, 0x2f, 0x45, 0x20, 0x55, 0x80, 0xa8, 0x0c, 0x82, 0x15, 0xe3, 0xdd, 0xb2, 0x82, 0xaf, + 0xc1, 0x49, 0x95, 0x55, 0x54, 0x98, 0x96, 0x27, 0x42, 0xce, 0x2b, 0x78, 0x81, 0x87, 0xd3, 0xe8, + 0x75, 0x9c, 0xe5, 0x47, 0x0e, 0x0c, 0x8c, 0xd3, 0x46, 0x3d, 0x66, 0xe3, 0x3e, 0x71, 0x01, 0x4a, + 0x70, 0x1c, 0x7d, 0x03, 0x5f, 0x18, 0x8f, 0xff, 0x51, 0xbb, 0xac, 0x0d, 0x00, 0xa5, 0x2b, 0x02, + 0x41, 0x83, 0x12, 0xe7, 0x6f, 0xb3, 0xfb, 0x71, 0x9b, 0x19, 0x6e, 0xc5, 0x67, 0x20, 0xa3, 0x15, + 0xe1, 0x4b, 0xc1, 0xfe, 0x5c, 0x55, 0x90, 0xbe, 0xc3, 0x55, 0x2e, 0x45, 0x66, 0x2f, 0x76, 0xe2, + 0x60, 0x90, 0xaf, 0xa5, 0xc8, 0xf1, 0x22, 0x47, 0xdb, 0xda, 0x92, 0x99, 0xbd, 0xf8, 0x91, 0x23, + 0xc5, 0x7a, 0xe2, 0xc3, 0xc3, 0xb1, 0x79, 0x55, 0x86, 0x15, 0xc3, 0x52, 0x22, 0xda, 0xe1, 0x5e, + 0x26, 0x0a, 0xfc, 0x2d, 0x18, 0x2c, 0x64, 0x33, 0xca, 0x5b, 0x6c, 0x37, 0x56, 0xd1, 0xfe, 0x1f, + 0xd8, 0xa1, 0x8e, 0xa4, 0xe2, 0xc2, 0x2d, 0x35, 0xb4, 0xd7, 0xe1, 0x0b, 0x4d, 0x6c, 0x1b, 0x49, + 0xda, 0x6b, 0x2f, 0x47, 0x44, 0xb8, 0x43, 0xa1, 0x0c, 0x93, 0xa3, 0xe1, 0x17, 0xd0, 0x97, 0x38, + 0x46, 0x17, 0x11, 0xb9, 0x89, 0x50, 0x41, 0xed, 0xb1, 0x00, 0xc7, 0x63, 0xb5, 0x55, 0xff, 0x85, + 0x07, 0x4c, 0xfa, 0xbd, 0x22, 0xd1, 0x8a, 0xdd, 0x25, 0xa2, 0xc3, 0x0d, 0x78, 0x49, 0x2e, 0x84, + 0x6c, 0xc9, 0xe2, 0xf8, 0x7e, 0x49, 0x48, 0x74, 0x67, 0xcd, 0x75, 0x13, 0x31, 0x17, 0x55, 0xe5, + 0x9e, 0x5f, 0x56, 0xed, 0xf8, 0xd2, 0x3d, 0xbd, 0x00, 0x86, 0x82, 0x99, 0xe0, 0x84, 0xd4, 0x95, + 0x98, 0x85, 0x2c, 0x31, 0x09, 0x06, 0x05, 0x5b, 0xfd, 0x7d, 0x64, 0xf7, 0x71, 0xa4, 0x83, 0xd5, + 0xca, 0xfc, 0x69, 0x03, 0x7e, 0x87, 0xb9, 0x0e, 0x42, 0x5e, 0x2f, 0xc2, 0x7e, 0xab, 0x80, 0xb6, + 0xf4, 0x31, 0x2b, 0x60, 0x1b, 0x7d, 0xf1, 0xf5, 0x13, 0x59, 0xb3, 0x0f, 0xa0, 0x91, 0xcd, 0x92, + 0x67, 0x29, 0xc9, 0x84, 0xc8, 0x98, 0xff, 0x98, 0x6f, 0x4a, 0xb4, 0x18, 0xb1, 0xb3, 0x58, 0x25, + 0x0d, 0xe2, 0xdf, 0xa5, 0x0f, 0x59, 0xaf, 0xb2, 0xf0, 0xa1, 0x40, 0x9b, 0x23, 0x29, 0xe4, 0xc5, + 0x8e, 0xe6, 0x8e, 0x9c, 0x01, 0x1e, 0xcc, 0xc8, 0x4c, 0x64, 0x48, 0xc5, 0xa8, 0xc0, 0x91, 0x0a, + 0x48, 0xd2, 0x9c, 0xe2, 0x2a, 0xd9, 0x1c, 0xe7, 0x53, 0x42, 0x3d, 0xe6, 0x59, 0xc4, 0x51, 0xdf, + 0x8d, 0x12, 0x2e, 0x4c, 0x13, 0xee, 0x63, 0x77, 0x1f, 0xd0, 0x25, 0x52, 0x31, 0x79, 0x29, 0x35, + 0x2e, 0x4e, 0x75, 0x53, 0x1e, 0xe5, 0xa7, 0xfd, 0x39, 0x10, 0x23, 0xd9, 0x23, 0xef, 0xff, 0x19, + 0x79, 0x89, 0x6c, 0xf7, 0xf5, 0x54, 0x23, 0x29, 0xa3, 0x73, 0xdc, 0xeb, 0x87, 0x19, 0x78, 0x1f, + 0x10, 0x30, 0x4a, 0xb4, 0x26, 0xb2, 0xe5, 0x0d, 0x1f, 0xcc, 0x94, 0x7c, 0x00, 0x09, 0x3a, 0x0e, + 0x08, 0x66, 0x68, 0xd5, 0x80, 0x21, 0xa2, 0x03, 0x5f, 0x6d, 0xf8, 0x88, 0xf0, 0x23, 0x9c, 0x99, + 0xdd, 0x95, 0xb2, 0xfc, 0xb7, 0xe8, 0x42, 0x7f, 0x8f, 0x91, 0xa9, 0x9a, 0x58, 0x27, 0xc2, 0x6f, + 0x6b, 0x04, 0x89, 0x59, 0x34, 0x91, 0x2a, 0xa6, 0x38, 0xbc, 0x48, 0xce, 0x5d, 0x93, 0xb9, 0x3e, + 0x48, 0x62, 0x60, 0xac, 0xb9, 0xa3, 0x0b, 0x9f, 0x31, 0x81, 0xd5, 0xce, 0x03, 0x4c, 0x61, 0x8e, + 0x64, 0x85, 0x3a, 0x17, 0x5f, 0x5c, 0xbe, 0x08, 0xf7, 0xac, 0x15, 0xd1, 0xcc, 0x5f, 0x3c, 0x74, + 0xa6, 0xed, 0x37, 0xff, 0x39, 0x94, 0xfa, 0x7d, 0x2e, 0xd7, 0xfe, 0xaf, 0x5d, 0x5e, 0x5e, 0xaf, + 0xf5, 0xca, 0xba, 0xe7, 0x3e, 0x89, 0x8c, 0xa8, 0x46, 0x09, 0x0e, 0x88, 0x72, 0x20, 0xb4, 0x26, + 0x51, 0x18, 0x79, 0x44, 0x2a, 0x70, 0x9c, 0x3c, 0x95, 0x5f, 0xc4, 0xd1, 0x4e, 0x45, 0x0b, 0xf1, + 0x21, 0x48, 0xce, 0x55, 0x37, 0x1b, 0x4d, 0xd5, 0x6a, 0x31, 0x47, 0x65, 0xcb, 0x9e, 0xfa, 0xf8, + 0x52, 0x12, 0x1c, 0xea, 0xf0, 0x02, 0xcc, 0x16, 0x9b, 0x42, 0x3f, 0x78, 0xa0, 0x63, 0xc8, 0x89, + 0xc2, 0xad, 0xb5, 0x09, 0x80, 0x55, 0x7a, 0xd3, 0x0a, 0x43, 0xe4, 0x1d, 0xbc, 0xca, 0xf2, 0xf3, + 0x1e, 0x6e, 0x8c, 0x64, 0x5d, 0xe2, 0x42, 0x86, 0x2d, 0xfe, 0xa9, 0x1b, 0x17, 0x43, 0x50, 0xd7, + 0x4d, 0x4b, 0xe3, 0xd2, 0x2e, 0x08, 0x01, 0xc3, 0xde, 0x43, 0xbc, 0x06, 0x2c, 0xbb, 0x61, 0x15, + 0x86, 0xb6, 0x2c, 0x80, 0xa6, 0x1e, 0x3b, 0xf0, 0xa1, 0xeb, 0x2c, 0xa8, 0x46, 0xa9, 0x35, 0x0c, + 0x76, 0x92, 0x7d, 0x89, 0x7d, 0x45, 0xb1, 0x59, 0x63, 0x15, 0xdd, 0x0e, 0xef, 0x12, 0x0a, 0x4f, + 0xe8, 0x3c, 0x4f, 0x4c, 0xf9, 0x8f, 0xad, 0x19, 0x73, 0x17, 0x51, 0x1f, 0x29, 0x7c, 0x48, 0x53, + 0x26, 0xa2, 0xec, 0xce, 0x8c, 0xcc, 0x14, 0x6f, 0x36, 0xb5, 0x05, 0x87, 0xcf, 0xf0, 0x57, 0xf2, + 0x43, 0x71, 0xb6, 0xf9, 0xc4, 0x15, 0x6f, 0xba, 0xb2, 0xf8, 0x28, 0xda, 0x39, 0x0f, 0x94, 0x3a, + 0xd7, 0x7c, 0x25, 0x77, 0x3a, 0x9d, 0xb2, 0xf2, 0x75, 0x3a, 0xa8, 0x91, 0x23, 0x21, 0x98, 0x80, + 0x83, 0xbd, 0xf3, 0xba, 0x48, 0x53, 0x07, 0x5f, 0x1e, 0xb0, 0x1d, 0xbc, 0x29, 0x43, 0x5a, 0x4b, + 0x64, 0x24, 0x22, 0x54, 0x7a, 0x9c, 0x48, 0x91, 0x03, 0x3d, 0x87, 0x1a, 0x6c, 0x3d, 0xdd, 0x41, + 0x3f, 0x3c, 0x5c, 0x1a, 0xb3, 0x24, 0x00, 0xd6, 0x9b, 0x84, 0xcb, 0x73, 0x71, 0x97, 0xf0, 0x50, + 0x11, 0x4a, 0x62, 0xbc, 0xd6, 0x97, 0xc8, 0x4b, 0xa3, 0x77, 0xd1, 0x72, 0xfa, 0xc5, 0x7d, 0x12, + 0x05, 0x5e, 0xac, 0x1f, 0x44, 0x62, 0x5e, 0xb1, 0x49, 0xcd, 0xdc, 0x4b, 0x98, 0x98, 0xda, 0x36, + 0x29, 0xd4, 0x4f, 0xdb, 0xa9, 0x03, 0x6c, 0xcb, 0x50, 0xed, 0xae, 0xc2, 0x5d, 0xc3, 0xac, 0x4f, + 0x1d, 0xa4, 0x3b, 0x3a, 0x99, 0x77, 0xfe, 0x14, 0x34, 0xbc, 0x65, 0x91, 0xc9, 0x06, 0x03, 0xed, + 0xb5, 0x3a, 0x5d, 0xbc, 0x4f, 0xc2, 0xa5, 0xb3, 0x24, 0x5e, 0x30, 0xaf, 0xae, 0x4c, 0x27, 0x73, + 0xb1, 0x64, 0xd9, 0x31, 0xeb, 0xe9, 0x3f, 0xc1, 0x59, 0x46, 0xd2, 0x68, 0x98, 0xa2, 0x37, 0x31, + 0xd0, 0x91, 0xaa, 0xfe, 0xf8, 0x28, 0xb1, 0x9f, 0x38, 0xc0, 0x80, 0xf3, 0xdf, 0x1a, 0x28, 0xb7, + 0x8a, 0xd0, 0x13, 0x59, 0x25, 0x29, 0x00, 0x5e, 0x43, 0xfa, 0xa2, 0x20, 0x61, 0xbd, 0x84, 0xaf, + 0x73, 0x92, 0x23, 0xd9, 0x6a, 0x06, 0x77, 0xf8, 0x2b, 0x9f, 0xff, 0x25, 0x60, 0x26, 0xd6, 0x9b, + 0x6e, 0x63, 0xaf, 0x5c, 0x53, 0x6b, 0xa6, 0x32, 0x68, 0xdc, 0x2d, 0x32, 0xf0, 0xa5, 0x9c, 0x9b, + 0x90, 0xd8, 0x32, 0x7c, 0x98, 0x52, 0x41, 0x89, 0x99, 0x68, 0x9f, 0x08, 0x7b, 0xc8, 0x54, 0x3d, + 0xa5, 0xb7, 0x49, 0x7c, 0x02, 0x96, 0xbc, 0x00, 0x04, 0x11, 0x27, 0xc2, 0xe3, 0x32, 0x42, 0x0e, + 0x32, 0x5c, 0xf9, 0x16, 0x19, 0x66, 0x29, 0x53, 0xe1, 0x02, 0xcc, 0x60, 0xcf, 0x6a, 0x39, 0x1c, + 0x49, 0x52, 0x4c, 0x76, 0x20, 0x80, 0xdf, 0x5c, 0x0c, 0xcd, 0x45, 0xc5, 0x0a, 0x12, 0xd6, 0xa9, + 0x59, 0xe0, 0xb4, 0xd2, 0xec, 0xf1, 0x36, 0xed, 0x8b, 0xb1, 0x83, 0xbe, 0x4e, 0xff, 0x30, 0x9d, + 0x48, 0xcf, 0x96, 0x9d, 0xf5, 0xf8, 0xcb, 0x0c, 0x8c, 0x4c, 0x08, 0x0b, 0x04, 0x17, 0x50, 0xa3, + 0x88, 0x1b, 0xb8, 0x67, 0x42, 0xe0, 0x70, 0x14, 0x4d, 0x46, 0x11, 0x42, 0xbc, 0x64, 0xba, 0x6c, + 0x2f, 0x05, 0x9c, 0xac, 0x5c, 0x56, 0x7a, 0x1e, 0xfb, 0xec, 0xd2, 0xf8, 0x90, 0x91, 0x65, 0x31, + 0x62, 0xae, 0x36, 0x81, 0x08, 0xb7, 0xe0, 0xb7, 0xc8, 0xa2, 0x24, 0x70, 0x4b, 0x82, 0xbb, 0x4f, + 0xc4, 0x08, 0xf8, 0x2a, 0x11, 0xd5, 0x63, 0x43, 0x07, 0x00, 0x85, 0x62, 0xb0, 0xdb, 0xcf, 0xc2, + 0x86, 0x70, 0x88, 0x90, 0x54, 0x22, 0xa1, 0x0b, 0x43, 0x5b, 0x15, 0xb4, 0xed, 0xd3, 0x38, 0xc1, + 0x30, 0x86, 0x68, 0xfb, 0xe0, 0x8a, 0xee, 0x97, 0x10, 0xf0, 0x46, 0x11, 0x07, 0x7f, 0x0c, 0xb8, + 0x3b, 0xd4, 0xdc, 0x12, 0x0e, 0x97, 0x7e, 0x8f, 0xe8, 0x58, 0xea, 0xfa, 0x92, 0xf8, 0x50, 0xec, + 0x57, 0x39, 0x54, 0x92, 0xfb, 0x4d, 0x6d, 0x34, 0x9d, 0x7a, 0x2a, 0x75, 0xe7, 0x23, 0x1f, 0x4d, + 0x33, 0x1d, 0x71, 0xdf, 0x52, 0x81, 0x9f, 0xa2, 0x37, 0xd5, 0xbe, 0xad, 0xf5, 0x72, 0xb9, 0x4a, + 0x92, 0x48, 0x1f, 0xc6, 0xd2, 0x4b, 0x76, 0x0d, 0x3b, 0x4d, 0x68, 0x41, 0x41, 0x4c, 0x19, 0x01, + 0xeb, 0x17, 0xa2, 0x63, 0x52, 0x73, 0xf6, 0xfc, 0x23, 0x05, 0x83, 0x16, 0x92, 0x8c, 0xac, 0xe4, + 0xbd, 0x3d, 0xf9, 0x12, 0xc0, 0x7f, 0xc1, 0x4c, 0x43, 0xcb, 0x76, 0x2b, 0xb1, 0x5b, 0xcb, 0x9b, + 0xbb, 0x7c, 0x7c, 0x56, 0x16, 0x63, 0x5e, 0x93, 0x95, 0x93, 0xd6, 0xb3, 0xc9, 0x8b, 0x11, 0xd4, + 0x80, 0xed, 0xe3, 0xe2, 0x01, 0x4f, 0x8e, 0x49, 0x97, 0xbe, 0xcf, 0x75, 0x72, 0xf1, 0x20, 0xac, + 0xe8, 0x29, 0xdb, 0x1a, 0x11, 0x13, 0x40, 0xbc, 0xcc, 0x7c, 0xf1, 0x00, 0xa8, 0x8e, 0xee, 0xd9, + 0xb0, 0x44, 0x83, 0xb2, 0x66, 0x76, 0x07, 0xb8, 0xd7, 0x3f, 0xda, 0x76, 0xf8, 0x50, 0x84, 0xb2, + 0x09, 0xd2, 0xa8, 0xdd, 0xc8, 0x25, 0xd9, 0x96, 0xff, 0x6c, 0x46, 0x79, 0x44, 0x47, 0x2e, 0xc1, + 0x92, 0x30, 0x02, 0x3e, 0xc3, 0x56, 0x93, 0x2a, 0x32, 0xf1, 0x97, 0xaf, 0x74, 0x0b, 0xff, 0xe2, + 0x06, 0xec, 0x78, 0xb7, 0xc6, 0x28, 0x72, 0x03, 0xd2, 0x25, 0xa8, 0xf3, 0xc9, 0x7a, 0x69, 0xc6, + 0x5c, 0x04, 0xda, 0x8b, 0xcb, 0xc7, 0x09, 0x81, 0xaa, 0x23, 0xf0, 0xbc, 0xda, 0xcd, 0xfc, 0x40, + 0xf9, 0x55, 0xf9, 0xe1, 0x49, 0xc8, 0x84, 0xd7, 0x97, 0xcb, 0x2c, 0x90, 0x58, 0xae, 0xe9, 0x22, + 0xc6, 0x58, 0xc5, 0x62, 0xbf, 0x1c, 0x53, 0x3c, 0x00, 0x5b, 0x2f, 0xa9, 0x7f, 0x53, 0xb6, 0x11, + 0x15, 0x6d, 0x32, 0xa8, 0x79, 0x16, 0xd6, 0xa9, 0xeb, 0x1e, 0x11, 0x2b, 0x3e, 0xb6, 0x72, 0x4a, + 0x6a, 0x94, 0x61, 0x8f, 0x13, 0x04, 0xb4, 0x6c, 0x04, 0x6a, 0x51, 0x88, 0xda, 0x58, 0x84, 0x10, + 0x29, 0xfe, 0x3c, 0xad, 0x19, 0xda, 0x13, 0x19, 0x4c, 0xa0, 0x86, 0xcb, 0x86, 0xd1, 0xab, 0xa6, + 0x91, 0x2a, 0x94, 0x3e, 0xce, 0x2f, 0x05, 0x44, 0x58, 0x18, 0x0f, 0xd2, 0x40, 0x2b, 0xdd, 0x0d, + 0xf7, 0xf1, 0x15, 0xc1, 0x5c, 0x86, 0x35, 0x62, 0x97, 0x91, 0x46, 0xf3, 0x86, 0x02, 0x5e, 0x8e, + 0x0f, 0x89, 0x05, 0x9a, 0x4c, 0xb5, 0xd0, 0x9e, 0x27, 0x3a, 0xc1, 0xaa, 0x69, 0x5c, 0x0f, 0x7b, + 0xff, 0xc6, 0xe3, 0x99, 0x06, 0x97, 0xaa, 0x7d, 0x22, 0xca, 0x7f, 0xd0, 0x33, 0x4d, 0x6f, 0xeb, + 0x24, 0xa7, 0xbe, 0xdd, 0xdb, 0xc2, 0x22, 0x41, 0x6c, 0xe1, 0x81, 0x03, 0x39, 0x0d, 0xeb, 0xb1, + 0xb0, 0x43, 0xa3, 0x1b, 0x9f, 0x05, 0x43, 0x08, 0x97, 0xe1, 0xfe, 0x50, 0x9d, 0x44, 0xa8, 0x65, + 0x02, 0xf4, 0x89, 0x9c, 0x1f, 0x0c, 0x15, 0xb8, 0x86, 0x82, 0xbc, 0x74, 0xc9, 0xdd, 0xf9, 0xcc, + 0x97, 0x7f, 0xd0, 0x55, 0x2a, 0x5d, 0x04, 0x99, 0x11, 0xd0, 0x96, 0x3e, 0xba, 0xfa, 0x36, 0xc7, + 0xd6, 0x57, 0xd1, 0xf2, 0xf8, 0x23, 0xb9, 0x88, 0x2b, 0xd5, 0xf5, 0xce, 0x7d, 0x73, 0x9f, 0x5c, + 0xe7, 0xd4, 0x7d, 0x27, 0x47, 0x73, 0xe0, 0x8a, 0xdd, 0xbb, 0x85, 0xd4, 0xa9, 0xc4, 0xc2, 0x83, + 0x2a, 0xa8, 0xb1, 0x85, 0x64, 0xdc, 0xcc, 0xa1, 0x36, 0x36, 0xa8, 0xdb, 0xe3, 0x67, 0x3c, 0xb6, + 0x58, 0x31, 0x5d, 0x3b, 0x9c, 0xc6, 0xbb, 0x98, 0x92, 0x4e, 0x7d, 0x59, 0xc8, 0xf8, 0xfa, 0x63, + 0xff, 0xe1, 0x48, 0xf6, 0xdb, 0x94, 0xf4, 0x71, 0x99, 0x3b, 0x68, 0x73, 0x35, 0xce, 0x30, 0x58, + 0x04, 0x3d, 0xa5, 0x7c, 0x28, 0x64, 0x89, 0x49, 0x94, 0x1f, 0x50, 0xca, 0x9f, 0xfd, 0x71, 0x73, + 0xcc, 0x07, 0x24, 0x2f, 0x63, 0x1a, 0xf8, 0x2b, 0x3c, 0x1b, 0x93, 0x6d, 0xef, 0x6f, 0x64, 0xac, + 0xff, 0x4e, 0x31, 0xdf, 0x0a, 0x15, 0xc5, 0x6e, 0x2b, 0x7a, 0xd0, 0x91, 0x51, 0x8e, 0x20, 0x89, + 0x8c, 0x9e, 0x9b, 0x1e, 0x24, 0x16, 0x08, 0xaa, 0x61, 0xb0, 0x38, 0x4c, 0x11, 0x89, 0xf0, 0xcb, + 0x5b, 0x2e, 0xbb, 0x18, 0x50, 0xc6, 0x6f, 0x85, 0x24, 0x47, 0x43, 0x50, 0xe8, 0x3c, 0x5c, 0xb0, + 0xfc, 0x24, 0x68, 0x6d, 0xc7, 0x86, 0xfd, 0x21, 0x61, 0xb3, 0x27, 0xb9, 0x49, 0x78, 0xba, 0xb1, + 0xe2, 0x43, 0xa5, 0x18, 0xa5, 0x35, 0x03, 0x46, 0x25, 0x45, 0xc0, 0x73, 0xce, 0xa1, 0x61, 0x51, + 0xda, 0x15, 0xd3, 0x58, 0xbd, 0x0b, 0x67, 0xf5, 0xff, 0x82, 0xcb, 0x8d, 0x8b, 0x81, 0x75, 0x62, + 0x05, 0xb4, 0x6d, 0x1d, 0x57, 0xd4, 0xe7, 0x0f, 0x73, 0xfc, 0x4c, 0x71, 0x69, 0xc4, 0xf9, 0x6a, + 0xaf, 0x5d, 0x1b, 0x16, 0x5a, 0xf9, 0xae, 0x2b, 0x15, 0x8a, 0xf1, 0x02, 0x07, 0x9f, 0x29, 0x88, + 0x61, 0x89, 0x0a, 0xc4, 0x30, 0x39, 0xc2, 0x45, 0xc0, 0x40, 0x00, 0x0e, 0xbf, 0x10, 0x44, 0x06, + 0x52, 0xd3, 0x92, 0xa0, 0x60, 0x09, 0xee, 0x59, 0x6f, 0x88, 0x05, 0x06, 0x15, 0xb8, 0xae, 0x55, + 0x52, 0xed, 0xbe, 0x52, 0xbd, 0x0d, 0x17, 0x8f, 0x39, 0xd1, 0x66, 0x52, 0x45, 0x09, 0xb5, 0x4f, + 0x6e, 0xde, 0x26, 0x3c, 0x56, 0xb5, 0x2f, 0x93, 0x77, 0x52, 0x50, 0x81, 0x37, 0x76, 0xe2, 0x61, + 0x42, 0x8f, 0xfa, 0xe4, 0xd9, 0xa4, 0xc1, 0x27, 0x0f, 0x2a, 0xf9, 0x68, 0xd2, 0xbb, 0xfc, 0x29, + 0x45, 0x81, 0x9e, 0xfe, 0xc6, 0x4c, 0x3b, 0x41, 0xef, 0x28, 0x3c, 0xd6, 0x8e, 0x81, 0x3e, 0x8f, + 0xca, 0xaa, 0x3d, 0xc2, 0x02, 0x02, 0x87, 0x2a, 0xed, 0x53, 0xe5, 0x29, 0x02, 0x07, 0x58, 0xac, + 0xd1, 0x29, 0x96, 0x7d, 0xa7, 0x42, 0x90, 0x91, 0x28, 0x15, 0x01, 0xa5, 0x9e, 0x45, 0x33, 0x62, + 0xc1, 0x2a, 0x37, 0x08, 0x02, 0xac, 0x88, 0x5b, 0xbf, 0x13, 0x18, 0x6b, 0x49, 0x12, 0xad, 0x4d, + 0x49, 0x8a, 0xfd, 0xb6, 0x8d, 0x4b, 0x89, 0x2f, 0x7c, 0x5a, 0xc7, 0x85, 0x05, 0x1e, 0x9a, 0x74, + 0x65, 0x93, 0x58, 0xae, 0xc6, 0x96, 0xb6, 0x8f, 0x67, 0x3f, 0x1a, 0xd7, 0x7f, 0x82, 0xbc, 0xb9, + 0x71, 0x92, 0x89, 0x8b, 0x2d, 0x8a, 0xde, 0x47, 0xdf, 0xec, 0xf7, 0xa7, 0xe5, 0x22, 0x49, 0x6f, + 0xa2, 0x65, 0x2f, 0x45, 0x8a, 0x6e, 0x72, 0xaa, 0x49, 0x24, 0x97, 0xae, 0xb1, 0x57, 0x56, 0xfa, + 0xc6, 0xfa, 0xef, 0x7d, 0x63, 0xdf, 0x45, 0xf1, 0xf5, 0x28, 0xb8, 0x98, 0x2c, 0x9f, 0x06, 0xea, + 0x36, 0xef, 0x7c, 0x2a, 0xe1, 0xc7, 0x6e, 0x55, 0xf8, 0x90, 0xa1, 0x94, 0xf8, 0x91, 0x8c, 0x32, + 0x56, 0xec, 0xe9, 0x1e, 0x8c, 0x11, 0x5d, 0x1b, 0x59, 0x52, 0x3a, 0xd7, 0x4d, 0xa0, 0x1c, 0x12, + 0x3f, 0x05, 0x25, 0x47, 0xa0, 0x1b, 0xa1, 0x8a, 0xca, 0xec, 0xf0, 0xb7, 0x08, 0x60, 0x22, 0x7f, + 0x8c, 0xd9, 0x6d, 0x32, 0xd0, 0x3c, 0x2e, 0x22, 0xfd, 0x67, 0x58, 0x51, 0xf4, 0x47, 0x34, 0xb1, + 0x0a, 0x47, 0x90, 0x4f, 0x1e, 0xd2, 0x0f, 0x10, 0x14, 0x15, 0x26, 0xc1, 0x21, 0xa1, 0x39, 0x44, + 0xa7, 0x7d, 0x8c, 0x13, 0x18, 0x87, 0x40, 0x74, 0x5c, 0xbc, 0xbc, 0x57, 0x42, 0x2a, 0x4b, 0xf0, + 0xa0, 0x92, 0x8b, 0x41, 0x52, 0xf5, 0x80, 0xe5, 0xed, 0x51, 0xb3, 0xf1, 0x36, 0xc6, 0xbb, 0x1f, + 0x0a, 0x16, 0x0d, 0x99, 0x0a, 0x39, 0xc2, 0xb7, 0x5e, 0xe0, 0xbb, 0x6b, 0x07, 0x83, 0xfd, 0x19, + 0x7e, 0xfd, 0xe2, 0x01, 0x50, 0x8e, 0x4c, 0x07, 0xfd, 0xfc, 0xe7, 0x8e, 0xbd, 0x75, 0xca, 0x7d, + 0x2f, 0x97, 0xc2, 0x97, 0x66, 0xb7, 0x43, 0x96, 0x19, 0x99, 0x46, 0xc4, 0xd8, 0xf5, 0xe2, 0x6c, + 0x37, 0x2e, 0x7c, 0x17, 0x59, 0xf9, 0xad, 0x58, 0x3d, 0x78, 0x80, 0x58, 0x2c, 0x2e, 0xb8, 0x0b, + 0x7c, 0xe7, 0x98, 0x36, 0xc7, 0x6e, 0x9d, 0x23, 0xe2, 0x02, 0x97, 0xe5, 0x41, 0x39, 0x06, 0xc7, + 0x2b, 0x07, 0x10, 0x39, 0x14, 0xb5, 0x76, 0xf4, 0xfe, 0x24, 0x12, 0x58, 0xdb, 0x3b, 0x3f, 0x78, + 0x80, 0x84, 0xee, 0x15, 0x89, 0x58, 0x3d, 0xc2, 0xc6, 0x73, 0x8e, 0x5b, 0x66, 0xc2, 0x32, 0x5f, + 0xc5, 0x9a, 0x46, 0x50, 0x38, 0xb4, 0xdf, 0xc2, 0x92, 0x65, 0xc5, 0xd5, 0x8f, 0xbd, 0xca, 0x66, + 0x73, 0x47, 0x7f, 0x84, 0x45, 0xe9, 0x19, 0xed, 0x46, 0x32, 0x60, 0x40, 0x19, 0xcf, 0xa1, 0xa9, + 0xa7, 0x8a, 0xe9, 0x36, 0x35, 0x5c, 0x13, 0x3f, 0xe0, 0xb4, 0x72, 0xb9, 0x48, 0xd1, 0x23, 0xa9, + 0xbe, 0xdf, 0x0a, 0x1c, 0xbc, 0x44, 0x60, 0x8f, 0x61, 0x89, 0x04, 0xd4, 0x6c, 0x55, 0x70, 0xac, + 0x61, 0xe8, 0xdd, 0xae, 0xe4, 0xec, 0x51, 0x4f, 0xce, 0x20, 0x40, 0xa2, 0xe5, 0x63, 0x9c, 0xd2, + 0x2c, 0x48, 0x91, 0xe5, 0x39, 0x50, 0x7a, 0xa0, 0x2a, 0x86, 0x02, 0x72, 0x10, 0x04, 0xb6, 0x2b, + 0x27, 0x40, 0x01, 0x0e, 0x48, 0x28, 0x84, 0x4e, 0x16, 0x32, 0xd8, 0xaf, 0x12, 0x24, 0x69, 0x19, + 0x16, 0x88, 0x58, 0xe2, 0xd5, 0xde, 0x56, 0x4d, 0x6e, 0xc4, 0xfa, 0x31, 0x1b, 0xe8, 0x3f, 0xa4, + 0x5a, 0x04, 0x53, 0x14, 0xef, 0xde, 0xed, 0x61, 0x11, 0x22, 0x24, 0xcb, 0x8a, 0xc2, 0x21, 0x74, + 0xa5, 0x94, 0x5c, 0xb1, 0xe2, 0x44, 0x87, 0x86, 0x5a, 0x69, 0xa7, 0xe0, 0x7c, 0x8e, 0xa5, 0xb9, + 0xa4, 0xe3, 0x79, 0x4f, 0x97, 0x67, 0xa7, 0xf8, 0x5b, 0x76, 0x94, 0x9c, 0xa4, 0x3a, 0x43, 0xd0, + 0x99, 0xd1, 0x28, 0xb7, 0x4a, 0xc0, 0x4b, 0xbb, 0xdf, 0x31, 0xcd, 0x54, 0xe5, 0x67, 0xcf, 0x56, + 0xdb, 0x69, 0xaf, 0x5d, 0x65, 0x19, 0xd5, 0xc9, 0x3a, 0x3f, 0x7c, 0x92, 0x71, 0xd5, 0x2e, 0x4f, + 0xa8, 0xe8, 0x7d, 0x62, 0xf9, 0x2a, 0xd3, 0xb5, 0xe0, 0x87, 0x77, 0x47, 0xdf, 0x25, 0xc5, 0x6e, + 0xfe, 0x34, 0xc9, 0x87, 0x16, 0x22, 0xe2, 0x99, 0x21, 0x23, 0x2b, 0x0b, 0x59, 0x66, 0xc3, 0x40, + 0x2e, 0xc0, 0x66, 0x5b, 0x0a, 0xd9, 0x56, 0xc1, 0x66, 0xff, 0x97, 0x84, 0xdf, 0xd4, 0xf0, 0x1c, + 0x5f, 0xfc, 0x29, 0x3b, 0x8a, 0x17, 0xe5, 0x4c, 0x20, 0x38, 0xba, 0x63, 0x4f, 0x2d, 0xb1, 0x1c, + 0x30, 0xcb, 0x7f, 0x8c, 0xcc, 0x95, 0xc7, 0xb4, 0xe5, 0xb7, 0xbb, 0x8a, 0xc5, 0x68, 0xf1, 0x10, + 0xa4, 0xbc, 0x5d, 0x45, 0xf4, 0xd0, 0x23, 0x15, 0x51, 0x75, 0x52, 0x28, 0x75, 0x27, 0xef, 0x12, + 0x34, 0x44, 0x9f, 0xf8, 0xba, 0x4a, 0x27, 0xb9, 0x46, 0x1f, 0x09, 0xbc, 0xdd, 0xdb, 0x54, 0x97, + 0xb3, 0xe4, 0x7a, 0xfe, 0x0a, 0x46, 0xba, 0x5b, 0x46, 0x0a, 0x1b, 0xb9, 0x48, 0xeb, 0x3f, 0x9b, + 0x63, 0xad, 0x3f, 0xc1, 0x2c, 0xf5, 0x45, 0x8a, 0xc5, 0x62, 0xb7, 0x71, 0x0a, 0x4e, 0x7e, 0x26, + 0x14, 0x22, 0x60, 0xc7, 0xa3, 0x54, 0x3e, 0x24, 0xe0, 0x6c, 0x2e, 0x45, 0x2c, 0xd8, 0xcb, 0x96, + 0xc5, 0x6e, 0xad, 0x90, 0xbc, 0xf7, 0x12, 0x21, 0x51, 0x82, 0xb8, 0x90, 0x4b, 0xe4, 0xe6, 0x4b, + 0x5e, 0xfa, 0xf1, 0x20, 0xac, 0xf0, 0x65, 0xb6, 0x2c, 0x3a, 0xa1, 0xad, 0x75, 0x16, 0xa6, 0x92, + 0xab, 0x78, 0x80, 0x44, 0x4c, 0x82, 0x02, 0xe7, 0xbc, 0x48, 0x2c, 0x38, 0xf1, 0x23, 0xd4, 0x56, + 0x5e, 0x17, 0x14, 0xc1, 0x6c, 0xfc, 0xb6, 0x5b, 0x71, 0xaa, 0x7c, 0x17, 0x18, 0x43, 0x8d, 0x0c, + 0x05, 0xb4, 0xa9, 0xb7, 0xbb, 0xfd, 0xc8, 0xc4, 0x99, 0x41, 0x7f, 0x86, 0x0b, 0xb9, 0x7e, 0x5a, + 0xea, 0xef, 0x4f, 0xfc, 0x16, 0x1f, 0x87, 0x94, 0x6c, 0x9b, 0x1e, 0xb3, 0xb9, 0x7c, 0x37, 0xc6, + 0x4a, 0xbc, 0x11, 0x9a, 0x85, 0x95, 0x42, 0x7f, 0x10, 0x14, 0x10, 0x72, 0xb1, 0xe4, 0xa7, 0x1d, + 0xc7, 0x23, 0x25, 0xea, 0x2d, 0x83, 0x0b, 0x38, 0xd3, 0x88, 0x61, 0xb3, 0xfc, 0x44, 0x20, 0x2d, + 0x59, 0x55, 0x00, 0x34, 0x33, 0x95, 0x19, 0x1e, 0x4c, 0x0c, 0x26, 0xee, 0x02, 0xbd, 0x0d, 0x90, + 0x89, 0x08, 0xa7, 0x45, 0x3f, 0x55, 0x96, 0x24, 0x48, 0x2a, 0x34, 0xb4, 0xb1, 0xbf, 0x9c, 0x88, + 0x09, 0x20, 0xe0, 0xe6, 0x9b, 0xbb, 0xd1, 0xc7, 0x84, 0x04, 0x0c, 0x12, 0x58, 0x0c, 0xf9, 0xa5, + 0xd3, 0xa2, 0xc1, 0x6e, 0xa4, 0x52, 0xbc, 0x82, 0xe2, 0x2b, 0x02, 0xc5, 0x40, 0xb4, 0xa0, 0xdc, + 0x8a, 0x83, 0x5a, 0xf2, 0x35, 0xe0, 0xde, 0x7c, 0x20, 0x20, 0x61, 0x22, 0x75, 0x0b, 0xdd, 0x43, + 0xf9, 0xd8, 0xe1, 0xac, 0x18, 0xd9, 0x18, 0x56, 0x18, 0xf6, 0xca, 0x30, 0x9b, 0x30, 0xee, 0x62, + 0x61, 0x42, 0x84, 0x76, 0x50, 0x1e, 0xc1, 0xf4, 0xc5, 0x4c, 0x01, 0x33, 0xe3, 0xed, 0xc7, 0x96, + 0xbf, 0x97, 0x86, 0x36, 0x84, 0xd3, 0xe6, 0xac, 0x10, 0x2f, 0x0c, 0x15, 0x2f, 0xca, 0x93, 0xfc, + 0x49, 0xa6, 0x5f, 0xcc, 0xc7, 0xc7, 0x88, 0x52, 0xfc, 0xec, 0x75, 0x13, 0xff, 0x85, 0x6c, 0x1b, + 0x06, 0x18, 0x60, 0x64, 0xe4, 0xe9, 0xe5, 0x03, 0xbd, 0xd1, 0xec, 0xff, 0xd1, 0xd8, 0xfa, 0xa0, + 0x03, 0xeb, 0x87, 0xd7, 0xe3, 0xd7, 0x2a, 0xe0, 0x8a, 0xa8, 0xff, 0xbe, 0xa8, 0x06, 0x93, 0x8c, + 0xdd, 0x55, 0xdd, 0x56, 0x81, 0x96, 0xea, 0x77, 0xfd, 0x62, 0xfa, 0xd7, 0xc9, 0x55, 0x66, 0xcf, + 0xd6, 0x2f, 0xaf, 0x5f, 0x56, 0xfa, 0xe6, 0xfa, 0xb5, 0x72, 0xd8, 0xe9, 0x99, 0x6f, 0x44, 0xce, + 0xae, 0x09, 0x30, 0x67, 0xc4, 0x90, 0x14, 0x1d, 0xf0, 0x53, 0xa3, 0x77, 0x75, 0x42, 0x02, 0xce, + 0x77, 0x35, 0x4e, 0x92, 0x18, 0x3b, 0x7f, 0xff, 0xe0, 0xa7, 0xb6, 0xdb, 0x35, 0xb7, 0xa9, 0xb2, + 0x37, 0xf8, 0x50, 0xe3, 0x1c, 0x76, 0x87, 0x68, 0x5e, 0xc6, 0x25, 0x90, 0xc9, 0x92, 0x35, 0xc5, + 0xfb, 0x19, 0x72, 0xc7, 0x7f, 0xc2, 0x94, 0xea, 0xba, 0x8f, 0x58, 0x6e, 0x6a, 0x09, 0xb0, 0x7d, + 0x96, 0xe9, 0xfe, 0x8e, 0xfc, 0x16, 0x0a, 0x62, 0xd5, 0x78, 0xcc, 0x2c, 0x95, 0x71, 0x8b, 0xb2, + 0x6f, 0x84, 0xc6, 0xdc, 0x7d, 0x5e, 0x54, 0xe8, 0x37, 0xf0, 0xa7, 0x31, 0xf4, 0xcb, 0x42, 0x0c, + 0x30, 0xe8, 0x21, 0xe0, 0x00, 0x1a, 0xd5, 0x72, 0x3c, 0x89, 0x9a, 0xb8, 0xe2, 0x53, 0xf1, 0x10, + 0xa5, 0xd0, 0xf1, 0x2f, 0x1c, 0x10, 0x24, 0x98, 0x96, 0xee, 0xcb, 0x63, 0x59, 0xc9, 0x92, 0x6b, + 0x9c, 0x4c, 0x6e, 0x6a, 0x8a, 0x0d, 0x43, 0x18, 0xe0, 0x78, 0x3c, 0x0f, 0x09, 0x40, 0x81, 0x7e, + 0xc2, 0x07, 0x72, 0x0b, 0xcf, 0x7b, 0xd8, 0xea, 0xff, 0xe0, 0xa6, 0xf8, 0x09, 0x70, 0xf5, 0x85, + 0xe2, 0x02, 0x41, 0x60, 0xfa, 0xe3, 0x18, 0xa2, 0x3e, 0xa8, 0x11, 0x18, 0xf4, 0x70, 0x7e, 0x09, + 0xcc, 0x9b, 0x64, 0x66, 0xb6, 0x75, 0x94, 0x1c, 0x44, 0x16, 0x09, 0x15, 0xb8, 0x87, 0x0f, 0x7a, + 0xad, 0xa3, 0xd5, 0x07, 0xbe, 0xce, 0x69, 0x97, 0x88, 0x05, 0x91, 0x5b, 0x8a, 0xc4, 0xbf, 0x6c, + 0xc2, 0x58, 0xe2, 0xff, 0xf8, 0x24, 0x31, 0x7f, 0x63, 0xeb, 0xdf, 0x05, 0x25, 0x2f, 0xe8, 0xa7, + 0x50, 0x52, 0x35, 0x0e, 0x61, 0xcc, 0xb3, 0xb7, 0xf7, 0xcd, 0x4e, 0x3a, 0x79, 0x74, 0x7c, 0x13, + 0x98, 0x7a, 0xc4, 0xb9, 0x44, 0xcd, 0x48, 0xd5, 0x3f, 0xf0, 0xa4, 0x60, 0x85, 0x27, 0x60, 0xe8, + 0x0e, 0xab, 0xfb, 0xb4, 0xb7, 0x17, 0x97, 0x2f, 0x74, 0x71, 0xf1, 0x21, 0x23, 0xea, 0x0e, 0x86, + 0xd6, 0x04, 0x4e, 0xc1, 0x7c, 0x40, 0x80, 0xa5, 0x94, 0x0b, 0xd2, 0x28, 0xd5, 0x5f, 0x61, 0xe4, + 0x76, 0x12, 0x4e, 0x57, 0xe2, 0x24, 0x38, 0x24, 0x16, 0x03, 0x03, 0x40, 0x99, 0xaf, 0x84, 0xaa, + 0x55, 0x90, 0x06, 0xf8, 0x52, 0x7e, 0x49, 0x2e, 0x41, 0x2c, 0x63, 0xd7, 0x31, 0x9a, 0x04, 0x01, + 0xf5, 0xa7, 0x14, 0x6a, 0xc0, 0x15, 0x4e, 0xd2, 0x99, 0xb4, 0x38, 0xe3, 0xb7, 0xa2, 0xaa, 0xa4, + 0x89, 0xb8, 0x44, 0x48, 0x2a, 0x96, 0xce, 0x41, 0x00, 0x42, 0x65, 0xde, 0x8c, 0xec, 0x5b, 0x9b, + 0xc4, 0x06, 0x44, 0xa4, 0x0c, 0x2a, 0xa0, 0x9d, 0x5c, 0x44, 0x12, 0xcc, 0x1d, 0x52, 0x4a, 0x41, + 0x77, 0xb6, 0xff, 0x74, 0x22, 0x28, 0xfc, 0x13, 0xf3, 0xb1, 0x15, 0x8a, 0xc5, 0x62, 0xbe, 0xf1, + 0x01, 0x71, 0x09, 0x86, 0x9a, 0x98, 0xb9, 0x2f, 0xec, 0xe6, 0x42, 0x09, 0xd0, 0xed, 0x18, 0x3b, + 0x52, 0x83, 0xff, 0x0d, 0xc2, 0x21, 0xfd, 0x28, 0x0d, 0xc8, 0x26, 0xc2, 0x47, 0x31, 0x67, 0xb3, + 0x66, 0x06, 0xfb, 0x17, 0xfe, 0x72, 0xe4, 0x05, 0x51, 0x0b, 0x21, 0x65, 0xff, 0x53, 0x25, 0x75, + 0x8a, 0xba, 0xb1, 0xf5, 0x61, 0xe0, 0x86, 0xcd, 0xa6, 0x91, 0xff, 0xe8, 0x8f, 0x2f, 0x57, 0xfa, + 0xfc, 0xbe, 0xbe, 0x2f, 0xa2, 0xb9, 0xf4, 0x5e, 0xf8, 0xac, 0xb2, 0x39, 0x3a, 0x4c, 0x9d, 0x0f, + 0xe6, 0x31, 0xf2, 0x62, 0x0d, 0x44, 0xc1, 0x04, 0xec, 0x9c, 0xf1, 0xe5, 0xc4, 0xbd, 0x98, 0x55, + 0x56, 0x51, 0x7c, 0x3e, 0x69, 0x66, 0x2e, 0xa8, 0x1c, 0xb3, 0xc4, 0x86, 0x01, 0xb4, 0xef, 0x0b, + 0x66, 0x67, 0xf8, 0x29, 0xb3, 0x15, 0x54, 0x5d, 0x45, 0xd5, 0x45, 0xe9, 0x29, 0x51, 0xfe, 0x11, + 0x93, 0xa0, 0xa6, 0x10, 0x15, 0x53, 0x28, 0x64, 0x11, 0x6d, 0x18, 0x3c, 0x4c, 0xa5, 0x74, 0x7f, + 0x12, 0x09, 0x49, 0x49, 0xad, 0xd3, 0xa1, 0x3f, 0x89, 0xf1, 0x21, 0x4b, 0x71, 0xdc, 0xb7, 0x15, + 0x89, 0x58, 0xb3, 0xd5, 0x05, 0x00, 0x00, 0x8a, 0xef, 0xbb, 0x9f, 0x0f, 0x05, 0x45, 0xdb, 0x5a, + 0xa3, 0x7b, 0xd0, 0x1e, 0x87, 0x2b, 0xd3, 0x67, 0xc1, 0x61, 0x58, 0x37, 0x14, 0x21, 0x06, 0x8d, + 0x09, 0x36, 0xc6, 0xdf, 0xf5, 0x76, 0x9f, 0x88, 0x85, 0x09, 0x95, 0x43, 0xde, 0xe4, 0xeb, 0x50, + 0x17, 0xb7, 0xe8, 0x27, 0x58, 0xbe, 0xe7, 0xd8, 0x55, 0xd3, 0x8e, 0x20, 0xf8, 0x52, 0x80, 0xd8, + 0xd0, 0xd4, 0xc8, 0x16, 0x89, 0x8a, 0xb4, 0x34, 0x05, 0x21, 0x05, 0xff, 0xf0, 0x51, 0x42, 0x64, + 0xac, 0x03, 0x62, 0x25, 0x33, 0xff, 0xa9, 0xda, 0xba, 0xf5, 0x71, 0x04, 0xab, 0xf2, 0xe3, 0xbf, + 0xf8, 0x53, 0x1c, 0xe2, 0xd3, 0xb2, 0xd9, 0x66, 0xd9, 0xb0, 0x8b, 0x88, 0xdb, 0x17, 0xd1, 0xe6, + 0x8d, 0x47, 0xa9, 0xab, 0x0b, 0xc7, 0x7b, 0xc4, 0x8c, 0x38, 0x4d, 0x83, 0xe3, 0x34, 0x83, 0xd2, + 0x0a, 0x10, 0x84, 0x18, 0x73, 0x8d, 0x22, 0xd7, 0x34, 0x10, 0x05, 0x04, 0x30, 0x38, 0xcf, 0xff, + 0x4a, 0x9c, 0x6d, 0xc7, 0x41, 0xaa, 0x3c, 0x29, 0x53, 0x18, 0xb7, 0x60, 0xd3, 0x0c, 0xa8, 0x09, + 0x52, 0x21, 0x46, 0x7a, 0x18, 0x09, 0x13, 0xf6, 0xd2, 0x14, 0x24, 0x6c, 0x8b, 0xb6, 0x9a, 0xcc, + 0x87, 0xb8, 0x91, 0x23, 0xef, 0x0c, 0x1d, 0xf9, 0x54, 0x3f, 0x4b, 0x81, 0xaf, 0x17, 0xab, 0x5e, + 0x00, 0x77, 0xeb, 0x67, 0xfd, 0x3f, 0x9d, 0xda, 0x6f, 0xdc, 0x58, 0x71, 0xaa, 0xfe, 0xfb, 0xa6, + 0x20, 0x40, 0x24, 0x8a, 0xc5, 0x6e, 0x50, 0x80, 0x2f, 0xe2, 0x06, 0x42, 0x1c, 0x10, 0xca, 0xf4, + 0x69, 0x09, 0x46, 0x21, 0x20, 0x88, 0x4d, 0x83, 0x06, 0xec, 0xa3, 0xd7, 0x78, 0x91, 0x00, 0x52, + 0x56, 0x1d, 0xa4, 0x94, 0x2e, 0x22, 0xdb, 0xab, 0xd0, 0x67, 0x94, 0x4c, 0xf1, 0x79, 0x80, 0x00, + 0x21, 0xf8, 0x41, 0xbb, 0x02, 0x66, 0x63, 0x95, 0xf8, 0x2b, 0x2b, 0xb1, 0x15, 0x47, 0xa6, 0x38, + 0x13, 0x63, 0xcf, 0x92, 0xaf, 0xe1, 0x3d, 0x80, 0xa3, 0xed, 0x92, 0x90, 0x5a, 0xfc, 0x84, 0x76, + 0xa8, 0xf8, 0x80, 0xa0, 0xc9, 0x92, 0x28, 0x9b, 0x62, 0xef, 0x24, 0x2a, 0xc5, 0x06, 0x18, 0x70, + 0x99, 0x79, 0xd8, 0xef, 0xc3, 0x62, 0x4e, 0xf2, 0x48, 0x1f, 0x7f, 0x3c, 0x31, 0x1a, 0x94, 0x33, + 0xa8, 0x67, 0x0e, 0x33, 0xfb, 0xbf, 0x93, 0xa2, 0x3f, 0xd1, 0x6f, 0xf5, 0x7b, 0xeb, 0x13, 0xaf, + 0x57, 0xae, 0x08, 0xf3, 0xb1, 0x63, 0xc7, 0x7c, 0x11, 0x11, 0x8d, 0x8d, 0x8d, 0x8f, 0x55, 0xc1, + 0x19, 0xde, 0xf6, 0xfa, 0x25, 0x7d, 0x5f, 0xeb, 0x2a, 0xeb, 0x1a, 0xb8, 0x72, 0xc4, 0x78, 0x40, + 0xd8, 0x8b, 0xc3, 0xa3, 0x9e, 0xac, 0x22, 0x54, 0xcf, 0x42, 0x5f, 0xe3, 0x48, 0x57, 0xae, 0x4f, + 0xae, 0xba, 0xaa, 0x52, 0xe2, 0x6d, 0x6d, 0x7d, 0xed, 0x60, 0xe6, 0x27, 0xdc, 0x70, 0x69, 0x7b, + 0xe8, 0x48, 0xa2, 0x42, 0xff, 0x05, 0x87, 0x9c, 0x31, 0x4d, 0x66, 0x32, 0xe7, 0x2a, 0xa3, 0x5f, + 0xc4, 0xc4, 0x1d, 0x3a, 0xa9, 0x2c, 0xe0, 0xdd, 0x99, 0x70, 0x48, 0x78, 0x2a, 0x40, 0x6e, 0x1d, + 0xc4, 0x41, 0x29, 0x36, 0x24, 0xda, 0x37, 0x30, 0xc1, 0x74, 0x19, 0x3e, 0xf8, 0xc8, 0xf4, 0xe4, + 0x78, 0xc7, 0xe2, 0x16, 0x0e, 0x4c, 0x5b, 0x0b, 0xe8, 0x2b, 0x2d, 0xab, 0xb1, 0xd8, 0xce, 0x38, + 0x80, 0x43, 0x71, 0x5d, 0xb9, 0xff, 0x89, 0x08, 0x88, 0x64, 0xc4, 0xe7, 0x2a, 0xf7, 0x2f, 0x3a, + 0x4e, 0xcc, 0x00, 0x0f, 0x82, 0xb1, 0x29, 0xda, 0x9c, 0x76, 0xae, 0x34, 0x88, 0xa3, 0x76, 0x1e, + 0x2c, 0xb4, 0x24, 0x61, 0xc7, 0x6a, 0xc4, 0xc3, 0x69, 0x8a, 0xd4, 0x3f, 0x5c, 0xbc, 0x40, 0x2b, + 0x98, 0x30, 0x13, 0xaf, 0x91, 0x83, 0xa9, 0x40, 0x3a, 0x12, 0x02, 0x1e, 0x62, 0x51, 0x01, 0x45, + 0x8a, 0x1f, 0xfc, 0x17, 0x4a, 0xdf, 0xa1, 0x43, 0xb3, 0xb1, 0x6f, 0x82, 0xaa, 0xca, 0x41, 0xbb, + 0x8a, 0xdc, 0xac, 0x5a, 0x02, 0x4f, 0x77, 0xc1, 0x3c, 0xac, 0xd2, 0x94, 0x34, 0xc1, 0x1e, 0x38, + 0xda, 0x7c, 0x11, 0x18, 0xcc, 0xee, 0xc7, 0xc9, 0x6e, 0x66, 0x3e, 0x0b, 0x73, 0xac, 0xdf, 0x9e, + 0x74, 0x71, 0xf8, 0x46, 0x5a, 0xd1, 0x32, 0xba, 0xca, 0x41, 0xd3, 0x10, 0xe7, 0x8c, 0x28, 0x87, + 0x0a, 0xf4, 0x2a, 0x12, 0xd5, 0xc7, 0xa6, 0xc6, 0x36, 0x7a, 0xc1, 0x2c, 0x92, 0x14, 0xba, 0x99, + 0xa8, 0xb3, 0xea, 0x34, 0x5c, 0x15, 0x4e, 0xfe, 0x27, 0xc2, 0x92, 0x12, 0x49, 0x74, 0x4a, 0xd6, + 0x64, 0xcb, 0x63, 0xf9, 0x6c, 0x9d, 0x00, 0x66, 0x31, 0x39, 0x76, 0xe2, 0xaa, 0xc2, 0x45, 0x86, + 0xea, 0x74, 0x32, 0x12, 0x35, 0x1c, 0x30, 0xff, 0xc2, 0x12, 0xd9, 0x6c, 0xf4, 0x20, 0x09, 0x6f, + 0xba, 0x22, 0x80, 0xeb, 0x43, 0x13, 0x0d, 0xe2, 0x21, 0x49, 0x39, 0x74, 0xe9, 0x1f, 0x84, 0x78, + 0x64, 0x1f, 0xad, 0xd6, 0x83, 0x0d, 0x70, 0x12, 0xa8, 0x3f, 0xd3, 0x92, 0x80, 0x9d, 0xda, 0x96, + 0x3d, 0x8d, 0x99, 0xd0, 0x09, 0x21, 0x6b, 0xdb, 0xa9, 0xbd, 0x7f, 0x85, 0x29, 0x5c, 0x27, 0x56, + 0xc2, 0x08, 0xf0, 0x58, 0x1c, 0xf5, 0x5e, 0xee, 0x68, 0x63, 0x76, 0x20, 0xdb, 0x90, 0x60, 0xac, + 0x08, 0x06, 0x9b, 0x97, 0x27, 0xbc, 0x33, 0x04, 0xa2, 0xb4, 0x5b, 0xf0, 0xa7, 0x79, 0x40, 0x11, + 0x05, 0xb3, 0xfa, 0x4d, 0xd7, 0x40, 0x34, 0x11, 0x02, 0x50, 0x1c, 0x02, 0x7f, 0xca, 0xe0, 0x80, + 0x95, 0x11, 0x0e, 0x02, 0xb0, 0x60, 0xc5, 0xc8, 0x3b, 0x63, 0x7c, 0x23, 0xad, 0x98, 0x35, 0xf2, + 0x32, 0x65, 0x3f, 0x4d, 0x7b, 0x10, 0xd4, 0xcb, 0x6d, 0x78, 0x81, 0x5c, 0x9b, 0x3d, 0xa6, 0x4d, + 0x8b, 0xc6, 0x16, 0x5e, 0x6d, 0xdf, 0xe7, 0x51, 0x89, 0x76, 0x2f, 0xb7, 0xe4, 0xb1, 0x4e, 0x32, + 0x7c, 0xe2, 0x01, 0x41, 0x85, 0x1b, 0xcf, 0x8c, 0x65, 0x97, 0xef, 0x8d, 0x15, 0x7b, 0x8a, 0xf2, + 0x79, 0xec, 0x0f, 0x07, 0x2f, 0x5b, 0x62, 0x16, 0x1d, 0x51, 0xa6, 0xde, 0x5e, 0x41, 0x01, 0xff, + 0x42, 0xf2, 0xfa, 0xea, 0xf9, 0x2c, 0xc6, 0x5c, 0x1f, 0xc1, 0x5e, 0x0d, 0xd8, 0x91, 0xb0, 0x6a, + 0x86, 0xc0, 0x34, 0xaf, 0x5f, 0x53, 0x27, 0xc4, 0xc9, 0x16, 0x23, 0xfe, 0xe8, 0x77, 0xdf, 0x6d, + 0x3f, 0x54, 0x77, 0xeb, 0xa9, 0xfa, 0xc3, 0xbe, 0x8d, 0xae, 0x26, 0x34, 0x8b, 0x0b, 0x6a, 0x99, + 0x30, 0xc8, 0x9a, 0x11, 0xb1, 0xe4, 0x51, 0x02, 0x3d, 0x39, 0xe8, 0x2d, 0xdb, 0xc8, 0xdf, 0x6f, + 0x8f, 0xe5, 0xe0, 0x81, 0x2c, 0x87, 0xa5, 0x9d, 0x42, 0x3d, 0x2c, 0xe5, 0x10, 0x18, 0xff, 0x7f, + 0x04, 0x75, 0x17, 0x33, 0x12, 0xe7, 0xc1, 0x51, 0xd2, 0xa3, 0x5b, 0x93, 0xa9, 0x55, 0x6f, 0x5a, + 0x9c, 0xe2, 0x63, 0x04, 0x86, 0xf9, 0x49, 0x25, 0x57, 0x42, 0x48, 0xa6, 0x2b, 0x90, 0x7c, 0xa6, + 0xb0, 0xb0, 0xf4, 0x33, 0x89, 0x07, 0x73, 0xfa, 0xe2, 0x20, 0x8c, 0x8f, 0xb1, 0xfb, 0x88, 0x82, + 0xc8, 0xe8, 0xd0, 0x95, 0x43, 0x26, 0xa2, 0x24, 0x11, 0xc1, 0xa0, 0xc0, 0x40, 0x15, 0xc2, 0x40, + 0xbc, 0x96, 0xd0, 0x77, 0xf7, 0xc7, 0x45, 0x65, 0xc7, 0x26, 0x41, 0xa0, 0xd8, 0xe5, 0x25, 0xf5, + 0xf0, 0xa5, 0xeb, 0x3f, 0x78, 0x80, 0x88, 0xb0, 0x4e, 0x1a, 0x98, 0x30, 0x4f, 0xfb, 0xca, 0x63, + 0x6f, 0xe5, 0x8e, 0xd1, 0xc1, 0xf8, 0x40, 0xc4, 0xf1, 0x02, 0x8c, 0xbd, 0x68, 0x95, 0xb2, 0x18, + 0xaa, 0x96, 0x6b, 0xe1, 0x23, 0xd5, 0xdf, 0x41, 0x6e, 0xce, 0x5c, 0xf0, 0x8e, 0x45, 0x33, 0xb4, + 0x8c, 0x43, 0x45, 0x89, 0x89, 0x1e, 0x8e, 0x8f, 0xe0, 0xab, 0xe1, 0xc8, 0x81, 0x93, 0x63, 0x14, + 0x07, 0x9d, 0x86, 0x68, 0x34, 0x90, 0x05, 0xe2, 0x01, 0x26, 0x99, 0x6e, 0x8d, 0x23, 0xf5, 0xef, + 0x9a, 0x91, 0x79, 0x2e, 0x3f, 0x04, 0xb1, 0x71, 0x86, 0x26, 0x62, 0x5a, 0x4b, 0x1f, 0xbe, 0x09, + 0xf2, 0xa9, 0x5d, 0x9a, 0xb3, 0x56, 0xf8, 0x2c, 0xe3, 0x37, 0x62, 0x0f, 0x90, 0x86, 0x28, 0xd9, + 0x09, 0x8c, 0x75, 0xe2, 0x81, 0xbc, 0x00, 0x03, 0xdc, 0x44, 0x29, 0x76, 0x39, 0x0e, 0x94, 0x20, + 0x0c, 0x37, 0x84, 0x01, 0x8a, 0xa6, 0x89, 0x4b, 0xa6, 0xf8, 0x16, 0xcb, 0x61, 0x56, 0x71, 0xf8, + 0x88, 0x26, 0x9e, 0x1d, 0x09, 0xcc, 0xe8, 0x3d, 0x00, 0xcf, 0x71, 0x02, 0x1d, 0x8e, 0x37, 0xf1, + 0x30, 0x8f, 0x40, 0xa4, 0xae, 0xe1, 0xe6, 0x02, 0x7e, 0xb5, 0xe2, 0x01, 0x37, 0x44, 0xf1, 0xd1, + 0x09, 0x40, 0xd9, 0x07, 0x0d, 0x33, 0xef, 0x0b, 0x3d, 0x38, 0x90, 0x59, 0x7e, 0xbb, 0x46, 0x95, + 0xaa, 0xa4, 0xf8, 0xc3, 0x9c, 0x83, 0x09, 0xa5, 0x72, 0x79, 0xe0, 0xfb, 0x07, 0x18, 0x17, 0xc4, + 0x69, 0x4b, 0xf6, 0x22, 0x84, 0x01, 0x68, 0x96, 0x22, 0x09, 0x64, 0x50, 0x51, 0x4a, 0x3e, 0x03, + 0x41, 0x8d, 0x3b, 0xfa, 0xf8, 0x43, 0xa6, 0x65, 0x42, 0xe7, 0xf8, 0x8f, 0x3e, 0xa1, 0x33, 0xa4, + 0xfe, 0x0b, 0xa6, 0xd3, 0xe1, 0x3b, 0xb2, 0xe3, 0x64, 0x4e, 0x2f, 0x8e, 0x99, 0x8e, 0x8c, 0x25, + 0xc5, 0xca, 0xde, 0x45, 0x96, 0x10, 0x3f, 0x5f, 0x10, 0x09, 0x47, 0x54, 0x57, 0x54, 0xa9, 0x3f, + 0x25, 0x54, 0x7a, 0x62, 0x31, 0xff, 0x1b, 0x4d, 0xe8, 0xc0, 0xfb, 0xa0, 0xbf, 0x3c, 0x7a, 0x9c, + 0xa8, 0x23, 0xa0, 0xe7, 0x82, 0x10, 0xa2, 0x04, 0x0d, 0xba, 0xc6, 0x09, 0x22, 0xb8, 0x12, 0x4e, + 0xe3, 0x4b, 0xcf, 0xc2, 0x74, 0x10, 0xd6, 0x01, 0x79, 0x0f, 0xb3, 0x9d, 0xf2, 0x81, 0x14, 0x95, + 0x40, 0xef, 0x69, 0xfe, 0x09, 0x4e, 0x96, 0x93, 0x06, 0x61, 0x8a, 0x2a, 0xa0, 0xf9, 0x76, 0x4b, + 0x7d, 0x71, 0x7d, 0x77, 0xfa, 0xa4, 0x5e, 0xa6, 0x55, 0x70, 0x45, 0x54, 0x9d, 0xd9, 0xf3, 0xd5, + 0xa6, 0x92, 0x4b, 0xfd, 0x5d, 0xf5, 0x20, 0xaf, 0xa9, 0xd2, 0xb8, 0x22, 0xb6, 0x86, 0xdd, 0xdf, + 0x52, 0xe7, 0xc1, 0x25, 0x1a, 0x36, 0x6e, 0xe7, 0xcd, 0x57, 0x5e, 0x26, 0x0a, 0xc4, 0x0f, 0x26, + 0x1a, 0xc3, 0xbf, 0x89, 0xf3, 0x79, 0x2e, 0x0f, 0x60, 0xaa, 0x6a, 0xd1, 0x1e, 0xf8, 0x25, 0x8c, + 0xd1, 0xf7, 0x15, 0x57, 0xca, 0xa9, 0x18, 0xcb, 0xe1, 0x4c, 0xaf, 0x13, 0x51, 0xf5, 0x17, 0x53, + 0x28, 0x52, 0xf4, 0xff, 0x67, 0x3f, 0xa3, 0xf8, 0x29, 0xbb, 0x61, 0x46, 0xc6, 0x31, 0x57, 0x03, + 0x37, 0x2b, 0x66, 0x0a, 0x2c, 0xc1, 0xc3, 0x87, 0x30, 0x25, 0xf6, 0x24, 0xea, 0xab, 0x58, 0x2a, + 0x54, 0xb3, 0xf0, 0x48, 0x4d, 0x0d, 0x5d, 0xf2, 0x76, 0x35, 0xc4, 0x41, 0x2c, 0x8c, 0x7e, 0x92, + 0xa3, 0xef, 0x82, 0x59, 0x14, 0x7d, 0x00, 0xac, 0xc8, 0xde, 0xf8, 0x21, 0x32, 0x7c, 0x6e, 0xff, + 0x09, 0xcb, 0xe5, 0x56, 0xdd, 0xbf, 0x13, 0xdb, 0x4e, 0x9d, 0x3f, 0x18, 0x5b, 0x19, 0x5d, 0x00, + 0xf9, 0x54, 0x3a, 0x1c, 0xa8, 0xb8, 0xc8, 0x90, 0xab, 0xc1, 0x27, 0x1e, 0xaf, 0xef, 0x8b, 0xbb, + 0x8f, 0xd4, 0x7b, 0x4c, 0xd4, 0xf8, 0xbe, 0x1b, 0x86, 0xe5, 0xae, 0xdf, 0x82, 0x1d, 0xb5, 0xb5, + 0x70, 0xa1, 0x4b, 0x8a, 0x8c, 0xce, 0x00, 0x01, 0x20, 0xda, 0xd6, 0x51, 0xd2, 0xca, 0x7e, 0xac, + 0x62, 0x8c, 0x0e, 0x5b, 0x32, 0x6e, 0x25, 0x88, 0x91, 0xe3, 0xde, 0x85, 0xb6, 0x52, 0x58, 0x06, + 0x38, 0xac, 0xb1, 0xd0, 0x8c, 0x77, 0x0c, 0x9c, 0x48, 0x90, 0x8d, 0x06, 0x56, 0x12, 0x74, 0x1b, + 0xca, 0x10, 0xbb, 0x3a, 0x7b, 0xb1, 0xf8, 0x24, 0xb4, 0x7c, 0x9b, 0x1c, 0xf1, 0x23, 0x0a, 0xc9, + 0x1a, 0x6b, 0xe6, 0x0f, 0xe6, 0x3f, 0xd6, 0x61, 0x6c, 0xa1, 0xf1, 0x0c, 0xa0, 0x00, 0xec, 0x45, + 0x00, 0x93, 0x3d, 0xec, 0x52, 0x41, 0x2c, 0x44, 0x6e, 0x94, 0x59, 0x44, 0x70, 0xd4, 0x57, 0x85, + 0xc6, 0x41, 0x4e, 0x79, 0xa3, 0x59, 0x13, 0xf6, 0x25, 0x28, 0x60, 0x82, 0x6e, 0x16, 0x68, 0x6c, + 0xdf, 0x83, 0x6b, 0x6e, 0xae, 0x92, 0x8e, 0xfd, 0xd5, 0x24, 0xbc, 0xa4, 0x96, 0x1f, 0x13, 0x13, + 0x5d, 0xb6, 0x79, 0x6a, 0xc1, 0xf8, 0x26, 0x39, 0xff, 0x9c, 0x92, 0x06, 0x5c, 0xd2, 0xbc, 0x4c, + 0x28, 0x43, 0x02, 0x01, 0x3a, 0x42, 0x98, 0xbf, 0x08, 0x1b, 0x58, 0x52, 0x75, 0x52, 0x24, 0xe0, + 0x82, 0xe2, 0x0a, 0x16, 0x4a, 0x0b, 0x53, 0x84, 0x61, 0x29, 0xb9, 0x33, 0x28, 0x60, 0xdb, 0x56, + 0x58, 0x98, 0x40, 0xca, 0x2f, 0xe3, 0x92, 0x69, 0xdf, 0xe1, 0x01, 0x2c, 0x23, 0x3f, 0x2a, 0xa9, + 0xbb, 0x26, 0xe2, 0x06, 0x81, 0x9c, 0xe3, 0xa5, 0xe5, 0xa0, 0x74, 0x08, 0xa6, 0xaf, 0x9f, 0x10, + 0x34, 0x76, 0x2d, 0x5d, 0xa6, 0x7a, 0xba, 0x5b, 0x62, 0x4f, 0xae, 0xbe, 0x22, 0x41, 0x27, 0x04, + 0x68, 0xc9, 0x05, 0x86, 0xe1, 0x70, 0xa0, 0x03, 0xb1, 0x41, 0x49, 0x46, 0x94, 0xb3, 0x1d, 0x11, + 0x66, 0x7f, 0xa1, 0x30, 0x7d, 0x70, 0xae, 0x7c, 0xac, 0x9e, 0x47, 0xff, 0x86, 0xae, 0x81, 0xdd, + 0x55, 0xe5, 0xff, 0xd7, 0x2f, 0xa2, 0x45, 0x5d, 0x58, 0xfa, 0x2e, 0x2f, 0x9a, 0xbb, 0xbe, 0xee, + 0xee, 0xbe, 0xb2, 0xfb, 0xa6, 0xdd, 0x3f, 0x7d, 0xdf, 0xce, 0x45, 0xaa, 0x23, 0x43, 0xdf, 0x04, + 0xe5, 0x15, 0x8a, 0xc4, 0xa0, 0x00, 0x12, 0xd8, 0xda, 0x92, 0xa8, 0x15, 0xde, 0x36, 0x02, 0x2a, + 0x50, 0x04, 0x27, 0x87, 0x46, 0x33, 0x07, 0xbe, 0xef, 0x19, 0xef, 0x8e, 0xa5, 0xef, 0xea, 0xaa, + 0xc4, 0x5a, 0x7f, 0xe0, 0x84, 0xe9, 0x2d, 0x51, 0xda, 0xe0, 0x84, 0x48, 0xc1, 0xaf, 0xbc, 0x5c, + 0x4c, 0x28, 0x30, 0xe2, 0x04, 0x98, 0x35, 0x65, 0x9e, 0xec, 0x2f, 0x78, 0xee, 0x0b, 0x58, 0x6c, + 0x0a, 0x69, 0x4a, 0x81, 0x47, 0xa1, 0x23, 0x2c, 0xc6, 0xd4, 0x81, 0xc4, 0x0c, 0x1a, 0x19, 0x12, + 0x80, 0x3f, 0xad, 0x8c, 0x5b, 0xa0, 0x79, 0x0e, 0x44, 0x7e, 0xc7, 0x8d, 0xc2, 0x09, 0xd5, 0x8d, + 0x63, 0x8b, 0x3a, 0x64, 0xaf, 0x90, 0x31, 0x9b, 0xff, 0x2d, 0x7a, 0x60, 0xb7, 0x6f, 0x89, 0x12, + 0x2e, 0xb0, 0xb5, 0x04, 0x08, 0x4b, 0xf4, 0xdf, 0x11, 0x0d, 0x56, 0xad, 0x1e, 0x61, 0x43, 0x7b, + 0xfe, 0x22, 0x14, 0xbe, 0x18, 0x44, 0x38, 0xa8, 0x94, 0x27, 0xea, 0xe0, 0x40, 0x24, 0x00, 0x00, + 0xc1, 0xa1, 0x77, 0x95, 0x08, 0x50, 0x4e, 0xe5, 0xbe, 0x0a, 0x67, 0xee, 0x17, 0x52, 0x0f, 0x15, + 0x0c, 0x9e, 0xfc, 0x60, 0x44, 0x7d, 0xf0, 0x51, 0x43, 0x9c, 0xaa, 0x9d, 0x40, 0xad, 0xf0, 0xbe, + 0xf8, 0x2a, 0x28, 0x81, 0x50, 0x7a, 0x10, 0x04, 0x2c, 0x3c, 0xbd, 0x8c, 0xbf, 0x42, 0xd8, 0x43, + 0x61, 0x01, 0x95, 0x19, 0x78, 0x2b, 0x23, 0x57, 0x61, 0xed, 0x57, 0x39, 0x4c, 0xa1, 0xe2, 0xe4, + 0x5f, 0x2d, 0x9b, 0x59, 0x54, 0xf8, 0x53, 0xa0, 0x64, 0x85, 0xcb, 0xe7, 0x4b, 0xce, 0xf5, 0x7f, + 0x1b, 0x88, 0x82, 0x3c, 0xea, 0x58, 0x2a, 0xdf, 0x88, 0x85, 0x24, 0xee, 0xb4, 0x22, 0xd5, 0x2d, + 0x73, 0x4d, 0x86, 0xce, 0x81, 0x9f, 0xd2, 0x7c, 0x64, 0x74, 0x6c, 0x20, 0x1e, 0x57, 0x83, 0xd6, + 0x5e, 0x68, 0x30, 0x14, 0x6a, 0xe8, 0xd6, 0x4f, 0x9d, 0xe3, 0x4d, 0xc4, 0x39, 0xe3, 0x2d, 0xc4, + 0x23, 0xac, 0x5e, 0x98, 0x7d, 0x31, 0xea, 0x70, 0x00, 0x05, 0xcc, 0x0a, 0xb5, 0xc1, 0xea, 0xf5, + 0xd0, 0xef, 0x0d, 0xc1, 0x90, 0x30, 0xba, 0x0b, 0x89, 0x28, 0x72, 0x14, 0xdd, 0x5b, 0xa3, 0x2d, + 0x9b, 0x95, 0x43, 0x54, 0xe2, 0x04, 0x02, 0x59, 0xd7, 0xec, 0x23, 0x1f, 0x8e, 0x00, 0xc8, 0x17, + 0x6f, 0x8a, 0xc0, 0x2a, 0xc7, 0xdd, 0x34, 0x50, 0x23, 0xae, 0xc5, 0x78, 0x91, 0x23, 0x39, 0x83, + 0x10, 0xc4, 0x5d, 0xe2, 0x8c, 0x56, 0x4c, 0xb8, 0x0f, 0x54, 0x2a, 0x1d, 0xe5, 0xe1, 0x47, 0x0a, + 0x2e, 0x1d, 0xf5, 0xc3, 0x43, 0x4f, 0x60, 0x58, 0x88, 0x4c, 0x89, 0x2a, 0x1c, 0xf2, 0x55, 0x55, + 0x08, 0x11, 0x58, 0xd0, 0x3f, 0x25, 0xa7, 0xf8, 0x90, 0x50, 0x47, 0x4b, 0x95, 0x09, 0x61, 0x01, + 0xf7, 0x89, 0x19, 0x8a, 0xc5, 0x65, 0x20, 0x9f, 0xa4, 0x4a, 0xd8, 0xd6, 0x5d, 0x2d, 0xc4, 0x96, + 0x45, 0x0b, 0xf1, 0x3c, 0x48, 0x9a, 0xc4, 0x02, 0xcb, 0x5e, 0x18, 0xd0, 0x84, 0x31, 0x35, 0x04, + 0x6f, 0x44, 0xee, 0x5b, 0x4c, 0x66, 0x10, 0x02, 0xcc, 0xfc, 0x3f, 0xa3, 0x75, 0x4c, 0x9a, 0x18, + 0x11, 0x9a, 0x65, 0x26, 0x4b, 0xa0, 0x5b, 0xf0, 0xed, 0x2f, 0xc9, 0x40, 0x2f, 0x60, 0x6f, 0x5d, + 0x0d, 0x19, 0xaf, 0xff, 0x52, 0xa5, 0x75, 0x3a, 0x7d, 0x7b, 0xeb, 0xdf, 0x5a, 0xae, 0xbd, 0x7d, + 0x75, 0xf5, 0x8a, 0x7e, 0xbd, 0xc4, 0xc2, 0x86, 0x05, 0xad, 0x31, 0x75, 0x15, 0xe4, 0x9c, 0xa9, + 0x70, 0x0a, 0x3e, 0xc5, 0x36, 0x54, 0x9a, 0x3e, 0x63, 0xb7, 0xc2, 0x85, 0x7a, 0xa8, 0xd0, 0x36, + 0x1a, 0x32, 0x2a, 0x4b, 0x1e, 0x45, 0xe8, 0xcb, 0x72, 0x60, 0xda, 0x43, 0xbb, 0xfc, 0x14, 0xf5, + 0x55, 0x43, 0xe5, 0x7b, 0x7c, 0x10, 0xea, 0x9d, 0xfe, 0x09, 0xed, 0xa1, 0xd1, 0x3c, 0x6c, 0x64, + 0x7a, 0x81, 0x8a, 0x37, 0xc2, 0x82, 0x2c, 0x1b, 0x72, 0x6c, 0xb8, 0x0f, 0xaf, 0xa1, 0xac, 0x06, + 0x70, 0xf7, 0x63, 0x35, 0x09, 0x4a, 0x22, 0xd5, 0xb8, 0xca, 0xa8, 0xa8, 0xc1, 0x89, 0x0c, 0x0c, + 0x1a, 0x4e, 0xae, 0xbf, 0x97, 0xd5, 0x77, 0x58, 0xae, 0xa6, 0xd2, 0x09, 0x5b, 0x2b, 0x14, 0x67, + 0x8a, 0x43, 0xc7, 0xe1, 0x00, 0xc8, 0x52, 0xf7, 0xaa, 0x97, 0x1e, 0x41, 0x1d, 0x68, 0x39, 0xa5, + 0xb5, 0x86, 0xf3, 0x85, 0x86, 0x88, 0x09, 0x63, 0x11, 0x77, 0x11, 0x19, 0x27, 0xe3, 0x41, 0xf1, + 0xd1, 0x01, 0x55, 0x63, 0x1b, 0x9e, 0x73, 0x43, 0xd8, 0x53, 0x8c, 0xf4, 0x78, 0x35, 0xc6, 0x9c, + 0x5b, 0x1f, 0x3c, 0x86, 0xa9, 0x0f, 0x29, 0x6b, 0xa1, 0x33, 0x15, 0xba, 0x2c, 0xb6, 0x25, 0x18, + 0x25, 0xb4, 0x8e, 0xe3, 0x54, 0x54, 0xdc, 0x08, 0x04, 0x76, 0xb6, 0xdb, 0x6d, 0xff, 0x82, 0x72, + 0x56, 0x72, 0x53, 0xb1, 0x60, 0x7c, 0xcb, 0x11, 0x04, 0x44, 0xad, 0x8d, 0xdc, 0x44, 0x4d, 0x53, + 0x28, 0x86, 0x3b, 0x8c, 0x84, 0x04, 0xe2, 0x0f, 0x82, 0x32, 0xc9, 0x1a, 0x5d, 0xf0, 0x55, 0xb0, + 0x63, 0x87, 0x0f, 0x2e, 0x11, 0x24, 0xed, 0x62, 0xfb, 0xe0, 0x9b, 0x98, 0x40, 0x8d, 0xc2, 0x75, + 0xa1, 0x09, 0x60, 0x50, 0x92, 0xfc, 0x3c, 0x56, 0x83, 0xf0, 0x71, 0x78, 0x0e, 0x30, 0x48, 0xf8, + 0xf6, 0xd4, 0x1f, 0x94, 0xd4, 0x6c, 0x00, 0x2c, 0x0d, 0x3b, 0xf7, 0x97, 0xa7, 0xe3, 0x22, 0x98, + 0xd8, 0x81, 0x58, 0x3e, 0xe5, 0x7a, 0x05, 0x82, 0x0a, 0x9b, 0x0f, 0x10, 0x9a, 0x9d, 0xce, 0x21, + 0xf6, 0x10, 0xd6, 0xe1, 0xfb, 0x29, 0x2a, 0x9a, 0xbb, 0xb5, 0x30, 0xd6, 0x0e, 0x11, 0x82, 0x73, + 0xfc, 0x16, 0x6d, 0x95, 0x4d, 0x67, 0x52, 0x9b, 0x9d, 0x8f, 0xd4, 0xd6, 0x84, 0x74, 0xb9, 0x7c, + 0x67, 0x9d, 0x42, 0x38, 0x9a, 0x08, 0x36, 0xbe, 0x75, 0xcb, 0xfd, 0x83, 0xc4, 0x08, 0x05, 0x72, + 0xb1, 0xa2, 0x1f, 0x04, 0x48, 0xa3, 0x26, 0x44, 0x04, 0x36, 0x3b, 0x2e, 0xf7, 0x74, 0x26, 0x3e, + 0xe5, 0x0e, 0x50, 0x68, 0x37, 0xf1, 0x99, 0xb9, 0x0a, 0xbb, 0x86, 0x32, 0x30, 0x82, 0xa8, 0x2c, + 0x71, 0x8c, 0x28, 0x00, 0x0d, 0x12, 0x79, 0xf6, 0xc1, 0x30, 0xd4, 0xe5, 0x45, 0x89, 0x8c, 0xce, + 0x18, 0x9c, 0x65, 0x8b, 0x20, 0x7b, 0x71, 0x43, 0x33, 0x59, 0x24, 0x2c, 0x37, 0x63, 0x51, 0x6c, + 0x50, 0x8b, 0x10, 0x20, 0x41, 0x1b, 0xe2, 0x73, 0xe6, 0x25, 0xf2, 0x29, 0xe2, 0x44, 0x0a, 0xb0, + 0x26, 0x93, 0xad, 0x86, 0x32, 0x37, 0xf8, 0x22, 0xae, 0x86, 0xff, 0x46, 0xef, 0x82, 0xab, 0xbb, + 0xba, 0x8f, 0x20, 0x13, 0x62, 0x5d, 0x8f, 0x47, 0x07, 0xe3, 0x30, 0x53, 0x30, 0x86, 0x46, 0xa5, + 0x4f, 0x2a, 0xad, 0xad, 0x7e, 0xc4, 0xa1, 0x46, 0x43, 0x01, 0xf1, 0x22, 0x41, 0x41, 0x2c, 0x86, + 0x46, 0x22, 0xb1, 0x88, 0x3f, 0xee, 0x3b, 0xf1, 0x22, 0x46, 0x4a, 0xc5, 0x9f, 0x23, 0x73, 0x84, + 0x40, 0x5e, 0xc5, 0xd4, 0x5d, 0x55, 0x55, 0x78, 0x80, 0xf1, 0xac, 0x5d, 0xb4, 0x1f, 0x14, 0x9d, + 0xb0, 0x60, 0xc9, 0x21, 0x36, 0x17, 0x8a, 0x37, 0x99, 0xdf, 0x02, 0xb5, 0x42, 0x96, 0x82, 0x77, + 0x8d, 0x24, 0x39, 0x7d, 0xfd, 0x1e, 0x2f, 0xae, 0x72, 0xfa, 0xd7, 0xc1, 0x11, 0x11, 0xa3, 0x9a, + 0xe2, 0xbe, 0xbd, 0x5c, 0x13, 0x66, 0x65, 0x0e, 0x8d, 0x0c, 0xcc, 0xfd, 0xf3, 0xd5, 0xd9, 0xb3, + 0x5f, 0xf0, 0x58, 0x55, 0x7d, 0xea, 0xec, 0x6a, 0x9d, 0xa4, 0xe7, 0xab, 0x4d, 0x24, 0x97, 0xae, + 0xbc, 0x7b, 0xe0, 0xac, 0x51, 0x3d, 0x73, 0x78, 0x5a, 0xa6, 0xec, 0x63, 0x25, 0x2c, 0xdf, 0xec, + 0xa3, 0xd9, 0x70, 0x05, 0xf5, 0x47, 0x7e, 0x10, 0x38, 0x6d, 0xdf, 0x74, 0x6a, 0x66, 0x18, 0xa0, + 0x4f, 0xcb, 0x8a, 0x37, 0x12, 0xe7, 0x10, 0x09, 0x0d, 0x0a, 0xa6, 0x40, 0xc6, 0xac, 0xab, 0x54, + 0xcf, 0x82, 0x98, 0x97, 0x13, 0x82, 0x06, 0x20, 0x22, 0x54, 0x32, 0x63, 0xe3, 0x8f, 0xff, 0x2d, + 0x1e, 0x16, 0xbd, 0xb9, 0xf8, 0x91, 0x01, 0x43, 0x88, 0x7b, 0xe0, 0xe4, 0x8b, 0x2b, 0x2d, 0xd8, + 0x51, 0xd0, 0xd4, 0xed, 0x89, 0x61, 0x67, 0xac, 0x6e, 0xe1, 0x10, 0xc0, 0x53, 0x9c, 0x88, 0x08, + 0x84, 0x40, 0x45, 0x62, 0xbb, 0x72, 0xdd, 0x8f, 0xa4, 0x22, 0x15, 0x8e, 0x7a, 0x3d, 0x83, 0xd6, + 0x04, 0x7f, 0xc4, 0x42, 0x87, 0x33, 0x1c, 0x8c, 0x81, 0x93, 0xa1, 0x00, 0xd8, 0x45, 0xea, 0xa1, + 0x44, 0xf4, 0x13, 0x08, 0xc9, 0x6f, 0x1f, 0x20, 0x14, 0x0b, 0x6d, 0x50, 0x4a, 0xd1, 0xe7, 0x1f, + 0x8c, 0x53, 0x40, 0x93, 0xfc, 0x20, 0x42, 0xd8, 0x95, 0x21, 0xe9, 0x89, 0xcf, 0x7f, 0xed, 0x8d, + 0x09, 0x8c, 0xaa, 0x68, 0xf8, 0x91, 0xe5, 0xd8, 0xc6, 0x6a, 0xb4, 0xe3, 0xf1, 0x11, 0x4b, 0xf2, + 0x1e, 0x12, 0x2b, 0xc6, 0x47, 0xa9, 0x2c, 0x18, 0x38, 0x51, 0x00, 0x10, 0x5b, 0x23, 0x73, 0x4a, + 0xd8, 0x43, 0xc0, 0x2b, 0x31, 0xe8, 0xa6, 0x58, 0xd5, 0xc8, 0x2b, 0x38, 0x7e, 0x26, 0x32, 0x32, + 0x90, 0x7a, 0x30, 0xa1, 0x49, 0x08, 0x31, 0xe1, 0x1c, 0xb5, 0xd6, 0x07, 0x79, 0x07, 0x08, 0x81, + 0x08, 0x7f, 0xa1, 0xb4, 0x40, 0x9c, 0x2a, 0x03, 0x7c, 0x79, 0x98, 0x73, 0x0e, 0x98, 0x88, 0x29, + 0x34, 0x1d, 0xf3, 0xf7, 0x7f, 0x7f, 0xd3, 0xfc, 0x20, 0x70, 0xa2, 0x82, 0xd0, 0x29, 0x0f, 0x61, + 0xe7, 0x5e, 0xc1, 0xd8, 0x6a, 0xe5, 0x50, 0x3e, 0xf8, 0xbf, 0xa2, 0x53, 0x3c, 0x24, 0x47, 0x43, + 0x2e, 0x50, 0x96, 0xa2, 0x1e, 0xc0, 0xf1, 0x9e, 0xa8, 0xc4, 0x42, 0xd4, 0x26, 0x35, 0xa0, 0x65, + 0x70, 0xe2, 0x62, 0xe2, 0x3b, 0xfb, 0xb2, 0x7f, 0x05, 0x34, 0x91, 0xd2, 0x63, 0x09, 0x91, 0x09, + 0x06, 0xf6, 0x04, 0x39, 0x62, 0x8d, 0xe2, 0xe2, 0x44, 0x82, 0xa3, 0xf4, 0x7a, 0xf3, 0x8f, 0xcd, + 0xe7, 0xca, 0x07, 0xdf, 0x19, 0x1e, 0x4c, 0x9c, 0xb0, 0xea, 0x41, 0xc0, 0x1a, 0xf3, 0x8a, 0x2a, + 0x2c, 0xbd, 0xb5, 0x2a, 0xb5, 0x0b, 0x7f, 0xf8, 0xfb, 0xd4, 0xed, 0x51, 0x42, 0x37, 0x9b, 0x8a, + 0xcb, 0x18, 0xa3, 0x10, 0xfc, 0x4c, 0x61, 0xa0, 0xf3, 0x29, 0xd5, 0xb4, 0x2e, 0x2e, 0xb3, 0x1b, + 0x66, 0xb0, 0x45, 0xaf, 0x2b, 0x3c, 0x48, 0x91, 0xc5, 0xdd, 0xa1, 0x8c, 0x34, 0x87, 0x20, 0x2c, + 0x6a, 0x41, 0x05, 0x2e, 0x16, 0xc5, 0x62, 0xbc, 0x44, 0x64, 0xf4, 0x30, 0x16, 0xe5, 0x9e, 0x90, + 0x5d, 0xd2, 0x44, 0xe3, 0xb9, 0x46, 0xa8, 0xc1, 0xa8, 0x90, 0x9a, 0x52, 0x78, 0xbc, 0x7e, 0x98, + 0x98, 0x44, 0xda, 0x37, 0x9c, 0x83, 0xa5, 0x6f, 0x4f, 0xc5, 0x90, 0xb8, 0x63, 0x85, 0xb4, 0x43, + 0x2c, 0xee, 0xfa, 0x3f, 0xe2, 0x04, 0x85, 0x37, 0x63, 0x77, 0xdd, 0xcb, 0x43, 0x9a, 0x59, 0x6c, + 0xe6, 0x96, 0xae, 0xa7, 0x86, 0x02, 0x3b, 0x7c, 0x75, 0xdc, 0xf4, 0xb7, 0x45, 0x9c, 0xb0, 0x72, + 0xc1, 0xca, 0x86, 0xd1, 0x62, 0x01, 0x46, 0xf4, 0x93, 0xa6, 0xda, 0x3b, 0xc4, 0x08, 0x13, 0x15, + 0x8a, 0x31, 0x58, 0x84, 0x83, 0x74, 0xfe, 0xce, 0xc2, 0x74, 0x3f, 0xbf, 0x73, 0xe7, 0x8c, 0x9d, + 0x97, 0x30, 0x6f, 0x4e, 0x39, 0xd7, 0xd3, 0xab, 0xd4, 0xa2, 0x8d, 0x07, 0x89, 0x8f, 0x35, 0xe9, + 0x33, 0x1d, 0xa7, 0xd4, 0x1d, 0xf3, 0x51, 0x0b, 0xe2, 0x06, 0xc1, 0xa9, 0x64, 0xe8, 0x80, 0xc9, + 0x96, 0xa1, 0x15, 0xb1, 0x38, 0xae, 0x21, 0xc9, 0x09, 0xdc, 0x74, 0xe0, 0x37, 0x00, 0xf1, 0xe4, + 0x44, 0xc4, 0x4d, 0x35, 0xd1, 0xfc, 0x21, 0x72, 0x40, 0x67, 0xd2, 0x66, 0xc0, 0xc5, 0x47, 0x9f, + 0xeb, 0x98, 0x5b, 0x1b, 0xbb, 0xf8, 0x24, 0x33, 0x35, 0x57, 0x95, 0xf0, 0x47, 0x7a, 0xad, 0x60, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x16, 0x0b, 0x30, 0x2e, 0x8b, 0xd0, 0x96, 0x3e, 0xae, 0x85, + 0x38, 0xbd, 0x9b, 0xc5, 0xc5, 0xd5, 0x7d, 0x09, 0x78, 0x8c, 0x44, 0x9c, 0x86, 0x3e, 0x3f, 0x0d, + 0x8e, 0xc0, 0x51, 0x06, 0x22, 0x0c, 0x5e, 0x19, 0x7e, 0xc0, 0x83, 0x08, 0x84, 0x8d, 0x18, 0x42, + 0x18, 0x1e, 0xf8, 0x51, 0x5c, 0x99, 0x52, 0xd6, 0xde, 0x5b, 0x6c, 0x70, 0x20, 0xc2, 0x92, 0x32, + 0xc3, 0x2f, 0x10, 0xb0, 0x9d, 0x45, 0x36, 0x24, 0x8c, 0x3b, 0x04, 0xa2, 0xb6, 0x90, 0xbe, 0x9a, + 0xe4, 0xd0, 0xe3, 0x43, 0xfc, 0x40, 0xb5, 0x5e, 0xce, 0xe3, 0x79, 0x05, 0x8a, 0x31, 0x46, 0x28, + 0xc5, 0x18, 0x88, 0x81, 0x08, 0xdc, 0x70, 0x78, 0x98, 0x2a, 0x14, 0xb2, 0xaa, 0x99, 0xee, 0x14, + 0x30, 0x16, 0x90, 0x53, 0x8c, 0xca, 0x5b, 0xce, 0x9c, 0x22, 0x19, 0x0a, 0x19, 0x08, 0xcd, 0x1e, + 0x70, 0xb0, 0x56, 0x48, 0xed, 0x33, 0x57, 0xbb, 0x89, 0x95, 0x5c, 0x83, 0xaf, 0xbb, 0xd6, 0xee, + 0x77, 0xae, 0x43, 0x38, 0xfa, 0xe5, 0xc0, 0xa2, 0x19, 0x05, 0x62, 0xf6, 0x86, 0x04, 0xcb, 0xa7, + 0x43, 0x80, 0x96, 0xd5, 0x80, 0x00, 0xee, 0xee, 0xe3, 0x8d, 0x11, 0xce, 0x34, 0x71, 0x2b, 0x6d, + 0xb6, 0xdf, 0xf8, 0x28, 0x30, 0xba, 0x8b, 0x8b, 0x9d, 0x89, 0x2e, 0xe9, 0xcc, 0x47, 0x0d, 0xf2, + 0xc5, 0xc5, 0xcb, 0xc5, 0xc6, 0x75, 0xef, 0xa2, 0x95, 0x3e, 0xa4, 0x05, 0x74, 0x6c, 0xab, 0xab, + 0xfd, 0x15, 0xe4, 0xe5, 0x24, 0xec, 0x4e, 0xc7, 0xa9, 0x52, 0x11, 0x82, 0x8a, 0x28, 0x8a, 0xb8, + 0x98, 0x5c, 0x50, 0x18, 0xad, 0x32, 0x4d, 0x7f, 0xf1, 0x1f, 0x63, 0x5a, 0x08, 0x12, 0x1b, 0x78, + 0xa8, 0x14, 0xa5, 0x07, 0x68, 0x59, 0x7f, 0x08, 0x02, 0xc1, 0x4d, 0x9b, 0xb7, 0x3c, 0x57, 0x58, + 0xb8, 0xbb, 0x3c, 0x10, 0x82, 0x69, 0xc2, 0xc5, 0x49, 0x87, 0xf7, 0x30, 0xd6, 0x27, 0xea, 0xe8, + 0x2a, 0x54, 0x74, 0x4e, 0x1c, 0x10, 0x6c, 0x8e, 0x56, 0x33, 0x01, 0xa8, 0x1f, 0x48, 0x4c, 0xbd, + 0x34, 0xd3, 0x4f, 0x05, 0x20, 0xc4, 0x3f, 0x5a, 0xc5, 0xd2, 0x38, 0xd0, 0x8c, 0xe9, 0x67, 0xe9, + 0x6a, 0x16, 0xfe, 0x14, 0x51, 0x46, 0x82, 0x63, 0x0d, 0xd0, 0x66, 0x42, 0xb6, 0x05, 0x6a, 0x6d, + 0x8f, 0xaf, 0xe0, 0x41, 0x06, 0x21, 0x81, 0x0e, 0x8b, 0xe0, 0x1d, 0x43, 0x69, 0xd5, 0x10, 0x39, + 0x41, 0xfe, 0x3b, 0x69, 0x55, 0x6a, 0x5d, 0x93, 0x7f, 0x03, 0x08, 0x29, 0x04, 0x1e, 0x82, 0x0e, + 0x35, 0x10, 0x37, 0xe3, 0x10, 0x8c, 0x85, 0xf0, 0xee, 0x06, 0xab, 0x54, 0x3d, 0xc0, 0x66, 0x1a, + 0xd4, 0x7f, 0x37, 0xf6, 0x01, 0x86, 0x1f, 0x2d, 0x05, 0x07, 0x5f, 0xac, 0x9f, 0x02, 0x88, 0x29, + 0x05, 0x64, 0xe2, 0x2c, 0x6c, 0xff, 0xf0, 0x5d, 0x12, 0x00, 0xd9, 0x53, 0xac, 0x15, 0xb0, 0xff, + 0xdf, 0x28, 0x5c, 0x56, 0x2b, 0x2d, 0x8a, 0xc7, 0xf4, 0x66, 0x45, 0xf3, 0x0a, 0x69, 0xa4, 0xa2, + 0xba, 0x1b, 0x0d, 0x2e, 0x20, 0x2f, 0x80, 0xdf, 0xdb, 0xf1, 0x7d, 0x45, 0xc3, 0xb1, 0x58, 0x53, + 0xcb, 0x0b, 0x16, 0x55, 0xfe, 0x10, 0x1a, 0x12, 0xb1, 0x2e, 0x77, 0xfd, 0xa6, 0xb1, 0xc5, 0x55, + 0x0b, 0x22, 0xf6, 0x5c, 0x1c, 0x63, 0xf8, 0xbb, 0xff, 0x08, 0x82, 0x9a, 0x89, 0x0f, 0x83, 0xab, + 0x93, 0xd9, 0xf3, 0x00, 0x09, 0x3d, 0xb2, 0x4e, 0x09, 0x07, 0x98, 0xcb, 0x91, 0x51, 0xce, 0x5c, + 0xc3, 0xac, 0xa0, 0x1d, 0x60, 0x37, 0x7a, 0x36, 0xdb, 0xdb, 0x6f, 0xfc, 0x70, 0x00, 0x61, 0xb2, + 0xfb, 0x6d, 0xb6, 0xde, 0x04, 0x10, 0x62, 0x34, 0x50, 0xa6, 0x28, 0x62, 0x7c, 0xb0, 0xcb, 0x32, + 0xcc, 0x5c, 0x2f, 0x40, 0x2e, 0x2e, 0x39, 0x28, 0x5b, 0x9a, 0x01, 0x3a, 0x56, 0x7d, 0x50, 0xc7, + 0x4a, 0x26, 0x00, 0x15, 0xd7, 0x13, 0xc1, 0xc0, 0x16, 0xd0, 0xd5, 0x8c, 0x38, 0xab, 0xa7, 0xf8, + 0x46, 0x14, 0x10, 0x59, 0xbe, 0x71, 0x66, 0x41, 0xca, 0x6b, 0x8a, 0x21, 0x90, 0x33, 0x20, 0xc9, + 0xe6, 0xae, 0xd3, 0x43, 0xe3, 0x8b, 0xd4, 0x8c, 0xd4, 0x90, 0x07, 0x23, 0xf8, 0xdf, 0x1b, 0x04, + 0xa8, 0x15, 0x31, 0x10, 0xa5, 0x20, 0x0e, 0x56, 0xf8, 0xfb, 0x73, 0x27, 0x38, 0x90, 0xef, 0x98, + 0xc7, 0x8f, 0xa5, 0xf3, 0xd1, 0xbf, 0xc1, 0x67, 0xe3, 0x8f, 0x2a, 0xea, 0x89, 0xd0, 0x81, 0xf3, + 0xcb, 0xbe, 0x08, 0x66, 0x50, 0xea, 0x2e, 0x6d, 0xb4, 0xff, 0x41, 0x72, 0x28, 0x89, 0xe8, 0x9c, + 0xa8, 0xdd, 0x7a, 0x14, 0xea, 0x62, 0xae, 0xac, 0x09, 0x0c, 0x04, 0x17, 0x0f, 0x0c, 0x8d, 0x08, + 0x0b, 0xc6, 0xa9, 0x88, 0x07, 0x4e, 0x00, 0x38, 0x78, 0x3c, 0x9c, 0xa6, 0x20, 0xd3, 0xd1, 0x49, + 0xcd, 0xd3, 0x80, 0x00, 0x8e, 0x15, 0xba, 0xcf, 0x00, 0x03, 0x3c, 0x71, 0x0f, 0x8e, 0x03, 0x18, + 0x18, 0xb8, 0xac, 0x47, 0x9e, 0xc0, 0x56, 0xa2, 0xb1, 0x4f, 0x88, 0x05, 0xd9, 0x59, 0xb4, 0xa2, + 0xd8, 0xbf, 0x70, 0x24, 0xc4, 0x84, 0x45, 0x18, 0xad, 0xc5, 0x65, 0x63, 0x87, 0x70, 0x2c, 0x89, + 0x05, 0x42, 0x05, 0xd4, 0x5d, 0x76, 0xa3, 0xaf, 0xc9, 0x4e, 0xa3, 0xc2, 0x24, 0xc5, 0x6b, 0x92, + 0xf8, 0x31, 0x0a, 0x0a, 0x55, 0x8c, 0x30, 0x03, 0xf2, 0x43, 0x3b, 0x18, 0x0a, 0x9a, 0x87, 0x60, + 0x00, 0x43, 0x41, 0x69, 0xe0, 0xec, 0x1c, 0xd1, 0xcc, 0x03, 0x35, 0x96, 0xb5, 0x4c, 0x25, 0x34, + 0x77, 0x55, 0x62, 0x9e, 0x71, 0x30, 0xa5, 0xb4, 0x4e, 0xf2, 0xe6, 0x2f, 0xf3, 0xf5, 0x46, 0x78, + 0x07, 0x07, 0x97, 0x29, 0x04, 0xad, 0x97, 0x07, 0x6c, 0x36, 0x78, 0xf8, 0x50, 0x4a, 0xe0, 0x94, + 0x73, 0x88, 0x97, 0x69, 0x6e, 0x55, 0x75, 0xe4, 0x5d, 0xa8, 0x9f, 0x73, 0xfd, 0xf8, 0x91, 0x00, + 0xb0, 0x47, 0x06, 0x5a, 0xf0, 0xe2, 0xa0, 0xee, 0x49, 0x00, 0x62, 0x8e, 0x01, 0xcb, 0x88, 0x76, + 0xf8, 0x29, 0x85, 0x15, 0x2c, 0x64, 0xa9, 0x8c, 0xff, 0xfb, 0x73, 0xe7, 0xde, 0x21, 0x04, 0xce, + 0xb3, 0xeb, 0xd1, 0x1d, 0x6b, 0xeb, 0x14, 0xdd, 0x6a, 0x7e, 0xb1, 0x5f, 0x58, 0x43, 0xc1, 0x16, + 0x76, 0x0f, 0x4d, 0xab, 0x97, 0x9e, 0x87, 0xa7, 0x88, 0x2a, 0x49, 0x69, 0x25, 0xf8, 0x24, 0xe9, + 0x25, 0x17, 0xc2, 0x7d, 0x24, 0xb4, 0x92, 0xf1, 0xd6, 0x9a, 0xda, 0x6b, 0x69, 0xaf, 0xc6, 0x76, + 0x9a, 0xb6, 0xd2, 0xed, 0x35, 0xb4, 0xd2, 0xe5, 0xb7, 0x6b, 0xea, 0x95, 0x78, 0x23, 0xa4, 0x93, + 0x4d, 0x25, 0x4b, 0xa2, 0x45, 0xf5, 0x8b, 0xc4, 0x02, 0x58, 0xba, 0x8b, 0x8b, 0xec, 0x47, 0xc6, + 0xf8, 0xd1, 0x8a, 0x2c, 0x5f, 0x63, 0x84, 0xfc, 0x80, 0x98, 0x00, 0x18, 0x72, 0xae, 0x06, 0x83, + 0x20, 0x83, 0xaf, 0x70, 0x6c, 0x1a, 0xec, 0xb0, 0x18, 0x31, 0x6a, 0x1e, 0x56, 0x2e, 0x41, 0xc8, + 0x0a, 0x00, 0x41, 0x21, 0x00, 0x9c, 0x07, 0x4e, 0x02, 0x70, 0x3d, 0x80, 0x86, 0x07, 0x60, 0x14, + 0x70, 0x76, 0x1c, 0x22, 0x30, 0x85, 0xe2, 0x9a, 0x8b, 0x92, 0x2f, 0x64, 0xbb, 0x5d, 0x4d, 0x27, + 0xe1, 0x6d, 0x81, 0x8e, 0x97, 0x37, 0x25, 0x34, 0xf0, 0xa0, 0x45, 0xc1, 0x89, 0xf4, 0xf4, 0x9c, + 0x27, 0x15, 0xbb, 0x95, 0x86, 0x98, 0x76, 0x07, 0xe3, 0xb8, 0xcd, 0xe9, 0x29, 0x90, 0xd0, 0x52, + 0x0e, 0x22, 0x80, 0x31, 0xb5, 0x6d, 0x67, 0xa6, 0x9f, 0xfb, 0x82, 0x6b, 0xc3, 0xc5, 0x80, 0x7a, + 0xc7, 0x3b, 0xbe, 0x19, 0x82, 0xc0, 0xa1, 0xf6, 0x73, 0x50, 0x90, 0x2f, 0xa7, 0xbb, 0xf4, 0xa6, + 0xe3, 0xcf, 0x2f, 0xee, 0x20, 0x48, 0x52, 0xc0, 0x51, 0x47, 0x4f, 0x14, 0x60, 0x9e, 0x81, 0x55, + 0x47, 0x1c, 0x26, 0x38, 0x53, 0x55, 0x37, 0x31, 0x13, 0x61, 0x42, 0xbf, 0x2f, 0xd3, 0x3f, 0x0a, + 0x0f, 0x28, 0xc0, 0x84, 0x4d, 0x3d, 0x67, 0xd8, 0xd2, 0xd4, 0x66, 0x38, 0x30, 0x1c, 0xee, 0x28, + 0xae, 0xce, 0xc3, 0xb2, 0x63, 0xe2, 0xc7, 0x2d, 0x56, 0x17, 0xa8, 0x2a, 0xa5, 0x16, 0x90, 0xa7, + 0x38, 0x90, 0x53, 0x52, 0xf0, 0xf9, 0x59, 0x24, 0x7c, 0xb4, 0xb4, 0x97, 0x15, 0xbe, 0x14, 0x8a, + 0x25, 0x33, 0xb9, 0x8c, 0xb8, 0x14, 0x01, 0x40, 0x21, 0x09, 0x96, 0x00, 0xc5, 0x18, 0xa3, 0x77, + 0xfa, 0xfe, 0x19, 0xe8, 0x98, 0x49, 0xd1, 0x98, 0x7a, 0xf4, 0xdc, 0x11, 0x89, 0x9e, 0x9a, 0x70, + 0xf5, 0x4a, 0xbc, 0x12, 0x73, 0xd0, 0xf4, 0x4a, 0xbd, 0x7b, 0xeb, 0xdf, 0x05, 0x13, 0xd0, 0xf4, + 0xcf, 0x4e, 0x55, 0xfd, 0x79, 0xf8, 0x40, 0x48, 0x27, 0x18, 0xce, 0x8c, 0x66, 0x02, 0x67, 0x8c, + 0x07, 0x0c, 0x14, 0x9f, 0x65, 0x23, 0xe2, 0xc4, 0x57, 0xc2, 0x86, 0x3f, 0xcb, 0x0e, 0xb1, 0x71, + 0xf7, 0x7f, 0x67, 0x3d, 0xfb, 0x1d, 0x8a, 0xe6, 0x8d, 0x4d, 0xcb, 0x71, 0x21, 0x90, 0x4c, 0x11, + 0x28, 0x46, 0x34, 0x22, 0x0f, 0xc3, 0xa6, 0x51, 0x78, 0x86, 0x8d, 0x58, 0x79, 0xc4, 0xfc, 0x18, + 0x88, 0xe0, 0xc4, 0x40, 0xab, 0xdd, 0xdb, 0x07, 0xef, 0x7c, 0x21, 0xe8, 0xd0, 0x17, 0x10, 0x11, + 0x09, 0x0a, 0x62, 0x40, 0xf1, 0x43, 0x2c, 0xe5, 0x5e, 0x23, 0x9c, 0xb9, 0xe0, 0xac, 0x78, 0x2a, + 0xb5, 0x0b, 0xcd, 0x5b, 0xff, 0x6c, 0x11, 0x6c, 0xb5, 0x91, 0x81, 0xa4, 0xc4, 0xca, 0xce, 0x31, + 0x02, 0x41, 0x21, 0x33, 0x2b, 0x1a, 0x80, 0x77, 0xc2, 0x82, 0xb9, 0x79, 0x6d, 0x30, 0xac, 0x25, + 0x16, 0x4c, 0xc7, 0x47, 0x38, 0x18, 0x1c, 0x30, 0x5f, 0x9b, 0xe0, 0x78, 0xe4, 0x78, 0xed, 0xc2, + 0x30, 0x52, 0x13, 0x12, 0xe2, 0x3e, 0xf5, 0x68, 0xf4, 0xe0, 0xaa, 0xa4, 0xff, 0x04, 0xd8, 0x33, + 0x13, 0x39, 0x34, 0x92, 0xf1, 0x71, 0x83, 0x78, 0x94, 0x24, 0x68, 0x00, 0xa4, 0x2d, 0xd1, 0x9c, + 0xbe, 0x8c, 0xff, 0x45, 0x70, 0x4e, 0x8e, 0x5e, 0x49, 0xd1, 0x1c, 0x93, 0x84, 0x73, 0xd3, 0x3d, + 0x0f, 0x4c, 0xf4, 0x3d, 0x3f, 0x37, 0x3d, 0x0f, 0x42, 0x62, 0x78, 0x81, 0x00, 0xb0, 0x62, 0x02, + 0x78, 0x60, 0x25, 0xe7, 0x00, 0xb1, 0x59, 0xb9, 0x76, 0xd8, 0xad, 0x4c, 0x34, 0x61, 0x6e, 0x20, + 0x30, 0x14, 0x31, 0x66, 0x2e, 0x59, 0x8b, 0x93, 0x92, 0x8d, 0x31, 0xed, 0x83, 0x83, 0xdb, 0xc7, + 0x8b, 0xb7, 0x07, 0x65, 0x35, 0x83, 0xc7, 0x93, 0x33, 0x9d, 0xf0, 0xb0, 0x44, 0x79, 0xcc, 0x01, + 0xa8, 0x80, 0x15, 0x86, 0xc1, 0x06, 0xef, 0x07, 0x28, 0xc4, 0xb6, 0x0a, 0x4b, 0x2e, 0xda, 0xd7, + 0x72, 0x3e, 0x74, 0x71, 0x54, 0x76, 0x39, 0xc4, 0xf2, 0x7a, 0xde, 0x78, 0x7c, 0x13, 0x96, 0x72, + 0x0c, 0xb1, 0xb1, 0xc2, 0x4e, 0x52, 0x03, 0x83, 0xfe, 0x0b, 0x02, 0x49, 0x89, 0x3d, 0x4b, 0x3a, + 0x1b, 0x71, 0xdc, 0x5c, 0x4f, 0x93, 0x44, 0x05, 0xdc, 0x8d, 0xc4, 0x88, 0x19, 0x67, 0xf1, 0x59, + 0xe0, 0xe6, 0x25, 0xf3, 0xdf, 0x17, 0xf8, 0x88, 0x4f, 0x3a, 0xd2, 0x58, 0x76, 0x17, 0xde, 0x26, + 0x0b, 0x49, 0xcd, 0x00, 0xa3, 0x88, 0xb9, 0x66, 0xbd, 0xc4, 0x86, 0x01, 0x48, 0x44, 0x3e, 0x00, + 0xbf, 0x85, 0xd8, 0x24, 0x12, 0xc7, 0xd5, 0xd7, 0x56, 0x8d, 0x0e, 0xa1, 0xbf, 0x64, 0x5c, 0x5c, + 0x6a, 0x07, 0x58, 0x14, 0x03, 0x1f, 0x42, 0x4e, 0x92, 0x70, 0x42, 0x43, 0xd0, 0xf4, 0xea, 0xba, + 0x34, 0x1f, 0x59, 0x57, 0x38, 0x91, 0xe5, 0x4d, 0x34, 0xd3, 0xf1, 0x9d, 0x1b, 0x0f, 0xa3, 0xb9, + 0x7d, 0x5a, 0xfa, 0xb8, 0x27, 0x25, 0xd5, 0xdf, 0xd1, 0x99, 0x2f, 0x42, 0x4a, 0x92, 0x40, 0x83, + 0x30, 0x8c, 0xc2, 0x02, 0x30, 0x08, 0x0e, 0x26, 0x0b, 0x09, 0x71, 0xbc, 0x6e, 0xd3, 0xbc, 0xc9, + 0xb0, 0x44, 0xc6, 0x70, 0xf1, 0x20, 0xb0, 0x41, 0x6e, 0xcf, 0x4b, 0x7b, 0xbb, 0x76, 0xe5, 0x0c, + 0x70, 0x42, 0x14, 0x9c, 0x0e, 0x1c, 0x03, 0x87, 0x83, 0x87, 0x80, 0xe1, 0x6e, 0xc9, 0xc4, 0x60, + 0xf7, 0x97, 0xa9, 0xc8, 0xf6, 0x04, 0x82, 0xa5, 0x80, 0x3c, 0xfe, 0x08, 0x41, 0x5d, 0xd3, 0xa6, + 0xc9, 0xbb, 0x63, 0x1c, 0xbc, 0x38, 0x70, 0x94, 0x1a, 0x8b, 0x69, 0x36, 0x5f, 0xcb, 0xc1, 0x48, + 0x2c, 0xe5, 0x55, 0xe5, 0xa0, 0xae, 0x21, 0xf3, 0xe7, 0x70, 0xc0, 0x29, 0x0a, 0x13, 0x14, 0xc5, + 0xc5, 0xcb, 0xe5, 0x54, 0xbc, 0x5e, 0x57, 0x77, 0xcb, 0xc4, 0x82, 0xb3, 0xee, 0xef, 0x9f, 0xf8, + 0x51, 0xa4, 0xbe, 0x0b, 0x4d, 0x5b, 0x95, 0xf8, 0xb9, 0x17, 0xee, 0x05, 0x00, 0x40, 0x09, 0x42, + 0xa3, 0x88, 0x1e, 0x0e, 0x8f, 0x1f, 0xa5, 0xe4, 0xc5, 0xd4, 0x89, 0xe1, 0x04, 0x74, 0xa9, 0xf1, + 0xc6, 0x3d, 0x0f, 0x4c, 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0xd7, 0x46, 0xaf, 0xaf, 0x57, 0x47, 0x77, + 0xcd, 0xcf, 0x43, 0xd1, 0x71, 0x53, 0xd0, 0xf4, 0xcf, 0x43, 0xd3, 0x11, 0xc4, 0x14, 0x56, 0x2b, + 0x15, 0x8a, 0xc5, 0x62, 0xb1, 0x58, 0xad, 0xf1, 0x7d, 0x24, 0x98, 0x3b, 0x4d, 0x13, 0xab, 0x9f, + 0x11, 0x69, 0xad, 0xa6, 0xb2, 0xf0, 0x9e, 0x9b, 0x5d, 0x24, 0x97, 0x13, 0xb7, 0x6e, 0xdd, 0xbf, + 0x46, 0x99, 0xf4, 0x73, 0xa5, 0xf5, 0x3a, 0x49, 0xd1, 0x2b, 0xfe, 0x24, 0x22, 0x29, 0x6b, 0x3f, + 0x33, 0x07, 0xe5, 0xe5, 0xe2, 0xea, 0x2f, 0xe3, 0x2e, 0xef, 0x11, 0xf1, 0x7c, 0x5e, 0x60, 0x40, + 0x15, 0x2f, 0x9f, 0x13, 0x19, 0x12, 0xe4, 0xd5, 0xe0, 0x00, 0x16, 0x90, 0x58, 0x30, 0x4b, 0x1d, + 0x6d, 0xe2, 0x47, 0xc4, 0x8e, 0x78, 0xec, 0x8d, 0x04, 0x03, 0x77, 0x29, 0x48, 0x1a, 0x41, 0x67, + 0xb5, 0x99, 0x6f, 0x11, 0x0a, 0x4b, 0x18, 0x81, 0x80, 0x80, 0x1c, 0x2c, 0x1c, 0xdd, 0xe0, 0x84, + 0xbf, 0x12, 0xfe, 0xee, 0xfc, 0x44, 0x22, 0x44, 0xe7, 0xe9, 0xbb, 0x88, 0x48, 0x37, 0x59, 0x3b, + 0x6a, 0x10, 0x78, 0xc3, 0x72, 0x6a, 0xde, 0x59, 0x02, 0xa8, 0xb9, 0x11, 0x50, 0xb1, 0x17, 0x2c, + 0x03, 0x2f, 0x91, 0x75, 0xc0, 0xc0, 0x18, 0x0a, 0x04, 0xc0, 0xa0, 0xe0, 0x1a, 0xa7, 0x56, 0x67, + 0xbd, 0x86, 0xef, 0x95, 0x66, 0x1d, 0xcf, 0x10, 0xcf, 0x9a, 0xa8, 0x63, 0x78, 0x40, 0x41, 0xd2, + 0x49, 0x24, 0x92, 0x49, 0x2f, 0x82, 0x2a, 0x49, 0x64, 0x4f, 0x82, 0x2a, 0x49, 0x71, 0x5f, 0x04, + 0xfa, 0x74, 0xd3, 0x42, 0x4d, 0x32, 0x27, 0xd7, 0x09, 0x38, 0x8b, 0x4d, 0x75, 0x55, 0xbe, 0x89, + 0xdf, 0x45, 0x78, 0x57, 0x89, 0xd3, 0x69, 0x0b, 0x69, 0xaf, 0x58, 0xa4, 0xe8, 0xc6, 0x4f, 0xa9, + 0x12, 0xf8, 0x2a, 0xf3, 0x74, 0x06, 0x03, 0xf3, 0x4a, 0x49, 0x41, 0x15, 0x0a, 0xb8, 0xe0, 0x2d, + 0xd0, 0x85, 0x85, 0x78, 0x13, 0xb8, 0x80, 0xc8, 0x2c, 0x19, 0x15, 0xca, 0x20, 0x2b, 0x95, 0x0b, + 0x57, 0x50, 0xc8, 0x52, 0xd0, 0xff, 0x08, 0x09, 0x0a, 0x59, 0xf3, 0xac, 0x52, 0x9f, 0x1c, 0x9e, + 0xce, 0xd8, 0xa0, 0x62, 0x43, 0x82, 0x81, 0x96, 0x19, 0xde, 0xe1, 0x08, 0x2a, 0x2a, 0x47, 0x70, + 0x32, 0x09, 0x02, 0xe4, 0x05, 0x99, 0x08, 0x49, 0x82, 0x20, 0x93, 0x23, 0x8a, 0xa5, 0xe9, 0xb8, + 0x88, 0x50, 0x89, 0x2a, 0xd8, 0x4c, 0xcf, 0x54, 0xea, 0xb5, 0x63, 0xc4, 0x88, 0x2d, 0xbb, 0x97, + 0xbb, 0xd9, 0xff, 0x8c, 0xdb, 0xee, 0xba, 0xda, 0x17, 0x13, 0xc1, 0x75, 0x95, 0xe2, 0x46, 0x15, + 0xa6, 0x25, 0x8f, 0x98, 0x58, 0x24, 0x6a, 0x36, 0xc9, 0xec, 0xf5, 0x0b, 0x1b, 0x99, 0x46, 0x09, + 0x66, 0x3f, 0xfe, 0x14, 0x18, 0xde, 0xff, 0xc2, 0xf5, 0xad, 0x97, 0x3a, 0xc1, 0x54, 0x5c, 0x7f, + 0x1b, 0x89, 0x08, 0x20, 0xb9, 0xd2, 0xba, 0x25, 0x57, 0x19, 0xcf, 0x43, 0xd3, 0x3d, 0x0f, 0x4c, + 0xf4, 0x3d, 0x33, 0xd0, 0xf4, 0xf1, 0x1e, 0x5a, 0x1d, 0x8b, 0xd8, 0xf8, 0x9c, 0xec, 0x4e, 0xc4, + 0xec, 0x4e, 0xc1, 0x3a, 0x38, 0xea, 0xf8, 0x21, 0x34, 0xec, 0x4e, 0xc3, 0x5f, 0x5a, 0x8c, 0xe1, + 0x2e, 0x7a, 0x1e, 0x99, 0xe8, 0x7a, 0x78, 0x21, 0xe7, 0xa1, 0xe8, 0xd1, 0x5d, 0x4a, 0xb3, 0xe2, + 0xf9, 0xe8, 0x7a, 0x67, 0xa1, 0xe9, 0xe8, 0x99, 0x5f, 0x45, 0x4e, 0x98, 0x71, 0x14, 0x00, 0xc2, + 0xdd, 0x76, 0x4f, 0x3e, 0xbd, 0x95, 0xa3, 0xfb, 0x7c, 0x4d, 0x4f, 0xde, 0xfc, 0x41, 0x02, 0xc5, + 0xe5, 0x9a, 0xf8, 0x81, 0xb3, 0xcf, 0x67, 0x13, 0xec, 0xd9, 0x14, 0xc9, 0x6a, 0x78, 0x1e, 0x0a, + 0xab, 0x81, 0x04, 0x68, 0x91, 0x40, 0xaa, 0xd5, 0x6d, 0x92, 0x38, 0x70, 0x86, 0x41, 0x08, 0x3c, + 0x40, 0x7b, 0x11, 0x85, 0x73, 0x8b, 0x62, 0x34, 0x13, 0x8f, 0x00, 0x43, 0x32, 0xfa, 0x67, 0xf5, + 0x78, 0x52, 0x38, 0xb5, 0x95, 0xd4, 0x16, 0x16, 0xb1, 0x45, 0xcb, 0xc5, 0x3a, 0x5c, 0xe3, 0x20, + 0x3e, 0x86, 0xd7, 0x82, 0xdf, 0xc9, 0x55, 0x70, 0x1b, 0x82, 0x59, 0x8b, 0x9e, 0x01, 0x8b, 0xf7, + 0x10, 0x11, 0x09, 0xd4, 0x53, 0xac, 0x51, 0xc5, 0x78, 0x81, 0x22, 0xce, 0xe3, 0xbe, 0x7b, 0x69, + 0x05, 0xdf, 0x97, 0x89, 0x12, 0x14, 0x29, 0x32, 0x83, 0xb4, 0x15, 0x14, 0x23, 0xde, 0x6e, 0x7b, + 0xed, 0x60, 0x44, 0x08, 0x10, 0x75, 0x95, 0x8d, 0x26, 0x5f, 0x3a, 0x78, 0xb2, 0x12, 0x9a, 0xe2, + 0xe2, 0x3f, 0x1e, 0x29, 0x55, 0x49, 0xa7, 0x8e, 0x65, 0x47, 0x04, 0x04, 0xfe, 0x2b, 0xa1, 0x67, + 0x62, 0x9f, 0x0c, 0x85, 0x03, 0x33, 0x7c, 0x4f, 0x0d, 0x89, 0x44, 0x28, 0xcf, 0xc1, 0x54, 0x68, + 0x18, 0xd9, 0x36, 0x73, 0x9c, 0x10, 0xe0, 0xc0, 0x40, 0x91, 0x7d, 0x11, 0xc9, 0xfa, 0xd5, 0x75, + 0x31, 0xbe, 0xa9, 0x50, 0xde, 0x08, 0xc8, 0xf7, 0xb1, 0xf5, 0x63, 0xeb, 0x29, 0xba, 0x2d, 0x5c, + 0x18, 0x88, 0x04, 0x9c, 0xc8, 0x03, 0xc8, 0x1a, 0x75, 0xf0, 0xa0, 0x4a, 0x28, 0xe1, 0x50, 0x68, + 0xe0, 0xb2, 0xb2, 0x16, 0xca, 0x8a, 0xc2, 0x63, 0xaf, 0xb6, 0x0f, 0x83, 0xf5, 0x70, 0x84, 0xd4, + 0x61, 0xbe, 0x14, 0x23, 0x24, 0x86, 0x0a, 0x01, 0xb5, 0x69, 0xe2, 0x88, 0x2d, 0xe4, 0x5c, 0xe0, + 0x19, 0xfc, 0x07, 0x27, 0x86, 0xb9, 0x4c, 0xbe, 0x03, 0x60, 0x1c, 0xa4, 0x53, 0xc0, 0x65, 0xb2, + 0xa1, 0x79, 0x44, 0x50, 0x3f, 0x08, 0xf7, 0x47, 0x1b, 0x24, 0x1c, 0x50, 0x06, 0x48, 0x15, 0xb7, + 0xc9, 0x68, 0xae, 0xe7, 0x14, 0x0a, 0xa1, 0xe3, 0xf6, 0xc1, 0xd7, 0x88, 0x64, 0xe1, 0x79, 0xf3, + 0x29, 0x28, 0xdd, 0xb3, 0x70, 0x12, 0x04, 0x5d, 0xbc, 0x85, 0xcf, 0xb9, 0x3a, 0xf1, 0xd0, 0x60, + 0x67, 0xb3, 0x8d, 0x99, 0x6d, 0x0f, 0x7d, 0x65, 0x83, 0xaf, 0x97, 0x96, 0xb5, 0x76, 0x14, 0x89, + 0x28, 0x89, 0xe0, 0xd2, 0x55, 0xa1, 0x96, 0x52, 0x1c, 0x40, 0x48, 0xf1, 0x78, 0xbe, 0x5e, 0x8f, + 0xc6, 0x1a, 0xdc, 0x02, 0x8b, 0x8c, 0x56, 0x27, 0xfc, 0x76, 0x53, 0x43, 0x0f, 0xae, 0xe8, 0x68, + 0x1a, 0x69, 0x22, 0x21, 0xa4, 0x0e, 0x3d, 0xc4, 0x56, 0x6b, 0x7a, 0xd6, 0x14, 0xc2, 0x4d, 0x4c, + 0x40, 0x80, 0xa0, 0x93, 0x93, 0x14, 0xe3, 0x52, 0xa6, 0xe4, 0x84, 0x93, 0x65, 0xa7, 0x9a, 0x20, + 0x6f, 0x7b, 0xbb, 0xde, 0x4f, 0xb0, 0x5e, 0xe4, 0xe6, 0xa3, 0x85, 0x43, 0xf8, 0x90, 0x54, 0x73, + 0x72, 0x90, 0xee, 0xe5, 0xcd, 0x69, 0x24, 0xfe, 0x24, 0x13, 0x88, 0x8f, 0x04, 0x23, 0x2e, 0xc1, + 0x57, 0xfe, 0x18, 0x05, 0x7a, 0x82, 0xd2, 0xf0, 0x34, 0x6b, 0x03, 0x38, 0x5e, 0x4c, 0xdb, 0x3a, + 0x60, 0xcd, 0x2f, 0x44, 0xc2, 0x40, 0x63, 0x75, 0xc8, 0xcd, 0x03, 0x35, 0x7d, 0x04, 0xd3, 0xb5, + 0xd4, 0x89, 0x7d, 0x5c, 0x04, 0xfa, 0x22, 0x74, 0xba, 0xbf, 0xd5, 0x2a, 0x5c, 0xd1, 0x58, 0xac, + 0x56, 0x2b, 0xf5, 0x68, 0xbe, 0xad, 0xe2, 0x01, 0x61, 0x8a, 0x80, 0xb5, 0x8f, 0x8c, 0x32, 0x73, + 0x90, 0xd9, 0x96, 0x62, 0xd5, 0xdb, 0xea, 0x47, 0xe5, 0xd8, 0xb9, 0x61, 0x75, 0xdf, 0x3c, 0xb8, + 0x88, 0x2a, 0xbf, 0x66, 0x19, 0x78, 0x52, 0x30, 0x91, 0x63, 0x6a, 0xf1, 0xd5, 0xc5, 0x61, 0xc0, + 0x42, 0x02, 0x51, 0x7c, 0x69, 0x92, 0x83, 0x2a, 0x90, 0x81, 0xbf, 0xa2, 0x5f, 0x24, 0xb0, 0x1a, + 0x59, 0x88, 0xcb, 0x81, 0xb9, 0x71, 0xbc, 0x0e, 0x3a, 0x37, 0x4d, 0xb1, 0xa1, 0x1c, 0xf2, 0xc1, + 0x9c, 0x03, 0x02, 0xc6, 0x58, 0x89, 0x7e, 0x5a, 0x3f, 0xe1, 0x43, 0x2f, 0xca, 0x05, 0x8e, 0x3e, + 0x99, 0x71, 0xdf, 0xc5, 0x65, 0xc2, 0xc6, 0x28, 0xc4, 0x0e, 0x0a, 0x0c, 0xb0, 0x1d, 0x2f, 0x10, + 0x20, 0x60, 0x94, 0x1a, 0x25, 0x9c, 0xbc, 0xc6, 0x24, 0xae, 0x32, 0xb1, 0x28, 0xac, 0xb8, 0x2f, + 0x79, 0x7e, 0x24, 0x48, 0xd2, 0x4b, 0x4b, 0x52, 0x13, 0x4c, 0xeb, 0x11, 0x8a, 0x6e, 0xb3, 0xa4, + 0xb3, 0x7c, 0xda, 0x75, 0xa6, 0xe5, 0xb7, 0x77, 0x3e, 0x7e, 0xb5, 0xc4, 0x09, 0x19, 0x52, 0xa9, + 0x35, 0xc9, 0x0e, 0x07, 0x70, 0x7b, 0xc2, 0xaa, 0x0e, 0xfe, 0x87, 0xe8, 0x5b, 0x39, 0xc9, 0x75, + 0xef, 0x10, 0x24, 0x13, 0x09, 0xd4, 0xbe, 0xce, 0xfe, 0x02, 0x17, 0x67, 0xc1, 0x5d, 0xd8, 0xdc, + 0x81, 0xc7, 0xb6, 0xe2, 0xb7, 0x77, 0xf9, 0xc1, 0x48, 0x31, 0x1e, 0x32, 0xc2, 0xac, 0xd7, 0x64, + 0x38, 0xf1, 0x42, 0xb0, 0xa0, 0x03, 0xe8, 0xb2, 0x96, 0xdc, 0x94, 0xae, 0x0a, 0x41, 0x88, 0x2b, + 0xef, 0xf4, 0xa3, 0xd5, 0xb3, 0xd5, 0x00, 0x02, 0x9a, 0xdb, 0x58, 0xc1, 0xa4, 0xe2, 0xc2, 0x67, + 0xa1, 0xe9, 0x9e, 0x87, 0xa7, 0xe1, 0x09, 0xe8, 0x7a, 0x68, 0xcf, 0x4c, 0xf4, 0x3d, 0x32, 0xf4, + 0x74, 0xd0, 0x87, 0x42, 0x19, 0x1f, 0xd0, 0x4d, 0xcf, 0x82, 0x41, 0x82, 0x98, 0x89, 0x88, 0x9f, + 0x2f, 0x7e, 0x19, 0x0c, 0x8d, 0x18, 0xaa, 0xa2, 0xeb, 0x51, 0x54, 0x5e, 0x2e, 0x29, 0x8c, 0x60, + 0xb0, 0xde, 0x84, 0xf0, 0x1b, 0x01, 0xdb, 0xdd, 0x7f, 0x84, 0x03, 0xda, 0x6e, 0x31, 0x89, 0xe5, + 0x55, 0x40, 0x90, 0x36, 0x81, 0xda, 0x91, 0x3f, 0x0e, 0xae, 0xeb, 0xfe, 0x10, 0x21, 0xe1, 0xbc, + 0x91, 0x89, 0x99, 0xf9, 0x79, 0x6f, 0x10, 0x24, 0x15, 0x19, 0xc5, 0x62, 0xb7, 0x3c, 0x73, 0x3f, + 0x90, 0xe3, 0x90, 0xab, 0xe3, 0x8d, 0x2a, 0xe2, 0x41, 0x65, 0xdd, 0xe4, 0xe3, 0x4c, 0x2c, 0xde, + 0xc6, 0x27, 0x40, 0x7d, 0x82, 0x8c, 0xf1, 0xcc, 0xcf, 0x89, 0x16, 0x9e, 0x33, 0x93, 0x60, 0x4e, + 0xe4, 0xfc, 0x6f, 0x7f, 0xc4, 0x86, 0x46, 0x45, 0xc5, 0xd5, 0x56, 0x2b, 0x15, 0xac, 0x5e, 0x28, + 0xc5, 0x18, 0xac, 0x18, 0xf9, 0x60, 0xa6, 0x14, 0x39, 0x39, 0xed, 0x16, 0x50, 0xe1, 0xe8, 0x40, + 0x56, 0x87, 0x1f, 0x4e, 0x70, 0x3f, 0x96, 0x81, 0xd7, 0x11, 0xf0, 0xe1, 0xc3, 0x84, 0x82, 0x78, + 0x24, 0x12, 0xc1, 0xb8, 0xc2, 0x01, 0x10, 0xa1, 0x47, 0x5f, 0x2e, 0x89, 0x15, 0x38, 0x18, 0x03, + 0xcb, 0x05, 0x03, 0xac, 0x50, 0x32, 0xc0, 0x01, 0x93, 0x80, 0x0a, 0x85, 0x40, 0x1c, 0x16, 0xca, + 0xff, 0x95, 0x2b, 0x22, 0xc0, 0x68, 0x40, 0x62, 0x45, 0x8c, 0x5e, 0x20, 0x48, 0xe1, 0x1b, 0xbd, + 0xa7, 0x5b, 0x15, 0xdb, 0xf8, 0x46, 0x34, 0xa8, 0xa9, 0xef, 0x43, 0x10, 0xb0, 0xc7, 0xcd, 0xcb, + 0x9f, 0x85, 0x06, 0x3d, 0xf5, 0xbb, 0xb7, 0x97, 0x40, 0xcf, 0x95, 0x44, 0xce, 0x4f, 0x89, 0x31, + 0xa4, 0x74, 0xb9, 0x6c, 0xb6, 0x2a, 0x1a, 0xb0, 0xe6, 0x1d, 0xc1, 0x48, 0x31, 0x04, 0x65, 0x6a, + 0xdc, 0x2e, 0x1e, 0x85, 0x3a, 0x17, 0x5f, 0x5c, 0xa6, 0xea, 0xf5, 0xd5, 0xe5, 0xea, 0xff, 0x5c, + 0xab, 0xab, 0x9f, 0x44, 0x73, 0xe8, 0xe3, 0x9b, 0xe0, 0x92, 0x2e, 0x2e, 0x2e, 0xac, 0x30, 0xc8, + 0x44, 0x16, 0x19, 0x45, 0xd7, 0x2e, 0x05, 0x14, 0x05, 0x83, 0x6b, 0x03, 0xd7, 0x9a, 0x08, 0x45, + 0xa0, 0x79, 0x58, 0x7c, 0x29, 0x17, 0x3c, 0xd1, 0x7d, 0x4d, 0xe6, 0xac, 0xa4, 0xb3, 0x63, 0x48, + 0xd4, 0x31, 0x21, 0x00, 0xa4, 0xba, 0xf4, 0xda, 0x4a, 0x21, 0x5b, 0x8a, 0xe5, 0xc3, 0xe2, 0xf4, + 0xd1, 0xdf, 0x12, 0x30, 0x90, 0xdd, 0x49, 0xe1, 0xc3, 0x68, 0xaa, 0x07, 0xbf, 0xa7, 0x6f, 0x2e, + 0x45, 0x61, 0x7f, 0x17, 0xe3, 0xd7, 0x7f, 0x0a, 0x19, 0x54, 0xbd, 0x53, 0x05, 0x00, 0x01, 0x26, + 0xc1, 0x78, 0x78, 0x06, 0x44, 0x02, 0x39, 0x33, 0x38, 0x79, 0x40, 0x00, 0x26, 0x88, 0x04, 0x3c, + 0x15, 0xe0, 0x0d, 0x93, 0xa2, 0x3b, 0xc4, 0x09, 0x19, 0x2c, 0x06, 0x34, 0x3c, 0x02, 0x9b, 0x0e, + 0x0c, 0xb5, 0x2a, 0x8e, 0xa6, 0x1f, 0xa6, 0x5e, 0xcc, 0x38, 0x33, 0xd0, 0xb0, 0x55, 0x91, 0xe0, + 0xc8, 0xaa, 0x07, 0x05, 0x65, 0x25, 0x3f, 0x88, 0x85, 0x07, 0x87, 0x54, 0xd6, 0xe2, 0xd5, 0x17, + 0x49, 0x59, 0x45, 0x55, 0xaa, 0xab, 0x38, 0x80, 0x82, 0x33, 0xf0, 0x20, 0x84, 0x42, 0x82, 0xc4, + 0xea, 0x39, 0x01, 0xf0, 0x66, 0x40, 0x62, 0x01, 0x0b, 0x94, 0x4a, 0x00, 0x04, 0x44, 0x04, 0xf0, + 0x00, 0x23, 0x85, 0xa0, 0x3e, 0x70, 0x00, 0xb0, 0x49, 0x18, 0x34, 0x40, 0xba, 0x8e, 0x57, 0xe9, + 0x96, 0x80, 0x0e, 0x08, 0xc0, 0x00, 0x9e, 0x05, 0x60, 0x1a, 0xae, 0x40, 0xd6, 0x00, 0x24, 0x68, + 0xa8, 0x65, 0xc0, 0x38, 0x3b, 0x62, 0x47, 0x70, 0x60, 0x6d, 0xef, 0xfc, 0x4b, 0xdf, 0xf6, 0xdb, + 0x6d, 0xb1, 0xc6, 0xf0, 0x62, 0x2a, 0x0c, 0xa6, 0x44, 0x96, 0x4d, 0xc2, 0x45, 0x90, 0xac, 0xb6, + 0x28, 0xc5, 0x1e, 0x20, 0x32, 0x33, 0x48, 0x84, 0x1f, 0xc6, 0x90, 0x6a, 0x82, 0x03, 0x78, 0xc6, + 0xef, 0x24, 0x51, 0x8d, 0x49, 0x88, 0x88, 0x11, 0x1f, 0x48, 0xa9, 0xc6, 0x9e, 0xda, 0x18, 0x18, + 0x3e, 0x20, 0x28, 0x29, 0x10, 0xa8, 0xfc, 0xbc, 0x57, 0x12, 0x90, 0x44, 0x38, 0x24, 0x7c, 0x43, + 0xdd, 0xef, 0xae, 0x0a, 0x41, 0x48, 0x28, 0x83, 0x48, 0xbc, 0x68, 0x4a, 0xdc, 0x63, 0x3a, 0xa2, + 0xa7, 0x3b, 0xf1, 0xdb, 0xc2, 0x27, 0x0a, 0xa2, 0x32, 0xfc, 0x55, 0xb6, 0x12, 0xe8, 0x47, 0x7d, + 0x17, 0x2f, 0xac, 0x57, 0xd1, 0x21, 0x95, 0xd1, 0x11, 0xd9, 0xfa, 0xc5, 0x2c, 0x10, 0x89, 0x05, + 0x72, 0x62, 0x88, 0x70, 0xb6, 0x2b, 0x15, 0x9b, 0x1d, 0x4a, 0x50, 0xab, 0x94, 0xdc, 0x4c, 0x12, + 0x19, 0xdf, 0x2a, 0x71, 0x22, 0x01, 0x77, 0x15, 0xc5, 0x6e, 0xee, 0xfe, 0x3e, 0x10, 0x3f, 0x3f, + 0x15, 0xdb, 0xdd, 0xaf, 0x10, 0x25, 0x94, 0x56, 0x70, 0xd1, 0xda, 0xc6, 0x22, 0x11, 0x11, 0x53, + 0x42, 0x57, 0x5a, 0x43, 0x03, 0x64, 0xe1, 0x49, 0xe1, 0x43, 0x0b, 0x8a, 0x62, 0x98, 0xa1, 0x97, + 0xbe, 0x78, 0x58, 0x34, 0x81, 0x83, 0x00, 0x02, 0x16, 0xa0, 0xa0, 0x06, 0x8a, 0xa0, 0x55, 0x30, + 0x1a, 0xb5, 0x23, 0x82, 0x71, 0x40, 0x8e, 0x35, 0xad, 0xe0, 0x70, 0x78, 0xf1, 0xcf, 0x10, 0x30, + 0xe6, 0x58, 0xf2, 0x98, 0x00, 0x11, 0x73, 0xc3, 0x21, 0x8f, 0x19, 0x1f, 0x12, 0xae, 0xa7, 0x45, + 0x1b, 0x99, 0xb6, 0xb1, 0x71, 0x96, 0x3f, 0x12, 0x75, 0x54, 0xae, 0xc4, 0xfc, 0x44, 0x55, 0xde, + 0xee, 0xee, 0xf8, 0x66, 0x20, 0xa4, 0x85, 0x4e, 0x79, 0xc7, 0x9c, 0xf2, 0xdd, 0x9e, 0xd0, 0xf7, + 0x30, 0x80, 0x31, 0x08, 0x4b, 0x6e, 0x79, 0x62, 0x4b, 0x92, 0x20, 0x1c, 0x24, 0x59, 0x43, 0x36, + 0x53, 0xe4, 0xa9, 0x70, 0x84, 0x64, 0x51, 0x85, 0x01, 0x40, 0x21, 0xe7, 0x02, 0xa1, 0x98, 0xee, + 0x90, 0x62, 0x4e, 0xe7, 0x18, 0x26, 0x3c, 0x94, 0xf3, 0x80, 0xc6, 0x6b, 0x65, 0xb3, 0x80, 0xe1, + 0x29, 0x95, 0x84, 0x02, 0x03, 0x25, 0xbf, 0x7e, 0xaa, 0x90, 0x81, 0xc7, 0xe1, 0x60, 0xed, 0x5f, + 0x88, 0x85, 0x2e, 0xe5, 0xf6, 0x5e, 0x6f, 0xe3, 0xd3, 0x77, 0x3b, 0x17, 0xff, 0x88, 0x96, 0xc5, + 0x62, 0xb7, 0x7d, 0xf1, 0x30, 0x58, 0x29, 0xb2, 0x65, 0xdd, 0xdd, 0xde, 0xee, 0x9d, 0x78, 0xc3, + 0x35, 0x66, 0x25, 0xbc, 0x1d, 0x59, 0xbb, 0xf1, 0x7b, 0xf0, 0x88, 0xb2, 0x89, 0x03, 0x82, 0xe7, + 0x6c, 0x7b, 0xc7, 0x7b, 0xf0, 0x8a, 0x09, 0xb4, 0x2b, 0xd0, 0x89, 0x57, 0x04, 0x47, 0x3d, 0x0f, + 0x4d, 0x3a, 0xf4, 0x54, 0xeb, 0xd1, 0x18, 0xfa, 0x94, 0x15, 0xc1, 0x11, 0x8f, 0x8f, 0xb7, 0xd5, + 0xbe, 0x8a, 0xe5, 0x72, 0xcf, 0x43, 0xd0, 0xb4, 0xfc, 0x13, 0xc5, 0x62, 0x1a, 0x0a, 0xcb, 0x68, + 0x77, 0x15, 0xe5, 0xc2, 0x21, 0x11, 0xe2, 0x1d, 0xde, 0xd3, 0x48, 0x18, 0xd3, 0x49, 0x7b, 0xf0, + 0x79, 0xc0, 0xa3, 0xb0, 0x80, 0x90, 0x54, 0x47, 0xe5, 0x4f, 0x25, 0xae, 0xb5, 0x5e, 0x47, 0xfc, + 0x61, 0x45, 0x6e, 0xf3, 0xc0, 0x1b, 0xb2, 0x92, 0xea, 0x8d, 0x51, 0x8f, 0x26, 0xf0, 0xea, 0xeb, + 0x94, 0xf0, 0xe7, 0x82, 0x6d, 0x4a, 0x5e, 0xca, 0x32, 0x06, 0x02, 0xcf, 0x54, 0xbe, 0x09, 0x4a, + 0x37, 0x6d, 0x4e, 0x35, 0x12, 0x45, 0xc6, 0xaa, 0xef, 0x10, 0x14, 0xb5, 0x0b, 0xbd, 0xc4, 0x9e, + 0x26, 0xc2, 0x6d, 0x34, 0xa4, 0x91, 0x71, 0x9a, 0xae, 0x01, 0x18, 0x93, 0xf0, 0x3a, 0xf0, 0x80, + 0xd1, 0x50, 0xb2, 0xb9, 0x88, 0x96, 0x20, 0x38, 0x36, 0x5a, 0xc0, 0xb4, 0xa4, 0xa1, 0x6d, 0xaf, + 0x00, 0x72, 0x16, 0x97, 0x25, 0x1a, 0x2f, 0x41, 0x46, 0x30, 0xba, 0xef, 0x80, 0x05, 0x65, 0x90, + 0x0a, 0xd1, 0xc0, 0x58, 0x5e, 0x80, 0x12, 0xa0, 0xf1, 0x19, 0x51, 0xa8, 0x7c, 0x73, 0x4f, 0xe3, + 0x6b, 0xc8, 0x10, 0x9d, 0xb3, 0xd4, 0xb0, 0xda, 0x35, 0x90, 0xeb, 0xd2, 0x7f, 0xcf, 0x0f, 0x38, + 0xeb, 0xfc, 0x19, 0xef, 0xe6, 0xef, 0xdf, 0x86, 0xdb, 0xa7, 0xe3, 0x25, 0xfc, 0xb8, 0x8c, 0xdc, + 0xb6, 0x70, 0xe3, 0x7c, 0x9c, 0x56, 0x7b, 0x9f, 0xc6, 0x14, 0xb6, 0x2a, 0xc7, 0x5f, 0xa4, 0x2e, + 0x4a, 0x55, 0x12, 0xb0, 0x15, 0xf1, 0x76, 0x1d, 0x59, 0x98, 0xc5, 0xbf, 0xf1, 0xe2, 0x48, 0xa5, + 0xb8, 0x63, 0xf9, 0x9e, 0x85, 0xbb, 0x15, 0x8a, 0x31, 0x46, 0x24, 0x68, 0x58, 0xf0, 0x88, 0x90, + 0x57, 0x26, 0x0c, 0x55, 0xe5, 0xe3, 0x3e, 0xd5, 0xd4, 0x4f, 0xa4, 0x26, 0x8c, 0x30, 0xdb, 0x0b, + 0xa2, 0x80, 0x03, 0xc3, 0xca, 0xf4, 0xb4, 0x9c, 0x7c, 0xff, 0x37, 0xf8, 0x4b, 0xc3, 0xb7, 0x70, + 0xfc, 0x76, 0x79, 0xa8, 0xb5, 0xac, 0x29, 0x6b, 0x10, 0xd6, 0xe9, 0xfd, 0xfd, 0x6d, 0xd7, 0xf5, + 0xb7, 0x48, 0x77, 0x8d, 0xe2, 0x4e, 0xe1, 0xf1, 0x18, 0x05, 0x3c, 0x32, 0x14, 0x37, 0x01, 0xb0, + 0x83, 0xa1, 0x9c, 0x1c, 0x38, 0xe5, 0x9c, 0x38, 0x03, 0x78, 0x8f, 0xde, 0x6d, 0x09, 0xcb, 0x08, + 0x70, 0x0f, 0x08, 0xd1, 0x89, 0x26, 0x46, 0xae, 0x46, 0x95, 0x18, 0xac, 0x40, 0x80, 0x94, 0x51, + 0xb6, 0x2b, 0x12, 0xfb, 0xc1, 0xfc, 0xd5, 0x55, 0x5e, 0x27, 0x89, 0x82, 0x32, 0x8a, 0xdc, 0xf4, + 0x2d, 0xa5, 0x78, 0x31, 0x08, 0x82, 0x72, 0x62, 0xb7, 0x15, 0x8a, 0xc4, 0x34, 0x3d, 0xc6, 0x1e, + 0x14, 0x30, 0xa3, 0x2d, 0x8a, 0x0c, 0x40, 0x0d, 0x01, 0x50, 0xc8, 0x91, 0x98, 0x1f, 0x73, 0x16, + 0x0c, 0xf0, 0x06, 0x82, 0x80, 0xcf, 0x1c, 0x2c, 0x06, 0x7b, 0xcb, 0x19, 0xe3, 0x87, 0x38, 0x70, + 0xe0, 0xd3, 0x1d, 0xf8, 0x50, 0xcd, 0xa4, 0xac, 0x1c, 0x40, 0xcb, 0x1d, 0x2c, 0x57, 0xcb, 0x65, + 0xb2, 0x61, 0x6c, 0xba, 0xcf, 0x01, 0x40, 0x5c, 0x74, 0xa9, 0x29, 0xe6, 0x3c, 0x22, 0x0a, 0x04, + 0x8a, 0x34, 0x05, 0x52, 0xd9, 0xc5, 0x1b, 0x47, 0x76, 0xe6, 0x8e, 0xdf, 0x56, 0x44, 0x74, 0x76, + 0x3e, 0xba, 0xfa, 0x36, 0xa4, 0xe8, 0xf9, 0x7c, 0xb7, 0xbd, 0xf5, 0xce, 0x7d, 0x73, 0x9f, 0x5c, + 0xe7, 0xd7, 0xa7, 0xe8, 0xa5, 0x43, 0x83, 0xc1, 0x0c, 0x14, 0x08, 0x93, 0x0b, 0x9b, 0x86, 0x51, + 0x8f, 0xc0, 0x2c, 0x36, 0x22, 0x33, 0x7c, 0x69, 0x03, 0x8c, 0xb3, 0x0c, 0x66, 0x65, 0xc6, 0x2b, + 0x97, 0xaf, 0x55, 0x58, 0xa1, 0xa1, 0xed, 0xe3, 0xc7, 0xfe, 0x24, 0x27, 0x77, 0x72, 0xd2, 0xac, + 0x1a, 0xf1, 0x21, 0x4b, 0xb6, 0xf2, 0xf2, 0x5d, 0x05, 0xcb, 0x35, 0x17, 0x9b, 0x8a, 0x62, 0x99, + 0xe7, 0x97, 0xfb, 0xc4, 0x9a, 0xaa, 0xab, 0x89, 0x12, 0x10, 0x12, 0x2b, 0x71, 0x5b, 0xe7, 0x50, + 0x56, 0x14, 0x5e, 0x57, 0x89, 0x0a, 0x18, 0xc4, 0x12, 0xf5, 0x52, 0x7b, 0x83, 0x0a, 0x17, 0xc1, + 0x29, 0xb0, 0x5c, 0xbe, 0x32, 0xb5, 0xa2, 0x50, 0xc6, 0x26, 0xe1, 0x01, 0x21, 0x43, 0x7b, 0x31, + 0x94, 0x23, 0x96, 0x1e, 0xd2, 0xac, 0xa3, 0xee, 0x73, 0x0a, 0xdf, 0xf3, 0xb9, 0x35, 0x84, 0x70, + 0x84, 0x28, 0x56, 0xd5, 0x22, 0x60, 0x3c, 0x52, 0xd0, 0x0d, 0xe0, 0xbe, 0xb9, 0xc5, 0x44, 0x14, + 0xaa, 0x19, 0x78, 0x87, 0xd2, 0x3d, 0xc4, 0x09, 0x19, 0x05, 0x5d, 0x61, 0x21, 0x32, 0x39, 0xe5, + 0x7b, 0x2c, 0x57, 0xbc, 0x76, 0xa5, 0xc1, 0x2f, 0x6f, 0xbf, 0x89, 0x0a, 0x4e, 0x0e, 0x33, 0xb9, + 0xa7, 0x3d, 0xab, 0x75, 0x3c, 0x56, 0xed, 0x16, 0xc5, 0x62, 0xb1, 0x5a, 0x3b, 0xc2, 0x30, 0x52, + 0x74, 0xb5, 0x7d, 0x67, 0xcd, 0x1c, 0x78, 0x88, 0xcd, 0xa4, 0x1a, 0x96, 0x78, 0xae, 0x6b, 0x10, + 0x38, 0x58, 0xc5, 0x18, 0xa3, 0x14, 0x62, 0x8f, 0x12, 0x19, 0x0a, 0x53, 0xad, 0x63, 0xde, 0x18, + 0x23, 0xcd, 0x08, 0x01, 0xee, 0xc6, 0xc3, 0x98, 0x41, 0x7b, 0x18, 0xc7, 0xc8, 0x8f, 0x87, 0x4c, + 0x5e, 0x31, 0xbe, 0x1c, 0xc7, 0x1c, 0x35, 0x29, 0x20, 0x83, 0xcc, 0xa8, 0xd5, 0xef, 0x4d, 0xe8, + 0xda, 0x36, 0x93, 0x32, 0xbc, 0x6d, 0xf5, 0xd6, 0xf8, 0x4b, 0xe1, 0x21, 0xd1, 0x0e, 0x11, 0x10, + 0x24, 0xd7, 0x67, 0xb7, 0x5c, 0x4f, 0xe6, 0x29, 0x54, 0x7c, 0x44, 0x13, 0x62, 0xb8, 0xac, 0xca, + 0x2e, 0x86, 0xfe, 0x11, 0x0a, 0x65, 0xc8, 0x76, 0x69, 0x3c, 0x95, 0x06, 0x2c, 0xff, 0x36, 0x9b, + 0x1c, 0xf2, 0xe6, 0x86, 0x4e, 0x4a, 0x33, 0x21, 0xfd, 0xe4, 0x71, 0xe2, 0x03, 0x21, 0x4b, 0xbe, + 0x95, 0x55, 0x64, 0xaf, 0xa7, 0xf0, 0x48, 0x0e, 0x16, 0x35, 0x7e, 0x1e, 0x3c, 0x03, 0x38, 0xc6, + 0x52, 0xfc, 0x1d, 0x41, 0xf8, 0x9c, 0x1e, 0x47, 0x1f, 0x12, 0x14, 0x9c, 0x00, 0xd0, 0xf0, 0x1e, + 0x78, 0xc9, 0xf6, 0x4e, 0x02, 0xd0, 0x63, 0x01, 0xd2, 0x3d, 0xc5, 0x88, 0x6a, 0xc5, 0x40, 0x37, + 0xc3, 0xa2, 0xb2, 0x82, 0x33, 0x23, 0x40, 0x47, 0x53, 0x14, 0x8f, 0xc4, 0x7d, 0x6f, 0x65, 0x95, + 0x39, 0x0c, 0x10, 0x50, 0x2d, 0x58, 0x40, 0x20, 0x14, 0x1d, 0xb6, 0x92, 0x8f, 0x99, 0xf2, 0xc1, + 0x8a, 0xcf, 0x82, 0xad, 0x12, 0xd2, 0xdc, 0xb1, 0x8c, 0xf8, 0xc5, 0x06, 0x58, 0x37, 0xe1, 0x08, + 0x23, 0x92, 0x15, 0xc9, 0x07, 0xc3, 0xc7, 0x91, 0x42, 0x9d, 0x09, 0x6f, 0xac, 0x69, 0x3a, 0xc7, + 0xbe, 0x8b, 0xe3, 0xeb, 0x2e, 0x19, 0x8a, 0x9f, 0x0a, 0x41, 0x36, 0x33, 0xdd, 0x0c, 0xbf, 0x12, + 0x20, 0x28, 0x68, 0x83, 0xc7, 0x1a, 0xce, 0x6d, 0xfd, 0x27, 0xe3, 0x0b, 0xda, 0x8e, 0xe4, 0x29, + 0x1e, 0x11, 0x0a, 0x15, 0xdc, 0x51, 0x8a, 0xda, 0x15, 0x88, 0x73, 0xdb, 0x4a, 0xa9, 0x3d, 0x4f, + 0xc4, 0xc4, 0xdd, 0xdd, 0xde, 0xff, 0x08, 0x88, 0x55, 0x5e, 0xed, 0xad, 0x53, 0xe2, 0x42, 0x62, + 0x48, 0x32, 0xef, 0x9c, 0x83, 0x7e, 0x10, 0x19, 0x17, 0x95, 0x8b, 0x88, 0x0e, 0x2f, 0x71, 0x58, + 0xae, 0xb5, 0xc4, 0x08, 0x0a, 0x10, 0xb3, 0x17, 0x17, 0x17, 0xbe, 0x42, 0xf8, 0xa6, 0x2e, 0x2e, + 0x23, 0x04, 0x85, 0x5a, 0x25, 0x84, 0xf4, 0xcc, 0xef, 0x85, 0x36, 0x2b, 0x0b, 0x8d, 0xcb, 0x2c, + 0x5d, 0x05, 0xf8, 0x84, 0x98, 0x75, 0x17, 0x1f, 0x46, 0xc4, 0xbc, 0x62, 0x1e, 0x2b, 0x10, 0x3c, + 0x9f, 0x4f, 0x6f, 0x10, 0x10, 0x0a, 0x1c, 0xa2, 0x33, 0x8b, 0x78, 0xb8, 0x33, 0x45, 0x0c, 0xe7, + 0x04, 0x8e, 0x16, 0xec, 0xa3, 0x50, 0xbb, 0xa2, 0x10, 0xf9, 0x14, 0xb4, 0xc5, 0x28, 0xe3, 0x86, + 0x19, 0x40, 0x2e, 0x97, 0x80, 0x50, 0x39, 0x69, 0xe7, 0x89, 0x31, 0x04, 0xb9, 0x74, 0x42, 0xea, + 0x1a, 0xb9, 0x4a, 0xe5, 0x67, 0x57, 0xf3, 0xf0, 0xc9, 0xf9, 0x54, 0x58, 0xf1, 0x23, 0x8d, 0x08, + 0xa9, 0x38, 0x44, 0x22, 0x14, 0xe1, 0x5a, 0x09, 0x2c, 0x10, 0x12, 0x6a, 0x16, 0x98, 0xa6, 0x39, + 0x7d, 0x99, 0xd4, 0x56, 0x5b, 0x74, 0x3e, 0xe0, 0xe4, 0x30, 0x0a, 0xa3, 0x8a, 0x91, 0x6c, 0x83, + 0xe4, 0xb8, 0xf2, 0xe5, 0xb7, 0x2f, 0x3d, 0xc0, 0xcd, 0x5a, 0xad, 0x1c, 0x78, 0x60, 0x40, 0x50, + 0xc2, 0xb1, 0x58, 0xac, 0x57, 0x8e, 0x91, 0x6e, 0xed, 0xd6, 0x29, 0x8f, 0xfc, 0x48, 0x64, 0x29, + 0x14, 0x6e, 0x28, 0xc5, 0x6f, 0xf2, 0xbd, 0x04, 0x9f, 0x1f, 0x0c, 0xb0, 0x6c, 0x0f, 0xe2, 0xf6, + 0x23, 0xa2, 0xe8, 0xef, 0xc1, 0x59, 0x53, 0x70, 0xab, 0x88, 0xdd, 0x4f, 0xaa, 0xaa, 0xa3, 0x8d, + 0x62, 0x3c, 0x48, 0x2b, 0x22, 0xd6, 0xbb, 0x3b, 0x49, 0x3f, 0x71, 0x30, 0xa1, 0x59, 0x8c, 0xc7, + 0xb6, 0xd2, 0x2e, 0x28, 0xc5, 0x18, 0x97, 0x0b, 0x18, 0xa0, 0xc5, 0x18, 0xa3, 0x14, 0x6f, 0x86, + 0x51, 0x40, 0x1e, 0xa3, 0x3e, 0x30, 0x42, 0xda, 0x8b, 0x13, 0x75, 0xbb, 0xbb, 0xbb, 0x9b, 0xbb, + 0xbb, 0x8b, 0x62, 0xdb, 0xad, 0xb6, 0xcb, 0x7d, 0x8e, 0x1b, 0x0c, 0xe0, 0x0c, 0x4e, 0x2a, 0x27, + 0xfb, 0xce, 0x3d, 0xff, 0x7b, 0xf3, 0xfc, 0xa0, 0xae, 0x56, 0x76, 0xdb, 0x8d, 0x30, 0x6a, 0x96, + 0x4a, 0x65, 0x1c, 0x33, 0x89, 0x68, 0x07, 0x70, 0xc8, 0x29, 0x0a, 0x12, 0xc5, 0x7b, 0x8a, 0xc2, + 0x83, 0xe1, 0x46, 0x58, 0x34, 0x85, 0xa1, 0x8c, 0xc6, 0x38, 0xbc, 0x15, 0x8a, 0xf8, 0xf8, 0xe3, + 0xc4, 0x42, 0x83, 0x0b, 0x7b, 0xe5, 0xc8, 0x3b, 0xe0, 0x9e, 0x0b, 0x88, 0xf3, 0xb9, 0x5a, 0xd3, + 0xac, 0x44, 0x6d, 0xcf, 0xf6, 0xdc, 0x57, 0x89, 0xe2, 0xc5, 0x5d, 0x82, 0xc3, 0xd5, 0x63, 0x93, + 0x9c, 0x29, 0x56, 0xff, 0x09, 0x74, 0x25, 0xc9, 0xba, 0x2f, 0x7d, 0x62, 0xae, 0xf7, 0xbf, 0x92, + 0xf7, 0x7c, 0x48, 0x81, 0xa6, 0x11, 0xc9, 0xcd, 0x0d, 0xd9, 0x8d, 0xc7, 0xd4, 0xc3, 0xb3, 0x53, + 0xfb, 0x55, 0x3e, 0x93, 0x9e, 0x38, 0xf3, 0x9e, 0x07, 0x2c, 0x48, 0xb6, 0x0e, 0x7e, 0x88, 0x9b, + 0xdf, 0x84, 0x01, 0x08, 0x20, 0xac, 0xd4, 0xbd, 0x4b, 0xd7, 0x99, 0x81, 0x7a, 0xe0, 0xd7, 0xed, + 0x47, 0x7f, 0x89, 0xb2, 0x9e, 0xc9, 0xaf, 0xe2, 0x88, 0xaa, 0x2e, 0xb2, 0x52, 0xbe, 0x0a, 0x8d, + 0xaa, 0xaa, 0x7a, 0x83, 0xfe, 0xb1, 0xf7, 0x10, 0x18, 0x0a, 0x0b, 0x06, 0x39, 0x2a, 0x88, 0xc5, + 0xd9, 0xa3, 0x66, 0x28, 0xcc, 0xa0, 0xf7, 0x28, 0x23, 0x3c, 0x2f, 0x33, 0x05, 0xe6, 0x2e, 0x84, + 0x35, 0x55, 0x1b, 0x30, 0xfb, 0x12, 0xf8, 0xfb, 0xbd, 0xb8, 0xa6, 0x29, 0xa8, 0xba, 0x8b, 0x8b, + 0xae, 0x20, 0x48, 0x50, 0x82, 0x99, 0x61, 0x89, 0x38, 0x59, 0xcd, 0xb1, 0xb1, 0x96, 0x6a, 0x29, + 0x8b, 0xc5, 0x71, 0x5c, 0xee, 0x26, 0x23, 0x2f, 0x27, 0x7d, 0x2f, 0x6f, 0xe0, 0x93, 0x7b, 0x9a, + 0xf0, 0xc8, 0x50, 0x48, 0x3f, 0xf5, 0x82, 0x2a, 0xe2, 0xa3, 0xd6, 0xa7, 0x2c, 0x5f, 0x75, 0x1c, + 0x19, 0x88, 0x27, 0x20, 0xd3, 0xb7, 0x4a, 0x70, 0x88, 0x90, 0x5c, 0x62, 0xd8, 0xad, 0xc5, 0x6d, + 0xdb, 0xb9, 0xc2, 0x10, 0x5b, 0x5d, 0xd4, 0x5d, 0x55, 0x1d, 0xe0, 0xa0, 0x14, 0x82, 0xce, 0xd5, + 0x23, 0xf4, 0xcf, 0xe5, 0xdc, 0xdc, 0xbd, 0xf8, 0x64, 0x20, 0x10, 0xb8, 0xad, 0xa6, 0xa4, 0xca, + 0x4a, 0xaa, 0xb8, 0x91, 0x00, 0x88, 0xa4, 0x92, 0x41, 0x79, 0x78, 0xba, 0x74, 0xa2, 0x7e, 0x20, + 0x48, 0xaa, 0xd6, 0xab, 0xf0, 0x56, 0x25, 0x26, 0xf1, 0x46, 0x28, 0xc3, 0xe2, 0xe8, 0x05, 0x8c, + 0x51, 0x8a, 0x31, 0x46, 0x28, 0xc7, 0xc6, 0x21, 0x88, 0x85, 0x29, 0x9e, 0x05, 0xd6, 0xdd, 0x08, + 0xa6, 0x36, 0xaf, 0x43, 0x9e, 0xf8, 0x1c, 0x98, 0xa6, 0x14, 0xa2, 0x15, 0x99, 0x8a, 0x3b, 0x54, + 0x8a, 0x42, 0x0e, 0x34, 0xc7, 0x78, 0x98, 0xc3, 0x96, 0xdc, 0xf6, 0x17, 0x65, 0xb1, 0x58, 0x84, + 0x60, 0xad, 0xf1, 0xc2, 0x20, 0x27, 0xac, 0x59, 0x60, 0xcb, 0x06, 0x28, 0x31, 0x41, 0xe2, 0x61, + 0x42, 0x09, 0x06, 0x87, 0xa6, 0x25, 0xb2, 0x71, 0xd1, 0xb9, 0xf1, 0x2d, 0x21, 0x13, 0xab, 0xbe, + 0xe3, 0x98, 0xe3, 0xc4, 0xc1, 0x59, 0x6d, 0xf8, 0xe5, 0xb1, 0x58, 0xad, 0xc5, 0x62, 0xb1, 0x58, + 0xac, 0x4a, 0x41, 0x1c, 0x31, 0xc1, 0xe1, 0x90, 0x52, 0x43, 0x0a, 0x31, 0x00, 0xd0, 0xf9, 0x78, + 0x88, 0x54, 0x44, 0xd5, 0x52, 0x15, 0xb8, 0xac, 0x12, 0xa3, 0x39, 0x2d, 0x74, 0xff, 0xc2, 0xd7, + 0xbb, 0x93, 0x9e, 0xe0, 0xbb, 0xb0, 0x45, 0xe8, 0x1e, 0x9f, 0x63, 0xb7, 0x7f, 0x27, 0x42, 0x7e, + 0x17, 0x73, 0x2e, 0x75, 0xcc, 0xa5, 0xca, 0x7d, 0x7e, 0x9f, 0xa2, 0x54, 0x5f, 0x57, 0x54, 0x44, + 0x13, 0xd3, 0x3a, 0x9e, 0x99, 0xb9, 0x77, 0xdc, 0x4c, 0x6e, 0x24, 0x65, 0xc4, 0x4a, 0xb1, 0x25, + 0x63, 0xf1, 0x73, 0xc5, 0x43, 0x3a, 0xf4, 0x32, 0x50, 0xa1, 0x03, 0xab, 0x9d, 0xe4, 0xd9, 0x0b, + 0xc1, 0x20, 0x0a, 0x44, 0xe0, 0x4a, 0xa0, 0x32, 0x84, 0xea, 0x57, 0xfc, 0x14, 0xde, 0x69, 0x5f, + 0x79, 0x6c, 0x6d, 0xb1, 0xed, 0xfe, 0x6b, 0xbb, 0xbf, 0x96, 0xee, 0xef, 0x89, 0x8a, 0x22, 0xa6, + 0xb5, 0x7b, 0xe2, 0x43, 0x23, 0x8a, 0xff, 0xbb, 0x9f, 0xfb, 0x4f, 0x7f, 0x10, 0x09, 0xca, 0xee, + 0xe2, 0xb2, 0x7d, 0x6f, 0xe2, 0x42, 0x91, 0x58, 0xad, 0xdc, 0x48, 0xe6, 0xbb, 0xd2, 0x25, 0xc7, + 0xf8, 0xaf, 0x97, 0x1d, 0x1d, 0xe2, 0x21, 0x48, 0x2e, 0xe6, 0x27, 0x3d, 0xd8, 0x70, 0x3d, 0x06, + 0xf1, 0x8a, 0x34, 0xf4, 0xe2, 0xb3, 0x68, 0x59, 0x55, 0x48, 0x4e, 0xe2, 0x44, 0x02, 0xc8, 0xb6, + 0x98, 0xb7, 0x10, 0xe4, 0xb0, 0x64, 0x23, 0x10, 0x03, 0xc5, 0x63, 0xc0, 0xfe, 0xbe, 0x14, 0x89, + 0x10, 0xc0, 0x94, 0x25, 0x80, 0x62, 0x6a, 0x3f, 0xc3, 0x9a, 0x3e, 0x4e, 0xe7, 0x59, 0x3c, 0x07, + 0xab, 0xa8, 0xaa, 0x7c, 0x7e, 0x88, 0xcc, 0x08, 0x15, 0xca, 0x0d, 0xc7, 0xa4, 0x7e, 0xfc, 0x40, + 0x80, 0xa6, 0x6e, 0xdc, 0x35, 0x08, 0x1a, 0xc3, 0x28, 0xde, 0x59, 0xaa, 0xcb, 0x67, 0x03, 0xc4, + 0xb8, 0x58, 0x32, 0x80, 0xee, 0x1c, 0x65, 0x00, 0x5f, 0xac, 0x03, 0xbd, 0x45, 0xd1, 0xbd, 0x2b, + 0x7f, 0xc4, 0xac, 0x8d, 0x32, 0x73, 0xf4, 0x12, 0xa6, 0x4e, 0xbe, 0x47, 0x98, 0x9c, 0x99, 0x81, + 0x13, 0x63, 0x0f, 0x98, 0xa1, 0xd0, 0x2a, 0xd5, 0x03, 0x4d, 0x7b, 0xff, 0x08, 0x82, 0x80, 0xa1, + 0x2d, 0xcb, 0x62, 0xb7, 0xe1, 0xc2, 0xc6, 0xcc, 0xb6, 0x2b, 0x5c, 0xca, 0x5c, 0x49, 0xe6, 0xe7, + 0x81, 0xe8, 0xe3, 0xf0, 0x55, 0x79, 0xd8, 0xaa, 0xaa, 0x8b, 0xeb, 0xdf, 0x04, 0x85, 0x51, 0x36, + 0x16, 0x7b, 0x89, 0x82, 0xce, 0x8c, 0xc4, 0x11, 0x1e, 0x0f, 0x7d, 0x9e, 0x38, 0x2a, 0x9c, 0xd4, + 0x39, 0x71, 0x10, 0x48, 0x4c, 0x44, 0x82, 0xaf, 0xe2, 0x01, 0x71, 0x96, 0xab, 0x77, 0x77, 0xe2, + 0x61, 0x43, 0xb8, 0xc9, 0x6d, 0x33, 0xb0, 0xe2, 0xb7, 0xc1, 0xb0, 0x13, 0x4a, 0x7b, 0xca, 0xdd, + 0x09, 0x41, 0xe5, 0xfe, 0xb6, 0xe3, 0x7a, 0x5c, 0x33, 0x28, 0x01, 0xe1, 0x25, 0xa4, 0x89, 0x30, + 0xa9, 0xa3, 0xf7, 0x2a, 0x5c, 0x46, 0x4e, 0xb0, 0x73, 0xf0, 0xc9, 0xd3, 0x49, 0x46, 0xe4, 0xaf, + 0xfd, 0x2d, 0x14, 0x89, 0x8a, 0xd1, 0x94, 0x49, 0x85, 0x16, 0xca, 0xdc, 0xd2, 0xd7, 0xf4, 0x83, + 0x52, 0xe5, 0x84, 0xb4, 0xe2, 0x89, 0x84, 0x12, 0x61, 0xa6, 0x8f, 0x05, 0x44, 0x2d, 0xbd, 0xb8, + 0xa3, 0x14, 0x62, 0xb1, 0x59, 0xa7, 0x49, 0x95, 0xc7, 0x10, 0x0a, 0x69, 0x15, 0x1f, 0xc9, 0x95, + 0x27, 0x56, 0x2a, 0xb1, 0x6a, 0xf7, 0x43, 0x1c, 0xdf, 0x05, 0x85, 0x45, 0x6e, 0xfb, 0x4e, 0xe1, + 0x3b, 0x54, 0xb6, 0x39, 0xfc, 0x4f, 0x86, 0x41, 0x48, 0x8d, 0x1b, 0xde, 0xbe, 0x24, 0x15, 0x0a, + 0x9f, 0x17, 0x1d, 0x33, 0x6b, 0x4b, 0x71, 0x09, 0x1c, 0x2d, 0xc4, 0xb0, 0x7f, 0x82, 0xda, 0x57, + 0x70, 0x77, 0x82, 0x01, 0x8f, 0x28, 0x0e, 0xf0, 0x0e, 0xf3, 0x93, 0xa3, 0xc5, 0x5d, 0x58, 0xfa, + 0xb0, 0x5d, 0x19, 0xe2, 0x7a, 0xf4, 0xbc, 0xc7, 0xbb, 0xdf, 0x0b, 0x91, 0x5d, 0x5e, 0x16, 0x79, + 0xb1, 0xa4, 0x08, 0x1f, 0x80, 0xfb, 0xee, 0x94, 0x06, 0x26, 0x40, 0x8d, 0xbf, 0x88, 0x1b, 0x72, + 0x83, 0x96, 0x0f, 0xa8, 0xaa, 0x23, 0x32, 0xd5, 0x42, 0xcc, 0x36, 0x43, 0x14, 0x61, 0xd8, 0x1e, + 0x1e, 0xa1, 0x65, 0x5e, 0x04, 0x13, 0xc0, 0xaf, 0x44, 0xd1, 0x45, 0x14, 0xdb, 0x5f, 0xfe, 0x3b, + 0x7b, 0x95, 0x4a, 0xfb, 0x7b, 0x7f, 0x65, 0x17, 0x53, 0x42, 0x7c, 0x29, 0xa9, 0xfd, 0x71, 0x77, + 0x17, 0x77, 0x77, 0xdd, 0x9f, 0xfe, 0x08, 0x88, 0x82, 0x22, 0x8b, 0xa3, 0xbe, 0x20, 0x84, 0x7b, + 0xbf, 0x8f, 0x12, 0x0c, 0xf7, 0x56, 0x60, 0x5d, 0x99, 0x38, 0x4c, 0xa2, 0x72, 0x80, 0x6f, 0x77, + 0xc3, 0x02, 0x42, 0x91, 0x84, 0x1c, 0x6d, 0x8b, 0xdd, 0x98, 0x50, 0x46, 0x85, 0x1a, 0x25, 0x4c, + 0x50, 0x63, 0xd4, 0x12, 0x03, 0xeb, 0x47, 0x7c, 0x48, 0x27, 0x96, 0xf8, 0xad, 0x3a, 0xe2, 0x38, + 0xf1, 0x22, 0x41, 0x54, 0xbd, 0x7a, 0x06, 0xf3, 0xdf, 0xba, 0xaa, 0xee, 0x8e, 0xf1, 0x31, 0x9b, + 0x8e, 0xae, 0xc9, 0x93, 0x9a, 0xa8, 0xf5, 0x8c, 0x51, 0x96, 0x31, 0x41, 0x8a, 0x3f, 0x0a, 0x5e, + 0xfa, 0x3c, 0x40, 0x2a, 0x05, 0x65, 0x8c, 0xb6, 0x7e, 0x2b, 0xbe, 0x68, 0xd1, 0xc7, 0x89, 0x08, + 0x84, 0x25, 0xb7, 0x15, 0xbb, 0xb4, 0x80, 0x4c, 0x25, 0x55, 0x5e, 0x11, 0xe2, 0x44, 0x84, 0xee, + 0x56, 0x1e, 0xdb, 0xaf, 0x13, 0x11, 0x51, 0x75, 0x17, 0x19, 0xea, 0x99, 0x39, 0xc4, 0x7c, 0x40, + 0x93, 0x2a, 0xaa, 0xad, 0x57, 0x89, 0x18, 0x5d, 0xde, 0xe8, 0x99, 0x6e, 0x2b, 0x69, 0xa0, 0xa3, + 0xe6, 0xe6, 0x26, 0x14, 0x2d, 0x1b, 0xd9, 0x2e, 0x22, 0x56, 0x3f, 0xbf, 0x1f, 0xc7, 0xfc, 0xb6, + 0xfc, 0x7e, 0x13, 0x20, 0x81, 0x16, 0x32, 0xd9, 0xc0, 0xa8, 0x2d, 0x92, 0x38, 0xf1, 0x22, 0x02, + 0x95, 0x79, 0x1e, 0xf3, 0xde, 0x73, 0xed, 0x0c, 0x66, 0x7e, 0x38, 0x60, 0x4c, 0x0e, 0x1a, 0x30, + 0x6f, 0x1a, 0x10, 0x27, 0x1a, 0x61, 0xa6, 0x91, 0x52, 0x01, 0xee, 0xf8, 0xca, 0xa4, 0x02, 0xbe, + 0xa0, 0xe9, 0x89, 0x76, 0x7a, 0x10, 0x04, 0x4a, 0x41, 0x2c, 0x70, 0xe5, 0x92, 0x12, 0x4b, 0x11, + 0x50, 0x34, 0x92, 0xe2, 0x42, 0x93, 0xd1, 0x01, 0x2d, 0xb5, 0x45, 0x8c, 0x92, 0x2e, 0xcb, 0x0b, + 0x77, 0x15, 0xb9, 0x6c, 0x43, 0x85, 0xb7, 0x7c, 0x23, 0xb6, 0x9e, 0xe2, 0xb4, 0x71, 0x75, 0x5c, + 0x48, 0x95, 0x7f, 0x8b, 0xa8, 0xb8, 0xba, 0xaa, 0x8b, 0xae, 0x24, 0x48, 0xeb, 0xdd, 0xd3, 0x64, + 0x37, 0x3d, 0x1e, 0xf8, 0x90, 0xf0, 0xc2, 0x71, 0xc2, 0xad, 0x32, 0xdb, 0xe1, 0x85, 0x6c, 0xac, + 0x5c, 0x02, 0x16, 0x34, 0x69, 0x46, 0x2b, 0xce, 0x2f, 0xf8, 0x28, 0x12, 0x94, 0x55, 0x33, 0x3d, + 0x12, 0xfa, 0x93, 0xa2, 0x3f, 0xd1, 0x5f, 0xea, 0xf7, 0xd6, 0x2f, 0xab, 0xd7, 0x57, 0x93, 0x9e, + 0xaa, 0xea, 0xfe, 0xfa, 0xbc, 0xbc, 0x12, 0x5d, 0xdd, 0xd1, 0xc7, 0x84, 0x44, 0x8d, 0x20, 0x56, + 0xe1, 0x15, 0x12, 0x8c, 0x3c, 0xb2, 0x58, 0x2c, 0xa1, 0x25, 0x7a, 0x30, 0x59, 0x55, 0xd8, 0xc3, + 0x88, 0xc4, 0xe4, 0x7b, 0xcb, 0xcf, 0xf3, 0xfd, 0xd4, 0x12, 0x0c, 0x31, 0x45, 0x24, 0x81, 0x4f, + 0x3b, 0x7b, 0xfc, 0x3e, 0x75, 0x94, 0xe6, 0x5e, 0x99, 0x7a, 0x6e, 0x6e, 0xf2, 0x26, 0x90, 0xf2, + 0xb0, 0xff, 0xe6, 0xbb, 0x8a, 0xc5, 0x7e, 0x08, 0x6e, 0xee, 0xe5, 0xbe, 0x0b, 0xa1, 0xda, 0xb4, + 0xa8, 0xaf, 0x6c, 0x5c, 0xde, 0x51, 0xc7, 0xe0, 0x8b, 0x31, 0xab, 0xeb, 0xe2, 0xc4, 0x35, 0xad, + 0x55, 0x71, 0x30, 0x52, 0x25, 0xce, 0x30, 0x45, 0x77, 0x6e, 0xe2, 0xb4, 0xe9, 0xb6, 0x32, 0x0e, + 0x11, 0x08, 0x09, 0x29, 0xe9, 0x04, 0x56, 0x73, 0x42, 0xdb, 0x8a, 0xc5, 0x62, 0xbc, 0x40, 0x90, + 0x53, 0xc4, 0xbd, 0xc5, 0x65, 0xe2, 0x5a, 0x58, 0xad, 0xdc, 0x57, 0xdc, 0x44, 0x7c, 0xce, 0x6d, + 0xcc, 0x62, 0x16, 0x0f, 0x58, 0x1b, 0xa1, 0x2a, 0x98, 0xb2, 0xdb, 0x85, 0x16, 0xcc, 0x48, 0x60, + 0x10, 0x90, 0xb6, 0x2b, 0x2c, 0x62, 0x8d, 0xdc, 0x48, 0x90, 0x49, 0x55, 0x55, 0x8b, 0x89, 0x12, + 0x26, 0xe5, 0xa0, 0xae, 0xde, 0xfe, 0x24, 0x11, 0xdb, 0xb6, 0x6e, 0xea, 0xe6, 0xb4, 0xd5, 0xac, + 0x40, 0x80, 0x91, 0x9d, 0xdd, 0xdd, 0xdf, 0xe3, 0x04, 0x89, 0xb0, 0x49, 0x65, 0x33, 0x44, 0x28, + 0xe2, 0x05, 0x81, 0x58, 0xac, 0xe4, 0x12, 0xd8, 0xac, 0xb6, 0x2b, 0x38, 0x80, 0xe2, 0x44, 0x02, + 0xb9, 0x69, 0x93, 0x39, 0x16, 0x32, 0xc6, 0x2b, 0x2c, 0x61, 0x51, 0x18, 0x36, 0x05, 0x62, 0xb1, + 0xf1, 0xc1, 0xe0, 0x80, 0x30, 0x14, 0x82, 0xe7, 0x22, 0x88, 0xe6, 0x64, 0x1c, 0x66, 0xa7, 0x8b, + 0x02, 0x8b, 0xe4, 0x92, 0x8e, 0x26, 0x00, 0x18, 0x89, 0x66, 0xdb, 0xa9, 0x52, 0x65, 0xfc, 0x7c, + 0xe4, 0x65, 0x26, 0x3a, 0x78, 0x78, 0xe2, 0x0a, 0x8d, 0x07, 0x31, 0xc7, 0x84, 0x42, 0x21, 0x49, + 0xe2, 0x91, 0x59, 0x95, 0x37, 0xf1, 0xea, 0x4d, 0x07, 0x89, 0x8a, 0xed, 0x0d, 0x07, 0x04, 0xa8, + 0x4a, 0x39, 0x2b, 0xb6, 0x02, 0xb0, 0xe7, 0xe2, 0x8e, 0x5c, 0x82, 0xb4, 0x02, 0x1b, 0x22, 0x38, + 0xf1, 0x31, 0xd8, 0x77, 0xcd, 0x90, 0xac, 0x56, 0xe2, 0xbb, 0x6d, 0x9f, 0xc4, 0xc2, 0x57, 0x72, + 0x98, 0x96, 0xc5, 0x6e, 0xe7, 0x31, 0xf0, 0x85, 0xc5, 0x6e, 0xed, 0x3d, 0x75, 0x5c, 0x48, 0x92, + 0x4c, 0xc0, 0xba, 0x8b, 0xe2, 0x25, 0x28, 0xb8, 0xb8, 0xb8, 0xbf, 0x13, 0xc4, 0x84, 0x47, 0x99, + 0x44, 0x9e, 0x2f, 0x2a, 0x0f, 0x7c, 0x5e, 0x31, 0x71, 0x4d, 0x45, 0xfc, 0x68, 0xa2, 0xfa, 0x48, + 0x35, 0xd6, 0x4c, 0xf7, 0x19, 0x48, 0x11, 0x18, 0x22, 0x06, 0x6c, 0x30, 0xf2, 0x95, 0x0c, 0x79, + 0xfd, 0x78, 0x8e, 0x51, 0x75, 0x63, 0x93, 0xab, 0x7d, 0x75, 0x15, 0xcc, 0x6b, 0xbb, 0xe1, 0x10, + 0x88, 0xd8, 0xab, 0x4c, 0x1d, 0xf9, 0xce, 0x03, 0x5d, 0x4e, 0x05, 0x82, 0xaa, 0xa3, 0x7b, 0xfb, + 0x79, 0xe2, 0xc5, 0x6b, 0xae, 0x12, 0x0d, 0x07, 0xae, 0xfc, 0x23, 0x65, 0xf1, 0x2f, 0xfe, 0x24, + 0x26, 0x4a, 0xa6, 0x6b, 0x5f, 0x82, 0x63, 0xcd, 0xb2, 0x74, 0x0e, 0x4e, 0xcf, 0x3f, 0x12, 0x20, + 0x28, 0x5b, 0xcf, 0x88, 0xde, 0xe1, 0x56, 0x85, 0xb7, 0xe3, 0xc8, 0x29, 0x13, 0x7b, 0x9f, 0x5e, + 0xf8, 0x2b, 0xdc, 0xcc, 0xe9, 0x25, 0xd6, 0xa8, 0xef, 0x89, 0xf1, 0x24, 0xa8, 0xd3, 0x25, 0x9e, + 0x24, 0x82, 0x1e, 0xfe, 0x20, 0x70, 0xb1, 0x2e, 0x6a, 0x2b, 0x15, 0xb8, 0xac, 0x56, 0xca, 0xa2, + 0xf8, 0x90, 0x80, 0x89, 0xd8, 0x2d, 0xdb, 0xb9, 0xc2, 0x00, 0xc5, 0x7e, 0x48, 0x94, 0x30, 0x1b, + 0x15, 0x8a, 0xf8, 0x91, 0x77, 0x15, 0x96, 0x85, 0xb2, 0xb0, 0x6f, 0x5c, 0xf1, 0x3f, 0x35, 0x45, + 0xc5, 0xd5, 0x62, 0x09, 0x2d, 0x1f, 0xe2, 0x19, 0x95, 0x55, 0x78, 0x81, 0x67, 0x39, 0x0a, 0x74, + 0xc5, 0x65, 0x31, 0x72, 0xdf, 0x85, 0x28, 0x12, 0x22, 0x93, 0xa4, 0x15, 0x6e, 0x0f, 0x7c, 0xe5, + 0x85, 0xa3, 0x04, 0xf5, 0x21, 0x6d, 0xf0, 0x39, 0x81, 0x63, 0x2c, 0x65, 0x8c, 0x51, 0xd7, 0x08, + 0x42, 0x91, 0x25, 0xe1, 0xee, 0xcb, 0xa2, 0xb4, 0xf3, 0x02, 0xd9, 0x3b, 0x85, 0xaa, 0xfe, 0xbe, + 0x84, 0x8a, 0xbd, 0x22, 0x57, 0x2a, 0xd6, 0x8d, 0x14, 0x8d, 0x63, 0xfe, 0x39, 0x8e, 0x0f, 0x12, + 0x10, 0x0a, 0x4a, 0xf3, 0x2f, 0x2d, 0x8a, 0xc9, 0xd5, 0x0e, 0x9b, 0xb3, 0x9e, 0x70, 0xe0, 0x87, + 0x1b, 0x43, 0xc1, 0xe5, 0xb2, 0xc6, 0x15, 0x15, 0x46, 0x82, 0xb1, 0x31, 0x93, 0xd9, 0x6c, 0x56, + 0x2b, 0x7b, 0x15, 0x8a, 0xc5, 0x6f, 0x6e, 0x25, 0xa5, 0x96, 0xcf, 0xfc, 0x27, 0x68, 0x20, 0xb5, + 0x09, 0xd0, 0x9b, 0x22, 0x9a, 0xf1, 0x22, 0x45, 0x5c, 0x56, 0xe2, 0xb3, 0xb1, 0x17, 0xe6, 0xaa, + 0xaa, 0xf9, 0xaa, 0xaa, 0xbc, 0x40, 0xb2, 0x8b, 0xa8, 0xb8, 0xb8, 0xb8, 0xba, 0xaf, 0x13, 0xe1, + 0x01, 0xf7, 0xdd, 0x45, 0xc9, 0xaa, 0x7c, 0x7b, 0x1d, 0xf0, 0xd8, 0xec, 0xf0, 0xa0, 0xe9, 0x33, + 0x4a, 0x49, 0x95, 0x23, 0x08, 0xbc, 0x28, 0xdf, 0xc1, 0xa8, 0xa9, 0xf0, 0x09, 0x7c, 0x2d, 0x3d, + 0xe7, 0x89, 0x60, 0x36, 0x4a, 0xaa, 0x4d, 0x9b, 0x0f, 0x90, 0xb3, 0xa3, 0xf6, 0x87, 0xf9, 0x7a, + 0x3e, 0x12, 0xf5, 0x65, 0x75, 0x74, 0xdd, 0x5d, 0x5d, 0x5c, 0xa8, 0x91, 0x23, 0x48, 0x66, 0x1c, + 0xec, 0xdd, 0xd0, 0x9d, 0x44, 0xe0, 0x27, 0xca, 0xec, 0x18, 0x13, 0x34, 0xbd, 0x6c, 0x80, 0x0a, + 0xc3, 0xa9, 0x88, 0x47, 0xa3, 0x1c, 0x39, 0x20, 0xea, 0x27, 0x4f, 0xf0, 0x52, 0x42, 0x66, 0x85, + 0x46, 0xc3, 0x99, 0x1d, 0xfc, 0xf3, 0x2b, 0x8c, 0x7c, 0x54, 0xfe, 0x24, 0x56, 0x7c, 0xd5, 0x7c, + 0x44, 0x22, 0x72, 0x41, 0x16, 0xdb, 0x65, 0x67, 0x51, 0x75, 0x5c, 0x48, 0x90, 0x59, 0xaa, 0xd5, + 0x63, 0x46, 0x16, 0xc8, 0x7d, 0xc4, 0xc6, 0x1c, 0x47, 0xa3, 0x33, 0x19, 0x58, 0x77, 0xa9, 0x08, + 0x22, 0xf3, 0x6e, 0xef, 0x88, 0x12, 0x0a, 0x22, 0xbb, 0xe6, 0xec, 0x1c, 0x9d, 0x0e, 0x3f, 0x0a, + 0x5b, 0x33, 0x0b, 0x02, 0x15, 0xa9, 0x54, 0xcc, 0x1b, 0xf4, 0x11, 0x17, 0xf2, 0xf8, 0x26, 0x23, + 0xbb, 0xbd, 0xbb, 0xbf, 0x1d, 0xf9, 0x27, 0x4a, 0x6e, 0xff, 0x82, 0x82, 0x2a, 0xaa, 0xaa, 0xaa, + 0xf7, 0xc6, 0x6a, 0xb5, 0xac, 0x5c, 0x5d, 0x45, 0xd5, 0x55, 0x78, 0x90, 0x50, 0x57, 0x77, 0x77, + 0x66, 0xef, 0xd5, 0xcb, 0xbb, 0xbf, 0x9a, 0xaa, 0xab, 0xc4, 0x02, 0x98, 0xb8, 0xba, 0xaa, 0xaa, + 0xc9, 0x90, 0x3e, 0xe7, 0xd5, 0xc7, 0x84, 0x74, 0x93, 0x77, 0x6d, 0xbc, 0x64, 0xc7, 0xe2, 0x42, + 0x25, 0xdd, 0xf6, 0xd3, 0x3a, 0x97, 0x3f, 0x6c, 0x6f, 0xc2, 0x39, 0x48, 0x26, 0x22, 0xfe, 0xee, + 0x32, 0x70, 0xb3, 0xc7, 0x07, 0x1f, 0xad, 0x53, 0x81, 0xcf, 0x0a, 0x6d, 0xed, 0xec, 0xa6, 0x2e, + 0x5b, 0x2d, 0x8a, 0xcb, 0x62, 0xb7, 0x37, 0xa1, 0x25, 0xfb, 0x2b, 0xd4, 0xb3, 0xd6, 0xe6, 0x71, + 0x30, 0x55, 0x19, 0x77, 0x72, 0x9e, 0x7b, 0x05, 0xad, 0x81, 0x91, 0x8f, 0x1f, 0x41, 0x00, 0x4f, + 0x79, 0x6c, 0x56, 0x2b, 0x47, 0x07, 0x88, 0xb2, 0x58, 0xae, 0xdf, 0xc2, 0x91, 0xb0, 0x80, 0xa2, + 0xcd, 0x7b, 0x45, 0x1a, 0x8a, 0xe7, 0x31, 0xcf, 0xd9, 0x12, 0xe2, 0x61, 0x13, 0xb6, 0x24, 0xf3, + 0x72, 0xcd, 0x2d, 0x21, 0x71, 0x71, 0x12, 0x09, 0x7f, 0x94, 0x84, 0x80, 0xee, 0x38, 0x58, 0x91, + 0x3c, 0x48, 0x90, 0x44, 0x45, 0x51, 0x75, 0xef, 0x0c, 0x82, 0xa3, 0xbd, 0xba, 0x97, 0x8b, 0x8b, + 0xa8, 0xba, 0x8b, 0x8e, 0x0d, 0xe2, 0x42, 0x95, 0x5e, 0x21, 0xa1, 0xd4, 0x2d, 0xc2, 0x1d, 0x45, + 0xf9, 0x88, 0x23, 0xcc, 0x9f, 0xe3, 0x47, 0x60, 0xc6, 0xa7, 0x06, 0xb3, 0x12, 0x48, 0x4d, 0x90, + 0xe5, 0xfb, 0x40, 0xec, 0x6b, 0x20, 0xc7, 0x4b, 0x6d, 0x78, 0x3a, 0x90, 0x12, 0xc0, 0xbe, 0x91, + 0x91, 0x82, 0xbb, 0xa8, 0x8f, 0xcf, 0xfc, 0x10, 0x89, 0x79, 0xaf, 0xd2, 0x72, 0x57, 0x52, 0x75, + 0x63, 0xea, 0xd2, 0x77, 0x5d, 0xcf, 0xc2, 0xfa, 0x4e, 0xf1, 0x5b, 0x0d, 0xd9, 0xf3, 0x30, 0x66, + 0x17, 0xc4, 0xc6, 0x0c, 0x2c, 0xc7, 0xfd, 0x23, 0x9e, 0x4a, 0x00, 0xd1, 0xf7, 0x0c, 0x41, 0x03, + 0x48, 0xfd, 0xb1, 0xcd, 0xc7, 0x72, 0x89, 0xf7, 0x4e, 0xf9, 0xfd, 0x1e, 0x5f, 0x5e, 0xf8, 0x81, + 0x21, 0x9b, 0xc8, 0xf8, 0xb8, 0xba, 0x8e, 0x5c, 0xc2, 0x01, 0x81, 0x83, 0x05, 0xc2, 0x7d, 0x16, + 0xe9, 0xf1, 0xd7, 0x1b, 0x77, 0x6b, 0x44, 0x22, 0xc3, 0x76, 0xaa, 0x9a, 0xb6, 0x2f, 0x41, 0xfe, + 0x8c, 0x80, 0x96, 0x10, 0x21, 0xd8, 0xe4, 0x14, 0x3d, 0x89, 0x0c, 0x05, 0x06, 0x88, 0xeb, 0xd8, + 0x45, 0x27, 0xa2, 0x9e, 0x85, 0x80, 0xc5, 0x6b, 0xea, 0xb5, 0xac, 0x9a, 0xa0, 0x23, 0xcc, 0x89, + 0x88, 0xaf, 0x8f, 0xa9, 0x3a, 0x22, 0xfb, 0x24, 0x14, 0x04, 0x2e, 0x10, 0x8e, 0xab, 0x9b, 0xde, + 0xea, 0x73, 0x02, 0xd9, 0x6d, 0xf8, 0x91, 0x37, 0xd1, 0xcb, 0x8d, 0x16, 0xf8, 0x90, 0x47, 0x22, + 0x96, 0x2b, 0x69, 0x1f, 0x96, 0xee, 0x2b, 0x15, 0xfa, 0x9e, 0xf8, 0x25, 0x9a, 0x12, 0xf1, 0x73, + 0x41, 0x65, 0xdc, 0x4c, 0x46, 0x47, 0xa2, 0x31, 0xbf, 0xb5, 0x87, 0xff, 0xcd, 0xa1, 0xbf, 0x84, + 0x01, 0x4c, 0x2f, 0x68, 0x2f, 0x2f, 0x51, 0x75, 0x17, 0x17, 0xa5, 0x7c, 0xbc, 0x41, 0x08, 0xee, + 0xef, 0x88, 0xfc, 0x16, 0x95, 0x15, 0xc7, 0xc9, 0x4f, 0x15, 0xcc, 0x8a, 0xf1, 0x11, 0x94, 0xea, + 0x53, 0xf0, 0xdb, 0x5a, 0xaf, 0x43, 0xa0, 0x63, 0xb2, 0x1d, 0x87, 0xe4, 0xe8, 0x69, 0xf8, 0xe9, + 0x92, 0xde, 0x37, 0x88, 0x46, 0x43, 0x95, 0x0b, 0x96, 0xed, 0xe2, 0x22, 0xee, 0xe2, 0xb7, 0x54, + 0xe9, 0xae, 0xa8, 0xef, 0xcd, 0x55, 0xae, 0x24, 0x48, 0x9b, 0xb8, 0xac, 0x56, 0x17, 0x15, 0x97, + 0x64, 0xf9, 0x6a, 0x2e, 0xab, 0xe3, 0x8a, 0x2e, 0x2e, 0x2e, 0x14, 0xf8, 0xbc, 0x5c, 0xbc, 0x44, + 0xc4, 0x44, 0x60, 0x97, 0x8a, 0x62, 0x4e, 0x62, 0x20, 0x94, 0xca, 0x2f, 0x2a, 0xa9, 0xc5, 0xfa, + 0xb1, 0x25, 0x23, 0x8a, 0xdf, 0x89, 0xf1, 0x21, 0x90, 0x8d, 0x65, 0x56, 0xf4, 0x7a, 0x8b, 0xe1, + 0x90, 0x52, 0x32, 0xaa, 0xaa, 0x7f, 0x93, 0x38, 0xe3, 0x17, 0x17, 0x55, 0xab, 0x6b, 0xc4, 0x02, + 0xb8, 0xe4, 0x5c, 0x5c, 0xa4, 0x4a, 0xcc, 0x29, 0x16, 0x2a, 0x2f, 0x1e, 0x24, 0x72, 0xa3, 0x8d, + 0x11, 0xd1, 0x7a, 0xfa, 0xea, 0x23, 0xaf, 0x71, 0x22, 0x42, 0x82, 0x02, 0x8d, 0x07, 0x6f, 0x8b, + 0xf4, 0x40, 0xcb, 0x56, 0xc9, 0xdb, 0xea, 0x1c, 0x27, 0xe0, 0xcc, 0xa0, 0xff, 0x0f, 0x80, 0xae, + 0xf1, 0x20, 0xba, 0x8c, 0x03, 0x94, 0xa2, 0xea, 0xe2, 0x58, 0x72, 0xb5, 0xd5, 0xf2, 0x89, 0x77, + 0x77, 0xc2, 0x22, 0x02, 0x82, 0x97, 0x73, 0x26, 0xea, 0x79, 0x80, 0x99, 0xd4, 0xdc, 0x69, 0x5b, + 0x13, 0x74, 0xf5, 0xe7, 0xa5, 0x3d, 0xf1, 0x5b, 0x40, 0x7c, 0xd5, 0xf8, 0x88, 0xc1, 0x66, 0xe0, + 0xa2, 0x33, 0x38, 0x76, 0xe5, 0x04, 0x71, 0xfd, 0xd9, 0xac, 0x2f, 0xcf, 0x07, 0xc5, 0x23, 0xd2, + 0x1e, 0x3e, 0x00, 0x5e, 0x37, 0x14, 0x78, 0x64, 0x20, 0x2a, 0xd0, 0xae, 0x21, 0xe2, 0xb2, 0x40, + 0x14, 0x02, 0xb3, 0x81, 0xf8, 0x81, 0x21, 0x1b, 0x1b, 0xde, 0xc5, 0x65, 0xb7, 0xcf, 0x82, 0xbc, + 0x44, 0x5d, 0xc5, 0x6e, 0xee, 0xee, 0xfc, 0x48, 0x50, 0xa2, 0x1c, 0xbb, 0xdc, 0xb9, 0x46, 0x2b, + 0x73, 0xf2, 0xc6, 0x7b, 0x46, 0xf3, 0xd8, 0x16, 0xcc, 0xf7, 0x89, 0x05, 0x75, 0x17, 0xdb, 0x55, + 0x5c, 0x42, 0xc3, 0x9c, 0x1f, 0x04, 0x86, 0x27, 0xf9, 0xd5, 0xd7, 0xb8, 0x81, 0x28, 0xbd, 0xf0, + 0x43, 0x4d, 0xb4, 0xdb, 0xef, 0xab, 0xfc, 0xd1, 0x5b, 0x88, 0x7d, 0xe2, 0x44, 0x88, 0xb1, 0xd1, + 0xb1, 0x94, 0x32, 0x48, 0xb7, 0xfc, 0x47, 0xe2, 0xca, 0xe8, 0xae, 0x9d, 0x36, 0xf8, 0x8e, 0x24, + 0x4f, 0x13, 0x25, 0x54, 0x5d, 0x7c, 0x41, 0x24, 0x5d, 0x55, 0x54, 0x5c, 0x5d, 0x44, 0x4d, 0x17, + 0x55, 0x5e, 0x23, 0xe2, 0xcd, 0x7b, 0xad, 0x57, 0x89, 0x25, 0x57, 0xf6, 0x72, 0x90, 0x5d, 0xc5, + 0x78, 0x91, 0x20, 0x96, 0xe8, 0xcc, 0x20, 0x32, 0x93, 0x74, 0x6f, 0x5c, 0x16, 0x08, 0x9b, 0xee, + 0xee, 0x2b, 0x78, 0x85, 0x86, 0xf2, 0xae, 0x8b, 0x95, 0xf5, 0xaf, 0xac, 0x51, 0xbc, 0x12, 0x77, + 0x77, 0xe2, 0x44, 0x0d, 0x10, 0x66, 0xce, 0xc0, 0xa2, 0xd3, 0x1d, 0x35, 0xa9, 0xe0, 0x0f, 0xa6, + 0xa7, 0x49, 0xa0, 0x1d, 0x74, 0xb0, 0x14, 0x52, 0xca, 0x40, 0x7a, 0x4c, 0x26, 0x63, 0xdf, 0x1a, + 0x96, 0x31, 0xa1, 0x55, 0xc1, 0x7f, 0x88, 0x3d, 0xcf, 0x4f, 0x37, 0xf2, 0xcc, 0x41, 0xaf, 0xcd, + 0x77, 0x77, 0xe2, 0x02, 0x5b, 0xce, 0x30, 0x5c, 0xf0, 0x7f, 0x10, 0x24, 0x28, 0x69, 0x71, 0xec, + 0x90, 0x58, 0x96, 0x03, 0x2c, 0x19, 0xfa, 0xa6, 0xa9, 0x89, 0x7e, 0xff, 0x2c, 0xe1, 0x89, 0x08, + 0x05, 0x05, 0xaf, 0x5d, 0xd5, 0x2e, 0x62, 0x1c, 0x39, 0x04, 0x51, 0x96, 0x31, 0x46, 0x28, 0xcb, + 0x19, 0x6c, 0x51, 0x8a, 0xcf, 0x3f, 0x84, 0x06, 0x45, 0x06, 0x75, 0x07, 0xbe, 0xed, 0x69, 0x82, + 0x99, 0x6b, 0x33, 0x6e, 0x64, 0xb6, 0x21, 0x63, 0xc4, 0x82, 0x00, 0xa1, 0x42, 0xcf, 0x82, 0x48, + 0x9e, 0xc3, 0x46, 0xec, 0xc6, 0x34, 0xb0, 0x15, 0xec, 0x33, 0xb8, 0xce, 0x1e, 0x1c, 0x2c, 0x67, + 0x00, 0xc0, 0x93, 0xe1, 0x59, 0x40, 0x2e, 0x91, 0x28, 0xa0, 0x08, 0x28, 0xff, 0xbf, 0x0e, 0xf3, + 0xfe, 0x3a, 0xdf, 0x53, 0xbc, 0xef, 0x6d, 0x6d, 0x65, 0xff, 0x88, 0x8f, 0xb3, 0xbd, 0x44, 0xc6, + 0x5b, 0x15, 0x8a, 0xc5, 0x6e, 0xd8, 0xec, 0x95, 0xf1, 0x00, 0xa8, 0x82, 0xb1, 0x58, 0x87, 0x2e, + 0xc5, 0x6e, 0x2b, 0x15, 0x8a, 0xc5, 0x62, 0xb4, 0x71, 0xc3, 0xb3, 0x80, 0x11, 0xc0, 0xdb, 0x6a, + 0xca, 0x1c, 0xff, 0xff, 0xd0, 0x17, 0x1c, 0x41, 0x93, 0xb8, 0x64, 0x15, 0x65, 0x7e, 0xaa, 0xaa, + 0x80, 0xff, 0x6d, 0xb6, 0xdb, 0xf0, 0x58, 0x62, 0x06, 0x1a, 0xdd, 0xc5, 0x62, 0xb1, 0x5b, 0x8a, + 0xc5, 0x67, 0x6f, 0x82, 0xb8, 0xac, 0x56, 0xee, 0x2b, 0x15, 0x89, 0x7d, 0x8a, 0xc5, 0x62, 0xb7, + 0x47, 0x1f, 0x8b, 0xb8, 0xac, 0x56, 0x25, 0x60, 0x56, 0x51, 0x01, 0xb2, 0xdf, 0x12, 0x2c, 0x8d, + 0x52, 0x49, 0x0d, 0x0d, 0x0c, 0x58, 0xf8, 0x90, 0x54, 0x5e, 0x5e, 0x2a, 0x36, 0x3a, 0x31, 0x51, + 0xb3, 0x96, 0x9e, 0x50, 0xe1, 0x00, 0x59, 0x77, 0x15, 0xb8, 0xac, 0x56, 0x2b, 0x15, 0xbb, 0x8a, + 0xc5, 0x7d, 0xe2, 0x46, 0x14, 0x42, 0x41, 0x29, 0x05, 0xf4, 0x39, 0x20, 0xb8, 0xa3, 0x2c, 0x62, + 0xb2, 0xdd, 0xbb, 0x9f, 0xdc, 0x10, 0x68, 0x40, 0xc3, 0x0e, 0xb2, 0x86, 0x90, 0x7f, 0xbc, 0xbc, + 0x53, 0x14, 0x66, 0xff, 0x11, 0x83, 0xa0, 0x23, 0x07, 0x41, 0x11, 0x7f, 0x2c, 0x25, 0x87, 0x89, + 0x09, 0x08, 0x3b, 0x30, 0x6e, 0x37, 0x41, 0x58, 0xac, 0xb6, 0xfe, 0x09, 0x68, 0x69, 0xc1, 0x99, + 0x91, 0x75, 0x91, 0x76, 0x71, 0x22, 0x02, 0x98, 0x9b, 0x04, 0x61, 0xaf, 0x34, 0x14, 0xbd, 0x45, + 0xdc, 0xc0, 0x5e, 0x70, 0x3e, 0x91, 0xdc, 0xef, 0x59, 0x8c, 0x71, 0xbc, 0x40, 0x42, 0xaa, 0xab, + 0xaa, 0x62, 0xbc, 0xb9, 0xe2, 0x0c, 0x62, 0xf2, 0xe3, 0xde, 0x20, 0x47, 0xcd, 0x55, 0x5f, 0x10, + 0x11, 0xa0, 0x6d, 0x55, 0x55, 0x55, 0xb6, 0xdb, 0x37, 0xc4, 0x09, 0x08, 0x12, 0x87, 0x7b, 0xdd, + 0xc5, 0x77, 0xc4, 0x84, 0x06, 0x55, 0x56, 0x9d, 0x6b, 0x55, 0xaa, 0xf1, 0x02, 0x42, 0x03, 0x53, + 0xb0, 0x0a, 0x4e, 0x55, 0x25, 0x8b, 0xba, 0x8b, 0xc8, 0x8d, 0x17, 0x18, 0x6a, 0x9b, 0x1b, 0x6b, + 0x8e, 0x6e, 0x59, 0xac, 0x62, 0x9d, 0x3e, 0x26, 0x2b, 0x4e, 0x41, 0x02, 0xa7, 0x58, 0x52, 0xfe, + 0x20, 0x14, 0x99, 0xa4, 0xd9, 0x0c, 0xbd, 0xf1, 0x18, 0xcc, 0x77, 0x46, 0xde, 0x5b, 0x67, 0x00, + 0xe5, 0x69, 0xcd, 0x39, 0x57, 0x30, 0xdb, 0xbb, 0xfa, 0x34, 0xaf, 0x82, 0x3e, 0xef, 0x58, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x17, 0x0b, 0xb0, 0x26, 0x8d, 0xd0, 0x97, 0x42, 0x98, 0x45, 0x17, + 0x2f, 0x08, 0x02, 0x32, 0x8b, 0x8b, 0x8b, 0x8b, 0xa3, 0x86, 0x23, 0xaa, 0x38, 0x30, 0x5b, 0x02, + 0x48, 0x60, 0x16, 0x8a, 0x53, 0x3e, 0x1d, 0xe8, 0x55, 0x55, 0x7e, 0x04, 0x11, 0x21, 0x41, 0x8c, + 0xc8, 0xa3, 0x15, 0xe2, 0xac, 0x45, 0x94, 0x42, 0x1e, 0x0e, 0xff, 0x3d, 0x83, 0x20, 0x3b, 0x79, + 0xf1, 0x4b, 0xf2, 0x84, 0xcf, 0xc9, 0x20, 0x7a, 0x0c, 0xfc, 0x7b, 0xc3, 0x3d, 0x47, 0x1a, 0x1a, + 0xeb, 0xde, 0x20, 0x10, 0xc9, 0x8c, 0xc7, 0xc7, 0x7f, 0x82, 0x00, 0xa0, 0x48, 0x78, 0xe0, 0xfb, + 0x2d, 0x94, 0x1b, 0x03, 0xaf, 0x0f, 0x62, 0x4f, 0x4c, 0x62, 0x07, 0x8e, 0x37, 0x85, 0x86, 0x87, + 0x85, 0x81, 0xc5, 0x1d, 0x6c, 0x9c, 0x1f, 0x98, 0xe0, 0x41, 0x12, 0x09, 0xa1, 0xdf, 0xe8, 0x19, + 0x6e, 0x5b, 0x15, 0x9c, 0xf7, 0xb1, 0xd0, 0xb7, 0x41, 0x5e, 0xfa, 0x95, 0x3e, 0xb5, 0x5d, 0x13, + 0x2a, 0xea, 0xff, 0x57, 0x97, 0xa9, 0x92, 0x11, 0x89, 0xa3, 0x8c, 0x63, 0x5f, 0x12, 0xb8, 0x8f, + 0x04, 0x03, 0x02, 0x81, 0xa5, 0x02, 0xdf, 0xe6, 0xc5, 0x0a, 0x59, 0xb2, 0x47, 0x15, 0x11, 0x7a, + 0x47, 0x2c, 0x12, 0x51, 0x02, 0xcd, 0x52, 0x3c, 0x7c, 0x40, 0x52, 0x77, 0xa1, 0x31, 0x8a, 0x29, + 0xca, 0x8a, 0xb5, 0xc9, 0x95, 0xf0, 0x84, 0x00, 0x14, 0xc1, 0x4b, 0x50, 0xb0, 0x0c, 0x6a, 0x4e, + 0x4b, 0x0a, 0x1d, 0x1b, 0xe0, 0xa4, 0x3f, 0x0f, 0x71, 0x02, 0x50, 0x4f, 0xbe, 0xa5, 0x47, 0x44, + 0xe8, 0x43, 0x8f, 0x04, 0x9c, 0x43, 0x80, 0x7c, 0x35, 0x1d, 0x25, 0x58, 0x31, 0x06, 0x21, 0x83, + 0xd5, 0x94, 0x49, 0xf0, 0xba, 0xb8, 0x60, 0xbe, 0x41, 0x34, 0x63, 0xf8, 0x7f, 0x3a, 0x57, 0x97, + 0xe0, 0x49, 0x06, 0x20, 0x80, 0xca, 0xd2, 0x9a, 0x98, 0x5e, 0xf8, 0x93, 0x5a, 0x16, 0x49, 0x6c, + 0x81, 0xf7, 0x40, 0xf4, 0x8b, 0xf8, 0xb6, 0x9e, 0x0a, 0x41, 0xc8, 0x28, 0x32, 0xa8, 0xe4, 0xf1, + 0x10, 0x24, 0x83, 0x33, 0x73, 0xc4, 0x30, 0x10, 0xa8, 0x71, 0x69, 0x0b, 0x43, 0x70, 0x20, 0x83, + 0x10, 0x46, 0x27, 0x4d, 0x81, 0x15, 0xa3, 0x98, 0x24, 0xe8, 0xb0, 0xd3, 0x62, 0x02, 0xe3, 0x2c, + 0xfd, 0x12, 0xba, 0x09, 0xf1, 0xc0, 0xde, 0x6e, 0x50, 0x03, 0xf0, 0x07, 0xcc, 0x09, 0x55, 0x64, + 0x85, 0xe2, 0x8f, 0x84, 0x02, 0x84, 0xae, 0x2b, 0x74, 0x23, 0x52, 0x2a, 0x91, 0x85, 0xe9, 0x91, + 0xbe, 0x4c, 0x5b, 0x77, 0x25, 0x07, 0x55, 0xb2, 0x30, 0x40, 0x65, 0x19, 0xd2, 0xaf, 0xb8, 0x10, + 0x44, 0x89, 0x1e, 0xa0, 0x9f, 0xe6, 0x48, 0x88, 0xab, 0xd3, 0x16, 0x04, 0xe8, 0x41, 0x93, 0x8f, + 0x2b, 0xbe, 0xef, 0x8a, 0xc5, 0x62, 0xb1, 0x5c, 0x3a, 0xa0, 0x0f, 0x53, 0x6c, 0x02, 0xa3, 0x6d, + 0xbd, 0xb6, 0xff, 0xd1, 0x22, 0x5e, 0x9a, 0x69, 0xa7, 0x0e, 0x21, 0x00, 0x02, 0x27, 0x5b, 0xc5, + 0x8a, 0xe0, 0x9f, 0xeb, 0xff, 0xe3, 0x86, 0x81, 0xd7, 0xca, 0x8f, 0xc5, 0x77, 0x04, 0x09, 0x10, + 0x50, 0x89, 0xb4, 0x9c, 0x78, 0xd2, 0x2e, 0x01, 0x4c, 0x4d, 0xb6, 0xd8, 0x30, 0x15, 0xec, 0x33, + 0x1a, 0x33, 0x86, 0x93, 0x30, 0x38, 0xf8, 0x51, 0x62, 0x1b, 0x0b, 0x0e, 0x54, 0x08, 0xd8, 0x15, + 0x43, 0x56, 0x45, 0x5e, 0x17, 0x13, 0x8e, 0xaa, 0xe7, 0x99, 0x60, 0x51, 0x5f, 0x07, 0x9f, 0x63, + 0x17, 0x5a, 0x9d, 0xaf, 0xfa, 0x4d, 0xcf, 0x12, 0x20, 0x12, 0xf9, 0x2f, 0xd2, 0x2c, 0xcb, 0xd2, + 0xf7, 0xc2, 0x9d, 0xac, 0x3d, 0x8a, 0x12, 0x4c, 0xd7, 0x91, 0x2a, 0xb5, 0x6c, 0x46, 0xb7, 0x83, + 0xc3, 0xee, 0x80, 0x65, 0x0d, 0x5f, 0xc2, 0xe3, 0xc8, 0x7f, 0xdf, 0x05, 0x22, 0x54, 0xaa, 0xf5, + 0x07, 0xcf, 0xa7, 0xd8, 0xc4, 0xbc, 0x5c, 0xbc, 0x5f, 0x99, 0xaf, 0x7d, 0x0d, 0x19, 0x48, 0x8e, + 0xbc, 0xa8, 0xdd, 0x7a, 0x14, 0xea, 0x5a, 0xba, 0xb0, 0x27, 0x5c, 0x38, 0x88, 0x5c, 0x62, 0xb7, + 0xcc, 0x30, 0xcc, 0xbc, 0x4d, 0x49, 0x6f, 0xde, 0x58, 0x78, 0x50, 0xc0, 0xa9, 0x83, 0x16, 0xd0, + 0xfd, 0x22, 0xc8, 0x01, 0xc1, 0x05, 0xe9, 0x2c, 0xee, 0xf2, 0xd6, 0x45, 0x20, 0x34, 0xc5, 0x5c, + 0x69, 0xc9, 0x52, 0x01, 0xe0, 0xdf, 0x00, 0xdf, 0xb6, 0x87, 0x23, 0x2b, 0xa2, 0x57, 0x88, 0x13, + 0x3b, 0x8c, 0xfa, 0xa6, 0x3d, 0x44, 0x59, 0x77, 0xfd, 0x44, 0x88, 0xf9, 0x84, 0xdd, 0xdf, 0x02, + 0x88, 0x39, 0x1a, 0x72, 0x71, 0x1c, 0x17, 0x03, 0x8b, 0x0a, 0xa2, 0xdc, 0x32, 0x05, 0xe3, 0x38, + 0x1d, 0x5b, 0x8b, 0xf3, 0xa3, 0xcc, 0x4f, 0x9e, 0x65, 0xe4, 0xc7, 0xc3, 0xc7, 0x8b, 0x93, 0x4e, + 0x42, 0xa5, 0x23, 0xd0, 0x5b, 0x60, 0x35, 0xa0, 0x2d, 0xd1, 0xf2, 0x1b, 0x8f, 0xc2, 0x78, 0x49, + 0xf0, 0x41, 0x18, 0x10, 0xac, 0x47, 0xcd, 0x11, 0x5a, 0x9d, 0xc1, 0x94, 0x94, 0x06, 0xce, 0x68, + 0xa3, 0x42, 0xf8, 0xd0, 0xa9, 0x9f, 0xe7, 0x1c, 0x7e, 0x62, 0xe8, 0x61, 0x18, 0x52, 0x14, 0x74, + 0x51, 0xa0, 0xea, 0xc6, 0x62, 0xe5, 0x2c, 0xd9, 0x23, 0x8e, 0x6c, 0xef, 0x15, 0xbf, 0xb8, 0x60, + 0x48, 0x92, 0x92, 0x1c, 0xbf, 0x72, 0xd3, 0xf1, 0x30, 0x89, 0xa4, 0xa2, 0x9e, 0x1c, 0xe2, 0x4f, + 0x14, 0xd9, 0xa5, 0xff, 0x82, 0xa2, 0x82, 0x25, 0x3b, 0x9a, 0x5b, 0x8d, 0xd1, 0x0b, 0x0d, 0x5f, + 0x6f, 0xea, 0xba, 0xaf, 0xb8, 0x10, 0x01, 0x82, 0x09, 0xf4, 0x47, 0x44, 0xaf, 0xac, 0x53, 0x75, + 0xa9, 0xfa, 0xc5, 0x7d, 0x61, 0x0f, 0x56, 0xbe, 0x20, 0xe7, 0xa1, 0xe9, 0x9e, 0x87, 0xa7, 0xe0, + 0x93, 0x9e, 0x87, 0xa4, 0x5f, 0x09, 0xf3, 0xd0, 0xf4, 0xcf, 0x43, 0xd3, 0xc7, 0x4f, 0x43, 0xd3, + 0x3d, 0x0f, 0x4c, 0xf4, 0x3d, 0x39, 0x3a, 0x22, 0x55, 0xe0, 0x8e, 0x7a, 0x1e, 0x9a, 0x54, 0xba, + 0xc5, 0xf5, 0x8b, 0xea, 0xde, 0x19, 0x04, 0xe2, 0x8c, 0xc2, 0xc4, 0xcd, 0x22, 0x99, 0xb5, 0x2b, + 0x1d, 0xc4, 0x86, 0x42, 0x82, 0x05, 0xd0, 0x35, 0x18, 0x01, 0x7a, 0x32, 0x86, 0x80, 0xa2, 0xe8, + 0xcf, 0x17, 0x4e, 0x0c, 0x02, 0x93, 0xa0, 0xe7, 0xd4, 0x59, 0xc2, 0xec, 0x56, 0x59, 0x62, 0x80, + 0xf9, 0x3c, 0x22, 0x10, 0x8b, 0x79, 0x4f, 0xe5, 0xde, 0x98, 0xba, 0x66, 0x61, 0x65, 0xeb, 0xc4, + 0xfc, 0xc1, 0x5a, 0x1c, 0x24, 0x63, 0xcc, 0x09, 0x33, 0x1a, 0xc0, 0x4c, 0x08, 0xd2, 0xc3, 0x02, + 0x02, 0x81, 0x08, 0x0f, 0x5e, 0xb0, 0x65, 0x4d, 0xec, 0x71, 0x59, 0x07, 0xb9, 0x12, 0xc5, 0x81, + 0x2a, 0xc3, 0x7a, 0x2a, 0x65, 0x95, 0x4e, 0x18, 0x10, 0x2c, 0x15, 0x45, 0x41, 0x8a, 0x1d, 0x40, + 0x05, 0x43, 0xef, 0x6c, 0xb1, 0xf8, 0x98, 0xc2, 0xf2, 0xca, 0x4b, 0x50, 0xde, 0xb9, 0x6d, 0x0f, + 0x72, 0xc8, 0x31, 0x22, 0xd4, 0x68, 0x29, 0xc3, 0xbb, 0xfd, 0x57, 0x11, 0x05, 0x63, 0x6c, 0x86, + 0x9a, 0x1f, 0x58, 0xeb, 0xad, 0x55, 0x37, 0xe2, 0x44, 0x98, 0x76, 0xab, 0xc4, 0x8e, 0xee, 0xd2, + 0xaa, 0xd4, 0x4e, 0x02, 0xf3, 0x81, 0x00, 0x18, 0x20, 0xaf, 0xe1, 0x9e, 0x8d, 0x84, 0xbd, 0x13, + 0xa6, 0xe8, 0xe9, 0xc3, 0xd5, 0x2a, 0xf5, 0x4a, 0xbd, 0x7b, 0xeb, 0xdf, 0x5f, 0xfd, 0x7f, 0xe1, + 0x00, 0x4e, 0x48, 0x99, 0x9a, 0x74, 0xe3, 0x45, 0x8f, 0x78, 0x44, 0x28, 0x38, 0x7a, 0xe4, 0x61, + 0xd0, 0xb0, 0xb3, 0x80, 0x05, 0x89, 0xcc, 0x1c, 0x37, 0x94, 0x41, 0xd0, 0x70, 0xfe, 0x50, 0x12, + 0xd2, 0x31, 0x5b, 0x79, 0x63, 0x11, 0x71, 0x2b, 0xc2, 0x00, 0xae, 0x46, 0x07, 0xae, 0x2e, 0x3c, + 0xb8, 0x9f, 0x26, 0xa8, 0xe9, 0x72, 0xb0, 0x94, 0xbe, 0x71, 0xf7, 0x71, 0x1e, 0x05, 0x90, 0x87, + 0x12, 0x20, 0x51, 0xe7, 0xfa, 0x89, 0xa8, 0x6c, 0xef, 0xc2, 0x01, 0x11, 0xc6, 0xcb, 0xc5, 0xd3, + 0x9d, 0xcb, 0xd3, 0x97, 0xc4, 0x09, 0x04, 0x23, 0xc9, 0xe5, 0xdd, 0x90, 0xef, 0xa3, 0x3f, 0xc5, + 0x08, 0x8a, 0x6a, 0xab, 0x5e, 0x0e, 0x01, 0x40, 0x50, 0x2a, 0x2b, 0x3e, 0x7b, 0xbe, 0xe2, 0xbd, + 0x55, 0x05, 0xb0, 0xb7, 0x57, 0x24, 0xe8, 0x8e, 0x09, 0xd1, 0xcb, 0x49, 0xd1, 0x1c, 0x8a, 0xc4, + 0x02, 0x22, 0x66, 0xbc, 0x63, 0xc4, 0x42, 0x83, 0x98, 0xa4, 0xa2, 0x7c, 0xa5, 0x47, 0x5f, 0xcd, + 0xed, 0x93, 0x2a, 0x38, 0xff, 0x06, 0xb2, 0xa6, 0x2b, 0x8c, 0x51, 0x9f, 0x38, 0x81, 0x03, 0xa5, + 0x75, 0x0e, 0x01, 0xf1, 0xda, 0xfa, 0x7e, 0xd9, 0x49, 0x5f, 0xa0, 0xab, 0xf1, 0x10, 0x4e, 0x6d, + 0x48, 0xc0, 0x9f, 0x04, 0x4b, 0x5d, 0x00, 0x07, 0x75, 0xf3, 0x10, 0xb8, 0xa0, 0x6b, 0x8c, 0x8b, + 0xe0, 0x3d, 0x71, 0x30, 0x90, 0x42, 0x5f, 0x15, 0xdf, 0xb7, 0xe2, 0x42, 0x82, 0xd6, 0x55, 0xad, + 0x32, 0xeb, 0x53, 0xde, 0xe7, 0xcb, 0xa2, 0xab, 0xfc, 0xc6, 0x81, 0xf3, 0x50, 0x64, 0xd5, 0x18, + 0x0f, 0x78, 0x4b, 0x77, 0x10, 0xf9, 0x4f, 0x6b, 0xc1, 0x58, 0xd0, 0x11, 0xff, 0x1f, 0xdb, 0xb3, + 0xd5, 0xb3, 0x12, 0xaa, 0xa2, 0xea, 0xaa, 0xad, 0xe1, 0x04, 0x24, 0xe9, 0x1f, 0xd4, 0x70, 0x69, + 0xfa, 0xb9, 0x7d, 0x5a, 0xfa, 0xb8, 0x27, 0x21, 0x1f, 0x73, 0x74, 0x52, 0xa4, 0x9c, 0x11, 0x08, + 0x77, 0x7a, 0x3f, 0x81, 0x04, 0x22, 0x09, 0xea, 0xaa, 0xa6, 0xc9, 0x27, 0xc7, 0x63, 0xf8, 0x40, + 0x10, 0x82, 0x11, 0x15, 0xab, 0xf8, 0x21, 0x18, 0x44, 0xeb, 0x56, 0xd2, 0xb9, 0x78, 0x3d, 0xe3, + 0x70, 0x50, 0x65, 0x83, 0xc4, 0x0b, 0x02, 0x83, 0x1e, 0x70, 0xe0, 0xc4, 0x21, 0x2f, 0x2c, 0x1e, + 0x28, 0xdc, 0x43, 0xf4, 0xc3, 0xd5, 0x99, 0xa9, 0x93, 0xfc, 0x40, 0x39, 0x0a, 0x1d, 0x55, 0x55, + 0x54, 0x5c, 0x5d, 0x54, 0x56, 0x2b, 0x51, 0x1a, 0x12, 0xe1, 0xfb, 0x82, 0x00, 0x72, 0x14, 0x32, + 0xaa, 0xaf, 0xf8, 0xf3, 0x4d, 0xca, 0x4d, 0xa6, 0x73, 0xec, 0xb6, 0x2b, 0xef, 0x85, 0x2d, 0x2a, + 0xac, 0x9f, 0x77, 0x14, 0x6f, 0xbb, 0xb3, 0xe2, 0xb5, 0x85, 0xea, 0x27, 0x87, 0x86, 0x01, 0xe0, + 0x0f, 0x99, 0xbe, 0x0b, 0x76, 0x80, 0x01, 0xf0, 0x55, 0xc6, 0x7c, 0xed, 0x09, 0xe1, 0x7f, 0x70, + 0x2c, 0x03, 0x80, 0xa0, 0x4c, 0xa4, 0xf2, 0x5d, 0x42, 0xd5, 0x36, 0xf9, 0x33, 0x77, 0x5a, 0xc9, + 0xf8, 0x8c, 0x9d, 0x08, 0xab, 0xe8, 0xee, 0x84, 0xba, 0xb9, 0xf1, 0x05, 0x3d, 0x0f, 0x4c, 0xf4, + 0x3d, 0x32, 0xf0, 0x9e, 0x76, 0x3c, 0xf4, 0x3d, 0x09, 0xd4, 0xe9, 0x7d, 0x4e, 0x92, 0xc0, 0x83, + 0x0c, 0x11, 0xc3, 0x3d, 0xe6, 0x8a, 0x4d, 0xb6, 0xba, 0x6b, 0x52, 0xc3, 0xfc, 0x30, 0x24, 0x12, + 0x8c, 0xdd, 0xf1, 0x5b, 0xf7, 0xc1, 0x4e, 0xef, 0x6c, 0xd8, 0x6f, 0x10, 0xac, 0x56, 0xee, 0xcf, + 0x12, 0x32, 0x6b, 0x1d, 0x41, 0xc0, 0xa8, 0x24, 0x1a, 0x89, 0x85, 0xd0, 0x48, 0x0f, 0x81, 0x28, + 0xe3, 0xe9, 0x3b, 0x2f, 0x98, 0x92, 0x78, 0xf3, 0xde, 0x28, 0x0e, 0xb5, 0xde, 0x8e, 0x7e, 0x0a, + 0xb9, 0xe0, 0xd4, 0xb6, 0xe4, 0x1a, 0x8b, 0x6e, 0xd7, 0xc1, 0xf7, 0xf2, 0xac, 0x21, 0x0a, 0x58, + 0xc1, 0x56, 0x08, 0x8a, 0x32, 0x5e, 0x07, 0x97, 0x84, 0xb1, 0xb5, 0x7d, 0xd1, 0x5b, 0x7a, 0x64, + 0x83, 0x4b, 0x5b, 0x70, 0x77, 0xfd, 0xf8, 0x88, 0x52, 0x21, 0xe4, 0xe2, 0xa7, 0xbc, 0xf7, 0x2e, + 0x5b, 0x6a, 0xcb, 0x6e, 0xee, 0xf7, 0xae, 0x22, 0x11, 0x33, 0xbb, 0xbd, 0xef, 0x15, 0xbb, 0xf1, + 0x00, 0xb2, 0x5b, 0x2d, 0x4a, 0xa2, 0x7c, 0x48, 0x60, 0x4c, 0x01, 0xc1, 0xd8, 0x4a, 0xca, 0xb7, + 0x08, 0x03, 0x01, 0xc1, 0x52, 0xd8, 0xac, 0x48, 0xe3, 0xe9, 0x9e, 0x87, 0xa6, 0x2b, 0x10, 0xe1, + 0x6f, 0xd4, 0x89, 0xf5, 0x8a, 0xf8, 0x27, 0xce, 0xc4, 0xec, 0x67, 0x63, 0x17, 0xd7, 0x09, 0x38, + 0x89, 0xe8, 0x7a, 0x67, 0xa1, 0xe9, 0xbe, 0xbd, 0xf5, 0x78, 0x5b, 0xac, 0x52, 0xf5, 0x3a, 0x5f, + 0x44, 0xc3, 0xc4, 0x18, 0x52, 0xa6, 0xd8, 0xb7, 0xe1, 0x4e, 0x7f, 0x55, 0x17, 0x13, 0xc2, 0xdb, + 0x8a, 0xc4, 0xbe, 0x16, 0xe4, 0xb0, 0x6d, 0xc4, 0x41, 0x41, 0x79, 0xb6, 0x99, 0xa0, 0x2b, 0x97, + 0x38, 0x88, 0x52, 0x24, 0x44, 0x06, 0xb1, 0x2d, 0x2a, 0x8a, 0x31, 0x58, 0x59, 0xf5, 0xbe, 0xf1, + 0x8a, 0xef, 0xf1, 0x33, 0xff, 0x77, 0xbe, 0x26, 0x09, 0x4a, 0xf6, 0xef, 0x8a, 0xdc, 0xf9, 0x17, + 0x11, 0x1c, 0x4c, 0xb4, 0x73, 0x74, 0xcd, 0x0d, 0xda, 0xda, 0xaa, 0xf1, 0x21, 0x41, 0x85, 0xe0, + 0xe2, 0x17, 0x53, 0xfc, 0x52, 0x94, 0x3e, 0xc1, 0xd6, 0x68, 0xe2, 0xf5, 0x0f, 0xba, 0x4a, 0xa3, + 0x22, 0xfe, 0xf8, 0x7c, 0x33, 0x0e, 0xca, 0x47, 0x8c, 0xb4, 0x5d, 0x1c, 0x5c, 0x49, 0xe3, 0x83, + 0x13, 0xb3, 0x68, 0x9e, 0xb7, 0x5f, 0xe0, 0x83, 0xf4, 0x4a, 0x88, 0xe8, 0xfa, 0x93, 0xa2, 0x54, + 0x6f, 0x56, 0x8a, 0xe8, 0x8e, 0x57, 0x5c, 0xaf, 0xab, 0xde, 0x21, 0x1c, 0xa9, 0xc4, 0x06, 0x45, + 0x84, 0x97, 0x5a, 0x69, 0xfc, 0x14, 0x5d, 0xc5, 0x67, 0x21, 0x1e, 0x52, 0x5b, 0x24, 0xa0, 0x48, + 0x15, 0x76, 0x62, 0x61, 0x7c, 0x66, 0xb4, 0xef, 0x78, 0x0d, 0xc3, 0xb5, 0x12, 0x52, 0x7e, 0x5c, + 0xae, 0x22, 0x5a, 0xa6, 0x9b, 0xe2, 0x22, 0x8b, 0x55, 0x17, 0x55, 0x5f, 0x92, 0xcd, 0x63, 0x86, + 0x5e, 0x12, 0xae, 0x6f, 0x7b, 0x78, 0x88, 0xa1, 0x0b, 0x4c, 0x3f, 0xdb, 0xfc, 0xaa, 0x3f, 0x05, + 0x21, 0x15, 0xe8, 0x34, 0x8b, 0xd5, 0x6b, 0x2a, 0xa9, 0x5d, 0xcc, 0x8b, 0xab, 0x2e, 0x47, 0x6f, + 0x12, 0x8b, 0xd1, 0x5d, 0x5c, 0x9f, 0xad, 0x57, 0x58, 0xdf, 0x56, 0x23, 0x7a, 0x23, 0x11, 0x1d, + 0x16, 0xaf, 0xae, 0xb8, 0x88, 0x27, 0x09, 0x0a, 0x62, 0x98, 0xa6, 0x29, 0x8b, 0xb6, 0x38, 0x67, + 0xf7, 0x11, 0x0a, 0x11, 0x56, 0x1b, 0x45, 0xe7, 0x31, 0xb7, 0x80, 0x64, 0x07, 0x6c, 0xe3, 0x4a, + 0x29, 0x99, 0x56, 0x7a, 0x82, 0x88, 0xc1, 0x79, 0x72, 0x4c, 0x32, 0x07, 0xc5, 0x97, 0x38, 0x81, + 0x03, 0x3b, 0x08, 0x23, 0xad, 0x98, 0x51, 0x2f, 0x58, 0x54, 0x05, 0x68, 0x1d, 0x04, 0xf4, 0x0d, + 0x70, 0xe9, 0xcc, 0xb0, 0x4e, 0x43, 0x60, 0xe9, 0x52, 0x61, 0x52, 0x33, 0x19, 0x90, 0x30, 0x4e, + 0x8e, 0xfc, 0x20, 0x30, 0xbb, 0x52, 0xaa, 0xb1, 0xb5, 0xb9, 0xcf, 0x2c, 0x41, 0xff, 0x3c, 0x07, + 0xe2, 0x41, 0x86, 0x22, 0x30, 0x9c, 0x82, 0x32, 0x9b, 0x6b, 0x42, 0x34, 0xad, 0x1f, 0x58, 0x1d, + 0xa1, 0x69, 0x45, 0x6e, 0xc3, 0xa9, 0x98, 0xef, 0x57, 0xc1, 0xbb, 0x05, 0xaa, 0x6f, 0xd6, 0xab, + 0x15, 0x7c, 0xe6, 0x33, 0xdb, 0x59, 0xe6, 0x79, 0x0d, 0xc1, 0x53, 0xf3, 0x10, 0x20, 0x13, 0x1c, + 0xa4, 0x28, 0xca, 0x80, 0xfc, 0x8c, 0x9e, 0x9c, 0x5e, 0xde, 0xcc, 0x0e, 0xa0, 0x7e, 0x6f, 0x7b, + 0x1c, 0x40, 0x80, 0x46, 0x51, 0x59, 0x6a, 0x20, 0x58, 0x57, 0x87, 0xf1, 0x21, 0x19, 0xbd, 0x0c, + 0xb8, 0xef, 0xdb, 0x6d, 0x0b, 0x89, 0x12, 0x66, 0x7d, 0xd4, 0x9f, 0xea, 0xee, 0x5e, 0x5e, 0x82, + 0x64, 0x4b, 0xea, 0xe0, 0x27, 0xd5, 0x3a, 0x5d, 0x11, 0x1f, 0x27, 0x56, 0x8b, 0xe0, 0x86, 0xaa, + 0xaa, 0xdc, 0x32, 0x24, 0x11, 0x92, 0x98, 0x4d, 0x34, 0x8b, 0x7d, 0xe2, 0x07, 0xd3, 0x1d, 0xc1, + 0x95, 0x2b, 0xc8, 0xf1, 0xc1, 0x2f, 0xb7, 0xf7, 0xbf, 0xc7, 0x0a, 0x3b, 0xce, 0x30, 0x2f, 0x26, + 0xe4, 0xda, 0x40, 0x6b, 0x1b, 0xa1, 0x6d, 0xfe, 0x32, 0x73, 0x61, 0xee, 0x37, 0x12, 0xb5, 0x07, + 0xc7, 0x83, 0x14, 0x3e, 0xb4, 0xcd, 0xff, 0x74, 0xbb, 0x71, 0x58, 0x87, 0x3c, 0x28, 0x5c, 0x73, + 0x25, 0xd5, 0x2d, 0x44, 0xa2, 0xbb, 0xa6, 0x4a, 0xae, 0xfc, 0x7d, 0xdf, 0x05, 0x44, 0x97, 0xb8, + 0xb2, 0xfb, 0xba, 0xa8, 0x83, 0x7f, 0x16, 0xa1, 0x44, 0xb0, 0xef, 0x12, 0x10, 0x8f, 0x75, 0xa0, + 0xc6, 0x47, 0x93, 0xd2, 0x12, 0x2c, 0x8f, 0xb7, 0x79, 0xc8, 0xae, 0x90, 0x5c, 0xc9, 0x7a, 0xfb, + 0xf8, 0x50, 0x58, 0x1d, 0xea, 0x2b, 0xa5, 0x1d, 0xdb, 0xbb, 0x88, 0x7d, 0xd0, 0x69, 0xbd, 0xdd, + 0xf8, 0x81, 0x05, 0xbb, 0xbf, 0xc5, 0x0c, 0xd3, 0x15, 0x6a, 0x5a, 0x57, 0x04, 0x20, 0xc4, 0x11, + 0x94, 0x2a, 0xae, 0x95, 0xad, 0x63, 0x06, 0x8a, 0xe8, 0x2a, 0x9a, 0x1f, 0xe8, 0x7b, 0x9f, 0x41, + 0x07, 0xe2, 0x43, 0x20, 0xb0, 0x64, 0x00, 0xfd, 0xe8, 0xcb, 0xc0, 0xf6, 0xbd, 0xd0, 0xaa, 0xab, + 0x2c, 0x72, 0xfa, 0xe2, 0x04, 0x82, 0xda, 0x27, 0x64, 0xe2, 0xb9, 0x6e, 0xe1, 0x44, 0x42, 0x82, + 0x21, 0xe6, 0xe4, 0x14, 0x55, 0xf7, 0x6b, 0x08, 0x17, 0x9a, 0x5c, 0x30, 0xfc, 0xf0, 0x1e, 0x90, + 0x12, 0x04, 0xf9, 0x52, 0x52, 0x65, 0xb0, 0x38, 0x85, 0x83, 0xbe, 0x06, 0x29, 0xba, 0x43, 0xb7, + 0x10, 0x24, 0x67, 0x7b, 0xd8, 0xdd, 0xdd, 0xed, 0xc5, 0x67, 0xd1, 0xe5, 0x0a, 0xa4, 0xb1, 0xd8, + 0x88, 0x2b, 0x13, 0x06, 0xf8, 0xe7, 0x5b, 0xb6, 0x8d, 0xc6, 0xf5, 0xc9, 0x78, 0x90, 0x57, 0x62, + 0x11, 0x60, 0xd4, 0x2f, 0x37, 0x95, 0x6a, 0xe5, 0xe5, 0xbf, 0xf0, 0xcc, 0x28, 0x70, 0x9b, 0x61, + 0xb3, 0x5c, 0xc3, 0xf0, 0x5a, 0x06, 0x7c, 0xcb, 0x6b, 0x4d, 0x19, 0xd7, 0xcf, 0x58, 0x93, 0xe6, + 0x8d, 0x15, 0x88, 0x12, 0x14, 0x9d, 0xc3, 0xf4, 0x39, 0xc2, 0x47, 0xc5, 0xb7, 0xde, 0xed, 0xc5, + 0x62, 0xb7, 0x77, 0x38, 0x7c, 0x40, 0x91, 0x24, 0x7b, 0xdf, 0x7c, 0x48, 0x90, 0x8d, 0x82, 0x13, + 0x31, 0x75, 0x5c, 0xee, 0x3a, 0x65, 0x6f, 0xdf, 0x10, 0x20, 0x28, 0x32, 0x32, 0xc1, 0x9e, 0xf2, + 0xab, 0x35, 0x8b, 0x89, 0xe9, 0xb9, 0x35, 0x4b, 0x6f, 0xc2, 0xc7, 0x79, 0xdc, 0x32, 0x0c, 0x41, + 0x19, 0xd8, 0x39, 0x88, 0x2d, 0x1f, 0x42, 0x9d, 0x09, 0xaf, 0xae, 0x51, 0x1d, 0x5e, 0x2f, 0xab, + 0x0c, 0x32, 0x11, 0x0a, 0x11, 0x55, 0x55, 0x55, 0x55, 0x56, 0x4d, 0x48, 0x5a, 0x1e, 0x3c, 0x56, + 0xb2, 0xf1, 0x00, 0xa7, 0x17, 0x52, 0x48, 0xb9, 0xee, 0x32, 0xb7, 0x45, 0x13, 0x81, 0xc3, 0xc9, + 0xdd, 0xf8, 0x90, 0x58, 0x45, 0x0b, 0x7c, 0xbd, 0x5c, 0x5c, 0x63, 0xb3, 0x8f, 0xb3, 0xe1, 0x43, + 0x17, 0x93, 0xa9, 0x7e, 0xae, 0xa8, 0xde, 0xd3, 0x62, 0xea, 0xab, 0x0e, 0x5f, 0x48, 0x72, 0xdd, + 0x1f, 0x88, 0x12, 0x14, 0x81, 0x8b, 0x15, 0xdb, 0x4f, 0x2a, 0xfe, 0x45, 0x82, 0xd8, 0x95, 0x0e, + 0xfa, 0x39, 0x57, 0x14, 0xb0, 0xce, 0xf2, 0xc0, 0x5f, 0x8e, 0x18, 0xf1, 0xc0, 0x5f, 0x94, 0xb4, + 0xcc, 0xcc, 0xab, 0xf1, 0x02, 0x01, 0x58, 0xd2, 0xd9, 0x6f, 0xce, 0x48, 0x49, 0x20, 0xca, 0x45, + 0xc2, 0x52, 0xfb, 0x88, 0x90, 0x8e, 0x2b, 0xbe, 0x24, 0x40, 0x50, 0xee, 0xe2, 0xb7, 0xb1, 0x59, + 0x72, 0xca, 0xc1, 0x6d, 0x39, 0x63, 0x15, 0x8a, 0x31, 0x46, 0xf8, 0x64, 0x82, 0x40, 0x1f, 0x60, + 0xb7, 0x3a, 0x37, 0xad, 0x77, 0xbf, 0x91, 0x8d, 0x7c, 0x48, 0x50, 0x8e, 0x2b, 0x77, 0xd2, 0x2e, + 0x3b, 0xb8, 0xad, 0xec, 0x56, 0x2b, 0x4d, 0xc4, 0x5e, 0x7b, 0xe1, 0x00, 0x80, 0xe1, 0x58, 0xe2, + 0xa8, 0xfd, 0x8d, 0x01, 0xef, 0x4a, 0x82, 0x2d, 0x1e, 0x5b, 0x7f, 0x82, 0x61, 0x16, 0xe5, 0x8c, + 0x2e, 0x2a, 0xc6, 0x7b, 0xc7, 0xd3, 0x17, 0xfe, 0x24, 0x10, 0x94, 0xa1, 0x5b, 0x8e, 0x3a, 0x76, + 0x07, 0x4f, 0xdf, 0x0c, 0xa0, 0xbf, 0x7c, 0xb1, 0x71, 0x71, 0x71, 0x70, 0x97, 0x42, 0xb2, 0x8d, + 0xe8, 0xd1, 0x49, 0xc1, 0x3d, 0xf7, 0x6b, 0x73, 0xb7, 0x0c, 0x89, 0x04, 0xdc, 0xb8, 0xe2, 0x5c, + 0x56, 0xc9, 0x55, 0x26, 0xbe, 0x14, 0x33, 0xa4, 0xe7, 0xc2, 0xe4, 0xb5, 0x35, 0x17, 0x51, 0x75, + 0x5c, 0x89, 0xc4, 0x42, 0x90, 0x04, 0xc5, 0x6b, 0xea, 0xf5, 0xa0, 0xc1, 0x3c, 0xcb, 0xc2, 0xd9, + 0x52, 0x9b, 0x8e, 0x7a, 0x97, 0xd2, 0x17, 0x55, 0x5b, 0xdc, 0x9d, 0xf7, 0xed, 0xdd, 0xf1, 0x11, + 0xe2, 0x5d, 0xad, 0x83, 0x60, 0xc7, 0x9a, 0xee, 0xc5, 0x55, 0xf1, 0xe6, 0x73, 0x74, 0x95, 0x31, + 0x2f, 0x52, 0xf1, 0x75, 0x33, 0x04, 0x34, 0xa8, 0xeb, 0x10, 0x24, 0x58, 0x8a, 0x47, 0x0d, 0x03, + 0xff, 0xce, 0x95, 0x5e, 0x24, 0x61, 0xe0, 0xe4, 0x99, 0xa6, 0x04, 0x1f, 0x5b, 0x39, 0x15, 0xab, + 0xf3, 0xca, 0x92, 0x03, 0x57, 0xa6, 0x05, 0x43, 0x68, 0xd9, 0xca, 0xb1, 0x7c, 0x20, 0x2e, 0xf2, + 0x6d, 0x49, 0x08, 0x23, 0x62, 0xc5, 0xc4, 0x09, 0x44, 0xff, 0x12, 0x11, 0x04, 0xa5, 0xba, 0xdd, + 0xdd, 0xff, 0xe1, 0x10, 0x9d, 0xa6, 0x92, 0xde, 0xf0, 0xeb, 0x38, 0x01, 0x6b, 0x46, 0x2f, 0xb9, + 0x38, 0x3d, 0xea, 0xaa, 0xaa, 0xa0, 0xed, 0xc7, 0x6f, 0xed, 0xfb, 0x2b, 0x2e, 0x0a, 0x41, 0x59, + 0x0b, 0x92, 0xdc, 0x65, 0x31, 0x79, 0xc8, 0x27, 0xf8, 0x89, 0x9d, 0xf0, 0x55, 0x12, 0xf7, 0x1a, + 0x58, 0x8c, 0x62, 0x19, 0x2a, 0x5b, 0xe2, 0x25, 0xc7, 0xe2, 0x51, 0x77, 0xd1, 0x0e, 0xba, 0x89, + 0x12, 0x10, 0x1d, 0xbb, 0xdd, 0xe5, 0xba, 0x5c, 0x48, 0x21, 0xe0, 0xa3, 0x0a, 0xf4, 0x3e, 0x55, + 0xd1, 0xd3, 0xaf, 0x45, 0x4e, 0x97, 0x44, 0x82, 0xfa, 0x23, 0x49, 0xc1, 0x21, 0x44, 0xac, 0x0a, + 0xdc, 0x56, 0x35, 0x63, 0x8f, 0x0c, 0x89, 0x05, 0x02, 0x1d, 0xda, 0x1e, 0xf3, 0x30, 0xe3, 0x09, + 0x1e, 0x70, 0xb5, 0x3f, 0x10, 0x24, 0x22, 0x6a, 0xdf, 0x66, 0xb6, 0xb5, 0xe2, 0x42, 0x85, 0xb8, + 0xa3, 0x14, 0x62, 0xb9, 0xf2, 0xed, 0x6c, 0xb2, 0x41, 0x57, 0x2d, 0x7c, 0x13, 0x10, 0x6e, 0x59, + 0x7c, 0x92, 0x48, 0xcf, 0x1b, 0x9b, 0x19, 0xe3, 0xf8, 0xe7, 0xf1, 0x20, 0x98, 0xed, 0x3a, 0x07, + 0xaa, 0xaf, 0x71, 0x30, 0x53, 0x7b, 0xbb, 0xbb, 0xeb, 0x17, 0xee, 0x20, 0x40, 0x50, 0x44, 0x69, + 0xa2, 0xec, 0x00, 0xe8, 0x15, 0x79, 0xf4, 0xdd, 0x5c, 0x0f, 0x11, 0xe9, 0x12, 0xd7, 0xfb, 0x32, + 0xd5, 0x54, 0x04, 0xbb, 0x36, 0x5e, 0x7e, 0xee, 0x59, 0x93, 0x00, 0x72, 0x15, 0x41, 0x73, 0x30, + 0x46, 0x3b, 0x88, 0x8d, 0xa2, 0x82, 0xec, 0x94, 0x88, 0x24, 0xa7, 0x97, 0x4e, 0xb1, 0xf7, 0x90, + 0x4a, 0x52, 0xd9, 0x41, 0xb2, 0x1a, 0x38, 0x5d, 0xc2, 0x7c, 0x55, 0x29, 0xd6, 0x05, 0x90, 0x5c, + 0x46, 0x01, 0x29, 0x2d, 0x59, 0xd0, 0xf6, 0xfc, 0x3f, 0xc6, 0x1e, 0xab, 0x6b, 0xff, 0xe1, 0x48, + 0xed, 0xbe, 0x71, 0xc6, 0x81, 0x93, 0xa5, 0x6d, 0xeb, 0xf1, 0x12, 0x47, 0xb9, 0x71, 0x22, 0x78, + 0x57, 0x6d, 0xf2, 0xdf, 0xb1, 0xbf, 0xe3, 0x1a, 0xeb, 0xd8, 0xb5, 0x51, 0x75, 0xe2, 0x0d, 0xbb, + 0xf1, 0x21, 0x10, 0x54, 0x58, 0x95, 0x88, 0xac, 0x50, 0x62, 0xb1, 0x58, 0xa3, 0x10, 0x0e, 0x16, + 0x31, 0x41, 0x8a, 0x0d, 0x1c, 0x78, 0x40, 0x22, 0x14, 0x23, 0xb9, 0x7c, 0x66, 0xf5, 0x13, 0xc9, + 0x12, 0xfd, 0xb0, 0x68, 0xb8, 0xcc, 0xef, 0xc3, 0x00, 0xa0, 0x61, 0x46, 0xfb, 0x63, 0x37, 0xc1, + 0xef, 0x12, 0x62, 0x05, 0x37, 0x89, 0xf9, 0x75, 0x1d, 0x47, 0x08, 0x82, 0xe8, 0xad, 0xdd, 0xea, + 0xaa, 0xfe, 0x11, 0x2d, 0xdd, 0x4d, 0x9e, 0x08, 0x6b, 0x5b, 0xf1, 0x30, 0xa5, 0xb7, 0x96, 0x85, + 0xc0, 0xd3, 0x1a, 0xf4, 0x7d, 0x41, 0xe7, 0x80, 0xf7, 0x84, 0xc2, 0xa5, 0x8d, 0x2f, 0xc2, 0x83, + 0xb7, 0x77, 0x10, 0xd0, 0x56, 0x5b, 0x3e, 0x6e, 0x2b, 0x15, 0xbd, 0xe9, 0xf8, 0x28, 0x8b, 0x88, + 0x70, 0x43, 0x82, 0x83, 0x2c, 0x63, 0xfd, 0x96, 0x31, 0x03, 0x4c, 0x10, 0x4a, 0x37, 0x11, 0xc6, + 0xc5, 0xf5, 0x62, 0xba, 0x36, 0xa2, 0xfa, 0x3f, 0x4f, 0xd1, 0x4a, 0x9c, 0x10, 0xf8, 0x81, 0x21, + 0x41, 0x8a, 0xcc, 0x4c, 0xe1, 0x86, 0xf6, 0xb6, 0xda, 0x2d, 0x3b, 0x8e, 0xdc, 0x20, 0x11, 0x15, + 0x55, 0x55, 0x36, 0x33, 0x3c, 0x40, 0x44, 0x29, 0x15, 0x8a, 0xfd, 0xdd, 0x6b, 0x88, 0x1e, 0x5e, + 0x73, 0xdf, 0xe3, 0xe5, 0x9a, 0x93, 0x25, 0x6b, 0x17, 0x55, 0x5c, 0x4c, 0x15, 0x09, 0x15, 0xdf, + 0x24, 0x05, 0x32, 0xcc, 0x47, 0x0e, 0x39, 0x17, 0x7e, 0x10, 0x10, 0x30, 0xc2, 0x98, 0xb8, 0xba, + 0x8c, 0x29, 0xcf, 0xa9, 0xf8, 0x5e, 0x29, 0x8a, 0x62, 0x9e, 0x59, 0x05, 0xeb, 0x88, 0x12, 0x14, + 0x26, 0x6e, 0xa3, 0xed, 0x48, 0x01, 0xe7, 0xb8, 0xa7, 0x2c, 0x34, 0xb2, 0x1c, 0x0d, 0x1e, 0x18, + 0x27, 0xd0, 0xbf, 0x38, 0xf4, 0xe5, 0xbe, 0xe2, 0x21, 0x42, 0x8a, 0x3a, 0x88, 0x42, 0xa3, 0xfe, + 0xe0, 0xa9, 0x7c, 0x88, 0xe1, 0xdf, 0x66, 0x15, 0x44, 0xfe, 0x15, 0x68, 0x9c, 0x31, 0x10, 0xa5, + 0xac, 0x96, 0x6d, 0x64, 0x93, 0x85, 0x41, 0x33, 0xdd, 0xd9, 0x6c, 0x56, 0xfe, 0x73, 0xec, 0xb7, + 0xde, 0x24, 0x29, 0x0e, 0xe0, 0x54, 0x78, 0xe2, 0x30, 0xc6, 0x17, 0xbd, 0xf2, 0x20, 0x71, 0x8c, + 0xb0, 0x72, 0x5e, 0x7e, 0xde, 0x74, 0xe2, 0x44, 0x8e, 0x3d, 0x2a, 0x8a, 0xc5, 0x62, 0xb1, 0x5a, + 0xf4, 0xf1, 0x1f, 0x12, 0x2a, 0x5e, 0x5b, 0x8a, 0xdd, 0xc4, 0x8c, 0x0b, 0x78, 0x80, 0x70, 0x14, + 0x8d, 0xe1, 0xc8, 0x73, 0xa7, 0x80, 0x38, 0x51, 0x35, 0x48, 0xbb, 0xb9, 0x63, 0x27, 0x55, 0xfd, + 0xb8, 0x2a, 0x2b, 0x91, 0xde, 0x11, 0x02, 0x08, 0x28, 0xda, 0x6e, 0x7b, 0xba, 0x3b, 0xe2, 0x45, + 0x55, 0x55, 0x55, 0x55, 0x70, 0x8f, 0x89, 0x0c, 0x82, 0xce, 0xa2, 0xf9, 0x14, 0x6a, 0xd4, 0xab, + 0xe2, 0x42, 0x20, 0xb8, 0x8a, 0xaa, 0xb7, 0xbf, 0xf8, 0x90, 0xc8, 0x9b, 0x9f, 0x34, 0xa2, 0xb7, + 0xc4, 0x42, 0x91, 0x03, 0x87, 0xbc, 0x40, 0x0e, 0x12, 0x8a, 0xa7, 0xd7, 0x80, 0xfb, 0xbd, 0xb3, + 0x49, 0x6a, 0x07, 0x1c, 0x6a, 0x3a, 0xf1, 0xc9, 0x07, 0x56, 0x1e, 0xe5, 0x8a, 0x0c, 0xac, 0x79, + 0xc9, 0x3a, 0xf0, 0x56, 0x28, 0xe0, 0xf5, 0x1c, 0x77, 0x0e, 0x39, 0x71, 0x69, 0xa9, 0x64, 0xed, + 0xda, 0xe0, 0x82, 0x09, 0x8e, 0xee, 0xf9, 0x4a, 0x4b, 0x97, 0xfa, 0xf4, 0x31, 0xd1, 0x63, 0xdf, + 0x5e, 0xa8, 0x47, 0xe2, 0x41, 0x49, 0x1d, 0xf3, 0xe1, 0xf8, 0x93, 0x8b, 0x15, 0x76, 0xbb, 0x84, + 0x03, 0x3c, 0x4c, 0x93, 0x41, 0x7e, 0x24, 0x29, 0xb5, 0x4a, 0xcb, 0x62, 0xb1, 0x23, 0x9b, 0x8a, + 0xe1, 0x46, 0xa1, 0x2b, 0x07, 0x83, 0x9d, 0xe1, 0x91, 0x85, 0x55, 0x4f, 0xf4, 0xa8, 0xb8, 0xb8, + 0x93, 0x9a, 0x31, 0x5a, 0xa5, 0x77, 0x56, 0x64, 0xbb, 0x31, 0x31, 0x94, 0x79, 0xd6, 0x27, 0xf1, + 0xa6, 0x22, 0x1e, 0xad, 0x8c, 0x96, 0x78, 0xbe, 0x22, 0x14, 0x20, 0xa0, 0x62, 0x99, 0x66, 0x2f, + 0x19, 0x59, 0xb4, 0x1b, 0x31, 0x4c, 0x5c, 0x5c, 0x5e, 0x33, 0x72, 0xfa, 0xcb, 0x71, 0x10, 0x4d, + 0x27, 0x46, 0x0f, 0x5d, 0x7a, 0xea, 0xbf, 0xf8, 0x27, 0xb9, 0x6d, 0xc5, 0x1c, 0x57, 0x73, 0xdc, + 0x44, 0x28, 0x53, 0x28, 0xa1, 0xbf, 0xdb, 0xe5, 0xa5, 0x68, 0x66, 0xfb, 0xdd, 0xff, 0xf0, 0xa1, + 0x42, 0xed, 0x45, 0xa9, 0xb8, 0xd2, 0x45, 0xbb, 0x47, 0x97, 0x56, 0xd4, 0xb1, 0x96, 0xc5, 0x18, + 0xac, 0xb6, 0x5b, 0x71, 0x5b, 0xf1, 0x3e, 0x0a, 0x44, 0x05, 0x0a, 0xaa, 0xab, 0x4a, 0xd2, 0x71, + 0xce, 0xb1, 0x58, 0xad, 0xc5, 0x7d, 0xc1, 0x00, 0x80, 0x52, 0x47, 0x9c, 0x82, 0x72, 0x0e, 0xe6, + 0xcb, 0xde, 0xfc, 0x48, 0x64, 0x17, 0x10, 0x56, 0x2b, 0xef, 0xaa, 0x3b, 0xe2, 0x07, 0xdd, 0xca, + 0xc5, 0xa8, 0xba, 0xa8, 0xb8, 0xb8, 0xb8, 0xbe, 0x24, 0x48, 0x40, 0x5b, 0x5a, 0xbd, 0xb5, 0x51, + 0x71, 0x71, 0x7e, 0x27, 0xc4, 0x05, 0x05, 0x2c, 0x47, 0x37, 0xb8, 0x53, 0x85, 0x57, 0xcb, 0xd9, + 0xe2, 0x77, 0xd2, 0xf9, 0x43, 0x12, 0x24, 0x12, 0x95, 0x6a, 0xa9, 0x25, 0x69, 0xf8, 0x42, 0x0a, + 0x4b, 0x70, 0x5b, 0xcb, 0x37, 0x04, 0xa0, 0x00, 0x13, 0xc0, 0xb6, 0x5b, 0x3d, 0xa1, 0xe3, 0x41, + 0x00, 0xd0, 0xe0, 0x68, 0x44, 0x38, 0xf0, 0x42, 0x0e, 0x44, 0x90, 0xf7, 0xd9, 0xce, 0x58, 0xac, + 0x56, 0x2b, 0x15, 0xe1, 0x10, 0xc8, 0x52, 0x9b, 0xe2, 0x07, 0xa4, 0x00, 0x1a, 0x05, 0x67, 0x02, + 0xa3, 0x36, 0x26, 0x2b, 0x46, 0xa6, 0x0a, 0xef, 0xfc, 0x44, 0x68, 0xe2, 0xa7, 0xcc, 0x79, 0x65, + 0xe9, 0x03, 0xde, 0x13, 0x93, 0x8a, 0xb7, 0xf6, 0xa4, 0xff, 0x64, 0x1f, 0xbf, 0x1b, 0xef, 0xf8, + 0x62, 0x1e, 0x28, 0xac, 0x57, 0x4e, 0x28, 0xc4, 0x8e, 0x1b, 0x1f, 0xaa, 0x77, 0x9b, 0xb3, 0x86, + 0x7a, 0xd4, 0x6d, 0x13, 0xaf, 0xf8, 0x88, 0x22, 0xcd, 0xf8, 0xbe, 0x5e, 0xaa, 0x16, 0xe8, 0x5f, + 0x7d, 0x62, 0x93, 0x82, 0xa3, 0x2e, 0xbc, 0x43, 0xcb, 0x78, 0xba, 0xc5, 0xc2, 0x00, 0xa4, 0x2d, + 0x10, 0xed, 0x93, 0xaa, 0xfc, 0x73, 0x15, 0xb1, 0x43, 0xf0, 0x20, 0x12, 0xb9, 0x62, 0x0a, 0x2f, + 0xba, 0xbf, 0xe0, 0x90, 0xae, 0xee, 0xef, 0xf0, 0x5a, 0x4a, 0xaa, 0xbd, 0xdd, 0xfc, 0x30, 0x30, + 0xda, 0xa8, 0x87, 0x96, 0x36, 0xf2, 0xd8, 0xb9, 0xb1, 0x2f, 0xc9, 0xbc, 0x48, 0x50, 0x4d, 0xe7, + 0x51, 0x5b, 0x54, 0xdd, 0x5a, 0x93, 0x32, 0x42, 0xd9, 0x3d, 0xbf, 0x08, 0x04, 0x07, 0x1e, 0x64, + 0x56, 0x21, 0xc1, 0xb5, 0x27, 0x34, 0x7f, 0x26, 0x35, 0x0a, 0xcb, 0x18, 0xb8, 0x9e, 0x62, 0x02, + 0x01, 0x41, 0x07, 0x7b, 0x31, 0x9c, 0x90, 0x6a, 0xa6, 0x19, 0x00, 0x05, 0x34, 0x5a, 0xd1, 0xa8, + 0x29, 0x6d, 0x31, 0x59, 0xb9, 0x29, 0x59, 0x24, 0x50, 0x87, 0xb9, 0xe2, 0x41, 0x0e, 0x57, 0xf7, + 0xc1, 0x5f, 0x77, 0x77, 0x77, 0x77, 0xb7, 0xdf, 0x05, 0x42, 0x5c, 0x56, 0x70, 0x80, 0x37, 0x15, + 0x8a, 0xde, 0x5f, 0x15, 0xfc, 0xf1, 0x21, 0x43, 0x0a, 0xdc, 0x56, 0x2b, 0xbb, 0xbd, 0xbb, 0xba, + 0xd5, 0x5f, 0x88, 0x12, 0x0a, 0xe3, 0x29, 0x8d, 0x4a, 0x62, 0xd7, 0xfd, 0xbe, 0xbd, 0xc5, 0x77, + 0xae, 0x11, 0x0c, 0x82, 0xc2, 0xbb, 0xe9, 0x89, 0x48, 0x26, 0x51, 0x9a, 0x8c, 0xdc, 0x57, 0xde, + 0x20, 0x15, 0x11, 0xdd, 0xdc, 0xf9, 0x9d, 0x54, 0x5d, 0xf8, 0x64, 0x40, 0x2e, 0xa6, 0x76, 0x0c, + 0xaa, 0xd5, 0x7a, 0xf8, 0x26, 0x3b, 0xbd, 0xc4, 0x73, 0x8b, 0xbf, 0x12, 0x10, 0x17, 0x55, 0x55, + 0x5d, 0x71, 0x02, 0x48, 0x29, 0x56, 0xb8, 0x88, 0x2c, 0x28, 0xc8, 0xc8, 0xbf, 0x23, 0xdc, 0xe1, + 0xdc, 0x4a, 0xdc, 0xb7, 0xdd, 0xfe, 0x14, 0xdb, 0xbb, 0xbb, 0xbb, 0xa5, 0x74, 0x9d, 0xdd, 0xef, + 0x85, 0x58, 0xb0, 0x00, 0xe1, 0x92, 0x0e, 0xce, 0xda, 0x83, 0xfc, 0xde, 0xde, 0xde, 0xde, 0x9a, + 0x71, 0xa7, 0x5e, 0x6e, 0x2f, 0x7b, 0xf0, 0x88, 0x44, 0x99, 0x8b, 0xa4, 0x88, 0xe3, 0x04, 0xfc, + 0xe6, 0x8d, 0xab, 0x32, 0xb9, 0xc2, 0x21, 0x91, 0x91, 0x58, 0xac, 0x56, 0x2b, 0x97, 0xe7, 0x8e, + 0x3f, 0x1d, 0x92, 0x2b, 0x8a, 0xf8, 0x64, 0x10, 0x8c, 0x25, 0xa3, 0x7d, 0x77, 0x77, 0xdd, 0xdd, + 0xf0, 0x84, 0x2a, 0x29, 0x45, 0xd7, 0x93, 0x62, 0x07, 0x81, 0x94, 0x34, 0x46, 0x83, 0xbe, 0xcf, + 0xf8, 0x7c, 0xe5, 0xc5, 0x38, 0x58, 0xc0, 0xd1, 0x57, 0x37, 0x09, 0x00, 0x0e, 0x0c, 0xc2, 0x69, + 0x25, 0x3d, 0xf0, 0x88, 0x8e, 0x2a, 0x53, 0xf6, 0x0e, 0x34, 0xc6, 0xca, 0xf9, 0xfa, 0x2f, 0x42, + 0x5d, 0x19, 0xd5, 0xd7, 0xb8, 0x98, 0x20, 0xad, 0xe3, 0x7c, 0xd6, 0x17, 0xa6, 0xb5, 0x8c, 0x5d, + 0x45, 0x30, 0x24, 0x87, 0xd2, 0x07, 0xd3, 0x64, 0x5b, 0xfc, 0x4c, 0x16, 0x95, 0xdd, 0xdd, 0xdc, + 0xb0, 0xb7, 0xfa, 0xbf, 0xc2, 0x17, 0x77, 0xdd, 0xee, 0xae, 0x6f, 0x89, 0x12, 0x42, 0x55, 0x57, + 0x89, 0x2d, 0xee, 0xf8, 0x91, 0x20, 0x94, 0xe2, 0x3f, 0x17, 0xbd, 0xdd, 0xf8, 0x90, 0x60, 0x14, + 0xee, 0x54, 0x85, 0x81, 0xee, 0xbf, 0x5d, 0x01, 0xaf, 0x55, 0xf1, 0x46, 0x0f, 0x3e, 0x58, 0x00, + 0x31, 0xd8, 0xfe, 0x18, 0x85, 0x23, 0xa8, 0x72, 0x5a, 0xc5, 0xc9, 0xa3, 0x4a, 0x56, 0x90, 0x56, + 0x16, 0xe4, 0x3a, 0xf9, 0xcf, 0x7f, 0x28, 0x55, 0x1f, 0x12, 0x5d, 0x0a, 0xc2, 0x5e, 0x51, 0xf0, + 0x51, 0x3b, 0x0d, 0xda, 0xa6, 0x2e, 0xd8, 0xca, 0xbf, 0x10, 0x19, 0x05, 0x7a, 0xbc, 0x56, 0x2b, + 0x2d, 0x8a, 0xef, 0x68, 0x7d, 0xc4, 0x08, 0x08, 0xf5, 0x75, 0xaa, 0xcb, 0xc4, 0x3c, 0xb7, 0xc4, + 0x82, 0xaa, 0xa8, 0xb9, 0x3b, 0x1b, 0xc6, 0x20, 0x78, 0xac, 0xb1, 0x8a, 0xc5, 0x1d, 0x1d, 0xe1, + 0x10, 0x38, 0x05, 0x0e, 0x78, 0x0b, 0x02, 0x83, 0x3c, 0x1e, 0xfc, 0x0b, 0x8a, 0xbb, 0x2b, 0x2c, + 0x0c, 0x4b, 0xd8, 0x3d, 0x84, 0x37, 0xed, 0xda, 0x73, 0x68, 0xf2, 0x8c, 0x90, 0x28, 0x14, 0x1d, + 0x59, 0x5d, 0x02, 0x4a, 0x44, 0x5f, 0x08, 0x42, 0x86, 0x12, 0xf5, 0xb5, 0x55, 0x5d, 0xcf, 0x7e, + 0xab, 0xa3, 0xb5, 0xc7, 0x95, 0x45, 0xd5, 0x55, 0x55, 0x55, 0x45, 0xd7, 0x12, 0x24, 0x13, 0x45, + 0xd5, 0x55, 0x55, 0x54, 0x71, 0xff, 0x04, 0x83, 0x2f, 0x7f, 0xf1, 0x30, 0xa0, 0xb2, 0x7d, 0x21, + 0x58, 0xac, 0x51, 0x8a, 0xc5, 0x7b, 0x8a, 0x31, 0x58, 0xac, 0x56, 0x2b, 0xa3, 0xbc, 0x44, 0x29, + 0x3f, 0x2c, 0x67, 0xa6, 0x27, 0x30, 0x3f, 0x57, 0x5a, 0x51, 0x3d, 0x35, 0xc5, 0xe2, 0x42, 0xc6, + 0x3c, 0x23, 0x93, 0xd3, 0x14, 0x4d, 0xca, 0x06, 0x1f, 0xf8, 0x5a, 0x64, 0x8e, 0xfc, 0x29, 0x6e, + 0x2f, 0x41, 0x44, 0xf3, 0x13, 0x92, 0x09, 0xc9, 0x04, 0xb6, 0x5b, 0x0e, 0xeb, 0x8e, 0x98, 0xd6, + 0x56, 0x4b, 0x8a, 0xf4, 0x71, 0xf1, 0x23, 0x27, 0xb0, 0x7f, 0x7f, 0x25, 0x59, 0x72, 0xf4, 0xcf, + 0x7a, 0x21, 0x4a, 0x59, 0xe3, 0x0a, 0xcd, 0xd9, 0xfc, 0x48, 0x95, 0x7e, 0x11, 0x0c, 0x82, 0x2b, + 0xc8, 0x47, 0x5c, 0x48, 0x44, 0x46, 0xb5, 0x26, 0x13, 0x35, 0xc3, 0x10, 0x54, 0x2a, 0x54, 0xe1, + 0xf2, 0xab, 0xac, 0xe1, 0xe7, 0x3a, 0x1d, 0x24, 0xae, 0x1f, 0xca, 0x2b, 0x25, 0x52, 0x08, 0x8e, + 0x1e, 0x1b, 0x2b, 0xa3, 0x1a, 0x21, 0x0c, 0xa0, 0xee, 0x90, 0x20, 0xb3, 0x95, 0xc1, 0x50, 0x25, + 0xd8, 0xfc, 0x25, 0xd7, 0xa2, 0x62, 0x44, 0x0d, 0xe2, 0xad, 0x5b, 0x17, 0x58, 0x84, 0x82, 0x29, + 0x88, 0xf0, 0x09, 0x6b, 0x15, 0xf3, 0x39, 0x3e, 0x3b, 0x1d, 0x87, 0x70, 0x08, 0x5a, 0x68, 0xef, + 0xff, 0x7b, 0xdf, 0xd1, 0x5f, 0x89, 0x89, 0xbb, 0xbb, 0xbb, 0xbb, 0xf1, 0x3f, 0x62, 0x1d, 0xe7, + 0x97, 0x0c, 0x8b, 0x13, 0xb6, 0x9c, 0xbd, 0x6f, 0x0c, 0x06, 0x47, 0x45, 0x74, 0xde, 0xea, 0xf8, + 0xba, 0xfc, 0x44, 0xb7, 0x67, 0xf1, 0x8e, 0xbf, 0x19, 0xe3, 0xdb, 0xf0, 0xc8, 0x44, 0x15, 0x44, + 0x8f, 0x6e, 0x16, 0xcb, 0x67, 0x8b, 0x07, 0x8a, 0x84, 0x2f, 0xcf, 0xf3, 0xae, 0xb8, 0x44, 0x43, + 0x21, 0x6c, 0x4b, 0xdb, 0xef, 0x08, 0x42, 0x87, 0x12, 0xb2, 0x89, 0x51, 0x78, 0x30, 0x55, 0xd4, + 0x23, 0x19, 0x75, 0x45, 0x63, 0x08, 0x51, 0x17, 0x0f, 0x7b, 0xf0, 0x7c, 0x77, 0x0d, 0x23, 0x80, + 0x5a, 0xc7, 0xea, 0xe3, 0x9d, 0x7a, 0xd6, 0xee, 0x7f, 0xd2, 0xae, 0xba, 0xdb, 0xb7, 0x6e, 0xb8, + 0x40, 0x14, 0x85, 0x0c, 0x28, 0xeb, 0x10, 0xe1, 0x33, 0x95, 0x9f, 0xfa, 0xbf, 0x2e, 0x44, 0xf0, + 0x8c, 0x16, 0x19, 0x78, 0x8f, 0x7e, 0x11, 0x84, 0xe5, 0xb1, 0x46, 0xee, 0xaa, 0xab, 0xc4, 0x88, + 0xd6, 0xaa, 0xaa, 0xbc, 0x4a, 0xf7, 0x88, 0x66, 0xaa, 0xaf, 0x85, 0x32, 0xf9, 0x19, 0x77, 0xb7, + 0x4e, 0xf7, 0x77, 0x2c, 0x2f, 0xc2, 0x22, 0x42, 0x85, 0x51, 0x5b, 0x18, 0xa3, 0x6d, 0x33, 0xfb, + 0x83, 0xdf, 0x10, 0xfa, 0xcb, 0x68, 0x85, 0x1b, 0x63, 0xe3, 0xbe, 0x0c, 0x02, 0x85, 0x17, 0x58, + 0x41, 0x07, 0x6c, 0x39, 0x4a, 0x3e, 0x80, 0xba, 0xf3, 0x69, 0xe4, 0x83, 0xaa, 0x54, 0x19, 0x7b, + 0x32, 0x71, 0x4d, 0x24, 0x1f, 0x8d, 0xd4, 0x71, 0xd8, 0x7c, 0xef, 0x0f, 0x60, 0x01, 0xae, 0x15, + 0x7e, 0x69, 0xbd, 0xd1, 0x1a, 0xf8, 0x90, 0xa7, 0x02, 0x60, 0x9f, 0x8c, 0x36, 0x0c, 0xf0, 0x72, + 0xc6, 0x29, 0xf5, 0x10, 0x12, 0x10, 0xb8, 0x6a, 0xeb, 0x76, 0xe2, 0x83, 0x6f, 0x3d, 0xc3, 0x9e, + 0x5b, 0x1f, 0x1c, 0x78, 0x98, 0x2b, 0xa6, 0x64, 0xe9, 0x1e, 0xfe, 0x33, 0xd8, 0x16, 0xcb, 0x62, + 0xb1, 0x5b, 0xe3, 0xe3, 0x8f, 0x13, 0x04, 0x77, 0x71, 0x5b, 0xa3, 0x8f, 0x08, 0x89, 0xe1, 0x90, + 0x62, 0x08, 0xea, 0xaa, 0xbd, 0xe1, 0x91, 0x04, 0x55, 0x55, 0x24, 0x3f, 0xc1, 0x08, 0xc1, 0x57, + 0x8d, 0xf8, 0xb6, 0x96, 0xd5, 0xbd, 0x32, 0x61, 0x61, 0xe4, 0xcf, 0x0d, 0x89, 0xd9, 0x28, 0x1a, + 0xda, 0x94, 0x0d, 0xc3, 0xf3, 0xa7, 0xe5, 0xea, 0xff, 0x57, 0xbe, 0xb1, 0x7d, 0x5e, 0xba, 0xbc, + 0xfd, 0x5e, 0x68, 0x91, 0x23, 0x48, 0x4e, 0x0e, 0x97, 0x4c, 0x76, 0xe2, 0x48, 0x80, 0x83, 0x5c, + 0xb4, 0x64, 0x5a, 0xc3, 0xb4, 0xa1, 0x03, 0x6a, 0x36, 0x3f, 0xe4, 0xa2, 0x6d, 0x62, 0x16, 0x71, + 0x02, 0xf6, 0x15, 0x91, 0x08, 0xa4, 0x19, 0xaf, 0xf6, 0xfe, 0x24, 0x14, 0x94, 0x3b, 0x7a, 0x4b, + 0x90, 0xff, 0xe0, 0xff, 0x84, 0x68, 0x47, 0x5f, 0x33, 0x6a, 0xc7, 0xbf, 0x75, 0x23, 0xd7, 0x7e, + 0x24, 0x43, 0xbb, 0xbb, 0xf9, 0x6e, 0xf7, 0xf3, 0x6e, 0xff, 0x15, 0xaa, 0xaa, 0xaa, 0xaa, 0x89, + 0x10, 0x12, 0xbb, 0xbb, 0xe3, 0x52, 0xbc, 0x14, 0x88, 0x18, 0x77, 0x8a, 0xdc, 0x2a, 0x0f, 0x8b, + 0x7c, 0xff, 0xba, 0xcf, 0xfc, 0x22, 0x09, 0xaf, 0x78, 0xa3, 0x14, 0x62, 0x8c, 0x48, 0xb0, 0x5b, + 0xe0, 0xae, 0xda, 0xb6, 0xa5, 0x60, 0x7b, 0x60, 0x1e, 0xd8, 0x6b, 0x06, 0x22, 0x33, 0xea, 0xaf, + 0xfe, 0x10, 0x05, 0x24, 0x77, 0x2e, 0xb3, 0x45, 0x62, 0x5c, 0xd6, 0xf7, 0x7e, 0x3b, 0xc4, 0xc2, + 0x92, 0xc6, 0x5b, 0x15, 0xbd, 0xde, 0xaa, 0xaa, 0xaa, 0xaa, 0xfc, 0x48, 0x97, 0x77, 0x77, 0xe1, + 0x1a, 0xef, 0x55, 0x5f, 0x17, 0xa6, 0x92, 0x71, 0x96, 0xcd, 0x5c, 0x40, 0x92, 0x65, 0xcd, 0xbf, + 0x89, 0x82, 0x4c, 0xb8, 0xf7, 0xdc, 0x08, 0x00, 0xc0, 0x28, 0x24, 0x26, 0x8f, 0x50, 0x4e, 0x09, + 0x81, 0x51, 0x35, 0x99, 0x14, 0x77, 0xc3, 0xfc, 0x77, 0xeb, 0x72, 0x3d, 0xed, 0xc5, 0xc0, 0x80, + 0x8e, 0xf8, 0x48, 0xc8, 0x58, 0x03, 0x26, 0x04, 0xc1, 0xb9, 0x30, 0x8c, 0x1c, 0xc7, 0x1c, 0x38, + 0xa0, 0x8b, 0x81, 0xa7, 0xb9, 0xe3, 0x92, 0xea, 0x14, 0x9c, 0x46, 0x97, 0x4c, 0x49, 0xf9, 0x28, + 0x98, 0xe7, 0x45, 0xa7, 0xa1, 0xd6, 0x6b, 0x3a, 0xbc, 0xf8, 0xc2, 0xd8, 0x63, 0xd4, 0xb0, 0x5e, + 0xc9, 0xf0, 0x06, 0x50, 0x75, 0x04, 0x78, 0xd4, 0x89, 0x57, 0xa6, 0x9f, 0x89, 0x85, 0x25, 0x8d, + 0xde, 0x14, 0x8f, 0x63, 0x15, 0xc5, 0x65, 0x8c, 0xb6, 0x5b, 0x78, 0xae, 0xe3, 0xe3, 0x83, 0xc4, + 0x89, 0x0a, 0x46, 0xf2, 0x6c, 0x0b, 0x76, 0x5c, 0x28, 0x80, 0x96, 0xdf, 0x8e, 0xee, 0xef, 0x7a, + 0x38, 0xf1, 0x02, 0x09, 0x6d, 0x5b, 0x1a, 0x31, 0xeb, 0xfe, 0x10, 0x8c, 0xaa, 0xaa, 0xa8, 0xba, + 0xaa, 0xa8, 0xba, 0xd6, 0xfe, 0x5d, 0x45, 0xc5, 0xfc, 0x22, 0x22, 0x24, 0x60, 0x99, 0xcf, 0xaa, + 0xaa, 0xeb, 0xc2, 0x11, 0xa4, 0x25, 0x52, 0x8b, 0x67, 0x06, 0x0e, 0xd3, 0xf1, 0x1e, 0x5b, 0x3e, + 0xc1, 0xf2, 0x8a, 0xf1, 0x78, 0x9b, 0x00, 0x97, 0x4c, 0x2e, 0x11, 0xe8, 0x67, 0x02, 0x91, 0x83, + 0xe3, 0x3a, 0x12, 0xd1, 0x90, 0x88, 0x91, 0xa6, 0x3a, 0x92, 0x69, 0xd4, 0xb1, 0x4b, 0x62, 0x8d, + 0xde, 0xce, 0xa3, 0x73, 0x71, 0x4e, 0x77, 0xb9, 0xa5, 0xc4, 0x30, 0x85, 0x54, 0x4f, 0xe2, 0x46, + 0xcd, 0xdb, 0xe1, 0x73, 0xeb, 0x0c, 0x6d, 0x50, 0xef, 0xc1, 0xbb, 0xbc, 0xdd, 0xe4, 0x47, 0x3c, + 0x6e, 0x66, 0xa3, 0xda, 0x24, 0x73, 0x2d, 0x2f, 0xff, 0x10, 0x24, 0x17, 0x55, 0xd3, 0x83, 0xea, + 0xff, 0xf1, 0x01, 0x11, 0x2e, 0x2b, 0x78, 0x87, 0xb9, 0x6c, 0x56, 0x33, 0x95, 0x2c, 0x43, 0xf8, + 0x92, 0xdd, 0xed, 0xfd, 0x47, 0xdf, 0x14, 0x45, 0x55, 0xe4, 0xfe, 0x25, 0x51, 0xdf, 0x12, 0x11, + 0x23, 0xdd, 0xe2, 0xf1, 0x7d, 0x57, 0xc7, 0x8b, 0x15, 0xbb, 0x9e, 0x96, 0xf6, 0xe2, 0xb7, 0x77, + 0xf0, 0x4d, 0x7b, 0x77, 0x15, 0xbb, 0xba, 0x38, 0x3f, 0x04, 0xd7, 0xde, 0xc4, 0x45, 0x2d, 0xe5, + 0xfc, 0x48, 0x95, 0x4e, 0x38, 0x91, 0x2a, 0xce, 0x26, 0x2a, 0xdd, 0xba, 0xa9, 0x94, 0x4b, 0xc4, + 0x08, 0x35, 0x55, 0x6f, 0x12, 0x90, 0x7c, 0x7d, 0xdf, 0x94, 0x60, 0xd9, 0x4c, 0x77, 0x77, 0x7e, + 0x24, 0x97, 0x77, 0x7c, 0x4c, 0x28, 0x57, 0x15, 0xb1, 0x0a, 0xda, 0x0b, 0x2a, 0x92, 0x95, 0x2b, + 0x1c, 0xec, 0x6c, 0x56, 0x2b, 0x7e, 0x24, 0x10, 0x82, 0xd9, 0x6c, 0xf1, 0x83, 0xbf, 0x05, 0x66, + 0x94, 0x43, 0x95, 0xc3, 0x20, 0x84, 0x29, 0x2c, 0x18, 0x54, 0x70, 0x58, 0x33, 0xdf, 0x2a, 0x84, + 0xeb, 0x58, 0x2c, 0x62, 0x56, 0x0e, 0x4c, 0x58, 0x71, 0xd6, 0x21, 0xe0, 0xef, 0xc9, 0x15, 0x1f, + 0x1c, 0x7e, 0x0a, 0x67, 0x29, 0x09, 0x91, 0xc8, 0x72, 0x90, 0xb7, 0x77, 0x72, 0xd8, 0xac, 0xb1, + 0x8a, 0xc7, 0xdf, 0x04, 0x57, 0x77, 0x74, 0x71, 0xf8, 0x21, 0xbb, 0xbb, 0xa3, 0xbe, 0x10, 0x1f, + 0x8d, 0x53, 0x3a, 0xdb, 0x26, 0x48, 0xf6, 0x51, 0x61, 0x00, 0xc0, 0x50, 0xa4, 0xf3, 0x2b, 0x5a, + 0x5c, 0xf4, 0x7e, 0xcc, 0xf7, 0x84, 0x7c, 0x48, 0x46, 0xa2, 0xea, 0xa2, 0xea, 0xab, 0x17, 0x5e, + 0x10, 0x8d, 0x1c, 0x98, 0x79, 0x1b, 0xe7, 0x38, 0x36, 0xfc, 0x04, 0x0f, 0x38, 0x52, 0x38, 0xac, + 0x56, 0xea, 0x6e, 0x7c, 0x19, 0xd7, 0xc5, 0x6d, 0x3d, 0xff, 0x84, 0x23, 0x70, 0x6f, 0xa6, 0x0e, + 0x97, 0x07, 0x37, 0x39, 0x64, 0xa9, 0x54, 0x05, 0xd3, 0x59, 0x46, 0xbf, 0x14, 0x89, 0x1a, 0x12, + 0x70, 0x70, 0x3e, 0xb3, 0xb5, 0x46, 0xad, 0x86, 0xcb, 0xc5, 0x74, 0x76, 0x57, 0x57, 0x4d, 0xd5, + 0xd5, 0xd5, 0xca, 0xe0, 0x9c, 0x97, 0xba, 0x1b, 0xc0, 0xbd, 0x34, 0x9f, 0xc4, 0x82, 0x93, 0x17, + 0xd6, 0xdf, 0x5c, 0x6e, 0xfb, 0x2c, 0x6f, 0x7e, 0x20, 0x32, 0x09, 0x3a, 0xab, 0xf8, 0x90, 0x90, + 0x91, 0xfb, 0x85, 0xbb, 0x79, 0x3c, 0x9f, 0xc1, 0x5c, 0xbe, 0xed, 0x8d, 0xb1, 0x1e, 0x7e, 0xd6, + 0x62, 0xe2, 0xea, 0xdc, 0x48, 0x84, 0x74, 0x77, 0xc4, 0xfc, 0x11, 0x13, 0x55, 0xef, 0x10, 0xbd, + 0xe2, 0x41, 0x0d, 0x6a, 0xaf, 0xf1, 0x44, 0xdd, 0xdd, 0xdd, 0xf1, 0x22, 0x01, 0x2d, 0xef, 0xdd, + 0xff, 0xf0, 0x52, 0x7b, 0xdd, 0xdf, 0x4e, 0x9f, 0x7a, 0xe6, 0xaa, 0xaa, 0xac, 0x40, 0x46, 0xb5, + 0xda, 0x6e, 0xaa, 0xa2, 0xef, 0x12, 0x6b, 0xbd, 0xfc, 0x65, 0xdd, 0xdd, 0xf7, 0x7d, 0xee, 0xff, + 0x18, 0x57, 0x2d, 0xbb, 0x8a, 0xdd, 0xce, 0xa1, 0xcf, 0x01, 0x5d, 0xd9, 0x6d, 0xdf, 0xc1, 0x2c, + 0x56, 0xd2, 0x0d, 0xd8, 0xad, 0xdd, 0xdf, 0xe0, 0xab, 0x75, 0x96, 0xcb, 0x18, 0x84, 0x20, 0x0d, + 0x8a, 0xc5, 0x6e, 0xe3, 0xee, 0x20, 0x40, 0xca, 0x21, 0x5f, 0x7b, 0xbb, 0xbb, 0xb6, 0xb5, 0x5c, + 0x57, 0x55, 0x51, 0x75, 0x17, 0xc4, 0x84, 0x42, 0x52, 0xf5, 0x55, 0x55, 0x17, 0x5c, 0x22, 0x24, + 0x4d, 0x75, 0x55, 0x55, 0x5c, 0x44, 0x12, 0x11, 0x6a, 0xe5, 0x4e, 0x24, 0x10, 0x04, 0x0a, 0x66, + 0x37, 0xd4, 0x57, 0xaa, 0xae, 0x19, 0x04, 0x20, 0xaa, 0x25, 0xc2, 0xa9, 0xb2, 0xf6, 0xc1, 0x9f, + 0x35, 0xbb, 0xbf, 0x12, 0x08, 0x46, 0x8c, 0x3e, 0xc6, 0x0e, 0xdc, 0x1f, 0x71, 0x3e, 0x79, 0xc2, + 0xaa, 0x40, 0x3c, 0xba, 0x9f, 0x62, 0xc4, 0x51, 0xd4, 0xad, 0x56, 0x2b, 0x6a, 0x33, 0x35, 0x16, + 0xd8, 0xae, 0xfe, 0x27, 0xa3, 0xb1, 0x19, 0xd4, 0x7d, 0xc4, 0x84, 0x46, 0x0a, 0x17, 0x97, 0x1c, + 0x1d, 0xfd, 0x82, 0x7d, 0x25, 0x46, 0x52, 0xf7, 0xac, 0x4e, 0x0c, 0xcd, 0xd8, 0x68, 0x62, 0x60, + 0xac, 0xe0, 0x20, 0xff, 0x6e, 0x13, 0xbf, 0xef, 0x58, 0x71, 0xa6, 0xea, 0xbb, 0xbb, 0xbb, 0x91, + 0xbe, 0xbd, 0x5c, 0x22, 0x41, 0x70, 0xd4, 0x62, 0x9e, 0xf7, 0xd6, 0x3c, 0xbe, 0x10, 0x1b, 0x2a, + 0x2f, 0x56, 0x0d, 0x70, 0x00, 0x14, 0x96, 0x0d, 0xff, 0x17, 0x77, 0x77, 0x1e, 0xa3, 0x59, 0xf8, + 0x9b, 0xbb, 0xbf, 0x13, 0x5f, 0xf1, 0x35, 0xff, 0xc1, 0x15, 0x54, 0x5d, 0x78, 0xe3, 0xc4, 0x42, + 0x9d, 0x53, 0x5a, 0xd4, 0x8c, 0x5b, 0x95, 0x5f, 0x71, 0x22, 0x41, 0x61, 0x9d, 0x8e, 0xc6, 0x2e, + 0xa2, 0xe2, 0xe5, 0xfe, 0xbd, 0x5c, 0x14, 0x14, 0xcc, 0x19, 0x83, 0x30, 0xe6, 0x15, 0x65, 0x72, + 0xf1, 0x00, 0xb6, 0x2e, 0xa8, 0x1d, 0x54, 0x5d, 0x5f, 0xe2, 0x48, 0xaa, 0xab, 0x5a, 0xae, 0x11, + 0x3d, 0xdc, 0x56, 0xee, 0xee, 0xee, 0x51, 0x83, 0x7e, 0x14, 0xb8, 0xae, 0xe2, 0xb1, 0x58, 0xa3, + 0x12, 0xf7, 0x7b, 0x8a, 0xcb, 0x18, 0xac, 0x56, 0x8e, 0xfc, 0x65, 0xde, 0xdc, 0x56, 0x2b, 0x15, + 0x8a, 0xdd, 0xde, 0xef, 0x7f, 0x05, 0xb7, 0x71, 0x5b, 0x8a, 0xdd, 0xdd, 0x1c, 0x6b, 0x9a, 0xaa, + 0xab, 0xe0, 0x86, 0xef, 0x74, 0x77, 0xe3, 0xab, 0x55, 0xaa, 0xea, 0xab, 0x89, 0x12, 0x14, 0x3b, + 0x4a, 0x31, 0x51, 0x78, 0xb8, 0xb8, 0x7c, 0xfc, 0x5e, 0xea, 0x4a, 0xac, 0x8b, 0xaa, 0xa5, 0xf8, + 0xe3, 0x2a, 0xaa, 0xbb, 0x73, 0x75, 0x55, 0x5f, 0x04, 0x35, 0x59, 0x58, 0xb8, 0x46, 0x38, 0x89, + 0x2e, 0xaa, 0x2e, 0xba, 0xaf, 0x08, 0x84, 0x62, 0xe2, 0xea, 0x2f, 0x7b, 0x8b, 0xaa, 0xac, 0x3a, + 0xc5, 0x80, 0x32, 0x80, 0xb7, 0x9f, 0x61, 0x0f, 0xcf, 0x6d, 0xb6, 0xdb, 0xa6, 0x28, 0x2c, 0x51, + 0x69, 0x8b, 0x62, 0xad, 0xb3, 0xd7, 0xbf, 0xf1, 0x20, 0x84, 0x16, 0x0e, 0x2e, 0xd2, 0x95, 0xa3, + 0x75, 0x57, 0x05, 0xc5, 0xd7, 0x2c, 0xe2, 0xe5, 0x9e, 0xfe, 0x24, 0x13, 0x78, 0xf5, 0xdc, 0x54, + 0x8b, 0x0c, 0x78, 0x5d, 0xca, 0x90, 0xa6, 0x24, 0x6c, 0xf9, 0x43, 0x17, 0x90, 0xe4, 0x76, 0x82, + 0xea, 0x4c, 0x91, 0xe5, 0x29, 0x78, 0x25, 0xa6, 0x11, 0x02, 0x42, 0x00, 0x83, 0xd9, 0x32, 0x64, + 0x2f, 0xf8, 0x81, 0x23, 0x60, 0xb5, 0x34, 0x95, 0xd2, 0x57, 0x49, 0xfb, 0xcf, 0x78, 0xbe, 0x67, + 0x6f, 0x83, 0xde, 0xee, 0x98, 0x2f, 0xcd, 0x82, 0xe7, 0xf0, 0x37, 0xd2, 0x58, 0xb1, 0x53, 0x5f, + 0xc4, 0x88, 0x5e, 0xae, 0xce, 0xee, 0xef, 0x88, 0x10, 0x0b, 0x04, 0x03, 0xb7, 0x23, 0x28, 0xb2, + 0x53, 0xce, 0x2b, 0x8a, 0xcf, 0x07, 0x75, 0x79, 0x16, 0x95, 0x78, 0x81, 0x87, 0x9a, 0x39, 0x4b, + 0xf3, 0xb7, 0x35, 0x3c, 0x43, 0x21, 0x83, 0x39, 0xa0, 0xff, 0x35, 0x80, 0x02, 0x4d, 0xa7, 0x44, + 0x48, 0x6b, 0xa1, 0x95, 0x75, 0x9a, 0xc9, 0xf8, 0x40, 0x28, 0x7d, 0xd5, 0x37, 0x3d, 0x04, 0xa4, + 0x12, 0xd8, 0xda, 0xb3, 0x1f, 0x8e, 0xcb, 0x15, 0xdb, 0x8f, 0xb8, 0x81, 0x3f, 0x5f, 0xfc, 0x11, + 0xdc, 0x56, 0xef, 0xff, 0x84, 0xaa, 0xaa, 0xa9, 0xb6, 0x5f, 0x5f, 0xa3, 0x77, 0x88, 0x04, 0xb5, + 0x5a, 0xaa, 0xaa, 0xf7, 0x88, 0x04, 0xb1, 0x75, 0x17, 0x17, 0x55, 0x55, 0xee, 0x24, 0x43, 0x2c, + 0xca, 0xaf, 0x85, 0x22, 0xe2, 0xeb, 0xdd, 0xce, 0xc3, 0xb1, 0xef, 0x78, 0xbe, 0xf5, 0xaf, 0x12, + 0xbd, 0xf0, 0x49, 0x77, 0x15, 0xba, 0x3b, 0xf0, 0x4b, 0x77, 0x77, 0x77, 0x77, 0x47, 0x7e, 0x0a, + 0x8b, 0x62, 0x4d, 0xb7, 0x15, 0xbb, 0x8a, 0xdd, 0xdc, 0x73, 0x7d, 0xc5, 0x62, 0xb1, 0x5b, 0xa8, + 0x91, 0x23, 0xaa, 0xaa, 0xb6, 0x55, 0x53, 0x50, 0x5c, 0xbf, 0x89, 0x24, 0xe4, 0x27, 0xc8, 0xf3, + 0x83, 0x88, 0x12, 0x4d, 0x67, 0x55, 0x5c, 0x44, 0x21, 0xa9, 0x3f, 0xb4, 0xea, 0xbf, 0x10, 0x08, + 0x49, 0x55, 0x5e, 0xf8, 0xbb, 0xbb, 0xbd, 0xa8, 0xbf, 0xb2, 0x2d, 0x7e, 0x63, 0xea, 0xb8, 0x90, + 0x88, 0xba, 0x8b, 0x8b, 0x8b, 0xab, 0x5e, 0x24, 0x22, 0x5a, 0xd5, 0x78, 0x44, 0x61, 0x8f, 0xc5, + 0x6c, 0x6e, 0xe7, 0x96, 0xc5, 0x65, 0x8c, 0x51, 0xbd, 0xe7, 0xc2, 0x56, 0x8e, 0xd4, 0xa1, 0x3e, + 0x8a, 0xfe, 0x24, 0x60, 0x88, 0xda, 0x88, 0x79, 0xe3, 0x04, 0x82, 0xf7, 0x1e, 0x81, 0x13, 0x0d, + 0x31, 0x5a, 0xd3, 0xc3, 0xdd, 0x50, 0xf2, 0x9e, 0xdf, 0x08, 0x82, 0xb1, 0x37, 0x15, 0xdd, 0xda, + 0x74, 0xce, 0xc7, 0xff, 0x8a, 0x26, 0xee, 0xee, 0xef, 0xc4, 0x22, 0xa7, 0x5e, 0x09, 0x2e, 0x2b, + 0xba, 0x75, 0xe0, 0xb0, 0x56, 0x20, 0x7c, 0x51, 0x8d, 0xe1, 0xd0, 0x98, 0xdc, 0x56, 0x2b, 0x3f, + 0x6f, 0x84, 0x06, 0xa6, 0xe3, 0x1c, 0xfd, 0xc3, 0xf4, 0x97, 0xc9, 0xaf, 0xe2, 0x44, 0x8c, 0xa5, + 0x13, 0x9d, 0x85, 0xcd, 0xf7, 0x93, 0xa6, 0xbc, 0x44, 0x75, 0xdd, 0xdd, 0xde, 0xef, 0x7e, 0x20, + 0x4f, 0x89, 0x04, 0x85, 0x6d, 0x36, 0xc8, 0xa5, 0x1c, 0x78, 0x98, 0x27, 0x95, 0x94, 0xca, 0xa7, + 0x52, 0x62, 0x56, 0x3e, 0xe2, 0x64, 0xb9, 0x52, 0x3d, 0xf8, 0x27, 0xbd, 0xde, 0xf3, 0xf1, 0xf7, + 0x89, 0x05, 0xda, 0x1a, 0xa1, 0xa7, 0x4f, 0xdf, 0x04, 0xb1, 0x84, 0xc7, 0x34, 0xcb, 0xcc, 0xa7, + 0xef, 0x13, 0xf0, 0x45, 0x4d, 0xbd, 0x1c, 0x7c, 0x40, 0x23, 0x8a, 0xdd, 0xc5, 0x68, 0xe3, 0xf1, + 0x45, 0x6e, 0xda, 0x62, 0xb1, 0x58, 0xac, 0x56, 0x4e, 0x28, 0x8a, 0xaa, 0xaa, 0xa2, 0xeb, 0x82, + 0x1b, 0xbb, 0xfe, 0x08, 0x48, 0xaa, 0xaa, 0x3b, 0x71, 0x02, 0x0b, 0x55, 0x4b, 0xea, 0x54, 0xf8, + 0x27, 0x23, 0xbd, 0xd3, 0x77, 0xf7, 0x88, 0x15, 0x5a, 0x3a, 0xeb, 0xe2, 0xeb, 0xa8, 0xbd, 0x57, + 0x11, 0x14, 0x25, 0x56, 0xaa, 0xb5, 0xc2, 0x22, 0x41, 0x55, 0x45, 0x35, 0xa6, 0x6d, 0x57, 0x46, + 0x82, 0x22, 0x8d, 0xf8, 0x91, 0x20, 0xb4, 0x8d, 0x52, 0xaa, 0xad, 0xf8, 0x64, 0x14, 0x8e, 0xad, + 0x56, 0x16, 0xd5, 0x83, 0x5a, 0xaf, 0x08, 0x82, 0x63, 0x32, 0x53, 0xdc, 0x3f, 0x0a, 0xb3, 0xb2, + 0x72, 0x20, 0x33, 0x2a, 0xe6, 0x1b, 0x77, 0x72, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x18, + 0x0c, 0x30, 0x7a, 0x02, 0x86, 0x11, 0x04, 0xe5, 0x76, 0x7c, 0x0c, 0x46, 0x6e, 0x51, 0x61, 0x17, + 0x46, 0x38, 0x80, 0x42, 0x10, 0x11, 0x86, 0x59, 0x67, 0x67, 0x31, 0x40, 0x6e, 0x2f, 0x55, 0xc3, + 0x18, 0x34, 0x88, 0x0c, 0x06, 0x87, 0xb7, 0x7a, 0x70, 0x71, 0x77, 0xb6, 0xf7, 0xc4, 0x82, 0x91, + 0x81, 0x06, 0x37, 0xa4, 0x7e, 0x4b, 0x5d, 0xf6, 0xd5, 0x4b, 0xeb, 0x17, 0xc2, 0x02, 0x44, 0xf9, + 0x3e, 0xed, 0x38, 0x5b, 0xa0, 0xaf, 0x7d, 0x4a, 0x9f, 0x5a, 0x93, 0xa3, 0x3f, 0xd1, 0x5e, 0x16, + 0xe8, 0xbb, 0x30, 0xeb, 0x80, 0x2a, 0xf5, 0x54, 0x3b, 0xdf, 0x9e, 0x1f, 0x98, 0x46, 0xd1, 0x20, + 0x99, 0x20, 0x89, 0xe9, 0x20, 0xac, 0xce, 0x24, 0x26, 0x16, 0xbd, 0xdb, 0xb7, 0xc4, 0x42, 0x98, + 0x9f, 0x58, 0x31, 0x4e, 0x6f, 0x52, 0xf5, 0x6f, 0xd4, 0xbf, 0x67, 0x88, 0x41, 0x3e, 0x97, 0xa3, + 0x38, 0x5c, 0xc7, 0x69, 0xd2, 0x4a, 0x12, 0xc2, 0x1b, 0x15, 0x28, 0x0c, 0x81, 0xbe, 0x9a, 0x69, + 0xa6, 0xdb, 0x6d, 0xb7, 0x0d, 0xa2, 0x00, 0x11, 0x1e, 0xbb, 0xe3, 0xfe, 0x7b, 0xff, 0xf1, 0xef, + 0x0b, 0x86, 0x0c, 0x1f, 0x30, 0x0c, 0xb6, 0xd9, 0xec, 0x9c, 0xfd, 0x2a, 0x30, 0xa3, 0xfc, 0x08, + 0x20, 0xe4, 0x14, 0x15, 0x38, 0xce, 0x7d, 0xe2, 0xeb, 0xcc, 0x81, 0x54, 0x44, 0x12, 0x0e, 0x8a, + 0xe5, 0xfc, 0x5d, 0xc4, 0x84, 0x42, 0x24, 0x89, 0xfa, 0x8b, 0xa9, 0xa3, 0x24, 0x59, 0xcd, 0xeb, + 0x88, 0xc9, 0xc4, 0x04, 0xdd, 0xf7, 0x7d, 0x43, 0x3e, 0x08, 0x60, 0xb0, 0x24, 0xe9, 0x54, 0x86, + 0x23, 0x99, 0x82, 0x29, 0x30, 0xe3, 0xdd, 0xa4, 0xe7, 0xc6, 0x70, 0xc0, 0x44, 0x75, 0x5a, 0x02, + 0xe9, 0x2f, 0xea, 0x26, 0x84, 0xf2, 0x27, 0xde, 0xc3, 0xf9, 0x6d, 0xff, 0x08, 0x09, 0x0a, 0x46, + 0xcb, 0x0f, 0x10, 0x1b, 0xb4, 0xdb, 0x78, 0x99, 0xa3, 0x7e, 0x74, 0x78, 0x79, 0xc8, 0x4b, 0xd8, + 0x8d, 0xf5, 0x31, 0x0f, 0x7e, 0x01, 0xee, 0x0e, 0x86, 0x5c, 0x40, 0x80, 0x42, 0x27, 0x98, 0xcc, + 0x6b, 0x5f, 0x47, 0xf4, 0x2f, 0xa1, 0x4e, 0xa5, 0xa6, 0xeb, 0x87, 0x08, 0x42, 0xe3, 0x01, 0xdb, + 0x94, 0x2b, 0x19, 0x89, 0xf4, 0x33, 0xcb, 0x17, 0xfc, 0xb0, 0xbe, 0x26, 0x30, 0xd5, 0x85, 0xa3, + 0x25, 0x06, 0x91, 0x4d, 0xea, 0x58, 0xdc, 0xb6, 0x17, 0x69, 0x7d, 0xf8, 0x64, 0xa5, 0x2f, 0x96, + 0xcb, 0x84, 0xe6, 0x1b, 0xc0, 0xf8, 0xd7, 0x0c, 0x84, 0x41, 0x60, 0xca, 0xae, 0xad, 0xec, 0x4d, + 0x10, 0xf2, 0xa1, 0x42, 0x03, 0xae, 0x7b, 0x88, 0x08, 0x8c, 0x31, 0x88, 0x29, 0x61, 0xd9, 0xfe, + 0x43, 0xd3, 0x68, 0xcb, 0x72, 0x81, 0xcd, 0xdd, 0xdf, 0x08, 0x84, 0x1f, 0xdd, 0x5a, 0xf3, 0x74, + 0xc4, 0x30, 0xc4, 0x89, 0x1d, 0xce, 0x91, 0xb1, 0x21, 0x84, 0x97, 0xcf, 0xe7, 0xf0, 0x84, 0x47, + 0x41, 0x3a, 0xfa, 0xc5, 0x37, 0x5a, 0x8f, 0xe8, 0xb1, 0x4f, 0xd5, 0x32, 0x5d, 0x12, 0x2f, 0xac, + 0x5e, 0x23, 0x88, 0x0c, 0x82, 0xd1, 0x9c, 0xbd, 0x6a, 0xbd, 0xc4, 0x89, 0x0a, 0x10, 0x3a, 0x02, + 0x8c, 0xfa, 0xc8, 0xb2, 0x1e, 0xc1, 0xe3, 0x17, 0x9c, 0xf6, 0xcc, 0x45, 0x9c, 0xd5, 0x86, 0xa5, + 0x0f, 0x8e, 0xc1, 0x76, 0x7e, 0x53, 0xd0, 0x95, 0x53, 0xe7, 0x84, 0x01, 0x34, 0x84, 0xab, 0x55, + 0x5e, 0x75, 0x96, 0xca, 0x6a, 0x2e, 0xa7, 0x49, 0x08, 0x89, 0x1f, 0x3e, 0xf1, 0x8f, 0x20, 0x07, + 0xce, 0x04, 0x06, 0xd3, 0x15, 0x95, 0x45, 0xf8, 0xeb, 0xd7, 0x3d, 0xeb, 0xd3, 0x0f, 0xfc, 0xbd, + 0xee, 0xdc, 0x4b, 0xfd, 0x8d, 0x1c, 0x29, 0x4d, 0x75, 0x89, 0x1c, 0x3a, 0x2e, 0x27, 0x88, 0x23, + 0x59, 0x87, 0x0e, 0x54, 0xec, 0x91, 0xcb, 0xe2, 0x10, 0x55, 0xe0, 0x9f, 0xaf, 0x7d, 0x7b, 0xea, + 0xff, 0x5f, 0xf1, 0x10, 0x4e, 0x29, 0x31, 0x5d, 0xd4, 0x8c, 0x54, 0xb7, 0x84, 0x42, 0x82, 0xa3, + 0x2d, 0xdc, 0xb0, 0xd9, 0xc2, 0xa1, 0x70, 0x17, 0x71, 0xb6, 0x25, 0xe5, 0xb3, 0xcb, 0x0d, 0xe4, + 0xfa, 0x58, 0xd6, 0x4f, 0x08, 0x89, 0xc7, 0xa7, 0x8d, 0xd3, 0x4d, 0xc2, 0x22, 0x4c, 0x2e, 0xec, + 0x80, 0x4d, 0xbe, 0xd9, 0xe5, 0x14, 0xbf, 0x3d, 0x30, 0x80, 0x90, 0x4a, 0x3e, 0x27, 0xe2, 0x6c, + 0x2f, 0x5e, 0xe2, 0x04, 0x8e, 0xad, 0x76, 0x96, 0xb5, 0x5f, 0x0a, 0x04, 0x38, 0xca, 0x85, 0x15, + 0x3d, 0xe5, 0xb7, 0x7d, 0x97, 0x2c, 0x55, 0x9d, 0xed, 0xfd, 0xf0, 0x42, 0x15, 0x10, 0x3e, 0x87, + 0x1a, 0x9c, 0x5c, 0x1a, 0x8e, 0xde, 0x10, 0x86, 0x7a, 0xb8, 0x27, 0x45, 0x2d, 0x27, 0x44, 0x72, + 0x2b, 0x04, 0x00, 0x9c, 0x96, 0xdd, 0xb4, 0xe9, 0xa5, 0xde, 0x19, 0x12, 0x38, 0xe7, 0x92, 0xb4, + 0x39, 0xe4, 0xad, 0x05, 0x6f, 0xe5, 0xf5, 0xf0, 0x88, 0x21, 0xe0, 0xa5, 0x4b, 0x22, 0x7b, 0xab, + 0x82, 0x41, 0xf0, 0x31, 0xb9, 0x6a, 0x72, 0x3d, 0x7c, 0x14, 0x0e, 0xf9, 0xba, 0xcb, 0xef, 0xe2, + 0x07, 0x1d, 0x63, 0x26, 0xdb, 0x7a, 0xbc, 0x8c, 0xd4, 0x40, 0x44, 0x22, 0x68, 0x33, 0xac, 0x91, + 0xc6, 0x99, 0xf1, 0x3b, 0xd7, 0x89, 0x04, 0x27, 0xdc, 0xe6, 0x0b, 0xd7, 0xb8, 0x80, 0xc4, 0x2d, + 0xd0, 0xf7, 0x2f, 0xab, 0x5f, 0x57, 0x03, 0xf8, 0x24, 0x10, 0xa9, 0x0c, 0xa9, 0xc0, 0x3e, 0x0e, + 0x05, 0x90, 0xc8, 0x28, 0xae, 0x21, 0x95, 0x03, 0xed, 0x47, 0xb8, 0x8e, 0xf8, 0xb7, 0x32, 0x9f, + 0xc4, 0x89, 0x18, 0x2b, 0x51, 0x5a, 0xcc, 0xaa, 0x2a, 0xbe, 0x20, 0x67, 0x54, 0xd7, 0x52, 0x12, + 0xd6, 0xaa, 0x23, 0xe6, 0x1e, 0x61, 0x70, 0x0e, 0x18, 0x95, 0x69, 0x69, 0xa7, 0xa6, 0x9f, 0xf9, + 0xeb, 0xdf, 0xf0, 0xe2, 0x10, 0x00, 0x32, 0x7d, 0xa9, 0xc6, 0x27, 0xfc, 0xff, 0xfc, 0xfc, 0xb0, + 0x1a, 0x90, 0xbc, 0x10, 0x90, 0x8e, 0x2b, 0x71, 0xce, 0x9c, 0x7f, 0xf0, 0x89, 0x47, 0x72, 0xb8, + 0x40, 0x22, 0x13, 0x2a, 0xd2, 0xaa, 0x9b, 0xb3, 0x78, 0x91, 0x86, 0x5c, 0x33, 0x48, 0x48, 0x40, + 0xc0, 0xe6, 0x1a, 0x6d, 0x0c, 0x06, 0xea, 0xc4, 0xe8, 0x23, 0xe7, 0x12, 0x20, 0x12, 0x8f, 0x24, + 0x05, 0x46, 0x0b, 0x74, 0x0a, 0x8f, 0x53, 0xd3, 0x0b, 0xd6, 0x54, 0x76, 0xf0, 0x40, 0xc4, 0xbb, + 0xe7, 0xea, 0xe8, 0x4b, 0xab, 0x90, 0x9c, 0x33, 0x05, 0x83, 0x07, 0xfc, 0xe0, 0x18, 0x0e, 0xa4, + 0x2e, 0x5c, 0x34, 0xab, 0xd0, 0xaf, 0xbe, 0xb8, 0x28, 0x07, 0x20, 0xa8, 0x93, 0xea, 0x19, 0x55, + 0xb8, 0xfb, 0xdd, 0xfd, 0xc4, 0x04, 0x46, 0x43, 0xa2, 0x25, 0x47, 0xb8, 0x58, 0x31, 0xe7, 0x82, + 0xac, 0x18, 0x80, 0x4b, 0x91, 0x4b, 0x20, 0xe1, 0x59, 0xc3, 0xdc, 0xb6, 0x25, 0xf5, 0xb3, 0x8e, + 0x5b, 0xaf, 0x84, 0x42, 0x92, 0x5e, 0x09, 0xcc, 0xb1, 0xff, 0x18, 0xe5, 0x96, 0xb2, 0x32, 0xcb, + 0x11, 0xdc, 0xc4, 0x2e, 0x49, 0x16, 0x3c, 0x3e, 0xa1, 0x26, 0x05, 0xfc, 0x9f, 0xe2, 0xf3, 0x17, + 0x12, 0x24, 0x64, 0x99, 0x3d, 0xd5, 0x7a, 0xc9, 0xc7, 0xa9, 0x25, 0xef, 0x62, 0x1f, 0x84, 0x01, + 0x08, 0xc2, 0x2c, 0x41, 0xf2, 0x64, 0xd4, 0xee, 0x2f, 0x8b, 0xb6, 0xb8, 0x80, 0x88, 0x92, 0xad, + 0x63, 0x18, 0xb2, 0xf2, 0xff, 0x18, 0x6e, 0x11, 0x28, 0xe5, 0x36, 0x11, 0x7e, 0x87, 0x3b, 0xcf, + 0x6a, 0x0e, 0x24, 0xfc, 0x43, 0xd4, 0x63, 0xc4, 0x88, 0x12, 0x13, 0x1b, 0x96, 0x9a, 0xb4, 0xe3, + 0x96, 0xaa, 0xab, 0xc1, 0x07, 0xd1, 0xe2, 0xbe, 0xb1, 0x7d, 0x70, 0x9f, 0xa2, 0x77, 0xd1, 0x5e, + 0x16, 0xeb, 0x14, 0x47, 0x46, 0xc3, 0xe6, 0x15, 0x2e, 0xc2, 0x83, 0x4e, 0x08, 0x42, 0x96, 0x65, + 0x8d, 0xe2, 0x5c, 0x56, 0xe2, 0x8c, 0x75, 0xfc, 0x74, 0xfa, 0x8a, 0xcf, 0x83, 0xca, 0x35, 0xc2, + 0x1f, 0x70, 0x84, 0x61, 0x4b, 0x92, 0xc6, 0x2b, 0x55, 0x4b, 0x5b, 0xd8, 0xac, 0x51, 0xb8, 0xa3, + 0x7f, 0x05, 0x24, 0x3f, 0xb0, 0xaa, 0xb6, 0xed, 0xbb, 0x67, 0x83, 0xec, 0xf7, 0x1b, 0x47, 0xe2, + 0x23, 0xb2, 0xab, 0x54, 0xf5, 0x55, 0xf8, 0xe3, 0xe9, 0xcb, 0x82, 0x58, 0x1c, 0xfa, 0xf9, 0x7b, + 0xdf, 0x12, 0x30, 0x83, 0xea, 0x5b, 0xf2, 0x74, 0x57, 0x5a, 0xa9, 0x7a, 0xfe, 0x30, 0x56, 0x6c, + 0xa4, 0xa3, 0x26, 0x89, 0xf6, 0x1c, 0x43, 0xdc, 0xe1, 0xe2, 0xb9, 0x2d, 0xf1, 0x22, 0x01, 0x58, + 0x44, 0x82, 0xbb, 0x6a, 0x61, 0x48, 0x1b, 0x15, 0x9d, 0x47, 0x7c, 0xaa, 0xaa, 0xfd, 0xc4, 0x02, + 0x0e, 0x10, 0xc4, 0x74, 0x2f, 0x50, 0x47, 0xd4, 0xa9, 0xc4, 0x48, 0x16, 0xdb, 0x64, 0x67, 0x10, + 0x19, 0x0a, 0x4b, 0x62, 0xb3, 0x9a, 0x16, 0xf8, 0x82, 0xce, 0x47, 0x00, 0xe0, 0xee, 0x12, 0x82, + 0x31, 0xcf, 0xcb, 0x1b, 0xc0, 0x03, 0xcf, 0x00, 0x79, 0xe0, 0xe1, 0x30, 0x38, 0x7e, 0x11, 0x12, + 0x14, 0x28, 0x91, 0xfd, 0xdc, 0x43, 0xda, 0x2d, 0x96, 0xdc, 0xb6, 0xda, 0xd5, 0x37, 0xe2, 0x04, + 0x82, 0x6d, 0xdb, 0xd5, 0x45, 0xd5, 0xfc, 0x47, 0x12, 0x20, 0xdd, 0xdf, 0x13, 0x14, 0x26, 0xaa, + 0xc3, 0x9a, 0x49, 0x3d, 0x8e, 0x24, 0xc1, 0x0b, 0xc1, 0xbe, 0x98, 0x40, 0x41, 0x43, 0x23, 0x62, + 0x09, 0x29, 0xd4, 0xc7, 0x7c, 0x4d, 0x7a, 0x2b, 0xab, 0x93, 0xf5, 0xab, 0xea, 0xc4, 0x33, 0x82, + 0x93, 0x05, 0x16, 0xbe, 0x10, 0x18, 0x47, 0x14, 0x71, 0x59, 0x6c, 0xb6, 0x1c, 0x70, 0x38, 0x69, + 0x99, 0x84, 0xce, 0x14, 0x9a, 0xac, 0x1b, 0x6f, 0x57, 0x04, 0x03, 0x27, 0xc7, 0xe2, 0xdd, 0x16, + 0xff, 0x10, 0xb1, 0x2d, 0x61, 0xb9, 0x57, 0x02, 0x69, 0xf2, 0xf7, 0xf0, 0x81, 0x4b, 0x6f, 0xdf, + 0x54, 0xdb, 0x76, 0xfc, 0x29, 0x7b, 0xdd, 0xc5, 0x62, 0xb9, 0xf6, 0x01, 0xb6, 0x25, 0xbc, 0x0e, + 0xf7, 0x8a, 0xa4, 0x68, 0x28, 0xb4, 0xc4, 0xb3, 0xe6, 0x34, 0x7e, 0x98, 0xef, 0x8c, 0x2e, 0x7c, + 0x77, 0x7c, 0xe9, 0x8c, 0xf1, 0x25, 0x9f, 0xfc, 0x49, 0x45, 0x67, 0xe2, 0xbc, 0xd1, 0xa2, 0xf1, + 0x22, 0x8c, 0x7c, 0x79, 0xd2, 0x72, 0xad, 0xc2, 0xdd, 0x65, 0xf5, 0xf0, 0xc8, 0x43, 0xc9, 0x9a, + 0xbb, 0x57, 0x3b, 0x2a, 0xb2, 0xa2, 0x3a, 0x09, 0xb8, 0x04, 0x9d, 0x19, 0xb8, 0x64, 0x48, 0x2b, + 0x26, 0x92, 0x58, 0x03, 0x61, 0xed, 0x61, 0x05, 0xbd, 0x0c, 0xeb, 0xa3, 0x2f, 0xff, 0xc4, 0x1a, + 0xb5, 0x49, 0x7f, 0x14, 0x22, 0x5c, 0x93, 0xbb, 0xbf, 0x8e, 0xa2, 0x05, 0x43, 0x96, 0x02, 0x9c, + 0xf6, 0x31, 0x9c, 0x6f, 0x75, 0x59, 0x39, 0x27, 0xf2, 0x9f, 0x77, 0xf1, 0x84, 0x06, 0x96, 0x60, + 0xe4, 0xc3, 0xe7, 0xec, 0xba, 0xb1, 0xff, 0x5c, 0x2f, 0x43, 0xae, 0xc8, 0x16, 0xd1, 0x03, 0xd6, + 0x83, 0xfe, 0x13, 0x7d, 0xb9, 0xee, 0x69, 0x6d, 0x1a, 0x27, 0x1d, 0x50, 0x05, 0xa3, 0xdb, 0xdb, + 0xc3, 0xb9, 0xab, 0xc9, 0x71, 0x50, 0xa6, 0x89, 0x65, 0x30, 0x3d, 0x64, 0xa2, 0xd8, 0x9e, 0x58, + 0x81, 0x03, 0x0b, 0xfd, 0x69, 0x5a, 0xc8, 0xe5, 0x69, 0xf9, 0x2b, 0x5e, 0x8d, 0x75, 0xf1, 0xc7, + 0xaa, 0xaf, 0x2b, 0x04, 0xfa, 0x8a, 0x7e, 0xee, 0xf6, 0xfc, 0x40, 0x2b, 0x18, 0xac, 0xf1, 0x78, + 0xbe, 0x6d, 0x49, 0x7d, 0xe0, 0xa4, 0x11, 0x84, 0x71, 0xad, 0xd7, 0xd1, 0x5d, 0x0b, 0x4d, 0x0f, + 0xf4, 0x3d, 0xcf, 0xa0, 0x83, 0xf1, 0x00, 0xc4, 0x13, 0x88, 0x81, 0xdb, 0xa4, 0x0a, 0x2d, 0x69, + 0x62, 0x65, 0xf8, 0xc2, 0xbb, 0x3e, 0x0b, 0x89, 0x95, 0x07, 0x88, 0x7a, 0xa8, 0x77, 0x9c, 0xfb, + 0xbe, 0x3b, 0x71, 0x34, 0x47, 0xf1, 0x23, 0x3c, 0x6c, 0x93, 0xc6, 0x7e, 0xda, 0x95, 0x36, 0x0b, + 0x0c, 0x10, 0x59, 0xcc, 0x23, 0x11, 0xae, 0xcc, 0xe5, 0x6b, 0x9c, 0x41, 0x8c, 0x6c, 0x8b, 0x8b, + 0xf9, 0x85, 0xd6, 0xbe, 0x09, 0x76, 0xdd, 0x1b, 0x41, 0x95, 0x25, 0x90, 0x0c, 0x3d, 0x69, 0x95, + 0xff, 0xec, 0xfb, 0x7f, 0x82, 0x52, 0x57, 0x01, 0x85, 0x1a, 0x3d, 0x91, 0xa3, 0x29, 0x7b, 0x0d, + 0x0e, 0x2b, 0xf8, 0x8f, 0x13, 0xf1, 0x55, 0x4b, 0xac, 0xdf, 0xc1, 0x31, 0xae, 0xf4, 0xde, 0x45, + 0x7d, 0xe0, 0xa4, 0x15, 0x84, 0x5d, 0xc5, 0x6e, 0xee, 0x69, 0x42, 0xdd, 0xf5, 0x05, 0x1d, 0x4c, + 0xa1, 0x86, 0x42, 0x20, 0xb2, 0x4c, 0x17, 0x55, 0xdc, 0xe1, 0x95, 0x56, 0x63, 0x71, 0x1d, 0xf8, + 0x29, 0x11, 0x55, 0x55, 0x5d, 0x76, 0xff, 0xf9, 0x0b, 0x49, 0xfc, 0x48, 0xc3, 0x6e, 0xf2, 0xf4, + 0x8d, 0x2e, 0x96, 0xef, 0x2d, 0xbb, 0xf9, 0x8c, 0xfb, 0x1f, 0x10, 0x3a, 0x15, 0x0c, 0xa2, 0xa6, + 0x96, 0x61, 0x39, 0x2b, 0xbd, 0x38, 0x66, 0xfe, 0x6d, 0x35, 0xc6, 0xe2, 0xb9, 0x7c, 0x7f, 0x88, + 0x63, 0x4a, 0xae, 0x58, 0xc5, 0x7c, 0x20, 0x0b, 0x89, 0xbb, 0x77, 0xbb, 0xf1, 0x22, 0x44, 0x9d, + 0xcb, 0xdf, 0x2b, 0x0d, 0x24, 0x14, 0xd4, 0x78, 0x8b, 0x2d, 0xdc, 0x4b, 0x98, 0x8a, 0x23, 0xf8, + 0x9f, 0x12, 0x20, 0x43, 0x6d, 0x6e, 0x1a, 0x01, 0xe1, 0x0f, 0xbf, 0x08, 0x1a, 0xee, 0x5c, 0xbb, + 0xb8, 0xa3, 0xb8, 0xaf, 0x82, 0x94, 0x3c, 0x76, 0x3b, 0xf4, 0x37, 0xa0, 0x83, 0xa0, 0x87, 0x4b, + 0x13, 0x05, 0x1c, 0xcd, 0xd5, 0x20, 0x3e, 0x1a, 0xbf, 0x0c, 0x89, 0x04, 0x04, 0x78, 0xac, 0x57, + 0x97, 0x4a, 0x5a, 0x3f, 0x2f, 0x0f, 0xdc, 0xbb, 0x74, 0xff, 0x08, 0x09, 0x05, 0x50, 0x06, 0x2d, + 0xfd, 0xae, 0x0f, 0x72, 0xcc, 0xed, 0x37, 0x66, 0x8b, 0x81, 0x10, 0x5f, 0x9e, 0x78, 0xdf, 0xd1, + 0xd6, 0xb4, 0xd8, 0x1d, 0xec, 0x2e, 0x56, 0x68, 0x35, 0x0f, 0x12, 0xef, 0xb9, 0xbe, 0x5c, 0x4c, + 0x16, 0x15, 0x5a, 0xdc, 0xd9, 0xe8, 0xcb, 0x4a, 0xf9, 0x88, 0xfa, 0xac, 0x4b, 0x9f, 0x1b, 0x2f, + 0x7a, 0x9e, 0x24, 0x13, 0x09, 0x3e, 0x35, 0xaa, 0xaa, 0x8e, 0xff, 0x12, 0x88, 0xff, 0x04, 0x25, + 0xb7, 0x77, 0x7f, 0x08, 0xd4, 0x40, 0x82, 0x94, 0xa4, 0x1b, 0xbf, 0x13, 0xf1, 0x02, 0x9e, 0x9c, + 0x56, 0x2b, 0x77, 0xf0, 0x98, 0xa1, 0x5b, 0xdc, 0xf8, 0x2b, 0xf8, 0x29, 0x16, 0x56, 0x73, 0xa4, + 0x7c, 0x57, 0xe0, 0xa7, 0x88, 0x0c, 0xc2, 0xbd, 0x0b, 0x95, 0xf4, 0x2d, 0x3a, 0x13, 0xd1, 0x19, + 0xc2, 0x22, 0x41, 0x11, 0xa7, 0xce, 0x97, 0xc4, 0x82, 0xb3, 0x19, 0x72, 0x1d, 0x01, 0xef, 0x69, + 0x56, 0xee, 0xf1, 0x7c, 0x65, 0x64, 0xce, 0xee, 0x58, 0xc5, 0x19, 0xf1, 0xf8, 0xfc, 0xfb, 0x88, + 0x08, 0x8c, 0xb4, 0x2f, 0xee, 0xf4, 0x8d, 0x95, 0x45, 0x31, 0x9c, 0xbc, 0x44, 0x5e, 0xd2, 0xaa, + 0xad, 0x71, 0x3f, 0x12, 0x11, 0x33, 0x8a, 0xc3, 0x2a, 0xd8, 0x09, 0xa9, 0x9f, 0x82, 0x4f, 0x85, + 0xa8, 0xb8, 0x40, 0x3f, 0x88, 0xdf, 0x58, 0x7c, 0x9b, 0xec, 0x0b, 0xfe, 0x0a, 0x09, 0x76, 0xae, + 0xd1, 0xb9, 0x67, 0xdf, 0x29, 0xf1, 0x75, 0xf3, 0x1d, 0x77, 0xe2, 0x4c, 0x55, 0x5f, 0x88, 0x04, + 0x9b, 0xdd, 0x1d, 0xf1, 0x21, 0x1b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbf, 0x84, 0xae, 0xf7, 0x73, + 0xe5, 0xf1, 0x10, 0x99, 0xde, 0xe4, 0x8e, 0x6d, 0xf8, 0x21, 0x23, 0xdd, 0xdf, 0xe6, 0x2a, 0xaa, + 0xae, 0x24, 0x4f, 0xc8, 0x30, 0x56, 0xef, 0x58, 0x44, 0x5d, 0x3a, 0x4c, 0xf1, 0x5b, 0xf0, 0xc9, + 0x47, 0xd4, 0x77, 0xd8, 0x63, 0xa3, 0x74, 0x44, 0x23, 0x08, 0xd5, 0x7a, 0xa4, 0x84, 0xee, 0x7c, + 0x2d, 0xf8, 0x2d, 0x10, 0xe0, 0x77, 0xd4, 0x5d, 0x9d, 0x27, 0xca, 0x0f, 0x84, 0x7a, 0xae, 0x2b, + 0x72, 0xe5, 0xdb, 0x58, 0x60, 0x10, 0xf1, 0x31, 0x95, 0x26, 0x27, 0x33, 0x5a, 0x66, 0xf5, 0x67, + 0xeb, 0x89, 0x08, 0x04, 0xc4, 0xbb, 0xbb, 0x89, 0xf1, 0x4d, 0x45, 0xf8, 0x40, 0x59, 0x96, 0x6c, + 0x69, 0xc5, 0x6a, 0xfc, 0x48, 0xc2, 0x28, 0xba, 0xa7, 0x07, 0x6d, 0xd9, 0x0a, 0xe6, 0xc6, 0xd3, + 0x3c, 0xf2, 0x4e, 0x38, 0x90, 0xa1, 0x4d, 0x65, 0xe5, 0xbd, 0x0a, 0xa8, 0x9a, 0x89, 0x97, 0xeb, + 0x17, 0xad, 0x5b, 0xe3, 0x89, 0xcd, 0x8a, 0xe7, 0xc6, 0xb6, 0x38, 0xbf, 0x5f, 0x08, 0x41, 0xd7, + 0xdc, 0x38, 0x31, 0xc7, 0xdd, 0xdd, 0xdd, 0xf1, 0x22, 0x4c, 0x35, 0xef, 0xc4, 0xf8, 0x44, 0x48, + 0xc9, 0x99, 0xce, 0xc6, 0xef, 0x2a, 0x99, 0x54, 0xde, 0xff, 0x08, 0x5c, 0xea, 0x2e, 0xf7, 0x7b, + 0xdf, 0x11, 0xf1, 0x2a, 0x8e, 0xf0, 0x88, 0x8e, 0x20, 0x22, 0x09, 0x34, 0xae, 0xfc, 0x48, 0x45, + 0x19, 0x1d, 0xe1, 0x90, 0xc8, 0x4b, 0xbb, 0x8d, 0x55, 0xeb, 0x89, 0x85, 0x0d, 0x1e, 0xee, 0x88, + 0xf1, 0xcf, 0x66, 0x0a, 0xab, 0xe7, 0x8a, 0xc5, 0x7d, 0xdc, 0x05, 0x20, 0xa7, 0x83, 0x00, 0x80, + 0x2a, 0x21, 0x6c, 0x56, 0x3b, 0xe3, 0xf1, 0xde, 0xa3, 0xe5, 0x1b, 0x69, 0x47, 0xe0, 0x82, 0x2c, + 0xe2, 0x3e, 0xce, 0xef, 0x7e, 0x23, 0x0f, 0x70, 0x8e, 0x5c, 0x7b, 0x9b, 0x15, 0x98, 0x5e, 0x4c, + 0x8b, 0xc1, 0x00, 0x29, 0x05, 0x1c, 0xb9, 0x55, 0xab, 0x1e, 0x24, 0x12, 0x6b, 0x57, 0xe2, 0x62, + 0xaa, 0xaa, 0xaa, 0x23, 0xd5, 0x66, 0x3c, 0x29, 0xad, 0x55, 0x57, 0x5d, 0x55, 0x57, 0x7e, 0x11, + 0x82, 0xa2, 0x8a, 0xef, 0x55, 0xe2, 0xf5, 0x7e, 0x20, 0x10, 0x84, 0x48, 0xef, 0x37, 0x58, 0xb9, + 0x3a, 0x97, 0xff, 0x08, 0xc5, 0x36, 0x67, 0xbb, 0xbe, 0xfe, 0x13, 0xcb, 0xed, 0x97, 0x9b, 0xb7, + 0xf1, 0x22, 0x75, 0x5c, 0xeb, 0xe2, 0x6c, 0xa9, 0x9f, 0xbd, 0xe2, 0x44, 0x8f, 0x2a, 0xef, 0x9f, + 0xef, 0x7c, 0x48, 0x80, 0x5b, 0x1a, 0x56, 0xfa, 0xe3, 0x77, 0x15, 0x8a, 0xd1, 0xde, 0x18, 0x82, + 0x3d, 0xde, 0x8e, 0xfc, 0x29, 0x77, 0x77, 0xa7, 0x4d, 0xdd, 0xc5, 0x67, 0xf0, 0x5e, 0xb8, 0x91, + 0x20, 0xbb, 0x8a, 0xea, 0xaa, 0xbc, 0x77, 0xe6, 0x3a, 0xaa, 0xae, 0x24, 0x49, 0x4c, 0xaa, 0xab, + 0xc4, 0xfc, 0xbd, 0xdf, 0x10, 0x20, 0x21, 0x39, 0x04, 0xe7, 0x0a, 0x63, 0x6f, 0x69, 0xdd, 0xdd, + 0xf8, 0x64, 0x29, 0x29, 0xac, 0x6b, 0x74, 0xee, 0x6b, 0xdf, 0x95, 0x24, 0x65, 0x8a, 0xf6, 0x4e, + 0xc6, 0xa4, 0xd8, 0x8e, 0xf1, 0x10, 0xa1, 0x98, 0xe3, 0x79, 0x54, 0x46, 0xb2, 0x15, 0x19, 0x7a, + 0x77, 0x2d, 0xd8, 0xd6, 0xd1, 0x8e, 0xdf, 0x88, 0x12, 0x38, 0x41, 0x6a, 0x9d, 0xc1, 0x21, 0xc7, + 0xd5, 0xb8, 0x9d, 0xf0, 0x80, 0x90, 0x56, 0x51, 0x3c, 0x36, 0x25, 0x13, 0x8a, 0xcf, 0x85, 0xbe, + 0x21, 0xe2, 0x26, 0x90, 0xec, 0x4c, 0x12, 0x16, 0x4d, 0x27, 0x2d, 0xe1, 0xf0, 0x5d, 0x2c, 0x2c, + 0x79, 0x65, 0xc5, 0x76, 0xbb, 0xe0, 0xa8, 0xae, 0x5c, 0x7a, 0x9f, 0x4c, 0x73, 0xdf, 0x7e, 0x26, + 0x24, 0x8e, 0xee, 0x5e, 0xfb, 0xfc, 0x79, 0xab, 0x55, 0x95, 0x89, 0xf2, 0x71, 0x76, 0x7e, 0x24, + 0x14, 0x8b, 0x64, 0xaa, 0xa2, 0x98, 0xb9, 0x32, 0x6f, 0x7a, 0x75, 0xc2, 0x01, 0x42, 0xd9, 0x8c, + 0xb4, 0x5a, 0x8b, 0xe5, 0xb1, 0x46, 0x2b, 0x15, 0x8a, 0xdb, 0x77, 0xef, 0x10, 0x0b, 0x05, 0x53, + 0x8a, 0xee, 0xe2, 0xb7, 0x12, 0xfd, 0xd5, 0xc1, 0x0d, 0xdb, 0xeb, 0xe0, 0xa8, 0x49, 0xfb, 0x89, + 0x60, 0xde, 0xfa, 0xd5, 0xdd, 0xbf, 0xf8, 0x81, 0x20, 0x92, 0xee, 0xee, 0xff, 0x04, 0xfb, 0xdd, + 0x5d, 0x53, 0x47, 0x70, 0xea, 0x38, 0x01, 0xf7, 0xe5, 0x6e, 0x8e, 0xe4, 0xee, 0x31, 0x24, 0x7f, + 0x72, 0xc5, 0xeb, 0x2e, 0x82, 0x18, 0xcf, 0x37, 0xfe, 0x20, 0x48, 0x2c, 0x10, 0xbb, 0xbb, 0xdb, + 0xea, 0xaf, 0xc4, 0x89, 0x04, 0x38, 0xad, 0xdf, 0xb8, 0x98, 0xba, 0xad, 0x56, 0xab, 0x89, 0x98, + 0x4a, 0xaa, 0xaf, 0x98, 0x52, 0xaa, 0xaf, 0x8c, 0x8b, 0x8e, 0xe4, 0x14, 0xd5, 0x1b, 0x71, 0xef, + 0xc8, 0xc5, 0xce, 0x63, 0x7f, 0x0a, 0x15, 0xef, 0x49, 0x23, 0xe3, 0xf1, 0x0b, 0x58, 0xcd, 0x54, + 0x71, 0x2c, 0x7b, 0x97, 0x0e, 0x71, 0xf8, 0x46, 0x38, 0xae, 0xf6, 0xee, 0xee, 0xee, 0xf6, 0xfc, + 0x48, 0x28, 0xa5, 0x29, 0x05, 0xf5, 0x21, 0x05, 0x1d, 0xe0, 0xa4, 0x1c, 0x82, 0xb3, 0x2d, 0xa6, + 0x8f, 0x63, 0xbd, 0xf6, 0x6d, 0x52, 0x7e, 0x0a, 0x41, 0x88, 0x2c, 0xa8, 0x4a, 0x73, 0x46, 0xbd, + 0x82, 0x01, 0x07, 0xde, 0x70, 0xc0, 0x51, 0xbd, 0x33, 0xf9, 0x47, 0x78, 0x30, 0x10, 0x34, 0x46, + 0xfc, 0xee, 0x3f, 0xe9, 0x1c, 0xf1, 0x59, 0x60, 0xe3, 0x75, 0x95, 0x41, 0x6e, 0x2b, 0x03, 0x95, + 0xa3, 0x9d, 0x55, 0x6c, 0xff, 0xc3, 0x65, 0x2f, 0x6c, 0xae, 0x53, 0x85, 0x80, 0x80, 0x91, 0xca, + 0x9d, 0x24, 0x58, 0x27, 0x45, 0xf9, 0xfa, 0x2f, 0x42, 0xbc, 0x38, 0x61, 0x58, 0xa3, 0x69, 0xad, + 0x6e, 0xaf, 0xf8, 0x40, 0x18, 0xf1, 0x22, 0x41, 0x31, 0xdd, 0xef, 0x7b, 0xd1, 0xdf, 0xb2, 0x33, + 0x75, 0x5e, 0x24, 0x84, 0xd5, 0x7c, 0x71, 0x6b, 0x6d, 0xee, 0xee, 0xf7, 0xc4, 0x42, 0x45, 0x77, + 0xb8, 0xbd, 0x78, 0x81, 0x02, 0xc9, 0xc5, 0x6e, 0x21, 0xc1, 0x59, 0xc2, 0xc7, 0x82, 0x6a, 0xae, + 0x5c, 0x96, 0xef, 0xf0, 0x45, 0x77, 0x77, 0x47, 0x7c, 0x23, 0xe2, 0x41, 0x1f, 0x36, 0x1b, 0x1f, + 0x89, 0x12, 0x62, 0xb8, 0xad, 0xc5, 0x1f, 0x01, 0x00, 0x30, 0xe2, 0x40, 0x1c, 0x3c, 0x01, 0xc1, + 0x2f, 0x1d, 0x78, 0x4a, 0xae, 0x1f, 0xbf, 0x2d, 0x69, 0x7e, 0x23, 0xa8, 0x5a, 0x89, 0xea, 0x78, + 0x72, 0x78, 0x79, 0x61, 0xf1, 0x20, 0xb8, 0xd7, 0xb7, 0x55, 0x55, 0xae, 0x27, 0xe2, 0x48, 0x75, + 0x55, 0x5f, 0x04, 0x5d, 0xb5, 0x7f, 0x11, 0xf1, 0xe4, 0x18, 0x32, 0x51, 0x5f, 0x6f, 0xcb, 0xb2, + 0xd1, 0xee, 0xfc, 0x48, 0x2c, 0x23, 0xdb, 0xdd, 0xed, 0x3b, 0x8a, 0xc5, 0x68, 0xef, 0x84, 0x46, + 0x16, 0xf7, 0x77, 0x7b, 0x2b, 0x4e, 0xd5, 0x24, 0xbc, 0x76, 0xc7, 0x72, 0x7f, 0xbb, 0xbd, 0xfe, + 0x14, 0x3a, 0xa3, 0x9f, 0x0b, 0x48, 0xaa, 0x74, 0xa2, 0x9c, 0x10, 0x15, 0x78, 0xd3, 0x63, 0x89, + 0x12, 0x84, 0x3f, 0x04, 0x01, 0x10, 0x4d, 0x17, 0x58, 0xb8, 0xbc, 0x53, 0x17, 0x67, 0x06, 0x02, + 0x06, 0x88, 0x26, 0x05, 0x50, 0x80, 0x0d, 0x0b, 0xbf, 0x60, 0x00, 0x08, 0xaa, 0xdc, 0xa0, 0xf8, + 0x76, 0xb3, 0x0a, 0xf5, 0xb3, 0x07, 0x4f, 0x97, 0x96, 0x90, 0x8e, 0x02, 0x6b, 0xbf, 0xcb, 0xd7, + 0xfc, 0x36, 0x52, 0xb0, 0xa3, 0x54, 0x5d, 0x81, 0x0e, 0x61, 0xc0, 0xe4, 0x87, 0xdf, 0x86, 0xe2, + 0x63, 0x66, 0x50, 0x17, 0xa6, 0x01, 0xc5, 0x28, 0x92, 0xf1, 0x72, 0x61, 0x78, 0x72, 0x4c, 0x99, + 0x22, 0x87, 0x1b, 0xdf, 0xeb, 0xee, 0x27, 0x6b, 0x8b, 0x88, 0x61, 0x1f, 0xe2, 0x04, 0x82, 0x6d, + 0xdd, 0xa7, 0xbd, 0xfe, 0x8a, 0x8e, 0x3f, 0x54, 0x77, 0xe8, 0xcf, 0xf2, 0xdd, 0xfe, 0x24, 0xa5, + 0xb6, 0xeb, 0x86, 0x03, 0x21, 0x19, 0x79, 0x60, 0x03, 0x36, 0x96, 0x00, 0xd0, 0x35, 0x5d, 0x8a, + 0x34, 0xc5, 0x78, 0x20, 0x85, 0x0a, 0x5f, 0xb2, 0xf6, 0xc1, 0xb5, 0x44, 0xb9, 0x19, 0xaa, 0x0b, + 0xda, 0x97, 0x96, 0xb2, 0xf7, 0xf7, 0x74, 0x62, 0xbc, 0x29, 0xb9, 0x6d, 0x77, 0x71, 0xf5, 0x39, + 0xe7, 0xbc, 0xe7, 0x9c, 0x3c, 0xb1, 0x9c, 0xf2, 0xc7, 0x91, 0xde, 0x24, 0x48, 0x25, 0x30, 0xa3, + 0x15, 0x8a, 0xcf, 0xdd, 0xfa, 0x3b, 0xe2, 0x42, 0x25, 0x54, 0xd3, 0x7b, 0xdd, 0xc5, 0x06, 0xe2, + 0x8f, 0x80, 0x80, 0x0a, 0x09, 0x07, 0x40, 0x7c, 0x2e, 0x3e, 0x1d, 0x01, 0xf2, 0xd9, 0xe0, 0x38, + 0x58, 0x03, 0x2d, 0x8a, 0x0c, 0xf0, 0x07, 0xbf, 0x0a, 0x20, 0x6a, 0x7a, 0xcc, 0x18, 0x25, 0x16, + 0x2a, 0x32, 0x88, 0x94, 0x65, 0x0e, 0xe1, 0x75, 0x03, 0x48, 0x1f, 0x59, 0xf3, 0x43, 0x34, 0x3f, + 0x8f, 0x5c, 0x84, 0xba, 0xe4, 0x24, 0x6a, 0xb1, 0x02, 0x04, 0x88, 0x15, 0xde, 0xef, 0x7f, 0x45, + 0xea, 0xc4, 0xab, 0xf8, 0x82, 0x0a, 0xbd, 0xf1, 0x22, 0x42, 0x82, 0x55, 0x33, 0x51, 0xbd, 0xf6, + 0x7e, 0xdb, 0x7b, 0x67, 0x3d, 0xfc, 0xb7, 0x6f, 0x1f, 0x0f, 0x32, 0x80, 0x01, 0xd6, 0x9a, 0x83, + 0xca, 0x3c, 0x37, 0xf6, 0x72, 0x50, 0xe6, 0x94, 0xeb, 0x6c, 0xfd, 0xfc, 0xf6, 0x8d, 0xa6, 0xfb, + 0xc5, 0x72, 0x3a, 0xfb, 0xdf, 0xe3, 0x8c, 0xfb, 0xa3, 0x10, 0xe6, 0x28, 0xef, 0xe1, 0x00, 0x81, + 0xec, 0x9f, 0x62, 0x73, 0xe1, 0x6d, 0x1c, 0xbb, 0xc4, 0xc1, 0x66, 0xaa, 0xae, 0xee, 0xea, 0xaa, + 0xa8, 0x8e, 0xb8, 0x91, 0x7a, 0xaa, 0xaa, 0xaa, 0xe0, 0xc4, 0x08, 0x3c, 0x30, 0x11, 0x20, 0xa5, + 0x38, 0xe5, 0x8f, 0x0c, 0x04, 0x46, 0x92, 0x30, 0x75, 0xf4, 0xc7, 0x5f, 0x0b, 0x1a, 0x1c, 0xf2, + 0xcf, 0x6f, 0x9b, 0x89, 0x0f, 0x43, 0x2c, 0xe3, 0x1b, 0x45, 0x37, 0x7f, 0x0c, 0xf3, 0x1c, 0x99, + 0xa5, 0x89, 0x8d, 0x21, 0x78, 0x3b, 0x74, 0xeb, 0x8d, 0x17, 0x12, 0x6d, 0xcd, 0xcb, 0xad, 0xed, + 0xea, 0xf0, 0x2d, 0x0f, 0x0b, 0xe2, 0xb6, 0x05, 0x4d, 0x89, 0xd5, 0x92, 0x9d, 0x3f, 0x10, 0x19, + 0x0a, 0x14, 0x4e, 0x2e, 0x48, 0xde, 0x73, 0x83, 0x29, 0xb2, 0x1c, 0xc9, 0x9a, 0xec, 0x2f, 0x2c, + 0x31, 0x7d, 0xb9, 0xba, 0x7e, 0x22, 0xe7, 0xeb, 0x5f, 0x89, 0x29, 0x5e, 0xfe, 0x27, 0xc4, 0x8a, + 0x25, 0xaa, 0xad, 0x55, 0x44, 0xcd, 0x77, 0xf0, 0xc8, 0x21, 0x35, 0xdd, 0xdf, 0x04, 0x15, 0xae, + 0x24, 0x22, 0x2f, 0xbb, 0xdd, 0xdf, 0x08, 0x88, 0x0a, 0x49, 0x1b, 0xc7, 0x4c, 0xdc, 0xc9, 0x6e, + 0x83, 0x77, 0x6e, 0x2b, 0x73, 0xe5, 0xd1, 0xde, 0x0e, 0x01, 0x08, 0xc3, 0xb6, 0x5f, 0x2f, 0xde, + 0xaf, 0x1b, 0x8a, 0xe2, 0xf1, 0x78, 0x69, 0xc0, 0x9c, 0xa6, 0x64, 0x86, 0xf7, 0xff, 0xaa, 0xfa, + 0x6f, 0x11, 0xc4, 0x89, 0x29, 0x2d, 0xdb, 0xc4, 0xc1, 0x15, 0x55, 0x6f, 0xe2, 0x5e, 0xee, 0xfc, + 0x41, 0x0c, 0xb5, 0xf8, 0x2d, 0x2d, 0xdd, 0xdd, 0xdd, 0xdf, 0x84, 0x42, 0x23, 0x0b, 0xab, 0xbc, + 0xe9, 0x23, 0xa7, 0x07, 0xc1, 0xa2, 0x03, 0x96, 0xc4, 0x26, 0x22, 0x8c, 0xe1, 0xf8, 0x80, 0x80, + 0x52, 0x76, 0x0f, 0x7b, 0x4f, 0xe2, 0x5e, 0xb4, 0x44, 0x1c, 0x2c, 0x16, 0xcf, 0xf2, 0xf5, 0x4a, + 0xce, 0x6b, 0x78, 0x8f, 0x18, 0x6e, 0x85, 0xb4, 0x4e, 0xa1, 0x77, 0x01, 0x97, 0x39, 0x41, 0x8e, + 0x17, 0xc2, 0x76, 0xe3, 0x5e, 0xf6, 0x23, 0x18, 0xce, 0x97, 0x6f, 0x5b, 0xa3, 0xd0, 0x3f, 0xff, + 0xbc, 0x22, 0x11, 0x9f, 0x29, 0x93, 0x1d, 0xdc, 0x56, 0xf1, 0xcd, 0x7c, 0x41, 0x6f, 0xbe, 0x24, + 0x48, 0x25, 0xee, 0x5c, 0x55, 0x95, 0x47, 0x7c, 0x41, 0x75, 0x55, 0xc4, 0x86, 0x5d, 0xdf, 0xe1, + 0x12, 0x0a, 0x48, 0x4f, 0x21, 0x5a, 0xe1, 0x00, 0xc8, 0xc2, 0x83, 0xb6, 0x08, 0x01, 0xe5, 0x81, + 0xad, 0x50, 0x77, 0xe4, 0xe7, 0xbd, 0x9c, 0x47, 0xc8, 0x92, 0x90, 0xfc, 0x2e, 0x37, 0x6d, 0x8c, + 0xe8, 0xad, 0x19, 0xc3, 0x86, 0x70, 0xa2, 0xb1, 0x92, 0x00, 0xd4, 0x96, 0xb1, 0x38, 0x7e, 0x20, + 0x10, 0x8e, 0x8e, 0xa9, 0x58, 0x33, 0x11, 0x92, 0xb9, 0x2a, 0xb3, 0x43, 0xfd, 0xce, 0x61, 0x8e, + 0x27, 0xfc, 0x4a, 0x2b, 0xf0, 0xc8, 0x60, 0x17, 0x15, 0x52, 0x62, 0xdd, 0xdd, 0x1d, 0xf1, 0x02, + 0xab, 0xad, 0x57, 0xc4, 0x1b, 0xb4, 0xbe, 0x08, 0x89, 0x5a, 0xbf, 0xca, 0x45, 0x5d, 0x43, 0x21, + 0x80, 0x54, 0x34, 0x57, 0x12, 0xfb, 0xdf, 0x4e, 0x9b, 0xf1, 0x30, 0xa4, 0x56, 0xee, 0xe2, 0xb1, + 0x58, 0xac, 0x56, 0xee, 0xee, 0xee, 0xee, 0x3e, 0xe2, 0x20, 0xa8, 0x82, 0xb7, 0xbb, 0xc5, 0x6e, + 0xe5, 0xc7, 0x6d, 0xd1, 0xc7, 0xc3, 0x00, 0x96, 0x2b, 0x15, 0xbb, 0xf5, 0x5e, 0xf1, 0x20, 0x86, + 0xf7, 0x76, 0x78, 0x44, 0x27, 0x7b, 0x55, 0x55, 0x5f, 0x36, 0x4e, 0xb3, 0xc4, 0x98, 0x9a, 0xaf, + 0x97, 0x7b, 0xf1, 0x1e, 0x24, 0x12, 0x94, 0x47, 0xa9, 0x33, 0xbb, 0xbe, 0x47, 0x7c, 0x40, 0xc9, + 0xf3, 0xed, 0xac, 0xb8, 0xe9, 0x5c, 0x57, 0xbb, 0xe2, 0x04, 0x05, 0x36, 0xef, 0xa5, 0x8a, 0xcb, + 0x18, 0xac, 0x51, 0xb2, 0x97, 0x62, 0xb7, 0x9f, 0x2b, 0x0a, 0x4a, 0x01, 0x98, 0x16, 0xc9, 0x11, + 0x30, 0x1f, 0x66, 0xf2, 0xed, 0xd9, 0x51, 0x76, 0x5d, 0x9f, 0x5f, 0xaf, 0xd7, 0xea, 0xd9, 0x6b, + 0x65, 0xbf, 0x4a, 0xad, 0x52, 0x8d, 0x19, 0xe4, 0x86, 0x54, 0x00, 0xb9, 0xcf, 0xe5, 0x6d, 0xe1, + 0x59, 0x3f, 0x87, 0xea, 0xa7, 0x85, 0x95, 0x89, 0xcb, 0xad, 0x66, 0xea, 0x55, 0xd3, 0xfd, 0x4a, + 0x2a, 0xc4, 0x93, 0xfd, 0xb8, 0xca, 0x37, 0x4a, 0xcc, 0xf1, 0x11, 0xc4, 0x2d, 0xb9, 0x6d, 0xe9, + 0x3b, 0x9e, 0xe5, 0x96, 0xc4, 0xbf, 0x10, 0x24, 0x9a, 0xd7, 0x89, 0xe2, 0x04, 0xf1, 0x16, 0x5d, + 0x57, 0x10, 0x24, 0x15, 0x6a, 0xb2, 0x71, 0xd4, 0x0a, 0xdb, 0x56, 0x08, 0x0a, 0xb3, 0xa3, 0xbf, + 0x04, 0xe3, 0xa2, 0x8d, 0xa1, 0x00, 0xb0, 0xe4, 0x80, 0x35, 0x3a, 0x20, 0x14, 0x06, 0xa0, 0xf8, + 0x58, 0xa6, 0xca, 0x1f, 0x64, 0x10, 0x61, 0x57, 0x1f, 0x1b, 0x00, 0x55, 0x81, 0xb4, 0x37, 0x48, + 0x20, 0x2c, 0x52, 0x92, 0xf0, 0x98, 0x20, 0x66, 0xdf, 0x85, 0x3a, 0x2b, 0xd7, 0x04, 0x86, 0x77, + 0x9e, 0x0f, 0xc4, 0x84, 0x41, 0x49, 0x9d, 0xb1, 0x5b, 0x69, 0xbf, 0xee, 0xca, 0xd6, 0xbe, 0xf6, + 0xff, 0x08, 0x82, 0xc1, 0x2e, 0xf7, 0x55, 0x5b, 0xe3, 0x89, 0x97, 0xe2, 0x60, 0xa6, 0x2b, 0x71, + 0x58, 0xae, 0xf7, 0xbb, 0x59, 0x67, 0x7f, 0x12, 0x0b, 0x0f, 0x5a, 0xec, 0xdd, 0x57, 0x2d, 0xc4, + 0x89, 0xe2, 0x68, 0x88, 0xef, 0x13, 0xf0, 0x88, 0xf2, 0x5e, 0xee, 0xee, 0xef, 0xbe, 0x22, 0xce, + 0xee, 0xfc, 0x48, 0x90, 0x8d, 0xde, 0xee, 0xee, 0xef, 0x76, 0xd7, 0x77, 0x77, 0x7e, 0x27, 0xc4, + 0xd4, 0x4c, 0x45, 0xbb, 0xdd, 0xfe, 0x20, 0xa4, 0xdd, 0xf8, 0x91, 0xe7, 0x6a, 0xb8, 0xe7, 0xb6, + 0xe9, 0xbf, 0xc5, 0x71, 0x5b, 0xbb, 0xf8, 0x88, 0xe9, 0xd8, 0x2d, 0xd5, 0x15, 0xba, 0x49, 0x5d, + 0xfc, 0x48, 0x25, 0x2c, 0x1b, 0x6e, 0xef, 0x9f, 0xbd, 0x71, 0x22, 0x41, 0x51, 0x1b, 0xee, 0xc5, + 0x65, 0xbb, 0x15, 0xbe, 0xee, 0x8e, 0xf1, 0x02, 0x02, 0x9b, 0xb1, 0x58, 0x87, 0x0b, 0x65, 0xb2, + 0xdb, 0xbd, 0xd4, 0xf1, 0xf4, 0xd1, 0xdf, 0x9b, 0x59, 0xbf, 0x8a, 0xa8, 0xba, 0xaa, 0xaa, 0xaf, + 0x10, 0x33, 0x36, 0x55, 0x56, 0xab, 0x55, 0x55, 0xfc, 0x45, 0x55, 0x55, 0x55, 0x57, 0x12, 0x19, + 0xf8, 0x27, 0x2a, 0x5d, 0xf5, 0x5e, 0xe2, 0x42, 0x20, 0x8c, 0x55, 0xd6, 0x8e, 0xf0, 0x80, 0x64, + 0x69, 0x16, 0x96, 0x13, 0xce, 0x47, 0xb0, 0x0d, 0xea, 0x3b, 0xf3, 0xbf, 0xaa, 0x5e, 0xcf, 0x44, + 0xd8, 0xe9, 0x65, 0xdd, 0xbf, 0x0b, 0x61, 0x11, 0x84, 0x54, 0xde, 0x2b, 0x34, 0x98, 0xcf, 0xc6, + 0x48, 0x0a, 0xbb, 0xe6, 0x65, 0x7a, 0xb5, 0x38, 0x80, 0xc8, 0x21, 0x39, 0x19, 0xf5, 0xab, 0x21, + 0x84, 0xec, 0xb6, 0x9f, 0x2f, 0xbb, 0xdd, 0xf8, 0x94, 0x57, 0xf1, 0x00, 0xb8, 0x45, 0xef, 0x8d, + 0x99, 0x29, 0x57, 0xe2, 0x44, 0x21, 0xa8, 0xef, 0x89, 0x54, 0x76, 0xba, 0xf7, 0xc1, 0x14, 0xcc, + 0x4d, 0x7f, 0xc4, 0x09, 0x29, 0x95, 0x55, 0x71, 0x32, 0xd7, 0x5e, 0x20, 0x13, 0xe9, 0xd3, 0xd5, + 0x7b, 0x89, 0x12, 0x08, 0xef, 0x77, 0x7e, 0x26, 0x0b, 0xaf, 0x7a, 0xaa, 0xa8, 0xed, 0xc4, 0x88, + 0x04, 0x65, 0x17, 0x55, 0x5e, 0xfa, 0xf7, 0x11, 0x44, 0xef, 0x84, 0x0f, 0xaa, 0xad, 0x6f, 0x7f, + 0x12, 0x0b, 0xb5, 0x55, 0x77, 0x77, 0xaf, 0x85, 0x25, 0xc4, 0x9c, 0x56, 0x7c, 0x12, 0xe1, 0xef, + 0x2d, 0x8a, 0xdc, 0x56, 0xf6, 0xee, 0xf4, 0x77, 0xe0, 0xa7, 0x6f, 0xb7, 0xa9, 0xe2, 0xf6, 0xe3, + 0xef, 0x82, 0x32, 0xaa, 0xd5, 0x1d, 0xe2, 0x21, 0x3b, 0x9f, 0x3d, 0x34, 0xf0, 0x88, 0x92, 0x45, + 0x65, 0xc7, 0xbc, 0x4c, 0x11, 0x11, 0xf7, 0xa3, 0xbf, 0x09, 0x16, 0xb5, 0x5a, 0xaf, 0x8c, 0x22, + 0xa8, 0xba, 0xad, 0x55, 0x55, 0x55, 0xee, 0xdf, 0xba, 0xaa, 0xae, 0x11, 0x12, 0x33, 0xab, 0x4b, + 0x33, 0x09, 0xad, 0x55, 0xd9, 0xbb, 0xf8, 0x46, 0xaa, 0xaa, 0x2b, 0x8a, 0xdb, 0x55, 0x52, 0x66, + 0x22, 0x30, 0xe2, 0x74, 0x14, 0xe5, 0x29, 0x37, 0x55, 0x95, 0xd5, 0x78, 0x81, 0xa3, 0xa2, 0xea, + 0xa8, 0x74, 0xc3, 0xd5, 0x31, 0x3c, 0x13, 0xc5, 0x16, 0x12, 0xe2, 0xf9, 0x07, 0x63, 0xcd, 0x3b, + 0xfe, 0x20, 0x48, 0x26, 0xb8, 0xac, 0xab, 0xd2, 0xf3, 0xe7, 0x06, 0x2a, 0x52, 0xc3, 0x9c, 0x14, + 0xb4, 0x29, 0xcd, 0xa6, 0x98, 0x3c, 0xfe, 0x10, 0x0c, 0x82, 0x92, 0x26, 0x2b, 0x11, 0xd7, 0xf6, + 0x96, 0x56, 0xf2, 0x7e, 0x4c, 0xc0, 0x77, 0x1c, 0x40, 0x94, 0x5c, 0xbc, 0x47, 0xc1, 0x21, 0xde, + 0xee, 0x8e, 0xf8, 0x80, 0xa0, 0x8b, 0xdd, 0x52, 0x93, 0xd5, 0xdc, 0x4a, 0xa4, 0xbb, 0xc3, 0x8a, + 0xdc, 0x57, 0x5d, 0x93, 0xbc, 0x36, 0x4d, 0xa7, 0x7c, 0x49, 0x5f, 0xfb, 0xf9, 0xa8, 0xb4, 0x54, + 0xa8, 0x98, 0x25, 0x07, 0x2b, 0xf8, 0x26, 0x17, 0x54, 0xf4, 0xae, 0x97, 0x89, 0x10, 0xc8, 0xf7, + 0x7f, 0x5e, 0x38, 0xfd, 0x51, 0xdf, 0x92, 0xaa, 0xab, 0xc4, 0x02, 0x2b, 0xbd, 0xf8, 0xef, 0x89, + 0x58, 0xbe, 0x08, 0x8b, 0xaa, 0xc5, 0xe2, 0x38, 0x8b, 0x33, 0xbb, 0x5e, 0x20, 0x14, 0x56, 0x4e, + 0xf4, 0xdd, 0x34, 0x77, 0x89, 0x97, 0x72, 0xfb, 0xe2, 0x46, 0x6f, 0x7d, 0xdd, 0x77, 0x77, 0x77, + 0x85, 0x99, 0x40, 0x35, 0x50, 0x61, 0x69, 0x9d, 0x45, 0x6a, 0x23, 0x4b, 0xa4, 0x2b, 0x3a, 0xda, + 0xd4, 0x9a, 0xff, 0xc2, 0x90, 0xa8, 0x28, 0x1f, 0xd3, 0x8f, 0x2b, 0xa6, 0x25, 0xa1, 0x22, 0xa7, + 0x24, 0x15, 0xa9, 0x86, 0xb2, 0xa5, 0x5a, 0xa1, 0xac, 0x16, 0xda, 0xc5, 0xa3, 0xb5, 0xcd, 0x55, + 0x55, 0xc2, 0x21, 0x13, 0x6b, 0x5e, 0x26, 0xb8, 0x4a, 0xab, 0x56, 0xf5, 0xf6, 0x45, 0xaf, 0x11, + 0x64, 0xaa, 0xfc, 0x4d, 0x75, 0x8b, 0xa8, 0xbe, 0x11, 0x13, 0xc4, 0x84, 0x46, 0x6a, 0x5c, 0xd4, + 0x5d, 0x55, 0xdd, 0x75, 0xae, 0x24, 0x10, 0x85, 0x0b, 0x25, 0xea, 0x42, 0x09, 0x31, 0x98, 0x74, + 0x82, 0x7f, 0x34, 0x89, 0x82, 0xfc, 0xac, 0xb8, 0x42, 0x34, 0xc7, 0x81, 0x60, 0x99, 0xc1, 0x61, + 0x9c, 0xfb, 0x15, 0xd8, 0xac, 0x69, 0x45, 0x4e, 0x91, 0xa4, 0xac, 0x1d, 0x3e, 0xde, 0x84, 0x01, + 0x50, 0xb6, 0x2b, 0xf7, 0xa9, 0x7f, 0x84, 0xf9, 0x8a, 0xf7, 0x7f, 0x05, 0x82, 0x09, 0xbb, 0xbd, + 0x3b, 0xb8, 0xae, 0x2b, 0x2d, 0xe2, 0x41, 0x49, 0xc9, 0x39, 0xbf, 0x1f, 0xe7, 0x34, 0x7c, 0xb9, + 0x7a, 0xee, 0xee, 0xef, 0xc4, 0x71, 0x02, 0x41, 0x60, 0x8b, 0x58, 0x17, 0x6f, 0xa4, 0xda, 0xc4, + 0x0f, 0x4c, 0xb1, 0xf7, 0x11, 0x0a, 0x0d, 0x0b, 0xc2, 0x13, 0xc5, 0x75, 0xa5, 0x43, 0x6d, 0x9d, + 0xeb, 0x27, 0xe3, 0x97, 0x32, 0xff, 0x5f, 0x13, 0xbb, 0xbd, 0xa6, 0xfc, 0x4f, 0x89, 0xf1, 0x35, + 0xaf, 0x13, 0xf5, 0xef, 0x89, 0xd3, 0xa6, 0xef, 0xfa, 0xd7, 0xc1, 0x11, 0x55, 0x55, 0x78, 0xef, + 0x13, 0x44, 0xe3, 0xbe, 0x24, 0x59, 0x5d, 0xdd, 0xca, 0xc1, 0x58, 0x6b, 0x0d, 0x63, 0x89, 0x08, + 0xf7, 0x71, 0x58, 0xac, 0xb6, 0x2b, 0x77, 0x77, 0xe1, 0x11, 0xd2, 0xf5, 0x66, 0x3a, 0xe2, 0xd2, + 0x91, 0x9a, 0x1e, 0x24, 0x10, 0x84, 0x39, 0x19, 0x3f, 0xf7, 0x7b, 0xbf, 0x12, 0x11, 0x05, 0x7b, + 0xb7, 0x74, 0x34, 0x34, 0x34, 0x37, 0x77, 0x74, 0x76, 0xa2, 0x44, 0x82, 0x3a, 0xd5, 0x51, 0xde, + 0x26, 0x23, 0x55, 0x51, 0x71, 0x72, 0x63, 0x33, 0xdc, 0x5c, 0x9e, 0x63, 0xf4, 0x41, 0xdb, 0xc4, + 0xf1, 0x1f, 0x96, 0xaa, 0xbe, 0x20, 0x51, 0xab, 0x55, 0x55, 0x5e, 0x20, 0x20, 0x25, 0xf7, 0xd5, + 0x5a, 0xa5, 0xf0, 0x55, 0x55, 0xc4, 0xf1, 0xd8, 0x4c, 0x66, 0x6a, 0x2e, 0xfe, 0x20, 0xc4, 0x25, + 0x15, 0x57, 0x82, 0x90, 0x4f, 0x51, 0x1b, 0x5e, 0x8a, 0x2a, 0xfd, 0x78, 0x31, 0x0a, 0x45, 0xf3, + 0x7d, 0x54, 0x56, 0x5e, 0x3b, 0x75, 0x8e, 0x17, 0x14, 0x32, 0xf1, 0x4f, 0xa7, 0x80, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x9a, 0x19, 0x0c, 0xb0, 0x4a, 0x0d, 0xe0, 0x41, 0x41, 0x1e, 0x83, 0x50, 0xf2, + 0x14, 0x00, 0x21, 0xef, 0xea, 0x66, 0xbb, 0xdf, 0xff, 0xc5, 0x5f, 0x2b, 0xeb, 0xde, 0x19, 0x94, + 0x37, 0xef, 0xfc, 0x1b, 0x5c, 0x52, 0xfb, 0xf2, 0x09, 0x60, 0xd6, 0x18, 0x02, 0x08, 0x50, 0x52, + 0xaa, 0xaa, 0x91, 0x95, 0x95, 0x55, 0x59, 0x32, 0x2b, 0xf7, 0x0c, 0x03, 0x90, 0x81, 0xa4, 0xb3, + 0x89, 0x3d, 0x4f, 0x39, 0x14, 0xc9, 0xe5, 0xe9, 0xe0, 0xc3, 0x06, 0x81, 0xd4, 0x13, 0x08, 0xd8, + 0x1e, 0xb1, 0xde, 0xda, 0x6f, 0xfe, 0x00, 0x47, 0x75, 0xdd, 0xef, 0x89, 0x07, 0x28, 0x29, 0xdc, + 0x40, 0x31, 0x89, 0xe8, 0x2e, 0x3e, 0xf0, 0xca, 0xb1, 0xf0, 0x47, 0x6e, 0x27, 0x9e, 0x82, 0xac, + 0x40, 0x50, 0x28, 0xa9, 0xd5, 0xb8, 0xf6, 0x93, 0x17, 0x51, 0x7d, 0x42, 0x83, 0x56, 0x3b, 0x20, + 0x70, 0xc8, 0xcd, 0x49, 0xf5, 0xd4, 0xe0, 0xf8, 0x80, 0x0f, 0x27, 0x52, 0x7d, 0x70, 0x51, 0x9b, + 0x82, 0x41, 0xfa, 0x43, 0x79, 0x3f, 0x12, 0x24, 0x16, 0x0e, 0xcb, 0x82, 0x1a, 0x47, 0x5f, 0x71, + 0x33, 0x91, 0xc7, 0xa7, 0x99, 0xee, 0x7d, 0xf8, 0x20, 0x0c, 0x84, 0x7b, 0x63, 0x5f, 0x23, 0x37, + 0xdb, 0x91, 0x5e, 0x10, 0x12, 0x3f, 0x97, 0xae, 0x29, 0x89, 0x0e, 0x44, 0x1c, 0x37, 0x98, 0x79, + 0x84, 0x40, 0x06, 0x46, 0xbe, 0x96, 0xf5, 0x83, 0xfe, 0xdf, 0xa3, 0x1c, 0x9f, 0xf5, 0xfe, 0xe0, + 0xaa, 0x20, 0x30, 0x0a, 0x87, 0x4d, 0xe6, 0xea, 0xea, 0xe3, 0x19, 0xa9, 0x32, 0x40, 0x68, 0xe4, + 0xed, 0x45, 0x8d, 0xfc, 0x71, 0x17, 0x99, 0xb9, 0x66, 0xa2, 0x4f, 0xad, 0x5f, 0xfe, 0x24, 0x48, + 0xf0, 0xce, 0xb5, 0x95, 0xcb, 0xcc, 0x14, 0xea, 0xb2, 0xc4, 0x89, 0x31, 0xa8, 0x9b, 0x4f, 0x11, + 0x09, 0x0a, 0xb6, 0x9a, 0xaa, 0xaf, 0x88, 0x29, 0xee, 0x65, 0xfd, 0x52, 0xc2, 0x21, 0x0e, 0x10, + 0x08, 0x89, 0xcb, 0x83, 0x99, 0x20, 0x9e, 0x90, 0xa4, 0x4b, 0x98, 0x2b, 0x88, 0x05, 0x20, 0xb2, + 0xb9, 0x3d, 0x6b, 0x57, 0x4c, 0xbe, 0x5c, 0x48, 0x44, 0x64, 0x55, 0x9b, 0x5b, 0x67, 0x7d, 0x99, + 0x80, 0x6b, 0xe0, 0xef, 0x6f, 0x73, 0x38, 0x2f, 0x93, 0x1d, 0x72, 0x63, 0x10, 0x26, 0x4e, 0x4b, + 0xed, 0x78, 0xe2, 0x16, 0xc7, 0xbb, 0xe5, 0x7d, 0xdf, 0x13, 0x43, 0x5f, 0xc4, 0x0a, 0x26, 0xab, + 0x59, 0x73, 0xc8, 0x22, 0xeb, 0x05, 0x5d, 0x05, 0xde, 0xa1, 0x00, 0x88, 0xa0, 0x85, 0xd0, 0xca, + 0x4d, 0xf7, 0x5c, 0x48, 0x29, 0x29, 0x1e, 0xfc, 0x40, 0x92, 0xef, 0x15, 0xbc, 0x20, 0x09, 0x05, + 0xcb, 0x28, 0x74, 0xd3, 0x57, 0xca, 0x31, 0xde, 0xfc, 0x40, 0x2a, 0x08, 0x9f, 0xf5, 0x17, 0xad, + 0x57, 0xec, 0x72, 0x8f, 0xa1, 0xf7, 0x84, 0x42, 0x21, 0x0a, 0xae, 0xb5, 0xc4, 0x9c, 0xf1, 0x00, + 0x94, 0x26, 0x7c, 0x64, 0x73, 0x9a, 0xae, 0xd0, 0x59, 0x10, 0x24, 0x28, 0x21, 0x55, 0x55, 0x6a, + 0x80, 0x95, 0x55, 0x56, 0xa4, 0x48, 0x31, 0xbc, 0x10, 0x85, 0x0d, 0x0b, 0xac, 0x6e, 0x2b, 0x22, + 0xfa, 0xbc, 0xbf, 0xca, 0xa8, 0xba, 0xb1, 0xe0, 0xa4, 0x66, 0x7e, 0x9d, 0x6b, 0x5d, 0xb7, 0x3f, + 0x5c, 0xfd, 0x04, 0xdb, 0xe6, 0x37, 0x1b, 0xfa, 0xe2, 0x44, 0x1f, 0xd8, 0xef, 0x7f, 0x9b, 0xc3, + 0x83, 0xd8, 0x44, 0x22, 0x12, 0x36, 0xab, 0x5d, 0x71, 0x02, 0x47, 0x15, 0x41, 0x8a, 0xa3, 0x92, + 0x35, 0x8f, 0x2f, 0x98, 0x32, 0x07, 0x91, 0x6b, 0x1a, 0x2c, 0xfb, 0x05, 0x98, 0x94, 0x2d, 0xfc, + 0x10, 0x23, 0x37, 0x86, 0x46, 0x08, 0xaa, 0xa8, 0xba, 0x6b, 0x5d, 0xeb, 0x5e, 0x08, 0x04, 0x94, + 0x1e, 0x7c, 0x74, 0xf8, 0x45, 0xd4, 0xb4, 0xf9, 0x28, 0x34, 0x83, 0x38, 0x58, 0x7f, 0xe2, 0x3e, + 0x0a, 0x05, 0xaa, 0xaa, 0x9b, 0xcf, 0x3c, 0x49, 0xc7, 0xf1, 0x24, 0x1d, 0x15, 0xbf, 0x89, 0x31, + 0xef, 0x06, 0xfa, 0x70, 0x8f, 0xc4, 0xc3, 0xa2, 0xc9, 0x0c, 0xdb, 0xf4, 0xd4, 0x88, 0x39, 0x27, + 0xe2, 0x04, 0x41, 0x60, 0x75, 0x0b, 0x01, 0x37, 0xd9, 0xd4, 0xf7, 0xf7, 0x7b, 0x29, 0xfd, 0x81, + 0x8e, 0xa9, 0xc5, 0xeb, 0xc2, 0x7b, 0x5a, 0xfe, 0x24, 0x08, 0x23, 0x06, 0x2a, 0xaa, 0xa8, 0xd2, + 0x62, 0x8c, 0xa6, 0x6d, 0xc1, 0x03, 0x8a, 0x62, 0xad, 0x60, 0xe1, 0xf8, 0x59, 0x79, 0x89, 0x06, + 0x01, 0x49, 0x6b, 0x55, 0xf9, 0x97, 0xaa, 0x62, 0xe6, 0x09, 0xb1, 0x2a, 0x1e, 0x70, 0x72, 0x78, + 0x1e, 0x62, 0x52, 0xa8, 0xb2, 0x2e, 0xc9, 0x80, 0x00, 0x87, 0x88, 0x83, 0x04, 0x8d, 0xee, 0x20, + 0x48, 0x2b, 0x9c, 0x2c, 0x64, 0x80, 0xd1, 0x0a, 0x98, 0xae, 0xac, 0x9c, 0xc5, 0xa9, 0x20, 0x0e, + 0x83, 0x90, 0x3c, 0x03, 0x2c, 0xf8, 0x70, 0x15, 0xc1, 0xc7, 0xd7, 0x38, 0x80, 0x62, 0x2e, 0x5b, + 0x71, 0xdf, 0x2a, 0x2e, 0x17, 0x0f, 0x70, 0x75, 0xe6, 0x18, 0x05, 0x21, 0x23, 0x40, 0x71, 0x71, + 0x26, 0x00, 0xf5, 0xf2, 0xc6, 0x4f, 0xf5, 0x5f, 0xfd, 0x7b, 0xba, 0xe2, 0x04, 0x84, 0x04, 0xcf, + 0x98, 0xbd, 0x2f, 0x0a, 0x28, 0x58, 0x81, 0x21, 0x11, 0x12, 0xdb, 0xbc, 0x57, 0x6e, 0xf5, 0xf8, + 0x81, 0xe5, 0xc0, 0x85, 0xb6, 0x64, 0x65, 0x99, 0xec, 0xc5, 0x55, 0xe1, 0x88, 0x2c, 0xc4, 0x84, + 0x0d, 0xb6, 0x45, 0xdb, 0x62, 0xed, 0xc1, 0x1b, 0xdd, 0xd7, 0x02, 0x00, 0x16, 0x41, 0x56, 0x35, + 0x4b, 0x59, 0xee, 0xaa, 0x94, 0x99, 0x14, 0xb9, 0x7e, 0x0a, 0x04, 0x82, 0xab, 0x3f, 0x38, 0xbe, + 0x2f, 0x5b, 0xf8, 0x64, 0x61, 0x0f, 0x07, 0xe2, 0xb7, 0x1b, 0xc5, 0xcb, 0x22, 0xfb, 0x97, 0x77, + 0x76, 0xef, 0xe1, 0x11, 0xf3, 0xcd, 0x98, 0x4c, 0xe6, 0x55, 0x5e, 0xfe, 0x11, 0x18, 0x52, 0xfa, + 0xdc, 0xb6, 0x2b, 0x14, 0x77, 0xbb, 0xbf, 0x89, 0x8e, 0xe8, 0x1b, 0x8a, 0xde, 0xea, 0x25, 0xcb, + 0x5f, 0x8c, 0x11, 0x8a, 0xf6, 0xa8, 0x75, 0x74, 0x1f, 0x53, 0xce, 0x1c, 0x58, 0x2b, 0x0a, 0x8a, + 0xf2, 0xeb, 0xf8, 0x21, 0x1e, 0x78, 0xf0, 0xc7, 0xee, 0xe2, 0x7e, 0x5f, 0xde, 0x18, 0x89, 0xe8, + 0x6e, 0xa1, 0xce, 0x8d, 0x84, 0x44, 0x14, 0x03, 0x11, 0x81, 0x0a, 0xc4, 0xf2, 0x56, 0x39, 0xb9, + 0x7a, 0xa9, 0x35, 0xc7, 0xfe, 0xf8, 0x20, 0x05, 0x91, 0x59, 0x6c, 0x56, 0x2b, 0x73, 0x60, 0x5e, + 0xa3, 0x4a, 0xfb, 0x8e, 0x04, 0x7c, 0x07, 0x08, 0xb9, 0x47, 0x70, 0xcc, 0x48, 0x00, 0x3d, 0x62, + 0xa4, 0x6f, 0x23, 0x82, 0x74, 0x27, 0xff, 0xc9, 0x93, 0xa7, 0x32, 0xb9, 0x7e, 0x39, 0x7c, 0xbf, + 0xe2, 0x75, 0x88, 0x82, 0x12, 0x0a, 0xc5, 0x18, 0xac, 0x56, 0xfc, 0x48, 0x40, 0x45, 0x6b, 0xe5, + 0xcc, 0x4c, 0x20, 0x5c, 0x56, 0x2b, 0x77, 0xdf, 0x7c, 0x44, 0xd7, 0x77, 0x7c, 0x40, 0x65, 0x8c, + 0xcd, 0x70, 0x50, 0x18, 0xfa, 0x0b, 0xf4, 0x16, 0xc2, 0x20, 0xc0, 0x15, 0x05, 0x2f, 0x73, 0x87, + 0x94, 0x47, 0x4b, 0x3d, 0x86, 0xaa, 0xfc, 0x48, 0x29, 0x0a, 0x4b, 0x18, 0x79, 0x00, 0xd4, 0xf5, + 0x84, 0x40, 0x00, 0x4d, 0x58, 0xf0, 0x00, 0x2f, 0x87, 0x80, 0x01, 0x3c, 0x34, 0x40, 0xe9, 0xc7, + 0x80, 0x30, 0x47, 0x47, 0x2d, 0x09, 0x45, 0x9b, 0x61, 0x67, 0xdc, 0x6a, 0x47, 0x6c, 0x2d, 0xa4, + 0xf1, 0xc8, 0x41, 0xa6, 0x54, 0xe1, 0xd0, 0x7b, 0xbf, 0xc6, 0x4f, 0x00, 0x1e, 0x7b, 0xcb, 0x00, + 0x67, 0x8f, 0x10, 0xf1, 0x41, 0xb7, 0x96, 0x03, 0x27, 0x1c, 0x8b, 0x76, 0x2b, 0x2e, 0xc5, 0x18, + 0xb6, 0xf8, 0x40, 0x32, 0x09, 0x8b, 0xaa, 0xad, 0x7d, 0xe2, 0x02, 0x5b, 0xbb, 0xde, 0xfc, 0x40, + 0xc2, 0x8a, 0x31, 0x46, 0x2b, 0x14, 0x69, 0x45, 0x6e, 0xef, 0xb8, 0xae, 0xfc, 0x20, 0x2e, 0x2b, + 0x77, 0x7d, 0xdf, 0x89, 0x14, 0x21, 0x22, 0xb1, 0x7b, 0xbb, 0xf0, 0x42, 0x12, 0x1f, 0xaa, 0x8b, + 0x8b, 0xb7, 0x05, 0xb0, 0x8c, 0x5f, 0x3a, 0xf9, 0x7a, 0x77, 0xc1, 0x08, 0xa1, 0x5a, 0x6d, 0xc7, + 0x72, 0x7a, 0xb8, 0x81, 0x86, 0x16, 0xb5, 0x18, 0x10, 0xc4, 0x04, 0xa9, 0x74, 0x2a, 0x2e, 0x9e, + 0x10, 0x36, 0x31, 0x6b, 0x63, 0xe1, 0x13, 0xb8, 0x7e, 0x11, 0x3e, 0xa4, 0xa1, 0x71, 0x01, 0x2a, + 0x6e, 0xfa, 0x14, 0x7a, 0xe7, 0xc4, 0x7c, 0x64, 0x1a, 0xae, 0x0b, 0xc9, 0x29, 0x33, 0x20, 0xbc, + 0x78, 0xf1, 0x07, 0xa7, 0x95, 0x4a, 0xb0, 0xe8, 0x6c, 0x6a, 0x0e, 0xda, 0xa6, 0x15, 0xbb, 0x0a, + 0xef, 0xed, 0xfb, 0xd7, 0x4b, 0xfb, 0x39, 0xa8, 0xcf, 0xf1, 0x02, 0x04, 0xbb, 0xef, 0x7a, 0xe8, + 0x67, 0x70, 0x50, 0x0a, 0x41, 0x30, 0x5d, 0x37, 0x4d, 0xf5, 0x4c, 0x44, 0x54, 0x15, 0xc4, 0xc1, + 0x68, 0x89, 0x97, 0xd6, 0xab, 0xfe, 0x18, 0x06, 0x24, 0x24, 0x3d, 0x4c, 0xfc, 0x49, 0x6b, 0xaf, + 0x82, 0xdb, 0xb2, 0x54, 0x4d, 0x32, 0x52, 0x24, 0x72, 0xb8, 0x29, 0xdd, 0xef, 0x97, 0xbb, 0xdd, + 0xfe, 0x43, 0x16, 0x50, 0x16, 0xd3, 0xaa, 0x29, 0x4d, 0xff, 0x27, 0x49, 0xdf, 0x5e, 0xf8, 0x28, + 0x23, 0xbd, 0xf1, 0x5f, 0xb0, 0x8b, 0x0c, 0x84, 0x1f, 0x6a, 0x4c, 0xb5, 0xf8, 0x29, 0x89, 0x12, + 0x08, 0xcd, 0x88, 0xb1, 0xbf, 0x08, 0x02, 0x1a, 0xe5, 0x18, 0xee, 0xff, 0x1e, 0x66, 0xe5, 0xcf, + 0x05, 0xb2, 0x0b, 0x05, 0xf7, 0xf5, 0xa6, 0x3c, 0xbe, 0xda, 0x9f, 0x0d, 0xc8, 0x35, 0xdb, 0x7f, + 0x10, 0x09, 0x45, 0x4b, 0x97, 0x66, 0x2c, 0xaf, 0x71, 0x00, 0x87, 0x82, 0x80, 0x8a, 0x0b, 0xf6, + 0x2d, 0x17, 0xd1, 0x87, 0x78, 0x67, 0x8b, 0x09, 0x3b, 0xf7, 0xbe, 0x0c, 0x44, 0xab, 0xf1, 0x01, + 0x10, 0x48, 0x67, 0x41, 0x0a, 0xe3, 0x37, 0x10, 0x24, 0x17, 0x14, 0x43, 0x01, 0x5b, 0xba, 0xba, + 0xab, 0x1c, 0x40, 0x9f, 0x10, 0x3f, 0xbb, 0xbb, 0x61, 0x46, 0xac, 0xf7, 0x16, 0x2f, 0xe1, 0x23, + 0x5f, 0x9e, 0xaa, 0xb8, 0x22, 0x1a, 0xb5, 0xf5, 0x74, 0x57, 0xac, 0x4d, 0x44, 0x89, 0x28, 0x87, + 0x7f, 0xc8, 0x21, 0xd2, 0xf1, 0x21, 0x93, 0x5e, 0xef, 0xc1, 0x4f, 0x02, 0x80, 0x46, 0x08, 0xe1, + 0x18, 0xb1, 0x6f, 0x7f, 0x2e, 0x70, 0x88, 0xa2, 0x6e, 0x7c, 0xd2, 0x2e, 0x60, 0x80, 0x32, 0x13, + 0x23, 0xb5, 0xe5, 0xee, 0x73, 0xf1, 0x31, 0x17, 0x3e, 0x7d, 0x37, 0xc4, 0x88, 0x10, 0x77, 0xbd, + 0x57, 0xe1, 0x12, 0xd6, 0xbc, 0x48, 0x91, 0x62, 0x39, 0x7c, 0x0d, 0xcf, 0x82, 0xfb, 0x13, 0x2d, + 0x8f, 0x91, 0x71, 0x21, 0x22, 0x5e, 0xf2, 0xa7, 0xb6, 0xbc, 0x49, 0xd9, 0x36, 0x6d, 0xc4, 0x71, + 0x0e, 0x48, 0x71, 0x3c, 0x4d, 0x09, 0xe9, 0x71, 0x08, 0xbd, 0xe2, 0x7e, 0x09, 0x4c, 0x92, 0x5d, + 0xd6, 0xfc, 0x4c, 0x82, 0xb5, 0x36, 0x70, 0xcf, 0x04, 0x01, 0x12, 0x8b, 0xcf, 0x28, 0x21, 0xe6, + 0x29, 0xf1, 0xe2, 0x1f, 0xc2, 0x20, 0x8c, 0xcb, 0x8b, 0xf3, 0xe3, 0xe3, 0x1d, 0x1b, 0x33, 0x7b, + 0xf5, 0x4b, 0xc7, 0xdd, 0xde, 0xdb, 0x35, 0xea, 0xa9, 0xb9, 0x7f, 0x08, 0xba, 0xaa, 0xf1, 0x21, + 0x0f, 0x8b, 0xaa, 0xad, 0x77, 0xf0, 0x54, 0x65, 0x95, 0x5d, 0x9c, 0x8c, 0x33, 0xae, 0xb6, 0x71, + 0x32, 0x5e, 0xab, 0x89, 0x93, 0x24, 0x67, 0x87, 0x10, 0x24, 0xb5, 0x4e, 0x12, 0xd6, 0x35, 0x0e, + 0x7c, 0x48, 0xb1, 0x37, 0xbc, 0xb4, 0xf8, 0x9f, 0x84, 0x6f, 0xbb, 0xbb, 0xbb, 0xbb, 0xbe, 0x24, + 0x4a, 0xbf, 0xc2, 0x57, 0xbb, 0xbb, 0xdd, 0x44, 0x89, 0xcf, 0x38, 0x24, 0x75, 0x4b, 0x12, 0x11, + 0x46, 0x7e, 0x11, 0x12, 0x42, 0x49, 0x97, 0xc1, 0x80, 0x80, 0x52, 0x28, 0xfe, 0x03, 0xb6, 0xc5, + 0x9f, 0x1f, 0x77, 0xc8, 0x8e, 0xb0, 0x60, 0x24, 0x28, 0x71, 0x03, 0x82, 0xb1, 0x5b, 0xbb, 0x9f, + 0x1f, 0x8f, 0x8b, 0xe2, 0x98, 0xb9, 0x17, 0x04, 0x10, 0x8c, 0x98, 0xad, 0x5f, 0x04, 0x01, 0x9e, + 0x20, 0x22, 0x62, 0xac, 0x5c, 0x5f, 0x89, 0x14, 0x4e, 0x56, 0x2e, 0xee, 0xa2, 0x44, 0x90, 0xea, + 0xaa, 0xbc, 0x48, 0x22, 0x33, 0xbf, 0xde, 0x24, 0x79, 0x2f, 0x55, 0x7b, 0x6f, 0x77, 0xe2, 0x4c, + 0x7b, 0x76, 0xfc, 0x14, 0xed, 0xdb, 0xd5, 0x5d, 0xf7, 0xa8, 0x90, 0xcf, 0x08, 0x89, 0xe2, 0x3f, + 0x09, 0x9d, 0xee, 0xf7, 0x77, 0xe1, 0x9b, 0xc4, 0x82, 0x4d, 0xde, 0xf5, 0x84, 0x59, 0x2a, 0xbc, + 0x1c, 0x83, 0x90, 0x45, 0x77, 0xfb, 0x83, 0x09, 0x04, 0x6a, 0xb8, 0x30, 0x12, 0x08, 0x6f, 0x6c, + 0xbc, 0x6b, 0x7c, 0xfd, 0x53, 0x4d, 0xdb, 0xf0, 0xf4, 0x20, 0x0e, 0x42, 0xa5, 0x3f, 0xdd, 0xef, + 0x08, 0x43, 0x72, 0xa1, 0x55, 0x77, 0xff, 0xf1, 0x2c, 0xae, 0xfe, 0x24, 0x47, 0xc5, 0x88, 0xad, + 0x56, 0xbe, 0x19, 0x30, 0x95, 0x5f, 0x13, 0xf9, 0x4d, 0x7b, 0xe2, 0x26, 0xd6, 0xab, 0xa1, 0x2f, + 0xf0, 0x44, 0x5b, 0xdd, 0xf8, 0x99, 0x89, 0x7b, 0xc3, 0x4c, 0xe0, 0x13, 0xbd, 0x21, 0x86, 0xd1, + 0xf6, 0x7f, 0xfb, 0x9c, 0x20, 0x20, 0x41, 0x1c, 0x56, 0xef, 0x4d, 0x57, 0x89, 0x04, 0x24, 0x7b, + 0xbd, 0x78, 0x81, 0x25, 0x7b, 0xd5, 0x55, 0x56, 0x27, 0xc4, 0xb3, 0x2d, 0x57, 0x13, 0x12, 0x7a, + 0xa5, 0xc5, 0x6f, 0xe3, 0x0b, 0x7b, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xa8, 0x31, 0x07, 0x3c, + 0x18, 0x08, 0x09, 0x0e, 0x17, 0x17, 0x5e, 0x2e, 0xb8, 0x30, 0x8f, 0x8b, 0x88, 0xf3, 0x72, 0xfb, + 0xb8, 0xae, 0xeb, 0xc4, 0xe1, 0xc8, 0x88, 0x5f, 0x37, 0xd5, 0x52, 0x83, 0x4c, 0x64, 0x9d, 0xfd, + 0x62, 0x7c, 0x4d, 0x44, 0xc1, 0x09, 0xc9, 0xdb, 0xd3, 0xf1, 0x01, 0x01, 0x57, 0xbb, 0xde, 0xf8, + 0x81, 0x03, 0xea, 0x5f, 0x71, 0x58, 0x5d, 0x5d, 0x71, 0xf4, 0x09, 0xaf, 0x41, 0x89, 0xfc, 0x12, + 0x5f, 0x77, 0xa8, 0x91, 0x3c, 0x40, 0x29, 0xf0, 0x11, 0x01, 0x41, 0x22, 0x80, 0x0c, 0x48, 0x0f, + 0x14, 0x06, 0x58, 0x37, 0x06, 0x35, 0x25, 0x15, 0x41, 0x41, 0x8a, 0x03, 0x15, 0x8a, 0x36, 0xcf, + 0x3c, 0x51, 0xab, 0xa3, 0xf1, 0x01, 0x16, 0x6b, 0x7b, 0x75, 0x89, 0x45, 0x7e, 0x26, 0x08, 0x4a, + 0xaa, 0xaa, 0xf7, 0x89, 0x05, 0x62, 0xb6, 0x9d, 0x26, 0xa9, 0x3b, 0xa4, 0xff, 0xf8, 0x44, 0x4b, + 0xbb, 0xb8, 0xac, 0x56, 0x2b, 0x15, 0xbb, 0xbb, 0xf8, 0x8b, 0xbb, 0xdd, 0xfc, 0x4d, 0xe5, 0xa7, + 0x83, 0x10, 0x20, 0xf0, 0x60, 0x24, 0x11, 0x0c, 0x6c, 0x28, 0xac, 0x95, 0xaa, 0x0e, 0x20, 0x32, + 0x36, 0x78, 0x0e, 0x0a, 0x0c, 0x94, 0x1b, 0x85, 0x8c, 0xfc, 0x4b, 0x95, 0x93, 0x54, 0xf0, 0xe1, + 0x5e, 0xa2, 0x43, 0xd1, 0x00, 0x78, 0xa2, 0xd4, 0xb0, 0xdd, 0xb9, 0x2a, 0x50, 0xcb, 0x1d, 0x06, + 0x5f, 0x6a, 0xd1, 0x59, 0x5f, 0x0e, 0x44, 0xc1, 0x65, 0xdf, 0xab, 0x35, 0xaa, 0xae, 0xbc, 0x49, + 0x8b, 0x5a, 0xe2, 0x7f, 0x25, 0xef, 0xf3, 0x19, 0x77, 0xc4, 0xfe, 0x43, 0xdd, 0xdf, 0x10, 0x20, + 0x7f, 0x8a, 0xdf, 0x71, 0x5b, 0x8a, 0xc5, 0x62, 0x8f, 0xc1, 0x35, 0xb5, 0x3b, 0x39, 0x6c, 0x56, + 0xe2, 0xbe, 0xf1, 0x00, 0x93, 0xcb, 0xdf, 0x89, 0x0c, 0x8c, 0x2e, 0xe2, 0xb7, 0xbb, 0x85, 0xdf, + 0x1e, 0xe5, 0xd6, 0x5b, 0x12, 0xe3, 0xfc, 0x48, 0x24, 0x25, 0xdd, 0xeb, 0x89, 0x12, 0x14, 0x2a, + 0xae, 0xe2, 0xb4, 0xc5, 0x63, 0xad, 0x61, 0xb1, 0x9b, 0x3e, 0x2b, 0xf5, 0xda, 0x3b, 0xc1, 0x44, + 0xa4, 0xbb, 0xf8, 0x80, 0x91, 0x56, 0xb7, 0xbf, 0x89, 0xf9, 0x75, 0xab, 0xc4, 0x02, 0xcd, 0xdf, + 0x77, 0x77, 0x7b, 0xbf, 0x08, 0x09, 0x11, 0x3f, 0xa8, 0x60, 0xc6, 0x5c, 0xa0, 0x62, 0xb6, 0xf0, + 0x84, 0x15, 0x6f, 0x71, 0x58, 0xad, 0xc5, 0x77, 0xbb, 0xf1, 0x15, 0x7e, 0x26, 0xa8, 0xef, 0x13, + 0xe2, 0x41, 0x89, 0xab, 0x5e, 0x20, 0x32, 0x41, 0x5b, 0xbc, 0x4f, 0xc3, 0x6c, 0xa0, 0x00, 0xf4, + 0xc9, 0xa9, 0xc8, 0x15, 0xee, 0x9f, 0xf2, 0x1d, 0x8c, 0x7c, 0x94, 0x83, 0x08, 0xfb, 0x76, 0xde, + 0x18, 0x3d, 0x1d, 0x15, 0xa2, 0x01, 0xd8, 0x68, 0x36, 0x43, 0xc3, 0x5c, 0x16, 0x55, 0xd8, 0xfc, + 0xb8, 0x86, 0x1c, 0x1c, 0x80, 0xa3, 0x5a, 0x69, 0x68, 0xf8, 0x03, 0x5f, 0x38, 0x40, 0x14, 0x84, + 0xe2, 0x5c, 0xfd, 0x34, 0xb1, 0x37, 0x77, 0xf8, 0x8a, 0x89, 0xdc, 0x40, 0x64, 0x97, 0x7f, 0x84, + 0x41, 0x2d, 0xde, 0xef, 0x7b, 0xf1, 0x31, 0x17, 0x7d, 0xef, 0xc4, 0x89, 0x57, 0xe2, 0x42, 0x21, + 0x42, 0xac, 0x5f, 0x7b, 0xee, 0xee, 0x2b, 0x77, 0xbf, 0x02, 0xc4, 0x15, 0x8b, 0x3c, 0x01, 0xe7, + 0x8f, 0x2c, 0x00, 0x67, 0xbc, 0x56, 0x7b, 0x8f, 0x59, 0xf0, 0x3b, 0x96, 0x2f, 0x3c, 0x3d, 0xf8, + 0x64, 0x43, 0x10, 0xee, 0xef, 0x89, 0x12, 0x6a, 0xaa, 0xf8, 0x95, 0x1d, 0xb8, 0x91, 0x3f, 0x29, + 0x96, 0xbf, 0x15, 0xbb, 0xef, 0x7f, 0x18, 0x7d, 0xd2, 0x70, 0xd3, 0xe7, 0x2d, 0x8a, 0xdc, 0x57, + 0x12, 0xb0, 0x7a, 0xc3, 0xfc, 0x20, 0x10, 0xdd, 0xf6, 0xfc, 0xbe, 0x5f, 0xc4, 0x02, 0x8e, 0xef, + 0xbb, 0xa3, 0xb8, 0x59, 0x14, 0x09, 0xdf, 0x80, 0xd4, 0x21, 0x3f, 0xd3, 0xd3, 0xb6, 0xdc, 0x9f, + 0x89, 0xe2, 0x3c, 0x4c, 0x12, 0x13, 0x55, 0x47, 0x78, 0x89, 0x2b, 0x5f, 0x07, 0x20, 0x88, 0x64, + 0x5e, 0x2e, 0x5b, 0x88, 0x12, 0x34, 0x5a, 0x8a, 0xc4, 0x7c, 0x67, 0xe4, 0xf5, 0xb3, 0xd4, 0x1a, + 0x05, 0x14, 0x51, 0xf9, 0xdc, 0xa3, 0x62, 0x08, 0x89, 0xdc, 0x58, 0x08, 0x7c, 0x1e, 0x0f, 0xbf, + 0x86, 0x39, 0x89, 0xa6, 0x32, 0xb8, 0x80, 0x42, 0x37, 0x0a, 0x00, 0xaa, 0x8f, 0x1f, 0x7c, 0x07, + 0xd4, 0x55, 0x6b, 0x97, 0x32, 0x88, 0xf1, 0xed, 0xde, 0x0d, 0xc9, 0x3f, 0xf1, 0x02, 0x7e, 0x08, + 0x4b, 0x77, 0xbf, 0x12, 0x25, 0x6b, 0xe4, 0xbd, 0xef, 0x08, 0x16, 0x21, 0x83, 0x1b, 0x69, 0xf1, + 0x00, 0x9e, 0xee, 0xef, 0x77, 0xbf, 0xc1, 0x19, 0x5d, 0xdd, 0xd2, 0xae, 0x24, 0x15, 0xea, 0xf7, + 0xbd, 0xdd, 0xc5, 0x68, 0xef, 0x11, 0x14, 0x47, 0x15, 0x8a, 0xc5, 0x18, 0xac, 0x56, 0xef, 0x83, + 0x01, 0x21, 0x41, 0x67, 0x50, 0xdf, 0x97, 0xd6, 0x29, 0xd6, 0x2e, 0x2b, 0xb6, 0x95, 0x94, 0x4f, + 0x05, 0xd3, 0xf0, 0x88, 0x60, 0x82, 0x1f, 0x7e, 0x11, 0x9b, 0xaa, 0xf0, 0x8f, 0x13, 0xae, 0x08, + 0x8c, 0xfb, 0xf7, 0x89, 0x04, 0x45, 0x8a, 0xe5, 0xf7, 0xf1, 0x21, 0x4b, 0xbe, 0xee, 0xee, 0xee, + 0xfb, 0xbd, 0xdf, 0x89, 0x82, 0xd9, 0xf2, 0xf7, 0x77, 0x77, 0xe2, 0x21, 0x32, 0xbd, 0xee, 0x74, + 0x97, 0xe2, 0x41, 0x5d, 0xdd, 0xde, 0xf7, 0xb3, 0x77, 0x47, 0x78, 0x98, 0x23, 0xdd, 0xe8, 0xef, + 0xd5, 0xfe, 0x2a, 0xaa, 0xaa, 0xaa, 0xbc, 0x44, 0xb5, 0xd7, 0x13, 0xe0, 0x82, 0x30, 0x63, 0x7b, + 0xfd, 0xc5, 0x38, 0x92, 0xc3, 0xde, 0xe7, 0x9f, 0x7b, 0xf9, 0x4a, 0x94, 0xfe, 0x16, 0xe0, 0x93, + 0xbb, 0xd7, 0x12, 0x11, 0x0a, 0x08, 0x7b, 0xea, 0xd9, 0x27, 0x5b, 0xb6, 0x0d, 0x4c, 0xc7, 0x2f, + 0x72, 0xdd, 0x71, 0x02, 0x42, 0x65, 0x7f, 0x5f, 0x5a, 0xf8, 0x2b, 0x3a, 0xd7, 0x75, 0xe9, 0xb7, + 0x5c, 0x22, 0x10, 0x08, 0x5e, 0xf7, 0x6d, 0x37, 0x97, 0x22, 0xbf, 0x45, 0x7f, 0x10, 0xaf, 0x5c, + 0xb5, 0xaf, 0x13, 0x62, 0x2f, 0x7c, 0x22, 0x18, 0x18, 0x2e, 0xee, 0xf7, 0x4d, 0xf1, 0x7b, 0xbb, + 0xb5, 0xe1, 0x4b, 0xbb, 0xdd, 0xdd, 0xdd, 0xee, 0xee, 0xee, 0x8e, 0xf8, 0x20, 0x0a, 0x50, 0xef, + 0xe6, 0xc7, 0x1d, 0xc6, 0x3b, 0x89, 0xcf, 0x8f, 0xe2, 0x06, 0x5d, 0xef, 0x7b, 0xbb, 0xdd, 0xcf, + 0xdd, 0xff, 0x04, 0x21, 0x00, 0x43, 0xbb, 0xba, 0x3b, 0xc4, 0xd5, 0x1d, 0xe1, 0x1a, 0x27, 0x57, + 0x35, 0xdd, 0xdd, 0xf2, 0x5d, 0xdf, 0xe4, 0xdd, 0xfc, 0x32, 0x08, 0xef, 0x7d, 0x71, 0x22, 0x42, + 0x25, 0x77, 0x77, 0x7b, 0xbb, 0xdf, 0x88, 0x82, 0x69, 0x73, 0xde, 0xef, 0xbf, 0xc1, 0x36, 0xf7, + 0xdd, 0xeb, 0xc4, 0x84, 0xea, 0xab, 0x4a, 0xd7, 0x11, 0xe1, 0x01, 0x1f, 0x27, 0x55, 0xc4, 0x82, + 0x10, 0x54, 0x29, 0x57, 0x85, 0xdb, 0x9b, 0xad, 0x60, 0xe1, 0x80, 0xc8, 0x52, 0x5a, 0xc4, 0x1e, + 0x36, 0xa5, 0xe1, 0x65, 0x4b, 0x5c, 0x6d, 0x9e, 0xfd, 0xbe, 0x9c, 0x42, 0xc7, 0x28, 0x5a, 0x24, + 0x22, 0x09, 0xc8, 0x7e, 0xa5, 0x93, 0x67, 0xf4, 0xdf, 0xae, 0x5c, 0x20, 0x19, 0x1d, 0x27, 0x69, + 0xbe, 0xb7, 0x7b, 0x93, 0xff, 0x08, 0xf8, 0x9a, 0xc4, 0x94, 0x6b, 0xbd, 0xf8, 0x8e, 0x27, 0xc4, + 0x88, 0x5e, 0xf1, 0x22, 0x09, 0x5a, 0xad, 0x55, 0x62, 0x0b, 0xaa, 0xaf, 0x82, 0x4a, 0xa6, 0xae, + 0xff, 0x09, 0x96, 0xdb, 0x1b, 0x76, 0xea, 0xb1, 0x35, 0x89, 0x31, 0xb5, 0x5e, 0x27, 0xe0, 0x9c, + 0xf7, 0x7b, 0xc6, 0xd7, 0x7f, 0x10, 0x4b, 0xbf, 0xe2, 0xca, 0xee, 0xef, 0x4e, 0xdb, 0xe0, 0x96, + 0xe7, 0xef, 0x75, 0xdb, 0x7a, 0x3b, 0xe2, 0x19, 0x37, 0x75, 0x10, 0x23, 0x89, 0x08, 0xf8, 0x44, + 0x4d, 0x75, 0xd5, 0xf8, 0x82, 0x6b, 0x5c, 0x4c, 0x14, 0x16, 0xb5, 0x55, 0x5b, 0xf8, 0x44, 0x50, + 0xe1, 0x00, 0xf1, 0x2f, 0x2f, 0x3d, 0xf4, 0xd3, 0x45, 0x88, 0x12, 0x34, 0x4e, 0xdb, 0xd3, 0x55, + 0x14, 0x5a, 0x18, 0x2c, 0x09, 0x54, 0x3d, 0xea, 0x2e, 0xe6, 0x72, 0x8b, 0x8a, 0xfe, 0x15, 0x84, + 0x03, 0x21, 0x41, 0x49, 0xba, 0x6e, 0x7c, 0xf1, 0x70, 0x7d, 0xeb, 0xc5, 0xeb, 0xef, 0x13, 0xe2, + 0x3c, 0x4f, 0x10, 0x10, 0x15, 0x2b, 0x17, 0x77, 0x77, 0x12, 0xa4, 0xf2, 0x8b, 0x07, 0xec, 0x28, + 0xbb, 0xf4, 0xf1, 0x35, 0x88, 0xae, 0xbd, 0xf1, 0xf1, 0x1c, 0x8a, 0xfb, 0x8a, 0xdc, 0x4b, 0x9e, + 0x24, 0x49, 0x48, 0xee, 0xee, 0xb1, 0x3e, 0x26, 0xa2, 0x44, 0x0b, 0x3b, 0xef, 0xbb, 0xe2, 0x60, + 0xae, 0x5e, 0xee, 0xef, 0x15, 0xde, 0xfb, 0xf1, 0x30, 0x86, 0xf7, 0x7b, 0xbb, 0xdf, 0xe1, 0x0b, + 0xbd, 0xdd, 0xdd, 0xde, 0xef, 0xec, 0xa7, 0x49, 0xbf, 0x13, 0x17, 0x55, 0xd6, 0xab, 0xc4, 0x16, + 0xab, 0x55, 0xca, 0x4d, 0x57, 0x11, 0x18, 0x75, 0x5a, 0xaa, 0x8b, 0x8b, 0xaa, 0xaa, 0xaa, 0xaf, + 0x89, 0xa8, 0x91, 0x25, 0x15, 0x55, 0x5e, 0x11, 0x04, 0x55, 0xaa, 0xf6, 0x19, 0x8b, 0x01, 0xd9, + 0x82, 0x9d, 0x7f, 0xed, 0xb7, 0xe6, 0x4f, 0x05, 0x20, 0xb0, 0x64, 0x55, 0xa6, 0xea, 0x2e, 0xaa, + 0xb5, 0x5d, 0x71, 0x11, 0x84, 0x76, 0x96, 0xce, 0x3e, 0xf7, 0xb8, 0x58, 0xd3, 0x2c, 0x30, 0x57, + 0xac, 0xbe, 0xe1, 0x4e, 0x2b, 0x0a, 0x03, 0x8b, 0xfe, 0x2d, 0x8a, 0xf8, 0x97, 0x66, 0x7b, 0xc4, + 0xf8, 0x80, 0x8c, 0xdc, 0xbb, 0x54, 0xde, 0xfb, 0x97, 0x0b, 0x7e, 0x24, 0xb6, 0xc3, 0x17, 0x44, + 0x9b, 0x7e, 0x26, 0x8e, 0xf5, 0x88, 0xf1, 0x0b, 0xff, 0xad, 0x78, 0x95, 0x7f, 0xaf, 0x7d, 0x7a, + 0xb9, 0x2b, 0x43, 0xf1, 0x22, 0xaf, 0x77, 0x7d, 0xf8, 0x90, 0x5d, 0xbb, 0xf7, 0x77, 0xf0, 0x88, + 0x23, 0xbb, 0xbb, 0xdf, 0xc4, 0x88, 0xbb, 0xee, 0xef, 0xe2, 0x04, 0x95, 0xdd, 0xdd, 0xee, 0xfc, + 0x42, 0xa3, 0xbc, 0x4c, 0x25, 0x55, 0x55, 0x5d, 0x70, 0x88, 0x91, 0x75, 0x55, 0x55, 0xd7, 0x12, + 0x24, 0x76, 0xaa, 0x91, 0x21, 0xd5, 0xb5, 0xaf, 0x12, 0x24, 0x8b, 0xaa, 0xae, 0xba, 0x27, 0x78, + 0x8f, 0x13, 0xf0, 0x9d, 0xdf, 0xd5, 0x71, 0x22, 0x45, 0xf5, 0x5d, 0x57, 0x13, 0x15, 0x5a, 0xe9, + 0x25, 0xe0, 0xc4, 0xc4, 0x5d, 0x78, 0x64, 0x15, 0x9f, 0x75, 0x0a, 0xaa, 0xab, 0x05, 0x10, 0x35, + 0xac, 0xbc, 0x5d, 0x54, 0x01, 0x53, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1a, 0x0d, 0x30, + 0xa8, 0x37, 0xd0, 0x4f, 0xa0, 0xd4, 0x24, 0x8c, 0x0b, 0xb2, 0x05, 0x8a, 0xfd, 0x7b, 0xf8, 0x23, + 0x2e, 0x06, 0x3d, 0xc3, 0x5a, 0xec, 0x90, 0x83, 0x50, 0xf2, 0x18, 0x00, 0x09, 0xab, 0xef, 0x56, + 0xa6, 0x62, 0xff, 0xf3, 0xf1, 0xee, 0x0b, 0x8e, 0x09, 0x80, 0x0f, 0x01, 0xeb, 0x03, 0x3d, 0xc1, + 0xbb, 0xb9, 0xfe, 0x0a, 0x00, 0xa2, 0x0a, 0x08, 0x0c, 0x6e, 0xc1, 0x96, 0x48, 0xba, 0xd5, 0x57, + 0xdc, 0x1c, 0x41, 0x40, 0x4c, 0x5c, 0x5d, 0x55, 0x57, 0x19, 0x48, 0x33, 0xeb, 0x17, 0xc2, 0xe1, + 0x22, 0x50, 0xa9, 0xc6, 0x31, 0x44, 0x21, 0xe4, 0xc0, 0x00, 0x47, 0x28, 0x75, 0x06, 0xa0, 0x49, + 0x18, 0x14, 0x25, 0xfb, 0xcb, 0xf0, 0x52, 0x05, 0x11, 0x84, 0x2d, 0x62, 0x81, 0x9b, 0x97, 0x86, + 0x00, 0x0f, 0x49, 0x66, 0x2e, 0xad, 0x64, 0x74, 0x3f, 0x2a, 0x24, 0xf4, 0xc7, 0x6f, 0x83, 0x00, + 0xc0, 0x93, 0xa4, 0xa5, 0x6f, 0xc1, 0xb3, 0xc2, 0xbc, 0x0a, 0x1d, 0x1e, 0x42, 0x17, 0x7d, 0x7c, + 0x41, 0x4f, 0x44, 0x1d, 0xb8, 0x88, 0x50, 0x24, 0x15, 0x01, 0xa8, 0xb6, 0x73, 0xdf, 0xc4, 0x02, + 0xc1, 0x6d, 0xf8, 0x5b, 0x4c, 0xf7, 0xc4, 0x0b, 0x1c, 0x18, 0xac, 0x33, 0x88, 0x27, 0x07, 0x28, + 0xc2, 0x01, 0x91, 0x36, 0x7d, 0x9e, 0x4f, 0x2a, 0x44, 0xb0, 0x8f, 0xc1, 0x20, 0x45, 0xe9, 0x97, + 0x20, 0xc3, 0xa8, 0x80, 0x06, 0x36, 0xaf, 0x9e, 0xfb, 0xcf, 0xfe, 0xde, 0x1e, 0x8c, 0x5c, 0x30, + 0x60, 0x31, 0x21, 0xc5, 0x5b, 0x5a, 0x69, 0x60, 0xc0, 0x1c, 0x8b, 0x11, 0xbe, 0x82, 0x07, 0x28, + 0x8b, 0x22, 0x39, 0xd7, 0x30, 0x40, 0x04, 0x92, 0x97, 0x75, 0x0c, 0x63, 0x82, 0x0c, 0x15, 0x44, + 0x04, 0x42, 0x86, 0x88, 0x1f, 0x10, 0xf5, 0x6a, 0x78, 0x7d, 0x8e, 0xaf, 0x4e, 0x4e, 0xc6, 0x89, + 0x5a, 0xb3, 0x81, 0xe3, 0x5d, 0xf1, 0x93, 0xce, 0x49, 0x61, 0xa9, 0x18, 0x06, 0x4b, 0x0c, 0xe7, + 0x79, 0x60, 0x62, 0x3c, 0x94, 0x38, 0x38, 0x3f, 0x05, 0xd2, 0x51, 0x22, 0x5a, 0xe0, 0xc3, 0x2e, + 0x11, 0x04, 0xc2, 0x75, 0x55, 0x55, 0xf7, 0x84, 0x48, 0x2a, 0xef, 0xc4, 0x04, 0x47, 0x5e, 0xf9, + 0x2f, 0xab, 0xbb, 0xbe, 0x24, 0x41, 0x0a, 0xaf, 0x87, 0xc9, 0x98, 0x90, 0x42, 0x38, 0xc7, 0x8f, + 0x7e, 0x16, 0x3b, 0xa9, 0x73, 0x7c, 0xfc, 0x15, 0xc4, 0x04, 0x01, 0x51, 0x62, 0xea, 0xb1, 0x03, + 0xd3, 0x39, 0xf1, 0x5c, 0x51, 0xf3, 0x70, 0xc8, 0x29, 0x19, 0x5d, 0x49, 0x16, 0x07, 0x2c, 0x95, + 0x2c, 0x38, 0x90, 0xf1, 0x40, 0x61, 0x10, 0x92, 0x99, 0x0f, 0x3a, 0x81, 0xe5, 0x53, 0x12, 0x54, + 0x37, 0x0f, 0xa8, 0xc2, 0x02, 0x41, 0x18, 0xb7, 0x9c, 0xb0, 0xaf, 0x26, 0x24, 0xc3, 0x1d, 0x5f, + 0x88, 0xba, 0x45, 0x34, 0x56, 0xea, 0x26, 0x20, 0x58, 0x97, 0xdb, 0xef, 0x7e, 0x08, 0x42, 0x23, + 0x2a, 0x2e, 0x4f, 0xc5, 0xcd, 0xe3, 0x2f, 0xf8, 0x81, 0x61, 0x45, 0x20, 0xfa, 0x87, 0xd3, 0x5a, + 0xc1, 0x5c, 0x20, 0x0e, 0x41, 0x61, 0xa3, 0x29, 0x9b, 0xba, 0xaf, 0x19, 0x4c, 0xf1, 0xdd, 0xc4, + 0x86, 0x47, 0x93, 0x9a, 0xcc, 0xe9, 0xc5, 0x6d, 0xe2, 0x04, 0x82, 0x31, 0x36, 0xcb, 0xeb, 0xe9, + 0x22, 0x04, 0xfc, 0x49, 0xeb, 0x5a, 0xd7, 0x86, 0x78, 0x91, 0x1c, 0x32, 0x0a, 0x11, 0xbb, 0x86, + 0x41, 0x84, 0x15, 0xc4, 0x41, 0x24, 0xcc, 0xce, 0x19, 0x15, 0x8e, 0xef, 0x08, 0x82, 0x91, 0x0e, + 0x66, 0x1f, 0xce, 0xc4, 0xeb, 0xb6, 0xad, 0x8b, 0xf7, 0x86, 0x41, 0x48, 0x93, 0x9f, 0x5b, 0x7e, + 0xb5, 0xbd, 0xfd, 0x5c, 0xa7, 0xd5, 0x57, 0xe2, 0x3c, 0x40, 0x92, 0x8c, 0xaa, 0xae, 0x10, 0x84, + 0xa2, 0x47, 0x38, 0x9f, 0x07, 0x97, 0x4b, 0xe0, 0xc2, 0x0a, 0xf1, 0x06, 0x1b, 0x1d, 0xa5, 0xd7, + 0xc3, 0x00, 0xb0, 0x42, 0xa1, 0x2f, 0x5a, 0x87, 0x69, 0x90, 0x6c, 0x63, 0xee, 0x24, 0x20, 0x24, + 0x8a, 0x90, 0x9b, 0x12, 0x79, 0x62, 0x45, 0xf8, 0x80, 0x82, 0x3f, 0x78, 0x43, 0xe0, 0x90, 0xbc, + 0x01, 0x5c, 0xcc, 0x93, 0x7e, 0x55, 0x44, 0x09, 0x04, 0xb4, 0xdd, 0xfa, 0xaf, 0x78, 0x90, 0x88, + 0xce, 0x18, 0xd3, 0xf1, 0x5b, 0xdb, 0x46, 0xdf, 0x24, 0xb8, 0x20, 0x1c, 0x12, 0xe5, 0x58, 0x44, + 0x14, 0x31, 0x61, 0xa9, 0x86, 0x74, 0xbe, 0x0b, 0x22, 0x7c, 0x40, 0x93, 0x1a, 0x45, 0x0c, 0x1b, + 0x1b, 0x84, 0x42, 0x03, 0x26, 0x61, 0xa1, 0x56, 0xae, 0x0e, 0xde, 0x35, 0x42, 0xc5, 0x8b, 0x87, + 0x5c, 0xa4, 0xa1, 0xf5, 0xdc, 0x9a, 0xae, 0x0c, 0x07, 0x08, 0x09, 0x08, 0x4c, 0xce, 0x33, 0xb2, + 0xe6, 0x49, 0x55, 0x71, 0xd4, 0x42, 0x8c, 0xdc, 0x73, 0x80, 0x79, 0xc0, 0x0d, 0x30, 0x50, 0x11, + 0x17, 0xc4, 0x03, 0x42, 0xd2, 0xa3, 0x7f, 0x6d, 0x31, 0x02, 0x42, 0x46, 0x5b, 0x77, 0x90, 0x35, + 0xed, 0x3d, 0x57, 0x88, 0x12, 0x13, 0x17, 0x2b, 0xf8, 0xe8, 0x90, 0x5c, 0x12, 0xc6, 0x14, 0xe6, + 0x9a, 0x94, 0x4e, 0x55, 0x7f, 0xbc, 0x10, 0x41, 0x64, 0x48, 0x83, 0x71, 0xaf, 0x2b, 0x8c, 0xc0, + 0x90, 0x04, 0x91, 0x64, 0x48, 0x51, 0x96, 0xc5, 0x61, 0x75, 0x6a, 0xf8, 0x60, 0x10, 0x8c, 0xe5, + 0xc8, 0x3e, 0xc2, 0x40, 0x0e, 0x4d, 0x13, 0x6a, 0x2d, 0xb8, 0xac, 0x56, 0xc7, 0x3e, 0x20, 0x22, + 0x0a, 0xa3, 0xa0, 0x58, 0x78, 0x06, 0x03, 0x43, 0x49, 0xc1, 0xc3, 0x0c, 0xa5, 0x99, 0x58, 0xb2, + 0x24, 0x2b, 0x0b, 0x17, 0xa8, 0xee, 0xe2, 0x42, 0x21, 0x39, 0x4a, 0xcb, 0x9a, 0x66, 0xa2, 0x8b, + 0xd7, 0x84, 0x46, 0x5a, 0x7e, 0x0b, 0xcb, 0xf2, 0xf7, 0x17, 0xdd, 0xdd, 0xdf, 0x89, 0x15, 0xd4, + 0x9d, 0x79, 0x33, 0x88, 0x14, 0x6f, 0x10, 0xe0, 0xac, 0x95, 0x95, 0xfc, 0x10, 0x8d, 0x6c, 0x37, + 0xc6, 0x3c, 0xc2, 0x7b, 0xc3, 0x10, 0x5b, 0x08, 0x06, 0x42, 0x22, 0x1d, 0x39, 0x5f, 0x15, 0xa5, + 0x77, 0xc1, 0x48, 0x28, 0x19, 0xab, 0xc5, 0x31, 0x4c, 0x5c, 0x47, 0x05, 0x1b, 0x9f, 0x2f, 0x36, + 0x1b, 0x70, 0xc0, 0x21, 0x0a, 0x0b, 0x68, 0x79, 0x59, 0x85, 0xe5, 0xe2, 0x3c, 0x9e, 0x31, 0x0e, + 0x1c, 0x38, 0x70, 0x0e, 0x1e, 0x03, 0xcb, 0x61, 0x66, 0x85, 0x83, 0x26, 0x69, 0x47, 0x78, 0x98, + 0xe1, 0x18, 0xad, 0xc5, 0xf9, 0x63, 0x96, 0x37, 0xc2, 0x21, 0x02, 0xf7, 0x7c, 0x48, 0x40, 0x48, + 0x95, 0xad, 0xdd, 0x32, 0x90, 0x71, 0x30, 0x8d, 0x67, 0x77, 0x77, 0x69, 0x93, 0xbf, 0x11, 0xc1, + 0x00, 0x88, 0x2e, 0x82, 0x01, 0x03, 0x06, 0x49, 0xb1, 0x6d, 0xb9, 0x11, 0xc0, 0xe1, 0xc0, 0x39, + 0x11, 0xf1, 0x4c, 0x99, 0x52, 0xc6, 0xcf, 0x78, 0x31, 0x08, 0x8c, 0xa7, 0x15, 0x83, 0xcf, 0x01, + 0x72, 0xe3, 0xa7, 0xa6, 0xe0, 0x00, 0xf3, 0x0a, 0xab, 0x83, 0xa4, 0x94, 0x7a, 0x12, 0xaf, 0x0f, + 0xe1, 0x4f, 0xca, 0xfb, 0x63, 0xae, 0x11, 0x9e, 0x6c, 0x3b, 0x07, 0xf1, 0xd4, 0xc2, 0x60, 0xe2, + 0xdb, 0x84, 0x12, 0x40, 0xd5, 0xe0, 0x00, 0x27, 0xd3, 0xa3, 0xd7, 0x48, 0xbc, 0x63, 0x86, 0x42, + 0x21, 0x49, 0x63, 0x2c, 0x76, 0xd0, 0xa3, 0x2d, 0xbb, 0x87, 0xe0, 0x6a, 0xd8, 0x85, 0xc0, 0x73, + 0xe2, 0x60, 0x5a, 0xf3, 0x8f, 0x19, 0x5a, 0xe1, 0x81, 0x02, 0x4e, 0x2b, 0x89, 0x7d, 0xb5, 0x9e, + 0x24, 0x20, 0x2b, 0x4a, 0xf6, 0x81, 0xbf, 0xcd, 0xcf, 0x19, 0x4a, 0x21, 0x46, 0x28, 0xd5, 0x32, + 0xe6, 0xe2, 0xbb, 0x96, 0xc5, 0x1b, 0x8a, 0xfc, 0x61, 0xdd, 0xf7, 0x7a, 0xee, 0xe9, 0x5d, 0xf8, + 0x8f, 0xb1, 0x75, 0x93, 0xe1, 0x11, 0x10, 0x59, 0x88, 0x30, 0xae, 0x6b, 0xc2, 0x10, 0xa0, 0x8e, + 0x6e, 0x2b, 0x0d, 0x82, 0x69, 0x55, 0xd5, 0x74, 0xd6, 0xfc, 0x30, 0x08, 0x06, 0x1b, 0x3d, 0x67, + 0xb7, 0x30, 0xd5, 0x2f, 0xc3, 0x87, 0x0b, 0x67, 0x3f, 0x5a, 0x47, 0xe4, 0x83, 0xa3, 0xf1, 0xa1, + 0x80, 0xf1, 0x03, 0xaf, 0x0f, 0x2d, 0x99, 0x0b, 0xd9, 0x59, 0x6f, 0x15, 0xb7, 0xc1, 0x97, 0xed, + 0x62, 0x43, 0x1e, 0x24, 0x64, 0x37, 0xc2, 0x20, 0xf2, 0x94, 0xc4, 0x17, 0xb8, 0x53, 0xba, 0xae, + 0x2b, 0x7d, 0x87, 0xb7, 0x91, 0xb2, 0x6d, 0x97, 0x10, 0x97, 0xad, 0x84, 0xc6, 0x7c, 0xc2, 0x66, + 0x61, 0xb9, 0xf1, 0x07, 0x77, 0xbb, 0xbb, 0xbf, 0x98, 0x45, 0x6b, 0x89, 0x08, 0x96, 0xb5, 0x50, + 0x5b, 0x08, 0x04, 0x45, 0x89, 0x6a, 0xb3, 0xe2, 0xeb, 0x84, 0x48, 0xcc, 0xda, 0xf4, 0xbe, 0x68, + 0x13, 0x2a, 0xcf, 0xc4, 0x78, 0x8f, 0x8f, 0x22, 0x9e, 0x4b, 0x24, 0x31, 0x44, 0xc9, 0xd0, 0x3f, + 0xac, 0xe9, 0xd2, 0xed, 0x57, 0xe2, 0x0b, 0x07, 0x5e, 0x1f, 0x3e, 0x27, 0xc4, 0xd4, 0x40, 0x44, + 0xb7, 0xdf, 0xd0, 0x57, 0xa0, 0xaa, 0x10, 0x0c, 0xd7, 0x30, 0x53, 0x73, 0xfc, 0x48, 0x81, 0xe4, + 0xb2, 0x50, 0x7f, 0xf1, 0xb5, 0xbc, 0x7c, 0xc7, 0xe2, 0x05, 0xdd, 0x86, 0xac, 0xf8, 0x14, 0x7c, + 0xdc, 0xbc, 0xfc, 0x97, 0xdf, 0x10, 0x11, 0x2d, 0xf7, 0xc1, 0x04, 0xa1, 0x95, 0x5c, 0x13, 0xf0, + 0x48, 0x3b, 0x97, 0x35, 0xc4, 0x04, 0x41, 0x49, 0x31, 0x0e, 0x75, 0x49, 0xa5, 0xe3, 0xff, 0x13, + 0x2d, 0xed, 0x54, 0x48, 0x83, 0x5e, 0xab, 0x88, 0x12, 0x28, 0x93, 0xf0, 0x7f, 0xc7, 0x5f, 0x13, + 0x64, 0x77, 0xe1, 0x7c, 0x24, 0xb5, 0xf8, 0x92, 0x83, 0xbf, 0xde, 0xcd, 0xec, 0xd7, 0xd2, 0x7c, + 0xc2, 0x56, 0xaa, 0xb1, 0x32, 0x72, 0x1b, 0x97, 0xe2, 0x64, 0x10, 0xb5, 0xf0, 0x8f, 0x84, 0x60, + 0x96, 0x11, 0x84, 0xc5, 0x93, 0xf7, 0x3e, 0x2c, 0xe1, 0x98, 0x4c, 0xce, 0xfc, 0xde, 0x24, 0xfe, + 0x24, 0xd7, 0xbb, 0xa8, 0x91, 0x26, 0x12, 0xef, 0xac, 0x40, 0x44, 0x66, 0xee, 0xe2, 0xf0, 0x7b, + 0xa0, 0x55, 0xf6, 0xaf, 0xbe, 0x25, 0x9e, 0xb9, 0xd9, 0xac, 0x4f, 0x13, 0xbe, 0x51, 0xb7, 0x7a, + 0x88, 0xfc, 0x40, 0xc5, 0x5d, 0x56, 0xb8, 0x8f, 0x10, 0x11, 0x16, 0x47, 0xd7, 0x2e, 0x17, 0x30, + 0x86, 0x08, 0xa1, 0x1f, 0x04, 0x00, 0x87, 0xe2, 0x8b, 0x3d, 0xf5, 0xaf, 0xba, 0xd7, 0xc2, 0x1c, + 0x4c, 0x97, 0xd5, 0x71, 0x44, 0xb6, 0x8d, 0xcb, 0xd5, 0x55, 0x7c, 0x27, 0xba, 0xd7, 0x55, 0xca, + 0x37, 0x77, 0x71, 0x32, 0xee, 0xfc, 0x40, 0x42, 0x5e, 0x41, 0x03, 0xfe, 0x27, 0x59, 0x74, 0x7c, + 0x22, 0x09, 0x4d, 0x6f, 0x8a, 0xc5, 0x6d, 0x48, 0xb3, 0x86, 0x20, 0xb8, 0x4b, 0xb9, 0xf3, 0x36, + 0x1b, 0x14, 0xbe, 0x28, 0x20, 0xc4, 0x93, 0xbb, 0xfb, 0xb6, 0xa7, 0x67, 0x58, 0x9e, 0x26, 0x26, + 0xaa, 0xaa, 0xa4, 0xeb, 0xe2, 0x44, 0x7c, 0x55, 0xdb, 0x77, 0x7d, 0x7d, 0x90, 0xf9, 0xeb, 0x10, + 0x52, 0xdd, 0xdf, 0xcd, 0x77, 0xbe, 0x24, 0x22, 0x84, 0xbf, 0x89, 0x93, 0x12, 0xbd, 0xc4, 0xf8, + 0x9f, 0x12, 0x27, 0xc4, 0xf8, 0x92, 0xf5, 0x5c, 0x31, 0x61, 0x05, 0x55, 0xe1, 0x01, 0x20, 0xac, + 0xba, 0xad, 0xd3, 0x15, 0xde, 0x55, 0x20, 0x81, 0x48, 0x7f, 0xa8, 0xbe, 0xe1, 0x00, 0xcd, 0x62, + 0x7c, 0x20, 0x0b, 0x8e, 0xaa, 0xab, 0x5a, 0xbf, 0x84, 0x4b, 0x5a, 0xf1, 0x02, 0x7e, 0x20, 0x8d, + 0x2a, 0xf5, 0x5c, 0x4d, 0x5f, 0x89, 0x13, 0xc4, 0x08, 0x20, 0xb7, 0x15, 0xdf, 0x04, 0x22, 0x08, + 0x4b, 0xdf, 0x05, 0x21, 0x1f, 0x11, 0xf7, 0xbd, 0xf1, 0x22, 0x38, 0x81, 0x35, 0x89, 0x35, 0xde, + 0xfc, 0x4f, 0x13, 0x65, 0x77, 0xf0, 0x8f, 0x84, 0x6e, 0xb4, 0xb8, 0x63, 0xc3, 0x10, 0xe8, 0x88, + 0xbd, 0x77, 0x75, 0x55, 0xe1, 0xd3, 0x16, 0xfc, 0x3b, 0xc5, 0xef, 0x77, 0x9b, 0x38, 0x40, 0x33, + 0xc4, 0x89, 0x45, 0x7a, 0xc2, 0x04, 0x14, 0x2b, 0x7b, 0xf1, 0x20, 0x84, 0x4a, 0xae, 0xe5, 0x61, + 0x02, 0x12, 0x7f, 0xf0, 0x8d, 0x44, 0x09, 0xf0, 0x8f, 0x08, 0x78, 0x64, 0x48, 0x91, 0x7b, 0xab, + 0xdd, 0xf8, 0x81, 0x73, 0xe7, 0x55, 0x55, 0x51, 0x22, 0x6f, 0xa3, 0x3f, 0xd6, 0xab, 0x12, 0x84, + 0xd7, 0x12, 0x19, 0xe1, 0x90, 0xc9, 0x08, 0xaa, 0xbc, 0x40, 0x64, 0x13, 0x88, 0x68, 0x40, 0xfe, + 0x6c, 0xe7, 0xf8, 0x6e, 0x0e, 0xda, 0xe2, 0x00, 0x30, 0x0e, 0xa4, 0xa1, 0x48, 0xc7, 0x70, 0x63, + 0x6a, 0xda, 0x78, 0x72, 0x22, 0x0b, 0x77, 0x7b, 0x1b, 0x75, 0xee, 0x20, 0x22, 0x63, 0xb6, 0xba, + 0xc4, 0x78, 0x8f, 0x13, 0xc4, 0x51, 0x1f, 0xc4, 0x1b, 0x7b, 0xe2, 0x75, 0xc2, 0x22, 0x5e, 0x72, + 0x0c, 0x4a, 0x41, 0x77, 0xd8, 0xaf, 0xc2, 0x3f, 0x12, 0xa8, 0xef, 0x05, 0x01, 0x0f, 0x12, 0x08, + 0xef, 0x7f, 0x4b, 0xc1, 0x15, 0xdd, 0xdd, 0xf8, 0x8f, 0x11, 0x92, 0x24, 0x33, 0xc4, 0x02, 0x10, + 0xb8, 0xe5, 0x37, 0xa9, 0xe1, 0x5d, 0xc5, 0x43, 0x9b, 0xd1, 0xff, 0x12, 0x0a, 0x05, 0x93, 0xa9, + 0x58, 0x97, 0x55, 0x58, 0x10, 0xba, 0x1a, 0xe0, 0x90, 0x9b, 0x19, 0xff, 0x71, 0x00, 0x87, 0x89, + 0xdc, 0x48, 0x97, 0xdd, 0xfc, 0xd7, 0x77, 0x7f, 0x2e, 0x4f, 0x4f, 0x86, 0x41, 0x6d, 0xdf, 0x5a, + 0xab, 0xf1, 0x02, 0x41, 0x15, 0xef, 0xae, 0x22, 0x09, 0xca, 0xef, 0x15, 0xb7, 0x6e, 0xfc, 0x48, + 0x47, 0xe6, 0xdb, 0x7e, 0x20, 0x10, 0x05, 0x04, 0xbd, 0xdd, 0xdd, 0xee, 0xe2, 0xb7, 0x7b, 0xdf, + 0x13, 0x84, 0x8a, 0xfc, 0xd4, 0x48, 0x9a, 0xc4, 0xd7, 0x14, 0x6b, 0xbd, 0xee, 0xf8, 0x99, 0xbb, + 0xbf, 0x96, 0xca, 0xee, 0xe2, 0x44, 0x94, 0xea, 0xaa, 0xaa, 0x22, 0x41, 0x11, 0x5f, 0x88, 0x08, + 0x98, 0x53, 0xbb, 0x8a, 0xfc, 0xe2, 0xe0, 0xe0, 0xb7, 0xf7, 0xe1, 0x98, 0x80, 0xc8, 0x29, 0x34, + 0x40, 0xfb, 0x96, 0xee, 0x89, 0xe2, 0x47, 0xf5, 0xf6, 0x55, 0x5a, 0xa0, 0xb3, 0x28, 0xd3, 0x83, + 0xfe, 0xff, 0xfa, 0x23, 0xdf, 0x2d, 0xef, 0xf0, 0x50, 0x54, 0xdb, 0xef, 0x77, 0xf1, 0x20, 0xa2, + 0xf7, 0xde, 0xef, 0xc4, 0xc1, 0x1d, 0xef, 0x7e, 0x26, 0x12, 0xbb, 0xbb, 0xbb, 0xbf, 0x11, 0x09, + 0x97, 0x77, 0xdd, 0xf1, 0x00, 0x87, 0x89, 0x0c, 0x18, 0x95, 0xab, 0xc4, 0xc9, 0x89, 0x04, 0xf7, + 0xdd, 0xef, 0xaf, 0x11, 0xc4, 0xfc, 0x4d, 0x70, 0x91, 0x55, 0x56, 0xb1, 0x7e, 0x27, 0xc4, 0x48, + 0x31, 0x4a, 0xc2, 0xf8, 0x40, 0x48, 0xc8, 0xac, 0xfc, 0x75, 0x4b, 0x6a, 0xe6, 0xfe, 0xdd, 0xcf, + 0xf2, 0xf9, 0x1f, 0xf0, 0xc6, 0x24, 0x16, 0x12, 0x2b, 0x77, 0x4e, 0x30, 0x6c, 0xc4, 0x3e, 0xdf, + 0x07, 0x10, 0x11, 0x10, 0x57, 0xf7, 0xbb, 0xbb, 0xfd, 0x96, 0xf7, 0xc4, 0x88, 0x2e, 0xf7, 0xe1, + 0x19, 0x22, 0x44, 0x70, 0xc8, 0x60, 0x41, 0xdd, 0xde, 0xfb, 0xe2, 0x6e, 0xee, 0xfc, 0x40, 0x81, + 0x37, 0xdd, 0xef, 0xf1, 0x17, 0x77, 0x77, 0xbb, 0xf1, 0x05, 0xbd, 0xdd, 0xe2, 0x65, 0x89, 0x12, + 0x14, 0xbe, 0xee, 0xef, 0xb4, 0xd3, 0xdd, 0xde, 0xbe, 0x0b, 0x6e, 0xfb, 0xbd, 0x13, 0xfd, 0x6f, + 0x5c, 0xbb, 0xbd, 0xc4, 0x57, 0xbc, 0x48, 0x27, 0xaa, 0xad, 0x55, 0x57, 0xb8, 0x88, 0x22, 0x15, + 0x02, 0x6b, 0xb1, 0xf0, 0xba, 0xa9, 0x2d, 0xc2, 0x01, 0x10, 0xe9, 0x7a, 0xd7, 0x52, 0xf3, 0xfa, + 0x75, 0xa7, 0x44, 0x7f, 0x87, 0x1e, 0xef, 0xc2, 0xd8, 0x91, 0x82, 0x17, 0x77, 0x12, 0x30, 0x9f, + 0x1d, 0xf9, 0x7b, 0xaf, 0x5c, 0x20, 0x08, 0x5d, 0xff, 0xf8, 0x9f, 0x94, 0xeb, 0x5e, 0x26, 0x58, + 0xd2, 0x08, 0xf9, 0xa2, 0x3e, 0x27, 0xe1, 0x12, 0xbd, 0xf7, 0xbb, 0xbd, 0xf8, 0x85, 0x7a, 0xeb, + 0xdc, 0x4e, 0xa2, 0x75, 0xcb, 0x77, 0x7f, 0x90, 0xae, 0xee, 0xeb, 0x11, 0xe2, 0x38, 0x8f, 0x10, + 0x10, 0x36, 0xb1, 0x7c, 0x44, 0x95, 0x55, 0xf1, 0x1f, 0x35, 0x6a, 0xbc, 0x21, 0xc2, 0x21, 0x92, + 0x93, 0x55, 0xc2, 0x02, 0x02, 0x62, 0x35, 0x58, 0xae, 0x5f, 0xe6, 0x12, 0x9b, 0x78, 0x53, 0x98, + 0xdc, 0xbf, 0x08, 0x06, 0x42, 0x04, 0x52, 0xdc, 0x43, 0xd6, 0xa9, 0xd5, 0x6e, 0x20, 0x4f, 0x88, + 0xfa, 0x1a, 0xf7, 0x13, 0x54, 0x76, 0xf9, 0x88, 0xef, 0x7e, 0x20, 0xb7, 0x77, 0x7c, 0x48, 0x9f, + 0x8b, 0xaa, 0xfb, 0xbe, 0x24, 0x49, 0x4a, 0xce, 0xff, 0x66, 0xdd, 0xfd, 0xde, 0xfc, 0x47, 0xe0, + 0xa0, 0x4d, 0xd3, 0xbd, 0xdd, 0xfe, 0x4b, 0xde, 0xb1, 0x24, 0x2a, 0xaa, 0xaf, 0x13, 0x5c, 0x86, + 0xad, 0x5e, 0x27, 0xc4, 0xf8, 0x40, 0xd5, 0x5f, 0xc1, 0x41, 0x55, 0x7d, 0x57, 0xb8, 0x90, 0xc9, + 0x06, 0x45, 0xba, 0x16, 0x10, 0x08, 0x02, 0xbb, 0x6e, 0x87, 0x07, 0xde, 0x1d, 0x0a, 0xd7, 0x77, + 0x73, 0xd0, 0xa7, 0x21, 0x25, 0xf1, 0xf5, 0xf2, 0x94, 0x5d, 0x35, 0xf1, 0x15, 0x13, 0xac, 0x48, + 0x98, 0xda, 0xe5, 0xb9, 0x94, 0xaf, 0x89, 0xd7, 0x42, 0x7b, 0x89, 0x13, 0xe2, 0x3c, 0x48, 0x24, + 0xea, 0xbd, 0xf2, 0x5d, 0xdd, 0xf1, 0x22, 0x1d, 0xdd, 0xdf, 0xd5, 0xf8, 0x88, 0x21, 0xbb, 0xef, + 0x51, 0x10, 0x4b, 0x7b, 0xdd, 0xde, 0xff, 0x05, 0x3b, 0xae, 0xf7, 0xbb, 0xdf, 0xe0, 0x86, 0xc6, + 0xc7, 0x77, 0xa8, 0x8d, 0x71, 0x75, 0x55, 0x55, 0x5f, 0xcd, 0xaa, 0xfc, 0x4e, 0xab, 0x5d, 0x7c, + 0xd5, 0x5f, 0x89, 0xbc, 0x4b, 0x20, 0xaf, 0xf8, 0x23, 0xad, 0x57, 0xb8, 0x91, 0x3e, 0x08, 0x51, + 0x8e, 0x0f, 0x82, 0x31, 0x38, 0xab, 0xbc, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1b, 0x0d, + 0xb1, 0xa0, 0x28, 0xf4, 0x3f, 0xa0, 0xd6, 0x05, 0x10, 0x86, 0x1e, 0x90, 0x42, 0x41, 0xff, 0xc1, + 0xbd, 0x7f, 0x5d, 0x3f, 0x83, 0x50, 0xec, 0x40, 0x00, 0x26, 0xa3, 0x77, 0x92, 0x3a, 0x7a, 0xff, + 0xee, 0xdc, 0x7b, 0x0c, 0x80, 0x1f, 0x60, 0x1f, 0x8b, 0x7c, 0xfe, 0x1c, 0xc1, 0xd4, 0xd0, 0x6c, + 0x1f, 0xfc, 0xf1, 0x27, 0xc1, 0x9f, 0xb8, 0x15, 0x62, 0xdf, 0x15, 0x7c, 0x0a, 0x00, 0xa1, 0x0b, + 0xe8, 0xa1, 0xd9, 0x08, 0x5d, 0xf5, 0x78, 0x29, 0x0e, 0x31, 0xc0, 0x00, 0x7e, 0x81, 0xe4, 0x7e, + 0x64, 0x19, 0xf5, 0xe3, 0xef, 0x83, 0x6b, 0x87, 0x2f, 0xf9, 0xe7, 0xb6, 0x70, 0x75, 0x72, 0x92, + 0xb9, 0xbc, 0x5f, 0x97, 0xe0, 0xe4, 0x1c, 0x85, 0x08, 0x4f, 0xb3, 0x1c, 0xa2, 0x25, 0x38, 0x00, + 0x09, 0x10, 0x6b, 0x25, 0x02, 0xa5, 0x16, 0xaf, 0x90, 0xe8, 0xfb, 0x98, 0xc7, 0x6f, 0x15, 0x71, + 0x71, 0x00, 0xa4, 0x13, 0x14, 0x47, 0xc9, 0x8d, 0xcc, 0xee, 0x29, 0x53, 0xe1, 0x28, 0x56, 0x74, + 0x46, 0x11, 0x0c, 0x04, 0xeb, 0x4b, 0x2e, 0x25, 0x97, 0xe3, 0xf2, 0xec, 0x33, 0x09, 0x32, 0x34, + 0xfe, 0x9f, 0xe3, 0x30, 0x35, 0x97, 0x19, 0xa0, 0xab, 0x82, 0x73, 0x41, 0xe7, 0xe9, 0xd6, 0xa3, + 0x19, 0xb8, 0x80, 0x80, 0x50, 0x51, 0x60, 0x31, 0xdb, 0x89, 0x01, 0xc2, 0xab, 0xc2, 0x8a, 0x6c, + 0x60, 0xb0, 0x33, 0xc7, 0x0b, 0x07, 0x62, 0xbc, 0x1d, 0x0b, 0x85, 0x9a, 0x1c, 0x03, 0xac, 0xf0, + 0x88, 0x2b, 0x9f, 0xc6, 0x20, 0x2b, 0x04, 0xb1, 0x95, 0x80, 0x54, 0xcb, 0x00, 0x02, 0x50, 0x72, + 0xbb, 0x75, 0x6b, 0xf7, 0x06, 0x19, 0x60, 0xc4, 0x49, 0x86, 0xf1, 0xd4, 0xfc, 0x18, 0xc1, 0x20, + 0xc2, 0x48, 0xf9, 0x53, 0x22, 0xae, 0x0a, 0x42, 0x84, 0xcb, 0x83, 0xcb, 0x48, 0xa2, 0x99, 0x0e, + 0x36, 0x3f, 0x1d, 0xce, 0x1c, 0x2d, 0x97, 0xcf, 0x17, 0x05, 0x00, 0x84, 0x13, 0xf5, 0x53, 0x72, + 0x50, 0x0e, 0x22, 0xc8, 0x94, 0xbe, 0x1b, 0x67, 0x00, 0x06, 0x5a, 0x64, 0x46, 0x9b, 0x12, 0xb1, + 0x57, 0xff, 0x95, 0x00, 0xf5, 0x0f, 0x23, 0xef, 0x95, 0x67, 0x4f, 0xb7, 0x05, 0x58, 0x94, 0x37, + 0xb8, 0x98, 0x50, 0x20, 0x9b, 0xae, 0xdf, 0xc4, 0x0f, 0x38, 0x71, 0x49, 0xcd, 0xd6, 0x29, 0xc3, + 0xcb, 0x06, 0x78, 0xe1, 0xe0, 0x2c, 0x7b, 0x84, 0x44, 0x0c, 0xcf, 0x33, 0xb8, 0x24, 0x0b, 0x0a, + 0x4a, 0x54, 0x9d, 0x5c, 0xc4, 0xa9, 0x78, 0xba, 0xe2, 0x02, 0x12, 0x61, 0x1e, 0x0c, 0x04, 0x8f, + 0x26, 0x88, 0xd9, 0xa9, 0x75, 0x5f, 0x12, 0x20, 0xb5, 0x78, 0xb8, 0x80, 0xe2, 0xc5, 0xe0, 0xa8, + 0x59, 0x63, 0x1f, 0x57, 0xce, 0xe0, 0xbb, 0xbb, 0xb8, 0xad, 0xdf, 0x82, 0x90, 0x80, 0xf1, 0x09, + 0x24, 0xf1, 0x1c, 0x1e, 0x59, 0x33, 0x02, 0xe6, 0xe5, 0x26, 0x92, 0x0e, 0x30, 0x52, 0x08, 0x41, + 0x49, 0x07, 0x2b, 0x42, 0xf6, 0x8e, 0x37, 0x3c, 0x68, 0x61, 0x94, 0xee, 0x78, 0xcd, 0xcf, 0x75, + 0x9f, 0xa0, 0xaf, 0x07, 0x20, 0xa4, 0xa2, 0xfc, 0x77, 0xc2, 0x16, 0x09, 0x05, 0x31, 0x6c, 0x5e, + 0xff, 0x71, 0xae, 0xc3, 0x6c, 0x80, 0x42, 0x0b, 0xd2, 0x3f, 0x78, 0xb7, 0x6c, 0x2a, 0x66, 0x0d, + 0x07, 0x30, 0x0f, 0x70, 0x50, 0x7f, 0x0e, 0x5c, 0xc0, 0xbe, 0xef, 0xa2, 0xa2, 0xe1, 0x80, 0x42, + 0x09, 0x82, 0x27, 0xdb, 0x98, 0xcc, 0xcd, 0x5f, 0x49, 0x10, 0x24, 0xa1, 0x2b, 0xbf, 0xc1, 0x48, + 0xf2, 0xb0, 0x6c, 0x56, 0x6c, 0xed, 0xd6, 0xf7, 0x3c, 0x33, 0xc4, 0xf8, 0x91, 0x03, 0x86, 0x43, + 0x42, 0x8e, 0x21, 0xe5, 0x13, 0x40, 0x9b, 0x4f, 0x64, 0x07, 0xe3, 0xdb, 0xfd, 0x76, 0x42, 0x79, + 0xe0, 0xe0, 0x4c, 0x11, 0xf4, 0x13, 0x68, 0x88, 0x40, 0x1c, 0x82, 0x61, 0xc2, 0xea, 0x4c, 0x9a, + 0xaa, 0x8e, 0xef, 0x12, 0x12, 0x25, 0x69, 0xac, 0x5f, 0xec, 0x5d, 0x72, 0xb3, 0x78, 0x82, 0x0a, + 0xaa, 0xf0, 0x84, 0xa7, 0x4d, 0xdd, 0xf1, 0x01, 0x06, 0x75, 0xd7, 0x10, 0x10, 0x30, 0x8e, 0x30, + 0x83, 0x08, 0x04, 0x47, 0x12, 0x20, 0x78, 0x36, 0xd9, 0x2f, 0x40, 0x28, 0xc4, 0x80, 0xe2, 0xd5, + 0x7e, 0x2c, 0xe6, 0xf2, 0xf9, 0xc3, 0x22, 0x10, 0x57, 0xab, 0x0c, 0x41, 0x56, 0x0a, 0x01, 0x50, + 0xea, 0xd5, 0x0d, 0x75, 0x55, 0x96, 0x6c, 0x36, 0xcc, 0x00, 0x40, 0xde, 0x7c, 0x48, 0xf5, 0xe2, + 0xf4, 0x39, 0x1f, 0x4e, 0xae, 0x33, 0x75, 0xca, 0x18, 0xfd, 0xdf, 0xdf, 0x84, 0x02, 0x25, 0x1b, + 0xa1, 0xaa, 0x84, 0x04, 0x98, 0xd0, 0xd9, 0x4c, 0x82, 0x17, 0x38, 0xf3, 0xc4, 0x19, 0x22, 0x62, + 0xea, 0xbf, 0x13, 0xc4, 0x06, 0x4d, 0xaa, 0xfc, 0x23, 0x6c, 0xa4, 0x57, 0x1c, 0x58, 0x49, 0x07, + 0x12, 0xc0, 0xd8, 0x3b, 0x69, 0x48, 0xf2, 0xdd, 0x9a, 0xbc, 0x48, 0x28, 0x82, 0xd8, 0x40, 0x23, + 0xc4, 0x84, 0x06, 0x55, 0xc5, 0xf8, 0x9f, 0x89, 0xf5, 0x55, 0x59, 0xbf, 0x88, 0x9b, 0xa4, 0x2d, + 0x61, 0x18, 0x28, 0x2e, 0x2d, 0x25, 0x5a, 0x1f, 0x7c, 0x86, 0xa8, 0x03, 0x00, 0x5b, 0xd6, 0x27, + 0xc4, 0x04, 0x8a, 0x14, 0x54, 0x51, 0x3a, 0x95, 0x58, 0x1d, 0xcb, 0x4e, 0x7c, 0x10, 0x31, 0xa0, + 0x8e, 0xd9, 0xaf, 0x7c, 0x16, 0xc1, 0x40, 0x21, 0x04, 0x63, 0x32, 0xe0, 0xaf, 0xb8, 0x40, 0x22, + 0x32, 0x62, 0x48, 0xe3, 0xe7, 0x90, 0xc9, 0xe2, 0xc3, 0x7f, 0x02, 0x42, 0xad, 0x35, 0x12, 0x4d, + 0xde, 0xd7, 0x84, 0x03, 0x21, 0x48, 0xa6, 0x24, 0xb1, 0x2e, 0x44, 0x23, 0x81, 0xa0, 0xca, 0x99, + 0xc5, 0x7a, 0xd7, 0xbc, 0x22, 0x30, 0xaa, 0x22, 0xab, 0xfb, 0xa1, 0x16, 0x2b, 0xb5, 0x15, 0x5a, + 0x17, 0x11, 0xeb, 0x3c, 0x48, 0x29, 0xbc, 0xf9, 0x10, 0xd0, 0xf5, 0x84, 0x7c, 0xee, 0x74, 0xf8, + 0x53, 0x8b, 0xd6, 0xb2, 0x60, 0x8c, 0x3a, 0x94, 0x99, 0xbf, 0xc7, 0x88, 0x55, 0x55, 0xe5, 0xc1, + 0x5a, 0xf5, 0xf8, 0x44, 0x30, 0xc6, 0x93, 0x46, 0xf4, 0x5a, 0xb7, 0xf0, 0x45, 0xd0, 0xda, 0x8b, + 0x82, 0x00, 0xc8, 0x48, 0x28, 0x98, 0x97, 0xa2, 0xa9, 0x53, 0x5e, 0x22, 0x30, 0xa5, 0x8f, 0xb8, + 0xaf, 0x5b, 0x7c, 0xb9, 0xc4, 0x09, 0x04, 0xfb, 0xc4, 0x3e, 0x0f, 0x3f, 0x07, 0x9f, 0xbf, 0x08, + 0x88, 0x2d, 0xdc, 0xb1, 0xbe, 0x24, 0x41, 0x22, 0xea, 0x2e, 0xb8, 0x81, 0x01, 0x22, 0xb5, 0xa5, + 0xbb, 0xac, 0x47, 0xd0, 0xfe, 0xe1, 0x9c, 0x16, 0x42, 0x01, 0x12, 0x0e, 0xad, 0x71, 0x31, 0x82, + 0x9e, 0x98, 0xae, 0xe5, 0x8b, 0xd9, 0x8a, 0x33, 0x7c, 0xf0, 0x58, 0x33, 0x10, 0xff, 0x81, 0xf0, + 0x53, 0x17, 0xa6, 0x86, 0x11, 0x10, 0x11, 0xdc, 0xfd, 0xaa, 0x0e, 0xd8, 0x1d, 0x2f, 0xc6, 0xdf, + 0xb0, 0x9d, 0x81, 0xd9, 0xb0, 0x76, 0xbd, 0x2a, 0x1e, 0xb9, 0x82, 0xcc, 0xd7, 0x0c, 0x84, 0x42, + 0x85, 0x14, 0x62, 0xb2, 0xc6, 0x28, 0xc5, 0x65, 0xb1, 0x58, 0xa3, 0x71, 0x59, 0xef, 0xc5, 0x62, + 0xb6, 0x9d, 0xf8, 0x40, 0x40, 0xe8, 0xa3, 0x89, 0x7d, 0xdd, 0xf5, 0xd7, 0x84, 0x44, 0x12, 0xaa, + 0xe2, 0xbc, 0x44, 0x21, 0xc5, 0x65, 0xc1, 0x59, 0x6e, 0xef, 0x8a, 0xf8, 0x91, 0xe2, 0xee, 0xee, + 0xf7, 0xae, 0xea, 0x0c, 0x30, 0x5d, 0x12, 0x10, 0x1e, 0x2a, 0x2b, 0xb8, 0x10, 0xbd, 0x63, 0x0c, + 0xff, 0xc8, 0x30, 0x3d, 0x4d, 0x06, 0xbf, 0xb9, 0xd6, 0x59, 0x7c, 0x7b, 0x05, 0xdc, 0x7e, 0x18, + 0x18, 0x61, 0x63, 0x8f, 0xbe, 0xcb, 0x79, 0x79, 0xf7, 0x2d, 0x5a, 0x41, 0x79, 0x6d, 0xdd, 0xf2, + 0xe3, 0xf1, 0x03, 0x24, 0xe0, 0xa1, 0x0f, 0x3f, 0x67, 0x0b, 0x07, 0x8f, 0xee, 0xe5, 0xb6, 0x9d, + 0xef, 0xf1, 0x47, 0x86, 0xcf, 0x5d, 0x2b, 0x54, 0x9f, 0x12, 0x2c, 0x56, 0xe2, 0xb7, 0xba, 0xba, + 0xc4, 0x94, 0x46, 0xee, 0x08, 0x3a, 0x09, 0xf4, 0x6c, 0x20, 0x25, 0x8c, 0x66, 0x7a, 0x7c, 0x47, + 0x11, 0x1e, 0x65, 0x4f, 0x3d, 0xca, 0xeb, 0x5a, 0xf1, 0x15, 0xc9, 0x7d, 0xb5, 0x89, 0xae, 0x28, + 0xcf, 0x7c, 0x57, 0xe1, 0x89, 0x4a, 0xf3, 0xc0, 0xb9, 0xe8, 0x2b, 0xd0, 0x55, 0x08, 0x09, 0x41, + 0x0e, 0xf1, 0x1f, 0x31, 0x0a, 0xc6, 0xbc, 0x40, 0x40, 0x84, 0x84, 0x6d, 0x59, 0x96, 0x7b, 0x9c, + 0xcc, 0x06, 0xda, 0xdd, 0xe2, 0x04, 0x84, 0x0b, 0x9b, 0x0d, 0x8c, 0xc6, 0x4a, 0x14, 0x96, 0x82, + 0xbe, 0xb1, 0x3f, 0x30, 0xd7, 0xdd, 0x61, 0x0b, 0x84, 0x28, 0x57, 0x41, 0x4c, 0x40, 0x90, 0x51, + 0x9b, 0xe6, 0xdd, 0xe5, 0x7c, 0xbb, 0xda, 0xe2, 0x02, 0x64, 0xaa, 0xac, 0x18, 0xd4, 0xb5, 0x92, + 0x62, 0x0a, 0x11, 0xdd, 0xf1, 0x21, 0x9f, 0x08, 0xf1, 0x21, 0x1e, 0x24, 0x22, 0x28, 0x53, 0xbf, + 0x7b, 0xf1, 0x3c, 0x40, 0x9c, 0x4b, 0xc1, 0x2c, 0x4f, 0xe1, 0x32, 0x6e, 0xd5, 0xaa, 0xe2, 0x2f, + 0xbb, 0xbc, 0x48, 0x27, 0xdd, 0x3a, 0x6e, 0x9f, 0xb8, 0x88, 0xc2, 0x0b, 0xa8, 0xba, 0x88, 0x58, + 0x54, 0x99, 0xb7, 0x32, 0x23, 0x9b, 0x69, 0xbe, 0xff, 0x28, 0x9a, 0x88, 0xc2, 0xc9, 0x88, 0xf0, + 0x87, 0x11, 0xf1, 0x15, 0xcc, 0x4a, 0xd7, 0x10, 0x24, 0xa6, 0x5a, 0xae, 0x20, 0x4c, 0x12, 0x42, + 0x01, 0x1f, 0x8a, 0x3d, 0x59, 0xab, 0xd5, 0x78, 0x9f, 0xb1, 0x25, 0xcf, 0x89, 0xfc, 0x24, 0x2a, + 0xac, 0x75, 0xaf, 0xc1, 0x54, 0x5c, 0xbd, 0x6a, 0x6d, 0x3d, 0x55, 0x57, 0xbe, 0x13, 0xaa, 0xf6, + 0xad, 0xf9, 0x8e, 0xf7, 0xf1, 0x25, 0x3b, 0xbd, 0xf1, 0x3e, 0x26, 0x62, 0xde, 0xea, 0x20, 0x47, + 0xd5, 0xee, 0x20, 0x32, 0x22, 0xaa, 0xab, 0x03, 0x04, 0x87, 0xd6, 0x67, 0x8c, 0x1d, 0x2b, 0x2b, + 0x69, 0x55, 0x57, 0x55, 0xf0, 0xc4, 0x26, 0x47, 0x9b, 0x2f, 0xbf, 0x12, 0x09, 0x45, 0xbb, 0xf7, + 0x68, 0xf9, 0x1c, 0x82, 0x0e, 0x69, 0xf1, 0x95, 0xf8, 0x94, 0x4e, 0xe2, 0x03, 0x3e, 0x11, 0xa8, + 0x98, 0x23, 0x12, 0xda, 0xef, 0xc4, 0x09, 0x04, 0x42, 0x1d, 0xfe, 0xf8, 0x2d, 0xad, 0x76, 0xea, + 0xff, 0x25, 0x57, 0xe2, 0x7e, 0x28, 0xae, 0xfb, 0xdf, 0x89, 0x12, 0xcf, 0x7b, 0xe2, 0x35, 0xd9, + 0x1e, 0xf3, 0xf1, 0x1a, 0xad, 0x47, 0x11, 0x33, 0x84, 0x21, 0x71, 0x9c, 0xdd, 0xfb, 0xf6, 0x9c, + 0x55, 0xfe, 0x10, 0x82, 0x42, 0xd6, 0x45, 0x11, 0x43, 0xd1, 0x1e, 0x22, 0xef, 0x77, 0xc4, 0x04, + 0x51, 0xde, 0xb9, 0x04, 0x3b, 0xbf, 0x84, 0x45, 0x09, 0x5a, 0xea, 0xab, 0x89, 0x84, 0xeb, 0x5e, + 0xef, 0xe4, 0x32, 0xd5, 0x49, 0x88, 0x28, 0xd5, 0xaf, 0x08, 0xf8, 0x44, 0x41, 0x62, 0xb7, 0x7f, + 0x82, 0x1b, 0xdf, 0xd5, 0xdd, 0xef, 0x26, 0x27, 0x89, 0x13, 0xc4, 0x78, 0x64, 0x22, 0x22, 0xab, + 0x56, 0x8b, 0x4f, 0x08, 0x48, 0x39, 0xb9, 0x55, 0xc4, 0x41, 0x19, 0xf1, 0x79, 0x52, 0x1d, 0xfc, + 0x40, 0x66, 0xe2, 0x65, 0x11, 0x5a, 0xf8, 0x4c, 0x5a, 0xd2, 0xee, 0xf8, 0x81, 0x26, 0xee, 0xfc, + 0x47, 0xc9, 0x5a, 0xfc, 0xd7, 0x7f, 0xcc, 0x77, 0x77, 0x7f, 0x31, 0x39, 0xd4, 0x62, 0x03, 0x3c, + 0x14, 0x82, 0x11, 0x27, 0x77, 0xde, 0xfc, 0x46, 0x5c, 0x4f, 0xd1, 0x9f, 0x89, 0xdc, 0x22, 0x19, + 0x75, 0x5a, 0xe1, 0x08, 0x27, 0x35, 0x45, 0xd3, 0x5d, 0x4b, 0x7c, 0x37, 0xc7, 0x16, 0xc2, 0xdf, + 0x9c, 0x38, 0x28, 0x7e, 0x1c, 0xf2, 0xc4, 0x06, 0x08, 0x5d, 0xdb, 0xc4, 0x09, 0x75, 0xaf, 0xcb, + 0x77, 0x7b, 0x89, 0x8f, 0x13, 0xbb, 0xbb, 0xde, 0xf3, 0xa8, 0xe1, 0x1f, 0x8a, 0x35, 0xef, 0x77, + 0xe1, 0x80, 0xc0, 0x8b, 0xa3, 0xc7, 0xfd, 0xed, 0xbc, 0x23, 0xc4, 0x86, 0x7c, 0x23, 0x5d, 0xdd, + 0xbf, 0x84, 0x64, 0xc3, 0x3c, 0x40, 0x44, 0x10, 0x8a, 0x91, 0x3c, 0xac, 0x1f, 0x0d, 0x8b, 0xc7, + 0x17, 0x3d, 0xc4, 0x3f, 0xe1, 0xae, 0x09, 0x0c, 0x9b, 0x6e, 0xb5, 0xc4, 0x06, 0x4c, 0x5b, 0xdd, + 0xc4, 0x88, 0xa8, 0x91, 0x35, 0x89, 0x26, 0xee, 0xfc, 0x22, 0x09, 0x6e, 0xee, 0xee, 0xee, 0xef, + 0xe2, 0x42, 0x76, 0xf7, 0x77, 0xf8, 0x9e, 0x24, 0x4f, 0x82, 0x00, 0x88, 0xd3, 0xf7, 0x71, 0x58, + 0xad, 0xdd, 0xe7, 0xf7, 0xe2, 0x7e, 0x09, 0x04, 0x72, 0x77, 0xbc, 0x20, 0x88, 0xff, 0x15, 0x77, + 0x7d, 0xdd, 0xfd, 0x16, 0xbe, 0x09, 0xef, 0x7e, 0xac, 0x6f, 0xc4, 0x7c, 0x4b, 0x2b, 0xde, 0xe2, + 0x35, 0x10, 0x11, 0x05, 0x43, 0x8b, 0xd3, 0xdb, 0x5a, 0xbb, 0x97, 0x96, 0xf2, 0xfa, 0x17, 0xa8, + 0x67, 0x82, 0x71, 0x0d, 0xa9, 0x98, 0xe2, 0x9b, 0x62, 0x9c, 0x5f, 0x14, 0x5b, 0xbb, 0xbe, 0xfe, + 0xaf, 0x51, 0x02, 0x2b, 0x11, 0x51, 0x22, 0x7c, 0x4a, 0xbf, 0x13, 0xf1, 0x3c, 0x4f, 0xc2, 0x3c, + 0x23, 0x21, 0x5e, 0xfc, 0x48, 0x46, 0x48, 0x9f, 0xc5, 0xdd, 0xf7, 0x77, 0x7f, 0x77, 0x6d, 0xfe, + 0x4b, 0xef, 0x88, 0xcb, 0xc1, 0x08, 0x85, 0x5a, 0x95, 0xb8, 0x81, 0x20, 0xae, 0xe2, 0xb1, 0x58, + 0xad, 0x4f, 0x8b, 0x2d, 0x95, 0x44, 0x8a, 0x45, 0x74, 0x31, 0xc2, 0x24, 0x76, 0xba, 0x9c, 0xde, + 0xb8, 0xaf, 0x08, 0x06, 0x44, 0x14, 0xf9, 0xea, 0xbf, 0x21, 0xdd, 0xfc, 0x4c, 0x12, 0x5d, 0xdd, + 0xea, 0x68, 0x90, 0x82, 0x2a, 0x3b, 0xe2, 0x47, 0x6e, 0xf7, 0xbb, 0xde, 0xfe, 0x08, 0xae, 0xf7, + 0x7f, 0x10, 0x22, 0xef, 0xde, 0xf8, 0x90, 0x41, 0xff, 0x9b, 0x5a, 0xa8, 0x44, 0x47, 0x13, 0xa8, + 0x8d, 0xf1, 0x77, 0x77, 0x77, 0x7b, 0xf1, 0x3c, 0x46, 0xb0, 0x8d, 0x77, 0x55, 0xf8, 0x92, 0x0c, + 0xa6, 0xa4, 0xf8, 0x81, 0x20, 0xa4, 0x49, 0xea, 0xba, 0x8c, 0xf5, 0xc7, 0x15, 0xc4, 0x0f, 0x73, + 0xd0, 0xbc, 0x20, 0x19, 0x62, 0x8b, 0x4f, 0x88, 0x08, 0xb3, 0xea, 0xea, 0x24, 0x22, 0xef, 0x7f, + 0x8b, 0x3b, 0xbb, 0xe6, 0xfa, 0x89, 0xf1, 0x22, 0x49, 0x55, 0xaf, 0x13, 0xf0, 0x44, 0x4d, 0xdf, + 0xb8, 0x90, 0x87, 0x12, 0x21, 0x5f, 0xc2, 0x15, 0xeb, 0x12, 0xbd, 0x71, 0x16, 0x57, 0xbb, 0x97, + 0x9a, 0xab, 0xf1, 0x3f, 0x2e, 0xaa, 0xbe, 0x12, 0xaa, 0xaa, 0xaa, 0xd7, 0x89, 0xbc, 0x48, 0x2a, + 0x15, 0x7a, 0xbb, 0x97, 0x96, 0xd3, 0x72, 0x42, 0xdf, 0xe0, 0x8c, 0x4e, 0x7e, 0xfd, 0x0a, 0x71, + 0x46, 0xe3, 0x49, 0x9c, 0x6a, 0x56, 0x70, 0x80, 0x44, 0x10, 0x93, 0xcb, 0xcf, 0x54, 0x40, 0x9a, + 0x89, 0xd4, 0x23, 0xbe, 0x85, 0xbd, 0x76, 0x45, 0xad, 0x61, 0x1f, 0xf1, 0x3e, 0x20, 0x4d, 0x72, + 0x9d, 0xde, 0xfc, 0x4f, 0x13, 0xe2, 0x44, 0xf1, 0x3f, 0x8b, 0x2d, 0x56, 0xb5, 0xae, 0x52, 0x56, + 0xbe, 0x42, 0xd5, 0x57, 0x12, 0x11, 0xac, 0x4f, 0xcc, 0x45, 0x5a, 0xae, 0x08, 0x84, 0x46, 0x71, + 0x85, 0xae, 0x10, 0x08, 0x0c, 0xcd, 0xba, 0xaa, 0xd3, 0x85, 0xab, 0xde, 0xe1, 0x48, 0x81, 0x20, + 0xa0, 0x9c, 0x5e, 0xaa, 0x2e, 0x52, 0xe2, 0x02, 0x32, 0x44, 0x88, 0x17, 0x7b, 0xbe, 0xef, 0xc4, + 0x89, 0x3e, 0x7e, 0xa3, 0xf9, 0x4a, 0xd1, 0xa0, 0xc9, 0x1b, 0x13, 0xf0, 0x5c, 0x25, 0xc5, 0x6e, + 0xef, 0x77, 0xaf, 0x93, 0xbb, 0xf1, 0x3e, 0x22, 0xa2, 0x75, 0xde, 0xef, 0xf7, 0xbd, 0xfc, 0x9a, + 0xd7, 0x11, 0x75, 0xaa, 0xf9, 0xba, 0xaf, 0x96, 0xaa, 0xb5, 0xd5, 0xb8, 0x91, 0x24, 0x22, 0xaf, + 0x89, 0xf8, 0x94, 0x4e, 0xf1, 0x3c, 0x40, 0x9e, 0x19, 0x0c, 0x82, 0x52, 0xaa, 0xd5, 0x57, 0xef, + 0x0c, 0x89, 0x11, 0x35, 0x64, 0xab, 0x88, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1c, 0x0e, + 0x30, 0xe8, 0x37, 0xd0, 0x47, 0xa0, 0x28, 0x3a, 0xc5, 0x84, 0x5e, 0x09, 0xc6, 0xab, 0xec, 0xac, + 0xa3, 0x38, 0x20, 0x68, 0xce, 0xbd, 0x05, 0x30, 0x80, 0x1a, 0x41, 0x60, 0x43, 0x89, 0xe2, 0x9b, + 0x61, 0x63, 0x50, 0x5e, 0xa7, 0x80, 0x01, 0x0e, 0x7e, 0x41, 0x53, 0x8a, 0xa3, 0xb8, 0x80, 0x30, + 0x8b, 0x30, 0x83, 0xc6, 0x55, 0xd1, 0xa4, 0x6d, 0xd5, 0xcb, 0x18, 0x65, 0x84, 0xc1, 0xaa, 0x65, + 0xff, 0xb7, 0xed, 0xec, 0x88, 0xe7, 0x29, 0x5b, 0xb6, 0x16, 0x65, 0xff, 0xa2, 0x35, 0x44, 0xe0, + 0xa6, 0x22, 0x14, 0x08, 0x6e, 0xe5, 0xb2, 0x60, 0x72, 0x15, 0x8a, 0xc6, 0xa2, 0xae, 0x17, 0x1c, + 0xbb, 0xc4, 0x0f, 0x18, 0xee, 0x18, 0x02, 0x40, 0x52, 0x5e, 0x2b, 0x3c, 0x59, 0x4d, 0xe0, 0xe9, + 0x61, 0x3c, 0x3d, 0xdd, 0x4e, 0x0f, 0x1d, 0xfb, 0x31, 0x2a, 0x3c, 0x74, 0x5c, 0xe0, 0x03, 0xc1, + 0x34, 0xd0, 0x63, 0xc0, 0x00, 0x94, 0x7a, 0x0c, 0x2f, 0x83, 0x08, 0x99, 0x9e, 0x83, 0x3f, 0x83, + 0xa9, 0xa2, 0x94, 0x92, 0xa0, 0x59, 0x55, 0xa6, 0x4b, 0xcc, 0x3d, 0xdd, 0xdd, 0x04, 0x51, 0x41, + 0xd7, 0xa2, 0x00, 0xa2, 0x12, 0x6b, 0x10, 0x0e, 0x88, 0x07, 0x74, 0xd3, 0x85, 0x94, 0x11, 0xe5, + 0xa3, 0xff, 0xe9, 0xf0, 0x82, 0x86, 0xfe, 0x8c, 0x73, 0x19, 0x31, 0x9f, 0xc0, 0xc1, 0x04, 0xda, + 0xd7, 0x14, 0xe9, 0x04, 0x15, 0x07, 0x18, 0xe0, 0x01, 0x2a, 0xb3, 0x23, 0x5b, 0x5b, 0xcd, 0xf1, + 0x43, 0x71, 0x27, 0xfb, 0x97, 0xd5, 0x35, 0x10, 0x8c, 0x2b, 0x3c, 0x23, 0x77, 0x3c, 0x28, 0x62, + 0xc0, 0x06, 0x25, 0xe7, 0x80, 0x0e, 0x25, 0x05, 0x07, 0x8e, 0x13, 0x9c, 0x3a, 0x4c, 0x5c, 0xf0, + 0x70, 0xb7, 0x6e, 0x70, 0xf2, 0x8f, 0x82, 0xd9, 0x41, 0x1d, 0x20, 0x2d, 0x30, 0x88, 0x31, 0x0a, + 0x4b, 0xe9, 0x1d, 0x50, 0xc2, 0x58, 0x65, 0x3d, 0x79, 0x66, 0x59, 0x96, 0x62, 0x9c, 0x8b, 0xa8, + 0xa7, 0xae, 0x0a, 0x37, 0xd0, 0xd6, 0xf0, 0x88, 0xa1, 0x57, 0x74, 0x04, 0x5e, 0x95, 0x4c, 0x75, + 0xfa, 0xe0, 0x80, 0x14, 0x94, 0xd7, 0x8d, 0xf1, 0x22, 0x47, 0x68, 0x9e, 0x3c, 0xa3, 0xa5, 0x8a, + 0x2a, 0x38, 0xe0, 0xa0, 0xc5, 0x62, 0xb7, 0xc2, 0x21, 0x10, 0xa6, 0xa2, 0x01, 0xc6, 0xe0, 0x83, + 0x81, 0x60, 0x0d, 0x59, 0x78, 0x97, 0x37, 0xaa, 0xf5, 0xc1, 0x80, 0x14, 0x46, 0x64, 0xe4, 0x22, + 0xb3, 0x05, 0xd4, 0x6c, 0xf7, 0x7e, 0x0a, 0xec, 0x71, 0x05, 0xc2, 0x34, 0x02, 0xb1, 0x96, 0x64, + 0xb0, 0x3a, 0x13, 0x85, 0xe2, 0xc0, 0x02, 0xd1, 0x19, 0x1a, 0xb2, 0x33, 0x5b, 0xff, 0xfb, 0xff, + 0xc1, 0x73, 0x81, 0x0a, 0x18, 0xa8, 0xd8, 0xfb, 0x10, 0x55, 0x0c, 0x45, 0x17, 0x83, 0xa5, 0xe0, + 0xd4, 0x2a, 0x49, 0xc3, 0x4e, 0x04, 0x10, 0xa0, 0xa8, 0xac, 0x3d, 0x8a, 0x2d, 0x68, 0x72, 0x82, + 0x3a, 0x2b, 0xcc, 0x7b, 0x63, 0x9b, 0x97, 0xca, 0xc4, 0x42, 0xc6, 0xce, 0x24, 0x40, 0x53, 0xa9, + 0x14, 0xe2, 0x2c, 0x17, 0x95, 0x92, 0xf4, 0xcf, 0x56, 0x53, 0xa0, 0xb3, 0xb8, 0x59, 0x97, 0x8a, + 0x6f, 0xc1, 0x44, 0x48, 0x4d, 0x6b, 0x5a, 0xab, 0xc4, 0x02, 0x41, 0x96, 0xe5, 0x7f, 0x70, 0x40, + 0x19, 0x10, 0x2a, 0xb4, 0x97, 0x57, 0xf0, 0x4a, 0x36, 0x3b, 0x67, 0xac, 0xee, 0xdd, 0xf0, 0xca, + 0x12, 0x01, 0xe4, 0x8c, 0xa5, 0xc9, 0xa7, 0xff, 0xf9, 0x51, 0xd6, 0x07, 0x10, 0x70, 0x0b, 0x84, + 0x05, 0xc5, 0x6f, 0xa9, 0xb9, 0xb8, 0xaa, 0x17, 0x57, 0x02, 0xc8, 0x40, 0x16, 0x0a, 0xae, 0x40, + 0xdb, 0x93, 0x11, 0x86, 0x5b, 0x74, 0x82, 0x12, 0xde, 0xe8, 0x11, 0x15, 0xbc, 0xf0, 0xbd, 0x15, + 0x89, 0xe3, 0x13, 0x3a, 0x3f, 0x07, 0x36, 0x58, 0x24, 0x87, 0xe5, 0x93, 0x82, 0x81, 0x76, 0x21, + 0x19, 0x57, 0xc1, 0x50, 0x71, 0x8b, 0x00, 0x19, 0x17, 0x5d, 0x6d, 0x3f, 0x77, 0xbf, 0xff, 0x65, + 0x0a, 0x9d, 0x7f, 0xfa, 0xd7, 0x11, 0x0a, 0x0a, 0x2b, 0x37, 0x85, 0xd4, 0x0f, 0xf5, 0x96, 0xb1, + 0x79, 0x7d, 0x8c, 0x1d, 0x5d, 0x8d, 0x18, 0x14, 0xcf, 0x1e, 0x20, 0x28, 0x47, 0x28, 0x8b, 0x53, + 0x33, 0xc6, 0xdf, 0x2f, 0xbb, 0x7f, 0x70, 0x20, 0x41, 0x58, 0x45, 0xde, 0xf9, 0x3f, 0x8d, 0x32, + 0x7a, 0xe0, 0xa2, 0xab, 0xda, 0x74, 0x45, 0x2e, 0x08, 0x01, 0x08, 0xa0, 0x95, 0x6b, 0xa6, 0xfc, + 0x43, 0x17, 0x6d, 0x34, 0xb0, 0x80, 0x67, 0x89, 0x0c, 0x9b, 0xc6, 0xaa, 0xc1, 0x80, 0x90, 0x88, + 0xa1, 0x3e, 0x30, 0x38, 0xea, 0x03, 0xcf, 0x03, 0x3e, 0x07, 0x91, 0x42, 0xfa, 0xca, 0xa0, 0x55, + 0x1d, 0xe4, 0xe0, 0xe9, 0xbe, 0x96, 0xfc, 0x10, 0xc1, 0x49, 0xd0, 0x0a, 0xd7, 0x53, 0x20, 0xfc, + 0xd6, 0x51, 0x52, 0x63, 0xe4, 0x5a, 0x16, 0xa7, 0x27, 0xbe, 0x7a, 0x0b, 0x31, 0x00, 0xaa, 0xa2, + 0x16, 0x17, 0x76, 0x1d, 0xec, 0x65, 0x2b, 0x88, 0xa0, 0xee, 0x91, 0x41, 0x76, 0x35, 0xcf, 0x10, + 0x3c, 0x85, 0xec, 0x53, 0xd5, 0x71, 0x7e, 0x20, 0x41, 0x82, 0x7c, 0xf6, 0xa1, 0x0f, 0xc4, 0x04, + 0x19, 0xdd, 0x2a, 0xbf, 0xc2, 0x62, 0xf1, 0xfc, 0xba, 0xd7, 0x08, 0x02, 0x10, 0x58, 0x45, 0x5a, + 0x75, 0x8d, 0x22, 0x25, 0x3f, 0x9e, 0xe0, 0xe0, 0x18, 0x84, 0x45, 0x06, 0xe8, 0xaf, 0x3e, 0x8a, + 0xe6, 0x8a, 0xc6, 0x04, 0xcd, 0xd3, 0xaf, 0xbe, 0x83, 0xdc, 0xda, 0xef, 0xe0, 0xc0, 0x20, 0x24, + 0x6b, 0x66, 0x21, 0x38, 0xc9, 0x96, 0x07, 0x70, 0x9d, 0x49, 0x7f, 0x49, 0x7c, 0x1c, 0x08, 0x82, + 0xbc, 0x4f, 0xc1, 0x38, 0x85, 0x27, 0x4b, 0x28, 0xc1, 0xb6, 0x2e, 0x3b, 0x78, 0x40, 0x29, 0x58, + 0x9e, 0x1a, 0x20, 0xa4, 0x55, 0x22, 0x6d, 0x15, 0x29, 0xf5, 0x0b, 0x17, 0x13, 0x20, 0x2b, 0x2c, + 0xfb, 0xc4, 0xf1, 0x02, 0x78, 0x91, 0x00, 0xb4, 0x81, 0xf2, 0x92, 0xd9, 0xe2, 0xe4, 0xc5, 0x9e, + 0xe2, 0x42, 0x06, 0x16, 0xab, 0x0b, 0xe9, 0xe6, 0x15, 0xa2, 0x5c, 0x32, 0x08, 0x01, 0x4d, 0x63, + 0x19, 0xc5, 0x2b, 0x06, 0xcf, 0xc1, 0x24, 0xf1, 0x98, 0x05, 0xe5, 0x3b, 0x36, 0x67, 0xb8, 0x80, + 0xc8, 0x21, 0x12, 0x80, 0x11, 0x87, 0xfe, 0x97, 0x31, 0x2f, 0xe8, 0x2c, 0x84, 0x04, 0x8a, 0xd8, + 0xa6, 0x5e, 0x03, 0xb5, 0xa6, 0x0e, 0xfc, 0x7b, 0x5a, 0x66, 0x20, 0x48, 0xb2, 0x77, 0xe4, 0xd4, + 0x67, 0xf8, 0x2a, 0xc6, 0x54, 0xc4, 0x2b, 0xd6, 0xb1, 0x77, 0x50, 0xbd, 0x03, 0x5a, 0x8e, 0xef, + 0x85, 0x0a, 0x43, 0x44, 0xc7, 0x9d, 0x25, 0x73, 0xa8, 0x0f, 0xe7, 0x51, 0xfc, 0x54, 0x31, 0x4f, + 0xa4, 0xa6, 0xcc, 0x55, 0x52, 0xba, 0xd7, 0x78, 0xef, 0x9f, 0x78, 0x90, 0x53, 0x51, 0x76, 0xa5, + 0x56, 0x19, 0x27, 0x7b, 0xec, 0xeb, 0xdf, 0x19, 0x29, 0x05, 0x04, 0x2b, 0x21, 0x11, 0xdf, 0x4d, + 0x55, 0x71, 0x06, 0x94, 0xaf, 0xe3, 0x08, 0xaa, 0xaa, 0xb4, 0xea, 0x9c, 0x9e, 0x2e, 0xef, 0xe1, + 0x12, 0x79, 0x70, 0x5d, 0x04, 0x2e, 0x6d, 0x10, 0xc2, 0xaf, 0x86, 0x41, 0x00, 0x81, 0x63, 0xda, + 0x86, 0x5c, 0x1e, 0x27, 0xcf, 0xd7, 0xe7, 0xfc, 0x14, 0x82, 0x0e, 0x08, 0x70, 0x57, 0x89, 0xe1, + 0x00, 0x88, 0x2a, 0x23, 0x04, 0x10, 0x7a, 0x60, 0xf3, 0x2a, 0xfa, 0x91, 0x45, 0xec, 0x3b, 0xee, + 0x7c, 0xdb, 0xee, 0x10, 0x12, 0x09, 0xb8, 0xca, 0xed, 0x5f, 0x6e, 0x22, 0x3e, 0xb7, 0xae, 0x94, + 0x56, 0x9b, 0xe2, 0x22, 0x32, 0xf5, 0xca, 0xfe, 0x3e, 0xab, 0x55, 0xd7, 0x15, 0xbf, 0x12, 0x10, + 0x3b, 0x8a, 0xe5, 0x61, 0xee, 0xf7, 0xbf, 0xa1, 0x0f, 0xf0, 0x4c, 0x24, 0x19, 0x6c, 0x57, 0xaa, + 0x20, 0x56, 0x79, 0x43, 0x18, 0xa3, 0xa3, 0x07, 0x7e, 0xfc, 0x47, 0x84, 0x3c, 0x23, 0x82, 0xb8, + 0x20, 0x13, 0xe2, 0x02, 0x82, 0x30, 0xdc, 0xc4, 0x0b, 0xb1, 0xd7, 0x61, 0x70, 0x1e, 0xc7, 0x1b, + 0x9d, 0xc9, 0xab, 0x30, 0xc3, 0x38, 0x0d, 0xba, 0x64, 0xa3, 0x38, 0xf8, 0xc4, 0xe0, 0x3e, 0xa1, + 0x16, 0x6c, 0xea, 0xe0, 0xfc, 0xff, 0x08, 0xf7, 0x75, 0x85, 0xbe, 0xe1, 0x12, 0x98, 0xa8, 0x62, + 0x56, 0x23, 0xab, 0x12, 0x11, 0x18, 0x71, 0x58, 0x59, 0xa0, 0xa3, 0x6e, 0x65, 0xd1, 0x59, 0xb2, + 0xce, 0x5e, 0x2b, 0x46, 0xe6, 0xeb, 0x38, 0xd1, 0x38, 0xd3, 0x11, 0x19, 0xa7, 0x5d, 0xdd, 0xfe, + 0x4d, 0x8d, 0x2c, 0xaf, 0x84, 0x73, 0x91, 0x76, 0x11, 0x8a, 0xee, 0x25, 0x20, 0x96, 0xdf, 0x9f, + 0x82, 0xbb, 0x8a, 0xdb, 0xec, 0xf7, 0x0b, 0x7d, 0xce, 0xc5, 0xbf, 0xc9, 0x96, 0x5f, 0x11, 0xc1, + 0x86, 0x0b, 0x78, 0xaf, 0x2d, 0x27, 0xff, 0x8f, 0x11, 0x19, 0xcf, 0x8e, 0xf6, 0x1e, 0x02, 0x6f, + 0xdc, 0xaf, 0x66, 0xc5, 0x80, 0xa2, 0x9b, 0xa2, 0x0e, 0xb7, 0x4b, 0xc2, 0x9a, 0xa4, 0xc3, 0x34, + 0x2e, 0x86, 0x7a, 0x43, 0xe8, 0xfc, 0xd2, 0x5c, 0x39, 0x20, 0x42, 0xae, 0x06, 0xd0, 0xb1, 0x90, + 0xd6, 0xe2, 0x68, 0xc1, 0xbc, 0xb3, 0x63, 0xee, 0x7b, 0xed, 0x34, 0x68, 0x9f, 0xde, 0x58, 0x0e, + 0x9f, 0x43, 0xdc, 0x5f, 0x2e, 0x8e, 0xf8, 0x91, 0x3b, 0x1d, 0xf1, 0x63, 0xb2, 0xc1, 0x8a, 0xb5, + 0xd9, 0xde, 0x24, 0x41, 0xbc, 0xbf, 0x11, 0x19, 0x13, 0xa4, 0x41, 0x80, 0x1c, 0xc7, 0xf6, 0x52, + 0xc2, 0x50, 0x59, 0xd1, 0xdd, 0xb9, 0x83, 0x0c, 0x9b, 0x36, 0x86, 0xbf, 0x49, 0x55, 0xdc, 0xfc, + 0x14, 0x89, 0x4a, 0xd3, 0xde, 0xef, 0x7b, 0xfc, 0x49, 0xca, 0xc3, 0xe9, 0xbb, 0xfe, 0x61, 0xd7, + 0x8a, 0xfc, 0x11, 0x8d, 0x55, 0x59, 0x68, 0x2c, 0xe0, 0x9c, 0xb0, 0xe8, 0xc5, 0xd9, 0x96, 0x14, + 0xdc, 0x7f, 0xf8, 0x82, 0x59, 0x69, 0x90, 0x95, 0x95, 0x7c, 0x15, 0x11, 0x41, 0xbf, 0x35, 0xc7, + 0xac, 0x3a, 0x41, 0x3e, 0x6e, 0x5f, 0x44, 0xfc, 0x48, 0x80, 0x4a, 0x42, 0x61, 0xd1, 0xf7, 0x2f, + 0x24, 0x4b, 0x0d, 0xfe, 0xe2, 0x04, 0x82, 0x3a, 0xaa, 0xfb, 0xc4, 0x02, 0x72, 0x97, 0x57, 0xb5, + 0x7b, 0x77, 0x7b, 0xf1, 0x31, 0x04, 0x50, 0x69, 0x0d, 0x79, 0x27, 0x2e, 0x19, 0x6c, 0x37, 0x91, + 0xef, 0xcb, 0x2f, 0x06, 0x7f, 0x96, 0x8d, 0xeb, 0xe6, 0x12, 0xab, 0xae, 0x0a, 0x86, 0x2e, 0x2f, + 0x8b, 0xc4, 0x73, 0x37, 0xee, 0x18, 0x12, 0x51, 0xae, 0xed, 0x85, 0xc2, 0x2c, 0x37, 0x5f, 0xad, + 0x41, 0x4c, 0x40, 0x8e, 0x18, 0x08, 0xfc, 0xa1, 0xeb, 0x96, 0x8d, 0xa7, 0x84, 0x49, 0x83, 0xbf, + 0x05, 0x77, 0x28, 0xea, 0x0d, 0xd6, 0xce, 0xdc, 0xf8, 0x40, 0x9b, 0x3f, 0x26, 0x5a, 0x64, 0xa8, + 0x23, 0x1a, 0xf1, 0x67, 0x21, 0x04, 0x70, 0x40, 0xaf, 0x66, 0xbf, 0xc4, 0x5f, 0x04, 0x62, 0xdf, + 0x77, 0xf1, 0x35, 0xc2, 0x61, 0x01, 0x0d, 0x15, 0xfb, 0xb9, 0x72, 0x2b, 0xc2, 0x02, 0x50, 0xd7, + 0x82, 0x8e, 0x11, 0xbd, 0xf5, 0x2e, 0x45, 0xcd, 0x98, 0x60, 0x22, 0x0c, 0x08, 0xf1, 0x03, 0x82, + 0xb7, 0x7b, 0x8c, 0xf5, 0xb8, 0xb7, 0xfc, 0x40, 0x90, 0x81, 0x6f, 0x71, 0x5f, 0x76, 0xd7, 0xe3, + 0xef, 0xbb, 0xbb, 0xe4, 0xb3, 0x69, 0xa0, 0x3e, 0xcc, 0x4c, 0x70, 0x87, 0x6b, 0x17, 0xa6, 0xf5, + 0x7f, 0x8e, 0xaa, 0x72, 0x2e, 0x46, 0x17, 0xe5, 0xfa, 0xa1, 0xf8, 0x40, 0xac, 0xc5, 0xf5, 0x5d, + 0x52, 0xc4, 0xef, 0x90, 0x5b, 0xbb, 0xbb, 0xe4, 0x14, 0xed, 0xbb, 0xf8, 0x4c, 0x42, 0xd6, 0xab, + 0xe1, 0x01, 0x28, 0xbd, 0x04, 0xd1, 0x10, 0x54, 0x72, 0xc9, 0xd2, 0x2f, 0xbb, 0x88, 0x71, 0xaa, + 0xb4, 0xab, 0x08, 0x04, 0x41, 0x39, 0xae, 0xfe, 0x2f, 0x2f, 0x12, 0x08, 0x67, 0xa1, 0xea, 0x2b, + 0xaf, 0xb8, 0x9f, 0x10, 0x11, 0x10, 0x72, 0x53, 0x88, 0x60, 0xfc, 0x72, 0xde, 0x26, 0x0b, 0x05, + 0x5d, 0xf4, 0xdb, 0x8d, 0xd2, 0x4c, 0xf9, 0xe1, 0x5b, 0x94, 0xff, 0x08, 0x54, 0x68, 0x2c, 0x36, + 0xb0, 0x2d, 0xfc, 0xda, 0xe2, 0x39, 0x1e, 0x24, 0x48, 0x91, 0x6e, 0xaf, 0xcf, 0xeb, 0x13, 0xf5, + 0x7f, 0x13, 0xc4, 0x09, 0xe2, 0x3c, 0x40, 0x8e, 0x22, 0x4e, 0xed, 0x78, 0x25, 0x11, 0xaa, 0xd2, + 0x53, 0x7e, 0xf0, 0x88, 0xbd, 0x6b, 0x9b, 0x0d, 0xb8, 0x81, 0x25, 0x2e, 0xd3, 0x58, 0x42, 0x61, + 0x79, 0x72, 0x08, 0xa2, 0x26, 0x11, 0x27, 0xf0, 0xc0, 0x44, 0x41, 0x2a, 0xb5, 0x55, 0x5e, 0x24, + 0x67, 0x96, 0x8c, 0xf7, 0xdd, 0xdd, 0xef, 0xeb, 0xdc, 0x4d, 0x1f, 0xb8, 0x81, 0x21, 0x1a, 0xea, + 0xaa, 0xaa, 0xa4, 0xc2, 0xa9, 0xf1, 0x31, 0xc2, 0x9b, 0x11, 0xaa, 0xb9, 0x45, 0xd0, 0x07, 0x18, + 0xb4, 0x1e, 0x57, 0xc6, 0xd4, 0xa9, 0xfc, 0x4b, 0xe7, 0xd1, 0x3a, 0x78, 0x40, 0xa7, 0x85, 0x13, + 0x0e, 0x6f, 0xac, 0x3a, 0x59, 0x53, 0xe5, 0x3d, 0xd3, 0xbe, 0x8e, 0xfe, 0x20, 0xbc, 0x56, 0xfe, + 0x5b, 0xbb, 0xbe, 0x24, 0x4f, 0x12, 0x19, 0xf1, 0x3c, 0x44, 0x12, 0x92, 0x1d, 0xf7, 0x1e, 0xb1, + 0xc5, 0xbe, 0xf8, 0x25, 0x15, 0x2a, 0xaa, 0xef, 0x6e, 0x39, 0xc4, 0x5c, 0xf9, 0xdf, 0x11, 0x05, + 0x42, 0x76, 0x9c, 0xb9, 0xbf, 0x1a, 0xa4, 0x5c, 0x4c, 0xbd, 0x72, 0x62, 0x7d, 0x6a, 0x1e, 0x84, + 0x23, 0x27, 0xc7, 0xc5, 0x61, 0x45, 0x55, 0x31, 0x1d, 0x2b, 0x93, 0x1d, 0x18, 0xbe, 0x24, 0x22, + 0x4d, 0x55, 0xef, 0x5d, 0xf8, 0x47, 0x89, 0xb2, 0x55, 0x57, 0xcc, 0x75, 0xaf, 0x84, 0x38, 0x80, + 0x88, 0xa8, 0xac, 0x51, 0xc7, 0xfc, 0xfb, 0x7f, 0x1c, 0x4b, 0xc5, 0x77, 0x7a, 0xd2, 0xe2, 0x04, + 0x9b, 0xaa, 0xf1, 0x03, 0x8e, 0xf7, 0xaf, 0x49, 0x66, 0x47, 0x6e, 0xdf, 0xe1, 0x1b, 0xee, 0xa9, + 0xa6, 0xe7, 0xfd, 0xf8, 0x46, 0xb8, 0x44, 0xfb, 0x8a, 0xdf, 0x77, 0x77, 0x7f, 0x31, 0x1e, 0xef, + 0xe0, 0x84, 0xaf, 0x7b, 0xf1, 0x02, 0x7e, 0x4d, 0x6b, 0xc4, 0x8b, 0xee, 0xf5, 0xaf, 0x13, 0xe2, + 0x51, 0x3b, 0xc4, 0xf1, 0x02, 0x43, 0x43, 0x1a, 0xc5, 0xc5, 0xc6, 0x0e, 0x93, 0xdb, 0xff, 0x82, + 0x32, 0xe0, 0xd8, 0x97, 0xd7, 0xc1, 0x1f, 0x18, 0xa7, 0xd0, 0xec, 0x21, 0x04, 0xe5, 0xb1, 0xdd, + 0xea, 0x23, 0xfb, 0xe0, 0xba, 0xf3, 0xe5, 0x6a, 0xa2, 0xf1, 0x85, 0x89, 0x1d, 0x7c, 0xff, 0x4f, + 0xff, 0xc9, 0x55, 0xfc, 0xc6, 0x7b, 0xfc, 0x50, 0x95, 0xad, 0x69, 0xfc, 0x27, 0x5a, 0xf7, 0x75, + 0x11, 0x05, 0xc6, 0x34, 0x16, 0xb5, 0x5f, 0x71, 0x31, 0x25, 0x68, 0xdb, 0xbd, 0xbf, 0x8e, 0x3d, + 0x24, 0x9e, 0x4c, 0x4b, 0x77, 0x7f, 0x9a, 0xef, 0xe1, 0x19, 0xae, 0xf7, 0xf1, 0xd7, 0x1b, 0xf7, + 0xb7, 0xf7, 0x7f, 0x2d, 0xef, 0xc4, 0x89, 0x05, 0xa4, 0x77, 0xde, 0xfe, 0xe2, 0x44, 0xde, 0x27, + 0x89, 0xab, 0xf8, 0x90, 0x42, 0x77, 0xd9, 0xbf, 0x08, 0x86, 0x48, 0x45, 0x5a, 0x5c, 0x48, 0x22, + 0xb4, 0x29, 0xbd, 0xb8, 0x40, 0x48, 0x29, 0x14, 0xed, 0x15, 0xa5, 0x74, 0x6d, 0xc5, 0x6f, 0xe5, + 0xf0, 0x4e, 0x72, 0xff, 0x75, 0x81, 0x0b, 0xa1, 0xde, 0x09, 0xeb, 0x7d, 0xc5, 0x6e, 0x33, 0x70, + 0x80, 0x29, 0xf1, 0x26, 0x2d, 0x6e, 0xb8, 0x91, 0x4b, 0x8b, 0xa8, 0xa6, 0xab, 0x89, 0xb3, 0xae, + 0xb8, 0x81, 0x21, 0x1d, 0xdd, 0xab, 0xbd, 0xb4, 0xd2, 0x7c, 0x4c, 0x65, 0xb3, 0x6b, 0x33, 0x2d, + 0x73, 0x3b, 0xc6, 0xef, 0xd7, 0x27, 0xa8, 0x8a, 0xbf, 0x11, 0x30, 0x97, 0x7a, 0x5e, 0x09, 0x2e, + 0xc6, 0xc4, 0x66, 0x3f, 0xe1, 0x10, 0x55, 0x57, 0x17, 0x8a, 0xdc, 0x57, 0x78, 0x97, 0x1e, 0x3f, + 0x13, 0x64, 0x77, 0xf1, 0x13, 0x5b, 0x5a, 0xf1, 0x2e, 0xf7, 0x47, 0x89, 0x10, 0x43, 0xd6, 0xfc, + 0x48, 0xae, 0xab, 0x59, 0xbe, 0x24, 0x41, 0x05, 0x56, 0xbc, 0x48, 0xba, 0xc9, 0x9b, 0xbf, 0x12, + 0x24, 0x51, 0xe5, 0xc7, 0xde, 0xff, 0x31, 0x5f, 0x75, 0x86, 0x7c, 0x22, 0x0b, 0x4c, 0xba, 0xea, + 0xaf, 0xc2, 0x02, 0x41, 0x51, 0xa9, 0x3b, 0x12, 0xc5, 0x33, 0x29, 0x10, 0x72, 0x5b, 0x46, 0x0d, + 0x77, 0xcf, 0x2b, 0x5d, 0x30, 0x67, 0xef, 0xc3, 0x7c, 0xda, 0xaa, 0x1e, 0x20, 0x48, 0x46, 0xd5, + 0xe9, 0x45, 0x71, 0x47, 0x77, 0xf1, 0x22, 0x5e, 0xdd, 0xee, 0xfe, 0x42, 0x4f, 0x4f, 0x89, 0x04, + 0x59, 0xb2, 0xbf, 0xf1, 0x24, 0x10, 0xef, 0xf1, 0x00, 0xb0, 0x5b, 0xde, 0xfb, 0xed, 0xad, 0x71, + 0x1f, 0x12, 0x2c, 0x8f, 0x7b, 0xdf, 0xe4, 0xbb, 0xbb, 0xe2, 0x38, 0x5d, 0x8d, 0x01, 0x00, 0x03, + 0xb5, 0xf1, 0xef, 0xfb, 0xdf, 0xcb, 0xfc, 0x22, 0x61, 0x13, 0x31, 0xf1, 0x22, 0xaf, 0x7b, 0xdc, + 0x8c, 0x62, 0x22, 0x65, 0xc7, 0x7c, 0xfe, 0xf8, 0x91, 0x3e, 0x11, 0xe1, 0x0f, 0x11, 0x14, 0x57, + 0x9e, 0x6f, 0xe2, 0x28, 0x63, 0xfc, 0x78, 0xd1, 0x76, 0xa9, 0x5c, 0xbd, 0xfe, 0xee, 0xf8, 0x88, + 0x93, 0x5e, 0xd6, 0xee, 0xb1, 0x3f, 0x62, 0xde, 0xd7, 0x84, 0x48, 0x23, 0x55, 0xe1, 0x94, 0x4c, + 0x38, 0x40, 0x48, 0x54, 0x91, 0x76, 0x21, 0x4e, 0xb1, 0x73, 0xa6, 0xbc, 0x69, 0x13, 0xfc, 0xe2, + 0x48, 0x4c, 0xb5, 0x3d, 0xf8, 0x6a, 0x18, 0x87, 0xcc, 0xa7, 0xe6, 0x60, 0xf7, 0xb9, 0x6c, 0xf0, + 0xb5, 0xa7, 0x07, 0xe2, 0xe2, 0x34, 0x86, 0x05, 0x17, 0xe2, 0x01, 0x08, 0x26, 0xd6, 0xb4, 0xd5, + 0x65, 0xf3, 0x1d, 0x55, 0x78, 0x46, 0xaf, 0x58, 0x8f, 0x84, 0x6d, 0x8b, 0xee, 0xee, 0xef, 0x72, + 0xa8, 0xc4, 0x04, 0x38, 0x81, 0x20, 0xaa, 0xc6, 0xf7, 0x15, 0xb8, 0x87, 0xdb, 0xbb, 0xbd, 0xf8, + 0x98, 0x52, 0xef, 0x7b, 0xcb, 0x01, 0xda, 0xac, 0xb6, 0x2b, 0x7b, 0x7b, 0xf1, 0x01, 0x11, 0x1b, + 0x6e, 0x5a, 0x3b, 0xef, 0x89, 0x82, 0x9b, 0x8a, 0xdd, 0xdd, 0xdd, 0xdf, 0x69, 0xf8, 0x99, 0xaf, + 0x7e, 0x0a, 0x01, 0x40, 0xe1, 0x22, 0x1e, 0xee, 0xdb, 0x97, 0x42, 0xb1, 0x5b, 0x9f, 0x1e, 0xf8, + 0x67, 0xec, 0xdb, 0x69, 0xe2, 0x6b, 0xdc, 0x4f, 0xe5, 0xae, 0xbe, 0x63, 0x5d, 0xdf, 0xc8, 0x77, + 0x3f, 0x7f, 0xc2, 0x98, 0x57, 0x73, 0xe6, 0x27, 0xbb, 0xdf, 0x4d, 0xf8, 0x89, 0xb7, 0xa5, 0xe4, + 0xbc, 0xf8, 0xd2, 0x88, 0xf1, 0x33, 0x55, 0x7c, 0x21, 0x20, 0x84, 0xcc, 0xc2, 0xce, 0x10, 0x12, + 0x14, 0xab, 0x8a, 0x6a, 0xda, 0xd4, 0x5e, 0xb1, 0x46, 0xe2, 0x47, 0x0b, 0x6d, 0xf0, 0x46, 0x24, + 0xdf, 0xfa, 0x18, 0xe6, 0x35, 0xdf, 0xc4, 0x8d, 0xb9, 0xf4, 0x4d, 0x86, 0x52, 0x36, 0xe0, 0xa7, + 0xfa, 0xce, 0x0a, 0x8e, 0x26, 0x0c, 0xcc, 0x29, 0x79, 0xf2, 0xc4, 0xf5, 0x62, 0x15, 0x1f, 0xe2, + 0x04, 0x8b, 0xde, 0x5e, 0xfb, 0x7f, 0x16, 0x52, 0xe6, 0xaa, 0xd9, 0x57, 0x04, 0x94, 0xde, 0xef, + 0xf0, 0x50, 0x47, 0xbe, 0xb4, 0xdf, 0xe1, 0x2b, 0xf6, 0xd5, 0x69, 0x62, 0x44, 0x98, 0xaf, 0x7f, + 0x12, 0x11, 0xdd, 0xdf, 0x77, 0x7b, 0xfd, 0xdd, 0xdf, 0xe0, 0x9a, 0xee, 0xf7, 0x77, 0x7a, 0xf9, + 0xae, 0xd8, 0xac, 0x6c, 0x62, 0xa8, 0x44, 0x32, 0x13, 0x2b, 0xbb, 0xbb, 0xef, 0xc3, 0x01, 0x3b, + 0xbd, 0xc5, 0x6f, 0x78, 0x5a, 0x46, 0x54, 0xff, 0xff, 0xe2, 0x2f, 0x8a, 0xdd, 0xee, 0xff, 0x82, + 0xcb, 0xbb, 0xdd, 0xf7, 0x7a, 0x68, 0xef, 0x10, 0x20, 0x16, 0x16, 0x86, 0xc3, 0x72, 0xe7, 0x66, + 0xee, 0xe2, 0xb4, 0x77, 0x88, 0x96, 0xfa, 0x78, 0x40, 0x41, 0xbc, 0xbd, 0xf0, 0x45, 0xdd, 0xdf, + 0x89, 0x08, 0x8a, 0xd6, 0xb5, 0xaf, 0x08, 0x84, 0x86, 0x5e, 0xfa, 0xaf, 0x87, 0x7b, 0xbd, 0xdb, + 0x70, 0x2c, 0x93, 0x52, 0x55, 0x49, 0x80, 0xdc, 0x27, 0x72, 0x02, 0x16, 0x85, 0x1e, 0xce, 0x66, + 0x9f, 0x86, 0x22, 0x04, 0x05, 0x29, 0xba, 0x6f, 0x0c, 0x09, 0x04, 0x68, 0x35, 0xe0, 0xdd, 0x8a, + 0x47, 0x4d, 0x5c, 0x25, 0x35, 0x4b, 0x7f, 0x71, 0x01, 0x12, 0x97, 0x2f, 0xfc, 0xa5, 0x7b, 0x64, + 0xfe, 0x3c, 0xa8, 0x98, 0xeb, 0x1c, 0x37, 0x17, 0xd6, 0xee, 0x5c, 0xbc, 0x4d, 0x93, 0x7b, 0xae, + 0x2a, 0xa9, 0xeb, 0x55, 0xc4, 0x89, 0xf1, 0x02, 0x7a, 0xb9, 0x3b, 0xf3, 0xc3, 0x20, 0xa0, 0x61, + 0x45, 0x76, 0xdc, 0xf4, 0xdc, 0xaa, 0x1f, 0x8c, 0x75, 0xc6, 0xe9, 0xbf, 0x0c, 0x85, 0x39, 0xfd, + 0x24, 0xaf, 0x6c, 0xfe, 0x5b, 0xbf, 0x0c, 0x41, 0x09, 0x2f, 0x77, 0xe1, 0x08, 0x29, 0xbe, 0xed, + 0xf7, 0x7b, 0xdf, 0x88, 0x10, 0xee, 0xfa, 0xc4, 0xab, 0xd6, 0x27, 0xe6, 0x35, 0x56, 0xa2, 0x7f, + 0x20, 0x96, 0x9f, 0xc2, 0x32, 0xdd, 0xdd, 0xfc, 0x9b, 0xbc, 0x9c, 0x9a, 0xd7, 0x89, 0xf8, 0x2a, + 0xaa, 0xd4, 0xd9, 0xd5, 0x55, 0x55, 0xf8, 0x80, 0xc8, 0x2c, 0x10, 0xd9, 0x79, 0xb1, 0x3e, 0xa4, + 0xa9, 0xf9, 0x7b, 0xc5, 0x26, 0xf8, 0xd3, 0xa2, 0x5a, 0xd1, 0x5b, 0xbb, 0x67, 0x24, 0x07, 0x26, + 0x35, 0xbd, 0xdb, 0xd5, 0xb8, 0x87, 0xfc, 0x2d, 0x88, 0x14, 0x29, 0xb1, 0x25, 0x99, 0x20, 0xac, + 0x61, 0x7c, 0x20, 0x08, 0x41, 0x4e, 0xed, 0x44, 0x93, 0xbb, 0xf7, 0xbc, 0xbc, 0x48, 0xe3, 0xd6, + 0x56, 0x2e, 0xf4, 0xda, 0xc2, 0xc1, 0xe2, 0x61, 0x12, 0xaa, 0x7a, 0xd4, 0xf9, 0x76, 0x21, 0x5e, + 0x24, 0x48, 0xeb, 0xdf, 0xc5, 0x6f, 0xa5, 0xe0, 0x9a, 0xf7, 0xbe, 0xf5, 0xc2, 0x3a, 0xe1, 0x3a, + 0xae, 0xab, 0x5e, 0x27, 0x89, 0x82, 0x4e, 0xee, 0xfc, 0x48, 0x80, 0x59, 0xc5, 0x6e, 0xef, 0x8a, + 0xdf, 0xaf, 0x84, 0x6e, 0xc6, 0xf9, 0x58, 0xbd, 0xb6, 0xed, 0xc2, 0xca, 0x09, 0x12, 0x4a, 0x76, + 0xf7, 0xd6, 0xb5, 0xff, 0xaf, 0x7c, 0xbb, 0xdf, 0x13, 0xf9, 0xaf, 0xbe, 0x27, 0x51, 0x35, 0x7a, + 0xe4, 0x2a, 0xef, 0xe0, 0x8b, 0xbb, 0xbf, 0xc2, 0x3b, 0xbb, 0xea, 0xf3, 0xe3, 0x5f, 0x82, 0x1b, + 0xef, 0xde, 0x20, 0x12, 0x55, 0x55, 0x47, 0x6f, 0x82, 0xb9, 0xb3, 0xaa, 0xaa, 0xb4, 0xaa, 0x97, + 0x7d, 0xd5, 0x57, 0xe5, 0xdd, 0x6b, 0xb1, 0x4a, 0xbe, 0x20, 0x32, 0x14, 0x96, 0xdc, 0x51, 0x9f, + 0x8a, 0xde, 0xdf, 0x8b, 0xde, 0x2b, 0x30, 0x3e, 0x10, 0x3d, 0xdb, 0xe6, 0x7d, 0x8d, 0x8e, 0xe1, + 0x4c, 0x40, 0xa3, 0x73, 0xb0, 0xdc, 0x37, 0x0e, 0x97, 0x66, 0x18, 0x04, 0x23, 0x49, 0x35, 0x0d, + 0x8a, 0x6c, 0x69, 0xef, 0x32, 0x4c, 0x1c, 0x4b, 0x55, 0xe3, 0xcf, 0x47, 0xfd, 0x62, 0x4a, 0x27, + 0x10, 0xe3, 0x7c, 0x40, 0x2a, 0xac, 0xac, 0x74, 0x44, 0x76, 0x4d, 0x3a, 0x8b, 0xdf, 0xe6, 0x35, + 0xef, 0xe5, 0x17, 0x76, 0x3f, 0x92, 0x48, 0x7f, 0x37, 0x55, 0xe2, 0x3e, 0x09, 0x75, 0xaa, 0xa7, + 0xf5, 0xf2, 0x11, 0xde, 0xfc, 0x43, 0xa7, 0x7e, 0x27, 0x58, 0x90, 0x56, 0x53, 0xd3, 0x8a, 0x37, + 0xbb, 0xbb, 0xdf, 0x89, 0xf1, 0x1e, 0x27, 0xf3, 0x5d, 0x53, 0x7f, 0x31, 0x5f, 0x36, 0x79, 0x6a, + 0xb2, 0xbe, 0x08, 0xa3, 0x4b, 0xcd, 0xfe, 0x6e, 0xab, 0xe4, 0x22, 0xad, 0x78, 0x92, 0x16, 0xb6, + 0xfc, 0x26, 0x4c, 0x99, 0x55, 0xae, 0x24, 0x48, 0xba, 0xd5, 0x5f, 0x6f, 0x11, 0x31, 0x15, 0x7c, + 0x20, 0x20, 0x51, 0xd6, 0xaa, 0xb3, 0x86, 0x7c, 0x47, 0x89, 0x14, 0x32, 0x16, 0x05, 0x06, 0xe3, + 0x97, 0x35, 0xe1, 0x08, 0x44, 0xb7, 0xbd, 0x12, 0x61, 0xd3, 0x5b, 0xee, 0xe2, 0xb0, 0xa4, 0x20, + 0x24, 0x28, 0x6b, 0xbb, 0x8a, 0xb1, 0xf3, 0x01, 0xbe, 0x08, 0x29, 0x93, 0xeb, 0x97, 0x97, 0xcf, + 0x2e, 0x22, 0x38, 0xb1, 0x0b, 0xca, 0x8b, 0xf2, 0x67, 0xae, 0x20, 0xef, 0x7a, 0xaf, 0x89, 0x12, + 0xc9, 0xaa, 0xf8, 0x27, 0x33, 0x9f, 0xd2, 0x77, 0x3b, 0x0f, 0x61, 0xfe, 0x10, 0x17, 0x47, 0x5a, + 0x51, 0xdf, 0x9b, 0xa8, 0xbc, 0xae, 0x24, 0x22, 0x5a, 0xd7, 0x89, 0x08, 0x71, 0x22, 0x01, 0x1d, + 0x6b, 0xaf, 0x11, 0xf5, 0x7e, 0x20, 0x48, 0xa8, 0xac, 0x56, 0xe2, 0xb7, 0x7f, 0xc6, 0x45, 0x71, + 0x5b, 0x93, 0x3c, 0x56, 0x2b, 0x15, 0x8a, 0xde, 0xef, 0xe1, 0x2e, 0x4d, 0x8a, 0xc5, 0x62, 0xb1, + 0x5f, 0x13, 0xf7, 0x77, 0x77, 0xc4, 0x88, 0x2e, 0xee, 0xf8, 0x89, 0x2e, 0x5e, 0xff, 0x10, 0x3c, + 0xb9, 0xf5, 0xdd, 0xdd, 0xdd, 0xdd, 0xf1, 0x02, 0x07, 0x5d, 0x8f, 0x9f, 0x1f, 0x2c, 0x18, 0xfe, + 0x10, 0x10, 0x59, 0xd8, 0xb7, 0xc4, 0x04, 0x38, 0x8b, 0x93, 0xff, 0x8b, 0xaa, 0xd5, 0x6b, 0xc4, + 0x89, 0x7d, 0x57, 0xd9, 0x2a, 0xab, 0xe1, 0x13, 0xaa, 0x88, 0xc0, 0xbd, 0x54, 0xdc, 0xbf, 0x13, + 0xe2, 0xfe, 0x27, 0x51, 0x32, 0x8a, 0x55, 0xf8, 0x44, 0x12, 0x96, 0x4f, 0x5d, 0x62, 0xfd, 0x85, + 0x59, 0x40, 0x08, 0xa8, 0xf4, 0xb9, 0x76, 0x37, 0x6b, 0xed, 0xfb, 0x66, 0xfb, 0x6d, 0xf0, 0xc8, + 0x2b, 0x35, 0x56, 0xab, 0x55, 0xa9, 0x3f, 0x78, 0x44, 0x61, 0xa3, 0x9b, 0x37, 0x57, 0x55, 0x91, + 0xc5, 0x57, 0xe2, 0x20, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1d, 0x0e, 0xb0, 0x6a, 0x0d, 0xf4, + 0x11, 0xe8, 0x35, 0xe0, 0x9c, 0xd6, 0xad, 0xd2, 0x9b, 0x12, 0x87, 0xa2, 0xe5, 0xe2, 0x60, 0xd7, + 0xa2, 0x22, 0xbf, 0x82, 0x73, 0xea, 0xb9, 0x28, 0x4a, 0x25, 0x41, 0x6e, 0x89, 0xd3, 0x74, 0x47, + 0x85, 0xfa, 0x3c, 0x65, 0x75, 0xee, 0x19, 0x82, 0x6a, 0x1a, 0x56, 0xa5, 0xa2, 0x9c, 0x7a, 0x55, + 0x89, 0xa2, 0x74, 0x57, 0x04, 0x65, 0xb4, 0xc9, 0x7d, 0x05, 0x31, 0x00, 0x84, 0x16, 0x0e, 0xd5, + 0x69, 0x49, 0xa2, 0x6c, 0x25, 0x0c, 0xb1, 0xa8, 0x21, 0x24, 0xe8, 0x03, 0xc2, 0xd1, 0xc4, 0x02, + 0x10, 0x59, 0xaa, 0xce, 0xf1, 0x1c, 0x3c, 0xd4, 0x48, 0xa6, 0xd1, 0x05, 0xeb, 0xb5, 0x67, 0xb8, + 0x88, 0x23, 0x1b, 0x82, 0x26, 0xb1, 0xba, 0x7e, 0x1c, 0x26, 0x77, 0xbd, 0x30, 0x71, 0x57, 0xfe, + 0x34, 0x4c, 0x96, 0xb2, 0x4c, 0xf5, 0x5a, 0xba, 0xb9, 0x73, 0x8a, 0xf2, 0x6a, 0x5b, 0x4d, 0x34, + 0xd7, 0x82, 0x42, 0x35, 0x59, 0x59, 0x6b, 0xab, 0xa0, 0xa7, 0x85, 0x02, 0x4a, 0x8c, 0xab, 0x2b, + 0x2d, 0xff, 0x2f, 0x86, 0x12, 0x87, 0x23, 0x44, 0x62, 0xf6, 0xca, 0xf5, 0x12, 0x30, 0x52, 0x91, + 0xdc, 0x20, 0x08, 0x02, 0x94, 0x80, 0x01, 0x54, 0xe8, 0xa2, 0xae, 0x85, 0x2b, 0x4d, 0x17, 0xd1, + 0x69, 0xa2, 0x99, 0xb9, 0x12, 0x58, 0x53, 0x85, 0xb2, 0x64, 0x8d, 0xb6, 0xf9, 0x51, 0x26, 0x68, + 0x42, 0xad, 0xaf, 0x2c, 0xc7, 0x56, 0x8e, 0xad, 0x38, 0x38, 0x42, 0x09, 0x8f, 0x58, 0xf0, 0xae, + 0x47, 0xe8, 0xf7, 0xb3, 0x33, 0x25, 0xb2, 0x5d, 0x78, 0xb2, 0x37, 0xc6, 0x89, 0x4d, 0xc8, 0x75, + 0x55, 0xa8, 0x10, 0x60, 0x88, 0xe2, 0xb2, 0xdb, 0xe2, 0xc2, 0x0a, 0x81, 0x8f, 0x31, 0xcc, 0x64, + 0xc6, 0x74, 0xd3, 0x50, 0xc8, 0x80, 0x43, 0x77, 0xfa, 0x3f, 0xad, 0x47, 0xf5, 0x8a, 0x2e, 0x10, + 0x08, 0x82, 0x20, 0x92, 0xd7, 0x6e, 0x5c, 0x48, 0x44, 0x29, 0x4d, 0x46, 0x4c, 0xdd, 0x81, 0xcb, + 0x1f, 0xc9, 0xe1, 0x00, 0x00, 0x8f, 0x50, 0x9c, 0x36, 0x04, 0x02, 0x18, 0x08, 0xe1, 0x68, 0x20, + 0x16, 0x31, 0xd5, 0xcf, 0x0a, 0x80, 0x90, 0x54, 0x50, 0xfe, 0x82, 0x93, 0x11, 0x08, 0x11, 0x95, + 0x5e, 0xc8, 0x8d, 0xe9, 0x18, 0xdf, 0x8e, 0xab, 0x67, 0x1e, 0x73, 0xc4, 0x2c, 0xc6, 0x5e, 0x99, + 0xf1, 0x0c, 0x2a, 0xb5, 0x92, 0x10, 0x12, 0x09, 0x02, 0x10, 0x1d, 0xa1, 0xa7, 0x13, 0xd5, 0x06, + 0x5f, 0x08, 0x09, 0x0a, 0x1b, 0x48, 0xb9, 0x88, 0x68, 0x32, 0x47, 0x56, 0x5b, 0x74, 0x99, 0x8f, + 0xbf, 0x08, 0x04, 0x42, 0x9e, 0xa6, 0xb1, 0x3c, 0x08, 0xd1, 0x56, 0xc7, 0x0d, 0x2d, 0xfb, 0x33, + 0x22, 0x3a, 0xc3, 0x00, 0x84, 0x67, 0x75, 0x90, 0x83, 0x8a, 0x61, 0xc3, 0x50, 0x4e, 0xad, 0x77, + 0x32, 0x48, 0x8d, 0x28, 0xf0, 0xc0, 0x29, 0x05, 0x65, 0xdb, 0x93, 0x80, 0x70, 0x75, 0x10, 0xf0, + 0x71, 0x71, 0x06, 0x61, 0xf9, 0x79, 0x0e, 0x9a, 0x7e, 0x0e, 0x01, 0x4a, 0x09, 0x8e, 0xe8, 0x29, + 0xea, 0xfe, 0x24, 0x13, 0x8c, 0x84, 0x31, 0x9e, 0x5a, 0xac, 0xdd, 0x4b, 0x91, 0xb9, 0x35, 0x32, + 0x24, 0xe6, 0xf0, 0x88, 0xd3, 0x78, 0x72, 0x9e, 0x0f, 0xf3, 0x2e, 0x9d, 0x69, 0x58, 0x5a, 0x2d, + 0x28, 0x57, 0x20, 0xb7, 0x31, 0xa1, 0x31, 0x83, 0x82, 0xca, 0xe4, 0x04, 0xa5, 0x24, 0xd1, 0x3f, + 0xe2, 0xf5, 0xc4, 0x08, 0x19, 0x24, 0xf0, 0xf6, 0xc3, 0x3a, 0x9a, 0x0f, 0xd8, 0x27, 0x4a, 0xa6, + 0x1d, 0xec, 0xe7, 0x0b, 0x07, 0x1f, 0x06, 0x72, 0xc3, 0x3b, 0xcc, 0x59, 0xf0, 0x50, 0x11, 0x41, + 0x37, 0xfa, 0xf5, 0x42, 0x13, 0x0e, 0x87, 0x01, 0xa4, 0x11, 0x97, 0x4e, 0x9b, 0xfd, 0x1c, 0x40, + 0x29, 0x33, 0x55, 0x68, 0xbf, 0xed, 0xd9, 0xed, 0xfb, 0x88, 0x89, 0x16, 0x95, 0xa9, 0x48, 0x2e, + 0xfe, 0x24, 0x28, 0x72, 0x92, 0x1d, 0x88, 0x7c, 0xc1, 0x7a, 0x45, 0x5e, 0x97, 0x77, 0x77, 0x71, + 0xba, 0x9f, 0x46, 0xab, 0x04, 0x30, 0x4a, 0x65, 0x66, 0x47, 0xb9, 0x6d, 0xa2, 0xb5, 0x29, 0x4c, + 0xae, 0xd3, 0xac, 0x48, 0x90, 0x54, 0x28, 0xb1, 0xd8, 0xae, 0x53, 0x32, 0xa3, 0x0b, 0xa9, 0x0c, + 0x66, 0xa9, 0x39, 0xea, 0x86, 0x34, 0x80, 0x81, 0xb1, 0xde, 0x11, 0x08, 0x0b, 0x98, 0xa9, 0x21, + 0x01, 0xac, 0x40, 0x92, 0x9e, 0x3d, 0xd8, 0xef, 0x55, 0xc1, 0x56, 0x20, 0x13, 0xd4, 0xa7, 0x63, + 0x8c, 0x5d, 0x44, 0x71, 0x54, 0x40, 0x97, 0x37, 0x10, 0x10, 0x05, 0x46, 0x3b, 0xed, 0x46, 0x76, + 0x4a, 0xa1, 0x0e, 0xde, 0xce, 0xe2, 0x9f, 0x20, 0xa1, 0xcb, 0xf8, 0x91, 0xc4, 0x95, 0x99, 0x6e, + 0xb1, 0x59, 0xfb, 0x3b, 0x14, 0xfc, 0xa1, 0x34, 0xdd, 0xeb, 0x98, 0x8a, 0xbe, 0x20, 0x48, 0x22, + 0x08, 0x3e, 0xfa, 0x1d, 0xfb, 0xe2, 0x46, 0xb3, 0x3a, 0xd1, 0x9c, 0x3d, 0x6d, 0xae, 0x20, 0x22, + 0xca, 0xcd, 0xfe, 0x24, 0xc4, 0xdc, 0x76, 0x05, 0xc4, 0x82, 0x81, 0x55, 0xca, 0x41, 0x09, 0x7a, + 0x75, 0xf5, 0x35, 0xdf, 0x1d, 0x2c, 0x49, 0xcd, 0x08, 0x48, 0x07, 0xce, 0xd5, 0x5e, 0x38, 0x68, + 0x5a, 0x88, 0xa8, 0xf8, 0x30, 0x82, 0x98, 0x81, 0x26, 0x1f, 0xc6, 0xa9, 0x88, 0x10, 0x0b, 0x61, + 0x66, 0x84, 0xa8, 0xd1, 0xe0, 0xf9, 0x46, 0x53, 0x8f, 0x0a, 0x0a, 0xb0, 0xca, 0x65, 0x7a, 0x95, + 0x85, 0x63, 0xbc, 0xcd, 0xb4, 0xea, 0x27, 0xd0, 0xaa, 0x3e, 0x78, 0x80, 0xa1, 0x12, 0x70, 0xe6, + 0xf1, 0xdc, 0xb9, 0x55, 0x18, 0x31, 0x6d, 0xc1, 0x7b, 0x0d, 0x42, 0x60, 0x43, 0x57, 0x19, 0xff, + 0xff, 0xfe, 0xa1, 0x01, 0x02, 0xc2, 0x5c, 0xbd, 0x09, 0x3a, 0x0d, 0x3c, 0x48, 0x40, 0x20, 0x5a, + 0xd6, 0xf7, 0x44, 0xad, 0xaf, 0x82, 0x61, 0x35, 0x55, 0xcb, 0x89, 0x3f, 0x11, 0x05, 0x9a, 0xd4, + 0x32, 0xaa, 0x77, 0x56, 0x39, 0x66, 0x94, 0x15, 0x6f, 0xbb, 0x88, 0x85, 0x07, 0x70, 0xd2, 0x74, + 0x8b, 0xdb, 0xec, 0xe1, 0xc9, 0x6d, 0xbd, 0x5e, 0x61, 0xa1, 0xe1, 0xaf, 0xa9, 0xa8, 0xc3, 0xf7, + 0x88, 0x10, 0x25, 0x81, 0x0d, 0xee, 0x25, 0xeb, 0xde, 0x71, 0xfc, 0x22, 0x08, 0x18, 0xfb, 0x7f, + 0x88, 0x82, 0xa8, 0x66, 0xc9, 0x25, 0xfe, 0x0b, 0x07, 0x4f, 0x76, 0xc9, 0x1a, 0x95, 0xa6, 0x0c, + 0x7d, 0x7d, 0xf0, 0x81, 0x26, 0x35, 0x55, 0x55, 0x21, 0x06, 0x5c, 0x18, 0x4c, 0xbb, 0x71, 0x10, + 0x99, 0x55, 0x6b, 0x88, 0x68, 0x37, 0xd8, 0x42, 0x6c, 0xfd, 0x3f, 0xc2, 0x04, 0x95, 0x83, 0x61, + 0x45, 0x19, 0xcb, 0x31, 0x7a, 0xaa, 0xe2, 0x02, 0x20, 0xac, 0x4d, 0xa5, 0xb5, 0x5f, 0x09, 0x1a, + 0x69, 0x7f, 0xe6, 0x10, 0x83, 0xc7, 0x6b, 0xe2, 0x02, 0x5e, 0x09, 0x31, 0xe0, 0x98, 0x55, 0x1b, + 0xfc, 0x48, 0x80, 0x42, 0x24, 0x09, 0xb2, 0xee, 0xa8, 0x3b, 0xc1, 0xb2, 0x57, 0x3b, 0xda, 0x7e, + 0xf0, 0xc4, 0x67, 0x41, 0x17, 0x87, 0xe1, 0x01, 0x00, 0xb0, 0x21, 0x15, 0x69, 0x9f, 0x58, 0xf3, + 0x90, 0x63, 0xb5, 0x97, 0x1a, 0xc3, 0x9e, 0x20, 0x13, 0x93, 0x93, 0x55, 0xb7, 0xf7, 0x11, 0x19, + 0x29, 0x0c, 0xea, 0x38, 0xf4, 0xd6, 0x04, 0x0f, 0x19, 0x73, 0xb7, 0x51, 0xc4, 0x1b, 0x29, 0x05, + 0xbc, 0xb7, 0xe3, 0xe2, 0xfd, 0xda, 0x41, 0x6c, 0x2e, 0x95, 0xdf, 0xe1, 0x42, 0x96, 0xda, 0x64, + 0x9e, 0x44, 0xab, 0xa1, 0x3c, 0x30, 0x16, 0x46, 0xaa, 0x0e, 0x6d, 0x2f, 0x5f, 0x56, 0x3e, 0x09, + 0x64, 0x24, 0xcf, 0x31, 0xe3, 0x86, 0x02, 0xdc, 0x07, 0x16, 0xff, 0x82, 0xb3, 0x55, 0x52, 0x52, + 0xb0, 0x4c, 0xdc, 0x77, 0x83, 0xc2, 0xb2, 0xe8, 0x90, 0x9d, 0xc4, 0x88, 0x0a, 0x55, 0x54, 0x79, + 0x10, 0xea, 0x38, 0x05, 0x94, 0xcd, 0x71, 0x2e, 0xb0, 0xae, 0xd3, 0x2b, 0x77, 0x83, 0x97, 0xf8, + 0x91, 0x68, 0x10, 0x26, 0x5e, 0x27, 0x4b, 0x06, 0x3e, 0x61, 0xc9, 0x8b, 0x86, 0x42, 0x05, 0x1a, + 0x4f, 0xc4, 0xf5, 0xd4, 0x4f, 0x46, 0x94, 0x27, 0xd6, 0x09, 0xe0, 0x82, 0x28, 0x65, 0x87, 0x1d, + 0x6e, 0x9a, 0x0d, 0xaf, 0x41, 0x5b, 0x96, 0x52, 0x52, 0x66, 0x10, 0x12, 0x14, 0x9c, 0xd3, 0x4d, + 0xbc, 0xe5, 0xd1, 0xe7, 0x60, 0xa4, 0x3a, 0x0f, 0xdd, 0x9f, 0x1f, 0xeb, 0x7e, 0x6d, 0xf0, 0xa4, + 0x94, 0x2c, 0x27, 0x54, 0xa3, 0x89, 0x43, 0x49, 0x8a, 0x37, 0x37, 0x7b, 0xa6, 0x74, 0xe2, 0x61, + 0x1b, 0xb4, 0x7f, 0xdd, 0xde, 0xd5, 0x8d, 0x97, 0x94, 0x9b, 0xbf, 0x82, 0xc2, 0xa3, 0x5f, 0x15, + 0xf7, 0x77, 0xf9, 0x0b, 0x2f, 0x5f, 0x88, 0x20, 0xa2, 0x65, 0x7c, 0xe7, 0x1b, 0xe2, 0x04, 0x8f, + 0x14, 0x13, 0xd8, 0xf3, 0xc5, 0x9b, 0x03, 0x4c, 0x72, 0x4d, 0x74, 0x7e, 0xf9, 0x64, 0xfc, 0x15, + 0xf1, 0x81, 0x4e, 0x34, 0x81, 0xd4, 0xcf, 0xd1, 0xab, 0xbc, 0x69, 0x01, 0x79, 0x39, 0xd6, 0x0e, + 0x3f, 0xc2, 0x9d, 0x1b, 0xd0, 0x33, 0xe5, 0xbd, 0x47, 0x07, 0x0c, 0xb9, 0xad, 0x75, 0x0d, 0x74, + 0x4d, 0x7c, 0x14, 0x15, 0x04, 0x55, 0x0a, 0xc9, 0x59, 0x95, 0x38, 0xac, 0xf0, 0x45, 0x7c, 0x44, + 0x16, 0x5e, 0xb7, 0xdc, 0x9e, 0x16, 0xa0, 0x97, 0xf9, 0x37, 0x7f, 0x82, 0x8e, 0xab, 0xaa, 0xbd, + 0x62, 0x45, 0x5d, 0xbf, 0x9f, 0xe2, 0x44, 0x89, 0x8b, 0xd2, 0x9c, 0xc5, 0xd3, 0xe0, 0xb7, 0x82, + 0x41, 0xbc, 0x3b, 0x96, 0xaf, 0x10, 0x28, 0x60, 0xe1, 0x30, 0xb1, 0x58, 0xc6, 0x4f, 0xf1, 0x31, + 0xe6, 0x7a, 0x46, 0xce, 0xcb, 0x38, 0x73, 0xad, 0xcc, 0x5d, 0x0c, 0xb3, 0xd1, 0x86, 0xc1, 0x45, + 0xd0, 0xa7, 0x4c, 0x1c, 0xb0, 0x1f, 0x74, 0xf1, 0x94, 0x0d, 0xd5, 0xd9, 0x5b, 0xfb, 0x08, 0x67, + 0xa1, 0xcb, 0x0f, 0x10, 0x52, 0xb1, 0x55, 0x14, 0xed, 0x20, 0x0e, 0xb1, 0x30, 0xeb, 0x11, 0x1d, + 0xf8, 0xe3, 0xc5, 0x94, 0xd4, 0x0e, 0xfd, 0xdf, 0x12, 0x20, 0x15, 0x96, 0xc5, 0x7b, 0xec, 0x9f, + 0xbb, 0xf9, 0xf0, 0x8c, 0xcc, 0x0e, 0x73, 0x0c, 0x8d, 0x5e, 0xcb, 0xde, 0x28, 0x88, 0xf2, 0x1e, + 0xaf, 0x1d, 0x1b, 0xf3, 0xc4, 0x05, 0x59, 0xd3, 0xad, 0x34, 0x74, 0xc2, 0xca, 0xf1, 0xd4, 0xe9, + 0x8f, 0xf9, 0x82, 0xb2, 0xd7, 0xd8, 0x7f, 0xf1, 0x27, 0x53, 0x10, 0x6f, 0x9e, 0x1f, 0x8b, 0x2a, + 0x57, 0xa6, 0xe9, 0xf8, 0x93, 0x0e, 0x5a, 0xe1, 0xb4, 0x15, 0x00, 0x62, 0xdd, 0xf8, 0x8e, 0xfc, + 0xbf, 0xf0, 0x5a, 0xfd, 0xf8, 0x21, 0x5f, 0x4f, 0xe0, 0xae, 0x22, 0x8a, 0xfe, 0x18, 0x30, 0xab, + 0x65, 0x35, 0x4b, 0x89, 0x13, 0x76, 0x90, 0x68, 0x84, 0xd8, 0xe2, 0xe2, 0x20, 0x9c, 0xcc, 0xd6, + 0x8f, 0xaf, 0x3e, 0x7d, 0xc4, 0xc2, 0x84, 0xbe, 0x33, 0xd2, 0x56, 0x91, 0x7e, 0x6d, 0x3b, 0xd6, + 0x9a, 0xb8, 0xac, 0x57, 0x77, 0xe2, 0x04, 0x82, 0x92, 0xad, 0x56, 0xeb, 0x4e, 0x2f, 0xd7, 0x11, + 0x0a, 0x66, 0x6c, 0xbd, 0x13, 0xc0, 0xfd, 0xb8, 0x85, 0x32, 0xb5, 0x23, 0x7b, 0xbf, 0x3d, 0xdf, + 0xe3, 0x24, 0x76, 0xa8, 0xea, 0xc2, 0x36, 0xa2, 0xf3, 0x9e, 0x8c, 0x1a, 0x9e, 0x76, 0xf3, 0x78, + 0x28, 0xcb, 0x7f, 0x6f, 0x2c, 0xf8, 0x0e, 0x7c, 0x15, 0x55, 0x71, 0x2a, 0xff, 0x42, 0x7f, 0x50, + 0xc4, 0x26, 0x3a, 0x2b, 0xdf, 0x15, 0xe1, 0x88, 0x23, 0x09, 0xe3, 0x02, 0x8e, 0xe2, 0xfa, 0x0a, + 0xa5, 0x82, 0x8e, 0x60, 0xb7, 0x02, 0x6a, 0xf8, 0xff, 0x08, 0xc1, 0x1f, 0xb1, 0x4c, 0xfb, 0x86, + 0x22, 0xc4, 0x1a, 0x1d, 0xad, 0x2c, 0x4c, 0x9d, 0x57, 0xc5, 0x1a, 0x68, 0x0d, 0xaa, 0x20, 0xf8, + 0xe7, 0x8b, 0x11, 0xfc, 0x9a, 0x61, 0x1e, 0x20, 0x48, 0x2c, 0xe9, 0x88, 0x79, 0x92, 0xf1, 0x97, + 0x91, 0x6d, 0xd8, 0xdc, 0x47, 0x9c, 0x44, 0x06, 0x59, 0x15, 0xd9, 0xc2, 0xef, 0x84, 0x0e, 0x52, + 0x73, 0xc7, 0xc3, 0x15, 0x54, 0x44, 0x98, 0x46, 0x4a, 0xb2, 0x6f, 0x5a, 0xe2, 0x42, 0x3f, 0x04, + 0xe7, 0x97, 0x2f, 0xa6, 0xfd, 0xe2, 0x01, 0x2c, 0xb8, 0x7f, 0xef, 0x7e, 0xa8, 0x99, 0x2b, 0xaf, + 0x8a, 0x10, 0x49, 0x2f, 0x64, 0xdb, 0x14, 0xa1, 0xb9, 0x88, 0xd2, 0xe2, 0x6c, 0x44, 0xd9, 0x9c, + 0x21, 0xfa, 0x0d, 0xf4, 0x13, 0xc2, 0x10, 0x48, 0x10, 0x97, 0x97, 0x2e, 0x2e, 0x22, 0x0a, 0x2a, + 0x89, 0x53, 0xbb, 0x9f, 0x25, 0xc4, 0x78, 0x81, 0x20, 0x93, 0x2d, 0x15, 0x9a, 0xff, 0x04, 0x66, + 0x7d, 0xff, 0xf1, 0x98, 0x90, 0x65, 0x6b, 0x92, 0xe6, 0xe7, 0xf3, 0x1e, 0xbb, 0x3e, 0xcd, 0x77, + 0xfe, 0x26, 0x0b, 0x85, 0xd3, 0xdd, 0x99, 0x71, 0x2f, 0xbe, 0xaf, 0xf2, 0x95, 0xd8, 0x6e, 0x3a, + 0x06, 0x00, 0xe2, 0x60, 0x87, 0x77, 0xf7, 0x13, 0x11, 0x77, 0xba, 0x3d, 0xf1, 0x15, 0x7e, 0x24, + 0x4f, 0x11, 0x10, 0x29, 0x3d, 0xe7, 0xb7, 0xb5, 0x08, 0x7c, 0x23, 0x04, 0xb0, 0x84, 0x31, 0x96, + 0x83, 0x9e, 0x97, 0x77, 0x7c, 0xb3, 0xfa, 0x7f, 0x88, 0x82, 0xed, 0x93, 0x4e, 0xdd, 0x65, 0x07, + 0x10, 0x24, 0x4d, 0xe3, 0xeb, 0x1e, 0xef, 0xf4, 0x57, 0xf8, 0x28, 0x9f, 0x05, 0x7c, 0xb2, 0x63, + 0xfb, 0xe1, 0x11, 0x95, 0x55, 0xaa, 0xa8, 0xb9, 0x39, 0x15, 0x7e, 0x30, 0xaa, 0x3a, 0x99, 0x43, + 0x1d, 0x4c, 0x8e, 0xff, 0x5e, 0x59, 0x17, 0xdf, 0xe5, 0x63, 0x88, 0x12, 0x51, 0xa6, 0xff, 0xc9, + 0xc5, 0xd7, 0xd7, 0xfe, 0x25, 0xf2, 0xfe, 0x20, 0x4f, 0xc2, 0x45, 0xbb, 0xdd, 0x0d, 0xfc, 0x4a, + 0xbf, 0x12, 0x24, 0x12, 0x11, 0xdd, 0xf5, 0xc4, 0x89, 0x44, 0xff, 0xc4, 0x0a, 0x9f, 0x32, 0xe3, + 0xbb, 0xf8, 0x23, 0xad, 0x57, 0xb8, 0x88, 0x24, 0x3e, 0x2b, 0x6e, 0xf0, 0x47, 0x08, 0x41, 0x46, + 0xd2, 0xd3, 0xbf, 0xb8, 0x60, 0x22, 0x08, 0x7a, 0xad, 0xfc, 0x4f, 0xc5, 0xee, 0xf7, 0xaf, 0xcb, + 0xd5, 0x78, 0x90, 0x8d, 0xde, 0x6b, 0xad, 0x55, 0xb0, 0x8f, 0xaf, 0x12, 0x3c, 0x42, 0x85, 0xcc, + 0xac, 0x96, 0xa5, 0x04, 0x5e, 0x1d, 0x2c, 0x0f, 0x92, 0x92, 0x85, 0x62, 0x89, 0xdf, 0x88, 0x2d, + 0x45, 0xd4, 0x5f, 0xca, 0x75, 0xcb, 0xfc, 0x10, 0x89, 0x5a, 0xdf, 0xe4, 0xbb, 0xf8, 0x99, 0x8e, + 0x8f, 0x15, 0xe2, 0x44, 0x89, 0x23, 0xd2, 0x4a, 0xef, 0xc4, 0x89, 0x13, 0x77, 0xbe, 0xef, 0xea, + 0xfe, 0x24, 0x85, 0x4e, 0xbc, 0x47, 0xe2, 0x35, 0xaa, 0x75, 0xa8, 0x88, 0x78, 0x20, 0xba, 0xca, + 0x41, 0xb4, 0xab, 0xc5, 0x4c, 0x5b, 0xff, 0x08, 0x42, 0x37, 0x7d, 0x0e, 0xbd, 0x51, 0xf8, 0x26, + 0x12, 0xef, 0xdd, 0x1d, 0xe1, 0xfe, 0x52, 0xd6, 0xb8, 0x42, 0x09, 0xcc, 0x9e, 0xf4, 0x4e, 0xe7, + 0xb8, 0x60, 0x22, 0x0b, 0xa3, 0x9e, 0xfa, 0xae, 0xfc, 0x4c, 0xc5, 0x49, 0xb8, 0xe4, 0xaf, 0x14, + 0x29, 0x03, 0x6a, 0x95, 0xef, 0xe0, 0x84, 0x4a, 0xad, 0x79, 0xfe, 0x12, 0xd6, 0xab, 0x55, 0xf0, + 0x5a, 0x4e, 0xc6, 0xf9, 0x73, 0xde, 0x20, 0x29, 0x13, 0x60, 0x8c, 0xa8, 0xca, 0x3d, 0xdf, 0x29, + 0x9b, 0xdb, 0xdd, 0xbf, 0xf1, 0x22, 0x41, 0x3f, 0x15, 0xc5, 0x6e, 0xf7, 0xe2, 0x24, 0xa6, 0xf7, + 0xe2, 0x41, 0x68, 0x97, 0x7c, 0x1f, 0x77, 0x4e, 0x8e, 0xfc, 0x11, 0xdd, 0xc5, 0x6e, 0xff, 0x09, + 0x6e, 0xee, 0x9b, 0xfc, 0x40, 0x21, 0xbb, 0xbb, 0xd7, 0x11, 0xfb, 0x2e, 0xee, 0xf9, 0x89, 0x5a, + 0xf1, 0x20, 0x9f, 0x33, 0x1c, 0xcc, 0x7f, 0xe1, 0x11, 0x20, 0x9a, 0x91, 0x33, 0x2d, 0x35, 0x7e, + 0x10, 0x90, 0x54, 0x43, 0x4f, 0x08, 0x41, 0x59, 0x2e, 0xd3, 0x4a, 0xbf, 0x17, 0x8b, 0xe1, 0xb2, + 0xe6, 0xcc, 0x14, 0xd1, 0xb8, 0x1a, 0xf7, 0xde, 0x1e, 0x86, 0x04, 0x82, 0xc2, 0xdc, 0x99, 0x7a, + 0x6d, 0x9f, 0x79, 0x4c, 0x41, 0xd6, 0xf1, 0x04, 0xb7, 0x34, 0x2a, 0x26, 0x08, 0x6b, 0x5b, 0xf1, + 0x21, 0x00, 0x54, 0x65, 0x53, 0x78, 0x96, 0xaa, 0xb5, 0x5e, 0xe2, 0x44, 0x82, 0xe1, 0x2f, 0x4e, + 0xbb, 0xbf, 0xc9, 0xbd, 0xaf, 0x08, 0x88, 0x65, 0x41, 0xaa, 0x77, 0xd2, 0xbf, 0x90, 0xb5, 0x55, + 0xe2, 0x04, 0xf3, 0x78, 0x9b, 0x09, 0xa9, 0x58, 0xf1, 0x42, 0x5b, 0xbb, 0x6a, 0xbf, 0xb9, 0x7b, + 0xc6, 0xf8, 0x46, 0xaf, 0xe2, 0x45, 0x5d, 0xce, 0x93, 0xd3, 0x7c, 0x44, 0x45, 0xdd, 0xde, 0xf7, + 0xf4, 0x47, 0xf1, 0x1f, 0x20, 0xbd, 0x57, 0x89, 0x42, 0x3b, 0xeb, 0xde, 0x25, 0x7b, 0xc4, 0x96, + 0x5c, 0xf8, 0x90, 0x88, 0xbc, 0xd9, 0xed, 0x3f, 0x12, 0x43, 0x3a, 0x5e, 0x10, 0x82, 0x92, 0x63, + 0x77, 0x35, 0x64, 0xed, 0xf4, 0x9d, 0xfc, 0x7c, 0x32, 0x7a, 0x54, 0xd7, 0x06, 0x5a, 0xfe, 0x1d, + 0xe1, 0x4b, 0xea, 0xc7, 0x77, 0x52, 0xfb, 0xbf, 0xef, 0xf9, 0x78, 0x90, 0x43, 0x9a, 0x9f, 0xfe, + 0x08, 0x7b, 0x6b, 0xdc, 0x44, 0x13, 0xf2, 0xf7, 0xd5, 0x37, 0xf8, 0x29, 0x22, 0xc4, 0xc8, 0x35, + 0xac, 0x5d, 0x45, 0xff, 0xfb, 0x2a, 0xaf, 0xe1, 0x1b, 0x9f, 0x28, 0xdf, 0x43, 0x40, 0xf3, 0xef, + 0x8e, 0xd4, 0x2b, 0x58, 0x51, 0xc5, 0xf7, 0x7f, 0x0d, 0x38, 0x16, 0xbc, 0x2a, 0x55, 0xaf, 0x5f, + 0xfc, 0x95, 0x71, 0x24, 0x2a, 0xc9, 0xdf, 0xc5, 0x96, 0xee, 0xfc, 0x69, 0xa3, 0xc5, 0xf4, 0x88, + 0xee, 0x36, 0xdf, 0xa0, 0x58, 0x90, 0x89, 0x2f, 0x7e, 0x26, 0x09, 0x0c, 0xee, 0xef, 0x7f, 0x10, + 0x4b, 0xef, 0xc4, 0x82, 0x32, 0xaa, 0xef, 0xc4, 0x51, 0xdf, 0xc2, 0x26, 0xd5, 0x0d, 0x7c, 0xc3, + 0xab, 0x5f, 0x04, 0x87, 0xdd, 0xfb, 0xe5, 0xdd, 0xf8, 0x8b, 0x12, 0x96, 0xf8, 0x88, 0x89, 0x88, + 0x98, 0x8d, 0x9d, 0x31, 0xd8, 0xc6, 0x64, 0x57, 0xc4, 0xbf, 0x89, 0x09, 0x19, 0x6a, 0xa4, 0xb2, + 0x5a, 0x32, 0xe7, 0x84, 0x44, 0x98, 0x9a, 0xae, 0x20, 0x48, 0x2a, 0x22, 0x57, 0xc6, 0xe5, 0x0b, + 0xc6, 0x29, 0xa8, 0xb9, 0x28, 0x70, 0x7c, 0x13, 0x74, 0x6f, 0xcd, 0x0b, 0x43, 0x70, 0x84, 0x10, + 0x5b, 0x4d, 0xb4, 0x3b, 0x69, 0xe1, 0x7d, 0x10, 0xc9, 0x83, 0x40, 0x25, 0x9e, 0x21, 0xa7, 0xe2, + 0x04, 0xad, 0x78, 0x94, 0x27, 0xff, 0x44, 0xee, 0x22, 0x08, 0xb1, 0x9a, 0x74, 0xbe, 0x24, 0xa2, + 0x16, 0xa9, 0xfa, 0x12, 0xfe, 0x20, 0x12, 0x5d, 0xbe, 0x7f, 0x12, 0x09, 0x31, 0x76, 0xc5, 0xff, + 0xf3, 0x79, 0x3f, 0x94, 0xa8, 0x9b, 0xaf, 0x82, 0x10, 0x80, 0x50, 0x58, 0x90, 0x1e, 0x58, 0xc4, + 0x83, 0xcb, 0x7b, 0xbb, 0x76, 0xeb, 0x58, 0xfd, 0xc4, 0x04, 0x41, 0x50, 0xa8, 0xae, 0x87, 0x91, + 0x44, 0x20, 0x18, 0x1b, 0xa1, 0xfe, 0xe2, 0x24, 0xbb, 0xbb, 0xe2, 0x03, 0x00, 0xa7, 0x2d, 0x94, + 0xb6, 0xe7, 0x47, 0xbb, 0xbb, 0xbf, 0x89, 0x5e, 0xfa, 0xf5, 0x73, 0x6b, 0x5e, 0x27, 0xc4, 0x82, + 0x6e, 0xab, 0xa6, 0x7e, 0xfc, 0x40, 0x9f, 0xa2, 0xbf, 0xc1, 0x2e, 0xee, 0xf7, 0x72, 0xd1, 0xf8, + 0x98, 0x4b, 0xbb, 0x47, 0xa3, 0x3f, 0xd9, 0x92, 0x2e, 0xb5, 0xf8, 0xa3, 0x49, 0xf7, 0x7a, 0x1e, + 0x20, 0x48, 0x29, 0xea, 0x52, 0x19, 0xaa, 0x7c, 0x98, 0xac, 0x21, 0x17, 0xa7, 0xcc, 0x7d, 0xb5, + 0x0d, 0x44, 0x43, 0xa6, 0x33, 0x22, 0x5e, 0x66, 0x6e, 0x99, 0x6e, 0x86, 0xe5, 0x60, 0x56, 0xf9, + 0x45, 0x6e, 0xcc, 0x97, 0xfc, 0x40, 0x44, 0x27, 0x3f, 0xf4, 0x8f, 0xdf, 0xe2, 0x78, 0x8a, 0x2f, + 0x56, 0x24, 0x10, 0x88, 0x54, 0xef, 0xfe, 0x22, 0x09, 0x04, 0xa7, 0x23, 0x3a, 0xf8, 0x9d, 0x32, + 0xb3, 0xb9, 0x18, 0x8b, 0xf8, 0xe2, 0xdd, 0x8d, 0xc6, 0xcd, 0xb1, 0x3f, 0xd9, 0x99, 0x71, 0x08, + 0x59, 0xa5, 0xe2, 0x63, 0x24, 0xe9, 0xe9, 0xee, 0x5f, 0x95, 0x41, 0xf9, 0x40, 0x00, 0x39, 0x6d, + 0xfc, 0x15, 0xc3, 0xac, 0x03, 0xbb, 0x8c, 0xa0, 0xab, 0x48, 0xb7, 0x7e, 0x5b, 0xf1, 0x02, 0x59, + 0x1d, 0xff, 0x05, 0x85, 0x6e, 0xf2, 0x92, 0x2f, 0xed, 0xdd, 0xdf, 0x84, 0x01, 0x89, 0x48, 0x52, + 0x09, 0x09, 0x5f, 0x84, 0x20, 0xb4, 0xb5, 0xab, 0xbd, 0xdf, 0xc1, 0x08, 0x23, 0xa2, 0xb6, 0xbd, + 0xe2, 0x4b, 0xdd, 0xde, 0x24, 0x22, 0x67, 0xbb, 0x7b, 0xbe, 0xe5, 0xcc, 0x4c, 0x17, 0x1d, 0xef, + 0x3b, 0x18, 0xad, 0xfe, 0x0a, 0x2e, 0x58, 0x3e, 0x81, 0xa2, 0x7b, 0xfc, 0x16, 0x69, 0x3b, 0xbd, + 0xee, 0xe5, 0xce, 0x5f, 0x7c, 0xd4, 0xf1, 0x2a, 0xfe, 0x25, 0x5f, 0x89, 0x08, 0xf1, 0x12, 0x0a, + 0x64, 0x62, 0x0d, 0x71, 0x10, 0x53, 0x9f, 0x3b, 0xbc, 0x9e, 0x2f, 0x1d, 0xbe, 0x0a, 0x45, 0xc8, + 0xa5, 0x6d, 0xbb, 0xf2, 0xbd, 0xe2, 0x86, 0x38, 0x70, 0x44, 0xcc, 0x44, 0xd2, 0x2d, 0xe7, 0x9f, + 0xf1, 0x22, 0x60, 0x77, 0xd7, 0x3f, 0xc9, 0x06, 0x65, 0x7a, 0xe2, 0x21, 0x23, 0x9f, 0xdb, 0xbb, + 0xa7, 0xc4, 0x89, 0x5b, 0xfc, 0x11, 0xea, 0xb7, 0xe2, 0x44, 0x88, 0xd6, 0xba, 0x6f, 0xe6, 0x11, + 0x55, 0xe2, 0x44, 0x82, 0xc3, 0xbd, 0xe9, 0xbe, 0xf7, 0x7e, 0xf1, 0x22, 0xe4, 0xff, 0x2d, 0x3c, + 0x48, 0x47, 0xc2, 0x20, 0x86, 0xf5, 0xef, 0xf0, 0x9f, 0x1d, 0x35, 0x4f, 0xf1, 0x55, 0x4e, 0x9b, + 0xcb, 0x85, 0xcf, 0x25, 0xf7, 0xf6, 0x25, 0xee, 0x55, 0x1c, 0x20, 0x24, 0x97, 0x7b, 0xef, 0xc4, + 0x08, 0xbd, 0xea, 0xd7, 0xee, 0xee, 0xfc, 0x4f, 0xc4, 0xa3, 0x77, 0x13, 0x16, 0x5e, 0x4c, 0xe7, + 0x63, 0x10, 0x10, 0x1d, 0x2e, 0x5a, 0x3c, 0x37, 0x7c, 0xb8, 0x4d, 0xf1, 0x77, 0xdd, 0x37, 0xd6, + 0x26, 0x4e, 0x5b, 0xbb, 0xf8, 0x91, 0x42, 0x1d, 0xbe, 0x80, 0xd5, 0x7c, 0x37, 0x15, 0xa2, 0x03, + 0xa5, 0xa9, 0xef, 0x0a, 0x9b, 0x16, 0x70, 0xb2, 0x83, 0xf0, 0xbf, 0x37, 0x8e, 0x47, 0x61, 0x81, + 0x23, 0x60, 0xff, 0x88, 0x16, 0x13, 0x28, 0xf4, 0x09, 0x13, 0xbe, 0xb7, 0x8f, 0x60, 0xcd, 0xd1, + 0xa0, 0x8b, 0x2d, 0x64, 0x3e, 0x35, 0xa4, 0xde, 0xe6, 0x1b, 0x9c, 0x3c, 0x6d, 0x02, 0x3f, 0xf8, + 0x96, 0x57, 0xec, 0xd6, 0x4a, 0x71, 0x0c, 0xae, 0xff, 0x12, 0x09, 0x4a, 0xfa, 0x27, 0xbb, 0xdf, + 0xe0, 0x90, 0x95, 0xad, 0x7c, 0x14, 0x5a, 0x69, 0x6b, 0x55, 0x7a, 0xe4, 0x10, 0xf7, 0xf0, 0x87, + 0x88, 0x18, 0x36, 0xf7, 0x15, 0xbb, 0xbb, 0xb8, 0xaf, 0x77, 0x7e, 0x11, 0x19, 0x49, 0x74, 0xdb, + 0x4d, 0xbd, 0xd5, 0xca, 0xc3, 0xb5, 0x8c, 0x40, 0x93, 0x11, 0xcf, 0x47, 0xbf, 0x05, 0x19, 0xf1, + 0xf7, 0x71, 0x5b, 0xbf, 0x84, 0x01, 0x0e, 0xf7, 0x7e, 0x24, 0x40, 0x21, 0xbe, 0xef, 0x51, 0x3a, + 0x89, 0xf8, 0x85, 0xee, 0x20, 0x48, 0xae, 0xee, 0xfb, 0xf1, 0x22, 0xee, 0xef, 0x77, 0x77, 0xf0, + 0x89, 0x5a, 0x10, 0xe3, 0x9e, 0xe3, 0xbb, 0x8a, 0xdd, 0x4d, 0x05, 0x67, 0x30, 0xf0, 0x59, 0x3e, + 0x59, 0x6f, 0x77, 0x15, 0xb9, 0xfb, 0xf1, 0x30, 0x55, 0xbb, 0xe9, 0xbe, 0xef, 0x7f, 0x82, 0x19, + 0xf1, 0x21, 0x5a, 0x4f, 0xe2, 0x57, 0xbe, 0xbd, 0xe1, 0x12, 0xd5, 0x55, 0x71, 0x21, 0x12, 0x10, + 0x99, 0xfc, 0x32, 0x0a, 0x8d, 0x94, 0x3f, 0x6d, 0x18, 0x87, 0x96, 0x2d, 0x0c, 0x11, 0xd6, 0x43, + 0xd6, 0x41, 0xdf, 0x22, 0xf1, 0xc7, 0xca, 0xc3, 0x11, 0xb4, 0xf9, 0x45, 0xb7, 0x31, 0x5e, 0xdc, + 0xe1, 0x5e, 0x6f, 0x0d, 0x52, 0x7c, 0x30, 0x3c, 0x65, 0x35, 0xd9, 0xdb, 0x95, 0xca, 0xc6, 0x20, + 0x22, 0xea, 0xcc, 0x7b, 0x0f, 0x89, 0x04, 0x42, 0x6f, 0x77, 0xf8, 0xa2, 0xdd, 0xdc, 0xb0, 0xdb, + 0xe2, 0x44, 0x3c, 0xb9, 0xf9, 0x35, 0x55, 0xe2, 0x15, 0xfc, 0x43, 0xd6, 0xbe, 0x6d, 0x6a, 0xa1, + 0x10, 0x80, 0x44, 0xae, 0xee, 0xc6, 0xe7, 0xaa, 0x75, 0xf5, 0x4f, 0x88, 0x0a, 0x5d, 0xdd, 0xf7, + 0x3f, 0x2d, 0x2e, 0x33, 0xd0, 0xec, 0x3f, 0xed, 0xbf, 0x84, 0x01, 0x5e, 0x78, 0x5c, 0x5b, 0xa7, + 0x7b, 0xbd, 0x7c, 0x10, 0xf6, 0xcb, 0xdf, 0xe0, 0x92, 0x2f, 0xbb, 0xfc, 0x10, 0xe9, 0xd3, 0x7e, + 0x26, 0x84, 0x75, 0x62, 0x6a, 0x22, 0x38, 0xf3, 0xed, 0xcd, 0x9f, 0x97, 0x0b, 0x9c, 0x40, 0x4a, + 0x2b, 0x77, 0x7d, 0xd3, 0x58, 0x90, 0x59, 0xcf, 0x47, 0xbd, 0x95, 0xbb, 0xfb, 0x89, 0x82, 0x9b, + 0xbd, 0xef, 0x77, 0x77, 0x7f, 0xfc, 0x10, 0xdd, 0xdd, 0xdf, 0x88, 0xab, 0xfc, 0xba, 0xaa, 0xbe, + 0x09, 0x6e, 0xf9, 0xf1, 0xaa, 0xf7, 0xc5, 0x08, 0x4c, 0x7c, 0x44, 0x55, 0xc9, 0x9a, 0xf0, 0xc8, + 0xde, 0x39, 0x2f, 0x71, 0x46, 0x2b, 0x15, 0x9f, 0xa6, 0x5c, 0x44, 0xd4, 0x97, 0xd8, 0xaf, 0x4a, + 0x02, 0xbf, 0xfe, 0x2c, 0xe9, 0x27, 0xd2, 0xa4, 0x14, 0x88, 0x8a, 0x11, 0xe6, 0xee, 0xb9, 0x60, + 0xb3, 0xb0, 0x9b, 0xab, 0x0c, 0x04, 0x42, 0x17, 0x0c, 0x0c, 0x50, 0x99, 0xc7, 0x6f, 0x94, 0x6e, + 0x2b, 0x3a, 0xaf, 0x11, 0xc4, 0x41, 0x41, 0xd6, 0x95, 0x75, 0xff, 0x88, 0x05, 0xb4, 0x37, 0x56, + 0x96, 0xb7, 0xf0, 0x88, 0x52, 0xf1, 0x58, 0xad, 0xef, 0x3e, 0x62, 0xb3, 0xe3, 0xf7, 0xbf, 0x89, + 0x45, 0x7e, 0x26, 0x09, 0x73, 0xbd, 0xbe, 0x7e, 0xbb, 0xfc, 0x11, 0xeb, 0x57, 0xe2, 0x44, 0x82, + 0x32, 0x2a, 0xaa, 0xbf, 0x89, 0x54, 0x77, 0xe0, 0x8e, 0xb5, 0xbf, 0xd7, 0xbe, 0x6c, 0xec, 0x3d, + 0x1f, 0xab, 0xf1, 0x37, 0x77, 0xd7, 0x16, 0x59, 0x58, 0x7e, 0xe2, 0xb7, 0xc4, 0x89, 0xe2, 0x28, + 0x9d, 0xe2, 0x41, 0x61, 0x5e, 0x5c, 0x7b, 0x6e, 0xf1, 0xbf, 0xdf, 0x79, 0xf1, 0xf5, 0xc4, 0x14, + 0xd4, 0xea, 0xb5, 0x86, 0x70, 0x9b, 0xe4, 0x75, 0x7c, 0xf4, 0xe9, 0x97, 0xfe, 0xdf, 0x57, 0xf8, + 0x2b, 0xe5, 0xa6, 0xab, 0x55, 0x37, 0x9f, 0xfc, 0x95, 0xaa, 0xf9, 0x08, 0xb5, 0xf8, 0x22, 0xaa, + 0xd7, 0xbe, 0x13, 0xad, 0x75, 0x5f, 0x10, 0x0b, 0x3a, 0xaa, 0xae, 0xab, 0x51, 0xda, 0xb8, 0x20, + 0x14, 0x5a, 0x1c, 0x3e, 0x21, 0xf4, 0xd7, 0x2f, 0x8d, 0x65, 0xab, 0xad, 0x97, 0xe2, 0x20, 0xac, + 0xf7, 0x63, 0x75, 0x6b, 0x46, 0x4a, 0x09, 0x06, 0xa2, 0xeb, 0xdb, 0xf4, 0x27, 0x89, 0x5e, 0xe1, + 0x08, 0xc1, 0x09, 0x08, 0x68, 0x21, 0xe7, 0xba, 0x12, 0xe0, 0x70, 0x6d, 0x94, 0xe8, 0x2e, 0xbd, + 0xb9, 0x39, 0xb8, 0x0a, 0x3a, 0x85, 0xcb, 0xca, 0xca, 0xf1, 0x3f, 0x45, 0xff, 0x10, 0x24, 0x24, + 0x25, 0x57, 0xad, 0xf8, 0x80, 0x91, 0xae, 0xca, 0xab, 0xe2, 0x44, 0x09, 0x10, 0x6e, 0xce, 0xb3, + 0x5a, 0x2e, 0x24, 0x22, 0x11, 0xcd, 0x8a, 0x37, 0x8d, 0xfe, 0xa2, 0xeb, 0xe2, 0x02, 0x95, 0x51, + 0x72, 0x7a, 0x3a, 0x89, 0x3e, 0x44, 0x1f, 0xea, 0xaf, 0xf3, 0x13, 0x51, 0x7e, 0x23, 0xc4, 0x71, + 0x3f, 0x8f, 0xde, 0xee, 0x5c, 0x15, 0x96, 0xdc, 0x57, 0xe2, 0x44, 0x8b, 0x23, 0xbb, 0xbb, 0xbb, + 0xbf, 0x12, 0x6d, 0xdf, 0x88, 0x08, 0x8b, 0x39, 0x58, 0x72, 0xfc, 0xf9, 0x55, 0xe2, 0x44, 0x1b, + 0x77, 0x7b, 0xd4, 0x48, 0x80, 0x4c, 0x7d, 0xd2, 0x4d, 0xbe, 0xfe, 0x20, 0x5e, 0xee, 0xfc, 0xcd, + 0xf0, 0x8c, 0x56, 0xf7, 0x77, 0xde, 0xed, 0xdf, 0x16, 0x54, 0x97, 0xad, 0x78, 0x90, 0x99, 0x13, + 0xd3, 0xd5, 0xae, 0x24, 0x95, 0xd7, 0xcb, 0xcd, 0xfe, 0xcf, 0x5a, 0xf8, 0x27, 0x32, 0xcd, 0xc5, + 0xd1, 0x55, 0x7b, 0x89, 0x82, 0x6e, 0xaa, 0xb4, 0xa5, 0x4e, 0x20, 0x49, 0x4c, 0xab, 0xe2, 0x23, + 0xce, 0xd3, 0x6a, 0x6e, 0xaa, 0xe5, 0x1d, 0x64, 0x97, 0x98, 0xa9, 0x2f, 0xe0, 0x9c, 0x55, 0xc2, + 0x0d, 0xaa, 0xaa, 0xf7, 0x86, 0x41, 0x19, 0x09, 0x99, 0xff, 0xe1, 0xb1, 0x28, 0xa5, 0xca, 0xe3, + 0x3d, 0xf9, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1e, 0x0f, 0x30, 0x26, 0x8d, 0xd1, 0xdd, + 0x0a, 0xf4, 0x2f, 0xe4, 0x2b, 0x12, 0x27, 0xc4, 0x7e, 0x1e, 0xe1, 0x73, 0x72, 0x30, 0x66, 0xbf, + 0xf1, 0x23, 0xf3, 0x69, 0x6e, 0xd7, 0xa2, 0x8b, 0xaf, 0x82, 0x39, 0xf1, 0xa0, 0x9f, 0x1c, 0xa9, + 0xc8, 0x33, 0xe8, 0x9d, 0xf0, 0xcf, 0x69, 0x73, 0xe4, 0x83, 0x74, 0xe3, 0xfe, 0xc3, 0xf0, 0x51, + 0x4a, 0x1a, 0x19, 0xb2, 0x2d, 0xdc, 0xe2, 0x63, 0xe1, 0xd3, 0xf9, 0xb3, 0x3e, 0x1f, 0x32, 0x65, + 0xce, 0x22, 0x64, 0x44, 0xcf, 0xf9, 0xe3, 0xca, 0x9a, 0x71, 0xa7, 0xe1, 0x5e, 0x89, 0xdf, 0x53, + 0x27, 0xd6, 0xa4, 0xe8, 0x8f, 0xf5, 0x78, 0x5b, 0xa3, 0x89, 0xdc, 0xf9, 0xfd, 0x4d, 0x34, 0xd3, + 0x2b, 0x35, 0x95, 0x97, 0xc7, 0xcf, 0x1d, 0x80, 0xf4, 0xd3, 0x4d, 0x36, 0xdb, 0xad, 0xbf, 0x0f, + 0xce, 0xc7, 0x61, 0x12, 0xa5, 0x42, 0xe5, 0xc3, 0x2b, 0xa4, 0xee, 0xa7, 0x4c, 0x2d, 0xa5, 0x7f, + 0xfd, 0x13, 0xbe, 0xa5, 0x47, 0x4f, 0x9a, 0xaa, 0xef, 0xe8, 0xcf, 0x5d, 0x1d, 0xeb, 0x9c, 0xa0, + 0x34, 0x00, 0x7d, 0xb6, 0xdb, 0x6f, 0xc1, 0x1c, 0x7d, 0x0a, 0x5c, 0x00, 0x03, 0x01, 0x8e, 0xe8, + 0xce, 0x88, 0xe4, 0x7f, 0x2d, 0xea, 0xe2, 0x7a, 0xba, 0x58, 0x40, 0x40, 0x28, 0x19, 0x8c, 0xa0, + 0xac, 0x18, 0xa6, 0x82, 0x32, 0xc2, 0xd3, 0x89, 0x32, 0xaa, 0x25, 0x8c, 0x2d, 0x1c, 0x20, 0x10, + 0x0c, 0x5d, 0x9b, 0x80, 0x46, 0x0f, 0x6a, 0x97, 0xc5, 0x78, 0x00, 0x8f, 0x1c, 0x5c, 0x4c, 0xd7, + 0xfc, 0x14, 0x0f, 0xb9, 0x86, 0x0c, 0xea, 0x94, 0x83, 0xb7, 0x11, 0x57, 0xf1, 0x2a, 0xf2, 0xf0, + 0x48, 0x42, 0x4c, 0xf0, 0xc5, 0xf7, 0xc2, 0x02, 0x49, 0x19, 0xf0, 0xf8, 0xdc, 0x7e, 0x64, 0xc3, + 0xe1, 0x08, 0x3f, 0x8d, 0x21, 0xc8, 0x35, 0x8a, 0xfe, 0xb5, 0x7d, 0x4e, 0x05, 0x29, 0x67, 0xd6, + 0xa7, 0x48, 0x5d, 0xf5, 0x40, 0x5f, 0x82, 0xde, 0xe7, 0x64, 0xec, 0xee, 0x55, 0xa2, 0x7a, 0xf2, + 0xa3, 0x75, 0xe8, 0x67, 0x11, 0xe2, 0x01, 0x50, 0x60, 0x9e, 0xa7, 0x86, 0x92, 0xcc, 0x45, 0xc5, + 0x89, 0x06, 0xb9, 0x05, 0xeb, 0xe9, 0x9f, 0x85, 0x27, 0x9a, 0x05, 0x51, 0x25, 0x13, 0x4a, 0xe5, + 0xb0, 0x9d, 0x28, 0x41, 0x6d, 0xe8, 0x0b, 0xd9, 0xcd, 0x87, 0x7d, 0x96, 0xcf, 0x11, 0x01, 0x22, + 0x2d, 0xa4, 0x8e, 0x0f, 0x84, 0x85, 0xea, 0xa0, 0xfd, 0x8d, 0x89, 0xf8, 0x64, 0x47, 0x42, 0xc7, + 0x97, 0xd7, 0xbc, 0x40, 0x22, 0xbb, 0xf8, 0x7d, 0x7a, 0x0a, 0x71, 0x20, 0x9c, 0x30, 0xa8, 0xb4, + 0x6c, 0x75, 0xa3, 0xbf, 0x05, 0x54, 0x12, 0xc2, 0x78, 0x20, 0x17, 0xa8, 0x83, 0x8f, 0xd6, 0x20, + 0xf5, 0x0b, 0x50, 0x38, 0xab, 0xf1, 0x01, 0x01, 0x64, 0xab, 0xf2, 0x7e, 0x11, 0x94, 0x2a, 0xba, + 0x92, 0x18, 0x10, 0x11, 0x09, 0x67, 0xde, 0x5b, 0x10, 0xd8, 0xf5, 0x3f, 0x86, 0x04, 0x70, 0xc0, + 0x82, 0x13, 0x54, 0xf0, 0x80, 0x81, 0x1d, 0x57, 0x55, 0xc2, 0x11, 0x25, 0xdb, 0x57, 0xb9, 0x58, + 0xc3, 0x18, 0x2a, 0xc4, 0x7c, 0x13, 0xcf, 0xb1, 0x60, 0xea, 0x60, 0xb6, 0x07, 0x65, 0x42, 0xd8, + 0xec, 0xc1, 0xc8, 0xc1, 0x7f, 0x04, 0x22, 0x6d, 0xeb, 0x56, 0xd4, 0x90, 0xc7, 0xc4, 0xbd, 0xdf, + 0xe1, 0x21, 0xa8, 0x21, 0xf1, 0x3f, 0xde, 0xf8, 0x81, 0x3c, 0x48, 0x92, 0x91, 0xdf, 0xc4, 0x89, + 0x30, 0xae, 0x58, 0x71, 0x20, 0x8c, 0x6a, 0x1c, 0xbf, 0x14, 0x15, 0x62, 0x41, 0x39, 0xad, 0xa7, + 0x4d, 0x88, 0xb1, 0x8c, 0x63, 0xde, 0x20, 0x79, 0x39, 0x14, 0x31, 0x9e, 0xf7, 0x32, 0x7b, 0xc5, + 0xb2, 0xd8, 0xb6, 0x7f, 0xc2, 0x02, 0x6b, 0xba, 0x8d, 0x19, 0x4c, 0x5c, 0x99, 0x7e, 0xc8, 0xb7, + 0x89, 0xb3, 0xb8, 0x62, 0x09, 0x04, 0xc5, 0x73, 0xf7, 0xf9, 0x46, 0x2a, 0xff, 0x61, 0x13, 0xfb, + 0x5c, 0x32, 0x23, 0xc4, 0x18, 0x9c, 0x22, 0xf4, 0x79, 0x85, 0x6a, 0xbe, 0x23, 0xca, 0xd7, 0xa5, + 0xc1, 0x5f, 0x04, 0x43, 0x5b, 0x22, 0x54, 0x3a, 0x21, 0xdb, 0x88, 0x08, 0x84, 0x45, 0x0b, 0xb1, + 0x40, 0x9f, 0x67, 0xaa, 0x77, 0x28, 0x9f, 0x10, 0x10, 0x13, 0x6a, 0x83, 0xdf, 0x6f, 0xe1, 0x45, + 0x09, 0x7e, 0x15, 0x33, 0x04, 0xf7, 0x93, 0xb3, 0xd0, 0x4f, 0xf5, 0xea, 0x27, 0x51, 0x02, 0x78, + 0x8b, 0x18, 0xd0, 0xd6, 0x63, 0x19, 0x63, 0xf9, 0x42, 0x2a, 0xaa, 0xa1, 0xde, 0x43, 0x3b, 0xc4, + 0x3f, 0x88, 0x18, 0x39, 0x3b, 0x19, 0x19, 0x11, 0x06, 0xe2, 0xfa, 0x8b, 0xe6, 0x60, 0xcc, 0x44, + 0xfb, 0x74, 0xbc, 0x66, 0x30, 0x71, 0x2c, 0x34, 0xf0, 0x84, 0x10, 0x71, 0x22, 0x1a, 0x64, 0xe0, + 0xe5, 0xe1, 0xac, 0x4c, 0x96, 0x1b, 0xeb, 0x25, 0x93, 0xa4, 0x83, 0xe7, 0xc6, 0x83, 0xc1, 0x00, + 0x40, 0x5d, 0x8c, 0x2e, 0x23, 0x8a, 0xdc, 0x40, 0xff, 0x38, 0x80, 0x87, 0x55, 0xdd, 0x37, 0xaa, + 0xf8, 0x21, 0xc2, 0x67, 0x81, 0xee, 0x0b, 0xbc, 0x40, 0x27, 0xde, 0xf0, 0xa2, 0xc4, 0x24, 0x62, + 0xa6, 0x5f, 0x71, 0xfe, 0x42, 0x6c, 0x6f, 0x89, 0x8e, 0x2a, 0xa9, 0x71, 0x22, 0x4e, 0x03, 0x82, + 0x62, 0x07, 0x21, 0xb7, 0x8f, 0xdd, 0xaa, 0x17, 0xc6, 0x7f, 0xe2, 0x19, 0xc7, 0x42, 0x02, 0xb5, + 0x7e, 0xa8, 0x16, 0x43, 0x01, 0x00, 0x89, 0x13, 0x40, 0xc9, 0xfb, 0x94, 0x85, 0x1c, 0x2f, 0x52, + 0xf4, 0xbf, 0x10, 0x12, 0x24, 0x2b, 0x32, 0xaf, 0x13, 0xd2, 0x17, 0xf1, 0x22, 0x0d, 0x5c, 0xcc, + 0x7b, 0x2c, 0x94, 0xf1, 0x33, 0x5e, 0x7c, 0x7c, 0x48, 0x81, 0xd4, 0xd2, 0xf7, 0x3d, 0x39, 0xfe, + 0x26, 0x0a, 0x0c, 0xba, 0xaa, 0xad, 0xfe, 0x08, 0xeb, 0x5f, 0x7d, 0x84, 0x41, 0x1b, 0xa1, 0xd8, + 0x43, 0x56, 0xfa, 0xf0, 0x88, 0x98, 0x9e, 0x85, 0xea, 0x1c, 0xe8, 0xd8, 0x4f, 0x0c, 0x04, 0x0c, + 0x39, 0xb5, 0x3c, 0xbc, 0x4c, 0xd5, 0x63, 0xf1, 0x02, 0x44, 0x15, 0xa8, 0xe3, 0x2d, 0x80, 0xb2, + 0x62, 0x89, 0xf1, 0x10, 0x45, 0x68, 0x57, 0xf7, 0xc2, 0x77, 0xaa, 0xd4, 0xbe, 0xfe, 0x41, 0x4f, + 0x7f, 0x82, 0x30, 0xbe, 0x32, 0x2b, 0x27, 0xbc, 0x4a, 0x2c, 0xbe, 0x89, 0xd0, 0x59, 0x10, 0x24, + 0x78, 0x59, 0xde, 0xef, 0x60, 0x2a, 0xf1, 0x6d, 0x4f, 0x9b, 0x95, 0x5e, 0x20, 0x61, 0x5c, 0x71, + 0x1d, 0x09, 0x1e, 0xd1, 0x09, 0x99, 0xac, 0x31, 0x68, 0x20, 0x0b, 0x60, 0x9c, 0xa2, 0x3c, 0xf0, + 0x1a, 0xba, 0x91, 0x99, 0x6c, 0xd0, 0x2b, 0xc1, 0xa7, 0x98, 0x88, 0x2b, 0x98, 0x30, 0x1c, 0xb7, + 0x3d, 0xb8, 0x36, 0xba, 0xeb, 0x59, 0x03, 0xb4, 0xe5, 0xab, 0x89, 0x97, 0x2b, 0x09, 0x19, 0x64, + 0x82, 0x9a, 0xc2, 0x01, 0x11, 0xe5, 0xbd, 0xa3, 0xe1, 0xf3, 0xf3, 0xef, 0x8c, 0xea, 0xa7, 0x22, + 0xd1, 0xdc, 0x3c, 0xe0, 0xba, 0x9d, 0x6c, 0xcc, 0x9b, 0x27, 0x10, 0x24, 0xbc, 0x5d, 0xaf, 0x24, + 0xac, 0x2b, 0xf8, 0x91, 0x35, 0xc7, 0xff, 0x2f, 0xb9, 0xf8, 0x2e, 0xe3, 0xc9, 0x3f, 0xbd, 0x9c, + 0x61, 0x69, 0xdd, 0x31, 0xd5, 0xeb, 0x88, 0x12, 0x30, 0x8e, 0x10, 0x14, 0x27, 0x78, 0x81, 0x13, + 0x1a, 0x6e, 0x50, 0x99, 0xe7, 0x12, 0xe1, 0xd2, 0x62, 0x57, 0x7d, 0xd0, 0x65, 0x9d, 0x41, 0x1e, + 0xa4, 0x8f, 0x46, 0x90, 0xad, 0x1b, 0xaf, 0xac, 0x48, 0x91, 0x96, 0x14, 0xa4, 0xb7, 0xa7, 0x0a, + 0x14, 0xeb, 0x3a, 0x9a, 0xf7, 0x9d, 0x25, 0x4d, 0x55, 0x71, 0xf8, 0xee, 0x52, 0x41, 0x4c, 0x63, + 0x52, 0xc3, 0x17, 0x26, 0xa5, 0x0b, 0xd7, 0x06, 0x2d, 0xb2, 0x91, 0x58, 0x34, 0x7b, 0x88, 0x0f, + 0x82, 0x93, 0x95, 0xec, 0xa2, 0xe9, 0xe2, 0x5b, 0x58, 0x21, 0x64, 0x0b, 0x35, 0x6b, 0xab, 0x4b, + 0x5a, 0xff, 0x1c, 0x75, 0x11, 0xcd, 0xef, 0x24, 0x5b, 0xf8, 0x93, 0x55, 0x7f, 0x30, 0xcc, 0xbf, + 0x1e, 0x82, 0xe0, 0x8f, 0xf7, 0x00, 0x1a, 0xa7, 0x76, 0xb5, 0x82, 0xbe, 0xaf, 0xc3, 0x02, 0x01, + 0x60, 0x81, 0xc6, 0x50, 0x9d, 0x45, 0xd9, 0xb9, 0x71, 0xe9, 0x36, 0x2c, 0x97, 0xef, 0x89, 0x84, + 0x78, 0x85, 0x57, 0xda, 0xdb, 0xf0, 0x89, 0x1f, 0x2d, 0x3a, 0xb7, 0xb9, 0xfb, 0x67, 0xe1, 0x37, + 0x19, 0xce, 0xf1, 0x0c, 0x42, 0xfd, 0x22, 0xba, 0xe3, 0x0f, 0x4a, 0x21, 0xe1, 0x23, 0x89, 0xa1, + 0x06, 0x23, 0x28, 0x44, 0x6f, 0x14, 0xc7, 0x83, 0x6d, 0xe7, 0xcd, 0x7c, 0xad, 0xf8, 0xcb, 0x4a, + 0xfb, 0xb4, 0xdd, 0x21, 0xcd, 0x51, 0xdb, 0x78, 0xff, 0x49, 0x72, 0xe8, 0x2d, 0x72, 0xdd, 0x06, + 0x39, 0x78, 0xda, 0x55, 0x57, 0x89, 0x2d, 0xcd, 0x17, 0xf7, 0xe7, 0xd7, 0x21, 0x8b, 0x82, 0xbb, + 0x1e, 0x22, 0x0b, 0x88, 0xa9, 0xaa, 0x6b, 0x55, 0x6f, 0x82, 0x60, 0x9b, 0xbb, 0xbe, 0x68, 0xdb, + 0xe8, 0x2a, 0x96, 0x0a, 0x61, 0x81, 0x00, 0x88, 0x39, 0x7b, 0xf7, 0x10, 0x24, 0x29, 0x9a, 0xab, + 0x6e, 0xe9, 0x23, 0x9e, 0x0c, 0xbb, 0x47, 0x16, 0xbb, 0xe1, 0x32, 0x2a, 0xae, 0x43, 0x15, 0xf1, + 0x11, 0x86, 0x4d, 0xd8, 0xf3, 0xab, 0x4b, 0x6d, 0xd5, 0x43, 0x6a, 0xd2, 0xc7, 0xe2, 0xf8, 0x87, + 0x03, 0x4d, 0xca, 0xc4, 0x0c, 0x0f, 0xbf, 0xc1, 0x30, 0xbe, 0x5c, 0x1f, 0x37, 0xb7, 0x2f, 0x7f, + 0xab, 0xf0, 0x8c, 0x87, 0xdd, 0xf8, 0x91, 0x71, 0xa4, 0xcf, 0xde, 0xf5, 0xc9, 0x86, 0x9a, 0xfb, + 0x38, 0x81, 0x02, 0x86, 0x17, 0x49, 0x6c, 0x7d, 0xef, 0x88, 0x84, 0x08, 0xec, 0xaa, 0xd5, 0xd2, + 0x5a, 0xe1, 0xb6, 0x15, 0x01, 0x26, 0xe6, 0xb1, 0x9f, 0xff, 0x83, 0x3f, 0x7f, 0xcc, 0x3f, 0xac, + 0x13, 0x74, 0x2a, 0xaa, 0x18, 0x10, 0x0a, 0x3c, 0x79, 0x6a, 0x5e, 0x1c, 0x8c, 0xc9, 0xc4, 0x09, + 0x13, 0x72, 0xa4, 0x42, 0xc7, 0x21, 0x34, 0xb8, 0xdf, 0xde, 0x93, 0xbf, 0x8f, 0x22, 0x5b, 0x8c, + 0xa9, 0xef, 0xf9, 0x37, 0x89, 0x10, 0x3c, 0xc2, 0x4e, 0x64, 0xf9, 0xbb, 0x93, 0x9a, 0x39, 0x3e, + 0x92, 0x7d, 0x38, 0x80, 0x52, 0x52, 0x87, 0xa1, 0x28, 0x35, 0x0f, 0xff, 0x6e, 0xb1, 0xff, 0x8f, + 0xf8, 0x8f, 0xee, 0x22, 0x20, 0x5d, 0x9a, 0xae, 0x6a, 0x2f, 0x90, 0x97, 0x5e, 0x22, 0x10, 0x3b, + 0xdb, 0xba, 0x68, 0x03, 0x15, 0xbb, 0xbf, 0x8e, 0x2b, 0xed, 0xbb, 0xbe, 0xdb, 0xfc, 0x4d, 0xdd, + 0xce, 0xc3, 0xef, 0xf2, 0x91, 0xde, 0xea, 0x20, 0x40, 0x48, 0x52, 0x9a, 0x83, 0x6b, 0xd3, 0xa7, + 0xc4, 0x82, 0x33, 0x2a, 0xfd, 0xc4, 0x89, 0x28, 0x96, 0xa2, 0x74, 0x35, 0x01, 0x2c, 0x21, 0x37, + 0x55, 0xc2, 0x10, 0x59, 0x3d, 0xb5, 0xb9, 0x68, 0x6a, 0x3b, 0x1a, 0x59, 0x98, 0x3f, 0x8f, 0x35, + 0x98, 0x4c, 0xfb, 0xb8, 0xaf, 0xf1, 0x35, 0x89, 0x05, 0x47, 0xbc, 0x56, 0xae, 0xa9, 0x6d, 0x21, + 0xcd, 0x90, 0xb9, 0x57, 0x71, 0x01, 0x10, 0x88, 0x85, 0x15, 0xb5, 0x25, 0x2e, 0x99, 0x78, 0xf0, + 0x81, 0x45, 0x6f, 0x08, 0xe3, 0xf0, 0x81, 0xd3, 0x92, 0x28, 0x75, 0xb2, 0x3e, 0xf4, 0x98, 0x1d, + 0x1f, 0xa5, 0xba, 0x7c, 0xcb, 0xe1, 0xb1, 0x63, 0x33, 0x2f, 0x5e, 0x11, 0xac, 0x4b, 0x13, 0x77, + 0xf9, 0xae, 0xff, 0x94, 0xae, 0xff, 0x88, 0xec, 0x45, 0x62, 0xe9, 0x56, 0x20, 0xc4, 0x77, 0x7e, + 0x18, 0x08, 0x7c, 0xa3, 0xb5, 0x5f, 0x2c, 0x98, 0xbf, 0x82, 0x31, 0x28, 0xe2, 0x78, 0x8f, 0x28, + 0x22, 0x86, 0x26, 0xdd, 0x4d, 0x9e, 0x09, 0xef, 0x4f, 0xbb, 0xc7, 0xe2, 0x63, 0xf2, 0xe4, 0xd4, + 0xb3, 0xe6, 0x6c, 0x9b, 0xc9, 0x9c, 0x4a, 0x27, 0x57, 0x29, 0x55, 0x7f, 0x08, 0x9b, 0x10, 0x71, + 0xe3, 0xc7, 0x35, 0x4e, 0xe8, 0xa5, 0x4b, 0x89, 0x85, 0x08, 0x78, 0xd1, 0x2c, 0xc6, 0xd5, 0x18, + 0xba, 0x0a, 0x7b, 0x76, 0xed, 0x93, 0x67, 0xc7, 0xe2, 0x62, 0x0b, 0x53, 0x30, 0xde, 0x78, 0xb3, + 0xde, 0xa2, 0x25, 0x1a, 0x8e, 0x5e, 0xfe, 0x6e, 0xef, 0xe4, 0xbb, 0xbb, 0xe2, 0x21, 0x0d, 0x6e, + 0xee, 0x93, 0xb9, 0x71, 0xef, 0xc1, 0x25, 0xde, 0xef, 0xc4, 0x4b, 0x7b, 0xd0, 0xa4, 0x24, 0x14, + 0xc7, 0xcb, 0x08, 0x78, 0x8a, 0x14, 0xfc, 0x45, 0x0a, 0x7e, 0x22, 0x6e, 0x7f, 0xf0, 0xe0, 0x9d, + 0x35, 0x53, 0x6a, 0x74, 0xfc, 0x3f, 0x0c, 0x6b, 0x8e, 0xa5, 0x93, 0x92, 0xfd, 0xed, 0x57, 0x10, + 0x24, 0x7d, 0x75, 0xe6, 0xc9, 0x27, 0x11, 0xdf, 0x10, 0x4d, 0x46, 0x6e, 0x3e, 0x3f, 0x08, 0x78, + 0x93, 0x66, 0xa2, 0xce, 0x26, 0x10, 0xb8, 0xa6, 0xeb, 0xd5, 0x5b, 0x4c, 0x47, 0xdf, 0x88, 0xee, + 0xf4, 0xef, 0x88, 0x89, 0x8b, 0xd6, 0xaa, 0xab, 0x89, 0x89, 0x8d, 0xa6, 0x7f, 0x7b, 0x7e, 0x11, + 0x16, 0xfb, 0xe5, 0x85, 0xcb, 0xdf, 0xc4, 0xfc, 0x49, 0x09, 0x77, 0x7c, 0x44, 0x28, 0x5d, 0xa7, + 0x64, 0xed, 0x6e, 0xee, 0xec, 0x62, 0xb7, 0x7f, 0x8a, 0xbb, 0xbb, 0xcb, 0x4f, 0xdd, 0xf7, 0x2c, + 0x48, 0x91, 0x59, 0xcc, 0x5e, 0xef, 0x7e, 0x24, 0x83, 0x1d, 0xe7, 0xcc, 0x44, 0x15, 0x5a, 0xd7, + 0x22, 0x4d, 0xf3, 0x65, 0x45, 0xa3, 0xeb, 0xb9, 0x0e, 0xf4, 0x3f, 0xbe, 0x0b, 0x04, 0x44, 0x2c, + 0x2c, 0x46, 0xfd, 0xc5, 0x62, 0xb8, 0x2d, 0xef, 0x8b, 0xd5, 0x32, 0xee, 0xd3, 0x7c, 0x48, 0x8a, + 0x32, 0xe6, 0xf5, 0xf8, 0xcb, 0x55, 0x55, 0xd6, 0xbb, 0x55, 0x54, 0xfc, 0x49, 0x1e, 0x30, 0x8b, + 0xb7, 0xf7, 0xf0, 0x89, 0xe4, 0xeb, 0x91, 0x47, 0xad, 0x7c, 0x16, 0x55, 0x6a, 0xba, 0xe9, 0x88, + 0x16, 0x1b, 0xe1, 0x43, 0x1b, 0xfa, 0x74, 0xef, 0xaa, 0x6e, 0xef, 0x67, 0x89, 0x05, 0xc5, 0x7d, + 0x6f, 0x76, 0x7d, 0xee, 0xc7, 0xf3, 0x1d, 0x56, 0xb8, 0x98, 0x4a, 0xee, 0xd3, 0x4a, 0xd7, 0xc4, + 0x84, 0xa6, 0x20, 0xed, 0x2d, 0xae, 0x10, 0x10, 0x2e, 0xe5, 0x66, 0xdd, 0xdd, 0xf0, 0x80, 0x83, + 0x5c, 0x6d, 0x06, 0xfc, 0x9b, 0xbb, 0xfa, 0x2a, 0x74, 0xe2, 0x7c, 0x44, 0x51, 0x37, 0x77, 0xdf, + 0xc4, 0xd1, 0x9c, 0x83, 0x47, 0xa4, 0xfe, 0x0b, 0xa7, 0xce, 0xe5, 0x10, 0x1d, 0xf8, 0x88, 0x27, + 0x11, 0x1c, 0x00, 0x06, 0xfd, 0xef, 0xfe, 0x22, 0x0b, 0x89, 0x9c, 0x00, 0x03, 0x7a, 0xbe, 0x5f, + 0x04, 0x47, 0xe5, 0x62, 0x0f, 0xa9, 0xe8, 0x6e, 0x10, 0x8a, 0xa6, 0xee, 0xdc, 0x49, 0x50, 0x27, + 0xc9, 0x82, 0x98, 0xc4, 0x09, 0x04, 0x3b, 0x35, 0x92, 0xc3, 0x44, 0x81, 0x36, 0x7b, 0xcf, 0x92, + 0x95, 0xa7, 0xf9, 0xfe, 0xdd, 0xee, 0x71, 0x12, 0x6b, 0x5e, 0x24, 0x20, 0x45, 0x4b, 0xd5, 0x65, + 0xa3, 0xb4, 0x83, 0xc2, 0x23, 0xed, 0x52, 0xd5, 0x55, 0xb5, 0xf1, 0x21, 0x00, 0x4c, 0x5a, 0xae, + 0xd9, 0x7d, 0x6f, 0xc4, 0x09, 0x1d, 0xe6, 0xe2, 0xb2, 0xda, 0x96, 0xc2, 0xc7, 0x4d, 0xb2, 0x6e, + 0x22, 0xe7, 0xdd, 0x4b, 0x87, 0xc4, 0x7e, 0x14, 0x39, 0xc3, 0x01, 0x7c, 0xff, 0xd2, 0x7b, 0xbb, + 0xbd, 0x7c, 0x10, 0x94, 0xdf, 0xa5, 0x5e, 0x88, 0xdc, 0x22, 0x24, 0x4d, 0x46, 0x53, 0x04, 0xf9, + 0x03, 0x03, 0x31, 0x0f, 0x84, 0x04, 0x93, 0x77, 0x7b, 0xbf, 0x12, 0xfb, 0xbf, 0x94, 0xb5, 0xae, + 0x20, 0x22, 0x0b, 0x8e, 0xab, 0xbd, 0xdd, 0x2f, 0x89, 0x17, 0xbb, 0xeb, 0x5e, 0x25, 0x0e, 0xef, + 0x12, 0x10, 0x3b, 0x25, 0x98, 0xa7, 0x1e, 0x30, 0xfa, 0x45, 0x9e, 0x26, 0x08, 0xb7, 0xb3, 0x7e, + 0x22, 0x2c, 0xf4, 0x53, 0x6b, 0x97, 0x2e, 0xfc, 0x66, 0xd1, 0x69, 0xa8, 0xee, 0x34, 0x5b, 0xb9, + 0x71, 0xdf, 0xf1, 0x21, 0x42, 0x36, 0x1e, 0x5b, 0xab, 0xb3, 0x9a, 0x9a, 0x23, 0x82, 0x00, 0xf7, + 0xc1, 0x69, 0x35, 0x4b, 0x6d, 0x62, 0xf8, 0x7c, 0x8a, 0x4b, 0x24, 0x39, 0x55, 0x2c, 0xe4, 0x51, + 0x05, 0x2a, 0xcd, 0x8d, 0xb1, 0x2f, 0xf8, 0x21, 0xa2, 0x29, 0xdb, 0x1f, 0x43, 0x71, 0x11, 0xb3, + 0x74, 0xc5, 0xd3, 0xe3, 0x15, 0x67, 0xc5, 0x36, 0x0b, 0x6d, 0xda, 0x97, 0xd0, 0x96, 0x70, 0x2d, + 0x81, 0x2c, 0xcb, 0x08, 0xfe, 0x9f, 0x88, 0x12, 0xf8, 0xcb, 0x8f, 0x89, 0xb1, 0x32, 0xd3, 0xc4, + 0xc8, 0x67, 0xbf, 0x12, 0x24, 0x23, 0x59, 0x51, 0xee, 0xd5, 0x6e, 0xfe, 0x20, 0x30, 0xe5, 0xf8, + 0xdf, 0x84, 0x5c, 0x56, 0xdf, 0xe0, 0x8a, 0x3a, 0xd1, 0x16, 0x4e, 0x8e, 0xf1, 0x33, 0x72, 0xfe, + 0x23, 0xc4, 0x09, 0x47, 0x77, 0x84, 0x5d, 0xdd, 0xdf, 0x10, 0x25, 0x5f, 0x88, 0x90, 0x8e, 0xee, + 0xfe, 0x24, 0xa7, 0x20, 0xb4, 0x4d, 0xac, 0x6e, 0xf7, 0xe2, 0x49, 0x5a, 0xaf, 0x08, 0x08, 0x2a, + 0xb1, 0x2c, 0x5e, 0xbc, 0x40, 0x44, 0x16, 0x95, 0xdd, 0xdf, 0x2e, 0x5f, 0xe2, 0x0c, 0xfb, 0xc5, + 0xeb, 0x89, 0x11, 0xf1, 0xe4, 0xd6, 0xb8, 0xcd, 0x1f, 0x77, 0x77, 0xe2, 0x44, 0x78, 0xe2, 0xd5, + 0x77, 0x2c, 0x3c, 0x24, 0x77, 0xbb, 0xbb, 0xbb, 0xf8, 0x28, 0x8d, 0xb2, 0xbb, 0x2a, 0x41, 0x6a, + 0xe2, 0x2d, 0x77, 0xc5, 0xf2, 0xda, 0x31, 0x5b, 0xbf, 0x89, 0x31, 0x2a, 0x5a, 0x57, 0xc4, 0x90, + 0x43, 0xab, 0xf8, 0x90, 0x53, 0x1e, 0x1a, 0x13, 0x21, 0x6a, 0x0a, 0xeb, 0x77, 0x47, 0x8d, 0x42, + 0xf8, 0x74, 0xeb, 0x27, 0xed, 0xab, 0x73, 0x93, 0x4d, 0x58, 0xe3, 0x31, 0x7f, 0x0d, 0x70, 0x52, + 0x60, 0x7d, 0xdf, 0x53, 0x45, 0xfc, 0x7d, 0xed, 0xbd, 0xfc, 0x40, 0xe3, 0xd0, 0x1f, 0x23, 0xbf, + 0x10, 0x24, 0xa5, 0x54, 0xbf, 0x04, 0x9e, 0x5c, 0x47, 0x6b, 0x82, 0xc2, 0xb3, 0xb4, 0xf7, 0xa7, + 0x1d, 0xb8, 0xf5, 0x25, 0xf1, 0x06, 0x14, 0xb2, 0x6f, 0xc8, 0x55, 0x6f, 0xe2, 0x15, 0xfe, 0x0a, + 0xca, 0x5e, 0x1f, 0x68, 0x3e, 0x6e, 0x7e, 0xdf, 0x75, 0x91, 0x7f, 0x08, 0xec, 0x9f, 0x15, 0x9f, + 0xef, 0x4f, 0xe0, 0xaa, 0x4f, 0x5e, 0xee, 0xef, 0x7a, 0xf1, 0x01, 0x3d, 0xde, 0x7a, 0x4b, 0xdf, + 0x12, 0x24, 0xdc, 0x65, 0x31, 0xe2, 0x21, 0x0c, 0x75, 0x09, 0xcb, 0x6e, 0xf4, 0xef, 0x78, 0x6a, + 0x50, 0x02, 0x23, 0x57, 0xd3, 0x3e, 0xde, 0xfa, 0xd7, 0x57, 0x67, 0x54, 0xdf, 0xc2, 0x25, 0xea, + 0x64, 0x98, 0x98, 0xb9, 0xfd, 0xe4, 0xf5, 0xf0, 0xc0, 0x8b, 0xbd, 0xdd, 0xdf, 0x89, 0x12, 0x8d, + 0x17, 0x88, 0x75, 0xaf, 0x89, 0x08, 0x15, 0xef, 0x77, 0x15, 0xdd, 0xdd, 0xfc, 0x97, 0x74, 0xd9, + 0xf8, 0x4e, 0xe3, 0x2c, 0x9d, 0xe4, 0x13, 0xe7, 0xf2, 0xca, 0xc5, 0xeb, 0xbd, 0xef, 0x88, 0x92, + 0xe5, 0xa7, 0xe1, 0xa1, 0x4e, 0xac, 0x1b, 0x6b, 0x1a, 0xec, 0x7f, 0xe3, 0x4b, 0xc7, 0x88, 0xb0, + 0x1d, 0x4c, 0x83, 0x3b, 0xe2, 0x13, 0xe8, 0xeb, 0x79, 0xfd, 0xe0, 0x42, 0xc8, 0x05, 0xb9, 0x67, + 0xff, 0x39, 0xd4, 0xf0, 0x8e, 0xd8, 0xfc, 0x31, 0x10, 0x20, 0x2e, 0x2a, 0x9d, 0x36, 0xc1, 0x61, + 0x13, 0x44, 0x31, 0x3c, 0x04, 0xd5, 0x2f, 0x15, 0xfe, 0x20, 0x48, 0x92, 0xe7, 0x50, 0x9e, 0xc3, + 0x1f, 0x44, 0xbe, 0x13, 0x29, 0x7c, 0x56, 0xfb, 0x37, 0xc4, 0x09, 0x27, 0x74, 0xb8, 0x90, 0x95, + 0xef, 0x93, 0xfe, 0x2a, 0xf7, 0xbd, 0xfe, 0xc5, 0x3e, 0xfe, 0x09, 0xc5, 0xd4, 0xfb, 0xb6, 0xbd, + 0x7c, 0x12, 0xcd, 0x4a, 0xc4, 0x58, 0xad, 0xfe, 0x13, 0xbd, 0xa4, 0x95, 0x6b, 0x84, 0x44, 0x8c, + 0xa7, 0x58, 0x3f, 0x62, 0xd6, 0xf6, 0x98, 0x3b, 0x6b, 0xe3, 0xa9, 0x31, 0xde, 0xef, 0x3b, 0x3e, + 0x87, 0xc4, 0x82, 0x89, 0xba, 0xdf, 0x3e, 0x37, 0xdc, 0x4c, 0x9b, 0x77, 0x7c, 0x20, 0x0a, 0x5c, + 0xff, 0xfc, 0x20, 0x5b, 0xb9, 0x72, 0xf8, 0x41, 0xd1, 0x6f, 0x51, 0x3e, 0x26, 0x52, 0x3b, 0xfc, + 0x48, 0x44, 0xb9, 0xf6, 0x4d, 0xee, 0xe8, 0x9f, 0xc2, 0x17, 0x77, 0xb8, 0xaf, 0x77, 0x63, 0x7e, + 0x20, 0x29, 0x77, 0x77, 0xbc, 0x75, 0x5d, 0xce, 0x92, 0xdf, 0x77, 0x7f, 0x12, 0x13, 0xf2, 0xef, + 0x7f, 0x8b, 0x3e, 0x5c, 0x75, 0xb1, 0xb1, 0xac, 0x4a, 0xbf, 0x88, 0x44, 0xef, 0x12, 0x08, 0xaa, + 0xbf, 0x78, 0x90, 0xd0, 0xa9, 0x72, 0x5f, 0x05, 0xd6, 0x39, 0xa7, 0xf8, 0x43, 0x4a, 0xd8, 0xda, + 0xd6, 0xf8, 0x73, 0x6b, 0x2f, 0xca, 0x56, 0x1a, 0xbc, 0x2d, 0xc1, 0x25, 0x76, 0x9b, 0x86, 0x02, + 0x23, 0x8c, 0x0f, 0x7c, 0x2e, 0x0b, 0x10, 0x7b, 0xe3, 0xa7, 0xcf, 0xc3, 0xfb, 0xe2, 0x5e, 0x9f, + 0x12, 0x24, 0x4b, 0x12, 0x14, 0xcc, 0x63, 0x09, 0xb6, 0xa2, 0x61, 0x03, 0xde, 0xec, 0x62, 0xb1, + 0x5b, 0xd2, 0x7f, 0xa2, 0x23, 0xbe, 0x27, 0x89, 0x12, 0x89, 0x5c, 0x4c, 0x4d, 0x36, 0xf5, 0x5a, + 0x1f, 0x84, 0x8a, 0x60, 0x5d, 0xfa, 0x6f, 0x0c, 0xa3, 0x80, 0x0e, 0xd2, 0xf3, 0xb6, 0x9b, 0x9f, + 0x69, 0xbd, 0xbf, 0x12, 0xf5, 0xb6, 0x98, 0xc9, 0x83, 0x2c, 0xe2, 0x23, 0xfc, 0xaa, 0x0f, 0x36, + 0x66, 0x37, 0xc3, 0xc7, 0xf5, 0x58, 0xcd, 0x31, 0x10, 0xa1, 0xaf, 0xbd, 0x3a, 0x76, 0x9f, 0x0c, + 0xc4, 0x9e, 0xf2, 0x66, 0xf8, 0x6b, 0x00, 0x43, 0x77, 0x71, 0xfb, 0x2b, 0x6d, 0x92, 0xd0, 0x1f, + 0x7f, 0x4d, 0xbf, 0x3f, 0x7e, 0x10, 0x10, 0xf7, 0x77, 0xe1, 0x80, 0x81, 0x47, 0xfa, 0xed, 0xdf, + 0x5d, 0x57, 0x08, 0x88, 0x04, 0xd3, 0xb1, 0x68, 0xd8, 0xe6, 0xf6, 0xfb, 0xc4, 0xa2, 0x3f, 0x89, + 0x75, 0xaf, 0x84, 0x4c, 0x61, 0x7d, 0x7d, 0x0b, 0x7f, 0x88, 0x26, 0x5c, 0x57, 0xbf, 0xc1, 0x4d, + 0xcb, 0x8f, 0x65, 0xb1, 0x5d, 0xdf, 0x77, 0xf1, 0x20, 0xa8, 0xb6, 0xef, 0x72, 0xb0, 0xed, 0x31, + 0x3e, 0xef, 0x7e, 0x20, 0x40, 0x27, 0x8a, 0xde, 0xee, 0xef, 0xae, 0x22, 0x10, 0xdb, 0xbc, 0x56, + 0x7e, 0xf6, 0xe9, 0x6b, 0x8a, 0xf3, 0x41, 0x75, 0xf8, 0x4c, 0xa9, 0xb7, 0xcb, 0xdb, 0xf8, 0x9f, + 0xa1, 0x51, 0x78, 0x91, 0xa4, 0x51, 0x0f, 0x56, 0x33, 0x68, 0x2d, 0x56, 0x3a, 0xba, 0x4e, 0xe7, + 0x04, 0x61, 0x21, 0xd1, 0x87, 0xff, 0x82, 0xb3, 0x8f, 0x95, 0x3f, 0x43, 0x48, 0x7c, 0xe0, 0xaf, + 0x90, 0x36, 0xa0, 0xd8, 0xe0, 0x85, 0xa0, 0x80, 0x22, 0x30, 0x61, 0xf4, 0x3c, 0x74, 0x36, 0xe6, + 0x01, 0x98, 0x3a, 0x3d, 0x33, 0xdf, 0xbf, 0x66, 0x0a, 0xe6, 0xc1, 0xbe, 0x57, 0xfc, 0x13, 0x17, + 0x61, 0x9f, 0x1e, 0xc5, 0xf7, 0x95, 0x44, 0xcc, 0x25, 0xb9, 0xff, 0xc2, 0x57, 0xbd, 0xa7, 0x27, + 0xb7, 0xd5, 0xfc, 0x48, 0x22, 0x35, 0xee, 0xfc, 0x44, 0x11, 0x95, 0x53, 0x37, 0x67, 0xef, 0x8f, + 0x38, 0xc2, 0x06, 0xd1, 0xbe, 0xfb, 0x6f, 0x74, 0xfe, 0x09, 0x08, 0x5c, 0x32, 0x97, 0xfb, 0xc4, + 0x04, 0x2e, 0xee, 0xfb, 0xcb, 0xdd, 0xef, 0xe3, 0x37, 0xbb, 0xdb, 0xbc, 0x57, 0xbe, 0xf8, 0x91, + 0x21, 0x2b, 0xbe, 0x87, 0x76, 0x7e, 0x6b, 0x55, 0xf0, 0x88, 0x22, 0x23, 0xbb, 0xbb, 0xf1, 0x30, + 0x5c, 0x5a, 0xb5, 0xdd, 0xff, 0xe2, 0x45, 0x11, 0xee, 0xed, 0xd6, 0xb1, 0x22, 0x8f, 0x4a, 0xd3, + 0xbb, 0xf8, 0x90, 0x4d, 0x2b, 0x1a, 0xdd, 0xef, 0x7f, 0xba, 0x74, 0xd7, 0xcd, 0x77, 0x77, 0xc4, + 0x89, 0x1f, 0xad, 0x95, 0xed, 0x39, 0x69, 0x7c, 0x46, 0xb1, 0x3c, 0x4c, 0x71, 0x56, 0xaa, 0x8e, + 0xbd, 0x49, 0xfd, 0x7b, 0x88, 0x82, 0x2a, 0x40, 0xd6, 0xe5, 0x73, 0x5f, 0xe0, 0xa4, 0x64, 0xaf, + 0xd5, 0x35, 0x5e, 0x2f, 0x12, 0x32, 0xff, 0x0f, 0x74, 0x27, 0x7a, 0x6e, 0x6d, 0x3d, 0x83, 0xed, + 0xfc, 0x13, 0x1f, 0x44, 0x46, 0x71, 0xd4, 0x2d, 0xe1, 0x48, 0x62, 0x14, 0x14, 0x2d, 0xb4, 0x5e, + 0xee, 0xa4, 0xec, 0x6a, 0x03, 0x1b, 0x93, 0xcd, 0xa7, 0x8f, 0x40, 0xeb, 0x52, 0x88, 0xef, 0x8a, + 0x7a, 0x5b, 0xe0, 0x94, 0xa1, 0xfe, 0xa3, 0xc0, 0x6e, 0x52, 0x70, 0x15, 0xcb, 0x67, 0x62, 0x5f, + 0x13, 0x15, 0xee, 0xe9, 0x3b, 0xf1, 0x24, 0x3a, 0x08, 0xec, 0x5a, 0xf2, 0x13, 0x77, 0xf0, 0x4c, + 0x7b, 0x42, 0xb7, 0xb6, 0xe2, 0xbd, 0x7c, 0x4c, 0xbd, 0xdc, 0xbd, 0xec, 0xbc, 0xb7, 0xe0, 0xa0, + 0x95, 0x55, 0xd5, 0x5c, 0xe2, 0x7e, 0x23, 0xc4, 0xf8, 0x9f, 0x84, 0xae, 0xcb, 0x17, 0xaf, 0x84, + 0x47, 0xe5, 0xff, 0x3f, 0xb7, 0xb9, 0x22, 0x66, 0xde, 0x2b, 0xe2, 0x44, 0x6e, 0xef, 0xaa, 0x6b, + 0x10, 0x2c, 0xae, 0xe5, 0x00, 0x00, 0xf7, 0x77, 0xf2, 0xdd, 0xc5, 0x77, 0xd1, 0x5f, 0xe3, 0xe2, + 0x1e, 0xee, 0x7a, 0x1d, 0x8f, 0x67, 0x76, 0x3e, 0x22, 0x49, 0x30, 0x9f, 0xf1, 0x1d, 0x56, 0x4c, + 0xfc, 0x65, 0x0d, 0xb9, 0xba, 0x48, 0x1d, 0x4e, 0x82, 0x97, 0xe4, 0xcf, 0x94, 0x8b, 0xa7, 0x88, + 0x97, 0x8f, 0xe3, 0xf0, 0x4c, 0x5d, 0xb5, 0xd2, 0x4b, 0x9f, 0xc4, 0x89, 0xd2, 0x4d, 0xb5, 0x5f, + 0x10, 0x20, 0x13, 0x8e, 0x6a, 0x48, 0x14, 0x90, 0x43, 0xc8, 0xdf, 0x36, 0x3d, 0x47, 0xf9, 0x4f, + 0x4c, 0x2f, 0x6c, 0xe4, 0x61, 0x3e, 0x6b, 0x46, 0xe4, 0x60, 0x60, 0x25, 0x09, 0xd8, 0x80, 0x88, + 0x29, 0x34, 0x2a, 0x86, 0x02, 0x7c, 0x5e, 0x9b, 0xcf, 0x41, 0x35, 0x5e, 0xe3, 0x13, 0x29, 0x30, + 0x3e, 0x6b, 0xbe, 0xb1, 0x3e, 0x24, 0x85, 0xa3, 0x97, 0x7c, 0x49, 0x9f, 0x54, 0x9c, 0x7d, 0x02, + 0x73, 0xe6, 0x08, 0xd5, 0x45, 0xf1, 0x22, 0x04, 0x99, 0x56, 0xa2, 0xe2, 0xe2, 0xe2, 0xfe, 0x09, + 0x3a, 0xaa, 0x3b, 0xc4, 0xc1, 0x46, 0xab, 0x75, 0xaf, 0x71, 0x22, 0x05, 0xd5, 0xb5, 0x5a, 0xd7, + 0x12, 0x24, 0x79, 0x57, 0x55, 0xd6, 0xaa, 0xb8, 0x98, 0x28, 0x33, 0xbd, 0xdf, 0x7a, 0xf8, 0x9c, + 0x5d, 0xc9, 0x82, 0xbf, 0xc4, 0x89, 0x2d, 0xbb, 0xbf, 0x12, 0x30, 0xa5, 0xcb, 0xdc, 0xec, 0x31, + 0xd1, 0xde, 0xee, 0xfe, 0x24, 0x48, 0x83, 0x38, 0xaf, 0x71, 0x5c, 0x56, 0xb9, 0x84, 0xcf, 0x0b, + 0xe2, 0x60, 0x86, 0xe2, 0x5e, 0xf6, 0xff, 0x04, 0x37, 0x69, 0xdf, 0xbe, 0xe9, 0xb9, 0x98, 0xf8, + 0x95, 0x7a, 0xe6, 0x93, 0xff, 0x17, 0xad, 0x96, 0xab, 0xc2, 0x23, 0xfb, 0x32, 0xd1, 0x2e, 0x6a, + 0x2e, 0xd9, 0x98, 0xf1, 0x5a, 0xd6, 0xa6, 0x84, 0xf8, 0xea, 0x6d, 0xdd, 0xdb, 0x94, 0xda, 0x55, + 0xae, 0x84, 0x77, 0xc7, 0x9d, 0xdb, 0xd5, 0x75, 0xa9, 0xb3, 0x08, 0xc1, 0x19, 0x66, 0xcd, 0xde, + 0x27, 0xc4, 0x84, 0x07, 0x5a, 0x8d, 0x5d, 0x98, 0xcd, 0xd5, 0x71, 0xb2, 0x9c, 0x71, 0x10, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x1f, 0x0f, 0xb0, 0x2a, 0x8d, 0xd0, 0x97, 0x42, 0x9c, 0xa5, 0xb3, + 0x19, 0x4d, 0xaf, 0xc1, 0x41, 0x5a, 0x68, 0x9f, 0xe6, 0xc1, 0xde, 0x41, 0xaf, 0x0b, 0x9b, 0x37, + 0xb9, 0xe7, 0x67, 0x15, 0xa6, 0xa6, 0x8f, 0xf8, 0x23, 0x2e, 0x7d, 0x1e, 0x10, 0x3c, 0x3e, 0xae, + 0x41, 0x9f, 0x44, 0xef, 0xae, 0xbe, 0x09, 0x3a, 0xaa, 0x53, 0xe0, 0x84, 0xe4, 0xf5, 0xa6, 0x41, + 0x6e, 0x89, 0xdf, 0x52, 0xa7, 0xd6, 0xab, 0xae, 0x55, 0xd1, 0x1f, 0xe8, 0xaf, 0x2f, 0x44, 0x2a, + 0x42, 0x3d, 0x1e, 0x67, 0xce, 0x5a, 0xba, 0xba, 0xfb, 0xe8, 0xc7, 0x4f, 0xa9, 0x91, 0x13, 0xe6, + 0x97, 0x0b, 0x84, 0xc6, 0x67, 0xa1, 0x0f, 0x5c, 0x68, 0x99, 0x7f, 0x9b, 0x2d, 0x1f, 0x19, 0x78, + 0xe2, 0x90, 0xc5, 0xc4, 0x2f, 0xfd, 0x31, 0x6d, 0xf5, 0x1d, 0xd1, 0x9d, 0x5c, 0x86, 0x3a, 0xc3, + 0x4b, 0x88, 0x04, 0x03, 0xb3, 0x75, 0x9a, 0x81, 0x35, 0xaf, 0x90, 0xae, 0x06, 0xd0, 0x12, 0x28, + 0xb6, 0x4f, 0x10, 0x18, 0x8c, 0x52, 0x78, 0xd2, 0xff, 0x10, 0x0a, 0x23, 0x97, 0xc1, 0xef, 0x0c, + 0x46, 0x6d, 0xd7, 0x88, 0xc0, 0x03, 0x0f, 0xa6, 0x39, 0xfc, 0x70, 0xe0, 0x7d, 0xe4, 0xfc, 0x56, + 0x18, 0x7c, 0x13, 0x8f, 0xcd, 0x9c, 0xf9, 0x98, 0x7a, 0xbf, 0xd5, 0xeb, 0xa3, 0x39, 0x7c, 0x38, + 0x51, 0xfa, 0xbb, 0x8a, 0xdb, 0x0d, 0x71, 0x3b, 0x8d, 0xff, 0x87, 0x0f, 0x9c, 0xd1, 0xcb, 0xae, + 0x1e, 0x71, 0x68, 0x47, 0x34, 0xaf, 0xe9, 0xfe, 0x16, 0x26, 0x7f, 0xe5, 0xc5, 0xb9, 0xaa, 0x82, + 0xfa, 0xe0, 0x86, 0xca, 0x2d, 0x6e, 0x89, 0xeb, 0xcc, 0x8d, 0xd7, 0xa1, 0xae, 0x30, 0x2c, 0x95, + 0x89, 0xb7, 0xbb, 0x9f, 0x60, 0xf6, 0x15, 0xc8, 0x7e, 0x42, 0xe1, 0xb3, 0x6c, 0x29, 0xff, 0x24, + 0xda, 0x8e, 0xf5, 0x99, 0x78, 0xdf, 0x3a, 0xec, 0x18, 0xb5, 0x8a, 0x1a, 0xd6, 0xca, 0xd0, 0x72, + 0x38, 0xb6, 0xe9, 0x17, 0x6a, 0x88, 0xdb, 0xc0, 0xb9, 0x08, 0xac, 0xfb, 0x6a, 0x78, 0x62, 0x02, + 0x00, 0x98, 0x4d, 0x5d, 0x9a, 0xdb, 0xb6, 0x29, 0xfa, 0xe7, 0x7d, 0xd5, 0x35, 0x94, 0x89, 0x3c, + 0xfc, 0xe2, 0xca, 0x96, 0xeb, 0x31, 0xa7, 0x1a, 0xff, 0x3c, 0xe9, 0xc7, 0x25, 0xac, 0x97, 0xfe, + 0x09, 0x7b, 0xbe, 0xef, 0xe3, 0xeb, 0x87, 0xd7, 0xa2, 0x3a, 0x25, 0x7d, 0x62, 0x9b, 0xad, 0x47, + 0xf5, 0x8a, 0x2f, 0x8a, 0x0a, 0x13, 0xe9, 0x79, 0xa3, 0xc4, 0x85, 0x2e, 0xfe, 0x85, 0x5f, 0x56, + 0x10, 0x47, 0x57, 0xe4, 0x4f, 0x88, 0xa8, 0x5c, 0x90, 0xaa, 0xbb, 0x28, 0x55, 0x0b, 0x77, 0xf8, + 0x92, 0x69, 0x12, 0xdf, 0xb3, 0xf9, 0xb9, 0xf9, 0xfe, 0x5c, 0x42, 0xbf, 0x88, 0x27, 0x1a, 0x4c, + 0xab, 0x48, 0xc2, 0x22, 0x02, 0x9b, 0x51, 0x68, 0x4a, 0xae, 0xd6, 0xa4, 0x63, 0x7e, 0x20, 0x40, + 0x21, 0x9b, 0x07, 0x14, 0xee, 0x17, 0xbf, 0x88, 0x08, 0x70, 0xf7, 0xbf, 0x34, 0x33, 0x64, 0x15, + 0xe2, 0x01, 0x26, 0x2b, 0x4d, 0xcb, 0x71, 0x02, 0x06, 0x55, 0x91, 0x17, 0x92, 0xd6, 0x2e, 0x2a, + 0xd5, 0x6b, 0x12, 0xb3, 0x22, 0xad, 0x61, 0xb7, 0x30, 0xa0, 0x5f, 0x6d, 0xed, 0xb2, 0xf1, 0x0f, + 0x74, 0x09, 0x47, 0x97, 0x63, 0x29, 0xf1, 0xb5, 0xff, 0xbe, 0x60, 0x8a, 0xaf, 0x88, 0xa0, 0x83, + 0xd7, 0x04, 0xc3, 0xc6, 0xff, 0xcd, 0x6f, 0x7f, 0x9a, 0xe5, 0x63, 0xc4, 0xfc, 0x48, 0xf0, 0x83, + 0xad, 0x5f, 0x7b, 0x4a, 0xaa, 0xbc, 0x40, 0x23, 0x1a, 0xb7, 0xf4, 0x15, 0x44, 0x48, 0x64, 0xea, + 0xbe, 0x28, 0xc6, 0xec, 0xeb, 0xaa, 0x6d, 0x2e, 0x22, 0x10, 0x9c, 0xf6, 0xb0, 0x21, 0x62, 0xcb, + 0x6e, 0x2b, 0x6d, 0x6b, 0x71, 0x1f, 0x89, 0xd5, 0x45, 0xea, 0xa4, 0x63, 0xcc, 0x3e, 0xf7, 0x58, + 0x9e, 0x23, 0xf0, 0x42, 0x30, 0x5c, 0x3d, 0x08, 0x28, 0x9f, 0xe8, 0x2b, 0xe0, 0xa0, 0x5d, 0xce, + 0x4a, 0xeb, 0x5b, 0xbc, 0x49, 0x05, 0x29, 0x3d, 0x71, 0x31, 0xda, 0xd6, 0x98, 0x8f, 0xcd, 0x54, + 0xd4, 0x45, 0xc3, 0xc1, 0x20, 0x55, 0xee, 0xf5, 0x86, 0x14, 0x79, 0x8f, 0xff, 0xd3, 0x85, 0x9b, + 0x9d, 0xf4, 0x16, 0xef, 0x8e, 0x16, 0xa7, 0xe0, 0x4c, 0xd3, 0xd6, 0xb6, 0x4b, 0x82, 0x4e, 0x25, + 0x50, 0x1c, 0x14, 0xd3, 0xfc, 0x20, 0x2b, 0x53, 0x51, 0x65, 0x42, 0xb0, 0x82, 0x27, 0x02, 0x64, + 0x3f, 0xc2, 0x63, 0x51, 0x1a, 0x02, 0x70, 0xd6, 0xb0, 0x59, 0x88, 0xf1, 0x00, 0x9c, 0xdb, 0x1a, + 0xb1, 0xb7, 0x6f, 0xb8, 0x81, 0x02, 0x09, 0xbb, 0xb7, 0x3f, 0xe2, 0x04, 0x71, 0x22, 0x17, 0xaf, + 0x85, 0x2f, 0x2b, 0x27, 0x51, 0x77, 0x12, 0xe0, 0x75, 0x12, 0x15, 0x76, 0x1a, 0xa4, 0x24, 0x5b, + 0xf1, 0x31, 0xde, 0x5b, 0xb1, 0xb0, 0x71, 0x3c, 0x66, 0x7f, 0xb1, 0x27, 0x28, 0xb2, 0x4b, 0x2c, + 0x15, 0xf3, 0x0b, 0xe2, 0x7f, 0x84, 0x01, 0x08, 0xcb, 0xcf, 0xe2, 0xe2, 0x44, 0x08, 0x25, 0x1a, + 0xae, 0x4c, 0xf8, 0xcd, 0xdc, 0x65, 0x09, 0x82, 0x63, 0x78, 0x20, 0x0f, 0x5f, 0x2b, 0xde, 0xdf, + 0x85, 0x0b, 0x18, 0xf7, 0x26, 0x80, 0x01, 0x4c, 0x5a, 0xcb, 0x97, 0x73, 0xd3, 0xbc, 0x41, 0x35, + 0x36, 0x4e, 0x24, 0x40, 0xca, 0xab, 0x3a, 0x8b, 0xfb, 0xba, 0x5b, 0xe2, 0x44, 0x14, 0xdb, 0x9f, + 0xf8, 0x22, 0x2a, 0x63, 0x55, 0x20, 0xb7, 0xf8, 0x21, 0x1e, 0xb7, 0x08, 0x1c, 0x76, 0x25, 0xfb, + 0xc4, 0xc4, 0xf4, 0x27, 0x50, 0xe7, 0x46, 0x82, 0x7c, 0x20, 0x11, 0x08, 0x3e, 0x1f, 0x55, 0x3d, + 0x24, 0xed, 0x4c, 0x99, 0xac, 0x77, 0xf1, 0xfc, 0x44, 0x23, 0xb3, 0x9d, 0x4a, 0x91, 0x47, 0x5a, + 0x58, 0x98, 0xa1, 0x25, 0xb2, 0xb1, 0x72, 0x2a, 0xdc, 0xfb, 0x89, 0x10, 0x38, 0xd6, 0xce, 0xce, + 0xb3, 0x28, 0x26, 0x1d, 0x84, 0x3f, 0xe0, 0x86, 0xbb, 0x31, 0x7b, 0xe3, 0x8b, 0xb4, 0xa6, 0xcc, + 0xcc, 0xc4, 0xa2, 0x6f, 0x10, 0x24, 0xda, 0x6f, 0xe2, 0x48, 0x28, 0x9c, 0x69, 0x02, 0xaa, 0x41, + 0x88, 0x82, 0x30, 0xbb, 0xc7, 0x7d, 0x9e, 0xf1, 0x28, 0xa6, 0x6f, 0xa2, 0x74, 0x16, 0x44, 0x47, + 0x85, 0xa5, 0xf1, 0xa5, 0xa5, 0x34, 0xd3, 0x3e, 0x2d, 0x00, 0x02, 0xf0, 0xa1, 0x4d, 0xb0, 0xe2, + 0xce, 0xec, 0x47, 0x67, 0x52, 0x4f, 0xd6, 0xca, 0x46, 0x09, 0xe2, 0x09, 0xad, 0x9e, 0x5c, 0xc0, + 0xb7, 0x6a, 0x7b, 0xc3, 0x41, 0x5d, 0x40, 0xac, 0xa2, 0x40, 0xe5, 0x56, 0x2f, 0xc1, 0xce, 0x65, + 0x9f, 0x88, 0x8c, 0xa4, 0xb8, 0xb9, 0xdc, 0x5c, 0xfb, 0x1c, 0xc6, 0xc0, 0x6f, 0x91, 0x16, 0x31, + 0x23, 0xf3, 0xe7, 0xaa, 0x41, 0xc9, 0x6f, 0x05, 0x72, 0x6b, 0x7e, 0xf9, 0xf5, 0x57, 0xf1, 0x21, + 0x42, 0xb4, 0xe8, 0xfa, 0x9b, 0x30, 0xed, 0x5b, 0x59, 0x09, 0x46, 0x9a, 0xc8, 0xbe, 0x1a, 0x2d, + 0x7e, 0x26, 0x14, 0xd0, 0xc7, 0xb9, 0xad, 0x63, 0x77, 0x62, 0xea, 0x1f, 0xc3, 0xce, 0x33, 0x17, + 0x87, 0xac, 0x95, 0x0c, 0x8b, 0xd9, 0xcf, 0xf8, 0x81, 0x00, 0x9b, 0x97, 0xcd, 0x36, 0x2f, 0xda, + 0x7e, 0x26, 0x2a, 0x4c, 0x06, 0xa8, 0xc1, 0x39, 0x5e, 0x99, 0x5a, 0x25, 0xe2, 0x04, 0x09, 0xca, + 0xca, 0x8e, 0x53, 0x98, 0x2d, 0xe8, 0x59, 0x6f, 0x12, 0x0a, 0x87, 0x73, 0x30, 0xaf, 0x39, 0x85, + 0x14, 0x16, 0xf6, 0xa0, 0x4f, 0xe2, 0x47, 0x91, 0x50, 0x60, 0x3c, 0x1b, 0xba, 0x81, 0x1a, 0xd7, + 0x5a, 0xe1, 0x08, 0x13, 0x4e, 0xf4, 0x41, 0x8e, 0x86, 0x25, 0x7a, 0x07, 0xc7, 0x89, 0x19, 0x87, + 0x43, 0x60, 0xd9, 0x74, 0x7c, 0xca, 0xaf, 0x21, 0x33, 0x06, 0x02, 0x87, 0x66, 0x7d, 0x9e, 0x0e, + 0xbf, 0x0a, 0x13, 0x42, 0x42, 0x19, 0x79, 0x93, 0xc6, 0x81, 0x66, 0xd1, 0xb2, 0x3d, 0x62, 0x74, + 0x21, 0x6b, 0x9b, 0xd0, 0xa0, 0x5e, 0x7d, 0x7e, 0xf8, 0x92, 0x8f, 0xe8, 0x3f, 0xa6, 0xa0, 0x83, + 0xea, 0x27, 0xa3, 0x07, 0x78, 0xfc, 0x17, 0x1e, 0x2f, 0xe7, 0xf7, 0xe2, 0x64, 0xad, 0x78, 0x88, + 0x4c, 0x54, 0xff, 0x3f, 0xf1, 0xe8, 0x2a, 0x02, 0x1f, 0x7b, 0xf0, 0x56, 0xe3, 0x8e, 0xab, 0xb7, + 0x58, 0x25, 0x3a, 0x38, 0x65, 0xe3, 0x74, 0x47, 0xe2, 0x04, 0x02, 0x71, 0x46, 0x72, 0xa4, 0x14, + 0x55, 0xda, 0x41, 0xbf, 0x7c, 0x97, 0xd7, 0xc4, 0x11, 0xd9, 0x35, 0x27, 0x93, 0x04, 0x27, 0x87, + 0x7a, 0x8e, 0x2f, 0x04, 0x22, 0x38, 0xbb, 0xf7, 0x88, 0x42, 0x5f, 0xe2, 0x09, 0x57, 0x8e, 0x8d, + 0x6d, 0x94, 0x26, 0xff, 0x11, 0x36, 0x3e, 0xd3, 0xdc, 0xcd, 0x75, 0xf0, 0x4c, 0x7c, 0xbe, 0xee, + 0xee, 0xf5, 0xc1, 0x09, 0x9d, 0xde, 0xfc, 0x44, 0x28, 0x4c, 0x56, 0xef, 0x7b, 0x19, 0xe1, 0x33, + 0x3c, 0x56, 0xfd, 0x5d, 0x02, 0x74, 0xb0, 0x53, 0x08, 0x7e, 0xc3, 0x94, 0xd3, 0xf8, 0x48, 0x95, + 0xab, 0xb4, 0xff, 0x04, 0x86, 0x51, 0xf1, 0x9b, 0xbf, 0xc2, 0x92, 0xe3, 0x88, 0x60, 0x5a, 0x9e, + 0x17, 0xb2, 0x94, 0xe5, 0x20, 0x7d, 0x91, 0x96, 0xd4, 0xe4, 0xda, 0x7e, 0xf8, 0x26, 0x16, 0xdd, + 0x6a, 0xea, 0x3d, 0x63, 0x77, 0xf8, 0x89, 0x7b, 0xde, 0xef, 0xe2, 0x4c, 0x77, 0x77, 0x7f, 0x05, + 0x37, 0x77, 0x77, 0xde, 0xef, 0x7e, 0x10, 0xa2, 0x77, 0x89, 0x65, 0x97, 0xfe, 0x08, 0x86, 0x26, + 0x2b, 0xdf, 0x88, 0x82, 0xb2, 0x3c, 0x56, 0xee, 0x5e, 0xf9, 0xfd, 0xdf, 0xbe, 0x82, 0xbd, 0x43, + 0xd0, 0x9f, 0x53, 0xfe, 0x09, 0xa2, 0x28, 0x28, 0xff, 0x04, 0xdb, 0xdd, 0x5d, 0xef, 0x5c, 0x16, + 0x4f, 0x56, 0xad, 0x8c, 0xfb, 0xee, 0xb5, 0xef, 0x82, 0x21, 0x0f, 0x7f, 0x7c, 0x49, 0x43, 0xca, + 0x65, 0x09, 0xc8, 0x64, 0x75, 0x21, 0x8a, 0x16, 0xa6, 0x23, 0xf2, 0x8b, 0x12, 0x91, 0x60, 0xd0, + 0x3f, 0x94, 0x9a, 0x49, 0x78, 0x48, 0xe8, 0x1a, 0xbc, 0xe9, 0x58, 0xfc, 0x48, 0x92, 0xdd, 0xef, + 0xfc, 0x4f, 0x89, 0x12, 0x41, 0x09, 0x66, 0xfe, 0x0a, 0x7b, 0xb1, 0x99, 0x42, 0x53, 0x08, 0xe5, + 0xdb, 0xb9, 0xd3, 0xec, 0x43, 0x29, 0x98, 0x26, 0xe6, 0x17, 0x69, 0xa3, 0x66, 0x22, 0x53, 0x3e, + 0xae, 0x20, 0x48, 0x42, 0xf7, 0xd4, 0x94, 0x87, 0x7b, 0xf1, 0x1f, 0x14, 0x76, 0xa9, 0x4f, 0x2f, + 0xe2, 0x89, 0x27, 0x5e, 0xc7, 0x29, 0x07, 0xc5, 0x98, 0xed, 0x45, 0x8c, 0x0d, 0x26, 0x7a, 0x1d, + 0xfc, 0x13, 0x1e, 0x84, 0x86, 0x4a, 0xa8, 0xa7, 0x26, 0xfb, 0xd7, 0x12, 0x75, 0xda, 0xe5, 0xeb, + 0x10, 0x09, 0xae, 0xf7, 0xbd, 0xfb, 0x88, 0x08, 0x33, 0xbb, 0xdf, 0xc2, 0x17, 0x74, 0xdd, 0x2d, + 0x37, 0xbf, 0x89, 0xe2, 0x35, 0xc2, 0x61, 0x25, 0x54, 0x75, 0xaf, 0xc1, 0x77, 0x36, 0x75, 0x6b, + 0x5f, 0x38, 0x96, 0x3b, 0x62, 0xaf, 0xc1, 0x17, 0x36, 0xaa, 0x2f, 0x88, 0xf1, 0x10, 0x43, 0x55, + 0x5f, 0x7c, 0x5c, 0xbc, 0x56, 0xee, 0x25, 0xeb, 0x5f, 0xd5, 0xeb, 0x82, 0x73, 0x30, 0xe8, 0x8b, + 0x9c, 0x17, 0x6a, 0x85, 0xff, 0xf0, 0xec, 0x37, 0x20, 0xdb, 0xcd, 0x64, 0xbf, 0x68, 0x55, 0x93, + 0x4f, 0x77, 0x75, 0xfb, 0x47, 0xcf, 0xc1, 0x1e, 0xf7, 0xff, 0xc1, 0x15, 0x6b, 0xee, 0x26, 0x08, + 0x46, 0x8b, 0xcd, 0x7b, 0xea, 0xf5, 0xc1, 0x27, 0x77, 0xff, 0x08, 0x06, 0x04, 0x5e, 0xf7, 0x77, + 0x72, 0xf1, 0x58, 0xc8, 0x90, 0x49, 0xca, 0x0f, 0xbc, 0xa6, 0xbd, 0x8c, 0xb7, 0xe0, 0x86, 0x23, + 0xf0, 0x5a, 0x55, 0xa5, 0x26, 0xf1, 0x43, 0xc7, 0xaf, 0x7c, 0x11, 0x5d, 0xf7, 0xe2, 0x60, 0xa6, + 0xb2, 0x40, 0x61, 0x59, 0xee, 0xb2, 0x2f, 0x7f, 0x8b, 0x12, 0x9b, 0xa7, 0x6c, 0xd8, 0x66, 0x35, + 0xc7, 0x8a, 0x76, 0x54, 0xcc, 0xc1, 0x7a, 0xeb, 0x9c, 0xd1, 0xfc, 0x16, 0x1e, 0x8d, 0xb2, 0xe3, + 0xb8, 0xad, 0xe5, 0x63, 0x7f, 0x82, 0x72, 0x4b, 0x26, 0xdd, 0xd6, 0x77, 0xfa, 0xff, 0xe1, 0x11, + 0x6e, 0xf7, 0x77, 0xdd, 0x9d, 0xd7, 0x05, 0xc4, 0xe7, 0x93, 0xdd, 0xde, 0xa2, 0x3e, 0x20, 0x13, + 0x09, 0xdd, 0xdd, 0xef, 0xe7, 0xc9, 0x55, 0x5a, 0xc4, 0xdf, 0x41, 0x07, 0x7c, 0x5d, 0x74, 0xac, + 0x4a, 0xd7, 0x9b, 0xc7, 0x94, 0x3d, 0xc1, 0x59, 0x79, 0xeb, 0x49, 0x32, 0xe3, 0xef, 0xaf, 0xbd, + 0xee, 0xf8, 0x52, 0x4e, 0x27, 0x41, 0x72, 0x4d, 0x13, 0xe5, 0xc1, 0x72, 0xf5, 0x55, 0xd5, 0x5f, + 0xea, 0xfe, 0x20, 0x15, 0x55, 0x57, 0x7b, 0xda, 0x51, 0x07, 0x25, 0xf1, 0xc4, 0x17, 0x8b, 0xa6, + 0xee, 0x2b, 0x75, 0x7d, 0xfc, 0x17, 0x15, 0xa5, 0xb7, 0x7b, 0xf7, 0xd5, 0xfe, 0x53, 0x9f, 0x3b, + 0x89, 0x12, 0x2a, 0xe7, 0x50, 0xf6, 0xee, 0xef, 0xe3, 0x37, 0xbb, 0x95, 0x47, 0x6a, 0xe8, 0xee, + 0xf8, 0x88, 0x28, 0xa1, 0x19, 0x8d, 0xed, 0x2f, 0x7c, 0x85, 0x37, 0xea, 0x23, 0x5c, 0xc4, 0x7b, + 0xfc, 0x5d, 0xdd, 0xdd, 0xef, 0x5d, 0x88, 0xbb, 0xb8, 0x7a, 0x22, 0x2e, 0xdd, 0xba, 0xe2, 0x4a, + 0x9f, 0x3d, 0xee, 0xa6, 0xa7, 0xfe, 0x41, 0x28, 0x8d, 0x24, 0xbf, 0x05, 0x93, 0x74, 0x56, 0xd2, + 0x5d, 0x75, 0x7f, 0x84, 0x44, 0x2a, 0xd7, 0x55, 0x37, 0x93, 0xf4, 0x2f, 0xc4, 0x41, 0x31, 0x45, + 0x71, 0x0e, 0x6d, 0xb3, 0xfb, 0x7f, 0x11, 0xe2, 0x41, 0x64, 0x53, 0x3b, 0xc9, 0x9b, 0xc2, 0xca, + 0x44, 0xd6, 0xa9, 0x57, 0xab, 0xbc, 0x41, 0xae, 0xf7, 0xf0, 0x4c, 0x7b, 0x35, 0x8a, 0xe5, 0x31, + 0x7f, 0xfc, 0x25, 0x5d, 0x37, 0x7a, 0x3f, 0x08, 0x77, 0x77, 0x98, 0x87, 0x22, 0x8f, 0x89, 0x57, + 0xe1, 0x00, 0x80, 0x26, 0x24, 0xaa, 0x61, 0xba, 0x63, 0x43, 0xf5, 0xc7, 0x5d, 0x2a, 0x2d, 0xee, + 0x20, 0x22, 0x5f, 0x37, 0xe2, 0x4a, 0x5a, 0xd7, 0x11, 0x04, 0x02, 0x58, 0xea, 0xee, 0x91, 0xf3, + 0x8a, 0xd8, 0x0e, 0xff, 0x45, 0x44, 0x6f, 0xe8, 0xcf, 0xe2, 0x7e, 0x11, 0x20, 0xad, 0xee, 0xfb, + 0x95, 0x8b, 0xea, 0x22, 0x20, 0xee, 0xee, 0xee, 0x52, 0x0f, 0xe2, 0x27, 0xa1, 0xe8, 0xcd, 0xf4, + 0x6e, 0xc5, 0x5f, 0x29, 0x31, 0xd6, 0x57, 0xe6, 0x21, 0xa8, 0xcd, 0xaf, 0x90, 0x8d, 0xa0, 0x4c, + 0x02, 0xbe, 0x12, 0xed, 0xb5, 0x42, 0x3b, 0x69, 0x06, 0xf8, 0x2c, 0xab, 0x06, 0x16, 0x99, 0xbc, + 0xdd, 0x3d, 0xca, 0x52, 0x37, 0xf8, 0x29, 0x29, 0x60, 0xed, 0x62, 0xdd, 0xde, 0x19, 0x61, 0x19, + 0x22, 0x85, 0xfe, 0xa2, 0x04, 0x9a, 0x87, 0xaf, 0x10, 0x09, 0xcc, 0xec, 0x57, 0xbb, 0x4e, 0xcf, + 0x12, 0x0a, 0x0b, 0x3f, 0x48, 0xf7, 0x9b, 0xd9, 0x2b, 0xfc, 0x9b, 0xb5, 0xc4, 0x42, 0x73, 0xbf, + 0xcd, 0xf6, 0xb1, 0x12, 0x66, 0xe6, 0xcd, 0x44, 0x09, 0x29, 0xdb, 0x5a, 0xfa, 0xa3, 0xbf, 0x04, + 0x7b, 0x07, 0x2e, 0xd7, 0x11, 0x44, 0xfb, 0x84, 0x61, 0x32, 0xd5, 0xd7, 0x55, 0xf1, 0x1d, 0xb2, + 0x75, 0x40, 0xf5, 0x51, 0x30, 0x42, 0x7b, 0xdd, 0x3a, 0xc4, 0xc1, 0x41, 0x1c, 0x56, 0xef, 0x5a, + 0x6f, 0xc4, 0x09, 0x04, 0x23, 0x37, 0x7f, 0xfc, 0x78, 0x99, 0x98, 0xdd, 0xef, 0x7b, 0xf8, 0x26, + 0xe9, 0xba, 0x4e, 0xe9, 0x3d, 0x44, 0x41, 0x09, 0x5d, 0xdd, 0xfb, 0x88, 0x82, 0x9d, 0xbb, 0xba, + 0x8c, 0x80, 0x0d, 0xdd, 0xdd, 0xdf, 0x88, 0x82, 0x1b, 0x08, 0x24, 0xca, 0x5d, 0x0e, 0xf0, 0xe8, + 0xa3, 0x3d, 0xfe, 0x3f, 0x8b, 0x76, 0xc2, 0xd0, 0xa8, 0x9b, 0x32, 0x93, 0x03, 0x17, 0x0a, 0xa8, + 0x27, 0xfc, 0x15, 0x14, 0xb7, 0xbb, 0xc7, 0x65, 0x5d, 0xa5, 0x77, 0xf8, 0x24, 0xa7, 0xa7, 0xdf, + 0x04, 0xb3, 0x53, 0xb7, 0x13, 0xa7, 0xbc, 0x40, 0x27, 0xa4, 0x18, 0x1f, 0x34, 0x80, 0x55, 0x24, + 0xae, 0x01, 0x53, 0x23, 0xfc, 0x14, 0x9a, 0xeb, 0xd7, 0x93, 0xe2, 0x96, 0xfd, 0xc4, 0x89, 0x04, + 0x45, 0x72, 0xa8, 0x7b, 0x7e, 0x24, 0x4f, 0x11, 0x65, 0x9d, 0xfe, 0x26, 0x0a, 0xae, 0x9f, 0x49, + 0xdc, 0xb0, 0xbb, 0xf7, 0xc6, 0x14, 0xff, 0x56, 0x6c, 0xde, 0xe7, 0xeb, 0x4f, 0x9b, 0x9b, 0xee, + 0xef, 0xe2, 0xcc, 0xa4, 0x63, 0x66, 0xd3, 0xfc, 0x20, 0x52, 0x7f, 0x46, 0xb9, 0x81, 0x24, 0x4a, + 0xf7, 0xe2, 0x2d, 0xe9, 0x27, 0x19, 0x5b, 0xc4, 0x7e, 0x2e, 0xb5, 0x57, 0xaf, 0x13, 0x04, 0x77, + 0x8a, 0xdc, 0xb5, 0x62, 0x41, 0x51, 0x9e, 0xee, 0x9d, 0x71, 0xf4, 0xcf, 0x7e, 0x24, 0x40, 0x4e, + 0xaa, 0xab, 0x7a, 0x7e, 0x30, 0xe7, 0xc6, 0x7a, 0x6f, 0x65, 0x71, 0x2f, 0x5b, 0x79, 0x86, 0xef, + 0xa4, 0x07, 0x88, 0x84, 0x26, 0x61, 0xb1, 0x49, 0xfc, 0xd1, 0xb6, 0xbd, 0x7e, 0x5b, 0xa6, 0xc8, + 0xb4, 0xfc, 0x7d, 0x19, 0x68, 0x62, 0x5b, 0x1b, 0xa2, 0x40, 0xcb, 0x4f, 0xf1, 0xfd, 0xd9, 0xcb, + 0x87, 0x20, 0xda, 0x34, 0xed, 0x78, 0x26, 0xf3, 0xd3, 0xb3, 0x7f, 0x7c, 0x56, 0xb5, 0x93, 0xfe, + 0xeb, 0x5f, 0x84, 0xc5, 0x28, 0xf4, 0x23, 0xa3, 0x36, 0x57, 0xc1, 0x69, 0x52, 0x6e, 0x94, 0xdc, + 0x90, 0x8f, 0xbe, 0x1c, 0x3b, 0x4e, 0x85, 0x5f, 0x4d, 0x35, 0x8c, 0xea, 0xf1, 0x91, 0x10, 0x58, + 0x2a, 0x65, 0x2e, 0xb5, 0x36, 0xe9, 0x9d, 0x44, 0x55, 0x4a, 0x0f, 0x0f, 0x0c, 0x01, 0x9a, 0xe2, + 0x17, 0x5f, 0x0a, 0x1d, 0x64, 0x21, 0x51, 0xa5, 0xea, 0x63, 0xa9, 0xd0, 0x37, 0x5f, 0xf8, 0x37, + 0xb0, 0xb9, 0xf0, 0x8c, 0x4c, 0xff, 0x5e, 0xa8, 0x98, 0x22, 0xde, 0xef, 0xf0, 0x5b, 0x49, 0x9a, + 0xb1, 0xa5, 0x77, 0x7f, 0x12, 0x14, 0x10, 0x5b, 0x76, 0xe7, 0xfb, 0x68, 0x6f, 0xe5, 0xf7, 0xf8, + 0x2c, 0x17, 0xbb, 0xbd, 0x36, 0x4e, 0xf7, 0x7f, 0x10, 0x2a, 0x86, 0x55, 0xcb, 0x29, 0x08, 0xbf, + 0x74, 0x2f, 0xeb, 0xfe, 0x23, 0xc4, 0x41, 0x0e, 0xc6, 0xc6, 0xd3, 0xfc, 0x17, 0x56, 0xa6, 0xfb, + 0x33, 0x63, 0xf8, 0x91, 0x15, 0xd3, 0x1e, 0x13, 0xbc, 0x7c, 0x21, 0x15, 0x19, 0x4c, 0x41, 0xdb, + 0x50, 0x3b, 0xc9, 0x85, 0xfc, 0x26, 0x5b, 0x8d, 0xa4, 0x5d, 0x6b, 0xc2, 0x00, 0xb3, 0x77, 0xd4, + 0x99, 0xd6, 0xa5, 0xbe, 0x08, 0x48, 0xee, 0x5a, 0x7d, 0xf1, 0x5a, 0xd6, 0x95, 0xae, 0x25, 0x11, + 0xf8, 0x89, 0x8a, 0x5a, 0x7f, 0x19, 0x7b, 0x2a, 0x8b, 0x89, 0xee, 0x89, 0x22, 0x86, 0x36, 0xd6, + 0xdf, 0x84, 0x67, 0x79, 0xff, 0x76, 0x3a, 0x6c, 0x77, 0xf0, 0x56, 0x55, 0xa9, 0x24, 0x85, 0x6e, + 0xe9, 0x5d, 0xff, 0xe2, 0x41, 0x19, 0x69, 0x4d, 0xaf, 0xf4, 0x67, 0xe2, 0x68, 0xaf, 0xe2, 0x7e, + 0x89, 0x95, 0x70, 0x5e, 0x21, 0x8e, 0x3e, 0x9b, 0x79, 0x58, 0x67, 0x05, 0x94, 0x76, 0x90, 0x4a, + 0xf6, 0xc2, 0xfc, 0xd8, 0x8a, 0x42, 0x24, 0x32, 0x67, 0x1f, 0xc4, 0x91, 0x33, 0x9a, 0x65, 0xec, + 0x7d, 0x4f, 0xe1, 0x41, 0x22, 0x4f, 0xcc, 0x62, 0xb5, 0x77, 0x41, 0xc9, 0xfa, 0xb5, 0xdf, 0x25, + 0xe7, 0x10, 0x1f, 0x85, 0x0f, 0x77, 0xab, 0x56, 0xe4, 0x4e, 0xef, 0x77, 0xef, 0xa2, 0x3f, 0x12, + 0x24, 0x25, 0x7b, 0xcb, 0x7a, 0x7c, 0x48, 0x25, 0x32, 0xea, 0xd5, 0x6f, 0xe2, 0x41, 0x15, 0xdf, + 0x7f, 0x12, 0x43, 0xf3, 0xff, 0x05, 0x27, 0x7e, 0xb5, 0x55, 0x17, 0x52, 0x67, 0xc7, 0x7c, 0x48, + 0x4e, 0x66, 0x1f, 0xb6, 0xed, 0xa0, 0x2f, 0x66, 0x7d, 0x9e, 0x20, 0x42, 0xd7, 0xc4, 0xdd, 0xde, + 0xf1, 0x5b, 0xf8, 0x28, 0x2b, 0x64, 0x52, 0xdc, 0x6f, 0x4f, 0x5f, 0x04, 0xd7, 0x15, 0xbd, 0xe4, + 0x66, 0xff, 0x31, 0x35, 0x5f, 0x37, 0x33, 0x0f, 0xe0, 0x88, 0xcf, 0x7f, 0xfc, 0x48, 0x48, 0x59, + 0xf5, 0x63, 0x9e, 0xa3, 0x77, 0xf0, 0x44, 0x43, 0xc1, 0x8a, 0x75, 0x0f, 0xf7, 0x61, 0x1e, 0xae, + 0x26, 0x0a, 0x8a, 0x86, 0x99, 0x7b, 0xeb, 0x60, 0x63, 0xfe, 0x73, 0x16, 0x4e, 0xd2, 0x5b, 0xb7, + 0xc1, 0x5c, 0xd9, 0xe9, 0x36, 0x14, 0xe8, 0x33, 0x68, 0xd9, 0x61, 0x6e, 0x5f, 0xdc, 0x4d, 0xd9, + 0xee, 0x73, 0x1c, 0x21, 0x11, 0x7d, 0x8d, 0x75, 0xc2, 0x01, 0x0f, 0x90, 0xba, 0x6f, 0xe1, 0x22, + 0x64, 0xcd, 0x6b, 0xc4, 0xa3, 0x27, 0x41, 0x88, 0x88, 0x81, 0x59, 0x75, 0x4a, 0x63, 0xac, 0x4b, + 0x73, 0xc4, 0x04, 0x4b, 0x55, 0x13, 0xc7, 0x2b, 0x17, 0x8a, 0x55, 0x78, 0x90, 0x52, 0x7d, 0xd5, + 0xe9, 0x5a, 0x7d, 0x4b, 0x7c, 0x13, 0xdb, 0x6a, 0x4a, 0xb7, 0xd7, 0xbc, 0x48, 0x25, 0x2c, 0xf9, + 0xef, 0x7e, 0xf8, 0x52, 0x86, 0xad, 0xdd, 0x1b, 0xee, 0xf6, 0x93, 0xfb, 0xe5, 0x22, 0xd7, 0xc4, + 0x10, 0xaa, 0x6e, 0x97, 0xc4, 0x82, 0x21, 0x03, 0x3a, 0x7d, 0xfc, 0x48, 0x25, 0x12, 0xe7, 0x10, + 0x2e, 0xff, 0xcb, 0x8c, 0x71, 0x11, 0xfb, 0xde, 0xf7, 0xba, 0x63, 0x2d, 0x1e, 0x33, 0x4d, 0xce, + 0xbd, 0xcf, 0xf8, 0xda, 0x64, 0x91, 0x68, 0xa3, 0x7f, 0x16, 0xd7, 0xd2, 0x3c, 0x4d, 0xe5, 0xf2, + 0x06, 0x7c, 0x15, 0x56, 0xb1, 0x5b, 0x4e, 0x95, 0xdd, 0xeb, 0xe0, 0x96, 0xef, 0x69, 0xde, 0xdf, + 0x7c, 0x16, 0xe9, 0x9b, 0xc7, 0x69, 0x7d, 0xc4, 0x89, 0x66, 0x6c, 0x2f, 0xff, 0x31, 0x79, 0xd8, + 0xc4, 0xc5, 0x93, 0x6d, 0x4c, 0xc6, 0x0b, 0xe3, 0xca, 0xef, 0xaa, 0x7b, 0xbf, 0xea, 0xff, 0x76, + 0xb4, 0xbc, 0x26, 0x58, 0xae, 0xf7, 0x77, 0xc4, 0x89, 0x05, 0x92, 0x63, 0x7f, 0xba, 0x6e, 0x2b, + 0xdf, 0xc4, 0x8c, 0xe9, 0x5d, 0x93, 0x0e, 0x58, 0x24, 0x7c, 0x6f, 0x7c, 0x67, 0x4b, 0xf0, 0x9c, + 0x56, 0xf0, 0x52, 0xc4, 0xb4, 0xf1, 0x30, 0x57, 0x5b, 0x33, 0x08, 0x60, 0x53, 0x4c, 0x94, 0xcf, + 0xbe, 0x0b, 0x2a, 0xb1, 0x1e, 0x4c, 0x6b, 0xe4, 0xfd, 0xf5, 0xef, 0x82, 0xcc, 0xbe, 0xeb, 0x5b, + 0xdf, 0xde, 0x25, 0x5f, 0xe0, 0x9c, 0x51, 0x9e, 0xfa, 0xea, 0xfe, 0x24, 0x35, 0x7b, 0xb6, 0x60, + 0x47, 0xf4, 0xff, 0x85, 0x71, 0x03, 0x48, 0x99, 0xfb, 0xfc, 0x61, 0x0e, 0x5c, 0xdd, 0xfa, 0x13, + 0xb0, 0x82, 0x3f, 0x5a, 0xcb, 0x4f, 0xe2, 0x41, 0x49, 0x5f, 0xbd, 0xee, 0xed, 0x30, 0xf0, 0x7c, + 0x65, 0xef, 0x40, 0xea, 0x4e, 0x21, 0xee, 0xef, 0x57, 0x5e, 0x24, 0x15, 0x1d, 0x35, 0xd4, 0x92, + 0xad, 0x1a, 0x0c, 0x7e, 0x0f, 0xbf, 0xdf, 0x08, 0x13, 0x54, 0xde, 0xa7, 0xaa, 0x68, 0xd7, 0xe0, + 0xa8, 0xf7, 0x8e, 0xa6, 0x04, 0xbf, 0x67, 0x60, 0xec, 0x74, 0x1f, 0x7c, 0x4d, 0xd0, 0x15, 0x96, + 0x8e, 0xa5, 0x09, 0xed, 0x62, 0x01, 0x35, 0xf3, 0x7a, 0xad, 0xde, 0x20, 0x16, 0x56, 0xaa, 0x4c, + 0xf5, 0x7f, 0x70, 0x84, 0x22, 0x22, 0x93, 0xd4, 0x9d, 0x67, 0xa6, 0xde, 0x26, 0x0a, 0x3a, 0xae, + 0xab, 0xdc, 0x44, 0x11, 0x77, 0xbd, 0x78, 0x90, 0x89, 0xe7, 0xf6, 0xe8, 0x91, 0x88, 0x58, 0x9f, + 0xcc, 0xc7, 0x12, 0x0a, 0xec, 0x6c, 0x6f, 0x7b, 0x1a, 0x8d, 0x8f, 0xbb, 0x9e, 0x11, 0x04, 0xd4, + 0x9f, 0x77, 0xfb, 0x89, 0x92, 0x8d, 0xff, 0x0a, 0x5e, 0xfb, 0xdd, 0x3a, 0x7b, 0xbb, 0xbf, 0x13, + 0xf8, 0x4e, 0xd2, 0xf6, 0x39, 0x23, 0xe3, 0x0a, 0x3b, 0x53, 0x72, 0xed, 0xcc, 0x91, 0xda, 0x90, + 0xb9, 0x0d, 0xaa, 0x16, 0xfd, 0xd4, 0x9a, 0x23, 0xa2, 0xf0, 0xa5, 0xc5, 0x7b, 0xa2, 0x15, 0xf6, + 0x93, 0x9e, 0x24, 0x1b, 0xd1, 0x95, 0x07, 0x7c, 0x11, 0xdd, 0xf2, 0xb5, 0xfe, 0x08, 0xe9, 0x0e, + 0x32, 0xef, 0xf0, 0x55, 0x4d, 0xf4, 0x06, 0xca, 0xfb, 0xbb, 0xf1, 0x02, 0x01, 0x15, 0x78, 0x20, + 0x57, 0x68, 0xbb, 0xe2, 0xf5, 0x63, 0xe6, 0x63, 0xe6, 0xb1, 0xe4, 0xf8, 0x9f, 0x11, 0x09, 0x4d, + 0x4a, 0xa7, 0xcc, 0xc6, 0x24, 0x48, 0x24, 0xae, 0x62, 0x0f, 0x7c, 0x12, 0x6b, 0x5e, 0xf1, 0x03, + 0xf7, 0xb4, 0xa0, 0xd7, 0x10, 0x35, 0x79, 0xd3, 0x76, 0x97, 0xb1, 0xf8, 0xc1, 0x8e, 0xe4, 0x67, + 0x99, 0x74, 0xc6, 0xea, 0x78, 0x3b, 0x6d, 0x3e, 0x3e, 0x98, 0xa2, 0xf0, 0x91, 0xef, 0x2f, 0x3d, + 0x3c, 0x27, 0xc1, 0x3d, 0x56, 0xb0, 0x6a, 0x94, 0x6b, 0x04, 0x40, 0x43, 0x0d, 0x4d, 0x93, 0xbc, + 0x44, 0x14, 0x98, 0xd2, 0x00, 0xcd, 0xdc, 0xbb, 0x8a, 0x7c, 0x7c, 0xf7, 0x80, 0xf9, 0xff, 0x14, + 0x58, 0x4b, 0xd7, 0xc3, 0xee, 0xb5, 0xf8, 0x2e, 0x2c, 0x99, 0xe2, 0xf7, 0xf8, 0x24, 0x2d, 0x56, + 0xff, 0x1e, 0x67, 0xde, 0x65, 0x11, 0x35, 0x0d, 0x97, 0xb6, 0xbe, 0x10, 0xd1, 0x0d, 0x44, 0x78, + 0xda, 0x04, 0x54, 0x57, 0x2b, 0x1e, 0x20, 0x15, 0x0d, 0x2f, 0xb1, 0x47, 0x54, 0x5a, 0xa9, 0x0c, + 0x67, 0xff, 0x09, 0x9b, 0x55, 0x27, 0x55, 0x13, 0xfe, 0x0a, 0x2b, 0x92, 0x75, 0x59, 0x57, 0xf8, + 0x28, 0x8b, 0xaa, 0xad, 0x6a, 0xff, 0x05, 0xba, 0xd6, 0xa4, 0xff, 0x9f, 0x05, 0x55, 0x17, 0xaa, + 0xae, 0x26, 0xc0, 0xe2, 0x64, 0x98, 0xce, 0xff, 0x04, 0x99, 0xd8, 0x6f, 0x7f, 0x90, 0x8b, 0x32, + 0x67, 0x12, 0x11, 0x2f, 0x3f, 0x77, 0xba, 0x76, 0xfc, 0x48, 0x80, 0x8d, 0xdc, 0xea, 0x37, 0x77, + 0x7b, 0xb9, 0xf3, 0x89, 0x04, 0xa4, 0x77, 0x7d, 0xe9, 0xff, 0x89, 0xbb, 0xc2, 0xaf, 0x7e, 0x0b, + 0x04, 0xa4, 0xe8, 0x7e, 0x7c, 0x4f, 0x46, 0xfd, 0xc4, 0x7e, 0x3a, 0xef, 0x23, 0x49, 0xec, 0x50, + 0xe8, 0x36, 0x87, 0x6b, 0xef, 0xe3, 0x2f, 0x77, 0x3a, 0x5a, 0x07, 0xb6, 0xaf, 0xe5, 0xed, 0xe2, + 0x44, 0xfc, 0xda, 0x6b, 0xf0, 0x47, 0x9e, 0x3b, 0xf1, 0x30, 0x43, 0xe5, 0xef, 0xe2, 0x01, 0x6d, + 0x55, 0x55, 0xa6, 0x39, 0xd4, 0x3f, 0xc2, 0x95, 0x7d, 0x66, 0xa4, 0xc4, 0x3e, 0xb1, 0xe4, 0x0c, + 0x7c, 0x23, 0x55, 0x55, 0x53, 0x31, 0x33, 0xcd, 0x86, 0x51, 0x89, 0x90, 0x85, 0xa7, 0xff, 0x82, + 0xe2, 0xbb, 0xa3, 0x44, 0x55, 0x32, 0xa8, 0xbf, 0x89, 0x04, 0x3d, 0x25, 0x7f, 0x82, 0x21, 0x0b, + 0x28, 0x8e, 0x41, 0xa6, 0x5f, 0xe0, 0x94, 0x8d, 0x63, 0xd5, 0xb5, 0x9e, 0xfb, 0x12, 0x9d, 0x67, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x20, 0x10, 0x30, 0x12, 0xa7, 0xc4, 0x0b, 0xa2, 0x1a, + 0x0f, 0x2a, 0xa5, 0xeb, 0xd0, 0x40, 0x25, 0xc3, 0x1c, 0x24, 0x62, 0x5d, 0xf1, 0xd4, 0xc6, 0x89, + 0x97, 0x83, 0x7e, 0x0b, 0xbf, 0xe7, 0xa2, 0x0d, 0xf1, 0xd2, 0x65, 0xac, 0xac, 0x26, 0x54, 0x5d, + 0xf2, 0xe3, 0xc8, 0x63, 0xc8, 0x7f, 0x94, 0x63, 0xde, 0x11, 0xe2, 0xc7, 0xb7, 0x4f, 0x1f, 0x37, + 0x07, 0x19, 0xde, 0x60, 0xa3, 0xe1, 0x88, 0x2d, 0xed, 0x55, 0x46, 0x93, 0x79, 0xa9, 0xf6, 0x8f, + 0xf4, 0xc7, 0x1e, 0xb7, 0x5c, 0xed, 0x12, 0x14, 0xaa, 0x83, 0x41, 0xb8, 0x82, 0x5b, 0xe5, 0x30, + 0x03, 0xdd, 0x71, 0xf0, 0x42, 0x85, 0x30, 0xcd, 0x8a, 0x39, 0x87, 0xd4, 0xc0, 0x11, 0xb7, 0x56, + 0xe7, 0x2f, 0xf7, 0x3f, 0x0c, 0x47, 0x5d, 0x01, 0xd7, 0x44, 0xbb, 0x61, 0xbf, 0x56, 0x34, 0x10, + 0x11, 0x90, 0xfb, 0xb9, 0x99, 0x3b, 0x1c, 0xbd, 0x9a, 0x53, 0x47, 0xe4, 0x9b, 0x84, 0x47, 0xf5, + 0x87, 0xe6, 0x8d, 0xa0, 0xf8, 0x5b, 0x87, 0x04, 0x46, 0x09, 0xd8, 0x78, 0x49, 0xa0, 0xcc, 0xa6, + 0xd1, 0x7d, 0xdf, 0xe0, 0xa6, 0x62, 0xb3, 0x1b, 0x86, 0x29, 0xad, 0x8b, 0xdf, 0x4e, 0x87, 0x82, + 0x3f, 0x0b, 0x46, 0x29, 0xb1, 0x96, 0xd8, 0x67, 0x46, 0x77, 0x40, 0xca, 0x5b, 0xa6, 0x97, 0xf8, + 0x83, 0xe1, 0xc4, 0x5f, 0x6d, 0x7f, 0x8c, 0xb5, 0x7c, 0x34, 0x30, 0xaa, 0xc7, 0xc4, 0x1d, 0xb7, + 0x84, 0xf0, 0x1d, 0x36, 0x5b, 0x0f, 0xf0, 0x4d, 0xa4, 0xd4, 0x02, 0x76, 0x9a, 0x94, 0x8c, 0xe1, + 0x73, 0x8f, 0x32, 0x71, 0xe9, 0x6b, 0xa5, 0xf8, 0xbe, 0x7a, 0x55, 0xf8, 0xe4, 0xb5, 0x92, 0xdf, + 0x0b, 0xd3, 0xad, 0x45, 0x2a, 0x1b, 0x5c, 0xe4, 0x57, 0xb0, 0x55, 0x6f, 0x92, 0x21, 0x36, 0xbf, + 0xff, 0x0b, 0xa6, 0x31, 0xb3, 0xcc, 0x85, 0x74, 0x73, 0xc2, 0x77, 0x7a, 0xd2, 0x0b, 0x2d, 0x73, + 0xc6, 0xcb, 0x4b, 0x3a, 0xcc, 0x17, 0x5b, 0x8f, 0x78, 0x97, 0x49, 0x71, 0x72, 0x96, 0x4f, 0xd7, + 0x64, 0xad, 0xf7, 0xbb, 0xef, 0x1a, 0xc4, 0xee, 0xc1, 0x03, 0x44, 0xb1, 0xc5, 0x4f, 0x0f, 0xff, + 0x40, 0x66, 0xcf, 0xa9, 0xc3, 0x23, 0xfa, 0x27, 0x3e, 0xb9, 0xc2, 0xf1, 0xba, 0x9e, 0x6c, 0x97, + 0xb4, 0xe7, 0x39, 0x69, 0xf5, 0xfd, 0x5a, 0x69, 0x9c, 0x31, 0x8e, 0xfe, 0x24, 0x92, 0x7c, 0x37, + 0x44, 0xd5, 0xa4, 0x6a, 0xdf, 0x4f, 0xf0, 0x1b, 0xde, 0x48, 0xcf, 0x23, 0x26, 0x08, 0x0d, 0x26, + 0x37, 0x12, 0xb9, 0xec, 0xa6, 0xca, 0x57, 0x33, 0x1f, 0xbe, 0x12, 0xe9, 0xb9, 0xe4, 0x5f, 0xc1, + 0x7e, 0x18, 0x51, 0xf8, 0x0d, 0x6b, 0x0e, 0xa4, 0x81, 0xff, 0x5d, 0xc2, 0x44, 0x2d, 0x22, 0x7f, + 0x75, 0x62, 0x0e, 0xeb, 0x32, 0xe6, 0xd8, 0x85, 0x2b, 0x66, 0xac, 0x6d, 0x86, 0xf8, 0x25, 0x10, + 0x6e, 0x8b, 0x44, 0x3e, 0x2e, 0x05, 0xc1, 0x87, 0x7e, 0xf8, 0xd2, 0x96, 0x81, 0xa7, 0x7f, 0x6d, + 0x24, 0xb0, 0x92, 0xbc, 0x9f, 0xa1, 0x5a, 0x88, 0xc7, 0xba, 0x8f, 0x7f, 0x2f, 0xcb, 0x4b, 0xff, + 0x0e, 0xe9, 0x0e, 0xf9, 0x84, 0x90, 0x31, 0xce, 0x62, 0x0a, 0x28, 0x07, 0xf1, 0xff, 0x67, 0xf7, + 0xa5, 0x3f, 0x06, 0x3e, 0x5f, 0xc6, 0xd6, 0x82, 0x21, 0xa3, 0x05, 0x0c, 0x00, 0xee, 0x60, 0x00, + 0x08, 0x2d, 0xcd, 0xc0, 0xca, 0x2d, 0xa2, 0x06, 0x17, 0x8c, 0x1c, 0xc3, 0x05, 0x06, 0x5b, 0xcc, + 0x75, 0x4f, 0x4d, 0x87, 0xd5, 0x1f, 0x8e, 0x69, 0xaf, 0x65, 0xc2, 0x66, 0x0a, 0xff, 0xd7, 0x0f, + 0x90, 0x65, 0xa1, 0xb5, 0x5e, 0xba, 0x05, 0x19, 0x66, 0x9f, 0x8c, 0x7b, 0x91, 0x24, 0xd2, 0x6f, + 0xeb, 0x86, 0xa1, 0xfa, 0xa5, 0xa2, 0x8d, 0x50, 0x0c, 0xb2, 0x42, 0xc0, 0x5f, 0xd1, 0x0f, 0x6c, + 0xe0, 0x82, 0x38, 0x10, 0x41, 0xa2, 0xa8, 0xf4, 0xcf, 0x8d, 0x10, 0x44, 0xfb, 0xfd, 0x84, 0xc9, + 0xa2, 0x88, 0xd7, 0xcb, 0x9d, 0xab, 0x50, 0x88, 0x1a, 0x1b, 0xc2, 0x76, 0x38, 0x1c, 0x04, 0x0f, + 0xb9, 0xdb, 0xec, 0x7e, 0xbb, 0x5b, 0x5f, 0x84, 0x34, 0xd7, 0x85, 0x84, 0xe3, 0x14, 0xd3, 0x2d, + 0x42, 0x74, 0x10, 0x8a, 0xdb, 0xa6, 0x34, 0x04, 0xb6, 0x08, 0x4c, 0x1f, 0x9f, 0x4e, 0x6a, 0x16, + 0x7e, 0x72, 0x92, 0x92, 0x11, 0x8b, 0x9f, 0xae, 0x5e, 0x35, 0xec, 0xbc, 0x2f, 0x6e, 0xf4, 0xfd, + 0xc3, 0x2c, 0xee, 0xca, 0x10, 0xdd, 0x2d, 0x32, 0xd4, 0x40, 0xa6, 0x2d, 0x8d, 0x75, 0xd5, 0x77, + 0x34, 0xed, 0xba, 0xaf, 0x71, 0x09, 0x45, 0x10, 0x9e, 0x37, 0x90, 0x21, 0x6f, 0x1d, 0x24, 0x35, + 0x86, 0x39, 0xb2, 0x21, 0x03, 0x3b, 0x12, 0x13, 0x4f, 0xfc, 0x08, 0xea, 0xb1, 0x9b, 0x24, 0x8d, + 0x2c, 0xa7, 0xa5, 0xa7, 0xc1, 0x0b, 0x85, 0x46, 0x30, 0xb5, 0x65, 0xeb, 0xdd, 0x9e, 0x35, 0x69, + 0x6c, 0xb0, 0xb0, 0x83, 0xc3, 0xfd, 0xfb, 0x03, 0xad, 0xa5, 0xac, 0xd3, 0xb5, 0x2d, 0xd4, 0xe8, + 0xc5, 0x6a, 0xf8, 0xed, 0x6d, 0x8b, 0xf9, 0x90, 0xd0, 0xbc, 0x8e, 0xb2, 0xb3, 0x32, 0x3c, 0x6c, + 0xb2, 0xf8, 0xf1, 0x10, 0xd7, 0x14, 0x4e, 0x24, 0x31, 0x96, 0x41, 0x96, 0xb4, 0xcb, 0x5a, 0x65, + 0xb1, 0xe8, 0x89, 0x96, 0x05, 0xf7, 0x2b, 0xb6, 0x97, 0xfc, 0xf8, 0x8a, 0x20, 0xda, 0x65, 0xad, + 0x32, 0xc5, 0x6d, 0x93, 0x36, 0xc8, 0x2e, 0xb0, 0x94, 0xdb, 0x1d, 0x70, 0x4b, 0x18, 0x93, 0x8b, + 0xf9, 0xf1, 0xe2, 0x66, 0xd1, 0x64, 0x77, 0x2a, 0x71, 0xdf, 0x25, 0x37, 0xfe, 0x16, 0xdc, 0x76, + 0x7f, 0x64, 0xe5, 0x73, 0xdf, 0xed, 0xf8, 0x63, 0x2c, 0x62, 0x22, 0x96, 0xf4, 0x18, 0x96, 0xed, + 0x55, 0x2f, 0xb8, 0xbf, 0xb8, 0x3e, 0x67, 0xcd, 0xe1, 0x23, 0x0c, 0xfc, 0x9b, 0x86, 0x71, 0x81, + 0x86, 0x3c, 0xe1, 0xd3, 0x2c, 0x68, 0xd0, 0xb4, 0xd1, 0x97, 0x5b, 0x5c, 0x66, 0x1f, 0x62, 0xa1, + 0xc6, 0x2b, 0xfc, 0x34, 0xc5, 0x7c, 0x32, 0xf7, 0x57, 0xc7, 0xbc, 0x8e, 0xcd, 0x7f, 0x14, 0x0f, + 0xba, 0xc6, 0x8d, 0x8d, 0xff, 0xb0, 0x28, 0xff, 0xbc, 0xf3, 0x27, 0x1e, 0x96, 0xba, 0x5f, 0x9b, + 0xac, 0x52, 0x73, 0xca, 0x9c, 0x72, 0x5a, 0xc9, 0x7e, 0xb9, 0xe0, 0x00, 0x2c, 0x1f, 0x19, 0x07, + 0xc6, 0x47, 0xc6, 0x7f, 0xcf, 0x12, 0xd3, 0x88, 0x4c, 0x88, 0x4c, 0xff, 0x9e, 0x17, 0x89, 0x13, + 0x32, 0xc2, 0x71, 0x93, 0xe6, 0x7f, 0xc3, 0x7e, 0x35, 0xe4, 0x02, 0x78, 0x68, 0xd9, 0x61, 0xef, + 0x7f, 0x3c, 0x74, 0x9d, 0x0d, 0x4b, 0x55, 0x2f, 0x34, 0xb5, 0xd2, 0xd7, 0xcb, 0x5f, 0x2f, 0xfc, + 0x54, 0x32, 0x87, 0xaf, 0x4b, 0xec, 0xda, 0xe9, 0x69, 0x7d, 0xf8, 0xd2, 0x07, 0xc6, 0x38, 0xad, + 0xec, 0x3d, 0x51, 0x11, 0x0c, 0x37, 0x51, 0xab, 0x13, 0x8c, 0x78, 0xfd, 0x86, 0xcc, 0x76, 0x8f, + 0x04, 0x34, 0x6d, 0x61, 0x1a, 0x2b, 0xca, 0x08, 0x23, 0xc0, 0xc6, 0x3e, 0xf8, 0xae, 0x6f, 0xf0, + 0xf9, 0x70, 0xda, 0x11, 0x18, 0xd6, 0xa9, 0x06, 0x59, 0x6c, 0x2d, 0x1e, 0x9b, 0x2d, 0x41, 0xf2, + 0xa1, 0xa2, 0xaa, 0x35, 0x2d, 0xda, 0x3e, 0x32, 0x0f, 0x8c, 0xaa, 0x96, 0xed, 0x27, 0x0a, 0xf0, + 0xe1, 0xb4, 0xaa, 0xf0, 0x20, 0xdd, 0x77, 0xc6, 0xfd, 0x33, 0xce, 0x8d, 0x1a, 0x96, 0xaa, 0x5f, + 0xc7, 0x6e, 0x5b, 0x0f, 0x1b, 0x86, 0x94, 0xca, 0x3b, 0x50, 0x97, 0x2c, 0x44, 0x78, 0x08, 0xf5, + 0x96, 0x37, 0x8a, 0x82, 0x98, 0x3b, 0x1a, 0x3f, 0x54, 0x73, 0x83, 0xdd, 0x3f, 0xf9, 0xe2, 0x29, + 0x3c, 0x42, 0x64, 0x42, 0x67, 0xfe, 0x79, 0xd2, 0x35, 0x2d, 0x54, 0xbf, 0xff, 0x8e, 0x91, 0xda, + 0xbf, 0xc5, 0x8c, 0xb1, 0x09, 0xb1, 0x7f, 0xf9, 0x16, 0x7e, 0xab, 0xc2, 0x16, 0xab, 0xce, 0x2e, + 0xa4, 0xe8, 0x78, 0x1d, 0x3e, 0x1c, 0xe0, 0x6b, 0x48, 0x7f, 0x87, 0xc6, 0x66, 0x28, 0xfd, 0x41, + 0xdb, 0x5b, 0x87, 0x50, 0x00, 0x6b, 0x02, 0xfe, 0xd2, 0x90, 0x80, 0xea, 0x4c, 0x7c, 0xdc, 0xdc, + 0xdd, 0x56, 0x0f, 0xc4, 0x8d, 0x18, 0x18, 0x7f, 0x18, 0x18, 0x7f, 0x27, 0x1b, 0xc3, 0x8f, 0x20, + 0xf1, 0xaa, 0x1f, 0x65, 0xb4, 0x8e, 0x96, 0x80, 0x6a, 0x61, 0xec, 0x55, 0xc3, 0x61, 0x50, 0x08, + 0xe7, 0x82, 0x4d, 0x9b, 0x25, 0xe8, 0xb7, 0xe9, 0xd0, 0xad, 0x8d, 0x4b, 0x55, 0x2d, 0x67, 0x14, + 0x34, 0x98, 0x62, 0x51, 0xe8, 0x5a, 0x5e, 0x79, 0x98, 0x04, 0xee, 0x5b, 0xc1, 0x5c, 0x24, 0x3f, + 0xc2, 0x1a, 0x63, 0x4f, 0x9f, 0xc6, 0x9f, 0x29, 0xa5, 0xfc, 0x18, 0x70, 0xf3, 0x3a, 0xe1, 0x00, + 0xe2, 0x91, 0x0b, 0x3e, 0x77, 0x1e, 0x8d, 0x22, 0x14, 0x37, 0x72, 0x4b, 0x34, 0x3e, 0x65, 0xf3, + 0x5e, 0x86, 0xf6, 0xaa, 0xae, 0xeb, 0x92, 0xd1, 0xa7, 0xf7, 0x9e, 0x80, 0x4f, 0xff, 0xc7, 0xc6, + 0x7a, 0xe3, 0x63, 0x46, 0xeb, 0xd9, 0x65, 0xad, 0xd8, 0xa3, 0x59, 0x2a, 0x67, 0x53, 0x81, 0x07, + 0x57, 0xdf, 0x6f, 0x6e, 0xce, 0x6f, 0xef, 0x4f, 0xd9, 0x2d, 0xc5, 0xf6, 0x37, 0xcb, 0x08, 0x32, + 0xed, 0x8d, 0xa8, 0x9e, 0xbe, 0xcb, 0x0a, 0x82, 0xa0, 0xc6, 0x0e, 0xbb, 0xa6, 0x41, 0x10, 0x5d, + 0x84, 0xf7, 0x51, 0x49, 0x46, 0x04, 0x9f, 0xfb, 0x2a, 0x6d, 0x3f, 0x8d, 0x81, 0xb5, 0x05, 0x8a, + 0x0c, 0xb2, 0x6d, 0x2f, 0x51, 0xeb, 0x19, 0x64, 0x14, 0xcf, 0x5c, 0xd7, 0x36, 0x6d, 0xda, 0x7c, + 0x56, 0x4c, 0x4b, 0x5a, 0x14, 0x53, 0x07, 0x46, 0xb8, 0xbb, 0xd9, 0x0f, 0x99, 0x94, 0xf6, 0x9d, + 0x8a, 0x5d, 0x5f, 0x08, 0xfc, 0xf1, 0x2d, 0x08, 0xb5, 0x8f, 0x8c, 0x83, 0xe3, 0x22, 0x66, 0x44, + 0xcc, 0xf5, 0xc2, 0x14, 0xe9, 0x68, 0x1c, 0x35, 0x91, 0xa6, 0xb1, 0xaf, 0x78, 0x6e, 0x0f, 0x59, + 0xe9, 0x7f, 0x13, 0xd9, 0xb7, 0xc6, 0x88, 0x40, 0xd5, 0x12, 0xa0, 0x72, 0xe0, 0x4f, 0x83, 0x34, + 0xb2, 0x0b, 0x5b, 0x06, 0x01, 0xa9, 0x7a, 0x59, 0x19, 0x74, 0xd6, 0x98, 0x5b, 0xac, 0x3b, 0x55, + 0x43, 0x8c, 0xdc, 0xc4, 0x4a, 0x33, 0x1a, 0x20, 0x4e, 0x5a, 0x0e, 0x9a, 0x4c, 0xdd, 0x4e, 0x62, + 0x3b, 0x38, 0xbf, 0xed, 0x0d, 0x78, 0x7f, 0x4e, 0x24, 0xef, 0x63, 0x80, 0x2d, 0xfe, 0x1f, 0xb3, + 0x13, 0xde, 0x57, 0xd0, 0x71, 0xba, 0x78, 0x4b, 0x28, 0xc2, 0x13, 0x7f, 0x3f, 0xb6, 0x52, 0xc0, + 0x41, 0x33, 0xdb, 0x02, 0xff, 0x60, 0xaa, 0x61, 0x4f, 0x97, 0x79, 0x35, 0xad, 0xa3, 0x75, 0x26, + 0xcd, 0x81, 0xfd, 0xd3, 0xa5, 0x39, 0x3c, 0x68, 0x9d, 0xb0, 0x87, 0xd2, 0xf0, 0xf7, 0x85, 0x9f, + 0x9d, 0x7b, 0xf1, 0x4b, 0x73, 0xa0, 0xe1, 0xdd, 0x0d, 0x0f, 0xb8, 0xf9, 0xfe, 0xd3, 0xa0, 0x54, + 0x37, 0x6e, 0x8e, 0xc3, 0xfc, 0x5e, 0xf9, 0xbb, 0x82, 0x01, 0x9e, 0xf9, 0x6a, 0x53, 0x2d, 0x25, + 0xc1, 0x8d, 0x8e, 0xfa, 0x4e, 0x4b, 0xb9, 0xb6, 0x64, 0xd7, 0x78, 0x15, 0x5c, 0x43, 0xfc, 0x6f, + 0x88, 0x1e, 0xf2, 0x22, 0xef, 0x3a, 0x5c, 0xb2, 0x5c, 0xb3, 0x95, 0x97, 0x01, 0xc4, 0x0f, 0x79, + 0x80, 0x30, 0x12, 0xb6, 0x5a, 0xd9, 0x79, 0xe5, 0xad, 0x96, 0x31, 0x2d, 0x44, 0xbc, 0x12, 0xd5, + 0x4b, 0xf1, 0x91, 0x00, 0xe0, 0x3d, 0xe7, 0xa4, 0x0f, 0x2c, 0x10, 0x0e, 0x03, 0xde, 0x7d, 0x20, + 0x79, 0x67, 0x86, 0x28, 0x06, 0x0e, 0xbe, 0x19, 0x9e, 0x1b, 0x56, 0x33, 0x96, 0x02, 0x9d, 0x99, + 0x9b, 0xe8, 0x3f, 0x3f, 0x5e, 0x03, 0x00, 0x20, 0x20, 0x45, 0x42, 0x1d, 0x97, 0x2e, 0x84, 0xcc, + 0x89, 0x99, 0x08, 0xf0, 0x5a, 0x9e, 0x4e, 0x79, 0xd2, 0x33, 0x2d, 0x4c, 0xbf, 0xf3, 0xf1, 0x5e, + 0x10, 0xed, 0xaf, 0xc2, 0x1d, 0xb5, 0xf8, 0x5f, 0x86, 0xf2, 0xc8, 0xf2, 0xca, 0x9a, 0x3c, 0xcd, + 0x75, 0xf3, 0xa2, 0x0e, 0xbc, 0x42, 0x64, 0x42, 0x64, 0x6e, 0x5a, 0xb9, 0x7e, 0x17, 0xc1, 0x3b, + 0x67, 0xc3, 0xde, 0x35, 0x4a, 0x51, 0x81, 0xc4, 0x47, 0x43, 0x12, 0xd9, 0xbc, 0x7e, 0x5a, 0xf9, + 0x7f, 0xe3, 0x68, 0x9a, 0x5d, 0x06, 0x89, 0x3d, 0x54, 0x18, 0x37, 0x97, 0x2c, 0x32, 0x41, 0xfb, + 0x2a, 0xca, 0xd1, 0x7d, 0x3f, 0x76, 0x19, 0x5c, 0xd3, 0xbf, 0x2b, 0x46, 0x29, 0xa5, 0x95, 0x34, + 0x19, 0x3c, 0x76, 0x5a, 0xd9, 0x7f, 0xf1, 0xbd, 0x53, 0x46, 0x1b, 0xcb, 0x7f, 0xe1, 0xf6, 0x5b, + 0xc7, 0x9a, 0x11, 0x97, 0xfc, 0x42, 0x64, 0x6a, 0x71, 0x36, 0x70, 0xd4, 0x48, 0x80, 0x50, 0x09, + 0x23, 0x59, 0x4b, 0x2b, 0x9e, 0x8f, 0x2e, 0x24, 0x40, 0xb8, 0x81, 0xc1, 0x03, 0x84, 0xe2, 0x32, + 0x79, 0xd6, 0x1a, 0xbb, 0xe8, 0x7c, 0xa2, 0x3a, 0x2f, 0x5f, 0x5b, 0xa3, 0xfa, 0x27, 0x43, 0x5c, + 0x78, 0x5a, 0x2a, 0xaa, 0xfc, 0xae, 0x45, 0xd5, 0x57, 0x88, 0x10, 0x3b, 0xcd, 0xae, 0x7a, 0x59, + 0x6f, 0x2d, 0x20, 0x64, 0xdc, 0x4d, 0x1d, 0xe2, 0x71, 0x08, 0x6f, 0x41, 0x5c, 0x4f, 0x88, 0x08, + 0x0f, 0x0d, 0x34, 0xfe, 0x2f, 0xb6, 0x1b, 0x0f, 0x0a, 0xd9, 0x98, 0xd3, 0x8c, 0xf1, 0x12, 0xf1, + 0x7e, 0x2e, 0x9a, 0xd5, 0x44, 0x78, 0x9f, 0x13, 0x82, 0xbe, 0x09, 0xc4, 0xaa, 0xb6, 0x61, 0x83, + 0x5a, 0x9b, 0xf8, 0x90, 0xa1, 0x09, 0xda, 0x62, 0x9c, 0x5d, 0xd6, 0x4d, 0x62, 0x0f, 0x9d, 0x20, + 0x77, 0xe5, 0xe8, 0xf4, 0x17, 0xb7, 0xde, 0x9a, 0xc9, 0xc5, 0x6d, 0xb1, 0x1b, 0xac, 0x8b, 0xaf, + 0xba, 0xac, 0xfc, 0xc3, 0xc5, 0x77, 0xa8, 0x42, 0x43, 0x3e, 0xde, 0x26, 0x11, 0x14, 0x78, 0x6d, + 0xd6, 0x15, 0xf8, 0xd8, 0x4d, 0xc8, 0x97, 0x19, 0x3e, 0x24, 0x6e, 0x09, 0xef, 0xf9, 0xb2, 0x8f, + 0x1d, 0x50, 0xcf, 0x42, 0xdc, 0x04, 0x71, 0x01, 0x21, 0x44, 0xcf, 0x8b, 0x5f, 0x8c, 0x30, 0xbb, + 0x8b, 0x97, 0x8e, 0x37, 0x62, 0x82, 0xa3, 0x50, 0xa4, 0xb9, 0x53, 0x24, 0x4b, 0x99, 0x64, 0x55, + 0x09, 0xb4, 0x2a, 0xae, 0x45, 0xa8, 0xe2, 0x44, 0xee, 0xac, 0x6c, 0x35, 0x8d, 0xb5, 0x35, 0xfc, + 0x41, 0x42, 0x79, 0x39, 0x8b, 0xac, 0x48, 0x24, 0x14, 0xd1, 0x79, 0x58, 0xd8, 0xf1, 0x22, 0x05, + 0x4b, 0x9f, 0x4d, 0xfc, 0x12, 0x84, 0x4b, 0xb8, 0xee, 0xef, 0xe3, 0xbf, 0x04, 0xf9, 0x69, 0xbb, + 0xfd, 0xf2, 0x11, 0x9d, 0x7e, 0x09, 0x45, 0x6a, 0x8b, 0x1b, 0x6c, 0xa0, 0xbb, 0xe2, 0x6f, 0x68, + 0x55, 0x17, 0x18, 0xf4, 0xf1, 0x00, 0x84, 0x2e, 0xdb, 0xbb, 0xe5, 0x0a, 0xf5, 0x72, 0xfa, 0xb5, + 0xf5, 0x70, 0x2b, 0xa2, 0x95, 0x2f, 0x12, 0xbd, 0x5c, 0x10, 0x0c, 0x0d, 0x1b, 0x92, 0x66, 0x0a, + 0x41, 0xdf, 0xfb, 0x92, 0xfa, 0xc7, 0x5e, 0xcb, 0xa2, 0x4d, 0xfd, 0xb6, 0x67, 0x33, 0x52, 0x2f, + 0xfc, 0x48, 0x50, 0x46, 0x48, 0x8c, 0x27, 0xd8, 0xed, 0xcd, 0x0a, 0x64, 0xc6, 0x36, 0x62, 0x34, + 0x2e, 0xa1, 0x03, 0xd4, 0x83, 0x81, 0x27, 0x8f, 0x04, 0x9d, 0x69, 0x25, 0xe0, 0xb7, 0x82, 0x00, + 0xa4, 0xfc, 0x8c, 0xc4, 0xe3, 0x25, 0xfa, 0x37, 0x27, 0xba, 0x18, 0x00, 0x02, 0x94, 0x91, 0xc6, + 0xfa, 0x37, 0x20, 0x16, 0x74, 0x7f, 0xf8, 0x40, 0x48, 0x23, 0x09, 0xee, 0xe3, 0xb7, 0xc1, 0x25, + 0x28, 0xae, 0x3b, 0x78, 0x80, 0x5a, 0x16, 0x1e, 0xa1, 0x7c, 0xed, 0xb0, 0x85, 0xe4, 0xeb, 0xc1, + 0x08, 0xb0, 0xc0, 0x6a, 0x53, 0x24, 0xcc, 0xef, 0x84, 0x3a, 0xad, 0x4f, 0x4d, 0xb9, 0xc8, 0x94, + 0xbf, 0x8b, 0xa0, 0x1c, 0x8f, 0xf1, 0x32, 0xde, 0x40, 0xc8, 0xf0, 0xd9, 0xf1, 0x82, 0xa6, 0x5d, + 0xcb, 0x64, 0x1a, 0x42, 0x7b, 0x55, 0x08, 0x10, 0x86, 0x84, 0x27, 0xe6, 0x0f, 0x1c, 0xfb, 0x5a, + 0x1e, 0xe1, 0x86, 0xba, 0x5f, 0xe0, 0xa4, 0x68, 0x76, 0x41, 0xde, 0x08, 0xe5, 0xd3, 0x37, 0x18, + 0x9b, 0x5f, 0xa4, 0x4c, 0xef, 0xa1, 0x79, 0x71, 0x30, 0x51, 0xc7, 0x7c, 0xb7, 0xde, 0x3b, 0xee, + 0xfa, 0x11, 0x17, 0xd6, 0xaf, 0xa3, 0xba, 0x12, 0xea, 0xe4, 0x57, 0x45, 0x3a, 0x5f, 0x53, 0xa4, + 0xd1, 0x30, 0x58, 0x21, 0x39, 0xca, 0x1a, 0xf1, 0x24, 0x61, 0x2f, 0xb1, 0xd4, 0x5a, 0x64, 0x46, + 0x34, 0x61, 0x56, 0xc2, 0x51, 0xfa, 0x35, 0xbf, 0xaf, 0x85, 0x05, 0x24, 0xae, 0x96, 0xfe, 0x99, + 0x44, 0x19, 0x27, 0xd6, 0x36, 0x1d, 0x50, 0x46, 0xe2, 0x0e, 0x74, 0x99, 0xdd, 0x2a, 0x51, 0x41, + 0x6e, 0x8c, 0x00, 0x30, 0xb6, 0x6f, 0x48, 0x7f, 0xc2, 0xef, 0x02, 0x65, 0x95, 0x45, 0x10, 0x75, + 0x47, 0xd3, 0x6e, 0x26, 0x14, 0x27, 0x58, 0x38, 0x32, 0x19, 0x63, 0x9a, 0x50, 0x42, 0x70, 0x67, + 0xa7, 0x46, 0xde, 0x65, 0x02, 0xaf, 0x42, 0xd3, 0x30, 0x83, 0xdd, 0x74, 0xca, 0x92, 0xba, 0xcd, + 0x85, 0xe7, 0x13, 0x19, 0xad, 0x6a, 0xaa, 0xa1, 0xfa, 0x72, 0x35, 0xc9, 0x02, 0xd5, 0x95, 0x22, + 0x27, 0xe4, 0xf1, 0x8f, 0x82, 0x2d, 0x34, 0xc3, 0x08, 0x3e, 0x71, 0xfe, 0x32, 0x0d, 0x6e, 0x37, + 0x24, 0xf0, 0x16, 0x68, 0xdc, 0xcc, 0x5e, 0xcb, 0xcf, 0xe4, 0xd7, 0x2f, 0x2d, 0xe2, 0x66, 0xc3, + 0xe4, 0xda, 0x04, 0xae, 0xa4, 0x1d, 0x7b, 0x13, 0x0a, 0x5d, 0x30, 0xad, 0x33, 0x40, 0xa6, 0x47, + 0x2c, 0x9b, 0x52, 0x43, 0x06, 0xfe, 0x87, 0x1e, 0xf3, 0x02, 0x16, 0xc6, 0x21, 0x03, 0xec, 0x83, + 0x84, 0x2d, 0x27, 0xd3, 0x0b, 0xe5, 0x7e, 0x24, 0x5f, 0xdf, 0x11, 0xd9, 0xac, 0xbe, 0x8d, 0xa0, + 0xfd, 0xa4, 0x10, 0xca, 0xb1, 0xe4, 0xbc, 0x48, 0x93, 0x5e, 0x9c, 0x4e, 0xe7, 0x7d, 0x13, 0x5f, + 0x74, 0x17, 0x71, 0x34, 0x7e, 0xfa, 0x3c, 0x5f, 0x5c, 0x27, 0xeb, 0xdf, 0x57, 0x85, 0xba, 0xc5, + 0x2f, 0x52, 0x25, 0xf0, 0x48, 0x42, 0x4a, 0xfc, 0x38, 0x88, 0x50, 0x64, 0xcc, 0x19, 0x72, 0xb9, + 0x42, 0xaa, 0x65, 0x84, 0x12, 0x56, 0x8b, 0x5d, 0x05, 0x60, 0xd9, 0xa2, 0x08, 0x6b, 0x64, 0x8a, + 0x3e, 0xa7, 0x53, 0x30, 0x9a, 0x21, 0x3e, 0x7c, 0x28, 0x4d, 0x9b, 0xe8, 0x5b, 0xf1, 0x38, 0x0a, + 0x53, 0xb3, 0xc2, 0x7a, 0x0d, 0x09, 0x37, 0x73, 0x89, 0x10, 0x3f, 0x95, 0xa3, 0x51, 0x01, 0x62, + 0xa4, 0xb5, 0x8c, 0x40, 0xb5, 0x9c, 0xea, 0xbf, 0x10, 0x0a, 0x4a, 0x55, 0xfe, 0x6f, 0xca, 0x29, + 0x09, 0xec, 0xc0, 0x1a, 0xb4, 0x29, 0xd9, 0x33, 0xb0, 0x70, 0x0d, 0xde, 0x20, 0x67, 0xbd, 0xbe, + 0x3d, 0x38, 0xb1, 0x9d, 0x50, 0xf3, 0xed, 0x8b, 0x98, 0x86, 0x9f, 0x0a, 0x72, 0x63, 0xa9, 0xc8, + 0x38, 0x55, 0xa3, 0xe2, 0x09, 0x55, 0x7b, 0x05, 0x20, 0xbf, 0x0d, 0x93, 0xbc, 0x30, 0x1a, 0x6e, + 0xf8, 0x40, 0xcf, 0xc2, 0xb1, 0xf1, 0x8c, 0xaa, 0x5a, 0x84, 0x73, 0x81, 0x67, 0x26, 0xd0, 0xb7, + 0xe2, 0x23, 0xa8, 0xc5, 0x62, 0x15, 0x0a, 0xcd, 0x73, 0xd4, 0xb4, 0x65, 0x4e, 0x95, 0xd7, 0x34, + 0x94, 0x68, 0x36, 0x96, 0x0f, 0xf0, 0x4c, 0x13, 0x22, 0x66, 0x6d, 0xf5, 0xa1, 0x8e, 0x87, 0x1a, + 0x3c, 0x91, 0x7e, 0x6a, 0x2b, 0xa1, 0x3a, 0x93, 0xa2, 0x54, 0xbd, 0x13, 0x50, 0x9f, 0x5e, 0x9f, + 0x82, 0xc1, 0xcd, 0xb0, 0x21, 0x81, 0x70, 0x3d, 0x27, 0xae, 0x4c, 0x9c, 0xb1, 0x45, 0x13, 0xf1, + 0x22, 0x02, 0x96, 0x8c, 0x3d, 0x57, 0x54, 0xdd, 0x48, 0x71, 0x62, 0x01, 0xc4, 0x0c, 0x5a, 0x59, + 0xfb, 0xe3, 0x04, 0xa1, 0xcf, 0x26, 0x83, 0xd2, 0x30, 0xd2, 0x2b, 0x3a, 0x55, 0x34, 0x62, 0x3d, + 0xe0, 0x6d, 0x59, 0xf0, 0x62, 0xe0, 0x8f, 0xf3, 0x97, 0x5a, 0xb6, 0x58, 0x81, 0x23, 0x0c, 0xe3, + 0x68, 0x4c, 0x50, 0x4f, 0x50, 0xf6, 0xec, 0x46, 0xd6, 0x6a, 0xb3, 0x34, 0xea, 0x4b, 0xdd, 0x17, + 0xc7, 0x49, 0xf9, 0x36, 0x4c, 0x91, 0x7a, 0x8e, 0x9c, 0x3c, 0x44, 0x61, 0x64, 0xaa, 0x86, 0x84, + 0x0b, 0xa5, 0x55, 0xdb, 0xac, 0x74, 0x94, 0x09, 0x59, 0x01, 0x82, 0xeb, 0xc4, 0xc6, 0x5b, 0x25, + 0xbd, 0xdb, 0x72, 0x06, 0x03, 0xc9, 0xa7, 0xfa, 0xaf, 0x08, 0x02, 0xa1, 0x1a, 0xcc, 0x63, 0x0a, + 0xa6, 0x45, 0xef, 0xd2, 0x76, 0xec, 0x1f, 0x12, 0x7f, 0x10, 0x50, 0x99, 0x41, 0x00, 0xc0, 0x9d, + 0x9c, 0x63, 0x32, 0x74, 0xd7, 0x5e, 0xf8, 0x21, 0xe4, 0xf3, 0xd1, 0x3d, 0x5c, 0x9f, 0xad, 0x57, + 0x56, 0xfa, 0xb1, 0x1b, 0xd5, 0x88, 0xbc, 0x40, 0x50, 0x28, 0x34, 0xa6, 0xa9, 0x34, 0x56, 0x4a, + 0x68, 0x6a, 0x8a, 0x36, 0x23, 0x54, 0x2b, 0xad, 0xa0, 0xc0, 0x30, 0x56, 0x6e, 0x45, 0xcb, 0x49, + 0x19, 0x7b, 0xf1, 0x90, 0xf3, 0x6f, 0x4c, 0x86, 0x7c, 0x3f, 0xc6, 0x16, 0x0d, 0xfe, 0xcd, 0xbd, + 0x4c, 0x4f, 0x27, 0x13, 0xc2, 0xe4, 0xc6, 0x28, 0x88, 0x20, 0x60, 0xab, 0x0a, 0xc2, 0x59, 0xc7, + 0xa6, 0x1f, 0xff, 0xaa, 0x3f, 0xa8, 0x78, 0x39, 0x3f, 0x32, 0xc3, 0x38, 0x7e, 0xd0, 0xc4, 0xb8, + 0x0e, 0x55, 0x00, 0x79, 0x0f, 0x6e, 0x16, 0x1b, 0x50, 0x98, 0x88, 0x2b, 0xdf, 0xc7, 0x94, 0x0f, + 0xa4, 0xa3, 0xfe, 0xbc, 0xe0, 0x40, 0x30, 0xef, 0x80, 0x5a, 0x60, 0x18, 0x45, 0xc7, 0x36, 0x71, + 0xca, 0x37, 0xe2, 0x63, 0xb8, 0x39, 0xd4, 0x69, 0xcb, 0xdd, 0x78, 0x20, 0x80, 0x8b, 0xea, 0xfe, + 0x2a, 0x2c, 0x35, 0xe6, 0x20, 0x48, 0xc2, 0xbe, 0x9e, 0xf9, 0x51, 0x86, 0xfb, 0xc4, 0x19, 0x9b, + 0xbc, 0x70, 0xdb, 0x7c, 0x84, 0x11, 0xa7, 0x78, 0x09, 0x27, 0x1a, 0x12, 0x59, 0xc4, 0x05, 0x24, + 0x61, 0xdd, 0x89, 0x22, 0x7a, 0x41, 0xa2, 0x74, 0x0c, 0x52, 0xa6, 0x52, 0x24, 0x94, 0x4e, 0xdc, + 0xd6, 0xc2, 0xc2, 0xb3, 0xbd, 0xc9, 0xf1, 0xdf, 0xdf, 0x08, 0x67, 0x8d, 0x8c, 0x68, 0x00, 0x4b, + 0xa1, 0x04, 0xe0, 0xca, 0x5a, 0x42, 0xfe, 0x32, 0xa9, 0xac, 0x40, 0xb0, 0x64, 0xa0, 0x34, 0xdd, + 0xc6, 0xaa, 0x39, 0x4d, 0x8e, 0xb2, 0xf9, 0xf1, 0x3c, 0xc9, 0x88, 0xd7, 0xdd, 0x59, 0xca, 0x45, + 0x83, 0x35, 0xa1, 0xf9, 0xc2, 0xeb, 0x34, 0x26, 0x87, 0x97, 0xa1, 0x07, 0x4b, 0xea, 0xe0, 0x27, + 0xd5, 0x22, 0x5d, 0x5f, 0xea, 0x95, 0x3e, 0xad, 0x15, 0xd7, 0x5f, 0x05, 0xd7, 0xbe, 0x38, 0x75, + 0x0c, 0xee, 0xa9, 0x52, 0x7c, 0x60, 0x42, 0x42, 0x31, 0xc1, 0x86, 0xb2, 0x21, 0x42, 0xa6, 0xac, + 0xb5, 0xad, 0xcb, 0xea, 0xcc, 0xe3, 0x5a, 0x10, 0xaf, 0x03, 0xf1, 0xa4, 0x43, 0xfa, 0x42, 0xb7, + 0x71, 0x21, 0x47, 0x68, 0xc0, 0xfd, 0x35, 0x03, 0x31, 0x2b, 0x27, 0x84, 0x3f, 0xd0, 0x85, 0xef, + 0x05, 0x18, 0x9e, 0x76, 0xb1, 0xf8, 0xd1, 0xbc, 0x63, 0xf2, 0xc5, 0xa5, 0x51, 0xa5, 0xa6, 0xdd, + 0x02, 0xc7, 0xc0, 0x03, 0x41, 0x5d, 0xf0, 0xd2, 0x56, 0x66, 0x40, 0x0b, 0xd4, 0x9f, 0x31, 0xd7, + 0x8a, 0xf7, 0x79, 0x9e, 0xfb, 0x22, 0xad, 0x7f, 0x0a, 0x45, 0xc4, 0x09, 0x1b, 0x62, 0x6c, 0x23, + 0x2a, 0x68, 0x38, 0x58, 0x9c, 0x40, 0xd1, 0xce, 0xe3, 0x5c, 0xb1, 0x22, 0xea, 0x31, 0x82, 0x1d, + 0xaa, 0x8c, 0x7b, 0x71, 0xb7, 0x1d, 0x67, 0x88, 0xe8, 0xb7, 0x02, 0x7a, 0x95, 0x41, 0x9e, 0x04, + 0xf3, 0x0a, 0x14, 0xb7, 0xae, 0x7f, 0xf7, 0x89, 0x0a, 0x1d, 0xea, 0x8f, 0x60, 0x80, 0xd2, 0x43, + 0x71, 0x9b, 0x58, 0xa9, 0xa1, 0xb1, 0x02, 0xb7, 0xce, 0x41, 0x34, 0xb5, 0xc4, 0x88, 0x0a, 0x13, + 0x00, 0x5b, 0x73, 0x85, 0x6c, 0xbc, 0x10, 0x49, 0xe0, 0x68, 0x8d, 0xa8, 0x11, 0xaa, 0xb8, 0x9c, + 0x0b, 0x73, 0x5f, 0xff, 0xd0, 0xcd, 0x21, 0x2a, 0x88, 0x89, 0xaa, 0x27, 0x59, 0x8b, 0xd0, 0xa4, + 0x0f, 0x8e, 0x1e, 0xa3, 0x7a, 0x36, 0xda, 0x78, 0x9f, 0x2e, 0xfc, 0xcc, 0xe0, 0x10, 0x2f, 0xf8, + 0xfd, 0x21, 0x3a, 0x0f, 0x7f, 0xeb, 0xf1, 0x22, 0x46, 0x95, 0xc7, 0xb1, 0xbc, 0x91, 0x99, 0x17, + 0xb3, 0xd2, 0xab, 0xa6, 0x6c, 0xa7, 0x83, 0x89, 0xfd, 0xc5, 0x0c, 0xd7, 0x2e, 0x10, 0x4b, 0x89, + 0xcc, 0x9d, 0x64, 0xd0, 0x00, 0xb7, 0x32, 0x5b, 0xb1, 0x03, 0x05, 0x80, 0x09, 0x67, 0x2c, 0x5c, + 0x2f, 0xff, 0x17, 0xf1, 0x21, 0x43, 0xf0, 0x16, 0x35, 0x8d, 0x29, 0x0d, 0x31, 0x1c, 0x0a, 0xfd, + 0x78, 0x81, 0x80, 0x7e, 0xcd, 0x63, 0x2f, 0x65, 0xf8, 0xab, 0xa5, 0xbe, 0x14, 0xc5, 0x33, 0x06, + 0x83, 0xad, 0x06, 0xdf, 0x55, 0x8b, 0xcb, 0xbf, 0xf1, 0x23, 0x05, 0x15, 0x41, 0x48, 0xd3, 0x11, + 0xa1, 0x04, 0x49, 0x9d, 0x6d, 0xde, 0x48, 0x28, 0x2a, 0xea, 0x16, 0x75, 0x3e, 0xaf, 0x82, 0x30, + 0xaf, 0x26, 0x64, 0x58, 0xe3, 0xf0, 0x1d, 0x49, 0xf0, 0x43, 0x90, 0xd6, 0x42, 0xec, 0x85, 0xfc, + 0x57, 0x45, 0x4b, 0x0f, 0xf4, 0x3d, 0xcf, 0x82, 0x70, 0x87, 0x37, 0x83, 0x59, 0x61, 0xdb, 0x8e, + 0xff, 0x88, 0x0a, 0x0a, 0x15, 0x8a, 0xec, 0x51, 0xa7, 0x11, 0xc4, 0x49, 0x2c, 0xd7, 0x25, 0x54, + 0x8c, 0xeb, 0x15, 0x0a, 0x78, 0x94, 0x9b, 0x5b, 0x47, 0x4a, 0x4a, 0xbc, 0x14, 0xe0, 0x8a, 0xc5, + 0x53, 0x86, 0x28, 0xc6, 0xc2, 0xf5, 0x88, 0x25, 0x94, 0x61, 0xbc, 0xff, 0x04, 0x04, 0x31, 0xc3, + 0x49, 0x15, 0xe4, 0x07, 0x67, 0x29, 0xca, 0xe2, 0xb8, 0x86, 0x33, 0x50, 0x1b, 0xe0, 0x34, 0xcc, + 0x07, 0x51, 0xaa, 0xcc, 0xdb, 0x32, 0xe5, 0xfe, 0xf8, 0x3e, 0x2d, 0x5f, 0xa3, 0x27, 0xe2, 0x42, + 0x82, 0x3a, 0xa3, 0x66, 0xc7, 0xdd, 0xfb, 0xdb, 0xcc, 0x6a, 0x5b, 0x82, 0xdd, 0xf4, 0x31, 0xd7, + 0x1c, 0x40, 0x40, 0x4e, 0x78, 0x2d, 0xae, 0x3a, 0xe6, 0x63, 0x89, 0x0a, 0x61, 0xc2, 0x23, 0x0c, + 0x64, 0xd1, 0xa0, 0x3a, 0xce, 0xfd, 0x0d, 0xdb, 0x4e, 0xee, 0x01, 0x94, 0xc7, 0x11, 0xa8, 0x43, + 0x17, 0x9a, 0xbd, 0xa7, 0xff, 0xa6, 0xd4, 0x58, 0xa8, 0x96, 0xca, 0x3c, 0x8e, 0x33, 0xcf, 0xc4, + 0x42, 0x84, 0x7d, 0xad, 0x59, 0xff, 0xc5, 0x10, 0xa5, 0xd1, 0x2d, 0xf9, 0x0c, 0xbf, 0xfd, 0x4c, + 0xfb, 0x0f, 0x39, 0xd1, 0x89, 0x48, 0x2b, 0xe4, 0xc6, 0x64, 0x49, 0xa2, 0xde, 0x62, 0x2e, 0xd5, + 0xc1, 0xc9, 0xaf, 0xce, 0xbc, 0x13, 0x1e, 0x89, 0xfd, 0x50, 0xf8, 0xd2, 0x95, 0xca, 0xaf, 0x10, + 0x0a, 0xcb, 0x61, 0xc9, 0xd0, 0x27, 0x91, 0x6d, 0xd9, 0x60, 0xcd, 0x95, 0x45, 0xf0, 0x58, 0x28, + 0x7d, 0x15, 0x2e, 0xbc, 0xb4, 0x36, 0x1a, 0xaa, 0xa6, 0xc6, 0xc3, 0x8a, 0x66, 0x5f, 0x05, 0x84, + 0xbd, 0xc9, 0x1c, 0x48, 0x86, 0xe4, 0xb6, 0xd3, 0xcc, 0x3c, 0x11, 0x84, 0xd2, 0x43, 0x1e, 0x64, + 0xc6, 0x52, 0xaf, 0x38, 0x55, 0x12, 0xff, 0x15, 0x28, 0xa9, 0x05, 0x3a, 0x0c, 0x57, 0xd7, 0x28, + 0x8e, 0xaf, 0x17, 0xc1, 0x27, 0x61, 0x0d, 0xd6, 0xc3, 0xc1, 0x61, 0x0e, 0x41, 0xb7, 0x09, 0x1c, + 0xa3, 0x3c, 0x76, 0x31, 0xad, 0x3a, 0x02, 0x26, 0xac, 0xdf, 0x0a, 0x58, 0x10, 0x06, 0x17, 0x89, + 0xf6, 0x79, 0x5d, 0xe9, 0x36, 0x30, 0x60, 0xc2, 0xa4, 0xec, 0x32, 0xe1, 0xca, 0xa0, 0x65, 0xac, + 0x25, 0x11, 0x39, 0xe2, 0x42, 0x84, 0xe9, 0xbb, 0x8d, 0xf9, 0xd7, 0x51, 0xda, 0x7b, 0xf2, 0xd3, + 0x27, 0x23, 0x40, 0x3c, 0xff, 0x4f, 0x01, 0x34, 0xfe, 0x20, 0x69, 0xba, 0xb3, 0x19, 0x90, 0xda, + 0xfc, 0xb7, 0x51, 0x0f, 0xef, 0x33, 0x8f, 0xad, 0x0d, 0xac, 0xba, 0xba, 0x44, 0x0b, 0x02, 0xdf, + 0x63, 0x3f, 0x00, 0x88, 0xa0, 0x8e, 0xe1, 0x24, 0xd1, 0xff, 0xc5, 0x5d, 0x3f, 0x0a, 0x4d, 0xe5, + 0x55, 0x88, 0x0f, 0x2e, 0x0f, 0x5c, 0x6b, 0x01, 0x86, 0xf6, 0x46, 0x69, 0x77, 0x42, 0x66, 0x3f, + 0xfc, 0xe6, 0x69, 0xd9, 0x2a, 0x93, 0xa7, 0xa9, 0xda, 0x6c, 0xfe, 0xef, 0x80, 0x9f, 0x0a, 0x0b, + 0xd4, 0x63, 0x99, 0xea, 0xd8, 0xbc, 0xfa, 0x69, 0xbb, 0xac, 0xf5, 0x2b, 0x25, 0x63, 0x5f, 0x78, + 0x80, 0x57, 0x40, 0xda, 0xcd, 0x0e, 0x2b, 0xb5, 0x79, 0xa3, 0xde, 0x20, 0x14, 0x9d, 0xb7, 0x10, + 0xab, 0xb0, 0xb8, 0x13, 0x7a, 0x91, 0xe2, 0x41, 0xec, 0x28, 0xd5, 0x12, 0x41, 0x07, 0x01, 0x58, + 0xe6, 0x75, 0xe3, 0x2a, 0x42, 0x23, 0x22, 0x1f, 0x9a, 0xa8, 0xde, 0xc6, 0xec, 0x51, 0x9a, 0x51, + 0x58, 0xac, 0x56, 0xf8, 0x91, 0x21, 0x4c, 0x5d, 0x59, 0x1d, 0xc6, 0x7d, 0x4f, 0xe8, 0xef, 0x97, + 0xb6, 0xcf, 0x85, 0x3a, 0x4e, 0xe3, 0x5a, 0x65, 0x4b, 0xd7, 0x20, 0x5d, 0x6c, 0xcb, 0xf7, 0x88, + 0x0a, 0x0c, 0x8c, 0x24, 0x67, 0x5f, 0xec, 0xf7, 0x68, 0x21, 0x00, 0x21, 0x52, 0x26, 0x64, 0x47, + 0x2b, 0x54, 0x10, 0x9c, 0x15, 0xa2, 0x1d, 0x3e, 0x0a, 0xc9, 0xb9, 0x2d, 0xf0, 0x6e, 0x8c, 0x32, + 0xa6, 0xb8, 0x5c, 0x37, 0x5b, 0xa0, 0x4c, 0x3c, 0x13, 0x05, 0x78, 0xbd, 0xdd, 0x41, 0x48, 0x67, + 0xe8, 0xbd, 0x86, 0xd1, 0x7f, 0xe7, 0x85, 0xff, 0xd3, 0x69, 0xb4, 0xf0, 0xfc, 0x27, 0xd0, 0xcc, + 0xa1, 0x18, 0x98, 0xa3, 0x52, 0x72, 0xe3, 0xdf, 0xe0, 0x92, 0xc1, 0xa8, 0xee, 0x19, 0xb9, 0x7c, + 0x3f, 0x2d, 0x09, 0xb6, 0x9a, 0xa1, 0x60, 0x0a, 0x22, 0x03, 0xf5, 0x67, 0xb7, 0x08, 0x40, 0x8a, + 0xf3, 0x3d, 0xf8, 0xb7, 0x2d, 0x7c, 0x29, 0x08, 0x9c, 0x1e, 0x10, 0xf5, 0x99, 0x3c, 0x72, 0xa7, + 0x6f, 0xe1, 0x90, 0x63, 0x3a, 0x98, 0x3f, 0xc5, 0x14, 0x7d, 0x69, 0xfe, 0xb2, 0xdb, 0x23, 0xca, + 0xef, 0x22, 0x96, 0x65, 0xe1, 0x1b, 0xf0, 0x99, 0x48, 0x6a, 0xa6, 0x45, 0xdd, 0x70, 0x92, 0x48, + 0x1a, 0xd9, 0xd2, 0xf1, 0xe4, 0x69, 0x18, 0x6d, 0x22, 0xea, 0x51, 0xd6, 0xd5, 0xab, 0xb8, 0xfd, + 0xe8, 0x2f, 0x1e, 0x69, 0x17, 0x1c, 0xc3, 0x29, 0xb8, 0x6a, 0x2e, 0x8c, 0x2b, 0x18, 0x88, 0x35, + 0xa2, 0x17, 0x89, 0x18, 0x5c, 0xb4, 0xae, 0xae, 0xc4, 0x75, 0x19, 0x52, 0xc2, 0xe8, 0xfc, 0xad, + 0x2b, 0xaf, 0x38, 0x38, 0xed, 0x3f, 0x4d, 0xa3, 0x02, 0xff, 0xe1, 0x11, 0x79, 0x95, 0x94, 0xc8, + 0xb8, 0x99, 0x04, 0x5d, 0x9d, 0x94, 0x85, 0x41, 0x1f, 0x3c, 0x61, 0x28, 0xce, 0x45, 0x7b, 0xe9, + 0xed, 0xf9, 0x6d, 0x21, 0x81, 0x5f, 0x7b, 0xf1, 0x21, 0x43, 0x92, 0xa3, 0x10, 0xf4, 0x60, 0xa9, + 0x26, 0x0b, 0x61, 0xb1, 0x91, 0x49, 0x70, 0xbf, 0x96, 0xdc, 0xa3, 0x82, 0x6a, 0x2b, 0x69, 0xaf, + 0xf1, 0x10, 0x56, 0x5b, 0x21, 0x41, 0x5a, 0x11, 0x58, 0xf9, 0xd4, 0x45, 0x62, 0xb1, 0x5c, 0xcc, + 0xe1, 0xe1, 0x4c, 0x7f, 0x4a, 0xea, 0xac, 0x3e, 0xc3, 0x9a, 0xb1, 0x59, 0xcd, 0x0b, 0xd7, 0xa4, + 0x0a, 0x6f, 0xbc, 0x9f, 0xb1, 0x58, 0xf8, 0x50, 0x95, 0x16, 0xf4, 0xd0, 0x71, 0x9a, 0x9e, 0xf6, + 0xae, 0x5e, 0xde, 0x20, 0x11, 0x08, 0x1a, 0x68, 0x70, 0x96, 0xc2, 0x7f, 0x8c, 0xa4, 0x69, 0x97, + 0xa9, 0x33, 0x4c, 0x95, 0xe5, 0x48, 0xa4, 0xe6, 0x5b, 0x61, 0xa3, 0x47, 0x75, 0x56, 0xfc, 0x7e, + 0xcd, 0xf8, 0x40, 0x45, 0x4c, 0x91, 0xb4, 0xa9, 0x56, 0x20, 0xad, 0x98, 0xc5, 0x63, 0x48, 0x51, + 0xdf, 0x94, 0x4c, 0xa8, 0x40, 0xce, 0xca, 0xf5, 0xc3, 0x1d, 0x17, 0x55, 0xd1, 0xd2, 0x2f, 0x45, + 0x48, 0x97, 0x44, 0x82, 0xfa, 0x23, 0x49, 0xd1, 0x59, 0xf0, 0x58, 0x22, 0x38, 0x99, 0xe9, 0xb6, + 0xac, 0xd1, 0xa1, 0x10, 0x82, 0xae, 0xbe, 0xf8, 0xd3, 0x44, 0x81, 0xa0, 0x6f, 0x6f, 0xb4, 0x3c, + 0xc8, 0xbb, 0x93, 0x4e, 0x91, 0xf8, 0xc0, 0xba, 0x54, 0x86, 0xd6, 0x5f, 0xf8, 0x52, 0xc2, 0x0c, + 0x14, 0xa8, 0x96, 0x12, 0x09, 0xf6, 0x1d, 0x43, 0x3c, 0x4d, 0x03, 0x0d, 0x72, 0x7f, 0x8e, 0xdd, + 0x84, 0x15, 0xc9, 0x18, 0x6e, 0x79, 0x7b, 0xe2, 0x4a, 0xed, 0x41, 0xd9, 0x48, 0x4f, 0xae, 0xef, + 0xe0, 0xb6, 0xd1, 0x0b, 0xb1, 0xfb, 0x4c, 0x92, 0x3d, 0xe2, 0x01, 0x4c, 0xb7, 0x1a, 0x71, 0xad, + 0x3d, 0x13, 0x6d, 0x80, 0xa8, 0x0b, 0x1a, 0x52, 0xb0, 0xe5, 0xce, 0x9f, 0x0a, 0x08, 0x86, 0x12, + 0x0e, 0x32, 0x37, 0xed, 0x7a, 0x45, 0x98, 0xc2, 0xd7, 0x00, 0x8c, 0x36, 0x00, 0x02, 0x8a, 0x0d, + 0x9a, 0x32, 0x6b, 0x34, 0x6f, 0xeb, 0xef, 0xf8, 0x91, 0x87, 0x6e, 0x7c, 0x8c, 0xc7, 0x38, 0x15, + 0xb4, 0x35, 0x07, 0xea, 0xe6, 0x04, 0x2f, 0xde, 0x13, 0x48, 0xfb, 0x49, 0xc0, 0xb1, 0x1f, 0x51, + 0xb2, 0xbe, 0x0f, 0xbe, 0x2a, 0xe8, 0xf8, 0x2b, 0x12, 0x4a, 0xb6, 0xa2, 0xdd, 0x69, 0xe2, 0xaa, + 0x1f, 0xdf, 0x05, 0xd5, 0x46, 0xad, 0x5d, 0xef, 0xe2, 0x01, 0x4d, 0xed, 0x10, 0x84, 0x81, 0x0d, + 0x2d, 0xdb, 0xdb, 0xf7, 0xc5, 0xe4, 0x20, 0xa4, 0xf4, 0xd7, 0x13, 0xf8, 0xf2, 0xcb, 0x62, 0xb7, + 0xa0, 0xcc, 0x20, 0x2f, 0x22, 0xbb, 0xfc, 0x13, 0xf2, 0x45, 0xdf, 0x2b, 0x27, 0xff, 0x0a, 0x6a, + 0x46, 0x32, 0x74, 0x59, 0xc6, 0x08, 0x86, 0x16, 0xf6, 0x0b, 0x44, 0x3b, 0xb3, 0xe0, 0xa0, 0x8d, + 0x3d, 0x37, 0xbd, 0xfe, 0x30, 0x8b, 0x55, 0x1b, 0xac, 0xf7, 0x55, 0xae, 0x6c, 0x0a, 0xd7, 0xc2, + 0x82, 0xb0, 0x97, 0x15, 0x48, 0xd9, 0x87, 0x9a, 0x49, 0x1e, 0xd2, 0xcf, 0xcb, 0xf2, 0xf8, 0x2b, + 0xe6, 0x8e, 0x4d, 0xcb, 0x8e, 0x52, 0x5d, 0x7c, 0x58, 0x93, 0x20, 0x9b, 0x4c, 0xcf, 0x1d, 0x00, + 0x09, 0xe1, 0x81, 0x2f, 0x55, 0x74, 0xe7, 0x38, 0xd2, 0x3c, 0xb8, 0xab, 0x3d, 0x7c, 0xdc, 0xc2, + 0x16, 0xb3, 0x74, 0x76, 0x2b, 0xa3, 0x4a, 0x4e, 0x63, 0xb4, 0xd2, 0x53, 0xf5, 0xe9, 0xfa, 0x29, + 0x93, 0xe0, 0xa0, 0x44, 0xcc, 0x49, 0x98, 0xdf, 0xf3, 0x17, 0xc6, 0x99, 0x22, 0x10, 0x5a, 0xa0, + 0xd4, 0xe9, 0xfb, 0x8c, 0x2e, 0x21, 0x51, 0x7f, 0xcc, 0x9d, 0x3a, 0xff, 0xc1, 0x5f, 0x43, 0x36, + 0x34, 0xc1, 0x87, 0x8d, 0xa1, 0xa2, 0x5a, 0x61, 0xfc, 0x40, 0x52, 0x40, 0xc0, 0x5f, 0x42, 0x4a, + 0xf9, 0xbc, 0x25, 0x71, 0x07, 0x17, 0xc9, 0x06, 0x99, 0xf1, 0x87, 0x10, 0xb1, 0x05, 0x06, 0x5a, + 0x3a, 0x9e, 0x3e, 0xa4, 0x45, 0xaa, 0xae, 0xa3, 0x3c, 0xfc, 0x40, 0x53, 0x2e, 0x1a, 0x94, 0xcb, + 0x9a, 0x6c, 0xb6, 0x23, 0x63, 0xb2, 0x54, 0x82, 0x6a, 0x23, 0xff, 0xc1, 0x50, 0x86, 0x9c, 0xba, + 0xec, 0x61, 0x26, 0x29, 0xbc, 0xb0, 0xaa, 0xf7, 0xf0, 0x55, 0x3c, 0x30, 0x9f, 0xcc, 0x44, 0xf9, + 0x06, 0x5f, 0x1b, 0xd7, 0x93, 0x88, 0x00, 0x16, 0x84, 0xd7, 0xe4, 0x4c, 0x0b, 0x1b, 0xe0, 0x89, + 0x0a, 0x26, 0xc1, 0xca, 0x76, 0xf7, 0x1c, 0x46, 0xf4, 0xae, 0xa6, 0xbe, 0x4c, 0x25, 0x53, 0x7d, + 0xf8, 0xde, 0xb8, 0xa9, 0x8b, 0x46, 0x0c, 0x7b, 0xc4, 0x52, 0x89, 0x84, 0xce, 0x55, 0xb3, 0x78, + 0x1c, 0xf3, 0xdc, 0x40, 0xec, 0xb6, 0x94, 0x69, 0x31, 0xaf, 0x8e, 0x5f, 0x37, 0xc7, 0xf1, 0x9e, + 0x8d, 0xaf, 0x37, 0x96, 0x9c, 0xa6, 0xfa, 0x4d, 0x81, 0x2f, 0x3d, 0x6a, 0xe2, 0x04, 0x88, 0x1a, + 0x56, 0x1c, 0x77, 0xfc, 0x95, 0x5f, 0x88, 0x05, 0x94, 0xa9, 0x5d, 0xdd, 0xd9, 0xcb, 0x4b, 0x71, + 0x02, 0x02, 0x37, 0x7a, 0x6e, 0xe7, 0xf8, 0xfe, 0xe2, 0xcf, 0x9c, 0x40, 0x52, 0x25, 0xc3, 0xb0, + 0xff, 0x71, 0xc3, 0x92, 0x0f, 0x93, 0xa3, 0x04, 0xe7, 0x28, 0x67, 0xa1, 0x00, 0x6d, 0xd3, 0x8c, + 0x6e, 0xa6, 0xe2, 0x44, 0x82, 0x8a, 0x24, 0x37, 0xbe, 0xef, 0xf0, 0x59, 0xdd, 0xc5, 0x62, 0xb1, + 0x58, 0xad, 0xe7, 0xc9, 0xff, 0xc2, 0x25, 0x7a, 0x7a, 0xa2, 0x2a, 0x35, 0xc9, 0x01, 0x00, 0x71, + 0x11, 0xc5, 0xac, 0xcc, 0xfb, 0xa1, 0xe4, 0xc5, 0xf0, 0x56, 0x69, 0x9b, 0x1a, 0x55, 0xd6, 0x34, + 0x70, 0x8b, 0x63, 0xe2, 0xdf, 0x82, 0x12, 0x48, 0x42, 0x72, 0x19, 0x9c, 0xf8, 0x54, 0x51, 0xfd, + 0xdc, 0x3a, 0x3d, 0x69, 0x08, 0x93, 0x44, 0x04, 0x8b, 0xf0, 0x70, 0xfb, 0x62, 0xaf, 0xf0, 0xff, + 0xeb, 0x4c, 0x9a, 0xc3, 0x5f, 0x93, 0x8d, 0x88, 0x13, 0x4d, 0x41, 0x0f, 0x20, 0x80, 0xec, 0x5b, + 0x2e, 0xff, 0xf0, 0xa0, 0x9c, 0x3c, 0xd2, 0x7c, 0x9c, 0xb9, 0x07, 0x70, 0x69, 0x73, 0x61, 0x4d, + 0x49, 0x3d, 0x5d, 0x54, 0x18, 0x69, 0xbb, 0x78, 0x0e, 0x89, 0x3b, 0xf0, 0x4d, 0x49, 0x2d, 0xa8, + 0xae, 0xf3, 0xc9, 0x0a, 0x75, 0x6f, 0xac, 0x69, 0x3a, 0xfe, 0xfa, 0xf5, 0x70, 0xbe, 0x78, 0x74, + 0xd2, 0xbf, 0x8f, 0x7f, 0xfc, 0x69, 0x16, 0x9a, 0x61, 0x66, 0x21, 0xa1, 0xa5, 0xa1, 0xcc, 0x35, + 0x8e, 0x7f, 0x1b, 0x36, 0x4b, 0xfc, 0xf6, 0xb1, 0xb7, 0xfe, 0x3b, 0xe5, 0xc6, 0x62, 0xba, 0xf2, + 0xa4, 0x65, 0xf8, 0x52, 0xb5, 0xa5, 0x23, 0x5e, 0xa4, 0xb4, 0x92, 0x78, 0x60, 0x61, 0x46, 0x1b, + 0x61, 0x29, 0x71, 0x02, 0x06, 0x54, 0x89, 0xa5, 0x60, 0x30, 0x6d, 0x7f, 0x39, 0x46, 0xa0, 0x83, + 0x23, 0xb4, 0x3d, 0xd7, 0x9e, 0x3b, 0xf9, 0x59, 0x5f, 0x05, 0x22, 0x46, 0xdb, 0x7c, 0xfd, 0xb9, + 0x7e, 0x50, 0xc0, 0x65, 0x1b, 0x3d, 0xc4, 0x88, 0x04, 0xe2, 0x13, 0x10, 0xf9, 0x71, 0x2b, 0x1b, + 0x68, 0xdf, 0xe1, 0x49, 0x43, 0x02, 0xc5, 0x41, 0x15, 0x09, 0x7a, 0x64, 0xee, 0x0e, 0x98, 0xa1, + 0xe5, 0x8d, 0x1c, 0x68, 0x34, 0xdd, 0xfb, 0x28, 0xb8, 0xa0, 0xa7, 0xca, 0x31, 0x24, 0xb0, 0xf5, + 0x87, 0x9f, 0x18, 0x5c, 0xa4, 0x18, 0x38, 0x12, 0x6c, 0x29, 0xb0, 0x82, 0x31, 0x52, 0x82, 0xe6, + 0x0a, 0x8c, 0x76, 0x95, 0xcd, 0x86, 0xcd, 0x1e, 0x09, 0x88, 0xe4, 0x48, 0xc8, 0xde, 0xc1, 0xba, + 0x14, 0xfb, 0xe0, 0x97, 0xad, 0x33, 0x75, 0x97, 0xa6, 0xc7, 0x89, 0x0a, 0x0b, 0x3a, 0xe8, 0x6b, + 0x51, 0x60, 0x26, 0x0e, 0xd8, 0xfb, 0x81, 0x58, 0x40, 0xb4, 0x66, 0xfa, 0xd2, 0x8c, 0x8a, 0x11, + 0x53, 0x8c, 0xfa, 0x83, 0xa2, 0x8f, 0x85, 0x08, 0x5d, 0x9a, 0xed, 0xed, 0x88, 0xf3, 0x7f, 0xb1, + 0x9b, 0x62, 0x4b, 0x0b, 0x92, 0x7e, 0x12, 0x6c, 0x71, 0x10, 0x57, 0xad, 0x59, 0x92, 0xe9, 0xb4, + 0x81, 0xbc, 0xa4, 0x11, 0x97, 0xd3, 0x78, 0x90, 0xa1, 0x46, 0xe8, 0x95, 0x00, 0x70, 0x73, 0x85, + 0x8e, 0xc2, 0x8e, 0x7c, 0x8d, 0x15, 0xbb, 0x6d, 0x34, 0xd6, 0x03, 0xca, 0x50, 0xbb, 0x4a, 0xad, + 0x57, 0xff, 0x10, 0x08, 0xe4, 0x50, 0xf2, 0xa9, 0xfc, 0x40, 0x29, 0x2b, 0xc8, 0xec, 0xdd, 0xf4, + 0xb2, 0x92, 0x1d, 0x97, 0xe2, 0x6e, 0x63, 0xcd, 0xeb, 0xf0, 0x48, 0x64, 0x34, 0xaf, 0xff, 0x84, + 0x76, 0x37, 0xee, 0xa6, 0xe3, 0x48, 0x29, 0xfe, 0x14, 0x9d, 0x13, 0x44, 0x24, 0x74, 0x94, 0xd2, + 0x34, 0xd5, 0x4b, 0x86, 0xdc, 0xf3, 0x7f, 0x4e, 0x7b, 0x63, 0xe0, 0xae, 0x4b, 0x21, 0x18, 0x0e, + 0x8f, 0x49, 0xb4, 0xc6, 0x59, 0xc6, 0xbd, 0x93, 0x92, 0xb3, 0xe0, 0x94, 0x52, 0x4d, 0xfa, 0x08, + 0x6e, 0x9d, 0x09, 0x84, 0xe7, 0x2f, 0x8d, 0xa9, 0x98, 0xb6, 0x99, 0x2e, 0x19, 0x31, 0x59, 0x80, + 0x68, 0xe8, 0x09, 0xe9, 0xae, 0x8c, 0x47, 0x0d, 0x71, 0xe1, 0x49, 0xa5, 0x1a, 0xf5, 0xfd, 0xcb, + 0x41, 0x7a, 0x1b, 0x63, 0xb5, 0x3f, 0x13, 0x1b, 0x9b, 0x34, 0xec, 0x65, 0x20, 0xc4, 0xd4, 0xf4, + 0x18, 0xd0, 0x95, 0x7b, 0x43, 0x1d, 0xae, 0xd1, 0x6d, 0x4f, 0x7f, 0xe1, 0x6d, 0x51, 0xa3, 0xb9, + 0x56, 0xfd, 0x4a, 0x37, 0xef, 0xf1, 0x30, 0x5b, 0xbb, 0xd8, 0xdd, 0xf9, 0x43, 0x1d, 0x0b, 0x8a, + 0xb9, 0x08, 0xee, 0xef, 0xe8, 0xb5, 0xf0, 0xf0, 0x8a, 0x26, 0xcc, 0x41, 0x0f, 0xe6, 0xec, 0x76, + 0xab, 0x09, 0x05, 0x3f, 0x2d, 0xab, 0x75, 0xb6, 0xdf, 0xf8, 0x2b, 0xa8, 0xb3, 0xe9, 0xa9, 0x3f, + 0x69, 0x5c, 0x99, 0xca, 0x1e, 0x09, 0xec, 0x8b, 0x1a, 0x45, 0xa6, 0x48, 0x5f, 0x88, 0x8c, 0xcc, + 0xf2, 0xd4, 0xb1, 0xde, 0x68, 0x22, 0x70, 0xa2, 0x81, 0xc9, 0x1e, 0xf0, 0xa4, 0xe5, 0x8a, 0xcb, + 0x1b, 0x31, 0x1f, 0x2e, 0xa6, 0xfc, 0xcf, 0x60, 0xe2, 0xf5, 0xb3, 0x88, 0x8c, 0xd6, 0x52, 0x84, + 0x85, 0xd0, 0x52, 0xb6, 0xd9, 0x8b, 0xea, 0xbf, 0x05, 0x9d, 0x4c, 0x41, 0x3e, 0xa1, 0x34, 0x92, + 0x66, 0xee, 0xb9, 0x04, 0x9d, 0xa7, 0xdf, 0x1c, 0x45, 0xc9, 0x96, 0xc0, 0x7f, 0x27, 0xa1, 0x79, + 0x06, 0xe2, 0x93, 0x4c, 0x72, 0x50, 0x6f, 0x97, 0x48, 0xd8, 0xb3, 0xb8, 0x91, 0x87, 0x0a, 0x70, + 0xe6, 0xce, 0xb4, 0x12, 0x98, 0x42, 0x5c, 0x53, 0x96, 0x21, 0x67, 0x88, 0x10, 0x14, 0x3a, 0x09, + 0x21, 0xf1, 0x48, 0xec, 0x31, 0x9a, 0x7f, 0x33, 0x20, 0x37, 0x70, 0x76, 0xf2, 0xca, 0x70, 0xd5, + 0x3a, 0xc4, 0x44, 0xe3, 0x78, 0x11, 0x4c, 0x55, 0x42, 0x15, 0xaa, 0x3c, 0x22, 0x42, 0x96, 0xee, + 0xe7, 0xdd, 0x37, 0xf1, 0x22, 0x41, 0x36, 0xe8, 0x21, 0x80, 0x87, 0xbd, 0x46, 0xff, 0x1f, 0x7b, + 0x77, 0xb3, 0xb0, 0x5e, 0xf6, 0x13, 0xd0, 0x1b, 0xf8, 0x9e, 0xd1, 0x17, 0xd7, 0x5c, 0x44, 0x13, + 0x09, 0x5d, 0x76, 0x35, 0x53, 0xa7, 0x88, 0x27, 0x4c, 0xbf, 0xcc, 0x29, 0xd4, 0xac, 0x3b, 0xf8, + 0x9b, 0xa5, 0xae, 0x3f, 0x84, 0x0b, 0xc5, 0x6d, 0x49, 0x99, 0xfb, 0x5e, 0x22, 0x0a, 0x68, 0xd1, + 0x94, 0xb5, 0xbf, 0x1e, 0x41, 0xda, 0xa4, 0xff, 0x7c, 0x16, 0xe6, 0xa7, 0x79, 0xf2, 0x37, 0xc2, + 0x42, 0x1c, 0x30, 0x8d, 0x04, 0x25, 0x9b, 0xd4, 0x65, 0xa7, 0xc6, 0x92, 0x81, 0x84, 0x5e, 0xb7, + 0xcd, 0xfe, 0x06, 0xae, 0x61, 0xcb, 0xb3, 0xa4, 0xce, 0xfe, 0x1d, 0xa4, 0xb0, 0xb7, 0x28, 0xcd, + 0x4f, 0xf0, 0xf9, 0xd5, 0xa6, 0x65, 0x5a, 0x09, 0x8d, 0x8c, 0xb5, 0x0d, 0x64, 0x7c, 0x62, 0xa4, + 0x1a, 0x74, 0x2b, 0x0d, 0x5b, 0x45, 0xff, 0x0b, 0x72, 0xb1, 0xd2, 0xb2, 0xe1, 0x0c, 0xe0, 0xff, + 0xbf, 0x9f, 0xa2, 0xd4, 0x29, 0xc1, 0x38, 0x84, 0xb4, 0xe6, 0xed, 0x0f, 0x36, 0x46, 0x37, 0xcb, + 0x77, 0xfe, 0x0b, 0x8e, 0x76, 0xdd, 0x9d, 0x68, 0x75, 0xf0, 0x49, 0xc4, 0x39, 0x4d, 0xf0, 0x4e, + 0x2b, 0xbb, 0xbb, 0x8a, 0xc6, 0xe9, 0xde, 0x0a, 0x42, 0x87, 0x93, 0x4a, 0xc5, 0x56, 0xd5, 0x5a, + 0xa2, 0x5b, 0x91, 0x5c, 0x9f, 0x47, 0xbe, 0x13, 0xc8, 0xa2, 0xbc, 0x75, 0x13, 0x11, 0x0a, 0x54, + 0x5c, 0x94, 0xc4, 0x0c, 0x1a, 0xa8, 0x6c, 0xd0, 0xf5, 0x02, 0xe6, 0x32, 0x4d, 0x65, 0xbd, 0x8a, + 0xe8, 0x1c, 0xbe, 0x2b, 0x71, 0x5b, 0xa6, 0x2b, 0x4d, 0xfc, 0xb7, 0xa7, 0xf4, 0x7a, 0xf1, 0x22, + 0xed, 0xa6, 0xe5, 0xe9, 0x23, 0xb3, 0x94, 0xe2, 0x06, 0x6b, 0x54, 0x22, 0x7f, 0x1f, 0x2e, 0xe8, + 0x0d, 0x10, 0xe1, 0x23, 0xf8, 0x22, 0xba, 0x1e, 0xde, 0x20, 0x13, 0x12, 0xf2, 0xb0, 0x5a, 0x1c, + 0xb1, 0xbf, 0xd7, 0xbc, 0x4a, 0x2b, 0x9f, 0x1e, 0x27, 0x2d, 0x1d, 0xdd, 0xfa, 0x6f, 0xe0, 0x84, + 0x8f, 0x7b, 0xd7, 0x21, 0xb7, 0x7f, 0x05, 0x39, 0x69, 0xb6, 0x81, 0xd4, 0x4e, 0x3e, 0x2b, 0xb9, + 0x71, 0xb8, 0x81, 0x00, 0xa0, 0xee, 0xee, 0xe8, 0x23, 0x56, 0x43, 0x85, 0xff, 0x34, 0x4b, 0x87, + 0x20, 0xbb, 0xf3, 0xc2, 0x44, 0x9c, 0x20, 0xd5, 0xfb, 0x25, 0xce, 0x21, 0x4f, 0x4d, 0x19, 0xd4, + 0x7f, 0x86, 0xef, 0x2a, 0x3c, 0x12, 0x9a, 0xf1, 0xc3, 0xcf, 0x86, 0xf8, 0x9d, 0x25, 0x43, 0x4f, + 0x69, 0x71, 0xc2, 0x69, 0x3d, 0x27, 0xd0, 0x68, 0x9f, 0xec, 0xd5, 0xaf, 0x08, 0x0e, 0x26, 0xa6, + 0xc7, 0x85, 0x52, 0xd2, 0x1e, 0xf4, 0xf1, 0x23, 0x0b, 0x6d, 0xce, 0x62, 0x5f, 0xac, 0x8a, 0x2e, + 0xed, 0xb1, 0x31, 0x45, 0x3e, 0x11, 0x15, 0xdc, 0x8f, 0x8b, 0xa6, 0x31, 0x56, 0x24, 0x49, 0x2c, + 0x47, 0xff, 0x82, 0x6a, 0x68, 0x64, 0x8b, 0x18, 0x58, 0xcc, 0x30, 0x77, 0xf8, 0x22, 0xdd, 0xe9, + 0xeb, 0x11, 0xf0, 0x99, 0xda, 0xa7, 0x6f, 0x72, 0xef, 0x89, 0x12, 0x09, 0xc9, 0x44, 0x0f, 0x94, + 0x58, 0xd2, 0x47, 0x1e, 0xbe, 0x53, 0xbe, 0xd7, 0x13, 0xc4, 0x4d, 0x7b, 0xa3, 0xe2, 0x42, 0x45, + 0x3e, 0x5b, 0x8a, 0xd5, 0x31, 0x98, 0x89, 0xf4, 0x47, 0xf8, 0xf1, 0x97, 0xbe, 0xd9, 0x30, 0xca, + 0xb7, 0x4b, 0xca, 0x26, 0xe9, 0x7c, 0x4c, 0xe4, 0x1b, 0x77, 0x72, 0xdf, 0xe2, 0xce, 0xf7, 0xbb, + 0xb8, 0x97, 0xf8, 0x21, 0xb5, 0x4b, 0xdf, 0x05, 0xb4, 0x90, 0x3b, 0x4d, 0x35, 0x64, 0xff, 0x44, + 0xef, 0x82, 0x21, 0x12, 0x18, 0x93, 0xc1, 0x37, 0xc3, 0xda, 0x02, 0x52, 0xb7, 0x38, 0x3c, 0xc0, + 0x11, 0xc1, 0x1b, 0x62, 0x98, 0xe4, 0x04, 0x95, 0x18, 0x2c, 0x0e, 0xae, 0xb2, 0x53, 0xff, 0x04, + 0x07, 0xa6, 0xaa, 0x53, 0x89, 0x35, 0x7c, 0xce, 0xe9, 0xf2, 0x0b, 0x29, 0x7f, 0xcd, 0xd5, 0xfe, + 0xaf, 0x27, 0x57, 0x89, 0xea, 0xf2, 0xf0, 0xe6, 0xb1, 0xeb, 0xb2, 0xee, 0x6a, 0x7f, 0xb3, 0x1b, + 0x34, 0x92, 0xf2, 0x94, 0xa1, 0x81, 0x4f, 0x5c, 0xdb, 0x55, 0xe1, 0x01, 0xdd, 0x2b, 0xe2, 0xa8, + 0x42, 0xc3, 0xcd, 0xc9, 0x9e, 0x10, 0x23, 0x4d, 0xf7, 0x6d, 0x08, 0xd2, 0x23, 0xf0, 0x5c, 0x4c, + 0xb5, 0x93, 0xf1, 0x02, 0x1f, 0x55, 0xc4, 0x41, 0x50, 0x93, 0x72, 0x10, 0x46, 0xef, 0xba, 0x24, + 0x83, 0x27, 0x7b, 0x11, 0xf2, 0xaa, 0xe7, 0xc1, 0x4d, 0xb5, 0x6c, 0x83, 0x06, 0x66, 0x69, 0x9f, + 0x67, 0x18, 0x62, 0xe3, 0x11, 0x11, 0x56, 0x96, 0xb5, 0x17, 0x78, 0x90, 0x57, 0x32, 0xed, 0x65, + 0x22, 0xd7, 0x62, 0x1d, 0x6b, 0xba, 0xb8, 0x9a, 0x67, 0xe4, 0xf5, 0xab, 0xeb, 0x9b, 0x63, 0x37, + 0xfc, 0x12, 0x11, 0xf6, 0x3e, 0xf8, 0x29, 0xee, 0xe9, 0xbd, 0xf9, 0xb1, 0xfe, 0x0a, 0xcb, 0xb3, + 0x2c, 0x19, 0xb7, 0xa1, 0x51, 0x36, 0x86, 0x61, 0xe7, 0xe3, 0x1f, 0x04, 0x95, 0x3e, 0x3d, 0x5d, + 0xf0, 0x47, 0x47, 0x3f, 0x95, 0x7e, 0x24, 0x4f, 0x27, 0xd2, 0x94, 0xcf, 0x82, 0x3b, 0xbf, 0x5f, + 0x36, 0x45, 0x4b, 0xf8, 0x22, 0xd0, 0xe7, 0x50, 0xf5, 0xc3, 0xa6, 0x65, 0x53, 0xab, 0xce, 0x62, + 0xd9, 0xcd, 0x63, 0xc7, 0x29, 0x6d, 0x7a, 0x8f, 0x24, 0xee, 0xb5, 0xff, 0x08, 0x9f, 0x22, 0xf3, + 0x06, 0x0c, 0xa1, 0x83, 0x4d, 0x8d, 0xa3, 0xa5, 0x19, 0xd5, 0xa3, 0x39, 0x45, 0x72, 0xb0, 0xb8, + 0xc1, 0x2c, 0x8a, 0xce, 0x9d, 0x3b, 0xdf, 0x79, 0x1f, 0xe4, 0xbb, 0x7a, 0x89, 0x84, 0xfb, 0x4b, + 0xbb, 0x78, 0x88, 0x91, 0x45, 0x51, 0xbb, 0xcf, 0x0f, 0xc4, 0x09, 0x4f, 0x55, 0xd7, 0xc9, 0x5a, + 0xb1, 0xe2, 0x02, 0x04, 0xae, 0xc7, 0xc4, 0x57, 0x08, 0x96, 0x91, 0x58, 0xba, 0x1b, 0x8d, 0x81, + 0x40, 0x72, 0xb1, 0x5b, 0xc1, 0x1e, 0x11, 0x19, 0x56, 0x08, 0xcd, 0x9c, 0xed, 0x7a, 0x43, 0xa9, + 0x2c, 0x0c, 0x1a, 0xf7, 0x62, 0x09, 0x79, 0x71, 0xb8, 0x80, 0x8d, 0x9d, 0x05, 0x19, 0x07, 0x01, + 0x15, 0xb9, 0xc9, 0x06, 0xdf, 0x7e, 0x20, 0x20, 0x12, 0xd9, 0xdc, 0x57, 0x77, 0xe1, 0x05, 0x73, + 0x88, 0x84, 0xba, 0xa1, 0xca, 0xc5, 0xbf, 0x77, 0xbb, 0x1f, 0x89, 0x33, 0xb5, 0x7d, 0xb2, 0x7f, + 0x05, 0xc5, 0x76, 0xe6, 0xee, 0xe7, 0xce, 0xfa, 0xbd, 0x74, 0x5f, 0xfc, 0x16, 0x16, 0x66, 0x1a, + 0xc9, 0x65, 0xa5, 0xd8, 0x20, 0x2d, 0xb5, 0x01, 0x8e, 0x1a, 0x97, 0x28, 0x7a, 0x33, 0x7c, 0x10, + 0x96, 0x8e, 0xaf, 0xf2, 0x11, 0xb4, 0xef, 0xe0, 0xba, 0x9e, 0xf8, 0xae, 0x00, 0x5f, 0x30, 0xa8, + 0xc8, 0xcc, 0x82, 0xfc, 0xbe, 0x9b, 0x7e, 0x0a, 0x0b, 0xa2, 0x19, 0xcd, 0x2e, 0x94, 0x50, 0xa7, + 0x45, 0x6a, 0xe6, 0x36, 0x92, 0x7e, 0x10, 0x25, 0x00, 0x53, 0x29, 0x0c, 0xe8, 0x46, 0x4d, 0x1e, + 0x86, 0xbe, 0xc4, 0xec, 0x6b, 0xe0, 0x97, 0x76, 0x13, 0x27, 0xec, 0xfb, 0xe0, 0x84, 0xee, 0xee, + 0xfd, 0xf2, 0x93, 0x2f, 0xae, 0x11, 0x33, 0xda, 0xd6, 0x4f, 0x3a, 0x8f, 0xcb, 0x7c, 0xdf, 0x89, + 0x04, 0x82, 0x4d, 0x4d, 0x5f, 0xc4, 0x82, 0xb2, 0xd4, 0x5d, 0x4c, 0xa2, 0x72, 0x42, 0x87, 0x1e, + 0x23, 0xef, 0x8a, 0x91, 0x44, 0x8a, 0x10, 0x95, 0x68, 0x5e, 0x08, 0xcc, 0x92, 0x52, 0x90, 0x7b, + 0xe0, 0x9c, 0xa6, 0xca, 0x25, 0x43, 0x59, 0x69, 0xef, 0x82, 0xcb, 0x1a, 0x14, 0x14, 0x91, 0xf3, + 0x3f, 0x72, 0xd5, 0x0a, 0xf5, 0x7f, 0x7c, 0x25, 0x74, 0x4e, 0x33, 0x26, 0xda, 0x7c, 0x22, 0x08, + 0xef, 0x38, 0x20, 0x0a, 0x37, 0xa8, 0x99, 0xad, 0x39, 0x14, 0x93, 0x29, 0x8f, 0x62, 0x9e, 0xff, + 0x62, 0xd6, 0x82, 0x4b, 0xe8, 0x9d, 0xf0, 0x43, 0x72, 0xd1, 0xec, 0xa9, 0xf4, 0x57, 0xfa, 0xf7, + 0xc9, 0x0c, 0xa2, 0x94, 0x77, 0x6e, 0xf8, 0x26, 0x2a, 0x4f, 0xb4, 0xc8, 0xd0, 0xea, 0xf8, 0xf1, + 0xd3, 0x80, 0x06, 0xf9, 0x4d, 0x31, 0x95, 0x4b, 0x80, 0x02, 0x82, 0x60, 0x60, 0x7c, 0x18, 0x1c, + 0x72, 0x0e, 0x36, 0xac, 0x9a, 0x66, 0x4d, 0x88, 0x65, 0x23, 0x5c, 0x4d, 0xdf, 0x13, 0xd5, 0xe3, + 0x3a, 0xf7, 0xc3, 0xe3, 0x2a, 0x56, 0x37, 0x62, 0x91, 0xb9, 0xc5, 0x53, 0x56, 0xdd, 0x7f, 0xe1, + 0x02, 0xc4, 0x43, 0x69, 0x64, 0x53, 0xdb, 0x67, 0x55, 0x5c, 0x22, 0x27, 0x1e, 0x0a, 0x1a, 0x3b, + 0xa6, 0x32, 0x22, 0x20, 0x66, 0x61, 0xaa, 0x5c, 0xc7, 0x82, 0xb9, 0x25, 0x94, 0xe4, 0x68, 0x9b, + 0x1d, 0x76, 0xee, 0x85, 0x5f, 0x5a, 0xf1, 0x03, 0xea, 0x6c, 0xd5, 0x72, 0xc2, 0x76, 0x4b, 0xb8, + 0x99, 0x73, 0x30, 0x81, 0xcf, 0x8f, 0x34, 0xb4, 0xc7, 0xf1, 0xdb, 0xbb, 0xaf, 0xc1, 0x48, 0xba, + 0x11, 0xc8, 0xdc, 0xe0, 0x84, 0x8b, 0xf9, 0xe0, 0xcf, 0x73, 0xe3, 0x35, 0xaa, 0xca, 0xd9, 0x9b, + 0x9b, 0x27, 0x9c, 0x30, 0xaf, 0x13, 0xe2, 0x41, 0x57, 0x84, 0xce, 0x34, 0xa4, 0xcc, 0xb6, 0xdd, + 0x8d, 0xee, 0xe2, 0x44, 0x89, 0xb8, 0xad, 0xdc, 0x67, 0xa2, 0xda, 0xf0, 0xa4, 0xa4, 0x1b, 0x77, + 0xb7, 0x6d, 0xb9, 0xbe, 0x99, 0xfc, 0x63, 0x9b, 0xe3, 0xec, 0x49, 0x97, 0x21, 0x26, 0xc4, 0x93, + 0x02, 0xa7, 0x5f, 0x08, 0x08, 0x8d, 0x8d, 0x36, 0xdf, 0x73, 0x7e, 0xbe, 0x09, 0xcf, 0x74, 0xb2, + 0xe2, 0x5b, 0xfc, 0x40, 0x87, 0x77, 0x79, 0x8d, 0x57, 0xd1, 0xdf, 0xe5, 0xbe, 0xdf, 0x96, 0xed, + 0x3b, 0xae, 0xaf, 0xf3, 0x1e, 0x3e, 0x63, 0xae, 0x08, 0x65, 0x8e, 0xc3, 0xef, 0xa2, 0x77, 0xc1, + 0x41, 0x6c, 0x9d, 0xc9, 0x84, 0xcf, 0xdf, 0x5e, 0xf8, 0x2c, 0xd2, 0x9c, 0x8b, 0x36, 0xa9, 0x5a, + 0x6a, 0xf5, 0xc5, 0x8c, 0x45, 0x48, 0xc7, 0xd8, 0xd2, 0xa2, 0x63, 0xf0, 0x44, 0x75, 0x5e, 0x28, + 0x53, 0xa1, 0x5d, 0xf3, 0x95, 0x4f, 0x46, 0xff, 0xf7, 0x95, 0x8b, 0x7e, 0x53, 0xa4, 0x45, 0x0d, + 0x7e, 0x09, 0xc8, 0xf9, 0xc8, 0x3b, 0xb7, 0x7f, 0x82, 0x33, 0x90, 0xb9, 0x84, 0x1a, 0x1d, 0x7c, + 0xb9, 0xbf, 0xc4, 0x78, 0x80, 0x43, 0xb6, 0xd5, 0x9c, 0x48, 0x8f, 0x12, 0x24, 0x43, 0xa4, 0x8c, + 0x66, 0x45, 0x8c, 0x5d, 0x71, 0x02, 0x4b, 0xbd, 0xfc, 0x25, 0xbc, 0xb8, 0xaa, 0xab, 0xc4, 0x82, + 0xa3, 0xaa, 0x14, 0xbd, 0x34, 0xd8, 0x93, 0xa6, 0xc7, 0xdf, 0x04, 0xf7, 0x4d, 0xdd, 0xda, 0x7a, + 0x5f, 0x88, 0xef, 0x7d, 0x35, 0xe2, 0x66, 0xda, 0xaf, 0x84, 0xe8, 0x62, 0xe9, 0x2d, 0xcb, 0x8d, + 0xf8, 0x98, 0x2d, 0x26, 0x7f, 0x7e, 0xdf, 0xef, 0x82, 0x21, 0x22, 0xb7, 0x38, 0x60, 0x37, 0xdf, + 0x57, 0xfa, 0xbf, 0xd5, 0xfe, 0xbd, 0x27, 0x36, 0x9a, 0x7f, 0x5e, 0xf8, 0x24, 0xad, 0x3f, 0x57, + 0x04, 0x43, 0x1d, 0xf2, 0x27, 0xd9, 0xf5, 0x4c, 0x27, 0xc1, 0x3d, 0x57, 0x5b, 0x47, 0x56, 0xef, + 0x82, 0x83, 0x31, 0x21, 0xda, 0xd5, 0x6f, 0x5c, 0xa5, 0x55, 0xfc, 0x41, 0x49, 0x4e, 0xd5, 0x52, + 0x7d, 0x1f, 0xff, 0x0a, 0x19, 0x55, 0x55, 0xde, 0xc6, 0xd9, 0x7d, 0x72, 0xca, 0xff, 0x1d, 0xdd, + 0xc9, 0xac, 0x6f, 0xce, 0xa6, 0xff, 0x82, 0x4e, 0xa8, 0x6f, 0xc4, 0x88, 0x11, 0xe7, 0xc9, 0x33, + 0xc4, 0xc7, 0x45, 0xc5, 0xd5, 0x55, 0x2b, 0xd5, 0x57, 0x12, 0x24, 0x23, 0xab, 0x3a, 0x9b, 0x1b, + 0x9a, 0x96, 0xbe, 0x0a, 0x88, 0x4c, 0x64, 0x5a, 0xe5, 0xff, 0x4d, 0xfd, 0xf2, 0x15, 0x8d, 0x8d, + 0x8d, 0x8f, 0x89, 0x04, 0xb7, 0x77, 0x7b, 0xdd, 0xea, 0x26, 0x42, 0x3d, 0xdf, 0x11, 0x04, 0x22, + 0x53, 0x6d, 0x08, 0xdf, 0xff, 0x04, 0x57, 0x15, 0x9d, 0x43, 0xc8, 0x3d, 0x7c, 0x4f, 0x54, 0x95, + 0x3d, 0x75, 0x7f, 0xab, 0xfc, 0x10, 0xd5, 0xaa, 0x06, 0xff, 0x57, 0xf9, 0xaf, 0x69, 0x7d, 0x11, + 0xfe, 0x0a, 0x88, 0xef, 0x9b, 0xfc, 0xc1, 0x80, 0xb6, 0xff, 0x42, 0x5f, 0xea, 0x8e, 0xfc, 0x10, + 0x88, 0x52, 0x66, 0x5c, 0xae, 0x38, 0xa9, 0x37, 0xd9, 0xac, 0xec, 0x1a, 0xe7, 0x79, 0xe0, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x21, 0x10, 0xb0, 0x11, 0xa1, 0x1c, 0xb7, 0xbc, 0x25, 0xd0, 0xda, + 0x87, 0xb8, 0xb1, 0x0d, 0x20, 0x63, 0xae, 0xa5, 0xa9, 0xb3, 0xa8, 0xd1, 0xf8, 0x6e, 0x70, 0x96, + 0x03, 0x22, 0xf8, 0x23, 0x20, 0x81, 0x8d, 0xc6, 0x7f, 0xe5, 0x99, 0x2e, 0x54, 0x45, 0xe8, 0x93, + 0x80, 0x87, 0x43, 0xdf, 0xe4, 0x20, 0xa0, 0xc5, 0x06, 0x28, 0x31, 0x41, 0xae, 0x72, 0xb9, 0xf1, + 0x82, 0x3a, 0xf8, 0x6f, 0x85, 0x45, 0x4e, 0x21, 0x9d, 0xc8, 0x7d, 0xfa, 0x6d, 0x6f, 0x21, 0x8f, + 0xf8, 0x21, 0x2b, 0x69, 0xf7, 0xf9, 0x32, 0xde, 0x6e, 0xb1, 0x7d, 0x08, 0xaf, 0xa1, 0x24, 0x28, + 0xee, 0x6f, 0x0c, 0xad, 0x42, 0xea, 0x7a, 0x11, 0xe8, 0xf1, 0x46, 0x70, 0x99, 0xad, 0x9d, 0x8f, + 0x95, 0x81, 0x3d, 0x08, 0x74, 0x6f, 0x30, 0xf4, 0xd2, 0xcb, 0xd5, 0x97, 0xc2, 0x74, 0xe9, 0x5a, + 0x6b, 0x5c, 0x10, 0x88, 0x40, 0xd5, 0x9a, 0xcb, 0xe0, 0xc3, 0x4d, 0x24, 0xe3, 0x68, 0x48, 0x0b, + 0x1c, 0x84, 0x71, 0x61, 0xc6, 0xc2, 0xf2, 0x72, 0x89, 0x05, 0x68, 0x44, 0x15, 0x2d, 0x01, 0x5a, + 0x40, 0x56, 0x68, 0x02, 0xdc, 0xbe, 0x1c, 0xc7, 0x3e, 0x1d, 0xc7, 0xfd, 0xd3, 0xe3, 0x95, 0xf4, + 0xf1, 0x8f, 0x7d, 0x22, 0xf2, 0x68, 0xc4, 0xbe, 0xb9, 0x88, 0x3f, 0x4d, 0x7d, 0x3f, 0x0f, 0x0a, + 0x4d, 0x4d, 0xe3, 0x62, 0x86, 0x50, 0x1b, 0x82, 0x71, 0x27, 0x96, 0x40, 0xf2, 0xdf, 0xcd, 0xd7, + 0xc3, 0x62, 0xc2, 0x15, 0x21, 0x2c, 0x8e, 0x01, 0x13, 0x6d, 0x30, 0xdf, 0x65, 0xc3, 0xaa, 0x02, + 0x20, 0x37, 0x46, 0x1e, 0x7b, 0x0b, 0x32, 0xff, 0x06, 0x05, 0xc3, 0x4c, 0xb2, 0x26, 0x5b, 0x0d, + 0x32, 0xc8, 0x99, 0x62, 0xa7, 0x55, 0x2d, 0x54, 0xbf, 0x5c, 0x64, 0x33, 0x0b, 0xe7, 0xa9, 0x83, + 0x49, 0x03, 0xa7, 0x4d, 0x31, 0xaf, 0x27, 0x21, 0xb4, 0x5e, 0x4b, 0xfc, 0x5e, 0x18, 0xa5, 0x6a, + 0x03, 0x5a, 0xeb, 0x99, 0x39, 0x6c, 0x54, 0x09, 0x24, 0x01, 0xf0, 0x3e, 0x58, 0x3d, 0x3c, 0x20, + 0xd5, 0xdc, 0xff, 0xc6, 0x90, 0x3c, 0xbd, 0x74, 0x1e, 0x10, 0x0f, 0xcb, 0x55, 0xe5, 0x1c, 0x68, + 0x31, 0x8c, 0xd0, 0xd0, 0x85, 0x9d, 0xdb, 0x2a, 0x83, 0xc2, 0x5e, 0x0f, 0xa8, 0x71, 0x38, 0x03, + 0xb9, 0x70, 0xec, 0xd6, 0xe3, 0x87, 0x36, 0x3c, 0x5e, 0x10, 0xd2, 0x16, 0x7a, 0xf0, 0xfe, 0x57, + 0x22, 0x70, 0xe8, 0x69, 0x3c, 0x63, 0x06, 0x6e, 0xf8, 0x3e, 0x3f, 0xe6, 0xe1, 0xc1, 0xf6, 0x1a, + 0x1d, 0xfb, 0x31, 0x06, 0x9b, 0xce, 0x52, 0xa7, 0x1c, 0x96, 0xb2, 0x5f, 0xfe, 0xf0, 0x3e, 0xda, + 0x3f, 0x86, 0x61, 0x3b, 0x03, 0xbe, 0x51, 0xaa, 0xfe, 0x48, 0x08, 0x8c, 0x72, 0x74, 0x4c, 0x85, + 0xb2, 0xf1, 0x06, 0x0c, 0x10, 0xb6, 0x34, 0xd3, 0x46, 0xa5, 0x38, 0x40, 0x68, 0x41, 0x45, 0xc6, + 0xda, 0x91, 0xda, 0x19, 0xbc, 0x1b, 0x69, 0x50, 0xf1, 0xbd, 0xe3, 0x2f, 0xad, 0x07, 0xfd, 0xf9, + 0x00, 0x43, 0x7f, 0x67, 0xde, 0xe5, 0xe8, 0x9f, 0xbb, 0x47, 0x27, 0x58, 0x45, 0x22, 0xdc, 0x4e, + 0x60, 0x68, 0x27, 0x90, 0xc9, 0x0f, 0x51, 0x89, 0xdc, 0x2a, 0x89, 0x37, 0x87, 0xda, 0x82, 0xad, + 0xa8, 0x76, 0x23, 0x6f, 0x5c, 0x6c, 0xc3, 0x06, 0x25, 0xa6, 0xc2, 0x0e, 0xdd, 0x84, 0xd2, 0xe7, + 0x08, 0x0d, 0xa6, 0xac, 0x37, 0xd3, 0x0e, 0x54, 0x9a, 0x0b, 0x33, 0x2f, 0xbe, 0x0d, 0xea, 0xb3, + 0x96, 0x01, 0xef, 0x89, 0xf5, 0x60, 0x5f, 0xfa, 0x8f, 0xa7, 0x3b, 0x0c, 0x8c, 0xa4, 0x41, 0xb7, + 0x94, 0xe3, 0xeb, 0x43, 0x6f, 0xd6, 0x6d, 0x1c, 0xcd, 0x6e, 0xaa, 0xa2, 0xd6, 0xbe, 0xd8, 0x1d, + 0x7f, 0x11, 0x87, 0x9e, 0x37, 0x3d, 0x47, 0xee, 0x4b, 0x02, 0x3d, 0x48, 0xcf, 0xf8, 0x90, 0xd9, + 0xc9, 0x18, 0xee, 0x54, 0x3e, 0xdf, 0x0e, 0x28, 0x6d, 0xd4, 0xf2, 0xbb, 0x05, 0xb7, 0xe2, 0x22, + 0x4a, 0xb5, 0x4b, 0xe1, 0xd1, 0xe2, 0x56, 0x46, 0xbd, 0x77, 0xda, 0x66, 0x3b, 0x4b, 0xb3, 0x7c, + 0x3f, 0x97, 0xb1, 0x54, 0xef, 0x07, 0x54, 0x3d, 0x04, 0x8a, 0xa4, 0x78, 0x80, 0xdf, 0x7b, 0x78, + 0x06, 0xc0, 0xf3, 0xf6, 0x92, 0x50, 0x9b, 0x5d, 0xf1, 0xb2, 0x25, 0x52, 0xb9, 0x52, 0xd1, 0x82, + 0x9b, 0x44, 0xa1, 0x9b, 0xc8, 0x54, 0xd0, 0x85, 0x4f, 0xb7, 0x60, 0xd7, 0x94, 0xa6, 0x34, 0x2a, + 0x7d, 0x8e, 0xc1, 0x6e, 0xf4, 0xcd, 0xa2, 0x1a, 0x8f, 0xf3, 0xb7, 0xf0, 0x61, 0xd5, 0x79, 0x57, + 0x87, 0xfd, 0xf3, 0xa1, 0xd9, 0xf4, 0xfb, 0xdf, 0xa7, 0xd3, 0x6b, 0xb7, 0xc1, 0x87, 0x8c, 0x8f, + 0x41, 0xaf, 0x2d, 0x68, 0xf4, 0xeb, 0xcf, 0xa7, 0xdf, 0xe3, 0x4d, 0x39, 0x06, 0x88, 0xe3, 0x0a, + 0x74, 0xcf, 0x7b, 0x99, 0x46, 0xae, 0x04, 0x08, 0x49, 0xcb, 0xe2, 0xa9, 0xcb, 0xf0, 0x8a, 0x0c, + 0xd4, 0xe6, 0x22, 0x76, 0xb2, 0xae, 0xff, 0x85, 0x4e, 0x35, 0xe5, 0x5e, 0xf5, 0x5e, 0x55, 0xef, + 0x4d, 0xff, 0x24, 0x24, 0x87, 0x88, 0xaa, 0xf2, 0xaf, 0x7a, 0xaf, 0x2a, 0xf7, 0xf8, 0xda, 0xaf, + 0x2a, 0xf7, 0xaa, 0xf2, 0xaf, 0x7c, 0x69, 0x31, 0x54, 0x98, 0x48, 0x8a, 0x6a, 0x6a, 0xc5, 0xfb, + 0x46, 0xdb, 0xf5, 0x6a, 0x0d, 0xb4, 0xe8, 0x0d, 0xf2, 0xe7, 0x5a, 0x1d, 0x94, 0xe9, 0x93, 0x4c, + 0x68, 0x46, 0xd6, 0xee, 0x66, 0xfd, 0xfa, 0x1b, 0xa8, 0x7f, 0x85, 0x6c, 0x48, 0x24, 0xa6, 0xa8, + 0xf1, 0x26, 0xf1, 0xb0, 0x20, 0xdd, 0x61, 0xff, 0xfd, 0x68, 0x8f, 0x68, 0x55, 0x7f, 0xe1, 0x6a, + 0x58, 0x6d, 0x7a, 0x1b, 0x97, 0xff, 0xc7, 0x7d, 0xa9, 0x25, 0x90, 0xb6, 0x06, 0xa6, 0x05, 0x22, + 0x6e, 0xfc, 0x5a, 0xfa, 0xf2, 0xea, 0x18, 0x4c, 0xcf, 0xdc, 0x7f, 0x8d, 0xe1, 0xf6, 0x58, 0x7c, + 0x70, 0x19, 0xfd, 0xde, 0xc8, 0xd5, 0x7e, 0xcb, 0x4b, 0x55, 0x4d, 0xf3, 0xe6, 0x55, 0x4c, 0x60, + 0xd5, 0xe9, 0x6d, 0x28, 0xbd, 0x59, 0xc5, 0xc2, 0x0e, 0xb9, 0x67, 0x2e, 0x2f, 0xcf, 0xe8, 0xb6, + 0x47, 0x4f, 0xa6, 0xd9, 0x9e, 0x2f, 0xd6, 0xf9, 0x6f, 0xb5, 0xbe, 0x5b, 0xef, 0x1b, 0x31, 0xc5, + 0xa6, 0x34, 0x88, 0x0e, 0xfb, 0xfe, 0x75, 0xa4, 0x1e, 0x56, 0x60, 0xff, 0xb8, 0x0d, 0x51, 0xc4, + 0x36, 0x97, 0xf8, 0x35, 0xfa, 0xdd, 0x14, 0x52, 0xb7, 0x10, 0xe5, 0xf7, 0xb3, 0xae, 0x26, 0x80, + 0x56, 0x20, 0xd3, 0xbe, 0x13, 0x9a, 0xa8, 0x59, 0x63, 0x9c, 0xc5, 0x0d, 0x8a, 0xd4, 0xc7, 0x9e, + 0x64, 0x65, 0x89, 0x3a, 0x24, 0xee, 0xdd, 0x2e, 0xf9, 0xe4, 0x49, 0x34, 0x9b, 0xfd, 0x75, 0x32, + 0x2a, 0x5c, 0x25, 0x9f, 0xe7, 0xff, 0xcf, 0x4a, 0xbf, 0x36, 0x9b, 0x7c, 0xf2, 0x24, 0x9a, 0x4d, + 0xff, 0xcf, 0x1d, 0x89, 0x68, 0xc6, 0x8c, 0x68, 0xc6, 0x9c, 0x6b, 0x16, 0xc5, 0xbf, 0x3c, 0x89, + 0x26, 0x93, 0x7f, 0xf8, 0x7e, 0x32, 0xd0, 0xb7, 0xda, 0xd6, 0x81, 0xb7, 0x1f, 0x68, 0x62, 0x5f, + 0xca, 0x9c, 0xda, 0x6d, 0xff, 0x04, 0x11, 0x96, 0x85, 0x2d, 0x1f, 0x09, 0x5a, 0xed, 0x19, 0x8e, + 0x92, 0x3b, 0x50, 0xbf, 0xde, 0x44, 0x54, 0x4d, 0x26, 0xfc, 0xfa, 0x7d, 0xf3, 0xd2, 0xaf, 0xcf, + 0xa7, 0xdf, 0x19, 0x0e, 0xe7, 0x7f, 0x19, 0x68, 0xf8, 0xef, 0xbe, 0x31, 0x2f, 0xfe, 0x78, 0x24, + 0x62, 0x96, 0x43, 0x31, 0x61, 0x0d, 0x4b, 0x61, 0x17, 0x45, 0x42, 0x79, 0xa1, 0x5d, 0x18, 0x88, + 0xcf, 0xc2, 0xb6, 0xd1, 0x37, 0x24, 0xd1, 0xe3, 0x51, 0x45, 0x63, 0x32, 0x84, 0x2c, 0x1e, 0xff, + 0xf0, 0x46, 0x29, 0x0e, 0xbe, 0x93, 0x9c, 0x69, 0x12, 0x4d, 0x26, 0xfe, 0x4e, 0xa6, 0x94, 0xae, + 0x1f, 0xe6, 0x21, 0x1d, 0x68, 0x13, 0xa7, 0xe2, 0x5f, 0x48, 0x4c, 0x68, 0xa7, 0x27, 0x90, 0xaa, + 0xcf, 0xbf, 0x0d, 0xe3, 0x1e, 0xe9, 0xd7, 0xed, 0x9f, 0x75, 0xcf, 0x32, 0x38, 0xf9, 0x74, 0xba, + 0x68, 0xb3, 0x7c, 0x4c, 0x68, 0x4b, 0x69, 0x5d, 0x1a, 0xd1, 0x64, 0x46, 0x6e, 0x48, 0x8b, 0x68, + 0x8b, 0x4c, 0x47, 0x62, 0x88, 0x24, 0xb0, 0x93, 0xe5, 0xea, 0xca, 0x6d, 0x2b, 0xa0, 0x3a, 0xea, + 0x7b, 0x2d, 0x49, 0xda, 0xc5, 0x40, 0xc0, 0xa1, 0xc5, 0xb7, 0xe5, 0x4a, 0x1a, 0xa8, 0x22, 0xde, + 0x43, 0x0d, 0xab, 0xc1, 0x8e, 0x39, 0x52, 0x50, 0x7a, 0xed, 0x7f, 0xe2, 0x46, 0xd3, 0x6a, 0x1f, + 0x3a, 0x6f, 0x75, 0x01, 0x5b, 0xdb, 0xdd, 0xc8, 0xce, 0xfa, 0x9c, 0x78, 0xfd, 0x5e, 0xf3, 0x95, + 0x47, 0xf6, 0x70, 0x30, 0x3a, 0xea, 0x1b, 0x1b, 0x93, 0x33, 0xbc, 0x5f, 0x0a, 0x0c, 0x06, 0x19, + 0x68, 0x8a, 0x2d, 0x99, 0x53, 0x18, 0xce, 0xd2, 0x8d, 0xa8, 0x0d, 0xda, 0xed, 0x19, 0xf7, 0xc5, + 0xe9, 0x03, 0x04, 0x09, 0x8e, 0x94, 0x32, 0xba, 0x21, 0x9f, 0xf8, 0xf2, 0xbe, 0xe8, 0xbe, 0x47, + 0x39, 0x87, 0xbf, 0xe6, 0x1c, 0x63, 0x61, 0x95, 0x82, 0x43, 0x22, 0x78, 0x5b, 0xe2, 0x03, 0xe5, + 0xaa, 0xc0, 0xc7, 0x1d, 0xdb, 0x14, 0xc4, 0xcc, 0xc9, 0x85, 0xa8, 0xdf, 0x65, 0xef, 0xa5, 0xf5, + 0x73, 0x15, 0x2f, 0xf3, 0x61, 0x7d, 0x01, 0x3d, 0x3d, 0xbf, 0x47, 0xe7, 0x0e, 0x39, 0xee, 0xee, + 0xfe, 0x17, 0x1f, 0xc7, 0x7c, 0xb7, 0xcb, 0xfc, 0xbf, 0xcb, 0x7c, 0xb7, 0xc9, 0x57, 0xf3, 0x69, + 0xb7, 0x89, 0x0a, 0xc6, 0x3c, 0xa3, 0xde, 0xa3, 0xca, 0x3d, 0xe3, 0xb2, 0xa3, 0xe9, 0xf4, 0xda, + 0xed, 0xcd, 0xa6, 0xdf, 0x04, 0x17, 0xc7, 0x87, 0x60, 0xd5, 0x3c, 0x75, 0xa0, 0x7d, 0x48, 0x2f, + 0x1d, 0xe6, 0x1a, 0x21, 0xb5, 0x77, 0xa2, 0xdb, 0x6a, 0x5b, 0xff, 0x0a, 0x0a, 0x19, 0x5d, 0xf6, + 0xb2, 0xca, 0xb3, 0x83, 0xda, 0x5b, 0xa8, 0x60, 0x40, 0x2e, 0x83, 0x50, 0x6a, 0x40, 0xd9, 0xfc, + 0xe6, 0x5f, 0x1a, 0x24, 0x31, 0xcc, 0x64, 0xd1, 0x27, 0xd5, 0x51, 0x62, 0x76, 0x5a, 0x45, 0x2d, + 0x76, 0x92, 0x98, 0xfa, 0x4c, 0x66, 0x8e, 0x1d, 0xb8, 0xb4, 0x3f, 0xf3, 0xe4, 0x12, 0x7e, 0xc0, + 0xd1, 0x73, 0xf0, 0x6a, 0x6a, 0xdc, 0xc8, 0x96, 0x3c, 0x31, 0x18, 0x70, 0x0c, 0xd4, 0x5b, 0x51, + 0xe2, 0x66, 0xd8, 0xff, 0x1a, 0x4d, 0x4c, 0xac, 0xd8, 0x34, 0x66, 0xcb, 0x40, 0x4c, 0xd6, 0x05, + 0x51, 0x8b, 0xef, 0x86, 0xb6, 0xf8, 0x0d, 0x3e, 0xe2, 0xaf, 0x76, 0x74, 0x9b, 0xd1, 0xca, 0xe9, + 0x47, 0x57, 0xf1, 0x91, 0xba, 0xc3, 0xbf, 0xfb, 0x16, 0xa2, 0xf1, 0xe9, 0x1c, 0x96, 0xba, 0x6c, + 0xeb, 0x6c, 0x79, 0xce, 0x9d, 0x7f, 0xf6, 0x1a, 0xd0, 0xd1, 0xc9, 0xa3, 0x93, 0x5e, 0x17, 0xaa, + 0xf6, 0x2f, 0x3f, 0x4f, 0x73, 0x89, 0x78, 0x94, 0x8e, 0xbc, 0x86, 0x88, 0x68, 0xe4, 0xd1, 0xc9, + 0xa8, 0x71, 0x51, 0x32, 0xdf, 0xff, 0x36, 0x9b, 0x73, 0x69, 0xb4, 0x45, 0xa1, 0xc9, 0xa1, 0x50, + 0xb4, 0xe3, 0x8d, 0x3f, 0x0a, 0xfc, 0x77, 0xda, 0xaf, 0x2a, 0xf2, 0xa6, 0x87, 0x60, 0x8e, 0x08, + 0x94, 0xc4, 0xe6, 0x89, 0xe3, 0x0d, 0x86, 0xf0, 0x47, 0xa9, 0x3f, 0xbb, 0xf8, 0x5b, 0x8b, 0xca, + 0xbd, 0xf8, 0xd7, 0xb1, 0x8a, 0x14, 0xad, 0xf7, 0x8d, 0x3f, 0xd7, 0x54, 0x5c, 0x7a, 0x95, 0x2b, + 0xa9, 0x52, 0xf9, 0xc8, 0x3e, 0xa4, 0x92, 0x69, 0xff, 0xa8, 0xf2, 0xf9, 0x32, 0xd0, 0xc4, 0x1f, + 0xc9, 0x9e, 0x8c, 0xff, 0x75, 0xd5, 0x7d, 0xf5, 0x1f, 0x4f, 0xd1, 0x22, 0xbe, 0xb0, 0x87, 0xab, + 0x49, 0xd6, 0x29, 0xba, 0xa6, 0x5e, 0xa9, 0x52, 0xeb, 0x17, 0xd6, 0x2f, 0x10, 0x30, 0x21, 0x14, + 0x6e, 0xfc, 0xde, 0x02, 0x4f, 0x00, 0x77, 0xac, 0x58, 0xc4, 0xdd, 0xf3, 0x66, 0xf2, 0x90, 0xd4, + 0x54, 0x86, 0x10, 0x1a, 0x98, 0x31, 0xff, 0x12, 0x36, 0x61, 0xd2, 0x2c, 0x3b, 0xc6, 0x85, 0xaf, + 0x80, 0xd8, 0x54, 0xdf, 0xe9, 0x2c, 0x2c, 0x26, 0x6e, 0x1a, 0x58, 0x65, 0xae, 0x27, 0x3f, 0x6b, + 0xdc, 0xbf, 0xb4, 0x93, 0xe2, 0xde, 0xaf, 0xee, 0x8d, 0x34, 0xf9, 0x0a, 0x75, 0x9b, 0xff, 0xab, + 0xf1, 0x8d, 0xbb, 0x48, 0x5d, 0xd3, 0xf3, 0x7a, 0x01, 0xf1, 0x03, 0xad, 0xd2, 0xa8, 0x27, 0x7c, + 0x46, 0x9f, 0x88, 0x8c, 0xec, 0x63, 0x37, 0xad, 0xf0, 0x24, 0x5c, 0xfd, 0x19, 0xe0, 0x19, 0x57, + 0x1b, 0x0e, 0x20, 0x28, 0x41, 0x68, 0x60, 0xd7, 0xed, 0xc5, 0xba, 0x17, 0x18, 0x49, 0xa8, 0x24, + 0xa3, 0x4f, 0xad, 0x34, 0x21, 0x57, 0x4c, 0x67, 0x56, 0xac, 0x43, 0xee, 0x9c, 0xff, 0x04, 0xc1, + 0x5c, 0x4f, 0x18, 0xc9, 0xa5, 0xea, 0x99, 0x54, 0xbe, 0x63, 0x28, 0xd3, 0xd0, 0x5c, 0xe8, 0x00, + 0x07, 0xc2, 0x83, 0x27, 0x00, 0x0a, 0x90, 0x0c, 0xe9, 0xd8, 0x69, 0xae, 0x52, 0x63, 0xb5, 0xa4, + 0x00, 0xe2, 0x47, 0x25, 0x27, 0x01, 0x30, 0x1a, 0xd5, 0xe8, 0x7a, 0x1b, 0x7b, 0x8e, 0x7d, 0xc9, + 0x7c, 0x87, 0x24, 0xdd, 0xa6, 0xc0, 0xdb, 0xca, 0x50, 0x30, 0xb4, 0xa0, 0xbd, 0xbe, 0x73, 0x7c, + 0x69, 0x38, 0x1d, 0x9c, 0x58, 0xfe, 0x8d, 0x5f, 0x8b, 0x34, 0xe2, 0x91, 0x02, 0x30, 0x23, 0x26, + 0x6e, 0xd2, 0x2a, 0x68, 0x18, 0x1d, 0xe6, 0x8f, 0x8e, 0x15, 0x26, 0x9d, 0x1f, 0x6a, 0xff, 0x83, + 0x08, 0xd9, 0xe9, 0x43, 0x06, 0x0d, 0xac, 0xd2, 0x73, 0x10, 0x1f, 0xf4, 0xba, 0xb7, 0xa0, 0xc6, + 0x39, 0x1c, 0x80, 0x2d, 0x98, 0xf3, 0xe4, 0x5d, 0x99, 0x88, 0x54, 0x93, 0x0b, 0x25, 0xa0, 0x00, + 0x83, 0xd9, 0x04, 0x94, 0xc6, 0x4d, 0xbf, 0xf1, 0x01, 0x49, 0xbb, 0x4f, 0x49, 0xe9, 0x1b, 0xd9, + 0x46, 0xda, 0xaa, 0x01, 0x1f, 0x7a, 0xef, 0xf5, 0xb0, 0x0a, 0x9b, 0x13, 0xb3, 0x6b, 0xc1, 0xda, + 0x52, 0x05, 0x4f, 0x87, 0x5d, 0xb2, 0xad, 0xe2, 0x01, 0x5d, 0x1c, 0xd3, 0xd0, 0x89, 0xd9, 0xa0, + 0x4b, 0x8f, 0xb5, 0xd0, 0x86, 0x06, 0x80, 0xc6, 0xc2, 0x08, 0xf4, 0x24, 0x7f, 0x01, 0xaf, 0xd3, + 0xa3, 0x81, 0xc3, 0xc1, 0x48, 0x5f, 0x54, 0xe2, 0x16, 0x2f, 0x73, 0xb3, 0x45, 0x4b, 0xc8, 0x79, + 0xb2, 0x27, 0xc3, 0xbd, 0x05, 0x3a, 0x23, 0xa1, 0x29, 0x97, 0xaf, 0x7d, 0x7b, 0xeb, 0xff, 0x08, + 0x02, 0x71, 0xcf, 0x8c, 0xa7, 0x53, 0xac, 0x17, 0xd5, 0x02, 0x25, 0xa0, 0x30, 0x6e, 0xa4, 0xbe, + 0x14, 0x20, 0x31, 0xe4, 0x48, 0x69, 0x3a, 0x3b, 0x47, 0x45, 0x8e, 0xcd, 0xcc, 0xa2, 0x53, 0x1a, + 0x10, 0x14, 0xf2, 0x29, 0xcc, 0xd1, 0x22, 0x99, 0x65, 0xa1, 0x8b, 0x14, 0xb1, 0xb3, 0x3c, 0xeb, + 0x89, 0x0a, 0x7d, 0x8d, 0xb9, 0xdd, 0xf9, 0x33, 0xb8, 0xf9, 0x96, 0xfc, 0x21, 0x04, 0xc1, 0x34, + 0xeb, 0xd3, 0x77, 0xfa, 0xf7, 0xcd, 0xd5, 0x7c, 0x28, 0x12, 0xe5, 0xe7, 0xa5, 0xb7, 0xa7, 0xab, + 0x5c, 0xec, 0x3b, 0x1b, 0x2f, 0xc6, 0x1e, 0x0b, 0x65, 0xb3, 0xd9, 0xf3, 0x47, 0x73, 0x37, 0xbe, + 0x14, 0x1e, 0x8d, 0x05, 0xd9, 0x86, 0xa8, 0xdb, 0x46, 0x9a, 0x05, 0xb2, 0xb2, 0xb5, 0xf6, 0x3d, + 0xd9, 0x6e, 0xd7, 0xef, 0x82, 0x7b, 0xd7, 0x33, 0xe1, 0x8e, 0x18, 0x35, 0x4d, 0x35, 0xd5, 0x5d, + 0x46, 0x71, 0x30, 0x58, 0x64, 0x98, 0x1d, 0x5a, 0xc3, 0x3f, 0xa8, 0xbf, 0xfe, 0x14, 0x14, 0xf5, + 0x4b, 0xc6, 0x16, 0xfa, 0x4b, 0x76, 0xf6, 0xc6, 0xad, 0x0c, 0x4a, 0xca, 0xc6, 0xd0, 0xe2, 0xd9, + 0x86, 0x06, 0x74, 0x6f, 0xc7, 0xe0, 0xef, 0x25, 0x46, 0xf2, 0xb2, 0xc0, 0x39, 0x5f, 0x71, 0x22, + 0x01, 0x30, 0xbd, 0x00, 0x00, 0x26, 0x52, 0x02, 0xad, 0x2b, 0x02, 0x36, 0xfd, 0x9d, 0x5a, 0xa9, + 0x4a, 0x7c, 0xba, 0x58, 0x04, 0x37, 0xd0, 0x55, 0xc1, 0x50, 0x8e, 0x6a, 0x17, 0xfd, 0xb4, 0x87, + 0x29, 0x7d, 0xf0, 0x46, 0x22, 0xee, 0xfd, 0xe2, 0x3e, 0x82, 0x7d, 0x37, 0x30, 0x8e, 0x6f, 0x89, + 0xfc, 0x40, 0x85, 0x67, 0x4e, 0xb5, 0xfa, 0xf3, 0x1a, 0xe1, 0x01, 0x30, 0x57, 0x89, 0x13, 0xbb, + 0xbd, 0xd3, 0x75, 0xd0, 0x4e, 0xab, 0x94, 0x2d, 0x07, 0x57, 0x83, 0x14, 0x83, 0xd8, 0xb5, 0x55, + 0xa8, 0x88, 0xb2, 0x62, 0x78, 0x06, 0xcd, 0x4b, 0x61, 0x7b, 0x55, 0x35, 0x58, 0x91, 0x05, 0x37, + 0x17, 0x7d, 0x05, 0x7b, 0xe8, 0xdd, 0x0b, 0x74, 0x35, 0xc8, 0x4f, 0x82, 0x23, 0x4b, 0xe3, 0x62, + 0x27, 0x5f, 0x62, 0xad, 0xf7, 0x5c, 0x5c, 0x92, 0x8f, 0x10, 0xb6, 0x36, 0xcd, 0xb5, 0x78, 0x44, + 0x9c, 0x79, 0x51, 0x32, 0x6e, 0x88, 0xbd, 0x45, 0xfc, 0x27, 0x3e, 0xc8, 0xd6, 0x1a, 0x6e, 0x6e, + 0xf5, 0xcd, 0x1a, 0xc9, 0xd0, 0x51, 0xde, 0x22, 0x22, 0x2b, 0xa8, 0xdd, 0x98, 0xd9, 0x2c, 0xc3, + 0x97, 0x15, 0x0b, 0x5c, 0xb1, 0x02, 0x58, 0x95, 0x8a, 0xf3, 0x4a, 0x65, 0xdb, 0xe8, 0xfd, 0x13, + 0xd1, 0x7b, 0xe8, 0xaf, 0x0b, 0x75, 0x8a, 0x5e, 0xa7, 0x4b, 0xe0, 0x93, 0x1a, 0x10, 0x22, 0x21, + 0xa5, 0x87, 0xc1, 0x60, 0xe2, 0x98, 0xc8, 0x33, 0x79, 0x64, 0x29, 0xd0, 0x6d, 0x20, 0x63, 0xca, + 0xfc, 0x48, 0x81, 0xc4, 0x8d, 0xf8, 0x5c, 0x9e, 0x68, 0xa9, 0xa6, 0x63, 0x31, 0x02, 0x54, 0x4a, + 0x7d, 0x2f, 0xc6, 0x68, 0x24, 0x9d, 0xee, 0xfb, 0x0c, 0x64, 0x00, 0x15, 0x01, 0xf2, 0xff, 0x10, + 0x5e, 0x18, 0x44, 0xd5, 0x0d, 0x00, 0x62, 0x63, 0xf1, 0x77, 0xb7, 0xc8, 0xc9, 0x2b, 0xe2, 0xb5, + 0x4b, 0x9e, 0x08, 0xbc, 0x51, 0x9d, 0xa2, 0xe2, 0x94, 0x26, 0x27, 0xe1, 0xf2, 0xaf, 0x1f, 0x71, + 0xb1, 0xb1, 0xf4, 0xe4, 0x00, 0x04, 0xef, 0x6e, 0xbf, 0xc1, 0x30, 0x4c, 0x13, 0xe2, 0x7d, 0x06, + 0x6b, 0x4d, 0x90, 0x10, 0x2e, 0x82, 0xa0, 0x33, 0xff, 0xa2, 0xba, 0x13, 0xa9, 0x3a, 0x25, 0x4b, + 0xd1, 0x35, 0x11, 0xd1, 0x5a, 0x2b, 0xa2, 0x39, 0xf5, 0xef, 0xae, 0x57, 0xd5, 0xef, 0x90, 0x72, + 0x0a, 0x34, 0x5c, 0x7f, 0x04, 0xf4, 0x97, 0x37, 0x5b, 0xda, 0xbb, 0xc5, 0xf0, 0x4a, 0x25, 0x7a, + 0x5c, 0xca, 0x98, 0x40, 0x43, 0x57, 0xe0, 0x93, 0xac, 0x45, 0xf0, 0xa1, 0x19, 0xd1, 0xb5, 0xe4, + 0x65, 0xb3, 0xc7, 0x93, 0x28, 0x45, 0x8d, 0x5f, 0x0f, 0x21, 0x34, 0x82, 0xfa, 0x6d, 0xf5, 0xbd, + 0xfe, 0x0a, 0x74, 0x66, 0x61, 0xf9, 0xb4, 0xdb, 0xf7, 0x26, 0xb7, 0x35, 0xf7, 0x3b, 0x2d, 0xb7, + 0xf0, 0x54, 0x51, 0xa6, 0xcf, 0x60, 0xdd, 0x81, 0x47, 0xd3, 0x3c, 0xef, 0xbf, 0x88, 0x1e, 0x2a, + 0xb9, 0x88, 0x70, 0xa8, 0xd8, 0x1f, 0x4d, 0x53, 0x08, 0x2f, 0xd4, 0x3b, 0xda, 0x79, 0x42, 0x20, + 0x75, 0xba, 0x51, 0x3b, 0x69, 0xae, 0x8b, 0xdf, 0x5a, 0x89, 0xea, 0xe4, 0xfd, 0x6a, 0xba, 0xc6, + 0xfa, 0xb1, 0x1b, 0xd1, 0x98, 0x8b, 0xe3, 0xc2, 0x4d, 0xea, 0xc0, 0x6e, 0x4a, 0x62, 0x98, 0x8f, + 0x52, 0x58, 0x9c, 0xf1, 0xa5, 0x78, 0xac, 0x4a, 0x18, 0x0b, 0xce, 0x71, 0xdd, 0x84, 0xf5, 0x2f, + 0x32, 0xce, 0x80, 0xa0, 0xeb, 0xec, 0xaa, 0xbd, 0x4c, 0x93, 0x72, 0x5f, 0xdc, 0xd9, 0xe1, 0x29, + 0x57, 0xb4, 0xcf, 0x40, 0xa4, 0x62, 0x4f, 0x25, 0x6b, 0xf3, 0x16, 0xaa, 0xbe, 0x14, 0xea, 0xa4, + 0x49, 0x95, 0x55, 0xea, 0xc1, 0xab, 0x8f, 0x2d, 0x6b, 0xe2, 0x01, 0x55, 0x6a, 0xa8, 0x64, 0xfa, + 0x5e, 0x96, 0xad, 0x7f, 0xf1, 0x37, 0xb2, 0xfb, 0xa2, 0x6c, 0xfe, 0x0c, 0xdd, 0x0f, 0x22, 0x5f, + 0x57, 0x01, 0x3e, 0xa9, 0xd2, 0xe8, 0x8f, 0x1d, 0xd1, 0x75, 0xe2, 0x0c, 0x4b, 0x73, 0x7e, 0x24, + 0x60, 0xe8, 0x83, 0xe2, 0x3c, 0x98, 0xdc, 0x45, 0xca, 0x54, 0xbc, 0x6d, 0xcf, 0x64, 0x28, 0x4a, + 0x27, 0xfc, 0x16, 0x11, 0x8d, 0x2a, 0xb4, 0x39, 0x63, 0xd5, 0xf1, 0x64, 0x3a, 0x98, 0x08, 0x95, + 0x9c, 0x04, 0x6f, 0x97, 0x3c, 0x5e, 0xf8, 0x29, 0x86, 0xab, 0x36, 0x76, 0x13, 0x6a, 0xf3, 0x09, + 0xd2, 0x63, 0xb7, 0xb1, 0xf3, 0x9c, 0xd8, 0x9a, 0x8e, 0xfb, 0x39, 0x18, 0x59, 0x5f, 0x14, 0x44, + 0x4c, 0x21, 0x9a, 0x9c, 0x31, 0x7e, 0x6d, 0x30, 0x1f, 0x8e, 0x29, 0xb0, 0x3d, 0x1a, 0x54, 0x7d, + 0x36, 0x0f, 0xf4, 0x12, 0x89, 0x1e, 0x3b, 0x6e, 0x1e, 0xee, 0x78, 0x62, 0xba, 0x3b, 0xd7, 0x42, + 0xf2, 0x8b, 0xe8, 0xa9, 0x61, 0xfe, 0x87, 0xb9, 0xf4, 0x10, 0xe3, 0xfe, 0x85, 0x4b, 0xeb, 0x91, + 0xc7, 0xe1, 0x22, 0x32, 0xe1, 0x9d, 0x1e, 0x88, 0x4e, 0x90, 0x6d, 0xfb, 0x88, 0x04, 0xe2, 0x14, + 0x9e, 0xb9, 0x88, 0x2a, 0x9f, 0xe2, 0xc4, 0xad, 0x12, 0xaa, 0xaa, 0xf9, 0x23, 0x66, 0xe3, 0x45, + 0x5d, 0x6e, 0x85, 0x46, 0xb1, 0xbc, 0x20, 0x4e, 0x16, 0x96, 0x79, 0x5b, 0x91, 0x2f, 0x6a, 0x5a, + 0x6f, 0xb3, 0x92, 0x4a, 0x2f, 0x09, 0x9d, 0xab, 0x1b, 0x4e, 0xff, 0xa2, 0xc5, 0x05, 0x9d, 0x58, + 0x2e, 0x08, 0x88, 0x5e, 0x72, 0x0b, 0xdf, 0xfc, 0x40, 0x2c, 0x22, 0xd5, 0x25, 0x5a, 0xab, 0xcf, + 0x9f, 0xf1, 0x23, 0x0c, 0xd1, 0xee, 0x2b, 0x08, 0x25, 0xc4, 0xc6, 0xa9, 0xd0, 0x43, 0xe3, 0xda, + 0x45, 0xdb, 0xc9, 0x13, 0xb2, 0x9b, 0x29, 0xb3, 0xc6, 0x5c, 0x28, 0xab, 0xe8, 0x82, 0x1d, 0xc9, + 0x4b, 0x67, 0xe4, 0xe1, 0xd0, 0x9b, 0xe2, 0x3f, 0x93, 0x4c, 0x95, 0x2d, 0xe3, 0x17, 0xe8, 0xca, + 0x62, 0x0c, 0xdf, 0x27, 0xf0, 0x4c, 0x2e, 0xdf, 0x8a, 0xa1, 0xe5, 0x5f, 0xff, 0x5e, 0xae, 0x43, + 0xdd, 0xfe, 0xac, 0x93, 0x94, 0xb5, 0x57, 0xf4, 0x5e, 0x85, 0x3a, 0x11, 0x94, 0x25, 0xd1, 0xba, + 0xb8, 0x26, 0x94, 0x45, 0x8c, 0xd8, 0xce, 0x66, 0x1b, 0xd0, 0x39, 0x2d, 0xf3, 0x6b, 0x55, 0xc1, + 0x08, 0xa3, 0xe5, 0xef, 0xf0, 0x4c, 0x51, 0x0f, 0xc5, 0x72, 0xfd, 0x84, 0xff, 0x16, 0x2c, 0xd7, + 0x69, 0xa4, 0xd3, 0xa6, 0xba, 0xbf, 0xd1, 0xe2, 0x40, 0x5d, 0x11, 0xa1, 0xce, 0x89, 0xab, 0xe8, + 0x5a, 0x74, 0x27, 0xa2, 0x33, 0xe8, 0x47, 0x57, 0x28, 0x85, 0xaf, 0x88, 0x47, 0x7a, 0xe0, 0xb3, + 0xc8, 0xd5, 0xab, 0x94, 0x40, 0xa2, 0x52, 0x54, 0x20, 0x7c, 0xff, 0xdf, 0xe1, 0x01, 0x19, 0x70, + 0x56, 0x84, 0x7e, 0xaa, 0xe8, 0x13, 0xe4, 0x8b, 0x12, 0x3c, 0x4b, 0xe3, 0x6e, 0xf8, 0xc3, 0x9b, + 0x71, 0xa4, 0x29, 0xaa, 0xa8, 0x5e, 0xdf, 0x5d, 0x5b, 0xd8, 0x2b, 0x66, 0x42, 0x3e, 0x7f, 0x82, + 0x13, 0xa6, 0x71, 0x01, 0x4f, 0xef, 0xab, 0xfd, 0x7a, 0xf8, 0xb3, 0xb8, 0xad, 0xdd, 0xc5, 0x62, + 0xb7, 0xf5, 0x67, 0xc1, 0x09, 0x1d, 0x77, 0x87, 0xba, 0xf4, 0x57, 0x30, 0x84, 0x32, 0x24, 0x59, + 0xf0, 0x84, 0xd0, 0xa3, 0xc8, 0x88, 0xc1, 0xaf, 0x27, 0xe2, 0x11, 0x5b, 0xe0, 0x8e, 0xb5, 0xf7, + 0xc1, 0x38, 0x80, 0xbd, 0x6e, 0x80, 0x46, 0x56, 0x46, 0x54, 0x1f, 0x68, 0xdf, 0xaf, 0x19, 0xbb, + 0xf7, 0xc3, 0xb2, 0x0a, 0x09, 0x58, 0xde, 0x3c, 0x74, 0x32, 0x27, 0x9e, 0x10, 0xca, 0xbc, 0xec, + 0xd0, 0x92, 0xc8, 0xf7, 0xd6, 0x87, 0xcb, 0xfa, 0x44, 0xfe, 0x14, 0xf1, 0x96, 0xcb, 0xcd, 0x81, + 0x32, 0xd5, 0xd4, 0x21, 0xb5, 0x36, 0x17, 0xd6, 0x5f, 0x92, 0x8d, 0x9e, 0x79, 0x43, 0xc1, 0x45, + 0x79, 0xb6, 0x5d, 0x48, 0x97, 0x57, 0xfb, 0x1a, 0xaa, 0xbf, 0x56, 0xae, 0xad, 0xf7, 0x93, 0x7f, + 0x57, 0xae, 0x41, 0x3b, 0xba, 0xe0, 0x88, 0x51, 0x48, 0x39, 0xe9, 0x39, 0x0c, 0xf4, 0x4e, 0x9f, + 0xa2, 0xf5, 0x75, 0x7a, 0xe5, 0x22, 0xd5, 0x7c, 0x29, 0x51, 0x75, 0x51, 0x71, 0x1c, 0x5d, 0x75, + 0xa1, 0xc6, 0xa9, 0xdf, 0x13, 0x58, 0x92, 0xc2, 0x65, 0xec, 0x8b, 0xd3, 0xf3, 0x1d, 0x52, 0x54, + 0xbc, 0x26, 0x22, 0xb5, 0x7b, 0xfc, 0x64, 0xb1, 0xa8, 0xae, 0xdc, 0xc4, 0xea, 0x81, 0x8f, 0x50, + 0x3c, 0xae, 0x8e, 0x12, 0x01, 0x1f, 0xc3, 0xf8, 0xc2, 0x9f, 0x9e, 0xb6, 0xbd, 0xeb, 0x15, 0xef, + 0xc7, 0xd5, 0x84, 0x18, 0xfa, 0xbf, 0xec, 0x91, 0xcc, 0xa7, 0x88, 0x84, 0xed, 0x08, 0x68, 0xad, + 0xe7, 0xfb, 0x1f, 0x10, 0x85, 0xbf, 0xc1, 0x19, 0x1f, 0x2b, 0x0c, 0x7c, 0x12, 0x76, 0x9d, 0xbe, + 0x0b, 0x8b, 0x47, 0x25, 0x13, 0xdf, 0xf5, 0xd1, 0x6a, 0x4e, 0x84, 0x31, 0x0f, 0x74, 0x58, 0xaf, + 0xad, 0x57, 0x14, 0x67, 0xa5, 0x34, 0x3f, 0x82, 0xeb, 0xba, 0x6f, 0x3b, 0x34, 0x37, 0x3e, 0x08, + 0x48, 0xb4, 0xbd, 0xf0, 0x4d, 0x11, 0xc9, 0x17, 0x6c, 0x5c, 0x8a, 0x16, 0x53, 0xf8, 0x80, 0x47, + 0x5b, 0xdf, 0xc4, 0x02, 0xa9, 0x98, 0x4f, 0x45, 0xaa, 0x89, 0xd0, 0x49, 0xa1, 0x37, 0xcf, 0xf1, + 0xd6, 0x24, 0x70, 0xa0, 0x3b, 0xe9, 0xa4, 0x46, 0x69, 0x93, 0x2c, 0x37, 0x7d, 0xb6, 0x82, 0x3d, + 0xf3, 0xfe, 0x33, 0x97, 0xa7, 0xe3, 0x63, 0x47, 0x95, 0x86, 0x3e, 0x93, 0xa4, 0xb8, 0xc1, 0x6a, + 0xaf, 0x56, 0xa9, 0x2a, 0xd6, 0xd3, 0xf8, 0x80, 0x4d, 0xb4, 0x8d, 0xa4, 0x86, 0x94, 0x8a, 0x36, + 0xf1, 0x08, 0x8f, 0xf5, 0x7a, 0xee, 0xf7, 0xbe, 0x5f, 0x35, 0x3c, 0x5c, 0xbc, 0x57, 0x4d, 0xb5, + 0xa5, 0x89, 0x12, 0x0a, 0x2a, 0xa9, 0x78, 0xcc, 0x01, 0xfe, 0x09, 0x77, 0xbb, 0xbf, 0xdf, 0x04, + 0xd1, 0xd6, 0x8b, 0xd0, 0x9d, 0xdd, 0xe2, 0xf9, 0x0d, 0x11, 0x51, 0xf9, 0x09, 0x9f, 0xc4, 0xf4, + 0x2f, 0xa7, 0xeb, 0x51, 0xbc, 0x38, 0x46, 0x3c, 0xd0, 0x96, 0x4f, 0x47, 0xfe, 0x59, 0xab, 0xa7, + 0xf4, 0x7f, 0xbe, 0x12, 0x94, 0xdc, 0x01, 0x16, 0x8f, 0x46, 0x37, 0x9d, 0x3b, 0xf8, 0x2a, 0x14, + 0xa6, 0x63, 0x4d, 0xb5, 0x51, 0x8f, 0x1b, 0x09, 0x69, 0x81, 0x38, 0x47, 0xdc, 0x40, 0x64, 0x28, + 0x70, 0x91, 0x74, 0xd3, 0xbf, 0x93, 0x40, 0x60, 0x20, 0x3a, 0x3a, 0x1b, 0xc3, 0x01, 0x92, 0xc6, + 0x36, 0xa2, 0xec, 0x53, 0xe5, 0xf8, 0x2c, 0xa9, 0x0e, 0xa1, 0xe9, 0x36, 0xa6, 0xfc, 0xd7, 0xde, + 0x24, 0x29, 0x35, 0x0c, 0x42, 0x68, 0xb9, 0xb0, 0x28, 0x9b, 0x42, 0xaf, 0x93, 0x29, 0x81, 0x5d, + 0x09, 0x41, 0x7b, 0xe1, 0x4b, 0xbe, 0x76, 0x2f, 0x74, 0xf7, 0xbe, 0xe7, 0x53, 0xe0, 0x87, 0x74, + 0x91, 0x7f, 0x88, 0x82, 0xd3, 0x95, 0x8b, 0x32, 0xa9, 0x34, 0x51, 0x26, 0xd7, 0x7d, 0xe9, 0x57, + 0x88, 0x09, 0x4d, 0x04, 0xc6, 0xa1, 0x19, 0x42, 0xea, 0x1e, 0x76, 0x54, 0x7c, 0x20, 0x14, 0xa1, + 0x2a, 0x2e, 0x55, 0x08, 0x37, 0x7f, 0x0c, 0xe0, 0x80, 0x43, 0xc2, 0x3b, 0x53, 0x07, 0x5b, 0x1d, + 0xff, 0x04, 0x84, 0x3d, 0x9d, 0x0e, 0xdf, 0x04, 0xfc, 0x8c, 0xaa, 0x1a, 0x07, 0x7a, 0xf8, 0x29, + 0x2d, 0xbb, 0x66, 0x63, 0xcb, 0x97, 0x6f, 0xff, 0x82, 0x11, 0x26, 0x20, 0xaa, 0x4a, 0xcf, 0x82, + 0x92, 0x5e, 0xf5, 0x53, 0x63, 0xb1, 0x99, 0xae, 0x6b, 0xfc, 0x16, 0x0c, 0x1b, 0xb1, 0xec, 0xa4, + 0xbb, 0x86, 0xad, 0xd5, 0x1d, 0x67, 0x6b, 0xfc, 0xc7, 0x0b, 0xa8, 0x2d, 0x13, 0x4d, 0x7e, 0x0b, + 0x2f, 0xd8, 0xdd, 0xbc, 0xbe, 0xcb, 0xed, 0xf8, 0x88, 0x2c, 0x39, 0x71, 0x03, 0x15, 0xbb, 0x18, + 0xc8, 0xe2, 0x42, 0x80, 0x67, 0x34, 0x26, 0x7c, 0x72, 0x62, 0x5b, 0x4e, 0xbc, 0x14, 0xc8, 0x76, + 0x9f, 0x0f, 0x35, 0x63, 0xea, 0xb9, 0xc6, 0x46, 0x7f, 0x29, 0x3b, 0x10, 0x73, 0xcf, 0x70, 0xb7, + 0xd5, 0xc2, 0x82, 0x1a, 0x77, 0x66, 0x33, 0x63, 0xcf, 0x0d, 0xce, 0xcd, 0x86, 0x8c, 0xfa, 0x9d, + 0x78, 0xd2, 0x26, 0x70, 0xf3, 0x8a, 0xd2, 0x36, 0x10, 0x87, 0xc9, 0xa9, 0x1d, 0x31, 0xe0, 0xe7, + 0x1c, 0x00, 0xa7, 0xd2, 0x46, 0xa8, 0xbf, 0xc2, 0x91, 0xc9, 0xb6, 0xad, 0x44, 0xc5, 0x2c, 0x68, + 0xe0, 0xd4, 0xeb, 0x34, 0x9e, 0x80, 0xdb, 0x45, 0xc7, 0xad, 0xa1, 0xa8, 0xbe, 0xb1, 0x4d, 0xd1, + 0x58, 0x85, 0x38, 0x2f, 0x33, 0x3d, 0x06, 0xfa, 0xa2, 0x58, 0xda, 0x0b, 0xeb, 0xfe, 0x1f, 0x38, + 0xf8, 0x81, 0x7c, 0x6d, 0x0f, 0x5a, 0xd0, 0xd6, 0x5a, 0xb3, 0x4b, 0x5d, 0x8a, 0x8c, 0x7f, 0xfc, + 0xa5, 0x20, 0x20, 0x0b, 0x12, 0xe3, 0x09, 0x74, 0x78, 0xf3, 0x72, 0x51, 0x90, 0xbc, 0x19, 0xa0, + 0x5a, 0x67, 0xfe, 0x24, 0x86, 0x18, 0x80, 0x7a, 0x7e, 0x14, 0x38, 0xf8, 0xe8, 0xd6, 0xb6, 0xa9, + 0x3d, 0x9e, 0xf4, 0x92, 0x8a, 0x67, 0xb0, 0x43, 0x37, 0x39, 0x6f, 0xdf, 0x15, 0x9b, 0x69, 0x11, + 0x47, 0x40, 0x2e, 0x20, 0x11, 0x45, 0xc5, 0xcd, 0x49, 0x4c, 0xbc, 0x23, 0xbb, 0x95, 0x43, 0x65, + 0x50, 0xdb, 0x79, 0xcb, 0x16, 0x7b, 0x8f, 0x63, 0x88, 0x0a, 0x77, 0x6b, 0x1d, 0xc5, 0xe7, 0x8e, + 0x3a, 0x67, 0x0c, 0x07, 0xfc, 0x44, 0x13, 0x1c, 0x63, 0x3e, 0xd8, 0xe6, 0xc6, 0x9d, 0x0e, 0xf8, + 0x2c, 0x21, 0x14, 0x26, 0x55, 0xfb, 0xbb, 0x52, 0x6c, 0x53, 0xc8, 0x60, 0x3d, 0xc4, 0x42, 0x85, + 0x80, 0x37, 0x28, 0x60, 0x31, 0xb6, 0x49, 0x35, 0x76, 0x40, 0xa6, 0x37, 0x96, 0x34, 0x39, 0xee, + 0x63, 0xfe, 0x11, 0x05, 0x84, 0xdb, 0x43, 0xb3, 0xe5, 0x23, 0x0d, 0xc5, 0xa0, 0x76, 0x3b, 0x03, + 0x01, 0xfb, 0x88, 0x82, 0x62, 0xa9, 0x08, 0x35, 0x73, 0xfb, 0xe5, 0xc4, 0x08, 0x08, 0x72, 0x43, + 0x77, 0x15, 0xa6, 0xbf, 0x8c, 0x2a, 0x24, 0x48, 0x91, 0x0e, 0x55, 0xea, 0xee, 0x9d, 0x24, 0x53, + 0x98, 0xae, 0x0a, 0xb7, 0x7a, 0x1c, 0xae, 0x4c, 0x81, 0x80, 0xf5, 0x7f, 0x8e, 0x1d, 0x97, 0xb7, + 0x46, 0xc8, 0xa9, 0x6e, 0xef, 0xe2, 0x04, 0x9e, 0x07, 0xcb, 0xdb, 0xdf, 0x01, 0x5b, 0x48, 0x3e, + 0x0a, 0xad, 0xbf, 0x60, 0xc3, 0x6e, 0xec, 0x19, 0x46, 0x92, 0x79, 0xbe, 0xf8, 0xa3, 0xc6, 0xf4, + 0xbc, 0x3b, 0x23, 0x5e, 0x01, 0x78, 0x53, 0x7c, 0x8a, 0xdb, 0x08, 0x78, 0x47, 0x36, 0xb0, 0x32, + 0x00, 0x09, 0x14, 0x0a, 0x72, 0x55, 0x21, 0xb0, 0x63, 0x54, 0xf8, 0x53, 0x4c, 0xc4, 0x39, 0x99, + 0x2d, 0x51, 0x3e, 0xcd, 0x7d, 0x74, 0xba, 0x01, 0x3f, 0x1d, 0x27, 0xf8, 0x2c, 0x22, 0x4f, 0x8a, + 0x59, 0x74, 0xbb, 0x0e, 0xba, 0xa9, 0x22, 0xef, 0x85, 0xc4, 0x0c, 0xd9, 0xa0, 0x79, 0x9b, 0x1b, + 0x13, 0x3a, 0x28, 0xb0, 0x7f, 0x5f, 0xfc, 0x29, 0x60, 0xd0, 0x48, 0x92, 0xfc, 0xc3, 0x4a, 0x0d, + 0xdb, 0xd4, 0xbb, 0x81, 0x6e, 0x4a, 0xc1, 0x01, 0x61, 0x46, 0xa9, 0x8a, 0x80, 0xb2, 0xf8, 0x24, + 0x39, 0x4b, 0x8c, 0x35, 0xb5, 0x56, 0xa6, 0xea, 0xdf, 0x56, 0x93, 0xab, 0x57, 0x44, 0x79, 0xfa, + 0xb4, 0xbc, 0xde, 0x68, 0xf8, 0xd9, 0x8b, 0xe3, 0xc3, 0x45, 0xa1, 0x85, 0x80, 0xf9, 0xf6, 0xe8, + 0xf6, 0x55, 0x6c, 0x6a, 0x2c, 0x64, 0x38, 0xa5, 0xc7, 0xff, 0xc1, 0x55, 0xaa, 0x7a, 0x98, 0x0b, + 0x61, 0x8e, 0x83, 0x82, 0x7f, 0xf9, 0x7c, 0x71, 0x63, 0xdf, 0x8a, 0xd1, 0xa9, 0xcd, 0x85, 0x63, + 0xf0, 0x53, 0xaa, 0x6d, 0xca, 0x9a, 0x4a, 0xad, 0x53, 0x56, 0x7f, 0x5e, 0x20, 0x15, 0x91, 0x3c, + 0x72, 0xdf, 0x48, 0x37, 0x52, 0xc6, 0x3b, 0xc4, 0x85, 0x29, 0x35, 0x18, 0x2b, 0x12, 0xc7, 0x7f, + 0x9e, 0xaa, 0xaa, 0xfe, 0x24, 0x45, 0xb4, 0xc6, 0x1d, 0x56, 0xa3, 0x4a, 0xb0, 0x7c, 0x40, 0x52, + 0xcc, 0xbb, 0x32, 0x70, 0xb5, 0x58, 0x18, 0x0b, 0x6b, 0x59, 0xba, 0x02, 0x77, 0x89, 0x08, 0x1e, + 0x92, 0x37, 0x48, 0xdb, 0xee, 0xc2, 0xdd, 0x21, 0xd0, 0x00, 0x09, 0xf0, 0x00, 0x0c, 0xb0, 0x82, + 0x36, 0x42, 0xa0, 0x9a, 0x30, 0xf8, 0x81, 0x00, 0xb2, 0xae, 0xe3, 0x04, 0x13, 0x45, 0x03, 0xf0, + 0x15, 0x37, 0x26, 0xb1, 0x25, 0x07, 0xac, 0x8e, 0x5a, 0x02, 0x48, 0xef, 0x88, 0x35, 0x32, 0xf3, + 0x8e, 0x47, 0xe0, 0xb0, 0x88, 0x72, 0x38, 0x06, 0x37, 0x94, 0x84, 0xc6, 0x35, 0x31, 0xb4, 0x61, + 0x86, 0xff, 0x18, 0x5e, 0x3e, 0x10, 0x1a, 0x47, 0x52, 0x30, 0xf4, 0x72, 0x8d, 0x39, 0x8a, 0xad, + 0x63, 0xd8, 0x14, 0x65, 0x33, 0x96, 0x68, 0x0a, 0x36, 0x33, 0x78, 0x91, 0x00, 0xab, 0x56, 0xfd, + 0x69, 0x77, 0x27, 0x46, 0xef, 0x57, 0xe7, 0x07, 0x14, 0x60, 0xbf, 0x12, 0x24, 0x95, 0x5d, 0x71, + 0x76, 0xe9, 0x25, 0x15, 0xbd, 0x70, 0x4e, 0x48, 0xf2, 0x61, 0x8f, 0x1f, 0xa9, 0xe8, 0x76, 0x2a, + 0xf8, 0x28, 0xea, 0xc6, 0x2b, 0x30, 0x40, 0xba, 0xb1, 0xa0, 0x9b, 0xe0, 0xb4, 0xae, 0x54, 0x4d, + 0x50, 0x11, 0x41, 0x00, 0x98, 0xf5, 0x2a, 0x02, 0x7f, 0x82, 0xbb, 0x97, 0x1d, 0x58, 0x37, 0x8d, + 0x4d, 0x1b, 0x30, 0x0e, 0xff, 0xb7, 0x7f, 0x9f, 0x0a, 0x46, 0x41, 0xa0, 0xf1, 0x61, 0xc7, 0xe1, + 0x2e, 0x2f, 0x48, 0x6d, 0x06, 0xd3, 0x54, 0x2a, 0xc8, 0x2c, 0xda, 0xbf, 0xc2, 0x85, 0x38, 0x60, + 0xc0, 0xd0, 0xa9, 0xc2, 0x51, 0x1a, 0xdc, 0x75, 0x27, 0x8e, 0xd2, 0x80, 0xd2, 0x6e, 0x9a, 0xb3, + 0xb8, 0x47, 0xfb, 0x8f, 0xff, 0x05, 0x57, 0x40, 0xd2, 0x61, 0x42, 0x3d, 0x2f, 0x28, 0x23, 0xd3, + 0x46, 0x60, 0x80, 0x4c, 0x6e, 0x9f, 0x7c, 0x13, 0x12, 0xbb, 0x68, 0x2a, 0x4b, 0xe5, 0xf0, 0x47, + 0xaa, 0x54, 0xff, 0x04, 0xa2, 0xa4, 0xaa, 0xf5, 0x0d, 0x03, 0xe0, 0x7b, 0x46, 0x83, 0x8f, 0xf0, + 0xa1, 0x68, 0x90, 0x1b, 0x5b, 0x9a, 0x7b, 0x3c, 0x6c, 0x6e, 0xa7, 0x96, 0x12, 0x99, 0xcf, 0x64, + 0xce, 0xa8, 0xad, 0xf0, 0x89, 0xec, 0x34, 0x9b, 0x41, 0x0d, 0x1e, 0x7d, 0xaa, 0x3b, 0x8c, 0xea, + 0xf1, 0x7c, 0xa2, 0x17, 0x7f, 0x0a, 0x69, 0xbc, 0x6d, 0x33, 0x6d, 0x5d, 0x41, 0x11, 0x32, 0xb6, + 0x92, 0xf0, 0x42, 0x6b, 0x2d, 0x71, 0xc8, 0x3e, 0x0a, 0x4a, 0x80, 0x8e, 0x62, 0x6c, 0xe3, 0xb9, + 0x5e, 0x54, 0x3d, 0xfe, 0x65, 0xd5, 0x3a, 0x10, 0x52, 0x75, 0xb7, 0xbb, 0xe6, 0x93, 0xff, 0x11, + 0x34, 0xad, 0x6d, 0x37, 0xf7, 0x5d, 0x5a, 0xf2, 0x59, 0x3d, 0x03, 0x5f, 0x85, 0x04, 0x28, 0x9f, + 0xe3, 0x86, 0x15, 0xc2, 0xdd, 0x32, 0x69, 0x22, 0xad, 0xcc, 0xf7, 0xa4, 0x9f, 0xc4, 0x0c, 0x12, + 0x10, 0xbf, 0x85, 0x16, 0x60, 0x7b, 0x2a, 0x3a, 0x28, 0x46, 0xf0, 0xb7, 0x08, 0x6a, 0x6f, 0xdd, + 0xdf, 0x84, 0x05, 0xf6, 0x93, 0xa9, 0x98, 0xfc, 0x74, 0x36, 0x35, 0x11, 0xdb, 0x76, 0xc7, 0x7d, + 0x57, 0x13, 0x05, 0x3d, 0x51, 0x93, 0x2a, 0x8d, 0xc1, 0x00, 0x58, 0x01, 0x4e, 0x24, 0x3f, 0xfc, + 0x48, 0x2a, 0xd3, 0x28, 0x16, 0x3d, 0x1c, 0x96, 0x7a, 0x2b, 0xf2, 0x2f, 0xbe, 0x13, 0x2e, 0x70, + 0x01, 0x69, 0x53, 0x1e, 0x08, 0x5f, 0x7e, 0x8c, 0x48, 0x90, 0x57, 0x94, 0x10, 0x1a, 0x4c, 0x0b, + 0x98, 0x77, 0xc5, 0x4d, 0x0c, 0x60, 0x68, 0x9f, 0xf8, 0x81, 0x98, 0x51, 0x64, 0xfe, 0x36, 0x64, + 0xeb, 0x6b, 0xd1, 0xc0, 0x0d, 0xa6, 0xdb, 0x54, 0x7e, 0x08, 0x7d, 0x63, 0xe7, 0x7f, 0xab, 0xfc, + 0x10, 0xdc, 0x56, 0xef, 0x2f, 0x97, 0xba, 0x5e, 0x0b, 0x0d, 0xc8, 0xc6, 0x8c, 0xb8, 0xd9, 0x7c, + 0xfb, 0xe0, 0xa4, 0xb6, 0x24, 0x8b, 0x20, 0xc3, 0xb8, 0xfb, 0xf1, 0x5d, 0xfe, 0x14, 0xe8, 0xcb, + 0xed, 0x1c, 0xd5, 0x10, 0x86, 0x8c, 0x1e, 0x12, 0xe3, 0xe0, 0xf1, 0x83, 0x67, 0x38, 0x73, 0x8d, + 0xf0, 0x4b, 0x79, 0x36, 0x3a, 0x03, 0x06, 0x06, 0xe4, 0x8a, 0xd2, 0x18, 0xf8, 0x50, 0xa4, 0x92, + 0xe6, 0xf7, 0x53, 0xa7, 0x99, 0xe3, 0xd4, 0x6e, 0xdc, 0xec, 0x42, 0xcb, 0x1d, 0xf8, 0x50, 0xae, + 0xde, 0x8b, 0x32, 0xd6, 0x63, 0xb2, 0x52, 0xae, 0x92, 0xd9, 0x9d, 0x3e, 0x0a, 0x4d, 0x3b, 0x52, + 0x82, 0xd5, 0x68, 0x42, 0xa1, 0x12, 0x5b, 0xfc, 0x10, 0x95, 0x5d, 0x1d, 0x2a, 0xf1, 0x24, 0x15, + 0xf9, 0x54, 0x4f, 0x8b, 0x87, 0x85, 0x59, 0xa4, 0x25, 0x4d, 0x12, 0x54, 0x68, 0x2a, 0xf2, 0x87, + 0x66, 0x47, 0x27, 0x12, 0xa6, 0x3a, 0x97, 0x80, 0xbf, 0xc3, 0xb0, 0xe4, 0xdb, 0x56, 0x14, 0x58, + 0x18, 0x17, 0xc9, 0x60, 0x73, 0xa7, 0xb2, 0xa0, 0x4a, 0x1a, 0xbc, 0xb9, 0x87, 0x28, 0x62, 0xa6, + 0xe9, 0x9e, 0x5f, 0xe1, 0xf2, 0xca, 0xf1, 0xe4, 0xfe, 0x99, 0xd9, 0xec, 0x64, 0x67, 0xe9, 0x04, + 0x0d, 0x6a, 0xcf, 0x8a, 0xea, 0xf5, 0xd5, 0xe6, 0xea, 0xf5, 0xd1, 0x5e, 0xb8, 0x7c, 0xd2, 0xb1, + 0x43, 0x6b, 0x4a, 0x77, 0xb2, 0xd7, 0x73, 0x57, 0xfc, 0x3a, 0x42, 0x86, 0x5c, 0x10, 0x12, 0x02, + 0x0a, 0x94, 0xc3, 0x94, 0x51, 0x39, 0x2e, 0xb4, 0xd8, 0x9d, 0x42, 0xf5, 0x56, 0x26, 0xa8, 0xff, + 0xc2, 0x22, 0x52, 0x38, 0x60, 0x65, 0x81, 0xc1, 0x01, 0x54, 0x3b, 0xe8, 0x98, 0xbc, 0x14, 0xc3, + 0x2e, 0x4a, 0x17, 0xd3, 0x34, 0x9a, 0x6d, 0x75, 0xf0, 0xa1, 0xd0, 0x48, 0xb0, 0x89, 0x83, 0xb4, + 0x99, 0xb1, 0xe9, 0x06, 0x52, 0x31, 0xfa, 0x48, 0x2b, 0x23, 0xef, 0x7c, 0xa4, 0xbb, 0x2f, 0x84, + 0x2d, 0x29, 0x28, 0xcd, 0x59, 0x54, 0x0e, 0x7c, 0x7f, 0x10, 0x20, 0x28, 0x65, 0x74, 0x17, 0x9c, + 0xd9, 0x35, 0x5a, 0xd7, 0xbc, 0x22, 0x0a, 0x32, 0xeb, 0xe7, 0x49, 0x2b, 0x1e, 0xf8, 0x50, 0x49, + 0xbe, 0x50, 0x00, 0x1a, 0x07, 0x37, 0x58, 0xeb, 0xc2, 0x40, 0x7a, 0x6f, 0x1e, 0x02, 0xaf, 0xac, + 0x21, 0x6f, 0xf8, 0x8d, 0x78, 0x88, 0x50, 0xa1, 0x4e, 0x4e, 0xf5, 0x9f, 0xa2, 0x85, 0xe3, 0x91, + 0x98, 0x4a, 0x68, 0x82, 0xd9, 0x42, 0x90, 0x95, 0x11, 0x7a, 0xc5, 0x91, 0xdb, 0x89, 0x10, 0x14, + 0xab, 0x1a, 0x6b, 0x92, 0xb3, 0x95, 0x8b, 0xd9, 0xc4, 0x36, 0x91, 0xde, 0x11, 0x31, 0xc3, 0xc5, + 0xa0, 0x1f, 0x71, 0x31, 0xc6, 0x40, 0xe5, 0xa4, 0xae, 0x2b, 0x01, 0xe5, 0xcc, 0x50, 0xdd, 0xa7, + 0x23, 0x90, 0x10, 0x1f, 0x04, 0xc5, 0x4e, 0x6a, 0x34, 0x30, 0x3a, 0x3c, 0x71, 0xdf, 0xf0, 0x53, + 0xb2, 0xf1, 0xc8, 0x96, 0x4d, 0xe4, 0x14, 0xa2, 0x17, 0x04, 0x03, 0xa0, 0xae, 0x01, 0x97, 0xd7, + 0xdc, 0x44, 0x29, 0xdf, 0xac, 0x18, 0x8c, 0x7e, 0xda, 0x89, 0x58, 0x43, 0x7b, 0x0d, 0xe9, 0x95, + 0xae, 0xf0, 0x68, 0x60, 0x8c, 0x77, 0xc1, 0x5d, 0xbd, 0x95, 0x8b, 0x7f, 0x25, 0x47, 0x45, 0xe4, + 0x16, 0xb2, 0xef, 0xf0, 0x5c, 0x47, 0x10, 0xc1, 0xcb, 0x74, 0xd7, 0xdf, 0x2c, 0xb8, 0xff, 0x94, + 0xd3, 0x34, 0xa4, 0x1a, 0xbc, 0x60, 0xb3, 0xa3, 0x80, 0x41, 0x87, 0x78, 0x6b, 0x05, 0x29, 0x45, + 0x8d, 0xc2, 0x8b, 0x4d, 0x99, 0xed, 0x0e, 0x70, 0xf5, 0x41, 0xed, 0x3c, 0x61, 0x04, 0x34, 0x7e, + 0x29, 0x95, 0x59, 0x79, 0xd9, 0x60, 0x42, 0xbe, 0x62, 0x9d, 0x52, 0x37, 0x98, 0xa3, 0xad, 0xf9, + 0x5f, 0x8c, 0xfc, 0xec, 0x25, 0x76, 0x25, 0xee, 0x7b, 0x81, 0x1f, 0x29, 0x63, 0xb3, 0xdc, 0x2d, + 0x96, 0xdf, 0xc2, 0x85, 0x1f, 0xe4, 0x48, 0x52, 0x11, 0x8b, 0xc8, 0x7d, 0x20, 0x91, 0x1f, 0x5b, + 0x01, 0xf2, 0xb8, 0xc7, 0xcb, 0xa7, 0xbf, 0x0b, 0x65, 0xb0, 0xb0, 0xf6, 0xad, 0xdb, 0x71, 0x94, + 0xa1, 0xe1, 0x4b, 0xda, 0x3e, 0xeb, 0x86, 0xc2, 0x2b, 0xcb, 0x0c, 0x0a, 0xee, 0x4a, 0xbc, 0xe1, + 0x7d, 0x10, 0xc0, 0xd6, 0x52, 0x70, 0x31, 0xdb, 0xe1, 0x4d, 0x84, 0x36, 0x28, 0xb7, 0x2b, 0x05, + 0x32, 0xe3, 0x39, 0x84, 0x14, 0x0e, 0x38, 0x93, 0x24, 0x13, 0x06, 0xf1, 0x01, 0x97, 0xd7, 0x5f, + 0x58, 0xff, 0x05, 0x45, 0xa1, 0xbc, 0x94, 0x4f, 0x8e, 0xd8, 0xf5, 0xf1, 0xc4, 0x4b, 0x6e, 0xb2, + 0x28, 0x72, 0x8a, 0x95, 0x3f, 0x04, 0x06, 0x28, 0xb3, 0xf1, 0xd6, 0xd2, 0x7e, 0x89, 0xf3, 0xa0, + 0xd6, 0xd8, 0x6d, 0xd6, 0xaa, 0x58, 0x7f, 0xe3, 0x48, 0xc8, 0xd9, 0x6b, 0x8e, 0x83, 0x60, 0x91, + 0xfc, 0x36, 0x80, 0x73, 0xe2, 0x1e, 0xc1, 0xd4, 0x08, 0xa6, 0x15, 0xae, 0x8e, 0x6b, 0xc6, 0x1a, + 0x27, 0x1d, 0x4b, 0x2f, 0xd3, 0xf0, 0x52, 0x76, 0x06, 0x32, 0x2a, 0x9c, 0x47, 0xa0, 0x66, 0x2a, + 0x1b, 0xcf, 0x4c, 0x3a, 0xa0, 0xf3, 0x4a, 0xa4, 0x12, 0x54, 0x27, 0xab, 0x46, 0x72, 0xea, 0x97, + 0xc6, 0x0c, 0x70, 0xda, 0x0a, 0xae, 0xf8, 0x58, 0x6c, 0x87, 0xec, 0x6d, 0xa5, 0x06, 0xf7, 0xf1, + 0x85, 0x0f, 0xa2, 0xec, 0xc0, 0x4a, 0x11, 0x75, 0x6b, 0xa9, 0xb7, 0x43, 0x64, 0xbf, 0x82, 0xb3, + 0xa7, 0x4c, 0x75, 0x4c, 0x46, 0x0c, 0xd9, 0x53, 0x4a, 0x9a, 0x7d, 0xf7, 0x37, 0x87, 0x6d, 0x7f, + 0xe0, 0x88, 0xbb, 0x6d, 0x14, 0x3f, 0x85, 0x2d, 0x27, 0xac, 0xd0, 0x26, 0x48, 0xfb, 0x74, 0x1d, + 0x94, 0x9f, 0xfa, 0xe3, 0x3a, 0x06, 0x68, 0x1d, 0x9f, 0x37, 0x6a, 0x36, 0x7a, 0xaf, 0x11, 0x0a, + 0x08, 0x10, 0xd1, 0xf3, 0x90, 0x75, 0x3f, 0xd6, 0x6b, 0x9e, 0x17, 0x9f, 0x89, 0x12, 0x34, 0x5e, + 0xba, 0xd6, 0x0c, 0x15, 0x65, 0x88, 0x7d, 0x7a, 0x84, 0x0c, 0x1b, 0x1e, 0x3a, 0xda, 0xa5, 0x60, + 0xc4, 0xe1, 0xbb, 0xba, 0xd7, 0xf1, 0x10, 0xa6, 0x8c, 0xb4, 0x65, 0xa3, 0x63, 0x7b, 0x37, 0x7a, + 0xcd, 0xd5, 0x00, 0x08, 0xd1, 0xce, 0xb1, 0x42, 0x59, 0x8f, 0x3d, 0xb8, 0x89, 0x2e, 0xe2, 0x04, + 0x82, 0xc2, 0x53, 0x4c, 0x57, 0x95, 0xb7, 0x07, 0x8c, 0xd0, 0xec, 0xf2, 0xe2, 0x3c, 0x44, 0x28, + 0x56, 0xac, 0x65, 0xe8, 0xc8, 0x5a, 0xec, 0xe4, 0x17, 0x10, 0xac, 0xe9, 0xb8, 0xce, 0x45, 0xe7, + 0x13, 0x05, 0x5f, 0x19, 0x37, 0x3b, 0x4e, 0xc3, 0x46, 0x16, 0x21, 0x6a, 0x81, 0xd4, 0xcd, 0x00, + 0xc7, 0xf8, 0x46, 0xab, 0xd2, 0x0e, 0xae, 0xed, 0x83, 0xfd, 0xf9, 0xc6, 0x8c, 0x08, 0x07, 0x88, + 0x05, 0x02, 0x1f, 0x6c, 0x66, 0x63, 0x5f, 0xfe, 0x20, 0x28, 0x77, 0x4a, 0xab, 0x49, 0x5e, 0xf5, + 0x4e, 0x84, 0xff, 0x04, 0x86, 0x57, 0xb6, 0xff, 0x0a, 0x14, 0xfe, 0xc4, 0xb9, 0x6c, 0x37, 0x22, + 0xa8, 0xab, 0x2f, 0x3f, 0x7c, 0x34, 0x0c, 0xaa, 0x1b, 0xbe, 0xf8, 0x2a, 0x9d, 0x2b, 0x54, 0x6d, + 0xec, 0x51, 0xd4, 0x8b, 0x52, 0xdd, 0xbe, 0x33, 0x7a, 0x06, 0x35, 0x73, 0xdd, 0x8f, 0x9d, 0xb7, + 0x64, 0xff, 0x0a, 0x1e, 0xfa, 0x48, 0x93, 0x4b, 0x12, 0x8c, 0xf5, 0x87, 0xe1, 0x8f, 0x91, 0xec, + 0x6f, 0x48, 0x4d, 0xaa, 0x10, 0x7d, 0xf8, 0xb9, 0xd2, 0x5a, 0x9e, 0x03, 0x39, 0x1c, 0x1f, 0x82, + 0x52, 0x16, 0xcb, 0x7d, 0x9f, 0x0e, 0xab, 0xdb, 0xe3, 0x0a, 0x64, 0x43, 0xa3, 0xd9, 0x12, 0xe4, + 0x31, 0x8f, 0x6c, 0x25, 0x71, 0xc1, 0x6d, 0x10, 0x92, 0x3a, 0x2d, 0x28, 0x0e, 0x46, 0x0a, 0x21, + 0x3d, 0x3a, 0xf2, 0x62, 0x02, 0xf0, 0x44, 0x44, 0x1b, 0x58, 0x22, 0x6f, 0x8f, 0x7c, 0x13, 0x74, + 0xd2, 0x2e, 0x56, 0xab, 0xdf, 0x04, 0x7a, 0xd9, 0xf7, 0xc2, 0x85, 0xbd, 0xa3, 0xda, 0xe8, 0x65, + 0xa6, 0xe6, 0x9c, 0x8b, 0xa2, 0x6a, 0xdd, 0xf0, 0x53, 0xdd, 0xec, 0x72, 0x47, 0x58, 0xf3, 0x1e, + 0xf8, 0x2a, 0x9d, 0xdd, 0x43, 0x69, 0x48, 0xc7, 0x21, 0xaa, 0xe1, 0x86, 0x06, 0xa3, 0x86, 0x8e, + 0xfc, 0x22, 0x31, 0x01, 0x5b, 0x40, 0x9b, 0x62, 0xcd, 0x4f, 0x54, 0xf6, 0xf6, 0x5e, 0x14, 0x8d, + 0x99, 0x7a, 0x26, 0x76, 0x0a, 0xc6, 0x06, 0x5c, 0xa7, 0x9f, 0x9a, 0xbb, 0x19, 0x14, 0xa6, 0x7e, + 0x34, 0xe3, 0x91, 0xbd, 0x15, 0xbd, 0xa2, 0x82, 0x12, 0xe5, 0x02, 0x58, 0x28, 0x97, 0x17, 0x39, + 0x4e, 0x4a, 0xb2, 0xf1, 0xfc, 0x9d, 0x5c, 0xbc, 0x68, 0xa4, 0xa9, 0xb4, 0x50, 0x48, 0x25, 0xd0, + 0xd1, 0x65, 0xc1, 0x8e, 0x61, 0xfc, 0xec, 0x6d, 0x9d, 0x88, 0x4c, 0x3e, 0xe0, 0xf5, 0x0d, 0xf3, + 0xcd, 0x93, 0x54, 0xff, 0x82, 0xa2, 0xde, 0x5c, 0x63, 0x54, 0x6a, 0x63, 0x44, 0x3f, 0x61, 0x49, + 0xcb, 0xc8, 0xd3, 0x5a, 0xb5, 0xdf, 0x19, 0x73, 0x35, 0xf2, 0x50, 0x94, 0xd1, 0x4b, 0x6d, 0x36, + 0x84, 0xdf, 0xc1, 0x09, 0xf6, 0x49, 0x31, 0xd7, 0xc2, 0x44, 0xa3, 0xad, 0x48, 0xc3, 0x1d, 0xe1, + 0x43, 0xa7, 0x60, 0xd3, 0x41, 0x86, 0x5d, 0x97, 0x34, 0xa0, 0x9c, 0x75, 0x93, 0x89, 0x4c, 0x5e, + 0x41, 0xa5, 0xdf, 0x15, 0xe6, 0xc5, 0xeb, 0xe6, 0x22, 0xd3, 0xf8, 0x28, 0xaa, 0xae, 0x4e, 0xb2, + 0xfe, 0x20, 0x16, 0x54, 0xdd, 0xb9, 0x54, 0xd7, 0x57, 0xbf, 0x10, 0x24, 0x29, 0x2f, 0xb7, 0x69, + 0x93, 0x85, 0x70, 0xa3, 0x26, 0x7e, 0x2d, 0x45, 0x39, 0x93, 0x63, 0xdc, 0x42, 0xa5, 0x4f, 0x85, + 0x34, 0x38, 0xcb, 0x2b, 0x7b, 0x05, 0xb5, 0xd6, 0x7b, 0xa1, 0xfb, 0xa6, 0xfe, 0x20, 0x29, 0x56, + 0x0d, 0x0e, 0xbe, 0x37, 0xdb, 0xaa, 0xaa, 0x87, 0xed, 0x60, 0x8e, 0x1d, 0xef, 0xc4, 0x89, 0x0a, + 0x16, 0xee, 0x36, 0x99, 0x6d, 0x32, 0xd6, 0x26, 0x42, 0xac, 0x8e, 0x01, 0x54, 0x9b, 0x7b, 0x65, + 0x54, 0xc7, 0x10, 0x24, 0x13, 0x77, 0x4c, 0xad, 0xe0, 0xda, 0x7f, 0x84, 0x29, 0x89, 0x7d, 0xbc, + 0x98, 0x89, 0xaa, 0xf1, 0x02, 0x41, 0x5d, 0xef, 0x76, 0xb6, 0x98, 0x77, 0x7f, 0x12, 0x0a, 0x6f, + 0x15, 0xbb, 0x8a, 0xdc, 0xaa, 0x18, 0xd8, 0xd8, 0xd9, 0xe6, 0x7c, 0x14, 0x99, 0xf6, 0xf6, 0xad, + 0xbb, 0xe3, 0x29, 0xf0, 0x8d, 0x32, 0xeb, 0xd0, 0xae, 0xee, 0xda, 0x63, 0xf8, 0xfc, 0x16, 0x09, + 0x49, 0x78, 0x4b, 0x66, 0xc0, 0x40, 0x9c, 0x36, 0x75, 0x04, 0x0f, 0x1e, 0x98, 0xb4, 0x31, 0x6b, + 0xda, 0xa3, 0x45, 0x6b, 0xc1, 0x56, 0x5e, 0xdb, 0x63, 0x9e, 0x93, 0x28, 0x8c, 0xb6, 0xff, 0xf8, + 0x21, 0xa3, 0x46, 0xf7, 0xf8, 0x52, 0xeb, 0x61, 0x5c, 0xfe, 0xd4, 0xd5, 0x7d, 0xc2, 0x03, 0x6b, + 0xff, 0xc1, 0x4d, 0x08, 0xe4, 0x19, 0xe8, 0x3e, 0xca, 0xfc, 0xf8, 0xb5, 0x23, 0xbf, 0x0a, 0x5c, + 0xd5, 0xd6, 0xa2, 0x56, 0x2a, 0x2d, 0x52, 0xd6, 0xb1, 0x9a, 0xdb, 0x73, 0x3b, 0xc4, 0xe0, 0x13, + 0x4d, 0x73, 0xbf, 0x15, 0x1a, 0x40, 0xc2, 0x0e, 0xac, 0x6b, 0xf8, 0x29, 0xe6, 0x8d, 0xf2, 0xb1, + 0xad, 0x1f, 0xfe, 0x32, 0xdc, 0x75, 0x6a, 0xc7, 0x9f, 0x15, 0x20, 0x88, 0x52, 0x92, 0xf8, 0xe8, + 0xe7, 0x92, 0xfc, 0x7e, 0x35, 0x11, 0x57, 0xd2, 0x59, 0x54, 0x7e, 0x14, 0x99, 0x8e, 0x0d, 0x0f, + 0x9a, 0x10, 0x71, 0x91, 0xb9, 0x65, 0x99, 0x3f, 0x1d, 0xbe, 0x09, 0x75, 0xa6, 0x2f, 0xb7, 0xdf, + 0x04, 0xbc, 0x6f, 0xcb, 0x5b, 0x11, 0x06, 0x33, 0xcf, 0x39, 0x7c, 0x68, 0xc8, 0x26, 0x9a, 0x4d, + 0x6d, 0xdd, 0x1a, 0xe6, 0x96, 0xa8, 0x5e, 0xd5, 0x0d, 0x49, 0x8b, 0x03, 0x02, 0xe1, 0x88, 0xea, + 0xd5, 0x8a, 0xff, 0xc1, 0x59, 0xc7, 0x2e, 0xef, 0x53, 0xa1, 0x11, 0x25, 0x74, 0x1c, 0x8b, 0xec, + 0x84, 0xfa, 0xc0, 0x81, 0xe3, 0x4c, 0x33, 0xe3, 0x98, 0x1b, 0x1d, 0xd7, 0x1b, 0xb0, 0xf0, 0x80, + 0xdb, 0x41, 0x4a, 0x5b, 0x91, 0xa4, 0x12, 0x82, 0xce, 0xaa, 0x03, 0x75, 0x1d, 0x5f, 0x94, 0x24, + 0xf2, 0xfd, 0x94, 0x53, 0xff, 0xc1, 0x0d, 0xb5, 0xbb, 0x7c, 0x71, 0x5d, 0x92, 0x1d, 0x99, 0xbb, + 0x5d, 0x6b, 0xe2, 0xca, 0xb5, 0x55, 0x53, 0xb6, 0xaf, 0x05, 0x26, 0xcf, 0x4c, 0x84, 0xe9, 0xee, + 0x96, 0x5f, 0x1d, 0x7c, 0x37, 0x8d, 0xdd, 0xf0, 0xc6, 0x6c, 0x56, 0x02, 0x69, 0x52, 0xf5, 0x6e, + 0x05, 0xf0, 0xa0, 0xd2, 0x32, 0xd9, 0x27, 0x52, 0x44, 0xaa, 0xc4, 0x56, 0xb5, 0x94, 0x6b, 0x1c, + 0x5c, 0x43, 0xd4, 0x36, 0x99, 0xe3, 0xbf, 0x05, 0xa6, 0x6a, 0x94, 0xea, 0x10, 0xf2, 0xa2, 0x6f, + 0x10, 0x0a, 0xe6, 0x75, 0x96, 0x5d, 0x63, 0xce, 0xc0, 0xad, 0xa3, 0xaa, 0x7f, 0x12, 0x14, 0x93, + 0x2d, 0xdf, 0x6d, 0xee, 0xea, 0xd8, 0xd5, 0x1b, 0xcc, 0xdc, 0x23, 0x05, 0x57, 0x8a, 0xca, 0x56, + 0xad, 0xce, 0xbd, 0xfe, 0x14, 0x8b, 0x99, 0x59, 0x98, 0x96, 0x7d, 0x99, 0x17, 0x17, 0x11, 0xe5, + 0xf2, 0xaa, 0xaf, 0xc4, 0xc2, 0x92, 0xdd, 0x4c, 0x6c, 0xf5, 0x8d, 0x36, 0x36, 0x8a, 0x97, 0x4d, + 0x3e, 0xf1, 0x04, 0x21, 0xbe, 0xd9, 0x8c, 0xf8, 0x28, 0x2d, 0x86, 0xa3, 0x07, 0x9e, 0xdd, 0xfc, + 0x48, 0x29, 0xd2, 0xa4, 0x56, 0x1e, 0xdd, 0xc5, 0x77, 0xe4, 0x5e, 0x12, 0x21, 0xfe, 0x85, 0x76, + 0x3f, 0xc1, 0x65, 0xef, 0x6f, 0x74, 0xdf, 0xff, 0xc2, 0x82, 0x4f, 0x81, 0xc1, 0xc6, 0x7b, 0xd9, + 0xc6, 0xdc, 0x8d, 0x2c, 0x7c, 0x60, 0xe3, 0xb7, 0x21, 0x2f, 0x49, 0x5d, 0x74, 0xf1, 0x4f, 0xc2, + 0x91, 0xf1, 0x77, 0x46, 0xb4, 0x42, 0x5b, 0x70, 0x9a, 0xac, 0x4e, 0x2f, 0xde, 0xf4, 0x6d, 0x90, + 0xb1, 0x8f, 0x74, 0x38, 0x65, 0x1e, 0xcf, 0x46, 0x0f, 0x27, 0xc7, 0xe8, 0xe0, 0x66, 0xce, 0x18, + 0x4f, 0x75, 0x60, 0x9f, 0x72, 0x87, 0x14, 0xba, 0x36, 0x35, 0xf0, 0x57, 0x41, 0xbd, 0x0c, 0xc8, + 0x93, 0x8c, 0x38, 0xab, 0x76, 0xef, 0xdf, 0x05, 0x5b, 0x1a, 0x64, 0x72, 0x17, 0x1c, 0x64, 0x7a, + 0x56, 0xff, 0xbe, 0x09, 0xe6, 0xcc, 0x42, 0x20, 0x26, 0x29, 0x04, 0x70, 0xc1, 0x80, 0x69, 0x7e, + 0x14, 0x97, 0xab, 0x5a, 0x09, 0xa9, 0x37, 0xb2, 0x1d, 0x33, 0xeb, 0x91, 0xb0, 0x9d, 0x1a, 0x55, + 0xe1, 0x4e, 0x1e, 0xd4, 0xa0, 0xa7, 0xec, 0x7e, 0xc6, 0xd1, 0xb9, 0xc1, 0x00, 0x49, 0xfa, 0x55, + 0xe0, 0xae, 0x8c, 0xe4, 0x33, 0x39, 0xbb, 0x0e, 0xa9, 0x4c, 0xaa, 0x76, 0x9f, 0xe0, 0xb2, 0x52, + 0x35, 0x6d, 0x34, 0x0c, 0x9d, 0xa8, 0xac, 0x4c, 0xce, 0xd4, 0x77, 0xe0, 0xab, 0xb1, 0x87, 0xa2, + 0x18, 0x42, 0xd6, 0x32, 0xa0, 0xd8, 0x6e, 0x9b, 0x26, 0xb0, 0xf8, 0x2d, 0x21, 0x58, 0x4b, 0xb4, + 0xaa, 0xd5, 0xc2, 0x85, 0x69, 0x91, 0x12, 0x50, 0xce, 0x92, 0xf0, 0xeb, 0x06, 0x9b, 0x68, 0x8d, + 0x90, 0xd5, 0x2a, 0x7d, 0x30, 0x1f, 0x2f, 0xc7, 0xd5, 0x55, 0x27, 0x6f, 0x69, 0xaf, 0xc6, 0x08, + 0xd1, 0xbb, 0x0d, 0xe5, 0xa3, 0x23, 0x7d, 0x8d, 0x5a, 0x1c, 0x68, 0xa2, 0xcd, 0xbe, 0x1f, 0x26, + 0x3c, 0xe0, 0x4c, 0xb6, 0x9d, 0x07, 0x09, 0x86, 0xda, 0xb8, 0xba, 0x6b, 0xb6, 0xa8, 0xa2, 0x2a, + 0x3f, 0xe0, 0x8c, 0x4b, 0x47, 0x7a, 0x2e, 0x32, 0xb9, 0x8f, 0x55, 0x52, 0xc0, 0x00, 0x00, 0x00, + 0x01, 0x41, 0x9a, 0x22, 0x11, 0x30, 0x12, 0xa1, 0x1c, 0x14, 0x5e, 0x1c, 0x68, 0xf2, 0xaa, 0x2a, + 0xa2, 0x14, 0x25, 0xd0, 0xba, 0x87, 0xb9, 0x44, 0x34, 0x81, 0xcf, 0x4f, 0x54, 0x8c, 0xdc, 0x3f, + 0x25, 0x23, 0xe0, 0x24, 0xd5, 0x0a, 0x9f, 0xb4, 0x48, 0x99, 0xc5, 0x06, 0x03, 0xbe, 0x69, 0xec, + 0x84, 0x66, 0x2e, 0x08, 0xfa, 0x4e, 0x04, 0xdb, 0x86, 0x1a, 0xda, 0x63, 0xca, 0x63, 0xb1, 0x84, + 0x3a, 0x16, 0xff, 0x76, 0x0d, 0xb0, 0xd2, 0xee, 0x60, 0x35, 0xd5, 0xc8, 0x73, 0xa3, 0x3c, 0xfd, + 0x62, 0xfa, 0x11, 0x5f, 0x04, 0x62, 0xc5, 0x7b, 0x19, 0x0a, 0x10, 0xea, 0x7a, 0x2b, 0x9b, 0x9d, + 0x83, 0x80, 0x00, 0x4f, 0xd1, 0x62, 0x8c, 0xe2, 0x89, 0x40, 0x4c, 0x61, 0xa5, 0xf9, 0xf6, 0x33, + 0x30, 0x27, 0xa1, 0x4e, 0x8d, 0xe6, 0x1e, 0x9a, 0x5a, 0xe6, 0x83, 0x16, 0xc8, 0xa2, 0xd9, 0x14, + 0x53, 0x22, 0x8a, 0x64, 0xfa, 0xb2, 0xf8, 0x4e, 0x9d, 0x2b, 0x4d, 0x6b, 0x82, 0x11, 0x08, 0x1a, + 0xb3, 0x59, 0x7d, 0xe9, 0xa4, 0x98, 0x7b, 0xa3, 0x16, 0x89, 0xe6, 0x1b, 0x0e, 0x21, 0xdd, 0xff, + 0x0e, 0xc7, 0xc4, 0x13, 0xe3, 0xa3, 0x61, 0xec, 0x75, 0x00, 0xbe, 0xa9, 0xab, 0x47, 0xa8, 0x35, + 0xc3, 0x49, 0xc3, 0xff, 0xc1, 0x36, 0x32, 0x30, 0x91, 0x22, 0x69, 0x0d, 0x07, 0xaf, 0xcc, 0x36, + 0x70, 0x49, 0x84, 0x06, 0x8e, 0x0f, 0x9d, 0x0d, 0xb3, 0x26, 0x1e, 0x3c, 0x6a, 0xf8, 0x16, 0x78, + 0x59, 0xf1, 0xd6, 0x88, 0xa3, 0x4b, 0xb0, 0x78, 0x1a, 0xfe, 0x1e, 0x04, 0x45, 0xa7, 0x1b, 0x19, + 0x7a, 0x00, 0x58, 0x05, 0x52, 0x32, 0x79, 0xe8, 0x69, 0xc8, 0x67, 0x38, 0xef, 0x09, 0xab, 0xc5, + 0x71, 0x43, 0x9b, 0xc7, 0x54, 0xc4, 0xf0, 0x34, 0xc0, 0xd4, 0xd7, 0x38, 0x37, 0x93, 0x01, 0xc7, + 0xa2, 0x37, 0xe6, 0x03, 0x0c, 0x63, 0x4c, 0x73, 0x87, 0xd6, 0x8f, 0x82, 0x35, 0xd5, 0x3f, 0x4c, + 0x3f, 0xda, 0xa9, 0x3e, 0xe1, 0x01, 0xb0, 0xab, 0x0c, 0x8c, 0x35, 0x21, 0xa7, 0x19, 0xd5, 0x28, + 0x07, 0xd2, 0xa8, 0x10, 0x58, 0x58, 0x5b, 0x10, 0xb0, 0x94, 0x71, 0x3a, 0x2b, 0xe0, 0x03, 0xf2, + 0x58, 0x6f, 0xa8, 0xb4, 0x00, 0x05, 0xe3, 0x06, 0xcf, 0xa6, 0x00, 0x79, 0x13, 0x7d, 0xcd, 0x43, + 0x70, 0xdb, 0x5b, 0xe8, 0x91, 0x7f, 0x88, 0x58, 0xaf, 0x74, 0x3b, 0x12, 0x4c, 0x34, 0xc4, 0x45, + 0xe6, 0x82, 0x33, 0xd2, 0x94, 0x17, 0x87, 0x42, 0x23, 0xa9, 0xbe, 0x3c, 0xd3, 0xe3, 0x4d, 0x25, + 0xaf, 0x28, 0x3f, 0xca, 0x30, 0x15, 0x6d, 0x48, 0x2a, 0x7f, 0xe0, 0x8a, 0x19, 0x45, 0x9f, 0xac, + 0x0f, 0xd9, 0xeb, 0xe0, 0x90, 0x42, 0xc8, 0x02, 0x4c, 0x8b, 0x2f, 0xa2, 0xf7, 0xc2, 0xa5, 0x1e, + 0x2c, 0x7e, 0x3c, 0x0d, 0x0f, 0xd7, 0xc2, 0x2d, 0xf5, 0x02, 0xfe, 0x1f, 0xb6, 0xdd, 0x83, 0x81, + 0xd9, 0xaf, 0xda, 0x82, 0x6d, 0xad, 0xfe, 0xbf, 0xb6, 0x09, 0x7d, 0xe9, 0x71, 0x5e, 0x36, 0x0b, + 0x5c, 0x38, 0x80, 0xf3, 0x27, 0x3c, 0xc8, 0xab, 0x1b, 0x96, 0xae, 0x5e, 0x33, 0x2d, 0x4c, 0xb5, + 0xc7, 0x43, 0xf1, 0x2d, 0x57, 0xe3, 0x6a, 0xc5, 0x10, 0xda, 0xa7, 0x89, 0x6a, 0x2c, 0xbc, 0x25, + 0x86, 0x33, 0xbe, 0xda, 0x06, 0xc2, 0x0e, 0xe7, 0x7e, 0x5e, 0x09, 0x1e, 0x15, 0xe9, 0x51, 0xb9, + 0xf3, 0xd7, 0xc3, 0xdb, 0x8f, 0xf9, 0x49, 0xc3, 0x89, 0xfe, 0xc4, 0xf0, 0x49, 0x1d, 0x4c, 0x2f, + 0xa7, 0x91, 0x19, 0xf8, 0x7a, 0x3f, 0x4d, 0x7d, 0x33, 0x09, 0x0f, 0x0b, 0x11, 0x87, 0xa2, 0x7e, + 0xd1, 0x47, 0xb8, 0x5f, 0xdf, 0x1f, 0x21, 0x2f, 0x21, 0x7f, 0x85, 0x86, 0x50, 0x6f, 0x13, 0x65, + 0x0c, 0xe7, 0xc6, 0x2e, 0xfb, 0x18, 0x8f, 0x62, 0xb7, 0xce, 0x2c, 0xa8, 0xcb, 0x36, 0x9b, 0x72, + 0xe9, 0x74, 0xbd, 0x4d, 0x29, 0x36, 0x20, 0x16, 0x04, 0x32, 0x82, 0x49, 0x52, 0x78, 0x80, 0xa6, + 0x28, 0x75, 0x99, 0xcd, 0x00, 0xcb, 0x34, 0x63, 0x57, 0x6e, 0x19, 0x54, 0x44, 0x5c, 0x07, 0x02, + 0x30, 0x53, 0xc4, 0x8d, 0xa8, 0xb0, 0x74, 0x2a, 0x2f, 0xd3, 0x1b, 0xd5, 0xbd, 0x27, 0xf2, 0x86, + 0xc0, 0xaa, 0x0e, 0xff, 0xc8, 0x78, 0xe7, 0x23, 0xa3, 0xf6, 0x23, 0x68, 0x90, 0x61, 0x12, 0x25, + 0x98, 0xad, 0xc4, 0xa5, 0xa3, 0x03, 0x23, 0x9b, 0xb1, 0x82, 0xc7, 0xf9, 0x81, 0x98, 0x57, 0x0c, + 0xc3, 0xfd, 0x90, 0x30, 0x82, 0xf5, 0x5c, 0xb2, 0x92, 0xf6, 0x86, 0x11, 0x89, 0xb0, 0x9e, 0x1a, + 0x99, 0xbd, 0x38, 0x62, 0x9e, 0x9f, 0x94, 0x66, 0x4c, 0x1f, 0x58, 0x5f, 0xfe, 0x88, 0xf3, 0x34, + 0x4f, 0xcf, 0xc2, 0x85, 0x60, 0x81, 0x1b, 0xa5, 0x21, 0x60, 0x04, 0xd5, 0x8c, 0xca, 0x1e, 0x8a, + 0x80, 0x2c, 0x0c, 0x67, 0xea, 0x6d, 0x36, 0x17, 0x83, 0x95, 0xc1, 0x7f, 0x38, 0x90, 0xbb, 0x8b, + 0x3b, 0x95, 0xd1, 0x8c, 0xe1, 0x5f, 0x04, 0x83, 0x5b, 0x66, 0x61, 0x0c, 0x05, 0x87, 0xc1, 0x28, + 0x89, 0x76, 0xf7, 0x61, 0xbe, 0x5f, 0x0a, 0x09, 0x0f, 0xa1, 0xa9, 0x56, 0x04, 0x02, 0xc1, 0x01, + 0x37, 0xc1, 0xf0, 0x46, 0xb8, 0xb4, 0x25, 0x5e, 0xfd, 0x63, 0x86, 0xad, 0x7a, 0x02, 0x41, 0x23, + 0x43, 0x68, 0xb8, 0x20, 0x70, 0x61, 0xf0, 0x42, 0x4d, 0xa2, 0x51, 0x8c, 0xa5, 0x4b, 0x86, 0xce, + 0x28, 0x31, 0x41, 0x8a, 0x0c, 0x50, 0x62, 0x2d, 0x22, 0xa1, 0x0a, 0x85, 0xfa, 0xe4, 0xf1, 0xa6, + 0x8f, 0x0a, 0xf5, 0x5e, 0xfc, 0x21, 0x52, 0x11, 0x4a, 0xf2, 0x69, 0x9e, 0x78, 0x42, 0x5d, 0x51, + 0x71, 0xea, 0x54, 0xf9, 0x38, 0xeb, 0x47, 0xea, 0x54, 0x93, 0xa3, 0x0f, 0x29, 0x38, 0x68, 0xbc, + 0x6b, 0xc4, 0x7c, 0x90, 0x96, 0x46, 0xd1, 0x13, 0x34, 0x11, 0x0d, 0x2e, 0x15, 0x8e, 0xb4, 0x2d, + 0x68, 0xf5, 0xad, 0x0b, 0x5a, 0x3c, 0x65, 0x1d, 0x20, 0x90, 0x45, 0xd6, 0xe9, 0xf4, 0xfb, 0x9f, + 0xa3, 0x45, 0x5d, 0x49, 0x7d, 0x61, 0x0f, 0x54, 0x88, 0x9d, 0x62, 0x97, 0x96, 0x76, 0x3f, 0xaa, + 0x65, 0xea, 0x95, 0x2e, 0xb1, 0x7d, 0x62, 0xf1, 0x01, 0xe0, 0x85, 0xbe, 0xea, 0x15, 0x84, 0x18, + 0xd0, 0x21, 0x12, 0x51, 0xef, 0x10, 0x89, 0x04, 0x10, 0x15, 0xfb, 0xab, 0xf0, 0x88, 0xda, 0xf9, + 0x57, 0xa8, 0x16, 0xc1, 0x9c, 0xb4, 0x51, 0x92, 0xec, 0x97, 0xdb, 0xc7, 0x9e, 0x01, 0xb6, 0x3c, + 0x5d, 0xc9, 0x53, 0x0f, 0x29, 0x95, 0x31, 0x04, 0xd8, 0x51, 0x04, 0xa2, 0x08, 0x09, 0xb9, 0xc0, + 0x98, 0x98, 0xa8, 0x47, 0xac, 0x3c, 0x8f, 0xf3, 0xc2, 0x57, 0xf1, 0x23, 0x09, 0x1a, 0xc4, 0xe1, + 0x3f, 0xc7, 0xc6, 0x70, 0x04, 0xf4, 0xc7, 0xfe, 0x0e, 0xfe, 0x3a, 0xb8, 0x43, 0x11, 0x2c, 0xa6, + 0x09, 0x11, 0x8c, 0xc5, 0x4d, 0xfd, 0x6c, 0x23, 0xf0, 0x56, 0x15, 0x4e, 0x99, 0x99, 0x40, 0xf0, + 0xf4, 0x51, 0x9d, 0x5a, 0x95, 0x4a, 0xe6, 0xc5, 0x73, 0xa2, 0xf3, 0x1a, 0xa8, 0x45, 0x5f, 0x11, + 0x0a, 0x0c, 0x4d, 0x48, 0xc6, 0x43, 0x4e, 0xfe, 0x62, 0x44, 0x08, 0x05, 0xb2, 0x4a, 0xb2, 0x8e, + 0x2a, 0x11, 0x84, 0x20, 0x25, 0x86, 0xd4, 0x47, 0x95, 0x05, 0xe5, 0x65, 0xed, 0x71, 0x11, 0x84, + 0x26, 0x82, 0xd6, 0x6d, 0x13, 0xba, 0x31, 0x32, 0x11, 0x52, 0x64, 0x23, 0x0b, 0xaa, 0xc8, 0xd8, + 0x30, 0x11, 0xc5, 0x36, 0xb0, 0x37, 0xcd, 0x5b, 0xf0, 0x96, 0x00, 0x04, 0xb9, 0x77, 0xc6, 0x66, + 0xac, 0x20, 0xae, 0x67, 0x89, 0x10, 0x36, 0x0e, 0xf1, 0x26, 0x39, 0xd5, 0xa8, 0x3c, 0xad, 0xb0, + 0x75, 0xeb, 0x45, 0x40, 0xcf, 0x4d, 0x54, 0x6d, 0x33, 0x43, 0x61, 0x19, 0xf1, 0x2f, 0xc5, 0x5b, + 0x69, 0xf8, 0x80, 0xec, 0x60, 0x6c, 0x4a, 0x8b, 0x30, 0x09, 0x81, 0x30, 0x93, 0x10, 0xf4, 0xb2, + 0xe2, 0xf9, 0x48, 0x2a, 0x4d, 0x4f, 0x3e, 0x9f, 0x7e, 0x20, 0x29, 0x63, 0x28, 0xf1, 0x85, 0x94, + 0x8b, 0x5d, 0x6a, 0xc6, 0xcb, 0x64, 0x47, 0x0f, 0x5c, 0x2e, 0x31, 0x31, 0x83, 0xaa, 0x44, 0x90, + 0x80, 0x8c, 0xc8, 0x4d, 0xc1, 0xdf, 0x04, 0xa1, 0x7c, 0x94, 0x62, 0xbb, 0x06, 0xe8, 0xf7, 0xc8, + 0x7e, 0x3c, 0x98, 0x0c, 0x74, 0x3b, 0x09, 0x7a, 0x27, 0x5f, 0x21, 0xdd, 0xd5, 0x5f, 0x54, 0x81, + 0xea, 0x99, 0x7a, 0xa5, 0x5e, 0xbd, 0xf5, 0xef, 0xa9, 0x57, 0xe1, 0x00, 0xf0, 0xee, 0x6e, 0x66, + 0x49, 0x00, 0x65, 0x13, 0xe1, 0x20, 0xbf, 0x8e, 0x98, 0xd2, 0xbb, 0xdd, 0x02, 0x68, 0x2d, 0x99, + 0x7d, 0x03, 0xbd, 0x95, 0x8b, 0xff, 0x04, 0x03, 0x7a, 0xea, 0xd4, 0x0b, 0x53, 0xa2, 0xe4, 0xbd, + 0xb1, 0xb8, 0x15, 0xdc, 0x16, 0x80, 0xfc, 0x21, 0x80, 0x44, 0x18, 0x57, 0x80, 0x12, 0xe8, 0x6a, + 0x41, 0x32, 0x17, 0xfd, 0x26, 0xe6, 0x10, 0xa4, 0xb6, 0x35, 0xca, 0x49, 0x16, 0x82, 0xe0, 0xd8, + 0x4e, 0xe2, 0x02, 0x7a, 0xd9, 0xaf, 0x81, 0x64, 0x74, 0x71, 0xfa, 0x9e, 0xc0, 0xdc, 0xb7, 0x0d, + 0xb2, 0x06, 0x99, 0x50, 0xdd, 0x44, 0xff, 0xfe, 0x78, 0xdd, 0x05, 0x19, 0x3e, 0x33, 0x5d, 0x8f, + 0x5e, 0xe8, 0xae, 0x5f, 0x2e, 0xc3, 0xa1, 0x16, 0xfe, 0xfd, 0x5a, 0xeb, 0x5f, 0x41, 0x57, 0xfa, + 0xf5, 0x71, 0xa1, 0x27, 0xbc, 0x30, 0x94, 0x05, 0xd6, 0x91, 0xf8, 0xe6, 0x14, 0x38, 0xcf, 0x22, + 0x4f, 0x89, 0x3a, 0x1c, 0x03, 0x64, 0x1f, 0x3e, 0xc1, 0xb2, 0x77, 0x85, 0xf8, 0x98, 0xf9, 0xc3, + 0x84, 0xe2, 0xa9, 0xc6, 0xb2, 0xea, 0x42, 0x8f, 0x1e, 0xae, 0xa5, 0xe2, 0x33, 0xf3, 0x72, 0xe3, + 0x4a, 0x78, 0x50, 0x7b, 0x52, 0x1a, 0xf0, 0xe2, 0x9e, 0x93, 0xaa, 0xe4, 0xf2, 0x38, 0xe9, 0xa5, + 0x86, 0x3e, 0xb8, 0x04, 0xd5, 0x35, 0xdf, 0x8b, 0xb8, 0x98, 0x52, 0x99, 0x17, 0x43, 0xb9, 0xc8, + 0x36, 0x8c, 0x36, 0x95, 0x6c, 0xb4, 0x47, 0x52, 0xdc, 0xfe, 0x1c, 0x8e, 0x7c, 0x10, 0x98, 0xe5, + 0x6e, 0x2d, 0x7c, 0x60, 0x84, 0x69, 0x05, 0x34, 0x4c, 0xef, 0x02, 0x33, 0x37, 0x99, 0x00, 0x71, + 0x97, 0x52, 0xf0, 0x84, 0x05, 0x47, 0x59, 0x30, 0x12, 0x28, 0x22, 0x9b, 0xa8, 0x25, 0xae, 0xf0, + 0x00, 0x21, 0x2f, 0xdc, 0x7d, 0x9a, 0xe1, 0x00, 0xf9, 0xd3, 0xd7, 0xb5, 0x39, 0x81, 0x83, 0x73, + 0x0f, 0x8e, 0x52, 0xa5, 0x68, 0x34, 0xa6, 0x1e, 0xdb, 0xab, 0xed, 0x35, 0xdf, 0xeb, 0x27, 0x86, + 0x7a, 0x3b, 0xc9, 0xd1, 0xcd, 0x49, 0xd1, 0x1c, 0xae, 0x5b, 0xba, 0xa9, 0xf1, 0x23, 0x45, 0x41, + 0xaa, 0x55, 0x21, 0x9e, 0x0c, 0x72, 0xc6, 0x01, 0xe6, 0x7b, 0x26, 0x44, 0x44, 0x85, 0x9a, 0xaa, + 0x3f, 0x45, 0xbd, 0xa2, 0x12, 0x9c, 0x59, 0x4d, 0xf0, 0x14, 0x95, 0x5d, 0x5d, 0xc4, 0x61, 0x5f, + 0x0a, 0x08, 0xd1, 0xb8, 0x64, 0x6c, 0x2d, 0x90, 0xfe, 0xac, 0x99, 0x20, 0x89, 0x23, 0x15, 0x0c, + 0x2e, 0x87, 0x8e, 0x13, 0x23, 0x06, 0x99, 0xc2, 0xc3, 0xc0, 0xf2, 0x50, 0x68, 0x58, 0x0c, 0x95, + 0x41, 0x5e, 0x08, 0x06, 0x6c, 0x92, 0x29, 0xcd, 0x74, 0x42, 0xe4, 0x0f, 0x1f, 0x34, 0x32, 0x5b, + 0x49, 0x6f, 0x51, 0x36, 0xd9, 0xbd, 0x7c, 0x77, 0xe0, 0xa0, 0x27, 0x56, 0x4d, 0xe3, 0x44, 0x4f, + 0xbe, 0xaf, 0xf1, 0xe2, 0x97, 0x55, 0x31, 0x88, 0xf5, 0xda, 0x29, 0x1a, 0x0e, 0x08, 0xcb, 0x34, + 0x32, 0xa5, 0xe1, 0x41, 0x02, 0x18, 0x10, 0xb3, 0xb4, 0x89, 0x07, 0xda, 0xa4, 0xce, 0x30, 0x9b, + 0x94, 0x0b, 0x7a, 0x85, 0xe7, 0x1b, 0xe3, 0x93, 0xe0, 0xf8, 0x50, 0x78, 0xc9, 0x31, 0x1a, 0x93, + 0x54, 0x4e, 0x14, 0xa3, 0xa5, 0x69, 0x0e, 0xd3, 0x72, 0x5a, 0x6c, 0xf7, 0x3c, 0x20, 0x0a, 0x76, + 0xcb, 0x9b, 0x9d, 0x8b, 0xdc, 0x77, 0xfa, 0xf8, 0x2b, 0x34, 0x4b, 0xde, 0xee, 0x80, 0x49, 0x8c, + 0xdf, 0x8e, 0x7c, 0x50, 0xa5, 0x8d, 0x0c, 0x53, 0x2f, 0x6a, 0x52, 0x22, 0x64, 0x70, 0x2a, 0x0f, + 0xe3, 0x8a, 0x7a, 0xfd, 0x0c, 0xe5, 0xc6, 0xe6, 0x74, 0x0d, 0xc0, 0xa8, 0x21, 0xd8, 0xfe, 0x2f, + 0x12, 0x82, 0xa7, 0x48, 0xce, 0xe7, 0xc3, 0xe1, 0xb1, 0xd8, 0x40, 0xd2, 0x08, 0x80, 0x18, 0xcf, + 0x50, 0x0a, 0x04, 0xee, 0xbf, 0x05, 0x74, 0x00, 0xee, 0x88, 0xef, 0xf8, 0xe0, 0x00, 0x4e, 0x97, + 0xa0, 0x93, 0x97, 0xc1, 0x0c, 0x5c, 0x5d, 0x55, 0xaf, 0xab, 0x82, 0x72, 0x55, 0x5d, 0x4d, 0xd4, + 0xc9, 0x7d, 0x7b, 0xe6, 0x35, 0x67, 0x53, 0x88, 0x12, 0x14, 0x23, 0xdc, 0xea, 0x15, 0xdc, 0x44, + 0x5a, 0x23, 0x25, 0x84, 0x22, 0x52, 0x0d, 0x71, 0x51, 0x47, 0xc4, 0x95, 0x31, 0x18, 0x11, 0x1a, + 0x3b, 0xf1, 0x82, 0x0e, 0x1a, 0x1e, 0x84, 0x01, 0x2d, 0x9e, 0x90, 0x5a, 0x30, 0x6d, 0xb9, 0x65, + 0x83, 0x1d, 0x7c, 0xf1, 0x83, 0xfc, 0x46, 0x0c, 0x07, 0xf0, 0x88, 0xed, 0x11, 0x21, 0x26, 0x2f, + 0x37, 0x7e, 0x54, 0x87, 0x50, 0xa6, 0x57, 0xa0, 0x9d, 0x71, 0x30, 0x47, 0x77, 0xcc, 0x8c, 0xbc, + 0x28, 0x16, 0xb7, 0x6e, 0x83, 0x74, 0x1a, 0x67, 0x87, 0x11, 0x1a, 0xbe, 0x33, 0x2c, 0xfd, 0x7c, + 0x14, 0x8b, 0xe9, 0xa4, 0xbb, 0x8e, 0x34, 0x56, 0x5e, 0x6c, 0x3d, 0xf2, 0x6e, 0xbf, 0x16, 0x65, + 0x98, 0x61, 0xcd, 0x12, 0x10, 0x53, 0x41, 0xa3, 0xf0, 0x52, 0x49, 0xa4, 0x0f, 0xf9, 0x94, 0x7f, + 0x83, 0x62, 0xe6, 0xf1, 0xca, 0x6e, 0xdd, 0xe9, 0xb1, 0xf8, 0xb5, 0xa1, 0x9c, 0x40, 0x77, 0xc4, + 0xab, 0x0b, 0x8f, 0x10, 0x3c, 0x95, 0x05, 0x4b, 0xe8, 0x33, 0xe1, 0x54, 0x3d, 0xf8, 0x45, 0x09, + 0x3a, 0x7d, 0x7a, 0xba, 0x11, 0xd7, 0xd1, 0xdd, 0x09, 0x75, 0x72, 0x27, 0xab, 0x3e, 0x8a, 0x44, + 0xbe, 0xa4, 0x49, 0x79, 0x48, 0xbb, 0x3f, 0x04, 0xe4, 0x92, 0x28, 0x2f, 0xa3, 0xda, 0x0c, 0x64, + 0xac, 0xfb, 0xe0, 0x98, 0x51, 0x6c, 0x4b, 0xf3, 0x5b, 0x87, 0xb1, 0xbc, 0x1f, 0x04, 0x08, 0x48, + 0x7a, 0x06, 0x8c, 0x1e, 0xf8, 0xc2, 0x3b, 0x7b, 0xe4, 0x5a, 0xdd, 0x86, 0x45, 0x4d, 0xf7, 0x76, + 0x05, 0xe6, 0xad, 0x57, 0xc1, 0x44, 0xa1, 0x95, 0xc8, 0x18, 0x1b, 0x63, 0xe5, 0x2c, 0xc3, 0x9f, + 0x13, 0x31, 0x05, 0x75, 0xc4, 0xa3, 0x39, 0xa9, 0x5f, 0xbd, 0x6b, 0x88, 0x8c, 0x91, 0x88, 0xd8, + 0x9d, 0x83, 0x88, 0x7b, 0x92, 0xb9, 0x1a, 0xbc, 0xd0, 0x5b, 0x69, 0xa3, 0x98, 0x29, 0xaa, 0x93, + 0xa8, 0xe7, 0x08, 0xc4, 0x53, 0x05, 0x62, 0xcf, 0xe9, 0x25, 0xff, 0x4a, 0xa4, 0xcd, 0xfd, 0xc0, + 0xbf, 0x54, 0xac, 0x6a, 0x7e, 0xc4, 0x9c, 0x79, 0x0f, 0x73, 0x32, 0xbc, 0x3d, 0x7d, 0x2e, 0x27, + 0x10, 0xbf, 0x47, 0xef, 0xa3, 0xc5, 0xf5, 0xc2, 0x7e, 0xbd, 0xf5, 0x78, 0x5b, 0xac, 0x52, 0xf5, + 0x22, 0x5f, 0x44, 0xc3, 0xe6, 0x18, 0xf5, 0x1f, 0x28, 0xd7, 0x19, 0x40, 0x25, 0xe0, 0x36, 0xec, + 0x00, 0x03, 0x4c, 0xe1, 0xa8, 0xf7, 0x56, 0x20, 0x27, 0x11, 0x83, 0xb1, 0xd1, 0x84, 0x8f, 0x7c, + 0x99, 0x5a, 0xf8, 0x4c, 0xd6, 0x96, 0xf7, 0x7f, 0x2c, 0xc3, 0x12, 0xd1, 0x7e, 0x5f, 0x82, 0x10, + 0x98, 0xf0, 0x04, 0x67, 0x7e, 0x8a, 0xe8, 0x4e, 0xa4, 0xe8, 0x95, 0x2f, 0x44, 0xd4, 0x47, 0x45, + 0x68, 0xae, 0x88, 0xe7, 0xd7, 0xbe, 0xb9, 0x5f, 0x57, 0xbe, 0x2c, 0x73, 0xbd, 0x92, 0x6d, 0x8e, + 0x8b, 0x03, 0xae, 0x84, 0xf7, 0xc8, 0x47, 0xdd, 0xf0, 0x42, 0x54, 0x9e, 0x83, 0x7f, 0x88, 0x14, + 0xbb, 0x49, 0xbd, 0xfc, 0xa1, 0x1c, 0x6c, 0x40, 0x65, 0x74, 0x5e, 0xfa, 0xd4, 0x4f, 0x57, 0x27, + 0xeb, 0x55, 0xd6, 0x37, 0xd5, 0x88, 0xde, 0x88, 0xc4, 0x47, 0x45, 0xab, 0xe3, 0x02, 0xd6, 0xd0, + 0x8a, 0xcb, 0x8c, 0xf6, 0xa8, 0x66, 0x35, 0x2a, 0xaa, 0xbe, 0x14, 0x29, 0x48, 0x3b, 0x15, 0xd3, + 0x77, 0x53, 0x0a, 0xd9, 0x14, 0x56, 0x84, 0xab, 0xeb, 0xdf, 0xe2, 0xf6, 0x6c, 0x2b, 0x2e, 0x20, + 0xb0, 0x76, 0x08, 0x12, 0x15, 0xf1, 0x35, 0x59, 0x19, 0x36, 0x6f, 0x00, 0x15, 0xf2, 0x95, 0x3b, + 0xa0, 0x2f, 0x19, 0x9b, 0x14, 0xbf, 0x54, 0xd2, 0x80, 0xab, 0x9d, 0xa8, 0x5e, 0xaa, 0xac, 0xd7, + 0x2e, 0xaa, 0xbe, 0x27, 0x41, 0xc6, 0xce, 0x14, 0x74, 0xcc, 0x9d, 0x91, 0xba, 0x1e, 0x74, 0xbe, + 0xae, 0x02, 0x7d, 0x52, 0x25, 0xd1, 0x1e, 0x4e, 0xad, 0x15, 0xd1, 0x75, 0xf4, 0x47, 0xf1, 0x02, + 0x87, 0x50, 0x0a, 0x2b, 0x73, 0xa4, 0x15, 0xdf, 0x8c, 0x24, 0xca, 0x4b, 0xaa, 0x68, 0x45, 0x61, + 0x91, 0x96, 0x73, 0x35, 0x41, 0xa7, 0xc4, 0xd6, 0x59, 0x05, 0x58, 0x4f, 0x64, 0x22, 0xec, 0xbc, + 0x21, 0x01, 0xed, 0xce, 0x76, 0x6c, 0xdc, 0xa3, 0x5a, 0x35, 0x22, 0x93, 0x54, 0x15, 0x6f, 0x2e, + 0xd1, 0xaa, 0x86, 0x3f, 0xa3, 0xb3, 0xe1, 0x12, 0x2a, 0x31, 0x9a, 0x8d, 0xac, 0x38, 0x29, 0xd3, + 0x69, 0x1a, 0xad, 0x9c, 0xd1, 0x00, 0xea, 0xf1, 0x25, 0xd4, 0xdf, 0x41, 0xfa, 0x65, 0xcd, 0x6f, + 0x6d, 0xf6, 0xd7, 0x25, 0x32, 0x78, 0x15, 0xc1, 0x49, 0xd8, 0xd5, 0x6f, 0x7a, 0xaa, 0x3f, 0x57, + 0x42, 0xf2, 0x8b, 0xe8, 0xa9, 0x61, 0xfe, 0x87, 0xb9, 0xf4, 0x10, 0xff, 0xc8, 0x28, 0x81, 0x83, + 0x6b, 0xe0, 0xb6, 0x91, 0x32, 0x92, 0x1e, 0xff, 0xf8, 0xd2, 0x4e, 0xda, 0xae, 0x50, 0x3c, 0x16, + 0x28, 0xa6, 0x37, 0x4f, 0x4c, 0x9e, 0x01, 0xb5, 0x2d, 0x25, 0xf5, 0x77, 0x62, 0xf2, 0x88, 0xe3, + 0xcc, 0xbc, 0x82, 0x6d, 0xb7, 0xf0, 0x45, 0x04, 0xba, 0x57, 0x25, 0xc6, 0x29, 0x41, 0xfc, 0xb8, + 0x8b, 0x54, 0xc7, 0xc6, 0x13, 0x38, 0x11, 0x7a, 0x98, 0x86, 0x92, 0x5d, 0x1d, 0x86, 0x33, 0x47, + 0x54, 0xbe, 0xce, 0x83, 0x26, 0x22, 0xfc, 0x11, 0x97, 0x2b, 0x18, 0xaf, 0xa2, 0xa6, 0x41, 0x13, + 0xc4, 0x80, 0xf6, 0x9f, 0x13, 0xa1, 0x95, 0xf5, 0xca, 0x23, 0xab, 0xc5, 0xf5, 0x61, 0xe2, 0xc9, + 0x77, 0x76, 0x0e, 0x40, 0x80, 0x97, 0x3c, 0x21, 0x4d, 0x72, 0x74, 0x5a, 0x9c, 0x90, 0x69, 0x08, + 0x1e, 0x9b, 0xa9, 0xe6, 0x25, 0xe8, 0xfc, 0x15, 0x1a, 0x48, 0xef, 0xa5, 0x87, 0x77, 0x34, 0x4b, + 0x89, 0x54, 0xba, 0x7d, 0x93, 0x1f, 0x17, 0x29, 0xc1, 0x5c, 0x20, 0x8d, 0xba, 0x1b, 0x11, 0x4b, + 0x56, 0x99, 0xf8, 0x26, 0x16, 0x5c, 0x2d, 0x44, 0xbd, 0xc6, 0x89, 0xc7, 0x6f, 0x56, 0xcb, 0xda, + 0xb9, 0x0a, 0xef, 0x55, 0xd5, 0x95, 0xc5, 0x0a, 0xad, 0x1b, 0x74, 0xeb, 0x82, 0x30, 0x8d, 0xdd, + 0x6c, 0x7d, 0x17, 0xa1, 0x4e, 0x84, 0x65, 0x09, 0xf3, 0x08, 0x6b, 0x6b, 0xcb, 0x55, 0x55, 0x58, + 0x81, 0x9c, 0x86, 0xda, 0x74, 0x33, 0xb9, 0x50, 0xc1, 0x48, 0xe8, 0x8d, 0xe5, 0xdd, 0xd9, 0xaf, + 0x90, 0x43, 0x23, 0x31, 0xf8, 0xb2, 0xe3, 0x70, 0x87, 0x33, 0x56, 0xd7, 0xc2, 0x42, 0xcd, 0x6c, + 0xcf, 0x72, 0x0d, 0x62, 0xe5, 0xd7, 0x90, 0x10, 0x07, 0xd9, 0x27, 0xa2, 0x06, 0xd2, 0x0f, 0x82, + 0xc3, 0x9c, 0x30, 0x17, 0x47, 0xa4, 0x70, 0xa4, 0x24, 0x56, 0x63, 0xdc, 0xff, 0x45, 0x89, 0xc3, + 0xcd, 0xd0, 0xd7, 0xd1, 0x1b, 0xe4, 0x10, 0xaa, 0xaa, 0xf9, 0x6a, 0xaa, 0x98, 0x6b, 0xa1, 0x69, + 0xd7, 0xa2, 0xa4, 0x4b, 0xa2, 0x41, 0x7d, 0x11, 0xa4, 0xe8, 0xac, 0xae, 0x28, 0x61, 0x06, 0x2d, + 0x48, 0xa1, 0x66, 0xbe, 0x28, 0x92, 0x8c, 0x57, 0x5b, 0x1f, 0xd9, 0xfa, 0xaa, 0xe1, 0x19, 0xc3, + 0x03, 0x1b, 0x69, 0xcb, 0xe9, 0xe5, 0xf4, 0x3f, 0x08, 0x88, 0xdb, 0x7b, 0x98, 0x53, 0xa2, 0x8d, + 0x04, 0x9f, 0x12, 0x7d, 0x01, 0x99, 0xfc, 0x06, 0x96, 0x74, 0x9e, 0x09, 0x04, 0xbd, 0xdf, 0xbe, + 0xaf, 0xf5, 0xea, 0xe5, 0x29, 0x32, 0xff, 0x57, 0xfa, 0xb3, 0xe0, 0x90, 0x8a, 0xaa, 0xaf, 0x5c, + 0x83, 0x96, 0xbf, 0x2e, 0x4c, 0xfc, 0xa2, 0x5d, 0xaa, 0x8d, 0xe8, 0xec, 0x57, 0x46, 0xd4, 0x5f, + 0x47, 0xe9, 0xfa, 0x29, 0x52, 0xf8, 0xb1, 0x8a, 0xab, 0xca, 0xd6, 0x0b, 0x88, 0x08, 0xe2, 0xe8, + 0x97, 0x68, 0x53, 0x5a, 0xfc, 0x11, 0x15, 0x05, 0x9b, 0xf7, 0xc1, 0x46, 0xb5, 0xaa, 0xdf, 0xe1, + 0x11, 0x0d, 0x9c, 0x26, 0x68, 0xa5, 0x93, 0x15, 0x8d, 0xc0, 0xa1, 0x19, 0xe7, 0x21, 0x1f, 0x0b, + 0x14, 0xf7, 0xc1, 0x54, 0x90, 0xb2, 0x2b, 0x23, 0x2e, 0x12, 0xb9, 0x44, 0x85, 0x91, 0xc7, 0xba, + 0x03, 0xec, 0x24, 0x6e, 0xcb, 0xbe, 0x2a, 0xc0, 0xb2, 0xe2, 0xcc, 0x85, 0xbc, 0xb7, 0xb1, 0x27, + 0xc5, 0x8d, 0x4c, 0x78, 0x6c, 0x67, 0xc6, 0xf2, 0xf5, 0x6a, 0xea, 0xdf, 0x57, 0xfa, 0xbd, 0x72, + 0x09, 0xd5, 0x7d, 0x1b, 0xe3, 0xc1, 0x09, 0x1c, 0xb8, 0x53, 0x1b, 0x1d, 0xff, 0x14, 0x29, 0x9a, + 0xb3, 0x67, 0x69, 0x61, 0x7e, 0x8e, 0xff, 0x57, 0x9f, 0xa2, 0xf5, 0x75, 0x7f, 0x8a, 0x32, 0x34, + 0x68, 0xd1, 0xb5, 0x69, 0xa5, 0xdd, 0xba, 0xfc, 0x75, 0x45, 0xdb, 0x45, 0x29, 0x91, 0xf8, 0xf8, + 0x55, 0xaf, 0x10, 0x24, 0x4d, 0xd1, 0xbb, 0xd8, 0x33, 0xd7, 0xc8, 0x22, 0x4d, 0xfc, 0x12, 0xd0, + 0xa1, 0x2e, 0x92, 0x9a, 0x5a, 0xa1, 0xfe, 0xcb, 0x4d, 0xab, 0xfb, 0x23, 0xbb, 0xba, 0xe8, 0x5b, + 0xfc, 0x11, 0x91, 0x55, 0x6f, 0xf5, 0x7f, 0x82, 0xa2, 0xd9, 0x2a, 0x6c, 0x99, 0x22, 0x4d, 0xec, + 0xbf, 0xae, 0x08, 0x4a, 0xe2, 0xb7, 0x15, 0xda, 0xba, 0x37, 0xeb, 0x82, 0x8b, 0xbd, 0xdd, 0xdd, + 0xdf, 0xea, 0xcf, 0x8a, 0x14, 0xab, 0x51, 0xf5, 0xff, 0x82, 0x88, 0x8c, 0x04, 0x69, 0x5c, 0x90, + 0x52, 0xa7, 0xd6, 0x2f, 0xae, 0x50, 0xc7, 0x42, 0xfb, 0xeb, 0x15, 0xf5, 0xaf, 0x82, 0x83, 0x46, + 0x0d, 0x3d, 0x83, 0x48, 0xd1, 0xb8, 0xed, 0xf7, 0x74, 0x6c, 0xfe, 0xac, 0x7c, 0x25, 0x3c, 0x72, + 0x19, 0x4a, 0xd7, 0xc6, 0x45, 0xc5, 0xf1, 0x7d, 0x0d, 0x62, 0x63, 0x04, 0xc3, 0x04, 0xef, 0xd2, + 0x9a, 0x9e, 0x4b, 0xdf, 0xe0, 0x92, 0xdc, 0x78, 0x1b, 0x98, 0xb4, 0x5f, 0x05, 0x24, 0x0b, 0xee, + 0x28, 0x9c, 0x35, 0x48, 0xa2, 0x9a, 0x69, 0xcc, 0x2f, 0xf8, 0x2e, 0xde, 0x2a, 0xe0, 0x94, 0xe4, + 0x48, 0x2f, 0xaa, 0x94, 0x20, 0xc4, 0xff, 0x0a, 0x09, 0x04, 0x8e, 0x87, 0xf0, 0x9f, 0x0c, 0x07, + 0x87, 0x8c, 0x9b, 0xb3, 0x9c, 0x1d, 0x68, 0xa6, 0x6a, 0x74, 0xf3, 0x51, 0xb3, 0xa3, 0x7c, 0x12, + 0xd8, 0x23, 0x03, 0x9d, 0xb9, 0x88, 0x24, 0x10, 0x23, 0xe0, 0xc4, 0xea, 0x71, 0xff, 0x04, 0x66, + 0x52, 0x28, 0x5d, 0xfe, 0x0a, 0x22, 0xb7, 0x77, 0x22, 0x9c, 0x09, 0x0d, 0xfe, 0xbd, 0xf0, 0x45, + 0x7d, 0xba, 0xf8, 0x24, 0x12, 0xae, 0x94, 0x89, 0x71, 0x30, 0x46, 0x22, 0x65, 0x07, 0x51, 0xc1, + 0xf5, 0x7f, 0x82, 0x3d, 0xa6, 0xbd, 0xf5, 0xf7, 0xc4, 0x18, 0x92, 0x9a, 0x5b, 0x6d, 0x7c, 0x49, + 0x2c, 0x06, 0x34, 0xca, 0xac, 0x99, 0xf8, 0x2d, 0x3a, 0x52, 0xfd, 0x35, 0x60, 0xca, 0x9f, 0x04, + 0x7c, 0xbb, 0x79, 0xfa, 0x2f, 0x4f, 0xd1, 0x3a, 0x37, 0x82, 0x2c, 0x60, 0x7b, 0x7c, 0xbe, 0x14, + 0xc8, 0xd0, 0x33, 0xa1, 0xce, 0x26, 0xc2, 0xce, 0x9b, 0x76, 0xa9, 0x99, 0xbe, 0x8b, 0xf5, 0xf0, + 0xa1, 0x16, 0x54, 0x9e, 0x8e, 0xab, 0x35, 0x58, 0xe7, 0xee, 0xab, 0x10, 0x14, 0xb0, 0xb3, 0x66, + 0x3c, 0xac, 0x89, 0x6a, 0xb9, 0x14, 0x1b, 0x25, 0xe6, 0xc3, 0xa6, 0x3d, 0xe2, 0x01, 0x0d, 0x8c, + 0xca, 0x84, 0x1a, 0x3b, 0xe2, 0x01, 0x4d, 0x8e, 0xef, 0x19, 0x40, 0x56, 0x1a, 0xa0, 0xfe, 0xd9, + 0x3d, 0x7d, 0x1f, 0xb8, 0x88, 0x23, 0xcb, 0xde, 0x27, 0xf8, 0x2a, 0x88, 0xa8, 0x17, 0x51, 0x35, + 0x0a, 0xac, 0x49, 0x25, 0x09, 0x47, 0x43, 0x1a, 0xa7, 0xc1, 0x1d, 0x02, 0x6e, 0x93, 0xf8, 0x80, + 0x46, 0x48, 0xd0, 0xce, 0x51, 0x6d, 0xf8, 0x88, 0x2e, 0xab, 0x15, 0x1b, 0xca, 0xd2, 0x91, 0xef, + 0xa2, 0xff, 0xe0, 0x84, 0x4a, 0x4f, 0x76, 0x7d, 0x11, 0xeb, 0xb3, 0x4b, 0xef, 0xea, 0xf5, 0xc4, + 0x15, 0xcb, 0x47, 0x79, 0x8c, 0xc3, 0x11, 0xf0, 0x9d, 0x73, 0x3f, 0x0a, 0x63, 0xcc, 0x91, 0x32, + 0xdb, 0x7d, 0x01, 0xa6, 0x75, 0xa1, 0x52, 0x84, 0xbc, 0x63, 0x84, 0x94, 0x51, 0x23, 0x2d, 0x61, + 0x10, 0x1a, 0xf9, 0x0c, 0xab, 0x57, 0xc1, 0x17, 0x6d, 0x72, 0x9b, 0xab, 0xc2, 0xbc, 0x4c, 0x3b, + 0x64, 0xfe, 0x3a, 0x67, 0x44, 0xb8, 0x28, 0xc6, 0xfe, 0x38, 0x98, 0xfa, 0x1b, 0xf5, 0x70, 0x57, + 0x53, 0x52, 0x38, 0xac, 0x09, 0x90, 0x2c, 0x5d, 0x0a, 0x91, 0x24, 0xb3, 0xe2, 0x69, 0x5b, 0xaa, + 0x1d, 0x0f, 0x89, 0x08, 0x4a, 0x18, 0xc4, 0x41, 0xab, 0x5a, 0x6c, 0x11, 0x18, 0x6f, 0xe2, 0x04, + 0x8c, 0xee, 0x70, 0x83, 0x37, 0xdf, 0x2d, 0x0a, 0x52, 0x99, 0x06, 0x0b, 0xa9, 0xe5, 0xca, 0xca, + 0xeb, 0xaf, 0x7c, 0x17, 0x15, 0xd6, 0xda, 0xd8, 0x6d, 0xff, 0xe0, 0x98, 0x8a, 0xaa, 0x6a, 0x6a, + 0x97, 0x7d, 0x17, 0x2f, 0x10, 0x3e, 0x9b, 0xf3, 0xa0, 0x66, 0xe5, 0x62, 0xdf, 0xc4, 0x08, 0x2e, + 0x4f, 0x56, 0x6b, 0xf1, 0xfd, 0xde, 0xda, 0xdd, 0xec, 0x7e, 0xaf, 0xf3, 0x0e, 0xdd, 0xd7, 0x47, + 0xef, 0xb1, 0x22, 0xb1, 0x58, 0xad, 0xfd, 0x62, 0xf8, 0x52, 0x49, 0x66, 0x6a, 0x89, 0xaa, 0xba, + 0x6f, 0x18, 0xbf, 0x14, 0x8c, 0x22, 0x1a, 0x94, 0x4b, 0x2c, 0x86, 0xff, 0x04, 0xc4, 0x03, 0x1f, + 0x20, 0x58, 0x41, 0xb2, 0x80, 0x03, 0x75, 0x64, 0x77, 0x7d, 0x08, 0x1d, 0xbe, 0x6b, 0xdf, 0xe8, + 0xfa, 0x9b, 0xab, 0x7d, 0x5a, 0x4e, 0xad, 0x5d, 0x11, 0xa7, 0xea, 0xf3, 0x75, 0xaf, 0xac, 0x5f, + 0x21, 0x55, 0x55, 0x7d, 0x6b, 0xe8, 0x95, 0xe2, 0x42, 0x12, 0xa9, 0xcf, 0xd6, 0xaa, 0x41, 0x86, + 0x37, 0x43, 0x0c, 0x32, 0xf8, 0x83, 0xa6, 0x42, 0x7f, 0x5b, 0x36, 0x5c, 0x93, 0x66, 0xc5, 0x6d, + 0xb4, 0x74, 0x7c, 0x27, 0x6c, 0xdd, 0xa0, 0x95, 0x03, 0x92, 0xb5, 0xe2, 0x09, 0x56, 0x39, 0x47, + 0xbd, 0x11, 0xeb, 0xab, 0xfc, 0x17, 0x1d, 0x24, 0xb4, 0xdb, 0x22, 0x9a, 0xdb, 0xc4, 0x82, 0x9b, + 0x4f, 0x10, 0xb1, 0xa6, 0xe9, 0x28, 0xf7, 0xaf, 0x8c, 0x99, 0x47, 0x6a, 0x2b, 0x95, 0x8c, 0xec, + 0x0d, 0xf3, 0xfb, 0x1f, 0x12, 0x09, 0xf3, 0xb0, 0x81, 0xd1, 0xa5, 0x74, 0x04, 0x5f, 0xf0, 0x5c, + 0x65, 0xaa, 0xdd, 0xfd, 0xe2, 0x41, 0x36, 0x7b, 0xd5, 0x64, 0x51, 0x17, 0xc1, 0x21, 0x47, 0x89, + 0x88, 0x12, 0x90, 0x80, 0xa5, 0xfe, 0x08, 0xa5, 0x31, 0x14, 0x62, 0xb6, 0x02, 0xf3, 0xea, 0xff, + 0x45, 0xff, 0xc1, 0x5d, 0x2d, 0x42, 0xd5, 0x96, 0xd7, 0x35, 0x24, 0xc2, 0x53, 0xbe, 0x08, 0x88, + 0xc1, 0xcd, 0x7c, 0xab, 0x90, 0x52, 0xad, 0x57, 0x28, 0xb7, 0x7c, 0x67, 0x57, 0x8c, 0xe7, 0x15, + 0x2d, 0x4b, 0x08, 0x5f, 0xec, 0xe2, 0x5e, 0x81, 0x57, 0xc4, 0x61, 0x97, 0x28, 0xbf, 0x82, 0x5a, + 0x32, 0x70, 0xa1, 0x8d, 0x4a, 0xa2, 0xf2, 0xb2, 0x35, 0x44, 0xcc, 0x6b, 0x75, 0xb7, 0xd9, 0xcf, + 0x16, 0x51, 0xb1, 0xac, 0x40, 0x8a, 0x08, 0xb8, 0xf6, 0x5c, 0x7f, 0xe0, 0xb6, 0x80, 0xdd, 0x92, + 0x6e, 0xff, 0xfe, 0x0a, 0x2f, 0x67, 0xa1, 0xbf, 0xae, 0x22, 0x3c, 0xb3, 0x57, 0x3f, 0x18, 0x42, + 0x47, 0xb4, 0x46, 0x51, 0xde, 0x22, 0xb9, 0xfc, 0x40, 0x24, 0xb4, 0xbb, 0xfc, 0x11, 0x65, 0x61, + 0xdb, 0xe5, 0xf3, 0x53, 0x99, 0x9f, 0xa3, 0x57, 0xc1, 0x11, 0x65, 0x84, 0xf0, 0xbf, 0xc1, 0x14, + 0xb6, 0xee, 0xed, 0xf5, 0x63, 0xe8, 0xad, 0xf4, 0x52, 0x27, 0xd1, 0x9e, 0x5e, 0x61, 0x12, 0x0d, + 0x19, 0x06, 0x2f, 0xa2, 0xb5, 0x75, 0x69, 0xba, 0xb5, 0x75, 0x7b, 0xe1, 0x01, 0x14, 0xce, 0x00, + 0xdc, 0x7d, 0x7d, 0x5b, 0x6b, 0x82, 0xe1, 0x79, 0x4e, 0x36, 0xe8, 0x9b, 0xf7, 0xd1, 0x7a, 0xf8, + 0xa1, 0x4a, 0xaa, 0xa8, 0x75, 0xf8, 0x2c, 0x2a, 0xb7, 0x9a, 0xac, 0x04, 0x35, 0x66, 0x8c, 0x57, + 0x0a, 0xb8, 0x8a, 0xff, 0x04, 0xa5, 0x17, 0x66, 0xc7, 0xb6, 0x95, 0xfc, 0x48, 0x50, 0xab, 0x27, + 0xa8, 0xb8, 0xba, 0xa3, 0xd5, 0x6c, 0x02, 0xb5, 0xc4, 0x09, 0x0a, 0x48, 0x41, 0x28, 0x60, 0x30, + 0x2c, 0xc2, 0x02, 0xa3, 0xd4, 0xc5, 0xf1, 0xc1, 0x70, 0x32, 0xba, 0x1f, 0xfe, 0x0a, 0xcd, 0x8e, + 0xa0, 0x39, 0xc2, 0xf2, 0xd5, 0x26, 0x1f, 0x04, 0xa9, 0x17, 0x35, 0x8a, 0x5f, 0x05, 0xc5, 0x66, + 0x7a, 0x72, 0x32, 0x70, 0xc3, 0x77, 0xe2, 0x20, 0xb2, 0x64, 0x83, 0x86, 0xc1, 0x13, 0xb1, 0xdd, + 0xc7, 0x51, 0x1a, 0xc4, 0x70, 0x0e, 0x7b, 0x89, 0x82, 0x1d, 0xb8, 0xad, 0xfb, 0xc4, 0x02, 0x39, + 0x14, 0x24, 0x5c, 0x52, 0x10, 0x14, 0x7f, 0x12, 0x89, 0xd5, 0x89, 0x09, 0x19, 0x8e, 0xa9, 0x2d, + 0x45, 0xfc, 0x24, 0x2c, 0xe2, 0x02, 0xee, 0xe3, 0xb2, 0xad, 0xf9, 0x6b, 0x82, 0xac, 0x64, 0xaa, + 0x2c, 0x20, 0xa1, 0xa0, 0xce, 0x18, 0x0f, 0x8f, 0x03, 0x81, 0xa6, 0x91, 0xbc, 0x48, 0x53, 0x4a, + 0x66, 0xb3, 0x29, 0x19, 0x50, 0x06, 0x0b, 0x1c, 0x3a, 0xbb, 0x71, 0xee, 0x5f, 0x05, 0x36, 0x88, + 0x41, 0x85, 0x0d, 0x05, 0x26, 0x67, 0x5d, 0x71, 0x30, 0x45, 0x99, 0xcb, 0xc6, 0x7c, 0x10, 0x96, + 0xc6, 0xba, 0xbe, 0x61, 0xcf, 0x77, 0x15, 0xd1, 0x5a, 0x37, 0x82, 0x21, 0x49, 0x96, 0x0c, 0x9f, + 0xfa, 0xba, 0x17, 0xd5, 0xd1, 0x5f, 0xe0, 0x8e, 0x4c, 0x97, 0x1f, 0xf2, 0x44, 0x44, 0xf5, 0x2a, + 0x04, 0xb0, 0x74, 0xfb, 0x07, 0x89, 0x85, 0x3a, 0x6a, 0xda, 0xb7, 0x54, 0xd5, 0x36, 0xcd, 0x9a, + 0x3b, 0xf0, 0x49, 0x6a, 0x60, 0xc1, 0x43, 0x95, 0x71, 0x7d, 0xcb, 0xcf, 0xff, 0x88, 0x05, 0x9c, + 0x94, 0xb5, 0x74, 0x0d, 0x68, 0x1a, 0x1b, 0xf1, 0x02, 0x5d, 0xcb, 0xde, 0xfc, 0x10, 0x91, 0xed, + 0xd3, 0xaf, 0xa2, 0xbd, 0x70, 0x51, 0xdd, 0x37, 0x9d, 0x9f, 0xbe, 0x14, 0x94, 0x10, 0x06, 0xce, + 0x30, 0x74, 0x93, 0x3c, 0xb7, 0xa2, 0xee, 0x41, 0xd6, 0xfa, 0xf5, 0x70, 0x45, 0x77, 0x7b, 0x57, + 0x04, 0x33, 0x90, 0x4b, 0x62, 0xb2, 0xfe, 0xae, 0xbd, 0xf4, 0x5e, 0xfa, 0xf7, 0xd5, 0xab, 0xb1, + 0x8e, 0xf7, 0xf4, 0x77, 0x2b, 0xab, 0xa1, 0x2e, 0x14, 0x14, 0xa8, 0xfb, 0x97, 0xbd, 0x27, 0x0d, + 0x23, 0x6d, 0x28, 0xb2, 0x96, 0xfb, 0xa5, 0x2f, 0x85, 0x0a, 0x2b, 0x1f, 0x33, 0x39, 0x48, 0xb6, + 0x5c, 0x00, 0xae, 0xb3, 0xab, 0x75, 0x55, 0x17, 0xb7, 0xcd, 0x55, 0xfc, 0x12, 0x96, 0xb5, 0x55, + 0x55, 0xaf, 0x84, 0x26, 0x81, 0xc3, 0x52, 0xe5, 0x0a, 0xca, 0x19, 0x45, 0x03, 0x60, 0xe5, 0x54, + 0xbe, 0x8b, 0xdf, 0x35, 0xf7, 0x5c, 0x16, 0xd3, 0x28, 0x21, 0x4f, 0x6e, 0xd9, 0x0a, 0x3f, 0xc1, + 0x09, 0x2a, 0x4c, 0x91, 0xff, 0xec, 0x95, 0x55, 0x5d, 0x5f, 0x88, 0x82, 0x61, 0x36, 0xd5, 0x55, + 0xb1, 0x8d, 0x20, 0x92, 0xaf, 0x57, 0xf8, 0x9b, 0xef, 0x75, 0x5f, 0x57, 0xfa, 0xe6, 0x7c, 0xa6, + 0x77, 0x7a, 0xe3, 0xce, 0xee, 0xe7, 0x50, 0xf2, 0x0b, 0xdb, 0xb7, 0x6d, 0x3e, 0x24, 0x12, 0xcf, + 0x03, 0x11, 0xab, 0xd5, 0xa4, 0x0f, 0xff, 0x57, 0xf8, 0x23, 0x2b, 0x7b, 0x67, 0x5f, 0xd7, 0x24, + 0xf8, 0x28, 0x91, 0x55, 0x9f, 0x33, 0x0c, 0xbb, 0x89, 0x8e, 0x8e, 0xd2, 0x9e, 0x5e, 0x52, 0x25, + 0x62, 0x2d, 0xb4, 0x52, 0x41, 0xdd, 0x7e, 0x09, 0xf3, 0x28, 0xd8, 0x8d, 0x5c, 0xeb, 0xfb, 0x95, + 0x6a, 0x03, 0x66, 0xba, 0x25, 0x7c, 0x16, 0x14, 0xcc, 0x1b, 0x39, 0xa9, 0x65, 0x1d, 0x4e, 0x4a, + 0xc7, 0x6f, 0x82, 0x7b, 0xab, 0xb6, 0x81, 0x18, 0x61, 0x7a, 0xb2, 0xf9, 0x87, 0x69, 0xbf, 0xa3, + 0xbc, 0x23, 0xc9, 0xb6, 0xdb, 0x6b, 0x82, 0x49, 0x66, 0x73, 0x13, 0x93, 0x6c, 0x3b, 0xe3, 0x8c, + 0x3a, 0xc5, 0x2b, 0xef, 0xe6, 0x44, 0xbf, 0x06, 0x9a, 0xd9, 0xeb, 0xc3, 0xc0, 0x83, 0x52, 0x1e, + 0x01, 0xad, 0xed, 0x5c, 0xbe, 0x4a, 0xaa, 0xfc, 0x28, 0x59, 0xef, 0x5d, 0x92, 0xaa, 0xc9, 0x49, + 0x63, 0x56, 0xfb, 0x2a, 0xa9, 0xb2, 0x5f, 0x47, 0xf7, 0xd1, 0x9b, 0xe5, 0x93, 0xd7, 0xe6, 0xaa, + 0x8b, 0xaf, 0xab, 0xfc, 0x16, 0xd5, 0x32, 0x7b, 0xd8, 0xd5, 0xfe, 0x14, 0xea, 0xb4, 0xdb, 0x33, + 0x11, 0x7a, 0xac, 0xfd, 0xc4, 0x09, 0x04, 0x24, 0x73, 0x77, 0xf4, 0x37, 0xfa, 0x2b, 0xfc, 0x12, + 0x5c, 0x56, 0xef, 0x55, 0xc1, 0x09, 0x2f, 0x7a, 0xae, 0x8f, 0xdf, 0x27, 0x66, 0x7c, 0xf2, 0x48, + 0x18, 0x0a, 0xd4, 0xb8, 0x95, 0x7f, 0x82, 0xd2, 0xb9, 0xd8, 0x10, 0xd2, 0xe2, 0xb7, 0x29, 0x8a, + 0x6a, 0xe8, 0xcd, 0xf6, 0x4d, 0xda, 0xf4, 0x27, 0xa4, 0xe8, 0x91, 0x95, 0xcc, 0x7b, 0xbb, 0x96, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x23, 0x11, 0xb0, 0x11, 0xa0, 0xd7, 0x43, 0x6a, 0x0b, 0xb9, + 0xe8, 0xe0, 0x9f, 0x15, 0x62, 0xac, 0x55, 0x8a, 0xb1, 0x5d, 0x5c, 0x87, 0x3a, 0x23, 0xcf, 0xd6, + 0x2f, 0xa1, 0x15, 0xf0, 0x46, 0x2c, 0x57, 0xb1, 0x90, 0xa1, 0x0e, 0xa7, 0xa1, 0x1e, 0x8b, 0x14, + 0x67, 0x31, 0xb9, 0x58, 0x13, 0xd0, 0x87, 0x46, 0xf3, 0x0f, 0x4d, 0x2d, 0x70, 0x49, 0x03, 0x58, + 0x92, 0x43, 0x31, 0x24, 0x83, 0x42, 0x53, 0x83, 0x52, 0x44, 0x12, 0x98, 0x1a, 0x90, 0xe0, 0x00, + 0x4e, 0x38, 0x00, 0x12, 0xbe, 0xac, 0xbe, 0x13, 0xa7, 0x4a, 0xd3, 0x5a, 0xe0, 0x84, 0x42, 0x06, + 0xac, 0xd6, 0x5f, 0x7a, 0x69, 0x26, 0x1e, 0xe8, 0xc5, 0xa2, 0xb9, 0x06, 0xce, 0xc7, 0xea, 0x70, + 0x49, 0x10, 0x18, 0x0a, 0x04, 0x0e, 0xc0, 0x6e, 0xa0, 0x23, 0x84, 0x75, 0x0c, 0x94, 0x0b, 0xae, + 0x81, 0xf8, 0x41, 0xd5, 0x43, 0x1a, 0x1e, 0xbd, 0xa2, 0x04, 0xff, 0x42, 0x46, 0xb0, 0x0d, 0x83, + 0xc7, 0x2c, 0xc6, 0x43, 0xcc, 0x42, 0x10, 0xd8, 0x7a, 0xc2, 0x72, 0x60, 0x2a, 0xa1, 0xb6, 0x1b, + 0xb5, 0x66, 0xc5, 0x40, 0x1e, 0x4b, 0xa4, 0x8a, 0x09, 0xa0, 0x3a, 0xfc, 0x8c, 0x06, 0x08, 0x8d, + 0xe8, 0x31, 0xa8, 0x9d, 0x70, 0x80, 0xda, 0x5a, 0x00, 0x35, 0x0b, 0x58, 0x0f, 0x23, 0x90, 0x00, + 0x3e, 0xc5, 0xab, 0x98, 0xca, 0xf8, 0x5f, 0x24, 0x70, 0xe6, 0xc9, 0x90, 0xbd, 0x2c, 0xea, 0xba, + 0x00, 0x1a, 0x13, 0xc3, 0x55, 0x1e, 0xd8, 0x01, 0xab, 0x3a, 0x00, 0x01, 0x00, 0x5c, 0x88, 0x8f, + 0x51, 0x1f, 0x89, 0xad, 0x20, 0x47, 0x53, 0x4d, 0xfb, 0x84, 0x65, 0xf8, 0x23, 0xb0, 0xea, 0x9f, + 0xd3, 0x46, 0x20, 0xf2, 0xf4, 0x65, 0xa7, 0xec, 0x22, 0x28, 0x0c, 0x50, 0x19, 0x60, 0xc5, 0x07, + 0xeb, 0xd7, 0xc1, 0x21, 0x96, 0x92, 0x64, 0x59, 0x7d, 0x17, 0xa1, 0xbe, 0x1d, 0x98, 0x01, 0x3e, + 0x11, 0xfe, 0xc8, 0x2e, 0xd8, 0x8f, 0xfb, 0x9a, 0xcb, 0x09, 0x61, 0xfe, 0x3a, 0x66, 0x2e, 0x62, + 0x31, 0x4d, 0x7d, 0x31, 0xfa, 0x7f, 0xd4, 0x88, 0xcf, 0xc1, 0x15, 0x1b, 0x36, 0x06, 0x3a, 0x04, + 0x5e, 0xf8, 0xd1, 0x07, 0x19, 0x29, 0x8e, 0xc2, 0x69, 0xac, 0x83, 0x0b, 0xce, 0x5b, 0x1f, 0x2c, + 0x3d, 0x5e, 0x96, 0x84, 0xe8, 0x26, 0xd3, 0xc4, 0x73, 0x8d, 0x11, 0x52, 0x98, 0x18, 0xf5, 0x56, + 0x85, 0x52, 0x68, 0x42, 0x77, 0x10, 0x4b, 0x82, 0x0e, 0x03, 0xbf, 0xc7, 0x38, 0x63, 0x15, 0xd4, + 0x3b, 0xfa, 0x41, 0xec, 0x27, 0x12, 0xd8, 0xe1, 0xc4, 0x85, 0x50, 0x50, 0xf5, 0xb5, 0xf0, 0xdc, + 0x63, 0xdf, 0x51, 0xfb, 0x9f, 0xfe, 0xf1, 0x03, 0x42, 0x47, 0x24, 0x1a, 0x4f, 0x1e, 0xf7, 0x88, + 0xaa, 0x33, 0xc1, 0xc3, 0x14, 0x21, 0xe4, 0x36, 0x2e, 0x55, 0x29, 0x91, 0xa7, 0x12, 0xb0, 0x20, + 0x7a, 0xfe, 0x31, 0xb2, 0xd0, 0x61, 0xbf, 0xa5, 0x42, 0x3a, 0xb2, 0x65, 0x33, 0x5c, 0x1d, 0xd4, + 0xfb, 0x03, 0x05, 0xe0, 0xb3, 0x34, 0x04, 0x3d, 0x5b, 0x04, 0x41, 0x73, 0x87, 0x3f, 0x0c, 0x44, + 0x6e, 0xb5, 0x82, 0x5a, 0x3c, 0x1c, 0xce, 0x6f, 0xa7, 0x68, 0xf0, 0x6c, 0x02, 0x00, 0x71, 0xb8, + 0x9b, 0x40, 0x03, 0xf5, 0xa6, 0x36, 0x2f, 0x10, 0xce, 0x41, 0x8b, 0x68, 0x4c, 0x10, 0xa9, 0xec, + 0x2d, 0xa8, 0xf6, 0xb9, 0xb1, 0x57, 0xfc, 0x97, 0x0c, 0xfb, 0x5d, 0x00, 0xf3, 0x5a, 0x60, 0xe2, + 0x89, 0xc1, 0x39, 0x03, 0x14, 0x3e, 0xed, 0xf4, 0xdb, 0x3a, 0x6d, 0x53, 0x3e, 0x14, 0x2f, 0x03, + 0x45, 0x81, 0xe7, 0x41, 0x64, 0xc6, 0xc7, 0x5f, 0x56, 0x08, 0x52, 0x13, 0x30, 0x29, 0x9a, 0x00, + 0x01, 0xb3, 0xe3, 0x46, 0xb8, 0x18, 0x3c, 0xa3, 0xc7, 0xce, 0x3e, 0x92, 0xe3, 0x71, 0x8f, 0x0d, + 0x53, 0x5e, 0xcb, 0x4b, 0xdc, 0x2a, 0x0f, 0x3c, 0x3b, 0xec, 0xc1, 0xfe, 0xf6, 0x92, 0xd9, 0x90, + 0xda, 0x63, 0x3e, 0x83, 0xe7, 0x14, 0x79, 0x31, 0x5a, 0x74, 0x21, 0x7e, 0x3a, 0xf4, 0x72, 0x9f, + 0x1a, 0x2b, 0xc2, 0x17, 0x3b, 0x17, 0x2a, 0xd0, 0x10, 0x9c, 0xfd, 0x8c, 0x43, 0x98, 0x34, 0xb5, + 0x52, 0x43, 0xe0, 0xee, 0x0b, 0x5a, 0x04, 0x04, 0x19, 0xd6, 0x1b, 0x66, 0xa2, 0xa5, 0x58, 0x8c, + 0x3c, 0x68, 0x90, 0xfc, 0xb7, 0x2b, 0xdb, 0x8d, 0xdc, 0x3f, 0x83, 0xb0, 0x1c, 0xc7, 0x86, 0xe3, + 0x76, 0x50, 0x68, 0x95, 0x7a, 0x85, 0x22, 0x6a, 0xb5, 0x5a, 0xb8, 0xc2, 0x7b, 0x56, 0xca, 0x0a, + 0xdb, 0x43, 0x5e, 0x07, 0xd8, 0x3e, 0x4d, 0x2d, 0xcf, 0xe0, 0x58, 0x1f, 0x82, 0x37, 0xcd, 0x9d, + 0x18, 0x3c, 0xd2, 0xb3, 0x7b, 0x23, 0x48, 0x22, 0x7c, 0x73, 0x98, 0xb8, 0x89, 0x9b, 0xc6, 0x90, + 0xd4, 0x6b, 0x65, 0x1f, 0x11, 0xd1, 0xd2, 0xe8, 0x63, 0x00, 0x5e, 0x71, 0x01, 0xe1, 0x8c, 0x8b, + 0xc3, 0x0f, 0xd1, 0x9c, 0x00, 0x45, 0xb2, 0xb8, 0x45, 0x2f, 0xfc, 0xc7, 0x14, 0x06, 0x28, 0x0c, + 0x50, 0x18, 0xa0, 0x3f, 0x15, 0xc3, 0x19, 0xb3, 0x2c, 0x18, 0xa0, 0x31, 0x40, 0x61, 0xc0, 0x01, + 0xe5, 0xcf, 0x50, 0x9b, 0x94, 0xe1, 0xa6, 0xd6, 0x63, 0x80, 0xf9, 0xa0, 0xdf, 0xd6, 0x03, 0xe7, + 0x82, 0x3e, 0x10, 0xb6, 0xd7, 0xa2, 0xd4, 0xb9, 0xe8, 0x0b, 0xf8, 0xe2, 0x0f, 0xe7, 0x95, 0x38, + 0xcc, 0xb5, 0x32, 0xd7, 0xdc, 0xfa, 0xe7, 0x95, 0x38, 0xcc, 0xb5, 0x32, 0xff, 0xd1, 0x0a, 0x9f, + 0x0c, 0x47, 0xfc, 0xbf, 0xde, 0xa5, 0xa1, 0x4b, 0x42, 0xe6, 0x85, 0xcd, 0x04, 0x44, 0x45, 0xd2, + 0xee, 0x5d, 0x2e, 0xfe, 0x14, 0xe3, 0x4d, 0x0a, 0x9a, 0x35, 0x4d, 0x0a, 0x9a, 0x14, 0xb4, 0x29, + 0x68, 0x5a, 0xd0, 0xb5, 0xa1, 0x4b, 0x42, 0x96, 0x85, 0xad, 0x0b, 0x5a, 0x3b, 0xe3, 0x7a, 0xa6, + 0x85, 0x4d, 0x1a, 0xa6, 0x85, 0x4d, 0x0a, 0x5a, 0x14, 0xb4, 0x2d, 0x68, 0x5a, 0xd0, 0xa5, 0xa1, + 0x4b, 0x47, 0x88, 0x64, 0x54, 0x2d, 0x8b, 0x66, 0x34, 0xe3, 0x59, 0xb4, 0xdb, 0xe3, 0x63, 0xad, + 0x1d, 0x58, 0xf3, 0x46, 0xac, 0xa4, 0x11, 0x12, 0x0e, 0x42, 0x0f, 0x10, 0x90, 0x48, 0x92, 0x69, + 0x37, 0xff, 0x93, 0x64, 0x1b, 0xa7, 0x57, 0xe9, 0xe1, 0xe8, 0xf0, 0xe4, 0xf8, 0x6e, 0xd4, 0x6e, + 0x6c, 0x37, 0x6a, 0x37, 0x36, 0xc7, 0xc2, 0x2f, 0x89, 0x9b, 0xfc, 0x9c, 0x6b, 0xd8, 0x9e, 0x89, + 0x15, 0x75, 0x25, 0xf5, 0x80, 0xf1, 0xea, 0x91, 0x78, 0x21, 0x15, 0x4e, 0x9d, 0x95, 0xce, 0x34, + 0xc8, 0xcb, 0x26, 0x93, 0x72, 0xe9, 0x77, 0xc3, 0x3e, 0x3b, 0xe1, 0x32, 0x53, 0x4d, 0xc6, 0x9c, + 0x6b, 0xdf, 0x3d, 0x32, 0xfc, 0xba, 0x5d, 0xf2, 0x71, 0xdf, 0x2d, 0xf7, 0x87, 0xbd, 0x04, 0x32, + 0xd1, 0xe3, 0xfe, 0xe3, 0x2f, 0x9f, 0x98, 0x6e, 0x7c, 0xcf, 0xff, 0x82, 0xbc, 0x77, 0xce, 0x63, + 0xcc, 0xc4, 0xf4, 0x19, 0x75, 0xa3, 0x65, 0x13, 0x2f, 0x04, 0xbe, 0x34, 0xd0, 0xa9, 0xa3, 0xaa, + 0x68, 0x54, 0xd0, 0x89, 0x6a, 0x10, 0x58, 0xe4, 0x88, 0xa4, 0x9a, 0x69, 0xa7, 0xa0, 0x90, 0x5e, + 0x88, 0x3c, 0xbe, 0xa3, 0xcb, 0xc4, 0x8d, 0x1c, 0xed, 0x6b, 0xc2, 0xad, 0x4f, 0x4e, 0xd1, 0x74, + 0xed, 0xcf, 0x0b, 0x8e, 0xcc, 0x10, 0xca, 0x06, 0x65, 0x03, 0xb8, 0xb2, 0xc6, 0x08, 0x00, 0x62, + 0x02, 0x27, 0x8e, 0x29, 0x60, 0xc8, 0x49, 0x0f, 0xc4, 0x08, 0x0a, 0x63, 0xf8, 0x91, 0x69, 0x00, + 0xf8, 0x70, 0x02, 0x50, 0x30, 0x79, 0x24, 0x22, 0x2b, 0x74, 0x78, 0x1e, 0x88, 0x48, 0x8e, 0xc6, + 0x8e, 0x45, 0x96, 0x41, 0xb0, 0x83, 0x01, 0x0a, 0x78, 0xc5, 0x09, 0x90, 0x21, 0x7f, 0x96, 0xc1, + 0x39, 0x89, 0x5f, 0x5d, 0x5a, 0xb3, 0x35, 0x8b, 0xd0, 0x4a, 0x0e, 0x0e, 0xe2, 0x03, 0x01, 0x42, + 0x2e, 0xc6, 0x61, 0x06, 0xc6, 0x3f, 0x07, 0x99, 0xef, 0xc8, 0x77, 0x9b, 0xea, 0x29, 0xa9, 0x83, + 0xa1, 0x70, 0x9a, 0xa2, 0x14, 0x35, 0xa8, 0x83, 0x5e, 0x39, 0x77, 0x4e, 0x1e, 0x0b, 0x82, 0xb2, + 0x31, 0xcd, 0x0c, 0xa8, 0xcf, 0xd7, 0xbe, 0xa5, 0xbe, 0x11, 0x35, 0x83, 0xc5, 0x1f, 0x78, 0xc6, + 0x5f, 0xd6, 0xd8, 0x19, 0x0b, 0xc1, 0xf8, 0x88, 0xd1, 0x94, 0x1b, 0xc3, 0x02, 0xf0, 0x29, 0x83, + 0x15, 0xb6, 0x48, 0x64, 0x50, 0xc0, 0xc6, 0xd9, 0x05, 0x71, 0x0b, 0x33, 0xe2, 0xa2, 0xd0, 0xd1, + 0x41, 0x8a, 0x2a, 0xab, 0x13, 0x64, 0x47, 0x7f, 0xcb, 0xbb, 0xf1, 0x01, 0x42, 0x50, 0xca, 0xd3, + 0x82, 0x08, 0x02, 0x77, 0x97, 0x60, 0xb0, 0xa4, 0xc5, 0x19, 0x54, 0x60, 0xae, 0x0b, 0xf4, 0x93, + 0x4a, 0x02, 0x6a, 0xd9, 0x82, 0x13, 0x12, 0xe8, 0x4c, 0x1c, 0x48, 0x81, 0xb0, 0xa0, 0x65, 0xfe, + 0x56, 0x43, 0xd4, 0xc2, 0x2e, 0x44, 0x44, 0x38, 0xd4, 0x65, 0xb7, 0xb2, 0x34, 0x70, 0xb6, 0xe3, + 0xd8, 0xfa, 0x93, 0x52, 0xff, 0x12, 0x20, 0x29, 0x24, 0x01, 0xd0, 0xe0, 0x68, 0xfd, 0x39, 0x68, + 0x7c, 0x7e, 0x72, 0x20, 0x84, 0x52, 0x34, 0x11, 0xa1, 0x03, 0x16, 0x8c, 0xba, 0x4a, 0x4d, 0x5f, + 0xfe, 0x75, 0xf1, 0x22, 0x02, 0x9b, 0x40, 0x34, 0xf5, 0x17, 0x21, 0x37, 0xa9, 0x53, 0xba, 0xed, + 0xa1, 0xb0, 0x63, 0xb6, 0x2f, 0x70, 0xa0, 0x07, 0x13, 0xc3, 0x4a, 0xe1, 0x18, 0x74, 0x2e, 0x7f, + 0x7d, 0xb5, 0x99, 0x59, 0x68, 0x03, 0xbe, 0xfa, 0x5e, 0xfc, 0xeb, 0x0d, 0x94, 0x3b, 0x71, 0x54, + 0x47, 0x5d, 0x33, 0xb6, 0x42, 0x24, 0x9c, 0x75, 0xb4, 0xb6, 0x22, 0x37, 0xd2, 0xaf, 0x39, 0xce, + 0x9f, 0x8d, 0x77, 0x0b, 0xf5, 0x23, 0x7d, 0x0a, 0xc3, 0xeb, 0x2f, 0xac, 0x1f, 0x44, 0x6f, 0x82, + 0x19, 0x08, 0xa4, 0xd3, 0x4c, 0x3c, 0x12, 0x48, 0x62, 0xf6, 0x2e, 0xbe, 0x43, 0x9b, 0x0d, 0x87, + 0xc7, 0xe2, 0xea, 0x45, 0x9f, 0x0a, 0xc9, 0xda, 0xa1, 0x3d, 0x25, 0xb4, 0xe0, 0xe1, 0xef, 0x26, + 0x7d, 0x52, 0xaf, 0x54, 0xcb, 0xd4, 0x76, 0xf8, 0x21, 0x96, 0x92, 0x90, 0x63, 0xb7, 0xd4, 0xc8, + 0x6a, 0xb1, 0x02, 0x06, 0x8e, 0xbb, 0xa1, 0x42, 0x78, 0x00, 0x04, 0x60, 0x01, 0xa9, 0x0b, 0xf6, + 0x42, 0x26, 0x3a, 0xbd, 0xfa, 0xc1, 0xe0, 0x6c, 0x12, 0xed, 0x83, 0x38, 0xfc, 0xf8, 0xbc, 0x32, + 0x36, 0x0b, 0x67, 0x80, 0x40, 0x34, 0xb8, 0x4f, 0xba, 0x8d, 0xad, 0xd5, 0x44, 0xbd, 0x8c, 0xd4, + 0x38, 0x13, 0xc5, 0xd5, 0x1f, 0x10, 0xea, 0x8b, 0xc1, 0x87, 0x19, 0x9f, 0x70, 0x40, 0x4d, 0x42, + 0x34, 0xc2, 0x80, 0xd5, 0xd3, 0x84, 0x10, 0x28, 0x37, 0xe5, 0xf0, 0x51, 0x87, 0x04, 0xaf, 0x75, + 0x4d, 0x75, 0x0e, 0x0e, 0x84, 0xa1, 0xc8, 0x83, 0x82, 0xff, 0x91, 0xdf, 0x51, 0x1a, 0x41, 0x19, + 0x60, 0x4e, 0x59, 0x22, 0x68, 0x1d, 0x89, 0x51, 0x18, 0x32, 0x24, 0x24, 0x48, 0xe3, 0x22, 0xc6, + 0xca, 0x1b, 0x64, 0x05, 0xc2, 0x93, 0x38, 0xb1, 0x2b, 0xf6, 0xbb, 0xc7, 0xdd, 0x18, 0x7d, 0xe6, + 0xbf, 0x07, 0x7c, 0xab, 0xdd, 0xcb, 0x27, 0xcf, 0xc4, 0x54, 0x4d, 0x00, 0xc5, 0xe8, 0xd8, 0xab, + 0xdc, 0xd1, 0x52, 0x1a, 0x6c, 0xac, 0xef, 0xef, 0x7f, 0x0f, 0x85, 0x58, 0x36, 0x31, 0xda, 0xba, + 0x0c, 0x72, 0xb0, 0x3b, 0x68, 0x52, 0xd1, 0xfc, 0x54, 0x07, 0x1f, 0x79, 0xe7, 0xf0, 0xc5, 0x18, + 0xb1, 0x6c, 0x1c, 0x9a, 0x72, 0x11, 0xad, 0x6c, 0x6f, 0x24, 0xd1, 0x3e, 0xff, 0x05, 0x14, 0x04, + 0x7b, 0xf6, 0x9a, 0x7c, 0xbe, 0x14, 0x09, 0x6d, 0xa6, 0xa4, 0x4a, 0x94, 0xf3, 0x12, 0xb1, 0x1a, + 0xa0, 0x75, 0xd2, 0xe1, 0x34, 0x95, 0x1e, 0x09, 0x19, 0x8d, 0x24, 0xc2, 0x18, 0x00, 0x0b, 0xc0, + 0x98, 0x90, 0x87, 0x7e, 0x08, 0xb5, 0x8e, 0x20, 0x29, 0xa3, 0x08, 0x14, 0x1d, 0xa0, 0xf7, 0x0d, + 0x71, 0x5e, 0x25, 0x81, 0x73, 0xcc, 0x4d, 0xb4, 0x2a, 0x7d, 0x4c, 0xa7, 0x56, 0xa9, 0x59, 0xdc, + 0x57, 0xb7, 0x1a, 0xa2, 0xfc, 0x68, 0xf2, 0x6b, 0x61, 0x24, 0xb8, 0x4d, 0x15, 0xfd, 0x52, 0xa0, + 0x14, 0x35, 0x52, 0x14, 0x3c, 0x12, 0xee, 0xab, 0xd1, 0xbc, 0x57, 0xd1, 0x65, 0xe2, 0x4f, 0xa2, + 0x9d, 0x23, 0x9a, 0x1a, 0x30, 0x5a, 0xbc, 0x93, 0x77, 0xf8, 0xda, 0x14, 0x1d, 0x27, 0x1d, 0x7a, + 0x96, 0xd8, 0x6e, 0x53, 0x82, 0x2d, 0x90, 0xec, 0x6c, 0x44, 0x40, 0x28, 0xe5, 0x69, 0x87, 0xeb, + 0x4f, 0xab, 0x06, 0x15, 0x56, 0x10, 0x91, 0x41, 0x2f, 0x30, 0x48, 0x3f, 0xd1, 0x1a, 0xa9, 0xfb, + 0x69, 0x93, 0xe2, 0x21, 0x43, 0x32, 0x0e, 0x1a, 0x00, 0xce, 0xfb, 0xa0, 0x77, 0x72, 0x6b, 0x86, + 0xc7, 0x1c, 0x10, 0x12, 0x23, 0xf5, 0x2e, 0x2d, 0x56, 0x69, 0x02, 0x91, 0x0c, 0x5a, 0xb1, 0x24, + 0x00, 0xc5, 0xa5, 0x76, 0xb6, 0xa9, 0x3b, 0xb5, 0x05, 0xc5, 0xf0, 0xfd, 0xa8, 0x45, 0xfb, 0xc8, + 0x96, 0xb1, 0x02, 0x06, 0x8a, 0x31, 0x0d, 0x58, 0x40, 0xe3, 0x82, 0xa0, 0xcd, 0x82, 0x61, 0x14, + 0xb4, 0x20, 0xb2, 0x18, 0x61, 0x50, 0x33, 0x09, 0xc7, 0x16, 0x00, 0x54, 0xa0, 0x8f, 0x32, 0xba, + 0xc9, 0xc5, 0xd0, 0x04, 0x0e, 0xc6, 0x96, 0x90, 0x68, 0xda, 0x9e, 0xf8, 0x71, 0x43, 0x3f, 0x77, + 0x67, 0xc2, 0x03, 0x44, 0xaa, 0x34, 0x06, 0x0e, 0x19, 0x6c, 0x9a, 0x09, 0x9f, 0x60, 0x74, 0x69, + 0xd6, 0x92, 0x1f, 0x47, 0xdf, 0xab, 0xf0, 0xd3, 0xed, 0xbd, 0xb0, 0xcf, 0xec, 0xe4, 0x60, 0xbe, + 0x97, 0x6e, 0x2e, 0x80, 0x08, 0xaf, 0xd4, 0xe5, 0xa3, 0xf9, 0x78, 0x28, 0x1a, 0x92, 0x5a, 0x49, + 0x6f, 0xf1, 0x94, 0x92, 0xd2, 0x4b, 0x49, 0x2d, 0xa6, 0xb1, 0xfc, 0x11, 0x11, 0xbd, 0x24, 0xed, + 0xf4, 0x67, 0xfa, 0x2b, 0xc9, 0xd1, 0xcb, 0xca, 0xe8, 0x56, 0x55, 0xd1, 0xdc, 0xae, 0x59, 0xb0, + 0xd8, 0x7c, 0x7e, 0x1f, 0x10, 0x34, 0x50, 0x96, 0xa7, 0x1c, 0x06, 0xd8, 0xc1, 0x34, 0x83, 0x52, + 0x2f, 0x5d, 0x85, 0x8e, 0xcf, 0xa7, 0x43, 0xd0, 0xb1, 0xac, 0xc8, 0xf8, 0xf5, 0xe5, 0xc7, 0xc2, + 0x75, 0x7c, 0x1e, 0x44, 0x50, 0xfa, 0xcd, 0x0e, 0x24, 0x68, 0x8a, 0x61, 0x15, 0xe0, 0x3f, 0x91, + 0xa6, 0x09, 0x1f, 0x87, 0x9f, 0x92, 0x88, 0xa0, 0x06, 0x22, 0x38, 0xd0, 0x00, 0xa8, 0x1d, 0x4f, + 0xe1, 0xa5, 0x36, 0x3c, 0x03, 0xd8, 0xba, 0xe4, 0x3b, 0xea, 0xa3, 0x2f, 0xea, 0xb0, 0x04, 0x5a, + 0x46, 0x5e, 0xc9, 0x29, 0x40, 0x64, 0x86, 0xcc, 0x43, 0xba, 0xf0, 0x7c, 0x09, 0x39, 0xaa, 0xa0, + 0x94, 0x46, 0xe6, 0x84, 0x8d, 0xe7, 0xbe, 0x78, 0x5f, 0xc4, 0x04, 0x42, 0x95, 0xa3, 0xc0, 0x19, + 0xc2, 0x14, 0x7a, 0x62, 0xdc, 0x78, 0xf3, 0xde, 0xa3, 0x50, 0x87, 0x64, 0x9a, 0x02, 0x23, 0x3a, + 0x7d, 0x1c, 0xd0, 0xa5, 0x3e, 0x88, 0x34, 0x63, 0x5d, 0x8b, 0x17, 0xef, 0x5a, 0x4b, 0x9f, 0x0f, + 0x85, 0x59, 0x2d, 0xeb, 0xb4, 0xda, 0x40, 0x48, 0xfc, 0x6f, 0xe6, 0xc4, 0x19, 0xf2, 0x1f, 0x8f, + 0x85, 0x53, 0xde, 0xe4, 0x68, 0xc8, 0xdb, 0x6c, 0xc9, 0x5d, 0x17, 0x97, 0x93, 0xf8, 0x28, 0xed, + 0xb3, 0x66, 0x11, 0x30, 0x31, 0x26, 0xd8, 0xad, 0x7f, 0x1a, 0x32, 0xaa, 0x38, 0x75, 0x0c, 0x65, + 0xe2, 0x43, 0x37, 0x3c, 0xb4, 0x28, 0x20, 0x8f, 0x0f, 0x0e, 0x72, 0xed, 0xb0, 0x23, 0x68, 0xd7, + 0xe9, 0x97, 0x64, 0x5a, 0xb2, 0x7c, 0x3f, 0xc2, 0x82, 0x1e, 0x2e, 0x90, 0x5b, 0x0d, 0x61, 0x08, + 0xc4, 0x84, 0x0f, 0xb0, 0x39, 0x55, 0x9d, 0xca, 0x2d, 0xa0, 0xe5, 0xe1, 0xb0, 0x80, 0x12, 0x11, + 0xca, 0xe8, 0xaa, 0xb3, 0x8e, 0x50, 0x80, 0xb5, 0xa3, 0xc9, 0x2b, 0x6e, 0xa4, 0x59, 0xc3, 0xc6, + 0x8f, 0xc7, 0xb2, 0x9d, 0x30, 0x99, 0x5a, 0xdc, 0x59, 0xa1, 0x18, 0xa9, 0x31, 0xa9, 0xb0, 0xe5, + 0x47, 0x08, 0x60, 0x2e, 0x0c, 0x0a, 0x06, 0xc3, 0x6e, 0x1a, 0x29, 0xdf, 0x91, 0xce, 0x7a, 0x5f, + 0x12, 0x0a, 0xb5, 0x66, 0xe8, 0x6d, 0x21, 0x8a, 0x8f, 0x0c, 0xb1, 0x52, 0x68, 0xf5, 0x22, 0x7c, + 0x15, 0x88, 0x61, 0x16, 0x12, 0xfd, 0x87, 0x13, 0xe3, 0x60, 0x69, 0x62, 0xf0, 0x48, 0xcd, 0x8f, + 0xd0, 0x80, 0x65, 0xf0, 0xa0, 0x82, 0x5a, 0xc6, 0x4a, 0x89, 0x49, 0x09, 0x87, 0x53, 0xb8, 0x8d, + 0x7d, 0xd0, 0x6e, 0xed, 0x41, 0x00, 0x19, 0x51, 0xbc, 0x7e, 0x8b, 0x5c, 0x05, 0x0b, 0x80, 0x1b, + 0x9e, 0x49, 0x2b, 0xc8, 0x04, 0x56, 0x90, 0x51, 0xa4, 0x64, 0xf1, 0x88, 0xa3, 0xb2, 0x31, 0xc9, + 0x6f, 0x34, 0x72, 0xf2, 0x7f, 0xce, 0xae, 0xc8, 0x1f, 0x1e, 0x3b, 0xfc, 0x4c, 0x28, 0x79, 0x06, + 0x10, 0x13, 0x74, 0xc1, 0xa3, 0x8d, 0xbd, 0x1c, 0xb6, 0xe5, 0x48, 0x37, 0x62, 0x99, 0xd2, 0x8e, + 0x06, 0x94, 0xd1, 0x69, 0x9f, 0xf3, 0x8d, 0x23, 0xaa, 0xd4, 0x30, 0x1e, 0xed, 0xe5, 0x4f, 0x77, + 0xf0, 0x88, 0x2a, 0x09, 0xd7, 0xb5, 0xd8, 0x82, 0xad, 0x18, 0x9f, 0x94, 0x62, 0x2d, 0x2f, 0xa2, + 0x57, 0xd0, 0x8c, 0xbe, 0xb0, 0x7c, 0x11, 0x5d, 0xd5, 0x65, 0xf2, 0x8b, 0x4a, 0x92, 0x5e, 0x12, + 0xe9, 0x25, 0xb4, 0xd7, 0x8e, 0xb4, 0xd2, 0x49, 0x34, 0xd2, 0x56, 0x9a, 0x49, 0x9f, 0x84, 0x6d, + 0x35, 0xb4, 0xd6, 0xd3, 0x5f, 0x89, 0xe9, 0x25, 0xa4, 0x97, 0x84, 0x6d, 0x35, 0xb4, 0xd6, 0xd3, + 0x58, 0x8e, 0x08, 0x84, 0x3d, 0x5f, 0x10, 0xf4, 0x77, 0x2b, 0x9a, 0x92, 0x5f, 0x82, 0x1b, 0x4d, + 0x24, 0x93, 0x5f, 0x57, 0x1e, 0xfa, 0x49, 0x3e, 0x48, 0xca, 0x15, 0xaa, 0x55, 0xec, 0x7d, 0x19, + 0x95, 0xd9, 0xf6, 0x9a, 0x7d, 0x4a, 0x97, 0xd7, 0xbe, 0x09, 0xcd, 0xcb, 0xe5, 0x66, 0x87, 0xdc, + 0x48, 0x81, 0xa4, 0x87, 0x98, 0xa5, 0x48, 0x00, 0x0b, 0x0a, 0x84, 0x1c, 0xe3, 0xc1, 0x66, 0x90, + 0xeb, 0xd3, 0xd7, 0x0d, 0x32, 0x29, 0x86, 0x59, 0x18, 0x81, 0x3a, 0x7c, 0x5c, 0x7c, 0x14, 0x31, + 0x15, 0xfb, 0xb6, 0x78, 0x43, 0x71, 0x00, 0x4d, 0xc8, 0x49, 0x47, 0xdb, 0x9c, 0xf3, 0x7c, 0x5a, + 0x65, 0x4e, 0x86, 0xc5, 0x06, 0x4d, 0x7c, 0x05, 0x71, 0xf6, 0x18, 0x6e, 0x93, 0x0e, 0x8c, 0x62, + 0xca, 0xb3, 0x77, 0x85, 0xbc, 0x7d, 0xbd, 0x5a, 0x4c, 0x03, 0xe4, 0x05, 0x52, 0x84, 0xc6, 0x34, + 0x2c, 0xc5, 0xec, 0x0c, 0xd2, 0x0d, 0xcd, 0x09, 0x7b, 0xb8, 0xac, 0x2c, 0x71, 0x93, 0x74, 0xaf, + 0x89, 0x0a, 0x58, 0x58, 0xc1, 0xa8, 0x02, 0x6f, 0x04, 0x47, 0x6c, 0xb1, 0x65, 0x85, 0x9a, 0xc0, + 0xea, 0xcf, 0x23, 0x1e, 0xe8, 0x09, 0x05, 0x65, 0x46, 0x30, 0xf7, 0xe9, 0x3c, 0x87, 0x1f, 0x72, + 0xb6, 0x64, 0xb9, 0xf2, 0x9e, 0x37, 0xc3, 0xe1, 0x3e, 0x2e, 0x95, 0x82, 0x31, 0x8c, 0xa4, 0xed, + 0xc6, 0xd1, 0x00, 0x9f, 0x4d, 0x3f, 0xf0, 0x59, 0x8a, 0x23, 0x6d, 0x44, 0x20, 0x90, 0x82, 0x6a, + 0x79, 0xf2, 0xc4, 0x54, 0x55, 0xe1, 0xe0, 0xb5, 0xa4, 0x4f, 0xca, 0xd1, 0x03, 0xb8, 0x89, 0x94, + 0x61, 0xea, 0xd7, 0xa3, 0x8d, 0x76, 0x53, 0xff, 0x0a, 0x0b, 0x70, 0x9b, 0x10, 0xb1, 0x22, 0xae, + 0x6c, 0xfa, 0x9f, 0xf3, 0x76, 0xc1, 0xf5, 0x14, 0xe2, 0x37, 0x0d, 0x3b, 0x52, 0x6f, 0xe2, 0x55, + 0xe1, 0x1b, 0xc2, 0xe9, 0x8c, 0x04, 0x2b, 0xd2, 0x8a, 0x98, 0xf4, 0x4a, 0xfd, 0xa2, 0x88, 0x16, + 0x24, 0x42, 0x31, 0x57, 0xf0, 0xa5, 0x81, 0x9a, 0xb8, 0x37, 0x20, 0xe0, 0x07, 0x70, 0xc0, 0x6f, + 0xa0, 0x08, 0xd8, 0x24, 0x69, 0xca, 0xf4, 0xdd, 0xba, 0x43, 0x7e, 0x82, 0x44, 0xc7, 0x71, 0x1d, + 0x02, 0x36, 0x04, 0xaf, 0x34, 0x35, 0x17, 0xa0, 0xce, 0x82, 0x1e, 0x6b, 0xd0, 0x7c, 0x0f, 0xbf, + 0xc2, 0x82, 0xcc, 0x02, 0xb8, 0x6a, 0x6f, 0xa6, 0x6f, 0xbf, 0x81, 0xe7, 0x23, 0x0e, 0xaa, 0x31, + 0xf8, 0x3d, 0xdd, 0xc5, 0x63, 0xf2, 0x12, 0x3f, 0xb6, 0x6c, 0x75, 0x7f, 0x12, 0x84, 0x91, 0x3e, + 0xa3, 0xb7, 0xd0, 0x8a, 0xfa, 0xf7, 0xd4, 0xa0, 0xae, 0x8e, 0xe8, 0xfe, 0x8e, 0xc5, 0xf4, 0x47, + 0x25, 0xe5, 0xa5, 0xa6, 0x4e, 0x89, 0x33, 0xe8, 0xe7, 0x4b, 0xea, 0x74, 0x93, 0xa2, 0x57, 0xc1, + 0x44, 0xbd, 0x8c, 0xbe, 0x19, 0x39, 0x52, 0x37, 0xb4, 0x34, 0x5b, 0xe0, 0x80, 0xd8, 0x2c, 0x46, + 0xa9, 0xb3, 0x13, 0x9a, 0xc7, 0x9e, 0x90, 0x6c, 0x4a, 0xe6, 0xc3, 0xc8, 0x88, 0xc2, 0x20, 0x43, + 0x54, 0x29, 0x6a, 0x78, 0x47, 0xf1, 0xfe, 0x14, 0x11, 0x5d, 0x33, 0x87, 0x8d, 0xc8, 0xb1, 0x4e, + 0x08, 0xd2, 0x80, 0x30, 0x21, 0xd8, 0x2d, 0x15, 0x96, 0xce, 0x74, 0x82, 0xc5, 0x00, 0x00, 0x29, + 0xe4, 0x97, 0x30, 0xf3, 0xb0, 0x72, 0xb2, 0x83, 0xf0, 0x0e, 0x3e, 0x02, 0x57, 0xe9, 0xfd, 0xe7, + 0x40, 0xf2, 0x40, 0x30, 0x41, 0xf0, 0xa1, 0x3f, 0x7a, 0x58, 0x8d, 0xf6, 0x29, 0x38, 0x30, 0x17, + 0x66, 0x17, 0x5d, 0x16, 0xa6, 0x39, 0x42, 0x01, 0x47, 0x15, 0x3c, 0x05, 0xcb, 0xd1, 0x1b, 0xfa, + 0xea, 0x61, 0xc7, 0x72, 0xef, 0xb1, 0xfe, 0x1f, 0xf6, 0x08, 0xb1, 0x4e, 0x80, 0x55, 0xd4, 0xa4, + 0xe3, 0x23, 0xd2, 0xd5, 0x64, 0x9b, 0x67, 0x72, 0xd5, 0x5f, 0x69, 0xa3, 0xed, 0x78, 0x98, 0x53, + 0xc7, 0x7d, 0x64, 0xda, 0x18, 0x77, 0xf4, 0x69, 0xa4, 0x8c, 0x3c, 0xcc, 0x34, 0xee, 0xb6, 0xbc, + 0x20, 0x15, 0x93, 0x21, 0x35, 0x60, 0xb1, 0xc5, 0xf0, 0x53, 0x30, 0x41, 0x20, 0x40, 0x1b, 0x28, + 0x21, 0x59, 0x84, 0xee, 0x0c, 0x07, 0x4e, 0xbb, 0x7b, 0x33, 0x61, 0x47, 0x2a, 0x1c, 0x8f, 0xf0, + 0x4f, 0x63, 0x45, 0x59, 0x0a, 0x94, 0x30, 0xa0, 0x87, 0x61, 0x8b, 0x89, 0x10, 0x14, 0xc7, 0x42, + 0x4c, 0x78, 0xdb, 0x41, 0xbd, 0x68, 0x37, 0x04, 0x57, 0xc6, 0x15, 0x7d, 0x6c, 0x22, 0xac, 0x3b, + 0x54, 0xc1, 0x61, 0x09, 0xf4, 0x8f, 0x03, 0xb7, 0x7c, 0x14, 0x94, 0xa0, 0x02, 0x38, 0x55, 0x89, + 0x9a, 0x90, 0x74, 0xc2, 0x9a, 0x37, 0xf5, 0x31, 0x08, 0xda, 0x02, 0x5f, 0xc8, 0x17, 0xe8, 0x30, + 0xd3, 0x2f, 0x21, 0xac, 0xdd, 0x6b, 0xb4, 0x7f, 0xf8, 0x98, 0x29, 0x2c, 0x26, 0x70, 0xd8, 0x50, + 0x28, 0x21, 0x71, 0xb6, 0xb5, 0xe6, 0xb3, 0x9e, 0xf1, 0x28, 0x79, 0x0a, 0xba, 0x10, 0x3b, 0x7c, + 0x12, 0x1c, 0xec, 0x15, 0x8c, 0x89, 0xf5, 0xc2, 0x5e, 0x4a, 0x7a, 0x4b, 0x82, 0x5e, 0xd3, 0x5b, + 0x4d, 0x77, 0xd5, 0xe1, 0x4e, 0x08, 0x6d, 0x35, 0xf7, 0xde, 0x76, 0x28, 0x7e, 0xb1, 0x5f, 0x1f, + 0x69, 0xa4, 0x92, 0x6a, 0x92, 0xed, 0x35, 0xe8, 0x85, 0x4f, 0xa9, 0xd2, 0xf8, 0x24, 0x94, 0xca, + 0x01, 0x1c, 0xd3, 0x54, 0x61, 0xc4, 0xc2, 0x83, 0x06, 0x50, 0x1a, 0x2f, 0xd0, 0x92, 0x99, 0x61, + 0x3a, 0x56, 0x0a, 0xa8, 0xf6, 0x72, 0x07, 0x08, 0x26, 0x94, 0x2c, 0xe6, 0xa2, 0x38, 0x0c, 0x53, + 0xf0, 0xd5, 0x2e, 0x6e, 0x2f, 0x23, 0xcb, 0xff, 0x9e, 0x51, 0x01, 0xd4, 0x31, 0x78, 0x50, 0xa0, + 0x6f, 0x8e, 0x25, 0x8d, 0x17, 0x6e, 0x1b, 0xf4, 0x11, 0x46, 0x95, 0x69, 0x8d, 0x41, 0x57, 0x51, + 0x5b, 0xd4, 0x78, 0xce, 0xf8, 0xd9, 0x34, 0x97, 0xda, 0x56, 0x32, 0x0f, 0xe8, 0xd3, 0x1e, 0xca, + 0x1d, 0xf0, 0xa1, 0x53, 0xa4, 0xe3, 0xc0, 0xd0, 0xa5, 0xe4, 0x68, 0x62, 0x91, 0x2e, 0x21, 0x3e, + 0x9a, 0xd0, 0xdb, 0xa1, 0x8d, 0x85, 0xdc, 0x30, 0x90, 0xf9, 0xea, 0x69, 0x05, 0x53, 0x93, 0xfc, + 0x29, 0xd9, 0x22, 0xbf, 0xce, 0x88, 0xc0, 0xcd, 0x15, 0xa0, 0x80, 0x5f, 0x3b, 0x16, 0xb8, 0x1c, + 0x1d, 0xeb, 0x90, 0x6b, 0x7e, 0xa5, 0xd0, 0x3d, 0x9f, 0x0a, 0x5e, 0x18, 0xe0, 0x0d, 0x8c, 0x9e, + 0xe1, 0x82, 0xa2, 0xa6, 0xd8, 0x8c, 0x74, 0x6c, 0xb8, 0x7d, 0x2e, 0xde, 0xb0, 0x97, 0x94, 0xed, + 0x35, 0x62, 0x9a, 0x0f, 0x85, 0x0d, 0x4e, 0x89, 0x79, 0x52, 0x68, 0xc5, 0x79, 0x60, 0xde, 0x41, + 0xb6, 0x87, 0x3a, 0x09, 0xe1, 0x8a, 0x80, 0x83, 0x1a, 0x72, 0xa2, 0x06, 0x0b, 0x05, 0x51, 0x88, + 0x23, 0x6a, 0x30, 0x59, 0xf1, 0x96, 0x0c, 0x6c, 0x18, 0x28, 0x9e, 0x30, 0x56, 0x88, 0x2d, 0xba, + 0x64, 0x2a, 0x1a, 0x54, 0x12, 0x57, 0x96, 0xcd, 0x33, 0x66, 0x04, 0xd1, 0xf8, 0xfe, 0x09, 0x82, + 0x6b, 0x1d, 0xf6, 0x33, 0x21, 0x84, 0x4d, 0x28, 0xde, 0xf9, 0xe0, 0x2d, 0x27, 0x45, 0x8f, 0xbc, + 0x4f, 0xd5, 0x3c, 0x47, 0x42, 0x47, 0x57, 0xd1, 0x9a, 0xfa, 0xd4, 0xbc, 0xf1, 0xd5, 0x55, 0x55, + 0xf1, 0x1d, 0x5a, 0x2b, 0xa3, 0x15, 0x67, 0xd7, 0xbe, 0xb9, 0x5f, 0x57, 0xbe, 0x11, 0x1c, 0xcd, + 0x24, 0x24, 0x56, 0x0d, 0xbe, 0x18, 0x45, 0xb4, 0x33, 0x12, 0xa1, 0x97, 0xe1, 0x4f, 0x05, 0xcb, + 0x55, 0x15, 0x8d, 0x28, 0x7a, 0x05, 0x0d, 0xc1, 0x15, 0x81, 0x5e, 0x9d, 0xf6, 0xe7, 0xc1, 0x40, + 0x93, 0x9e, 0x92, 0x58, 0xe0, 0xd8, 0x59, 0xef, 0x8c, 0x23, 0x5b, 0xdd, 0x03, 0x6b, 0x4d, 0x01, + 0x87, 0xa0, 0xf8, 0x58, 0x6c, 0x9e, 0x18, 0x0b, 0xb3, 0xcd, 0x9b, 0xd7, 0xc1, 0x15, 0x89, 0x33, + 0x33, 0x57, 0x7d, 0x15, 0xfe, 0x41, 0x4d, 0x31, 0x6f, 0x4d, 0x7a, 0xf9, 0x42, 0x32, 0xd1, 0x8b, + 0xe2, 0x38, 0x8a, 0x2f, 0x7d, 0x6a, 0x27, 0xab, 0x93, 0xf5, 0xaa, 0xeb, 0x11, 0xdf, 0xab, 0x11, + 0xbd, 0x19, 0x88, 0x8e, 0x8b, 0x52, 0x71, 0x61, 0x22, 0x20, 0x43, 0xc1, 0x66, 0x34, 0xa9, 0x94, + 0xb2, 0x40, 0xe2, 0x79, 0xe5, 0x9b, 0x10, 0x18, 0xd6, 0xc2, 0x0d, 0x84, 0xb9, 0x8b, 0x53, 0x79, + 0xf0, 0x85, 0x6a, 0x40, 0xc2, 0xb2, 0x18, 0xa6, 0xe0, 0x12, 0xd6, 0x27, 0xa1, 0xe4, 0x4b, 0xea, + 0xe0, 0x27, 0xd5, 0x3a, 0x5d, 0x11, 0xe4, 0xea, 0xd1, 0x5d, 0x17, 0x5f, 0x44, 0x7a, 0xe4, 0x09, + 0x72, 0x04, 0x01, 0x63, 0x7c, 0x47, 0x91, 0x88, 0x3f, 0xc0, 0x4e, 0xdb, 0x38, 0xde, 0x5e, 0x24, + 0xea, 0x7d, 0x0d, 0xa5, 0x34, 0xd0, 0xdf, 0xec, 0xe8, 0x68, 0x68, 0x68, 0x7e, 0xbd, 0xf3, 0x0c, + 0xdb, 0x5f, 0x41, 0x7c, 0xa2, 0xfa, 0x2a, 0x58, 0x7f, 0xa1, 0xee, 0x7d, 0x04, 0x3f, 0xf0, 0x90, + 0xad, 0xb6, 0xcf, 0xd5, 0xb6, 0xfc, 0x11, 0x5b, 0x57, 0xff, 0xe5, 0x22, 0xaa, 0x91, 0x42, 0xe5, + 0x93, 0xd2, 0x52, 0x74, 0x78, 0xbe, 0x41, 0x4d, 0x87, 0x68, 0x37, 0xf8, 0x40, 0x94, 0xeb, 0xad, + 0xac, 0x99, 0xf0, 0x46, 0x13, 0xb1, 0x9b, 0x18, 0xa1, 0x2a, 0x0a, 0xf4, 0x4a, 0xfa, 0xe5, 0x11, + 0xd5, 0xe2, 0xfa, 0xb0, 0x27, 0x63, 0x97, 0xaf, 0xbb, 0xbb, 0xfc, 0x11, 0x8b, 0x55, 0xab, 0xdf, + 0x21, 0xdf, 0x7f, 0x56, 0x7d, 0x7b, 0xe2, 0x06, 0x2d, 0x55, 0x42, 0xf3, 0x18, 0xbc, 0x26, 0x46, + 0x53, 0x55, 0xd2, 0xba, 0xf8, 0x23, 0x0a, 0xd5, 0x5e, 0xc7, 0xd1, 0x7a, 0x14, 0xe8, 0x46, 0x50, + 0x9f, 0x30, 0x8a, 0xaa, 0xfa, 0xf5, 0xf6, 0x21, 0x0f, 0x7f, 0x05, 0x25, 0x72, 0x29, 0x1b, 0xcd, + 0x94, 0xe4, 0x91, 0x6b, 0xc7, 0x98, 0xb1, 0x96, 0xbe, 0x86, 0xbf, 0xd1, 0x62, 0x40, 0xf3, 0x76, + 0x37, 0xf4, 0x46, 0xf9, 0x04, 0x36, 0x9f, 0xe5, 0x8b, 0xbd, 0x8b, 0xd8, 0x81, 0x72, 0x7a, 0xf9, + 0x44, 0xdd, 0x61, 0x8e, 0x8f, 0xd5, 0xd1, 0xd2, 0x2f, 0x45, 0x4e, 0xbd, 0x11, 0x8f, 0xa9, 0x41, + 0x5d, 0x19, 0xbe, 0xad, 0xf4, 0x57, 0x2f, 0xab, 0x3e, 0x73, 0x56, 0x9c, 0xdf, 0xfc, 0x49, 0x11, + 0x27, 0x4e, 0x5c, 0x6a, 0x7c, 0x26, 0x4c, 0x98, 0xb5, 0xaf, 0x82, 0x93, 0x8d, 0x44, 0x53, 0xd6, + 0x66, 0x3d, 0xdb, 0x4d, 0xf1, 0x56, 0x16, 0x7f, 0x74, 0x7f, 0x04, 0x53, 0x39, 0x08, 0x74, 0x69, + 0xe6, 0xf8, 0xf1, 0x0e, 0x43, 0x4c, 0x3d, 0xe8, 0xb6, 0x88, 0x8e, 0x01, 0x7b, 0x3a, 0xb0, 0x40, + 0x59, 0xcb, 0x5b, 0x14, 0xf8, 0x29, 0x12, 0xcb, 0x1d, 0x4c, 0x31, 0x37, 0x3b, 0x59, 0x0e, 0x31, + 0xaf, 0xff, 0x04, 0x95, 0x55, 0x54, 0xeb, 0xc1, 0x55, 0xa3, 0x90, 0x52, 0xba, 0x37, 0xcb, 0x43, + 0xe5, 0x9d, 0x3e, 0x0a, 0xb8, 0x6a, 0x56, 0x7d, 0x5e, 0xcd, 0x03, 0x74, 0x77, 0xf8, 0x26, 0x2b, + 0xdf, 0xa4, 0xd2, 0x55, 0xe0, 0xa6, 0xc9, 0x22, 0xd2, 0x81, 0x33, 0xb9, 0xb0, 0x84, 0xbb, 0x4f, + 0xf0, 0x49, 0x45, 0x5a, 0x4f, 0x82, 0x52, 0x2a, 0xaa, 0x47, 0xfb, 0xe7, 0xf8, 0x22, 0x24, 0x99, + 0x36, 0x65, 0xf1, 0xe2, 0xb1, 0x7c, 0xd9, 0x26, 0x05, 0x6d, 0x0f, 0x4b, 0xf1, 0x73, 0x22, 0xbb, + 0x9a, 0x99, 0x24, 0x3c, 0x36, 0x24, 0xd8, 0x83, 0x3a, 0x20, 0x32, 0xbf, 0x9b, 0x53, 0x1b, 0xd1, + 0xd8, 0xae, 0x8d, 0x29, 0x39, 0x8e, 0xf7, 0x9f, 0xaf, 0x4f, 0xd1, 0x4c, 0x9f, 0x14, 0x22, 0x19, + 0x96, 0xcf, 0xca, 0x8a, 0xdf, 0x82, 0xc3, 0x5a, 0x8b, 0x96, 0x21, 0xf3, 0xe4, 0x74, 0xa6, 0x98, + 0x5e, 0x4c, 0xae, 0x83, 0x25, 0xf1, 0xd5, 0x33, 0x05, 0x18, 0xc1, 0x0b, 0xd8, 0x59, 0xd7, 0x89, + 0x04, 0x7c, 0xd0, 0x3a, 0x87, 0xfa, 0x3f, 0x7c, 0x10, 0xd2, 0x6f, 0x7f, 0x8d, 0x11, 0x79, 0x42, + 0x03, 0x60, 0x26, 0x61, 0x23, 0x3c, 0x03, 0x1b, 0x4c, 0xbf, 0x40, 0xd1, 0x44, 0x08, 0xdd, 0x9a, + 0xff, 0xe2, 0xfe, 0x1f, 0x94, 0x68, 0xa5, 0x77, 0x10, 0x1e, 0xde, 0xee, 0xdb, 0x69, 0x38, 0xf3, + 0x0d, 0x19, 0x4d, 0x7f, 0x82, 0xb8, 0xcc, 0x5a, 0x79, 0xcb, 0x3e, 0xe7, 0x50, 0xc6, 0xc1, 0xd6, + 0x65, 0xd8, 0xf8, 0x9d, 0x9b, 0x98, 0xfb, 0x52, 0xb2, 0xf8, 0x03, 0x61, 0x78, 0xe1, 0xac, 0x93, + 0xac, 0xbc, 0xdb, 0xd8, 0xc7, 0x2a, 0x80, 0x7e, 0x0a, 0xe7, 0xe4, 0xda, 0xb4, 0x96, 0xac, 0xb6, + 0xf8, 0x2a, 0xbb, 0x1c, 0xaa, 0x2c, 0x36, 0x44, 0x73, 0xec, 0xd1, 0x9d, 0xbe, 0x0a, 0xe9, 0x8e, + 0xa1, 0xd7, 0x95, 0x0e, 0x19, 0xca, 0x16, 0x5a, 0x18, 0xe9, 0x11, 0xbe, 0x14, 0xee, 0x86, 0x32, + 0x22, 0x3d, 0xca, 0xc7, 0x5d, 0x23, 0xb1, 0xbf, 0xd5, 0xfe, 0x24, 0xb3, 0x8d, 0x37, 0xb1, 0xbf, + 0xe2, 0x8b, 0x69, 0xc6, 0xd6, 0xfc, 0xfc, 0x16, 0x98, 0x85, 0x6b, 0xb7, 0x2b, 0x1f, 0x1e, 0x0a, + 0x89, 0x34, 0xf2, 0xd9, 0x6c, 0x4b, 0xee, 0x34, 0x7d, 0xdf, 0xec, 0x53, 0x18, 0x5d, 0x55, 0xd1, + 0xf8, 0x29, 0xb4, 0xd9, 0xd4, 0xd3, 0xdc, 0xf4, 0x36, 0xdb, 0x57, 0x3e, 0x1c, 0x12, 0x92, 0x02, + 0xa6, 0xd9, 0x92, 0x9a, 0xbf, 0x85, 0x7a, 0xb7, 0xd5, 0xa4, 0xeb, 0xfb, 0xeb, 0xd5, 0xc1, 0x17, + 0x76, 0x9f, 0xe1, 0x42, 0x3a, 0x27, 0xa4, 0x2e, 0x36, 0x6e, 0x90, 0xfa, 0x8e, 0xee, 0x4f, 0xf2, + 0x85, 0x67, 0xf9, 0x19, 0xfe, 0x6b, 0x48, 0x6a, 0xdf, 0x82, 0xcb, 0x06, 0x3e, 0xc9, 0xa9, 0x48, + 0xc2, 0x03, 0xca, 0x3a, 0xb7, 0xc1, 0x4e, 0x03, 0xba, 0x34, 0xe8, 0x34, 0x97, 0x56, 0x3e, 0x2c, + 0x4e, 0x3e, 0x10, 0x17, 0x52, 0x8a, 0xfe, 0x61, 0x12, 0xe3, 0xdf, 0x8a, 0x8c, 0x77, 0x9c, 0x30, + 0x16, 0x59, 0xda, 0x73, 0x2b, 0x8f, 0xa1, 0xb4, 0x93, 0x3e, 0xdc, 0x43, 0x40, 0xed, 0x1c, 0xad, + 0x1f, 0x82, 0x2b, 0x6d, 0x6e, 0x7c, 0x15, 0x8b, 0xa0, 0x69, 0xd4, 0x7c, 0x11, 0xb7, 0x84, 0x50, + 0xf8, 0xf3, 0xc1, 0xfe, 0x08, 0x89, 0x32, 0xa4, 0x5e, 0xff, 0x05, 0xd3, 0x2b, 0x38, 0xc4, 0xe1, + 0x8c, 0x13, 0x6d, 0xd8, 0x0a, 0x7f, 0x82, 0x32, 0xdb, 0x76, 0x7f, 0xfa, 0xc5, 0xf4, 0x5b, 0x7c, + 0x9c, 0x9a, 0xbe, 0x0a, 0x4c, 0xad, 0x55, 0x66, 0xf7, 0x17, 0x43, 0x37, 0x2a, 0xfe, 0x09, 0xa6, + 0xfa, 0xa3, 0x77, 0x77, 0x63, 0xe0, 0x86, 0xa6, 0x72, 0xd0, 0x37, 0xf8, 0x29, 0xb9, 0x85, 0x5f, + 0x66, 0x90, 0x42, 0xf5, 0xae, 0xc4, 0x21, 0x60, 0xb6, 0xcf, 0x8a, 0x14, 0x90, 0xe8, 0x76, 0x6e, + 0x62, 0xff, 0x96, 0x38, 0x5c, 0x35, 0x6a, 0x1a, 0xe8, 0x5f, 0x7d, 0x62, 0xbe, 0x09, 0x3a, 0x65, + 0x66, 0xbe, 0x34, 0xd2, 0x90, 0x67, 0xc1, 0xbb, 0x0e, 0xea, 0xe5, 0x31, 0x28, 0x7f, 0xf4, 0x1a, + 0x9f, 0x3e, 0x2a, 0xc7, 0xa7, 0xa4, 0x28, 0xf5, 0x1c, 0xc2, 0x2a, 0xbf, 0x89, 0x0a, 0x4f, 0x48, + 0x3b, 0xea, 0xfa, 0xa9, 0x14, 0x51, 0x34, 0xc5, 0x70, 0x72, 0xb7, 0x77, 0xf8, 0x29, 0xaa, 0xd9, + 0xd1, 0x8d, 0xd1, 0xe6, 0x2a, 0x4c, 0x4b, 0xf9, 0xf0, 0xa7, 0x46, 0x46, 0xb8, 0x50, 0x55, 0x4c, + 0x00, 0xe7, 0xa7, 0x93, 0xa6, 0xde, 0x73, 0xde, 0x62, 0x70, 0xf7, 0xfb, 0xc7, 0x60, 0x81, 0xf8, + 0x53, 0x3a, 0xd5, 0x63, 0xc5, 0x3f, 0x40, 0x25, 0x59, 0x30, 0xf7, 0xc1, 0x67, 0x2a, 0x54, 0xcc, + 0xcb, 0x14, 0x64, 0x08, 0x68, 0x9b, 0xad, 0x02, 0xcb, 0xe5, 0x21, 0x25, 0x81, 0x22, 0xf2, 0xee, + 0xef, 0xe1, 0x43, 0x8c, 0xa0, 0xad, 0x68, 0x3e, 0xf1, 0x20, 0x1a, 0x49, 0xcb, 0x8d, 0x26, 0x4f, + 0x7d, 0x5a, 0xf7, 0xcc, 0x75, 0x17, 0x17, 0x17, 0xf5, 0xff, 0xc1, 0x09, 0x1d, 0x9e, 0xff, 0x04, + 0x56, 0xb6, 0x9f, 0xe0, 0xb7, 0xa4, 0xd6, 0x9a, 0x5d, 0xf0, 0x47, 0x4e, 0xdb, 0x0e, 0xbe, 0x0a, + 0x04, 0xd0, 0xcc, 0x4e, 0x27, 0x5c, 0xe9, 0xf0, 0x9d, 0xb2, 0x74, 0x0f, 0x14, 0xd5, 0x55, 0x70, + 0x48, 0x21, 0x8c, 0x78, 0xe2, 0xc1, 0xf0, 0xfe, 0x0a, 0xaa, 0x92, 0x99, 0x46, 0x76, 0xa4, 0xe2, + 0xb7, 0x77, 0xf8, 0x24, 0xb5, 0x76, 0x7d, 0xf0, 0x57, 0x9c, 0x93, 0x15, 0x68, 0xe3, 0x2d, 0x61, + 0xc7, 0xab, 0xb8, 0x11, 0xf7, 0xc2, 0x86, 0x53, 0x18, 0xe2, 0x20, 0x00, 0x13, 0x60, 0x48, 0xc2, + 0x83, 0xf1, 0x01, 0x7e, 0x35, 0x5d, 0x6a, 0x0a, 0x3d, 0x01, 0x14, 0x95, 0xf8, 0x58, 0x83, 0x06, + 0xde, 0x95, 0x0d, 0x6b, 0xd8, 0xf9, 0xab, 0xff, 0xe8, 0xe7, 0xc7, 0xc1, 0x75, 0xb3, 0x45, 0x96, + 0x7f, 0xda, 0x7e, 0x8b, 0xd3, 0xf4, 0x4a, 0x8b, 0xea, 0xca, 0xe0, 0xaf, 0x33, 0x7a, 0x74, 0xe1, + 0xe9, 0x26, 0xbc, 0x5f, 0x77, 0xa9, 0x8e, 0x71, 0x5f, 0x1a, 0x54, 0xab, 0xd3, 0x6a, 0xe6, 0x3b, + 0x7a, 0x03, 0x28, 0x82, 0x41, 0x01, 0xce, 0x8f, 0xf7, 0xbb, 0x7e, 0x3e, 0x9e, 0x64, 0x4d, 0x24, + 0xd2, 0xf2, 0xe8, 0x34, 0x3f, 0x82, 0x81, 0x44, 0xa7, 0xca, 0xbe, 0xbe, 0x0a, 0xce, 0x25, 0xf1, + 0xba, 0x55, 0x63, 0x89, 0x57, 0xd3, 0x2b, 0x0c, 0x6c, 0x6f, 0x7c, 0x27, 0x42, 0x2d, 0x28, 0x44, + 0x53, 0x90, 0xc7, 0xc1, 0x4f, 0x8f, 0x0e, 0xed, 0x78, 0x18, 0x05, 0xca, 0x1b, 0x9e, 0xef, 0xbd, + 0x8c, 0x8c, 0xc6, 0xb8, 0x26, 0x3b, 0x61, 0x00, 0x87, 0xcc, 0xa3, 0xe6, 0x40, 0x74, 0x83, 0x1b, + 0xe1, 0x4d, 0x81, 0x99, 0x86, 0xb2, 0xdd, 0xac, 0x79, 0xd8, 0xa6, 0x12, 0x6a, 0x72, 0xe2, 0xe9, + 0x2a, 0xf0, 0x59, 0x47, 0x3b, 0x90, 0xd2, 0x40, 0xd5, 0x0b, 0x81, 0x61, 0x8e, 0x61, 0x26, 0xe3, + 0xef, 0x85, 0x21, 0x9c, 0xf8, 0xfb, 0x76, 0x3b, 0x1d, 0xec, 0x43, 0x45, 0xd7, 0x28, 0x3b, 0xa1, + 0xad, 0x11, 0x2c, 0xa1, 0x5f, 0xe8, 0x89, 0x7e, 0xbd, 0xf0, 0x50, 0x54, 0xf4, 0xd5, 0x0f, 0x3f, + 0xf8, 0x21, 0x13, 0x7b, 0xb3, 0xe1, 0x42, 0x48, 0xc7, 0xca, 0xc4, 0x94, 0x43, 0xfa, 0x4e, 0xff, + 0x04, 0xc3, 0x2b, 0x5a, 0x06, 0xa9, 0xcb, 0xe0, 0xb0, 0xee, 0x3e, 0xbc, 0x3e, 0xad, 0x5b, 0x60, + 0xd4, 0x83, 0x3d, 0x70, 0x8f, 0x24, 0xff, 0x0a, 0x6c, 0x65, 0xe8, 0x7c, 0xa9, 0xb8, 0xad, 0x8e, + 0xfb, 0x89, 0xdf, 0x9c, 0xb5, 0xff, 0xf0, 0x56, 0x76, 0x74, 0x94, 0xd4, 0xda, 0x41, 0xbc, 0x49, + 0x1d, 0x03, 0x8e, 0x8c, 0x73, 0xdc, 0x61, 0xc4, 0x85, 0x23, 0xfc, 0x4c, 0x38, 0xda, 0x67, 0x24, + 0x49, 0x2e, 0xb7, 0x82, 0x15, 0xbb, 0x5b, 0xee, 0x9b, 0x11, 0xc9, 0x34, 0x00, 0x0e, 0x1d, 0x42, + 0x91, 0xcf, 0xf4, 0x4a, 0xae, 0x10, 0x11, 0x93, 0xa3, 0x27, 0x64, 0x17, 0x92, 0x06, 0x33, 0x57, + 0x9e, 0xc4, 0x70, 0xd1, 0x5a, 0x99, 0x86, 0x8d, 0x7f, 0xaf, 0x49, 0xd1, 0xe2, 0xae, 0xaf, 0x0a, + 0x70, 0x44, 0x22, 0x3f, 0x10, 0x19, 0x69, 0x7b, 0x85, 0xc1, 0x50, 0xb4, 0x1e, 0x76, 0x07, 0x07, + 0x8b, 0x84, 0x34, 0x1e, 0x3c, 0x3a, 0x2e, 0xa1, 0x25, 0x4b, 0xf7, 0xf8, 0x24, 0x32, 0x48, 0x33, + 0xad, 0xf7, 0xc1, 0x19, 0xa7, 0xd6, 0x6e, 0x99, 0x6f, 0xa3, 0xbc, 0xbd, 0x1f, 0xff, 0x44, 0xef, + 0x82, 0x62, 0xaa, 0x45, 0x80, 0x7e, 0x10, 0xb9, 0x71, 0x54, 0x42, 0x3f, 0xf0, 0x4c, 0x47, 0x77, + 0xe5, 0xc4, 0x0b, 0xbe, 0x0b, 0x4a, 0x33, 0x48, 0x03, 0xde, 0x56, 0x19, 0x79, 0x3a, 0xf0, 0xcd, + 0xd8, 0x0a, 0x9e, 0x56, 0xdb, 0x6d, 0xbf, 0xf1, 0x45, 0xa3, 0x7c, 0xec, 0x7e, 0x3f, 0xaa, 0xa3, + 0x97, 0x2a, 0xb2, 0x2f, 0xe0, 0xaf, 0x56, 0x76, 0x24, 0x9e, 0xc3, 0xd4, 0x21, 0xb1, 0xb8, 0x33, + 0x6f, 0xf1, 0x03, 0x9a, 0xdc, 0xe9, 0x1e, 0xdf, 0x89, 0x0a, 0x1e, 0x80, 0xde, 0x20, 0x28, 0xbd, + 0xa8, 0xe8, 0xca, 0xcb, 0x72, 0x4b, 0xe9, 0x56, 0x24, 0x48, 0x28, 0xbb, 0x96, 0x8f, 0x83, 0x3b, + 0xc8, 0x3e, 0xf1, 0x02, 0xc4, 0x92, 0xe5, 0xa6, 0xeb, 0xf0, 0xa5, 0x61, 0xd4, 0xca, 0x81, 0x99, + 0xab, 0x86, 0x23, 0x9e, 0xf5, 0x98, 0x10, 0x0d, 0x43, 0x4d, 0x2f, 0x0f, 0xd0, 0x4a, 0x07, 0xfd, + 0x1f, 0x17, 0xc1, 0x3d, 0x8e, 0xf2, 0xa4, 0xd1, 0xbf, 0xc1, 0x69, 0x13, 0x56, 0x0d, 0x4f, 0x0f, + 0xef, 0x82, 0x51, 0x02, 0xf5, 0x98, 0x82, 0xa4, 0x3c, 0x1b, 0x81, 0x00, 0x58, 0xf8, 0x73, 0x2a, + 0x1b, 0x8d, 0x42, 0x2d, 0x8e, 0x51, 0x84, 0x6c, 0xf7, 0xfe, 0x1d, 0x3a, 0x36, 0xa9, 0xd0, 0x98, + 0xcd, 0xa8, 0x51, 0xf2, 0xee, 0x96, 0xcf, 0xdb, 0x37, 0xa9, 0x7a, 0x33, 0xfd, 0x15, 0xbe, 0xad, + 0x27, 0x56, 0xae, 0xaf, 0x3f, 0x04, 0x7b, 0xbd, 0xa5, 0xe4, 0xb4, 0xbf, 0x98, 0x83, 0xf1, 0xf0, + 0xb4, 0xb8, 0x90, 0x52, 0x54, 0x09, 0x43, 0x38, 0x3a, 0xad, 0x23, 0xcf, 0x2e, 0x5c, 0xc9, 0xe2, + 0x41, 0x45, 0x26, 0xdf, 0x96, 0x09, 0x39, 0xf0, 0x57, 0x44, 0x92, 0x11, 0xd4, 0xb4, 0xc1, 0x01, + 0xe5, 0xda, 0x8f, 0xbe, 0x14, 0x91, 0x56, 0xf4, 0x86, 0xd1, 0x11, 0xac, 0x08, 0xbb, 0x92, 0x47, + 0x99, 0xa5, 0x0f, 0x3a, 0xdd, 0xe2, 0x01, 0x39, 0x15, 0xbf, 0x9b, 0xf5, 0xf1, 0x82, 0x5d, 0x98, + 0xe8, 0x00, 0x58, 0x30, 0xd2, 0xad, 0xd0, 0x37, 0xd3, 0x99, 0x98, 0xc8, 0x83, 0x60, 0x6c, 0xa7, + 0x82, 0x4d, 0x11, 0x92, 0x6e, 0xf8, 0x2a, 0x8e, 0x0d, 0x0f, 0x67, 0x4d, 0x50, 0x1a, 0x41, 0x44, + 0x44, 0x11, 0x92, 0x46, 0x4f, 0xfc, 0x11, 0x92, 0x0f, 0x99, 0x97, 0xf8, 0x44, 0xa6, 0xa3, 0x0d, + 0x8e, 0x8c, 0x8a, 0xea, 0xd3, 0x63, 0xb0, 0x8f, 0xf0, 0xa7, 0x41, 0xbb, 0x90, 0xba, 0x6e, 0x45, + 0xb9, 0x53, 0xcc, 0x97, 0x15, 0x86, 0xaa, 0x08, 0x83, 0x6d, 0x00, 0x00, 0xd0, 0x93, 0x87, 0x82, + 0x4b, 0xbb, 0xbb, 0x7d, 0x68, 0xe3, 0x5d, 0x5f, 0xe8, 0x9d, 0xf0, 0x53, 0xb0, 0x67, 0x96, 0x58, + 0x1f, 0xd8, 0x53, 0xf9, 0xff, 0x78, 0x80, 0x56, 0x52, 0x84, 0x01, 0xa0, 0xad, 0xde, 0x1f, 0x82, + 0x69, 0x00, 0x68, 0x02, 0x3e, 0x32, 0x3f, 0x0f, 0xe1, 0x49, 0x42, 0x2d, 0x10, 0x17, 0x25, 0x44, + 0x23, 0x26, 0xca, 0x5d, 0x6a, 0x5b, 0x71, 0xb0, 0x82, 0xb2, 0xe3, 0x77, 0xcc, 0x3e, 0x14, 0xb2, + 0x7a, 0x48, 0xd0, 0x13, 0x00, 0x8e, 0x0d, 0x55, 0x16, 0xdc, 0xb4, 0x57, 0x87, 0x14, 0xdd, 0x77, + 0xf8, 0x25, 0x2d, 0xb4, 0x40, 0xbf, 0x40, 0xd0, 0x18, 0xe8, 0xfe, 0x62, 0x5f, 0xfc, 0x15, 0x54, + 0x73, 0xba, 0x75, 0x9d, 0x74, 0x13, 0x29, 0xb2, 0x51, 0xdc, 0xf8, 0x25, 0x22, 0x1e, 0x84, 0xf3, + 0x99, 0x31, 0xdf, 0x2f, 0x8c, 0xaa, 0x06, 0x96, 0x32, 0x0f, 0x9d, 0x6e, 0x45, 0x06, 0xa3, 0x1b, + 0x61, 0xf8, 0x4c, 0x56, 0x84, 0xaa, 0x52, 0x14, 0x4b, 0xf3, 0x14, 0xc4, 0x58, 0xd3, 0xf8, 0x74, + 0xe0, 0x99, 0xa9, 0x22, 0x88, 0xfa, 0x28, 0x7a, 0x37, 0x82, 0x4f, 0x81, 0xcf, 0x7c, 0x25, 0x06, + 0x88, 0x03, 0x32, 0x4b, 0x68, 0x83, 0x09, 0xec, 0xc3, 0xc6, 0xa9, 0xf9, 0xeb, 0xea, 0xea, 0xe2, + 0xfa, 0xbf, 0xc1, 0x25, 0xbb, 0x69, 0xea, 0x2f, 0x9c, 0x56, 0x14, 0x4c, 0xa2, 0xcf, 0xfc, 0x3e, + 0x72, 0x41, 0x80, 0xed, 0x8c, 0x82, 0x23, 0xe7, 0x0e, 0xd0, 0x19, 0xd1, 0x1d, 0x21, 0xe7, 0xee, + 0x7e, 0xb1, 0x20, 0x9f, 0x37, 0x3a, 0x8f, 0x8f, 0x68, 0xf5, 0xcd, 0x6c, 0xb1, 0xd7, 0x75, 0x1a, + 0x10, 0x25, 0x97, 0xc1, 0x56, 0x9b, 0xb0, 0x76, 0xee, 0xe3, 0x43, 0x1f, 0xff, 0xf5, 0xfb, 0xe0, + 0x98, 0xaf, 0x96, 0x93, 0x32, 0x3c, 0x39, 0xd8, 0x25, 0xdf, 0x05, 0xda, 0x6a, 0x86, 0xc4, 0xf7, + 0x7f, 0x84, 0xb4, 0x06, 0xa9, 0x9d, 0x8d, 0x01, 0x30, 0x7e, 0x14, 0xad, 0x25, 0xd5, 0x6d, 0xa0, + 0xc7, 0x6c, 0x2a, 0xc3, 0x9d, 0x7f, 0x04, 0x74, 0x66, 0xa5, 0xdf, 0xe0, 0x8e, 0xb3, 0x66, 0x5f, + 0x05, 0x91, 0xfd, 0xfe, 0x30, 0xf4, 0xfd, 0x00, 0xc7, 0xec, 0x3f, 0xc1, 0x59, 0xa6, 0x97, 0x7b, + 0x2d, 0x23, 0xe6, 0x1b, 0xfb, 0xc4, 0x82, 0xa2, 0xa4, 0xf8, 0x17, 0x21, 0x39, 0x69, 0x3e, 0x0f, + 0xab, 0xcc, 0x60, 0xda, 0x18, 0x0e, 0xff, 0x04, 0x7a, 0x6d, 0xb6, 0xdf, 0x05, 0x92, 0x9c, 0x94, + 0x46, 0x44, 0xcd, 0x9a, 0x32, 0xe9, 0x58, 0x64, 0x61, 0xc1, 0x0f, 0xc7, 0xc9, 0x77, 0x77, 0xf0, + 0x44, 0x7d, 0x90, 0xc6, 0xa7, 0x4f, 0x82, 0x82, 0x1d, 0x86, 0x6e, 0x7a, 0x06, 0x72, 0x74, 0x3f, + 0x2a, 0xf0, 0x5a, 0x57, 0x62, 0xba, 0xa7, 0xc5, 0xf0, 0x44, 0x45, 0x18, 0x4c, 0x2f, 0x5f, 0x1d, + 0xe4, 0xae, 0x40, 0xc0, 0xcc, 0x08, 0x06, 0x6f, 0x47, 0xe8, 0x54, 0xff, 0x2d, 0x84, 0x98, 0xaf, + 0xe0, 0xbc, 0xab, 0xa6, 0x99, 0xe7, 0xaa, 0x43, 0x47, 0xae, 0x48, 0x64, 0x81, 0x9e, 0x2b, 0xab, + 0xd7, 0x57, 0xf9, 0x8b, 0x6d, 0xb4, 0x32, 0xf5, 0x7a, 0xea, 0xf5, 0xd9, 0xaf, 0x3e, 0xf8, 0xc2, + 0x42, 0x45, 0x8b, 0x28, 0x9a, 0x71, 0xc6, 0x0c, 0x77, 0x8a, 0x21, 0x4d, 0xf7, 0xc1, 0x85, 0x04, + 0x61, 0x11, 0xb9, 0xd2, 0x8e, 0x60, 0xbd, 0x45, 0x27, 0x1e, 0x35, 0xf0, 0x5a, 0x24, 0xc6, 0x7a, + 0x6a, 0x9c, 0x98, 0xcc, 0xbe, 0x58, 0xc5, 0xde, 0xaf, 0x12, 0x0a, 0xce, 0x84, 0x76, 0x23, 0xc3, + 0x30, 0xd1, 0xb8, 0x7c, 0x28, 0x95, 0x70, 0x38, 0x20, 0x18, 0x69, 0xb1, 0xa0, 0x78, 0xc4, 0x1e, + 0x24, 0x16, 0x13, 0x19, 0xab, 0xca, 0xd9, 0xd4, 0xe6, 0xd9, 0x14, 0x16, 0x3e, 0xb8, 0x25, 0x32, + 0x90, 0x10, 0x07, 0x2c, 0x2f, 0x7f, 0x82, 0x12, 0xb2, 0x42, 0x4c, 0x81, 0xb7, 0xf8, 0x2e, 0x2c, + 0xac, 0x1c, 0x3d, 0xcb, 0x1b, 0x27, 0xf8, 0x2a, 0x28, 0xd8, 0xc4, 0xd8, 0xa2, 0x2b, 0x1f, 0x70, + 0x20, 0x65, 0xb6, 0x3d, 0xee, 0x7c, 0x17, 0x65, 0x93, 0x3d, 0x01, 0x43, 0x32, 0x84, 0xff, 0xe0, + 0xa0, 0xd1, 0x93, 0xee, 0x63, 0xdb, 0x97, 0xc1, 0x61, 0x52, 0x4e, 0xcd, 0x3b, 0xd2, 0x7a, 0x0e, + 0x8e, 0xfc, 0x16, 0xdb, 0x6a, 0x86, 0x36, 0x08, 0x8f, 0x7c, 0xff, 0x5e, 0xf8, 0x23, 0xb3, 0x43, + 0x43, 0x78, 0xff, 0x44, 0xef, 0x93, 0x9a, 0x9f, 0x66, 0xe3, 0xdd, 0xe0, 0xa8, 0x58, 0xae, 0xdc, + 0xb8, 0xcd, 0x80, 0x90, 0xe9, 0x4e, 0xce, 0x23, 0x02, 0xf7, 0xc1, 0x4e, 0x88, 0x61, 0x2e, 0x90, + 0x84, 0x40, 0x4c, 0x1c, 0xbc, 0x80, 0x77, 0x63, 0x0b, 0x30, 0x68, 0x2e, 0xda, 0x4d, 0x12, 0x83, + 0x24, 0x8b, 0xc2, 0x95, 0xa6, 0x51, 0xb5, 0x23, 0x81, 0x01, 0x1b, 0x75, 0xfc, 0x7c, 0xe3, 0x0d, + 0x3f, 0x29, 0x4c, 0x45, 0x0f, 0x78, 0x6f, 0x82, 0x8d, 0xdd, 0x0f, 0x9d, 0xf9, 0x7d, 0x6c, 0x3c, + 0x7c, 0xf0, 0x47, 0x36, 0x2e, 0x81, 0x10, 0xfa, 0x02, 0x87, 0x32, 0xbf, 0x04, 0xd3, 0x88, 0x0d, + 0x2f, 0x4a, 0xd6, 0xbe, 0x0a, 0xfb, 0xb2, 0xa4, 0xec, 0x28, 0xe2, 0x43, 0x17, 0x13, 0x3f, 0x04, + 0x95, 0x55, 0x17, 0xaf, 0x9a, 0xc0, 0xd0, 0x11, 0xdc, 0xf6, 0x17, 0x28, 0xa2, 0x33, 0x8d, 0x26, + 0x3c, 0x3c, 0x73, 0x82, 0x02, 0xb3, 0x07, 0x58, 0x33, 0x8d, 0x30, 0x3c, 0xd0, 0xc0, 0xd6, 0x65, + 0x4a, 0xc3, 0x32, 0x93, 0x26, 0xef, 0xe2, 0x7a, 0xbf, 0xd5, 0xaf, 0x96, 0xd3, 0x49, 0x24, 0x27, + 0x85, 0x06, 0x36, 0xc2, 0x66, 0x18, 0x64, 0x95, 0x82, 0xd9, 0xbb, 0x26, 0x96, 0xca, 0x90, 0x90, + 0x74, 0x0c, 0x8a, 0xad, 0x08, 0x7f, 0x2f, 0xb2, 0xe8, 0xa0, 0x21, 0x8c, 0xbc, 0x14, 0x1f, 0x87, + 0x30, 0xa2, 0x75, 0x8e, 0x3b, 0x3e, 0x0b, 0x39, 0xc6, 0x14, 0xd4, 0xc1, 0x00, 0x76, 0xa8, 0x8d, + 0x2d, 0x7c, 0x28, 0x72, 0x97, 0x95, 0x06, 0xec, 0x53, 0x11, 0xe3, 0x8e, 0x0a, 0xb1, 0x2f, 0x28, + 0x60, 0x23, 0xeb, 0x05, 0x23, 0x35, 0xf3, 0xf8, 0x80, 0xa5, 0xe0, 0xd7, 0x21, 0x31, 0xb3, 0x65, + 0x03, 0xca, 0x1d, 0x49, 0x8e, 0x60, 0xcf, 0xb0, 0x94, 0x7d, 0x7d, 0x7c, 0xeb, 0xc1, 0x61, 0x9a, + 0xad, 0x8f, 0xaa, 0x04, 0x6c, 0x43, 0xca, 0x95, 0xc1, 0x61, 0x18, 0xe6, 0x41, 0x9b, 0xd5, 0xbf, + 0x2e, 0xcf, 0x82, 0xc1, 0x70, 0xf2, 0x4b, 0x2c, 0x7d, 0xcc, 0x1a, 0xd8, 0x1c, 0xec, 0x8d, 0x12, + 0x4a, 0x9f, 0x05, 0x59, 0x0d, 0x49, 0x0b, 0x96, 0x6b, 0x1c, 0x1c, 0x61, 0x33, 0x47, 0x8f, 0x38, + 0x3b, 0xe8, 0x92, 0xae, 0x0a, 0x4a, 0xc4, 0xa5, 0x8b, 0xe6, 0x51, 0x08, 0xfd, 0x8e, 0x74, 0x6d, + 0x50, 0x87, 0xe9, 0xd7, 0x82, 0xcc, 0x7c, 0x6d, 0x6a, 0x63, 0xde, 0xa6, 0x6f, 0x1f, 0xe1, 0x1b, + 0x6c, 0x47, 0x8c, 0x12, 0xcc, 0x18, 0x73, 0xa8, 0x84, 0xec, 0x0c, 0xb1, 0xe0, 0xa0, 0xcd, 0xeb, + 0x59, 0x31, 0x2c, 0x76, 0xf1, 0x20, 0xb4, 0xaf, 0x9c, 0xc5, 0xb5, 0x37, 0x2f, 0x47, 0x7c, 0x48, + 0x44, 0xc3, 0xec, 0x5c, 0x57, 0xa4, 0x4c, 0x65, 0x12, 0xd3, 0xf1, 0x20, 0x98, 0xab, 0x56, 0xb6, + 0x9e, 0xbc, 0x48, 0x52, 0x2b, 0xe5, 0xcc, 0xc3, 0x06, 0x9c, 0x94, 0xbc, 0xf8, 0x56, 0x3b, 0xeb, + 0xdf, 0x04, 0xa5, 0x58, 0x1b, 0x20, 0x1b, 0x85, 0x30, 0xea, 0x7a, 0x38, 0xca, 0xdc, 0x56, 0xff, + 0x0a, 0x6b, 0x2b, 0x83, 0x0f, 0x2b, 0xc3, 0x1f, 0x1b, 0xb8, 0xce, 0x86, 0xa1, 0xbb, 0xa9, 0x60, + 0x5a, 0x9a, 0x91, 0x95, 0xab, 0x82, 0xbc, 0xe5, 0x19, 0xdc, 0xe1, 0x8b, 0xb8, 0x83, 0x4c, 0x7e, + 0xe7, 0xdf, 0x0a, 0x5a, 0xad, 0x45, 0xc2, 0xf5, 0x78, 0x81, 0x2d, 0x23, 0x9c, 0xf1, 0x82, 0xf0, + 0xc5, 0xc9, 0x21, 0x52, 0x35, 0xf0, 0x57, 0xa4, 0xa8, 0x74, 0x31, 0xe7, 0x34, 0x7b, 0xe6, 0x8c, + 0xac, 0xc1, 0x02, 0xdf, 0xf5, 0xef, 0xaf, 0x7d, 0x5b, 0xc4, 0x82, 0xa1, 0x49, 0xde, 0xe3, 0x05, + 0x61, 0x12, 0xa4, 0x11, 0x62, 0xbd, 0xdf, 0xbe, 0x27, 0xbc, 0x03, 0x21, 0xb2, 0x0a, 0x3d, 0x27, + 0xf0, 0x46, 0x72, 0xa4, 0x43, 0x40, 0xbf, 0x2b, 0xab, 0xa2, 0x7a, 0xea, 0x23, 0xaf, 0x7c, 0x13, + 0x8a, 0x28, 0x60, 0x2c, 0x0a, 0x98, 0xcb, 0x82, 0xd6, 0x8c, 0x8f, 0x74, 0x61, 0xe1, 0x52, 0x92, + 0x2a, 0xbf, 0x03, 0x1f, 0xee, 0x8f, 0xa2, 0x5c, 0x23, 0x26, 0x53, 0x3f, 0xf0, 0x9c, 0x8a, 0x16, + 0x3a, 0xa7, 0xf8, 0x23, 0x28, 0xd3, 0xdf, 0x95, 0x4f, 0x7c, 0x23, 0x8c, 0xb3, 0x41, 0xe9, 0x31, + 0x4e, 0x7c, 0xc6, 0x2c, 0x1c, 0x7f, 0x05, 0xc5, 0xee, 0x8b, 0x61, 0x96, 0x87, 0x0f, 0xe1, 0x3a, + 0xd7, 0xa3, 0xc8, 0x72, 0x20, 0x95, 0x83, 0x3a, 0x0b, 0xc1, 0x29, 0x16, 0x1d, 0x91, 0xc7, 0x28, + 0x9b, 0x29, 0xf9, 0xf5, 0x7f, 0x82, 0x4d, 0x69, 0x3f, 0xc4, 0x10, 0x3e, 0xe9, 0xef, 0x6d, 0x58, + 0xa2, 0xbe, 0x6b, 0xb4, 0xd5, 0x70, 0x58, 0x24, 0x8c, 0x83, 0xb3, 0x23, 0x56, 0x68, 0xcc, 0x95, + 0x03, 0x4f, 0x06, 0x66, 0x50, 0xd7, 0x1c, 0x6b, 0xe0, 0x8a, 0x82, 0x1b, 0x02, 0x01, 0xa9, 0x42, + 0xbf, 0xc9, 0x15, 0xdd, 0xfc, 0x13, 0xfb, 0x06, 0x34, 0x3a, 0x28, 0x1c, 0x98, 0x8b, 0x33, 0x3f, + 0xc2, 0x9d, 0x43, 0x96, 0x79, 0x7a, 0x8b, 0x47, 0x88, 0x0e, 0xc1, 0x50, 0x19, 0x58, 0xcc, 0xf1, + 0x05, 0x35, 0xec, 0x7c, 0x40, 0x25, 0xdb, 0x5a, 0x4e, 0x53, 0x17, 0xc1, 0xfc, 0x41, 0x8f, 0x2f, + 0xbf, 0x82, 0xe8, 0x70, 0x71, 0x8b, 0x77, 0xca, 0xf6, 0x17, 0x3a, 0xf5, 0x7f, 0x82, 0xe2, 0x90, + 0x30, 0x59, 0x16, 0x8b, 0x2e, 0x48, 0xcc, 0x83, 0x0c, 0x7f, 0x82, 0x7a, 0x1b, 0x4d, 0x7a, 0x6f, + 0x9d, 0xf0, 0x5b, 0x20, 0x10, 0xe3, 0x47, 0x1a, 0x60, 0xfb, 0x3a, 0x35, 0x3a, 0x8f, 0x92, 0xf6, + 0x9c, 0xe7, 0xe0, 0xaf, 0x0e, 0x9d, 0x2e, 0x7a, 0x17, 0x75, 0xe3, 0xfc, 0x27, 0x52, 0x63, 0x36, + 0xd6, 0x86, 0x30, 0xd7, 0xf3, 0x11, 0xf3, 0x67, 0xad, 0x7d, 0x16, 0xbe, 0x0a, 0x6c, 0xb3, 0xaf, + 0x75, 0xa7, 0xaa, 0xe7, 0x3e, 0x14, 0x1c, 0xa1, 0xa1, 0xc1, 0xb9, 0x30, 0x77, 0xa6, 0x31, 0x9a, + 0xcd, 0x9a, 0xd8, 0xe3, 0x05, 0xdd, 0x88, 0xaf, 0x35, 0xbc, 0xce, 0xf8, 0x2d, 0x3a, 0x76, 0xf0, + 0x98, 0x4c, 0x0e, 0x44, 0xf0, 0x9f, 0x04, 0x94, 0xb1, 0x0f, 0xef, 0x84, 0x0c, 0xc9, 0x33, 0x98, + 0xb4, 0x30, 0x2f, 0x7b, 0xb4, 0xa4, 0xc9, 0xf0, 0x57, 0xad, 0x75, 0x55, 0x55, 0x56, 0x2b, 0x82, + 0x71, 0x31, 0xc0, 0x48, 0x26, 0x33, 0xb1, 0x53, 0x98, 0x82, 0xdf, 0x04, 0xe6, 0xad, 0x94, 0xa0, + 0x88, 0xbc, 0xbf, 0xc4, 0xee, 0xd5, 0x55, 0x89, 0xc6, 0x81, 0xc0, 0x7c, 0x2a, 0x35, 0xe8, 0x08, + 0xbd, 0x83, 0xda, 0x21, 0xd8, 0xb0, 0xf9, 0x38, 0xbf, 0xe1, 0x43, 0x34, 0x50, 0x80, 0x72, 0x57, + 0x41, 0x99, 0x22, 0x89, 0xf9, 0x1e, 0xa5, 0x3d, 0xae, 0xf8, 0x2b, 0x96, 0x2d, 0x3d, 0x25, 0xee, + 0xd3, 0x42, 0xd2, 0xef, 0xf0, 0x4b, 0xd9, 0x9a, 0x89, 0x6a, 0xf7, 0xc1, 0x6c, 0x73, 0x23, 0xb9, + 0x3a, 0x65, 0x75, 0xb7, 0xf8, 0x22, 0xad, 0x49, 0xff, 0xf0, 0x47, 0xa4, 0xdf, 0xdf, 0x04, 0xa4, + 0x6c, 0xbb, 0xc1, 0xe5, 0x62, 0xdf, 0x04, 0x25, 0x61, 0xba, 0x3b, 0xfc, 0x11, 0xdd, 0xdd, 0xeb, + 0xe2, 0x09, 0x77, 0x78, 0x36, 0xf6, 0xef, 0xc1, 0x65, 0xed, 0xdf, 0x6d, 0x37, 0x2f, 0x7f, 0xdf, + 0x28, 0x91, 0xf9, 0xd9, 0xfe, 0x0a, 0x68, 0x6f, 0x63, 0x46, 0xcd, 0x27, 0xc6, 0xf0, 0xd5, 0x1d, + 0xf0, 0x57, 0x0f, 0xc1, 0x68, 0x61, 0x2d, 0x17, 0xed, 0x10, 0x2d, 0x0c, 0x2e, 0x5f, 0x44, 0x47, + 0x30, 0x79, 0x13, 0xee, 0xc0, 0x4b, 0x27, 0xf5, 0xfa, 0xb8, 0x8b, 0x28, 0xc0, 0x88, 0xf2, 0x88, + 0x11, 0xd0, 0x36, 0xf2, 0xd0, 0x1c, 0x70, 0x62, 0x42, 0xf0, 0x5d, 0x24, 0x99, 0x87, 0xe5, 0xf0, + 0x69, 0x36, 0xd1, 0x12, 0x67, 0xff, 0x24, 0x5d, 0x45, 0xc5, 0xfc, 0x14, 0x46, 0x04, 0x3a, 0xe3, + 0x6f, 0xb8, 0x40, 0x54, 0x4e, 0x93, 0x87, 0xc1, 0x39, 0x16, 0x66, 0xc5, 0x95, 0x17, 0x2a, 0xbe, + 0x09, 0x89, 0x42, 0x55, 0x55, 0x55, 0x67, 0xc1, 0x18, 0x91, 0xb7, 0x76, 0x43, 0x9d, 0x3e, 0x2e, + 0xd4, 0x94, 0xf3, 0x4b, 0xc3, 0x62, 0x29, 0xab, 0x06, 0x94, 0x54, 0xff, 0xff, 0x04, 0x24, 0x1f, + 0x10, 0x90, 0xa3, 0xf7, 0xd0, 0x98, 0xca, 0xe6, 0x3d, 0x55, 0x49, 0xd1, 0xab, 0x00, 0x00, 0x00, + 0x01, 0x41, 0x9a, 0x24, 0x12, 0x30, 0x3a, 0x81, 0x84, 0x4f, 0xe7, 0x08, 0xae, 0x33, 0xdf, 0xf8, + 0x6e, 0x18, 0xf7, 0xd4, 0x7f, 0xbf, 0xe0, 0x83, 0xab, 0x90, 0x35, 0x44, 0x06, 0x01, 0x40, 0xe6, + 0x50, 0xe7, 0x5c, 0x6e, 0x04, 0x99, 0x80, 0xff, 0x48, 0x88, 0x6b, 0x70, 0xb0, 0x50, 0xc8, 0x02, + 0x85, 0x1f, 0xb4, 0x3c, 0xb8, 0x80, 0x40, 0x08, 0xfa, 0xbc, 0x2c, 0x41, 0x45, 0x04, 0x60, 0x0d, + 0x00, 0x40, 0x71, 0x38, 0x25, 0xea, 0x5a, 0x3f, 0x10, 0x34, 0xc8, 0x1f, 0x2a, 0xe2, 0x50, 0xf6, + 0xa1, 0xd8, 0x2c, 0x16, 0xda, 0xc8, 0xac, 0x03, 0x4b, 0xf0, 0x54, 0x55, 0x37, 0xe2, 0x5e, 0x7f, + 0x3b, 0xc4, 0x3f, 0xaf, 0x30, 0x44, 0xb5, 0x84, 0xbb, 0x82, 0x05, 0x06, 0x6a, 0x50, 0x10, 0x3c, + 0x46, 0x3b, 0xf3, 0xf5, 0xaf, 0x12, 0x32, 0x5c, 0x5d, 0xe0, 0x7b, 0x3e, 0x85, 0x8c, 0x43, 0x94, + 0xa0, 0x20, 0x00, 0xbf, 0xbc, 0x00, 0x04, 0x78, 0xdb, 0x01, 0x8d, 0x79, 0x01, 0xf3, 0xa0, 0x00, + 0x37, 0x91, 0xe3, 0x6c, 0x09, 0x47, 0x04, 0xa9, 0x04, 0xbc, 0x12, 0x0b, 0xd2, 0x4e, 0xe4, 0x10, + 0x74, 0x72, 0x23, 0x35, 0xc4, 0x0a, 0x43, 0x33, 0x28, 0x6b, 0x68, 0x7a, 0x1e, 0x9c, 0x77, 0x04, + 0x06, 0x29, 0x16, 0x0e, 0x78, 0x0c, 0x44, 0x62, 0x70, 0xc2, 0x0b, 0x54, 0x1d, 0xb7, 0x39, 0x72, + 0x60, 0xd0, 0xfa, 0x82, 0x70, 0x28, 0x86, 0xb8, 0x97, 0x12, 0x7f, 0xaa, 0xaa, 0xf1, 0x23, 0x3c, + 0x65, 0x83, 0xc5, 0x64, 0xaa, 0x87, 0x51, 0xe0, 0xe1, 0x60, 0x5a, 0xd6, 0x26, 0x83, 0x84, 0x70, + 0x40, 0x12, 0xc1, 0xd6, 0x70, 0x03, 0x84, 0xa2, 0x20, 0x3e, 0x08, 0xca, 0x89, 0xd7, 0x64, 0x55, + 0x16, 0x50, 0x44, 0x70, 0xc0, 0xb3, 0x50, 0x4e, 0xc0, 0x74, 0x52, 0x8c, 0x1d, 0x0a, 0x0a, 0x34, + 0x87, 0x7c, 0x1c, 0x40, 0x42, 0xf8, 0x38, 0x81, 0x0b, 0xe1, 0xc0, 0x1b, 0xe6, 0xd3, 0x69, 0x35, + 0x9b, 0xe5, 0x29, 0x63, 0x14, 0x65, 0x8c, 0x51, 0xfa, 0x9e, 0xae, 0x8a, 0x8e, 0x00, 0x04, 0x61, + 0x5e, 0x84, 0x45, 0x5d, 0x49, 0x7c, 0xf8, 0x0f, 0x1e, 0x86, 0x86, 0xab, 0xea, 0x91, 0x0a, 0xea, + 0x99, 0x7a, 0xa6, 0x4b, 0xa8, 0xf2, 0xfa, 0x8f, 0x2f, 0x10, 0x14, 0x09, 0x5d, 0xdd, 0x9f, 0xd9, + 0xee, 0xef, 0x8d, 0xf7, 0x78, 0x90, 0xa5, 0x0c, 0x16, 0x3e, 0x07, 0xf9, 0x0a, 0x18, 0x19, 0x38, + 0x3d, 0x96, 0xdf, 0x97, 0x0e, 0x84, 0x2a, 0x06, 0x31, 0x88, 0x43, 0xc2, 0x0f, 0x1c, 0x7c, 0x57, + 0xa9, 0x67, 0x23, 0xf8, 0x80, 0x80, 0x26, 0x9f, 0xed, 0x63, 0x60, 0x45, 0x5d, 0xa4, 0x2c, 0xe5, + 0xb7, 0xf9, 0xc2, 0x65, 0x46, 0x7e, 0x46, 0x1e, 0xd7, 0xaf, 0x7d, 0x4b, 0x7c, 0xc6, 0x77, 0x36, + 0x7c, 0x40, 0x2e, 0x1d, 0x77, 0x75, 0x51, 0x71, 0x78, 0xb8, 0x91, 0x01, 0x49, 0x71, 0xc4, 0x21, + 0x80, 0x96, 0xdc, 0x64, 0x82, 0xdd, 0x67, 0x8b, 0x14, 0x1d, 0xb6, 0x64, 0xfa, 0xf2, 0xe2, 0x04, + 0x02, 0xaa, 0x62, 0x10, 0x92, 0xa1, 0x30, 0xe0, 0xc0, 0x44, 0x34, 0x0a, 0x0d, 0x82, 0x03, 0x56, + 0x83, 0xde, 0xec, 0x73, 0xa7, 0x10, 0x10, 0x0a, 0x55, 0x28, 0x00, 0x86, 0xad, 0x08, 0x6c, 0xac, + 0x09, 0xf2, 0x41, 0x8d, 0x15, 0x31, 0x22, 0x7a, 0x85, 0x25, 0xd1, 0x6f, 0x7b, 0xbe, 0x63, 0xc2, + 0x03, 0x21, 0x1c, 0x9d, 0x08, 0x4c, 0x31, 0x76, 0x3d, 0x8d, 0x40, 0x76, 0xf0, 0xba, 0x00, 0xc4, + 0x64, 0x21, 0xc4, 0xcd, 0x78, 0x05, 0x5f, 0xac, 0xfa, 0xa7, 0xa7, 0x90, 0xbf, 0x1e, 0x5a, 0x17, + 0xc3, 0xc0, 0x10, 0xc5, 0x1c, 0x98, 0x90, 0x80, 0x23, 0x16, 0xaa, 0x32, 0x22, 0x8f, 0x8d, 0x89, + 0x32, 0xe8, 0xca, 0x47, 0x07, 0xe8, 0x22, 0x74, 0x85, 0xfa, 0x91, 0xbe, 0x85, 0x61, 0xf5, 0x95, + 0x74, 0x46, 0xfa, 0xb0, 0xf5, 0xe9, 0x7a, 0x3c, 0x55, 0xd5, 0x2a, 0xf5, 0x4c, 0xbd, 0x7b, 0xeb, + 0xdf, 0x53, 0x28, 0xf1, 0x01, 0x11, 0xce, 0x7e, 0xca, 0xde, 0xf2, 0x98, 0xb7, 0x1e, 0xf8, 0x44, + 0x28, 0x4a, 0xc5, 0xc3, 0x51, 0x29, 0xb8, 0x01, 0x53, 0x95, 0x90, 0x11, 0x83, 0x86, 0x79, 0x6e, + 0x2f, 0xa2, 0xf7, 0xac, 0x1d, 0x42, 0xeb, 0x07, 0xb3, 0x2c, 0x2f, 0xeb, 0xa8, 0xd1, 0x66, 0xe4, + 0x38, 0xa8, 0x4d, 0xcc, 0x77, 0x78, 0x40, 0x13, 0x59, 0xd4, 0xd3, 0x63, 0x32, 0x6c, 0x93, 0xeb, + 0x67, 0x88, 0x08, 0x05, 0x4a, 0x56, 0x9e, 0x43, 0x6c, 0x6d, 0x21, 0x68, 0xa6, 0xbf, 0x96, 0x44, + 0x69, 0xfe, 0x09, 0x33, 0x9a, 0x69, 0xa4, 0x1c, 0xbc, 0x40, 0x27, 0x0a, 0x0a, 0xcd, 0xc3, 0x8d, + 0x28, 0x8f, 0xe1, 0x78, 0x9f, 0x9c, 0x7f, 0x05, 0x25, 0x0f, 0x1c, 0x8a, 0x04, 0x05, 0x00, 0x56, + 0xb7, 0x0d, 0x31, 0x43, 0xa0, 0xa0, 0xc4, 0xb3, 0xc9, 0x26, 0xe3, 0x30, 0xf7, 0xd0, 0xd9, 0xf8, + 0x98, 0x28, 0xf0, 0xcf, 0xee, 0xa1, 0xaf, 0x45, 0xf0, 0x56, 0x61, 0xf6, 0x28, 0xe3, 0xb9, 0x43, + 0x28, 0xc1, 0xcb, 0x37, 0x74, 0xcc, 0xd0, 0x40, 0x7d, 0x79, 0xf5, 0x7c, 0x28, 0x2b, 0xed, 0xdc, + 0xfc, 0xa4, 0xd0, 0x12, 0xaa, 0x88, 0x69, 0x38, 0x50, 0x15, 0x3c, 0x68, 0xc7, 0x03, 0x93, 0x13, + 0x01, 0xfb, 0x0b, 0x76, 0xb3, 0xa0, 0x6e, 0x7c, 0x10, 0x89, 0x7c, 0x06, 0x84, 0x82, 0x42, 0x3c, + 0x1c, 0x4e, 0xfd, 0x52, 0xf0, 0x50, 0x35, 0x24, 0xb4, 0x92, 0xdf, 0xe3, 0x29, 0x25, 0xa4, 0x96, + 0x92, 0x5b, 0x4d, 0x63, 0xf8, 0x6a, 0x76, 0x33, 0xd0, 0xa8, 0xef, 0x8f, 0x27, 0xfb, 0xe8, 0x43, + 0xfd, 0x15, 0xe4, 0xe8, 0xe5, 0xe5, 0x74, 0x2b, 0x2a, 0xe8, 0xee, 0x44, 0xe2, 0x02, 0x82, 0x85, + 0xa0, 0x2d, 0x98, 0x84, 0x09, 0x4b, 0x08, 0x41, 0xfa, 0x76, 0xc1, 0x86, 0x22, 0x48, 0xa2, 0x1b, + 0x73, 0xd4, 0xc2, 0xc5, 0xbb, 0x76, 0x05, 0xc1, 0xf7, 0x49, 0x84, 0x3d, 0xd5, 0x90, 0x9c, 0x48, + 0x5a, 0xa1, 0x34, 0x1e, 0x00, 0xf4, 0x7c, 0xc9, 0xe1, 0x90, 0xa0, 0x82, 0xc9, 0x71, 0x60, 0x95, + 0x63, 0xd0, 0xc0, 0x4a, 0x90, 0xc8, 0x23, 0xdd, 0x92, 0x8c, 0x4c, 0x10, 0x17, 0x61, 0x52, 0x8c, + 0x86, 0x77, 0x82, 0x79, 0x01, 0xa5, 0x59, 0x8c, 0x34, 0x95, 0xb0, 0x94, 0x3b, 0x70, 0x5a, 0xb5, + 0x7c, 0x02, 0xb2, 0x6c, 0x59, 0x84, 0x77, 0x12, 0x11, 0x0a, 0x56, 0xc2, 0xa3, 0x0c, 0x41, 0x02, + 0xc5, 0x4d, 0x74, 0x02, 0x00, 0x21, 0x49, 0x49, 0x2b, 0x49, 0x29, 0xaa, 0xb1, 0x70, 0xfc, 0xc4, + 0xa5, 0x64, 0x53, 0x60, 0xff, 0x92, 0x8b, 0x32, 0x9e, 0x08, 0x06, 0xee, 0x22, 0x0a, 0x02, 0xac, + 0x74, 0x8e, 0x20, 0xf1, 0x90, 0x00, 0x3e, 0xfa, 0x8e, 0xbf, 0xc2, 0x83, 0x39, 0xf6, 0x68, 0x29, + 0x4e, 0xb1, 0xaa, 0x62, 0x75, 0x2c, 0xe1, 0xc3, 0x81, 0xc4, 0x71, 0xf8, 0x50, 0x40, 0x37, 0x1c, + 0x45, 0x51, 0x65, 0x0b, 0x52, 0x65, 0x24, 0x26, 0xb0, 0x9f, 0x48, 0xdc, 0xe4, 0x82, 0x38, 0x3f, + 0x24, 0x29, 0xc1, 0x51, 0x1a, 0x2a, 0xc7, 0xa5, 0x8d, 0xfd, 0xce, 0x24, 0x40, 0x26, 0x1e, 0x9d, + 0x2d, 0x0c, 0x6a, 0x22, 0x7d, 0xc8, 0xa6, 0x8a, 0x2f, 0x82, 0xd9, 0x7b, 0x12, 0x06, 0xd1, 0x0e, + 0xc8, 0x15, 0x31, 0x2c, 0xaa, 0x26, 0x11, 0x08, 0x34, 0x61, 0xf6, 0xd5, 0x90, 0xfb, 0xef, 0xb8, + 0x20, 0x09, 0x36, 0x51, 0x0d, 0x7e, 0x14, 0x12, 0x05, 0xd6, 0x19, 0xc7, 0x86, 0x02, 0xee, 0x82, + 0xa0, 0x82, 0x1e, 0xc6, 0x0f, 0xd8, 0x84, 0x47, 0x07, 0xdd, 0xdc, 0xe4, 0x1a, 0x50, 0xe1, 0x14, + 0x11, 0x22, 0x5f, 0x44, 0xaf, 0xa1, 0x19, 0x7d, 0x60, 0xf8, 0x22, 0xaa, 0xbb, 0xcb, 0xe5, 0x16, + 0x95, 0x24, 0xbc, 0x25, 0xd2, 0x4b, 0x69, 0xaf, 0x1d, 0x69, 0xa4, 0x92, 0x69, 0xa4, 0xad, 0x34, + 0x93, 0x3f, 0x08, 0xda, 0x6b, 0x69, 0xad, 0xa6, 0xbf, 0x13, 0xd2, 0x4b, 0x49, 0x2f, 0x08, 0xda, + 0x6b, 0x69, 0xad, 0xa6, 0xb1, 0x1d, 0x08, 0xc4, 0x3d, 0x1d, 0xcb, 0xe0, 0x87, 0x9e, 0x87, 0xa3, + 0x5f, 0x57, 0x1e, 0xf9, 0xe8, 0x7a, 0x3e, 0x49, 0x88, 0x5e, 0x55, 0x5e, 0x8c, 0xca, 0xec, 0xf9, + 0xe8, 0x7a, 0x3e, 0xa5, 0x4b, 0xeb, 0xdf, 0x46, 0xef, 0x82, 0xc3, 0x1e, 0xf5, 0x88, 0x41, 0xb5, + 0x4a, 0xb4, 0x24, 0x5d, 0xb4, 0x56, 0x7d, 0x83, 0x4d, 0xa6, 0x74, 0x14, 0x98, 0x90, 0x80, 0x50, + 0xc7, 0xb4, 0x74, 0xd1, 0x88, 0x1f, 0x13, 0x37, 0x1f, 0x01, 0xcd, 0xd8, 0x2c, 0x06, 0xbe, 0x83, + 0xc0, 0xf8, 0x77, 0x1d, 0x11, 0x00, 0xd6, 0x2a, 0xc3, 0xae, 0x09, 0xd5, 0x5f, 0x30, 0xa8, 0x50, + 0xf2, 0xd6, 0x81, 0xb1, 0xd2, 0xae, 0x11, 0x0a, 0x4b, 0x7e, 0x2c, 0x08, 0x83, 0x3c, 0x1e, 0xad, + 0x58, 0xd4, 0xd6, 0x02, 0x22, 0x32, 0xc6, 0xfe, 0x78, 0xf7, 0xf6, 0x79, 0x72, 0x8e, 0xbe, 0x0a, + 0x02, 0x76, 0x4c, 0x06, 0xae, 0xe5, 0x51, 0xa4, 0x0f, 0x04, 0x5e, 0x7a, 0x15, 0x15, 0x79, 0x02, + 0xcb, 0xdf, 0x89, 0x04, 0x22, 0xce, 0x18, 0x0d, 0xb4, 0x30, 0x1e, 0x2f, 0x12, 0x0b, 0x0a, 0x2e, + 0xa1, 0x5a, 0x63, 0x64, 0x88, 0x3b, 0x48, 0x20, 0xad, 0x2c, 0x22, 0x54, 0x18, 0x58, 0xec, 0xc4, + 0x10, 0x0e, 0x0c, 0x5e, 0x6a, 0xd5, 0xa6, 0x1e, 0x0a, 0xc5, 0x41, 0x2c, 0xe6, 0x07, 0xaf, 0x02, + 0x81, 0x7a, 0xb1, 0x19, 0x7a, 0x60, 0x77, 0xa2, 0xc8, 0x0c, 0x83, 0xb0, 0x8a, 0x01, 0xd4, 0x20, + 0x17, 0x67, 0x71, 0x22, 0x06, 0x5c, 0x32, 0xc5, 0x84, 0x8c, 0x3e, 0x0e, 0xd1, 0x32, 0x7b, 0xb4, + 0x4f, 0xdc, 0x83, 0x1b, 0xb1, 0x6f, 0xaa, 0xd4, 0x0b, 0xb0, 0x5e, 0x0d, 0xb3, 0x10, 0xc4, 0xe6, + 0x6d, 0x56, 0x57, 0x45, 0x34, 0x22, 0x67, 0xe7, 0x58, 0xcb, 0xff, 0x88, 0x12, 0x14, 0x16, 0x0d, + 0x73, 0x90, 0x2a, 0xef, 0x56, 0xde, 0x6d, 0xa9, 0x6e, 0xa6, 0x97, 0xed, 0x2c, 0xb6, 0xee, 0xe9, + 0xd7, 0x12, 0x84, 0x91, 0x3e, 0xa3, 0xb7, 0xd0, 0x8a, 0xfa, 0xf7, 0xd7, 0x0a, 0xe8, 0xee, 0x8f, + 0xe8, 0xec, 0x5f, 0x44, 0x72, 0x5e, 0x5f, 0x3b, 0x04, 0xe8, 0x93, 0x3e, 0x8e, 0x74, 0xbe, 0xa7, + 0x49, 0x3a, 0x25, 0x7d, 0x4b, 0x71, 0x10, 0xa0, 0x85, 0xad, 0x88, 0x8a, 0x0e, 0x43, 0xa8, 0x72, + 0x20, 0xd9, 0x76, 0x35, 0xa5, 0xa6, 0x40, 0x6b, 0xa6, 0x32, 0x03, 0xb3, 0xe3, 0x4c, 0xf0, 0x26, + 0x29, 0xd4, 0x83, 0x84, 0x60, 0x96, 0xfb, 0x2d, 0xb8, 0xac, 0xf1, 0xc7, 0xc3, 0x79, 0x5d, 0xbb, + 0xbf, 0x7c, 0xd0, 0x6c, 0xf0, 0xa5, 0xe1, 0x42, 0x13, 0x39, 0x26, 0xa7, 0xc4, 0xe2, 0x89, 0xd0, + 0x10, 0xec, 0xc3, 0x63, 0x1e, 0x22, 0x64, 0x80, 0x3e, 0x07, 0xec, 0xf8, 0xe1, 0x61, 0xf1, 0x5e, + 0xcc, 0x85, 0x62, 0xf3, 0x6c, 0xb6, 0x52, 0xf8, 0x28, 0x96, 0x18, 0x2c, 0x8a, 0x98, 0x3a, 0xd0, + 0xc5, 0x78, 0x74, 0xb0, 0x4f, 0x0a, 0x6f, 0x14, 0x33, 0x3c, 0xbe, 0x0b, 0x31, 0xaa, 0x30, 0x24, + 0x65, 0x50, 0x5f, 0x93, 0x0c, 0x44, 0x24, 0xa8, 0x0b, 0xcb, 0x82, 0x9c, 0x74, 0xce, 0xa6, 0x1e, + 0x58, 0xbc, 0x8a, 0x17, 0x12, 0x20, 0x5e, 0x9b, 0x63, 0xa5, 0x05, 0x44, 0x9c, 0x9b, 0xf5, 0x99, + 0xe3, 0x0b, 0x13, 0x17, 0x31, 0x8a, 0x6b, 0x33, 0x2d, 0x9b, 0x42, 0xa9, 0x0b, 0x80, 0xf1, 0x10, + 0x52, 0x52, 0x8f, 0x78, 0xf3, 0x66, 0xb0, 0x8e, 0xcf, 0x14, 0xe7, 0x33, 0xd8, 0x2a, 0x6f, 0x8c, + 0xed, 0x57, 0x4e, 0xbb, 0x52, 0xef, 0xee, 0xdf, 0xff, 0x10, 0x5e, 0xda, 0x6a, 0xcd, 0xdc, 0xf9, + 0x7c, 0x4a, 0x1e, 0x42, 0xae, 0x84, 0x57, 0xd1, 0xc8, 0x9f, 0x5c, 0x25, 0xe4, 0xf3, 0xd1, 0x75, + 0xef, 0xab, 0xc2, 0x9c, 0x10, 0xcf, 0x43, 0xd3, 0xea, 0xeb, 0x15, 0xf1, 0xf3, 0xd0, 0xf4, 0xcf, + 0x4d, 0x73, 0xd1, 0x9f, 0xa2, 0x15, 0x3e, 0xa7, 0x4b, 0xeb, 0x87, 0xca, 0x31, 0x26, 0xcc, 0xdf, + 0x13, 0x08, 0x90, 0xb9, 0x78, 0x10, 0x16, 0x3d, 0xbb, 0x03, 0x14, 0x62, 0xb2, 0xff, 0xf8, 0xfd, + 0x8a, 0xd5, 0x5a, 0xda, 0xbd, 0xbf, 0x18, 0x50, 0x6f, 0x19, 0x04, 0x63, 0xcc, 0xb2, 0x53, 0xd6, + 0x54, 0xd5, 0xf0, 0x1a, 0x01, 0xf9, 0x9d, 0x8b, 0x7d, 0x54, 0x43, 0x7d, 0xf6, 0x6e, 0xa5, 0xe8, + 0x88, 0xff, 0x05, 0xb5, 0x75, 0xcb, 0xb0, 0xbd, 0x54, 0x6b, 0x29, 0xe7, 0xf8, 0x2a, 0xf4, 0x95, + 0x49, 0xa7, 0x9e, 0x77, 0xac, 0xd0, 0xee, 0x36, 0x34, 0x8d, 0xd9, 0xfb, 0xe1, 0x42, 0x32, 0x0c, + 0x44, 0xec, 0x7a, 0x87, 0x72, 0x41, 0x52, 0xb1, 0x88, 0x12, 0x46, 0x42, 0xdd, 0x42, 0xb3, 0x87, + 0xa7, 0x00, 0x64, 0x0d, 0x6d, 0xce, 0xd5, 0x5a, 0x76, 0xcd, 0xc4, 0x09, 0x09, 0x72, 0xbe, 0x93, + 0x9f, 0x4b, 0x20, 0xdc, 0x40, 0x56, 0x50, 0x60, 0x2a, 0x0b, 0x89, 0x04, 0x21, 0x1d, 0x94, 0x3c, + 0xc7, 0x0c, 0xc2, 0xa8, 0x76, 0xae, 0xa9, 0xe2, 0x3a, 0x12, 0x3a, 0xbe, 0x8c, 0xd7, 0xd6, 0xa3, + 0x7a, 0xb4, 0x57, 0x53, 0x2c, 0xfa, 0x8e, 0xdf, 0x44, 0xca, 0xfa, 0x2a, 0x74, 0xf8, 0x50, 0x20, + 0xef, 0xc9, 0x01, 0xa3, 0x87, 0x22, 0x08, 0xf8, 0x92, 0x91, 0xa6, 0x8e, 0x04, 0xc3, 0xc2, 0x97, + 0x00, 0x58, 0x20, 0x85, 0x83, 0xc3, 0x2e, 0x00, 0x04, 0x48, 0x29, 0x24, 0x46, 0x8f, 0x60, 0x79, + 0xc6, 0x22, 0x20, 0x27, 0x3c, 0x6d, 0x8b, 0xf0, 0xc0, 0x51, 0x25, 0xac, 0xd9, 0xf0, 0xa0, 0x95, + 0x41, 0xbd, 0x84, 0xb2, 0x04, 0xd5, 0x42, 0xc0, 0xca, 0xf4, 0x71, 0x22, 0xa8, 0xc1, 0x82, 0xa8, + 0x7b, 0x8c, 0xa1, 0x7a, 0x14, 0x57, 0xd8, 0x35, 0x89, 0xff, 0xcf, 0x82, 0xb2, 0x30, 0xae, 0x86, + 0x38, 0x31, 0x4d, 0x78, 0xfe, 0x82, 0xf7, 0x7d, 0x7a, 0xb1, 0x06, 0xf3, 0x4f, 0x33, 0x03, 0x9c, + 0x78, 0x52, 0x0e, 0xae, 0x49, 0x03, 0x80, 0x22, 0x64, 0x15, 0xa3, 0x0f, 0x9e, 0x1d, 0xd2, 0x67, + 0x8b, 0x31, 0x92, 0x53, 0xa1, 0xe5, 0xf0, 0xa4, 0x97, 0xcc, 0x7e, 0xc6, 0x2b, 0x9b, 0x0d, 0x81, + 0x8c, 0xc4, 0xbc, 0x58, 0x7c, 0xcb, 0xad, 0x1d, 0xa3, 0x43, 0xd1, 0x84, 0xd8, 0xdb, 0xce, 0x8d, + 0x0e, 0x4a, 0xf8, 0x50, 0xae, 0x1c, 0x62, 0x1d, 0x74, 0x23, 0x7f, 0x81, 0x2a, 0x29, 0x38, 0x9a, + 0xe6, 0xc5, 0x86, 0x5c, 0xad, 0x06, 0x79, 0x89, 0xea, 0x4c, 0x0b, 0x89, 0xfc, 0x48, 0xf1, 0x51, + 0x07, 0x27, 0xd7, 0x6a, 0x49, 0x1a, 0x9e, 0xbc, 0xf1, 0x70, 0xf8, 0x9e, 0x28, 0x27, 0xb0, 0x6e, + 0x05, 0x9a, 0x24, 0x01, 0x08, 0x4f, 0x04, 0xc1, 0x1d, 0xc3, 0x31, 0x2e, 0x0d, 0x03, 0x1a, 0xe1, + 0x49, 0x0b, 0x03, 0x75, 0x17, 0x7d, 0x1e, 0x2f, 0x82, 0x7d, 0x85, 0x37, 0x60, 0xdd, 0xf1, 0xd9, + 0x7e, 0x19, 0x8c, 0x91, 0x26, 0x8a, 0x4a, 0x0d, 0x7b, 0x99, 0x88, 0xbd, 0xd9, 0x5f, 0x89, 0xea, + 0x99, 0x1f, 0xa8, 0xfa, 0xba, 0x21, 0x88, 0xe3, 0xf5, 0x4a, 0x86, 0xf4, 0x21, 0x88, 0x8e, 0x8b, + 0x57, 0xc5, 0x05, 0x95, 0x45, 0xd7, 0x21, 0x8a, 0x5e, 0x30, 0xa5, 0xf8, 0xb8, 0xbf, 0x55, 0x9e, + 0x8d, 0xd9, 0x4e, 0x6a, 0xe8, 0x06, 0x54, 0x3e, 0xcc, 0x82, 0x5f, 0x78, 0x46, 0xdd, 0x26, 0x61, + 0x7b, 0x25, 0xc5, 0x68, 0x6d, 0x93, 0x7d, 0x4a, 0xa7, 0x4e, 0x4d, 0xfd, 0xd6, 0x31, 0xed, 0xf6, + 0xbe, 0xaa, 0x20, 0x00, 0xa5, 0x8d, 0xe6, 0xb4, 0xbf, 0x8c, 0x2b, 0x74, 0x19, 0xbd, 0x77, 0x66, + 0xcb, 0x96, 0xbb, 0x77, 0xc4, 0x42, 0x36, 0xb5, 0xbc, 0xd9, 0xad, 0x7d, 0xe4, 0xc3, 0x05, 0x65, + 0x72, 0xca, 0x10, 0x0a, 0x65, 0x20, 0xc4, 0x6e, 0x87, 0x9d, 0x2f, 0xab, 0x80, 0x9f, 0x54, 0x89, + 0x74, 0x47, 0x93, 0xab, 0x45, 0x74, 0x5d, 0x7d, 0x11, 0xfe, 0x0b, 0x07, 0x30, 0x63, 0xd6, 0x6d, + 0xc5, 0x4d, 0x27, 0x4e, 0xda, 0x6b, 0xbe, 0x3c, 0x98, 0xe9, 0x8b, 0x61, 0x75, 0x65, 0xc7, 0x74, + 0x2b, 0x79, 0x72, 0x63, 0xa4, 0xe6, 0x6c, 0x39, 0x86, 0x89, 0x64, 0xaf, 0x13, 0xd3, 0x3f, 0x46, + 0x38, 0x26, 0x1a, 0x91, 0xb8, 0x4a, 0xe4, 0xb8, 0xac, 0x08, 0xd5, 0x6e, 0x00, 0x1d, 0x55, 0xdd, + 0x89, 0x5c, 0x37, 0x1e, 0xb6, 0xc7, 0x60, 0xb1, 0x4b, 0xf1, 0xc7, 0x20, 0x93, 0xf0, 0x70, 0xef, + 0xee, 0xac, 0xe9, 0xa6, 0x10, 0x60, 0xef, 0x93, 0x1b, 0x38, 0x7e, 0x24, 0xe3, 0x86, 0x24, 0x93, + 0x93, 0x91, 0x46, 0xe0, 0xfa, 0xaf, 0xcb, 0xd7, 0xab, 0xa1, 0x79, 0x45, 0xf4, 0x54, 0xb0, 0xff, + 0x43, 0xdc, 0xfa, 0x08, 0x7f, 0xc4, 0x82, 0xc1, 0x48, 0xc7, 0x5f, 0xac, 0xb9, 0x26, 0xf4, 0x6b, + 0xdb, 0x28, 0xfb, 0xfd, 0x7f, 0xf1, 0xe4, 0xb6, 0xb7, 0xe3, 0x7a, 0x7b, 0xdf, 0xec, 0x43, 0x73, + 0xaa, 0xe4, 0x3b, 0x62, 0x8a, 0x3e, 0x2b, 0x8c, 0xf1, 0x97, 0xa8, 0x48, 0xcd, 0x99, 0xd3, 0x56, + 0x75, 0x7a, 0x50, 0x5d, 0x19, 0xc6, 0x0b, 0x55, 0x7b, 0x2d, 0x8f, 0x9e, 0x3e, 0x8b, 0x17, 0xc1, + 0x38, 0xa8, 0x88, 0x60, 0x29, 0x4a, 0xad, 0x83, 0xef, 0x84, 0x08, 0x46, 0x58, 0xcb, 0xc7, 0xb2, + 0x53, 0x8c, 0x25, 0xd2, 0x79, 0x25, 0x21, 0x57, 0xbd, 0x04, 0xd3, 0x20, 0xaf, 0x44, 0xaf, 0xae, + 0x51, 0x11, 0x13, 0x5e, 0xf1, 0x7d, 0x58, 0x78, 0x27, 0x23, 0x63, 0x85, 0xc2, 0xd3, 0x82, 0x00, + 0xd4, 0x24, 0x6b, 0x9a, 0x68, 0xc7, 0xe3, 0xf2, 0xc1, 0xc9, 0xb0, 0xd4, 0x35, 0x1d, 0x49, 0x46, + 0x3a, 0x6a, 0xb4, 0x3e, 0x24, 0x59, 0x2f, 0x76, 0x8d, 0x08, 0xc2, 0xf9, 0x8c, 0xef, 0xf8, 0x4e, + 0xb5, 0x94, 0xc5, 0xd8, 0xfe, 0x08, 0xc5, 0xde, 0xef, 0x27, 0x45, 0x67, 0xc9, 0x6d, 0xaf, 0xc6, + 0x0a, 0x5d, 0x49, 0xce, 0x75, 0x47, 0x9b, 0x7d, 0x8e, 0x6e, 0xde, 0x50, 0xc0, 0xd4, 0xf0, 0x40, + 0x1f, 0x08, 0x11, 0x99, 0x17, 0x56, 0x51, 0x94, 0xf5, 0x52, 0x7f, 0x04, 0x61, 0x5b, 0xba, 0xd8, + 0xfa, 0x2f, 0x42, 0x9d, 0x08, 0xca, 0x13, 0xe1, 0x81, 0x19, 0x60, 0x6c, 0x1a, 0xca, 0x91, 0xf6, + 0x0e, 0x07, 0x16, 0x5a, 0xb6, 0xd3, 0x7f, 0xe2, 0xef, 0xb7, 0xaa, 0xaf, 0x82, 0x1c, 0x56, 0x4e, + 0xde, 0xdf, 0x09, 0x73, 0x2c, 0x51, 0xd2, 0x49, 0x76, 0x48, 0xe0, 0xc2, 0x23, 0x0a, 0xae, 0xf9, + 0x45, 0xb4, 0xb6, 0x0d, 0x75, 0x7f, 0xa3, 0xc4, 0xe1, 0xe6, 0x8a, 0xc5, 0x65, 0x62, 0xf8, 0x84, + 0x46, 0x3c, 0x49, 0x04, 0x0f, 0x90, 0x7b, 0x4b, 0xc1, 0x55, 0x98, 0x77, 0x39, 0x80, 0xcb, 0xce, + 0x08, 0x80, 0x87, 0x6a, 0x4b, 0xb2, 0x58, 0xb7, 0xf8, 0x40, 0x44, 0xb4, 0xda, 0xaa, 0xe2, 0x30, + 0x17, 0x31, 0x8c, 0xf9, 0x44, 0xac, 0x48, 0x70, 0x5c, 0x35, 0xd0, 0xb4, 0xeb, 0xd1, 0x53, 0xa5, + 0xd1, 0x2a, 0xfa, 0x23, 0x49, 0xc1, 0x11, 0x6a, 0xee, 0xca, 0xe0, 0xb0, 0x67, 0x23, 0x19, 0x18, + 0x53, 0xa9, 0x66, 0x17, 0xce, 0x3f, 0x12, 0x0a, 0x48, 0x5e, 0x7a, 0x30, 0x4e, 0x72, 0xe9, 0x69, + 0x29, 0x6d, 0x8f, 0xef, 0x12, 0x63, 0xb4, 0xd5, 0x57, 0x5f, 0xd7, 0x19, 0x15, 0x73, 0xc0, 0x62, + 0x86, 0x63, 0xa8, 0x17, 0x68, 0x42, 0x75, 0x92, 0x7c, 0x16, 0x65, 0xb0, 0x54, 0x9f, 0x3f, 0x47, + 0xe9, 0x3a, 0x2a, 0x65, 0xea, 0xff, 0x57, 0xf8, 0x25, 0x22, 0x21, 0x98, 0xcf, 0x4d, 0x12, 0xdf, + 0xe0, 0x9c, 0x83, 0xd2, 0x17, 0xcb, 0x1d, 0x6c, 0xf3, 0xfc, 0x24, 0x29, 0x75, 0xad, 0x71, 0x11, + 0x77, 0xbb, 0x95, 0x8d, 0x8c, 0xa8, 0xee, 0x87, 0xb1, 0x5d, 0x1b, 0xa2, 0xfa, 0x3f, 0x4f, 0xd1, + 0x4a, 0x9f, 0x30, 0x8d, 0xdd, 0x71, 0x04, 0x35, 0x19, 0x8b, 0x3a, 0x64, 0xee, 0x53, 0xe1, 0x08, + 0x6d, 0xcf, 0x42, 0xd1, 0xa3, 0x46, 0x64, 0xe3, 0x27, 0x7b, 0x6f, 0x88, 0xfb, 0xaa, 0xaa, 0xf9, + 0x48, 0x96, 0xbe, 0x32, 0x12, 0x11, 0xe2, 0x27, 0x01, 0xa9, 0x08, 0x24, 0x4c, 0xea, 0x62, 0x9a, + 0x96, 0xdf, 0xe1, 0x22, 0x81, 0x7a, 0xbb, 0xbd, 0xbb, 0x31, 0xaa, 0x3f, 0x19, 0xfb, 0x71, 0xf1, + 0xca, 0x4b, 0x33, 0xfb, 0x7b, 0xbb, 0xfe, 0x6b, 0xd6, 0xba, 0x1e, 0xd5, 0xd5, 0xbe, 0xaf, 0xf0, + 0x43, 0x12, 0xe0, 0x96, 0x0f, 0x6f, 0x71, 0x10, 0x4b, 0x96, 0x9a, 0x4d, 0xca, 0xde, 0x75, 0x89, + 0x82, 0x22, 0x21, 0xed, 0x26, 0xff, 0x05, 0x42, 0x94, 0xd4, 0x7f, 0x9b, 0x26, 0xfb, 0x9f, 0x2d, + 0x69, 0x28, 0x5b, 0xa3, 0xb7, 0xd5, 0xa7, 0xe8, 0xbd, 0x5d, 0x5f, 0xe6, 0x35, 0x55, 0x78, 0x95, + 0xcb, 0xc4, 0x12, 0xf2, 0xd3, 0xe1, 0x48, 0x97, 0xab, 0xe2, 0xf7, 0xc5, 0x94, 0x67, 0x2f, 0xc5, + 0x6f, 0xe1, 0x76, 0x95, 0xca, 0x62, 0x3e, 0x34, 0xb5, 0xc9, 0xbb, 0xdf, 0x13, 0x7b, 0xbc, 0xfd, + 0xff, 0x2d, 0xcb, 0xe8, 0x0b, 0xd0, 0xb7, 0xe2, 0x60, 0xa0, 0x8f, 0x9b, 0xd3, 0x20, 0x40, 0x1d, + 0x1d, 0xfa, 0xbf, 0xd1, 0x7f, 0x5d, 0x16, 0xd5, 0xd1, 0x9e, 0xb8, 0x27, 0xde, 0xe5, 0xce, 0xd3, + 0xf1, 0x10, 0x51, 0x67, 0x76, 0xb9, 0x7b, 0x3e, 0x41, 0x43, 0xc8, 0x8e, 0x21, 0x65, 0x27, 0xc3, + 0xfb, 0x00, 0x85, 0xab, 0x9e, 0x58, 0x11, 0xf1, 0x07, 0x30, 0xd9, 0x08, 0x1b, 0x18, 0xa5, 0x9d, + 0x5f, 0xc3, 0x5d, 0x0b, 0xef, 0xac, 0x57, 0xd6, 0xbe, 0x09, 0x0c, 0xb5, 0x8e, 0xfa, 0xe5, 0xcd, + 0x4f, 0xc9, 0x9a, 0x0b, 0xf8, 0x52, 0x4e, 0x0d, 0x1f, 0xcf, 0x05, 0x8b, 0x95, 0x52, 0x71, 0x20, + 0xfb, 0x0b, 0x89, 0x87, 0xf5, 0xe5, 0x93, 0xd7, 0x05, 0x55, 0xd6, 0x21, 0xf1, 0x59, 0xf0, 0x77, + 0xc2, 0x22, 0xfd, 0xf0, 0x99, 0x18, 0x1d, 0xce, 0x2e, 0xf5, 0x40, 0xfc, 0x57, 0x76, 0xde, 0xef, + 0xe8, 0xfd, 0xf1, 0xc7, 0x71, 0x5b, 0x8a, 0xca, 0x20, 0x22, 0xbb, 0x15, 0x8b, 0x8b, 0xaa, 0xfa, + 0xbf, 0xd1, 0x1f, 0xea, 0x3f, 0xfc, 0x12, 0x5c, 0x56, 0xef, 0xdf, 0x5a, 0xf8, 0x24, 0x12, 0xef, + 0x9d, 0x2a, 0x26, 0x30, 0x55, 0x6b, 0x55, 0x9f, 0xef, 0x55, 0x52, 0x28, 0xf1, 0x5a, 0xd5, 0xdf, + 0xf4, 0x57, 0xe2, 0x44, 0xaf, 0xf8, 0x88, 0x2c, 0xa9, 0x0e, 0x47, 0x92, 0x2d, 0x0b, 0x44, 0xdc, + 0x0e, 0x78, 0x35, 0x70, 0xd8, 0xc1, 0x3e, 0xb5, 0x1a, 0x82, 0x9c, 0xdd, 0x17, 0xae, 0x8e, 0xf3, + 0xf4, 0x5e, 0x9f, 0xa2, 0x74, 0x5f, 0x57, 0xae, 0xbd, 0xf0, 0x4d, 0x69, 0xa4, 0x92, 0x55, 0x99, + 0x47, 0x71, 0x31, 0x85, 0x15, 0x97, 0x37, 0x7c, 0xbf, 0x4c, 0xe7, 0x19, 0x47, 0xe2, 0x6b, 0x06, + 0x21, 0x03, 0x3f, 0x74, 0x3e, 0x71, 0x82, 0xf7, 0x71, 0x5f, 0x08, 0xfd, 0x5e, 0x5e, 0x09, 0x04, + 0xbb, 0xfd, 0xf0, 0x43, 0x7b, 0xbb, 0xfc, 0x24, 0x47, 0x43, 0x77, 0x77, 0x77, 0xf5, 0xef, 0xa2, + 0xbf, 0xc1, 0x08, 0x9b, 0xdd, 0x9c, 0x4d, 0x11, 0xfe, 0x41, 0x8b, 0xad, 0x70, 0x4a, 0x25, 0xa6, + 0x8a, 0x41, 0x89, 0x1e, 0xbf, 0xf9, 0x8b, 0x99, 0xe3, 0x6f, 0xaf, 0x04, 0x33, 0x9b, 0xce, 0x6c, + 0xc6, 0xf9, 0x3e, 0x08, 0xc8, 0x5b, 0x6b, 0xaf, 0x82, 0xf2, 0x13, 0x14, 0xd7, 0x11, 0xdc, 0xcc, + 0xb7, 0x8e, 0x96, 0x1b, 0x8f, 0xff, 0x82, 0x42, 0x6a, 0xfd, 0x11, 0xd1, 0x5e, 0x14, 0xc4, 0x8d, + 0x36, 0xab, 0x0a, 0x47, 0xd0, 0x51, 0x4d, 0x67, 0x2b, 0x1b, 0x56, 0x0d, 0xb1, 0x90, 0xd2, 0xba, + 0xc4, 0xab, 0x0c, 0x3d, 0xa5, 0xeb, 0x12, 0x09, 0xc5, 0x94, 0xd5, 0x66, 0x37, 0x20, 0x83, 0xd7, + 0xd9, 0x97, 0x6f, 0x88, 0x31, 0xa8, 0x04, 0xd9, 0x3f, 0x08, 0x02, 0x83, 0xa0, 0xed, 0xf3, 0x30, + 0xb5, 0xbf, 0xde, 0xaa, 0xbe, 0x4f, 0x37, 0xe2, 0x4b, 0x77, 0x71, 0x5f, 0x82, 0x4b, 0xbb, 0x9e, + 0x15, 0x5d, 0x7b, 0xe0, 0x9c, 0xe7, 0x83, 0xbd, 0xf7, 0xff, 0xc1, 0x39, 0x2f, 0x77, 0x77, 0x7e, + 0xf8, 0x21, 0x3b, 0x96, 0x05, 0x0c, 0x06, 0xf2, 0xf8, 0x21, 0xaa, 0xaa, 0xe5, 0x5c, 0x26, 0x5d, + 0xdd, 0xdf, 0xc4, 0x41, 0x09, 0x1d, 0xb5, 0xbd, 0xc4, 0x42, 0x84, 0xa9, 0x46, 0x3a, 0x27, 0xa3, + 0x20, 0x40, 0x19, 0xc6, 0x1c, 0x80, 0x02, 0xbf, 0x71, 0x1f, 0x98, 0xa7, 0xbc, 0x84, 0xbc, 0x23, + 0x43, 0x36, 0x4c, 0xaa, 0x92, 0xde, 0xdc, 0x7f, 0xde, 0xbd, 0xe2, 0x45, 0x0a, 0x34, 0xe6, 0x78, + 0x4a, 0xc4, 0x9f, 0xcb, 0x5c, 0xaf, 0xa3, 0xea, 0x6e, 0xad, 0xf5, 0x69, 0x3a, 0xb5, 0x74, 0x47, + 0x9f, 0xab, 0x4d, 0xc1, 0x3d, 0xc2, 0x07, 0x2a, 0x86, 0x46, 0x8f, 0x8e, 0xd7, 0x89, 0xfa, 0xf7, + 0x88, 0x0a, 0x6e, 0x45, 0x2f, 0x61, 0x72, 0xa5, 0x85, 0x67, 0x43, 0x48, 0xcc, 0x44, 0xf5, 0x1b, + 0x12, 0xf1, 0x47, 0xbb, 0xdd, 0xdd, 0xf8, 0x94, 0x47, 0xf8, 0xc2, 0xf2, 0xc8, 0x6c, 0xcb, 0x76, + 0x84, 0xae, 0xe4, 0xa0, 0xc6, 0xa6, 0xb5, 0x19, 0x60, 0x55, 0x14, 0xf8, 0x9f, 0xbb, 0xbb, 0xba, + 0xee, 0x56, 0x1f, 0x5d, 0x13, 0xbe, 0x08, 0x6e, 0xe8, 0x3f, 0x78, 0x90, 0x89, 0x5a, 0xb9, 0x95, + 0x38, 0xae, 0xdb, 0x03, 0x5f, 0x91, 0x88, 0x35, 0xe2, 0x6b, 0xde, 0x24, 0x44, 0x69, 0x59, 0x95, + 0x55, 0x68, 0xa6, 0xa0, 0xf1, 0x22, 0x55, 0xf8, 0x91, 0x28, 0xb5, 0xf0, 0x48, 0x4a, 0xd9, 0x65, + 0x5c, 0x82, 0x96, 0xbf, 0x04, 0x65, 0x18, 0x31, 0xf8, 0x23, 0x7a, 0x2b, 0xc6, 0x71, 0x42, 0x29, + 0xb7, 0x72, 0xa4, 0x7a, 0xf8, 0x90, 0x91, 0xde, 0xce, 0xda, 0xfc, 0x4a, 0xd7, 0x88, 0x57, 0xf8, + 0x2b, 0xee, 0x21, 0x83, 0x1c, 0xa9, 0x35, 0x59, 0xf6, 0xf8, 0x28, 0x92, 0x8a, 0xb9, 0x32, 0xf9, + 0xbc, 0x40, 0x4c, 0x43, 0x4f, 0xad, 0x57, 0xc5, 0x09, 0x22, 0x9a, 0x1d, 0x27, 0xfc, 0x23, 0x71, + 0x90, 0xd0, 0x2f, 0x3c, 0x77, 0xdd, 0x6d, 0xf1, 0x3e, 0x25, 0x7f, 0xf0, 0x47, 0xd5, 0x7b, 0xc4, + 0x05, 0x0a, 0xe7, 0xee, 0xf3, 0x2f, 0xd3, 0xd0, 0xcc, 0x41, 0x62, 0x5d, 0x26, 0x7d, 0x5f, 0xe2, + 0x2a, 0x2f, 0x6d, 0xee, 0xfe, 0xaf, 0xf5, 0x7f, 0xac, 0xab, 0x8a, 0x33, 0xdd, 0xdd, 0xdf, 0xe8, + 0xaf, 0xe2, 0x44, 0xd1, 0xbf, 0x26, 0xb0, 0xaf, 0x88, 0x04, 0x39, 0xf1, 0xf6, 0x2a, 0x20, 0x40, + 0x23, 0x3b, 0x4c, 0x9a, 0xc5, 0xc4, 0xd9, 0x37, 0x45, 0xc4, 0x57, 0x35, 0xc6, 0x95, 0xaf, 0xc1, + 0x38, 0xa6, 0xe9, 0xa0, 0x6a, 0xab, 0xef, 0x87, 0xca, 0x30, 0x00, 0x9e, 0xe9, 0x36, 0x37, 0x73, + 0x38, 0x5a, 0xda, 0x5a, 0x87, 0xba, 0x8b, 0x6e, 0x7e, 0x2f, 0xab, 0xd7, 0x57, 0x9b, 0xab, 0xd7, + 0x45, 0x7b, 0xe1, 0x21, 0x4f, 0xb4, 0x78, 0x32, 0x7f, 0x10, 0x41, 0x23, 0x43, 0x27, 0x1f, 0x89, + 0x04, 0x65, 0x49, 0xb7, 0x7c, 0xaf, 0x98, 0x9a, 0xaf, 0x82, 0xc2, 0x0a, 0xdb, 0x77, 0xdb, 0x59, + 0x71, 0xfb, 0x7c, 0x5d, 0xf7, 0x55, 0x5f, 0x12, 0x09, 0xc4, 0xb2, 0x48, 0xc1, 0xcf, 0x6d, 0x5f, + 0xe3, 0x4f, 0x54, 0xbc, 0x94, 0x95, 0xef, 0x13, 0xb8, 0x40, 0x48, 0x20, 0x39, 0x01, 0x3e, 0xb7, + 0xff, 0x82, 0x52, 0x39, 0x45, 0xb8, 0xd8, 0x00, 0x6f, 0xff, 0xec, 0x89, 0xaa, 0x0b, 0xe8, 0xb6, + 0xf1, 0x20, 0x96, 0xce, 0xc6, 0xd4, 0x79, 0xc1, 0x66, 0x3f, 0xc1, 0x25, 0x3a, 0x63, 0xed, 0x3d, + 0xf0, 0x4d, 0x3f, 0x9a, 0x95, 0x17, 0x91, 0x78, 0xff, 0x44, 0xef, 0x92, 0xaa, 0xaa, 0xba, 0x2b, + 0xbc, 0x48, 0xcb, 0x43, 0xa3, 0x0c, 0xd9, 0xca, 0xa0, 0x6c, 0x0e, 0x21, 0xc3, 0xca, 0x00, 0x96, + 0x03, 0x82, 0xe2, 0x0b, 0x51, 0xb0, 0x8f, 0x10, 0xe3, 0x30, 0x9e, 0x36, 0xfc, 0x29, 0x41, 0x30, + 0x45, 0x22, 0xb0, 0xd8, 0x58, 0x05, 0x11, 0x91, 0x59, 0x92, 0xa1, 0xd9, 0x92, 0x66, 0xca, 0xd6, + 0xcf, 0x97, 0xc1, 0x4d, 0x71, 0xba, 0x03, 0x88, 0x60, 0x72, 0x1b, 0x18, 0x74, 0x22, 0xcd, 0x60, + 0x1d, 0x1d, 0x78, 0x90, 0x85, 0x83, 0x24, 0x26, 0x84, 0xa6, 0x49, 0x60, 0xe3, 0x85, 0xc3, 0xf8, + 0x85, 0xd7, 0xc1, 0x15, 0x55, 0x56, 0x2f, 0xad, 0x7c, 0x4c, 0x7d, 0x8f, 0xb6, 0x5c, 0xb7, 0x7f, + 0x1e, 0x68, 0xf3, 0x1b, 0xf6, 0x72, 0xaa, 0xb5, 0xf0, 0xf9, 0x13, 0x23, 0xaf, 0x75, 0x4d, 0x47, + 0x8c, 0x17, 0x59, 0xab, 0xb8, 0xdd, 0x38, 0x2c, 0xda, 0x3c, 0x6f, 0xfd, 0x1f, 0xa2, 0x7a, 0xbc, + 0x6f, 0x08, 0x8c, 0x72, 0xc1, 0xfb, 0xbb, 0xba, 0xba, 0xf1, 0x21, 0x32, 0x98, 0x78, 0x85, 0x75, + 0x7d, 0xdd, 0xf8, 0x84, 0x76, 0x7c, 0x45, 0x55, 0x64, 0xf5, 0xfa, 0x3f, 0x7d, 0x7a, 0xb8, 0x2a, + 0xa4, 0x42, 0x5a, 0x86, 0xc2, 0x42, 0x89, 0x97, 0xbd, 0x9e, 0xaa, 0x24, 0x40, 0xbb, 0xb6, 0xb5, + 0x60, 0xd4, 0x8c, 0x78, 0x52, 0x64, 0x75, 0xca, 0xc2, 0xce, 0xa2, 0x73, 0x6b, 0xdd, 0x0d, 0x88, + 0x74, 0x68, 0xea, 0xee, 0x26, 0x14, 0x24, 0xb8, 0x9d, 0x77, 0x9d, 0x8c, 0x55, 0xc4, 0xb1, 0x4e, + 0x8e, 0xf2, 0xf8, 0x22, 0xcb, 0x14, 0x9a, 0xa5, 0xdc, 0x4c, 0x10, 0x95, 0xed, 0x50, 0xad, 0xf0, + 0x49, 0x6d, 0x1c, 0xd1, 0x22, 0xf8, 0x98, 0x47, 0x83, 0x22, 0x8c, 0xda, 0xd6, 0x81, 0x4c, 0xe9, + 0x7c, 0x49, 0x0c, 0x93, 0xfe, 0x08, 0x4a, 0xce, 0xb6, 0xfb, 0x32, 0xd4, 0xd9, 0xe0, 0x84, 0xaf, + 0x77, 0xaf, 0x82, 0x1a, 0xd7, 0xdf, 0x19, 0x19, 0x95, 0xd7, 0x37, 0xe9, 0x34, 0xd6, 0x9b, 0x6c, + 0x55, 0xd5, 0xab, 0x8e, 0xd2, 0x44, 0xc8, 0xf9, 0xb7, 0xb4, 0xbe, 0x27, 0xeb, 0x87, 0x11, 0x04, + 0x67, 0x49, 0x1a, 0x73, 0x83, 0xeb, 0xdf, 0x05, 0x76, 0x51, 0x96, 0x8d, 0x94, 0xaa, 0x3c, 0xbc, + 0x7e, 0xc3, 0x57, 0x28, 0xc7, 0x92, 0x22, 0x58, 0x7a, 0x3b, 0x95, 0xd5, 0xd0, 0x97, 0x30, 0xa4, + 0x19, 0x60, 0x2b, 0xa1, 0x78, 0xd2, 0x84, 0x6b, 0x75, 0x42, 0x54, 0x6c, 0xa3, 0x70, 0x3f, 0x61, + 0x06, 0x7b, 0xb3, 0xd5, 0x6a, 0x2e, 0x77, 0xca, 0x41, 0x9e, 0xbf, 0x5d, 0x17, 0xab, 0xb2, 0xbb, + 0xdf, 0xcb, 0x6d, 0x3b, 0x5e, 0x89, 0x33, 0xea, 0xff, 0x05, 0xb2, 0x60, 0xc7, 0xb2, 0x9e, 0x9f, + 0x7c, 0x97, 0xbb, 0xf8, 0x4a, 0xc0, 0xdd, 0xdd, 0xe2, 0xb7, 0xe2, 0x01, 0x5d, 0x58, 0xcf, 0xaa, + 0xcf, 0xb3, 0x30, 0xdf, 0x1e, 0x53, 0x7a, 0xcb, 0xce, 0xc1, 0x7e, 0x9b, 0x40, 0xce, 0xbf, 0x10, + 0xaf, 0xc4, 0xc1, 0x47, 0x9b, 0x33, 0x65, 0xfe, 0x09, 0xe9, 0xa6, 0x9b, 0x05, 0x5a, 0xbf, 0x89, + 0x04, 0xd3, 0x6b, 0xd0, 0x0f, 0x4d, 0xb6, 0x7c, 0x51, 0xb7, 0x77, 0xdf, 0x89, 0x75, 0xd3, 0xf3, + 0x1c, 0xff, 0x5f, 0x5e, 0xf8, 0x50, 0xac, 0xd8, 0x9b, 0x0d, 0xe3, 0x84, 0x49, 0xd6, 0x86, 0x9e, + 0x99, 0x99, 0xb4, 0x71, 0x8d, 0x6f, 0xf0, 0x59, 0x55, 0x47, 0x8d, 0x8c, 0x66, 0xa7, 0x9a, 0x1c, + 0x7f, 0x82, 0x38, 0x97, 0x05, 0x62, 0xb1, 0x09, 0x07, 0x2f, 0x12, 0x3b, 0x21, 0x59, 0x86, 0x0d, + 0xa3, 0x07, 0xe0, 0x92, 0x95, 0x3f, 0xf0, 0x47, 0xdc, 0x68, 0x12, 0x1c, 0xf8, 0x21, 0x92, 0x9a, + 0x1b, 0xf8, 0x9f, 0x8b, 0xd0, 0xc9, 0x0a, 0xc5, 0xd4, 0x5c, 0xc1, 0x80, 0xf8, 0x21, 0x26, 0x48, + 0x6b, 0xc4, 0xa2, 0xd7, 0xc1, 0x55, 0xdd, 0xde, 0x8d, 0xf2, 0x51, 0x58, 0x4f, 0x2a, 0xe8, 0x43, + 0xc6, 0xf0, 0x58, 0x25, 0xd7, 0x5d, 0x50, 0xdf, 0x69, 0x39, 0xea, 0x92, 0x4d, 0x35, 0xeb, 0x8d, + 0xae, 0xa9, 0x56, 0x7a, 0x4b, 0x6b, 0x1a, 0xb2, 0x1a, 0x4b, 0x82, 0xb6, 0x1b, 0x20, 0xc5, 0x4b, + 0x2c, 0x18, 0xbe, 0x9f, 0x8a, 0xcb, 0x7e, 0x34, 0x40, 0x78, 0x6f, 0x04, 0x88, 0x2a, 0x0b, 0xf4, + 0xba, 0x22, 0x72, 0xba, 0xb2, 0x72, 0xc0, 0xa1, 0x48, 0x9b, 0xce, 0x8e, 0xcb, 0x49, 0x78, 0xf3, + 0x6a, 0x5e, 0x0e, 0xa4, 0xc1, 0xf3, 0xe5, 0x45, 0x0f, 0xfe, 0x14, 0x91, 0xcc, 0xc7, 0x42, 0x29, + 0x26, 0x0b, 0xcb, 0x3a, 0xa4, 0x66, 0x38, 0xbf, 0x3e, 0x09, 0x6a, 0xc7, 0x5d, 0x1a, 0xbf, 0xc1, + 0x48, 0x94, 0xd0, 0x46, 0xa2, 0x7f, 0x2d, 0x62, 0x61, 0xcc, 0x2b, 0x28, 0x93, 0x94, 0xb7, 0xc1, + 0x49, 0x97, 0x40, 0x64, 0xe4, 0xb6, 0x02, 0x80, 0x83, 0x88, 0x00, 0x73, 0x28, 0xe9, 0xdb, 0xe2, + 0xa3, 0x10, 0xac, 0x33, 0x04, 0xe5, 0x21, 0x89, 0x1a, 0xb4, 0xd8, 0xc0, 0xbd, 0x3f, 0x0a, 0x0d, + 0x37, 0x34, 0x70, 0x54, 0x4e, 0x00, 0x03, 0xd6, 0x8e, 0x48, 0x46, 0x6c, 0xc7, 0x1c, 0x33, 0x63, + 0x44, 0x20, 0xcc, 0xdd, 0xdd, 0x7c, 0xc9, 0xa6, 0x8d, 0xa9, 0x9b, 0x30, 0xf9, 0xa7, 0x00, 0x60, + 0x83, 0x22, 0xe2, 0x42, 0x86, 0x1e, 0x10, 0xd1, 0x39, 0x8e, 0x6a, 0x1b, 0x27, 0x99, 0xde, 0x81, + 0x91, 0x44, 0xa8, 0x6c, 0x92, 0xa7, 0xc2, 0x97, 0x72, 0x5f, 0x52, 0xd3, 0xcb, 0x37, 0x83, 0xc8, + 0x69, 0x83, 0x83, 0x9f, 0xe1, 0x4d, 0x82, 0x96, 0x8e, 0xf6, 0x88, 0x3e, 0xd6, 0x52, 0x2d, 0x1b, + 0x45, 0x10, 0x6a, 0xa5, 0x4d, 0xf0, 0x55, 0x44, 0x10, 0xfc, 0xea, 0xb8, 0x00, 0x17, 0x2b, 0xb2, + 0x2a, 0x35, 0x02, 0xec, 0x8a, 0xb0, 0x3b, 0xf0, 0xa5, 0x8d, 0x0c, 0x94, 0xa4, 0x76, 0x05, 0xdb, + 0x33, 0x26, 0x2e, 0x21, 0x2b, 0x10, 0x3b, 0x10, 0xe4, 0xab, 0x18, 0x93, 0x67, 0x5f, 0xc2, 0x98, + 0xe3, 0x93, 0x41, 0x00, 0xad, 0x88, 0x51, 0x44, 0x52, 0x30, 0x80, 0xb3, 0x34, 0x92, 0xfb, 0x85, + 0xb8, 0x0c, 0x34, 0xd7, 0x10, 0x0d, 0x50, 0xc4, 0x45, 0x46, 0xdd, 0x01, 0xc2, 0xe2, 0x60, 0x88, + 0x84, 0xa8, 0x41, 0x5c, 0x42, 0xf6, 0x60, 0xf7, 0xe2, 0x04, 0x85, 0x0b, 0x35, 0x10, 0xa0, 0x83, + 0x97, 0xb9, 0x60, 0xfb, 0x5d, 0x01, 0x97, 0x20, 0x22, 0xbd, 0xd2, 0x6c, 0x9e, 0xbb, 0x37, 0x7f, + 0x85, 0x30, 0xb2, 0xf4, 0x19, 0xc1, 0x32, 0x5c, 0x2a, 0xae, 0x5a, 0xb0, 0x55, 0x56, 0x8f, 0xdd, + 0xd8, 0xae, 0xcf, 0x52, 0x43, 0xaf, 0x82, 0xc2, 0x1d, 0x98, 0x9c, 0x43, 0x85, 0x5c, 0x7e, 0xaa, + 0x3a, 0x32, 0xdd, 0xf5, 0xe2, 0x41, 0x4e, 0xd1, 0xb2, 0x55, 0x57, 0x2b, 0xff, 0xc4, 0x0c, 0x12, + 0x2b, 0x3a, 0x87, 0xb9, 0x89, 0x34, 0xf8, 0xa0, 0x19, 0x52, 0x5a, 0xc6, 0x00, 0x05, 0x3d, 0x1a, + 0x1e, 0xf0, 0xa5, 0x8d, 0x68, 0xd0, 0xd9, 0x10, 0x00, 0x11, 0xe7, 0x0c, 0xb4, 0xc5, 0xc1, 0x8f, + 0x78, 0x20, 0x34, 0x0c, 0x25, 0xfe, 0xa5, 0xc2, 0x31, 0x57, 0xf0, 0xa4, 0x20, 0xfe, 0xb8, 0x56, + 0x3c, 0x78, 0x0a, 0x88, 0xd8, 0x48, 0x87, 0x08, 0xde, 0x72, 0x20, 0x3d, 0x2a, 0x5b, 0x4a, 0xcc, + 0x1f, 0x80, 0x70, 0x6c, 0x16, 0x5f, 0x0a, 0x57, 0x0e, 0x6b, 0x5d, 0x15, 0x3c, 0x31, 0x78, 0x00, + 0x09, 0x90, 0x37, 0x54, 0x96, 0xc4, 0x2d, 0xae, 0x0a, 0x8d, 0x4e, 0xc5, 0x69, 0x2c, 0x9b, 0x8b, + 0xe1, 0x49, 0x09, 0xe2, 0x3a, 0xe3, 0xe0, 0x0c, 0x90, 0x54, 0x5b, 0xb8, 0x7a, 0x8e, 0x00, 0xa8, + 0x0e, 0x80, 0x58, 0x86, 0x5a, 0x61, 0xdb, 0xfb, 0xc4, 0x8c, 0xb2, 0x03, 0x03, 0xe0, 0xb2, 0x0c, + 0xa3, 0xab, 0x7b, 0xce, 0x03, 0x5e, 0x10, 0x57, 0x06, 0x03, 0x33, 0x2e, 0x36, 0x55, 0x4b, 0x97, + 0x88, 0x0a, 0x78, 0x4c, 0xd5, 0x39, 0x67, 0xc6, 0x51, 0x2f, 0x3d, 0x1d, 0xfa, 0x1e, 0x50, 0x85, + 0x04, 0xc0, 0x4c, 0x00, 0x99, 0xb8, 0x60, 0x4b, 0xc0, 0x00, 0xb9, 0xe2, 0x02, 0x93, 0x1c, 0xad, + 0x80, 0xe6, 0x9c, 0x91, 0xb6, 0xde, 0x29, 0xc2, 0x19, 0x22, 0x0f, 0x0a, 0x5a, 0xa3, 0x69, 0xcf, + 0x10, 0x14, 0x98, 0x72, 0xba, 0x74, 0xa2, 0xbb, 0x34, 0x43, 0x80, 0xb6, 0x96, 0x27, 0x1c, 0x18, + 0x13, 0xa6, 0x30, 0x46, 0xe9, 0xbc, 0x25, 0x53, 0x98, 0x80, 0x15, 0x41, 0x36, 0x46, 0x2b, 0xc1, + 0x56, 0x03, 0x1e, 0x63, 0xaa, 0x56, 0x72, 0x6c, 0xe9, 0x91, 0x0d, 0x80, 0x92, 0xf8, 0x80, 0x5d, + 0x33, 0x24, 0x31, 0x43, 0x80, 0xd0, 0x31, 0xd4, 0x56, 0x01, 0xf0, 0xf8, 0x26, 0x20, 0xe6, 0x91, + 0x17, 0xcf, 0xe2, 0x88, 0xf3, 0xea, 0x1b, 0xe6, 0x20, 0xe2, 0x07, 0xe2, 0xf4, 0x06, 0xd8, 0x6e, + 0xc7, 0xc2, 0x82, 0x61, 0xf8, 0x2e, 0x68, 0x1c, 0x09, 0x78, 0x92, 0xd1, 0xc0, 0x5d, 0xe8, 0x54, + 0x63, 0xfa, 0xf6, 0x00, 0x04, 0x7f, 0x58, 0xbe, 0x2a, 0xab, 0x06, 0xdb, 0x07, 0x03, 0x48, 0x84, + 0xc9, 0x93, 0xe1, 0x71, 0x01, 0x48, 0x30, 0x21, 0x20, 0xa6, 0xad, 0x72, 0x0c, 0x31, 0x80, 0x58, + 0x19, 0x4e, 0x4a, 0xb1, 0xb2, 0xf9, 0xa1, 0x4d, 0x85, 0xe9, 0x13, 0xc9, 0x0a, 0xf8, 0x29, 0x25, + 0xb4, 0xd1, 0x07, 0x84, 0xdd, 0x5d, 0xc7, 0xac, 0x41, 0xdd, 0x83, 0x84, 0x23, 0x43, 0x02, 0xba, + 0x99, 0x48, 0x51, 0x7c, 0x28, 0x25, 0x8c, 0x94, 0x0f, 0x63, 0xab, 0xa8, 0x66, 0x12, 0xc7, 0x3a, + 0xb7, 0x99, 0x40, 0xa4, 0xaa, 0xe9, 0xb1, 0x99, 0x8c, 0xae, 0x63, 0xdd, 0xdf, 0xc1, 0x21, 0x91, + 0xbb, 0xac, 0xaf, 0xad, 0x60, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x25, 0x12, 0xb0, 0x32, 0x81, + 0x96, 0x20, 0xe1, 0x34, 0xab, 0xf3, 0x69, 0xb4, 0x1b, 0x71, 0x64, 0xda, 0x6b, 0x69, 0xa1, 0xbc, + 0xc2, 0x1d, 0x5d, 0x40, 0x8f, 0x10, 0x08, 0x03, 0x06, 0x2c, 0x19, 0x04, 0x6e, 0x91, 0x18, 0x19, + 0x10, 0xc0, 0x79, 0x00, 0xf2, 0x21, 0x1c, 0x07, 0xb8, 0x36, 0x40, 0xe3, 0xed, 0x25, 0x01, 0xaa, + 0xa5, 0x1d, 0x6e, 0xcc, 0xbf, 0xf1, 0x01, 0x82, 0xed, 0xaa, 0x82, 0x8a, 0x83, 0x5e, 0x14, 0x83, + 0x9c, 0xef, 0xd1, 0x10, 0xe1, 0xf1, 0x54, 0x4e, 0x72, 0xa4, 0x2f, 0x64, 0x7a, 0xf5, 0x04, 0x02, + 0xae, 0xf4, 0x5d, 0x16, 0x21, 0x5d, 0x61, 0xbf, 0x2f, 0x50, 0x7f, 0x4e, 0x30, 0x26, 0xb4, 0x18, + 0x62, 0x61, 0x00, 0x04, 0x94, 0x0c, 0xd4, 0x13, 0x7f, 0x12, 0x30, 0xc4, 0xd2, 0x60, 0x15, 0x6f, + 0x2c, 0x63, 0xa3, 0xf3, 0xc0, 0x60, 0x5c, 0x78, 0x1e, 0x78, 0x3d, 0xe0, 0x1e, 0x70, 0x00, 0xe1, + 0xee, 0x1e, 0xf5, 0x6a, 0x4a, 0xd0, 0xbd, 0x0d, 0xb9, 0x04, 0x1d, 0x1c, 0x89, 0x08, 0x62, 0x02, + 0x81, 0x07, 0x13, 0xf1, 0x27, 0xbb, 0xd2, 0x90, 0x02, 0x22, 0x52, 0x56, 0xb2, 0xb6, 0xe2, 0x5e, + 0xbc, 0xc4, 0xf3, 0xf8, 0x90, 0xa5, 0xf7, 0x96, 0xcb, 0x18, 0xa3, 0x38, 0x58, 0x38, 0x58, 0x2c, + 0x65, 0x8c, 0x28, 0xd0, 0xb6, 0x3d, 0xf2, 0xd8, 0xa3, 0x3b, 0x02, 0x05, 0x8b, 0x46, 0xd6, 0x20, + 0x40, 0x2d, 0x3b, 0xb8, 0xad, 0xc2, 0x55, 0xc0, 0xce, 0xcc, 0x83, 0xa7, 0xe1, 0xc1, 0x28, 0xe0, + 0x1c, 0xe3, 0xd2, 0x9e, 0x07, 0x2c, 0x06, 0x1a, 0x17, 0x40, 0x1c, 0xa6, 0xc9, 0xa3, 0x9c, 0x2e, + 0x01, 0x83, 0x89, 0xd6, 0x21, 0xae, 0x10, 0x08, 0x02, 0x81, 0x98, 0x1c, 0x0c, 0xaa, 0x39, 0xd7, + 0x38, 0x18, 0x06, 0xa9, 0xc3, 0x4c, 0xec, 0x0c, 0x3b, 0xe2, 0x7e, 0x17, 0x72, 0xa3, 0x17, 0x08, + 0x88, 0x42, 0xfa, 0x18, 0xe8, 0xb1, 0x57, 0x52, 0x5f, 0x58, 0x63, 0xd5, 0x22, 0x15, 0xd5, 0x32, + 0xf5, 0x4c, 0x97, 0x58, 0xbe, 0xb1, 0x78, 0x40, 0x13, 0x84, 0x93, 0x3f, 0x72, 0xdb, 0x8a, 0xc5, + 0x62, 0xb1, 0x3c, 0x47, 0xf1, 0x20, 0xa6, 0x37, 0xad, 0xe4, 0x3a, 0x32, 0xd1, 0x61, 0xf8, 0x5a, + 0x61, 0xff, 0x2b, 0x4e, 0xd8, 0xa4, 0x39, 0xc7, 0x41, 0xea, 0x07, 0x0c, 0x7a, 0x79, 0xe2, 0x01, + 0x6e, 0xf7, 0x26, 0x53, 0x77, 0xfa, 0x09, 0x95, 0x2f, 0x98, 0xce, 0x33, 0x84, 0xc6, 0x08, 0x64, + 0xee, 0x20, 0x13, 0x8e, 0xdb, 0x55, 0x55, 0x5f, 0xf8, 0x85, 0xee, 0x22, 0x09, 0x62, 0xe2, 0xa8, + 0x99, 0xbf, 0x1f, 0x1c, 0x4b, 0xcc, 0x78, 0x80, 0x52, 0x76, 0x00, 0x99, 0x92, 0xa1, 0x8d, 0x80, + 0x76, 0x25, 0x92, 0xe5, 0x9e, 0xc1, 0xec, 0xc0, 0x05, 0x5a, 0xca, 0xd7, 0x0c, 0x30, 0x86, 0xf5, + 0xd3, 0xd6, 0x1f, 0xfc, 0x78, 0x81, 0xe6, 0x2f, 0x11, 0xf1, 0x1c, 0x61, 0x9a, 0xe3, 0xaa, 0x1f, + 0x0f, 0xd8, 0xc1, 0xee, 0xe1, 0x00, 0x52, 0x25, 0xb9, 0xd8, 0x77, 0x77, 0x71, 0x9c, 0x7c, 0xfe, + 0x4f, 0xa6, 0x00, 0x6f, 0x3a, 0xfd, 0x68, 0x7d, 0x0c, 0xf4, 0x27, 0x09, 0x3a, 0x33, 0x0f, 0x5e, + 0x9f, 0xa1, 0x29, 0x57, 0xaa, 0x65, 0xeb, 0xdf, 0x5e, 0xfa, 0x99, 0x47, 0x84, 0x06, 0x8e, 0x70, + 0x61, 0xc0, 0x00, 0x5c, 0x7b, 0xe5, 0xb1, 0x2e, 0xaf, 0xc4, 0x19, 0x6a, 0x73, 0xd4, 0xe0, 0x58, + 0x38, 0x70, 0x89, 0x6f, 0xb1, 0xc3, 0x94, 0x93, 0xaf, 0x1e, 0x3d, 0x8d, 0xd0, 0xff, 0x82, 0xb2, + 0x48, 0x7a, 0x3a, 0x28, 0x6f, 0x4c, 0xf3, 0xc5, 0xa6, 0x99, 0x8b, 0x11, 0xa6, 0x4a, 0xfe, 0xf8, + 0x26, 0xb8, 0xad, 0xcb, 0xc2, 0xad, 0x0b, 0xbc, 0xbc, 0xf4, 0x98, 0x83, 0x58, 0xf1, 0x7f, 0x05, + 0x25, 0x2b, 0xc8, 0xfd, 0xc2, 0x02, 0xea, 0x11, 0x26, 0xaa, 0x14, 0x98, 0x97, 0xf8, 0x21, 0x1a, + 0x92, 0x47, 0xba, 0x8b, 0x1d, 0xe1, 0x11, 0x00, 0x8b, 0x5a, 0xc6, 0x78, 0x90, 0x58, 0x61, 0x75, + 0x51, 0x76, 0x35, 0xb0, 0x4a, 0xa1, 0x2b, 0x0d, 0xa4, 0x10, 0xde, 0x5b, 0x89, 0x57, 0x8b, 0x15, + 0x25, 0xc0, 0x1e, 0x64, 0x56, 0x6f, 0xe0, 0x84, 0x4c, 0xe0, 0x8c, 0xb2, 0x5a, 0x8b, 0xbc, 0x99, + 0x5a, 0xcb, 0xad, 0x1c, 0x65, 0xe0, 0xa0, 0x6a, 0x49, 0x69, 0x25, 0xbf, 0xc6, 0x52, 0x4b, 0x49, + 0x2d, 0x24, 0xb6, 0x9a, 0xc7, 0xf5, 0x4e, 0xdf, 0x42, 0x1f, 0xe8, 0xaf, 0x27, 0x47, 0x2f, 0x24, + 0xe8, 0x8e, 0x44, 0xf0, 0x54, 0x30, 0x38, 0x0f, 0x16, 0x03, 0x73, 0xc3, 0xbb, 0xc1, 0x6c, 0xb1, + 0x96, 0xc5, 0x6b, 0x55, 0xf1, 0xe1, 0x11, 0xa4, 0x87, 0xa0, 0xe8, 0x86, 0x48, 0x0d, 0x8c, 0x02, + 0x53, 0x5d, 0x38, 0xef, 0xd4, 0xff, 0x68, 0xc1, 0x58, 0x0f, 0xce, 0x85, 0xb0, 0x7d, 0x86, 0xa5, + 0x93, 0x2c, 0x84, 0x97, 0x44, 0xf0, 0xce, 0x2c, 0x33, 0xec, 0x9d, 0x93, 0xf0, 0x88, 0x9f, 0x19, + 0xe3, 0x99, 0xfc, 0xc1, 0xe5, 0x63, 0xc1, 0x08, 0x4e, 0xdb, 0xff, 0xf0, 0x47, 0xc1, 0xc6, 0x22, + 0x3c, 0x18, 0x8a, 0xff, 0x82, 0x41, 0x85, 0xe9, 0x18, 0x30, 0x25, 0xbe, 0xe2, 0x44, 0x05, 0x04, + 0x36, 0x0c, 0xba, 0x4e, 0x60, 0xff, 0x96, 0xef, 0x6e, 0x2b, 0x15, 0xc5, 0x69, 0xf7, 0x12, 0x20, + 0x13, 0x0f, 0x34, 0xc3, 0x68, 0x6b, 0xc0, 0x18, 0xd0, 0xc6, 0xf2, 0x8c, 0x13, 0x78, 0xff, 0x05, + 0x1a, 0xc6, 0x81, 0xf9, 0x36, 0x04, 0xb6, 0xc6, 0x75, 0x9f, 0x43, 0x3b, 0xe1, 0x42, 0x21, 0x85, + 0x9c, 0x39, 0x20, 0xa9, 0x13, 0xe9, 0x61, 0x4f, 0x0a, 0xaf, 0x18, 0xc5, 0x10, 0x54, 0x1e, 0x7f, + 0xbb, 0x5a, 0xbf, 0xef, 0x82, 0xb1, 0xa5, 0x83, 0x12, 0x24, 0x10, 0xb8, 0xed, 0x1d, 0xb0, 0x63, + 0xbd, 0xdd, 0xde, 0xbc, 0x22, 0x0b, 0x86, 0xb7, 0x6a, 0xc5, 0x96, 0xa4, 0x4b, 0xe8, 0x95, 0x5d, + 0x1a, 0x0f, 0x82, 0x2b, 0xba, 0xac, 0xbe, 0x51, 0x29, 0x52, 0x4b, 0xc2, 0x5d, 0x24, 0xb6, 0x9a, + 0x87, 0x09, 0x03, 0x1a, 0x3c, 0xcd, 0xb6, 0xfd, 0x34, 0xd2, 0x4b, 0x41, 0x47, 0x48, 0xc5, 0x36, + 0xda, 0x09, 0x04, 0x9a, 0x6d, 0xb7, 0xe1, 0x1b, 0x4d, 0x6d, 0x35, 0xb4, 0xd7, 0xe2, 0x7a, 0x49, + 0x69, 0x25, 0xe1, 0x1b, 0x4d, 0x6d, 0x35, 0xb4, 0xd6, 0x23, 0xa3, 0x62, 0x1e, 0x8e, 0xe5, 0xf5, + 0x6b, 0xea, 0xe0, 0xbd, 0x19, 0x92, 0xf4, 0x24, 0xa9, 0x7d, 0x47, 0x6f, 0xa1, 0x1d, 0xe2, 0x01, + 0x61, 0x9b, 0x9c, 0x60, 0xab, 0xa6, 0xd2, 0x76, 0xb2, 0x28, 0xd7, 0x84, 0x02, 0x86, 0x06, 0xdd, + 0x18, 0x04, 0x5a, 0x0a, 0x91, 0xa6, 0x16, 0x02, 0x5e, 0x79, 0xc8, 0x32, 0xc3, 0x22, 0x42, 0xb3, + 0xa0, 0xb8, 0x2a, 0xa1, 0x52, 0xe9, 0x50, 0x07, 0xa0, 0xf0, 0x0e, 0x12, 0x9b, 0x16, 0x03, 0xf3, + 0xbd, 0x4c, 0xe2, 0x42, 0x21, 0x48, 0x31, 0x66, 0x0a, 0x02, 0x22, 0x9e, 0x3c, 0x67, 0xe4, 0x9c, + 0xcb, 0x07, 0x59, 0x63, 0x6c, 0x9d, 0xb2, 0x6e, 0x26, 0x5f, 0x05, 0x01, 0x3a, 0x00, 0x95, 0x89, + 0x77, 0xd2, 0x07, 0xa9, 0x51, 0x57, 0x8a, 0x0b, 0x44, 0x2a, 0x25, 0xef, 0x6e, 0xfe, 0x0a, 0x85, + 0xb4, 0xd1, 0x6f, 0x8c, 0x9a, 0x22, 0xc7, 0x7b, 0x9f, 0x51, 0x7f, 0x88, 0x08, 0x82, 0x32, 0xbc, + 0xfe, 0xc3, 0x10, 0x24, 0x58, 0xc7, 0x28, 0xc1, 0x7b, 0xe4, 0x87, 0x12, 0x12, 0xc2, 0xa6, 0x43, + 0x41, 0x94, 0x2d, 0x05, 0x6d, 0xf7, 0x88, 0x12, 0x19, 0x1e, 0x31, 0xff, 0x59, 0xab, 0xe5, 0xac, + 0xa9, 0x64, 0x7f, 0xff, 0x12, 0x8e, 0x44, 0xfa, 0x8e, 0xdf, 0x42, 0x2b, 0xeb, 0xdf, 0x5c, 0x2b, + 0xa3, 0xba, 0x3f, 0xa3, 0xb1, 0x7d, 0x11, 0xc8, 0x9e, 0x89, 0x33, 0xe8, 0xe7, 0x4b, 0xea, 0x74, + 0x93, 0xa2, 0x57, 0xd4, 0xb7, 0x12, 0x24, 0x16, 0x08, 0x82, 0xd0, 0x69, 0x84, 0xe2, 0xc4, 0xd3, + 0x2b, 0x08, 0x79, 0x5b, 0x33, 0x17, 0x56, 0x7c, 0x18, 0x06, 0x31, 0xdd, 0x29, 0x07, 0x42, 0xb0, + 0xdf, 0x0a, 0x1a, 0xda, 0xd2, 0xdf, 0x17, 0x43, 0x5a, 0x21, 0x7e, 0x98, 0xaa, 0x1e, 0x44, 0xc0, + 0x31, 0x0f, 0x3c, 0x94, 0x04, 0xd8, 0xb9, 0x03, 0xd0, 0xc2, 0x78, 0x34, 0xde, 0x15, 0xd7, 0x76, + 0x9b, 0x02, 0xb0, 0x6b, 0x87, 0x94, 0xce, 0x15, 0xcf, 0x12, 0x14, 0x20, 0x31, 0x98, 0xcb, 0x33, + 0x9b, 0xc1, 0x6c, 0xdb, 0xf3, 0xf7, 0xee, 0xa8, 0x38, 0x98, 0x0c, 0xf0, 0xe2, 0x63, 0xe3, 0x8e, + 0x28, 0xcc, 0x6a, 0x43, 0xa0, 0x39, 0x40, 0x3f, 0x70, 0x03, 0x53, 0xb8, 0x88, 0x28, 0xd8, 0xf2, + 0x8a, 0xce, 0xd8, 0x77, 0x95, 0xb6, 0xa3, 0xcc, 0xb7, 0xf8, 0x46, 0xab, 0x8d, 0x79, 0xd8, 0xcc, + 0x65, 0x14, 0x5e, 0x57, 0xc2, 0x15, 0x61, 0x2a, 0xd5, 0x56, 0x89, 0x53, 0xc4, 0x41, 0x5e, 0xec, + 0x09, 0xf1, 0x58, 0xef, 0x93, 0x0b, 0x02, 0x64, 0x48, 0x0a, 0xa3, 0x01, 0xef, 0xf1, 0x22, 0x01, + 0x55, 0x66, 0xc2, 0xe3, 0x8e, 0x8a, 0x8e, 0xdc, 0x62, 0x7d, 0xdd, 0xf8, 0x98, 0x29, 0x28, 0x52, + 0x84, 0x70, 0xc2, 0x69, 0xa0, 0x3c, 0x7d, 0xad, 0xbc, 0x11, 0xad, 0xa8, 0x3a, 0x50, 0x4a, 0x41, + 0x3f, 0xd7, 0x59, 0xe7, 0x7d, 0x1d, 0xf8, 0x21, 0x13, 0x40, 0xcb, 0x44, 0x09, 0xbc, 0x56, 0xd8, + 0x3b, 0x78, 0x94, 0x2c, 0x85, 0x5d, 0x08, 0xaf, 0xa3, 0x91, 0x3e, 0xb8, 0x4f, 0xd7, 0xbe, 0xaf, + 0x0a, 0x75, 0xea, 0xeb, 0x14, 0x9d, 0x10, 0xa9, 0xf5, 0x3a, 0x5f, 0x5c, 0x3c, 0x48, 0x50, 0x64, + 0x23, 0xbc, 0x10, 0x56, 0xbf, 0x75, 0x3c, 0x10, 0x47, 0x9e, 0x06, 0x16, 0x13, 0x98, 0x18, 0xad, + 0x2b, 0xf7, 0x50, 0x1d, 0x9a, 0x95, 0x4c, 0xcb, 0x9a, 0x65, 0x4f, 0x85, 0x09, 0x65, 0x81, 0x51, + 0xd5, 0x45, 0x54, 0x40, 0xc1, 0x90, 0x0a, 0xd0, 0x8c, 0x3b, 0x17, 0x65, 0x72, 0xe2, 0x50, 0xc9, + 0xde, 0x90, 0xbe, 0x85, 0x11, 0x1b, 0x17, 0x89, 0x19, 0xcf, 0xbe, 0x52, 0x03, 0xf0, 0x7e, 0xd5, + 0x90, 0x9a, 0x02, 0x61, 0xcd, 0x4e, 0x53, 0x01, 0x97, 0xed, 0x1d, 0x19, 0xee, 0x20, 0x28, 0x55, + 0xea, 0xc5, 0x0e, 0x08, 0x0a, 0xb9, 0x4a, 0x33, 0x42, 0x3a, 0xe4, 0xf5, 0xce, 0x30, 0xfc, 0xa9, + 0x5f, 0x09, 0x40, 0x1c, 0xf8, 0xff, 0x4c, 0x80, 0x39, 0x5e, 0xf8, 0x52, 0x4e, 0xbe, 0x24, 0xa3, + 0xcb, 0xc2, 0x0f, 0x9e, 0xe2, 0xdc, 0xc3, 0xf9, 0x1f, 0xe6, 0xa4, 0xa4, 0x92, 0x91, 0x38, 0x5e, + 0xcd, 0x2d, 0x8e, 0xdf, 0x1b, 0x42, 0xc5, 0xc1, 0x92, 0xcc, 0x8e, 0x90, 0x4b, 0xdf, 0x47, 0x69, + 0x30, 0x39, 0x50, 0x25, 0x5c, 0xeb, 0x62, 0x22, 0x1b, 0xd2, 0xd9, 0x6d, 0xff, 0xc5, 0xa6, 0xdf, + 0xfe, 0x13, 0x27, 0x7d, 0x1d, 0xcc, 0x2e, 0x74, 0x9f, 0x8e, 0xf3, 0xfd, 0x11, 0x9a, 0x5c, 0x1e, + 0xee, 0x34, 0x43, 0x2d, 0x63, 0x5d, 0xf7, 0xe0, 0x8c, 0x78, 0xce, 0xbf, 0x1d, 0xb8, 0x81, 0x3f, + 0x45, 0x4f, 0x11, 0xd1, 0xc7, 0x57, 0xd1, 0x9a, 0xfa, 0xd4, 0x6f, 0x56, 0x8a, 0xea, 0x65, 0x9f, + 0x51, 0xdb, 0xe8, 0x99, 0x5f, 0x45, 0x4e, 0x9e, 0x24, 0x16, 0x04, 0x20, 0x91, 0x31, 0xdc, 0xe7, + 0xe9, 0xcd, 0x53, 0x30, 0x4a, 0xe4, 0xd8, 0x16, 0xcb, 0x62, 0x13, 0x14, 0xc1, 0xe1, 0x4c, 0xf7, + 0xcd, 0xbc, 0x37, 0x8b, 0xce, 0x26, 0x4e, 0x13, 0x80, 0x66, 0xdc, 0xbb, 0x0d, 0x18, 0x2f, 0x0f, + 0x2c, 0x19, 0xc8, 0xc1, 0x3c, 0x7b, 0xc8, 0x69, 0x8b, 0x4d, 0x65, 0x0e, 0xdf, 0xc4, 0x05, 0x04, + 0xb2, 0x92, 0xa8, 0x0a, 0x03, 0x62, 0x5a, 0x26, 0x01, 0x63, 0x16, 0xdf, 0x4e, 0x28, 0x12, 0xb4, + 0x87, 0xfd, 0xa1, 0xfe, 0x1b, 0x32, 0xbb, 0xd0, 0x86, 0x8a, 0x78, 0x90, 0x54, 0x48, 0x81, 0x2e, + 0x63, 0x70, 0x17, 0x26, 0x9e, 0xfb, 0x69, 0x88, 0x97, 0x96, 0x37, 0x7c, 0xbf, 0xe1, 0x49, 0x6a, + 0x66, 0x31, 0x11, 0x29, 0x13, 0x2a, 0x77, 0x0b, 0xd4, 0xd0, 0x51, 0x72, 0xf2, 0x30, 0x5b, 0xc4, + 0x85, 0x3c, 0xa9, 0x0b, 0xcc, 0x08, 0x0f, 0x7b, 0xba, 0x9a, 0x1b, 0x08, 0x0b, 0x79, 0x06, 0xff, + 0x04, 0x85, 0x31, 0x05, 0x54, 0x4c, 0x82, 0xff, 0x18, 0x28, 0x32, 0xcb, 0x3f, 0x3e, 0x4d, 0x2a, + 0xf6, 0xc1, 0x9a, 0x9e, 0x59, 0x28, 0x54, 0xb8, 0x3d, 0x04, 0x7b, 0xe8, 0xf1, 0x7d, 0x47, 0x65, + 0xfa, 0x90, 0xa2, 0x7a, 0xa6, 0x47, 0xea, 0x3e, 0xae, 0x88, 0x63, 0x7d, 0x52, 0xa1, 0xbc, 0x11, + 0xd6, 0xb6, 0x3e, 0xa9, 0x5f, 0xac, 0xa6, 0xeb, 0x57, 0x88, 0x0a, 0x05, 0x10, 0xc8, 0x9e, 0xbb, + 0x10, 0xf2, 0x9f, 0x3d, 0x81, 0x2c, 0x28, 0x68, 0x46, 0x04, 0x80, 0x0b, 0x60, 0x1a, 0x06, 0x19, + 0x41, 0x80, 0x80, 0x93, 0x46, 0xd4, 0xe1, 0x00, 0x02, 0xbc, 0xaa, 0x74, 0x0b, 0x82, 0x1f, 0xc6, + 0x95, 0x86, 0xd1, 0x5c, 0xf9, 0xa7, 0x08, 0x5b, 0x95, 0xd1, 0x00, 0x0e, 0x27, 0xca, 0x47, 0xb1, + 0x2f, 0x42, 0x89, 0x3e, 0x1c, 0xb8, 0x03, 0x8d, 0x04, 0xc8, 0x6b, 0x22, 0x35, 0x41, 0xa6, 0x8c, + 0xc5, 0x2c, 0xc6, 0x19, 0xdc, 0x15, 0xe0, 0x5d, 0xff, 0x62, 0x4e, 0x09, 0x9c, 0xd2, 0xc4, 0xef, + 0x09, 0xa6, 0xaf, 0xf6, 0x55, 0x68, 0x1b, 0xb1, 0x9b, 0x24, 0x0f, 0xdb, 0x2e, 0xf8, 0x53, 0x76, + 0x48, 0x12, 0x6c, 0x20, 0x82, 0x03, 0x99, 0xe8, 0xc6, 0x09, 0xbe, 0xea, 0x70, 0x1e, 0xc2, 0x0a, + 0xbd, 0x92, 0x63, 0xfe, 0xe9, 0xbb, 0x48, 0x0e, 0xc5, 0x14, 0xd3, 0xb7, 0x24, 0xc3, 0x36, 0x53, + 0x48, 0x06, 0x85, 0xa6, 0xd2, 0x2f, 0x19, 0xa3, 0x3e, 0x59, 0xc8, 0xc1, 0xaa, 0xe3, 0x13, 0x19, + 0xd3, 0xaa, 0x1b, 0x42, 0xa7, 0x2b, 0x1f, 0x81, 0xc1, 0xb4, 0xbb, 0x1d, 0x41, 0xdf, 0xce, 0x61, + 0x06, 0xac, 0xde, 0x4a, 0x7b, 0xc2, 0x87, 0x56, 0x28, 0x90, 0xf4, 0xa8, 0x9c, 0x92, 0x5c, 0x08, + 0x60, 0x35, 0x89, 0x82, 0x06, 0x96, 0x31, 0x3c, 0x80, 0x00, 0x4e, 0xb0, 0x6c, 0xab, 0xa5, 0x35, + 0x91, 0x6c, 0x82, 0x08, 0x52, 0x94, 0x18, 0x86, 0x98, 0x5c, 0x35, 0xbf, 0xef, 0x85, 0x21, 0x2b, + 0xec, 0xa7, 0x75, 0x2d, 0x82, 0x4a, 0xac, 0xcb, 0x42, 0xfc, 0x8b, 0xc5, 0x80, 0xd9, 0x86, 0x0c, + 0xb6, 0x5a, 0x9c, 0x83, 0x64, 0x65, 0x04, 0x3a, 0xe0, 0x14, 0x69, 0x04, 0x4e, 0x75, 0x49, 0xaa, + 0x82, 0x80, 0x0d, 0x6c, 0x8b, 0x10, 0x9c, 0x61, 0xbc, 0xbc, 0x4d, 0x23, 0x15, 0xe1, 0x4b, 0x18, + 0xc9, 0xca, 0x7f, 0x86, 0x00, 0x01, 0x29, 0x17, 0xeb, 0x20, 0x5e, 0x5d, 0x61, 0x21, 0x20, 0xa0, + 0x43, 0xbe, 0xbb, 0x49, 0x38, 0x86, 0x13, 0xee, 0xb6, 0x1c, 0x48, 0x52, 0x4a, 0x10, 0xdb, 0xaf, + 0x24, 0x40, 0x41, 0x40, 0x02, 0x85, 0xae, 0x08, 0x0d, 0xff, 0x04, 0x65, 0x03, 0xf5, 0x3c, 0x20, + 0x39, 0xca, 0xb9, 0xf0, 0x4c, 0x42, 0xaf, 0x11, 0xae, 0xca, 0x19, 0x14, 0x72, 0xbf, 0x47, 0xaf, + 0x51, 0x12, 0x0c, 0xfd, 0xf0, 0xc0, 0x67, 0x3c, 0xc7, 0x7d, 0xaa, 0x68, 0x54, 0xd1, 0xce, 0xb3, + 0x69, 0xb4, 0xfa, 0x7d, 0xfc, 0xa2, 0x29, 0xc4, 0xeb, 0xaa, 0x76, 0xba, 0x91, 0x2f, 0xab, 0x80, + 0x9f, 0x46, 0x4e, 0x97, 0x57, 0xfa, 0xa6, 0x4f, 0xab, 0x45, 0x75, 0xd7, 0xc2, 0x98, 0x97, 0x3c, + 0xa2, 0x13, 0xd9, 0x58, 0xe1, 0x85, 0x3c, 0x7e, 0x29, 0xd9, 0x3e, 0xe2, 0x70, 0xe2, 0x41, 0x60, + 0x42, 0x60, 0x87, 0x86, 0x81, 0x7f, 0x9b, 0xd6, 0x23, 0x4c, 0x35, 0x16, 0x08, 0xbf, 0xe1, 0x42, + 0x5f, 0x04, 0xf5, 0x12, 0xae, 0xc2, 0x49, 0xa9, 0x50, 0xe8, 0x8d, 0xb2, 0x91, 0x1f, 0xf3, 0xa1, + 0x6d, 0x9a, 0xa4, 0xf1, 0x4c, 0x23, 0x23, 0x52, 0x96, 0x6c, 0x51, 0x0c, 0xe1, 0x60, 0xe7, 0x12, + 0x00, 0x32, 0x92, 0x8d, 0xe9, 0x91, 0x49, 0x19, 0x0a, 0x00, 0x7c, 0x35, 0x83, 0xa7, 0x38, 0xd5, + 0xd0, 0xe7, 0xc2, 0x95, 0xc0, 0x4a, 0x02, 0x54, 0xe6, 0xb9, 0xc2, 0x49, 0xbc, 0x5a, 0xb0, 0x43, + 0xd8, 0xb0, 0xcb, 0xc1, 0x71, 0x83, 0x31, 0xfb, 0x69, 0x5d, 0x96, 0xac, 0x63, 0x75, 0x2b, 0x57, + 0x12, 0xfa, 0xf3, 0x38, 0x6e, 0x52, 0xc6, 0x33, 0x30, 0x40, 0x62, 0xf8, 0x29, 0x3f, 0x3c, 0xd3, + 0x98, 0xb0, 0xfc, 0xa3, 0x25, 0xa6, 0x30, 0x1f, 0xfe, 0x14, 0x24, 0x42, 0x2e, 0x46, 0xe0, 0x64, + 0x20, 0x35, 0xa0, 0x92, 0x90, 0xe3, 0x48, 0x06, 0xea, 0x9e, 0xca, 0x60, 0xdd, 0x73, 0x27, 0x8a, + 0x07, 0xf1, 0x30, 0x87, 0x5c, 0x73, 0x6f, 0x78, 0x17, 0xe4, 0xf8, 0x2a, 0x00, 0xa1, 0x98, 0xf4, + 0xeb, 0xbc, 0x6a, 0x18, 0x2f, 0x36, 0x3e, 0x0c, 0x49, 0x97, 0xf6, 0x56, 0x13, 0x83, 0x27, 0x09, + 0x58, 0xdf, 0x1c, 0x51, 0xd0, 0x1f, 0x22, 0x27, 0xed, 0xe1, 0x62, 0x88, 0x9d, 0xcc, 0x9e, 0xae, + 0xde, 0x29, 0x57, 0x8a, 0xda, 0xf8, 0xba, 0x16, 0x64, 0xbf, 0xc7, 0x54, 0x17, 0xda, 0x39, 0x06, + 0xd7, 0x15, 0x1c, 0x2d, 0xdb, 0x06, 0x05, 0x5d, 0x39, 0x30, 0xbc, 0xa7, 0x1d, 0x62, 0x63, 0xa1, + 0x96, 0x95, 0x6c, 0xf8, 0x90, 0x4f, 0x4e, 0x12, 0x79, 0x61, 0x9d, 0x3e, 0x61, 0x4b, 0x0d, 0x85, + 0xa4, 0x4d, 0x5f, 0x41, 0x5c, 0xa2, 0xfa, 0x2a, 0x58, 0x7f, 0xa1, 0xae, 0x7d, 0x0e, 0xff, 0xd0, + 0xa7, 0xf1, 0x21, 0x48, 0xc2, 0x47, 0xa0, 0x63, 0x09, 0xbc, 0x3d, 0x83, 0xb8, 0xad, 0xdf, 0x0e, + 0x4a, 0x58, 0xec, 0x77, 0xe1, 0x42, 0x13, 0xbb, 0x77, 0x48, 0x9e, 0x60, 0x2b, 0xb4, 0x85, 0xb9, + 0xfd, 0x3e, 0x0d, 0x53, 0x85, 0x02, 0x0a, 0x0f, 0xb1, 0xaf, 0x50, 0x66, 0xd8, 0x6c, 0x29, 0x3b, + 0x5b, 0xa6, 0xc0, 0x00, 0x11, 0x90, 0x7c, 0x70, 0x82, 0xa4, 0x64, 0xfd, 0xaa, 0x3d, 0x57, 0x3e, + 0xfc, 0x40, 0x9a, 0xaa, 0x1d, 0xd5, 0x97, 0x8c, 0xb7, 0x87, 0xfa, 0xa8, 0x1c, 0x48, 0x87, 0x01, + 0x94, 0xb8, 0xed, 0x09, 0x70, 0x76, 0xfa, 0x40, 0x1f, 0x7d, 0xe5, 0x73, 0x3b, 0xc2, 0x0b, 0x52, + 0x71, 0x8b, 0xd1, 0xe5, 0xd6, 0xd9, 0x7f, 0x53, 0x97, 0x74, 0x74, 0xf8, 0x90, 0xa1, 0x06, 0xc1, + 0x8d, 0x16, 0xed, 0xd8, 0x0e, 0x63, 0xea, 0xc1, 0x65, 0xfe, 0x1f, 0x7d, 0x8f, 0xaa, 0xfc, 0x9f, + 0x38, 0x45, 0xc2, 0x47, 0x39, 0x38, 0x0b, 0xa5, 0x3b, 0x84, 0xf8, 0x25, 0x11, 0xee, 0xe1, 0x6e, + 0x7d, 0x4e, 0xe2, 0x65, 0xbf, 0xc2, 0x87, 0xaa, 0xb6, 0xc7, 0xdd, 0x6e, 0x1d, 0x8a, 0x6b, 0x6b, + 0xda, 0x7d, 0xfe, 0x09, 0x4b, 0x9b, 0xda, 0x36, 0xd3, 0x2a, 0x7c, 0x40, 0xc9, 0x08, 0x6b, 0x2b, + 0xb9, 0x67, 0xc1, 0x5e, 0x5a, 0x3a, 0x3c, 0x81, 0xa3, 0x7a, 0x8d, 0x55, 0x29, 0x88, 0xa0, 0x97, + 0xe1, 0xf0, 0x46, 0x11, 0xa1, 0x8d, 0x06, 0x8c, 0x94, 0x95, 0x05, 0x7a, 0x25, 0x7d, 0x72, 0x88, + 0xea, 0xf1, 0x7d, 0x6c, 0x3c, 0x13, 0x93, 0x8e, 0x85, 0x2c, 0x8f, 0x00, 0x04, 0x9f, 0xfc, 0x4c, + 0x64, 0x42, 0x9f, 0x83, 0xa1, 0xea, 0xcb, 0xe8, 0x9d, 0xf1, 0xa6, 0x40, 0x44, 0xc4, 0xca, 0x70, + 0xa4, 0x73, 0x24, 0x61, 0x60, 0xfc, 0x02, 0x01, 0x6f, 0x0b, 0x6d, 0x40, 0xca, 0x10, 0x0a, 0x78, + 0x3b, 0x09, 0xaf, 0x62, 0x5a, 0x52, 0xe8, 0x91, 0x0f, 0x25, 0x3e, 0xce, 0x31, 0xdf, 0x8c, 0xa8, + 0xa1, 0xe9, 0x83, 0x9f, 0x05, 0xd5, 0x00, 0x0f, 0xc4, 0xca, 0x20, 0x1d, 0x95, 0x7b, 0x62, 0xd7, + 0xa9, 0x91, 0xdf, 0x47, 0x71, 0xca, 0x35, 0x75, 0x50, 0xf2, 0x9d, 0x8b, 0x2b, 0xf0, 0x56, 0x34, + 0xa5, 0xe4, 0xcb, 0x45, 0x43, 0x81, 0x98, 0x65, 0xb2, 0xd7, 0x01, 0xde, 0xc9, 0xef, 0x10, 0x0b, + 0x8b, 0xb3, 0x6c, 0x8f, 0x55, 0x55, 0x77, 0xc2, 0x9a, 0x47, 0xeb, 0x00, 0x41, 0xd9, 0x4f, 0x07, + 0x76, 0x90, 0x5d, 0xac, 0x3f, 0x12, 0xf8, 0x91, 0xf5, 0xb3, 0x9d, 0x23, 0xc3, 0x77, 0x50, 0x66, + 0x3a, 0x2f, 0x20, 0xc5, 0x57, 0x09, 0x4a, 0xbf, 0xa5, 0xf7, 0x82, 0xb2, 0x28, 0x44, 0xde, 0x38, + 0x1a, 0xa0, 0x2e, 0x59, 0x99, 0x82, 0xf2, 0x7c, 0xa7, 0xaf, 0x12, 0x82, 0xe9, 0x5f, 0xaf, 0x42, + 0x9d, 0x1b, 0x28, 0x4f, 0x82, 0x71, 0x04, 0xbf, 0x49, 0x6c, 0xf8, 0x52, 0x60, 0x80, 0xae, 0xcc, + 0x9d, 0x29, 0xfb, 0xab, 0x59, 0x00, 0xe1, 0xe0, 0xaa, 0x4f, 0xe8, 0x72, 0x56, 0x0d, 0xf0, 0x85, + 0x78, 0x71, 0xfc, 0x48, 0x46, 0xa3, 0xb3, 0x83, 0xa6, 0x17, 0xd5, 0x8b, 0x4e, 0x37, 0x55, 0xeb, + 0x8b, 0xdf, 0xc1, 0x28, 0x88, 0x0f, 0xc9, 0xf9, 0x3d, 0xcf, 0x8c, 0x2d, 0x6e, 0xd0, 0x76, 0xec, + 0xed, 0x2b, 0x4b, 0x4c, 0x78, 0x00, 0x05, 0x9c, 0xa0, 0xaa, 0x6b, 0x5f, 0x85, 0x05, 0xc7, 0xc0, + 0xbc, 0x26, 0xd6, 0x66, 0x98, 0xc1, 0x98, 0x71, 0x38, 0xa7, 0x8e, 0x8d, 0xbf, 0xe5, 0x16, 0xeb, + 0x92, 0x7c, 0x8a, 0x27, 0xfb, 0x24, 0x63, 0xd9, 0xf0, 0xa1, 0xd0, 0x11, 0x83, 0x08, 0x4f, 0xff, + 0x1e, 0xa4, 0xa6, 0x3f, 0xec, 0x19, 0x83, 0x3b, 0xec, 0x7f, 0xf8, 0x2d, 0x2f, 0x14, 0x6b, 0x4f, + 0x12, 0x07, 0x8b, 0xa7, 0x2a, 0x8d, 0xaa, 0xe2, 0x04, 0xfc, 0x12, 0x0c, 0xbb, 0x48, 0xd9, 0xf1, + 0x98, 0xd0, 0x92, 0x34, 0xa0, 0x1c, 0x94, 0x10, 0x0c, 0x88, 0x94, 0x06, 0x05, 0x75, 0x37, 0x19, + 0xea, 0xd7, 0x8c, 0x10, 0x1a, 0x3d, 0x51, 0xdc, 0x38, 0xc3, 0x03, 0x5a, 0xee, 0x69, 0xe7, 0x4c, + 0x53, 0x48, 0x2b, 0x10, 0x1c, 0x44, 0x11, 0x8b, 0x0a, 0x35, 0x43, 0x01, 0x90, 0xeb, 0x36, 0x1a, + 0x7d, 0x7e, 0xac, 0x54, 0x86, 0xba, 0x12, 0x91, 0x7a, 0x2a, 0x75, 0xe8, 0x8c, 0x7d, 0x4c, 0x0a, + 0xe8, 0xcd, 0xf5, 0x6f, 0xa2, 0xb9, 0x7c, 0x11, 0x6e, 0xaa, 0xcf, 0x98, 0xd4, 0x8b, 0x26, 0x91, + 0xe2, 0x41, 0x61, 0x1d, 0x28, 0x50, 0x46, 0x23, 0x11, 0xf2, 0x2d, 0x1d, 0x88, 0x1c, 0x2d, 0x8a, + 0x53, 0xe1, 0x42, 0x1e, 0x4b, 0x32, 0xe3, 0x8a, 0xc3, 0xea, 0x97, 0xb8, 0xae, 0x5a, 0x37, 0x4c, + 0x3e, 0x09, 0x8e, 0xb3, 0x29, 0xc0, 0x81, 0xcd, 0x9a, 0x98, 0xc4, 0xff, 0xe4, 0xb0, 0x6c, 0x48, + 0xb4, 0x5e, 0x11, 0xea, 0xb8, 0xc1, 0xc3, 0xc8, 0xb9, 0x28, 0x93, 0xde, 0x14, 0x10, 0xaa, 0xa2, + 0xeb, 0x4e, 0x2e, 0x27, 0x40, 0xf8, 0x6a, 0x88, 0x06, 0x59, 0x91, 0x0b, 0xf0, 0x64, 0x3a, 0xed, + 0x99, 0xfe, 0x10, 0x38, 0x6e, 0x71, 0xc6, 0x68, 0xcf, 0x47, 0xd1, 0xa4, 0x12, 0xbe, 0x6e, 0x03, + 0x92, 0x17, 0x5d, 0x6b, 0x5f, 0x42, 0x7f, 0x7d, 0x6f, 0xf0, 0x58, 0x73, 0xfa, 0xee, 0x7a, 0x3d, + 0x03, 0x3e, 0x72, 0x5e, 0xfe, 0x24, 0x14, 0xd1, 0xbb, 0x02, 0x97, 0x6b, 0x40, 0x34, 0xb3, 0x16, + 0x7e, 0x22, 0x14, 0xb9, 0x44, 0x0d, 0xf2, 0x03, 0xec, 0x64, 0x48, 0xb2, 0xa3, 0x51, 0xcc, 0x46, + 0x8e, 0xb1, 0xa4, 0xa4, 0x77, 0xe0, 0x8c, 0xc8, 0xd7, 0x7c, 0xff, 0x04, 0xe4, 0x3b, 0x71, 0xb6, + 0x6e, 0xcd, 0x24, 0x9a, 0x7f, 0x8e, 0x15, 0xa6, 0x12, 0x1c, 0xbd, 0x62, 0xbb, 0x10, 0x9e, 0x25, + 0x39, 0x2d, 0x7e, 0x5a, 0x5a, 0x5e, 0x51, 0x35, 0x13, 0xc8, 0xc6, 0xf4, 0x76, 0x23, 0x7a, 0xf4, + 0xfd, 0x14, 0xc9, 0xf3, 0x08, 0xbb, 0xbe, 0x26, 0x11, 0x37, 0x15, 0xd0, 0x9d, 0xc5, 0x6f, 0x7e, + 0x24, 0x29, 0x15, 0x8a, 0xdd, 0xec, 0xc1, 0xed, 0xef, 0xb2, 0x89, 0x55, 0x61, 0xe2, 0x42, 0x97, + 0x9d, 0x43, 0x61, 0x5a, 0x93, 0x1f, 0x17, 0xd6, 0xf6, 0x1b, 0xa7, 0xb0, 0x25, 0x58, 0xcf, 0x36, + 0x1f, 0x3c, 0x48, 0x2b, 0x3f, 0x52, 0x75, 0x9a, 0x1a, 0xa8, 0xd2, 0x22, 0xcf, 0x7c, 0x15, 0x79, + 0xf1, 0x5a, 0xd5, 0xa7, 0x40, 0x64, 0x54, 0xff, 0x18, 0x2b, 0x77, 0x19, 0x5b, 0x00, 0x03, 0xe3, + 0x81, 0x81, 0x6a, 0x85, 0x11, 0x01, 0x9e, 0xe1, 0x6b, 0x0b, 0x9c, 0x3b, 0x27, 0xc6, 0xe2, 0x47, + 0x4f, 0xb0, 0xb1, 0x3c, 0x7c, 0xb1, 0x1b, 0xb1, 0xc8, 0x29, 0xce, 0x82, 0xd9, 0xee, 0x33, 0xfa, + 0x4d, 0x2c, 0xa2, 0xd4, 0xe7, 0xd3, 0x2a, 0x96, 0xbf, 0x0a, 0x4f, 0xa3, 0xe9, 0x0b, 0x19, 0x33, + 0x90, 0x89, 0x8d, 0x8a, 0xdf, 0xe2, 0xb1, 0x73, 0x7d, 0xde, 0xcc, 0x83, 0xd3, 0xe5, 0xba, 0x73, + 0xe2, 0x4b, 0x7b, 0x0f, 0x53, 0x66, 0x0c, 0xf2, 0xa7, 0xb6, 0xb0, 0x42, 0x78, 0xd8, 0x6f, 0x28, + 0xb7, 0x77, 0x7f, 0x56, 0xac, 0x48, 0x28, 0x8d, 0x88, 0x17, 0xb0, 0xd3, 0x3e, 0x1d, 0x25, 0xa6, + 0x78, 0x81, 0x00, 0xaa, 0xd6, 0x9d, 0xf6, 0x35, 0x2b, 0x0e, 0xfd, 0xff, 0x13, 0x57, 0xf9, 0x4a, + 0x86, 0xba, 0xe0, 0x8a, 0x5a, 0x3b, 0x10, 0xf0, 0xd8, 0xf8, 0xc4, 0xc2, 0xe6, 0x3f, 0x03, 0xd8, + 0x96, 0xb5, 0x8e, 0x32, 0x65, 0x0c, 0xe4, 0x76, 0xd9, 0xa9, 0xff, 0x85, 0x05, 0x13, 0xf8, 0xef, + 0xdb, 0x11, 0x04, 0x01, 0x60, 0xd1, 0x04, 0xc5, 0xa2, 0x0b, 0xb1, 0xb5, 0xbd, 0xc9, 0x77, 0xf8, + 0x42, 0xfa, 0xa6, 0xca, 0xac, 0x31, 0x86, 0xd0, 0x36, 0x52, 0xfd, 0x09, 0x68, 0x57, 0xab, 0xfd, + 0x5e, 0x4e, 0xbf, 0xbe, 0xbd, 0x5c, 0x12, 0x5d, 0x9b, 0x9f, 0x1f, 0xc4, 0x82, 0x92, 0x1f, 0x08, + 0x47, 0xdd, 0xcf, 0x83, 0x99, 0x45, 0x17, 0xde, 0x20, 0x94, 0x0e, 0x93, 0xf8, 0x52, 0x9b, 0xb1, + 0xba, 0x65, 0xb1, 0xd5, 0xb9, 0x72, 0x78, 0x59, 0xf3, 0x10, 0xfd, 0x71, 0x30, 0xa4, 0x9b, 0x71, + 0x3c, 0x6c, 0x20, 0xa3, 0x24, 0xe0, 0x9b, 0xcc, 0xbf, 0x79, 0x2c, 0xd5, 0x0c, 0x42, 0xc3, 0x22, + 0x97, 0xfb, 0xad, 0xfe, 0x08, 0xc4, 0x9a, 0x99, 0xf1, 0xa3, 0xf1, 0x22, 0x1d, 0xd3, 0xea, 0x9f, + 0x85, 0x2c, 0x0d, 0x0e, 0x93, 0x9e, 0x79, 0x66, 0x34, 0x31, 0x8f, 0x17, 0x89, 0xc7, 0xf8, 0x14, + 0x65, 0x1c, 0x02, 0x30, 0x50, 0x82, 0x36, 0xa3, 0xb8, 0x55, 0xf2, 0x94, 0x56, 0x80, 0xc4, 0x24, + 0x12, 0xdf, 0x98, 0x8d, 0x29, 0x98, 0x70, 0x60, 0xf8, 0x23, 0xee, 0xec, 0x7c, 0x13, 0x8b, 0x10, + 0xe0, 0xac, 0xa1, 0x80, 0xdb, 0x8a, 0xdd, 0xde, 0xb8, 0x50, 0x8e, 0xdb, 0x69, 0x49, 0xee, 0x95, + 0xab, 0xed, 0xbf, 0xc1, 0x69, 0x43, 0xa8, 0x0a, 0x60, 0xd0, 0x4e, 0xbe, 0x13, 0x88, 0x54, 0x39, + 0x6f, 0xfc, 0x40, 0x90, 0x53, 0x69, 0x64, 0xc9, 0x84, 0x06, 0x2a, 0xc5, 0xfe, 0x27, 0x5c, 0x48, + 0x40, 0xaa, 0x65, 0x62, 0xf2, 0x52, 0x0e, 0xfb, 0x52, 0xea, 0xe8, 0xcf, 0xc4, 0xc1, 0x6e, 0xa9, + 0xcb, 0x89, 0x0a, 0xcb, 0x42, 0xff, 0x85, 0x37, 0x90, 0xde, 0x86, 0x5a, 0x1e, 0x88, 0x0a, 0x4c, + 0xbb, 0xb9, 0xab, 0xcb, 0x3b, 0x83, 0x47, 0x78, 0x91, 0x20, 0xa6, 0xda, 0x5c, 0xc5, 0x1f, 0x1f, + 0x66, 0xac, 0xcf, 0x9f, 0x05, 0x42, 0xab, 0xee, 0x6c, 0x82, 0xc2, 0xbc, 0xae, 0xfc, 0x5f, 0x17, + 0x18, 0xd1, 0x26, 0x68, 0x50, 0xca, 0xde, 0x33, 0xc6, 0x79, 0x06, 0xba, 0x17, 0xdf, 0x58, 0xaf, + 0xad, 0x7c, 0x86, 0xd1, 0x10, 0xc7, 0xc2, 0xd5, 0xed, 0x4b, 0x4b, 0x03, 0x3e, 0xb6, 0xef, 0xff, + 0x04, 0xf4, 0x49, 0x19, 0x5e, 0xa4, 0xa7, 0xdf, 0x05, 0xd2, 0x53, 0x97, 0x07, 0xe5, 0x34, 0x63, + 0x93, 0x1f, 0x89, 0x10, 0x0a, 0x48, 0x59, 0x86, 0x03, 0x38, 0x2e, 0x70, 0x7c, 0x6f, 0xb9, 0x66, + 0xb3, 0x05, 0x99, 0x27, 0x07, 0xb8, 0x98, 0x2c, 0x2d, 0xb2, 0xb1, 0xb2, 0x86, 0x19, 0x66, 0xd2, + 0xb5, 0xcb, 0xe0, 0x9e, 0xa4, 0xc5, 0x92, 0xd1, 0xe0, 0x80, 0x25, 0xfb, 0xfc, 0x15, 0x90, 0xb6, + 0x7a, 0x90, 0x48, 0x98, 0xc0, 0x34, 0xec, 0x7d, 0xca, 0x96, 0x8f, 0xfb, 0xe0, 0xab, 0x77, 0x8a, + 0xde, 0xd2, 0x1a, 0x19, 0x59, 0xa6, 0xe7, 0xc1, 0x71, 0xc5, 0x62, 0x13, 0x13, 0x6b, 0xfa, 0x12, + 0x37, 0xf7, 0xc2, 0x87, 0x1d, 0x7c, 0x56, 0xa2, 0x17, 0xbb, 0x1e, 0x41, 0x7e, 0xd2, 0xf7, 0x7d, + 0xdb, 0xef, 0xc4, 0x89, 0x04, 0x95, 0x9d, 0x43, 0x17, 0x1d, 0xe2, 0x44, 0x82, 0xc2, 0x13, 0xa0, + 0x74, 0x06, 0x85, 0x08, 0xbd, 0x6b, 0xcb, 0x97, 0xe2, 0x04, 0x02, 0xbd, 0xa8, 0x85, 0x4b, 0x3e, + 0x05, 0x1d, 0x00, 0x05, 0xa1, 0xda, 0x2c, 0x0a, 0x74, 0x9f, 0xe0, 0x9f, 0x37, 0x2d, 0x35, 0x26, + 0x10, 0x82, 0xcf, 0xdc, 0x48, 0x85, 0xaf, 0x12, 0x20, 0xf9, 0x7d, 0x2b, 0x5e, 0x23, 0x51, 0x14, + 0x68, 0x38, 0x81, 0x20, 0x9f, 0x3d, 0x34, 0x26, 0xa9, 0x23, 0xbe, 0x20, 0x11, 0x5d, 0xdd, 0xff, + 0xf0, 0x5d, 0x94, 0xc5, 0xee, 0xe3, 0xac, 0xb6, 0xf8, 0x22, 0x10, 0x2f, 0x31, 0x70, 0x09, 0x7c, + 0x27, 0x60, 0x28, 0x72, 0x48, 0x66, 0x1d, 0x63, 0x33, 0x0f, 0xfe, 0x8b, 0x07, 0xd5, 0xa7, 0xe8, + 0xbd, 0x3f, 0x44, 0xa8, 0xbe, 0xad, 0x5c, 0x39, 0x77, 0xd6, 0x6a, 0x2c, 0xff, 0x12, 0x16, 0x86, + 0x30, 0x12, 0x07, 0x25, 0xef, 0x22, 0xf1, 0x72, 0x30, 0x1f, 0xa2, 0x9f, 0xf8, 0x4c, 0xa6, 0x9f, + 0xbb, 0x56, 0x5e, 0x58, 0x61, 0x88, 0x7c, 0x95, 0xcb, 0x3e, 0xab, 0x84, 0x42, 0x82, 0x28, 0x4e, + 0xea, 0xb1, 0xd4, 0xed, 0xc4, 0x31, 0x0e, 0x2a, 0x66, 0x51, 0x6c, 0xf7, 0x9c, 0x8c, 0x17, 0xf7, + 0xe2, 0x03, 0x20, 0xae, 0x78, 0xfc, 0xb7, 0x3d, 0x80, 0xfc, 0x68, 0xf3, 0xe4, 0xea, 0xe0, 0xff, + 0xdd, 0xb7, 0x12, 0x20, 0x13, 0x15, 0x41, 0xb6, 0x9d, 0x03, 0x2f, 0x7e, 0x7d, 0xfe, 0x3e, 0xee, + 0xef, 0x6f, 0x10, 0xb0, 0xdd, 0x48, 0x46, 0x00, 0x00, 0xf1, 0x20, 0xba, 0x2b, 0x40, 0x77, 0x77, + 0xbf, 0x3f, 0xd7, 0xab, 0x12, 0x61, 0x35, 0x63, 0x38, 0x00, 0xe2, 0x20, 0x92, 0x5e, 0x61, 0x53, + 0x81, 0xec, 0x71, 0xfe, 0x24, 0x29, 0x55, 0x66, 0xe0, 0xc7, 0xea, 0xc6, 0x71, 0x5f, 0x7b, 0x4c, + 0x04, 0x4e, 0xc1, 0xaf, 0x26, 0x2b, 0x47, 0x78, 0x9f, 0xc1, 0x59, 0x0d, 0xd2, 0x40, 0xd4, 0xdd, + 0xc9, 0x1a, 0xc6, 0x6d, 0xe2, 0x8e, 0xdf, 0x04, 0x25, 0x64, 0x65, 0xc6, 0x52, 0x34, 0x63, 0xe2, + 0x41, 0x29, 0xe9, 0x4e, 0xa2, 0xe5, 0x53, 0x0d, 0xfe, 0x08, 0xc9, 0x5b, 0x27, 0xac, 0x48, 0x48, + 0xce, 0xf7, 0x17, 0x53, 0x42, 0x7c, 0x11, 0x5a, 0xc6, 0x4c, 0x7f, 0x88, 0x82, 0xa3, 0x92, 0xd2, + 0xb3, 0x90, 0x63, 0x20, 0xdd, 0xc5, 0xc5, 0xd4, 0x5d, 0x86, 0x22, 0x08, 0xad, 0x20, 0x94, 0xdc, + 0x82, 0x02, 0x50, 0x3a, 0xc4, 0x42, 0x84, 0x56, 0x5c, 0xe4, 0x12, 0x0a, 0x4b, 0x0a, 0x08, 0x4c, + 0x30, 0x18, 0x73, 0x48, 0xc8, 0xa0, 0x1e, 0x3f, 0x90, 0xcb, 0x2a, 0xbe, 0x1e, 0x92, 0xa7, 0x2f, + 0x47, 0x90, 0x3c, 0x83, 0x08, 0x78, 0xde, 0x94, 0x29, 0xf8, 0xb4, 0xd2, 0xb1, 0x7e, 0xd3, 0x43, + 0xc6, 0x2c, 0xd1, 0x1b, 0x4a, 0x8f, 0xfc, 0x3b, 0x49, 0xaa, 0x06, 0x73, 0x17, 0xec, 0x70, 0x06, + 0xbc, 0x25, 0xf1, 0xe4, 0x74, 0x99, 0x9a, 0x44, 0xd6, 0xed, 0x37, 0x6d, 0xb9, 0x7a, 0x2c, 0x55, + 0xd5, 0xe1, 0x4e, 0x08, 0x44, 0x6a, 0xba, 0xf1, 0x20, 0x84, 0xf2, 0x80, 0x00, 0x48, 0x7a, 0x2a, + 0xf8, 0x50, 0xa3, 0x01, 0x02, 0x43, 0x89, 0x81, 0x94, 0x40, 0x69, 0xc3, 0xaa, 0x08, 0xc7, 0x94, + 0x68, 0xc0, 0xd6, 0x7a, 0xf8, 0xa3, 0x2a, 0x93, 0x24, 0xca, 0x25, 0x45, 0xf8, 0x60, 0x28, 0x45, + 0x8d, 0x48, 0x1a, 0x25, 0x41, 0x01, 0x6e, 0x4e, 0x23, 0x84, 0xda, 0xbf, 0x96, 0x64, 0x77, 0xfc, + 0x48, 0x50, 0xa7, 0xa0, 0x00, 0x17, 0x2b, 0x2a, 0x87, 0x2a, 0x91, 0x36, 0x35, 0x1e, 0x84, 0x9e, + 0xf5, 0x69, 0x82, 0x75, 0x5b, 0x6e, 0x02, 0xf7, 0xc6, 0x54, 0xdd, 0x75, 0x62, 0x51, 0xe1, 0x01, + 0xd1, 0x2c, 0xfa, 0x43, 0x79, 0xf1, 0x77, 0x77, 0x75, 0x1c, 0x42, 0xcf, 0x84, 0x2d, 0xdf, 0x66, + 0xd7, 0x65, 0xb0, 0x58, 0x18, 0xf3, 0xb7, 0x82, 0xdb, 0xdd, 0x13, 0x6c, 0x1e, 0xbe, 0xfa, 0x3f, + 0xfe, 0x28, 0x8d, 0xf4, 0x9d, 0xdb, 0x30, 0x00, 0x38, 0x98, 0x22, 0x2b, 0xee, 0x3b, 0x1d, 0xf1, + 0x00, 0xb0, 0x8f, 0xcc, 0x4a, 0xa0, 0x3d, 0x26, 0xe8, 0xed, 0x2f, 0x0c, 0x06, 0xfb, 0xf2, 0xfc, + 0x11, 0x9c, 0xe1, 0x86, 0xfc, 0xce, 0x26, 0x0a, 0x7a, 0x21, 0x59, 0xd7, 0xc8, 0xf5, 0x49, 0x44, + 0x38, 0x3b, 0x96, 0x7f, 0x8b, 0xa1, 0xee, 0xd6, 0x5c, 0xe2, 0x46, 0x15, 0xdd, 0x4d, 0x8c, 0x09, + 0x09, 0xe4, 0x65, 0x54, 0x39, 0x30, 0xef, 0xe4, 0xa7, 0x82, 0xe2, 0x68, 0xcb, 0x87, 0x61, 0x0d, + 0x89, 0x24, 0x77, 0xc4, 0x90, 0x61, 0x20, 0xc3, 0xaf, 0x10, 0x14, 0x13, 0x69, 0xbb, 0x98, 0xd1, + 0x88, 0xb5, 0x0e, 0x5f, 0x74, 0xdf, 0x8e, 0xad, 0xe9, 0x57, 0x7c, 0x13, 0x69, 0x90, 0xc6, 0x2c, + 0x83, 0xf1, 0xec, 0xbc, 0x30, 0x88, 0x90, 0x5a, 0x79, 0x69, 0x43, 0x6e, 0x3f, 0x8f, 0x9f, 0x84, + 0x44, 0x82, 0x9a, 0x4e, 0x71, 0x9c, 0x71, 0xab, 0x2d, 0x73, 0x5c, 0x78, 0x89, 0xf2, 0xa7, 0x11, + 0x0a, 0x5b, 0x8f, 0x71, 0xc9, 0x3b, 0x53, 0x55, 0x50, 0x93, 0xab, 0x8e, 0xa1, 0xad, 0x60, 0x00, + 0x13, 0xd3, 0xc1, 0x86, 0x7e, 0x9d, 0x71, 0x20, 0x94, 0x85, 0x83, 0xe4, 0x6b, 0xa0, 0x56, 0xff, + 0xf9, 0x04, 0x3e, 0xed, 0xf8, 0x7e, 0x61, 0x8d, 0x06, 0x7f, 0x31, 0x10, 0x40, 0x11, 0xc5, 0x17, + 0x2c, 0xec, 0x74, 0x2d, 0x1a, 0x30, 0x10, 0x76, 0xe6, 0x46, 0x47, 0xf2, 0xe8, 0x25, 0x48, 0x1b, + 0xff, 0xd1, 0xf5, 0x2f, 0x46, 0x6f, 0xa2, 0xb7, 0xd5, 0xa4, 0xea, 0xd5, 0xd5, 0xa7, 0xea, 0xf3, + 0x70, 0xe9, 0x1c, 0x70, 0x79, 0x18, 0xe5, 0x14, 0xa0, 0xa7, 0xf6, 0x61, 0x75, 0x31, 0x9c, 0x54, + 0x08, 0xca, 0x49, 0x3f, 0xfc, 0xa5, 0x46, 0x4a, 0x25, 0x12, 0xe0, 0x86, 0xaa, 0x3c, 0xb2, 0xfe, + 0x20, 0x29, 0x26, 0x25, 0x78, 0x94, 0xa8, 0xdf, 0x87, 0xbe, 0x33, 0x61, 0xf0, 0xd5, 0x37, 0x19, + 0x45, 0xd6, 0x6c, 0x3c, 0x3e, 0x30, 0xcf, 0x66, 0xb5, 0xe9, 0x9c, 0x61, 0x61, 0x46, 0xeb, 0xc4, + 0x76, 0xb2, 0x4e, 0x34, 0x6a, 0x5b, 0xa0, 0x72, 0xdb, 0x0f, 0x1e, 0x5a, 0x63, 0x80, 0xe0, 0x2d, + 0x63, 0x79, 0xc3, 0xf2, 0xb3, 0x21, 0xef, 0x05, 0x78, 0xcc, 0x7a, 0x3d, 0x8c, 0x14, 0x27, 0x30, + 0x75, 0x73, 0x0e, 0x33, 0xe0, 0xa4, 0xe3, 0xa2, 0x24, 0xd3, 0x77, 0x3a, 0x2f, 0xaf, 0xa1, 0xb3, + 0x1d, 0x93, 0x03, 0x65, 0x20, 0x3e, 0x2f, 0x12, 0x0a, 0xe7, 0x08, 0x03, 0x65, 0xb2, 0xc0, 0xe4, + 0x1b, 0x38, 0xc1, 0xcc, 0xc1, 0xc0, 0x1d, 0xdf, 0x05, 0xb2, 0x94, 0x43, 0x63, 0x19, 0xe5, 0x32, + 0xa0, 0xea, 0x08, 0x23, 0x03, 0x07, 0xff, 0x44, 0x7e, 0x26, 0x42, 0xf1, 0xf5, 0xe2, 0x7e, 0x08, + 0xa2, 0xbe, 0xdf, 0x5a, 0xf8, 0xcb, 0xcf, 0xe8, 0x57, 0x79, 0x79, 0x48, 0x37, 0x5a, 0x1f, 0xab, + 0xf8, 0x94, 0x4e, 0xf8, 0x25, 0xb4, 0x3e, 0xdc, 0x94, 0x4f, 0xc3, 0xe5, 0x0f, 0xff, 0xc1, 0x11, + 0x6c, 0xf0, 0x6d, 0xe9, 0x1f, 0xc4, 0x82, 0xb8, 0xd1, 0x0b, 0x90, 0xac, 0xc8, 0x38, 0xe3, 0x67, + 0x7a, 0x40, 0xd3, 0x27, 0x90, 0xbe, 0x17, 0xe1, 0xc7, 0x7f, 0x10, 0x20, 0x14, 0xda, 0x08, 0x02, + 0xe9, 0x12, 0x05, 0xa1, 0x69, 0xea, 0xc4, 0xbb, 0xfc, 0x28, 0x59, 0x1e, 0x53, 0x1a, 0x06, 0xf4, + 0x13, 0x22, 0x20, 0x6d, 0x21, 0xa5, 0x44, 0x8e, 0x32, 0x21, 0x85, 0x1d, 0x36, 0x35, 0xc2, 0xaf, + 0x88, 0x82, 0x1f, 0x3a, 0x87, 0xf8, 0x50, 0x8e, 0x53, 0x13, 0xa4, 0xd4, 0x94, 0x91, 0x82, 0xb0, + 0xd9, 0xf2, 0x9a, 0x76, 0x93, 0xe5, 0x58, 0x90, 0x58, 0x29, 0xee, 0x36, 0xae, 0xf9, 0xf0, 0xb7, + 0xeb, 0xe8, 0xa7, 0x05, 0xf2, 0x95, 0x6f, 0x15, 0xd5, 0xe3, 0x38, 0x70, 0x44, 0x6e, 0x83, 0xb8, + 0x7f, 0x5a, 0xba, 0xff, 0x86, 0x4e, 0xf0, 0xf6, 0x67, 0xaf, 0xd5, 0xef, 0xe0, 0x8a, 0x96, 0xdf, + 0x7c, 0x11, 0x59, 0x4a, 0xc7, 0x3f, 0xd5, 0xfe, 0xaf, 0xe2, 0x02, 0x82, 0x09, 0xda, 0x12, 0x37, + 0x15, 0xe3, 0xf5, 0x11, 0x65, 0x99, 0xe6, 0xec, 0xb5, 0x87, 0x72, 0xfe, 0x24, 0x14, 0x89, 0x67, + 0x7f, 0xb1, 0x23, 0x97, 0x8d, 0x39, 0xb9, 0xc6, 0x18, 0xfb, 0xc4, 0x84, 0xa6, 0x00, 0x00, 0xe4, + 0x82, 0x24, 0x01, 0x9f, 0x91, 0x47, 0x82, 0x7b, 0x49, 0xa7, 0xdd, 0xae, 0xf8, 0x28, 0xad, 0x73, + 0xc1, 0x2c, 0x77, 0xf1, 0x30, 0x4b, 0x8f, 0x23, 0x28, 0x64, 0x96, 0xb8, 0xed, 0xc4, 0x41, 0x59, + 0x4f, 0x81, 0xde, 0x0b, 0x7c, 0x78, 0x20, 0x87, 0x08, 0x37, 0x0c, 0x19, 0x51, 0x9f, 0xaa, 0x7f, + 0xaf, 0xfe, 0xaf, 0xe2, 0x57, 0x23, 0xbe, 0x11, 0x04, 0xdc, 0x68, 0x21, 0x5d, 0x79, 0x58, 0xb9, + 0x9b, 0xc4, 0x96, 0x5d, 0xda, 0xf4, 0x6e, 0xf1, 0x08, 0xbb, 0xfc, 0x13, 0xcb, 0xbb, 0x04, 0x64, + 0x30, 0x06, 0xf6, 0xf1, 0x21, 0x4a, 0xc6, 0x88, 0xcc, 0x3f, 0x7b, 0xdf, 0x49, 0xfc, 0x78, 0x91, + 0x7a, 0x65, 0xd8, 0xe9, 0x18, 0xfd, 0x0b, 0x12, 0x24, 0x22, 0x27, 0xbb, 0xa6, 0x1e, 0x48, 0x5b, + 0xbe, 0xf1, 0x90, 0x42, 0x20, 0x24, 0xc7, 0xff, 0x04, 0x66, 0xb3, 0xd1, 0xb9, 0x95, 0x3e, 0x09, + 0x8a, 0x5f, 0x4c, 0xea, 0xee, 0x65, 0x75, 0x8e, 0x7d, 0x12, 0xbe, 0x11, 0xf2, 0x56, 0x77, 0x59, + 0xb2, 0x81, 0x2f, 0xc2, 0x62, 0x8f, 0xa4, 0x96, 0x6e, 0xd2, 0x0d, 0x26, 0x03, 0xf0, 0xd1, 0x58, + 0x83, 0x69, 0x6e, 0x26, 0x10, 0xed, 0x28, 0xc1, 0x43, 0x23, 0xaf, 0x37, 0x71, 0x7d, 0x5a, 0xba, + 0xb4, 0xdd, 0x5a, 0xba, 0x2b, 0xde, 0x24, 0x28, 0x28, 0xea, 0x10, 0x65, 0x21, 0x2f, 0x45, 0xac, + 0x3c, 0x71, 0x91, 0xc3, 0xe6, 0xc8, 0x82, 0x62, 0x71, 0xf7, 0x77, 0xa7, 0xf1, 0x20, 0xa4, 0x48, + 0xa3, 0x6c, 0x28, 0xe9, 0xc2, 0xcb, 0xd3, 0x01, 0x92, 0xa3, 0x07, 0x27, 0x50, 0x6f, 0xf0, 0x5a, + 0x51, 0x83, 0x87, 0x40, 0x6c, 0x13, 0xba, 0x12, 0x59, 0x7c, 0x27, 0x18, 0x8c, 0x97, 0x18, 0xc0, + 0x85, 0x40, 0xc5, 0x40, 0xd8, 0x6c, 0x0f, 0xc6, 0x6d, 0x29, 0xa9, 0x17, 0xe2, 0xe6, 0xa5, 0x1e, + 0x7e, 0x33, 0x65, 0x71, 0x42, 0x2d, 0xc2, 0xea, 0xdc, 0x6d, 0xfc, 0x20, 0x0a, 0xba, 0xd8, 0xea, + 0xd4, 0xde, 0x4f, 0xef, 0x10, 0x0b, 0x84, 0xb6, 0x84, 0xeb, 0xe3, 0x9d, 0x37, 0x7e, 0x26, 0x0a, + 0xca, 0xe2, 0xb1, 0x99, 0x0b, 0x70, 0x72, 0x51, 0x23, 0xab, 0x4e, 0x32, 0x99, 0xf9, 0xe2, 0x41, + 0x35, 0x73, 0x04, 0x03, 0x92, 0x11, 0xd8, 0xef, 0xc1, 0x11, 0xb2, 0xb1, 0x7e, 0x26, 0x0a, 0xca, + 0xcb, 0xba, 0x14, 0xec, 0x59, 0x2b, 0x1f, 0x5c, 0x4c, 0x16, 0xdc, 0xe0, 0x00, 0x11, 0x0b, 0x05, + 0xb9, 0x48, 0x32, 0x06, 0x05, 0xf8, 0x98, 0x25, 0x95, 0x22, 0x37, 0x86, 0x02, 0xda, 0x20, 0xec, + 0x71, 0x44, 0x04, 0xab, 0xf8, 0x23, 0x8e, 0x0c, 0x3a, 0x37, 0x10, 0xb3, 0x95, 0x0e, 0xfc, 0x12, + 0x93, 0x4d, 0xb7, 0xbb, 0xf7, 0x88, 0x04, 0xfa, 0x56, 0xaa, 0x2e, 0xaf, 0xf1, 0xc6, 0x74, 0xb0, + 0xaa, 0xc9, 0x5b, 0x39, 0x95, 0x51, 0x3c, 0x2f, 0xe2, 0x02, 0x82, 0xe8, 0x8c, 0x41, 0x99, 0xc6, + 0x9e, 0xc5, 0x65, 0x6e, 0xe4, 0x24, 0xa6, 0x09, 0xab, 0xb1, 0x5e, 0xef, 0x82, 0xc8, 0xf8, 0x40, + 0x5b, 0x86, 0x08, 0xcf, 0xac, 0x98, 0x22, 0xa1, 0xe0, 0x14, 0x6d, 0xec, 0xe3, 0xfd, 0x61, 0xbc, + 0x40, 0x25, 0xb0, 0x19, 0x43, 0x01, 0xb1, 0xc0, 0xc6, 0x2d, 0xf9, 0xc7, 0x10, 0x09, 0xb1, 0xb6, + 0xdc, 0x19, 0x87, 0x2a, 0x90, 0x96, 0xe8, 0x15, 0xe3, 0x8e, 0xbe, 0x4b, 0x2d, 0x1a, 0xf1, 0x20, + 0x96, 0x1f, 0x5e, 0x42, 0xa3, 0x95, 0x57, 0x6a, 0xd4, 0xb1, 0xa6, 0x7b, 0xc4, 0x82, 0x3e, 0xa8, + 0x7a, 0x2b, 0xf1, 0x3c, 0x48, 0x44, 0x12, 0x65, 0x56, 0xcb, 0xef, 0x8b, 0x32, 0xaa, 0xaa, 0x11, + 0x76, 0x64, 0x9e, 0x62, 0x20, 0x33, 0x28, 0x7f, 0xd1, 0xce, 0x08, 0x9e, 0xaf, 0xf5, 0x68, 0xce, + 0x08, 0x06, 0x26, 0x16, 0x13, 0x05, 0xea, 0xcc, 0xe3, 0x2a, 0x32, 0xa5, 0xb4, 0x6f, 0x7f, 0x18, + 0x83, 0x1e, 0x3d, 0x93, 0x87, 0x7f, 0xbf, 0x88, 0x05, 0xa5, 0x99, 0x4d, 0x91, 0x86, 0x0a, 0xaa, + 0xbf, 0xc1, 0x48, 0x98, 0xb2, 0x49, 0xb3, 0x6c, 0x2d, 0x64, 0x9e, 0x51, 0xde, 0x26, 0x14, 0xf9, + 0xd8, 0x90, 0xca, 0x7d, 0xe5, 0x31, 0x9c, 0xa2, 0x0d, 0xcc, 0x3f, 0xd1, 0x7b, 0xe1, 0x4a, 0xb7, + 0xf2, 0xd9, 0x01, 0x00, 0x5b, 0x8f, 0x61, 0x6d, 0x0a, 0xc4, 0x74, 0x02, 0x88, 0x76, 0xf8, 0x25, + 0x32, 0xf2, 0x62, 0xeb, 0xbf, 0xc2, 0x05, 0x43, 0x33, 0x19, 0x30, 0x56, 0x80, 0x8f, 0x51, 0xae, + 0x9c, 0x99, 0x89, 0x82, 0xa1, 0x0a, 0xaa, 0xac, 0x61, 0x5c, 0x92, 0x63, 0x14, 0xcf, 0x71, 0x11, + 0x62, 0x74, 0x9d, 0xc5, 0x67, 0xc1, 0x5d, 0xf1, 0x00, 0xb6, 0xd3, 0x68, 0xbb, 0x4e, 0x81, 0xa1, + 0x8e, 0xdc, 0x40, 0x80, 0xa7, 0x9c, 0x10, 0x05, 0xce, 0xa9, 0x1c, 0x1c, 0xc9, 0x39, 0x93, 0x0d, + 0x22, 0x0a, 0xaa, 0x33, 0xaf, 0x2e, 0x20, 0x40, 0x26, 0xa0, 0x32, 0x88, 0x0b, 0xd7, 0x9b, 0x2e, + 0xe2, 0x04, 0x2b, 0x78, 0x80, 0x57, 0x1f, 0xa6, 0xd5, 0x0e, 0x3f, 0x73, 0x80, 0xab, 0x63, 0x30, + 0xdb, 0xf1, 0x02, 0x1c, 0xcc, 0x08, 0xe2, 0xcf, 0x85, 0x09, 0x41, 0xbb, 0x6d, 0xa1, 0xb6, 0xec, + 0xae, 0xf4, 0xce, 0xae, 0x3e, 0xf1, 0x00, 0x8c, 0xa2, 0xeb, 0x56, 0xf1, 0x02, 0x8d, 0x96, 0x05, + 0xa3, 0xdf, 0xe8, 0xb5, 0xf0, 0x53, 0xcb, 0x42, 0xd2, 0x1a, 0x3b, 0xbc, 0x0d, 0xd8, 0x7d, 0xf5, + 0x6f, 0xa2, 0xbf, 0xc1, 0x6d, 0x0f, 0x51, 0x5b, 0xb8, 0xad, 0xbe, 0x32, 0xf9, 0x51, 0x36, 0x35, + 0x33, 0x07, 0xd0, 0xcb, 0x50, 0x8d, 0xef, 0xa7, 0x6d, 0x1b, 0xca, 0xe9, 0x7c, 0x29, 0x44, 0xaa, + 0xa7, 0xfc, 0xd7, 0x35, 0x13, 0xa0, 0xd7, 0x20, 0x42, 0x2f, 0xe7, 0x88, 0x17, 0x62, 0x46, 0x42, + 0x2e, 0x0c, 0x3a, 0xb2, 0xe2, 0x01, 0x44, 0x79, 0x13, 0xcb, 0xb5, 0x29, 0x78, 0xf0, 0xf1, 0x0b, + 0x07, 0xd7, 0xbe, 0xad, 0x5c, 0xa2, 0x87, 0x70, 0xd4, 0x18, 0x4a, 0xf5, 0x4f, 0x47, 0xf9, 0x5d, + 0x5d, 0x13, 0xd7, 0x51, 0x1d, 0x7b, 0xc4, 0x82, 0xc1, 0x4c, 0x21, 0x34, 0x91, 0x3f, 0x61, 0x4d, + 0xc4, 0x41, 0x00, 0x4f, 0x0c, 0x09, 0x82, 0xf8, 0x86, 0x55, 0x25, 0xdf, 0x12, 0x5b, 0x73, 0x98, + 0x3f, 0x36, 0x26, 0x67, 0xc4, 0x82, 0xc9, 0xd4, 0x27, 0x75, 0x5a, 0xb1, 0xb9, 0x98, 0xbf, 0xf8, + 0x90, 0x89, 0x5c, 0xb8, 0x44, 0x37, 0x6c, 0xff, 0xc6, 0xe4, 0x77, 0x98, 0xe2, 0x44, 0x8c, 0xa7, + 0x00, 0x60, 0xeb, 0x50, 0xd1, 0x85, 0xdd, 0xeb, 0x93, 0x67, 0x2a, 0x31, 0x94, 0x0a, 0xef, 0xa0, + 0x02, 0x70, 0xab, 0xb4, 0x19, 0xec, 0xb1, 0x30, 0xa1, 0x46, 0x16, 0x4e, 0xfd, 0x06, 0x85, 0x0c, + 0x32, 0x06, 0xaa, 0x93, 0x38, 0xb4, 0xed, 0x9d, 0xad, 0xc3, 0xf2, 0xca, 0x07, 0xf1, 0x21, 0x1c, + 0x79, 0xd1, 0x9a, 0x09, 0x86, 0x59, 0x50, 0x1a, 0xb0, 0x68, 0xbe, 0x88, 0x3b, 0xfc, 0x48, 0x2c, + 0xe4, 0xeb, 0x33, 0x08, 0x73, 0x5d, 0x6f, 0xe2, 0x41, 0x17, 0x6d, 0xa1, 0xdf, 0xc4, 0xc1, 0x29, + 0x15, 0x6b, 0x55, 0xff, 0xe0, 0xbb, 0x4e, 0xee, 0xed, 0xdf, 0xe3, 0x2d, 0xea, 0x86, 0x3d, 0x8e, + 0x26, 0x66, 0xcf, 0xb7, 0x37, 0xc4, 0xc7, 0x1d, 0x9b, 0x4f, 0x43, 0x4d, 0x0c, 0xbf, 0x92, 0x3e, + 0xaf, 0xc4, 0x41, 0x35, 0x33, 0xc3, 0xad, 0xb7, 0xfa, 0xbf, 0x89, 0x56, 0x78, 0x90, 0x44, 0x47, + 0xcc, 0x93, 0xbe, 0x2e, 0xab, 0xd4, 0x70, 0xe1, 0xf8, 0xc3, 0xa4, 0xb6, 0x9c, 0x73, 0xd4, 0xcd, + 0x13, 0xb1, 0x72, 0x3e, 0xb7, 0xf6, 0xa9, 0xf0, 0x53, 0xa9, 0xf7, 0x41, 0x0c, 0x88, 0x12, 0x59, + 0xcd, 0x50, 0x7b, 0x8e, 0xde, 0x25, 0x5f, 0xe0, 0x9c, 0xa8, 0x9d, 0x9a, 0xb7, 0x4d, 0x03, 0x22, + 0xfe, 0x14, 0x9f, 0x3e, 0x77, 0x21, 0xa1, 0xa6, 0x4c, 0x0c, 0x55, 0xa6, 0x7c, 0xdd, 0x3f, 0xcb, + 0x31, 0x7d, 0xfc, 0x12, 0xd4, 0x5c, 0xd4, 0x3a, 0xc6, 0x56, 0x37, 0x3e, 0xb1, 0xfe, 0x4c, 0x66, + 0x3d, 0x81, 0xfe, 0x22, 0x5b, 0x77, 0x15, 0xb5, 0x3b, 0x8f, 0x0f, 0x04, 0x64, 0xa9, 0xc6, 0x1c, + 0x89, 0xf0, 0x46, 0x5d, 0x11, 0xeb, 0x5f, 0x05, 0xb5, 0xad, 0x77, 0x29, 0xcf, 0x8f, 0x1c, 0x39, + 0x4b, 0x8c, 0xa9, 0xeb, 0x89, 0x60, 0xe1, 0xda, 0xd9, 0x32, 0x64, 0x5e, 0x8c, 0x56, 0xbd, 0x1d, + 0xe1, 0x3e, 0x6d, 0xe5, 0x87, 0x12, 0x0a, 0x8c, 0xa3, 0x9a, 0x0a, 0x9b, 0x90, 0x1a, 0xf5, 0x6e, + 0x3a, 0x5d, 0xbd, 0xdd, 0x0f, 0x0f, 0x10, 0x0a, 0xfa, 0xaa, 0xaa, 0xd5, 0x55, 0x55, 0xfe, 0xaf, + 0xe2, 0x10, 0x96, 0xe2, 0x28, 0xcd, 0xf2, 0xf3, 0x47, 0xe0, 0x84, 0x6b, 0x8a, 0xdc, 0x56, 0x91, + 0x71, 0x3e, 0x20, 0x14, 0x1b, 0x4c, 0xec, 0x6d, 0x26, 0xff, 0x35, 0xdd, 0xf8, 0x88, 0x22, 0xdd, + 0xdd, 0xbc, 0x48, 0x27, 0xcf, 0x8d, 0xcd, 0x6b, 0xff, 0x82, 0x8d, 0xe7, 0xc4, 0xb7, 0x6f, 0x85, + 0x08, 0x9d, 0x18, 0xe3, 0x65, 0x6d, 0xcd, 0xeb, 0x93, 0x0b, 0xa9, 0xb9, 0x8a, 0xd0, 0xeb, 0xbf, + 0x11, 0x45, 0x7f, 0x8c, 0xaa, 0x93, 0x34, 0x97, 0xdd, 0xd5, 0x17, 0xe8, 0x95, 0xc4, 0x88, 0x5f, + 0xfd, 0x89, 0xdd, 0xfc, 0x10, 0xdd, 0xdf, 0xdf, 0x15, 0x6f, 0xbd, 0xde, 0xb8, 0x23, 0xd1, 0x5f, + 0xea, 0xe2, 0xea, 0xd2, 0x03, 0x4e, 0x99, 0x5f, 0x3e, 0x4b, 0x09, 0x2b, 0xf8, 0x21, 0xb4, 0xf6, + 0xe7, 0x3e, 0xa9, 0x7c, 0x4a, 0xe1, 0xf0, 0x50, 0x49, 0xe1, 0x2f, 0xa0, 0x29, 0xbb, 0x57, 0x45, + 0x8a, 0xf8, 0x91, 0x80, 0xaa, 0xee, 0x33, 0x96, 0x18, 0x18, 0x52, 0x39, 0x72, 0xf2, 0xb1, 0xe8, + 0x4c, 0x65, 0x73, 0x1e, 0xee, 0xe4, 0xe8, 0xd5, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x26, + 0x13, 0x30, 0x32, 0x80, 0xd1, 0xc5, 0x8f, 0xda, 0x6b, 0x69, 0xa1, 0x7d, 0x90, 0x9c, 0xbd, 0x36, + 0xf5, 0xcc, 0x45, 0x75, 0x70, 0x23, 0xc4, 0x06, 0x06, 0x88, 0xa1, 0x81, 0x88, 0xd3, 0x8a, 0x86, + 0xe1, 0xe2, 0xe1, 0x16, 0x24, 0x37, 0x8d, 0x42, 0x3a, 0x05, 0x77, 0x54, 0x0e, 0xf9, 0xef, 0x0a, + 0x03, 0x1f, 0xaa, 0x42, 0x1e, 0x32, 0xf4, 0x0d, 0x6a, 0xd8, 0x00, 0x11, 0x31, 0x2c, 0x8f, 0x86, + 0xbe, 0x33, 0xcf, 0x4d, 0x91, 0xac, 0x56, 0x7e, 0x6e, 0x5f, 0x1e, 0x20, 0x30, 0x10, 0xed, 0xc8, + 0xb0, 0x8e, 0x45, 0x14, 0xb2, 0x2a, 0xf6, 0x43, 0x18, 0xc1, 0x03, 0x3f, 0xad, 0x83, 0x5c, 0x48, + 0xd9, 0x46, 0xe4, 0x6d, 0x17, 0x46, 0xc3, 0x4a, 0x90, 0x30, 0x08, 0x01, 0x4c, 0x8b, 0xc8, 0xf6, + 0xe8, 0xd0, 0x99, 0x1a, 0x15, 0x16, 0x97, 0x57, 0x44, 0x33, 0xc8, 0x00, 0xd1, 0xb3, 0x32, 0xa7, + 0xf9, 0x25, 0x06, 0x5c, 0x6a, 0xe8, 0x0e, 0xb3, 0x34, 0x7f, 0xc4, 0x85, 0x08, 0x3f, 0xe6, 0x24, + 0x36, 0x4a, 0xb2, 0x7d, 0x83, 0x20, 0x96, 0x9a, 0x50, 0x01, 0xd6, 0x7e, 0x2b, 0xf1, 0x46, 0x70, + 0xf3, 0xb0, 0x7a, 0xc0, 0xeb, 0xfd, 0x2f, 0x43, 0x6e, 0x41, 0x07, 0x47, 0x22, 0x42, 0x1c, 0x28, + 0x12, 0x6c, 0xb3, 0x83, 0xa5, 0xd7, 0x11, 0xc4, 0x90, 0x88, 0x0a, 0xcb, 0xb0, 0x76, 0xee, 0xef, + 0x39, 0x79, 0x1a, 0x9b, 0xe3, 0x36, 0x28, 0xce, 0x70, 0xb1, 0xdd, 0xb9, 0x7c, 0x51, 0xa6, 0x2b, + 0x14, 0x75, 0x89, 0x1e, 0x7b, 0xf1, 0x02, 0x10, 0x9e, 0x9b, 0x94, 0xe9, 0x4b, 0x85, 0xcc, 0x30, + 0x20, 0x10, 0x0a, 0x77, 0x77, 0xda, 0x6b, 0x80, 0x2b, 0x8d, 0xf1, 0x01, 0xb2, 0xa7, 0x2d, 0x34, + 0xd3, 0x5f, 0x88, 0x08, 0x02, 0xb2, 0x3d, 0xe7, 0xdb, 0x7d, 0xc8, 0x00, 0x2e, 0xd2, 0x53, 0x01, + 0x23, 0x24, 0x0a, 0xb9, 0x2c, 0x5c, 0x48, 0x80, 0x46, 0x26, 0xd0, 0x04, 0xcd, 0x4c, 0x30, 0xc1, + 0xaf, 0xe8, 0x63, 0xa1, 0x71, 0x57, 0x52, 0x5f, 0x58, 0x63, 0xd5, 0x22, 0x15, 0xd5, 0x32, 0xf5, + 0x4c, 0x97, 0x58, 0xbe, 0x08, 0xbc, 0x6a, 0x91, 0x78, 0x60, 0x60, 0x49, 0xd6, 0x52, 0xd6, 0x56, + 0x58, 0x0d, 0x4c, 0x19, 0xe3, 0x8c, 0x0d, 0x39, 0x77, 0x2f, 0x2c, 0x69, 0x15, 0xb3, 0xdc, 0x3c, + 0x7f, 0x12, 0x36, 0x2b, 0x34, 0xc1, 0xd7, 0xca, 0xfa, 0x06, 0xb3, 0x19, 0xcd, 0xef, 0xa4, 0x0b, + 0x4f, 0x9e, 0x79, 0x20, 0x29, 0x83, 0xc7, 0xb9, 0xef, 0xb6, 0xf9, 0xa1, 0x5f, 0x10, 0xe4, 0xe9, + 0xcc, 0xa7, 0xd0, 0x4c, 0xa9, 0x7c, 0xc2, 0x06, 0x10, 0x44, 0xc0, 0xc4, 0x60, 0xb0, 0x2e, 0xe2, + 0x3e, 0x86, 0x38, 0xf0, 0xa1, 0x48, 0x18, 0x0c, 0x01, 0x08, 0xb0, 0xb0, 0x20, 0x5f, 0x6d, 0xc5, + 0x39, 0x1b, 0x25, 0x55, 0xe1, 0x02, 0xae, 0xf7, 0x0b, 0x5e, 0x20, 0x69, 0x48, 0xa5, 0xec, 0x1e, + 0x0e, 0xc5, 0xc4, 0xc7, 0xce, 0x04, 0x01, 0x26, 0x97, 0x2a, 0x02, 0x25, 0x6b, 0xe6, 0x35, 0x6b, + 0x7f, 0xad, 0x03, 0x3b, 0xea, 0x11, 0xd0, 0x99, 0x7e, 0x4d, 0x4f, 0x88, 0x18, 0x21, 0xee, 0x17, + 0xeb, 0x93, 0x4f, 0xe5, 0x7b, 0x44, 0x3c, 0xb7, 0xc3, 0x03, 0x8f, 0x8f, 0x19, 0x6e, 0xee, 0xe6, + 0x80, 0xa6, 0xcc, 0x02, 0x21, 0xf7, 0xdd, 0x4c, 0x7d, 0x4f, 0x6a, 0x06, 0x7a, 0x17, 0x84, 0x9d, + 0x19, 0x87, 0xaf, 0x4f, 0xd0, 0x94, 0xab, 0xd5, 0x32, 0xf5, 0xef, 0xaf, 0x7c, 0x12, 0x45, 0xc5, + 0xc5, 0xc5, 0xcc, 0xa3, 0x88, 0x10, 0x14, 0x08, 0x08, 0x7d, 0x75, 0x38, 0x38, 0x49, 0x40, 0x5f, + 0xc5, 0xcf, 0xf1, 0x7c, 0x80, 0x81, 0x19, 0x8d, 0x7e, 0x16, 0xc9, 0x49, 0xa6, 0x14, 0xe1, 0x62, + 0x0f, 0x1b, 0x07, 0x50, 0x1f, 0x8e, 0x8b, 0xe3, 0x77, 0x36, 0xbf, 0xe2, 0x62, 0xb9, 0xfc, 0x1d, + 0xf9, 0xa2, 0xda, 0x9a, 0x13, 0x10, 0x08, 0x6e, 0xc7, 0x2b, 0x0f, 0xf0, 0x56, 0x53, 0xf2, 0xf2, + 0xfb, 0x51, 0x7d, 0x33, 0xa9, 0xef, 0xf0, 0x44, 0x34, 0x45, 0x40, 0xb8, 0x89, 0x04, 0xbc, 0xb1, + 0xaa, 0xc4, 0x88, 0x31, 0xb6, 0x9d, 0x70, 0x88, 0xc6, 0xcb, 0x28, 0xa6, 0xf7, 0x15, 0xee, 0xfe, + 0x09, 0x45, 0x88, 0xcf, 0xf0, 0x16, 0x9e, 0x77, 0x14, 0x2c, 0x1a, 0x88, 0xc7, 0x28, 0xf6, 0x8e, + 0x5b, 0x71, 0xcd, 0x2f, 0x42, 0xde, 0x10, 0xea, 0x9d, 0xbe, 0x84, 0x3f, 0xd1, 0x5e, 0x4e, 0x8e, + 0x5e, 0x49, 0xd1, 0x1c, 0x89, 0xe0, 0xa8, 0x60, 0x18, 0xa0, 0x31, 0x95, 0x4d, 0x5e, 0xd3, 0xd8, + 0x16, 0xcb, 0x65, 0xb3, 0xf7, 0xba, 0x0f, 0xc7, 0x86, 0x46, 0x11, 0xea, 0x8e, 0x00, 0x58, 0x61, + 0x09, 0xc0, 0xb0, 0x90, 0xc9, 0xe7, 0xd2, 0x03, 0xe0, 0xf3, 0x0e, 0x85, 0xb2, 0x0c, 0x65, 0xe8, + 0xf3, 0xc5, 0x37, 0xc2, 0x18, 0x09, 0xe1, 0x20, 0xf1, 0x20, 0xae, 0xf6, 0x09, 0xd1, 0x82, 0x1e, + 0x14, 0x1f, 0x7a, 0x84, 0xca, 0x50, 0x48, 0x8a, 0x69, 0x64, 0x05, 0x47, 0x41, 0x65, 0x47, 0x6f, + 0x82, 0x10, 0x9c, 0xec, 0x3f, 0xff, 0xa9, 0x5f, 0xf0, 0x4e, 0x30, 0xdc, 0x73, 0x3b, 0x60, 0xa7, + 0x0a, 0x82, 0xd0, 0xe1, 0xfe, 0xf8, 0x23, 0x10, 0x66, 0x13, 0x94, 0xd1, 0xdf, 0x85, 0x07, 0xa8, + 0x99, 0x8a, 0x97, 0xb3, 0x7d, 0xb9, 0x03, 0xb7, 0x60, 0x65, 0x0c, 0x07, 0xff, 0xc1, 0x46, 0xe5, + 0x65, 0xa0, 0x87, 0x87, 0x1c, 0xa7, 0x38, 0x98, 0x28, 0x19, 0xe1, 0x2b, 0x5c, 0x14, 0xc9, 0x08, + 0x67, 0x0a, 0x3b, 0x41, 0xc7, 0x66, 0xc0, 0x47, 0x39, 0xc4, 0xc1, 0x4e, 0x14, 0x88, 0x80, 0x6a, + 0x90, 0x89, 0x8e, 0x43, 0x12, 0x2a, 0xc2, 0x1a, 0xc2, 0x6a, 0x39, 0x03, 0x25, 0x29, 0x1a, 0x16, + 0xda, 0x5b, 0x43, 0xe8, 0xef, 0xc1, 0x50, 0xd7, 0x42, 0xf8, 0xaf, 0x18, 0x96, 0xc5, 0xc4, 0x61, + 0x30, 0xb4, 0x43, 0xfd, 0xca, 0x41, 0x15, 0x96, 0xef, 0xe1, 0x14, 0x24, 0x89, 0x7d, 0x12, 0xab, + 0xa3, 0x41, 0xf0, 0x45, 0x55, 0x77, 0x97, 0xca, 0x27, 0x3d, 0x0f, 0x47, 0xc2, 0x33, 0xd0, 0xf4, + 0xcf, 0x43, 0xd3, 0x3d, 0x0f, 0x4f, 0xc4, 0xf3, 0xd0, 0xf4, 0xe7, 0xa1, 0xe9, 0xe1, 0x19, 0xe8, + 0x7a, 0x67, 0xa1, 0xe9, 0x9e, 0x87, 0xa6, 0x23, 0xa3, 0x62, 0x1e, 0x8e, 0xe5, 0xf5, 0x6b, 0xea, + 0xe0, 0xbd, 0x19, 0x92, 0xf4, 0x24, 0xa9, 0x7d, 0x47, 0x6f, 0x82, 0x71, 0x1a, 0x11, 0xbc, 0x71, + 0x30, 0x6e, 0x6c, 0x73, 0x82, 0x91, 0xe2, 0x01, 0x80, 0x8b, 0xbb, 0xd0, 0x27, 0x3f, 0x52, 0xc2, + 0x58, 0x22, 0xfe, 0x20, 0x28, 0x40, 0x9c, 0x26, 0x78, 0x58, 0x0f, 0xe5, 0x42, 0xf4, 0x17, 0x01, + 0x55, 0x87, 0x07, 0x91, 0x76, 0x07, 0xe5, 0x09, 0x0a, 0xf5, 0x87, 0x42, 0x5a, 0x32, 0x0b, 0xd0, + 0x3a, 0x2f, 0x42, 0x80, 0x3d, 0x4f, 0x03, 0x8a, 0x93, 0x08, 0x00, 0xad, 0x4b, 0xe4, 0x3f, 0xc6, + 0x0b, 0x6e, 0x24, 0x22, 0x14, 0xd9, 0x78, 0x7b, 0x30, 0x94, 0x2c, 0x19, 0x15, 0xb1, 0x94, 0xe5, + 0x7e, 0x58, 0xfa, 0xdf, 0x1e, 0x3b, 0x72, 0x75, 0x26, 0xe1, 0xcd, 0x7f, 0x82, 0x40, 0x9b, 0xbe, + 0x90, 0x3d, 0x4a, 0x8a, 0xbc, 0x16, 0x05, 0x9c, 0xe4, 0xc4, 0x56, 0x5b, 0xc6, 0x81, 0x89, 0x00, + 0xcb, 0x0a, 0xc5, 0x6c, 0x9a, 0xf5, 0x87, 0xe2, 0x41, 0x28, 0xb6, 0xfb, 0x83, 0x89, 0x7a, 0x68, + 0x6f, 0xff, 0xd4, 0x40, 0x90, 0x88, 0x83, 0x14, 0x88, 0xa2, 0x01, 0x43, 0x64, 0x56, 0x59, 0x32, + 0x4a, 0x1c, 0x69, 0x0d, 0x7f, 0xbf, 0x77, 0xe1, 0x01, 0x2c, 0x26, 0x18, 0xb6, 0xc0, 0x07, 0xb9, + 0x4e, 0x5f, 0x38, 0x8f, 0x12, 0xa4, 0x4f, 0xaf, 0x7d, 0x1a, 0xbe, 0xbd, 0xf5, 0xc2, 0xba, 0x3b, + 0xa3, 0xfa, 0x3b, 0x17, 0xd1, 0x1c, 0x89, 0xe8, 0x93, 0x3e, 0x8e, 0x74, 0xbe, 0xa7, 0x49, 0x3a, + 0x25, 0x7d, 0x4b, 0x7c, 0x2e, 0x29, 0x45, 0xd4, 0x7c, 0x99, 0x08, 0x9f, 0x0a, 0x96, 0x15, 0x46, + 0x03, 0x05, 0x16, 0x60, 0x4d, 0xc6, 0x89, 0x75, 0x75, 0x75, 0xaa, 0x78, 0x98, 0xd2, 0x5a, 0x00, + 0x56, 0x53, 0x99, 0x57, 0x8f, 0x80, 0xb0, 0xed, 0xa3, 0xe3, 0x8f, 0x83, 0x05, 0xaa, 0x58, 0x34, + 0x20, 0x02, 0xc9, 0x74, 0x72, 0x49, 0x58, 0xfb, 0x5a, 0x77, 0xbd, 0x41, 0x61, 0x5c, 0xaf, 0xc1, + 0x11, 0xd1, 0x71, 0x3b, 0xac, 0x94, 0xf8, 0x50, 0xc1, 0xcb, 0x94, 0x1e, 0xa2, 0xe2, 0xc6, 0xfe, + 0xc9, 0x5d, 0x18, 0xbc, 0x93, 0x32, 0xc1, 0x92, 0x8e, 0x0f, 0x71, 0x7e, 0x6c, 0x29, 0x49, 0xcf, + 0x93, 0x4c, 0xb8, 0xdf, 0x88, 0x87, 0xcb, 0x37, 0x5d, 0xc6, 0x21, 0x5f, 0x87, 0x5f, 0x17, 0x0e, + 0xca, 0x1b, 0x6a, 0x59, 0x6b, 0x52, 0xc2, 0x98, 0x30, 0xf7, 0x2f, 0xe5, 0xd6, 0xf1, 0x30, 0x41, + 0x89, 0xf8, 0x44, 0xd4, 0x93, 0x64, 0xe5, 0x98, 0x2a, 0x4c, 0x58, 0x32, 0xdd, 0x2c, 0x4d, 0x45, + 0xb8, 0xdd, 0x82, 0x34, 0x17, 0x4c, 0x9b, 0xfe, 0x27, 0xb4, 0x30, 0x13, 0xf9, 0xc8, 0xc4, 0x59, + 0x80, 0x3f, 0x04, 0x56, 0x35, 0xd9, 0xc4, 0xc1, 0x64, 0x56, 0x82, 0x8e, 0xe4, 0x6e, 0x83, 0x58, + 0x9d, 0x36, 0x0b, 0xdf, 0x05, 0x25, 0x00, 0x73, 0x66, 0xc6, 0x2f, 0x4c, 0xec, 0x8d, 0xfd, 0x8e, + 0xb6, 0xe7, 0xd6, 0x20, 0x48, 0xee, 0xd5, 0x71, 0x20, 0xf7, 0xfc, 0xbe, 0x0c, 0x06, 0xd7, 0xa2, + 0xf3, 0x4c, 0xc2, 0x65, 0x94, 0x44, 0xcf, 0x54, 0xed, 0x2f, 0xf1, 0x28, 0xa4, 0x2a, 0xe8, 0x45, + 0x7d, 0x1c, 0x89, 0xf5, 0xc2, 0x7e, 0xbd, 0xf5, 0x78, 0x53, 0xaf, 0x57, 0x58, 0xa4, 0xe8, 0x85, + 0x4f, 0xa9, 0xd2, 0xfa, 0xe1, 0xf0, 0xa0, 0xc4, 0xc3, 0x83, 0x1b, 0x11, 0x52, 0x50, 0x5d, 0x05, + 0xea, 0x71, 0x0b, 0xa9, 0x64, 0xae, 0xb5, 0x6b, 0x13, 0x20, 0xbf, 0xd8, 0x6c, 0xe3, 0x87, 0x4b, + 0x01, 0xe7, 0x10, 0x40, 0x8f, 0x6d, 0xa5, 0xfe, 0x14, 0x23, 0x88, 0xc9, 0x49, 0x90, 0xe8, 0xb0, + 0x6b, 0xdb, 0x61, 0xe1, 0x48, 0x79, 0xa0, 0xf2, 0xc3, 0xb9, 0xa4, 0x49, 0x56, 0x7f, 0x27, 0x5e, + 0x10, 0xf6, 0xfe, 0x7e, 0x87, 0xf2, 0x1c, 0x49, 0x3a, 0xe6, 0x63, 0xc2, 0x85, 0x07, 0x7c, 0x44, + 0x32, 0x85, 0x60, 0xf7, 0xbe, 0xb8, 0x00, 0xd9, 0x11, 0x83, 0x42, 0xf6, 0x9d, 0x62, 0xc8, 0x3f, + 0x1f, 0x87, 0xf2, 0xcc, 0x97, 0x89, 0x38, 0x4e, 0x4c, 0x8a, 0x9f, 0x0a, 0x45, 0x56, 0x20, 0xfb, + 0xd1, 0x86, 0x94, 0xbb, 0xd6, 0xb0, 0x40, 0xa8, 0x1a, 0xe6, 0x4e, 0x48, 0xb9, 0xa2, 0x49, 0x61, + 0x02, 0x13, 0xc0, 0x02, 0x33, 0x1b, 0x84, 0x8a, 0xf1, 0xfe, 0x24, 0x14, 0xfd, 0xce, 0x68, 0x5b, + 0x2d, 0x93, 0x2c, 0x44, 0xac, 0x3c, 0x62, 0xd3, 0x7c, 0x8e, 0x2f, 0x1d, 0xf1, 0x21, 0x42, 0x5b, + 0xde, 0xc6, 0x2e, 0x0e, 0xac, 0x55, 0xb1, 0x0a, 0x19, 0x60, 0x18, 0x50, 0x80, 0x01, 0x38, 0x8b, + 0x1f, 0x09, 0x51, 0x01, 0x47, 0x16, 0xd0, 0x2a, 0x4d, 0x96, 0x39, 0x45, 0xc2, 0x49, 0x1b, 0x4a, + 0x9f, 0x12, 0x0a, 0x42, 0x20, 0x98, 0x91, 0xe7, 0x3e, 0x80, 0x55, 0x81, 0xe6, 0x60, 0x64, 0x72, + 0x50, 0x5e, 0xab, 0xaa, 0x78, 0x8e, 0x84, 0x8e, 0xaf, 0xa3, 0x35, 0xf5, 0xa8, 0xde, 0xad, 0x15, + 0xd4, 0xcb, 0x3e, 0xa3, 0xb7, 0xd1, 0x32, 0xbe, 0x8a, 0x9d, 0x3e, 0x11, 0x08, 0x42, 0x38, 0xa5, + 0xdd, 0x71, 0x07, 0x2a, 0x63, 0x12, 0xff, 0x0a, 0x6c, 0x6b, 0xcf, 0x27, 0xb2, 0xe9, 0x28, 0xb9, + 0x78, 0xc2, 0x01, 0x4e, 0x3b, 0x1e, 0x57, 0xf8, 0xff, 0x82, 0x31, 0x2e, 0x20, 0xa8, 0x56, 0x62, + 0x72, 0xf1, 0x21, 0x42, 0x08, 0xfb, 0x4c, 0x43, 0x85, 0x99, 0x1d, 0xb1, 0xd1, 0x76, 0xf8, 0xe0, + 0xe1, 0xb5, 0x6e, 0x9c, 0x92, 0x2a, 0x5b, 0x6c, 0x1f, 0xdf, 0x88, 0x12, 0x3f, 0xb0, 0x40, 0x13, + 0xe4, 0x1d, 0x2a, 0x0d, 0x6e, 0x13, 0x69, 0x89, 0xd8, 0x7b, 0x0e, 0xd8, 0x71, 0x01, 0x42, 0xeb, + 0xc7, 0x82, 0x80, 0x74, 0x07, 0x54, 0x19, 0x32, 0x0c, 0xfa, 0x44, 0x46, 0x12, 0x50, 0x83, 0x20, + 0xc4, 0x66, 0x3d, 0x96, 0x04, 0xcc, 0x9c, 0x6b, 0xea, 0xf1, 0x00, 0x9a, 0xd6, 0xbe, 0x7d, 0x85, + 0x7f, 0x12, 0x09, 0xc5, 0x12, 0x44, 0x23, 0x43, 0x06, 0x29, 0x76, 0x19, 0xf1, 0x20, 0x22, 0x14, + 0xff, 0x12, 0x13, 0x70, 0x00, 0x5e, 0x49, 0xe8, 0xb3, 0x0c, 0x08, 0xc6, 0xea, 0x39, 0x1c, 0x14, + 0xf4, 0x58, 0xbe, 0xa3, 0xb2, 0xfd, 0x48, 0x51, 0x3d, 0x53, 0x23, 0xf5, 0x1f, 0x57, 0x44, 0x31, + 0xbe, 0xa9, 0x50, 0xde, 0x08, 0xeb, 0x5b, 0x1f, 0x54, 0xaf, 0xd6, 0x53, 0x75, 0xab, 0xe0, 0x9c, + 0x28, 0x27, 0xce, 0xd4, 0x5a, 0x4a, 0x50, 0x12, 0x09, 0x05, 0x28, 0xd0, 0x10, 0xdc, 0xab, 0xe0, + 0x2c, 0xcc, 0x98, 0xf8, 0x50, 0xb0, 0xe4, 0xa0, 0x72, 0x1c, 0x41, 0x61, 0x06, 0x0c, 0x74, 0x58, + 0x0e, 0xac, 0x64, 0x9e, 0x46, 0xc0, 0x5f, 0x2c, 0xe0, 0x1a, 0x36, 0x99, 0x98, 0xf5, 0xd0, 0xc0, + 0x02, 0x9f, 0xbc, 0x18, 0x1a, 0x58, 0x46, 0xfc, 0xa3, 0x60, 0x35, 0x89, 0x20, 0x67, 0x6e, 0x60, + 0xcc, 0x08, 0xb0, 0xf0, 0xc3, 0xc4, 0x8c, 0xdb, 0xdb, 0xb8, 0xae, 0xb6, 0x40, 0x76, 0x19, 0x01, + 0x23, 0x60, 0xf1, 0x36, 0xa9, 0x36, 0x22, 0x4c, 0xbd, 0xe3, 0x81, 0xc4, 0x29, 0xee, 0x20, 0xb7, + 0x7b, 0x7e, 0x24, 0x15, 0x9c, 0xa3, 0x05, 0xbe, 0x7c, 0x0a, 0x21, 0x01, 0x12, 0x3a, 0x39, 0x70, + 0x69, 0x3e, 0x5c, 0x42, 0x47, 0x52, 0xce, 0xf8, 0x52, 0xee, 0x79, 0xc3, 0x02, 0x00, 0x94, 0xc6, + 0x67, 0xf3, 0x22, 0x99, 0x87, 0x1d, 0xc3, 0xb9, 0x49, 0x45, 0xdc, 0x06, 0x29, 0xda, 0x57, 0x9a, + 0xa9, 0x2a, 0xc4, 0x45, 0xc9, 0x13, 0x0f, 0x50, 0x7d, 0x95, 0x31, 0xa5, 0xce, 0x9f, 0x82, 0x52, + 0x6a, 0xb3, 0xcf, 0x59, 0x73, 0xc4, 0x82, 0x38, 0x55, 0xa5, 0x65, 0xb1, 0x5b, 0xd7, 0x28, 0x46, + 0x76, 0x0f, 0x4b, 0x5d, 0x53, 0xb5, 0xd4, 0x89, 0x7d, 0x5c, 0x04, 0xba, 0xbf, 0xc1, 0x1e, 0xee, + 0xe9, 0x17, 0x90, 0xce, 0xff, 0xab, 0xfd, 0x52, 0xa7, 0xd1, 0x5a, 0x2b, 0x9e, 0x3a, 0xae, 0xee, + 0xff, 0xe1, 0xcb, 0x0d, 0x83, 0x3a, 0x54, 0xe9, 0x6e, 0x1c, 0xc2, 0xb3, 0x7f, 0xf0, 0xa0, 0x40, + 0x87, 0x76, 0x38, 0x2a, 0x90, 0x87, 0x48, 0x2a, 0x48, 0xb8, 0x60, 0xab, 0x08, 0x22, 0xe3, 0x69, + 0xef, 0xb2, 0xde, 0x33, 0xe3, 0x48, 0x17, 0x60, 0xec, 0x1a, 0xc1, 0x37, 0x82, 0xe7, 0x9a, 0x3e, + 0xe3, 0x52, 0x3b, 0x28, 0x5c, 0x1b, 0xa7, 0xe8, 0x46, 0x35, 0xf5, 0x45, 0x61, 0xaa, 0x42, 0x27, + 0x49, 0xc9, 0x0f, 0x7c, 0x97, 0x76, 0x35, 0x06, 0x4a, 0x51, 0x5e, 0xa4, 0xb4, 0xca, 0x50, 0x50, + 0x30, 0x47, 0xde, 0x6a, 0xc2, 0xa6, 0x3c, 0x84, 0x5f, 0x81, 0x53, 0x96, 0xe0, 0x33, 0x22, 0x85, + 0xfe, 0x3d, 0xd1, 0xdf, 0x22, 0xc7, 0xe3, 0xa9, 0xe1, 0xd7, 0xa4, 0xf8, 0xdc, 0x6e, 0x25, 0x93, + 0x7e, 0xae, 0x00, 0x33, 0x22, 0x76, 0xeb, 0x93, 0x38, 0x6b, 0xef, 0xd8, 0x26, 0x78, 0xd1, 0xac, + 0x49, 0x12, 0x53, 0xae, 0xb0, 0x57, 0x01, 0xbf, 0xe5, 0x30, 0xfb, 0x68, 0x7b, 0x6b, 0x34, 0xcc, + 0x69, 0xb9, 0x3b, 0xff, 0x53, 0x6d, 0x5e, 0x3f, 0xc3, 0xd4, 0xf9, 0x1d, 0xcc, 0x0b, 0xdf, 0x07, + 0xf1, 0xdd, 0x59, 0x39, 0xfb, 0xb9, 0x45, 0xf8, 0x26, 0x3a, 0xb0, 0xb3, 0x51, 0x8e, 0x27, 0xec, + 0x5d, 0x01, 0xb6, 0xc2, 0x16, 0xa9, 0x6f, 0x8c, 0x24, 0x40, 0xb6, 0x08, 0x5d, 0x10, 0x33, 0xb3, + 0x19, 0x05, 0xc0, 0xb2, 0x21, 0x75, 0xea, 0x4b, 0x1f, 0x7a, 0x3e, 0x1c, 0x31, 0x82, 0xf1, 0xb3, + 0x02, 0x1f, 0x69, 0xd1, 0x89, 0xc0, 0x61, 0x2f, 0xee, 0xa1, 0x29, 0x06, 0x70, 0x78, 0x23, 0xe3, + 0xcf, 0x8d, 0xe6, 0x0a, 0xea, 0x9c, 0xf1, 0xe8, 0x27, 0xeb, 0xc9, 0x2c, 0x1a, 0x6d, 0x16, 0xdb, + 0x47, 0xc7, 0x8d, 0x28, 0xb1, 0x36, 0x04, 0xb7, 0xc8, 0x10, 0x18, 0x24, 0xcd, 0x10, 0xdb, 0x9d, + 0x10, 0xf7, 0x48, 0x35, 0xd0, 0x06, 0xc3, 0x70, 0xcd, 0xe2, 0xfe, 0x0d, 0x1b, 0x23, 0x02, 0x4e, + 0x99, 0x3e, 0xdf, 0x82, 0xb1, 0x8d, 0x5e, 0x5c, 0x57, 0x8f, 0x8b, 0x27, 0xcb, 0xd8, 0xa5, 0x45, + 0x5b, 0xd7, 0x25, 0xb0, 0x42, 0x78, 0xfa, 0x4e, 0x10, 0x1e, 0xbe, 0x2d, 0xfe, 0x24, 0x28, 0x7c, + 0x04, 0xb5, 0xa2, 0x05, 0xad, 0x1d, 0x8a, 0x92, 0x57, 0x9f, 0x9a, 0xe7, 0x23, 0xc8, 0xfe, 0x39, + 0xab, 0x10, 0xc1, 0x41, 0x06, 0xe0, 0xbd, 0x63, 0x65, 0x09, 0xaa, 0x70, 0x6e, 0x38, 0x80, 0x53, + 0x49, 0x92, 0x26, 0x4f, 0x66, 0xc5, 0x23, 0x76, 0xd4, 0x63, 0x26, 0x1e, 0x10, 0x14, 0xd9, 0x82, + 0x00, 0xe1, 0x2d, 0x63, 0x2c, 0xa8, 0xf0, 0xf4, 0x61, 0x93, 0xd1, 0x4f, 0x87, 0x02, 0xb9, 0x72, + 0x23, 0xb6, 0xf3, 0xd3, 0x1f, 0xec, 0xdc, 0xb1, 0x5f, 0x2f, 0x45, 0x4b, 0x08, 0x74, 0x21, 0x92, + 0x74, 0x7c, 0x22, 0xfa, 0x16, 0xe7, 0xc2, 0xe2, 0xad, 0x8c, 0xca, 0x69, 0x5a, 0x36, 0xc4, 0x64, + 0x10, 0x37, 0x86, 0x02, 0x3b, 0x1d, 0xfb, 0x6d, 0xc5, 0xbe, 0x24, 0x30, 0x29, 0x0d, 0x2c, 0xa6, + 0x98, 0x88, 0x91, 0x2c, 0x86, 0x29, 0x78, 0x82, 0x85, 0x78, 0xbf, 0xfe, 0x36, 0x80, 0x85, 0x1b, + 0x4d, 0x26, 0xf4, 0x8d, 0xe5, 0x50, 0x82, 0xb4, 0x61, 0xaa, 0x00, 0xdc, 0xc1, 0xf1, 0x01, 0x4b, + 0xd1, 0x9d, 0xf0, 0xe6, 0x17, 0xe4, 0xda, 0x7c, 0x48, 0xd2, 0x15, 0xa9, 0x55, 0x28, 0xaf, 0xae, + 0x01, 0x93, 0x0a, 0x41, 0x10, 0x6f, 0xa4, 0x24, 0x77, 0x04, 0xd7, 0x3a, 0xc1, 0xa6, 0xbb, 0xb5, + 0x42, 0xe1, 0x64, 0x44, 0x82, 0xb8, 0xe9, 0xdc, 0x81, 0xb5, 0x63, 0x38, 0xcb, 0x08, 0x9f, 0x6c, + 0x23, 0xef, 0xad, 0x38, 0x97, 0x7f, 0x89, 0x1a, 0x20, 0xcd, 0xba, 0xb2, 0x17, 0xfb, 0x8a, 0x8b, + 0x7f, 0x6b, 0x50, 0xdb, 0x8a, 0x0e, 0x3e, 0x17, 0x9b, 0xe9, 0x8c, 0x94, 0x81, 0xef, 0x2d, 0x7e, + 0x1b, 0xbf, 0x89, 0x0a, 0x09, 0x8d, 0x52, 0x08, 0xf6, 0x44, 0xac, 0x58, 0x56, 0x33, 0x60, 0xa3, + 0x0d, 0x4f, 0xcf, 0x45, 0x17, 0xc1, 0x51, 0x1c, 0x65, 0x2b, 0xd0, 0x89, 0x85, 0x47, 0x2c, 0x8f, + 0x76, 0xc8, 0xd2, 0xe0, 0x85, 0xdb, 0xbe, 0x64, 0x8a, 0x1b, 0x80, 0x71, 0x29, 0x94, 0xff, 0xf5, + 0xba, 0x89, 0x19, 0xb2, 0x6b, 0x85, 0xf1, 0xb5, 0xd0, 0xa2, 0x6e, 0x9a, 0xaa, 0x88, 0x30, 0xc4, + 0x1d, 0xdd, 0x5e, 0x85, 0x0a, 0x87, 0xc9, 0xce, 0x20, 0xa6, 0x5d, 0x87, 0x5d, 0xa0, 0xd9, 0xd8, + 0xa0, 0x12, 0x2c, 0xb4, 0xa1, 0xb2, 0x82, 0x84, 0x25, 0xc7, 0x25, 0xdd, 0x4c, 0xcb, 0xfb, 0x51, + 0x94, 0xcb, 0xc9, 0xdc, 0xf9, 0x1f, 0x82, 0x93, 0xe8, 0x08, 0x0e, 0xe2, 0x23, 0xda, 0xe9, 0xc1, + 0xb1, 0xef, 0x09, 0xcd, 0x47, 0xf8, 0x2c, 0x29, 0x59, 0xcb, 0x22, 0xb1, 0x61, 0x47, 0x43, 0x07, + 0x66, 0x32, 0x84, 0xf1, 0x20, 0x94, 0x65, 0xea, 0x28, 0xc9, 0xc1, 0x64, 0x4e, 0x09, 0xb0, 0xf6, + 0x04, 0xc2, 0xb0, 0x7c, 0x15, 0xd3, 0x64, 0x8a, 0xd0, 0x1e, 0x47, 0x0b, 0x23, 0x1d, 0x15, 0x52, + 0x8a, 0x2a, 0x74, 0x69, 0x03, 0x52, 0x41, 0x00, 0x0b, 0x5c, 0x8a, 0xa8, 0xbb, 0xe9, 0xcf, 0x86, + 0xc2, 0x36, 0x35, 0x82, 0x7b, 0xf0, 0xc4, 0xca, 0x98, 0xb6, 0xfe, 0xa2, 0x2c, 0x48, 0xf2, 0x63, + 0x5c, 0x98, 0xc2, 0x7d, 0x0c, 0xaf, 0xae, 0x5f, 0x04, 0x7b, 0xde, 0x09, 0x7a, 0xbd, 0x75, 0x79, + 0x7a, 0xbf, 0xc1, 0x15, 0x83, 0x39, 0x14, 0xbc, 0xab, 0xae, 0x73, 0xe8, 0x98, 0xca, 0xe1, 0xc3, + 0xcc, 0x80, 0xec, 0x2a, 0x07, 0x1a, 0x50, 0xc5, 0x5a, 0x5f, 0xc4, 0x82, 0xc3, 0x61, 0x94, 0x40, + 0xc3, 0x25, 0x3e, 0x80, 0xf6, 0xb9, 0x9c, 0xb0, 0x82, 0x4e, 0x2d, 0xa8, 0x18, 0xe0, 0xff, 0x8d, + 0xb8, 0x77, 0x5c, 0x0a, 0x16, 0xef, 0xb5, 0x0d, 0xc1, 0x05, 0x59, 0x4e, 0x9f, 0xb4, 0x5c, 0x52, + 0x10, 0x11, 0x16, 0x7e, 0x6f, 0x5e, 0x20, 0x28, 0x43, 0x42, 0x58, 0x95, 0x4c, 0xc3, 0x02, 0x41, + 0x83, 0x28, 0x68, 0x1e, 0xa4, 0x18, 0x24, 0x8e, 0x16, 0x34, 0xbc, 0x1e, 0x60, 0xcf, 0x8d, 0x32, + 0xe3, 0x2a, 0x89, 0xba, 0xd6, 0x31, 0xe5, 0x2d, 0x88, 0x54, 0x3a, 0xc7, 0x70, 0x8a, 0x39, 0x68, + 0x0f, 0x64, 0xe2, 0xc6, 0x8a, 0x0f, 0x41, 0x8a, 0x79, 0xd4, 0xb4, 0x30, 0x17, 0xb8, 0xdd, 0x8e, + 0x39, 0x42, 0xdc, 0xdb, 0x9a, 0x47, 0x02, 0xaf, 0x35, 0x06, 0xd1, 0x51, 0x7e, 0x14, 0xbe, 0x04, + 0x80, 0x3e, 0xa2, 0x9a, 0xae, 0x06, 0xa3, 0x9a, 0x26, 0xa5, 0xb8, 0xee, 0xe5, 0xde, 0xda, 0xb2, + 0x1d, 0x8e, 0xae, 0x67, 0x81, 0xd7, 0xb1, 0xd7, 0x8b, 0x17, 0x43, 0x58, 0x48, 0x3f, 0x10, 0xbc, + 0x13, 0xd5, 0x8d, 0xc1, 0x13, 0x7e, 0x41, 0xf2, 0x05, 0xb3, 0x1f, 0xf7, 0xc2, 0x83, 0x57, 0x91, + 0x1a, 0x5d, 0x58, 0x20, 0xc9, 0xc6, 0x22, 0xdb, 0x94, 0x52, 0x1a, 0x41, 0xaf, 0xd7, 0x7f, 0x0c, + 0xc2, 0x63, 0x60, 0xfd, 0x1d, 0x43, 0x46, 0x66, 0x31, 0x0f, 0x05, 0xc4, 0x19, 0x3e, 0xe5, 0x85, + 0x49, 0x75, 0xc4, 0x42, 0x82, 0x43, 0xec, 0x31, 0x95, 0x15, 0x49, 0xa2, 0x84, 0x96, 0xa2, 0x49, + 0x0e, 0xf6, 0x9c, 0xb1, 0x9c, 0xb0, 0xf8, 0x2c, 0x55, 0x8d, 0x4b, 0x0e, 0x2b, 0xc1, 0xe0, 0x30, + 0x9a, 0x73, 0x4c, 0x7c, 0x29, 0x52, 0x00, 0x21, 0x96, 0xd5, 0x14, 0xc6, 0x9a, 0x2b, 0xf5, 0xe8, + 0x1a, 0xde, 0xcd, 0xdf, 0x05, 0xb6, 0xcc, 0x45, 0xbb, 0x49, 0x02, 0x6c, 0x83, 0x0b, 0x7c, 0x29, + 0x74, 0x24, 0x68, 0x19, 0x03, 0x1b, 0xf6, 0x8d, 0x0e, 0x41, 0x01, 0xca, 0x10, 0xa7, 0x7d, 0xf0, + 0xa0, 0xc3, 0x66, 0xd3, 0x0a, 0xf0, 0x7f, 0x46, 0x5a, 0x91, 0x84, 0x2d, 0x09, 0x5b, 0x89, 0x42, + 0x81, 0xa3, 0x60, 0xea, 0x63, 0x25, 0xe1, 0x02, 0x99, 0xae, 0x97, 0xba, 0x54, 0x10, 0x17, 0xf8, + 0x40, 0x82, 0x2f, 0x45, 0xcd, 0xd4, 0xe2, 0x21, 0x9d, 0x08, 0xa2, 0xa1, 0x8d, 0x44, 0x2a, 0x6e, + 0xe4, 0xe6, 0xaf, 0x05, 0x81, 0x73, 0x65, 0x22, 0x31, 0x21, 0x89, 0x0f, 0xfa, 0xbe, 0x84, 0xbb, + 0x32, 0xf8, 0x80, 0x2f, 0x85, 0xad, 0x35, 0xf2, 0xe8, 0x8e, 0x0e, 0xe3, 0x69, 0x4f, 0x0f, 0x86, + 0xd1, 0xff, 0xe7, 0x84, 0xf0, 0xf9, 0x5a, 0x23, 0xa4, 0xd7, 0xc3, 0xf0, 0x97, 0x41, 0x0e, 0xfa, + 0x2e, 0x5f, 0x58, 0xaf, 0xa2, 0x43, 0x3e, 0xac, 0x1f, 0x44, 0x62, 0x27, 0xaf, 0x7c, 0x27, 0x26, + 0x7b, 0x73, 0xc3, 0x13, 0x05, 0x15, 0x26, 0x30, 0x40, 0x59, 0x2b, 0x41, 0x56, 0xa1, 0xab, 0x09, + 0x47, 0xe2, 0x44, 0x02, 0xc9, 0x87, 0x2a, 0x96, 0xfc, 0xb2, 0x75, 0xb0, 0x08, 0x4d, 0x61, 0xd4, + 0xaf, 0x5e, 0x24, 0x16, 0x58, 0xee, 0x3e, 0x2e, 0x04, 0xb4, 0x1b, 0x36, 0x1c, 0x82, 0xfc, 0xd4, + 0x02, 0x0b, 0xdf, 0xc4, 0x02, 0x18, 0xe8, 0x68, 0x1d, 0x60, 0x5f, 0xca, 0x0f, 0x8c, 0x10, 0x80, + 0x42, 0x0c, 0x6d, 0x1e, 0x93, 0x78, 0xc1, 0xbc, 0x83, 0x98, 0x5a, 0x1e, 0xe5, 0x93, 0x61, 0x17, + 0xb8, 0xb7, 0xb0, 0x73, 0x47, 0x86, 0x03, 0xc4, 0x05, 0x0b, 0x86, 0xde, 0xe0, 0xd8, 0x1e, 0x46, + 0x4d, 0x0c, 0x83, 0x34, 0x55, 0x8f, 0xfa, 0x52, 0x68, 0x47, 0x32, 0x1f, 0xb8, 0x89, 0xeb, 0xe5, + 0xe2, 0x42, 0x82, 0xf6, 0x88, 0x59, 0xb4, 0xa6, 0x6a, 0x06, 0xf3, 0xa4, 0xe7, 0xe4, 0xa9, 0x55, + 0x56, 0xd4, 0x9d, 0xf1, 0xb8, 0xba, 0x77, 0xa7, 0xab, 0x70, 0x1a, 0x7f, 0x89, 0x20, 0xfc, 0xe2, + 0xa7, 0x07, 0x06, 0xf1, 0x85, 0x23, 0x2d, 0x15, 0x36, 0x7e, 0x14, 0x3a, 0xd9, 0x3a, 0x12, 0x0c, + 0x66, 0x11, 0x2d, 0x08, 0x0b, 0x82, 0x04, 0xea, 0x97, 0x95, 0x43, 0x80, 0x01, 0xb5, 0x86, 0x4b, + 0x80, 0xa0, 0x58, 0xe6, 0xb1, 0xca, 0x1e, 0x14, 0x28, 0x65, 0x3f, 0x56, 0xe3, 0x2d, 0xda, 0x4c, + 0xac, 0x59, 0x54, 0x3d, 0x13, 0xd8, 0xa9, 0xfb, 0xcc, 0x4e, 0x1e, 0x3e, 0x81, 0xb0, 0x86, 0xb5, + 0x45, 0x71, 0xa2, 0xca, 0xe9, 0x12, 0xc6, 0x05, 0x7d, 0xd8, 0xea, 0x17, 0x8e, 0x26, 0xac, 0x63, + 0x8f, 0x06, 0x85, 0xaf, 0x3b, 0x78, 0x1a, 0x17, 0x8f, 0x10, 0xae, 0x85, 0x39, 0x80, 0xd4, 0x70, + 0x08, 0x0a, 0x93, 0x56, 0x5f, 0xe1, 0x42, 0x3a, 0xaa, 0x16, 0xda, 0x90, 0xff, 0x38, 0x0e, 0x33, + 0x0e, 0xe5, 0x48, 0xe4, 0xf0, 0xb1, 0x3f, 0x2b, 0x87, 0x2e, 0xf8, 0x50, 0x97, 0xf2, 0xca, 0x80, + 0x02, 0x07, 0xe9, 0x52, 0x10, 0x01, 0x39, 0xda, 0x34, 0xac, 0x63, 0x7b, 0x8c, 0xc3, 0xa6, 0x27, + 0x07, 0x1d, 0x8e, 0x81, 0x21, 0xc9, 0x32, 0xc4, 0x42, 0x82, 0xe5, 0xa7, 0x55, 0xba, 0x66, 0x48, + 0xf4, 0x36, 0x68, 0xed, 0xcb, 0xc3, 0x1d, 0x7b, 0xe8, 0xa7, 0xbe, 0x8a, 0x9d, 0x7a, 0x2a, 0x75, + 0xe8, 0x8c, 0x7d, 0x4a, 0x0f, 0xa2, 0x37, 0xc1, 0x14, 0x70, 0x8e, 0x5d, 0x47, 0x51, 0xbe, 0xad, + 0xf5, 0x72, 0xf8, 0x68, 0xa6, 0x22, 0x4c, 0x76, 0xe3, 0x27, 0xee, 0xd9, 0x4c, 0x4c, 0xc2, 0xd7, + 0xc1, 0x00, 0x88, 0xe4, 0x5b, 0x14, 0x46, 0xf2, 0xc0, 0xea, 0xa1, 0x09, 0x46, 0x09, 0xe8, 0x20, + 0x0b, 0xff, 0x8c, 0xe3, 0xc3, 0x64, 0xb7, 0x1d, 0xb2, 0xd6, 0x70, 0x75, 0x55, 0xbf, 0xe2, 0x04, + 0x8d, 0x20, 0x5d, 0x7a, 0x13, 0x89, 0xe0, 0xe1, 0xc3, 0xda, 0x1e, 0xf5, 0x22, 0x1d, 0xe9, 0x17, + 0x82, 0x14, 0x76, 0x4b, 0x6e, 0x31, 0x52, 0xe0, 0x41, 0x28, 0x0f, 0x8d, 0x54, 0x45, 0xcf, 0xe5, + 0xaf, 0xf8, 0x25, 0x3d, 0x19, 0x14, 0xd1, 0x6f, 0x54, 0x40, 0xc0, 0xff, 0xf8, 0x2c, 0xb3, 0x60, + 0x20, 0xa3, 0xd1, 0x31, 0x39, 0x94, 0x4a, 0xba, 0xa0, 0x16, 0x93, 0xfc, 0x15, 0x4a, 0x08, 0x2e, + 0xf5, 0x0b, 0xcf, 0x24, 0x22, 0x1f, 0x14, 0xe3, 0xdc, 0xa4, 0x10, 0xa2, 0xe8, 0x21, 0x3b, 0x5a, + 0x31, 0xf0, 0xa0, 0x82, 0xd9, 0x63, 0x10, 0x38, 0x58, 0x3b, 0x4e, 0x09, 0x54, 0x0f, 0xd2, 0xf2, + 0x56, 0x04, 0x00, 0xd4, 0x16, 0x39, 0x60, 0xea, 0x6c, 0x7f, 0x8d, 0xa9, 0x49, 0x88, 0x0a, 0xda, + 0x23, 0x44, 0x09, 0x9f, 0x05, 0x67, 0x3d, 0x6a, 0x05, 0xd0, 0xa0, 0xcb, 0x30, 0x3b, 0xda, 0x01, + 0xc7, 0xcc, 0x38, 0x6e, 0x80, 0x3e, 0xb8, 0x0f, 0x30, 0x61, 0x2a, 0x43, 0xd5, 0x09, 0x54, 0xf3, + 0x8e, 0xf8, 0x80, 0xa0, 0x92, 0x27, 0xe3, 0x8b, 0x1e, 0x7f, 0xab, 0x0b, 0x44, 0xe6, 0x7b, 0x48, + 0x44, 0xf1, 0x4d, 0xd8, 0x41, 0x3a, 0x18, 0x09, 0xff, 0xc1, 0x56, 0x46, 0x9d, 0x57, 0x12, 0x86, + 0x1e, 0x54, 0x6a, 0xf4, 0xc5, 0x6e, 0x5a, 0x16, 0xd2, 0xbf, 0x09, 0x50, 0x16, 0x76, 0xa3, 0xaa, + 0x12, 0x3f, 0x04, 0x79, 0x11, 0x90, 0xa3, 0xa3, 0x4b, 0xf0, 0x5a, 0x73, 0x34, 0x8b, 0xb2, 0xed, + 0x12, 0xc2, 0xe8, 0x31, 0x57, 0x39, 0xa2, 0xe9, 0x2a, 0xf0, 0x4b, 0xdd, 0x22, 0x36, 0x59, 0x78, + 0x21, 0x3a, 0xf6, 0x9c, 0xe6, 0x5f, 0xe3, 0x6f, 0x69, 0xc7, 0x08, 0x39, 0x42, 0xa2, 0x57, 0x2d, + 0x4a, 0x90, 0x41, 0x58, 0xda, 0x1b, 0xe5, 0xf4, 0x38, 0x01, 0x7a, 0x89, 0x81, 0x00, 0xa3, 0xbf, + 0x68, 0x9d, 0xb9, 0xe2, 0x42, 0x86, 0x40, 0xc6, 0xd9, 0x7c, 0x02, 0x19, 0x71, 0x21, 0x28, 0x99, + 0x24, 0xf7, 0x7a, 0xbb, 0x79, 0x1d, 0xf8, 0x50, 0x8f, 0x23, 0xc8, 0x5f, 0xe3, 0x53, 0x2a, 0xab, + 0x05, 0x1c, 0x63, 0x36, 0x72, 0xb2, 0xee, 0xb5, 0x3f, 0xc2, 0x82, 0x90, 0xe8, 0x25, 0x0e, 0x9e, + 0x8b, 0x16, 0x98, 0x98, 0xf6, 0x83, 0x4c, 0x6f, 0x2c, 0x09, 0x9f, 0xb5, 0x89, 0xae, 0xdc, 0x6e, + 0x22, 0x2f, 0x67, 0xe7, 0x38, 0x95, 0x2d, 0x00, 0xcd, 0x86, 0xee, 0xa1, 0x80, 0x93, 0xa5, 0x87, + 0x11, 0x0c, 0x09, 0x2e, 0x4d, 0x6e, 0xf2, 0x75, 0x49, 0x83, 0xb8, 0xc5, 0x5f, 0xfc, 0x36, 0x26, + 0xcc, 0xd9, 0x5e, 0x5f, 0xc6, 0xd6, 0xfc, 0x3a, 0x5d, 0xa3, 0x66, 0x38, 0xbe, 0x38, 0x51, 0x46, + 0xbc, 0x6f, 0xbd, 0xf4, 0x39, 0x91, 0x1d, 0x09, 0x63, 0xeb, 0xaf, 0xa3, 0x54, 0x9d, 0x1f, 0x2f, + 0x82, 0x3a, 0xd7, 0x57, 0xd7, 0x39, 0xf5, 0xce, 0x7d, 0x73, 0x9f, 0x51, 0xda, 0xb9, 0x37, 0x59, + 0x7a, 0x29, 0x53, 0xe0, 0xb0, 0x44, 0x3a, 0x80, 0x49, 0x27, 0x89, 0x11, 0x83, 0x95, 0x4b, 0x63, + 0x99, 0x57, 0x2d, 0xb9, 0xf0, 0x5e, 0x67, 0xac, 0xe4, 0x74, 0x32, 0x41, 0x8d, 0x9f, 0x10, 0x71, + 0xef, 0xa7, 0x1e, 0xdb, 0x3f, 0xf1, 0xbc, 0x08, 0x69, 0x03, 0x8e, 0x2d, 0xa7, 0xf3, 0xa9, 0x21, + 0x10, 0x3e, 0x18, 0x06, 0xb4, 0x51, 0xb0, 0xe7, 0xff, 0xf0, 0xa4, 0xa1, 0xd7, 0x90, 0x47, 0xd3, + 0x14, 0x11, 0x62, 0x72, 0xad, 0xf7, 0x49, 0xdf, 0x37, 0x98, 0xc9, 0x29, 0xb0, 0x1b, 0xbc, 0x40, + 0x25, 0x38, 0x66, 0x8d, 0xe8, 0x9b, 0x64, 0x3e, 0xcf, 0xff, 0xc2, 0x96, 0x53, 0x95, 0xd4, 0x0e, + 0x57, 0x99, 0x89, 0x13, 0xf2, 0xb2, 0x4a, 0x2c, 0xa9, 0xfe, 0x30, 0x57, 0x2c, 0x89, 0x5a, 0xe1, + 0x8b, 0xc0, 0xb2, 0x3c, 0x30, 0x3b, 0x93, 0x21, 0x59, 0x1a, 0x84, 0x65, 0xe6, 0x86, 0xe0, 0x97, + 0xe2, 0xbb, 0x28, 0x98, 0xd0, 0xcf, 0x8d, 0xcc, 0x26, 0x00, 0x20, 0x27, 0xc8, 0x54, 0x50, 0x02, + 0x63, 0x21, 0xa3, 0x4e, 0xf1, 0xff, 0x05, 0xf2, 0xa0, 0x31, 0x82, 0x02, 0x17, 0xe2, 0x94, 0xb0, + 0x82, 0x8d, 0x5b, 0x13, 0x1a, 0x4f, 0xdd, 0x9a, 0x73, 0x42, 0xfd, 0x49, 0x6d, 0xd2, 0x35, 0x49, + 0x53, 0x46, 0x3f, 0x0a, 0x70, 0x91, 0x9e, 0x37, 0xc3, 0x41, 0xd5, 0x87, 0x38, 0xf2, 0x81, 0xdb, + 0x52, 0x01, 0x67, 0x74, 0x92, 0x6a, 0x10, 0xc2, 0xc9, 0x21, 0x95, 0x28, 0x07, 0x55, 0x09, 0x94, + 0x7c, 0x3f, 0xc3, 0x89, 0x0a, 0x14, 0xb7, 0xe6, 0x12, 0xad, 0xb6, 0x51, 0xb6, 0x28, 0x19, 0x5b, + 0xa7, 0xe5, 0xf3, 0x72, 0xb0, 0x10, 0x1e, 0x55, 0x36, 0x3a, 0x4b, 0xdc, 0x92, 0x7e, 0x7c, 0x17, + 0x0b, 0x25, 0xb1, 0x40, 0x39, 0x28, 0x62, 0x54, 0x32, 0x71, 0xe0, 0xb2, 0x8e, 0x46, 0x08, 0xf4, + 0x0e, 0xd9, 0xe8, 0x67, 0xf4, 0x2f, 0xbe, 0x0b, 0x26, 0x02, 0x14, 0x16, 0x61, 0x8d, 0xb6, 0x40, + 0x6a, 0x03, 0xbc, 0xa3, 0x68, 0xe9, 0x8a, 0x7f, 0xc2, 0x96, 0xa3, 0xe8, 0x11, 0x18, 0x40, 0x78, + 0x92, 0xd9, 0x17, 0xb1, 0x4b, 0x13, 0x1b, 0x2a, 0xc1, 0x01, 0x77, 0xc2, 0x94, 0xe8, 0xd9, 0xb4, + 0x3e, 0x44, 0xc1, 0xb1, 0xaa, 0xf2, 0x9c, 0x3c, 0x33, 0x23, 0x8c, 0x49, 0xc6, 0x2b, 0xc2, 0x9e, + 0x8f, 0x32, 0xa2, 0xe7, 0x96, 0x8b, 0x45, 0x2d, 0x5b, 0x19, 0x04, 0x12, 0xb7, 0xf8, 0xf2, 0xa0, + 0x61, 0xba, 0x10, 0x52, 0x76, 0x91, 0xb9, 0x46, 0x98, 0xe6, 0x3f, 0x8c, 0x29, 0xc8, 0x6e, 0x46, + 0x63, 0x2c, 0xef, 0x27, 0x99, 0xbc, 0x8c, 0x7e, 0x1e, 0x32, 0xc8, 0x6a, 0x2d, 0x95, 0x92, 0xb7, + 0x52, 0x5a, 0xda, 0xd1, 0x63, 0xf6, 0xcc, 0x8a, 0xf8, 0x98, 0xd2, 0x16, 0xc9, 0x44, 0x50, 0x5d, + 0x6d, 0x0c, 0x1f, 0x28, 0xb3, 0x67, 0x41, 0xa4, 0x5a, 0x85, 0x76, 0x4b, 0xe3, 0x92, 0x34, 0x73, + 0x0b, 0x08, 0x62, 0xb7, 0xd2, 0x2d, 0x3f, 0x0a, 0x0c, 0xf1, 0x3a, 0x45, 0x29, 0x60, 0x12, 0x76, + 0xd5, 0x96, 0xc5, 0x77, 0x8b, 0xb9, 0xcc, 0x62, 0xf8, 0xd2, 0xa9, 0x63, 0x0d, 0x9f, 0x19, 0xcb, + 0x62, 0xca, 0xc4, 0x6c, 0x35, 0x88, 0x4e, 0xc7, 0x8c, 0x1d, 0x60, 0xf8, 0x28, 0xa5, 0x58, 0x44, + 0x32, 0xad, 0x1f, 0x4b, 0x5f, 0xfc, 0x3e, 0x7c, 0xa3, 0x65, 0x12, 0x81, 0x9a, 0x31, 0x50, 0xd8, + 0x0a, 0x4a, 0x21, 0x3c, 0x7e, 0x6a, 0x79, 0xb2, 0x0f, 0xb5, 0x2f, 0xc3, 0x11, 0xac, 0x55, 0x06, + 0x34, 0xc8, 0x35, 0x24, 0x4d, 0x0c, 0x39, 0x90, 0xa8, 0x95, 0x22, 0xf1, 0x5c, 0x2f, 0xf1, 0x75, + 0xae, 0xed, 0x9d, 0x81, 0x3d, 0x1a, 0x28, 0xae, 0x8a, 0xff, 0x5b, 0xc9, 0xd7, 0xf5, 0xca, 0x57, + 0x77, 0x7f, 0x5f, 0x1f, 0x53, 0x0b, 0xe0, 0x9e, 0x3d, 0x61, 0x68, 0x00, 0x26, 0xe2, 0x0b, 0x6d, + 0x5c, 0x84, 0x8c, 0xbe, 0xd8, 0x77, 0xfc, 0x32, 0x6e, 0x66, 0x10, 0xde, 0x78, 0x2f, 0xfe, 0x36, + 0x2f, 0x06, 0x81, 0xd5, 0x11, 0x19, 0xe8, 0x35, 0x22, 0x4a, 0x13, 0x14, 0x8d, 0x3b, 0x30, 0x37, + 0xdb, 0x6f, 0xfc, 0x65, 0x38, 0x0d, 0x19, 0x15, 0x85, 0xdb, 0x8e, 0x47, 0x05, 0x8c, 0x75, 0xf2, + 0x19, 0x71, 0x96, 0x19, 0x52, 0x20, 0x45, 0xbe, 0xc7, 0x25, 0xf8, 0x52, 0xb4, 0x60, 0x92, 0xa1, + 0x61, 0x3d, 0x08, 0x03, 0x08, 0xf9, 0x8e, 0xe0, 0xc0, 0x54, 0x1b, 0xc8, 0x24, 0xa3, 0x83, 0x9e, + 0x4e, 0x08, 0x80, 0x97, 0xa6, 0x5f, 0xd1, 0x9f, 0x82, 0xa1, 0x21, 0x4d, 0xc3, 0xb0, 0x2f, 0x2c, + 0xe6, 0x10, 0x9d, 0xec, 0x99, 0x44, 0x98, 0x21, 0x46, 0xb5, 0xbf, 0x9d, 0xf1, 0x01, 0x41, 0x19, + 0xf7, 0x3d, 0xc3, 0xc7, 0x12, 0x24, 0x16, 0xcb, 0xcc, 0x56, 0x9c, 0x50, 0x61, 0x2d, 0x64, 0xdf, + 0x0a, 0x45, 0x66, 0x32, 0x89, 0x37, 0x06, 0x13, 0x8f, 0x84, 0x69, 0xb4, 0x5b, 0xb4, 0x2e, 0x15, + 0x58, 0xc6, 0x45, 0x8e, 0x10, 0x3a, 0xe5, 0x7c, 0x03, 0x05, 0xe8, 0xaa, 0x4c, 0xc3, 0xe2, 0x02, + 0xc0, 0xc1, 0xc6, 0x7c, 0x28, 0x57, 0xbc, 0x3d, 0x6c, 0xa0, 0xd8, 0x76, 0xc0, 0x9d, 0x99, 0x9f, + 0x2a, 0x37, 0x48, 0x3c, 0x04, 0xf8, 0x60, 0x3b, 0x03, 0x01, 0x0b, 0xea, 0x62, 0x21, 0xb3, 0x18, + 0x94, 0x7a, 0xa8, 0xff, 0xc6, 0x13, 0x75, 0x0b, 0xc8, 0x2b, 0xec, 0x34, 0x40, 0x58, 0x90, 0xbd, + 0xcc, 0x17, 0xe7, 0x68, 0xe8, 0xda, 0x99, 0x40, 0xbb, 0x3f, 0x10, 0x14, 0xa9, 0xc7, 0x06, 0xa9, + 0x33, 0xf6, 0xc9, 0xdb, 0x8c, 0x3a, 0x01, 0x40, 0x86, 0x42, 0x04, 0xee, 0xe7, 0xc2, 0x82, 0xd0, + 0x1e, 0xca, 0xc0, 0xf1, 0x11, 0x96, 0xc2, 0xae, 0xaa, 0x1f, 0x1b, 0x72, 0x6d, 0xc0, 0x00, 0x39, + 0x01, 0x05, 0x2f, 0x89, 0x05, 0x84, 0x38, 0xc4, 0xd4, 0x6a, 0x87, 0x1c, 0x10, 0x43, 0xae, 0x51, + 0x93, 0x14, 0xf2, 0xd1, 0xef, 0x12, 0x0a, 0x69, 0x52, 0x29, 0xc3, 0x6b, 0x65, 0xc0, 0xd9, 0x4f, + 0x39, 0xc7, 0xaf, 0x1c, 0x69, 0x99, 0x8e, 0xf8, 0x90, 0x54, 0x56, 0x94, 0x00, 0x8c, 0x26, 0x05, + 0x15, 0x00, 0x73, 0x03, 0x06, 0xf8, 0x6d, 0xda, 0x22, 0x5a, 0x79, 0x18, 0xaf, 0xe0, 0xa2, 0xd5, + 0xdf, 0x63, 0x33, 0x4a, 0xa6, 0x1f, 0x12, 0x2f, 0x1a, 0x56, 0x03, 0x4c, 0x9a, 0xd2, 0x0b, 0x57, + 0xdf, 0xad, 0x66, 0x54, 0x32, 0x68, 0xf9, 0x94, 0x8d, 0xbf, 0xab, 0xe7, 0xfb, 0x7e, 0x32, 0xc8, + 0xb2, 0x63, 0x88, 0x27, 0xc9, 0x7b, 0xd3, 0x4c, 0xdf, 0x19, 0x94, 0xd6, 0x99, 0x88, 0x38, 0x98, + 0x2c, 0x32, 0xb6, 0x27, 0x4a, 0xaa, 0x19, 0x53, 0x17, 0x71, 0x7d, 0x90, 0x0e, 0xd5, 0xb4, 0xff, + 0x05, 0x9d, 0x1b, 0xb6, 0x3f, 0x76, 0x7d, 0xd8, 0x4e, 0x13, 0x76, 0xda, 0x12, 0x29, 0xf8, 0x52, + 0x60, 0xca, 0x89, 0x54, 0x1c, 0x1c, 0x2c, 0x3c, 0x85, 0x10, 0xa0, 0x2d, 0x8e, 0xb2, 0xbd, 0xa7, + 0xfe, 0xc4, 0xb8, 0x90, 0x30, 0xc8, 0x91, 0x98, 0xd0, 0xc7, 0x2e, 0x61, 0x56, 0x8b, 0xc6, 0x36, + 0x28, 0xc3, 0x53, 0x69, 0x53, 0x44, 0x9f, 0xa2, 0xdc, 0xad, 0x17, 0xff, 0xc6, 0x8a, 0xb2, 0x7f, + 0x0a, 0xe2, 0x26, 0x90, 0x5f, 0xd0, 0x9b, 0xe2, 0xf7, 0x8a, 0xea, 0x46, 0xd3, 0x76, 0x6b, 0x3a, + 0xb0, 0x5f, 0x7b, 0xff, 0x87, 0xeb, 0x02, 0x2d, 0xa5, 0x93, 0x9c, 0xa9, 0x25, 0x02, 0x5c, 0x24, + 0x25, 0x46, 0xb0, 0xc9, 0x49, 0x50, 0x8a, 0x04, 0xa8, 0xc7, 0x6e, 0x9e, 0x72, 0x40, 0xc7, 0x75, + 0x86, 0xe3, 0x39, 0xa2, 0x29, 0x3f, 0xf1, 0xbc, 0xa9, 0x90, 0x65, 0x58, 0xf5, 0x41, 0x0e, 0x3b, + 0xb2, 0x3a, 0x36, 0xef, 0x69, 0x01, 0x73, 0x9a, 0xa8, 0x3a, 0x6d, 0x3f, 0xc3, 0xbd, 0x38, 0xa3, + 0x36, 0x05, 0x3c, 0x70, 0xda, 0x3f, 0x0d, 0x14, 0xb3, 0xe1, 0x5b, 0x46, 0x1a, 0xa5, 0x7f, 0xf0, + 0x43, 0x69, 0x8f, 0x65, 0x87, 0xd9, 0x66, 0x43, 0x50, 0x87, 0x57, 0x2b, 0x94, 0xa8, 0xc8, 0xad, + 0x19, 0x73, 0x27, 0x5e, 0xfa, 0x2c, 0x5f, 0x25, 0xd0, 0x37, 0x40, 0xd7, 0x04, 0x92, 0x74, 0x2b, + 0x3a, 0xf1, 0x23, 0x44, 0x50, 0x0a, 0x0f, 0xb1, 0xc1, 0x81, 0x3d, 0xa2, 0xa3, 0x42, 0x39, 0x56, + 0x28, 0x5c, 0x21, 0x19, 0x05, 0x77, 0xb6, 0x71, 0x0d, 0x86, 0x0d, 0x79, 0x44, 0x50, 0x58, 0x96, + 0xb4, 0xdb, 0x6e, 0xfe, 0x0a, 0xe1, 0xe2, 0xb4, 0xdf, 0x45, 0xd4, 0x5e, 0xc2, 0x87, 0xf3, 0xe3, + 0x48, 0x4e, 0xa3, 0xc4, 0x82, 0x1c, 0xec, 0x72, 0xe2, 0x60, 0x9e, 0xaa, 0x98, 0xa8, 0xe9, 0x72, + 0x30, 0x8c, 0xac, 0x17, 0x26, 0x28, 0x8f, 0xf0, 0x56, 0x42, 0x40, 0x6e, 0x0b, 0xae, 0x83, 0x87, + 0x0a, 0x2d, 0x4e, 0x01, 0x80, 0xef, 0xcb, 0x06, 0x4a, 0x2b, 0x55, 0xca, 0x5f, 0xc9, 0xe1, 0x10, + 0xa1, 0xcc, 0xc0, 0xc0, 0x41, 0x01, 0xdd, 0x96, 0x53, 0x79, 0x33, 0x28, 0x77, 0x58, 0x3a, 0x29, + 0x35, 0x84, 0xb0, 0x78, 0x0d, 0xd9, 0x15, 0x32, 0x4b, 0x11, 0x12, 0x9f, 0xe0, 0x90, 0x89, 0x90, + 0x31, 0x4b, 0x7f, 0x82, 0x99, 0xe1, 0x81, 0x31, 0x1d, 0x10, 0x74, 0xa8, 0xb0, 0xa0, 0x68, 0xd2, + 0xd6, 0x2b, 0x0d, 0x10, 0xd4, 0x57, 0x44, 0x81, 0x1b, 0x06, 0x35, 0xe2, 0x01, 0x55, 0xe4, 0x18, + 0x59, 0x6c, 0xb4, 0x5a, 0x78, 0xbd, 0xd8, 0x32, 0x86, 0x98, 0x42, 0xc7, 0x89, 0x0a, 0x14, 0xa6, + 0x84, 0x13, 0xc7, 0x22, 0x81, 0x02, 0x83, 0x2f, 0x50, 0x30, 0x87, 0x02, 0x04, 0x9a, 0xd0, 0x90, + 0xe9, 0xa0, 0x97, 0x2b, 0xbe, 0x9f, 0x3f, 0xc2, 0x87, 0x24, 0x74, 0xb4, 0x73, 0xe8, 0x25, 0xe4, + 0xe8, 0xc7, 0x56, 0x14, 0x66, 0x4d, 0x0c, 0x05, 0x6c, 0x4d, 0x1b, 0x29, 0xd6, 0xdc, 0x88, 0xe1, + 0xe1, 0x4a, 0x68, 0x55, 0x5c, 0x0e, 0xe0, 0x10, 0xeb, 0x35, 0x0c, 0x46, 0xc4, 0x10, 0xb6, 0xde, + 0x7b, 0x8a, 0xc4, 0x11, 0xa2, 0xa5, 0xb3, 0xd6, 0x3d, 0xf0, 0xa1, 0x37, 0x53, 0x2b, 0x0a, 0x86, + 0x83, 0x01, 0x00, 0x70, 0xfa, 0x12, 0xae, 0x5b, 0x27, 0x62, 0x0e, 0x68, 0x31, 0x73, 0xf3, 0x4d, + 0x1d, 0xf8, 0x2c, 0x8e, 0x9d, 0xef, 0x04, 0x0a, 0x52, 0x0c, 0x19, 0x55, 0xa9, 0x41, 0xd1, 0x48, + 0x23, 0xbe, 0x20, 0x29, 0x2b, 0x1c, 0xb9, 0xe4, 0x61, 0x3a, 0xd2, 0x56, 0xd4, 0x04, 0x02, 0x38, + 0x08, 0x26, 0x09, 0x47, 0xc2, 0x92, 0x33, 0xd4, 0x76, 0x38, 0x6f, 0x09, 0x6e, 0x74, 0x99, 0x90, + 0x56, 0x3a, 0x89, 0x4a, 0xbe, 0x28, 0xec, 0x1c, 0xbe, 0xa4, 0x2f, 0xf1, 0x23, 0x3a, 0x9c, 0x20, + 0x62, 0x6b, 0x23, 0x1a, 0xca, 0x83, 0x89, 0x1d, 0x7c, 0x60, 0x8e, 0x86, 0x56, 0x6b, 0x9e, 0xdd, + 0x11, 0x58, 0xcb, 0x58, 0x26, 0xd7, 0x89, 0x0a, 0x66, 0x31, 0x63, 0xf9, 0x34, 0x06, 0x66, 0xf1, + 0xc4, 0x13, 0x11, 0x4a, 0xac, 0x63, 0xea, 0x9f, 0xc4, 0x05, 0x0b, 0x4c, 0xe2, 0x02, 0xa0, 0x6b, + 0x28, 0x20, 0x0c, 0x4f, 0x36, 0xf6, 0x15, 0xd0, 0x60, 0x17, 0xce, 0x1e, 0xe3, 0x5f, 0x9c, 0x44, + 0x29, 0x07, 0xe4, 0xdd, 0x47, 0xd1, 0xf4, 0x75, 0xdb, 0x42, 0xa8, 0x0f, 0xf5, 0x08, 0xff, 0x42, + 0x7b, 0xdf, 0x6d, 0x0c, 0x15, 0x46, 0xe4, 0x4f, 0xfc, 0x14, 0xf8, 0x91, 0xb0, 0xf8, 0xfd, 0x49, + 0xae, 0x84, 0x34, 0xab, 0x08, 0x94, 0x1a, 0x75, 0xaf, 0x5e, 0x0e, 0x02, 0x5d, 0x75, 0x0d, 0xf8, + 0xe1, 0x80, 0xb9, 0x56, 0x34, 0x21, 0x93, 0x63, 0xbd, 0xff, 0xc6, 0x8a, 0xde, 0xed, 0x93, 0x2e, + 0x48, 0x7e, 0x4e, 0x1e, 0xb1, 0xce, 0xe2, 0x5c, 0x53, 0x2b, 0x7e, 0x12, 0x84, 0xdc, 0xbb, 0x26, + 0x37, 0xa7, 0xff, 0xe3, 0x6e, 0x0c, 0xc0, 0x31, 0xfb, 0x60, 0x32, 0x88, 0x1a, 0x7b, 0x19, 0x2e, + 0x70, 0x6b, 0x52, 0x7b, 0xb3, 0x50, 0xc5, 0xde, 0x1c, 0x26, 0xcb, 0x7d, 0xc3, 0x79, 0xa7, 0x57, + 0xfc, 0x69, 0x59, 0xb5, 0x91, 0xe3, 0xa5, 0xc9, 0x28, 0x19, 0x73, 0xb1, 0x25, 0x4e, 0x21, 0x82, + 0x30, 0x61, 0x3a, 0x27, 0x10, 0x68, 0x3e, 0xa0, 0x51, 0x30, 0xc4, 0xcf, 0xe8, 0xd0, 0xf7, 0xf8, + 0x6e, 0xc5, 0x1e, 0x73, 0x6d, 0x1e, 0x43, 0x2e, 0xa2, 0x6e, 0x1f, 0x93, 0xa2, 0xfc, 0x7a, 0xe5, + 0x5c, 0x11, 0x5d, 0x9f, 0xf7, 0xd5, 0x01, 0x24, 0xe3, 0xf5, 0x77, 0x55, 0x77, 0x55, 0xd7, 0x44, + 0xea, 0xeb, 0x14, 0xbd, 0x73, 0x7c, 0x11, 0xd2, 0x48, 0xe4, 0x68, 0x36, 0xbe, 0xb9, 0xeb, 0x8d, + 0xd6, 0x8c, 0x95, 0x78, 0x40, 0x1c, 0x6e, 0xb9, 0x33, 0x2a, 0x84, 0xa8, 0x42, 0x38, 0x72, 0x67, + 0x40, 0x60, 0xfb, 0x0b, 0x71, 0x2c, 0x3f, 0xf1, 0xb9, 0x56, 0xdd, 0x43, 0xd7, 0x63, 0xd6, 0x81, + 0x20, 0x25, 0x62, 0x15, 0x68, 0x82, 0xa8, 0x5e, 0x42, 0x76, 0x4f, 0x77, 0x77, 0xfe, 0x24, 0x28, + 0x52, 0x84, 0x01, 0x60, 0xd2, 0x2b, 0x8f, 0x10, 0x17, 0x1d, 0x33, 0xef, 0x93, 0x8c, 0x9e, 0xf5, + 0x61, 0xcc, 0xbf, 0x2e, 0x84, 0x19, 0x66, 0xc4, 0x19, 0x9d, 0x9c, 0xbf, 0xc6, 0x59, 0x03, 0xc5, + 0xdd, 0xc2, 0x02, 0x30, 0xd8, 0xcc, 0x4b, 0xa9, 0x3a, 0x8c, 0x31, 0x78, 0xce, 0x8c, 0xae, 0xbe, + 0x5f, 0x24, 0x93, 0x42, 0xa0, 0x66, 0xc4, 0xc6, 0x08, 0x72, 0xe5, 0xe5, 0xe5, 0xea, 0x24, 0xe4, + 0xcc, 0x40, 0xa4, 0xf8, 0xc1, 0x24, 0x84, 0x04, 0x4b, 0x18, 0x27, 0x07, 0xe2, 0x44, 0x05, 0x20, + 0x95, 0x71, 0xcb, 0x17, 0x6f, 0x75, 0xb3, 0xf4, 0x1e, 0xcf, 0x85, 0x46, 0xa3, 0x39, 0x2a, 0x39, + 0x50, 0xd5, 0xb6, 0x16, 0x2b, 0x3c, 0x77, 0xc4, 0x82, 0xb2, 0xc1, 0x38, 0xd6, 0xa1, 0xf5, 0x37, + 0xab, 0x27, 0xf2, 0x7e, 0xff, 0x19, 0x6d, 0x8c, 0xa0, 0x80, 0xe9, 0x8f, 0x98, 0xd0, 0x91, 0xa5, + 0x84, 0xd5, 0x0f, 0x61, 0x4d, 0xc1, 0x08, 0x40, 0x1b, 0x68, 0x49, 0xe1, 0x80, 0xf1, 0x00, 0xab, + 0x41, 0x8a, 0x49, 0xa2, 0x89, 0x77, 0xc8, 0x62, 0x86, 0xd5, 0xa6, 0x0f, 0xbc, 0x48, 0x2a, 0xb3, + 0x63, 0x9c, 0x9b, 0xd4, 0xb7, 0x1e, 0x55, 0xf8, 0x5c, 0xdd, 0x3e, 0xf8, 0x50, 0xf6, 0xc1, 0xb3, + 0xe8, 0xe3, 0xb5, 0x1e, 0xc0, 0xe2, 0x4e, 0xb8, 0x6a, 0x5c, 0x1a, 0x06, 0xce, 0x58, 0x62, 0x0a, + 0x3e, 0x2f, 0x31, 0x30, 0xa4, 0x79, 0xa1, 0xa2, 0xd4, 0x6b, 0x6f, 0xb0, 0x30, 0x15, 0x9b, 0x33, + 0x60, 0x20, 0x0c, 0xc4, 0x19, 0x95, 0x98, 0xdb, 0xfc, 0x29, 0xf1, 0x92, 0x60, 0x56, 0x72, 0xa1, + 0x69, 0x82, 0x44, 0xf0, 0xf9, 0xc9, 0x04, 0x2e, 0x99, 0x51, 0xc3, 0xd6, 0x3f, 0x13, 0x57, 0x3c, + 0x40, 0xf2, 0x34, 0xa1, 0x33, 0x80, 0x58, 0xea, 0x40, 0x61, 0x02, 0x83, 0x54, 0xaf, 0xdf, 0xf0, + 0xa6, 0x8d, 0x0e, 0xb4, 0x02, 0xdc, 0x9f, 0x63, 0x5a, 0x97, 0xa9, 0x28, 0x5e, 0xff, 0x05, 0x25, + 0x56, 0x34, 0x3e, 0xe0, 0xfb, 0x0e, 0xb1, 0xc1, 0x18, 0x40, 0x45, 0xdc, 0x91, 0x98, 0xef, 0x8d, + 0x12, 0x50, 0x00, 0x0b, 0xb4, 0x9e, 0xc6, 0x0a, 0xc1, 0xca, 0x32, 0xf4, 0x21, 0xe3, 0x93, 0x84, + 0x6d, 0x60, 0x75, 0x7a, 0x34, 0x63, 0xfa, 0xaa, 0x1f, 0x82, 0x42, 0x36, 0x30, 0xc8, 0xd0, 0xa0, + 0x49, 0x57, 0x8f, 0x19, 0xc8, 0xc4, 0x98, 0xc7, 0x06, 0x36, 0xc6, 0x3d, 0x8f, 0xc1, 0x49, 0xd6, + 0x8d, 0xf4, 0x25, 0xe9, 0x8a, 0x38, 0xf0, 0xd0, 0x4f, 0xb1, 0x0f, 0x18, 0x10, 0x5b, 0x38, 0x9d, + 0x78, 0x2a, 0xb1, 0x16, 0x7a, 0xe3, 0xfa, 0x30, 0x27, 0x2a, 0x23, 0x2c, 0x16, 0xc6, 0x28, 0x77, + 0xc4, 0x85, 0x0e, 0xbb, 0xd2, 0x67, 0x93, 0x6f, 0x03, 0xd0, 0xa7, 0x11, 0xda, 0x0c, 0x12, 0x06, + 0x56, 0x87, 0xe4, 0x14, 0x01, 0x30, 0x20, 0x29, 0x75, 0x4f, 0x0c, 0x4c, 0x29, 0x20, 0x82, 0xa8, + 0xb8, 0xd0, 0xa9, 0x30, 0x30, 0x30, 0xb1, 0x80, 0x20, 0x67, 0x18, 0x3a, 0x48, 0x1b, 0x85, 0x0c, + 0x5d, 0xc1, 0x81, 0x77, 0xc2, 0x84, 0x80, 0x22, 0x52, 0xaa, 0x2a, 0x06, 0x34, 0x22, 0xfc, 0xd8, + 0x61, 0x82, 0x63, 0xa0, 0x41, 0xa8, 0x27, 0x4e, 0x82, 0x68, 0x00, 0x04, 0x5c, 0xb3, 0xe0, 0xa4, + 0xca, 0x74, 0x74, 0x36, 0x24, 0x4d, 0x8f, 0x44, 0x34, 0xa7, 0x29, 0xe6, 0xa6, 0xf8, 0x7f, 0x48, + 0xf0, 0x1c, 0x05, 0x42, 0x44, 0x10, 0x29, 0x49, 0x11, 0x0d, 0xa1, 0x09, 0x21, 0x26, 0x00, 0x2b, + 0x9e, 0x9c, 0x73, 0x45, 0x8b, 0xbf, 0xf8, 0x2c, 0x8f, 0x19, 0xec, 0x0c, 0x67, 0x37, 0x39, 0x79, + 0x85, 0x11, 0x0c, 0x01, 0xc0, 0x2c, 0x2e, 0xe3, 0xc3, 0x71, 0xd1, 0x4f, 0x03, 0x36, 0x6b, 0xd3, + 0xab, 0x22, 0xd1, 0x93, 0x63, 0xeb, 0x82, 0x42, 0xa4, 0x93, 0x52, 0xa5, 0x75, 0x8a, 0xba, 0xbf, + 0xd5, 0x87, 0xa2, 0x3f, 0xd5, 0xe5, 0xea, 0xff, 0x5f, 0x97, 0xc3, 0x94, 0x34, 0x34, 0x34, 0x3b, + 0x13, 0xfb, 0x6d, 0xf9, 0x3a, 0x3f, 0x49, 0xc1, 0x00, 0xa4, 0x94, 0x4c, 0x9c, 0x57, 0x3d, 0x0d, + 0x21, 0xd6, 0x25, 0xb4, 0xac, 0xa8, 0x25, 0x70, 0x15, 0x09, 0x80, 0x09, 0x59, 0x19, 0xf3, 0xc3, + 0xfc, 0x28, 0x7d, 0x60, 0x84, 0x44, 0xa0, 0x7b, 0x38, 0x1d, 0x4f, 0x3e, 0x05, 0x0d, 0x25, 0xcc, + 0x4a, 0x74, 0x63, 0xa3, 0x0e, 0x10, 0xc3, 0x7c, 0x16, 0x17, 0xc9, 0x66, 0x0d, 0x91, 0xf0, 0x24, + 0xe9, 0xcc, 0x8f, 0x8e, 0xc5, 0xa3, 0x17, 0x5d, 0x64, 0x45, 0x6d, 0xf0, 0x54, 0x6b, 0xb4, 0xc8, + 0xbf, 0x3c, 0xad, 0x15, 0x15, 0xa7, 0xe2, 0x21, 0x42, 0x2a, 0x11, 0x99, 0xdc, 0x4d, 0x2c, 0x95, + 0x9c, 0xd2, 0x75, 0x95, 0xcd, 0xa9, 0x0c, 0x20, 0xd1, 0x36, 0x0c, 0x15, 0xe4, 0x2b, 0xfc, 0x14, + 0xdf, 0x61, 0x49, 0xf8, 0x5b, 0x4c, 0xe4, 0xe7, 0x4b, 0x8a, 0xe2, 0x12, 0x3f, 0xcf, 0x10, 0x14, + 0x2b, 0x3d, 0xe1, 0xa9, 0xb5, 0x05, 0x93, 0x89, 0xe1, 0x8c, 0x58, 0x62, 0xd7, 0x33, 0xb5, 0xf0, + 0x5b, 0x6d, 0x52, 0x04, 0x50, 0x59, 0x58, 0x1b, 0x3a, 0xef, 0x12, 0x32, 0xdc, 0xa5, 0x12, 0x92, + 0x29, 0xba, 0x79, 0x63, 0x38, 0x64, 0x2c, 0xb2, 0x52, 0x11, 0x2f, 0x62, 0xd1, 0x02, 0x58, 0x78, + 0x2a, 0x91, 0x8c, 0xea, 0xa5, 0x63, 0x42, 0xcf, 0x3e, 0x55, 0xe1, 0x43, 0xf5, 0x99, 0x89, 0x93, + 0xa0, 0xd1, 0xe8, 0x11, 0xd9, 0xc6, 0x69, 0x9d, 0x7f, 0x04, 0x84, 0x63, 0x0c, 0xb0, 0x52, 0x06, + 0x68, 0xed, 0xf8, 0x4b, 0xc2, 0x21, 0x42, 0x87, 0x60, 0x92, 0x7b, 0xb9, 0x14, 0x8d, 0x99, 0x3c, + 0x24, 0xe5, 0x4f, 0x55, 0x5c, 0x23, 0x3c, 0x35, 0xa7, 0x74, 0x4c, 0x11, 0x84, 0x89, 0x05, 0x4e, + 0x20, 0x28, 0x47, 0x10, 0xd1, 0xb8, 0x58, 0xc7, 0x44, 0x43, 0xc0, 0x1f, 0x68, 0x4f, 0x31, 0xe5, + 0x52, 0xda, 0xd0, 0x68, 0xf7, 0xc2, 0x87, 0x0d, 0xc2, 0x11, 0x60, 0x6d, 0x52, 0x45, 0xd6, 0x47, + 0xd1, 0x64, 0xee, 0x7a, 0x4e, 0xf5, 0x0e, 0xdd, 0x58, 0x7e, 0xf3, 0x99, 0xd4, 0xf8, 0x52, 0x71, + 0x01, 0x8a, 0xda, 0x72, 0x58, 0xad, 0x03, 0x79, 0x66, 0x64, 0x38, 0xbd, 0x9e, 0x6f, 0xf3, 0xfc, + 0x45, 0xc1, 0x80, 0xac, 0x36, 0x1d, 0xa2, 0xa0, 0xa1, 0x6a, 0x44, 0x0e, 0x5b, 0xf2, 0x94, 0x43, + 0x44, 0x83, 0x51, 0x12, 0xa1, 0x71, 0x20, 0xac, 0x96, 0x01, 0x18, 0xb0, 0xe2, 0x1e, 0x6a, 0x13, + 0x1a, 0x1f, 0x1a, 0x0f, 0xa9, 0x2d, 0x32, 0x99, 0x78, 0x29, 0x19, 0x19, 0x68, 0x3d, 0x2e, 0x03, + 0xb1, 0x96, 0x96, 0x82, 0xbb, 0xbe, 0x30, 0xee, 0x63, 0x53, 0x2b, 0x0d, 0x2e, 0x90, 0x65, 0xe1, + 0x5b, 0x58, 0xc7, 0x53, 0xf0, 0x7e, 0x88, 0xe0, 0xd7, 0x39, 0x79, 0x69, 0xe0, 0xaf, 0xd7, 0x5b, + 0xbc, 0xc4, 0xa0, 0x00, 0x16, 0x13, 0x81, 0x48, 0x49, 0xaf, 0xc3, 0x10, 0x20, 0x15, 0x89, 0x60, + 0x56, 0xde, 0x8a, 0x36, 0x1a, 0x18, 0xa3, 0x00, 0x82, 0x22, 0x84, 0x3b, 0x7c, 0x15, 0xd8, 0x32, + 0x24, 0x9c, 0x37, 0x49, 0x50, 0x24, 0xb5, 0x01, 0x36, 0xca, 0x1e, 0x87, 0x03, 0x32, 0x7c, 0x29, + 0x40, 0x24, 0x68, 0x37, 0x97, 0x91, 0x22, 0x2e, 0xb3, 0xdc, 0xa0, 0xc3, 0x80, 0x18, 0x50, 0x31, + 0x31, 0xc0, 0x81, 0xa6, 0x91, 0xa6, 0x7a, 0x76, 0xe2, 0xda, 0xcb, 0x42, 0x5f, 0x03, 0x71, 0xb6, + 0x3e, 0x14, 0x22, 0xc0, 0x06, 0x25, 0x24, 0x16, 0x21, 0x09, 0xa4, 0x0b, 0xf2, 0xb9, 0x6c, 0xd3, + 0x87, 0xca, 0x3e, 0x35, 0x41, 0xaa, 0xfe, 0x0b, 0x04, 0x17, 0x87, 0x79, 0x16, 0x03, 0x55, 0x92, + 0x7b, 0x6a, 0xca, 0xbe, 0x1d, 0xa2, 0x44, 0xfe, 0x3a, 0x0f, 0x09, 0xe1, 0x01, 0x38, 0x00, 0x15, + 0x8e, 0x6c, 0x08, 0x90, 0xdc, 0x3b, 0x0d, 0xb7, 0xff, 0x0f, 0x9f, 0x03, 0x87, 0xd9, 0x1c, 0x21, + 0xce, 0x88, 0x6b, 0xdb, 0x9f, 0x15, 0x64, 0x6f, 0x4d, 0xa2, 0x43, 0xab, 0xfe, 0x16, 0xa9, 0x99, + 0x0c, 0x2a, 0x96, 0xd8, 0xae, 0x92, 0x69, 0xa8, 0x98, 0xc9, 0x55, 0xac, 0xd5, 0xe2, 0x07, 0xc9, + 0xd1, 0x9f, 0xe8, 0xb6, 0xfa, 0xb7, 0xdd, 0xed, 0xaa, 0xeb, 0xdf, 0x56, 0xae, 0xb8, 0xa6, 0xeb, + 0x5f, 0x57, 0xbe, 0x89, 0x15, 0x70, 0x50, 0x52, 0x33, 0x43, 0xba, 0x24, 0xe6, 0x2f, 0x82, 0xb2, + 0x30, 0x40, 0xbc, 0x10, 0x06, 0x3b, 0x83, 0xb0, 0xbc, 0x82, 0x19, 0x96, 0x4e, 0x31, 0x01, 0xce, + 0x43, 0xa8, 0xef, 0xf8, 0x50, 0xb0, 0xe3, 0x1f, 0x1b, 0x18, 0x30, 0x78, 0x96, 0xb0, 0x47, 0x9a, + 0xf1, 0x4a, 0x85, 0x83, 0x5b, 0xd0, 0xc6, 0x18, 0xd7, 0xfe, 0xa3, 0x70, 0xe0, 0xf8, 0x52, 0x89, + 0x90, 0xe6, 0x71, 0x75, 0x5a, 0xaa, 0x8b, 0x8c, 0x42, 0x30, 0xf1, 0x9e, 0x20, 0x29, 0x27, 0x1c, + 0xd2, 0x50, 0x53, 0x22, 0x22, 0xb5, 0xc9, 0x86, 0x02, 0x00, 0x97, 0xc3, 0x55, 0xc6, 0x10, 0x87, + 0x04, 0x07, 0x29, 0x1c, 0x7e, 0x0b, 0x6c, 0x02, 0xb2, 0x18, 0x75, 0x11, 0xe9, 0x19, 0x8a, 0x2e, + 0x61, 0x83, 0x88, 0xf0, 0x80, 0x50, 0xda, 0x18, 0x59, 0x3c, 0xc0, 0xc9, 0x88, 0xb7, 0x2d, 0x21, + 0xbe, 0x12, 0x0f, 0x52, 0xf5, 0x62, 0xfa, 0x05, 0x6d, 0x63, 0x7c, 0x5e, 0x20, 0x15, 0x95, 0x49, + 0xbe, 0x04, 0xf4, 0xaf, 0x2a, 0x83, 0xa3, 0x6e, 0xbb, 0xd0, 0x26, 0x88, 0x92, 0x2f, 0x12, 0x2a, + 0x43, 0xe3, 0x08, 0x46, 0x93, 0x40, 0x00, 0x46, 0x8e, 0x0c, 0x65, 0x61, 0x71, 0x7a, 0x4f, 0x1a, + 0x52, 0x56, 0xaa, 0x07, 0x48, 0x6c, 0xdc, 0xbc, 0x21, 0x24, 0xab, 0xc0, 0xab, 0x0d, 0x4f, 0x3a, + 0xb7, 0x9f, 0x0c, 0xac, 0xda, 0xb3, 0x2e, 0xcc, 0x46, 0x3f, 0x53, 0x7f, 0x88, 0x05, 0x90, 0xc4, + 0x1c, 0x4b, 0xd4, 0xb1, 0x4b, 0x4a, 0xb5, 0xdc, 0xb4, 0x75, 0xb5, 0x16, 0xef, 0x9f, 0xc4, 0x85, + 0x0a, 0x40, 0x15, 0x86, 0xca, 0x20, 0x9a, 0x14, 0x52, 0x81, 0xc8, 0x98, 0xce, 0x58, 0x3d, 0x50, + 0xe3, 0xd1, 0xb0, 0x11, 0x7a, 0xd0, 0x64, 0x16, 0xed, 0x8b, 0x0a, 0x8d, 0x99, 0xe3, 0xbc, 0x4c, + 0x28, 0x64, 0x9f, 0x08, 0x07, 0x1f, 0x60, 0x0e, 0x35, 0x1c, 0x7f, 0xa1, 0x2a, 0x9a, 0x80, 0x4d, + 0x5d, 0x6b, 0x28, 0x03, 0xc8, 0x20, 0x27, 0x43, 0xbf, 0x1a, 0x77, 0xf2, 0x15, 0x1d, 0x00, 0x10, + 0x64, 0xc3, 0x67, 0xa7, 0x45, 0xd2, 0xdf, 0xd0, 0x28, 0x99, 0x21, 0xb5, 0xbb, 0x00, 0xb4, 0xc8, + 0xed, 0x52, 0x94, 0xe6, 0x03, 0x07, 0xb4, 0x43, 0x78, 0x77, 0xe7, 0x45, 0x3f, 0x37, 0xae, 0x22, + 0x14, 0x23, 0xb1, 0xb6, 0x58, 0x7d, 0x27, 0x0f, 0x70, 0x43, 0xe8, 0x6c, 0x79, 0xd4, 0x44, 0xdb, + 0xb5, 0xe1, 0x81, 0x7f, 0x08, 0x85, 0x0a, 0x5c, 0xb9, 0x72, 0x98, 0xeb, 0x3d, 0xe3, 0x13, 0x44, + 0xd5, 0xae, 0x5a, 0xdf, 0xda, 0x19, 0xa0, 0x57, 0x76, 0x7c, 0x69, 0x3e, 0x0a, 0xb6, 0xb5, 0x36, + 0x8e, 0xa2, 0x75, 0x09, 0xac, 0x1e, 0xa8, 0xb4, 0x22, 0x2b, 0x23, 0x3d, 0x7c, 0x29, 0x33, 0x7c, + 0xbc, 0xc8, 0x0a, 0xfa, 0xc8, 0xce, 0x89, 0x43, 0xea, 0x4d, 0xd4, 0x65, 0xdf, 0x05, 0x56, 0xe7, + 0x6e, 0x8d, 0x3a, 0x66, 0x25, 0xa0, 0x19, 0xa0, 0x38, 0xff, 0x12, 0x0b, 0x0d, 0x54, 0x12, 0x95, + 0xdf, 0x9b, 0x84, 0x78, 0xd6, 0x61, 0x90, 0xfe, 0x31, 0xdb, 0xe0, 0xae, 0xf2, 0x4c, 0xde, 0x93, + 0x6f, 0x0c, 0xa6, 0xe2, 0xe8, 0x3a, 0x83, 0xac, 0x04, 0x10, 0xe7, 0x5e, 0x6b, 0x01, 0xdf, 0xf0, + 0xa1, 0x4d, 0x4c, 0x3b, 0x21, 0x88, 0xea, 0x89, 0xfc, 0x75, 0xae, 0x98, 0x75, 0x88, 0x92, 0x24, + 0x40, 0x8d, 0x88, 0xb6, 0x68, 0x8d, 0xe2, 0xb2, 0x25, 0xfe, 0x0a, 0xb2, 0x42, 0x8d, 0x04, 0x10, + 0xa9, 0x51, 0x7e, 0x9a, 0x00, 0x1e, 0xb9, 0xd0, 0x21, 0xa1, 0xf1, 0x32, 0x1d, 0xf8, 0x53, 0x45, + 0x60, 0xca, 0xbc, 0xfe, 0xc6, 0xe4, 0xac, 0x22, 0xdb, 0x8c, 0x1d, 0x83, 0xcf, 0x4d, 0xfe, 0x0a, + 0x8a, 0xd0, 0xa2, 0x83, 0xcb, 0x42, 0x01, 0x80, 0x6a, 0x32, 0x50, 0x26, 0x9c, 0x10, 0x71, 0xc1, + 0x57, 0x00, 0x58, 0xe0, 0x73, 0x32, 0x18, 0xf8, 0x90, 0xa7, 0x62, 0x2c, 0x0c, 0x06, 0x6a, 0x50, + 0x2a, 0x91, 0x45, 0x7c, 0xd8, 0x34, 0x28, 0x9b, 0x18, 0x41, 0xfa, 0x09, 0x00, 0x47, 0x05, 0x81, + 0x59, 0x04, 0xff, 0x0a, 0x10, 0xfd, 0x1d, 0x42, 0x87, 0xf2, 0xda, 0xd2, 0x60, 0xa9, 0x58, 0x66, + 0x24, 0x0e, 0x5a, 0x87, 0x31, 0x71, 0x5a, 0x7c, 0x12, 0xd0, 0x4c, 0x68, 0x26, 0xcf, 0x40, 0xd8, + 0x32, 0xd2, 0x3e, 0xf8, 0x78, 0x51, 0xf7, 0xac, 0xa8, 0x0c, 0xa6, 0x87, 0x3e, 0x47, 0xdc, 0x0a, + 0x48, 0x8e, 0xd0, 0xbf, 0xf8, 0x74, 0xae, 0x41, 0x03, 0x84, 0x82, 0xc3, 0xa8, 0x4f, 0x90, 0x61, + 0xd8, 0xcb, 0x60, 0xa0, 0x90, 0xf2, 0x0e, 0xc8, 0xf7, 0x48, 0x19, 0x3a, 0x68, 0x62, 0xaa, 0x97, + 0xb2, 0x7e, 0x14, 0x3e, 0xd1, 0x6b, 0x4f, 0x1b, 0x1c, 0x72, 0x51, 0xbe, 0x43, 0x6c, 0x47, 0xa9, + 0x02, 0x0c, 0x50, 0xcf, 0xae, 0x5f, 0x5d, 0x49, 0xc1, 0x09, 0x18, 0xd6, 0xce, 0xbe, 0xbd, 0x2f, + 0x57, 0xfa, 0xea, 0x6e, 0x62, 0x24, 0x94, 0xe4, 0x49, 0xcb, 0x4c, 0x9b, 0xf8, 0xd9, 0x70, 0x98, + 0x37, 0x18, 0xe6, 0x70, 0x20, 0x7b, 0x42, 0xc8, 0xa8, 0xd7, 0x5d, 0x15, 0x3d, 0x43, 0x22, 0x74, + 0x26, 0x41, 0x01, 0x72, 0x51, 0x9e, 0x78, 0x83, 0x43, 0x8a, 0x41, 0x1c, 0x0e, 0x5d, 0x03, 0x13, + 0x9a, 0x78, 0x21, 0x89, 0xc1, 0xcb, 0x7f, 0x12, 0x34, 0xa4, 0xcf, 0xad, 0x3f, 0xa5, 0xf4, 0x9d, + 0x4a, 0x22, 0x66, 0xfc, 0xd5, 0x94, 0xad, 0xca, 0x8f, 0x92, 0x6c, 0x90, 0x78, 0xf9, 0x1b, 0x62, + 0xda, 0x8e, 0x89, 0x21, 0x04, 0x50, 0x40, 0x5e, 0x08, 0x06, 0x25, 0x09, 0xd9, 0x35, 0x64, 0x55, + 0xa7, 0xfe, 0x0a, 0xaa, 0x6c, 0x32, 0x30, 0x4c, 0x27, 0xa6, 0xb1, 0xc1, 0x01, 0x84, 0x75, 0x47, + 0xde, 0x20, 0x29, 0x34, 0x19, 0x04, 0xa6, 0x4e, 0x1a, 0x88, 0x61, 0xd4, 0x1f, 0x2e, 0x1a, 0xa8, + 0x19, 0x8c, 0x65, 0xc9, 0x7e, 0x5c, 0x48, 0x90, 0x51, 0x32, 0x44, 0xae, 0x92, 0x2b, 0x27, 0xf8, + 0x52, 0x56, 0x64, 0x71, 0xa0, 0xbc, 0xb2, 0x66, 0xb1, 0x8d, 0x4c, 0x86, 0xfe, 0x8d, 0x93, 0x60, + 0xf4, 0x5a, 0x7f, 0x12, 0x14, 0x10, 0x4e, 0x2a, 0x48, 0x2c, 0x8b, 0x64, 0xe0, 0xad, 0xb7, 0x0c, + 0xff, 0xdd, 0x7d, 0xfd, 0x5a, 0x16, 0x9b, 0x78, 0xde, 0x0e, 0x7b, 0xf0, 0x76, 0xe2, 0x61, 0x41, + 0x25, 0x73, 0x85, 0xa2, 0x4d, 0x63, 0x5a, 0x08, 0x27, 0x65, 0xa2, 0x58, 0x86, 0x23, 0x74, 0x18, + 0x23, 0x35, 0x10, 0x37, 0x67, 0x7c, 0x64, 0x3a, 0x77, 0x09, 0xa1, 0x1c, 0x0f, 0xbb, 0xbd, 0xd9, + 0x06, 0x70, 0x00, 0xb0, 0xc9, 0xcd, 0x2a, 0x77, 0xae, 0x4b, 0xec, 0xa1, 0x80, 0x9e, 0xe6, 0x26, + 0x0a, 0xf6, 0x21, 0xdb, 0x1b, 0x70, 0x4a, 0x41, 0xbb, 0xe3, 0x23, 0x0b, 0xbe, 0x14, 0xc5, 0x5b, + 0x1b, 0x68, 0x06, 0x86, 0xa3, 0x39, 0xf9, 0x98, 0x41, 0xae, 0x08, 0x06, 0x01, 0x56, 0x8e, 0xfc, + 0x16, 0x5e, 0x10, 0x17, 0xd1, 0xf5, 0x47, 0x96, 0x10, 0x69, 0x70, 0xef, 0xc3, 0x89, 0x9a, 0x92, + 0x3a, 0xe2, 0x66, 0xc9, 0x5f, 0x88, 0x0a, 0x14, 0xa1, 0x80, 0xa7, 0x43, 0x88, 0x15, 0x96, 0xeb, + 0xae, 0x56, 0xd0, 0xd5, 0x93, 0x03, 0x60, 0xdc, 0xa0, 0xc3, 0x07, 0xff, 0xc1, 0x57, 0x6e, 0x58, + 0x34, 0x43, 0x40, 0xee, 0xf3, 0xab, 0xa5, 0xf8, 0x27, 0xcb, 0x44, 0xbe, 0x59, 0x66, 0xf8, 0x29, + 0xa9, 0x03, 0x01, 0x52, 0xf2, 0xf3, 0xf0, 0x1a, 0x64, 0x74, 0x82, 0xc3, 0x30, 0xa5, 0x1c, 0x9c, + 0x5c, 0x4c, 0x29, 0xca, 0x30, 0x4c, 0xcb, 0x74, 0xe1, 0x07, 0x2c, 0x8f, 0x9e, 0xd0, 0x36, 0xdc, + 0x18, 0x11, 0xe4, 0x0b, 0x28, 0xff, 0x05, 0x46, 0x95, 0x8e, 0xe0, 0xed, 0xba, 0x12, 0x6c, 0x77, + 0xef, 0x12, 0x0b, 0x0a, 0xa0, 0xd0, 0x8a, 0x53, 0x2c, 0x46, 0xad, 0x20, 0xc2, 0x12, 0x1c, 0xad, + 0x12, 0x73, 0x77, 0x88, 0x0b, 0x10, 0xb5, 0x7d, 0x1d, 0xf8, 0x52, 0x6c, 0xef, 0x1a, 0xd9, 0x8e, + 0x89, 0x81, 0x00, 0x54, 0x9c, 0xb0, 0x30, 0x16, 0x52, 0x01, 0x2f, 0x1c, 0x50, 0x16, 0x38, 0x70, + 0x6a, 0x37, 0xa6, 0x4d, 0x70, 0x40, 0x49, 0x7e, 0x0a, 0xe8, 0xe2, 0xe8, 0x09, 0xd3, 0x9d, 0x50, + 0x48, 0x1b, 0x11, 0xa2, 0x2f, 0x91, 0xf8, 0x2d, 0xb0, 0x1d, 0x8d, 0x0b, 0x86, 0x1d, 0xa2, 0x88, + 0x0e, 0x74, 0x71, 0xc4, 0x46, 0x09, 0x37, 0x1f, 0x10, 0x26, 0xa1, 0x6c, 0x29, 0x54, 0xf8, 0x2f, + 0x40, 0x62, 0xa9, 0xd3, 0xcd, 0x65, 0x44, 0xde, 0xc5, 0x50, 0x35, 0xcf, 0xae, 0x24, 0x20, 0x6d, + 0x76, 0x32, 0xa3, 0xa3, 0x80, 0x48, 0x75, 0x77, 0xe2, 0x41, 0x29, 0x63, 0x89, 0xb2, 0xf7, 0x10, + 0x50, 0x48, 0x35, 0x02, 0xaa, 0x2f, 0x82, 0xa2, 0x3a, 0x88, 0xad, 0xb7, 0xbc, 0xf2, 0x89, 0x64, + 0xca, 0xff, 0x2c, 0xc4, 0x13, 0x10, 0x55, 0xab, 0x69, 0xe3, 0x45, 0x2e, 0xc2, 0xa1, 0x51, 0x73, + 0x04, 0xb9, 0x31, 0xe7, 0x4c, 0x06, 0x60, 0xf0, 0x22, 0xc5, 0x04, 0xc5, 0x16, 0x0d, 0xd4, 0x10, + 0xcb, 0x6c, 0x98, 0xc5, 0xea, 0x38, 0x33, 0x69, 0xc2, 0x8a, 0xb0, 0xc9, 0x53, 0xc5, 0x34, 0x34, + 0x88, 0xae, 0xfe, 0x1f, 0x2d, 0xeb, 0xc1, 0x9d, 0xc1, 0x5d, 0x8a, 0x55, 0x90, 0x00, 0x1a, 0xf0, + 0x35, 0x0d, 0x21, 0x7c, 0xb4, 0x3b, 0xe7, 0x0c, 0x77, 0xb0, 0xc9, 0xe8, 0xd4, 0x9f, 0xf8, 0x30, + 0x90, 0x85, 0x34, 0x0e, 0x42, 0x1c, 0xe9, 0x5a, 0x64, 0xd8, 0x22, 0xa0, 0x85, 0xeb, 0xbd, 0x26, + 0x66, 0xb7, 0xd7, 0x0b, 0xe8, 0xa5, 0x55, 0x70, 0x45, 0x76, 0x0d, 0x55, 0xfe, 0x7a, 0xa4, 0x93, + 0x4d, 0x7f, 0xab, 0xfc, 0x12, 0x4e, 0xca, 0x1e, 0x71, 0x5f, 0x52, 0x25, 0x75, 0x7f, 0xab, 0x3e, + 0x09, 0x2c, 0xd9, 0xa3, 0x57, 0xae, 0x09, 0xcc, 0xb4, 0xa8, 0x08, 0x6e, 0x59, 0x42, 0xcb, 0x23, + 0x36, 0xf8, 0xd2, 0x0d, 0xc4, 0x40, 0x3d, 0xff, 0x6f, 0xc0, 0x11, 0x79, 0xa2, 0xc2, 0x8b, 0x81, + 0xdc, 0xe3, 0xfa, 0xca, 0x18, 0x43, 0xc9, 0x68, 0x19, 0x4f, 0xe2, 0x01, 0x58, 0x9f, 0xdc, 0x69, + 0x30, 0xc1, 0xb6, 0x70, 0xf3, 0x30, 0xd2, 0x23, 0x30, 0x2a, 0x63, 0x28, 0x6a, 0xbc, 0x15, 0x51, + 0x0f, 0x08, 0x47, 0x59, 0x19, 0x63, 0x72, 0x27, 0xfb, 0x58, 0x40, 0x65, 0xb7, 0x68, 0xec, 0x77, + 0xc4, 0x82, 0xa2, 0xb8, 0x40, 0x5a, 0x2a, 0x9a, 0xeb, 0xe9, 0x0f, 0xd9, 0x83, 0xa0, 0xcc, 0x70, + 0xc2, 0x02, 0xbc, 0x6a, 0x21, 0x8b, 0x98, 0xef, 0x10, 0x0a, 0x76, 0x6f, 0x56, 0xa9, 0x41, 0x99, + 0x9a, 0x13, 0x09, 0x9c, 0x5f, 0x18, 0x4a, 0x26, 0x38, 0xf5, 0xc9, 0xbc, 0x5b, 0x96, 0xd9, 0x66, + 0x46, 0x97, 0x89, 0x12, 0x0a, 0xc8, 0x9d, 0x73, 0x4a, 0xc3, 0x41, 0xb9, 0xe1, 0xdf, 0x11, 0x7b, + 0x7d, 0x2a, 0x5e, 0x14, 0x39, 0x02, 0x4d, 0xae, 0xe4, 0x88, 0x20, 0x56, 0xdc, 0xb1, 0xfb, 0x07, + 0x2c, 0x2f, 0xf3, 0x81, 0x50, 0x7c, 0x7b, 0xcf, 0xf0, 0xa1, 0xca, 0x3e, 0xf1, 0x83, 0x9d, 0x8a, + 0xd7, 0xa0, 0xea, 0x63, 0x77, 0xfb, 0x5a, 0xb3, 0xa4, 0x1c, 0xac, 0xe7, 0xf1, 0x01, 0x49, 0x6c, + 0x95, 0x04, 0x20, 0xac, 0xf4, 0x60, 0xa4, 0x40, 0x33, 0xc0, 0xc6, 0x01, 0xe8, 0xa6, 0xb5, 0x68, + 0x7e, 0x06, 0x80, 0x47, 0x8d, 0xb8, 0x88, 0x50, 0xdc, 0x23, 0xbd, 0x11, 0x52, 0xc0, 0x2c, 0xb8, + 0xa0, 0x29, 0xfd, 0xce, 0x25, 0x2f, 0xe2, 0x2a, 0xe7, 0x88, 0x57, 0xf8, 0x50, 0xa2, 0x20, 0x80, + 0x2a, 0x91, 0x04, 0xc4, 0x04, 0xbf, 0x40, 0x16, 0xd2, 0x71, 0xf0, 0x70, 0x3b, 0x82, 0xa1, 0x06, + 0xd0, 0xa9, 0x9f, 0xc2, 0x23, 0x73, 0x18, 0x90, 0x30, 0x76, 0xe8, 0xd2, 0x03, 0x35, 0x52, 0x06, + 0x19, 0x01, 0x6b, 0x41, 0xa5, 0x70, 0x44, 0xb0, 0x86, 0xfc, 0xdf, 0xaa, 0xbe, 0x26, 0x0a, 0xc9, + 0xdb, 0xf5, 0x54, 0x9e, 0x86, 0x46, 0x59, 0x43, 0xa7, 0x11, 0x0a, 0x64, 0xa1, 0xbc, 0x93, 0xa3, + 0xcc, 0xe7, 0x10, 0x5d, 0x49, 0x64, 0x16, 0x82, 0xbb, 0xfc, 0x22, 0x6e, 0xca, 0xc5, 0xa4, 0x5c, + 0x72, 0xdc, 0x19, 0x08, 0x3f, 0x12, 0x0a, 0x84, 0x84, 0x94, 0xe9, 0x99, 0x26, 0x06, 0x02, 0xb5, + 0xc0, 0xd8, 0xd0, 0xc1, 0x7c, 0x49, 0x60, 0x81, 0x5c, 0x4c, 0xcc, 0x45, 0xaf, 0x10, 0x14, 0x9b, + 0xe6, 0x6e, 0x07, 0xd2, 0x21, 0xd8, 0x7c, 0x20, 0xca, 0xf9, 0xa5, 0x5f, 0x47, 0x40, 0xdd, 0x5e, + 0x30, 0x58, 0x32, 0xf2, 0x0e, 0x78, 0x90, 0x57, 0x3d, 0xb2, 0x33, 0xb8, 0x3c, 0x22, 0x92, 0x87, + 0x4d, 0x1d, 0x98, 0xf3, 0x83, 0xef, 0x12, 0x14, 0x9c, 0x9a, 0xa8, 0x44, 0xba, 0xa9, 0x44, 0x65, + 0x61, 0xbb, 0x65, 0x18, 0xc8, 0xc5, 0x38, 0x09, 0x16, 0x7f, 0x12, 0x14, 0xa1, 0xe5, 0x3c, 0x6b, + 0xd3, 0xa2, 0x0d, 0x48, 0x94, 0x61, 0x8b, 0xfa, 0x2f, 0x3a, 0x80, 0xbb, 0xab, 0x31, 0xea, 0x2d, + 0xb4, 0x32, 0xcf, 0x82, 0x8a, 0x6e, 0x45, 0x6b, 0x3a, 0xe2, 0xd0, 0xec, 0x74, 0xf8, 0xcf, 0x10, + 0x14, 0xde, 0x61, 0xfb, 0xa0, 0x68, 0xcf, 0x0d, 0xa9, 0x8c, 0x5a, 0x08, 0x9c, 0x31, 0x84, 0x28, + 0x4f, 0x82, 0x6c, 0xb4, 0x58, 0xb3, 0x3d, 0xe8, 0xca, 0xdf, 0x05, 0x85, 0x5b, 0x46, 0x0c, 0xa6, + 0x80, 0x29, 0x21, 0xd8, 0x1c, 0x6c, 0x6a, 0x20, 0x38, 0x88, 0x53, 0x94, 0x85, 0x24, 0xf2, 0x22, + 0xbc, 0x71, 0xd2, 0x9b, 0xa9, 0x70, 0xb0, 0x31, 0x67, 0x82, 0x1b, 0x9c, 0xa9, 0x33, 0x21, 0x53, + 0xe3, 0x44, 0x5c, 0x0d, 0x0d, 0x03, 0x66, 0xe0, 0x31, 0x09, 0x58, 0x18, 0x69, 0xdd, 0xed, 0xb8, + 0x82, 0x87, 0xa5, 0x92, 0xaa, 0x8e, 0x3f, 0xfc, 0x61, 0x11, 0xdd, 0x27, 0x0c, 0xad, 0x14, 0x2a, + 0x08, 0x2a, 0x08, 0x67, 0x1a, 0x7e, 0xdb, 0x2d, 0x0f, 0x1c, 0xd9, 0xa6, 0x10, 0x74, 0x2d, 0x18, + 0x26, 0x3e, 0x33, 0x5a, 0x78, 0x78, 0xe7, 0x24, 0x80, 0x58, 0xfd, 0xd2, 0x8f, 0x41, 0xd1, 0x91, + 0x1b, 0xc0, 0xe5, 0xa2, 0x30, 0xfc, 0x5e, 0x8f, 0xeb, 0xd2, 0xf5, 0xcb, 0xe8, 0x91, 0x57, 0x57, + 0xfa, 0x2e, 0x2f, 0x9a, 0xfa, 0xbe, 0x13, 0xd5, 0x6c, 0x72, 0xc9, 0x83, 0xf5, 0x94, 0x9d, 0x5d, + 0x5c, 0x10, 0x57, 0x15, 0xe3, 0x58, 0xc7, 0x15, 0xaa, 0x96, 0x79, 0x22, 0xee, 0x08, 0x8c, 0x7d, + 0x91, 0x5f, 0x5f, 0x18, 0x30, 0xc3, 0xc8, 0x3c, 0x6c, 0x4e, 0x24, 0x43, 0x18, 0xbc, 0xdd, 0x18, + 0x40, 0x23, 0x9d, 0x7b, 0x80, 0x00, 0x23, 0xa7, 0x03, 0x91, 0x82, 0xb4, 0x68, 0xff, 0x12, 0x14, + 0x2a, 0x6c, 0x84, 0x36, 0x9d, 0x27, 0x0d, 0xa5, 0x75, 0xd8, 0x9d, 0x5d, 0x3f, 0x1d, 0x10, 0x13, + 0x29, 0x6f, 0x21, 0x78, 0x91, 0x27, 0x09, 0x13, 0x11, 0x5b, 0x94, 0x56, 0x83, 0x39, 0xa0, 0x86, + 0x87, 0xac, 0x16, 0xfc, 0x15, 0x5e, 0xce, 0x8c, 0xa7, 0x9e, 0x8c, 0x21, 0x71, 0x47, 0xe1, 0x8d, + 0x73, 0xfc, 0x16, 0x1e, 0xd1, 0x8e, 0xe3, 0x96, 0xc1, 0x50, 0xfb, 0x02, 0x91, 0xe3, 0xb7, 0xc1, + 0x74, 0x93, 0xc6, 0x2d, 0x8c, 0x63, 0x35, 0x43, 0x22, 0xb1, 0xa3, 0x41, 0xd8, 0xf8, 0x2c, 0x33, + 0x6b, 0x4a, 0xb6, 0x07, 0x28, 0x82, 0x68, 0x74, 0x82, 0xd3, 0x37, 0xe2, 0x04, 0x04, 0x4b, 0x3e, + 0x50, 0x33, 0x54, 0x8d, 0xfa, 0xb3, 0xf0, 0xa0, 0x86, 0xc8, 0x63, 0x2a, 0x92, 0x83, 0xfa, 0x75, + 0x93, 0x4f, 0xda, 0xc5, 0xe6, 0x4e, 0x20, 0x40, 0x50, 0x4a, 0x09, 0x14, 0x94, 0xb1, 0x56, 0x7e, + 0x96, 0xfa, 0x29, 0x08, 0x13, 0x66, 0x25, 0x9c, 0x40, 0xfa, 0x99, 0xc1, 0xe8, 0x3a, 0x9c, 0x6d, + 0xe4, 0x8b, 0x13, 0x0a, 0x4b, 0x66, 0x5e, 0xac, 0x61, 0x34, 0x21, 0x53, 0x4c, 0xb5, 0xa9, 0x04, + 0x05, 0xec, 0xab, 0xa8, 0x23, 0xd4, 0x00, 0x02, 0x6a, 0xbc, 0x44, 0xc9, 0x93, 0x89, 0x82, 0xed, + 0x86, 0x87, 0x1a, 0xee, 0xe3, 0x63, 0x5c, 0x1c, 0x82, 0xc1, 0x31, 0x30, 0x55, 0x28, 0x69, 0x14, + 0x60, 0x4c, 0x43, 0x60, 0xb7, 0x21, 0xde, 0x76, 0x53, 0xf1, 0x30, 0x5d, 0x15, 0x95, 0x87, 0x39, + 0x63, 0x32, 0xea, 0xde, 0x11, 0x05, 0x72, 0x5e, 0xa6, 0x61, 0xca, 0xa1, 0xab, 0x26, 0x27, 0xef, + 0x50, 0xc7, 0x3f, 0x88, 0x04, 0xd5, 0x43, 0xc4, 0xea, 0xdb, 0x3d, 0x37, 0xf8, 0x50, 0x94, 0x7c, + 0x88, 0x98, 0xf6, 0xe8, 0x03, 0x4c, 0xac, 0x29, 0x14, 0x16, 0x20, 0xb2, 0x48, 0xa7, 0x9d, 0x6f, + 0x12, 0x14, 0x2c, 0x99, 0x9d, 0xf2, 0xab, 0x4d, 0x26, 0x39, 0x12, 0x32, 0x81, 0x9a, 0xd3, 0x06, + 0x0e, 0xe7, 0x89, 0x14, 0x66, 0x95, 0x55, 0x57, 0xe2, 0x01, 0x51, 0x4e, 0xa1, 0xa8, 0xe0, 0xf6, + 0xc0, 0x4b, 0xbe, 0xbb, 0x57, 0xa0, 0xc9, 0x94, 0xde, 0x6d, 0xf0, 0xa6, 0x8e, 0xdd, 0x12, 0xea, + 0x38, 0xc5, 0xac, 0x41, 0xc0, 0x34, 0x0a, 0x81, 0xb4, 0x40, 0x4e, 0x00, 0x2f, 0x04, 0x01, 0x84, + 0xfb, 0x43, 0xbb, 0xe1, 0x48, 0xc0, 0x83, 0x1f, 0xc9, 0xc4, 0x9b, 0x6b, 0x8d, 0x10, 0xd0, 0x0a, + 0xd2, 0xa6, 0x8a, 0x06, 0xa8, 0x78, 0x68, 0x17, 0xb8, 0xf5, 0x2b, 0xf2, 0x2e, 0x1b, 0x30, 0x75, + 0x7c, 0x28, 0x70, 0xd4, 0x1e, 0xf6, 0xb3, 0xb0, 0x20, 0x60, 0x37, 0x41, 0x04, 0xfb, 0x35, 0xcc, + 0x58, 0x20, 0x26, 0x58, 0x1a, 0x39, 0x64, 0x9e, 0xe1, 0x75, 0xa3, 0xb9, 0x02, 0x60, 0xc1, 0x4b, + 0xe2, 0x01, 0x61, 0x13, 0x24, 0xa3, 0xba, 0x23, 0x40, 0x2c, 0x5e, 0x4e, 0x71, 0x0b, 0x46, 0xf9, + 0x19, 0xf5, 0x12, 0x32, 0xbc, 0x28, 0x57, 0x70, 0xe2, 0x24, 0xd5, 0x21, 0xb3, 0x68, 0x28, 0x00, + 0x05, 0xa0, 0x50, 0xe9, 0xa4, 0x71, 0x7f, 0xe8, 0x6b, 0x07, 0x82, 0x8b, 0x7c, 0x2a, 0x65, 0xa2, + 0x34, 0x10, 0x51, 0xb2, 0xf8, 0x30, 0x27, 0xc0, 0x8e, 0x41, 0xb3, 0xbe, 0x80, 0xa2, 0x87, 0x31, + 0x7f, 0xfc, 0x14, 0x47, 0xb0, 0xea, 0x54, 0xd7, 0xcc, 0xc0, 0xae, 0xc1, 0x43, 0xdf, 0x05, 0x77, + 0x43, 0x4d, 0xf1, 0xaf, 0xd8, 0x2b, 0xbb, 0x4e, 0x60, 0x2f, 0xc1, 0x69, 0x58, 0x3a, 0xe3, 0x88, + 0xa5, 0x1f, 0x22, 0xa5, 0x42, 0x21, 0xbe, 0x0f, 0x12, 0x14, 0xd4, 0xcf, 0x9e, 0xe6, 0x87, 0xaa, + 0x4b, 0x11, 0xa7, 0xe3, 0x4a, 0x78, 0xe3, 0x14, 0xf8, 0x52, 0xac, 0x6c, 0xa8, 0x8f, 0xb5, 0x25, + 0x86, 0x90, 0x42, 0xc1, 0x8f, 0x15, 0x38, 0x7e, 0x12, 0x0c, 0x2a, 0xf4, 0xf4, 0xd4, 0x05, 0x03, + 0xdb, 0xe3, 0x46, 0x72, 0xc2, 0x8b, 0xa2, 0x88, 0x13, 0x01, 0x16, 0x30, 0x56, 0xf1, 0x1e, 0x41, + 0xd8, 0x62, 0xa0, 0x30, 0x37, 0x10, 0x4c, 0xe6, 0x0f, 0x4a, 0x1e, 0x82, 0xff, 0x1b, 0x1a, 0x11, + 0x59, 0x43, 0x77, 0x02, 0x67, 0x8d, 0x96, 0x4f, 0x50, 0xf1, 0xeb, 0x76, 0x23, 0x23, 0x96, 0x23, + 0xf4, 0x4d, 0x68, 0x33, 0x7b, 0x19, 0xea, 0xb0, 0xc9, 0x81, 0x70, 0x65, 0x83, 0xb3, 0x39, 0x52, + 0x27, 0x2e, 0x7f, 0xc6, 0x9c, 0x7c, 0x1c, 0x05, 0xa2, 0x06, 0xaa, 0x87, 0x5e, 0x1b, 0xde, 0x8a, + 0x81, 0xb0, 0x35, 0x20, 0x4a, 0x69, 0xc0, 0x34, 0x35, 0xc9, 0x20, 0xe3, 0xe0, 0x8c, 0xdd, 0x9e, + 0x64, 0x8e, 0x3b, 0xbf, 0xfd, 0x4c, 0x9f, 0x57, 0x7d, 0x48, 0x9f, 0x5e, 0xfa, 0xf7, 0xd6, 0xab, + 0xaf, 0x5f, 0x3f, 0x5f, 0x69, 0xa4, 0x92, 0xf5, 0x8b, 0xe6, 0x99, 0x94, 0x36, 0x34, 0xd7, 0x25, + 0xb5, 0xc9, 0xd7, 0xbe, 0x08, 0x05, 0x4d, 0x01, 0x2e, 0xca, 0x34, 0xd6, 0xe9, 0x54, 0xcb, 0x75, + 0x34, 0xd9, 0xb7, 0xfc, 0x48, 0x74, 0xa6, 0x10, 0x44, 0xbc, 0xa8, 0x44, 0xa7, 0x81, 0x85, 0xa9, + 0x3e, 0x79, 0xb3, 0xbb, 0x6c, 0x92, 0x32, 0xff, 0x94, 0xcf, 0x44, 0xb8, 0x6d, 0xc1, 0x7f, 0x8c, + 0xb7, 0xab, 0x2b, 0x97, 0xd8, 0x94, 0xa4, 0x55, 0x00, 0xa9, 0x52, 0xb2, 0x17, 0x10, 0x14, 0x2b, + 0xc4, 0x9e, 0x41, 0x78, 0xa3, 0xc2, 0x00, 0xa0, 0x91, 0xaf, 0x42, 0xa3, 0x78, 0x9f, 0xae, 0x32, + 0x45, 0xf3, 0xf8, 0x80, 0xa5, 0x8c, 0x6d, 0x92, 0x1a, 0x3a, 0x69, 0x3d, 0xbf, 0xd9, 0x8d, 0xc4, + 0x34, 0x04, 0x8d, 0x53, 0xa3, 0x6e, 0xb7, 0x2f, 0x4c, 0x7b, 0x4a, 0xf8, 0xe2, 0xed, 0xa6, 0x50, + 0x58, 0xe0, 0x43, 0xba, 0x3d, 0x13, 0xc6, 0x0b, 0x9d, 0x40, 0x3e, 0x0a, 0x73, 0x02, 0x00, 0xa1, + 0x29, 0x1e, 0x3b, 0x1d, 0x6e, 0x56, 0x32, 0x25, 0xf7, 0x13, 0x05, 0x24, 0x0e, 0x21, 0xc0, 0x69, + 0x6c, 0x37, 0xb6, 0x83, 0x4a, 0x8b, 0x4e, 0x8e, 0xf1, 0x10, 0x43, 0x56, 0x15, 0x04, 0x65, 0x08, + 0xef, 0x12, 0x24, 0x11, 0x4a, 0x10, 0x04, 0x60, 0x20, 0x6e, 0xd2, 0x8f, 0xe2, 0x41, 0x59, 0x35, + 0x04, 0x01, 0x7a, 0x86, 0x88, 0x34, 0xed, 0xde, 0xed, 0xb5, 0x5f, 0x05, 0x35, 0xc6, 0x05, 0x43, + 0xd8, 0x9f, 0x9b, 0xc9, 0x94, 0x0b, 0xb3, 0xb7, 0x89, 0x18, 0x53, 0xb0, 0x57, 0xaf, 0x1a, 0x2d, + 0x65, 0xe4, 0x16, 0x88, 0x1b, 0x7c, 0x9e, 0xd6, 0xa2, 0x2c, 0xe8, 0xf2, 0x82, 0x02, 0xb1, 0xe2, + 0x20, 0xa6, 0x46, 0x05, 0x8d, 0x8c, 0x35, 0x82, 0x7e, 0x8c, 0xac, 0xb1, 0x43, 0x86, 0x16, 0x31, + 0x72, 0xe2, 0x61, 0x42, 0xb1, 0x15, 0xd9, 0x44, 0x36, 0x1e, 0x9d, 0xaf, 0x40, 0x1b, 0x21, 0xd7, + 0xd2, 0xea, 0xa9, 0x57, 0x85, 0x35, 0xba, 0x83, 0xe4, 0x94, 0x58, 0x43, 0x5a, 0xd2, 0x55, 0x3a, + 0x8a, 0xa9, 0xaf, 0x26, 0x8f, 0x46, 0x33, 0xa0, 0x63, 0x06, 0x88, 0x72, 0x35, 0x5e, 0x0b, 0x23, + 0x81, 0x0f, 0x02, 0xd5, 0x1a, 0x19, 0x29, 0x12, 0x03, 0x23, 0x87, 0xba, 0x0c, 0xe8, 0xe1, 0xc4, + 0x05, 0x2c, 0x48, 0x82, 0xf9, 0x25, 0xdd, 0x01, 0xa6, 0xe0, 0xd1, 0x14, 0xd4, 0xf7, 0x44, 0x34, + 0x4b, 0x1b, 0x18, 0x8b, 0x61, 0x09, 0x87, 0x88, 0x04, 0x66, 0x96, 0xbf, 0xdf, 0x04, 0x7a, 0x6c, + 0x91, 0x3b, 0xe0, 0x84, 0xe4, 0x0d, 0xa0, 0x34, 0x46, 0x76, 0xbe, 0x0a, 0x66, 0x06, 0xe4, 0x44, + 0x92, 0x2d, 0xca, 0xf5, 0xa3, 0x17, 0x05, 0x71, 0xe0, 0xaa, 0x94, 0x1a, 0xd8, 0x30, 0xd2, 0x20, + 0x9e, 0xf4, 0x27, 0x7f, 0x12, 0x0a, 0xca, 0xf0, 0xe9, 0x86, 0x23, 0xa0, 0x70, 0x0b, 0x80, 0x6a, + 0x20, 0x4b, 0x43, 0x77, 0x0b, 0x69, 0x89, 0xbe, 0x3b, 0xf0, 0x57, 0x18, 0x66, 0xc3, 0x99, 0xe3, + 0x54, 0xf1, 0xe1, 0xc3, 0xa2, 0x6f, 0x10, 0x14, 0x8c, 0x3c, 0x88, 0x1e, 0x03, 0x48, 0xbb, 0x2d, + 0x44, 0x1c, 0x04, 0x8f, 0xc2, 0x6c, 0x08, 0x16, 0x04, 0x01, 0xa0, 0x65, 0x9c, 0x64, 0x54, 0xe8, + 0x30, 0x68, 0x37, 0x82, 0x0a, 0x45, 0xc4, 0x85, 0x21, 0x61, 0xd7, 0xe8, 0x87, 0xae, 0x9a, 0x05, + 0x42, 0xc4, 0x2d, 0x18, 0x5a, 0x00, 0x03, 0x53, 0x92, 0xa8, 0x6f, 0x79, 0x5d, 0x0c, 0x01, 0x3d, + 0xcf, 0x85, 0x2e, 0x18, 0x2c, 0xca, 0xa8, 0xe0, 0x11, 0x01, 0x02, 0x3a, 0x99, 0x6e, 0xaa, 0x9e, + 0x32, 0x47, 0xfa, 0xbe, 0xef, 0xcc, 0x21, 0x14, 0x68, 0x45, 0xfc, 0x65, 0xc8, 0x4d, 0x80, 0xfd, + 0x4d, 0x7d, 0x6e, 0xea, 0x85, 0xd0, 0x0b, 0x01, 0xa8, 0x1b, 0x14, 0x1d, 0x2a, 0xda, 0x19, 0x60, + 0xdc, 0x91, 0x0d, 0xfc, 0x48, 0x21, 0x97, 0x9e, 0x41, 0x00, 0x44, 0xc8, 0x27, 0xc8, 0x39, 0x78, + 0x81, 0xc4, 0x34, 0x86, 0x2f, 0xe8, 0x05, 0xc1, 0x80, 0xa1, 0xd7, 0x63, 0x64, 0x6b, 0xfc, 0xe5, + 0xac, 0x7b, 0x3d, 0x7f, 0xe1, 0x12, 0x20, 0x09, 0x29, 0x57, 0x93, 0xe3, 0x2a, 0xc6, 0x81, 0x09, + 0xfc, 0x68, 0xad, 0x21, 0xb8, 0x00, 0x06, 0x57, 0x10, 0x90, 0xae, 0x90, 0xd4, 0xba, 0xa8, 0x52, + 0xce, 0x61, 0xc9, 0x02, 0x37, 0x85, 0xfa, 0xe7, 0xa6, 0xe9, 0x54, 0xf3, 0x38, 0xac, 0xaa, 0xe9, + 0xff, 0x8d, 0x3c, 0x48, 0x9b, 0x6a, 0xe1, 0xdb, 0x90, 0x9b, 0xb3, 0xed, 0x51, 0xea, 0x0d, 0xe2, + 0x6a, 0xd2, 0xde, 0x81, 0xce, 0x69, 0x8c, 0x2d, 0x0b, 0x4a, 0xa5, 0xab, 0x7e, 0xba, 0xe5, 0x7d, + 0x6b, 0xeb, 0x15, 0xf5, 0xef, 0x96, 0xd5, 0x24, 0x42, 0x79, 0xa7, 0x82, 0x08, 0x1b, 0xf2, 0x24, + 0x01, 0x5f, 0x0c, 0x99, 0xa6, 0x98, 0xbd, 0x4a, 0x41, 0x9d, 0xd7, 0xf8, 0x80, 0x4d, 0x21, 0x8d, + 0x0d, 0x56, 0xbe, 0xf9, 0x23, 0x19, 0x55, 0x52, 0xf8, 0x29, 0x12, 0x56, 0x21, 0xd7, 0x9b, 0xcd, + 0xcf, 0x4a, 0xed, 0xf4, 0x6b, 0xfc, 0x29, 0x0a, 0x0a, 0x43, 0xdf, 0x90, 0x83, 0x48, 0xb0, 0xc0, + 0xc7, 0x82, 0x0d, 0x19, 0xc6, 0xb0, 0xc4, 0xb0, 0x01, 0x43, 0x7f, 0xdf, 0x5a, 0x2a, 0x44, 0xe8, + 0xd2, 0xce, 0xff, 0x0a, 0x0d, 0x70, 0xc1, 0x89, 0xe1, 0x41, 0x01, 0x1b, 0x04, 0x06, 0x8c, 0xab, + 0xe0, 0xde, 0xed, 0x65, 0x07, 0xc9, 0xd0, 0xc3, 0xc0, 0x7f, 0x41, 0x39, 0xf0, 0x42, 0x65, 0x43, + 0xee, 0x78, 0x90, 0x59, 0x7b, 0x9d, 0xce, 0x5e, 0xfa, 0xba, 0xbe, 0x8e, 0xf1, 0x10, 0x43, 0xd5, + 0x38, 0xb8, 0x88, 0x28, 0xb9, 0xf0, 0xad, 0x7b, 0x4c, 0x20, 0x23, 0x48, 0x93, 0x38, 0xb8, 0x81, + 0x01, 0x48, 0x81, 0x62, 0xcb, 0xf2, 0xc1, 0x5c, 0x8a, 0x31, 0x0d, 0x1e, 0xf3, 0x30, 0xcf, 0xe3, + 0xbc, 0x4c, 0x29, 0x46, 0x21, 0x1c, 0x7a, 0x97, 0x9f, 0xd7, 0xb3, 0x9e, 0x9b, 0x8e, 0x21, 0x0a, + 0xce, 0x93, 0x38, 0x00, 0x05, 0xce, 0x20, 0x40, 0x29, 0x24, 0x8c, 0x16, 0x15, 0x3b, 0xe3, 0xc6, + 0xb4, 0x94, 0x5d, 0xe0, 0xdf, 0xe1, 0x42, 0xba, 0xea, 0x78, 0x8c, 0x23, 0x0e, 0xa4, 0x64, 0x6c, + 0x60, 0xc1, 0x99, 0x0e, 0x11, 0x4d, 0x67, 0x00, 0x44, 0xfb, 0xf1, 0x22, 0x02, 0x99, 0xe7, 0x06, + 0x32, 0x98, 0x1c, 0x26, 0x3a, 0x72, 0x42, 0x02, 0x37, 0xf5, 0xc4, 0xc1, 0x59, 0x25, 0x46, 0x98, + 0xf4, 0x60, 0xee, 0xc5, 0x8d, 0xb4, 0x6d, 0x7b, 0xe0, 0xae, 0x9a, 0x11, 0x72, 0xcb, 0x6f, 0xaa, + 0xf1, 0x1d, 0xf8, 0xc1, 0x21, 0x65, 0xd1, 0x78, 0x76, 0x8c, 0xd6, 0x63, 0xaf, 0xad, 0x86, 0x15, + 0xe5, 0xc5, 0x20, 0xa0, 0xf1, 0x71, 0xa3, 0x43, 0xfb, 0x04, 0x1f, 0x04, 0x33, 0x75, 0x29, 0xe6, + 0x8e, 0x55, 0xfd, 0x72, 0xf8, 0x25, 0xb0, 0x1c, 0x6d, 0x04, 0xb6, 0x60, 0x40, 0x16, 0x3b, 0x8b, + 0xe0, 0xaa, 0xc0, 0xec, 0x9d, 0x50, 0xde, 0xfb, 0xfd, 0xe2, 0x04, 0xd4, 0x67, 0x04, 0xf1, 0xcc, + 0x00, 0x17, 0xbe, 0x24, 0x14, 0x4f, 0x09, 0x45, 0x5f, 0x8e, 0x83, 0x02, 0xe7, 0xc4, 0x4c, 0x8c, + 0xe8, 0x69, 0x65, 0x10, 0x19, 0x14, 0x62, 0x63, 0x22, 0xbc, 0x7d, 0x78, 0x6c, 0x49, 0xe6, 0x34, + 0x98, 0x2f, 0x6a, 0xf6, 0x19, 0x7a, 0x98, 0x40, 0xfe, 0x14, 0x2b, 0xc1, 0x02, 0xbc, 0x57, 0x39, + 0x4d, 0x07, 0x04, 0xa9, 0xfc, 0x5f, 0x40, 0x28, 0x13, 0x3b, 0x45, 0x61, 0x29, 0x15, 0xc9, 0x46, + 0x60, 0x16, 0x3b, 0x00, 0xe4, 0x23, 0xb6, 0xf0, 0x49, 0xbe, 0x0a, 0x49, 0xa1, 0xb0, 0x33, 0x5e, + 0x61, 0xa6, 0xe3, 0x62, 0xe3, 0xbc, 0x2b, 0x87, 0x89, 0x05, 0x64, 0x60, 0x63, 0xa1, 0x10, 0xb0, + 0x68, 0x8a, 0xc0, 0x85, 0x82, 0xe4, 0x81, 0x9e, 0xac, 0xe8, 0xdb, 0xc4, 0x82, 0x92, 0x65, 0x83, + 0xe7, 0x20, 0xa7, 0x5d, 0xaf, 0x78, 0x90, 0xa1, 0xf2, 0xb0, 0x86, 0xaa, 0xaa, 0x7c, 0xcb, 0x49, + 0x98, 0xc3, 0x54, 0xf2, 0x94, 0x5f, 0x10, 0x5b, 0xcc, 0x4d, 0xd0, 0x3c, 0xe0, 0x83, 0xe1, 0x21, + 0x59, 0x49, 0x5a, 0x68, 0xd9, 0x3e, 0x1d, 0x21, 0x1b, 0x63, 0xb3, 0x8f, 0xe8, 0x77, 0xb4, 0x84, + 0x32, 0x4a, 0x6a, 0x5e, 0xf4, 0xe5, 0x9a, 0x7f, 0xe8, 0x4c, 0x65, 0x73, 0x1e, 0xaa, 0xbe, 0x09, + 0x0d, 0x55, 0x79, 0x5f, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x27, 0x13, 0xb0, 0x32, + 0x80, 0xd1, 0xc5, 0x8d, 0xda, 0x6b, 0x69, 0xa1, 0xbc, 0xc6, 0x75, 0x75, 0x08, 0xf2, 0x94, 0x5c, + 0x5c, 0x5c, 0x5c, 0x1a, 0xf0, 0xf4, 0x8c, 0x29, 0x18, 0x92, 0x71, 0x3f, 0x06, 0x2a, 0x82, 0xec, + 0xd2, 0x33, 0x2b, 0x6d, 0x13, 0x65, 0x8a, 0x23, 0x46, 0xf8, 0x80, 0xc0, 0x50, 0x20, 0x2e, 0x84, + 0xb4, 0x1c, 0x8b, 0xab, 0x06, 0xc8, 0x2a, 0xc3, 0x51, 0xa7, 0x18, 0xeb, 0xa6, 0x40, 0x34, 0x82, + 0xfc, 0x06, 0x68, 0xaa, 0x31, 0x84, 0xfa, 0xce, 0x11, 0x2a, 0x99, 0x98, 0x35, 0xaa, 0x23, 0x38, + 0xc8, 0x57, 0x04, 0x71, 0xa8, 0xd4, 0x2e, 0x20, 0x30, 0x09, 0xb9, 0xc6, 0x0d, 0x2c, 0x61, 0x9c, + 0x07, 0xe3, 0x08, 0x04, 0x9a, 0xca, 0x03, 0xb0, 0x6b, 0x84, 0x42, 0x90, 0x60, 0x2c, 0xa5, 0x90, + 0x2e, 0x51, 0xa8, 0x2c, 0x41, 0x28, 0xbc, 0xc9, 0xe0, 0x00, 0x1b, 0x88, 0x42, 0x34, 0x40, 0x5a, + 0xcb, 0x3b, 0x72, 0xd6, 0x23, 0xa4, 0x17, 0xd6, 0x26, 0x27, 0x3e, 0x14, 0x92, 0x34, 0x0a, 0xb1, + 0xae, 0x58, 0xc9, 0xc6, 0x99, 0xc2, 0xc4, 0x51, 0x8a, 0x32, 0xc1, 0x8a, 0x0c, 0xe7, 0xc9, 0x9b, + 0x9b, 0x25, 0xe8, 0x6d, 0xcb, 0xe5, 0x29, 0x39, 0x79, 0x3b, 0x78, 0x6f, 0x9e, 0x3a, 0xae, 0xee, + 0xfe, 0x12, 0xe0, 0xa8, 0x24, 0x56, 0x4b, 0xea, 0x9d, 0x69, 0xa0, 0xd6, 0x93, 0xfd, 0xf0, 0xa4, + 0x56, 0x28, 0x30, 0xb6, 0x12, 0x58, 0x38, 0x18, 0x97, 0x0f, 0xe3, 0x33, 0xde, 0x44, 0x83, 0xd6, + 0x58, 0xc9, 0x5a, 0x49, 0xe3, 0xdf, 0x57, 0xe2, 0x20, 0x8c, 0x68, 0x14, 0x5e, 0xf3, 0x96, 0xc0, + 0x34, 0xdf, 0xb7, 0xaf, 0x96, 0xca, 0x07, 0x69, 0xb9, 0xa8, 0x9a, 0x03, 0x3f, 0x4e, 0x2a, 0xaa, + 0xbc, 0x20, 0x20, 0x3e, 0x29, 0xed, 0xdd, 0xdd, 0xd8, 0xec, 0x76, 0x9c, 0x28, 0x83, 0xbd, 0x2a, + 0xb9, 0xb5, 0x3f, 0xe1, 0x00, 0xc4, 0x0c, 0x86, 0x4c, 0x62, 0x80, 0x26, 0xf4, 0xb0, 0xc0, 0x56, + 0x82, 0x0c, 0x4a, 0x1c, 0x61, 0x28, 0xe9, 0x62, 0x03, 0x2c, 0x3c, 0xb2, 0x9d, 0x17, 0x52, 0xd3, + 0xfc, 0x48, 0x80, 0x46, 0x52, 0xe4, 0xa3, 0xe6, 0x35, 0x97, 0x77, 0xca, 0x3c, 0x56, 0x2b, 0x15, + 0x8a, 0xc2, 0xfd, 0x62, 0xae, 0xa4, 0xbe, 0x89, 0x07, 0xd5, 0xa2, 0xba, 0x2a, 0x65, 0xea, 0x99, + 0x2e, 0xb1, 0x71, 0x10, 0xbc, 0x5c, 0x9c, 0x5c, 0xfb, 0x29, 0x47, 0xc5, 0x4c, 0x9d, 0x85, 0xff, + 0x0c, 0x0c, 0x0a, 0x1f, 0x8c, 0xe3, 0x25, 0x6a, 0x7e, 0x15, 0xba, 0x25, 0x1e, 0x7f, 0xa7, 0x66, + 0x36, 0x9c, 0xe0, 0x16, 0x04, 0x5b, 0xc1, 0x2d, 0xf7, 0xc4, 0x85, 0x24, 0x82, 0x60, 0xb6, 0x89, + 0xd0, 0x7a, 0xc5, 0xdd, 0x8f, 0x90, 0x48, 0x75, 0x59, 0x2a, 0xaa, 0x89, 0x92, 0xa9, 0xd2, 0xec, + 0xb6, 0xfe, 0x7c, 0x13, 0x17, 0xbb, 0x6f, 0xb7, 0x29, 0xca, 0x75, 0xfb, 0xe8, 0x22, 0x54, 0xbe, + 0x61, 0x51, 0x27, 0x86, 0xd7, 0x1a, 0x66, 0x21, 0x75, 0xc4, 0x0c, 0x18, 0xed, 0x97, 0xd6, 0x68, + 0xb4, 0x49, 0xc4, 0x92, 0x2d, 0xd4, 0x95, 0x59, 0x8d, 0x4d, 0x6c, 0xcd, 0x98, 0x97, 0x82, 0x9d, + 0x15, 0x5d, 0x95, 0x33, 0x19, 0x84, 0x86, 0x5e, 0xb9, 0x28, 0x62, 0x20, 0xa4, 0x49, 0x20, 0x64, + 0x99, 0x5b, 0x7f, 0x10, 0xf7, 0x84, 0x01, 0x56, 0xab, 0xff, 0x10, 0x14, 0x9e, 0x72, 0x3e, 0xc2, + 0x9a, 0x53, 0x31, 0x99, 0xde, 0xf7, 0x4b, 0x11, 0xd3, 0xc4, 0x02, 0x93, 0x17, 0x97, 0x99, 0x24, + 0x8c, 0x2d, 0xc6, 0x28, 0xf5, 0xa5, 0x97, 0x84, 0x01, 0x59, 0xee, 0x0a, 0x27, 0x45, 0x45, 0x5b, + 0x47, 0x98, 0x9c, 0x28, 0x93, 0xb5, 0x2d, 0x5f, 0xb3, 0xf2, 0x19, 0xe8, 0x5e, 0x12, 0x74, 0x66, + 0x1e, 0xbd, 0x3f, 0x42, 0x52, 0xaf, 0x54, 0xcb, 0xd7, 0xbe, 0xbd, 0xc4, 0xc1, 0x24, 0x7f, 0x21, + 0xb3, 0xa2, 0x51, 0x07, 0x4a, 0xc8, 0xca, 0x38, 0x80, 0x80, 0xd1, 0xc0, 0xe3, 0xf3, 0xe9, 0x01, + 0xc6, 0xe5, 0x81, 0x9c, 0x1f, 0x93, 0x64, 0xb3, 0xd6, 0x65, 0xec, 0x12, 0x35, 0x40, 0x42, 0x15, + 0x17, 0x8a, 0x10, 0x16, 0xe6, 0x60, 0xb0, 0x5e, 0x9b, 0x9b, 0xf1, 0x03, 0x39, 0x54, 0x6a, 0x83, + 0x1d, 0x1f, 0x6f, 0x8d, 0x5e, 0x71, 0xb8, 0x54, 0xa8, 0x8e, 0x41, 0xb4, 0x41, 0xc4, 0xf9, 0xe7, + 0x9d, 0x4a, 0x4a, 0x56, 0x3e, 0x20, 0x13, 0x5f, 0xc7, 0x70, 0x3a, 0xfa, 0xcb, 0x2f, 0xe5, 0xb7, + 0xf7, 0x90, 0x7a, 0x4c, 0x40, 0x22, 0x24, 0x0e, 0x10, 0x9c, 0x2f, 0xbe, 0x14, 0x3b, 0x70, 0xe5, + 0x8c, 0x57, 0x08, 0x8a, 0x16, 0x2e, 0x4d, 0x8c, 0x14, 0x1d, 0x18, 0x87, 0xa1, 0x7f, 0xf8, 0x27, + 0x24, 0x6c, 0x00, 0x05, 0x85, 0x48, 0xd9, 0xd5, 0xeb, 0x82, 0xd1, 0x84, 0x88, 0x42, 0x2b, 0x60, + 0x2a, 0xc4, 0xe0, 0x62, 0x5c, 0x97, 0x9f, 0xd7, 0x0c, 0x04, 0x42, 0xc1, 0x12, 0xb6, 0xde, 0xc0, + 0x1f, 0x71, 0x68, 0xb7, 0x7f, 0x5d, 0xfb, 0xae, 0xca, 0x41, 0x69, 0x07, 0x4a, 0x0d, 0x16, 0x9f, + 0x97, 0xa2, 0xbc, 0x21, 0xd5, 0x3b, 0x7d, 0x08, 0x7f, 0xa2, 0xbc, 0x9d, 0x1c, 0xbc, 0x93, 0xa2, + 0x39, 0x13, 0x89, 0x04, 0xc3, 0x00, 0x2e, 0xc7, 0x0f, 0x61, 0xf2, 0x75, 0xb8, 0xf4, 0xb5, 0xaf, + 0x04, 0x04, 0xf5, 0xb3, 0x91, 0x2d, 0x43, 0x6c, 0x80, 0x04, 0x36, 0x24, 0x41, 0x53, 0x44, 0xab, + 0x2f, 0x1f, 0xfb, 0x0a, 0xb7, 0x15, 0x5d, 0xc2, 0x6e, 0x02, 0xe0, 0x00, 0x43, 0x2c, 0x2a, 0x3c, + 0xc1, 0x50, 0x00, 0x21, 0x2a, 0xd0, 0x8f, 0x55, 0x74, 0x2c, 0x78, 0xf3, 0xac, 0xa0, 0x3a, 0x00, + 0xad, 0x58, 0x4a, 0xf2, 0xd0, 0x00, 0xaa, 0x7a, 0xcf, 0xb2, 0xb2, 0xe2, 0x04, 0x82, 0x9f, 0x67, + 0xbe, 0xcf, 0x7a, 0xac, 0xaa, 0x47, 0x87, 0x5f, 0x62, 0x74, 0x1c, 0x47, 0xfb, 0xe8, 0x27, 0xff, + 0xa9, 0x5f, 0xe2, 0x10, 0xe1, 0xdb, 0xe0, 0xa4, 0xd2, 0x29, 0xa7, 0x20, 0x40, 0x16, 0xeb, 0x51, + 0x75, 0x57, 0xf8, 0x25, 0x1e, 0x87, 0x2f, 0x3d, 0x17, 0xe7, 0x5e, 0x0a, 0x35, 0x04, 0xbb, 0x5e, + 0xbd, 0xfb, 0x04, 0x40, 0xab, 0x86, 0xd3, 0xaf, 0x16, 0x3b, 0x44, 0x07, 0x70, 0x94, 0x49, 0xc0, + 0xb8, 0x78, 0x3e, 0x12, 0xb0, 0xff, 0x82, 0x9a, 0x43, 0x6a, 0x08, 0xd4, 0x1d, 0x2a, 0xe8, 0x1a, + 0x91, 0xb9, 0x53, 0xe0, 0x63, 0xff, 0xd1, 0x52, 0x6b, 0x9a, 0x69, 0x42, 0x45, 0xa7, 0x09, 0x0b, + 0x72, 0x41, 0x57, 0x1d, 0x27, 0xdc, 0xae, 0x10, 0x12, 0x0a, 0x82, 0x78, 0xea, 0x3d, 0x00, 0x00, + 0xbc, 0x20, 0x00, 0x13, 0x95, 0x16, 0x8f, 0x0e, 0x71, 0xf2, 0x90, 0x73, 0x21, 0xc7, 0xe0, 0x90, + 0xad, 0xe5, 0x08, 0x04, 0x89, 0x7d, 0x12, 0xab, 0xa3, 0x41, 0xf0, 0x45, 0x77, 0x55, 0x94, 0x77, + 0x5c, 0x3e, 0x84, 0xb9, 0x7d, 0x5a, 0xfa, 0xb8, 0x2f, 0x46, 0x64, 0xbd, 0x09, 0x2a, 0x5f, 0x51, + 0xdb, 0xe0, 0x90, 0x44, 0xde, 0xc3, 0x8b, 0x88, 0x10, 0x08, 0x04, 0x53, 0x4a, 0xe5, 0x18, 0x2f, + 0x6d, 0x61, 0x3d, 0xde, 0xf7, 0x55, 0xab, 0xf8, 0x52, 0x54, 0x09, 0x68, 0x6e, 0x00, 0x34, 0xd0, + 0xa8, 0x12, 0x85, 0x88, 0xf7, 0x1d, 0x58, 0x5c, 0xb9, 0xa1, 0x6f, 0x42, 0xb1, 0x52, 0x83, 0x86, + 0x1d, 0x18, 0x82, 0x74, 0xc5, 0xa0, 0xd1, 0x82, 0x36, 0x12, 0xa6, 0x4f, 0x3f, 0x8f, 0x07, 0xe2, + 0x04, 0x45, 0x80, 0xf5, 0x24, 0x89, 0xc9, 0x37, 0x12, 0x11, 0x08, 0x1b, 0xb0, 0x47, 0xa2, 0x41, + 0x38, 0xd3, 0x42, 0x27, 0xbd, 0xdd, 0xf1, 0xeb, 0x90, 0x0c, 0x52, 0x59, 0xff, 0x04, 0x81, 0x57, + 0x7d, 0x20, 0x78, 0x24, 0xe2, 0xe2, 0xe5, 0x45, 0x5c, 0x48, 0xc0, 0xb5, 0x05, 0x1e, 0x04, 0x0c, + 0x40, 0xf1, 0x47, 0x7e, 0x84, 0x14, 0x06, 0xa1, 0x0d, 0x1b, 0xbf, 0x85, 0x06, 0x8e, 0x2e, 0x77, + 0x0a, 0x20, 0x87, 0x12, 0x70, 0xb2, 0xd9, 0xe9, 0x01, 0x3d, 0xc8, 0x0e, 0x99, 0xea, 0x8d, 0x7a, + 0x13, 0xc2, 0x00, 0x8e, 0xc7, 0x7e, 0x0a, 0xfc, 0x8c, 0x68, 0x66, 0x96, 0x1b, 0x43, 0x77, 0x6d, + 0xf7, 0xc1, 0x20, 0xa3, 0x84, 0x02, 0xb1, 0x18, 0x77, 0xc2, 0x51, 0x54, 0xb0, 0x1a, 0x61, 0x61, + 0x17, 0x12, 0xe0, 0xe2, 0xd7, 0x86, 0x02, 0x28, 0x26, 0x70, 0x7d, 0x48, 0xdc, 0x23, 0x5e, 0xfa, + 0x35, 0x7d, 0x7b, 0xeb, 0x85, 0x74, 0x77, 0x47, 0xf4, 0x76, 0x2f, 0xa2, 0x39, 0x13, 0xd1, 0x26, + 0x7d, 0x1c, 0xe9, 0x7d, 0x4e, 0x92, 0x74, 0x4a, 0xfa, 0x96, 0xe2, 0x44, 0x82, 0x21, 0x50, 0x6a, + 0x3c, 0xab, 0x44, 0xb7, 0xf8, 0xd2, 0x3e, 0xc1, 0xe0, 0x1e, 0x2c, 0x4d, 0x04, 0xa0, 0x0a, 0xc3, + 0xc1, 0xef, 0x88, 0x80, 0x9e, 0x38, 0x7b, 0x84, 0xa0, 0x38, 0xdf, 0x8b, 0x21, 0xe2, 0x0e, 0xb9, + 0x5f, 0xaa, 0xaa, 0x27, 0x02, 0x08, 0x11, 0xc1, 0xeb, 0xe4, 0x7c, 0x90, 0xf8, 0x50, 0xc8, 0x40, + 0x65, 0xad, 0x03, 0x15, 0x5a, 0x2c, 0x0f, 0x59, 0x49, 0x63, 0x2b, 0x54, 0xc9, 0x7e, 0x26, 0xa9, + 0x39, 0xc1, 0x81, 0x49, 0x1b, 0x13, 0xc6, 0x1c, 0x87, 0x98, 0xe4, 0x25, 0x77, 0xdc, 0x21, 0x0c, + 0x14, 0x20, 0x62, 0xcb, 0x27, 0x90, 0x98, 0x5c, 0x85, 0x43, 0xbc, 0xe8, 0x96, 0xca, 0x85, 0x3c, + 0x1c, 0xf2, 0xab, 0x73, 0x6a, 0x7f, 0xe0, 0xb3, 0xb6, 0x27, 0x86, 0x98, 0x9c, 0x01, 0xda, 0x21, + 0x8f, 0xb0, 0xfb, 0x11, 0xe5, 0xf9, 0x2a, 0xf1, 0x92, 0x7a, 0x7a, 0x6e, 0x3f, 0x93, 0xeb, 0x9a, + 0xa9, 0x06, 0x0f, 0xc4, 0x82, 0x4d, 0x6d, 0xbb, 0x89, 0x8b, 0xb0, 0x0d, 0x52, 0x0e, 0x04, 0x6c, + 0xdd, 0x9e, 0x26, 0x20, 0xe0, 0x1b, 0x85, 0xa6, 0x01, 0xfb, 0x74, 0xc4, 0xc8, 0xc2, 0xea, 0x37, + 0xce, 0xc5, 0xc5, 0x6c, 0xb8, 0x90, 0x42, 0x2c, 0x38, 0x63, 0x79, 0x02, 0x7c, 0x46, 0xed, 0x8d, + 0x55, 0x6c, 0xec, 0x3e, 0x8a, 0x41, 0x62, 0x17, 0xe8, 0x45, 0x7d, 0x1c, 0x89, 0xf5, 0xc2, 0x7e, + 0xbd, 0xf5, 0x78, 0x53, 0xaf, 0x57, 0x58, 0xa4, 0xe8, 0x85, 0x4f, 0xa9, 0xd2, 0xf8, 0x24, 0x8e, + 0x80, 0x29, 0x88, 0xb6, 0x0f, 0x0f, 0x12, 0x14, 0x14, 0x36, 0x60, 0xd1, 0xa6, 0x0c, 0xa3, 0xe1, + 0xd6, 0x85, 0x56, 0x82, 0x99, 0x44, 0xe8, 0xdc, 0x4a, 0xda, 0x56, 0x51, 0x0a, 0xa6, 0xec, 0x3c, + 0x06, 0x48, 0xf9, 0x56, 0x4e, 0xc1, 0xa8, 0x38, 0x88, 0x50, 0xd9, 0x70, 0xb8, 0xd8, 0x6c, 0x00, + 0x3a, 0x17, 0x20, 0xb1, 0x20, 0x4f, 0x70, 0xf7, 0x0b, 0x37, 0x64, 0x01, 0x2c, 0x40, 0xf7, 0xdc, + 0x7f, 0x85, 0x3a, 0xc0, 0xf5, 0xa3, 0xcf, 0x05, 0x3f, 0xde, 0xd3, 0x7e, 0x14, 0x1c, 0xca, 0x4b, + 0xec, 0x79, 0x45, 0xff, 0xf1, 0x10, 0xa1, 0x55, 0x42, 0x1c, 0xf4, 0x44, 0xb1, 0xb8, 0x8b, 0xcf, + 0xa4, 0x54, 0xdd, 0x2c, 0xe6, 0x35, 0x75, 0xa0, 0xc1, 0x0d, 0xbc, 0x60, 0xdf, 0x71, 0x30, 0xa4, + 0x5d, 0x64, 0xc8, 0xf7, 0x9b, 0x25, 0xcc, 0x89, 0xd6, 0x29, 0xfe, 0xad, 0xdd, 0x05, 0x57, 0x2c, + 0xa1, 0xf8, 0x19, 0x86, 0x63, 0x34, 0xe7, 0x07, 0x6f, 0x85, 0x3a, 0x33, 0x97, 0xc4, 0x0a, 0x86, + 0xa4, 0x2a, 0x83, 0x87, 0x27, 0x8f, 0xa2, 0x30, 0x69, 0x91, 0x01, 0x5c, 0x50, 0xff, 0x7c, 0x14, + 0x13, 0x76, 0x57, 0x77, 0xc5, 0xf0, 0x95, 0x40, 0x5d, 0x79, 0x1c, 0x31, 0xbd, 0xcb, 0xde, 0xbc, + 0x0e, 0x3b, 0x5a, 0x02, 0xc4, 0x09, 0x04, 0x21, 0x16, 0x71, 0x0a, 0x4b, 0xbc, 0x39, 0xca, 0xae, + 0xa9, 0xe2, 0x3a, 0x12, 0x3a, 0xbe, 0x8c, 0xd7, 0xd6, 0xa3, 0x7a, 0xb4, 0x57, 0x53, 0x2c, 0xfa, + 0x8e, 0xdf, 0x44, 0xca, 0xfa, 0x2a, 0x74, 0xf1, 0x20, 0xb0, 0x74, 0x40, 0x30, 0x2b, 0x14, 0xec, + 0x71, 0x02, 0x20, 0x36, 0x2b, 0x27, 0x1a, 0x16, 0x3f, 0x3e, 0x14, 0xa3, 0x6b, 0xcd, 0x68, 0xc2, + 0xcc, 0x31, 0xff, 0xc1, 0x08, 0x79, 0x63, 0x3f, 0x14, 0x6b, 0xa9, 0x19, 0xc3, 0xe8, 0x67, 0xb9, + 0xaf, 0x85, 0x0a, 0xdc, 0x05, 0xaa, 0xac, 0x95, 0x65, 0xb2, 0xda, 0x4a, 0xc5, 0x78, 0x97, 0x18, + 0x79, 0xfc, 0x40, 0x2e, 0x24, 0xac, 0xaa, 0x4a, 0xaa, 0xff, 0x19, 0x76, 0x17, 0x89, 0xd0, 0xbc, + 0xee, 0x45, 0x29, 0x97, 0x8b, 0x89, 0xb0, 0x5e, 0xab, 0x17, 0xf1, 0x87, 0x50, 0x85, 0x23, 0xee, + 0xb9, 0x4f, 0x70, 0x9d, 0x06, 0x05, 0xd4, 0x84, 0x5e, 0xce, 0x38, 0xcb, 0x59, 0xe5, 0xcd, 0x0f, + 0x10, 0x67, 0xc1, 0x16, 0xdc, 0x56, 0x2b, 0x7f, 0x8a, 0x14, 0x82, 0x11, 0x20, 0xac, 0x42, 0xf1, + 0x71, 0x07, 0xf1, 0x20, 0x98, 0x26, 0xf0, 0xc0, 0xa7, 0x4f, 0x37, 0xd8, 0x2a, 0x31, 0x00, 0x13, + 0xec, 0x20, 0x8b, 0x2a, 0x73, 0xeb, 0x5f, 0xea, 0x3b, 0x2f, 0xd4, 0x85, 0x13, 0xd5, 0x32, 0x3f, + 0x51, 0xf5, 0x74, 0x43, 0x1b, 0xea, 0x95, 0x0d, 0xe0, 0x8e, 0xb5, 0xb1, 0xf5, 0x4a, 0xfd, 0x65, + 0x37, 0x5a, 0xbe, 0x3c, 0x29, 0x3b, 0xa4, 0x07, 0x9c, 0x22, 0x02, 0x4a, 0xd1, 0x5f, 0x8e, 0x1a, + 0x3b, 0x1e, 0x44, 0x61, 0x91, 0x24, 0x83, 0xe1, 0x42, 0xaf, 0xf5, 0x8f, 0x0f, 0x0a, 0xc7, 0x93, + 0xe7, 0x0e, 0x17, 0x09, 0xc1, 0x6a, 0x34, 0x00, 0x7c, 0x90, 0x94, 0x3c, 0x48, 0xb4, 0x40, 0xb4, + 0xc0, 0x7f, 0x00, 0xe4, 0xb8, 0x66, 0x19, 0xa0, 0x2d, 0x45, 0x24, 0x0e, 0xd1, 0xe1, 0x40, 0xf8, + 0xe7, 0x11, 0x1c, 0xe6, 0x3c, 0x40, 0x2c, 0xa8, 0xba, 0xcb, 0x34, 0x31, 0x7c, 0x2e, 0xb8, 0x38, + 0xcc, 0xac, 0x0a, 0x30, 0xbd, 0xba, 0xda, 0x7f, 0x12, 0x14, 0x9f, 0x29, 0xb6, 0x76, 0x2f, 0x75, + 0x8b, 0x8f, 0x60, 0x25, 0x89, 0x04, 0x99, 0x63, 0x0a, 0x77, 0xd5, 0x87, 0x88, 0x0f, 0x7c, 0x12, + 0x1e, 0xaa, 0xbd, 0xc4, 0x46, 0x65, 0x52, 0x31, 0xaa, 0xc7, 0x04, 0x0b, 0xc5, 0x76, 0x0d, 0x5d, + 0x65, 0x1b, 0xc7, 0x1c, 0x1e, 0x04, 0x05, 0xe4, 0x68, 0x7e, 0x22, 0xcc, 0x72, 0x7c, 0x56, 0xff, + 0x12, 0x09, 0x48, 0x4b, 0x41, 0x6c, 0xb3, 0x01, 0xef, 0xe2, 0x01, 0x37, 0xa6, 0x65, 0xc1, 0xe5, + 0xec, 0x53, 0xbc, 0x9d, 0x04, 0xd3, 0xbf, 0x54, 0xa7, 0xd4, 0x89, 0x7d, 0x5c, 0x04, 0xba, 0x23, + 0xfd, 0x52, 0x2f, 0x21, 0x15, 0x7f, 0x57, 0xfa, 0xa6, 0x4f, 0xa2, 0xb4, 0x5f, 0x56, 0x1e, 0x11, + 0x08, 0x66, 0x4d, 0x29, 0x58, 0xa1, 0x26, 0xec, 0x1c, 0x4d, 0x83, 0x40, 0xbf, 0xc6, 0x91, 0xc0, + 0x04, 0x00, 0x08, 0xce, 0x12, 0xa8, 0x7b, 0x45, 0x0f, 0xb7, 0xfc, 0xb7, 0xad, 0x48, 0xfb, 0xc7, + 0x40, 0x0d, 0xd8, 0x90, 0x57, 0x45, 0x52, 0x34, 0xe1, 0x8a, 0x8f, 0xbd, 0x3b, 0xe8, 0xe0, 0x41, + 0x7c, 0x98, 0xd4, 0x3a, 0x2c, 0x62, 0xaa, 0x38, 0x51, 0xe2, 0xe0, 0x2a, 0xd8, 0x2d, 0x82, 0x58, + 0x6d, 0x89, 0x9e, 0x2a, 0x77, 0x24, 0x3f, 0xc2, 0x91, 0x07, 0xc8, 0x27, 0xb6, 0x3c, 0x52, 0x0b, + 0x3a, 0xad, 0xbd, 0xe4, 0x86, 0xb8, 0xca, 0xa3, 0x31, 0xec, 0xf0, 0x41, 0xb0, 0x56, 0xf6, 0x4a, + 0x08, 0x0c, 0x8c, 0x49, 0xad, 0xe1, 0xd6, 0xa5, 0xab, 0x7d, 0x44, 0xfe, 0xd3, 0xe5, 0x87, 0xdf, + 0x05, 0x67, 0xcc, 0x04, 0x3c, 0x06, 0xf0, 0x00, 0x0c, 0x27, 0x79, 0x78, 0xfa, 0xf0, 0x37, 0xcf, + 0xe2, 0x46, 0x90, 0xf8, 0x06, 0xa3, 0x61, 0xc0, 0xab, 0x09, 0x14, 0x02, 0x01, 0x64, 0xca, 0x01, + 0x3c, 0x1c, 0x1d, 0x02, 0x92, 0xd6, 0x1c, 0x54, 0x01, 0x21, 0xca, 0x74, 0xb2, 0x20, 0x05, 0x71, + 0x4a, 0x4a, 0x96, 0xfc, 0xb5, 0xe2, 0x06, 0xa8, 0x11, 0x03, 0x18, 0x03, 0x54, 0xd7, 0x3f, 0xf5, + 0x4a, 0x0c, 0x9e, 0x94, 0x1e, 0x7d, 0x6c, 0xe4, 0x23, 0x42, 0x88, 0xb6, 0x73, 0xfe, 0x5f, 0x67, + 0xc4, 0x85, 0x0a, 0x74, 0x18, 0x27, 0xcc, 0xcf, 0x16, 0x38, 0x09, 0xe5, 0x3d, 0x8c, 0x88, 0xa5, + 0x31, 0x1a, 0x50, 0x65, 0xa2, 0x86, 0x8d, 0xc3, 0xce, 0x25, 0x89, 0x21, 0x30, 0xb5, 0x63, 0x98, + 0xf8, 0x7f, 0x0f, 0x2d, 0x5d, 0xde, 0x53, 0xfd, 0x6f, 0xcb, 0x26, 0xb9, 0x85, 0xdf, 0xbc, 0x40, + 0x2b, 0x3b, 0x20, 0xed, 0x71, 0x65, 0xce, 0x92, 0x51, 0x6b, 0x23, 0x4a, 0xad, 0x3f, 0xb9, 0xaf, + 0xa7, 0x0f, 0x04, 0xbc, 0xaa, 0x34, 0x04, 0xac, 0xfc, 0x38, 0x90, 0x56, 0x28, 0x6b, 0xe5, 0xb8, + 0x08, 0x51, 0xde, 0xe0, 0xef, 0xe7, 0x09, 0x89, 0x71, 0xe3, 0x3a, 0x0c, 0xa5, 0x84, 0x3a, 0x10, + 0xc9, 0x3a, 0x3e, 0x11, 0x7d, 0x0b, 0x73, 0xe8, 0x50, 0xee, 0x3e, 0x0b, 0x05, 0x1b, 0xd0, 0x0d, + 0x8a, 0x6c, 0x5d, 0xdd, 0x32, 0xec, 0x19, 0x5e, 0xbc, 0x8e, 0xfc, 0x29, 0x43, 0x1a, 0x63, 0x82, + 0xa6, 0x38, 0x22, 0xe0, 0xf7, 0x3c, 0x2d, 0x27, 0x71, 0x08, 0x60, 0x30, 0x8f, 0x10, 0x34, 0x85, + 0x05, 0xb2, 0x16, 0x4e, 0x2c, 0x7b, 0xcc, 0x56, 0x4f, 0x60, 0xe9, 0x42, 0xfc, 0x52, 0xa6, 0x0f, + 0xdc, 0xe7, 0xdf, 0xb0, 0x00, 0x07, 0x0a, 0x0a, 0xa6, 0x1d, 0xf5, 0x56, 0x65, 0x09, 0x9d, 0xd0, + 0x1d, 0x8b, 0x57, 0xa2, 0x4c, 0x31, 0x6e, 0xa7, 0x88, 0x0a, 0x08, 0x6d, 0x1e, 0xd0, 0x12, 0x04, + 0xe4, 0xcb, 0xfe, 0x5c, 0xf4, 0xd8, 0x0b, 0x12, 0x4e, 0xed, 0x17, 0xb9, 0xf0, 0x52, 0x25, 0x2c, + 0xac, 0x67, 0xc6, 0xe2, 0xdc, 0xf9, 0xbf, 0xc3, 0xc4, 0x8a, 0x85, 0x13, 0xe0, 0x6f, 0x65, 0xdb, + 0xd0, 0x9a, 0xc0, 0x7c, 0x6b, 0x38, 0xc2, 0xaf, 0x8b, 0xd3, 0x78, 0x09, 0x45, 0x5f, 0xf9, 0xb8, + 0x98, 0x94, 0xaf, 0xff, 0xda, 0x93, 0x78, 0x81, 0x92, 0x71, 0xdc, 0xac, 0xa1, 0x82, 0xc8, 0x51, + 0xb3, 0x41, 0x93, 0x7f, 0x3c, 0x1e, 0xb0, 0x62, 0x46, 0x82, 0x82, 0x9d, 0x05, 0xcc, 0x12, 0x2d, + 0x38, 0x91, 0x88, 0x02, 0x7f, 0xf3, 0x30, 0xc5, 0xf6, 0xc7, 0x8c, 0x09, 0x65, 0x93, 0x48, 0xe5, + 0xc5, 0x1e, 0xa3, 0xd5, 0xe0, 0xac, 0xf9, 0x86, 0x2a, 0x47, 0x64, 0x2b, 0x00, 0x2c, 0xc2, 0xdb, + 0xb6, 0xe6, 0xfb, 0xfd, 0x16, 0x13, 0xe0, 0x88, 0x62, 0x71, 0x37, 0xc3, 0xe1, 0x0a, 0xc5, 0xd4, + 0xe8, 0x4e, 0xc0, 0x9e, 0x08, 0x79, 0xb3, 0x25, 0xb2, 0x4d, 0x16, 0x43, 0xd0, 0x45, 0x32, 0x0a, + 0xf4, 0x4a, 0xfa, 0xe5, 0xf0, 0x47, 0xad, 0x60, 0x97, 0xab, 0xd7, 0x57, 0x97, 0xab, 0xfd, 0x72, + 0xae, 0xb9, 0xcf, 0xa2, 0x63, 0x2b, 0xa3, 0xa5, 0x0e, 0x24, 0x12, 0x1b, 0x28, 0xc1, 0x71, 0xd8, + 0xe3, 0xe2, 0x01, 0x0e, 0x2e, 0x39, 0xa6, 0x8e, 0xf8, 0x90, 0xa1, 0x1d, 0xdd, 0xdc, 0xb6, 0x2b, + 0x6c, 0x89, 0xda, 0x0d, 0xd8, 0x18, 0x9c, 0x34, 0x46, 0x5e, 0x14, 0x34, 0xd9, 0x24, 0x1f, 0xe3, + 0x5e, 0x1b, 0x8a, 0x10, 0x63, 0x26, 0x15, 0x48, 0x17, 0x3e, 0x75, 0x20, 0x89, 0x07, 0xc1, 0xc0, + 0x1b, 0x7c, 0x5d, 0x3e, 0x6d, 0x69, 0x1f, 0x15, 0x67, 0xc2, 0x96, 0x10, 0x4b, 0x32, 0xf0, 0x73, + 0x68, 0xa7, 0x87, 0x36, 0xad, 0xc7, 0x44, 0x62, 0x8c, 0x1c, 0xf8, 0x47, 0xe8, 0x7e, 0xd8, 0x7b, + 0x92, 0xb9, 0xdb, 0x6a, 0xd3, 0x58, 0xce, 0x41, 0x94, 0xf8, 0x88, 0x0e, 0x67, 0x88, 0x0a, 0x0d, + 0x4e, 0x52, 0xfc, 0x69, 0xc3, 0x8b, 0xb3, 0xa6, 0xe8, 0x08, 0x5f, 0x2d, 0xd8, 0x68, 0xb7, 0xc0, + 0x7d, 0x29, 0xa8, 0x7b, 0x7c, 0xea, 0x06, 0x9f, 0xe2, 0x41, 0x19, 0x23, 0xdd, 0x77, 0x7e, 0x24, + 0x48, 0x2c, 0x12, 0x9d, 0x8b, 0x1d, 0x58, 0x71, 0x50, 0x74, 0x60, 0xa2, 0x90, 0x36, 0x62, 0x1a, + 0xce, 0x10, 0x05, 0xfc, 0x48, 0x2e, 0xb3, 0x36, 0x3f, 0x4a, 0xff, 0x78, 0x91, 0xf4, 0x08, 0x61, + 0x9b, 0x1d, 0x03, 0xd2, 0x22, 0x4d, 0x8e, 0x7c, 0x63, 0xe2, 0x41, 0x4f, 0x74, 0xc5, 0x61, 0x03, + 0x8c, 0xc0, 0x0a, 0xcb, 0x77, 0x9e, 0x7f, 0xf8, 0x50, 0x67, 0x94, 0x82, 0xab, 0x84, 0x0a, 0x86, + 0x5f, 0xb6, 0x87, 0x36, 0xe3, 0xe6, 0x83, 0x31, 0xbf, 0xc1, 0x59, 0x0e, 0x5d, 0x19, 0x20, 0x18, + 0xc6, 0x72, 0x5a, 0x9e, 0x1e, 0xdd, 0x73, 0x06, 0xc7, 0x38, 0xc1, 0x62, 0xf7, 0xd0, 0x5e, 0x2f, + 0x82, 0x1b, 0x4d, 0x6c, 0x42, 0x7d, 0x0a, 0xef, 0xa2, 0xe5, 0xf5, 0x8a, 0xfa, 0x24, 0x33, 0xea, + 0xc1, 0xf4, 0x46, 0x22, 0x7a, 0xf5, 0x70, 0xc6, 0xe2, 0xb4, 0x22, 0xb4, 0x78, 0x10, 0xe9, 0xfc, + 0xa5, 0x35, 0x01, 0x6a, 0x1d, 0xdc, 0xff, 0xff, 0x0d, 0x47, 0x29, 0xd2, 0x18, 0xc1, 0x2f, 0xdc, + 0x55, 0xfc, 0x15, 0xd9, 0x98, 0xcd, 0x52, 0xd3, 0x9b, 0x2a, 0x6c, 0xda, 0x3e, 0xb5, 0x3f, 0x89, + 0x05, 0x32, 0xd5, 0x14, 0x9a, 0xb7, 0xbf, 0x0f, 0x18, 0xd9, 0x9c, 0x04, 0x2b, 0x9e, 0x8f, 0xf0, + 0xa8, 0x82, 0xf9, 0x70, 0x20, 0x0e, 0xb0, 0x7f, 0x7c, 0xfd, 0x7f, 0x05, 0x25, 0x69, 0xb8, 0x70, + 0xdc, 0xd8, 0x07, 0xa6, 0x61, 0x82, 0x4f, 0x34, 0x54, 0x7b, 0x95, 0x54, 0x9c, 0xb8, 0x34, 0xe5, + 0x45, 0x2c, 0x8e, 0xdc, 0x44, 0x28, 0x2e, 0x2d, 0xaa, 0x8d, 0x73, 0x20, 0xed, 0xbd, 0xed, 0xca, + 0x2b, 0x68, 0x94, 0x41, 0x4f, 0x8d, 0x32, 0x73, 0x8d, 0xa2, 0x42, 0x19, 0xc8, 0x20, 0xbc, 0x37, + 0xf8, 0x2e, 0x21, 0x59, 0x50, 0x08, 0x38, 0x07, 0xb3, 0x66, 0x6a, 0xd3, 0xef, 0x85, 0x0f, 0x1d, + 0x74, 0x1c, 0x00, 0x02, 0xde, 0xd0, 0x81, 0x65, 0xed, 0x47, 0x06, 0xf5, 0x50, 0xbc, 0x30, 0x13, + 0xe4, 0x11, 0xaa, 0x18, 0x86, 0x20, 0x40, 0x74, 0xa3, 0x9e, 0x2f, 0xca, 0x4e, 0x73, 0x12, 0xe4, + 0x67, 0xff, 0x2a, 0x38, 0x55, 0x1a, 0xff, 0x82, 0x59, 0x71, 0x86, 0xf6, 0x3a, 0x06, 0x49, 0x5b, + 0xef, 0x82, 0x12, 0x13, 0x3d, 0x23, 0xa7, 0x89, 0x04, 0xe2, 0x03, 0xce, 0x55, 0x1d, 0xb9, 0xcc, + 0x49, 0xd6, 0x32, 0xd9, 0x67, 0x4b, 0x84, 0x04, 0x0b, 0x93, 0xa9, 0x7a, 0xaa, 0xa9, 0x20, 0x27, + 0x8c, 0xc2, 0xff, 0x05, 0x03, 0x44, 0x58, 0x62, 0x2f, 0x40, 0xd6, 0xca, 0xf0, 0xc7, 0x5e, 0xfa, + 0xd7, 0xd1, 0xd3, 0xaf, 0x45, 0x4e, 0xbd, 0x11, 0x8f, 0xa9, 0x41, 0xf4, 0x46, 0xfa, 0xb7, 0xd5, + 0xbe, 0xae, 0x4b, 0xc6, 0x88, 0x1f, 0x62, 0xf6, 0x1a, 0x93, 0x70, 0xd3, 0x3b, 0x29, 0x8d, 0x06, + 0xd4, 0xfa, 0xaa, 0x65, 0x02, 0xe5, 0xe3, 0x61, 0x7d, 0x3b, 0x6f, 0xc4, 0x85, 0x08, 0x49, 0x11, + 0x25, 0x8c, 0x78, 0xf0, 0xb1, 0x91, 0x1d, 0xb3, 0x96, 0xa2, 0x1d, 0xe9, 0x92, 0x8b, 0x80, 0xf7, + 0xaf, 0xea, 0xde, 0x42, 0x89, 0x40, 0xd1, 0xa7, 0xef, 0x82, 0x13, 0x90, 0x91, 0x48, 0x29, 0xfc, + 0xeb, 0x89, 0x05, 0x9b, 0x73, 0x86, 0x02, 0xbc, 0xf0, 0xc7, 0x91, 0x16, 0xa4, 0xa8, 0xef, 0x88, + 0x0a, 0x5f, 0xaa, 0x56, 0xae, 0xc0, 0x98, 0x05, 0xb2, 0x1b, 0x55, 0x3e, 0x30, 0x4b, 0x36, 0x3e, + 0x14, 0x10, 0x6e, 0xaa, 0x28, 0x79, 0x3c, 0x2a, 0x59, 0x16, 0x63, 0x77, 0xc5, 0xb8, 0xc3, 0xe5, + 0x66, 0xbb, 0x1f, 0x05, 0x67, 0x0b, 0xc7, 0x89, 0x63, 0x17, 0x0d, 0xee, 0x3c, 0x2f, 0x7a, 0x76, + 0x92, 0xed, 0x70, 0x6d, 0x11, 0x44, 0x3b, 0x8c, 0x1b, 0x9f, 0xcf, 0x78, 0x94, 0x25, 0xfc, 0x42, + 0xa6, 0x7c, 0x48, 0x29, 0x85, 0xc8, 0xf5, 0x76, 0x08, 0xb7, 0x81, 0x71, 0xbe, 0xae, 0xa7, 0x37, + 0xba, 0x9e, 0x1f, 0x99, 0xbe, 0xc7, 0x28, 0xdb, 0x7f, 0x82, 0xbe, 0xc1, 0x02, 0xef, 0xb1, 0xd9, + 0x99, 0x05, 0xbb, 0xe3, 0x4e, 0xa9, 0xe7, 0x2c, 0x71, 0xe4, 0x0f, 0x94, 0x82, 0x3a, 0x2b, 0xee, + 0xda, 0x2d, 0x37, 0xfd, 0xb2, 0xf8, 0xf8, 0x80, 0x4b, 0x60, 0x2c, 0xaa, 0x05, 0x18, 0xa3, 0x2c, + 0x62, 0x8d, 0xfe, 0x22, 0xf6, 0xdd, 0x81, 0x8d, 0xd1, 0x9b, 0xc4, 0x07, 0xc1, 0x21, 0xae, 0xbc, + 0xdf, 0x04, 0xa4, 0x6d, 0x78, 0xad, 0x21, 0xbf, 0xc2, 0x82, 0x83, 0x21, 0x90, 0x94, 0x91, 0x30, + 0xf6, 0x95, 0x31, 0xee, 0xc8, 0x78, 0x94, 0xe5, 0xb7, 0xda, 0xdc, 0xde, 0xfb, 0xe1, 0x0e, 0xab, + 0xd5, 0x4a, 0xd9, 0x35, 0x55, 0xf4, 0x26, 0xe3, 0xd0, 0x9c, 0xbe, 0xcb, 0x9e, 0x8c, 0x1b, 0xe8, + 0x73, 0x22, 0x3a, 0x12, 0xc7, 0xd7, 0x5f, 0x46, 0xa9, 0x3a, 0x3e, 0x5f, 0x04, 0x77, 0xbe, 0xaf, + 0xae, 0x73, 0xeb, 0x9c, 0xfa, 0xe7, 0x3e, 0xa3, 0xea, 0xe4, 0xd5, 0xe5, 0xe8, 0xa5, 0x4f, 0x82, + 0x43, 0x2d, 0xc4, 0x8d, 0x13, 0x2f, 0x0a, 0x19, 0x0d, 0x08, 0x60, 0x13, 0xb8, 0x0a, 0x32, 0x30, + 0xd4, 0x79, 0x58, 0x44, 0xc1, 0x33, 0x5e, 0x76, 0xbc, 0xe3, 0x91, 0xb0, 0xcd, 0xc8, 0xbf, 0x85, + 0x25, 0xe2, 0x78, 0xb2, 0xf6, 0xb5, 0x1f, 0x31, 0x06, 0x68, 0x44, 0xc8, 0xe4, 0x7b, 0x32, 0x69, + 0x09, 0xfc, 0x48, 0x52, 0x4c, 0x34, 0x25, 0x64, 0x48, 0x09, 0xc0, 0xe5, 0xe1, 0x66, 0x9c, 0x5c, + 0xd1, 0xcb, 0xb3, 0x45, 0x25, 0x16, 0x60, 0xc9, 0x0d, 0x9d, 0x7c, 0x6e, 0x18, 0x30, 0x63, 0x73, + 0x67, 0x47, 0x07, 0xe0, 0xac, 0xa4, 0xd1, 0xa0, 0xe6, 0x0b, 0xcb, 0xf6, 0x06, 0x32, 0x20, 0x22, + 0xe4, 0x31, 0xd7, 0x8d, 0x1f, 0x82, 0xa9, 0x03, 0x07, 0x20, 0x60, 0x26, 0xca, 0x93, 0xad, 0xd0, + 0x5d, 0xd4, 0x56, 0x6a, 0x3b, 0xf0, 0x58, 0x28, 0x9c, 0x61, 0x81, 0x8c, 0x50, 0x63, 0x8b, 0xc7, + 0x10, 0xfc, 0x56, 0x7b, 0xa4, 0x05, 0x93, 0x69, 0xe9, 0x5f, 0x86, 0x02, 0xe3, 0xc6, 0xcd, 0xe2, + 0xa0, 0x79, 0x1c, 0x68, 0x43, 0xa0, 0xb7, 0x0f, 0x98, 0x72, 0x1d, 0x80, 0xf4, 0x1c, 0x0b, 0xe0, + 0x76, 0x1a, 0x94, 0x41, 0xf9, 0xee, 0x42, 0x82, 0xd4, 0xfb, 0xa3, 0x2a, 0x7e, 0x7d, 0xb7, 0xe1, + 0x4f, 0x5a, 0x30, 0x3f, 0x16, 0x0c, 0x3f, 0xd4, 0x9e, 0x6c, 0x83, 0x48, 0x10, 0x01, 0x44, 0x65, + 0x24, 0x56, 0x5b, 0xb9, 0xc0, 0x90, 0x54, 0x2e, 0xa1, 0xf8, 0x78, 0xe3, 0x8f, 0x05, 0x85, 0xbb, + 0x9f, 0x91, 0x15, 0x6d, 0x8e, 0x72, 0xc8, 0x8a, 0x10, 0xeb, 0xcc, 0xb5, 0xcf, 0xfc, 0x4a, 0x16, + 0x7e, 0x3c, 0x11, 0xc7, 0x04, 0x0a, 0x5b, 0x91, 0x73, 0x7c, 0x13, 0xcc, 0x30, 0x69, 0xe1, 0xc4, + 0xe6, 0x58, 0xa2, 0xad, 0xfe, 0x09, 0xaf, 0x23, 0x53, 0x02, 0x4a, 0x96, 0x3e, 0x1e, 0x1f, 0xbc, + 0x22, 0x0a, 0xa8, 0xc6, 0x06, 0x33, 0x3a, 0x5d, 0x4e, 0xea, 0x1a, 0x63, 0x0a, 0xaf, 0x1a, 0xf3, + 0xea, 0xff, 0x65, 0xd3, 0x5f, 0x05, 0x25, 0x49, 0xe8, 0x45, 0xe1, 0x4c, 0x5f, 0xe7, 0x61, 0xfe, + 0x08, 0x8d, 0x77, 0x77, 0x1e, 0x14, 0x21, 0x68, 0x2b, 0x1f, 0x22, 0x75, 0x77, 0x50, 0x27, 0xdc, + 0x0d, 0x9f, 0xb7, 0x54, 0x6c, 0xe6, 0x9c, 0x90, 0xfe, 0x23, 0x65, 0x13, 0x85, 0x71, 0x88, 0xd3, + 0x0b, 0x08, 0x8a, 0xea, 0x1f, 0x32, 0xf1, 0x83, 0x09, 0x22, 0x82, 0x7f, 0x3c, 0x4f, 0x98, 0x82, + 0xa4, 0xc4, 0x10, 0x10, 0xfd, 0x79, 0xb9, 0x76, 0xf5, 0xb9, 0x87, 0x8b, 0xc1, 0x59, 0x6e, 0xec, + 0xcb, 0xda, 0x37, 0x3c, 0xb0, 0x9d, 0x62, 0xd4, 0xff, 0x47, 0xe8, 0xbe, 0x8d, 0xd1, 0x5d, 0x15, + 0xfe, 0xb7, 0x93, 0xaf, 0xef, 0xa2, 0xf8, 0xfa, 0xc1, 0xf5, 0x7f, 0x8d, 0x34, 0xa3, 0x04, 0xb0, + 0xec, 0xc9, 0xb2, 0xcd, 0x1d, 0xa0, 0x85, 0x40, 0xb8, 0xab, 0x17, 0x5a, 0x3b, 0x3a, 0x09, 0x11, + 0xda, 0x36, 0xc3, 0xff, 0x56, 0x1e, 0x3e, 0x85, 0x69, 0xb9, 0x4c, 0x52, 0x02, 0xea, 0x37, 0x8c, + 0x59, 0xd0, 0x67, 0xda, 0x58, 0x91, 0x01, 0x49, 0xe6, 0x69, 0x93, 0x89, 0x7c, 0xf9, 0xc3, 0xec, + 0x51, 0x97, 0x61, 0x57, 0x25, 0x27, 0x12, 0x50, 0x28, 0x85, 0xe5, 0x86, 0x75, 0x49, 0xe2, 0x62, + 0x5d, 0x96, 0x33, 0xe7, 0x88, 0x04, 0x22, 0x6c, 0xc5, 0x8a, 0xbc, 0x58, 0x1f, 0x1f, 0x0a, 0x08, + 0x4c, 0xb4, 0x5c, 0x67, 0x7f, 0x2b, 0xfc, 0x4c, 0x0c, 0x13, 0x30, 0x9a, 0xcb, 0xcb, 0x67, 0x08, + 0x03, 0x7e, 0xf1, 0x21, 0x49, 0x2b, 0x84, 0x78, 0xf5, 0xa9, 0x50, 0x0a, 0xa5, 0x21, 0x01, 0x23, + 0x4a, 0x53, 0xcc, 0x29, 0x30, 0x30, 0x4c, 0x1c, 0x87, 0x54, 0x94, 0x0f, 0x2a, 0x9c, 0xb4, 0xe0, + 0xc0, 0x5c, 0x15, 0x88, 0x5e, 0x67, 0xc2, 0x85, 0x68, 0x79, 0x03, 0x76, 0x6a, 0xb5, 0xb8, 0xfe, + 0x45, 0xbc, 0xea, 0x34, 0x77, 0xe3, 0x08, 0x9b, 0xdb, 0xdd, 0xf7, 0x77, 0xb6, 0x2b, 0x3c, 0x7c, + 0x14, 0xc2, 0x57, 0xdb, 0x02, 0x41, 0x5c, 0xb0, 0xee, 0xe1, 0xdd, 0x8d, 0x37, 0xb7, 0x73, 0xc4, + 0x05, 0x05, 0x89, 0x52, 0x31, 0x1c, 0x80, 0x00, 0x6c, 0x70, 0x68, 0x34, 0xb3, 0x00, 0x2e, 0xa8, + 0x59, 0x41, 0x69, 0xc4, 0x82, 0x56, 0xa5, 0x32, 0x08, 0x04, 0x3e, 0xe8, 0x12, 0x94, 0x8a, 0x6b, + 0x10, 0x09, 0x09, 0x39, 0x89, 0x8f, 0x6d, 0xe2, 0x01, 0x11, 0x45, 0x65, 0x48, 0x28, 0xcb, 0x79, + 0xfe, 0xb1, 0x3a, 0xf0, 0x54, 0x52, 0xb1, 0xdb, 0xdf, 0x9e, 0x15, 0xf1, 0x53, 0x01, 0x77, 0x17, + 0x33, 0x06, 0x50, 0x5f, 0xc4, 0x85, 0x0c, 0xf4, 0x1b, 0xd3, 0xb4, 0xdb, 0xfb, 0xbf, 0xe1, 0xea, + 0x0f, 0x7b, 0x21, 0x47, 0xaf, 0xab, 0x0e, 0x24, 0x17, 0x4a, 0x23, 0x96, 0x8c, 0x72, 0x00, 0x11, + 0x3c, 0x92, 0xc1, 0x49, 0x82, 0x11, 0x20, 0xb2, 0x41, 0xe7, 0x57, 0x22, 0x82, 0x02, 0x00, 0xcf, + 0x41, 0x9e, 0xdc, 0x10, 0x07, 0x5f, 0x05, 0x42, 0xb0, 0xc9, 0x93, 0xe2, 0x04, 0x46, 0xd8, 0x89, + 0xe2, 0x4c, 0xc2, 0xd3, 0x7f, 0x89, 0x90, 0x87, 0x53, 0x46, 0xba, 0x9c, 0x9c, 0x27, 0xd8, 0x99, + 0xaa, 0xe0, 0x04, 0x27, 0xa9, 0xda, 0xba, 0xf4, 0x21, 0xcc, 0x74, 0x68, 0xd1, 0xa3, 0xf5, 0x72, + 0x4e, 0x8b, 0xd5, 0xd7, 0xbe, 0xb1, 0x7c, 0x97, 0xba, 0x5e, 0x08, 0x75, 0x7f, 0x7d, 0x6b, 0xe1, + 0xe3, 0x5d, 0xdf, 0x2c, 0x1a, 0x34, 0x24, 0x72, 0x94, 0x14, 0x72, 0xe6, 0xaa, 0x7f, 0xf8, 0x25, + 0xaa, 0xa8, 0xbf, 0x26, 0x31, 0xf0, 0x57, 0xaa, 0xec, 0x96, 0xaa, 0x3c, 0x80, 0xf9, 0x07, 0xbe, + 0x0a, 0xa8, 0x8e, 0xf4, 0xfb, 0x19, 0x18, 0x36, 0xf8, 0x55, 0x00, 0x04, 0x15, 0x9c, 0x24, 0x14, + 0x77, 0xe1, 0x42, 0x12, 0x03, 0x42, 0x77, 0x8e, 0x07, 0x9e, 0xf3, 0xea, 0x39, 0x54, 0x00, 0x2a, + 0x83, 0xac, 0x6a, 0x70, 0x98, 0x9c, 0x39, 0x9b, 0x1b, 0x91, 0xdb, 0xe0, 0xa0, 0xea, 0x60, 0x80, + 0x35, 0x55, 0x55, 0xef, 0x12, 0x09, 0x89, 0x7a, 0xb3, 0xa1, 0x1f, 0x51, 0xdf, 0x82, 0x98, 0x5c, + 0x02, 0x20, 0x2a, 0x61, 0x70, 0xbc, 0x45, 0x26, 0x63, 0x46, 0x9a, 0xbe, 0x73, 0xc7, 0xda, 0xbe, + 0x38, 0x6c, 0x64, 0x6e, 0x31, 0xe2, 0x41, 0x17, 0x8f, 0x0d, 0xab, 0xfc, 0x14, 0x95, 0xc2, 0x5b, + 0x4a, 0x3c, 0xf7, 0xe2, 0x5f, 0xa6, 0x89, 0x3e, 0xe2, 0x44, 0x85, 0x0e, 0x27, 0xc9, 0xa8, 0x07, + 0x50, 0xf7, 0x20, 0x19, 0x48, 0xad, 0x06, 0x05, 0xa2, 0x0e, 0x74, 0xd8, 0x3a, 0xb5, 0x3a, 0x18, + 0xf1, 0x22, 0x41, 0x25, 0x08, 0xa4, 0x19, 0x2f, 0x94, 0xf8, 0x21, 0x21, 0xf9, 0xbb, 0xbb, 0xb7, + 0xd5, 0xbe, 0xb1, 0x7c, 0x14, 0x5d, 0xc5, 0x6e, 0xaa, 0x6e, 0x5f, 0x5f, 0x18, 0x26, 0x9c, 0xc3, + 0xc7, 0xb9, 0x7b, 0x18, 0x99, 0x8c, 0x97, 0x85, 0x2c, 0x4e, 0xf3, 0x29, 0x67, 0x5a, 0x83, 0xc6, + 0x66, 0xc2, 0xaf, 0x41, 0xb0, 0xcc, 0x5d, 0x8a, 0x20, 0x0b, 0x41, 0x11, 0xc6, 0x57, 0x93, 0xac, + 0x48, 0x44, 0x41, 0x48, 0x23, 0x22, 0x41, 0xfc, 0x5d, 0x0a, 0x71, 0x04, 0xac, 0x37, 0x3c, 0x12, + 0x4b, 0x7a, 0x2f, 0x9e, 0x20, 0x13, 0x4f, 0x46, 0x67, 0xa3, 0xe8, 0x3a, 0x16, 0x5a, 0x46, 0xe8, + 0x17, 0x7c, 0x91, 0xd0, 0x38, 0x02, 0xd0, 0x00, 0x0d, 0xdf, 0x82, 0x21, 0x02, 0xea, 0x90, 0xbb, + 0xfc, 0x3f, 0x59, 0x28, 0x9c, 0x2b, 0xca, 0xcc, 0xd4, 0x9e, 0x97, 0x4c, 0x64, 0x79, 0xf2, 0x53, + 0x35, 0xfa, 0xe8, 0xaf, 0x27, 0x45, 0xf8, 0xf5, 0xca, 0xb8, 0x22, 0xaa, 0x3f, 0xef, 0xaa, 0x01, + 0xa4, 0xe3, 0xf7, 0x55, 0x77, 0x55, 0x77, 0xd7, 0x44, 0xea, 0xeb, 0x14, 0xbd, 0x73, 0x7d, 0x5a, + 0xfa, 0xe7, 0xae, 0xb2, 0xf8, 0x21, 0xa6, 0xa7, 0x52, 0xef, 0x87, 0xc1, 0x09, 0x45, 0x9a, 0x31, + 0x66, 0x2c, 0xef, 0x58, 0x91, 0x42, 0x1a, 0x7c, 0xe5, 0x22, 0xae, 0x58, 0xc4, 0xff, 0x0a, 0x4a, + 0xdd, 0x0f, 0x7a, 0x61, 0x4c, 0x3c, 0x7c, 0x46, 0xba, 0xa8, 0x32, 0xa5, 0xa0, 0x3c, 0x79, 0x5e, + 0xa7, 0xa4, 0x1a, 0xed, 0x3a, 0xc2, 0x3d, 0xe2, 0x42, 0x85, 0x48, 0x8a, 0x2a, 0xcf, 0x41, 0xe8, + 0x6d, 0xb4, 0x34, 0xe0, 0x77, 0x34, 0x3d, 0xa4, 0x68, 0x3f, 0x05, 0x97, 0x77, 0x1f, 0x00, 0x8a, + 0x02, 0x60, 0x9d, 0xcb, 0x8d, 0x91, 0x6c, 0xe7, 0x32, 0xf8, 0x2d, 0xee, 0xe8, 0xd1, 0xc0, 0x35, + 0x05, 0x23, 0xc4, 0x02, 0x19, 0x3f, 0x8e, 0xde, 0x24, 0x13, 0x1c, 0xc2, 0x03, 0x0a, 0x80, 0xab, + 0x46, 0x75, 0xf1, 0x02, 0x01, 0x16, 0xef, 0x7e, 0x24, 0x22, 0x14, 0xb2, 0xbc, 0xee, 0xd8, 0x31, + 0xf7, 0x25, 0x8c, 0x52, 0x30, 0xee, 0x18, 0xc8, 0x8a, 0xc8, 0xb8, 0x4d, 0x18, 0xac, 0x48, 0x90, + 0xa4, 0x30, 0xb1, 0x8e, 0xe7, 0xcc, 0x48, 0xe0, 0xba, 0x99, 0xba, 0x4c, 0x73, 0xa6, 0xbd, 0xd0, + 0x61, 0xa6, 0xe1, 0x59, 0xa0, 0xa8, 0xeb, 0x89, 0x0a, 0x12, 0x0a, 0xaa, 0x92, 0x31, 0x65, 0x58, + 0x1b, 0x55, 0x14, 0xf6, 0x04, 0x01, 0xa0, 0x20, 0xac, 0x61, 0x5b, 0x02, 0x47, 0x19, 0x99, 0xcc, + 0x14, 0xd4, 0x3a, 0x3e, 0x0d, 0xf7, 0x89, 0x04, 0x54, 0xf5, 0x7f, 0x08, 0x82, 0xe2, 0xd4, 0x82, + 0x03, 0x23, 0x27, 0x0e, 0x8e, 0xff, 0x0a, 0x09, 0x1f, 0x34, 0xdd, 0x04, 0x91, 0xca, 0x8d, 0x22, + 0x9e, 0x40, 0x70, 0xfb, 0x18, 0x85, 0xf4, 0x13, 0x99, 0xbb, 0xfd, 0x11, 0x2a, 0xe2, 0x45, 0x8a, + 0x65, 0x55, 0x21, 0xd4, 0x2c, 0xa4, 0x3e, 0x30, 0xab, 0x0c, 0xda, 0x4f, 0x81, 0xb7, 0xd9, 0xba, + 0x0c, 0x82, 0x86, 0x4b, 0x29, 0x4d, 0xc1, 0x01, 0x6b, 0xbc, 0x29, 0x56, 0x94, 0x30, 0x9a, 0x47, + 0x35, 0x48, 0xa7, 0x42, 0x39, 0xcb, 0xf1, 0x0e, 0x2a, 0x9d, 0xb9, 0x6f, 0x82, 0x53, 0x8b, 0x32, + 0x50, 0xb9, 0x97, 0x33, 0xc8, 0xf7, 0x57, 0xe1, 0x88, 0x84, 0x22, 0x24, 0x10, 0xb4, 0x4e, 0x1a, + 0x9b, 0x86, 0xd9, 0xbb, 0x41, 0x99, 0x71, 0x84, 0x55, 0xcc, 0x6c, 0x05, 0x71, 0x21, 0x42, 0x1c, + 0x21, 0x39, 0x8e, 0x54, 0x41, 0x2b, 0x97, 0x22, 0x1e, 0xce, 0x53, 0x6a, 0x6a, 0x4f, 0x00, 0x24, + 0x04, 0x5a, 0x64, 0x06, 0xe9, 0xd7, 0x85, 0x0d, 0x05, 0x94, 0x89, 0xd9, 0x1e, 0x19, 0x25, 0xa4, + 0x33, 0x0b, 0xb0, 0xcb, 0xf1, 0x69, 0xd0, 0x68, 0x64, 0x1b, 0xe3, 0x79, 0x39, 0x0b, 0xa0, 0x8c, + 0x20, 0x2d, 0x0d, 0x2d, 0x30, 0x1e, 0xc1, 0x81, 0xdb, 0x70, 0xbc, 0xc7, 0x93, 0x57, 0x06, 0x13, + 0xe4, 0x77, 0x98, 0x6d, 0x27, 0x28, 0xe7, 0xff, 0xab, 0x87, 0xd1, 0x4c, 0x95, 0xd6, 0x2a, 0xea, + 0xff, 0x56, 0x1e, 0x88, 0xff, 0x57, 0x97, 0xab, 0xfd, 0x7e, 0x5f, 0x56, 0x24, 0xe8, 0xfd, 0x27, + 0x04, 0x02, 0x87, 0xe1, 0x3e, 0x68, 0xa6, 0xf9, 0xfe, 0xec, 0x8b, 0x68, 0x43, 0xda, 0x7f, 0xe8, + 0xf2, 0xfa, 0x2f, 0x7c, 0x12, 0x19, 0x95, 0x11, 0x5e, 0xfe, 0x20, 0x28, 0x44, 0xea, 0x98, 0x54, + 0x72, 0x20, 0xbe, 0x3b, 0xa9, 0x42, 0xce, 0xa6, 0xa3, 0xa8, 0xec, 0xde, 0xad, 0xb0, 0x24, 0x18, + 0xa7, 0x8c, 0x7e, 0x1d, 0xb3, 0x61, 0x00, 0xbd, 0x9b, 0x7a, 0x59, 0xeb, 0x46, 0x73, 0x98, 0xac, + 0x6b, 0x1d, 0xfb, 0xab, 0xaf, 0x85, 0x0b, 0x42, 0xd5, 0x38, 0xdc, 0xd2, 0xf6, 0xaf, 0x79, 0xd4, + 0x3f, 0x88, 0x05, 0x54, 0x74, 0x91, 0xa5, 0x15, 0xea, 0x85, 0xa0, 0x29, 0xf1, 0xdc, 0xae, 0x47, + 0x9f, 0x19, 0x74, 0x1d, 0xfb, 0xe0, 0xa2, 0x2e, 0x2f, 0x22, 0xe4, 0x10, 0x15, 0x82, 0x94, 0x1f, + 0x5e, 0xfa, 0x39, 0x17, 0xc4, 0x89, 0x05, 0xb9, 0xca, 0x48, 0xc1, 0x99, 0x63, 0x1d, 0xa5, 0x18, + 0xec, 0x77, 0x88, 0x82, 0x6c, 0x26, 0x01, 0xc8, 0xb3, 0x02, 0xc8, 0x6d, 0x46, 0xb3, 0xae, 0x20, + 0x16, 0x91, 0xa3, 0x06, 0xdd, 0xdd, 0xdd, 0xfb, 0xe0, 0x8c, 0xae, 0x2b, 0x15, 0x89, 0x48, 0x23, + 0x54, 0xf8, 0x25, 0xd0, 0x32, 0xb1, 0xd8, 0x27, 0x51, 0xaa, 0xf8, 0x98, 0x2e, 0x29, 0x48, 0x21, + 0x74, 0x84, 0x6d, 0x60, 0xc2, 0x39, 0x55, 0x13, 0xb0, 0xfd, 0xe2, 0x41, 0x75, 0x09, 0xd9, 0x5a, + 0x38, 0x00, 0x1d, 0x2a, 0xe2, 0x01, 0x76, 0x70, 0xbb, 0xc1, 0x5d, 0x80, 0xdd, 0xfe, 0x09, 0x07, + 0x31, 0xa6, 0xe5, 0xc4, 0x77, 0xc4, 0x04, 0x8e, 0xd3, 0x0d, 0x30, 0xea, 0x28, 0x24, 0xf9, 0x6e, + 0x63, 0x89, 0x04, 0x75, 0x22, 0x81, 0x79, 0xf0, 0xf0, 0x42, 0x25, 0x55, 0x45, 0xc7, 0x6e, 0x22, + 0x14, 0x8f, 0x91, 0xf8, 0x94, 0x20, 0x20, 0xd6, 0xf2, 0x56, 0xbf, 0x56, 0xdd, 0xba, 0xa8, 0x45, + 0xa0, 0x94, 0xf1, 0xd8, 0xd9, 0xe8, 0x38, 0x12, 0x0d, 0x33, 0x06, 0x39, 0x7c, 0x29, 0xc0, 0xb8, + 0x1b, 0x16, 0xc9, 0xa9, 0x6a, 0xa5, 0xa5, 0x69, 0xa5, 0xba, 0xf2, 0x46, 0xa5, 0x12, 0xf7, 0xd2, + 0x97, 0xd2, 0xe0, 0x60, 0xfb, 0x1f, 0x05, 0xa4, 0xdd, 0xf6, 0x92, 0x4a, 0x3f, 0xc7, 0x8a, 0xaa, + 0x62, 0xbc, 0x93, 0xcd, 0xdb, 0xa2, 0xaf, 0x82, 0x3a, 0x90, 0x00, 0x57, 0x1d, 0xbe, 0x84, 0xb3, + 0xeb, 0x94, 0x9d, 0x19, 0xfe, 0x8b, 0x6f, 0xab, 0x5f, 0x5e, 0xfa, 0xb5, 0x75, 0xc5, 0x37, 0x5a, + 0xfa, 0xbd, 0xf4, 0x48, 0xaf, 0x12, 0x1d, 0x8b, 0xac, 0x43, 0x83, 0x80, 0xd0, 0xf9, 0x38, 0xae, + 0xdc, 0xa4, 0x17, 0xb5, 0x4b, 0x03, 0x30, 0x81, 0x8f, 0xf8, 0x91, 0x25, 0x13, 0xe6, 0x60, 0xe8, + 0x20, 0x0c, 0xaa, 0x90, 0x30, 0x15, 0x8e, 0x0f, 0x04, 0x9c, 0xd8, 0xb8, 0xcf, 0x84, 0xa4, 0xf1, + 0xaa, 0x6b, 0x27, 0x3a, 0x8f, 0x0a, 0x5d, 0x46, 0x7d, 0x2a, 0x2a, 0x83, 0x81, 0xf6, 0x70, 0x3d, + 0x9b, 0x39, 0xb0, 0x86, 0x22, 0xd3, 0x34, 0x40, 0x93, 0x35, 0x98, 0x2f, 0xc6, 0x18, 0xb0, 0x3d, + 0xa6, 0x68, 0xa9, 0x37, 0x78, 0x35, 0x39, 0x18, 0x74, 0x9d, 0x8a, 0xbd, 0x82, 0xdc, 0x19, 0x1b, + 0xe0, 0x8c, 0xa5, 0xa4, 0xb6, 0xf1, 0x56, 0x24, 0x28, 0x50, 0x31, 0x86, 0xa2, 0xda, 0x40, 0xda, + 0xa1, 0x38, 0x38, 0x24, 0x76, 0xa0, 0xae, 0xf0, 0x22, 0x9a, 0xb2, 0x1f, 0x1d, 0x24, 0xe2, 0x91, + 0xd5, 0xbb, 0x4f, 0x68, 0xe6, 0x68, 0xff, 0xe2, 0x42, 0x96, 0xf6, 0x02, 0xc4, 0x8f, 0x21, 0x33, + 0x78, 0x1a, 0xd1, 0x03, 0x87, 0xc4, 0x01, 0x4d, 0x03, 0xa8, 0xf7, 0x63, 0x51, 0x03, 0x1b, 0xe1, + 0x42, 0xb0, 0x32, 0xd6, 0x00, 0xb3, 0x04, 0xdc, 0xe3, 0x05, 0xec, 0xec, 0xde, 0xce, 0x58, 0x32, + 0xd8, 0xac, 0x57, 0xc7, 0x1f, 0x94, 0xc9, 0xa0, 0x10, 0xe0, 0xfc, 0xf1, 0x30, 0x44, 0x76, 0x87, + 0xca, 0xd6, 0x03, 0xa2, 0x3a, 0xf8, 0x81, 0x00, 0xac, 0x95, 0xa0, 0x63, 0x41, 0xa9, 0xbd, 0xd4, + 0x82, 0x18, 0x3c, 0x28, 0xa0, 0x74, 0x54, 0x70, 0x66, 0xb8, 0xf5, 0xe6, 0x8b, 0xf3, 0xfc, 0x10, + 0x95, 0x8e, 0xfd, 0x3f, 0xc1, 0x4d, 0xef, 0x65, 0xbb, 0x36, 0x76, 0x9f, 0xc4, 0x02, 0x4b, 0xdf, + 0xde, 0x24, 0x12, 0xdf, 0x72, 0xd1, 0x83, 0xb3, 0x88, 0x0b, 0xfd, 0x19, 0x9e, 0x20, 0x16, 0xc1, + 0x6c, 0x51, 0xaa, 0xdd, 0x26, 0x8e, 0x3a, 0x37, 0x68, 0xbb, 0xb8, 0xae, 0xff, 0x04, 0x65, 0x64, + 0x55, 0x03, 0xcd, 0xac, 0x4a, 0xfe, 0x24, 0x29, 0x0c, 0x2e, 0xa1, 0xe2, 0x02, 0xc3, 0xb2, 0x71, + 0x8e, 0x86, 0xd8, 0xfb, 0xd0, 0xd1, 0xdf, 0xcc, 0xb3, 0x1e, 0x16, 0x95, 0x08, 0xb4, 0x6e, 0x2c, + 0x10, 0x2a, 0xf8, 0x2a, 0x8a, 0xdc, 0xfb, 0x85, 0x91, 0x02, 0x86, 0xd0, 0x42, 0x69, 0xe2, 0x88, + 0x09, 0x65, 0x4d, 0x7a, 0x3b, 0xe2, 0x41, 0x34, 0xbe, 0x65, 0x4b, 0xc4, 0x58, 0x56, 0x28, 0x4e, + 0xfd, 0x15, 0xfe, 0x89, 0xaf, 0x82, 0x28, 0x8e, 0x48, 0xb8, 0xbf, 0x7c, 0xa2, 0x97, 0x5f, 0x04, + 0x65, 0x34, 0x51, 0x12, 0x36, 0x54, 0xfa, 0x3c, 0x33, 0xeb, 0x97, 0xd7, 0x52, 0x74, 0x4a, 0xfa, + 0xf4, 0xbd, 0x5f, 0xeb, 0xa8, 0xbe, 0x43, 0x53, 0x4d, 0xf8, 0x83, 0x9d, 0x46, 0xc9, 0x7b, 0x86, + 0x16, 0x2f, 0xf5, 0xef, 0xae, 0x5f, 0x57, 0xa8, 0x91, 0x20, 0xac, 0x46, 0x5e, 0xd8, 0xbf, 0x35, + 0x08, 0x20, 0x29, 0x97, 0xfb, 0xe1, 0x41, 0x67, 0xa5, 0x32, 0xb1, 0x19, 0x18, 0x52, 0x6b, 0xd1, + 0x4a, 0x66, 0xba, 0xcd, 0xf0, 0xe1, 0x1d, 0xc9, 0x05, 0xee, 0xa0, 0xee, 0xf8, 0x8b, 0x4d, 0x41, + 0xa0, 0x0b, 0x95, 0x43, 0xbc, 0x83, 0xe0, 0xb2, 0x7c, 0x7a, 0xf9, 0x04, 0x0a, 0x48, 0x0b, 0x8e, + 0x09, 0x98, 0x08, 0x6b, 0x7c, 0x14, 0xe7, 0x32, 0x76, 0x60, 0xbb, 0xb1, 0xf2, 0x41, 0xce, 0x26, + 0x09, 0xbc, 0x7c, 0x49, 0x2d, 0x9f, 0x60, 0x18, 0xbd, 0x7c, 0x44, 0x15, 0x5a, 0x00, 0x37, 0xa0, + 0x08, 0xd4, 0xcb, 0xf9, 0x55, 0x8d, 0x80, 0x08, 0xff, 0x88, 0xf1, 0x21, 0x4d, 0x6b, 0x34, 0x65, + 0x15, 0x1e, 0x37, 0x87, 0xa1, 0xe5, 0xf9, 0x71, 0xd0, 0xd3, 0x53, 0x17, 0x1d, 0xff, 0x05, 0x45, + 0x90, 0x40, 0x4e, 0xab, 0x47, 0x32, 0x47, 0x5a, 0x3b, 0xbe, 0x0a, 0xa3, 0x6d, 0xc6, 0x0d, 0x6c, + 0xbd, 0xca, 0x0a, 0x45, 0x03, 0xa0, 0x75, 0x44, 0x82, 0x3a, 0x78, 0x80, 0x53, 0x73, 0xcb, 0x6a, + 0x22, 0xa2, 0xb1, 0x06, 0x88, 0x59, 0x13, 0x51, 0x15, 0x55, 0x24, 0x17, 0x88, 0x04, 0x52, 0x2a, + 0x46, 0x71, 0x85, 0xe0, 0x67, 0xf8, 0x26, 0x11, 0x72, 0xf2, 0xdb, 0x9e, 0x0f, 0xf3, 0xfd, 0x17, + 0x6f, 0x84, 0xa8, 0x19, 0x5c, 0xbc, 0xe2, 0x03, 0x47, 0xeb, 0x07, 0xc1, 0x14, 0x6d, 0xf1, 0xaa, + 0x54, 0x8a, 0x18, 0x91, 0x20, 0x8c, 0x4d, 0x03, 0x4d, 0xd2, 0xfc, 0x26, 0x6b, 0xd0, 0xee, 0xbf, + 0x04, 0x25, 0x16, 0x92, 0x9c, 0x88, 0xc0, 0x53, 0xe0, 0xb4, 0x8b, 0x58, 0xd7, 0xad, 0x9d, 0x4e, + 0x2f, 0xf2, 0xf4, 0x4f, 0xe0, 0x94, 0x54, 0xb6, 0x91, 0xf4, 0x4f, 0x6f, 0x8e, 0xf7, 0xd1, 0x46, + 0x4f, 0xf5, 0x69, 0x7a, 0xe1, 0x7d, 0x14, 0xca, 0xae, 0x08, 0xab, 0x77, 0x7f, 0x9e, 0xad, 0x34, + 0x92, 0x5f, 0xea, 0xff, 0x52, 0x0a, 0xfa, 0x9d, 0x2b, 0xab, 0xfd, 0x59, 0xf0, 0x49, 0x46, 0x8d, + 0x9b, 0xbd, 0x74, 0x6d, 0xbe, 0x34, 0x93, 0x90, 0x4b, 0xce, 0x1c, 0x02, 0x6f, 0xbe, 0x33, 0xad, + 0x5b, 0xc7, 0x12, 0x08, 0x80, 0xa1, 0x1c, 0xb0, 0xa0, 0xdc, 0xcd, 0x49, 0x66, 0xcf, 0x9e, 0xa6, + 0x1b, 0x59, 0x01, 0xfd, 0x7f, 0xf1, 0x82, 0x54, 0x4c, 0xf0, 0x07, 0x98, 0xcc, 0xab, 0x8f, 0x82, + 0x07, 0x3a, 0x97, 0x21, 0x5f, 0x13, 0x0a, 0x48, 0x7d, 0xf7, 0x19, 0x05, 0x8d, 0x05, 0x6f, 0x2a, + 0x8d, 0xa3, 0x07, 0xbf, 0x7c, 0x28, 0x76, 0x1b, 0x01, 0x94, 0x40, 0xa2, 0x82, 0x3c, 0x87, 0x0e, + 0x82, 0xcc, 0xf1, 0x54, 0xc0, 0x88, 0x7f, 0x58, 0xfc, 0x8f, 0xfe, 0xee, 0x4f, 0x49, 0x82, 0x06, + 0x8d, 0x68, 0xb2, 0x68, 0x41, 0xa4, 0x3b, 0xfe, 0x14, 0x22, 0x42, 0x24, 0xb9, 0xfa, 0xa9, 0x80, + 0x00, 0x38, 0x6c, 0xea, 0x0f, 0xa8, 0x29, 0xb8, 0x3d, 0xac, 0x11, 0x0c, 0x3f, 0x85, 0x2c, 0x19, + 0x61, 0xd0, 0xcf, 0x8c, 0x1c, 0x19, 0x04, 0x12, 0xa4, 0x78, 0x82, 0xa8, 0xd1, 0x55, 0xd4, 0xf7, + 0xc1, 0x39, 0x8e, 0x91, 0xc5, 0x65, 0x50, 0xf6, 0xef, 0xdf, 0x08, 0x68, 0xcf, 0xf7, 0xa8, 0x2e, + 0x5d, 0x83, 0x1f, 0xa1, 0x34, 0x61, 0xaf, 0xc1, 0x19, 0xd4, 0x5d, 0x55, 0xfe, 0x0b, 0x0e, 0xcb, + 0xa8, 0xb5, 0xc4, 0x88, 0x20, 0x08, 0x86, 0x02, 0x83, 0x2d, 0xbc, 0x00, 0x02, 0x2b, 0x48, 0x9c, + 0x23, 0x95, 0x03, 0x54, 0x7f, 0x8e, 0xa6, 0x99, 0xd8, 0x18, 0xa6, 0xbf, 0x6e, 0xeb, 0x10, 0x22, + 0x6c, 0x19, 0xe8, 0xb8, 0x80, 0x42, 0x6b, 0x77, 0x15, 0xbf, 0xc1, 0x51, 0x4b, 0x81, 0x64, 0xf0, + 0x2b, 0x2d, 0xc3, 0xd2, 0x1f, 0x03, 0x3b, 0xd4, 0x21, 0xee, 0x71, 0x22, 0x42, 0x94, 0x31, 0xab, + 0x09, 0xf1, 0xdf, 0x46, 0x8a, 0x88, 0x07, 0xf7, 0x76, 0x3f, 0xff, 0x07, 0x4b, 0x93, 0xf1, 0x00, + 0xac, 0x65, 0x3e, 0xc0, 0x30, 0x72, 0xc0, 0x23, 0x18, 0xef, 0x12, 0x24, 0x15, 0xf0, 0x08, 0x5f, + 0x51, 0x02, 0xc7, 0x02, 0x90, 0xd9, 0x58, 0xdc, 0xe1, 0x80, 0xff, 0xe0, 0x92, 0xe5, 0x20, 0xe4, + 0x1f, 0xe8, 0x9f, 0x3e, 0x08, 0x65, 0xea, 0x2e, 0xaf, 0xe2, 0x41, 0x69, 0xac, 0x4a, 0xb5, 0x37, + 0x2f, 0x4a, 0x1e, 0x0a, 0x44, 0x94, 0x82, 0x60, 0xa4, 0xd4, 0x74, 0x88, 0x4a, 0x40, 0x04, 0x6e, + 0xfe, 0xbe, 0x14, 0xc7, 0x42, 0x04, 0x0f, 0xbe, 0xf2, 0x54, 0x20, 0x43, 0xd2, 0x0e, 0x6d, 0x87, + 0x18, 0x19, 0xa5, 0x01, 0xb6, 0x98, 0xbc, 0xcf, 0x82, 0xbd, 0x90, 0x86, 0x9e, 0x1b, 0x49, 0x92, + 0x1e, 0xbb, 0x42, 0xf6, 0x52, 0x79, 0xfe, 0x09, 0x2a, 0x8f, 0xcf, 0xf0, 0x5b, 0x89, 0x43, 0x06, + 0x86, 0xa4, 0x04, 0x06, 0x32, 0x26, 0x8a, 0xb3, 0xeb, 0x8c, 0xf8, 0x99, 0xd0, 0x94, 0xdb, 0x07, + 0x9f, 0xa5, 0x7f, 0x04, 0x7d, 0x50, 0xcc, 0xdf, 0x45, 0x20, 0x3e, 0x08, 0xaa, 0xf9, 0x52, 0xb8, + 0x2e, 0x18, 0xd1, 0x48, 0x36, 0x9b, 0xa0, 0xce, 0x30, 0x8e, 0xd5, 0xd1, 0xfa, 0x5e, 0xb9, 0x7d, + 0x12, 0x2a, 0xea, 0xff, 0x45, 0xc5, 0xf3, 0x57, 0x77, 0xde, 0xef, 0xf5, 0x94, 0x9d, 0x5d, 0x5d, + 0x7b, 0xc4, 0x85, 0x06, 0x12, 0xd8, 0x37, 0x9b, 0x89, 0x38, 0x13, 0xa5, 0xdd, 0x5b, 0x75, 0x55, + 0x13, 0x50, 0x59, 0xf4, 0x04, 0x8e, 0x95, 0x78, 0xe2, 0xf5, 0x6d, 0xd1, 0x26, 0x9d, 0x55, 0x55, + 0x74, 0x27, 0x7f, 0x82, 0x32, 0x89, 0x48, 0x22, 0x1e, 0x21, 0x04, 0x01, 0x2d, 0x8e, 0xde, 0x24, + 0x25, 0x16, 0x98, 0x44, 0xe3, 0x17, 0x91, 0x1f, 0x1b, 0x35, 0x7f, 0x0a, 0x1b, 0x8e, 0x79, 0xc2, + 0x23, 0x31, 0x31, 0x93, 0xfd, 0xa4, 0x11, 0xdf, 0x56, 0xaf, 0xc4, 0x89, 0x08, 0x15, 0xb1, 0xff, + 0x41, 0xd1, 0xdc, 0x66, 0x92, 0xd2, 0x1b, 0x24, 0xbc, 0x82, 0x1d, 0xcb, 0x07, 0xff, 0x0a, 0x09, + 0x20, 0x81, 0x6b, 0x0d, 0x60, 0xf6, 0x01, 0x26, 0x68, 0x25, 0x68, 0xfd, 0x94, 0x6e, 0x50, 0xab, + 0x63, 0x2e, 0xf7, 0x16, 0x32, 0xd9, 0xeb, 0x17, 0x91, 0xa0, 0xaf, 0x0a, 0x57, 0xfa, 0x9f, 0x6e, + 0xf6, 0x58, 0xc9, 0x6b, 0x8d, 0xef, 0x72, 0xc2, 0x21, 0x51, 0xfe, 0x24, 0x40, 0x52, 0xe6, 0x17, + 0xad, 0x1a, 0xd8, 0x43, 0x68, 0x38, 0x0c, 0x2c, 0xe4, 0xe9, 0x05, 0xd6, 0x3d, 0xb0, 0x8e, 0x89, + 0xad, 0x2b, 0x82, 0x01, 0x1d, 0xf9, 0x5d, 0x83, 0x45, 0xeb, 0x0b, 0x8f, 0x84, 0x6c, 0xf5, 0x30, + 0x85, 0x1f, 0x9d, 0x76, 0xd0, 0x2d, 0xbe, 0x24, 0x7d, 0x63, 0x44, 0x47, 0x10, 0x58, 0x8e, 0xea, + 0x0d, 0xac, 0x4e, 0xcc, 0x57, 0xc4, 0x02, 0x1d, 0x07, 0xa8, 0x1b, 0xea, 0x47, 0x7e, 0x0a, 0xa4, + 0x0d, 0x6e, 0x86, 0xc5, 0x01, 0x98, 0x20, 0x16, 0xd5, 0xb6, 0x00, 0x00, 0xb7, 0x1f, 0x28, 0x78, + 0x50, 0x84, 0xe0, 0xee, 0xde, 0x7a, 0xa3, 0x60, 0xd8, 0xad, 0xb9, 0xf9, 0xa8, 0xc6, 0x76, 0xbe, + 0xf1, 0x00, 0x8e, 0x62, 0x36, 0xb0, 0xff, 0x3e, 0x0a, 0x6a, 0x27, 0x05, 0x50, 0xa8, 0x06, 0xe4, + 0xeb, 0x81, 0x49, 0x20, 0xc4, 0x55, 0x8f, 0x04, 0x56, 0xd8, 0x3f, 0x89, 0x1d, 0x8d, 0xfb, 0xbe, + 0xab, 0x5e, 0x24, 0x79, 0x43, 0x88, 0x30, 0x23, 0xf9, 0xfa, 0x2a, 0x08, 0x0a, 0xcd, 0x77, 0x9e, + 0x20, 0xb8, 0x10, 0xa4, 0x42, 0x3a, 0xe4, 0x16, 0xf7, 0x67, 0x12, 0x32, 0x2a, 0xf9, 0x7a, 0xc4, + 0x25, 0xe3, 0x09, 0x20, 0xcb, 0x09, 0x36, 0x57, 0x69, 0xc5, 0xc0, 0xba, 0x03, 0x61, 0xbf, 0xd5, + 0x1f, 0xc1, 0x69, 0x6a, 0x2e, 0x30, 0x80, 0x47, 0x05, 0xd4, 0x4d, 0x8e, 0x5f, 0x12, 0x14, 0x26, + 0xd3, 0x65, 0xc3, 0xf1, 0x91, 0x70, 0x6f, 0x11, 0x82, 0x15, 0x74, 0x5d, 0x5a, 0x4d, 0x65, 0xf0, + 0x1e, 0xff, 0x04, 0x65, 0xb2, 0x0c, 0xc4, 0xdc, 0x48, 0x96, 0x99, 0x7d, 0x13, 0xcf, 0x82, 0x39, + 0x60, 0xe5, 0x20, 0xbe, 0x05, 0x0d, 0xf0, 0x5d, 0x56, 0x3a, 0xd6, 0xa9, 0xbe, 0x8b, 0x07, 0xc1, + 0x15, 0x75, 0xcb, 0xe0, 0x9a, 0xdd, 0xfb, 0xb3, 0xb7, 0xc1, 0x10, 0xc9, 0xd2, 0x4a, 0x91, 0x95, + 0xd1, 0xe5, 0xf5, 0x2a, 0x7d, 0x5d, 0xf5, 0x3a, 0x7d, 0x7b, 0xeb, 0xdf, 0x5a, 0xae, 0xbd, 0x7c, + 0xfd, 0x7d, 0x24, 0x9a, 0x6b, 0xd6, 0x29, 0xfa, 0xf7, 0xc2, 0x82, 0x98, 0xea, 0xf3, 0x31, 0x33, + 0x2b, 0x90, 0x41, 0x15, 0xa5, 0x07, 0x31, 0x00, 0x38, 0xad, 0xb9, 0x3f, 0xf6, 0x55, 0x2a, 0x72, + 0x91, 0xb0, 0xfc, 0x14, 0xd5, 0x55, 0x58, 0x06, 0x4f, 0x51, 0x79, 0x32, 0xbe, 0x8b, 0x3f, 0xd6, + 0xbc, 0x48, 0x50, 0xec, 0x34, 0x08, 0x30, 0x95, 0x42, 0xb8, 0x11, 0x88, 0x2a, 0xf9, 0x17, 0xb4, + 0x41, 0x9a, 0x47, 0xe8, 0xa8, 0x62, 0x33, 0x17, 0x15, 0x9f, 0xf1, 0x01, 0xa8, 0x6d, 0x9b, 0xa0, + 0xf2, 0x43, 0xbe, 0xa7, 0xff, 0x13, 0xf0, 0x46, 0x43, 0x24, 0x51, 0x71, 0x1f, 0xf3, 0xe0, 0xb2, + 0x66, 0x98, 0xf5, 0xb7, 0x74, 0x1b, 0x8a, 0xc4, 0x2a, 0x21, 0x86, 0x10, 0xfc, 0x4c, 0x71, 0x96, + 0x02, 0x45, 0x17, 0x8f, 0x27, 0x15, 0x9f, 0x9e, 0xb0, 0x7b, 0xfd, 0x7d, 0xc4, 0x41, 0x49, 0x77, + 0x71, 0x5a, 0xcf, 0x64, 0xa4, 0xc1, 0x2c, 0x82, 0x03, 0xef, 0x85, 0x34, 0xa8, 0x8c, 0x30, 0x63, + 0x0b, 0x6e, 0x56, 0x5e, 0xda, 0xe9, 0xb0, 0x0c, 0x7c, 0xed, 0xa2, 0x06, 0x55, 0x10, 0x25, 0x65, + 0xc4, 0x88, 0x76, 0x35, 0xaf, 0x85, 0x0a, 0x4f, 0x9d, 0xe3, 0x4c, 0x49, 0xe9, 0xd1, 0xc0, 0xd6, + 0x9a, 0xce, 0xb0, 0xed, 0x55, 0xd3, 0x2b, 0xd1, 0x22, 0x04, 0x74, 0xe2, 0x60, 0xb0, 0xd6, 0x8d, + 0x06, 0x76, 0xb3, 0x55, 0x08, 0x3f, 0x3f, 0x89, 0x57, 0xf1, 0x00, 0x88, 0xe8, 0x98, 0xd1, 0x1c, + 0x31, 0xd7, 0xc2, 0x94, 0x85, 0xdd, 0x84, 0xd1, 0x08, 0x2f, 0xb6, 0x62, 0xf4, 0x0c, 0xa6, 0x07, + 0xb0, 0x41, 0x86, 0xe8, 0x0a, 0xe3, 0x88, 0x05, 0xd5, 0xee, 0x96, 0x45, 0xbf, 0x5d, 0x5f, 0xe0, + 0x8c, 0xa5, 0x04, 0x9e, 0xf6, 0x05, 0xc7, 0x7e, 0x26, 0xc0, 0xd6, 0xba, 0xb1, 0x6c, 0x31, 0xf1, + 0x0f, 0xea, 0x91, 0x7a, 0xb9, 0xf0, 0x47, 0x55, 0xa9, 0x17, 0xf0, 0x5d, 0x73, 0x06, 0x1d, 0x6f, + 0x1c, 0x06, 0xf8, 0x23, 0x8b, 0x8b, 0x85, 0xa5, 0x01, 0x34, 0x48, 0x65, 0xf1, 0x24, 0x61, 0xda, + 0x38, 0x78, 0x3b, 0xad, 0x22, 0x5a, 0x6c, 0xc4, 0xba, 0x93, 0xc4, 0x82, 0xa1, 0x8e, 0x23, 0x8f, + 0x58, 0xf1, 0x25, 0xbc, 0xbe, 0xc1, 0x66, 0xc1, 0x27, 0xd9, 0x30, 0x6e, 0x23, 0xbf, 0x28, 0x90, + 0xed, 0x18, 0x5e, 0x64, 0x61, 0xdc, 0x37, 0x00, 0x4b, 0xae, 0x57, 0xd6, 0xbe, 0xb1, 0x5f, 0x5e, + 0x8a, 0xe6, 0xa3, 0x4d, 0x41, 0x4b, 0x93, 0xc6, 0x98, 0xe3, 0x05, 0x6e, 0x45, 0x10, 0x13, 0x86, + 0x0d, 0x9b, 0xde, 0xdb, 0xf6, 0x10, 0x19, 0xc3, 0x8b, 0x75, 0xb8, 0x05, 0xe4, 0xe7, 0xac, 0x11, + 0xe8, 0x7a, 0xc7, 0xfe, 0x14, 0xcd, 0x93, 0x60, 0xe6, 0x8b, 0x2a, 0x96, 0x75, 0x2f, 0x95, 0x23, + 0x13, 0x2b, 0xe1, 0xe0, 0x87, 0x9a, 0x95, 0xef, 0xa1, 0x36, 0xf8, 0x50, 0x83, 0x0b, 0x24, 0x98, + 0x03, 0xa8, 0x48, 0x85, 0x44, 0x85, 0x2b, 0xcb, 0x09, 0x79, 0xf4, 0x86, 0x0c, 0x04, 0x96, 0x85, + 0x09, 0x1a, 0x2a, 0x39, 0x38, 0xe0, 0xd3, 0x28, 0x7a, 0x25, 0xfc, 0x4a, 0x1a, 0x9d, 0x78, 0x50, + 0x87, 0x65, 0x8e, 0xc1, 0xa1, 0xd5, 0x81, 0xd8, 0xcc, 0x81, 0x61, 0xc0, 0xf5, 0xe0, 0x0b, 0xce, + 0xb8, 0x85, 0x6f, 0x85, 0x2a, 0x91, 0x72, 0xfa, 0x1b, 0xb8, 0xce, 0x81, 0x96, 0x56, 0x3f, 0xc6, + 0x50, 0x80, 0x31, 0xdf, 0xf8, 0x88, 0x52, 0xf0, 0xc5, 0x72, 0x1f, 0x24, 0x25, 0x50, 0xc6, 0x13, + 0x80, 0x64, 0xa3, 0xdb, 0xe9, 0x78, 0xbe, 0x14, 0xa6, 0x5d, 0x2d, 0xb7, 0x45, 0xcc, 0x41, 0x92, + 0x7d, 0x28, 0x19, 0x84, 0xac, 0x2e, 0x0d, 0x2c, 0xe6, 0x8f, 0xe3, 0xbb, 0xe0, 0xba, 0x75, 0x83, + 0x31, 0xc9, 0x56, 0x03, 0x7f, 0xce, 0x26, 0x14, 0x23, 0x50, 0xad, 0x30, 0xd5, 0x5a, 0x74, 0xcb, + 0xe5, 0x6a, 0xb4, 0xbf, 0xf0, 0x43, 0x55, 0xab, 0xf1, 0x02, 0x46, 0x1c, 0x8d, 0x1c, 0x1b, 0x27, + 0xfe, 0x16, 0xd0, 0x98, 0x7d, 0x83, 0x55, 0xa9, 0x44, 0xb3, 0x51, 0x7f, 0x05, 0x86, 0xca, 0x41, + 0x15, 0xde, 0xd5, 0xbb, 0xfb, 0xeb, 0x17, 0x13, 0x0a, 0x09, 0x05, 0xb5, 0xb3, 0x00, 0x6a, 0x90, + 0xeb, 0x3b, 0x0d, 0x96, 0xce, 0x36, 0x40, 0xf2, 0x5d, 0xef, 0xa7, 0x09, 0x30, 0xab, 0x4f, 0xfc, + 0x10, 0xd2, 0x4b, 0x68, 0xab, 0xf8, 0x52, 0xe3, 0xe4, 0x21, 0x0e, 0x2f, 0xbe, 0x1f, 0xc9, 0x07, + 0x24, 0x15, 0x08, 0x69, 0xd4, 0xd1, 0xb6, 0xee, 0x4c, 0xb6, 0x7a, 0x15, 0x75, 0x2c, 0x81, 0xcf, + 0xe2, 0x42, 0x93, 0x0e, 0x5e, 0xf2, 0x80, 0xfa, 0xc6, 0x40, 0x61, 0x16, 0xf9, 0x42, 0x00, 0x90, + 0x30, 0x1a, 0x07, 0x11, 0x60, 0x86, 0xd6, 0xee, 0x54, 0xf8, 0x52, 0xe5, 0x7a, 0xb2, 0x61, 0xbd, + 0xcb, 0x0b, 0xa1, 0x40, 0x1d, 0x97, 0x77, 0x1e, 0xa0, 0xbd, 0x0f, 0xef, 0x12, 0x2f, 0x04, 0x51, + 0x86, 0xee, 0x80, 0x6c, 0x7f, 0x0a, 0x79, 0x54, 0x4f, 0x06, 0x2b, 0x01, 0x63, 0xd4, 0x69, 0xe6, + 0x32, 0x27, 0x03, 0xb4, 0x26, 0x88, 0x13, 0x95, 0xdf, 0x9d, 0x8f, 0x05, 0x85, 0x75, 0x3f, 0x70, + 0xc1, 0x28, 0x20, 0x29, 0x0f, 0x07, 0x02, 0xd0, 0x5d, 0x7a, 0x80, 0x6b, 0xd3, 0x7d, 0x13, 0x0f, + 0x82, 0x22, 0x14, 0x5d, 0x83, 0x7b, 0x7c, 0x11, 0x11, 0x55, 0x7d, 0xf0, 0x44, 0x77, 0x77, 0xc5, + 0xc4, 0x89, 0x14, 0x52, 0xe1, 0xc3, 0x0f, 0xb0, 0xcf, 0x0f, 0x04, 0xe3, 0x02, 0x4e, 0xfc, 0x0c, + 0xcf, 0x3b, 0x39, 0x62, 0x71, 0x01, 0xbf, 0x7c, 0x15, 0xdd, 0xa6, 0x17, 0x04, 0x25, 0x2f, 0x5b, + 0xd6, 0x49, 0x36, 0xb2, 0x54, 0x76, 0x52, 0xb8, 0x21, 0x88, 0x27, 0xfa, 0x3c, 0x65, 0x73, 0x1e, + 0xaa, 0xbe, 0x09, 0x0d, 0x77, 0x59, 0x5f, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x28, + 0x14, 0x30, 0x32, 0x80, 0xd1, 0xd0, 0xd8, 0xa3, 0x79, 0x8c, 0xae, 0xae, 0x10, 0xe6, 0x2e, 0x2e, + 0x2f, 0xe1, 0x82, 0x34, 0x36, 0x98, 0x00, 0xec, 0x03, 0xc0, 0xca, 0x35, 0x2d, 0x82, 0xc7, 0x18, + 0xfe, 0x26, 0xc5, 0xe5, 0x61, 0xd8, 0xe1, 0x3c, 0xbd, 0xb8, 0xab, 0x07, 0x6f, 0xe0, 0xa0, 0xec, + 0x1c, 0x05, 0xa7, 0x2b, 0x8d, 0xa6, 0xba, 0xf1, 0x10, 0x67, 0x10, 0x18, 0x1a, 0x6a, 0xaa, 0x8e, + 0xe4, 0x03, 0x92, 0x0e, 0xdb, 0x33, 0xec, 0x73, 0xbe, 0x9a, 0xf7, 0xfd, 0xcb, 0xed, 0x27, 0xb8, + 0x2f, 0x75, 0x64, 0x5c, 0x0e, 0x38, 0x36, 0xee, 0x5b, 0x08, 0xd5, 0xca, 0xab, 0x98, 0x80, 0x80, + 0xd1, 0x90, 0xca, 0x54, 0xf4, 0x90, 0x0c, 0x2f, 0x0d, 0x4c, 0x0c, 0x7c, 0x57, 0x40, 0x00, 0x9f, + 0xc6, 0x08, 0xf6, 0x05, 0x67, 0xe3, 0xc0, 0x74, 0xfa, 0xaf, 0xc3, 0xfe, 0x82, 0x18, 0x13, 0xc6, + 0x25, 0xa3, 0xe8, 0x4a, 0xa6, 0x03, 0x5e, 0xa2, 0x5a, 0xcf, 0x59, 0xf4, 0xdb, 0x4f, 0x10, 0x20, + 0xb3, 0x88, 0x08, 0xf4, 0x97, 0xf1, 0x30, 0x69, 0x89, 0x1b, 0x07, 0x45, 0xc7, 0x8b, 0xa3, 0xed, + 0xfc, 0xe1, 0x80, 0xd8, 0x8a, 0x87, 0x11, 0x51, 0x64, 0xe9, 0x83, 0xd8, 0x35, 0xe5, 0x71, 0x8e, + 0x5f, 0x89, 0x61, 0x12, 0xc3, 0xe3, 0x24, 0x8d, 0x0a, 0x5e, 0x0f, 0x70, 0x9d, 0x5b, 0x9e, 0xf9, + 0xe0, 0xf2, 0xd9, 0x60, 0xc2, 0xa9, 0xc2, 0xdd, 0xbf, 0x2f, 0x43, 0x6e, 0x5f, 0x39, 0x55, 0xd5, + 0x5f, 0xc1, 0x66, 0x23, 0xe1, 0x40, 0x92, 0x5b, 0x4c, 0x6a, 0xa1, 0x13, 0xfc, 0xde, 0x5b, 0x43, + 0x4d, 0x4a, 0x10, 0xac, 0xf4, 0x60, 0xfb, 0xc4, 0x85, 0x36, 0xb6, 0x97, 0x65, 0x8e, 0x2b, 0x07, + 0x4f, 0x9e, 0x3c, 0xe7, 0x0f, 0x7d, 0xe1, 0x56, 0xe2, 0x6a, 0x71, 0xdc, 0x44, 0x14, 0x0f, 0x4d, + 0x06, 0x07, 0x96, 0xf5, 0x66, 0x42, 0x0e, 0xf5, 0x34, 0x48, 0x80, 0xc1, 0x30, 0xd0, 0x89, 0x34, + 0x0e, 0xf0, 0x8a, 0x97, 0x39, 0x31, 0xa4, 0xe1, 0xe2, 0x10, 0xac, 0x96, 0x06, 0x40, 0x00, 0x7c, + 0x43, 0xb8, 0x4f, 0x56, 0x10, 0xa6, 0x01, 0xe9, 0xc4, 0xeb, 0xfc, 0x40, 0x24, 0x14, 0x6b, 0x07, + 0x2f, 0x02, 0xef, 0x85, 0x57, 0xf7, 0xcf, 0x10, 0x0b, 0x3b, 0xb8, 0x32, 0x0f, 0xc1, 0xf0, 0x0f, + 0xc5, 0xbe, 0x15, 0x7f, 0x12, 0x00, 0x3e, 0x24, 0x07, 0xd6, 0x7b, 0x91, 0x71, 0x22, 0x01, 0x31, + 0x5d, 0xdd, 0xdf, 0x2d, 0x09, 0x58, 0x88, 0x03, 0xc8, 0xec, 0x31, 0xd0, 0x46, 0x2a, 0xea, 0x4b, + 0xeb, 0x0c, 0x7a, 0xa4, 0x42, 0xba, 0xa6, 0x5e, 0xa9, 0x92, 0xeb, 0x17, 0x89, 0x58, 0xbc, 0x20, + 0x14, 0x09, 0x1e, 0x29, 0x00, 0x70, 0x1e, 0x11, 0x27, 0x83, 0xac, 0x72, 0x7c, 0x42, 0x42, 0x7e, + 0xa5, 0xd8, 0xa0, 0xe2, 0xb2, 0xdf, 0x8d, 0x77, 0xc2, 0x91, 0x9d, 0xa7, 0x84, 0xc9, 0x80, 0x4f, + 0x11, 0xff, 0x31, 0x9c, 0x22, 0x7f, 0xba, 0xc6, 0x22, 0xfa, 0x3b, 0x05, 0x9c, 0x55, 0x29, 0x96, + 0xa1, 0x5b, 0x6f, 0x62, 0xe6, 0xf1, 0x00, 0xa0, 0xf2, 0xfa, 0x9f, 0xf5, 0xff, 0xd0, 0xd2, 0xa5, + 0xe1, 0x00, 0xc0, 0xae, 0x1c, 0x65, 0xa0, 0x8e, 0x9c, 0xc0, 0x76, 0xda, 0x02, 0xc1, 0x66, 0x88, + 0xe3, 0xfa, 0x87, 0x80, 0xba, 0x70, 0xb3, 0x2d, 0xbb, 0xfe, 0x0b, 0x46, 0x2a, 0xf4, 0xd7, 0xdb, + 0x7f, 0x82, 0xa2, 0x97, 0xbc, 0x43, 0x01, 0x17, 0x66, 0x1f, 0x48, 0x07, 0x29, 0x1a, 0x77, 0xf8, + 0xf8, 0x27, 0x3e, 0xd1, 0x01, 0x3e, 0x58, 0xf1, 0x97, 0x2b, 0xff, 0x82, 0x99, 0x6c, 0xb6, 0xd3, + 0x49, 0x5d, 0xea, 0xbc, 0xc7, 0x88, 0x10, 0x20, 0xe2, 0xc1, 0x31, 0xc8, 0xee, 0x3b, 0x09, 0x2b, + 0x07, 0x8c, 0xaf, 0x08, 0x02, 0xd3, 0xbb, 0xbc, 0xc6, 0x5b, 0x03, 0x5c, 0xa2, 0x8c, 0xd1, 0xf1, + 0xd8, 0x67, 0xa1, 0x78, 0x49, 0xd1, 0x98, 0x7a, 0xf4, 0xfd, 0x09, 0x4a, 0xbd, 0x53, 0x2f, 0x5e, + 0xfa, 0xf7, 0x10, 0x20, 0x15, 0x5d, 0xc5, 0x62, 0xb7, 0x3c, 0x45, 0x60, 0x5b, 0xf3, 0x4b, 0xd5, + 0x17, 0x3d, 0x47, 0x91, 0x03, 0x2d, 0x0b, 0x43, 0x28, 0xe2, 0x23, 0x47, 0x09, 0x2c, 0x1f, 0xc7, + 0xc0, 0xb0, 0x3e, 0xc0, 0x7a, 0xf1, 0xf7, 0xe9, 0xdf, 0x8b, 0xa6, 0x92, 0xaf, 0x7a, 0x18, 0x9a, + 0x70, 0x17, 0xff, 0xc4, 0x0d, 0x93, 0x34, 0x4e, 0xa6, 0x2d, 0xa5, 0xf5, 0x32, 0xc1, 0xff, 0xa6, + 0x7c, 0xc8, 0xad, 0xa6, 0x39, 0x04, 0x99, 0x44, 0xa6, 0x32, 0x3d, 0x0e, 0x0f, 0x39, 0xe5, 0x86, + 0x73, 0xdb, 0xe7, 0x7c, 0xef, 0xf8, 0x7c, 0xa2, 0x8d, 0x99, 0xef, 0xb1, 0xdf, 0x9e, 0xf1, 0xc7, + 0xef, 0xe2, 0x58, 0x3a, 0xf2, 0xe1, 0xbe, 0xbd, 0xd7, 0xc9, 0xc6, 0x08, 0x7b, 0xb7, 0x38, 0x58, + 0x93, 0xdb, 0xad, 0x3d, 0x03, 0x53, 0x53, 0xc2, 0x82, 0x4f, 0x60, 0x9d, 0x50, 0x95, 0x15, 0x0b, + 0xa7, 0x31, 0xdf, 0x92, 0x33, 0xd7, 0x32, 0x4c, 0x23, 0x09, 0xc7, 0xa3, 0xbf, 0x04, 0x22, 0x4a, + 0x5d, 0x0f, 0xff, 0x88, 0x44, 0xc9, 0x7e, 0x61, 0x41, 0x44, 0x84, 0x37, 0x1c, 0x86, 0x53, 0xc1, + 0xf0, 0x04, 0x40, 0x7c, 0x29, 0xa4, 0x63, 0x47, 0x30, 0x68, 0x3d, 0xf1, 0xbd, 0x57, 0x2f, 0x39, + 0xe5, 0xb2, 0x71, 0xea, 0xad, 0xdd, 0xdc, 0xe2, 0x04, 0x82, 0x90, 0x9c, 0xdf, 0xc8, 0xff, 0x35, + 0x70, 0xdd, 0x59, 0xb3, 0xb7, 0xb7, 0xde, 0x5e, 0xaf, 0x08, 0x75, 0x4e, 0xdf, 0x42, 0x1f, 0xe8, + 0xaf, 0x27, 0x47, 0x2f, 0x24, 0xe8, 0x8e, 0x44, 0xf1, 0xe3, 0x8e, 0x79, 0xc3, 0x08, 0xde, 0x05, + 0x6e, 0x5b, 0x3f, 0x40, 0xf2, 0xdb, 0x50, 0xdb, 0x80, 0x1f, 0xd2, 0x10, 0xbe, 0xf5, 0x9d, 0x57, + 0xeb, 0x7c, 0xe7, 0x9e, 0x0c, 0x16, 0x5c, 0x0e, 0xe7, 0x82, 0x63, 0x83, 0x42, 0x38, 0x36, 0x16, + 0x61, 0x86, 0x6d, 0x31, 0x53, 0x5c, 0x44, 0xac, 0x0d, 0x3a, 0x24, 0xd5, 0x00, 0xa9, 0xb2, 0xae, + 0x50, 0xb6, 0xb2, 0xe8, 0x2a, 0xa0, 0x2f, 0x81, 0xff, 0xc8, 0xf9, 0x1f, 0xc4, 0x06, 0x01, 0x4f, + 0xb1, 0xdf, 0x93, 0x34, 0x16, 0x13, 0x36, 0x6f, 0x5b, 0xb1, 0xd0, 0x2f, 0x17, 0x19, 0x95, 0xba, + 0xf8, 0xc7, 0xaf, 0xf4, 0x11, 0xff, 0xd4, 0xaf, 0xf8, 0x28, 0x1d, 0xc9, 0x52, 0x68, 0x87, 0x9e, + 0xc0, 0xf1, 0xc6, 0x1e, 0x38, 0xca, 0xeb, 0x6f, 0xac, 0xe7, 0xe8, 0x7f, 0x7c, 0x11, 0xd8, 0xee, + 0x50, 0x01, 0x2e, 0x38, 0x81, 0x21, 0x11, 0xdc, 0x38, 0x2a, 0x43, 0x88, 0xe7, 0x00, 0xe1, 0xc0, + 0xe0, 0x9a, 0xf3, 0x1a, 0x0b, 0x72, 0xe9, 0xb3, 0xdb, 0x88, 0x12, 0x3a, 0x32, 0xa4, 0x80, 0xe4, + 0xf8, 0xfb, 0xa6, 0x0f, 0x89, 0xd8, 0x74, 0xd8, 0x46, 0xe3, 0x49, 0x0b, 0x4b, 0xff, 0x38, 0x4f, + 0x24, 0x02, 0x7a, 0x25, 0xfe, 0x25, 0x14, 0x89, 0x7d, 0x12, 0xab, 0xa3, 0x41, 0xf0, 0x45, 0x55, + 0x77, 0x94, 0x77, 0x5c, 0x3e, 0x84, 0xb9, 0x7d, 0x5a, 0xfa, 0xb8, 0x2f, 0x46, 0x64, 0xbd, 0x09, + 0x2a, 0x5f, 0x51, 0xdb, 0xe8, 0x44, 0x5c, 0x40, 0x81, 0xe2, 0x9d, 0xdd, 0xf6, 0x98, 0x34, 0xc7, + 0x56, 0xad, 0x2c, 0x48, 0x44, 0x29, 0x05, 0x79, 0x81, 0xfc, 0x58, 0x01, 0xac, 0x85, 0x83, 0xf8, + 0xa1, 0xd6, 0x2d, 0x46, 0xb3, 0x41, 0xb7, 0xc7, 0xd9, 0x40, 0x7d, 0x18, 0xba, 0x2f, 0xc1, 0xc0, + 0xf2, 0x71, 0x18, 0x25, 0xb3, 0xc7, 0x92, 0xaf, 0x4b, 0xf8, 0x44, 0x20, 0x47, 0xf2, 0xf4, 0x63, + 0x11, 0x40, 0x47, 0xa3, 0x04, 0xf7, 0x6c, 0x75, 0x71, 0x75, 0x62, 0x8f, 0xc1, 0x20, 0x55, 0xdf, + 0x48, 0x1e, 0xa5, 0x45, 0x5e, 0x28, 0x2c, 0x99, 0xee, 0x39, 0x6d, 0xdd, 0xfc, 0x48, 0x29, 0x1a, + 0xd6, 0x1e, 0x36, 0x30, 0x4b, 0xf7, 0x64, 0x94, 0xf3, 0xb8, 0x35, 0x4d, 0x04, 0xb6, 0xf1, 0x2b, + 0xdf, 0x18, 0x2b, 0x2b, 0x29, 0xbc, 0xe9, 0x19, 0x01, 0x25, 0xec, 0x0d, 0xfa, 0xc7, 0x00, 0x91, + 0x1e, 0x01, 0x81, 0x55, 0xfe, 0x83, 0x36, 0x13, 0x7c, 0x5c, 0xf1, 0x30, 0x5b, 0x0b, 0x72, 0xd2, + 0x2a, 0x09, 0x37, 0x93, 0xf5, 0xc4, 0x41, 0x10, 0x4c, 0x34, 0x94, 0x77, 0xc5, 0xe3, 0x89, 0x12, + 0xa4, 0x6f, 0xaf, 0x7d, 0x1a, 0xbe, 0xbd, 0xf5, 0xc2, 0xba, 0x3b, 0xa3, 0xfa, 0x3b, 0x17, 0xd1, + 0x1c, 0x89, 0xe8, 0x93, 0x3e, 0x8e, 0x74, 0xbe, 0xa7, 0x49, 0x3a, 0x25, 0x7d, 0x4b, 0x78, 0x90, + 0x4e, 0x30, 0x4a, 0x90, 0x9c, 0x4c, 0x63, 0x83, 0xb6, 0xcb, 0x24, 0xe1, 0xe1, 0x49, 0xc3, 0x82, + 0x76, 0x43, 0x32, 0x22, 0xa4, 0x36, 0x2f, 0x80, 0x3d, 0xf0, 0x79, 0xc2, 0x41, 0x3c, 0x1c, 0x46, + 0x0e, 0x09, 0x40, 0x04, 0x00, 0x42, 0x54, 0x6c, 0x14, 0x43, 0x52, 0xaa, 0xa9, 0x7a, 0x11, 0x0e, + 0x94, 0x9c, 0x39, 0x1c, 0x07, 0x06, 0x57, 0xe2, 0x02, 0x82, 0x11, 0xe9, 0x13, 0x87, 0x47, 0xc7, + 0x94, 0x65, 0x29, 0x54, 0xca, 0x12, 0xa5, 0x0c, 0xb0, 0x68, 0x44, 0x00, 0x12, 0x61, 0x62, 0xc8, + 0xeb, 0x49, 0x2c, 0x0f, 0x0e, 0x69, 0xe2, 0x25, 0xc2, 0x10, 0x56, 0x5a, 0x6a, 0xd3, 0x30, 0xd1, + 0x56, 0x51, 0x55, 0x88, 0x0a, 0xf0, 0xa7, 0xce, 0x89, 0x89, 0x03, 0x89, 0x48, 0x61, 0x73, 0xd8, + 0x5f, 0x89, 0x82, 0xcd, 0x64, 0x50, 0x94, 0x1d, 0x91, 0x0c, 0xd1, 0xe9, 0xa0, 0x73, 0x1a, 0x92, + 0x14, 0x33, 0x80, 0x7d, 0xfe, 0x3a, 0x8c, 0xf8, 0xcf, 0x96, 0xc5, 0x77, 0x9c, 0xf1, 0x10, 0xa5, + 0xca, 0x65, 0xfe, 0x12, 0x5f, 0xc7, 0x2f, 0x73, 0x90, 0x40, 0x12, 0xe3, 0x80, 0x46, 0x11, 0x20, + 0x0a, 0x91, 0x39, 0xb3, 0xe4, 0xce, 0x24, 0x40, 0x52, 0x68, 0x7d, 0x81, 0x1e, 0x0c, 0x2d, 0x5c, + 0x08, 0x02, 0xa9, 0x97, 0x2c, 0xc4, 0xc1, 0xa9, 0x7b, 0xbf, 0xc2, 0x82, 0x42, 0x44, 0xce, 0x66, + 0xe7, 0x37, 0xca, 0xcf, 0xfc, 0xc4, 0xaf, 0x9b, 0xc1, 0xf1, 0x34, 0x6f, 0x36, 0x9b, 0x81, 0x7a, + 0x4e, 0x79, 0xf3, 0xe4, 0x70, 0x7e, 0x0a, 0x45, 0x88, 0x5b, 0x80, 0xd3, 0xdb, 0x80, 0xb8, 0xe9, + 0xaa, 0xdf, 0x6f, 0xad, 0xd4, 0x74, 0xa2, 0xfb, 0xc4, 0xac, 0x15, 0xd1, 0xab, 0xe8, 0xe4, 0x4f, + 0xae, 0x13, 0xf5, 0xef, 0xab, 0xc2, 0x9d, 0x7a, 0xba, 0xc5, 0x27, 0x44, 0x2a, 0x7d, 0x4e, 0x97, + 0xd7, 0x0f, 0x85, 0x06, 0x18, 0x30, 0x4d, 0xc5, 0xb1, 0xdf, 0x93, 0xc7, 0xae, 0xd2, 0x6f, 0xf9, + 0x66, 0x23, 0x8f, 0x63, 0xb7, 0x88, 0x1c, 0x4c, 0xd8, 0x6c, 0x8c, 0xb4, 0x09, 0x39, 0x25, 0x86, + 0x58, 0x72, 0x67, 0x84, 0x27, 0x3d, 0xb8, 0x3a, 0xb1, 0xda, 0x91, 0xf1, 0x8b, 0x96, 0xcd, 0xd3, + 0xc5, 0xf1, 0x02, 0x42, 0x87, 0x64, 0x04, 0xcf, 0xa1, 0xf4, 0x0d, 0x24, 0x31, 0x82, 0x02, 0x9c, + 0xe2, 0x64, 0xec, 0xd8, 0x2d, 0x5e, 0x23, 0x42, 0xfd, 0x74, 0x9a, 0xd3, 0x57, 0x4c, 0x02, 0x2e, + 0x76, 0xe2, 0xae, 0xad, 0xc7, 0x02, 0x01, 0xef, 0x12, 0x14, 0x9c, 0x1c, 0x2c, 0xe9, 0x85, 0x39, + 0x16, 0x71, 0x9c, 0x71, 0x86, 0x54, 0x80, 0x00, 0xd6, 0xd0, 0x80, 0x28, 0x65, 0x44, 0xe2, 0x30, + 0x59, 0x19, 0x27, 0x35, 0x7f, 0x88, 0x12, 0x14, 0xd2, 0xdb, 0xca, 0x20, 0x58, 0xa1, 0xde, 0x4b, + 0xef, 0xa0, 0x22, 0x73, 0x48, 0x6f, 0x12, 0x83, 0xb6, 0x16, 0xae, 0xe2, 0x61, 0x43, 0x66, 0x20, + 0xa0, 0x29, 0x92, 0x90, 0x63, 0x50, 0xf1, 0xfa, 0xac, 0x95, 0x54, 0x7c, 0x31, 0xbf, 0x51, 0x3e, + 0xe4, 0x86, 0xf8, 0xff, 0x09, 0x55, 0x50, 0x7e, 0xc9, 0xd6, 0x03, 0xbc, 0xbe, 0xd1, 0x15, 0x34, + 0x9d, 0xb9, 0x57, 0xe1, 0x50, 0x98, 0x14, 0x1c, 0xfd, 0x71, 0xd2, 0x08, 0x26, 0x80, 0xb4, 0xb3, + 0xe5, 0x03, 0xbf, 0x49, 0xcc, 0x92, 0x41, 0xb6, 0xbf, 0xc4, 0xfd, 0x53, 0xc4, 0x74, 0x71, 0xd5, + 0xf4, 0x66, 0xbe, 0xb5, 0x1b, 0xd5, 0xa2, 0xba, 0x99, 0x67, 0xd4, 0x76, 0xfa, 0x26, 0x57, 0xd1, + 0x53, 0xa7, 0xc1, 0x60, 0xe3, 0x28, 0x14, 0xd7, 0xc4, 0x9c, 0x55, 0x3b, 0xcb, 0xff, 0xf0, 0x57, + 0x08, 0x30, 0x1e, 0x61, 0xe8, 0x40, 0x75, 0x17, 0x13, 0xc1, 0x77, 0x40, 0x80, 0x00, 0x12, 0x28, + 0x92, 0x68, 0xc1, 0xef, 0x85, 0x0a, 0x2b, 0xb4, 0x0c, 0x57, 0x77, 0x6b, 0x6b, 0x17, 0xc5, 0xf9, + 0xfc, 0x48, 0x50, 0x82, 0x39, 0x1e, 0xec, 0x63, 0xfa, 0x4e, 0x41, 0x00, 0x45, 0x68, 0x09, 0xb6, + 0x06, 0x99, 0x6d, 0x37, 0x7f, 0x8f, 0x9c, 0x48, 0x35, 0x28, 0xc8, 0xff, 0xa0, 0xde, 0x41, 0xce, + 0xa2, 0xf7, 0xf0, 0xa1, 0xdf, 0x8d, 0x66, 0xd7, 0x91, 0x0d, 0xa8, 0x94, 0x96, 0x48, 0x7e, 0xe0, + 0x80, 0x3b, 0x68, 0xf0, 0x76, 0xa4, 0x80, 0x2d, 0x1a, 0x08, 0x62, 0x61, 0x4c, 0x4a, 0x04, 0x08, + 0xe4, 0x40, 0x60, 0x13, 0x7c, 0xbf, 0x49, 0xa2, 0x83, 0x77, 0x7b, 0x52, 0x56, 0xfe, 0x24, 0x50, + 0xc9, 0x7f, 0xdb, 0x2f, 0x10, 0xe3, 0x30, 0x56, 0xad, 0x7c, 0x48, 0x55, 0x45, 0x5f, 0x20, 0x00, + 0x19, 0xdf, 0x5d, 0x47, 0x68, 0xae, 0xae, 0x4f, 0xd6, 0xab, 0xa9, 0x8d, 0xf5, 0x4a, 0x86, 0xf0, + 0x47, 0x5a, 0xd8, 0xfa, 0xa5, 0x7e, 0xb2, 0x9b, 0xad, 0x5f, 0x05, 0x81, 0x41, 0x72, 0x72, 0x61, + 0x66, 0xaf, 0x44, 0x70, 0x38, 0x73, 0x87, 0x83, 0x85, 0x83, 0x97, 0xc2, 0x85, 0x66, 0x33, 0x07, + 0x45, 0x84, 0xa7, 0xce, 0x51, 0x25, 0x98, 0x8f, 0x28, 0x06, 0xf8, 0xcc, 0x00, 0x33, 0xf3, 0x2c, + 0x06, 0x19, 0xd8, 0xd2, 0x02, 0xe6, 0xc0, 0x2a, 0xfc, 0xf9, 0x5c, 0x0a, 0x5b, 0x02, 0xe6, 0x7f, + 0xe1, 0x41, 0xef, 0xa0, 0x0f, 0x21, 0x85, 0xa7, 0x39, 0xe2, 0x46, 0x5f, 0x47, 0x92, 0x7b, 0xce, + 0x47, 0xa8, 0xd7, 0xea, 0xb2, 0x55, 0x25, 0x28, 0x84, 0xc1, 0xf7, 0x10, 0x0a, 0x72, 0xdb, 0x55, + 0x31, 0x06, 0xb8, 0xf0, 0x76, 0x0d, 0x4b, 0x22, 0x37, 0x12, 0x20, 0x15, 0x9c, 0x5c, 0x62, 0xc6, + 0x55, 0x42, 0xf9, 0x47, 0x12, 0x08, 0xba, 0x93, 0x7c, 0x39, 0xb7, 0xbe, 0x14, 0xc3, 0x82, 0x63, + 0xa8, 0xe7, 0x0a, 0x30, 0x4a, 0xbb, 0x22, 0xdc, 0x6b, 0x84, 0x9a, 0x34, 0x99, 0xfe, 0x5f, 0x10, + 0xc5, 0x5f, 0xf8, 0x8d, 0x01, 0x4b, 0x9d, 0x25, 0xf0, 0x4a, 0x45, 0xd4, 0xe7, 0x09, 0x90, 0x81, + 0x34, 0xaa, 0x49, 0xfc, 0x48, 0x26, 0xf6, 0xe1, 0x98, 0x14, 0x63, 0xbf, 0x10, 0x3e, 0xde, 0x4e, + 0x82, 0x69, 0xdf, 0xaa, 0x53, 0xea, 0x44, 0xbe, 0xae, 0x02, 0x5d, 0x11, 0xfe, 0xa9, 0x17, 0x90, + 0x8e, 0xff, 0xab, 0xfd, 0x52, 0xa7, 0xd1, 0x5a, 0x2f, 0xab, 0x0f, 0x04, 0xe1, 0x08, 0x87, 0xb9, + 0x6e, 0x2b, 0x71, 0x59, 0x13, 0xe3, 0x48, 0x4e, 0x02, 0x84, 0xaa, 0xc9, 0x47, 0xe8, 0xfb, 0x09, + 0x5d, 0xe1, 0x6f, 0x70, 0xe8, 0x19, 0xd7, 0xc1, 0x9c, 0x45, 0x97, 0xae, 0x12, 0x99, 0x61, 0xc4, + 0x09, 0x8a, 0x66, 0x70, 0xd3, 0x88, 0x98, 0x3a, 0x81, 0xb3, 0xe0, 0x3e, 0xf1, 0xd3, 0x92, 0x07, + 0xbd, 0x09, 0xe2, 0x58, 0x5c, 0xf5, 0x28, 0x7a, 0x64, 0x9c, 0x77, 0x7e, 0x14, 0x8e, 0x8e, 0x86, + 0xe9, 0xb4, 0xac, 0x9f, 0x61, 0x62, 0x9b, 0x7b, 0x77, 0xa9, 0x73, 0x2a, 0x20, 0x28, 0xc5, 0xf1, + 0xb7, 0x2b, 0x83, 0x1f, 0xd9, 0xd3, 0x44, 0xbb, 0x1d, 0x5d, 0xb0, 0xfb, 0x7b, 0xb9, 0xc8, 0x4c, + 0xb5, 0x2d, 0xd2, 0xbe, 0x09, 0xce, 0x64, 0x8c, 0x1a, 0x1a, 0x98, 0x30, 0x1d, 0xb5, 0xff, 0xc6, + 0x11, 0xc4, 0x10, 0xf2, 0x1a, 0xe0, 0xa1, 0x1f, 0x84, 0x30, 0xc3, 0x00, 0xfe, 0x03, 0x4e, 0x9f, + 0xb8, 0x10, 0xe0, 0xed, 0x83, 0x50, 0x23, 0xc5, 0xae, 0x43, 0xc6, 0x3b, 0x67, 0x57, 0xae, 0x92, + 0x2a, 0x50, 0xb1, 0xb5, 0x13, 0x62, 0x0e, 0x10, 0x25, 0x33, 0xa6, 0xe1, 0xc4, 0xe9, 0x75, 0xaa, + 0xdf, 0x88, 0x0a, 0x14, 0xe0, 0x61, 0x5b, 0xcf, 0x30, 0xb2, 0x0c, 0x96, 0xd0, 0x9f, 0x05, 0xdd, + 0x69, 0x97, 0xd3, 0x8a, 0x25, 0xa2, 0x23, 0x20, 0xf7, 0x1a, 0x99, 0x8e, 0x97, 0x0a, 0xdc, 0xf1, + 0xc5, 0x60, 0xbe, 0x6d, 0xbd, 0x88, 0x68, 0x89, 0x61, 0x5f, 0x35, 0x5a, 0x43, 0xed, 0x7d, 0xf1, + 0x87, 0xb4, 0xb7, 0xf8, 0xe5, 0xcd, 0x83, 0x0e, 0xa0, 0xcd, 0xbf, 0x22, 0xe5, 0xa5, 0x3a, 0xf8, + 0x2d, 0xdb, 0x43, 0x3f, 0x18, 0x8b, 0x4d, 0x86, 0x2f, 0x31, 0xef, 0x10, 0x10, 0x15, 0x2b, 0x22, + 0xf5, 0xab, 0x4e, 0x2f, 0xf3, 0x85, 0x49, 0x52, 0x58, 0xe2, 0x27, 0x8b, 0xe8, 0xa9, 0x61, 0x0e, + 0x84, 0x32, 0x4e, 0x8f, 0x84, 0x5f, 0x42, 0xdc, 0xfa, 0x14, 0x3b, 0x8f, 0x12, 0x0b, 0x05, 0x24, + 0x2e, 0x3a, 0x16, 0x5c, 0x20, 0x59, 0x8e, 0xf8, 0x30, 0xaa, 0xe0, 0xc8, 0x5f, 0xb4, 0x24, 0x3c, + 0xdd, 0x7a, 0x9f, 0x9a, 0xf8, 0xd9, 0x68, 0x2b, 0xd3, 0x9f, 0x2c, 0x7a, 0x91, 0x82, 0xf9, 0xb0, + 0x5c, 0xbc, 0x75, 0x0f, 0xd4, 0x67, 0xff, 0xf1, 0x23, 0x4c, 0x3d, 0x61, 0x2a, 0x81, 0x76, 0x99, + 0xf5, 0x4d, 0x21, 0xb0, 0x13, 0xa8, 0x31, 0x6d, 0x98, 0x8d, 0x5f, 0xee, 0xc1, 0x26, 0xf8, 0x91, + 0x98, 0x6c, 0x3e, 0x96, 0x35, 0x46, 0xc4, 0x2e, 0x5e, 0x0b, 0xb1, 0x38, 0x79, 0x25, 0x1a, 0x6c, + 0x5c, 0x48, 0xc3, 0x3f, 0x6a, 0x57, 0x45, 0x86, 0x57, 0xe9, 0xc5, 0x25, 0xd9, 0x6d, 0xf6, 0xec, + 0x56, 0xee, 0x21, 0xcb, 0xf0, 0x4c, 0x24, 0xb9, 0xef, 0x15, 0xbb, 0xfc, 0x69, 0x1e, 0xdc, 0x51, + 0xcb, 0x00, 0xc5, 0x65, 0xf1, 0x84, 0x17, 0x2a, 0x3e, 0x4d, 0x82, 0xac, 0x63, 0x46, 0x40, 0x51, + 0x9a, 0xb7, 0xf8, 0xfb, 0x7b, 0xed, 0x31, 0x3b, 0xa4, 0x9a, 0x41, 0xb9, 0xea, 0xaa, 0xff, 0x89, + 0x05, 0x70, 0xab, 0xa1, 0x34, 0x47, 0x4f, 0x6b, 0x96, 0x9b, 0xc8, 0x8e, 0xaf, 0xdf, 0x77, 0x7d, + 0xe7, 0x6f, 0xc0, 0x39, 0xf3, 0x5a, 0x04, 0xe6, 0xbc, 0x92, 0xa8, 0x12, 0xa9, 0x83, 0xa1, 0x2b, + 0x52, 0x93, 0x6a, 0xc1, 0x13, 0x21, 0x4a, 0x78, 0xb2, 0xf8, 0x26, 0x3a, 0x01, 0x8a, 0xd3, 0x1e, + 0xb8, 0x45, 0x72, 0xf7, 0x73, 0xea, 0xff, 0x0c, 0x9c, 0xf4, 0x96, 0x15, 0x2f, 0xdd, 0x6b, 0xe1, + 0x11, 0xc2, 0x00, 0xe0, 0x80, 0xc0, 0x53, 0x38, 0xe2, 0xad, 0x5b, 0x77, 0x59, 0xf0, 0x57, 0x1e, + 0xcf, 0x0d, 0xb4, 0x2c, 0x49, 0x7f, 0xa5, 0xe9, 0x2b, 0x40, 0x1e, 0xc8, 0xa1, 0xd7, 0x65, 0x8b, + 0xde, 0x00, 0x8d, 0x37, 0xbc, 0xf1, 0x20, 0x98, 0x23, 0xa4, 0x91, 0xe1, 0xf4, 0xc8, 0x2b, 0xd1, + 0x2b, 0xeb, 0x97, 0xc1, 0x1e, 0xf7, 0x82, 0x5e, 0xaf, 0x5d, 0x5e, 0x5e, 0xaf, 0xf5, 0xca, 0xba, + 0xe7, 0x3e, 0x89, 0x8c, 0xae, 0x8e, 0x94, 0x16, 0x24, 0x20, 0x21, 0xf8, 0xe2, 0x2c, 0xaa, 0x6d, + 0xf2, 0x29, 0xb8, 0xfe, 0x5c, 0x40, 0xda, 0xa8, 0x8b, 0x12, 0xa2, 0x78, 0x2f, 0x03, 0xae, 0xac, + 0xde, 0xf1, 0xcf, 0xbb, 0x77, 0xf1, 0xa2, 0x28, 0xcf, 0x11, 0x01, 0x4d, 0x76, 0x4f, 0x3f, 0x9a, + 0x43, 0x52, 0x41, 0xc8, 0xe1, 0xa5, 0x0a, 0xb2, 0xc5, 0xac, 0x5e, 0x79, 0xfc, 0x77, 0x3a, 0x2a, + 0x2c, 0x99, 0x89, 0x3a, 0x6d, 0xb7, 0xfc, 0x40, 0xda, 0x8d, 0x65, 0x24, 0xfd, 0x8e, 0x96, 0x07, + 0x61, 0x29, 0x65, 0x0f, 0x59, 0x0a, 0x62, 0xc4, 0xf0, 0xe1, 0xbc, 0xc1, 0x1b, 0x7d, 0x0a, 0x5b, + 0xeb, 0x41, 0xc2, 0x2b, 0xb9, 0x20, 0xbe, 0xc0, 0x80, 0x63, 0x79, 0x09, 0xc0, 0xf0, 0xae, 0xb3, + 0x1c, 0xfb, 0x6d, 0xd7, 0xc1, 0x48, 0xd7, 0x28, 0x98, 0x91, 0xe5, 0xb1, 0xe5, 0x0b, 0x83, 0x1b, + 0x2c, 0x2f, 0x54, 0xea, 0x0b, 0x18, 0x40, 0x77, 0x76, 0xe3, 0xd1, 0x1f, 0xe1, 0xe1, 0x23, 0xb6, + 0x16, 0xf8, 0xac, 0x61, 0x7d, 0x5b, 0xe4, 0x9d, 0x00, 0x00, 0xcc, 0xc4, 0x68, 0xb1, 0x47, 0x6a, + 0xdd, 0x3f, 0xf0, 0xa5, 0x1d, 0x80, 0x00, 0x19, 0xbe, 0xd3, 0x0c, 0x5d, 0xb0, 0x81, 0x9a, 0xe2, + 0xcb, 0x9f, 0x78, 0x83, 0x5f, 0x7f, 0x5f, 0xfc, 0x60, 0xc2, 0xcb, 0x5e, 0x6e, 0x90, 0x56, 0x0d, + 0xf2, 0x84, 0x72, 0x5b, 0x28, 0xde, 0xe4, 0x9b, 0x72, 0x7d, 0x23, 0xcf, 0xac, 0xfe, 0x98, 0x3d, + 0x47, 0x84, 0x08, 0xb3, 0xb7, 0x5a, 0xe4, 0xc9, 0xc2, 0xde, 0xd7, 0x50, 0xbf, 0xd0, 0x5e, 0x2f, + 0x82, 0x1b, 0x4d, 0x6c, 0x42, 0x7d, 0x0a, 0xef, 0xa2, 0xe5, 0xf5, 0x8a, 0xfa, 0x24, 0x33, 0xea, + 0xc1, 0xf4, 0x46, 0x22, 0x7a, 0xf5, 0x71, 0x76, 0xb6, 0x91, 0x90, 0x00, 0x1b, 0xf8, 0xbe, 0x7f, + 0x49, 0x0d, 0x83, 0x6b, 0x89, 0x34, 0x42, 0xa0, 0x56, 0xe2, 0xbe, 0x20, 0x29, 0xb3, 0x8a, 0xd2, + 0x9f, 0x45, 0xcf, 0x06, 0xd7, 0x55, 0xc3, 0xf1, 0x53, 0x13, 0xe0, 0x80, 0xa9, 0x00, 0x43, 0xf8, + 0x91, 0xe2, 0x1b, 0x4c, 0xb6, 0xef, 0xdd, 0xce, 0xc1, 0x58, 0x6f, 0xf1, 0xa5, 0x1e, 0xee, 0xf6, + 0x50, 0x30, 0x10, 0x76, 0xd2, 0x46, 0x8b, 0xf6, 0xf1, 0x01, 0x5c, 0xe8, 0xac, 0x55, 0x25, 0x31, + 0x41, 0x4b, 0x19, 0x8c, 0xf1, 0x9d, 0xfa, 0x00, 0x7c, 0x9f, 0x57, 0xe2, 0x41, 0x58, 0xb7, 0x24, + 0x9a, 0x8e, 0x44, 0x1f, 0x50, 0x6f, 0x95, 0x81, 0xfd, 0xb0, 0x10, 0x25, 0xcc, 0x94, 0x87, 0x0d, + 0xfe, 0x14, 0x22, 0x9c, 0xb7, 0x3b, 0x50, 0xea, 0x33, 0x04, 0xa3, 0x09, 0xee, 0x21, 0x79, 0x26, + 0x37, 0x53, 0xb8, 0x81, 0x01, 0x43, 0x8e, 0x88, 0x5c, 0x9e, 0xc5, 0x1c, 0xb0, 0x43, 0xf0, 0x09, + 0x72, 0xe6, 0xb0, 0x19, 0x07, 0xd5, 0x97, 0xdd, 0x29, 0x6f, 0x16, 0xab, 0x8b, 0x80, 0x68, 0x72, + 0xbe, 0x2f, 0x82, 0x92, 0xf5, 0x0e, 0xe2, 0x54, 0x0f, 0x3b, 0x04, 0xc8, 0xbb, 0xfc, 0x11, 0x58, + 0x1a, 0x01, 0x4e, 0xc7, 0x7c, 0x11, 0x90, 0xd4, 0x8d, 0x1c, 0x33, 0xa7, 0xc5, 0x08, 0x27, 0xf5, + 0xee, 0xbe, 0x14, 0x25, 0x5b, 0x93, 0xc7, 0x44, 0x94, 0xc8, 0x8c, 0xca, 0x7b, 0x81, 0x74, 0xc9, + 0x7d, 0x98, 0xef, 0x86, 0x7f, 0x11, 0x24, 0xfc, 0x8b, 0xcf, 0x18, 0x49, 0x46, 0x5e, 0x15, 0xe9, + 0xb3, 0x93, 0x60, 0x9d, 0xfc, 0xad, 0x09, 0x42, 0xe7, 0x61, 0x89, 0x12, 0x08, 0xc6, 0xae, 0x1d, + 0x95, 0x22, 0xbc, 0x94, 0xac, 0xc1, 0x78, 0x63, 0xaf, 0x7d, 0x6b, 0xe8, 0xe9, 0xd7, 0xa2, 0xa7, + 0x5e, 0x88, 0xc7, 0xd4, 0xa0, 0xfa, 0x23, 0x7d, 0x5b, 0xea, 0xdf, 0x57, 0x24, 0xe6, 0x23, 0x8d, + 0x82, 0xa3, 0x08, 0xad, 0xc4, 0x78, 0x28, 0x26, 0x95, 0x55, 0x23, 0x0b, 0x36, 0x3e, 0x30, 0x86, + 0xc5, 0x4a, 0x2f, 0xc6, 0x20, 0x68, 0x28, 0xc7, 0x5f, 0x92, 0xd1, 0x8c, 0xb1, 0xa0, 0x14, 0x8a, + 0x37, 0xf9, 0xe2, 0x41, 0x19, 0xd3, 0x5f, 0xbc, 0x43, 0xa5, 0x54, 0x0f, 0x89, 0x0a, 0x4f, 0x96, + 0xe2, 0xb8, 0x94, 0xb1, 0xe3, 0xee, 0x3f, 0x3a, 0x47, 0x2f, 0x38, 0x40, 0x00, 0x3d, 0xf1, 0x82, + 0x34, 0x19, 0x79, 0xc3, 0x47, 0x9c, 0xbb, 0x40, 0xce, 0x10, 0x00, 0x09, 0x63, 0x2a, 0xec, 0xd7, + 0x78, 0x55, 0x82, 0xde, 0x85, 0x2b, 0xdf, 0x82, 0x93, 0x96, 0xb8, 0x18, 0x30, 0x6c, 0x6d, 0xd4, + 0xca, 0x96, 0x64, 0x27, 0x0b, 0xc8, 0xf9, 0x8b, 0x80, 0x1f, 0x13, 0x35, 0xf7, 0x88, 0x42, 0x5f, + 0xc4, 0x82, 0x8c, 0xd5, 0x58, 0x2d, 0xd9, 0x3b, 0xea, 0xff, 0x05, 0x15, 0xd0, 0xe8, 0xea, 0xef, + 0x82, 0x13, 0xab, 0xef, 0xf0, 0x55, 0x81, 0x30, 0xc3, 0xce, 0xab, 0xb8, 0xf5, 0xdb, 0x21, 0x6e, + 0x79, 0x6c, 0x1b, 0xca, 0x18, 0x0a, 0xa6, 0x4c, 0xef, 0xf7, 0x7e, 0xfe, 0x09, 0x0d, 0x57, 0xe6, + 0xe2, 0x44, 0x82, 0x53, 0x4a, 0xde, 0x99, 0x6c, 0xc9, 0x1e, 0x41, 0x73, 0x88, 0x10, 0x0a, 0x84, + 0x33, 0x11, 0x9f, 0xaf, 0x6b, 0x54, 0x2c, 0x7c, 0x4c, 0x55, 0xd2, 0x25, 0xaf, 0x1f, 0x71, 0x10, + 0x51, 0x2d, 0xb9, 0xe8, 0x5b, 0x2e, 0x5a, 0x62, 0x5c, 0x7f, 0xa1, 0x37, 0x1e, 0x84, 0xe5, 0x27, + 0x42, 0x99, 0x11, 0xd0, 0x96, 0x3e, 0xba, 0xfa, 0x35, 0x49, 0xd1, 0xf2, 0xf8, 0x23, 0xad, 0x75, + 0x7d, 0x73, 0x9f, 0x5c, 0xe7, 0xd7, 0x39, 0xf5, 0x1d, 0xab, 0x93, 0x75, 0x97, 0xa2, 0x95, 0x3e, + 0x63, 0x05, 0x1f, 0x37, 0x22, 0x69, 0x07, 0x13, 0x0a, 0x1b, 0x56, 0x31, 0x8c, 0xa3, 0xdf, 0x48, + 0x74, 0x40, 0x4b, 0x19, 0x43, 0x01, 0x7f, 0xbc, 0x71, 0xff, 0x05, 0x5a, 0xaa, 0xaa, 0xad, 0x22, + 0x38, 0xd4, 0x89, 0xfc, 0x48, 0xd9, 0x89, 0xd6, 0x11, 0x49, 0x22, 0x46, 0xa9, 0x02, 0xed, 0x63, + 0x23, 0xe5, 0x7d, 0x1a, 0x08, 0x7b, 0xb5, 0x45, 0x53, 0xa9, 0x59, 0x05, 0x47, 0xca, 0x82, 0x74, + 0x31, 0xe3, 0x11, 0x9f, 0x8b, 0xc5, 0xfc, 0x10, 0x95, 0x99, 0xaf, 0xde, 0x20, 0x16, 0x4a, 0x41, + 0x76, 0xd4, 0x98, 0x92, 0x49, 0x39, 0x48, 0x2f, 0xb7, 0xc6, 0x0a, 0x54, 0xd7, 0x58, 0xd1, 0xc2, + 0xe0, 0xb8, 0x7c, 0xc1, 0x11, 0x95, 0x06, 0x1f, 0x23, 0x40, 0xa6, 0xc4, 0x40, 0x65, 0xd6, 0x8d, + 0xb7, 0xf8, 0xca, 0xf0, 0x41, 0x0c, 0xc3, 0xc1, 0x78, 0x20, 0xe2, 0x14, 0x4b, 0xf3, 0xf8, 0x04, + 0xb4, 0x14, 0xf8, 0x3c, 0xef, 0x9e, 0x06, 0x87, 0x00, 0x1c, 0x7d, 0xc6, 0x8c, 0x34, 0x3e, 0x28, + 0xbf, 0x1b, 0x39, 0xe7, 0x83, 0x04, 0x47, 0x05, 0xaa, 0x1d, 0x16, 0x16, 0xa2, 0x3c, 0x66, 0x83, + 0xf4, 0x3e, 0xc6, 0x65, 0x43, 0xb9, 0x7a, 0x09, 0x34, 0xf4, 0x1d, 0xc3, 0xc3, 0x81, 0x4f, 0xe2, + 0xd8, 0x75, 0xc7, 0xf0, 0x5a, 0x54, 0x94, 0x5f, 0x20, 0xbd, 0x92, 0x25, 0x99, 0x30, 0xc6, 0x45, + 0x2b, 0x27, 0xf1, 0x08, 0x5c, 0xe3, 0xd7, 0xcf, 0xab, 0xfd, 0x7e, 0xf8, 0x21, 0xb3, 0x60, 0xee, + 0xe7, 0xd5, 0xfc, 0x48, 0x82, 0xaa, 0x63, 0x4b, 0x2a, 0xbf, 0x8f, 0x2c, 0xa6, 0x32, 0xaa, 0xb6, + 0x96, 0x7a, 0x7e, 0x08, 0x8c, 0x2b, 0x14, 0x62, 0x8c, 0x51, 0xb8, 0xf0, 0xa1, 0x0b, 0x62, 0xb7, + 0x15, 0xc0, 0x09, 0xdc, 0x86, 0x98, 0x92, 0xd9, 0xde, 0xdd, 0xd8, 0xf8, 0x50, 0x60, 0xb9, 0xb1, + 0x99, 0x27, 0x92, 0x4e, 0x25, 0xdb, 0xbb, 0xb3, 0x05, 0xed, 0xba, 0xf8, 0x23, 0x28, 0x9e, 0x18, + 0x82, 0xa2, 0x51, 0x3e, 0x55, 0xfe, 0x08, 0xce, 0x63, 0x14, 0xd4, 0xbf, 0xa2, 0xfa, 0x37, 0x45, + 0x74, 0x57, 0xfa, 0xde, 0x4e, 0xbf, 0xbe, 0x8b, 0xe3, 0xeb, 0x07, 0xc1, 0x24, 0x9c, 0xbc, 0x71, + 0x6d, 0xfe, 0x08, 0xcc, 0xcd, 0xa3, 0xed, 0x4f, 0xe2, 0x41, 0x84, 0xb1, 0x96, 0x8f, 0x6d, 0x4e, + 0x91, 0x00, 0x85, 0xe1, 0x07, 0xea, 0x9a, 0xf8, 0x46, 0xf6, 0xb3, 0x1a, 0x43, 0xd4, 0xab, 0x4c, + 0x5e, 0x63, 0x7e, 0x09, 0xa7, 0x76, 0xdf, 0x88, 0x54, 0x5d, 0x9e, 0x20, 0x15, 0x09, 0x41, 0x9d, + 0xd4, 0x95, 0x39, 0x03, 0x01, 0xd9, 0x9b, 0x39, 0x17, 0x12, 0x0a, 0x04, 0x30, 0x13, 0xee, 0x72, + 0x1d, 0x7e, 0xf1, 0x01, 0x4a, 0x02, 0x2c, 0x45, 0x6e, 0xe6, 0xc2, 0xf3, 0x8f, 0xdf, 0x48, 0x28, + 0x0e, 0x40, 0xcd, 0x9c, 0x47, 0x88, 0x40, 0x1d, 0xcf, 0x82, 0xd2, 0xb8, 0x94, 0x30, 0x14, 0x3b, + 0x15, 0x4c, 0x02, 0x2e, 0xa4, 0x42, 0xa5, 0xc4, 0x0a, 0x21, 0xf3, 0xdd, 0xdd, 0xf8, 0x90, 0x84, + 0xee, 0x9e, 0xe1, 0x29, 0x55, 0x00, 0xc8, 0xa1, 0x76, 0x9f, 0x89, 0x0b, 0x0b, 0x9f, 0xde, 0x8a, + 0xef, 0xfb, 0x53, 0xff, 0x05, 0x84, 0x7a, 0xbc, 0xe2, 0x02, 0x5a, 0x16, 0xe2, 0x28, 0xc1, 0x14, + 0x76, 0x4b, 0x89, 0x12, 0x09, 0xb4, 0xd3, 0x1b, 0xd1, 0x40, 0x40, 0x37, 0x46, 0x5f, 0xcd, 0xf0, + 0xa1, 0x48, 0x4c, 0x0c, 0x6c, 0x00, 0x11, 0x0d, 0x2d, 0xb8, 0x5c, 0xba, 0x53, 0x10, 0x57, 0x43, + 0x34, 0x6e, 0x08, 0x05, 0x73, 0xf8, 0x90, 0x4f, 0xa3, 0x60, 0xcd, 0x0d, 0xcf, 0x54, 0xeb, 0x89, + 0x04, 0x45, 0x3a, 0xf6, 0x9e, 0xbc, 0x47, 0x84, 0x51, 0x9c, 0xf1, 0x21, 0x4d, 0xd2, 0xd0, 0xcd, + 0x47, 0x06, 0x04, 0x82, 0x02, 0xe4, 0x04, 0x01, 0x83, 0x70, 0x80, 0xba, 0x90, 0x0f, 0x36, 0x1e, + 0xa6, 0xc7, 0xc1, 0x14, 0x56, 0x2b, 0x71, 0x5e, 0xbe, 0x14, 0x15, 0xcb, 0xcd, 0x86, 0xc4, 0xa5, + 0xce, 0x41, 0xbb, 0x48, 0x27, 0xfe, 0x8e, 0xff, 0x1b, 0x80, 0x58, 0x4f, 0x53, 0x8e, 0x04, 0x01, + 0x93, 0x27, 0x57, 0x6c, 0x02, 0x71, 0x13, 0x69, 0x07, 0xe9, 0x6d, 0x00, 0x7e, 0x67, 0xc8, 0x6a, + 0x43, 0x0b, 0x00, 0x44, 0x76, 0xd3, 0x46, 0xa2, 0xd5, 0xf7, 0xd7, 0xa1, 0x1e, 0x8e, 0xe4, 0x9d, + 0x17, 0xab, 0xaf, 0x7d, 0x62, 0xf9, 0x2b, 0x5f, 0x82, 0x1d, 0xd7, 0xdf, 0x5a, 0xf8, 0x22, 0x34, + 0x48, 0x1b, 0x57, 0x3e, 0xac, 0x78, 0x80, 0x49, 0x4a, 0x3d, 0x94, 0x7d, 0xf1, 0x9d, 0xcc, 0xd6, + 0x0d, 0xf3, 0x82, 0x00, 0xa7, 0xda, 0x3e, 0x7a, 0x5e, 0x30, 0x8e, 0x21, 0x10, 0x1b, 0x39, 0x10, + 0x1a, 0xd5, 0xcb, 0x6e, 0x2b, 0xbb, 0x6f, 0xe0, 0x8c, 0xf5, 0x5f, 0x7c, 0x51, 0x1b, 0x08, 0xd8, + 0xe3, 0x65, 0x86, 0x38, 0x78, 0x3c, 0xa4, 0x2e, 0x98, 0x93, 0x88, 0x0a, 0x53, 0x82, 0x2c, 0x47, + 0xc6, 0x09, 0x84, 0x12, 0x89, 0x8a, 0xfc, 0x3f, 0x50, 0x07, 0x63, 0x39, 0x2b, 0x2b, 0xe0, 0x48, + 0x22, 0x86, 0x02, 0x76, 0x33, 0x98, 0xa5, 0x5e, 0x09, 0xa5, 0x20, 0x96, 0xdc, 0x56, 0xf1, 0x83, + 0x6d, 0x62, 0xef, 0xe2, 0x42, 0x85, 0x21, 0x66, 0x06, 0x3e, 0x81, 0xa2, 0x02, 0x68, 0x4c, 0xf9, + 0xf9, 0x18, 0x4c, 0xb5, 0xd8, 0xbb, 0x88, 0x10, 0x0b, 0x8a, 0x5b, 0x0a, 0x24, 0x46, 0xad, 0x31, + 0x86, 0x49, 0x3f, 0x3e, 0xf1, 0x20, 0x9a, 0x70, 0x40, 0x17, 0x88, 0x0f, 0xbd, 0x22, 0xa9, 0xe2, + 0x02, 0x93, 0xe4, 0x03, 0x60, 0x45, 0x80, 0x69, 0x56, 0x83, 0xa0, 0xd1, 0x31, 0xd2, 0x6b, 0x09, + 0x5d, 0xbd, 0x06, 0x55, 0x37, 0x6a, 0x4f, 0x82, 0xbd, 0x46, 0x80, 0x80, 0xab, 0x01, 0xbf, 0x6a, + 0xcf, 0x88, 0x68, 0x2b, 0x12, 0x88, 0x09, 0x6f, 0xde, 0x11, 0x05, 0x73, 0x7a, 0x1c, 0x8c, 0x54, + 0x65, 0x4e, 0x86, 0x0d, 0x7f, 0x64, 0x4f, 0x10, 0x08, 0xec, 0x45, 0x69, 0xcb, 0x51, 0x99, 0x43, + 0x89, 0x29, 0x5d, 0xc5, 0x65, 0xce, 0x22, 0xb1, 0x1f, 0x44, 0xf9, 0xe2, 0x42, 0x96, 0x65, 0x00, + 0x06, 0x35, 0x61, 0x55, 0xd4, 0xf9, 0xe4, 0x3c, 0x8e, 0x36, 0x36, 0xdc, 0x18, 0x0c, 0x19, 0x53, + 0xe0, 0xae, 0x12, 0xb8, 0x76, 0x26, 0x86, 0x02, 0xa4, 0xca, 0xcf, 0x71, 0x08, 0xcb, 0x29, 0x65, + 0x6c, 0xc5, 0x9e, 0xa8, 0x75, 0xa1, 0x01, 0x2f, 0x02, 0x01, 0x67, 0xc6, 0x8a, 0xd0, 0xd4, 0x7e, + 0xd0, 0x7e, 0x3f, 0xac, 0x20, 0x9f, 0x61, 0xa6, 0xb4, 0x0f, 0x37, 0xb6, 0x06, 0x6c, 0x77, 0x5c, + 0x63, 0xff, 0x87, 0xe6, 0x8a, 0xa5, 0x0c, 0x05, 0x92, 0x1c, 0x96, 0x2d, 0x23, 0xb8, 0xd7, 0xd6, + 0x2e, 0x09, 0x7a, 0x52, 0xc4, 0x06, 0x00, 0xcd, 0x46, 0xfa, 0x44, 0xd8, 0x7a, 0xe8, 0xaf, 0x27, + 0x45, 0xf8, 0xf5, 0xca, 0xb8, 0x22, 0xbb, 0x3f, 0xef, 0xaa, 0x02, 0x49, 0xc7, 0xea, 0xee, 0xaa, + 0xee, 0xab, 0xae, 0x89, 0xd5, 0xd6, 0x29, 0x7a, 0xe6, 0xfa, 0xb5, 0xf5, 0xcf, 0x5c, 0x12, 0x4f, + 0x24, 0x0d, 0x1b, 0x52, 0xf1, 0x21, 0xd8, 0x6a, 0xb4, 0xe0, 0xc0, 0x8f, 0x78, 0x1f, 0xea, 0xdb, + 0x2a, 0x34, 0x1d, 0xef, 0x0d, 0xf6, 0x85, 0x13, 0xc2, 0xae, 0xa2, 0xff, 0x89, 0x0a, 0x14, 0xc4, + 0x8b, 0x70, 0xd9, 0x52, 0xb8, 0x12, 0x34, 0xa3, 0x7d, 0x8d, 0x8c, 0x4a, 0xbb, 0x01, 0x8d, 0x1b, + 0x17, 0x22, 0x3f, 0xc5, 0x7c, 0x7d, 0x2f, 0x51, 0x3f, 0xe0, 0xb0, 0x46, 0xe7, 0x84, 0x56, 0xe1, + 0x75, 0x08, 0x56, 0x78, 0xe1, 0xc3, 0xc9, 0xdd, 0x28, 0xd5, 0x71, 0x21, 0x48, 0x68, 0x19, 0x1f, + 0xc7, 0xbe, 0x55, 0x78, 0x84, 0xb5, 0xd2, 0x0d, 0xc5, 0x95, 0x85, 0xfb, 0x2b, 0xf9, 0x5c, 0x27, + 0xac, 0xdd, 0x12, 0xbe, 0x8b, 0x97, 0xc1, 0x3c, 0xe3, 0x05, 0xf9, 0x78, 0xae, 0xf9, 0x7c, 0x15, + 0xd5, 0x48, 0x4d, 0x38, 0x23, 0x22, 0x13, 0x99, 0x22, 0x85, 0x95, 0x52, 0x61, 0x7d, 0xde, 0x24, + 0x44, 0x60, 0x36, 0x47, 0xe3, 0x57, 0x58, 0x0a, 0xf8, 0x80, 0x46, 0x7b, 0xd9, 0xc7, 0xf1, 0x20, + 0x8b, 0x66, 0xb7, 0xf1, 0x0a, 0x39, 0x9d, 0x71, 0x20, 0x8b, 0x7c, 0xf0, 0xae, 0x27, 0xf0, 0x57, + 0x52, 0x22, 0x0b, 0x6a, 0x58, 0xaf, 0x38, 0x37, 0xad, 0x30, 0x86, 0xf5, 0x0a, 0xc6, 0x4a, 0xde, + 0xdd, 0x01, 0x5f, 0x57, 0xf8, 0x2e, 0x39, 0x01, 0x36, 0x60, 0x7e, 0xc0, 0x25, 0x20, 0xb0, 0x1b, + 0xc2, 0x00, 0xbf, 0xc1, 0x66, 0x55, 0x07, 0x0c, 0x1d, 0x8c, 0x84, 0xb0, 0xee, 0x14, 0xa0, 0x26, + 0x36, 0x14, 0xa8, 0xb2, 0xae, 0x23, 0xe1, 0x21, 0x0a, 0xaa, 0xa7, 0x60, 0xf4, 0x7b, 0xf5, 0x35, + 0xf0, 0xa0, 0x90, 0xdd, 0x99, 0xd3, 0x49, 0x1a, 0x25, 0x1d, 0xc3, 0x04, 0xcd, 0xc1, 0x6b, 0x9b, + 0xf3, 0x04, 0x02, 0xd3, 0x48, 0xd0, 0x50, 0x66, 0x04, 0x05, 0x1c, 0xad, 0x06, 0x1a, 0x6a, 0x4e, + 0x68, 0xc2, 0xa9, 0x6f, 0x31, 0xa2, 0xf4, 0x2f, 0xaf, 0x0c, 0x48, 0x90, 0x91, 0x1e, 0x93, 0x49, + 0x63, 0x65, 0xb7, 0xe7, 0xea, 0x99, 0xa6, 0xde, 0xd9, 0xfa, 0x7f, 0x82, 0xb1, 0x0f, 0xbd, 0xee, + 0xf5, 0x74, 0x9b, 0xea, 0xe7, 0xd5, 0xc3, 0xe8, 0xa5, 0x4a, 0xeb, 0x15, 0x75, 0x7f, 0xab, 0x0f, + 0x44, 0x7f, 0xab, 0xcb, 0xd5, 0xfe, 0xbf, 0x2f, 0xab, 0x12, 0x74, 0x7e, 0x93, 0x12, 0x34, 0x51, + 0x12, 0x13, 0x04, 0x1c, 0x29, 0x4a, 0xfd, 0x29, 0xe3, 0xd1, 0x44, 0x67, 0x68, 0x09, 0x1a, 0x50, + 0xc3, 0xe9, 0xb4, 0x9d, 0x31, 0x5e, 0x81, 0x63, 0x17, 0x2d, 0x14, 0x7b, 0xa4, 0x88, 0x29, 0x55, + 0x36, 0x90, 0x8a, 0x2f, 0xf1, 0xa5, 0xc8, 0xc8, 0xf2, 0xf7, 0x22, 0x98, 0x97, 0x53, 0xad, 0x15, + 0x92, 0xc8, 0xf5, 0x3d, 0xc4, 0x7c, 0xbf, 0xf1, 0x01, 0x43, 0x8c, 0x17, 0x0b, 0xb1, 0x85, 0xdc, + 0x72, 0x4e, 0x6d, 0x22, 0x79, 0x60, 0x28, 0x98, 0xa0, 0xc1, 0x00, 0x6a, 0x73, 0x1c, 0x08, 0x72, + 0x00, 0xcf, 0x10, 0x28, 0xca, 0x81, 0xda, 0x55, 0x27, 0xf8, 0x80, 0x4e, 0x4d, 0x26, 0x4e, 0x4f, + 0x1f, 0xff, 0x08, 0x05, 0x39, 0x6c, 0xb0, 0xb8, 0xba, 0xe8, 0x87, 0x5c, 0x3b, 0xae, 0x71, 0x01, + 0x4b, 0xbe, 0x08, 0x8b, 0x10, 0xf8, 0x85, 0x87, 0xf8, 0x2a, 0x8a, 0xc4, 0x26, 0x25, 0xb6, 0xc0, + 0x7d, 0x93, 0xf3, 0x3f, 0x7b, 0x8c, 0x99, 0x71, 0xc7, 0xe1, 0x0e, 0xc0, 0x4e, 0x86, 0x2b, 0x3a, + 0x96, 0xf3, 0xde, 0x99, 0x7e, 0x58, 0x78, 0xb9, 0x46, 0xb9, 0x02, 0x01, 0xd0, 0xc8, 0xcf, 0x82, + 0xd3, 0xcd, 0x5e, 0x86, 0xcc, 0xa5, 0x4e, 0x07, 0x5c, 0x40, 0x22, 0xb7, 0x15, 0x69, 0xdb, 0xe0, + 0x8e, 0x2b, 0x77, 0x15, 0xcb, 0xe8, 0x9e, 0x1c, 0x41, 0x8a, 0x91, 0x30, 0x57, 0x7e, 0x09, 0x6e, + 0x5b, 0x3a, 0x83, 0xda, 0x33, 0x0c, 0x06, 0x9f, 0xff, 0x5e, 0xf1, 0x00, 0xa4, 0xe5, 0xee, 0x82, + 0xa0, 0x1c, 0xa0, 0x68, 0xa5, 0x20, 0x94, 0xd3, 0xe8, 0x95, 0x70, 0x88, 0xb2, 0x36, 0x6a, 0x55, + 0x6a, 0xeb, 0x12, 0x14, 0x20, 0x7a, 0xb5, 0x01, 0x98, 0xd1, 0xc7, 0x60, 0x36, 0x9b, 0x1d, 0x39, + 0x2f, 0x3e, 0x10, 0x05, 0xd4, 0x40, 0x7d, 0x9e, 0x8e, 0x65, 0xf4, 0xc7, 0xff, 0x05, 0x95, 0x6f, + 0x12, 0xa8, 0x7e, 0xc7, 0xc0, 0xa0, 0x36, 0x12, 0x79, 0x75, 0x50, 0x3f, 0x0c, 0x48, 0x90, 0x52, + 0x79, 0x60, 0x60, 0x26, 0x20, 0xfe, 0xc2, 0xf6, 0x38, 0x93, 0x40, 0x71, 0xdb, 0xe2, 0x63, 0x45, + 0x97, 0xb0, 0x6d, 0x64, 0x86, 0x22, 0x09, 0x6d, 0x34, 0xe6, 0x04, 0x04, 0xe1, 0x01, 0x28, 0x40, + 0x56, 0x17, 0x2c, 0xc6, 0x3e, 0x08, 0x89, 0xaa, 0xc7, 0xf8, 0x5c, 0x51, 0x20, 0xac, 0x21, 0x36, + 0x2b, 0x6c, 0x56, 0x87, 0x70, 0xbf, 0x1f, 0xfc, 0x31, 0x52, 0x23, 0x59, 0x28, 0x81, 0xd5, 0x5d, + 0x55, 0x1f, 0xfa, 0x12, 0xcf, 0xae, 0x52, 0x74, 0x67, 0xfa, 0x2d, 0xbe, 0xad, 0x7d, 0x7b, 0xea, + 0xd5, 0xd7, 0x14, 0xdd, 0x6b, 0xea, 0xf7, 0xd1, 0x22, 0xbc, 0x40, 0x2b, 0xce, 0x9b, 0xa6, 0x7e, + 0xf6, 0xb8, 0xc0, 0x72, 0xcf, 0xf0, 0x46, 0x5e, 0x56, 0x5e, 0x24, 0x12, 0xd0, 0x33, 0x21, 0x1e, + 0x1d, 0xbf, 0x37, 0x7f, 0x82, 0x5a, 0xe8, 0x94, 0x8c, 0x6c, 0xf8, 0x22, 0xd2, 0xa5, 0x87, 0x88, + 0x1c, 0x68, 0x85, 0x83, 0x73, 0x96, 0x2b, 0x5e, 0x17, 0x9b, 0x1b, 0xe3, 0xf8, 0x80, 0x46, 0x57, + 0xdb, 0x8b, 0xe0, 0xb2, 0xc1, 0xf1, 0xb7, 0xf8, 0xc2, 0x62, 0x02, 0x96, 0x04, 0x9e, 0xc0, 0x69, + 0xa3, 0x8f, 0x88, 0x0a, 0x14, 0x39, 0xc7, 0x22, 0xb9, 0x14, 0xcb, 0x0e, 0xbb, 0x4e, 0x8e, 0xd1, + 0x34, 0x63, 0x95, 0x26, 0xd4, 0x23, 0x44, 0x3b, 0xea, 0x86, 0x0b, 0x18, 0x95, 0x77, 0x4f, 0xbe, + 0x15, 0xd2, 0x8d, 0x81, 0xba, 0x91, 0x08, 0xef, 0xee, 0x2c, 0xdd, 0x7f, 0x88, 0x45, 0xf7, 0x89, + 0x21, 0x8a, 0x00, 0x01, 0x56, 0x6f, 0xc4, 0x82, 0x33, 0x92, 0x4f, 0xff, 0xc4, 0x02, 0x82, 0x2a, + 0x7b, 0xb8, 0x97, 0x1a, 0xc7, 0x7c, 0x10, 0x95, 0xdf, 0x1a, 0x67, 0xf1, 0x00, 0x9a, 0xf7, 0xbb, + 0xef, 0xe2, 0x41, 0x25, 0x36, 0x06, 0xe8, 0xbb, 0xe0, 0xbb, 0x6a, 0xfc, 0x6c, 0x55, 0xa5, 0x5c, + 0x42, 0x33, 0x3e, 0x0a, 0xe2, 0xbd, 0xa6, 0x08, 0xa8, 0x97, 0x92, 0x0d, 0x50, 0x88, 0xbf, 0x12, + 0x1a, 0x2e, 0x6d, 0xaf, 0xba, 0xbf, 0x88, 0x05, 0x75, 0x99, 0x60, 0x41, 0xd3, 0xe0, 0x82, 0x68, + 0x50, 0x36, 0x19, 0x46, 0x5a, 0xb1, 0xf7, 0xc2, 0x9d, 0x10, 0xf0, 0xd0, 0x20, 0xc1, 0x17, 0x3a, + 0x91, 0xd4, 0xe1, 0x90, 0x9d, 0x2a, 0x70, 0x19, 0xcc, 0x7d, 0x15, 0x18, 0x81, 0x04, 0xa4, 0xc1, + 0x34, 0xc1, 0xf8, 0xb2, 0x9b, 0x0c, 0x00, 0x01, 0x6d, 0x40, 0x81, 0x10, 0x00, 0x04, 0x83, 0xc6, + 0x0c, 0xc8, 0xfb, 0xc4, 0x89, 0x05, 0x44, 0xbb, 0xdd, 0x82, 0x67, 0x94, 0x40, 0x59, 0xa7, 0x55, + 0xbb, 0xc4, 0x82, 0xaa, 0x57, 0xc6, 0xc4, 0x26, 0xe8, 0x64, 0x7f, 0xdf, 0x05, 0x42, 0xa5, 0x49, + 0x9a, 0x90, 0x10, 0x05, 0x7d, 0xd2, 0xef, 0x9c, 0xa3, 0x11, 0x53, 0x6d, 0xc7, 0x71, 0xfe, 0x8f, + 0x0c, 0xfa, 0xe5, 0xf5, 0xd4, 0x9d, 0x12, 0xbe, 0xbd, 0x2f, 0x57, 0xfa, 0xea, 0x2f, 0x8a, 0x33, + 0xbd, 0xcb, 0x43, 0x96, 0x07, 0x2c, 0xbf, 0xf1, 0x21, 0x62, 0xa3, 0x93, 0xe0, 0x12, 0x5b, 0xcb, + 0xa6, 0x6f, 0xf8, 0x91, 0x01, 0x42, 0xa2, 0x60, 0x8c, 0x08, 0x06, 0x9b, 0x06, 0x55, 0x09, 0x63, + 0x24, 0x4a, 0x90, 0xb1, 0xfb, 0x6a, 0x32, 0x34, 0x16, 0x91, 0x18, 0xcc, 0x01, 0x1e, 0x38, 0xf8, + 0x90, 0x49, 0x6c, 0xb3, 0x40, 0x70, 0x8c, 0xce, 0x1c, 0x48, 0x25, 0x98, 0x9d, 0xaa, 0x0d, 0x1a, + 0xb6, 0x8e, 0xf1, 0x22, 0x41, 0x55, 0x0d, 0xd6, 0x78, 0xac, 0x69, 0x47, 0x44, 0xc7, 0x9c, 0x86, + 0x1f, 0xc1, 0x48, 0xa1, 0x0f, 0x3f, 0x6b, 0x0d, 0xe5, 0x62, 0xbf, 0x10, 0x65, 0xf1, 0xc1, 0xb5, + 0x5e, 0x24, 0x28, 0x2c, 0x3b, 0x2a, 0xf3, 0xb8, 0xe3, 0xac, 0xc2, 0x06, 0x0a, 0x37, 0xf5, 0xe0, + 0x20, 0xb6, 0xaa, 0xb0, 0x99, 0xd3, 0x70, 0x8f, 0xb0, 0xd2, 0x32, 0x59, 0xa6, 0x0f, 0x05, 0x96, + 0x10, 0xf8, 0xc2, 0x32, 0x88, 0xce, 0x84, 0xe8, 0xa0, 0x2e, 0x01, 0x52, 0x7c, 0xff, 0x04, 0x5b, + 0x2b, 0x30, 0x62, 0x8e, 0x3c, 0x4c, 0x29, 0x1e, 0x20, 0xcc, 0x8b, 0xac, 0x68, 0x10, 0x19, 0x71, + 0xc4, 0x0f, 0xba, 0x07, 0xd8, 0x36, 0x33, 0xf7, 0xc1, 0x1e, 0x80, 0x9c, 0x83, 0x06, 0x7f, 0x85, + 0x28, 0x60, 0xed, 0xc8, 0xa2, 0x90, 0x72, 0xe0, 0xcb, 0xe8, 0x43, 0x61, 0x0b, 0x86, 0xb1, 0x08, + 0xc7, 0x74, 0xf8, 0x6b, 0xa5, 0x5f, 0xc2, 0x52, 0x8d, 0xa4, 0xc2, 0x62, 0x86, 0xc0, 0x6b, 0xc0, + 0xb9, 0xe6, 0xb1, 0x30, 0xa6, 0x2b, 0xbc, 0x4f, 0x04, 0x01, 0xd8, 0x1b, 0xa0, 0x6a, 0x36, 0x99, + 0xad, 0xec, 0x57, 0x7e, 0x26, 0x0a, 0x8a, 0x52, 0x0a, 0x22, 0x8c, 0x79, 0xd4, 0xdd, 0x3a, 0x6d, + 0xa7, 0x1c, 0x4c, 0x12, 0xe3, 0x66, 0xbd, 0xe3, 0x13, 0xb7, 0x2d, 0xf0, 0x47, 0xd5, 0xce, 0x8f, + 0xf5, 0x7f, 0x84, 0x84, 0x0f, 0x99, 0x7b, 0xbb, 0xbf, 0xc2, 0x85, 0x74, 0x09, 0x82, 0x1c, 0x00, + 0x02, 0x38, 0x60, 0x4f, 0xc1, 0x9d, 0xc3, 0x14, 0x9e, 0xc3, 0x1f, 0xb3, 0x9b, 0xed, 0xe2, 0x41, + 0x65, 0x20, 0xcc, 0xa5, 0xf0, 0x89, 0x8b, 0x0f, 0xe8, 0x13, 0x31, 0xe3, 0x78, 0xf8, 0xa8, 0x77, + 0x3e, 0x0a, 0xac, 0x20, 0xce, 0x1d, 0x82, 0x06, 0xc0, 0x40, 0x1a, 0x16, 0x45, 0x73, 0xb2, 0xce, + 0x1b, 0xea, 0x74, 0xf8, 0x28, 0x13, 0x9d, 0x43, 0x8f, 0xab, 0x88, 0x26, 0xec, 0x33, 0x5d, 0x84, + 0x69, 0x7c, 0x48, 0x50, 0xc6, 0xeb, 0xbd, 0xee, 0x30, 0xf3, 0xc0, 0x03, 0x8d, 0x0a, 0xc2, 0x40, + 0x78, 0x61, 0x6c, 0x14, 0x68, 0x61, 0xf5, 0x1c, 0x6f, 0xa2, 0xc5, 0xe2, 0x01, 0x39, 0x1e, 0xf1, + 0x58, 0xac, 0x56, 0x2b, 0xbf, 0xc4, 0xc5, 0xd5, 0x45, 0xc7, 0x3c, 0xdf, 0x89, 0xff, 0x0f, 0x8a, + 0x43, 0x24, 0x58, 0x15, 0x1d, 0xe6, 0x20, 0xa4, 0x37, 0x7a, 0x8d, 0xcc, 0x4f, 0x25, 0x32, 0x69, + 0xa9, 0xfe, 0x08, 0xcb, 0x0a, 0xd3, 0x16, 0xe3, 0xfd, 0x5a, 0x5e, 0xb8, 0x5f, 0x45, 0x2a, 0xab, + 0x82, 0x2b, 0xd5, 0x5f, 0xe7, 0xaa, 0x49, 0x34, 0xd7, 0xfa, 0xbf, 0xd4, 0xe2, 0xbe, 0xa4, 0x4a, + 0xea, 0xff, 0x56, 0x7c, 0x12, 0x59, 0xb3, 0x46, 0xaf, 0x5d, 0x1b, 0x6f, 0x8c, 0x22, 0x7a, 0x79, + 0xe6, 0xcb, 0x85, 0x90, 0x54, 0x06, 0xac, 0x4e, 0x38, 0x40, 0x67, 0x97, 0xf8, 0x48, 0x48, 0xba, + 0x8b, 0xdc, 0x8a, 0x2b, 0xaf, 0x13, 0x04, 0x3d, 0x0d, 0x49, 0xfc, 0xf1, 0x00, 0x9c, 0xa4, 0x5a, + 0xb7, 0x94, 0x40, 0x41, 0xf0, 0x81, 0x03, 0xfc, 0x70, 0xff, 0xf1, 0x00, 0x86, 0x68, 0x96, 0x0c, + 0x99, 0x32, 0x0f, 0xf4, 0x4e, 0xf8, 0x22, 0x23, 0xa4, 0xcd, 0xfb, 0xc4, 0x04, 0x69, 0x4a, 0x41, + 0x40, 0xdf, 0x4e, 0xad, 0xa7, 0xc4, 0x02, 0x63, 0xb9, 0xbd, 0x50, 0xe9, 0xa6, 0xff, 0x04, 0x27, + 0xc6, 0x9f, 0x34, 0x90, 0x05, 0xf0, 0x57, 0x20, 0xd4, 0xea, 0xa7, 0x52, 0x22, 0xa5, 0xb6, 0x29, + 0x0e, 0xa1, 0xe0, 0x35, 0x8e, 0xbe, 0x55, 0xc6, 0x0b, 0x7d, 0x19, 0xf8, 0x98, 0x21, 0x96, 0xfd, + 0xcf, 0x82, 0x2b, 0xa5, 0xbf, 0x11, 0x45, 0xff, 0xc1, 0x4e, 0xa7, 0x0c, 0xc1, 0xa1, 0x2b, 0x56, + 0xe0, 0xab, 0xa4, 0x50, 0x11, 0xd7, 0xf0, 0x48, 0x44, 0x3b, 0x11, 0x3f, 0x17, 0xaf, 0x04, 0x59, + 0xdb, 0x42, 0x4b, 0xe2, 0x02, 0x46, 0x61, 0x51, 0x3d, 0xef, 0xe0, 0x98, 0x48, 0xfe, 0x50, 0xf2, + 0x10, 0xaa, 0xe1, 0x88, 0x6b, 0xf5, 0xf5, 0x8e, 0x7c, 0x21, 0x60, 0x4c, 0x04, 0x15, 0xe1, 0xd0, + 0xa4, 0x77, 0x8c, 0x18, 0x66, 0x11, 0x51, 0x11, 0x3d, 0x53, 0xd1, 0x78, 0x52, 0x79, 0x86, 0xa0, + 0xa0, 0x4e, 0xc2, 0x99, 0x59, 0x1c, 0x6c, 0xce, 0xa9, 0x90, 0xdd, 0x4d, 0xae, 0xd0, 0xfb, 0x54, + 0xce, 0x7d, 0x8c, 0xff, 0x05, 0xb1, 0x58, 0x96, 0x8f, 0x77, 0x92, 0x06, 0xf3, 0x9f, 0x05, 0x5c, + 0x7b, 0xca, 0xe8, 0x70, 0x7c, 0xd4, 0x39, 0x74, 0x01, 0xd8, 0x6e, 0xa7, 0xe2, 0x62, 0x28, 0x0f, + 0x2b, 0x13, 0xde, 0xcf, 0xe0, 0xac, 0xac, 0x0a, 0xe9, 0xb0, 0x52, 0xf6, 0x36, 0x55, 0x3e, 0x9e, + 0xf1, 0x20, 0xb2, 0x3c, 0xd1, 0xc6, 0xd5, 0xd0, 0x31, 0xed, 0x18, 0x87, 0x4e, 0x14, 0x4a, 0x1d, + 0x65, 0x2f, 0x82, 0x2a, 0xbe, 0x54, 0xae, 0x34, 0x60, 0x59, 0x57, 0xf6, 0x18, 0xad, 0x38, 0x1f, + 0x98, 0x83, 0x06, 0xc6, 0x0f, 0x13, 0x9f, 0x44, 0x95, 0x41, 0x2e, 0xe4, 0x7b, 0x05, 0xc1, 0x28, + 0x47, 0x04, 0x54, 0xc6, 0xd1, 0x42, 0xf4, 0x06, 0x5f, 0xea, 0xee, 0xda, 0xe8, 0xfd, 0x2f, 0x5c, + 0xbe, 0x89, 0x15, 0x75, 0x7f, 0xa2, 0xe2, 0xf9, 0xaf, 0xab, 0xef, 0x55, 0xfa, 0xca, 0x4e, 0xae, + 0xae, 0xbd, 0xf1, 0xe3, 0x32, 0xe2, 0xde, 0xe7, 0x20, 0xdd, 0xbf, 0x09, 0x94, 0x9d, 0x18, 0x3d, + 0x64, 0x60, 0x9c, 0xbe, 0xeb, 0x85, 0x04, 0xd6, 0x61, 0x82, 0xcc, 0x97, 0x30, 0x08, 0x7c, 0x58, + 0x18, 0x06, 0xf0, 0xee, 0x9b, 0x04, 0x41, 0x22, 0xde, 0xff, 0x45, 0x1d, 0xbe, 0xe2, 0x63, 0x04, + 0x4f, 0x08, 0x41, 0x2f, 0xf0, 0x46, 0x67, 0x15, 0xbb, 0xbf, 0xc2, 0x25, 0x88, 0xa8, 0x32, 0xb9, + 0xa9, 0xc2, 0x2f, 0x63, 0x63, 0x3c, 0x2f, 0xc2, 0x22, 0x06, 0xa7, 0x6b, 0x8d, 0x06, 0xee, 0xee, + 0x84, 0xf7, 0xf0, 0x4c, 0x25, 0x84, 0x86, 0x45, 0xfd, 0x35, 0xe7, 0x38, 0x98, 0x52, 0x80, 0x2f, + 0x57, 0x71, 0xda, 0x74, 0xaf, 0x9c, 0x04, 0x21, 0xed, 0xa0, 0xef, 0xfa, 0xb1, 0xc4, 0x88, 0x19, + 0x60, 0x98, 0xce, 0xcd, 0x43, 0x2d, 0x0f, 0x18, 0x38, 0xda, 0x6b, 0x26, 0x34, 0xce, 0xf7, 0x7a, + 0x0b, 0x9c, 0x40, 0x8f, 0x12, 0x0b, 0xae, 0xbb, 0x02, 0x64, 0xf1, 0xc1, 0xdf, 0x04, 0x3d, 0x58, + 0xfb, 0x88, 0x12, 0x14, 0x24, 0xaa, 0x89, 0xb0, 0xf6, 0x39, 0xe8, 0x68, 0xdf, 0x77, 0xfd, 0xf5, + 0xef, 0x10, 0x14, 0xbb, 0xbb, 0xdc, 0xbc, 0xf7, 0xa4, 0xe3, 0x34, 0xbb, 0xb4, 0x1b, 0x77, 0xfb, + 0x9d, 0x45, 0xd8, 0xaf, 0xc1, 0x59, 0x50, 0x23, 0x2b, 0x10, 0xe4, 0x43, 0x17, 0x63, 0x80, 0x23, + 0x88, 0x16, 0x4c, 0x0c, 0xea, 0x49, 0x1c, 0x3b, 0xe0, 0xa6, 0x16, 0xde, 0xa9, 0x58, 0xc4, 0xea, + 0xa2, 0xf5, 0x43, 0xba, 0xfb, 0x83, 0xe0, 0xa4, 0xad, 0x23, 0x09, 0xf5, 0x50, 0x3f, 0x17, 0x4a, + 0x3e, 0x41, 0xd6, 0xa1, 0x44, 0x43, 0x01, 0x9e, 0x31, 0xf1, 0x00, 0x8c, 0x89, 0x9d, 0x4d, 0xb7, + 0xf8, 0x2e, 0x2d, 0x56, 0x86, 0x30, 0x31, 0x18, 0x54, 0x1e, 0x5c, 0x4c, 0x16, 0x13, 0x47, 0x21, + 0xd8, 0x07, 0x19, 0x1b, 0xf1, 0x80, 0x01, 0xf7, 0x06, 0x05, 0x8f, 0xcf, 0x8e, 0xb0, 0x09, 0x84, + 0x2d, 0x1b, 0xa4, 0x8f, 0x26, 0x11, 0xce, 0x62, 0x97, 0x89, 0x12, 0x0a, 0xaf, 0x68, 0x80, 0xbd, + 0x68, 0x79, 0x05, 0x1d, 0x2f, 0x12, 0x24, 0x61, 0x4c, 0xde, 0x03, 0x54, 0x27, 0xb2, 0x6e, 0xc5, + 0x33, 0x4d, 0x93, 0x29, 0x33, 0x00, 0x4d, 0xf8, 0x22, 0xae, 0xb9, 0x7c, 0x11, 0xf7, 0x67, 0x6f, + 0x12, 0x0b, 0x06, 0x17, 0x63, 0x2a, 0x43, 0x61, 0x55, 0x4d, 0xa3, 0x61, 0xf3, 0x8b, 0x48, 0xe2, + 0x3d, 0xf2, 0xc1, 0xd3, 0x82, 0x4a, 0xb3, 0x16, 0x4c, 0x20, 0x3e, 0x8f, 0x2f, 0xa9, 0x93, 0xea, + 0xef, 0xa9, 0x13, 0xeb, 0xdf, 0x5e, 0xfa, 0xd5, 0x70, 0x47, 0x48, 0xb8, 0x72, 0x35, 0x75, 0xf3, + 0xf5, 0xf6, 0x9a, 0x49, 0x2f, 0x58, 0xa7, 0xeb, 0xdf, 0x04, 0x02, 0xa5, 0x48, 0x5f, 0x77, 0xbd, + 0x86, 0x01, 0x58, 0x0b, 0xf0, 0x01, 0x14, 0x5f, 0x41, 0x1d, 0x65, 0x51, 0xc4, 0x5f, 0xf0, 0xec, + 0x48, 0xc0, 0x1a, 0xea, 0x70, 0xc2, 0x65, 0x55, 0x57, 0xeb, 0xfa, 0x9c, 0xa3, 0x28, 0x9d, 0x3f, + 0xf8, 0x2b, 0x2d, 0x36, 0xeb, 0x17, 0x55, 0xae, 0xbe, 0x28, 0xa3, 0xa0, 0x8b, 0x15, 0x06, 0x33, + 0x08, 0xd6, 0x99, 0x59, 0xf5, 0xaf, 0xa3, 0xff, 0xe0, 0x86, 0xa5, 0x18, 0x24, 0x35, 0x00, 0xba, + 0xb8, 0x26, 0x22, 0x5b, 0xcf, 0x5b, 0x66, 0xee, 0x7c, 0x12, 0xce, 0x41, 0x69, 0x3d, 0x00, 0x48, + 0x41, 0x58, 0x28, 0xff, 0x66, 0xdb, 0x42, 0x2b, 0x3e, 0x0a, 0x3b, 0xba, 0x1d, 0xd3, 0xff, 0x13, + 0x0a, 0x16, 0x53, 0x2d, 0xd8, 0x2d, 0x8c, 0x6d, 0x8c, 0xe2, 0xb1, 0x93, 0x40, 0xac, 0xb7, 0x9b, + 0xbf, 0xc7, 0x1e, 0x20, 0x48, 0x2e, 0xd0, 0x45, 0x08, 0x57, 0xa2, 0x0e, 0x52, 0xb6, 0x29, 0xe5, + 0xf1, 0xe5, 0x6e, 0xd2, 0xd1, 0x91, 0xde, 0x5c, 0x19, 0x19, 0x3c, 0x17, 0x49, 0xdd, 0x53, 0x21, + 0x15, 0xb5, 0x3f, 0xc4, 0xee, 0x86, 0x72, 0x0e, 0xec, 0xfc, 0x16, 0x5a, 0x60, 0xcc, 0xa1, 0x9c, + 0x84, 0xf6, 0xd6, 0x6a, 0x56, 0xf1, 0x08, 0xdd, 0xf5, 0x7f, 0x12, 0x30, 0xea, 0x30, 0x00, 0x38, + 0xba, 0xee, 0x2e, 0x41, 0xe4, 0x86, 0x38, 0xe2, 0x1a, 0x8c, 0x0d, 0x60, 0xb8, 0x28, 0x6e, 0xa4, + 0x09, 0x8a, 0x20, 0xff, 0x05, 0xdd, 0xdd, 0x89, 0x6f, 0x15, 0x9a, 0xee, 0x3c, 0x28, 0x5c, 0x13, + 0xb4, 0x01, 0x01, 0x23, 0xef, 0x3d, 0x62, 0x82, 0x29, 0xf2, 0x19, 0x04, 0x9a, 0x1e, 0x05, 0x90, + 0x20, 0x35, 0x60, 0x43, 0x42, 0x72, 0xa3, 0x27, 0x15, 0xdd, 0xee, 0x2c, 0x21, 0x82, 0x75, 0xeb, + 0xc7, 0x7c, 0x48, 0x4a, 0x40, 0x2b, 0x19, 0xd4, 0xab, 0x09, 0xb5, 0x49, 0x2f, 0x04, 0x31, 0xd0, + 0xe0, 0x2e, 0x07, 0x40, 0x70, 0x02, 0xdc, 0x44, 0x11, 0x59, 0x1e, 0x3b, 0xbe, 0x0a, 0x35, 0x93, + 0x2c, 0x19, 0x18, 0x56, 0x29, 0x23, 0xfc, 0x21, 0x1c, 0x71, 0x50, 0x20, 0xf6, 0xe0, 0x94, 0x60, + 0x96, 0xcb, 0x62, 0x54, 0x8c, 0x77, 0x86, 0xca, 0x00, 0x03, 0x88, 0x10, 0x14, 0xb7, 0x01, 0xb6, + 0x50, 0x84, 0x74, 0xb4, 0x33, 0xe5, 0x43, 0x54, 0x0c, 0x9b, 0x86, 0x29, 0x37, 0x36, 0x1d, 0x70, + 0x45, 0x61, 0x48, 0x47, 0x33, 0x78, 0x90, 0x99, 0x38, 0xf5, 0xca, 0x48, 0x6c, 0x6d, 0xb0, 0xd6, + 0x24, 0x15, 0x4c, 0xc3, 0x88, 0x39, 0x71, 0xe1, 0x80, 0x8a, 0xcb, 0x64, 0x87, 0x51, 0xc7, 0x9f, + 0x14, 0x32, 0xe9, 0xd5, 0x3b, 0x35, 0xd0, 0xb8, 0xbe, 0xb9, 0xcb, 0xeb, 0x5f, 0x44, 0x8a, 0x7e, + 0x8a, 0xd2, 0x73, 0xd5, 0xa6, 0x92, 0x4b, 0xd7, 0x34, 0xac, 0x07, 0xc7, 0x69, 0x10, 0x34, 0x30, + 0x31, 0x6f, 0x1c, 0x23, 0x2f, 0x3f, 0x7f, 0x9a, 0x0e, 0x48, 0xd4, 0xc0, 0xde, 0x7c, 0xbf, 0x04, + 0xb5, 0x55, 0x55, 0x55, 0x5f, 0xf8, 0x90, 0x5d, 0xa5, 0x77, 0x77, 0x7e, 0xf8, 0x21, 0x12, 0x78, + 0xa6, 0x85, 0xb5, 0x70, 0x46, 0x20, 0x7a, 0xf3, 0x63, 0x47, 0x4b, 0xff, 0x43, 0x53, 0xaf, 0x04, + 0x44, 0x63, 0x8c, 0xf3, 0x04, 0x3e, 0xf8, 0x24, 0xa6, 0xdd, 0xb6, 0xf8, 0x23, 0xb7, 0x6d, 0x3f, + 0xfc, 0x29, 0x9e, 0x8e, 0xd7, 0x14, 0x10, 0x08, 0x99, 0x8e, 0x96, 0x38, 0x31, 0x6b, 0x4c, 0xea, + 0x53, 0x9c, 0x5e, 0x20, 0x11, 0x63, 0x95, 0x0a, 0xe6, 0xde, 0x21, 0x7e, 0x78, 0x80, 0x4e, 0x45, + 0xaa, 0xaa, 0xff, 0xf8, 0x28, 0xcf, 0x47, 0xb4, 0x3d, 0x5f, 0xe3, 0x0e, 0x1a, 0x40, 0x8a, 0xdb, + 0x07, 0x86, 0x09, 0x9d, 0x0e, 0x02, 0xbe, 0x6c, 0x36, 0x46, 0xb0, 0x6c, 0x2f, 0xc4, 0x88, 0x46, + 0xee, 0x26, 0x0a, 0x2e, 0x2b, 0x3f, 0xb7, 0xa6, 0x81, 0xc5, 0xf1, 0x82, 0x64, 0x38, 0x22, 0x20, + 0x27, 0xf1, 0xa4, 0x28, 0x36, 0x87, 0x07, 0x83, 0x49, 0x95, 0xb2, 0x42, 0x12, 0xe3, 0x73, 0xe3, + 0xe1, 0x4a, 0x0c, 0x71, 0xb0, 0xa1, 0x06, 0xd5, 0x11, 0x1a, 0xf6, 0x9b, 0xa1, 0x35, 0x44, 0x0d, + 0xb8, 0x5b, 0xcb, 0x09, 0x44, 0x09, 0x53, 0xe0, 0x8f, 0x7b, 0xe7, 0xf8, 0x24, 0xbe, 0xe5, 0x4f, + 0x12, 0x08, 0xa3, 0xa3, 0x0a, 0x9f, 0xef, 0x10, 0x6b, 0xdf, 0xe0, 0xa3, 0x30, 0x60, 0x32, 0x04, + 0x21, 0x44, 0xc9, 0x4e, 0x85, 0xb2, 0xda, 0x2d, 0xf1, 0x06, 0xc6, 0x85, 0x42, 0xc0, 0x75, 0x78, + 0xc9, 0x31, 0x36, 0x11, 0x03, 0x01, 0x94, 0x82, 0xdc, 0x5b, 0xa0, 0x13, 0x67, 0x53, 0x7f, 0xc2, + 0x25, 0x2b, 0x15, 0x90, 0xfd, 0x65, 0x82, 0x07, 0x2c, 0xb4, 0x02, 0x1f, 0x79, 0x78, 0x88, 0x2e, + 0x26, 0x4d, 0xab, 0x79, 0xc1, 0xf0, 0x58, 0x43, 0xa1, 0x79, 0x8c, 0x64, 0xed, 0x8c, 0xca, 0xd8, + 0x38, 0x4b, 0xc6, 0x09, 0x81, 0xc7, 0x7c, 0x11, 0x11, 0xdc, 0xfe, 0xfb, 0xc4, 0x02, 0x23, 0xbb, + 0xb8, 0xae, 0x2a, 0xe8, 0x47, 0x7c, 0x3b, 0x00, 0xce, 0x9b, 0x65, 0x34, 0x20, 0xb4, 0xa2, 0xcb, + 0xe0, 0xfc, 0xbc, 0x1e, 0xc2, 0x0d, 0xa0, 0x75, 0xf1, 0x8b, 0x47, 0x50, 0x70, 0x98, 0xff, 0xd1, + 0xe3, 0x2b, 0x98, 0xf5, 0x55, 0xf0, 0x48, 0x6a, 0xab, 0xca, 0xfa, 0xd6, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x29, 0x14, 0xb0, 0x32, 0x80, 0xd1, 0xd0, 0xd8, 0xa3, 0x79, 0x8c, 0xea, 0xea, 0x10, + 0x84, 0x04, 0x02, 0xe8, 0xad, 0xc5, 0x6e, 0xd8, 0x2a, 0xa1, 0x87, 0x55, 0x76, 0xc1, 0x58, 0x31, + 0x00, 0xd1, 0xa8, 0xfc, 0x40, 0x60, 0x10, 0x19, 0xc5, 0x6e, 0xf5, 0xd7, 0x86, 0x91, 0x41, 0x50, + 0x28, 0x29, 0x06, 0xd8, 0x0f, 0x74, 0xe3, 0xa1, 0x19, 0x1c, 0x23, 0xb4, 0x3c, 0x06, 0xf3, 0xfd, + 0xb2, 0x7f, 0x04, 0x83, 0x4f, 0x43, 0xd3, 0xa8, 0x34, 0xc4, 0x02, 0x71, 0x11, 0x0b, 0x75, 0x1a, + 0x71, 0x9b, 0x8e, 0xc6, 0x9b, 0xe0, 0x31, 0xf8, 0x50, 0x66, 0xff, 0xb6, 0xd3, 0x3c, 0x06, 0xf2, + 0x18, 0x08, 0x3a, 0x78, 0x7b, 0x49, 0x33, 0x02, 0x6c, 0x7b, 0x88, 0x60, 0x5b, 0xf7, 0x10, 0x10, + 0x04, 0xd0, 0x3b, 0x4b, 0xa0, 0x35, 0x2e, 0xb1, 0x3a, 0x4b, 0x8f, 0x06, 0x91, 0x21, 0x14, 0x17, + 0x1c, 0x01, 0xbc, 0x48, 0x50, 0x28, 0x12, 0x29, 0x54, 0xf1, 0x77, 0x45, 0x67, 0xef, 0x69, 0x9c, + 0x60, 0xe3, 0x1a, 0x4f, 0x0b, 0x67, 0x9e, 0x2b, 0x6a, 0x1f, 0x7c, 0x65, 0xd3, 0x02, 0xa0, 0x74, + 0x54, 0xee, 0xef, 0x2c, 0x62, 0x5e, 0x58, 0x37, 0xc2, 0xf7, 0x2f, 0x43, 0x6e, 0x41, 0x07, 0x47, + 0x22, 0x47, 0xf0, 0x49, 0x17, 0x17, 0x17, 0x17, 0x1c, 0x1b, 0xe1, 0xd0, 0xa1, 0xd9, 0x53, 0xb3, + 0xd2, 0x1f, 0x73, 0x25, 0xa3, 0x3f, 0xd9, 0x13, 0x6a, 0x2d, 0xb4, 0x90, 0x92, 0x1f, 0xf0, 0xa4, + 0xb1, 0xbf, 0x8a, 0xed, 0x71, 0x9d, 0xb8, 0x30, 0x12, 0xd8, 0xec, 0x97, 0x8a, 0x35, 0x67, 0x15, + 0x91, 0xb6, 0xcc, 0x1f, 0x71, 0x02, 0x10, 0xf4, 0xf3, 0x43, 0x22, 0x01, 0x01, 0x85, 0xfe, 0x02, + 0x1e, 0x2e, 0xe7, 0xe8, 0xa9, 0x4c, 0x2d, 0xe5, 0xe3, 0x5c, 0x09, 0xfd, 0x55, 0x80, 0x9e, 0x87, + 0xe1, 0x73, 0x51, 0x2d, 0xd0, 0x79, 0xc0, 0x3f, 0xd1, 0xcf, 0xf8, 0x80, 0x50, 0x23, 0xf2, 0xcc, + 0x0d, 0xa7, 0xc4, 0x82, 0x20, 0x36, 0xfc, 0x8f, 0xe2, 0x01, 0x44, 0xb0, 0x62, 0x8e, 0xdc, 0x50, + 0x62, 0x01, 0x0c, 0x05, 0xef, 0xbc, 0x40, 0xb8, 0xae, 0x2b, 0x12, 0xc1, 0xe7, 0x39, 0x0c, 0x74, + 0x15, 0x8a, 0xba, 0x92, 0xfa, 0xc3, 0x1e, 0xa9, 0x10, 0xae, 0xa9, 0x97, 0xaa, 0x64, 0xba, 0xc5, + 0xc4, 0x51, 0x22, 0xf1, 0x01, 0x41, 0xc5, 0xd8, 0x85, 0x82, 0x7b, 0x4c, 0xa9, 0x2e, 0x28, 0xc4, + 0x8d, 0x04, 0xb8, 0x5b, 0x77, 0x94, 0x40, 0x71, 0x3e, 0x36, 0x1d, 0x01, 0x12, 0x05, 0xac, 0xa4, + 0x69, 0x82, 0xde, 0xee, 0x6a, 0x4c, 0xe1, 0x63, 0x50, 0x88, 0xb2, 0x0d, 0xec, 0x65, 0xf6, 0xa8, + 0xcb, 0x7d, 0x5d, 0x7f, 0xc1, 0x30, 0x97, 0x1b, 0x2c, 0x2b, 0x88, 0x16, 0x0f, 0x40, 0xa0, 0x37, + 0x3e, 0x3b, 0xf4, 0x2c, 0xa9, 0x7c, 0xc3, 0x23, 0x59, 0x1b, 0x87, 0x14, 0x59, 0xe2, 0x20, 0x90, + 0x55, 0x8e, 0x6c, 0xef, 0x88, 0x2b, 0xe6, 0x04, 0xc6, 0xa6, 0xda, 0x10, 0xb8, 0x3e, 0x03, 0x89, + 0x2f, 0x04, 0xa7, 0x59, 0x20, 0xc0, 0x63, 0x61, 0x04, 0xf8, 0xec, 0x71, 0xf8, 0x2e, 0xa0, 0x66, + 0x93, 0x4f, 0x22, 0xa2, 0xe2, 0xe2, 0xe2, 0x3a, 0x8f, 0x10, 0x0a, 0x8c, 0x2e, 0x90, 0x0f, 0xcb, + 0x22, 0xd0, 0x25, 0xa4, 0x80, 0x04, 0x84, 0x66, 0x2c, 0xcc, 0x77, 0x25, 0x2d, 0x8b, 0x48, 0x25, + 0x1c, 0x82, 0x5b, 0xc2, 0x02, 0x4a, 0x5e, 0x46, 0x4e, 0x3d, 0xbd, 0x68, 0xcd, 0x43, 0xe1, 0x9e, + 0x85, 0xe1, 0x27, 0x46, 0x61, 0xeb, 0xd3, 0xf4, 0x25, 0x2a, 0xf5, 0x4c, 0xbd, 0x7b, 0xeb, 0xde, + 0x20, 0x15, 0x11, 0xdf, 0x71, 0xb0, 0x44, 0x72, 0xe0, 0x3c, 0xf0, 0x4b, 0x87, 0x03, 0xdf, 0x88, + 0x8d, 0x10, 0x4c, 0x1a, 0x1c, 0x12, 0x09, 0x58, 0x58, 0x27, 0x80, 0x08, 0x26, 0xf5, 0x21, 0x31, + 0xf5, 0x12, 0x35, 0x23, 0x80, 0x11, 0x95, 0x90, 0x1e, 0xc1, 0x04, 0x45, 0xc9, 0xeb, 0xfe, 0x20, + 0x28, 0x43, 0xd5, 0x07, 0x80, 0x16, 0x0f, 0x58, 0x3c, 0x00, 0xc0, 0xa9, 0xe8, 0x56, 0x0e, 0x81, + 0xd1, 0x5a, 0x24, 0x00, 0x02, 0x28, 0x01, 0x8a, 0x34, 0xc4, 0xe0, 0x05, 0x31, 0x9b, 0xa2, 0x2c, + 0xc2, 0xaa, 0x36, 0xef, 0x11, 0x9f, 0x7a, 0x0a, 0x94, 0xea, 0xf2, 0x79, 0x0e, 0x7b, 0xff, 0xa1, + 0x75, 0xc3, 0x61, 0xc5, 0x6d, 0xc3, 0x8f, 0xf8, 0xe1, 0xde, 0x20, 0x2c, 0x24, 0xa8, 0xb5, 0xef, + 0x8a, 0xbc, 0x65, 0xb0, 0x84, 0x13, 0x35, 0x3e, 0x0b, 0x04, 0xa3, 0x08, 0x1a, 0xff, 0xad, 0x5c, + 0x98, 0x80, 0xb8, 0xa3, 0x5b, 0x54, 0x45, 0x6c, 0xcf, 0x9d, 0x3d, 0x15, 0x5f, 0xfc, 0x13, 0x09, + 0x15, 0x9f, 0x88, 0x7d, 0xd0, 0xd4, 0x5d, 0x26, 0x18, 0x81, 0x23, 0x44, 0xa9, 0xd4, 0x66, 0xc5, + 0x17, 0x17, 0xa5, 0x54, 0x90, 0xa6, 0x68, 0xef, 0xdd, 0x5f, 0xfc, 0x12, 0x12, 0xb3, 0xd7, 0xc7, + 0x11, 0xe2, 0x04, 0x82, 0x91, 0x91, 0x58, 0x80, 0x79, 0xe2, 0xc1, 0xe2, 0x91, 0x2d, 0x42, 0x47, + 0x3f, 0x3f, 0xa8, 0x4e, 0x8c, 0xd6, 0x3c, 0x4a, 0x0a, 0xbc, 0xbd, 0x5e, 0x10, 0xea, 0x9d, 0xbe, + 0x84, 0x3f, 0xd1, 0x5e, 0x4e, 0x8e, 0x5e, 0x49, 0xd1, 0x1c, 0x88, 0xc4, 0xf8, 0x90, 0x56, 0x39, + 0xf2, 0x74, 0x09, 0x5d, 0xcd, 0xc8, 0xa5, 0xfd, 0x72, 0x95, 0x04, 0xb8, 0x6d, 0xc0, 0x12, 0x82, + 0xcf, 0xec, 0x01, 0xa6, 0x41, 0x3b, 0x27, 0x42, 0xf0, 0xac, 0x4d, 0x32, 0xb2, 0x65, 0xab, 0x69, + 0x56, 0x5a, 0xf8, 0x8f, 0x7b, 0x02, 0x92, 0xe2, 0x25, 0x06, 0x09, 0x44, 0x7c, 0x8c, 0x15, 0xd7, + 0x60, 0x03, 0x44, 0x66, 0x81, 0x7a, 0x33, 0xea, 0xeb, 0xc4, 0x06, 0x01, 0x35, 0x99, 0xd0, 0x74, + 0xf9, 0x59, 0xd0, 0xaa, 0x74, 0x5a, 0x12, 0xf1, 0x62, 0x3f, 0x91, 0xb6, 0xa7, 0xfa, 0x08, 0xff, + 0xea, 0x57, 0xfc, 0x13, 0x8e, 0xbd, 0xcb, 0x84, 0x8a, 0x86, 0x91, 0xb8, 0x14, 0x0c, 0x3c, 0x16, + 0x99, 0x4d, 0x05, 0x92, 0xfc, 0xdc, 0x78, 0x22, 0x1e, 0x4c, 0x4a, 0xff, 0x1e, 0x0a, 0x28, 0x73, + 0x08, 0x27, 0x6e, 0x5a, 0xb0, 0x12, 0x30, 0xaf, 0x04, 0x83, 0x92, 0x0a, 0xd8, 0x9c, 0xc9, 0x37, + 0x4f, 0xf1, 0x30, 0x53, 0x08, 0x44, 0x5b, 0x30, 0x2a, 0xd0, 0xa8, 0x0b, 0x86, 0x65, 0xb5, 0x63, + 0x0b, 0x1b, 0xe0, 0xf8, 0xb7, 0xc6, 0xd2, 0x0e, 0xf8, 0xfc, 0xf8, 0x70, 0x41, 0x12, 0x13, 0x2c, + 0x65, 0xb2, 0xd8, 0x95, 0x27, 0x2e, 0x7a, 0x29, 0x12, 0xfa, 0x25, 0x57, 0x46, 0x83, 0xe0, 0x8a, + 0xee, 0xab, 0x28, 0xee, 0xb8, 0x7d, 0x09, 0x72, 0xfa, 0xb5, 0xf5, 0x70, 0x5e, 0x8c, 0xc9, 0x7a, + 0x12, 0x54, 0xbe, 0xa3, 0xb7, 0x13, 0x42, 0x22, 0xe2, 0x04, 0x02, 0x51, 0x4c, 0x3b, 0x78, 0xb9, + 0x39, 0x89, 0x1f, 0x49, 0x7f, 0x85, 0x22, 0x80, 0x13, 0xc8, 0x8b, 0x19, 0x1d, 0x14, 0x09, 0xe8, + 0xca, 0xa8, 0xf7, 0x9d, 0x66, 0x95, 0x38, 0xe3, 0xe9, 0xa8, 0x1c, 0x20, 0xe4, 0x3e, 0x9e, 0x98, + 0x0f, 0x3e, 0x17, 0x9a, 0x41, 0xfc, 0xbf, 0x79, 0x8e, 0x03, 0x94, 0x95, 0x89, 0xe3, 0x2e, 0x3b, + 0xc4, 0x84, 0x41, 0x59, 0x09, 0x8f, 0xf7, 0xd7, 0x93, 0x84, 0x95, 0xcd, 0x6e, 0x16, 0x5a, 0x90, + 0x77, 0x21, 0x4d, 0x7f, 0x85, 0xf7, 0xa7, 0x02, 0x99, 0xd7, 0x65, 0x25, 0xbe, 0x09, 0x02, 0xae, + 0xfa, 0x40, 0xf5, 0x2a, 0x2a, 0xf0, 0x58, 0x16, 0x39, 0x81, 0x6c, 0x56, 0x3e, 0xce, 0x32, 0x30, + 0x66, 0x93, 0x69, 0x1e, 0xe5, 0xe7, 0xa5, 0xe5, 0xe2, 0x41, 0x30, 0xd1, 0x20, 0xe1, 0xfb, 0xf3, + 0x6f, 0xe5, 0xf6, 0xf8, 0x28, 0xcc, 0xd3, 0x80, 0x00, 0x44, 0x43, 0x21, 0x8d, 0x8a, 0x3c, 0x32, + 0x07, 0x0f, 0xc6, 0x2a, 0xe5, 0x40, 0xd9, 0xab, 0x27, 0x89, 0xff, 0x8f, 0xf1, 0x31, 0x82, 0xb2, + 0x71, 0xec, 0xaa, 0x7e, 0x12, 0x49, 0xb8, 0x4c, 0x7a, 0xf0, 0x1f, 0x64, 0x8d, 0x0e, 0xd7, 0x29, + 0x21, 0x14, 0x79, 0x49, 0x8e, 0x37, 0x82, 0x9a, 0x19, 0xa9, 0x4d, 0x64, 0xab, 0xed, 0xc7, 0xfd, + 0xdf, 0xc4, 0xa0, 0x9c, 0x5f, 0x52, 0x37, 0xd7, 0xbe, 0x8d, 0x5f, 0x5e, 0xfa, 0xe1, 0x5d, 0x1d, + 0xd1, 0xfd, 0x1d, 0x8b, 0xe8, 0x8e, 0x44, 0xf4, 0x49, 0x9f, 0x47, 0x3a, 0x5f, 0x53, 0xa4, 0x9d, + 0x12, 0xbe, 0xa5, 0xb8, 0x90, 0x88, 0x25, 0x19, 0x92, 0xe7, 0x60, 0x7d, 0x57, 0xef, 0x85, 0x27, + 0xb0, 0x70, 0x2a, 0x0c, 0x8d, 0x4f, 0x00, 0x70, 0x90, 0x15, 0x9f, 0x8f, 0x31, 0x63, 0xed, 0x08, + 0x03, 0xa1, 0xec, 0x12, 0x82, 0xa3, 0xab, 0x1e, 0x45, 0xb2, 0x27, 0x02, 0xa7, 0x90, 0x80, 0x34, + 0x63, 0xf1, 0x82, 0x2f, 0x80, 0xcd, 0x92, 0x08, 0xe6, 0x57, 0xab, 0xd8, 0x25, 0x4d, 0x45, 0x33, + 0xf8, 0xec, 0x2c, 0x32, 0x94, 0xa4, 0x7a, 0x35, 0x08, 0x38, 0x69, 0x57, 0xa8, 0x71, 0x3c, 0xc4, + 0x41, 0x01, 0xde, 0x52, 0x0a, 0x06, 0xd9, 0xcf, 0x70, 0x3b, 0x18, 0xf3, 0x81, 0xd8, 0x7e, 0x98, + 0x2a, 0xc7, 0x4e, 0x6d, 0x36, 0xa5, 0x48, 0xbb, 0xe3, 0x7c, 0xbe, 0xdb, 0x19, 0x99, 0x6a, 0x53, + 0x85, 0x70, 0x9b, 0xe0, 0xc9, 0xb9, 0x15, 0xc6, 0x38, 0xb9, 0x8f, 0xdd, 0xb6, 0xfc, 0x24, 0x46, + 0xfa, 0x3b, 0x9d, 0xf5, 0x55, 0x13, 0x17, 0x20, 0xb0, 0xf6, 0x43, 0x84, 0x2c, 0x3e, 0x25, 0x8f, + 0xf8, 0x29, 0x16, 0x10, 0xf7, 0x20, 0x1a, 0xd5, 0x68, 0x2c, 0xcb, 0x76, 0x97, 0x0b, 0x40, 0x40, + 0xbf, 0x68, 0x9b, 0x47, 0xfd, 0xbb, 0xf8, 0x90, 0x42, 0x2d, 0x82, 0xe6, 0x5f, 0xbe, 0xb0, 0x57, + 0x46, 0xaf, 0xa3, 0x91, 0x3e, 0xb8, 0x4f, 0xd7, 0xbe, 0xaf, 0x0a, 0x75, 0xea, 0xeb, 0x14, 0x9d, + 0x10, 0xa9, 0xf5, 0x3a, 0x5f, 0x04, 0x9a, 0x09, 0x91, 0x65, 0x87, 0x13, 0x05, 0x82, 0x87, 0x10, + 0x7d, 0xc5, 0x79, 0xe8, 0x3e, 0x45, 0x4d, 0x33, 0x2f, 0xeb, 0x82, 0x3f, 0xf8, 0x80, 0xa1, 0xb3, + 0x60, 0x9e, 0x0c, 0x59, 0x22, 0xed, 0x9c, 0xc5, 0xea, 0x32, 0x19, 0x31, 0xf0, 0xf1, 0x67, 0x16, + 0x48, 0x1f, 0x69, 0x93, 0x2e, 0xf1, 0x01, 0x4b, 0xc8, 0x80, 0xe5, 0x46, 0x64, 0x55, 0x59, 0x37, + 0x16, 0x92, 0xdd, 0x85, 0xb1, 0x9e, 0x19, 0x70, 0xb2, 0xaa, 0x89, 0x38, 0xa0, 0x6f, 0x8b, 0x22, + 0xe7, 0xc2, 0x87, 0x4e, 0x88, 0x2b, 0x5c, 0x6e, 0x13, 0x0b, 0x60, 0xf3, 0xc4, 0x00, 0x94, 0x61, + 0x1d, 0xf0, 0xb1, 0x22, 0x9e, 0xe3, 0xd0, 0xa1, 0x84, 0x21, 0xd4, 0x8e, 0x68, 0x39, 0x67, 0xdf, + 0x0a, 0x49, 0xd2, 0x11, 0xee, 0xa1, 0xba, 0x85, 0x1b, 0xe5, 0x59, 0xd0, 0x00, 0x09, 0x92, 0x39, + 0x44, 0x9f, 0x50, 0x7e, 0x05, 0xea, 0x15, 0x8a, 0x47, 0x6f, 0x85, 0x2f, 0x66, 0x05, 0xa8, 0xa6, + 0x29, 0x85, 0x6a, 0x71, 0x48, 0xd9, 0xb6, 0xae, 0x18, 0x7e, 0x97, 0x18, 0xe3, 0x7c, 0x51, 0xae, + 0xf1, 0xbf, 0x37, 0x23, 0x2d, 0xf8, 0xe9, 0x72, 0x92, 0x99, 0x08, 0x27, 0x1d, 0x00, 0x5c, 0x9d, + 0x06, 0x0b, 0xae, 0x5f, 0xfc, 0x40, 0x94, 0x13, 0xaa, 0xea, 0x9e, 0x23, 0xa3, 0x8e, 0xaf, 0xa3, + 0x35, 0xf5, 0xa8, 0xde, 0xad, 0x15, 0xd4, 0xcb, 0x3e, 0xa3, 0xb7, 0xd1, 0x32, 0xbe, 0x8a, 0x9d, + 0x3c, 0x48, 0x20, 0x1c, 0x1c, 0x69, 0x12, 0x0f, 0x98, 0xb2, 0xf1, 0x02, 0xe2, 0x8c, 0x43, 0xcb, + 0x67, 0x8f, 0x1e, 0x7c, 0x63, 0xf1, 0x7a, 0xff, 0x12, 0x10, 0xa7, 0x52, 0x1d, 0x7e, 0xe2, 0x8c, + 0x51, 0x96, 0x30, 0xba, 0x28, 0x2e, 0x50, 0x00, 0x09, 0x6c, 0xb7, 0xe1, 0x42, 0x8f, 0x82, 0x11, + 0xfd, 0xec, 0x35, 0x8c, 0x4a, 0x20, 0x6d, 0x56, 0xf3, 0x43, 0x59, 0x3b, 0x10, 0xc5, 0xe4, 0x29, + 0x5c, 0xff, 0x0a, 0x12, 0x03, 0x30, 0x80, 0xd4, 0xf2, 0x91, 0x8a, 0x4e, 0x3d, 0x42, 0x06, 0xce, + 0x30, 0xbd, 0x86, 0x99, 0x99, 0x82, 0x63, 0xc8, 0xef, 0x13, 0x05, 0x32, 0xc7, 0x65, 0xb7, 0x7b, + 0xde, 0xf3, 0x27, 0xc1, 0x49, 0xc5, 0xd1, 0x4f, 0x5a, 0xef, 0x34, 0x42, 0x22, 0x0a, 0x5c, 0xc3, + 0x05, 0x71, 0xcd, 0xf0, 0x43, 0xa0, 0xea, 0xf7, 0xf1, 0x23, 0x06, 0x44, 0xf1, 0xec, 0x9c, 0xdc, + 0x24, 0xd5, 0xcc, 0xa3, 0x06, 0xd1, 0x71, 0xcc, 0x59, 0xce, 0x71, 0x20, 0x94, 0x2a, 0xa4, 0xee, + 0xd8, 0x10, 0x39, 0xe3, 0xff, 0x5d, 0x47, 0x68, 0xae, 0xae, 0x4f, 0xd6, 0xab, 0xa9, 0x8d, 0xf5, + 0x4a, 0x89, 0xce, 0x71, 0xc9, 0x53, 0x4d, 0x34, 0xfd, 0x70, 0x99, 0x12, 0x4b, 0x69, 0xa4, 0xe7, + 0xe0, 0x8c, 0x8b, 0x5b, 0x1f, 0x56, 0x3e, 0xb2, 0x9b, 0x82, 0x62, 0xa4, 0x85, 0x4e, 0x9d, 0x3a, + 0xbe, 0x3c, 0x2d, 0x10, 0xfc, 0xb1, 0xbf, 0x89, 0x70, 0xf1, 0x31, 0x06, 0xb7, 0x87, 0x7c, 0x2f, + 0x2f, 0xf0, 0xa1, 0x5f, 0x96, 0x3c, 0xf0, 0xe7, 0x1d, 0xcb, 0x62, 0x10, 0xc0, 0x44, 0x11, 0xc7, + 0x0d, 0x08, 0x23, 0xab, 0xb1, 0xe0, 0x34, 0x82, 0x0a, 0xc0, 0x56, 0xc2, 0x6c, 0x4b, 0x2e, 0x1e, + 0x01, 0x20, 0x88, 0x4c, 0x21, 0xaa, 0x63, 0x64, 0x80, 0x08, 0x7e, 0x00, 0xe6, 0x61, 0xe0, 0xaf, + 0x3e, 0x98, 0x93, 0x99, 0xce, 0x5d, 0x07, 0x71, 0x0e, 0x16, 0x36, 0x3e, 0x14, 0xab, 0x4c, 0xca, + 0xc4, 0x90, 0xc7, 0x48, 0xb8, 0x70, 0x2c, 0x10, 0x09, 0xb4, 0xe6, 0x98, 0x3f, 0x20, 0xff, 0x0d, + 0x87, 0xcc, 0x7c, 0x16, 0x1d, 0x44, 0x73, 0x6d, 0xa5, 0x86, 0x82, 0x7a, 0x8b, 0x9b, 0x09, 0xbe, + 0x35, 0xda, 0x70, 0x53, 0x7c, 0x29, 0x46, 0x6c, 0x4a, 0x21, 0x76, 0x89, 0x85, 0xf8, 0xac, 0xe1, + 0xce, 0xdd, 0xdf, 0x8e, 0xfc, 0x15, 0xcd, 0x5d, 0x55, 0x20, 0x40, 0x11, 0xd4, 0x4d, 0x48, 0x91, + 0x67, 0x1f, 0x88, 0x04, 0x44, 0x84, 0x48, 0xaa, 0x23, 0xab, 0xbf, 0xc1, 0x36, 0x22, 0xb2, 0x1b, + 0xe9, 0xa3, 0x57, 0x9d, 0xf8, 0xbd, 0xe4, 0xe8, 0x26, 0x9d, 0xfa, 0xa5, 0x3e, 0xa4, 0x4b, 0xea, + 0xe0, 0x25, 0xd1, 0x1f, 0xea, 0x91, 0x79, 0x08, 0xab, 0xfa, 0xbf, 0xd5, 0x32, 0x7d, 0x15, 0xa2, + 0xf8, 0x24, 0xda, 0x8d, 0x0c, 0x46, 0x1e, 0x09, 0xc2, 0x04, 0xb2, 0x5a, 0xb7, 0x2a, 0x27, 0x05, + 0x2f, 0xff, 0xc2, 0x84, 0x27, 0x02, 0x60, 0x48, 0xc4, 0x45, 0xf6, 0x50, 0xb2, 0x05, 0xed, 0xe0, + 0x3d, 0xef, 0xe4, 0x28, 0x7e, 0xf8, 0xcc, 0xf0, 0x09, 0x1c, 0x6a, 0x2c, 0x1d, 0xa5, 0x47, 0xda, + 0x25, 0x40, 0xca, 0xf6, 0xf4, 0x69, 0x8b, 0xe7, 0xd4, 0x4e, 0x54, 0x4e, 0xed, 0x74, 0xaf, 0x5a, + 0xb5, 0x53, 0x45, 0x88, 0x70, 0x99, 0xf8, 0xc9, 0x49, 0x77, 0xae, 0xf1, 0x21, 0x4a, 0x84, 0x2a, + 0x6f, 0xb0, 0x1a, 0xed, 0x63, 0x93, 0xc1, 0x73, 0x0f, 0x7b, 0x0d, 0x8c, 0x96, 0x3d, 0x44, 0xed, + 0xe2, 0xf9, 0x15, 0xea, 0xf9, 0x3f, 0x60, 0x50, 0x9b, 0x12, 0x3e, 0xb9, 0x75, 0xf7, 0x56, 0x65, + 0xdb, 0xdd, 0x44, 0x35, 0x4e, 0x1c, 0xb0, 0xaa, 0x7c, 0x17, 0x1c, 0x5e, 0x22, 0x2b, 0x1a, 0x06, + 0xa7, 0xe2, 0x82, 0xf9, 0x7e, 0xff, 0x18, 0x49, 0x07, 0x49, 0x1f, 0x38, 0xe4, 0x39, 0x1d, 0xa2, + 0xc0, 0x78, 0x68, 0xcd, 0x99, 0x50, 0x2b, 0xb9, 0x83, 0x5e, 0x65, 0xfc, 0xf4, 0xb5, 0x2c, 0x12, + 0x3e, 0xc6, 0xc5, 0xb1, 0xa5, 0x8b, 0x85, 0x6d, 0xe1, 0xb0, 0x66, 0xea, 0x9c, 0x24, 0x7c, 0xc0, + 0xda, 0x00, 0x15, 0x27, 0x89, 0x86, 0x0d, 0xe0, 0x0b, 0x7f, 0x6c, 0xdc, 0x48, 0x50, 0xa5, 0x85, + 0x70, 0x1e, 0x3c, 0x56, 0x01, 0x09, 0x4c, 0x24, 0xa0, 0x11, 0x37, 0xcc, 0x52, 0x72, 0x87, 0xf8, + 0x4f, 0x87, 0x19, 0xf9, 0x8a, 0x2e, 0x69, 0xb8, 0x31, 0x07, 0xa6, 0x61, 0xbb, 0xc0, 0x42, 0x18, + 0x71, 0x5c, 0x97, 0x65, 0x2e, 0x1f, 0x0f, 0xfd, 0x2b, 0xf7, 0xc2, 0x87, 0xce, 0x47, 0x4f, 0xca, + 0xa8, 0xb9, 0x16, 0xf7, 0x65, 0xb8, 0x5b, 0x42, 0x74, 0x68, 0xe2, 0xf3, 0x4f, 0xf0, 0x49, 0x3f, + 0x6e, 0xbd, 0xf0, 0x80, 0xa1, 0x1c, 0x07, 0xde, 0x23, 0xd4, 0x9c, 0x98, 0x52, 0xf8, 0xe2, 0x3f, + 0xe8, 0x2a, 0x66, 0x8b, 0xe8, 0xa9, 0x61, 0x0e, 0x84, 0x32, 0x4e, 0x8f, 0x84, 0x5f, 0x42, 0xdc, + 0xfa, 0x14, 0x3b, 0x8f, 0xa1, 0x5a, 0xf8, 0x52, 0x68, 0x04, 0x14, 0xfd, 0x83, 0x03, 0xc9, 0x0a, + 0x10, 0xbc, 0x83, 0x42, 0x2f, 0x9b, 0xbb, 0xa5, 0x2d, 0x1c, 0x76, 0x70, 0xe2, 0x06, 0x98, 0x91, + 0x88, 0x06, 0xf0, 0x78, 0xb0, 0x7b, 0x68, 0x85, 0x69, 0xfd, 0x14, 0x51, 0x03, 0xa7, 0x83, 0x56, + 0x3a, 0xee, 0x98, 0x97, 0x1f, 0xeb, 0x7a, 0x0e, 0x31, 0xf0, 0xfd, 0x5f, 0xd1, 0xf8, 0x50, 0xcd, + 0x4b, 0x37, 0x26, 0x15, 0x9d, 0x39, 0xf6, 0x35, 0xdd, 0xf5, 0x5a, 0x35, 0x96, 0x7f, 0x12, 0x09, + 0x84, 0x85, 0x04, 0xb8, 0x5f, 0x46, 0x8c, 0x1a, 0xed, 0xce, 0x41, 0xbe, 0x3b, 0xf0, 0xa1, 0x0e, + 0xab, 0x28, 0xb8, 0xa6, 0x03, 0x9e, 0xb6, 0xb7, 0x60, 0xb5, 0x4a, 0x80, 0x7c, 0x6e, 0x50, 0xe3, + 0xc9, 0xb6, 0x8b, 0xec, 0x46, 0x75, 0xff, 0xdd, 0x33, 0x1e, 0x98, 0x48, 0x15, 0xb1, 0x1c, 0x35, + 0xa9, 0x0f, 0x28, 0x71, 0x00, 0xae, 0xb2, 0xf4, 0xfa, 0xea, 0x64, 0x65, 0x32, 0xde, 0xe7, 0xbd, + 0x05, 0x40, 0x0a, 0x7a, 0xaa, 0x02, 0x48, 0x67, 0x3d, 0x41, 0xd8, 0xd4, 0x60, 0x3a, 0xcb, 0x15, + 0x3f, 0x8b, 0x11, 0xe0, 0xeb, 0xcf, 0xbe, 0x09, 0x8e, 0xae, 0x5f, 0x24, 0x52, 0xd8, 0x3e, 0x19, + 0x60, 0xf5, 0xc4, 0x08, 0x51, 0x75, 0x5a, 0x04, 0x66, 0x08, 0x10, 0x07, 0xf0, 0x4d, 0x5a, 0xa8, + 0xf7, 0x17, 0xed, 0xbb, 0xe8, 0x22, 0x99, 0x05, 0x7a, 0x25, 0x7d, 0x72, 0xf8, 0x23, 0xd6, 0xb0, + 0x4b, 0xd5, 0xeb, 0xab, 0xcb, 0xd5, 0xfe, 0xb9, 0x57, 0x5c, 0xe7, 0xd1, 0x31, 0x95, 0xd1, 0xd2, + 0x87, 0x98, 0xc2, 0xc3, 0x1a, 0x08, 0x05, 0xb7, 0x24, 0xf0, 0xa4, 0x99, 0x1e, 0x02, 0x47, 0x0a, + 0x39, 0xea, 0xd4, 0x6e, 0xef, 0x84, 0x54, 0xf4, 0xdd, 0x45, 0x5c, 0x20, 0x85, 0x03, 0x2e, 0x24, + 0x28, 0x4b, 0x2f, 0xb2, 0xdd, 0xb8, 0xad, 0xed, 0xf7, 0x75, 0x6d, 0x53, 0xaf, 0x1a, 0x64, 0x33, + 0xf9, 0x20, 0x00, 0x19, 0x17, 0x04, 0x3f, 0x81, 0x28, 0x3a, 0xe5, 0xd0, 0xb2, 0xa3, 0x46, 0x19, + 0x04, 0x69, 0xb5, 0x25, 0x0d, 0x4a, 0x6d, 0x0f, 0xb2, 0xaa, 0x43, 0xda, 0x44, 0x62, 0x7d, 0xb7, + 0x27, 0x8f, 0x89, 0x19, 0x15, 0x8a, 0x33, 0xc7, 0x05, 0x16, 0x66, 0x12, 0x3c, 0xfc, 0x71, 0xf5, + 0x7b, 0x75, 0xb3, 0x83, 0x82, 0x84, 0x88, 0xd2, 0xef, 0x38, 0x1d, 0x6b, 0x82, 0x58, 0x50, 0xb1, + 0x7f, 0x2f, 0x12, 0x96, 0x77, 0x68, 0xf0, 0x4c, 0x37, 0x25, 0xed, 0x05, 0x83, 0x54, 0xca, 0x0c, + 0x87, 0x0b, 0xd3, 0xa7, 0x0f, 0x0a, 0x12, 0x80, 0x9d, 0xb5, 0x93, 0x28, 0xdd, 0xb6, 0x3c, 0xad, + 0x83, 0x7f, 0x12, 0x0a, 0x44, 0x8e, 0x80, 0x28, 0x6b, 0x39, 0x3a, 0x93, 0x89, 0x5d, 0x14, 0x83, + 0xc0, 0x5b, 0x99, 0x80, 0x00, 0x2a, 0x04, 0x04, 0xec, 0x0b, 0xc7, 0x63, 0x45, 0x7a, 0xfd, 0xe2, + 0x42, 0x04, 0x51, 0x1a, 0x51, 0xa3, 0x95, 0x5b, 0x4e, 0x7c, 0xa3, 0xf4, 0x5f, 0xfc, 0x28, 0x30, + 0x47, 0xa2, 0x72, 0x2b, 0x79, 0x6b, 0x0b, 0x06, 0xe1, 0xef, 0x52, 0xcd, 0xb9, 0x85, 0x6c, 0x49, + 0x06, 0xc3, 0xd4, 0x9c, 0xf3, 0xdf, 0xdf, 0x05, 0x64, 0x63, 0x09, 0x23, 0x00, 0xfc, 0x35, 0x90, + 0xcb, 0xce, 0x26, 0x32, 0x59, 0x8e, 0x2e, 0x4c, 0x7c, 0xed, 0xce, 0x3c, 0x17, 0x85, 0xf4, 0x8e, + 0xc1, 0x68, 0x80, 0x7c, 0x52, 0xe3, 0xf3, 0xc9, 0x0d, 0xf1, 0xf0, 0x43, 0x69, 0xae, 0x75, 0xc2, + 0x7d, 0x0a, 0xef, 0xa2, 0xe5, 0xf5, 0x8a, 0xfa, 0x24, 0x33, 0xea, 0xc1, 0xf4, 0x46, 0x22, 0x7a, + 0xf5, 0x70, 0x49, 0x45, 0x3e, 0x8d, 0x00, 0x30, 0x7d, 0xf1, 0xb2, 0x62, 0x4b, 0x11, 0xc9, 0x49, + 0x21, 0xe0, 0x05, 0x66, 0x0b, 0x10, 0x65, 0xa6, 0x49, 0xdf, 0x4b, 0xdb, 0x83, 0xef, 0xff, 0x04, + 0x56, 0x74, 0xcb, 0x3a, 0x63, 0x8d, 0xe2, 0x42, 0x97, 0x1f, 0x88, 0x3d, 0x07, 0x6a, 0x40, 0x95, + 0x9e, 0xb2, 0xa4, 0x51, 0xf7, 0x39, 0xc7, 0xe3, 0x7a, 0x35, 0x4c, 0xbf, 0xc4, 0x02, 0xa1, 0x05, + 0xf2, 0x23, 0xfc, 0xe7, 0xb3, 0xee, 0x68, 0x40, 0x68, 0xbc, 0xe2, 0x07, 0x16, 0xfb, 0x41, 0x6b, + 0xc0, 0xef, 0x29, 0x56, 0x95, 0x77, 0x40, 0x2c, 0x42, 0x82, 0x48, 0x38, 0x89, 0xc2, 0x82, 0x90, + 0x28, 0xab, 0xc1, 0x18, 0xb1, 0x04, 0x90, 0x89, 0x21, 0x05, 0xc5, 0x93, 0x38, 0x0e, 0xfc, 0x13, + 0x10, 0x8a, 0xb2, 0x65, 0x59, 0xaf, 0x7c, 0x28, 0x71, 0x10, 0x40, 0x1c, 0x2b, 0xc3, 0x38, 0xda, + 0x92, 0xa0, 0x80, 0xdb, 0xe8, 0x6c, 0x32, 0x5d, 0x37, 0xbd, 0xa4, 0x17, 0x7a, 0x48, 0x05, 0xf7, + 0x88, 0x05, 0x45, 0x62, 0xe7, 0x61, 0xc9, 0x1c, 0xc9, 0x38, 0xc7, 0x89, 0xaa, 0x5f, 0x24, 0x50, + 0x2e, 0xee, 0x9c, 0x3c, 0x29, 0x51, 0x2e, 0x2e, 0x1f, 0x5f, 0xca, 0xf6, 0x94, 0x3e, 0x4a, 0x91, + 0x7b, 0x8d, 0xe7, 0x2c, 0x2b, 0x4a, 0x84, 0xcf, 0x78, 0x94, 0x43, 0xa7, 0xc5, 0x08, 0x56, 0xb0, + 0x93, 0xb1, 0x65, 0x57, 0xc1, 0x69, 0x25, 0xde, 0x42, 0x0d, 0xd5, 0xdf, 0x89, 0x12, 0x13, 0x21, + 0xb3, 0x11, 0x6c, 0x2c, 0x46, 0x22, 0x5f, 0xc9, 0x1a, 0x6d, 0x1f, 0xe0, 0x8c, 0x6d, 0x90, 0x82, + 0xbb, 0x37, 0x4d, 0xe1, 0x8e, 0xbd, 0xf5, 0xaf, 0xa3, 0xa7, 0x5e, 0x8a, 0x9d, 0x7a, 0x23, 0x1f, + 0x52, 0x83, 0xe8, 0x8d, 0xf5, 0x6f, 0xab, 0x7d, 0x5c, 0x93, 0x85, 0x27, 0xce, 0xe7, 0x18, 0x2b, + 0xbb, 0x10, 0x67, 0x6c, 0xb4, 0x32, 0x1e, 0x2f, 0x8a, 0x37, 0x34, 0x91, 0x06, 0x82, 0x9d, 0x78, + 0x20, 0x10, 0xc1, 0x85, 0x95, 0x95, 0x57, 0x3e, 0xd9, 0x8f, 0xc5, 0x76, 0x3a, 0x19, 0x94, 0x4b, + 0xdb, 0x6c, 0x9f, 0xfc, 0x51, 0x13, 0xb4, 0xdc, 0x56, 0x3f, 0x81, 0x2f, 0x39, 0x87, 0xa3, 0xf2, + 0xbf, 0x2e, 0xb6, 0x7e, 0x0b, 0x35, 0x09, 0x88, 0x08, 0xf2, 0x41, 0x7c, 0xc3, 0xc6, 0x0c, 0x19, + 0xd4, 0xdc, 0xf3, 0x9d, 0xf0, 0xa0, 0x8a, 0xa8, 0x93, 0x0c, 0xd1, 0x58, 0xc4, 0x87, 0x9c, 0x60, + 0x1f, 0x4a, 0x5d, 0x0f, 0xba, 0x12, 0x27, 0x39, 0x3a, 0x78, 0x90, 0xa0, 0x92, 0x70, 0x4d, 0xaa, + 0x68, 0x6e, 0x2b, 0x43, 0xa4, 0x10, 0x16, 0xa8, 0xb7, 0x18, 0xda, 0x3c, 0x3d, 0xdf, 0x4b, 0x1c, + 0x89, 0x2c, 0x34, 0x55, 0xe0, 0xf6, 0x4a, 0x9d, 0x25, 0x85, 0xb8, 0x3b, 0xfe, 0x08, 0x8f, 0x2d, + 0x34, 0x77, 0xc4, 0x2b, 0xbc, 0x4a, 0x97, 0xf8, 0x90, 0x43, 0x17, 0x17, 0x13, 0x18, 0x25, 0xe5, + 0x0f, 0xc4, 0x02, 0x13, 0xad, 0xef, 0xe2, 0x41, 0x35, 0xb2, 0x90, 0x74, 0x24, 0xe1, 0xe8, 0x64, + 0xd1, 0x8f, 0x89, 0x08, 0x5c, 0x74, 0xdd, 0xbe, 0x4b, 0x76, 0x06, 0xb8, 0xb2, 0xfc, 0x10, 0x98, + 0xcd, 0xa7, 0x8d, 0x53, 0xc4, 0x23, 0x39, 0xc4, 0x41, 0x50, 0x82, 0xc6, 0x58, 0xdc, 0x2c, 0xd1, + 0x82, 0x96, 0x0c, 0x56, 0xc1, 0x89, 0x11, 0x83, 0x19, 0x16, 0x05, 0xfe, 0x2e, 0x23, 0x8b, 0xa4, + 0x9c, 0x92, 0xf8, 0x23, 0x13, 0x2b, 0x02, 0x4e, 0x38, 0x30, 0x14, 0xe1, 0xe8, 0x4e, 0x52, 0x74, + 0x29, 0x91, 0x1d, 0x09, 0x63, 0xeb, 0xaf, 0xa3, 0x54, 0x9d, 0x1f, 0x2f, 0x82, 0x3b, 0xdf, 0x57, + 0xd7, 0x39, 0xf5, 0xce, 0x7d, 0x73, 0x9f, 0x51, 0xf5, 0x72, 0x6a, 0xf2, 0xf4, 0x52, 0xa7, 0xcc, + 0x6b, 0xa9, 0x7f, 0x9c, 0xdf, 0xd4, 0xdb, 0xff, 0x8d, 0xa9, 0x86, 0x09, 0x3c, 0x97, 0xd4, 0x65, + 0x88, 0xba, 0x85, 0xa2, 0x03, 0x90, 0x40, 0x92, 0x02, 0xae, 0x80, 0x44, 0x04, 0xe8, 0xe9, 0x6b, + 0x6f, 0xfe, 0x0a, 0x71, 0x59, 0x6c, 0x7d, 0x7d, 0x69, 0xdd, 0xee, 0x79, 0x3e, 0x08, 0xca, 0x38, + 0x65, 0x1d, 0x9b, 0x3e, 0xf1, 0x23, 0x22, 0xea, 0x2e, 0x2f, 0x69, 0x06, 0x52, 0xb6, 0xcb, 0xba, + 0xbb, 0x08, 0x41, 0x87, 0xe0, 0xb0, 0x51, 0x38, 0x72, 0x8d, 0x42, 0x82, 0xa3, 0xa1, 0xe4, 0x43, + 0xe2, 0x1e, 0xfc, 0x5c, 0xb9, 0x7a, 0x50, 0xe2, 0x42, 0x92, 0x38, 0x03, 0x43, 0x49, 0x12, 0x00, + 0x30, 0x25, 0xc1, 0x36, 0x05, 0x92, 0x96, 0x09, 0xe7, 0x10, 0xc0, 0x63, 0x4b, 0x0a, 0xb7, 0x16, + 0xbd, 0x05, 0xe9, 0x46, 0x01, 0x4c, 0x9f, 0x07, 0x1f, 0xcf, 0x72, 0xce, 0xe5, 0xd8, 0xce, 0x1a, + 0x3f, 0xa6, 0x0e, 0x20, 0x29, 0x7f, 0xde, 0x3d, 0xe0, 0x1c, 0x0f, 0x7a, 0x9e, 0x58, 0xa1, 0x96, + 0x60, 0x3f, 0x56, 0x07, 0xb8, 0x58, 0xdf, 0x96, 0x20, 0x70, 0x35, 0x2d, 0x70, 0x99, 0x53, 0xc6, + 0x9c, 0x3c, 0x16, 0x16, 0xef, 0x2a, 0xd9, 0x9c, 0xe2, 0xd3, 0x23, 0xc7, 0x2f, 0x6d, 0xa3, 0xbe, + 0x24, 0x28, 0x2e, 0x3c, 0x58, 0x7a, 0x86, 0x5f, 0x40, 0x71, 0xd1, 0x70, 0x58, 0x20, 0x2a, 0x46, + 0x2a, 0x8d, 0xfc, 0x40, 0x29, 0x90, 0x61, 0x7f, 0x3e, 0x1e, 0x0c, 0xcf, 0x41, 0xa4, 0x4c, 0x63, + 0xfc, 0x48, 0x2a, 0xa1, 0xbe, 0x56, 0x47, 0x63, 0x1e, 0xc4, 0x03, 0x59, 0xa5, 0xb0, 0x1e, 0x6d, + 0x7d, 0x38, 0xef, 0xc1, 0x36, 0xd4, 0xef, 0x07, 0x1d, 0x8d, 0x7e, 0x09, 0xbd, 0x81, 0x92, 0x91, + 0xb6, 0x93, 0x09, 0x63, 0x99, 0xd7, 0x82, 0x1d, 0x0c, 0xf4, 0x78, 0x69, 0x1d, 0xf1, 0x02, 0x0a, + 0xac, 0x48, 0x95, 0x57, 0x5c, 0x16, 0xc7, 0xc8, 0x47, 0x8e, 0x54, 0xd5, 0x5b, 0xa4, 0xe3, 0xc2, + 0x22, 0x0b, 0x50, 0xaf, 0x84, 0x34, 0x86, 0x2b, 0x71, 0x5b, 0xdb, 0xbb, 0xf8, 0x50, 0x54, 0x9f, + 0xc5, 0x25, 0xf0, 0xba, 0x65, 0xe1, 0x5f, 0xad, 0xd7, 0xbd, 0x90, 0x48, 0x7d, 0x8f, 0xf0, 0xc1, + 0x44, 0xc8, 0x23, 0x1c, 0x59, 0x9d, 0xf0, 0x4c, 0x45, 0xfc, 0x0c, 0x52, 0x79, 0xb7, 0xfd, 0x1f, + 0xa2, 0xfa, 0x37, 0x45, 0x74, 0x57, 0xfa, 0xde, 0x4e, 0xbf, 0xbe, 0x8b, 0xe3, 0xeb, 0x07, 0xd5, + 0xfe, 0x1d, 0x32, 0x48, 0xdc, 0xfc, 0x23, 0x7a, 0x75, 0x37, 0x9d, 0xf9, 0x0b, 0xe4, 0xa1, 0x97, + 0xe1, 0xdf, 0x70, 0xb5, 0xf1, 0x01, 0x27, 0x4d, 0xd9, 0x93, 0xab, 0xdd, 0x71, 0x52, 0x19, 0x2d, + 0xbb, 0xbd, 0xfe, 0x14, 0x96, 0x0f, 0xbc, 0xf9, 0x24, 0xfb, 0xdc, 0x56, 0xdb, 0xab, 0x3e, 0x09, + 0x04, 0xe8, 0xd7, 0xbe, 0x08, 0x44, 0x17, 0x1d, 0xfd, 0xe2, 0x46, 0xc5, 0x63, 0x36, 0x33, 0x91, + 0x24, 0x50, 0x25, 0x54, 0x2d, 0xbc, 0x38, 0xfc, 0x9c, 0xc0, 0xb0, 0x4e, 0x19, 0x05, 0xdd, 0x27, + 0x9f, 0xf9, 0xd2, 0x33, 0xfd, 0xd6, 0x8b, 0x88, 0x0e, 0x96, 0xdc, 0xfe, 0x65, 0xeb, 0xbd, 0x91, + 0x69, 0x22, 0xa4, 0x2d, 0xe6, 0x7c, 0xbc, 0x99, 0x5f, 0xc4, 0x85, 0x09, 0x77, 0xe0, 0xa3, 0x48, + 0xb3, 0x3a, 0x85, 0x8f, 0x50, 0xfc, 0xfa, 0x3c, 0x8b, 0xd7, 0x10, 0x08, 0x6f, 0x26, 0x66, 0xfd, + 0xf2, 0x8b, 0x9c, 0x0b, 0x7e, 0x25, 0x10, 0xf7, 0xc1, 0x4c, 0x68, 0x20, 0x2e, 0x31, 0x5e, 0xef, + 0x20, 0x00, 0x06, 0xce, 0x0a, 0x6b, 0x1f, 0xf8, 0x21, 0x2e, 0xee, 0x74, 0x3b, 0xf0, 0xd5, 0x93, + 0x26, 0xb8, 0x1a, 0xa3, 0xfd, 0x7f, 0x88, 0x45, 0xaf, 0x92, 0x36, 0xc9, 0xa4, 0x17, 0x65, 0x5e, + 0x8c, 0xe7, 0xc1, 0x1e, 0xb6, 0x32, 0xe1, 0xc4, 0x85, 0x27, 0x81, 0x3b, 0x53, 0x4e, 0xcd, 0x8e, + 0x3d, 0x47, 0xaa, 0x34, 0x31, 0x2e, 0xa4, 0xb1, 0xe5, 0x8a, 0x78, 0x91, 0x20, 0xa6, 0x7b, 0x5e, + 0x1a, 0x07, 0xd1, 0xaf, 0x12, 0xf1, 0x85, 0x56, 0x86, 0xc0, 0xde, 0xc6, 0x37, 0xfe, 0x0a, 0x85, + 0x6a, 0x2b, 0x48, 0x4f, 0x09, 0x43, 0xa4, 0x12, 0x7f, 0x9b, 0x42, 0x68, 0x6b, 0xff, 0xc4, 0xce, + 0x03, 0x21, 0x8c, 0xc3, 0x76, 0x48, 0x6b, 0x12, 0x60, 0x60, 0x2f, 0xaf, 0x42, 0x3d, 0x1e, 0x39, + 0x27, 0x45, 0xea, 0xeb, 0xdf, 0x58, 0xbe, 0x4b, 0xdf, 0xe0, 0x87, 0x57, 0xf7, 0xd6, 0xbc, 0x48, + 0xd3, 0x6e, 0x6e, 0xe2, 0x53, 0x17, 0x53, 0x1c, 0x19, 0x0b, 0xdd, 0xce, 0xb0, 0x5a, 0x9c, 0xed, + 0x30, 0x60, 0x17, 0x48, 0x34, 0x19, 0xc5, 0x1d, 0x5b, 0x47, 0x53, 0xfc, 0x3d, 0x0f, 0x06, 0xa5, + 0xa4, 0x99, 0x55, 0x7f, 0xb7, 0x9e, 0xd2, 0xd9, 0xa1, 0xf1, 0x6a, 0xfb, 0xd3, 0x4f, 0xc1, 0x64, + 0x73, 0xef, 0x53, 0x43, 0xaa, 0x2a, 0xb3, 0x51, 0x43, 0xe3, 0x81, 0x0c, 0x6f, 0x84, 0x36, 0x6c, + 0x06, 0x70, 0xc0, 0x75, 0x5c, 0xbd, 0x7f, 0x1c, 0x48, 0xae, 0x21, 0x61, 0xdf, 0x77, 0x39, 0x50, + 0x5e, 0x5b, 0xf0, 0x48, 0x74, 0x44, 0xd5, 0x68, 0x80, 0xf7, 0xc5, 0x12, 0xf1, 0x46, 0xe2, 0x46, + 0x0d, 0x35, 0x27, 0x12, 0x36, 0x59, 0xa4, 0x0e, 0x02, 0x0f, 0x60, 0x80, 0xd2, 0xb6, 0x05, 0x0e, + 0xf0, 0xaa, 0xb7, 0x8d, 0xaa, 0x94, 0x2f, 0xfd, 0x6a, 0xfe, 0x0b, 0x2a, 0xb4, 0x03, 0x41, 0xbd, + 0x97, 0x25, 0x80, 0xee, 0x56, 0x8e, 0xf8, 0x80, 0x4a, 0x57, 0x15, 0x8c, 0xd2, 0xdf, 0x41, 0x5d, + 0xfb, 0xc4, 0x82, 0xb2, 0x8c, 0x0d, 0x09, 0x63, 0x73, 0x51, 0x48, 0x08, 0x03, 0x2e, 0xff, 0xde, + 0x20, 0x11, 0x59, 0x18, 0x00, 0x0b, 0xe6, 0x53, 0xc4, 0x05, 0x22, 0xb1, 0x28, 0x80, 0xa0, 0x0b, + 0x43, 0x01, 0x4d, 0x8f, 0x30, 0xd9, 0x58, 0x5f, 0xc5, 0xa7, 0x76, 0xe7, 0x10, 0x17, 0x78, 0x80, + 0x49, 0x57, 0x51, 0xd4, 0x1e, 0xae, 0xa5, 0x50, 0xf2, 0x95, 0xdf, 0x7c, 0x16, 0x9a, 0x60, 0x32, + 0xf4, 0x22, 0x98, 0xc6, 0xfe, 0x21, 0x7e, 0x7d, 0xc5, 0x9a, 0x34, 0x66, 0x10, 0xfa, 0xb3, 0xe1, + 0x21, 0x0a, 0xaa, 0xa5, 0xa0, 0xeb, 0x24, 0xa9, 0xf8, 0x23, 0x90, 0x30, 0x1a, 0xa9, 0xc3, 0xf9, + 0xca, 0xb6, 0x8d, 0xb1, 0xff, 0xab, 0xc9, 0xd1, 0x7e, 0x3d, 0x72, 0xae, 0x08, 0xaa, 0x8f, 0xfb, + 0xea, 0x80, 0x69, 0x38, 0xfd, 0xd5, 0x5d, 0xd5, 0x5d, 0xf5, 0xd1, 0x3a, 0xba, 0xc5, 0x2f, 0x5c, + 0xdf, 0x56, 0xbe, 0xb9, 0xeb, 0x82, 0x4c, 0x57, 0x79, 0x7c, 0x13, 0x46, 0x08, 0x9c, 0xdb, 0x6e, + 0xa3, 0x8d, 0xf0, 0x4a, 0x5a, 0x33, 0x9b, 0x86, 0x73, 0x74, 0x27, 0x9b, 0x87, 0x99, 0x5d, 0x08, + 0x7f, 0x84, 0xb3, 0xe5, 0xbb, 0xdf, 0x89, 0x05, 0x25, 0x49, 0x68, 0xb1, 0x75, 0x1f, 0x4c, 0x7a, + 0x0f, 0x2f, 0x10, 0xb9, 0x78, 0x80, 0xcc, 0xec, 0x16, 0x31, 0x5d, 0xdf, 0x44, 0x7e, 0xff, 0xa9, + 0xef, 0x12, 0x8e, 0x8e, 0xfc, 0x15, 0xde, 0x60, 0x80, 0x3a, 0xa3, 0xe7, 0x9d, 0x18, 0x87, 0x12, + 0x08, 0xb1, 0x9a, 0x2b, 0x7f, 0x87, 0x82, 0x1d, 0xb9, 0x6c, 0x43, 0x95, 0x5c, 0x11, 0xf6, 0x37, + 0x4a, 0x7c, 0x13, 0xc4, 0x48, 0x22, 0x3c, 0x5c, 0xbc, 0x80, 0x80, 0x27, 0xcc, 0x48, 0xc1, 0x7b, + 0xfc, 0x13, 0x9c, 0x5c, 0x5c, 0x5c, 0x5f, 0x2b, 0x08, 0x27, 0xfa, 0x96, 0x55, 0xc4, 0x82, 0x21, + 0x99, 0xb4, 0xec, 0xff, 0xc4, 0x85, 0x0a, 0x4d, 0x8e, 0xab, 0x9f, 0xb3, 0x5b, 0x24, 0x68, 0xd1, + 0xaa, 0xad, 0x23, 0x74, 0xab, 0xc1, 0x4d, 0xd0, 0x3c, 0xdb, 0x0c, 0x2f, 0x88, 0xe8, 0xa9, 0x6e, + 0xe5, 0xb8, 0x8a, 0x3f, 0x2f, 0x11, 0x0a, 0x4a, 0x08, 0x08, 0xf8, 0xa9, 0x1f, 0x08, 0x09, 0x0c, + 0xfb, 0xe0, 0x3b, 0x51, 0x98, 0x9a, 0x4b, 0x68, 0xeb, 0x93, 0x01, 0x00, 0x64, 0xe8, 0x60, 0x2b, + 0x8a, 0xc7, 0x41, 0x82, 0x03, 0xff, 0x12, 0x09, 0x48, 0x74, 0xfd, 0x8d, 0xcf, 0x9b, 0xfc, 0x34, + 0x61, 0x1c, 0x0f, 0x68, 0x36, 0x2a, 0x21, 0x1d, 0x58, 0x35, 0xa4, 0xff, 0xe0, 0x9b, 0x56, 0x66, + 0x61, 0x06, 0x44, 0x8c, 0x83, 0x9f, 0x57, 0x0f, 0xa2, 0x99, 0x2b, 0xac, 0x55, 0xd5, 0xfe, 0xac, + 0x3d, 0x11, 0xfe, 0xaf, 0x2f, 0x57, 0xfa, 0xfc, 0xbe, 0xac, 0x49, 0xd1, 0xfa, 0x4e, 0x0b, 0x45, + 0x51, 0xc9, 0x2b, 0x19, 0x23, 0xc1, 0xf4, 0x57, 0x7d, 0x1d, 0x95, 0xc2, 0x82, 0x91, 0x14, 0xdb, + 0x3d, 0xda, 0xa3, 0x51, 0x7a, 0xaa, 0x4b, 0x1d, 0xff, 0x0a, 0x4a, 0xc2, 0x9b, 0x96, 0xf8, 0x3f, + 0xde, 0xa5, 0x5b, 0x8c, 0x7f, 0x3e, 0x84, 0x64, 0x53, 0xfe, 0xf8, 0x22, 0x2d, 0x6a, 0xff, 0x05, + 0x50, 0xc1, 0xe7, 0x52, 0x2b, 0x61, 0xad, 0x5a, 0x5a, 0x8e, 0xdf, 0x05, 0x7c, 0x94, 0x64, 0x77, + 0x2e, 0x0c, 0x5f, 0x27, 0xf8, 0xf9, 0x2b, 0x68, 0x84, 0x1e, 0x21, 0x1c, 0x81, 0x1f, 0x5c, 0xe3, + 0xd4, 0xb7, 0x89, 0x44, 0x1d, 0xbe, 0x30, 0xa2, 0x12, 0x21, 0x86, 0xbc, 0x20, 0x20, 0x0b, 0xcd, + 0x6d, 0xbe, 0x92, 0x48, 0xf3, 0xd3, 0xe0, 0x86, 0x2e, 0x2e, 0xa2, 0xff, 0xfa, 0xf7, 0xc1, 0x29, + 0xee, 0x70, 0x80, 0x3d, 0xaa, 0x36, 0x04, 0x95, 0x79, 0x88, 0xfb, 0xf8, 0x22, 0x18, 0x96, 0x97, + 0x78, 0x80, 0x58, 0x71, 0x5d, 0x4e, 0x2b, 0x2f, 0x7a, 0x37, 0x7b, 0xbf, 0x12, 0x25, 0x4f, 0x28, + 0x78, 0x50, 0x4b, 0x34, 0x9d, 0x12, 0x0d, 0x94, 0xca, 0x53, 0x98, 0x87, 0x1a, 0x0f, 0xc5, 0xc5, + 0x20, 0x02, 0x07, 0x1b, 0x89, 0x8b, 0xb4, 0xba, 0x09, 0xe1, 0x3d, 0x84, 0x82, 0x39, 0xb6, 0x9a, + 0xe2, 0x42, 0x96, 0x98, 0x32, 0xa8, 0xa6, 0x71, 0x96, 0x6a, 0xf4, 0xd7, 0x91, 0x2f, 0x40, 0x19, + 0x17, 0x98, 0x60, 0xa5, 0x58, 0x88, 0x50, 0x83, 0x43, 0xd3, 0x3f, 0x49, 0xc6, 0x47, 0xc2, 0x06, + 0x5f, 0xda, 0x3c, 0xc3, 0x05, 0xc8, 0xee, 0x04, 0x06, 0x54, 0x70, 0xf0, 0xa0, 0xad, 0x6a, 0x11, + 0xab, 0x19, 0xaa, 0xd5, 0x34, 0x47, 0x4d, 0x74, 0x8d, 0x93, 0x18, 0x8d, 0x53, 0xe0, 0x9b, 0x8e, + 0x63, 0x94, 0xeb, 0x53, 0xdf, 0x42, 0x59, 0xf5, 0xca, 0x4e, 0x8c, 0xff, 0x45, 0xb7, 0xd5, 0xaf, + 0xaf, 0x7d, 0x5a, 0xba, 0xe2, 0xbe, 0x52, 0x24, 0x95, 0xa5, 0xd1, 0xda, 0xb8, 0x23, 0xaa, 0x3d, + 0xef, 0xa3, 0x45, 0x7c, 0x37, 0x15, 0xbb, 0xbe, 0x7c, 0x7d, 0x32, 0xb0, 0xbf, 0xc1, 0x11, 0x49, + 0xc7, 0xd3, 0x08, 0xd6, 0x84, 0x03, 0x2f, 0xab, 0xfc, 0x12, 0x46, 0x15, 0xbf, 0x76, 0x78, 0x90, + 0x55, 0x8e, 0x32, 0x5d, 0xf6, 0x1e, 0x12, 0x42, 0x73, 0x42, 0x84, 0x01, 0x40, 0x20, 0x01, 0xad, + 0xf8, 0x7c, 0x71, 0xbd, 0xef, 0xbb, 0xef, 0x7f, 0x04, 0x25, 0xb7, 0x1c, 0xa4, 0x5e, 0x24, 0x16, + 0x53, 0x6e, 0x84, 0x4a, 0x0d, 0x40, 0x16, 0x7a, 0xa9, 0xd7, 0xf0, 0x5c, 0x55, 0x0f, 0xd3, 0xc1, + 0xf1, 0x93, 0x49, 0x11, 0x7e, 0xdf, 0x05, 0xb5, 0x7c, 0x23, 0xc6, 0xd7, 0x10, 0xd1, 0x87, 0x1c, + 0x48, 0x21, 0x2b, 0xde, 0x5b, 0xe3, 0x0c, 0xc8, 0x38, 0xc7, 0x8a, 0xd7, 0x96, 0x83, 0x39, 0x06, + 0x9a, 0xf6, 0x82, 0xaf, 0x9c, 0x20, 0x09, 0xd0, 0x25, 0x05, 0x57, 0x88, 0x04, 0x87, 0xba, 0xff, + 0xf4, 0x4e, 0xf1, 0x20, 0xb8, 0xb7, 0xb4, 0xc0, 0x98, 0x04, 0xbf, 0x3c, 0xff, 0x04, 0xd7, 0xbc, + 0x51, 0x8a, 0x37, 0x77, 0xf8, 0x24, 0xdd, 0xd8, 0x2e, 0xfa, 0xa5, 0x5e, 0x0b, 0x08, 0x80, 0xc6, + 0x46, 0x81, 0x71, 0xb4, 0xcc, 0xa2, 0x74, 0x96, 0xe1, 0x94, 0x8a, 0xd2, 0xf8, 0x93, 0x93, 0xff, + 0x4e, 0xdb, 0xf1, 0x02, 0x0e, 0x75, 0x16, 0xe5, 0xa1, 0x71, 0xb9, 0x46, 0x87, 0xb7, 0xeb, 0xdc, + 0x44, 0x14, 0xcb, 0x89, 0x16, 0xcb, 0x52, 0xb1, 0x04, 0xa1, 0x71, 0xf0, 0x04, 0xd3, 0xb9, 0xee, + 0x24, 0x48, 0x27, 0xca, 0x06, 0xb9, 0xae, 0x2d, 0xfc, 0x47, 0xd7, 0xbe, 0xbd, 0xf0, 0x4e, 0x2a, + 0x7c, 0xad, 0x6f, 0xd5, 0xd0, 0xb8, 0x67, 0xd7, 0x2f, 0xae, 0xa4, 0xe8, 0x95, 0xf5, 0xeb, 0xe8, + 0xa8, 0xf2, 0xba, 0xa3, 0xbf, 0x5d, 0x45, 0xf0, 0x48, 0x29, 0x73, 0xa8, 0x2d, 0xf0, 0x4c, 0x52, + 0xa4, 0x70, 0x72, 0xf7, 0x7c, 0xab, 0xa2, 0xb0, 0xf5, 0x6f, 0x12, 0x0b, 0x28, 0x0d, 0x6f, 0xa3, + 0xbe, 0xbc, 0xa4, 0xef, 0xcd, 0x01, 0x48, 0x75, 0xe5, 0x14, 0xef, 0x7f, 0x62, 0xdb, 0x60, 0x64, + 0x66, 0x3f, 0x04, 0xdc, 0xf2, 0x62, 0x27, 0x80, 0x42, 0xb5, 0xc8, 0xe0, 0xfc, 0x55, 0xdd, 0xd0, + 0xdc, 0xa1, 0x00, 0x45, 0x65, 0xbc, 0x48, 0x90, 0xa5, 0xdd, 0x13, 0xa4, 0xb6, 0x04, 0xc6, 0xda, + 0xbf, 0x68, 0xb5, 0x1e, 0xc3, 0xa1, 0x25, 0xe7, 0x8b, 0x7c, 0x42, 0xcf, 0xe2, 0x41, 0x55, 0xdc, + 0x10, 0x04, 0x70, 0x20, 0x16, 0x39, 0xf4, 0xb2, 0x0d, 0x17, 0x60, 0x2d, 0x1d, 0xfb, 0xb9, 0xcc, + 0x5c, 0xb7, 0xeb, 0x7f, 0xa2, 0xa7, 0x5e, 0x08, 0x6e, 0x2b, 0x15, 0xb9, 0x6f, 0x82, 0x3e, 0xee, + 0x74, 0x7f, 0xab, 0xf8, 0x94, 0x23, 0xbc, 0x40, 0x2a, 0x2b, 0x9c, 0x40, 0x44, 0xa2, 0x02, 0x5b, + 0x64, 0xc9, 0x00, 0x4f, 0x13, 0xf9, 0x9b, 0xed, 0xf0, 0x45, 0x48, 0xf0, 0xdc, 0xf8, 0x2e, 0xb8, + 0xad, 0xde, 0x48, 0xb2, 0x87, 0x0d, 0xf2, 0x55, 0x49, 0x46, 0x53, 0x89, 0x0a, 0x09, 0x60, 0xc3, + 0x69, 0x5e, 0x3d, 0x33, 0x47, 0x69, 0x6d, 0xa3, 0x09, 0x11, 0x4c, 0x51, 0xa9, 0x91, 0xf6, 0xad, + 0x5e, 0x09, 0x80, 0x1e, 0x5f, 0xb3, 0x2a, 0xfe, 0x8b, 0x17, 0xc1, 0x39, 0x16, 0xb4, 0x92, 0x2e, + 0x37, 0x2f, 0xf1, 0x75, 0x17, 0x91, 0x74, 0x47, 0x0b, 0xd9, 0x78, 0x22, 0x14, 0xd9, 0x5a, 0xca, + 0x86, 0x9f, 0xe1, 0xb2, 0xa0, 0x0c, 0xb9, 0x8f, 0x96, 0xa4, 0x32, 0xc3, 0x3f, 0xea, 0xd2, 0xf5, + 0xc2, 0xfa, 0x29, 0x95, 0x5c, 0x11, 0x56, 0xee, 0xff, 0x3d, 0x5a, 0x69, 0x24, 0xbf, 0xd5, 0xfe, + 0xa4, 0x15, 0xf5, 0x3a, 0x57, 0x57, 0xfa, 0xb3, 0xe0, 0x92, 0x8d, 0x1b, 0x37, 0x7a, 0xe8, 0xdb, + 0x78, 0x90, 0xa1, 0x19, 0xb6, 0xd8, 0xf0, 0x20, 0x47, 0x36, 0x5b, 0x58, 0x08, 0x5c, 0x53, 0x28, + 0x92, 0x40, 0x54, 0x99, 0x30, 0x41, 0xbb, 0x61, 0x30, 0x7f, 0x62, 0x5d, 0x4a, 0x63, 0x3e, 0xbe, + 0x78, 0x90, 0xa1, 0x49, 0x83, 0xd1, 0x86, 0x60, 0xc5, 0xb3, 0x5b, 0xc0, 0x8c, 0x94, 0xc2, 0x38, + 0x76, 0x71, 0x01, 0x60, 0x20, 0x0c, 0x38, 0x09, 0x1c, 0x26, 0x0f, 0x10, 0x46, 0xa1, 0xf8, 0x80, + 0x47, 0x46, 0xdb, 0x88, 0x2d, 0xc3, 0x8f, 0xe2, 0x51, 0x07, 0x6f, 0x82, 0xa2, 0x34, 0xd6, 0x32, + 0xc5, 0xfd, 0xec, 0x3e, 0x84, 0x52, 0x5b, 0x4d, 0xff, 0x5d, 0x1d, 0xfc, 0x48, 0x22, 0x3c, 0x76, + 0x07, 0x80, 0xcb, 0x1d, 0xe2, 0x61, 0x4e, 0x42, 0x4e, 0xa4, 0x00, 0x4a, 0x0c, 0xaa, 0x2b, 0x50, + 0x08, 0x68, 0x38, 0xa2, 0x03, 0x5b, 0xdb, 0xde, 0xa2, 0x1b, 0x10, 0x8c, 0x77, 0x88, 0x04, 0x46, + 0x10, 0xe0, 0xac, 0xe4, 0x1b, 0x7f, 0x12, 0xa9, 0xd7, 0x82, 0x79, 0xe4, 0xc1, 0xd0, 0x13, 0x8c, + 0xf1, 0x2f, 0x7f, 0x82, 0xa2, 0xa0, 0x13, 0x19, 0xe8, 0xfe, 0x3c, 0x0d, 0x04, 0xbd, 0x81, 0x80, + 0xb8, 0x40, 0x6e, 0xed, 0x71, 0xff, 0x05, 0x59, 0x7b, 0x4f, 0xa1, 0xc8, 0x2f, 0xca, 0xc7, 0x3a, + 0xfe, 0x89, 0xd7, 0x13, 0x15, 0x17, 0x13, 0x61, 0x59, 0x00, 0xb7, 0x95, 0x8c, 0x2b, 0xa2, 0xe2, + 0x41, 0x1f, 0x1b, 0x36, 0x05, 0xd0, 0x00, 0x8d, 0xa1, 0x51, 0xd2, 0xe0, 0xa8, 0xa7, 0x0c, 0x13, + 0xa8, 0x9c, 0x8e, 0x9b, 0xd0, 0x36, 0x34, 0x0c, 0x56, 0x9d, 0x78, 0x26, 0xa7, 0x60, 0xc8, 0x81, + 0x07, 0x13, 0xb2, 0xce, 0x7c, 0x16, 0x71, 0x90, 0x00, 0x9b, 0x19, 0x82, 0x73, 0x00, 0x00, 0xdb, + 0x50, 0x07, 0x7f, 0x12, 0x0a, 0xe7, 0xcb, 0x0d, 0x90, 0x69, 0x17, 0xd5, 0x59, 0x08, 0x9a, 0x6e, + 0x34, 0x63, 0x7b, 0xa6, 0x1c, 0x5e, 0x67, 0x40, 0xa8, 0x5f, 0x3e, 0x0a, 0xb0, 0x95, 0xa0, 0x33, + 0xd1, 0x6a, 0xca, 0x81, 0x15, 0x85, 0x80, 0x47, 0xc7, 0xd4, 0xa5, 0xf0, 0x4b, 0x77, 0x77, 0x57, + 0xca, 0x9f, 0x21, 0x94, 0x94, 0x59, 0xf0, 0x99, 0x1a, 0x89, 0x27, 0x21, 0xa0, 0x65, 0x0b, 0xb3, + 0xd7, 0x47, 0xe9, 0x7a, 0xe5, 0xf4, 0x48, 0xab, 0xab, 0xfd, 0x17, 0x17, 0xcd, 0x5d, 0xdf, 0x7b, + 0xbf, 0xd6, 0x52, 0x75, 0x75, 0x75, 0xef, 0x82, 0xc1, 0x8e, 0x21, 0xe2, 0xb4, 0x6f, 0x5d, 0xc5, + 0x18, 0x85, 0x89, 0xa9, 0x41, 0x2a, 0xdf, 0x0a, 0x14, 0xc8, 0x5b, 0x3d, 0xfe, 0x3a, 0xa9, 0x78, + 0xbe, 0xd0, 0x5b, 0x62, 0x92, 0x71, 0x24, 0x30, 0x82, 0xce, 0x5e, 0x5f, 0x96, 0xd9, 0x95, 0x40, + 0xb6, 0xf8, 0x2b, 0x13, 0x40, 0x4d, 0x9d, 0x13, 0x31, 0x43, 0x44, 0xd0, 0xa0, 0x47, 0x20, 0xa1, + 0xd6, 0x3b, 0x7c, 0x12, 0x52, 0x74, 0xbb, 0xf1, 0x30, 0xa1, 0x46, 0x49, 0x75, 0x31, 0xab, 0x28, + 0xc1, 0x02, 0xd3, 0x1b, 0xba, 0x90, 0x40, 0x03, 0xe2, 0xdd, 0x30, 0xf2, 0x10, 0xe0, 0xed, 0x5d, + 0x19, 0xfe, 0x62, 0xd0, 0xea, 0xb8, 0x52, 0x22, 0x10, 0x05, 0x8c, 0x90, 0x91, 0xca, 0x3d, 0x43, + 0xe9, 0x58, 0xab, 0x35, 0x0f, 0xd9, 0x15, 0x83, 0x4f, 0x5f, 0x2f, 0x10, 0x08, 0x64, 0xf9, 0x7b, + 0xfc, 0x29, 0x90, 0x60, 0xbc, 0x26, 0xa8, 0x05, 0xd5, 0x06, 0x10, 0xb0, 0x79, 0x04, 0xac, 0x75, + 0x92, 0x29, 0x84, 0x50, 0x02, 0x5b, 0x98, 0x84, 0x7c, 0xdd, 0x5f, 0x89, 0x19, 0x43, 0x4d, 0x64, + 0x10, 0x12, 0x08, 0x0a, 0xc8, 0x64, 0xa4, 0x5b, 0x59, 0xe7, 0xbf, 0xc1, 0x1d, 0xb2, 0x63, 0x72, + 0xde, 0x24, 0x12, 0xf3, 0xf4, 0x3b, 0x63, 0xf0, 0x9f, 0xbe, 0x08, 0xc8, 0xaa, 0xab, 0xf7, 0xc1, + 0x6c, 0x5d, 0x6b, 0x26, 0x2c, 0xf7, 0xc1, 0x74, 0x5c, 0x5d, 0x55, 0xdc, 0x4a, 0x08, 0x03, 0x77, + 0xf8, 0x2b, 0xbb, 0x58, 0xff, 0xaf, 0xcb, 0xe5, 0xc3, 0xa7, 0xd1, 0x5b, 0xe0, 0x87, 0x7a, 0x1e, + 0x0f, 0x82, 0xd2, 0xb9, 0xe8, 0xf8, 0x8e, 0x0e, 0x32, 0x7f, 0xef, 0x12, 0x09, 0xc8, 0x3e, 0x98, + 0x5e, 0xc5, 0xca, 0x34, 0x24, 0x72, 0xd3, 0x3f, 0xc1, 0x09, 0x75, 0x5e, 0x5c, 0x45, 0x10, 0x77, + 0x2b, 0x82, 0x2d, 0xec, 0x68, 0xd7, 0xe6, 0x2a, 0xaf, 0xe0, 0x8a, 0xba, 0xe5, 0xf0, 0x51, 0xdd, + 0x99, 0xf8, 0xf0, 0x00, 0x09, 0xef, 0x77, 0xb5, 0x72, 0x8c, 0x08, 0x9f, 0x76, 0x56, 0x4f, 0xac, + 0xd1, 0x7d, 0x7a, 0x3c, 0xbe, 0xa5, 0x4f, 0xab, 0xbe, 0xa7, 0x4f, 0xaf, 0x7d, 0x7b, 0xeb, 0x55, + 0xd7, 0xaf, 0x9f, 0xaf, 0xa4, 0x93, 0x4d, 0x7a, 0xc5, 0x3f, 0x5e, 0xf8, 0x24, 0x14, 0xee, 0xee, + 0xff, 0x77, 0x73, 0xfa, 0x3f, 0x05, 0xc5, 0x55, 0x32, 0x89, 0x6c, 0x8a, 0x69, 0xd5, 0x70, 0x8e, + 0xec, 0x37, 0x18, 0xf7, 0x02, 0x13, 0xe6, 0xcb, 0x65, 0x96, 0xf1, 0x30, 0x56, 0x2c, 0x71, 0x8d, + 0x98, 0xe9, 0xcb, 0x3b, 0xd4, 0xd0, 0xef, 0x7e, 0x16, 0xc3, 0xc3, 0xa2, 0x87, 0x63, 0xbf, 0xc4, + 0x82, 0xea, 0x4c, 0x02, 0x43, 0xb8, 0xed, 0xbb, 0x0f, 0x39, 0x41, 0xe2, 0x41, 0x69, 0x84, 0x58, + 0x1e, 0x7a, 0x2b, 0x86, 0x0b, 0x6c, 0x19, 0xe5, 0x7f, 0xfa, 0xb9, 0xf0, 0x43, 0x15, 0xbb, 0xbb, + 0xfc, 0x79, 0x08, 0x63, 0x1e, 0xd5, 0x68, 0xd6, 0x9f, 0xaf, 0xfe, 0x0a, 0xca, 0xc2, 0x45, 0x5a, + 0xb5, 0xc5, 0xd4, 0x76, 0xf8, 0x22, 0xb1, 0x89, 0x6a, 0x3d, 0x53, 0x59, 0x97, 0xc1, 0x11, 0x45, + 0xc4, 0xe8, 0xb2, 0x38, 0xdf, 0x05, 0x5d, 0x5e, 0x2e, 0x40, 0x40, 0x11, 0x79, 0x17, 0x55, 0x17, + 0x2f, 0xfb, 0xd5, 0x8f, 0xc4, 0x82, 0x98, 0x3b, 0x6b, 0x19, 0x8b, 0xb0, 0x31, 0x8f, 0x1b, 0x0b, + 0xcf, 0x8f, 0x0c, 0x04, 0xe6, 0x30, 0x52, 0xf1, 0x21, 0x43, 0x6e, 0xd6, 0x5d, 0xea, 0xdc, 0x5c, + 0x5e, 0xa3, 0x1b, 0xe0, 0x96, 0xf7, 0xbd, 0x3a, 0x35, 0xfb, 0x3a, 0x44, 0xc7, 0x82, 0xf0, 0xa4, + 0x18, 0xfe, 0xa4, 0xe2, 0x0d, 0x06, 0x96, 0x3a, 0x80, 0x67, 0xd0, 0x5b, 0x0c, 0xf0, 0x86, 0xf1, + 0x83, 0x40, 0x34, 0x5e, 0x78, 0x27, 0x2c, 0x32, 0x83, 0x60, 0xf7, 0xce, 0x1e, 0x4e, 0xbd, 0x78, + 0xef, 0xc1, 0x4c, 0xdc, 0x60, 0xe0, 0x16, 0xe4, 0x5e, 0xf6, 0xac, 0xae, 0x3a, 0xaa, 0x27, 0x2a, + 0x5a, 0x9c, 0xfa, 0xb7, 0xc1, 0x34, 0x72, 0x5b, 0x68, 0x4a, 0xc8, 0x5b, 0x80, 0x38, 0x52, 0x00, + 0x44, 0x2e, 0xe2, 0x20, 0xaf, 0xb6, 0x5e, 0x29, 0xb8, 0x82, 0x29, 0xb0, 0x82, 0x50, 0xc0, 0x46, + 0xa8, 0x99, 0x17, 0x73, 0xa2, 0x88, 0xed, 0x70, 0x49, 0x42, 0xcd, 0xa6, 0x6b, 0xe8, 0x8e, 0x7c, + 0x60, 0xc7, 0xac, 0xed, 0x95, 0xeb, 0x89, 0x61, 0xb2, 0x55, 0x1f, 0xf1, 0x0c, 0x70, 0xa8, 0xdc, + 0xf1, 0x62, 0x5f, 0x58, 0xd1, 0x8a, 0x52, 0x5e, 0xba, 0xe5, 0x7d, 0x6b, 0xeb, 0x15, 0xf5, 0xe8, + 0xae, 0x6a, 0x89, 0x84, 0x02, 0xe5, 0x3a, 0xf8, 0xd1, 0x03, 0x20, 0x00, 0x48, 0x9a, 0x8b, 0x1b, + 0x8d, 0x94, 0x44, 0x59, 0xb2, 0x39, 0xe5, 0x6e, 0xca, 0xba, 0xf9, 0xb1, 0x75, 0x84, 0x2f, 0xf0, + 0xb4, 0xff, 0xf0, 0x51, 0x55, 0xaa, 0xaa, 0xab, 0xfc, 0x11, 0x15, 0x53, 0x6f, 0xdf, 0x47, 0xb5, + 0x70, 0x46, 0x21, 0xb2, 0x0e, 0x5b, 0xff, 0x88, 0x43, 0x53, 0xaf, 0x44, 0xf7, 0xd5, 0xbc, 0x48, + 0x21, 0xba, 0x5f, 0xfe, 0xb8, 0xb8, 0x98, 0xc8, 0xf0, 0xf8, 0x97, 0xc4, 0x90, 0xc7, 0x8e, 0xc2, + 0x8e, 0xde, 0x7f, 0x3a, 0x85, 0x3e, 0x68, 0xb7, 0xe1, 0x4c, 0x8b, 0x91, 0x21, 0xdc, 0x22, 0x8b, + 0x73, 0x1d, 0xdb, 0x8a, 0x3e, 0xef, 0xf3, 0xc4, 0x82, 0xb2, 0x65, 0xc8, 0x91, 0x62, 0x5b, 0x97, + 0xd3, 0x8e, 0xc7, 0x78, 0x98, 0x50, 0xa9, 0x3d, 0xc7, 0xf4, 0x68, 0x00, 0x05, 0x6a, 0x23, 0x46, + 0x0a, 0xcc, 0xc0, 0xf7, 0x95, 0x0c, 0x28, 0x03, 0x95, 0xe7, 0xe2, 0x61, 0x29, 0xa9, 0xdd, 0x6f, + 0xc4, 0xc1, 0x61, 0x13, 0xb8, 0xad, 0x8c, 0xfe, 0x50, 0x40, 0x3b, 0xda, 0xee, 0x22, 0x08, 0xe2, + 0xe2, 0xea, 0x23, 0xe2, 0xf8, 0x50, 0x48, 0x56, 0x30, 0xa6, 0x02, 0x9c, 0x93, 0x7b, 0xd0, 0x6c, + 0xdd, 0x07, 0x3e, 0x40, 0x52, 0x80, 0xb8, 0xef, 0xc2, 0x93, 0x82, 0x48, 0x08, 0x05, 0xac, 0x12, + 0x0e, 0x03, 0x88, 0x28, 0x95, 0xd9, 0x11, 0x0b, 0x44, 0x44, 0x0d, 0x06, 0x9e, 0x12, 0x82, 0x16, + 0xee, 0xcd, 0x58, 0xdb, 0xb5, 0x13, 0xc2, 0x01, 0x7b, 0xbe, 0xf1, 0x20, 0x97, 0x60, 0x6c, 0x65, + 0x22, 0x77, 0x61, 0x78, 0xe4, 0x2f, 0xe5, 0x4e, 0xbf, 0x82, 0x4b, 0xee, 0x54, 0xfa, 0xf7, 0xcd, + 0x7b, 0xfc, 0x55, 0x44, 0xf8, 0xbb, 0xb9, 0x08, 0x34, 0x75, 0xe2, 0x46, 0x6e, 0xe3, 0xa0, 0xf2, + 0x2f, 0x77, 0x17, 0x17, 0x25, 0xdc, 0x31, 0x99, 0x78, 0xab, 0x60, 0xe5, 0x5a, 0xc4, 0x96, 0x23, + 0x03, 0x18, 0xab, 0x33, 0xd4, 0xe0, 0xf8, 0x23, 0x21, 0x18, 0x17, 0x36, 0x4b, 0x7d, 0x13, 0xbe, + 0x0b, 0x4e, 0xaa, 0xb2, 0x8c, 0x1d, 0x28, 0xbe, 0x32, 0xf8, 0xad, 0xdd, 0xea, 0xa6, 0xc7, 0x62, + 0xac, 0xaf, 0x82, 0x21, 0x0d, 0xc7, 0x5e, 0xae, 0x8f, 0x19, 0x5c, 0xc7, 0xaa, 0xaf, 0x82, 0x43, + 0x5d, 0xd6, 0x57, 0xd6, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x2a, 0x15, 0x30, 0x52, 0x87, + 0x70, 0x00, 0xe2, 0x42, 0x75, 0x23, 0x51, 0x34, 0x95, 0x27, 0x42, 0x3e, 0x5d, 0xc7, 0x6e, 0xdb, + 0xd6, 0xdc, 0x79, 0x79, 0x78, 0xab, 0x13, 0xf8, 0xb8, 0x0a, 0x00, 0x80, 0x40, 0x17, 0xeb, 0xe1, + 0xdc, 0x00, 0x57, 0xb9, 0xce, 0x45, 0x97, 0x8f, 0xd4, 0x2a, 0x0e, 0x14, 0x3e, 0x3c, 0x7a, 0x93, + 0x0d, 0xc5, 0x38, 0x60, 0x23, 0x31, 0xe6, 0xbd, 0xf8, 0x73, 0x01, 0xaa, 0x04, 0x44, 0x00, 0xc4, + 0x9b, 0x38, 0xe8, 0x8f, 0x5e, 0x91, 0x67, 0x18, 0xb7, 0x6d, 0x66, 0x0b, 0xf1, 0x7e, 0xa2, 0x36, + 0x5e, 0xf5, 0xae, 0x19, 0xc0, 0x75, 0x98, 0x12, 0x67, 0xfe, 0xff, 0x22, 0x1a, 0x2a, 0x1d, 0xc0, + 0x04, 0x70, 0x57, 0x19, 0x03, 0xc6, 0x15, 0xd6, 0xbe, 0x21, 0xed, 0xe5, 0xe5, 0xdf, 0xcb, 0x48, + 0xac, 0xb1, 0xbd, 0xbf, 0xe1, 0xdc, 0x02, 0x94, 0xa1, 0x79, 0xa0, 0x01, 0x1f, 0xbd, 0xf9, 0x76, + 0x2e, 0x20, 0x68, 0x59, 0xad, 0x65, 0x8c, 0x53, 0x10, 0xf2, 0xf5, 0x89, 0xf8, 0x82, 0xe2, 0x56, + 0xfd, 0x6b, 0x0c, 0xca, 0x03, 0x1e, 0x33, 0xcf, 0x5f, 0xff, 0x96, 0x18, 0xc0, 0xc4, 0x42, 0x46, + 0x7a, 0xff, 0xf7, 0xc3, 0xb2, 0x00, 0x04, 0x1c, 0x22, 0xae, 0xa7, 0x33, 0x05, 0xf0, 0xa7, 0x57, + 0xed, 0xde, 0xe0, 0xc5, 0xf5, 0x47, 0x1f, 0x8e, 0x37, 0x01, 0x01, 0x0d, 0xcb, 0xaa, 0x7b, 0xe1, + 0xdc, 0x00, 0x1a, 0xc9, 0xb6, 0x81, 0x15, 0xeb, 0xd1, 0x1e, 0x30, 0xbc, 0xe7, 0xbb, 0x7c, 0x83, + 0xb7, 0xbb, 0xa6, 0x0e, 0xdd, 0xdc, 0x1f, 0xf1, 0xff, 0xc1, 0xff, 0x10, 0x66, 0x27, 0x6b, 0xb6, + 0xfa, 0x70, 0xe2, 0x80, 0x5b, 0xc3, 0x22, 0x04, 0x69, 0x40, 0xfa, 0xad, 0x29, 0x9b, 0xbb, 0x8b, + 0x62, 0xdd, 0x79, 0x77, 0xcd, 0xeb, 0x07, 0x6e, 0x5a, 0xcb, 0x58, 0x32, 0xa2, 0x5d, 0x3d, 0x36, + 0xf6, 0xe1, 0x4c, 0x00, 0x84, 0xcf, 0xf4, 0x60, 0x8f, 0xd1, 0x77, 0xa3, 0x07, 0x6f, 0x2f, 0xff, + 0xc3, 0x38, 0x08, 0xc2, 0xd6, 0x81, 0x95, 0x3b, 0xea, 0x9f, 0x6f, 0x6f, 0x79, 0x7b, 0x66, 0xe7, + 0x3e, 0x4a, 0x8c, 0xa1, 0x99, 0x40, 0x0c, 0xaa, 0xbb, 0xc3, 0xf4, 0x7b, 0xab, 0xae, 0xbf, 0xcf, + 0x86, 0x64, 0x00, 0x13, 0x73, 0x41, 0xaa, 0x5c, 0x50, 0x8d, 0xdc, 0xf7, 0x2f, 0x37, 0xae, 0x72, + 0xf6, 0xeb, 0x8c, 0xb4, 0x97, 0x8e, 0xec, 0x2b, 0x80, 0x0e, 0xf3, 0x68, 0x3f, 0x73, 0xae, 0x79, + 0x5e, 0xeb, 0x17, 0xde, 0x88, 0x5e, 0xcb, 0x0c, 0xe0, 0x05, 0x5a, 0x00, 0x66, 0xb8, 0x0e, 0x10, + 0x27, 0x9a, 0xf3, 0xc0, 0xb0, 0x7c, 0x2c, 0xf6, 0x11, 0x5b, 0x96, 0x62, 0xb2, 0xc7, 0x62, 0x06, + 0x09, 0xb1, 0xb0, 0x99, 0xe0, 0x07, 0x29, 0x54, 0x67, 0x7c, 0x66, 0x2b, 0x1f, 0xf1, 0x11, 0x01, + 0xc1, 0xe8, 0xdc, 0x50, 0x1f, 0x62, 0x62, 0x5e, 0x37, 0x37, 0x1f, 0xf1, 0xbe, 0xf8, 0xd9, 0x03, + 0x4f, 0x36, 0x22, 0x44, 0xe3, 0x62, 0x45, 0x0f, 0xb1, 0xb2, 0x08, 0x78, 0xec, 0x7e, 0x15, 0x88, + 0x0f, 0x30, 0xd5, 0xb9, 0x37, 0xfb, 0xfc, 0x46, 0x06, 0xb8, 0x87, 0xe3, 0x4c, 0x2e, 0x2e, 0x29, + 0x8b, 0x83, 0xcf, 0x96, 0x00, 0xce, 0x79, 0xc0, 0x00, 0xf1, 0x4c, 0x53, 0x10, 0x70, 0xee, 0x1c, + 0xf3, 0x80, 0x1f, 0x19, 0xe0, 0x0e, 0x08, 0x10, 0x1e, 0x24, 0x59, 0x28, 0xbf, 0xc3, 0xb8, 0x01, + 0x39, 0x5d, 0xd1, 0x56, 0xd7, 0x57, 0x72, 0x68, 0xcb, 0x58, 0x3b, 0xf0, 0x77, 0xfb, 0xe2, 0xba, + 0x6d, 0x29, 0x76, 0x31, 0xa5, 0xbc, 0x52, 0x87, 0x1d, 0x32, 0x54, 0xb4, 0x5f, 0xdf, 0x0e, 0x60, + 0x03, 0xa9, 0x87, 0xe2, 0x40, 0x59, 0xb5, 0x6f, 0x2e, 0x2a, 0xdc, 0xb0, 0x07, 0x6f, 0x09, 0xf1, + 0x2e, 0xd2, 0xbf, 0x0e, 0x2b, 0xc3, 0x6c, 0xf7, 0x8e, 0xdc, 0x24, 0x94, 0x3a, 0x63, 0x57, 0x79, + 0xdb, 0xc3, 0x98, 0x09, 0x40, 0x93, 0xf1, 0x30, 0xf2, 0x85, 0x98, 0xdd, 0x0b, 0xae, 0xce, 0x9e, + 0x2e, 0x2d, 0x8b, 0x6e, 0xa1, 0xb8, 0xb1, 0x3f, 0xed, 0x3f, 0x87, 0x70, 0x03, 0x6a, 0xfc, 0xda, + 0xbf, 0xb1, 0x34, 0xdb, 0x3f, 0xf2, 0xff, 0x4e, 0xdd, 0xe6, 0x3b, 0x69, 0xfc, 0x3b, 0x80, 0x13, + 0xc1, 0x5a, 0xf2, 0xa9, 0x33, 0xfc, 0x5f, 0x1c, 0xbc, 0x5e, 0xda, 0x8a, 0xb6, 0xdf, 0xec, 0xdf, + 0x58, 0xc7, 0xdf, 0x1d, 0xf3, 0x78, 0xf6, 0xfe, 0x1c, 0x50, 0x01, 0x49, 0xba, 0x0f, 0xa9, 0x48, + 0x12, 0xb1, 0xbe, 0x1c, 0x7f, 0x89, 0xf4, 0xcb, 0x79, 0x7d, 0x44, 0xfa, 0xb3, 0x82, 0x5a, 0xd6, + 0x5f, 0xf0, 0xee, 0x00, 0x1f, 0x59, 0x14, 0xcf, 0xd0, 0x60, 0x9a, 0x06, 0xfe, 0x2c, 0xbc, 0x56, + 0x5e, 0x5f, 0xb7, 0x77, 0x2f, 0xa6, 0x4e, 0xce, 0x09, 0xb4, 0xdf, 0xcb, 0x5f, 0x87, 0x30, 0x01, + 0xae, 0x79, 0x8f, 0x70, 0x94, 0x24, 0xfd, 0x77, 0x26, 0x5e, 0x6e, 0xea, 0xc9, 0xb9, 0x65, 0x97, + 0x67, 0x7f, 0xb7, 0x6d, 0xb6, 0xc6, 0x05, 0x74, 0x63, 0xfc, 0xbf, 0xbf, 0x86, 0x70, 0x25, 0x6f, + 0xab, 0xef, 0xae, 0xdf, 0xff, 0xab, 0x9d, 0x58, 0x77, 0x00, 0x38, 0x51, 0xa2, 0x02, 0x61, 0x02, + 0xa0, 0xac, 0x5c, 0xbc, 0x7d, 0xf5, 0x4e, 0xfd, 0x70, 0xdd, 0xd6, 0xf6, 0xfe, 0x1d, 0xc0, 0x11, + 0x89, 0xf6, 0xbd, 0x46, 0xfc, 0x76, 0xdb, 0x66, 0x9d, 0xe9, 0xaf, 0x13, 0x29, 0xd5, 0xfe, 0x19, + 0xc0, 0x07, 0x2a, 0x52, 0x4a, 0x67, 0xbe, 0x66, 0xa4, 0xfd, 0x3f, 0x6d, 0xbf, 0x1e, 0x58, 0x57, + 0x00, 0x2f, 0x49, 0x1d, 0xe4, 0x23, 0xff, 0x82, 0x79, 0xfe, 0x6e, 0xfe, 0x9d, 0xb6, 0xe1, 0xcc, + 0x00, 0x4f, 0x6c, 0x57, 0x58, 0xbb, 0xbd, 0xf1, 0xb9, 0xb0, 0xdf, 0x7d, 0xba, 0x7a, 0xc1, 0x2d, + 0xc9, 0xff, 0x1b, 0x38, 0x11, 0x32, 0x0e, 0x56, 0x32, 0x61, 0xd9, 0x80, 0x07, 0xc8, 0x31, 0xeb, + 0x7e, 0x29, 0x21, 0x86, 0xfe, 0x1b, 0xe2, 0xd6, 0x58, 0xd4, 0x2e, 0xf5, 0x31, 0xf7, 0x2e, 0xc7, + 0x79, 0xb4, 0xc2, 0xc3, 0xc5, 0x19, 0x4e, 0x74, 0xfe, 0xad, 0x51, 0xc0, 0xeb, 0x4d, 0x1f, 0x1f, + 0xbf, 0x81, 0xc0, 0x02, 0x40, 0x09, 0xa0, 0xf3, 0xc6, 0xe8, 0xe8, 0x1f, 0x7f, 0x18, 0xe0, 0x06, + 0x31, 0xd7, 0xfa, 0xb1, 0xa0, 0xdc, 0x09, 0x10, 0x5a, 0x3d, 0x57, 0x55, 0xc7, 0x00, 0x1b, 0xe8, + 0x83, 0x80, 0xef, 0xa8, 0xe0, 0x36, 0x27, 0x6a, 0x36, 0x24, 0xd9, 0xd8, 0x5e, 0x12, 0x00, 0x9c, + 0x55, 0xdb, 0xa0, 0x48, 0x02, 0x6a, 0x8d, 0xbd, 0x63, 0x4d, 0x34, 0xcb, 0xd6, 0xb4, 0xcb, 0x71, + 0x46, 0x0a, 0x30, 0x48, 0xe1, 0x72, 0x40, 0x89, 0x56, 0x27, 0x7d, 0xd5, 0x97, 0xa8, 0x1d, 0xd6, + 0x88, 0x8f, 0x30, 0xbe, 0x1b, 0xc0, 0x06, 0x0a, 0xa3, 0x32, 0x20, 0xdf, 0xbf, 0xbb, 0xf7, 0x6f, + 0xbb, 0x75, 0x75, 0x4d, 0x97, 0xff, 0x09, 0xe0, 0x10, 0xf2, 0x9d, 0x55, 0xbf, 0xd3, 0xdf, 0xe1, + 0x35, 0x08, 0x66, 0x79, 0xd7, 0xad, 0x7a, 0xd6, 0x1c, 0xc0, 0x05, 0xfa, 0x2c, 0xe3, 0x11, 0x84, + 0xcb, 0xfc, 0x5f, 0xda, 0x62, 0xf2, 0x7a, 0x69, 0xff, 0xe4, 0xdf, 0x4d, 0x79, 0xdc, 0x31, 0x42, + 0x17, 0x50, 0x01, 0x01, 0x86, 0x9d, 0x49, 0x00, 0xa6, 0x8c, 0x7e, 0xdf, 0x6d, 0xb6, 0xdc, 0xfd, + 0xcb, 0x65, 0xad, 0xb6, 0xd4, 0x3c, 0x70, 0xdd, 0x70, 0x07, 0xb0, 0x01, 0x18, 0x0a, 0x41, 0xa8, + 0x00, 0xd4, 0xa8, 0xea, 0x55, 0x03, 0x51, 0xd5, 0xcf, 0x03, 0xce, 0x0f, 0x2c, 0x00, 0xcb, 0x03, + 0x3c, 0x1e, 0x4b, 0x52, 0xc0, 0x19, 0x6b, 0x38, 0x0e, 0x1c, 0x7c, 0xc4, 0x30, 0x00, 0x0f, 0xc6, + 0x80, 0x05, 0x43, 0xc4, 0x80, 0x8b, 0x22, 0x46, 0x61, 0x0a, 0xa2, 0xb7, 0x75, 0x2f, 0xbb, 0x79, + 0x46, 0x4f, 0x1a, 0xed, 0x8d, 0xe5, 0xef, 0xf8, 0x63, 0x00, 0x61, 0xea, 0x2d, 0xf7, 0x6f, 0xfd, + 0x34, 0xde, 0x5e, 0x9d, 0x1d, 0xc2, 0x92, 0x80, 0x9c, 0x6b, 0xdf, 0x2f, 0xfd, 0xbf, 0xc3, 0x08, + 0x80, 0x04, 0x27, 0x31, 0x5d, 0x95, 0x85, 0xe0, 0xf7, 0xd9, 0xff, 0xbb, 0x67, 0xf2, 0xc3, 0x4e, + 0x03, 0x0b, 0xb8, 0x0d, 0x4c, 0x3a, 0x3d, 0xb7, 0xb7, 0x7d, 0x9e, 0x35, 0x3f, 0xca, 0x8c, 0xa1, + 0x52, 0x40, 0x21, 0xde, 0x2e, 0x66, 0xdf, 0xfd, 0x35, 0xae, 0x19, 0x70, 0x5d, 0x24, 0x1e, 0xeb, + 0xee, 0xdc, 0xd1, 0xde, 0xe6, 0x18, 0xc0, 0x05, 0x37, 0xe8, 0xe3, 0x4c, 0xb3, 0xfd, 0x5d, 0xc9, + 0x1c, 0x4e, 0x61, 0xb0, 0xc6, 0xc8, 0xa5, 0x8d, 0xcd, 0xf0, 0xbe, 0x03, 0x07, 0xeb, 0x7d, 0x7b, + 0xfe, 0x78, 0x44, 0x83, 0x0f, 0xbe, 0x31, 0x04, 0x49, 0xb5, 0x88, 0x51, 0x5c, 0x72, 0x20, 0x95, + 0x47, 0x63, 0xb4, 0xfd, 0x89, 0xf1, 0x6e, 0x6c, 0xd9, 0x8e, 0xc7, 0x99, 0x56, 0x29, 0x42, 0xb9, + 0x51, 0x8a, 0x4c, 0x7c, 0x51, 0x2f, 0x18, 0xcc, 0x58, 0xc5, 0x8a, 0xd9, 0xc3, 0xb3, 0x00, 0x06, + 0x47, 0xea, 0xbf, 0x57, 0xff, 0xff, 0xff, 0xe0, 0xda, 0xee, 0xf5, 0xf8, 0x78, 0x90, 0x01, 0x73, + 0x65, 0x21, 0x75, 0x7f, 0x0e, 0xc1, 0x3a, 0x37, 0x89, 0x3c, 0xa2, 0xd6, 0x38, 0x9f, 0xf1, 0x78, + 0xd9, 0x5f, 0xa6, 0xe0, 0x18, 0x23, 0x05, 0x1b, 0xe1, 0xbe, 0x9e, 0x1e, 0xc0, 0x13, 0xe7, 0x9b, + 0x67, 0xbc, 0x99, 0xba, 0xbf, 0xbe, 0x5e, 0xb8, 0x6d, 0x8a, 0x0c, 0xf6, 0xdf, 0xe1, 0xc5, 0x00, + 0xce, 0x18, 0xc4, 0x97, 0x28, 0xc5, 0xb1, 0xcf, 0x1f, 0x7c, 0x7f, 0xcb, 0x2e, 0x7f, 0xe3, 0x7c, + 0xfa, 0xb7, 0x9d, 0xa9, 0x54, 0x5d, 0x6b, 0xf0, 0xf2, 0x80, 0x1e, 0x6c, 0x8c, 0x14, 0x1e, 0xcf, + 0xbb, 0x13, 0xcc, 0x43, 0xf1, 0x58, 0x3b, 0xf9, 0x8e, 0xde, 0xe7, 0x3e, 0xe4, 0xbc, 0x94, 0xf8, + 0x6d, 0xc0, 0x07, 0x33, 0xfc, 0x42, 0xee, 0x28, 0xa5, 0x96, 0xb1, 0x45, 0x97, 0xb3, 0x96, 0xb2, + 0xd6, 0x3e, 0xe5, 0x97, 0x37, 0x6c, 0xbc, 0x7d, 0xc7, 0x54, 0xbd, 0xd9, 0x6e, 0xff, 0x0f, 0x60, + 0x01, 0x2e, 0xe5, 0x93, 0x46, 0x68, 0xd4, 0x4d, 0x66, 0xbe, 0xbe, 0x2b, 0x89, 0x70, 0x9a, 0xb7, + 0x19, 0x7a, 0xc7, 0x1c, 0x82, 0x97, 0xcd, 0x7f, 0x87, 0x89, 0x00, 0xcc, 0xc7, 0x7a, 0x81, 0x7f, + 0xff, 0xb2, 0xbb, 0x39, 0x7a, 0xd7, 0x1b, 0xd7, 0x5e, 0xde, 0x37, 0xc2, 0xeb, 0x7f, 0xe1, 0xdc, + 0x00, 0xf5, 0x12, 0x20, 0x4b, 0x32, 0x13, 0xc0, 0xef, 0xe6, 0x92, 0xc7, 0x9f, 0x8f, 0x72, 0x77, + 0x78, 0x87, 0xb2, 0x9e, 0x17, 0x8e, 0xdf, 0xc3, 0x38, 0x04, 0x43, 0x63, 0xb8, 0x38, 0x36, 0xfb, + 0xf3, 0x76, 0xfb, 0x77, 0xec, 0x3b, 0x80, 0x0d, 0x45, 0xde, 0x73, 0xa9, 0x50, 0xdb, 0xee, 0xdc, + 0x1a, 0x2d, 0x5b, 0x9f, 0xf3, 0xd4, 0x7f, 0xf3, 0x72, 0x9b, 0xbe, 0x2b, 0x48, 0xe7, 0x29, 0xe8, + 0x6f, 0xff, 0x0e, 0xa2, 0x80, 0x23, 0xf7, 0x4e, 0x7f, 0xf9, 0xff, 0xf7, 0x51, 0x58, 0x9d, 0x15, + 0x72, 0x74, 0xfe, 0x1d, 0x44, 0x00, 0x13, 0xcf, 0x65, 0x03, 0x97, 0x08, 0xff, 0xd3, 0xa7, 0x6c, + 0xbe, 0xc6, 0xf8, 0xab, 0x72, 0xfe, 0x1e, 0xbe, 0x9e, 0x31, 0x0c, 0xe9, 0xfe, 0x1e, 0xc0, 0x0c, + 0xcd, 0x21, 0x31, 0x91, 0x57, 0xc0, 0xef, 0xcf, 0xf8, 0xce, 0xff, 0x4f, 0xfb, 0x63, 0x52, 0xa2, + 0xff, 0x0f, 0x28, 0x03, 0x29, 0xcf, 0x48, 0xf3, 0xea, 0xe2, 0xf5, 0xd3, 0x27, 0xca, 0x7f, 0x6f, + 0xe1, 0x85, 0x00, 0x62, 0x7e, 0x0e, 0xf5, 0x04, 0xff, 0xf6, 0xdb, 0xdb, 0x6f, 0x8b, 0x0b, 0xb2, + 0x82, 0x06, 0x80, 0xb9, 0xef, 0xaf, 0xff, 0xd6, 0x1c, 0x44, 0x00, 0x1b, 0xe2, 0xb6, 0x2e, 0x65, + 0x31, 0x5d, 0x6f, 0xf2, 0xc7, 0x2f, 0xff, 0xad, 0x17, 0xfc, 0x48, 0x26, 0xe0, 0xc4, 0xd7, 0x28, + 0x86, 0xad, 0xc3, 0x80, 0x00, 0xbe, 0x14, 0x40, 0x35, 0x00, 0x40, 0x16, 0x39, 0x84, 0xc6, 0x18, + 0xb6, 0x29, 0x4b, 0x91, 0x2b, 0x8c, 0x53, 0x63, 0x63, 0x91, 0x3d, 0x85, 0xe3, 0x80, 0x12, 0x3f, + 0x24, 0x75, 0xf7, 0xfe, 0xbe, 0x7f, 0xb6, 0x6e, 0xe6, 0x13, 0x24, 0x02, 0x46, 0x6c, 0x9b, 0xe7, + 0xfc, 0xd6, 0xb7, 0x77, 0xad, 0x5d, 0xc5, 0x78, 0x4f, 0x04, 0x69, 0x06, 0x72, 0xcd, 0x7d, 0xd6, + 0xbf, 0x84, 0xd4, 0x13, 0xa2, 0xb1, 0x27, 0xfe, 0xf7, 0xfc, 0x2a, 0x8a, 0x02, 0x5c, 0xd6, 0x15, + 0xf7, 0xff, 0x5c, 0x2c, 0x48, 0x01, 0xab, 0x2d, 0xc3, 0x32, 0xbb, 0xdf, 0xe7, 0xed, 0xbf, 0x5c, + 0x53, 0x89, 0xa2, 0x87, 0xa4, 0x00, 0x23, 0x80, 0x5d, 0x8a, 0xa8, 0x1a, 0xa2, 0xe8, 0xae, 0x5e, + 0x39, 0x83, 0xbe, 0x32, 0xfa, 0xd5, 0x31, 0x1f, 0x55, 0x5f, 0xf0, 0xf6, 0x00, 0x5e, 0x2c, 0x48, + 0x55, 0x3b, 0xaa, 0x1e, 0xb2, 0xce, 0x26, 0x1c, 0x32, 0x04, 0xe0, 0xe3, 0x14, 0xf0, 0xaf, 0x8a, + 0x3e, 0x1d, 0x5a, 0x6c, 0xe2, 0xdc, 0x6d, 0xf1, 0xc6, 0xae, 0xdb, 0xdd, 0x38, 0x6c, 0x90, 0x03, + 0x1f, 0xc3, 0xf6, 0xbb, 0x4f, 0xdf, 0xdc, 0x74, 0xfa, 0x9f, 0xfd, 0xbd, 0x9c, 0x7f, 0xe3, 0xdd, + 0xcb, 0x25, 0x3d, 0x7e, 0x13, 0xc0, 0x17, 0x7d, 0x8a, 0x83, 0xeb, 0x5f, 0xd6, 0xb0, 0xd9, 0x20, + 0x03, 0x44, 0x5b, 0x03, 0xc4, 0xe0, 0xea, 0x37, 0x5e, 0xfd, 0xdb, 0x77, 0xbb, 0xbb, 0xb9, 0x63, + 0x7f, 0xef, 0x0c, 0x28, 0x01, 0x33, 0x4d, 0x06, 0x51, 0x95, 0xce, 0xff, 0x07, 0xe2, 0xac, 0xb6, + 0x78, 0xb7, 0x7d, 0xfa, 0xd7, 0x1d, 0xc6, 0x18, 0x70, 0x01, 0xb9, 0x2a, 0xe5, 0xc8, 0x33, 0x3f, + 0x85, 0x53, 0x60, 0xdf, 0xc5, 0x97, 0x24, 0xe0, 0xf5, 0xcb, 0xb8, 0xd3, 0xe3, 0xe3, 0xa4, 0x79, + 0x85, 0x89, 0x00, 0x3f, 0xdf, 0x0f, 0x0b, 0xb2, 0x7b, 0x7b, 0x77, 0x57, 0xaf, 0x85, 0x30, 0x09, + 0x9b, 0x97, 0x5b, 0xf4, 0xe3, 0xd3, 0x07, 0xfe, 0xfb, 0x6d, 0xfc, 0x2c, 0xa0, 0x0f, 0xa8, 0x2e, + 0x7d, 0xaa, 0x02, 0x9c, 0xd5, 0xe9, 0x97, 0x96, 0xa2, 0xae, 0xcf, 0xde, 0xdb, 0xb9, 0x6d, 0xcb, + 0xe1, 0xbc, 0x02, 0x68, 0xc6, 0x56, 0x7a, 0x56, 0x5c, 0xa1, 0x43, 0xfb, 0x1f, 0x92, 0x71, 0x65, + 0x2b, 0x03, 0xcf, 0xf8, 0xf8, 0xd4, 0x3f, 0x5c, 0xec, 0xa0, 0x26, 0x63, 0x4a, 0x6a, 0x2e, 0x2c, + 0x40, 0x3f, 0xd8, 0xe5, 0x3a, 0x9e, 0xc6, 0x4b, 0x6c, 0x43, 0x10, 0x3e, 0xce, 0x28, 0x90, 0xb9, + 0x58, 0xe5, 0x26, 0x36, 0x26, 0x53, 0x6c, 0x5f, 0x8b, 0x18, 0x42, 0x63, 0x98, 0xc8, 0x56, 0x0e, + 0xa0, 0x52, 0x46, 0x21, 0x9e, 0xc3, 0xc4, 0x09, 0x00, 0x01, 0x34, 0xcb, 0x30, 0xcc, 0xe6, 0x00, + 0x8f, 0x7e, 0xfc, 0x7b, 0xa8, 0x8f, 0x24, 0x3e, 0x1e, 0xbb, 0x6e, 0x23, 0xd4, 0xef, 0x2c, 0xce, + 0x1c, 0xac, 0xb5, 0x96, 0x36, 0x3d, 0x6b, 0x58, 0x6d, 0xc0, 0x45, 0xda, 0x38, 0xd6, 0xfd, 0x6a, + 0xb3, 0xf9, 0xb2, 0x67, 0xb3, 0x2f, 0x4d, 0x33, 0x5d, 0xbf, 0xc2, 0xd8, 0x08, 0x39, 0xc4, 0xaf, + 0xf5, 0xaa, 0x69, 0xdb, 0xfa, 0x7c, 0x3b, 0x81, 0x2a, 0x6b, 0x43, 0xd3, 0xbf, 0x5d, 0x3f, 0x75, + 0x4d, 0x31, 0xbe, 0x1d, 0xb8, 0xad, 0x46, 0x95, 0x3f, 0x87, 0x5c, 0x01, 0x72, 0x4b, 0xc5, 0x65, + 0x2c, 0x32, 0xfc, 0x3e, 0xf6, 0xcd, 0xfd, 0xeb, 0xb1, 0x6c, 0xde, 0x3f, 0xe6, 0xcd, 0xe9, 0xf6, + 0xd3, 0xdb, 0x87, 0x89, 0x00, 0x0b, 0x2d, 0xf7, 0x15, 0x10, 0xbd, 0x5c, 0x5b, 0x9f, 0xea, 0x50, + 0xba, 0xad, 0xd6, 0xe9, 0xee, 0x9e, 0x69, 0x16, 0xe3, 0x0a, 0xbc, 0x7a, 0xcb, 0x2c, 0xa5, 0x70, + 0x9f, 0x77, 0x13, 0x22, 0x2b, 0x64, 0xed, 0xe7, 0xed, 0xe9, 0xc3, 0xce, 0x04, 0xcd, 0xee, 0x0d, + 0xea, 0x8e, 0xef, 0xec, 0xf7, 0xb7, 0x4f, 0x71, 0x57, 0x5e, 0x4a, 0xbf, 0xf0, 0xe3, 0x80, 0x31, + 0x86, 0x0b, 0xe8, 0xee, 0x7c, 0xda, 0xcd, 0xcb, 0x47, 0xd2, 0x38, 0xeb, 0x6f, 0x6d, 0xb1, 0x1d, + 0x77, 0x26, 0x3f, 0xf0, 0xde, 0x02, 0x06, 0x8d, 0x50, 0x7f, 0x77, 0x4d, 0x3f, 0xbd, 0xbf, 0x4e, + 0x30, 0x7f, 0xf0, 0xcb, 0x80, 0x4f, 0xe1, 0x6a, 0x1c, 0x78, 0x7d, 0x3a, 0x69, 0xaf, 0xf9, 0x94, + 0x61, 0x8c, 0x03, 0x01, 0x5a, 0x94, 0x60, 0x4e, 0x5e, 0xdb, 0x7f, 0xfb, 0x30, 0xe6, 0x01, 0x2b, + 0xd3, 0xb3, 0xff, 0xbd, 0x35, 0xc1, 0xaf, 0xf0, 0xee, 0x00, 0x80, 0x56, 0x2d, 0xe2, 0x7c, 0xfe, + 0x8b, 0xb9, 0x5f, 0xcf, 0xe7, 0xe6, 0xfd, 0x46, 0x4a, 0xf5, 0x2f, 0xf8, 0x5e, 0x52, 0x43, 0xfb, + 0x7f, 0x2f, 0x7d, 0xf0, 0xbc, 0x80, 0x06, 0x6f, 0xdc, 0x44, 0xaf, 0x4d, 0xad, 0x7d, 0x35, 0x4d, + 0x7c, 0xa0, 0xc6, 0x21, 0x21, 0x0e, 0x66, 0x1d, 0xd8, 0x77, 0x08, 0x59, 0xe5, 0x53, 0xdb, 0xff, + 0xff, 0xd3, 0xb7, 0xf8, 0x65, 0x88, 0x02, 0x11, 0x3a, 0x4a, 0xbf, 0xc6, 0xf8, 0xb5, 0xd8, 0x3e, + 0xeb, 0xf3, 0x98, 0x6c, 0x90, 0x03, 0xe4, 0x32, 0x94, 0xb4, 0xc1, 0x8c, 0xb3, 0x8e, 0xfc, 0x43, + 0x07, 0xc7, 0xc5, 0x79, 0x78, 0xa5, 0xef, 0x2b, 0x1f, 0xf7, 0xbe, 0x2e, 0x34, 0xd9, 0x81, 0x5f, + 0x80, 0xf8, 0x51, 0xa0, 0x02, 0x98, 0xd2, 0x1c, 0xd9, 0xc8, 0xa2, 0x17, 0x3c, 0x86, 0x20, 0xc3, + 0x71, 0xc0, 0x01, 0xd8, 0xa6, 0x43, 0x17, 0x68, 0xbf, 0x2c, 0x01, 0x4c, 0x19, 0x7c, 0x58, 0xb7, + 0x81, 0x85, 0x8a, 0x2c, 0xb1, 0x6d, 0xb6, 0x4e, 0xf3, 0x7e, 0x2d, 0xdc, 0x1f, 0xf0, 0xa3, 0xc3, + 0x00, 0x18, 0xe1, 0xaa, 0x6b, 0x7f, 0x0d, 0xe0, 0x01, 0xfb, 0xd8, 0xdc, 0x4c, 0xdb, 0x78, 0xe3, + 0x8b, 0xe0, 0x76, 0xe7, 0xf9, 0xfe, 0x79, 0xfc, 0x90, 0xa9, 0x67, 0x22, 0x9d, 0x71, 0x2f, 0x5c, + 0xaf, 0x7f, 0xc2, 0xf8, 0x01, 0x05, 0x71, 0xb4, 0x39, 0x0b, 0xeb, 0xe5, 0x84, 0xb0, 0x76, 0xc2, + 0xaf, 0x16, 0xb5, 0xb1, 0x77, 0x47, 0x70, 0x9b, 0x9a, 0x2b, 0x44, 0xe7, 0xeb, 0x5f, 0xc2, 0xb1, + 0x21, 0x88, 0x3b, 0xd5, 0xf7, 0xff, 0xc2, 0xec, 0x40, 0x01, 0x90, 0x2a, 0x1f, 0xc7, 0xb7, 0xd2, + 0x6e, 0xa3, 0x3d, 0x37, 0x7f, 0x2f, 0x53, 0xda, 0x28, 0xff, 0xc6, 0xb1, 0xc7, 0x76, 0x14, 0x67, + 0x00, 0x7b, 0x6f, 0xab, 0x13, 0x4f, 0x4c, 0x9f, 0xff, 0x85, 0x54, 0x09, 0x9b, 0x87, 0xd4, 0x37, + 0xa7, 0xff, 0xf0, 0xc2, 0x80, 0x3b, 0x99, 0xe1, 0xa4, 0xcb, 0x1a, 0xb7, 0x7f, 0xff, 0xb1, 0x8a, + 0x03, 0xd3, 0x35, 0xaa, 0xc2, 0xae, 0x1b, 0x5e, 0x5f, 0xaf, 0xff, 0x0d, 0x10, 0xc0, 0x23, 0x31, + 0xe1, 0x9c, 0x1f, 0x0b, 0x5e, 0x75, 0x0a, 0xb5, 0xc8, 0x96, 0x2e, 0x31, 0xec, 0x34, 0xe0, 0x20, + 0x49, 0xfd, 0xe9, 0xce, 0xbe, 0xde, 0x8e, 0x74, 0x78, 0x3f, 0xf3, 0x4b, 0x8e, 0x70, 0xe3, 0xeb, + 0xe2, 0x11, 0x42, 0x19, 0xd6, 0xa1, 0x9c, 0x11, 0x34, 0x5b, 0xf2, 0xdf, 0xff, 0xfa, 0xc3, 0x04, + 0x81, 0x3f, 0x9a, 0x16, 0xaf, 0xbf, 0xff, 0x16, 0x1a, 0x90, 0x00, 0xad, 0xe6, 0x05, 0x2e, 0x82, + 0xe0, 0xe9, 0x19, 0xd9, 0x7a, 0xc6, 0x5e, 0xa3, 0x9f, 0x96, 0x5a, 0xd5, 0x53, 0x16, 0xd3, 0x4d, + 0xb0, 0xba, 0x80, 0x01, 0x29, 0x01, 0x57, 0xe3, 0x2c, 0x67, 0xd1, 0x5f, 0x5b, 0x4f, 0xe0, 0xe7, + 0xe0, 0xff, 0x8f, 0xf8, 0xff, 0xa7, 0x2c, 0x2c, 0x1c, 0xfe, 0x73, 0x09, 0xb3, 0x82, 0x41, 0x95, + 0xb3, 0xff, 0x4f, 0xf0, 0xbb, 0x97, 0x3f, 0xff, 0xa6, 0xd8, 0x5a, 0x60, 0x00, 0x3c, 0xc9, 0x81, + 0x44, 0x1d, 0xa2, 0x10, 0x5d, 0xef, 0x5f, 0xd3, 0xc5, 0xb0, 0x70, 0x3b, 0x83, 0xd7, 0x2c, 0xb1, + 0xcd, 0xdb, 0xe1, 0x3c, 0x00, 0x52, 0x92, 0x87, 0xd9, 0x87, 0x69, 0x7b, 0xda, 0x6f, 0xe2, 0x1f, + 0x65, 0xb4, 0xf7, 0xc7, 0x42, 0x60, 0x52, 0x5d, 0x61, 0x9e, 0xc5, 0xa1, 0xb1, 0xd9, 0x14, 0x5a, + 0x09, 0x63, 0x98, 0xb5, 0xa4, 0xce, 0xf8, 0xb4, 0x51, 0x7e, 0x36, 0xa3, 0x10, 0xf8, 0xec, 0x4a, + 0x50, 0xdb, 0x0f, 0x00, 0x0c, 0xa1, 0x98, 0x35, 0xf8, 0x21, 0x5f, 0x7f, 0xc2, 0xbb, 0x74, 0xc4, + 0x1f, 0xb3, 0xe9, 0x93, 0xb6, 0x83, 0xee, 0x15, 0x78, 0xb1, 0x6f, 0xa0, 0x97, 0xf6, 0xff, 0x86, + 0xf0, 0x08, 0xe8, 0xe4, 0x47, 0xf2, 0xac, 0xdd, 0xf6, 0x7d, 0xa6, 0xcf, 0x1f, 0xdd, 0x31, 0x70, + 0x7b, 0xff, 0x87, 0x70, 0x01, 0xce, 0x7d, 0x09, 0x0a, 0xa7, 0xef, 0xeb, 0x5d, 0xd5, 0xb4, 0xdc, + 0x55, 0xb6, 0xea, 0x02, 0x3f, 0x48, 0x9b, 0xf0, 0xee, 0x00, 0x30, 0x8d, 0x81, 0xbc, 0xba, 0x88, + 0xff, 0xdf, 0x4d, 0x83, 0x8f, 0xc4, 0xbe, 0x37, 0xd6, 0x47, 0xaf, 0x1e, 0x23, 0xd3, 0xca, 0x3f, + 0x0e, 0x2b, 0x95, 0xbe, 0x29, 0xb8, 0x18, 0x5b, 0x19, 0x02, 0x75, 0x6a, 0xff, 0xfc, 0x3b, 0x80, + 0x08, 0xa1, 0x40, 0xec, 0x83, 0x51, 0x2d, 0xc7, 0xfd, 0xfb, 0x67, 0xf7, 0x76, 0x36, 0x00, 0xd1, + 0xf0, 0x55, 0xb8, 0xf6, 0x12, 0x12, 0x44, 0x7f, 0xa8, 0x53, 0x9f, 0xc3, 0xaa, 0x00, 0x45, 0xc3, + 0x5e, 0xc4, 0x7e, 0xb0, 0x11, 0x39, 0xff, 0x8e, 0x1f, 0x55, 0x31, 0x4b, 0xac, 0xb1, 0x60, 0xf7, + 0xe3, 0x8a, 0xaa, 0x20, 0x78, 0xf5, 0xee, 0x43, 0x71, 0x43, 0xea, 0xd3, 0xf2, 0xdf, 0xaf, 0xa7, + 0x0d, 0xe0, 0x01, 0x2a, 0xab, 0x5a, 0x28, 0x82, 0x2c, 0x17, 0xfa, 0x4e, 0xd2, 0x53, 0xf1, 0xaf, + 0xc5, 0x62, 0x2a, 0x55, 0xeb, 0xe1, 0xb5, 0x00, 0x0d, 0xf9, 0xe3, 0xb6, 0x53, 0x42, 0x6e, 0x1b, + 0xe2, 0xd6, 0x58, 0xe6, 0xe5, 0xb5, 0x2f, 0x66, 0x2d, 0xab, 0x64, 0xad, 0x7a, 0x63, 0x54, 0x64, + 0xbf, 0xe1, 0xb7, 0x00, 0x29, 0x89, 0xe4, 0x71, 0x09, 0xcf, 0x2e, 0x1f, 0xc5, 0x71, 0x5a, 0xb6, + 0x6e, 0x9e, 0x2d, 0x46, 0x6f, 0x5f, 0xc3, 0x8e, 0x00, 0xcb, 0xab, 0x23, 0x11, 0xbe, 0xd7, 0xfd, + 0x36, 0xdb, 0x4d, 0x36, 0xe4, 0x4e, 0x9f, 0xe2, 0xa7, 0x02, 0x26, 0xb8, 0xfe, 0x18, 0x98, 0x04, + 0xaf, 0xa2, 0x42, 0xa6, 0xbd, 0xdb, 0x6d, 0x34, 0xff, 0xf3, 0x61, 0xe2, 0x40, 0x07, 0xf7, 0x3c, + 0x91, 0xe2, 0xdc, 0xa0, 0xff, 0xe0, 0xfb, 0xcd, 0xbf, 0xf1, 0x6a, 0x5b, 0x7d, 0x3f, 0x86, 0x5c, + 0x02, 0x57, 0x3d, 0x95, 0xf3, 0xfd, 0xbf, 0x6e, 0x9a, 0x7e, 0x7b, 0x0e, 0x28, 0x00, 0x1d, 0xa9, + 0xb0, 0xf3, 0xd2, 0x81, 0x1e, 0xf2, 0x7e, 0xef, 0xe2, 0xaf, 0x2a, 0xf1, 0xde, 0xb8, 0xee, 0x93, + 0x96, 0x8d, 0xdf, 0xc2, 0xee, 0x00, 0x42, 0x6d, 0x5e, 0x93, 0xbf, 0x2f, 0xf6, 0xf5, 0xfe, 0xc3, + 0x33, 0x82, 0x6f, 0x8b, 0xb8, 0xff, 0x5f, 0xc6, 0xfb, 0x4a, 0xa1, 0xe6, 0x60, 0x00, 0xd1, 0x10, + 0x66, 0xcf, 0xc8, 0xe0, 0xe3, 0x4a, 0x38, 0xbf, 0x9f, 0x9f, 0xb6, 0x3a, 0xf8, 0xe2, 0xb9, 0xf8, + 0xeb, 0xf6, 0x73, 0xcf, 0x7e, 0xde, 0x98, 0x6b, 0xa0, 0x48, 0xab, 0x6d, 0xed, 0xbf, 0x03, 0x40, + 0x04, 0x80, 0x12, 0xcb, 0x00, 0x03, 0xb0, 0xd8, 0x00, 0x19, 0x18, 0x71, 0x60, 0x6a, 0x5a, 0xf0, + 0x75, 0xff, 0x01, 0xc0, 0x01, 0x1f, 0x8e, 0x20, 0xb8, 0xfb, 0x11, 0xe2, 0x89, 0xc7, 0x21, 0x36, + 0xc7, 0x23, 0x30, 0x7d, 0x85, 0xe3, 0x00, 0x04, 0x98, 0x57, 0x4e, 0xac, 0x21, 0x00, 0x3e, 0x26, + 0x4f, 0x97, 0x63, 0xef, 0x27, 0xea, 0x48, 0x97, 0xc2, 0x14, 0xc1, 0x60, 0x63, 0x01, 0x50, 0xee, + 0x00, 0xf9, 0x02, 0x26, 0xdc, 0x41, 0x10, 0x8e, 0xcd, 0xdd, 0xa3, 0x10, 0x7c, 0x65, 0xe7, 0x8c, + 0x24, 0xf1, 0x80, 0xa2, 0xfc, 0x98, 0x8f, 0xa8, 0x77, 0x3c, 0x3e, 0xf3, 0x9e, 0xde, 0x02, 0x0d, + 0xeb, 0xf0, 0xde, 0x00, 0x5f, 0xdf, 0x18, 0xc4, 0x2b, 0x3e, 0x8e, 0xfd, 0xf8, 0x9d, 0xd6, 0x6f, + 0x87, 0xd3, 0x52, 0xc2, 0x4b, 0x0c, 0x47, 0x9c, 0x07, 0xb3, 0x9c, 0x30, 0x2f, 0x38, 0x18, 0x17, + 0x83, 0xbb, 0x19, 0xef, 0xf9, 0xdc, 0xe6, 0xa7, 0x94, 0x26, 0x51, 0x69, 0x30, 0x9a, 0x20, 0x01, + 0x27, 0xc3, 0x91, 0x6a, 0x17, 0xdd, 0x5e, 0xf7, 0xbf, 0x3f, 0x6e, 0x13, 0x47, 0x04, 0xea, 0x20, + 0x2c, 0xe3, 0xff, 0x55, 0xfc, 0x2a, 0xa1, 0x11, 0x81, 0x23, 0x7f, 0xbf, 0xfc, 0xee, 0x08, 0x54, + 0xe9, 0xe8, 0x4e, 0x40, 0x08, 0x1e, 0xde, 0x1b, 0x69, 0xff, 0xfc, 0xfe, 0x1c, 0xc0, 0x05, 0xd3, + 0x83, 0x4a, 0xb0, 0x63, 0xce, 0xdd, 0xfb, 0xfc, 0xfc, 0x55, 0x9e, 0xf1, 0xc7, 0xe2, 0xad, 0xb2, + 0xc5, 0x83, 0xb7, 0x12, 0x68, 0x44, 0x96, 0x9a, 0x7b, 0x6d, 0xc3, 0x2e, 0x00, 0x22, 0xae, 0x21, + 0xf7, 0x8c, 0x16, 0xef, 0xf4, 0x57, 0x2f, 0xa6, 0xea, 0xde, 0xef, 0x2f, 0x65, 0x5b, 0xb3, 0x41, + 0xf9, 0x0d, 0xe0, 0x04, 0x21, 0xd0, 0xe6, 0x7b, 0x7b, 0xbd, 0x4b, 0xd6, 0xb6, 0xdc, 0xbe, 0x19, + 0xbd, 0xba, 0x0f, 0xe4, 0x63, 0xa7, 0xfb, 0x70, 0xa6, 0x01, 0x38, 0x74, 0x81, 0x0e, 0x86, 0xa6, + 0xe9, 0xc7, 0xa6, 0x9b, 0x6d, 0xca, 0xcd, 0xf8, 0x53, 0x00, 0x28, 0x19, 0x6e, 0x5d, 0x4b, 0x1f, + 0x74, 0xed, 0xdc, 0xd4, 0xc9, 0x42, 0xea, 0x69, 0xb7, 0x6e, 0x15, 0x50, 0x02, 0xad, 0x3c, 0xb5, + 0x15, 0xff, 0x9f, 0x8a, 0xb5, 0x83, 0xb7, 0x37, 0x85, 0x65, 0x02, 0x26, 0xf4, 0x8f, 0xff, 0xe9, + 0xc2, 0x8c, 0x80, 0x11, 0xb3, 0x94, 0x8a, 0xdf, 0xf7, 0xa6, 0xdf, 0xdb, 0xc2, 0x98, 0x03, 0x7c, + 0x51, 0xe7, 0x70, 0xc4, 0x8a, 0x2b, 0x9b, 0xdb, 0xee, 0xdb, 0xc7, 0xff, 0x74, 0xd3, 0xcb, 0xdb, + 0xd3, 0x2e, 0xe1, 0xac, 0x01, 0x4c, 0xca, 0x0b, 0x14, 0xe0, 0xa3, 0xa2, 0xe3, 0xde, 0x37, 0x9f, + 0xdd, 0x8a, 0xb6, 0xdb, 0x6d, 0xd5, 0x2c, 0xb8, 0xd3, 0x05, 0xc0, 0xc1, 0x9a, 0x00, 0x1d, 0xca, + 0xeb, 0x47, 0xe1, 0xa5, 0x00, 0x0a, 0xec, 0x25, 0xe5, 0x2d, 0x30, 0x62, 0x34, 0xe1, 0x7f, 0xf8, + 0x55, 0x9b, 0x80, 0xef, 0x21, 0x8b, 0x1b, 0x10, 0xf7, 0x85, 0xc9, 0x62, 0x78, 0xfa, 0xf0, 0x7b, + 0xac, 0xb5, 0x8a, 0xb2, 0xd6, 0x2a, 0xc5, 0x58, 0xab, 0x45, 0xaa, 0x1c, 0xc0, 0x07, 0x5e, 0x24, + 0x20, 0x7b, 0xb5, 0xb9, 0x56, 0x79, 0x30, 0x51, 0xb8, 0xf0, 0x1d, 0xae, 0xb3, 0xc0, 0x1d, 0x2a, + 0x00, 0xf5, 0xac, 0xf7, 0xfc, 0x05, 0xb3, 0x3c, 0x00, 0xcc, 0x66, 0xab, 0xc4, 0x74, 0x93, 0x7d, + 0x3f, 0x09, 0xb8, 0x03, 0xe3, 0x4d, 0xbc, 0x18, 0xed, 0xe4, 0x3e, 0xf4, 0x62, 0x8d, 0x0a, 0x32, + 0x77, 0xb9, 0xb2, 0xfd, 0xf5, 0xd6, 0xb8, 0xa5, 0xc4, 0x3e, 0x28, 0x82, 0xc3, 0xf9, 0x27, 0x9c, + 0x99, 0x0d, 0xa0, 0x90, 0x00, 0x45, 0x1b, 0x9a, 0x08, 0xbe, 0x62, 0x17, 0xf8, 0x37, 0x77, 0xcb, + 0x03, 0x8a, 0x07, 0x20, 0xbe, 0xb5, 0x9f, 0xc4, 0x30, 0x86, 0xf0, 0x00, 0x91, 0x44, 0x2b, 0x8a, + 0xe1, 0x2c, 0xc3, 0x45, 0xd8, 0xff, 0xfd, 0xbc, 0x43, 0xe3, 0x1e, 0xfe, 0x33, 0xdc, 0x00, 0x45, + 0x3e, 0x7a, 0xd9, 0x4c, 0x53, 0x16, 0x21, 0xcc, 0x1c, 0x00, 0xc0, 0x04, 0xe2, 0xa0, 0xd8, 0x1a, + 0x97, 0x9c, 0x00, 0xf0, 0x7b, 0xe7, 0x00, 0x0e, 0x17, 0x9c, 0x00, 0x04, 0x78, 0x39, 0x00, 0x30, + 0x48, 0xb0, 0xdb, 0x80, 0x3b, 0x3c, 0xfa, 0x3a, 0x08, 0xf7, 0x7c, 0xe6, 0xed, 0x6a, 0xaa, 0x3b, + 0xac, 0xfe, 0xa0, 0xed, 0xe4, 0x6e, 0x67, 0xa7, 0xf8, 0x7b, 0x00, 0x2d, 0x36, 0x99, 0x82, 0x79, + 0x2b, 0x14, 0x43, 0xd7, 0xd4, 0x1f, 0xf1, 0xf7, 0xb6, 0x7e, 0x5a, 0xeb, 0x2d, 0x66, 0xf1, 0x83, + 0xf6, 0xcd, 0xd6, 0x3f, 0x87, 0x70, 0x01, 0x5e, 0x4d, 0xa3, 0x70, 0x85, 0x77, 0xca, 0xda, 0xbe, + 0xe6, 0x35, 0xd9, 0x39, 0x3f, 0xf9, 0x1d, 0xc6, 0xdb, 0x7f, 0x86, 0x14, 0x02, 0xdd, 0xf3, 0x51, + 0x82, 0x07, 0x57, 0x5e, 0x57, 0xf1, 0x77, 0xf6, 0xdb, 0x7d, 0xb0, 0xdb, 0xf8, 0x79, 0x40, 0x19, + 0x2d, 0x34, 0x46, 0xff, 0x77, 0xa2, 0x1a, 0x17, 0x8a, 0xc5, 0xed, 0x9f, 0xfb, 0x77, 0xc4, 0xbc, + 0x11, 0x53, 0x4f, 0xf8, 0x5f, 0x00, 0xc9, 0xb0, 0xa3, 0x53, 0xeb, 0x17, 0xf5, 0x17, 0xaf, 0xd8, + 0x75, 0x40, 0x09, 0x12, 0x1d, 0xbf, 0x60, 0xce, 0x6e, 0x15, 0x9b, 0xbe, 0x6f, 0x5a, 0x71, 0x2e, + 0x08, 0xf8, 0xff, 0x8d, 0x54, 0xed, 0xaf, 0xc3, 0xaa, 0x00, 0xae, 0x27, 0x10, 0x1c, 0xde, 0x3d, + 0x19, 0xf8, 0xd3, 0xdb, 0x5a, 0xf8, 0x26, 0xb7, 0x7f, 0xc3, 0x98, 0x01, 0xc4, 0x76, 0x4e, 0xce, + 0x9b, 0xfe, 0xfa, 0xb7, 0x4f, 0x3f, 0x14, 0x5e, 0x28, 0xb3, 0x78, 0xad, 0xcd, 0x52, 0x57, 0xe1, + 0xec, 0x00, 0x9a, 0x81, 0x57, 0xb4, 0xa3, 0x6d, 0xfc, 0xdd, 0x3b, 0x6d, 0xb7, 0x70, 0xba, 0xb7, + 0x9f, 0xca, 0xb6, 0x3b, 0x75, 0x7f, 0x87, 0xb0, 0x01, 0x27, 0x89, 0x3a, 0xee, 0x17, 0xca, 0x1f, + 0x6d, 0xbc, 0x4b, 0xc1, 0xdf, 0xbe, 0xab, 0xd4, 0xaa, 0x94, 0xfd, 0x47, 0xdc, 0x32, 0x87, 0x69, + 0xa8, 0xda, 0xfc, 0x32, 0xe0, 0x0d, 0x51, 0xd8, 0x54, 0xe8, 0xee, 0x2b, 0x37, 0x73, 0xbe, 0xbb, + 0x3e, 0xd9, 0x7e, 0x2b, 0x4c, 0x2e, 0xe2, 0x80, 0xb9, 0xb7, 0x39, 0xfa, 0xfe, 0xa4, 0x6c, 0x30, + 0x43, 0x80, 0x4e, 0xfc, 0x2a, 0x9e, 0x7d, 0xbe, 0x2d, 0xff, 0xfc, 0x97, 0x0a, 0x60, 0x53, 0x99, + 0x29, 0x27, 0xff, 0xfe, 0x18, 0x21, 0x80, 0x09, 0x7a, 0xe6, 0xb5, 0x9f, 0xdf, 0xbb, 0xdb, 0xfe, + 0xb0, 0xe2, 0x80, 0x10, 0xc0, 0xc5, 0x4b, 0xd8, 0xe1, 0x1b, 0xbb, 0xa6, 0x5a, 0x45, 0x1d, 0x3d, + 0x31, 0x0f, 0x97, 0xc4, 0x6f, 0xf7, 0xe1, 0xb7, 0x00, 0x30, 0x80, 0x75, 0xe5, 0x35, 0x17, 0x73, + 0xbf, 0xde, 0x3d, 0xf1, 0x6e, 0x98, 0xb6, 0x2d, 0x95, 0x47, 0xf4, 0xd3, 0x85, 0xf0, 0x00, 0x83, + 0xd2, 0x77, 0xa7, 0x3f, 0xff, 0x07, 0x3f, 0x2f, 0xfc, 0xd9, 0xe3, 0x4d, 0x91, 0x0b, 0xe1, 0x05, + 0x1c, 0x00, 0x63, 0x9f, 0x08, 0xa2, 0x8e, 0x00, 0x04, 0x63, 0x87, 0x0d, 0xc2, 0x00, 0x04, 0x14, + 0xe3, 0x68, 0x70, 0x9f, 0xa2, 0x26, 0x45, 0x83, 0xa0, 0x78, 0x6f, 0x86, 0xdd, 0x00, 0x62, 0x7c, + 0x55, 0x58, 0xa5, 0x3d, 0x8b, 0x65, 0x79, 0xfd, 0xbc, 0x30, 0xa0, 0x03, 0x28, 0xcc, 0x57, 0x62, + 0x88, 0xb7, 0xff, 0xfe, 0xaf, 0x76, 0xfa, 0x7a, 0x69, 0xd3, 0x4c, 0x91, 0x11, 0xd0, 0x3f, 0x50, + 0xc6, 0x00, 0xd0, 0x38, 0x88, 0x88, 0xa0, 0xf8, 0x49, 0xc4, 0xcd, 0x4b, 0x6a, 0x25, 0xee, 0xf3, + 0x7b, 0x6b, 0xf9, 0xdf, 0x58, 0x80, 0xcc, 0x26, 0xe0, 0x97, 0x76, 0xe8, 0xb9, 0xff, 0xb7, 0xb7, + 0x85, 0xb0, 0x46, 0x12, 0x1d, 0x97, 0xff, 0xea, 0xf0, 0xd6, 0x00, 0x9b, 0x9a, 0x49, 0x8c, 0xfa, + 0xd7, 0xad, 0x7f, 0xb0, 0x9b, 0x28, 0x03, 0x0d, 0xf7, 0xdd, 0x7b, 0xfd, 0xef, 0xf8, 0x56, 0x50, + 0x9a, 0x73, 0xae, 0x9f, 0xff, 0xc4, 0xa3, 0x02, 0xc0, 0xd8, 0x9c, 0x3d, 0x80, 0x15, 0x86, 0xec, + 0x88, 0x71, 0x78, 0xe7, 0xcf, 0xe2, 0xbc, 0x55, 0x8a, 0x2d, 0xcf, 0xc1, 0xdf, 0x8e, 0xfc, 0x1a, + 0x70, 0x59, 0xe9, 0x93, 0xed, 0xf0, 0x62, 0x03, 0x64, 0x29, 0x2a, 0x20, 0xd6, 0x47, 0x4f, 0xca, + 0x8f, 0xfc, 0x1e, 0xf9, 0xe0, 0xf9, 0x2d, 0x97, 0x62, 0x07, 0x85, 0x05, 0x4b, 0x06, 0x30, 0x00, + 0x0c, 0xc6, 0x80, 0x70, 0xba, 0x80, 0xc2, 0xc2, 0xce, 0x42, 0x2f, 0xf5, 0x2b, 0xcd, 0x56, 0x55, + 0x1d, 0x66, 0xfd, 0x7e, 0x99, 0x43, 0x04, 0x80, 0x48, 0x7a, 0x7f, 0x69, 0x40, 0x8f, 0x3e, 0xe5, + 0xe9, 0x9f, 0xdd, 0xa2, 0x2d, 0x17, 0xf2, 0x14, 0x33, 0xd5, 0x12, 0xa9, 0x04, 0x8c, 0x18, 0xfc, + 0x3d, 0x80, 0x14, 0x7e, 0x58, 0x38, 0x11, 0xea, 0xa5, 0x8f, 0x63, 0x64, 0xec, 0xb6, 0x37, 0xae, + 0x6c, 0xde, 0x98, 0xee, 0xf7, 0xeb, 0x0d, 0x12, 0x22, 0x3e, 0x26, 0x75, 0x7e, 0xdb, 0x77, 0xff, + 0x7c, 0x38, 0x48, 0x01, 0x6b, 0x5d, 0xe3, 0x12, 0x09, 0x24, 0x19, 0x1b, 0xe3, 0xf8, 0x5f, 0xc7, + 0xe3, 0xab, 0x9f, 0xbc, 0x4b, 0xcf, 0x7d, 0x76, 0xa0, 0x86, 0x0b, 0xfe, 0xdf, 0x0b, 0xe0, 0x04, + 0xfc, 0x3e, 0x5b, 0x4d, 0x87, 0xe1, 0x2d, 0x31, 0xee, 0x27, 0xdb, 0xf1, 0xd5, 0xcf, 0xf6, 0x24, + 0x51, 0x70, 0xde, 0x3a, 0xbb, 0x66, 0x45, 0x50, 0xc6, 0x00, 0x6a, 0x7b, 0xc1, 0x43, 0xcd, 0xbd, + 0x3f, 0xfa, 0x69, 0x99, 0x15, 0x43, 0x44, 0x38, 0x0e, 0xc3, 0x78, 0x0b, 0xff, 0xdb, 0xf1, 0xf0, + 0xa2, 0x81, 0xe8, 0x7d, 0xfd, 0x3f, 0xf8, 0x79, 0x08, 0x00, 0x0c, 0x74, 0xdb, 0xe4, 0x4d, 0xaf, + 0x7f, 0xfc, 0xfc, 0x7e, 0x42, 0xab, 0x91, 0xcf, 0xf6, 0xe1, 0xe7, 0x00, 0x0a, 0xd6, 0x8c, 0x18, + 0x8e, 0x95, 0xd0, 0x9d, 0xf7, 0xfe, 0x5a, 0x83, 0xbf, 0x2d, 0xbf, 0x8e, 0xbf, 0x35, 0x8e, 0x2f, + 0xaf, 0x92, 0xb2, 0xd6, 0xaa, 0x4e, 0x8b, 0x0f, 0x7f, 0x12, 0xfc, 0x64, 0x26, 0x4c, 0xec, 0x63, + 0xfb, 0x11, 0x9b, 0xc7, 0x49, 0xbe, 0x1b, 0x63, 0x80, 0x06, 0xcd, 0xa4, 0x11, 0x55, 0x8c, 0x29, + 0xea, 0xf7, 0xf2, 0x7f, 0x8c, 0x61, 0x61, 0x7d, 0xfe, 0xca, 0x1e, 0x50, 0x01, 0xdf, 0xc8, 0x08, + 0x5a, 0x9c, 0x1a, 0x3c, 0x27, 0xd5, 0xe9, 0x27, 0xfb, 0x7a, 0x96, 0xc7, 0x50, 0x49, 0xfe, 0xae, + 0xea, 0xf4, 0x6c, 0xe5, 0xd3, 0xc0, 0xc4, 0xdf, 0x85, 0x68, 0x3c, 0x36, 0xe0, 0x01, 0x87, 0xdd, + 0xf7, 0x7f, 0xef, 0xfb, 0xc9, 0x01, 0xef, 0xd7, 0xfa, 0xfc, 0x11, 0x61, 0x60, 0x05, 0x6b, 0x54, + 0x12, 0x00, 0x28, 0x70, 0xe1, 0xe7, 0x00, 0x2c, 0xc8, 0xc7, 0x76, 0x7b, 0xe0, 0x48, 0xff, 0xdf, + 0x19, 0xef, 0x75, 0x07, 0x3f, 0x1e, 0xbe, 0xce, 0x28, 0xc5, 0x38, 0xc9, 0x41, 0xdb, 0xe0, 0xf3, + 0xf7, 0x07, 0xc1, 0x2d, 0x23, 0x37, 0xba, 0x33, 0x7a, 0x70, 0xee, 0x00, 0x17, 0xb6, 0xe4, 0xc6, + 0x8c, 0xf1, 0x81, 0x5f, 0xfe, 0x74, 0xc1, 0xd5, 0xf6, 0x7d, 0xe5, 0xeb, 0x27, 0xa3, 0x9e, 0x80, + 0xc3, 0x6b, 0x6d, 0xa7, 0xfc, 0x18, 0x42, 0x91, 0x20, 0x00, 0x57, 0x02, 0xe0, 0x00, 0xa8, 0x90, + 0x00, 0x27, 0xca, 0xa6, 0xa3, 0x88, 0xf0, 0x0e, 0x28, 0x0d, 0x71, 0xe3, 0xc0, 0xe9, 0x86, 0xb9, + 0x28, 0x2a, 0x8e, 0x30, 0x7b, 0xe7, 0x00, 0x01, 0x56, 0x16, 0x28, 0xc0, 0x5f, 0x70, 0x1d, 0xc0, + 0x18, 0x8c, 0x10, 0xe9, 0x20, 0x0b, 0xdc, 0xce, 0xc5, 0x94, 0x77, 0x43, 0x77, 0xcf, 0xa4, 0x9f, + 0xf1, 0x36, 0x9a, 0x77, 0xc0, 0xff, 0xac, 0x75, 0x77, 0xf3, 0x77, 0x56, 0x31, 0x0e, 0x86, 0x36, + 0x74, 0x91, 0x7c, 0x3b, 0x80, 0x0e, 0x4c, 0x28, 0x5f, 0x8b, 0x12, 0x9c, 0xfc, 0xff, 0x75, 0x49, + 0x53, 0x72, 0x51, 0xec, 0x99, 0xe1, 0xd2, 0xf8, 0x7d, 0x71, 0x3f, 0x84, 0x52, 0x17, 0x6d, 0xbf, + 0x75, 0x86, 0x70, 0x03, 0x03, 0x2a, 0x93, 0x1f, 0x56, 0xb6, 0xe9, 0x97, 0xcf, 0xed, 0x8a, 0xec, + 0x36, 0x8a, 0x01, 0x11, 0xbd, 0x19, 0xd7, 0x9f, 0x7b, 0xff, 0xdf, 0x5a, 0xfc, 0x3b, 0x20, 0x01, + 0x7f, 0x96, 0x83, 0x44, 0x3b, 0xea, 0xb6, 0x2a, 0xf0, 0x76, 0xed, 0xa6, 0x0f, 0xfd, 0xb1, 0xf7, + 0xf8, 0xed, 0x4f, 0xfc, 0x3a, 0x48, 0x00, 0xee, 0x32, 0x67, 0x54, 0x1a, 0x65, 0xee, 0xe8, 0x56, + 0xc9, 0xc1, 0xf7, 0x27, 0xdb, 0xfe, 0xfa, 0x60, 0xe3, 0xb8, 0x8d, 0x72, 0xfe, 0xeb, 0xf8, 0x78, + 0x90, 0x02, 0xd6, 0x3f, 0xb4, 0x8c, 0xd4, 0xf9, 0xbb, 0x6b, 0xea, 0xa2, 0xdf, 0x79, 0xef, 0x7f, + 0xc3, 0x4a, 0x00, 0x5d, 0x67, 0x29, 0x38, 0x11, 0x79, 0x76, 0xff, 0xbf, 0x77, 0x77, 0x3d, 0x86, + 0x09, 0x00, 0x96, 0xb7, 0x71, 0xfb, 0xf6, 0xfd, 0x6f, 0xc5, 0x86, 0x99, 0x40, 0x08, 0xfe, 0xae, + 0x4d, 0xd7, 0xa7, 0xd6, 0x9f, 0xcd, 0x61, 0x77, 0x13, 0x47, 0xff, 0xdb, 0xf8, 0xd8, 0x6d, 0xc0, + 0x18, 0xfd, 0xa7, 0x5f, 0xfd, 0x9f, 0xbf, 0xde, 0xf1, 0xf9, 0xdf, 0xf0, 0xd2, 0x80, 0x4c, 0xf4, + 0x25, 0x5f, 0xf5, 0x7e, 0x9f, 0xfd, 0xcc, 0x34, 0x88, 0x00, 0x49, 0xd7, 0x66, 0x75, 0x77, 0x76, + 0xfe, 0xf7, 0xf4, 0x4c, 0xe1, 0xc5, 0x00, 0x9c, 0x3e, 0x23, 0x08, 0x9f, 0xce, 0x7e, 0x99, 0x29, + 0x4f, 0xfd, 0xfe, 0x9a, 0x7c, 0x3c, 0x48, 0x02, 0xfb, 0x1a, 0xa5, 0x90, 0x84, 0x18, 0xb7, 0xbd, + 0x9f, 0xdd, 0x48, 0xce, 0xf4, 0xf1, 0x93, 0x6a, 0xa2, 0x1a, 0xcf, 0x40, 0x6a, 0xb9, 0x9c, 0xb8, + 0xfd, 0x36, 0xd9, 0xe0, 0xc4, 0x04, 0x48, 0x52, 0x4c, 0x52, 0xc1, 0x9f, 0xaa, 0xea, 0x1f, 0x03, + 0x53, 0x80, 0x1c, 0x27, 0x00, 0x02, 0x2a, 0x4e, 0x2a, 0x24, 0x1f, 0xf1, 0xa0, 0x03, 0x00, 0x71, + 0x6c, 0x3e, 0x28, 0x63, 0xb1, 0xf8, 0xcf, 0xd8, 0x86, 0x10, 0x60, 0xe1, 0xb8, 0xe0, 0x0c, 0x51, + 0xd4, 0xf1, 0xdc, 0x00, 0x04, 0x00, 0xbf, 0x6f, 0x8f, 0x62, 0x73, 0x19, 0x6c, 0x0b, 0x58, 0x9f, + 0x92, 0xf1, 0x76, 0xc1, 0x5b, 0x09, 0x5c, 0x4f, 0x8c, 0x00, 0x14, 0x34, 0x2a, 0x9f, 0xf0, 0xbb, + 0x80, 0x57, 0xfc, 0x4b, 0x14, 0x4e, 0x89, 0x55, 0x58, 0x96, 0x0a, 0xf8, 0x12, 0x07, 0x9a, 0x03, + 0xed, 0xf8, 0xb0, 0x39, 0x7c, 0x0b, 0x15, 0xf8, 0x04, 0xb3, 0x28, 0x5d, 0xc0, 0x98, 0x64, 0x4d, + 0x76, 0xeb, 0xf6, 0xb7, 0x57, 0x57, 0x35, 0x86, 0xdc, 0x00, 0x7f, 0x48, 0x75, 0x14, 0xc1, 0x51, + 0x3f, 0x5e, 0x21, 0xed, 0x9b, 0xdc, 0xad, 0x8b, 0xb8, 0x3f, 0xf0, 0xdb, 0xdb, 0xc1, 0x4c, 0x13, + 0xaf, 0x7d, 0x38, 0x7b, 0x00, 0x0c, 0x3d, 0x01, 0xf4, 0xa9, 0x08, 0x02, 0x91, 0xff, 0xfb, 0x56, + 0xe2, 0xb8, 0xac, 0x1d, 0xf8, 0xed, 0xdb, 0xf1, 0x56, 0xd8, 0xab, 0x14, 0x58, 0x96, 0x83, 0x75, + 0xe9, 0xed, 0xb7, 0x0a, 0x28, 0x01, 0xbd, 0x17, 0xbc, 0x85, 0x76, 0xfd, 0xe8, 0xcf, 0xe9, 0xf4, + 0xc9, 0xe1, 0xcc, 0x01, 0x56, 0x70, 0xab, 0xc6, 0xff, 0xf4, 0xd3, 0xf2, 0xe9, 0xa7, 0xb6, 0xdc, + 0x38, 0x48, 0x00, 0xd6, 0xad, 0x85, 0xc2, 0xa5, 0x07, 0xbe, 0x5f, 0xee, 0x2a, 0xc5, 0xb0, 0x73, + 0xf0, 0x71, 0xf8, 0xab, 0x1c, 0xfc, 0xbb, 0x01, 0x1d, 0xe9, 0xfc, 0x3c, 0xa0, 0x01, 0xb3, 0x4c, + 0x48, 0xc5, 0x55, 0x23, 0x0f, 0xbd, 0xbb, 0x72, 0xf6, 0xe5, 0xc9, 0xd3, 0xd9, 0xce, 0xf2, 0x73, + 0x8f, 0x5d, 0xb3, 0xfe, 0xb0, 0xf6, 0x00, 0x93, 0x0a, 0x17, 0x59, 0xc0, 0x6c, 0x58, 0xb1, 0x56, + 0x5e, 0x5d, 0xbb, 0xb3, 0x9d, 0xf2, 0xce, 0x5d, 0xcc, 0xbb, 0xa6, 0x0f, 0xf8, 0xd4, 0x8a, 0xab, + 0xd6, 0x6f, 0xa7, 0xc0, 0x92, 0x01, 0x99, 0x0a, 0x43, 0xed, 0x47, 0xf8, 0x4c, 0xa9, 0x3a, 0xad, + 0xcc, 0x77, 0xd1, 0x3c, 0xf1, 0x03, 0x87, 0xe2, 0x7c, 0xb0, 0xf1, 0x27, 0x8c, 0x00, 0x03, 0xf1, + 0xc0, 0x00, 0xb6, 0x1a, 0x50, 0x03, 0x2b, 0x68, 0xb6, 0x0d, 0xf7, 0xf5, 0x15, 0x1c, 0x9b, 0x8f, + 0x9a, 0x5b, 0x43, 0x9e, 0xa8, 0xab, 0x17, 0xe5, 0xb6, 0xdb, 0xdb, 0xf6, 0xc3, 0x6e, 0x01, 0x3e, + 0xa2, 0x33, 0x48, 0x8f, 0x12, 0xa9, 0x4f, 0x01, 0x2f, 0x39, 0x83, 0xf9, 0x61, 0xc2, 0x18, 0xe4, + 0x52, 0xd8, 0x26, 0xa7, 0x11, 0x8e, 0xda, 0x76, 0xfe, 0x1e, 0xc0, 0x0c, 0x8b, 0x59, 0x31, 0x1a, + 0x7f, 0xcf, 0xea, 0xaa, 0xa9, 0xa7, 0xf1, 0x1d, 0x11, 0x5f, 0xf8, 0x5c, 0x90, 0x00, 0xd2, 0xc8, + 0x70, 0xf0, 0xd0, 0x71, 0x7c, 0xbf, 0x26, 0xf7, 0x7b, 0x9f, 0xde, 0xe2, 0x5e, 0xfe, 0x5b, 0xfb, + 0xe1, 0x48, 0x1d, 0xc3, 0x5a, 0xac, 0x5c, 0x53, 0x11, 0xe2, 0x86, 0x5d, 0xae, 0x52, 0xc3, 0x3f, + 0x01, 0xa1, 0xcb, 0x40, 0x1f, 0x12, 0x8c, 0xcf, 0x8b, 0x80, 0xf0, 0x78, 0x07, 0x83, 0x80, 0x01, + 0x78, 0xe0, 0x07, 0x0c, 0xe0, 0x05, 0xb4, 0xe6, 0xe0, 0xb6, 0x28, 0x49, 0xbf, 0xf2, 0x8d, 0x09, + 0xfc, 0xfa, 0x96, 0x6e, 0xf5, 0xef, 0x89, 0x30, 0x07, 0xbe, 0x4b, 0xe0, 0xeb, 0xea, 0xf7, 0xe7, + 0xff, 0x98, 0x61, 0x40, 0x01, 0xee, 0x09, 0x0a, 0xce, 0x53, 0x10, 0x52, 0x4b, 0xaf, 0x5b, 0xb6, + 0x2a, 0xc1, 0x61, 0x43, 0x0a, 0x8f, 0x3e, 0x3a, 0x4f, 0x1c, 0x69, 0x92, 0x03, 0x8d, 0x4e, 0x23, + 0xbb, 0x0a, 0x28, 0x04, 0xf7, 0x50, 0x08, 0x2e, 0x1a, 0xa6, 0x8c, 0x5b, 0x2a, 0xa2, 0x0b, 0x74, + 0x4f, 0x44, 0xf5, 0xba, 0x73, 0xbb, 0x7d, 0x75, 0xf0, 0xa2, 0x80, 0x0c, 0x76, 0x9c, 0x63, 0x45, + 0x21, 0xfb, 0x61, 0x18, 0xc8, 0x87, 0x44, 0x3a, 0xbc, 0xd0, 0xa7, 0xbe, 0x38, 0xf8, 0x61, 0x40, + 0x01, 0xb6, 0x68, 0xc4, 0xb1, 0x60, 0xb4, 0x43, 0x4e, 0x6c, 0x55, 0x97, 0x60, 0xe7, 0xe4, 0xec, + 0x87, 0xb8, 0x59, 0x65, 0x85, 0xa7, 0x1e, 0x9a, 0x7e, 0x48, 0xb8, 0x0b, 0x80, 0x42, 0x52, 0x71, + 0x5f, 0x8e, 0x00, 0x0c, 0x70, 0x0f, 0xc1, 0x27, 0x1e, 0x53, 0xc3, 0x83, 0x80, 0x03, 0x18, 0x15, + 0x0e, 0x48, 0x00, 0x86, 0xed, 0x34, 0xfe, 0xbf, 0x4f, 0x14, 0xb1, 0x4b, 0x2e, 0x96, 0x2e, 0x34, + 0xc4, 0x83, 0xa7, 0x83, 0xb1, 0x97, 0x69, 0x57, 0xe9, 0xa7, 0x0d, 0xb8, 0x00, 0x6d, 0x61, 0xe3, + 0x2a, 0x3d, 0x0d, 0x87, 0xfb, 0xd8, 0xb6, 0x9f, 0x8b, 0x0c, 0x38, 0xd9, 0xc9, 0x7c, 0x0d, 0x3f, + 0x29, 0xe6, 0x73, 0x20, 0xb5, 0x18, 0xa7, 0xf4, 0xf0, 0xbb, 0x3b, 0xff, 0xf1, 0xb9, 0xfb, 0xf6, + 0xc6, 0x21, 0x74, 0xea, 0x1b, 0x61, 0x00, 0x00, 0x49, 0xea, 0xb6, 0xdd, 0x2c, 0x4f, 0xe6, 0x81, + 0x6c, 0x4e, 0x05, 0x8f, 0xc4, 0x98, 0x16, 0x30, 0x96, 0x94, 0x5c, 0x43, 0xee, 0x23, 0x7e, 0xca, + 0xca, 0x1b, 0xc0, 0x02, 0xfe, 0x30, 0xf6, 0x21, 0x79, 0x03, 0xd1, 0x13, 0xe1, 0xc5, 0x22, 0x1f, + 0xda, 0x17, 0x41, 0x83, 0xab, 0xf6, 0x4b, 0x16, 0x51, 0x2c, 0x49, 0x0e, 0x07, 0x91, 0x19, 0x69, + 0xa7, 0xb7, 0x86, 0xf0, 0x25, 0xac, 0x59, 0x15, 0x69, 0x39, 0x03, 0x92, 0xfc, 0x3f, 0xcb, 0xdb, + 0x90, 0x0e, 0x8f, 0x87, 0x9e, 0x00, 0x78, 0x3b, 0x43, 0xf1, 0x60, 0x65, 0x7f, 0x72, 0x84, 0xfb, + 0x32, 0x0f, 0x1d, 0xef, 0x17, 0x9b, 0xb7, 0x1b, 0x16, 0x17, 0xe4, 0x58, 0x37, 0x50, 0xdc, 0x50, + 0x01, 0xec, 0x61, 0x74, 0x96, 0x07, 0xcf, 0xec, 0x8b, 0x73, 0x7b, 0x49, 0x8b, 0x7a, 0x69, 0x83, + 0x06, 0xe3, 0xc1, 0xd1, 0x70, 0xc1, 0x8e, 0x01, 0xdf, 0x81, 0x96, 0x44, 0xcb, 0x4e, 0xb6, 0xc5, + 0x5c, 0x3a, 0xa0, 0x01, 0xcf, 0x42, 0xc0, 0x97, 0x2a, 0x82, 0xe3, 0x7f, 0xdf, 0x0b, 0xd6, 0x4e, + 0xee, 0xe9, 0x7f, 0x57, 0x67, 0x8e, 0x9e, 0xd9, 0x40, 0x31, 0x45, 0x0d, 0x40, 0x75, 0x4a, 0x1d, + 0x5a, 0xd8, 0x46, 0xb0, 0x15, 0xc0, 0xe8, 0x6d, 0x53, 0x6d, 0xbc, 0xda, 0x6d, 0x87, 0x5c, 0x0d, + 0x6c, 0xcb, 0x21, 0xfc, 0x17, 0x48, 0xc6, 0xf8, 0x5b, 0xf5, 0xda, 0x16, 0xca, 0x2b, 0x94, 0x73, + 0x37, 0xc3, 0x8d, 0xeb, 0x5a, 0xb1, 0xed, 0x41, 0xff, 0x3b, 0xf9, 0x27, 0x12, 0xd0, 0xd0, 0x53, + 0xd9, 0x92, 0x8d, 0xce, 0xf4, 0xe1, 0xc2, 0x40, 0x22, 0xe0, 0x42, 0xd6, 0x31, 0x1d, 0xee, 0xef, + 0x72, 0xf5, 0x3c, 0xf2, 0x6f, 0xcb, 0xb1, 0xdb, 0x96, 0x2e, 0x3c, 0xb7, 0xb6, 0x6e, 0x37, 0xd5, + 0xbe, 0x80, 0xbc, 0x81, 0xb6, 0xe9, 0xf8, 0x71, 0xc0, 0x04, 0x45, 0xe2, 0x52, 0x0a, 0xd9, 0xca, + 0xff, 0xbb, 0xa7, 0x2d, 0x9c, 0x68, 0x9c, 0x67, 0xbf, 0x18, 0xdf, 0x05, 0xbc, 0x59, 0x63, 0x82, + 0x9c, 0xa0, 0xd8, 0x01, 0x90, 0x1a, 0xa9, 0xdb, 0x5d, 0x9c, 0x35, 0x80, 0x0f, 0xf4, 0xd9, 0xc2, + 0x92, 0xfa, 0xfd, 0xd7, 0xd5, 0x1a, 0xea, 0x15, 0x78, 0xb5, 0x93, 0x3c, 0xde, 0x0c, 0xe8, 0xee, + 0x1b, 0x70, 0x02, 0x8f, 0xb2, 0x12, 0xa9, 0x2e, 0xee, 0xd7, 0xf8, 0x3b, 0x75, 0x1c, 0xaf, 0x3f, + 0xab, 0xfd, 0x70, 0xe2, 0x80, 0x3b, 0xc9, 0x65, 0xd8, 0x4d, 0x3d, 0x32, 0x7f, 0xfc, 0x17, 0xad, + 0xb7, 0x34, 0x7e, 0x1b, 0xc0, 0x08, 0x53, 0xe4, 0x8c, 0xc4, 0x7a, 0x9f, 0xdf, 0x6d, 0xb3, 0xfa, + 0xee, 0x29, 0xbd, 0x7e, 0x1d, 0xc0, 0x0c, 0xe3, 0xaf, 0x6d, 0x3e, 0xa7, 0xff, 0xfa, 0xa7, 0x54, + 0xf9, 0x35, 0x3f, 0xf0, 0xe2, 0x82, 0x75, 0xeb, 0x38, 0xfb, 0xff, 0xe3, 0xf1, 0xeb, 0xf0, 0xc6, + 0x00, 0x71, 0xa4, 0xde, 0xc7, 0xa4, 0xfe, 0xff, 0xf7, 0x61, 0x79, 0x41, 0x02, 0x8f, 0xe2, 0xd7, + 0xff, 0xe4, 0x4c, 0x3b, 0x80, 0x22, 0xaf, 0x26, 0x53, 0xfe, 0x3f, 0xfd, 0xc1, 0xdb, 0x9e, 0x85, + 0xd9, 0xdf, 0x6f, 0xfc, 0x33, 0x20, 0x04, 0x08, 0xd6, 0xd2, 0x25, 0xb5, 0xb9, 0x7b, 0x6b, 0x8b, + 0xb7, 0x97, 0xeb, 0x91, 0xf8, 0x63, 0x00, 0x1c, 0xeb, 0xa6, 0xc6, 0xc1, 0xff, 0xed, 0xfc, 0x97, + 0x0c, 0x90, 0xe0, 0x9d, 0xca, 0x6e, 0x4d, 0xff, 0xff, 0xac, 0x76, 0x33, 0x72, 0xb0, 0xe4, 0xc0, + 0x08, 0x13, 0x23, 0x68, 0x88, 0xda, 0x9a, 0x0f, 0x7f, 0x1e, 0xbf, 0xff, 0xaf, 0x97, 0xb3, 0xf0, + 0xf6, 0x00, 0x8c, 0x27, 0x89, 0x23, 0x38, 0x25, 0x1b, 0xfe, 0xe6, 0xf2, 0xcb, 0xa8, 0xb7, 0x15, + 0xd5, 0x55, 0x4b, 0xc5, 0x2e, 0x7c, 0xbf, 0x4d, 0xe5, 0xf0, 0xbb, 0x80, 0x22, 0x9b, 0x48, 0xf8, + 0xf7, 0xf8, 0x87, 0xc4, 0xbf, 0xfd, 0x8e, 0x43, 0xf1, 0x1f, 0x88, 0x5c, 0x37, 0x1c, 0x00, 0x52, + 0x93, 0x06, 0xc4, 0x39, 0xc4, 0xdf, 0x2d, 0xfc, 0xbc, 0xbd, 0x36, 0xf8, 0xe2, 0xb7, 0x15, 0xce, + 0xeb, 0xdf, 0x0e, 0x28, 0x02, 0x52, 0xdd, 0x35, 0x06, 0xe4, 0xe8, 0x96, 0xbf, 0xe1, 0x55, 0xa2, + 0x42, 0x07, 0xcf, 0x88, 0x7c, 0xf5, 0x39, 0x88, 0xef, 0xce, 0x18, 0x8e, 0xfd, 0x30, 0x7d, 0x6c, + 0x14, 0x82, 0xcc, 0x77, 0x9b, 0x61, 0x67, 0x0c, 0x2c, 0x65, 0x0e, 0xdd, 0x3f, 0xe1, 0xec, 0x00, + 0xcb, 0x2a, 0x71, 0x72, 0x00, 0x42, 0xfd, 0xf5, 0x79, 0x2d, 0x09, 0xe3, 0x2f, 0x4c, 0x47, 0x96, + 0xd9, 0xdf, 0x01, 0x4e, 0x80, 0xfa, 0x97, 0x37, 0xa7, 0xdb, 0x86, 0xdc, 0x00, 0x0e, 0xf7, 0x89, + 0x75, 0x7b, 0x9b, 0xf6, 0xfd, 0xc5, 0x59, 0xbd, 0xdc, 0x1d, 0xbb, 0xbe, 0x2d, 0xa0, 0xea, 0xe9, + 0xae, 0xdb, 0xc2, 0xee, 0x00, 0x3f, 0x70, 0xfa, 0x90, 0x7e, 0x4a, 0xd4, 0xff, 0x26, 0x21, 0xe2, + 0xad, 0xfe, 0xed, 0xe1, 0x47, 0x9b, 0x77, 0x07, 0xff, 0x77, 0x27, 0x1e, 0x44, 0xf8, 0x14, 0x3c, + 0x3a, 0xa0, 0x02, 0xbc, 0x0a, 0xae, 0x51, 0x42, 0x35, 0xbd, 0x7a, 0xdd, 0xdb, 0xac, 0x9e, 0x38, + 0xc1, 0xf7, 0x3b, 0xd9, 0xcb, 0xb1, 0x6e, 0x32, 0xfc, 0x8e, 0x3d, 0xb6, 0xd7, 0xc3, 0x18, 0x01, + 0x10, 0x76, 0x4c, 0xc1, 0x82, 0x34, 0xfb, 0xb9, 0x5b, 0xe4, 0xe4, 0xec, 0xa1, 0xf9, 0xbd, 0xcb, + 0xbb, 0xf9, 0xff, 0x8a, 0xd6, 0x21, 0xc5, 0x01, 0x1c, 0x01, 0x5c, 0xca, 0x63, 0x81, 0x57, 0x77, + 0xa7, 0x95, 0x2f, 0x1f, 0xf8, 0xc7, 0xfe, 0x5b, 0xb6, 0xdd, 0x6d, 0x8a, 0xb1, 0xf1, 0xc7, 0x37, + 0xfe, 0x1c, 0xc0, 0x23, 0x25, 0x02, 0x55, 0x82, 0xd2, 0x3e, 0xee, 0xac, 0x55, 0xdb, 0x8e, 0xdc, + 0x75, 0x76, 0xc4, 0x71, 0x5e, 0x9b, 0xa8, 0xff, 0x8f, 0xbc, 0x63, 0xee, 0x2a, 0x26, 0xbe, 0xdf, + 0x4e, 0x1e, 0x24, 0x0f, 0xc4, 0x2a, 0xeb, 0x72, 0x77, 0x6e, 0x5c, 0x55, 0x8e, 0xfd, 0xf6, 0x78, + 0xe6, 0x5f, 0x2f, 0x10, 0xf1, 0x4d, 0x4e, 0x3f, 0xe1, 0xe2, 0x40, 0x0f, 0xb3, 0x19, 0x0d, 0xe3, + 0x1e, 0x80, 0x94, 0xf9, 0x5d, 0x93, 0x97, 0x6d, 0xe0, 0xff, 0xc5, 0xf2, 0x6e, 0x0f, 0xf8, 0x39, + 0xfc, 0x9e, 0x6a, 0x2b, 0x59, 0xed, 0xfc, 0x36, 0xa0, 0x00, 0xf6, 0xc5, 0x19, 0x2f, 0xac, 0x51, + 0x37, 0xbf, 0xce, 0xdb, 0xb8, 0x3b, 0x73, 0x52, 0x39, 0x6f, 0xb1, 0xc9, 0xf1, 0xff, 0x4c, 0x9f, + 0x07, 0x7e, 0x25, 0xa1, 0x77, 0xa7, 0x7e, 0x1b, 0x70, 0x0b, 0x14, 0x49, 0x26, 0x31, 0x61, 0xcf, + 0xee, 0x34, 0xb1, 0x4c, 0x28, 0xfc, 0xa0, 0x3c, 0xc3, 0xff, 0x4c, 0x9c, 0x7d, 0xcb, 0xbe, 0x21, + 0x6b, 0x33, 0x6a, 0x7f, 0xc3, 0xae, 0x00, 0x17, 0x86, 0xda, 0xf5, 0x17, 0x18, 0xba, 0xb7, 0x3f, + 0xe2, 0xd4, 0x18, 0x0d, 0x53, 0xdb, 0x1f, 0x73, 0xc6, 0xaa, 0xda, 0x12, 0x9a, 0x33, 0xc6, 0xaa, + 0x56, 0xe8, 0x2a, 0x89, 0x63, 0x78, 0xdc, 0xfc, 0xa9, 0xf6, 0xfc, 0x30, 0xe0, 0x00, 0xef, 0x86, + 0x8e, 0x09, 0x12, 0x85, 0xbc, 0x11, 0x52, 0x7f, 0xf2, 0x62, 0xdc, 0x69, 0x82, 0xc7, 0x19, 0x40, + 0x35, 0x63, 0x2e, 0xd6, 0x71, 0x76, 0x58, 0x8b, 0xb3, 0x8b, 0x62, 0xd9, 0x76, 0x2d, 0x8e, 0x7e, + 0x1d, 0xc0, 0x05, 0x22, 0x24, 0x84, 0xab, 0x46, 0xf5, 0x17, 0x84, 0x9f, 0xf5, 0x8f, 0xfa, 0x21, + 0x1e, 0xa7, 0x35, 0x1d, 0xbe, 0x73, 0xee, 0x3d, 0xf6, 0x54, 0xe7, 0xe2, 0xf0, 0x81, 0x4f, 0xf8, + 0x75, 0xc0, 0x0d, 0x8f, 0xf9, 0x1f, 0x20, 0xf9, 0x4f, 0x7f, 0xfc, 0xb7, 0x9b, 0xdd, 0xdb, 0xec, + 0xfc, 0x1b, 0xdb, 0xd7, 0x62, 0x12, 0xdc, 0x12, 0x9c, 0x69, 0xf0, 0x44, 0x17, 0x9b, 0xfe, 0x13, + 0x70, 0x01, 0xf5, 0xbd, 0xa6, 0x23, 0x29, 0x6e, 0x08, 0x9e, 0x27, 0xee, 0x81, 0xb5, 0xa6, 0x34, + 0x1d, 0x00, 0xa0, 0x65, 0x4d, 0xcb, 0xe3, 0x74, 0x09, 0x01, 0xc1, 0xf8, 0x12, 0x38, 0xc1, 0xc0, + 0x0b, 0x80, 0x46, 0x27, 0x9a, 0x2d, 0x2c, 0x70, 0x00, 0x27, 0x1c, 0x00, 0xe3, 0x58, 0xbb, 0x78, + 0x39, 0x04, 0x83, 0x8d, 0xe5, 0xd1, 0x1e, 0x38, 0x00, 0x31, 0xc0, 0xe2, 0xe3, 0xe9, 0x9c, 0x3c, + 0xc2, 0x40, 0x03, 0x2f, 0x24, 0xcc, 0x64, 0xdd, 0xbc, 0xff, 0xd3, 0x52, 0x7a, 0x8b, 0x60, 0xd2, + 0x96, 0x22, 0x93, 0xf5, 0xc3, 0x44, 0x80, 0x1e, 0x1f, 0x52, 0xf1, 0x1d, 0xa0, 0x77, 0x5f, 0x93, + 0x8f, 0xbe, 0x9e, 0x98, 0xed, 0x87, 0x94, 0x00, 0x21, 0x86, 0x27, 0x0d, 0xea, 0x2d, 0x0e, 0x43, + 0xdd, 0xca, 0x0a, 0x41, 0xbf, 0x6d, 0x1b, 0x17, 0xbc, 0x43, 0xdd, 0xc5, 0x75, 0x9d, 0x8f, 0x3f, + 0x2f, 0xe1, 0xb2, 0x40, 0x2c, 0x85, 0x41, 0x4d, 0x64, 0x0a, 0x54, 0xb8, 0x30, 0xf3, 0xea, 0x89, + 0xf1, 0xf8, 0xe9, 0xa6, 0xce, 0x90, 0x1f, 0x33, 0x96, 0x03, 0xf8, 0x19, 0x61, 0x03, 0xf1, 0xdb, + 0x7f, 0xc3, 0x98, 0x00, 0x77, 0x9a, 0x91, 0x18, 0x75, 0x84, 0x59, 0xfc, 0x2d, 0xef, 0x1c, 0xe6, + 0x73, 0x8f, 0x67, 0x03, 0xec, 0x22, 0x6c, 0x9b, 0x37, 0x86, 0x3e, 0x4c, 0xb4, 0x81, 0x57, 0xe5, + 0xa1, 0xec, 0x00, 0x3d, 0x70, 0x83, 0x2f, 0xff, 0x95, 0x66, 0xdb, 0x7d, 0x80, 0x77, 0x50, 0xc9, + 0x0f, 0xf5, 0xa9, 0xef, 0xdf, 0xbf, 0xdb, 0xb7, 0x35, 0x60, 0x3e, 0x78, 0xcf, 0x29, 0x4a, 0x7f, + 0x8a, 0x00, 0x02, 0xa3, 0x2c, 0x00, 0x09, 0xfe, 0x09, 0x50, 0x61, 0x93, 0xe6, 0xd1, 0xfe, 0x8f, + 0x8f, 0x0e, 0x28, 0x03, 0xfe, 0x18, 0x26, 0x75, 0x5e, 0x90, 0x0b, 0x3e, 0xed, 0x2a, 0xce, 0x53, + 0x28, 0xb6, 0x5d, 0xb3, 0x62, 0x7e, 0x9e, 0xea, 0xc3, 0x20, 0xd5, 0x0b, 0x61, 0x50, 0xaa, 0x2c, + 0x00, 0x2c, 0x1c, 0x00, 0x33, 0x8d, 0xc6, 0x0d, 0xb6, 0xf2, 0xea, 0x69, 0xf0, 0xe6, 0x00, 0x07, + 0x0e, 0x52, 0x0b, 0x93, 0xf0, 0x68, 0xe7, 0xa6, 0xb6, 0xcf, 0xdf, 0x40, 0x6c, 0x7a, 0x0e, 0xdd, + 0x28, 0x00, 0x29, 0x44, 0xdb, 0xf1, 0x5c, 0x66, 0xa4, 0xd3, 0x37, 0xc4, 0x35, 0xd6, 0xfc, 0xbb, + 0x57, 0x6f, 0x0c, 0x00, 0xc0, 0x1b, 0xdd, 0xb9, 0x6d, 0x83, 0xa0, 0xb8, 0xab, 0x1b, 0x85, 0xc9, + 0x78, 0x35, 0x38, 0x18, 0x13, 0x00, 0x01, 0xfd, 0x0a, 0x00, 0xae, 0x16, 0xe4, 0xf0, 0x38, 0x1c, + 0x54, 0xa9, 0x80, 0x07, 0x86, 0x00, 0x80, 0x1d, 0xc0, 0x26, 0xe4, 0xef, 0x6c, 0x1a, 0xfd, 0x3c, + 0x32, 0x14, 0x95, 0x81, 0x64, 0x1c, 0xc4, 0xa5, 0xde, 0x1c, 0x39, 0xa6, 0x96, 0xcb, 0x62, 0x8c, + 0xb0, 0x06, 0x58, 0x0c, 0xb0, 0x01, 0x8a, 0x03, 0x14, 0x18, 0xac, 0x51, 0x81, 0x40, 0x5c, 0x9b, + 0x00, 0xb1, 0x42, 0x40, 0x96, 0x02, 0xa0, 0x08, 0x03, 0x65, 0x80, 0xc9, 0x41, 0xc0, 0x80, 0x18, + 0x01, 0x02, 0x79, 0x98, 0x16, 0xd0, 0x41, 0xcc, 0x5b, 0x79, 0x8a, 0xcc, 0xdc, 0x81, 0x0d, 0xe1, + 0x80, 0x40, 0x3a, 0x1d, 0xd8, 0x68, 0x0c, 0xbd, 0x41, 0x00, 0xd3, 0x8b, 0x43, 0xcb, 0x00, 0x03, + 0xf1, 0x60, 0x00, 0xc1, 0xd9, 0x06, 0x32, 0x40, 0x00, 0x32, 0xa0, 0x6c, 0x00, 0xc3, 0x2a, 0xfc, + 0x95, 0x18, 0xee, 0x1d, 0xc0, 0x10, 0x01, 0xce, 0x58, 0x13, 0xd2, 0x35, 0xc7, 0x35, 0x3c, 0x6a, + 0xea, 0xb3, 0xcc, 0xb3, 0x92, 0xbc, 0xca, 0xd9, 0xfa, 0x8f, 0xf8, 0xed, 0xd7, 0xf1, 0x76, 0x3e, + 0xe1, 0x73, 0x10, 0xed, 0x5f, 0xc3, 0x0e, 0x62, 0xef, 0x4f, 0x87, 0x54, 0x00, 0x3a, 0x76, 0xaf, + 0x86, 0x6e, 0xaf, 0x63, 0xff, 0xe3, 0xf9, 0x7d, 0x65, 0xe4, 0x4b, 0xcf, 0xe3, 0x3b, 0xf9, 0xcd, + 0x1d, 0x47, 0xcc, 0x93, 0x81, 0xf7, 0xf3, 0x1c, 0xaa, 0x50, 0xa8, 0x17, 0xfc, 0x36, 0xa0, 0x01, + 0x6e, 0xb0, 0x91, 0xd4, 0x9d, 0x48, 0x51, 0x52, 0x25, 0xb8, 0xdb, 0xcb, 0x65, 0xe5, 0xb1, 0x38, + 0x36, 0x95, 0xb3, 0x07, 0xdc, 0x1e, 0xfa, 0x4f, 0xad, 0xf0, 0x1a, 0x01, 0xcb, 0x89, 0xc0, 0x43, + 0x87, 0x71, 0x32, 0x7e, 0x1c, 0x24, 0x00, 0x31, 0x94, 0xb3, 0x6c, 0xa2, 0x33, 0xff, 0xf9, 0x7f, + 0x4e, 0x9e, 0x9f, 0x07, 0x7e, 0x2b, 0xc3, 0xfb, 0x2f, 0x89, 0x7f, 0xc3, 0x6e, 0x02, 0x76, 0xda, + 0x0f, 0xd7, 0xbf, 0x71, 0x5b, 0xf8, 0xef, 0xdf, 0xcb, 0xe3, 0xf0, 0x18, 0xfb, 0x8f, 0x2d, 0xbf, + 0x86, 0xf0, 0x06, 0xe5, 0xd7, 0x43, 0xde, 0xff, 0x7b, 0xa9, 0x95, 0xb2, 0x56, 0x5f, 0x0e, 0xa8, + 0x01, 0x9f, 0x3c, 0x85, 0x63, 0xbe, 0xe5, 0x6e, 0x9c, 0xbc, 0xdf, 0x4d, 0x3f, 0x57, 0x53, 0x83, + 0xba, 0xfc, 0x2e, 0xe1, 0x02, 0x3f, 0x78, 0x17, 0x0f, 0x3f, 0xef, 0x75, 0xef, 0x58, 0x5c, 0x90, + 0x25, 0x5a, 0x8d, 0xeb, 0xff, 0x6f, 0xef, 0x8d, 0x47, 0x08, 0xcd, 0x73, 0x65, 0x8d, 0x70, 0xf9, + 0x4d, 0x4f, 0x86, 0x64, 0x00, 0x60, 0x5a, 0xbd, 0x59, 0xfb, 0xfb, 0xfd, 0xef, 0x2c, 0x3c, 0xe0, + 0x05, 0xbd, 0xae, 0xe4, 0x6d, 0x4f, 0xcb, 0xff, 0x7a, 0x66, 0xba, 0x7f, 0x86, 0x5c, 0x05, 0xdd, + 0x09, 0x6a, 0x6d, 0xbf, 0xdb, 0xff, 0x1f, 0x1c, 0xca, 0x13, 0x6b, 0x31, 0xd8, 0xd5, 0x1c, 0x5e, + 0xc2, 0xec, 0xa1, 0xf5, 0x33, 0xfd, 0xbf, 0xe9, 0x70, 0xa4, 0x81, 0x2f, 0x99, 0xcf, 0xdf, 0xff, + 0x87, 0x88, 0x60, 0x0a, 0x82, 0x47, 0xf5, 0x79, 0x9f, 0x40, 0xff, 0x8c, 0xf5, 0x4a, 0xfb, 0x87, + 0xd1, 0xed, 0xb1, 0x37, 0x4b, 0xb4, 0xf7, 0x40, 0x5f, 0x72, 0xfa, 0x62, 0xdc, 0x39, 0x81, 0xc5, + 0xa6, 0x5f, 0xed, 0xb6, 0x9a, 0x6d, 0xb6, 0x9a, 0x66, 0x46, 0x5b, 0x6d, 0xe9, 0xa7, 0x18, 0xa3, + 0x5e, 0xec, 0x2e, 0xe0, 0x0c, 0x3f, 0x99, 0xad, 0xdd, 0xfd, 0xbc, 0xf0, 0xf2, 0x40, 0xf6, 0x07, + 0x18, 0x1e, 0x30, 0x6d, 0x71, 0x72, 0x47, 0x70, 0xbb, 0x80, 0x0d, 0x9c, 0x48, 0x22, 0xbc, 0x18, + 0x3c, 0xdf, 0x3f, 0x26, 0xc8, 0x8c, 0x60, 0xb2, 0x4f, 0x84, 0x6e, 0x8b, 0x39, 0xe5, 0xe1, 0xce, + 0xb4, 0x1c, 0xf0, 0x1c, 0x94, 0x0b, 0x49, 0x9c, 0xb4, 0x8b, 0xc6, 0xd1, 0x54, 0x3a, 0xe0, 0x0f, + 0xa1, 0x4b, 0x0f, 0x46, 0xd5, 0x66, 0x7f, 0xd9, 0xa0, 0x2b, 0x95, 0x58, 0x74, 0x0b, 0xdd, 0x01, + 0xef, 0xc6, 0xde, 0x73, 0xc9, 0x19, 0x7f, 0xcc, 0xdd, 0xbf, 0xc3, 0x78, 0x02, 0xb9, 0xfb, 0x06, + 0x6f, 0xdc, 0x20, 0x87, 0xba, 0x57, 0x85, 0xd8, 0x3d, 0xe7, 0x1f, 0x3d, 0xb7, 0xc4, 0xb3, 0x8a, + 0x1d, 0xef, 0x41, 0x0f, 0x75, 0xd7, 0x0f, 0x38, 0x00, 0x9d, 0x9e, 0x98, 0x13, 0xa4, 0x60, 0x56, + 0xf1, 0x31, 0x6d, 0xb5, 0x11, 0x8b, 0xa2, 0xd8, 0x52, 0x9b, 0xbc, 0xbf, 0xde, 0xe2, 0x8e, 0x6b, + 0xfc, 0x37, 0x80, 0x2e, 0xfc, 0xc7, 0x08, 0xae, 0x70, 0x13, 0xbb, 0xfa, 0x1d, 0x62, 0x5e, 0x7f, + 0xd3, 0x55, 0x2d, 0x97, 0x8a, 0xc5, 0x58, 0xba, 0x83, 0xab, 0x9f, 0xe6, 0x82, 0x1b, 0xef, 0xf0, + 0xc2, 0x80, 0x1a, 0x63, 0x9d, 0x05, 0xc9, 0xef, 0x56, 0xf7, 0xda, 0x7a, 0x69, 0xa3, 0x15, 0x0d, + 0x28, 0x51, 0x1c, 0x85, 0xfb, 0xff, 0xfd, 0x3a, 0x86, 0x94, 0x00, 0xa4, 0x9e, 0x58, 0x4b, 0x0d, + 0xce, 0xa5, 0xf1, 0xb7, 0xbf, 0xcb, 0xee, 0xec, 0x61, 0xdc, 0x00, 0x86, 0xb8, 0xc4, 0xfa, 0xde, + 0xff, 0x6d, 0xdc, 0xb6, 0x99, 0x7d, 0x5d, 0xb8, 0xad, 0xb1, 0x2f, 0xa7, 0x55, 0xef, 0xc3, 0x6e, + 0x00, 0x3b, 0x40, 0x45, 0xf2, 0x76, 0x17, 0xe7, 0xfb, 0xe7, 0x3d, 0x35, 0xae, 0x2a, 0xed, 0x35, + 0xf8, 0x3f, 0xc1, 0xff, 0x8f, 0x0a, 0x3e, 0x2d, 0xdd, 0x7b, 0xc3, 0x64, 0x80, 0x3f, 0x9a, 0x0f, + 0x10, 0x53, 0x6c, 0x82, 0x4f, 0x7b, 0xec, 0xbc, 0xdc, 0x71, 0x3e, 0x25, 0xec, 0xf8, 0x8f, 0x85, + 0x6f, 0xf2, 0x9b, 0x39, 0x3b, 0x38, 0x78, 0xc1, 0xb0, 0x27, 0x87, 0x27, 0xe7, 0xff, 0x0f, 0x12, + 0x02, 0x02, 0x1f, 0x84, 0x39, 0x59, 0xf7, 0x2f, 0xfe, 0x0e, 0xfc, 0x55, 0x9f, 0x9f, 0x96, 0xba, + 0xc1, 0x78, 0x74, 0x3d, 0xbd, 0x34, 0xf8, 0x70, 0x90, 0x08, 0x01, 0x2c, 0x7e, 0xa3, 0x8c, 0xa6, + 0xf6, 0xdf, 0xc6, 0x31, 0xfa, 0xeb, 0xf7, 0xe4, 0x67, 0xf4, 0xfb, 0xc3, 0xb8, 0x01, 0xe1, 0x23, + 0x06, 0xe9, 0x8d, 0x1d, 0xf8, 0x69, 0xcf, 0x85, 0x7e, 0xca, 0x00, 0xb2, 0x01, 0x70, 0xaa, 0x26, + 0x7e, 0xeb, 0x9a, 0x00, 0x29, 0xfc, 0xaf, 0x2a, 0x15, 0x40, 0xb9, 0xe5, 0x81, 0x65, 0xca, 0x0f, + 0xff, 0xf7, 0x47, 0xf8, 0x65, 0x40, 0x09, 0x86, 0xb2, 0x54, 0x1e, 0x52, 0xfa, 0xee, 0xbd, 0xde, + 0x21, 0xe4, 0xe3, 0xad, 0x65, 0xd8, 0x3e, 0xf7, 0x16, 0xc5, 0xb7, 0xc3, 0xb8, 0x0c, 0x30, 0x48, + 0x53, 0x35, 0x13, 0xf8, 0x75, 0x49, 0x8e, 0x9b, 0xd4, 0x6b, 0x52, 0xf6, 0x28, 0x1c, 0xfc, 0xbb, + 0x4d, 0x69, 0x95, 0x0a, 0x97, 0x4d, 0x6d, 0x8a, 0xb8, 0x61, 0x40, 0xab, 0x16, 0xa4, 0xaf, 0xb2, + 0xfe, 0x9e, 0x9a, 0x74, 0x1f, 0xac, 0x05, 0x88, 0x01, 0x26, 0x46, 0xc9, 0x86, 0xb3, 0x83, 0x83, + 0x82, 0xbe, 0x44, 0x1c, 0x10, 0x73, 0x83, 0x88, 0x7f, 0x0f, 0xc0, 0x1a, 0x8e, 0x11, 0x72, 0xe0, + 0xe4, 0x1e, 0x0f, 0x0f, 0x06, 0x80, 0x31, 0x81, 0xb6, 0xd8, 0xea, 0xbb, 0x53, 0x4c, 0x43, 0xa7, + 0x3b, 0x0e, 0x28, 0x01, 0xc1, 0xf9, 0x1f, 0x0e, 0xbf, 0xf8, 0xab, 0xc5, 0x58, 0xab, 0x11, 0x91, + 0x56, 0xdb, 0x7a, 0x66, 0xd8, 0x75, 0xc0, 0x05, 0xed, 0x28, 0x4a, 0xba, 0x48, 0x5b, 0xa9, 0xbc, + 0xb6, 0xce, 0xec, 0xef, 0xa7, 0x27, 0x34, 0x31, 0x2c, 0x45, 0xa0, 0x9d, 0x04, 0xbd, 0x47, 0x16, + 0x37, 0x5b, 0x17, 0x84, 0x14, 0x10, 0x30, 0xeb, 0x4a, 0xdb, 0x7a, 0x69, 0xf8, 0x03, 0xd0, 0x00, + 0x90, 0x0d, 0x88, 0x07, 0x93, 0x80, 0xa8, 0x58, 0x54, 0x77, 0xe1, 0xdc, 0xa8, 0x79, 0xe5, 0x86, + 0x59, 0x8e, 0x96, 0x3e, 0x02, 0x40, 0x03, 0xc3, 0xa4, 0x12, 0x92, 0xd4, 0xb3, 0x91, 0x70, 0x2c, + 0xb1, 0x4c, 0xd4, 0x89, 0xff, 0xc3, 0x98, 0x08, 0xa0, 0xc5, 0x99, 0x05, 0xdd, 0xfd, 0xba, 0x3c, + 0x4e, 0xb3, 0x72, 0xfe, 0xdf, 0x4c, 0x1f, 0xf6, 0xeb, 0x80, 0x61, 0x56, 0xb7, 0xc7, 0x55, 0xfb, + 0x83, 0xff, 0x0e, 0x28, 0x02, 0xd7, 0x20, 0xfa, 0x58, 0x9c, 0x16, 0x7d, 0xff, 0x54, 0xac, 0xcd, + 0xa6, 0xc1, 0xd0, 0x3c, 0x74, 0xa3, 0x2b, 0x6d, 0x83, 0xfe, 0x3f, 0xf5, 0xd6, 0x5d, 0xa6, 0x0f, + 0xd0, 0x44, 0x0e, 0x44, 0xd3, 0x6e, 0x0b, 0x0d, 0x88, 0xad, 0xff, 0xae, 0x1b, 0xc0, 0x0b, 0x0e, + 0x59, 0x4e, 0x43, 0x02, 0xdb, 0x18, 0x26, 0x12, 0x1c, 0x27, 0x05, 0x60, 0xa0, 0x97, 0x2a, 0xfa, + 0xe7, 0xe4, 0x9c, 0x3c, 0x1e, 0x76, 0x05, 0x86, 0x23, 0xa2, 0x3b, 0xb4, 0x07, 0xac, 0x2b, 0x31, + 0x3e, 0x97, 0xb5, 0x0f, 0x60, 0x01, 0xba, 0x40, 0xfa, 0xd5, 0x19, 0x57, 0x4e, 0x71, 0xfd, 0xd3, + 0x13, 0xec, 0xe7, 0x7d, 0x6d, 0xf1, 0xbf, 0x96, 0xbc, 0xfc, 0x4b, 0xa5, 0x5d, 0x41, 0xd6, 0x01, + 0x18, 0x1b, 0x97, 0xbd, 0x30, 0x60, 0xb5, 0x3f, 0xdb, 0xc1, 0x0c, 0x6c, 0x40, 0xc0, 0x3b, 0x86, + 0xa5, 0xac, 0x3b, 0xca, 0xfb, 0xa7, 0x9c, 0x3c, 0xe1, 0x61, 0x8b, 0xa9, 0x47, 0x8e, 0x3e, 0x00, + 0x79, 0x65, 0x8f, 0x2c, 0x38, 0xe1, 0xc0, 0x0e, 0x0f, 0x07, 0x83, 0x00, 0x01, 0x41, 0x8c, 0x15, + 0x6b, 0x4c, 0x5b, 0x93, 0x8a, 0xb2, 0xc5, 0xe0, 0x2e, 0x00, 0x24, 0x03, 0x65, 0xe5, 0x1b, 0x30, + 0x0e, 0xe9, 0x4a, 0x2e, 0xc9, 0xca, 0x16, 0x00, 0x12, 0x02, 0xe2, 0x9b, 0x30, 0x00, 0x10, 0x0b, + 0x0f, 0x8b, 0x10, 0x58, 0xa8, 0x89, 0x46, 0x91, 0x15, 0x39, 0x29, 0x60, 0xf1, 0x27, 0x16, 0x15, + 0x7f, 0xf7, 0x40, 0x06, 0xa2, 0xf7, 0x2e, 0xb2, 0x46, 0x80, 0xc0, 0x72, 0x7d, 0xbf, 0x88, 0x75, + 0xb8, 0x78, 0x90, 0x03, 0x36, 0x6a, 0x20, 0x31, 0x6d, 0xba, 0x05, 0x54, 0x88, 0x60, 0xaf, 0x89, + 0x5c, 0x2e, 0xc5, 0x72, 0x2e, 0x78, 0xf2, 0x8b, 0xc1, 0xe3, 0x07, 0xd0, 0xef, 0x3b, 0xd0, 0xc6, + 0x50, 0x52, 0x81, 0xb0, 0x30, 0x2e, 0x44, 0xf4, 0xed, 0xaa, 0xf0, 0x40, 0x18, 0x0a, 0x4f, 0x1e, + 0x2c, 0xae, 0x3d, 0xce, 0xc8, 0x00, 0x14, 0xe4, 0xc0, 0xb1, 0x31, 0x14, 0x44, 0xaf, 0x00, 0x01, + 0x2c, 0xe3, 0x06, 0x08, 0x73, 0x21, 0xf8, 0x4b, 0x52, 0xa3, 0x80, 0x03, 0x18, 0x00, 0x06, 0x14, + 0x39, 0x80, 0x0f, 0xc3, 0x2c, 0xe8, 0x2a, 0x3d, 0x5e, 0x53, 0x37, 0x1f, 0xdf, 0x5d, 0x51, 0x0f, + 0x27, 0x42, 0xa6, 0xa9, 0x8b, 0x4f, 0xd3, 0x8e, 0xdd, 0x3c, 0x07, 0x40, 0x02, 0x23, 0xa1, 0x44, + 0xc3, 0x78, 0x97, 0x42, 0x61, 0x2e, 0x93, 0x8e, 0x1b, 0x70, 0x42, 0xd6, 0x60, 0x54, 0x87, 0x5c, + 0x13, 0xfb, 0xb6, 0xeb, 0x32, 0x6d, 0x0f, 0xff, 0xb6, 0xe2, 0xd1, 0xf9, 0xd0, 0x26, 0x1e, 0x59, + 0xaf, 0xc9, 0xc0, 0xc2, 0x21, 0x80, 0x64, 0x71, 0xb9, 0xa8, 0x16, 0x50, 0x1e, 0x1f, 0xf0, 0xa9, + 0x41, 0xc3, 0xa4, 0x80, 0x4f, 0x22, 0x3d, 0xbc, 0x32, 0x3b, 0xeb, 0xdb, 0x6d, 0x45, 0x79, 0xf8, + 0xe6, 0x14, 0xe0, 0xbf, 0xcf, 0xeb, 0x2c, 0x09, 0x38, 0xf8, 0x74, 0x90, 0x02, 0xab, 0x8d, 0xd0, + 0x88, 0xf7, 0x74, 0x15, 0xc6, 0x7e, 0x5f, 0x2d, 0xa6, 0x9e, 0xa5, 0xfb, 0x67, 0xf7, 0x0e, 0xc4, + 0xa9, 0x46, 0x58, 0x96, 0x6c, 0x94, 0x7b, 0xe1, 0xd5, 0x00, 0x2d, 0xa1, 0xf5, 0x96, 0x23, 0x77, + 0xe9, 0xbb, 0x7a, 0xd6, 0x9e, 0x5d, 0x6a, 0xe5, 0xa5, 0x61, 0x20, 0xa2, 0xf4, 0xc8, 0xd9, 0x57, + 0xcd, 0x05, 0xba, 0x2f, 0x87, 0x54, 0x00, 0x3f, 0xd9, 0x34, 0xe4, 0x1a, 0xa0, 0xef, 0x7b, 0xb5, + 0x6c, 0x77, 0x8b, 0x2e, 0xbb, 0x73, 0x75, 0x5e, 0x62, 0x6b, 0x42, 0xfc, 0x6b, 0x3c, 0x7d, 0xfc, + 0x31, 0x80, 0xfc, 0x78, 0xf9, 0x56, 0x33, 0x0e, 0xdc, 0xb5, 0xe2, 0xac, 0x55, 0xfe, 0xaf, 0x73, + 0xa6, 0x1e, 0xc0, 0x00, 0xba, 0xbd, 0x73, 0x6a, 0xff, 0xbd, 0xd5, 0xd4, 0xdd, 0xe3, 0xb6, 0xae, + 0xa0, 0xbc, 0xd7, 0xa2, 0xbe, 0xca, 0x1c, 0x24, 0x0e, 0x73, 0x5f, 0xfd, 0xb6, 0xfc, 0x18, 0x6e, + 0xf1, 0x0f, 0xef, 0x0e, 0x38, 0x01, 0x46, 0x9a, 0xe3, 0x9b, 0x3d, 0xf7, 0x97, 0xff, 0x83, 0xd6, + 0x6a, 0xbf, 0x86, 0xf0, 0x06, 0x0a, 0xc8, 0xbf, 0xbb, 0x2a, 0xb3, 0xff, 0xff, 0xa7, 0xbb, 0xff, + 0x0e, 0x60, 0x09, 0x9e, 0x9e, 0xbf, 0xd7, 0xff, 0xed, 0xb6, 0x05, 0xc8, 0x7a, 0x2a, 0xd5, 0x97, + 0xe1, 0xa5, 0x01, 0x3f, 0x2a, 0x00, 0xfa, 0xf5, 0xad, 0x34, 0xf7, 0xbc, 0x4c, 0xbc, 0x30, 0x48, + 0x24, 0x77, 0x7f, 0x9f, 0xbe, 0xdb, 0x7f, 0xd2, 0x38, 0x75, 0x14, 0x34, 0x3a, 0xbf, 0xf6, 0xe9, + 0xb7, 0x4e, 0x88, 0xb5, 0x6d, 0x34, 0xfe, 0x33, 0x04, 0x1e, 0x1d, 0xfa, 0x45, 0x56, 0x10, 0x71, + 0x93, 0x86, 0x5f, 0xef, 0x16, 0xe1, 0x45, 0x05, 0x67, 0x94, 0x79, 0xe7, 0x0d, 0xc8, 0x09, 0x73, + 0x1d, 0x2e, 0xff, 0xfe, 0x7e, 0x64, 0xf3, 0xff, 0x87, 0x88, 0x40, 0x01, 0x18, 0x65, 0x79, 0xa1, + 0x75, 0xfb, 0xe7, 0xcb, 0xdd, 0xbf, 0x2f, 0x37, 0xbf, 0x11, 0x14, 0x6e, 0x5f, 0xbe, 0x89, 0xfc, + 0x30, 0x8a, 0x03, 0xe9, 0xc9, 0x4d, 0x3a, 0x69, 0xa6, 0x9f, 0xf9, 0x15, 0x8c, 0x54, 0x7d, 0x85, + 0xd9, 0x04, 0xc8, 0x91, 0x56, 0x2f, 0x13, 0x08, 0x53, 0x2c, 0x17, 0xc5, 0x0c, 0xb6, 0x16, 0x03, + 0x83, 0xc5, 0x8d, 0x77, 0xc2, 0x6e, 0x00, 0xd4, 0x06, 0x4a, 0xbc, 0x88, 0xe6, 0x09, 0x81, 0xd0, + 0x75, 0x40, 0x71, 0x1c, 0x25, 0x4b, 0xd4, 0x5d, 0xf0, 0xbc, 0x8b, 0x89, 0xf2, 0xf8, 0x7b, 0x01, + 0x15, 0x56, 0x32, 0x2b, 0xfe, 0xfd, 0x6f, 0xf4, 0xfd, 0x69, 0xd3, 0x05, 0x63, 0x47, 0xd7, 0xbc, + 0x36, 0xe0, 0x00, 0x56, 0xa2, 0x8e, 0x8a, 0x06, 0xfe, 0x8d, 0x0b, 0x27, 0xb5, 0xaa, 0xdb, 0x8a, + 0xde, 0xaa, 0xa6, 0xbd, 0xfe, 0x1b, 0x70, 0x02, 0x00, 0x48, 0x37, 0x12, 0x24, 0xfb, 0xfc, 0x27, + 0x4d, 0xd6, 0xaf, 0x15, 0xc5, 0x6d, 0xdb, 0x59, 0x04, 0x3d, 0x75, 0x75, 0x86, 0x14, 0x00, 0x35, + 0x44, 0xd3, 0x04, 0x51, 0xa5, 0x67, 0x37, 0x47, 0xee, 0xfc, 0xff, 0x3f, 0xc4, 0xf8, 0xea, 0xff, + 0x37, 0xd1, 0x1f, 0x0d, 0xe0, 0x05, 0x7f, 0x83, 0xb4, 0x8c, 0x2e, 0x0b, 0x40, 0xa2, 0x63, 0xab, + 0xb7, 0x5a, 0x8e, 0xae, 0x3a, 0xb8, 0x9f, 0x3f, 0xcd, 0xe5, 0xdc, 0x76, 0xf4, 0xcb, 0x74, 0xdb, + 0xdb, 0x84, 0xf0, 0x05, 0x46, 0x6c, 0x81, 0x91, 0xfb, 0xdb, 0xfa, 0xdb, 0x15, 0x6d, 0xd5, 0xb3, + 0x78, 0x77, 0x00, 0x30, 0x10, 0x76, 0x30, 0xb3, 0xcf, 0xaf, 0x3f, 0xf6, 0xc1, 0xdf, 0xe2, 0x8b, + 0x14, 0x5c, 0x5d, 0x34, 0xf6, 0xdb, 0x87, 0x49, 0x00, 0x0e, 0x89, 0xef, 0x1b, 0x49, 0x22, 0x66, + 0x44, 0xb1, 0x4f, 0x97, 0xb6, 0x7b, 0xe1, 0x8b, 0x88, 0xfd, 0x8a, 0xb3, 0x71, 0x9c, 0x2a, 0xa3, + 0x58, 0x68, 0x2d, 0x32, 0xaa, 0x91, 0x08, 0x5c, 0xd6, 0xcd, 0x49, 0xbf, 0xc3, 0x6a, 0x00, 0x40, + 0x70, 0xf9, 0x0b, 0x50, 0x42, 0x1a, 0x77, 0xdd, 0x5f, 0x20, 0x99, 0x8b, 0xd2, 0xfd, 0xc8, 0xc8, + 0x46, 0xfa, 0xc3, 0xc3, 0xf2, 0x5e, 0x79, 0xf7, 0x2d, 0xa9, 0x90, 0xde, 0xcd, 0xee, 0x51, 0xbd, + 0xe1, 0xcc, 0x00, 0x5f, 0x1a, 0x20, 0xcc, 0x12, 0x15, 0xd7, 0xed, 0x0a, 0xd5, 0xc4, 0x79, 0xdf, + 0x5e, 0x25, 0xe4, 0xe3, 0xd7, 0x3b, 0xf1, 0x59, 0x6d, 0xcb, 0xc5, 0xc8, 0x52, 0x73, 0xf5, 0xd5, + 0xe1, 0x92, 0x40, 0x1a, 0x67, 0x0e, 0xa3, 0x05, 0x21, 0x07, 0xef, 0xe1, 0xff, 0xd5, 0x7c, 0x1d, + 0x5c, 0xbe, 0xb6, 0xdb, 0x15, 0x6d, 0xff, 0x0b, 0xe0, 0x03, 0xad, 0xe5, 0x87, 0x39, 0xb3, 0x74, + 0xfb, 0xcb, 0x06, 0xd4, 0xde, 0x75, 0x99, 0x15, 0x43, 0x2e, 0x00, 0x2e, 0xdb, 0xc0, 0xa2, 0xf1, + 0x54, 0x23, 0xf5, 0x8d, 0xee, 0xed, 0xdd, 0xb3, 0xd0, 0x0e, 0xcf, 0x4a, 0xc9, 0xc1, 0xb8, 0xce, + 0x6f, 0x2c, 0xf2, 0x0c, 0xf9, 0x85, 0xdc, 0x00, 0xfa, 0xb4, 0x2a, 0xe5, 0xa7, 0xcb, 0x2c, 0xff, + 0xcd, 0x7e, 0x68, 0xa7, 0x0e, 0xa8, 0x02, 0x77, 0x97, 0x19, 0x33, 0xa7, 0x8b, 0x62, 0xdf, 0xf6, + 0xf3, 0xa1, 0x94, 0xdb, 0x7a, 0x69, 0xf1, 0x8a, 0x09, 0x41, 0x83, 0xa5, 0x11, 0xaa, 0x86, 0x14, + 0x07, 0x43, 0x6b, 0x89, 0xec, 0x9d, 0x5b, 0xdf, 0x6f, 0x6d, 0x53, 0x4e, 0x9a, 0x71, 0x6c, 0x13, + 0xc3, 0x8a, 0x00, 0x33, 0x5c, 0x7c, 0x86, 0xa1, 0x1b, 0xea, 0x0c, 0xeb, 0xcb, 0x2c, 0x50, 0xb6, + 0xd2, 0xdf, 0x6f, 0x8d, 0x4d, 0x3d, 0xb7, 0xef, 0x80, 0x2f, 0x00, 0x09, 0x00, 0xd8, 0x1c, 0x3d, + 0x54, 0x7f, 0xa7, 0x80, 0x03, 0xcb, 0x16, 0x56, 0x54, 0x38, 0x07, 0x95, 0x0b, 0x50, 0xe0, 0x07, + 0x9e, 0x00, 0x38, 0x50, 0x1f, 0x41, 0x00, 0xf2, 0xc0, 0x18, 0xb1, 0x09, 0x61, 0xc0, 0x3d, 0x29, + 0x58, 0x98, 0x1e, 0x07, 0x01, 0x80, 0xe0, 0x5a, 0xc4, 0xb0, 0x88, 0x7e, 0xb1, 0x3f, 0x1d, 0x38, + 0x44, 0x9a, 0x48, 0xb7, 0x0e, 0x4c, 0x00, 0x17, 0xc4, 0x9d, 0x91, 0x80, 0x5c, 0x39, 0x87, 0x95, + 0x5d, 0xd3, 0x94, 0x59, 0xa0, 0x22, 0xfa, 0xff, 0x05, 0x85, 0x62, 0x4f, 0x1b, 0x86, 0xcd, 0xc7, + 0xbb, 0xc1, 0x9c, 0x8f, 0xc3, 0x78, 0x00, 0x9c, 0x8a, 0x61, 0x52, 0xe8, 0x41, 0x76, 0xe7, 0x97, + 0x0b, 0x7f, 0x56, 0x6b, 0x35, 0x2c, 0x7e, 0xab, 0xc6, 0xe0, 0x97, 0x41, 0xa0, 0x1f, 0x2b, 0xff, + 0x8b, 0x4f, 0xc2, 0xb8, 0x80, 0xb2, 0xe0, 0xed, 0xc6, 0x4c, 0x1c, 0xee, 0x0c, 0x39, 0x83, 0x45, + 0x7d, 0x43, 0x98, 0x01, 0x61, 0xcc, 0xa5, 0x6c, 0xa1, 0xfb, 0x94, 0xd9, 0x3d, 0x62, 0x07, 0x53, + 0x4e, 0xb6, 0xa3, 0x8f, 0x83, 0x11, 0x29, 0x5a, 0xfe, 0x50, 0x4b, 0x81, 0x64, 0x00, 0x00, 0x6d, + 0xd4, 0xae, 0x9e, 0x5f, 0x0e, 0xe0, 0x2c, 0x3e, 0xdc, 0x36, 0xac, 0x27, 0xa7, 0xa6, 0x9d, 0xe9, + 0xa7, 0xe5, 0x99, 0x7a, 0x69, 0xc7, 0x86, 0x14, 0x0a, 0x4d, 0x16, 0x49, 0x3e, 0x9c, 0x7f, 0xfb, + 0xb0, 0xe2, 0x80, 0x23, 0x29, 0xf4, 0x61, 0x19, 0x14, 0x8d, 0x3e, 0x32, 0xef, 0xad, 0x79, 0xf9, + 0xd1, 0x1d, 0xbf, 0x5e, 0x0e, 0x61, 0x4b, 0x87, 0x25, 0x19, 0xf1, 0x44, 0x1a, 0xad, 0x4b, 0x83, + 0xcc, 0x3f, 0x0c, 0x01, 0x79, 0x42, 0xae, 0x00, 0x86, 0xf8, 0x00, 0x1a, 0xa1, 0xe0, 0x00, 0xf1, + 0x61, 0xb8, 0xf0, 0x07, 0x96, 0xcb, 0x80, 0xb0, 0x94, 0x00, 0x09, 0x2a, 0xa5, 0x25, 0x00, 0xa8, + 0xc0, 0x00, 0x23, 0x18, 0x00, 0x06, 0x83, 0x0c, 0x80, 0x4e, 0x46, 0xc6, 0x8e, 0x18, 0xc3, 0xbe, + 0xaf, 0xfe, 0xd9, 0x22, 0xe2, 0xe4, 0xa2, 0xad, 0xc2, 0x50, 0x00, 0x54, 0xe0, 0x07, 0x22, 0x48, + 0xe0, 0x1c, 0x38, 0x07, 0x07, 0x00, 0x03, 0x70, 0xd4, 0x05, 0xf2, 0x7b, 0x62, 0xaf, 0x81, 0xe4, + 0x6c, 0x3a, 0x9a, 0x91, 0x40, 0x60, 0x5a, 0x06, 0xd7, 0x49, 0xc0, 0xca, 0x0e, 0x03, 0x00, 0x55, + 0x28, 0x80, 0x00, 0x80, 0x1f, 0x8f, 0x70, 0x94, 0x07, 0x6c, 0xc4, 0x7f, 0x8e, 0x07, 0x0e, 0x71, + 0x2b, 0x4c, 0x6e, 0x5e, 0x2a, 0x05, 0x40, 0x49, 0xcc, 0xc0, 0x00, 0x40, 0x03, 0x21, 0x10, 0x1c, + 0x3e, 0x05, 0xf2, 0xf9, 0x6b, 0x4f, 0x80, 0x80, 0x0a, 0x4b, 0x06, 0x7e, 0x08, 0xc3, 0x48, 0xbd, + 0xd5, 0xe2, 0xc4, 0xb2, 0x00, 0x01, 0x00, 0x04, 0x8f, 0x38, 0xf0, 0x00, 0x08, 0x03, 0x40, 0x14, + 0x51, 0x10, 0x79, 0x62, 0xf6, 0x43, 0xc3, 0xa0, 0x58, 0x38, 0x31, 0xc0, 0x38, 0x6d, 0xc0, 0x31, + 0x36, 0x31, 0x32, 0x75, 0x63, 0xff, 0xfb, 0x64, 0xeb, 0x6d, 0x9f, 0xdf, 0x7b, 0x77, 0x0e, 0xcd, + 0x89, 0x5c, 0x67, 0xca, 0x58, 0x36, 0xb1, 0x10, 0xb1, 0x87, 0x5c, 0x00, 0x86, 0xa3, 0x76, 0xc5, + 0x0f, 0xf7, 0x5b, 0x6e, 0x4e, 0xdb, 0x6c, 0xd5, 0x35, 0x6c, 0x5b, 0x27, 0x6c, 0xb5, 0x82, 0x80, + 0x22, 0xfa, 0x94, 0x73, 0x05, 0x99, 0xdd, 0xf8, 0x6d, 0xc0, 0x1f, 0xcf, 0xd0, 0x51, 0x56, 0x53, + 0x77, 0xfb, 0xa8, 0x99, 0xdf, 0x7b, 0x6b, 0x9f, 0x8f, 0x75, 0xc8, 0x3e, 0xea, 0x5e, 0x0f, 0x69, + 0x64, 0x35, 0x59, 0x9c, 0x7f, 0xc3, 0x78, 0x00, 0xc3, 0xa5, 0x89, 0x39, 0x4a, 0xcf, 0x93, 0x4d, + 0x6c, 0xf6, 0xa2, 0x5f, 0x1c, 0x4b, 0xed, 0xf8, 0x62, 0x0d, 0x28, 0x3d, 0x71, 0x45, 0xa4, 0x56, + 0xf8, 0x7c, 0x36, 0xe0, 0x48, 0x6e, 0xe3, 0x75, 0x35, 0xf7, 0x55, 0xfe, 0x2a, 0x1e, 0x5b, 0x9f, + 0xc3, 0x38, 0x22, 0x33, 0x63, 0x77, 0xff, 0x6f, 0xdb, 0x4a, 0xa3, 0xf0, 0x15, 0xe9, 0xf9, 0xdb, + 0x2b, 0x2b, 0x2b, 0x28, 0x5e, 0x50, 0x14, 0xf9, 0xc8, 0x26, 0x4f, 0xff, 0xf8, 0xd5, 0x30, 0x96, + 0x09, 0x55, 0x81, 0xb8, 0x82, 0x44, 0x14, 0xd3, 0x6c, 0x43, 0xfd, 0xf0, 0xea, 0x20, 0x03, 0x08, + 0xd2, 0x1f, 0xcd, 0xd9, 0xff, 0xb6, 0x2a, 0xcf, 0xfc, 0xe2, 0x2e, 0xe6, 0xff, 0x87, 0x9c, 0x04, + 0xbd, 0xca, 0xd7, 0xfb, 0xf4, 0xf5, 0xf8, 0xec, 0xbd, 0x7a, 0xe1, 0xdc, 0x09, 0x57, 0x23, 0x42, + 0x3f, 0xf6, 0xeb, 0xb6, 0x99, 0xf7, 0xf8, 0x41, 0x94, 0x32, 0x32, 0x8a, 0xb7, 0x4d, 0x3d, 0xb6, + 0xe1, 0xc2, 0x40, 0x2d, 0xe3, 0x21, 0xff, 0x4f, 0xff, 0xb6, 0x9a, 0x6e, 0x74, 0xd3, 0xdb, 0x6e, + 0x18, 0x44, 0x02, 0x07, 0x78, 0x1e, 0x76, 0xff, 0xed, 0xfc, 0x73, 0x08, 0x28, 0xdb, 0x58, 0xbd, + 0x3f, 0x84, 0x14, 0x35, 0xe5, 0xed, 0xfc, 0x20, 0xa8, 0xf5, 0xe9, 0xfc, 0x38, 0xa0, 0x0c, 0xa7, + 0x54, 0x68, 0x77, 0xbb, 0xe5, 0xff, 0xb6, 0x7e, 0x9c, 0x7a, 0xf7, 0xf8, 0x6f, 0x01, 0xc0, 0x29, + 0xff, 0xbd, 0xfd, 0xc6, 0xf9, 0x74, 0xfd, 0xfd, 0xdd, 0xbd, 0x9f, 0x16, 0xc5, 0xb0, 0x3d, 0x64, + 0x00, 0x7f, 0xf2, 0xcb, 0x10, 0x1d, 0xdb, 0x6e, 0x10, 0x50, 0xb0, 0x3e, 0x2a, 0xbb, 0x6d, 0xfc, + 0x62, 0x9c, 0x83, 0x16, 0x17, 0x70, 0x06, 0x50, 0x34, 0xa4, 0x0d, 0x30, 0xc4, 0x0f, 0x9a, 0x6e, + 0x48, 0x27, 0x8d, 0x31, 0x59, 0x21, 0xc0, 0xa3, 0x38, 0x30, 0x6f, 0xb2, 0xdb, 0x82, 0xb0, 0x67, + 0xc3, 0x6e, 0x00, 0x5a, 0xa3, 0xc1, 0x24, 0x0b, 0x0a, 0x7c, 0x0e, 0xd0, 0x24, 0x1d, 0x07, 0x68, + 0x9c, 0x00, 0xf8, 0x58, 0x4e, 0x38, 0xd0, 0x2c, 0x00, 0x63, 0x8d, 0x02, 0xc0, 0x06, 0x88, 0xfc, + 0x6f, 0x05, 0xb2, 0xf6, 0xff, 0xc3, 0x6e, 0x00, 0x2b, 0xce, 0xc1, 0x3c, 0x40, 0x62, 0x4b, 0xdb, + 0x5c, 0x9d, 0x4e, 0xf2, 0xf8, 0x93, 0xd4, 0x9e, 0x65, 0x4d, 0x12, 0xfd, 0xfa, 0xc3, 0xb8, 0x01, + 0x0a, 0x22, 0x3c, 0x83, 0x05, 0xec, 0x6f, 0x19, 0xcc, 0x8c, 0xb2, 0x2f, 0x8a, 0xcf, 0xf9, 0xef, + 0x7c, 0x0b, 0x6f, 0x81, 0xff, 0x55, 0xc5, 0xac, 0x4e, 0x84, 0x52, 0x5a, 0xa6, 0xf7, 0xc3, 0x6e, + 0x00, 0x4d, 0xc7, 0x10, 0x1e, 0x67, 0x77, 0xfe, 0x57, 0xbf, 0x4d, 0xb7, 0x37, 0xc9, 0xf5, 0x27, + 0x86, 0x7f, 0xbc, 0x33, 0x80, 0x0c, 0x34, 0x5a, 0x4c, 0x28, 0xaf, 0xf7, 0x2b, 0x5f, 0xc5, 0x2c, + 0x1f, 0xfd, 0x3f, 0x70, 0x07, 0x80, 0x01, 0x51, 0x0a, 0x44, 0x7e, 0xb1, 0x2e, 0x0e, 0x9e, 0x72, + 0xf9, 0x78, 0xa3, 0x96, 0xc4, 0x38, 0x34, 0x00, 0x0c, 0xa0, 0x48, 0x01, 0xc3, 0xa4, 0x80, 0x43, + 0xb6, 0x16, 0x53, 0x81, 0x88, 0x69, 0x0b, 0x59, 0xbc, 0x9c, 0xb5, 0x96, 0xb8, 0xc1, 0xf7, 0x11, + 0xe3, 0xee, 0x77, 0xc9, 0x76, 0x3e, 0xf5, 0x0d, 0xf8, 0xb1, 0x6f, 0xf8, 0x73, 0x00, 0x22, 0x86, + 0x30, 0x71, 0x8a, 0x14, 0xac, 0xfe, 0xbe, 0x9a, 0x6d, 0xb7, 0xd3, 0x3f, 0x3d, 0xed, 0xe7, 0x3c, + 0x63, 0x1b, 0xf5, 0xef, 0x0f, 0x28, 0x00, 0x7f, 0x4c, 0x70, 0x13, 0x7e, 0x9e, 0x19, 0x2d, 0x8d, + 0xe6, 0x4d, 0xc6, 0xab, 0xf2, 0xca, 0xf1, 0x7c, 0xb6, 0xae, 0xeb, 0xf4, 0x28, 0x6e, 0x3c, 0xf3, + 0xfc, 0xef, 0x91, 0x1b, 0x7b, 0xd5, 0xd6, 0x1b, 0x50, 0x6f, 0x6d, 0xf3, 0x05, 0x02, 0xfb, 0x7e, + 0xe9, 0x6c, 0xb5, 0x88, 0xfa, 0x50, 0xe8, 0xfe, 0x55, 0x5c, 0x9b, 0x28, 0xff, 0x59, 0x98, 0x77, + 0xeb, 0xde, 0x9c, 0x38, 0xa0, 0x0a, 0xcf, 0x6c, 0x90, 0x1f, 0x74, 0x0a, 0xf7, 0x69, 0xbb, 0xb6, + 0x5f, 0x1f, 0xac, 0xdc, 0xbf, 0xa6, 0x0e, 0xdc, 0xff, 0x13, 0x21, 0xaa, 0xfd, 0x3e, 0x1e, 0x70, + 0x02, 0xde, 0xa2, 0x43, 0x17, 0xd5, 0x81, 0x6c, 0x7e, 0xf8, 0xe7, 0xd8, 0xac, 0x56, 0xdb, 0x75, + 0x71, 0x0f, 0xc5, 0x65, 0xf9, 0x6c, 0x4b, 0xc0, 0xe9, 0x42, 0x96, 0xb3, 0x7e, 0xf8, 0x79, 0xc0, + 0x62, 0x71, 0x25, 0x85, 0x1c, 0x1f, 0xbf, 0x79, 0xfe, 0xab, 0x15, 0xa6, 0x2b, 0x6b, 0xdf, 0xf0, + 0xc9, 0x20, 0x0c, 0xfc, 0xc9, 0xc4, 0x40, 0x21, 0x5a, 0x8b, 0x07, 0x27, 0xb4, 0x99, 0x55, 0x5d, + 0x57, 0xb6, 0xd9, 0x23, 0xb8, 0x85, 0x00, 0xee, 0xe0, 0x74, 0xd0, 0xbe, 0x00, 0x86, 0xcd, 0x33, + 0xc2, 0xef, 0xfb, 0xb6, 0x7f, 0xb6, 0xdf, 0x61, 0x37, 0x04, 0xd4, 0x36, 0x32, 0x5f, 0xfb, 0x6d, + 0xfc, 0x6a, 0x38, 0x69, 0x9e, 0x6b, 0x1d, 0x30, 0x40, 0xa5, 0xec, 0x3c, 0xa0, 0x02, 0xd3, 0x72, + 0xc2, 0x7a, 0xca, 0x32, 0xea, 0xd4, 0xb1, 0x93, 0x9c, 0x17, 0xdf, 0xc1, 0xef, 0xe5, 0x40, 0x16, + 0xfc, 0x5f, 0xc0, 0x18, 0x00, 0x0f, 0x81, 0xb3, 0xc7, 0x05, 0x61, 0xc5, 0x02, 0x55, 0xf9, 0x3e, + 0xdc, 0x98, 0x00, 0x0c, 0x5c, 0x1a, 0x24, 0x2e, 0x28, 0x80, 0x09, 0x48, 0x48, 0x00, 0x4b, 0x8a, + 0xc9, 0xab, 0x50, 0x84, 0x34, 0x07, 0x63, 0x4c, 0x5b, 0x5f, 0xe0, 0x48, 0x05, 0x01, 0x4d, 0x27, + 0x15, 0xa4, 0x4c, 0x15, 0xd8, 0xac, 0x51, 0xb4, 0x7c, 0x15, 0xbf, 0x18, 0x00, 0xa1, 0xc1, 0xe0, + 0xe6, 0x15, 0xb3, 0x0f, 0xee, 0x0d, 0xea, 0xb9, 0x7d, 0xab, 0xa8, 0x60, 0x00, 0xa0, 0xd4, 0x6f, + 0xf9, 0x30, 0xa0, 0xf8, 0x0c, 0x18, 0x5b, 0xcf, 0x7b, 0x88, 0x63, 0x8d, 0x9b, 0x8e, 0x30, 0x04, + 0x00, 0x02, 0x82, 0x46, 0x46, 0xf2, 0xaa, 0xec, 0x68, 0x6d, 0xf9, 0x3d, 0x14, 0x3d, 0x80, 0x30, + 0x80, 0x25, 0x31, 0x02, 0x94, 0x97, 0x7f, 0xe0, 0x3a, 0x5e, 0x9c, 0x1d, 0x5f, 0xf6, 0xdb, 0x07, + 0x4b, 0xeb, 0x07, 0x12, 0xe6, 0x89, 0x39, 0x7e, 0x5e, 0x5f, 0xcb, 0xe1, 0x8c, 0x01, 0xfd, 0x2d, + 0x5c, 0x7a, 0x69, 0xf8, 0xa5, 0x8a, 0x5e, 0x29, 0x62, 0x97, 0x11, 0x19, 0xc3, 0xaa, 0x00, 0x3e, + 0x85, 0xd2, 0x91, 0x8e, 0x0a, 0xce, 0xd2, 0x69, 0xdc, 0xff, 0xf7, 0xb9, 0xf8, 0x7f, 0xe3, 0xc7, + 0x8c, 0x58, 0x12, 0xe0, 0xb5, 0x01, 0x9e, 0xe8, 0xb9, 0xe3, 0x0f, 0x60, 0x01, 0xf4, 0x44, 0x27, + 0x5a, 0xdc, 0x23, 0xe8, 0xc9, 0xa3, 0x18, 0xc0, 0xff, 0xbb, 0xec, 0xab, 0x6e, 0x38, 0xbe, 0x4b, + 0xdb, 0xd4, 0xf6, 0x5b, 0x17, 0x30, 0x6b, 0x66, 0xfc, 0xdc, 0xbf, 0x97, 0xc3, 0xaa, 0x12, 0xf5, + 0x83, 0x4f, 0xdd, 0xa7, 0xc7, 0x1d, 0x3e, 0x5f, 0xfe, 0x23, 0x2d, 0x34, 0xf6, 0xdb, 0x87, 0x09, + 0x00, 0xf7, 0x50, 0x17, 0x53, 0x0a, 0x5f, 0xda, 0xd6, 0xa4, 0xe0, 0xe8, 0x48, 0x70, 0xf8, 0x4d, + 0x14, 0x6f, 0x07, 0xe1, 0x96, 0x6f, 0x63, 0xbf, 0xe1, 0xdc, 0x00, 0xef, 0x58, 0x48, 0xd1, 0x21, + 0x31, 0x2e, 0xff, 0xc7, 0x0f, 0xb2, 0x56, 0x8e, 0x1e, 0x19, 0xb1, 0x24, 0x3d, 0x83, 0x4d, 0x83, + 0x19, 0xc3, 0xa5, 0x22, 0x1f, 0xd1, 0xa9, 0x6c, 0x83, 0xc2, 0xb5, 0x59, 0x0a, 0xd9, 0x14, 0x3b, + 0x66, 0xce, 0xc0, 0xdc, 0xec, 0x8d, 0x84, 0x1e, 0xcc, 0xf8, 0xd7, 0x2d, 0x48, 0xe1, 0x43, 0xb8, + 0x01, 0x3f, 0x19, 0xa6, 0xc3, 0x2a, 0xc8, 0xed, 0xeb, 0x14, 0x65, 0xf8, 0x87, 0x7f, 0x44, 0xd3, + 0x8d, 0x35, 0x3a, 0x2e, 0x48, 0x3d, 0xc7, 0x5d, 0x34, 0xc0, 0xf2, 0x03, 0x10, 0xea, 0x2d, 0x93, + 0xc6, 0xaa, 0xe6, 0x77, 0xe1, 0xcc, 0x08, 0xae, 0x34, 0x72, 0xfe, 0xdd, 0xbf, 0xe3, 0xa2, 0xdb, + 0x29, 0xfc, 0x39, 0x80, 0xc0, 0xd6, 0x38, 0x51, 0x0f, 0xea, 0x9e, 0xbb, 0x7f, 0x4f, 0xe3, 0xfe, + 0xdf, 0xc3, 0x8a, 0x00, 0xc1, 0x8d, 0x11, 0x82, 0x5c, 0x9d, 0x71, 0x5d, 0xd3, 0xff, 0x09, 0x17, + 0x4c, 0x8b, 0x63, 0x9f, 0xff, 0x0e, 0x60, 0x04, 0x02, 0xe8, 0xbe, 0x0c, 0xd7, 0xb4, 0xde, 0xd8, + 0xab, 0x07, 0x1f, 0xd3, 0xfd, 0xb6, 0xc2, 0x7d, 0xa5, 0x0a, 0xe6, 0xfa, 0xff, 0x87, 0x89, 0x00, + 0x49, 0x1d, 0x54, 0x1e, 0x89, 0x67, 0x76, 0xe3, 0xb7, 0xe9, 0xe9, 0xa7, 0x94, 0x99, 0x13, 0xa6, + 0xdb, 0x7f, 0x0c, 0x28, 0x12, 0x8f, 0xa6, 0x8d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdf, 0xff, 0x91, 0x43, + 0x8a, 0x38, 0xeb, 0x6f, 0xb6, 0xdf, 0xfe, 0x75, 0x96, 0xdb, 0xdb, 0x6f, 0x87, 0x14, 0x04, 0x2d, + 0x46, 0x13, 0xf4, 0xd3, 0xff, 0x34, 0x4c, 0xb4, 0xf4, 0xd3, 0xe1, 0xc5, 0x04, 0x89, 0x08, 0x65, + 0xa5, 0x3e, 0x5f, 0xb6, 0xdf, 0xfd, 0x6e, 0x97, 0x7f, 0x86, 0x15, 0x0a, 0x55, 0x7f, 0xf6, 0xf3, + 0xf6, 0xde, 0x74, 0xc3, 0x8a, 0x10, 0xe2, 0xa0, 0xd3, 0x4f, 0x4d, 0x3b, 0x6f, 0xaf, 0xa9, 0xf5, + 0xfb, 0xfc, 0x72, 0x86, 0x27, 0xe9, 0xcb, 0x18, 0xa0, 0x83, 0x1d, 0x6d, 0x58, 0x50, 0x90, 0xe6, + 0xab, 0x4f, 0x4d, 0x3f, 0xfe, 0x21, 0x42, 0x17, 0xab, 0xc4, 0x28, 0x1a, 0xc7, 0x2d, 0x0c, 0x28, + 0x17, 0xd6, 0x5b, 0xdb, 0xff, 0xec, 0x61, 0x82, 0x40, 0x89, 0xf3, 0x0b, 0xfd, 0x5f, 0xf9, 0x61, + 0x85, 0x1f, 0x6b, 0xed, 0xb7, 0xfd, 0xfe, 0xc2, 0xca, 0x15, 0x44, 0x0b, 0xfd, 0x7f, 0xc7, 0x12, + 0x13, 0x73, 0xbf, 0x61, 0x3c, 0x00, 0x2e, 0xef, 0x70, 0xb3, 0xf2, 0x90, 0xcf, 0xfe, 0x91, 0x83, + 0xc1, 0x8f, 0xd3, 0x53, 0x7b, 0x53, 0x74, 0x43, 0x45, 0x76, 0x4b, 0xe4, 0xb3, 0xc3, 0x6e, 0x03, + 0x8f, 0x66, 0x3c, 0x0f, 0x7e, 0xef, 0xb2, 0x4e, 0x78, 0x79, 0xd6, 0x56, 0x54, 0x54, 0x58, 0x7b, + 0x00, 0x8b, 0x6d, 0x2b, 0x19, 0x0b, 0x5f, 0xa5, 0xb9, 0xbf, 0xef, 0x59, 0xbc, 0x5d, 0x14, 0xdf, + 0xaf, 0x87, 0x9c, 0x00, 0x57, 0x09, 0x15, 0x5d, 0xf8, 0x64, 0x91, 0x25, 0xf2, 0xfc, 0x5d, 0x35, + 0xbd, 0x90, 0x3f, 0xf1, 0xc6, 0x0f, 0xf9, 0x99, 0x5f, 0x6f, 0xe1, 0xdc, 0x00, 0x55, 0xa9, 0x31, + 0xbb, 0x3b, 0x6b, 0x2e, 0x2b, 0xb8, 0xbb, 0x3a, 0x97, 0xd3, 0x2f, 0xac, 0xb4, 0x1d, 0x2e, 0x7b, + 0xca, 0x2b, 0x8a, 0xc5, 0x9b, 0xff, 0x0e, 0x60, 0x04, 0xee, 0x1a, 0x82, 0x54, 0xde, 0x35, 0x61, + 0x57, 0xcf, 0xb2, 0xf4, 0xe3, 0x6f, 0x76, 0xf1, 0xff, 0x8c, 0x5b, 0x3b, 0xc7, 0xdc, 0xbb, 0x1f, + 0xf2, 0xcb, 0x1c, 0xfc, 0x68, 0x50, 0x0a, 0x2d, 0xb7, 0xa7, 0x6f, 0x0d, 0x12, 0x00, 0x39, 0x29, + 0x98, 0x70, 0xa6, 0x23, 0x7f, 0xec, 0xde, 0xa7, 0xab, 0x59, 0x17, 0x96, 0x35, 0x2d, 0xd5, 0xbb, + 0x6c, 0xc3, 0x04, 0x80, 0x60, 0xb9, 0x4c, 0x1c, 0x0e, 0x6e, 0xd4, 0xd5, 0xb6, 0xcd, 0xdb, 0x77, + 0xff, 0x13, 0x3d, 0x86, 0xc9, 0x00, 0x12, 0xf5, 0xbb, 0xd0, 0x9d, 0xef, 0xbb, 0xd4, 0x90, 0x1d, + 0x05, 0xd3, 0x00, 0x3e, 0xf5, 0xa6, 0xd8, 0x3b, 0x72, 0x21, 0x7a, 0xaf, 0x7e, 0x1e, 0x50, 0x0a, + 0x01, 0x21, 0x8b, 0x01, 0x50, 0x5a, 0x5f, 0xfe, 0xa0, 0x5d, 0x41, 0x1b, 0x38, 0x07, 0xca, 0x61, + 0x78, 0x7b, 0xb1, 0xf9, 0x9d, 0xd3, 0x3b, 0x05, 0xf8, 0x14, 0x1f, 0xc5, 0xbc, 0xc7, 0x1f, 0xb3, + 0x10, 0xfd, 0x9f, 0x03, 0x8f, 0xce, 0x74, 0x55, 0x16, 0x7a, 0x7f, 0x0c, 0xb8, 0x01, 0x2e, 0x6f, + 0x13, 0x75, 0x87, 0x40, 0x65, 0xbf, 0x15, 0xbe, 0x87, 0x20, 0xf7, 0xca, 0xbf, 0x46, 0xdf, 0xcf, + 0x5c, 0x1b, 0xf8, 0xa7, 0xef, 0x1b, 0x82, 0x1c, 0x33, 0x80, 0x84, 0x30, 0x25, 0xa1, 0x16, 0x87, + 0x7f, 0xb2, 0x32, 0xff, 0x37, 0x4e, 0x3e, 0x0e, 0x5f, 0x4f, 0xee, 0x61, 0xc2, 0x40, 0x01, 0x38, + 0x3a, 0x8b, 0xe8, 0x98, 0x82, 0x67, 0x5e, 0x90, 0x74, 0xba, 0xde, 0x77, 0x0f, 0x76, 0x09, 0x86, + 0xc2, 0xed, 0x41, 0xdf, 0x1f, 0x8b, 0xaf, 0x19, 0xda, 0x45, 0xbc, 0xba, 0xec, 0xf1, 0xd6, 0x37, + 0x18, 0xab, 0xde, 0xb5, 0x87, 0x49, 0x00, 0xb2, 0x54, 0x88, 0x53, 0x0e, 0xf7, 0xfc, 0x87, 0xae, + 0xa3, 0xa1, 0xbf, 0xef, 0x7b, 0x9e, 0x99, 0xa1, 0x19, 0x19, 0xd7, 0x4f, 0xb7, 0x0c, 0xe0, 0x03, + 0x5a, 0x5c, 0x46, 0x54, 0x6e, 0xd2, 0xd6, 0xab, 0xa6, 0x98, 0xa5, 0x8b, 0x69, 0xf7, 0x30, 0xc2, + 0x28, 0x27, 0x38, 0xbe, 0x3b, 0x6f, 0x6c, 0xdf, 0xff, 0x7c, 0x28, 0x88, 0x43, 0xe4, 0xf4, 0xbf, + 0xb2, 0xdf, 0xf8, 0x53, 0x00, 0x4b, 0xd3, 0xc2, 0x2c, 0x9f, 0x56, 0xcd, 0xfe, 0xbc, 0x27, 0x80, + 0x0d, 0x7b, 0x1b, 0x58, 0xe5, 0x11, 0x5a, 0xed, 0xcf, 0xc6, 0xb1, 0xcb, 0x71, 0x5b, 0x6f, 0x0d, + 0x28, 0x0b, 0xb4, 0x2e, 0x7f, 0xaf, 0xff, 0xe1, 0xac, 0x00, 0xdf, 0x2f, 0x14, 0x3f, 0x4f, 0xfd, + 0x7f, 0x7c, 0x37, 0x80, 0x66, 0x51, 0x01, 0xf7, 0x8a, 0x0c, 0xf5, 0x96, 0x0e, 0x28, 0x0c, 0xa2, + 0x58, 0xcb, 0x0f, 0x14, 0x1c, 0x40, 0xf0, 0xa0, 0x1c, 0x65, 0x25, 0x88, 0xc1, 0xaf, 0x1f, 0x55, + 0xf0, 0x88, 0x12, 0x42, 0x93, 0x66, 0x29, 0x8b, 0xea, 0x2e, 0x2e, 0x29, 0xa6, 0x5c, 0x14, 0xc5, + 0xe2, 0x8e, 0x00, 0x05, 0x63, 0xb8, 0x71, 0x43, 0xb9, 0x66, 0xdb, 0xdb, 0x6f, 0xdd, 0x7f, 0xa9, + 0xa6, 0xdb, 0x7f, 0x0e, 0x60, 0x30, 0x82, 0x93, 0x48, 0x6f, 0x37, 0x60, 0xc6, 0xd6, 0x2c, 0xde, + 0x8e, 0x4c, 0xa0, 0x7d, 0x3e, 0x4f, 0x30, 0x73, 0xf1, 0x94, 0xb0, 0x09, 0x0d, 0x0d, 0x8b, 0x36, + 0xe8, 0x87, 0xd3, 0x42, 0xd7, 0xb6, 0x56, 0x7d, 0x0e, 0x60, 0x0e, 0x8a, 0xcb, 0x4f, 0x5f, 0xb6, + 0xde, 0xdb, 0x75, 0xca, 0x3f, 0x0e, 0x37, 0x6d, 0xb2, 0xd6, 0x2a, 0xc0, 0x20, 0x41, 0xe3, 0x5f, + 0x5e, 0x51, 0x24, 0x1c, 0x3b, 0x80, 0x09, 0xb3, 0x0c, 0x8d, 0xbf, 0x28, 0x45, 0xac, 0x0d, 0x4b, + 0xb6, 0x50, 0x15, 0x57, 0xbf, 0x1c, 0x3c, 0x7b, 0xae, 0x4d, 0xe8, 0xa4, 0x2f, 0xd3, 0x2f, 0xcb, + 0xe1, 0xbc, 0x00, 0x47, 0x03, 0x75, 0x18, 0x7d, 0xef, 0x84, 0x23, 0xde, 0x85, 0x47, 0xa5, 0x83, + 0xac, 0x68, 0x66, 0x4a, 0x81, 0xdd, 0x68, 0xa1, 0x86, 0x94, 0x8a, 0x0e, 0x0d, 0xbc, 0x07, 0x61, + 0x61, 0x5a, 0x0d, 0x20, 0xae, 0xc2, 0x01, 0xbd, 0xcd, 0xb2, 0x04, 0x99, 0x45, 0x6a, 0xee, 0xc6, + 0x2e, 0x61, 0xc5, 0x00, 0x7b, 0xd8, 0xbb, 0x2b, 0x0b, 0x94, 0x91, 0xff, 0xff, 0x83, 0xcf, 0x9c, + 0xf7, 0x29, 0x3e, 0xac, 0xdf, 0xd7, 0xe3, 0x68, 0x14, 0x0a, 0xae, 0xad, 0xfe, 0x19, 0x08, 0x0d, + 0x8e, 0x9f, 0x8e, 0x9f, 0xc7, 0x96, 0x59, 0x81, 0xc2, 0xa0, 0xaa, 0x70, 0xd0, 0x58, 0x10, 0x1d, + 0x31, 0xdc, 0x43, 0x42, 0x41, 0xf1, 0xfc, 0x1d, 0xb0, 0x31, 0x83, 0x86, 0x06, 0x84, 0xfc, 0x69, + 0xa6, 0x9c, 0x3d, 0x80, 0x1f, 0xcb, 0x99, 0x58, 0x0a, 0xce, 0x7f, 0x7a, 0xb3, 0xde, 0x4e, 0x70, + 0xf3, 0xcf, 0x7f, 0x9a, 0xdb, 0xc9, 0x07, 0x05, 0x8b, 0x7d, 0x71, 0xed, 0x04, 0xb0, 0x48, 0x14, + 0x88, 0x8e, 0x96, 0xfe, 0x9e, 0x18, 0x50, 0x08, 0x8a, 0x30, 0xd9, 0x8c, 0xa0, 0xf8, 0xdf, 0x0b, + 0xf0, 0xfa, 0x16, 0x5c, 0x6d, 0xfc, 0x27, 0xd1, 0xbe, 0xb3, 0xf7, 0xfa, 0xdf, 0xcf, 0x7d, 0x9e, + 0x3e, 0x45, 0x44, 0x36, 0xe0, 0x0c, 0x8d, 0x92, 0x10, 0x2b, 0xc4, 0x2f, 0x9e, 0xb4, 0x61, 0xf6, + 0x57, 0x68, 0xbb, 0xbd, 0xb0, 0x5e, 0x03, 0xaf, 0x7b, 0xc4, 0xb5, 0xc3, 0x04, 0x80, 0xde, 0xb1, + 0x60, 0x93, 0x4f, 0xfd, 0x7d, 0xeb, 0x0c, 0x60, 0x0f, 0xf7, 0x0e, 0xce, 0xff, 0xfe, 0x9c, 0x58, + 0x51, 0x40, 0x0c, 0x2e, 0x94, 0x9a, 0x65, 0xff, 0xf7, 0x3f, 0x1d, 0xfc, 0x28, 0xa0, 0x03, 0x02, + 0x0e, 0x74, 0xc4, 0x1f, 0x48, 0xf6, 0xfe, 0xf6, 0xc1, 0x41, 0xc6, 0x58, 0xb6, 0xc1, 0xd7, 0xc2, + 0xae, 0xa5, 0x77, 0x42, 0x6a, 0x08, 0xe2, 0x1d, 0x8a, 0x8f, 0xf6, 0xfb, 0x78, 0xab, 0x6e, 0x1c, + 0x50, 0x02, 0x44, 0x0f, 0xf6, 0x60, 0x54, 0x94, 0xdd, 0xaf, 0xf3, 0xf6, 0xf7, 0x07, 0x7e, 0x2a, + 0xc7, 0x5f, 0x2d, 0x6b, 0xa6, 0x9f, 0xc3, 0x0a, 0x00, 0x68, 0x00, 0x7c, 0x62, 0x88, 0xb6, 0xf4, + 0xff, 0x4d, 0x34, 0xc5, 0xb9, 0xf8, 0x3f, 0xe7, 0x9a, 0xc5, 0x87, 0x14, 0x00, 0x9a, 0xf6, 0xb0, + 0x9c, 0x3e, 0x9d, 0xfe, 0x5e, 0x9d, 0x74, 0xdc, 0x1d, 0xfd, 0x6b, 0xb6, 0xdf, 0xc3, 0x6a, 0x01, + 0x2f, 0x17, 0x85, 0x03, 0xbf, 0xdb, 0x6f, 0xe7, 0xeb, 0xa7, 0xf8, 0x71, 0x40, 0x06, 0x01, 0x86, + 0xb9, 0x90, 0x55, 0x99, 0xf9, 0xfb, 0xb7, 0x50, 0x77, 0xe7, 0x31, 0x12, 0xf7, 0xf1, 0xc5, 0xf5, + 0xdc, 0xba, 0x69, 0xfc, 0x2e, 0xa0, 0x0a, 0x29, 0x40, 0xec, 0xe5, 0xbf, 0xf7, 0xac, 0xfd, 0xb6, + 0xeb, 0x6c, 0x76, 0xc3, 0x8a, 0x00, 0x78, 0x32, 0x5e, 0x47, 0xe6, 0x03, 0x5e, 0xfe, 0xdb, 0x6f, + 0x6f, 0x89, 0xd3, 0xa6, 0x9f, 0xc3, 0x0a, 0x02, 0x56, 0xd9, 0xdd, 0x6d, 0xdb, 0xfe, 0xde, 0xdb, + 0x79, 0x61, 0xc5, 0x01, 0x0e, 0x33, 0x04, 0x76, 0x71, 0xfb, 0xed, 0x97, 0xc6, 0xdd, 0x34, 0xca, + 0xb3, 0xdb, 0xf8, 0x5f, 0x00, 0xc1, 0xd0, 0x0c, 0x49, 0x9d, 0xfe, 0x6e, 0x2a, 0xcb, 0xdd, 0xbb, + 0x6d, 0x8b, 0x23, 0xb8, 0x69, 0x40, 0x8d, 0x4f, 0x45, 0xdf, 0xfe, 0xdb, 0xf9, 0x53, 0x0e, 0x28, + 0x03, 0x2d, 0xd4, 0xab, 0xfa, 0xff, 0xfe, 0xde, 0xdb, 0x6b, 0xd3, 0xf8, 0x61, 0x40, 0x0c, 0xd5, + 0xb1, 0xad, 0x4d, 0xcb, 0xb7, 0x76, 0xdc, 0xfe, 0xb8, 0xd3, 0x6e, 0x2d, 0x97, 0x95, 0x58, 0x61, + 0x40, 0x19, 0x4d, 0xdc, 0x32, 0xcb, 0x5f, 0x9b, 0xae, 0xdd, 0x45, 0x59, 0xbe, 0x7c, 0x28, 0xa0, + 0x1b, 0xae, 0x18, 0xbf, 0x4f, 0xfe, 0xd9, 0x7b, 0x3c, 0x28, 0x48, 0x15, 0x1c, 0x54, 0x7f, 0xe9, + 0xa7, 0xa6, 0x9c, 0x37, 0x83, 0x83, 0xa6, 0x52, 0xdf, 0xe2, 0xb9, 0x34, 0x09, 0xf7, 0x77, 0x7e, + 0x9a, 0x8d, 0x64, 0xad, 0x6f, 0x7c, 0x2e, 0xe0, 0x0c, 0x03, 0x4c, 0x0f, 0xd8, 0x33, 0xef, 0x36, + 0x14, 0x42, 0x30, 0x27, 0x4e, 0x68, 0x8f, 0x0b, 0x08, 0x8f, 0x02, 0xc4, 0xab, 0x3c, 0xd6, 0x1c, + 0x50, 0x00, 0x28, 0x86, 0x42, 0xd7, 0xa0, 0x89, 0x4a, 0x9b, 0xfa, 0x73, 0x77, 0x67, 0x77, 0x37, + 0x67, 0x1d, 0xf8, 0x3d, 0xf3, 0xbe, 0x9a, 0xbe, 0x25, 0x7a, 0xb2, 0xab, 0xe8, 0x62, 0xc0, 0x62, + 0x1d, 0x7e, 0x1d, 0xc0, 0x01, 0xfc, 0x75, 0xd6, 0xdd, 0x85, 0x85, 0x84, 0x76, 0x6c, 0xd0, 0xac, + 0xfc, 0x32, 0xfd, 0xb3, 0xcc, 0x1b, 0x27, 0x38, 0x5c, 0xc1, 0xd2, 0x89, 0x74, 0xfb, 0x7e, 0x1b, + 0xc0, 0x2e, 0x85, 0x0a, 0x56, 0x18, 0xd7, 0xce, 0xe6, 0xfb, 0x2f, 0x39, 0xfe, 0x4e, 0xf1, 0x0f, + 0x8a, 0x3d, 0xe9, 0x80, 0x80, 0x8a, 0x9e, 0xba, 0xbe, 0x1e, 0xc0, 0x04, 0x12, 0xa0, 0x37, 0x46, + 0x50, 0x17, 0x04, 0x7f, 0xc3, 0x71, 0xdb, 0xd6, 0x3b, 0x7a, 0xec, 0x76, 0xf5, 0xdb, 0x2f, 0x6f, + 0x77, 0xae, 0xb1, 0x57, 0x82, 0x07, 0xdb, 0xe1, 0xb7, 0x00, 0x0c, 0xc2, 0xda, 0x64, 0x46, 0x43, + 0x55, 0xf1, 0x3e, 0x7e, 0x27, 0xe3, 0xa5, 0xcd, 0xfe, 0x20, 0xb5, 0x69, 0xf6, 0xf0, 0xd2, 0x39, + 0x93, 0xbf, 0xff, 0xf9, 0x61, 0xe2, 0x18, 0x00, 0x2b, 0x5f, 0x89, 0xbe, 0x57, 0xe2, 0xd7, 0x97, + 0x9f, 0xbf, 0x89, 0x7f, 0x3f, 0xbd, 0xa6, 0x98, 0x3e, 0xfc, 0x6f, 0xdb, 0xf8, 0x61, 0x40, 0x0b, + 0x52, 0x0e, 0xd4, 0xad, 0x7c, 0x0b, 0x26, 0xbc, 0xb5, 0x9f, 0xea, 0xee, 0x4f, 0x9e, 0xe6, 0xf9, + 0xf0, 0xf3, 0x80, 0x8c, 0x08, 0x4d, 0x57, 0x0c, 0x4a, 0x99, 0xde, 0x7f, 0xaf, 0x88, 0xf9, 0x3b, + 0xe3, 0xf1, 0x1e, 0x26, 0xbd, 0xeb, 0x5c, 0x31, 0x80, 0x05, 0xed, 0xe1, 0x5a, 0xf8, 0xe8, 0x08, + 0xf4, 0x28, 0x39, 0x7f, 0x4d, 0x30, 0x6d, 0xf2, 0x9e, 0xfc, 0x91, 0xc4, 0xe6, 0x0f, 0x86, 0x5c, + 0x05, 0x14, 0xc8, 0x63, 0x3f, 0xf7, 0xf7, 0xc7, 0x51, 0x3e, 0x1b, 0x70, 0x01, 0xa9, 0x47, 0xd6, + 0x49, 0x85, 0x3c, 0xbe, 0x14, 0xe1, 0x34, 0x3f, 0x79, 0x3b, 0xf9, 0x21, 0xba, 0xbf, 0xe1, 0xc7, + 0x00, 0x48, 0xed, 0x83, 0x72, 0x19, 0x03, 0xc3, 0xff, 0xcb, 0x19, 0x58, 0xcf, 0x3a, 0x3f, 0xe5, + 0xf1, 0x93, 0x7e, 0x4d, 0xc2, 0x30, 0x52, 0x0b, 0x0c, 0xaa, 0x77, 0x17, 0xa9, 0xee, 0xdd, 0x8d, + 0x28, 0x0f, 0x9d, 0xbf, 0x5c, 0x39, 0x80, 0x03, 0x44, 0x8e, 0xf0, 0x3c, 0x65, 0x25, 0x74, 0xaa, + 0x63, 0x6d, 0xb7, 0xbb, 0x5b, 0x6e, 0xa6, 0x8a, 0x0c, 0xa3, 0x4b, 0x86, 0xfe, 0xfe, 0x2e, 0x55, + 0x39, 0x40, 0x35, 0x52, 0x83, 0x4f, 0x31, 0x32, 0xcc, 0x76, 0xf1, 0x0d, 0x74, 0xc5, 0xb8, 0x79, + 0xc0, 0x09, 0x2b, 0x62, 0xf0, 0xa2, 0xb7, 0x6b, 0xfd, 0xbd, 0xe3, 0x6f, 0xef, 0x96, 0xbf, 0x2f, + 0xae, 0xdf, 0x4f, 0x0c, 0xa2, 0x80, 0x31, 0xeb, 0x91, 0xaf, 0xb5, 0xff, 0xfa, 0x93, 0xf6, 0x19, + 0x50, 0x06, 0x3e, 0x7b, 0xc1, 0x3a, 0x7e, 0x5e, 0xdb, 0xdf, 0x15, 0xfe, 0x2c, 0x69, 0x20, 0x2c, + 0xe8, 0x73, 0x73, 0x73, 0x0f, 0x10, 0x80, 0x03, 0x19, 0x47, 0xd3, 0x12, 0x0e, 0xfd, 0x7d, 0xff, + 0xc3, 0x9c, 0x60, 0x7d, 0xc1, 0xf7, 0x28, 0x0d, 0x30, 0x0e, 0x38, 0x7b, 0x8e, 0xe7, 0xb7, 0xd3, + 0xc0, 0x5c, 0x00, 0x40, 0x46, 0xc1, 0xd0, 0x17, 0x0b, 0xe0, 0x02, 0x48, 0x17, 0x22, 0xf9, 0x83, + 0x67, 0x61, 0xe2, 0xd9, 0xe3, 0x15, 0x94, 0x43, 0xc8, 0x74, 0xf1, 0x95, 0xe6, 0x7f, 0x0f, 0x72, + 0xa2, 0xf1, 0x70, 0xf0, 0x03, 0x88, 0x6e, 0x4e, 0x9f, 0xc3, 0xd8, 0x26, 0xed, 0x57, 0xff, 0xef, + 0xf7, 0xef, 0x4d, 0x3f, 0xe1, 0xe5, 0x08, 0x02, 0x0c, 0x97, 0xd5, 0xe9, 0xdb, 0x6c, 0xfd, 0x3d, + 0xb6, 0xea, 0x3c, 0xad, 0xff, 0x85, 0x94, 0x05, 0xbe, 0x4b, 0x28, 0x9a, 0x7a, 0x7d, 0xea, 0xfe, + 0xb8, 0x02, 0x40, 0x00, 0x90, 0x0d, 0x94, 0x5a, 0xc9, 0x5e, 0xa7, 0x0e, 0x35, 0x28, 0xeb, 0x38, + 0x36, 0x6a, 0x2e, 0x79, 0xc2, 0xc0, 0x18, 0x32, 0xf3, 0x0c, 0x59, 0x1a, 0x47, 0x80, 0x30, 0xf8, + 0x06, 0x06, 0x1c, 0x45, 0xe2, 0xd7, 0xe2, 0x7f, 0x5c, 0x38, 0x75, 0xc0, 0x0c, 0x37, 0xcc, 0x3c, + 0x33, 0x7f, 0xaf, 0xb7, 0x6f, 0x83, 0x2f, 0xbd, 0xb6, 0xf8, 0xc7, 0xfa, 0x9b, 0xcc, 0x3b, 0x80, + 0x0b, 0x6c, 0xf3, 0x1a, 0x06, 0x26, 0xbd, 0x3b, 0x7c, 0x3d, 0xc7, 0x3c, 0xa2, 0xba, 0x99, 0x33, + 0x84, 0x7b, 0x4a, 0x73, 0xff, 0x11, 0x81, 0xa0, 0xa3, 0x5c, 0x1a, 0x7e, 0xca, 0x03, 0xf8, 0x7c, + 0xc9, 0xe2, 0xb4, 0xcb, 0xf2, 0xde, 0x1e, 0xc0, 0x13, 0xc0, 0x3b, 0x62, 0x56, 0x07, 0x34, 0x87, + 0x9f, 0xf8, 0x3b, 0x1a, 0x18, 0xa3, 0xa0, 0x85, 0xc7, 0xa8, 0x03, 0xb8, 0xef, 0x54, 0x8e, 0x50, + 0x56, 0x39, 0x6f, 0x9d, 0x7a, 0x64, 0xb0, 0x16, 0x2c, 0x0c, 0xc0, 0xb2, 0xc7, 0xdd, 0x67, 0xa3, + 0x1d, 0x81, 0x2a, 0x4e, 0x6d, 0xb6, 0x3b, 0x2c, 0x4f, 0x4b, 0xb8, 0x6d, 0xc0, 0x15, 0x7a, 0xcc, + 0xc1, 0x7e, 0x2c, 0x8e, 0x3f, 0xa1, 0x3e, 0x04, 0x19, 0xdc, 0xef, 0x77, 0x77, 0x8b, 0x0f, 0x88, + 0xac, 0x95, 0x1a, 0x81, 0xeb, 0xbe, 0xf1, 0x05, 0xdf, 0xcd, 0x70, 0xd9, 0x20, 0x01, 0xf7, 0xe7, + 0x0e, 0x9c, 0x4e, 0xd3, 0x5f, 0xfe, 0xf8, 0x5a, 0x8a, 0x8a, 0x48, 0x7f, 0x34, 0x24, 0x6c, 0x4f, + 0xd4, 0xb4, 0x70, 0xd2, 0x01, 0xc7, 0x3c, 0x03, 0xae, 0x5e, 0x3d, 0x9b, 0x04, 0x13, 0x70, 0x73, + 0xd9, 0x01, 0xd3, 0x84, 0x20, 0xee, 0x3c, 0x53, 0x9f, 0xad, 0x61, 0x8c, 0x0c, 0x0c, 0xd4, 0x63, + 0xcb, 0xa6, 0xe5, 0xda, 0x77, 0x4c, 0xbf, 0xc6, 0x9e, 0x9a, 0x69, 0x70, 0xea, 0x80, 0x36, 0xc2, + 0x54, 0x38, 0x59, 0x80, 0xd3, 0x1b, 0xfc, 0x26, 0x78, 0x7b, 0xa5, 0x9c, 0x3c, 0x48, 0xd6, 0xb1, + 0xff, 0x25, 0x7e, 0xf6, 0xe7, 0xed, 0xe7, 0x0f, 0x1d, 0x7d, 0x7f, 0x00, 0x42, 0x14, 0xe5, 0xf0, + 0x68, 0xa3, 0x09, 0xc7, 0x0f, 0x60, 0x01, 0x73, 0x50, 0x21, 0x1b, 0x57, 0xc9, 0x57, 0xb6, 0xff, + 0x26, 0xae, 0xfd, 0x95, 0xc7, 0x3f, 0x2d, 0x95, 0xfc, 0x50, 0x35, 0x4d, 0xf2, 0xa1, 0xaa, 0xdb, + 0x07, 0x87, 0x76, 0xcd, 0xdb, 0xb4, 0x71, 0x8e, 0xde, 0x1e, 0xc0, 0x4b, 0xb8, 0x18, 0x1a, 0xdc, + 0xbf, 0x6f, 0x4c, 0xde, 0xbd, 0x99, 0x38, 0xc6, 0x54, 0x9a, 0x7f, 0xe1, 0xc5, 0x00, 0x15, 0xf7, + 0x74, 0x4b, 0x33, 0x77, 0x5d, 0x34, 0xe3, 0x4d, 0x3f, 0x6e, 0x9a, 0x6b, 0x6f, 0xf8, 0x51, 0x40, + 0x41, 0xb9, 0x0e, 0xdd, 0xfe, 0xf3, 0xdb, 0xed, 0xb1, 0x2f, 0xdb, 0xd3, 0x6d, 0xb8, 0x61, 0x40, + 0x12, 0x74, 0x4e, 0x1c, 0x0d, 0xeb, 0x67, 0xb6, 0xf2, 0x7d, 0xfa, 0xb7, 0x3a, 0x61, 0xd5, 0x00, + 0x1d, 0xfb, 0xf2, 0x66, 0x6c, 0xfc, 0x7f, 0x6d, 0xed, 0xff, 0xae, 0xb6, 0xdb, 0xf2, 0xdd, 0x3f, + 0xc3, 0x98, 0x00, 0xe1, 0x0b, 0xb3, 0x12, 0xab, 0x26, 0x07, 0xfe, 0x59, 0xfb, 0x66, 0xf5, 0xcd, + 0xf9, 0x6a, 0x20, 0x74, 0x10, 0xa6, 0xfd, 0x97, 0xf4, 0x00, 0x3c, 0x38, 0x31, 0xd7, 0xe1, 0x97, + 0x00, 0x32, 0x88, 0xf4, 0xe1, 0x67, 0xdd, 0xde, 0xbd, 0xb6, 0xdb, 0x6d, 0xb6, 0xce, 0xc2, 0xdb, + 0xd3, 0x04, 0x03, 0x61, 0xc5, 0x00, 0x1d, 0xef, 0xb9, 0xc9, 0x7e, 0x7c, 0x57, 0x4f, 0xed, 0xe5, + 0x4a, 0x7f, 0xe1, 0x9c, 0x02, 0x9a, 0x97, 0xf9, 0x01, 0xaf, 0xf9, 0xef, 0x7e, 0xa9, 0xb7, 0x27, + 0x4d, 0x69, 0xc3, 0x19, 0xd8, 0x77, 0x00, 0x70, 0x6b, 0x60, 0x91, 0xa6, 0x37, 0xae, 0x73, 0xff, + 0xfc, 0xb6, 0x9f, 0xf0, 0xce, 0x10, 0x0d, 0x32, 0x9f, 0xf7, 0xfe, 0xae, 0xbb, 0xf3, 0x58, 0x64, + 0x90, 0x03, 0x73, 0xf6, 0x15, 0x55, 0xdb, 0x3f, 0x2f, 0x92, 0xf9, 0xfe, 0xed, 0x87, 0x14, 0x1d, + 0xa3, 0x85, 0xc6, 0x9e, 0x9a, 0x6d, 0xb7, 0xe9, 0xab, 0x78, 0xfd, 0x34, 0xfe, 0x1e, 0x50, 0x06, + 0x31, 0x59, 0xe6, 0x57, 0x72, 0x25, 0x2b, 0xbb, 0xfe, 0x5f, 0x4f, 0x54, 0xd3, 0x6d, 0xbf, 0x86, + 0x14, 0x04, 0xfd, 0xe9, 0x2b, 0x6d, 0xcf, 0xd7, 0xaf, 0x37, 0x7f, 0x2c, 0x3a, 0xa0, 0xb5, 0xc7, + 0xad, 0xf4, 0xd3, 0xfe, 0xbc, 0x5b, 0x7f, 0xc3, 0xb8, 0x03, 0x1f, 0x87, 0xa4, 0x65, 0xef, 0x6d, + 0xfd, 0x38, 0xeb, 0x6c, 0x9e, 0x37, 0x7a, 0xe0, 0xd7, 0xf8, 0x61, 0x40, 0x0c, 0xbf, 0x50, 0xa5, + 0xdd, 0xe6, 0xa9, 0xd7, 0xd3, 0xfa, 0x45, 0x0c, 0x60, 0x04, 0x01, 0xae, 0x30, 0x37, 0x9a, 0xf2, + 0xe7, 0xf6, 0xdb, 0x6e, 0xff, 0xcb, 0x0e, 0x12, 0x04, 0x8f, 0x1c, 0x6f, 0xfd, 0x34, 0xf4, 0xd3, + 0xf5, 0x34, 0xff, 0x85, 0xdc, 0x00, 0xc6, 0x34, 0x13, 0xc1, 0x3f, 0xdd, 0xa6, 0x4e, 0xaf, 0x73, + 0x42, 0xd5, 0xb5, 0x34, 0x25, 0xe5, 0xcd, 0x2e, 0x1b, 0x70, 0x00, 0xee, 0xf5, 0xb0, 0x26, 0x44, + 0xb5, 0x5f, 0xd4, 0xcf, 0x05, 0xb8, 0xde, 0xdc, 0xf6, 0x05, 0xb3, 0xd8, 0x1c, 0x30, 0x6d, 0xf3, + 0xfa, 0x3b, 0x45, 0xd9, 0x78, 0x6f, 0x00, 0x0f, 0xf0, 0xf2, 0xee, 0x50, 0xb2, 0x81, 0x15, 0x7b, + 0x97, 0xff, 0xa8, 0x3d, 0x71, 0x2f, 0xbe, 0x84, 0xe2, 0x3c, 0xef, 0x65, 0x0f, 0x34, 0x55, 0xff, + 0x0e, 0xe0, 0x01, 0x24, 0x82, 0xd7, 0x20, 0xe2, 0x2b, 0x4e, 0x43, 0x5d, 0x04, 0xe9, 0x1f, 0xf3, + 0xfd, 0x47, 0xfe, 0x36, 0xf1, 0xff, 0x74, 0x0f, 0xfc, 0x5c, 0x06, 0x76, 0xed, 0xbd, 0x53, 0x58, + 0x73, 0x00, 0x1b, 0xe6, 0x15, 0x7c, 0x70, 0x20, 0xbe, 0x1e, 0xaf, 0x45, 0x77, 0x10, 0xf8, 0xce, + 0x7c, 0x6a, 0x5e, 0xb8, 0xff, 0x97, 0x69, 0xa6, 0x37, 0x2a, 0xaf, 0xf0, 0xf1, 0x20, 0x0f, 0xfe, + 0xb4, 0x33, 0x67, 0x14, 0x7d, 0x1c, 0x6a, 0x5f, 0x74, 0xcb, 0xcd, 0xeb, 0x77, 0xaf, 0xb7, 0x31, + 0xaf, 0xf0, 0xee, 0x00, 0x60, 0xb3, 0x74, 0xce, 0x0d, 0xf4, 0xa6, 0x6e, 0xc1, 0xd5, 0xcb, 0xe4, + 0xde, 0x7f, 0xa8, 0x3f, 0xed, 0xed, 0xed, 0xf9, 0xbb, 0xc8, 0xc5, 0x02, 0xfb, 0xae, 0xbc, 0x26, + 0xca, 0x04, 0x8f, 0x24, 0xdb, 0xfd, 0x6b, 0xf8, 0x6d, 0x90, 0x00, 0x44, 0xef, 0x46, 0x98, 0xf0, + 0x84, 0xdd, 0xe6, 0x65, 0x55, 0xd5, 0xd5, 0x45, 0xe6, 0xfc, 0x7b, 0x7b, 0xd6, 0xb0, 0xc2, 0x80, + 0x1d, 0x58, 0x48, 0xe0, 0x90, 0x34, 0x36, 0xcd, 0x4f, 0x2f, 0x8d, 0xd3, 0x5c, 0xa7, 0xa6, 0x98, + 0xf8, 0xee, 0x13, 0xc0, 0x68, 0x0f, 0x48, 0xf6, 0x8e, 0xb8, 0xaf, 0xe2, 0xb8, 0xaf, 0xf0, 0x9e, + 0x02, 0x6e, 0x69, 0x3d, 0xdf, 0xff, 0x7b, 0xc3, 0x6e, 0x01, 0x1b, 0x2c, 0x89, 0x1f, 0x51, 0xfe, + 0xed, 0xfc, 0x9f, 0xaf, 0x7f, 0xc2, 0xd8, 0x49, 0x13, 0xcd, 0x33, 0x4f, 0x2f, 0x75, 0x7f, 0x8a, + 0xef, 0x0e, 0xe0, 0x01, 0x5d, 0xe7, 0x0d, 0x3b, 0x05, 0x8c, 0x6e, 0xfc, 0x15, 0x0a, 0x04, 0xc0, + 0x29, 0x18, 0x2c, 0xdd, 0xcb, 0x15, 0xad, 0x2c, 0x6d, 0xfc, 0x5b, 0x2f, 0x2d, 0x65, 0x7f, 0xbc, + 0x66, 0x2b, 0x7b, 0xcd, 0xf3, 0xec, 0x39, 0x80, 0x1d, 0x8a, 0x7e, 0xc2, 0x7d, 0xa4, 0xf7, 0x34, + 0x14, 0xff, 0xd7, 0x76, 0xf9, 0x01, 0x31, 0x07, 0xa8, 0xe3, 0x1c, 0xfc, 0x38, 0x85, 0x57, 0x8c, + 0x04, 0x96, 0x86, 0x01, 0x24, 0xbe, 0xa9, 0xd9, 0x7f, 0x51, 0x56, 0x2a, 0xe1, 0xcc, 0x15, 0x1a, + 0x51, 0xd2, 0xcf, 0xb6, 0x1c, 0x06, 0x9a, 0x7f, 0x48, 0x41, 0xe0, 0x8e, 0xbf, 0xfe, 0xf6, 0x59, + 0x6b, 0xbe, 0xcf, 0x3e, 0x3d, 0xc4, 0x61, 0xda, 0xb1, 0x95, 0xe0, 0x0f, 0x94, 0x9a, 0x13, 0x1f, + 0x79, 0xc1, 0xd6, 0xc5, 0x21, 0xc1, 0x97, 0x5a, 0x3f, 0xd1, 0x29, 0x0d, 0x53, 0xb7, 0x97, 0x4b, + 0xdf, 0xbc, 0x32, 0xe0, 0x08, 0x0d, 0x0b, 0x96, 0x0c, 0xa4, 0xc5, 0xf8, 0x7f, 0xd3, 0x6f, 0x1f, + 0xfa, 0x8b, 0x69, 0xee, 0x0e, 0x2f, 0xd7, 0xac, 0x96, 0x1a, 0xc0, 0x03, 0x9f, 0x24, 0x66, 0xf2, + 0x91, 0x7e, 0xfe, 0x7b, 0xd6, 0xa9, 0xa6, 0x9e, 0x23, 0x43, 0x9d, 0x77, 0xe3, 0xb0, 0xde, 0x00, + 0x1e, 0xd8, 0x42, 0x7a, 0x0c, 0x4c, 0x8d, 0x96, 0xe8, 0xfd, 0xeb, 0x19, 0xe1, 0x40, 0x7e, 0x28, + 0xe7, 0x0d, 0x47, 0x46, 0x3d, 0x81, 0xa6, 0xc0, 0x76, 0xf9, 0x68, 0x7d, 0x02, 0xaa, 0x1d, 0x60, + 0x57, 0x19, 0xeb, 0xc6, 0xc7, 0x50, 0xf4, 0x52, 0xc4, 0x45, 0x18, 0xe3, 0x66, 0x0b, 0xf8, 0x37, + 0x71, 0xbd, 0x70, 0xde, 0x00, 0x4a, 0x1a, 0x91, 0x0c, 0x17, 0xf1, 0x29, 0x79, 0x46, 0x44, 0x48, + 0x09, 0xe2, 0xc8, 0x28, 0xab, 0x10, 0xe6, 0x0e, 0x7b, 0xde, 0xdd, 0x6d, 0x77, 0x84, 0x71, 0x26, + 0x67, 0x2e, 0xb9, 0x4a, 0x96, 0x49, 0x94, 0x24, 0xe9, 0x3a, 0x42, 0xd9, 0xb6, 0x31, 0x1f, 0x87, + 0x7f, 0x9f, 0x02, 0xa9, 0x06, 0x0f, 0xf2, 0x3b, 0xde, 0xef, 0xec, 0xbb, 0x39, 0xd1, 0xdf, 0xc3, + 0xc4, 0x80, 0x13, 0x88, 0xb7, 0xa4, 0x2c, 0x1a, 0xed, 0x1c, 0xb2, 0xb4, 0x1c, 0x90, 0x60, 0x7f, + 0xa6, 0x43, 0x01, 0xcf, 0x5e, 0x22, 0xfb, 0xda, 0x7b, 0xb0, 0xf3, 0x80, 0xe3, 0xc3, 0xe0, 0xb2, + 0xb4, 0x52, 0x85, 0xc3, 0xea, 0x0f, 0x66, 0x96, 0x0c, 0x34, 0xdc, 0xa8, 0x90, 0x7c, 0x41, 0xfc, + 0x2c, 0x5f, 0x96, 0x10, 0xeb, 0x81, 0x35, 0x40, 0xfb, 0xf7, 0xce, 0xad, 0xcb, 0xdb, 0x57, 0x6f, + 0x82, 0x19, 0x96, 0xbf, 0x86, 0x70, 0x01, 0xdf, 0xef, 0x6a, 0xb7, 0xef, 0x1f, 0xb6, 0xe9, 0xad, + 0x5d, 0xbe, 0x6f, 0xf9, 0x61, 0x65, 0x00, 0x3f, 0x1a, 0x48, 0x7e, 0x56, 0x49, 0xd7, 0xfc, 0xfd, + 0xbd, 0xb3, 0xf8, 0x75, 0x40, 0x05, 0xe4, 0xb8, 0x66, 0x2a, 0x47, 0x36, 0x7f, 0xfe, 0x0e, 0xa6, + 0x5e, 0xe3, 0x0d, 0x87, 0xcb, 0x77, 0xd2, 0x81, 0xf6, 0xb0, 0x3d, 0xc0, 0x2e, 0x25, 0x51, 0x2c, + 0x2f, 0xe0, 0x08, 0xc0, 0x06, 0x80, 0xd9, 0xe0, 0x0c, 0x00, 0xad, 0xca, 0x58, 0x33, 0xc1, 0xc3, + 0x8f, 0x76, 0x94, 0xf2, 0xe4, 0xb0, 0x6f, 0xe1, 0x1c, 0xd2, 0x3d, 0x8f, 0x1f, 0x0b, 0x60, 0x1a, + 0x96, 0xca, 0xc1, 0xa8, 0x51, 0xe2, 0x82, 0x08, 0x6f, 0xdb, 0x86, 0x3d, 0xd8, 0xe1, 0xbc, 0x00, + 0x6a, 0x2e, 0x32, 0x40, 0x45, 0x07, 0x5c, 0x19, 0x6f, 0x26, 0x0f, 0x3a, 0x00, 0xfa, 0x17, 0xa9, + 0x09, 0x79, 0x3f, 0x45, 0x38, 0x48, 0x7d, 0xac, 0x1d, 0x05, 0x78, 0x3f, 0x08, 0xcf, 0x35, 0xc5, + 0x30, 0xb5, 0x0a, 0x03, 0xc0, 0xff, 0xdb, 0xb1, 0x38, 0x70, 0xea, 0x80, 0x13, 0x5a, 0x31, 0x69, + 0xae, 0xdb, 0x83, 0x7f, 0xfc, 0xcf, 0x1c, 0xa7, 0x89, 0x1d, 0x7e, 0x18, 0xab, 0x06, 0x91, 0xa0, + 0xfb, 0x83, 0x84, 0xa8, 0x1e, 0x35, 0xa6, 0xcd, 0x3e, 0x3d, 0xdc, 0x38, 0xa0, 0x0b, 0xd7, 0xc6, + 0x8e, 0x87, 0xeb, 0xff, 0xff, 0x68, 0xed, 0xde, 0x77, 0x03, 0x6b, 0x19, 0x30, 0x07, 0x3f, 0x6e, + 0xbf, 0x8c, 0x49, 0xa4, 0xde, 0x9a, 0x7c, 0x38, 0xa3, 0x80, 0x03, 0x33, 0x96, 0x1d, 0xe9, 0xc8, + 0x00, 0xfc, 0xf0, 0x01, 0xdd, 0x33, 0xc0, 0x07, 0x4f, 0x00, 0x1d, 0xfd, 0xb6, 0xf6, 0xd7, 0xd2, + 0x4b, 0x86, 0x14, 0x04, 0xa2, 0xb1, 0xd9, 0xcb, 0xd3, 0x75, 0xb9, 0xc6, 0x4c, 0xde, 0xe4, 0xfa, + 0x69, 0xd8, 0xc3, 0x2a, 0x00, 0xce, 0xb3, 0x7e, 0x32, 0xf6, 0x7f, 0xb6, 0x1c, 0x7e, 0x58, 0xbc, + 0xf1, 0xd3, 0xc7, 0x69, 0xbd, 0xd3, 0x6d, 0xb4, 0xfd, 0x87, 0x54, 0x00, 0x5b, 0x1a, 0x2e, 0xa8, + 0x8a, 0x3c, 0xf3, 0x1a, 0x38, 0xdc, 0x71, 0xff, 0xac, 0xb7, 0x05, 0xca, 0x44, 0xdb, 0x74, 0xc2, + 0xde, 0xb1, 0x4a, 0x1c, 0x7e, 0x15, 0x8d, 0x86, 0xf0, 0xc8, 0xfa, 0x9c, 0x7d, 0x1c, 0x77, 0xc4, + 0x80, 0x20, 0x11, 0xb0, 0xb8, 0x60, 0x22, 0x8e, 0x01, 0xda, 0x90, 0xc0, 0x34, 0x9e, 0x00, 0x02, + 0xb4, 0x1a, 0x49, 0xe5, 0x19, 0x00, 0x2e, 0x9c, 0x28, 0x20, 0x6a, 0x8f, 0x00, 0x32, 0x16, 0x00, + 0x6a, 0x78, 0x00, 0xe1, 0x44, 0x00, 0xf8, 0xf0, 0x07, 0x95, 0x1d, 0x4b, 0x00, 0x31, 0xef, 0x0a, + 0xd5, 0x42, 0x4e, 0x34, 0x2b, 0x1a, 0xef, 0xf8, 0x6d, 0xc0, 0x0d, 0xfd, 0x64, 0x4c, 0x6a, 0x89, + 0xae, 0x1b, 0x3e, 0xaf, 0x6c, 0xfc, 0xb3, 0x52, 0xf2, 0x7c, 0x9d, 0x30, 0x1a, 0x5f, 0x13, 0xed, + 0xeb, 0x86, 0x70, 0x02, 0x0e, 0xe9, 0x76, 0x5f, 0xed, 0xfb, 0xd3, 0xa6, 0xbb, 0xfb, 0x0c, 0x12, + 0x01, 0x27, 0x32, 0x9d, 0xce, 0xef, 0xea, 0x9e, 0x4e, 0x99, 0xbd, 0x65, 0x3e, 0x19, 0x70, 0x03, + 0xf3, 0xd6, 0x5a, 0xb1, 0x4e, 0xdc, 0x9d, 0x6b, 0x4c, 0xbd, 0xbf, 0xa6, 0xf9, 0xf0, 0xe1, 0x20, + 0x02, 0x52, 0xce, 0x42, 0x94, 0x39, 0x68, 0x08, 0xd3, 0xf7, 0xb4, 0x14, 0x47, 0xe3, 0xf1, 0xae, + 0x7e, 0x76, 0x07, 0x4e, 0x35, 0x84, 0x5e, 0x2e, 0xc5, 0x1a, 0x22, 0xb0, 0x51, 0xa2, 0x0a, 0xc3, + 0xfb, 0x3c, 0x16, 0x50, 0x2c, 0xc6, 0x75, 0x9b, 0x5d, 0xbc, 0x3a, 0xe0, 0x12, 0x0a, 0x44, 0xe5, + 0x46, 0x47, 0xd7, 0x71, 0x52, 0x5e, 0x4c, 0x0a, 0x26, 0xa4, 0xea, 0xee, 0x6b, 0x69, 0x89, 0x68, + 0x2c, 0x38, 0xcf, 0x4f, 0x1a, 0x61, 0x3a, 0x10, 0x17, 0x41, 0x5e, 0x34, 0xa7, 0xda, 0xd7, 0x0c, + 0xe0, 0x0f, 0x6a, 0x64, 0xb5, 0xc9, 0xef, 0xff, 0xe5, 0x6c, 0x31, 0x80, 0x40, 0xfb, 0xd7, 0x3a, + 0xdf, 0xff, 0x6f, 0x6c, 0x29, 0x80, 0x45, 0xb7, 0x25, 0xf7, 0x7f, 0xf5, 0x4d, 0x69, 0x93, 0xf0, + 0xa1, 0x0a, 0x01, 0xdf, 0xfb, 0x9f, 0xfd, 0x34, 0xff, 0x86, 0xa4, 0x00, 0x20, 0x3f, 0xec, 0x5e, + 0xbe, 0x29, 0xfd, 0xdb, 0xe9, 0xa6, 0xda, 0xa6, 0x5f, 0x8b, 0x6c, 0x28, 0xa0, 0x07, 0x5e, 0xed, + 0x43, 0x79, 0x7a, 0x7b, 0x75, 0xaf, 0xc2, 0x98, 0x23, 0xfa, 0xb1, 0xee, 0xbf, 0xff, 0x85, 0x1c, + 0x01, 0xc7, 0x95, 0xcf, 0x3b, 0xe4, 0xe9, 0xfb, 0x6d, 0xde, 0x14, 0xc0, 0x22, 0x67, 0xaf, 0xfe, + 0xb7, 0xd3, 0x6f, 0x75, 0xfc, 0x3b, 0x80, 0x1c, 0xcb, 0x38, 0xa0, 0xbf, 0xe6, 0x2f, 0xdd, 0xd7, + 0xff, 0xf5, 0xbf, 0xf0, 0xc2, 0x81, 0x30, 0x2b, 0x27, 0x6a, 0x7f, 0x8a, 0xb1, 0x56, 0x9a, 0x7f, + 0x4e, 0xde, 0x58, 0x61, 0x40, 0x35, 0x54, 0x87, 0x6a, 0xa7, 0xd3, 0x4d, 0x6d, 0xa7, 0xe9, 0x9d, + 0x46, 0x17, 0x21, 0x42, 0x00, 0x86, 0x4d, 0x8b, 0x4d, 0x3d, 0x34, 0xff, 0xe2, 0xc3, 0x6c, 0x80, + 0x01, 0xbf, 0xcd, 0xb0, 0x50, 0x9e, 0x1b, 0xbf, 0xc7, 0xfb, 0xe6, 0x4e, 0xbd, 0x56, 0x61, 0x90, + 0x74, 0x33, 0xc0, 0xff, 0x15, 0x9f, 0xfb, 0x37, 0x77, 0xaa, 0xac, 0x2f, 0x80, 0x0d, 0x18, 0xa5, + 0x29, 0x60, 0x88, 0x12, 0xdf, 0x3e, 0x2b, 0x54, 0xf2, 0xf9, 0x6c, 0x6a, 0xe6, 0x51, 0xae, 0x46, + 0x5f, 0x8a, 0xef, 0x87, 0x09, 0x00, 0x20, 0xa3, 0xf3, 0xaf, 0x51, 0x5f, 0x7e, 0x45, 0x68, 0x97, + 0x14, 0xdc, 0x5d, 0xb1, 0x3f, 0xfd, 0xa3, 0xb3, 0x5b, 0xff, 0x0f, 0x12, 0x00, 0xdb, 0x62, 0x97, + 0x18, 0xa3, 0x2f, 0xdf, 0xd6, 0x9a, 0xc1, 0xff, 0x25, 0xf1, 0x7e, 0xaa, 0xab, 0x88, 0x7c, 0xbc, + 0x50, 0x1f, 0xd6, 0xf7, 0x86, 0xf0, 0x10, 0xdc, 0xd0, 0x4a, 0x37, 0x7f, 0xbf, 0x2b, 0xcd, 0xfe, + 0xa9, 0xfc, 0xdf, 0xeb, 0xe3, 0x59, 0xc0, 0x41, 0xa4, 0xeb, 0x93, 0xe1, 0x84, 0x60, 0x02, 0x7d, + 0x6c, 0xd0, 0x47, 0x36, 0xb5, 0x7c, 0xbe, 0x37, 0x4f, 0xfc, 0x5b, 0x61, 0xbc, 0x00, 0x52, 0xa7, + 0x88, 0xb0, 0x5c, 0x20, 0xf5, 0xd5, 0x5d, 0xbf, 0x15, 0xb6, 0x21, 0xed, 0xe6, 0xed, 0xbb, 0xbb, + 0x95, 0x19, 0x77, 0xeb, 0x0c, 0xe0, 0x04, 0xde, 0x27, 0x2c, 0x08, 0x4d, 0xbb, 0xb4, 0xee, 0xee, + 0xf9, 0x78, 0xb7, 0xe9, 0xa7, 0x2f, 0xec, 0x37, 0x80, 0x0f, 0x97, 0x1b, 0x04, 0x2b, 0xd0, 0x3b, + 0x7f, 0xf0, 0x6f, 0x30, 0xcd, 0xf5, 0x8a, 0xdd, 0xce, 0x1f, 0x9f, 0xf1, 0x3e, 0xa2, 0xb9, 0x9b, + 0xee, 0xba, 0xce, 0x8a, 0x13, 0xea, 0xf8, 0x85, 0x5c, 0x04, 0xc6, 0xc4, 0xb3, 0xb3, 0xe2, 0x18, + 0x7f, 0xf0, 0xdb, 0x20, 0x00, 0x14, 0xaa, 0x0f, 0x91, 0x50, 0x78, 0x3c, 0xf1, 0x0f, 0xad, 0x78, + 0x81, 0xe9, 0xbb, 0xa7, 0xc6, 0x33, 0x56, 0xbb, 0xf0, 0xdb, 0x80, 0x1f, 0xf8, 0x28, 0xbc, 0xf2, + 0xe5, 0xad, 0xd5, 0xd5, 0x6a, 0xdb, 0x9b, 0xe6, 0x96, 0xf7, 0x55, 0x75, 0x78, 0x79, 0x40, 0x43, + 0x1a, 0xaf, 0xd5, 0xe9, 0xdb, 0x6f, 0xa7, 0xa6, 0xdf, 0x69, 0xff, 0x0c, 0x28, 0x01, 0x8c, 0x12, + 0xa1, 0xaa, 0x15, 0x5f, 0x13, 0x11, 0xd6, 0xcb, 0x59, 0x36, 0x2a, 0xdb, 0x4d, 0x3e, 0x98, 0x3e, + 0xe3, 0xee, 0xf8, 0x79, 0x40, 0x09, 0xb6, 0x67, 0x8c, 0x52, 0x14, 0xff, 0xa7, 0x85, 0x59, 0x62, + 0xdb, 0x4c, 0x77, 0xef, 0xf1, 0x97, 0x64, 0xf1, 0xf9, 0x3a, 0xf7, 0xfb, 0x7e, 0x16, 0xc0, 0x23, + 0x24, 0x43, 0xb2, 0x88, 0x84, 0xaf, 0xfb, 0xf4, 0xc9, 0x52, 0x76, 0xf9, 0x92, 0xfb, 0xae, 0xbc, + 0xf5, 0x40, 0x3a, 0xb9, 0xfb, 0x6b, 0x0a, 0x60, 0x03, 0x28, 0x0f, 0x23, 0x1a, 0x94, 0x82, 0xa1, + 0xfe, 0xe5, 0x3c, 0x67, 0x0f, 0x80, 0xa2, 0x34, 0x4b, 0x10, 0x26, 0xf2, 0x2b, 0x5d, 0xac, 0x6b, + 0x30, 0x5d, 0xc3, 0x2a, 0x00, 0xa4, 0xf1, 0x1a, 0xc5, 0xac, 0x88, 0xdd, 0xfc, 0x5d, 0xb6, 0xd9, + 0xc7, 0xbe, 0x38, 0xdc, 0x76, 0xe3, 0xff, 0x55, 0x75, 0xbf, 0x4c, 0x6f, 0x89, 0x8f, 0x71, 0x9c, + 0x3a, 0xa0, 0x05, 0x9d, 0xc1, 0x95, 0x3f, 0x4a, 0x16, 0xdf, 0xff, 0xc4, 0xcd, 0x6f, 0x63, 0xa9, + 0x72, 0xd7, 0x7c, 0xbd, 0xb3, 0x9f, 0x65, 0xad, 0xb4, 0xd6, 0x27, 0xa7, 0xfe, 0x1d, 0xc0, 0x03, + 0x90, 0xac, 0x74, 0x43, 0x93, 0x8a, 0xf2, 0x3b, 0xf0, 0x28, 0x1a, 0x3b, 0x25, 0x0f, 0x47, 0xf2, + 0x92, 0x8e, 0x0b, 0x58, 0xe8, 0xfc, 0x56, 0xd8, 0x7d, 0xf2, 0x87, 0x5d, 0xa9, 0x2a, 0x80, 0x93, + 0x81, 0x6a, 0x31, 0xeb, 0xc9, 0xe1, 0xe7, 0x10, 0x94, 0x5b, 0xed, 0xe1, 0x43, 0xeb, 0x4e, 0xa9, + 0xae, 0xbb, 0xbd, 0xf7, 0xef, 0xf8, 0x65, 0x40, 0x20, 0x75, 0x1c, 0x7c, 0xf6, 0x9f, 0xfb, 0xbb, + 0x75, 0x7c, 0x2b, 0x80, 0x18, 0xf7, 0x90, 0x89, 0xfb, 0x1e, 0xe4, 0xe9, 0xc6, 0xcf, 0x1d, 0xbe, + 0x6b, 0x86, 0x70, 0x83, 0x2c, 0x15, 0xee, 0x3f, 0xff, 0xdb, 0xec, 0x3b, 0x80, 0x1f, 0xd0, 0xde, + 0x2c, 0x09, 0x96, 0x4b, 0xca, 0x78, 0xa0, 0x89, 0x01, 0x6d, 0x29, 0xf5, 0xdd, 0xc5, 0x63, 0xb7, + 0xc2, 0xbd, 0x14, 0x9c, 0xe0, 0xb0, 0x67, 0xe0, 0x58, 0x0e, 0x46, 0xd8, 0x12, 0x90, 0xa3, 0x89, + 0x69, 0xdf, 0x0c, 0xb8, 0x05, 0x5d, 0x89, 0x2a, 0x8f, 0x8b, 0x15, 0x79, 0xff, 0x6c, 0xdd, 0xba, + 0xcb, 0x36, 0xc5, 0xfe, 0x3e, 0x24, 0xf8, 0x07, 0x20, 0x06, 0x80, 0xda, 0x30, 0x00, 0x22, 0xb1, + 0x6d, 0xd2, 0x60, 0x05, 0x45, 0x85, 0xe0, 0x5e, 0x07, 0x53, 0x59, 0x38, 0xc2, 0xa2, 0xc7, 0x2f, + 0x53, 0xcf, 0x2a, 0xaa, 0x16, 0x60, 0x58, 0x47, 0x0b, 0xa4, 0x2f, 0xab, 0xa7, 0x71, 0x18, 0x42, + 0xee, 0x03, 0xda, 0x28, 0x6f, 0xee, 0x5f, 0xdf, 0x5f, 0xab, 0xe1, 0x8c, 0x05, 0xda, 0x49, 0x2e, + 0xff, 0xd7, 0xfb, 0x0a, 0xa8, 0x00, 0xe5, 0x5f, 0x3a, 0x6d, 0xf9, 0xd9, 0x7f, 0xa6, 0xa8, 0x96, + 0x13, 0x70, 0x03, 0x1b, 0xb5, 0xf6, 0xbf, 0xdf, 0xeb, 0x9e, 0x38, 0xbc, 0xdd, 0xb7, 0xf0, 0xf1, + 0x20, 0x09, 0xc1, 0x1a, 0x2f, 0xb6, 0x2c, 0x1f, 0xf3, 0x41, 0xc5, 0x65, 0xb1, 0x5b, 0x22, 0xce, + 0x2e, 0xe2, 0xb7, 0x71, 0x72, 0x11, 0xa8, 0x8b, 0xcb, 0x02, 0xff, 0x87, 0x89, 0x00, 0x5d, 0xe9, + 0x9e, 0x09, 0xcf, 0x85, 0x1f, 0xfe, 0xf4, 0xda, 0x9f, 0xe1, 0xdb, 0xc2, 0xad, 0xc3, 0x75, 0x9f, + 0xd6, 0x2f, 0x08, 0x4f, 0x96, 0xb4, 0x70, 0xfb, 0xba, 0xba, 0xc3, 0x6e, 0x00, 0xa4, 0x4a, 0x10, + 0xa9, 0x54, 0xd9, 0xa9, 0x6a, 0x53, 0x88, 0xc7, 0xd1, 0x6c, 0x7b, 0x62, 0xad, 0x56, 0xad, 0xa1, + 0x79, 0xe0, 0xc3, 0xe0, 0x56, 0x19, 0xb1, 0xc5, 0x4b, 0xf0, 0xe6, 0x00, 0xab, 0x8a, 0x7a, 0xc0, + 0x51, 0xdd, 0x39, 0xa0, 0x9b, 0x3b, 0x7d, 0xbd, 0x3d, 0x31, 0x6f, 0x16, 0xc9, 0xc3, 0x59, 0x73, + 0x83, 0x1d, 0x4b, 0x17, 0xf0, 0xf2, 0x80, 0x27, 0x03, 0x35, 0x5d, 0x8d, 0x3e, 0xa7, 0xfe, 0x6e, + 0x2d, 0x97, 0x76, 0xc5, 0xb0, 0x73, 0xfc, 0xbb, 0x69, 0x7c, 0x3b, 0x80, 0x10, 0x3c, 0x69, 0x27, + 0x7e, 0x76, 0x9e, 0xe9, 0x97, 0xe1, 0x5f, 0xf5, 0x3d, 0xf0, 0xf7, 0xc2, 0x97, 0xb7, 0x0e, 0xc6, + 0xd8, 0x72, 0xc2, 0x1e, 0x70, 0x02, 0x02, 0x2d, 0x05, 0x67, 0x58, 0x83, 0xdf, 0xd4, 0x20, 0x79, + 0xde, 0x73, 0xe3, 0xb7, 0x77, 0xb1, 0x59, 0x76, 0x28, 0x37, 0x7b, 0x89, 0xa4, 0xae, 0x7a, 0xe1, + 0xb7, 0x00, 0x94, 0x95, 0x80, 0xe9, 0x7f, 0x49, 0x64, 0xa2, 0x84, 0x8d, 0xf3, 0x8c, 0x31, 0x42, + 0x51, 0x49, 0x1c, 0x61, 0x51, 0xa7, 0x6c, 0x2a, 0x2b, 0xdf, 0x09, 0x92, 0x00, 0x75, 0x7d, 0x54, + 0x2e, 0xbd, 0xf5, 0xe9, 0xfe, 0x18, 0x50, 0x24, 0x54, 0x06, 0xe8, 0x57, 0x57, 0xa7, 0xad, 0x7f, + 0x58, 0x51, 0x40, 0x0e, 0xae, 0x4d, 0xa8, 0x1a, 0xb6, 0xb9, 0xff, 0x93, 0xa7, 0x3c, 0x53, 0xa5, + 0x09, 0xa8, 0x03, 0x8c, 0x9a, 0x39, 0x78, 0xbf, 0x74, 0xdb, 0x17, 0x75, 0x7b, 0xe1, 0x87, 0x00, + 0xcc, 0x72, 0xb6, 0x56, 0xdb, 0xcf, 0xdb, 0x6d, 0xb7, 0x27, 0xd5, 0xfb, 0xe1, 0x65, 0x02, 0x36, + 0x53, 0xfb, 0x8f, 0x57, 0xfd, 0x3b, 0x6d, 0xc2, 0x6a, 0x02, 0x3a, 0xae, 0xe3, 0xda, 0x74, 0xf6, + 0xf3, 0x76, 0xee, 0xdb, 0xc2, 0xea, 0x00, 0xa7, 0x17, 0x5c, 0x54, 0xe7, 0xb6, 0xdb, 0x75, 0xd5, + 0x31, 0x79, 0x79, 0x3b, 0x97, 0xd6, 0x15, 0xc0, 0x06, 0x2d, 0xe7, 0xa6, 0x2a, 0xf3, 0xfe, 0xb7, + 0xeb, 0x2f, 0x4e, 0xfd, 0xe1, 0x35, 0x00, 0x19, 0xbd, 0xdc, 0xd1, 0xbf, 0x4f, 0xf6, 0xee, 0xbf, + 0x0a, 0x38, 0x22, 0x1b, 0xbf, 0x5f, 0x27, 0x8c, 0x9e, 0x3e, 0xe6, 0xf5, 0xf8, 0x53, 0x00, 0x9d, + 0xf7, 0x20, 0xca, 0x66, 0xfd, 0xb7, 0x6f, 0x7a, 0x69, 0xf1, 0x18, 0x24, 0x0c, 0xab, 0x21, 0xbc, + 0x03, 0x9b, 0x43, 0x9a, 0xde, 0xfc, 0x84, 0x89, 0x12, 0x24, 0xeb, 0xb8, 0xce, 0x21, 0x36, 0x0c, + 0x8b, 0x6f, 0x8a, 0xe7, 0x7f, 0x7c, 0x2e, 0xe0, 0x01, 0xbb, 0xdb, 0x41, 0x6f, 0x9c, 0x12, 0x35, + 0xf2, 0x7c, 0x46, 0x1a, 0xc9, 0x02, 0x73, 0x87, 0xc0, 0xbe, 0xb1, 0x8b, 0x1b, 0x70, 0xe6, 0x00, + 0x39, 0x91, 0x63, 0x32, 0xe5, 0x45, 0x3e, 0xf2, 0xf4, 0xbf, 0x3d, 0x2a, 0xa6, 0x4e, 0xe2, 0x1f, + 0x18, 0xf7, 0xd8, 0xff, 0x78, 0x67, 0x00, 0x6b, 0x99, 0xa9, 0x0c, 0xe1, 0xbe, 0xff, 0x6a, 0xd8, + 0x9f, 0xbf, 0x8b, 0xe6, 0xee, 0x27, 0xf1, 0x8b, 0x2e, 0x19, 0xc0, 0x00, 0xa4, 0xd1, 0x03, 0x64, + 0xbc, 0x14, 0xa6, 0xe9, 0x34, 0xf2, 0xd0, 0xdc, 0x51, 0xd7, 0x3f, 0x97, 0xb6, 0x17, 0x97, 0x8c, + 0x62, 0xec, 0x35, 0x80, 0x09, 0xf7, 0xd8, 0xa2, 0xc1, 0x12, 0xdf, 0x7a, 0x99, 0xbe, 0x9a, 0x7c, + 0xac, 0x6b, 0xaa, 0xc5, 0x86, 0x59, 0xc7, 0x53, 0xff, 0xbf, 0xde, 0xe7, 0xf8, 0x66, 0x60, 0x02, + 0x6d, 0x4d, 0xb0, 0x8f, 0x3d, 0x75, 0x2f, 0xbe, 0x6e, 0x5f, 0xfc, 0xbe, 0xe5, 0xb0, 0xd6, 0x00, + 0x1c, 0xe3, 0x36, 0x89, 0x38, 0x0c, 0x49, 0x79, 0x66, 0xeb, 0xf8, 0x9f, 0xb6, 0xdc, 0xdd, 0xbd, + 0x33, 0x87, 0x70, 0x00, 0xe7, 0xa5, 0x07, 0x55, 0x13, 0x0b, 0x1e, 0x8b, 0xcb, 0xdd, 0xbe, 0x44, + 0xfc, 0x65, 0xfe, 0xea, 0x25, 0xe5, 0xae, 0x76, 0xfb, 0xaf, 0x09, 0xb8, 0x00, 0xca, 0xba, 0x4e, + 0x32, 0x04, 0xd7, 0x7b, 0xef, 0x9b, 0xfe, 0x25, 0xc0, 0x91, 0xc9, 0x4a, 0x43, 0x78, 0x01, 0x83, + 0x91, 0x64, 0xf2, 0xf7, 0x5b, 0xdd, 0x53, 0x59, 0x7d, 0xbb, 0x96, 0x40, 0x5e, 0xfe, 0x18, 0xc0, + 0x04, 0x8a, 0x36, 0x98, 0x1a, 0x0b, 0x97, 0x7f, 0xca, 0xda, 0x26, 0xdb, 0x73, 0x79, 0x44, 0xa5, + 0x9b, 0x7c, 0x9b, 0xeb, 0x16, 0x1d, 0xc0, 0x03, 0x63, 0xca, 0x89, 0xec, 0x28, 0x6b, 0x4d, 0xff, + 0xad, 0x97, 0xb7, 0xbf, 0xbb, 0xc6, 0xef, 0x22, 0xd8, 0xb7, 0x88, 0xa4, 0x31, 0x5d, 0xb4, 0xf4, + 0xe1, 0x85, 0x00, 0x25, 0x43, 0x9e, 0x09, 0x2b, 0xd7, 0xce, 0xf5, 0x53, 0x59, 0x8e, 0xd9, 0x35, + 0x9b, 0xb8, 0xab, 0x97, 0x8b, 0x1e, 0xc3, 0x2e, 0x00, 0x56, 0xf5, 0x67, 0xa1, 0x1f, 0x7b, 0xbd, + 0x9b, 0x8a, 0xb1, 0x57, 0xad, 0xdc, 0xbd, 0x34, 0xcd, 0x15, 0xf4, 0x3f, 0xe6, 0x4c, 0x32, 0xe0, + 0x00, 0xfd, 0xb6, 0x9d, 0xa1, 0xf6, 0xfb, 0xd2, 0xc3, 0x45, 0xf3, 0x68, 0xc4, 0x65, 0x56, 0x44, + 0x4f, 0x1d, 0x32, 0xcb, 0x96, 0xa8, 0xfe, 0x00, 0xf4, 0x00, 0x23, 0x01, 0x49, 0xfc, 0x2c, 0xc9, + 0xc3, 0xc2, 0xda, 0x87, 0x22, 0x39, 0x60, 0xb1, 0x96, 0xcf, 0x79, 0xc3, 0xcd, 0x56, 0xa7, 0x83, + 0x2c, 0x18, 0x97, 0x8a, 0x0c, 0xf1, 0xe3, 0x80, 0xc7, 0x00, 0xe1, 0xd7, 0x00, 0x62, 0x56, 0x63, + 0xbd, 0x18, 0x8f, 0xce, 0xbb, 0xd7, 0x6a, 0x87, 0xe5, 0x0b, 0xf6, 0x4e, 0x6d, 0xfe, 0xaf, 0x14, + 0x5f, 0x9d, 0x8a, 0x7b, 0x7a, 0xf0, 0xc2, 0x80, 0x36, 0xf7, 0x41, 0xb3, 0x2b, 0x1e, 0xfe, 0x23, + 0x16, 0xd3, 0x83, 0x9f, 0x96, 0x5b, 0xa7, 0xa7, 0x4d, 0x33, 0x7c, 0xc8, 0x79, 0x87, 0x94, 0x04, + 0xfe, 0x48, 0xee, 0xe6, 0xfe, 0x3a, 0xe9, 0xf6, 0xfc, 0x19, 0x98, 0xd5, 0x36, 0x34, 0xbf, 0xe1, + 0xcc, 0x00, 0x52, 0xfc, 0xe1, 0x39, 0xd4, 0x8d, 0xad, 0x9f, 0xbb, 0xbe, 0xb0, 0x77, 0xf4, 0xf6, + 0x9f, 0xe0, 0xdb, 0xe1, 0x8a, 0xcf, 0x37, 0x12, 0xa5, 0xed, 0xc3, 0x2e, 0x04, 0xcf, 0xee, 0x77, + 0xfa, 0xd9, 0x5f, 0xfb, 0x0a, 0x28, 0x0d, 0x7e, 0xde, 0x9b, 0xaf, 0x7f, 0xbd, 0xe1, 0x57, 0x00, + 0x32, 0xa9, 0x96, 0x08, 0x9d, 0x7f, 0xf2, 0xf9, 0x39, 0x3e, 0x4f, 0x9a, 0xd7, 0x0f, 0x60, 0x0d, + 0xb1, 0xdb, 0x29, 0xe9, 0x83, 0x1b, 0xbd, 0xab, 0x2d, 0x78, 0x5c, 0x14, 0x43, 0x8f, 0x1f, 0xce, + 0x7c, 0x41, 0x83, 0xa0, 0x29, 0xd2, 0x1a, 0xa0, 0x25, 0x2b, 0xdf, 0x83, 0xbc, 0x30, 0x04, 0x92, + 0x01, 0x29, 0x0a, 0x63, 0x71, 0x1f, 0xc9, 0x8e, 0x5b, 0x38, 0x3d, 0xce, 0x0f, 0xb7, 0x14, 0x18, + 0x87, 0x92, 0x8d, 0x0a, 0x86, 0x95, 0x0d, 0xb8, 0x00, 0x7a, 0x1f, 0xf1, 0x8b, 0xd8, 0xe4, 0xc1, + 0xcf, 0xfe, 0x2f, 0x6f, 0xa6, 0x73, 0xd4, 0xe1, 0x90, 0x0f, 0xed, 0x70, 0x3b, 0x3d, 0x52, 0xa9, + 0x47, 0xb2, 0x2a, 0x92, 0x27, 0x8c, 0x03, 0x83, 0xe6, 0x51, 0x20, 0x29, 0x01, 0xe6, 0xc0, 0x96, + 0x8b, 0x97, 0xca, 0xd2, 0x44, 0x07, 0x7f, 0x10, 0xd3, 0x81, 0x2f, 0x4f, 0x7d, 0x9a, 0xeb, 0xcf, + 0xf8, 0xee, 0xc3, 0x58, 0x05, 0x0e, 0xeb, 0x27, 0x17, 0x75, 0xa6, 0xdb, 0x7f, 0x54, 0xf5, 0x85, + 0x9c, 0x00, 0xe8, 0xf1, 0xe1, 0x5e, 0x1b, 0x61, 0xef, 0xb2, 0xa7, 0x27, 0xad, 0x3a, 0x70, 0xa2, + 0x84, 0x27, 0x35, 0xbe, 0x1f, 0xeb, 0xf5, 0x6c, 0xdf, 0xfe, 0x1e, 0xc0, 0x06, 0x94, 0x63, 0x6e, + 0xc2, 0xe6, 0x1d, 0xfa, 0x8a, 0x6e, 0xdb, 0xbb, 0x62, 0xb7, 0x77, 0x8d, 0x73, 0xeb, 0x8d, 0x72, + 0x58, 0x51, 0xc7, 0x83, 0x6f, 0xbe, 0x1d, 0xc0, 0x03, 0x94, 0x50, 0xe8, 0xf5, 0xe4, 0x7d, 0xfd, + 0x62, 0xb1, 0x0f, 0x6f, 0x2f, 0x79, 0xb7, 0xb7, 0x95, 0x6e, 0x6f, 0x65, 0x8f, 0x71, 0x53, 0xf1, + 0x42, 0xb8, 0x0e, 0xf0, 0x9a, 0x6f, 0x70, 0xee, 0xa9, 0xa7, 0x0e, 0x28, 0x00, 0xfe, 0x36, 0x61, + 0x2a, 0x73, 0x3a, 0xed, 0x85, 0x0c, 0x98, 0x79, 0x63, 0x1c, 0xdc, 0x5b, 0x2f, 0x58, 0xd3, 0xad, + 0xba, 0x9b, 0x8e, 0xdf, 0x23, 0x00, 0x6c, 0x83, 0xe8, 0xfa, 0xdb, 0x6e, 0x1c, 0x50, 0x01, 0x2b, + 0x46, 0x5d, 0xd6, 0x0c, 0xfd, 0x69, 0x34, 0xe5, 0xd2, 0xf6, 0xfb, 0x7e, 0x5f, 0x8f, 0xfe, 0x24, + 0xbf, 0x85, 0xb0, 0x04, 0x9a, 0x61, 0xdd, 0x58, 0x16, 0xbd, 0xff, 0xb3, 0x83, 0xb7, 0xfc, 0x30, + 0x76, 0xe2, 0xb2, 0xd6, 0xdb, 0x66, 0xf5, 0xc3, 0x8a, 0x00, 0x9f, 0x6c, 0x2a, 0xeb, 0x84, 0x59, + 0xcf, 0x76, 0x2b, 0xf8, 0x7f, 0xf8, 0x8e, 0x94, 0xae, 0xdf, 0xdf, 0x33, 0x76, 0xff, 0x86, 0xf0, + 0x04, 0x6c, 0x63, 0x76, 0x49, 0x8b, 0xdf, 0x5b, 0x23, 0xf1, 0xda, 0x0f, 0xb9, 0xcf, 0x26, 0x38, + 0x10, 0xf2, 0xce, 0xc1, 0x8b, 0xe1, 0x46, 0x5b, 0x8b, 0xd7, 0xe1, 0xb2, 0x40, 0x0b, 0x17, 0x99, + 0x04, 0xb7, 0x1b, 0xe7, 0x41, 0xa9, 0x68, 0x0c, 0x46, 0x80, 0x90, 0x0f, 0x52, 0xd2, 0xaf, 0x4b, + 0x2c, 0xe4, 0x53, 0x65, 0x64, 0x98, 0x5b, 0x32, 0x8a, 0xb9, 0x2b, 0x7f, 0x0c, 0xb8, 0x11, 0xd3, + 0x33, 0xe5, 0xe5, 0xba, 0xf6, 0x55, 0x7b, 0xeb, 0xec, 0x28, 0x8a, 0x08, 0x07, 0xc0, 0xcd, 0x4f, + 0x6d, 0xb4, 0xed, 0xff, 0x85, 0x91, 0x00, 0x25, 0xd5, 0xd9, 0xc5, 0x93, 0xbd, 0x7b, 0x7e, 0xb5, + 0x75, 0x66, 0xb0, 0xca, 0x80, 0x87, 0x0d, 0x10, 0xe2, 0x3f, 0xe6, 0xef, 0xb7, 0xe2, 0xc2, 0xd8, + 0x20, 0xbc, 0x0b, 0x42, 0x24, 0xee, 0xee, 0xde, 0xef, 0xef, 0xef, 0x3f, 0xe1, 0x3c, 0x04, 0x75, + 0x93, 0x0e, 0xfd, 0xfa, 0xbc, 0x9e, 0xb7, 0xbe, 0x19, 0xc0, 0x19, 0xff, 0x66, 0x62, 0xd0, 0xdb, + 0x7e, 0xa9, 0xfa, 0xfe, 0xc2, 0xb8, 0x0a, 0xe6, 0x14, 0xb5, 0x4d, 0xd7, 0xad, 0xbb, 0x2f, 0x6f, + 0xc2, 0x98, 0x02, 0xae, 0xb4, 0xf0, 0x29, 0xbf, 0x29, 0xa7, 0x4c, 0xbf, 0x6d, 0xbc, 0xdf, 0xc2, + 0xb8, 0x16, 0xa4, 0xd8, 0xe3, 0x2e, 0xb3, 0xf5, 0x71, 0x76, 0xdb, 0xe2, 0xfc, 0x27, 0x80, 0x89, + 0x2f, 0x69, 0x9a, 0x7f, 0x3f, 0x5e, 0xbc, 0x2d, 0x85, 0x63, 0x5b, 0xcb, 0xd6, 0x58, 0x2b, 0x61, + 0x77, 0x45, 0x2c, 0x2f, 0x09, 0xe1, 0x38, 0x18, 0x4d, 0x5f, 0xeb, 0xb7, 0xb6, 0xdc, 0x36, 0xe0, + 0x1d, 0xeb, 0xe8, 0x45, 0x07, 0xa7, 0x17, 0x64, 0x68, 0xdc, 0x97, 0x8b, 0xb8, 0xb8, 0xaf, 0x17, + 0x4d, 0xeb, 0x5f, 0xc3, 0x2a, 0x00, 0xc0, 0x8a, 0x2c, 0x58, 0x02, 0xfa, 0x8c, 0xea, 0xee, 0x73, + 0x02, 0xff, 0x15, 0xef, 0x7c, 0x2f, 0x80, 0x11, 0xb7, 0x9e, 0x81, 0x7f, 0x85, 0x29, 0x9f, 0x4e, + 0x6f, 0x58, 0xd5, 0x55, 0xb8, 0x55, 0xe3, 0x72, 0xf3, 0xfc, 0xbc, 0xdf, 0x0e, 0xe0, 0x02, 0x18, + 0x50, 0xae, 0x73, 0x8d, 0x24, 0x91, 0xff, 0x64, 0xcb, 0xd3, 0x2c, 0x67, 0xfa, 0xc8, 0x9f, 0x8a, + 0xee, 0xe7, 0xf8, 0xad, 0xdc, 0x14, 0x82, 0xa2, 0xfd, 0x78, 0x6d, 0xc0, 0x06, 0x7b, 0x9c, 0x27, + 0x83, 0x25, 0xed, 0xfb, 0xab, 0xc6, 0xf6, 0xd4, 0xff, 0x2f, 0xbc, 0x56, 0xfa, 0xd6, 0xf7, 0xc0, + 0x90, 0x01, 0x20, 0x0a, 0x44, 0x80, 0x01, 0x1e, 0x58, 0x00, 0xc4, 0x80, 0x01, 0x1e, 0x78, 0x38, + 0x24, 0x07, 0x09, 0x80, 0x00, 0x8a, 0x96, 0xc9, 0x81, 0x53, 0xc0, 0x07, 0x9e, 0x3c, 0xb0, 0x19, + 0xef, 0xb2, 0xde, 0x5e, 0x38, 0x00, 0x1f, 0x8e, 0x00, 0x04, 0xb0, 0xde, 0x00, 0x6f, 0xf7, 0xe0, + 0xa3, 0x8a, 0xe2, 0xaf, 0xfd, 0x33, 0xff, 0xd5, 0xdc, 0xde, 0x66, 0xb5, 0x1f, 0xff, 0xae, 0x19, + 0x65, 0x01, 0x1d, 0x26, 0x61, 0xaf, 0xa7, 0xff, 0x9a, 0x5c, 0x36, 0xc8, 0x00, 0x1d, 0xb8, 0x82, + 0x77, 0xd0, 0xe1, 0x07, 0xd1, 0xce, 0xe2, 0xb1, 0x0f, 0xac, 0x55, 0xdb, 0x72, 0xfb, 0x8f, 0x7c, + 0x7f, 0xc7, 0xbe, 0x3f, 0xe0, 0xe5, 0xc1, 0x95, 0x5d, 0xb7, 0xf0, 0xea, 0x80, 0x0d, 0xdb, 0x98, + 0x22, 0x85, 0x23, 0x60, 0xdd, 0x80, 0xed, 0xc5, 0x5b, 0xbe, 0x7b, 0xeb, 0x74, 0xd9, 0xc5, 0xb6, + 0x76, 0x71, 0x6c, 0x5b, 0xd3, 0xa3, 0xbf, 0xe9, 0xc3, 0x78, 0x08, 0x21, 0x6a, 0x23, 0x20, 0x04, + 0xff, 0x5b, 0x3b, 0xae, 0xbe, 0x5f, 0x2d, 0xf1, 0xf9, 0xd9, 0x1b, 0xf5, 0xae, 0x19, 0x67, 0x00, + 0x7b, 0x75, 0xfe, 0x7d, 0x6b, 0xfe, 0xf8, 0x68, 0x86, 0x00, 0x1c, 0xbb, 0x4f, 0x3f, 0x55, 0xf9, + 0x4f, 0xd4, 0xb1, 0xea, 0xb5, 0x14, 0x6a, 0x58, 0x93, 0xe5, 0x34, 0xee, 0x1e, 0x70, 0x04, 0xef, + 0x19, 0x2b, 0x18, 0x29, 0x0a, 0x1f, 0xfb, 0xd2, 0x57, 0xf0, 0x9f, 0x98, 0xcb, 0xc6, 0x55, 0x9a, + 0xa2, 0x74, 0x27, 0x3c, 0x3c, 0xa9, 0xf8, 0x70, 0xcf, 0xc1, 0x34, 0x2c, 0x7b, 0xfa, 0x70, 0xde, + 0x00, 0x10, 0x19, 0x48, 0xc6, 0x69, 0x9f, 0x7e, 0x95, 0x2e, 0xfe, 0xde, 0xee, 0xfe, 0xf7, 0xeb, + 0xe3, 0x51, 0x40, 0x46, 0xb7, 0x5d, 0x9d, 0x87, 0x64, 0x00, 0x2e, 0x91, 0x6d, 0x02, 0x84, 0x10, + 0xeb, 0x06, 0x07, 0x11, 0x51, 0x46, 0x1f, 0x41, 0xcf, 0xed, 0xbb, 0x41, 0x64, 0x5b, 0x05, 0xeb, + 0x50, 0x7f, 0xf7, 0xfd, 0x1f, 0x0f, 0x28, 0x00, 0xd4, 0x1a, 0xef, 0x81, 0xeb, 0x73, 0x48, 0xf9, + 0x59, 0x37, 0xe4, 0xc7, 0xe3, 0x89, 0x72, 0x33, 0x61, 0x03, 0xcc, 0x8f, 0x00, 0xa8, 0x33, 0xec, + 0x69, 0x0f, 0x25, 0x4b, 0x1b, 0xa6, 0x3f, 0xe7, 0x3a, 0xc2, 0x76, 0x96, 0xa8, 0x8e, 0x27, 0xcd, + 0x54, 0xd1, 0xb7, 0x0e, 0xe0, 0x2a, 0x80, 0x29, 0x68, 0x37, 0x45, 0x47, 0x1f, 0xb7, 0xe4, 0xe2, + 0x12, 0x29, 0x80, 0x75, 0x86, 0xfe, 0x98, 0xe2, 0x26, 0xa3, 0x72, 0x32, 0xa0, 0xaf, 0x0f, 0x4d, + 0x18, 0x00, 0xde, 0x16, 0xa8, 0xe7, 0xaf, 0xf1, 0x28, 0xd4, 0xb5, 0x30, 0xd2, 0x60, 0xe2, 0x2c, + 0xe9, 0xf6, 0xcd, 0x58, 0x68, 0x90, 0x7c, 0xa4, 0x89, 0x00, 0x91, 0x77, 0xe1, 0xeb, 0xcf, 0xd8, + 0x39, 0x98, 0x90, 0x7f, 0xd3, 0xff, 0xd6, 0x15, 0xc0, 0x1f, 0xf2, 0x6a, 0xd9, 0xff, 0xe9, 0xf8, + 0x51, 0x14, 0x00, 0xd0, 0x1b, 0x37, 0x7a, 0xcc, 0xa6, 0xdb, 0xf6, 0xdb, 0xff, 0x86, 0x51, 0x00, + 0x0d, 0x5d, 0x98, 0xbc, 0xed, 0xd9, 0xff, 0x6d, 0xbf, 0x6c, 0x55, 0xd7, 0x00, 0x7a, 0x00, 0xe4, + 0x6d, 0x44, 0x71, 0xe2, 0x17, 0x14, 0x38, 0x56, 0xa2, 0x8c, 0x56, 0x28, 0xc5, 0x19, 0x72, 0x22, + 0xc6, 0x2b, 0x03, 0x28, 0x6b, 0x62, 0xaf, 0xf8, 0x7b, 0x00, 0x30, 0x3b, 0x21, 0xfe, 0x9f, 0xb5, + 0x6f, 0x6f, 0x6d, 0xb8, 0x71, 0x1f, 0x8d, 0xec, 0xf7, 0x3b, 0x60, 0xed, 0xfe, 0x1d, 0x70, 0x08, + 0x3f, 0x78, 0x7e, 0x1f, 0x35, 0xfe, 0xb1, 0x4b, 0x47, 0xeb, 0xb7, 0xfc, 0x01, 0x5c, 0x00, 0xc8, + 0x1b, 0x14, 0xc5, 0xf2, 0x76, 0xea, 0x67, 0x00, 0x38, 0xf7, 0x6d, 0x47, 0x81, 0xf1, 0x72, 0xa1, + 0x75, 0x1a, 0x00, 0x06, 0x60, 0x50, 0x0a, 0x7c, 0x4b, 0x08, 0xae, 0x1d, 0x70, 0x04, 0x02, 0x50, + 0xa2, 0x9b, 0x62, 0x3e, 0xf3, 0x3c, 0xc7, 0x2f, 0x38, 0x60, 0x2e, 0x73, 0x06, 0xfe, 0xeb, 0xcd, + 0xe6, 0xfa, 0xba, 0xbf, 0x0c, 0x0d, 0x96, 0x01, 0x9a, 0x84, 0x49, 0x13, 0x86, 0x87, 0x80, 0x65, + 0x89, 0xf5, 0x57, 0x03, 0xdf, 0x71, 0x90, 0x2b, 0x1d, 0x65, 0x86, 0x2c, 0x81, 0xf1, 0xa3, 0x24, + 0x6a, 0x52, 0x5d, 0x67, 0x98, 0x69, 0x58, 0x1b, 0x80, 0x0c, 0x0d, 0x19, 0x84, 0x51, 0x3e, 0xf3, + 0xd8, 0x0d, 0x20, 0x38, 0x7c, 0x3d, 0x80, 0x3f, 0x98, 0xa3, 0x47, 0x71, 0x47, 0x57, 0xff, 0xfb, + 0xad, 0xb2, 0x61, 0xd3, 0xdb, 0x92, 0xba, 0x07, 0x42, 0x9c, 0xc9, 0xb9, 0x47, 0x16, 0x00, 0x58, + 0x50, 0x0f, 0xdb, 0xa7, 0xb4, 0x03, 0x2e, 0x07, 0x58, 0xb2, 0xd4, 0xfa, 0x6f, 0x3f, 0x8d, 0x43, + 0x78, 0x00, 0x85, 0x41, 0x77, 0x74, 0x38, 0xde, 0xfd, 0xf3, 0xdf, 0xbc, 0xf7, 0xcb, 0x0b, 0x07, + 0x0d, 0xf8, 0x39, 0xff, 0x81, 0xd9, 0x6d, 0xb7, 0x8a, 0xa0, 0xbc, 0xc4, 0x30, 0xe0, 0x1b, 0x72, + 0x36, 0xaa, 0xdf, 0x37, 0xae, 0xeb, 0xd7, 0x2c, 0x26, 0xe0, 0x50, 0x4d, 0x36, 0x97, 0x6f, 0xe5, + 0x81, 0xe0, 0xd8, 0x7c, 0x36, 0xa0, 0x06, 0x36, 0xec, 0xe5, 0xbf, 0xf6, 0xdb, 0x77, 0x99, 0xa1, + 0x7b, 0xea, 0x0b, 0xd7, 0xb5, 0xf1, 0xbe, 0xf8, 0x75, 0xc0, 0x09, 0xb0, 0x5d, 0x8b, 0xf0, 0xa7, + 0x15, 0xcd, 0x3e, 0xe5, 0xba, 0xae, 0xe5, 0xda, 0xa8, 0xee, 0xdf, 0xc7, 0x5f, 0x48, 0x51, 0x75, + 0x9e, 0xcf, 0xdf, 0xc7, 0x4f, 0x8e, 0x2f, 0x8b, 0xaf, 0xc1, 0xbb, 0x63, 0x8c, 0x57, 0x7d, 0x7f, + 0x0f, 0x38, 0x00, 0x7a, 0x5a, 0x09, 0x83, 0xc3, 0x35, 0x00, 0xd4, 0xcf, 0xc9, 0x97, 0x97, 0x65, + 0xbc, 0xb4, 0x73, 0xc7, 0xd8, 0x81, 0xf6, 0x5b, 0x2d, 0x93, 0x0f, 0x08, 0x78, 0xb9, 0x5e, 0x4d, + 0xeb, 0xde, 0x1e, 0x50, 0x01, 0x4e, 0xe0, 0x55, 0xc2, 0xa7, 0x83, 0x0f, 0xfd, 0x98, 0xda, 0x8e, + 0xdf, 0x6c, 0x4b, 0xdf, 0x8e, 0xc0, 0x5c, 0xc9, 0xcc, 0x0b, 0x64, 0xc2, 0xe0, 0xc7, 0xa8, 0xd4, + 0x09, 0xee, 0x00, 0xea, 0xe1, 0xc4, 0x46, 0x5f, 0xd6, 0x17, 0x70, 0x00, 0x5f, 0x1f, 0xf5, 0xdd, + 0x8d, 0x4b, 0x50, 0x80, 0xef, 0xdf, 0x11, 0xdf, 0x93, 0x9d, 0x2f, 0x70, 0x5e, 0xfa, 0xc0, 0x7d, + 0xd9, 0x7d, 0xde, 0x79, 0x30, 0xe6, 0x00, 0x5c, 0xac, 0x6a, 0x85, 0xe1, 0xbd, 0xf9, 0xcd, 0xde, + 0xb6, 0xdb, 0x6d, 0xb7, 0x0b, 0x38, 0x4d, 0xd1, 0xe1, 0x60, 0xfc, 0xa0, 0x6a, 0xa2, 0xb7, 0xfd, + 0xb8, 0x71, 0x40, 0x0c, 0xfb, 0x90, 0x66, 0x15, 0x19, 0x30, 0xfc, 0x5d, 0x8b, 0x78, 0xb6, 0x0b, + 0x4f, 0xc9, 0x9c, 0x03, 0xcd, 0xc5, 0x58, 0xef, 0xa7, 0x83, 0xb0, 0xa0, 0x38, 0x06, 0x83, 0x14, + 0xa8, 0x2a, 0xa2, 0x90, 0x5a, 0xa2, 0x4c, 0x26, 0x86, 0xa9, 0xc3, 0x2e, 0x02, 0x5f, 0xcd, 0x95, + 0x7f, 0xf7, 0xeb, 0x5f, 0xfa, 0x71, 0xf6, 0x19, 0x70, 0x0c, 0x4f, 0x50, 0x9d, 0x5f, 0xfd, 0xf7, + 0xf2, 0xc3, 0x58, 0x27, 0xb5, 0x7b, 0x7f, 0xff, 0xaf, 0x58, 0x65, 0xc0, 0x0f, 0xcf, 0xd4, 0x87, + 0x2f, 0xef, 0xba, 0xd1, 0x96, 0x17, 0xd1, 0x7b, 0xf0, 0x60, 0x01, 0x20, 0x0a, 0x46, 0x94, 0xee, + 0x37, 0x9c, 0xe4, 0x5f, 0x4d, 0x7a, 0xdd, 0xe5, 0x4b, 0xc4, 0x87, 0x09, 0xf0, 0xae, 0x08, 0x8e, + 0xd1, 0xdf, 0xff, 0x3f, 0xe1, 0x5c, 0x00, 0xc6, 0xd4, 0x3c, 0xaf, 0x7d, 0xca, 0xff, 0x8d, 0x61, + 0xde, 0x61, 0xeb, 0x86, 0x54, 0x10, 0x8a, 0x1b, 0xf7, 0xcb, 0xd6, 0x8a, 0xf7, 0xb6, 0x6e, 0xbc, + 0x58, 0x67, 0x00, 0x1d, 0xb7, 0x2c, 0x6b, 0xff, 0xef, 0xf8, 0xbd, 0xfb, 0x26, 0xdf, 0xb9, 0x20, + 0xc8, 0xd6, 0x16, 0x70, 0x02, 0xac, 0x2d, 0x6c, 0x8e, 0x25, 0x35, 0xee, 0xab, 0x9d, 0x5d, 0x61, + 0x9c, 0x00, 0x60, 0xe8, 0xdd, 0x94, 0x54, 0xf1, 0x5f, 0xc5, 0x71, 0x0c, 0x2b, 0x17, 0x2c, 0x32, + 0xc2, 0x98, 0x00, 0xbf, 0xb2, 0x1c, 0xd6, 0xe7, 0xdd, 0xf9, 0x5e, 0xfe, 0xdd, 0xd0, 0x45, 0xf0, + 0xc6, 0x02, 0x47, 0x22, 0x01, 0x8f, 0x9f, 0xcb, 0xe9, 0xff, 0x45, 0x58, 0x64, 0x90, 0x23, 0x09, + 0x6a, 0x33, 0xdf, 0xef, 0x3f, 0xfb, 0xe1, 0x7c, 0x00, 0x8d, 0x32, 0x04, 0x9b, 0x28, 0x7b, 0xb9, + 0x3b, 0x29, 0x33, 0x8d, 0x65, 0x45, 0xcb, 0x71, 0x5c, 0x7c, 0x77, 0x0c, 0x28, 0x03, 0x0c, 0x9b, + 0x82, 0x15, 0xae, 0xdb, 0xe5, 0xfa, 0x28, 0x9f, 0x1f, 0xc7, 0xef, 0x86, 0x70, 0x00, 0x84, 0x62, + 0x22, 0x0e, 0x94, 0xd4, 0xc5, 0x22, 0x65, 0xb2, 0xf3, 0x9e, 0x79, 0xee, 0xf2, 0xef, 0x2f, 0xef, + 0x2f, 0x4c, 0x14, 0xca, 0xe1, 0xe2, 0x40, 0x03, 0x6f, 0x65, 0x85, 0x95, 0xd0, 0x4b, 0xdf, 0x2d, + 0xdd, 0x5e, 0x72, 0x76, 0x76, 0x78, 0xe4, 0xe2, 0xd8, 0xfb, 0x95, 0x19, 0x7b, 0x7e, 0x1e, 0xc0, + 0x3f, 0x83, 0x23, 0x70, 0x74, 0x21, 0x7c, 0x9d, 0xdd, 0xdb, 0x77, 0x6c, 0x48, 0xfa, 0xcb, 0x7b, + 0x6e, 0xad, 0xf5, 0x7e, 0xbe, 0x15, 0x70, 0x0d, 0xd5, 0xfc, 0x48, 0x77, 0xcf, 0x5d, 0xf4, 0xd3, + 0xff, 0xc3, 0x0a, 0x00, 0x3d, 0x48, 0x1c, 0xc8, 0xa2, 0xd7, 0x9f, 0x4d, 0x83, 0xb7, 0xc5, 0x58, + 0xab, 0xfe, 0xdf, 0x58, 0x79, 0x40, 0x15, 0xd6, 0xc0, 0xd9, 0xdd, 0x97, 0x6f, 0x6d, 0xb6, 0xfe, + 0x4e, 0x98, 0xf2, 0x3a, 0x69, 0xed, 0xb7, 0xc3, 0x6e, 0x00, 0x67, 0x13, 0x04, 0x78, 0x14, 0xc6, + 0x2f, 0xf5, 0x53, 0x73, 0xfe, 0x66, 0x54, 0xdc, 0xff, 0xc4, 0xfc, 0xa9, 0x7a, 0x8a, 0x58, 0x17, + 0x7b, 0xfe, 0x18, 0x47, 0x01, 0x4d, 0x5e, 0x2a, 0x3d, 0xe8, 0xff, 0xff, 0xef, 0x88, 0x50, 0x20, + 0x2d, 0x0f, 0x95, 0x0b, 0x10, 0xc0, 0x26, 0xcc, 0x98, 0x79, 0xff, 0xfd, 0xb8, 0x77, 0x00, 0x08, + 0x00, 0x3e, 0xcf, 0xdf, 0x66, 0x21, 0xbb, 0xd8, 0xce, 0x89, 0xbe, 0x07, 0x97, 0x26, 0x74, 0x3b, + 0x42, 0x60, 0x1c, 0x1b, 0x9d, 0x5c, 0x7a, 0xba, 0xeb, 0x38, 0x1e, 0x6e, 0x78, 0xf1, 0xd4, 0x7b, + 0xee, 0x9d, 0xe1, 0xdc, 0x01, 0x51, 0xd8, 0x84, 0x5d, 0xda, 0x50, 0xed, 0xdf, 0x85, 0x77, 0x8a, + 0xfd, 0x9e, 0x06, 0x2f, 0x1a, 0x21, 0x55, 0x7a, 0xd7, 0x2b, 0xd6, 0x58, 0x79, 0x27, 0x47, 0xf0, + 0xd6, 0x4c, 0xdb, 0xeb, 0x6d, 0x15, 0xfd, 0x35, 0x5c, 0x29, 0x80, 0x59, 0xdd, 0x26, 0xef, 0xfd, + 0x34, 0xf4, 0xd3, 0x85, 0x65, 0x01, 0xc7, 0xb9, 0xaf, 0xff, 0x6f, 0xe2, 0x14, 0x0d, 0x3e, 0x7c, + 0xa1, 0x85, 0x00, 0x95, 0xda, 0xa0, 0xfc, 0x22, 0xf4, 0xc5, 0xbf, 0xfd, 0x8c, 0x38, 0xa0, 0x0e, + 0x0d, 0x6e, 0x7e, 0x77, 0x96, 0xb2, 0xd7, 0xff, 0xb7, 0xd3, 0xf8, 0x55, 0x48, 0x3c, 0x9f, 0xff, + 0xf8, 0x57, 0x05, 0x81, 0xb5, 0x2d, 0xbf, 0xff, 0xc2, 0xb8, 0x06, 0xac, 0x8d, 0xa4, 0xc9, 0xa7, + 0xff, 0xfc, 0x72, 0x20, 0x18, 0x61, 0xc8, 0xdf, 0x05, 0x38, 0xea, 0xbe, 0x5b, 0x14, 0x76, 0x84, + 0xbe, 0x24, 0x7c, 0x71, 0x8f, 0xc2, 0x98, 0x02, 0xb7, 0x0a, 0xda, 0x9f, 0x94, 0xfa, 0x74, 0xfd, + 0xb6, 0xf8, 0x71, 0x40, 0x06, 0x5b, 0x5c, 0xf0, 0x25, 0xaf, 0x71, 0xb6, 0xf2, 0xf7, 0xd3, 0x4d, + 0xba, 0x69, 0xdb, 0x15, 0x36, 0x2a, 0xff, 0x87, 0x30, 0x00, 0xc0, 0xa1, 0xe5, 0xab, 0x85, 0x8f, + 0x54, 0xdb, 0x69, 0x83, 0xfe, 0x7e, 0x3a, 0x2e, 0x73, 0x02, 0x70, 0xe3, 0x4c, 0x5b, 0x35, 0x45, + 0xb7, 0xa3, 0x8c, 0x5f, 0x2c, 0x1a, 0xdd, 0x0b, 0x1e, 0x58, 0x86, 0x1e, 0x0a, 0x40, 0x48, 0x8d, + 0x8a, 0x03, 0x3f, 0x38, 0x79, 0xe3, 0xd5, 0xbf, 0x9e, 0xe1, 0x63, 0x91, 0x54, 0xf6, 0xa3, 0x58, + 0x90, 0xbf, 0x99, 0x2b, 0xc0, 0x48, 0xc6, 0xec, 0xad, 0xe6, 0x4e, 0x70, 0xf2, 0xc0, 0x0c, 0x1e, + 0x70, 0xb8, 0x6c, 0x73, 0x03, 0xc0, 0x0c, 0x40, 0x79, 0xfd, 0x14, 0x33, 0xbc, 0x94, 0x01, 0xb8, + 0x32, 0xc5, 0xc4, 0xca, 0xae, 0x5f, 0x06, 0x90, 0x38, 0x90, 0x81, 0x59, 0xcd, 0xff, 0x82, 0x00, + 0x12, 0x03, 0x6c, 0x08, 0xea, 0x17, 0x17, 0xf3, 0x39, 0x7e, 0x0c, 0x80, 0xe9, 0x28, 0x40, 0x3a, + 0x1d, 0xe5, 0x9b, 0x39, 0xfe, 0xa5, 0x40, 0x95, 0x65, 0x91, 0x0f, 0x80, 0x1e, 0x31, 0x96, 0xf7, + 0x4c, 0x57, 0xc3, 0xaa, 0x00, 0x9f, 0xb0, 0xdd, 0xba, 0xe0, 0xa4, 0x37, 0xfb, 0x2b, 0xe0, 0xef, + 0x71, 0x38, 0xe0, 0x9f, 0x86, 0x28, 0x0b, 0x38, 0x7c, 0x0b, 0x1a, 0x60, 0x14, 0x8e, 0xb1, 0x51, + 0x7e, 0xc7, 0x1b, 0xa3, 0x7c, 0xa4, 0xbe, 0x01, 0xd0, 0x2d, 0x89, 0x18, 0x72, 0x5e, 0x31, 0x8e, + 0x43, 0x89, 0xd1, 0x80, 0xf9, 0x01, 0x60, 0x37, 0x5c, 0xec, 0xd3, 0x14, 0x62, 0x3e, 0xa1, 0x41, + 0x6a, 0x17, 0xdb, 0x15, 0x0f, 0xf2, 0xc3, 0x14, 0xcb, 0x0c, 0x5c, 0x10, 0x00, 0x05, 0xe6, 0x7e, + 0xb2, 0xfc, 0x2c, 0xe0, 0x3b, 0x89, 0xe9, 0xbd, 0xf2, 0xdc, 0x47, 0x5c, 0xbd, 0x5d, 0x74, 0xd9, + 0xbd, 0x34, 0xe1, 0xe2, 0x40, 0x07, 0x9c, 0x46, 0xe2, 0xa6, 0xd1, 0xc1, 0x3e, 0xb2, 0xed, 0xbd, + 0x95, 0x0b, 0x1c, 0x16, 0xf7, 0x09, 0x80, 0x2d, 0xf8, 0x24, 0x3d, 0x6f, 0x3c, 0x95, 0xe0, 0xd1, + 0xa5, 0x92, 0x8a, 0x01, 0xbe, 0xa7, 0xf8, 0x39, 0x03, 0x80, 0x52, 0x58, 0x0c, 0x3b, 0x9a, 0x8a, + 0x03, 0x3f, 0xc7, 0x6c, 0x8c, 0xb0, 0xc9, 0xc1, 0xc4, 0xf9, 0xe1, 0xe3, 0xbf, 0x2c, 0xcb, 0x00, + 0xe3, 0x11, 0xcc, 0x51, 0xce, 0x07, 0x10, 0x62, 0x14, 0x8b, 0x81, 0x8d, 0x74, 0x92, 0xd4, 0xf1, + 0x90, 0x92, 0xc8, 0x03, 0x08, 0x3e, 0x09, 0x7b, 0xe6, 0xc3, 0x67, 0x17, 0x54, 0x7e, 0x1c, 0x50, + 0x3b, 0x99, 0x01, 0x64, 0xb0, 0x82, 0x21, 0xfb, 0xbf, 0x55, 0x2c, 0x64, 0x21, 0x45, 0xf5, 0xa1, + 0x83, 0x67, 0x2d, 0x4f, 0xdb, 0x6b, 0x6d, 0xdd, 0x35, 0x98, 0x1d, 0x22, 0x14, 0xbc, 0xda, 0x3e, + 0xfc, 0x36, 0xe0, 0x0a, 0x31, 0x47, 0x7d, 0x78, 0xd1, 0xf0, 0xd7, 0xfc, 0x5a, 0xdb, 0x3b, 0xed, + 0x6b, 0x3b, 0xcb, 0x6a, 0x34, 0x3d, 0xe3, 0x5d, 0x5e, 0x0c, 0x7e, 0xa4, 0x07, 0xeb, 0xe1, 0xd5, + 0x00, 0x0c, 0xcc, 0xdd, 0xb6, 0x1a, 0x73, 0x7f, 0xfe, 0xbc, 0x57, 0x55, 0x5b, 0x6d, 0x96, 0xb5, + 0x27, 0xcf, 0x23, 0x67, 0xe9, 0xf0, 0xce, 0x01, 0x7b, 0xd8, 0x49, 0x7a, 0x7c, 0xca, 0xfe, 0x88, + 0x71, 0x5d, 0x6f, 0x61, 0x72, 0x5f, 0xdb, 0x2d, 0x0f, 0x52, 0xbf, 0xfa, 0xc3, 0xd8, 0x00, 0x76, + 0x29, 0x58, 0x94, 0xa8, 0xae, 0x6b, 0xff, 0x12, 0xa9, 0xb6, 0x95, 0xb2, 0xab, 0x93, 0x3c, 0x6a, + 0xeb, 0xa6, 0x05, 0x12, 0xac, 0x57, 0xcc, 0x24, 0xad, 0x05, 0x54, 0x8b, 0xc6, 0xb4, 0xf8, 0x4d, + 0xc0, 0x25, 0x0a, 0xfc, 0x30, 0x3f, 0xd1, 0x22, 0xa2, 0xd4, 0xde, 0x8a, 0xb2, 0x76, 0x5c, 0x32, + 0xa0, 0x0f, 0xf7, 0xa4, 0x96, 0xaf, 0xdb, 0x67, 0xf7, 0xba, 0xf6, 0x15, 0x50, 0x22, 0x6d, 0x21, + 0xfb, 0x7b, 0x97, 0xa7, 0xfd, 0x6b, 0x85, 0xb0, 0x21, 0xb5, 0x8b, 0xb7, 0x7b, 0xff, 0x5a, 0x7c, + 0x26, 0x48, 0x03, 0x5d, 0xbc, 0x8d, 0x5a, 0x5a, 0xde, 0xf5, 0x75, 0x7d, 0x56, 0x15, 0xc0, 0x11, + 0x8c, 0xb7, 0x54, 0x8a, 0xea, 0xeb, 0x56, 0xef, 0xab, 0x68, 0xb0, 0xaa, 0x80, 0x4e, 0x5c, 0x69, + 0x93, 0x6d, 0xc9, 0xcb, 0xd6, 0xdd, 0x11, 0x60, 0x5e, 0xbe, 0x15, 0x50, 0x04, 0x8e, 0x99, 0xa4, + 0x5f, 0x1a, 0x29, 0xbf, 0x6f, 0x5f, 0x6e, 0x18, 0xc0, 0x04, 0x95, 0xe4, 0x2f, 0x25, 0x67, 0xaf, + 0xfc, 0x2b, 0xc1, 0x79, 0x7d, 0xac, 0x5d, 0xcd, 0x04, 0xe3, 0x8b, 0xa6, 0x2f, 0x16, 0x19, 0x70, + 0x11, 0xd3, 0xc6, 0xba, 0x2b, 0xe9, 0xfd, 0xb0, 0xc2, 0x64, 0xad, 0x83, 0x22, 0xda, 0xb2, 0x5d, + 0xfb, 0xe1, 0x5c, 0x03, 0x4a, 0x44, 0x12, 0x2d, 0x69, 0xe7, 0x42, 0x59, 0xf6, 0xeb, 0x67, 0xdf, + 0x7c, 0x2c, 0xa0, 0x0d, 0xdd, 0x8a, 0x21, 0xb7, 0xc3, 0x77, 0x5a, 0x27, 0x7a, 0xd5, 0xdd, 0xb6, + 0xe1, 0x94, 0x70, 0x35, 0xea, 0x48, 0xc5, 0xff, 0xdb, 0x6f, 0x6d, 0xbe, 0xc2, 0xf3, 0x00, 0x10, + 0xcf, 0x1a, 0xc8, 0x02, 0x3a, 0xff, 0x6f, 0x4d, 0xd4, 0x56, 0xfd, 0x45, 0x6a, 0xf7, 0xc3, 0x38, + 0x08, 0xca, 0x99, 0x8b, 0x8b, 0xff, 0xbb, 0x4b, 0xc9, 0x87, 0x02, 0xe5, 0x8e, 0x55, 0x4d, 0xd4, + 0x57, 0x2c, 0x2b, 0x52, 0xf6, 0x17, 0x70, 0x02, 0xab, 0x14, 0x5d, 0x44, 0x58, 0x98, 0xf4, 0xd3, + 0xd7, 0xad, 0x66, 0x97, 0x0c, 0x28, 0x46, 0x9e, 0x11, 0x96, 0x2b, 0x5b, 0x6e, 0x4f, 0x74, 0xcb, + 0xfe, 0xf9, 0xd1, 0x14, 0x3b, 0x80, 0x0c, 0x04, 0x2d, 0x54, 0x90, 0x4b, 0x4a, 0xf2, 0x69, 0xc6, + 0x99, 0x3b, 0xf7, 0x72, 0xf6, 0xfa, 0xa7, 0x8c, 0xb7, 0xfe, 0x19, 0xc0, 0x08, 0x19, 0xf4, 0x11, + 0x68, 0xb2, 0xff, 0xc7, 0xbb, 0xee, 0x99, 0x43, 0x4e, 0x12, 0x35, 0xe1, 0xff, 0xdb, 0xfe, 0xc3, + 0x4a, 0x00, 0x6f, 0xc8, 0xd0, 0x40, 0x87, 0xf6, 0xba, 0x93, 0xc7, 0x29, 0xd6, 0xab, 0x58, 0xba, + 0x47, 0x0c, 0x12, 0x00, 0x52, 0xbb, 0x15, 0x23, 0xf3, 0xef, 0x37, 0xae, 0xdf, 0xfc, 0xb0, 0xab, + 0x28, 0x13, 0x31, 0xe7, 0xbe, 0x2e, 0xbf, 0xfd, 0xf0, 0xce, 0x09, 0xce, 0x96, 0xde, 0xff, 0xed, + 0xff, 0x7c, 0x46, 0x01, 0x8e, 0x64, 0x83, 0x43, 0x18, 0x03, 0x10, 0xda, 0xdb, 0x1d, 0xfe, 0xbe, + 0xdf, 0xff, 0xd8, 0x63, 0x09, 0xc2, 0xf4, 0x60, 0x51, 0x9d, 0x97, 0xfa, 0x7f, 0xfb, 0xe2, 0x30, + 0x08, 0x9b, 0x4d, 0x06, 0x7b, 0x78, 0xa5, 0x02, 0x5c, 0x4e, 0xa8, 0x51, 0xc0, 0x42, 0xfb, 0xa3, + 0xbf, 0xdf, 0x7f, 0x8a, 0x50, 0xde, 0xe2, 0x23, 0x30, 0xcc, 0x76, 0x13, 0xaa, 0xe3, 0xb1, 0xca, + 0x5b, 0x6c, 0x28, 0xa1, 0x1b, 0x4f, 0x9f, 0xff, 0x6f, 0x85, 0x9c, 0x09, 0x12, 0x86, 0x45, 0xed, + 0xfd, 0x7a, 0x78, 0x51, 0x90, 0x00, 0x8c, 0x17, 0xf1, 0x36, 0x2f, 0xbc, 0x9a, 0x7a, 0x69, 0xff, + 0x15, 0x77, 0x87, 0x94, 0x00, 0xd4, 0x01, 0xd2, 0xf0, 0x4f, 0xd5, 0xdd, 0xc9, 0xd3, 0x4f, 0xc5, + 0x58, 0xab, 0x1f, 0x52, 0xc5, 0x97, 0x53, 0x2c, 0x58, 0xa2, 0xc4, 0xb4, 0x22, 0x4b, 0x4d, 0x3d, + 0xb6, 0xe1, 0x85, 0x02, 0xa0, 0x61, 0x43, 0x7f, 0x7f, 0x6f, 0x6d, 0xba, 0x6d, 0xb6, 0x2d, 0x8a, + 0x5e, 0x7f, 0x85, 0x22, 0x47, 0x96, 0xc4, 0xbf, 0x7b, 0x4e, 0xb9, 0x4b, 0x32, 0xcc, 0x50, 0xc5, + 0xd4, 0x53, 0x14, 0xc6, 0x28, 0xca, 0x18, 0xc0, 0xc4, 0x94, 0x49, 0x3f, 0x6e, 0x9f, 0xff, 0xcc, + 0x3a, 0xa0, 0x11, 0x36, 0xb8, 0xb9, 0xbf, 0x39, 0xac, 0xbe, 0x9b, 0x6d, 0xfa, 0x56, 0x9f, 0xdf, + 0xf1, 0xbb, 0xac, 0x94, 0x38, 0x5d, 0x9a, 0x97, 0xd6, 0x2e, 0x73, 0xa3, 0x78, 0x12, 0xd0, 0xac, + 0x6d, 0xdd, 0xa8, 0xa5, 0x74, 0x60, 0x59, 0x00, 0xc4, 0x34, 0xdf, 0xa8, 0x8a, 0x8d, 0x61, 0x95, + 0x01, 0x83, 0xd4, 0xdb, 0xf5, 0x29, 0x15, 0xa8, 0xaf, 0xeb, 0xa2, 0xb9, 0x62, 0xc8, 0xe7, 0x3e, + 0x14, 0xeb, 0x51, 0x85, 0x9b, 0x3f, 0x4d, 0xf1, 0x58, 0xa3, 0x2d, 0x89, 0x79, 0x6c, 0x70, 0x00, + 0x33, 0x1d, 0xc3, 0xaa, 0x00, 0x1b, 0x36, 0xa2, 0x08, 0xe7, 0xa4, 0x62, 0xe8, 0xb0, 0x3b, 0x03, + 0x98, 0x28, 0xd2, 0xc9, 0xec, 0xbc, 0xb7, 0x67, 0x87, 0x07, 0x8b, 0x87, 0x83, 0xec, 0x2e, 0xe6, + 0xdc, 0x2a, 0x28, 0x3e, 0x1d, 0xc0, 0x0c, 0x49, 0x52, 0x13, 0x64, 0x40, 0x05, 0xbf, 0x1b, 0x84, + 0xbe, 0xbc, 0x7d, 0xeb, 0x6a, 0xfd, 0x7b, 0xc2, 0xa4, 0x12, 0x4e, 0xf7, 0xfe, 0x1a, 0x24, 0x04, + 0x70, 0x36, 0xf8, 0x12, 0x75, 0xba, 0xd7, 0x74, 0xdd, 0x34, 0xd3, 0xfa, 0x74, 0xd8, 0xc3, 0x4a, + 0x03, 0x8b, 0x64, 0x3c, 0x8f, 0xd6, 0xbf, 0x5f, 0xb6, 0xdb, 0x75, 0x86, 0x09, 0x00, 0x25, 0xa3, + 0xe2, 0x33, 0x1b, 0xeb, 0x9e, 0xf2, 0x6c, 0xff, 0x7b, 0xbe, 0x1d, 0x70, 0x03, 0xe1, 0x55, 0x57, + 0x72, 0x55, 0x2a, 0x12, 0x7f, 0xdc, 0x48, 0xe2, 0x3a, 0x60, 0xdb, 0x55, 0x1e, 0xfb, 0xb2, 0xb6, + 0xc4, 0xc3, 0x69, 0xb0, 0x4b, 0xe9, 0x8f, 0xf3, 0x0f, 0x62, 0xdd, 0x01, 0xa7, 0x03, 0x97, 0x29, + 0x51, 0x97, 0x4e, 0x9b, 0xb7, 0x0e, 0xe0, 0x16, 0x41, 0x5a, 0xb9, 0xb0, 0x98, 0x3e, 0x1e, 0xf2, + 0xb9, 0x61, 0xd8, 0x17, 0x55, 0xc0, 0xa0, 0xfd, 0x08, 0x37, 0x36, 0x37, 0x78, 0x15, 0x55, 0x83, + 0x1b, 0x56, 0x23, 0xf9, 0x51, 0x7c, 0xfa, 0xcf, 0xf9, 0xd1, 0x57, 0x93, 0xeb, 0xc2, 0xca, 0x02, + 0x6a, 0xd0, 0x4c, 0xe3, 0xa4, 0xfc, 0x68, 0x7a, 0x7a, 0xd6, 0xbe, 0xb8, 0x79, 0xc0, 0x0e, 0xe6, + 0xe8, 0x18, 0xc8, 0x97, 0x2f, 0xa3, 0x37, 0x15, 0xcf, 0x4c, 0x56, 0xa2, 0xb8, 0x12, 0x21, 0x33, + 0xfe, 0x0b, 0x37, 0xbe, 0x1a, 0x70, 0x06, 0x3f, 0x43, 0xb8, 0xbf, 0x39, 0x20, 0xf5, 0xee, 0xdb, + 0xbf, 0x44, 0xda, 0x9a, 0x03, 0xb6, 0x15, 0x50, 0x45, 0x43, 0x77, 0x6b, 0xfd, 0x7f, 0x0a, 0x38, + 0x02, 0x5f, 0xe9, 0x06, 0x92, 0xf5, 0x7d, 0xe8, 0x99, 0x2c, 0x5f, 0x83, 0x80, 0x30, 0x02, 0xbb, + 0x4d, 0x54, 0x5c, 0x5c, 0x6d, 0x54, 0xad, 0x5b, 0x8e, 0xe6, 0x43, 0xb8, 0x65, 0xc0, 0x08, 0xce, + 0x64, 0x3b, 0x3c, 0xd7, 0xfd, 0x5f, 0x17, 0x53, 0x43, 0x37, 0x52, 0xfb, 0xa1, 0xdf, 0x0c, 0xa8, + 0x00, 0xd9, 0xb5, 0x64, 0x69, 0xe6, 0xe7, 0xea, 0x7b, 0xab, 0xa9, 0xf8, 0x8c, 0x0f, 0xdb, 0x1a, + 0x61, 0x6e, 0x19, 0x02, 0xfa, 0xc2, 0x98, 0x09, 0xc9, 0x3c, 0x35, 0x40, 0xd5, 0xcc, 0x47, 0xa7, + 0x2f, 0x7e, 0xd9, 0xfe, 0xda, 0xa7, 0x85, 0x94, 0x02, 0x01, 0x5e, 0xd8, 0x7e, 0x37, 0xb5, 0x75, + 0x7f, 0xb9, 0x6b, 0x4e, 0xca, 0x65, 0x10, 0xa6, 0x00, 0x55, 0xe7, 0xc3, 0x4c, 0xc2, 0xcb, 0xac, + 0x90, 0x3f, 0x58, 0xf4, 0x4c, 0x9e, 0x14, 0x24, 0x01, 0x87, 0x4b, 0x7f, 0x6f, 0xcd, 0xdb, 0xd5, + 0xb6, 0xd9, 0x7e, 0xfc, 0x2a, 0xa0, 0x08, 0x52, 0x3c, 0x0a, 0x0a, 0xf4, 0x58, 0xd7, 0x4f, 0x4e, + 0x31, 0x8d, 0x90, 0xa6, 0x4f, 0xc3, 0x38, 0x01, 0x79, 0x59, 0x20, 0x25, 0x49, 0xdc, 0xca, 0x68, + 0xea, 0x8b, 0x1a, 0x6c, 0x9e, 0x5f, 0x15, 0xf6, 0x13, 0xc0, 0x25, 0xd8, 0x50, 0xf2, 0xf7, 0xfd, + 0x3d, 0x34, 0xf8, 0xd9, 0xc1, 0x74, 0xda, 0xc3, 0x46, 0x38, 0x6a, 0x60, 0x10, 0x2a, 0x06, 0xb5, + 0x79, 0x2c, 0x25, 0x85, 0x6a, 0xb6, 0xaf, 0xba, 0xc5, 0x84, 0xdc, 0x00, 0x85, 0xad, 0x53, 0x33, + 0x34, 0x90, 0x52, 0xff, 0xa9, 0x20, 0xb0, 0xab, 0xc3, 0x32, 0x80, 0xc1, 0x93, 0x22, 0xdf, 0x5a, + 0xbe, 0xff, 0x7c, 0x33, 0x20, 0x4a, 0x0e, 0xc8, 0x1c, 0xfb, 0x77, 0x6f, 0x4f, 0x4f, 0xfe, 0xb0, + 0xbb, 0x80, 0x0c, 0x99, 0x6c, 0x2e, 0x25, 0xdf, 0xec, 0xed, 0x97, 0xc7, 0x5a, 0xa6, 0x5f, 0x4f, + 0x2f, 0xe6, 0x30, 0x9b, 0x80, 0x32, 0x04, 0xdf, 0x17, 0xf1, 0xf5, 0x55, 0xe9, 0xaa, 0x93, 0xcc, + 0x2e, 0xe0, 0x03, 0x92, 0x6f, 0x15, 0x30, 0x56, 0x96, 0xbc, 0xbf, 0xee, 0x99, 0x7e, 0xf7, 0xc3, + 0x52, 0x87, 0x59, 0x6f, 0xfd, 0xb6, 0xf6, 0xdb, 0x9d, 0x85, 0x5c, 0x02, 0x5f, 0x3a, 0x0f, 0xcb, + 0xcf, 0xbd, 0xff, 0xe1, 0x79, 0x00, 0x0c, 0x0c, 0x1a, 0x2e, 0x84, 0x3b, 0x4d, 0xdf, 0xd6, 0xfd, + 0x7f, 0x23, 0x8d, 0x70, 0x11, 0xa9, 0x9a, 0x6f, 0x17, 0xb0, 0xe1, 0x20, 0x07, 0x1d, 0x92, 0x4c, + 0x72, 0xff, 0xff, 0xb6, 0xdb, 0x67, 0xe7, 0xef, 0xe5, 0x42, 0xef, 0xf7, 0x87, 0x30, 0x02, 0x18, + 0xb8, 0x83, 0x88, 0x11, 0xfb, 0xd7, 0xfd, 0x66, 0xeb, 0x77, 0xae, 0x9f, 0x6f, 0x09, 0xb2, 0x81, + 0x39, 0x68, 0x66, 0xbb, 0x3f, 0x4f, 0xff, 0x11, 0x81, 0x1d, 0xe2, 0xb6, 0x8d, 0x70, 0x09, 0xf3, + 0xf5, 0x5b, 0xbb, 0x12, 0xa1, 0xc0, 0xc1, 0x98, 0x85, 0x03, 0x41, 0xec, 0xa4, 0x76, 0xad, 0x8d, + 0xc0, 0xbb, 0xa2, 0x1b, 0xb1, 0x0a, 0x34, 0xca, 0x21, 0x40, 0x12, 0x3c, 0x87, 0x25, 0x79, 0x09, + 0xb8, 0x01, 0x0d, 0xa5, 0xb9, 0x96, 0x7f, 0xff, 0xff, 0x5a, 0xc3, 0xd2, 0x00, 0x17, 0xcf, 0x28, + 0xf0, 0xca, 0xc0, 0x9f, 0x3b, 0x1c, 0xf2, 0xdb, 0x83, 0xfe, 0xad, 0x96, 0x58, 0xb7, 0xb7, 0xf3, + 0xb0, 0x7f, 0x6d, 0xbf, 0xe1, 0xa2, 0x40, 0x3d, 0x84, 0x88, 0x55, 0x41, 0x56, 0xd8, 0xb6, 0x9f, + 0xed, 0xb7, 0xb6, 0x7e, 0x71, 0xf8, 0x30, 0x01, 0xe0, 0x0a, 0xa1, 0x83, 0xdf, 0x53, 0x64, 0x48, + 0x7b, 0x8e, 0x8b, 0x8a, 0xc7, 0x4b, 0x8e, 0x0c, 0x73, 0x87, 0x14, 0x00, 0xa0, 0x99, 0x21, 0xa0, + 0x76, 0x31, 0x3e, 0xc5, 0x58, 0x3b, 0x7a, 0x6d, 0xb6, 0x5b, 0xae, 0xe6, 0xf2, 0x6e, 0xee, 0x1f, + 0x38, 0xda, 0xe9, 0xff, 0x03, 0xc8, 0x2d, 0xb8, 0xae, 0xe2, 0x3e, 0x71, 0xf1, 0xc6, 0x39, 0xe0, + 0x51, 0x03, 0x08, 0x52, 0xfc, 0x57, 0x2a, 0xf5, 0x8b, 0xc5, 0x6e, 0xe2, 0xb1, 0xc6, 0x3f, 0x81, + 0x04, 0x04, 0xc0, 0x20, 0x85, 0x83, 0x4b, 0x26, 0xd1, 0xfd, 0xe2, 0xb1, 0x5f, 0x6c, 0x48, 0x70, + 0x31, 0x40, 0x38, 0xc4, 0x9b, 0xeb, 0xf8, 0x62, 0x0a, 0xed, 0xbf, 0x78, 0x76, 0x25, 0xa9, 0xde, + 0xd8, 0xe0, 0x00, 0x66, 0x35, 0x50, 0xf1, 0x20, 0x02, 0xf9, 0xe2, 0xe5, 0xe4, 0x08, 0x42, 0x7f, + 0xde, 0x0a, 0xe2, 0xb1, 0x73, 0xbd, 0xd4, 0x62, 0xc5, 0x62, 0x0f, 0x4c, 0xe3, 0x0b, 0x2f, 0xbc, + 0x16, 0x2f, 0xad, 0x20, 0xa3, 0xa4, 0xfc, 0x27, 0x80, 0x18, 0x1a, 0x0f, 0xe8, 0xf5, 0xf9, 0x7e, + 0xa9, 0xef, 0x5a, 0xe1, 0x95, 0x01, 0x00, 0x5a, 0x66, 0x7f, 0x95, 0x7f, 0x6d, 0xbf, 0xbc, 0xbf, + 0x2c, 0x36, 0xe0, 0x01, 0xa7, 0x0f, 0x0b, 0xb1, 0xb0, 0x40, 0xd6, 0xbf, 0xf7, 0x3d, 0xbf, 0x3f, + 0x2d, 0x41, 0xc6, 0xe5, 0x8c, 0x77, 0xe2, 0xaf, 0x1c, 0x19, 0xc5, 0x05, 0x95, 0x19, 0x74, 0xfe, + 0x1a, 0x24, 0x00, 0x86, 0x00, 0xcf, 0xa1, 0x9d, 0xc2, 0xdd, 0xef, 0xbe, 0x28, 0xb1, 0x45, 0x9f, + 0xf5, 0xb6, 0x29, 0x99, 0x60, 0x16, 0x80, 0x20, 0x85, 0x21, 0x71, 0xcc, 0xf0, 0x31, 0xc9, 0xe1, + 0xdc, 0x14, 0x26, 0x37, 0x40, 0x00, 0x5f, 0x95, 0x66, 0x34, 0x18, 0xe3, 0x0b, 0x80, 0x02, 0xa5, + 0xac, 0xf0, 0x71, 0xfc, 0xbe, 0x62, 0x2e, 0x0f, 0x38, 0xc0, 0x10, 0xc8, 0x0e, 0x80, 0xa4, 0xef, + 0xa8, 0x38, 0xc0, 0x12, 0x8f, 0x2e, 0x3c, 0xf8, 0x80, 0x07, 0x9c, 0x3c, 0xb0, 0x19, 0x48, 0x00, + 0x25, 0x1c, 0x8b, 0x92, 0x00, 0x01, 0x05, 0x29, 0x4a, 0x5b, 0x12, 0x38, 0xff, 0x9b, 0x30, 0x9b, + 0x80, 0x1b, 0x8a, 0x58, 0x83, 0xc3, 0x85, 0x45, 0x27, 0x37, 0x77, 0xd9, 0xba, 0xbb, 0xbb, 0xac, + 0xd6, 0x0e, 0xde, 0x6f, 0x0b, 0xe0, 0x05, 0x9e, 0x11, 0xdf, 0x1c, 0x24, 0x91, 0x53, 0x83, 0x17, + 0xd0, 0x66, 0xc1, 0x39, 0xed, 0xb8, 0xeb, 0x6c, 0xef, 0x52, 0xf1, 0x76, 0xc3, 0xd8, 0x0c, 0x12, + 0xd9, 0x5b, 0x5d, 0xb3, 0x2b, 0x7a, 0xfb, 0xe2, 0xb5, 0x89, 0xf8, 0x6d, 0xa4, 0x2f, 0xed, 0x2d, + 0x13, 0xeb, 0xf0, 0xcb, 0x80, 0x11, 0x75, 0x25, 0x63, 0x7a, 0xbe, 0x89, 0x6a, 0xcb, 0x6f, 0xb2, + 0xac, 0x2f, 0x80, 0x48, 0xda, 0x9d, 0xbd, 0x99, 0x3c, 0x56, 0xc9, 0x90, 0xae, 0x78, 0x9c, 0x30, + 0xa4, 0xfa, 0x5e, 0xde, 0xf8, 0x55, 0x40, 0x9a, 0x79, 0x03, 0xa1, 0xaf, 0x9a, 0xfd, 0x6d, 0x59, + 0x36, 0xed, 0xfe, 0x15, 0xc0, 0x20, 0x9a, 0xb3, 0x0d, 0xab, 0x6b, 0xf7, 0x17, 0x53, 0xc1, 0x69, + 0x16, 0xc5, 0xc5, 0x6b, 0x0a, 0xa8, 0x03, 0x24, 0xa9, 0xcb, 0xf9, 0xff, 0x8d, 0xe1, 0xde, 0xe5, + 0x91, 0x3a, 0xc2, 0xb5, 0xac, 0x31, 0x80, 0xbc, 0xf1, 0x55, 0x47, 0xbc, 0xde, 0xf8, 0xac, 0x5c, + 0xd0, 0x44, 0x5f, 0x15, 0xde, 0xb5, 0xc3, 0x0a, 0x61, 0x13, 0x84, 0xc4, 0xad, 0x45, 0xb8, 0xae, + 0x9c, 0x2d, 0xd9, 0x4f, 0x0d, 0x56, 0x13, 0x50, 0x02, 0x9e, 0x9f, 0xc8, 0x4e, 0xed, 0xe8, 0x95, + 0x12, 0xb9, 0xb8, 0xac, 0xfc, 0x3a, 0xe1, 0x35, 0x00, 0x30, 0x1e, 0x39, 0xb2, 0x7f, 0xeb, 0x54, + 0x5e, 0xc9, 0x97, 0x12, 0xc2, 0x68, 0x16, 0x05, 0xf0, 0xaa, 0x80, 0x26, 0x12, 0xce, 0x20, 0x92, + 0x46, 0xed, 0xf6, 0xdb, 0xb8, 0xac, 0x47, 0x8f, 0xe8, 0xa3, 0x17, 0xcf, 0x08, 0x61, 0x40, 0x08, + 0x7a, 0x6a, 0x4e, 0x75, 0x7d, 0x45, 0x76, 0x68, 0xb6, 0xf9, 0xa3, 0x96, 0x1a, 0x50, 0x20, 0x9e, + 0x24, 0x9c, 0xbb, 0x7b, 0x6d, 0xff, 0xe5, 0x9f, 0x04, 0x45, 0x87, 0x4d, 0x09, 0xe0, 0x0c, 0xa9, + 0x74, 0x08, 0x50, 0x7b, 0xe9, 0xaf, 0xd6, 0xb8, 0x59, 0xc0, 0x9b, 0x98, 0xd3, 0xb3, 0x7f, 0x4f, + 0xf7, 0xc2, 0xb8, 0x08, 0xc3, 0x63, 0xac, 0xff, 0xee, 0xdb, 0x6d, 0xb7, 0x16, 0xa0, 0x26, 0x66, + 0xa9, 0xb3, 0x61, 0x85, 0x00, 0x27, 0xcb, 0x8c, 0x27, 0x21, 0x5b, 0xbf, 0x7e, 0x5e, 0x5f, 0x15, + 0xfd, 0xef, 0xca, 0xe1, 0xe2, 0x40, 0x08, 0x3d, 0xb7, 0x0c, 0x83, 0x1f, 0xfb, 0x5b, 0xaf, 0xba, + 0xbd, 0x66, 0xed, 0x8e, 0xb3, 0x7f, 0xe1, 0x82, 0x40, 0x1d, 0xef, 0x60, 0xe0, 0xbf, 0xed, 0xb7, + 0xf9, 0x22, 0xfc, 0x36, 0xe0, 0x04, 0x97, 0x0d, 0xcc, 0xa0, 0xe3, 0x8f, 0xbd, 0x6c, 0xbe, 0xdb, + 0x6d, 0xb6, 0xcb, 0xce, 0x7c, 0x57, 0x77, 0x82, 0x90, 0x19, 0x46, 0xbd, 0xf0, 0xc2, 0x80, 0x15, + 0x06, 0xa3, 0xec, 0x58, 0xb1, 0xbe, 0xb1, 0x7e, 0xed, 0x89, 0xf9, 0xbb, 0xe1, 0x77, 0x00, 0x19, + 0x9f, 0x98, 0xbc, 0xf1, 0xfe, 0xef, 0xff, 0x9b, 0xcf, 0xff, 0xd3, 0xb8, 0x53, 0x00, 0x33, 0x36, + 0x8e, 0x2c, 0xbf, 0xff, 0x7d, 0xff, 0xf0, 0x07, 0x60, 0x06, 0x00, 0xa5, 0xc1, 0xd7, 0x87, 0xe5, + 0xe3, 0xa3, 0xc2, 0xc1, 0xbb, 0x09, 0x95, 0x0a, 0x82, 0xaa, 0x94, 0xb0, 0x06, 0x70, 0xe1, 0x61, + 0xc6, 0xdd, 0x8c, 0x60, 0x31, 0xa7, 0x0c, 0x28, 0x00, 0x85, 0x23, 0x12, 0xe5, 0x27, 0x97, 0xdf, + 0xe7, 0xae, 0x32, 0xf7, 0x70, 0x76, 0xf8, 0xbf, 0xa6, 0xaf, 0x1d, 0xd8, 0x6f, 0x00, 0x0d, 0xf6, + 0x60, 0xe1, 0x90, 0xf8, 0x1c, 0xa1, 0xd7, 0xe3, 0x79, 0xe7, 0xfc, 0xf3, 0xc1, 0xdb, 0x9b, 0x8e, + 0xae, 0x6f, 0x77, 0x8a, 0x93, 0xbf, 0xac, 0x27, 0x38, 0x13, 0xad, 0xe8, 0x72, 0xb6, 0xff, 0xff, + 0x1a, 0xa0, 0x62, 0xac, 0x5d, 0x87, 0x66, 0x00, 0x18, 0x63, 0x56, 0x8e, 0x82, 0xd2, 0xaf, 0xf7, + 0xfb, 0xb6, 0xe7, 0xe6, 0xf1, 0xdb, 0x83, 0xb7, 0x4c, 0xba, 0x7f, 0x0a, 0xb8, 0x03, 0x1f, 0x69, + 0x33, 0xba, 0x5f, 0xfb, 0x7f, 0x9d, 0xc0, 0x2b, 0xd5, 0xcc, 0x8a, 0x21, 0x41, 0x2d, 0x7e, 0x4e, + 0xe1, 0x54, 0xce, 0x2b, 0x29, 0x06, 0x21, 0xc7, 0x06, 0x2c, 0x69, 0x20, 0x1d, 0xe1, 0xd3, 0x1f, + 0x0a, 0x22, 0x82, 0xea, 0x78, 0xbd, 0xba, 0xff, 0xfc, 0x01, 0x08, 0x01, 0xa0, 0x12, 0x98, 0x56, + 0x2b, 0xdc, 0xa2, 0x4b, 0xc7, 0x06, 0x34, 0xe1, 0xec, 0x01, 0x55, 0x0a, 0x7a, 0x0b, 0x92, 0x74, + 0x8c, 0x85, 0xb6, 0xc4, 0x0f, 0x39, 0xf3, 0x27, 0x79, 0xde, 0xe7, 0x3e, 0x5e, 0xcf, 0x31, 0xa9, + 0xf7, 0xef, 0xe0, 0x82, 0x14, 0x9c, 0x7d, 0x9a, 0xf1, 0x71, 0x5a, 0x56, 0x2b, 0x14, 0x62, 0xb1, + 0x58, 0xa3, 0x15, 0xb8, 0xe0, 0x31, 0x80, 0x56, 0x03, 0x42, 0x0a, 0x62, 0x78, 0xa3, 0xcb, 0x0b, + 0x0e, 0x24, 0x70, 0x5f, 0x2c, 0x71, 0x5c, 0x70, 0x18, 0xe1, 0xc3, 0x98, 0x03, 0xf1, 0xfb, 0xb3, + 0xb0, 0xf8, 0xc6, 0x97, 0xbf, 0xc6, 0x9e, 0xe5, 0xb2, 0xf3, 0x9f, 0xf0, 0x7f, 0xf3, 0x22, 0xba, + 0xf7, 0xe1, 0xc5, 0x00, 0x32, 0x82, 0x91, 0x52, 0x8d, 0x3e, 0x51, 0x6e, 0x5a, 0xa2, 0xaa, 0x1e, + 0x5d, 0x93, 0x9e, 0x8d, 0x14, 0x65, 0x54, 0x62, 0xa9, 0xa7, 0xd7, 0x94, 0x03, 0x57, 0xb6, 0xde, + 0x6e, 0x9f, 0x0d, 0xe0, 0x02, 0xc9, 0x67, 0x26, 0x3d, 0x21, 0x61, 0x6e, 0x72, 0xda, 0xce, 0x3d, + 0x85, 0xd5, 0xd9, 0x43, 0x60, 0x75, 0x73, 0xc6, 0x12, 0xe2, 0xc0, 0x29, 0x89, 0x59, 0xa4, 0x2d, + 0x10, 0xec, 0xf0, 0x7e, 0x5e, 0x4a, 0xfc, 0x2b, 0x80, 0x21, 0x58, 0xe9, 0xe8, 0x40, 0xbb, 0xb7, + 0xef, 0xba, 0xeb, 0x0d, 0x38, 0x00, 0xe6, 0xb8, 0x6c, 0x9c, 0x74, 0x2b, 0xbb, 0xe2, 0x5e, 0x7e, + 0x7b, 0xfb, 0xbd, 0xbd, 0xf8, 0x07, 0x40, 0x40, 0xd8, 0xd5, 0x80, 0x7c, 0x7b, 0xcf, 0x70, 0xb6, + 0xb9, 0x4b, 0x38, 0x81, 0xfe, 0x61, 0x7a, 0xb9, 0x29, 0x51, 0xdb, 0x49, 0x85, 0x4b, 0x0c, 0x74, + 0xb0, 0x28, 0xfa, 0x02, 0x76, 0xc4, 0x0e, 0xc1, 0xef, 0xfc, 0x31, 0x80, 0x1e, 0x69, 0xcd, 0x32, + 0x03, 0x77, 0xeb, 0x25, 0xee, 0xf6, 0x5e, 0x77, 0xe4, 0xa6, 0x58, 0x55, 0x40, 0x03, 0xe2, 0xbc, + 0x96, 0x2a, 0x53, 0x1e, 0xe5, 0x59, 0xc8, 0xc7, 0x6e, 0x5d, 0xc6, 0x3b, 0x72, 0x8c, 0xad, 0xfd, + 0xa6, 0xbd, 0x9c, 0x3a, 0x48, 0x01, 0x04, 0x99, 0x59, 0x24, 0x03, 0x1d, 0x73, 0x9f, 0xe1, 0xeb, + 0xb2, 0x65, 0x06, 0x52, 0xa2, 0xf8, 0x71, 0x7c, 0x51, 0x75, 0xac, 0xc6, 0x4f, 0xa6, 0x4e, 0xb1, + 0x90, 0x71, 0x4e, 0xdf, 0xe0, 0x3a, 0x40, 0x44, 0x05, 0x23, 0x8a, 0xfc, 0x1e, 0x2f, 0x8a, 0xef, + 0x2c, 0x0c, 0x4f, 0x04, 0x1c, 0x38, 0x38, 0xb2, 0x4a, 0xb3, 0x07, 0xfe, 0x0a, 0x41, 0x00, 0x53, + 0x5a, 0xaa, 0x93, 0xe2, 0xe2, 0xea, 0x96, 0x31, 0xeb, 0x44, 0x03, 0x83, 0x28, 0x01, 0xa8, 0x58, + 0x00, 0x13, 0x8e, 0x63, 0xb8, 0x6d, 0xc0, 0x04, 0xb3, 0x92, 0x0b, 0xc4, 0x53, 0xb6, 0xe5, 0x27, + 0x18, 0xe9, 0x39, 0xa3, 0x67, 0x8c, 0x3d, 0x72, 0xdc, 0x57, 0x05, 0x27, 0xa4, 0x53, 0x5c, 0x15, + 0x2f, 0xe1, 0x9c, 0x06, 0x83, 0x25, 0x08, 0xbb, 0xad, 0x95, 0xe8, 0x9d, 0xdc, 0xb0, 0xaa, 0x9a, + 0x0f, 0x86, 0x70, 0xc8, 0x74, 0xec, 0x97, 0xaf, 0x75, 0x5e, 0x7b, 0x0d, 0x28, 0x46, 0x29, 0xc5, + 0x49, 0x04, 0x5a, 0xd5, 0xdb, 0xba, 0xa2, 0x45, 0x52, 0xd8, 0x55, 0x40, 0x99, 0x6c, 0xc0, 0x3f, + 0x35, 0x65, 0xb9, 0x20, 0x58, 0x6a, 0xe8, 0xbd, 0x5e, 0x13, 0xc0, 0x8b, 0xff, 0x87, 0xec, 0xfa, + 0x52, 0xbb, 0xd9, 0x5e, 0x78, 0x59, 0x3b, 0xa2, 0xc3, 0x18, 0x00, 0xd7, 0x52, 0xc3, 0x22, 0x97, + 0xdf, 0x85, 0xc5, 0x62, 0xe2, 0xb7, 0x57, 0x56, 0xc1, 0xdf, 0xc4, 0xb0, 0xe4, 0x84, 0x96, 0x1e, + 0xc0, 0x0a, 0x34, 0x3a, 0x9b, 0xcb, 0x9f, 0x9c, 0xb6, 0xf2, 0x42, 0x92, 0x2b, 0xee, 0x37, 0xae, + 0x5e, 0xa6, 0xa8, 0xbf, 0xc3, 0x2a, 0x00, 0x77, 0xbc, 0x69, 0x48, 0xbe, 0xe8, 0x56, 0x3b, 0x42, + 0x2a, 0x55, 0xe1, 0xb3, 0xe9, 0xe0, 0xb6, 0x58, 0x17, 0xb6, 0x07, 0x61, 0xd8, 0x69, 0x40, 0x07, + 0x7a, 0x7b, 0xe9, 0x36, 0xff, 0xa8, 0xe9, 0xc0, 0xbc, 0x99, 0xc5, 0xf7, 0x34, 0x1f, 0x09, 0xb9, + 0xe0, 0xa5, 0xb8, 0xe6, 0x17, 0x50, 0x07, 0x2e, 0xa1, 0xd2, 0x7a, 0x3a, 0x96, 0x72, 0xdc, 0x12, + 0x70, 0x7b, 0x0b, 0x2f, 0x6c, 0x07, 0xa8, 0x07, 0xeb, 0x0b, 0xf0, 0xab, 0x1e, 0x48, 0x36, 0xee, + 0x3e, 0xc3, 0x0a, 0x00, 0x32, 0x71, 0x79, 0xf8, 0x91, 0x3f, 0xbc, 0xc8, 0x57, 0x2f, 0x29, 0x93, + 0xf0, 0xb6, 0xa4, 0xfd, 0x3c, 0x95, 0x42, 0xee, 0x00, 0x3e, 0x9a, 0x1a, 0xec, 0x52, 0xe2, 0xdf, + 0xee, 0xd8, 0x97, 0xdb, 0x6d, 0xf5, 0x85, 0x70, 0x0b, 0x0f, 0x46, 0x89, 0x9e, 0xff, 0x7b, 0xeb, + 0x58, 0x59, 0x40, 0x88, 0xcd, 0xa3, 0xda, 0x34, 0x1d, 0x5f, 0xd7, 0xfc, 0x52, 0x82, 0xa2, 0x7d, + 0x0d, 0xb8, 0x03, 0x44, 0xf3, 0xc0, 0x92, 0x7a, 0xf7, 0x7b, 0xef, 0x7f, 0x18, 0xc4, 0x55, 0x6b, + 0x7b, 0xe1, 0x55, 0x00, 0x31, 0x3b, 0x9f, 0x93, 0xbe, 0xe9, 0xf5, 0xff, 0xe1, 0x9c, 0x01, 0x6c, + 0xd0, 0x36, 0xf2, 0x3f, 0xed, 0xd7, 0xef, 0x86, 0xdc, 0x00, 0xae, 0x99, 0xc8, 0xc6, 0xbb, 0x67, + 0x72, 0xfb, 0xfd, 0xef, 0x57, 0xca, 0xaf, 0xba, 0xf0, 0xbc, 0xa0, 0x9a, 0x9e, 0x9b, 0xef, 0x7f, + 0xbf, 0x58, 0x5d, 0x98, 0x00, 0xab, 0x4d, 0x1b, 0xae, 0xde, 0xde, 0xf7, 0xbd, 0xd7, 0x4d, 0x3f, + 0x38, 0x30, 0x04, 0x20, 0x8c, 0xa7, 0xf7, 0xf8, 0xd2, 0x87, 0x00, 0x02, 0x18, 0x7a, 0x40, 0x02, + 0x5d, 0x8a, 0x75, 0x39, 0xac, 0xf8, 0xdd, 0xb6, 0xcd, 0xf6, 0xfa, 0x75, 0x8b, 0xf2, 0xbe, 0xeb, + 0xac, 0x52, 0x28, 0x54, 0x53, 0x61, 0xc9, 0x00, 0x00, 0xdb, 0x2e, 0x06, 0x47, 0xc3, 0x16, 0x42, + 0xbc, 0x43, 0xc7, 0xbe, 0xe7, 0x3f, 0xe2, 0xbb, 0x8f, 0xfa, 0xf7, 0xf0, 0x43, 0x0a, 0x45, 0xc5, + 0xeb, 0x51, 0x71, 0x4e, 0xa0, 0xef, 0xf1, 0xd3, 0xea, 0xef, 0x71, 0xa5, 0x0e, 0x00, 0x04, 0x30, + 0xdb, 0x84, 0x0a, 0x27, 0xff, 0x2b, 0xde, 0xb1, 0x7b, 0xde, 0xaa, 0xb1, 0xdb, 0x7b, 0xfc, 0x4c, + 0x48, 0x35, 0x96, 0x2b, 0x0f, 0x95, 0x6c, 0x02, 0x20, 0x01, 0x20, 0x0a, 0x08, 0x3f, 0x25, 0x02, + 0xa2, 0x8d, 0xba, 0x70, 0x1e, 0x1d, 0x46, 0xa7, 0x70, 0xbc, 0x50, 0x76, 0x28, 0xc5, 0x7a, 0x51, + 0x46, 0x0a, 0x60, 0x9f, 0x01, 0xf2, 0x08, 0x42, 0x90, 0xec, 0x35, 0x3c, 0x00, 0x1c, 0x3c, 0xe0, + 0x76, 0xd4, 0x50, 0x01, 0x8a, 0x00, 0x33, 0xc0, 0x70, 0xf0, 0x07, 0x0f, 0x0f, 0x26, 0x0a, 0x94, + 0x52, 0x9e, 0x00, 0x1e, 0x1d, 0xa5, 0x3d, 0xc2, 0x60, 0x02, 0xa4, 0xc5, 0x43, 0xe7, 0x1a, 0x54, + 0x26, 0xe0, 0x03, 0x3b, 0x74, 0x68, 0x3d, 0x2b, 0xfd, 0xbb, 0xbf, 0xe2, 0x30, 0x63, 0xcb, 0x85, + 0x99, 0xc0, 0x24, 0xcf, 0x24, 0x37, 0xff, 0xff, 0x4d, 0x3e, 0x37, 0x05, 0x95, 0x01, 0x7b, 0x0a, + 0xa8, 0x64, 0x33, 0xd7, 0xff, 0xa7, 0xe2, 0xb0, 0xfb, 0x95, 0x09, 0xe0, 0x46, 0x6f, 0x9c, 0xdf, + 0xd3, 0xfe, 0xf0, 0xaa, 0x80, 0x25, 0x6a, 0xac, 0xd7, 0xeb, 0xe6, 0xef, 0xff, 0xc2, 0xaa, 0x00, + 0x6e, 0xd5, 0xb4, 0x3e, 0x7d, 0xdb, 0x4f, 0xff, 0xc2, 0xaa, 0x02, 0xec, 0x8d, 0xef, 0x7f, 0xa6, + 0xff, 0x76, 0xf0, 0xaa, 0x84, 0x86, 0x7e, 0x9f, 0xe9, 0xfe, 0x9d, 0x70, 0x73, 0x0a, 0x11, 0x45, + 0xea, 0x2e, 0xbd, 0x37, 0x8a, 0xef, 0x1c, 0x18, 0xfe, 0x00, 0xbc, 0x01, 0x88, 0x2a, 0xdc, 0x5e, + 0xf7, 0x15, 0xda, 0x8b, 0x8e, 0x31, 0xce, 0x18, 0x50, 0x09, 0x52, 0x3e, 0x37, 0x3f, 0xab, 0xf2, + 0x8a, 0xef, 0x4d, 0xb0, 0x76, 0xe9, 0xe9, 0xdf, 0x0f, 0x60, 0x04, 0xb7, 0xde, 0x0f, 0x1b, 0xca, + 0xa0, 0x96, 0x07, 0x67, 0x0e, 0x3c, 0x1a, 0x28, 0xc1, 0x3b, 0x3f, 0xc6, 0x9c, 0x2b, 0xe4, 0xa4, + 0x71, 0xb2, 0x91, 0x53, 0xd3, 0xf8, 0x65, 0xc0, 0x02, 0x7d, 0x1a, 0xdd, 0x1a, 0x17, 0x05, 0xd7, + 0xd3, 0x4e, 0x9c, 0x69, 0x8b, 0x82, 0x98, 0xbf, 0xec, 0x35, 0x80, 0x11, 0x4f, 0x91, 0x01, 0x63, + 0x80, 0x29, 0xe4, 0x9e, 0x9a, 0x69, 0xda, 0x63, 0x1f, 0x5a, 0x9f, 0x83, 0xaf, 0xbf, 0xdd, 0x34, + 0xeb, 0x00, 0x43, 0x11, 0xb8, 0x38, 0xa8, 0x3a, 0x82, 0x70, 0x00, 0xf0, 0x0f, 0xec, 0x65, 0xb3, + 0xc0, 0x00, 0x94, 0x0d, 0x50, 0x43, 0x3b, 0xca, 0x08, 0x4b, 0x18, 0xde, 0x7c, 0x48, 0x00, 0x54, + 0xb8, 0xb0, 0xbd, 0xa7, 0x0e, 0x01, 0x83, 0xc0, 0x20, 0x19, 0xea, 0x65, 0xf7, 0xf8, 0x08, 0x10, + 0x88, 0xdd, 0xb2, 0x61, 0xc2, 0xb5, 0x54, 0xe4, 0x53, 0x29, 0xb0, 0x88, 0x00, 0x56, 0x61, 0xfb, + 0xc8, 0x95, 0x56, 0x61, 0x60, 0x3b, 0x08, 0x8b, 0x80, 0x30, 0x0d, 0xc1, 0xcb, 0xff, 0x86, 0xf0, + 0x02, 0xfd, 0x59, 0xae, 0x4c, 0x2e, 0xfe, 0xb5, 0x3f, 0x9a, 0xb8, 0x78, 0x3e, 0xa4, 0x4a, 0x1e, + 0x1d, 0x92, 0x9e, 0x83, 0xbe, 0x17, 0xa4, 0x56, 0xff, 0x9f, 0xc3, 0x98, 0x04, 0x2c, 0x72, 0x65, + 0xbc, 0x81, 0x57, 0xff, 0x6c, 0xa9, 0xb8, 0x70, 0xfe, 0x7a, 0xc7, 0x7e, 0x76, 0xbb, 0xf8, 0x35, + 0xb0, 0xc8, 0xc6, 0x84, 0x7c, 0x7e, 0x83, 0xfe, 0x2e, 0x57, 0x9f, 0x04, 0x07, 0xe3, 0x21, 0xe6, + 0xe9, 0xeb, 0x58, 0x69, 0xc0, 0x10, 0x82, 0x1c, 0xc2, 0xd2, 0x20, 0xf7, 0xd5, 0x9b, 0x31, 0xeb, + 0xed, 0xd8, 0x97, 0x83, 0xbf, 0x3d, 0xf6, 0xdd, 0xbb, 0xf9, 0x6f, 0x07, 0x5f, 0x1c, 0x31, 0xdc, + 0x36, 0xe0, 0x03, 0xbf, 0xd8, 0x15, 0xf4, 0xae, 0xdf, 0xd8, 0x51, 0xc4, 0xe6, 0x06, 0x2c, 0x9b, + 0x7a, 0xc3, 0xbb, 0x67, 0x9b, 0x9f, 0x85, 0x9f, 0x86, 0x01, 0xd8, 0xc5, 0xc8, 0xf5, 0x0f, 0x86, + 0x70, 0x02, 0x9c, 0xdf, 0x85, 0x12, 0x35, 0xec, 0x95, 0xd0, 0x24, 0x65, 0xcd, 0x07, 0x3b, 0xec, + 0x90, 0x2d, 0xc2, 0x63, 0x0d, 0x12, 0x01, 0x5e, 0xbe, 0xa4, 0xdb, 0xbb, 0xd6, 0x2e, 0xeb, 0x65, + 0xda, 0xd1, 0x5e, 0xcd, 0xb0, 0xb3, 0x80, 0x37, 0xd6, 0x32, 0x5a, 0x67, 0x5e, 0x2a, 0x42, 0xba, + 0x39, 0xe1, 0x15, 0xab, 0x26, 0x50, 0xc6, 0x00, 0x54, 0xb7, 0xc2, 0x8a, 0xe9, 0x6a, 0x68, 0xdd, + 0xeb, 0xdf, 0xb3, 0x32, 0x61, 0xac, 0x04, 0xc0, 0x6d, 0x8f, 0x27, 0x2f, 0x9a, 0x16, 0x55, 0x92, + 0x17, 0xbe, 0xb0, 0xd2, 0x80, 0x19, 0x0f, 0x87, 0x88, 0xbc, 0xdf, 0x17, 0xdb, 0x60, 0xdf, 0x39, + 0x58, 0x4d, 0xed, 0x96, 0xf1, 0x78, 0xbb, 0xe1, 0x55, 0x00, 0x39, 0xcc, 0x74, 0xd6, 0xcd, 0xd7, + 0x7e, 0xc9, 0xcb, 0xf7, 0x27, 0xdb, 0x58, 0x5d, 0xc0, 0x04, 0x3c, 0xe8, 0xe3, 0x0b, 0x7f, 0xf7, + 0x4b, 0x07, 0xb9, 0xb3, 0x40, 0x3b, 0x78, 0x78, 0x91, 0xea, 0x4e, 0x3a, 0xe0, 0xce, 0x3a, 0x70, + 0xec, 0x27, 0x80, 0x12, 0xd5, 0xd1, 0x30, 0x1b, 0xbe, 0x2b, 0xad, 0x62, 0xfe, 0xc8, 0x90, 0x34, + 0x3c, 0x20, 0x18, 0x0a, 0x63, 0x0a, 0x0d, 0x30, 0x65, 0xbb, 0x4c, 0x2f, 0x57, 0x1a, 0xa0, 0x54, + 0x69, 0x25, 0xe7, 0x9e, 0x23, 0xce, 0xe0, 0xe6, 0x38, 0x0f, 0x0c, 0x01, 0x64, 0x29, 0x68, 0x2c, + 0x2a, 0x5f, 0x9e, 0x0e, 0x1e, 0x03, 0x97, 0x9c, 0x62, 0xb2, 0xfc, 0xb1, 0x97, 0x8e, 0x63, 0x83, + 0x86, 0x70, 0x9d, 0xd9, 0xc0, 0x7d, 0x8b, 0x2f, 0xed, 0xb7, 0x54, 0x44, 0x87, 0xe5, 0x84, 0xf1, + 0xd3, 0xc6, 0xbf, 0x5a, 0xfe, 0x17, 0xc1, 0x35, 0x35, 0xb2, 0x3f, 0xd6, 0xbf, 0x7c, 0x27, 0x84, + 0x7e, 0xb6, 0xef, 0xff, 0xf0, 0xd3, 0x86, 0x80, 0x53, 0x6a, 0xea, 0xf3, 0x7d, 0x5d, 0x5e, 0xb5, + 0x96, 0x16, 0xc0, 0x8a, 0x9c, 0x85, 0xfc, 0xdd, 0x7e, 0xae, 0xdf, 0xe1, 0x9c, 0x01, 0x83, 0xe2, + 0x4b, 0xc5, 0xfc, 0xdf, 0xff, 0x6f, 0x96, 0x18, 0x24, 0x01, 0xb3, 0x4c, 0xc2, 0xd7, 0x7f, 0xfb, + 0xa7, 0xc9, 0xb0, 0xb2, 0x82, 0x55, 0x3c, 0xef, 0xfd, 0x7d, 0xe1, 0x7c, 0x00, 0xb7, 0x68, 0x83, + 0xc8, 0x42, 0xff, 0x2f, 0xe5, 0xed, 0x9b, 0xd4, 0x9e, 0x39, 0xec, 0xc2, 0xca, 0x00, 0x71, 0xf9, + 0x16, 0x77, 0x2e, 0x9e, 0x9f, 0x6c, 0xff, 0x6f, 0x0d, 0xe0, 0x07, 0x7b, 0x8a, 0x61, 0x97, 0xf3, + 0xff, 0x7b, 0xdd, 0xdd, 0xb1, 0x59, 0xbc, 0x5b, 0xf5, 0xe1, 0x47, 0x2e, 0x7f, 0xa6, 0x9f, 0x4d, + 0x3e, 0x1c, 0xc0, 0x04, 0x17, 0x93, 0x47, 0x8e, 0xe6, 0xfb, 0xde, 0xdb, 0xee, 0xa9, 0xb9, 0xaf, + 0x7e, 0x17, 0x70, 0x06, 0xc5, 0x7f, 0x88, 0xf0, 0x7f, 0x9b, 0xdf, 0xee, 0x0f, 0xb8, 0xff, 0xbc, + 0x7f, 0xcb, 0xc6, 0x6c, 0x2e, 0xe0, 0x1a, 0x99, 0xa4, 0xd2, 0xdb, 0x6f, 0xfb, 0x7f, 0x58, 0xb7, + 0x02, 0x15, 0x16, 0x0b, 0xe2, 0x48, 0x70, 0x8b, 0x14, 0xce, 0x14, 0x46, 0x04, 0xc2, 0xe9, 0xe9, + 0x7f, 0xee, 0x6f, 0xf8, 0x0a, 0x80, 0x28, 0x85, 0x2e, 0xe5, 0x81, 0xc4, 0x70, 0x9a, 0xa5, 0x48, + 0xd4, 0xb3, 0x2e, 0xdf, 0x77, 0x17, 0x16, 0xd2, 0x06, 0x46, 0xa0, 0xa0, 0x63, 0x0a, 0x86, 0xdc, + 0x04, 0xc9, 0x4f, 0x10, 0xc5, 0xc9, 0xdd, 0x65, 0x7d, 0x56, 0x35, 0xf3, 0xc9, 0x7b, 0xd6, 0xb8, + 0xa9, 0xc3, 0x39, 0xbe, 0x25, 0xc2, 0x66, 0x3c, 0x88, 0x73, 0x88, 0xc4, 0x48, 0x08, 0xe7, 0xcd, + 0x54, 0x46, 0x06, 0x6e, 0x5e, 0x25, 0x40, 0x89, 0xcf, 0x8e, 0x85, 0x54, 0x06, 0x7e, 0x4b, 0xff, + 0xfb, 0xc4, 0x60, 0x81, 0x49, 0x73, 0xf0, 0x09, 0xc8, 0x31, 0x05, 0x51, 0x5e, 0xb8, 0xba, 0xaa, + 0xe3, 0x83, 0x1c, 0xe1, 0x97, 0x04, 0xc3, 0xb5, 0xd5, 0xff, 0x7d, 0x3f, 0xf7, 0x00, 0x9c, 0x83, + 0x80, 0x47, 0xc5, 0x6e, 0x38, 0x31, 0xf8, 0x57, 0x00, 0x33, 0x2e, 0xec, 0x5d, 0xd7, 0x2f, 0xa6, + 0xbe, 0x9d, 0xbf, 0x00, 0xa4, 0xc1, 0x49, 0x02, 0xa1, 0x52, 0xc0, 0x38, 0x89, 0x82, 0x3e, 0xcc, + 0xbd, 0xe3, 0x83, 0x1c, 0xe1, 0x44, 0x50, 0x09, 0x3e, 0xad, 0x1f, 0x6d, 0x5f, 0xfb, 0x7b, 0x7e, + 0x00, 0x9c, 0x20, 0xa8, 0x98, 0x1c, 0x1c, 0x75, 0xe5, 0x80, 0x01, 0x98, 0xa0, 0x00, 0x66, 0x06, + 0x24, 0x1f, 0x16, 0x00, 0x06, 0xf8, 0x18, 0x28, 0x7c, 0xb2, 0x02, 0xa4, 0xc3, 0xb8, 0x00, 0xfe, + 0x1e, 0x75, 0x85, 0x61, 0x7d, 0xdf, 0xf9, 0xfb, 0xdd, 0x3a, 0x6f, 0xab, 0x65, 0x1b, 0x95, 0xea, + 0x6f, 0xfa, 0x31, 0xe9, 0xa7, 0xf0, 0xe2, 0x80, 0x06, 0x97, 0x9b, 0x4f, 0xac, 0x16, 0xff, 0xdd, + 0xe5, 0xf3, 0x13, 0x82, 0x6e, 0x0e, 0xfd, 0x7e, 0x1b, 0xae, 0xb6, 0xcb, 0x01, 0x4e, 0xba, 0x7c, + 0x3b, 0x80, 0x11, 0xca, 0xb0, 0x6c, 0xc5, 0x3b, 0x7c, 0x0f, 0xf8, 0xb1, 0x34, 0x82, 0xc6, 0x33, + 0xc9, 0x46, 0x40, 0xe7, 0xba, 0x0d, 0xe2, 0x47, 0xaa, 0xe3, 0xde, 0xf8, 0xad, 0xc4, 0x7c, 0x56, + 0x11, 0xe9, 0xd3, 0x24, 0x38, 0x71, 0x40, 0x15, 0xa4, 0xe4, 0x1d, 0x7a, 0x21, 0x07, 0x6d, 0xbc, + 0x07, 0xdb, 0xf3, 0xe0, 0x01, 0xe8, 0x9f, 0x0c, 0xc1, 0x78, 0x57, 0x74, 0xe6, 0xb2, 0x7f, 0x26, + 0x0a, 0x2f, 0xf0, 0x2c, 0x42, 0x91, 0xc1, 0xbc, 0x72, 0x3e, 0x38, 0xbe, 0x50, 0x8f, 0x05, 0x5e, + 0x8a, 0x33, 0xe5, 0xf4, 0xe4, 0xb0, 0x19, 0x6c, 0x51, 0xec, 0xde, 0xe3, 0x68, 0x50, 0xe1, 0x97, + 0x00, 0x37, 0xec, 0x73, 0x25, 0xee, 0xc5, 0xf4, 0x4f, 0xed, 0xdc, 0x4f, 0xc1, 0xff, 0x6e, 0xd9, + 0xe6, 0x56, 0xd9, 0x7f, 0xd8, 0x6d, 0xc0, 0x14, 0x6a, 0xb4, 0x3f, 0x57, 0xb2, 0x40, 0x43, 0x08, + 0x4f, 0xa8, 0x86, 0x12, 0x70, 0xc2, 0x10, 0x8a, 0xb3, 0x42, 0x2a, 0x5f, 0x09, 0xe0, 0x1e, 0xf8, + 0x92, 0xac, 0xc6, 0x9d, 0xcf, 0xd1, 0x66, 0x81, 0xe0, 0xbb, 0x46, 0xc4, 0xbe, 0xe6, 0x92, 0xb2, + 0x85, 0x9c, 0x05, 0x5b, 0x83, 0x95, 0xfd, 0x56, 0xc8, 0x43, 0x0b, 0xcc, 0x90, 0xc2, 0x79, 0x24, + 0x40, 0xf7, 0x53, 0xc2, 0xb5, 0x17, 0xa4, 0x48, 0x42, 0xa2, 0x54, 0x50, 0xce, 0x02, 0x72, 0x6e, + 0x4e, 0xbd, 0x76, 0x54, 0x44, 0x82, 0x2e, 0xbd, 0xe2, 0xb8, 0x58, 0x67, 0x00, 0x61, 0x8a, 0x2d, + 0xb8, 0x48, 0xb7, 0xfa, 0xad, 0x17, 0xf6, 0x18, 0x50, 0x20, 0x4a, 0x94, 0x37, 0xeb, 0xee, 0xae, + 0xa8, 0x89, 0x04, 0xfe, 0xc2, 0x8a, 0x00, 0x1b, 0x7f, 0xf8, 0xef, 0xf7, 0x5f, 0xf8, 0xfd, 0xb3, + 0xfa, 0xe6, 0xf5, 0xdf, 0x44, 0xc9, 0x70, 0xcb, 0x80, 0x27, 0xeb, 0x15, 0x49, 0xcd, 0x5b, 0xbe, + 0x7f, 0x3a, 0xc4, 0x97, 0xb6, 0x05, 0xa4, 0x4a, 0xe1, 0x9e, 0x68, 0x56, 0xe6, 0x1d, 0x7c, 0x6b, + 0x0c, 0xe0, 0x03, 0x61, 0xdb, 0x16, 0xfe, 0xa6, 0x37, 0xef, 0xb1, 0xbc, 0x62, 0xe2, 0x5e, 0x89, + 0xf3, 0xbf, 0x74, 0xc0, 0x52, 0x1c, 0x93, 0x88, 0x38, 0x21, 0x01, 0xb0, 0x14, 0x87, 0xfd, 0x31, + 0xc5, 0xf8, 0xc5, 0x76, 0x72, 0xc5, 0x18, 0xef, 0xca, 0xc1, 0x3b, 0x41, 0xdf, 0xb5, 0x83, 0xec, + 0xe2, 0x42, 0xc8, 0xe0, 0x06, 0x38, 0x00, 0xe1, 0xa5, 0x00, 0x18, 0x73, 0x4a, 0x20, 0xc3, 0xc3, + 0xfd, 0xd9, 0x6b, 0x10, 0xc1, 0x46, 0x81, 0xb0, 0x52, 0x35, 0x51, 0xe1, 0x90, 0x7c, 0x3b, 0xce, + 0x92, 0x8d, 0x26, 0xb0, 0xce, 0x01, 0x25, 0x52, 0x4e, 0x1b, 0xeb, 0xf7, 0x75, 0xf9, 0x3f, 0xfd, + 0x61, 0x79, 0x45, 0x07, 0xff, 0xf7, 0xbb, 0xe2, 0x70, 0x14, 0xf4, 0x96, 0xe1, 0x75, 0x00, 0x9d, + 0x39, 0xa5, 0x36, 0xff, 0x15, 0xc5, 0x7a, 0x21, 0xdd, 0x1b, 0x12, 0xa6, 0x16, 0x64, 0x00, 0xef, + 0x0f, 0xa1, 0x5d, 0x5f, 0xc9, 0x0b, 0x84, 0xff, 0x0b, 0x60, 0x20, 0x3e, 0x58, 0x7d, 0x7f, 0x5f, + 0xaf, 0x0c, 0x38, 0x13, 0x04, 0xc8, 0x00, 0x68, 0x6a, 0x96, 0xb4, 0xf2, 0xf5, 0xd7, 0xc7, 0xc7, + 0x70, 0xd3, 0x80, 0x11, 0x0b, 0x71, 0x1c, 0x0c, 0xd9, 0x7e, 0xdb, 0x7e, 0x9c, 0xbc, 0xbf, 0x31, + 0x86, 0x59, 0x40, 0x9f, 0x68, 0x71, 0xb7, 0xff, 0xa7, 0xff, 0x61, 0x94, 0x40, 0x02, 0x13, 0x33, + 0x50, 0xdc, 0x97, 0xb4, 0xdf, 0xdb, 0x3f, 0xbf, 0xfb, 0x0a, 0x92, 0x00, 0x86, 0xcb, 0xdb, 0x9b, + 0xa9, 0xe9, 0xb9, 0xfd, 0xff, 0xe1, 0x00, 0x14, 0x01, 0x48, 0x5c, 0x54, 0xf7, 0x0f, 0x7e, 0xfc, + 0x26, 0x15, 0x53, 0xf8, 0xf7, 0x89, 0xf2, 0xc3, 0x12, 0x79, 0x61, 0x8c, 0x00, 0x03, 0x89, 0x87, + 0x14, 0x0e, 0x0c, 0x81, 0x63, 0xed, 0x0e, 0xed, 0xed, 0xed, 0xb7, 0xfe, 0x3c, 0xe5, 0x34, 0xf6, + 0xdb, 0xe1, 0xbc, 0x00, 0x33, 0xaf, 0x6c, 0x2c, 0xb7, 0x80, 0x8c, 0xf3, 0x6a, 0xda, 0xad, 0x6a, + 0x2e, 0xa2, 0xeb, 0x58, 0x8e, 0xc5, 0x3f, 0xeb, 0x0e, 0x28, 0x00, 0x9f, 0x65, 0x9c, 0x68, 0x11, + 0xd9, 0xae, 0x4d, 0xbf, 0x1f, 0xf1, 0xff, 0x97, 0xff, 0x8b, 0x26, 0xdb, 0xe9, 0xf0, 0xe6, 0x00, + 0x24, 0x47, 0x34, 0xc0, 0x4b, 0xc2, 0x48, 0x73, 0x76, 0xf6, 0x70, 0x75, 0x76, 0xcb, 0xdb, 0x4e, + 0x3f, 0xd9, 0xbf, 0x5e, 0x15, 0x62, 0x41, 0x1b, 0x13, 0x55, 0xed, 0xff, 0xf8, 0x95, 0x1d, 0xc7, + 0x85, 0x04, 0x03, 0xa7, 0xcb, 0xc1, 0xd7, 0xcf, 0x03, 0xcd, 0xa2, 0x8c, 0xac, 0x94, 0xb6, 0x0e, + 0x9f, 0x1d, 0x0b, 0x89, 0x01, 0xe3, 0xfd, 0x38, 0x03, 0xe3, 0x1e, 0x59, 0x18, 0xe3, 0x1f, 0x86, + 0x14, 0x00, 0xdc, 0xf9, 0x90, 0x5f, 0xf5, 0xbd, 0x38, 0xff, 0xf1, 0xf1, 0xdc, 0x4a, 0x38, 0xb0, + 0xe2, 0x94, 0x70, 0x70, 0x44, 0x32, 0x83, 0x44, 0x16, 0x51, 0x0e, 0x38, 0xc6, 0x2a, 0x41, 0x38, + 0x44, 0xa2, 0x95, 0x88, 0x94, 0x40, 0x22, 0x9f, 0x3e, 0x58, 0x07, 0xa2, 0x09, 0xea, 0x29, 0xa8, + 0xbd, 0x6e, 0x38, 0xec, 0x4b, 0x81, 0x43, 0xa9, 0xae, 0x23, 0x00, 0x61, 0xeb, 0x79, 0x1f, 0x30, + 0x08, 0x80, 0x12, 0x01, 0x0d, 0xdd, 0xda, 0x1c, 0x18, 0xfe, 0x04, 0x00, 0xc0, 0x22, 0x9b, 0x8a, + 0x1d, 0x21, 0xc1, 0x8f, 0xc3, 0x33, 0x00, 0x17, 0xd1, 0xdc, 0x41, 0x89, 0x4b, 0x4f, 0x6c, 0xbe, + 0xfe, 0x21, 0xed, 0xd9, 0x66, 0xe0, 0x0c, 0x40, 0x40, 0x52, 0xe2, 0xb1, 0x3c, 0xc5, 0x71, 0x58, + 0xac, 0xf0, 0x0f, 0x03, 0xb0, 0x25, 0x1d, 0x0b, 0x96, 0x00, 0x04, 0xa1, 0xd9, 0x2b, 0xf0, 0x98, + 0x00, 0x2a, 0x1d, 0x89, 0x41, 0x20, 0x31, 0xa1, 0x58, 0x21, 0xa2, 0x8e, 0x0c, 0x73, 0x86, 0x11, + 0x00, 0x37, 0x28, 0x4c, 0x6e, 0xd3, 0xff, 0xfd, 0xf8, 0x38, 0x0c, 0x02, 0x78, 0x58, 0x15, 0x38, + 0x01, 0xf8, 0xa0, 0xe2, 0xb7, 0x8e, 0x32, 0x07, 0x85, 0x27, 0x83, 0xf3, 0xde, 0x9e, 0x2f, 0x3d, + 0xed, 0x61, 0xee, 0x37, 0x2f, 0x1d, 0xf8, 0xc0, 0x01, 0x43, 0xb8, 0x79, 0x41, 0x04, 0xd4, 0xd7, + 0x7d, 0x94, 0xfd, 0xb7, 0xae, 0x7e, 0x71, 0x3d, 0x11, 0x23, 0xfe, 0x01, 0x50, 0x02, 0x48, 0xd8, + 0xa0, 0x0c, 0x48, 0x0f, 0x12, 0x38, 0x58, 0xcb, 0x18, 0x90, 0x70, 0x7d, 0x6a, 0x8a, 0x3b, 0x96, + 0xb1, 0x76, 0xd2, 0x08, 0x88, 0xa0, 0x41, 0xd9, 0x7c, 0xbc, 0x28, 0xf7, 0xc3, 0x38, 0x0a, 0xbb, + 0x31, 0x3b, 0x63, 0xef, 0xd5, 0x6d, 0xb7, 0x5e, 0x68, 0x26, 0x3d, 0x7b, 0xfc, 0x95, 0x42, 0x6e, + 0x00, 0xec, 0xba, 0x0c, 0x4e, 0xfb, 0xaf, 0xd5, 0xc5, 0xc5, 0x7c, 0x05, 0xc0, 0xd9, 0xf9, 0x66, + 0x7e, 0x79, 0xe5, 0x9d, 0x9e, 0xfe, 0x5f, 0x5a, 0x76, 0xe2, 0x5e, 0xfe, 0x1c, 0x2f, 0x1d, 0xc2, + 0x9e, 0x13, 0x87, 0xf0, 0xa3, 0x80, 0x2f, 0x0a, 0xeb, 0x23, 0x55, 0xd5, 0x95, 0xff, 0xf0, 0xaa, + 0x86, 0x71, 0xd7, 0x96, 0x04, 0x82, 0xe5, 0x93, 0xcf, 0xde, 0x1d, 0xc0, 0x18, 0xdd, 0x1d, 0x6d, + 0xf6, 0x91, 0x22, 0x64, 0xea, 0xc9, 0x10, 0x9c, 0x19, 0x55, 0x94, 0x47, 0xd5, 0x7b, 0xfc, 0x32, + 0xa0, 0x07, 0x34, 0x3b, 0x77, 0x35, 0x75, 0xdd, 0x4f, 0x34, 0x52, 0xec, 0x84, 0x8f, 0x3b, 0xcb, + 0x08, 0x56, 0x21, 0x84, 0x7c, 0x2a, 0xa0, 0x03, 0xfe, 0x91, 0x71, 0x08, 0x52, 0xdf, 0xd6, 0x58, + 0x29, 0xcc, 0x11, 0x22, 0xbc, 0x28, 0x48, 0x07, 0x4a, 0xea, 0xb1, 0xd5, 0xd7, 0x7d, 0x77, 0xbe, + 0x14, 0x50, 0x15, 0xb5, 0x01, 0xb9, 0x8e, 0xea, 0x9f, 0x77, 0xfe, 0x0a, 0x00, 0x24, 0x01, 0x4a, + 0x6e, 0x67, 0xef, 0xb6, 0x98, 0xf5, 0x35, 0xd4, 0xc1, 0xdb, 0xc6, 0xd8, 0xb6, 0x38, 0x63, 0x80, + 0x38, 0x75, 0xc0, 0x0c, 0x2a, 0x64, 0xb4, 0x6d, 0xe7, 0x87, 0xbe, 0xe1, 0x1f, 0x83, 0xfe, 0xa7, + 0x8b, 0x27, 0xc1, 0xf0, 0xb5, 0x7f, 0xfc, 0x09, 0x01, 0x4b, 0x79, 0x56, 0xc5, 0xb3, 0x9e, 0x79, + 0x65, 0x9f, 0xec, 0x79, 0x6b, 0x8d, 0xb4, 0x3c, 0xde, 0xa3, 0x86, 0x38, 0x0e, 0x15, 0xc0, 0x07, + 0xff, 0xed, 0xd3, 0x6b, 0xed, 0xf3, 0x28, 0x27, 0x74, 0x6c, 0x59, 0xdb, 0x06, 0x72, 0xdf, 0x2d, + 0xa1, 0x29, 0xbe, 0x07, 0xfc, 0x32, 0x48, 0x4e, 0x98, 0x76, 0xe9, 0xed, 0xfe, 0x7f, 0xf6, 0x15, + 0x94, 0x34, 0xd1, 0xf7, 0xbe, 0xeb, 0x15, 0xcf, 0x48, 0x6e, 0x40, 0x02, 0xae, 0x8a, 0x8f, 0x16, + 0xb5, 0xf8, 0xbe, 0x18, 0x5f, 0xc8, 0xa5, 0xb6, 0xca, 0x9d, 0xff, 0x0f, 0x12, 0x00, 0x4b, 0xc9, + 0x63, 0xb9, 0x15, 0xf7, 0xbd, 0xf6, 0xe8, 0x0a, 0xc7, 0x68, 0x38, 0x9c, 0x26, 0x81, 0x6d, 0x6a, + 0x61, 0xd5, 0x25, 0x3a, 0x8c, 0x41, 0xa2, 0xfe, 0x1e, 0x70, 0x07, 0x76, 0x0a, 0x5c, 0x5e, 0x12, + 0x09, 0x2b, 0xe9, 0x79, 0x7d, 0x34, 0xd5, 0x69, 0x98, 0x14, 0x6c, 0x53, 0x2d, 0x38, 0xc9, 0xd7, + 0x7f, 0xc3, 0x18, 0x01, 0xa1, 0x0e, 0xd6, 0x16, 0x6c, 0x4d, 0xed, 0xfb, 0x6d, 0xdb, 0x26, 0x8e, + 0x7e, 0xdb, 0x6c, 0xab, 0xfb, 0xe1, 0x7c, 0x00, 0x73, 0xd5, 0xd6, 0x94, 0x7f, 0xf7, 0xdb, 0x6e, + 0xf8, 0x61, 0x40, 0x04, 0x65, 0x77, 0x7d, 0xf3, 0xe5, 0xfe, 0x9a, 0x7a, 0x69, 0xb1, 0x85, 0xb0, + 0x06, 0x1f, 0x9c, 0x8a, 0x07, 0x19, 0xdd, 0xf9, 0x7e, 0x9c, 0xfe, 0xcf, 0xcb, 0x5d, 0x70, 0x9b, + 0x80, 0x81, 0x2d, 0x30, 0xfb, 0xfd, 0xb6, 0xf7, 0xfe, 0x1a, 0x50, 0x08, 0xf1, 0xc4, 0x95, 0x61, + 0x56, 0xde, 0xdf, 0xfb, 0xd3, 0x63, 0x86, 0x01, 0x48, 0x2d, 0xa8, 0xa7, 0x17, 0x78, 0xae, 0x38, + 0x00, 0x14, 0x8f, 0xe0, 0xe4, 0x0b, 0x20, 0xb2, 0x2e, 0x27, 0x82, 0x99, 0x66, 0xee, 0xfa, 0xd4, + 0x70, 0x00, 0x31, 0xb0, 0xde, 0x02, 0x95, 0x03, 0x35, 0x1d, 0x17, 0xae, 0xf1, 0x5e, 0xde, 0x2b, + 0x8a, 0xe6, 0xef, 0x2c, 0x6f, 0xd7, 0x85, 0xd9, 0x41, 0x23, 0x52, 0x6f, 0xff, 0x5f, 0x7d, 0x98, + 0xd2, 0x09, 0x19, 0xc3, 0xe2, 0xa6, 0x09, 0x01, 0x23, 0xc8, 0x4d, 0x41, 0x49, 0x26, 0x7f, 0xd6, + 0xbf, 0x0a, 0x28, 0x03, 0xfa, 0x2d, 0x5c, 0x53, 0xe3, 0x4f, 0xff, 0x85, 0x54, 0x08, 0x4d, 0x7a, + 0x6f, 0xff, 0xeb, 0x14, 0xa0, 0x46, 0xa6, 0x92, 0xc8, 0xcc, 0x3f, 0xc5, 0xd8, 0xe9, 0x4b, 0x22, + 0xa6, 0x18, 0x44, 0x01, 0xb9, 0x1c, 0x9f, 0x4f, 0xff, 0xcb, 0x0a, 0x23, 0x00, 0x8e, 0xe1, 0x73, + 0xb2, 0x76, 0x9a, 0x76, 0xfb, 0x7d, 0x36, 0xf0, 0x99, 0x20, 0x06, 0x0f, 0xa6, 0x5b, 0x3e, 0x7f, + 0xa7, 0xa7, 0xf1, 0x4c, 0xe0, 0x8c, 0xd5, 0x2f, 0x04, 0x77, 0xbc, 0x71, 0x8f, 0xe0, 0x10, 0x10, + 0x3c, 0x05, 0x09, 0x8a, 0xdd, 0x45, 0xe2, 0xee, 0xf7, 0x78, 0xad, 0xc7, 0x77, 0x01, 0x00, 0x18, + 0x04, 0x77, 0x8a, 0xdc, 0x77, 0x62, 0x59, 0xca, 0x7e, 0x25, 0x40, 0xab, 0xe9, 0xf0, 0xb4, 0x80, + 0x12, 0xfd, 0x2a, 0x73, 0xef, 0x7d, 0x3f, 0xc3, 0xac, 0x80, 0x0c, 0xe0, 0x06, 0x2a, 0xad, 0xe0, + 0x23, 0x7a, 0xad, 0xcb, 0xdb, 0xf7, 0x74, 0xe3, 0x4c, 0x7f, 0xf2, 0xed, 0x34, 0xd3, 0x0d, 0x5d, + 0x5d, 0xbf, 0x87, 0x70, 0x01, 0xf2, 0xa2, 0x81, 0x0b, 0x99, 0xa6, 0xc0, 0xed, 0xcd, 0xd9, 0xfd, + 0xb6, 0xd9, 0xc5, 0xb9, 0xa7, 0x2f, 0x4f, 0x91, 0x6d, 0xfe, 0x16, 0x70, 0xd6, 0x27, 0xff, 0xa7, + 0xf8, 0x9c, 0x01, 0xa3, 0xe4, 0xcc, 0x3d, 0x61, 0x88, 0x2a, 0xc5, 0x77, 0x38, 0x78, 0xef, 0xcb, + 0x74, 0x6e, 0xf7, 0x04, 0x82, 0xa1, 0x80, 0x6a, 0x00, 0xa0, 0x09, 0xb0, 0x7b, 0xde, 0x21, 0xe3, + 0x80, 0x01, 0x38, 0xef, 0xc1, 0x3c, 0x2c, 0x1a, 0x8a, 0x65, 0x9f, 0x77, 0x07, 0x81, 0xa1, 0xdc, + 0x3a, 0xa2, 0x1f, 0xb3, 0xbc, 0x94, 0xbf, 0x5a, 0xff, 0x24, 0x0f, 0x53, 0x4f, 0xf8, 0x71, 0x40, + 0x0c, 0x40, 0x0d, 0xe6, 0x6a, 0x7a, 0xad, 0xfb, 0x6f, 0x12, 0xf6, 0xdf, 0xdf, 0xa2, 0x7c, 0x56, + 0xa2, 0x76, 0xd3, 0xff, 0xc2, 0x99, 0x15, 0xb3, 0x96, 0xd7, 0xaf, 0x28, 0x64, 0xef, 0xfb, 0x65, + 0xe2, 0x0f, 0x51, 0xeb, 0x81, 0xb0, 0x03, 0x1d, 0xc2, 0x6a, 0x00, 0xc2, 0xa6, 0xfc, 0xad, 0xfb, + 0xd5, 0x97, 0xec, 0xbb, 0xcb, 0x08, 0x65, 0x40, 0x08, 0x39, 0xb3, 0x88, 0x80, 0x0d, 0x79, 0x59, + 0x2b, 0x2b, 0xdc, 0x90, 0x74, 0x07, 0xf1, 0x2f, 0x5a, 0xcc, 0xbc, 0x33, 0x80, 0x30, 0x4c, 0x34, + 0x67, 0xb7, 0x6e, 0xbf, 0x34, 0x23, 0xba, 0x76, 0x4e, 0x73, 0x07, 0x6c, 0x2b, 0x0a, 0xb8, 0x90, + 0x00, 0xce, 0xbb, 0xe4, 0x7b, 0x06, 0x77, 0xc3, 0xa4, 0x58, 0xe7, 0x86, 0x89, 0x55, 0xe5, 0xd6, + 0x19, 0xc0, 0x20, 0xb8, 0xfc, 0xf1, 0xc2, 0x3c, 0xf6, 0x05, 0xe5, 0xb9, 0x71, 0x73, 0xfb, 0xe4, + 0xa4, 0x22, 0xc2, 0x10, 0xa6, 0xc2, 0xb8, 0x06, 0xec, 0x72, 0xbb, 0x57, 0x97, 0xef, 0x64, 0x68, + 0x3a, 0x0e, 0xf7, 0xc0, 0xd2, 0x07, 0x10, 0xa4, 0x48, 0xf6, 0xcf, 0x7e, 0x2b, 0x43, 0x91, 0x83, + 0xde, 0x56, 0x02, 0xa3, 0x4c, 0x8c, 0x9f, 0xe5, 0x62, 0x47, 0x31, 0xc0, 0x78, 0x09, 0x90, 0x88, + 0x52, 0xe6, 0x05, 0x67, 0xd8, 0xce, 0xc5, 0xb1, 0xb5, 0x2d, 0xdb, 0x51, 0x1e, 0x2e, 0xce, 0x3e, + 0x38, 0x0f, 0x01, 0x23, 0x0a, 0x47, 0x54, 0xab, 0x29, 0x36, 0x8e, 0xf8, 0x97, 0x95, 0x88, 0x33, + 0xcb, 0x19, 0xe5, 0x84, 0x34, 0x32, 0x30, 0x87, 0x18, 0xe0, 0x63, 0x80, 0x38, 0x64, 0x90, 0x8f, + 0x1c, 0xd0, 0xdd, 0x9f, 0x75, 0x9a, 0x0f, 0x7d, 0x97, 0x16, 0x1a, 0x52, 0x12, 0xa5, 0xed, 0xd3, + 0x74, 0x1f, 0xf6, 0x6e, 0x2f, 0xf9, 0x61, 0x8c, 0x00, 0x60, 0x6b, 0xef, 0xe3, 0x9f, 0x6f, 0x6d, + 0xb4, 0x56, 0xe9, 0xa7, 0xf6, 0x1d, 0xc0, 0x1a, 0xae, 0xc9, 0x26, 0xd1, 0x7b, 0x2b, 0xd9, 0xc4, + 0xb0, 0x17, 0x2d, 0xa9, 0xa0, 0x2f, 0x4b, 0xbb, 0x2f, 0xc3, 0x98, 0x00, 0xec, 0x4e, 0xf3, 0x40, + 0x48, 0xd3, 0xce, 0x4a, 0x78, 0x4b, 0xd2, 0xa9, 0x53, 0x98, 0x48, 0xab, 0x79, 0x94, 0x39, 0x81, + 0x66, 0xd8, 0x12, 0x1e, 0x51, 0xdf, 0x1a, 0xce, 0xd1, 0x23, 0x45, 0xf8, 0x60, 0x90, 0x04, 0x84, + 0xd4, 0x4f, 0x0d, 0xbd, 0xe2, 0x75, 0x29, 0x97, 0x8f, 0xff, 0xf4, 0x65, 0x43, 0x2a, 0x26, 0x7b, + 0x3b, 0x60, 0xfa, 0xd5, 0x3f, 0xff, 0xac, 0x30, 0xa0, 0x02, 0xf4, 0x9c, 0x19, 0x2e, 0xe5, 0x8a, + 0xf3, 0xd1, 0x20, 0xfa, 0x78, 0xa8, 0xb6, 0xaf, 0x10, 0xc0, 0x19, 0x7a, 0xaf, 0xe2, 0x36, 0x1b, + 0x45, 0x01, 0x19, 0x6a, 0xb3, 0x0a, 0xcf, 0xd7, 0x7d, 0xed, 0xe3, 0x5e, 0xef, 0xf8, 0xb6, 0x40, + 0x05, 0xbd, 0x98, 0x44, 0x9c, 0x8a, 0xd8, 0x4d, 0xc0, 0x0c, 0xfc, 0x2f, 0x90, 0x82, 0xde, 0x75, + 0x2f, 0xdb, 0xde, 0xb5, 0xb7, 0xf0, 0x19, 0x00, 0x70, 0x04, 0x31, 0x5f, 0x1c, 0x00, 0x08, 0x47, + 0x38, 0x63, 0x04, 0xa3, 0x15, 0x1f, 0x6f, 0xff, 0x7c, 0x76, 0x6b, 0x18, 0xa2, 0xae, 0x08, 0x02, + 0x9b, 0x77, 0x9b, 0xc4, 0xfe, 0xaa, 0xf3, 0x89, 0x04, 0xa3, 0xc1, 0x88, 0x28, 0xac, 0xdf, 0x77, + 0x15, 0x8c, 0x00, 0x28, 0x77, 0x0e, 0xe0, 0x03, 0x00, 0x99, 0x16, 0xb1, 0x8d, 0xb4, 0x6e, 0x6f, + 0x37, 0xd7, 0xcb, 0xd7, 0x26, 0xf3, 0xd3, 0xbb, 0xfc, 0x32, 0x42, 0x81, 0x8c, 0xe1, 0x54, 0xef, + 0xff, 0xad, 0x5f, 0x0f, 0x61, 0x6c, 0x1a, 0xcd, 0x0f, 0xcd, 0x7e, 0xaf, 0x7f, 0xc3, 0x64, 0x83, + 0x12, 0x38, 0x7e, 0xbb, 0xdd, 0x7f, 0x75, 0xfc, 0x2a, 0xa0, 0x24, 0x12, 0xf8, 0xfe, 0xa7, 0xf6, + 0x5b, 0xa2, 0x8a, 0x95, 0x94, 0x34, 0xa1, 0x08, 0xc9, 0x7f, 0xfb, 0xec, 0x85, 0x36, 0x17, 0x50, + 0x03, 0x3e, 0x2f, 0x3c, 0x9b, 0x7e, 0xff, 0xe8, 0x99, 0x59, 0x4a, 0x98, 0x69, 0x10, 0x02, 0x00, + 0x57, 0xb1, 0x16, 0xbf, 0xdf, 0x2f, 0x55, 0xd4, 0x63, 0xf8, 0x39, 0x00, 0x90, 0x05, 0x22, 0xb1, + 0x59, 0xfe, 0x25, 0xee, 0x56, 0x58, 0xc9, 0xef, 0x96, 0xd8, 0xca, 0xcc, 0x6f, 0xf1, 0x89, 0x01, + 0xa1, 0xdc, 0x32, 0x48, 0x09, 0x97, 0xb5, 0x4d, 0x7b, 0xfd, 0xd5, 0x93, 0xba, 0x2a, 0xc2, 0xce, + 0x05, 0xdf, 0x2e, 0x57, 0xfe, 0xeb, 0xf0, 0xaa, 0x80, 0x35, 0x69, 0xa7, 0xf7, 0x8d, 0xff, 0xff, + 0x85, 0x14, 0x09, 0x44, 0x0a, 0xe7, 0x6b, 0x4d, 0x3f, 0xed, 0xa6, 0x9f, 0x15, 0x80, 0x85, 0x9b, + 0x0a, 0x4f, 0x60, 0x16, 0x00, 0x12, 0x20, 0x90, 0xf8, 0xba, 0x8e, 0x31, 0xfc, 0x22, 0x02, 0x20, + 0x11, 0x55, 0x6a, 0x3b, 0x63, 0x49, 0x04, 0x3c, 0xde, 0xb1, 0xb8, 0x38, 0x08, 0x28, 0xe0, 0xf6, + 0x30, 0x84, 0x02, 0x3a, 0x62, 0x96, 0x33, 0x08, 0x28, 0xe8, 0x91, 0x2a, 0x2a, 0xd1, 0x7e, 0x1d, + 0x50, 0x20, 0x9d, 0x93, 0x5f, 0xef, 0x7f, 0xeb, 0xbb, 0xfe, 0x00, 0xb4, 0x01, 0x80, 0x52, 0x91, + 0x30, 0x56, 0x5b, 0x37, 0x14, 0xeb, 0x17, 0x8a, 0xee, 0xeb, 0x51, 0x80, 0x2a, 0xe0, 0x09, 0xa0, + 0x1c, 0x82, 0xe8, 0xbc, 0x5d, 0x53, 0x97, 0x89, 0x78, 0xc0, 0x05, 0x46, 0x24, 0x90, 0x21, 0x62, + 0x73, 0xaf, 0x83, 0x80, 0xc0, 0x2a, 0xa9, 0xcf, 0x58, 0xde, 0xdc, 0xdd, 0x35, 0x4c, 0x42, 0x03, + 0xb0, 0xc3, 0x80, 0x40, 0xd3, 0x0d, 0x4a, 0xb9, 0x5d, 0x5e, 0xec, 0x9c, 0x46, 0x14, 0x9d, 0xf1, + 0xfb, 0x0e, 0x7c, 0x2f, 0xb0, 0xd2, 0x80, 0x11, 0x16, 0xce, 0x5d, 0x74, 0xac, 0xac, 0x9d, 0xb0, + 0xb8, 0xf7, 0x65, 0xec, 0xae, 0xcb, 0xd8, 0x5d, 0x40, 0x63, 0x20, 0x67, 0x6d, 0x91, 0xe0, 0xac, + 0x8e, 0xc2, 0xd5, 0xf0, 0x17, 0x7c, 0x25, 0xf7, 0xec, 0x26, 0xe0, 0x26, 0xb5, 0x20, 0x29, 0xa1, + 0xef, 0x45, 0xbd, 0xf5, 0x7b, 0xe1, 0x3c, 0x02, 0x08, 0xec, 0xb2, 0x5e, 0xf6, 0x54, 0x94, 0xd0, + 0xbb, 0xb8, 0x8c, 0x25, 0x90, 0xa5, 0x81, 0xe4, 0x04, 0xc0, 0x2a, 0xe5, 0xf9, 0xc0, 0x3c, 0x2e, + 0x0a, 0x85, 0x95, 0xad, 0xac, 0x49, 0xf9, 0x78, 0xe0, 0x00, 0x5e, 0x3b, 0x85, 0x14, 0x02, 0x37, + 0xaf, 0xdc, 0xf3, 0xef, 0x36, 0x2e, 0x87, 0x74, 0x6d, 0x67, 0x98, 0xac, 0xef, 0xa4, 0x49, 0x8b, + 0x92, 0xa9, 0x1c, 0x32, 0xa1, 0x80, 0x53, 0x15, 0x1a, 0xfd, 0x7e, 0xaa, 0x3b, 0x61, 0x6c, 0x02, + 0x47, 0xaf, 0x46, 0xa7, 0xba, 0x29, 0x60, 0xfe, 0x2b, 0x8a, 0xe1, 0x72, 0x40, 0x45, 0x92, 0xe2, + 0x04, 0x50, 0x64, 0x19, 0x06, 0x41, 0x90, 0xeb, 0x2e, 0x43, 0xe8, 0x03, 0xf8, 0x32, 0x12, 0xba, + 0xd6, 0x1a, 0x50, 0x06, 0xee, 0xfd, 0xf6, 0x23, 0xdf, 0xcf, 0xdd, 0xd5, 0x78, 0x97, 0xca, 0xfc, + 0x4a, 0xd7, 0x98, 0xe0, 0x50, 0x0c, 0x85, 0x35, 0x73, 0x30, 0x2e, 0xc6, 0x49, 0xcd, 0x0a, 0x5d, + 0x1f, 0x3f, 0x2b, 0x07, 0x85, 0x82, 0x41, 0xa1, 0x61, 0x9c, 0x0b, 0x03, 0x98, 0xe0, 0x0e, 0x14, + 0x24, 0x07, 0xef, 0x9c, 0x86, 0xb6, 0x34, 0x52, 0xe8, 0x86, 0x31, 0xe7, 0x35, 0x54, 0x42, 0xf0, + 0xa2, 0x81, 0x2b, 0x52, 0x90, 0x7d, 0xdd, 0x6d, 0xee, 0xb5, 0xbd, 0xe1, 0x77, 0x00, 0x33, 0xf2, + 0x15, 0xd9, 0x3e, 0xb9, 0x95, 0x55, 0xdd, 0xdd, 0x6a, 0x89, 0xf3, 0x40, 0xb6, 0x16, 0x50, 0x44, + 0xfa, 0xb7, 0x91, 0x7a, 0xff, 0xfe, 0x1d, 0xc0, 0x1d, 0x31, 0xc0, 0xc0, 0xc3, 0xfe, 0x69, 0x5e, + 0x88, 0x5d, 0xd4, 0x56, 0xe5, 0x8b, 0xce, 0x7f, 0x3f, 0x12, 0x0d, 0x2e, 0xcb, 0xf8, 0x7b, 0x00, + 0xa5, 0x4e, 0xa4, 0x30, 0xab, 0xfa, 0xf7, 0xfa, 0xb8, 0x8c, 0x07, 0x74, 0x92, 0xc6, 0x3a, 0xb8, + 0xe2, 0xfa, 0xae, 0x5f, 0xa4, 0xc5, 0xf4, 0xdf, 0xc3, 0xb8, 0x01, 0x9f, 0xc4, 0x63, 0xd6, 0x7f, + 0x75, 0xf0, 0x58, 0x61, 0x96, 0xb6, 0x64, 0x81, 0xf1, 0x1f, 0xf9, 0x6a, 0xac, 0xf1, 0x5f, 0xd2, + 0xc3, 0x6a, 0x00, 0x21, 0x95, 0x1e, 0x6b, 0x87, 0x3d, 0xff, 0x6b, 0x7c, 0xfd, 0xa1, 0x7d, 0x68, + 0xe0, 0xef, 0x1c, 0xbf, 0x4f, 0x87, 0x54, 0x00, 0x0b, 0xf1, 0xf2, 0xc7, 0xc3, 0x5c, 0x7f, 0x64, + 0x60, 0xc1, 0x66, 0x2c, 0x9f, 0xfb, 0x93, 0xca, 0x51, 0x9b, 0xf0, 0xc2, 0xb7, 0x71, 0x0d, 0x1d, + 0x03, 0x98, 0x1f, 0xef, 0xe2, 0x09, 0xa3, 0xa1, 0x85, 0x6e, 0xef, 0x6f, 0x87, 0x1c, 0x00, 0x80, + 0x8a, 0x6c, 0x60, 0xb3, 0x83, 0xe1, 0xef, 0x96, 0x59, 0x7b, 0xb7, 0x88, 0x0e, 0x88, 0x0e, 0xf2, + 0x5e, 0x15, 0xea, 0xb7, 0x59, 0xa6, 0xda, 0x85, 0x9d, 0x08, 0xfd, 0x72, 0x7f, 0xc3, 0xae, 0x00, + 0x39, 0x5a, 0x0d, 0x48, 0xe7, 0xeb, 0xb6, 0x14, 0x2c, 0x46, 0xa8, 0x9f, 0xfc, 0xb1, 0xad, 0xb1, + 0xae, 0xed, 0xb6, 0x1d, 0x0e, 0xac, 0x9f, 0xf0, 0xe2, 0x80, 0x31, 0x8c, 0xc9, 0x18, 0xdb, 0xad, + 0xf5, 0xdc, 0xff, 0x6d, 0xb4, 0xdc, 0x75, 0xff, 0x19, 0xb5, 0xfe, 0x17, 0x24, 0x00, 0xeb, 0xd1, + 0xdc, 0x83, 0xfb, 0xdd, 0x7d, 0xd5, 0xb5, 0xf3, 0xe3, 0x0c, 0x92, 0x0a, 0x64, 0x9f, 0xfe, 0xff, + 0x1d, 0x8c, 0x54, 0x30, 0x48, 0x02, 0xf4, 0xe7, 0xa3, 0xf1, 0xfd, 0x7d, 0xcd, 0x3b, 0xf3, 0xac, + 0x1c, 0xc2, 0x91, 0x2f, 0x8d, 0xfe, 0x5b, 0x76, 0x5b, 0x54, 0xe2, 0xdb, 0x63, 0x94, 0x3d, 0xe3, + 0x86, 0x38, 0xe1, 0x65, 0x00, 0x5f, 0x2e, 0xd7, 0xd2, 0x37, 0xf7, 0x7d, 0xfd, 0xe5, 0xe2, 0xee, + 0x4b, 0xe7, 0xd2, 0x18, 0x50, 0x12, 0x8f, 0xa6, 0x76, 0x25, 0xf9, 0xa1, 0xb9, 0x61, 0xb6, 0x6e, + 0xfb, 0xfb, 0x6f, 0x85, 0xc9, 0x00, 0x33, 0xad, 0x05, 0x6e, 0xdf, 0xcf, 0x96, 0x5f, 0xde, 0x39, + 0xa7, 0x6a, 0xee, 0xef, 0xac, 0x3b, 0x80, 0x18, 0x52, 0x77, 0xd6, 0x9f, 0x99, 0x5c, 0x4f, 0xf7, + 0x77, 0x4e, 0x78, 0x5d, 0x44, 0x30, 0xe4, 0xa2, 0xff, 0x0c, 0x92, 0x01, 0xad, 0xc8, 0x9c, 0xb2, + 0xab, 0x92, 0x0e, 0xc8, 0x57, 0x79, 0xc7, 0x6c, 0x38, 0xa0, 0x3b, 0x85, 0xe4, 0xc9, 0xb5, 0x2d, + 0x2f, 0xb2, 0xb2, 0xdf, 0xab, 0xff, 0x86, 0x49, 0x09, 0x18, 0x9c, 0x7a, 0xb2, 0xfd, 0xd5, 0xc5, + 0xc6, 0xab, 0xc2, 0xea, 0x02, 0x13, 0xf5, 0x39, 0xef, 0xae, 0xf7, 0x96, 0x12, 0xc2, 0x4b, 0x09, + 0xa8, 0x08, 0x50, 0xd1, 0x44, 0x02, 0xe1, 0xeb, 0xef, 0xd6, 0xaf, 0x7f, 0x01, 0x32, 0x0b, 0x34, + 0xdd, 0x62, 0xad, 0x8c, 0x6e, 0x96, 0xd6, 0x50, 0xf7, 0x8e, 0x00, 0x05, 0xe3, 0x8e, 0x16, 0x24, + 0x02, 0x11, 0x6b, 0xd9, 0x6f, 0x85, 0x72, 0xc2, 0x2b, 0x11, 0x81, 0x60, 0x5f, 0x32, 0xff, 0xc3, + 0x6a, 0x03, 0x22, 0xef, 0x82, 0xb0, 0x5e, 0xc9, 0x90, 0xaf, 0x24, 0x17, 0x8e, 0xe8, 0x8d, 0x5e, + 0xa3, 0x03, 0xf9, 0xa7, 0xfc, 0x37, 0x80, 0x18, 0x1c, 0xb3, 0xf5, 0xaf, 0x9f, 0xee, 0xe5, 0x99, + 0x6f, 0x37, 0x82, 0xb7, 0x4f, 0xf0, 0xd6, 0x31, 0x67, 0xff, 0xed, 0xf5, 0x85, 0xb0, 0x02, 0x03, + 0x75, 0xc8, 0x97, 0xef, 0x6f, 0xec, 0xbf, 0x80, 0x70, 0x04, 0x82, 0x58, 0xae, 0x2b, 0x71, 0x71, + 0x77, 0x8e, 0x37, 0x00, 0xb0, 0x02, 0x90, 0xa5, 0x57, 0x17, 0x55, 0xbe, 0x9f, 0x10, 0x3c, 0x71, + 0xb8, 0x31, 0x07, 0x20, 0xa2, 0xdd, 0xfd, 0x5c, 0xdc, 0x56, 0x3b, 0x71, 0x80, 0x29, 0xe0, 0x51, + 0x05, 0x1c, 0x4f, 0xe4, 0xf3, 0x30, 0x09, 0x00, 0x6f, 0x07, 0x00, 0xb2, 0xed, 0xa6, 0xdd, 0x6a, + 0x0f, 0xbe, 0x39, 0x17, 0x6c, 0x48, 0x1a, 0x61, 0xb2, 0x40, 0x8c, 0x66, 0xba, 0xdf, 0xaf, 0x45, + 0x24, 0x1d, 0x90, 0x96, 0x0c, 0x9f, 0x41, 0xc1, 0xf4, 0x48, 0xbf, 0xc0, 0xc0, 0x0a, 0x42, 0x9b, + 0x73, 0x71, 0x7b, 0x3d, 0xdd, 0xdf, 0xe3, 0xb8, 0x97, 0xb8, 0xe0, 0x00, 0x47, 0xe1, 0xb5, 0x01, + 0x03, 0xac, 0xd6, 0x37, 0x3f, 0xef, 0xf3, 0xcc, 0xfc, 0xbc, 0x62, 0xbd, 0x95, 0x97, 0xf8, 0x52, + 0x5e, 0x2a, 0xec, 0x1d, 0x5c, 0xbb, 0xd4, 0xd3, 0x2d, 0x93, 0x9a, 0x0a, 0xcf, 0xb0, 0x72, 0xc2, + 0x9c, 0xb1, 0x18, 0xe0, 0x00, 0x5f, 0xf0, 0x24, 0x41, 0x67, 0x15, 0x69, 0xdd, 0xdc, 0x55, 0xee, + 0x38, 0x00, 0x15, 0xf8, 0x5d, 0x40, 0x16, 0xce, 0x5c, 0x8d, 0x1b, 0xf7, 0x9e, 0x19, 0xbd, 0xe3, + 0xbf, 0xe1, 0x48, 0xa3, 0x0b, 0xaa, 0x7f, 0x92, 0x8e, 0x0f, 0x79, 0x57, 0xc5, 0x42, 0x5f, 0x12, + 0x3f, 0x46, 0x0e, 0xaf, 0x64, 0x30, 0x00, 0x0c, 0xc7, 0x70, 0xca, 0x84, 0x05, 0xae, 0x9c, 0xb5, + 0x75, 0x15, 0xc5, 0x68, 0xa1, 0x56, 0xfd, 0xf0, 0x9b, 0x80, 0x4c, 0x7c, 0xe1, 0x0c, 0xa2, 0x92, + 0x02, 0xe6, 0x84, 0xba, 0x15, 0x71, 0x75, 0xd5, 0xe1, 0x7c, 0x02, 0x55, 0xc1, 0xba, 0x1a, 0xff, + 0x7a, 0x27, 0x54, 0x42, 0xe5, 0x82, 0x24, 0x44, 0x86, 0x29, 0x92, 0xb8, 0x17, 0x2c, 0x64, 0x4c, + 0x35, 0x80, 0x1b, 0xec, 0x2b, 0x72, 0xba, 0xfa, 0xa7, 0x97, 0xb8, 0x9c, 0x2f, 0xb2, 0x2c, 0x04, + 0x98, 0x59, 0x31, 0xc5, 0xd6, 0x1a, 0x50, 0x00, 0xfb, 0x5d, 0x92, 0x0d, 0x59, 0xad, 0xff, 0x16, + 0x82, 0xe5, 0xb2, 0x52, 0xd7, 0x11, 0xe7, 0xa5, 0xc9, 0xe1, 0x24, 0x11, 0x32, 0x03, 0xb6, 0x15, + 0x70, 0x8f, 0x01, 0xce, 0x76, 0xfe, 0x59, 0x3e, 0xdf, 0x5a, 0xef, 0x15, 0x8b, 0xc2, 0xdd, 0x21, + 0x60, 0x16, 0x10, 0x1b, 0x01, 0x4b, 0xb6, 0x5f, 0x88, 0x58, 0x6f, 0x6d, 0xac, 0x17, 0xe3, 0x6f, + 0x18, 0xa1, 0xf6, 0x07, 0x00, 0x02, 0xf1, 0xdc, 0x2f, 0x81, 0x28, 0xbc, 0x40, 0x40, 0xa9, 0x70, + 0xb1, 0x77, 0x25, 0x1f, 0xeb, 0x5a, 0xe1, 0x90, 0x10, 0x01, 0x4b, 0xb9, 0x4b, 0xa1, 0x2e, 0x83, + 0xee, 0x5b, 0x12, 0x3e, 0xdf, 0xa7, 0x87, 0x8f, 0xb9, 0x67, 0x1d, 0xf0, 0xb9, 0x51, 0xf1, 0xc0, + 0x70, 0xbb, 0x80, 0xcb, 0x6c, 0xa3, 0x00, 0x5f, 0xff, 0xfa, 0x5f, 0x2c, 0xd9, 0xad, 0x60, 0xc5, + 0x60, 0xef, 0x17, 0x82, 0x45, 0x73, 0x24, 0x1f, 0x58, 0x65, 0x40, 0x02, 0x5a, 0x4e, 0x70, 0x03, + 0x59, 0xb1, 0xbf, 0x85, 0x64, 0x82, 0x90, 0xe4, 0xee, 0x8e, 0x86, 0xe8, 0x44, 0xbe, 0x4f, 0x1f, + 0x25, 0xf1, 0x75, 0xec, 0x26, 0xa0, 0x00, 0x5d, 0x54, 0x87, 0x71, 0x5d, 0xb7, 0xed, 0xc5, 0x6c, + 0x96, 0x89, 0xc5, 0x1b, 0x89, 0x60, 0x68, 0xb6, 0x0e, 0x89, 0x63, 0x85, 0xd4, 0x01, 0x8d, 0x49, + 0x0e, 0xa3, 0x75, 0x99, 0xa1, 0xb1, 0xa2, 0x24, 0x1d, 0x0c, 0xd1, 0x6c, 0xa5, 0x56, 0x16, 0xc0, + 0x0e, 0x51, 0x54, 0x61, 0xb2, 0xb4, 0x51, 0x38, 0x16, 0x05, 0xea, 0xe4, 0x85, 0xd8, 0xbc, 0x1f, + 0x42, 0x19, 0x50, 0x0e, 0xb3, 0xc8, 0x9b, 0xff, 0xd7, 0x4d, 0x3c, 0x89, 0x85, 0xf0, 0x13, 0x03, + 0xb6, 0x01, 0x4d, 0xaf, 0x3c, 0x3b, 0xde, 0xe6, 0x85, 0xcb, 0x21, 0xc6, 0xc2, 0xd8, 0x01, 0x80, + 0x79, 0x66, 0x0d, 0x1d, 0xf6, 0x29, 0xe8, 0x48, 0x79, 0xff, 0xcf, 0x73, 0x50, 0x48, 0xf2, 0x43, + 0xa4, 0x3c, 0xa0, 0x0d, 0xe9, 0xc3, 0xf4, 0xe5, 0xdb, 0xf0, 0xec, 0x30, 0x7d, 0x07, 0x6e, 0x91, + 0x6b, 0x5a, 0xa4, 0x17, 0xed, 0xbe, 0x24, 0x49, 0xa7, 0xfc, 0x30, 0x48, 0x00, 0x6a, 0x77, 0x4c, + 0xe8, 0xb3, 0x5c, 0xe3, 0xf9, 0xd4, 0xcf, 0x74, 0x1b, 0x02, 0x6e, 0x22, 0x9d, 0x56, 0xe1, 0x66, + 0x9c, 0x7e, 0x30, 0xf2, 0x80, 0x4f, 0x0e, 0xf8, 0xa9, 0x5e, 0x44, 0x5b, 0x27, 0x70, 0x7b, 0x49, + 0x85, 0x37, 0xd3, 0x2f, 0x2f, 0x5b, 0xa0, 0xf3, 0x95, 0xaf, 0xe1, 0xa5, 0x00, 0xff, 0x4b, 0x24, + 0x67, 0xec, 0x2d, 0xc6, 0x58, 0xd5, 0x4f, 0x69, 0x66, 0x17, 0x74, 0x9a, 0x57, 0x11, 0xf1, 0x1e, + 0x35, 0x5f, 0x03, 0x40, 0x08, 0x10, 0xa4, 0xf7, 0x09, 0x9a, 0x6d, 0xe7, 0x83, 0xce, 0x7d, 0x9c, + 0xb0, 0xf2, 0x7b, 0xe5, 0x0d, 0xac, 0x97, 0x9f, 0xe3, 0x86, 0x38, 0xf0, 0x11, 0x20, 0xc0, 0x29, + 0xcf, 0xd8, 0xdf, 0xe5, 0x65, 0x60, 0xf7, 0xb8, 0x5f, 0x46, 0xf3, 0xfc, 0xa7, 0xa0, 0xe1, 0x8e, + 0xe1, 0x75, 0x10, 0x0f, 0x63, 0xe5, 0xd2, 0xf7, 0x47, 0xfb, 0xbe, 0x0e, 0xaf, 0xbe, 0x13, 0xc2, + 0x40, 0xb2, 0x23, 0x27, 0xaf, 0xac, 0x5f, 0xf0, 0xaa, 0x80, 0x8d, 0x24, 0xb3, 0xb3, 0xe1, 0xc9, + 0x07, 0x2f, 0x77, 0xfb, 0xaa, 0x8b, 0x8b, 0xc2, 0xae, 0x00, 0xc1, 0x4c, 0x38, 0x90, 0x47, 0xd5, + 0x45, 0xf4, 0x4c, 0xa9, 0x42, 0x8b, 0xe2, 0xb1, 0x78, 0xbd, 0x61, 0x9c, 0x00, 0x7c, 0x82, 0xb2, + 0x2e, 0x45, 0x47, 0x7d, 0x63, 0xe2, 0x1e, 0x2f, 0x6e, 0xe2, 0x1e, 0x5e, 0x73, 0xd9, 0x4d, 0xed, + 0x92, 0x8a, 0xef, 0x85, 0xd4, 0x03, 0x3b, 0x32, 0x15, 0x97, 0x0f, 0xff, 0x9b, 0x51, 0x5c, 0xaa, + 0xab, 0x22, 0xc2, 0x8a, 0x4d, 0x05, 0x74, 0x2b, 0x0a, 0x28, 0x01, 0x1b, 0x23, 0x92, 0x9b, 0xbf, + 0xe5, 0xec, 0xa7, 0xe4, 0x83, 0xe4, 0x9d, 0x1b, 0x8a, 0xf0, 0xde, 0x00, 0x4d, 0xd6, 0x11, 0x75, + 0x57, 0x7f, 0x59, 0x71, 0x71, 0x59, 0x21, 0x27, 0x60, 0x7e, 0x02, 0xe2, 0x8e, 0x0f, 0x70, 0x2f, + 0x2f, 0x74, 0x24, 0x63, 0x55, 0xd5, 0xfe, 0x16, 0xc0, 0x1c, 0x8a, 0xc4, 0x58, 0xf8, 0xf0, 0x2c, + 0x1f, 0x08, 0x52, 0xc2, 0x58, 0x3e, 0x1b, 0xe1, 0xbd, 0xe1, 0xa7, 0x01, 0x8b, 0x8a, 0x7a, 0xfb, + 0xf4, 0xcb, 0xf6, 0x56, 0x4a, 0xff, 0xff, 0x09, 0xa8, 0x01, 0xb3, 0x20, 0x8f, 0x1e, 0x8e, 0x17, + 0x39, 0x20, 0xca, 0xe8, 0x65, 0x83, 0x23, 0x98, 0x4a, 0x22, 0xf1, 0x9b, 0x90, 0xd6, 0x00, 0x73, + 0x43, 0x91, 0xe0, 0x6d, 0x4c, 0xf4, 0x5b, 0xdd, 0x17, 0x7b, 0xf5, 0x85, 0xf0, 0x46, 0x60, 0x63, + 0xd7, 0x28, 0xa8, 0xb6, 0x4e, 0xcb, 0x7b, 0xbb, 0xe2, 0xc2, 0xea, 0x00, 0x4d, 0x78, 0xd6, 0x55, + 0xae, 0xb4, 0x23, 0x09, 0x0f, 0xad, 0x27, 0x55, 0x97, 0x26, 0x45, 0x89, 0xfa, 0x55, 0xc5, 0x3a, + 0xc2, 0xb8, 0x04, 0x8e, 0xbc, 0xc3, 0xff, 0x9c, 0x2f, 0xf5, 0x8e, 0xe9, 0x7d, 0x14, 0x3d, 0x80, + 0x1b, 0xed, 0xb4, 0x69, 0xfa, 0xf8, 0xad, 0xe5, 0xd0, 0xd2, 0x36, 0xd2, 0xae, 0xae, 0xd8, 0x1b, + 0xe3, 0xba, 0x4f, 0xd9, 0x7e, 0x19, 0xc0, 0x11, 0xe3, 0x6c, 0xd2, 0x0b, 0x8a, 0xf3, 0xd2, 0x10, + 0xbc, 0x9a, 0x77, 0x77, 0xb1, 0x73, 0x87, 0xad, 0x83, 0x71, 0x87, 0x94, 0x04, 0x46, 0xb0, 0x8e, + 0x77, 0x05, 0x75, 0x7a, 0x4a, 0xba, 0x3c, 0xa6, 0x5a, 0x4f, 0x51, 0xb2, 0xcb, 0xff, 0x87, 0x09, + 0x00, 0x24, 0x0f, 0xb5, 0x98, 0x2f, 0x08, 0xae, 0x3c, 0x22, 0x58, 0x16, 0xb4, 0xf1, 0xfd, 0x2c, + 0xe6, 0x96, 0x27, 0xdc, 0xed, 0x2b, 0xd7, 0x5f, 0xc3, 0x44, 0x80, 0x20, 0xf3, 0xb1, 0x50, 0xbf, + 0x7d, 0x57, 0x72, 0x76, 0xf5, 0xf1, 0x6f, 0x30, 0xe9, 0x20, 0x09, 0x47, 0x6c, 0x1c, 0xbf, 0xcc, + 0x21, 0x81, 0x2f, 0x01, 0x57, 0x07, 0x61, 0x4b, 0xa5, 0x38, 0x60, 0x76, 0x02, 0x8c, 0xbf, 0xe6, + 0xa5, 0x82, 0x19, 0x60, 0xd6, 0x3e, 0x1b, 0x24, 0x02, 0x7a, 0xb3, 0x41, 0xa7, 0xcf, 0x15, 0xad, + 0x13, 0x2b, 0x8b, 0xc5, 0xdd, 0x45, 0x62, 0xe3, 0x47, 0xd1, 0x61, 0x2f, 0xf0, 0x2c, 0x85, 0x25, + 0xe2, 0x1e, 0x2e, 0x73, 0xd8, 0xee, 0x8d, 0xd4, 0x7f, 0xd4, 0x7f, 0xeb, 0x8e, 0xdc, 0x1e, 0xb8, + 0xc0, 0x00, 0x2e, 0xbe, 0x0e, 0x40, 0x54, 0x05, 0x2a, 0x4e, 0x96, 0x1d, 0x16, 0xa0, 0xeb, 0xe1, + 0xd4, 0xa8, 0x3b, 0xf1, 0x5b, 0x9e, 0x3d, 0xfc, 0xfb, 0x03, 0xbf, 0x2f, 0x39, 0x60, 0x70, 0x00, + 0x33, 0x1d, 0xc3, 0xce, 0x00, 0x5e, 0xbb, 0xc4, 0x8f, 0xf1, 0xbf, 0xef, 0xac, 0xbf, 0x5a, 0xaa, + 0xab, 0x29, 0x73, 0x42, 0x4f, 0xc2, 0x13, 0xe5, 0x84, 0xb0, 0xf8, 0x69, 0x40, 0x45, 0x72, 0xa6, + 0x5a, 0xf9, 0x16, 0x31, 0x73, 0xc2, 0x6f, 0xd2, 0xad, 0x71, 0x5b, 0xe1, 0x72, 0x40, 0x48, 0x87, + 0x34, 0x59, 0xd6, 0xbd, 0xfa, 0xe2, 0xb8, 0xad, 0x4b, 0x5b, 0x37, 0xc3, 0x4a, 0x00, 0x55, 0xfd, + 0x72, 0x06, 0x23, 0xdd, 0x82, 0x1a, 0x1f, 0x80, 0xa3, 0x9b, 0x57, 0xeb, 0x6f, 0xc6, 0xec, 0x30, + 0xa0, 0x20, 0x06, 0x23, 0x80, 0xa5, 0x97, 0xba, 0x8a, 0xff, 0x45, 0x2c, 0x14, 0x76, 0xc2, 0xca, + 0x19, 0x05, 0x52, 0xf7, 0x5a, 0xae, 0xae, 0xaf, 0x85, 0x89, 0x01, 0x11, 0xcd, 0xe9, 0x05, 0xed, + 0xfe, 0xcf, 0x09, 0xe0, 0x58, 0x4c, 0x25, 0x77, 0x40, 0x43, 0x02, 0xcf, 0xf0, 0xc1, 0x20, 0xb3, + 0xa7, 0x1f, 0xea, 0xf7, 0xfa, 0xe0, 0x28, 0x03, 0x20, 0xae, 0xa4, 0xf2, 0x77, 0x67, 0x78, 0xe2, + 0xb7, 0x15, 0x8e, 0x00, 0x06, 0x63, 0xb8, 0x57, 0x00, 0x3b, 0xee, 0xc5, 0x4f, 0xd5, 0x7d, 0x54, + 0x56, 0x3b, 0xa1, 0xcc, 0x1d, 0x5d, 0x4b, 0x6d, 0x83, 0xdc, 0x27, 0x80, 0x36, 0x37, 0x8b, 0x2b, + 0xdd, 0x5b, 0x0c, 0xe6, 0x1a, 0xd4, 0xe6, 0x16, 0xc3, 0x0a, 0xb8, 0x04, 0xc0, 0x32, 0xd4, 0xc9, + 0xad, 0xcf, 0x07, 0xc0, 0xf0, 0xf1, 0x18, 0x39, 0x7b, 0xe8, 0xbf, 0x00, 0xb0, 0x00, 0xe9, 0x1b, + 0x14, 0x6c, 0x6e, 0x3d, 0x4b, 0x15, 0xb5, 0x82, 0x8f, 0x47, 0x2f, 0x71, 0x78, 0xce, 0x58, 0x53, + 0x96, 0x02, 0x51, 0x80, 0x31, 0xc7, 0x10, 0xf9, 0xe9, 0xfe, 0x1d, 0x89, 0xe9, 0xe3, 0xca, 0xea, + 0x16, 0xf1, 0x3e, 0xc6, 0x7f, 0xc5, 0x2c, 0x66, 0x60, 0x3a, 0x48, 0x70, 0x1e, 0x21, 0xff, 0x85, + 0xdc, 0x00, 0xab, 0xa0, 0xa5, 0xa4, 0xbe, 0xf6, 0xab, 0xad, 0x56, 0xb5, 0x1e, 0xd2, 0x5f, 0x0d, + 0x12, 0x00, 0x63, 0x92, 0xa8, 0xdf, 0xe4, 0xe2, 0xe2, 0xb2, 0x43, 0x7b, 0xf7, 0x65, 0xbc, 0xb0, + 0xce, 0x01, 0x33, 0x56, 0x15, 0x15, 0x12, 0x3f, 0x89, 0x0e, 0x9e, 0x49, 0x8d, 0x61, 0xfd, 0xb1, + 0xb6, 0x45, 0xb6, 0x4f, 0x09, 0xd1, 0x65, 0x85, 0x09, 0x00, 0xf3, 0xd6, 0xa2, 0x05, 0x7b, 0xed, + 0x8c, 0x63, 0x0a, 0x12, 0xa2, 0x6e, 0xf7, 0x44, 0xc8, 0x90, 0xa5, 0x0b, 0x28, 0x03, 0x1f, 0x1f, + 0x84, 0xd7, 0xdc, 0x3d, 0x24, 0x42, 0x70, 0x97, 0xcd, 0x02, 0xc3, 0xb7, 0x72, 0xf9, 0x3c, 0x2e, + 0xe0, 0x03, 0x1f, 0x91, 0x92, 0x60, 0xd0, 0xff, 0xd7, 0x8a, 0xc9, 0x06, 0xcb, 0x90, 0xae, 0x21, + 0x81, 0x20, 0x5b, 0x6c, 0x6e, 0xd9, 0x77, 0x07, 0x21, 0x90, 0xa4, 0x7b, 0xe5, 0xb6, 0xfb, 0x8d, + 0xd1, 0x6b, 0x8c, 0x56, 0x35, 0x82, 0x67, 0x1d, 0x64, 0x60, 0x70, 0xc7, 0x07, 0x0a, 0xb8, 0x07, + 0xbb, 0x48, 0xd4, 0x52, 0xf4, 0x8f, 0xe0, 0x94, 0x8e, 0xb6, 0xd3, 0x4d, 0x96, 0x5b, 0xdb, 0x6f, + 0x04, 0x00, 0x40, 0x0a, 0x5d, 0xc4, 0xbf, 0x74, 0xd5, 0x32, 0xdb, 0x73, 0xf9, 0x7d, 0xc7, 0x3f, + 0x0d, 0x28, 0x03, 0x03, 0x47, 0x32, 0x13, 0xbc, 0xf7, 0x97, 0x5a, 0xdd, 0xc5, 0xe2, 0x7d, 0xf8, + 0x0c, 0x80, 0x1b, 0x21, 0x4c, 0x43, 0xe9, 0x8a, 0xf9, 0x98, 0xcb, 0x5d, 0xdd, 0x31, 0x58, 0xe0, + 0x63, 0xb8, 0x4f, 0x00, 0xcd, 0xd2, 0x2b, 0xab, 0xad, 0x5d, 0x59, 0x7f, 0x0a, 0xa8, 0x25, 0xd8, + 0x19, 0x74, 0xbe, 0x68, 0x5a, 0x9f, 0xdd, 0x51, 0x0b, 0xd2, 0x34, 0x2e, 0x1d, 0xc0, 0x0c, 0x74, + 0x6e, 0x89, 0xe8, 0x27, 0xfa, 0xc9, 0xdd, 0x62, 0xff, 0x63, 0x7b, 0xfc, 0x2e, 0xe2, 0x02, 0x88, + 0xdf, 0x73, 0xa4, 0xef, 0x85, 0xe7, 0x86, 0xef, 0xd1, 0x51, 0x4b, 0x82, 0x10, 0x30, 0x02, 0x9c, + 0x56, 0xaf, 0x97, 0x6e, 0x98, 0x8f, 0xce, 0xf8, 0xe1, 0x8e, 0x38, 0x5f, 0x22, 0x91, 0x41, 0xf2, + 0x14, 0x96, 0xab, 0x5c, 0x5d, 0xc5, 0xd6, 0xa5, 0x87, 0x61, 0x6c, 0x11, 0x84, 0x9d, 0xd1, 0xef, + 0xd7, 0xd5, 0x7c, 0x37, 0x80, 0x84, 0xd9, 0xaa, 0x4f, 0xc4, 0x34, 0xd6, 0xa5, 0x8d, 0x45, 0x1b, + 0x6b, 0x7f, 0xe1, 0x77, 0x00, 0x2a, 0xfa, 0x16, 0x5d, 0xe3, 0xe2, 0xc1, 0x90, 0x79, 0xb9, 0xe1, + 0x72, 0x43, 0xb6, 0xcf, 0xdf, 0xef, 0x86, 0x70, 0x01, 0x9d, 0xde, 0xb8, 0x3a, 0x47, 0xfa, 0x8d, + 0xcb, 0x6f, 0x8d, 0xa8, 0xae, 0xe5, 0xb4, 0x58, 0xbd, 0xdf, 0x1c, 0xc3, 0x04, 0x80, 0x0f, 0xaf, + 0x86, 0xdb, 0xba, 0x7f, 0xf9, 0xea, 0x2e, 0xac, 0x96, 0x94, 0xf0, 0x8a, 0xee, 0x6f, 0x6e, 0xf6, + 0x54, 0xc3, 0x4a, 0x02, 0x83, 0x0b, 0x4b, 0x1d, 0x1a, 0xaf, 0x96, 0x0a, 0x37, 0x89, 0x54, 0x6a, + 0xfa, 0xd4, 0x59, 0x61, 0xc2, 0x40, 0x12, 0x99, 0x85, 0xcb, 0x43, 0xf1, 0xbc, 0x83, 0xf8, 0x49, + 0x0a, 0x48, 0x9f, 0x06, 0x42, 0xb9, 0x33, 0x88, 0x57, 0x96, 0xff, 0xc3, 0x2e, 0x04, 0x0d, 0x35, + 0x87, 0x0a, 0x2d, 0x75, 0x77, 0x77, 0x59, 0xa0, 0x78, 0x3f, 0x2c, 0x3b, 0x09, 0xe0, 0x04, 0xff, + 0xe2, 0xb6, 0x47, 0x7b, 0xac, 0xf1, 0xaf, 0x65, 0xd1, 0x77, 0x85, 0xf0, 0x08, 0x44, 0x7e, 0x04, + 0xf3, 0xcd, 0x3e, 0x21, 0x83, 0x23, 0x41, 0xec, 0x3a, 0x0b, 0xee, 0x16, 0x07, 0xe0, 0xd8, 0x3a, + 0x12, 0xbd, 0x3e, 0x56, 0xd8, 0xd6, 0x1e, 0x70, 0x01, 0xfa, 0x1f, 0xb5, 0x49, 0x16, 0xbb, 0xee, + 0xd4, 0x7b, 0x4b, 0x2c, 0xdb, 0x03, 0xc2, 0xe9, 0x58, 0xa7, 0x88, 0xc0, 0x4b, 0xcb, 0xcf, 0x1f, + 0x32, 0xd7, 0xf8, 0x5b, 0x01, 0x0a, 0x46, 0xfc, 0xb9, 0x4c, 0x90, 0x51, 0x58, 0xb9, 0xe1, 0xca, + 0xcd, 0x0a, 0x57, 0x47, 0xe1, 0x4a, 0xa5, 0x2e, 0xda, 0xcc, 0xb6, 0x0e, 0x7e, 0x37, 0x42, 0xec, + 0xfd, 0xdc, 0x56, 0x5a, 0xed, 0xb9, 0xf8, 0xe0, 0x00, 0x4e, 0x38, 0x38, 0x65, 0xc0, 0x18, 0x9e, + 0x33, 0xfc, 0xc2, 0x7e, 0x7d, 0x6d, 0xde, 0x27, 0xe3, 0x9a, 0x7d, 0xf0, 0x52, 0xd8, 0xc7, 0x70, + 0x07, 0x00, 0x19, 0x0a, 0x63, 0x3f, 0x3b, 0xee, 0x3a, 0x5d, 0x64, 0xe3, 0xf1, 0xc9, 0x77, 0xdd, + 0xc7, 0x00, 0x02, 0xff, 0x80, 0x3f, 0x10, 0x1d, 0x00, 0xb3, 0x6c, 0xcc, 0x5d, 0xb7, 0x2b, 0x03, + 0xef, 0x97, 0x6d, 0x8c, 0x00, 0x03, 0x31, 0xc7, 0x0c, 0xe0, 0x33, 0xdc, 0xaf, 0xbf, 0x5d, 0x6b, + 0x27, 0xfa, 0x35, 0x12, 0xfb, 0x8b, 0x8a, 0xcf, 0x7c, 0x15, 0xc4, 0xbc, 0xbe, 0x26, 0xc4, 0x2d, + 0xa1, 0x39, 0x66, 0xf7, 0x9d, 0x92, 0xec, 0x9f, 0x41, 0xc0, 0x00, 0xcc, 0x77, 0x09, 0x92, 0x02, + 0x27, 0x6a, 0x9b, 0x7e, 0x68, 0x7e, 0x68, 0x39, 0xa0, 0xf8, 0x60, 0x41, 0x85, 0x2b, 0x58, 0xa3, + 0x73, 0xfa, 0xd7, 0xac, 0x1d, 0x5d, 0x33, 0xfc, 0x70, 0x00, 0x37, 0x1c, 0x78, 0x29, 0x0c, 0x85, + 0x30, 0x7f, 0xe5, 0xf5, 0x8b, 0x96, 0xb5, 0x4d, 0xbe, 0x36, 0xf7, 0xfd, 0xfe, 0x38, 0x00, 0x1b, + 0x8d, 0x1c, 0x30, 0xa0, 0x02, 0x97, 0xd8, 0xb5, 0xeb, 0x0b, 0x4b, 0x35, 0x2d, 0x97, 0xb9, 0xa1, + 0xf6, 0x5b, 0xe1, 0x35, 0x00, 0xe7, 0xad, 0xd0, 0x62, 0x7b, 0xf6, 0xdd, 0x5d, 0x72, 0x78, 0xb8, + 0xad, 0x65, 0xec, 0x94, 0xf0, 0xc0, 0x18, 0x44, 0x29, 0x17, 0x55, 0x93, 0x1a, 0x23, 0x15, 0x26, + 0xbd, 0xb1, 0x0b, 0x0d, 0xb7, 0xb6, 0x38, 0x00, 0x19, 0x8e, 0xe1, 0x52, 0x42, 0x3c, 0x34, 0x53, + 0x8f, 0x83, 0xb0, 0x64, 0xab, 0x14, 0xa2, 0xb7, 0x72, 0xf8, 0xbb, 0x96, 0x1f, 0x86, 0x54, 0x01, + 0x3a, 0x66, 0xfc, 0x93, 0xb7, 0xa2, 0x6c, 0x4b, 0xe6, 0x29, 0xc5, 0xdc, 0x5c, 0x56, 0x29, 0xb8, + 0x9c, 0x1c, 0xfc, 0x3b, 0x09, 0xe0, 0x21, 0x4c, 0xc1, 0x40, 0x25, 0xa2, 0xb2, 0x9a, 0x0b, 0xe5, + 0x81, 0x79, 0x6c, 0x5e, 0x8b, 0xc0, 0x16, 0x84, 0x29, 0x14, 0x00, 0x62, 0x5e, 0x28, 0x0d, 0xfd, + 0x76, 0x78, 0x76, 0x15, 0xca, 0x31, 0x5f, 0x27, 0x1c, 0x45, 0xc7, 0xdc, 0xe5, 0x91, 0xc8, 0xb8, + 0xe0, 0x00, 0x5e, 0x3b, 0x85, 0x70, 0x06, 0xa8, 0xe2, 0xa1, 0x67, 0xd2, 0xae, 0x2e, 0xef, 0x15, + 0xd8, 0x9c, 0x33, 0x42, 0x17, 0x78, 0x6f, 0xae, 0x18, 0x70, 0x19, 0x4a, 0x85, 0x63, 0x4b, 0xf9, + 0xfc, 0xbf, 0x46, 0xf3, 0xf5, 0xd1, 0x5d, 0xfe, 0x6d, 0x4a, 0x9c, 0x06, 0x84, 0x29, 0x14, 0x18, + 0xa3, 0x12, 0xfa, 0x85, 0x66, 0xf5, 0x57, 0x43, 0x8f, 0x83, 0x2c, 0xd5, 0x62, 0x7c, 0x70, 0x00, + 0x2f, 0x1d, 0xc3, 0x58, 0x13, 0x59, 0x31, 0xab, 0x8d, 0xa8, 0x4a, 0xba, 0xb8, 0xbe, 0xb7, 0x12, + 0x7b, 0xba, 0x0f, 0xc0, 0x50, 0x42, 0x91, 0x47, 0x12, 0x3c, 0xdc, 0x56, 0x7f, 0x1b, 0xfd, 0x97, + 0xe6, 0xeb, 0xca, 0x63, 0x80, 0x01, 0x98, 0xee, 0x17, 0xc0, 0x18, 0x03, 0xc1, 0xfb, 0x47, 0xf7, + 0xfb, 0x9a, 0x08, 0x9d, 0x0e, 0x2b, 0x96, 0x03, 0xb4, 0x1b, 0x07, 0xc0, 0xb6, 0xba, 0xff, 0x0b, + 0xa8, 0x01, 0xb8, 0xe1, 0x59, 0xe5, 0x11, 0xb6, 0x56, 0x5a, 0xcd, 0x07, 0x65, 0x64, 0x68, 0x32, + 0x66, 0x3b, 0xc1, 0x90, 0xac, 0x2a, 0xa0, 0x07, 0x46, 0xce, 0x27, 0x86, 0xb9, 0x59, 0x44, 0x3e, + 0x8a, 0x89, 0x4b, 0x72, 0x2b, 0xd9, 0x61, 0x85, 0x00, 0x30, 0x74, 0x36, 0x56, 0xbe, 0xeb, 0x39, + 0x79, 0x7b, 0xa1, 0xf4, 0xee, 0xb1, 0x75, 0xcb, 0x0b, 0x12, 0x02, 0xc2, 0xa1, 0xbd, 0x5d, 0xef, + 0x35, 0x7b, 0xdd, 0x5c, 0xd0, 0xb8, 0x58, 0x90, 0x14, 0x06, 0x2c, 0x17, 0x62, 0xb2, 0xee, 0xe7, + 0x87, 0xde, 0xf0, 0xb1, 0x20, 0x24, 0xe4, 0x22, 0xa7, 0x63, 0x2f, 0xba, 0xbf, 0xab, 0x8b, 0xe1, + 0x65, 0x00, 0x75, 0xea, 0x30, 0x29, 0xaf, 0xce, 0xfd, 0x59, 0x3b, 0x27, 0xc4, 0x04, 0x42, 0x9b, + 0x6e, 0xda, 0xea, 0xa2, 0x8d, 0xb1, 0x41, 0x9f, 0xd5, 0xdc, 0x73, 0x1c, 0x07, 0x82, 0x98, 0x52, + 0x27, 0xb6, 0x7d, 0x8d, 0x64, 0xf8, 0xa2, 0xb6, 0xd3, 0xa7, 0xa3, 0x83, 0x85, 0xd4, 0x07, 0x3b, + 0x84, 0xc5, 0x7f, 0x2b, 0x3b, 0x07, 0x2f, 0x2d, 0x9f, 0x83, 0xba, 0x05, 0xe5, 0x9b, 0x86, 0x3e, + 0x10, 0xc0, 0xb3, 0x2d, 0x8a, 0x77, 0xe1, 0x88, 0x25, 0xc2, 0x15, 0x96, 0xb5, 0x77, 0x36, 0x48, + 0xca, 0x1c, 0x07, 0x83, 0x90, 0x18, 0x20, 0xba, 0x2f, 0xdd, 0xdb, 0x15, 0xb6, 0x38, 0x63, 0xbc, + 0x10, 0x42, 0x91, 0x5b, 0xbb, 0xa6, 0xfe, 0x66, 0x1f, 0xc5, 0xb7, 0x4e, 0xef, 0x2d, 0xc7, 0x31, + 0xdc, 0x32, 0xe0, 0x1d, 0x7e, 0x1e, 0x5f, 0x9f, 0x7f, 0xed, 0x5e, 0x99, 0xfe, 0x5e, 0xbd, 0x61, + 0xd3, 0x8b, 0xb8, 0xbe, 0xf8, 0x65, 0x40, 0x20, 0xcd, 0x49, 0x3d, 0xd6, 0xf7, 0xad, 0x6f, 0xf7, + 0x5a, 0xc2, 0x98, 0x00, 0x3d, 0x42, 0xb5, 0x6c, 0x5f, 0x1c, 0xc9, 0xff, 0xac, 0xdc, 0xdf, 0xa2, + 0xbb, 0xa0, 0x21, 0xf4, 0xa1, 0x1a, 0x03, 0x58, 0x74, 0x21, 0xb7, 0x02, 0x26, 0x90, 0xfc, 0x36, + 0xe4, 0x80, 0xee, 0x95, 0xd5, 0xb4, 0x2d, 0x96, 0x37, 0x55, 0xae, 0xba, 0x25, 0xf8, 0x7b, 0x02, + 0x3c, 0x67, 0x2c, 0xf5, 0x75, 0x7d, 0x5d, 0x45, 0x6a, 0x2b, 0xc3, 0x5a, 0xfc, 0x2e, 0xe2, 0x52, + 0x48, 0x0c, 0xba, 0x3a, 0xf5, 0x7f, 0x57, 0xbd, 0xf0, 0xba, 0x80, 0x18, 0xb6, 0xe5, 0x86, 0xad, + 0xe4, 0x52, 0x43, 0xec, 0x83, 0xb2, 0x17, 0x76, 0x47, 0x85, 0x61, 0x5c, 0x05, 0x55, 0xf3, 0x57, + 0xf5, 0xbd, 0xee, 0xb5, 0x5c, 0x30, 0x04, 0x80, 0xa4, 0x50, 0x61, 0x70, 0x54, 0x43, 0xea, 0x7f, + 0x8f, 0x27, 0x44, 0xa0, 0xe3, 0x73, 0xbc, 0x5d, 0x9c, 0xf0, 0xb0, 0x77, 0x8c, 0x31, 0xdc, 0x34, + 0x48, 0x11, 0x1f, 0x31, 0xf1, 0xda, 0xe5, 0xb5, 0xdc, 0x58, 0x1f, 0x82, 0xf5, 0xa8, 0xac, 0x5e, + 0x58, 0x61, 0x40, 0x42, 0x05, 0x1d, 0x43, 0xbb, 0x96, 0xb7, 0x3f, 0xeb, 0x79, 0x60, 0xab, 0x2a, + 0xd8, 0x5d, 0x40, 0x2b, 0x3f, 0x10, 0x1b, 0xac, 0xbb, 0xf5, 0xab, 0xf8, 0xbb, 0x8b, 0x9e, 0xc2, + 0xf8, 0x04, 0x08, 0xfd, 0x4e, 0x7d, 0x72, 0xa8, 0x97, 0xaa, 0x23, 0x41, 0xcb, 0xff, 0x2c, 0x34, + 0xa0, 0x47, 0x45, 0xfd, 0xfe, 0xad, 0xd7, 0xaf, 0xba, 0xb8, 0xbd, 0x78, 0x16, 0x01, 0x4c, 0xed, + 0xac, 0xbe, 0xfd, 0x44, 0xd8, 0xee, 0x30, 0x00, 0x0d, 0xc7, 0x1c, 0x33, 0x80, 0x57, 0x68, 0x87, + 0xaa, 0x2c, 0x19, 0x0b, 0x2f, 0xe8, 0x9d, 0x5e, 0xfb, 0xe5, 0x84, 0xdc, 0x00, 0x85, 0xb3, 0x07, + 0x35, 0xe7, 0xfa, 0xf4, 0xb6, 0x48, 0x52, 0x5d, 0x59, 0x29, 0xa0, 0x2e, 0xe8, 0x36, 0x12, 0x5b, + 0x58, 0x59, 0xc0, 0x09, 0x6d, 0x44, 0xf0, 0x99, 0xdd, 0xd7, 0xbc, 0x23, 0xc3, 0xa5, 0xd6, 0x62, + 0xce, 0xfa, 0x44, 0xf6, 0x7c, 0x28, 0xa0, 0x13, 0x82, 0x36, 0x96, 0xa5, 0xf1, 0xf7, 0xc5, 0x77, + 0xd7, 0x77, 0xc3, 0x4a, 0x00, 0x44, 0x6e, 0x6e, 0x13, 0xee, 0xf5, 0xff, 0xdc, 0x9d, 0x7f, 0xb0, + 0xba, 0x82, 0x5f, 0x37, 0x4b, 0xeb, 0xf7, 0x8a, 0xcd, 0x41, 0x59, 0x67, 0xd8, 0x4c, 0x90, 0x04, + 0x54, 0xce, 0x4e, 0xd6, 0x2e, 0x2b, 0x15, 0xad, 0x10, 0xce, 0x8f, 0x99, 0xc3, 0x09, 0x57, 0x5c, + 0x2e, 0xe0, 0x06, 0x56, 0x9f, 0x26, 0xbd, 0xd7, 0x34, 0x1f, 0x07, 0xdd, 0x66, 0xaf, 0x81, 0x6e, + 0x95, 0xee, 0xf8, 0x57, 0x00, 0x23, 0x77, 0x2b, 0x07, 0x1e, 0x96, 0xd1, 0x6e, 0xfd, 0x5c, 0xf3, + 0x79, 0x3f, 0xc0, 0xe2, 0x0c, 0x42, 0x9b, 0xb6, 0x2d, 0x85, 0x06, 0xe4, 0x8e, 0xbe, 0xb2, 0x82, + 0xe0, 0xe4, 0xf9, 0xde, 0x3c, 0x7c, 0x71, 0x7c, 0xf2, 0xc9, 0x6b, 0x1c, 0xfc, 0x70, 0x00, 0x37, + 0x1c, 0x1e, 0x19, 0x0c, 0x85, 0x22, 0x1e, 0xd9, 0xe3, 0xcb, 0xe3, 0x73, 0x10, 0x7d, 0xc7, 0x5f, + 0x67, 0x2d, 0x71, 0x9b, 0xb3, 0x9f, 0xf1, 0x8e, 0x00, 0x06, 0x63, 0xbf, 0x0a, 0x5d, 0x73, 0x74, + 0x39, 0xd6, 0x2e, 0x35, 0x43, 0x8f, 0xd3, 0x15, 0x8e, 0x00, 0x06, 0xe3, 0x8e, 0x19, 0x70, 0x06, + 0x2a, 0x3a, 0x3d, 0x8f, 0x12, 0x12, 0xc8, 0x4d, 0xa8, 0x96, 0x05, 0xfa, 0x9f, 0x9f, 0xcb, 0xa9, + 0x92, 0xe0, 0x49, 0x06, 0x21, 0x48, 0xac, 0x2f, 0xa3, 0x9f, 0x62, 0x49, 0xf4, 0xdc, 0xae, 0xa1, + 0xff, 0x62, 0x1e, 0xeb, 0xd4, 0x70, 0x00, 0x2f, 0x1d, 0xc3, 0x38, 0x0c, 0xeb, 0xf6, 0x53, 0xee, + 0x63, 0x98, 0x39, 0x6d, 0xc5, 0xcb, 0x6a, 0x2b, 0x1d, 0xe7, 0x67, 0x69, 0xa8, 0xad, 0x5e, 0x2c, + 0x2e, 0xa0, 0x10, 0x7e, 0x41, 0xbe, 0x78, 0xff, 0x56, 0x4a, 0xcb, 0x8b, 0xcb, 0x09, 0xb8, 0x44, + 0xc1, 0xc4, 0xb2, 0x76, 0x4e, 0xa5, 0x84, 0xbc, 0x56, 0xa5, 0x84, 0xe8, 0xa1, 0x85, 0x00, 0x62, + 0xc0, 0xc4, 0x8a, 0xda, 0xfe, 0xd0, 0xac, 0x5d, 0xc5, 0xe7, 0x8b, 0xd2, 0xaa, 0xdd, 0xe2, 0xbb, + 0xf0, 0x24, 0x42, 0x91, 0xdf, 0xb7, 0xd6, 0x52, 0xe8, 0x2b, 0x15, 0xd8, 0xad, 0x4e, 0x78, 0xa7, + 0x1d, 0x9f, 0x22, 0x4e, 0x0e, 0x00, 0x05, 0xe3, 0xbc, 0x30, 0x20, 0x29, 0x12, 0x3e, 0xdf, 0xdb, + 0xcb, 0x19, 0xf6, 0x0b, 0x6e, 0x62, 0xbe, 0x36, 0xd4, 0xbd, 0x63, 0x80, 0x01, 0x78, 0xe3, 0xc0, + 0x64, 0x89, 0x0a, 0x45, 0x1e, 0x72, 0xc5, 0xef, 0x1d, 0xf8, 0x9b, 0x35, 0xb7, 0xcb, 0xdb, 0x71, + 0x72, 0xb0, 0x5e, 0x38, 0x00, 0x15, 0x8e, 0x3c, 0x0e, 0x10, 0x59, 0x93, 0xef, 0x7e, 0xe2, 0xb1, + 0xc0, 0x00, 0xbc, 0x71, 0xf0, 0x72, 0x14, 0xea, 0xb4, 0x32, 0xf8, 0xba, 0xc5, 0xd0, 0xd3, 0x37, + 0x4e, 0xb1, 0xc0, 0x00, 0xcc, 0x71, 0xc2, 0xf8, 0x12, 0xc8, 0x81, 0xbc, 0x6e, 0xaf, 0x09, 0xd1, + 0x6b, 0xba, 0x27, 0x45, 0xdc, 0x14, 0x42, 0x94, 0xcb, 0x58, 0xb9, 0x58, 0x06, 0x7a, 0x51, 0x8f, + 0xfd, 0x18, 0x9f, 0x29, 0xe9, 0x9c, 0xfa, 0xd8, 0xc7, 0x5f, 0x8c, 0x70, 0x00, 0x33, 0x1c, 0x70, + 0x9e, 0x02, 0x3b, 0x09, 0x64, 0x7e, 0xef, 0x3d, 0x0a, 0x12, 0x24, 0x57, 0xba, 0x24, 0x44, 0x87, + 0xf8, 0x20, 0x02, 0x80, 0x52, 0xae, 0xd8, 0x58, 0x34, 0x77, 0x39, 0xe3, 0xb7, 0x8e, 0x56, 0x2a, + 0x36, 0x4c, 0x1a, 0x16, 0xb4, 0xdf, 0xe3, 0x1c, 0x00, 0x0d, 0xc7, 0x7e, 0x14, 0x9c, 0xf3, 0xc1, + 0xfb, 0xe2, 0x83, 0x57, 0x6d, 0x33, 0xfc, 0x5c, 0x5c, 0x5c, 0x49, 0xe3, 0x80, 0x01, 0x98, 0xee, + 0x19, 0x24, 0x00, 0x8e, 0xec, 0x5f, 0xac, 0x5f, 0x6f, 0x29, 0xe8, 0x35, 0x86, 0x42, 0x45, 0xec, + 0x46, 0x0d, 0x83, 0x21, 0x0a, 0x6c, 0xb3, 0x75, 0x97, 0x02, 0x80, 0x64, 0x29, 0x10, 0xf3, 0xde, + 0xf6, 0x0b, 0x17, 0x18, 0xac, 0x1b, 0x25, 0x76, 0xbd, 0x91, 0xdb, 0x9f, 0x60, 0xb3, 0x38, 0x0f, + 0x3c, 0x2c, 0x16, 0x19, 0xe0, 0x7c, 0x47, 0x1e, 0x02, 0x26, 0x14, 0xf3, 0xfa, 0xd6, 0x21, 0x60, + 0x9e, 0xd4, 0x5c, 0x5c, 0x4f, 0xa3, 0x8f, 0x07, 0x21, 0x00, 0xa6, 0xae, 0xb4, 0xdc, 0xbf, 0x07, + 0xae, 0xef, 0xd6, 0x8e, 0x0e, 0x17, 0x70, 0x01, 0x0b, 0xb6, 0xe6, 0x87, 0xa6, 0xf3, 0xa2, 0x2d, + 0x96, 0x0a, 0xac, 0x84, 0xbb, 0x60, 0x8a, 0x13, 0x20, 0x4f, 0xc0, 0xfe, 0x07, 0xf9, 0x16, 0x61, + 0x7c, 0x04, 0x40, 0x33, 0xcf, 0xcd, 0xba, 0xf5, 0xb1, 0x38, 0x6a, 0xe2, 0x30, 0x66, 0x7f, 0xcb, + 0x0d, 0x60, 0x02, 0xfe, 0xeb, 0x07, 0x67, 0xaf, 0x7e, 0x9e, 0x88, 0xbd, 0x5d, 0x61, 0x23, 0xc4, + 0xbc, 0xf3, 0xc9, 0x8a, 0x07, 0xfa, 0xe0, 0xa0, 0x14, 0x05, 0x25, 0xd9, 0x2d, 0xc1, 0xd5, 0xc7, + 0x2b, 0xb6, 0xa3, 0x07, 0xd0, 0xa0, 0xdc, 0x3e, 0xc9, 0x55, 0xad, 0x27, 0x79, 0x94, 0x70, 0x78, + 0x66, 0x14, 0xc4, 0xb8, 0xec, 0x91, 0x2e, 0x09, 0x72, 0x66, 0x77, 0xdd, 0xd1, 0xc1, 0xc0, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x2b, 0x15, 0xb0, 0x52, 0x04, 0x3d, 0xdd, 0xf0, 0xaf, 0x41, 0x16, + 0x89, 0xec, 0x21, 0x77, 0x68, 0x0c, 0x63, 0x50, 0x4e, 0xe4, 0x1a, 0x61, 0x95, 0x6b, 0xe8, 0x24, + 0xf0, 0x67, 0x82, 0x94, 0x3d, 0xa0, 0xdf, 0xa0, 0x8f, 0x46, 0x70, 0x44, 0x1e, 0x77, 0xfc, 0x4b, + 0xdd, 0xb6, 0xed, 0x88, 0xeb, 0xd3, 0xf6, 0x2d, 0xf5, 0x06, 0x3c, 0xa2, 0xab, 0x50, 0x45, 0xcb, + 0xd5, 0x42, 0x3d, 0x7f, 0x06, 0x9c, 0xb9, 0xe0, 0xf8, 0x21, 0xeb, 0xd0, 0xc7, 0x04, 0x56, 0xb7, + 0x7f, 0xaf, 0x45, 0xf2, 0x6a, 0xf0, 0x28, 0xf3, 0x55, 0x57, 0xeb, 0xd0, 0x3c, 0x73, 0x6a, 0xb0, + 0x41, 0xc9, 0xdd, 0xc2, 0x7d, 0x7a, 0x3b, 0x93, 0x7b, 0x83, 0x9e, 0x6c, 0x33, 0xba, 0x20, 0x8a, + 0x51, 0xfa, 0x78, 0x2c, 0xd4, 0xb9, 0x10, 0x23, 0x24, 0x3c, 0x70, 0x19, 0xb4, 0x32, 0xcf, 0x98, + 0x78, 0x3f, 0x8d, 0xf2, 0xc8, 0xba, 0xe0, 0x00, 0x13, 0xa6, 0x3c, 0x01, 0xe2, 0xdc, 0x9f, 0x45, + 0x32, 0x95, 0x18, 0xaf, 0x13, 0x5a, 0xeb, 0xd7, 0xe2, 0x05, 0xea, 0xaa, 0x90, 0xd3, 0x50, 0x63, + 0x44, 0x04, 0xb6, 0x79, 0x0d, 0xe5, 0xf5, 0x67, 0xfc, 0xd8, 0x97, 0xab, 0xc5, 0xf5, 0x78, 0x6b, + 0xaf, 0x7d, 0x60, 0xf9, 0x79, 0x32, 0x6e, 0x4c, 0x67, 0x3d, 0x6f, 0xe2, 0x41, 0x2d, 0x4c, 0x5d, + 0xf0, 0xef, 0xbd, 0xee, 0x97, 0x7c, 0xdb, 0xdf, 0xc1, 0x6f, 0xbb, 0xf1, 0x3e, 0xed, 0xff, 0x7d, + 0xea, 0x32, 0xb3, 0xe1, 0x1e, 0x0b, 0x3a, 0xf5, 0x75, 0x79, 0xb9, 0xb8, 0x9d, 0x01, 0xd5, 0x9e, + 0x3a, 0xd5, 0xa2, 0x9a, 0x70, 0x6f, 0x68, 0x8a, 0x2c, 0xd9, 0x37, 0x72, 0xfe, 0x09, 0xf9, 0xbb, + 0xb8, 0x8e, 0x09, 0x7b, 0xb6, 0xf0, 0xd5, 0x7b, 0xe2, 0x3c, 0x47, 0xef, 0x70, 0x27, 0xf0, 0x44, + 0x59, 0x7e, 0xd0, 0xaf, 0x27, 0x49, 0x41, 0xa6, 0x26, 0xb8, 0x4a, 0x2f, 0xf4, 0x8b, 0x84, 0xe4, + 0x25, 0xda, 0x84, 0x79, 0x6c, 0x7b, 0x82, 0x9e, 0x4b, 0xbe, 0x16, 0xea, 0xf1, 0x1d, 0x8b, 0xbd, + 0xc1, 0xef, 0x20, 0xa6, 0x9d, 0xb8, 0x3e, 0xeb, 0x14, 0x09, 0xfd, 0x5e, 0x1a, 0xea, 0xf3, 0x75, + 0x78, 0x20, 0xeb, 0x14, 0x23, 0xd5, 0xe1, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x2c, 0x16, + 0x30, 0x89, 0x73, 0x6d, 0xca, 0xc8, 0xae, 0xb3, 0xbe, 0xac, 0x3d, 0x17, 0xc4, 0xfc, 0x87, 0x5d, + 0xd7, 0x42, 0x5b, 0xe8, 0x95, 0x5d, 0x58, 0xf0, 0x87, 0xf8, 0x67, 0x86, 0x11, 0x80, 0x4a, 0xd7, + 0x79, 0xf5, 0xbd, 0x7f, 0xff, 0x4b, 0xc8, 0x31, 0xf5, 0xf0, 0x48, 0x5d, 0x12, 0xff, 0xe4, 0xe5, + 0xf3, 0x72, 0x6d, 0xd2, 0xf7, 0x48, 0x92, 0xfd, 0x65, 0x5d, 0x9f, 0x97, 0x17, 0x38, 0xae, 0xbc, + 0xff, 0xfe, 0x10, 0x09, 0xaa, 0xfa, 0xaa, 0xaf, 0xc1, 0x02, 0xbf, 0x86, 0x7f, 0xf9, 0x7a, 0x18, + 0xd3, 0x77, 0xe4, 0xc2, 0x75, 0x7f, 0xab, 0xd7, 0x2d, 0xb8, 0x51, 0xca, 0x48, 0x3a, 0x34, 0xdb, + 0xef, 0xae, 0xa5, 0xc3, 0x3f, 0x42, 0x27, 0x93, 0x94, 0xc7, 0x72, 0xa7, 0x27, 0x08, 0x72, 0x74, + 0x51, 0xef, 0x7d, 0xb4, 0xfe, 0x08, 0xb9, 0xaa, 0x86, 0xff, 0x26, 0xad, 0x7c, 0xdd, 0xd5, 0x72, + 0x15, 0xef, 0x27, 0x0a, 0x63, 0x6a, 0xd5, 0x51, 0x25, 0x6f, 0x6d, 0x26, 0xa9, 0x64, 0x88, 0x37, + 0xd5, 0xe6, 0xe8, 0xbd, 0x08, 0x74, 0x21, 0xe2, 0xba, 0x16, 0xd3, 0xf6, 0x29, 0x6b, 0xf3, 0x09, + 0xad, 0x5f, 0x76, 0xda, 0xc4, 0x44, 0x42, 0x36, 0xb7, 0x55, 0xee, 0x87, 0xf0, 0x96, 0x4c, 0xee, + 0xf7, 0xcb, 0x5a, 0x2f, 0x9b, 0xc4, 0x38, 0x61, 0x68, 0xea, 0x92, 0x5e, 0x50, 0x82, 0xd2, 0x88, + 0xec, 0xa9, 0x25, 0xfa, 0x2e, 0x53, 0x77, 0xcf, 0x92, 0x61, 0x9b, 0x18, 0x85, 0xbf, 0x45, 0xf3, + 0x05, 0x96, 0xb3, 0xf0, 0x48, 0x27, 0x4d, 0xfe, 0x9b, 0xa1, 0x2f, 0x3f, 0x43, 0xa2, 0x9f, 0xab, + 0xfc, 0x11, 0x15, 0xb7, 0xf7, 0xf8, 0x22, 0xdb, 0x4a, 0x5b, 0xe5, 0xee, 0xc6, 0xb9, 0x2f, 0x5f, + 0x8b, 0xdc, 0x9b, 0xb7, 0x5b, 0xe0, 0x8f, 0xb6, 0xac, 0x49, 0xd0, 0xd7, 0x7d, 0x7b, 0xea, 0xc7, + 0xd1, 0x4e, 0xa3, 0xe8, 0x28, 0xf2, 0x73, 0x14, 0x9f, 0xf8, 0x23, 0xd3, 0xbc, 0xab, 0xb3, 0xd5, + 0x62, 0xfa, 0xb9, 0xf3, 0x5a, 0x69, 0xa6, 0xbd, 0x19, 0x82, 0xe4, 0x1e, 0xab, 0x88, 0xe0, 0x88, + 0x73, 0xa7, 0xf4, 0xdd, 0xd2, 0x4a, 0xfe, 0x8a, 0xf7, 0xd1, 0x9c, 0xae, 0x0b, 0x4b, 0x4a, 0xd3, + 0xd6, 0xe0, 0xbc, 0x9c, 0x9f, 0xe0, 0x97, 0x6d, 0xd5, 0x5a, 0x4a, 0xc5, 0x72, 0x9b, 0x2c, 0x2b, + 0xa0, 0x46, 0x3b, 0x49, 0xc8, 0x08, 0x2e, 0xb7, 0xd1, 0x1e, 0x12, 0xe2, 0xaf, 0x3d, 0xb3, 0x2d, + 0x0e, 0x69, 0xf1, 0x26, 0xe5, 0xc7, 0x85, 0xd8, 0xf7, 0xff, 0xc6, 0x7b, 0xff, 0x42, 0x1c, 0x40, + 0x8b, 0x77, 0xad, 0xfc, 0x27, 0x27, 0xf4, 0x92, 0xc5, 0xf4, 0x3f, 0xa1, 0x7e, 0x09, 0x02, 0x0b, + 0x5b, 0xd6, 0x24, 0x24, 0x47, 0xb5, 0x77, 0xbf, 0x12, 0x22, 0xec, 0xab, 0xee, 0xe3, 0x7a, 0x3e, + 0xbe, 0x27, 0xb6, 0xbb, 0xb6, 0xf9, 0x0f, 0x93, 0xba, 0xe8, 0x98, 0x7c, 0x4e, 0xa9, 0x97, 0xda, + 0xa7, 0xe0, 0x86, 0xdd, 0xbb, 0xfc, 0xa5, 0x55, 0xfd, 0xd5, 0xf5, 0xc1, 0x26, 0xda, 0xff, 0x5d, + 0x19, 0x93, 0xf6, 0x6a, 0xd7, 0xc7, 0x9f, 0x48, 0x99, 0x4e, 0x9d, 0x3a, 0x7e, 0xf4, 0xde, 0xb8, + 0xbb, 0xbd, 0xdd, 0xff, 0x66, 0x5d, 0x46, 0x70, 0x41, 0x64, 0x31, 0xee, 0xed, 0xb4, 0x2b, 0xdb, + 0x55, 0xfc, 0x75, 0x13, 0x7d, 0xe4, 0xf2, 0x71, 0x9c, 0x12, 0x89, 0x4f, 0x76, 0x8f, 0x85, 0xcf, + 0x55, 0xc9, 0x49, 0x35, 0x4f, 0xc1, 0x3e, 0x6f, 0xdd, 0xb4, 0xdf, 0xee, 0xd3, 0xcb, 0xf1, 0x35, + 0xef, 0x82, 0x8a, 0xda, 0x6a, 0xd3, 0xd8, 0xfa, 0xbf, 0xd6, 0x2f, 0x84, 0xca, 0x5c, 0xfb, 0xb7, + 0xe0, 0x8a, 0x91, 0x75, 0xaa, 0x9f, 0xe6, 0xbd, 0xeb, 0x9b, 0x79, 0xba, 0xe4, 0xee, 0xe2, 0xf9, + 0x06, 0x5d, 0xe7, 0xe0, 0xb4, 0xfa, 0x69, 0xd5, 0xfd, 0x5d, 0x5c, 0x2e, 0xcc, 0xe8, 0xa5, 0x61, + 0x44, 0x78, 0x88, 0x2c, 0xd5, 0x9a, 0x56, 0x9a, 0x6c, 0x42, 0xc0, 0xbb, 0xcb, 0x7f, 0x7c, 0xb4, + 0xec, 0xb7, 0xc6, 0xf0, 0x5a, 0x26, 0xdd, 0xa7, 0x7a, 0x72, 0xfa, 0xf7, 0xd5, 0x9f, 0x37, 0x97, + 0x17, 0x08, 0xf4, 0xdd, 0x36, 0xda, 0xa7, 0xbf, 0x82, 0x29, 0x3d, 0xa7, 0x8b, 0xe0, 0x93, 0xbb, + 0xbd, 0x70, 0x9d, 0x37, 0xbe, 0xd3, 0x43, 0xb8, 0xf2, 0x5a, 0xa7, 0xba, 0xf2, 0xf5, 0xd9, 0x37, + 0x73, 0xf3, 0x1e, 0xed, 0x26, 0xb9, 0x2b, 0xbf, 0xb3, 0xed, 0xab, 0xe5, 0x19, 0x5a, 0x2f, 0x0b, + 0x9f, 0x97, 0x2e, 0xd3, 0x5d, 0x16, 0xd3, 0xff, 0xc3, 0xb9, 0x31, 0xf8, 0x96, 0x0a, 0xe4, 0xa2, + 0xbb, 0x59, 0x45, 0xb4, 0xff, 0xf0, 0xa4, 0xb8, 0x5c, 0xf5, 0x77, 0x33, 0x30, 0xfb, 0x92, 0x93, + 0xcd, 0x8d, 0x69, 0xc1, 0x75, 0x7b, 0xee, 0xda, 0x77, 0x27, 0x58, 0xbe, 0x4d, 0xda, 0x75, 0xc9, + 0xcf, 0x19, 0x7b, 0xb6, 0x96, 0x14, 0xeb, 0xd3, 0x70, 0x49, 0xda, 0x3c, 0x18, 0x78, 0x23, 0xa7, + 0xbb, 0xfd, 0x15, 0x89, 0x79, 0x84, 0x3d, 0xeb, 0xd7, 0x06, 0x1c, 0x67, 0x3b, 0x7b, 0xa2, 0xd8, + 0x79, 0x79, 0xa9, 0x62, 0x15, 0xd1, 0xf5, 0xf1, 0xd4, 0x92, 0x48, 0xb8, 0x96, 0x2a, 0x7d, 0xa5, + 0xc2, 0x75, 0xae, 0xf6, 0x89, 0xc2, 0x77, 0x4b, 0xbb, 0xb4, 0x33, 0x94, 0x99, 0xfc, 0x6f, 0x21, + 0x5f, 0x6c, 0x6f, 0x0b, 0x08, 0xa9, 0x52, 0x45, 0x64, 0x6c, 0x6c, 0x97, 0x2f, 0x47, 0xe6, 0xec, + 0x4d, 0x34, 0xe6, 0xe0, 0xba, 0xd6, 0x97, 0x36, 0x3f, 0xcb, 0xb6, 0xb2, 0xf7, 0xba, 0x4d, 0xf8, + 0xee, 0xda, 0x4d, 0x52, 0x4a, 0x93, 0x97, 0xae, 0x23, 0x4a, 0x7d, 0x7e, 0x4f, 0xe6, 0xb6, 0xbf, + 0x89, 0xbb, 0x5d, 0xa4, 0x93, 0xf1, 0x36, 0xe9, 0x5f, 0x7f, 0x5e, 0xbe, 0x0a, 0x6d, 0x24, 0x30, + 0xb9, 0x70, 0xb9, 0xc7, 0x2f, 0xbc, 0x6f, 0x2e, 0x4e, 0x58, 0xe2, 0x7b, 0x11, 0x9f, 0xd7, 0x47, + 0xef, 0xac, 0x55, 0xd9, 0xaa, 0xed, 0x8a, 0xe2, 0x4f, 0x9b, 0x13, 0x27, 0x8f, 0xf3, 0x6e, 0xed, + 0x78, 0xbd, 0x69, 0x2b, 0x7b, 0xee, 0x7f, 0x6b, 0xef, 0xa4, 0x92, 0xe8, 0xb5, 0x7c, 0x55, 0x2b, + 0xdc, 0xfa, 0xd7, 0xe1, 0x0b, 0xe9, 0x35, 0xa4, 0x9b, 0x5f, 0x9a, 0x4f, 0xfd, 0x92, 0x93, 0xfc, + 0x12, 0x76, 0x9f, 0xab, 0x8b, 0x2c, 0xf9, 0x9f, 0x0f, 0x99, 0xbb, 0xae, 0xa5, 0xee, 0xf7, 0xf8, + 0x25, 0xa6, 0xe9, 0xeb, 0x77, 0x8b, 0xec, 0x84, 0xda, 0x5f, 0x75, 0xd8, 0xfc, 0xba, 0x74, 0xcd, + 0xc9, 0xad, 0xd7, 0x27, 0x56, 0x32, 0x71, 0x5a, 0xba, 0x57, 0x2d, 0x35, 0xd7, 0x52, 0x73, 0x72, + 0xf6, 0xc9, 0xc5, 0xea, 0xc8, 0xb1, 0xcf, 0x8a, 0xb8, 0x4f, 0x54, 0xf6, 0x3b, 0xbe, 0x4e, 0xee, + 0xbb, 0xb7, 0x1c, 0xaa, 0xfd, 0x13, 0xa5, 0xeb, 0xdf, 0x30, 0xbd, 0xdc, 0x67, 0x04, 0x42, 0x93, + 0x7e, 0x52, 0x73, 0x55, 0x7f, 0x29, 0xd0, 0xe6, 0xb4, 0xfc, 0xb6, 0x44, 0xd2, 0x6d, 0x65, 0xe6, + 0xdb, 0xb6, 0xb9, 0xa3, 0x95, 0x7b, 0xf8, 0xbb, 0x1d, 0x8d, 0xbb, 0xa7, 0x27, 0x04, 0xe6, 0xb4, + 0xfb, 0xd5, 0xcf, 0x11, 0xf2, 0xd7, 0x57, 0xc4, 0x15, 0xda, 0xda, 0xa7, 0x5c, 0xb2, 0xb3, 0x6e, + 0xb9, 0x2c, 0x64, 0x6d, 0x0f, 0xcd, 0x3f, 0xdb, 0xf0, 0x8d, 0xad, 0xe9, 0x26, 0x5c, 0x4b, 0x1b, + 0x7e, 0xe9, 0xe6, 0x63, 0xcd, 0xb6, 0xee, 0xb8, 0x4f, 0xb6, 0x9b, 0x57, 0xae, 0x09, 0x29, 0x25, + 0xf5, 0x73, 0x68, 0x8b, 0xbb, 0xe8, 0x95, 0xf2, 0xf3, 0xf9, 0xb9, 0x45, 0xe4, 0xf2, 0x70, 0x4d, + 0xb5, 0x6b, 0x93, 0x32, 0x97, 0x8b, 0x23, 0x97, 0x3d, 0xd2, 0xf5, 0x73, 0xe0, 0x9e, 0x5c, 0x49, + 0x24, 0xb2, 0xcd, 0x37, 0x3e, 0x43, 0x2d, 0x6b, 0x94, 0xab, 0x29, 0x96, 0x66, 0xe2, 0xfa, 0x4f, + 0x4a, 0x5c, 0xf7, 0xab, 0xfc, 0xdb, 0x1d, 0xd7, 0x04, 0xe6, 0x9b, 0xea, 0x0b, 0x13, 0xc5, 0x06, + 0xd4, 0x38, 0x9d, 0x1f, 0xe1, 0x4a, 0xa8, 0x80, 0x70, 0x70, 0x97, 0x30, 0x72, 0x3c, 0x06, 0xcf, + 0xc0, 0x87, 0x03, 0xb7, 0x04, 0xe9, 0x95, 0xd4, 0x7b, 0xfd, 0x70, 0x94, 0xd0, 0x9d, 0xbc, 0x47, + 0xef, 0x35, 0x84, 0xab, 0x88, 0x13, 0xa7, 0x77, 0xfa, 0xf5, 0xf8, 0x81, 0x78, 0xba, 0x91, 0x25, + 0x21, 0x89, 0xc3, 0x66, 0x77, 0x2e, 0x20, 0x4d, 0x57, 0xbb, 0x51, 0x5a, 0xe2, 0x44, 0xd6, 0x76, + 0x48, 0xc6, 0xa9, 0xf8, 0x2e, 0xbd, 0xaa, 0x7b, 0xc5, 0xf2, 0x6f, 0x36, 0x78, 0xcb, 0x2b, 0x5e, + 0xdd, 0x5b, 0x6c, 0xb0, 0xb6, 0x9b, 0x8d, 0xd6, 0x35, 0x54, 0xf8, 0x28, 0xc1, 0xb7, 0x7d, 0x10, + 0xf6, 0x22, 0xf9, 0x2d, 0xdf, 0xe2, 0x29, 0x59, 0xfc, 0xdb, 0x2f, 0xdf, 0x21, 0x15, 0x71, 0xbc, + 0x82, 0x5b, 0xb7, 0xf7, 0x5d, 0xc9, 0xc1, 0x09, 0x15, 0xed, 0x31, 0xf0, 0x9e, 0xf7, 0xda, 0x75, + 0xd5, 0xab, 0x90, 0xba, 0x4b, 0xe0, 0xaf, 0xab, 0x49, 0x2f, 0x3e, 0x6e, 0x5f, 0x08, 0x99, 0xde, + 0xef, 0x2e, 0x3d, 0xdd, 0xc9, 0xcc, 0x46, 0xe6, 0x9f, 0xc1, 0x25, 0xbc, 0xac, 0x4a, 0xf9, 0xeb, + 0x8b, 0xc6, 0xf5, 0xfb, 0xe0, 0x86, 0xd4, 0xbb, 0x77, 0xc9, 0x8c, 0x5a, 0x48, 0x59, 0xf0, 0x5d, + 0x67, 0x67, 0xd6, 0xf7, 0xf0, 0x88, 0x9b, 0xa9, 0x33, 0x37, 0xdb, 0xe1, 0x10, 0x45, 0x37, 0xde, + 0xac, 0xf1, 0xbe, 0xff, 0x04, 0xd6, 0x63, 0x19, 0x58, 0x1d, 0x27, 0xb9, 0x5c, 0x49, 0x6a, 0x87, + 0xe5, 0x63, 0xc2, 0x54, 0xde, 0x46, 0x2d, 0xbd, 0x71, 0x7c, 0xad, 0xa1, 0xde, 0xb9, 0xa8, 0x77, + 0xf8, 0x9b, 0x1a, 0x4d, 0x9f, 0x50, 0xe3, 0xb5, 0xee, 0x46, 0x3a, 0xee, 0x95, 0xfe, 0x26, 0xba, + 0x1c, 0x8c, 0x50, 0xfc, 0xbd, 0xa6, 0x97, 0x57, 0x97, 0xb9, 0x32, 0xe9, 0x1b, 0x98, 0xb4, 0xe9, + 0xf9, 0x2d, 0x6d, 0x7b, 0xed, 0x34, 0xb8, 0x24, 0xde, 0xd7, 0x7c, 0xdd, 0x54, 0xdc, 0x4d, 0xa6, + 0xb9, 0x32, 0xfe, 0x43, 0x3d, 0xef, 0x82, 0x5b, 0xcf, 0x99, 0x71, 0xea, 0xef, 0x94, 0xad, 0x6f, + 0xe3, 0xef, 0x4b, 0x56, 0xa9, 0x69, 0x2e, 0x4a, 0x19, 0x3f, 0xe1, 0x4f, 0x37, 0xa4, 0x9b, 0xd2, + 0x44, 0x5e, 0x89, 0x3a, 0xb9, 0x57, 0x66, 0x5d, 0xc9, 0x88, 0x05, 0x76, 0x65, 0x9f, 0x08, 0x94, + 0xd5, 0x01, 0x69, 0xaa, 0x72, 0x72, 0xca, 0x9d, 0xcd, 0x10, 0xae, 0xa0, 0xe9, 0x67, 0x7c, 0x25, + 0x2e, 0x1c, 0xc4, 0xc6, 0x2c, 0x85, 0x42, 0x35, 0x63, 0xa7, 0x89, 0xbe, 0x3c, 0xe9, 0xd2, 0x4a, + 0x95, 0xe9, 0xb6, 0x9f, 0x8a, 0xa2, 0x4a, 0xca, 0xa7, 0x62, 0xfc, 0x15, 0x58, 0x86, 0xef, 0x52, + 0x30, 0x4f, 0x24, 0xc9, 0x74, 0xaa, 0xb9, 0x89, 0xcb, 0x01, 0x1c, 0x82, 0x6b, 0x72, 0xf4, 0x29, + 0xe4, 0xe4, 0x13, 0x57, 0x49, 0x73, 0x13, 0x6d, 0x5f, 0x45, 0x6f, 0x97, 0x57, 0xf9, 0x75, 0x4e, + 0x7e, 0x4e, 0x7d, 0x97, 0x82, 0x42, 0x55, 0xaf, 0x7d, 0xdd, 0x27, 0xf8, 0xf2, 0x37, 0xae, 0x4d, + 0xab, 0x5f, 0x82, 0xc2, 0xad, 0x2d, 0xda, 0x77, 0xa7, 0xe9, 0x79, 0x0d, 0x05, 0x94, 0x99, 0x34, + 0x63, 0x9c, 0x42, 0xb9, 0xe2, 0x01, 0x26, 0xef, 0x79, 0x38, 0x4c, 0x4a, 0x69, 0x3a, 0x4a, 0x9e, + 0x4e, 0x6d, 0x0e, 0xeb, 0x8e, 0xc9, 0x2d, 0x52, 0xdb, 0xb7, 0xf2, 0x51, 0x21, 0xb6, 0x56, 0x17, + 0x64, 0xe4, 0xfe, 0xbd, 0xf1, 0x35, 0xbd, 0x3d, 0xfd, 0x96, 0xdd, 0xb5, 0xc1, 0x56, 0x86, 0xfd, + 0x53, 0x6e, 0xf2, 0x5f, 0x04, 0x9d, 0x55, 0xdf, 0x09, 0xe7, 0xf6, 0xde, 0xa9, 0xbe, 0x23, 0xb4, + 0xd1, 0xf5, 0xad, 0x49, 0xc9, 0x48, 0xde, 0x97, 0x98, 0x45, 0x56, 0x7e, 0x51, 0x35, 0x7a, 0xe1, + 0x32, 0xbb, 0xe7, 0xce, 0xba, 0xf5, 0x72, 0x6e, 0xbf, 0x09, 0x13, 0x76, 0xeb, 0x55, 0xc1, 0x6f, + 0x49, 0xb7, 0xdf, 0x2f, 0x88, 0x23, 0x4d, 0x36, 0xcc, 0xf9, 0x8e, 0x4e, 0x4b, 0x56, 0xab, 0x94, + 0x8f, 0x7a, 0xff, 0x11, 0xcb, 0x8e, 0xe2, 0xbc, 0x47, 0x62, 0x67, 0xdc, 0xfc, 0xa4, 0x23, 0xf5, + 0x11, 0xc1, 0x10, 0x9b, 0xaf, 0x10, 0x5c, 0x18, 0x6e, 0x5c, 0xd4, 0x99, 0x99, 0x22, 0x5d, 0x15, + 0x7f, 0xa8, 0x9c, 0x9c, 0x97, 0x7d, 0x72, 0x0c, 0xd5, 0x7c, 0xb5, 0x5a, 0xfb, 0x3a, 0x6d, 0xb5, + 0xf2, 0x5e, 0x7c, 0x6b, 0xd1, 0xda, 0xfa, 0xb5, 0x72, 0xda, 0x69, 0xa6, 0xbd, 0xf9, 0x7f, 0x93, + 0x5a, 0x4b, 0x8b, 0x22, 0xdb, 0xdd, 0xaf, 0x8c, 0x93, 0xb4, 0x9d, 0xdd, 0xa7, 0x55, 0xd5, 0x6d, + 0xf9, 0x49, 0xaa, 0x84, 0xf8, 0xed, 0xa5, 0xa6, 0xd6, 0x96, 0x92, 0xe3, 0x0a, 0xd2, 0x4e, 0xd2, + 0x49, 0x6a, 0x87, 0xa4, 0x97, 0xc4, 0x57, 0x2d, 0xdb, 0xd7, 0x35, 0x32, 0xff, 0xd5, 0x8f, 0x84, + 0xb3, 0xe5, 0xa4, 0xb7, 0xf2, 0xef, 0x71, 0x5c, 0xbb, 0xd5, 0xf4, 0x7e, 0x97, 0x94, 0x8e, 0xfb, + 0xe6, 0xd2, 0xba, 0xe1, 0x3c, 0xba, 0xbd, 0x4b, 0x91, 0x78, 0xad, 0xbb, 0xa6, 0xff, 0xb1, 0x0b, + 0x6d, 0x2e, 0x20, 0xc2, 0x72, 0xed, 0x74, 0x23, 0x2b, 0xeb, 0xd2, 0xf4, 0x79, 0x7c, 0x29, 0x23, + 0x3a, 0xae, 0x87, 0x61, 0xa6, 0xf4, 0xca, 0xc5, 0x7a, 0xf8, 0x42, 0xdd, 0xbe, 0x46, 0xa6, 0x92, + 0x2a, 0xf8, 0x24, 0xbe, 0xdc, 0x5f, 0x1f, 0x63, 0x3c, 0xb6, 0x9a, 0x43, 0x43, 0xcf, 0xc9, 0xa4, + 0xe2, 0xcc, 0xe8, 0xb6, 0xa8, 0x6e, 0xb9, 0x0b, 0xb4, 0xd7, 0x90, 0xb6, 0xed, 0xae, 0x2b, 0x4e, + 0x9e, 0xd3, 0x6b, 0x8a, 0x97, 0xfd, 0x22, 0x6b, 0xc4, 0x93, 0xbb, 0xae, 0x62, 0x37, 0xb7, 0xe1, + 0x2c, 0xf8, 0xde, 0x7f, 0xe6, 0xe5, 0x17, 0x75, 0xf8, 0x6c, 0x73, 0xe6, 0xea, 0xb5, 0x77, 0xba, + 0x93, 0xa1, 0xed, 0x5d, 0x91, 0xeb, 0x7c, 0x27, 0x7b, 0xbc, 0xdf, 0xf2, 0xd2, 0x57, 0xf8, 0x22, + 0xed, 0x34, 0xff, 0x08, 0xdd, 0x5a, 0xaa, 0xad, 0x5f, 0xf0, 0x4f, 0x48, 0xba, 0xf5, 0xf3, 0x76, + 0xbe, 0x3e, 0xad, 0x6f, 0xca, 0xde, 0xff, 0x09, 0x9a, 0x9c, 0x9a, 0xf7, 0xf9, 0x09, 0x6a, 0xfe, + 0x34, 0xb1, 0xeb, 0x8f, 0xd4, 0xec, 0x7c, 0xac, 0x55, 0x0e, 0x86, 0xa2, 0xe9, 0xaf, 0xfc, 0xbc, + 0x8c, 0x57, 0x76, 0xab, 0xf2, 0x52, 0xbb, 0xf8, 0x2d, 0xa9, 0x19, 0x4a, 0xe7, 0x7d, 0x29, 0x7c, + 0x25, 0x6f, 0x6e, 0x9d, 0x3f, 0x09, 0x50, 0xf5, 0x74, 0x3d, 0xf3, 0x4f, 0xff, 0x97, 0x49, 0x3f, + 0x88, 0x99, 0xba, 0xa4, 0xdf, 0xe1, 0x1b, 0x4c, 0x88, 0xc6, 0xde, 0xe8, 0x64, 0xff, 0x92, 0xa9, + 0x7e, 0x0a, 0x67, 0x61, 0x8c, 0x8f, 0xe3, 0x86, 0xdf, 0x43, 0xbc, 0x7f, 0x84, 0xf7, 0x76, 0x19, + 0xe5, 0xfc, 0xbc, 0x8c, 0x40, 0xa7, 0xcb, 0xdd, 0xc2, 0x9d, 0x1b, 0xa0, 0x37, 0xa0, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x9a, 0x2d, 0x16, 0xb1, 0xaf, 0x10, 0x63, 0x31, 0xfd, 0x34, 0xfc, 0x15, 0x15, + 0xed, 0xc6, 0x33, 0x7a, 0xda, 0x52, 0xb1, 0xa7, 0x15, 0xc4, 0x94, 0xdd, 0xdd, 0xba, 0xc6, 0xf1, + 0xd7, 0xf0, 0x44, 0x69, 0xbb, 0x78, 0xad, 0x63, 0xc8, 0x45, 0xa5, 0xf0, 0x5c, 0x36, 0x7e, 0xf3, + 0x93, 0xa7, 0xf3, 0xe1, 0x4b, 0x76, 0xf9, 0x3d, 0xbb, 0x6e, 0x9d, 0x3b, 0x9f, 0x42, 0xa2, 0xf8, + 0xa9, 0x21, 0x0a, 0xc7, 0x37, 0x4b, 0xf7, 0x54, 0xd5, 0x7c, 0x71, 0xf4, 0xdb, 0x99, 0x84, 0xb6, + 0xdb, 0x7f, 0x82, 0xbb, 0x69, 0x11, 0xab, 0xa7, 0x4a, 0xb4, 0x4d, 0x1c, 0x1f, 0x04, 0xe5, 0x4d, + 0x52, 0x7a, 0xb4, 0xd4, 0xbe, 0x14, 0x11, 0x69, 0xbe, 0x35, 0x94, 0xa7, 0x4f, 0xab, 0x74, 0xaf, + 0xc1, 0x5c, 0xad, 0xf6, 0xf2, 0x36, 0xc7, 0x4d, 0x79, 0x17, 0x82, 0x5d, 0x8d, 0xf3, 0x28, 0x9d, + 0x4b, 0x1f, 0x04, 0x21, 0x79, 0x59, 0x53, 0x22, 0xaf, 0x04, 0x97, 0x77, 0x73, 0x22, 0xaf, 0x57, + 0xae, 0xcc, 0x2f, 0xfc, 0x16, 0x1e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe6, 0x4a, 0xe0, 0x86, 0xaa, + 0xaa, 0x65, 0x1f, 0x44, 0x3a, 0x5e, 0x11, 0x5c, 0x91, 0x71, 0x0c, 0xd3, 0x7f, 0x88, 0x29, 0x1f, + 0x5f, 0x08, 0x8a, 0x4d, 0x95, 0xd5, 0x3a, 0x6e, 0xe6, 0xdf, 0xc6, 0x15, 0x22, 0x6d, 0x0f, 0xcf, + 0x2b, 0x6c, 0x69, 0xad, 0xfe, 0x24, 0x8f, 0xcd, 0xd3, 0xed, 0x79, 0x74, 0xe9, 0x78, 0xe3, 0x9e, + 0x31, 0xf9, 0xef, 0x4c, 0xb9, 0xf8, 0x2b, 0xb2, 0x2c, 0x73, 0x75, 0x4f, 0x4e, 0xd9, 0x6a, 0xe0, + 0xb0, 0x86, 0xf1, 0x33, 0xba, 0xf5, 0x97, 0x3b, 0xef, 0x6e, 0xfe, 0x14, 0x39, 0xf6, 0x36, 0xd3, + 0x6d, 0xba, 0x5b, 0x9f, 0x49, 0xbe, 0x7c, 0x73, 0xe1, 0x13, 0x32, 0x44, 0x97, 0x37, 0x4d, 0x69, + 0x7c, 0x28, 0x5e, 0x37, 0x9e, 0xec, 0xdd, 0xed, 0xea, 0x8a, 0xff, 0x17, 0x49, 0x2e, 0x9b, 0xfc, + 0x10, 0x6e, 0xcd, 0x9b, 0x69, 0x5a, 0xcd, 0xd7, 0xc5, 0x9e, 0x39, 0xdf, 0xe3, 0x7a, 0xb9, 0xf3, + 0xb4, 0xcb, 0x56, 0xc9, 0xd6, 0xb3, 0xcb, 0xb3, 0xae, 0x24, 0x94, 0xbf, 0xc7, 0xb3, 0xff, 0x0e, + 0x9c, 0xff, 0x76, 0xd2, 0x4d, 0xf2, 0xd6, 0x53, 0x1f, 0x97, 0xcf, 0xe2, 0x86, 0x35, 0x4f, 0xc9, + 0x0f, 0x1d, 0x2e, 0x67, 0xa5, 0x57, 0x8d, 0xf8, 0xf4, 0xfc, 0x11, 0x05, 0x75, 0x5c, 0xd8, 0xc5, + 0x1e, 0x64, 0xd3, 0x72, 0x86, 0x15, 0x5e, 0x6e, 0xac, 0xfb, 0xea, 0xab, 0xb1, 0x36, 0xee, 0xf9, + 0x67, 0xdf, 0xe2, 0xab, 0x6e, 0x48, 0x68, 0x80, 0xd5, 0xcd, 0xcd, 0x8d, 0x02, 0x0e, 0x2f, 0x34, + 0x52, 0xea, 0xf1, 0x9c, 0x5e, 0x9a, 0xa9, 0xf3, 0xfc, 0x49, 0x75, 0x4d, 0xb4, 0xdb, 0x4f, 0xca, + 0x49, 0x7f, 0xe0, 0x9c, 0xfb, 0xac, 0xdf, 0xf7, 0xc1, 0x35, 0xde, 0x9a, 0xef, 0xdf, 0x04, 0xfa, + 0x74, 0xd2, 0xbd, 0xbe, 0x52, 0x3e, 0xd3, 0xe6, 0x22, 0x74, 0x46, 0x51, 0xe6, 0xb5, 0x6d, 0xbf, + 0x25, 0x64, 0xbf, 0x82, 0x3b, 0x7a, 0xa5, 0x5e, 0x09, 0x04, 0xab, 0x5f, 0x7c, 0xc4, 0x5c, 0xdb, + 0xe4, 0x11, 0x5a, 0x9b, 0x88, 0x08, 0xbb, 0xee, 0xfa, 0xe8, 0x4a, 0x65, 0xe8, 0x2d, 0xd7, 0xc3, + 0xd5, 0x5d, 0x34, 0xdd, 0x13, 0xb2, 0x63, 0x7e, 0xd6, 0x4c, 0xff, 0x1f, 0x69, 0x36, 0x59, 0x7f, + 0x87, 0xeb, 0x70, 0x7e, 0xad, 0xf2, 0x6e, 0x9d, 0x77, 0x66, 0xce, 0xeb, 0xba, 0x29, 0x6a, 0x97, + 0xb2, 0xe9, 0xbf, 0x82, 0xba, 0xb7, 0xe5, 0x8a, 0xdb, 0xb5, 0x07, 0xc2, 0x1b, 0x52, 0xcb, 0x8e, + 0xe6, 0xb8, 0x5f, 0x16, 0x4b, 0x32, 0xc7, 0x6b, 0x49, 0x70, 0x54, 0x7a, 0x56, 0xb3, 0xfd, 0x39, + 0x71, 0xbe, 0x08, 0xf7, 0xb5, 0x07, 0xc1, 0x29, 0x53, 0xa7, 0x7d, 0xa4, 0x59, 0xf0, 0x89, 0xad, + 0xbc, 0xf9, 0xa6, 0xd4, 0xd9, 0xf0, 0x46, 0x44, 0x9b, 0xdd, 0xf1, 0x74, 0xaf, 0xbd, 0x93, 0xe8, + 0x26, 0xd0, 0x22, 0xf3, 0x05, 0xa6, 0xf4, 0x9f, 0x05, 0x96, 0xd9, 0x2f, 0x56, 0x79, 0x23, 0xf0, + 0x2f, 0x04, 0x59, 0x88, 0x2c, 0xfe, 0xae, 0x8a, 0xde, 0x27, 0x88, 0xf0, 0x51, 0x8f, 0xe0, 0x8a, + 0xe9, 0xd3, 0x62, 0x16, 0xe5, 0x22, 0x57, 0x97, 0x9b, 0x1a, 0xc3, 0xd6, 0xbb, 0xad, 0xd2, 0x7c, + 0xc3, 0xf7, 0x75, 0xc1, 0x21, 0x24, 0xef, 0xf9, 0x5c, 0x49, 0xad, 0x57, 0x2e, 0xae, 0x20, 0x4f, + 0xca, 0x65, 0x5a, 0xf8, 0x9b, 0xde, 0xf7, 0x89, 0xe8, 0xaf, 0x27, 0x45, 0x73, 0xea, 0xc7, 0xc1, + 0x0d, 0x6d, 0xd2, 0xfc, 0x4f, 0x56, 0xb5, 0x4d, 0x70, 0x46, 0x25, 0xad, 0xa2, 0x02, 0xf8, 0xb2, + 0x4d, 0x8d, 0xb3, 0x53, 0xea, 0xba, 0x28, 0xa7, 0x7d, 0x6f, 0xf1, 0x5a, 0x4b, 0xe5, 0xd1, 0x1d, + 0x0e, 0x7a, 0xec, 0xe9, 0x25, 0xf8, 0xab, 0xb7, 0x49, 0xdf, 0x5c, 0xd4, 0xee, 0xfe, 0x53, 0x36, + 0xad, 0xfc, 0xd4, 0xd3, 0xd7, 0x04, 0xe7, 0x72, 0x25, 0x6b, 0xdd, 0xb7, 0xf8, 0xc1, 0x0d, 0xab, + 0x97, 0x71, 0x18, 0x27, 0x3c, 0x2f, 0x91, 0x87, 0xfc, 0x24, 0x59, 0x76, 0xe3, 0x55, 0xf0, 0xd7, + 0xcb, 0x7b, 0xd7, 0x17, 0x43, 0xbf, 0x9a, 0xd7, 0x37, 0x6d, 0xd4, 0x40, 0x91, 0xc4, 0x7b, 0xe7, + 0xc5, 0x9d, 0x5a, 0xc4, 0x88, 0xf8, 0xe2, 0x8b, 0xaf, 0xc5, 0xf7, 0x7f, 0x64, 0x4c, 0x4b, 0xd3, + 0x7f, 0x13, 0xc8, 0x77, 0x6d, 0xdb, 0x5c, 0x55, 0xdb, 0xd6, 0x97, 0xd1, 0x70, 0xf9, 0x88, 0xdd, + 0x7e, 0x8a, 0xe7, 0xc9, 0xe6, 0x92, 0xe4, 0xb4, 0xd2, 0x4b, 0xeb, 0x38, 0xf2, 0x5e, 0x7d, 0xf8, + 0x2e, 0xa4, 0x96, 0x9c, 0x91, 0xc1, 0x5d, 0x17, 0xc5, 0x77, 0xb5, 0x4b, 0xd7, 0x60, 0x27, 0xa1, + 0x8f, 0x5c, 0xa5, 0x3e, 0xf2, 0x73, 0x11, 0xdd, 0xeb, 0x94, 0xae, 0xd5, 0x7c, 0xa4, 0x6d, 0x36, + 0xfe, 0x26, 0xb5, 0x5d, 0x26, 0xfc, 0x87, 0x4d, 0x3b, 0x5e, 0xf6, 0x9a, 0x69, 0x72, 0x92, 0xef, + 0xf1, 0x24, 0xdd, 0xef, 0x75, 0x11, 0xe2, 0x44, 0xf1, 0x31, 0x3d, 0x21, 0xdf, 0x03, 0x89, 0xe3, + 0xf3, 0x2f, 0x04, 0x25, 0xb3, 0xab, 0x93, 0x72, 0xcb, 0x0e, 0x4e, 0x10, 0x12, 0x2f, 0xda, 0xdf, + 0x69, 0xaf, 0x56, 0x0f, 0x85, 0xfa, 0x6d, 0x25, 0x6a, 0xe1, 0x9c, 0x9c, 0xdb, 0xfe, 0xae, 0x7c, + 0x17, 0x77, 0x37, 0xab, 0x79, 0x4d, 0xd8, 0x8d, 0x19, 0x28, 0x5e, 0x09, 0x0b, 0x26, 0xf0, 0xc2, + 0xe5, 0x33, 0xdf, 0xe0, 0x94, 0xf9, 0x32, 0xb9, 0x71, 0x28, 0x78, 0x2b, 0xdc, 0x99, 0xea, 0xf7, + 0x79, 0x87, 0x57, 0x14, 0x4e, 0x58, 0xbd, 0xdf, 0xdf, 0x55, 0xf3, 0x77, 0x7f, 0x74, 0x9f, 0xf5, + 0x7a, 0xee, 0xeb, 0x49, 0x70, 0x81, 0xd2, 0xb9, 0xfd, 0xd6, 0xd2, 0xfe, 0xf7, 0x7f, 0x82, 0x33, + 0x9e, 0x34, 0xe9, 0x52, 0xc4, 0x18, 0x75, 0x6f, 0xe2, 0x77, 0x5a, 0xeb, 0xe1, 0x31, 0x3c, 0xb8, + 0xd1, 0x99, 0xf1, 0x10, 0x4e, 0x49, 0x4c, 0x62, 0xb9, 0xf3, 0x7e, 0x22, 0x08, 0xe7, 0xed, 0x3e, + 0x2f, 0x88, 0xa2, 0xb9, 0x64, 0x5d, 0x26, 0x52, 0xfc, 0x10, 0x9e, 0xb4, 0x99, 0x7c, 0x16, 0x5b, + 0xbd, 0xa6, 0xaa, 0xfb, 0xc5, 0x27, 0x04, 0x64, 0x6b, 0x5c, 0x2b, 0x82, 0x4e, 0xd3, 0x4f, 0xf0, + 0x4b, 0x4d, 0xf2, 0xc7, 0xb0, 0xf1, 0x35, 0x19, 0xed, 0x34, 0x9e, 0xeb, 0xbd, 0xa4, 0xfe, 0x5d, + 0xa4, 0xab, 0x84, 0xb4, 0xa6, 0xd3, 0x67, 0xf5, 0xca, 0xfa, 0xb1, 0xf0, 0x45, 0xe6, 0xec, 0x7d, + 0x58, 0xfb, 0xb4, 0xd6, 0xba, 0xc5, 0xf5, 0x8a, 0x6e, 0x3e, 0xd5, 0xea, 0x99, 0x98, 0x67, 0x4b, + 0x2b, 0x4c, 0xc3, 0xe1, 0x0a, 0x6d, 0x35, 0x4e, 0x9e, 0x9d, 0x3f, 0x15, 0x7d, 0xdc, 0xce, 0xdf, + 0x05, 0x13, 0xf8, 0xae, 0xda, 0x54, 0x8a, 0xdf, 0x08, 0x91, 0xe7, 0xda, 0xa2, 0x4a, 0xe8, 0x49, + 0xfe, 0x38, 0xa4, 0xc9, 0x36, 0xed, 0xf4, 0xaf, 0xe5, 0xf3, 0xd3, 0xc4, 0x1f, 0x36, 0xcd, 0xd7, + 0xf0, 0x44, 0x4c, 0xad, 0xb1, 0xf0, 0x59, 0x4d, 0xd3, 0xe9, 0x24, 0x9e, 0xaf, 0xf0, 0x95, 0xc4, + 0xbe, 0xda, 0x6d, 0x13, 0xd7, 0x89, 0x84, 0x6d, 0x2f, 0xa9, 0x71, 0x24, 0xbf, 0x94, 0x89, 0xa7, + 0x7f, 0x1e, 0x4d, 0x37, 0x34, 0x2c, 0xf3, 0x31, 0x4f, 0xe3, 0x4f, 0x6a, 0xd1, 0xf1, 0xbe, 0x4d, + 0x94, 0x92, 0xd2, 0x57, 0xa6, 0x9b, 0x6d, 0xfe, 0x11, 0x82, 0x7e, 0xd3, 0x4b, 0x49, 0x27, 0xe2, + 0x23, 0x32, 0x1d, 0x99, 0x83, 0x47, 0x5d, 0xf5, 0xde, 0x3a, 0xb8, 0x89, 0x30, 0xcd, 0x4e, 0xf8, + 0xab, 0x0e, 0x92, 0x53, 0xc4, 0xdb, 0xae, 0x62, 0x35, 0x24, 0x2b, 0x82, 0xa2, 0xa5, 0x19, 0x5d, + 0x24, 0x92, 0x49, 0x3b, 0x5d, 0x7c, 0x25, 0x75, 0xe9, 0x5f, 0xc6, 0x15, 0x24, 0x92, 0xa5, 0x19, + 0x5a, 0xf4, 0x92, 0x8c, 0xfa, 0x97, 0xe2, 0x34, 0xd7, 0x4a, 0x92, 0xe2, 0x29, 0x26, 0x95, 0x24, + 0xbf, 0x42, 0x22, 0xae, 0x6e, 0xe6, 0x87, 0x8a, 0x3b, 0xde, 0x9d, 0x34, 0x4b, 0x84, 0xed, 0xda, + 0x69, 0xeb, 0x27, 0x05, 0x5d, 0xa4, 0xf6, 0xdb, 0x65, 0x24, 0x38, 0x7c, 0x4d, 0xb2, 0xfd, 0x29, + 0x7c, 0x9c, 0x16, 0xed, 0x97, 0xe9, 0x4f, 0x2d, 0x7c, 0x45, 0x3d, 0x2c, 0xb8, 0x5c, 0x37, 0x42, + 0xba, 0x7e, 0x51, 0x6e, 0x5c, 0x3e, 0xeb, 0x94, 0x42, 0xba, 0x9f, 0xf9, 0xbc, 0x1e, 0xbf, 0x96, + 0xf8, 0x37, 0xf4, 0x2f, 0xb8, 0x98, 0x42, 0xed, 0x6e, 0xa7, 0x67, 0x9f, 0xb1, 0xbf, 0xf8, 0x22, + 0x91, 0x81, 0x7f, 0xbe, 0x61, 0x19, 0x26, 0x35, 0x4f, 0x04, 0x12, 0x33, 0x49, 0xb2, 0x45, 0xdc, + 0x93, 0x6e, 0xd6, 0x5f, 0xc5, 0xe4, 0xe2, 0xb9, 0x20, 0x9a, 0x4c, 0x67, 0xf4, 0x82, 0xbc, 0x49, + 0xf3, 0x6f, 0x9b, 0x3c, 0x45, 0xa6, 0xfa, 0x93, 0xd7, 0x04, 0x52, 0x73, 0x30, 0xd3, 0xb7, 0x0f, + 0x84, 0xe9, 0x6a, 0xbd, 0x6b, 0x82, 0xe2, 0x13, 0x29, 0xf4, 0x92, 0x82, 0xb8, 0xbf, 0x36, 0x2a, + 0x4c, 0xfa, 0xe6, 0x26, 0xaa, 0x4e, 0x4a, 0xd7, 0xe8, 0x5f, 0x7c, 0x11, 0x08, 0x5d, 0x7a, 0xf8, + 0x21, 0x2a, 0x74, 0xef, 0x5c, 0x12, 0x6f, 0x64, 0x99, 0xfb, 0x30, 0xe5, 0xc6, 0xb1, 0xa0, 0xd7, + 0x25, 0xa7, 0x55, 0x51, 0x10, 0x48, 0x52, 0xe9, 0x61, 0xb9, 0xf1, 0x46, 0xe4, 0x82, 0x59, 0xe0, + 0xfe, 0x22, 0x58, 0x11, 0x7d, 0x96, 0xd6, 0x62, 0x7f, 0xcb, 0x3e, 0xff, 0x1c, 0x7c, 0xf8, 0xd3, + 0xbb, 0x7b, 0x69, 0xde, 0x24, 0x84, 0x5b, 0xfd, 0xc7, 0x73, 0x85, 0xcd, 0xd7, 0xab, 0xb9, 0xe6, + 0xc2, 0x26, 0xeb, 0x98, 0xf4, 0x92, 0x9b, 0x97, 0x3f, 0xd7, 0x14, 0x5b, 0xb7, 0x49, 0x3f, 0xc8, + 0x6d, 0x4d, 0xc4, 0xf2, 0x6a, 0xc6, 0x4e, 0xbb, 0x93, 0x6d, 0x49, 0xd5, 0x8f, 0x97, 0x5b, 0xbe, + 0x63, 0xb7, 0x6f, 0xe4, 0xd6, 0x56, 0x4d, 0xcc, 0x21, 0x92, 0xd8, 0xfc, 0x13, 0xde, 0xec, 0x9b, + 0x23, 0x55, 0x8c, 0xb3, 0xe4, 0xae, 0x93, 0xe4, 0x2a, 0xdb, 0x4b, 0xc9, 0xd2, 0x4b, 0xc7, 0xde, + 0x5c, 0x93, 0xfb, 0x77, 0xf1, 0x3a, 0x1c, 0x8c, 0xac, 0x79, 0xb8, 0x43, 0x4e, 0xb6, 0x34, 0x92, + 0x78, 0xaf, 0xe6, 0xd2, 0x6e, 0x4e, 0x08, 0x74, 0xe6, 0x7e, 0x52, 0xf7, 0xb4, 0xb5, 0xc1, 0x0d, + 0x0d, 0x8e, 0xef, 0xf0, 0x53, 0x93, 0x13, 0x8a, 0xa9, 0x5f, 0x43, 0x8f, 0xf5, 0x8a, 0xb8, 0xc9, + 0xb3, 0x4a, 0xed, 0xd3, 0x4b, 0x4b, 0x6b, 0xc9, 0xe6, 0xdf, 0x15, 0x4f, 0x72, 0xff, 0xf2, 0xdb, + 0x65, 0x4b, 0xcd, 0xc9, 0xfe, 0x49, 0xf5, 0x36, 0xbe, 0x4e, 0x92, 0x4f, 0xb2, 0x52, 0xa4, 0x2f, + 0x92, 0x9d, 0x36, 0x9c, 0x4c, 0xb6, 0xa9, 0xb7, 0xe2, 0x2d, 0x5a, 0xb1, 0x8d, 0xab, 0x70, 0x7e, + 0x3b, 0xcc, 0xd3, 0x41, 0x63, 0xe3, 0xb2, 0xb7, 0xe2, 0x1f, 0x84, 0x6b, 0x43, 0xb6, 0xba, 0x54, + 0xab, 0xb8, 0xe7, 0x7f, 0xdf, 0x24, 0x3e, 0x63, 0xe5, 0xc6, 0xfd, 0xdb, 0x4f, 0xf6, 0x43, 0xef, + 0xf0, 0x51, 0xda, 0x4c, 0xac, 0x74, 0xb5, 0xf2, 0x91, 0x3d, 0x3f, 0x56, 0x1e, 0x41, 0x29, 0x5f, + 0xe2, 0x88, 0x5c, 0x7e, 0xd3, 0x6a, 0x6e, 0x32, 0xaf, 0x79, 0x3d, 0x26, 0xab, 0x68, 0xf8, 0xb5, + 0x78, 0x8d, 0x24, 0xa9, 0x5f, 0xe1, 0x19, 0x48, 0x6d, 0xf5, 0x6a, 0x95, 0x7c, 0x25, 0xbd, 0x2b, + 0xb5, 0xf1, 0x34, 0x48, 0xc8, 0x63, 0x93, 0x3a, 0xe1, 0x33, 0xa7, 0x23, 0x39, 0xba, 0x1f, 0xec, + 0x8f, 0x5f, 0x8c, 0xbd, 0x3d, 0x24, 0xe8, 0xad, 0xac, 0x7d, 0x7f, 0x89, 0xa4, 0xf7, 0xea, 0x97, + 0x82, 0x9d, 0x95, 0xdb, 0xbe, 0xf6, 0xdb, 0xe0, 0x9b, 0x9f, 0x69, 0x21, 0xa5, 0x6f, 0x9a, 0x7f, + 0xd7, 0x15, 0xd5, 0x2b, 0x49, 0x7c, 0x9d, 0x24, 0xbc, 0x12, 0xd5, 0x5e, 0x9b, 0xf1, 0x7c, 0x14, + 0xd3, 0xd2, 0xd2, 0x49, 0xd2, 0xf2, 0xae, 0x13, 0xae, 0xa9, 0x25, 0x93, 0x82, 0x5e, 0xdb, 0x67, + 0xc3, 0x6f, 0x8d, 0x5c, 0x85, 0x76, 0xd6, 0x27, 0x88, 0x10, 0x91, 0x20, 0xfd, 0x51, 0x3a, 0xe0, + 0x94, 0x84, 0x20, 0xb3, 0x76, 0x3d, 0xdf, 0xc4, 0xb2, 0x9e, 0x57, 0x25, 0xae, 0x51, 0x2e, 0xba, + 0xe2, 0x44, 0x65, 0xde, 0x7c, 0xae, 0x09, 0xca, 0xed, 0xa7, 0xa7, 0x4e, 0x5f, 0x0e, 0x1a, 0x56, + 0x35, 0xbc, 0x57, 0xeb, 0x8a, 0xed, 0x27, 0x9b, 0xfd, 0x5e, 0xba, 0x3a, 0x55, 0xe2, 0xa5, 0x6d, + 0xad, 0x57, 0xe2, 0x76, 0x93, 0xbb, 0x7b, 0xe2, 0x84, 0x2a, 0xe8, 0xaf, 0x27, 0x04, 0xe2, 0x58, + 0xdd, 0x8d, 0x0f, 0x6c, 0xba, 0xd1, 0x1c, 0x65, 0x2d, 0xba, 0xaf, 0x36, 0x37, 0xa4, 0xdf, 0x82, + 0x3b, 0x53, 0x30, 0x96, 0x5f, 0x2d, 0x2a, 0x5f, 0x13, 0xb7, 0x49, 0x8c, 0x6e, 0x8b, 0xf9, 0x29, + 0x52, 0x7f, 0x08, 0x49, 0x96, 0xed, 0xef, 0x55, 0xd7, 0x09, 0xd5, 0x4b, 0xbd, 0xda, 0xbe, 0x43, + 0x3d, 0xfe, 0x28, 0xe4, 0xcf, 0x75, 0xf8, 0x25, 0xa7, 0xaa, 0x63, 0xaa, 0x5f, 0x1e, 0x20, 0x2b, + 0xb2, 0xbd, 0xdf, 0xc1, 0x14, 0xbb, 0xdd, 0xf7, 0x26, 0x13, 0x7f, 0x7a, 0xbc, 0x9d, 0x91, 0x69, + 0x7c, 0x57, 0x2e, 0x72, 0xe5, 0xf6, 0x44, 0xdb, 0x7a, 0xe3, 0xad, 0x50, 0xda, 0x52, 0xa8, 0x4f, + 0x27, 0xff, 0x35, 0x84, 0x87, 0x5f, 0x27, 0x93, 0xae, 0x5a, 0x1e, 0xfe, 0x2e, 0xd5, 0xfa, 0x6d, + 0x79, 0xaa, 0xad, 0x57, 0x72, 0x7f, 0xe4, 0x8f, 0x0e, 0x8f, 0xb6, 0xf9, 0x0a, 0x76, 0xd8, 0xeb, + 0xbf, 0x36, 0x79, 0xb2, 0x31, 0x43, 0xf5, 0xea, 0xe1, 0x3b, 0x6d, 0xf6, 0xab, 0xe2, 0xb9, 0x3e, + 0xc6, 0x66, 0x35, 0xcb, 0x6a, 0xd7, 0xde, 0x6d, 0xfc, 0x99, 0xf3, 0xf2, 0x9d, 0x3a, 0x50, 0xdf, + 0x12, 0x2b, 0x4d, 0xa2, 0x7d, 0x6f, 0x88, 0x9e, 0x5a, 0x1b, 0x75, 0x52, 0x73, 0x6b, 0x5f, 0x37, + 0x2f, 0xbe, 0x2c, 0x91, 0xac, 0x84, 0xf0, 0x59, 0x2b, 0x95, 0x2a, 0x10, 0xd5, 0x07, 0x4a, 0x9e, + 0x5e, 0x24, 0xd0, 0x98, 0x33, 0x94, 0xfc, 0xac, 0x78, 0x9b, 0xa1, 0xf4, 0x93, 0xf9, 0x7b, 0x4b, + 0xe5, 0xe4, 0xf2, 0xf2, 0x6d, 0xbb, 0x66, 0xe2, 0x6b, 0xa6, 0x92, 0x58, 0xbe, 0x63, 0xea, 0xa5, + 0xec, 0x41, 0x3d, 0x67, 0xe0, 0x88, 0xb2, 0x67, 0x97, 0xc1, 0x17, 0x9b, 0x1e, 0xb8, 0xb1, 0x1a, + 0xad, 0x55, 0x7c, 0x97, 0xd9, 0x6a, 0xfc, 0xb7, 0xbb, 0x82, 0xae, 0xc4, 0xbb, 0x56, 0x82, 0x7d, + 0xde, 0x9c, 0x39, 0xcb, 0x4d, 0xa5, 0x6b, 0xcb, 0x69, 0xac, 0x21, 0xc8, 0x21, 0xdf, 0x7d, 0xdd, + 0xf2, 0xf6, 0x75, 0x4b, 0x3f, 0x15, 0x69, 0xf2, 0x33, 0x4b, 0xe6, 0xe8, 0x8c, 0xa5, 0xf3, 0x15, + 0xe9, 0xa6, 0xfb, 0xd2, 0x4b, 0xe2, 0x7a, 0x49, 0x5b, 0x4d, 0xb1, 0xdc, 0x11, 0x88, 0x5a, 0xaf, + 0x91, 0x5c, 0xa2, 0x77, 0x71, 0xdc, 0xd4, 0x3d, 0xc3, 0xbc, 0x84, 0xad, 0x2f, 0x12, 0x72, 0x7f, + 0xdd, 0xe3, 0x39, 0x84, 0x56, 0xbe, 0x52, 0x2a, 0xe4, 0xe8, 0xf2, 0x84, 0xb9, 0x8a, 0xeb, 0x9b, + 0x82, 0xda, 0x5b, 0x77, 0x79, 0x92, 0xb9, 0x0c, 0xde, 0xab, 0x82, 0x4b, 0xb7, 0x6d, 0xbe, 0x4b, + 0x56, 0xeb, 0x82, 0x33, 0xe6, 0xc7, 0xfd, 0x72, 0x75, 0x57, 0xc5, 0xf7, 0x7d, 0x5c, 0xbc, 0xa4, + 0x6a, 0xb7, 0xc4, 0x1d, 0x57, 0x95, 0x9b, 0x7c, 0x47, 0xc1, 0x26, 0xb2, 0x67, 0x4d, 0xc1, 0x19, + 0x09, 0xfd, 0x7c, 0x4c, 0xbb, 0xdf, 0x7f, 0x04, 0xf7, 0x3f, 0x1d, 0x5a, 0xf7, 0x73, 0xe4, 0x8b, + 0x3e, 0x32, 0x94, 0xac, 0x6e, 0x7e, 0x73, 0xed, 0x3f, 0x5d, 0xbf, 0xc4, 0x92, 0xad, 0xab, 0x78, + 0xaf, 0xc1, 0x19, 0x5d, 0xab, 0x1e, 0x15, 0xc3, 0xe4, 0x6d, 0x3b, 0xca, 0xc7, 0xa9, 0x98, 0x51, + 0x8e, 0xff, 0xbe, 0x5c, 0xcd, 0xcb, 0xc9, 0x6c, 0xec, 0x7e, 0x3e, 0xc7, 0x69, 0x50, 0xd0, 0xe7, + 0xce, 0x31, 0x57, 0x82, 0x52, 0xd0, 0xde, 0x95, 0xfd, 0xf0, 0x95, 0x33, 0x33, 0x33, 0x0f, 0x36, + 0x7c, 0xd3, 0x61, 0xb3, 0xf0, 0x9d, 0xbb, 0x8e, 0x5d, 0xda, 0x55, 0xc1, 0x55, 0x9a, 0x55, 0x47, + 0x9e, 0xb3, 0x63, 0x71, 0x57, 0xc4, 0xdd, 0xe0, 0xfc, 0xbe, 0xf8, 0x23, 0xa9, 0x7d, 0x36, 0x57, + 0x05, 0x5d, 0xa5, 0xb4, 0xfd, 0x56, 0x2f, 0x88, 0xb4, 0xd7, 0x2f, 0xfc, 0x12, 0x6b, 0x78, 0x3e, + 0x0a, 0x48, 0x5e, 0xfd, 0x6d, 0xae, 0x9d, 0x7c, 0x99, 0xf3, 0x5d, 0x1f, 0xab, 0x82, 0x6d, 0xbb, + 0x75, 0xaf, 0x57, 0x52, 0xaf, 0xe0, 0x8e, 0xd5, 0xb6, 0xde, 0xb8, 0x4c, 0x97, 0x6d, 0xe4, 0x65, + 0x0f, 0x5d, 0x62, 0xf8, 0xa9, 0x71, 0x2e, 0xd5, 0x7c, 0x25, 0xd2, 0x49, 0xab, 0x55, 0xc2, 0x27, + 0x76, 0xde, 0xb2, 0xe2, 0x4b, 0xaf, 0x82, 0xca, 0xed, 0xee, 0x92, 0x4f, 0x7e, 0x6a, 0xe0, 0xa7, + 0x5a, 0xae, 0xfb, 0xb6, 0x57, 0x5f, 0x04, 0x84, 0xcc, 0xc6, 0x2f, 0x8a, 0x93, 0x14, 0xfe, 0x4f, + 0xf3, 0xff, 0x85, 0x32, 0x7e, 0x23, 0x98, 0x9f, 0xcf, 0xe7, 0xe9, 0xf3, 0x7d, 0x62, 0xf8, 0x25, + 0xcf, 0x9e, 0xf2, 0x32, 0xcf, 0xae, 0xbe, 0x2e, 0x46, 0x58, 0xc6, 0xb2, 0xd3, 0x96, 0x55, 0xc1, + 0x1e, 0x9a, 0x1a, 0xbf, 0xc9, 0xcc, 0xc7, 0xd1, 0x22, 0xae, 0x20, 0xf7, 0xb7, 0x4d, 0x39, 0x39, + 0x44, 0x53, 0x79, 0x39, 0x4b, 0xbb, 0x84, 0xb8, 0x22, 0xd6, 0xdb, 0xfc, 0xdc, 0xde, 0x27, 0x84, + 0xa5, 0xd9, 0xa4, 0xef, 0xf8, 0xbe, 0xd1, 0x5e, 0xa9, 0xe9, 0x78, 0xea, 0xef, 0x59, 0xbb, 0xcf, + 0xdb, 0xf0, 0x43, 0x15, 0xb7, 0x77, 0x5f, 0x44, 0xde, 0xfa, 0xbc, 0x33, 0xd5, 0xe4, 0xea, 0xf0, + 0x9f, 0x57, 0xfb, 0xee, 0x98, 0xde, 0xf6, 0xd3, 0x89, 0xeb, 0x14, 0x47, 0x35, 0xef, 0x09, 0xf5, + 0xeb, 0xe1, 0x3e, 0x4f, 0x6d, 0xbc, 0x57, 0x57, 0x8e, 0xe4, 0xbb, 0xeb, 0xab, 0xc4, 0xf5, 0x78, + 0x6f, 0x96, 0xf7, 0xae, 0xbd, 0x2f, 0x57, 0xae, 0xb2, 0x88, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, + 0x9a, 0x2e, 0x17, 0x30, 0xeb, 0xc6, 0x1a, 0x33, 0xde, 0x39, 0x58, 0x79, 0x23, 0x45, 0x36, 0x3a, + 0xe1, 0x4d, 0x36, 0xbc, 0xbe, 0x4d, 0x4f, 0x1e, 0xa7, 0x34, 0xbf, 0x04, 0x47, 0x5d, 0x62, 0x77, + 0xe1, 0x13, 0x3d, 0x97, 0x69, 0xdb, 0x4b, 0xf0, 0x53, 0x26, 0x42, 0x9a, 0x09, 0xa7, 0xa6, 0x76, + 0x1c, 0xc3, 0x1b, 0x9f, 0xdf, 0x08, 0x8b, 0x97, 0x7b, 0x6a, 0xa9, 0xa7, 0x7f, 0x1f, 0xee, 0xfc, + 0xbd, 0x6d, 0x2f, 0x82, 0x41, 0x4c, 0x6d, 0x47, 0x99, 0x30, 0xf0, 0xdd, 0xb7, 0x9c, 0x16, 0xe9, + 0xaf, 0xf8, 0x9d, 0x69, 0xd3, 0xaf, 0x82, 0x43, 0xab, 0x77, 0xcf, 0x7c, 0x16, 0x92, 0xdc, 0xb6, + 0x79, 0x23, 0x63, 0x23, 0xb2, 0xf8, 0x4b, 0x2b, 0x11, 0x9a, 0x26, 0x5d, 0x24, 0xe2, 0x27, 0x41, + 0x53, 0x2f, 0xe6, 0x11, 0x7b, 0xf8, 0x2e, 0x2e, 0xae, 0xee, 0xef, 0x62, 0xa1, 0x1a, 0xd2, 0xaf, + 0x45, 0x47, 0x78, 0x62, 0x88, 0xdc, 0x4c, 0x25, 0x55, 0xd6, 0xbe, 0x11, 0x04, 0x45, 0x55, 0x55, + 0x3a, 0x22, 0xff, 0x08, 0x31, 0x12, 0xcb, 0x5c, 0x12, 0x0e, 0xb3, 0x72, 0xbc, 0x83, 0x2b, 0x82, + 0xee, 0x6d, 0x44, 0xdb, 0x23, 0xee, 0xe3, 0xc1, 0x47, 0x34, 0x91, 0x52, 0x9a, 0x2f, 0xf0, 0xc1, + 0x68, 0x99, 0x25, 0xb6, 0xd2, 0xb4, 0x8e, 0x6a, 0x7f, 0x84, 0xe7, 0xff, 0xa2, 0x2e, 0x78, 0x7c, + 0x89, 0x24, 0xd4, 0xf1, 0x4b, 0x48, 0x6b, 0x4e, 0x96, 0x29, 0xab, 0x7f, 0xae, 0x0b, 0x6b, 0xa7, + 0x36, 0xa7, 0xc1, 0xf0, 0xc8, 0x97, 0xcb, 0x8f, 0x9b, 0xaf, 0xfe, 0x30, 0xd5, 0x64, 0xc6, 0xfb, + 0x24, 0xb4, 0xaa, 0x9b, 0xf8, 0x2b, 0x2d, 0xd1, 0x5a, 0xab, 0x22, 0x69, 0x23, 0x16, 0xc7, 0xc1, + 0x35, 0xe8, 0x8b, 0x6f, 0xef, 0xa4, 0x95, 0x73, 0xe0, 0x9f, 0xab, 0x52, 0x7b, 0x3c, 0xbe, 0x09, + 0x77, 0x45, 0xad, 0xa8, 0x2b, 0x84, 0x0d, 0x25, 0x4d, 0x27, 0x5d, 0x8c, 0xf9, 0xa2, 0x3e, 0x7e, + 0xf2, 0xc1, 0x2a, 0x7e, 0xc2, 0xba, 0xaf, 0xab, 0xdf, 0x56, 0x2b, 0x82, 0xd0, 0xb7, 0x1f, 0xbb, + 0x4e, 0x9b, 0xfc, 0x14, 0xf5, 0x4b, 0xa7, 0x4f, 0xe6, 0xfd, 0xf0, 0x47, 0x59, 0xfa, 0xbb, 0xe4, + 0x2d, 0x5b, 0x7f, 0x10, 0x66, 0xe8, 0xea, 0xb5, 0xf8, 0xa3, 0xa7, 0x4e, 0x9b, 0xa6, 0xa4, 0xe0, + 0x8e, 0x9a, 0x6f, 0x4a, 0xfc, 0x9a, 0xd3, 0xf0, 0x4e, 0x4a, 0x26, 0xdd, 0xbb, 0x6d, 0xf7, 0xc1, + 0x1d, 0xe8, 0xbd, 0xf0, 0x99, 0x6d, 0x5a, 0x36, 0x1b, 0xa5, 0xf9, 0x64, 0x7a, 0x26, 0xcc, 0x97, + 0xcc, 0x47, 0x43, 0x6a, 0xf1, 0x11, 0x18, 0x41, 0x0f, 0xaa, 0x88, 0xa2, 0x3b, 0xe8, 0x44, 0xbe, + 0x52, 0x69, 0x3f, 0x84, 0xca, 0x4b, 0x74, 0x56, 0x59, 0xa3, 0xe0, 0xb8, 0x8c, 0x91, 0x36, 0x93, + 0x6b, 0xcb, 0xef, 0x9e, 0x0d, 0xf8, 0x9e, 0x6a, 0xaa, 0x6d, 0xe4, 0xe6, 0x2b, 0xa2, 0x69, 0xb5, + 0xca, 0x54, 0x9e, 0xdf, 0x82, 0xe3, 0x36, 0xd7, 0xba, 0x6f, 0xf0, 0x43, 0x6d, 0xf3, 0x34, 0x3d, + 0xbe, 0x2a, 0x7c, 0x9d, 0xb7, 0x7a, 0xe8, 0xe7, 0x3f, 0xc1, 0x29, 0x97, 0x36, 0x31, 0x93, 0x36, + 0x58, 0x7c, 0xa4, 0x6f, 0x19, 0xbb, 0xc4, 0xd1, 0xd0, 0x64, 0xb2, 0x15, 0x88, 0xf9, 0x83, 0x8f, + 0xb8, 0x33, 0xe4, 0xea, 0xa1, 0x0e, 0x6e, 0xee, 0x05, 0x7e, 0x08, 0xc4, 0x95, 0x9c, 0xfc, 0xf8, + 0x53, 0x74, 0xe9, 0x24, 0x95, 0x3a, 0x79, 0x19, 0x4b, 0x20, 0xbe, 0xe4, 0xff, 0xc5, 0xd0, 0xe5, + 0x6f, 0x53, 0x6f, 0x8a, 0x2d, 0x69, 0x24, 0xd9, 0x72, 0xfc, 0x45, 0xd7, 0x2e, 0x93, 0x52, 0x8b, + 0xc1, 0x31, 0x53, 0x3f, 0xd6, 0xbe, 0xf9, 0x29, 0xe9, 0xf8, 0xca, 0x6e, 0x5e, 0xfd, 0x7d, 0x53, + 0xe5, 0x73, 0x7b, 0xcf, 0xbe, 0x2c, 0x56, 0xd8, 0xbd, 0x4d, 0x85, 0xfe, 0x09, 0xb9, 0xfd, 0xf1, + 0x6f, 0xf7, 0xcb, 0xd4, 0xdb, 0x89, 0x85, 0x0b, 0x2f, 0xa2, 0xb4, 0xa9, 0x35, 0x1d, 0x9a, 0x76, + 0x0a, 0x86, 0x7f, 0x03, 0x81, 0xf7, 0x12, 0x24, 0x10, 0xd3, 0xdf, 0xbe, 0x27, 0x93, 0x39, 0x79, + 0x77, 0xc5, 0x11, 0xa7, 0x45, 0x7c, 0xd0, 0xf2, 0xcd, 0x96, 0x24, 0xf8, 0x25, 0x3a, 0x4d, 0xc9, + 0xb4, 0xd2, 0x49, 0xdf, 0x0a, 0x09, 0x27, 0x3e, 0x4d, 0x4e, 0xdb, 0x4f, 0x9b, 0x1a, 0xb4, 0xd7, + 0x24, 0xf8, 0x2d, 0xa5, 0x73, 0xe3, 0x4d, 0x6e, 0x7c, 0x14, 0x08, 0x7c, 0xd9, 0xc5, 0xdd, 0x2e, + 0x08, 0x2f, 0xa1, 0x0f, 0xf0, 0xd8, 0x93, 0x3e, 0x74, 0x16, 0x7f, 0x1b, 0xd7, 0xf0, 0x4f, 0x24, + 0x43, 0x6a, 0xd6, 0x9a, 0x97, 0xed, 0xf0, 0x54, 0x4e, 0x86, 0x66, 0x17, 0x08, 0xb3, 0x9a, 0x09, + 0x73, 0x8f, 0x0a, 0x69, 0x27, 0x48, 0xb0, 0xb2, 0x84, 0xd1, 0xa3, 0xda, 0x6f, 0x17, 0xc6, 0xe5, + 0x90, 0xce, 0x97, 0x77, 0x35, 0x76, 0x8b, 0x47, 0x3c, 0xd2, 0x64, 0xa8, 0xdc, 0x53, 0x09, 0xfb, + 0x6e, 0xa7, 0xea, 0x6d, 0x67, 0xf0, 0xed, 0xa1, 0xac, 0xe1, 0x52, 0xea, 0xd4, 0x22, 0xf9, 0xa3, + 0x5b, 0x64, 0x94, 0x5f, 0xe1, 0x4a, 0x59, 0x60, 0xd6, 0x3e, 0x91, 0x31, 0x3c, 0xe5, 0xf4, 0x56, + 0x3e, 0x0a, 0xca, 0x9b, 0xda, 0x6e, 0x79, 0x67, 0xf6, 0xf2, 0xf9, 0x8c, 0x89, 0x2a, 0x7e, 0x0a, + 0x25, 0xc7, 0xed, 0xb7, 0x49, 0xfe, 0x12, 0xa4, 0xba, 0x5b, 0xf8, 0x52, 0x68, 0x13, 0xea, 0xda, + 0x4d, 0xba, 0x5d, 0xaa, 0xb9, 0xf1, 0x85, 0xe7, 0xdb, 0xdd, 0xa7, 0xc3, 0x4b, 0x7f, 0x04, 0xb2, + 0xc5, 0xdf, 0x25, 0x0b, 0xdb, 0xb1, 0xf0, 0x47, 0xb9, 0xb3, 0xc3, 0xeb, 0x97, 0xc1, 0x4e, 0x6f, + 0x2e, 0x26, 0x96, 0xe9, 0x69, 0xb9, 0xef, 0x82, 0x5a, 0x6d, 0x73, 0xe6, 0xe3, 0xc1, 0x2c, 0xf0, + 0x49, 0xbb, 0x2a, 0xb6, 0xe1, 0x70, 0xf9, 0xa9, 0x12, 0xaf, 0xe9, 0x45, 0x69, 0x1b, 0x67, 0xb9, + 0xf1, 0xfc, 0x67, 0xda, 0xe8, 0x11, 0x80, 0xd0, 0x1b, 0xe8, 0x21, 0x14, 0xbc, 0xa1, 0xa5, 0x5c, + 0x9c, 0xb7, 0xbf, 0xdd, 0x57, 0x71, 0x16, 0x58, 0x38, 0xca, 0x7e, 0x96, 0x27, 0xf6, 0x4b, 0xdc, + 0x4c, 0x40, 0x93, 0x5a, 0x93, 0x38, 0x81, 0x30, 0x8f, 0x42, 0x73, 0xfd, 0x5e, 0xf9, 0x3b, 0x6b, + 0xe1, 0x2e, 0xdb, 0x76, 0xed, 0xfb, 0x2b, 0xad, 0xfd, 0x70, 0x8e, 0xec, 0x66, 0xaa, 0xf9, 0x2b, + 0xaa, 0xe3, 0xf7, 0x6b, 0x58, 0x8f, 0x7e, 0x7f, 0xe5, 0xea, 0xc8, 0x44, 0x40, 0x9a, 0xe2, 0xb7, + 0xb9, 0xbf, 0xe2, 0x25, 0xa7, 0x4d, 0xb0, 0xf7, 0x04, 0x85, 0x55, 0x5c, 0xab, 0x88, 0xd5, 0xaa, + 0xd3, 0xae, 0x33, 0xaa, 0xa7, 0x4f, 0x5a, 0xac, 0x5e, 0xb8, 0xb1, 0x2f, 0x75, 0xa6, 0xb5, 0xca, + 0x47, 0xbb, 0xfb, 0x23, 0x6b, 0xfb, 0xd2, 0xba, 0xe1, 0x23, 0xdd, 0xfb, 0xb5, 0xe1, 0x31, 0x09, + 0x29, 0xe1, 0xba, 0x2d, 0x76, 0x59, 0x33, 0x5d, 0x7d, 0x5c, 0x14, 0x67, 0xd3, 0xc7, 0x93, 0xa1, + 0xc7, 0x3b, 0xe5, 0xb4, 0xd3, 0xfc, 0x16, 0x90, 0x4e, 0x15, 0x37, 0x59, 0xbb, 0x26, 0x71, 0x22, + 0x07, 0x49, 0x89, 0x33, 0xea, 0xba, 0xa7, 0xe2, 0x60, 0x9c, 0xa1, 0x4a, 0xdb, 0x32, 0x8a, 0xb5, + 0x6f, 0x89, 0x23, 0x62, 0x3c, 0xde, 0x3e, 0xaf, 0xea, 0xdf, 0x11, 0x68, 0xf9, 0x9f, 0x3f, 0x96, + 0x46, 0x4a, 0x20, 0x75, 0xd6, 0x11, 0x7d, 0x1e, 0x5f, 0x7a, 0xb2, 0xf8, 0x4b, 0x4e, 0x9a, 0x3a, + 0xfd, 0x62, 0xf8, 0x25, 0x2b, 0x47, 0xf6, 0xa9, 0xd2, 0xca, 0xb8, 0x2a, 0xbd, 0x72, 0xe6, 0xde, + 0xfa, 0xf8, 0x5a, 0x5c, 0xad, 0xed, 0x66, 0x4f, 0x59, 0xbf, 0xfc, 0xb7, 0xbf, 0xd5, 0xc7, 0x97, + 0x27, 0xfc, 0x10, 0xc9, 0xbb, 0x6c, 0x17, 0x04, 0x25, 0x93, 0x0d, 0xe5, 0xfe, 0x22, 0x9d, 0x2b, + 0xed, 0xf8, 0x22, 0xaa, 0xf5, 0xf0, 0x47, 0xad, 0x4d, 0x5f, 0x09, 0xd5, 0xe9, 0x3b, 0xfe, 0x22, + 0xd3, 0x5b, 0x4d, 0x6b, 0x89, 0x15, 0x41, 0x9e, 0x14, 0x98, 0x8d, 0x03, 0xaf, 0xae, 0x5a, 0x54, + 0x36, 0xbc, 0x16, 0xef, 0x6a, 0xef, 0x38, 0x3e, 0x23, 0xb6, 0xa4, 0xf9, 0x52, 0x71, 0x04, 0x77, + 0xdd, 0xef, 0xe6, 0xbb, 0xeb, 0x97, 0x53, 0xff, 0xc8, 0x7b, 0x77, 0xf1, 0x84, 0xc2, 0xcd, 0xde, + 0x58, 0xdb, 0xad, 0x4a, 0xa2, 0x6a, 0xa4, 0xcf, 0x73, 0x62, 0xcc, 0xbc, 0x29, 0x46, 0x8e, 0x3a, + 0x81, 0xb8, 0xbb, 0x2c, 0xd3, 0x1f, 0xfe, 0xb4, 0xc3, 0xae, 0x0c, 0xed, 0xf4, 0x36, 0xe3, 0x89, + 0x09, 0x8e, 0x95, 0x46, 0xe2, 0xbb, 0xf1, 0x20, 0xa2, 0xfb, 0x81, 0x8d, 0x60, 0xbb, 0xcb, 0x2a, + 0xb8, 0x7f, 0x04, 0xd5, 0x8e, 0x73, 0x70, 0x28, 0xe3, 0xa2, 0x78, 0xee, 0x8f, 0x28, 0xbe, 0x12, + 0x2d, 0x2a, 0x49, 0x6e, 0xf8, 0x6c, 0x95, 0xb6, 0xac, 0xc4, 0x75, 0x7f, 0xf0, 0x4e, 0x5a, 0xd5, + 0x2b, 0xd8, 0x2e, 0xc8, 0xf2, 0xbe, 0xb8, 0x25, 0x3b, 0x46, 0xf6, 0xed, 0x35, 0x99, 0xf0, 0x47, + 0xb9, 0xb7, 0x73, 0xe0, 0x8b, 0xb4, 0xfa, 0xf8, 0x2e, 0xb7, 0xa4, 0xd9, 0x3d, 0xe2, 0x5f, 0x84, + 0x4b, 0x49, 0xbe, 0x7d, 0x69, 0xbb, 0x7f, 0x0a, 0x49, 0xb7, 0x97, 0x52, 0xa7, 0x8e, 0x2e, 0x76, + 0xbf, 0x47, 0x2b, 0x89, 0x32, 0x7c, 0x14, 0x53, 0xa2, 0x37, 0xb4, 0x4e, 0xaf, 0x3d, 0x7c, 0xf2, + 0x14, 0xd4, 0xdf, 0xc9, 0xc5, 0xde, 0xb2, 0x62, 0x5f, 0x94, 0x89, 0x25, 0xfa, 0xfc, 0xf8, 0x24, + 0xbb, 0xee, 0x57, 0x13, 0xcf, 0x0b, 0x36, 0x69, 0x24, 0xb8, 0xbe, 0xeb, 0xaa, 0x88, 0xec, 0x96, + 0x97, 0xe1, 0x0b, 0xee, 0xef, 0xbd, 0xfe, 0x3a, 0xa4, 0xfe, 0xa8, 0x75, 0x7a, 0xe6, 0xea, 0x6c, + 0xf1, 0x3b, 0xbf, 0x3c, 0xbe, 0x5a, 0xaf, 0xe3, 0xae, 0x95, 0x57, 0xaa, 0xd6, 0xf8, 0xb1, 0x34, + 0xeb, 0x74, 0xf8, 0x98, 0x4c, 0xb7, 0x49, 0xad, 0x5b, 0x5c, 0x11, 0x0e, 0x2d, 0xc0, 0xb6, 0xf8, + 0xbd, 0x6c, 0x79, 0x3d, 0x44, 0x48, 0x5b, 0x45, 0x15, 0xe2, 0x21, 0x2c, 0x99, 0x9f, 0xd0, 0x57, + 0xcb, 0xb7, 0x6d, 0xf2, 0x6a, 0x77, 0xfe, 0x23, 0x45, 0x19, 0xa4, 0xb9, 0x40, 0x9a, 0x1c, 0x0c, + 0xf1, 0x35, 0x99, 0x8c, 0x6b, 0x34, 0x5b, 0xe0, 0x8f, 0xaa, 0x4f, 0x5c, 0x34, 0x57, 0xdd, 0xf4, + 0xd4, 0x9f, 0xd7, 0x62, 0x26, 0xf6, 0x2c, 0x4d, 0x5e, 0xb8, 0x8a, 0xa7, 0x4f, 0x2b, 0x0b, 0xe0, + 0xa8, 0xeb, 0xbd, 0xd3, 0xe5, 0x64, 0x9f, 0x1a, 0x78, 0x98, 0x24, 0xaa, 0x5f, 0x7c, 0x51, 0x87, + 0x29, 0xcc, 0xcc, 0x44, 0x7a, 0x7e, 0x8f, 0xd5, 0x11, 0x0e, 0x47, 0x84, 0x2f, 0x4d, 0xdc, 0x79, + 0x66, 0xc3, 0x8c, 0x98, 0xf0, 0x47, 0x5d, 0xd2, 0xb0, 0xc7, 0x13, 0x97, 0x37, 0x4f, 0x5c, 0x93, + 0xfb, 0x77, 0xc2, 0x53, 0x66, 0xf9, 0x98, 0xf9, 0x34, 0xab, 0xe0, 0xaa, 0xdd, 0xbb, 0xba, 0x2d, + 0x6a, 0xff, 0x12, 0x47, 0xde, 0xe9, 0xd7, 0x2c, 0xdf, 0xf8, 0x2b, 0x3c, 0xba, 0x6d, 0xf9, 0xb1, + 0xb5, 0xf0, 0x7c, 0x60, 0x97, 0xa6, 0xd9, 0x3a, 0x71, 0xd3, 0xa7, 0x59, 0xfa, 0xfa, 0x1d, 0xdf, + 0x05, 0x05, 0x54, 0xb9, 0xb7, 0xc2, 0xa2, 0x63, 0x32, 0x66, 0xaa, 0x97, 0x63, 0x7a, 0xd7, 0xc1, + 0x39, 0xed, 0xd2, 0xbb, 0x4f, 0x1f, 0xe3, 0xcc, 0xfb, 0x8a, 0xb2, 0x4a, 0x06, 0xd9, 0xa6, 0xf6, + 0xc6, 0xdf, 0x8c, 0xcb, 0xf7, 0x92, 0x2d, 0x1a, 0x00, 0xf9, 0xee, 0x61, 0x08, 0xa6, 0x68, 0xaf, + 0xe2, 0xc8, 0x88, 0xe6, 0xb4, 0xea, 0x87, 0xe1, 0x42, 0xb7, 0x7e, 0xa7, 0xca, 0x62, 0x68, 0x28, + 0x1b, 0x7b, 0xf3, 0xfc, 0xa2, 0x6a, 0xbf, 0x04, 0xb3, 0x6e, 0xbc, 0xec, 0x27, 0x4b, 0x8a, 0x10, + 0xef, 0x49, 0x65, 0xed, 0xf8, 0x52, 0x7c, 0x1e, 0xe9, 0x59, 0xe2, 0x4a, 0xf7, 0x0c, 0x63, 0xbd, + 0x27, 0xcb, 0x69, 0xaa, 0xa4, 0x5e, 0x2a, 0xf9, 0x3d, 0x35, 0xf8, 0x27, 0xa4, 0xf5, 0xcb, 0xbe, + 0xf8, 0x23, 0xdd, 0x24, 0xfb, 0x88, 0x8d, 0x97, 0x1f, 0x5a, 0xb0, 0xe6, 0x42, 0xc7, 0x6a, 0xdd, + 0x84, 0x2e, 0xcc, 0x1e, 0xf6, 0x14, 0x4c, 0x90, 0x3c, 0x64, 0xd7, 0x75, 0x53, 0xf0, 0x57, 0xcd, + 0xff, 0xa9, 0xa2, 0x33, 0x83, 0xc5, 0xf0, 0x55, 0x7b, 0x1e, 0xc3, 0x2e, 0xf2, 0x99, 0x3e, 0xc3, + 0xb9, 0x7c, 0x16, 0xc6, 0xc7, 0x0f, 0x53, 0x68, 0x50, 0xe2, 0xd6, 0x56, 0xcf, 0x82, 0x73, 0xd2, + 0xa4, 0xad, 0xee, 0x57, 0x16, 0x23, 0x21, 0x24, 0xa8, 0xcb, 0x1f, 0xcd, 0x49, 0x34, 0x7f, 0x04, + 0xa5, 0x7a, 0x7b, 0x72, 0xeb, 0xfc, 0x11, 0x5c, 0xb2, 0xdf, 0xe3, 0xb6, 0xd3, 0xa7, 0x4e, 0x9d, + 0xaf, 0x93, 0x97, 0xd7, 0x73, 0xe3, 0x47, 0xd7, 0xe7, 0x84, 0xf4, 0xda, 0x8e, 0xad, 0xff, 0x1d, + 0x7d, 0xaa, 0xa5, 0x4d, 0x27, 0xfb, 0xa7, 0x7b, 0xe2, 0x8a, 0x92, 0x7b, 0x5a, 0x7e, 0x3e, 0xec, + 0x99, 0xb3, 0x9b, 0x0d, 0x95, 0x53, 0x26, 0xc1, 0xf8, 0x42, 0x59, 0x67, 0xb6, 0x91, 0x63, 0xbf, + 0x84, 0x2e, 0xc9, 0x9d, 0x3d, 0x33, 0xf6, 0x37, 0xff, 0xc1, 0x6f, 0x2b, 0x26, 0x81, 0xfe, 0xba, + 0xf8, 0xe3, 0x26, 0xdf, 0x26, 0xbe, 0xa9, 0xfe, 0x6d, 0xbb, 0x7e, 0x0a, 0xca, 0xef, 0xbb, 0x5b, + 0x4d, 0x6c, 0x4b, 0xc5, 0x08, 0xad, 0x6b, 0x6f, 0xdd, 0x6b, 0xf1, 0xf5, 0xeb, 0x55, 0x5a, 0xa4, + 0xbe, 0x51, 0x78, 0xbf, 0xc2, 0x42, 0x1a, 0x55, 0xe9, 0x25, 0xe0, 0x8f, 0xa6, 0x9b, 0x1f, 0x57, + 0x7c, 0x85, 0xb1, 0x4e, 0xa3, 0xcb, 0xda, 0x27, 0xc4, 0xc9, 0x23, 0x3a, 0xfc, 0x41, 0x8c, 0x91, + 0xfe, 0xd7, 0x15, 0xba, 0xe0, 0xa8, 0x84, 0x82, 0x37, 0x2d, 0x76, 0xa5, 0x2d, 0xd6, 0x31, 0x13, + 0xdf, 0xe2, 0x0b, 0xcf, 0x0a, 0xa7, 0x4f, 0xcc, 0x5e, 0x7f, 0xe5, 0x36, 0xab, 0xe3, 0x23, 0xa3, + 0x41, 0x4d, 0x1e, 0x7d, 0x7a, 0xe6, 0xf8, 0x31, 0xa9, 0x97, 0xc6, 0x34, 0xca, 0x75, 0x74, 0xf0, + 0x4d, 0x85, 0x42, 0x29, 0x9e, 0x7b, 0x93, 0x16, 0xbe, 0x38, 0xe9, 0x25, 0xda, 0xa6, 0x56, 0xff, + 0x08, 0xe4, 0x85, 0x2b, 0x54, 0x9e, 0x9f, 0xc1, 0x25, 0xb6, 0xbe, 0xae, 0xc9, 0xcd, 0x33, 0xf7, + 0x67, 0xaa, 0xe5, 0xad, 0x7e, 0x43, 0x99, 0xb7, 0xf8, 0x9e, 0x9b, 0xa5, 0xb5, 0xe4, 0x8e, 0x65, + 0xe8, 0x9f, 0x15, 0xb6, 0x9b, 0xd3, 0xb5, 0xe1, 0x1b, 0x4d, 0xed, 0x35, 0xad, 0x24, 0xbc, 0x25, + 0xa4, 0x94, 0x99, 0xfe, 0x30, 0xbb, 0xb5, 0x49, 0xa6, 0x93, 0x6f, 0xa5, 0x2c, 0x97, 0x09, 0x11, + 0x34, 0x8f, 0x9b, 0x76, 0xda, 0x27, 0x1f, 0x7d, 0x74, 0xd4, 0x9b, 0x97, 0x3e, 0x09, 0x6d, 0x6a, + 0xda, 0xd2, 0x83, 0xe5, 0xb6, 0x9e, 0xb9, 0x88, 0xdd, 0x8d, 0x7c, 0xdb, 0x74, 0x97, 0x05, 0x34, + 0xd0, 0xe9, 0xb7, 0x79, 0x3e, 0xb7, 0x04, 0xe1, 0x3f, 0x27, 0xa7, 0x5f, 0x36, 0xdb, 0xfc, 0x21, + 0x5d, 0x5b, 0xb9, 0x75, 0x53, 0x9f, 0x98, 0x4d, 0xb9, 0xf5, 0x76, 0x21, 0x28, 0xce, 0xcf, 0xef, + 0x4e, 0xab, 0x84, 0xf7, 0x7d, 0xd7, 0xe2, 0x64, 0x99, 0x6a, 0xcf, 0x26, 0x6b, 0xe0, 0x9e, 0xc9, + 0x26, 0xd9, 0x67, 0xce, 0x1f, 0x1f, 0x4b, 0x4d, 0x3a, 0xcc, 0x83, 0x93, 0xb7, 0xf9, 0xbc, 0x7b, + 0x2f, 0x13, 0x65, 0x66, 0x9b, 0xed, 0x2f, 0x2f, 0x4c, 0xfd, 0x70, 0x81, 0xe6, 0xcd, 0x36, 0xda, + 0x56, 0x9d, 0x2a, 0xe0, 0xaa, 0x4e, 0x5f, 0xb4, 0xa9, 0xa5, 0x9f, 0x7d, 0x5c, 0xa6, 0x36, 0x57, + 0xe0, 0x8c, 0x8e, 0xcb, 0xef, 0x8c, 0x17, 0x6d, 0xd5, 0x24, 0xe8, 0x8f, 0xf9, 0xb0, 0xfb, 0xbd, + 0xab, 0xe3, 0x36, 0xda, 0xe9, 0xa4, 0xe9, 0x37, 0x4d, 0x24, 0xd2, 0xf2, 0x58, 0xcf, 0x94, 0xfc, + 0x65, 0x33, 0x62, 0x7b, 0x54, 0xb4, 0x87, 0x2e, 0x47, 0x33, 0x1b, 0xe0, 0x8c, 0xd5, 0xa2, 0x72, + 0x4e, 0x5d, 0x13, 0xfc, 0x4e, 0x92, 0x6f, 0x3a, 0x8a, 0x0f, 0xc2, 0x27, 0x4d, 0x2d, 0x57, 0xb4, + 0xff, 0x1d, 0x49, 0x2c, 0x9b, 0xf3, 0x63, 0x5a, 0xe2, 0xf6, 0xa4, 0x8b, 0x19, 0xf3, 0xf8, 0x4f, + 0x49, 0xa2, 0xf3, 0xea, 0xd3, 0xf1, 0x96, 0xe7, 0x66, 0x96, 0xdd, 0x74, 0xd7, 0x43, 0x36, 0xf8, + 0x43, 0x59, 0x7a, 0x51, 0xcb, 0x9f, 0xa2, 0x7e, 0xd2, 0x5c, 0x15, 0xdb, 0xcb, 0xa8, 0x7a, 0x37, + 0x4a, 0x46, 0x58, 0xcf, 0x7c, 0x21, 0xa4, 0x94, 0x8f, 0x33, 0x34, 0xba, 0xbf, 0xc7, 0x49, 0x89, + 0x5e, 0xf3, 0xed, 0xa7, 0x4b, 0xc4, 0xf6, 0x9a, 0xd8, 0xd7, 0xc7, 0xe9, 0x52, 0x49, 0x2d, 0xa6, + 0xb1, 0x7c, 0xa2, 0x0d, 0x95, 0x9f, 0x93, 0xcb, 0xd7, 0x09, 0x71, 0xa7, 0xcd, 0x28, 0x27, 0xe6, + 0xbe, 0xeb, 0x11, 0x15, 0xc4, 0x4f, 0x06, 0x7b, 0x96, 0x2b, 0xe2, 0x62, 0x08, 0xf7, 0x45, 0x57, + 0xf9, 0xbc, 0x92, 0x05, 0xbd, 0x8d, 0xa7, 0x51, 0xbc, 0xc6, 0xdd, 0xc2, 0x1c, 0x9d, 0x57, 0xd7, + 0x08, 0x26, 0xea, 0xe5, 0x73, 0x13, 0x55, 0x3f, 0x57, 0x97, 0x84, 0x76, 0x9f, 0x1a, 0xc1, 0xbe, + 0xb1, 0x71, 0xf6, 0x03, 0xaa, 0x9e, 0x12, 0xb2, 0x76, 0x59, 0xb0, 0x2d, 0xf3, 0x38, 0x28, 0x89, + 0xbd, 0x5e, 0xfb, 0xee, 0xe5, 0xe5, 0xd3, 0xa4, 0x4e, 0x4d, 0x0e, 0x68, 0x71, 0x00, 0xa7, 0x5d, + 0xbb, 0x96, 0x9b, 0xdf, 0x17, 0xc7, 0x49, 0xfe, 0x89, 0xb9, 0x6f, 0xbb, 0xbe, 0x14, 0xe5, 0x3d, + 0xbb, 0x63, 0xba, 0xb4, 0x4f, 0x62, 0x1e, 0xf1, 0x3d, 0x95, 0x57, 0xf2, 0x65, 0xcf, 0xc2, 0x73, + 0xe5, 0x49, 0x8f, 0x7f, 0x84, 0xbb, 0x4d, 0xd6, 0xe0, 0x87, 0x82, 0x42, 0x6a, 0xbd, 0x15, 0xcc, + 0x2d, 0xdf, 0x5c, 0x9a, 0x6b, 0x02, 0xff, 0x62, 0xad, 0x3d, 0x76, 0x34, 0x99, 0xc4, 0xf3, 0x76, + 0xd5, 0xf2, 0x08, 0x5a, 0xa9, 0x39, 0x29, 0xdd, 0x30, 0xf7, 0x2d, 0xef, 0x0b, 0x72, 0xf7, 0x70, + 0xb7, 0x26, 0xb4, 0x82, 0xdc, 0xa5, 0x3f, 0xef, 0x9b, 0xa4, 0xa1, 0x4e, 0x13, 0xdd, 0xf4, 0x34, + 0xda, 0x27, 0x7a, 0x55, 0xf7, 0x6e, 0xf1, 0x7c, 0x9b, 0x6e, 0xdf, 0x97, 0x43, 0xaf, 0x93, 0x9f, + 0xfc, 0x7e, 0x76, 0xdb, 0x72, 0xbd, 0x0e, 0x39, 0x71, 0x3b, 0xf1, 0x76, 0x45, 0x84, 0xaf, 0xbb, + 0x1f, 0xcd, 0xa7, 0x4f, 0xc2, 0x56, 0xd8, 0xe7, 0x66, 0x99, 0x9b, 0x2b, 0x9a, 0xe8, 0x6d, 0xa1, + 0xae, 0xe7, 0xce, 0xf8, 0xa9, 0x58, 0x1e, 0xaf, 0x46, 0x66, 0x1c, 0xda, 0x4f, 0x8b, 0xcb, 0x2d, + 0x39, 0x21, 0x7d, 0x7b, 0xeb, 0x17, 0xc2, 0x74, 0xd2, 0xed, 0xc8, 0xc7, 0x9e, 0xaf, 0x2b, 0x1f, + 0xf0, 0x51, 0x56, 0xdb, 0x53, 0x63, 0x74, 0x68, 0x72, 0xae, 0x14, 0xb1, 0xae, 0xb4, 0xb9, 0x62, + 0xc9, 0x0e, 0x56, 0x08, 0xc9, 0x52, 0xb8, 0xa2, 0x4f, 0xd3, 0x9a, 0xb7, 0xf0, 0xa1, 0x78, 0xe5, + 0x1b, 0x5f, 0xe7, 0xf7, 0x33, 0x0c, 0x7c, 0x5f, 0x13, 0x9f, 0xf5, 0x65, 0xf1, 0x9d, 0xdd, 0xab, + 0xf2, 0xb2, 0xa9, 0xd1, 0x0f, 0x53, 0xcb, 0x4f, 0x06, 0xd9, 0xb8, 0xcd, 0xdd, 0x8d, 0x15, 0xa4, + 0x56, 0xd3, 0x91, 0x85, 0xd4, 0x5f, 0xc5, 0x46, 0x6f, 0x74, 0xb5, 0xa1, 0x97, 0x84, 0xae, 0x9b, + 0x59, 0xf7, 0x5d, 0x6b, 0xe2, 0xe9, 0xd3, 0xd8, 0xe3, 0x98, 0x37, 0x16, 0x46, 0xdb, 0xef, 0x2a, + 0x2f, 0x17, 0x4f, 0x3b, 0xb7, 0x1f, 0xc4, 0x95, 0xe9, 0xd0, 0x67, 0x65, 0xb7, 0xa1, 0xf2, 0x69, + 0x99, 0xb9, 0x38, 0x2b, 0xd2, 0xbb, 0xa1, 0xf3, 0xb1, 0xca, 0xf9, 0x48, 0xb2, 0x78, 0x9e, 0x13, + 0x2e, 0x66, 0x2f, 0xb1, 0xf8, 0x25, 0x93, 0x13, 0x7a, 0x9b, 0xad, 0xf7, 0xdd, 0x50, 0xf2, 0x70, + 0xa5, 0x8e, 0x89, 0xbb, 0x19, 0xbe, 0x3b, 0x75, 0xed, 0xa5, 0xe6, 0xf6, 0xdf, 0xe3, 0xed, 0x27, + 0xba, 0xcb, 0xcf, 0x9d, 0xcd, 0xcc, 0x44, 0xef, 0x5c, 0xb7, 0xb4, 0xeb, 0x8a, 0xe7, 0xe5, 0x63, + 0x72, 0xea, 0xe0, 0x98, 0xa7, 0xcf, 0xb4, 0xde, 0x5f, 0x09, 0xd8, 0xf7, 0x95, 0x86, 0x3d, 0x70, + 0x4b, 0xc9, 0xd3, 0x97, 0xf5, 0x5c, 0xdb, 0x6b, 0x11, 0xc5, 0xf3, 0x7b, 0x1b, 0xb1, 0xc9, 0xc8, + 0x44, 0x9a, 0xdf, 0x05, 0x65, 0x4d, 0xc9, 0xfb, 0xdb, 0xb6, 0xbe, 0xfb, 0x91, 0xae, 0xd7, 0xc7, + 0xc3, 0xea, 0xdb, 0xd9, 0xd3, 0x43, 0xbb, 0x79, 0x92, 0xb2, 0x5c, 0x21, 0xa6, 0xa9, 0xa7, 0xb7, + 0xa1, 0xaa, 0xe2, 0x34, 0xd3, 0xea, 0xab, 0xbc, 0x66, 0xbf, 0xe4, 0xb6, 0xf6, 0x32, 0xf2, 0xed, + 0xaf, 0xc1, 0x69, 0x0f, 0xbd, 0x6a, 0xbe, 0x8c, 0xef, 0x3e, 0xeb, 0xbf, 0x36, 0x78, 0x8d, 0xee, + 0x94, 0x56, 0xfe, 0xed, 0x37, 0x75, 0xd9, 0x4e, 0xce, 0xe5, 0xe1, 0x0f, 0x37, 0x4f, 0x4f, 0x63, + 0x5f, 0x82, 0x1b, 0xed, 0x95, 0x3e, 0xc9, 0xbb, 0x61, 0x0e, 0x12, 0xd8, 0xdf, 0x4a, 0xfe, 0x4a, + 0x6a, 0x87, 0xf0, 0x91, 0x4b, 0xf2, 0xb1, 0x9d, 0xfa, 0xe0, 0xa7, 0xcc, 0xc2, 0x1a, 0xd6, 0x5c, + 0x43, 0x99, 0x23, 0xfa, 0xe0, 0x8f, 0x77, 0xd7, 0xcd, 0x7b, 0x6a, 0xb8, 0x92, 0x53, 0x6f, 0x43, + 0x69, 0xaf, 0x1d, 0x97, 0xed, 0xa7, 0xde, 0x89, 0x72, 0xe9, 0xbf, 0xc5, 0x6b, 0x1e, 0xa6, 0x8d, + 0xe4, 0xe2, 0xad, 0xb5, 0xd3, 0xb9, 0x39, 0x79, 0x19, 0x43, 0x2f, 0x36, 0xdb, 0x5f, 0x35, 0xdf, + 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x2f, 0x17, 0xb0, 0xe8, 0x57, 0x66, 0xbb, 0xbf, 0x9a, + 0xbb, 0xbe, 0x10, 0x17, 0x2b, 0x29, 0xb1, 0x84, 0xfb, 0x5b, 0x6d, 0xfb, 0x10, 0x86, 0x89, 0x29, + 0x7a, 0x0a, 0xbd, 0x74, 0x4f, 0x92, 0x75, 0x79, 0xf8, 0x90, 0x86, 0xef, 0x75, 0x2b, 0x7c, 0x37, + 0x46, 0x69, 0xf5, 0x8e, 0xed, 0xff, 0xf0, 0xc6, 0x57, 0xf7, 0x6b, 0x55, 0xb8, 0xed, 0x8b, 0xdf, + 0x26, 0xdb, 0x23, 0x47, 0xc2, 0xba, 0x24, 0xda, 0xa6, 0x6d, 0x59, 0x45, 0x2a, 0xa5, 0x29, 0x4b, + 0xf8, 0x9e, 0x09, 0x68, 0xd4, 0xf4, 0x84, 0xc6, 0x87, 0x7d, 0x7c, 0xd5, 0x5d, 0xf4, 0x11, 0xca, + 0xf8, 0x80, 0x92, 0x75, 0x92, 0x56, 0xd1, 0x2e, 0xeb, 0xaf, 0x88, 0x2b, 0xb6, 0x9f, 0x6d, 0x3f, + 0x05, 0x45, 0xa6, 0xdb, 0x6b, 0xa6, 0x5d, 0x76, 0xd2, 0xf8, 0xf0, 0x46, 0x23, 0x27, 0x53, 0xa7, + 0xc1, 0x50, 0x9a, 0xd6, 0x9c, 0x65, 0x7b, 0x4d, 0x77, 0xc3, 0x42, 0x1f, 0x1e, 0x5c, 0x34, 0xd5, + 0x3f, 0xf0, 0xa6, 0xd5, 0x6d, 0x9b, 0x1a, 0xd3, 0x1f, 0xc5, 0x6a, 0xd5, 0xec, 0x49, 0x92, 0x76, + 0xf8, 0x52, 0xa9, 0xa1, 0xb5, 0x75, 0xea, 0x9b, 0x2c, 0x92, 0xb3, 0xe3, 0xc4, 0x97, 0x09, 0x89, + 0x46, 0xaa, 0x5c, 0xc6, 0xb3, 0xa9, 0x6e, 0x5f, 0x8c, 0xa1, 0xca, 0xc6, 0x86, 0xda, 0x1d, 0x4b, + 0x68, 0xf9, 0x55, 0x46, 0xcf, 0x05, 0x44, 0x75, 0xa4, 0xc9, 0x27, 0x6e, 0x7d, 0x7d, 0xdf, 0x0a, + 0x4b, 0xb6, 0xfd, 0xd2, 0xda, 0xed, 0x86, 0xbc, 0x6c, 0xaa, 0x2c, 0xe7, 0xc2, 0x25, 0x2e, 0xa4, + 0x87, 0xd2, 0x55, 0xa2, 0xf8, 0x52, 0xa4, 0x64, 0x8c, 0xe5, 0xd9, 0xdb, 0x8c, 0x1c, 0x2c, 0x62, + 0x81, 0xa1, 0xba, 0xb0, 0x64, 0x4f, 0x8e, 0x23, 0x61, 0xda, 0xd2, 0xfb, 0x11, 0x75, 0x6a, 0x14, + 0xac, 0x07, 0x1d, 0x75, 0x3f, 0x04, 0xd7, 0xd6, 0xa4, 0x97, 0xb5, 0x73, 0x04, 0x5d, 0xff, 0x2d, + 0xde, 0xe8, 0x5e, 0x1b, 0xf1, 0xda, 0xb1, 0x1f, 0x21, 0xab, 0x5e, 0x10, 0xf8, 0x2e, 0x2a, 0xd6, + 0xf7, 0x77, 0xf8, 0x24, 0x33, 0xab, 0x62, 0x3f, 0x3b, 0xe4, 0xa9, 0x99, 0xfc, 0x12, 0x1b, 0x88, + 0x73, 0x0f, 0x85, 0x4c, 0x4d, 0x24, 0xb4, 0x9a, 0x64, 0xcd, 0x66, 0xa9, 0x72, 0xbf, 0xf0, 0xa1, + 0x5e, 0x12, 0x32, 0xde, 0xab, 0x45, 0x3c, 0x0d, 0x9f, 0x77, 0xc1, 0x04, 0x6a, 0xff, 0xb1, 0xe9, + 0x2a, 0x19, 0x99, 0x34, 0xa1, 0xf2, 0xa9, 0xf5, 0xd0, 0x3f, 0xa6, 0x9d, 0x7c, 0x6c, 0x67, 0x28, + 0xea, 0xc9, 0x16, 0xaa, 0x64, 0x9b, 0x5f, 0x7a, 0xb3, 0xc2, 0x2a, 0xcd, 0xd5, 0xf8, 0xbb, 0xd4, + 0xff, 0xf1, 0xbb, 0xc7, 0xac, 0xcb, 0x99, 0x58, 0x64, 0xc9, 0xcd, 0x68, 0x97, 0x73, 0x2c, 0xc5, + 0x87, 0x1f, 0xd5, 0x97, 0xfe, 0x33, 0xcb, 0xae, 0x8b, 0x65, 0xd1, 0x39, 0xef, 0xb3, 0x7f, 0x0e, + 0xd9, 0x19, 0xa6, 0xae, 0x5b, 0x44, 0x4c, 0x6c, 0x35, 0x49, 0x47, 0x74, 0xd9, 0xa8, 0x3f, 0xf1, + 0xb3, 0xb0, 0xc9, 0x98, 0xa7, 0x09, 0xe1, 0x34, 0x33, 0xea, 0xdf, 0x28, 0x8f, 0x3a, 0x94, 0xfe, + 0x2d, 0x51, 0xb4, 0x1d, 0x71, 0xa1, 0x7f, 0x88, 0xe9, 0xbd, 0x33, 0x67, 0xe1, 0x4a, 0x8c, 0xea, + 0x1b, 0x7b, 0xd9, 0x53, 0xc4, 0x3f, 0x5d, 0x83, 0x6d, 0x4d, 0x31, 0xac, 0x9e, 0xfd, 0x32, 0xe7, + 0xbf, 0xc2, 0x85, 0x2e, 0x6d, 0xa6, 0xf6, 0xf3, 0xf5, 0x69, 0x5b, 0x45, 0x9f, 0xe3, 0x4d, 0x35, + 0x79, 0x64, 0xee, 0xb7, 0xb3, 0x9b, 0x2b, 0xc5, 0x63, 0x4c, 0x63, 0x7f, 0xf8, 0x5a, 0xcc, 0xdb, + 0xa2, 0x93, 0x7e, 0x97, 0x27, 0xeb, 0xfe, 0xf6, 0x93, 0x65, 0xe0, 0xa4, 0xe7, 0xd2, 0xb0, 0x87, + 0x4d, 0x69, 0xdb, 0x46, 0xac, 0xca, 0xb1, 0xe3, 0xee, 0xaa, 0x9d, 0x6e, 0x9b, 0x53, 0x7f, 0x05, + 0xa4, 0x35, 0x9a, 0x92, 0x38, 0xf8, 0xb7, 0x8b, 0xe3, 0x89, 0x96, 0x2a, 0xab, 0xa4, 0x3b, 0xf6, + 0x4d, 0xa7, 0xa0, 0xbb, 0x38, 0x60, 0x4e, 0x75, 0x2c, 0x96, 0x10, 0x57, 0x3e, 0x83, 0x4f, 0xf2, + 0xf3, 0xe2, 0x6b, 0xbb, 0xdb, 0xae, 0x63, 0xd3, 0x6b, 0xe4, 0xad, 0x22, 0xe2, 0xe5, 0x14, 0xfb, + 0xae, 0x30, 0x5b, 0xa2, 0x2f, 0xf1, 0x3e, 0x94, 0x4d, 0x1b, 0x52, 0xe3, 0x3e, 0x27, 0xf8, 0x2e, + 0x36, 0x5d, 0xf3, 0xae, 0x8b, 0xfe, 0x09, 0x39, 0x35, 0x2d, 0x9f, 0x2e, 0x9a, 0x7f, 0x13, 0x43, + 0x95, 0x89, 0xf3, 0xf8, 0xbb, 0x4d, 0x6d, 0x6d, 0x2e, 0x5e, 0x2b, 0xf8, 0x23, 0x12, 0x7c, 0x7d, + 0x8b, 0x17, 0x1e, 0x1d, 0xf2, 0x3f, 0xe6, 0x11, 0x5a, 0xf9, 0x7a, 0xaf, 0xac, 0x7f, 0xa2, 0x9e, + 0xc5, 0xac, 0xa8, 0xeb, 0xc1, 0x11, 0x1d, 0xf1, 0x6c, 0xdf, 0x47, 0x7b, 0xe1, 0xf0, 0x80, 0xf2, + 0xf5, 0x15, 0xb4, 0x9e, 0x6d, 0x69, 0xba, 0xa7, 0x97, 0x7f, 0xc1, 0x35, 0x15, 0x52, 0xc8, 0x9d, + 0xb8, 0x4d, 0x89, 0x27, 0xc2, 0x99, 0xb0, 0x9e, 0xb9, 0xa4, 0x4c, 0x9a, 0x29, 0x71, 0xed, 0x1a, + 0x0f, 0xf0, 0x47, 0x6f, 0xbb, 0x05, 0xc1, 0x6d, 0xaa, 0xcd, 0x0c, 0xbd, 0x2d, 0xfe, 0x42, 0x5a, + 0x64, 0xfe, 0x12, 0x2e, 0x95, 0xb7, 0x9e, 0x3f, 0x05, 0x56, 0x93, 0xe7, 0x86, 0x93, 0x54, 0x9d, + 0x5c, 0x46, 0xdd, 0x66, 0xf2, 0x67, 0x8c, 0xd1, 0x91, 0xb7, 0xd3, 0x4b, 0x66, 0xda, 0x3c, 0x71, + 0x5f, 0x9e, 0x62, 0xa4, 0x2f, 0xf8, 0x48, 0x89, 0xd3, 0xa7, 0xbf, 0x82, 0xe3, 0xd3, 0xb4, 0xef, + 0x8a, 0x70, 0xf1, 0x3a, 0x4d, 0x37, 0x49, 0xdf, 0xc1, 0x19, 0xa3, 0xd9, 0x32, 0x87, 0xd5, 0xc1, + 0x18, 0xd5, 0xaf, 0x34, 0x82, 0xd1, 0xf1, 0xcf, 0x94, 0x39, 0x5a, 0x9b, 0xa1, 0xbd, 0x08, 0x72, + 0x8c, 0x7b, 0xc1, 0x17, 0x2d, 0x6a, 0xa0, 0x43, 0xe5, 0xde, 0xe0, 0xbb, 0x97, 0xbb, 0x9e, 0x27, + 0xc4, 0xe5, 0xef, 0x37, 0xd6, 0x27, 0xc4, 0x82, 0x3a, 0x4e, 0xcc, 0x99, 0x17, 0x89, 0x84, 0xf9, + 0x05, 0xcd, 0xff, 0x5c, 0x22, 0xba, 0x10, 0xf2, 0x71, 0x54, 0xaf, 0x7b, 0xfc, 0xbc, 0x5e, 0xb8, + 0x2e, 0x3d, 0x25, 0xde, 0xe4, 0x0c, 0x79, 0x48, 0x6f, 0xeb, 0x96, 0x2f, 0xaf, 0x84, 0xb3, 0x66, + 0xb7, 0xe2, 0x7c, 0x44, 0x56, 0x68, 0xbb, 0x18, 0x3f, 0x72, 0x89, 0x91, 0x78, 0x99, 0x73, 0xce, + 0xa2, 0x5b, 0x75, 0xc4, 0xf6, 0x9c, 0xb2, 0x8f, 0x5c, 0xa3, 0xee, 0x83, 0x7f, 0x28, 0xb5, 0x55, + 0x54, 0x35, 0x90, 0x18, 0xf5, 0x23, 0xbc, 0x44, 0x14, 0x04, 0x35, 0x4f, 0x15, 0xdf, 0x88, 0xfc, + 0x51, 0xa4, 0x83, 0xc9, 0x7f, 0xe2, 0x20, 0x8e, 0x14, 0xae, 0xdf, 0x79, 0x79, 0xb7, 0xa1, 0xae, + 0x19, 0xe7, 0x48, 0xdc, 0x60, 0xb5, 0x7f, 0x27, 0x1e, 0x74, 0x9a, 0xae, 0x93, 0xd1, 0x21, 0x8f, + 0x53, 0xde, 0xdb, 0xdf, 0x05, 0x65, 0x26, 0xdd, 0xde, 0xdb, 0x2d, 0x26, 0xa5, 0xf0, 0x4f, 0x7d, + 0x53, 0xde, 0x3b, 0xe0, 0x90, 0xa4, 0xcd, 0x53, 0xd7, 0x09, 0x91, 0xd7, 0xd5, 0x7c, 0x25, 0x18, + 0xcb, 0xe9, 0xa7, 0x66, 0xb8, 0x21, 0x2e, 0x92, 0x5d, 0x11, 0xcc, 0x32, 0xb5, 0xf2, 0xd5, 0x57, + 0xef, 0xcc, 0xc7, 0x8b, 0xa6, 0xfb, 0xbd, 0xc9, 0xc1, 0x71, 0x77, 0x76, 0xd2, 0xf2, 0x92, 0x26, + 0x09, 0xac, 0x6f, 0xf3, 0xe3, 0x1f, 0x04, 0x5b, 0x6d, 0xe2, 0xf8, 0x83, 0x0e, 0x29, 0xec, 0x25, + 0xda, 0xf2, 0xdf, 0x11, 0x14, 0x57, 0x7b, 0xb5, 0x4b, 0xe5, 0xbd, 0xa4, 0x6b, 0x96, 0x69, 0x50, + 0xeb, 0x92, 0x46, 0x56, 0xab, 0x84, 0x88, 0xa7, 0xcf, 0x0e, 0xd2, 0x5e, 0x24, 0x47, 0xc8, 0x51, + 0x36, 0x0a, 0xc4, 0xac, 0x62, 0x21, 0x32, 0x37, 0xdb, 0xf5, 0x78, 0x7b, 0x8a, 0x2a, 0xae, 0x9d, + 0x0d, 0x44, 0x73, 0x11, 0xd1, 0x7e, 0x09, 0xad, 0xe6, 0x80, 0xf6, 0x38, 0xfa, 0xf8, 0x8b, 0xdd, + 0x56, 0x9f, 0x11, 0x7c, 0xd9, 0xfe, 0x22, 0x59, 0x58, 0x9f, 0xfc, 0x49, 0x74, 0x89, 0xc9, 0x9f, + 0xec, 0xae, 0xde, 0xb8, 0xee, 0x6c, 0x4f, 0x49, 0x5b, 0x6b, 0xc4, 0xc1, 0x11, 0x12, 0x4a, 0xd6, + 0x21, 0xe3, 0xc8, 0xef, 0xb7, 0x6e, 0x76, 0x6d, 0xd4, 0x40, 0x97, 0xad, 0x3a, 0xe2, 0x04, 0x8a, + 0xaa, 0xaa, 0xd8, 0x37, 0x7c, 0x4c, 0x11, 0xc1, 0xe7, 0x40, 0xba, 0xbe, 0xe1, 0x73, 0x1e, 0xf5, + 0x27, 0x31, 0x98, 0x6a, 0xdc, 0x4f, 0x38, 0xde, 0xde, 0x6a, 0x79, 0x3b, 0xcf, 0xb8, 0xfe, 0x51, + 0x8e, 0xee, 0xeb, 0xb3, 0xae, 0xab, 0xb2, 0x6e, 0xfe, 0x2b, 0x27, 0xf5, 0x4f, 0x13, 0x15, 0xaa, + 0xed, 0x36, 0xbe, 0x12, 0xbd, 0xbb, 0x7a, 0xf8, 0x4e, 0xfb, 0xb7, 0x72, 0xc3, 0xd7, 0x5f, 0x77, + 0xbf, 0xc2, 0x67, 0x5a, 0xd3, 0xda, 0x2f, 0x21, 0x9b, 0x6d, 0xcf, 0xf8, 0x81, 0x37, 0x5e, 0xa3, + 0x36, 0xfe, 0x23, 0xe3, 0xf1, 0x5b, 0xf7, 0x1d, 0xca, 0x7b, 0x94, 0xfc, 0xe5, 0x7f, 0x97, 0xc2, + 0x55, 0x76, 0xd7, 0x45, 0xd4, 0x47, 0x58, 0xe8, 0x5b, 0xa3, 0x3f, 0xc7, 0xcb, 0x8d, 0xdb, 0x9f, + 0x1b, 0xea, 0xbf, 0x15, 0xad, 0x6b, 0x55, 0xcd, 0x4e, 0x9f, 0xd1, 0xe7, 0x2b, 0x90, 0x42, 0x74, + 0xfe, 0xe9, 0x5d, 0x2f, 0x2f, 0x76, 0xf1, 0x31, 0x17, 0x78, 0xdd, 0x15, 0x9c, 0xf2, 0xc3, 0x7f, + 0x94, 0xf6, 0xee, 0xbb, 0x38, 0xea, 0xff, 0xc5, 0x91, 0x53, 0xf5, 0x4b, 0xde, 0xd3, 0xf1, 0x31, + 0x3c, 0xea, 0x2d, 0xdf, 0xef, 0x99, 0x8f, 0x9a, 0x95, 0x24, 0xbc, 0x60, 0x82, 0xfd, 0xd6, 0x66, + 0x2f, 0xba, 0xcc, 0xc5, 0x76, 0x7d, 0xa6, 0xb1, 0x11, 0xb1, 0xb3, 0x77, 0x84, 0x8c, 0xe1, 0xf7, + 0x3d, 0xab, 0x98, 0xd2, 0xdb, 0xa8, 0xb1, 0xf3, 0x1d, 0xf5, 0xbc, 0xa9, 0x06, 0xdf, 0xeb, 0x9f, + 0xe0, 0xb8, 0x88, 0x7b, 0x9b, 0x6f, 0x82, 0xf8, 0xcb, 0xb4, 0x7f, 0xb5, 0x53, 0x70, 0xf3, 0xb5, + 0x89, 0x4d, 0x55, 0x9a, 0x50, 0xe3, 0x6f, 0xc1, 0x2f, 0x33, 0x68, 0x72, 0xb6, 0x9c, 0x7c, 0x10, + 0xef, 0x2c, 0x62, 0xf9, 0x4a, 0xf3, 0x53, 0xe4, 0xa4, 0x92, 0x49, 0x78, 0x29, 0x2e, 0xe9, 0x52, + 0xa4, 0x9d, 0x3f, 0x7c, 0x11, 0xf4, 0xdf, 0x2f, 0x82, 0x31, 0x0d, 0x65, 0xbe, 0xae, 0x6a, 0xa1, + 0xd8, 0x37, 0xd1, 0xfb, 0xe0, 0x90, 0xce, 0x6c, 0x34, 0x3e, 0xae, 0x5b, 0x4d, 0xd5, 0x72, 0xcf, + 0xad, 0x62, 0xf8, 0x9e, 0xee, 0xed, 0x7e, 0x5d, 0xd3, 0x72, 0x73, 0x75, 0x55, 0xde, 0xab, 0x7c, + 0x94, 0x32, 0x76, 0xe3, 0xf2, 0xcd, 0xcb, 0x05, 0xfc, 0x15, 0xf7, 0x6e, 0xdb, 0xcb, 0x74, 0x82, + 0xd4, 0x0f, 0xf2, 0xf2, 0x1b, 0xc9, 0xf3, 0xfd, 0x8b, 0xa8, 0xaf, 0xee, 0xa5, 0x62, 0xd7, 0x92, + 0x96, 0x96, 0x26, 0x0a, 0x04, 0x6a, 0x95, 0x26, 0x81, 0xf7, 0x71, 0xe2, 0x35, 0xab, 0x3f, 0xbe, + 0x1a, 0xce, 0x52, 0x68, 0xb8, 0xf8, 0xef, 0x7f, 0x05, 0x72, 0x40, 0x6b, 0x32, 0xec, 0xcf, 0xe9, + 0xa3, 0x27, 0x7a, 0x36, 0x7c, 0x28, 0x53, 0x66, 0xd2, 0x76, 0xad, 0xc1, 0x3b, 0x59, 0x7b, 0x4a, + 0x99, 0x89, 0xe1, 0x1b, 0x6a, 0xd4, 0x9f, 0xb9, 0xb6, 0x9f, 0x9a, 0x95, 0x3f, 0x96, 0x31, 0x97, + 0xfd, 0xed, 0x3c, 0xbc, 0x25, 0xe2, 0xed, 0x35, 0xf8, 0x46, 0xe5, 0xbd, 0xe9, 0x52, 0x4d, 0xc9, + 0x9e, 0xfb, 0x93, 0x4f, 0xc1, 0x4f, 0x23, 0xd0, 0xe5, 0x81, 0xab, 0x5d, 0x67, 0xd4, 0xd5, 0xcc, + 0x45, 0xaf, 0xcd, 0x63, 0xb4, 0xd7, 0x82, 0x1a, 0x19, 0xd7, 0x6d, 0x72, 0x62, 0x0f, 0x8c, 0x93, + 0x7c, 0xdb, 0x68, 0x5c, 0xdf, 0xce, 0xcb, 0xae, 0x33, 0xaa, 0x6d, 0xdb, 0x49, 0x55, 0x76, 0xda, + 0x7f, 0x05, 0x76, 0x97, 0x6d, 0x2b, 0xaa, 0x7b, 0x7c, 0x14, 0x09, 0xab, 0x59, 0xbe, 0xdf, 0x14, + 0x21, 0x72, 0x75, 0x9a, 0xf8, 0x23, 0xad, 0x70, 0xc7, 0xab, 0xfc, 0x16, 0x16, 0x5f, 0x4d, 0x3a, + 0x79, 0x7d, 0x36, 0x1e, 0x10, 0x8f, 0xd2, 0x27, 0xb3, 0xda, 0xda, 0xcd, 0x4f, 0x82, 0x1f, 0x3e, + 0x6d, 0xf0, 0xa1, 0x8d, 0xc6, 0xee, 0x51, 0x7d, 0x75, 0xba, 0x56, 0xfd, 0xdd, 0x52, 0x76, 0x57, + 0xe5, 0xc4, 0xfe, 0x3c, 0x8c, 0xda, 0x22, 0x9a, 0x44, 0xcb, 0x33, 0x0b, 0x3e, 0x26, 0x8a, 0xfc, + 0x4d, 0x97, 0x55, 0xf0, 0x91, 0xb8, 0xdd, 0xc8, 0xe7, 0xa5, 0xbc, 0x44, 0x64, 0x8c, 0x9b, 0xd6, + 0xfc, 0xc3, 0x57, 0x2f, 0x32, 0xf1, 0x87, 0xba, 0x84, 0xcf, 0x4d, 0x75, 0xe2, 0xd1, 0xf7, 0xe2, + 0x6c, 0x2a, 0x84, 0xf6, 0x71, 0xdf, 0xb3, 0xeb, 0xe5, 0x3b, 0x27, 0x45, 0x5c, 0x4d, 0x93, 0xda, + 0xa6, 0xff, 0x21, 0x04, 0x2c, 0x5f, 0xe0, 0x87, 0x83, 0xce, 0x62, 0xa7, 0x1a, 0xf7, 0xc1, 0x0f, + 0x97, 0xb1, 0xf3, 0x5a, 0x6b, 0x27, 0x26, 0xda, 0x5f, 0x15, 0x65, 0x95, 0x8a, 0x44, 0x8e, 0xf8, + 0x83, 0xb1, 0xcc, 0xcb, 0x4d, 0xef, 0xe3, 0x33, 0x7e, 0x9d, 0x27, 0x7d, 0x2d, 0xbf, 0x09, 0xd2, + 0x97, 0x54, 0x9b, 0xfc, 0x82, 0x0c, 0x89, 0x0d, 0x0b, 0xe6, 0x2d, 0x6d, 0xf8, 0x2c, 0x3d, 0x55, + 0x2d, 0x31, 0xbc, 0x0f, 0x55, 0x53, 0xdb, 0x1d, 0x7c, 0x4d, 0x6e, 0x88, 0xff, 0xab, 0xe0, 0xab, + 0xb6, 0x99, 0x33, 0x74, 0xdb, 0xf5, 0x5c, 0x59, 0x36, 0x9a, 0xda, 0x69, 0x71, 0x25, 0x97, 0xb7, + 0x5b, 0x4d, 0x7e, 0x3b, 0x69, 0xc9, 0xd9, 0x0c, 0xe3, 0xad, 0x37, 0xea, 0x5f, 0x82, 0xc9, 0xfc, + 0x98, 0x9b, 0x57, 0x65, 0x27, 0x4f, 0xcb, 0xe0, 0xb6, 0xbb, 0x6d, 0x97, 0x6d, 0xe5, 0x27, 0x04, + 0x46, 0x54, 0xd7, 0xaf, 0x96, 0x86, 0x4f, 0xf8, 0xbf, 0x33, 0x76, 0x97, 0xc5, 0x79, 0x9a, 0x96, + 0x97, 0xc5, 0xea, 0xdf, 0x69, 0x3f, 0x62, 0x52, 0x4d, 0x2f, 0x8f, 0x35, 0x2b, 0x69, 0x52, 0xdb, + 0xb7, 0xe0, 0x8e, 0xdd, 0xfe, 0x5f, 0x05, 0x27, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xcd, 0xed, 0xdb, + 0xaf, 0x84, 0x34, 0xe9, 0xa7, 0x4c, 0xd9, 0xcd, 0x9e, 0x08, 0xc4, 0x26, 0xdd, 0x5c, 0x3e, 0x0b, + 0x2f, 0x7a, 0xea, 0x9b, 0x6d, 0x3a, 0x5e, 0x26, 0xaf, 0xc4, 0x44, 0x51, 0xd1, 0x3a, 0x56, 0xb8, + 0x98, 0x27, 0xb4, 0xcd, 0x9e, 0xf5, 0x73, 0xe6, 0xb0, 0xf2, 0x7f, 0x08, 0xdb, 0x27, 0x13, 0xfe, + 0x7c, 0x8e, 0x61, 0xfd, 0x91, 0xaf, 0xc1, 0x76, 0xa8, 0xd7, 0x88, 0x72, 0x39, 0xc4, 0xcb, 0x55, + 0xfe, 0x0b, 0xa6, 0x9c, 0x4e, 0x1d, 0x56, 0x2a, 0x03, 0x41, 0x22, 0x67, 0xc1, 0x59, 0x47, 0x0f, + 0xda, 0xca, 0x83, 0xdc, 0x5d, 0x8c, 0xb0, 0x7d, 0xf5, 0x5c, 0xba, 0x32, 0xee, 0xb8, 0x4c, 0x41, + 0x58, 0xa7, 0x6a, 0xdd, 0x70, 0x8e, 0xf6, 0xa7, 0xcf, 0x24, 0x27, 0xe1, 0x22, 0xa6, 0xfd, 0x06, + 0xd3, 0x6b, 0x82, 0x3a, 0xd9, 0x58, 0xae, 0x6e, 0x56, 0x57, 0xcd, 0x43, 0x5b, 0x62, 0xb9, 0x0e, + 0x56, 0x2d, 0xd7, 0x25, 0x12, 0x1c, 0x8c, 0xf8, 0xbc, 0xf9, 0xbb, 0xfe, 0x28, 0xc9, 0xb6, 0xfd, + 0x35, 0xf0, 0xa4, 0xad, 0xe8, 0x69, 0x26, 0xc6, 0xd2, 0x19, 0xb2, 0x77, 0x69, 0xfe, 0x08, 0xb4, + 0xca, 0xc4, 0xe7, 0xf8, 0x4a, 0xfb, 0x6a, 0x8a, 0xc7, 0xe0, 0x92, 0x78, 0xde, 0x2c, 0x6f, 0x82, + 0x3a, 0x9b, 0x2b, 0x07, 0xc2, 0x22, 0xe7, 0xd4, 0xa6, 0xeb, 0x75, 0xfc, 0x12, 0x08, 0x4a, 0xf7, + 0x1e, 0x0a, 0xed, 0x54, 0x4f, 0x34, 0x8c, 0xfb, 0xb5, 0x8b, 0xe1, 0x4e, 0x5c, 0x8d, 0x63, 0xad, + 0x7c, 0xf8, 0x5d, 0x76, 0x5d, 0x1b, 0x1f, 0x35, 0x5b, 0xd7, 0x04, 0xdb, 0xa5, 0xe5, 0x63, 0x0f, + 0x85, 0x09, 0x6a, 0xaa, 0x5e, 0x2f, 0x9d, 0x4e, 0x5f, 0x5c, 0xd9, 0xdc, 0x4c, 0x4d, 0x2b, 0xdf, + 0x53, 0xe2, 0x20, 0x93, 0xbb, 0x6f, 0xc4, 0x42, 0x05, 0xdd, 0x1e, 0x63, 0x12, 0xf6, 0x5d, 0xfc, + 0x13, 0xcc, 0x65, 0x56, 0x81, 0xda, 0x99, 0xc6, 0x5e, 0xef, 0xdf, 0x19, 0xf1, 0x84, 0xbf, 0xd4, + 0x1e, 0x6e, 0x55, 0xf5, 0xa1, 0xb0, 0xa8, 0x63, 0x8d, 0x0d, 0xc4, 0x65, 0xcf, 0x88, 0x85, 0x2e, + 0x7f, 0x6c, 0x6e, 0xb5, 0x19, 0x7e, 0xe1, 0x1b, 0x78, 0x92, 0x1a, 0x50, 0xc7, 0x89, 0xf4, 0xde, + 0xa6, 0xa8, 0xbc, 0x84, 0xa7, 0x5f, 0x5d, 0x7c, 0x10, 0x89, 0x73, 0xf1, 0xba, 0xae, 0x2f, 0x92, + 0x7d, 0x36, 0xa5, 0x2b, 0x90, 0xc7, 0xba, 0x49, 0x78, 0xfb, 0x9f, 0x1a, 0xbb, 0x69, 0x8c, 0xab, + 0xc1, 0x97, 0x3f, 0x64, 0x7b, 0x6b, 0xf1, 0x22, 0xcb, 0xd2, 0xa4, 0xd5, 0x8c, 0xf9, 0xe8, 0x91, + 0x7c, 0x93, 0xe5, 0xb7, 0xf7, 0xa6, 0xdd, 0x70, 0x4c, 0x46, 0xd7, 0xa4, 0x8d, 0x93, 0x12, 0x72, + 0xea, 0xdd, 0xf0, 0x50, 0x74, 0xca, 0xd2, 0x33, 0x8e, 0x53, 0xa3, 0xf7, 0xc1, 0x59, 0x52, 0xbd, + 0xd5, 0x29, 0x98, 0xe7, 0xdf, 0x64, 0x76, 0x3f, 0xc5, 0x4d, 0x0b, 0x9f, 0x72, 0x76, 0xfc, 0x14, + 0x74, 0x9c, 0xcd, 0x58, 0x8c, 0xd7, 0x3e, 0x0a, 0x63, 0x38, 0xf4, 0x9f, 0x4e, 0x95, 0xcc, 0xd5, + 0xc1, 0x64, 0xff, 0x26, 0xce, 0xc2, 0x5c, 0xb2, 0x2e, 0xd7, 0x2f, 0x84, 0xb6, 0x38, 0xed, 0x6f, + 0x63, 0x1b, 0x5f, 0x13, 0x26, 0xa5, 0x12, 0x48, 0x8a, 0xc7, 0xe1, 0x2c, 0xad, 0xed, 0x1a, 0x30, + 0xbc, 0x25, 0x49, 0x26, 0x9a, 0x69, 0xe9, 0xf8, 0xcd, 0xa4, 0xed, 0x34, 0xaa, 0x37, 0x4d, 0xd8, + 0x9b, 0xbe, 0xb9, 0x04, 0x56, 0xa7, 0xe5, 0x23, 0xbe, 0x2a, 0x26, 0xf1, 0x5d, 0xaf, 0x73, 0xfe, + 0x3c, 0x23, 0xcb, 0x3e, 0xea, 0x05, 0xf8, 0x9f, 0xcb, 0xbb, 0xba, 0x89, 0xc5, 0x70, 0x99, 0x64, + 0xce, 0xf6, 0xbc, 0x59, 0x2a, 0xd1, 0xb3, 0x19, 0x96, 0x3e, 0xcf, 0x2c, 0xb6, 0xab, 0x25, 0x48, + 0x27, 0x89, 0xdc, 0x48, 0x9f, 0x96, 0xf7, 0x89, 0xe6, 0xaa, 0xeb, 0x89, 0xca, 0x7b, 0xde, 0x0a, + 0xb9, 0x84, 0xad, 0x7c, 0x40, 0xa1, 0x1a, 0xaa, 0xd6, 0xf9, 0x2f, 0x77, 0x11, 0xd5, 0xfe, 0x62, + 0x9b, 0x0d, 0x95, 0x04, 0x3c, 0x26, 0x45, 0x55, 0xad, 0x61, 0x3e, 0xef, 0x64, 0xe0, 0x8f, 0x9a, + 0xab, 0x5c, 0x48, 0x98, 0x35, 0xe4, 0x3b, 0x64, 0xcf, 0xd9, 0x55, 0x70, 0xc7, 0x26, 0x7c, 0xa6, + 0x5e, 0xc9, 0x49, 0x29, 0xf9, 0x6d, 0x21, 0xd0, 0xfc, 0x93, 0xb3, 0x96, 0x0f, 0x97, 0xcd, 0x8f, + 0x9b, 0x4a, 0x97, 0x9b, 0x55, 0x7f, 0x09, 0x6d, 0xdb, 0xba, 0x5f, 0x05, 0xd7, 0xbd, 0x52, 0x6f, + 0x14, 0x11, 0xf2, 0x59, 0x3e, 0xb8, 0x4e, 0xf7, 0xd0, 0xdd, 0x7c, 0x10, 0xcd, 0x8c, 0x68, 0x4d, + 0xbf, 0xc5, 0xd6, 0x9d, 0xd3, 0xc7, 0xf3, 0x65, 0xd9, 0xff, 0xbd, 0x6a, 0xb9, 0x4b, 0x5a, 0x84, + 0x7b, 0xee, 0xe1, 0xfe, 0xb1, 0x7c, 0x5d, 0xbb, 0xe9, 0xd3, 0x3f, 0x04, 0x7d, 0x8d, 0xdc, 0xae, + 0x4d, 0xb6, 0xe7, 0xe4, 0xf2, 0xe7, 0x89, 0xda, 0x4b, 0x49, 0xaf, 0x84, 0xf2, 0xef, 0x7a, 0x7e, + 0x11, 0xd6, 0xb9, 0x59, 0x7b, 0xa5, 0xf7, 0xbb, 0xfc, 0xdc, 0xcc, 0x4d, 0xc5, 0xf2, 0xe6, 0x9d, + 0xb0, 0x8f, 0x17, 0x69, 0x0d, 0x6d, 0x34, 0xd3, 0x42, 0xb9, 0x24, 0xff, 0xe0, 0x8c, 0x9a, 0xa1, + 0xf7, 0xcb, 0x9d, 0xff, 0x9b, 0x2c, 0x65, 0xdf, 0x2d, 0x3e, 0xfe, 0x5e, 0xd2, 0x64, 0xee, 0xda, + 0x79, 0xb8, 0x8b, 0xd7, 0x6a, 0xdf, 0x97, 0x5b, 0x4f, 0xab, 0xd7, 0x3d, 0x5d, 0xdd, 0xff, 0xc5, + 0x56, 0x89, 0xd3, 0xa7, 0x27, 0x09, 0xf3, 0xb5, 0x36, 0xeb, 0x5d, 0xd0, 0xdf, 0xf2, 0xd5, 0x3c, + 0xdc, 0x13, 0xdb, 0xbe, 0x78, 0x27, 0x1b, 0x22, 0x38, 0xbd, 0xda, 0x93, 0x3a, 0xe2, 0x2d, 0xbe, + 0xd1, 0x98, 0xd7, 0x2c, 0xb1, 0xc8, 0xc1, 0x39, 0x2f, 0xb6, 0x6e, 0x6f, 0x37, 0x5c, 0xd6, 0xf2, + 0xb1, 0xe2, 0x7a, 0x1b, 0xd1, 0x4b, 0x86, 0xe0, 0x96, 0xa8, 0x6f, 0xbd, 0x17, 0x7c, 0xd4, 0xd5, + 0x3f, 0x82, 0x5a, 0x7b, 0x7c, 0xaf, 0xe9, 0xb8, 0x4a, 0xde, 0xdd, 0x8d, 0xe6, 0xe6, 0xcd, 0xf3, + 0x70, 0x47, 0x3f, 0xef, 0x2f, 0x2d, 0xee, 0xda, 0xe5, 0xa7, 0x7a, 0xe6, 0xc9, 0xb4, 0xbc, 0x4e, + 0xf6, 0xd8, 0xf7, 0x5c, 0x14, 0x5d, 0x5e, 0x4c, 0x26, 0x75, 0xf0, 0x85, 0x6a, 0x9e, 0xa4, 0xef, + 0xdd, 0x72, 0x5a, 0xa7, 0x7c, 0xbd, 0xd5, 0x75, 0xab, 0xe4, 0xc7, 0x57, 0x93, 0x88, 0xea, 0xc6, + 0xb0, 0x7a, 0xef, 0x73, 0xb3, 0xf9, 0x33, 0x7d, 0xf7, 0x43, 0xdc, 0xfc, 0x21, 0xb4, 0x89, 0xb7, + 0x63, 0x7b, 0x69, 0xd4, 0x4f, 0x17, 0xd9, 0x3b, 0x74, 0xfe, 0xba, 0xf8, 0x22, 0xac, 0x9d, 0x8e, + 0x5f, 0x35, 0xf7, 0xf3, 0x5e, 0xff, 0x09, 0xca, 0xd5, 0xb2, 0x3b, 0x1d, 0x70, 0x4f, 0xa1, 0xad, + 0x6f, 0x7f, 0x85, 0x3b, 0x9f, 0x18, 0xf2, 0xd6, 0xe9, 0xcd, 0xf8, 0xa4, 0xe4, 0xa6, 0xf9, 0x38, + 0x29, 0xbb, 0x76, 0x48, 0x64, 0xfd, 0x3b, 0x72, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x30, + 0x18, 0x30, 0x6a, 0xf1, 0xa6, 0x96, 0x5f, 0x68, 0xaf, 0x44, 0xad, 0xec, 0x8f, 0xae, 0xc5, 0x4d, + 0x39, 0x7b, 0x6d, 0xcd, 0xfc, 0x14, 0x5a, 0xbb, 0x53, 0x2a, 0x8c, 0x74, 0xab, 0xc2, 0x91, 0xcf, + 0x31, 0x44, 0xc1, 0x28, 0x5f, 0x91, 0x87, 0x31, 0x2c, 0xab, 0x58, 0xe7, 0xc6, 0x09, 0x24, 0x29, + 0x63, 0x19, 0xd5, 0x5e, 0x78, 0xb5, 0x35, 0x8b, 0xfe, 0x1e, 0x31, 0xb5, 0x6e, 0x4f, 0xbf, 0x29, + 0x0a, 0xce, 0xd1, 0xdc, 0xb6, 0xf2, 0xb3, 0x63, 0xf2, 0xfb, 0xf8, 0x50, 0x8a, 0x30, 0x85, 0x5b, + 0x57, 0xe4, 0xf3, 0xca, 0x6d, 0x65, 0xd5, 0xa8, 0xbe, 0x12, 0x1a, 0xdc, 0x65, 0x77, 0x5b, 0x7e, + 0x4b, 0x6d, 0xd2, 0xf1, 0x82, 0x9c, 0xff, 0xd2, 0x33, 0x0e, 0xc6, 0xcf, 0xcf, 0x9d, 0x58, 0xf3, + 0x81, 0x9f, 0xc1, 0x04, 0xba, 0xee, 0x5c, 0xa9, 0xdb, 0x7c, 0xa9, 0x57, 0xb4, 0xe3, 0xd3, 0x9e, + 0xaf, 0xe0, 0xa7, 0x35, 0xe9, 0x9a, 0x23, 0xde, 0x97, 0x6c, 0x2b, 0x9f, 0x05, 0x87, 0x3b, 0xdb, + 0x16, 0x5e, 0xdb, 0x69, 0xd2, 0x4a, 0x18, 0xf0, 0xf9, 0x2a, 0xa9, 0x3d, 0xa7, 0x76, 0xc7, 0xb0, + 0xcd, 0xd5, 0x72, 0x9d, 0x4b, 0xdb, 0xb9, 0xbf, 0x8c, 0x12, 0xef, 0x92, 0x0f, 0x91, 0xa2, 0xe7, + 0xd4, 0xf5, 0xa7, 0xce, 0xd2, 0x31, 0xe3, 0x44, 0x44, 0x5a, 0x35, 0x8a, 0x74, 0x8c, 0xc5, 0x93, + 0x19, 0x5e, 0xd8, 0x52, 0x3f, 0x46, 0xd7, 0x2e, 0x6f, 0x2a, 0xa7, 0x6f, 0xfc, 0x6f, 0x3b, 0x53, + 0xea, 0xb2, 0x64, 0xf4, 0x66, 0x41, 0x1f, 0xc3, 0x20, 0xba, 0xb6, 0x3e, 0x36, 0x49, 0xe9, 0x3e, + 0x3b, 0xaa, 0x7f, 0x0a, 0x11, 0x32, 0xe4, 0x6b, 0x1f, 0x26, 0x3f, 0xae, 0x39, 0x9e, 0x0d, 0x99, + 0x2e, 0x75, 0xf4, 0x19, 0x7f, 0x82, 0x61, 0x0a, 0xaa, 0xaa, 0xea, 0xe9, 0x56, 0x26, 0x8b, 0x63, + 0xc4, 0x22, 0xbf, 0x11, 0x53, 0xa5, 0x74, 0x4c, 0xdf, 0x04, 0xfd, 0x24, 0xb2, 0x67, 0xc7, 0xd9, + 0x5d, 0x5d, 0x7d, 0x91, 0x56, 0xbe, 0x0b, 0x08, 0x37, 0x7a, 0xfe, 0xa5, 0x21, 0xc3, 0x18, 0xdc, + 0xb1, 0xf0, 0x4a, 0x4a, 0x9f, 0x2a, 0x69, 0xa3, 0x63, 0xb2, 0x3f, 0xc1, 0x00, 0xa6, 0x87, 0x6a, + 0x24, 0x60, 0xf9, 0xa8, 0x92, 0x1b, 0x67, 0x4c, 0xa9, 0x35, 0x36, 0x87, 0xba, 0xaa, 0x2f, 0xe1, + 0x1b, 0xe9, 0x99, 0xa4, 0x6c, 0x2c, 0x72, 0xa8, 0x76, 0x57, 0xf8, 0x7a, 0xd3, 0xe9, 0x24, 0xc9, + 0xb6, 0x6d, 0x21, 0xe3, 0x47, 0xf4, 0xf6, 0x2f, 0xf1, 0x35, 0xa5, 0x33, 0xe7, 0x72, 0x1f, 0x85, + 0x0a, 0xb4, 0x44, 0xe4, 0xbe, 0x8c, 0x62, 0xb6, 0xbb, 0x76, 0xc9, 0x1d, 0x2c, 0x1c, 0x7c, 0x10, + 0x67, 0xc4, 0x9d, 0xcf, 0x32, 0xce, 0x0d, 0xbb, 0x4e, 0xe1, 0xd3, 0xa8, 0xfe, 0xc3, 0xdc, 0xf8, + 0xcc, 0x27, 0x15, 0x7f, 0x0b, 0x13, 0x45, 0x39, 0x06, 0xcd, 0x24, 0x4f, 0xcb, 0x6e, 0xcf, 0xfc, + 0x29, 0x49, 0xcf, 0x8b, 0xf9, 0x23, 0x3f, 0x44, 0x95, 0x5b, 0x77, 0x46, 0x9c, 0x3c, 0x13, 0xd8, + 0xd3, 0x1e, 0xaa, 0x6a, 0x76, 0xcf, 0xaf, 0xf1, 0xa2, 0x6a, 0xb6, 0x40, 0xbe, 0xf8, 0x94, 0xae, + 0x7a, 0x1a, 0xb0, 0xb2, 0xd2, 0x9b, 0x0f, 0xb8, 0x51, 0xe7, 0xff, 0x1a, 0x6e, 0x9b, 0x19, 0x6a, + 0xc8, 0x27, 0x57, 0xcf, 0xf5, 0xbb, 0x4f, 0x2f, 0x48, 0xb0, 0xf9, 0x80, 0x33, 0xee, 0xb8, 0xd3, + 0xff, 0x1a, 0x57, 0x69, 0x9b, 0xd1, 0x8c, 0x6a, 0xe8, 0x56, 0xd5, 0x1e, 0xd2, 0x77, 0x5c, 0x94, + 0x47, 0x3f, 0xe1, 0xe8, 0xe5, 0xf8, 0x3e, 0x46, 0xbd, 0x96, 0xb7, 0xb6, 0x7d, 0xc2, 0x4e, 0xf1, + 0x73, 0xd9, 0xff, 0x8c, 0xbd, 0xaa, 0x2b, 0xaa, 0xca, 0x36, 0xba, 0x37, 0x4d, 0xf2, 0x84, 0x49, + 0x92, 0x70, 0x7f, 0x87, 0xe3, 0x1f, 0xde, 0xcd, 0x45, 0xc5, 0x96, 0x69, 0x77, 0x4d, 0xb5, 0x47, + 0x1c, 0x37, 0x29, 0x34, 0x7f, 0x8c, 0x2a, 0x4a, 0xca, 0xe5, 0xc9, 0x3e, 0x3a, 0xb1, 0xa5, 0xbf, + 0xc3, 0x82, 0x87, 0x1c, 0x34, 0x1f, 0x4e, 0xc7, 0xf1, 0xc5, 0xff, 0x1d, 0x6e, 0x89, 0x8f, 0x55, + 0x19, 0xb3, 0x4b, 0xfa, 0x0a, 0x95, 0x95, 0x70, 0xc2, 0xd1, 0x8a, 0xe1, 0x95, 0x89, 0x14, 0x32, + 0xa0, 0x74, 0xd3, 0x26, 0xdb, 0xdb, 0x6f, 0x6f, 0xb6, 0xdd, 0xb1, 0x3a, 0x1d, 0x3c, 0x4a, 0x8e, + 0xfa, 0xe0, 0x94, 0x2c, 0x9a, 0xe9, 0x9f, 0x78, 0xbe, 0x0a, 0x2a, 0xaa, 0xb3, 0xb2, 0x95, 0x19, + 0x44, 0xcd, 0xf1, 0xd7, 0x53, 0xf8, 0x89, 0xd8, 0xc3, 0x23, 0x8f, 0x55, 0xc5, 0x5c, 0xa4, 0xbb, + 0xc9, 0xc1, 0x18, 0xb4, 0x3d, 0xe2, 0x5f, 0x94, 0xcd, 0x34, 0xd3, 0x41, 0x1e, 0x2c, 0x5a, 0xd7, + 0x7b, 0xae, 0x0a, 0x46, 0x5b, 0x2c, 0x38, 0x68, 0x8a, 0xc3, 0xdb, 0x6d, 0x36, 0x5a, 0xf9, 0xca, + 0xa7, 0x84, 0xf0, 0xf9, 0x38, 0x6e, 0xb4, 0xe9, 0x81, 0x6e, 0xae, 0x8d, 0x3a, 0x5f, 0xea, 0xcf, + 0xaf, 0x7c, 0x11, 0xf2, 0x49, 0x1c, 0xaf, 0x82, 0x3a, 0x34, 0x43, 0x58, 0x8d, 0xc2, 0xe0, 0x96, + 0x9e, 0x94, 0xf2, 0x45, 0xcc, 0xae, 0x08, 0xcb, 0x4d, 0xbb, 0x07, 0xd0, 0xd6, 0x51, 0xd4, 0xb2, + 0xe2, 0x7c, 0x42, 0xb9, 0x5c, 0x11, 0x86, 0x25, 0xfb, 0xd7, 0x57, 0x93, 0x98, 0x9b, 0xbf, 0x84, + 0xfb, 0xbb, 0xbb, 0xcb, 0xdc, 0x7e, 0x4f, 0xf8, 0x27, 0x29, 0x1a, 0x92, 0x1e, 0xd2, 0xb5, 0x50, + 0xbf, 0x74, 0xdd, 0x8d, 0x0d, 0xf0, 0x5a, 0x57, 0xda, 0x5a, 0x52, 0x1c, 0x93, 0x84, 0x36, 0x47, + 0x96, 0xba, 0x2e, 0x6c, 0x12, 0x2d, 0x04, 0x71, 0xc9, 0x7a, 0x19, 0xd7, 0xd7, 0xaf, 0x82, 0x4d, + 0x6d, 0x92, 0xf9, 0x87, 0x3e, 0xe1, 0x4e, 0x42, 0xcb, 0xd7, 0x5c, 0xd6, 0x8d, 0x3b, 0x32, 0x71, + 0x3e, 0x4d, 0x1b, 0x5f, 0xbe, 0x84, 0xd5, 0x73, 0x08, 0x56, 0xb5, 0xc5, 0xe4, 0xcf, 0x6d, 0x23, + 0xf4, 0x13, 0xe8, 0xee, 0x60, 0xa5, 0x69, 0x3e, 0x5e, 0x4f, 0x3f, 0x36, 0xef, 0x04, 0x7c, 0x94, + 0x3a, 0xc9, 0xcc, 0x25, 0x55, 0x55, 0xf2, 0x8a, 0xd5, 0x41, 0x6f, 0x09, 0x9f, 0x63, 0x59, 0xf1, + 0xaf, 0xcb, 0x32, 0x06, 0x9b, 0x5f, 0x04, 0xa5, 0x6e, 0xb4, 0xdb, 0x48, 0xdd, 0xdf, 0x30, 0x88, + 0xbd, 0x7c, 0xd5, 0xad, 0x70, 0x56, 0x54, 0x9b, 0xb6, 0x92, 0x49, 0xf6, 0xd3, 0xc1, 0x47, 0xc1, + 0x25, 0xcb, 0xfa, 0x2b, 0x5e, 0x14, 0xa5, 0x7d, 0x54, 0x99, 0x6e, 0x9b, 0x9d, 0x93, 0xbf, 0x57, + 0x2b, 0x8c, 0xa6, 0x7e, 0x5e, 0xf6, 0x11, 0x66, 0x9e, 0xee, 0x96, 0x66, 0x3c, 0x29, 0x69, 0x25, + 0x24, 0x0b, 0x29, 0xcf, 0x03, 0xfa, 0x22, 0x94, 0xfe, 0x12, 0x26, 0xa9, 0x2f, 0x34, 0x54, 0xf8, + 0xe9, 0x52, 0x5e, 0x22, 0xd5, 0x0e, 0x6f, 0xb2, 0x21, 0xa8, 0x5e, 0x09, 0xb5, 0x4e, 0xd9, 0x3e, + 0xef, 0x94, 0x8f, 0x3e, 0x57, 0x11, 0x18, 0x5d, 0xd8, 0x31, 0x46, 0x37, 0xe5, 0xe0, 0x84, 0x68, + 0xfb, 0x45, 0x7d, 0x8e, 0x26, 0x6e, 0xa0, 0xcb, 0x68, 0xc4, 0x09, 0x05, 0x02, 0x25, 0xca, 0xa2, + 0x19, 0xf4, 0x08, 0x3b, 0xdd, 0x3d, 0xc4, 0x09, 0x56, 0x93, 0x8b, 0x98, 0xe4, 0xd0, 0xab, 0x49, + 0xfc, 0xc4, 0xdd, 0xfd, 0x04, 0xf0, 0xf8, 0x23, 0x08, 0x46, 0xf7, 0xfb, 0xe1, 0xab, 0xe8, 0xfb, + 0x79, 0xf7, 0xfc, 0x56, 0xda, 0x73, 0x5f, 0xf1, 0x56, 0x9f, 0x52, 0xdf, 0xe6, 0xbc, 0xb2, 0xf8, + 0xc2, 0xa6, 0xd5, 0xe5, 0xfd, 0xce, 0xfe, 0x8e, 0x6b, 0xf0, 0xef, 0x36, 0x1b, 0x53, 0xee, 0xe9, + 0xf2, 0x33, 0x71, 0x59, 0xa3, 0x9f, 0xff, 0x84, 0x2d, 0xa5, 0xbe, 0xed, 0xa6, 0xff, 0x35, 0x16, + 0x35, 0x97, 0x82, 0x5b, 0x53, 0x6d, 0xaa, 0xcc, 0xdf, 0x06, 0x05, 0x49, 0xe9, 0x36, 0xbc, 0x16, + 0x21, 0xee, 0x2c, 0x20, 0xbf, 0xc1, 0x76, 0x4d, 0x2e, 0x6d, 0xa7, 0x8b, 0x93, 0xe3, 0xab, 0x5a, + 0xe9, 0x55, 0x24, 0xbc, 0x27, 0xcb, 0x89, 0x16, 0x5f, 0xc2, 0x9b, 0x55, 0x6d, 0xa4, 0x92, 0xb5, + 0x55, 0x74, 0xf0, 0x8f, 0x82, 0xcc, 0xfa, 0xf2, 0xe7, 0xc6, 0xbe, 0x4c, 0xc7, 0x1e, 0x08, 0xca, + 0xb5, 0x8b, 0xa7, 0x5e, 0x09, 0x35, 0x7b, 0x1f, 0x10, 0x21, 0x59, 0x64, 0x8a, 0xeb, 0x96, 0x58, + 0x5b, 0xae, 0x82, 0x79, 0x57, 0x20, 0x5a, 0x25, 0xcb, 0x5e, 0x6a, 0x67, 0xcf, 0xc1, 0x1d, 0xf5, + 0x8b, 0xe3, 0x34, 0xaf, 0xbb, 0xb9, 0xf0, 0x57, 0x79, 0xfd, 0xaf, 0x17, 0x5d, 0x53, 0x4f, 0xf0, + 0x8d, 0x49, 0xc9, 0xf6, 0xd5, 0x8d, 0x59, 0xf3, 0xf1, 0x65, 0x54, 0xfa, 0x57, 0xf1, 0x44, 0x9b, + 0x34, 0x93, 0xfc, 0x7e, 0xa9, 0xdd, 0xed, 0x6e, 0xbe, 0x10, 0xbe, 0x6f, 0x55, 0xb2, 0xaf, 0xc2, + 0x72, 0xcb, 0xf2, 0x67, 0xcb, 0x9b, 0x09, 0x9e, 0x26, 0x2a, 0xe7, 0xa3, 0x47, 0x2c, 0x0f, 0x20, + 0x6f, 0xc7, 0x2e, 0x78, 0x22, 0xa4, 0x42, 0x0e, 0xff, 0x11, 0x21, 0x07, 0x5b, 0x4b, 0x5c, 0xd5, + 0xcf, 0x0f, 0x30, 0xf7, 0x7d, 0x44, 0xcc, 0x4b, 0x52, 0x33, 0x88, 0x90, 0x5d, 0x6b, 0xc4, 0x82, + 0x40, 0x87, 0x2e, 0x30, 0xf3, 0x19, 0x5b, 0xfc, 0x94, 0xde, 0xf8, 0x88, 0x29, 0x29, 0x09, 0x56, + 0x2f, 0x77, 0xc7, 0x19, 0x5d, 0xfe, 0x08, 0x6e, 0xfe, 0x1f, 0x64, 0x7a, 0x77, 0xc2, 0x55, 0xa2, + 0x63, 0x63, 0xce, 0xa3, 0xc9, 0x49, 0x24, 0xbe, 0x32, 0xe6, 0x41, 0x8d, 0x18, 0x87, 0x46, 0x46, + 0xb1, 0xa6, 0x8c, 0x6e, 0x5c, 0xd1, 0xa5, 0x09, 0x71, 0x25, 0x47, 0x3b, 0x86, 0xab, 0xb1, 0xff, + 0x84, 0x6c, 0x66, 0x61, 0xb8, 0xda, 0x3c, 0x5b, 0xdf, 0x3d, 0x1d, 0xf1, 0x45, 0x75, 0xa5, 0x56, + 0x99, 0x78, 0x7a, 0x58, 0xe9, 0xa2, 0x4e, 0x24, 0x99, 0x5a, 0x9a, 0x8b, 0x37, 0xb3, 0xf7, 0xd1, + 0xdc, 0x2e, 0x52, 0x66, 0xdf, 0xbe, 0x6c, 0xae, 0x3c, 0xad, 0x35, 0xb5, 0x4b, 0xb4, 0xd7, 0xab, + 0x8f, 0x2c, 0x57, 0xba, 0xe2, 0x86, 0x53, 0xab, 0x7a, 0x5e, 0x8e, 0xe3, 0xcf, 0x5c, 0xba, 0x5d, + 0xf5, 0xc2, 0x46, 0xaa, 0xa9, 0xfd, 0x8b, 0xe2, 0xfa, 0x4b, 0xcd, 0x9e, 0x08, 0xed, 0xac, 0xf2, + 0xf8, 0x2a, 0xe9, 0x97, 0xe2, 0xb2, 0xea, 0x1e, 0xf7, 0x1e, 0x3e, 0xab, 0x5a, 0xad, 0x53, 0xd5, + 0x7c, 0xa7, 0xaa, 0xfc, 0x9b, 0xdf, 0xc1, 0x2d, 0xcf, 0xee, 0x95, 0xd3, 0x7f, 0x8c, 0xa4, 0xaf, + 0xa5, 0x6f, 0x1d, 0x56, 0xfb, 0xbb, 0xf8, 0xe3, 0x6a, 0xa6, 0xcd, 0x56, 0x35, 0x75, 0xe2, 0x42, + 0x93, 0xe0, 0xad, 0x3d, 0x75, 0xa0, 0xdd, 0xbd, 0xef, 0x05, 0x70, 0x4a, 0x76, 0xab, 0xae, 0x8e, + 0xdb, 0x05, 0xca, 0x41, 0x84, 0xc7, 0x4b, 0xe1, 0x4e, 0xda, 0x6f, 0x6a, 0xd9, 0x92, 0x23, 0x6e, + 0xdf, 0x47, 0x87, 0xd4, 0xa5, 0xf7, 0x3b, 0x33, 0xb0, 0x97, 0x97, 0x76, 0x7c, 0x4c, 0x55, 0xb8, + 0xe9, 0xb6, 0xf7, 0xf3, 0x5a, 0x1d, 0x5f, 0xe1, 0x42, 0x39, 0xa8, 0xf6, 0x39, 0xf3, 0xdc, 0x7c, + 0xa6, 0xef, 0xad, 0x7b, 0x89, 0x10, 0x3a, 0x4c, 0x5e, 0xaa, 0x92, 0x42, 0xe9, 0x78, 0x98, 0x82, + 0x8b, 0x88, 0xe2, 0x50, 0x30, 0x7d, 0xc1, 0x8b, 0xc4, 0xbf, 0x3c, 0x13, 0x10, 0xa8, 0x96, 0x18, + 0xc9, 0xff, 0xde, 0xee, 0x5f, 0x08, 0xcc, 0x59, 0x04, 0x9d, 0xce, 0x10, 0xa7, 0x2f, 0x65, 0x13, + 0x3e, 0xb8, 0x99, 0xdb, 0x49, 0xbb, 0x53, 0x45, 0xa7, 0xc4, 0x1e, 0x78, 0xdb, 0x4f, 0x6f, 0xc5, + 0xef, 0x36, 0xdb, 0xaf, 0x88, 0xa9, 0xe3, 0x66, 0xab, 0x2f, 0xfb, 0xed, 0x34, 0xb8, 0x21, 0xd3, + 0xb6, 0xc3, 0xce, 0x56, 0x31, 0xdd, 0x53, 0xfd, 0xf0, 0x5b, 0xdb, 0x4a, 0xd5, 0xa9, 0x7c, 0xd2, + 0x47, 0x52, 0x71, 0x65, 0xc5, 0xea, 0xbf, 0x82, 0x39, 0x33, 0xc1, 0x5c, 0x11, 0x55, 0xbe, 0xbe, + 0x20, 0x51, 0xa9, 0x74, 0x8d, 0x5f, 0x48, 0x9c, 0x25, 0xd5, 0x4e, 0xd6, 0xbf, 0x09, 0x92, 0x4c, + 0xd2, 0xbc, 0x9c, 0x21, 0xc5, 0xea, 0xbe, 0x6c, 0xf9, 0x4f, 0xab, 0x5e, 0x0a, 0x69, 0xc9, 0xdb, + 0x6a, 0x9d, 0x33, 0x7f, 0x05, 0x3e, 0x28, 0xce, 0xee, 0x54, 0xaf, 0x59, 0xf3, 0xf1, 0x93, 0xc1, + 0x72, 0xea, 0x93, 0x12, 0xfb, 0x90, 0x40, 0x67, 0xa6, 0xfc, 0x4c, 0x45, 0x6a, 0xee, 0xef, 0xc4, + 0xcd, 0x77, 0x3b, 0x16, 0xb8, 0xca, 0x49, 0xb6, 0x4f, 0x74, 0xe7, 0xf9, 0x58, 0x5a, 0xd7, 0x13, + 0x65, 0xbd, 0xdf, 0x2e, 0xab, 0xf0, 0x4f, 0xa3, 0x77, 0x6b, 0x57, 0x38, 0x98, 0xa2, 0x13, 0xd8, + 0x3e, 0xef, 0x52, 0x0f, 0xbd, 0x89, 0xb1, 0x7e, 0x61, 0xea, 0xbe, 0x22, 0x09, 0x07, 0x09, 0x48, + 0x29, 0xb8, 0xaf, 0x94, 0xf1, 0x22, 0xb5, 0xa9, 0x6c, 0xb5, 0x28, 0xb5, 0xe0, 0xae, 0xd4, 0x5d, + 0x98, 0x48, 0x11, 0xd3, 0x8c, 0x17, 0x73, 0x7a, 0xf9, 0x3f, 0xe7, 0xd1, 0x5c, 0x2e, 0xb0, 0xc7, + 0xb2, 0x37, 0xb6, 0xb8, 0x4a, 0xc2, 0x69, 0xa2, 0x42, 0x9d, 0xfc, 0x5d, 0x01, 0xb4, 0xcc, 0x74, + 0x69, 0xb5, 0x5b, 0x06, 0xb8, 0x5c, 0xe8, 0xa9, 0xad, 0x13, 0x45, 0x8c, 0x56, 0x45, 0xa3, 0x0a, + 0x97, 0xf9, 0xef, 0x32, 0x4d, 0x33, 0x25, 0xff, 0x7a, 0x69, 0x7d, 0xf2, 0x6f, 0xc1, 0x09, 0x5d, + 0xd5, 0xe2, 0x97, 0x87, 0x3b, 0x4d, 0x75, 0x34, 0x64, 0x8f, 0xe6, 0xe2, 0x09, 0x4e, 0xed, 0x56, + 0xb8, 0x6f, 0xaa, 0x4b, 0x1d, 0xef, 0xeb, 0xac, 0x5f, 0x37, 0x69, 0xa5, 0xca, 0x47, 0x49, 0x0a, + 0xb8, 0x2e, 0xb1, 0x35, 0x6e, 0xf2, 0xff, 0xfc, 0x27, 0xd3, 0x7c, 0x98, 0xab, 0x90, 0xad, 0x52, + 0xf9, 0x0d, 0xab, 0xf1, 0x0e, 0xe5, 0xa2, 0xcf, 0x89, 0xea, 0xb5, 0xaf, 0x97, 0x9b, 0xfc, 0xdd, + 0xdf, 0x11, 0x37, 0x77, 0x51, 0x30, 0x42, 0x50, 0xbe, 0x8c, 0x62, 0x76, 0x3e, 0x52, 0xbb, 0x4d, + 0x57, 0x13, 0x1a, 0x5f, 0xa7, 0x5f, 0x94, 0xef, 0xa1, 0xe2, 0x7e, 0x24, 0x50, 0xc3, 0x31, 0xc5, + 0xe9, 0x5a, 0xf1, 0x34, 0xb2, 0x7a, 0x26, 0xd2, 0x58, 0x90, 0x55, 0x2d, 0x02, 0xac, 0x87, 0xa5, + 0xd6, 0xe7, 0xf4, 0x32, 0xfe, 0xf9, 0x71, 0x10, 0x5e, 0x72, 0x68, 0x5e, 0x26, 0xb8, 0x87, 0x1b, + 0x2a, 0xd2, 0xde, 0xc3, 0xc4, 0x76, 0x9d, 0x1c, 0x77, 0xf9, 0x38, 0x23, 0x11, 0xca, 0xf6, 0x3e, + 0xc5, 0xa4, 0xff, 0x94, 0xc9, 0xe5, 0x67, 0xc5, 0xd0, 0xc8, 0xa4, 0x68, 0xc9, 0xb3, 0xaa, 0x5f, + 0x04, 0x76, 0xa5, 0x42, 0x9c, 0x78, 0x63, 0xbb, 0x56, 0xab, 0x92, 0xab, 0x4f, 0xcb, 0x27, 0xef, + 0x92, 0xe3, 0xeb, 0xfc, 0x41, 0x32, 0xa0, 0xb1, 0x91, 0x8f, 0x24, 0x4d, 0x9c, 0x56, 0xfa, 0xe4, + 0x2a, 0xeb, 0xe2, 0x2d, 0x6d, 0xb1, 0x9d, 0x84, 0x3c, 0x9c, 0xc4, 0x7d, 0xfc, 0x61, 0xa7, 0xef, + 0x62, 0x30, 0x93, 0xe9, 0xdd, 0xdb, 0x27, 0xd1, 0x98, 0xe6, 0x3c, 0x4f, 0xe8, 0xed, 0xe2, 0x42, + 0x97, 0x43, 0xe4, 0xcd, 0xce, 0x91, 0xf1, 0xd1, 0x85, 0xb9, 0xed, 0xe6, 0x3e, 0x09, 0xbb, 0x4d, + 0x63, 0xc6, 0x6f, 0x48, 0x8a, 0xeb, 0x98, 0x46, 0x99, 0xfb, 0xe1, 0x22, 0xe9, 0xb6, 0x8d, 0xe4, + 0x65, 0xf0, 0x48, 0x79, 0x76, 0xd1, 0x68, 0xae, 0x08, 0x69, 0x6f, 0x14, 0x9d, 0x7a, 0x5e, 0x14, + 0xe9, 0x37, 0x4a, 0x5d, 0x6d, 0xdd, 0xcf, 0xb3, 0xf2, 0x97, 0x88, 0x33, 0xb7, 0xa5, 0xb6, 0xb8, + 0x4e, 0xb5, 0x5d, 0x54, 0xbc, 0xb5, 0x4b, 0x5c, 0x13, 0x09, 0xcb, 0x91, 0xda, 0xab, 0x5f, 0x4d, + 0xdc, 0x44, 0x51, 0x8d, 0xc9, 0xd0, 0xd4, 0x2b, 0x6a, 0x2e, 0x9b, 0xdf, 0x82, 0x3a, 0x95, 0x25, + 0x4e, 0x27, 0x0f, 0x0e, 0xf5, 0x1f, 0x88, 0xfc, 0x13, 0x5f, 0x77, 0x84, 0x6c, 0x57, 0x04, 0xd7, + 0x16, 0xb1, 0x97, 0x13, 0x16, 0x2f, 0x23, 0x0a, 0xdd, 0xa4, 0x3f, 0x16, 0x4d, 0x37, 0x5a, 0xdf, + 0x1c, 0x21, 0xdb, 0x69, 0x59, 0xec, 0x7c, 0x39, 0xa1, 0xfd, 0x12, 0xb3, 0xf2, 0x94, 0xda, 0x5e, + 0x4d, 0x8f, 0xc4, 0x5b, 0xa7, 0xcf, 0xbf, 0x04, 0x58, 0x3b, 0x4a, 0x1a, 0x79, 0x8f, 0x12, 0x2c, + 0x97, 0x52, 0x40, 0xf0, 0x4b, 0x3c, 0x3c, 0x11, 0x9e, 0xcc, 0xd9, 0xbf, 0xc5, 0x1a, 0x5f, 0xc9, + 0x0f, 0xc4, 0x10, 0x43, 0x87, 0x48, 0x3a, 0xa7, 0xb0, 0x78, 0xff, 0x0b, 0x9e, 0x26, 0xef, 0x75, + 0x6f, 0xf6, 0x5a, 0xce, 0x1c, 0x5c, 0x75, 0x0c, 0x7a, 0xc7, 0xe5, 0x8d, 0xdf, 0x0c, 0x70, 0x49, + 0x55, 0xaf, 0x4b, 0x88, 0xae, 0x3c, 0xa4, 0xc9, 0x3d, 0x73, 0x79, 0x75, 0x3f, 0xd6, 0x52, 0x71, + 0x04, 0x56, 0xfa, 0x29, 0x7d, 0xd4, 0x4c, 0x41, 0x15, 0x98, 0xf7, 0xe4, 0xef, 0x24, 0xa2, 0x1f, + 0x88, 0xdc, 0x4c, 0x27, 0x07, 0x6e, 0x0f, 0x6c, 0xbb, 0x98, 0x92, 0x35, 0xf1, 0x34, 0x14, 0xdc, + 0x85, 0x8d, 0xeb, 0x3d, 0x52, 0x75, 0x5d, 0x8b, 0x7d, 0x56, 0x24, 0x20, 0x66, 0xfb, 0xd4, 0x4f, + 0x35, 0xcd, 0x9e, 0x0a, 0x6d, 0xae, 0xd5, 0x57, 0x1f, 0x31, 0xb0, 0x5c, 0x96, 0xa9, 0x7d, 0xe7, + 0xf8, 0xae, 0xae, 0x0b, 0xc1, 0x08, 0xb4, 0xad, 0x27, 0x15, 0xf3, 0x5a, 0xdf, 0xc1, 0x25, 0x13, + 0xd7, 0xbe, 0x08, 0x76, 0xad, 0x74, 0x9c, 0x15, 0xc6, 0xea, 0xfe, 0x7d, 0xee, 0xf9, 0x5f, 0x31, + 0x9b, 0x6b, 0x5c, 0x10, 0xee, 0xd5, 0x9f, 0x67, 0x5d, 0x57, 0x30, 0x85, 0xaf, 0xc1, 0x6d, 0xbb, + 0xef, 0x6d, 0xc7, 0xba, 0xb4, 0xaa, 0xf8, 0xaa, 0xb7, 0xd6, 0xdf, 0xad, 0x57, 0x5a, 0x9b, 0x8e, + 0xba, 0xee, 0x5a, 0xb2, 0x81, 0xdd, 0x31, 0x9b, 0x8b, 0x90, 0xf6, 0x98, 0xd8, 0xc4, 0x71, 0x9b, + 0x44, 0xf5, 0x2a, 0x7e, 0xd9, 0xd9, 0x2b, 0x7b, 0x1a, 0xe1, 0x31, 0x1c, 0x9a, 0xda, 0x56, 0xfc, + 0x23, 0xab, 0x56, 0xf5, 0x76, 0xe8, 0x6b, 0x84, 0x8a, 0xda, 0x5d, 0xa5, 0xf8, 0x8e, 0x6c, 0xa6, + 0xdb, 0x1a, 0x5e, 0x59, 0xb5, 0xb3, 0xfc, 0x57, 0x2e, 0xf4, 0xcf, 0xc2, 0x74, 0xd3, 0xf9, 0xde, + 0xb9, 0x76, 0x8b, 0xb9, 0x39, 0x2d, 0xdd, 0x12, 0xe6, 0xbd, 0xe5, 0xe0, 0xab, 0x91, 0x2b, 0x74, + 0xa9, 0x11, 0xae, 0xa6, 0xff, 0x18, 0x45, 0x4b, 0xa6, 0xb3, 0x53, 0xf2, 0xe1, 0x22, 0x61, 0x22, + 0xb2, 0x3f, 0xb2, 0x5c, 0xd1, 0xf3, 0x47, 0xf1, 0xed, 0x2e, 0x16, 0xbe, 0xd1, 0xa6, 0xa6, 0x5f, + 0x5c, 0xb6, 0xbe, 0x4e, 0x23, 0x33, 0x29, 0xd5, 0x3a, 0x1b, 0x18, 0xae, 0x11, 0xee, 0xe9, 0xad, + 0x56, 0xd7, 0xc1, 0x1c, 0xf0, 0xcc, 0xc5, 0x57, 0x0f, 0xd2, 0x3b, 0xfa, 0x6d, 0x24, 0xde, 0xac, + 0xf1, 0xed, 0x7f, 0xcf, 0x8a, 0x3d, 0xaf, 0x5f, 0xc6, 0x76, 0x56, 0x4c, 0xa9, 0x2e, 0x63, 0x34, + 0x57, 0xcb, 0xd7, 0x54, 0xbf, 0x05, 0x77, 0x7a, 0x57, 0x4d, 0xde, 0x2b, 0x6e, 0x3b, 0xe0, 0x9a, + 0xe9, 0xbd, 0x3a, 0xe1, 0x85, 0xc1, 0x1f, 0x55, 0x71, 0xe0, 0x88, 0x4d, 0xef, 0xaf, 0xb1, 0x49, + 0x53, 0x7f, 0x09, 0x5d, 0xbc, 0x61, 0x67, 0x5f, 0x08, 0x55, 0x49, 0xea, 0x5b, 0x77, 0x7f, 0xc2, + 0x43, 0x53, 0x7c, 0xbf, 0xf8, 0x50, 0x54, 0x66, 0xee, 0x8f, 0xc6, 0x31, 0x64, 0x6c, 0xf9, 0xa3, + 0x83, 0xef, 0x59, 0x7c, 0x4f, 0xe0, 0x88, 0x49, 0xf2, 0xb3, 0xe6, 0x91, 0x62, 0x60, 0x94, 0x40, + 0xbb, 0x46, 0x45, 0x34, 0x19, 0xaa, 0xd8, 0xd7, 0xc4, 0x13, 0x52, 0xa1, 0x4c, 0xf9, 0xfd, 0xca, + 0x89, 0x7e, 0x24, 0x41, 0x43, 0x68, 0x46, 0x98, 0xf7, 0x0c, 0x1c, 0x6d, 0x97, 0xfc, 0x12, 0x9f, + 0x3f, 0xa5, 0xa5, 0x73, 0xe6, 0xcb, 0x9f, 0x89, 0xd2, 0x57, 0xa6, 0x4a, 0xfe, 0x08, 0x0c, 0x89, + 0xb6, 0x10, 0xe6, 0x4e, 0x5c, 0xeb, 0xe9, 0x64, 0x80, 0x4a, 0x2f, 0xfe, 0x13, 0xea, 0xf5, 0x7b, + 0x21, 0x9a, 0xfd, 0xb2, 0x47, 0xe1, 0x02, 0xa2, 0x6c, 0x9e, 0xbd, 0xc9, 0x85, 0x85, 0xfb, 0xf1, + 0x86, 0x26, 0xd2, 0x4a, 0x95, 0x26, 0xdd, 0xed, 0x1e, 0x5a, 0xe3, 0x70, 0xeb, 0xbd, 0x32, 0x8f, + 0x8e, 0x0d, 0x1a, 0x33, 0x21, 0xd5, 0x90, 0x7a, 0x0e, 0xbf, 0xa8, 0xea, 0x47, 0x82, 0xfb, 0x4d, + 0x53, 0x1d, 0x18, 0xd9, 0xfa, 0xf8, 0xd6, 0x9f, 0xf1, 0x37, 0x69, 0xb9, 0x0d, 0xb4, 0x8f, 0xe3, + 0x0e, 0xd5, 0xb4, 0x89, 0xfb, 0x97, 0x62, 0x43, 0x4a, 0x5f, 0xf9, 0x6c, 0x69, 0x24, 0x97, 0x85, + 0x2d, 0xe6, 0xca, 0x95, 0xf2, 0x4d, 0xd2, 0x6c, 0x8c, 0xd7, 0xa7, 0x04, 0x9c, 0x49, 0xa6, 0x34, + 0x21, 0x85, 0x62, 0xb9, 0xca, 0x7c, 0x23, 0xd5, 0x51, 0x5b, 0x5c, 0xe2, 0x04, 0xe6, 0xbc, 0xbb, + 0x98, 0x61, 0x73, 0xbc, 0x69, 0xd0, 0xca, 0xd4, 0x3e, 0x33, 0x5f, 0x23, 0x52, 0x23, 0x62, 0x4b, + 0x5d, 0x7d, 0xdd, 0xdf, 0xc5, 0x49, 0xfc, 0x8c, 0xd0, 0xfc, 0x25, 0x19, 0xa5, 0x1a, 0x9a, 0x51, + 0xaa, 0xaf, 0xc1, 0x64, 0x9a, 0x8b, 0xda, 0x6c, 0xbb, 0xab, 0x2f, 0x82, 0xaa, 0x19, 0x3d, 0x0d, + 0xb2, 0xed, 0xce, 0xdf, 0xbb, 0xe1, 0x2d, 0x8c, 0xdf, 0xc7, 0x57, 0xf0, 0x4f, 0x4a, 0x93, 0xb1, + 0x9f, 0xf5, 0xf1, 0x5d, 0xa4, 0xdd, 0x0d, 0x24, 0x5e, 0x0a, 0xa8, 0x74, 0x37, 0x2e, 0xb1, 0xf2, + 0x32, 0x65, 0x5c, 0xbe, 0x10, 0xa6, 0x93, 0xe3, 0x92, 0x4e, 0xdd, 0xfe, 0x13, 0x99, 0x8c, 0x9d, + 0x0c, 0xb1, 0xfc, 0x66, 0xc6, 0x9b, 0x65, 0xc3, 0x36, 0x28, 0xa3, 0x4a, 0xe5, 0xca, 0xe0, 0xd8, + 0xfc, 0x15, 0xd0, 0xc8, 0xcb, 0xd6, 0x5f, 0x46, 0xaa, 0xb7, 0x32, 0x9d, 0xf8, 0xfa, 0xf8, 0x4a, + 0x92, 0x5b, 0x6b, 0x6b, 0xcc, 0x43, 0xb2, 0x6d, 0x63, 0xfc, 0x15, 0x17, 0x75, 0x26, 0x2e, 0xde, + 0x9a, 0x6c, 0xf8, 0x25, 0x26, 0xa9, 0x64, 0x95, 0x87, 0x82, 0x7b, 0xa4, 0xfb, 0xa7, 0x86, 0x3c, + 0x16, 0x6e, 0xee, 0xa9, 0xb7, 0x73, 0xf2, 0xff, 0x0f, 0x82, 0x62, 0xba, 0x4d, 0xa5, 0xdd, 0x26, + 0xbe, 0x08, 0xcc, 0xb5, 0xb3, 0xe0, 0x88, 0x6a, 0xae, 0xff, 0x04, 0x52, 0xfa, 0x7a, 0x5f, 0x8b, + 0x37, 0x36, 0x27, 0xab, 0xe4, 0x35, 0xb2, 0xe7, 0xe2, 0x68, 0x6b, 0xda, 0x4f, 0xe2, 0x84, 0xed, + 0x3a, 0x69, 0xa6, 0x3a, 0xab, 0x96, 0x7c, 0xb4, 0xfe, 0x0a, 0xa9, 0x24, 0x6c, 0xa9, 0xf5, 0xba, + 0x79, 0x71, 0x3f, 0x82, 0x62, 0xb6, 0xfd, 0xc5, 0x6e, 0xe7, 0xc1, 0x16, 0x4c, 0x2d, 0xb6, 0x91, + 0x57, 0x04, 0x26, 0x49, 0x27, 0xbf, 0xc4, 0xcb, 0x36, 0x13, 0x77, 0x12, 0xf7, 0x25, 0x57, 0xd5, + 0xbe, 0x0c, 0x39, 0x70, 0xba, 0x93, 0x6d, 0x56, 0x35, 0xef, 0xfe, 0x13, 0x32, 0xb6, 0x5d, 0xcb, + 0x56, 0x1f, 0xe5, 0xf2, 0x7f, 0x0a, 0xea, 0xd4, 0x98, 0x9a, 0x2e, 0x5f, 0x8e, 0xd4, 0xa3, 0xf0, + 0x49, 0x4e, 0xad, 0x7f, 0xe2, 0x32, 0x25, 0x65, 0xb1, 0xb6, 0xc3, 0x7f, 0x0b, 0x65, 0xc2, 0xc1, + 0xf8, 0x74, 0x95, 0x8d, 0x9b, 0x3c, 0x7f, 0xc6, 0xbf, 0xf8, 0xc2, 0xdb, 0x9b, 0x54, 0x9b, 0x5e, + 0x66, 0x22, 0x72, 0xf6, 0x5d, 0xd7, 0x64, 0xd1, 0x1f, 0x7c, 0x47, 0x4d, 0x22, 0xc8, 0x7a, 0x8f, + 0x73, 0x10, 0x78, 0x8b, 0x0e, 0x2c, 0x48, 0xcf, 0x6b, 0xfc, 0x23, 0x3e, 0x1f, 0xcf, 0xbb, 0xba, + 0xf5, 0xf0, 0xa1, 0x73, 0x65, 0x60, 0x14, 0xda, 0x3d, 0x7e, 0xab, 0xcb, 0xe0, 0xa7, 0xa1, 0x26, + 0x35, 0x5c, 0x8d, 0xca, 0xc2, 0xb2, 0x8d, 0x65, 0x6a, 0xe0, 0x8e, 0xd5, 0x72, 0xf8, 0x48, 0xaf, + 0x23, 0xf7, 0x2b, 0x68, 0xfc, 0x25, 0x93, 0xa7, 0xd8, 0xe7, 0x67, 0xc1, 0x6f, 0x2b, 0x1b, 0x24, + 0xd8, 0xf2, 0xf8, 0x43, 0x2c, 0x76, 0x32, 0xe6, 0x5c, 0x63, 0x91, 0x94, 0xe2, 0xf1, 0x9b, 0xd7, + 0x2b, 0x1a, 0xa4, 0x5d, 0xcf, 0xec, 0xbc, 0x4d, 0xec, 0x68, 0x78, 0xdd, 0xc4, 0x94, 0x1c, 0x7c, + 0x17, 0x6d, 0x34, 0x7d, 0x97, 0x38, 0xbe, 0x28, 0xd7, 0x6e, 0xc6, 0x9b, 0x72, 0x70, 0x98, 0xb5, + 0x4e, 0x2b, 0xd5, 0x7c, 0xc2, 0x13, 0x4a, 0x97, 0x85, 0x29, 0xb1, 0x19, 0x9c, 0xd9, 0xd3, 0x8c, + 0xaf, 0x26, 0x44, 0xa4, 0xf4, 0xb1, 0x0f, 0x04, 0x73, 0x65, 0xda, 0x87, 0x71, 0xe0, 0x96, 0xdb, + 0x24, 0x9e, 0x56, 0x6e, 0xdf, 0x04, 0x36, 0xea, 0x6a, 0xd7, 0x73, 0xe0, 0xb7, 0x9f, 0xdb, 0x44, + 0x7c, 0xe2, 0xf8, 0x44, 0xa6, 0xd3, 0x62, 0xc4, 0xb4, 0x5b, 0x4d, 0x7c, 0x10, 0x88, 0xdb, 0x7e, + 0xf8, 0x22, 0xc5, 0x7f, 0x7c, 0x15, 0x8b, 0x27, 0xcd, 0xd3, 0xe9, 0xbd, 0x26, 0xa7, 0xf8, 0x28, + 0xf3, 0x6c, 0xde, 0xf0, 0x95, 0xc5, 0x53, 0x2f, 0xe2, 0xed, 0xfc, 0x25, 0x11, 0xcd, 0xa5, 0xaf, + 0xc1, 0x67, 0x1c, 0x75, 0x5e, 0x5d, 0xf6, 0x8d, 0x9d, 0xf0, 0x8d, 0x2c, 0xb9, 0x7b, 0xa7, 0xb5, + 0xf0, 0x45, 0xa6, 0x5d, 0x9e, 0xf8, 0x2b, 0x9f, 0xfd, 0xe9, 0x8d, 0xaf, 0x6d, 0xf7, 0xc2, 0x77, + 0xdd, 0xf5, 0xf7, 0x79, 0xf3, 0x89, 0x84, 0xe9, 0x25, 0xda, 0xaf, 0x85, 0x29, 0x5f, 0x5a, 0xe9, + 0xb6, 0xb7, 0xfb, 0xe0, 0xaa, 0xb4, 0x92, 0x76, 0x92, 0x4b, 0x3e, 0x25, 0xdf, 0x05, 0x44, 0x78, + 0xa7, 0xc4, 0xb9, 0x69, 0x61, 0xa4, 0x4c, 0x77, 0xc2, 0x06, 0xa4, 0xf7, 0xc2, 0xbe, 0xfe, 0x6d, + 0x55, 0x7c, 0x4c, 0xcd, 0xbd, 0xa6, 0x95, 0x7c, 0x28, 0x26, 0xad, 0x51, 0x62, 0xea, 0xd3, 0x4d, + 0x5a, 0xb4, 0xcf, 0x84, 0x2d, 0x6d, 0x3d, 0x76, 0xed, 0xf8, 0x2b, 0x31, 0x91, 0xa4, 0xce, 0x68, + 0x33, 0xad, 0x18, 0x4b, 0xbd, 0x28, 0xe0, 0x73, 0x3b, 0xe1, 0x42, 0x9d, 0xf4, 0x54, 0xe9, 0x66, + 0x93, 0x7c, 0x1b, 0x45, 0x4b, 0x9d, 0x3e, 0x0b, 0x36, 0xe9, 0x21, 0xb7, 0x64, 0x87, 0x91, 0x96, + 0x3e, 0x08, 0x8c, 0xf9, 0xa5, 0x97, 0xc5, 0x6d, 0xd5, 0x12, 0xfe, 0xed, 0xd2, 0xf8, 0x2c, 0x2d, + 0x92, 0xe6, 0xd6, 0xf7, 0x62, 0x7b, 0xfc, 0x16, 0x47, 0x39, 0xc4, 0x79, 0x33, 0x97, 0xb5, 0xbf, + 0xc6, 0x1a, 0xe8, 0x9a, 0xb3, 0xbc, 0x23, 0x67, 0x0a, 0xb2, 0x45, 0x5e, 0xd6, 0x6d, 0x99, 0xe3, + 0x0a, 0x68, 0x73, 0xd6, 0xc1, 0xc6, 0x9c, 0x4c, 0x41, 0x4c, 0xaf, 0x2b, 0x4c, 0xb4, 0x8a, 0x8b, + 0xbf, 0xf1, 0xf2, 0x91, 0x34, 0xb7, 0x23, 0x79, 0x72, 0xf7, 0xf2, 0x58, 0xde, 0x45, 0x1e, 0x14, + 0x2a, 0x1b, 0xf3, 0x37, 0x64, 0xd2, 0xc8, 0xd3, 0x6c, 0xc5, 0x97, 0xc5, 0x52, 0xa7, 0xb4, 0x97, + 0xc2, 0x36, 0x3d, 0xed, 0x32, 0x59, 0xd9, 0x4e, 0x8f, 0xcb, 0x49, 0x23, 0xb1, 0xf8, 0x2a, 0xb9, + 0xd9, 0x8f, 0xdc, 0xd2, 0x8c, 0xbd, 0x13, 0xb6, 0x3a, 0xa6, 0xbe, 0x32, 0x97, 0x6e, 0x86, 0xc6, + 0xc4, 0x9e, 0xc3, 0xa4, 0x30, 0x6d, 0x3e, 0xcb, 0x91, 0x41, 0xf8, 0xc8, 0xdd, 0xd7, 0x3e, 0x38, + 0xa6, 0x83, 0x71, 0xb4, 0x7f, 0x6e, 0xb6, 0x46, 0x8b, 0x7f, 0x85, 0x25, 0xfd, 0xf3, 0x62, 0x1a, + 0x61, 0x1b, 0x78, 0xad, 0x37, 0x46, 0xcc, 0x52, 0xab, 0x97, 0xc2, 0x1c, 0x8f, 0x4e, 0xb8, 0xf5, + 0x19, 0xa8, 0x3b, 0x34, 0x43, 0x9e, 0x0a, 0xb1, 0x0b, 0x09, 0xc1, 0xb1, 0x9f, 0x4a, 0xd7, 0xb6, + 0x76, 0x99, 0x9a, 0x3e, 0xf8, 0x53, 0x5a, 0xdb, 0xa5, 0xb4, 0xd5, 0x0c, 0xb6, 0xa6, 0xd3, 0xa7, + 0xc7, 0x52, 0xb6, 0xc6, 0x56, 0xab, 0x77, 0xed, 0xaf, 0x05, 0x76, 0xed, 0xcf, 0xe7, 0x6f, 0x77, + 0x3a, 0x44, 0xf5, 0x4f, 0x37, 0x26, 0xb2, 0xe3, 0xc4, 0xfc, 0x55, 0xa6, 0xbd, 0x57, 0xcd, 0x5d, + 0xcd, 0x13, 0xf9, 0x84, 0x3d, 0xfe, 0x52, 0x3b, 0xbc, 0x4c, 0x44, 0x55, 0xc4, 0x3e, 0x3e, 0x84, + 0xd7, 0x5e, 0x21, 0x5c, 0xf9, 0x77, 0xb8, 0x33, 0xef, 0x7b, 0xac, 0x47, 0xc2, 0x35, 0xbe, 0xf7, + 0x7b, 0xc1, 0x17, 0x17, 0xaa, 0xe4, 0xf5, 0x06, 0xdc, 0x12, 0xc9, 0x9d, 0x57, 0x94, 0x4f, 0x20, + 0xbb, 0xa7, 0x15, 0xd8, 0x85, 0x5c, 0x11, 0x72, 0x5f, 0x4c, 0x7f, 0x04, 0x3d, 0x36, 0x8a, 0x90, + 0x4f, 0xc8, 0x72, 0x67, 0x37, 0x5a, 0x8a, 0xe1, 0x33, 0x3b, 0xef, 0x78, 0x04, 0x8e, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x9a, 0x31, 0x18, 0xb0, 0x22, 0xbc, 0x58, 0x8d, 0x25, 0xdd, 0x3f, 0x0a, 0x95, + 0x32, 0xef, 0x43, 0x23, 0x48, 0xcb, 0xd7, 0x28, 0xaa, 0x0e, 0xf0, 0x83, 0xaa, 0x0e, 0x48, 0xcb, + 0x0f, 0x04, 0x64, 0xcc, 0xc7, 0x0f, 0x8b, 0x12, 0x56, 0x0e, 0xc7, 0xb2, 0x5f, 0x04, 0x66, 0xaa, + 0xdf, 0xe1, 0xdb, 0x68, 0x30, 0x87, 0x6f, 0xe6, 0x62, 0xac, 0x1d, 0xfe, 0x09, 0xbb, 0x91, 0xad, + 0x38, 0x42, 0x1a, 0x7f, 0x88, 0x16, 0xed, 0x47, 0xeb, 0xb2, 0x73, 0xff, 0x08, 0x6d, 0x52, 0x63, + 0x3b, 0x0c, 0x6e, 0x6a, 0x49, 0xdb, 0xf8, 0x54, 0x52, 0x6d, 0x5a, 0x33, 0xa7, 0x4d, 0x53, 0x4c, + 0xdb, 0xff, 0x85, 0x25, 0x66, 0x3c, 0xef, 0x66, 0x83, 0xb2, 0xc5, 0xa5, 0x77, 0x95, 0x45, 0x3b, + 0xe0, 0x52, 0x0b, 0x7c, 0x3d, 0x56, 0x52, 0xaa, 0x94, 0xf8, 0x6d, 0xdd, 0x35, 0xf5, 0x55, 0x5f, + 0x18, 0x76, 0xd9, 0x5c, 0xf9, 0xa9, 0xd2, 0x5d, 0x2a, 0x27, 0x43, 0xf0, 0x40, 0x46, 0xcf, 0xe2, + 0x5e, 0x89, 0x13, 0x71, 0xcb, 0x9d, 0x75, 0xa6, 0x6f, 0xff, 0xa3, 0x99, 0x1d, 0x78, 0x78, 0xd6, + 0xcf, 0x38, 0x90, 0xd9, 0xa7, 0x9e, 0x0f, 0x4b, 0x0f, 0x8a, 0xe4, 0xe9, 0xf8, 0x30, 0x96, 0xad, + 0x88, 0xce, 0xfc, 0x98, 0xc6, 0xff, 0x3d, 0x79, 0x5f, 0x0a, 0x11, 0xd3, 0x4d, 0xa6, 0x44, 0x91, + 0x9f, 0x46, 0xc7, 0xaa, 0x51, 0xc4, 0xd7, 0xbd, 0xaf, 0x9c, 0x32, 0x8e, 0xfd, 0xb6, 0xdb, 0x6f, + 0xd0, 0x83, 0x27, 0xd6, 0xc7, 0xd0, 0x97, 0xae, 0x16, 0x93, 0xff, 0x36, 0x3b, 0xf7, 0x77, 0xf4, + 0x4c, 0xdf, 0x04, 0x95, 0x5f, 0x90, 0xfb, 0x29, 0xbb, 0xf9, 0xbb, 0xff, 0xa2, 0x15, 0x4f, 0xa3, + 0x3f, 0xc1, 0x0d, 0xf3, 0x73, 0xac, 0xf8, 0x74, 0x67, 0x16, 0xed, 0xb4, 0xc3, 0x69, 0xa6, 0xae, + 0x0d, 0x18, 0x4c, 0x8b, 0x2f, 0xf0, 0xec, 0x91, 0xa1, 0xd1, 0xcd, 0x1e, 0x86, 0xcb, 0x1f, 0x8c, + 0xeb, 0x48, 0xb1, 0xac, 0x95, 0xd5, 0xfc, 0x17, 0xec, 0x65, 0xdc, 0x88, 0x07, 0x4e, 0x0c, 0x33, + 0x46, 0xb5, 0xb3, 0x16, 0xd3, 0xcd, 0x5c, 0x5d, 0xbf, 0x0f, 0x64, 0xd6, 0xf8, 0x91, 0x36, 0x89, + 0x65, 0x89, 0xe8, 0xc5, 0xac, 0x65, 0x97, 0xf8, 0xd2, 0xb6, 0x63, 0x96, 0x55, 0xee, 0x4f, 0x37, + 0x63, 0x66, 0x6c, 0x69, 0xb5, 0x97, 0x57, 0x8b, 0x76, 0xfc, 0x3d, 0x43, 0x33, 0x08, 0x6f, 0x7b, + 0x23, 0x5e, 0x8c, 0xcc, 0xc2, 0x18, 0x65, 0xe1, 0x6a, 0xa5, 0x65, 0x02, 0x05, 0x15, 0x66, 0xfe, + 0x08, 0x08, 0x9b, 0x4c, 0x1d, 0x8d, 0x38, 0xe5, 0x84, 0xdb, 0x89, 0x38, 0x67, 0x61, 0xb6, 0x3f, + 0xff, 0xf0, 0x84, 0xec, 0x7b, 0x36, 0x33, 0x6b, 0xdd, 0x3c, 0xe5, 0x21, 0xf1, 0xb6, 0x9c, 0xd9, + 0x06, 0x1b, 0xfb, 0xfc, 0x25, 0xaa, 0xe9, 0x34, 0xaa, 0x68, 0xa8, 0xca, 0xcf, 0xfe, 0x0a, 0x04, + 0xee, 0xd5, 0x21, 0xff, 0x72, 0xf8, 0xd3, 0x17, 0x61, 0x75, 0x45, 0xe7, 0x9a, 0x6d, 0xf8, 0xbe, + 0x9b, 0x6d, 0xa7, 0xe1, 0x72, 0xa2, 0x3c, 0xbd, 0xcf, 0x8a, 0x69, 0x3a, 0x43, 0xb9, 0x52, 0xff, + 0x06, 0x1e, 0x4a, 0x65, 0xa4, 0xb2, 0x5a, 0x8d, 0x85, 0xb7, 0x6f, 0xf8, 0xd9, 0xe9, 0x0e, 0xce, + 0x8d, 0xb3, 0xc2, 0xda, 0x7d, 0x5b, 0x5a, 0x8c, 0x95, 0x41, 0xee, 0xaf, 0xf0, 0x53, 0x39, 0x3f, + 0x09, 0x5b, 0x3c, 0xf1, 0xf8, 0x91, 0x76, 0xcc, 0xd7, 0x7c, 0x79, 0x63, 0x7b, 0x47, 0x0f, 0xb6, + 0xd2, 0xda, 0xf8, 0x74, 0x53, 0x6c, 0x1b, 0x68, 0x65, 0x31, 0xcd, 0x9f, 0x1d, 0x8c, 0x5c, 0x77, + 0xc6, 0xa2, 0x94, 0x3d, 0x31, 0xa3, 0xef, 0xfc, 0x2d, 0xcc, 0xbb, 0x09, 0x83, 0x29, 0xd6, 0x14, + 0xa9, 0x2b, 0x9e, 0xfe, 0xa0, 0x86, 0x82, 0x75, 0xc1, 0x44, 0x17, 0x5d, 0xf6, 0xae, 0xd9, 0x51, + 0x7e, 0xb1, 0x7d, 0x16, 0xff, 0x0e, 0x07, 0x37, 0x49, 0x89, 0xbb, 0x7c, 0xbd, 0x3f, 0xe1, 0x02, + 0xee, 0x9d, 0xde, 0xc3, 0x0e, 0x94, 0x83, 0x3d, 0x69, 0x9f, 0x87, 0x6c, 0x6a, 0x26, 0xc2, 0x85, + 0x52, 0xb3, 0x2a, 0x2e, 0x51, 0xee, 0x6a, 0x4b, 0xe2, 0xff, 0xc2, 0x34, 0xf5, 0x0c, 0xd6, 0xeb, + 0x89, 0x21, 0x7b, 0x7f, 0x1c, 0x54, 0xb6, 0xa6, 0x8a, 0xd2, 0x6d, 0xba, 0x7e, 0x0b, 0xcd, 0x4c, + 0x99, 0xd3, 0xa4, 0xa6, 0xf5, 0xe7, 0xe9, 0xfe, 0x24, 0xf6, 0xdb, 0xc9, 0x89, 0xdf, 0x87, 0xc4, + 0x37, 0xb4, 0xd1, 0xfd, 0x6d, 0x5b, 0x9d, 0x92, 0x30, 0xbf, 0x6d, 0xdb, 0xf0, 0xd6, 0xac, 0x78, + 0x22, 0x3e, 0xb6, 0x65, 0x84, 0xf5, 0xf0, 0x84, 0x8c, 0xd2, 0xd2, 0x2b, 0x98, 0xfb, 0xb7, 0xf0, + 0x50, 0x27, 0x2f, 0x4e, 0xf3, 0x7e, 0xf8, 0xad, 0x24, 0xb2, 0xf6, 0xff, 0x05, 0xa4, 0x43, 0xa4, + 0x49, 0xd3, 0x93, 0xc5, 0xf1, 0xd7, 0xc3, 0x46, 0x66, 0x50, 0xeb, 0x8f, 0xd5, 0x5b, 0xd2, 0x7e, + 0x0a, 0x0a, 0xa6, 0x66, 0xd2, 0x1a, 0x19, 0x59, 0x6e, 0xb9, 0xf0, 0x9d, 0x21, 0xec, 0x99, 0x63, + 0xa7, 0x51, 0xd0, 0xdb, 0xf0, 0xa1, 0x10, 0xf7, 0xb9, 0x61, 0xc7, 0x0d, 0x95, 0x36, 0x8e, 0x6b, + 0x19, 0xa2, 0xc3, 0xf9, 0x41, 0xf5, 0xae, 0x11, 0x08, 0xd8, 0xb2, 0x04, 0x46, 0x32, 0x05, 0xb1, + 0xf7, 0xc2, 0x64, 0x4a, 0x5e, 0xef, 0xbe, 0xad, 0xf0, 0x48, 0x4b, 0x75, 0xc6, 0x57, 0x0c, 0x99, + 0xef, 0x4c, 0x3f, 0xc2, 0xde, 0xf0, 0x58, 0x44, 0xf6, 0xf6, 0x32, 0xb2, 0x9a, 0x4d, 0x96, 0xe7, + 0xc3, 0xc5, 0x45, 0x02, 0x7d, 0xba, 0x5b, 0x6a, 0x50, 0x43, 0x29, 0x9f, 0xf4, 0x0b, 0xfd, 0x91, + 0x1b, 0x2b, 0x4f, 0xc2, 0x57, 0xd1, 0x22, 0xdb, 0x6b, 0xc1, 0x1f, 0x44, 0xec, 0x93, 0x87, 0x4a, + 0xed, 0x6e, 0xf4, 0xd9, 0xb3, 0x46, 0x6c, 0x5a, 0xa4, 0xbf, 0xe1, 0xb2, 0x4c, 0xdd, 0x31, 0x3c, + 0xb5, 0x33, 0xff, 0x1a, 0x25, 0x38, 0xd9, 0xef, 0x76, 0xf4, 0x89, 0xe3, 0xa9, 0xac, 0x29, 0xab, + 0x31, 0xec, 0xbf, 0xc1, 0x79, 0x8f, 0xb0, 0xd9, 0xf3, 0x35, 0x0d, 0x68, 0x66, 0xba, 0x1d, 0x7f, + 0xe0, 0x83, 0x3f, 0x5a, 0xc9, 0x97, 0x6a, 0x93, 0x56, 0x61, 0xbb, 0xff, 0xe1, 0x8f, 0x2f, 0x64, + 0x8b, 0x4d, 0xcc, 0xa2, 0x76, 0x7f, 0xe1, 0xe2, 0xd1, 0xd5, 0x9b, 0xbe, 0xd5, 0x54, 0xf6, 0x2a, + 0xf4, 0xe2, 0xdf, 0xe7, 0xab, 0xbb, 0x7f, 0xf0, 0xe1, 0x25, 0xdf, 0x45, 0xc5, 0x9f, 0xff, 0xe1, + 0xd2, 0x36, 0xbe, 0xab, 0x2c, 0x1b, 0xf5, 0xe0, 0xff, 0xff, 0xc1, 0x40, 0x5e, 0xf7, 0xbd, 0xf4, + 0x9c, 0x20, 0x11, 0x5e, 0xf8, 0x24, 0xea, 0xa8, 0xfa, 0xea, 0xe7, 0xc1, 0x58, 0x68, 0xac, 0x60, + 0xea, 0xe6, 0xde, 0xd3, 0x5d, 0x95, 0xdd, 0x3a, 0xb7, 0xef, 0xb4, 0xd7, 0x8b, 0x13, 0x2c, 0x9a, + 0xa4, 0x6d, 0x6b, 0x6f, 0xc6, 0x5d, 0xb3, 0xfa, 0xae, 0xda, 0x7d, 0xb3, 0xe2, 0xe5, 0x3f, 0x05, + 0x7c, 0xb9, 0xcb, 0xdd, 0x27, 0x3e, 0xfd, 0xf0, 0x44, 0x2a, 0xd1, 0x61, 0xb3, 0xe1, 0xfe, 0x48, + 0xb2, 0x44, 0x7a, 0x51, 0x52, 0xb9, 0x01, 0xc6, 0xbb, 0xff, 0x19, 0xb4, 0x82, 0x3c, 0xe9, 0xa4, + 0xe7, 0x63, 0x7f, 0xb6, 0xdf, 0xe0, 0x88, 0x4d, 0x2b, 0x8b, 0x2f, 0x82, 0x73, 0x39, 0xf1, 0xf7, + 0x69, 0xcf, 0x98, 0x87, 0x85, 0x28, 0xae, 0xee, 0x79, 0x3b, 0xe0, 0x7c, 0xde, 0xc9, 0x33, 0x54, + 0xe0, 0x70, 0xf1, 0xdd, 0x8d, 0xf5, 0xa6, 0x96, 0x97, 0xba, 0x69, 0x15, 0x14, 0x7e, 0x23, 0xcb, + 0x89, 0x74, 0xbc, 0x55, 0x37, 0xa2, 0x2e, 0xc5, 0xf8, 0x52, 0x57, 0xb5, 0x4b, 0xb4, 0x6c, 0x93, + 0x39, 0xa9, 0x79, 0x9f, 0x04, 0x62, 0x65, 0xb3, 0x63, 0xb1, 0xd8, 0xb6, 0x2c, 0x77, 0x1d, 0x7c, + 0x10, 0x91, 0x57, 0xab, 0xe8, 0xac, 0x63, 0xf2, 0x71, 0x8a, 0x07, 0x77, 0xfb, 0x77, 0xc1, 0x15, + 0x57, 0x77, 0xc8, 0x18, 0x57, 0xb5, 0xe0, 0xa8, 0x5d, 0xa2, 0x78, 0xf6, 0xaa, 0x8a, 0x92, 0x45, + 0x6f, 0x82, 0xad, 0x91, 0xe3, 0x67, 0x8c, 0x27, 0xe5, 0xa5, 0xb9, 0x53, 0xea, 0xe3, 0xc2, 0x93, + 0x3e, 0x0d, 0x73, 0xe3, 0x5a, 0x53, 0xc1, 0x26, 0x3b, 0x37, 0xb9, 0xf0, 0x54, 0x6d, 0xa2, 0xb3, + 0x56, 0xac, 0xc7, 0x74, 0xea, 0xee, 0xf8, 0x29, 0x3d, 0x4b, 0x06, 0x4d, 0x12, 0xd4, 0x6f, 0x74, + 0x6c, 0xb3, 0x2b, 0x85, 0x2b, 0x45, 0x26, 0x7e, 0x6e, 0xd3, 0x71, 0x3c, 0x1f, 0x5d, 0x7c, 0x33, + 0x46, 0x4b, 0xa6, 0xad, 0x1b, 0x7f, 0xf0, 0x49, 0xb6, 0xb7, 0x1e, 0x08, 0xba, 0xa5, 0xdf, 0x05, + 0x45, 0x7b, 0xee, 0xd6, 0x78, 0xa7, 0x98, 0xaf, 0x88, 0xd6, 0xb6, 0xd3, 0xae, 0x51, 0x93, 0x36, + 0xaa, 0x11, 0xf8, 0x9a, 0x39, 0x3f, 0x31, 0xb5, 0x51, 0x1d, 0x8d, 0x77, 0xdf, 0x09, 0x0a, 0x7b, + 0x7b, 0xee, 0x7e, 0x2a, 0xd3, 0x5e, 0x7a, 0xc3, 0x3d, 0x1e, 0x17, 0xcd, 0x45, 0x63, 0x23, 0x21, + 0x8e, 0x61, 0x17, 0xb8, 0x8e, 0xef, 0x78, 0x2f, 0xc4, 0x92, 0xa6, 0xa5, 0x4d, 0xc9, 0x77, 0xc1, + 0x6f, 0x37, 0x64, 0xaf, 0x9b, 0x55, 0x9f, 0x12, 0x86, 0xf7, 0x89, 0x28, 0xcd, 0xa3, 0x53, 0x89, + 0xbc, 0x49, 0x37, 0xbf, 0x13, 0x04, 0x1d, 0x7a, 0x11, 0xff, 0x26, 0xb5, 0xc4, 0x7e, 0x09, 0x32, + 0x41, 0x77, 0xf9, 0xae, 0x7c, 0x0a, 0x96, 0x41, 0xd6, 0x5e, 0xe2, 0x06, 0x75, 0x17, 0x55, 0x27, + 0x98, 0x92, 0x6e, 0x37, 0x2d, 0xed, 0xfc, 0x5d, 0xee, 0xef, 0x76, 0xc1, 0x74, 0x47, 0x88, 0x12, + 0x4a, 0xb5, 0x5e, 0x22, 0xa2, 0x21, 0x38, 0x85, 0x88, 0x85, 0x87, 0xcb, 0x4f, 0x93, 0x53, 0x66, + 0xb8, 0x8b, 0x4f, 0xcc, 0xb6, 0xee, 0xfe, 0x0a, 0x6e, 0x28, 0xc5, 0x62, 0x41, 0xe3, 0xeb, 0xdc, + 0x48, 0xe3, 0xfe, 0xe1, 0x71, 0xf7, 0x10, 0xe6, 0x5d, 0xa4, 0xb3, 0x7c, 0x39, 0xc9, 0x55, 0xc9, + 0xc9, 0xbb, 0xcb, 0xcb, 0x2b, 0x12, 0xb1, 0x11, 0x11, 0x04, 0xfc, 0xfe, 0xf3, 0xe0, 0x51, 0x94, + 0xfe, 0x24, 0x5f, 0xcb, 0xb9, 0x30, 0x99, 0xe5, 0x83, 0xde, 0x05, 0x1d, 0x1f, 0x4c, 0xbc, 0xb7, + 0x7f, 0xc6, 0x6a, 0xd2, 0x35, 0x34, 0x52, 0x8a, 0x93, 0xb9, 0x64, 0x54, 0x69, 0x5d, 0xf8, 0xaa, + 0x57, 0xcf, 0xe2, 0x58, 0x78, 0x9d, 0xe2, 0xbb, 0x93, 0xd8, 0x20, 0xe5, 0x2e, 0x92, 0xae, 0xc9, + 0x7b, 0xf9, 0x7a, 0xb6, 0xe2, 0x72, 0x72, 0x6d, 0xdf, 0xcb, 0xab, 0xfc, 0x82, 0x6a, 0xb3, 0xf8, + 0x88, 0x4c, 0x97, 0x14, 0xf8, 0x98, 0xaf, 0xf4, 0x54, 0x57, 0x7c, 0xc6, 0xad, 0x7c, 0x4e, 0xab, + 0xa5, 0x7f, 0x30, 0x95, 0xb3, 0x35, 0xf8, 0xa3, 0x5e, 0xec, 0xa9, 0x33, 0xf1, 0x58, 0x59, 0xa3, + 0xf7, 0xbf, 0x82, 0x6b, 0xfd, 0x89, 0x7a, 0x15, 0x61, 0xec, 0x0b, 0x59, 0xcc, 0x37, 0x01, 0x9e, + 0x62, 0x2d, 0x62, 0x78, 0x8e, 0xab, 0x8a, 0xd4, 0x5f, 0x21, 0xe5, 0x97, 0x88, 0x84, 0x3a, 0x9e, + 0x12, 0x43, 0xcc, 0xf3, 0xff, 0x3d, 0x87, 0xe3, 0xe8, 0x9a, 0xe2, 0x8d, 0x0f, 0x53, 0x36, 0x5f, + 0x59, 0x22, 0x2c, 0xbc, 0x3c, 0x85, 0x7b, 0xbf, 0x8b, 0x20, 0x97, 0x1a, 0xda, 0x69, 0x45, 0xf8, + 0x80, 0x51, 0xcb, 0x6d, 0x56, 0x9f, 0x57, 0x67, 0x3f, 0xe1, 0xfe, 0xf2, 0xcb, 0x5c, 0x92, 0xe5, + 0xdd, 0x62, 0x49, 0x9b, 0x5e, 0x5c, 0x4c, 0xbc, 0x3c, 0x3b, 0xcb, 0x83, 0x2a, 0x27, 0x51, 0x35, + 0x7f, 0x84, 0x88, 0xb5, 0xe5, 0x6c, 0x9d, 0xd6, 0x95, 0x62, 0x47, 0xd3, 0x51, 0x74, 0x38, 0xcb, + 0x6b, 0x1a, 0x5f, 0x0b, 0x95, 0xe2, 0x41, 0x1f, 0x27, 0x0f, 0x8f, 0xe4, 0x5f, 0x08, 0x4b, 0xe0, + 0xcb, 0xca, 0xde, 0xed, 0x8c, 0x34, 0x0d, 0x48, 0xd9, 0x44, 0xff, 0xfb, 0xaa, 0xe1, 0xbe, 0xad, + 0x5c, 0xb5, 0xaf, 0x13, 0x2d, 0x57, 0x5c, 0x41, 0x56, 0xd6, 0xb5, 0x7c, 0x51, 0x63, 0xb4, 0xad, + 0xa5, 0xbe, 0x21, 0xeb, 0x8a, 0x83, 0xb7, 0x9b, 0xd5, 0x8f, 0xf6, 0x66, 0xca, 0xc4, 0x72, 0x9e, + 0x62, 0x2a, 0xfe, 0x5a, 0xaf, 0xe6, 0x29, 0xf3, 0xae, 0x08, 0xb9, 0x69, 0x3a, 0x7c, 0x21, 0x4d, + 0x34, 0x9f, 0x92, 0xec, 0xaf, 0xe0, 0x9a, 0x38, 0x71, 0xc6, 0x99, 0x69, 0xb9, 0x82, 0x03, 0xbf, + 0x9c, 0xf8, 0xe5, 0x26, 0x49, 0xc9, 0xc5, 0x7f, 0x74, 0x9a, 0xd7, 0x04, 0x54, 0x47, 0xce, 0x2f, + 0x88, 0xdd, 0xe3, 0xa7, 0x87, 0xf8, 0x6f, 0x90, 0xb5, 0x49, 0x5f, 0x47, 0xe9, 0x3a, 0x14, 0xd5, + 0xc8, 0x26, 0x5f, 0x4f, 0xd9, 0xb1, 0x5d, 0xc4, 0xc4, 0x77, 0x7d, 0xdf, 0x13, 0xae, 0x2b, 0x72, + 0xfa, 0xc6, 0xe8, 0xcf, 0xa7, 0xe5, 0xdd, 0xeb, 0xbd, 0x92, 0x6d, 0xfc, 0x16, 0x62, 0x2b, 0x9a, + 0xab, 0xf8, 0x4b, 0x7b, 0xf3, 0x62, 0xe2, 0xfb, 0x64, 0x4b, 0x97, 0x53, 0xf2, 0x5b, 0x7a, 0x03, + 0xf0, 0x94, 0x89, 0x34, 0xf5, 0x7b, 0xea, 0xc0, 0x6f, 0x36, 0x5a, 0x5c, 0x2b, 0xc1, 0x51, 0x49, + 0x0e, 0xdb, 0x26, 0xb5, 0xa4, 0xeb, 0xe0, 0x8a, 0x94, 0x56, 0xdb, 0xdf, 0x04, 0xc2, 0x56, 0x5d, + 0xd6, 0x6f, 0x5f, 0x63, 0x1f, 0x7f, 0x1d, 0xbd, 0xa6, 0x9e, 0xda, 0xa7, 0xae, 0x09, 0x06, 0xea, + 0xa9, 0x93, 0xec, 0x55, 0xa5, 0xbe, 0x33, 0xb0, 0x83, 0x0d, 0x70, 0x63, 0x59, 0x2e, 0x95, 0x8a, + 0x79, 0xd8, 0xba, 0x1f, 0x8f, 0x21, 0xd5, 0x0c, 0x0c, 0x1f, 0xcc, 0x18, 0x31, 0x2a, 0x43, 0xe4, + 0x29, 0x3f, 0x89, 0x29, 0x58, 0x32, 0x46, 0xa5, 0xc9, 0xa6, 0x5f, 0xf6, 0x76, 0xf6, 0xc4, 0x70, + 0x4a, 0x22, 0xa5, 0xdd, 0x86, 0x99, 0x12, 0xd6, 0xe3, 0xcd, 0x07, 0xba, 0x04, 0x0b, 0x4e, 0x09, + 0x5a, 0x96, 0xf9, 0xe1, 0x8a, 0xff, 0x57, 0x62, 0x1a, 0x62, 0xb1, 0x9c, 0x9b, 0xed, 0xc9, 0xa4, + 0x50, 0x4e, 0x08, 0xb3, 0xb1, 0x65, 0x94, 0xfc, 0x48, 0x92, 0xb3, 0x43, 0xd6, 0xfe, 0x6a, 0x1a, + 0xa1, 0xd7, 0x27, 0x54, 0x3f, 0x7b, 0x1a, 0x1b, 0x7e, 0x4d, 0x2a, 0x42, 0x78, 0x2d, 0xea, 0x95, + 0x8d, 0x91, 0x21, 0x0a, 0xbb, 0x35, 0xd7, 0xe4, 0xde, 0xfe, 0x52, 0xb7, 0x6f, 0xe4, 0xea, 0xd7, + 0x94, 0xd5, 0xa5, 0xeb, 0xa9, 0xf8, 0x44, 0x5b, 0x4d, 0x36, 0x9e, 0x7c, 0xda, 0xb5, 0xe4, 0xf3, + 0x62, 0xe2, 0x35, 0x59, 0x92, 0xde, 0xf8, 0x2a, 0xb7, 0x3e, 0xd2, 0x8d, 0xad, 0x6e, 0xca, 0x57, + 0x69, 0xb8, 0x29, 0x11, 0x2e, 0x35, 0xde, 0x9a, 0x6f, 0x44, 0xdf, 0x15, 0x63, 0x54, 0x95, 0x93, + 0x1b, 0x4c, 0xbc, 0x7c, 0x86, 0x5b, 0xfa, 0x70, 0xf7, 0x95, 0x65, 0xcf, 0xc4, 0x02, 0xb9, 0x58, + 0x81, 0x5d, 0xac, 0x26, 0x07, 0xee, 0xac, 0xf8, 0xfb, 0x7c, 0x11, 0xcb, 0xd0, 0xda, 0xb2, 0xb8, + 0x27, 0xb2, 0x23, 0x39, 0x90, 0x6d, 0xc1, 0xf1, 0x9b, 0x65, 0x63, 0x65, 0x2d, 0xb2, 0x7b, 0x43, + 0xd8, 0x4d, 0x7f, 0xbb, 0x33, 0x19, 0xa1, 0xae, 0xb9, 0x8b, 0xe1, 0x1a, 0x56, 0x37, 0x23, 0x90, + 0xd0, 0xd1, 0xb2, 0x91, 0xff, 0x09, 0x95, 0xb2, 0x6b, 0x50, 0x74, 0x34, 0x32, 0x3c, 0x4f, 0x1f, + 0xb6, 0x68, 0xe7, 0x62, 0x4d, 0x26, 0x25, 0xb4, 0xdf, 0x82, 0xac, 0xac, 0x46, 0x33, 0x3b, 0xf4, + 0x72, 0xcb, 0x43, 0x38, 0xbe, 0x11, 0xee, 0x86, 0x3b, 0x5f, 0xa1, 0xdb, 0x53, 0x41, 0x77, 0x6e, + 0xf5, 0xc9, 0x7b, 0xcb, 0xd9, 0xaa, 0xb0, 0x8f, 0x2e, 0x8d, 0xdf, 0xcd, 0xb5, 0x17, 0x19, 0xc1, + 0x45, 0xa2, 0x1a, 0x96, 0x43, 0xd9, 0xca, 0xcd, 0x19, 0x92, 0xf9, 0x75, 0x59, 0x38, 0x91, 0x2d, + 0x31, 0xb7, 0x69, 0x36, 0x36, 0x35, 0xc3, 0x94, 0xdb, 0xb3, 0x5d, 0xb1, 0x57, 0xe6, 0xe0, 0x92, + 0x9d, 0xd9, 0x4a, 0xf8, 0x4f, 0x4e, 0x93, 0x4d, 0x7e, 0x09, 0x85, 0x97, 0x83, 0xbf, 0xef, 0x7d, + 0x7c, 0x12, 0x8c, 0x7a, 0x72, 0x77, 0x63, 0x6a, 0x73, 0xe1, 0x42, 0xb1, 0xbd, 0x0d, 0xe7, 0xe4, + 0xd2, 0x6e, 0x5c, 0x73, 0xb5, 0xfd, 0x65, 0x6a, 0xf2, 0x30, 0x4f, 0x8c, 0x3a, 0xeb, 0xbd, 0x24, + 0xa2, 0x93, 0xb9, 0x37, 0xa6, 0x6d, 0xd7, 0xc1, 0x49, 0xa9, 0x5d, 0xb4, 0x8b, 0xa5, 0xb6, 0xf6, + 0xf5, 0xf0, 0xa4, 0xb2, 0xd9, 0x22, 0x9b, 0x75, 0xb6, 0xda, 0x95, 0x2e, 0x16, 0xce, 0x77, 0x2d, + 0xa5, 0x88, 0x78, 0x52, 0x95, 0xa3, 0xe1, 0xa2, 0xdb, 0xd8, 0x56, 0xba, 0x49, 0xe0, 0xe4, 0xdd, + 0x9f, 0x0a, 0x4b, 0xa4, 0xc6, 0xe5, 0x62, 0x3c, 0x9e, 0x26, 0x75, 0x2b, 0x13, 0x7d, 0x60, 0xc6, + 0x5c, 0xe7, 0x27, 0x22, 0x95, 0xe0, 0x98, 0xfb, 0xbf, 0x17, 0xce, 0x3c, 0x16, 0x67, 0xfe, 0xd3, + 0x59, 0xb0, 0x9e, 0x02, 0xd5, 0xe1, 0x43, 0x34, 0xd9, 0x71, 0xd8, 0x6d, 0x4d, 0xdb, 0x1e, 0x92, + 0x4a, 0x4f, 0x27, 0x17, 0xb2, 0x07, 0x85, 0x25, 0xde, 0xda, 0xd6, 0xed, 0xdb, 0x71, 0xd5, 0xbb, + 0x23, 0x9f, 0x0a, 0x75, 0x5b, 0x73, 0xea, 0xc5, 0xaa, 0x37, 0x1b, 0x5e, 0xc4, 0xf9, 0x84, 0xa7, + 0xc1, 0x59, 0x2a, 0xd4, 0xf8, 0x78, 0x2e, 0x5e, 0x92, 0xd2, 0xaf, 0x05, 0x42, 0xdb, 0x2e, 0xac, + 0x49, 0x27, 0x76, 0x8f, 0xb6, 0xe3, 0x9f, 0x05, 0x5b, 0x47, 0xed, 0xd6, 0x8d, 0xb9, 0x39, 0xb9, + 0xfc, 0xa5, 0xef, 0x8f, 0xa6, 0xdc, 0x6d, 0x9f, 0xec, 0xfd, 0x63, 0x9b, 0x7c, 0x29, 0x25, 0x06, + 0x3b, 0x8b, 0x46, 0xba, 0x62, 0xb6, 0xd2, 0xb5, 0x6f, 0x82, 0xdb, 0xea, 0x7e, 0x6e, 0xdb, 0xbb, + 0x7c, 0x11, 0xea, 0xbe, 0xf8, 0x52, 0xd3, 0x4d, 0x34, 0xab, 0xb8, 0x8e, 0x52, 0x4e, 0x91, 0x35, + 0xfe, 0x08, 0xe9, 0x24, 0x73, 0x91, 0x7b, 0xe0, 0xaa, 0xd1, 0xf3, 0x3e, 0x73, 0x63, 0x57, 0x6f, + 0x82, 0x98, 0xc5, 0x6d, 0xcd, 0xa7, 0xd8, 0xda, 0x1e, 0x5f, 0xc5, 0xaf, 0xc1, 0x28, 0xc7, 0x2e, + 0x3d, 0xb3, 0x6a, 0xb0, 0x7c, 0x15, 0x5d, 0xaa, 0x8b, 0x88, 0xe7, 0x1b, 0xab, 0xb1, 0xf0, 0xa1, + 0xc1, 0x7a, 0x4d, 0x6f, 0x5d, 0x92, 0x35, 0x2e, 0xb3, 0xc0, 0xb2, 0xe5, 0xdb, 0x42, 0x4e, 0xb8, + 0x90, 0xa1, 0x33, 0xd5, 0x55, 0x47, 0x15, 0x9f, 0x51, 0xf5, 0x57, 0xc7, 0x69, 0x0e, 0x53, 0x9c, + 0xf8, 0x50, 0xea, 0x7c, 0x67, 0x6e, 0x05, 0x95, 0xf3, 0x6d, 0x56, 0xe6, 0xd7, 0xed, 0xb7, 0x3e, + 0x36, 0x69, 0x1f, 0xbb, 0x69, 0x17, 0x49, 0x06, 0xec, 0x49, 0x9f, 0x11, 0x0f, 0xbe, 0x91, 0x36, + 0x21, 0x48, 0xc1, 0x8d, 0xdf, 0xfc, 0x69, 0x1a, 0x2b, 0x65, 0xd6, 0x45, 0x86, 0xe9, 0x59, 0x71, + 0xb8, 0x88, 0x7e, 0xe3, 0x71, 0xb1, 0x6f, 0xdb, 0xc4, 0x35, 0xf1, 0xa5, 0x50, 0xcd, 0x6c, 0x1d, + 0xd9, 0x1d, 0xfb, 0xda, 0x7c, 0x8e, 0xdc, 0x89, 0xcd, 0x71, 0xb3, 0x1d, 0x9d, 0x76, 0xfb, 0xb0, + 0x87, 0x83, 0x0f, 0xe0, 0xd6, 0xef, 0xc2, 0x82, 0x29, 0x9b, 0xc4, 0x46, 0xa2, 0x84, 0x77, 0xb1, + 0xbe, 0x87, 0x8c, 0x56, 0x7b, 0xf2, 0xf8, 0xc1, 0x25, 0xd6, 0xeb, 0x69, 0x45, 0xdb, 0x27, 0x3f, + 0xbc, 0x5c, 0x9d, 0xbe, 0xff, 0x0a, 0x42, 0x85, 0x5d, 0xaa, 0x95, 0xdd, 0xcf, 0xfe, 0xdd, 0xb3, + 0x48, 0x19, 0xf3, 0x89, 0x55, 0x4c, 0x7c, 0x16, 0x08, 0x93, 0x77, 0x43, 0x66, 0x7a, 0xb5, 0x22, + 0x64, 0x1e, 0xf8, 0x28, 0xa3, 0x25, 0x35, 0xb4, 0xa9, 0x77, 0xc2, 0x96, 0x99, 0xc6, 0xad, 0xa3, + 0xa9, 0x67, 0xf1, 0xb5, 0x89, 0xb3, 0x51, 0x53, 0x75, 0x1d, 0x4f, 0x3e, 0x14, 0xa2, 0x32, 0xce, + 0x34, 0x3f, 0xce, 0xee, 0x99, 0x6d, 0x25, 0x38, 0xa8, 0xfe, 0x3f, 0x5f, 0x09, 0x14, 0xb1, 0x6d, + 0xa8, 0x9e, 0x7f, 0x0a, 0x72, 0x56, 0x3d, 0xb7, 0x41, 0xed, 0x66, 0x9e, 0xa3, 0xfa, 0xf6, 0x46, + 0x38, 0x97, 0x0e, 0x07, 0x7e, 0x1e, 0x8d, 0x9c, 0x5a, 0xca, 0xb5, 0x6b, 0x31, 0xca, 0xd3, 0x8b, + 0x77, 0x14, 0xf8, 0x4c, 0xc5, 0x91, 0x5b, 0x5f, 0x3f, 0xe1, 0x43, 0xb9, 0xef, 0x48, 0xb6, 0xba, + 0x43, 0xe7, 0x6a, 0xae, 0x28, 0x3b, 0x84, 0xe9, 0x3f, 0x4d, 0x1f, 0xd3, 0x15, 0xc4, 0xea, 0xd8, + 0xee, 0xde, 0x3c, 0xc1, 0xfc, 0x69, 0x1f, 0xd0, 0x97, 0x5e, 0x40, 0xad, 0x86, 0xfc, 0xdf, 0x89, + 0x35, 0x65, 0x70, 0x36, 0xbc, 0x3f, 0x51, 0x41, 0xdc, 0x16, 0xa9, 0x36, 0xa4, 0xe9, 0xb7, 0x4d, + 0xff, 0xc2, 0x92, 0xe0, 0xcd, 0x76, 0xef, 0x26, 0x94, 0x52, 0xee, 0x89, 0x32, 0x37, 0x3e, 0xb7, + 0xf8, 0x39, 0x7c, 0x29, 0x48, 0xef, 0x4e, 0x8d, 0xb6, 0x86, 0x6e, 0xaf, 0x4a, 0xa1, 0x0c, 0x56, + 0xfe, 0xf5, 0x2c, 0x61, 0xca, 0x2d, 0xbe, 0x14, 0xd6, 0xba, 0x0e, 0xd1, 0x19, 0x63, 0x35, 0xb5, + 0x12, 0x2a, 0x9d, 0xc6, 0x99, 0x54, 0x7c, 0x29, 0x69, 0x23, 0x9c, 0xd2, 0x3a, 0xc1, 0x2f, 0x4a, + 0xfd, 0x36, 0xdc, 0x49, 0x25, 0x45, 0x6a, 0xc6, 0x1c, 0xc9, 0xce, 0xb9, 0xa5, 0x4f, 0x85, 0x28, + 0x3b, 0xd8, 0x0f, 0xd6, 0xd3, 0xd9, 0x5b, 0x04, 0xc8, 0xd1, 0xa9, 0x49, 0x63, 0x54, 0xaa, 0xab, + 0xd1, 0x6b, 0xe3, 0xe3, 0xb4, 0xdc, 0xf6, 0x39, 0xe5, 0x4d, 0x64, 0x69, 0x73, 0xc2, 0x93, 0x73, + 0xb7, 0x1d, 0x57, 0x30, 0xec, 0x72, 0x85, 0xca, 0x33, 0x5a, 0x5a, 0xc7, 0x35, 0xb1, 0x5a, 0x71, + 0x74, 0xa0, 0xe2, 0x32, 0x2a, 0xf0, 0xa6, 0x7d, 0x51, 0x72, 0x8c, 0x71, 0x5f, 0x91, 0x6a, 0x4d, + 0xb2, 0xba, 0x8d, 0x81, 0x9a, 0xdc, 0x4c, 0x8c, 0xbf, 0x8c, 0xe3, 0x34, 0xae, 0x46, 0x11, 0x57, + 0x91, 0xa4, 0x45, 0x07, 0x51, 0x36, 0x97, 0x8c, 0xa2, 0x3e, 0x19, 0x97, 0xf6, 0x9a, 0xd7, 0x2e, + 0xa7, 0x5a, 0x44, 0xc7, 0xfc, 0x16, 0x16, 0x9a, 0x93, 0xc1, 0xdb, 0xbf, 0x1c, 0x69, 0x93, 0xdf, + 0xe0, 0x9c, 0x89, 0x13, 0xa4, 0x48, 0xaa, 0x6f, 0xd4, 0xdb, 0xb7, 0xf8, 0x50, 0xb0, 0x6d, 0x68, + 0x6f, 0xd5, 0xd5, 0x57, 0x47, 0x2b, 0x03, 0x2b, 0x07, 0x97, 0x97, 0xd4, 0x98, 0xf8, 0x52, 0xa1, + 0x6e, 0x23, 0xfa, 0x74, 0xe3, 0x77, 0x4f, 0x1b, 0x55, 0x2b, 0x5b, 0x37, 0x02, 0xa5, 0xe0, 0xa3, + 0x57, 0x36, 0x35, 0xaa, 0xe7, 0xc1, 0x51, 0x13, 0x4b, 0x71, 0xb5, 0x1b, 0x56, 0xe5, 0x71, 0x1b, + 0xa9, 0x51, 0x53, 0x30, 0xf8, 0xdf, 0x56, 0xc9, 0xd9, 0xac, 0xf5, 0x09, 0x7b, 0xb9, 0x6b, 0x76, + 0x2e, 0x5a, 0xa5, 0xd9, 0xfa, 0xcd, 0xfc, 0x66, 0xdd, 0xde, 0xdb, 0x6d, 0xbd, 0x54, 0xfa, 0xb9, + 0x5b, 0xad, 0xdf, 0x0a, 0x10, 0xdf, 0xdb, 0x68, 0xf8, 0xb3, 0xbb, 0xbb, 0xdf, 0xdf, 0x0e, 0xd9, + 0xee, 0x3e, 0x92, 0xbd, 0xa7, 0x68, 0x57, 0x33, 0x4c, 0xbe, 0x5f, 0xfe, 0x0b, 0x0f, 0x27, 0x6f, + 0xba, 0x9b, 0x55, 0xf5, 0x21, 0x16, 0x2f, 0x05, 0x5b, 0xb5, 0xa4, 0x7f, 0x76, 0xd3, 0x3f, 0x63, + 0xe3, 0x4c, 0x7c, 0xb4, 0x2f, 0x3e, 0xb6, 0x93, 0xdf, 0x59, 0xfc, 0xda, 0x92, 0xcf, 0x18, 0x48, + 0x96, 0x6e, 0xbf, 0xe1, 0x4e, 0x5e, 0x8f, 0x5a, 0xad, 0xf1, 0xdc, 0x93, 0x29, 0xd3, 0xae, 0x7a, + 0x4c, 0x5f, 0x1b, 0x65, 0x64, 0x6d, 0xda, 0x6a, 0xf7, 0xb6, 0x9d, 0x8b, 0xd3, 0x7f, 0xf0, 0x4c, + 0x34, 0x98, 0x34, 0xb2, 0xbd, 0x72, 0xf3, 0x38, 0xf8, 0x47, 0x37, 0x9f, 0xae, 0xf4, 0x9d, 0xfc, + 0x3e, 0x2a, 0x35, 0xcd, 0xaa, 0x5b, 0x75, 0x73, 0x6b, 0x52, 0x54, 0xfe, 0x7e, 0xdf, 0x85, 0x0e, + 0x7e, 0xa9, 0x67, 0x0e, 0x72, 0xeb, 0x6d, 0x1c, 0xd0, 0x2d, 0x5a, 0xb4, 0x9a, 0xa7, 0x3e, 0x0b, + 0x2f, 0x11, 0xf2, 0xe1, 0x71, 0x28, 0xa6, 0x92, 0xf7, 0xc1, 0x5d, 0x4d, 0xb8, 0xad, 0x2b, 0x49, + 0x66, 0xef, 0xf0, 0xa1, 0x4d, 0xb5, 0xcf, 0x86, 0xf7, 0xfd, 0xaa, 0xf2, 0xe2, 0xb7, 0x89, 0x05, + 0x1d, 0x57, 0x2f, 0x15, 0xb7, 0xc2, 0x99, 0x71, 0x62, 0x49, 0x2f, 0x55, 0x88, 0x70, 0x71, 0x5b, + 0xdc, 0xf8, 0x2b, 0x25, 0xbb, 0x6e, 0xef, 0xf5, 0xbb, 0x9b, 0x3d, 0x33, 0xf0, 0x56, 0x7c, 0x56, + 0xae, 0xed, 0x85, 0xeb, 0x4a, 0xad, 0xfe, 0x14, 0x33, 0x59, 0xf2, 0x3f, 0x82, 0x51, 0xb9, 0xfb, + 0x6e, 0xe3, 0xab, 0xe9, 0xcb, 0xe0, 0xac, 0x56, 0x5b, 0xdf, 0x69, 0xef, 0xd7, 0xc2, 0x82, 0x45, + 0xbe, 0x5c, 0x2e, 0xa3, 0x7e, 0xdd, 0x69, 0xd9, 0x73, 0x7e, 0x7c, 0xd7, 0xc6, 0xdb, 0x8a, 0x7c, + 0xfb, 0x64, 0x63, 0x2f, 0xa8, 0x99, 0x51, 0xa5, 0x1f, 0xeb, 0xb3, 0x1f, 0xe3, 0x24, 0x7c, 0x7e, + 0x1e, 0x28, 0x7e, 0x6e, 0xdf, 0xe3, 0x09, 0x2f, 0xeb, 0x55, 0xf0, 0xc4, 0x38, 0xed, 0xca, 0xaa, + 0xcd, 0x87, 0x82, 0xfc, 0x3f, 0x1f, 0x9e, 0x14, 0x25, 0xd9, 0xce, 0x37, 0xa9, 0xeb, 0xb2, 0xa4, + 0xba, 0xbb, 0x5d, 0xdf, 0xe0, 0xb7, 0x1d, 0xf7, 0x8d, 0x62, 0xbe, 0x30, 0xf7, 0x0b, 0xab, 0xda, + 0x17, 0x36, 0xd4, 0x7d, 0x8d, 0x2c, 0xce, 0xbe, 0x14, 0xb7, 0x92, 0x77, 0x53, 0x57, 0xae, 0xb5, + 0x9f, 0x5b, 0xef, 0x87, 0x4d, 0x7b, 0x96, 0xab, 0x37, 0x3f, 0x7e, 0x56, 0x5b, 0x7a, 0xbd, 0xaf, + 0xf0, 0xa1, 0xdb, 0x88, 0x91, 0x56, 0xc9, 0xc8, 0xc6, 0x32, 0xaf, 0xe9, 0x18, 0xf6, 0xa6, 0xd1, + 0x35, 0xd7, 0x5b, 0x86, 0x67, 0xf8, 0x53, 0xc9, 0xcf, 0x28, 0xd3, 0xc6, 0x72, 0x92, 0x5c, 0xdd, + 0xc7, 0x30, 0xc6, 0x19, 0x17, 0xc3, 0xbe, 0x14, 0xa5, 0x65, 0x8d, 0x45, 0x40, 0xd1, 0x8a, 0x56, + 0x63, 0x1b, 0x36, 0x10, 0x85, 0x38, 0x87, 0x6f, 0x3d, 0x33, 0xd0, 0x99, 0x16, 0xd0, 0xf1, 0xf0, + 0xc9, 0x5e, 0x63, 0xe1, 0x4a, 0xec, 0xe3, 0xaa, 0x7c, 0x3e, 0xa7, 0x9c, 0xf6, 0x8b, 0x63, 0x6b, + 0x4d, 0x0e, 0xbe, 0x5d, 0x68, 0xaa, 0x67, 0xe1, 0x49, 0xf0, 0xfa, 0x6c, 0x77, 0x36, 0x2e, 0xb0, + 0x5e, 0xcc, 0x5d, 0x4a, 0x58, 0xca, 0x9e, 0x85, 0x75, 0x62, 0x2d, 0x72, 0x2e, 0x28, 0xe2, 0xb6, + 0x55, 0xe3, 0x74, 0x91, 0xe4, 0xd6, 0x3a, 0xc4, 0xd4, 0x0a, 0x90, 0xa1, 0x0d, 0xf0, 0xcd, 0x59, + 0x3d, 0xcc, 0x41, 0xea, 0xa7, 0x8c, 0x59, 0x29, 0xa8, 0x81, 0x5c, 0xff, 0x0a, 0x15, 0x55, 0xc6, + 0x24, 0xf1, 0x8c, 0xa8, 0xc9, 0x94, 0x74, 0x89, 0xde, 0x92, 0x7c, 0xe3, 0x48, 0x55, 0x18, 0x1f, + 0x0a, 0x56, 0x51, 0x0d, 0x4e, 0x0f, 0x64, 0xae, 0x4a, 0xd7, 0xad, 0x4c, 0x8e, 0xdd, 0x8d, 0xec, + 0xba, 0x2b, 0x2e, 0x36, 0x19, 0xd9, 0xc5, 0xf0, 0xa5, 0x45, 0x76, 0x5d, 0x86, 0x1d, 0x73, 0xe0, + 0x81, 0xc8, 0xe4, 0xae, 0x48, 0xa7, 0x2f, 0xa3, 0x1d, 0xcd, 0x5d, 0x14, 0x5d, 0xe8, 0x3f, 0xac, + 0x23, 0x7c, 0x29, 0xf7, 0x3b, 0x5f, 0xa6, 0xae, 0x71, 0xb9, 0xb3, 0x03, 0x34, 0x9e, 0xd0, 0xdf, + 0x8b, 0x68, 0x4d, 0xc9, 0x55, 0xcf, 0xd1, 0x45, 0xf0, 0xa5, 0xb1, 0x64, 0x15, 0xa6, 0x38, 0x24, + 0x43, 0x49, 0xa1, 0xdf, 0xa8, 0x77, 0x61, 0xc6, 0xb7, 0xa4, 0xb4, 0xcd, 0x8a, 0x57, 0x64, 0x99, + 0x5b, 0xd9, 0x45, 0xcf, 0x8c, 0x33, 0x9b, 0xd4, 0xd2, 0x54, 0x73, 0x37, 0x6e, 0xa3, 0x77, 0x2d, + 0xcc, 0xc1, 0xf8, 0x53, 0xbb, 0x6d, 0xc8, 0xe0, 0xd8, 0xd0, 0xcb, 0x19, 0x59, 0x83, 0x34, 0x58, + 0x91, 0xcc, 0x33, 0xe3, 0xf2, 0x76, 0xd9, 0xb6, 0xae, 0xeb, 0xbf, 0x1a, 0xac, 0xea, 0x5a, 0xdf, + 0x15, 0x18, 0x38, 0x42, 0x7b, 0x33, 0xb2, 0x32, 0x2f, 0x0e, 0xd8, 0xce, 0xa6, 0x90, 0x68, 0x66, + 0x92, 0xc2, 0xf3, 0xc9, 0x74, 0xcb, 0xff, 0xc2, 0x9a, 0x49, 0x11, 0xb9, 0x9b, 0xe8, 0x32, 0xed, + 0x94, 0xa9, 0x49, 0x27, 0xa4, 0x29, 0x7c, 0x15, 0xe7, 0xe9, 0xbb, 0xd7, 0x5b, 0xfd, 0x59, 0xb0, + 0xd8, 0xe7, 0xde, 0xea, 0xbe, 0x33, 0x3f, 0x63, 0xf5, 0xad, 0xb6, 0xb4, 0xe9, 0xae, 0x43, 0x49, + 0xff, 0x12, 0x76, 0xb4, 0xe4, 0xd5, 0x2e, 0xd7, 0xe1, 0x0d, 0xcd, 0x9b, 0x49, 0x9f, 0x73, 0x6c, + 0xdb, 0xf0, 0x4c, 0x4a, 0x9f, 0x37, 0x49, 0xde, 0xdf, 0x05, 0xc2, 0x69, 0xd3, 0x59, 0xbb, 0x73, + 0x7c, 0x83, 0x1d, 0xbf, 0xca, 0x2f, 0x49, 0xdf, 0x20, 0xa2, 0x67, 0xf8, 0x48, 0xa9, 0x52, 0x2e, + 0xba, 0xbd, 0x70, 0x42, 0x2d, 0x75, 0xef, 0x96, 0xed, 0xdf, 0xc6, 0x04, 0x1b, 0x5e, 0xab, 0x9f, + 0xbd, 0x79, 0xbb, 0xc5, 0xe3, 0x3d, 0x45, 0xf2, 0x7c, 0xd4, 0xd8, 0xad, 0x7f, 0x12, 0x7b, 0xa7, + 0xc9, 0xd3, 0xf2, 0x16, 0xdd, 0xbf, 0x05, 0x65, 0xac, 0x9d, 0x28, 0x9d, 0xde, 0x9e, 0xbe, 0x08, + 0x6d, 0x6d, 0x37, 0xd5, 0x30, 0x79, 0x69, 0xd3, 0x7f, 0x09, 0xf6, 0x93, 0xcf, 0x92, 0x7f, 0x36, + 0x90, 0xad, 0xaf, 0x19, 0x6a, 0xd5, 0xbc, 0xbb, 0x4e, 0x99, 0xf3, 0xfe, 0x3b, 0xcb, 0x8d, 0xdd, + 0xdf, 0x8f, 0xaf, 0x8c, 0xd6, 0x4c, 0xa7, 0x9a, 0x4d, 0xb6, 0x4e, 0xe9, 0x4d, 0xb4, 0x94, 0xf9, + 0xe0, 0xac, 0xd3, 0x65, 0x2e, 0x5f, 0x6e, 0xed, 0xf0, 0x51, 0x5d, 0xf6, 0xcd, 0xfb, 0xe3, 0x3c, + 0x99, 0x8d, 0xe8, 0x94, 0x8e, 0x2e, 0xec, 0xed, 0x17, 0x17, 0x08, 0xe3, 0x99, 0x25, 0xcd, 0xc8, + 0x8e, 0xdb, 0x8f, 0x5d, 0x71, 0x42, 0x3c, 0xb2, 0x59, 0x17, 0x5f, 0x1a, 0x59, 0xfb, 0xfd, 0xcd, + 0xa3, 0xde, 0x5a, 0x68, 0x38, 0xf7, 0x32, 0x7b, 0xeb, 0xad, 0xbd, 0x33, 0xfc, 0x6b, 0xbf, 0x1f, + 0x8a, 0xee, 0xf7, 0xe7, 0x4a, 0xcb, 0xc1, 0x3c, 0xb7, 0x6d, 0x15, 0x03, 0x7b, 0x6e, 0xff, 0x09, + 0x7b, 0xed, 0x34, 0xdd, 0xaf, 0x57, 0xfb, 0x9f, 0xd6, 0xdb, 0x7e, 0x0a, 0x4a, 0xdb, 0x58, 0xd3, + 0xe3, 0x2b, 0x48, 0xef, 0x85, 0x2f, 0x8f, 0xe6, 0x93, 0xbf, 0xc2, 0xcd, 0x12, 0xa2, 0xd9, 0x27, + 0xe3, 0x31, 0x51, 0xe7, 0x65, 0x10, 0xcd, 0x51, 0x2b, 0xb9, 0x63, 0x79, 0xd9, 0x84, 0xd3, 0x1f, + 0x82, 0xaf, 0xb7, 0xcc, 0x71, 0xc9, 0x99, 0x64, 0xb3, 0xea, 0x1d, 0x7c, 0x46, 0x5d, 0x4b, 0x92, + 0x33, 0x26, 0xf8, 0xca, 0xfb, 0x19, 0x99, 0x64, 0x99, 0xbd, 0x8c, 0xac, 0x74, 0x69, 0x21, 0xfc, + 0x21, 0x68, 0xfa, 0x94, 0x1c, 0xac, 0xb1, 0x31, 0x72, 0xae, 0x96, 0xc7, 0xe2, 0xe4, 0x6a, 0x75, + 0xe5, 0x82, 0xd5, 0xe0, 0xb2, 0x86, 0x38, 0x9e, 0x46, 0x5a, 0xcb, 0x6d, 0x0c, 0xd5, 0x5d, 0x54, + 0x6c, 0x6d, 0xcb, 0xe1, 0x4e, 0x56, 0x91, 0x78, 0xeb, 0x7e, 0x8f, 0xd5, 0xc7, 0xa4, 0xa5, 0x5e, + 0xc4, 0x1f, 0xaf, 0x82, 0x3d, 0x25, 0xca, 0xb9, 0xa9, 0x97, 0xe2, 0xb8, 0x23, 0xee, 0xe9, 0xd1, + 0x38, 0x99, 0xf3, 0xaa, 0x7a, 0xe2, 0xfb, 0xbb, 0xee, 0x23, 0x92, 0x94, 0x5b, 0xec, 0x9b, 0xb9, + 0xba, 0x10, 0xc0, 0x11, 0xf2, 0x8f, 0xdd, 0xd7, 0x63, 0x9f, 0x75, 0x89, 0x81, 0x0e, 0x23, 0xf2, + 0xdd, 0xf0, 0x09, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x32, 0x19, 0x30, 0x7a, 0x5c, 0x11, + 0x6a, 0x44, 0x50, 0xea, 0x23, 0x90, 0xd5, 0xaa, 0xec, 0xf7, 0x77, 0xf1, 0x33, 0x66, 0x49, 0x4e, + 0xc4, 0xe9, 0x0e, 0xc2, 0xe5, 0x23, 0xee, 0xba, 0xb3, 0xec, 0x2e, 0x2b, 0x15, 0x8a, 0xc5, 0x64, + 0xe0, 0x84, 0xd3, 0x31, 0x63, 0x26, 0x3e, 0x8a, 0xf7, 0xd7, 0x23, 0x3f, 0x46, 0xea, 0xe8, 0xac, + 0xfa, 0x33, 0xc2, 0xbd, 0x1e, 0xbe, 0xea, 0xbf, 0xac, 0x5f, 0x5b, 0xfc, 0x28, 0x14, 0xba, 0x4d, + 0xbe, 0x7e, 0x93, 0x91, 0xb4, 0x6d, 0x69, 0x60, 0x2d, 0x3c, 0x36, 0x56, 0xed, 0xd6, 0xb3, 0x42, + 0x2b, 0x96, 0x1e, 0x0a, 0xe4, 0xcf, 0x4a, 0x9d, 0x93, 0xb2, 0x2a, 0x7c, 0x17, 0x59, 0x5d, 0x94, + 0xda, 0x8b, 0x2d, 0xf0, 0x81, 0x55, 0x27, 0xd4, 0x92, 0x47, 0xc2, 0x30, 0xb5, 0x7c, 0x12, 0x99, + 0xcb, 0x13, 0x36, 0x8d, 0x9d, 0x19, 0x19, 0xd8, 0xf8, 0xb3, 0xbe, 0xd8, 0xed, 0x50, 0x74, 0x6d, + 0xf8, 0x22, 0x10, 0x7c, 0x1b, 0x53, 0xe6, 0xc3, 0xc6, 0x5a, 0xc1, 0xd4, 0x07, 0x54, 0xd3, 0xd7, + 0x63, 0xd2, 0x49, 0xad, 0xe9, 0x25, 0x26, 0x7c, 0x2b, 0x36, 0x13, 0x3b, 0x43, 0x35, 0xb1, 0xaf, + 0xcc, 0xe6, 0x3e, 0xb4, 0xd7, 0xc2, 0x22, 0x6d, 0x4c, 0xc3, 0x4e, 0xd5, 0x6a, 0xfc, 0x45, 0x35, + 0xeb, 0x45, 0xf0, 0x60, 0x47, 0x8a, 0x9c, 0xec, 0x17, 0x1c, 0xdd, 0x66, 0xf2, 0x7f, 0xf1, 0x9a, + 0x57, 0xc7, 0xee, 0x6c, 0xdf, 0x43, 0x81, 0x9b, 0xcc, 0x93, 0xc2, 0x85, 0x6d, 0x33, 0x7c, 0xaf, + 0x52, 0xfe, 0x93, 0x4c, 0x66, 0x3a, 0x46, 0xc9, 0x5f, 0x9d, 0xf0, 0x41, 0x63, 0xa9, 0x98, 0x30, + 0x40, 0x12, 0x85, 0x96, 0x82, 0x05, 0xc5, 0x8f, 0x42, 0xbc, 0xda, 0xba, 0xba, 0xff, 0x82, 0x82, + 0x36, 0x36, 0x54, 0xb0, 0xe2, 0x7b, 0xad, 0x74, 0xc9, 0x99, 0xaa, 0xcf, 0x96, 0x34, 0x78, 0xba, + 0x2f, 0x94, 0x26, 0xb2, 0x7f, 0x9b, 0x8d, 0xf9, 0x5f, 0xb8, 0x92, 0x13, 0x55, 0x5c, 0xe5, 0x57, + 0x77, 0x7f, 0xf3, 0x91, 0x5d, 0xdd, 0xd5, 0x55, 0x7c, 0x12, 0xc8, 0x41, 0x4b, 0x49, 0x27, 0x78, + 0xff, 0x08, 0xd5, 0xad, 0x57, 0xd5, 0x7c, 0x16, 0x69, 0xcb, 0xda, 0x6b, 0x69, 0xdb, 0xa5, 0x5e, + 0x08, 0xe4, 0xff, 0xff, 0x05, 0xa6, 0xe7, 0xdd, 0x56, 0x04, 0x3e, 0x08, 0x6a, 0xbc, 0xeb, 0x3e, + 0x1c, 0x34, 0xb8, 0xc6, 0xa1, 0xc4, 0xa9, 0xe2, 0x75, 0xff, 0x0f, 0x93, 0x33, 0x23, 0x8a, 0xd8, + 0xf0, 0xfc, 0xac, 0x3b, 0xe4, 0x84, 0x94, 0xf8, 0x6c, 0xa5, 0x32, 0x57, 0x1b, 0x6c, 0xb7, 0x14, + 0xa8, 0x4e, 0x30, 0x86, 0x9a, 0x89, 0x73, 0x7f, 0x1a, 0x42, 0x6d, 0x8f, 0x6e, 0x7b, 0x49, 0x11, + 0x63, 0x13, 0xc4, 0x8c, 0xf9, 0x89, 0x4b, 0x53, 0xff, 0x8d, 0x99, 0x97, 0x7f, 0xd9, 0x38, 0xe2, + 0x65, 0x73, 0x82, 0xb7, 0xec, 0x6b, 0xd7, 0x6b, 0xcb, 0x22, 0x6d, 0xbf, 0xff, 0x8a, 0x9a, 0x49, + 0x91, 0x98, 0x4e, 0x43, 0xed, 0xfe, 0x32, 0x58, 0xb3, 0x73, 0x60, 0xcb, 0xb8, 0x87, 0x2d, 0x64, + 0xfe, 0xb7, 0x78, 0xbc, 0x3f, 0x43, 0x5c, 0x73, 0xf0, 0xaa, 0xb3, 0x6c, 0xf1, 0x26, 0xd2, 0xf0, + 0x48, 0xd6, 0xec, 0x53, 0xfe, 0x1e, 0x9e, 0x2c, 0xd0, 0xd0, 0xd6, 0xe5, 0x83, 0x4f, 0x9b, 0xb6, + 0x8e, 0x09, 0x11, 0xfe, 0xdd, 0x4f, 0xf1, 0xa5, 0x4f, 0x57, 0x6d, 0x5b, 0xbd, 0x11, 0xab, 0xc3, + 0x6a, 0x39, 0xfb, 0xb7, 0x37, 0xf1, 0xe4, 0x98, 0xd0, 0xcc, 0x32, 0xe7, 0x1e, 0x08, 0xb8, 0x9f, + 0x4f, 0xc3, 0x22, 0x51, 0xae, 0xf2, 0xee, 0x68, 0x92, 0x87, 0xa1, 0xa8, 0xda, 0x79, 0x8c, 0x8c, + 0xf2, 0x96, 0x9e, 0x08, 0x6d, 0x4d, 0xb8, 0x3e, 0x1c, 0xcd, 0xa9, 0xfd, 0x92, 0xad, 0xb5, 0x57, + 0xf8, 0xb2, 0xb4, 0xf3, 0x7b, 0x32, 0x47, 0xf0, 0x96, 0xda, 0x74, 0x92, 0x73, 0xe7, 0x88, 0x23, + 0x23, 0xc9, 0x3a, 0xc9, 0x16, 0x26, 0x5d, 0x7e, 0x09, 0x88, 0x67, 0xde, 0xc4, 0x3e, 0xa7, 0x10, + 0x6c, 0xb6, 0x11, 0x8e, 0xfa, 0x0b, 0x9a, 0xfa, 0xf7, 0xd5, 0xeb, 0xaa, 0x3a, 0x7c, 0x24, 0x1a, + 0x1e, 0xbb, 0x7b, 0x56, 0xdf, 0xe3, 0xe7, 0xf7, 0xfb, 0x1a, 0x1d, 0xa6, 0xe8, 0x6d, 0xf8, 0x2c, + 0xd2, 0xae, 0x93, 0x72, 0xb2, 0xed, 0x61, 0x9f, 0x17, 0xa7, 0x4e, 0xeb, 0xf1, 0xc2, 0x5b, 0x8d, + 0xb4, 0xcb, 0xec, 0xee, 0x92, 0xfe, 0xaf, 0xf7, 0xb7, 0x6f, 0xc1, 0x50, 0xa4, 0x68, 0xe6, 0x31, + 0x65, 0x65, 0x58, 0xdc, 0xec, 0x23, 0x87, 0xb1, 0xf1, 0x99, 0x62, 0x8e, 0x8a, 0x0d, 0xb1, 0x5e, + 0x06, 0xc6, 0xed, 0x1f, 0xbd, 0x97, 0xf8, 0x9a, 0x26, 0xda, 0xa5, 0xdf, 0xc1, 0x48, 0x9b, 0x4d, + 0x1a, 0x4d, 0x74, 0xc9, 0xf8, 0xc2, 0xa0, 0x3b, 0xe1, 0x13, 0x68, 0x9c, 0xbd, 0xdb, 0x8d, 0xd2, + 0xf2, 0xa4, 0xf1, 0xf7, 0x33, 0x5e, 0xea, 0xba, 0x44, 0x6d, 0x1f, 0xe2, 0xa4, 0xde, 0xe9, 0xba, + 0x5f, 0x2e, 0xda, 0xaf, 0x84, 0xf1, 0x37, 0xda, 0x6b, 0xe0, 0x9a, 0x76, 0x1e, 0x75, 0xbd, 0x37, + 0xb6, 0xc3, 0xc3, 0x76, 0x79, 0x22, 0xc7, 0xcd, 0x44, 0xd1, 0xfc, 0x12, 0x09, 0xcb, 0xec, 0x09, + 0xca, 0x7d, 0xdf, 0xd5, 0xbc, 0x20, 0xee, 0xf6, 0xbd, 0x15, 0xcc, 0x7e, 0x1e, 0xf0, 0x93, 0x40, + 0x77, 0x5e, 0xdb, 0x6d, 0xfc, 0x11, 0x91, 0x55, 0x55, 0x8f, 0xa3, 0xf7, 0xc1, 0x17, 0x55, 0x67, + 0xc5, 0x06, 0xaa, 0x13, 0x3c, 0xb4, 0x96, 0x1f, 0x04, 0x02, 0xc7, 0x32, 0x81, 0xad, 0xaf, 0x69, + 0xc6, 0xae, 0xb9, 0x8c, 0xd0, 0xb6, 0xd2, 0xc9, 0x92, 0xff, 0xc9, 0xb4, 0xec, 0xfc, 0x6e, 0xb4, + 0x4d, 0x1a, 0x53, 0xeb, 0xb9, 0xe5, 0x95, 0xd1, 0x5b, 0x7f, 0x54, 0xf4, 0x2c, 0x1e, 0xab, 0xfc, + 0x3b, 0x7d, 0x75, 0x4d, 0x95, 0x53, 0x43, 0x1e, 0xba, 0xba, 0x62, 0x1a, 0xd2, 0xff, 0x04, 0xc6, + 0x19, 0xf5, 0x6f, 0xba, 0x65, 0xbe, 0xd4, 0x1f, 0x06, 0x07, 0xca, 0xc5, 0x26, 0xe4, 0xd8, 0x31, + 0xc3, 0x22, 0x67, 0xfe, 0x30, 0x93, 0x49, 0x3b, 0xa9, 0x7a, 0xa4, 0x33, 0xa5, 0x2d, 0xbf, 0x1a, + 0x53, 0x33, 0x93, 0x29, 0xcb, 0x24, 0x9d, 0x94, 0xae, 0xed, 0x4e, 0x4f, 0x5c, 0xbd, 0x1f, 0xf8, + 0x29, 0xb7, 0x7c, 0x5d, 0x3a, 0xa4, 0xcf, 0x72, 0x4f, 0x5f, 0x05, 0x56, 0xb3, 0x63, 0xbb, 0xb3, + 0x54, 0xaf, 0x2f, 0x8d, 0xd9, 0x2d, 0x36, 0x49, 0x36, 0x4c, 0xed, 0x5a, 0xbc, 0xbe, 0xa5, 0xb5, + 0xf8, 0x7a, 0xab, 0xa5, 0xdd, 0xa6, 0x98, 0xd0, 0xda, 0x1f, 0x8f, 0xa6, 0x3a, 0x8b, 0xfe, 0x1e, + 0x2b, 0x76, 0xfb, 0x66, 0xf4, 0xad, 0x3e, 0x6a, 0x64, 0xa7, 0xf8, 0x20, 0x23, 0xde, 0x88, 0x9b, + 0x4a, 0x3a, 0x68, 0xf1, 0x5b, 0xf7, 0xff, 0xf8, 0x4c, 0xeb, 0x65, 0xdd, 0x13, 0x49, 0x7c, 0x3b, + 0x1b, 0xe8, 0x77, 0x2e, 0x24, 0x6c, 0x89, 0x2d, 0x2d, 0xed, 0xa3, 0x9e, 0xab, 0x37, 0x6f, 0xc6, + 0x19, 0x6b, 0xad, 0x72, 0x64, 0xde, 0xb4, 0x8b, 0x9e, 0x10, 0x10, 0xd9, 0x75, 0x93, 0xa1, 0xef, + 0x87, 0x24, 0xbe, 0x2c, 0x27, 0xa6, 0xba, 0xaf, 0x9b, 0x77, 0x72, 0x72, 0x86, 0xb5, 0x55, 0xc1, + 0x41, 0xde, 0xe7, 0x62, 0x87, 0x76, 0x3e, 0x52, 0x93, 0x37, 0xf1, 0xe2, 0x46, 0xd7, 0xcf, 0x96, + 0x49, 0xa7, 0x63, 0x48, 0xcd, 0xf0, 0x80, 0xce, 0x5a, 0x43, 0xf5, 0x6f, 0xa5, 0x5f, 0x30, 0xd7, + 0xbf, 0xc6, 0x5d, 0xc9, 0x9d, 0x2a, 0x6a, 0xb4, 0xa2, 0xff, 0x82, 0x62, 0x25, 0xb6, 0x9e, 0xdb, + 0x7c, 0x12, 0xe9, 0xa4, 0x93, 0x75, 0xbd, 0xf0, 0x88, 0x8a, 0xa7, 0xaa, 0x55, 0x68, 0x90, 0x9f, + 0x67, 0xba, 0xd7, 0x04, 0x25, 0xba, 0x5b, 0xfc, 0x15, 0x77, 0x7a, 0xcb, 0xaf, 0x16, 0xe5, 0x76, + 0x3b, 0x2e, 0xfc, 0x58, 0xda, 0x73, 0x63, 0xea, 0x69, 0xf0, 0x80, 0x8b, 0xdd, 0xec, 0xaf, 0x7f, + 0xa0, 0xaf, 0x67, 0xf1, 0x68, 0x8e, 0x62, 0x53, 0x16, 0xa7, 0xd4, 0x9f, 0x31, 0x55, 0x55, 0x49, + 0xc4, 0x84, 0x9d, 0xb9, 0x21, 0xd3, 0x4f, 0xc1, 0x65, 0x27, 0xf4, 0xdb, 0x3f, 0x65, 0xcc, 0x63, + 0xe4, 0xb5, 0xbf, 0x82, 0xe2, 0x6a, 0x7e, 0xa6, 0xab, 0x0f, 0x24, 0x90, 0x66, 0x8a, 0xb9, 0x2f, + 0xaf, 0x98, 0xa8, 0x99, 0x36, 0x8b, 0xca, 0x54, 0xaa, 0x9e, 0x22, 0x8b, 0x2f, 0x87, 0x8c, 0xd1, + 0xb2, 0x92, 0xd3, 0x4d, 0x2a, 0xf2, 0xa9, 0x72, 0xcf, 0xfc, 0x25, 0xa4, 0xd6, 0xdb, 0xb7, 0xe1, + 0x0e, 0xda, 0xe9, 0xba, 0x72, 0x7f, 0x82, 0x9c, 0xf8, 0x8b, 0xcf, 0xec, 0x92, 0x6d, 0x28, 0x0c, + 0xbe, 0xf5, 0x24, 0x3f, 0x16, 0x7c, 0x9b, 0x37, 0xd5, 0x76, 0x31, 0xa7, 0x9e, 0xbe, 0x82, 0x3a, + 0xfa, 0x2f, 0xd3, 0x76, 0x1a, 0x7b, 0xc5, 0x44, 0x89, 0xe2, 0x70, 0x6b, 0x89, 0x09, 0x16, 0x86, + 0xb6, 0xd7, 0xf2, 0xe5, 0x63, 0x05, 0xbc, 0xb5, 0x55, 0x52, 0x72, 0xee, 0xef, 0xe3, 0xaa, 0xb5, + 0x5d, 0xd6, 0x4e, 0x9b, 0xe1, 0x02, 0xe1, 0x9b, 0xb9, 0x7a, 0x17, 0x24, 0x9f, 0x2e, 0xb3, 0xf3, + 0x11, 0x6b, 0xe2, 0x7e, 0x0b, 0xa9, 0xbb, 0xcd, 0x4a, 0x56, 0x7c, 0x4c, 0xc6, 0x32, 0x1f, 0x26, + 0x0c, 0x65, 0xf3, 0x73, 0x04, 0x76, 0x30, 0x9b, 0xe2, 0xe2, 0x41, 0x40, 0xca, 0x47, 0xa3, 0x11, + 0xdf, 0x0b, 0x89, 0x15, 0x6c, 0xbe, 0xe1, 0x0d, 0xf3, 0x08, 0xe0, 0x73, 0x35, 0xc4, 0x86, 0x41, + 0x51, 0xf5, 0x55, 0x55, 0x4f, 0x6d, 0x5f, 0x89, 0x0c, 0x94, 0x82, 0xbb, 0x47, 0x64, 0x33, 0xc1, + 0x19, 0x77, 0x63, 0xc2, 0xb8, 0x4e, 0xf7, 0xd8, 0xee, 0xf9, 0x75, 0x34, 0x27, 0xcd, 0xd5, 0x7c, + 0x41, 0xc9, 0xf5, 0x4b, 0x7f, 0x08, 0x10, 0xb2, 0xfd, 0xb7, 0x49, 0x74, 0xbc, 0x11, 0x6e, 0xd5, + 0xdf, 0x15, 0x9f, 0xa2, 0xd4, 0x90, 0x65, 0xf9, 0x35, 0x8e, 0x7b, 0x11, 0x05, 0x55, 0x40, 0xe9, + 0xd9, 0x46, 0x62, 0x48, 0x1f, 0x8f, 0x7b, 0x1d, 0x87, 0x86, 0xaf, 0x70, 0xdd, 0x34, 0xe2, 0x5c, + 0x6f, 0xff, 0x05, 0x11, 0x7a, 0xde, 0xef, 0x97, 0xdd, 0x23, 0x31, 0xf9, 0x29, 0x2f, 0xe2, 0xec, + 0x77, 0xca, 0xfd, 0xf0, 0x44, 0x2f, 0x55, 0x6f, 0x82, 0x31, 0x39, 0x3d, 0xf8, 0x81, 0x23, 0x06, + 0x6e, 0xd2, 0xce, 0xd5, 0x55, 0x8d, 0x8c, 0x77, 0x25, 0xb5, 0x78, 0x27, 0x33, 0xa4, 0xa5, 0xf7, + 0x77, 0xc7, 0x3e, 0x0a, 0xa1, 0xa6, 0xa9, 0x2c, 0x86, 0x66, 0x1e, 0xe8, 0x18, 0x6a, 0x73, 0xd2, + 0xfb, 0x88, 0x8b, 0xf0, 0xa8, 0xae, 0xef, 0x7c, 0x48, 0x90, 0xe6, 0xc8, 0x66, 0xa9, 0xbe, 0x7f, + 0x4e, 0x6a, 0xc5, 0x5f, 0x08, 0x85, 0x37, 0x06, 0xc3, 0x32, 0x18, 0xe7, 0xd5, 0xca, 0x9c, 0xe5, + 0x69, 0xa3, 0x56, 0x3e, 0x3f, 0x76, 0x1f, 0xa5, 0x45, 0x1f, 0xc7, 0x87, 0x8c, 0x70, 0x10, 0xc0, + 0x04, 0xcb, 0xc2, 0x92, 0x4a, 0xc3, 0x2d, 0x95, 0x81, 0x58, 0xa3, 0xda, 0x21, 0x83, 0xaf, 0x85, + 0x82, 0xd8, 0x3f, 0xc0, 0x43, 0x1e, 0x15, 0x01, 0xd0, 0xb0, 0x74, 0x16, 0x1c, 0x07, 0x0e, 0x00, + 0xe0, 0xec, 0x6d, 0x62, 0x23, 0x08, 0x5c, 0x38, 0x71, 0xd8, 0x4c, 0xa8, 0x87, 0x27, 0x8e, 0x4b, + 0x0d, 0x62, 0x96, 0x06, 0xce, 0x5b, 0x72, 0xd9, 0x61, 0xe0, 0xa2, 0x12, 0xe5, 0xad, 0x39, 0xef, + 0x8b, 0x16, 0x4f, 0xdd, 0xf0, 0x57, 0xad, 0x6b, 0x37, 0x5c, 0xa9, 0xd2, 0xb8, 0x92, 0x96, 0x91, + 0xce, 0x64, 0xa8, 0xea, 0x9b, 0xbe, 0x1b, 0x2b, 0xc9, 0xbc, 0xab, 0x52, 0xd5, 0xb5, 0xaf, 0x82, + 0x8b, 0x24, 0x65, 0xcd, 0xad, 0x36, 0x2b, 0xac, 0x5f, 0x05, 0x65, 0xba, 0x57, 0xb3, 0x75, 0xcb, + 0x0b, 0x9f, 0x58, 0x7f, 0x39, 0x55, 0x5d, 0x1f, 0xfc, 0xf5, 0x5a, 0xb7, 0xfe, 0x42, 0x5b, 0xb5, + 0xe0, 0xa2, 0x92, 0x9a, 0x99, 0xf7, 0x90, 0x00, 0x47, 0xde, 0xc9, 0x92, 0x6b, 0x89, 0x3a, 0x76, + 0xe3, 0xeb, 0xe9, 0xae, 0x7c, 0xe6, 0x5a, 0x12, 0x96, 0x99, 0x7b, 0xfe, 0x10, 0x1d, 0x5b, 0x2a, + 0x69, 0x65, 0x9a, 0x3d, 0xf7, 0xb1, 0x91, 0x9b, 0xf0, 0xf9, 0x54, 0xc8, 0x3b, 0xa0, 0xc3, 0x14, + 0xfa, 0xba, 0xab, 0xad, 0x17, 0xf8, 0x53, 0x85, 0x37, 0x25, 0x58, 0xd0, 0xcb, 0xe6, 0xa4, 0x8c, + 0xcf, 0x23, 0x39, 0x8b, 0xe1, 0x4c, 0x4e, 0x08, 0x37, 0x72, 0x74, 0xe7, 0x3b, 0x1f, 0x4d, 0x2e, + 0xf8, 0x53, 0x1d, 0xcb, 0x7a, 0x57, 0x3b, 0x0d, 0xf1, 0x3b, 0x5e, 0xa6, 0x8d, 0xc8, 0x3e, 0x14, + 0xbb, 0x19, 0xea, 0x76, 0x4d, 0x15, 0x95, 0x25, 0x2b, 0x97, 0xb3, 0xce, 0x68, 0x72, 0x87, 0x82, + 0x52, 0xb9, 0xbe, 0x5e, 0xe9, 0x2f, 0x7c, 0x28, 0x53, 0xe1, 0x1b, 0x1d, 0x57, 0x4e, 0xdc, 0x6d, + 0x62, 0xb5, 0x36, 0x11, 0x3e, 0x09, 0x48, 0x2b, 0x15, 0x9b, 0x7c, 0xb0, 0x3e, 0x0a, 0xb3, 0xe1, + 0x1e, 0x7e, 0x5c, 0x3f, 0x3f, 0x7b, 0xbd, 0x37, 0xf1, 0xa4, 0x24, 0x87, 0x15, 0xde, 0x63, 0x46, + 0x6f, 0x2d, 0x9a, 0x07, 0xf2, 0x5e, 0x3d, 0x43, 0x4e, 0xd8, 0x4b, 0xd6, 0xff, 0xc6, 0x58, 0x33, + 0x9c, 0x27, 0xb7, 0x68, 0x36, 0x35, 0xbd, 0x07, 0xf4, 0x2f, 0xcf, 0x83, 0x98, 0xe5, 0x65, 0x3f, + 0x04, 0xf6, 0x85, 0xc9, 0x93, 0x33, 0x1f, 0x7c, 0x15, 0x1d, 0x66, 0xdb, 0x84, 0xbd, 0x22, 0xfd, + 0x8c, 0xb1, 0xb5, 0x11, 0x51, 0x49, 0xc5, 0xf0, 0xa0, 0x85, 0x6a, 0xa2, 0xe5, 0xc4, 0xe7, 0x6b, + 0x28, 0xa4, 0x4f, 0xc9, 0x3d, 0xfd, 0x60, 0x89, 0xfd, 0xc4, 0xc2, 0x85, 0xd8, 0xfa, 0x88, 0xc2, + 0xa9, 0x07, 0x69, 0x46, 0x33, 0xd4, 0x3e, 0xec, 0x6c, 0xcf, 0x7d, 0xf1, 0xb2, 0x42, 0xa7, 0x35, + 0x06, 0x2c, 0x9a, 0xfa, 0xac, 0xff, 0x6b, 0xe5, 0x55, 0x54, 0xc6, 0x52, 0xed, 0x7d, 0xd6, 0x8f, + 0xc2, 0xf5, 0xad, 0x21, 0x9a, 0xae, 0xa3, 0xff, 0x48, 0x9b, 0xe1, 0x8d, 0x0e, 0xb9, 0x2b, 0x7b, + 0x38, 0xad, 0xae, 0xd8, 0xd4, 0x6c, 0x0b, 0xfc, 0x31, 0x49, 0x27, 0xd2, 0x73, 0xea, 0xb4, 0xd2, + 0x49, 0x25, 0x1e, 0xf9, 0x77, 0xe3, 0x69, 0x52, 0x63, 0x4c, 0x55, 0x97, 0xe3, 0x38, 0xb6, 0x2f, + 0xd1, 0x2c, 0x2d, 0x41, 0x34, 0x7d, 0x63, 0x2f, 0x73, 0x29, 0x17, 0xaf, 0xe1, 0xcd, 0x28, 0x87, + 0x96, 0xa6, 0x4f, 0x37, 0x4f, 0x2f, 0xf0, 0xa1, 0x31, 0x58, 0x61, 0x02, 0xa9, 0x19, 0xe6, 0x1a, + 0xbd, 0x6a, 0x4b, 0xe0, 0xba, 0xe8, 0xd7, 0x4d, 0x7f, 0xa7, 0xc6, 0xee, 0xc5, 0x3c, 0x52, 0x62, + 0x44, 0x02, 0xb9, 0x79, 0x32, 0x76, 0x71, 0x7e, 0x5c, 0xba, 0x79, 0x71, 0x31, 0xa5, 0x07, 0xac, + 0x0a, 0x85, 0x55, 0x2c, 0x8e, 0x12, 0x85, 0x32, 0x98, 0x74, 0xa7, 0x9b, 0x6e, 0x8e, 0xc5, 0x75, + 0x4b, 0x9d, 0x5e, 0x92, 0x57, 0x3e, 0x5b, 0xff, 0x1a, 0x47, 0x40, 0x6a, 0xcb, 0x34, 0xae, 0x96, + 0x52, 0x0b, 0x7c, 0x43, 0x1e, 0xef, 0xf0, 0x91, 0xb1, 0x3a, 0xb9, 0xcc, 0xf1, 0x03, 0x72, 0xa4, + 0x52, 0xbe, 0x81, 0x6b, 0x0c, 0xe1, 0x28, 0x4c, 0x53, 0x41, 0xa5, 0x7c, 0x29, 0x84, 0x9f, 0x4d, + 0x4d, 0xc7, 0x95, 0xaa, 0x66, 0x8f, 0x61, 0xf1, 0xe1, 0x21, 0xf1, 0x99, 0x1f, 0x47, 0xc2, 0x03, + 0x63, 0x4e, 0x17, 0x01, 0xf5, 0x12, 0xb9, 0xe7, 0xe3, 0xe8, 0xfa, 0x9a, 0x40, 0xe1, 0xeb, 0x08, + 0x03, 0x00, 0x55, 0x2d, 0x3b, 0x1a, 0x9f, 0x2c, 0x1b, 0x0a, 0x8e, 0x40, 0xdc, 0x14, 0x89, 0x35, + 0x6b, 0x0c, 0x94, 0xca, 0x5d, 0xe3, 0xa1, 0x52, 0x70, 0x16, 0x40, 0x86, 0x39, 0xfc, 0x5b, 0x3e, + 0x96, 0xb8, 0x7b, 0x01, 0x60, 0x67, 0x38, 0x79, 0x95, 0x0a, 0x8f, 0x32, 0x41, 0xa6, 0xbc, 0x5b, + 0x6d, 0x40, 0x37, 0x3e, 0x0f, 0xa0, 0x70, 0x4c, 0x34, 0x51, 0x6b, 0x63, 0xbe, 0x20, 0xf0, 0x69, + 0xb0, 0x6b, 0xa7, 0x1c, 0xad, 0x24, 0x80, 0x25, 0x01, 0xfe, 0x5f, 0xa2, 0x0c, 0x11, 0x60, 0x67, + 0x21, 0x14, 0x56, 0x84, 0xb8, 0x2d, 0x06, 0xe4, 0x72, 0x44, 0xe5, 0x80, 0x75, 0x26, 0x2b, 0x41, + 0xab, 0x12, 0x95, 0xd1, 0xb3, 0x06, 0x06, 0xf3, 0x6c, 0xf0, 0x6a, 0x85, 0xee, 0x24, 0x6c, 0x40, + 0x1e, 0x54, 0xaa, 0x0b, 0x4b, 0x9d, 0x1a, 0x12, 0x00, 0x01, 0x3a, 0x8c, 0x04, 0x1a, 0x0f, 0x00, + 0x02, 0x78, 0xe4, 0x01, 0x91, 0xe0, 0xc4, 0x31, 0xa5, 0x50, 0x57, 0xad, 0xe3, 0xa6, 0xe4, 0x07, + 0x89, 0x81, 0x55, 0x00, 0x6c, 0x19, 0x60, 0xec, 0x1b, 0x01, 0x26, 0x0d, 0xa6, 0xb2, 0x76, 0xeb, + 0x36, 0x71, 0x23, 0x77, 0x45, 0x24, 0xee, 0x63, 0x7e, 0x51, 0xa8, 0xb9, 0x50, 0x61, 0x32, 0xf4, + 0x4f, 0x72, 0x0c, 0x15, 0xe9, 0x1a, 0x91, 0xfe, 0x49, 0x29, 0x93, 0xef, 0xcb, 0x59, 0x7e, 0x20, + 0x22, 0x37, 0x43, 0x2f, 0x14, 0x13, 0x5a, 0x1c, 0x1b, 0xa1, 0x62, 0xe8, 0x18, 0x70, 0xb8, 0xdd, + 0x05, 0x96, 0xd8, 0xa4, 0x4a, 0x96, 0x03, 0x96, 0x65, 0x92, 0x86, 0xc2, 0xf8, 0x81, 0xfb, 0x11, + 0x9f, 0xd1, 0xc5, 0x5e, 0x22, 0x36, 0x56, 0x4b, 0xb3, 0x85, 0xe8, 0x49, 0xb6, 0x57, 0x2d, 0x61, + 0x55, 0x09, 0x2e, 0xc6, 0x14, 0x04, 0x92, 0x74, 0x57, 0x21, 0x64, 0xf4, 0x0b, 0x28, 0x34, 0xa0, + 0x4b, 0x47, 0x22, 0x83, 0xc5, 0x34, 0xc7, 0xd1, 0x3f, 0x1a, 0x7a, 0x4a, 0x59, 0x66, 0x64, 0x66, + 0xfc, 0xac, 0x68, 0xa3, 0x93, 0xb5, 0xaf, 0x29, 0x52, 0x18, 0xca, 0x8b, 0xff, 0x0e, 0xcf, 0x06, + 0x3a, 0xa9, 0xbd, 0x13, 0x18, 0xc6, 0x6b, 0xa9, 0x09, 0xef, 0x9c, 0x89, 0x91, 0x0f, 0xf8, 0x7e, + 0x9b, 0x43, 0xdf, 0x76, 0x3b, 0x59, 0x67, 0x6a, 0xdc, 0x92, 0x6b, 0x0f, 0x3f, 0xca, 0x98, 0x67, + 0xb3, 0x7a, 0x28, 0x5f, 0xe3, 0x69, 0xa5, 0xdc, 0xf0, 0xb9, 0xe7, 0x8e, 0x6b, 0x09, 0xf7, 0x38, + 0xe7, 0x1e, 0x2a, 0x95, 0xd5, 0xff, 0x0f, 0x16, 0x13, 0x44, 0xdd, 0xf1, 0x9c, 0x3a, 0xbc, 0xc8, + 0xcd, 0xaa, 0x8c, 0x72, 0xff, 0xe3, 0x48, 0x4c, 0x2c, 0xbb, 0x7a, 0xe4, 0x6d, 0x25, 0x68, 0x38, + 0xad, 0xaa, 0xae, 0x09, 0x94, 0x9e, 0x0f, 0xa7, 0x64, 0xeb, 0xe3, 0x4b, 0x4a, 0x91, 0xbe, 0xb5, + 0x27, 0xd9, 0x4c, 0x61, 0x4d, 0xbd, 0x5e, 0x88, 0xca, 0xff, 0xc2, 0x9d, 0x21, 0xb5, 0x2b, 0x2b, + 0x6f, 0xcd, 0x7e, 0xad, 0x16, 0x2e, 0x8e, 0xf8, 0x7c, 0x14, 0xf4, 0xe4, 0x92, 0xe6, 0x97, 0x72, + 0xac, 0xf8, 0x7a, 0xd3, 0x4d, 0x13, 0x68, 0xe3, 0x56, 0x2c, 0x69, 0x90, 0x3b, 0x1a, 0x7a, 0x22, + 0x17, 0xb6, 0xcd, 0x53, 0xf1, 0x91, 0xf5, 0xdd, 0x98, 0xda, 0xee, 0xbe, 0x9d, 0x33, 0xca, 0x2f, + 0x05, 0x39, 0x4a, 0xb4, 0x94, 0xfa, 0x92, 0x5f, 0x7c, 0x3d, 0xee, 0xea, 0x9e, 0xc9, 0x6d, 0x2b, + 0x69, 0x8d, 0x73, 0xff, 0xf8, 0x50, 0xad, 0xed, 0x2a, 0xe5, 0x6a, 0xca, 0x9d, 0x91, 0x5b, 0x75, + 0x20, 0x3e, 0x15, 0xac, 0xbd, 0xad, 0xdd, 0x4f, 0xcd, 0x44, 0x75, 0x9a, 0xa5, 0xe4, 0xa4, 0xf8, + 0x63, 0x4e, 0x6d, 0xb7, 0x6d, 0x60, 0xed, 0xde, 0x3f, 0xf3, 0x57, 0x7f, 0x0b, 0xe9, 0x3d, 0xcb, + 0x2a, 0x24, 0xb2, 0xa5, 0xd3, 0x25, 0x7f, 0xc1, 0x28, 0xa9, 0xa9, 0xe7, 0xbe, 0x2f, 0x82, 0x61, + 0x3a, 0xbd, 0xd2, 0x4b, 0xab, 0x82, 0x51, 0xcf, 0xba, 0x4d, 0xf2, 0xf8, 0xd3, 0xa5, 0x05, 0x48, + 0xca, 0x25, 0xca, 0xb2, 0xc3, 0x4c, 0x78, 0xfc, 0x75, 0x35, 0xd9, 0x45, 0xab, 0x1b, 0xb1, 0xba, + 0x1b, 0x24, 0x33, 0x43, 0xc1, 0x39, 0x1b, 0x27, 0x6f, 0xad, 0x8e, 0x5f, 0x04, 0x3e, 0x66, 0x37, + 0xf8, 0x29, 0xe9, 0xa5, 0xb6, 0xf2, 0x6f, 0xbf, 0xc1, 0x56, 0xaf, 0xcd, 0xd7, 0x2e, 0x70, 0xf8, + 0x52, 0xd5, 0x32, 0x75, 0x59, 0xd5, 0x56, 0xd5, 0x4a, 0x0f, 0x8f, 0x3d, 0x7a, 0xb6, 0xcf, 0xb4, + 0xd2, 0xfc, 0x16, 0xe7, 0xdd, 0xef, 0x77, 0xc6, 0x9a, 0x31, 0x5c, 0x56, 0xe8, 0xa1, 0x1b, 0xe9, + 0xb6, 0x9a, 0x1f, 0x48, 0xf5, 0x83, 0x55, 0x27, 0x53, 0x4d, 0x32, 0x7f, 0xf0, 0xa5, 0x23, 0x1c, + 0x42, 0xc7, 0x69, 0x8a, 0x4e, 0x31, 0x67, 0x47, 0xc6, 0xe0, 0x53, 0xfd, 0x3c, 0x81, 0xa8, 0x3d, + 0x81, 0x7f, 0xdd, 0x37, 0x32, 0xfe, 0x14, 0xbf, 0x7f, 0xa4, 0xd5, 0x2a, 0x52, 0x7a, 0x7b, 0x1f, + 0x27, 0x49, 0xfc, 0x20, 0x76, 0xe7, 0xc6, 0x33, 0xfa, 0xcf, 0xf5, 0x5f, 0x13, 0x1a, 0x44, 0x38, + 0x72, 0xb0, 0xb7, 0x37, 0xb6, 0x2a, 0x89, 0x32, 0xa2, 0xa0, 0xb5, 0x2a, 0x3e, 0x7e, 0x73, 0x8b, + 0xff, 0x10, 0x24, 0x12, 0xcb, 0xe0, 0xc9, 0x9b, 0xda, 0x4b, 0xb3, 0xe3, 0x4e, 0xdc, 0xa9, 0xfb, + 0x93, 0xf2, 0xfe, 0x93, 0xd2, 0xbb, 0xfd, 0xc6, 0x17, 0xf8, 0xda, 0x8c, 0xf0, 0xae, 0xd9, 0x45, + 0x1e, 0x76, 0x5b, 0x69, 0xb4, 0x9d, 0x42, 0xbd, 0x4d, 0xa6, 0xdd, 0x99, 0x17, 0xe3, 0x65, 0x19, + 0x49, 0x2b, 0xf5, 0xc4, 0xbc, 0x6d, 0x44, 0x38, 0x7e, 0xc9, 0x47, 0x16, 0xdb, 0x4a, 0xd9, 0xa5, + 0x3d, 0xda, 0xcf, 0xbb, 0xc9, 0xbe, 0x30, 0x89, 0x20, 0xda, 0xc5, 0x90, 0x93, 0xa9, 0xce, 0x58, + 0xbb, 0x3e, 0x3d, 0xac, 0x1f, 0x3c, 0x61, 0xa6, 0xe9, 0x37, 0x8a, 0xb4, 0xef, 0x2f, 0x3d, 0x72, + 0xdb, 0x17, 0x82, 0x90, 0x8a, 0x8b, 0xf9, 0xff, 0x55, 0x20, 0x5c, 0x44, 0x3e, 0x38, 0xc3, 0x00, + 0x49, 0xb9, 0x02, 0x4b, 0x4f, 0x5d, 0x42, 0x1e, 0x05, 0xa4, 0x08, 0x98, 0xd4, 0x72, 0xe2, 0xb4, + 0x61, 0xdf, 0x28, 0xea, 0x6c, 0xc0, 0xff, 0xff, 0x12, 0x34, 0xb3, 0x62, 0x9d, 0xca, 0x83, 0x5e, + 0x3f, 0x02, 0xf2, 0xe3, 0x70, 0xf4, 0x82, 0x26, 0xfa, 0x42, 0x30, 0xff, 0x05, 0x2d, 0x29, 0x0c, + 0x6a, 0x2c, 0x34, 0x3e, 0x65, 0x7f, 0xaf, 0xbf, 0x57, 0xd6, 0xae, 0x24, 0x28, 0x4c, 0xf4, 0x36, + 0x46, 0x7e, 0x5b, 0x7e, 0xbf, 0xc8, 0x7c, 0x23, 0x5d, 0xff, 0xe2, 0x2a, 0xaf, 0x36, 0xe2, 0x51, + 0x18, 0x56, 0xf8, 0xe2, 0x97, 0x5b, 0xea, 0x4a, 0x51, 0xed, 0xff, 0x1d, 0xd2, 0xb5, 0x76, 0x9a, + 0x49, 0x2f, 0x11, 0x0a, 0x77, 0x7f, 0xb9, 0x70, 0x56, 0xdb, 0xb6, 0x4f, 0xc5, 0x4a, 0xbc, 0x69, + 0x0b, 0x65, 0xb2, 0xc6, 0xe4, 0xe3, 0x29, 0x73, 0x27, 0xc7, 0x3e, 0xaf, 0xd7, 0xb2, 0x48, 0x99, + 0x0c, 0xfb, 0x19, 0xf4, 0x6f, 0x46, 0x2b, 0xf8, 0x80, 0xa1, 0x5d, 0x06, 0x65, 0x49, 0xbe, 0x8e, + 0x64, 0xc6, 0xee, 0x5c, 0xb4, 0x9b, 0x96, 0xe7, 0x88, 0x1a, 0x4b, 0x2f, 0x7a, 0x75, 0x37, 0x19, + 0xaf, 0x6a, 0x91, 0xf1, 0x25, 0x2a, 0x62, 0xb4, 0xa8, 0xdd, 0xbf, 0x5e, 0xa4, 0xf2, 0xc0, 0xad, + 0x66, 0x5b, 0x77, 0xfe, 0x11, 0x0c, 0x85, 0x27, 0xbd, 0xf1, 0x05, 0x81, 0x29, 0x0c, 0xed, 0xae, + 0x17, 0x8e, 0x2d, 0x72, 0x32, 0x05, 0x8d, 0x0d, 0x02, 0x7d, 0xb3, 0xa5, 0x46, 0x44, 0x81, 0x76, + 0x88, 0xdb, 0x12, 0xef, 0xda, 0x37, 0x8f, 0xb2, 0x14, 0x6a, 0x36, 0x3f, 0x81, 0x9e, 0x38, 0x91, + 0xb4, 0x54, 0x68, 0xd3, 0x21, 0x27, 0x1c, 0xf2, 0x4e, 0x49, 0xd5, 0x6d, 0xff, 0x2b, 0x94, 0x43, + 0xc9, 0x1a, 0x94, 0xa0, 0x38, 0x16, 0x36, 0x63, 0xf0, 0xcb, 0x27, 0xfa, 0x6b, 0x2c, 0x7f, 0xc1, + 0x01, 0xd3, 0x6c, 0x66, 0xad, 0xd5, 0xa4, 0x6c, 0xbb, 0xe0, 0xca, 0x02, 0x09, 0x1a, 0x3f, 0x89, + 0x2c, 0xa9, 0xdf, 0xe1, 0x29, 0x1e, 0xc6, 0xdb, 0x1d, 0xbb, 0x7e, 0x36, 0xe8, 0x35, 0x8b, 0xb4, + 0xd4, 0xe4, 0x9f, 0x8f, 0x54, 0xd6, 0xcf, 0x21, 0x6e, 0xde, 0x49, 0xd8, 0xc2, 0x12, 0xfe, 0xff, + 0x1b, 0xa3, 0x8c, 0xef, 0x51, 0x75, 0xad, 0x1a, 0x1b, 0xd8, 0x83, 0x4a, 0xad, 0x23, 0xad, 0xa5, + 0xdb, 0x51, 0xe4, 0x97, 0x43, 0xff, 0x85, 0x8a, 0x5e, 0x9c, 0x69, 0xec, 0x67, 0x83, 0x9e, 0x3d, + 0xdf, 0xf8, 0x20, 0xf9, 0x75, 0x57, 0x3e, 0x27, 0xa4, 0x37, 0x8c, 0xb1, 0x5d, 0xff, 0xc1, 0x4f, + 0x4d, 0xbd, 0xdd, 0x35, 0x76, 0xd5, 0x2f, 0x8d, 0x97, 0x63, 0x7e, 0xc6, 0xbb, 0xad, 0xd3, 0x11, + 0xf1, 0xd5, 0x59, 0xf9, 0x66, 0xd9, 0x9a, 0x6d, 0xa6, 0x8b, 0xc1, 0x05, 0xb4, 0xdb, 0x36, 0x3b, + 0x6d, 0x9a, 0x44, 0x87, 0x4a, 0xa9, 0x9a, 0x2a, 0x12, 0x7f, 0xf0, 0x41, 0x93, 0x4b, 0x95, 0x3a, + 0xbb, 0x4d, 0x85, 0x2c, 0xbf, 0x5f, 0x89, 0xc2, 0x4d, 0x0f, 0xc1, 0x06, 0x95, 0xed, 0xc6, 0xbe, + 0xda, 0x7a, 0xcf, 0xa3, 0x8f, 0x69, 0xfe, 0x3b, 0x48, 0x9e, 0xd4, 0x99, 0xd9, 0xf3, 0xf0, 0x41, + 0x6c, 0x69, 0x5a, 0x6f, 0xb7, 0x57, 0xe7, 0xaa, 0x77, 0xbb, 0x4d, 0x7e, 0x26, 0x15, 0xf1, 0xa5, + 0x8e, 0xf4, 0xe3, 0xdb, 0x4c, 0xbd, 0xdb, 0xfe, 0x0b, 0x09, 0x74, 0xdf, 0x69, 0xaa, 0x9b, 0x3d, + 0xfe, 0x0b, 0x2f, 0xb4, 0x95, 0xa7, 0xc9, 0xa5, 0xcc, 0x43, 0xc1, 0x44, 0x9d, 0xe2, 0x7d, 0xdc, + 0x50, 0x9f, 0x05, 0xb6, 0xcd, 0x07, 0xac, 0xf9, 0x75, 0xb3, 0x71, 0xe1, 0x48, 0xde, 0x9f, 0x2f, + 0x4d, 0x34, 0xd5, 0x6a, 0xf4, 0xed, 0xf0, 0x49, 0x35, 0x19, 0xdf, 0xff, 0x05, 0x3d, 0xdf, 0x77, + 0x4b, 0x69, 0x3a, 0xf3, 0x08, 0x96, 0x05, 0xdf, 0xc2, 0x85, 0x57, 0x2a, 0x33, 0x30, 0xa3, 0x1f, + 0xae, 0xf6, 0xb5, 0x53, 0xd8, 0x63, 0x84, 0x5d, 0xa3, 0xcc, 0xc1, 0x86, 0x1e, 0x34, 0xb1, 0xaf, + 0x4c, 0x5f, 0x68, 0x98, 0xee, 0xd6, 0x2e, 0xee, 0x6b, 0x3f, 0x2f, 0xe4, 0xe6, 0xff, 0x84, 0x09, + 0x33, 0xcc, 0xb7, 0x07, 0x2e, 0x36, 0xe3, 0xaa, 0x7c, 0x57, 0x73, 0xc2, 0x91, 0x95, 0xbb, 0x6d, + 0xb2, 0xf6, 0x36, 0xb0, 0xa5, 0x5f, 0xed, 0x7a, 0xd7, 0x38, 0xe6, 0x58, 0xfe, 0x34, 0xbc, 0xbb, + 0x37, 0x5c, 0xd4, 0xa9, 0xfb, 0x0b, 0x4c, 0x6f, 0x05, 0xef, 0xbb, 0x6d, 0xbf, 0x87, 0xb0, 0x93, + 0xa4, 0xab, 0x86, 0x15, 0x6a, 0x3a, 0xd2, 0x3a, 0x86, 0x25, 0xd6, 0xde, 0x5f, 0xf1, 0x86, 0x55, + 0xab, 0x49, 0x8e, 0x7d, 0xbc, 0xd0, 0x98, 0x92, 0xcf, 0x9f, 0x85, 0x22, 0x1a, 0x07, 0xd8, 0xd3, + 0xe9, 0x77, 0x74, 0xab, 0x3d, 0x7d, 0xa8, 0xcc, 0xa7, 0x7c, 0x29, 0x9b, 0x1b, 0x3b, 0xcb, 0xf2, + 0x4e, 0x5d, 0xe0, 0x45, 0x24, 0xbd, 0x36, 0xa0, 0x65, 0xe1, 0x42, 0xb7, 0x7c, 0x9d, 0x02, 0x9a, + 0x2e, 0x31, 0x83, 0x4e, 0xd8, 0x0e, 0x46, 0xab, 0x2e, 0x36, 0xa8, 0x9f, 0xe1, 0x3b, 0xd7, 0xf4, + 0xf6, 0x19, 0x6b, 0x89, 0x12, 0x14, 0x23, 0xe7, 0xbc, 0x8b, 0xcb, 0xee, 0x3d, 0xe7, 0xda, 0xf1, + 0x20, 0xa3, 0x72, 0x33, 0x75, 0x15, 0xd9, 0xc4, 0x08, 0x1e, 0x53, 0x9f, 0x46, 0xf5, 0x26, 0x13, + 0x31, 0x85, 0x8a, 0xa6, 0x3f, 0x05, 0x67, 0x1c, 0xab, 0x8b, 0x6c, 0x56, 0xee, 0xac, 0x6e, 0xc7, + 0xc6, 0x68, 0x67, 0xf4, 0x9c, 0xf0, 0xbd, 0x42, 0x3e, 0x96, 0x39, 0x4f, 0x13, 0x05, 0x36, 0x47, + 0xae, 0xa9, 0x4a, 0xc6, 0x5c, 0x15, 0xdf, 0x89, 0x8c, 0x2b, 0xc5, 0x9f, 0x1a, 0xed, 0xb5, 0xde, + 0xdb, 0x63, 0x35, 0xfe, 0x11, 0x10, 0xed, 0x65, 0xb9, 0xab, 0xbe, 0x56, 0x3e, 0x0a, 0x88, 0x4f, + 0xc6, 0xd8, 0xad, 0x8a, 0x5c, 0x73, 0x9e, 0xf7, 0xef, 0x8d, 0x84, 0x5a, 0xef, 0x7b, 0x6b, 0x52, + 0xa2, 0x8a, 0xba, 0x34, 0x2e, 0x1c, 0x25, 0xe9, 0x04, 0x4b, 0xa7, 0x80, 0xf6, 0x94, 0xed, 0x4e, + 0x32, 0x4d, 0x4d, 0x3d, 0xb0, 0x76, 0xff, 0x85, 0x0e, 0x4c, 0xf4, 0xf1, 0x10, 0x8f, 0x3d, 0x4c, + 0x5b, 0x29, 0x52, 0xf9, 0x7e, 0xd3, 0xe2, 0xf8, 0xd2, 0x4e, 0xe7, 0x5a, 0xd2, 0x7d, 0xbe, 0x05, + 0xd4, 0x4f, 0x6a, 0xd5, 0x81, 0x81, 0x2d, 0x2d, 0xa9, 0xe9, 0x05, 0x35, 0xee, 0xb1, 0x8a, 0xd1, + 0x57, 0xa6, 0x34, 0x88, 0xb7, 0x88, 0x10, 0x34, 0xb9, 0x24, 0xf5, 0xeb, 0x32, 0x5d, 0xf0, 0xd1, + 0x80, 0xd1, 0x49, 0xdf, 0x5f, 0xcb, 0x51, 0x28, 0xcd, 0x2f, 0x05, 0xc6, 0x7e, 0xa1, 0xd3, 0x1d, + 0x9c, 0xbc, 0xc7, 0xe3, 0x0f, 0x08, 0x89, 0x77, 0x77, 0xb9, 0xa7, 0xbd, 0xfe, 0x0a, 0x84, 0x08, + 0x72, 0xf0, 0xae, 0xa5, 0x59, 0x68, 0x90, 0x76, 0x1d, 0x72, 0xaa, 0xe9, 0x7c, 0x6c, 0x28, 0x03, + 0x42, 0xa2, 0xd4, 0xaf, 0x52, 0xaf, 0x87, 0x63, 0xb6, 0x63, 0x50, 0x81, 0x2a, 0xb3, 0x77, 0x5b, + 0x93, 0x72, 0xc9, 0x15, 0x15, 0x29, 0xfc, 0x91, 0x7f, 0x0a, 0x09, 0x0b, 0x0e, 0x0a, 0x27, 0x42, + 0x61, 0x52, 0x56, 0xab, 0x7b, 0x12, 0x38, 0xa7, 0x05, 0x8c, 0xe1, 0x83, 0xe8, 0x24, 0x70, 0xf7, + 0x10, 0x0c, 0x87, 0x02, 0x41, 0x45, 0x3e, 0x20, 0x68, 0x8b, 0x58, 0x76, 0xb2, 0x50, 0x92, 0xea, + 0x64, 0xa1, 0xa9, 0x06, 0x73, 0xce, 0x04, 0xc9, 0x33, 0x42, 0x54, 0x68, 0x9c, 0xe5, 0x9e, 0x90, + 0x4f, 0x73, 0x27, 0xfa, 0xd1, 0x3f, 0x08, 0x0d, 0xf2, 0x01, 0x1c, 0xfa, 0x30, 0x11, 0x60, 0x02, + 0x8f, 0x8c, 0xa2, 0xb2, 0x62, 0x0e, 0x25, 0x50, 0x04, 0x70, 0x5b, 0x0a, 0xa0, 0x55, 0x43, 0x13, + 0xbc, 0x1a, 0x89, 0x61, 0x8c, 0x12, 0xb7, 0xc5, 0x72, 0x64, 0x0c, 0xc8, 0x1c, 0x9b, 0x7c, 0xff, + 0xbe, 0x83, 0x8a, 0xdc, 0xa1, 0xd8, 0x92, 0xd8, 0xf9, 0xec, 0x81, 0x2d, 0x02, 0x9b, 0x9e, 0x79, + 0x04, 0xc5, 0x27, 0xb1, 0xfb, 0xc8, 0xb8, 0xf3, 0xa3, 0x03, 0x1a, 0x35, 0x27, 0xc4, 0xc6, 0xc9, + 0x41, 0xd9, 0xd4, 0x3d, 0xaa, 0x86, 0x6c, 0xe0, 0x06, 0x1d, 0x2a, 0x7c, 0x16, 0x1e, 0xcd, 0x7a, + 0x67, 0x50, 0x8a, 0xda, 0x70, 0xe1, 0xed, 0xeb, 0x4b, 0x8c, 0x69, 0xf9, 0x7e, 0xb5, 0xbf, 0x7e, + 0x8d, 0x57, 0xdb, 0x65, 0x67, 0xf0, 0xd1, 0x4d, 0xae, 0x93, 0x4e, 0xde, 0x42, 0xd3, 0xb0, 0x9b, + 0x13, 0x6d, 0xb6, 0xdf, 0x87, 0xa4, 0x94, 0x59, 0xf0, 0x96, 0x9e, 0x6d, 0x4b, 0xb4, 0xc5, 0x4b, + 0xff, 0xf0, 0xed, 0xcd, 0x6b, 0x5f, 0xea, 0x76, 0x55, 0x17, 0x69, 0xa5, 0x58, 0x88, 0xf9, 0x7f, + 0xf0, 0xed, 0xee, 0x6c, 0xd3, 0xef, 0x67, 0x73, 0xe5, 0x47, 0x4c, 0x34, 0xe1, 0xcf, 0xcd, 0xff, + 0x05, 0x36, 0x59, 0x3a, 0x8e, 0xeb, 0x0d, 0xf6, 0xfb, 0xcd, 0xb9, 0xbe, 0x0a, 0xae, 0xda, 0x53, + 0x75, 0x1f, 0xcf, 0x77, 0x3d, 0xe4, 0xc2, 0x68, 0xbd, 0xdf, 0x08, 0x73, 0x7d, 0xa3, 0xe3, 0x76, + 0x33, 0xe9, 0xb1, 0xba, 0xcc, 0xf0, 0x41, 0x56, 0x9e, 0xd6, 0xd2, 0x3e, 0x35, 0xf2, 0x72, 0x5c, + 0x66, 0x37, 0xff, 0x85, 0x26, 0x94, 0x6f, 0x48, 0xd0, 0x36, 0x6e, 0xed, 0xea, 0x6b, 0x9b, 0xe0, + 0xc2, 0xea, 0xd3, 0x36, 0x54, 0xa4, 0xf2, 0x79, 0xad, 0x09, 0x76, 0xdf, 0xf8, 0xcb, 0x37, 0x54, + 0xfb, 0x51, 0xe9, 0x4d, 0xf9, 0xe3, 0x0a, 0x6f, 0x13, 0x1a, 0x92, 0x9a, 0x9b, 0x9e, 0x3a, 0xa5, + 0xea, 0xcf, 0x57, 0xcb, 0xc9, 0xb1, 0x78, 0x2c, 0xbc, 0xe9, 0xba, 0x6e, 0xdd, 0xb9, 0x53, 0xe0, + 0xba, 0x92, 0xc2, 0x8a, 0x9b, 0x4f, 0xbf, 0x7c, 0xba, 0xd7, 0xc1, 0x4c, 0x47, 0xd5, 0xd4, 0xfc, + 0xee, 0xa9, 0xd7, 0xc1, 0x56, 0xba, 0x5b, 0x43, 0x95, 0x71, 0x9b, 0x0f, 0x95, 0xbf, 0xc4, 0xe3, + 0x69, 0x3c, 0xd3, 0x6f, 0xc6, 0x5a, 0x6b, 0x4d, 0xb4, 0xdb, 0xa9, 0xb7, 0xab, 0x46, 0xcf, 0x08, + 0x56, 0x4f, 0xcf, 0xcd, 0xaf, 0xc9, 0x79, 0xf5, 0xd9, 0xe0, 0xa3, 0xb4, 0x7c, 0xcf, 0x87, 0xc8, + 0xbe, 0x0a, 0x4c, 0x76, 0x7a, 0x63, 0xf9, 0x51, 0xbb, 0x28, 0xd8, 0xf2, 0x30, 0xe7, 0xc7, 0x43, + 0x54, 0xfb, 0x6a, 0xae, 0xd0, 0xfe, 0x65, 0x5e, 0x36, 0x82, 0xbf, 0x5a, 0xf8, 0x53, 0x63, 0xbf, + 0x74, 0xee, 0x9e, 0x48, 0xb2, 0x97, 0xf8, 0x50, 0xa2, 0xbb, 0x6a, 0x7d, 0x26, 0xe0, 0x6b, 0x05, + 0xfa, 0x68, 0x91, 0x56, 0x15, 0xf5, 0x52, 0x98, 0x7f, 0x85, 0x2d, 0xd8, 0xaa, 0xeb, 0x8d, 0xac, + 0xcf, 0xc1, 0x52, 0x89, 0x24, 0x8a, 0x22, 0x8f, 0x84, 0x89, 0x49, 0x53, 0x69, 0xba, 0x5e, 0x16, + 0x13, 0x7b, 0x76, 0xed, 0xe2, 0x04, 0xea, 0x9f, 0xfc, 0x12, 0x11, 0x11, 0x7a, 0x1d, 0xeb, 0xe1, + 0x42, 0x18, 0xc5, 0xd8, 0x38, 0x73, 0x3a, 0xcd, 0xc8, 0x3b, 0xdf, 0xcf, 0x3e, 0x38, 0x6c, 0xd5, + 0x7b, 0x6f, 0x8f, 0xaf, 0xa9, 0x6e, 0x52, 0xac, 0xc9, 0x6f, 0xb6, 0xe2, 0x45, 0xbe, 0xfe, 0x3b, + 0x7a, 0x49, 0x25, 0x8d, 0xbc, 0xb9, 0xaf, 0xc9, 0xb0, 0xc4, 0x08, 0x19, 0x9c, 0xcc, 0xb8, 0xeb, + 0xea, 0xea, 0xae, 0xc6, 0xad, 0x27, 0x8d, 0xc9, 0x27, 0xf1, 0xe5, 0x32, 0x6f, 0xd1, 0xd0, 0xd1, + 0x73, 0xe5, 0xda, 0x97, 0x7c, 0x67, 0x54, 0xe8, 0x69, 0x31, 0x9b, 0x26, 0x4d, 0x44, 0xd8, 0x6f, + 0x43, 0x07, 0xe2, 0x0f, 0x37, 0x7f, 0x69, 0x57, 0x13, 0x05, 0x5a, 0x0d, 0xa6, 0xad, 0x8d, 0x93, + 0x73, 0xb6, 0x76, 0x1f, 0xe2, 0x88, 0x58, 0x3b, 0x27, 0x3e, 0x2b, 0xab, 0xe2, 0x21, 0x4d, 0x23, + 0x30, 0xd6, 0x34, 0x8a, 0xc3, 0x58, 0x9b, 0x5e, 0x55, 0x17, 0x7e, 0x26, 0x10, 0x95, 0x57, 0x1f, + 0xab, 0xaa, 0x6b, 0xc4, 0xc2, 0x5a, 0x69, 0x25, 0xaa, 0x58, 0x98, 0xc3, 0x72, 0x84, 0xa4, 0x83, + 0x47, 0xb2, 0x3d, 0xf7, 0xb3, 0x91, 0x44, 0x1c, 0xbe, 0xf6, 0x44, 0x3d, 0xf5, 0xf0, 0xa1, 0xeb, + 0x59, 0xb0, 0xd9, 0x5a, 0x4c, 0xeb, 0xf7, 0x4b, 0x2f, 0x8d, 0xc6, 0xdf, 0x07, 0x9f, 0xaa, 0x44, + 0xd5, 0xe4, 0xd6, 0xed, 0xdf, 0x6c, 0xf4, 0xfc, 0x3f, 0x31, 0x33, 0x96, 0x50, 0xcc, 0x6f, 0xd0, + 0xad, 0x46, 0x78, 0xc7, 0x64, 0x23, 0x1d, 0x93, 0x64, 0xa1, 0xa3, 0x56, 0x20, 0xac, 0x4a, 0x7c, + 0xa1, 0x8d, 0x0b, 0xd1, 0x32, 0x59, 0xef, 0xc2, 0x94, 0x92, 0x77, 0x23, 0x5e, 0xae, 0xa6, 0xf7, + 0xa9, 0x30, 0x85, 0xed, 0x7a, 0xfc, 0x57, 0xf0, 0xe9, 0x16, 0xcd, 0x56, 0xf7, 0x74, 0x86, 0xd7, + 0x4c, 0x7a, 0xca, 0xc5, 0xa8, 0xc9, 0xa3, 0xad, 0xff, 0xc2, 0x84, 0x5b, 0xe4, 0xf3, 0x61, 0x50, + 0x92, 0x35, 0x42, 0x35, 0x7e, 0x54, 0x80, 0x14, 0xc6, 0x0e, 0xa4, 0x27, 0xfd, 0xc8, 0x38, 0x27, + 0x38, 0x75, 0xa6, 0x61, 0xdb, 0x3c, 0x48, 0x50, 0xec, 0xfc, 0x6c, 0xe2, 0xb6, 0xa6, 0x16, 0xb2, + 0xf9, 0x31, 0x98, 0x59, 0x62, 0xf0, 0xc8, 0x1f, 0x11, 0x1a, 0x43, 0xc1, 0xf6, 0x51, 0x1d, 0x0b, + 0x3b, 0x6f, 0x14, 0xd2, 0xf5, 0x11, 0x05, 0x8d, 0x80, 0xa3, 0x49, 0x66, 0x7f, 0xbe, 0xf2, 0x6a, + 0x78, 0x80, 0x88, 0xce, 0xd3, 0x36, 0x5a, 0xd3, 0x99, 0x72, 0x28, 0xfd, 0xc4, 0x7e, 0x86, 0x1a, + 0x56, 0x87, 0x39, 0x9f, 0xd8, 0xf6, 0x0f, 0x7a, 0xc4, 0x1e, 0x14, 0x2e, 0xcc, 0x35, 0xaf, 0x6f, + 0xeb, 0x4b, 0xd0, 0xa7, 0x27, 0x00, 0x38, 0xbe, 0xcc, 0xb6, 0x28, 0xeb, 0x42, 0x5a, 0x02, 0xa9, + 0x43, 0xa8, 0x95, 0x78, 0x5a, 0x42, 0xcd, 0x70, 0x2f, 0x9e, 0xf7, 0x78, 0x44, 0x06, 0x19, 0x1c, + 0x3c, 0x1e, 0xab, 0x30, 0xd7, 0xc3, 0xe5, 0xcb, 0x89, 0x26, 0xed, 0x47, 0xaf, 0x76, 0xeb, 0xa6, + 0x6d, 0xff, 0x04, 0x34, 0xdb, 0x4d, 0xb8, 0x3e, 0x0a, 0x34, 0x9f, 0x88, 0x61, 0x63, 0xe3, 0x0c, + 0xf2, 0x7a, 0x4d, 0xe9, 0xbb, 0x07, 0x43, 0x37, 0x1f, 0xb2, 0xbe, 0x3f, 0xc2, 0x87, 0xf2, 0x6d, + 0xe5, 0xcc, 0x76, 0xd4, 0xf6, 0xdb, 0x63, 0xe1, 0x43, 0x24, 0x97, 0x66, 0x76, 0x37, 0x68, 0xfe, + 0x13, 0x65, 0xaa, 0xae, 0x5e, 0xf8, 0x42, 0x5d, 0x8b, 0x74, 0x9f, 0xd6, 0x97, 0x84, 0xbc, 0xfb, + 0x76, 0x4d, 0x78, 0x50, 0xe5, 0xc3, 0xb1, 0xd2, 0x26, 0xa7, 0xac, 0x9c, 0xda, 0xd6, 0xa6, 0xca, + 0x4a, 0xbc, 0x71, 0xab, 0x56, 0xfb, 0x6d, 0xe3, 0xad, 0xde, 0x0b, 0x0b, 0x7b, 0x53, 0xea, 0x1d, + 0x76, 0xca, 0xce, 0xff, 0x04, 0x64, 0x73, 0xcb, 0xa7, 0x5e, 0x36, 0x9c, 0x71, 0x6b, 0xda, 0x69, + 0xb7, 0x10, 0xf5, 0x86, 0xb1, 0x56, 0xa9, 0xd6, 0x7d, 0x3e, 0xff, 0x82, 0x89, 0x9f, 0x5b, 0x6d, + 0x3d, 0xfe, 0x11, 0x2d, 0x58, 0xda, 0x36, 0x27, 0x49, 0x5a, 0xfc, 0x14, 0x5d, 0xbb, 0xb4, 0x6d, + 0x6a, 0x39, 0x7c, 0x29, 0x79, 0xdb, 0x48, 0xcd, 0xe2, 0x73, 0xe5, 0x6d, 0x1f, 0x6d, 0xc4, 0xcb, + 0xc1, 0x51, 0x34, 0x9a, 0xed, 0xb5, 0x1a, 0xa9, 0xee, 0x2f, 0x82, 0x8e, 0xd1, 0x99, 0x84, 0xde, + 0x7c, 0x73, 0xe5, 0x29, 0xd8, 0xff, 0x0c, 0x4b, 0xb7, 0x36, 0x6d, 0x34, 0xad, 0xb6, 0x5d, 0x6e, + 0xff, 0x82, 0xb2, 0x2d, 0xc9, 0x8b, 0xb7, 0x68, 0x9e, 0xed, 0xf0, 0xff, 0x1b, 0xbd, 0x5c, 0x86, + 0xc5, 0x06, 0x3e, 0x83, 0xbc, 0xb8, 0xbe, 0xf2, 0xbf, 0xe3, 0x2d, 0x66, 0x83, 0x1a, 0x1c, 0x95, + 0x24, 0x8c, 0x15, 0x86, 0x3e, 0x0d, 0x7d, 0xc7, 0x31, 0x07, 0xe1, 0x4a, 0x1b, 0x92, 0xb5, 0x2f, + 0xc2, 0xe5, 0x26, 0xfb, 0xda, 0x58, 0xe2, 0xf2, 0xf8, 0x2c, 0xb5, 0x5c, 0xba, 0x96, 0x96, 0x36, + 0xae, 0xed, 0xf1, 0xb7, 0x64, 0xfb, 0xae, 0x95, 0x4d, 0x84, 0xf0, 0xa1, 0x27, 0x65, 0xe5, 0xf4, + 0xff, 0xc2, 0x85, 0x4f, 0x6f, 0x6d, 0xbb, 0x43, 0xcb, 0x2d, 0x36, 0xd2, 0xb7, 0xc7, 0x89, 0x4d, + 0x3f, 0x54, 0xe5, 0xff, 0x8a, 0x1c, 0xdb, 0x53, 0x62, 0xc8, 0xb8, 0xa7, 0xe1, 0x42, 0xf4, 0xdb, + 0xd9, 0xb3, 0x24, 0x55, 0xb1, 0x75, 0x5d, 0x7d, 0xf0, 0x5d, 0x17, 0x4f, 0x36, 0x6e, 0xed, 0xf1, + 0x9c, 0x64, 0xd1, 0xde, 0x96, 0x4a, 0xa5, 0x4a, 0x96, 0x55, 0x09, 0x31, 0x6c, 0x4c, 0x15, 0x96, + 0xa8, 0x90, 0xca, 0x56, 0x32, 0xb5, 0x86, 0xf9, 0xad, 0xbc, 0x77, 0x9f, 0x0b, 0x91, 0x25, 0x8c, + 0x5a, 0x67, 0x6d, 0x42, 0x8d, 0x62, 0xf2, 0xfb, 0xb2, 0x9e, 0x1e, 0x14, 0xf4, 0x33, 0xd8, 0xe7, + 0xa9, 0xe3, 0x0e, 0x29, 0xd4, 0x73, 0xe9, 0x49, 0x49, 0x80, 0x7d, 0x6b, 0x04, 0xb8, 0x4e, 0xb2, + 0xdf, 0x85, 0x0c, 0xf8, 0x50, 0x9d, 0x27, 0xaa, 0xdb, 0x96, 0x5b, 0x73, 0x4b, 0x60, 0x1a, 0x3e, + 0xcb, 0x3c, 0xc7, 0x11, 0x04, 0x65, 0x56, 0x54, 0x39, 0x5a, 0x69, 0xfc, 0x3e, 0x0a, 0xc5, 0xba, + 0x5b, 0x54, 0x26, 0xab, 0x22, 0x4c, 0x3e, 0x24, 0x85, 0x50, 0xc5, 0x74, 0x93, 0xaf, 0xe1, 0x09, + 0x3e, 0x87, 0xa9, 0x94, 0x46, 0x9e, 0xb8, 0x88, 0x27, 0x36, 0xa6, 0xe8, 0xa9, 0xa5, 0x83, 0x89, + 0x85, 0x2a, 0x4f, 0x30, 0x19, 0xc2, 0xc5, 0x75, 0xcb, 0x75, 0x80, 0xec, 0x1f, 0xc1, 0xec, 0x2e, + 0xbc, 0xbe, 0x09, 0x34, 0xa4, 0xde, 0xf9, 0x67, 0x63, 0x46, 0x5c, 0xf0, 0xf5, 0x53, 0xa7, 0x8b, + 0x4f, 0x4d, 0xb1, 0x7b, 0x53, 0xce, 0xc2, 0xfd, 0x10, 0xfb, 0xe2, 0x23, 0x7b, 0xc2, 0x08, 0xd5, + 0xcf, 0x50, 0x75, 0xab, 0x64, 0xf5, 0x2c, 0x21, 0xad, 0x02, 0x5f, 0xb4, 0xc9, 0x7b, 0xc9, 0xd1, + 0x08, 0x7c, 0x0d, 0x73, 0x29, 0x6d, 0xb5, 0xa6, 0x8f, 0xc6, 0x97, 0x3b, 0x7a, 0x19, 0x77, 0x51, + 0x5d, 0x83, 0x6a, 0xcf, 0x65, 0x5b, 0x3e, 0x3f, 0x83, 0xb5, 0x78, 0x81, 0x23, 0x4c, 0x03, 0x1e, + 0xba, 0xb2, 0xa2, 0x16, 0x97, 0x80, 0x92, 0xab, 0xbd, 0x3d, 0x05, 0x95, 0xd4, 0x03, 0x7f, 0xc1, + 0xb0, 0x46, 0x02, 0x94, 0x5a, 0xac, 0x34, 0x6a, 0x48, 0x5b, 0xdc, 0xc6, 0x05, 0x1c, 0x94, 0xa8, + 0xf2, 0xfb, 0xff, 0xc1, 0x59, 0x38, 0xdc, 0xed, 0x03, 0x7d, 0x12, 0xa4, 0xc8, 0xb4, 0x58, 0x51, + 0x5e, 0xac, 0x2f, 0xf7, 0xb9, 0xf0, 0x85, 0x4d, 0x20, 0x89, 0x1a, 0x71, 0x83, 0xfc, 0x05, 0xae, + 0x91, 0x42, 0x01, 0xa1, 0x3b, 0x61, 0xf8, 0x35, 0x7f, 0xf0, 0xa1, 0x64, 0x4e, 0x0e, 0x82, 0xbd, + 0x11, 0x27, 0x46, 0x92, 0xcd, 0x19, 0x74, 0xd9, 0x06, 0x0c, 0x2d, 0xa3, 0x44, 0x06, 0xf2, 0xb0, + 0xba, 0xf8, 0xd1, 0x36, 0x64, 0x59, 0x72, 0xfb, 0xb7, 0x7e, 0xd5, 0x26, 0xa6, 0x0f, 0xf1, 0x5d, + 0xfc, 0x15, 0x0a, 0x3b, 0x15, 0x73, 0x91, 0xbe, 0x0c, 0x8b, 0x2b, 0x9f, 0x94, 0x82, 0xc1, 0xbf, + 0xb7, 0x13, 0x0a, 0x6e, 0x37, 0xd1, 0xd8, 0xd8, 0xcc, 0xd3, 0x27, 0xa8, 0xa8, 0x7a, 0x63, 0x54, + 0xcf, 0x55, 0xc3, 0xe0, 0x9b, 0x7b, 0x49, 0x34, 0xa8, 0x92, 0x87, 0x82, 0x43, 0xec, 0x8b, 0x09, + 0x7c, 0x4d, 0x21, 0xac, 0xf1, 0x71, 0xe5, 0xf0, 0x45, 0x9e, 0x49, 0x5e, 0xbe, 0xbd, 0xf0, 0x56, + 0x46, 0x9a, 0xeb, 0x6e, 0x32, 0x63, 0x39, 0x3b, 0xf1, 0xf9, 0xff, 0xb6, 0xad, 0xc9, 0xbf, 0x08, + 0x50, 0xe8, 0xd6, 0xd2, 0xd5, 0xf7, 0xf0, 0x54, 0x76, 0xdf, 0xde, 0xd5, 0x3c, 0xf8, 0x7c, 0x97, + 0x5b, 0xe1, 0xab, 0x5b, 0x66, 0x8c, 0x28, 0xef, 0x4e, 0xdf, 0xf8, 0x2a, 0x9d, 0x9b, 0x9b, 0x1c, + 0xb3, 0x74, 0x7b, 0x4d, 0xdb, 0xe0, 0x82, 0xd2, 0x6d, 0x22, 0x48, 0x9a, 0x4d, 0x8a, 0xb2, 0x46, + 0x48, 0x25, 0x56, 0xdb, 0x5f, 0xf0, 0x4d, 0x33, 0x1a, 0x37, 0x73, 0x1c, 0x6c, 0x7d, 0xf0, 0x59, + 0x4e, 0xda, 0x22, 0xeb, 0x6c, 0x94, 0xf0, 0x83, 0xed, 0xf0, 0x59, 0x4d, 0xa6, 0x69, 0xb4, 0xdb, + 0xda, 0xd2, 0x6f, 0x82, 0x1f, 0x4c, 0x6b, 0x5e, 0xf8, 0x7a, 0xf9, 0xe4, 0x89, 0xb7, 0xe6, 0xc9, + 0xee, 0x98, 0x23, 0x2a, 0x4e, 0xfc, 0xff, 0x1c, 0x4c, 0xd4, 0xab, 0x3a, 0xd2, 0x54, 0xb4, 0x97, + 0x10, 0x56, 0x5c, 0xd7, 0x9a, 0xcd, 0x7e, 0x14, 0x25, 0x58, 0xe6, 0x84, 0x57, 0xaa, 0x1a, 0x99, + 0x8e, 0x50, 0xe0, 0xf8, 0x53, 0x59, 0x99, 0xd2, 0xe9, 0x4c, 0x91, 0xbd, 0x36, 0x98, 0xe7, 0x18, + 0x78, 0x53, 0x64, 0x33, 0x7b, 0x8a, 0xd8, 0xbe, 0x68, 0x53, 0xa4, 0x46, 0x29, 0xe7, 0x1e, 0x14, + 0xe6, 0xfe, 0xa4, 0xee, 0xc1, 0xcb, 0x84, 0x95, 0xae, 0xac, 0x92, 0xb0, 0xf0, 0x41, 0x8a, 0x62, + 0xe4, 0xc5, 0x68, 0xba, 0xd8, 0x9f, 0xaf, 0x5f, 0x77, 0x97, 0xf8, 0x25, 0x85, 0xb8, 0x93, 0xbd, + 0xd8, 0x93, 0x5e, 0x17, 0xc3, 0xfa, 0x19, 0xf8, 0xbf, 0xc9, 0x86, 0x49, 0x2f, 0xf6, 0x99, 0xff, + 0xfe, 0x10, 0x3e, 0xcd, 0x56, 0x4f, 0xad, 0x7c, 0x15, 0x19, 0xb6, 0xed, 0x19, 0x89, 0x9c, 0xde, + 0x48, 0x62, 0x1e, 0x0a, 0x64, 0xfe, 0x95, 0x2b, 0x4b, 0x3c, 0xbe, 0x12, 0xab, 0x55, 0x49, 0x5d, + 0x7c, 0x16, 0x15, 0xe0, 0xa5, 0x50, 0xd3, 0x5c, 0xea, 0x09, 0xe8, 0x92, 0x3f, 0x08, 0x49, 0xd4, + 0x16, 0x2e, 0xb4, 0xcb, 0xd1, 0x98, 0xd2, 0xcd, 0x07, 0xf0, 0xc8, 0x3b, 0x57, 0x63, 0x13, 0x0a, + 0x4f, 0x06, 0x67, 0xae, 0xf7, 0x95, 0x1d, 0x01, 0x99, 0x5e, 0x99, 0xf1, 0xa5, 0xac, 0x7b, 0x95, + 0xa4, 0xf7, 0xc2, 0x86, 0x4a, 0x76, 0x2d, 0x9c, 0xbf, 0x6c, 0xae, 0xd1, 0xb7, 0x65, 0x36, 0xfb, + 0x24, 0x61, 0x1a, 0x33, 0x9f, 0x7c, 0x16, 0x92, 0x98, 0xe9, 0x55, 0x5f, 0x1b, 0x34, 0xae, 0x18, + 0x9b, 0xef, 0x2f, 0x8d, 0xf0, 0x81, 0xff, 0xd1, 0x42, 0x42, 0x33, 0xa1, 0xbb, 0x6b, 0x3f, 0x0e, + 0x94, 0x83, 0x62, 0x33, 0x2c, 0xb2, 0x98, 0xfd, 0x73, 0x52, 0xa6, 0xb4, 0xca, 0xad, 0x12, 0x9e, + 0x5d, 0x6b, 0xc6, 0x14, 0x63, 0x2f, 0x67, 0x55, 0xdf, 0xdc, 0x99, 0x32, 0x46, 0x38, 0x6f, 0xb3, + 0x57, 0x89, 0x08, 0x16, 0xef, 0x2b, 0x1d, 0xa0, 0xe2, 0xc7, 0x39, 0x96, 0x97, 0x8c, 0x35, 0x25, + 0x0c, 0x02, 0x89, 0xb3, 0x51, 0x08, 0xfc, 0xf6, 0xab, 0xcb, 0xa9, 0xac, 0x9f, 0x51, 0x55, 0x28, + 0x82, 0x0c, 0x30, 0xde, 0x1f, 0x8c, 0xa8, 0xec, 0xca, 0x74, 0x2c, 0x41, 0xf5, 0xd7, 0x9c, 0x8c, + 0xc8, 0x69, 0x38, 0xc6, 0xc0, 0x90, 0x51, 0x56, 0x30, 0x8d, 0x47, 0x75, 0x24, 0xab, 0xd3, 0x5b, + 0x7e, 0x36, 0x2d, 0x88, 0x94, 0x8a, 0x10, 0x93, 0x2f, 0x9a, 0x1a, 0x50, 0xd9, 0x98, 0x0c, 0x94, + 0xed, 0xf9, 0x9d, 0x37, 0x73, 0xa9, 0xb5, 0xe6, 0x37, 0x3d, 0x48, 0xd9, 0x7a, 0x8b, 0x93, 0x72, + 0xa9, 0x17, 0xc1, 0xd7, 0x0e, 0x68, 0xf8, 0xc3, 0xa6, 0x9e, 0x33, 0x9f, 0x4a, 0xe4, 0xd1, 0x79, + 0xf1, 0x58, 0xcf, 0x82, 0x9c, 0xf5, 0xcf, 0x36, 0xd2, 0xd3, 0x26, 0x5a, 0x55, 0xe3, 0xea, 0x86, + 0x93, 0xa5, 0xb5, 0xdb, 0x5f, 0x1e, 0x46, 0xab, 0x1b, 0x55, 0x6c, 0x81, 0x13, 0xb2, 0x69, 0xde, + 0x40, 0x82, 0xde, 0x36, 0x10, 0x0d, 0xa3, 0x07, 0xc6, 0xcd, 0x94, 0xe4, 0x5d, 0xdd, 0xb6, 0x95, + 0xe9, 0xb6, 0x69, 0xf6, 0x5c, 0xad, 0xe6, 0x99, 0x7d, 0xc9, 0x28, 0x7a, 0xa3, 0xa8, 0x6c, 0xcd, + 0xbb, 0xf1, 0x22, 0x01, 0x7c, 0xcb, 0xe6, 0x44, 0xe1, 0x8e, 0xbb, 0xae, 0xb6, 0x8e, 0xad, 0xb2, + 0x97, 0xe2, 0x44, 0x0d, 0xce, 0xc7, 0x03, 0xad, 0xf8, 0x3b, 0x1a, 0xcc, 0x47, 0x62, 0x53, 0x29, + 0x32, 0x6e, 0xa8, 0xa3, 0x26, 0x8c, 0x2f, 0xf8, 0x91, 0x01, 0x49, 0x77, 0x46, 0xd3, 0xa2, 0x67, + 0xb0, 0x3b, 0x5a, 0xf9, 0xe9, 0xb5, 0x1b, 0x54, 0x32, 0xfd, 0x32, 0x28, 0xf8, 0x52, 0xed, 0xc9, + 0xd5, 0xec, 0xf8, 0xca, 0xe9, 0x5a, 0xe9, 0x9b, 0x37, 0xf8, 0xd9, 0xab, 0x06, 0xdb, 0x44, 0xa2, + 0x51, 0xb3, 0x7d, 0x0e, 0xac, 0x65, 0xc2, 0xa4, 0xda, 0xd7, 0xfe, 0xf6, 0xcf, 0x58, 0xfc, 0x6f, + 0x66, 0x93, 0x67, 0xd6, 0x52, 0x0d, 0x18, 0x52, 0x29, 0x17, 0x2d, 0x96, 0xf4, 0xae, 0x7d, 0x6f, + 0xff, 0x1a, 0x42, 0xf0, 0x41, 0x55, 0x63, 0x2f, 0x8c, 0x95, 0x55, 0xaf, 0x8a, 0x51, 0x4c, 0xf0, + 0xcb, 0x7f, 0xba, 0x8f, 0x02, 0x70, 0x14, 0x8c, 0xb0, 0x63, 0xb7, 0x72, 0x41, 0x3e, 0xad, 0x62, + 0xf5, 0xf0, 0xa1, 0xea, 0x26, 0x9d, 0x17, 0x14, 0xb5, 0x0c, 0xf5, 0x3e, 0x8b, 0x52, 0x1a, 0x56, + 0x55, 0xce, 0x3c, 0x3e, 0x55, 0x89, 0x93, 0x2d, 0x27, 0x7b, 0x65, 0x84, 0x7a, 0xbc, 0xff, 0xfe, + 0x14, 0xa5, 0x6a, 0x49, 0x2d, 0x3b, 0x64, 0x84, 0x6c, 0x65, 0xd2, 0x4a, 0x8d, 0x9f, 0x1b, 0x63, + 0x3f, 0xa5, 0x6d, 0xa6, 0x36, 0xcc, 0xc3, 0x74, 0xb4, 0x93, 0xd1, 0x5b, 0xb4, 0x6c, 0xbf, 0xf0, + 0x4c, 0x21, 0xb8, 0xe1, 0xb3, 0xae, 0x77, 0xdc, 0xf8, 0xd2, 0x8c, 0x08, 0x0b, 0x18, 0x61, 0x8b, + 0xa0, 0xa2, 0xa8, 0x38, 0x52, 0xa5, 0x68, 0x72, 0x1d, 0x97, 0x8a, 0x36, 0xa3, 0x59, 0x7f, 0x1d, + 0xd7, 0xf0, 0x5c, 0x79, 0x70, 0xec, 0x57, 0x75, 0xa6, 0x5e, 0x08, 0x66, 0xd3, 0x6f, 0x3f, 0xc2, + 0x94, 0x88, 0xd4, 0x3e, 0x9d, 0x5b, 0x72, 0xb2, 0xe6, 0x8f, 0xdc, 0xa5, 0x47, 0xc0, 0xaf, 0xe3, + 0xf1, 0xbb, 0x88, 0x7b, 0xdc, 0xda, 0x34, 0x32, 0x3d, 0xf0, 0x64, 0xe6, 0x7c, 0x2a, 0x4b, 0xda, + 0x4d, 0xfb, 0x67, 0x02, 0xa2, 0x78, 0xed, 0xff, 0x82, 0xeb, 0x1c, 0xda, 0xb5, 0xce, 0xa9, 0xf6, + 0xc9, 0x3d, 0x7c, 0x71, 0x53, 0xae, 0xa9, 0x6b, 0x5f, 0x04, 0x14, 0x92, 0xbd, 0x51, 0x1e, 0x18, + 0xda, 0xea, 0x9c, 0x55, 0xff, 0xc2, 0x3d, 0x8c, 0x66, 0xc4, 0x9c, 0x8d, 0xe8, 0xea, 0x4b, 0xe1, + 0xdb, 0x35, 0x51, 0x6e, 0xc6, 0x5a, 0xd9, 0xdc, 0x69, 0x6d, 0x55, 0xbd, 0x6f, 0xfc, 0x13, 0x10, + 0x91, 0x63, 0x14, 0xe9, 0x97, 0x73, 0xcb, 0x37, 0xc6, 0xc7, 0x3f, 0x4e, 0x11, 0xa4, 0x66, 0x8d, + 0xac, 0xbd, 0x85, 0xde, 0xf5, 0x3d, 0x4b, 0xa5, 0xdf, 0xfc, 0x14, 0x9f, 0xcd, 0x9b, 0x4d, 0x68, + 0x8f, 0x9c, 0xbf, 0x0a, 0x08, 0x41, 0xc9, 0x13, 0x60, 0x5f, 0x49, 0x77, 0x96, 0x78, 0x99, 0xda, + 0xd5, 0x59, 0x28, 0x41, 0x53, 0x14, 0xe0, 0xa7, 0xc2, 0x92, 0xee, 0x0c, 0x8a, 0x26, 0x6d, 0x2d, + 0x8d, 0x53, 0xcb, 0x8a, 0x75, 0x8f, 0x0a, 0x5e, 0xd8, 0xdd, 0xd3, 0x7d, 0x90, 0x1e, 0xaf, 0xa4, + 0x31, 0x8c, 0xc2, 0x26, 0xc7, 0x3e, 0x0b, 0x2b, 0x2e, 0xa2, 0x43, 0x43, 0x64, 0xa3, 0xb4, 0xa5, + 0xcc, 0xbe, 0x0a, 0xa9, 0xb1, 0x9f, 0x2e, 0xae, 0xd5, 0x37, 0x7f, 0x82, 0x91, 0x3b, 0x69, 0xaa, + 0x75, 0x6e, 0xda, 0xec, 0xf8, 0x2c, 0x31, 0xfa, 0xbb, 0x8b, 0xf7, 0x4b, 0x3c, 0xe3, 0xe1, 0x4c, + 0x8b, 0x92, 0x13, 0x83, 0xb6, 0xed, 0x5d, 0xe3, 0x54, 0x95, 0xbe, 0x09, 0x88, 0xe9, 0x52, 0xb6, + 0x9a, 0xc1, 0xe2, 0x02, 0x16, 0xa9, 0x97, 0xad, 0x1a, 0x89, 0xb1, 0x75, 0x43, 0xc4, 0xc5, 0x0b, + 0x69, 0xa5, 0xbd, 0xaf, 0x8a, 0xa6, 0x3e, 0x90, 0x6d, 0x7c, 0x13, 0xcd, 0xbf, 0x18, 0x21, 0xec, + 0xa8, 0xf5, 0x7b, 0x63, 0xb5, 0x3c, 0x37, 0x6a, 0x5d, 0x26, 0x62, 0x61, 0x4b, 0x97, 0x36, 0x63, + 0x33, 0x73, 0xf6, 0xfd, 0xee, 0x4c, 0x45, 0xe6, 0x26, 0x33, 0x13, 0x29, 0xa8, 0xf3, 0x2e, 0xab, + 0xaa, 0xd5, 0x9c, 0x68, 0x43, 0xf8, 0xe9, 0x9a, 0xe6, 0xee, 0x90, 0x9a, 0x23, 0x90, 0x5e, 0x41, + 0x66, 0xff, 0xc1, 0x4e, 0xc6, 0x57, 0x70, 0x63, 0x6f, 0xfe, 0xdc, 0x9b, 0x07, 0xc6, 0x6e, 0x92, + 0x8e, 0xa9, 0xb6, 0x3b, 0x7f, 0x5b, 0x1a, 0x5b, 0x4d, 0x1c, 0x30, 0x18, 0x56, 0x36, 0x63, 0xc2, + 0x34, 0xc6, 0x74, 0x05, 0xaf, 0x0c, 0xf6, 0xd2, 0xc4, 0x3d, 0x5e, 0x52, 0x9d, 0x48, 0x9f, 0x0a, + 0x72, 0xe3, 0x31, 0x4f, 0x36, 0x79, 0xe5, 0x74, 0x7e, 0x45, 0xc7, 0x68, 0xd3, 0x1e, 0x17, 0xaf, + 0x7c, 0x6f, 0x8b, 0x63, 0x2c, 0x8c, 0xd2, 0x3c, 0xaf, 0x96, 0xef, 0x49, 0x7b, 0x2a, 0x67, 0x34, + 0xbb, 0xcb, 0xf2, 0x6a, 0x71, 0xf8, 0xda, 0xe3, 0x73, 0x3a, 0xab, 0xa1, 0xe7, 0x58, 0xac, 0x53, + 0xc5, 0x1c, 0x8a, 0xdf, 0xb4, 0x6a, 0xf5, 0x62, 0x95, 0x44, 0x9c, 0xf3, 0xff, 0x0a, 0x15, 0xd2, + 0x95, 0xeb, 0x3e, 0x86, 0x5c, 0xcc, 0xcd, 0xa4, 0xd9, 0xf0, 0xa7, 0xa6, 0x30, 0xad, 0x27, 0xa6, + 0x86, 0xf6, 0x09, 0xe2, 0x45, 0x34, 0x35, 0xf0, 0xa5, 0xb4, 0xdb, 0x6a, 0xc6, 0x3f, 0x53, 0xda, + 0x35, 0x54, 0x5d, 0xcc, 0x51, 0xf2, 0xf8, 0x47, 0x6d, 0xdf, 0x72, 0x41, 0x27, 0xaf, 0xe3, 0x44, + 0x52, 0xb1, 0xa5, 0x4c, 0xb2, 0x5d, 0x54, 0xad, 0x91, 0x0c, 0x1c, 0xac, 0xaa, 0x38, 0x64, 0x79, + 0x25, 0x9e, 0x3f, 0xfd, 0x95, 0x31, 0xc5, 0x9a, 0xbc, 0x28, 0x47, 0x41, 0xb4, 0xe3, 0x79, 0xaa, + 0xad, 0xac, 0xf4, 0x32, 0xed, 0x4a, 0xcf, 0xeb, 0xae, 0x93, 0xe1, 0x11, 0x76, 0x9f, 0x3e, 0xaf, + 0x91, 0x86, 0xff, 0x19, 0xd8, 0xce, 0xd5, 0xb7, 0x31, 0x57, 0xc4, 0xa9, 0x7c, 0x31, 0x2e, 0x97, + 0x5f, 0xcb, 0xad, 0x18, 0x14, 0xd3, 0x6d, 0xbf, 0xf0, 0x4f, 0xa9, 0x59, 0xad, 0x0e, 0x86, 0x4d, + 0x15, 0xac, 0x78, 0x26, 0x10, 0xf6, 0xd2, 0x7b, 0x38, 0xd2, 0xc1, 0xe4, 0x65, 0xdc, 0x48, 0x91, + 0x90, 0x03, 0x05, 0x1a, 0xcb, 0x4f, 0xef, 0xc0, 0xf0, 0x17, 0xda, 0x5a, 0xf8, 0xa6, 0x3c, 0xf0, + 0x71, 0x77, 0x2c, 0x6e, 0x3a, 0x57, 0x51, 0x6c, 0xb6, 0x7a, 0xf4, 0xca, 0x0a, 0x72, 0x79, 0xe8, + 0x00, 0xa6, 0x16, 0xcb, 0x17, 0x83, 0xab, 0xf8, 0xcf, 0xa1, 0x9d, 0x4e, 0x94, 0xdf, 0xb1, 0x91, + 0x4a, 0xe4, 0xda, 0xfa, 0x5e, 0x34, 0xa8, 0x76, 0x4f, 0x63, 0x43, 0x4f, 0x35, 0x46, 0x3e, 0xd2, + 0x7b, 0xc1, 0xcc, 0x6c, 0xbb, 0xfe, 0x14, 0xd7, 0x33, 0x28, 0x66, 0x62, 0x62, 0x3b, 0x29, 0x55, + 0xdd, 0x84, 0x89, 0xa3, 0xf5, 0xf1, 0x72, 0xf8, 0xda, 0xa7, 0xbc, 0x8c, 0x27, 0x06, 0x46, 0x1e, + 0xd8, 0x69, 0xfc, 0xb5, 0x15, 0x23, 0xb2, 0x99, 0x56, 0xb6, 0x76, 0x4c, 0x7d, 0xec, 0x4b, 0x0b, + 0xf8, 0x64, 0x8f, 0x5d, 0x0a, 0x89, 0xec, 0x7d, 0x56, 0xbe, 0x3e, 0x9b, 0xd2, 0xcc, 0xa5, 0xaf, + 0xf7, 0xc9, 0xa9, 0x78, 0xe1, 0x23, 0xd5, 0x56, 0xf6, 0xc7, 0x66, 0x92, 0x1b, 0x1a, 0x49, 0x91, + 0xbe, 0x14, 0xb2, 0x44, 0x89, 0x92, 0x19, 0xf1, 0x12, 0x3a, 0x96, 0x33, 0xfc, 0xf3, 0x6b, 0x28, + 0xf2, 0xa7, 0xc2, 0x97, 0xe4, 0xc1, 0x9d, 0xbc, 0x43, 0xb8, 0xb7, 0x2b, 0x01, 0xba, 0xb2, 0x9b, + 0xed, 0x68, 0xff, 0x70, 0xf8, 0x52, 0x33, 0x55, 0x6c, 0x6a, 0xdc, 0x37, 0xd1, 0xa1, 0xb6, 0x34, + 0xbb, 0x6d, 0xd3, 0xef, 0x85, 0x21, 0xfa, 0xe5, 0x35, 0x96, 0x59, 0x32, 0xe0, 0xca, 0xec, 0xaa, + 0xb5, 0x6f, 0x66, 0x2d, 0xc3, 0xd5, 0x46, 0x31, 0x7b, 0xbe, 0x14, 0xf9, 0x98, 0xba, 0x6c, 0x98, + 0xe8, 0xe8, 0xd8, 0xca, 0xcc, 0xd6, 0xca, 0xbe, 0x11, 0x9b, 0x2e, 0x91, 0xa1, 0xd1, 0x4c, 0xd6, + 0x3f, 0xc1, 0x61, 0x27, 0x71, 0xfb, 0x9e, 0xe8, 0x6c, 0x9b, 0x1c, 0xb7, 0xbe, 0x0b, 0x6c, 0x6d, + 0x24, 0xc6, 0x89, 0xf1, 0x8b, 0x39, 0x7c, 0x15, 0x96, 0xa3, 0x40, 0xac, 0x2e, 0xad, 0x6c, 0xdb, + 0xa1, 0xa6, 0x86, 0xf1, 0x7c, 0x29, 0x4d, 0xb4, 0xdb, 0x1e, 0xea, 0x99, 0x58, 0x6a, 0x6f, 0xec, + 0xc7, 0x2e, 0x29, 0xa9, 0xfe, 0x32, 0x86, 0xc9, 0xcb, 0x05, 0x49, 0xf0, 0x91, 0xfe, 0xbe, 0xaa, + 0xba, 0xd6, 0xab, 0x59, 0xf0, 0xcd, 0x63, 0x6f, 0xd6, 0xdb, 0x4d, 0x3f, 0xf2, 0x08, 0xb1, 0xd7, + 0xdf, 0x4c, 0x9f, 0xc1, 0x46, 0xab, 0xb1, 0xbf, 0xbe, 0x14, 0x9f, 0x5d, 0x88, 0x72, 0x7f, 0x17, + 0xa9, 0xd8, 0xf5, 0x3f, 0x84, 0xf8, 0x76, 0xdd, 0xcb, 0xf2, 0xb2, 0x4e, 0xfe, 0xfe, 0x14, 0xd5, + 0x7f, 0xc2, 0x75, 0xc9, 0x3a, 0x73, 0x62, 0xf9, 0x05, 0xd5, 0xfc, 0x40, 0x21, 0x11, 0xaa, 0x77, + 0x78, 0x90, 0x85, 0x73, 0x45, 0x26, 0x42, 0xdd, 0xaa, 0x7e, 0x1e, 0xd2, 0x4e, 0x4c, 0x2f, 0x6c, + 0x5d, 0xcb, 0x11, 0x95, 0x56, 0xae, 0x9b, 0xaf, 0xfe, 0x11, 0xcd, 0xf2, 0x75, 0x93, 0x65, 0xeb, + 0xe0, 0xac, 0xb4, 0xd5, 0x35, 0xaf, 0x35, 0x3d, 0xf0, 0x58, 0x6d, 0xda, 0xa6, 0xbc, 0xf2, 0xbb, + 0x88, 0x85, 0x29, 0xaa, 0x7b, 0x2a, 0xa1, 0xaa, 0x46, 0x7b, 0x69, 0xe3, 0x58, 0x4a, 0x7c, 0x21, + 0x7b, 0x42, 0xb9, 0x52, 0x4f, 0x5a, 0x58, 0x98, 0x2e, 0xd1, 0x9a, 0x90, 0x66, 0xa6, 0xa0, 0x1b, + 0x3e, 0x14, 0xbd, 0x74, 0x91, 0xcb, 0xb4, 0x45, 0x77, 0x54, 0x8c, 0x0d, 0x1b, 0x3b, 0xe3, 0xac, + 0x68, 0x57, 0x3f, 0x60, 0x9a, 0x05, 0xcb, 0x64, 0x77, 0xd3, 0xe0, 0xa7, 0x2c, 0x83, 0x2a, 0xa2, + 0x52, 0x64, 0xae, 0x38, 0xc3, 0x6d, 0x54, 0x0f, 0xe2, 0x2e, 0x4e, 0x37, 0xc2, 0x34, 0x4c, 0xe6, + 0x86, 0xe6, 0xec, 0x65, 0x78, 0xcb, 0x57, 0x5f, 0x05, 0x55, 0xea, 0xb7, 0x5e, 0x22, 0xdd, 0x6e, + 0xd4, 0x99, 0x46, 0xff, 0x05, 0x53, 0x66, 0xa1, 0x74, 0xf7, 0x78, 0xfc, 0xc1, 0x1b, 0x7b, 0x9f, + 0x9b, 0x0f, 0x85, 0x97, 0xe3, 0xf5, 0x32, 0xf7, 0xa6, 0xd2, 0x22, 0xc6, 0xb6, 0x89, 0x7e, 0x09, + 0xce, 0xc6, 0x2a, 0x3e, 0xdd, 0x27, 0xf8, 0x2a, 0x95, 0x86, 0x44, 0x7f, 0xb9, 0x23, 0x15, 0xf3, + 0xfc, 0x15, 0x91, 0xdb, 0xae, 0x67, 0x94, 0x92, 0x6d, 0x29, 0x71, 0xfb, 0xe3, 0x74, 0x47, 0xca, + 0xf2, 0xae, 0xc9, 0xaa, 0xcd, 0xbf, 0x41, 0xb7, 0x1e, 0xd8, 0x7b, 0x9a, 0x13, 0x39, 0x62, 0x01, + 0x49, 0x95, 0x41, 0xfe, 0x74, 0xe9, 0xbb, 0xb8, 0xcd, 0x20, 0xf8, 0x2c, 0x17, 0x63, 0x48, 0xec, + 0x11, 0x0e, 0xc6, 0xbb, 0xa5, 0xbf, 0xc1, 0x59, 0x1b, 0xe5, 0x96, 0x66, 0xe8, 0x9a, 0x4b, 0x0f, + 0x82, 0x6e, 0xe9, 0xb2, 0x5c, 0x82, 0xf8, 0x42, 0xc7, 0x36, 0x5d, 0xf4, 0xcd, 0xa8, 0x75, 0x78, + 0x48, 0xc9, 0x4d, 0x15, 0x5d, 0xb5, 0xc1, 0x37, 0x0c, 0x6b, 0x59, 0x8e, 0xd5, 0xca, 0xe1, 0x43, + 0xa3, 0xc7, 0x63, 0x3a, 0x56, 0xf9, 0xca, 0x96, 0x9b, 0xbb, 0xfc, 0x10, 0x91, 0x1b, 0x75, 0xab, + 0xb1, 0x7c, 0x24, 0x76, 0x3c, 0xb9, 0xa4, 0xbe, 0x11, 0x29, 0x24, 0x68, 0x87, 0xea, 0x39, 0xa8, + 0x67, 0x6d, 0x15, 0x79, 0x73, 0xe0, 0xb0, 0x96, 0xa9, 0xe8, 0x64, 0x79, 0xdb, 0x07, 0x46, 0x87, + 0x5f, 0x57, 0x3e, 0x0b, 0xb6, 0x32, 0xfb, 0x26, 0xd3, 0xb7, 0xcd, 0xa1, 0x9b, 0xc1, 0xf8, 0x2e, + 0x9b, 0x3d, 0x12, 0x49, 0x45, 0xf8, 0xf8, 0x4e, 0xae, 0x97, 0x3b, 0x1f, 0x17, 0x4e, 0xfa, 0xa2, + 0x6f, 0xcb, 0x4d, 0xbb, 0x7e, 0x69, 0x59, 0x6b, 0xf1, 0x7a, 0x19, 0x18, 0xa3, 0xd2, 0x6f, 0xcb, + 0xcb, 0x1f, 0x8b, 0x22, 0x1a, 0x24, 0x49, 0x26, 0x6d, 0x26, 0x7e, 0x22, 0xd9, 0x5b, 0xda, 0x5f, + 0x85, 0x2d, 0x6d, 0x29, 0x7b, 0x59, 0xdb, 0x99, 0x9a, 0xaa, 0xb5, 0x1c, 0xf8, 0x53, 0x5b, 0xc4, + 0x3e, 0xc8, 0x2a, 0xe2, 0x53, 0x8b, 0xbb, 0xc9, 0xfe, 0x2a, 0xe7, 0xe9, 0x51, 0xdd, 0xcb, 0x9e, + 0x59, 0xf3, 0x53, 0xf8, 0x52, 0x6a, 0x59, 0x2a, 0x74, 0xea, 0xb5, 0x4e, 0x6a, 0xca, 0x0a, 0xe3, + 0xb1, 0xfa, 0x17, 0x22, 0xad, 0x33, 0xfa, 0xe7, 0xf7, 0xf0, 0x55, 0xb6, 0x6a, 0x6d, 0xfb, 0x37, + 0xb6, 0x96, 0x19, 0xf0, 0x4b, 0x6a, 0xa4, 0x93, 0xab, 0xad, 0x7c, 0x10, 0x8b, 0x5d, 0xfb, 0xe1, + 0x21, 0x4a, 0x4d, 0xb4, 0xd2, 0x4a, 0x35, 0xde, 0x0b, 0x25, 0x8c, 0xb6, 0xc8, 0xcc, 0xbc, 0xcc, + 0xbd, 0xfe, 0xff, 0x05, 0x36, 0x72, 0xcc, 0x70, 0xc9, 0x36, 0xf8, 0xf1, 0xbf, 0xd5, 0xfe, 0x13, + 0x12, 0x7c, 0x53, 0xee, 0x4f, 0x5f, 0xa1, 0x09, 0x87, 0xc3, 0xd2, 0xbc, 0xc8, 0x0e, 0xad, 0x5d, + 0x47, 0x40, 0x04, 0x13, 0xdb, 0xa0, 0xcf, 0x73, 0x78, 0x50, 0x7b, 0x9f, 0x18, 0x4f, 0xb4, 0xd2, + 0x26, 0xa7, 0xe2, 0x61, 0x42, 0x68, 0x62, 0x4c, 0x2e, 0x08, 0x58, 0xbe, 0x54, 0xf7, 0x63, 0xc8, + 0x29, 0x8a, 0xa9, 0xd3, 0xa5, 0x18, 0x49, 0x4e, 0xfc, 0x15, 0x94, 0x8c, 0x67, 0xba, 0x4f, 0x65, + 0xdd, 0x50, 0x67, 0x71, 0xe4, 0x76, 0x99, 0xd3, 0xf6, 0xb3, 0xe3, 0x5a, 0xf8, 0xc3, 0xdd, 0x2f, + 0x37, 0x7d, 0xcf, 0xbe, 0x7f, 0xe0, 0xaa, 0xd7, 0x4a, 0xa8, 0x99, 0x25, 0x7d, 0x7c, 0x14, 0x4b, + 0x06, 0xb9, 0xfa, 0x6e, 0x36, 0x50, 0x7c, 0x17, 0x19, 0x84, 0x43, 0x55, 0x7b, 0xbb, 0x3e, 0x36, + 0x37, 0x57, 0xed, 0xac, 0xe6, 0x29, 0x49, 0x76, 0x59, 0xb3, 0xaf, 0xab, 0x2d, 0x9d, 0x2f, 0xf8, + 0x54, 0xa9, 0xed, 0x31, 0xab, 0x5c, 0x67, 0x0d, 0x71, 0xbf, 0xf0, 0x99, 0xa4, 0xdd, 0x8d, 0x35, + 0x43, 0x5c, 0x64, 0xcb, 0x2a, 0x5c, 0x4d, 0x78, 0xd9, 0xca, 0xa3, 0x8f, 0x54, 0x77, 0x71, 0xbb, + 0xb2, 0x98, 0xc7, 0x85, 0x29, 0x55, 0x8e, 0x61, 0x2b, 0xac, 0x77, 0xe9, 0x3e, 0x89, 0x48, 0x8c, + 0xf0, 0xd8, 0x68, 0xe4, 0x8c, 0x3a, 0x06, 0x0e, 0x72, 0x28, 0x3c, 0x39, 0x3d, 0x67, 0xed, 0xe2, + 0x01, 0x5d, 0x37, 0x1c, 0x69, 0x6e, 0x30, 0x2f, 0x32, 0xac, 0xc9, 0xee, 0x0f, 0xf6, 0x6c, 0xed, + 0xa7, 0x3e, 0x09, 0x0f, 0x99, 0xba, 0xf8, 0x2a, 0xca, 0xcc, 0xac, 0xdf, 0x43, 0x4a, 0x5d, 0x8a, + 0x2a, 0xe2, 0xc4, 0x21, 0xbb, 0x96, 0x4d, 0xb1, 0xbb, 0xcf, 0x82, 0xca, 0x52, 0xca, 0x5c, 0xe9, + 0x15, 0x18, 0xd8, 0xe8, 0xd1, 0x35, 0x56, 0x1f, 0x05, 0x7a, 0x43, 0x9f, 0x7f, 0x50, 0x5b, 0xae, + 0x1f, 0x04, 0xc3, 0x3e, 0xbc, 0xe3, 0x81, 0x61, 0x99, 0x11, 0xb6, 0xe8, 0x99, 0x6f, 0xb8, 0xb5, + 0xf0, 0xa1, 0x43, 0x4c, 0x25, 0x69, 0x14, 0x4f, 0xc4, 0xdb, 0xfa, 0xc2, 0xee, 0xd3, 0x4d, 0x98, + 0x95, 0x7c, 0x29, 0x2b, 0x0f, 0x64, 0xa4, 0xa2, 0x79, 0xbc, 0x29, 0x9c, 0x9b, 0x26, 0x64, 0x1a, + 0x16, 0x82, 0x9f, 0x85, 0x39, 0x37, 0x32, 0x8d, 0x56, 0xe1, 0xa3, 0xbd, 0x24, 0xac, 0xe5, 0xb8, + 0x30, 0x91, 0xf2, 0xf0, 0x7c, 0x15, 0x17, 0x91, 0x84, 0xf0, 0x9b, 0x3b, 0x30, 0x67, 0x6f, 0x97, + 0xc2, 0x54, 0xae, 0xdd, 0x8d, 0x0d, 0x2f, 0x09, 0xf4, 0xda, 0xda, 0x4f, 0xc6, 0x60, 0xfd, 0x94, + 0xbe, 0x92, 0x69, 0x2e, 0xc9, 0x0c, 0xb1, 0xfc, 0x3f, 0xa2, 0xba, 0x0e, 0x68, 0x5b, 0xda, 0x56, + 0xd1, 0x93, 0xff, 0xe0, 0x93, 0x44, 0xdb, 0x1c, 0x1f, 0x08, 0x65, 0x61, 0x3e, 0x9a, 0xb5, 0xb6, + 0xfe, 0x22, 0x48, 0x6d, 0x68, 0x8a, 0xc7, 0xa9, 0xd7, 0xf0, 0x5d, 0x4a, 0xd6, 0x91, 0x9b, 0x9b, + 0x1f, 0x05, 0x9b, 0x72, 0x6d, 0x28, 0xcd, 0x69, 0xf5, 0x1d, 0x4b, 0x1f, 0x04, 0xb4, 0xb4, 0x6c, + 0x79, 0x3d, 0xfe, 0x14, 0xa5, 0x2e, 0xdb, 0xae, 0x78, 0xf7, 0xa7, 0x92, 0xaf, 0x05, 0x13, 0x37, + 0xf6, 0x9a, 0x63, 0xe0, 0x84, 0xcc, 0x93, 0x4f, 0x3b, 0xec, 0xb5, 0xaf, 0x82, 0x82, 0x25, 0xa4, + 0x49, 0x6b, 0xe1, 0xf1, 0x3b, 0x53, 0xe1, 0x98, 0xe9, 0xf8, 0x4e, 0x9b, 0xcd, 0xa3, 0xaa, 0xfc, + 0xdb, 0xf6, 0x5c, 0xec, 0x57, 0x31, 0xaa, 0xbf, 0x11, 0x6a, 0xaa, 0xe9, 0x7e, 0xc6, 0x8b, 0xa5, + 0xf9, 0xb7, 0x7f, 0x98, 0xd7, 0xaf, 0x82, 0x13, 0x51, 0xba, 0xef, 0x81, 0x43, 0xf1, 0x7b, 0xa5, + 0x1a, 0x93, 0xfe, 0x84, 0xcf, 0x27, 0x11, 0x55, 0xc9, 0x95, 0xbf, 0xc8, 0x5b, 0xda, 0x7c, 0xa6, + 0x4a, 0xd3, 0xf9, 0xaf, 0x4b, 0xee, 0x5c, 0xff, 0x25, 0x93, 0x34, 0xbe, 0x8d, 0x05, 0x70, 0xd6, + 0xcc, 0xd5, 0xb2, 0x42, 0x4a, 0x17, 0xed, 0xf8, 0xcc, 0xac, 0x64, 0xd7, 0xc4, 0xf7, 0xc2, 0xa4, + 0xe1, 0x63, 0x33, 0xe8, 0xe3, 0xab, 0xcf, 0x1e, 0x20, 0x29, 0x34, 0xbf, 0x4d, 0xbd, 0xb1, 0x59, + 0x4a, 0xb9, 0x58, 0x0c, 0x3a, 0x16, 0xe2, 0xc9, 0x5c, 0x95, 0x5d, 0x7e, 0x37, 0xec, 0x6c, 0xf8, + 0x5b, 0x9a, 0xaf, 0xd2, 0x0d, 0xc2, 0x63, 0x73, 0x16, 0x8d, 0x69, 0xb2, 0xbf, 0x5c, 0xda, 0xd7, + 0xc2, 0x9a, 0xaa, 0xcc, 0x9e, 0x27, 0x06, 0x72, 0xf8, 0xa8, 0xd2, 0x4a, 0xd7, 0xc4, 0xd0, 0x6c, + 0xd1, 0xbb, 0xbd, 0xfc, 0x13, 0x16, 0x39, 0x73, 0x15, 0x9a, 0xa0, 0xa0, 0xf8, 0x9c, 0xeb, 0x26, + 0x77, 0xc1, 0x21, 0x50, 0xc1, 0xf7, 0xcb, 0x7c, 0x17, 0x4e, 0xdd, 0x8d, 0x0f, 0x33, 0x1d, 0xf0, + 0x9d, 0x3d, 0xd2, 0x6d, 0x0f, 0xe1, 0x28, 0x85, 0x98, 0xef, 0x63, 0xbf, 0x82, 0x1b, 0xdb, 0x8b, + 0xcb, 0xe0, 0x92, 0x86, 0xc4, 0x89, 0xa6, 0xf8, 0x2d, 0xa0, 0xc6, 0xe9, 0x73, 0x32, 0xef, 0xe9, + 0x7b, 0x2d, 0xd0, 0xef, 0x8b, 0x36, 0xa9, 0xde, 0xef, 0x8a, 0xa4, 0xdd, 0x27, 0xcd, 0x8a, 0x27, + 0xf0, 0x4a, 0x49, 0x7a, 0x4d, 0xc4, 0xf7, 0xc1, 0x08, 0x8e, 0x51, 0x2a, 0xd2, 0xfd, 0xf9, 0x73, + 0xc2, 0x54, 0x92, 0x77, 0xd5, 0x7c, 0x11, 0x6a, 0xb6, 0xfb, 0xde, 0xfe, 0xf4, 0xad, 0x78, 0x4b, + 0x3c, 0x1f, 0x26, 0x2f, 0xe2, 0x89, 0x9f, 0x37, 0xbf, 0x8b, 0x35, 0x27, 0xde, 0x6d, 0xf2, 0x5d, + 0xef, 0xe0, 0xb2, 0x96, 0xea, 0xa2, 0x9a, 0xea, 0xd2, 0x65, 0xe0, 0xb8, 0x4b, 0x49, 0x6d, 0x5a, + 0xb1, 0xf1, 0xd4, 0x6f, 0x44, 0xde, 0x68, 0x5b, 0xa7, 0xe1, 0xa3, 0x5a, 0xb6, 0xab, 0x46, 0x7a, + 0xfb, 0xe1, 0x3a, 0xae, 0xc6, 0xc3, 0x71, 0x9c, 0x78, 0x2a, 0x92, 0xac, 0xc6, 0x2e, 0xf1, 0x78, + 0x9f, 0xad, 0x65, 0xf1, 0x95, 0x4a, 0x3a, 0x1a, 0xd1, 0x52, 0x27, 0x89, 0x2a, 0x57, 0xc4, 0x91, + 0xf6, 0x34, 0x55, 0x5f, 0x1c, 0x53, 0xb6, 0x39, 0x44, 0x5f, 0x12, 0x31, 0xaf, 0x7a, 0xae, 0x27, + 0x2e, 0xe9, 0x5a, 0xae, 0x08, 0x4e, 0xed, 0x75, 0xf0, 0x55, 0xab, 0x69, 0xae, 0xda, 0x1b, 0x24, + 0xa9, 0x5f, 0xe0, 0xa2, 0xcc, 0xee, 0x6f, 0xa4, 0x47, 0xec, 0x4d, 0xc1, 0x35, 0x36, 0x53, 0xe1, + 0x7e, 0xd2, 0x4c, 0x5f, 0x1d, 0x5a, 0x5d, 0x24, 0x90, 0x87, 0x17, 0x88, 0xe4, 0x32, 0xd6, 0x3b, + 0x98, 0x5d, 0x6a, 0x5e, 0xc4, 0x13, 0x19, 0x99, 0x39, 0xbb, 0xb9, 0xf9, 0x08, 0xab, 0x70, 0xcf, + 0x59, 0x46, 0xf2, 0x8d, 0x55, 0x59, 0xbb, 0x1c, 0xf7, 0xbe, 0x42, 0xbd, 0xdc, 0x31, 0xc1, 0x21, + 0xef, 0x7b, 0xfc, 0x11, 0xed, 0x27, 0xaf, 0x84, 0xe9, 0xbf, 0xb6, 0xbe, 0x63, 0x52, 0x93, 0x7c, + 0x15, 0x1e, 0xd3, 0x57, 0xd1, 0x1b, 0x7b, 0x44, 0x47, 0x5e, 0x6d, 0xa5, 0xf8, 0xb2, 0x5b, 0xa4, + 0x5d, 0xcd, 0x70, 0x48, 0x4d, 0x37, 0x83, 0xec, 0x5b, 0x5b, 0xf8, 0x2b, 0x14, 0xa9, 0xda, 0x6d, + 0xac, 0xdb, 0x5b, 0x1f, 0x14, 0x2d, 0xed, 0x6f, 0x75, 0xc1, 0x09, 0x92, 0xb7, 0xaf, 0x94, 0xd2, + 0xee, 0x4e, 0x08, 0x6a, 0x38, 0xbf, 0x90, 0x7c, 0x87, 0x7b, 0x7f, 0x04, 0xc5, 0x49, 0x2d, 0xdf, + 0x7b, 0xec, 0xa2, 0xbf, 0xe0, 0xab, 0x6c, 0x47, 0xf5, 0x7f, 0x2e, 0x33, 0xe1, 0x2a, 0x5b, 0x4e, + 0xdf, 0xf1, 0x3d, 0x24, 0x9d, 0xff, 0x77, 0x49, 0x3f, 0xba, 0xdd, 0xfd, 0xeb, 0x49, 0x70, 0x99, + 0x9a, 0x4d, 0xf2, 0x41, 0x67, 0xcb, 0x69, 0x95, 0xaf, 0x09, 0x08, 0xd3, 0x4f, 0x93, 0x3d, 0x9e, + 0xab, 0xf1, 0x46, 0xa5, 0x73, 0xb1, 0xdf, 0xc1, 0x6d, 0x34, 0x93, 0x60, 0xd2, 0x52, 0xe4, 0x1c, + 0x5f, 0x0e, 0x16, 0xee, 0xea, 0x9d, 0xd3, 0xff, 0x05, 0x16, 0xdf, 0x36, 0x1c, 0x30, 0x1d, 0x3a, + 0xf1, 0x16, 0x18, 0x97, 0x33, 0xd1, 0x87, 0xf8, 0x4e, 0x7d, 0x65, 0x24, 0x6d, 0x35, 0x5c, 0x5e, + 0x66, 0xe8, 0x77, 0xbe, 0x62, 0xdb, 0xa7, 0xef, 0x43, 0x2c, 0xbf, 0x59, 0x57, 0x25, 0xd0, 0x6b, + 0xf2, 0x6c, 0x98, 0xc8, 0xdf, 0x79, 0x23, 0x69, 0xf0, 0xa1, 0x53, 0xdb, 0x4e, 0x9f, 0x77, 0x4c, + 0xfd, 0x3a, 0xef, 0xf0, 0x4b, 0x4e, 0x99, 0x7d, 0xd7, 0x5f, 0x1d, 0x51, 0xba, 0x60, 0xdd, 0xe6, + 0x7b, 0x9b, 0xf9, 0x04, 0x2e, 0xab, 0xe1, 0x13, 0xd6, 0x9d, 0xa7, 0xe9, 0xa7, 0xe1, 0x4c, 0xda, + 0xcb, 0x8e, 0x9d, 0x32, 0x65, 0x2b, 0xd2, 0xcb, 0xe0, 0xb6, 0xfb, 0x74, 0x49, 0x37, 0xdf, 0x08, + 0x53, 0x93, 0xc9, 0xf7, 0x26, 0x89, 0x7f, 0xf0, 0xa1, 0x32, 0xf4, 0x91, 0x36, 0x4d, 0xb8, 0xd7, + 0xed, 0x0a, 0xdb, 0xe3, 0x37, 0x4b, 0x2f, 0xd2, 0x2d, 0x0b, 0x4d, 0xb6, 0xeb, 0xe3, 0xea, 0x6e, + 0xde, 0xef, 0xe4, 0xed, 0x4f, 0xa3, 0xc5, 0xf0, 0x4e, 0x6d, 0xb3, 0xec, 0xdd, 0xd5, 0xac, 0x5f, + 0x1d, 0x37, 0xcf, 0x69, 0xa8, 0xdf, 0xae, 0x63, 0xa4, 0x93, 0xbf, 0x94, 0xa4, 0xcb, 0xff, 0xc1, + 0x61, 0x1d, 0x5e, 0xd5, 0xa6, 0xe5, 0xd1, 0xc5, 0xe0, 0x60, 0xf1, 0xe3, 0x39, 0xbd, 0x6a, 0xdd, + 0xb1, 0x7f, 0x04, 0xd1, 0x79, 0x98, 0x8b, 0xd6, 0xdf, 0x08, 0x84, 0x52, 0x4a, 0x9b, 0x4d, 0x6b, + 0x5f, 0x82, 0x9a, 0xdc, 0xfe, 0xd5, 0x6d, 0xdb, 0x6f, 0x82, 0x2a, 0xa6, 0x6f, 0x35, 0xf0, 0x4e, + 0x4d, 0xa3, 0xe5, 0x3a, 0x6d, 0xf1, 0x1d, 0xde, 0x4c, 0x7f, 0xc2, 0x74, 0x89, 0x95, 0x6f, 0x2e, + 0xf8, 0x2a, 0xa4, 0x93, 0xba, 0x56, 0xbc, 0x9e, 0xff, 0x09, 0xdd, 0xae, 0xd5, 0xfc, 0x7c, 0xb4, + 0x46, 0x37, 0xdc, 0x43, 0x42, 0xd1, 0xda, 0xfb, 0xfc, 0x15, 0x5d, 0xb7, 0xe6, 0x34, 0xb2, 0xad, + 0x63, 0xdb, 0x7d, 0x7c, 0x65, 0xed, 0x34, 0x91, 0x3e, 0x4c, 0x97, 0x29, 0x0e, 0x52, 0x4b, 0xe0, + 0xb3, 0x1a, 0x6e, 0xc5, 0xcd, 0x55, 0xca, 0x6c, 0xf8, 0x2b, 0x10, 0xd2, 0x18, 0xfb, 0xbb, 0xb8, + 0xae, 0xe6, 0xcc, 0xc7, 0xc1, 0x68, 0x99, 0xf3, 0xdc, 0x36, 0x62, 0xdf, 0xe1, 0x41, 0x91, 0xc8, + 0xdd, 0xd2, 0x9c, 0xc5, 0x95, 0x6b, 0x8e, 0xaf, 0x73, 0xe1, 0x42, 0xdb, 0xba, 0x4d, 0xf5, 0x37, + 0x0d, 0x37, 0x43, 0x9e, 0x6d, 0x62, 0x3c, 0x3e, 0x33, 0xa6, 0xf0, 0xf7, 0x4a, 0x06, 0xd6, 0xea, + 0x55, 0x6d, 0xee, 0x74, 0xd5, 0xbf, 0x0f, 0x6d, 0xd4, 0x7a, 0x27, 0x81, 0xb6, 0xc3, 0x95, 0x8a, + 0xfe, 0x99, 0x3f, 0x94, 0x95, 0x4b, 0xe3, 0x4a, 0x76, 0x13, 0x1d, 0x32, 0x6b, 0x5e, 0xfe, 0x6f, + 0x5b, 0xf0, 0x7d, 0x5e, 0xdd, 0x24, 0xdb, 0x38, 0xc4, 0xb0, 0x7c, 0x73, 0x13, 0xfc, 0x65, 0x0e, + 0xc6, 0x65, 0xcd, 0xaf, 0x26, 0xb5, 0xc9, 0xbe, 0x3a, 0x95, 0x92, 0x4d, 0xbd, 0x37, 0x4e, 0xaf, + 0x84, 0xed, 0xa4, 0x54, 0x19, 0x99, 0x3b, 0x3f, 0x82, 0xb3, 0xa4, 0x7c, 0x19, 0x30, 0x91, 0xd6, + 0xf6, 0x27, 0xda, 0xf2, 0x62, 0x5a, 0x1b, 0x7c, 0x29, 0xa2, 0x1d, 0xca, 0x96, 0x66, 0xed, 0x4c, + 0xb6, 0xb1, 0x33, 0xc4, 0x89, 0xbe, 0x09, 0x67, 0x6a, 0xb4, 0x75, 0x43, 0xe7, 0x92, 0xe5, 0x04, + 0xc7, 0xff, 0x85, 0x32, 0x32, 0xc7, 0x19, 0xd1, 0x01, 0xdf, 0x5a, 0xd7, 0x21, 0x52, 0x24, 0xa1, + 0x71, 0x8a, 0xa8, 0xe0, 0xf8, 0x52, 0xee, 0x35, 0x47, 0xa9, 0x62, 0xf0, 0x69, 0xbf, 0x5f, 0x84, + 0x6c, 0x1b, 0x1a, 0xc6, 0xc5, 0x6d, 0x6c, 0x1b, 0x1f, 0x0a, 0x11, 0x0c, 0x79, 0x33, 0x07, 0x46, + 0xec, 0x1b, 0x4c, 0x31, 0x87, 0x32, 0xd1, 0x98, 0x3b, 0x2a, 0xd7, 0x24, 0x71, 0xda, 0xe2, 0xf8, + 0xc9, 0xbb, 0x9e, 0x2e, 0xbd, 0xed, 0x40, 0x73, 0x06, 0x50, 0x6c, 0x32, 0x45, 0x69, 0x86, 0xb0, + 0xc6, 0xb5, 0x14, 0x0e, 0x8c, 0xdf, 0xc2, 0x94, 0x30, 0xfa, 0x9b, 0xc1, 0xd0, 0xc7, 0xd3, 0x23, + 0x59, 0xae, 0xbc, 0x3e, 0xbf, 0xf3, 0xc4, 0x8b, 0x0a, 0xff, 0xc2, 0x94, 0x2a, 0x43, 0x18, 0xd5, + 0x06, 0x99, 0x1e, 0x56, 0x15, 0x9b, 0x99, 0x57, 0x5e, 0x6a, 0x5b, 0xde, 0xb1, 0x65, 0xf0, 0xa5, + 0x0d, 0x60, 0xe3, 0x79, 0xc1, 0xd6, 0xd3, 0x78, 0xde, 0x1a, 0x89, 0xea, 0x9e, 0x89, 0x3f, 0x9c, + 0x97, 0xcc, 0x7c, 0x13, 0x73, 0x34, 0xfa, 0xa7, 0x15, 0xc2, 0x3f, 0xef, 0x82, 0xc3, 0xa7, 0x4e, + 0xf7, 0xe5, 0xed, 0xd7, 0xc1, 0x6d, 0x49, 0xcf, 0xee, 0xe4, 0xe7, 0x3e, 0xbe, 0x0a, 0xf9, 0xfb, + 0x79, 0x58, 0x1c, 0xa2, 0x1b, 0x99, 0x7e, 0x15, 0x87, 0x76, 0x24, 0x97, 0xd8, 0xa5, 0xa6, 0xdf, + 0x82, 0xd1, 0x34, 0x8d, 0x9b, 0xe9, 0xa4, 0xf8, 0x52, 0x4c, 0x54, 0xab, 0xbb, 0xb3, 0x0b, 0xba, + 0xa6, 0x4f, 0x7a, 0x49, 0x4a, 0x3f, 0xc2, 0xe6, 0x6a, 0xdd, 0xb6, 0xf7, 0x7f, 0x4c, 0xbf, 0xc6, + 0x09, 0xc9, 0x51, 0x95, 0x4c, 0xbb, 0xe3, 0x8f, 0xa7, 0x7f, 0x18, 0x63, 0x7d, 0x29, 0xb6, 0xad, + 0xd2, 0x6d, 0xa6, 0xa9, 0xf8, 0x9b, 0xf1, 0xfa, 0x74, 0xc9, 0x9e, 0xb1, 0xcf, 0x88, 0x25, 0xda, + 0xda, 0xbf, 0x8f, 0xe9, 0xb5, 0xba, 0x77, 0xbf, 0x82, 0x3d, 0xb4, 0xee, 0x3c, 0x23, 0x9f, 0x1a, + 0xeb, 0x54, 0xf7, 0xf0, 0x58, 0x3d, 0xda, 0x4d, 0x5d, 0x2c, 0x9b, 0x6b, 0x6a, 0xe2, 0x87, 0x6f, + 0x3e, 0x53, 0x11, 0xec, 0xcf, 0x04, 0xa7, 0x97, 0x45, 0xf6, 0x64, 0xa4, 0xdc, 0x95, 0xf8, 0xa2, + 0xd6, 0xaf, 0xa7, 0xe0, 0x9c, 0xb9, 0xba, 0x89, 0x60, 0xdd, 0x3e, 0x7d, 0xf1, 0x77, 0xb7, 0xe5, + 0xcf, 0x25, 0xa3, 0xe7, 0xe0, 0xaa, 0xd3, 0x69, 0xed, 0x52, 0x5a, 0xeb, 0xe5, 0xbd, 0xdf, 0xc1, + 0x15, 0x78, 0xae, 0xcf, 0x84, 0x48, 0x6e, 0xef, 0x37, 0x7d, 0x69, 0x39, 0x77, 0xcb, 0xa4, 0x91, + 0x77, 0xc5, 0x49, 0xfb, 0x6d, 0x5b, 0xf1, 0xf4, 0x9d, 0xab, 0x63, 0xb4, 0xc6, 0x92, 0x7f, 0xae, + 0x5f, 0x1e, 0x6a, 0xd2, 0xe5, 0x91, 0x76, 0x66, 0xfe, 0x30, 0xd9, 0xb3, 0x6e, 0xdc, 0x29, 0x7f, + 0x69, 0x3f, 0x12, 0x36, 0xde, 0x96, 0xdc, 0xf0, 0xf8, 0x27, 0x22, 0x4e, 0x5d, 0xdb, 0x6e, 0xdd, + 0x7c, 0x28, 0x4c, 0x22, 0x7e, 0x87, 0x24, 0x73, 0x7b, 0x9b, 0x6e, 0xcf, 0x84, 0x4a, 0xc6, 0xc7, + 0x4c, 0xac, 0x22, 0x56, 0x6e, 0xad, 0x23, 0xf6, 0x3f, 0xc6, 0xcf, 0xa4, 0xf4, 0xa2, 0x83, 0x27, + 0x43, 0x67, 0x89, 0xd2, 0x48, 0xbb, 0xb7, 0x67, 0xa9, 0xa1, 0xa2, 0x19, 0xc7, 0xf8, 0x78, 0xd7, + 0x8d, 0xc9, 0x16, 0xfd, 0x47, 0xae, 0x33, 0x54, 0x73, 0x5b, 0x75, 0x7f, 0xf0, 0x52, 0x5d, 0xba, + 0x6d, 0x34, 0x9a, 0x8e, 0x62, 0x29, 0x43, 0x28, 0x3e, 0x08, 0xf4, 0x3a, 0xf7, 0xc1, 0x4e, 0xd3, + 0xdb, 0x4b, 0x3b, 0x32, 0xb4, 0xc8, 0x3b, 0xe3, 0xed, 0x8c, 0x57, 0xf7, 0x4a, 0xd9, 0xd9, 0xb1, + 0xf8, 0x40, 0xb9, 0x19, 0x7e, 0x0f, 0x2e, 0x21, 0x19, 0x8d, 0x2f, 0x0a, 0x5b, 0x8d, 0x99, 0xb5, + 0xa3, 0x86, 0x6f, 0x8d, 0xad, 0xcd, 0x71, 0xb5, 0x75, 0x22, 0xae, 0x0d, 0xc9, 0x4e, 0xca, 0x93, + 0x1b, 0x7c, 0x28, 0x44, 0x8e, 0xcc, 0x54, 0x68, 0x6c, 0x63, 0x38, 0x58, 0x72, 0xc7, 0xd2, 0xf6, + 0xd8, 0xb1, 0xb6, 0x1d, 0xf1, 0x97, 0xb1, 0xd1, 0xf3, 0x35, 0x0f, 0x92, 0x28, 0xd0, 0xb4, 0xe5, + 0x67, 0xc6, 0x72, 0x30, 0x5d, 0x9a, 0xd3, 0x74, 0xe2, 0xdd, 0xd3, 0x43, 0x4f, 0xc2, 0x9e, 0xba, + 0x4f, 0x99, 0xa9, 0x21, 0xd0, 0xcf, 0xaf, 0x63, 0x0d, 0xdf, 0xe0, 0xaa, 0x44, 0xbb, 0xbc, 0xfe, + 0xb1, 0xb4, 0x3f, 0xb6, 0x5c, 0x8e, 0xf8, 0x52, 0x9c, 0xcc, 0x19, 0xb2, 0xc2, 0xdd, 0x33, 0x30, + 0xc4, 0xa8, 0x9a, 0xb6, 0x33, 0x8b, 0xe3, 0x74, 0x37, 0x64, 0xd2, 0x83, 0x7d, 0xa3, 0xe2, 0x9c, + 0x71, 0xeb, 0x34, 0xaa, 0x4e, 0xcb, 0xff, 0x05, 0xf4, 0xac, 0x64, 0x78, 0xd1, 0xb7, 0xc7, 0xcd, + 0xa2, 0xc1, 0x7c, 0x9f, 0xfc, 0x14, 0x96, 0x90, 0xee, 0x75, 0x24, 0x93, 0x4d, 0x45, 0x1b, 0xce, + 0xa8, 0xa6, 0xe6, 0x15, 0xaa, 0x6b, 0x9b, 0x56, 0xe7, 0xe8, 0x6b, 0xdf, 0x62, 0x1d, 0xbc, 0xbc, + 0x24, 0x54, 0xab, 0x5c, 0xbd, 0x73, 0x11, 0x69, 0x5f, 0x5e, 0x92, 0x23, 0xf4, 0x23, 0xbe, 0xfb, + 0xb9, 0x38, 0xa1, 0x27, 0xfd, 0x8e, 0xdb, 0x6b, 0x82, 0x4e, 0xda, 0x4e, 0x5f, 0x05, 0x56, 0x34, + 0xed, 0x6d, 0x8f, 0xd3, 0xb4, 0xd9, 0xda, 0x4e, 0xe8, 0x57, 0x1e, 0x42, 0xf0, 0x85, 0xd0, 0xda, + 0x8c, 0x9f, 0xf1, 0xe4, 0x5e, 0xe4, 0xe0, 0x8f, 0x3e, 0xfa, 0xf8, 0x43, 0x7f, 0x4b, 0x61, 0xb4, + 0xdb, 0x55, 0x3f, 0xfc, 0xb7, 0x54, 0x1f, 0xcb, 0x4d, 0x5a, 0xae, 0x49, 0x73, 0xf9, 0xaf, 0xb5, + 0xe4, 0x32, 0x5a, 0x5e, 0x0b, 0x84, 0xe7, 0xe9, 0x37, 0x6f, 0x07, 0xd9, 0x39, 0x7f, 0x9b, 0xcf, + 0xcb, 0xc1, 0x15, 0x34, 0xfa, 0xae, 0x8b, 0xaf, 0xab, 0x7d, 0x62, 0xae, 0x2e, 0xdd, 0xb4, 0x3b, + 0x55, 0xf2, 0x71, 0xfa, 0xbf, 0x05, 0x44, 0x73, 0xfb, 0x65, 0xfc, 0xdb, 0xa6, 0xbd, 0x5c, 0xdc, + 0xcc, 0x42, 0x5c, 0xb9, 0x98, 0xdf, 0x1f, 0x96, 0x16, 0x33, 0x6b, 0x76, 0x76, 0xa6, 0xe6, 0x10, + 0xeb, 0xf1, 0x1c, 0xfa, 0x89, 0xb5, 0xb1, 0x93, 0x89, 0xd0, 0xca, 0xcc, 0x1e, 0x68, 0x4d, 0xc2, + 0x76, 0x90, 0xed, 0x2b, 0x6a, 0xdb, 0xe5, 0x9a, 0xf6, 0x82, 0x3c, 0xd4, 0x58, 0xf2, 0xbe, 0xe8, + 0x34, 0x48, 0x94, 0x67, 0x04, 0xdc, 0x66, 0x9d, 0xb1, 0xbd, 0xe5, 0xeb, 0x2a, 0xe5, 0xe4, 0x51, + 0xf2, 0xf3, 0x37, 0xe2, 0xa6, 0x4b, 0xa1, 0x9a, 0x11, 0xe6, 0xe6, 0xcd, 0xd3, 0xcb, 0xc9, 0xda, + 0x68, 0x9c, 0xbc, 0xd1, 0xf8, 0xe9, 0x12, 0xb2, 0x6e, 0xd4, 0xf2, 0x24, 0x5e, 0xff, 0x76, 0x3c, + 0xfd, 0xd2, 0xa7, 0x7c, 0x7f, 0x4d, 0xbb, 0xb6, 0x46, 0x32, 0xe7, 0xc9, 0x45, 0x95, 0x11, 0x3a, + 0xeb, 0xe6, 0xd8, 0xd7, 0xe6, 0xd0, 0x9d, 0xcd, 0xd7, 0x2f, 0x82, 0xad, 0x0e, 0xac, 0x9d, 0xbe, + 0x5d, 0x57, 0xf9, 0x49, 0xb1, 0xa8, 0xae, 0x52, 0xf3, 0x6f, 0x9b, 0xc9, 0xfc, 0x10, 0xde, 0xc6, + 0xc7, 0x53, 0x77, 0x4f, 0x55, 0xcb, 0xa6, 0x97, 0xc2, 0x56, 0xf4, 0xa5, 0x63, 0x5c, 0x55, 0x2d, + 0x33, 0xc7, 0xdf, 0x05, 0xd4, 0x36, 0xd1, 0x66, 0x63, 0x9f, 0xee, 0x3b, 0x8e, 0xaf, 0x82, 0x19, + 0x60, 0xd7, 0xaa, 0xe0, 0x86, 0xfb, 0xbf, 0xc1, 0x0e, 0xdd, 0x70, 0x9f, 0x9b, 0x43, 0xaa, 0xee, + 0xf4, 0x5f, 0x15, 0xc7, 0x57, 0x8e, 0x66, 0x6b, 0x92, 0x95, 0x27, 0x2f, 0x35, 0x5f, 0xf1, 0x16, + 0x1d, 0xb4, 0xf3, 0xfa, 0xe6, 0xed, 0xb6, 0x5e, 0x4c, 0xf8, 0xf5, 0xf9, 0x3b, 0xa1, 0xae, 0x10, + 0xa6, 0xff, 0x3c, 0x72, 0xfb, 0xef, 0x6c, 0x88, 0x3f, 0x05, 0xb9, 0x7e, 0xdd, 0x6e, 0xf9, 0x08, + 0xd6, 0x99, 0x78, 0x25, 0x29, 0x58, 0xf2, 0xb0, 0xfc, 0x5f, 0x24, 0xec, 0x7f, 0x2e, 0x54, 0x34, + 0xfc, 0x46, 0x8a, 0xe8, 0x69, 0x21, 0xd7, 0x34, 0xbf, 0x93, 0x88, 0xbd, 0x3d, 0x0d, 0x7e, 0x0b, + 0x36, 0x36, 0x37, 0x5a, 0x5d, 0x0d, 0x5e, 0x0e, 0x60, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x33, + 0x19, 0xb0, 0x7a, 0x15, 0xd9, 0xaf, 0x7f, 0x76, 0xd5, 0xb4, 0x22, 0x77, 0x4f, 0x73, 0xf4, 0x11, + 0x63, 0xe8, 0xef, 0x7d, 0x13, 0x2f, 0xaf, 0x5f, 0x46, 0x7f, 0xab, 0x90, 0xbf, 0x42, 0xef, 0x37, + 0x30, 0x59, 0x3d, 0xa3, 0x71, 0x62, 0xde, 0x46, 0xdb, 0x9e, 0x89, 0xfb, 0x35, 0xdf, 0xe5, 0xbd, + 0xdc, 0x46, 0x10, 0xbe, 0x86, 0xbd, 0xf5, 0x7f, 0xa2, 0x77, 0xd5, 0xe2, 0x39, 0x84, 0x5a, 0x4b, + 0xe2, 0xe9, 0xd8, 0x32, 0x55, 0x34, 0x3c, 0xf1, 0x17, 0xd0, 0x4f, 0xbe, 0xbd, 0xf5, 0x7a, 0xea, + 0x8f, 0x3e, 0x0b, 0x02, 0x92, 0xeb, 0x1b, 0xfe, 0x86, 0x76, 0x92, 0x31, 0xd7, 0x8b, 0xe1, 0x1e, + 0x33, 0x95, 0xb7, 0xb5, 0x15, 0xaf, 0x82, 0x9b, 0xb1, 0xce, 0xc3, 0xf4, 0xed, 0x3a, 0x2d, 0xfe, + 0x0a, 0xbb, 0xa6, 0x4c, 0xf9, 0x7a, 0x7b, 0xbe, 0x2c, 0xed, 0xdb, 0x49, 0x6f, 0xf0, 0x4b, 0xce, + 0xd6, 0xed, 0xdf, 0x5f, 0x08, 0xda, 0x23, 0x09, 0xc7, 0x26, 0x76, 0xdb, 0xaf, 0x84, 0x44, 0x30, + 0x68, 0x52, 0xe2, 0x65, 0xa2, 0x5b, 0xe7, 0x22, 0x3c, 0xcf, 0xc6, 0xc6, 0x6e, 0x3d, 0x5e, 0x3b, + 0x47, 0x3b, 0xee, 0x08, 0xd6, 0xb4, 0xcb, 0x7b, 0x16, 0x48, 0xbb, 0x73, 0xb4, 0xf1, 0x7f, 0x1c, + 0xef, 0xc2, 0x96, 0xe3, 0xf7, 0xe8, 0x43, 0xdb, 0x5b, 0xef, 0xac, 0x9c, 0xb8, 0xc8, 0xa5, 0x89, + 0x28, 0xbe, 0x3c, 0x4c, 0x5b, 0xbb, 0x2d, 0xa6, 0xff, 0x1a, 0x22, 0xb5, 0xa5, 0x5e, 0x58, 0xcb, + 0xdf, 0x8d, 0x09, 0x83, 0xaa, 0xa0, 0x42, 0x9c, 0xf1, 0x7f, 0xf1, 0xb4, 0xdd, 0x6a, 0x6b, 0x54, + 0x3b, 0xd5, 0x7f, 0xb8, 0x1a, 0x11, 0xa0, 0x49, 0x72, 0xac, 0x8b, 0x69, 0xdb, 0x15, 0x6d, 0xfe, + 0x19, 0xa0, 0x32, 0x08, 0x95, 0xb4, 0xfd, 0x53, 0xf6, 0xf7, 0x27, 0x4e, 0x3f, 0x0a, 0x16, 0x47, + 0xa2, 0x5b, 0x0e, 0xf5, 0x99, 0xc6, 0x39, 0x3a, 0xe5, 0x97, 0x67, 0xbf, 0x33, 0x6a, 0x7a, 0xf8, + 0x29, 0xd1, 0x17, 0xd2, 0x9b, 0x03, 0x28, 0xf7, 0x72, 0xe3, 0x70, 0x80, 0x2f, 0x5e, 0x8c, 0xdf, + 0x13, 0x32, 0x49, 0x7d, 0x0c, 0xcf, 0xfc, 0x11, 0x8b, 0x18, 0xed, 0xd5, 0x35, 0x70, 0xae, 0x20, + 0x6e, 0xab, 0xaa, 0xae, 0x2c, 0x8a, 0xbf, 0x3e, 0xfa, 0x22, 0x7f, 0x12, 0x08, 0xcb, 0xbb, 0xb9, + 0xf5, 0x72, 0xba, 0xb9, 0xf0, 0x44, 0x78, 0xc7, 0xb9, 0xd5, 0xe2, 0x15, 0x9f, 0x0a, 0x06, 0x89, + 0xdb, 0x73, 0x49, 0x0a, 0xfb, 0xb7, 0x46, 0x39, 0x57, 0x0a, 0x9b, 0x28, 0xc7, 0xc6, 0x09, 0x95, + 0xcc, 0xa1, 0xa7, 0x96, 0x7c, 0xb5, 0xb6, 0xdf, 0xc3, 0xf3, 0xb2, 0xfd, 0x24, 0xfd, 0x34, 0xd4, + 0x1f, 0xf4, 0xe5, 0xa7, 0xf8, 0x24, 0xda, 0x34, 0xe1, 0xb3, 0xe3, 0x6d, 0xa7, 0x5e, 0x58, 0x5a, + 0x4a, 0xc2, 0x5d, 0x98, 0xcc, 0x73, 0x22, 0xbe, 0xda, 0x23, 0xff, 0xc3, 0xc6, 0x4c, 0xf4, 0xec, + 0x19, 0xbd, 0x85, 0x33, 0x58, 0xd8, 0xe5, 0x47, 0x3d, 0xa3, 0xff, 0x0f, 0x89, 0xb1, 0xa3, 0x58, + 0x36, 0x51, 0x0c, 0xda, 0x67, 0xe5, 0x97, 0x7d, 0x53, 0x56, 0xfc, 0x3a, 0x43, 0xb9, 0x0e, 0xd9, + 0xfb, 0x1d, 0x61, 0x87, 0xf2, 0x7d, 0x4f, 0x65, 0x11, 0x6b, 0x10, 0xe0, 0xab, 0x1b, 0x34, 0xac, + 0x5f, 0xf0, 0xf9, 0x52, 0xaf, 0x6c, 0x76, 0xe7, 0xd5, 0x92, 0x6d, 0xb8, 0x64, 0x6a, 0x43, 0x94, + 0xd2, 0x9b, 0x7c, 0x6e, 0xcc, 0xd4, 0x55, 0x9d, 0xbd, 0xb8, 0xa1, 0xa4, 0xce, 0x58, 0xbb, 0xe2, + 0xe4, 0xb5, 0x07, 0x7f, 0x7b, 0xe3, 0x2f, 0xf1, 0x95, 0x24, 0x28, 0x92, 0x4b, 0x3e, 0xba, 0x39, + 0x35, 0x27, 0xab, 0xe1, 0xda, 0x27, 0xc9, 0x2f, 0x3f, 0xce, 0xb3, 0x3f, 0x66, 0xaf, 0xbf, 0xd1, + 0x35, 0xf0, 0x44, 0x74, 0xab, 0x98, 0x78, 0x2e, 0x23, 0x63, 0xfe, 0x47, 0xd5, 0x1f, 0xbe, 0x1f, + 0x12, 0xd5, 0x12, 0x6a, 0x5c, 0x27, 0x6e, 0x27, 0xae, 0xef, 0xa7, 0x76, 0xfc, 0x31, 0x6d, 0x53, + 0x97, 0x1d, 0x25, 0x21, 0x7d, 0x32, 0xfb, 0xf8, 0xd3, 0x27, 0xa6, 0x6f, 0x77, 0x9e, 0x11, 0xb6, + 0xbb, 0x5f, 0x2b, 0x15, 0x89, 0xd2, 0x23, 0x4f, 0xf0, 0xb0, 0x89, 0xe4, 0x75, 0x50, 0x66, 0x55, + 0xa1, 0xd3, 0x2f, 0x6d, 0x6b, 0xe1, 0xc0, 0x9a, 0xd6, 0xe7, 0x2f, 0x4f, 0xfd, 0x62, 0xfa, 0x2b, + 0x94, 0x3c, 0x9c, 0x6d, 0x3f, 0xfc, 0x28, 0x1e, 0x77, 0xb2, 0xeb, 0xaa, 0x8d, 0xf6, 0xdb, 0xdb, + 0xad, 0x65, 0x4f, 0x84, 0xed, 0x3e, 0x86, 0xe6, 0x7f, 0xe3, 0x8f, 0x3b, 0x36, 0x3d, 0x5b, 0x97, + 0x5f, 0xf0, 0xa1, 0x4e, 0xca, 0x6f, 0x66, 0x36, 0xaa, 0x94, 0x9b, 0xc7, 0x68, 0xda, 0xff, 0x1c, + 0x26, 0x58, 0xea, 0xf2, 0xaa, 0x24, 0x8b, 0x8a, 0xad, 0x6b, 0xf1, 0xa3, 0x13, 0x33, 0x39, 0x62, + 0xa3, 0xf7, 0x77, 0x6d, 0x23, 0x64, 0xd9, 0x2a, 0xaa, 0x66, 0xef, 0xa3, 0xcb, 0xc9, 0x4f, 0x18, + 0x35, 0xea, 0xad, 0xb6, 0xd0, 0xb6, 0xf8, 0x5e, 0xac, 0x78, 0x8a, 0xc7, 0x8f, 0xed, 0xb4, 0xb1, + 0xdd, 0x24, 0x8b, 0x8d, 0xcf, 0x08, 0x92, 0x93, 0x69, 0x5b, 0x7b, 0xad, 0x3f, 0x2d, 0x3a, 0x7f, + 0x1d, 0x4d, 0xa3, 0x7a, 0x8f, 0x9a, 0x93, 0x17, 0xfc, 0x48, 0xc1, 0x5a, 0x1b, 0xa3, 0x6c, 0xe2, + 0x9d, 0xd2, 0xb9, 0xe7, 0x61, 0x28, 0x5e, 0x0b, 0x7b, 0xb6, 0x68, 0x35, 0x02, 0x18, 0x8b, 0xb3, + 0xe0, 0x9c, 0x4b, 0xea, 0xd3, 0xd5, 0xfe, 0x3b, 0xa5, 0x78, 0xc2, 0xca, 0xd9, 0x8f, 0x75, 0xf0, + 0x58, 0x5c, 0xac, 0x35, 0xbb, 0x1c, 0xd8, 0xdb, 0xb2, 0x2f, 0x84, 0x79, 0x2d, 0x1b, 0xef, 0x57, + 0x6b, 0xc2, 0x61, 0x04, 0x92, 0x97, 0x1e, 0x99, 0x37, 0xc5, 0xe4, 0xcd, 0xbc, 0x6b, 0x4f, 0x04, + 0xc3, 0xd5, 0x75, 0xbe, 0xb7, 0x3e, 0x6d, 0x4d, 0x74, 0xfc, 0x14, 0x0c, 0xb8, 0x87, 0xdb, 0x24, + 0xc9, 0x38, 0x4d, 0xf0, 0x56, 0x54, 0x9b, 0x79, 0x1f, 0xc6, 0xd5, 0x2e, 0xec, 0xfa, 0x0a, 0x8a, + 0xa5, 0x4a, 0x22, 0x09, 0x08, 0xf7, 0xc7, 0x30, 0x91, 0x2c, 0x47, 0x42, 0xc7, 0x97, 0x7a, 0x7f, + 0x45, 0x75, 0xf1, 0x81, 0x8c, 0xdd, 0xeb, 0xd3, 0x4e, 0x7f, 0x13, 0x2a, 0x1c, 0xac, 0x7c, 0x2e, + 0x73, 0x79, 0x5a, 0x39, 0x71, 0xb4, 0x22, 0x3e, 0xc7, 0x71, 0xc3, 0x2f, 0xf0, 0xf5, 0xba, 0xfc, + 0x99, 0xae, 0xdd, 0xb5, 0x6c, 0xdb, 0xab, 0x7b, 0xe6, 0xaa, 0xea, 0xfe, 0x36, 0x8a, 0x53, 0x83, + 0xda, 0xd2, 0xc6, 0x35, 0x4c, 0xab, 0xfe, 0x86, 0x5a, 0xd0, 0x6f, 0xac, 0xea, 0x74, 0xc6, 0x4d, + 0x58, 0xb5, 0x5a, 0x63, 0xf9, 0xf8, 0x50, 0x95, 0x6e, 0xc5, 0xb6, 0x9f, 0x23, 0xd3, 0xf2, 0x39, + 0x2d, 0xfe, 0x36, 0x90, 0xd7, 0x33, 0x8d, 0xd5, 0xdb, 0x41, 0xca, 0x69, 0xd3, 0x7c, 0xe2, 0xa4, + 0x49, 0x6c, 0x46, 0x4d, 0x35, 0xab, 0xfe, 0x54, 0x47, 0xcf, 0xc1, 0x4d, 0x28, 0xa3, 0xcb, 0xd3, + 0xf7, 0x4e, 0x2f, 0x8d, 0xb5, 0x96, 0x3e, 0xaa, 0xc9, 0x1c, 0xda, 0xf8, 0xfe, 0x7a, 0xc2, 0x74, + 0x06, 0xfd, 0xff, 0x85, 0x8b, 0x9f, 0x9b, 0x52, 0xcf, 0x86, 0x81, 0xed, 0x3a, 0x21, 0xde, 0xff, + 0x1a, 0x57, 0x7c, 0xfb, 0x51, 0x76, 0x22, 0x51, 0x36, 0x34, 0x3d, 0xc5, 0x6b, 0x07, 0x7e, 0x1b, + 0x7f, 0xc3, 0xa5, 0xd5, 0x6e, 0x91, 0x9a, 0x2b, 0xad, 0xc1, 0xfa, 0xb7, 0xff, 0xe0, 0xa4, 0xd4, + 0xd2, 0xa6, 0x9e, 0xab, 0xa2, 0xb5, 0xe0, 0xc2, 0xc9, 0x93, 0x97, 0xb3, 0x72, 0x51, 0xf1, 0x48, + 0x01, 0x9e, 0x3b, 0x6f, 0x3f, 0xff, 0x0e, 0xed, 0x34, 0x77, 0x52, 0x0b, 0x57, 0xa6, 0xb4, 0xcd, + 0x3e, 0x7f, 0xfe, 0x36, 0xe8, 0xaa, 0x68, 0xb4, 0xf6, 0xe7, 0x87, 0x26, 0x12, 0xda, 0xef, 0x3d, + 0x09, 0xe7, 0xff, 0x04, 0xda, 0xb2, 0x62, 0xca, 0x46, 0x65, 0xac, 0x20, 0x23, 0xe2, 0xce, 0xda, + 0x57, 0xa6, 0xff, 0x14, 0x39, 0x1c, 0x7a, 0xc5, 0xd2, 0xd7, 0xc1, 0x2e, 0x56, 0x5e, 0x93, 0x1a, + 0xb5, 0x4c, 0x1e, 0x0b, 0x82, 0x6b, 0x57, 0x7b, 0xbf, 0x9f, 0x45, 0x48, 0xc9, 0xc2, 0x61, 0xaa, + 0x93, 0x23, 0x4c, 0xb9, 0xf8, 0x2e, 0xd0, 0x92, 0x49, 0x88, 0xf1, 0x65, 0x5b, 0xbe, 0x5d, 0x55, + 0x35, 0xc1, 0x20, 0xb4, 0xcb, 0xff, 0x7c, 0xc4, 0x6d, 0xa6, 0xd5, 0x70, 0x5a, 0x74, 0xfa, 0x64, + 0xdd, 0xb6, 0xf8, 0x4a, 0xbb, 0xe9, 0xbf, 0x8a, 0x26, 0xdb, 0xe7, 0xdf, 0x98, 0x55, 0xa8, 0xbf, + 0x84, 0x4b, 0x97, 0x38, 0x9e, 0x26, 0x93, 0x76, 0x5e, 0x08, 0xf6, 0x4f, 0x7f, 0x12, 0x12, 0xdd, + 0xdd, 0x8d, 0x35, 0xf9, 0x65, 0x8a, 0x4c, 0xbe, 0x28, 0xaf, 0x17, 0x59, 0x58, 0xf0, 0x48, 0x74, + 0x97, 0xc3, 0xe5, 0x22, 0xd6, 0xb9, 0x86, 0x3b, 0xfe, 0x5b, 0xbf, 0xe0, 0x84, 0xae, 0xfb, 0xfc, + 0x4d, 0x15, 0x48, 0xa7, 0xfd, 0xf4, 0x13, 0xef, 0xa3, 0xa7, 0x1f, 0x20, 0x5a, 0xa9, 0xa1, 0xf9, + 0x48, 0x95, 0xeb, 0x82, 0x42, 0xee, 0x86, 0xc7, 0xde, 0x7c, 0xfc, 0x95, 0xa3, 0x24, 0xd7, 0x3e, + 0x0a, 0x6d, 0x57, 0xfd, 0xd6, 0xdf, 0xc1, 0x76, 0xea, 0x9e, 0x9a, 0x7a, 0xf8, 0x24, 0xed, 0xa5, + 0xaf, 0x98, 0xaf, 0xbf, 0xab, 0xbe, 0x1e, 0xcb, 0xe8, 0xdb, 0x8e, 0x69, 0xe9, 0xd5, 0xba, 0x8f, + 0xeb, 0xeb, 0x82, 0x0b, 0x52, 0x77, 0x66, 0x8b, 0x74, 0x99, 0x53, 0xfd, 0x25, 0x92, 0x4f, 0xfa, + 0xe8, 0xae, 0x57, 0x21, 0x2a, 0xff, 0x05, 0x44, 0x97, 0x69, 0x0c, 0x79, 0xb5, 0xd6, 0x4c, 0xbb, + 0x8f, 0x2f, 0x6d, 0x2f, 0x04, 0x85, 0xcb, 0x94, 0xec, 0x21, 0xca, 0x2a, 0xb5, 0x58, 0x9b, 0xe5, + 0xe5, 0x91, 0x38, 0xce, 0x5d, 0x6a, 0x1d, 0xef, 0x7b, 0xf9, 0xb5, 0xa9, 0x39, 0xb5, 0xa9, 0xba, + 0xbb, 0xe2, 0xfc, 0x5e, 0xab, 0xf7, 0x3a, 0x18, 0x48, 0xa6, 0xe6, 0x1f, 0xc7, 0xb7, 0xc4, 0xf8, + 0x99, 0x30, 0x88, 0xa1, 0xd6, 0xd4, 0xbe, 0x66, 0x29, 0x71, 0x22, 0x6f, 0xbf, 0x07, 0xbc, 0x70, + 0xef, 0x31, 0x5e, 0xd5, 0x73, 0x55, 0x73, 0x72, 0x52, 0xa5, 0xf0, 0x9d, 0xcb, 0x87, 0xcf, 0x6c, + 0x68, 0xcf, 0xc4, 0x4c, 0xc7, 0x21, 0x05, 0x2f, 0xdc, 0x99, 0xe5, 0xe6, 0x17, 0xcd, 0xfc, 0xc7, + 0xe6, 0xf8, 0x81, 0x26, 0x19, 0xbb, 0xe2, 0x20, 0x88, 0x89, 0x1a, 0x9b, 0x9f, 0x19, 0x78, 0xea, + 0xda, 0xc7, 0xb0, 0x9a, 0xa6, 0x54, 0x96, 0x3c, 0xfb, 0x07, 0xee, 0x49, 0x88, 0x10, 0x52, 0xe1, + 0x23, 0x5c, 0xde, 0x26, 0x2b, 0xbb, 0xca, 0x72, 0x49, 0xf0, 0x88, 0x50, 0xd8, 0xac, 0x56, 0x34, + 0xb1, 0xbd, 0x4c, 0xbf, 0x27, 0xd2, 0x7b, 0x51, 0xce, 0x08, 0x02, 0x23, 0xa3, 0x8a, 0x3b, 0xe3, + 0x31, 0x9b, 0x0c, 0xba, 0x5b, 0xb8, 0x5f, 0x08, 0x85, 0x25, 0x13, 0xf0, 0x37, 0x78, 0x70, 0xb8, + 0x96, 0x2e, 0x84, 0x0f, 0x52, 0x8a, 0xe5, 0xe5, 0xac, 0x18, 0x75, 0x7f, 0x04, 0x6d, 0x69, 0x22, + 0xdf, 0x12, 0x14, 0xee, 0xf7, 0x3f, 0x8f, 0x12, 0xd0, 0xaf, 0x36, 0x52, 0x5b, 0x47, 0xff, 0xdf, + 0x2c, 0x98, 0x6e, 0xb8, 0x73, 0x98, 0xab, 0x5b, 0xe6, 0x3f, 0x2f, 0xf1, 0x7d, 0xdf, 0x77, 0x7c, + 0xbc, 0x74, 0xd1, 0xf8, 0x46, 0x86, 0x4e, 0x4c, 0x67, 0x4d, 0xee, 0xff, 0x18, 0x64, 0xe9, 0x0a, + 0xc6, 0xf2, 0x5a, 0x28, 0xf7, 0x2f, 0x9e, 0x52, 0x4b, 0xc9, 0xae, 0xa7, 0x6a, 0xcf, 0x8b, 0x29, + 0xe0, 0xec, 0x83, 0xa9, 0x9b, 0x17, 0xc2, 0x13, 0x7d, 0x5b, 0x56, 0x63, 0x9e, 0x5b, 0x31, 0x2f, + 0x2d, 0xf7, 0x51, 0x3f, 0x9a, 0x7c, 0x59, 0x37, 0x11, 0x15, 0x8d, 0x26, 0x33, 0x0d, 0x51, 0xae, + 0xf8, 0x98, 0xe3, 0x78, 0x51, 0x58, 0x1d, 0x9a, 0xb4, 0x30, 0x1a, 0xfb, 0x7f, 0x10, 0x0b, 0x0a, + 0x4c, 0x26, 0x6b, 0x26, 0x6f, 0x77, 0x1e, 0x09, 0x62, 0xe2, 0x43, 0xe9, 0x41, 0xc4, 0x43, 0x2f, + 0xb6, 0x38, 0x88, 0x2b, 0x8a, 0x5a, 0x6b, 0x4a, 0x0e, 0x8f, 0x77, 0x66, 0x91, 0x30, 0xf9, 0x7a, + 0x5f, 0x85, 0x34, 0xda, 0x2f, 0x37, 0x2c, 0xdf, 0xc9, 0x6b, 0x3b, 0xbe, 0x6d, 0x31, 0xc2, 0x21, + 0x01, 0xb3, 0x50, 0x0b, 0x1d, 0x2b, 0x14, 0x25, 0x13, 0x05, 0x80, 0x28, 0x41, 0x10, 0xb5, 0x66, + 0x88, 0x85, 0x80, 0x90, 0xd1, 0x70, 0xb5, 0x88, 0x00, 0x6a, 0x4d, 0xd0, 0x5e, 0x44, 0x77, 0x58, + 0x6a, 0xa2, 0x88, 0x4a, 0x1a, 0xb4, 0x9a, 0x1c, 0x1b, 0x17, 0x98, 0x49, 0xc4, 0x3d, 0x05, 0xdc, + 0x25, 0xf5, 0x5a, 0x78, 0x34, 0x44, 0x17, 0xc6, 0xf8, 0x62, 0x78, 0xda, 0x62, 0xb7, 0xb0, 0x80, + 0x91, 0xb6, 0x46, 0xf1, 0x22, 0xe2, 0x51, 0x2f, 0x1f, 0xc6, 0xf1, 0x46, 0x7f, 0x1f, 0x81, 0xdb, + 0x86, 0x02, 0x75, 0x89, 0xff, 0x02, 0x8e, 0x2f, 0x94, 0x0d, 0xa9, 0x3e, 0x19, 0xa7, 0x8a, 0x82, + 0x1f, 0x34, 0xe3, 0xdc, 0x00, 0x87, 0xa7, 0x53, 0xd7, 0x35, 0x9a, 0x51, 0x3c, 0x00, 0x21, 0x78, + 0x68, 0x32, 0x3c, 0xc8, 0x4b, 0x11, 0xbd, 0xe6, 0x6e, 0xe2, 0xfc, 0x22, 0x14, 0x88, 0x1c, 0x2c, + 0x19, 0x60, 0xc4, 0x0f, 0x2d, 0x85, 0x1e, 0x34, 0x5b, 0x32, 0x12, 0xe8, 0xf7, 0x2f, 0xb0, 0xb5, + 0x43, 0x6e, 0x0e, 0x15, 0x40, 0x8f, 0xa2, 0x91, 0x03, 0x6f, 0x23, 0x1f, 0x12, 0x32, 0xe1, 0xb0, + 0x77, 0x7c, 0xb2, 0x29, 0x90, 0xb1, 0x54, 0xae, 0x22, 0x3c, 0xaf, 0x61, 0xdc, 0x36, 0x1c, 0x65, + 0xe4, 0xb3, 0xa8, 0xdc, 0xf3, 0x98, 0x40, 0x32, 0x34, 0x92, 0xa5, 0x6b, 0x00, 0xfd, 0x97, 0x05, + 0xb8, 0x14, 0x10, 0x2e, 0x2c, 0xdd, 0x52, 0x9c, 0xc8, 0x2e, 0xe2, 0xdd, 0x92, 0x77, 0x36, 0xdc, + 0x9b, 0x46, 0xe0, 0x0b, 0x62, 0xb3, 0x56, 0x3f, 0xf0, 0xd9, 0x53, 0x85, 0xc1, 0x20, 0xc9, 0x6c, + 0x2d, 0xa9, 0x14, 0x61, 0x47, 0xb0, 0xb7, 0x04, 0xb6, 0x45, 0xd6, 0x55, 0xbe, 0xd3, 0xbe, 0x09, + 0xcb, 0x59, 0x98, 0xaa, 0xd3, 0xa5, 0xc6, 0x54, 0x9d, 0x0b, 0xd0, 0xc9, 0x88, 0x88, 0xbd, 0x63, + 0xd5, 0x3f, 0x19, 0x74, 0xad, 0xf6, 0x8e, 0xc6, 0x9b, 0x68, 0x97, 0xe7, 0x9f, 0x0a, 0xeb, 0x4d, + 0x56, 0xa5, 0x4f, 0x92, 0x28, 0xe2, 0xbf, 0x09, 0x93, 0x55, 0x55, 0xfc, 0xa7, 0xc7, 0x96, 0x57, + 0x21, 0x9e, 0x7f, 0xf0, 0x96, 0xd2, 0x5a, 0x4b, 0xf3, 0x56, 0xbf, 0x2e, 0x74, 0x93, 0xa4, 0x5c, + 0x29, 0xbd, 0xea, 0xeb, 0x15, 0xee, 0xfb, 0x9f, 0x5e, 0xf8, 0x2d, 0x12, 0x0e, 0xd8, 0x7f, 0x29, + 0x3d, 0x79, 0x7c, 0x29, 0x12, 0x70, 0xbe, 0x60, 0xd5, 0x78, 0xaa, 0x5e, 0xf7, 0x73, 0xfb, 0x49, + 0xe2, 0xbc, 0xdc, 0x44, 0x6c, 0xb5, 0x1b, 0x49, 0x91, 0x9a, 0x01, 0x5b, 0x18, 0xa2, 0x1e, 0x78, + 0xdd, 0x3c, 0x6c, 0x76, 0xc8, 0xab, 0xf2, 0xfb, 0xf3, 0xed, 0xaf, 0x1e, 0x49, 0x54, 0xf6, 0x92, + 0x49, 0xc5, 0x74, 0x3f, 0x18, 0x65, 0x54, 0x96, 0x93, 0x71, 0x59, 0x70, 0xbf, 0x7f, 0xfe, 0x1a, + 0x08, 0xc0, 0x44, 0x2b, 0x4c, 0x7d, 0xee, 0x0c, 0x73, 0x44, 0xf5, 0x0d, 0x3e, 0xce, 0x22, 0x0a, + 0xc7, 0x65, 0xcf, 0x84, 0x78, 0x42, 0xce, 0x55, 0x79, 0x40, 0x12, 0x23, 0x39, 0xed, 0x57, 0xde, + 0x24, 0x28, 0x5a, 0xd5, 0x54, 0xac, 0xcd, 0xb3, 0xf1, 0x7b, 0xaf, 0x96, 0xe5, 0xf4, 0xc1, 0xda, + 0x87, 0x0f, 0xe1, 0xb2, 0x13, 0x01, 0x91, 0xe4, 0x40, 0x07, 0x1c, 0xf1, 0xdc, 0x14, 0xe3, 0x6b, + 0xff, 0xa2, 0xbd, 0x62, 0x01, 0x4e, 0x67, 0x2f, 0x31, 0x07, 0x7d, 0xd8, 0xf0, 0x40, 0x34, 0x87, + 0x8c, 0xf1, 0x8a, 0xc2, 0xae, 0x17, 0xb4, 0x39, 0x60, 0x54, 0x9c, 0x6d, 0xa6, 0xe0, 0x1b, 0x9f, + 0x21, 0x11, 0xde, 0xda, 0x3c, 0xc2, 0x4a, 0x57, 0xf8, 0x40, 0x27, 0x23, 0x8f, 0xd1, 0xfb, 0x67, + 0x97, 0x38, 0x40, 0x29, 0xd0, 0x41, 0x10, 0xbc, 0x65, 0x7a, 0xe0, 0x64, 0xc1, 0x51, 0x75, 0xe4, + 0xce, 0x24, 0xc9, 0xb0, 0x81, 0x67, 0xb7, 0xdc, 0x5d, 0x26, 0xb1, 0x24, 0x9f, 0x7a, 0x60, 0xe1, + 0x91, 0x9d, 0x98, 0x0b, 0x00, 0x9c, 0x47, 0x76, 0xe7, 0x06, 0xfc, 0xd6, 0xc7, 0x70, 0x31, 0x91, + 0x82, 0x8d, 0x6c, 0xc5, 0xd4, 0xd6, 0x1c, 0x87, 0xad, 0xa6, 0xcd, 0x91, 0x8f, 0xa4, 0x6a, 0xba, + 0x43, 0xec, 0x69, 0xf8, 0x64, 0x6e, 0x73, 0x16, 0x74, 0x67, 0xac, 0x47, 0x83, 0x23, 0xe0, 0xeb, + 0xd5, 0x19, 0xe2, 0xd0, 0xb0, 0xe5, 0x86, 0x63, 0x7d, 0xaa, 0x51, 0xe2, 0xce, 0x2a, 0x5e, 0x0c, + 0x75, 0x95, 0x3f, 0x7c, 0xfc, 0x2a, 0x36, 0x37, 0x8f, 0x12, 0x5a, 0xfb, 0x71, 0x6e, 0x4e, 0x0c, + 0x29, 0xcf, 0xbb, 0x54, 0xd7, 0xcb, 0x93, 0xf3, 0x7f, 0x26, 0x95, 0xaf, 0x04, 0x92, 0x4b, 0xe1, + 0x13, 0xca, 0x33, 0x63, 0x2a, 0xcb, 0x90, 0x4c, 0xec, 0xb1, 0xfe, 0x42, 0x21, 0xa4, 0x87, 0xf0, + 0x87, 0x77, 0xbb, 0x95, 0x86, 0x34, 0xab, 0xf8, 0x23, 0x2d, 0x35, 0xc5, 0xf0, 0x5b, 0x66, 0x6a, + 0x52, 0x5b, 0x76, 0x3e, 0x14, 0x37, 0x9a, 0x89, 0xbe, 0x7a, 0x37, 0x1f, 0x2d, 0x36, 0x7c, 0x15, + 0x74, 0x33, 0xd0, 0xff, 0xb3, 0x39, 0x07, 0x73, 0xc0, 0x9f, 0xe3, 0x6d, 0xab, 0x4a, 0xd0, 0xe6, + 0x17, 0xe3, 0x90, 0x85, 0x59, 0x4d, 0x53, 0x3f, 0xcb, 0x4a, 0x25, 0xf0, 0x81, 0x72, 0x37, 0x59, + 0x1a, 0x8a, 0x9b, 0x0d, 0xaf, 0x19, 0x45, 0x55, 0x54, 0x35, 0xa3, 0x46, 0xcd, 0x9a, 0x44, 0x44, + 0xc7, 0x7e, 0x0a, 0x09, 0xb3, 0x74, 0x22, 0xee, 0xef, 0x82, 0x2e, 0xc6, 0xbd, 0xe2, 0x46, 0x14, + 0xbc, 0xe4, 0x1d, 0xee, 0xfe, 0x66, 0x1c, 0xf9, 0x93, 0x3c, 0x16, 0x1e, 0x9d, 0x2c, 0x1f, 0xe4, + 0xad, 0xd2, 0xb3, 0xe0, 0xaf, 0x74, 0xfb, 0x69, 0xe3, 0x6a, 0xdc, 0x6f, 0x82, 0x8b, 0x4b, 0x2a, + 0xb0, 0xdf, 0x65, 0xd7, 0xc6, 0x1c, 0x29, 0x59, 0xc6, 0x92, 0x9b, 0x8c, 0xeb, 0x4f, 0x6f, 0x42, + 0xb9, 0xd5, 0x78, 0x2b, 0x10, 0x56, 0x30, 0x6a, 0x46, 0x75, 0x8a, 0xec, 0x43, 0xd4, 0x6c, 0x6f, + 0x82, 0xa3, 0x3d, 0xdc, 0xbd, 0x2f, 0x2d, 0xff, 0x7c, 0x15, 0xce, 0x20, 0x9e, 0x26, 0xf5, 0x56, + 0x30, 0x84, 0xae, 0x87, 0x1c, 0x92, 0x03, 0xee, 0x22, 0x14, 0x3f, 0x1c, 0xb9, 0xa2, 0x69, 0x03, + 0xb9, 0x83, 0xa9, 0x42, 0xa3, 0x99, 0x98, 0x95, 0x47, 0xc3, 0x18, 0x88, 0x2a, 0x30, 0x93, 0x6e, + 0x67, 0xe5, 0xe3, 0x25, 0xec, 0x68, 0x59, 0xf6, 0x91, 0x32, 0x70, 0x56, 0xb9, 0x28, 0x3e, 0x45, + 0x27, 0x86, 0xcf, 0xa1, 0xab, 0x1c, 0x87, 0x34, 0xa1, 0x66, 0xfe, 0x9c, 0x07, 0xb4, 0xf6, 0x3f, + 0x10, 0x63, 0x98, 0xa2, 0x9c, 0xc6, 0xed, 0x7c, 0x68, 0x92, 0xe2, 0x58, 0xac, 0x2a, 0xaf, 0x4a, + 0x3a, 0x70, 0xf6, 0xd5, 0x7d, 0x34, 0xef, 0xc4, 0x07, 0xc4, 0x33, 0xfc, 0x4e, 0x95, 0x33, 0x25, + 0x65, 0xa4, 0x13, 0x30, 0x57, 0x88, 0x9d, 0xfd, 0xb7, 0x5f, 0x19, 0x0e, 0x90, 0xd6, 0x7a, 0x3e, + 0x0b, 0x7f, 0x5f, 0x18, 0xfe, 0x5e, 0xa6, 0xf3, 0x65, 0x94, 0x57, 0x88, 0x10, 0x14, 0x3e, 0x90, + 0xac, 0x40, 0x0f, 0xc5, 0x18, 0x81, 0xc1, 0x41, 0x96, 0x03, 0x10, 0x0c, 0x0f, 0x70, 0x50, 0x65, + 0x83, 0x3d, 0xc3, 0x35, 0x83, 0x18, 0x1f, 0x1d, 0xf1, 0x01, 0x43, 0x24, 0x28, 0xcb, 0x1b, 0x82, + 0x80, 0xed, 0x04, 0x48, 0x96, 0x74, 0x66, 0x52, 0x00, 0xf2, 0x8d, 0xe9, 0x97, 0x1f, 0x0e, 0xee, + 0xe1, 0xcb, 0x16, 0x14, 0x77, 0x52, 0x5b, 0xd2, 0x35, 0xf8, 0xdb, 0x7b, 0x78, 0x03, 0x82, 0x69, + 0x0d, 0xb4, 0xf8, 0x03, 0x82, 0xbf, 0x10, 0xeb, 0x72, 0x43, 0xc0, 0x6c, 0x4c, 0x62, 0x82, 0xd5, + 0xfa, 0x4e, 0x1a, 0x51, 0x01, 0xa3, 0x15, 0xf4, 0x28, 0x76, 0xc0, 0x8a, 0x41, 0x7c, 0x71, 0xd8, + 0xaf, 0x78, 0xc4, 0x4a, 0x14, 0x6f, 0x21, 0xf2, 0x98, 0x32, 0x57, 0x2d, 0xda, 0x29, 0x81, 0xf6, + 0x92, 0x00, 0xc8, 0xde, 0x89, 0x03, 0xe4, 0x84, 0xf1, 0xe1, 0x01, 0xbc, 0xc8, 0x65, 0xb1, 0x6a, + 0x50, 0xb6, 0xf1, 0x58, 0xad, 0x1f, 0x01, 0xfa, 0x8d, 0x11, 0xb4, 0x94, 0xc0, 0x7a, 0x19, 0x5d, + 0x29, 0xcb, 0x62, 0xb0, 0x19, 0x7f, 0x8a, 0xdb, 0xf0, 0x48, 0x56, 0xb1, 0x5e, 0xbe, 0x15, 0xcf, + 0x1d, 0x13, 0x48, 0xa4, 0x17, 0xdc, 0xdd, 0xbf, 0xc9, 0x63, 0x9d, 0xff, 0x04, 0x7a, 0x6f, 0x6a, + 0xe0, 0xbe, 0x96, 0xdb, 0x4d, 0x24, 0x92, 0xb6, 0xc9, 0xb6, 0xdb, 0x6d, 0x34, 0xfd, 0x53, 0x1f, + 0x7d, 0x21, 0x6b, 0xc5, 0x55, 0x9e, 0xfa, 0x7e, 0x27, 0x7a, 0xd2, 0x4b, 0xeb, 0xdf, 0x27, 0x74, + 0xfc, 0x35, 0xd5, 0x57, 0xd3, 0x4d, 0x34, 0xfc, 0x57, 0x77, 0xda, 0x6b, 0xc1, 0x0e, 0x95, 0xa7, + 0xf8, 0x23, 0xdd, 0xa6, 0x9f, 0xe6, 0xdb, 0x33, 0x34, 0x7e, 0x09, 0xe7, 0xd3, 0xe7, 0x79, 0xf7, + 0xbe, 0x0a, 0xfa, 0x9b, 0xdb, 0x59, 0x7a, 0x7f, 0x7c, 0xd4, 0x3a, 0x1a, 0x7e, 0x26, 0xdd, 0xbe, + 0x5f, 0xf0, 0x99, 0xa8, 0x6a, 0x86, 0x57, 0xb1, 0xd3, 0xf1, 0xfb, 0x6c, 0x6d, 0x31, 0xa4, 0xc7, + 0xcc, 0xc1, 0x99, 0xf0, 0x9e, 0xf7, 0x6e, 0xff, 0x05, 0x17, 0x6e, 0xed, 0x6a, 0xef, 0x85, 0x0a, + 0xf6, 0xec, 0x8d, 0xee, 0xea, 0xdd, 0xec, 0x86, 0x10, 0xb4, 0xbb, 0xe0, 0x9a, 0xa8, 0x1d, 0x1f, + 0x54, 0xfb, 0xe0, 0xac, 0x8b, 0x87, 0xd5, 0xbc, 0xa5, 0x6a, 0xd7, 0x62, 0xb8, 0x2f, 0x2c, 0x30, + 0xdd, 0x96, 0x25, 0x69, 0xd3, 0xc3, 0x5d, 0x93, 0xa7, 0xfe, 0x0a, 0xc8, 0xc5, 0x53, 0xac, 0xca, + 0x1f, 0x5a, 0xf5, 0xf2, 0x6a, 0xed, 0xf8, 0x2e, 0xad, 0x2b, 0xb6, 0x93, 0x7f, 0x1e, 0x14, 0x87, + 0x5d, 0x28, 0x7a, 0x84, 0x1d, 0x0d, 0x31, 0x24, 0x63, 0x0d, 0xd9, 0x0a, 0x9d, 0x49, 0xdc, 0xf9, + 0x50, 0xb4, 0x37, 0x7c, 0x13, 0x16, 0xc4, 0xb9, 0x23, 0xb3, 0xeb, 0xf3, 0x1f, 0x0a, 0x67, 0xc7, + 0xda, 0x7e, 0x6a, 0xd0, 0xd6, 0x4a, 0x6d, 0x6b, 0xa4, 0xc7, 0x89, 0x04, 0xe7, 0x21, 0x11, 0x86, + 0x5b, 0xb7, 0x7e, 0xf1, 0x23, 0xaa, 0x19, 0x32, 0x5b, 0xcc, 0x1c, 0xa9, 0x29, 0xa4, 0x9f, 0x12, + 0x30, 0x8a, 0xdb, 0x69, 0x72, 0x22, 0x63, 0xee, 0xe5, 0x63, 0xfc, 0x65, 0xcc, 0x4d, 0x94, 0x36, + 0xb1, 0x0c, 0x0a, 0x0c, 0xa7, 0x54, 0x74, 0x95, 0x34, 0x2e, 0x78, 0x98, 0x2b, 0xd0, 0xf2, 0xdb, + 0xc6, 0x76, 0x49, 0xeb, 0x43, 0x27, 0x43, 0xd2, 0xbe, 0x24, 0x25, 0xab, 0x7e, 0x6d, 0xf0, 0xe1, + 0x9b, 0x9b, 0x39, 0x63, 0x5a, 0x54, 0x69, 0xf8, 0x99, 0x8e, 0x5f, 0xfc, 0x10, 0x4e, 0x48, 0x1d, + 0x46, 0xee, 0xcf, 0xa6, 0x91, 0x77, 0xd3, 0x8f, 0xc0, 0x51, 0x93, 0x0b, 0xe2, 0x20, 0xb0, 0x8f, + 0x15, 0xd9, 0xcf, 0xb6, 0xae, 0xdb, 0x0f, 0x05, 0xe5, 0xaa, 0x1b, 0x4e, 0x79, 0x06, 0x95, 0x90, + 0x34, 0xa1, 0xf6, 0xc1, 0x6e, 0x87, 0xe0, 0xb8, 0x97, 0x3a, 0x26, 0x4f, 0xb2, 0xaf, 0x82, 0x02, + 0x2d, 0x08, 0x9a, 0x61, 0x65, 0x1c, 0x4c, 0xc4, 0x5c, 0x7b, 0xf5, 0x79, 0xc3, 0x20, 0x9a, 0x6c, + 0x39, 0xaf, 0xba, 0x6f, 0xf0, 0x40, 0x70, 0x9d, 0xae, 0xd1, 0xe9, 0x05, 0x2d, 0xd6, 0x3b, 0x73, + 0xf7, 0x77, 0x46, 0xd5, 0x10, 0x7b, 0x4b, 0xfc, 0x5f, 0xc4, 0x8d, 0x21, 0xc3, 0x85, 0xb3, 0xc7, + 0x09, 0xd5, 0x2d, 0x8f, 0xd7, 0x3d, 0x69, 0xc8, 0x60, 0x28, 0x7b, 0x2e, 0x4a, 0xa2, 0xa1, 0xe0, + 0x68, 0xa3, 0x94, 0x9c, 0x0f, 0x03, 0x8b, 0x30, 0xab, 0x1e, 0x5d, 0xb9, 0xff, 0xc6, 0x4e, 0x79, + 0xf5, 0x25, 0x83, 0x3c, 0x2a, 0x4b, 0x4f, 0xa9, 0xc3, 0xd8, 0xb3, 0xdc, 0xf6, 0xc5, 0x61, 0x61, + 0x42, 0x19, 0x40, 0xfc, 0xe1, 0x00, 0xa1, 0x69, 0x73, 0xa7, 0xc1, 0x81, 0xdf, 0x7d, 0x83, 0x5e, + 0xbe, 0xc1, 0xa1, 0x51, 0x74, 0xc6, 0xa2, 0xbb, 0xb3, 0xe5, 0x9c, 0x3c, 0xb5, 0x16, 0x28, 0xdf, + 0xe3, 0x74, 0x50, 0xfc, 0x60, 0xc7, 0x73, 0x93, 0xb7, 0x6c, 0xf8, 0x0f, 0x61, 0x5b, 0x20, 0x7f, + 0xc8, 0xbd, 0xb6, 0xc8, 0x8d, 0x1b, 0xff, 0xc1, 0x19, 0x5f, 0x77, 0x7c, 0x14, 0x77, 0x6d, 0xe5, + 0xf7, 0x1e, 0xb8, 0x7c, 0x34, 0x6e, 0x6e, 0xad, 0xb6, 0x9a, 0x7f, 0xe7, 0x3a, 0xb6, 0xda, 0x69, + 0xfb, 0xe2, 0x48, 0x91, 0x71, 0xfd, 0xd1, 0x78, 0xb2, 0x96, 0xd2, 0xad, 0xab, 0xae, 0x36, 0xee, + 0x9f, 0x69, 0x36, 0x53, 0x47, 0x3b, 0x1a, 0xa7, 0x3e, 0xb5, 0xfe, 0x13, 0x34, 0x57, 0xd1, 0xa4, + 0xcd, 0xf1, 0x25, 0x74, 0xad, 0x51, 0x32, 0x4f, 0xc1, 0x0d, 0x0d, 0x0e, 0xd6, 0x1f, 0x09, 0xd9, + 0x37, 0x43, 0x4d, 0xed, 0x78, 0x48, 0x89, 0x57, 0x2b, 0x0c, 0xd9, 0xb2, 0x4f, 0xc9, 0x93, 0xfe, + 0x62, 0xd2, 0x27, 0xb5, 0xd9, 0x24, 0x7f, 0xe1, 0xaa, 0xd0, 0xe9, 0xa9, 0x21, 0x24, 0x11, 0x7f, + 0x9e, 0xb1, 0xde, 0xc7, 0xfe, 0xee, 0xe5, 0xff, 0x86, 0xb5, 0x5a, 0x9b, 0xdb, 0xff, 0x82, 0x69, + 0x21, 0x96, 0x35, 0x5f, 0xbe, 0x8b, 0x95, 0x71, 0x06, 0xe7, 0xc6, 0xb7, 0xf1, 0xc5, 0x6e, 0xd3, + 0x35, 0xab, 0x33, 0x66, 0xad, 0x78, 0x24, 0xd2, 0x4b, 0x1c, 0xf8, 0x42, 0x92, 0x02, 0x97, 0x12, + 0xd2, 0xa4, 0x83, 0xbf, 0x9c, 0xaa, 0xf2, 0xc3, 0xfe, 0x3c, 0x88, 0x6d, 0xd9, 0xa1, 0x85, 0xfd, + 0x3b, 0xc8, 0xe4, 0x06, 0x36, 0x83, 0x69, 0x8f, 0x12, 0x14, 0xbc, 0x91, 0xca, 0x29, 0x2a, 0x6c, + 0xc0, 0x97, 0xc7, 0x13, 0xe2, 0x41, 0x48, 0x7b, 0x12, 0x8e, 0xbe, 0x7b, 0xd1, 0xe9, 0x40, 0xac, + 0x86, 0x5c, 0x8b, 0x6a, 0x8f, 0x8b, 0xc4, 0x05, 0x2d, 0xaa, 0x60, 0x8e, 0xa3, 0xe5, 0x5d, 0x50, + 0x0d, 0xfc, 0x09, 0x8c, 0x0a, 0xe3, 0xcf, 0x68, 0xb4, 0x40, 0xfe, 0x06, 0x47, 0x69, 0x28, 0x0b, + 0x00, 0xa2, 0x29, 0xc5, 0x1c, 0x00, 0xe8, 0x69, 0x4a, 0x61, 0x86, 0x49, 0x97, 0x10, 0x10, 0xad, + 0x0f, 0x65, 0xc8, 0x86, 0xa3, 0x1b, 0x84, 0x3f, 0x44, 0x9f, 0xfc, 0x3e, 0xce, 0xbd, 0xbc, 0x48, + 0x90, 0x88, 0xbc, 0xfe, 0xca, 0x5c, 0x4b, 0x9b, 0x71, 0x02, 0x42, 0x44, 0x79, 0x7d, 0xf7, 0xf0, + 0x45, 0x2b, 0x0f, 0x6b, 0xbc, 0x40, 0x2b, 0x21, 0x33, 0x9d, 0xb2, 0x62, 0x93, 0x73, 0x02, 0x02, + 0x83, 0xca, 0x1a, 0x26, 0x8b, 0xba, 0x61, 0x05, 0x34, 0xf2, 0x3d, 0xf0, 0xe9, 0x28, 0x91, 0x85, + 0x49, 0x91, 0x31, 0x31, 0xc7, 0x07, 0x56, 0xb9, 0x60, 0x67, 0xcc, 0x4a, 0x3b, 0xd5, 0x3c, 0xd4, + 0xff, 0x82, 0xa2, 0x9b, 0x2b, 0xb6, 0x6a, 0x6f, 0xbe, 0x1f, 0x0a, 0x69, 0x4b, 0xdd, 0x0f, 0xa2, + 0xcf, 0xdb, 0x69, 0x92, 0x87, 0x6a, 0x18, 0x5f, 0x04, 0x10, 0x2f, 0xef, 0x58, 0x28, 0xcd, 0x5f, + 0x1a, 0x41, 0xb8, 0xe1, 0x2b, 0x7d, 0x2a, 0x05, 0x28, 0xfb, 0x4d, 0x3f, 0xf1, 0xa4, 0xf0, 0xab, + 0x18, 0x87, 0x93, 0x43, 0x1e, 0x5b, 0xa2, 0x15, 0xc6, 0x4b, 0x0a, 0xb7, 0x27, 0x92, 0x0b, 0xe7, + 0x46, 0x0b, 0xc8, 0x33, 0xe1, 0x23, 0xd5, 0x3e, 0x0e, 0xd3, 0x2c, 0x38, 0x91, 0xa6, 0x0d, 0x54, + 0x27, 0x2a, 0x4a, 0x07, 0x05, 0x86, 0xe1, 0xc1, 0x45, 0xe3, 0x1a, 0xc6, 0xc8, 0xb3, 0x22, 0x95, + 0x57, 0x67, 0x18, 0x47, 0x21, 0x20, 0x22, 0xb2, 0xa2, 0x74, 0x9a, 0x65, 0x8f, 0xf8, 0x81, 0x23, + 0x49, 0x92, 0x12, 0xea, 0x35, 0xcc, 0x49, 0xd2, 0xc6, 0x1f, 0xaf, 0x6b, 0x63, 0xa5, 0x42, 0x70, + 0xc4, 0x3c, 0x82, 0xe1, 0x8e, 0x33, 0xf9, 0xb4, 0xdb, 0xe1, 0x49, 0xfe, 0x59, 0x9f, 0xe7, 0x58, + 0x3c, 0x03, 0xc1, 0xd8, 0x92, 0x61, 0xc7, 0x03, 0xb4, 0x99, 0x28, 0xb8, 0xd8, 0x26, 0x29, 0x35, + 0xbb, 0xa5, 0x10, 0xec, 0xba, 0x51, 0x1a, 0x04, 0x65, 0x07, 0xc2, 0x85, 0xc1, 0x99, 0xcd, 0x75, + 0xd3, 0x11, 0x61, 0xe4, 0x23, 0x6d, 0x74, 0xbf, 0xae, 0x1a, 0xa8, 0xdc, 0xb3, 0xe4, 0x4c, 0x31, + 0xf3, 0x10, 0xe1, 0xd5, 0x35, 0x16, 0xe9, 0x9d, 0xf0, 0x58, 0x26, 0x2b, 0x97, 0xef, 0x6f, 0xab, + 0x24, 0xbc, 0x4c, 0x15, 0x0a, 0xdf, 0xa8, 0xc7, 0x3a, 0x4a, 0xba, 0xaa, 0x55, 0x89, 0x82, 0xaa, + 0x6e, 0x84, 0x9a, 0x81, 0xda, 0xa2, 0x72, 0x89, 0x1a, 0xfb, 0xe0, 0x9a, 0xed, 0xbe, 0x4e, 0xe4, + 0x61, 0x47, 0x62, 0x3e, 0x11, 0x3d, 0x24, 0xe8, 0x8f, 0xa9, 0x4b, 0x24, 0xca, 0xa6, 0xbc, 0x77, + 0x2c, 0x5f, 0x8d, 0x5d, 0x7c, 0xbf, 0xe0, 0xa3, 0x4d, 0xda, 0x77, 0x4b, 0x87, 0xc1, 0x7d, 0x34, + 0xba, 0x54, 0xb5, 0x56, 0xe9, 0xff, 0x88, 0x22, 0x2a, 0x27, 0xda, 0x6b, 0xd7, 0xab, 0x8b, 0x3d, + 0xb6, 0xf9, 0x60, 0xbe, 0x32, 0xa3, 0x74, 0xf6, 0x8e, 0xce, 0xdb, 0x74, 0x31, 0x36, 0x7f, 0x17, + 0x64, 0xda, 0x77, 0x3d, 0x2c, 0x7e, 0x23, 0x64, 0x92, 0x92, 0x3f, 0xe6, 0x9f, 0xa3, 0xb3, 0xf7, + 0xdd, 0x3f, 0x15, 0x9f, 0x26, 0xb9, 0xf2, 0x9f, 0x8b, 0xf2, 0x35, 0xad, 0x1b, 0x1f, 0x96, 0xf6, + 0xfe, 0x0c, 0x08, 0x7b, 0x65, 0xb7, 0x49, 0x55, 0x27, 0x3e, 0x7f, 0xe0, 0x87, 0x49, 0xab, 0x1f, + 0x31, 0x76, 0x9a, 0xf0, 0x4e, 0x4d, 0x5b, 0x4a, 0xbc, 0xc7, 0xc1, 0x1e, 0x45, 0x04, 0xcf, 0xbe, + 0x0a, 0xa4, 0x97, 0xd5, 0x94, 0xdc, 0x97, 0x38, 0x7d, 0x4a, 0x0f, 0x82, 0xbc, 0x99, 0x26, 0x52, + 0xbd, 0xb7, 0xb7, 0xc6, 0xd6, 0x95, 0x6b, 0x27, 0x5d, 0xa7, 0xa4, 0xb7, 0x4d, 0x7f, 0xc4, 0x59, + 0xcc, 0x96, 0xb4, 0x36, 0xbc, 0xa7, 0x59, 0x14, 0x7c, 0x69, 0xb5, 0x55, 0x17, 0x8b, 0xaa, 0xed, + 0x8d, 0x21, 0x77, 0x7d, 0xe5, 0xef, 0xe1, 0xfe, 0xa4, 0xd6, 0x78, 0xd6, 0xbb, 0xac, 0xdd, 0xff, + 0xf0, 0xa1, 0x62, 0xbd, 0xa5, 0x5d, 0x2b, 0x77, 0xbb, 0x1f, 0x26, 0xeb, 0xf0, 0xd5, 0xe8, 0x90, + 0x4b, 0xf7, 0x57, 0xf0, 0x4b, 0x48, 0x1d, 0xb3, 0x73, 0x14, 0x6a, 0xdb, 0xbe, 0x30, 0xc3, 0xb9, + 0x78, 0xdd, 0x37, 0x66, 0xc8, 0x9b, 0x37, 0x4c, 0x0a, 0x2a, 0xc7, 0x6f, 0xc2, 0x84, 0xd9, 0x19, + 0xfc, 0xf7, 0x2c, 0x9f, 0xd0, 0x24, 0x04, 0xb1, 0xcf, 0xce, 0x18, 0x79, 0x97, 0x83, 0xcd, 0x79, + 0x98, 0x1e, 0x4b, 0xc9, 0x43, 0xc2, 0x93, 0x60, 0x72, 0x2e, 0x78, 0x9c, 0x39, 0x27, 0xd8, 0xae, + 0x3f, 0x95, 0x24, 0x74, 0xca, 0x25, 0xd4, 0xc2, 0xce, 0xb1, 0xc5, 0xaf, 0x14, 0x73, 0x58, 0xac, + 0xe9, 0x62, 0x23, 0x9e, 0x22, 0x4b, 0xc1, 0xf2, 0xf1, 0x40, 0x74, 0xa5, 0x5a, 0xf2, 0x03, 0x4b, + 0xa7, 0x07, 0x88, 0x0a, 0x1f, 0x6d, 0x6b, 0x03, 0xc5, 0x85, 0x98, 0x87, 0xbd, 0x4b, 0xb1, 0xdb, + 0x22, 0xe2, 0x3a, 0x72, 0xc1, 0xdc, 0x2f, 0x39, 0x62, 0xf2, 0xf1, 0x00, 0x92, 0xd0, 0x74, 0x8c, + 0x9a, 0x70, 0xa8, 0x67, 0xc6, 0xf1, 0xb3, 0x90, 0x25, 0x7c, 0xae, 0xd9, 0x01, 0x9f, 0x90, 0xb0, + 0x02, 0xbf, 0x15, 0xb4, 0x0a, 0xbe, 0xc5, 0x71, 0x2c, 0x9a, 0x10, 0x6b, 0x57, 0x0c, 0x50, 0x35, + 0xc1, 0x3f, 0x02, 0x54, 0xdc, 0x1e, 0xe9, 0x09, 0xed, 0x92, 0x94, 0x00, 0x91, 0xe1, 0xec, 0x31, + 0xa3, 0x82, 0x91, 0xb3, 0xf1, 0xbe, 0xfe, 0x34, 0x97, 0xab, 0x28, 0x2c, 0x2c, 0x84, 0xe8, 0x7a, + 0xed, 0xc6, 0x71, 0x88, 0x52, 0x9d, 0xed, 0x7c, 0x6b, 0x8e, 0xfb, 0x24, 0x08, 0x4c, 0x7e, 0xbe, + 0xab, 0xb2, 0x09, 0x1a, 0x15, 0x07, 0x34, 0xb5, 0x11, 0x04, 0x75, 0xbc, 0x1a, 0x62, 0xa0, 0x5c, + 0x92, 0xd7, 0x04, 0x20, 0xa3, 0xe1, 0xff, 0xf8, 0xda, 0xa9, 0xda, 0x88, 0xec, 0x9b, 0xdf, 0x66, + 0x40, 0xf9, 0xad, 0x61, 0xc5, 0x77, 0x84, 0x4c, 0x37, 0xb6, 0x40, 0xcb, 0xf5, 0x6c, 0xc2, 0x75, + 0xea, 0xb9, 0x86, 0x2a, 0x0f, 0x59, 0x44, 0x23, 0xf8, 0xc9, 0xa1, 0x25, 0xd7, 0x20, 0x1b, 0xe3, + 0xb6, 0x29, 0x7f, 0x0c, 0x1d, 0x1b, 0xa3, 0x4e, 0xef, 0x31, 0x99, 0xbe, 0xcf, 0xe2, 0x30, 0xf8, + 0xf9, 0x77, 0x64, 0xd2, 0x54, 0x68, 0x6d, 0xcf, 0x2f, 0xc2, 0x1b, 0x69, 0xe1, 0x34, 0x9e, 0xdb, + 0x5f, 0x05, 0x44, 0xba, 0xb8, 0x74, 0x17, 0x66, 0x42, 0x6f, 0xb3, 0x63, 0x95, 0x88, 0x47, 0xfc, + 0x6b, 0xe0, 0xa6, 0x33, 0x2d, 0xd8, 0xed, 0x65, 0xb3, 0x5f, 0xb4, 0xd8, 0xf9, 0x9e, 0x20, 0x55, + 0xf6, 0x52, 0xbd, 0x86, 0xd3, 0x2f, 0x0e, 0xe9, 0xe4, 0xb8, 0x79, 0x91, 0xb0, 0xfd, 0xd0, 0xdc, + 0x7c, 0xd5, 0x1e, 0x20, 0xfe, 0x49, 0x57, 0x10, 0x25, 0x82, 0x75, 0x26, 0xe7, 0xe3, 0x4a, 0xab, + 0x52, 0xc9, 0x8c, 0xb3, 0x75, 0x8c, 0x8b, 0xca, 0x59, 0x79, 0x29, 0x66, 0xd2, 0xba, 0x75, 0xde, + 0x48, 0x8b, 0xd7, 0x15, 0x65, 0x32, 0x9e, 0x7d, 0x3e, 0xfe, 0x36, 0x6a, 0x45, 0x4e, 0x4c, 0x06, + 0x5a, 0x8d, 0xac, 0x9e, 0x48, 0x29, 0x8c, 0xb5, 0xc3, 0x8c, 0x56, 0x39, 0x9e, 0xfc, 0xf3, 0xa3, + 0xaf, 0x3e, 0xb5, 0xe2, 0x23, 0x71, 0x4f, 0x95, 0x55, 0xda, 0x49, 0x0d, 0x48, 0xc4, 0x72, 0xb1, + 0x43, 0x4d, 0x8d, 0xff, 0xe1, 0x52, 0x18, 0x8e, 0x5c, 0x8a, 0xa4, 0x48, 0x1b, 0x9f, 0x6d, 0xed, + 0xf8, 0x40, 0x88, 0xf2, 0x1e, 0x72, 0x4f, 0x4d, 0x04, 0x5c, 0x2f, 0x3f, 0x24, 0x01, 0x54, 0xea, + 0x67, 0x9c, 0xeb, 0x51, 0x65, 0xff, 0x05, 0xa5, 0xad, 0xab, 0xa1, 0xd3, 0xa5, 0xc1, 0x1e, 0xd2, + 0x53, 0x17, 0xc7, 0x88, 0x8c, 0x9c, 0x91, 0xce, 0x63, 0x2a, 0x44, 0x74, 0x69, 0x3b, 0xd7, 0x38, + 0xb9, 0x45, 0xff, 0xf8, 0x47, 0x93, 0xd9, 0xcf, 0x14, 0x8c, 0xc2, 0x1f, 0x7c, 0x79, 0x0f, 0xa8, + 0x73, 0x53, 0x1c, 0xff, 0xdb, 0x6f, 0xc2, 0x55, 0x4d, 0x3c, 0xfe, 0xdf, 0x98, 0xbc, 0xd2, 0x5c, + 0x2b, 0x3b, 0x35, 0xd8, 0xea, 0x8e, 0xa9, 0xa3, 0x15, 0x7f, 0xf3, 0x64, 0xb4, 0xff, 0x14, 0x44, + 0x38, 0xcd, 0x73, 0xad, 0x3f, 0x09, 0x4d, 0x1d, 0xd8, 0xc8, 0xd4, 0x3f, 0xc3, 0x87, 0x77, 0xdc, + 0xe9, 0x8b, 0x7f, 0xe1, 0xe1, 0x15, 0xa1, 0x8b, 0xf5, 0x53, 0x42, 0x2e, 0xa2, 0xc9, 0xd9, 0x5d, + 0xfc, 0x2d, 0x75, 0xb1, 0xb2, 0xb6, 0xab, 0x6e, 0x6e, 0xe9, 0xd3, 0xf1, 0xf3, 0x21, 0xde, 0x31, + 0x83, 0xb1, 0xb2, 0x3b, 0xdb, 0xfd, 0xd9, 0x9a, 0x1f, 0x82, 0xdb, 0x6f, 0xec, 0x64, 0x85, 0x7d, + 0x89, 0x55, 0x6f, 0xe0, 0x88, 0xce, 0x9f, 0x07, 0xc3, 0x36, 0x63, 0x5b, 0xba, 0x93, 0xee, 0x7f, + 0xe1, 0xa2, 0x12, 0x5d, 0x54, 0xdf, 0xfa, 0xe0, 0xb8, 0x5d, 0x5b, 0xd8, 0xde, 0xff, 0x05, 0xbb, + 0xce, 0xc4, 0x9d, 0xad, 0xbe, 0x84, 0x30, 0x5c, 0x29, 0x54, 0x9e, 0xa3, 0x9c, 0xf6, 0x7f, 0x42, + 0x99, 0x4e, 0xa4, 0xd4, 0x5d, 0xc4, 0xc2, 0x9c, 0xd4, 0x10, 0xf1, 0xe3, 0xc2, 0x7f, 0x89, 0xfe, + 0x38, 0x1c, 0x39, 0x81, 0xf0, 0x77, 0xc6, 0x6c, 0x4b, 0xf2, 0xb4, 0x89, 0x0a, 0x8e, 0x33, 0x89, + 0x8c, 0x9d, 0xc1, 0xca, 0xc3, 0x87, 0x96, 0x31, 0xfe, 0x32, 0x47, 0x8e, 0x2b, 0xa8, 0xe7, 0xaf, + 0xa7, 0xb3, 0x07, 0xf8, 0x32, 0xb1, 0x71, 0x20, 0xaa, 0xa1, 0xb4, 0xe6, 0x87, 0xbe, 0xc6, 0x3d, + 0xcf, 0xc4, 0xaf, 0x33, 0x9a, 0x2b, 0x6b, 0xa4, 0x36, 0x85, 0xd8, 0xfc, 0xbc, 0x48, 0xcb, 0xbe, + 0xaf, 0xc2, 0x8f, 0x2d, 0xdd, 0x64, 0xb9, 0x50, 0xa1, 0x64, 0x74, 0x82, 0xa9, 0xf1, 0xff, 0x12, + 0x14, 0xde, 0x19, 0x2b, 0x43, 0xee, 0x61, 0xfe, 0xc3, 0x21, 0xcb, 0x00, 0xfd, 0x58, 0x87, 0x85, + 0xdc, 0xfb, 0x95, 0xaf, 0xb9, 0xbb, 0x2e, 0x8d, 0xd4, 0xe7, 0x11, 0xc7, 0xf8, 0x52, 0xe7, 0x10, + 0xa3, 0xa5, 0x67, 0x20, 0xf9, 0xda, 0xa4, 0x2c, 0x5e, 0x21, 0xc5, 0xe3, 0x96, 0x0b, 0x7d, 0x87, + 0xa4, 0xc2, 0x94, 0xc2, 0xe3, 0x5b, 0x7e, 0x0e, 0xbc, 0x22, 0xc7, 0x8d, 0xa8, 0xb2, 0x96, 0x5c, + 0x9e, 0x77, 0xe1, 0x6c, 0x5c, 0xca, 0xd3, 0x9d, 0x6e, 0x32, 0x4e, 0xfa, 0x4c, 0x9c, 0xf7, 0x99, + 0xb9, 0x37, 0xf5, 0xf3, 0x46, 0x99, 0xe7, 0xe5, 0x2b, 0xbe, 0x87, 0xe7, 0xab, 0x6d, 0xa6, 0x9f, + 0xfa, 0xe5, 0xf5, 0x97, 0xc1, 0x80, 0x80, 0xda, 0xb2, 0x3b, 0xad, 0x51, 0xb7, 0xdd, 0xb4, 0x4c, + 0xfc, 0x11, 0x17, 0x2e, 0x72, 0x55, 0xe1, 0xf2, 0x3a, 0xf4, 0xe5, 0xfb, 0x95, 0xf2, 0xfd, 0x12, + 0xcd, 0xfc, 0x48, 0xb4, 0xd2, 0x9a, 0x49, 0x42, 0xcb, 0x15, 0xc9, 0x6e, 0xff, 0x7b, 0x74, 0xbc, + 0x13, 0x88, 0x44, 0xbd, 0x0e, 0x56, 0x2b, 0x84, 0x43, 0x21, 0x48, 0x02, 0x3d, 0xee, 0x96, 0x2b, + 0xc7, 0xd2, 0x09, 0x2f, 0x5e, 0x3a, 0xcc, 0x85, 0x19, 0x1c, 0x0e, 0x01, 0xc0, 0x19, 0x72, 0x04, + 0x04, 0xd0, 0xd5, 0xb9, 0x50, 0x74, 0x4a, 0x40, 0x95, 0xc6, 0x99, 0xaf, 0x72, 0xee, 0xab, 0xc3, + 0xd7, 0x00, 0xdd, 0x0f, 0xc1, 0xa8, 0xdb, 0xa8, 0x35, 0xfc, 0xf5, 0x64, 0x98, 0xe0, 0xd8, 0xff, + 0xc1, 0x19, 0x76, 0x47, 0x85, 0x7c, 0x39, 0x66, 0xf4, 0x96, 0xd8, 0xc4, 0xbf, 0xfc, 0x13, 0xd7, + 0x44, 0x8d, 0x23, 0x3f, 0xc4, 0x7c, 0x10, 0x92, 0xf2, 0x2d, 0x97, 0xc3, 0x74, 0xda, 0x8e, 0x88, + 0xab, 0x24, 0x24, 0x87, 0xae, 0x61, 0x2d, 0xaf, 0xe4, 0xe6, 0xdf, 0x9e, 0xb5, 0x75, 0xff, 0x35, + 0x11, 0xe3, 0xf9, 0x34, 0xcb, 0x2f, 0xc4, 0x69, 0xa7, 0xa4, 0xd3, 0x7e, 0x0a, 0x49, 0xa4, 0x5d, + 0xbd, 0x17, 0x34, 0xf2, 0xf9, 0xa8, 0x6c, 0x76, 0xbc, 0x85, 0x45, 0x2b, 0x04, 0xdf, 0x25, 0xab, + 0x55, 0xdd, 0x8d, 0x0e, 0x9f, 0x8d, 0x20, 0xe5, 0x71, 0x76, 0x41, 0x92, 0x77, 0xb2, 0xc5, 0x3b, + 0x07, 0x64, 0x9b, 0x2e, 0x6b, 0x65, 0x8b, 0xee, 0xb5, 0xf0, 0xa7, 0x52, 0x2e, 0xd6, 0xb0, 0xcc, + 0xc5, 0x25, 0x39, 0xed, 0x5a, 0x27, 0xd2, 0x72, 0x4f, 0x8f, 0x8d, 0xa4, 0x66, 0x62, 0x8e, 0x0d, + 0x06, 0x89, 0xbb, 0x6d, 0x3a, 0x19, 0x7a, 0x56, 0x94, 0x4d, 0xd6, 0x27, 0xcb, 0xde, 0x9f, 0x83, + 0x0d, 0x09, 0xa1, 0xb4, 0xa0, 0xc5, 0x4e, 0x37, 0x52, 0xfe, 0xe6, 0xfd, 0x7c, 0x6e, 0x86, 0x91, + 0x9e, 0x5d, 0x57, 0xaa, 0x7b, 0x5a, 0x89, 0x26, 0xa8, 0xa3, 0x08, 0x1f, 0xc5, 0x6b, 0xf6, 0xdd, + 0xfc, 0x3b, 0x4d, 0xaf, 0xa4, 0x91, 0x20, 0x4f, 0xa2, 0xd3, 0x09, 0x2b, 0x2f, 0x4c, 0xf5, 0xbb, + 0x9b, 0xf8, 0x50, 0x5b, 0x7a, 0x6b, 0x6f, 0x9b, 0x4d, 0x94, 0x89, 0xfd, 0x7c, 0x16, 0x08, 0x47, + 0x5a, 0xae, 0xed, 0xa3, 0xeb, 0xe0, 0x82, 0x4c, 0x4b, 0x59, 0xfe, 0x9a, 0xd9, 0x4f, 0x2f, 0x37, + 0xa3, 0x37, 0xf1, 0xb6, 0xd0, 0x3b, 0xb1, 0xa6, 0xc6, 0x89, 0xe6, 0xd7, 0xa5, 0x3f, 0xef, 0x93, + 0x9e, 0x19, 0xe1, 0xe0, 0xa7, 0x5a, 0x93, 0xeb, 0xe6, 0x8a, 0x62, 0xb0, 0x06, 0xf8, 0x44, 0xa9, + 0xba, 0x5b, 0xd9, 0xa6, 0x9d, 0x3f, 0x0e, 0x99, 0xb1, 0xab, 0xb8, 0x1f, 0x3e, 0xd2, 0xcf, 0xe3, + 0x86, 0xe7, 0x89, 0x20, 0x9c, 0xbd, 0xfc, 0x6d, 0xa9, 0x96, 0x63, 0x34, 0x1d, 0xde, 0x38, 0xfd, + 0x93, 0x2d, 0xc2, 0x93, 0x6a, 0x6a, 0x97, 0xef, 0x1e, 0xec, 0x3f, 0x0a, 0x4b, 0x20, 0xa3, 0x47, + 0x36, 0x55, 0x99, 0x2b, 0xb3, 0xc1, 0xd0, 0xcd, 0x15, 0x67, 0x81, 0x18, 0x3b, 0x39, 0x55, 0xc4, + 0x09, 0x19, 0x75, 0x5b, 0x25, 0x35, 0x56, 0xf9, 0xdc, 0x63, 0xd4, 0x6a, 0x42, 0x57, 0xbb, 0x72, + 0xb9, 0x54, 0x71, 0x01, 0x42, 0x84, 0xdb, 0xc5, 0xe7, 0x3f, 0x5e, 0x6f, 0x37, 0x0b, 0x26, 0x61, + 0xe7, 0x87, 0xea, 0x28, 0xd6, 0x0b, 0x62, 0xcd, 0xb8, 0x46, 0x92, 0xd1, 0x14, 0x88, 0x69, 0xa3, + 0x41, 0xdd, 0xd9, 0x16, 0xb4, 0x3f, 0xc4, 0x13, 0xbb, 0x89, 0x8d, 0xa8, 0xc5, 0xd4, 0xef, 0xfd, + 0x08, 0x1d, 0xe2, 0xd0, 0x24, 0x5a, 0xfe, 0x74, 0x43, 0x95, 0x27, 0x0a, 0x09, 0xe8, 0x45, 0x4f, + 0xb5, 0xe1, 0xb5, 0x23, 0x08, 0xee, 0xe0, 0x56, 0x5e, 0x28, 0xf6, 0xb1, 0x70, 0x9d, 0xa8, 0xd8, + 0xda, 0xcb, 0xdb, 0xff, 0xc2, 0x84, 0xeb, 0x86, 0xe4, 0x46, 0x40, 0xf4, 0xf2, 0x06, 0xf9, 0x29, + 0x55, 0x83, 0x56, 0x38, 0x69, 0x2a, 0xfc, 0x48, 0x88, 0xdb, 0x24, 0xed, 0x10, 0xa0, 0xdd, 0xa9, + 0x23, 0x7f, 0x8d, 0xc7, 0x22, 0xf1, 0x5d, 0x1c, 0xc2, 0x64, 0xf9, 0x2c, 0x24, 0xbf, 0x14, 0x5f, + 0x77, 0x23, 0x71, 0xff, 0x73, 0xa6, 0xf3, 0xff, 0xf1, 0x92, 0x65, 0x91, 0x74, 0xea, 0x6c, 0xc5, + 0x97, 0x1d, 0xd0, 0x4c, 0xd3, 0xd9, 0x92, 0xe9, 0xf8, 0x76, 0xa3, 0x51, 0x57, 0xa6, 0x67, 0x85, + 0x1b, 0x1a, 0xe3, 0x2f, 0x15, 0x51, 0x28, 0xe1, 0x95, 0x7c, 0x9d, 0x99, 0xf8, 0xda, 0x21, 0xb5, + 0x3d, 0xd6, 0xe9, 0x16, 0x1c, 0x7e, 0x4b, 0xad, 0x11, 0x6c, 0xed, 0x5f, 0x1a, 0xc3, 0x14, 0xf3, + 0x11, 0xa0, 0xcb, 0xbf, 0xe3, 0x4e, 0x9b, 0x49, 0x8d, 0x5d, 0x6d, 0x71, 0xca, 0x52, 0xb2, 0x12, + 0xbb, 0x9a, 0xf2, 0xb5, 0x9b, 0xa8, 0xb6, 0x9d, 0x6f, 0xfe, 0x3b, 0x1f, 0xaa, 0xdc, 0xcb, 0xde, + 0x87, 0xa1, 0x9f, 0x61, 0x52, 0xf0, 0x58, 0x46, 0x4d, 0x28, 0x8c, 0xa6, 0xf2, 0xe6, 0x5c, 0x43, + 0x6e, 0xcb, 0xe3, 0x6d, 0x1d, 0xde, 0xb3, 0x19, 0x32, 0x6a, 0x07, 0x0a, 0xa5, 0x46, 0xd6, 0xc7, + 0xdf, 0xea, 0x64, 0xf6, 0x51, 0xa4, 0xe7, 0x82, 0xf1, 0xa4, 0x2b, 0x5b, 0xf4, 0xae, 0x76, 0xa6, + 0xc9, 0x72, 0xc2, 0x1d, 0x52, 0x72, 0xba, 0x97, 0xfc, 0xdd, 0xfc, 0x6e, 0x3d, 0x59, 0xfa, 0x8c, + 0x9a, 0xfb, 0x8c, 0xb1, 0x37, 0xcd, 0xfd, 0x69, 0x73, 0xb3, 0xdc, 0xc0, 0xd8, 0xe7, 0x9e, 0xa5, + 0x63, 0x0f, 0x38, 0xd9, 0x55, 0x96, 0x14, 0x53, 0xbd, 0x5a, 0x20, 0x3e, 0x10, 0x12, 0x87, 0x46, + 0xd7, 0xd1, 0xb9, 0x97, 0xb1, 0xed, 0x4f, 0x0f, 0x05, 0x24, 0x69, 0x90, 0xe6, 0x5a, 0x6d, 0xbb, + 0x2c, 0x66, 0xbf, 0xff, 0x8d, 0x91, 0x9c, 0x19, 0xa4, 0x56, 0x08, 0xcb, 0x98, 0xdb, 0xac, 0xbd, + 0xac, 0xf1, 0xca, 0xdd, 0xa9, 0xc1, 0x72, 0xc3, 0xfc, 0x7c, 0xba, 0xc6, 0xc9, 0x31, 0xaa, 0xe0, + 0xd8, 0xcc, 0x1d, 0x8c, 0xf9, 0xf8, 0x78, 0xc6, 0xc3, 0x33, 0x87, 0x55, 0xc9, 0x21, 0x07, 0x93, + 0xbb, 0x67, 0xb8, 0xac, 0xf1, 0xa3, 0xcf, 0xf8, 0x7a, 0x30, 0x63, 0xe2, 0xa2, 0x3a, 0xba, 0xc7, + 0x7c, 0xd3, 0x55, 0x31, 0xb4, 0xe0, 0x73, 0x18, 0x94, 0xa9, 0xb7, 0x53, 0x74, 0xdc, 0x94, 0xf0, + 0x53, 0x46, 0x53, 0x19, 0xa6, 0x63, 0x64, 0x33, 0x16, 0x58, 0x47, 0xb3, 0x35, 0xf1, 0x85, 0xa6, + 0xc2, 0x22, 0xcd, 0x84, 0x86, 0x1b, 0x15, 0x9c, 0xc7, 0x5b, 0xed, 0x1f, 0x66, 0x8d, 0x1f, 0x82, + 0xca, 0xaf, 0x22, 0x51, 0x9b, 0xd1, 0x96, 0x0d, 0xda, 0x5b, 0x9f, 0x0a, 0x46, 0xf2, 0x69, 0x07, + 0xac, 0x1a, 0x6d, 0x8e, 0x55, 0x23, 0x7a, 0x66, 0xfd, 0x45, 0xac, 0x05, 0xe7, 0x85, 0x28, 0x24, + 0xd7, 0xc0, 0xd6, 0x67, 0x6e, 0x2a, 0xd4, 0x98, 0x6f, 0x52, 0xb2, 0xe2, 0x30, 0xea, 0x98, 0x92, + 0x99, 0x7e, 0x9e, 0x0a, 0x0f, 0xe3, 0x63, 0x74, 0x33, 0x62, 0x73, 0x4f, 0x2e, 0xfd, 0xab, 0x1b, + 0x54, 0x67, 0x6e, 0xd5, 0x8e, 0x22, 0xe5, 0x21, 0xeb, 0xbe, 0xa5, 0x1c, 0xc6, 0x52, 0x39, 0xfb, + 0xdf, 0x87, 0x8a, 0x92, 0x1b, 0xe2, 0x81, 0x5b, 0x65, 0xbc, 0xda, 0x5d, 0xad, 0x49, 0xa9, 0x53, + 0xff, 0x16, 0x54, 0xcd, 0x1a, 0x52, 0x6f, 0xe1, 0x02, 0x20, 0xdb, 0x44, 0x3c, 0x71, 0xba, 0x56, + 0xe7, 0x88, 0xd6, 0x57, 0xe0, 0xa6, 0x99, 0xf6, 0xe9, 0x11, 0xf4, 0x36, 0xcb, 0xae, 0xd9, 0x65, + 0xf0, 0xf4, 0xdf, 0x1b, 0x4d, 0xa2, 0x07, 0x76, 0x5b, 0x84, 0xc8, 0x9d, 0xce, 0x29, 0xf1, 0xa7, + 0xff, 0x85, 0x2d, 0x71, 0xfe, 0x43, 0x26, 0x6c, 0x6d, 0x65, 0x4a, 0x47, 0xdd, 0x93, 0xf7, 0xc6, + 0x48, 0xf6, 0x3e, 0x77, 0xb1, 0x87, 0xab, 0x7c, 0x89, 0x6d, 0xde, 0x8b, 0xc2, 0x96, 0xa1, 0x53, + 0x64, 0x36, 0x65, 0x96, 0x3b, 0x65, 0xda, 0xcd, 0x0c, 0x3e, 0x33, 0x9b, 0x4f, 0x8c, 0xe3, 0x17, + 0x6b, 0xf8, 0xed, 0x68, 0xb6, 0xe4, 0x9a, 0x97, 0x8c, 0xd3, 0xb9, 0x60, 0x6d, 0x5f, 0x76, 0x0d, + 0x29, 0x76, 0xf8, 0xa9, 0xc3, 0x70, 0xbc, 0x65, 0xd4, 0x76, 0xf6, 0x94, 0xfd, 0x3a, 0x43, 0x74, + 0xab, 0x39, 0xcb, 0x17, 0xc6, 0x8f, 0xc6, 0x69, 0x91, 0x99, 0x56, 0xcf, 0xde, 0xfa, 0xf4, 0xcf, + 0x9d, 0x1a, 0x1f, 0x84, 0x28, 0x75, 0x35, 0x4f, 0x86, 0x29, 0xa5, 0x58, 0x92, 0xf0, 0xa1, 0x28, + 0xde, 0xca, 0x4e, 0xc6, 0xb6, 0x27, 0x4b, 0xb1, 0x9d, 0x97, 0xb1, 0x4d, 0x9b, 0x50, 0xf3, 0xbe, + 0x0a, 0xe9, 0x26, 0x56, 0x6b, 0x63, 0x59, 0xa4, 0x6b, 0x34, 0x9f, 0x73, 0x31, 0x4a, 0xf0, 0xfe, + 0xe9, 0x4d, 0xfe, 0x79, 0x27, 0x05, 0xf4, 0xcb, 0xd6, 0xd9, 0xbf, 0x82, 0x0b, 0x19, 0x5b, 0xb1, + 0xbc, 0xfc, 0x2a, 0xab, 0x62, 0xdd, 0x5b, 0x51, 0x4a, 0x6f, 0x1c, 0xb3, 0x2f, 0xaf, 0x47, 0xe3, + 0x35, 0xb9, 0xf7, 0xee, 0xfa, 0x75, 0xb4, 0x36, 0xb5, 0xc6, 0xfe, 0x0a, 0xa4, 0x95, 0x5a, 0x23, + 0x31, 0x7e, 0x92, 0x09, 0xc6, 0xdf, 0x0f, 0x8d, 0xb7, 0x9d, 0x20, 0xb3, 0x74, 0xf8, 0x69, 0xa5, + 0x35, 0x13, 0x18, 0x65, 0x1b, 0x2f, 0x77, 0x37, 0x4d, 0xd7, 0xc6, 0x0b, 0x1d, 0xaf, 0xd2, 0x57, + 0x5a, 0xa4, 0x16, 0xad, 0x4b, 0x6b, 0xe3, 0x46, 0x5d, 0xdc, 0xb2, 0xe8, 0xaf, 0x26, 0xbc, 0xf7, + 0x29, 0x42, 0x9a, 0xae, 0x5e, 0x9f, 0x82, 0xfb, 0xbf, 0xbd, 0x36, 0xd4, 0x99, 0x2e, 0x13, 0x27, + 0x7f, 0xfc, 0x4f, 0x34, 0x09, 0x09, 0x49, 0x75, 0xc1, 0x2d, 0x09, 0x88, 0xed, 0xb2, 0x2d, 0x2c, + 0xeb, 0xe3, 0x79, 0x90, 0xb2, 0xf6, 0xa3, 0xbf, 0xa4, 0x6e, 0x60, 0xe6, 0xe6, 0x6c, 0x9f, 0x59, + 0xbd, 0xbf, 0xf0, 0x4d, 0x9f, 0x4d, 0xa5, 0xf3, 0x1f, 0x1c, 0x2d, 0xb4, 0xfb, 0x23, 0x47, 0xc9, + 0x9f, 0x05, 0x42, 0x10, 0x25, 0xdb, 0x8c, 0xab, 0x5d, 0xde, 0xfa, 0x97, 0x4d, 0x74, 0x8d, 0xe7, + 0x15, 0x68, 0x81, 0xb0, 0xd4, 0x1d, 0xbe, 0x6e, 0x74, 0xe2, 0x61, 0x4d, 0x07, 0x85, 0xcc, 0x05, + 0xa7, 0x4b, 0xe7, 0xb4, 0x2f, 0xec, 0x2e, 0x2a, 0xa3, 0x8a, 0x00, 0x95, 0xb3, 0x18, 0x69, 0xff, + 0x7d, 0xa1, 0xa0, 0xba, 0x7f, 0x33, 0x26, 0x4e, 0x4f, 0xcc, 0x47, 0xba, 0xf4, 0xd0, 0x53, 0x8d, + 0x5e, 0xd4, 0xb2, 0xb7, 0x35, 0xd3, 0x77, 0x7b, 0x8e, 0x64, 0x79, 0x19, 0x74, 0x41, 0x8a, 0x21, + 0xd1, 0x78, 0x80, 0xa1, 0x07, 0xa4, 0xc3, 0x96, 0x99, 0x0f, 0xc9, 0x78, 0x81, 0x14, 0x64, 0x46, + 0x96, 0x95, 0x79, 0x7a, 0xe7, 0xd6, 0xb6, 0xcf, 0xf6, 0x19, 0x99, 0x9a, 0xca, 0x56, 0xb9, 0x34, + 0x65, 0x1f, 0xa1, 0x4a, 0xfe, 0xa6, 0xc3, 0x64, 0x43, 0x78, 0x5e, 0xae, 0xf8, 0xd2, 0xcb, 0xd4, + 0xe3, 0xcb, 0x78, 0x9a, 0x82, 0xc9, 0xc1, 0x42, 0x06, 0xa0, 0xf4, 0x34, 0x0f, 0x96, 0x8c, 0x8d, + 0x08, 0xc6, 0xcb, 0x6e, 0x5b, 0xb2, 0x90, 0x50, 0x35, 0x6c, 0x73, 0x0f, 0x0f, 0xd1, 0x56, 0xa1, + 0x2f, 0xf1, 0xe7, 0x2e, 0x25, 0xac, 0xf7, 0xe5, 0xdf, 0x8c, 0xe3, 0x9a, 0xb2, 0xa7, 0x55, 0x37, + 0xcb, 0x89, 0x36, 0xdb, 0x6d, 0xf8, 0x47, 0x5a, 0xee, 0x6e, 0xb4, 0xc2, 0xcc, 0x96, 0xeb, 0x6f, + 0xfe, 0x1d, 0x37, 0xc3, 0x76, 0x66, 0x6e, 0xa4, 0x13, 0x7b, 0xc3, 0x3e, 0x8c, 0x1d, 0xbf, 0xe0, + 0xa7, 0xbb, 0x47, 0xcc, 0x6d, 0xb5, 0x6d, 0x72, 0xf8, 0x50, 0xb4, 0x6d, 0x33, 0xa4, 0x77, 0xbe, + 0x46, 0xc8, 0x3d, 0x8c, 0xd1, 0xda, 0xcb, 0xe1, 0xe3, 0x66, 0xf3, 0x37, 0x1d, 0xa2, 0xdc, 0x7b, + 0x69, 0xec, 0x5b, 0x79, 0x23, 0x0f, 0x29, 0x15, 0xa8, 0x3c, 0x16, 0x6e, 0x54, 0x6c, 0xa2, 0x9b, + 0xb2, 0xdf, 0x8d, 0x7b, 0x56, 0x2f, 0x8b, 0x5f, 0x10, 0x37, 0xc6, 0x38, 0xb2, 0xd5, 0x0a, 0x63, + 0x97, 0x8c, 0x24, 0x15, 0x0e, 0x0c, 0x21, 0x8c, 0xf2, 0x87, 0x1e, 0xa1, 0x77, 0xd5, 0x6e, 0x44, + 0x93, 0x2e, 0x5c, 0x69, 0x25, 0x09, 0xca, 0x7f, 0xc6, 0xed, 0xb0, 0x42, 0xe9, 0xa5, 0xd5, 0xc0, + 0xaa, 0x4e, 0x9c, 0xa7, 0x26, 0x69, 0x92, 0xec, 0xad, 0xb7, 0x1f, 0xca, 0x00, 0x9f, 0x24, 0xa8, + 0xcb, 0x8e, 0x28, 0x22, 0x94, 0x9d, 0x16, 0x5c, 0xcd, 0x69, 0x2b, 0x34, 0x1f, 0x52, 0x64, 0x8d, + 0x9a, 0x29, 0x29, 0x3e, 0x20, 0x6c, 0x9c, 0x7f, 0xd2, 0xea, 0x07, 0x8a, 0x94, 0x90, 0x27, 0x35, + 0x61, 0xad, 0x6e, 0x42, 0x92, 0xaf, 0x24, 0xb4, 0xb0, 0xd9, 0x48, 0xf3, 0xb4, 0x7e, 0xb4, 0x5f, + 0x44, 0x1f, 0x6f, 0xaa, 0x15, 0xa1, 0xd3, 0x95, 0x49, 0xb9, 0x2e, 0xf8, 0x10, 0x67, 0xc6, 0x1c, + 0xfd, 0xba, 0xbd, 0x31, 0x07, 0xa1, 0xa4, 0xdf, 0x06, 0x30, 0x99, 0xe1, 0x41, 0x44, 0x87, 0x6f, + 0xc2, 0x96, 0xd2, 0x2c, 0xbd, 0x3b, 0x75, 0xb1, 0x99, 0x97, 0xb1, 0x4a, 0x30, 0xb8, 0x7c, 0x3b, + 0x43, 0xbc, 0xcb, 0xb5, 0x0a, 0xc2, 0x74, 0xba, 0xee, 0x26, 0xb7, 0xf8, 0x2a, 0x10, 0x7a, 0x8e, + 0x42, 0x78, 0x3a, 0xd5, 0xe6, 0x58, 0xae, 0x4e, 0xb9, 0x60, 0xee, 0x35, 0x45, 0x5f, 0x05, 0x3d, + 0x26, 0xb1, 0x0a, 0x5b, 0xe0, 0xcd, 0x49, 0xe2, 0x46, 0xf8, 0x7a, 0xf9, 0xf3, 0xcd, 0x24, 0x54, + 0xc9, 0x2b, 0x13, 0x08, 0x3b, 0x71, 0xb0, 0x7f, 0x4c, 0x6d, 0x7c, 0x28, 0x54, 0x2d, 0x72, 0xe7, + 0xb8, 0x62, 0xf1, 0x01, 0xc6, 0xf2, 0xad, 0xc9, 0xea, 0x20, 0x9d, 0x12, 0x23, 0x75, 0xe3, 0x7e, + 0xc4, 0x8d, 0xd3, 0x9f, 0x19, 0xda, 0x69, 0x14, 0x69, 0xda, 0x34, 0xea, 0x69, 0x28, 0x77, 0x8c, + 0x59, 0x57, 0x01, 0x20, 0x8e, 0x51, 0x84, 0x1f, 0x1b, 0x74, 0x2d, 0x43, 0x14, 0x8f, 0xd1, 0x24, + 0xa9, 0x4d, 0xdf, 0xc3, 0xad, 0x49, 0x50, 0x60, 0x8f, 0x46, 0xd0, 0xa3, 0x60, 0xd2, 0x84, 0x6e, + 0xe9, 0x7c, 0x1f, 0xf8, 0xd2, 0xbf, 0x27, 0x49, 0xb9, 0xad, 0xcd, 0xe3, 0xf3, 0xf7, 0x83, 0xff, + 0x76, 0xdf, 0xfc, 0x13, 0xd8, 0xe9, 0x21, 0xa1, 0xa4, 0x37, 0x5c, 0x65, 0x4f, 0x8c, 0xb4, 0xde, + 0x69, 0x12, 0x0d, 0x4a, 0x0d, 0x11, 0x9f, 0x43, 0xb1, 0x9f, 0xd1, 0xf8, 0x52, 0x90, 0xce, 0x63, + 0xf7, 0x39, 0x74, 0xf4, 0x33, 0x22, 0x4e, 0x93, 0xd8, 0x41, 0xc0, 0xcc, 0xcd, 0x7c, 0x29, 0x6e, + 0x29, 0x15, 0x71, 0x84, 0x71, 0x83, 0x6b, 0x1b, 0xf1, 0xd0, 0xeb, 0x34, 0x4c, 0x63, 0xe3, 0x29, + 0x96, 0x2c, 0x94, 0x54, 0x64, 0xd4, 0x98, 0xa8, 0xb9, 0xc1, 0xb2, 0x0d, 0xf2, 0xe6, 0xd7, 0xc2, + 0x98, 0xbc, 0xd2, 0xd9, 0x1d, 0x96, 0xdd, 0x01, 0x83, 0x82, 0xfb, 0x92, 0xe6, 0xcc, 0x50, 0x7c, + 0x6d, 0xb6, 0x98, 0xfa, 0x37, 0x3b, 0xce, 0xc5, 0x2a, 0x8d, 0x2a, 0x28, 0x1a, 0x0e, 0x6f, 0x86, + 0x5e, 0xbf, 0xf8, 0x9d, 0x68, 0x1e, 0xe4, 0x41, 0x8d, 0xfc, 0x10, 0x4d, 0xdf, 0x14, 0x36, 0xbd, + 0x08, 0xba, 0x84, 0xd5, 0xa5, 0x91, 0x84, 0xc6, 0xc1, 0xdc, 0xff, 0xfc, 0x14, 0xd9, 0x26, 0x35, + 0x35, 0x55, 0xa1, 0x99, 0x86, 0xb1, 0x2e, 0x67, 0x8b, 0xe1, 0x8a, 0x50, 0xcd, 0x36, 0xf7, 0x91, + 0x93, 0xe3, 0x75, 0xfd, 0x71, 0x5f, 0xfc, 0x2d, 0x92, 0x4c, 0xb8, 0x3e, 0x6c, 0xeb, 0x67, 0xf7, + 0xff, 0x04, 0xb6, 0xe2, 0x93, 0x34, 0x92, 0xcb, 0xe3, 0x49, 0x5c, 0x45, 0xce, 0x11, 0x75, 0x17, + 0x88, 0xea, 0xb5, 0xaf, 0x54, 0x85, 0xa2, 0xa4, 0x26, 0xef, 0xcb, 0xd7, 0xf8, 0xd2, 0xc5, 0x99, + 0x02, 0x4b, 0x4e, 0xb3, 0x38, 0x1c, 0x0d, 0x88, 0x9f, 0x3d, 0x6d, 0x93, 0xdd, 0x33, 0xf9, 0xf1, + 0xa4, 0x44, 0x6c, 0x4e, 0x61, 0x6a, 0xf9, 0xfc, 0xf9, 0x2c, 0x9a, 0x6f, 0x72, 0xa5, 0xf3, 0xbf, + 0x8d, 0x8e, 0x2c, 0x7c, 0xb6, 0xfe, 0xea, 0x6a, 0x66, 0x19, 0xad, 0xbd, 0x86, 0xb7, 0x3d, 0xc7, + 0xaf, 0x52, 0xf8, 0xed, 0xbf, 0xf0, 0xa6, 0xec, 0x94, 0x65, 0x49, 0x94, 0x26, 0xf2, 0x77, 0x24, + 0xaa, 0xdb, 0xb3, 0xf6, 0xee, 0x2e, 0x90, 0x7c, 0x16, 0x15, 0x91, 0x39, 0xb7, 0xd8, 0xcd, 0xc7, + 0xb6, 0xcd, 0x8e, 0x4c, 0xf7, 0xc2, 0x96, 0x48, 0xdc, 0x77, 0xdb, 0x6f, 0xeb, 0xaa, 0x64, 0x8a, + 0x2a, 0x60, 0xed, 0xc5, 0x71, 0x6f, 0xc2, 0x86, 0x76, 0x59, 0x3c, 0xea, 0xb9, 0xf5, 0x2e, 0xa4, + 0xd2, 0x26, 0x15, 0x7f, 0x1b, 0x4e, 0xda, 0xe6, 0xf9, 0xb0, 0x71, 0x56, 0x5e, 0x49, 0x51, 0xda, + 0xae, 0xc6, 0xf5, 0xf6, 0xea, 0xbe, 0x10, 0x1b, 0x16, 0x9d, 0xea, 0xa2, 0x0e, 0x2c, 0xf8, 0x52, + 0x90, 0x3e, 0xe3, 0x2b, 0xdc, 0xf9, 0x1c, 0x69, 0x27, 0x66, 0xc6, 0x97, 0x5f, 0x0a, 0x19, 0x32, + 0xf4, 0xdb, 0xcb, 0xa2, 0xee, 0x8c, 0x57, 0x36, 0x7b, 0x49, 0xa4, 0x9f, 0xe3, 0x4d, 0x51, 0xdb, + 0x09, 0xba, 0x69, 0x60, 0xc3, 0xfc, 0x28, 0x4a, 0x36, 0xfd, 0xab, 0xba, 0xfa, 0xab, 0x75, 0x92, + 0x69, 0xc2, 0xf1, 0xb1, 0xe1, 0x97, 0x81, 0xf0, 0x61, 0x2e, 0x76, 0xe6, 0x06, 0x9a, 0xa4, 0xcf, + 0x1d, 0x67, 0x49, 0xb5, 0xc3, 0xea, 0xca, 0xe9, 0x5b, 0x6e, 0x78, 0x66, 0x59, 0x9a, 0x8b, 0xf1, + 0xf8, 0xc1, 0x2d, 0xc4, 0xbb, 0x3e, 0x34, 0xef, 0x52, 0xb4, 0xf7, 0x3e, 0x7e, 0x14, 0xd4, 0xd3, + 0x4d, 0x36, 0x9a, 0x49, 0x13, 0x2e, 0xad, 0x3e, 0x8a, 0x7e, 0x32, 0x7e, 0x6f, 0xd9, 0xc4, 0x8d, + 0x1d, 0xab, 0x47, 0xc9, 0x76, 0x4f, 0x12, 0x1e, 0xb6, 0x87, 0x0d, 0x25, 0xf6, 0x5b, 0x27, 0x58, + 0xc3, 0xe9, 0x23, 0x71, 0x5a, 0x38, 0x7c, 0x5b, 0xf1, 0x02, 0x42, 0x91, 0x6d, 0x63, 0xb4, 0x9f, + 0x12, 0x0c, 0xe9, 0xd3, 0xfd, 0xbb, 0x4d, 0x97, 0xe2, 0x1c, 0x9f, 0x29, 0x39, 0xd7, 0xf0, 0xa1, + 0x6c, 0x6b, 0x6d, 0x3f, 0xac, 0x5d, 0xf6, 0xef, 0xa5, 0x72, 0x63, 0xff, 0xf8, 0x52, 0x4c, 0x26, + 0x78, 0xb6, 0x9d, 0x27, 0x69, 0xa8, 0x87, 0x26, 0xbe, 0x14, 0x22, 0x45, 0x95, 0x95, 0x65, 0xda, + 0x47, 0xc5, 0xca, 0x7c, 0xab, 0x25, 0xbd, 0xc5, 0xf0, 0xa5, 0xfb, 0xb8, 0x8e, 0x25, 0x16, 0x4f, + 0x48, 0x69, 0x53, 0x6e, 0xa5, 0x7e, 0x14, 0x94, 0xc4, 0xb6, 0x7b, 0x46, 0xe0, 0x31, 0xbe, 0xdb, + 0x57, 0xa7, 0x1f, 0x6e, 0xfc, 0x7c, 0xb5, 0x8e, 0xf8, 0x53, 0x6d, 0x35, 0x07, 0xfa, 0xda, 0x37, + 0x1b, 0x57, 0x65, 0x4d, 0xd8, 0xc9, 0x5e, 0xef, 0x82, 0xc2, 0x34, 0x33, 0x92, 0x29, 0x2d, 0xa3, + 0x49, 0xa7, 0x26, 0x49, 0x71, 0x22, 0xf0, 0xf9, 0x36, 0x34, 0x67, 0xad, 0xb6, 0xac, 0xba, 0xc6, + 0x6e, 0x21, 0xdb, 0x11, 0x79, 0x52, 0x7d, 0x25, 0xaf, 0xfc, 0x6c, 0xac, 0x67, 0xe9, 0x35, 0x9f, + 0x36, 0x4a, 0xc2, 0xab, 0xf6, 0x02, 0xbb, 0xe8, 0xe6, 0xf6, 0x97, 0xc6, 0xd6, 0xe1, 0xac, 0xc6, + 0xde, 0xf3, 0x26, 0x42, 0xb0, 0xa3, 0x7c, 0x5a, 0x2d, 0xa5, 0x22, 0x25, 0x2c, 0xc3, 0x8c, 0x47, + 0x5a, 0x41, 0xf8, 0xce, 0x63, 0x38, 0x5c, 0x97, 0xe3, 0x75, 0x8d, 0x86, 0x99, 0xf9, 0x17, 0xa4, + 0xc6, 0x86, 0x28, 0x93, 0xc8, 0x36, 0xc7, 0x79, 0xba, 0x86, 0x50, 0x49, 0x07, 0x10, 0x0c, 0x8b, + 0x78, 0x3e, 0x83, 0x6a, 0x30, 0xcc, 0x6c, 0xcd, 0x58, 0xdb, 0xf8, 0x81, 0xbb, 0x83, 0xa2, 0xb2, + 0x5d, 0x27, 0xec, 0x63, 0xcc, 0xa4, 0x29, 0xc1, 0xf6, 0x6f, 0x4e, 0xfd, 0x3a, 0x65, 0x35, 0x03, + 0x69, 0x07, 0xfc, 0x0f, 0xe4, 0xf6, 0x3c, 0x6b, 0x37, 0x09, 0x34, 0xe8, 0x46, 0xd1, 0x11, 0x72, + 0x2f, 0xec, 0xe8, 0xf9, 0x30, 0xa5, 0x9f, 0x0d, 0x53, 0x94, 0xf1, 0x7d, 0xc7, 0xbd, 0xdf, 0xc6, + 0xd8, 0xf9, 0xe8, 0x78, 0xfd, 0x59, 0x98, 0xda, 0x69, 0x32, 0x99, 0x89, 0x55, 0xa0, 0xd5, 0x45, + 0xce, 0x28, 0x1a, 0x20, 0x76, 0x6c, 0x44, 0x18, 0xaa, 0x65, 0xfa, 0x00, 0xb6, 0x9a, 0x95, 0xfc, + 0x28, 0x57, 0x6b, 0xc7, 0xaf, 0x63, 0x59, 0xde, 0x9e, 0x18, 0x53, 0xd6, 0x1a, 0x0a, 0x7c, 0xc6, + 0xa8, 0xcf, 0x74, 0x40, 0x0e, 0x7c, 0x69, 0x12, 0x6e, 0x68, 0x0e, 0x57, 0xd2, 0x3c, 0x2a, 0xa4, + 0xc4, 0x0a, 0x1d, 0x26, 0x34, 0x55, 0x95, 0x03, 0x75, 0x61, 0x2a, 0x6a, 0xb4, 0x87, 0x8f, 0x97, + 0xa4, 0xfe, 0x22, 0x37, 0x1f, 0x64, 0x9b, 0x0c, 0x73, 0x7a, 0x49, 0xf0, 0x06, 0x24, 0x0a, 0xbf, + 0xd6, 0x05, 0x5d, 0xb0, 0xdf, 0x47, 0x4b, 0xba, 0x88, 0x8e, 0x57, 0xa9, 0x3e, 0x7f, 0xe1, 0x48, + 0x6e, 0xa3, 0x1f, 0x12, 0xdd, 0x42, 0x2c, 0xf7, 0xc4, 0x69, 0x6e, 0xb8, 0x94, 0x63, 0xe2, 0xe9, + 0x73, 0x64, 0x9c, 0x7c, 0x6d, 0x83, 0x13, 0x9c, 0xd5, 0x2b, 0x36, 0x6e, 0x6f, 0x52, 0x57, 0xe6, + 0x65, 0x3b, 0x2c, 0x31, 0xfd, 0x37, 0x70, 0xdb, 0x72, 0x68, 0xf7, 0xe3, 0xfe, 0x14, 0xad, 0x7c, + 0x5d, 0x2c, 0x5c, 0x87, 0x79, 0x05, 0x7b, 0x54, 0xe5, 0xe4, 0xcf, 0x46, 0x98, 0xab, 0x95, 0x8e, + 0x6d, 0x4d, 0x96, 0x17, 0xc1, 0x7e, 0x14, 0x2b, 0xbb, 0xeb, 0x5d, 0x69, 0x10, 0x8a, 0x88, 0x77, + 0x9d, 0x5f, 0xec, 0x9f, 0x4e, 0x49, 0x8d, 0x21, 0x5c, 0x71, 0xea, 0x1a, 0x1d, 0xdf, 0xe3, 0x78, + 0xe3, 0x78, 0x72, 0x22, 0x6d, 0x47, 0x79, 0xd3, 0x47, 0xcb, 0x80, 0x9f, 0xad, 0x95, 0x37, 0xce, + 0x30, 0xf4, 0xe5, 0x4f, 0xee, 0x98, 0xf1, 0x97, 0x7f, 0x1a, 0x42, 0xe2, 0x6f, 0x31, 0x86, 0x68, + 0x37, 0x5e, 0x93, 0xd4, 0xf5, 0x6e, 0x4b, 0xf4, 0x19, 0x18, 0xc6, 0x43, 0xd3, 0xac, 0xcd, 0xf4, + 0x74, 0x54, 0x7f, 0xfe, 0x34, 0xe9, 0x30, 0xc6, 0x8c, 0x3f, 0xba, 0x0f, 0x82, 0xe3, 0xcb, 0x94, + 0x51, 0xbd, 0x8e, 0x92, 0x9f, 0x2c, 0x5a, 0x2a, 0xa1, 0xd6, 0x5d, 0xff, 0xc2, 0x18, 0x89, 0x0a, + 0xa6, 0xb7, 0x4d, 0x92, 0x22, 0xb5, 0x92, 0xa5, 0xf0, 0x8c, 0xf2, 0xa9, 0x95, 0x36, 0xfa, 0x23, + 0xb0, 0x56, 0x21, 0x78, 0x28, 0xa1, 0xcf, 0x0d, 0xa9, 0xa5, 0xff, 0x8c, 0xb5, 0x4c, 0x7d, 0x68, + 0x4e, 0x8e, 0x87, 0xb5, 0x96, 0xcd, 0x12, 0xe3, 0xa5, 0x07, 0xe3, 0x35, 0xc7, 0xa6, 0x5e, 0x7c, + 0xf7, 0x5a, 0x43, 0x97, 0x9c, 0xdf, 0x19, 0x49, 0xd5, 0x86, 0x6c, 0xbe, 0xb5, 0xc9, 0x97, 0x41, + 0xca, 0x82, 0xa5, 0xe7, 0xfe, 0x3e, 0x92, 0x1b, 0x1a, 0x1a, 0x19, 0x50, 0xdc, 0x60, 0xc4, 0x6f, + 0xd5, 0x4b, 0xe3, 0x48, 0xba, 0xa7, 0xc4, 0x77, 0x65, 0x8f, 0xad, 0x55, 0x77, 0x13, 0x31, 0x8f, + 0x6b, 0x5e, 0xcd, 0x43, 0x75, 0x2d, 0x3f, 0x8b, 0x72, 0x9b, 0x7c, 0xb0, 0xff, 0x0a, 0x5f, 0x14, + 0x9f, 0x95, 0xa0, 0xd0, 0x6e, 0x86, 0xa6, 0x93, 0xb1, 0x93, 0xc1, 0xee, 0x40, 0xfe, 0x33, 0xcd, + 0x1d, 0xbb, 0x6c, 0x79, 0x75, 0xad, 0xd1, 0xe5, 0x8f, 0x82, 0xb8, 0xc5, 0x7a, 0xda, 0x5f, 0x6c, + 0x90, 0x7d, 0x26, 0x22, 0xa7, 0xc1, 0x48, 0xb2, 0xbd, 0x0e, 0x9a, 0xab, 0xb9, 0x14, 0x42, 0x50, + 0x24, 0x5d, 0xf9, 0x97, 0x82, 0xa1, 0x0c, 0x71, 0xb1, 0xa6, 0xe7, 0x64, 0xf0, 0x59, 0x56, 0x8c, + 0xcc, 0xbd, 0x91, 0x52, 0x31, 0xf1, 0xb6, 0xae, 0x96, 0xb4, 0xd5, 0x46, 0xff, 0xfb, 0x95, 0x47, + 0xe7, 0xb5, 0x90, 0xf8, 0x47, 0xf4, 0x6b, 0xaa, 0x59, 0x53, 0x98, 0x53, 0x42, 0xd9, 0x51, 0x28, + 0xb2, 0xf8, 0x52, 0x9c, 0x47, 0xf7, 0xb6, 0x86, 0xb2, 0x35, 0x56, 0xec, 0xaf, 0x1e, 0x0f, 0x8d, + 0xe6, 0x61, 0x9a, 0xfb, 0x2c, 0xf5, 0x65, 0x69, 0x74, 0xba, 0xb6, 0x99, 0x74, 0x99, 0x71, 0x89, + 0xbd, 0x6b, 0x2f, 0x4d, 0xfe, 0x14, 0x99, 0x84, 0xb1, 0xdb, 0xc7, 0xed, 0xc5, 0x79, 0x0e, 0xd1, + 0x19, 0x5d, 0xbd, 0xcf, 0x73, 0x46, 0xf9, 0xd5, 0x77, 0xc2, 0x1a, 0xd9, 0xad, 0xa4, 0x33, 0xc1, + 0xbb, 0x1e, 0x98, 0xce, 0x67, 0xd8, 0xfc, 0x28, 0x53, 0x30, 0xa6, 0xe9, 0x9e, 0xae, 0x93, 0x5b, + 0x37, 0xa3, 0x83, 0x63, 0x43, 0xb2, 0x9b, 0x27, 0x61, 0x99, 0x7c, 0x14, 0x88, 0x4c, 0xd2, 0x63, + 0x6e, 0x29, 0xca, 0x5b, 0x9f, 0x43, 0x58, 0x63, 0xc3, 0x55, 0x8d, 0x3b, 0xad, 0xd5, 0x7f, 0xc2, + 0x02, 0xe5, 0xed, 0xef, 0x79, 0xfd, 0xcb, 0x1f, 0x19, 0x9f, 0x1a, 0x7e, 0x59, 0xf6, 0x37, 0x77, + 0x67, 0xf3, 0x13, 0x97, 0x7c, 0x66, 0x65, 0xf4, 0xd3, 0x4c, 0x9c, 0xdf, 0x5a, 0xea, 0xbe, 0x0a, + 0xed, 0xf1, 0x56, 0x99, 0xb9, 0xf2, 0xa6, 0xe9, 0x53, 0x3f, 0x05, 0x77, 0x3c, 0xb3, 0x66, 0x4e, + 0xe5, 0xcd, 0x3a, 0xf8, 0xed, 0x3a, 0x6e, 0xd6, 0xa7, 0x36, 0xbc, 0xf8, 0xe8, 0xad, 0xb6, 0xa4, + 0xee, 0x9c, 0x9a, 0x4d, 0x69, 0xbf, 0xc6, 0x52, 0x2c, 0x69, 0x57, 0xa6, 0x9b, 0xb4, 0x5c, 0x6b, + 0xb5, 0xe3, 0x35, 0x4d, 0xbd, 0xc5, 0xf1, 0x7d, 0x6b, 0xc4, 0x02, 0xeb, 0x97, 0x5a, 0xdc, 0x57, + 0x78, 0xbe, 0x10, 0xed, 0xb4, 0x92, 0x4f, 0x6d, 0x5f, 0xe2, 0xb2, 0xe4, 0xb8, 0x6c, 0xd7, 0xe2, + 0xa9, 0x69, 0x4b, 0xdb, 0x9f, 0x19, 0xbb, 0xa7, 0x25, 0x65, 0x9d, 0x24, 0x54, 0x87, 0x7b, 0xa6, + 0xcf, 0xc6, 0x92, 0x19, 0x58, 0xe8, 0x1b, 0xba, 0x38, 0x84, 0x2c, 0x7b, 0x43, 0xe2, 0x11, 0xeb, + 0x8b, 0xef, 0x9f, 0xf8, 0x2c, 0x32, 0x4d, 0x97, 0x75, 0x1f, 0xb6, 0xe3, 0xc9, 0x3a, 0x45, 0xad, + 0x07, 0x41, 0xd7, 0x11, 0x0a, 0x56, 0xb6, 0x71, 0xd1, 0xb7, 0x30, 0xd6, 0x2e, 0x2e, 0x2f, 0x17, + 0xc1, 0x5d, 0xea, 0x62, 0x5c, 0x98, 0x6b, 0x13, 0x19, 0x98, 0x67, 0x69, 0xaa, 0x7e, 0xf8, 0x2a, + 0x12, 0xad, 0xa3, 0x46, 0xce, 0x93, 0x6b, 0x78, 0xb6, 0x70, 0xf1, 0xb6, 0x55, 0x66, 0xa2, 0x1d, + 0x7c, 0x55, 0xb0, 0xec, 0x34, 0xec, 0x92, 0x4a, 0x6d, 0xe2, 0xd5, 0xca, 0x90, 0x0f, 0xee, 0xb9, + 0x15, 0x63, 0xaa, 0xbf, 0x8d, 0x33, 0x4e, 0xbb, 0xc0, 0x8d, 0xb3, 0x35, 0xbd, 0x2c, 0x03, 0x48, + 0xc2, 0x0a, 0x09, 0x25, 0xb0, 0xcf, 0x61, 0x54, 0xa5, 0xcc, 0xa2, 0xb4, 0x93, 0x4e, 0xb4, 0x82, + 0xfa, 0xf8, 0x50, 0xad, 0x54, 0xa2, 0xe2, 0x04, 0x79, 0x71, 0x56, 0x0d, 0x12, 0xbc, 0x50, 0xf1, + 0xd5, 0x32, 0x71, 0xd1, 0x86, 0x94, 0x1b, 0xe3, 0x35, 0x8d, 0x50, 0x7b, 0x25, 0x35, 0xb9, 0x24, + 0x25, 0x17, 0xa9, 0x33, 0x60, 0x9a, 0xa3, 0x89, 0x91, 0x52, 0xc2, 0xf1, 0xe6, 0x18, 0xbd, 0xc7, + 0x59, 0x58, 0x6e, 0x68, 0xca, 0x81, 0x95, 0x91, 0x54, 0x0f, 0xc2, 0x96, 0x28, 0x43, 0x76, 0xe0, + 0x7f, 0x9e, 0x7a, 0xac, 0xc2, 0x6c, 0x8f, 0x06, 0xf0, 0xa6, 0xa7, 0x30, 0xee, 0xee, 0x54, 0xf8, + 0x89, 0xdf, 0x33, 0xb4, 0xd9, 0x17, 0xf8, 0x50, 0xa4, 0xc6, 0x60, 0xed, 0x8c, 0xf1, 0xca, 0x58, + 0xd1, 0xbc, 0xf7, 0xc0, 0xda, 0x46, 0x54, 0x5a, 0xf6, 0xaa, 0xcf, 0xe7, 0xc2, 0x95, 0x06, 0x5e, + 0x5f, 0xa3, 0x2d, 0x68, 0x3c, 0x66, 0x90, 0x76, 0xd1, 0x1d, 0xb0, 0x34, 0x1c, 0xf8, 0xc3, 0x33, + 0x5f, 0x94, 0xe3, 0xb8, 0x10, 0xec, 0x66, 0xda, 0x2c, 0x31, 0xbb, 0x56, 0x3e, 0x2d, 0x8b, 0xf9, + 0xac, 0x6b, 0xe3, 0x4a, 0xa4, 0x78, 0x58, 0xb9, 0xaf, 0x3a, 0xc6, 0x4d, 0x35, 0xd9, 0x7c, 0x39, + 0xe5, 0x26, 0x3d, 0x8e, 0x3e, 0x4a, 0x3c, 0xc4, 0x4c, 0x52, 0x7e, 0x81, 0x5a, 0x4c, 0xf6, 0x1f, + 0x2d, 0x21, 0xe8, 0xff, 0x0a, 0x57, 0x10, 0x77, 0xc0, 0x87, 0x21, 0xac, 0x74, 0xcc, 0x02, 0xfd, + 0x90, 0xef, 0x3a, 0xb4, 0xdb, 0x26, 0x3e, 0x36, 0xfd, 0x3a, 0xc9, 0x79, 0x54, 0xbd, 0x6d, 0x60, + 0xed, 0xa6, 0xf9, 0x44, 0x6c, 0x84, 0xe4, 0x22, 0xb7, 0x6d, 0x02, 0xdd, 0x53, 0x2e, 0x77, 0xf8, + 0x50, 0xb6, 0x37, 0x24, 0x13, 0x08, 0x9b, 0xd5, 0x43, 0xdf, 0x05, 0xc7, 0xe9, 0xbb, 0x1d, 0x74, + 0x69, 0xa0, 0xc8, 0x92, 0xbe, 0x08, 0x36, 0xf3, 0xe6, 0x9e, 0x06, 0x54, 0xd5, 0x8f, 0xab, 0xbb, + 0xbf, 0xf8, 0x52, 0x89, 0x2a, 0x4d, 0x4b, 0x71, 0x15, 0x11, 0x91, 0x70, 0xcb, 0x96, 0x6d, 0xea, + 0x9d, 0xbe, 0x14, 0xe3, 0xc9, 0xec, 0x3d, 0x79, 0xb9, 0xb1, 0x84, 0xac, 0xdc, 0x76, 0x13, 0x45, + 0x63, 0x84, 0x7a, 0x6f, 0xf1, 0x95, 0x37, 0x5c, 0xa9, 0xf8, 0xfd, 0x94, 0x36, 0x63, 0x58, 0xc0, + 0x76, 0xb5, 0xa4, 0x92, 0xab, 0x74, 0x3a, 0x48, 0x5e, 0x85, 0xe3, 0x66, 0x53, 0x6b, 0x12, 0xa3, + 0x58, 0x87, 0xc4, 0x1e, 0x53, 0x49, 0x14, 0xf1, 0xf1, 0x78, 0x60, 0x58, 0xba, 0xa3, 0xbd, 0xe3, + 0x09, 0xc8, 0x8a, 0x65, 0xb3, 0x72, 0xff, 0xfc, 0x29, 0x66, 0x47, 0x8d, 0xe1, 0x0e, 0x8d, 0xf8, + 0xdc, 0x23, 0xea, 0x88, 0xd9, 0xe3, 0x06, 0xe3, 0xb7, 0xc2, 0x99, 0xb6, 0xd3, 0xdb, 0xee, 0x5c, + 0xde, 0xb1, 0x64, 0xc8, 0x60, 0x4e, 0x19, 0xf2, 0x59, 0x4b, 0xff, 0xea, 0xf8, 0x52, 0x35, 0x76, + 0xb7, 0xe3, 0xd0, 0x35, 0x96, 0xb5, 0xd9, 0x6d, 0x41, 0x4b, 0x79, 0x31, 0xee, 0xf0, 0x9d, 0x08, + 0xeb, 0xe2, 0xad, 0x11, 0x84, 0xdd, 0xcc, 0xc7, 0xf8, 0x2a, 0xd1, 0xb2, 0x50, 0xad, 0x6c, 0xd2, + 0x97, 0xb6, 0xfe, 0x39, 0x4e, 0x05, 0x5e, 0x14, 0xb1, 0x23, 0x52, 0xd0, 0xdb, 0xbb, 0x46, 0x61, + 0xcf, 0x7b, 0x2d, 0x89, 0x1c, 0xa6, 0xca, 0x93, 0x3e, 0xa0, 0xc2, 0xa0, 0xb7, 0xfc, 0x4f, 0x22, + 0xe8, 0x6a, 0x28, 0x69, 0x41, 0xb5, 0x6b, 0xf0, 0x89, 0xd3, 0xa3, 0xb1, 0xbb, 0x45, 0xcf, 0x4d, + 0x3f, 0x05, 0x83, 0x39, 0x36, 0x86, 0x86, 0x86, 0x87, 0xa7, 0x19, 0x57, 0x7c, 0x3a, 0x5a, 0x4a, + 0x5d, 0x24, 0x97, 0xd8, 0xf3, 0x32, 0xc3, 0xc5, 0xeb, 0xf1, 0x27, 0x49, 0xb2, 0xe6, 0xe8, 0xbf, + 0x31, 0x9b, 0xb6, 0xfe, 0x24, 0x95, 0xbd, 0xef, 0xe3, 0x0e, 0xd9, 0x9e, 0x87, 0x56, 0x31, 0x57, + 0x3e, 0xea, 0xd2, 0xab, 0x65, 0xcf, 0x0a, 0x13, 0x24, 0x35, 0x4e, 0x9e, 0xef, 0xcd, 0xe5, 0xf3, + 0x09, 0xc5, 0xd7, 0xc2, 0x33, 0xfb, 0xb4, 0xda, 0x69, 0xb6, 0xa5, 0xd6, 0xaa, 0xf0, 0xf9, 0x9c, + 0x5e, 0x6f, 0x17, 0x6c, 0x98, 0x4c, 0xb3, 0x3c, 0x5d, 0xbb, 0x67, 0xf5, 0x2f, 0x67, 0xf0, 0x52, + 0x5b, 0x6d, 0x49, 0xe3, 0xab, 0xaf, 0xaf, 0x85, 0xc9, 0xb4, 0x6e, 0xf6, 0xed, 0x66, 0xf1, 0x1f, + 0xfe, 0x89, 0x17, 0xca, 0x2c, 0xda, 0x6d, 0x1c, 0x57, 0x6f, 0x8c, 0x93, 0x34, 0xac, 0x91, 0x22, + 0x64, 0xd6, 0xd4, 0x9d, 0xb9, 0xf1, 0xf6, 0xaa, 0xb4, 0x93, 0xd2, 0x49, 0x2a, 0xf8, 0x43, 0x93, + 0x53, 0xa6, 0xf7, 0xb3, 0xaf, 0x9a, 0xd3, 0x4d, 0x34, 0xb8, 0x8b, 0xea, 0xf7, 0x7f, 0x76, 0x9a, + 0xfc, 0x23, 0xab, 0x4d, 0x6a, 0xb7, 0xb5, 0xe1, 0x1a, 0x1a, 0x13, 0x26, 0x9e, 0xd4, 0x8c, 0x44, + 0xd2, 0x7e, 0x14, 0x19, 0x47, 0xca, 0x95, 0x15, 0x8f, 0x35, 0x1e, 0xfc, 0xcd, 0xb1, 0xb1, 0xc4, + 0xc2, 0x93, 0xdd, 0x38, 0x4a, 0x55, 0x73, 0x5d, 0xba, 0xcc, 0x2d, 0xec, 0xf4, 0xdb, 0xef, 0x85, + 0x0e, 0xb1, 0x04, 0x2a, 0x04, 0xc6, 0x4f, 0x66, 0x0e, 0x41, 0xd3, 0x4f, 0x6d, 0x50, 0x3f, 0x6b, + 0xf1, 0xdf, 0x16, 0x41, 0x29, 0x8b, 0xb6, 0x05, 0xb2, 0x6f, 0xf8, 0x2b, 0x3a, 0x6f, 0x9e, 0x16, + 0xad, 0xd1, 0xa3, 0x8b, 0xe1, 0x1e, 0x99, 0x73, 0x7b, 0xb4, 0x38, 0xaa, 0xd7, 0x8b, 0xc3, 0xe4, + 0x65, 0x3d, 0x97, 0x1f, 0x1f, 0xb0, 0xe3, 0x31, 0x65, 0x04, 0x4a, 0x94, 0xd7, 0x6f, 0xfc, 0x10, + 0x16, 0x37, 0x4f, 0x3a, 0x11, 0x93, 0xff, 0x74, 0xd5, 0xe2, 0x5a, 0xff, 0xc3, 0xc2, 0x36, 0x45, + 0x41, 0x7b, 0xa4, 0x2b, 0x71, 0x0f, 0x72, 0xda, 0x55, 0x1f, 0x45, 0x15, 0x7f, 0xf8, 0x29, 0x12, + 0x58, 0xe4, 0xb0, 0xae, 0x4b, 0xd2, 0x5b, 0x5d, 0x2a, 0xf1, 0xd5, 0x91, 0x8a, 0x72, 0xc5, 0xb6, + 0xe7, 0xef, 0xe0, 0xa8, 0x45, 0xd9, 0x3d, 0xea, 0x8a, 0xd9, 0xc9, 0x56, 0x47, 0x9f, 0x05, 0x35, + 0xad, 0xd6, 0x5d, 0x7e, 0x76, 0xaa, 0xce, 0x77, 0xc1, 0x76, 0xb7, 0x31, 0x26, 0x5e, 0x66, 0x5f, + 0xe3, 0xb1, 0x68, 0xcf, 0x77, 0x1d, 0x1c, 0x77, 0x46, 0xa8, 0xb7, 0xef, 0x82, 0xb2, 0x97, 0x2d, + 0x38, 0xf3, 0x6d, 0x06, 0xec, 0xcf, 0xa2, 0x1c, 0x1e, 0x5e, 0x39, 0xf0, 0x55, 0x4a, 0xb9, 0x1d, + 0x61, 0x4b, 0xcb, 0x48, 0x3b, 0x1c, 0x5f, 0x0f, 0xf7, 0x65, 0x8d, 0x9a, 0xb6, 0xd3, 0xfb, 0x1b, + 0x23, 0xb0, 0xe1, 0x01, 0xa9, 0x56, 0x54, 0x7b, 0xff, 0x0f, 0x9d, 0x2a, 0x64, 0x4e, 0xe6, 0xe4, + 0x29, 0x6a, 0x31, 0x75, 0x5b, 0x7c, 0xbf, 0xfc, 0x16, 0x11, 0x09, 0x0d, 0x64, 0x7f, 0x42, 0x6d, + 0x13, 0xcd, 0x7c, 0x44, 0xeb, 0x3a, 0x4c, 0x4b, 0xae, 0x51, 0x33, 0xb9, 0x7f, 0x05, 0x7a, 0xa5, + 0xc2, 0x3c, 0x2a, 0x73, 0xbc, 0xac, 0xe2, 0x48, 0xad, 0xf0, 0x9d, 0xfa, 0x66, 0x55, 0x32, 0xaf, + 0x85, 0xa9, 0xb2, 0x19, 0x99, 0x4f, 0x59, 0x79, 0xe3, 0x0b, 0xfc, 0x6d, 0xb8, 0x2a, 0xd1, 0x51, + 0xb1, 0x2a, 0x5a, 0x9d, 0x47, 0x9d, 0x75, 0x4c, 0x9c, 0x45, 0xff, 0xf8, 0xce, 0x83, 0x3e, 0xd6, + 0xf4, 0x5b, 0x12, 0x46, 0x95, 0xa8, 0x75, 0x45, 0x5b, 0x85, 0x06, 0xc7, 0xe0, 0xb2, 0xc4, 0x89, + 0x25, 0x22, 0x0c, 0x7b, 0x24, 0x47, 0x4b, 0x07, 0xc3, 0xd2, 0x30, 0x54, 0x1b, 0x2a, 0x6c, 0xde, + 0xae, 0x46, 0xb1, 0xaa, 0x9a, 0x6d, 0xb7, 0xfe, 0x14, 0xec, 0xf7, 0xf4, 0xcb, 0x24, 0xb0, 0x49, + 0x1d, 0x98, 0x37, 0x66, 0x71, 0x7c, 0x25, 0x7b, 0x74, 0x9d, 0x2f, 0x8e, 0x2f, 0x71, 0x59, 0x3e, + 0xcf, 0x4e, 0xd8, 0xf5, 0x3c, 0x71, 0x1d, 0xbf, 0x26, 0x65, 0xec, 0x0d, 0xa6, 0x75, 0x69, 0x9f, + 0xc4, 0x94, 0xb1, 0xea, 0xa6, 0x97, 0xe1, 0xbd, 0xb9, 0xba, 0xfd, 0xb7, 0x6f, 0xc7, 0xdf, 0x63, + 0xe2, 0xb6, 0x9a, 0xb5, 0xe0, 0x80, 0x9c, 0xb8, 0xba, 0xad, 0x7a, 0xfc, 0x43, 0xef, 0xe3, 0x63, + 0xf5, 0xd4, 0xf6, 0xd5, 0x2f, 0x4e, 0x36, 0xe6, 0xe7, 0x6a, 0xac, 0xa5, 0x95, 0xd6, 0x2b, 0xff, + 0x0b, 0x5f, 0xeb, 0x8e, 0x92, 0x44, 0xc8, 0xaf, 0x55, 0x55, 0x7b, 0x67, 0xfe, 0x10, 0x23, 0x6d, + 0xba, 0x4e, 0xf2, 0xe0, 0xda, 0xca, 0xb5, 0xfc, 0x7e, 0xdd, 0xb6, 0xb5, 0x33, 0x13, 0x11, 0xfe, + 0x16, 0x3d, 0xd3, 0x86, 0xab, 0x32, 0x6b, 0x19, 0xf7, 0x10, 0xf9, 0xbe, 0x27, 0xfe, 0x0a, 0x6f, + 0x76, 0xae, 0x97, 0x49, 0x2d, 0x7c, 0x69, 0x9c, 0x67, 0x0f, 0xba, 0x2b, 0xee, 0x34, 0xde, 0xde, + 0x95, 0xdd, 0x09, 0x84, 0x9e, 0xdf, 0xf8, 0x28, 0xe9, 0xb5, 0x93, 0x4d, 0x5f, 0x3e, 0x1d, 0xe4, + 0xed, 0x69, 0xd3, 0xb4, 0x94, 0x2c, 0xbe, 0x6f, 0x46, 0xdf, 0x88, 0x1a, 0x94, 0x9f, 0xb4, 0xd7, + 0x85, 0x36, 0x9a, 0x69, 0x69, 0xcb, 0xb1, 0x24, 0x91, 0x36, 0xcd, 0x48, 0xc8, 0x8b, 0xc6, 0x8a, + 0x36, 0x7b, 0xa7, 0x4d, 0x3a, 0x19, 0x9e, 0xf8, 0x55, 0xc7, 0x3a, 0xff, 0xc6, 0x1d, 0x2a, 0x4d, + 0xbd, 0x24, 0x89, 0x5c, 0xd3, 0x6a, 0xab, 0xf3, 0x77, 0x4b, 0xc6, 0x5a, 0x76, 0xd5, 0xd7, 0xb9, + 0x3c, 0x69, 0xa4, 0xff, 0x09, 0x96, 0x4c, 0xf6, 0xd5, 0xf1, 0x44, 0xbd, 0xdb, 0x2e, 0xfe, 0x0a, + 0xce, 0xa6, 0xc3, 0xe7, 0xbb, 0xdd, 0xd6, 0xe7, 0xc6, 0x19, 0xab, 0x77, 0xe3, 0xd4, 0x1e, 0x4a, + 0x68, 0x7f, 0xb7, 0x6b, 0xef, 0xe0, 0x94, 0x53, 0xfa, 0xfa, 0x50, 0x9e, 0xc5, 0x3d, 0xe6, 0xf8, + 0x74, 0x4d, 0x35, 0x4e, 0x7c, 0x34, 0x37, 0xdb, 0xe8, 0xaf, 0x8b, 0xbf, 0xe1, 0xd9, 0xec, 0x2e, + 0xee, 0x8d, 0xd3, 0x47, 0x6d, 0xab, 0x25, 0xe9, 0xff, 0xe0, 0xb0, 0x84, 0x68, 0x74, 0x50, 0x9e, + 0xd1, 0x37, 0xa6, 0xd3, 0xf1, 0x3e, 0x38, 0xf0, 0xa7, 0x5a, 0x0a, 0xcb, 0x62, 0xb7, 0x70, 0xc3, + 0x4c, 0xaf, 0x36, 0x90, 0xd8, 0x75, 0xf4, 0xf6, 0x5c, 0x89, 0x87, 0x8d, 0x21, 0x11, 0x0d, 0x27, + 0xd1, 0xde, 0x2b, 0xb8, 0xdc, 0x5a, 0xf6, 0x9e, 0x32, 0x38, 0xd8, 0xe7, 0x1f, 0x8d, 0x73, 0xeb, + 0xe0, 0x90, 0xed, 0x0e, 0x29, 0x3c, 0x8b, 0x2f, 0x8f, 0xc6, 0x14, 0xde, 0x28, 0xc9, 0x14, 0x54, + 0x4d, 0x1d, 0xff, 0x84, 0x0c, 0xd3, 0x6e, 0x78, 0x5e, 0xfb, 0x96, 0x0f, 0x20, 0xf8, 0x29, 0x3b, + 0x36, 0x6c, 0x63, 0x25, 0x59, 0x52, 0xb0, 0xe7, 0x44, 0xf8, 0x78, 0xf8, 0x24, 0xd9, 0x31, 0x8f, + 0xe3, 0x63, 0xe3, 0x28, 0x6b, 0xb4, 0x18, 0xa9, 0x84, 0xd1, 0x4f, 0x3a, 0xdb, 0x87, 0xac, 0x37, + 0xbc, 0x83, 0x5d, 0x9e, 0x90, 0x52, 0x33, 0x45, 0xaf, 0x65, 0xe0, 0xb7, 0x49, 0x7b, 0x22, 0x12, + 0xdb, 0x91, 0x25, 0xf8, 0x2d, 0xb2, 0x61, 0x39, 0xcd, 0xb4, 0xcc, 0xcd, 0xeb, 0xe3, 0x23, 0x76, + 0x69, 0x52, 0xd2, 0x3c, 0x60, 0xd0, 0xcd, 0xbe, 0x75, 0x09, 0x7e, 0x11, 0x29, 0x16, 0xa1, 0xb9, + 0x35, 0x86, 0x4d, 0x43, 0xb7, 0xb0, 0xa0, 0xe3, 0xc0, 0xfc, 0x44, 0x35, 0x49, 0xd0, 0xe4, 0xe8, + 0x49, 0x26, 0x28, 0x3f, 0x84, 0x27, 0x4d, 0x8a, 0x99, 0x52, 0xd4, 0xb3, 0x2c, 0x86, 0x3b, 0x89, + 0xf1, 0xfd, 0xd8, 0xc7, 0xcf, 0x11, 0xd2, 0x2a, 0x42, 0xb5, 0xac, 0xa0, 0xdc, 0x18, 0x3e, 0x49, + 0x1e, 0x86, 0xdb, 0x7e, 0x34, 0xc7, 0x81, 0x71, 0x8f, 0xdb, 0xb7, 0x4e, 0x56, 0x1a, 0x69, 0x36, + 0x9e, 0x07, 0x4c, 0x8b, 0x14, 0xff, 0xf0, 0xfd, 0x26, 0x44, 0x6d, 0x27, 0xcb, 0xb9, 0x22, 0xd2, + 0x18, 0xd9, 0xeb, 0x1e, 0xd5, 0x12, 0x7f, 0xe0, 0x9e, 0xec, 0x36, 0x32, 0x21, 0x1f, 0x3c, 0xc1, + 0x40, 0xd6, 0x3f, 0xc1, 0x4c, 0x72, 0xbd, 0xed, 0x63, 0x42, 0x83, 0x1a, 0x4a, 0x6a, 0x07, 0xb1, + 0x44, 0xf4, 0x0f, 0x4e, 0xff, 0x0a, 0x58, 0x6d, 0x50, 0xde, 0xdc, 0x82, 0xc3, 0x3e, 0x3a, 0x19, + 0x5e, 0xd4, 0x44, 0x65, 0x71, 0xf9, 0x40, 0xab, 0xc1, 0x06, 0x6d, 0xa4, 0x89, 0xe5, 0x29, 0xa1, + 0x4c, 0xbe, 0xa3, 0xfc, 0x8f, 0xff, 0x13, 0xe5, 0x63, 0xba, 0x4c, 0x7e, 0x38, 0xe5, 0xff, 0x27, + 0x4d, 0x34, 0xdc, 0x5f, 0xf0, 0xa6, 0xe9, 0x9b, 0x8e, 0x51, 0xcc, 0xa6, 0xa8, 0xba, 0xb6, 0x37, + 0x31, 0x1e, 0xb9, 0x34, 0x75, 0xb1, 0xbf, 0xc2, 0x92, 0x31, 0x63, 0x2e, 0xdd, 0x55, 0xac, 0x41, + 0xb5, 0x86, 0xb0, 0xdb, 0x56, 0xaf, 0xf0, 0xa1, 0xa7, 0xc7, 0xa9, 0xa6, 0xa9, 0xe9, 0x24, 0x4c, + 0xe2, 0xcb, 0xe3, 0xcf, 0x3f, 0x5c, 0xff, 0x64, 0x9a, 0xaa, 0x7f, 0x1b, 0xd4, 0xd8, 0xd8, 0x9f, + 0xe8, 0xae, 0xda, 0x1d, 0x0c, 0xda, 0xcf, 0xb7, 0x6d, 0x7c, 0x28, 0x44, 0x0a, 0x94, 0x6d, 0x61, + 0x6d, 0x69, 0xe3, 0x27, 0x6e, 0x8d, 0x6a, 0xda, 0x29, 0x49, 0x14, 0xef, 0x82, 0xc1, 0x29, 0xa9, + 0x3c, 0x72, 0x79, 0x3e, 0xd3, 0x5c, 0xbe, 0x30, 0x63, 0x76, 0xd0, 0xea, 0xbf, 0x1a, 0xd2, 0x78, + 0xf3, 0xf8, 0xad, 0xf8, 0x50, 0x5b, 0xed, 0x24, 0xd8, 0x41, 0xdb, 0x1a, 0xd2, 0x6e, 0x49, 0x8d, + 0xf5, 0xf0, 0x52, 0x2b, 0x74, 0x53, 0xf3, 0xf1, 0xcc, 0x3f, 0xe6, 0xe9, 0x19, 0x4f, 0x84, 0x45, + 0xa6, 0x76, 0x55, 0xed, 0x58, 0xc5, 0x3a, 0x74, 0xfc, 0x60, 0xa1, 0xa5, 0x6e, 0xfb, 0x54, 0x8f, + 0xd3, 0x6c, 0xbf, 0x6d, 0x45, 0x4d, 0xa9, 0xaf, 0xc3, 0xe5, 0x2c, 0x54, 0x2a, 0x4a, 0xd6, 0x9b, + 0xb3, 0x68, 0xd6, 0xd6, 0xf6, 0x5a, 0x48, 0x9a, 0xb5, 0x4c, 0x1b, 0x6d, 0xb6, 0xff, 0xc1, 0x51, + 0xb2, 0x61, 0x75, 0x3e, 0x9e, 0xda, 0x73, 0x7c, 0x70, 0x45, 0x3d, 0xb3, 0xea, 0x75, 0xa6, 0xf7, + 0xf8, 0x2a, 0xdd, 0xcf, 0xaf, 0xc7, 0xe7, 0x4c, 0x57, 0x4c, 0xae, 0x3e, 0x15, 0x08, 0x45, 0x8d, + 0xae, 0x35, 0x95, 0x55, 0x8c, 0x61, 0x5d, 0xfb, 0x65, 0xfa, 0x7e, 0x37, 0x51, 0xe1, 0x1c, 0x75, + 0x3b, 0x49, 0x92, 0x59, 0xf5, 0x3d, 0x4d, 0x87, 0x14, 0xbd, 0x3c, 0xbd, 0xb3, 0x7f, 0xc1, 0x59, + 0xde, 0xad, 0x08, 0xfe, 0x67, 0xc6, 0x97, 0x11, 0x73, 0xf1, 0x85, 0xe3, 0xaa, 0x9f, 0x74, 0xeb, + 0x77, 0x12, 0xe7, 0x52, 0xf8, 0xc2, 0x97, 0xf9, 0x77, 0xe5, 0xe9, 0xe6, 0xd6, 0xff, 0x08, 0x5d, + 0xd5, 0x54, 0x5f, 0xba, 0x62, 0x1f, 0xe3, 0x2d, 0xb7, 0x93, 0x97, 0xbc, 0x97, 0x09, 0x8f, 0xc7, + 0x63, 0xf2, 0x2a, 0x92, 0xf0, 0x5d, 0x3e, 0x6a, 0xad, 0x29, 0xef, 0x8f, 0x9b, 0xa6, 0x7f, 0x79, + 0x6a, 0x6f, 0x44, 0x7f, 0xf8, 0x2d, 0xb4, 0x5d, 0x26, 0xc7, 0xaa, 0xd8, 0xf8, 0x2b, 0xa6, 0xc9, + 0x4b, 0x89, 0x74, 0xa7, 0xcc, 0x8a, 0x1e, 0x36, 0xd5, 0x2e, 0x7d, 0x78, 0x9c, 0xf9, 0xc4, 0x9a, + 0x42, 0x5e, 0x54, 0xab, 0xab, 0xba, 0xba, 0xf8, 0x52, 0x4c, 0x96, 0xec, 0x8c, 0x63, 0x76, 0x76, + 0x8f, 0xd5, 0xae, 0x7f, 0x0b, 0x2a, 0x37, 0xc6, 0x19, 0xba, 0xb2, 0xb5, 0x49, 0x4e, 0x7b, 0xa4, + 0x49, 0x24, 0x96, 0xdf, 0x82, 0xca, 0x49, 0x26, 0x35, 0xf1, 0x95, 0xe5, 0x18, 0xd6, 0x54, 0xe2, + 0x67, 0x17, 0xc2, 0x96, 0xd2, 0x6d, 0x59, 0x73, 0x05, 0x0c, 0x9b, 0x4a, 0xa4, 0x43, 0x8e, 0x90, + 0xdf, 0x9d, 0x7c, 0x27, 0xd2, 0x26, 0x5e, 0x34, 0x41, 0x84, 0x0d, 0x0e, 0xae, 0x06, 0x93, 0x6b, + 0x8f, 0xa6, 0x6a, 0x32, 0xb1, 0xa8, 0x95, 0x7c, 0xf4, 0xff, 0x0e, 0x9e, 0x9d, 0x26, 0xcf, 0x57, + 0x58, 0xab, 0x36, 0xcf, 0x10, 0xd3, 0x85, 0x19, 0xc6, 0x7b, 0xff, 0x0a, 0x1a, 0xcb, 0x91, 0xb7, + 0x2e, 0x8e, 0xcb, 0xb8, 0xad, 0xa4, 0x50, 0x72, 0x6b, 0x3e, 0x37, 0x08, 0x1d, 0x3c, 0xa8, 0x36, + 0x3a, 0x95, 0x86, 0x35, 0xde, 0xa1, 0x3d, 0x0a, 0xbd, 0x63, 0x48, 0xe3, 0xba, 0x5b, 0x9e, 0x90, + 0xa8, 0x49, 0x59, 0x79, 0x2b, 0x2d, 0x23, 0xff, 0xf1, 0xa5, 0x19, 0xce, 0x12, 0x47, 0x51, 0xa1, + 0xd4, 0x44, 0x1a, 0x88, 0xc5, 0xc3, 0x2b, 0x3a, 0x05, 0xcd, 0xb0, 0xd9, 0x91, 0xec, 0x4e, 0x18, + 0x75, 0x33, 0xdb, 0x7f, 0xf0, 0xa5, 0x90, 0xca, 0x10, 0xe5, 0x6b, 0x55, 0x7d, 0x2d, 0x7d, 0x4c, + 0x65, 0x8d, 0x5f, 0x75, 0xb0, 0xe0, 0x90, 0x3b, 0x68, 0xa9, 0xbb, 0xe3, 0x69, 0xda, 0x05, 0x65, + 0xa4, 0xc0, 0xcf, 0xfc, 0x86, 0xe5, 0x9a, 0xa8, 0x34, 0x45, 0x0c, 0x3f, 0xde, 0x4c, 0xb1, 0xa7, + 0x77, 0xd5, 0x6c, 0xdd, 0xdb, 0x1b, 0x49, 0x37, 0x7a, 0xde, 0x33, 0x23, 0xd0, 0x94, 0x6f, 0x74, + 0x1a, 0x27, 0xc1, 0xcb, 0xb6, 0x7f, 0x59, 0x20, 0xc7, 0x2e, 0x31, 0x77, 0xf1, 0xb1, 0xdd, 0x03, + 0xb6, 0x81, 0x75, 0x6b, 0x53, 0x15, 0x36, 0xc4, 0xaf, 0xfb, 0xf9, 0xb3, 0x56, 0x90, 0xac, 0xed, + 0x65, 0xd5, 0xe7, 0x8a, 0xcf, 0x58, 0x1f, 0xf6, 0x7f, 0xc2, 0x99, 0xda, 0xc6, 0xf7, 0x91, 0xba, + 0xf4, 0x26, 0x6a, 0xca, 0xe9, 0x6f, 0x99, 0xa8, 0x78, 0xa5, 0xbe, 0x14, 0x28, 0xe2, 0x16, 0xd6, + 0x46, 0x30, 0xe3, 0x57, 0x94, 0xdc, 0xa1, 0xd7, 0x04, 0x91, 0xfb, 0xe4, 0xa0, 0xee, 0x30, 0x76, + 0xa5, 0x97, 0x3e, 0x14, 0xd1, 0xcc, 0xcd, 0xc8, 0x59, 0xc8, 0xcb, 0xd0, 0x02, 0x7a, 0xd2, 0x83, + 0xc2, 0x73, 0xbd, 0x88, 0x1a, 0xa4, 0x6d, 0xf0, 0xa6, 0x34, 0x24, 0x5d, 0x68, 0x9e, 0xb8, 0x45, + 0xad, 0x48, 0x98, 0x8c, 0xac, 0xd0, 0xda, 0x8a, 0x38, 0x8f, 0x89, 0xd5, 0x1b, 0xe3, 0x68, 0x67, + 0x92, 0x0e, 0x11, 0xd4, 0x11, 0x14, 0xe5, 0xa3, 0x64, 0x58, 0xc6, 0x3b, 0x71, 0xfb, 0xc8, 0x57, + 0xa2, 0x34, 0x3f, 0xc6, 0xd4, 0xdd, 0x5d, 0x71, 0xf1, 0xe3, 0x8c, 0xe6, 0xf8, 0x58, 0xd5, 0x43, + 0x07, 0x14, 0x4a, 0x8e, 0x6c, 0x79, 0xd9, 0x32, 0x4d, 0xdb, 0x9f, 0xf8, 0x52, 0x93, 0xb1, 0xba, + 0x5d, 0x27, 0xea, 0x54, 0x46, 0x60, 0x78, 0xf2, 0xf8, 0xb2, 0x15, 0x00, 0xd7, 0xc6, 0xc6, 0xf1, + 0xd9, 0x75, 0x8c, 0x7e, 0xb6, 0x2f, 0x03, 0x40, 0x90, 0xba, 0x4c, 0x7a, 0xf1, 0x0d, 0x49, 0x12, + 0x45, 0x63, 0x54, 0x0a, 0x4a, 0xa8, 0xe7, 0xaf, 0xf8, 0x53, 0x18, 0x7d, 0xd6, 0x07, 0xda, 0xda, + 0x4a, 0xc6, 0x33, 0x17, 0xa4, 0x91, 0x50, 0x0c, 0xd1, 0xed, 0xc3, 0x7d, 0x8c, 0xbe, 0x36, 0x48, + 0x5a, 0x1d, 0x48, 0xee, 0xca, 0xc3, 0xb8, 0x1f, 0xb2, 0xd0, 0x86, 0xcf, 0xa9, 0x58, 0xa6, 0x9b, + 0x6d, 0xff, 0x8d, 0xa1, 0x22, 0x6d, 0x8c, 0x32, 0xef, 0x0d, 0x51, 0x49, 0x7e, 0x63, 0xd7, 0xb6, + 0xe1, 0x1e, 0x74, 0xdd, 0x1b, 0x72, 0x2a, 0xa6, 0x2d, 0xff, 0xe1, 0xfa, 0xab, 0x92, 0xfd, 0xa9, + 0xea, 0x55, 0xa0, 0xad, 0x12, 0x9b, 0xb7, 0x89, 0x26, 0xa6, 0x9b, 0x6d, 0xff, 0x8a, 0x2b, 0xb7, + 0x6e, 0xdc, 0xff, 0xc6, 0x5e, 0x2d, 0x53, 0x4e, 0xdb, 0xd6, 0xfc, 0xb9, 0xe6, 0xc5, 0x6b, 0xf0, + 0xa0, 0x8b, 0x76, 0xee, 0xd9, 0x36, 0xdd, 0xb2, 0x64, 0x5b, 0xd7, 0xc7, 0x1d, 0x97, 0x2c, 0x5d, + 0x3e, 0x49, 0x5c, 0x43, 0xf9, 0xf8, 0x53, 0x8d, 0xd2, 0x8f, 0x49, 0xd9, 0x92, 0x94, 0xf4, 0x88, + 0x6d, 0x5f, 0x4f, 0xbe, 0x36, 0xdd, 0x3d, 0xf7, 0x13, 0x2f, 0x64, 0xad, 0xbb, 0x61, 0x53, 0xe6, + 0xc6, 0xee, 0x9c, 0xaa, 0x4c, 0xbd, 0xdd, 0xdf, 0xc2, 0x96, 0xaa, 0x68, 0xd9, 0x8b, 0xd2, 0x66, + 0xb7, 0x62, 0xe9, 0x93, 0xc7, 0x3e, 0x14, 0x26, 0x35, 0x7a, 0x34, 0xcf, 0x2f, 0xc7, 0x68, 0x79, + 0x3c, 0x66, 0x8e, 0xcf, 0x8c, 0xb7, 0x4e, 0x7c, 0xd5, 0xd3, 0xdf, 0x1a, 0xaa, 0xaf, 0x1b, 0x23, + 0xfd, 0xb3, 0x31, 0x73, 0x09, 0xa5, 0x4a, 0x1d, 0xac, 0x83, 0x64, 0x32, 0x89, 0x9f, 0xa7, 0x9b, + 0xf8, 0xc3, 0xb3, 0x09, 0x8d, 0xc6, 0xe4, 0x43, 0xfa, 0xaa, 0x49, 0x2c, 0x43, 0x9f, 0x0a, 0x1a, + 0xd4, 0xd9, 0x53, 0x75, 0xb4, 0x86, 0x7d, 0x8a, 0xd0, 0xd5, 0x53, 0x14, 0xf2, 0xfc, 0x3f, 0x9e, + 0x66, 0x4d, 0x6e, 0xbd, 0x99, 0xec, 0x2c, 0xac, 0x58, 0x3d, 0x66, 0xe6, 0xf9, 0x79, 0xbf, 0x85, + 0x0d, 0x57, 0xb7, 0x6f, 0x52, 0x76, 0x32, 0xb2, 0x97, 0x48, 0xfc, 0x60, 0xdb, 0x49, 0xa6, 0xd0, + 0xbb, 0xc9, 0xb9, 0x71, 0x32, 0xf3, 0xf8, 0xeb, 0xf0, 0xa1, 0x53, 0x4e, 0x9a, 0x45, 0xed, 0xcb, + 0x74, 0xaf, 0x77, 0x3d, 0xf0, 0x91, 0x1b, 0x6f, 0x73, 0xe1, 0x23, 0xf8, 0xd1, 0x95, 0x87, 0x2b, + 0x5f, 0x3e, 0xab, 0xb2, 0x91, 0xfb, 0x72, 0x6e, 0x94, 0x5c, 0xa2, 0x6f, 0xdb, 0xff, 0x13, 0x8e, + 0xe5, 0x1e, 0xab, 0xe3, 0x02, 0x29, 0x17, 0x12, 0x9b, 0x6c, 0xdf, 0xe5, 0xca, 0x74, 0xfc, 0x15, + 0xee, 0x92, 0x57, 0x36, 0x5b, 0xbf, 0x2f, 0x85, 0x2d, 0xa9, 0xb2, 0x2a, 0xd3, 0xb6, 0x95, 0xe9, + 0x0e, 0x2b, 0x7c, 0x1f, 0x08, 0x12, 0xae, 0xd5, 0xa2, 0xe9, 0xff, 0x7b, 0xf8, 0x42, 0xe9, 0x6d, + 0x35, 0x76, 0x96, 0xd7, 0x8e, 0xd5, 0xf5, 0xb6, 0x3e, 0xaf, 0xd6, 0x9a, 0xfc, 0x29, 0xa4, 0xed, + 0x5b, 0x76, 0xdc, 0xdd, 0xfc, 0x7d, 0x5f, 0x8b, 0xe1, 0x1e, 0xd0, 0x55, 0xaa, 0x72, 0xf3, 0x63, + 0x7c, 0xad, 0xef, 0x19, 0x19, 0x7c, 0xb4, 0x82, 0xad, 0xc0, 0xbd, 0x4e, 0x69, 0x01, 0xb4, 0x85, + 0xb4, 0x7f, 0x5d, 0xe7, 0xe6, 0xfa, 0x5c, 0xf4, 0xf0, 0xa7, 0x89, 0x3d, 0x6a, 0x9a, 0x75, 0x25, + 0x57, 0xc0, 0xe1, 0xe1, 0x4c, 0x74, 0x9d, 0xd8, 0xf5, 0x49, 0x12, 0x06, 0x6b, 0xb4, 0xdb, 0x34, + 0xab, 0xc2, 0x96, 0xa2, 0xb9, 0xa3, 0xb1, 0xda, 0xa4, 0x34, 0xc8, 0x6f, 0x25, 0x2b, 0xbf, 0x18, + 0x78, 0x2a, 0x10, 0x93, 0x24, 0x3b, 0xa3, 0xb0, 0x3b, 0x6a, 0xfc, 0x8f, 0x49, 0x26, 0x9b, 0xef, + 0x85, 0x04, 0x8d, 0xdd, 0xe1, 0xc7, 0xea, 0xda, 0x41, 0x21, 0x26, 0x43, 0x3a, 0xa3, 0x83, 0xca, + 0x41, 0x1a, 0x68, 0x92, 0x27, 0xc6, 0x8c, 0x84, 0xc1, 0x4b, 0xc8, 0x6d, 0x34, 0x06, 0x1d, 0xe9, + 0xdd, 0x54, 0xda, 0xd1, 0x0c, 0xf1, 0x69, 0x8c, 0xf7, 0xff, 0x1a, 0x57, 0x76, 0xfa, 0x77, 0x3f, + 0xad, 0x4c, 0x43, 0xa8, 0x9f, 0x1c, 0xd6, 0xf4, 0x0e, 0xd7, 0x06, 0x98, 0x86, 0xbf, 0xa6, 0x6f, + 0xf8, 0xdd, 0xf9, 0x1e, 0xfb, 0x4c, 0xac, 0xca, 0x94, 0x26, 0x14, 0x0d, 0x63, 0x73, 0xf5, 0x4c, + 0x87, 0x52, 0x91, 0x5e, 0x58, 0x9e, 0x6d, 0x67, 0xfe, 0x36, 0x6b, 0xbf, 0xe6, 0x29, 0x17, 0x20, + 0x71, 0xd5, 0x49, 0x4e, 0x62, 0x5a, 0xc5, 0x26, 0x2e, 0x30, 0x81, 0x0a, 0x9e, 0x31, 0xea, 0xef, + 0x76, 0xd9, 0x7c, 0x5b, 0x1b, 0x3d, 0x2a, 0x8f, 0xc3, 0xa4, 0x5c, 0xbe, 0x98, 0xf9, 0xf2, 0xf3, + 0x7c, 0x1c, 0x16, 0xd3, 0x25, 0x86, 0xdb, 0x53, 0xf8, 0xee, 0x31, 0xf8, 0x74, 0xb4, 0xca, 0xa0, + 0x36, 0xae, 0xb8, 0xf2, 0x93, 0x76, 0x34, 0x6f, 0x5a, 0xa6, 0x39, 0x88, 0x6d, 0xb3, 0xf9, 0x28, + 0x9f, 0xe3, 0x2d, 0xab, 0x6a, 0xbb, 0xcf, 0x38, 0xc6, 0x4d, 0xdd, 0x37, 0xc1, 0xc1, 0xac, 0x9c, + 0x67, 0xbf, 0x8d, 0xd8, 0x75, 0xad, 0x9d, 0x6d, 0x65, 0x8f, 0xa3, 0xc6, 0x93, 0x1a, 0x19, 0xd9, + 0x7e, 0x36, 0x7d, 0x06, 0x46, 0x45, 0x42, 0x89, 0x7d, 0xc4, 0x4e, 0x63, 0xfc, 0x14, 0xc3, 0x2a, + 0xd2, 0x4e, 0xf3, 0xb7, 0x8d, 0xcc, 0x0f, 0x51, 0xf0, 0x52, 0x7e, 0xb1, 0x0e, 0xb5, 0x89, 0x10, + 0x62, 0xe0, 0xff, 0x0a, 0x1e, 0x86, 0xa4, 0xef, 0x83, 0x6a, 0x26, 0xc5, 0xe8, 0x5b, 0x81, 0x37, + 0x27, 0x73, 0x50, 0x35, 0x7f, 0x9d, 0xa7, 0x55, 0x07, 0xc2, 0x9a, 0x8a, 0x89, 0x52, 0x65, 0xa8, + 0x20, 0x87, 0x4f, 0x15, 0xb6, 0x0f, 0x4d, 0xcb, 0xad, 0x38, 0x33, 0x68, 0x6e, 0x5b, 0x2a, 0x08, + 0xbe, 0x37, 0x65, 0x0c, 0x15, 0x27, 0x2b, 0xcd, 0xaa, 0xb2, 0x6a, 0x96, 0xea, 0x1e, 0xc3, 0xd3, + 0x41, 0x4d, 0x56, 0x53, 0x1e, 0x90, 0xd3, 0x3f, 0x68, 0x8d, 0x9c, 0x70, 0xa7, 0x24, 0x07, 0xb1, + 0xfe, 0x14, 0xc6, 0x40, 0xc0, 0x79, 0xd8, 0x43, 0x0c, 0x3b, 0xda, 0x30, 0xeb, 0x83, 0x59, 0xd0, + 0x37, 0x47, 0x43, 0x1b, 0xc2, 0x25, 0x06, 0x49, 0x5f, 0x8d, 0xaa, 0x12, 0xf8, 0x28, 0x46, 0xd3, + 0x75, 0xc7, 0x74, 0xa3, 0x82, 0x6e, 0x69, 0xd6, 0xc6, 0x75, 0x17, 0x2a, 0x69, 0xb6, 0xdf, 0xf8, + 0x27, 0x22, 0x1b, 0x56, 0x99, 0x31, 0x0d, 0x24, 0xf0, 0x8f, 0x8d, 0xf8, 0x6f, 0xb8, 0x57, 0x9d, + 0x0d, 0xac, 0xde, 0xe4, 0x18, 0x69, 0x5b, 0x52, 0x92, 0xc9, 0x14, 0x4c, 0xa2, 0xd5, 0x11, 0xa3, + 0xfe, 0x37, 0x74, 0x34, 0x4c, 0x58, 0xa4, 0x4a, 0xc8, 0xba, 0xac, 0xe1, 0x03, 0xfa, 0xf5, 0x67, + 0xd8, 0xf0, 0xab, 0x12, 0xc4, 0x9a, 0xff, 0xc6, 0xc9, 0x28, 0x59, 0xe0, 0x9a, 0x4c, 0x9b, 0xd6, + 0x1b, 0x6c, 0xfb, 0x43, 0xd0, 0xda, 0x93, 0xce, 0x87, 0x11, 0x19, 0xd7, 0xd1, 0xff, 0x82, 0xcb, + 0xd5, 0x2a, 0x87, 0x1d, 0x4d, 0xa3, 0x56, 0x6d, 0x68, 0x8f, 0x48, 0x7a, 0xe3, 0xfc, 0x15, 0xc2, + 0x06, 0xff, 0x98, 0x2b, 0xde, 0x14, 0x66, 0x40, 0xb9, 0x35, 0x49, 0xc6, 0x8e, 0x24, 0x95, 0x4a, + 0x2f, 0xb3, 0xbb, 0xfe, 0x32, 0xc6, 0x46, 0x58, 0xd8, 0xcb, 0x71, 0x64, 0xd4, 0xe3, 0xdb, 0x1d, + 0xd9, 0x3b, 0x05, 0xa3, 0xf0, 0xee, 0xc6, 0xe7, 0x62, 0xa5, 0x60, 0x7c, 0xc3, 0x19, 0xa3, 0x8e, + 0xa8, 0x91, 0x12, 0x2c, 0x8f, 0xf8, 0x2d, 0x15, 0x3e, 0x1b, 0x37, 0x97, 0xf6, 0xf8, 0xc1, 0x2b, + 0xf2, 0x3b, 0xdb, 0xdd, 0x89, 0x73, 0x63, 0x59, 0xba, 0x49, 0x44, 0x9b, 0xf8, 0xde, 0xa5, 0xfb, + 0x6e, 0x4e, 0xdf, 0x74, 0xa2, 0xdc, 0x7a, 0xa6, 0xbf, 0x1a, 0x65, 0xea, 0x7b, 0x9f, 0x76, 0x25, + 0xa4, 0x5d, 0xd7, 0xae, 0x5b, 0xca, 0xb6, 0xcd, 0xff, 0xc1, 0x60, 0x92, 0xe3, 0x0e, 0x27, 0x99, + 0x87, 0x33, 0xe2, 0x69, 0xa4, 0xd1, 0xeb, 0xe1, 0x43, 0x25, 0xb4, 0x66, 0x63, 0x79, 0x35, 0xbb, + 0x5a, 0x57, 0xf3, 0x59, 0x18, 0xbf, 0xe1, 0x4e, 0x79, 0x5a, 0x6c, 0x52, 0x56, 0x44, 0xcc, 0x79, + 0x73, 0x4a, 0xd4, 0x9b, 0xe3, 0x75, 0xa7, 0xdf, 0xea, 0xb3, 0xf6, 0xab, 0x9b, 0x41, 0xb2, 0xa4, + 0xa2, 0xd8, 0xb7, 0xff, 0x85, 0x09, 0x49, 0x36, 0xaa, 0xb5, 0x66, 0x7b, 0xee, 0xcd, 0xdb, 0xe0, + 0xa7, 0x7a, 0x72, 0x6e, 0xa5, 0xc5, 0x8f, 0x67, 0xc1, 0x4d, 0x52, 0xa5, 0xb6, 0x5d, 0x88, 0xbf, + 0x9f, 0xc1, 0xf0, 0xf4, 0x6b, 0x27, 0x33, 0x6b, 0x6e, 0xa6, 0x5f, 0xd2, 0x77, 0xea, 0xda, 0xb7, + 0xff, 0x1c, 0x3f, 0x69, 0xb6, 0xc9, 0xb7, 0x36, 0xcf, 0xde, 0xf8, 0x90, 0x4d, 0x9b, 0xaf, 0x7a, + 0x70, 0x7c, 0x68, 0xe9, 0xfc, 0xed, 0x3c, 0x2f, 0x65, 0x91, 0x58, 0xac, 0x43, 0x8f, 0x8b, 0xb3, + 0x76, 0x26, 0x62, 0x40, 0x4c, 0xbf, 0x6c, 0xdd, 0x3f, 0xc2, 0x87, 0x2e, 0xfa, 0x45, 0x26, 0xa1, + 0xb3, 0x9d, 0x32, 0xfb, 0x69, 0x25, 0x97, 0xc4, 0xd3, 0x98, 0xa1, 0xdf, 0x3b, 0x6a, 0xdb, 0x7e, + 0x09, 0x84, 0xa7, 0x65, 0xf2, 0x5c, 0xbb, 0x51, 0xfe, 0x26, 0x7c, 0x7e, 0x6d, 0xdc, 0x9f, 0xc1, + 0x1c, 0x98, 0x98, 0xda, 0xec, 0x7c, 0x25, 0xdd, 0xcd, 0x86, 0xc4, 0xa2, 0xf0, 0x9c, 0x71, 0x6a, + 0x50, 0xb1, 0x2d, 0xdf, 0xc1, 0x5c, 0xbd, 0xd3, 0xc3, 0xe8, 0xf5, 0xd4, 0x7c, 0x15, 0xd5, 0xaf, + 0x82, 0xe2, 0x37, 0x7a, 0x5a, 0xfb, 0xe0, 0xaa, 0xfd, 0x34, 0xf6, 0x9a, 0xce, 0xc8, 0xba, 0x7f, + 0x85, 0x35, 0x9f, 0x65, 0xde, 0x5c, 0xad, 0x52, 0x44, 0xcf, 0x89, 0xb7, 0xd6, 0xcd, 0xb6, 0xac, + 0x6b, 0xe0, 0x9e, 0xa9, 0x32, 0x74, 0xcf, 0xaf, 0x2d, 0xf0, 0xa1, 0x89, 0x9b, 0xf5, 0xb3, 0xe4, + 0xd5, 0x7e, 0xd7, 0x67, 0xc6, 0x58, 0x8a, 0xfd, 0xcf, 0x87, 0xcc, 0x9e, 0x9a, 0xe5, 0x13, 0xba, + 0x2a, 0xa7, 0x97, 0xff, 0x85, 0x06, 0xb3, 0x66, 0xda, 0xdb, 0x72, 0xf4, 0x93, 0x2d, 0xf7, 0x68, + 0xf8, 0xe3, 0xc6, 0x10, 0x76, 0xba, 0x9b, 0xbb, 0x69, 0xb9, 0x75, 0x98, 0x22, 0xce, 0x6d, 0x98, + 0xb4, 0xbc, 0x14, 0x91, 0xf0, 0xab, 0xb4, 0x31, 0x7a, 0x72, 0x2f, 0x97, 0x1f, 0xe7, 0xc6, 0x95, + 0x7a, 0x1d, 0x6f, 0x92, 0x67, 0x65, 0x3c, 0xaf, 0x61, 0xc5, 0x1b, 0x37, 0x19, 0x92, 0x49, 0xb8, + 0xd8, 0x79, 0x16, 0xde, 0xb2, 0x17, 0xfe, 0x36, 0xd5, 0xde, 0x80, 0xca, 0x34, 0xd0, 0xd3, 0xc6, + 0x94, 0x7a, 0x4e, 0x92, 0x47, 0xb8, 0xf8, 0xd0, 0xff, 0xc3, 0x06, 0x3e, 0x88, 0xb2, 0xf7, 0xe8, + 0x93, 0x68, 0xec, 0x47, 0xa1, 0xbd, 0x63, 0x3d, 0xed, 0xff, 0x18, 0x5d, 0x47, 0xaa, 0xad, 0x1a, + 0x64, 0x6a, 0x4e, 0xb5, 0xe8, 0x1b, 0x05, 0x95, 0xc7, 0x18, 0x8e, 0xf8, 0x52, 0x3c, 0xa7, 0x76, + 0x8d, 0x8c, 0xd6, 0xda, 0x55, 0x37, 0x1a, 0xd2, 0xf8, 0x52, 0x3a, 0x72, 0xef, 0x8d, 0xb1, 0xf4, + 0x68, 0xdc, 0x99, 0xde, 0xc6, 0x08, 0xcc, 0x1b, 0xd0, 0x93, 0x15, 0x68, 0xde, 0xc9, 0x56, 0xdc, + 0xd6, 0x48, 0x85, 0x76, 0x7f, 0xf0, 0x59, 0x25, 0x0e, 0xcb, 0x1e, 0xda, 0x11, 0x54, 0xda, 0xd8, + 0xe6, 0x4f, 0x85, 0x0a, 0xb0, 0xc2, 0x2a, 0xc8, 0xdc, 0xcb, 0x12, 0x35, 0x36, 0x31, 0x06, 0xc9, + 0xb1, 0x08, 0xba, 0x5f, 0x18, 0xce, 0x63, 0x15, 0xe9, 0x17, 0x82, 0x09, 0x58, 0x6a, 0x01, 0x9c, + 0x50, 0xe8, 0x99, 0x24, 0x32, 0x90, 0xd4, 0xad, 0x96, 0x45, 0x8e, 0x0a, 0x24, 0x51, 0x65, 0xfe, + 0x14, 0x25, 0x1c, 0xb9, 0x3d, 0xc5, 0x06, 0x58, 0x3f, 0xc6, 0xac, 0xfe, 0x86, 0x44, 0xb1, 0x67, + 0xd9, 0x7c, 0x29, 0xad, 0xe0, 0xa9, 0x4a, 0x8d, 0xa9, 0x92, 0xe0, 0xf7, 0x34, 0x6a, 0xa6, 0xa8, + 0x6f, 0x8c, 0xc9, 0xba, 0x51, 0x17, 0x12, 0xa3, 0x3c, 0x3f, 0x63, 0x5f, 0x85, 0x2a, 0xa4, 0xf0, + 0x54, 0x6a, 0xf6, 0xc2, 0x3a, 0xb6, 0xf6, 0x8c, 0x5f, 0x1b, 0xb6, 0xb2, 0xc7, 0x44, 0xa1, 0x3e, + 0xfe, 0x77, 0xb1, 0xee, 0xc6, 0x9d, 0x26, 0xce, 0xbf, 0xf8, 0x7f, 0x2a, 0x52, 0x6e, 0xba, 0x26, + 0x99, 0x51, 0x2a, 0x94, 0x9d, 0xf0, 0x5f, 0xf1, 0xb9, 0x96, 0x3e, 0x3d, 0x02, 0x0e, 0x25, 0xd7, + 0xa0, 0x70, 0x7b, 0x27, 0xad, 0xa6, 0xd5, 0xc8, 0xe1, 0x85, 0x48, 0xad, 0x87, 0xfe, 0x36, 0x3d, + 0x9b, 0x51, 0x28, 0x4d, 0x7b, 0x0c, 0x42, 0xc5, 0x19, 0x54, 0xa9, 0x4c, 0x2b, 0x10, 0xc6, 0x38, + 0x8c, 0xea, 0xa1, 0xa9, 0x38, 0xa6, 0xe8, 0x47, 0x75, 0x2f, 0xff, 0xc2, 0x85, 0x85, 0x7f, 0x7d, + 0xdd, 0xfd, 0xf9, 0xa6, 0xfc, 0x7e, 0x3f, 0x1f, 0x9a, 0xf8, 0xfe, 0xaa, 0x5f, 0x39, 0xea, 0x98, + 0x42, 0xe9, 0xf0, 0x7d, 0x6b, 0x7e, 0x34, 0x80, 0xff, 0xa7, 0x68, 0xa8, 0x86, 0x28, 0x56, 0x54, + 0x51, 0xe1, 0x81, 0x8a, 0x95, 0x1f, 0x06, 0x3d, 0x19, 0x05, 0x07, 0x15, 0xa2, 0x1c, 0x49, 0x64, + 0x7f, 0xc6, 0xeb, 0x06, 0x32, 0x66, 0xb1, 0x8d, 0xa6, 0x33, 0x01, 0x0b, 0xff, 0xb5, 0x95, 0x23, + 0xab, 0xfb, 0x69, 0x97, 0x9a, 0x7f, 0x73, 0x27, 0x39, 0x43, 0x91, 0xb7, 0xd6, 0xcb, 0xb4, 0x2f, + 0xb1, 0xf0, 0x64, 0x9c, 0x20, 0x57, 0x7f, 0xc2, 0x84, 0xf2, 0xee, 0x94, 0x43, 0xde, 0x34, 0xbd, + 0x33, 0x3c, 0x97, 0xb6, 0x0c, 0xd6, 0xf8, 0xa3, 0x28, 0x95, 0x78, 0xdd, 0x69, 0x89, 0x75, 0x6a, + 0xa6, 0xd5, 0xbb, 0xf7, 0x56, 0xd9, 0x02, 0x4d, 0xce, 0x6e, 0x10, 0xbd, 0x95, 0x5c, 0xf1, 0x7c, + 0x3f, 0xc2, 0x85, 0x68, 0x71, 0x7b, 0xbe, 0xe2, 0xe6, 0xeb, 0x85, 0xab, 0xc7, 0x01, 0xd2, 0x7c, + 0x15, 0x17, 0x15, 0xbb, 0x69, 0x26, 0x93, 0xdd, 0xd3, 0x8f, 0x8d, 0x30, 0xff, 0x76, 0x62, 0x53, + 0xea, 0x75, 0x9e, 0x33, 0x51, 0x64, 0xd7, 0x1e, 0xc6, 0x33, 0xe9, 0xa6, 0xef, 0xe1, 0x49, 0x6a, + 0x1e, 0xcd, 0x26, 0xee, 0xa3, 0x4b, 0xd3, 0xac, 0xdd, 0x98, 0xac, 0xcc, 0x5b, 0x2a, 0xf0, 0xa1, + 0x62, 0x07, 0x6c, 0x5e, 0x0e, 0xdc, 0xbe, 0xb0, 0x3e, 0xd4, 0x7f, 0x9b, 0x4a, 0x15, 0x9a, 0xed, + 0x7c, 0x8e, 0x81, 0x6f, 0x11, 0x05, 0x32, 0xab, 0xf2, 0x75, 0x6e, 0xbf, 0xc5, 0xa2, 0x6b, 0xb9, + 0xb4, 0x95, 0x4c, 0x3f, 0x91, 0x67, 0xc2, 0x94, 0x96, 0x91, 0x74, 0x55, 0xe2, 0x17, 0x26, 0xbf, + 0x9e, 0x0f, 0xe9, 0x15, 0xb9, 0x4a, 0xeb, 0x32, 0x0b, 0xe1, 0x43, 0x24, 0xe9, 0x12, 0x27, 0xcb, + 0x79, 0xb4, 0x47, 0x1b, 0x85, 0xca, 0xf2, 0xf4, 0x43, 0xb6, 0x3f, 0xc2, 0x82, 0xd3, 0xb6, 0x7d, + 0xb6, 0xdb, 0x6d, 0x9d, 0x74, 0xc6, 0x95, 0x52, 0xc5, 0x14, 0x5f, 0x05, 0x67, 0x4d, 0x34, 0xd3, + 0x95, 0x2e, 0x37, 0x2f, 0x36, 0x6e, 0xf8, 0xf3, 0x3b, 0xe7, 0xd3, 0xe3, 0x7b, 0x6a, 0xd9, 0xbf, + 0x89, 0x89, 0x73, 0x97, 0xab, 0xf9, 0x67, 0xf8, 0x29, 0x9f, 0x93, 0x74, 0x4a, 0x22, 0x42, 0xd0, + 0x53, 0x62, 0x28, 0xae, 0xb3, 0xa1, 0x95, 0xe1, 0x0c, 0xad, 0x51, 0xb5, 0x96, 0x61, 0x46, 0x5d, + 0x6e, 0xd2, 0x6e, 0xd7, 0x85, 0x2d, 0x89, 0xf9, 0x71, 0x45, 0xb8, 0x89, 0xee, 0xe2, 0x5e, 0x6e, + 0x5f, 0x06, 0xbd, 0xf0, 0xa6, 0xdd, 0xb6, 0x8d, 0xb4, 0xee, 0x90, 0x9e, 0x6e, 0x6e, 0x46, 0xf8, + 0x2a, 0x2d, 0x72, 0xb2, 0x62, 0x9f, 0x2c, 0xf9, 0x55, 0x77, 0xf8, 0x2c, 0xab, 0x45, 0xe4, 0x8a, + 0xb8, 0xea, 0x88, 0x7d, 0x4f, 0xcb, 0xa9, 0xc8, 0x9f, 0x18, 0x21, 0xa3, 0xed, 0x4f, 0xe0, 0xed, + 0x85, 0xd1, 0xfe, 0xb3, 0x1e, 0x3d, 0x2b, 0xc4, 0xf5, 0x8d, 0x76, 0x5e, 0x32, 0xe6, 0xcb, 0xf5, + 0x4d, 0x5f, 0xa5, 0xd6, 0xe5, 0x7d, 0xb2, 0xe7, 0x84, 0x0f, 0x7b, 0xa4, 0x5c, 0x6e, 0x7a, 0xaf, + 0x85, 0x36, 0x92, 0x1a, 0x54, 0xce, 0xa4, 0x7f, 0xd6, 0xa6, 0x25, 0xbb, 0xd8, 0xdf, 0xa6, 0x5a, + 0xc9, 0x51, 0x97, 0x85, 0x08, 0x07, 0xff, 0x95, 0xf6, 0xfe, 0xb9, 0x57, 0x50, 0xa3, 0x73, 0x9d, + 0x4e, 0xe1, 0xb4, 0xda, 0xb9, 0x8c, 0x4c, 0x91, 0x91, 0x97, 0x8c, 0xf2, 0x37, 0x0c, 0x65, 0xbb, + 0x1a, 0xea, 0x6a, 0x6e, 0xb6, 0xd5, 0x7f, 0x0a, 0x1c, 0x7d, 0x9b, 0x97, 0x26, 0xd8, 0x58, 0xab, + 0x52, 0x5c, 0x24, 0x55, 0xb8, 0xdf, 0xed, 0x9c, 0x4c, 0x29, 0x3b, 0x0e, 0xf6, 0xbf, 0x0a, 0xc3, + 0xb1, 0x5d, 0x55, 0x5e, 0xc6, 0x95, 0xa5, 0x19, 0x5a, 0x57, 0xe3, 0x4d, 0x71, 0x34, 0x21, 0x60, + 0x98, 0xa9, 0x33, 0x11, 0x32, 0x64, 0x94, 0x1a, 0x37, 0x24, 0x44, 0x69, 0xad, 0x7f, 0xd6, 0xb0, + 0xe1, 0xa8, 0xd1, 0x8f, 0xd4, 0xbd, 0x69, 0x78, 0xd1, 0x0b, 0x2a, 0x8b, 0xc3, 0xb4, 0xc5, 0x6f, + 0x7f, 0x4f, 0xb7, 0x6c, 0x6e, 0x8a, 0x5f, 0xa3, 0x6d, 0x34, 0xfc, 0x29, 0x6f, 0x1f, 0xc5, 0xa2, + 0x7a, 0xab, 0x39, 0xeb, 0x56, 0xfe, 0x5c, 0x89, 0x5e, 0x8b, 0x7a, 0x28, 0x8c, 0xbf, 0x85, 0x04, + 0x85, 0x45, 0x55, 0x2a, 0xd5, 0x7f, 0x8c, 0x4e, 0x53, 0xe2, 0x5c, 0x2f, 0x73, 0x71, 0x59, 0x21, + 0x53, 0x8f, 0x0a, 0x72, 0xe9, 0xe0, 0x51, 0xd6, 0xb1, 0x2d, 0xad, 0xc8, 0x4f, 0x4b, 0x61, 0xfc, + 0xaa, 0x95, 0x5a, 0x87, 0xed, 0x4c, 0xcb, 0xf1, 0xb0, 0xbc, 0xcd, 0xc9, 0x61, 0xa2, 0x78, 0xd0, + 0xea, 0xc3, 0x9d, 0xec, 0x84, 0x77, 0x87, 0x7b, 0x32, 0x9f, 0x08, 0x51, 0xec, 0xae, 0x70, 0x75, + 0x20, 0xd5, 0x75, 0xca, 0xc9, 0x40, 0x6b, 0x72, 0x70, 0xfc, 0x3f, 0x64, 0x49, 0xb5, 0x31, 0x96, + 0xb6, 0xd9, 0xd8, 0xd7, 0x0c, 0xab, 0x45, 0xa3, 0x6b, 0x18, 0x39, 0xcb, 0x00, 0x55, 0x5e, 0xa7, + 0xff, 0x1a, 0x43, 0xb0, 0xdb, 0x95, 0x91, 0xec, 0x39, 0x02, 0x4a, 0x8a, 0x0e, 0xf0, 0xca, 0xa1, + 0x9b, 0x5e, 0x1c, 0xa2, 0x3d, 0xff, 0x5b, 0xc7, 0x37, 0x2d, 0xb2, 0x7f, 0xe3, 0x4a, 0x14, 0x75, + 0xfc, 0xb4, 0xe5, 0x66, 0x3b, 0xce, 0xa2, 0x99, 0x24, 0x0e, 0xf6, 0xb7, 0xbb, 0x09, 0x54, 0x9b, + 0x58, 0x6a, 0x50, 0xd2, 0xb2, 0xd1, 0xfb, 0x15, 0xda, 0x1d, 0x70, 0x2a, 0x72, 0xf8, 0xe3, 0xff, + 0x1a, 0x65, 0xaa, 0xb1, 0x70, 0xa6, 0x5a, 0xa9, 0xda, 0xe5, 0xe4, 0xdd, 0x8e, 0x35, 0x75, 0x34, + 0xa3, 0x5b, 0x45, 0x75, 0xe7, 0xad, 0xad, 0x0c, 0x7a, 0x3d, 0x73, 0xa1, 0x16, 0x6c, 0x65, 0x3f, + 0xf1, 0xb4, 0x7d, 0x62, 0x83, 0x9a, 0xad, 0xff, 0x38, 0xe8, 0xc7, 0x8d, 0xa1, 0x38, 0xc9, 0x62, + 0xcb, 0x82, 0x2c, 0x9c, 0xf5, 0xcb, 0xa7, 0x7b, 0xd2, 0x74, 0xf2, 0xd5, 0x88, 0x3f, 0xfe, 0x14, + 0x2c, 0xb1, 0xb1, 0x53, 0x62, 0x3c, 0x9e, 0xe5, 0xa2, 0xf1, 0xfc, 0xcf, 0xc9, 0x89, 0x92, 0x94, + 0xc1, 0x17, 0xdf, 0x95, 0xfb, 0xfc, 0x29, 0x63, 0x21, 0x93, 0xa9, 0x2c, 0x93, 0x94, 0xc4, 0x4c, + 0x48, 0xa8, 0xe6, 0xdf, 0x76, 0x46, 0xb8, 0xf1, 0xcc, 0xf1, 0x71, 0x03, 0xb3, 0x94, 0x55, 0xd4, + 0x00, 0xef, 0x8d, 0x94, 0xd5, 0xa4, 0x2a, 0x29, 0xa9, 0x56, 0xd3, 0x68, 0x8a, 0x68, 0x31, 0xac, + 0xf2, 0xd2, 0x9e, 0xdd, 0x77, 0x58, 0x2a, 0xdd, 0x40, 0xf9, 0xce, 0x51, 0x12, 0x2a, 0x69, 0x7d, + 0x6f, 0x0a, 0x93, 0x83, 0x15, 0x9b, 0xff, 0xe3, 0x79, 0xae, 0x20, 0xa7, 0xb9, 0x4f, 0x8f, 0x8d, + 0x5d, 0xc4, 0x6e, 0xb1, 0x69, 0x82, 0xde, 0x17, 0x7a, 0xd4, 0x62, 0x9a, 0x19, 0xed, 0x2d, 0x58, + 0x23, 0x77, 0x87, 0x66, 0x1d, 0x8d, 0xc0, 0x01, 0xb1, 0x0b, 0x03, 0x9c, 0xbf, 0x4f, 0xf1, 0xb5, + 0x47, 0x05, 0x74, 0x7a, 0x08, 0xd5, 0xa6, 0xc6, 0xe6, 0x9a, 0x73, 0x88, 0x45, 0x69, 0xf0, 0xaf, + 0x4e, 0xe5, 0x6f, 0x24, 0xca, 0x7a, 0xa1, 0x01, 0xe6, 0x46, 0x89, 0x3b, 0xa2, 0xcf, 0xfe, 0x36, + 0xc6, 0xdc, 0x21, 0xba, 0xc6, 0xcc, 0x40, 0xde, 0xd4, 0xfd, 0x37, 0x6b, 0x51, 0x27, 0xad, 0x3d, + 0x0b, 0x94, 0x46, 0xbe, 0x8a, 0x50, 0xf9, 0x90, 0xdd, 0xcf, 0x43, 0xff, 0x0a, 0x5a, 0x05, 0xdd, + 0x69, 0xea, 0x97, 0x1b, 0x83, 0xfe, 0xb7, 0xaa, 0x46, 0xad, 0x07, 0x6d, 0x24, 0xb8, 0xdc, 0xa5, + 0xba, 0x1f, 0x74, 0x6e, 0x40, 0xd4, 0x56, 0xf6, 0x46, 0x5e, 0x7c, 0x6d, 0xaa, 0x5d, 0xb2, 0x99, + 0xd7, 0x3d, 0xe5, 0xc9, 0xda, 0x3b, 0x70, 0xb4, 0xf5, 0xf1, 0x83, 0x1d, 0x00, 0x79, 0x4f, 0x94, + 0x53, 0x3a, 0x65, 0x01, 0x50, 0x8b, 0x23, 0xb8, 0x8f, 0x45, 0xfe, 0x36, 0x75, 0x0b, 0xa8, 0xb1, + 0x01, 0xf9, 0x1a, 0xdf, 0xe0, 0xd5, 0x7f, 0x8b, 0x0a, 0xd1, 0xe9, 0x1d, 0x89, 0x57, 0x30, 0xf5, + 0xc9, 0xd4, 0x8d, 0xf5, 0x59, 0xb9, 0xb9, 0x18, 0xae, 0xad, 0xc2, 0xcc, 0x3e, 0x0e, 0x87, 0xf8, + 0x52, 0xc6, 0xf9, 0x59, 0x0d, 0xab, 0x23, 0x52, 0x76, 0xa4, 0xca, 0xab, 0x4c, 0x70, 0xc4, 0x6a, + 0x2b, 0xa8, 0xb4, 0x79, 0x3a, 0xf0, 0xa5, 0x1b, 0xb2, 0x85, 0xba, 0x49, 0x9f, 0x2d, 0x42, 0x4c, + 0x60, 0xee, 0x5b, 0x3b, 0x33, 0x30, 0x29, 0xff, 0x0a, 0x4f, 0xd0, 0xd3, 0x66, 0xc3, 0x9a, 0xe3, + 0xaa, 0xaf, 0xb4, 0x9f, 0x19, 0xd5, 0x77, 0xf8, 0x68, 0xcf, 0x29, 0xa2, 0x2a, 0x49, 0x05, 0x92, + 0xaf, 0xfe, 0x14, 0x23, 0x63, 0x67, 0x04, 0x5c, 0x58, 0xf0, 0xc9, 0x97, 0x50, 0x67, 0x59, 0x8d, + 0x86, 0xfb, 0x9d, 0x3e, 0x1e, 0x2a, 0x28, 0x49, 0x33, 0x8e, 0xa3, 0xba, 0xed, 0xbd, 0xdf, 0xcf, + 0xdb, 0xfc, 0x29, 0x43, 0xde, 0x3d, 0x10, 0xcd, 0x7d, 0x73, 0x6b, 0xa5, 0xe7, 0xdc, 0x5f, 0x05, + 0x84, 0x43, 0x22, 0x4e, 0x48, 0x1e, 0x0c, 0xc2, 0xbc, 0x68, 0xc9, 0x2e, 0x96, 0xe8, 0x3b, 0xe0, + 0x80, 0x4c, 0x7d, 0x52, 0xde, 0xc5, 0xec, 0x5a, 0x57, 0x49, 0x29, 0x18, 0xb3, 0xad, 0xc6, 0x9c, + 0xbf, 0xe1, 0x42, 0x3b, 0x66, 0xdd, 0x5e, 0xed, 0xcb, 0x58, 0xe2, 0xd9, 0x43, 0x3e, 0x0a, 0xb4, + 0x9e, 0xbc, 0x92, 0xab, 0x79, 0x2b, 0xf1, 0x97, 0x5b, 0x5b, 0xe8, 0xf7, 0x5f, 0x6d, 0xff, 0x6d, + 0x66, 0xf6, 0xfc, 0x16, 0x4d, 0xbd, 0x74, 0xdd, 0xa1, 0x5f, 0x17, 0xc7, 0xef, 0xbd, 0x5b, 0x69, + 0x24, 0x93, 0xf8, 0x5e, 0xdf, 0x61, 0xb0, 0xd3, 0x2a, 0x74, 0x9e, 0x4e, 0x5f, 0x4f, 0xfc, 0x6c, + 0x61, 0x22, 0xb7, 0x42, 0xb7, 0x7b, 0x0c, 0x3d, 0x41, 0xb6, 0x5c, 0xd7, 0x45, 0x44, 0x59, 0x89, + 0x9b, 0x19, 0x4c, 0x5b, 0x4f, 0xfe, 0x14, 0x26, 0x7c, 0xd2, 0x6a, 0xdd, 0xc5, 0x1c, 0x5e, 0x36, + 0x33, 0xa9, 0xf0, 0x56, 0x26, 0xbe, 0xa8, 0x69, 0xd8, 0xec, 0x46, 0xee, 0x51, 0x18, 0xf8, 0x28, + 0x83, 0xbb, 0x33, 0xec, 0x26, 0xdd, 0xbe, 0x73, 0xe1, 0x1d, 0x0d, 0x50, 0xcd, 0xdb, 0xb1, 0x8d, + 0xd2, 0x0f, 0x07, 0xcc, 0xf8, 0x2b, 0xbe, 0xaa, 0x9d, 0x44, 0xf5, 0x27, 0x27, 0xd2, 0x2f, 0x82, + 0x0a, 0x97, 0xee, 0x9f, 0x43, 0x43, 0x1a, 0x36, 0xb1, 0x26, 0x1a, 0x64, 0xf1, 0xff, 0x87, 0xfb, + 0x6e, 0x6e, 0x5e, 0xfd, 0x83, 0x72, 0x46, 0x36, 0x3a, 0x1b, 0xca, 0x68, 0xa6, 0xb3, 0x0b, 0x71, + 0xfe, 0x11, 0x23, 0x55, 0xe4, 0x69, 0xbf, 0x2b, 0x16, 0x3f, 0x8d, 0x86, 0xde, 0x7e, 0xdb, 0x5a, + 0x8b, 0x43, 0x1f, 0xca, 0x68, 0xba, 0x9c, 0xb8, 0x1b, 0x75, 0x8c, 0x31, 0x4c, 0x91, 0xa2, 0xff, + 0x0a, 0x5f, 0xb5, 0x56, 0xe8, 0x93, 0x6b, 0x32, 0xdc, 0xb1, 0x1f, 0xc1, 0x2f, 0x82, 0x9c, 0xb8, + 0xd7, 0x14, 0xf4, 0x38, 0x32, 0xbc, 0xa0, 0x2b, 0xf8, 0x53, 0x18, 0xee, 0x2e, 0xda, 0xfa, 0x92, + 0xbd, 0x53, 0x2f, 0xef, 0xf0, 0xa4, 0xba, 0x95, 0xb7, 0x5a, 0xad, 0xd3, 0x67, 0xd4, 0x4f, 0x2a, + 0x32, 0x2a, 0xf0, 0x5b, 0x6a, 0xa6, 0x9a, 0xb6, 0xd3, 0xf7, 0xc1, 0x69, 0xea, 0xd3, 0x73, 0x63, + 0xd7, 0xb3, 0xe0, 0xaa, 0xff, 0xee, 0x91, 0x3d, 0x5e, 0xcd, 0xe7, 0x7c, 0x29, 0xf5, 0x75, 0x26, + 0x1f, 0x3c, 0xb8, 0x4c, 0x93, 0xfe, 0x7c, 0x11, 0xf4, 0xdf, 0xbe, 0x0b, 0x08, 0xb6, 0xda, 0xba, + 0x44, 0xfd, 0x2b, 0xeb, 0xe3, 0x7c, 0xb8, 0xe9, 0x4b, 0x72, 0xb3, 0x1a, 0xa7, 0x73, 0x26, 0x66, + 0x2a, 0x74, 0xc9, 0x0f, 0xf1, 0x96, 0x6c, 0x7d, 0xcb, 0x9e, 0x76, 0x26, 0xdc, 0xb9, 0xe1, 0xf9, + 0x68, 0xca, 0xb5, 0x2d, 0xd4, 0xcf, 0xee, 0x5e, 0x86, 0x66, 0x3a, 0xe3, 0x18, 0x26, 0x71, 0xfe, + 0x1f, 0xea, 0x9c, 0x48, 0x61, 0xe5, 0x6f, 0x3c, 0x12, 0xcc, 0x59, 0x19, 0x67, 0x8f, 0xfc, 0x29, + 0x2e, 0x44, 0x92, 0x55, 0xa6, 0x87, 0x43, 0x15, 0xae, 0xfc, 0xcb, 0xc6, 0xdd, 0xac, 0x67, 0x3e, + 0x2f, 0xab, 0x35, 0x64, 0xbc, 0xfc, 0x57, 0x48, 0x8c, 0xa9, 0x4d, 0x42, 0x87, 0x59, 0xa2, 0x8b, + 0x91, 0xcf, 0xf8, 0x52, 0x95, 0x0d, 0x8c, 0x56, 0x38, 0x98, 0x3e, 0xbd, 0x4d, 0xa6, 0xa0, 0xda, + 0x99, 0xdd, 0x2c, 0xba, 0x8a, 0x91, 0xb2, 0x95, 0x17, 0x3b, 0xe3, 0x3c, 0x18, 0xd9, 0x8e, 0x8f, + 0x50, 0xed, 0x46, 0x24, 0xc7, 0x50, 0x9a, 0x9c, 0x7d, 0x0f, 0x1b, 0x3c, 0xae, 0x43, 0xf1, 0xe4, + 0x5b, 0xbd, 0x14, 0x11, 0xd4, 0x2a, 0x4d, 0xd1, 0xa6, 0x55, 0xfc, 0x16, 0x5b, 0x16, 0x32, 0xb3, + 0xae, 0xed, 0xa6, 0xd8, 0xcd, 0x32, 0xf8, 0xb9, 0x59, 0x6e, 0x46, 0xaf, 0x58, 0xd8, 0xa5, 0xbf, + 0xc1, 0x45, 0xd7, 0x96, 0x17, 0x45, 0xff, 0x84, 0x27, 0xf4, 0x57, 0x69, 0x58, 0x6c, 0x94, 0xc8, + 0x99, 0x20, 0xeb, 0x7c, 0x61, 0xd9, 0x8a, 0xef, 0x69, 0x52, 0xcb, 0x0b, 0x76, 0x69, 0x59, 0x10, + 0xf7, 0x83, 0x3b, 0x7c, 0x14, 0x92, 0x9d, 0xd1, 0xf5, 0x9d, 0xae, 0x38, 0xf9, 0xe1, 0xce, 0xf8, + 0x29, 0x25, 0x13, 0x14, 0x19, 0x76, 0x2f, 0xc5, 0x4e, 0x84, 0xda, 0x79, 0x7c, 0x13, 0xe0, 0xed, + 0x3b, 0x7b, 0xbf, 0xc1, 0x66, 0xb5, 0x2b, 0x83, 0xe5, 0x8b, 0x19, 0x58, 0x54, 0x99, 0xb3, 0xb9, + 0xf0, 0xa1, 0x53, 0x53, 0x37, 0xf1, 0x6a, 0x6a, 0x40, 0xac, 0xda, 0xc4, 0xb1, 0xa4, 0x66, 0x9d, + 0x35, 0xf7, 0x92, 0xd2, 0x5e, 0x2c, 0xbe, 0x14, 0xf6, 0x92, 0x4c, 0x65, 0xf1, 0xaa, 0x65, 0x61, + 0xb8, 0xec, 0xe9, 0x39, 0x56, 0x5f, 0x0a, 0x5f, 0x2a, 0x36, 0x78, 0x9e, 0xaa, 0xb3, 0xc1, 0xc6, + 0x5c, 0xb1, 0x9b, 0xbd, 0x8c, 0xbe, 0x0a, 0x6e, 0xfd, 0xab, 0xbf, 0x76, 0xf9, 0x4b, 0xc5, 0x0a, + 0xd6, 0x43, 0x63, 0xd9, 0xc5, 0xdf, 0x36, 0xd5, 0x2f, 0x05, 0x07, 0x3e, 0x79, 0x7f, 0xef, 0x82, + 0x2e, 0x93, 0xb3, 0xea, 0x76, 0xf8, 0x29, 0xd1, 0x56, 0x9b, 0x99, 0xe7, 0x8f, 0x90, 0xbe, 0x0a, + 0x6e, 0x94, 0x70, 0xa9, 0x6e, 0x4c, 0xb1, 0xa6, 0xef, 0xf1, 0xf8, 0xaf, 0x44, 0x58, 0xa5, 0xa5, + 0x2f, 0xf9, 0x78, 0xe9, 0xb7, 0xf0, 0x53, 0x1d, 0x36, 0xbe, 0x1e, 0xb6, 0xec, 0x72, 0x7b, 0x6e, + 0x7c, 0x13, 0xdf, 0x6f, 0x7b, 0xb3, 0xe7, 0xa9, 0x5f, 0x3c, 0x3f, 0xeb, 0xaf, 0x8c, 0xb7, 0xad, + 0x0e, 0x56, 0x72, 0xfb, 0x1e, 0x9d, 0x57, 0x08, 0x70, 0x72, 0xa5, 0x22, 0x9b, 0x71, 0xb5, 0xe4, + 0xff, 0xc1, 0x45, 0xfb, 0x68, 0x63, 0x97, 0x75, 0xbd, 0x71, 0x7e, 0x46, 0xd6, 0x6d, 0xf0, 0x47, + 0x5b, 0xd9, 0x4d, 0xca, 0xe3, 0xed, 0xdd, 0xf2, 0xea, 0xf2, 0xe7, 0x82, 0x1e, 0x92, 0xb1, 0xf3, + 0xd6, 0xb3, 0x43, 0xfc, 0x65, 0x37, 0x6e, 0xb9, 0x58, 0x6d, 0x32, 0x2f, 0x6b, 0x47, 0xf8, 0x26, + 0xb8, 0xae, 0xcd, 0xdb, 0xed, 0x9c, 0x1f, 0x1b, 0xc1, 0xd6, 0x38, 0xf6, 0x94, 0xd9, 0xcb, 0x24, + 0xe8, 0xd5, 0xf3, 0xc1, 0xff, 0xc3, 0xf7, 0xfd, 0xba, 0xc9, 0xb9, 0x75, 0x25, 0x77, 0x65, 0xff, + 0x0a, 0x72, 0xfb, 0x19, 0x62, 0xfe, 0xe4, 0x62, 0xd2, 0xf1, 0x15, 0xc1, 0x27, 0x64, 0xec, 0x7c, + 0x56, 0xcf, 0x6d, 0x8c, 0xd0, 0xfc, 0x7f, 0x6a, 0x16, 0x95, 0x26, 0x60, 0xe0, 0xf6, 0xde, 0x74, + 0x1f, 0x19, 0xa3, 0x74, 0x3b, 0x98, 0xfa, 0x1b, 0xd0, 0xe5, 0x65, 0x0c, 0xdc, 0x14, 0x5c, 0xac, + 0x3b, 0x58, 0x4c, 0x32, 0xee, 0xbf, 0xbe, 0x33, 0x74, 0xed, 0xad, 0x95, 0x51, 0xea, 0x51, 0xae, + 0xfe, 0x09, 0x4d, 0xab, 0x52, 0xc9, 0xe9, 0x45, 0xf2, 0x6f, 0x52, 0x70, 0x99, 0x68, 0x77, 0x43, + 0x95, 0x98, 0x0a, 0x48, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x34, 0x1a, 0x32, 0x8f, 0x12, 0x20, + 0x87, 0x27, 0x77, 0x5f, 0x10, 0x11, 0x10, 0x49, 0x55, 0x55, 0xac, 0xbc, 0x26, 0x45, 0xd6, 0xb5, + 0xf2, 0x9d, 0x55, 0x60, 0xd6, 0x20, 0x40, 0xc3, 0x56, 0xaa, 0x29, 0xc9, 0x91, 0x3e, 0x6e, 0x78, + 0x7a, 0xe7, 0x96, 0x10, 0xf8, 0x80, 0x84, 0x5d, 0x59, 0x9a, 0x85, 0x4e, 0x04, 0x7a, 0x3a, 0xc2, + 0x9a, 0x99, 0x72, 0xff, 0x04, 0x65, 0x95, 0x8b, 0xb7, 0xc5, 0xd3, 0xdb, 0x5b, 0xfc, 0x5f, 0x07, + 0x68, 0x86, 0x5a, 0x8d, 0xc6, 0x2a, 0x0a, 0xf1, 0x3f, 0x2e, 0xef, 0x2c, 0x40, 0x83, 0x08, 0x93, + 0xaa, 0xea, 0x61, 0x90, 0x80, 0xca, 0xc1, 0x05, 0xc9, 0x88, 0x2d, 0x5d, 0xb2, 0xce, 0x5f, 0x55, + 0x51, 0x7c, 0x23, 0x13, 0x2f, 0x48, 0x05, 0x68, 0x9e, 0x65, 0xfc, 0x48, 0x80, 0xa0, 0x93, 0xfb, + 0x12, 0xc0, 0xc1, 0x06, 0x71, 0xe7, 0xbd, 0xb1, 0x03, 0xed, 0x80, 0xe0, 0x7c, 0xeb, 0xad, 0xf8, + 0x9f, 0x13, 0x30, 0x8d, 0x57, 0xcb, 0x77, 0xbe, 0x11, 0x13, 0x05, 0xdd, 0x8f, 0xad, 0x71, 0x10, + 0x88, 0xe1, 0x79, 0x3a, 0x13, 0xbe, 0xaa, 0xb2, 0xa9, 0x57, 0xf1, 0x35, 0xe9, 0xc6, 0x92, 0x45, + 0xfe, 0x24, 0x48, 0xbe, 0xb5, 0xbf, 0x08, 0xf8, 0x9f, 0x13, 0xfa, 0x89, 0x13, 0x8b, 0x20, 0xd1, + 0xa6, 0xad, 0xc1, 0x48, 0x44, 0xc1, 0x0d, 0x33, 0xfc, 0x32, 0x19, 0x09, 0x55, 0x6a, 0x56, 0x36, + 0xe0, 0x9b, 0x94, 0x4a, 0xaa, 0xa4, 0x58, 0x40, 0x48, 0x44, 0x50, 0x9f, 0x17, 0x17, 0x14, 0xf1, + 0x4c, 0x7b, 0x35, 0x17, 0xbe, 0x10, 0x05, 0x01, 0x0a, 0xb3, 0xd4, 0x2c, 0x15, 0x25, 0xe4, 0x58, + 0x65, 0x9c, 0x68, 0x30, 0x66, 0x52, 0xae, 0x63, 0x10, 0x20, 0x66, 0x9a, 0xb7, 0x5a, 0x8b, 0xc9, + 0x34, 0xf3, 0x30, 0x3d, 0x4c, 0x30, 0x20, 0x61, 0x4d, 0x87, 0xb9, 0xf1, 0x38, 0x44, 0x7a, 0x9c, + 0x13, 0x12, 0x6a, 0xc6, 0x4c, 0x76, 0x78, 0x89, 0x6b, 0x17, 0xf9, 0x8f, 0xa8, 0x9e, 0x79, 0x48, + 0xab, 0x22, 0xfe, 0x61, 0x0a, 0xbf, 0x98, 0x80, 0xf7, 0x81, 0x41, 0xd0, 0xf9, 0xe0, 0x84, 0x40, + 0xee, 0x5c, 0x10, 0xe5, 0x4f, 0xab, 0x25, 0x1e, 0xe7, 0xe2, 0x2e, 0xf3, 0xd8, 0x78, 0x91, 0x31, + 0x5d, 0xdd, 0xdc, 0xd9, 0x25, 0x88, 0x98, 0xf3, 0x31, 0x12, 0x54, 0x79, 0x6a, 0xaf, 0x8e, 0x6e, + 0x42, 0xa9, 0x22, 0x97, 0xe2, 0xed, 0xb5, 0xb2, 0x2c, 0x7f, 0x09, 0x53, 0x4f, 0xac, 0x9a, 0x12, + 0xe5, 0x23, 0x5a, 0xae, 0xe4, 0xc5, 0xa6, 0x4e, 0x13, 0x17, 0xaa, 0xee, 0xef, 0x8b, 0x19, 0xaa, + 0x9b, 0x25, 0xff, 0x14, 0x55, 0xae, 0xb6, 0xf8, 0x28, 0x19, 0x0a, 0x70, 0x3e, 0xd6, 0xe3, 0x60, + 0x4d, 0xf3, 0x3d, 0x59, 0xee, 0x57, 0x08, 0xe7, 0x02, 0xfc, 0x95, 0x6c, 0x7f, 0x81, 0xd9, 0xce, + 0x43, 0x44, 0x80, 0x5f, 0xeb, 0x70, 0xd1, 0xd7, 0xa7, 0xa8, 0xc8, 0x95, 0x1b, 0xe2, 0x5b, 0xbb, + 0x6b, 0x6d, 0x56, 0xda, 0xba, 0xbe, 0xb2, 0x7c, 0xe1, 0x80, 0x50, 0x0a, 0xe5, 0x86, 0x16, 0x0a, + 0x9e, 0x28, 0x3f, 0x3a, 0xb5, 0xdd, 0x11, 0xf1, 0xb2, 0x53, 0x8b, 0xf1, 0x31, 0x05, 0x37, 0x66, + 0x5b, 0x88, 0x69, 0x57, 0xc4, 0x08, 0x05, 0x42, 0x19, 0x7e, 0x6c, 0x37, 0x26, 0x3e, 0xc9, 0x59, + 0x8f, 0xbc, 0x49, 0x6a, 0x88, 0x4b, 0x02, 0x55, 0x7d, 0x9e, 0xb5, 0xc4, 0xc1, 0x60, 0x96, 0xaa, + 0xaa, 0xaa, 0xaa, 0xbf, 0x71, 0x22, 0x02, 0x75, 0x5a, 0x55, 0xae, 0x10, 0x82, 0x43, 0x54, 0xc3, + 0x05, 0x4b, 0x57, 0x3c, 0x30, 0x41, 0x85, 0xe2, 0x46, 0x82, 0x5c, 0x7e, 0x78, 0x21, 0x1a, 0xf9, + 0x73, 0x79, 0x70, 0x87, 0x89, 0x30, 0xaa, 0x75, 0xe2, 0x63, 0xf8, 0x28, 0x1e, 0x9b, 0xf6, 0x9a, + 0xb1, 0x2f, 0x62, 0x9a, 0x4a, 0x98, 0x8e, 0x09, 0xfc, 0x5d, 0xb4, 0xad, 0xce, 0xbe, 0xbd, 0xc4, + 0xc1, 0x5f, 0x77, 0x77, 0x7d, 0xe9, 0xbf, 0xc2, 0x55, 0xaa, 0xba, 0x4d, 0x57, 0x2f, 0x2e, 0x78, + 0x90, 0xa4, 0x3b, 0xe2, 0xce, 0x48, 0x62, 0x5e, 0x5e, 0x5e, 0x81, 0x2e, 0xaa, 0xaa, 0x9f, 0xb8, + 0x42, 0x14, 0x2e, 0x68, 0x30, 0xf9, 0xaa, 0x9b, 0x89, 0xe0, 0x9f, 0x2f, 0x94, 0xd5, 0xa7, 0xe0, + 0xa0, 0x22, 0x30, 0xcd, 0xa6, 0xa0, 0xff, 0xa5, 0x76, 0xe2, 0x3f, 0x67, 0xb8, 0xae, 0x20, 0x7e, + 0x22, 0x5d, 0x55, 0x7c, 0x23, 0xe2, 0x18, 0x6c, 0x63, 0xd9, 0x34, 0xf9, 0x32, 0x9e, 0x20, 0x40, + 0x88, 0x50, 0x4d, 0x96, 0xf8, 0x16, 0xdc, 0x56, 0xdf, 0x11, 0x1f, 0xa6, 0x9e, 0xdb, 0x63, 0xfa, + 0xbe, 0x82, 0x63, 0xc4, 0x7c, 0x48, 0x82, 0x6d, 0xad, 0xa1, 0x3a, 0x1d, 0x20, 0xf9, 0x2d, 0x6f, + 0xe2, 0x2a, 0x20, 0x4e, 0x1b, 0x84, 0xc0, 0x04, 0x1f, 0x5f, 0x77, 0xff, 0xaf, 0xfc, 0x0a, 0x22, + 0xb8, 0x7e, 0xee, 0x9f, 0xdf, 0x14, 0x10, 0x2f, 0x6c, 0xbe, 0xb2, 0xfe, 0xfe, 0x30, 0xeb, 0x55, + 0x51, 0xc3, 0x25, 0xd3, 0xbd, 0x62, 0xe4, 0xdf, 0x29, 0x1c, 0x9e, 0xf5, 0xcd, 0xad, 0xfc, 0x5d, + 0x24, 0xb4, 0x92, 0xcd, 0xc1, 0x38, 0x96, 0x6c, 0xe9, 0xed, 0x92, 0x0e, 0xf9, 0xb1, 0xec, 0x99, + 0x57, 0xe0, 0x87, 0x6a, 0xd6, 0x11, 0x3c, 0x12, 0x75, 0x58, 0x4a, 0xea, 0xd1, 0x51, 0x02, 0x0c, + 0x47, 0x77, 0x15, 0xf9, 0x49, 0xbb, 0xfb, 0xae, 0xbe, 0x5a, 0xad, 0x7c, 0x54, 0x43, 0x83, 0x39, + 0x1b, 0x4f, 0x73, 0x54, 0xf1, 0x02, 0x46, 0x14, 0xa3, 0x34, 0x6e, 0x20, 0xd5, 0x54, 0x0d, 0x33, + 0x18, 0x51, 0xf0, 0x54, 0xce, 0x91, 0x20, 0x0a, 0xbe, 0x00, 0xe0, 0x3d, 0x40, 0x7f, 0x2a, 0x2c, + 0x39, 0x0f, 0x1e, 0xeb, 0x87, 0x9c, 0x00, 0xd7, 0xc6, 0x06, 0xe9, 0x45, 0x19, 0xe9, 0xfe, 0xe7, + 0xf0, 0x79, 0xea, 0x74, 0x65, 0x77, 0x08, 0x76, 0x98, 0xf5, 0xc7, 0xdc, 0xbd, 0xc7, 0x37, 0x1f, + 0x79, 0x8f, 0xce, 0xce, 0x04, 0xf6, 0xe7, 0xf4, 0xf8, 0x62, 0x14, 0xab, 0x45, 0xe3, 0x15, 0x03, + 0xa7, 0x80, 0x3a, 0xbf, 0xa0, 0xdd, 0xaa, 0x5e, 0x03, 0xd1, 0xfc, 0x5e, 0x2e, 0x5e, 0x2e, 0x29, + 0xf7, 0xc2, 0x84, 0x2f, 0x2c, 0xcb, 0xd4, 0xb3, 0x51, 0x1c, 0x2c, 0xc5, 0xc5, 0xc5, 0xc5, 0xdd, + 0x85, 0xf2, 0x48, 0x77, 0xcb, 0x59, 0x7a, 0x64, 0x14, 0x83, 0x23, 0x8b, 0x0f, 0x44, 0x04, 0xdc, + 0x4d, 0xbf, 0xff, 0x78, 0x86, 0x09, 0x7f, 0xd7, 0x89, 0x04, 0xe2, 0xa7, 0xbf, 0x15, 0x88, 0x71, + 0xfe, 0x53, 0x69, 0x17, 0x31, 0x02, 0x41, 0x3e, 0x5e, 0xed, 0x66, 0x21, 0x66, 0xec, 0x31, 0x1e, + 0x22, 0x6d, 0xdf, 0x88, 0x10, 0x12, 0x83, 0xab, 0xc7, 0xde, 0xf8, 0x40, 0x40, 0x9a, 0x9e, 0x9a, + 0x26, 0xa9, 0x62, 0x21, 0x32, 0x36, 0x21, 0x63, 0x95, 0x88, 0xd6, 0x6b, 0x82, 0x12, 0xe4, 0xf6, + 0x43, 0xdc, 0x50, 0xb7, 0x15, 0xdd, 0xdd, 0xdf, 0x10, 0x20, 0xc6, 0xdd, 0xd7, 0x0a, 0x6b, 0x55, + 0x55, 0xa8, 0xbe, 0xa6, 0xa2, 0x86, 0xbb, 0x00, 0x94, 0xe0, 0xe0, 0x82, 0x0a, 0x88, 0x24, 0x01, + 0xc0, 0xa8, 0x02, 0xa6, 0x32, 0x6e, 0xea, 0xbd, 0x6f, 0x9d, 0xa5, 0x58, 0xe7, 0x10, 0x08, 0x02, + 0x85, 0x8e, 0xcd, 0x93, 0x76, 0xe2, 0xb8, 0xae, 0xdd, 0xd5, 0x62, 0xc3, 0x04, 0x80, 0x29, 0x4d, + 0x7a, 0x21, 0xbf, 0x2a, 0xb6, 0xf6, 0xdb, 0x6d, 0xbb, 0x76, 0xcf, 0xdf, 0xee, 0xd3, 0xbc, 0x0f, + 0x20, 0xe0, 0x29, 0x2d, 0xf1, 0x2e, 0x5a, 0x75, 0x88, 0xf5, 0x5a, 0x82, 0x16, 0x5f, 0x09, 0x28, + 0x43, 0x38, 0x00, 0x56, 0x66, 0x99, 0x8c, 0x8a, 0xac, 0x7e, 0x37, 0xfe, 0x6f, 0x37, 0x4c, 0x79, + 0xfa, 0xc9, 0x1c, 0x3f, 0xdb, 0xae, 0x2a, 0xc1, 0xdb, 0xe3, 0x38, 0x90, 0x42, 0x14, 0x97, 0x6a, + 0xc8, 0x1c, 0xb4, 0x90, 0x7a, 0xb1, 0x18, 0x05, 0x82, 0xae, 0xe4, 0xa5, 0x59, 0xcb, 0x3f, 0x8a, + 0x0c, 0x48, 0x44, 0x10, 0x1d, 0x8d, 0xb4, 0xf8, 0x35, 0x55, 0x54, 0xe7, 0xed, 0x55, 0x91, 0xde, + 0xd9, 0x77, 0x13, 0xd3, 0x6f, 0x12, 0x1f, 0x10, 0xee, 0xef, 0x76, 0x81, 0x82, 0xbd, 0x8b, 0x34, + 0xb1, 0xcd, 0xd1, 0x8a, 0xfc, 0x71, 0x5d, 0xbe, 0x08, 0xcb, 0x83, 0x05, 0x79, 0x3f, 0x29, 0x8e, + 0x07, 0x81, 0x21, 0xf8, 0x3a, 0x7e, 0x17, 0x15, 0xdf, 0xef, 0x9b, 0xb9, 0x44, 0xa8, 0x2a, 0x3c, + 0xfe, 0x2b, 0xff, 0x1e, 0x47, 0x77, 0x79, 0xbb, 0xd7, 0x9b, 0x0f, 0x0f, 0x04, 0x44, 0x81, 0xdb, + 0x57, 0xd8, 0xe2, 0x44, 0x2b, 0x78, 0x81, 0xc5, 0x07, 0xac, 0x10, 0x73, 0x43, 0x0d, 0x14, 0xcb, + 0xb7, 0x77, 0xe2, 0x02, 0x76, 0xec, 0xab, 0xe3, 0x26, 0x13, 0x1f, 0xc4, 0xc4, 0xe2, 0x1e, 0xbe, + 0xb4, 0xbc, 0x28, 0x4b, 0x65, 0xe8, 0x41, 0x1a, 0x8b, 0x91, 0xb3, 0xa1, 0x90, 0xaf, 0x8b, 0xca, + 0xde, 0x7d, 0x26, 0x25, 0x58, 0x9a, 0xb7, 0xa3, 0x15, 0xc4, 0x05, 0x2a, 0x7c, 0x3f, 0x71, 0x0a, + 0x31, 0x0e, 0x44, 0xb8, 0x06, 0xf8, 0xf2, 0x9b, 0x94, 0x58, 0xe6, 0xbc, 0xb3, 0x16, 0xe9, 0xc4, + 0x2b, 0x4a, 0xb8, 0x81, 0x9b, 0x8a, 0xc5, 0x6f, 0x8a, 0xd5, 0xc4, 0x3d, 0xf3, 0xc7, 0xed, 0x0a, + 0xf1, 0x02, 0x01, 0x3d, 0x25, 0xd4, 0xbe, 0x2e, 0xdf, 0x0c, 0x46, 0xf2, 0x7e, 0xcc, 0x9b, 0x2c, + 0xc2, 0x7a, 0xfe, 0x5a, 0x9e, 0xa0, 0x83, 0x8a, 0xde, 0xae, 0x0f, 0x3c, 0x81, 0x64, 0x9e, 0xc6, + 0x10, 0x85, 0x20, 0xb2, 0xff, 0x3b, 0xd2, 0x9e, 0x29, 0x59, 0xe5, 0xf5, 0xad, 0x1d, 0xb7, 0xd9, + 0xb9, 0xde, 0x78, 0x7b, 0x39, 0xc1, 0xc4, 0x09, 0x19, 0xad, 0x77, 0x0b, 0xd7, 0x12, 0x1c, 0x12, + 0x1a, 0x09, 0xe1, 0x61, 0x9d, 0xc2, 0xeb, 0x82, 0x81, 0x93, 0x73, 0x8f, 0xa4, 0xc8, 0x0a, 0xa1, + 0x70, 0xd4, 0x82, 0xe1, 0xb7, 0x71, 0x14, 0x02, 0xc8, 0x71, 0x6c, 0xe0, 0x0f, 0x67, 0xd2, 0x0f, + 0xdb, 0xc0, 0xc3, 0x0a, 0x4f, 0x01, 0xf5, 0x3f, 0x26, 0xae, 0x90, 0xf3, 0xc0, 0xf7, 0x28, 0xbc, + 0x3e, 0x2e, 0x01, 0xe1, 0xfc, 0x0e, 0xcd, 0x47, 0x21, 0xe0, 0x7b, 0xd4, 0x70, 0x31, 0xc1, 0xe1, + 0x10, 0x88, 0x53, 0x32, 0xe0, 0x87, 0x2c, 0xe5, 0xcb, 0x26, 0x07, 0x07, 0x80, 0xf0, 0x7b, 0x8b, + 0x87, 0x01, 0xd8, 0x5b, 0x94, 0x1b, 0xd8, 0xf8, 0xee, 0x1e, 0x21, 0x40, 0x41, 0xe7, 0x12, 0x60, + 0x8b, 0xd7, 0x4c, 0xbe, 0xa9, 0xab, 0x76, 0xdb, 0xfe, 0x44, 0xb5, 0xe9, 0xa7, 0xe0, 0x84, 0x04, + 0x08, 0x52, 0x31, 0xa5, 0x1b, 0xce, 0x3e, 0xc5, 0x1d, 0x42, 0x63, 0x88, 0x19, 0xe1, 0x60, 0x50, + 0xd3, 0x0a, 0x9c, 0x1e, 0x70, 0x4b, 0xd9, 0x95, 0x49, 0x98, 0xc5, 0xc3, 0xd3, 0x81, 0x59, 0x38, + 0x9d, 0xc9, 0xdf, 0x8d, 0x7e, 0x74, 0xf8, 0x9c, 0x20, 0x35, 0x0e, 0xe6, 0xfa, 0x35, 0x86, 0xd8, + 0x80, 0x04, 0xde, 0x20, 0x9c, 0xab, 0xea, 0x1a, 0xb8, 0x90, 0x7c, 0xc6, 0x0f, 0x06, 0x1f, 0xc5, + 0xcf, 0x01, 0x81, 0xd6, 0x0f, 0x01, 0x87, 0x8e, 0x18, 0xc6, 0x58, 0x7f, 0xe3, 0x10, 0xd0, 0xf4, + 0x26, 0xa3, 0x29, 0x87, 0x62, 0x00, 0x03, 0x8a, 0x23, 0x79, 0x90, 0x48, 0xa5, 0x69, 0xff, 0xf8, + 0x3a, 0xf8, 0x31, 0x7c, 0xfe, 0x12, 0x88, 0xc2, 0xb6, 0x5c, 0x1a, 0x4b, 0xb8, 0x3a, 0xfc, 0x3b, + 0x20, 0x00, 0x7f, 0x3b, 0x03, 0x82, 0xdf, 0xe1, 0x04, 0x78, 0xe0, 0xd5, 0xe0, 0x4b, 0xdb, 0xcf, + 0x34, 0x16, 0x4b, 0xc4, 0x87, 0x4e, 0x74, 0xd4, 0x9d, 0x9f, 0xe1, 0x88, 0xec, 0x49, 0x32, 0x73, + 0xc0, 0x91, 0xd3, 0x3f, 0xba, 0x0b, 0x88, 0x12, 0x27, 0xc4, 0x7c, 0xdc, 0xdb, 0xe2, 0x44, 0x82, + 0x42, 0xf3, 0xeb, 0x0c, 0x22, 0x24, 0x14, 0x11, 0x64, 0x8e, 0x96, 0x14, 0x6a, 0x56, 0xb6, 0x78, + 0xe1, 0x53, 0x88, 0xcb, 0xc2, 0x38, 0x82, 0x62, 0x21, 0xc9, 0x96, 0x11, 0x0a, 0x93, 0x7a, 0xec, + 0xe2, 0x2c, 0x75, 0x7f, 0xc4, 0x44, 0xe6, 0x23, 0xe7, 0xd8, 0xb7, 0x7c, 0x49, 0x23, 0x75, 0x72, + 0xa1, 0xee, 0x13, 0xdd, 0xef, 0xba, 0x88, 0x08, 0x85, 0x22, 0x8c, 0x56, 0x2b, 0x15, 0x97, 0xca, + 0xa4, 0x1b, 0x0f, 0x23, 0x2b, 0x65, 0x4b, 0xf9, 0x71, 0x43, 0x71, 0x4d, 0x39, 0x31, 0xc3, 0x21, + 0x10, 0xa4, 0xf7, 0x4e, 0x03, 0x91, 0x44, 0xcd, 0x25, 0x54, 0xb6, 0x5b, 0x15, 0x8a, 0x34, 0xc5, + 0x06, 0x28, 0xdc, 0x50, 0x62, 0x1c, 0xa3, 0xbe, 0x04, 0x10, 0x55, 0x93, 0xb9, 0x11, 0xc1, 0x01, + 0xc2, 0xc3, 0x95, 0xd5, 0x5f, 0x81, 0xa0, 0x09, 0x23, 0x24, 0x80, 0x71, 0x65, 0x86, 0x23, 0xdb, + 0xa5, 0x10, 0x25, 0xb5, 0x4a, 0xbb, 0xbf, 0x8a, 0xe1, 0xc5, 0x02, 0xa5, 0x5a, 0x06, 0xce, 0x6c, + 0x23, 0x77, 0x02, 0x6f, 0x8d, 0xd8, 0x0a, 0xa8, 0x73, 0x9a, 0xa3, 0xfe, 0xcf, 0x1b, 0x3a, 0xc6, + 0x4f, 0x4a, 0x9b, 0xe9, 0xfc, 0x05, 0x00, 0x60, 0x15, 0x1c, 0x98, 0x00, 0x08, 0x29, 0x66, 0x1f, + 0x09, 0x4e, 0xe0, 0xb8, 0x74, 0xf1, 0x66, 0xce, 0x24, 0x3c, 0x7d, 0xd2, 0x6f, 0x88, 0xe9, 0x87, + 0x30, 0x8a, 0x25, 0x5c, 0x0a, 0xdf, 0xf4, 0xe1, 0x3b, 0x79, 0x77, 0x97, 0xa6, 0x9f, 0x4c, 0x7f, + 0xf1, 0xf1, 0x27, 0xaf, 0x7e, 0x1e, 0x50, 0x01, 0x09, 0x5f, 0xb3, 0x62, 0x5a, 0x0b, 0x69, 0xbf, + 0xbf, 0xbc, 0xfb, 0x8f, 0xa7, 0xf1, 0xa5, 0x49, 0xad, 0xd6, 0x7d, 0x2a, 0xca, 0x9c, 0x70, 0xe2, + 0x30, 0x02, 0x3a, 0x36, 0x7b, 0x55, 0xb3, 0xa7, 0xbe, 0x77, 0x26, 0x1e, 0xe5, 0xd8, 0xb7, 0x4f, + 0xfc, 0x1e, 0x90, 0x04, 0x29, 0x8b, 0x7d, 0x62, 0xaf, 0x87, 0x94, 0x01, 0x7e, 0x61, 0x3b, 0xbf, + 0x9d, 0x3d, 0x3d, 0x3b, 0x6d, 0xdb, 0x6d, 0xb6, 0xdb, 0x47, 0x04, 0xfa, 0x49, 0x70, 0xf2, 0x80, + 0x0f, 0xb2, 0x26, 0x60, 0xef, 0x12, 0x5f, 0x77, 0xf3, 0x53, 0xf2, 0xd1, 0x7f, 0x9f, 0x59, 0x67, + 0x8e, 0x99, 0x76, 0xb8, 0xc4, 0x34, 0x6c, 0x74, 0x7c, 0x2f, 0x18, 0x49, 0x6a, 0x73, 0x5c, 0xbc, + 0xbb, 0xf0, 0x60, 0x24, 0x13, 0x44, 0x00, 0x07, 0xa8, 0xac, 0xac, 0x02, 0xa6, 0x39, 0x05, 0xe5, + 0x36, 0x78, 0x1c, 0x73, 0x03, 0x51, 0x78, 0x22, 0x2b, 0xef, 0xdf, 0x64, 0x7b, 0xfd, 0x09, 0x45, + 0x29, 0x7f, 0x10, 0x09, 0xc5, 0x2a, 0x9b, 0xcc, 0xde, 0xbd, 0xf3, 0x5d, 0xef, 0xe1, 0x31, 0x75, + 0xaa, 0xed, 0xf1, 0x0c, 0x44, 0x49, 0xf5, 0xe2, 0x02, 0x91, 0xda, 0x0a, 0xc1, 0xd4, 0xac, 0x18, + 0x7c, 0xc6, 0x57, 0x04, 0x2e, 0xef, 0x83, 0xa9, 0x04, 0x31, 0xce, 0x1e, 0x87, 0x4c, 0x6b, 0x79, + 0x54, 0xb5, 0xb4, 0x5f, 0x27, 0x20, 0x5a, 0xb1, 0xff, 0x4c, 0x60, 0x7f, 0xd0, 0xcf, 0x89, 0xd6, + 0x55, 0xcc, 0x49, 0x7a, 0x60, 0x82, 0x24, 0x30, 0x32, 0xd9, 0x0c, 0x70, 0x6b, 0x43, 0xd8, 0xa7, + 0xd4, 0x96, 0xb2, 0xed, 0xc4, 0xf8, 0xaf, 0x83, 0xb7, 0xf8, 0x60, 0x46, 0x16, 0x15, 0xe1, 0xc6, + 0x01, 0xa8, 0xb2, 0x00, 0x1f, 0xd6, 0x3a, 0xf3, 0x12, 0x11, 0x0a, 0x6d, 0xf7, 0xe1, 0x80, 0x54, + 0x14, 0x62, 0xb1, 0x41, 0x88, 0x07, 0x04, 0x3c, 0xe0, 0x00, 0x58, 0x0f, 0x81, 0xa9, 0x38, 0x02, + 0xaf, 0xe2, 0x02, 0x91, 0x03, 0x85, 0xb2, 0x71, 0x54, 0xf5, 0x25, 0xf9, 0x79, 0x63, 0x0f, 0xb5, + 0x2c, 0x65, 0x80, 0xce, 0x1c, 0x38, 0x79, 0xee, 0x16, 0xe4, 0xef, 0x02, 0x80, 0x0e, 0x90, 0x52, + 0x52, 0x10, 0x94, 0x1d, 0x6c, 0x00, 0x15, 0xa3, 0xcc, 0x62, 0x8d, 0x42, 0x75, 0x57, 0xfd, 0xf1, + 0xf5, 0x87, 0xb6, 0xa7, 0x98, 0xe2, 0x3f, 0x26, 0x01, 0x82, 0x18, 0x64, 0x10, 0x85, 0x04, 0xd8, + 0xa3, 0x4c, 0x56, 0x28, 0xcb, 0x19, 0xfa, 0xd5, 0x77, 0x10, 0xe7, 0x5b, 0x7b, 0x92, 0x0a, 0xa3, + 0xf8, 0x39, 0x85, 0x08, 0x28, 0xc5, 0x6f, 0xd8, 0xc5, 0x61, 0x60, 0x05, 0x5c, 0xb1, 0xca, 0xc5, + 0xcb, 0x9b, 0xe1, 0x24, 0x40, 0xd9, 0xce, 0x87, 0xfa, 0x7e, 0x1c, 0x50, 0x24, 0x69, 0xa2, 0x64, + 0xd3, 0xd3, 0x4f, 0xff, 0xab, 0x7d, 0x3f, 0x0b, 0x90, 0xa0, 0x07, 0xbe, 0x25, 0x9c, 0x89, 0x5a, + 0x77, 0x7d, 0xf7, 0x7f, 0xc6, 0x3d, 0x86, 0xe3, 0x00, 0x0c, 0x4a, 0x31, 0x6a, 0x3f, 0x2b, 0xba, + 0xbc, 0x7b, 0x0e, 0x1d, 0xec, 0x78, 0xad, 0xd0, 0x15, 0xe5, 0xe7, 0xeb, 0x5c, 0x0a, 0x11, 0x27, + 0x51, 0x97, 0x5d, 0x6e, 0xec, 0x2e, 0x21, 0x02, 0x25, 0xf1, 0x1f, 0x26, 0x06, 0x36, 0xb5, 0x8f, + 0x89, 0x2d, 0xee, 0xfe, 0x5e, 0xee, 0xb8, 0x44, 0xd3, 0xf0, 0x7f, 0xca, 0xbd, 0x2a, 0x6f, 0x2a, + 0xf1, 0x5a, 0x10, 0x54, 0xfc, 0xa7, 0xc3, 0x95, 0x9f, 0xb2, 0x3d, 0xfe, 0x5e, 0xa9, 0xf8, 0xa2, + 0xba, 0xb3, 0x75, 0xc8, 0x65, 0x62, 0xfe, 0x59, 0x3c, 0xaf, 0xc9, 0x90, 0x0f, 0x72, 0x11, 0xdf, + 0xf1, 0xe5, 0x7b, 0xdd, 0xdd, 0xdf, 0x7f, 0x13, 0x7b, 0xdf, 0x4f, 0x10, 0x25, 0xdd, 0xd7, 0x0e, + 0x90, 0xe0, 0x05, 0xe2, 0x52, 0x8b, 0x18, 0x8d, 0x89, 0xb6, 0x1b, 0x3f, 0xa7, 0xe2, 0xb8, 0xac, + 0x08, 0x70, 0x2f, 0x5e, 0xf5, 0xac, 0x35, 0x20, 0x00, 0xcc, 0x6d, 0xad, 0xcc, 0x5e, 0xfd, 0x7d, + 0x5f, 0x1f, 0xa5, 0x32, 0x4f, 0x37, 0x93, 0xeb, 0x2f, 0x9c, 0xb8, 0x80, 0x30, 0x82, 0xb9, 0xe0, + 0xfc, 0xf7, 0xcb, 0xe4, 0xcc, 0x43, 0xcb, 0xcb, 0x07, 0xd8, 0x5d, 0x89, 0x00, 0xa7, 0x48, 0x00, + 0x75, 0xf3, 0x99, 0x87, 0x99, 0xd7, 0x6a, 0x37, 0x47, 0x75, 0xcd, 0x2e, 0x1a, 0x44, 0x02, 0x4e, + 0xb4, 0x7d, 0x5f, 0xff, 0xd5, 0xb0, 0xc2, 0x86, 0x28, 0xef, 0xa7, 0xd3, 0xa7, 0xff, 0x61, 0xa2, + 0x40, 0x18, 0x72, 0x9e, 0x5d, 0xd9, 0x7b, 0x77, 0xfb, 0xbd, 0xdf, 0x16, 0xca, 0x08, 0x92, 0xeb, + 0x71, 0xdb, 0x0b, 0xc7, 0x00, 0x0c, 0xa3, 0x21, 0x15, 0xea, 0x1a, 0xbc, 0xdf, 0xc9, 0xfd, 0x59, + 0xd4, 0xbf, 0x99, 0x61, 0x90, 0x08, 0xc8, 0xd8, 0xde, 0x04, 0xb4, 0x35, 0x20, 0xf8, 0x6d, 0x8b, + 0x98, 0x0c, 0xc1, 0x60, 0x00, 0x56, 0x28, 0x00, 0x15, 0x9e, 0x00, 0xe1, 0xe0, 0x38, 0xdf, 0x5b, + 0xb4, 0xf6, 0x15, 0x54, 0xab, 0x05, 0x86, 0x18, 0xa0, 0x1c, 0x73, 0x07, 0x6e, 0x2a, 0xd7, 0xef, + 0x82, 0x22, 0xd6, 0x3b, 0x84, 0x58, 0xb1, 0x13, 0x4f, 0x0c, 0x56, 0xb0, 0x88, 0x29, 0x20, 0x5f, + 0x93, 0x98, 0x38, 0x30, 0x92, 0x51, 0xa7, 0x6d, 0x83, 0xb7, 0x38, 0xf1, 0xe5, 0x51, 0x5b, 0xf8, + 0x90, 0x87, 0xb9, 0x6c, 0x3a, 0x0f, 0xc3, 0xfc, 0xd5, 0x26, 0xbc, 0x4c, 0x64, 0x0e, 0xe2, 0xa6, + 0x1d, 0xd5, 0x39, 0x58, 0x76, 0xb0, 0x35, 0xfe, 0xe5, 0x68, 0x71, 0xdc, 0x62, 0x60, 0xac, 0xb8, + 0x31, 0xe8, 0x0a, 0x72, 0x07, 0x3d, 0xd2, 0x46, 0xe6, 0x43, 0xfd, 0x27, 0x5f, 0x2b, 0x0c, 0xa8, + 0x99, 0x89, 0x51, 0xa6, 0xa5, 0x14, 0xd7, 0x88, 0x13, 0xdd, 0xc7, 0xa9, 0x93, 0xee, 0x61, 0xf8, + 0x8f, 0x10, 0x20, 0x85, 0x88, 0x7d, 0xe1, 0x99, 0xc0, 0x07, 0x79, 0xfd, 0x18, 0xf3, 0x7f, 0xf6, + 0xf6, 0xdb, 0xf5, 0xb6, 0x0e, 0xdd, 0xbe, 0xda, 0x3f, 0x81, 0xa4, 0x06, 0x80, 0x50, 0x97, 0x77, + 0xac, 0x50, 0x0e, 0x20, 0xe0, 0xac, 0x56, 0x2b, 0x15, 0x9d, 0x93, 0x9c, 0xb7, 0xe3, 0x9c, 0x10, + 0x00, 0xd1, 0x0a, 0x77, 0x3f, 0x3f, 0xec, 0x2c, 0x2a, 0x79, 0xc7, 0x69, 0x28, 0x2a, 0x3a, 0x2e, + 0x4a, 0x0d, 0x47, 0xf9, 0x60, 0x19, 0xc7, 0x96, 0x01, 0x96, 0x06, 0x31, 0x8d, 0xe1, 0xa7, 0x09, + 0x4d, 0x91, 0xa7, 0xd5, 0xff, 0xd3, 0x4f, 0xfb, 0x0c, 0x60, 0x98, 0x61, 0x2d, 0xad, 0x34, 0xf4, + 0xd3, 0xa7, 0xd7, 0xeb, 0x0b, 0xa8, 0x00, 0xdb, 0xf2, 0x8d, 0x18, 0x5f, 0xf4, 0xff, 0x6e, 0x6e, + 0xde, 0xb7, 0xc2, 0x71, 0x60, 0x0c, 0x6e, 0x4a, 0x38, 0x07, 0xbe, 0xb5, 0xf7, 0x9f, 0xb7, 0x82, + 0x90, 0x0a, 0x08, 0x50, 0x42, 0xab, 0x78, 0xae, 0xf2, 0xe2, 0x96, 0xef, 0x15, 0x8e, 0xee, 0x0c, + 0x41, 0x88, 0x50, 0x8e, 0x2b, 0xbc, 0xdd, 0x4b, 0x3d, 0xdc, 0x5c, 0x48, 0x1e, 0x27, 0xcb, 0x0f, + 0xb0, 0xd9, 0x20, 0x1d, 0xee, 0x33, 0x9c, 0xbd, 0xec, 0x56, 0xe2, 0xb2, 0x53, 0x71, 0xbd, 0x18, + 0x15, 0x97, 0x62, 0xba, 0x67, 0x07, 0xb7, 0xa2, 0x8d, 0x7a, 0x8f, 0x41, 0x34, 0xe8, 0x9d, 0x17, + 0xf9, 0x4a, 0x13, 0x39, 0xcc, 0xb5, 0xf7, 0x7c, 0x86, 0x7b, 0xfc, 0x21, 0x5b, 0x97, 0x22, 0xbc, + 0x48, 0xe3, 0xb4, 0xd3, 0xc4, 0x88, 0xcd, 0x4c, 0xb3, 0x1d, 0x79, 0xf8, 0xf3, 0x96, 0xf8, 0x3b, + 0xe6, 0xd3, 0xf3, 0x7d, 0xfc, 0x74, 0x4b, 0x8e, 0xb7, 0x7d, 0x24, 0xad, 0x71, 0x20, 0x96, 0x2e, + 0x23, 0x9b, 0x30, 0x7d, 0x9b, 0xfc, 0x41, 0x99, 0x84, 0xcd, 0x99, 0xee, 0xa0, 0x82, 0x10, 0x8f, + 0x3a, 0xaf, 0x55, 0x55, 0xdf, 0x0c, 0x41, 0x6c, 0x5a, 0x14, 0xa7, 0x89, 0x1e, 0xe5, 0x8c, 0x57, + 0x30, 0xc4, 0xc1, 0x55, 0x24, 0x9d, 0xa8, 0x54, 0xe4, 0x6e, 0x78, 0x1e, 0xa3, 0xa2, 0xea, 0x53, + 0xd6, 0xec, 0x38, 0xa0, 0x02, 0xfe, 0x3e, 0xa7, 0x4a, 0xc1, 0x54, 0xb4, 0xf3, 0x30, 0x72, 0xf9, + 0x46, 0xe4, 0x7f, 0x0e, 0x7e, 0x3f, 0xe7, 0x3c, 0x7f, 0xf7, 0x76, 0xfe, 0xbd, 0xb1, 0x56, 0x24, + 0x41, 0x9a, 0xbb, 0x7f, 0x84, 0x00, 0x25, 0x23, 0x09, 0xc5, 0x62, 0xb7, 0x7c, 0xf8, 0x5b, 0x3f, + 0x77, 0x56, 0xc5, 0xf0, 0x41, 0x1e, 0x24, 0x2c, 0x02, 0xa7, 0x80, 0x38, 0xfc, 0x7e, 0x09, 0x00, + 0x70, 0x48, 0x0e, 0x16, 0xf5, 0x17, 0xae, 0x10, 0x08, 0x85, 0x04, 0x16, 0x31, 0x40, 0x77, 0x07, + 0x4f, 0x8a, 0xcb, 0x62, 0x07, 0xad, 0x6e, 0x58, 0xe2, 0x8f, 0xb0, 0xb1, 0x20, 0x0e, 0x6e, 0x07, + 0x67, 0x1f, 0xea, 0xea, 0xf9, 0x7a, 0x78, 0x10, 0x01, 0x88, 0x2b, 0x2b, 0x76, 0xed, 0xcf, 0xf2, + 0xf7, 0x38, 0x1f, 0xdc, 0x09, 0x21, 0x80, 0xa5, 0xa9, 0x3c, 0xdc, 0xf0, 0x3e, 0x24, 0x3c, 0xbd, + 0x32, 0xf4, 0xdb, 0x88, 0xb8, 0xaf, 0x1c, 0x1d, 0x2c, 0x3c, 0x42, 0x00, 0x08, 0xe5, 0xe2, 0xb1, + 0x0d, 0xf0, 0x9f, 0xa1, 0x58, 0x36, 0x5c, 0xde, 0x48, 0x7b, 0x8e, 0x3b, 0x6d, 0x5f, 0x14, 0x6c, + 0x27, 0x7d, 0x8b, 0xbf, 0xe0, 0x57, 0xba, 0xbb, 0x29, 0xa1, 0xf6, 0x50, 0xe9, 0x8e, 0x96, 0x0d, + 0x5b, 0x31, 0xf6, 0xec, 0x9c, 0x50, 0x83, 0x73, 0xf8, 0x24, 0xf3, 0x8f, 0x17, 0x92, 0x7f, 0xd9, + 0x45, 0xf3, 0x3e, 0x24, 0x28, 0x40, 0x07, 0xbf, 0xbe, 0xfb, 0x1b, 0x95, 0x2e, 0xf1, 0x09, 0x14, + 0x8b, 0xa9, 0xf8, 0xac, 0x56, 0xe2, 0xb6, 0x9e, 0x1d, 0xe6, 0x2b, 0xde, 0xb9, 0x0f, 0x15, 0xdf, + 0x08, 0xd9, 0x9e, 0xed, 0xf0, 0x62, 0x14, 0x8a, 0x37, 0x0a, 0xb5, 0xbb, 0x67, 0x03, 0xe0, 0xd9, + 0xa9, 0x41, 0xa8, 0x3e, 0xeb, 0x72, 0x19, 0xcf, 0xb9, 0xc3, 0x8d, 0xbb, 0x89, 0x03, 0xc8, 0x52, + 0x70, 0x2c, 0x39, 0xee, 0x75, 0x36, 0x3b, 0x05, 0xe2, 0x9a, 0x54, 0x93, 0x15, 0xc3, 0xe0, 0xe4, + 0x04, 0x00, 0x53, 0x39, 0x8a, 0xc2, 0xe3, 0xe3, 0xe3, 0xf1, 0x22, 0xe3, 0xd8, 0xff, 0x07, 0xf8, + 0xfc, 0x0e, 0xc3, 0x5c, 0xb8, 0x64, 0x02, 0x60, 0x14, 0xb3, 0x01, 0xeb, 0x0e, 0x70, 0xe7, 0x04, + 0x01, 0xc1, 0xe0, 0x59, 0x11, 0xdc, 0x25, 0x00, 0x07, 0xc4, 0xe0, 0x00, 0xe1, 0x7a, 0x87, 0x15, + 0xa9, 0xef, 0xcb, 0x16, 0x07, 0x62, 0x5b, 0xe1, 0x4c, 0x03, 0x17, 0xca, 0x75, 0x2e, 0xad, 0xb8, + 0xd3, 0x37, 0xad, 0x90, 0xb6, 0xdb, 0x89, 0x2a, 0xcf, 0xcb, 0x8c, 0xd8, 0x51, 0x40, 0x27, 0x31, + 0x59, 0xda, 0xcb, 0xfd, 0x78, 0xdf, 0x75, 0xe1, 0x85, 0x00, 0x23, 0x51, 0xec, 0x43, 0x55, 0xbf, + 0x9f, 0xa6, 0x2d, 0xc9, 0xed, 0xc6, 0x4d, 0x15, 0x65, 0x8b, 0xe4, 0x50, 0xe6, 0x00, 0x1d, 0xaf, + 0xe1, 0x39, 0xb9, 0x56, 0xfe, 0xf9, 0x34, 0xd5, 0xb6, 0xf2, 0xc7, 0x62, 0xba, 0xdb, 0xdb, 0x7c, + 0x65, 0x11, 0x7d, 0xf8, 0x76, 0x40, 0x01, 0xb7, 0xd1, 0x10, 0x02, 0x18, 0x5d, 0x27, 0x8a, 0xa4, + 0xce, 0x48, 0xe1, 0x9c, 0xb6, 0x2a, 0x89, 0x16, 0x18, 0x36, 0x8d, 0x87, 0xfd, 0xbc, 0xb1, 0xb8, + 0x81, 0xe5, 0x89, 0x31, 0x80, 0xe3, 0x96, 0x98, 0x12, 0x0a, 0x18, 0x11, 0xb6, 0xec, 0xb5, 0xfc, + 0xa5, 0x5a, 0xcd, 0xc1, 0x21, 0x17, 0x4f, 0x53, 0x71, 0x91, 0x0f, 0x2c, 0x1b, 0x4d, 0x1f, 0xb2, + 0xfc, 0x5f, 0xd4, 0x9c, 0x39, 0xde, 0xf7, 0x71, 0x10, 0x98, 0xf7, 0x77, 0x77, 0x77, 0x75, 0x83, + 0x02, 0x0c, 0x71, 0x03, 0xde, 0xe1, 0xe5, 0x00, 0x94, 0x73, 0x4d, 0xef, 0x93, 0xff, 0x1d, 0x5e, + 0xb9, 0xb6, 0xdf, 0xb6, 0x6e, 0x9a, 0x75, 0xb6, 0xbf, 0xb7, 0x87, 0x30, 0x00, 0xde, 0x89, 0xf4, + 0x28, 0xb3, 0xbd, 0xe9, 0xb3, 0xe9, 0xe9, 0x8a, 0xb1, 0x56, 0x0f, 0xfb, 0x2b, 0xdd, 0xb6, 0xf4, + 0xd3, 0xc0, 0xa2, 0x02, 0x84, 0x28, 0x52, 0x70, 0x55, 0xf8, 0x5a, 0xdd, 0x87, 0xb0, 0x38, 0x07, + 0x07, 0x9f, 0x2c, 0x00, 0x18, 0x3b, 0xf8, 0xc9, 0x95, 0x42, 0xf4, 0x20, 0xb2, 0xb9, 0x3f, 0x38, + 0xcf, 0x0c, 0x85, 0x27, 0xbf, 0x3c, 0x1f, 0x26, 0x17, 0x42, 0xb1, 0x41, 0x93, 0x80, 0xad, 0xed, + 0xb4, 0x0e, 0xf8, 0x24, 0x3c, 0xf0, 0x00, 0xe5, 0x61, 0x9c, 0x00, 0x42, 0x14, 0xc6, 0x2c, 0xfd, + 0x3d, 0x8b, 0xfb, 0x93, 0x2d, 0x9f, 0xa7, 0xf8, 0x9d, 0x36, 0x7c, 0xaa, 0xf8, 0xf3, 0x26, 0xf4, + 0xe7, 0xf3, 0xfb, 0xf0, 0x34, 0x01, 0xe4, 0x29, 0x03, 0x53, 0x0d, 0x64, 0x44, 0xe0, 0x02, 0xa5, + 0x59, 0x47, 0xbe, 0x55, 0x7e, 0x8e, 0xc3, 0xad, 0xaa, 0x43, 0xc9, 0xc0, 0x2b, 0x4c, 0x5a, 0xb7, + 0x1f, 0x42, 0x40, 0x00, 0x54, 0x3f, 0x06, 0xa0, 0x85, 0x02, 0xa4, 0x38, 0xa0, 0x0a, 0xca, 0x73, + 0x1b, 0x73, 0xc6, 0xbf, 0x6d, 0x97, 0xe6, 0xf5, 0x2e, 0xef, 0xe3, 0x4a, 0x9c, 0x6e, 0x76, 0xdb, + 0xd3, 0x4f, 0x88, 0x05, 0x50, 0x62, 0x5c, 0x0c, 0x72, 0x30, 0x00, 0xb0, 0x5e, 0xf7, 0x07, 0x84, + 0x44, 0x19, 0xc5, 0xf3, 0x55, 0xc5, 0xe0, 0x1b, 0x47, 0xe2, 0x88, 0x9c, 0x90, 0xaa, 0x1c, 0xcc, + 0x78, 0x47, 0x87, 0x9f, 0x8a, 0xdf, 0x93, 0x10, 0xc3, 0x68, 0xaa, 0xfc, 0x9d, 0xf9, 0xd8, 0x9b, + 0x4b, 0x88, 0x04, 0x75, 0xca, 0x4d, 0x5e, 0x5b, 0x17, 0x20, 0x8f, 0x8a, 0x3d, 0xde, 0xfb, 0xae, + 0x28, 0xd7, 0x77, 0xbd, 0xf1, 0x01, 0x91, 0xe2, 0x5f, 0x79, 0xf2, 0xfb, 0xde, 0x15, 0x50, 0x03, + 0x50, 0x6c, 0x97, 0x7a, 0xeb, 0xbb, 0xfa, 0x7b, 0x6d, 0xb6, 0xdb, 0x6d, 0xe2, 0x60, 0xa8, 0x93, + 0x55, 0x20, 0x51, 0x75, 0xe4, 0xde, 0x20, 0x49, 0x79, 0xa0, 0xd0, 0x1a, 0x74, 0x94, 0x06, 0x66, + 0xa4, 0xb5, 0x3a, 0x04, 0xf0, 0xd6, 0x00, 0x4d, 0xbe, 0xcf, 0x05, 0x38, 0x4c, 0x41, 0xbf, 0xe9, + 0xc6, 0x4e, 0x0f, 0xf8, 0xf2, 0xe7, 0x34, 0x2c, 0x39, 0x67, 0x86, 0x58, 0xb1, 0x73, 0x8c, 0xd0, + 0x97, 0x0f, 0x01, 0xd6, 0x57, 0xf1, 0xd4, 0x9c, 0x14, 0x84, 0x42, 0x92, 0x4d, 0x0a, 0x08, 0xb2, + 0x40, 0x00, 0x56, 0x41, 0x15, 0x01, 0x4d, 0x81, 0xa3, 0xe4, 0x81, 0x1f, 0x58, 0x77, 0x33, 0xb2, + 0xa1, 0xf7, 0x1d, 0x7d, 0x2d, 0xd1, 0x99, 0x64, 0xb2, 0xf8, 0xe7, 0x0c, 0x21, 0xa7, 0x28, 0xb6, + 0xc8, 0x78, 0xcf, 0x18, 0xac, 0x6a, 0x87, 0x9c, 0x09, 0x20, 0x78, 0x0a, 0x15, 0x42, 0x45, 0xdd, + 0xfe, 0xed, 0xdc, 0x56, 0xe2, 0xb1, 0x5b, 0xb8, 0xac, 0x57, 0x5f, 0x19, 0x7b, 0xbd, 0xdd, 0xdd, + 0xc5, 0x62, 0xbb, 0xbb, 0xe2, 0x66, 0xbb, 0xbf, 0x88, 0xf8, 0xbd, 0x62, 0xf8, 0x93, 0x82, 0x4e, + 0x1b, 0x88, 0x32, 0xaf, 0xb9, 0x89, 0xbf, 0x10, 0x12, 0xa1, 0xe6, 0x65, 0x37, 0x7f, 0x82, 0x6b, + 0xee, 0x0d, 0x6a, 0xf5, 0x19, 0x71, 0x80, 0x22, 0x88, 0x13, 0xc4, 0x89, 0x12, 0x77, 0xbe, 0xee, + 0xfe, 0x11, 0xbb, 0xbb, 0xde, 0xee, 0xee, 0xf8, 0x28, 0x8e, 0xbd, 0xdc, 0x5d, 0x3f, 0x0a, 0xab, + 0xe0, 0xa2, 0x3e, 0x28, 0xcf, 0xdf, 0xdd, 0xc5, 0x71, 0x47, 0x1d, 0x58, 0x61, 0x40, 0x21, 0xfe, + 0x39, 0x5d, 0x9e, 0xdd, 0x7a, 0x7d, 0xfd, 0xf8, 0x44, 0x40, 0x2c, 0xcb, 0x79, 0xb9, 0xb4, 0x53, + 0x2c, 0xea, 0xaa, 0x9f, 0x81, 0xc4, 0x1c, 0x08, 0x85, 0x0d, 0x2b, 0xcd, 0x2e, 0xce, 0x70, 0xe7, + 0x0b, 0x19, 0x6e, 0x1a, 0x73, 0x77, 0x0c, 0xef, 0xdb, 0xf4, 0xd6, 0xdf, 0xf7, 0x03, 0x48, 0x44, + 0x25, 0xdd, 0xb7, 0xbf, 0x03, 0xcc, 0x55, 0x4d, 0x95, 0x77, 0xf1, 0x11, 0x71, 0x5b, 0xbb, 0xee, + 0xf8, 0x20, 0x10, 0x0a, 0x4c, 0xe2, 0x4f, 0x93, 0x0b, 0x00, 0xcb, 0x03, 0x38, 0xe4, 0x8a, 0xed, + 0xec, 0x70, 0xc0, 0x80, 0x89, 0x1d, 0xdf, 0x71, 0x7b, 0xbb, 0xbf, 0x9b, 0x9b, 0x04, 0x87, 0x30, + 0x43, 0x05, 0x77, 0x79, 0xf9, 0xb2, 0xa3, 0xc0, 0xe0, 0xe8, 0x58, 0xd4, 0x74, 0x16, 0x01, 0xc6, + 0x09, 0x4a, 0xaf, 0x94, 0x4e, 0x3a, 0x2c, 0x27, 0x04, 0xff, 0xc4, 0x70, 0xc8, 0x40, 0x15, 0x16, + 0xdd, 0xde, 0xee, 0xe2, 0xb1, 0x46, 0xe2, 0xb7, 0xe0, 0xc4, 0x32, 0x3e, 0x28, 0xe2, 0x47, 0xf6, + 0x2b, 0x14, 0x77, 0x97, 0xc2, 0xae, 0x00, 0x66, 0x7a, 0x8c, 0xfd, 0xfd, 0xda, 0xd7, 0xfa, 0xeb, + 0xc3, 0x4a, 0x00, 0x90, 0x6b, 0xda, 0xae, 0x1b, 0x6f, 0x6d, 0xbd, 0x3b, 0x6f, 0xed, 0xe2, 0x02, + 0x11, 0x5f, 0x15, 0xc5, 0x75, 0x8b, 0xac, 0x2c, 0x48, 0x49, 0x45, 0x70, 0x69, 0xff, 0xff, 0x86, + 0x61, 0x0b, 0xbf, 0x48, 0x56, 0x20, 0x71, 0xc5, 0x67, 0x0e, 0x1c, 0x0e, 0x43, 0x0a, 0x02, 0x16, + 0xda, 0xaa, 0x5f, 0xe9, 0xa7, 0xff, 0xb8, 0x90, 0xc8, 0xec, 0xd8, 0xf1, 0x6f, 0x68, 0x56, 0xee, + 0x2b, 0xe0, 0x84, 0x26, 0x67, 0x7b, 0xbe, 0xfc, 0x32, 0x14, 0x30, 0x1b, 0xcb, 0x87, 0x20, 0x58, + 0xec, 0x76, 0x0e, 0x40, 0x58, 0x39, 0x01, 0x61, 0x66, 0x59, 0x8b, 0x96, 0x07, 0x26, 0x09, 0x00, + 0xe1, 0xe0, 0x70, 0x7a, 0xc3, 0x8e, 0x0e, 0xce, 0xb0, 0x62, 0x24, 0x29, 0x52, 0x60, 0x3a, 0x16, + 0x0e, 0x96, 0x0f, 0x58, 0x70, 0x1c, 0x76, 0xc4, 0x70, 0x00, 0x12, 0xc2, 0x60, 0x03, 0xe3, 0xb9, + 0x9d, 0xfe, 0x3b, 0xcc, 0x39, 0x80, 0x21, 0x94, 0x7e, 0x45, 0x07, 0x9f, 0xde, 0x2e, 0xd9, 0xeb, + 0x1c, 0x71, 0x57, 0x37, 0x4f, 0x6c, 0xfd, 0xcf, 0x79, 0x9a, 0xdb, 0x7f, 0xe2, 0x43, 0x23, 0xa7, + 0x00, 0x07, 0x96, 0x1b, 0x32, 0x21, 0x75, 0x59, 0xce, 0x58, 0xea, 0xca, 0x9f, 0x31, 0xdc, 0xb8, + 0x2b, 0x38, 0x07, 0x38, 0x90, 0x5a, 0x55, 0xbe, 0xe5, 0xcf, 0x28, 0x22, 0xc4, 0x71, 0x22, 0x48, + 0x21, 0x57, 0xf3, 0x5e, 0xff, 0x15, 0xbb, 0xbb, 0xdf, 0x0c, 0xb1, 0xa0, 0x13, 0xa7, 0x9e, 0x75, + 0xc2, 0x6e, 0x2a, 0xdb, 0xff, 0xf7, 0xc2, 0xca, 0x02, 0xa3, 0xc2, 0xf3, 0xef, 0x77, 0xbf, 0xf0, + 0x70, 0x18, 0x18, 0x68, 0xae, 0xe5, 0xc7, 0x2c, 0x62, 0x8d, 0xdb, 0x14, 0x6d, 0x88, 0x79, 0x60, + 0xe4, 0xf9, 0x0c, 0x60, 0x06, 0x32, 0x9f, 0x88, 0xac, 0xbe, 0xa4, 0xd3, 0xa6, 0x9d, 0x3b, 0x6d, + 0xfe, 0x9b, 0xf1, 0x00, 0xe4, 0x65, 0x6b, 0x7b, 0x8a, 0xd5, 0x5e, 0xef, 0x78, 0x5d, 0x14, 0x08, + 0xd6, 0x97, 0xbd, 0xe6, 0xf5, 0xfd, 0x35, 0x37, 0x27, 0xf7, 0xc2, 0xee, 0x02, 0x71, 0xb3, 0x46, + 0xde, 0xa6, 0xff, 0xfb, 0x7d, 0xb8, 0x14, 0x42, 0x22, 0x6f, 0xbd, 0xa4, 0xb0, 0xc4, 0xa0, 0x08, + 0x6f, 0x8d, 0x2c, 0xbd, 0x3d, 0xbb, 0x7f, 0xa6, 0x78, 0x91, 0x04, 0x32, 0xcf, 0x88, 0xf1, 0x12, + 0x62, 0xf1, 0x7e, 0x25, 0x8a, 0x2c, 0x31, 0x71, 0x72, 0x77, 0x13, 0xfb, 0x8a, 0x0c, 0x51, 0xb9, + 0xf0, 0x12, 0x62, 0x3c, 0x41, 0x37, 0xbc, 0x6b, 0x08, 0x80, 0x8b, 0x9b, 0x13, 0xf3, 0xb0, 0xd3, + 0x80, 0x55, 0xbc, 0x59, 0xe6, 0xf7, 0xbf, 0x2f, 0xba, 0xf6, 0x70, 0x88, 0x16, 0x02, 0x83, 0x0f, + 0xcb, 0x31, 0x59, 0x74, 0x0c, 0x4b, 0xe0, 0xe0, 0xb0, 0x1d, 0x63, 0x0e, 0xcd, 0x45, 0x76, 0xf1, + 0x3e, 0x2e, 0x80, 0x86, 0xa5, 0x10, 0x97, 0x10, 0xc0, 0xb0, 0x24, 0x29, 0xbc, 0xd4, 0xbd, 0x59, + 0xd0, 0xbd, 0x96, 0x21, 0xf1, 0x3c, 0x8b, 0xa6, 0x5c, 0x97, 0x12, 0x24, 0x28, 0x52, 0xd8, 0xac, + 0xb6, 0xe2, 0xb1, 0x58, 0xac, 0x57, 0x85, 0x40, 0x56, 0xee, 0xef, 0x7f, 0x88, 0x8a, 0x32, 0xc6, + 0x2b, 0x15, 0x8a, 0xdc, 0xf9, 0x56, 0x24, 0x48, 0xc3, 0x97, 0x89, 0x1c, 0x67, 0xdd, 0xf4, 0x84, + 0x38, 0xf6, 0x21, 0xc1, 0x0e, 0x3f, 0x1f, 0x98, 0x64, 0x22, 0x3e, 0xef, 0xb8, 0xaf, 0xbd, 0xf0, + 0xc0, 0x60, 0x4c, 0x56, 0xfb, 0xdc, 0xff, 0x13, 0x82, 0xce, 0x61, 0xdb, 0xbe, 0x22, 0x28, 0x6b, + 0xbb, 0xbb, 0xbb, 0xbc, 0x2a, 0x42, 0x80, 0x1f, 0x9a, 0xf4, 0x8e, 0xa9, 0xfe, 0xf7, 0xfc, 0x30, + 0x88, 0x00, 0x6a, 0xb4, 0x68, 0x39, 0x17, 0xf9, 0xff, 0x6e, 0x7e, 0x0e, 0xdf, 0x6e, 0xde, 0x20, + 0x28, 0x28, 0x48, 0x38, 0x3a, 0x0f, 0x0b, 0x98, 0x75, 0x00, 0x1a, 0x9e, 0x00, 0x02, 0x00, 0x30, + 0x2b, 0x6a, 0x54, 0x80, 0x01, 0xa8, 0xad, 0xb1, 0x5e, 0x32, 0xa1, 0x0e, 0xaa, 0x54, 0x86, 0xa6, + 0xf8, 0x6d, 0x8b, 0x01, 0x90, 0x73, 0x58, 0xda, 0xbf, 0x78, 0xf5, 0x8b, 0x3d, 0x62, 0xd6, 0xba, + 0x37, 0xa3, 0x7b, 0x76, 0xd1, 0x1e, 0xb5, 0xfe, 0x0e, 0x43, 0x24, 0xbb, 0xbb, 0xc3, 0x2c, 0xa0, + 0x20, 0x1e, 0x34, 0x06, 0x76, 0x7d, 0xbe, 0xf7, 0xfe, 0xc3, 0x18, 0x09, 0x46, 0xb8, 0x0d, 0xa5, + 0x3e, 0xa5, 0xff, 0xfe, 0xcf, 0x08, 0x89, 0x25, 0xef, 0xbb, 0x93, 0x8b, 0xc5, 0xe2, 0xe2, 0xf1, + 0x4d, 0x4b, 0xd9, 0x9d, 0xee, 0x09, 0x71, 0x21, 0x41, 0x6e, 0xee, 0xfb, 0xbb, 0xbc, 0x56, 0x2b, + 0x3e, 0x0a, 0xed, 0xf1, 0x38, 0x2e, 0xa3, 0xed, 0xf6, 0x3a, 0xee, 0xfc, 0x40, 0xc3, 0xbb, 0xed, + 0xef, 0xbd, 0xdd, 0xf8, 0x56, 0x70, 0x11, 0xa5, 0xec, 0xdb, 0xd0, 0x5f, 0xfe, 0xef, 0x9b, 0xe1, + 0x57, 0x01, 0x6f, 0x36, 0xea, 0xff, 0xfa, 0x6d, 0xf0, 0x88, 0x44, 0xc5, 0xb8, 0xac, 0x57, 0xe5, + 0xee, 0xf8, 0x9c, 0x9c, 0x86, 0x17, 0x14, 0xd4, 0x5f, 0xdc, 0x5e, 0x29, 0xa8, 0x29, 0x89, 0x13, + 0xc4, 0x04, 0x49, 0x7b, 0xbf, 0xbb, 0xdd, 0xf8, 0x87, 0xbd, 0xde, 0x10, 0x47, 0xff, 0x84, 0x0c, + 0x4c, 0x6b, 0xc9, 0x72, 0xcf, 0xbd, 0xee, 0x06, 0xde, 0x3e, 0xd2, 0xb7, 0xd3, 0x1d, 0x55, 0xd2, + 0x86, 0xf9, 0x89, 0xaa, 0xf9, 0x27, 0xc6, 0xd8, 0xe7, 0xe1, 0x4b, 0xdb, 0x43, 0x6e, 0xd1, 0x70, + 0xc9, 0x32, 0x3d, 0x34, 0x50, 0x6c, 0x6d, 0x45, 0xf1, 0x98, 0xd9, 0xb1, 0xe3, 0x84, 0xc9, 0x92, + 0x26, 0x39, 0xdb, 0x5a, 0x7f, 0x77, 0x74, 0xdf, 0xc7, 0xd0, 0xcd, 0x1d, 0xc9, 0xe5, 0xd3, 0xe6, + 0x87, 0x7c, 0x75, 0x92, 0xa6, 0xef, 0x43, 0xa2, 0xcd, 0xbe, 0x3f, 0xba, 0x95, 0x93, 0xb3, 0xec, + 0x92, 0x1a, 0xab, 0xca, 0x6e, 0x34, 0xbc, 0x59, 0x55, 0x0d, 0x7b, 0xbf, 0xb9, 0x3e, 0xd9, 0x39, + 0x26, 0x62, 0xc7, 0xf7, 0xda, 0x2f, 0x2f, 0x2d, 0x3d, 0xfc, 0xb6, 0x9a, 0x43, 0xf8, 0x9c, 0xab, + 0xed, 0xa4, 0xdf, 0xc2, 0x14, 0x34, 0x39, 0x19, 0x43, 0x6b, 0x19, 0xd9, 0x36, 0xfe, 0xb2, 0xf8, + 0x4e, 0x86, 0x86, 0xe6, 0xd5, 0x23, 0x69, 0xf8, 0x26, 0xdd, 0xb2, 0xfa, 0xf6, 0x31, 0xfa, 0xfb, + 0xe3, 0xf4, 0x37, 0x43, 0xd2, 0x2a, 0xd4, 0x32, 0xf9, 0xf2, 0xc9, 0xbf, 0xe2, 0xba, 0x63, 0xf7, + 0x5e, 0x3f, 0xc9, 0xa7, 0x4b, 0xc2, 0x34, 0xa9, 0x5a, 0x65, 0x7e, 0x7c, 0x5d, 0x5f, 0xe6, 0xa5, + 0x95, 0x95, 0xde, 0xdd, 0x2f, 0x11, 0x7b, 0xe5, 0x64, 0xd1, 0xfc, 0x5d, 0xee, 0x9a, 0xd3, 0xf9, + 0xb4, 0xdf, 0xe6, 0x9b, 0xed, 0x2e, 0x09, 0x6b, 0xb4, 0x9e, 0xed, 0x5c, 0x9b, 0x73, 0x31, 0xe5, + 0xbb, 0x6c, 0x68, 0x6b, 0x8b, 0xb2, 0x97, 0xc9, 0xe9, 0x7c, 0x9d, 0xd3, 0xf3, 0x59, 0x1b, 0x7f, + 0x37, 0x9b, 0xf9, 0x37, 0x63, 0xae, 0x27, 0x74, 0xa9, 0x21, 0xd0, 0xd7, 0x09, 0xf8, 0xc5, 0x24, + 0x7d, 0xb2, 0x71, 0x79, 0xa2, 0x87, 0x07, 0xcf, 0x2f, 0x24, 0xac, 0x6d, 0x79, 0xaf, 0xa7, 0xe0, + 0x87, 0x34, 0xac, 0xb2, 0xf8, 0x4e, 0x3a, 0x66, 0xed, 0xa5, 0xdb, 0x2b, 0x3b, 0xe6, 0x23, 0xe9, + 0x97, 0x8a, 0x3a, 0xc9, 0xec, 0x6f, 0xf8, 0x47, 0x76, 0xec, 0x65, 0x60, 0xcc, 0x41, 0xac, 0xc3, + 0x1f, 0xb5, 0xe1, 0x1b, 0xa6, 0xdd, 0x51, 0x4e, 0xca, 0x6d, 0xed, 0x78, 0x23, 0xd9, 0x0d, 0x18, + 0xdf, 0xe0, 0x96, 0xc6, 0xc6, 0xc6, 0xc6, 0xf6, 0xb8, 0x57, 0x17, 0x26, 0xef, 0xce, 0xc2, 0xe1, + 0x4e, 0xa3, 0x34, 0xe1, 0x0d, 0x5c, 0x37, 0xbd, 0x28, 0x39, 0x59, 0x97, 0xc2, 0x1f, 0x1a, 0x68, + 0x6d, 0xc1, 0xda, 0x4d, 0x6f, 0x8b, 0x31, 0xf2, 0xea, 0xc3, 0x3c, 0xa7, 0x6a, 0xe2, 0x8a, 0xdc, + 0x7d, 0xa6, 0xfe, 0x3f, 0x6c, 0x6e, 0x9b, 0x1c, 0x3f, 0x52, 0xbd, 0xb2, 0xb3, 0xf8, 0x28, 0xa7, + 0xbb, 0x19, 0xd8, 0xa2, 0x8a, 0xbb, 0xae, 0xd7, 0x84, 0xf9, 0xda, 0x91, 0x23, 0x6b, 0xe5, 0xbd, + 0x8f, 0xe3, 0xb4, 0xe9, 0x97, 0xbf, 0x4b, 0x6d, 0x77, 0xc8, 0xcb, 0x1b, 0xe0, 0xb6, 0xd6, 0x76, + 0xa6, 0xc6, 0xec, 0x6f, 0xf1, 0x11, 0xa3, 0xbe, 0x8e, 0xdd, 0x2f, 0xb2, 0x19, 0x8d, 0x53, 0xf1, + 0xe5, 0x63, 0xbf, 0x9b, 0x34, 0x92, 0xf0, 0x94, 0xdd, 0x3d, 0x4d, 0xad, 0xfe, 0x14, 0x92, 0x2f, + 0x2b, 0xe8, 0x8b, 0x2e, 0xd4, 0xec, 0xc5, 0xa4, 0x4f, 0xaf, 0x84, 0xf2, 0x40, 0x88, 0x25, 0x2b, + 0x68, 0xbc, 0x54, 0xad, 0xad, 0x15, 0xbb, 0xfc, 0x45, 0x13, 0x52, 0x25, 0x63, 0x6e, 0xb4, 0x3f, + 0x09, 0xec, 0x6f, 0xa1, 0xa6, 0x86, 0xbb, 0xa7, 0xb6, 0xfa, 0xcb, 0xe1, 0x3b, 0x72, 0x76, 0xdb, + 0x33, 0x3a, 0xe5, 0xdb, 0x6f, 0xe2, 0xed, 0xd0, 0xd8, 0xee, 0xff, 0x11, 0x63, 0x2b, 0x19, 0xff, + 0xf0, 0x8c, 0xfa, 0x7c, 0x5e, 0xed, 0xdb, 0x56, 0xfe, 0x5d, 0x36, 0x34, 0xd7, 0x2f, 0x76, 0xfc, + 0x12, 0xe9, 0x52, 0x4a, 0x4d, 0x6d, 0xbe, 0x6a, 0x52, 0xc3, 0xe2, 0xed, 0xe5, 0xf4, 0xd7, 0xeb, + 0x2f, 0xb9, 0xdb, 0xb7, 0xe0, 0xa3, 0x7b, 0x72, 0xca, 0xcb, 0xbe, 0xc9, 0x37, 0x6e, 0x92, 0xe0, + 0x98, 0xed, 0xb7, 0xd5, 0x12, 0x6f, 0xf0, 0x59, 0x63, 0xdd, 0x53, 0x91, 0xe3, 0x67, 0x6c, 0x7b, + 0x91, 0x6c, 0xf8, 0xbe, 0x7e, 0xad, 0x8e, 0x9c, 0x2d, 0x4b, 0xe2, 0x08, 0x7c, 0x43, 0xea, 0x9b, + 0xf8, 0x44, 0xbb, 0x6b, 0x93, 0x5b, 0xa6, 0x56, 0x7f, 0x09, 0x51, 0x5b, 0x23, 0x36, 0x33, 0x31, + 0xf9, 0x0c, 0xda, 0x6f, 0x7c, 0x61, 0x4a, 0xce, 0xdd, 0x8d, 0xce, 0xd4, 0x37, 0xba, 0x2a, 0x36, + 0x46, 0x7f, 0x82, 0x39, 0x59, 0xc1, 0xa6, 0x74, 0xf8, 0x2c, 0xbb, 0x69, 0xe5, 0x60, 0xfb, 0xe9, + 0x52, 0xcb, 0xe5, 0xb7, 0xa7, 0xe1, 0x1b, 0x25, 0x22, 0x19, 0x43, 0x72, 0x35, 0xbe, 0x15, 0x8d, + 0xf8, 0x21, 0xb6, 0x97, 0xff, 0x84, 0x2d, 0xb4, 0x87, 0x6e, 0xa9, 0xa5, 0x49, 0x3f, 0x04, 0x54, + 0xd3, 0x63, 0xf7, 0xd6, 0x2f, 0x8b, 0x21, 0xf5, 0x4d, 0x9e, 0xad, 0xae, 0x0a, 0x0a, 0x6d, 0xb5, + 0xa7, 0x6d, 0xcf, 0x96, 0x37, 0x5f, 0x52, 0x7e, 0x5e, 0x6c, 0xf8, 0xcd, 0x8c, 0xfe, 0x36, 0xf2, + 0x6b, 0x75, 0x6d, 0x36, 0xc1, 0x0f, 0xf1, 0xd6, 0x5a, 0xc7, 0x2a, 0xa2, 0x77, 0xf8, 0x8d, 0x2f, + 0xc2, 0x77, 0xa7, 0x49, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x35, 0x1a, 0xb0, 0x52, 0x37, + 0x15, 0x55, 0x55, 0x55, 0x55, 0x8d, 0x45, 0x02, 0xc3, 0xf1, 0xf9, 0xde, 0x0a, 0x60, 0xd6, 0x26, + 0x27, 0x55, 0x5a, 0xd4, 0xbc, 0xda, 0xa8, 0xbf, 0x0c, 0x0a, 0x20, 0x9f, 0x0a, 0x57, 0x69, 0xb7, + 0x6f, 0x88, 0x17, 0x51, 0x71, 0x1f, 0x24, 0xfd, 0xd6, 0x23, 0xe5, 0xe5, 0xc7, 0x06, 0x30, 0x40, + 0x20, 0x23, 0xe7, 0xf7, 0x77, 0xd5, 0x78, 0x81, 0x91, 0x72, 0x30, 0x71, 0xf3, 0x37, 0xa8, 0x8f, + 0x92, 0xf5, 0x6c, 0x5e, 0x2f, 0xc4, 0x09, 0x9d, 0xfc, 0xc5, 0xc9, 0xc5, 0x39, 0xc4, 0xc4, 0x5b, + 0x5d, 0x45, 0xeb, 0x89, 0x13, 0xc4, 0xc4, 0x5d, 0xf7, 0xdd, 0x42, 0x18, 0x2e, 0xe6, 0x2d, 0x62, + 0xf8, 0x60, 0x32, 0x38, 0x91, 0x27, 0xc7, 0xb0, 0x77, 0x97, 0x9d, 0xfe, 0x6b, 0xc3, 0x21, 0x0a, + 0xd6, 0x36, 0xbe, 0xb7, 0x6b, 0xee, 0x2e, 0xaa, 0xbc, 0x4c, 0xe7, 0x41, 0x16, 0xe2, 0xb8, 0x2a, + 0xe2, 0x82, 0x11, 0x27, 0xc4, 0xfe, 0x92, 0x78, 0x20, 0x08, 0x84, 0x7a, 0x8b, 0xac, 0x2c, 0x15, + 0xd4, 0x5d, 0xb5, 0xc4, 0x86, 0x05, 0xd6, 0x29, 0xb4, 0xa4, 0xe2, 0xe3, 0xef, 0x84, 0x04, 0x82, + 0x79, 0xf3, 0xf1, 0x0a, 0x4e, 0xe0, 0xc2, 0x6a, 0xaf, 0xe5, 0xac, 0x53, 0x55, 0x89, 0xe2, 0x44, + 0xf0, 0x42, 0x08, 0x42, 0x11, 0x5b, 0xda, 0x51, 0x77, 0x8b, 0xe0, 0xe8, 0xb3, 0x02, 0x00, 0x18, + 0x45, 0xd6, 0x7e, 0xc5, 0xac, 0x92, 0xe0, 0xe4, 0x40, 0xbc, 0xd8, 0x19, 0x07, 0xd7, 0xbb, 0xe1, + 0x00, 0x30, 0x96, 0xf7, 0x96, 0x23, 0xc4, 0x60, 0x93, 0xab, 0xb8, 0x80, 0xc0, 0xc9, 0x79, 0xb5, + 0xdb, 0xb2, 0x2f, 0x2b, 0x77, 0xe9, 0xb7, 0xc4, 0x0f, 0xad, 0x54, 0xde, 0x3f, 0x2f, 0x15, 0x96, + 0xf0, 0x40, 0x20, 0x65, 0x57, 0x5d, 0x54, 0xfe, 0x5b, 0x6f, 0x55, 0xe2, 0x4d, 0xbd, 0xf0, 0x40, + 0x10, 0x19, 0x76, 0xaa, 0xa2, 0xe2, 0x38, 0x48, 0x56, 0x5c, 0x8a, 0xce, 0x18, 0x16, 0xcb, 0x61, + 0x46, 0xe7, 0x08, 0x82, 0x3a, 0xa9, 0xce, 0x5b, 0xf8, 0x92, 0x75, 0x55, 0x07, 0x22, 0x09, 0x8c, + 0x7b, 0xc3, 0x0a, 0x20, 0x75, 0xb8, 0xd3, 0xf1, 0x57, 0xff, 0xb1, 0xe1, 0x80, 0x59, 0x9b, 0xa9, + 0xf8, 0x0b, 0xaa, 0x89, 0xe0, 0xca, 0x94, 0x43, 0xc8, 0x74, 0xb2, 0x5b, 0x88, 0x0c, 0x88, 0xca, + 0x6e, 0x33, 0x6e, 0xf9, 0x71, 0x3f, 0x25, 0xe9, 0xe1, 0x36, 0x77, 0xff, 0xc3, 0x83, 0xef, 0xc1, + 0x0f, 0x31, 0x97, 0x5f, 0x25, 0x57, 0xf2, 0x79, 0x7e, 0x18, 0x05, 0x23, 0xaa, 0x2e, 0x5e, 0x69, + 0xcf, 0x03, 0x64, 0x21, 0x1f, 0x85, 0x82, 0xbf, 0x84, 0x2e, 0xe2, 0xb1, 0x0e, 0x0e, 0xa9, 0x60, + 0xe4, 0xda, 0x7e, 0xa5, 0xb2, 0x66, 0x26, 0x3a, 0x2b, 0x7e, 0x2f, 0x55, 0xca, 0xe2, 0x02, 0x20, + 0xa6, 0xb5, 0xbb, 0xa6, 0xeb, 0x5f, 0x71, 0x11, 0xf5, 0xd3, 0x2a, 0x13, 0x98, 0x36, 0x4f, 0x82, + 0x44, 0xc0, 0xab, 0x44, 0xc0, 0x38, 0xe2, 0x01, 0x4c, 0xaa, 0x6a, 0x58, 0xc9, 0x15, 0x3d, 0xc7, + 0x7b, 0x72, 0xab, 0x5d, 0xb9, 0x73, 0xe6, 0x97, 0xcb, 0xf8, 0x8d, 0x62, 0x42, 0x57, 0x15, 0xcd, + 0x44, 0x92, 0xf1, 0x20, 0x81, 0xc7, 0xfc, 0xfb, 0x9d, 0x62, 0x73, 0xad, 0xf1, 0x55, 0xaa, 0x99, + 0x89, 0x17, 0x17, 0xe1, 0x01, 0x7c, 0xd8, 0x6c, 0xc4, 0xf0, 0xd0, 0xc4, 0x4b, 0x7d, 0xd7, 0x05, + 0x1e, 0x5c, 0x35, 0x12, 0x6e, 0x16, 0xd3, 0x2f, 0x17, 0x35, 0xa4, 0x7b, 0x8f, 0xc2, 0xe1, 0x72, + 0xa3, 0xf4, 0x0b, 0xf2, 0x6f, 0x73, 0x77, 0xbd, 0xfc, 0x9a, 0xd5, 0xe2, 0x06, 0x61, 0x88, 0x70, + 0x5c, 0xf7, 0x2a, 0x7c, 0xa7, 0x51, 0x0e, 0x37, 0x0b, 0x0c, 0x16, 0xb8, 0x88, 0x77, 0x84, 0x03, + 0x20, 0xb2, 0xef, 0xc1, 0x03, 0x85, 0xb1, 0xfe, 0x06, 0x01, 0xf8, 0xf0, 0x70, 0x98, 0x72, 0x0e, + 0xed, 0x5d, 0x87, 0x39, 0x11, 0x80, 0x77, 0x82, 0x91, 0x03, 0x36, 0x95, 0x9c, 0x47, 0x2b, 0x71, + 0x46, 0xf5, 0x8b, 0xe2, 0x23, 0x3b, 0xae, 0x23, 0x97, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x14, 0x3e, 0x10, 0x0a, 0x44, 0x64, 0x88, 0xab, 0x78, 0xfe, 0x0b, 0xa2, 0x3c, 0x5e, 0x58, 0x67, + 0x79, 0x79, 0xc7, 0xc8, 0x9f, 0x40, 0x54, 0x8a, 0x3f, 0x78, 0x89, 0xa2, 0x26, 0xee, 0x21, 0xcc, + 0x45, 0x5c, 0xf1, 0x20, 0x9f, 0xa9, 0x7d, 0x39, 0x21, 0xaa, 0x86, 0x20, 0x9f, 0xc6, 0x55, 0x4f, + 0xc1, 0x90, 0x7d, 0xaf, 0x78, 0x60, 0x64, 0x5c, 0x9a, 0xa5, 0x4b, 0x06, 0x5b, 0x3f, 0x12, 0xfe, + 0xc5, 0x67, 0x3d, 0xfe, 0xee, 0xa0, 0xa7, 0x84, 0x44, 0x04, 0xb5, 0x55, 0xcd, 0x9c, 0x20, 0x10, + 0x1f, 0x33, 0x01, 0x56, 0xe7, 0x7c, 0xb1, 0x5a, 0x97, 0xb7, 0x71, 0x10, 0xe7, 0x35, 0x2b, 0xf8, + 0xff, 0x7e, 0x08, 0x6e, 0x5b, 0x7b, 0x00, 0xe7, 0x04, 0x3a, 0xd7, 0xab, 0x90, 0xbb, 0xbb, 0xe0, + 0x9c, 0x9c, 0x90, 0x51, 0xd0, 0xb8, 0x38, 0x85, 0xca, 0x40, 0x94, 0x04, 0x45, 0x47, 0x10, 0x14, + 0x85, 0x00, 0x15, 0x1a, 0xe6, 0xa0, 0xeb, 0xcb, 0x6f, 0xbc, 0x5f, 0xe2, 0x78, 0x6e, 0x77, 0x0b, + 0x37, 0x61, 0x1e, 0xf0, 0x80, 0xcf, 0x62, 0xeb, 0x7b, 0xcf, 0x2e, 0x5c, 0x43, 0x97, 0xe1, 0x3e, + 0xef, 0x5a, 0xf0, 0x50, 0x10, 0xaa, 0xaa, 0xa8, 0xb8, 0xb8, 0xb9, 0x36, 0xb2, 0x9e, 0x20, 0x10, + 0x0f, 0xaa, 0xd4, 0x5c, 0x5d, 0x56, 0xe6, 0xc3, 0xfb, 0xe2, 0x64, 0xf2, 0xf6, 0x85, 0x0c, 0x5c, + 0xbc, 0x5c, 0xbc, 0x12, 0x66, 0xee, 0xa6, 0xb9, 0x7c, 0x95, 0x0e, 0x36, 0xb9, 0xe2, 0x1f, 0x93, + 0xfc, 0x12, 0xcd, 0xc6, 0x31, 0xf1, 0x3f, 0x11, 0xc6, 0xe2, 0x04, 0x02, 0x4e, 0xef, 0x1c, 0xf8, + 0x47, 0x2c, 0x62, 0x3c, 0xb7, 0x57, 0xcb, 0x37, 0xe1, 0x11, 0x23, 0x65, 0x5d, 0x51, 0x11, 0x91, + 0xd3, 0x08, 0x19, 0x48, 0x89, 0x1c, 0xc5, 0x2d, 0xa8, 0x73, 0xfe, 0xaa, 0x10, 0x55, 0x32, 0x61, + 0x60, 0x00, 0x49, 0xb0, 0x29, 0x6f, 0x92, 0x59, 0xe6, 0xc3, 0xc7, 0x0b, 0xdd, 0x84, 0x22, 0x23, + 0x5f, 0x4c, 0xfa, 0xfd, 0xc4, 0x08, 0x0a, 0x44, 0xa1, 0xa3, 0x98, 0x5c, 0xf0, 0x7b, 0x40, 0x08, + 0x60, 0x27, 0x64, 0x61, 0xe6, 0x1e, 0x0a, 0xde, 0x10, 0xac, 0xed, 0xee, 0xcf, 0x0d, 0x0f, 0x36, + 0x71, 0xcf, 0x96, 0x0d, 0x40, 0xd1, 0xc2, 0x50, 0xba, 0x0f, 0x2b, 0xd8, 0x07, 0x5f, 0x08, 0x42, + 0x9d, 0x53, 0x10, 0x3d, 0xec, 0xbf, 0x09, 0xb5, 0x16, 0x61, 0xc8, 0xdb, 0x41, 0xd7, 0x8a, 0x9a, + 0xc4, 0x3a, 0xf0, 0xf1, 0xc7, 0x3c, 0x40, 0x2d, 0xc9, 0xdb, 0x9c, 0x56, 0xf2, 0xe2, 0x44, 0x0c, + 0xe1, 0x57, 0xbc, 0xea, 0x3b, 0xb9, 0xf2, 0xcf, 0xcb, 0x76, 0x1f, 0x88, 0x12, 0x6e, 0xab, 0xe1, + 0x4b, 0xbd, 0xde, 0xfb, 0xde, 0x0b, 0x13, 0xe3, 0xf0, 0xec, 0x6b, 0x5c, 0x31, 0x0a, 0x43, 0xa0, + 0xfe, 0x33, 0x5c, 0x69, 0x25, 0xf2, 0xf6, 0x32, 0xb7, 0x82, 0xba, 0xec, 0xdd, 0x40, 0xeb, 0x4a, + 0x79, 0xe5, 0x81, 0xfb, 0x88, 0x10, 0x14, 0x8a, 0x65, 0xe2, 0x0f, 0x95, 0x2c, 0x0c, 0x5c, 0x48, + 0x1e, 0x71, 0xee, 0xc3, 0xbd, 0x99, 0x2c, 0xce, 0x3b, 0x9c, 0x22, 0x08, 0x02, 0x50, 0xd0, 0x0f, + 0x0d, 0x60, 0x0f, 0xad, 0xb2, 0x4e, 0x0d, 0x89, 0x78, 0x75, 0xc0, 0x3d, 0xdf, 0x18, 0x6d, 0xab, + 0xe5, 0x5e, 0xbf, 0x56, 0xd7, 0xfd, 0x9f, 0xeb, 0x82, 0x90, 0x2c, 0x82, 0xea, 0xaf, 0x69, 0x45, + 0xe8, 0xee, 0x19, 0x50, 0x05, 0xf3, 0x13, 0x79, 0x1b, 0x2f, 0x4d, 0x36, 0x7e, 0xef, 0xfe, 0x45, + 0x88, 0x08, 0xfc, 0xbd, 0x55, 0x88, 0x47, 0x3e, 0x43, 0x88, 0xc0, 0x01, 0x0b, 0xdd, 0xdc, 0xf9, + 0xfd, 0x18, 0x14, 0x8c, 0xff, 0xb1, 0xaf, 0x7f, 0xd5, 0xfc, 0x4f, 0x12, 0x24, 0x7d, 0xef, 0x7d, + 0x47, 0x17, 0x8b, 0x84, 0x20, 0x87, 0x55, 0xbf, 0xc1, 0x3e, 0xf1, 0x5d, 0xee, 0xfc, 0x21, 0xe2, + 0x04, 0x8e, 0x9f, 0xc8, 0x96, 0x11, 0x2c, 0xef, 0x3f, 0xf8, 0x22, 0xcb, 0x59, 0x31, 0xce, 0x10, + 0x10, 0x33, 0x53, 0x5c, 0xf0, 0x26, 0x44, 0xd8, 0x54, 0xd5, 0x60, 0xc6, 0xa2, 0xc1, 0xe1, 0x00, + 0x80, 0x29, 0xce, 0xd8, 0xe5, 0x85, 0xc5, 0x84, 0xf1, 0x65, 0x04, 0xfc, 0x88, 0x6a, 0x8c, 0x38, + 0x81, 0x33, 0xff, 0x51, 0x1e, 0xa5, 0x98, 0x7b, 0x10, 0x3e, 0xe7, 0xcd, 0xf8, 0xfc, 0xf9, 0x35, + 0x44, 0x09, 0x0a, 0x45, 0x6f, 0xe0, 0x76, 0x4b, 0x72, 0x0f, 0xb5, 0xcb, 0x18, 0x3b, 0x42, 0x50, + 0xb6, 0x2a, 0x95, 0x66, 0x2b, 0x15, 0xf9, 0x2f, 0x12, 0x11, 0x0a, 0x4b, 0x19, 0x6d, 0xef, 0x3e, + 0x4f, 0xe2, 0x8c, 0x43, 0x99, 0x75, 0x47, 0xc7, 0x7c, 0x22, 0x0b, 0x62, 0xe1, 0x50, 0xaa, 0xcd, + 0x56, 0x36, 0xbe, 0x24, 0x18, 0x05, 0x39, 0x77, 0x14, 0x31, 0x01, 0xea, 0xcc, 0xe7, 0xd8, 0x87, + 0x01, 0x83, 0x78, 0xb0, 0x50, 0xf8, 0xee, 0x1d, 0xc0, 0x08, 0x29, 0x5e, 0xb1, 0xd5, 0xf8, 0x9f, + 0xfe, 0xe2, 0x8b, 0x07, 0x7f, 0x7b, 0xaf, 0xf6, 0xf0, 0x38, 0x01, 0x44, 0x29, 0x3e, 0x1f, 0x31, + 0x58, 0x97, 0x23, 0xca, 0xf0, 0x71, 0x2c, 0x15, 0x46, 0xc3, 0xc3, 0xe5, 0x66, 0xe3, 0x9c, 0x10, + 0x01, 0x24, 0x29, 0x3e, 0x0a, 0x32, 0x62, 0xbb, 0x69, 0xcb, 0xc9, 0x80, 0x02, 0xa4, 0xc5, 0x4a, + 0x57, 0x90, 0x23, 0xdc, 0xb0, 0x62, 0x80, 0xca, 0x33, 0xc0, 0x82, 0x14, 0x8a, 0xdc, 0xb6, 0xf7, + 0x57, 0x58, 0x87, 0x05, 0x6b, 0x6c, 0x5f, 0x25, 0x58, 0x44, 0x18, 0x8d, 0x8a, 0x30, 0x76, 0xef, + 0x8a, 0xc4, 0x38, 0x28, 0x32, 0xc0, 0x69, 0xb8, 0xbc, 0x37, 0xe1, 0xd5, 0x87, 0xf9, 0x60, 0x61, + 0xab, 0x83, 0x85, 0xd2, 0x93, 0x4d, 0xbe, 0x5d, 0x4a, 0x1c, 0x50, 0x0e, 0xf7, 0xd6, 0xff, 0xed, + 0xb7, 0xf8, 0xd5, 0x15, 0x67, 0xd3, 0xee, 0x9a, 0x70, 0xe2, 0x80, 0x10, 0x82, 0x1a, 0xd6, 0x21, + 0xd4, 0x86, 0xed, 0x7f, 0xdb, 0x84, 0x82, 0xf0, 0x6d, 0xb1, 0x60, 0x6d, 0xc2, 0xf9, 0x7c, 0x0c, + 0xe9, 0x34, 0xf4, 0xf8, 0xab, 0x87, 0x14, 0x00, 0x6c, 0xc0, 0xb2, 0x29, 0xc7, 0xa5, 0x6d, 0xf7, + 0x6f, 0xc5, 0x58, 0xa2, 0xd9, 0xa8, 0x4d, 0xd2, 0xa9, 0x8a, 0x14, 0x36, 0x69, 0xe1, 0xaa, 0x36, + 0xdb, 0xd9, 0x83, 0xef, 0x88, 0xfc, 0x13, 0xdd, 0xde, 0xee, 0x9b, 0xe5, 0xe2, 0x3c, 0x4b, 0xae, + 0xb8, 0x8f, 0x84, 0x01, 0x64, 0x53, 0x51, 0x07, 0x25, 0x69, 0xcb, 0x19, 0x37, 0xfb, 0xc3, 0x03, + 0x25, 0xe5, 0xe2, 0x3f, 0x14, 0x73, 0xe3, 0x9f, 0xf5, 0x0a, 0x4c, 0x3b, 0xdb, 0xe2, 0x64, 0xaa, + 0xaf, 0x10, 0x24, 0x23, 0x88, 0x58, 0x8a, 0xc4, 0xd8, 0x8b, 0x93, 0xb8, 0x87, 0x30, 0x85, 0xd2, + 0xe2, 0x06, 0xc0, 0xc6, 0xa3, 0x2b, 0xc9, 0xa2, 0xc0, 0xb9, 0xd2, 0x92, 0x23, 0x13, 0x74, 0x0b, + 0xa9, 0x74, 0xf8, 0x25, 0xa0, 0x05, 0xe9, 0x31, 0xd7, 0xa2, 0x52, 0xaf, 0x07, 0x1e, 0xf9, 0x5c, + 0x08, 0x98, 0x10, 0x1a, 0x97, 0x0c, 0x86, 0x49, 0x4c, 0xb4, 0x23, 0x8f, 0xd5, 0xd5, 0xf1, 0x02, + 0x44, 0xf9, 0xef, 0xcd, 0x9d, 0xb0, 0xd7, 0x26, 0xb5, 0x27, 0x37, 0x77, 0xf1, 0x7d, 0xde, 0xee, + 0xf8, 0x44, 0x48, 0xc9, 0xfe, 0x39, 0x51, 0xbb, 0x23, 0x3d, 0x67, 0x4e, 0xa2, 0x79, 0x0a, 0x95, + 0xe2, 0x42, 0x79, 0x69, 0xbb, 0xdf, 0x89, 0x0a, 0x40, 0xee, 0x94, 0x63, 0x43, 0x28, 0x81, 0x2d, + 0xc0, 0x00, 0x24, 0x37, 0x60, 0x9e, 0x24, 0x08, 0xcb, 0x28, 0xf3, 0xe3, 0xac, 0x19, 0xd5, 0x20, + 0x2a, 0x14, 0x41, 0xe4, 0xe4, 0x07, 0x18, 0xff, 0xc3, 0x21, 0x01, 0x90, 0xf0, 0x04, 0x64, 0xe0, + 0x1e, 0x0e, 0x6d, 0x4b, 0xa3, 0x80, 0x38, 0x48, 0x15, 0x66, 0x17, 0x8e, 0x3e, 0x0e, 0xf8, 0x4c, + 0x92, 0xdb, 0x77, 0xc0, 0x80, 0x06, 0x9e, 0x24, 0x18, 0x0a, 0xaf, 0x17, 0x51, 0x7a, 0x58, 0x1a, + 0x41, 0x48, 0xf9, 0x6e, 0xea, 0x7c, 0xbf, 0x78, 0xaf, 0x05, 0x20, 0xe4, 0x29, 0x1d, 0x78, 0x7b, + 0x97, 0xea, 0x2e, 0xf1, 0x5d, 0x45, 0x0e, 0xb2, 0xc2, 0x8a, 0x00, 0xa0, 0xd2, 0xe3, 0x9b, 0xcd, + 0xb6, 0xdb, 0x75, 0xdb, 0x6d, 0x34, 0xff, 0xc1, 0x00, 0x16, 0x42, 0x9c, 0xd9, 0xa6, 0xa2, 0xea, + 0xae, 0xe4, 0xc2, 0xfb, 0xf7, 0x0c, 0x86, 0x41, 0x54, 0x0a, 0xba, 0xc2, 0xe1, 0x1b, 0x79, 0x63, + 0xfc, 0xfd, 0x6d, 0xdb, 0x17, 0xa2, 0x06, 0x10, 0x82, 0x68, 0x70, 0x00, 0x08, 0x73, 0x82, 0xa3, + 0xc5, 0xf2, 0x84, 0xa9, 0xa9, 0xcb, 0x41, 0x13, 0x13, 0xae, 0x5c, 0xf0, 0xd4, 0x4d, 0xdf, 0x7e, + 0x24, 0x64, 0xbe, 0x21, 0xe9, 0x8d, 0xd3, 0x28, 0x87, 0x4c, 0x4f, 0x09, 0xa7, 0x11, 0x07, 0x05, + 0x26, 0xa2, 0xbb, 0xd1, 0xe9, 0x22, 0x7d, 0x38, 0x92, 0x6f, 0x7e, 0x20, 0x23, 0x54, 0xf7, 0x15, + 0xc5, 0x6f, 0x15, 0xf8, 0x90, 0x9c, 0x9f, 0xcd, 0xeb, 0xc2, 0x32, 0x59, 0x13, 0xd8, 0xfc, 0x43, + 0xcd, 0x61, 0xec, 0x4f, 0x88, 0x1f, 0xbd, 0xee, 0xfb, 0xbb, 0xf1, 0x1e, 0x23, 0x84, 0x61, 0x39, + 0x79, 0xe3, 0xcb, 0xeb, 0xbd, 0xf8, 0x29, 0x09, 0xdd, 0xf9, 0xbd, 0x70, 0x88, 0x14, 0x42, 0x75, + 0x7b, 0xad, 0x3f, 0x90, 0x4b, 0xdf, 0x81, 0x60, 0x14, 0xe1, 0x84, 0x20, 0x11, 0x6e, 0x4b, 0x7f, + 0xff, 0x6d, 0xcf, 0x05, 0x2f, 0xaa, 0xc4, 0x22, 0x80, 0xdd, 0x07, 0x87, 0x03, 0xc8, 0x50, 0x82, + 0xb7, 0x79, 0xf6, 0x35, 0x06, 0x4f, 0x85, 0x77, 0x37, 0x55, 0xaa, 0x59, 0x9d, 0xef, 0xc1, 0x00, + 0x0b, 0x90, 0xa4, 0xe0, 0x78, 0xa0, 0xcb, 0x18, 0xa3, 0x14, 0x62, 0x8c, 0x56, 0xe5, 0x5b, 0x2a, + 0x8a, 0xc0, 0x94, 0xf3, 0x8d, 0x4b, 0xcd, 0x83, 0xba, 0x48, 0x9d, 0x44, 0x04, 0x41, 0x67, 0x9b, + 0xa8, 0xe2, 0xe9, 0xc0, 0x02, 0xa5, 0xda, 0x2e, 0x64, 0x2f, 0x12, 0x14, 0x88, 0xfc, 0x37, 0xa1, + 0xd4, 0xb4, 0x66, 0x35, 0x50, 0x58, 0xf9, 0x20, 0x47, 0xfc, 0x81, 0xe1, 0x4a, 0x6f, 0x71, 0x5d, + 0xfd, 0x5e, 0xe0, 0xdb, 0xc8, 0x7b, 0xc7, 0x38, 0x81, 0x21, 0x39, 0x33, 0xe4, 0xa1, 0xb3, 0xcb, + 0xdd, 0xfc, 0xd7, 0x76, 0x85, 0x57, 0x10, 0x09, 0xef, 0x7d, 0xd1, 0xbb, 0x9f, 0x04, 0x73, 0x64, + 0xa7, 0xce, 0x5a, 0x19, 0x89, 0xcb, 0xf8, 0x88, 0xfa, 0xd7, 0x7b, 0xdd, 0x7c, 0x14, 0x98, 0xaf, + 0x77, 0xe0, 0x22, 0x42, 0x84, 0x1f, 0xcf, 0x8e, 0xbb, 0xbc, 0x56, 0x15, 0x55, 0x31, 0x47, 0xbb, + 0xf1, 0x01, 0x9f, 0x11, 0x41, 0x4c, 0x0b, 0xb7, 0x02, 0xbe, 0xeb, 0xff, 0xf0, 0xc8, 0x21, 0x3a, + 0xad, 0x7d, 0x8a, 0x50, 0x0d, 0xdd, 0x3b, 0xb1, 0x02, 0x42, 0x86, 0x7d, 0xeb, 0x5d, 0x37, 0xbb, + 0xac, 0xb8, 0x5c, 0x7c, 0x36, 0xe0, 0x18, 0x4f, 0xa2, 0xa0, 0x10, 0x87, 0xfd, 0xe3, 0xe3, 0x2f, + 0x81, 0x2f, 0x04, 0xf1, 0xcb, 0x89, 0x60, 0x59, 0x93, 0x38, 0x28, 0xae, 0xeb, 0x6e, 0x40, 0xea, + 0x22, 0x42, 0xbd, 0xbe, 0x26, 0x5b, 0xde, 0xf9, 0x23, 0xe6, 0x3f, 0xe1, 0x08, 0xc6, 0x5e, 0x94, + 0x75, 0x7b, 0xfb, 0x89, 0xe1, 0xfc, 0xc2, 0x32, 0xdb, 0x97, 0xaa, 0x84, 0x44, 0x78, 0x91, 0x12, + 0x61, 0x33, 0x99, 0xfe, 0xb1, 0x20, 0xaa, 0x4c, 0x26, 0x67, 0x71, 0x90, 0xaa, 0xaf, 0x93, 0xaf, + 0x71, 0xdb, 0x78, 0xe1, 0xe8, 0x8f, 0xcd, 0xbc, 0xbf, 0x08, 0x06, 0x02, 0x57, 0x15, 0xef, 0x2d, + 0x8a, 0xe1, 0xa5, 0x00, 0x03, 0xa7, 0xce, 0x58, 0x0b, 0xbf, 0xef, 0x74, 0xd3, 0x64, 0x6e, 0x5f, + 0xaa, 0x6b, 0xde, 0xe3, 0x69, 0xc3, 0x30, 0xa4, 0x51, 0x8a, 0xdc, 0x55, 0xb4, 0xa2, 0x40, 0xe1, + 0x30, 0x55, 0x33, 0x75, 0x2f, 0x3c, 0x0f, 0x2c, 0x03, 0x2c, 0x31, 0x40, 0xc6, 0x31, 0xbe, 0x19, + 0x04, 0x20, 0xae, 0x9c, 0xef, 0x9c, 0x1e, 0x99, 0x60, 0x62, 0x3d, 0xdf, 0xe9, 0x38, 0x64, 0x14, + 0x9b, 0x77, 0x7c, 0x18, 0x04, 0x68, 0x2b, 0x81, 0x31, 0x7d, 0x17, 0xff, 0xed, 0xb7, 0x84, 0x42, + 0x21, 0x3b, 0xbb, 0xf8, 0xf2, 0xe1, 0x00, 0x10, 0x23, 0x77, 0x62, 0xb7, 0xbd, 0xdf, 0x8c, 0xd4, + 0x6c, 0x8c, 0xb0, 0xc5, 0xb6, 0xfe, 0xd9, 0xb9, 0x62, 0x02, 0x00, 0x9e, 0x4c, 0x2c, 0xd4, 0x49, + 0xe3, 0x74, 0x2c, 0xc9, 0x55, 0x43, 0x1c, 0xbe, 0xe2, 0x0f, 0xd9, 0xe7, 0xe2, 0x25, 0x6e, 0xf4, + 0x9d, 0xc1, 0x07, 0x09, 0x5c, 0x57, 0x77, 0x6d, 0xfc, 0x09, 0x25, 0xaa, 0xa4, 0x96, 0x0c, 0x41, + 0x48, 0x52, 0xa1, 0x5a, 0xeb, 0x3b, 0x9e, 0xe2, 0x07, 0x2b, 0x12, 0x38, 0x70, 0x38, 0x2e, 0x5e, + 0xdd, 0x2f, 0x97, 0x0c, 0x88, 0x17, 0x7d, 0xd7, 0x5c, 0x08, 0x02, 0x3e, 0x5d, 0x35, 0xe1, 0x89, + 0x2e, 0xfe, 0x0c, 0x04, 0xf1, 0x20, 0x80, 0x23, 0x7e, 0xbc, 0xb8, 0x3b, 0x90, 0x7e, 0xf0, 0x1f, + 0x9e, 0x46, 0xd6, 0x96, 0x0c, 0x01, 0x48, 0x52, 0x1f, 0xac, 0x70, 0x0d, 0x45, 0xe7, 0x8e, 0x37, + 0x4d, 0x64, 0x93, 0xf5, 0xf0, 0x0b, 0x05, 0xff, 0x13, 0xe1, 0xd8, 0x0a, 0x80, 0xd4, 0x4a, 0x36, + 0x16, 0xc0, 0x12, 0x05, 0x0e, 0x00, 0x04, 0x27, 0xe6, 0xb6, 0xf4, 0xcd, 0x10, 0x24, 0x23, 0x58, + 0xbb, 0xd4, 0x0e, 0xd2, 0xd8, 0x93, 0x81, 0xd9, 0x2b, 0x2d, 0xcc, 0x07, 0x62, 0x6e, 0xf7, 0xe2, + 0x2e, 0x2f, 0x55, 0xc4, 0x6b, 0x02, 0x40, 0x2a, 0xb8, 0x58, 0x55, 0xf3, 0x80, 0x07, 0x8a, 0x00, + 0x0c, 0x0e, 0xcd, 0x47, 0x43, 0xcd, 0xef, 0x4e, 0xb0, 0x70, 0x06, 0x00, 0xa6, 0x7d, 0x27, 0x10, + 0xe5, 0xc2, 0xa2, 0xb6, 0x58, 0x0c, 0x57, 0xba, 0x46, 0x02, 0x86, 0x18, 0x02, 0x40, 0xf8, 0xac, + 0x56, 0x7c, 0xa8, 0xfc, 0xee, 0x55, 0x22, 0xe2, 0x39, 0xe1, 0x00, 0x24, 0x05, 0x2a, 0xb4, 0xab, + 0x55, 0x2f, 0x13, 0xc8, 0xc5, 0x6e, 0x28, 0xcf, 0xdf, 0x0a, 0x60, 0x10, 0x1b, 0x35, 0x9a, 0xe7, + 0xc6, 0xb1, 0xeb, 0x6f, 0x4d, 0x37, 0x7d, 0x34, 0xd3, 0xc2, 0x98, 0x08, 0xd6, 0x59, 0x7b, 0x77, + 0xfe, 0xe4, 0xfd, 0xf8, 0x40, 0x65, 0x54, 0x98, 0xcc, 0x5c, 0x43, 0x2a, 0x6c, 0x1d, 0x59, 0xa4, + 0xec, 0x76, 0x33, 0x19, 0x9c, 0x10, 0x0c, 0xae, 0x70, 0xe0, 0xa3, 0x3f, 0x21, 0x7a, 0x86, 0xa7, + 0xb9, 0xd5, 0x55, 0x98, 0x4d, 0xc4, 0x38, 0x20, 0x73, 0x12, 0x04, 0x81, 0x12, 0x6f, 0x1c, 0xfc, + 0xf8, 0x55, 0x78, 0xfe, 0x7e, 0x2a, 0xca, 0xc6, 0xdc, 0xd1, 0xfc, 0x29, 0x7a, 0x7c, 0x38, 0x8c, + 0x7b, 0xcc, 0xf8, 0xfb, 0xf3, 0x35, 0x07, 0x28, 0xc7, 0xc1, 0x46, 0x5c, 0xcd, 0x49, 0xf9, 0xd2, + 0xdb, 0x49, 0xc5, 0x4d, 0xcb, 0xd6, 0xb5, 0x87, 0xbc, 0x91, 0x20, 0xe0, 0x92, 0x63, 0x33, 0xc1, + 0x48, 0x20, 0x36, 0xed, 0x1b, 0x31, 0x11, 0xf8, 0xad, 0xbb, 0x9e, 0xf6, 0xac, 0xb8, 0xec, 0x6a, + 0xbc, 0x20, 0x11, 0x19, 0xb3, 0xe0, 0xa3, 0x6e, 0x3f, 0x38, 0x50, 0x56, 0xcb, 0x01, 0xc5, 0x50, + 0x80, 0x68, 0x4e, 0x0a, 0x96, 0xaa, 0xb0, 0x41, 0x0a, 0x5a, 0xb6, 0xe5, 0x8a, 0xcf, 0xdd, 0x4a, + 0xf5, 0x03, 0x68, 0x78, 0x05, 0x15, 0x3c, 0x70, 0xb4, 0xfe, 0xfc, 0x22, 0x04, 0x81, 0x13, 0xe4, + 0xf6, 0x61, 0xdc, 0xaf, 0x10, 0xe7, 0x71, 0x99, 0xd4, 0x21, 0x71, 0x75, 0xf0, 0x80, 0x81, 0x7a, + 0xaa, 0xe2, 0xea, 0x6e, 0x4e, 0x6b, 0xc4, 0x04, 0xa9, 0xa6, 0xee, 0xfa, 0x7e, 0x08, 0xe6, 0xca, + 0x3b, 0x10, 0x4d, 0x10, 0x0c, 0x19, 0x5d, 0xfc, 0x48, 0x30, 0x24, 0x98, 0x59, 0xf8, 0x80, 0x70, + 0x38, 0x86, 0xcd, 0x71, 0x0f, 0xd6, 0xbc, 0x22, 0x10, 0xf1, 0x32, 0x42, 0x02, 0x01, 0x2e, 0x2f, + 0x51, 0x43, 0x14, 0x31, 0x4c, 0x47, 0x0e, 0x9f, 0x08, 0x45, 0xfd, 0x6b, 0xbd, 0xf0, 0xc8, 0x90, + 0x51, 0xd2, 0x10, 0xe5, 0x41, 0xc9, 0xe0, 0xe4, 0x78, 0xc7, 0x0c, 0x84, 0x45, 0xc4, 0x71, 0x47, + 0x23, 0xc1, 0xe3, 0xc5, 0xdc, 0x13, 0xf2, 0x77, 0x75, 0x11, 0x15, 0xbd, 0xee, 0xbf, 0x65, 0x77, + 0xf0, 0x43, 0x25, 0xf7, 0x70, 0xc8, 0x46, 0xa1, 0x98, 0xbe, 0xef, 0x7b, 0x92, 0x18, 0x05, 0x04, + 0x23, 0x85, 0x85, 0x6d, 0xf8, 0x1e, 0x01, 0xc0, 0xe9, 0xe7, 0x1b, 0xce, 0xfe, 0xee, 0xea, 0xae, + 0xf8, 0x18, 0x00, 0x80, 0x14, 0xe2, 0xf5, 0x12, 0x07, 0x8a, 0x00, 0x19, 0xc7, 0x0f, 0x00, 0xf3, + 0x66, 0x24, 0x3c, 0x40, 0x1f, 0x13, 0xe2, 0x4e, 0x13, 0x81, 0x51, 0xd8, 0xd8, 0xe1, 0x80, 0x70, + 0x14, 0x88, 0x00, 0xf2, 0x73, 0x80, 0x3d, 0x9e, 0xf7, 0x3b, 0x98, 0x76, 0x12, 0x97, 0xe2, 0x43, + 0x80, 0xe9, 0x66, 0x95, 0x3e, 0x6e, 0xe2, 0xbf, 0x2f, 0x0a, 0xab, 0x82, 0x3e, 0x5d, 0xef, 0x89, + 0xbb, 0xbb, 0xdf, 0x31, 0xf7, 0x78, 0x4e, 0x40, 0x16, 0xe5, 0x6f, 0x8f, 0xad, 0x7e, 0xbe, 0x24, + 0x47, 0xc9, 0x7b, 0xbb, 0x84, 0x72, 0x40, 0xa0, 0x04, 0x10, 0xa4, 0x56, 0x70, 0xe2, 0xbf, 0x1b, + 0x81, 0xec, 0x94, 0xb1, 0x9e, 0xf1, 0x72, 0x73, 0xe1, 0x72, 0xce, 0xac, 0x48, 0x70, 0x71, 0x4b, + 0x86, 0x19, 0x85, 0x23, 0xc1, 0x73, 0xbc, 0xa4, 0x12, 0x9d, 0xc9, 0x9e, 0x48, 0x15, 0x88, 0xef, + 0xb7, 0xbd, 0x17, 0xa7, 0x04, 0x21, 0x91, 0x57, 0x7b, 0xbb, 0xf0, 0xe2, 0x88, 0xed, 0xc9, 0x5d, + 0x5b, 0x74, 0xc4, 0xfb, 0x7a, 0xb6, 0xdd, 0x3b, 0x78, 0xa9, 0x82, 0x87, 0x07, 0x6f, 0xdb, 0xc1, + 0x1e, 0x22, 0xb8, 0xbb, 0xef, 0x77, 0x76, 0x25, 0xc1, 0xa3, 0x32, 0x85, 0xb0, 0xba, 0x65, 0xff, + 0xd7, 0xf8, 0x97, 0x77, 0xf1, 0x02, 0x5d, 0xef, 0xe2, 0x45, 0x95, 0xdd, 0xee, 0xf9, 0x43, 0xd3, + 0x00, 0xad, 0x26, 0x9c, 0xfe, 0xe5, 0xe5, 0xff, 0xf6, 0xd7, 0xaf, 0xe2, 0x60, 0x9a, 0xcf, 0x88, + 0xf8, 0x80, 0xf9, 0xc0, 0x1e, 0x23, 0xd2, 0x41, 0x44, 0x4d, 0xd6, 0xb2, 0x86, 0x14, 0x02, 0x10, + 0x4b, 0x78, 0x5f, 0x96, 0xfd, 0x77, 0xfd, 0xbe, 0x52, 0xbc, 0xff, 0x10, 0xe1, 0x5b, 0x61, 0x82, + 0xec, 0x80, 0x04, 0x95, 0xdb, 0x41, 0xa2, 0x3d, 0xdb, 0x77, 0xf7, 0x77, 0x2f, 0x2c, 0xd8, 0x6b, + 0x00, 0x42, 0xe6, 0xa9, 0x0d, 0xcc, 0x0c, 0xea, 0xdd, 0xe6, 0xf9, 0xbe, 0xa2, 0xda, 0x7f, 0xcc, + 0x41, 0x67, 0x35, 0xf7, 0xc4, 0x06, 0x19, 0x5e, 0xfe, 0x26, 0x7e, 0x42, 0x29, 0x7f, 0xee, 0x2e, + 0x2f, 0x82, 0xfe, 0xc4, 0xde, 0xe0, 0x13, 0x08, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x36, 0x1b, + 0x30, 0x52, 0x1b, 0xc5, 0x55, 0x55, 0x55, 0x55, 0x7c, 0x4d, 0x6b, 0xd5, 0x41, 0xa6, 0x18, 0x26, + 0xab, 0xc3, 0x01, 0x81, 0x95, 0x17, 0x8b, 0x85, 0x6a, 0x48, 0x57, 0xbd, 0xb7, 0x9b, 0xc4, 0x9f, + 0x83, 0x01, 0x02, 0x65, 0x9e, 0x5e, 0x27, 0xe6, 0x2a, 0xe2, 0xf7, 0xbb, 0xdd, 0xc1, 0x5e, 0x19, + 0x21, 0x6f, 0x7e, 0x11, 0x77, 0xbc, 0xbc, 0xd5, 0x55, 0x14, 0xf0, 0x84, 0x61, 0x2e, 0xa1, 0x46, + 0x9b, 0xba, 0x89, 0xe1, 0x76, 0x79, 0xec, 0xe3, 0xb7, 0x2f, 0x3f, 0xcb, 0xe1, 0x97, 0x00, 0x32, + 0xd0, 0x5f, 0xa6, 0x2a, 0xb0, 0xfc, 0xff, 0xd4, 0xff, 0xb5, 0x55, 0x55, 0x2f, 0x96, 0xfc, 0xe9, + 0xe0, 0x80, 0x64, 0x9f, 0xe6, 0xf5, 0x4e, 0x4f, 0x89, 0xf8, 0x9f, 0xe1, 0x90, 0x53, 0x71, 0x3c, + 0x0f, 0x94, 0x0e, 0x0f, 0x88, 0x7a, 0x96, 0xcb, 0x0c, 0x90, 0xa9, 0xdc, 0xdf, 0x86, 0x04, 0x7c, + 0x45, 0x31, 0x5d, 0xc5, 0x1b, 0xbb, 0xf8, 0x53, 0x88, 0x71, 0xf7, 0x71, 0x5b, 0xbd, 0xc5, 0x62, + 0xb1, 0x5f, 0xb8, 0x60, 0x4c, 0x14, 0x09, 0x62, 0x42, 0x04, 0x60, 0xe4, 0xbc, 0x48, 0x87, 0x77, + 0x77, 0xbc, 0xb0, 0x60, 0x19, 0x11, 0x5a, 0xd4, 0x47, 0xac, 0xe1, 0x80, 0x42, 0x14, 0xe6, 0xe4, + 0xf9, 0x7a, 0x9b, 0xca, 0xc6, 0xd7, 0x55, 0x55, 0x7e, 0x10, 0x06, 0x23, 0x2f, 0x7b, 0x46, 0xe2, + 0xf3, 0x8a, 0xc6, 0x73, 0x55, 0xf8, 0x88, 0xba, 0xcb, 0x82, 0x1c, 0xc4, 0x38, 0x2b, 0xe0, 0x83, + 0x84, 0x04, 0x70, 0x80, 0x8f, 0x10, 0x13, 0xbb, 0xee, 0xff, 0x10, 0x2f, 0xba, 0x59, 0x72, 0x0a, + 0x22, 0x3e, 0x25, 0xee, 0xef, 0x88, 0x94, 0xef, 0xb9, 0x20, 0x84, 0x30, 0x30, 0xd5, 0x55, 0x17, + 0x17, 0x12, 0x70, 0xb3, 0xab, 0xcf, 0x0f, 0x2c, 0x03, 0x48, 0x0f, 0xd2, 0xc3, 0x38, 0x4e, 0xeb, + 0xcd, 0xe3, 0xb4, 0xf4, 0xff, 0xfe, 0x2e, 0x26, 0x0b, 0x24, 0x83, 0x55, 0xd9, 0xaa, 0x2b, 0xbf, + 0x70, 0x40, 0x18, 0x19, 0x9c, 0x53, 0xb8, 0xae, 0xe3, 0x0b, 0xdf, 0x70, 0x7f, 0x9e, 0x10, 0xa4, + 0x5c, 0x3e, 0x5a, 0x9b, 0x03, 0xfd, 0x62, 0x51, 0x74, 0x92, 0x41, 0x44, 0x24, 0xb7, 0xd3, 0xff, + 0xff, 0x29, 0x9d, 0xc5, 0x62, 0xbf, 0x37, 0x55, 0xc4, 0x09, 0x08, 0x44, 0x39, 0xc5, 0xa1, 0x68, + 0xf8, 0xfc, 0x4b, 0x8d, 0x7a, 0x25, 0x94, 0x25, 0x6a, 0xe7, 0x83, 0x00, 0x62, 0x63, 0x56, 0xb0, + 0x9b, 0x39, 0x9b, 0xff, 0xbf, 0xcd, 0x11, 0x82, 0x08, 0x80, 0x89, 0x6e, 0xee, 0xe4, 0x88, 0x12, + 0x14, 0x33, 0xde, 0x2b, 0x6e, 0x3b, 0xf1, 0xe9, 0xbb, 0xb7, 0x2f, 0x37, 0x05, 0x00, 0x84, 0x15, + 0xd3, 0x48, 0xef, 0xcb, 0x39, 0x3e, 0xaf, 0xef, 0x82, 0x7c, 0xdf, 0x62, 0x78, 0x9e, 0xb1, 0xc4, + 0x04, 0x4b, 0x6f, 0x7c, 0x20, 0x19, 0x36, 0xdb, 0x9b, 0xf0, 0x80, 0x52, 0x7c, 0x0a, 0x8d, 0x44, + 0xee, 0xeb, 0x98, 0x97, 0x92, 0x59, 0x49, 0xde, 0x3c, 0x3c, 0x73, 0x27, 0x80, 0xe1, 0x28, 0xab, + 0x70, 0xaa, 0x6b, 0x74, 0xe1, 0xeb, 0x7e, 0x24, 0x48, 0x2e, 0xbb, 0x7a, 0xaf, 0xd5, 0x0c, 0x86, + 0x44, 0x45, 0x76, 0x7c, 0x7e, 0x4f, 0x39, 0xc3, 0x98, 0x04, 0x3d, 0x14, 0x2a, 0xdc, 0xdb, 0x62, + 0x96, 0x20, 0xea, 0x8e, 0x74, 0x73, 0xfe, 0xdf, 0xd3, 0xe2, 0x21, 0x3b, 0x3a, 0x5b, 0x90, 0xe3, + 0x8f, 0xa1, 0x78, 0x38, 0x07, 0x32, 0xe2, 0x3c, 0x4c, 0x10, 0x71, 0xd7, 0x7b, 0xee, 0xf7, 0xbb, + 0xee, 0xab, 0xe1, 0x11, 0x03, 0x22, 0xbb, 0xdc, 0x56, 0x5e, 0x70, 0x00, 0xe5, 0xea, 0x70, 0xf3, + 0x80, 0x18, 0x60, 0x74, 0x83, 0x5c, 0x32, 0x19, 0x0a, 0x6d, 0xdf, 0x96, 0xe9, 0x38, 0xae, 0xb1, + 0x7d, 0x53, 0x10, 0x03, 0xe0, 0xf0, 0x7d, 0x98, 0x73, 0x00, 0x32, 0x01, 0x9e, 0xce, 0xdf, 0xee, + 0xfe, 0x99, 0xb6, 0x2e, 0x9a, 0xc7, 0x1c, 0x8b, 0x69, 0xc5, 0xb0, 0x7f, 0xcc, 0x9e, 0xdf, 0x4f, + 0x89, 0x13, 0x6a, 0x23, 0xe2, 0x03, 0xe5, 0x81, 0x93, 0xf1, 0x20, 0xaf, 0x2f, 0xd6, 0xbb, 0x4a, + 0xae, 0x21, 0xbc, 0x00, 0x5f, 0x5a, 0x95, 0x38, 0xb7, 0xbc, 0xf5, 0xc2, 0xe4, 0xd9, 0x08, 0x8f, + 0x7f, 0x51, 0x71, 0x57, 0xe0, 0x35, 0xf3, 0x3b, 0x0e, 0xa9, 0x23, 0x75, 0xbd, 0x45, 0xdf, 0x9f, + 0xdf, 0x89, 0x82, 0x58, 0x91, 0x60, 0xfc, 0x9d, 0xa3, 0xf8, 0xad, 0xee, 0xfc, 0x4c, 0x57, 0x3f, + 0x0d, 0x03, 0x50, 0x56, 0x15, 0x66, 0x9f, 0x86, 0x26, 0x8a, 0xcb, 0x0f, 0x08, 0x89, 0x19, 0xd5, + 0x78, 0x3d, 0xe3, 0xa1, 0xac, 0x62, 0x30, 0x3b, 0x35, 0xe7, 0x89, 0x09, 0x6a, 0xc2, 0x46, 0x5b, + 0x7f, 0x11, 0x78, 0x97, 0x0b, 0x0f, 0x07, 0x20, 0xe3, 0x0a, 0x4b, 0xff, 0xe9, 0xe9, 0xc9, 0x84, + 0x0c, 0x47, 0x8a, 0xcb, 0xb8, 0x80, 0xc0, 0xcd, 0xd6, 0xd9, 0x3c, 0x7a, 0x97, 0x76, 0x8f, 0x9f, + 0xc4, 0x04, 0x0b, 0x4e, 0x4e, 0x5c, 0x5c, 0xda, 0xbb, 0xf8, 0xbc, 0x65, 0x77, 0x6e, 0xda, 0x86, + 0xb9, 0xb7, 0x7b, 0xe2, 0xf7, 0x77, 0x7b, 0xbb, 0xe0, 0x9f, 0x6f, 0x97, 0xac, 0xad, 0xb8, 0x38, + 0x10, 0x14, 0xb4, 0xd4, 0x59, 0x78, 0x87, 0x96, 0x0d, 0xa6, 0x81, 0x01, 0xc6, 0x09, 0x69, 0x72, + 0x64, 0xd8, 0x3b, 0xe2, 0x60, 0x03, 0xe5, 0x19, 0x8d, 0xa0, 0x43, 0x87, 0x54, 0x02, 0x93, 0x20, + 0x5b, 0x14, 0xab, 0x3b, 0xc9, 0xa6, 0x8e, 0xed, 0x82, 0x83, 0x8e, 0xb0, 0x77, 0xf8, 0xb6, 0x9d, + 0x1b, 0xbf, 0xcb, 0xb2, 0xec, 0x8c, 0x5d, 0xd3, 0x6f, 0xa7, 0xc4, 0x05, 0x21, 0x5a, 0xcf, 0x58, + 0xa6, 0x2e, 0xd0, 0x8e, 0x4c, 0xaf, 0x2b, 0xf7, 0x13, 0x05, 0x90, 0xe9, 0x88, 0x4c, 0x1f, 0x15, + 0xf9, 0xcd, 0xc1, 0x02, 0x2e, 0xbc, 0x7a, 0xf5, 0x94, 0x5b, 0xc2, 0x10, 0xa5, 0x66, 0xa9, 0x79, + 0x6d, 0x91, 0x73, 0xf8, 0x2e, 0x59, 0x9c, 0x1c, 0x14, 0x39, 0x17, 0x93, 0x13, 0x7b, 0x1d, 0x3f, + 0x15, 0x97, 0x3d, 0xdf, 0xc1, 0x2c, 0xb4, 0x39, 0xa6, 0xa7, 0xde, 0xd7, 0x78, 0x90, 0x57, 0x7b, + 0xcb, 0xde, 0x2b, 0x37, 0x4f, 0x4d, 0xea, 0x20, 0x40, 0x72, 0xa4, 0xc5, 0x2d, 0xfb, 0xf6, 0xe4, + 0xf8, 0x98, 0x53, 0x2f, 0xb9, 0x6f, 0x78, 0xac, 0x6f, 0x41, 0x59, 0xcd, 0x2a, 0x70, 0xe5, 0xfe, + 0x1a, 0x1a, 0xbf, 0x5f, 0xc4, 0x04, 0x6a, 0xbb, 0xa0, 0x67, 0xb0, 0xda, 0x55, 0x17, 0xc4, 0xc2, + 0x9a, 0x89, 0x9c, 0x2c, 0x6f, 0x66, 0x51, 0xb0, 0x77, 0xe2, 0xeb, 0x80, 0xc3, 0xe1, 0x33, 0x55, + 0x1b, 0xce, 0xde, 0x20, 0x5d, 0xde, 0x4d, 0xb9, 0xee, 0x49, 0x62, 0x44, 0x3d, 0xdf, 0xe2, 0x36, + 0xa9, 0x13, 0x1b, 0xf8, 0x63, 0x96, 0xb5, 0x55, 0xcd, 0x77, 0xfc, 0xdd, 0x57, 0x11, 0xc3, 0x32, + 0x82, 0x3b, 0xfe, 0x3d, 0xff, 0xff, 0x7f, 0x89, 0x20, 0xae, 0xfb, 0xdf, 0xcb, 0xdd, 0xfc, 0x16, + 0x78, 0x5e, 0xbb, 0x9b, 0x81, 0x8b, 0x2e, 0x2c, 0xdc, 0xf0, 0x03, 0x83, 0xfe, 0x29, 0x99, 0x61, + 0x80, 0x40, 0x0a, 0x62, 0xa2, 0x00, 0xc6, 0xf8, 0xdf, 0x3f, 0x4d, 0xdb, 0xbc, 0xcb, 0x35, 0x21, + 0xcf, 0x85, 0x2d, 0x6e, 0xee, 0xfc, 0x49, 0xc5, 0xba, 0xf7, 0x3e, 0xaf, 0xc4, 0x81, 0x00, 0x7d, + 0xf7, 0xdd, 0xda, 0xdf, 0xc7, 0x54, 0x5d, 0x55, 0x5f, 0x8b, 0x25, 0xc8, 0x8b, 0x62, 0x8f, 0xc1, + 0x5d, 0xe6, 0xd3, 0xf2, 0x7a, 0xd4, 0xd1, 0x4f, 0x1d, 0xc1, 0x62, 0x3e, 0x24, 0x25, 0x81, 0xdb, + 0x5d, 0x71, 0x0c, 0x3c, 0x48, 0x80, 0x55, 0x3d, 0xf7, 0xe3, 0xc9, 0x9b, 0xdd, 0xd2, 0x2f, 0x04, + 0xb5, 0x5c, 0x6b, 0x8a, 0x29, 0x59, 0x81, 0xfc, 0xb9, 0x8f, 0x82, 0x7e, 0x92, 0x4f, 0xbb, 0x1f, + 0x05, 0x59, 0xb1, 0x4b, 0xe3, 0x0d, 0xaa, 0x51, 0x95, 0x57, 0x31, 0xb3, 0xc4, 0x82, 0x5a, 0x30, + 0xd0, 0x1e, 0x89, 0x58, 0xa5, 0x51, 0x90, 0xc3, 0xa1, 0x96, 0x42, 0xce, 0x1b, 0x28, 0x82, 0xd5, + 0x89, 0x85, 0x24, 0x99, 0x42, 0xe3, 0x1e, 0xb6, 0x10, 0x64, 0xb7, 0x83, 0x12, 0x32, 0x11, 0xc9, + 0x27, 0x5b, 0xe9, 0x38, 0x01, 0xa4, 0x1a, 0x8f, 0x0d, 0x56, 0xe1, 0x01, 0x21, 0x48, 0x90, 0xf2, + 0x60, 0xa8, 0xe8, 0x5c, 0xe0, 0x0f, 0x25, 0x6a, 0x3e, 0xc1, 0xdf, 0x9f, 0xe3, 0xd6, 0x5e, 0x49, + 0x5f, 0x7f, 0x78, 0x90, 0xa6, 0xee, 0xe4, 0xca, 0xb0, 0x60, 0xa9, 0x2e, 0x72, 0x1e, 0xa5, 0x53, + 0x2c, 0x7d, 0xc2, 0x21, 0x00, 0xa4, 0x32, 0x0f, 0x79, 0xf6, 0xeb, 0x71, 0xca, 0x2f, 0xec, 0xb6, + 0x7b, 0x82, 0xbc, 0xf1, 0xc6, 0xdd, 0xb7, 0xf9, 0x78, 0x31, 0x35, 0xc3, 0xbc, 0x97, 0x7b, 0xf8, + 0xcb, 0xbb, 0xbe, 0xee, 0xef, 0xbb, 0xfe, 0x11, 0xde, 0x69, 0x3b, 0xbb, 0x9f, 0x94, 0x0b, 0xa0, + 0xc9, 0x07, 0x18, 0x60, 0x22, 0x14, 0x84, 0xab, 0x81, 0x33, 0xf5, 0x24, 0xba, 0x64, 0x9e, 0xaa, + 0x55, 0x02, 0x5e, 0xf7, 0x0b, 0x85, 0x4e, 0x00, 0x02, 0x18, 0x3e, 0xc0, 0xf5, 0xa8, 0xb6, 0xe1, + 0x00, 0xc0, 0x29, 0xb3, 0x6e, 0x3d, 0x5b, 0x52, 0x60, 0x2b, 0x19, 0xc7, 0x1d, 0x87, 0x5f, 0x0c, + 0x84, 0x09, 0x5b, 0xb5, 0x88, 0x08, 0xf0, 0x88, 0x30, 0x0a, 0x5e, 0xfb, 0x6f, 0x74, 0xb1, 0x0e, + 0x1d, 0x81, 0x5d, 0xbb, 0x89, 0x04, 0x06, 0xb4, 0xd1, 0xb2, 0x70, 0x80, 0x63, 0xe0, 0x8f, 0x77, + 0x69, 0xec, 0x3a, 0xa0, 0x03, 0x11, 0x7f, 0x22, 0x7a, 0x6b, 0xbf, 0xfb, 0x78, 0xab, 0x6c, 0x04, + 0x41, 0x7f, 0x13, 0xde, 0xde, 0x22, 0x12, 0xcd, 0xfc, 0x48, 0x71, 0x78, 0x9a, 0xe0, 0x8f, 0xa4, + 0xe9, 0x9f, 0xad, 0x71, 0x1e, 0x23, 0xf0, 0x43, 0xe4, 0xda, 0x75, 0xe0, 0x8a, 0x33, 0x63, 0xf1, + 0x71, 0x11, 0xdb, 0x9f, 0x30, 0xf8, 0xd4, 0x8b, 0x79, 0x78, 0x3b, 0x78, 0x9b, 0x1c, 0x40, 0x40, + 0x67, 0x8a, 0xf3, 0xf8, 0x6d, 0xd2, 0x53, 0x18, 0x06, 0xfe, 0x42, 0xde, 0xe9, 0xaa, 0x9c, 0x0b, + 0xb0, 0xdf, 0x51, 0x6d, 0x78, 0xa5, 0x9e, 0xc3, 0x88, 0x1d, 0x26, 0x71, 0xf4, 0x9d, 0xde, 0x4c, + 0xc4, 0xe1, 0xee, 0x2a, 0xee, 0xef, 0x7b, 0xf8, 0xac, 0xe7, 0xf6, 0xdf, 0xe3, 0x37, 0xbb, 0xee, + 0xd2, 0x62, 0xb1, 0x22, 0xc1, 0xc0, 0x0e, 0x0a, 0xd2, 0x38, 0x01, 0xc0, 0xfc, 0x35, 0xc4, 0x04, + 0x41, 0x65, 0xf7, 0x55, 0x42, 0xc9, 0x0a, 0xf7, 0xbf, 0x88, 0x05, 0x9b, 0xdd, 0x3b, 0x88, 0x72, + 0x2b, 0x10, 0xe1, 0xc3, 0x99, 0x2a, 0xc4, 0x02, 0x9e, 0x20, 0x18, 0x84, 0x22, 0xbb, 0xf3, 0x74, + 0xd6, 0xdf, 0x05, 0x01, 0x90, 0xa4, 0xfc, 0xdc, 0xfe, 0x4b, 0x30, 0xb8, 0x15, 0x14, 0x32, 0xc0, + 0x39, 0xb0, 0x48, 0x68, 0x54, 0x97, 0x8b, 0xc0, 0xea, 0x5e, 0x8c, 0x75, 0xe0, 0xe3, 0x1f, 0xc2, + 0x21, 0x00, 0xa4, 0xe3, 0xc9, 0xce, 0xe3, 0x31, 0x31, 0x5f, 0x2e, 0xeb, 0x39, 0xc5, 0x6a, 0x2f, + 0xd7, 0xb0, 0xe2, 0x80, 0x13, 0xd6, 0x7d, 0x31, 0x2d, 0xd7, 0xb9, 0xba, 0xcd, 0xb1, 0x57, 0xdb, + 0xc5, 0xac, 0x83, 0xfa, 0x5f, 0x05, 0x11, 0x0e, 0x17, 0x05, 0x00, 0x65, 0x83, 0x78, 0xa3, 0x12, + 0x3e, 0x06, 0x58, 0x1c, 0x00, 0x90, 0x36, 0x20, 0x38, 0x20, 0x38, 0x92, 0xa5, 0x10, 0x1c, 0x0a, + 0x80, 0x19, 0x49, 0x43, 0xcf, 0x07, 0x02, 0xe3, 0x28, 0x75, 0xee, 0x4c, 0x2f, 0x95, 0x9e, 0x6f, + 0x18, 0x50, 0xec, 0x5b, 0x4f, 0xfc, 0x09, 0x00, 0x60, 0x1b, 0x24, 0xe4, 0x59, 0xc6, 0xe3, 0x0a, + 0x2a, 0x22, 0xa1, 0x76, 0x0b, 0x96, 0x03, 0x64, 0xb6, 0x48, 0x15, 0xb8, 0xb6, 0xa4, 0x01, 0x62, + 0xf2, 0x99, 0x57, 0x12, 0xfe, 0x04, 0x01, 0x20, 0xa6, 0x52, 0x96, 0xfc, 0x0d, 0xb1, 0x76, 0x46, + 0xd7, 0x5e, 0xb9, 0xc9, 0x0f, 0x93, 0x7b, 0xf1, 0x20, 0x8a, 0x92, 0x57, 0x82, 0xff, 0xc1, 0x16, + 0xa9, 0xdd, 0xf0, 0xa5, 0x37, 0x4d, 0xde, 0xf5, 0xd5, 0xcf, 0xf7, 0xf1, 0x03, 0xea, 0xba, 0xaa, + 0xd6, 0xbe, 0x24, 0x15, 0xcf, 0xb1, 0x11, 0xf5, 0xa7, 0xa2, 0x95, 0x9e, 0xe2, 0x61, 0x48, 0xd9, + 0x54, 0x1a, 0xcb, 0x8b, 0x91, 0x6c, 0x29, 0xcd, 0x32, 0x0b, 0x72, 0x6e, 0x74, 0x07, 0xc7, 0xf4, + 0xf3, 0x29, 0x8c, 0x0e, 0xae, 0xf7, 0x99, 0x3a, 0x5c, 0xb1, 0x82, 0xba, 0x85, 0xe7, 0x75, 0x2a, + 0xe2, 0x41, 0x35, 0xec, 0xdd, 0xd4, 0x9a, 0xbe, 0xee, 0x87, 0xb8, 0xcb, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xef, 0xe4, 0xee, 0xfc, 0x22, 0x32, 0x76, 0x5d, 0xa4, 0xfa, 0x59, 0x6c, 0xb7, 0xa6, + 0x3a, 0x16, 0xac, 0xfd, 0x57, 0x04, 0x20, 0x84, 0x56, 0x94, 0x56, 0xda, 0x1b, 0x46, 0xcc, 0x08, + 0x21, 0x10, 0xa4, 0x47, 0x19, 0x97, 0x8f, 0x1f, 0x2c, 0x00, 0x18, 0x43, 0x6a, 0x1c, 0x60, 0x35, + 0x06, 0x3e, 0x64, 0x50, 0x72, 0xb9, 0x0c, 0x58, 0x96, 0x25, 0xc0, 0x25, 0x70, 0x55, 0xbe, 0xf1, + 0x1b, 0xe8, 0x27, 0x61, 0xab, 0xe0, 0x50, 0x08, 0x8e, 0x89, 0x0d, 0x04, 0x1c, 0x57, 0xed, 0x31, + 0x2e, 0x54, 0xbe, 0x7f, 0x0d, 0x98, 0x60, 0x48, 0x53, 0x96, 0x82, 0xfe, 0x7c, 0x5d, 0x25, 0x7a, + 0xad, 0x51, 0xde, 0x0a, 0x02, 0x20, 0xaf, 0x51, 0x6d, 0x6e, 0xef, 0x75, 0xad, 0xf0, 0xca, 0x82, + 0x74, 0xeb, 0xe6, 0xd7, 0xb7, 0xff, 0xe2, 0x75, 0x0d, 0x60, 0x12, 0x3f, 0x62, 0x99, 0xff, 0xd3, + 0xf8, 0xb0, 0xc2, 0x80, 0x19, 0xff, 0xc5, 0x92, 0xec, 0xfe, 0x9f, 0xfd, 0x70, 0x72, 0x24, 0x16, + 0xf9, 0x71, 0xee, 0xef, 0x7c, 0x36, 0xe0, 0x61, 0x0c, 0xbe, 0x96, 0x77, 0x63, 0x71, 0x5f, 0x78, + 0x91, 0xe3, 0x58, 0x14, 0x73, 0x72, 0xf2, 0x72, 0xc6, 0xba, 0x7a, 0xd7, 0x81, 0x83, 0xe2, 0x3e, + 0x49, 0x78, 0x51, 0x19, 0x2f, 0xcf, 0x0d, 0xe4, 0x86, 0xbe, 0x3c, 0x63, 0xeb, 0x9b, 0x37, 0x55, + 0xd8, 0xf1, 0x91, 0x0f, 0x77, 0x05, 0xaf, 0x98, 0xf7, 0x96, 0xc2, 0x4f, 0x7d, 0x1b, 0xd6, 0x6d, + 0xf5, 0x7f, 0x8c, 0xd2, 0x77, 0x49, 0xbc, 0x56, 0x2b, 0x77, 0xb7, 0x5f, 0x08, 0xee, 0x6f, 0x9b, + 0x54, 0x7d, 0xe0, 0x22, 0xfa, 0x7c, 0x44, 0x96, 0x13, 0xf6, 0xdf, 0x82, 0x39, 0x21, 0x72, 0x41, + 0x39, 0x0e, 0xc4, 0x59, 0xef, 0x75, 0x11, 0x18, 0x6b, 0xdd, 0xd7, 0x8a, 0xee, 0xf7, 0xe2, 0x44, + 0x0e, 0xad, 0x65, 0xd3, 0x21, 0x01, 0x2d, 0xbb, 0xbb, 0xe2, 0x24, 0x93, 0x0b, 0xa7, 0x7c, 0x48, + 0x28, 0x11, 0x1f, 0x63, 0xdc, 0x8f, 0x3d, 0xca, 0xbe, 0x0e, 0x49, 0x77, 0xf0, 0x40, 0x24, 0x79, + 0x5f, 0x77, 0xbb, 0xde, 0xf0, 0xa2, 0x84, 0x80, 0xc6, 0xdf, 0x6e, 0x9f, 0xee, 0xdf, 0x0c, 0x88, + 0xde, 0xf5, 0xac, 0x2a, 0xe0, 0x47, 0xb5, 0x9d, 0xef, 0xff, 0xb7, 0x13, 0x80, 0x8b, 0xc7, 0x3e, + 0xee, 0x14, 0x24, 0x01, 0xb2, 0xb9, 0xcf, 0x7b, 0xef, 0x7f, 0xbd, 0xf0, 0x62, 0x0c, 0x02, 0x84, + 0x12, 0x78, 0xc8, 0x99, 0x20, 0xe3, 0x87, 0x1e, 0x6e, 0x3a, 0x5a, 0xe7, 0x46, 0x58, 0x3e, 0xe2, + 0xb0, 0x75, 0x73, 0xf5, 0x39, 0xc5, 0x58, 0xd1, 0x77, 0x05, 0x22, 0x44, 0xdd, 0xf5, 0xd7, 0xc4, + 0xf8, 0x9f, 0xc9, 0x3c, 0x11, 0x5f, 0x89, 0x17, 0xd4, 0xd8, 0x97, 0x6f, 0x12, 0x24, 0x11, 0x7c, + 0x43, 0xdd, 0xc4, 0x09, 0x1b, 0x6e, 0x7c, 0x90, 0x24, 0x16, 0xca, 0xc1, 0x08, 0xe2, 0xf9, 0xdf, + 0x0d, 0x7e, 0xcc, 0xbf, 0xe2, 0x41, 0x44, 0x6d, 0x62, 0xa8, 0x94, 0x11, 0xc5, 0xee, 0xf8, 0x46, + 0xfb, 0x76, 0x92, 0x4b, 0x06, 0xff, 0x0b, 0x1d, 0x95, 0xe1, 0x2e, 0xd2, 0xe7, 0x38, 0xf8, 0x91, + 0x25, 0xea, 0xb8, 0x9a, 0xbf, 0x13, 0x17, 0x19, 0xa5, 0xa1, 0x1c, 0x6a, 0xa9, 0x34, 0xd7, 0x82, + 0x3a, 0xcb, 0xb4, 0xe4, 0x29, 0xcd, 0x5a, 0xcd, 0xc9, 0x5a, 0xde, 0x23, 0xe4, 0xbd, 0xf8, 0x99, + 0xb7, 0x97, 0xe1, 0x80, 0xc8, 0xad, 0x62, 0x7e, 0x2f, 0x17, 0xc4, 0x82, 0x90, 0x87, 0x49, 0xdc, + 0x56, 0x21, 0xc7, 0xe6, 0x2e, 0xbc, 0x1c, 0x82, 0xe2, 0xbb, 0xbf, 0x14, 0xc5, 0xf9, 0x96, 0x0a, + 0x01, 0x0e, 0x23, 0x00, 0xff, 0xca, 0xba, 0x60, 0xe0, 0x32, 0x10, 0x23, 0xbb, 0xdf, 0x77, 0x77, + 0x78, 0xe9, 0x43, 0xb1, 0xfb, 0x12, 0x42, 0x87, 0x05, 0x37, 0x86, 0x00, 0x90, 0x30, 0x43, 0x62, + 0xed, 0xe3, 0x2d, 0xc5, 0x6e, 0xe2, 0xb7, 0xbd, 0xe1, 0xec, 0x00, 0x8c, 0x27, 0x14, 0x40, 0x3b, + 0xfb, 0x96, 0x3d, 0x8d, 0x34, 0xee, 0xf8, 0x8a, 0xbd, 0x31, 0x45, 0x8a, 0xb4, 0xda, 0x18, 0x0a, + 0x17, 0x71, 0x79, 0xbd, 0x1b, 0x78, 0x89, 0x6b, 0x07, 0x97, 0xbe, 0x23, 0x0d, 0x3d, 0xf8, 0xea, + 0xfe, 0x6b, 0x51, 0x71, 0x7c, 0x4c, 0x4f, 0x95, 0x8b, 0x55, 0xe2, 0x64, 0xc4, 0x73, 0xe2, 0x78, + 0x99, 0x29, 0x25, 0xbe, 0x1a, 0x92, 0xd9, 0x97, 0xef, 0xb6, 0x2a, 0xff, 0x7c, 0x57, 0x70, 0xe6, + 0x23, 0xc4, 0x93, 0x77, 0x7f, 0x65, 0xdd, 0xf8, 0x92, 0x11, 0x3b, 0xf0, 0xcc, 0xbc, 0x6d, 0x6f, + 0x0c, 0x89, 0x0a, 0x5e, 0xe2, 0xb7, 0xbd, 0x28, 0x3b, 0xf1, 0x3c, 0xd5, 0x5d, 0x87, 0x09, 0x00, + 0x31, 0x9a, 0x1f, 0x76, 0xcb, 0xb7, 0xd6, 0xef, 0x5a, 0xa6, 0x9b, 0x49, 0xa6, 0x99, 0x39, 0x76, + 0x38, 0xc7, 0x3f, 0x7f, 0x82, 0x10, 0xc8, 0x23, 0x2a, 0xd2, 0xf6, 0x21, 0xd0, 0xe2, 0x1f, 0x09, + 0xe0, 0x9b, 0xfa, 0xcf, 0xff, 0xef, 0x81, 0x64, 0x32, 0x09, 0xc9, 0x58, 0xba, 0x44, 0xcf, 0xb8, + 0x62, 0x4c, 0x8c, 0x78, 0x30, 0x01, 0x12, 0x36, 0x13, 0x40, 0x92, 0x1f, 0x60, 0xd8, 0x53, 0x87, + 0x81, 0xe0, 0xf5, 0x81, 0xcd, 0x28, 0xe4, 0x0f, 0x03, 0xe0, 0x35, 0x28, 0x4f, 0x05, 0x80, 0x01, + 0x3b, 0x66, 0x3a, 0x3c, 0x38, 0x00, 0x0a, 0xf2, 0xc0, 0x00, 0xac, 0x3b, 0x06, 0xa2, 0xe1, 0x0a, + 0xb0, 0x19, 0x04, 0x81, 0xc2, 0x32, 0x37, 0x6e, 0x89, 0xd3, 0x4d, 0x3c, 0x48, 0x80, 0xa4, 0x3e, + 0x35, 0x25, 0x05, 0x43, 0xf0, 0x06, 0xa3, 0xa0, 0xfd, 0x6d, 0x16, 0xb1, 0x20, 0x70, 0xf0, 0x00, + 0x37, 0xc7, 0x40, 0xf9, 0xe0, 0x00, 0x67, 0x9e, 0x00, 0x3c, 0x76, 0xe3, 0xa0, 0x0b, 0x96, 0xb1, + 0xd0, 0x0b, 0x86, 0xc0, 0x51, 0x80, 0x04, 0x3c, 0x13, 0x70, 0xb5, 0x72, 0xa4, 0x09, 0x64, 0xa9, + 0x00, 0x54, 0x96, 0xbe, 0x09, 0x75, 0xb6, 0x29, 0x8b, 0xaf, 0x91, 0x08, 0x88, 0x08, 0x0a, 0xb1, + 0x83, 0xb7, 0x57, 0x75, 0x83, 0x25, 0x55, 0xd0, 0x37, 0x88, 0xf1, 0x25, 0xbd, 0xf8, 0x99, 0x37, + 0xbb, 0xc1, 0x00, 0xae, 0xe2, 0xb4, 0xc5, 0x1b, 0xbe, 0x04, 0x00, 0x28, 0x8c, 0x9f, 0x0b, 0xcb, + 0xb1, 0x59, 0x31, 0x4a, 0xcb, 0x78, 0x3e, 0xf6, 0x3d, 0x7b, 0xc4, 0xbf, 0x0c, 0xe0, 0x14, 0x95, + 0xb2, 0x1c, 0xa8, 0xdd, 0x5f, 0x37, 0x77, 0x9b, 0xe0, 0xff, 0xa7, 0xa6, 0x9e, 0x97, 0x82, 0x01, + 0x0b, 0xdc, 0x33, 0x04, 0xbb, 0xdd, 0xc5, 0x6e, 0x2b, 0xec, 0x26, 0xe0, 0x13, 0x0d, 0x1f, 0x4f, + 0x3f, 0xf3, 0x7f, 0x7c, 0x0a, 0x00, 0x51, 0x77, 0x77, 0xe1, 0x10, 0x62, 0x5d, 0xef, 0x81, 0x44, + 0x18, 0x05, 0x2a, 0x27, 0xd4, 0xb3, 0x0b, 0x86, 0xe1, 0x4d, 0x90, 0x63, 0x0a, 0x1c, 0x64, 0x4e, + 0x82, 0x4e, 0x16, 0x18, 0x90, 0x0c, 0x09, 0x2a, 0x68, 0x7f, 0x4e, 0x0f, 0x79, 0x23, 0x54, 0x63, + 0x0e, 0x12, 0x00, 0xe2, 0x8e, 0x62, 0x6c, 0x1f, 0xb4, 0xaf, 0xab, 0x77, 0x9a, 0xeb, 0x1d, 0x17, + 0x6c, 0x97, 0xcb, 0x9d, 0x6c, 0x4f, 0x1d, 0x22, 0xeb, 0x67, 0xab, 0xea, 0x7e, 0xb7, 0x0d, 0xb8, + 0x00, 0x84, 0x71, 0xc9, 0x8c, 0x50, 0xbf, 0x63, 0x2d, 0xdf, 0xdb, 0x65, 0x9a, 0x07, 0xa5, 0x31, + 0xbe, 0xbe, 0x04, 0xe7, 0x4c, 0x90, 0x3c, 0x54, 0xfc, 0x58, 0xb5, 0x56, 0x0e, 0xdd, 0xef, 0xf7, + 0x36, 0x02, 0x13, 0xc4, 0xd8, 0x3d, 0x97, 0x97, 0xc3, 0xb5, 0x86, 0xe3, 0x2a, 0x20, 0xe5, 0x4b, + 0xfd, 0x57, 0x36, 0x52, 0x85, 0xf9, 0xbb, 0xb9, 0x62, 0x7c, 0x46, 0xf8, 0x8b, 0xde, 0xee, 0xef, + 0xe0, 0xab, 0x8e, 0xaf, 0xac, 0x5c, 0x65, 0x4e, 0x71, 0x13, 0xc1, 0xc1, 0xaa, 0xb9, 0x7b, 0x70, + 0x50, 0x05, 0x11, 0x92, 0x67, 0x0d, 0xdb, 0x1d, 0xf3, 0x8c, 0xf8, 0xe7, 0x2f, 0xbc, 0xd4, 0xe5, + 0xa6, 0x19, 0x12, 0x10, 0xb5, 0x8a, 0x2a, 0x9c, 0xe6, 0x8d, 0xa6, 0x7c, 0x2f, 0xe2, 0x04, 0xf7, + 0x75, 0xb7, 0x38, 0x90, 0xc8, 0x9f, 0x2f, 0x97, 0xaf, 0x84, 0x44, 0x97, 0x8b, 0xaf, 0x12, 0x33, + 0x51, 0x71, 0x4c, 0x48, 0x70, 0x1f, 0x71, 0xf6, 0x92, 0x3a, 0x08, 0x0f, 0x2f, 0x11, 0xc9, 0x2c, + 0xcb, 0x0d, 0x20, 0x7d, 0x9c, 0x20, 0x33, 0x1b, 0xf1, 0xb9, 0xd4, 0xf8, 0xac, 0xbf, 0x25, 0x98, + 0x89, 0x06, 0x2e, 0x42, 0x09, 0x7e, 0x04, 0x81, 0x02, 0xb5, 0xae, 0x6e, 0x24, 0x39, 0xe2, 0x62, + 0x99, 0xdc, 0xd6, 0x78, 0x70, 0x5c, 0xdc, 0x13, 0xd3, 0x63, 0x24, 0x3a, 0x72, 0x41, 0xfc, 0x40, + 0xcb, 0x79, 0xb3, 0x1e, 0xca, 0x9d, 0x4d, 0x48, 0xb9, 0x69, 0xe2, 0x04, 0xef, 0x69, 0x55, 0x25, + 0x0e, 0x73, 0x5d, 0xee, 0x23, 0x9a, 0xf7, 0xae, 0x11, 0xbd, 0xdb, 0x56, 0x85, 0xc5, 0xda, 0x14, + 0x62, 0xeb, 0x84, 0x42, 0x03, 0x27, 0x83, 0x84, 0xe2, 0xae, 0xa6, 0x7b, 0x9a, 0x48, 0xac, 0x57, + 0x13, 0xc1, 0x59, 0xfa, 0xef, 0x3f, 0x31, 0x22, 0x47, 0x55, 0x7a, 0xbb, 0x22, 0xe4, 0xb6, 0xf8, + 0x98, 0x52, 0xaa, 0x95, 0x57, 0x69, 0x65, 0xd9, 0xb0, 0x4f, 0x0f, 0x0c, 0x1f, 0x84, 0x61, 0x08, + 0x93, 0xce, 0x3c, 0x77, 0x3c, 0xfe, 0x2b, 0x3e, 0xa2, 0x7e, 0x1e, 0x2b, 0x58, 0x66, 0x32, 0xa4, + 0xe0, 0xba, 0x4a, 0x17, 0xdd, 0x8b, 0x8b, 0x9c, 0x07, 0xcb, 0x32, 0x6a, 0xab, 0x82, 0x81, 0x2f, + 0xaa, 0xf1, 0x24, 0x89, 0x3c, 0xe0, 0x39, 0x11, 0xcc, 0x40, 0x90, 0x43, 0x24, 0x02, 0xa7, 0x72, + 0x7e, 0xe1, 0x01, 0x00, 0xae, 0xba, 0xa8, 0xb8, 0xa6, 0x2e, 0xb5, 0x17, 0x2a, 0x32, 0x36, 0x25, + 0xc9, 0x91, 0x7e, 0x3b, 0x97, 0xd0, 0x79, 0x98, 0x33, 0x1f, 0xc1, 0x35, 0xf7, 0x17, 0xf0, 0x5f, + 0x2d, 0xef, 0x0e, 0xf3, 0x1e, 0xf7, 0xe2, 0x7c, 0x4d, 0x62, 0x7c, 0x1c, 0x78, 0x10, 0x30, 0xf4, + 0xc0, 0x48, 0xdc, 0x07, 0xdb, 0xe9, 0xe9, 0xa9, 0x6a, 0xea, 0xfd, 0x1f, 0x5f, 0x7d, 0x3c, 0x22, + 0x08, 0x46, 0x5f, 0x6e, 0x4b, 0x96, 0x1b, 0x7c, 0x4f, 0x88, 0x1c, 0x56, 0x0a, 0xa1, 0x71, 0x7a, + 0xa9, 0x4f, 0xbc, 0x48, 0xcb, 0x3d, 0xd8, 0x81, 0xb2, 0xbc, 0xe3, 0x93, 0x2a, 0xaa, 0xbc, 0x08, + 0x01, 0x0c, 0x52, 0x29, 0xff, 0x10, 0xea, 0xba, 0x84, 0x42, 0x20, 0xa8, 0x82, 0x98, 0x83, 0x89, + 0x4b, 0x3b, 0x58, 0xb2, 0xd8, 0x87, 0x0e, 0x70, 0x40, 0x3c, 0x90, 0x00, 0x08, 0xf6, 0x48, 0xe1, + 0xbc, 0x00, 0xa5, 0xdc, 0x0a, 0x2f, 0x15, 0xcd, 0x34, 0xfe, 0xbe, 0xdd, 0xc5, 0x58, 0x3b, 0xf9, + 0x28, 0xf4, 0xfb, 0x78, 0x28, 0x08, 0x02, 0x8e, 0x03, 0x6f, 0x54, 0x0b, 0x08, 0x29, 0x64, 0x31, + 0x27, 0x07, 0x40, 0x58, 0x3a, 0x00, 0xb3, 0xb8, 0x10, 0x01, 0x40, 0x2c, 0xa4, 0x4c, 0xb9, 0xb1, + 0x4b, 0x35, 0xaa, 0x89, 0x38, 0x54, 0xe2, 0x04, 0x17, 0xaa, 0x82, 0x48, 0x91, 0x3e, 0x22, 0x4e, + 0x62, 0xdd, 0xee, 0x10, 0x07, 0x13, 0x41, 0x48, 0x63, 0x0b, 0xa2, 0x00, 0x16, 0xfb, 0x8d, 0x4b, + 0xfe, 0x9e, 0xfb, 0xa7, 0xf5, 0x6d, 0x4b, 0x36, 0x1e, 0x70, 0x0a, 0x49, 0x36, 0x22, 0x90, 0xac, + 0xa6, 0xae, 0xb2, 0xfe, 0xba, 0xf8, 0xcb, 0xe9, 0xe0, 0xff, 0x8b, 0x60, 0x30, 0x30, 0xd7, 0xdb, + 0xc0, 0x80, 0x05, 0x00, 0xa6, 0xa2, 0xfa, 0xa4, 0x4c, 0x34, 0x05, 0xc9, 0x05, 0x49, 0x45, 0x5c, + 0xf7, 0xfe, 0x3a, 0x7c, 0x13, 0x45, 0xd6, 0x71, 0x45, 0x06, 0xfd, 0x04, 0x71, 0x3e, 0x23, 0x27, + 0x2d, 0xdd, 0xfe, 0x6d, 0xee, 0xa2, 0x31, 0x01, 0x62, 0x40, 0x24, 0x71, 0x89, 0xb9, 0xdb, 0x5e, + 0x9b, 0x66, 0xe9, 0xb3, 0xfa, 0x71, 0xf8, 0x31, 0x02, 0x08, 0x89, 0x3e, 0x77, 0xc9, 0x8a, 0x17, + 0xe0, 0x20, 0x41, 0x48, 0x2a, 0xb3, 0x3b, 0xc9, 0x8f, 0x6e, 0x2b, 0xbb, 0x78, 0x81, 0x33, 0xc0, + 0x79, 0x6c, 0x9d, 0x5a, 0xad, 0x4f, 0xf2, 0x70, 0x4b, 0x12, 0x78, 0x90, 0xe4, 0x47, 0x16, 0x71, + 0xc3, 0x61, 0xd2, 0x1f, 0xe4, 0xbd, 0xe5, 0xc4, 0x1a, 0xef, 0x75, 0x86, 0x7c, 0x33, 0x51, 0x02, + 0x62, 0x02, 0xa8, 0xa0, 0x1a, 0xd7, 0xb1, 0x97, 0xfd, 0xbf, 0xf0, 0x40, 0x10, 0x29, 0x12, 0x51, + 0xb5, 0xc1, 0x47, 0x25, 0xde, 0xfe, 0x4b, 0xde, 0xb9, 0x04, 0xdd, 0xfc, 0x49, 0x88, 0xef, 0x7c, + 0x08, 0x20, 0x84, 0x56, 0x6f, 0x2e, 0x45, 0x6a, 0x5e, 0x22, 0x0c, 0x44, 0x82, 0x29, 0xfd, 0xef, + 0xc3, 0x02, 0x01, 0x59, 0x07, 0x47, 0xe0, 0xe8, 0x7e, 0x0e, 0x87, 0xc4, 0xf8, 0x5d, 0x59, 0x17, + 0x51, 0x75, 0xa8, 0x29, 0xc4, 0x3a, 0xea, 0x82, 0x71, 0x60, 0x9b, 0xd3, 0x7e, 0xeb, 0xf5, 0xaf, + 0xfc, 0xa2, 0x9e, 0xef, 0xc2, 0x02, 0xce, 0xfb, 0xbd, 0xdf, 0xdd, 0xdf, 0xf3, 0x5f, 0x73, 0x72, + 0x5c, 0x51, 0xe0, 0xab, 0x90, 0xae, 0xef, 0x09, 0xc4, 0x60, 0x12, 0x38, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x37, 0x1b, 0xb0, 0x52, 0x2f, 0x08, 0x77, 0x7b, 0xbb, 0xdd, 0xdf, 0xc5, 0x5d, 0xdd, + 0xdd, 0xdd, 0xe3, 0x65, 0x00, 0xc7, 0xe6, 0x1d, 0xdf, 0x7d, 0xdc, 0xbc, 0xa4, 0xad, 0x7c, 0xa5, + 0xdd, 0xc1, 0x6e, 0x18, 0x0a, 0x5d, 0xdd, 0xdd, 0xb7, 0x77, 0x77, 0x77, 0x77, 0xbd, 0x44, 0x65, + 0xc3, 0x01, 0x12, 0x2a, 0xef, 0x36, 0xea, 0xe4, 0xbc, 0x18, 0x46, 0x62, 0x83, 0xb8, 0x31, 0xd5, + 0x98, 0x78, 0xf6, 0xe5, 0xa5, 0x27, 0x3c, 0x1c, 0x3c, 0x1e, 0x7b, 0x85, 0x8e, 0x17, 0x70, 0x6a, + 0x83, 0xf3, 0xe7, 0x6d, 0xbf, 0xfd, 0x4b, 0x0d, 0x32, 0xf2, 0xd6, 0x29, 0x88, 0xff, 0x2d, 0xdc, + 0x56, 0xe0, 0xaf, 0x08, 0x88, 0x2b, 0xdf, 0x79, 0x7f, 0xbb, 0xbf, 0x2f, 0x31, 0x22, 0x7c, 0xdc, + 0x9c, 0x2b, 0x82, 0x80, 0x88, 0xec, 0x98, 0x25, 0xfb, 0x30, 0xbf, 0x1d, 0x3f, 0x2c, 0x6f, 0x89, + 0x8c, 0x83, 0xb7, 0x2c, 0x32, 0xb2, 0x58, 0x72, 0xe2, 0xe4, 0xf1, 0x4c, 0x5c, 0x53, 0x14, 0xd9, + 0xc4, 0x1e, 0xcf, 0x0b, 0xe0, 0x06, 0x33, 0x1c, 0xc8, 0x65, 0x57, 0x77, 0xbd, 0xd7, 0xdc, 0x2d, + 0xc5, 0x66, 0x3b, 0x86, 0x20, 0xaa, 0x29, 0xc9, 0x3f, 0xaa, 0xd6, 0xb7, 0xe1, 0x08, 0xeb, 0x55, + 0x56, 0xab, 0x55, 0x55, 0xe2, 0x1d, 0x3a, 0xaf, 0x10, 0xbe, 0x82, 0xf8, 0x28, 0x05, 0x23, 0xfa, + 0xae, 0x5b, 0x8c, 0xd2, 0xec, 0x4b, 0x0c, 0x4c, 0x21, 0x3c, 0x7d, 0xeb, 0xd6, 0xcd, 0xd7, 0x13, + 0xf8, 0x90, 0x2c, 0x82, 0xbb, 0x69, 0xba, 0x93, 0xb9, 0x87, 0x78, 0xee, 0xe2, 0x07, 0xf7, 0xc1, + 0x67, 0x2f, 0xbd, 0xde, 0xef, 0xd2, 0x62, 0x44, 0x62, 0xfa, 0xcf, 0x8d, 0x61, 0x01, 0x18, 0xa6, + 0x75, 0x04, 0xfc, 0x97, 0xdc, 0xd8, 0x80, 0x58, 0x60, 0xb2, 0xa7, 0x3b, 0x8a, 0xcd, 0xd4, 0x2a, + 0xac, 0xad, 0x7d, 0xe2, 0x49, 0x6b, 0x8b, 0xe1, 0x98, 0x52, 0xca, 0xa9, 0xcb, 0xc4, 0xf9, 0xfd, + 0x5a, 0xbd, 0x38, 0x87, 0x1c, 0x71, 0x01, 0x08, 0xba, 0xb9, 0x8e, 0x3b, 0xb7, 0x54, 0x89, 0x9c, + 0x40, 0x9b, 0xbb, 0x4e, 0xad, 0x74, 0x2a, 0x24, 0x84, 0x70, 0x84, 0xa2, 0x1e, 0xfe, 0x23, 0x84, + 0x04, 0x2f, 0x54, 0x10, 0x60, 0x9a, 0x24, 0x44, 0xa1, 0x77, 0x00, 0x57, 0xdd, 0xe2, 0xbe, 0x1a, + 0x3f, 0xfc, 0xf3, 0xfe, 0xda, 0x8e, 0xdf, 0xf4, 0xd9, 0xa3, 0x17, 0xd4, 0x91, 0x91, 0xd9, 0xb8, + 0x20, 0x8b, 0xa5, 0xbb, 0xc5, 0x6f, 0x88, 0x8b, 0xe2, 0x1c, 0x76, 0x3a, 0xf8, 0x67, 0xc2, 0x21, + 0x1a, 0xa6, 0x6f, 0xee, 0xf2, 0xed, 0xbf, 0x0a, 0x5e, 0xd4, 0xd4, 0x9b, 0xa9, 0x36, 0xa6, 0xea, + 0xca, 0x12, 0x83, 0x48, 0x96, 0xef, 0xc4, 0x04, 0x09, 0xbb, 0xde, 0x24, 0x94, 0x65, 0xb8, 0xc7, + 0xb1, 0x11, 0x13, 0x61, 0xb1, 0x99, 0x12, 0xbf, 0x88, 0xf0, 0x50, 0x08, 0x18, 0xd1, 0x03, 0x0b, + 0xc1, 0x37, 0x05, 0x23, 0x2e, 0xee, 0xf7, 0xbd, 0xf5, 0x5c, 0x5f, 0x77, 0xab, 0x75, 0x06, 0x01, + 0x10, 0x84, 0x51, 0x97, 0x4d, 0xba, 0x67, 0xe2, 0x1c, 0x7f, 0x8a, 0xdc, 0x4b, 0x4c, 0x10, 0x03, + 0x80, 0xa4, 0x56, 0x28, 0xc5, 0x06, 0xe2, 0xb1, 0x5b, 0x4d, 0x0a, 0x0c, 0x6d, 0x5f, 0x95, 0x12, + 0xd4, 0xb3, 0xd4, 0x7c, 0x63, 0xc2, 0x20, 0xe0, 0x29, 0x2d, 0x8a, 0xc7, 0x54, 0xb6, 0x66, 0x0d, + 0xe4, 0xbc, 0xbc, 0xda, 0x5d, 0xdd, 0xce, 0x0f, 0x48, 0xe0, 0xc2, 0x4f, 0xc4, 0x06, 0x44, 0xd6, + 0x4f, 0x26, 0x2b, 0x8f, 0x0b, 0xf8, 0x90, 0x55, 0x73, 0xff, 0x97, 0xae, 0xab, 0x97, 0x08, 0xc6, + 0x71, 0x5b, 0x58, 0x2b, 0x32, 0xfe, 0x95, 0xf7, 0x14, 0x76, 0xd4, 0x36, 0xe4, 0x53, 0x8e, 0x3c, + 0x22, 0x25, 0xe9, 0xbf, 0x08, 0x89, 0x11, 0x4d, 0xd6, 0xee, 0x5f, 0x16, 0x26, 0x2e, 0x42, 0x0a, + 0xe2, 0x0c, 0x06, 0xae, 0xfc, 0x21, 0x08, 0xf6, 0x6e, 0xa3, 0x2a, 0x1f, 0x77, 0xfc, 0x99, 0x79, + 0x70, 0xb6, 0xb1, 0x32, 0xe2, 0x0d, 0x79, 0x58, 0x65, 0xc4, 0x02, 0xcc, 0x9e, 0x48, 0x1b, 0x05, + 0xf9, 0xb0, 0xfe, 0x7d, 0xe2, 0x0b, 0x59, 0x30, 0xb8, 0x08, 0x39, 0x2f, 0x7b, 0x83, 0x91, 0x23, + 0x2a, 0x77, 0x30, 0xec, 0xd4, 0x1d, 0xa0, 0x0f, 0xd5, 0x13, 0x02, 0xb5, 0xa9, 0x30, 0x91, 0xee, + 0x9c, 0x2e, 0xe0, 0x15, 0xed, 0x5a, 0x8f, 0x3a, 0x8d, 0xe5, 0x39, 0xb9, 0x7c, 0x72, 0xda, 0x65, + 0xde, 0x36, 0x61, 0x9f, 0xb8, 0x46, 0x32, 0x58, 0xdd, 0xa3, 0xc2, 0x23, 0x82, 0xb1, 0xef, 0x04, + 0x39, 0xf1, 0x2e, 0x6f, 0xf0, 0x57, 0x3b, 0x9a, 0xd4, 0xb9, 0x5b, 0xbd, 0x5e, 0xdc, 0x4c, 0x29, + 0xaa, 0x33, 0x51, 0x23, 0x6c, 0xa5, 0x00, 0x0a, 0xe2, 0xcd, 0x66, 0x4d, 0xb0, 0xb9, 0x56, 0x7c, + 0x29, 0x1f, 0x62, 0xd5, 0x55, 0x8b, 0x93, 0x05, 0x5d, 0x87, 0x07, 0x0b, 0x3a, 0xdf, 0xa7, 0xe4, + 0xa4, 0x5c, 0x3e, 0x7c, 0x48, 0x99, 0xb4, 0x2e, 0xb5, 0xf8, 0x81, 0xc1, 0x5f, 0x12, 0xef, 0xba, + 0xe1, 0xad, 0xe5, 0x44, 0xee, 0xa7, 0xff, 0xe2, 0xe9, 0x97, 0x62, 0xb8, 0x86, 0x0e, 0xb7, 0x4f, + 0x19, 0xe2, 0xb7, 0xbe, 0xb7, 0x55, 0x13, 0xe5, 0x87, 0xe1, 0x49, 0xba, 0xc5, 0x6e, 0x49, 0xd3, + 0x18, 0xfd, 0x85, 0x17, 0x17, 0x12, 0x68, 0x58, 0x75, 0x05, 0xf4, 0x11, 0xfb, 0x3e, 0x5f, 0x2e, + 0x2e, 0x24, 0x40, 0x9a, 0x69, 0x6f, 0x78, 0x6b, 0x88, 0xd6, 0xab, 0x59, 0xf8, 0x28, 0xf1, 0x3e, + 0x6c, 0x71, 0x6c, 0x35, 0xeb, 0xdc, 0x40, 0x40, 0x29, 0x06, 0x10, 0xf2, 0x2b, 0xf2, 0x0b, 0xbb, + 0x57, 0xdc, 0x24, 0x72, 0x7e, 0x5f, 0xe5, 0x6a, 0xa2, 0xe2, 0x66, 0x73, 0x84, 0x61, 0x4e, 0xee, + 0xee, 0xee, 0x6c, 0xcb, 0xc5, 0xde, 0x38, 0xb7, 0x19, 0x8c, 0x50, 0x21, 0x19, 0xc4, 0xd6, 0x4a, + 0xb0, 0x40, 0x05, 0x00, 0x57, 0x75, 0x15, 0xbb, 0xef, 0x8a, 0xc5, 0x18, 0xec, 0x7e, 0x1a, 0xc0, + 0x02, 0xfa, 0x39, 0x1b, 0x59, 0x88, 0xac, 0xfa, 0xfb, 0x63, 0x4a, 0x5e, 0xe9, 0xf9, 0x7d, 0xcb, + 0xd3, 0x7c, 0x15, 0xeb, 0x48, 0xf6, 0x1b, 0xb5, 0xb9, 0xe6, 0xdb, 0xcb, 0xc5, 0x78, 0x9b, 0x15, + 0x49, 0x7c, 0x56, 0x9d, 0x57, 0x5c, 0x48, 0x87, 0x56, 0xbd, 0xbf, 0x86, 0xa6, 0x60, 0x4f, 0x8e, + 0x6d, 0x98, 0xc7, 0xd3, 0x2d, 0xfe, 0x3e, 0xb8, 0x7d, 0xdf, 0x3e, 0x7c, 0x15, 0x6d, 0xb5, 0x4e, + 0x9b, 0x74, 0xaf, 0x88, 0x71, 0x22, 0x26, 0x87, 0xf1, 0x5b, 0xf1, 0xbd, 0x56, 0x15, 0xaf, 0x26, + 0x1d, 0xc8, 0x79, 0xf9, 0x64, 0x83, 0xa2, 0x31, 0x1b, 0x1f, 0x77, 0x6d, 0xf8, 0x90, 0xa4, 0xb3, + 0x12, 0x00, 0x58, 0x11, 0x60, 0xe0, 0xe1, 0xc1, 0xe9, 0x1d, 0xf9, 0x31, 0x99, 0xe5, 0x7e, 0x40, + 0xe2, 0x06, 0x6f, 0x78, 0x14, 0x79, 0x52, 0x66, 0x61, 0x71, 0x8c, 0x1e, 0xf1, 0xcb, 0x65, 0xb1, + 0x47, 0x89, 0x10, 0x33, 0x51, 0xb3, 0x39, 0x88, 0x87, 0xb4, 0x4a, 0xd2, 0x4f, 0xff, 0x66, 0xf5, + 0xf0, 0x47, 0x1b, 0x5c, 0x9c, 0x07, 0x1b, 0x80, 0xf4, 0x4f, 0xe3, 0xfb, 0xbe, 0xec, 0xe3, 0x38, + 0x74, 0x2a, 0x98, 0x40, 0x40, 0x52, 0x02, 0xa2, 0xf2, 0xcd, 0xa6, 0x1b, 0x48, 0x22, 0x3b, 0x73, + 0xca, 0xfb, 0x96, 0x35, 0x52, 0xa8, 0x17, 0xfb, 0xc2, 0x01, 0x4b, 0xbb, 0x8a, 0xde, 0xf9, 0x8b, + 0x83, 0xa5, 0x8f, 0x67, 0x7e, 0xe0, 0xe0, 0x14, 0x02, 0xa8, 0xbf, 0xb7, 0x5b, 0x1e, 0xa3, 0x8c, + 0x7f, 0x08, 0x01, 0x64, 0x7d, 0xef, 0x4c, 0x57, 0x7b, 0xde, 0x17, 0x24, 0x00, 0xc4, 0x9b, 0x53, + 0xd9, 0xe7, 0xec, 0xbf, 0xb2, 0x91, 0xe7, 0x82, 0x80, 0xa5, 0xc5, 0x7b, 0xbb, 0xbf, 0x55, 0x55, + 0x50, 0x6e, 0xf0, 0x57, 0x74, 0x0e, 0xee, 0x10, 0x0c, 0x04, 0x62, 0x9a, 0xaa, 0xac, 0x54, 0xf2, + 0xc1, 0x89, 0x4e, 0x8c, 0x7b, 0xc2, 0xe7, 0x8b, 0xe0, 0xe4, 0x78, 0x0e, 0x43, 0xcc, 0x1c, 0x87, + 0x80, 0xe4, 0x79, 0xe0, 0xa3, 0x83, 0xcf, 0x01, 0xc9, 0xe6, 0x0e, 0x4f, 0x01, 0xe7, 0x91, 0xbc, + 0x32, 0x18, 0xe5, 0xc1, 0x1c, 0x0b, 0x85, 0x4b, 0xb1, 0xf6, 0x37, 0x81, 0xc3, 0x9c, 0x0c, 0x0f, + 0x6c, 0x1f, 0x74, 0xdb, 0x6c, 0x1d, 0xfd, 0x70, 0xe6, 0x00, 0xae, 0x69, 0x18, 0xc3, 0xef, 0xa6, + 0x99, 0x74, 0xfe, 0x3b, 0xcf, 0xdb, 0xbe, 0x14, 0xe3, 0x09, 0x2d, 0x0b, 0x60, 0xfb, 0xa3, 0x1d, + 0xfb, 0x62, 0xae, 0x0f, 0xbf, 0x12, 0x09, 0xa1, 0x60, 0x2a, 0xce, 0x48, 0x15, 0xe6, 0x21, 0xc9, + 0xd4, 0xf1, 0x2a, 0xfe, 0x25, 0x7f, 0xf0, 0x51, 0xc6, 0x72, 0xb6, 0xf5, 0x8b, 0xc4, 0x56, 0x20, + 0x27, 0x55, 0xf5, 0x6f, 0x89, 0x13, 0xb3, 0x35, 0x8c, 0x2f, 0xe2, 0x2b, 0xbb, 0x45, 0xbf, 0x89, + 0x1f, 0x8f, 0x1c, 0x3b, 0x1d, 0xa8, 0x88, 0xf8, 0xec, 0x47, 0xd2, 0xbb, 0xcb, 0xbe, 0x14, 0xb8, + 0xac, 0x74, 0xb0, 0x6b, 0x2e, 0x3f, 0x92, 0xda, 0xb2, 0x83, 0xcb, 0x24, 0xe8, 0x60, 0x22, 0xb2, + 0xe7, 0xf2, 0x7e, 0x09, 0xaa, 0xe7, 0xc1, 0x34, 0xad, 0xab, 0xfa, 0x2f, 0x5c, 0xdd, 0xfd, 0x0d, + 0x72, 0xde, 0xee, 0x4e, 0xee, 0xf7, 0xf1, 0x17, 0x77, 0xed, 0x36, 0xf0, 0xc0, 0x90, 0x57, 0x07, + 0x11, 0xf9, 0x3d, 0xfe, 0x21, 0xc1, 0x0e, 0x6e, 0x93, 0x1c, 0x22, 0x08, 0x41, 0x67, 0x8a, 0xc1, + 0xdb, 0x01, 0x80, 0xef, 0x14, 0x42, 0x51, 0xe0, 0x05, 0x83, 0xb6, 0x2f, 0xc8, 0x78, 0x0b, 0x9d, + 0xfa, 0x5e, 0x24, 0x1c, 0x02, 0xcb, 0x54, 0x8d, 0x8c, 0xef, 0x18, 0x80, 0x70, 0xa4, 0x24, 0xe5, + 0x49, 0x9c, 0x83, 0xf9, 0x72, 0xc2, 0x78, 0x02, 0xa7, 0x91, 0xa6, 0xfb, 0x59, 0x75, 0xbf, 0x8d, + 0x3d, 0x4b, 0xf7, 0x87, 0x14, 0x00, 0xea, 0xcf, 0x02, 0x4c, 0xe1, 0xc6, 0x3a, 0x97, 0x83, 0x4e, + 0xb1, 0x7f, 0xf9, 0x8d, 0xbe, 0x9f, 0x86, 0x00, 0x90, 0x14, 0xbe, 0xdc, 0x88, 0xb9, 0x71, 0x17, + 0x58, 0xa3, 0x14, 0x6e, 0x2b, 0x7b, 0x8a, 0xe2, 0xf0, 0x24, 0x02, 0x2d, 0xdd, 0xe3, 0x98, 0x63, + 0x14, 0x05, 0x6b, 0x88, 0xbf, 0xff, 0xdd, 0xc1, 0x08, 0x0c, 0x01, 0xd1, 0x46, 0x5b, 0x7c, 0x4c, + 0xcd, 0xef, 0xc1, 0x40, 0x08, 0x00, 0x55, 0xc1, 0xf6, 0x6c, 0xc2, 0xbe, 0x8b, 0xd5, 0x45, 0xdf, + 0x82, 0x80, 0x70, 0x1d, 0xa7, 0x56, 0xcf, 0xfd, 0x44, 0x1c, 0x10, 0x73, 0x85, 0x06, 0xc6, 0x35, + 0x92, 0x98, 0xc2, 0xba, 0x65, 0xdf, 0xf8, 0x60, 0x41, 0x75, 0xae, 0x20, 0x47, 0xc4, 0x5e, 0xf7, + 0x12, 0xe7, 0xe7, 0xbf, 0xf1, 0x9e, 0xde, 0x20, 0x77, 0x56, 0xa6, 0xf3, 0x75, 0x54, 0xeb, 0x8b, + 0x9b, 0x0d, 0x8a, 0x5e, 0xd1, 0x3c, 0x9d, 0x71, 0xf4, 0x37, 0x73, 0x64, 0x97, 0xa5, 0x0e, 0xc4, + 0xfa, 0x8a, 0xa5, 0xc4, 0x5f, 0xbb, 0x61, 0xae, 0xee, 0xff, 0x96, 0xb5, 0xa8, 0x8d, 0x77, 0x7b, + 0xf1, 0x21, 0x91, 0x95, 0x76, 0x55, 0xd9, 0xca, 0x8d, 0x66, 0xff, 0x3f, 0x55, 0xf0, 0x4f, 0x26, + 0x47, 0xcd, 0x18, 0x71, 0x51, 0xf8, 0x60, 0x05, 0x00, 0x52, 0x48, 0x0e, 0xd8, 0x36, 0xa7, 0x87, + 0x8e, 0xd8, 0xda, 0x12, 0x05, 0x72, 0xc0, 0x6a, 0xd4, 0x5e, 0x7c, 0x78, 0x0f, 0x88, 0x63, 0xa3, + 0xb8, 0x68, 0x90, 0x28, 0xba, 0xf7, 0x17, 0xf7, 0xbe, 0xdd, 0x3f, 0xa6, 0xe1, 0x10, 0x87, 0x02, + 0xc0, 0x38, 0xf8, 0xad, 0xef, 0xc5, 0xf8, 0x1c, 0x41, 0x27, 0x55, 0x7e, 0x0a, 0x01, 0x87, 0x82, + 0x00, 0x96, 0x34, 0xb8, 0xaa, 0xab, 0xc0, 0xc0, 0x14, 0xe9, 0xc1, 0xdb, 0xe5, 0xb1, 0x43, 0x14, + 0x32, 0x5a, 0x9c, 0x1c, 0xcf, 0x4e, 0x21, 0xc1, 0x0f, 0x38, 0x00, 0x72, 0x8b, 0xf8, 0x67, 0x5c, + 0x11, 0x4f, 0x85, 0x8d, 0x06, 0x8b, 0x8c, 0x44, 0xb9, 0xfe, 0xf8, 0x2b, 0xd3, 0xbc, 0xf9, 0xb7, + 0x37, 0xbf, 0xc5, 0x74, 0xcb, 0x49, 0x7c, 0xbf, 0x88, 0x19, 0xc6, 0x7d, 0xd5, 0x2d, 0xdf, 0xdc, + 0xfb, 0xad, 0x7c, 0x67, 0x15, 0xac, 0xda, 0xb9, 0x12, 0xd6, 0xe6, 0x1f, 0xcd, 0xff, 0xc1, 0x2c, + 0xff, 0xad, 0x55, 0xdc, 0x4d, 0xc2, 0xda, 0xb9, 0x86, 0x78, 0x9e, 0xee, 0xef, 0x93, 0x98, 0xef, + 0x7f, 0x84, 0xcd, 0x7b, 0xde, 0xeb, 0x12, 0x0a, 0x62, 0x0f, 0x51, 0x43, 0x17, 0x0b, 0x1b, 0x85, + 0xf2, 0x20, 0xc0, 0x47, 0x27, 0xee, 0x0c, 0x41, 0x88, 0xae, 0x1c, 0x43, 0x93, 0xe7, 0x89, 0x08, + 0x05, 0x23, 0xfe, 0x78, 0xf6, 0x72, 0x56, 0x84, 0xe7, 0x07, 0x70, 0xbe, 0x4e, 0xf9, 0x55, 0x8b, + 0xc4, 0x72, 0xb8, 0x44, 0x30, 0x0a, 0xe5, 0x98, 0x83, 0xc5, 0x36, 0x72, 0x7e, 0x31, 0x2f, 0x73, + 0x7a, 0x8b, 0xc4, 0xb8, 0x3b, 0x70, 0x24, 0x01, 0x23, 0x86, 0x7c, 0x20, 0x0a, 0x01, 0x61, 0x62, + 0x39, 0xbe, 0x2f, 0x8b, 0xab, 0x9c, 0x40, 0x30, 0x04, 0x75, 0xae, 0xb8, 0x28, 0x02, 0x03, 0xaa, + 0xf8, 0x60, 0x0b, 0x01, 0x02, 0x2d, 0x6b, 0xae, 0xef, 0x84, 0x21, 0x48, 0xac, 0xfd, 0xae, 0x45, + 0xc8, 0x7d, 0x1c, 0x03, 0xf8, 0xba, 0x8a, 0x64, 0xf0, 0xe8, 0x15, 0xb7, 0x4e, 0x06, 0x34, 0x3e, + 0x55, 0x0e, 0x60, 0x12, 0x87, 0x25, 0x86, 0xbd, 0xeb, 0xee, 0x9a, 0x76, 0xd3, 0x4f, 0x6c, 0xf7, + 0x4f, 0x74, 0x76, 0x59, 0x33, 0x2e, 0xbc, 0x3a, 0xe3, 0x11, 0xd3, 0x4f, 0x6d, 0xbf, 0x0c, 0x51, + 0x11, 0xe1, 0xe8, 0x09, 0x43, 0x94, 0xd5, 0x22, 0xe0, 0xf0, 0x1e, 0x1e, 0x03, 0xca, 0x22, 0x09, + 0x2f, 0xc5, 0x5b, 0x7e, 0x0a, 0x29, 0x0e, 0x78, 0xb0, 0x67, 0x03, 0x9c, 0x50, 0x18, 0x91, 0xe2, + 0x09, 0x21, 0x04, 0x97, 0x93, 0xc7, 0x73, 0x7c, 0x56, 0x38, 0xac, 0xdd, 0x27, 0x6e, 0x7e, 0x23, + 0x4a, 0xa7, 0xdc, 0x1e, 0xfb, 0x45, 0x7e, 0x31, 0x31, 0x99, 0xcf, 0x81, 0xdb, 0xa2, 0xae, 0x99, + 0x23, 0x72, 0x8c, 0x70, 0xc4, 0xf8, 0x81, 0x02, 0xfb, 0xbe, 0x5a, 0x78, 0x82, 0x49, 0x17, 0xf1, + 0x30, 0x85, 0x37, 0x4e, 0x0f, 0xfc, 0x93, 0x36, 0x6a, 0xd7, 0x96, 0xaa, 0xe9, 0x05, 0xf9, 0x6b, + 0x5f, 0x92, 0xf7, 0x6c, 0xbc, 0x5e, 0xef, 0x7d, 0xf1, 0x01, 0x8e, 0x11, 0x07, 0x26, 0xad, 0x78, + 0x30, 0x02, 0x08, 0x52, 0xb1, 0xb5, 0x99, 0x98, 0xa8, 0xeb, 0xf2, 0x0e, 0xbf, 0x8a, 0xe2, 0xb0, + 0x75, 0x7b, 0xe1, 0xc7, 0x11, 0x32, 0xa7, 0x57, 0x4e, 0x9a, 0x69, 0xa7, 0xb0, 0x98, 0x4d, 0xb6, + 0x73, 0x2f, 0x32, 0x74, 0x45, 0xef, 0xf0, 0x40, 0x18, 0x13, 0x27, 0xee, 0xbb, 0x6f, 0x83, 0x0f, + 0x02, 0xc8, 0x23, 0xe2, 0x78, 0xd7, 0xb0, 0x9e, 0x02, 0x1a, 0xba, 0x97, 0x7f, 0xfe, 0xff, 0x17, + 0xc5, 0x6e, 0xee, 0xf9, 0xd4, 0x0f, 0xd2, 0x1e, 0x0a, 0x40, 0xb0, 0x14, 0xa9, 0x7a, 0x45, 0xc5, + 0x29, 0xea, 0x1d, 0x98, 0x38, 0x00, 0x70, 0x28, 0xa9, 0xc0, 0x38, 0xd9, 0x15, 0x1a, 0xa4, 0xfd, + 0xe8, 0x76, 0x0d, 0x56, 0xb7, 0x32, 0x65, 0x63, 0x0e, 0x28, 0x0a, 0x0b, 0x34, 0x45, 0x81, 0x4a, + 0x69, 0x8b, 0x4c, 0xb7, 0xc7, 0x02, 0x21, 0x8a, 0x6c, 0xf1, 0xa7, 0x58, 0x3b, 0xf4, 0xf2, 0xd6, + 0x0e, 0xfc, 0x41, 0xd0, 0xe4, 0xb6, 0xdb, 0x76, 0x9a, 0x4d, 0x38, 0x74, 0x90, 0x05, 0x29, 0x20, + 0xd8, 0xc4, 0x10, 0x36, 0x35, 0x7f, 0xec, 0x1c, 0x97, 0x67, 0x51, 0xd5, 0xee, 0xde, 0xb0, 0x71, + 0x7c, 0x77, 0xef, 0xa1, 0x62, 0xc1, 0xc6, 0xfa, 0x84, 0x82, 0xde, 0xb3, 0x4c, 0x1f, 0x71, 0xf7, + 0xfc, 0x32, 0x04, 0x10, 0xa4, 0x48, 0xb0, 0x84, 0x00, 0x54, 0x12, 0x02, 0xc0, 0xaa, 0x0d, 0x4b, + 0x2c, 0x3a, 0xc2, 0x95, 0x1d, 0x3c, 0x2c, 0x65, 0xea, 0x76, 0x2f, 0x50, 0xf0, 0x51, 0x20, 0x97, + 0xb9, 0x3f, 0xf8, 0x27, 0x9f, 0xf8, 0xfe, 0x31, 0xd7, 0xc1, 0x27, 0x56, 0x9c, 0xbe, 0x49, 0x33, + 0xfc, 0x10, 0xc9, 0x88, 0xfe, 0xf1, 0x24, 0xaa, 0x5f, 0x88, 0x93, 0x3a, 0xad, 0x2f, 0x3d, 0x4f, + 0xad, 0xff, 0xe1, 0x3b, 0xbe, 0xb1, 0x4e, 0x14, 0xe4, 0xaa, 0xaa, 0x9f, 0x96, 0xf7, 0x75, 0xcb, + 0xdd, 0xd4, 0x14, 0xdd, 0xef, 0xc1, 0x88, 0x91, 0x95, 0x57, 0x8b, 0x92, 0x85, 0x54, 0xbc, 0x57, + 0x69, 0xeb, 0x5c, 0x08, 0x00, 0x24, 0x01, 0x5f, 0xbb, 0xe2, 0xe2, 0x3b, 0x72, 0xc7, 0x7c, 0x33, + 0x84, 0x00, 0x91, 0x65, 0x3d, 0xb6, 0xfd, 0x3f, 0xc3, 0x11, 0x0e, 0x12, 0x2e, 0xa6, 0xc2, 0x00, + 0x68, 0x35, 0xdd, 0xf8, 0x98, 0x9a, 0xd7, 0xbb, 0xcf, 0x84, 0xdf, 0x7e, 0xc3, 0xd8, 0x00, 0xa4, + 0x38, 0x55, 0xce, 0x60, 0xfc, 0xe3, 0x5f, 0x3c, 0x9c, 0xd4, 0x0a, 0x1c, 0x0d, 0x19, 0x2e, 0x36, + 0xdb, 0xb9, 0x41, 0xb1, 0x7d, 0x48, 0x5c, 0xbb, 0xd8, 0x38, 0x29, 0x02, 0x8b, 0x83, 0xaf, 0x9f, + 0xc7, 0x06, 0xd7, 0x0e, 0x77, 0x88, 0x01, 0x12, 0x14, 0x9e, 0x70, 0xcc, 0x2c, 0xe1, 0xe0, 0x58, + 0x3c, 0xb5, 0x80, 0x80, 0xab, 0x1d, 0x80, 0xa8, 0xd1, 0x18, 0xfd, 0xbe, 0x9c, 0x07, 0x96, 0x59, + 0xc1, 0xee, 0xa8, 0xbb, 0xa8, 0x50, 0x4a, 0x87, 0xe0, 0x50, 0x4a, 0x82, 0x4a, 0x0e, 0x27, 0x87, + 0x5c, 0x03, 0x38, 0xed, 0x4f, 0xc2, 0x35, 0x7f, 0x56, 0xff, 0x5b, 0x3d, 0x71, 0xed, 0x97, 0xd7, + 0xfc, 0x1a, 0x01, 0xa1, 0x83, 0x4d, 0x3f, 0xe1, 0xe5, 0x01, 0x35, 0xda, 0x27, 0x5d, 0x7b, 0x7c, + 0x77, 0xaa, 0x6b, 0x5b, 0xbd, 0xf9, 0x6b, 0xaf, 0xf8, 0x65, 0x40, 0x40, 0xa8, 0xe5, 0xf7, 0x69, + 0xff, 0xbd, 0xbf, 0xaf, 0x92, 0xab, 0x88, 0xc4, 0x05, 0x24, 0x48, 0xb1, 0x3e, 0x2e, 0x65, 0x05, + 0x9c, 0xc5, 0xf1, 0x1f, 0x14, 0xf8, 0xd0, 0xef, 0x2e, 0xef, 0x50, 0x40, 0x0e, 0x3c, 0x40, 0xcc, + 0x53, 0x9b, 0xaa, 0xb3, 0x26, 0xb3, 0x7c, 0xb8, 0x99, 0x6f, 0x02, 0x00, 0x18, 0x02, 0x92, 0x79, + 0x1e, 0x5f, 0x0a, 0x8c, 0x1a, 0x47, 0x8e, 0x67, 0xc5, 0x0b, 0x93, 0x05, 0x73, 0x31, 0xe5, 0x66, + 0x70, 0xf6, 0x10, 0x0c, 0xb3, 0x3f, 0x7e, 0x8d, 0x32, 0x56, 0xb4, 0xd3, 0x15, 0x6d, 0xb6, 0x6a, + 0xe5, 0xd9, 0xb7, 0xcf, 0xf4, 0xd3, 0xb7, 0x81, 0x40, 0x22, 0x0b, 0x3a, 0xa8, 0x52, 0xb9, 0x63, + 0x74, 0x82, 0xb5, 0x15, 0x9e, 0xfc, 0xb8, 0x44, 0x1c, 0x8c, 0xbb, 0xdd, 0xee, 0xf1, 0x4b, 0x7b, + 0xcd, 0x90, 0xab, 0x80, 0x46, 0xec, 0xa8, 0x09, 0xef, 0xff, 0xfc, 0x30, 0x02, 0x80, 0x16, 0x54, + 0x48, 0x7a, 0x45, 0xd2, 0xd4, 0x53, 0x10, 0x3c, 0xf1, 0xc3, 0xc0, 0xe1, 0xc7, 0xeb, 0x0e, 0x60, + 0x08, 0xcc, 0xdc, 0x65, 0x50, 0x27, 0x5d, 0x34, 0xe3, 0x1f, 0x72, 0x79, 0xe9, 0xa7, 0x3e, 0xe4, + 0x63, 0x45, 0xe9, 0xa7, 0xb7, 0xe2, 0x61, 0x4e, 0xaa, 0xa9, 0x23, 0xba, 0x47, 0xf1, 0x45, 0x7d, + 0x5a, 0x97, 0x04, 0x20, 0x69, 0x0a, 0x4b, 0x62, 0xb7, 0xc4, 0x9c, 0x83, 0x10, 0x95, 0x38, 0x9e, + 0xc9, 0x93, 0x8d, 0xb1, 0x17, 0xc0, 0xb0, 0x0a, 0x01, 0x54, 0x40, 0xf1, 0x8e, 0x0d, 0x45, 0xf5, + 0xb8, 0x1a, 0x3f, 0xed, 0xb6, 0x81, 0xa8, 0x96, 0x1f, 0xa5, 0x17, 0x80, 0x3b, 0xee, 0x0c, 0x04, + 0x29, 0x8b, 0x4e, 0x3d, 0x97, 0x8b, 0xd3, 0xac, 0xaf, 0x6e, 0x06, 0x1d, 0xe6, 0xbd, 0xe2, 0x31, + 0x3c, 0x40, 0x44, 0x92, 0xf2, 0xdf, 0xe0, 0xab, 0x6d, 0xe0, 0xe9, 0x60, 0x1d, 0xa5, 0x0e, 0x84, + 0x67, 0x80, 0x78, 0xa0, 0x1c, 0xbb, 0xe3, 0x83, 0x00, 0x34, 0x04, 0x6a, 0x2f, 0x49, 0x78, 0xf7, + 0x38, 0x97, 0x26, 0x71, 0x00, 0x84, 0x7d, 0x2b, 0xcb, 0x27, 0xe2, 0xce, 0xaf, 0xe3, 0x35, 0x34, + 0x2f, 0xd5, 0x71, 0x5b, 0xd6, 0xb8, 0x42, 0x32, 0xee, 0xa6, 0xc7, 0xca, 0xa4, 0xcc, 0xbe, 0xad, + 0x8b, 0xf0, 0x88, 0xcd, 0xc9, 0xb7, 0x7a, 0xad, 0xab, 0xc5, 0xc4, 0x6b, 0x1a, 0x31, 0xe0, 0xa6, + 0xb1, 0x1c, 0x58, 0xf2, 0xa9, 0x67, 0x5d, 0xdd, 0x7b, 0x81, 0x20, 0x1c, 0x8c, 0x9c, 0x01, 0xc1, + 0x40, 0xdb, 0x92, 0xbb, 0xe2, 0xeb, 0x2f, 0xbe, 0x04, 0x10, 0x42, 0x08, 0xeb, 0x55, 0xef, 0x89, + 0x9f, 0x1a, 0xad, 0x23, 0x64, 0x9b, 0xaf, 0x9f, 0x0a, 0x79, 0x73, 0x10, 0xe0, 0x64, 0x7e, 0x7b, + 0xfa, 0xdb, 0xe1, 0xe2, 0x02, 0x5d, 0xd4, 0x5c, 0x98, 0xb3, 0xe5, 0xe7, 0xf3, 0x72, 0xdd, 0xf0, + 0xa7, 0x25, 0xef, 0xf2, 0x6e, 0xee, 0x28, 0x56, 0x06, 0xb9, 0x91, 0xcc, 0x30, 0x24, 0xdb, 0xaf, + 0x82, 0x10, 0x9e, 0xad, 0x4b, 0x8f, 0x6b, 0x89, 0x05, 0x78, 0xb4, 0x89, 0xdc, 0xcc, 0x08, 0x1c, + 0x6e, 0x26, 0x58, 0xab, 0xcc, 0x3b, 0x85, 0xa3, 0xb8, 0x98, 0x46, 0xbc, 0x5c, 0x3e, 0x54, 0x97, + 0x1c, 0xa4, 0x5c, 0x5c, 0x5d, 0x70, 0x13, 0x01, 0x91, 0x27, 0x26, 0x4f, 0x5b, 0xbf, 0x8e, 0x21, + 0x33, 0x5e, 0xee, 0xab, 0xf0, 0x88, 0x2c, 0xb8, 0x8e, 0x3d, 0x6a, 0x2e, 0xaa, 0x6c, 0xe4, 0x5c, + 0xea, 0xe0, 0xe2, 0x14, 0x92, 0x00, 0x15, 0x3b, 0x87, 0x1c, 0xd2, 0x07, 0xac, 0x7b, 0x55, 0x17, + 0x57, 0x6d, 0xd7, 0xdf, 0x05, 0x10, 0x74, 0x58, 0x2e, 0x58, 0x01, 0x88, 0x03, 0xd6, 0x77, 0xaf, + 0x7c, 0xbc, 0x5e, 0x4e, 0x08, 0xb0, 0xef, 0xbf, 0x7d, 0x79, 0xd7, 0x10, 0x0a, 0xa8, 0x79, 0xd8, + 0xcb, 0x8d, 0xd6, 0xaf, 0xf0, 0x47, 0x13, 0xa7, 0xb0, 0x7c, 0xb7, 0x9f, 0xdf, 0x7b, 0xdc, 0x3f, + 0x12, 0x10, 0xe0, 0x49, 0x02, 0x0f, 0x12, 0x24, 0x99, 0x33, 0xe1, 0x11, 0xf6, 0x64, 0x3a, 0xde, + 0xba, 0xd5, 0x61, 0x9e, 0x0c, 0x42, 0x18, 0xa2, 0x43, 0xad, 0x3e, 0x05, 0x00, 0x28, 0x12, 0xa0, + 0x7e, 0x4b, 0xf1, 0x02, 0x41, 0x54, 0xb0, 0xce, 0x38, 0x23, 0x92, 0x59, 0x85, 0x8f, 0xba, 0xae, + 0x77, 0x1c, 0x22, 0x24, 0x17, 0x6b, 0x57, 0xee, 0xef, 0xe2, 0x02, 0x9a, 0xd5, 0xa3, 0x32, 0xb2, + 0xf1, 0x00, 0x0e, 0x05, 0x41, 0x51, 0xcf, 0x4a, 0xb6, 0x3c, 0xb8, 0x81, 0x01, 0x2d, 0x5e, 0xab, + 0x5f, 0x5e, 0x82, 0x68, 0x99, 0xb7, 0xba, 0xe5, 0xee, 0xaa, 0x08, 0x00, 0xa0, 0x52, 0xbb, 0xfc, + 0x10, 0x12, 0xa2, 0xf5, 0xc0, 0xb2, 0x0e, 0x5d, 0x6b, 0xc1, 0xc7, 0x15, 0x9f, 0x21, 0x67, 0x04, + 0x22, 0xaa, 0xbf, 0xff, 0xa7, 0xf1, 0x38, 0x10, 0xf5, 0xa2, 0xbf, 0x07, 0x00, 0xa1, 0xd5, 0x55, + 0x70, 0x80, 0x40, 0x4d, 0x57, 0xd5, 0x70, 0x43, 0x1e, 0x4a, 0xaa, 0xc4, 0xb9, 0xae, 0x21, 0xcc, + 0x1c, 0xc1, 0x66, 0x45, 0xd7, 0x2e, 0x0a, 0x32, 0xc7, 0xc5, 0x6f, 0x98, 0x61, 0x80, 0x88, 0x52, + 0x91, 0x28, 0xf6, 0x4c, 0x10, 0x07, 0x20, 0xd9, 0x87, 0xee, 0xc2, 0xab, 0x62, 0x4e, 0x05, 0x6a, + 0x8c, 0xf0, 0x0e, 0x1e, 0x1a, 0x23, 0x1f, 0x82, 0x8d, 0x45, 0x0d, 0x6a, 0xaa, 0x9e, 0xf9, 0xaa, + 0x6c, 0x52, 0xc0, 0xf8, 0x82, 0xf0, 0xb1, 0x5c, 0x13, 0x88, 0x94, 0x15, 0xd8, 0xa7, 0x90, 0x16, + 0xaa, 0xcc, 0x18, 0x83, 0x13, 0x75, 0x59, 0xf0, 0x42, 0x74, 0xae, 0xb8, 0x9c, 0x0c, 0xa6, 0x87, + 0x88, 0x2d, 0xee, 0xb4, 0xb1, 0x4e, 0x10, 0xeb, 0xa5, 0x15, 0x84, 0x8c, 0xe1, 0xe1, 0xa6, 0x60, + 0x23, 0xaf, 0x1c, 0x37, 0x1f, 0xdf, 0xef, 0xb6, 0x1c, 0x24, 0x00, 0x31, 0x30, 0x6a, 0x91, 0xe1, + 0x00, 0xfc, 0x71, 0xb6, 0xdb, 0x37, 0x6f, 0x5d, 0xeb, 0x10, 0xfd, 0xb3, 0x76, 0xdd, 0xc4, 0xe8, + 0xcd, 0x3d, 0x3f, 0xc1, 0x00, 0x44, 0x29, 0x5f, 0x99, 0x38, 0x15, 0x92, 0xcc, 0xb0, 0xd6, 0x64, + 0x14, 0xa9, 0xcf, 0x95, 0x38, 0x3e, 0x71, 0x2e, 0x2f, 0xde, 0x25, 0xcb, 0x0d, 0x4e, 0xe4, 0x4e, + 0x22, 0x4c, 0x49, 0xf1, 0x27, 0xf1, 0x20, 0xa6, 0x78, 0x07, 0x84, 0x70, 0x4a, 0x78, 0x06, 0x87, + 0x9a, 0xc5, 0xc7, 0xac, 0x51, 0x07, 0x0e, 0xfc, 0xf1, 0xf0, 0x4d, 0x86, 0x28, 0x43, 0x28, 0x7d, + 0x97, 0xc2, 0x20, 0x80, 0x95, 0x5d, 0x44, 0x84, 0x5d, 0x54, 0x99, 0xf1, 0x15, 0x84, 0x68, 0x3d, + 0x20, 0x01, 0xb8, 0x1f, 0x15, 0x50, 0x09, 0xcc, 0xbf, 0x17, 0x97, 0xa6, 0xdf, 0x1c, 0x97, 0x60, + 0xfb, 0xfa, 0x73, 0xed, 0x5f, 0xf0, 0xb9, 0x20, 0x17, 0xe5, 0xc5, 0x13, 0xf7, 0xfe, 0xa9, 0xaf, + 0xbd, 0xfe, 0x44, 0x31, 0xf9, 0x4a, 0xdc, 0x56, 0x90, 0x2d, 0xe0, 0x8a, 0xef, 0xbf, 0x0c, 0x89, + 0xe1, 0x10, 0x50, 0x3c, 0xbb, 0xba, 0xaf, 0x7b, 0x98, 0x33, 0x81, 0x16, 0xe6, 0x7a, 0x9f, 0xdf, + 0xfe, 0x58, 0xc4, 0x60, 0x11, 0x30, 0xe4, 0xcf, 0x37, 0x0c, 0x82, 0x91, 0x75, 0x5d, 0xdd, 0xc5, + 0x60, 0xaf, 0x11, 0xe1, 0x9f, 0x08, 0xf8, 0x66, 0x7c, 0x43, 0xbb, 0xe4, 0xe6, 0xd6, 0xa0, 0xdf, + 0x93, 0x7b, 0xf9, 0xaf, 0x78, 0x04, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x38, 0x1c, 0x30, + 0x52, 0x2f, 0x77, 0x7c, 0x4e, 0x24, 0x49, 0x5e, 0xfb, 0xdc, 0x15, 0xe2, 0x24, 0xef, 0xbb, 0x96, + 0x0a, 0x02, 0x2c, 0x8e, 0xfe, 0x0a, 0x23, 0x22, 0xb0, 0xb0, 0x2a, 0xef, 0xa0, 0xeb, 0xe4, 0xe5, + 0xbd, 0xb5, 0xaa, 0x6f, 0x36, 0xfe, 0x08, 0x04, 0x02, 0xac, 0x57, 0x12, 0xe3, 0xbd, 0xbb, 0x44, + 0xe2, 0x4e, 0x1f, 0xc8, 0xbe, 0x5e, 0x9b, 0xae, 0x5f, 0x2e, 0x02, 0xae, 0x42, 0xcb, 0xff, 0x36, + 0xf7, 0x2c, 0x21, 0x08, 0x92, 0xca, 0x0d, 0xa4, 0x0a, 0xb5, 0x93, 0x9a, 0x3d, 0x2c, 0x48, 0x91, + 0xd6, 0xd5, 0xfd, 0x5d, 0x13, 0x1a, 0xa4, 0x75, 0x96, 0xec, 0x66, 0x9f, 0x82, 0x6c, 0xaa, 0xaa, + 0xad, 0x7d, 0xf0, 0x4f, 0x14, 0x0c, 0xef, 0x12, 0x58, 0x93, 0x79, 0xac, 0xdc, 0x31, 0x36, 0xb5, + 0xc2, 0x17, 0xad, 0x71, 0x11, 0x12, 0x7a, 0xb2, 0x7a, 0xf8, 0x91, 0x77, 0x76, 0x9a, 0x15, 0xed, + 0x02, 0xf8, 0x80, 0xc8, 0xcd, 0x55, 0xb8, 0x8f, 0x4f, 0x51, 0x5e, 0x78, 0x5c, 0x4b, 0xfc, 0x55, + 0xba, 0x0d, 0xb3, 0x7e, 0xbe, 0x09, 0xb8, 0xe2, 0xe5, 0xe9, 0x7e, 0xf8, 0xa8, 0xba, 0x89, 0xf9, + 0x6d, 0x5d, 0x2e, 0x23, 0xc2, 0x15, 0x08, 0x08, 0x11, 0x4f, 0x3d, 0xbb, 0xfc, 0x20, 0x22, 0x0b, + 0x79, 0xb5, 0xaf, 0x82, 0xc9, 0xc1, 0x01, 0xb7, 0xb6, 0x2f, 0x57, 0x7b, 0xc7, 0x3e, 0x09, 0x2b, + 0x5b, 0xb8, 0x98, 0xfb, 0xbb, 0x57, 0xbd, 0x57, 0xf0, 0x8d, 0xad, 0xed, 0xbb, 0xaa, 0xcd, 0x4e, + 0x24, 0x21, 0x77, 0x7e, 0xab, 0x5a, 0x48, 0x44, 0xa1, 0xc4, 0x7e, 0x52, 0x5d, 0xc5, 0x6a, 0x10, + 0x96, 0x7f, 0x46, 0xb8, 0x28, 0xf0, 0x40, 0x23, 0x86, 0x30, 0x55, 0x89, 0x13, 0x0a, 0xab, 0x11, + 0xe3, 0xea, 0x12, 0x0f, 0xc4, 0x3c, 0xff, 0xc2, 0x7b, 0xdd, 0x3b, 0xfc, 0x23, 0xaa, 0x8b, 0x7b, + 0x93, 0x05, 0xd3, 0x2f, 0x55, 0xc1, 0x25, 0x32, 0xb2, 0x5e, 0x72, 0xcc, 0x5c, 0x4c, 0x66, 0x91, + 0x3b, 0xf0, 0x67, 0x4e, 0x95, 0x72, 0x61, 0xb8, 0x5f, 0x76, 0xc7, 0x43, 0xc2, 0x01, 0x0f, 0x82, + 0x5b, 0xbb, 0xf5, 0x5f, 0x1f, 0x35, 0xee, 0xf8, 0x98, 0x8b, 0x9f, 0xcf, 0x8d, 0x77, 0xc4, 0x49, + 0xbd, 0xfc, 0xba, 0x85, 0x63, 0x26, 0x0a, 0xb9, 0xb7, 0x8a, 0xf1, 0x02, 0x02, 0x90, 0x7b, 0xef, + 0xe6, 0xd5, 0x7f, 0xb0, 0x8b, 0xc9, 0x0e, 0x21, 0x0e, 0x6b, 0x48, 0xbe, 0xb9, 0x71, 0x22, 0x4b, + 0xad, 0x70, 0x88, 0x81, 0xf4, 0xeb, 0xc3, 0x2a, 0xbf, 0xab, 0xb9, 0xd8, 0xbe, 0x24, 0x15, 0xd3, + 0x93, 0xe6, 0x2f, 0x54, 0xfe, 0xe2, 0x63, 0xad, 0x2d, 0x59, 0xd6, 0xd5, 0x2d, 0xed, 0xd5, 0x2c, + 0x4c, 0x29, 0x6e, 0xa9, 0xa3, 0xd2, 0x39, 0x96, 0xb3, 0x1e, 0x5f, 0x2e, 0x35, 0x9e, 0x25, 0x3e, + 0x2d, 0xfa, 0xe1, 0x18, 0x4a, 0xf6, 0x3d, 0xe5, 0xac, 0x22, 0x24, 0x9d, 0x4d, 0xf0, 0x80, 0x81, + 0x3e, 0x6c, 0x59, 0xf1, 0x10, 0x87, 0x36, 0x47, 0xb2, 0x96, 0x64, 0x8b, 0xff, 0x25, 0x47, 0x19, + 0x12, 0xf5, 0xcc, 0x37, 0x8d, 0x7a, 0x14, 0x93, 0xff, 0xe6, 0xdd, 0x39, 0x78, 0x28, 0x10, 0x2e, + 0x6a, 0x66, 0xa5, 0x9d, 0xbe, 0x5b, 0x56, 0x31, 0x23, 0x00, 0xf7, 0x2f, 0x55, 0xf1, 0x7a, 0xdb, + 0xd5, 0x35, 0xcb, 0xdd, 0xd0, 0x63, 0x00, 0x1d, 0xb7, 0x2e, 0x29, 0x3f, 0x7f, 0xef, 0x1c, 0xfa, + 0x63, 0xfe, 0x71, 0x4a, 0xab, 0xea, 0xfe, 0xbb, 0x96, 0xb6, 0xc5, 0x5c, 0x78, 0xd1, 0xab, 0xb4, + 0x52, 0xb3, 0xc3, 0x21, 0x3c, 0xac, 0xdf, 0x7c, 0x4c, 0x15, 0xd1, 0x5f, 0x9f, 0xbd, 0xdd, 0xdf, + 0xe1, 0x09, 0x32, 0x2b, 0x5d, 0xdf, 0x77, 0xc4, 0x89, 0x05, 0x51, 0x75, 0x53, 0x65, 0x36, 0x41, + 0x63, 0x50, 0xe5, 0xda, 0xf4, 0x1a, 0x75, 0x89, 0x96, 0x38, 0xb9, 0x66, 0x98, 0xbe, 0x2b, 0x4e, + 0xdd, 0x39, 0x61, 0xe0, 0xb2, 0xdc, 0xb8, 0x5c, 0x48, 0x57, 0xb4, 0x5b, 0x7d, 0x1a, 0x7d, 0xbf, + 0x10, 0x20, 0x64, 0x5d, 0x7e, 0x2b, 0x70, 0x79, 0xd0, 0xb4, 0xbf, 0x4d, 0xfc, 0x40, 0x62, 0xda, + 0xd6, 0x0d, 0xa3, 0x62, 0x6f, 0x8f, 0x7f, 0x8b, 0xf8, 0xbf, 0x0f, 0x8e, 0x4d, 0x2b, 0x50, 0xcf, + 0x36, 0xb5, 0x2c, 0x4f, 0xec, 0xab, 0xaf, 0x82, 0x22, 0x3d, 0xf5, 0x5c, 0x10, 0x59, 0x87, 0x1c, + 0xbd, 0x5d, 0xbc, 0x9e, 0xba, 0x92, 0xbf, 0xe0, 0x96, 0xcc, 0x2e, 0xfb, 0x96, 0xdb, 0xbb, 0xb8, + 0x81, 0x0b, 0xdc, 0x32, 0x24, 0x12, 0x77, 0x77, 0xf8, 0x23, 0xbb, 0x62, 0xb7, 0xee, 0x20, 0x48, + 0x27, 0x9f, 0x66, 0x98, 0x22, 0xb5, 0xb4, 0xba, 0xbf, 0x8b, 0xe5, 0x88, 0x7b, 0x8b, 0x67, 0xef, + 0x82, 0x4c, 0x0f, 0x8d, 0x4b, 0xcb, 0x00, 0x60, 0x22, 0x01, 0xfc, 0x3b, 0xe5, 0xcb, 0x62, 0xb6, + 0xce, 0x01, 0xc2, 0xc6, 0x4e, 0x0a, 0xaf, 0x50, 0xe8, 0x68, 0x37, 0x12, 0x54, 0xe7, 0xf6, 0xe2, + 0x3f, 0xdd, 0x6b, 0xf2, 0xe2, 0xfb, 0xe0, 0x86, 0x9e, 0xec, 0x7c, 0x97, 0x7f, 0x7f, 0xcd, 0x65, + 0x7f, 0x12, 0x09, 0x6a, 0x48, 0x6f, 0x93, 0x1a, 0x9b, 0xe5, 0xf0, 0x4b, 0x51, 0x76, 0x63, 0x39, + 0x3d, 0xcd, 0x23, 0xf0, 0x55, 0xde, 0xf0, 0xf8, 0x46, 0xeb, 0x22, 0xdb, 0x85, 0xf6, 0x52, 0x63, + 0xc4, 0x12, 0x0c, 0x9a, 0xaf, 0xaf, 0x9f, 0x2d, 0xef, 0x0f, 0xf1, 0x57, 0xc3, 0xca, 0xc4, 0x35, + 0xa6, 0x2a, 0xf1, 0x88, 0x12, 0x14, 0x8f, 0xe5, 0x5b, 0x8e, 0x79, 0x78, 0xba, 0xed, 0x5f, 0xe6, + 0x86, 0xab, 0xd8, 0x63, 0x00, 0x1f, 0x63, 0x9e, 0x7e, 0x24, 0x6e, 0xfe, 0x79, 0x34, 0xd3, 0x4d, + 0x34, 0xd3, 0x4c, 0xdc, 0xb5, 0xe7, 0xec, 0xdc, 0xa0, 0xdc, 0x2c, 0xc3, 0x15, 0x06, 0x7e, 0x0b, + 0x37, 0x6a, 0x07, 0x39, 0xa8, 0xff, 0x1e, 0x00, 0x03, 0x38, 0x70, 0x00, 0x15, 0xc6, 0x60, 0x9d, + 0x03, 0xf0, 0x35, 0x25, 0x15, 0x0d, 0xa9, 0x5e, 0x24, 0x32, 0x0b, 0x2e, 0x2b, 0x71, 0x58, 0x3a, + 0xb0, 0x1d, 0x2c, 0x66, 0x1c, 0x70, 0x71, 0xb0, 0x99, 0x51, 0xe5, 0x84, 0x9c, 0xbb, 0x84, 0x43, + 0x23, 0x22, 0x8c, 0x4b, 0xdc, 0xb6, 0xf6, 0xd4, 0xf1, 0xf7, 0x8a, 0xc4, 0x38, 0x1f, 0x1a, 0x96, + 0x0c, 0xe0, 0x01, 0xf0, 0xe2, 0x80, 0x14, 0x7c, 0x76, 0x90, 0x49, 0x7e, 0xa7, 0x7a, 0x65, 0xe0, + 0xdc, 0xa7, 0x87, 0x59, 0xa9, 0x6d, 0x96, 0xb2, 0xd6, 0xdc, 0xc9, 0xdb, 0xfc, 0x31, 0x80, 0x56, + 0x27, 0x34, 0x92, 0x2c, 0xb8, 0xb6, 0x23, 0xa3, 0x9a, 0x63, 0xd6, 0x83, 0xec, 0xff, 0x36, 0x3c, + 0x0b, 0x00, 0xaa, 0x27, 0x9e, 0xab, 0xd2, 0x71, 0x5b, 0xbc, 0x0b, 0x01, 0x48, 0x9f, 0x07, 0x8b, + 0xc8, 0x72, 0x90, 0xac, 0x51, 0xdd, 0xdc, 0x56, 0xf5, 0xc9, 0x16, 0x18, 0x03, 0x40, 0x52, 0x9d, + 0xdb, 0x15, 0xb9, 0xb2, 0xa6, 0x95, 0x45, 0xcb, 0x0c, 0x2f, 0x90, 0x41, 0xc2, 0xa2, 0x48, 0x06, + 0x43, 0xc3, 0xa4, 0x91, 0xe9, 0x80, 0xf2, 0x07, 0x7f, 0xc7, 0xfe, 0xef, 0xf0, 0x3b, 0x08, 0xa2, + 0x0e, 0xfe, 0x6a, 0x4f, 0xf0, 0xea, 0x80, 0x06, 0x23, 0xd1, 0x93, 0x5e, 0x4f, 0xf7, 0xc2, 0xa7, + 0x4a, 0x50, 0xfb, 0xff, 0x01, 0x95, 0x1a, 0xef, 0x7d, 0xf0, 0x47, 0x65, 0x7b, 0xc9, 0xc2, 0x54, + 0x4b, 0x9b, 0x3e, 0x27, 0xf0, 0x55, 0x49, 0x21, 0xee, 0x99, 0xb0, 0x89, 0x07, 0x6e, 0xd0, 0xe2, + 0xf8, 0xcd, 0xd5, 0x6b, 0x2e, 0xb3, 0x1d, 0xf5, 0x5d, 0x19, 0x22, 0x1b, 0xef, 0x7b, 0x93, 0x84, + 0x77, 0xbd, 0xde, 0xee, 0xff, 0x08, 0xe2, 0xae, 0xa6, 0xbc, 0xff, 0xc4, 0x3f, 0x10, 0x25, 0x72, + 0xf8, 0x47, 0xbe, 0x99, 0x70, 0x1c, 0xbc, 0x03, 0xa8, 0xd4, 0x74, 0x01, 0xe0, 0x3d, 0xe0, 0x51, + 0x53, 0xc0, 0x00, 0x8e, 0x1e, 0x03, 0xf0, 0x50, 0x11, 0x19, 0x22, 0x80, 0xc7, 0xc3, 0x02, 0x03, + 0xf4, 0xc9, 0x60, 0x00, 0x46, 0x70, 0x03, 0x81, 0xd5, 0x78, 0x76, 0x1a, 0xea, 0x3d, 0x54, 0xb3, + 0x4b, 0x77, 0x86, 0x70, 0x11, 0x82, 0xd0, 0x69, 0x69, 0xce, 0xf0, 0xff, 0xf9, 0x7a, 0xfa, 0x9b, + 0xf6, 0xdd, 0x6a, 0xec, 0x2a, 0x8a, 0x00, 0x60, 0x6e, 0xb4, 0xdb, 0xbe, 0xbd, 0xba, 0xff, 0xfc, + 0x10, 0x01, 0xe0, 0x24, 0x4b, 0xdd, 0x57, 0x85, 0x30, 0x07, 0xb5, 0x6e, 0x9e, 0xff, 0xfe, 0xdf, + 0x06, 0x03, 0xae, 0x2b, 0xbb, 0xbb, 0xf3, 0x53, 0x83, 0x10, 0x60, 0x11, 0x2d, 0x6b, 0x5a, 0xaa, + 0xa8, 0xbe, 0x08, 0x00, 0xa0, 0x11, 0x20, 0xda, 0xcf, 0x17, 0x55, 0x5a, 0x8b, 0x93, 0xe1, 0x10, + 0x62, 0x14, 0xd2, 0x03, 0x79, 0x21, 0x7f, 0x1e, 0x2c, 0x10, 0x72, 0xed, 0x29, 0x2d, 0xb6, 0xd3, + 0x41, 0x70, 0x2a, 0x78, 0x70, 0x48, 0x92, 0xf8, 0x9c, 0xdb, 0xbb, 0xf8, 0x9c, 0xbc, 0xda, 0xab, + 0x1f, 0x96, 0x6e, 0x4e, 0xee, 0xcf, 0xe1, 0x2d, 0x57, 0x92, 0x10, 0xef, 0x2d, 0xef, 0x7c, 0x99, + 0xf2, 0x96, 0x20, 0x48, 0x42, 0xd6, 0xac, 0x95, 0x55, 0x6a, 0xbc, 0x40, 0x53, 0xc2, 0xea, 0xe2, + 0x5c, 0x7f, 0xf8, 0xba, 0xf3, 0x77, 0xe2, 0x63, 0xe7, 0x70, 0x79, 0x66, 0x3c, 0xb0, 0x4e, 0x99, + 0x35, 0xc5, 0x67, 0xcc, 0x10, 0x00, 0xc8, 0x0a, 0x5f, 0x54, 0xb7, 0x37, 0x2c, 0xf1, 0x4d, 0x39, + 0x3c, 0x73, 0x1c, 0x1c, 0x26, 0xce, 0x01, 0xbf, 0x9f, 0xeb, 0xff, 0x5f, 0xe1, 0x99, 0x0d, 0x5a, + 0xc3, 0x28, 0xa1, 0x83, 0x02, 0xeb, 0xff, 0xfe, 0xac, 0x1c, 0x14, 0x93, 0x77, 0xf0, 0x80, 0x40, + 0x11, 0x56, 0x6a, 0xfc, 0x48, 0x60, 0x29, 0x12, 0x70, 0xbc, 0xb3, 0x17, 0x67, 0x3c, 0xf9, 0x2f, + 0x17, 0x35, 0x39, 0x06, 0x9a, 0x82, 0x4f, 0x2a, 0x05, 0x28, 0x8c, 0x7e, 0x26, 0xb5, 0x97, 0xf9, + 0xb9, 0x2c, 0xa5, 0xcf, 0x8a, 0xee, 0x53, 0x1b, 0xc4, 0x3f, 0xd5, 0xfe, 0x26, 0xdc, 0x8d, 0xdc, + 0xd6, 0x51, 0xfd, 0xcc, 0x2f, 0xc8, 0x11, 0x62, 0x42, 0x91, 0x4d, 0x45, 0x35, 0x36, 0x4c, 0x88, + 0xd0, 0x5d, 0x75, 0x3e, 0xc5, 0x7d, 0xc3, 0x20, 0x84, 0x4d, 0x57, 0xaa, 0x99, 0x54, 0xe2, 0x42, + 0x20, 0xb2, 0x2f, 0x8b, 0x83, 0xa5, 0xd4, 0xac, 0xac, 0xb3, 0x95, 0x10, 0x96, 0x47, 0x10, 0x5d, + 0xf0, 0xdb, 0x80, 0x33, 0x8b, 0x50, 0x79, 0xaf, 0xb8, 0x7d, 0x6b, 0x34, 0x2b, 0xf6, 0xcd, 0xed, + 0x8d, 0x63, 0x3f, 0xad, 0x70, 0x50, 0x10, 0x08, 0x66, 0x9f, 0xcd, 0xee, 0x4f, 0xe1, 0x80, 0xc0, + 0x46, 0x2e, 0xaa, 0xaf, 0x7d, 0x62, 0xf0, 0xba, 0x80, 0x33, 0x96, 0xe6, 0x24, 0xe9, 0xbf, 0xde, + 0xdb, 0x79, 0xba, 0x8e, 0xee, 0x24, 0x1c, 0x04, 0xeb, 0x5b, 0x1a, 0xea, 0x08, 0x00, 0x82, 0x0a, + 0x35, 0x8b, 0xab, 0x83, 0xfe, 0x4e, 0xaf, 0x17, 0x70, 0x88, 0x60, 0x29, 0x97, 0x02, 0x82, 0xa5, + 0x83, 0x1d, 0xba, 0x00, 0xf0, 0x75, 0xea, 0xef, 0x91, 0x38, 0x2b, 0x5b, 0x5a, 0x2e, 0x75, 0x0e, + 0x03, 0xc1, 0xfe, 0x01, 0x7c, 0x1a, 0x0c, 0xa8, 0x78, 0xbb, 0xfe, 0x0a, 0x40, 0x4d, 0x70, 0xc0, + 0xcf, 0x38, 0x1c, 0x10, 0xe5, 0xc5, 0x67, 0xd2, 0x75, 0x69, 0x9e, 0xdc, 0x98, 0x3e, 0xc2, 0xd9, + 0x6f, 0x82, 0x00, 0xa4, 0x56, 0x2b, 0xb8, 0xa0, 0xc4, 0x8f, 0xb3, 0x89, 0xda, 0x3e, 0x3b, 0xf1, + 0xf7, 0x10, 0x08, 0x02, 0x93, 0xfa, 0xfe, 0x2d, 0x31, 0x0e, 0x08, 0x70, 0xb1, 0xa3, 0x07, 0x8f, + 0x1c, 0x2c, 0x1d, 0x10, 0x81, 0xa0, 0xe3, 0x70, 0x6f, 0xf5, 0xdc, 0xb8, 0xd4, 0x5c, 0xf9, 0x61, + 0x4d, 0x3f, 0xae, 0x7a, 0xfc, 0xb0, 0x7f, 0xc9, 0x37, 0xd7, 0xc9, 0x97, 0xaa, 0xda, 0x78, 0x28, + 0xa4, 0x39, 0xeb, 0xe8, 0x5e, 0x66, 0x12, 0xb4, 0xd0, 0x0d, 0xcb, 0xe6, 0xed, 0x35, 0xe6, 0x97, + 0x12, 0xfc, 0xdc, 0x18, 0xac, 0xb2, 0xc4, 0x89, 0x17, 0x5d, 0xf1, 0x0e, 0x05, 0x53, 0x2f, 0x2f, + 0x03, 0xb7, 0xe1, 0x02, 0xce, 0x10, 0xe6, 0xd6, 0xa2, 0x79, 0x2a, 0xbe, 0x11, 0x08, 0x8c, 0xc5, + 0xe2, 0xea, 0x78, 0x07, 0x8a, 0x67, 0x1c, 0x89, 0xfa, 0x9e, 0x60, 0xb2, 0xb2, 0xf7, 0x33, 0x89, + 0x03, 0x40, 0xc8, 0xa6, 0x2e, 0x59, 0xc9, 0xce, 0x78, 0xbb, 0x7c, 0x55, 0xab, 0x64, 0xcf, 0xf8, + 0x29, 0xd6, 0xa5, 0xea, 0x2e, 0xb5, 0x5f, 0x62, 0x08, 0x50, 0xf8, 0x8f, 0x89, 0xe2, 0x43, 0x3c, + 0x20, 0x11, 0xc3, 0xc4, 0x20, 0x00, 0x5e, 0x4a, 0x36, 0x1a, 0x95, 0x8e, 0x64, 0x02, 0x7e, 0xff, + 0x7b, 0x80, 0xeb, 0x8b, 0xcd, 0x2d, 0x50, 0xab, 0x08, 0xe9, 0x85, 0xa4, 0x0a, 0xcf, 0x00, 0x30, + 0x72, 0x6e, 0x88, 0x15, 0x04, 0xaa, 0x80, 0xfe, 0x94, 0x60, 0x6c, 0x3c, 0xd4, 0x1c, 0x16, 0x81, + 0xa2, 0x72, 0xd1, 0xb3, 0xd2, 0xa1, 0xce, 0x67, 0x3b, 0x48, 0x78, 0x90, 0x2c, 0x05, 0x27, 0x81, + 0x80, 0xf0, 0x2c, 0x38, 0x3c, 0xf3, 0xdf, 0xf1, 0xf6, 0x3a, 0x43, 0xdf, 0x73, 0x13, 0x2a, 0xa6, + 0x87, 0x00, 0xf2, 0x46, 0xe1, 0xc3, 0xd3, 0xfc, 0x27, 0xe4, 0xe9, 0x56, 0xd6, 0x22, 0x14, 0xac, + 0xda, 0x06, 0x36, 0x4f, 0x91, 0x5d, 0xe2, 0x4e, 0x4c, 0x9d, 0xa5, 0xbd, 0x7d, 0xf0, 0xa4, 0xb9, + 0x07, 0x23, 0x7e, 0xd1, 0x96, 0x41, 0x9a, 0xef, 0xa9, 0x56, 0xae, 0xe4, 0x2b, 0xea, 0xf3, 0xc2, + 0x31, 0xf8, 0x9f, 0xaa, 0x49, 0xbe, 0x2b, 0x4f, 0x89, 0x10, 0x10, 0x89, 0x74, 0x4e, 0x9d, 0xce, + 0x20, 0xd5, 0xa8, 0xe7, 0xb1, 0x39, 0x21, 0x11, 0x21, 0x3c, 0xfe, 0xe2, 0xb8, 0xaf, 0x86, 0x44, + 0x8a, 0x97, 0x8a, 0xc5, 0x67, 0xc7, 0xde, 0x11, 0xe5, 0xad, 0x62, 0x05, 0x62, 0x79, 0x86, 0x42, + 0x21, 0x1a, 0xc8, 0xba, 0xc6, 0x69, 0x53, 0x4d, 0x5f, 0xfe, 0x24, 0x29, 0x8d, 0xb5, 0x8a, 0x31, + 0x5b, 0xb4, 0xad, 0x0b, 0xaa, 0xc5, 0xc4, 0xf2, 0x2f, 0x08, 0x05, 0x39, 0xb2, 0xee, 0xd3, 0x81, + 0xfa, 0x52, 0xc3, 0x2d, 0x47, 0x88, 0x90, 0x0e, 0x15, 0x40, 0xbc, 0x1f, 0x92, 0x8f, 0x0b, 0x1f, + 0x0e, 0x60, 0x01, 0xa3, 0x70, 0x1c, 0x94, 0x54, 0x2b, 0x2d, 0xfb, 0xfd, 0xdc, 0x69, 0x5d, 0xae, + 0xd8, 0x84, 0x1d, 0x76, 0x2e, 0x53, 0x2f, 0xdb, 0xd2, 0xe0, 0xa4, 0x14, 0x96, 0xb6, 0x61, 0x73, + 0x86, 0x42, 0x15, 0x5c, 0x57, 0xd6, 0xbc, 0x30, 0x24, 0x15, 0xdd, 0xdd, 0xee, 0xa2, 0x78, 0x2b, + 0x2e, 0x46, 0x58, 0xd9, 0xf0, 0x55, 0x10, 0x72, 0x55, 0x75, 0x17, 0x11, 0xc4, 0x73, 0xb9, 0xc4, + 0x89, 0x1d, 0x85, 0x16, 0xc1, 0x0c, 0x1f, 0x1c, 0x43, 0xd1, 0x2d, 0x30, 0xe6, 0x3f, 0x10, 0x11, + 0x1d, 0x1a, 0x56, 0x71, 0xd3, 0xed, 0xed, 0xae, 0xe0, 0xd7, 0xa5, 0x55, 0xf1, 0x20, 0x86, 0x6e, + 0x2f, 0x77, 0xe7, 0xf2, 0xc4, 0xc4, 0xd8, 0xcf, 0xd8, 0xed, 0x8d, 0x8d, 0xfe, 0x32, 0x66, 0xa9, + 0xf7, 0x86, 0xfc, 0x17, 0xe2, 0xf9, 0x32, 0x42, 0x09, 0x49, 0x79, 0x6f, 0x6f, 0xac, 0x4f, 0x88, + 0x04, 0x9b, 0xc7, 0x97, 0xb8, 0x89, 0x29, 0xd3, 0xe1, 0x19, 0xb5, 0xa8, 0x5f, 0x9b, 0x7b, 0xb8, + 0x44, 0x22, 0x0a, 0xfb, 0xbb, 0x9b, 0xcd, 0xd6, 0x77, 0xc8, 0xf3, 0x0d, 0x92, 0x00, 0x7d, 0x38, + 0xc8, 0xc5, 0xa6, 0xf3, 0xcf, 0xcd, 0xe9, 0xab, 0x65, 0xf4, 0x9d, 0x3e, 0x9b, 0xf6, 0xd7, 0xf0, + 0xc8, 0x64, 0x45, 0x67, 0x99, 0xf0, 0x88, 0x80, 0x8d, 0x27, 0xe2, 0x97, 0xe6, 0x82, 0xe6, 0xce, + 0x20, 0x32, 0x32, 0x5b, 0x3d, 0xc5, 0x91, 0x54, 0xab, 0x5d, 0xea, 0xbc, 0x48, 0x92, 0xf4, 0x6f, + 0x86, 0x63, 0x2b, 0x2a, 0x91, 0x88, 0xb3, 0x38, 0xc2, 0xbf, 0x3d, 0x69, 0xc2, 0xea, 0x00, 0x2b, + 0x3d, 0x2e, 0x32, 0xaf, 0xdb, 0xcf, 0x7d, 0xb2, 0xf6, 0xf1, 0x2f, 0x1e, 0x40, 0xbf, 0x0b, 0x38, + 0xb5, 0xf1, 0xc5, 0x68, 0xc3, 0x0e, 0x28, 0x04, 0xdf, 0x22, 0xba, 0xef, 0xff, 0x16, 0xd3, 0x37, + 0xeb, 0x6f, 0xff, 0x57, 0x9f, 0x84, 0xaf, 0xb7, 0x36, 0x65, 0xc2, 0x1f, 0x19, 0xc5, 0xe9, 0x55, + 0x88, 0xe4, 0x49, 0xcb, 0x5b, 0xae, 0x13, 0xaa, 0xad, 0xee, 0xf8, 0x81, 0x3c, 0x4f, 0xe5, 0xea, + 0x9e, 0x26, 0x3f, 0xcf, 0xcd, 0x0e, 0x7a, 0x6e, 0x11, 0xee, 0xfb, 0xf9, 0xb7, 0xba, 0xc4, 0x5f, + 0x25, 0xdf, 0x27, 0x05, 0x57, 0x4f, 0x07, 0x8f, 0x03, 0xfd, 0x41, 0xd3, 0xc1, 0xd0, 0xf1, 0x21, + 0xcb, 0xc9, 0xf2, 0x27, 0x5c, 0x32, 0x2a, 0x8c, 0x43, 0x4d, 0xdd, 0xdf, 0x10, 0x11, 0x7a, 0x9a, + 0x51, 0x7e, 0x27, 0xc4, 0x8a, 0xa3, 0x21, 0x8a, 0xf6, 0x43, 0x7e, 0x74, 0x71, 0x01, 0x10, 0x59, + 0x52, 0x46, 0xbc, 0x0d, 0x4c, 0x98, 0x42, 0xa4, 0xc8, 0xbd, 0xc5, 0x4b, 0xca, 0x0e, 0x26, 0x3b, + 0xe7, 0x6d, 0x45, 0xd4, 0x5c, 0xbd, 0x57, 0x83, 0x80, 0x41, 0x11, 0xc5, 0x48, 0xcc, 0xe8, 0x12, + 0x64, 0x83, 0x9d, 0x07, 0x10, 0x3b, 0xcd, 0x9a, 0xa2, 0x6b, 0x5d, 0x6a, 0x9d, 0x38, 0x80, 0x47, + 0x17, 0xd7, 0xbe, 0x7a, 0xfe, 0x3d, 0xdb, 0x88, 0x84, 0xe6, 0xe2, 0x3f, 0xa7, 0x4f, 0x08, 0x09, + 0x08, 0xf8, 0x0f, 0xf9, 0x32, 0xf7, 0x82, 0x7f, 0x8f, 0x0c, 0x19, 0xd4, 0x30, 0x1f, 0x17, 0xf3, + 0x63, 0x83, 0xb7, 0xfe, 0x10, 0xdd, 0x31, 0x2f, 0x2b, 0x4b, 0x63, 0xef, 0x6f, 0x7e, 0x10, 0x13, + 0xc4, 0x09, 0x84, 0x39, 0x2b, 0x5a, 0xe4, 0xde, 0xe3, 0x03, 0x32, 0x80, 0xef, 0x71, 0x4f, 0xfe, + 0xde, 0xdd, 0xf8, 0x29, 0x03, 0x48, 0x2a, 0x21, 0xb5, 0xf6, 0x85, 0x71, 0x3c, 0xac, 0xe2, 0x02, + 0x44, 0x35, 0x0c, 0x4c, 0x46, 0x13, 0x32, 0x8f, 0xfb, 0xa9, 0x83, 0x66, 0x73, 0x0c, 0xdf, 0x03, + 0x00, 0x18, 0x5d, 0x4d, 0xeb, 0xd3, 0xf8, 0x9f, 0x84, 0xbb, 0x8a, 0xd5, 0x75, 0x13, 0x36, 0xb4, + 0xbc, 0x15, 0xf5, 0x55, 0x5d, 0x35, 0xda, 0x6c, 0x49, 0x33, 0x7b, 0x7c, 0x41, 0x6d, 0xdf, 0xe1, + 0x6b, 0xcd, 0xb1, 0x1c, 0xeb, 0xee, 0x9c, 0xfe, 0xb8, 0xbf, 0x2d, 0xf1, 0xdf, 0x78, 0xcd, 0x27, + 0x15, 0x88, 0xda, 0x0c, 0xb5, 0xf1, 0xf5, 0xf6, 0xff, 0x88, 0x88, 0xd7, 0x97, 0x06, 0x93, 0x07, + 0xbf, 0xf8, 0xa9, 0xf2, 0xb4, 0x96, 0xfc, 0x48, 0x9a, 0x6f, 0xe6, 0xe2, 0x3f, 0xc6, 0x62, 0x6c, + 0x60, 0x89, 0xf6, 0x3e, 0x89, 0x46, 0x77, 0xe9, 0xdc, 0xdc, 0x5e, 0xfe, 0xf1, 0x83, 0xb3, 0xe7, + 0x67, 0xcb, 0xbb, 0x25, 0x0a, 0xf3, 0x56, 0xb3, 0xf2, 0x15, 0x75, 0xc3, 0x3f, 0x84, 0xaa, 0x6b, + 0x78, 0x73, 0x75, 0xae, 0x0e, 0x01, 0x47, 0x04, 0x3e, 0x08, 0x42, 0x37, 0x08, 0xcb, 0xad, 0xf1, + 0x22, 0x3e, 0x0b, 0x88, 0x4c, 0xfa, 0x62, 0x1c, 0xcb, 0xc4, 0x05, 0x2b, 0x55, 0x69, 0xa3, 0x67, + 0x51, 0x00, 0xd0, 0xb1, 0xb3, 0x16, 0xec, 0x71, 0x02, 0x09, 0xb7, 0x71, 0x10, 0x85, 0xcf, 0xfa, + 0x88, 0xf1, 0x11, 0x91, 0x1c, 0x2f, 0xaa, 0xd7, 0x89, 0xe7, 0x56, 0xb1, 0x1e, 0x22, 0x4d, 0xee, + 0x19, 0xee, 0xf7, 0x93, 0x98, 0xb5, 0x5e, 0x08, 0x26, 0xd6, 0xb8, 0x90, 0x81, 0xab, 0x55, 0x8a, + 0xc2, 0x8a, 0xf8, 0xb9, 0xfd, 0xea, 0xaa, 0xab, 0x9a, 0xaa, 0xb5, 0xcb, 0xaa, 0xae, 0x23, 0xf0, + 0x96, 0x16, 0x57, 0x6a, 0xbe, 0x26, 0x24, 0x8f, 0xce, 0xf7, 0x77, 0xc4, 0xcd, 0xe3, 0x40, 0x81, + 0x13, 0x8b, 0xc5, 0xf1, 0x27, 0x14, 0x2a, 0x54, 0xb3, 0xf2, 0xf1, 0x3c, 0xb8, 0x9f, 0xcb, 0xc5, + 0x75, 0xc4, 0x42, 0x9f, 0x32, 0xfe, 0xb1, 0x77, 0xc5, 0xef, 0x77, 0xbb, 0x85, 0x39, 0x6f, 0x78, + 0x8c, 0x46, 0x15, 0x67, 0x00, 0xd7, 0xf4, 0x87, 0x6f, 0xff, 0xf1, 0x18, 0x6c, 0xe3, 0xe0, 0xa4, + 0x49, 0x48, 0xab, 0xf9, 0xb8, 0xba, 0xf1, 0x3c, 0x18, 0x89, 0xe1, 0x80, 0xc5, 0xc2, 0x3e, 0x11, + 0x82, 0x7b, 0xbd, 0xdb, 0xdf, 0xb8, 0x44, 0x48, 0x2d, 0x9b, 0x97, 0xa5, 0xd4, 0xd9, 0x07, 0xc1, + 0x1e, 0xef, 0xeb, 0x84, 0x04, 0x7c, 0x4c, 0x41, 0xc5, 0x17, 0x26, 0x2b, 0x33, 0x78, 0x8e, 0x11, + 0x10, 0x13, 0xae, 0xb7, 0x54, 0xf8, 0x8f, 0x11, 0xc4, 0x84, 0x1e, 0xe2, 0x5f, 0xa8, 0x89, 0x2e, + 0xf8, 0x52, 0x27, 0x27, 0x09, 0xd7, 0x55, 0xac, 0xb8, 0x63, 0x14, 0x8a, 0x26, 0xc4, 0x46, 0x3f, + 0x5e, 0x11, 0x0c, 0x12, 0xa4, 0xcb, 0xf8, 0x48, 0xca, 0x2f, 0x5d, 0x57, 0x88, 0x75, 0x5f, 0xc7, + 0x1d, 0x6a, 0x2f, 0xaa, 0xaa, 0xf8, 0x40, 0x31, 0x78, 0x82, 0x1b, 0x73, 0x7c, 0x32, 0x24, 0x45, + 0xeb, 0xf7, 0xa8, 0x88, 0x89, 0x78, 0x9e, 0x78, 0x83, 0x5e, 0xd7, 0xc5, 0x5a, 0xaa, 0xac, 0x53, + 0x17, 0xf2, 0xd6, 0xbe, 0x20, 0x56, 0xdd, 0x6a, 0xab, 0xc4, 0x0c, 0xb8, 0xaf, 0x77, 0xb9, 0x3c, + 0xef, 0x1a, 0xc5, 0xb8, 0xfc, 0x4f, 0x89, 0x85, 0xf1, 0x13, 0x09, 0x89, 0x04, 0x5b, 0x53, 0x1c, + 0x23, 0xf0, 0x99, 0x96, 0xaa, 0xaa, 0x2e, 0x2f, 0x13, 0x28, 0x19, 0xd1, 0xa7, 0x14, 0x48, 0x41, + 0xab, 0x6c, 0x31, 0x75, 0x5f, 0x08, 0xe3, 0xb8, 0x48, 0xc2, 0x38, 0xcc, 0xd3, 0x6d, 0x31, 0x2b, + 0x3e, 0x5e, 0xd8, 0xf5, 0x3c, 0x90, 0xf5, 0x60, 0xb3, 0xa6, 0x0e, 0xcc, 0xaf, 0xc6, 0x22, 0x26, + 0x5f, 0xe5, 0xf7, 0x78, 0x7c, 0x4a, 0x16, 0x3b, 0x8c, 0x48, 0x92, 0x8a, 0xd5, 0x78, 0x64, 0x95, + 0x5f, 0x86, 0x22, 0x39, 0x0a, 0xef, 0x97, 0x98, 0x9b, 0xb8, 0x05, 0x6a, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x39, 0x1c, 0xb0, 0x52, 0x02, 0x14, 0x31, 0x13, 0x78, 0xae, 0xf9, 0xd8, 0xc2, 0x10, + 0x8c, 0xfc, 0x29, 0x5f, 0x99, 0x8b, 0xbb, 0xbe, 0x20, 0x40, 0x9e, 0xee, 0xf6, 0x38, 0x92, 0xc7, + 0x96, 0x9d, 0xdf, 0x89, 0x83, 0x18, 0x60, 0x48, 0x42, 0xb6, 0xaa, 0xba, 0xdb, 0x11, 0x67, 0x89, + 0x19, 0xa9, 0xff, 0x23, 0x14, 0xdd, 0x36, 0xfa, 0xe8, 0x6b, 0xf1, 0x32, 0xfc, 0xaa, 0x2e, 0x99, + 0xfe, 0x20, 0x48, 0x53, 0x1a, 0x55, 0xcb, 0xcd, 0x77, 0x5a, 0xee, 0xbe, 0xe1, 0x88, 0x24, 0xd6, + 0xaf, 0xf2, 0x65, 0xab, 0xfc, 0x48, 0xfc, 0x4f, 0x2d, 0x35, 0x6a, 0xbb, 0x5e, 0x26, 0xf1, 0x5b, + 0xbd, 0x44, 0xf0, 0x17, 0x73, 0x16, 0xb5, 0xe1, 0x11, 0x44, 0x88, 0xa9, 0xc5, 0x6e, 0x2b, 0x7f, + 0x1f, 0xbb, 0xc9, 0x05, 0xaa, 0x6b, 0xe2, 0x04, 0x12, 0xaa, 0x2f, 0xc4, 0xc2, 0x35, 0xad, 0xef, + 0x55, 0x74, 0xbc, 0xa5, 0xc5, 0xaa, 0xe6, 0xbd, 0xf8, 0x40, 0x47, 0x08, 0x08, 0x21, 0x0e, 0xa3, + 0xe1, 0x89, 0x4f, 0xaa, 0x82, 0xdc, 0x48, 0x83, 0x4f, 0x0e, 0xdd, 0xfc, 0x41, 0x6b, 0x7f, 0x84, + 0xad, 0xaa, 0xaa, 0xdf, 0xc4, 0x16, 0x86, 0xb5, 0xe1, 0x00, 0x43, 0x77, 0xdf, 0x88, 0x11, 0xe2, + 0x0c, 0x5d, 0xdf, 0xca, 0x4d, 0xdf, 0xc9, 0xb4, 0x92, 0x5c, 0x47, 0x0c, 0x08, 0x37, 0x77, 0xc3, + 0x01, 0x08, 0x2a, 0xe2, 0xf5, 0xad, 0xef, 0x0b, 0xe0, 0x04, 0x6b, 0xa6, 0xe2, 0xc8, 0x6e, 0xda, + 0x7f, 0x2d, 0x9b, 0xcf, 0x4d, 0x9c, 0x4c, 0x45, 0xf7, 0x76, 0xbe, 0x20, 0x15, 0x5e, 0xdd, 0xbb, + 0x6f, 0xaa, 0xf7, 0xc1, 0x75, 0xc5, 0x6d, 0x79, 0x71, 0xfc, 0x48, 0x27, 0xcd, 0xea, 0xe1, 0x54, + 0x40, 0x53, 0x7f, 0x73, 0xe3, 0x22, 0x3d, 0xce, 0xfb, 0x7b, 0x6b, 0x46, 0x25, 0xe4, 0xe5, 0x4e, + 0x58, 0xaf, 0x5b, 0x7e, 0x0b, 0x77, 0xbe, 0x35, 0x11, 0xbf, 0xdd, 0xdf, 0xf1, 0x77, 0xbe, 0xf7, + 0xf0, 0x5b, 0x22, 0xb2, 0x90, 0x6d, 0x5d, 0xec, 0x7c, 0x55, 0xdd, 0xcb, 0x99, 0x89, 0x1e, 0xbe, + 0x5b, 0x4b, 0xc1, 0x37, 0x2e, 0xaa, 0xa4, 0xe4, 0xde, 0xf8, 0x40, 0x48, 0x42, 0xde, 0x4a, 0xac, + 0x7a, 0xc5, 0x75, 0x9e, 0x15, 0x08, 0x89, 0x05, 0x57, 0x63, 0xc7, 0xe9, 0xfa, 0x1d, 0xdf, 0x89, + 0x88, 0xaa, 0xae, 0xed, 0x71, 0x11, 0x54, 0xed, 0x6a, 0xb5, 0xc4, 0x88, 0x19, 0x8d, 0x7a, 0x96, + 0x11, 0xf2, 0xe5, 0x7d, 0x1f, 0xef, 0xcf, 0x9e, 0x24, 0x49, 0x26, 0xe9, 0xf8, 0x46, 0x6a, 0xca, + 0xcf, 0x13, 0x09, 0x72, 0x42, 0xab, 0xe2, 0x2f, 0x8f, 0x55, 0xfa, 0xf6, 0x26, 0x11, 0x2f, 0x05, + 0x71, 0x22, 0x46, 0x04, 0x1e, 0xe2, 0xbb, 0x21, 0x59, 0x72, 0xf5, 0x7d, 0xc5, 0x7e, 0xf5, 0x55, + 0xc2, 0x3f, 0x85, 0x3b, 0xb4, 0x2f, 0x5a, 0xa5, 0x74, 0x9d, 0xdf, 0xbe, 0x08, 0xb1, 0xea, 0x93, + 0x3e, 0xc3, 0xcd, 0x04, 0x00, 0x40, 0x0c, 0x61, 0x41, 0x54, 0xcb, 0x1d, 0x70, 0xbd, 0x4f, 0x38, + 0x55, 0x9d, 0x32, 0x7f, 0x5d, 0x5a, 0x4e, 0x6b, 0x54, 0x9f, 0xc2, 0x14, 0xdf, 0x72, 0xd1, 0xe9, + 0x8a, 0xc5, 0x6c, 0xd9, 0xf8, 0x53, 0xa4, 0x5c, 0xdd, 0xc5, 0x67, 0xbd, 0xa2, 0xd9, 0x6c, 0x56, + 0x2b, 0x15, 0xbc, 0x3b, 0xcb, 0xad, 0x57, 0x25, 0x6b, 0x27, 0x37, 0x77, 0xc4, 0xc2, 0x55, 0xaf, + 0x6d, 0x7c, 0x57, 0x9b, 0xc1, 0x9d, 0x9c, 0x99, 0x5e, 0x20, 0x15, 0xf4, 0xdc, 0xee, 0x3b, 0x45, + 0x60, 0x71, 0x22, 0x85, 0xcb, 0x69, 0xc9, 0xc0, 0x3c, 0x38, 0x8b, 0x0c, 0x0e, 0x11, 0x8b, 0xe6, + 0xcf, 0x2e, 0x78, 0x24, 0xee, 0xcd, 0xbe, 0x12, 0x9f, 0xf5, 0x5a, 0xae, 0x2f, 0x97, 0x01, 0xe7, + 0x98, 0x39, 0x1e, 0x03, 0x91, 0xe7, 0x10, 0x0a, 0x38, 0x3c, 0xf0, 0x18, 0x17, 0x65, 0x8e, 0x04, + 0xf8, 0x0c, 0x02, 0x76, 0x5c, 0xcb, 0x04, 0x00, 0xa0, 0x29, 0x14, 0xc4, 0x1c, 0x17, 0x90, 0x7d, + 0x81, 0x47, 0x1d, 0x44, 0xce, 0xdd, 0x10, 0x5b, 0x99, 0x08, 0x87, 0xa0, 0x3b, 0x80, 0xa1, 0x82, + 0x4f, 0x0c, 0x02, 0x90, 0x53, 0x3c, 0x00, 0x08, 0xe0, 0xc5, 0x87, 0xc4, 0xc0, 0x27, 0x07, 0x7b, + 0x9e, 0xb2, 0xa5, 0x16, 0x67, 0x27, 0x1c, 0xfa, 0x4e, 0xe4, 0xce, 0xba, 0xbd, 0x70, 0x45, 0x1d, + 0x55, 0x72, 0x7f, 0x7c, 0xd5, 0xd4, 0x3d, 0xc9, 0x55, 0xc9, 0xc1, 0x26, 0x56, 0x27, 0xef, 0xf0, + 0x85, 0xed, 0xeb, 0x5d, 0x56, 0xab, 0xe0, 0xa3, 0x37, 0xc1, 0x82, 0x0b, 0x20, 0xe3, 0x01, 0x28, + 0x7e, 0x25, 0x42, 0x00, 0x06, 0x38, 0x63, 0x70, 0xc8, 0x16, 0x02, 0x91, 0x82, 0x26, 0xc1, 0xd8, + 0xb2, 0x28, 0x4b, 0xce, 0xaa, 0xf6, 0x24, 0xdc, 0x9f, 0x4f, 0x93, 0x05, 0x4f, 0x38, 0x1a, 0x04, + 0x61, 0xce, 0x35, 0xd3, 0x03, 0xc1, 0xfe, 0x2c, 0xe0, 0x84, 0x1c, 0x02, 0x99, 0x5f, 0xf3, 0x51, + 0x12, 0x71, 0x63, 0x6e, 0xa2, 0x11, 0x9e, 0x0a, 0x43, 0xb8, 0x8c, 0xfc, 0xfc, 0x7e, 0x07, 0xed, + 0x76, 0xe1, 0x90, 0x50, 0x13, 0x96, 0x8e, 0x6f, 0x16, 0x11, 0xb9, 0xfb, 0xde, 0x24, 0x14, 0x13, + 0x11, 0xcf, 0x08, 0x02, 0x07, 0x49, 0x2f, 0x82, 0x80, 0x91, 0x4d, 0x4a, 0x6f, 0x73, 0xe7, 0xe1, + 0x02, 0x45, 0x8a, 0xfa, 0xaa, 0x8b, 0xa8, 0xbe, 0x24, 0x14, 0x05, 0x31, 0x6f, 0x16, 0x81, 0xf3, + 0x00, 0x0f, 0x30, 0x35, 0x04, 0x5a, 0x0e, 0x3c, 0x1b, 0xe6, 0x57, 0x5c, 0x2b, 0xef, 0x32, 0x83, + 0x71, 0x83, 0x10, 0x80, 0x7e, 0xc9, 0x39, 0x6b, 0xff, 0x27, 0x13, 0xcd, 0x4d, 0x80, 0xd2, 0x06, + 0xb5, 0xab, 0x7e, 0x7e, 0x6c, 0xde, 0xab, 0x84, 0x73, 0xcb, 0x7b, 0x46, 0xc7, 0x7f, 0xe0, 0xa7, + 0x48, 0x86, 0x9d, 0x44, 0x55, 0xf1, 0x66, 0xf7, 0xb9, 0xf1, 0x74, 0x92, 0xf4, 0x94, 0x37, 0xcb, + 0xbb, 0xcb, 0xc6, 0x6d, 0x37, 0x7a, 0xe5, 0x64, 0xff, 0xd2, 0x95, 0x8f, 0x11, 0x51, 0x79, 0x93, + 0xff, 0x82, 0x5a, 0xd5, 0x6a, 0xd6, 0xc7, 0x82, 0x90, 0xa7, 0x26, 0x27, 0x83, 0x91, 0x61, 0x42, + 0x2c, 0x92, 0xb1, 0x07, 0xc2, 0xc1, 0x24, 0x4b, 0x45, 0xff, 0x8f, 0x89, 0xf1, 0x2f, 0xda, 0xba, + 0xf8, 0xae, 0xaa, 0xab, 0xf0, 0xc7, 0x84, 0x0d, 0x97, 0x2f, 0xc3, 0x02, 0x2d, 0x56, 0xeb, 0xe1, + 0x81, 0x3c, 0x48, 0x60, 0x9a, 0xa8, 0xbf, 0x05, 0x03, 0x7a, 0xd4, 0x47, 0x0e, 0x0e, 0x4e, 0x23, + 0xe5, 0x64, 0x50, 0x66, 0x30, 0x4f, 0xd3, 0x16, 0xff, 0xf2, 0xd6, 0xaa, 0x7e, 0x2e, 0xfb, 0xd6, + 0xdf, 0x88, 0xae, 0xab, 0x58, 0xbf, 0x84, 0xef, 0x6d, 0x55, 0x35, 0xfb, 0x93, 0xc8, 0x18, 0x0f, + 0xd5, 0x90, 0xd7, 0x26, 0xb5, 0x2f, 0x09, 0x6f, 0x37, 0x7b, 0xf1, 0x11, 0x37, 0x7a, 0x9a, 0x27, + 0xe5, 0x63, 0xdd, 0x2b, 0xbe, 0x18, 0x08, 0x8a, 0xa7, 0x4f, 0xbb, 0x78, 0x62, 0x0a, 0xef, 0x75, + 0x3e, 0xc9, 0x78, 0x8f, 0xdc, 0xfd, 0xcf, 0xab, 0xf0, 0x60, 0x10, 0xf9, 0x6b, 0x14, 0xc5, 0x3c, + 0x48, 0x63, 0x86, 0x43, 0x1e, 0x24, 0xd5, 0x51, 0x71, 0x1f, 0x89, 0x82, 0xcc, 0x4f, 0x5d, 0xd8, + 0xc6, 0x5c, 0x38, 0x1c, 0x1e, 0x0e, 0x85, 0x66, 0x64, 0x3a, 0xb8, 0x77, 0x6a, 0x1f, 0xca, 0xcf, + 0x89, 0x97, 0xaf, 0x15, 0xf9, 0xb9, 0xad, 0x4c, 0xc7, 0x88, 0x15, 0xac, 0x9b, 0x07, 0xbf, 0x2f, + 0xf0, 0xa5, 0xc5, 0x6f, 0xba, 0xa6, 0x7b, 0x55, 0x69, 0x3d, 0x57, 0xaf, 0x85, 0x25, 0xd5, 0xba, + 0xd0, 0xe8, 0x9b, 0x37, 0x7f, 0x34, 0x10, 0xfa, 0x56, 0x08, 0x7b, 0xbd, 0xdf, 0x89, 0x75, 0x8d, + 0x57, 0x89, 0x09, 0x5a, 0xdf, 0x64, 0xfe, 0x2b, 0x37, 0xd4, 0x28, 0xd4, 0x4e, 0x48, 0x0d, 0x3c, + 0x29, 0x2f, 0x91, 0x74, 0xef, 0x5f, 0x5a, 0xd2, 0x5b, 0x1e, 0x08, 0x09, 0x77, 0xf0, 0x61, 0x11, + 0x15, 0xdf, 0x37, 0x97, 0x71, 0x20, 0xa0, 0x15, 0xe5, 0x4b, 0xc5, 0xd4, 0x5d, 0x55, 0x6b, 0x3a, + 0x22, 0xc4, 0x84, 0x70, 0xd3, 0x82, 0x2f, 0x27, 0x57, 0xff, 0xf7, 0x77, 0x10, 0x24, 0x29, 0x9b, + 0xa9, 0x79, 0x7b, 0x60, 0x9d, 0x09, 0x45, 0xe0, 0xa8, 0x26, 0xc0, 0x18, 0x2a, 0x51, 0xf8, 0x4e, + 0x28, 0x99, 0x26, 0x2f, 0xcd, 0xc4, 0x88, 0x1b, 0x0e, 0xf2, 0x9e, 0x1a, 0x30, 0x30, 0x11, 0xac, + 0xe8, 0x67, 0x31, 0x20, 0x67, 0x82, 0xca, 0x58, 0xb9, 0x4b, 0x79, 0xe7, 0x90, 0xa9, 0x7a, 0x61, + 0x4a, 0x55, 0x46, 0x19, 0x45, 0x80, 0x7f, 0x92, 0xc7, 0x82, 0xc4, 0x89, 0x83, 0xe2, 0xfe, 0x24, + 0x20, 0x23, 0xbb, 0x70, 0xe6, 0x8e, 0xf7, 0xe1, 0x01, 0xf1, 0x0c, 0x05, 0x61, 0xd1, 0x96, 0xc2, + 0xcb, 0x22, 0xdc, 0x65, 0xcb, 0x4f, 0xe1, 0x01, 0x97, 0x0a, 0x2b, 0xa9, 0xc3, 0x70, 0x67, 0x67, + 0xb8, 0x9e, 0xb1, 0xae, 0xd8, 0x93, 0xc8, 0xd5, 0x6f, 0x8a, 0xf4, 0x6f, 0xbe, 0xac, 0xfb, 0xe4, + 0xab, 0xd8, 0x7e, 0x08, 0xb3, 0x33, 0x0f, 0x2a, 0x45, 0xf1, 0x9b, 0xd6, 0x29, 0xe2, 0x3c, 0xdc, + 0xd2, 0x0f, 0xe5, 0xd4, 0x92, 0x39, 0x7e, 0x7e, 0xe4, 0x63, 0xe4, 0x89, 0x86, 0x3c, 0xdf, 0x07, + 0x4a, 0x80, 0x37, 0xb0, 0xb1, 0xc6, 0x4f, 0x10, 0xef, 0xf9, 0x7a, 0x6f, 0x64, 0xe0, 0x93, 0x8e, + 0xe1, 0x20, 0x03, 0x4c, 0x2d, 0x4f, 0x97, 0x98, 0xa3, 0x40, 0xe2, 0x58, 0x19, 0x88, 0xab, 0xfc, + 0x16, 0xd5, 0xec, 0x53, 0xe7, 0xef, 0xc4, 0x88, 0x05, 0x72, 0xf5, 0x11, 0xc7, 0x59, 0xe0, 0x5b, + 0x96, 0x37, 0x4e, 0xfc, 0x48, 0x44, 0x5e, 0x8c, 0xf9, 0x0e, 0xe9, 0x3e, 0x11, 0x12, 0x08, 0xef, + 0x2e, 0x24, 0xe7, 0x83, 0x1f, 0x06, 0x04, 0xaa, 0xaa, 0xe2, 0x44, 0x05, 0x3b, 0xbc, 0xcc, 0x56, + 0xee, 0xf5, 0x0a, 0x8e, 0x0f, 0xe7, 0x8f, 0x08, 0x82, 0xa8, 0x93, 0xca, 0x65, 0x2f, 0x83, 0x27, + 0xd4, 0x07, 0x6b, 0x51, 0xbc, 0xaf, 0x89, 0xb6, 0x58, 0x4b, 0xda, 0xf2, 0x77, 0xc2, 0x36, 0x79, + 0x18, 0xa7, 0x04, 0xc8, 0x43, 0x81, 0x47, 0xd5, 0xac, 0xa7, 0xca, 0x7e, 0x27, 0x8f, 0xd5, 0x55, + 0x6a, 0x25, 0xff, 0x82, 0xd9, 0x64, 0x7c, 0x7b, 0x8a, 0xfe, 0xf8, 0x8d, 0xb2, 0xec, 0x19, 0xa0, + 0xc8, 0x66, 0xef, 0xba, 0x2c, 0x66, 0x51, 0xe2, 0x60, 0x9e, 0x95, 0xf0, 0x5d, 0x48, 0x21, 0x96, + 0x19, 0x7f, 0x0c, 0xc6, 0x64, 0xb1, 0xc3, 0x3e, 0x05, 0x54, 0xdf, 0x7f, 0x92, 0x75, 0x3f, 0xf3, + 0x7c, 0x32, 0x20, 0x65, 0x65, 0xdd, 0xec, 0x27, 0x57, 0xa2, 0x53, 0x28, 0xcb, 0xb3, 0xb0, 0xda, + 0xed, 0x92, 0x19, 0x12, 0x32, 0xef, 0x78, 0x8c, 0x5d, 0x23, 0x6f, 0x4a, 0xf1, 0x3f, 0x9d, 0x82, + 0xf7, 0xb1, 0x86, 0x44, 0x88, 0xe9, 0xcf, 0xfe, 0xe2, 0x8c, 0xac, 0x1e, 0xe0, 0xee, 0x6d, 0x6a, + 0x32, 0x26, 0xf3, 0x7f, 0xc5, 0x53, 0x6d, 0x62, 0xe2, 0xea, 0x29, 0xe1, 0x01, 0x21, 0x4c, 0x42, + 0x38, 0x78, 0x59, 0x54, 0x4d, 0x01, 0xdc, 0x17, 0xb9, 0x3f, 0x87, 0xb6, 0x77, 0x0b, 0xc5, 0x52, + 0x31, 0x71, 0x78, 0x88, 0xcf, 0xc6, 0xc3, 0xac, 0x0b, 0xc1, 0x71, 0x22, 0xc0, 0xe3, 0x43, 0xcc, + 0x98, 0x63, 0x87, 0x8e, 0xc9, 0xf1, 0xe1, 0x4c, 0xb1, 0xca, 0x3c, 0x49, 0xf4, 0xb0, 0x82, 0xca, + 0x73, 0x11, 0x68, 0x07, 0xe4, 0x0a, 0x71, 0x55, 0xfe, 0x19, 0x10, 0x14, 0x8a, 0xcb, 0x89, 0xca, + 0xc5, 0x89, 0x29, 0x24, 0x5b, 0x7a, 0x79, 0xc9, 0x06, 0xd0, 0x93, 0x82, 0xec, 0xf3, 0xf8, 0x92, + 0x6b, 0x5c, 0x48, 0x81, 0x99, 0xf2, 0xa9, 0xde, 0x1e, 0xb2, 0xab, 0x55, 0x19, 0x52, 0xf5, 0x55, + 0xf1, 0x03, 0xa9, 0x24, 0xe5, 0xa2, 0x5b, 0xad, 0x54, 0xbd, 0xc7, 0xf5, 0x3e, 0xaa, 0x60, 0xf1, + 0x01, 0x11, 0x30, 0x74, 0x7d, 0xcf, 0xf3, 0xc1, 0xf1, 0x90, 0x88, 0x87, 0x71, 0x47, 0x15, 0xf9, + 0x2b, 0x3e, 0x22, 0x3b, 0x6e, 0xe9, 0xb1, 0xd8, 0xf2, 0x77, 0xf3, 0x74, 0xcd, 0xd7, 0x0b, 0xef, + 0x79, 0x7e, 0xcd, 0x66, 0x87, 0xe2, 0x04, 0xb8, 0xaf, 0x15, 0xbe, 0x27, 0x0a, 0xe2, 0x25, 0xe0, + 0xaf, 0x45, 0x7e, 0x6f, 0x9a, 0x14, 0xfc, 0x48, 0x29, 0x04, 0x56, 0xd6, 0x4c, 0xc9, 0x8f, 0x08, + 0x93, 0x36, 0x57, 0x12, 0x24, 0x77, 0xa4, 0xb2, 0x66, 0x7b, 0xd4, 0xd9, 0xc4, 0x89, 0xb9, 0x85, + 0xdd, 0xfc, 0x48, 0x90, 0x87, 0x3b, 0xf5, 0x37, 0x8b, 0x55, 0xe2, 0x47, 0x6d, 0x35, 0x54, 0x7a, + 0x9b, 0xaa, 0xd1, 0xc9, 0x67, 0x12, 0x24, 0x29, 0xd5, 0x44, 0xb8, 0xeb, 0x96, 0x55, 0x56, 0x58, + 0x62, 0xea, 0x2e, 0x7d, 0xe0, 0xa4, 0x44, 0x19, 0xfc, 0x3f, 0xcd, 0x98, 0xb4, 0x07, 0xe9, 0x59, + 0xdf, 0x9e, 0xbe, 0xf2, 0xc2, 0x7e, 0x2b, 0xa6, 0xeb, 0x64, 0x99, 0x7b, 0xad, 0x78, 0x88, 0x53, + 0x44, 0x24, 0xe0, 0xea, 0xca, 0xa7, 0x17, 0x1e, 0xb0, 0x53, 0x3f, 0x87, 0x85, 0x80, 0xb5, 0x95, + 0x75, 0x15, 0x38, 0x88, 0xab, 0xac, 0xb9, 0x15, 0xb4, 0xd2, 0xc4, 0x17, 0xbb, 0x7e, 0x49, 0xb0, + 0x4f, 0xd2, 0xe2, 0x78, 0x91, 0x22, 0xb4, 0xeb, 0x9a, 0x10, 0xbf, 0x27, 0x77, 0x24, 0x20, 0x24, + 0x11, 0x62, 0x8d, 0xa4, 0xc5, 0xc4, 0xf1, 0x23, 0xef, 0x0b, 0xab, 0xb5, 0xbb, 0xbf, 0xe2, 0x24, + 0xcf, 0x9b, 0x88, 0xf7, 0xf8, 0x90, 0x9e, 0x68, 0x65, 0xe5, 0xdb, 0x5c, 0x48, 0x53, 0x24, 0x69, + 0xad, 0xd2, 0x27, 0x4e, 0xf1, 0x58, 0x87, 0x01, 0x61, 0x25, 0xa2, 0xaa, 0xf0, 0xb7, 0xa6, 0xb0, + 0x31, 0x44, 0xab, 0x13, 0x08, 0xea, 0x6e, 0x77, 0x9b, 0xd6, 0x3e, 0xfa, 0xcd, 0x85, 0xf2, 0xcf, + 0x38, 0x60, 0x10, 0xdc, 0x46, 0x5e, 0xef, 0x7f, 0x82, 0x7d, 0xb5, 0x3a, 0x46, 0xdd, 0xb6, 0xdf, + 0xe0, 0xab, 0xc7, 0x2b, 0x81, 0xb9, 0xf2, 0x10, 0x7e, 0x55, 0xf1, 0xf3, 0x58, 0xde, 0x20, 0x21, + 0xb9, 0x79, 0xb0, 0xcc, 0x6c, 0x82, 0xaa, 0xfe, 0xa9, 0x2f, 0x8f, 0x88, 0xf2, 0x60, 0xd8, 0x53, + 0xb9, 0xac, 0x47, 0xac, 0xcc, 0x47, 0x12, 0x20, 0x64, 0x32, 0xa6, 0x60, 0xf9, 0xe9, 0x9d, 0x39, + 0x99, 0x07, 0xa6, 0xd3, 0x33, 0x01, 0xc9, 0xe7, 0x9d, 0x11, 0x14, 0x22, 0x2e, 0x90, 0x47, 0xbd, + 0x41, 0xfe, 0x38, 0x78, 0x59, 0xcb, 0x04, 0x21, 0x11, 0x91, 0x26, 0x84, 0xca, 0xdb, 0x8a, 0xa3, + 0xde, 0x37, 0x56, 0x08, 0xd0, 0x15, 0x01, 0x6a, 0x51, 0x85, 0xee, 0x4c, 0x3d, 0xff, 0xc3, 0x44, + 0x85, 0x28, 0x15, 0x67, 0x82, 0x39, 0xd6, 0x63, 0x61, 0x88, 0x58, 0x5f, 0xf2, 0xcb, 0x7f, 0xe6, + 0xe2, 0xb2, 0xc7, 0x10, 0x20, 0x99, 0x71, 0x7c, 0x40, 0x40, 0xf5, 0x18, 0xef, 0xf8, 0xfe, 0x6a, + 0xd6, 0x33, 0x97, 0x7b, 0xbe, 0xaf, 0xf0, 0x5d, 0x57, 0x66, 0xfb, 0xb1, 0xc1, 0x40, 0x21, 0x72, + 0xa5, 0x8d, 0xa9, 0x22, 0x44, 0x71, 0x32, 0xf7, 0x73, 0xf1, 0x1d, 0x53, 0x24, 0x36, 0x6f, 0xe1, + 0x9e, 0x35, 0xed, 0x51, 0xcf, 0xfe, 0xb8, 0x46, 0xbb, 0xf2, 0xca, 0xf7, 0xe2, 0x05, 0xcb, 0xd9, + 0x3f, 0xe2, 0x1e, 0xdf, 0x84, 0x3c, 0x40, 0x81, 0x5e, 0x9a, 0xa4, 0x16, 0x28, 0x95, 0x7f, 0x10, + 0x21, 0xdd, 0xd3, 0x94, 0xfc, 0x76, 0x15, 0x1a, 0xb1, 0x91, 0x34, 0xcb, 0xd1, 0x7d, 0x63, 0xbf, + 0x5a, 0xbf, 0x89, 0xb3, 0xa1, 0xaa, 0x19, 0xa9, 0x57, 0xe1, 0x08, 0xfd, 0x35, 0xf8, 0x95, 0x59, + 0xa5, 0x1e, 0xad, 0x1f, 0xf9, 0x5e, 0x1b, 0xc4, 0x57, 0x10, 0x59, 0xbe, 0x2f, 0xf0, 0x40, 0x0a, + 0x7e, 0xf5, 0xaf, 0x11, 0x20, 0x55, 0x40, 0x99, 0xec, 0x0f, 0x7e, 0x2b, 0x6d, 0xff, 0xaf, 0xf1, + 0x36, 0x47, 0x7f, 0xc1, 0x3f, 0x8b, 0xba, 0x4f, 0x63, 0xc4, 0x04, 0x3a, 0x8b, 0xac, 0x56, 0x28, + 0xc9, 0x8a, 0x7b, 0xff, 0x04, 0xdb, 0xa7, 0x11, 0xc5, 0xfb, 0xe5, 0xaa, 0xaa, 0x9b, 0x8c, 0x94, + 0xd4, 0x49, 0xe2, 0xbb, 0xdd, 0xe7, 0xf7, 0xf1, 0x3c, 0x40, 0x8f, 0x9b, 0xa8, 0x9e, 0x78, 0x9a, + 0xaa, 0xaa, 0xe5, 0x71, 0x11, 0xdc, 0xf2, 0x4b, 0x35, 0x2e, 0xd2, 0xfc, 0x46, 0x2b, 0xb9, 0x7e, + 0xfe, 0x5a, 0xd2, 0x85, 0x62, 0x44, 0x4f, 0xc8, 0x55, 0xaf, 0x88, 0xf9, 0x2a, 0xb5, 0xc4, 0xfe, + 0x6e, 0x6c, 0xc5, 0x3f, 0xc9, 0x5d, 0x78, 0x97, 0xd5, 0x49, 0x13, 0x09, 0x91, 0xdf, 0xbd, 0xf1, + 0x35, 0xef, 0xba, 0xae, 0xf8, 0x43, 0xaa, 0xa9, 0xbe, 0xad, 0x2a, 0xac, 0x47, 0x89, 0x77, 0xbf, + 0x11, 0xf1, 0x02, 0xfb, 0xbe, 0xef, 0xc4, 0x04, 0x66, 0xf3, 0x37, 0xbb, 0xde, 0x0e, 0xfe, 0x3b, + 0x93, 0xf9, 0xb9, 0xdf, 0xea, 0x20, 0x4f, 0x89, 0x17, 0xe7, 0xc7, 0xdb, 0xf9, 0x77, 0x92, 0x21, + 0x68, 0x9f, 0x88, 0x9f, 0xf0, 0x87, 0xee, 0xab, 0x5f, 0x65, 0x5a, 0xcb, 0xcc, 0x4c, 0xfd, 0x2f, + 0x17, 0xad, 0x5e, 0x9b, 0xf9, 0x6e, 0xf9, 0xb1, 0x17, 0x10, 0x11, 0xf9, 0xb4, 0xeb, 0xe1, 0x0d, + 0x56, 0xab, 0x54, 0xde, 0x2b, 0xe2, 0x0d, 0xaa, 0x9b, 0xe2, 0x04, 0x92, 0xf4, 0xfc, 0x48, 0x9b, + 0xef, 0xbd, 0xc3, 0x90, 0xc0, 0x20, 0xbe, 0x52, 0xad, 0x6b, 0x8b, 0xad, 0x75, 0x55, 0x2c, 0x23, + 0x09, 0x91, 0x53, 0xf5, 0x5f, 0x17, 0x15, 0xfd, 0xdc, 0xf8, 0x91, 0x5d, 0x56, 0x4d, 0xff, 0xc4, + 0xfc, 0xdc, 0xd8, 0xab, 0x84, 0x2a, 0xb5, 0x5b, 0x75, 0x12, 0x72, 0x15, 0x2b, 0xe1, 0x2b, 0xee, + 0xc7, 0xb3, 0xb5, 0xe6, 0xde, 0xfe, 0x27, 0x5a, 0x97, 0xb9, 0x8d, 0xb0, 0xa6, 0x22, 0xf9, 0x2b, + 0x55, 0x38, 0x52, 0x50, 0x0d, 0x67, 0x39, 0xeb, 0xff, 0xdd, 0xbf, 0xf1, 0x64, 0xad, 0x55, 0x55, + 0x32, 0x72, 0x0b, 0xd5, 0x45, 0x72, 0x0a, 0x7b, 0xde, 0x20, 0x5d, 0xb2, 0xf9, 0x58, 0x3c, 0x1d, + 0x8f, 0xfc, 0x25, 0x17, 0x52, 0x7d, 0xdb, 0xb7, 0xe2, 0x77, 0x77, 0x79, 0xfb, 0x7e, 0x49, 0xa2, + 0x3b, 0x74, 0xdd, 0xfd, 0xd9, 0xe7, 0xf1, 0x10, 0xe7, 0x7a, 0xaa, 0xbe, 0x09, 0x2b, 0xaf, 0x49, + 0x08, 0x08, 0x8b, 0xe5, 0xdd, 0x67, 0xff, 0x36, 0xf1, 0x58, 0x4f, 0x11, 0x12, 0x7e, 0x12, 0x88, + 0xfc, 0xb7, 0x7c, 0x02, 0x47, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3a, 0x1d, 0x30, 0x52, 0x1b, + 0xc5, 0x6f, 0x7b, 0xdf, 0xcb, 0x7b, 0xc1, 0x5f, 0x13, 0xdd, 0xdd, 0xf7, 0xcb, 0x7b, 0xcd, 0x0c, + 0x42, 0x17, 0x77, 0xbb, 0xde, 0x6e, 0x5e, 0xef, 0x88, 0x10, 0x32, 0xd3, 0x35, 0x73, 0xf2, 0xfb, + 0x72, 0xfc, 0xc5, 0x77, 0x6f, 0x10, 0x20, 0x29, 0x54, 0xee, 0xef, 0xae, 0x2e, 0xaa, 0xa4, 0xf1, + 0x7c, 0x5f, 0x76, 0xf5, 0x50, 0x4d, 0xd0, 0x47, 0xa3, 0x21, 0x80, 0xc8, 0xe0, 0x82, 0xaf, 0x53, + 0xfc, 0x5c, 0x71, 0x57, 0xf1, 0xf4, 0x3b, 0xd0, 0x9f, 0xd0, 0xe0, 0xd3, 0x2a, 0x05, 0xa5, 0x88, + 0x12, 0x11, 0xcd, 0xea, 0xfa, 0xaa, 0xaa, 0xe2, 0x23, 0xa5, 0xee, 0x63, 0x59, 0xd0, 0xf5, 0x99, + 0x8c, 0x47, 0xe2, 0x35, 0x5d, 0x64, 0xcc, 0x45, 0xcd, 0x8b, 0x3f, 0x2f, 0x36, 0x13, 0x82, 0xae, + 0x4b, 0xbe, 0x4e, 0x62, 0xae, 0xb0, 0xf1, 0x08, 0x00, 0x62, 0x52, 0xdf, 0xeb, 0xf6, 0x56, 0xf0, + 0xb3, 0xa5, 0x26, 0xce, 0x75, 0x7e, 0x4f, 0x4b, 0xfe, 0xb8, 0x88, 0x46, 0xa4, 0xeb, 0x2a, 0xbe, + 0xb5, 0x85, 0xb0, 0x08, 0x9a, 0xed, 0xc4, 0xaf, 0xd6, 0x8f, 0xf6, 0xfc, 0x17, 0x56, 0x62, 0xea, + 0xa9, 0xa5, 0xea, 0xe8, 0xef, 0x51, 0x10, 0x42, 0x61, 0x5d, 0xfd, 0xc2, 0x02, 0x0b, 0x36, 0x68, + 0x81, 0x6c, 0x47, 0x88, 0x12, 0x09, 0x6d, 0x0f, 0xe4, 0x34, 0xb4, 0x0e, 0xec, 0xf0, 0xb7, 0xf8, + 0x22, 0xbe, 0xdb, 0xd4, 0x21, 0xe2, 0x26, 0xae, 0x8d, 0xc4, 0x08, 0x2f, 0x77, 0xc4, 0xdd, 0x57, + 0xf3, 0x72, 0xe0, 0xef, 0xb0, 0x80, 0x40, 0xbf, 0x36, 0x61, 0x00, 0x84, 0x15, 0xe2, 0x42, 0x77, + 0xbd, 0x2b, 0xf1, 0x22, 0x41, 0x45, 0xf7, 0xc5, 0x76, 0x3c, 0x47, 0x88, 0xf8, 0xfa, 0xae, 0x6a, + 0x69, 0x8e, 0xa1, 0xb9, 0x3a, 0xa9, 0xa7, 0x76, 0x31, 0x31, 0x94, 0xc4, 0x34, 0x69, 0x06, 0xf7, + 0x4e, 0xa7, 0xa3, 0x7b, 0x68, 0x46, 0xfc, 0x40, 0xbe, 0xaa, 0xf4, 0x4e, 0xb9, 0x0a, 0x93, 0xf8, + 0x81, 0x02, 0x08, 0xa2, 0x74, 0xdd, 0x42, 0x6f, 0xbf, 0x84, 0xec, 0xcf, 0x78, 0xac, 0xfc, 0xfc, + 0xdd, 0x36, 0xc1, 0x1f, 0x2d, 0xdb, 0xfc, 0x25, 0x88, 0x7e, 0xb5, 0xf8, 0x25, 0xbb, 0xa6, 0x2a, + 0x8f, 0x8f, 0x6e, 0xff, 0x05, 0x37, 0x7c, 0x56, 0xfe, 0xd1, 0xb2, 0xff, 0x25, 0xf3, 0x31, 0x89, + 0x12, 0x08, 0xb3, 0xe9, 0xbc, 0xb7, 0x88, 0x08, 0x6d, 0xbf, 0x2d, 0x1d, 0x75, 0xc4, 0x89, 0x04, + 0xd7, 0x9f, 0x49, 0xa9, 0xdb, 0xd9, 0xc4, 0x89, 0x25, 0x45, 0xfc, 0x4f, 0x84, 0x04, 0x08, 0xdd, + 0xc7, 0x6e, 0x3d, 0xf9, 0xc4, 0x09, 0x1d, 0xc4, 0x9c, 0x5d, 0x99, 0xb0, 0x47, 0x0b, 0xfc, 0x40, + 0x45, 0xcd, 0x40, 0x7d, 0x85, 0xf8, 0x9e, 0x08, 0x69, 0xd6, 0xe0, 0x11, 0xc4, 0xc1, 0x3d, 0xee, + 0x7e, 0x2b, 0xbb, 0xbf, 0xc2, 0x19, 0x29, 0xb4, 0xbb, 0xda, 0xf8, 0x4b, 0x7b, 0xdd, 0x5a, 0xc4, + 0xc4, 0x66, 0xf5, 0xaa, 0xfc, 0x76, 0x76, 0xde, 0xca, 0xf7, 0xfb, 0x9f, 0x79, 0x22, 0x04, 0x78, + 0x60, 0x13, 0x6b, 0x37, 0xa9, 0xa2, 0xda, 0xf6, 0x16, 0x89, 0x6f, 0xff, 0xfb, 0x9b, 0x82, 0x71, + 0x19, 0x70, 0x43, 0x8f, 0x6c, 0x19, 0x66, 0x95, 0x78, 0x53, 0xbb, 0xbb, 0xdc, 0xfe, 0xd7, 0xca, + 0x57, 0xe7, 0x72, 0xdb, 0xbf, 0xc4, 0xea, 0x95, 0xe2, 0xb8, 0x77, 0x9b, 0xbb, 0x9e, 0x26, 0x3f, + 0x19, 0x68, 0xf7, 0xbc, 0x55, 0x46, 0x97, 0x12, 0x0c, 0x02, 0x90, 0x50, 0x75, 0x09, 0x80, 0xd0, + 0x9c, 0x65, 0x1c, 0x6e, 0x31, 0x5a, 0x83, 0x33, 0xc5, 0x82, 0xa2, 0x68, 0x16, 0xaa, 0x50, 0x78, + 0xf3, 0x3d, 0xe7, 0x32, 0x76, 0x3b, 0xdf, 0x89, 0x04, 0x01, 0x4b, 0xee, 0xa9, 0x63, 0xb6, 0x5d, + 0x26, 0x62, 0xb8, 0x6f, 0xad, 0x56, 0xad, 0x5c, 0x9e, 0x5d, 0xf0, 0x5d, 0xca, 0xc7, 0x97, 0x2b, + 0xc4, 0x17, 0x8e, 0x34, 0x7e, 0x14, 0x8b, 0xaa, 0xd5, 0x75, 0xcd, 0x0c, 0x98, 0x58, 0x16, 0xe1, + 0x18, 0x27, 0x85, 0x5c, 0x83, 0xbc, 0xb2, 0x36, 0xac, 0x04, 0xd8, 0x40, 0x37, 0x10, 0x45, 0x48, + 0x3f, 0x4e, 0x6f, 0x82, 0x9b, 0x1e, 0x2d, 0x2c, 0x09, 0x44, 0xcf, 0xf5, 0x55, 0xdb, 0xaf, 0xcb, + 0x4d, 0xc9, 0x15, 0xb6, 0x7c, 0xad, 0x71, 0xfd, 0x99, 0xd0, 0x8f, 0x97, 0x95, 0x23, 0x5f, 0xbc, + 0x1d, 0xe0, 0x97, 0x82, 0xa9, 0x33, 0xa0, 0x7e, 0x25, 0xf3, 0xbe, 0x57, 0x2f, 0x24, 0x9d, 0x4e, + 0xf8, 0xcd, 0x95, 0x85, 0xd9, 0x04, 0xc0, 0x35, 0xf4, 0x9f, 0x19, 0xcf, 0x0e, 0x5d, 0xbc, 0x22, + 0x10, 0x05, 0x5a, 0xb8, 0x56, 0xc9, 0x45, 0xfb, 0x8a, 0xee, 0xde, 0x20, 0x25, 0x93, 0x32, 0xe7, + 0xf8, 0x42, 0x92, 0x5b, 0xea, 0xee, 0xbf, 0x35, 0xf3, 0x7f, 0x26, 0xeb, 0xc4, 0xc6, 0x64, 0x62, + 0x3c, 0x80, 0x40, 0xb0, 0x8e, 0xc6, 0x78, 0xa5, 0x00, 0xf0, 0xd5, 0x75, 0x42, 0xf4, 0xd5, 0x75, + 0x75, 0x0e, 0x8c, 0x4b, 0xf0, 0x57, 0x67, 0xcd, 0x9f, 0x2b, 0x9b, 0x17, 0x29, 0xfa, 0xb0, 0x7c, + 0x15, 0x59, 0x3d, 0x91, 0xea, 0xd4, 0xa0, 0x36, 0x57, 0xbf, 0xc5, 0xeb, 0x3e, 0x2d, 0xde, 0x1f, + 0xef, 0x7b, 0x97, 0x82, 0x59, 0x7d, 0xf3, 0xff, 0x5f, 0x26, 0xb5, 0xf1, 0x45, 0xad, 0x77, 0x7e, + 0x10, 0x21, 0x1e, 0xbe, 0x10, 0x57, 0xf0, 0x80, 0x22, 0xf1, 0x7a, 0xf0, 0x80, 0x22, 0xca, 0xa8, + 0xbb, 0xf8, 0x80, 0x55, 0xa8, 0xc2, 0xd2, 0x91, 0x73, 0x31, 0x35, 0xa6, 0x2e, 0x1c, 0x4c, 0xbc, + 0x94, 0x9b, 0x9a, 0x56, 0x15, 0xba, 0xe0, 0xb2, 0xba, 0xaa, 0xd2, 0x99, 0x86, 0x38, 0xbb, 0xe5, + 0xb6, 0xad, 0xfc, 0x23, 0xb6, 0x95, 0xe9, 0xdb, 0xdb, 0xf2, 0xd5, 0xb5, 0x82, 0x38, 0x89, 0x24, + 0xed, 0xf1, 0x4e, 0x72, 0x38, 0x40, 0x31, 0xc4, 0x88, 0x04, 0x74, 0xda, 0x17, 0x58, 0xb8, 0x99, + 0x66, 0xeb, 0xf0, 0xc7, 0x89, 0xf8, 0xce, 0xaf, 0x6e, 0x2f, 0x72, 0xd1, 0xb4, 0x40, 0xd4, 0x9d, + 0x57, 0x48, 0x4f, 0x25, 0xf5, 0xf1, 0xd3, 0xfb, 0xa3, 0x5a, 0xcd, 0x42, 0xe2, 0xd4, 0x1b, 0xee, + 0xed, 0xe2, 0x79, 0xb7, 0xbe, 0x24, 0x40, 0x25, 0x85, 0xb8, 0xc9, 0x34, 0xe7, 0xdf, 0x7f, 0x08, + 0x17, 0x5a, 0xf8, 0x8b, 0xbf, 0x17, 0xfc, 0x44, 0x5d, 0x55, 0x45, 0xd5, 0x57, 0x88, 0x26, 0x6f, + 0xac, 0x48, 0x53, 0x55, 0x59, 0x52, 0x8c, 0xe5, 0xa8, 0xd6, 0x72, 0xf7, 0x60, 0xe7, 0x94, 0x61, + 0x5e, 0x5b, 0x1f, 0x0a, 0x4e, 0xe4, 0x50, 0xde, 0xe1, 0xc2, 0x03, 0x6f, 0x6b, 0x7c, 0xea, 0xd7, + 0x11, 0xf0, 0x60, 0x76, 0x54, 0xdc, 0xe2, 0x3f, 0x13, 0xcd, 0x71, 0x59, 0x48, 0x3f, 0x10, 0x0a, + 0xae, 0x3a, 0xc9, 0x28, 0xb1, 0x36, 0x23, 0x95, 0x9b, 0xd8, 0xc5, 0x51, 0xc7, 0x06, 0xe1, 0x4b, + 0x6d, 0x1b, 0x9f, 0xcc, 0xd9, 0x90, 0xd5, 0x36, 0x49, 0x92, 0xf9, 0x50, 0x24, 0x92, 0xf1, 0x77, + 0xdd, 0x63, 0xd8, 0x33, 0x2b, 0x1d, 0xe0, 0x8e, 0xaa, 0x0b, 0xfc, 0x05, 0x9e, 0xe7, 0x29, 0x79, + 0x78, 0x58, 0x72, 0x25, 0x54, 0x77, 0x37, 0x55, 0x2c, 0x48, 0x97, 0xbb, 0xfc, 0x55, 0x75, 0x6d, + 0x75, 0xc9, 0xad, 0x7d, 0xd7, 0x72, 0x62, 0x07, 0xd5, 0x36, 0x34, 0xb7, 0x76, 0x3b, 0xfc, 0x5c, + 0x1f, 0xe4, 0x7f, 0xef, 0xbc, 0x43, 0x41, 0xbf, 0x71, 0x22, 0xfa, 0x16, 0x59, 0x3d, 0x6f, 0x48, + 0x03, 0xc4, 0x53, 0x8f, 0x98, 0x88, 0xbd, 0x62, 0xe8, 0xd7, 0x12, 0x25, 0xea, 0xfe, 0x11, 0x05, + 0x97, 0x3d, 0x5e, 0xbe, 0x5e, 0xed, 0xb5, 0x89, 0xce, 0x3c, 0x29, 0x50, 0x62, 0xa8, 0x4e, 0xee, + 0xc4, 0x81, 0xcb, 0x3a, 0x33, 0xad, 0xf7, 0x77, 0x25, 0x3d, 0x27, 0xf8, 0x52, 0x39, 0x99, 0xdc, + 0x71, 0x26, 0x0e, 0xc8, 0x07, 0x79, 0x49, 0x7d, 0x46, 0x12, 0xea, 0x84, 0x4e, 0x2f, 0x15, 0x7c, + 0x55, 0xec, 0x1a, 0xaa, 0xbb, 0x5e, 0x23, 0x69, 0x49, 0xac, 0xd6, 0xfe, 0xbd, 0x13, 0xd7, 0xbe, + 0x09, 0x29, 0x9f, 0x62, 0x7c, 0x04, 0x5c, 0x23, 0x19, 0xac, 0x5e, 0x4e, 0x98, 0x93, 0x24, 0xd9, + 0x3a, 0x02, 0x8d, 0xeb, 0x84, 0x44, 0x02, 0xbe, 0x2b, 0xb2, 0xe5, 0x3f, 0x49, 0x35, 0x5e, 0x57, + 0xc5, 0x6f, 0x7b, 0xdf, 0x08, 0x89, 0x11, 0x77, 0x77, 0x84, 0x76, 0xcd, 0x6b, 0x18, 0x44, 0x48, + 0x8e, 0x3c, 0xdd, 0x09, 0xe2, 0xb4, 0x47, 0xc0, 0x8f, 0x75, 0xac, 0x57, 0x05, 0x59, 0xba, 0xd7, + 0x9e, 0x1a, 0x8b, 0xad, 0xde, 0x24, 0x16, 0x7a, 0x41, 0xea, 0xb2, 0xd5, 0x7a, 0x92, 0x8e, 0x78, + 0x90, 0xa6, 0x4a, 0xd5, 0x09, 0x6d, 0x0e, 0xa2, 0xff, 0xaf, 0x16, 0xe6, 0x72, 0xbe, 0xcf, 0x4e, + 0x66, 0x24, 0xb5, 0x77, 0x4e, 0xb1, 0x21, 0x10, 0x55, 0x20, 0x7a, 0x4c, 0x17, 0xe3, 0xe2, 0xc9, + 0xc5, 0x4f, 0x71, 0xf5, 0x9a, 0xad, 0xdf, 0x04, 0xd7, 0xac, 0x99, 0x65, 0x6e, 0x26, 0x3b, 0xaa, + 0xcb, 0x8b, 0xee, 0x68, 0xf1, 0x02, 0x37, 0x77, 0x8e, 0x78, 0x57, 0x7e, 0x33, 0x93, 0x17, 0xde, + 0xe9, 0x6a, 0xee, 0xbf, 0x13, 0x7b, 0xcf, 0xbc, 0x64, 0x4c, 0x7e, 0x7f, 0xa6, 0xba, 0x9c, 0xde, + 0x6e, 0x9f, 0x11, 0xf0, 0x96, 0xef, 0x37, 0xd1, 0xae, 0x5d, 0x53, 0x75, 0xc1, 0x37, 0x76, 0xb6, + 0xd2, 0x7a, 0xe5, 0x83, 0x2a, 0x99, 0x4a, 0xa6, 0x1a, 0xc2, 0x20, 0x93, 0x7b, 0xbf, 0xc1, 0x5f, + 0x37, 0xf1, 0x3c, 0xb4, 0xb3, 0x7e, 0xe2, 0x60, 0xaf, 0x7b, 0x54, 0x94, 0xd8, 0x92, 0xc6, 0xcb, + 0xbe, 0x6e, 0xad, 0xf8, 0xea, 0xb2, 0xa2, 0x4a, 0xfa, 0xab, 0x2f, 0x11, 0x58, 0x15, 0xeb, 0x5e, + 0x11, 0x04, 0xb8, 0xf2, 0xf6, 0x71, 0x54, 0xa9, 0x33, 0xe3, 0xe7, 0xc6, 0xd2, 0x2f, 0xbb, 0xbb, + 0xfe, 0xf8, 0xae, 0x33, 0x08, 0x0b, 0xaa, 0xf5, 0xa5, 0x88, 0x85, 0x3a, 0xab, 0xa9, 0xb1, 0xd8, + 0x2e, 0xc9, 0x54, 0x93, 0xe2, 0xfc, 0x5c, 0xa0, 0xf8, 0xea, 0x85, 0xb4, 0x99, 0xf2, 0xe0, 0xe2, + 0x09, 0x9f, 0x10, 0x23, 0x36, 0x3e, 0x2e, 0x4c, 0xf1, 0x3f, 0x93, 0x1c, 0xec, 0xe2, 0x22, 0xae, + 0x99, 0x58, 0xca, 0xc7, 0xc4, 0xcd, 0x55, 0xfd, 0xd4, 0x2f, 0xc2, 0x1c, 0xd7, 0xdb, 0x15, 0xd5, + 0xfc, 0x4b, 0xd2, 0x1b, 0x4a, 0xf8, 0x9e, 0x22, 0x3f, 0x5a, 0xd5, 0xf3, 0xc1, 0x6a, 0xe2, 0x42, + 0x39, 0x69, 0x46, 0xe3, 0xac, 0x8d, 0x95, 0x0c, 0x74, 0x64, 0xcc, 0xaa, 0x9f, 0x84, 0x75, 0x54, + 0xc9, 0x2e, 0xc8, 0x9f, 0xe4, 0xe2, 0xf5, 0xb7, 0xaa, 0x9b, 0x9e, 0xbf, 0xc5, 0xfc, 0x3d, 0xe2, + 0xb1, 0xdc, 0x13, 0x0c, 0xa4, 0x23, 0x52, 0xaa, 0xf5, 0x5c, 0xba, 0x0b, 0xe1, 0xf9, 0xfd, 0x9f, + 0x10, 0x33, 0xa5, 0x89, 0xe6, 0x4e, 0xa4, 0xfa, 0x91, 0x89, 0x21, 0xf8, 0x23, 0x9f, 0xde, 0x9c, + 0xbe, 0x14, 0x91, 0x42, 0xea, 0x8a, 0xa6, 0x64, 0x5f, 0x19, 0x4c, 0xf4, 0xaa, 0x66, 0x05, 0xcf, + 0x34, 0xcb, 0xc4, 0x04, 0x77, 0xa1, 0x9d, 0x45, 0x9f, 0x1e, 0x8c, 0x05, 0xf4, 0xb3, 0x2e, 0xfa, + 0xf1, 0x78, 0x88, 0xdb, 0xa0, 0xe2, 0xb7, 0xf1, 0x05, 0x97, 0xb6, 0xef, 0xe2, 0xab, 0x55, 0xcb, + 0x9e, 0x23, 0x88, 0x85, 0xa7, 0xf6, 0xed, 0xc7, 0xe9, 0x80, 0x15, 0x64, 0x87, 0xc3, 0xd1, 0x22, + 0x59, 0x62, 0xfa, 0x88, 0x97, 0x69, 0x03, 0x17, 0x5c, 0xd9, 0xf3, 0x7c, 0xc4, 0xd5, 0x7c, 0xbc, + 0xd8, 0xa6, 0xe0, 0x97, 0x8d, 0x65, 0xb3, 0x1e, 0xaa, 0xc3, 0x5c, 0xa5, 0xf1, 0x5d, 0x53, 0x49, + 0xc7, 0xb3, 0x8f, 0x88, 0x09, 0x5f, 0x4e, 0xeb, 0xf1, 0x22, 0x74, 0xaa, 0xaa, 0x97, 0xcd, 0xe3, + 0x74, 0xc4, 0x5d, 0xb5, 0xf1, 0x12, 0x47, 0xc7, 0x28, 0x65, 0x6f, 0x71, 0xf8, 0x98, 0x4f, 0x50, + 0xdc, 0xed, 0xac, 0xd2, 0x5f, 0x89, 0xdd, 0xee, 0x33, 0x2a, 0xfc, 0x1f, 0xc9, 0xad, 0x4d, 0x13, + 0x8a, 0x15, 0x28, 0xd4, 0xd4, 0x28, 0x48, 0x4b, 0xa6, 0xa7, 0xa6, 0x9f, 0xfe, 0xb9, 0xba, 0xab, + 0xe4, 0x25, 0x52, 0x49, 0x72, 0x5a, 0x71, 0x71, 0xc5, 0xc4, 0xc1, 0x0d, 0xf5, 0x3b, 0xfc, 0xbc, + 0x5e, 0x6e, 0xea, 0xf7, 0xf2, 0x5d, 0xfc, 0x47, 0xe6, 0xd5, 0x43, 0xc7, 0xe5, 0x88, 0x25, 0xc2, + 0xcf, 0x81, 0xae, 0xd4, 0xab, 0x34, 0x2e, 0x6e, 0xee, 0x1a, 0x89, 0xf1, 0x3a, 0xe1, 0x33, 0xaa, + 0xeb, 0x5f, 0x96, 0xaa, 0xbc, 0x4f, 0xe4, 0xd6, 0xab, 0x8e, 0xea, 0xb5, 0x5d, 0x55, 0x46, 0x71, + 0x46, 0x27, 0x7e, 0xf7, 0xf2, 0xde, 0xfe, 0x21, 0xc5, 0xeb, 0xc4, 0x42, 0x7c, 0xd9, 0xba, 0x06, + 0xf8, 0x8f, 0xc7, 0xd6, 0x2f, 0x77, 0xb5, 0x55, 0xf9, 0xb7, 0xba, 0xc4, 0x84, 0xae, 0x2b, 0xec, + 0xe7, 0xcf, 0x5e, 0x82, 0x0c, 0x4d, 0x72, 0x1d, 0x57, 0x27, 0x66, 0x55, 0x58, 0x9e, 0x5d, 0x6b, + 0x89, 0x12, 0x6d, 0xc5, 0xd0, 0xff, 0x88, 0xfc, 0x98, 0xad, 0x4b, 0xfc, 0x25, 0x71, 0x5e, 0xdd, + 0xbf, 0x12, 0x2b, 0x7b, 0xee, 0xe1, 0xde, 0x84, 0xb4, 0xdc, 0x56, 0xab, 0x5d, 0xd7, 0x7a, 0xd5, + 0xe2, 0x18, 0x87, 0x7c, 0xfc, 0x96, 0x95, 0x7e, 0x6d, 0xdf, 0xe3, 0xee, 0xfc, 0xac, 0x36, 0xba, + 0xe6, 0x37, 0x7e, 0x24, 0x15, 0xda, 0x15, 0x50, 0xad, 0xdb, 0x5b, 0x4d, 0xd3, 0x2c, 0x40, 0x90, + 0x95, 0x56, 0xa6, 0xdb, 0x0f, 0xe6, 0xe3, 0x98, 0x6c, 0x7c, 0x5c, 0xd1, 0xc7, 0xcf, 0x06, 0xd7, + 0x2e, 0x6f, 0x82, 0xfe, 0x4b, 0xb7, 0xa8, 0x88, 0x4a, 0xa9, 0x76, 0xed, 0xf1, 0x01, 0x2d, 0x6a, + 0x87, 0x1b, 0xa5, 0x1e, 0x20, 0x48, 0x8f, 0x2f, 0x3f, 0xd4, 0xd7, 0x5b, 0x58, 0xe2, 0x5d, 0xac, + 0x2b, 0xe9, 0x3c, 0x4c, 0x33, 0x13, 0x9b, 0xbe, 0xaa, 0x16, 0xc4, 0x12, 0xf7, 0xac, 0x4c, 0x16, + 0xf3, 0x6e, 0xff, 0x7d, 0xdc, 0x02, 0x47, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3b, 0x1d, 0xb0, + 0x88, 0x9c, 0xd7, 0x7b, 0x89, 0xe5, 0xea, 0xd7, 0x94, 0xad, 0x49, 0xae, 0x0b, 0x78, 0xfa, 0x77, + 0x72, 0xfe, 0xe9, 0x34, 0xee, 0xb9, 0x77, 0xb9, 0x39, 0x89, 0x17, 0x51, 0x21, 0xf8, 0x42, 0x0a, + 0x4c, 0xec, 0x1b, 0xd6, 0x6e, 0x4e, 0xfb, 0xc7, 0x38, 0x88, 0xfa, 0x6d, 0xc7, 0x7b, 0x77, 0xbf, + 0x11, 0x05, 0x13, 0x75, 0xaa, 0xef, 0xdf, 0x09, 0x09, 0xc4, 0xe0, 0xb8, 0x54, 0x57, 0xf1, 0x9d, + 0xdd, 0xef, 0x68, 0x7b, 0x52, 0x7a, 0x97, 0xaf, 0x9b, 0x3c, 0x5f, 0x0c, 0xb7, 0x55, 0xa3, 0x31, + 0x72, 0x5b, 0x70, 0x55, 0xcb, 0xcd, 0x89, 0x78, 0x46, 0xfb, 0xe5, 0xcb, 0xde, 0x58, 0x88, 0x44, + 0x45, 0x8e, 0x76, 0x54, 0x8c, 0x49, 0xd7, 0x6c, 0x52, 0xc4, 0x41, 0x51, 0x5d, 0x8d, 0xfe, 0xa6, + 0x49, 0x0e, 0xdc, 0x6e, 0xab, 0xb9, 0x4a, 0x3b, 0xf1, 0x02, 0x42, 0x13, 0x10, 0x7a, 0xaa, 0xd5, + 0x56, 0x6f, 0xe1, 0x22, 0x3b, 0xea, 0x22, 0xc4, 0x73, 0x84, 0x21, 0x41, 0x3e, 0x2e, 0x68, 0x25, + 0x2d, 0x54, 0xcc, 0x6a, 0x2e, 0xba, 0xfa, 0x33, 0xfc, 0x74, 0x9b, 0x4f, 0x5b, 0xdd, 0x45, 0xff, + 0x27, 0x77, 0x5d, 0x04, 0xfa, 0x09, 0xf8, 0xe3, 0x2a, 0xf6, 0xa9, 0xaa, 0xfe, 0x61, 0x8f, 0xb9, + 0x38, 0xa1, 0x35, 0x8b, 0xea, 0x6f, 0xc2, 0x22, 0x05, 0x56, 0x44, 0x8d, 0x65, 0x91, 0x83, 0xf8, + 0x80, 0x52, 0x56, 0xe6, 0xd5, 0x49, 0xfb, 0x77, 0x7f, 0x84, 0xc9, 0x5a, 0xd5, 0x57, 0x13, 0x19, + 0x24, 0x25, 0x49, 0xf5, 0x55, 0x26, 0xd1, 0x67, 0x57, 0x4b, 0xc1, 0x20, 0xbd, 0xdd, 0xfc, 0x20, + 0xbd, 0xf0, 0x44, 0x49, 0x9b, 0xbd, 0x72, 0x91, 0x03, 0xaa, 0x82, 0x9e, 0x42, 0xbe, 0xef, 0x98, + 0xf5, 0xae, 0x20, 0x22, 0x41, 0x11, 0x3c, 0x88, 0xe6, 0x20, 0x40, 0x52, 0x99, 0xc8, 0x2c, 0x1d, + 0x80, 0x9e, 0xe2, 0xb6, 0xd3, 0x6d, 0x5d, 0xdd, 0xf5, 0xf1, 0x1a, 0x06, 0xe8, 0x7a, 0x19, 0x98, + 0x85, 0xdc, 0x01, 0xd6, 0x91, 0xd3, 0xdf, 0x76, 0x5d, 0x8b, 0x46, 0xee, 0x3d, 0xda, 0xea, 0x4b, + 0xf1, 0x02, 0x01, 0x65, 0xdf, 0xaa, 0xd5, 0x6a, 0xfc, 0x44, 0x15, 0xcf, 0x92, 0xdb, 0x26, 0x7f, + 0xd5, 0xcb, 0x95, 0xc2, 0x1f, 0x08, 0x18, 0xbb, 0x9d, 0x8f, 0x14, 0x47, 0xbf, 0x77, 0xc4, 0x08, + 0x21, 0x32, 0x67, 0x10, 0x20, 0x5f, 0x46, 0x5a, 0x65, 0xc1, 0x0e, 0x62, 0x02, 0x06, 0xb6, 0x26, + 0xc0, 0xf2, 0xce, 0x20, 0x47, 0xd0, 0x45, 0xe0, 0x9b, 0xb3, 0x5d, 0x27, 0x71, 0x22, 0x05, 0x0a, + 0x5d, 0x3d, 0x37, 0xf0, 0xa1, 0xdd, 0xdd, 0xc4, 0xb8, 0x5b, 0xdc, 0x2c, 0xe9, 0x59, 0x79, 0xa9, + 0x1b, 0xa7, 0xbf, 0x13, 0x0a, 0x4b, 0x8e, 0xb7, 0xaa, 0xbb, 0x06, 0x50, 0xc0, 0x62, 0x77, 0x97, + 0x1b, 0xfc, 0xff, 0x19, 0x29, 0x0c, 0xd6, 0xc6, 0xab, 0x26, 0x6d, 0x2d, 0xb9, 0x25, 0xf8, 0xc2, + 0x62, 0xb8, 0x3e, 0x26, 0x13, 0xde, 0xad, 0x17, 0xa2, 0xbc, 0x23, 0x05, 0x06, 0x6d, 0x55, 0x27, + 0x77, 0x15, 0xf7, 0x89, 0x19, 0x71, 0x59, 0x79, 0xcb, 0x0f, 0xaf, 0x9e, 0x1f, 0x69, 0x78, 0x80, + 0x9f, 0x77, 0xd3, 0x7f, 0x18, 0x25, 0xdd, 0xdd, 0xef, 0x77, 0xbb, 0xbf, 0xe0, 0x84, 0xae, 0xfb, + 0xf8, 0x80, 0x4a, 0x21, 0x20, 0xfd, 0x2f, 0x3b, 0x9f, 0xdf, 0x21, 0x24, 0x47, 0xd7, 0x10, 0x22, + 0x6c, 0x45, 0x05, 0xd8, 0x47, 0xff, 0x87, 0x07, 0xdf, 0xde, 0x08, 0xb8, 0xa0, 0x83, 0xba, 0x59, + 0x73, 0xf1, 0x85, 0x1a, 0x66, 0xaf, 0xcb, 0x35, 0x24, 0x7d, 0xa3, 0x64, 0xb6, 0x10, 0xb7, 0x4b, + 0x9e, 0x44, 0xa9, 0x7c, 0x40, 0xbb, 0xea, 0x6e, 0xec, 0xf3, 0x89, 0x13, 0xf0, 0x51, 0x17, 0xaa, + 0x35, 0x45, 0xf5, 0x62, 0x44, 0x91, 0xe5, 0x4a, 0xe9, 0x1f, 0x9f, 0x3e, 0x24, 0x45, 0x55, 0xea, + 0x6e, 0x94, 0xf8, 0xae, 0xa2, 0xe6, 0xf9, 0xbd, 0x44, 0x09, 0x11, 0xc5, 0xd6, 0xf5, 0xe2, 0x68, + 0x41, 0x34, 0x2d, 0x05, 0x53, 0x72, 0x4e, 0x82, 0x5d, 0xf0, 0x86, 0x6c, 0x71, 0xea, 0x7f, 0x3f, + 0xae, 0x2f, 0xcf, 0x0b, 0x27, 0xf8, 0xbb, 0x2b, 0xe8, 0xd0, 0xcd, 0x00, 0xc7, 0x77, 0xbf, 0xcb, + 0xe2, 0xfe, 0x11, 0xba, 0x4e, 0xf7, 0xbb, 0xee, 0x4e, 0xf3, 0xe6, 0xb8, 0xcd, 0xcf, 0x84, 0xaa, + 0xbb, 0xba, 0xf5, 0xba, 0xdc, 0xf8, 0xf8, 0x99, 0xbb, 0xbf, 0x8b, 0xf1, 0x27, 0x1c, 0xe9, 0x34, + 0x35, 0xc9, 0x96, 0x56, 0xfc, 0xbc, 0xcf, 0x64, 0x4e, 0x2f, 0xa9, 0xb3, 0x0d, 0xe2, 0x5f, 0x12, + 0x26, 0xf0, 0x77, 0xe8, 0x63, 0xd7, 0x74, 0x0a, 0x9c, 0x34, 0xc6, 0x8c, 0xdd, 0xff, 0xfe, 0x7f, + 0xdf, 0x30, 0xad, 0x91, 0x71, 0xf5, 0xcb, 0xe4, 0x24, 0xd2, 0xfc, 0x31, 0x77, 0x44, 0x51, 0x84, + 0xbd, 0xe4, 0xe4, 0x56, 0xdc, 0x9f, 0xfc, 0x15, 0xee, 0xee, 0xee, 0xfb, 0xbb, 0xb8, 0xae, 0xbe, + 0x4e, 0xab, 0xe4, 0xd6, 0xe1, 0x9e, 0x6e, 0xab, 0xe5, 0xb4, 0xab, 0x2f, 0x16, 0x2c, 0xdd, 0x7d, + 0x57, 0xc2, 0x66, 0x77, 0xde, 0xef, 0xe5, 0xbb, 0xdf, 0xc6, 0x55, 0x6b, 0xad, 0x26, 0xe9, 0x22, + 0x27, 0xff, 0x89, 0x23, 0x09, 0xd2, 0xae, 0xb8, 0x46, 0x14, 0xa4, 0x4d, 0xf0, 0xae, 0x03, 0x33, + 0xc7, 0x32, 0xf0, 0xcc, 0x8a, 0x15, 0xdc, 0x7f, 0x16, 0x67, 0x7e, 0x11, 0x8b, 0x80, 0xcd, 0xc4, + 0x62, 0xaf, 0xee, 0x63, 0x8f, 0xde, 0x4a, 0xa9, 0xe4, 0xd1, 0xd7, 0xc9, 0xb9, 0x7d, 0x92, 0x11, + 0x10, 0x14, 0xac, 0x4b, 0xc0, 0x63, 0xc8, 0xf0, 0x18, 0xc6, 0x34, 0x89, 0x3d, 0x71, 0xe4, 0xe3, + 0x2a, 0x74, 0xe2, 0x20, 0x9b, 0x9e, 0xcf, 0x42, 0x9d, 0x9c, 0xdc, 0x17, 0xae, 0x5f, 0x7d, 0xdf, + 0xdc, 0x4e, 0x9f, 0xe4, 0xbb, 0xfe, 0x13, 0xd5, 0x0f, 0x4e, 0xbe, 0x5e, 0x6c, 0x50, 0xcf, 0x26, + 0xb5, 0xf7, 0x26, 0x2f, 0x27, 0x75, 0xac, 0xd0, 0x80, 0x80, 0x4b, 0x7b, 0xc5, 0xc5, 0xfe, 0xf1, + 0x02, 0x3a, 0xac, 0x96, 0xaf, 0xdc, 0x5e, 0xc8, 0x92, 0x7c, 0x24, 0x7d, 0xdd, 0x9b, 0xfe, 0x09, + 0x89, 0x7b, 0xea, 0xad, 0xf0, 0x4f, 0xa4, 0x74, 0x49, 0x06, 0x8e, 0xd4, 0x8d, 0x5b, 0xbe, 0xeb, + 0x0c, 0x7a, 0xae, 0x5b, 0xee, 0xba, 0xea, 0xb1, 0x0c, 0xaa, 0xb5, 0xf0, 0xa5, 0xb2, 0x6b, 0x7a, + 0x4a, 0xd5, 0xd7, 0x55, 0x31, 0x08, 0xed, 0xf0, 0xf8, 0x93, 0x29, 0x32, 0xd2, 0x78, 0xbe, 0x23, + 0xbb, 0x96, 0x54, 0x2b, 0xf9, 0xae, 0xcb, 0xf0, 0x85, 0xa6, 0x96, 0x3b, 0xfa, 0x79, 0xcc, 0x71, + 0xc3, 0x74, 0x87, 0xa2, 0x25, 0xaa, 0xaf, 0xc5, 0x5e, 0xf7, 0xdf, 0xdd, 0xf5, 0x27, 0x16, 0x56, + 0x65, 0x66, 0x6f, 0x4e, 0x7c, 0xf1, 0x85, 0x17, 0xf9, 0x3d, 0xf6, 0xaa, 0xbe, 0x22, 0x5d, 0x24, + 0xbe, 0x3f, 0xa9, 0x32, 0x6f, 0xbd, 0xfe, 0x3e, 0xca, 0x5c, 0xd9, 0x9f, 0x35, 0x5f, 0xc5, 0x1a, + 0xab, 0x55, 0x55, 0xf0, 0x43, 0x55, 0xeb, 0xe5, 0xaa, 0x7a, 0xeb, 0xdf, 0x24, 0x6f, 0xdf, 0xf4, + 0x25, 0x2b, 0x51, 0x15, 0x7f, 0x8a, 0x14, 0x95, 0x62, 0xbe, 0x7f, 0xf7, 0x77, 0xfc, 0x15, 0x1e, + 0xa4, 0xc8, 0xf2, 0xec, 0xf2, 0x6d, 0x2b, 0x1e, 0x23, 0xe0, 0xb4, 0xd0, 0x91, 0x4a, 0xc8, 0x87, + 0xbe, 0xdf, 0x04, 0x3c, 0x9f, 0xd0, 0xcf, 0x37, 0x55, 0xf0, 0x9d, 0xf7, 0xad, 0x5f, 0x18, 0x75, + 0x7b, 0xbd, 0xf7, 0xbb, 0xdf, 0xe6, 0x26, 0xef, 0xef, 0x37, 0xfc, 0x9b, 0x02, 0x54, 0xfd, 0x59, + 0x5d, 0x5f, 0xe6, 0x3b, 0xda, 0x6b, 0x10, 0x20, 0x49, 0x1c, 0xb4, 0xde, 0xfe, 0x20, 0xb5, 0x63, + 0x27, 0xf8, 0x40, 0x55, 0x55, 0x56, 0xb5, 0xf2, 0xd6, 0xbf, 0x05, 0x17, 0x6f, 0x5c, 0xac, 0x4b, + 0xe1, 0x22, 0x6e, 0xdd, 0xda, 0xfb, 0x29, 0x7e, 0x3a, 0xe0, 0x8a, 0x44, 0xac, 0x77, 0x62, 0xf9, + 0x89, 0xcd, 0xfc, 0x76, 0x0f, 0xf9, 0x14, 0x35, 0x84, 0xea, 0x67, 0xef, 0x3f, 0x58, 0x80, 0x95, + 0x57, 0x75, 0xaf, 0x13, 0x0f, 0xc4, 0x41, 0x50, 0xdb, 0xde, 0x5f, 0xee, 0xef, 0x5c, 0x50, 0xad, + 0xdb, 0x7b, 0xfd, 0x7a, 0x4e, 0xbd, 0xf6, 0x56, 0x75, 0xfb, 0xaa, 0xaa, 0xf8, 0x4f, 0x54, 0x18, + 0xe5, 0x54, 0xe9, 0xae, 0x38, 0xcb, 0x58, 0x71, 0xea, 0xec, 0xfe, 0x1e, 0x17, 0xc8, 0xbf, 0xbd, + 0x6c, 0xfc, 0x23, 0xe7, 0xad, 0xe5, 0x20, 0xee, 0xfe, 0x08, 0xaf, 0x77, 0xaf, 0x8a, 0xd2, 0x3e, + 0x8f, 0xfa, 0xc1, 0xb0, 0x37, 0xf2, 0xcf, 0xfd, 0x73, 0x16, 0x3a, 0xbf, 0xc8, 0x45, 0x64, 0xd9, + 0x23, 0xe6, 0xcd, 0x4f, 0xc7, 0xe2, 0xe6, 0x60, 0xbc, 0x71, 0x73, 0xbe, 0xb4, 0xdb, 0x15, 0xc5, + 0x97, 0x77, 0xb8, 0xef, 0x99, 0x20, 0xaf, 0x21, 0x2a, 0xab, 0xc2, 0x04, 0x3b, 0xbe, 0xb8, 0x4b, + 0x15, 0xbf, 0x57, 0xf1, 0x12, 0x77, 0x5d, 0x6a, 0xb8, 0x21, 0x26, 0xad, 0xbb, 0xe6, 0xdd, 0xfe, + 0x6e, 0x3d, 0xe1, 0x8f, 0x4b, 0x78, 0xbe, 0x0f, 0xf6, 0x32, 0x67, 0x4c, 0xa9, 0xf2, 0x15, 0xcc, + 0x7f, 0x09, 0x6f, 0x7e, 0x22, 0x4b, 0xc7, 0x97, 0x2f, 0xd5, 0x55, 0x52, 0x5f, 0x98, 0xc3, 0x37, + 0x3f, 0xe2, 0xf9, 0x72, 0x94, 0xb8, 0x21, 0xcf, 0x05, 0x1a, 0x4f, 0xd4, 0x9d, 0xcf, 0xbf, 0x36, + 0x7b, 0xd6, 0x91, 0x39, 0x39, 0x25, 0x7c, 0x13, 0x1c, 0x98, 0x23, 0x9a, 0x6f, 0xf5, 0x71, 0x99, + 0x33, 0x49, 0x25, 0xa5, 0x6a, 0xfa, 0xfb, 0xc9, 0x7f, 0x8d, 0xba, 0xed, 0xac, 0x9a, 0x7c, 0xca, + 0xc5, 0x14, 0xcc, 0x2d, 0x9c, 0x5f, 0xc4, 0x72, 0xd6, 0xb1, 0xfc, 0x98, 0xbd, 0x5f, 0x73, 0x72, + 0x7f, 0x13, 0xae, 0x52, 0x3d, 0xeb, 0x8c, 0x16, 0xef, 0xee, 0x6e, 0xef, 0x77, 0xae, 0xaf, 0x82, + 0x91, 0x05, 0xeb, 0x46, 0x9b, 0x4a, 0xac, 0x67, 0xf7, 0x95, 0x62, 0x44, 0x13, 0xc6, 0x55, 0xb9, + 0x02, 0x4d, 0xfa, 0x2b, 0xe2, 0x42, 0x76, 0x1a, 0x83, 0x53, 0xa5, 0xaa, 0x7f, 0xb2, 0xea, 0xbe, + 0x32, 0xd6, 0xd8, 0xf7, 0xbd, 0x5d, 0xa2, 0xc6, 0xde, 0x21, 0xcf, 0x8c, 0x9e, 0x87, 0xa7, 0xa7, + 0xde, 0xdb, 0xd7, 0x1a, 0x55, 0xcb, 0x7b, 0x4b, 0xeb, 0xdf, 0x08, 0x16, 0x6c, 0xab, 0xb7, 0x53, + 0xef, 0x4d, 0xf1, 0x62, 0x15, 0x3b, 0x1d, 0x6a, 0x33, 0xa2, 0xca, 0xb9, 0xaa, 0xb8, 0xfe, 0xea, + 0xba, 0xc4, 0x54, 0x4f, 0x88, 0xfc, 0x98, 0xaf, 0x5c, 0xdd, 0xdf, 0xc2, 0x5d, 0xdd, 0x6b, 0xf0, + 0x42, 0x5a, 0xbd, 0xeb, 0x8e, 0x26, 0xd1, 0x6a, 0xad, 0x6a, 0xb3, 0x4b, 0xc7, 0x75, 0x27, 0x5c, + 0x54, 0xa3, 0xfc, 0x57, 0x56, 0xb5, 0x32, 0x2f, 0x75, 0x49, 0xfe, 0x62, 0x6a, 0xd3, 0xe0, 0x94, + 0xb7, 0x77, 0x3f, 0xdb, 0xd7, 0xc1, 0x1d, 0xdb, 0xb5, 0x97, 0xc1, 0x1e, 0x37, 0xbe, 0xf3, 0x72, + 0x91, 0xb2, 0x25, 0x99, 0x27, 0x94, 0x4e, 0x37, 0x8f, 0xd1, 0x1c, 0xbe, 0x13, 0xea, 0xb5, 0xa9, + 0x38, 0x9a, 0xde, 0xed, 0xeb, 0x96, 0xb5, 0x50, 0x87, 0x2d, 0x56, 0xab, 0x84, 0xf7, 0x7c, 0xfd, + 0xec, 0x9c, 0xc2, 0x77, 0x7f, 0x08, 0x8c, 0x7b, 0xef, 0x77, 0xbc, 0xdc, 0x14, 0x9c, 0x61, 0x1d, + 0xde, 0x6a, 0x64, 0x59, 0xf7, 0x1e, 0x09, 0x4b, 0x2e, 0x21, 0xdb, 0x09, 0xa4, 0x5a, 0xe2, 0xdd, + 0x6e, 0xf9, 0x4d, 0x64, 0xda, 0xf8, 0x40, 0x95, 0x4b, 0xb3, 0x36, 0x0f, 0x4a, 0x99, 0x5f, 0x2f, + 0x26, 0x7c, 0x16, 0x89, 0x17, 0xeb, 0x5f, 0xbe, 0x12, 0xc7, 0x55, 0xee, 0x9a, 0xfc, 0xc4, 0xda, + 0x3e, 0xf9, 0x7a, 0xa9, 0xb8, 0xa2, 0x0c, 0x18, 0x98, 0x54, 0x33, 0x1f, 0xaf, 0x8f, 0xf4, 0xd2, + 0x29, 0xb0, 0x2f, 0x9e, 0xd8, 0xfc, 0xcd, 0x86, 0xd9, 0xd7, 0xf0, 0x4d, 0x7d, 0xe3, 0x19, 0xf3, + 0x64, 0xe4, 0x86, 0x63, 0x62, 0xf9, 0x8b, 0xcd, 0xdf, 0x29, 0x0f, 0x0d, 0xdf, 0x12, 0x5c, 0x9e, + 0x9d, 0x04, 0x79, 0x78, 0x9b, 0xde, 0x76, 0x38, 0xfe, 0x13, 0xd6, 0xb5, 0xaa, 0xe4, 0xbb, 0x6f, + 0xf3, 0x11, 0xdf, 0xf1, 0x27, 0x79, 0xfe, 0xef, 0x71, 0x3a, 0xc4, 0x7c, 0x97, 0xdd, 0xf3, 0x55, + 0x7e, 0x21, 0x95, 0xdf, 0xf1, 0x52, 0x74, 0xaf, 0xab, 0xfb, 0x10, 0x4b, 0x87, 0xbf, 0xb3, 0x94, + 0xaa, 0xaf, 0xd9, 0x49, 0x9f, 0xc4, 0x12, 0xb7, 0xba, 0x34, 0x9f, 0x05, 0x82, 0x33, 0x65, 0x54, + 0x98, 0x5f, 0x35, 0x36, 0x45, 0xf2, 0x95, 0x73, 0x2f, 0x70, 0xb7, 0xd0, 0xff, 0x82, 0x5a, 0x71, + 0xea, 0x66, 0x61, 0x94, 0xdd, 0xfe, 0x16, 0xd3, 0x0b, 0xfd, 0xc5, 0x4a, 0xff, 0x16, 0xec, 0xe6, + 0xe6, 0x23, 0xef, 0xe4, 0xb4, 0xde, 0x12, 0xc4, 0x44, 0xf4, 0x2d, 0xef, 0x84, 0x75, 0x5a, 0xd5, + 0x6b, 0x5f, 0x25, 0x25, 0xfc, 0x17, 0x56, 0xbc, 0x5e, 0x9d, 0x13, 0x9a, 0xab, 0xf0, 0x81, 0xb7, + 0xaf, 0x93, 0x2e, 0xf8, 0x89, 0x05, 0x0b, 0x97, 0xd7, 0xd9, 0x45, 0xd7, 0xf0, 0x54, 0x4a, 0xaa, + 0xd3, 0x55, 0x52, 0x67, 0x97, 0xc5, 0xd5, 0x55, 0x75, 0x5f, 0x17, 0x56, 0xab, 0x8b, 0xcd, 0xc9, + 0x97, 0xfe, 0x38, 0xba, 0xa6, 0x4d, 0xf5, 0x4c, 0xdf, 0x2c, 0x44, 0x93, 0xb1, 0x78, 0x53, 0x11, + 0x71, 0x32, 0x95, 0x56, 0xb8, 0x9d, 0x72, 0x5d, 0xfe, 0x26, 0xa2, 0x61, 0x3a, 0xae, 0xab, 0xf9, + 0x0b, 0x51, 0x7f, 0x9a, 0xab, 0xe2, 0x7f, 0x27, 0x54, 0x96, 0x25, 0xd5, 0x7c, 0x21, 0x05, 0xba, + 0xaa, 0xaa, 0xfd, 0xf1, 0xf5, 0x69, 0x57, 0x95, 0x8d, 0x56, 0x1a, 0x50, 0x33, 0x62, 0x79, 0x4d, + 0x3f, 0xff, 0x4f, 0xef, 0x90, 0x93, 0x12, 0xa6, 0xb9, 0x44, 0x3b, 0x13, 0xc9, 0xcb, 0xad, 0x5f, + 0x14, 0x77, 0xbe, 0xb5, 0xf1, 0xfa, 0xd6, 0xab, 0xad, 0x22, 0xf7, 0xbb, 0xd7, 0x64, 0x4e, 0x49, + 0x42, 0x38, 0x9f, 0x11, 0x58, 0x82, 0x1d, 0xdf, 0xc4, 0x08, 0xf9, 0x0c, 0xb5, 0xbe, 0x4b, 0xbe, + 0xf8, 0x28, 0x17, 0xaa, 0xd6, 0xad, 0x5c, 0x49, 0x16, 0xb5, 0x52, 0x64, 0xf8, 0xfe, 0xae, 0xab, + 0xea, 0x1b, 0x9e, 0xaf, 0x15, 0xc5, 0xea, 0xb5, 0xf3, 0x6b, 0x37, 0xf1, 0x65, 0xaa, 0xcd, 0x9f, + 0xde, 0xab, 0x5d, 0x11, 0xeb, 0x90, 0x43, 0xde, 0xb9, 0x0f, 0x7b, 0xe2, 0x3f, 0x27, 0x9d, 0x43, + 0xc4, 0x49, 0xcc, 0x4a, 0xd4, 0x31, 0xf8, 0x91, 0x35, 0x88, 0xfa, 0x12, 0xff, 0x30, 0x8b, 0xdf, + 0xcd, 0xad, 0x57, 0x43, 0x7a, 0xc2, 0x88, 0x80, 0x1a, 0xde, 0xc9, 0x5f, 0x9a, 0xae, 0xbf, 0xec, + 0x82, 0x3f, 0x3f, 0x24, 0x9f, 0xff, 0xc4, 0x7c, 0xa7, 0xad, 0x5f, 0x20, 0xc6, 0xaa, 0xbe, 0x51, + 0x65, 0x84, 0x6d, 0x73, 0xf6, 0x65, 0xac, 0xbc, 0x75, 0x37, 0xcf, 0x13, 0x4a, 0xda, 0xd0, 0xc7, + 0xaa, 0x09, 0xf3, 0x16, 0xb5, 0x7c, 0x27, 0x5a, 0xac, 0xb9, 0x93, 0x97, 0x88, 0xfe, 0x27, 0x37, + 0x35, 0x75, 0xf2, 0xd5, 0x7f, 0x21, 0xf5, 0x5f, 0x2f, 0x77, 0xf3, 0x55, 0x77, 0x08, 0x89, 0xf8, + 0x24, 0xae, 0xba, 0xf9, 0x0c, 0xf4, 0xe2, 0x39, 0x8c, 0x66, 0x6e, 0xc6, 0xbb, 0xad, 0x3f, 0x93, + 0x2b, 0xf0, 0xac, 0x4e, 0x7e, 0x5d, 0x6a, 0xf1, 0x02, 0x46, 0xea, 0xaa, 0xb5, 0x7c, 0x24, 0x65, + 0x26, 0x6b, 0x5f, 0x90, 0xaa, 0xab, 0xf7, 0x5a, 0xf1, 0x22, 0x26, 0xe3, 0xa5, 0xa0, 0xdf, 0xbe, + 0xee, 0x2b, 0xc3, 0x4c, 0xb3, 0xaf, 0xd9, 0x1e, 0x2b, 0x72, 0xf4, 0x57, 0xbe, 0xcc, 0x2f, 0x5b, + 0xe5, 0xb7, 0xbf, 0x93, 0x77, 0x84, 0xfb, 0xd6, 0xa2, 0xe2, 0x71, 0xf1, 0x1a, 0xe5, 0xde, 0xe0, + 0xc3, 0xb3, 0xbe, 0xe0, 0x3c, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3c, 0x1e, 0x31, 0xa7, + 0xca, 0x21, 0xef, 0xf2, 0x0b, 0x77, 0xdf, 0x09, 0xed, 0xd7, 0x27, 0x4f, 0x88, 0x19, 0xb4, 0xe5, + 0xce, 0x5f, 0x74, 0x68, 0xdf, 0x7f, 0x12, 0x61, 0x15, 0xaf, 0x9a, 0xef, 0xae, 0x41, 0x2e, 0x95, + 0xfc, 0x11, 0x92, 0xf2, 0xfe, 0xf8, 0x4c, 0xef, 0x77, 0x7b, 0xfd, 0x9b, 0x8a, 0xc1, 0x57, 0x05, + 0x77, 0x77, 0xbd, 0xfa, 0xad, 0x7c, 0x9b, 0xbb, 0xf8, 0xb2, 0xba, 0x77, 0xbb, 0xfc, 0x86, 0x7b, + 0xfd, 0x9d, 0xdf, 0x27, 0x04, 0x93, 0x63, 0x46, 0xe3, 0x1c, 0xb9, 0xb8, 0x88, 0x50, 0x52, 0x67, + 0xe9, 0xd2, 0x69, 0x54, 0x4f, 0x1e, 0xff, 0x13, 0xe5, 0xe3, 0x07, 0xfc, 0xb8, 0x88, 0x50, 0xb4, + 0x24, 0xcd, 0x01, 0xba, 0x1d, 0xcd, 0x20, 0x66, 0xc6, 0x69, 0xa6, 0xf7, 0xbd, 0xb7, 0xe2, 0x21, + 0x4a, 0xb9, 0x76, 0x83, 0x6d, 0xd8, 0x33, 0x61, 0x3a, 0x8a, 0xec, 0xd7, 0x48, 0x61, 0x99, 0x23, + 0x57, 0xbc, 0x40, 0x2c, 0x3c, 0xd8, 0xb2, 0x7e, 0x48, 0xed, 0xd6, 0xa2, 0xe6, 0x20, 0xf7, 0xc2, + 0x1b, 0xdb, 0x3c, 0xfe, 0x78, 0x63, 0x50, 0x8f, 0x17, 0xdd, 0x86, 0x31, 0xbd, 0xc5, 0xf4, 0x2d, + 0xe1, 0xfe, 0x2c, 0x65, 0x6c, 0x96, 0x97, 0xdf, 0x77, 0x2c, 0x44, 0xc2, 0x8f, 0x89, 0xb1, 0x3f, + 0x85, 0x0a, 0x19, 0x07, 0x59, 0x04, 0xd8, 0x51, 0x6a, 0x37, 0x73, 0x7c, 0x54, 0x63, 0xad, 0xbe, + 0xe3, 0x39, 0x7c, 0x29, 0x84, 0x6d, 0x6e, 0x5a, 0x8a, 0x6a, 0x66, 0x35, 0x55, 0x55, 0x57, 0x3e, + 0x09, 0x89, 0x48, 0xdc, 0xbf, 0x36, 0x21, 0x17, 0xf7, 0xc1, 0x48, 0xbb, 0x48, 0x6b, 0x33, 0x0d, + 0x4b, 0x1e, 0xaf, 0xc4, 0x59, 0x95, 0x03, 0x34, 0x20, 0xfc, 0x65, 0x62, 0x55, 0x4d, 0x25, 0x43, + 0x54, 0xb5, 0x2b, 0x13, 0x67, 0x84, 0x2e, 0xee, 0xf5, 0x4f, 0x34, 0x35, 0x2e, 0xa9, 0x71, 0x28, + 0x6f, 0x41, 0x47, 0x35, 0x69, 0xfd, 0x0c, 0xaf, 0x89, 0x16, 0xef, 0xdd, 0xee, 0x20, 0x49, 0x89, + 0x17, 0xf8, 0x91, 0xe2, 0x24, 0x1a, 0x5a, 0xeb, 0x3a, 0x8b, 0x02, 0xdd, 0xfc, 0x61, 0x46, 0xb4, + 0x9c, 0x62, 0x90, 0x42, 0xbc, 0x56, 0x3a, 0x81, 0xd7, 0xb9, 0x58, 0x52, 0x6d, 0x9a, 0xf8, 0x96, + 0x4a, 0xba, 0xf8, 0xcb, 0x63, 0x57, 0x1b, 0x2f, 0xe6, 0xcc, 0xd6, 0xba, 0x8c, 0x9d, 0x9f, 0xca, + 0x2f, 0x06, 0xd9, 0x96, 0xba, 0x27, 0x7c, 0x58, 0xaa, 0x55, 0x49, 0x2f, 0xd1, 0xdc, 0xf9, 0x45, + 0x9b, 0x37, 0x7d, 0x5e, 0x09, 0x22, 0x62, 0xb2, 0xf7, 0xee, 0xe5, 0xfe, 0x63, 0x5e, 0x9f, 0x98, + 0xfb, 0x6b, 0xef, 0xaa, 0xfb, 0xe4, 0xff, 0x10, 0x22, 0xf7, 0x55, 0x51, 0x81, 0x97, 0xc1, 0x2c, + 0xd1, 0x22, 0x5a, 0x37, 0x4d, 0xf8, 0x5b, 0xbb, 0xf1, 0x11, 0xf7, 0xdb, 0x9b, 0xd5, 0x54, 0x35, + 0x1f, 0xc4, 0x0a, 0xa9, 0xbd, 0x56, 0x89, 0x7c, 0x75, 0x98, 0xab, 0x3a, 0x76, 0x9a, 0x64, 0x28, + 0x5f, 0xc5, 0xe4, 0xfa, 0x4d, 0xa3, 0x40, 0xf1, 0x30, 0x47, 0x58, 0xc8, 0x40, 0x5b, 0xf8, 0x80, + 0x46, 0x54, 0xaf, 0xee, 0x20, 0x41, 0x49, 0xbb, 0xe2, 0x04, 0x71, 0x02, 0x05, 0x99, 0xbb, 0xa3, + 0xa4, 0x2b, 0x0a, 0x36, 0x30, 0x80, 0x83, 0x45, 0x6e, 0xef, 0x88, 0x08, 0x31, 0x75, 0xb1, 0xfb, + 0x13, 0x7b, 0x97, 0x98, 0x21, 0x3f, 0x89, 0x78, 0x73, 0xa2, 0xf7, 0xc5, 0x4f, 0xa6, 0xdd, 0xa5, + 0xfd, 0xdb, 0xbd, 0x72, 0x56, 0xb5, 0xcc, 0x2e, 0x99, 0xbf, 0xc4, 0x71, 0x22, 0x01, 0x50, 0xe5, + 0x5a, 0xd2, 0x57, 0x97, 0xd3, 0x73, 0xc4, 0x05, 0x04, 0xbc, 0x2a, 0xfa, 0xde, 0xf5, 0x8f, 0xaa, + 0x6b, 0x16, 0x9d, 0x83, 0x3c, 0xa9, 0xbf, 0xc6, 0x65, 0xd7, 0x6f, 0xa0, 0x58, 0x06, 0x1e, 0x42, + 0x38, 0x1c, 0x11, 0xae, 0xcb, 0x02, 0xa4, 0x78, 0x99, 0x6d, 0xe1, 0x03, 0x89, 0x88, 0x24, 0x55, + 0xed, 0x8c, 0xa6, 0x5a, 0xc3, 0x17, 0xfc, 0x12, 0xd5, 0x49, 0xb2, 0xaa, 0x97, 0xff, 0x04, 0xe4, + 0x3e, 0x59, 0x70, 0x8b, 0xfb, 0x43, 0x3b, 0xc3, 0x76, 0x57, 0xe2, 0x2f, 0x84, 0x25, 0xb4, 0x3e, + 0x06, 0x3f, 0xd4, 0x36, 0x88, 0x31, 0x50, 0xd0, 0x83, 0xa5, 0x65, 0x72, 0x57, 0x8b, 0xb7, 0xa2, + 0x2f, 0x11, 0x83, 0xd9, 0xfe, 0x20, 0x49, 0xfd, 0xee, 0xb4, 0xbc, 0x41, 0x53, 0xa4, 0x9d, 0x00, + 0xdd, 0xfc, 0x61, 0x34, 0x9d, 0x83, 0xd3, 0x77, 0x7c, 0xb0, 0xbf, 0xc5, 0x0c, 0xc9, 0x01, 0xc3, + 0x04, 0x87, 0xf1, 0x00, 0x84, 0x22, 0x62, 0x35, 0x55, 0xff, 0x9b, 0x08, 0x10, 0x21, 0x3b, 0x35, + 0xf7, 0x7d, 0xb8, 0x6d, 0x86, 0x7f, 0xf8, 0x45, 0xcd, 0xbf, 0xbf, 0xd6, 0xb0, 0xbf, 0x47, 0x8a, + 0xbb, 0x0c, 0x2a, 0xef, 0x90, 0x8e, 0xbf, 0xbe, 0xaa, 0xf9, 0x77, 0xba, 0xe4, 0xbb, 0x39, 0xf3, + 0xc2, 0x87, 0x36, 0xd8, 0xcd, 0xa6, 0xd1, 0x89, 0xb4, 0x84, 0xf5, 0xa8, 0xc7, 0x15, 0x8c, 0x17, + 0x50, 0x0d, 0x78, 0x40, 0x4d, 0x48, 0xf3, 0x6d, 0x10, 0x17, 0xf8, 0x53, 0x77, 0x66, 0x19, 0x60, + 0xc5, 0x1b, 0xfc, 0x55, 0xa1, 0xc3, 0x6b, 0x2a, 0xa5, 0x83, 0x8f, 0xc4, 0xc2, 0x04, 0x3f, 0x2a, + 0x44, 0x4a, 0xbe, 0x5b, 0xe9, 0xb6, 0x89, 0xf1, 0x32, 0x6a, 0xa8, 0x3e, 0x20, 0x45, 0x67, 0xfc, + 0x4e, 0x56, 0x38, 0x91, 0x96, 0xed, 0x39, 0xf2, 0xe1, 0x7e, 0xd6, 0xcd, 0x78, 0x90, 0x8c, 0x98, + 0xab, 0x6b, 0x5c, 0xfc, 0xb9, 0x89, 0x8a, 0xb1, 0x90, 0x82, 0x3d, 0x4d, 0xeb, 0xaa, 0x1f, 0x13, + 0x04, 0x24, 0xb7, 0x5e, 0xb8, 0x29, 0x13, 0x41, 0x44, 0x15, 0x67, 0xff, 0xc2, 0xb9, 0x7b, 0xb6, + 0x4e, 0x11, 0x0a, 0x3d, 0xfc, 0xb8, 0x56, 0x1b, 0x2d, 0x98, 0xd7, 0x8c, 0x3d, 0x3a, 0xa1, 0x84, + 0x4d, 0xff, 0x5e, 0x8c, 0xa6, 0x67, 0xa4, 0x34, 0x89, 0xfc, 0x13, 0x76, 0x53, 0x64, 0x26, 0x2d, + 0x5e, 0x41, 0x38, 0x62, 0xb1, 0xa1, 0xef, 0x84, 0xc9, 0xc9, 0x42, 0x5a, 0x2b, 0x30, 0xef, 0x45, + 0x7f, 0x8b, 0xd2, 0x4b, 0x54, 0xbe, 0x3e, 0xaa, 0xb9, 0x7f, 0x2e, 0xd2, 0xf1, 0x95, 0xec, 0xab, + 0x87, 0x6f, 0xbb, 0x97, 0xa1, 0x24, 0x09, 0x1e, 0xb0, 0xef, 0xd8, 0xf5, 0xbe, 0x0a, 0x6e, 0xb2, + 0xef, 0x3a, 0x86, 0xf8, 0xbd, 0xf1, 0x9b, 0xbb, 0xb6, 0xef, 0x79, 0x68, 0x1f, 0xa9, 0x0c, 0x27, + 0x9c, 0x98, 0xf7, 0xf8, 0x82, 0x36, 0xb5, 0x17, 0x66, 0xab, 0xe2, 0x2b, 0x27, 0xbb, 0xfe, 0x0b, + 0x0b, 0x62, 0x53, 0x76, 0x54, 0xdc, 0x8c, 0x24, 0xa1, 0x16, 0xef, 0x89, 0xd2, 0x27, 0xe5, 0x95, + 0x5e, 0x24, 0xd6, 0x36, 0x31, 0xc3, 0x09, 0x52, 0x17, 0xe2, 0x6d, 0xde, 0x9c, 0x49, 0xa6, 0x89, + 0xb7, 0x55, 0x0a, 0xb1, 0xa0, 0x11, 0xb5, 0xb4, 0x37, 0xbf, 0xff, 0x85, 0x5e, 0xf0, 0x4e, 0x28, + 0xf0, 0x39, 0x79, 0xc8, 0x39, 0x2b, 0x61, 0xe2, 0x88, 0xd6, 0xfb, 0xbf, 0x87, 0xba, 0x46, 0x96, + 0xec, 0x68, 0x1e, 0x1c, 0xd4, 0x5f, 0x6e, 0x5f, 0xeb, 0x85, 0xf7, 0xb4, 0x53, 0x16, 0xe1, 0x7d, + 0xfc, 0x7c, 0x64, 0xf0, 0xff, 0x8d, 0xda, 0xbe, 0x5c, 0x14, 0x6e, 0x18, 0x62, 0x1a, 0x75, 0x1f, + 0x47, 0xd2, 0x2d, 0x7e, 0x34, 0xdb, 0x6f, 0xc2, 0x97, 0x8a, 0xcb, 0xf1, 0x59, 0x71, 0x6f, 0xad, + 0xb0, 0x5f, 0x91, 0x72, 0xed, 0xdf, 0xe1, 0x22, 0x2d, 0x86, 0x9b, 0xcf, 0xfe, 0x2b, 0xcb, 0x07, + 0xbb, 0xf8, 0x4c, 0xae, 0x7f, 0x7f, 0x0d, 0xf5, 0x9e, 0x0a, 0x70, 0x84, 0x65, 0x1b, 0xce, 0xbe, + 0xda, 0x01, 0xdf, 0xab, 0x6b, 0xfe, 0xf9, 0xff, 0xe8, 0x7f, 0x9b, 0x7b, 0xbc, 0x40, 0xc2, 0x5f, + 0x1e, 0x68, 0xd2, 0x15, 0xdc, 0x7c, 0x78, 0x2b, 0x93, 0x53, 0x13, 0x08, 0xd5, 0x72, 0x31, 0xd1, + 0x63, 0xb4, 0x56, 0x70, 0x34, 0x4c, 0x97, 0x1d, 0x26, 0xcb, 0xfe, 0xf6, 0x72, 0x73, 0x7c, 0xd7, + 0xdd, 0x75, 0xee, 0x22, 0x49, 0x3b, 0x7a, 0xc1, 0xae, 0x49, 0xf2, 0xdf, 0xe2, 0x6b, 0xd7, 0xe5, + 0x4a, 0x8b, 0xf1, 0x54, 0xca, 0x66, 0x9a, 0x6f, 0x7f, 0x0b, 0xd8, 0xb6, 0xc7, 0x24, 0xbb, 0xe9, + 0x43, 0xe3, 0x9d, 0xac, 0x37, 0xcb, 0x7b, 0xba, 0xe2, 0xea, 0xbe, 0xaa, 0xb9, 0x8b, 0x7b, 0xf9, + 0x08, 0xee, 0xef, 0xe6, 0xd5, 0x6b, 0x92, 0xbd, 0x7c, 0x9d, 0x98, 0xcb, 0xf7, 0x35, 0x15, 0xb9, + 0x78, 0x22, 0xcb, 0xf9, 0x44, 0xf0, 0x9c, 0xd8, 0xc2, 0x45, 0xbd, 0xaf, 0x26, 0x52, 0x37, 0xf1, + 0xd4, 0x78, 0xc2, 0xb1, 0xe9, 0x9f, 0xee, 0xf8, 0x88, 0xce, 0xd2, 0xbe, 0xe8, 0x4a, 0x68, 0xe3, + 0xd2, 0xaf, 0x4f, 0xc4, 0xda, 0xae, 0x9c, 0x9c, 0x35, 0xcd, 0xe2, 0xe4, 0xee, 0xf7, 0x97, 0x10, + 0x8a, 0xf7, 0xca, 0x5d, 0x5f, 0xc5, 0xea, 0xa2, 0xfa, 0xab, 0xec, 0x45, 0xb5, 0x9b, 0x98, 0x4a, + 0xa7, 0x4f, 0x88, 0x20, 0x89, 0x98, 0x79, 0xc4, 0x08, 0xf8, 0xb3, 0xda, 0x4b, 0x65, 0x7f, 0x04, + 0x66, 0xd9, 0x2b, 0x7c, 0x64, 0x4a, 0xc8, 0x18, 0xd5, 0x79, 0x5c, 0x68, 0x39, 0xeb, 0x2a, 0xb2, + 0x55, 0x25, 0xef, 0xab, 0xa6, 0xbf, 0x13, 0x9e, 0x73, 0x58, 0x6b, 0xbd, 0xdf, 0xe2, 0x6b, 0x5a, + 0xd6, 0x2f, 0x10, 0x08, 0x77, 0xbb, 0x9f, 0x12, 0x7a, 0xaa, 0xae, 0xab, 0x88, 0xdd, 0xf1, 0x7f, + 0xca, 0x6a, 0x3b, 0x9a, 0x22, 0x10, 0xad, 0x64, 0xeb, 0xde, 0x56, 0x31, 0x30, 0x87, 0x6c, 0xca, + 0x45, 0xda, 0x81, 0xcc, 0xc4, 0xf4, 0xfc, 0x49, 0x3c, 0xfb, 0xe1, 0x0b, 0xf6, 0x50, 0xb6, 0x93, + 0x8f, 0xbd, 0xfd, 0xf7, 0x37, 0xf2, 0x50, 0x4b, 0x6f, 0xc4, 0x96, 0xef, 0xe3, 0x26, 0xa1, 0x9e, + 0x20, 0x97, 0x73, 0xf1, 0x7f, 0x15, 0xc9, 0xb3, 0x49, 0xbf, 0x27, 0x8b, 0xf8, 0x48, 0xf2, 0x43, + 0x5a, 0xfc, 0xb5, 0x5f, 0xc2, 0x54, 0xec, 0xd2, 0xad, 0x57, 0x08, 0x9b, 0x97, 0x25, 0xf6, 0x82, + 0xea, 0xdf, 0xf1, 0x19, 0xb1, 0xed, 0x3b, 0x72, 0x73, 0x79, 0x98, 0xf3, 0x77, 0x45, 0xe8, 0xae, + 0x3c, 0x26, 0x42, 0xf7, 0xf9, 0xe0, 0x78, 0x7f, 0x0c, 0xdf, 0x44, 0xbf, 0x6c, 0xd5, 0x8f, 0xc2, + 0x91, 0x3c, 0x2c, 0x0c, 0x53, 0x12, 0x1e, 0x9b, 0x71, 0xa6, 0x8c, 0x7d, 0x9b, 0x24, 0xd8, 0x1f, + 0x1f, 0x2e, 0xf9, 0x6b, 0x76, 0x28, 0x2b, 0xe2, 0xf9, 0xac, 0xb9, 0x8e, 0xf9, 0xb4, 0xf1, 0x7b, + 0x96, 0x93, 0x5a, 0x9b, 0x89, 0x9a, 0x86, 0x8b, 0xf7, 0xaf, 0xbb, 0xcf, 0xef, 0x82, 0x41, 0x34, + 0xad, 0x65, 0xf5, 0x7f, 0x9a, 0xd3, 0x5f, 0x9a, 0xc6, 0xb6, 0xc3, 0x5d, 0xeb, 0x52, 0x76, 0x21, + 0x53, 0xcb, 0x10, 0x20, 0x21, 0x60, 0xcd, 0xb9, 0xb3, 0x5d, 0x52, 0xf0, 0x55, 0xa4, 0x3a, 0xc8, + 0xe7, 0x31, 0x0e, 0x16, 0x89, 0x45, 0xea, 0x2f, 0x9a, 0x49, 0x36, 0x7f, 0xfb, 0xd5, 0x60, 0xa7, + 0x8f, 0x2a, 0xae, 0xab, 0xf3, 0xd3, 0x11, 0x35, 0xea, 0x79, 0x2e, 0x42, 0x6e, 0xeb, 0x8f, 0xb4, + 0xab, 0x44, 0xfe, 0xab, 0xec, 0xaf, 0xb8, 0x8e, 0x28, 0x85, 0xf4, 0x56, 0xdd, 0x0e, 0x6e, 0x6e, + 0xaa, 0x1a, 0xe5, 0xaa, 0xd5, 0x77, 0x7d, 0xfc, 0x97, 0x7f, 0xcb, 0x55, 0xcd, 0xcc, 0x54, 0x4d, + 0x52, 0xf1, 0x64, 0x74, 0x12, 0x8f, 0x79, 0x6e, 0xa1, 0x33, 0xc9, 0xaa, 0xc4, 0xf2, 0xdd, 0xfe, + 0x20, 0x11, 0xd6, 0xd9, 0x3b, 0x1f, 0x11, 0x7b, 0x9c, 0xc4, 0xb8, 0xf5, 0x7d, 0xcd, 0x94, 0x65, + 0x31, 0x27, 0x05, 0xbd, 0x56, 0xb5, 0xeb, 0xe2, 0x69, 0xef, 0x7b, 0x84, 0xb9, 0x0b, 0x5a, 0xbe, + 0x42, 0x5e, 0xeb, 0x90, 0xea, 0xb8, 0x9e, 0x52, 0xdd, 0xfe, 0xac, 0xf1, 0x05, 0x35, 0xa6, 0xb8, + 0x8f, 0xcc, 0x25, 0x57, 0x5c, 0x82, 0xad, 0xb5, 0x5c, 0x15, 0xf5, 0x69, 0x4d, 0x95, 0x69, 0x57, + 0xd1, 0x5c, 0xba, 0x49, 0xa2, 0xf1, 0x7c, 0xfe, 0x89, 0x90, 0xbd, 0xf2, 0xdd, 0xff, 0x09, 0x4e, + 0x18, 0x0b, 0x5e, 0x6a, 0x22, 0xf1, 0x3d, 0x4d, 0x29, 0xb7, 0xf3, 0x73, 0x31, 0x0e, 0x73, 0x09, + 0x5a, 0xde, 0x22, 0x6e, 0x85, 0x75, 0xf3, 0x55, 0x7f, 0x58, 0xa2, 0xb9, 0xb9, 0xee, 0x1f, 0xec, + 0x5e, 0xaa, 0x37, 0xb1, 0x52, 0x62, 0x3d, 0xf5, 0xf4, 0xfc, 0xb5, 0xd4, 0x2f, 0x13, 0x88, 0xc4, + 0x39, 0xfd, 0xe5, 0xec, 0x4e, 0xab, 0x89, 0xcb, 0xca, 0x21, 0x77, 0x27, 0x67, 0xc5, 0x71, 0x1c, + 0x84, 0x5d, 0xc2, 0xbc, 0x87, 0x7b, 0xd7, 0x31, 0x1b, 0x5a, 0x93, 0xa2, 0x35, 0xf2, 0x95, 0xef, + 0x3f, 0x65, 0x4a, 0xab, 0xe2, 0x4a, 0xb5, 0xd6, 0xa1, 0x2e, 0x85, 0x3c, 0x39, 0xdd, 0xef, 0x26, + 0x22, 0xf9, 0x46, 0xea, 0xab, 0x08, 0x3d, 0x56, 0x11, 0xec, 0x64, 0xcc, 0xd8, 0xc3, 0x58, 0x8f, + 0xbd, 0x6a, 0x4e, 0x24, 0x7d, 0x57, 0x75, 0x93, 0x84, 0x6b, 0xaa, 0xae, 0xba, 0xae, 0x23, 0xaa, + 0xaa, 0xaf, 0x88, 0x88, 0xe6, 0x1c, 0xab, 0x5f, 0x35, 0xf7, 0x04, 0x58, 0x88, 0x4f, 0x90, 0xb2, + 0x7d, 0x70, 0x9f, 0x77, 0xbd, 0xc0, 0x59, 0x75, 0xd4, 0x27, 0xdc, 0xef, 0x4f, 0x02, 0xf4, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3d, 0x1e, 0xb0, 0x4a, 0x7d, 0x88, 0x77, 0xbf, 0x82, 0x21, 0x6e, + 0xee, 0xf5, 0x5c, 0x20, 0x29, 0xdd, 0xde, 0x9d, 0xde, 0xef, 0xe3, 0x86, 0xa6, 0xf6, 0xd3, 0x1a, + 0xa2, 0x7b, 0xb7, 0x37, 0xf0, 0x49, 0x96, 0x45, 0xa6, 0xd5, 0xc7, 0x0a, 0xbd, 0xde, 0xef, 0x8b, + 0xaf, 0x97, 0x5a, 0xf8, 0xf1, 0x32, 0xfe, 0xcd, 0xf9, 0xf2, 0x17, 0xaf, 0x8c, 0x26, 0x27, 0x8b, + 0x25, 0xbf, 0x5e, 0xae, 0x2b, 0xf8, 0x44, 0xf5, 0x7a, 0x6e, 0x81, 0xa5, 0x3f, 0xb7, 0xe3, 0xcd, + 0x74, 0xef, 0x7b, 0xed, 0x1f, 0xa1, 0xec, 0x7d, 0x15, 0xef, 0xae, 0x50, 0xe7, 0x5b, 0xd7, 0x30, + 0x4a, 0xf4, 0xfc, 0x15, 0xdc, 0xfc, 0xb8, 0xff, 0x6f, 0xe7, 0xc7, 0xfb, 0x6d, 0x5f, 0xe0, 0x92, + 0xee, 0xef, 0x7f, 0x82, 0x92, 0xa4, 0x5c, 0xec, 0xce, 0xd7, 0x49, 0xaa, 0x69, 0xd7, 0xc4, 0x9a, + 0xef, 0xbd, 0xfc, 0x49, 0xd3, 0xad, 0xee, 0xd9, 0xd8, 0xfd, 0x08, 0xaf, 0xab, 0xfc, 0x12, 0x57, + 0x5e, 0xf9, 0x8a, 0xdb, 0x19, 0x18, 0x9f, 0x0a, 0x1a, 0x31, 0x7d, 0xeb, 0x6d, 0x66, 0x0d, 0x13, + 0x91, 0x20, 0xde, 0x1c, 0xc3, 0x22, 0xa0, 0xe4, 0xfa, 0x4c, 0xe0, 0xf8, 0x29, 0x28, 0xcb, 0x26, + 0xd3, 0x28, 0x60, 0x55, 0xf6, 0x81, 0x56, 0xd0, 0x27, 0x31, 0x92, 0x3e, 0xa7, 0x07, 0xc1, 0x5f, + 0x6c, 0xb2, 0x3c, 0x5d, 0x00, 0xfc, 0x88, 0xf2, 0x68, 0x64, 0x91, 0x33, 0xd6, 0xe7, 0xc2, 0x87, + 0x4c, 0xbc, 0x73, 0xca, 0xbc, 0xcc, 0x86, 0x39, 0x0d, 0xd6, 0xcc, 0x3f, 0x76, 0x19, 0x8a, 0x37, + 0xb2, 0xb6, 0xd9, 0x7c, 0x29, 0x4d, 0x2f, 0xa4, 0xe3, 0x95, 0xd1, 0xb4, 0x20, 0x2c, 0x40, 0x32, + 0x38, 0xde, 0xc4, 0xd2, 0x7f, 0x82, 0x6b, 0x56, 0xaa, 0xcd, 0x8b, 0xc9, 0x97, 0x30, 0x86, 0xae, + 0xeb, 0xec, 0x5a, 0xaa, 0xc4, 0x75, 0x68, 0x5f, 0xa3, 0xf5, 0xf4, 0x47, 0x26, 0xe8, 0x25, 0x52, + 0xf0, 0x88, 0xa7, 0x30, 0x60, 0x28, 0x7e, 0xa3, 0x57, 0x90, 0xd1, 0x31, 0x9f, 0x11, 0x1e, 0x57, + 0x09, 0x24, 0x77, 0x84, 0x19, 0x2a, 0x78, 0x57, 0x47, 0x41, 0x62, 0x66, 0x51, 0xae, 0x42, 0xb5, + 0x46, 0x70, 0x3f, 0x05, 0x16, 0xc9, 0xd7, 0x5a, 0x58, 0xff, 0x04, 0x44, 0xbb, 0x5d, 0x7c, 0x58, + 0xb2, 0x61, 0x33, 0x55, 0xa5, 0xe4, 0x33, 0x24, 0x1a, 0x6c, 0x7e, 0xfc, 0xa5, 0xf0, 0x4d, 0xa4, + 0xdc, 0xb4, 0x6a, 0x66, 0x5f, 0xe8, 0x6b, 0x41, 0x47, 0x74, 0x93, 0x5f, 0x8c, 0x18, 0xfb, 0xbd, + 0xde, 0xf7, 0xbb, 0xcb, 0x11, 0x0a, 0x67, 0x89, 0x05, 0x89, 0xe9, 0x0e, 0x58, 0x72, 0xdb, 0x1f, + 0x15, 0x89, 0x7d, 0xdb, 0xbf, 0x13, 0x13, 0xb0, 0x22, 0xee, 0xb4, 0x60, 0xb9, 0xef, 0x62, 0xfc, + 0x15, 0x5b, 0xb6, 0x5a, 0x3e, 0xa2, 0x29, 0xa9, 0xbc, 0xf7, 0xc1, 0x5c, 0x15, 0x52, 0x2a, 0x06, + 0xe6, 0x1d, 0x93, 0x2c, 0xd8, 0x9b, 0x96, 0x83, 0x31, 0x1d, 0xf6, 0x26, 0x66, 0x2c, 0x7e, 0x12, + 0xaa, 0xee, 0xff, 0x94, 0x97, 0xbf, 0x88, 0x14, 0x9b, 0xff, 0x79, 0xf3, 0x10, 0x20, 0xc7, 0xaa, + 0x55, 0x84, 0x0c, 0x3f, 0x1d, 0x38, 0x2d, 0x2c, 0x2b, 0x9b, 0x55, 0x50, 0x4b, 0xc1, 0x68, 0xab, + 0xba, 0x4e, 0x2b, 0xbb, 0x9f, 0x12, 0x77, 0xbe, 0xef, 0x7c, 0xc2, 0x29, 0x53, 0xf1, 0x31, 0xdc, + 0xea, 0x1f, 0x46, 0xd5, 0x69, 0xfc, 0x44, 0x28, 0x51, 0x0f, 0xae, 0x76, 0x58, 0x31, 0xaa, 0x2b, + 0xc6, 0x82, 0x77, 0x62, 0xe9, 0xc7, 0x2e, 0x4c, 0x73, 0xe2, 0xcd, 0x5a, 0xcd, 0xff, 0x35, 0x22, + 0x63, 0x05, 0xf8, 0x2e, 0x9f, 0x1a, 0x6a, 0xda, 0xcb, 0x8f, 0xf1, 0x65, 0x27, 0x6a, 0x04, 0xae, + 0xff, 0x82, 0x2d, 0xee, 0xfc, 0x40, 0x80, 0x47, 0x1c, 0x5d, 0xb8, 0xff, 0xf9, 0x05, 0x16, 0xf7, + 0xc4, 0x55, 0xcf, 0x8c, 0xf1, 0x5b, 0x58, 0xee, 0x2b, 0x15, 0xbb, 0x46, 0xf6, 0x7e, 0x20, 0x40, + 0x91, 0xef, 0x7b, 0xdb, 0x5f, 0x29, 0xd6, 0xdc, 0xb1, 0x11, 0x41, 0x0a, 0xaa, 0x46, 0xf1, 0x87, + 0x69, 0x8a, 0x10, 0x71, 0x20, 0x8e, 0x75, 0x17, 0xa8, 0x64, 0xe1, 0xf0, 0x46, 0x54, 0xd1, 0xd1, + 0x42, 0x1e, 0x5b, 0x49, 0xfe, 0xa4, 0xa2, 0x39, 0x2d, 0x69, 0x8d, 0xe2, 0xf5, 0x55, 0x6f, 0x4d, + 0x72, 0xcf, 0xbc, 0xbc, 0xa2, 0xda, 0x7b, 0xbe, 0x0b, 0x0d, 0x7b, 0x86, 0x96, 0x36, 0xc1, 0x56, + 0x9a, 0xda, 0x32, 0x7c, 0x16, 0x5e, 0x92, 0x03, 0x7e, 0x1d, 0xb5, 0xfc, 0xe0, 0x80, 0x2c, 0x36, + 0xa9, 0x7f, 0x84, 0x08, 0x59, 0x56, 0xc1, 0x37, 0x07, 0x79, 0x88, 0x4f, 0xc9, 0x69, 0xb4, 0xeb, + 0xf8, 0x47, 0x37, 0x45, 0xc9, 0x9f, 0x9f, 0xf8, 0xf2, 0x23, 0x45, 0x59, 0xf2, 0xc0, 0xb4, 0xdf, + 0xc2, 0x9e, 0x5c, 0x9d, 0x94, 0xd6, 0x7c, 0x2b, 0x2f, 0x18, 0x30, 0xb5, 0x4d, 0x7b, 0xe1, 0x1b, + 0xbd, 0xd5, 0x03, 0x55, 0x3c, 0xb9, 0x5f, 0x05, 0x02, 0x77, 0x4b, 0x03, 0x7e, 0x3b, 0xff, 0xc1, + 0x09, 0x5e, 0x5c, 0xbf, 0x13, 0x14, 0x4b, 0xbf, 0x35, 0xa0, 0x78, 0x88, 0xe1, 0xd2, 0xfb, 0xdb, + 0x48, 0x0e, 0xe5, 0xc1, 0x5b, 0xff, 0x82, 0xa0, 0xc9, 0x57, 0xb7, 0xd6, 0xca, 0xaa, 0xaf, 0x36, + 0x10, 0x14, 0x16, 0x6f, 0xae, 0x66, 0x1e, 0xb7, 0xf1, 0x26, 0xe6, 0x62, 0x37, 0x82, 0x31, 0x72, + 0x74, 0xbd, 0x57, 0x16, 0x5a, 0xd7, 0x26, 0x97, 0x57, 0x04, 0xf7, 0x6b, 0x97, 0x1a, 0x94, 0x9f, + 0x57, 0x4d, 0xd0, 0x47, 0xab, 0x90, 0x30, 0xba, 0xf9, 0xb5, 0x2f, 0xfc, 0x11, 0x9d, 0x8e, 0xf7, + 0xbe, 0x61, 0x54, 0xd6, 0xf8, 0xad, 0x6a, 0xde, 0x97, 0x84, 0xf4, 0x96, 0xf4, 0xc7, 0x57, 0xc1, + 0x49, 0xcb, 0x4d, 0x20, 0xe3, 0x12, 0x4b, 0x40, 0xc7, 0x63, 0x09, 0x37, 0xe5, 0x7d, 0xfe, 0x3b, + 0xb2, 0x7c, 0x3b, 0x9c, 0xbc, 0x01, 0x5d, 0xfe, 0x0a, 0x88, 0xfa, 0x74, 0x50, 0x1e, 0x4e, 0x52, + 0x53, 0xbb, 0x77, 0xf9, 0xa7, 0x7d, 0x53, 0xf0, 0xf6, 0xb5, 0x2f, 0xbd, 0xd3, 0x2d, 0x19, 0x6b, + 0xf7, 0x57, 0xf2, 0xd8, 0x54, 0x33, 0xcf, 0xdd, 0x29, 0xe8, 0xde, 0x26, 0x14, 0xb0, 0x66, 0xdd, + 0x7b, 0x23, 0xdf, 0x3d, 0x6a, 0x6f, 0xad, 0x0b, 0xb8, 0x8f, 0x13, 0x64, 0xe6, 0xcc, 0x4f, 0x14, + 0x4d, 0x8b, 0x41, 0x94, 0xd3, 0x27, 0x11, 0x14, 0x18, 0x10, 0x7c, 0x9e, 0x23, 0xe4, 0x22, 0xfe, + 0x11, 0x38, 0x78, 0x52, 0x63, 0xf7, 0xc6, 0x75, 0x29, 0xa9, 0xf3, 0xa0, 0xbf, 0x12, 0x08, 0xf8, + 0x59, 0xb8, 0x94, 0x1d, 0x0e, 0x7c, 0x12, 0x0d, 0xe0, 0x7c, 0xd5, 0xcf, 0x8b, 0x08, 0x6d, 0xe5, + 0xc9, 0xac, 0x67, 0x26, 0xd3, 0x11, 0x05, 0x55, 0xac, 0xf8, 0x3d, 0x46, 0xae, 0x93, 0x90, 0xee, + 0x5f, 0x2e, 0x7a, 0xa7, 0xf8, 0x2b, 0x2a, 0x2c, 0x9a, 0x93, 0x63, 0xe5, 0x8e, 0x19, 0xf0, 0x94, + 0xf3, 0xe8, 0x61, 0xea, 0xa4, 0x37, 0xb2, 0x2b, 0xa2, 0xb0, 0x37, 0x7c, 0xb9, 0x5d, 0x04, 0x62, + 0x97, 0x88, 0x0b, 0x69, 0xbd, 0xd9, 0x37, 0xe5, 0xaa, 0xfe, 0x0b, 0xad, 0x6a, 0xa9, 0xed, 0x5c, + 0xbd, 0xd2, 0x5c, 0x28, 0x56, 0x67, 0x23, 0x48, 0x61, 0xac, 0x04, 0xd9, 0xd5, 0x3e, 0x6b, 0x71, + 0xc0, 0xa9, 0xc3, 0xc1, 0x5d, 0x81, 0xb6, 0xdf, 0x37, 0x64, 0x9e, 0x9e, 0x5f, 0x17, 0xbb, 0x6d, + 0x8f, 0x90, 0xb7, 0x10, 0x9e, 0x1e, 0x38, 0xca, 0xba, 0x69, 0x66, 0x97, 0xf8, 0x9d, 0x24, 0xb4, + 0x92, 0xf8, 0x4c, 0xa3, 0x6e, 0x08, 0x4b, 0x5a, 0x3c, 0x91, 0x45, 0xeb, 0xd7, 0x89, 0x04, 0x94, + 0xf2, 0xb3, 0x17, 0xcb, 0x7b, 0x19, 0xae, 0x6b, 0xdf, 0xe7, 0x94, 0x33, 0xfb, 0x65, 0xd7, 0xc1, + 0x39, 0x25, 0xc4, 0xdf, 0x4b, 0x8e, 0xe0, 0xb7, 0x03, 0x06, 0x22, 0x32, 0xbc, 0x93, 0x7d, 0xa5, + 0xbb, 0xcb, 0x8c, 0xdf, 0x5f, 0x17, 0x7b, 0xc6, 0x0b, 0xbd, 0xf8, 0x88, 0x53, 0xc6, 0xf0, 0x59, + 0x3c, 0x34, 0x42, 0xb3, 0x7b, 0xdb, 0xdd, 0x26, 0xa0, 0xe2, 0x20, 0x9f, 0x77, 0x53, 0xb9, 0x9b, + 0x30, 0x7c, 0x5d, 0xf7, 0x8c, 0xab, 0x90, 0x1f, 0xed, 0x89, 0x8e, 0xc7, 0x94, 0x36, 0x54, 0x57, + 0x2c, 0x0d, 0xb3, 0x83, 0xff, 0x5a, 0xb6, 0x3f, 0xe1, 0x8e, 0x8b, 0xdf, 0x05, 0x59, 0xbd, 0x49, + 0xd5, 0x9e, 0x49, 0xfb, 0xeb, 0xe1, 0x4b, 0xbd, 0xde, 0xef, 0x77, 0x77, 0x7d, 0xfe, 0x52, 0x45, + 0xeb, 0xec, 0xe9, 0xd3, 0xf8, 0x2b, 0x3a, 0x44, 0xfd, 0x5b, 0x5e, 0x4e, 0xe7, 0xc1, 0x59, 0xaf, + 0x77, 0xde, 0xed, 0xdf, 0xe0, 0xbb, 0x97, 0x3c, 0x9a, 0xff, 0x05, 0x33, 0xd6, 0xdc, 0x94, 0x26, + 0x43, 0x9e, 0x7c, 0x19, 0x5a, 0x70, 0xbe, 0x0b, 0x88, 0xce, 0xf2, 0xf1, 0xd7, 0x4c, 0xdf, 0x83, + 0xe3, 0x31, 0x91, 0x42, 0x58, 0x2f, 0x13, 0xb0, 0x3d, 0xc4, 0x14, 0x4a, 0x45, 0x5a, 0xb1, 0x01, + 0x5b, 0x46, 0xd7, 0x5a, 0x5e, 0x6d, 0x8d, 0x4e, 0x18, 0x1f, 0x1d, 0xb9, 0xff, 0x8f, 0x44, 0x6f, + 0xff, 0xe1, 0x4a, 0xd5, 0x5c, 0xb6, 0xc2, 0xf5, 0x5b, 0x62, 0xec, 0xf5, 0xf1, 0x70, 0xc7, 0x79, + 0x7c, 0x58, 0xb6, 0x68, 0x2c, 0xf0, 0xf1, 0x7c, 0x7b, 0x36, 0x7d, 0x57, 0xc5, 0xf1, 0xc6, 0x4e, + 0x20, 0xd4, 0x9e, 0x3f, 0x0f, 0x64, 0x66, 0x46, 0xd0, 0x1a, 0x91, 0xeb, 0x1c, 0x23, 0xe2, 0xd8, + 0xc2, 0xf2, 0x7f, 0xf1, 0xbc, 0xb0, 0x9d, 0xaa, 0x9e, 0x99, 0x33, 0xe8, 0xea, 0x9f, 0x03, 0xcf, + 0x0d, 0xff, 0xc1, 0x75, 0xef, 0xe4, 0x93, 0xfc, 0x84, 0x44, 0xfe, 0x22, 0x10, 0x2a, 0x39, 0x3d, + 0x5a, 0x5d, 0xd2, 0xf8, 0x25, 0xc9, 0xf9, 0x28, 0xde, 0xc7, 0xc6, 0x74, 0xd2, 0xdc, 0x56, 0xc9, + 0xda, 0x3e, 0x3b, 0xed, 0x78, 0x77, 0x66, 0xe9, 0x3d, 0x45, 0x56, 0xaf, 0x77, 0xd8, 0x79, 0xe8, + 0xb4, 0xf1, 0x10, 0x52, 0x47, 0x29, 0x06, 0x7a, 0x6c, 0x6e, 0xc1, 0xbd, 0xd1, 0x90, 0x5f, 0x05, + 0x57, 0x0f, 0x92, 0x99, 0x1d, 0x9b, 0xa2, 0xe1, 0x16, 0x38, 0x7b, 0xdb, 0xc9, 0x5e, 0xf8, 0xfe, + 0x0a, 0xe2, 0x16, 0x27, 0x2c, 0x29, 0x6b, 0xf9, 0x31, 0x75, 0xc4, 0xc6, 0x96, 0x6e, 0x5c, 0x86, + 0xae, 0xa5, 0xfb, 0x64, 0x2e, 0xb6, 0x51, 0x4b, 0x0b, 0xfe, 0xf2, 0x7c, 0x44, 0x7d, 0x3d, 0x16, + 0xe2, 0xac, 0xc1, 0xb7, 0x27, 0x5b, 0x7d, 0x38, 0xca, 0xff, 0x0d, 0xd9, 0x08, 0x8e, 0x57, 0xf0, + 0xbf, 0xb0, 0xc7, 0x64, 0x4e, 0x9d, 0xf2, 0x75, 0x52, 0x77, 0xbd, 0x3f, 0x0c, 0xdb, 0xdc, 0xdd, + 0x7e, 0x9c, 0xff, 0xc1, 0x51, 0x58, 0x37, 0x4d, 0xf4, 0xee, 0x6f, 0x50, 0xee, 0x6b, 0x7f, 0x87, + 0xc1, 0x65, 0x4e, 0x44, 0xf1, 0x60, 0x60, 0x7c, 0x30, 0xbe, 0xa3, 0x24, 0xdd, 0x86, 0x61, 0xbe, + 0x32, 0x40, 0xc0, 0x89, 0x54, 0x46, 0xd9, 0x57, 0x16, 0xdc, 0x99, 0x52, 0x67, 0x9f, 0xf8, 0x2b, + 0x86, 0x69, 0x27, 0x10, 0xa2, 0x62, 0x8c, 0xc6, 0x28, 0xae, 0x5a, 0x7b, 0xd2, 0x3f, 0x25, 0x27, + 0x6b, 0xe2, 0xa4, 0xbd, 0x9b, 0x3b, 0x9a, 0xae, 0xa7, 0x82, 0x43, 0x9f, 0x1d, 0xde, 0x1f, 0x13, + 0x31, 0xab, 0x5e, 0x24, 0x61, 0x2d, 0xb5, 0xe5, 0x89, 0x94, 0xcb, 0xe9, 0xdc, 0x7f, 0x12, 0x09, + 0x8a, 0x64, 0xb7, 0x02, 0x01, 0xb3, 0xe1, 0xb9, 0xb8, 0x7f, 0xab, 0x8f, 0x13, 0x68, 0xf8, 0x5c, + 0xbc, 0x6d, 0x8e, 0xb8, 0xce, 0x7f, 0x6a, 0xbd, 0x84, 0x33, 0x10, 0x5c, 0x5b, 0x0b, 0xae, 0x8f, + 0x2f, 0x75, 0xf1, 0x10, 0x44, 0x5b, 0x29, 0xd4, 0x3f, 0xc1, 0x11, 0x25, 0xf4, 0x4e, 0x78, 0x86, + 0x40, 0xe8, 0xb2, 0x8f, 0x65, 0xaf, 0x10, 0x09, 0xe5, 0xa4, 0x3e, 0x56, 0x56, 0x7b, 0x89, 0x8c, + 0xbb, 0x96, 0x3b, 0x78, 0xda, 0x99, 0xa6, 0xab, 0xf4, 0x7b, 0xde, 0x8d, 0xeb, 0x2a, 0x5d, 0x29, + 0x92, 0x27, 0x84, 0x4b, 0x69, 0x36, 0x24, 0xb3, 0x50, 0xe5, 0x15, 0x91, 0x5a, 0x4a, 0xfb, 0x41, + 0x53, 0x3c, 0xb1, 0x10, 0x53, 0x39, 0xf5, 0x38, 0xc5, 0xd1, 0x2f, 0x6d, 0x3e, 0x92, 0x19, 0xe6, + 0xf1, 0x0f, 0x2c, 0x4c, 0xd6, 0x35, 0x9b, 0xae, 0x0a, 0x6c, 0x89, 0x89, 0x63, 0x92, 0xba, 0x3e, + 0x38, 0xce, 0x26, 0x3e, 0x89, 0x97, 0xc6, 0x16, 0x89, 0x5b, 0xfd, 0x91, 0x5c, 0x5f, 0x21, 0xe6, + 0x47, 0xa5, 0xed, 0x7b, 0xdb, 0x7f, 0x8c, 0x39, 0x37, 0x2e, 0x67, 0x25, 0x33, 0x15, 0x6b, 0xaa, + 0xf8, 0x52, 0x6c, 0xb3, 0x3c, 0x99, 0xcf, 0x42, 0xef, 0x47, 0x67, 0xc2, 0x99, 0x6b, 0xd5, 0x52, + 0x6f, 0x2e, 0x71, 0x5b, 0xbf, 0xc4, 0x42, 0xab, 0x2a, 0x7d, 0x9a, 0xa1, 0xaf, 0x12, 0x0a, 0x0d, + 0x10, 0xfc, 0xff, 0xbf, 0xc5, 0x68, 0x11, 0x15, 0xd7, 0x6e, 0xbe, 0x0b, 0xa3, 0xcb, 0xd5, 0xf6, + 0x33, 0x30, 0xff, 0x2f, 0x1b, 0xc7, 0xe0, 0x97, 0x6c, 0x1d, 0xf7, 0x7c, 0xbe, 0x0a, 0xf8, 0xce, + 0x4d, 0xda, 0xae, 0xd1, 0x91, 0x6e, 0xff, 0x0d, 0x9f, 0x2f, 0xaf, 0xe3, 0x3d, 0xf8, 0x81, 0x0f, + 0x88, 0x71, 0xa7, 0xf8, 0x9a, 0x12, 0xdc, 0x48, 0x80, 0x88, 0xc1, 0x59, 0xb8, 0x85, 0x8c, 0x5d, + 0x31, 0x3f, 0x2b, 0xf1, 0x3f, 0x12, 0x27, 0xc4, 0x0a, 0x17, 0x98, 0x82, 0x33, 0x45, 0x8d, 0x7e, + 0x30, 0xc2, 0xf2, 0x4a, 0xdb, 0x6c, 0x85, 0x4b, 0xb3, 0xf1, 0x6e, 0xb9, 0x6e, 0xb8, 0x88, 0x52, + 0x8c, 0x08, 0xb4, 0x14, 0x81, 0x76, 0xc1, 0x05, 0x95, 0x3f, 0x6d, 0x20, 0x65, 0xab, 0xd6, 0x1f, + 0x57, 0x19, 0xb5, 0xee, 0x37, 0x76, 0x30, 0x54, 0xb0, 0x36, 0xf8, 0x26, 0xdb, 0x1d, 0xda, 0xc7, + 0xa4, 0x21, 0x9e, 0x4c, 0x57, 0xf8, 0xab, 0x6b, 0x59, 0xbe, 0x5e, 0x4a, 0x68, 0x74, 0x3f, 0x2c, + 0x7d, 0x2e, 0xb8, 0xd2, 0xf1, 0x56, 0x87, 0xd2, 0xbf, 0x3d, 0xf8, 0xeb, 0x09, 0x4f, 0x49, 0xe9, + 0x25, 0x52, 0x7c, 0x40, 0xae, 0x9b, 0xa7, 0x7a, 0xe6, 0xd6, 0x2f, 0xe1, 0x1b, 0xdb, 0x57, 0x6b, + 0xad, 0xf8, 0x90, 0x4e, 0x74, 0xf3, 0xeb, 0x1e, 0xac, 0x5d, 0xf0, 0x43, 0x2b, 0x09, 0x6b, 0xb3, + 0xc4, 0x82, 0xa9, 0x3a, 0x7e, 0xa9, 0xb6, 0x9d, 0xfb, 0xe1, 0x11, 0x48, 0xfa, 0xaa, 0x9a, 0xcb, + 0xa5, 0x26, 0x3d, 0x5e, 0x13, 0x12, 0x8a, 0xac, 0xcc, 0x63, 0x1e, 0xaa, 0xf8, 0x66, 0x7e, 0xbf, + 0x87, 0xf3, 0xd0, 0x70, 0xf0, 0xba, 0x22, 0x51, 0xe2, 0x04, 0x90, 0x99, 0xb6, 0x33, 0x52, 0xb7, + 0xa7, 0x5e, 0x22, 0x11, 0x2b, 0x48, 0x71, 0x5f, 0x27, 0x8c, 0xa6, 0x25, 0xde, 0x20, 0x48, 0x52, + 0xe3, 0x67, 0x2d, 0x8f, 0x2f, 0x96, 0x1d, 0x67, 0x1f, 0x14, 0x35, 0xad, 0xfe, 0x0a, 0x65, 0x1d, + 0x74, 0xab, 0x8c, 0xcd, 0xf3, 0x79, 0x3e, 0xb6, 0xeb, 0xd3, 0x7f, 0x7e, 0x26, 0x49, 0x98, 0x8b, + 0xf0, 0x50, 0x52, 0x20, 0x48, 0xac, 0xa6, 0x9f, 0x1d, 0xcf, 0xe1, 0x7d, 0x7a, 0x15, 0xe4, 0x23, + 0xbd, 0xfc, 0xb7, 0x3f, 0x7a, 0xfc, 0xd7, 0xbf, 0xdd, 0x56, 0xaf, 0x12, 0x4a, 0xaf, 0xe2, 0xf9, + 0x3e, 0x7f, 0xf9, 0x69, 0x5f, 0xe5, 0x91, 0xd9, 0x24, 0xb8, 0x26, 0x8c, 0x26, 0x36, 0x2d, 0x26, + 0x76, 0x7c, 0x95, 0x36, 0x7e, 0x30, 0xf9, 0xb1, 0x56, 0xaa, 0xab, 0x51, 0x75, 0xf8, 0x90, 0x51, + 0x6d, 0x2d, 0x76, 0xbb, 0xe2, 0x35, 0x56, 0xb8, 0xe6, 0xbe, 0x0b, 0x3c, 0x57, 0xb8, 0xae, 0xd3, + 0xa1, 0x77, 0xc5, 0x99, 0xcd, 0x70, 0xaa, 0x64, 0x03, 0xe8, 0xfe, 0x46, 0x23, 0xd4, 0x20, 0x0b, + 0xcc, 0x7c, 0x64, 0xe4, 0x1a, 0x92, 0xa1, 0x48, 0x7c, 0xa8, 0xb6, 0xcc, 0xff, 0x48, 0x7c, 0x68, + 0x2d, 0x64, 0xb8, 0xb9, 0x08, 0x5f, 0x3f, 0xfe, 0x0b, 0xf6, 0x38, 0x79, 0xbe, 0x9a, 0x5b, 0x6a, + 0xde, 0x2f, 0xfe, 0x12, 0xb2, 0x18, 0x31, 0xe9, 0xd3, 0x5c, 0x16, 0x96, 0x33, 0x5c, 0x7e, 0xce, + 0x79, 0x4d, 0x2b, 0xc4, 0x09, 0x12, 0x67, 0x76, 0x7a, 0xe7, 0x35, 0x3e, 0x0b, 0x72, 0xf5, 0x3e, + 0xc8, 0xf3, 0x5f, 0xf3, 0x2f, 0x19, 0x63, 0x14, 0x3a, 0x30, 0xad, 0x45, 0x32, 0x30, 0x5f, 0x36, + 0xe2, 0xf1, 0x0e, 0x50, 0xf9, 0xf8, 0x2b, 0x2b, 0x18, 0xe7, 0xd5, 0xb2, 0x4b, 0x57, 0xab, 0x88, + 0x24, 0x96, 0xbd, 0xf6, 0x3f, 0x97, 0xf5, 0xff, 0xc1, 0x1f, 0x22, 0xef, 0xa9, 0x78, 0x40, 0xe7, + 0x0d, 0x2a, 0xe5, 0xce, 0x52, 0x46, 0x8b, 0x7f, 0x82, 0x8d, 0x52, 0x2e, 0x6a, 0xae, 0x47, 0x71, + 0x64, 0xac, 0xdd, 0x57, 0x4d, 0xf2, 0x56, 0xbf, 0x15, 0xb7, 0x57, 0x6f, 0xf1, 0x5b, 0x77, 0xbd, + 0xfc, 0x11, 0x55, 0xaf, 0xbe, 0x12, 0x3e, 0xee, 0x4f, 0x5f, 0x82, 0x72, 0x36, 0xbd, 0x5f, 0xd7, + 0xc9, 0x4b, 0x4b, 0xc2, 0x3a, 0x73, 0xcb, 0x2f, 0x4a, 0x45, 0x29, 0x33, 0x7c, 0x67, 0x48, 0x56, + 0x43, 0x56, 0x98, 0xda, 0x30, 0x7a, 0x48, 0x8e, 0x30, 0x4c, 0xea, 0xbf, 0x08, 0x55, 0x77, 0x2e, + 0x20, 0xa1, 0x63, 0xdd, 0x3e, 0x5b, 0x3b, 0x46, 0x5f, 0x88, 0x17, 0xc8, 0x88, 0xdd, 0x72, 0x6c, + 0xf1, 0x25, 0xe5, 0xd6, 0xb5, 0x59, 0xd5, 0xc4, 0x18, 0xcb, 0x37, 0xf1, 0x02, 0x88, 0x92, 0x29, + 0xd7, 0x05, 0x46, 0x70, 0x7a, 0xf7, 0xfb, 0xf0, 0xaa, 0xfd, 0xfc, 0x27, 0x7c, 0x26, 0x0f, 0xf8, + 0xda, 0x69, 0x7e, 0x28, 0xb3, 0xeb, 0x53, 0x67, 0x7f, 0x11, 0xe3, 0xf3, 0x83, 0x12, 0x9e, 0x5f, + 0xf8, 0x2b, 0xb2, 0x5a, 0x56, 0x96, 0xf7, 0xbd, 0x71, 0x19, 0x7e, 0x5c, 0x3c, 0x0a, 0x92, 0xfc, + 0x3f, 0x45, 0x6b, 0x1d, 0x99, 0x33, 0x33, 0x5a, 0x1d, 0xd3, 0x6c, 0xa7, 0x07, 0xe5, 0xf6, 0xf1, + 0x31, 0x10, 0xe3, 0xac, 0xae, 0xb9, 0xba, 0x7a, 0x89, 0x82, 0x53, 0xc6, 0x3d, 0xd8, 0x44, 0x35, + 0x5a, 0xf9, 0x7c, 0x94, 0x68, 0xd2, 0xf9, 0x74, 0xad, 0x78, 0x4b, 0x9a, 0xd9, 0xea, 0xbe, 0x1b, + 0xe4, 0x54, 0xdb, 0x3e, 0xd1, 0xb3, 0x37, 0x09, 0x99, 0x2b, 0x5e, 0x56, 0x3c, 0x7d, 0xba, 0xb4, + 0xe7, 0xc7, 0x19, 0xe9, 0xcd, 0x2f, 0x12, 0x25, 0x6b, 0xad, 0x46, 0xf0, 0x44, 0x65, 0x27, 0x6d, + 0x9e, 0x6f, 0x96, 0xaa, 0xaa, 0x6c, 0x41, 0xbb, 0xba, 0xe6, 0xa7, 0x51, 0xc5, 0x7c, 0x92, 0x7d, + 0x17, 0xc5, 0x5b, 0x1c, 0x6c, 0x4d, 0x98, 0x6e, 0xe6, 0x29, 0x78, 0x4f, 0x6e, 0xd9, 0xd4, 0xaa, + 0x81, 0xaf, 0x8e, 0x36, 0x21, 0xa0, 0xeb, 0x47, 0x0c, 0xb4, 0xf2, 0xdb, 0x5e, 0x0a, 0xca, 0x36, + 0x6d, 0x5e, 0x5c, 0x2d, 0xa3, 0x4d, 0x6e, 0x86, 0x60, 0xca, 0x2d, 0x5f, 0xe0, 0xa0, 0xad, 0xaf, + 0xcb, 0xfb, 0xe3, 0x3c, 0x7a, 0xc1, 0x0b, 0x72, 0xff, 0x18, 0xad, 0xf6, 0xd3, 0xee, 0x86, 0xd3, + 0x7c, 0x07, 0xe3, 0xc8, 0x95, 0xad, 0x19, 0x72, 0xef, 0x3e, 0x78, 0x68, 0xab, 0x79, 0xef, 0x88, + 0xc2, 0x4a, 0xfc, 0x95, 0xb6, 0x97, 0x84, 0x8b, 0x99, 0xa6, 0x6a, 0x76, 0xaf, 0x98, 0x53, 0xd0, + 0xfe, 0x09, 0x8a, 0x4e, 0x9e, 0xb5, 0xb7, 0x88, 0x97, 0x82, 0x79, 0x15, 0x11, 0x53, 0x5d, 0x33, + 0x76, 0x33, 0x2f, 0x85, 0x2a, 0x9e, 0x6d, 0x3e, 0x72, 0xf7, 0xd1, 0x29, 0x04, 0x07, 0xef, 0x8e, + 0xb1, 0x30, 0xd5, 0x33, 0xa8, 0xfa, 0x19, 0xc4, 0x0d, 0xf9, 0x7c, 0xdf, 0xc1, 0x3f, 0x77, 0xd2, + 0x73, 0x27, 0xc1, 0x3e, 0x9d, 0x3e, 0x59, 0x3f, 0xd7, 0xbe, 0x08, 0xb3, 0x6a, 0x97, 0xbb, 0xec, + 0xb8, 0xc5, 0x30, 0xef, 0x21, 0x95, 0x58, 0x3f, 0x89, 0x21, 0x65, 0x64, 0x9a, 0x2c, 0xc8, 0xbc, + 0xdd, 0x55, 0x76, 0x54, 0x77, 0x9b, 0x84, 0x88, 0xea, 0x9c, 0xff, 0xac, 0x40, 0x9e, 0x7f, 0x12, + 0xf8, 0x5d, 0xa3, 0xff, 0x94, 0x4e, 0x3b, 0x56, 0x5e, 0x24, 0x46, 0xab, 0x25, 0x30, 0xaf, 0x31, + 0x75, 0x55, 0xc2, 0x3c, 0x57, 0xbd, 0xde, 0x9f, 0xc9, 0x7b, 0xb9, 0x62, 0x77, 0xc7, 0x55, 0x7b, + 0xdd, 0x75, 0x78, 0x80, 0x91, 0xdb, 0x6b, 0x55, 0xd7, 0x08, 0x8a, 0x64, 0x39, 0xdd, 0x1b, 0x66, + 0xee, 0xa1, 0x39, 0x6d, 0xd0, 0x9f, 0x2d, 0x56, 0xc2, 0x5c, 0xc2, 0x5b, 0xd4, 0xd1, 0x33, 0x1a, + 0xf2, 0xb1, 0x89, 0x82, 0x1b, 0xbe, 0xef, 0x85, 0x24, 0xed, 0x29, 0x1e, 0xfe, 0x7f, 0x64, 0xf4, + 0xbb, 0x9b, 0xa5, 0xf8, 0x62, 0xe7, 0xcd, 0x9e, 0x69, 0x56, 0x3e, 0xbf, 0xfc, 0x11, 0x77, 0x2e, + 0x74, 0x9d, 0x70, 0xf8, 0xbd, 0x6c, 0xb8, 0xce, 0x9e, 0xbd, 0xf1, 0x3c, 0xac, 0x5e, 0x9c, 0x29, + 0xc9, 0x77, 0xfc, 0xdb, 0xbb, 0x8a, 0xe8, 0xec, 0x04, 0x76, 0x65, 0x42, 0x5f, 0x96, 0xaa, 0xa9, + 0x38, 0x89, 0x35, 0xae, 0x26, 0x26, 0xf7, 0xbe, 0xd0, 0x24, 0xc4, 0x98, 0x5b, 0xdd, 0xfc, 0x25, + 0x7d, 0xdf, 0x52, 0x72, 0x72, 0xea, 0x6b, 0x93, 0x93, 0x15, 0xf7, 0x77, 0xdf, 0x26, 0xb5, 0x2f, + 0x04, 0x62, 0xb5, 0x35, 0x1c, 0x9b, 0x9b, 0x6e, 0xe4, 0xe5, 0xd2, 0x9a, 0xdf, 0x35, 0x3a, 0x70, + 0xaf, 0x25, 0x56, 0xbe, 0x63, 0xea, 0xaa, 0x27, 0x3f, 0x21, 0x75, 0x51, 0x1c, 0x83, 0x37, 0x71, + 0x1c, 0x24, 0x77, 0xdd, 0xb7, 0xdf, 0x21, 0x9d, 0x3c, 0x37, 0xc9, 0xad, 0x7c, 0xa5, 0x5a, 0xd4, + 0x4e, 0x1a, 0xe1, 0x3c, 0xf9, 0xea, 0x98, 0x5f, 0x94, 0xf8, 0xbd, 0xf3, 0x0a, 0xd5, 0x5f, 0x09, + 0x16, 0xb5, 0x7b, 0xc6, 0x70, 0x9f, 0x54, 0xda, 0x3e, 0x63, 0x79, 0x89, 0xcd, 0xc3, 0x51, 0x3f, + 0x94, 0x4e, 0xaa, 0x11, 0xea, 0xf1, 0x9c, 0x51, 0x29, 0x3e, 0xe9, 0x78, 0x98, 0x4f, 0x11, 0x37, + 0x04, 0xe4, 0x5a, 0xd6, 0xb6, 0x84, 0xf9, 0xba, 0xaa, 0xe5, 0x1b, 0x8a, 0xe1, 0xbc, 0x44, 0x35, + 0xc8, 0x31, 0xee, 0xe1, 0xdc, 0x44, 0x02, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3e, 0x1f, + 0x30, 0x22, 0xbc, 0x41, 0x91, 0xcc, 0xc3, 0x69, 0x15, 0xbf, 0xb2, 0xeb, 0x6f, 0xc7, 0x13, 0x77, + 0x9e, 0x08, 0xb4, 0x84, 0x34, 0xbf, 0x84, 0x05, 0xb7, 0xd9, 0xd6, 0x24, 0x70, 0xef, 0xc6, 0x2f, + 0x3e, 0x13, 0x7c, 0x68, 0x86, 0xd5, 0x38, 0xe2, 0x61, 0x8c, 0x42, 0x80, 0xc5, 0x6f, 0x13, 0xb9, + 0x18, 0x99, 0x44, 0xec, 0x47, 0xd7, 0xfc, 0x29, 0x56, 0xfc, 0x8f, 0x88, 0x54, 0x5b, 0x97, 0x43, + 0xd4, 0xc3, 0x96, 0x25, 0x92, 0xdc, 0x57, 0x97, 0xc2, 0x82, 0xf1, 0x9a, 0x54, 0x45, 0x1b, 0x24, + 0x86, 0xd0, 0xc0, 0x65, 0xb9, 0x5d, 0x45, 0x99, 0xed, 0x50, 0x65, 0xfc, 0x29, 0x3e, 0x3c, 0x82, + 0xdc, 0x69, 0x2b, 0x4e, 0xef, 0xb3, 0xd2, 0x34, 0x1b, 0x89, 0xb7, 0x0a, 0x63, 0x55, 0x7a, 0xf8, + 0x74, 0x66, 0xef, 0xcd, 0x96, 0xf7, 0x5f, 0x6d, 0xb5, 0x6f, 0xc1, 0x04, 0xbb, 0xdb, 0x46, 0xec, + 0xda, 0x69, 0x03, 0x69, 0x1a, 0xfa, 0xa3, 0x5f, 0x84, 0x39, 0x57, 0xcb, 0x59, 0xa9, 0xfc, 0x24, + 0x27, 0x3e, 0x75, 0x4b, 0xc3, 0xe4, 0x1b, 0xce, 0xa5, 0x3f, 0xad, 0xaf, 0xa7, 0x9e, 0x8e, 0x3f, + 0x52, 0xda, 0x85, 0xcc, 0x8b, 0xf2, 0xf6, 0xbc, 0x28, 0x74, 0xe3, 0x2c, 0x9c, 0xca, 0x49, 0xe6, + 0x6a, 0xf6, 0xf6, 0x5a, 0xa4, 0xf6, 0xb0, 0x8e, 0x8e, 0x2d, 0x7c, 0x28, 0x66, 0x24, 0x9e, 0xa2, + 0x34, 0x9c, 0x3a, 0xd6, 0x3d, 0x88, 0x47, 0xa4, 0xd4, 0x4a, 0xfc, 0x5b, 0xca, 0x41, 0x4a, 0x1e, + 0x0a, 0x73, 0xa8, 0x41, 0xbd, 0x88, 0x36, 0x1a, 0xba, 0x40, 0xc3, 0x6a, 0x0f, 0x9d, 0x5b, 0x92, + 0x62, 0x3e, 0x51, 0xa9, 0xa6, 0x9a, 0x7e, 0xb9, 0xfe, 0x71, 0x28, 0xef, 0xd3, 0x4d, 0xb6, 0xff, + 0xfe, 0x25, 0x13, 0x3b, 0xe0, 0xbb, 0x3e, 0x5f, 0x66, 0x4c, 0xea, 0xea, 0x65, 0x3e, 0x0b, 0x8d, + 0xcf, 0x96, 0xad, 0xbf, 0xcb, 0x3e, 0x9f, 0x6b, 0xd7, 0x1a, 0x29, 0x0f, 0x2e, 0x95, 0x02, 0xe3, + 0x8b, 0x5b, 0xa7, 0xb4, 0x84, 0x1b, 0x60, 0x4d, 0x1c, 0x36, 0x70, 0x71, 0xe4, 0x48, 0x7e, 0xb8, + 0x52, 0x9e, 0x4f, 0x72, 0xee, 0x63, 0x15, 0x32, 0xad, 0x56, 0xe3, 0x28, 0xe9, 0xe0, 0x93, 0x85, + 0xad, 0xa3, 0x90, 0xea, 0x1d, 0x68, 0x66, 0x8a, 0x9e, 0x74, 0xcd, 0x1a, 0xff, 0xc1, 0x5c, 0x6a, + 0xe4, 0x4f, 0x8c, 0x21, 0xfb, 0x58, 0xf5, 0x1a, 0x5b, 0x48, 0xec, 0x8c, 0x2f, 0x82, 0xf3, 0x95, + 0xbb, 0x72, 0xeb, 0x79, 0xb9, 0xaa, 0x29, 0xe6, 0x68, 0xff, 0x82, 0x33, 0x51, 0x95, 0xd4, 0x66, + 0x15, 0x70, 0x4e, 0x5d, 0x59, 0x37, 0xb9, 0xd3, 0xe2, 0xb3, 0x99, 0xb6, 0xb6, 0x6c, 0x6b, 0x86, + 0xca, 0x6b, 0x4d, 0x95, 0x7e, 0x68, 0x1e, 0xbf, 0x8f, 0x14, 0x73, 0x55, 0x71, 0xb5, 0xd6, 0xb2, + 0x33, 0xf0, 0x47, 0x3a, 0xd6, 0x0d, 0x96, 0x5f, 0x0d, 0x85, 0x79, 0x71, 0x71, 0x57, 0xff, 0x0c, + 0x65, 0xcc, 0xb9, 0xea, 0x7a, 0x47, 0xff, 0xb2, 0x3b, 0xfe, 0xb1, 0x7d, 0x1e, 0xf5, 0xc5, 0x06, + 0x90, 0x90, 0x68, 0x41, 0x44, 0xc9, 0x36, 0xfb, 0xf8, 0x26, 0x97, 0xe5, 0xb9, 0x6d, 0xde, 0xef, + 0x96, 0xfb, 0xae, 0x33, 0x35, 0x9e, 0x17, 0x6e, 0xee, 0xdb, 0x1d, 0xee, 0xef, 0xe6, 0x2f, 0x2f, + 0x2f, 0x0a, 0x0a, 0xe4, 0x62, 0x76, 0xb1, 0x38, 0x30, 0x16, 0xa5, 0x09, 0xbc, 0x64, 0x6d, 0xe9, + 0x57, 0x82, 0xa2, 0xcf, 0x96, 0x3e, 0x69, 0x9d, 0x8c, 0xaa, 0x4a, 0xa1, 0x8f, 0x84, 0xf3, 0x19, + 0x88, 0x3b, 0x32, 0xa8, 0x87, 0xd5, 0x3c, 0x51, 0xe7, 0x8b, 0x0b, 0xc3, 0xc9, 0x5a, 0xb5, 0xc2, + 0x56, 0x36, 0xd7, 0x45, 0x51, 0x7d, 0x0b, 0x7a, 0xe8, 0x8f, 0x0a, 0xf4, 0x2f, 0xaf, 0xa2, 0x39, + 0x2f, 0x28, 0x49, 0xdb, 0xfc, 0xb9, 0xb2, 0x97, 0xbe, 0xee, 0x4e, 0x0b, 0x85, 0x2b, 0x3d, 0x89, + 0x8d, 0xdb, 0x62, 0xb8, 0xf2, 0xa0, 0x1a, 0x23, 0xa0, 0xaa, 0x74, 0x26, 0xa6, 0xca, 0xf8, 0x40, + 0x88, 0xd3, 0x63, 0x67, 0xd5, 0xb5, 0x43, 0xfd, 0x8b, 0x3d, 0x29, 0xfd, 0x9a, 0x4c, 0xfc, 0x12, + 0xd9, 0x99, 0x0d, 0x57, 0x1d, 0x41, 0x98, 0xf8, 0x8d, 0xee, 0xf4, 0xa2, 0x3a, 0x09, 0xb9, 0x0f, + 0xf2, 0x85, 0x35, 0x17, 0x5c, 0xc3, 0xeb, 0x48, 0x9c, 0xc4, 0xd5, 0x7c, 0x5d, 0x49, 0xfd, 0x8c, + 0xd3, 0x5c, 0x15, 0x1a, 0x64, 0x07, 0x14, 0xdd, 0xb2, 0xc1, 0xfc, 0xaa, 0x28, 0xd0, 0x16, 0xbe, + 0x08, 0x66, 0x6a, 0x3d, 0x26, 0xf8, 0xcd, 0xa1, 0xe3, 0x46, 0x56, 0xa6, 0xb9, 0xa1, 0xc9, 0x8a, + 0x39, 0x1b, 0xf8, 0x93, 0xd9, 0xaf, 0x1f, 0xc7, 0x89, 0x82, 0xed, 0x56, 0xda, 0xf2, 0xf1, 0x02, + 0xa9, 0x1a, 0x96, 0x26, 0x98, 0xec, 0x7c, 0x40, 0xe1, 0xcc, 0xcd, 0x4a, 0xea, 0xba, 0xab, 0xc4, + 0x7d, 0x86, 0x56, 0xb5, 0x13, 0xae, 0xbf, 0xfa, 0xbc, 0x39, 0xc3, 0x41, 0x4a, 0x54, 0xd7, 0xd3, + 0x2f, 0xfc, 0xd9, 0xb3, 0xf0, 0xa6, 0x66, 0x17, 0x2b, 0x7c, 0x69, 0xa5, 0x2c, 0xa8, 0xac, 0x7c, + 0xa5, 0xdb, 0x4c, 0x9c, 0xa2, 0x6a, 0xb5, 0xc8, 0x20, 0xe7, 0x61, 0x47, 0xa3, 0x3c, 0x56, 0xc1, + 0x9f, 0xad, 0x6f, 0x38, 0x80, 0xd8, 0xfc, 0x9f, 0x82, 0x62, 0xd2, 0xb4, 0xac, 0x86, 0xda, 0x20, + 0x6e, 0xf8, 0x83, 0x21, 0xca, 0xa6, 0x4d, 0xdb, 0xf1, 0x14, 0x56, 0x97, 0x99, 0x47, 0xcb, 0x6a, + 0xac, 0x5e, 0x24, 0xb9, 0xb2, 0xd1, 0x3a, 0xb9, 0x8f, 0xf8, 0xea, 0xae, 0x68, 0x2d, 0x35, 0x5f, + 0x88, 0x1c, 0x29, 0x47, 0x17, 0xb6, 0xe9, 0x54, 0x99, 0xf8, 0x24, 0xa4, 0x33, 0x73, 0xf7, 0xc7, + 0x72, 0xe0, 0x59, 0x64, 0xf5, 0x6c, 0x64, 0xb7, 0x5c, 0xd9, 0xc2, 0x05, 0x1f, 0x8f, 0xaf, 0xec, + 0xef, 0x7c, 0x72, 0x8e, 0xbe, 0x9a, 0x4e, 0x28, 0x21, 0x9b, 0x22, 0x7d, 0x33, 0x76, 0x7e, 0x22, + 0x5e, 0x10, 0x2a, 0x8e, 0xdd, 0xba, 0x0c, 0xa3, 0xa3, 0xdb, 0x69, 0xf0, 0x43, 0xa7, 0x78, 0xe7, + 0xc3, 0x16, 0x36, 0x6d, 0xa6, 0xdb, 0x5f, 0x8a, 0x8c, 0xaf, 0xf2, 0x70, 0xcf, 0x49, 0xb5, 0xa4, + 0x4f, 0xfa, 0xe1, 0x22, 0xb7, 0x6a, 0xd6, 0xab, 0x98, 0xbb, 0xa8, 0xae, 0x28, 0x42, 0x19, 0xd9, + 0x7d, 0xbc, 0xb0, 0xf5, 0xd7, 0xcb, 0x49, 0x5e, 0xb8, 0x4f, 0x56, 0xd2, 0xbb, 0x4f, 0xe5, 0x3d, + 0xb7, 0xf9, 0x4a, 0x9e, 0x9f, 0x89, 0x32, 0x49, 0x7c, 0x6b, 0xde, 0x09, 0x04, 0x6e, 0xf1, 0x7c, + 0xc2, 0x58, 0x66, 0x9f, 0xe1, 0x4f, 0x3b, 0x05, 0x51, 0x45, 0x77, 0xa8, 0xd8, 0x37, 0x8f, 0x08, + 0x1a, 0x5b, 0xfc, 0xc4, 0x7d, 0x0f, 0xc1, 0x5c, 0xe4, 0xea, 0xad, 0xd2, 0xbb, 0x9c, 0x5a, 0x05, + 0xb3, 0xe0, 0x8c, 0x95, 0x31, 0xbf, 0xbe, 0x33, 0x6a, 0x40, 0x00, 0x0a, 0xb4, 0x87, 0xb4, 0x3f, + 0x8c, 0x79, 0x1e, 0x33, 0x65, 0xc9, 0x0f, 0xfa, 0x1a, 0xc1, 0x17, 0xc2, 0x1c, 0x4b, 0xcb, 0x8c, + 0x21, 0x7b, 0x0e, 0x20, 0x93, 0xd8, 0xb9, 0xeb, 0x96, 0xf1, 0x22, 0x45, 0x1d, 0xf6, 0xad, 0xda, + 0xc4, 0x89, 0x0a, 0x1f, 0x43, 0x72, 0xe3, 0xe2, 0x18, 0x21, 0xb3, 0x36, 0x40, 0x1b, 0x1b, 0xe1, + 0x1d, 0x0c, 0x1e, 0x75, 0xe0, 0x88, 0xcf, 0xbb, 0x0f, 0x04, 0xc3, 0x1f, 0x7a, 0x36, 0x23, 0xe7, + 0xd5, 0x10, 0x10, 0x9b, 0x10, 0x62, 0xa9, 0x98, 0xe1, 0xb6, 0x19, 0xff, 0xef, 0xf1, 0xf1, 0xc7, + 0xeb, 0x5a, 0xe8, 0x29, 0x15, 0x71, 0x53, 0xd2, 0x95, 0x86, 0x9c, 0xe4, 0xda, 0x7c, 0x85, 0x76, + 0x7f, 0x85, 0x0b, 0x49, 0xfc, 0x5a, 0xb5, 0x4b, 0x49, 0x28, 0x3e, 0x08, 0x4c, 0x4d, 0xd3, 0x2c, + 0xf4, 0xbf, 0x0a, 0xe6, 0xb3, 0x4b, 0x4e, 0xed, 0x29, 0x63, 0xaf, 0xfa, 0xfd, 0x5c, 0x49, 0x69, + 0x1b, 0x76, 0x34, 0x34, 0xdc, 0xbc, 0x12, 0x4f, 0x9e, 0x0f, 0x82, 0x3a, 0xaf, 0x5f, 0x1c, 0x21, + 0x6d, 0xe9, 0xa3, 0x2c, 0x13, 0xdb, 0x7d, 0x06, 0xfb, 0xe2, 0x0d, 0xbb, 0xee, 0xfe, 0x50, 0x96, + 0x9b, 0x6b, 0x84, 0x8f, 0xa6, 0x96, 0xe6, 0xd5, 0xc1, 0x48, 0xa4, 0xd3, 0xf6, 0x9a, 0x5a, 0x48, + 0x93, 0x3f, 0x25, 0x74, 0xfc, 0x10, 0x96, 0xb5, 0xf1, 0xf2, 0x73, 0xff, 0x82, 0xce, 0xac, 0x8d, + 0x27, 0xf6, 0x4b, 0x3b, 0xe0, 0x88, 0x86, 0xbb, 0x45, 0xef, 0x84, 0x4e, 0xc0, 0xcd, 0xe5, 0x10, + 0x90, 0x2e, 0x72, 0x48, 0xf7, 0xa4, 0x88, 0xaa, 0x3c, 0x55, 0xdd, 0xa8, 0xd8, 0xc5, 0x7a, 0x4f, + 0xe0, 0xb8, 0x8d, 0xa1, 0xbd, 0xd0, 0x39, 0xe1, 0x17, 0xc9, 0x76, 0x53, 0x43, 0xd7, 0x3f, 0xc7, + 0xf4, 0xa5, 0x81, 0x18, 0x83, 0x69, 0xe7, 0xab, 0x7e, 0x7a, 0xf8, 0x25, 0xd6, 0xaa, 0xe5, 0x74, + 0x6e, 0xa3, 0x33, 0x91, 0x38, 0x88, 0x8b, 0x72, 0x64, 0x4f, 0x96, 0x6a, 0xcb, 0x10, 0x20, 0x45, + 0x08, 0x90, 0x27, 0x8e, 0x71, 0x2a, 0x84, 0x63, 0x1e, 0x34, 0xaf, 0xd8, 0x98, 0x82, 0x1c, 0xe1, + 0x48, 0x30, 0x2e, 0x5a, 0xfe, 0x09, 0x86, 0x90, 0xfe, 0xe9, 0x22, 0x4a, 0x7f, 0x36, 0xde, 0xb1, + 0x34, 0x2d, 0x0d, 0x4d, 0x32, 0x7c, 0xa1, 0x8d, 0xa3, 0x43, 0xc2, 0x87, 0xe6, 0xd4, 0xc1, 0xd9, + 0xee, 0x25, 0x5c, 0x99, 0xb3, 0x25, 0xf1, 0x78, 0x8b, 0xe6, 0x24, 0xed, 0xb5, 0xe2, 0x68, 0xeb, + 0x8d, 0x24, 0xaf, 0x82, 0x93, 0xdd, 0xfa, 0x4f, 0xc8, 0xf9, 0x7c, 0x11, 0xd6, 0xcd, 0x26, 0x4b, + 0xd9, 0x6e, 0x8a, 0xb9, 0xad, 0xd2, 0xf9, 0xa6, 0x93, 0x69, 0xfd, 0xdd, 0xdd, 0x7d, 0x95, 0xba, + 0xfc, 0x10, 0xdb, 0x4e, 0xba, 0x6b, 0xe8, 0xdd, 0xf4, 0x3c, 0xb7, 0xd7, 0x2a, 0xe4, 0x0b, 0x3b, + 0xe2, 0x78, 0x25, 0x3b, 0xee, 0xf9, 0x85, 0x1e, 0xbe, 0x09, 0xe9, 0x11, 0x5d, 0x37, 0xc6, 0x51, + 0x18, 0xf8, 0x4a, 0xf1, 0xb3, 0x29, 0xc4, 0x4c, 0x2c, 0x79, 0x8a, 0xe6, 0x31, 0x22, 0xdd, 0x97, + 0x82, 0x32, 0x95, 0x51, 0x97, 0x66, 0x6c, 0x7c, 0x25, 0x96, 0x54, 0x12, 0x6d, 0x35, 0xf0, 0x4f, + 0x49, 0xf9, 0xd4, 0x6c, 0xf1, 0x25, 0x17, 0x89, 0x54, 0xf8, 0x44, 0x12, 0x0a, 0xb9, 0xd4, 0x7d, + 0xe2, 0x41, 0x34, 0x8f, 0x4c, 0x6e, 0xe2, 0x4a, 0x5b, 0x03, 0x03, 0x59, 0x19, 0xdc, 0xae, 0x2e, + 0xfb, 0x58, 0x18, 0xd7, 0x1e, 0x30, 0xf0, 0xa5, 0x01, 0x98, 0x62, 0xdf, 0x6d, 0x3b, 0xb9, 0xe3, + 0xc9, 0x55, 0xa2, 0x25, 0x56, 0xb4, 0x6c, 0x3c, 0x10, 0x13, 0x97, 0x1f, 0x3c, 0x2e, 0x86, 0x40, + 0xb3, 0x3f, 0x4d, 0x99, 0xbe, 0x22, 0x8e, 0xff, 0x04, 0xe6, 0x9b, 0x24, 0x31, 0xcd, 0xd7, 0x05, + 0x0c, 0x4c, 0x29, 0x25, 0x65, 0x7a, 0x6d, 0x46, 0x59, 0x1c, 0xf0, 0xe2, 0xaf, 0x53, 0xb2, 0x53, + 0xb1, 0x33, 0xfc, 0xa6, 0xf0, 0xf0, 0x58, 0xfc, 0x48, 0x80, 0xa5, 0x49, 0x42, 0x4a, 0xb3, 0x25, + 0x62, 0xd4, 0xda, 0x22, 0x66, 0xaa, 0x22, 0xbf, 0xa1, 0x50, 0x42, 0xb4, 0xab, 0x12, 0x24, 0x65, + 0xef, 0x7b, 0xca, 0xc7, 0x6c, 0x39, 0x2a, 0xc6, 0x99, 0x9f, 0xc1, 0x1d, 0x8a, 0x02, 0x29, 0xd8, + 0xc7, 0xf7, 0x5e, 0x5f, 0x09, 0xc9, 0x6b, 0xb8, 0xf2, 0xcf, 0x30, 0xf0, 0xee, 0x09, 0x1d, 0x36, + 0x82, 0x11, 0x5d, 0x56, 0xa7, 0x53, 0x64, 0xbf, 0xa7, 0xa5, 0xb1, 0xff, 0xff, 0xc7, 0x3b, 0xeb, + 0x8a, 0x2d, 0xec, 0xb9, 0x23, 0xe0, 0x86, 0x78, 0xfb, 0xc9, 0xd9, 0x5a, 0xa5, 0x27, 0x42, 0x65, + 0x7c, 0x20, 0x42, 0xc1, 0xf4, 0xa9, 0x74, 0xdb, 0x13, 0xd0, 0xae, 0xf9, 0x6a, 0x9d, 0x5f, 0x1f, + 0x55, 0x9b, 0xa7, 0x8e, 0x2e, 0x4e, 0xb2, 0xb8, 0x22, 0x17, 0x93, 0xfb, 0xec, 0xd6, 0xda, 0xae, + 0x18, 0xd5, 0xdb, 0x0e, 0x5d, 0xdb, 0xcd, 0x39, 0x8d, 0x7e, 0xdb, 0xb7, 0xe0, 0xb0, 0x87, 0x23, + 0xd3, 0x69, 0xaa, 0x08, 0xf1, 0xf5, 0xef, 0x85, 0x29, 0xad, 0x18, 0x5b, 0x64, 0x35, 0x92, 0x06, + 0x50, 0xc0, 0x16, 0x65, 0xea, 0x5e, 0x91, 0x30, 0x9c, 0x78, 0x2b, 0xe2, 0x3e, 0x83, 0x52, 0x71, + 0x05, 0xaa, 0x96, 0x0a, 0x34, 0x3b, 0xbb, 0x1f, 0x57, 0x54, 0xcf, 0xc1, 0x2d, 0x2c, 0x92, 0xd5, + 0x34, 0xff, 0x17, 0xd4, 0x71, 0xc1, 0xca, 0xf8, 0x2b, 0xb1, 0x2d, 0x5b, 0xaa, 0xe3, 0xcd, 0x12, + 0xef, 0x8d, 0xaa, 0xf8, 0xab, 0x23, 0xf5, 0xa2, 0x96, 0xa4, 0xa8, 0x46, 0xda, 0x36, 0x8a, 0xf9, + 0x69, 0x9f, 0xf8, 0xef, 0x3f, 0xb4, 0x7c, 0xeb, 0xbe, 0x5f, 0x58, 0xbe, 0x09, 0x49, 0x5a, 0x97, + 0xa3, 0x03, 0xf6, 0x5f, 0x89, 0x10, 0x0a, 0xca, 0xb0, 0x29, 0x38, 0x9b, 0xb2, 0xd5, 0x57, 0x5b, + 0xc3, 0x78, 0x40, 0x12, 0xd9, 0x30, 0x82, 0xb8, 0xfa, 0xc2, 0x81, 0xfb, 0x12, 0xc4, 0xe7, 0x88, + 0x0f, 0x60, 0xf5, 0x53, 0x62, 0xca, 0xaa, 0xb4, 0xbe, 0x2a, 0xdb, 0xa7, 0x89, 0x10, 0x09, 0x6b, + 0x13, 0x31, 0x91, 0xa4, 0x8a, 0xbb, 0x60, 0xcf, 0x8c, 0x21, 0x60, 0xc4, 0x0d, 0x11, 0x83, 0x4e, + 0x03, 0x76, 0xdc, 0x01, 0x0c, 0x4a, 0xe2, 0x50, 0x5d, 0x24, 0x0b, 0xa4, 0x11, 0x73, 0x4f, 0x2a, + 0xb0, 0xc7, 0xd9, 0x3e, 0x1a, 0x65, 0xf8, 0x98, 0xd9, 0xfe, 0x16, 0x6b, 0x44, 0x02, 0x09, 0x40, + 0xb0, 0x16, 0xa8, 0xc9, 0x21, 0xd1, 0xc2, 0x13, 0xdf, 0x2a, 0x83, 0xcf, 0x22, 0xf4, 0xba, 0x90, + 0xf7, 0x85, 0x98, 0x5b, 0xe4, 0x0f, 0xdb, 0xc2, 0x82, 0xdf, 0xdb, 0x6c, 0xf4, 0xc4, 0x88, 0x0a, + 0x46, 0xe9, 0x19, 0x47, 0xa4, 0x22, 0xe3, 0xbe, 0x17, 0x59, 0x73, 0xd9, 0x72, 0x71, 0x6c, 0xbc, + 0x40, 0xcf, 0xad, 0x26, 0x30, 0x60, 0x87, 0xec, 0xb5, 0xcd, 0x8d, 0x0b, 0x93, 0xcc, 0xa7, 0xc7, + 0x73, 0x53, 0x07, 0x4b, 0xcd, 0xef, 0x7f, 0x45, 0xd4, 0x2f, 0xc1, 0x39, 0xc4, 0xf9, 0x31, 0x62, + 0x89, 0xb0, 0x91, 0xf6, 0x25, 0xf1, 0xc4, 0x43, 0xa9, 0x75, 0x57, 0x58, 0xf8, 0xfe, 0xf5, 0x5f, + 0x88, 0xbd, 0xdd, 0xc5, 0x7f, 0x9b, 0x26, 0x7e, 0x27, 0xa9, 0xb1, 0x92, 0xe4, 0xcf, 0x16, 0x7d, + 0x53, 0x8a, 0xd3, 0x7f, 0x19, 0x1f, 0xa7, 0xa3, 0x77, 0x72, 0xe0, 0xfd, 0x2e, 0xdc, 0xf9, 0xa9, + 0x70, 0x30, 0x87, 0xc6, 0x91, 0xf9, 0xf1, 0x23, 0x98, 0xb9, 0x00, 0x89, 0xeb, 0xb6, 0xde, 0xdb, + 0xed, 0x13, 0x97, 0x98, 0x76, 0x2d, 0x74, 0x10, 0xb7, 0xbf, 0x46, 0xb4, 0xe1, 0x97, 0xeb, 0x6d, + 0x9e, 0x1e, 0x14, 0xb4, 0x30, 0x15, 0xbb, 0xc0, 0x28, 0xd4, 0xb5, 0x60, 0xc1, 0x35, 0x0c, 0x2b, + 0x59, 0xa7, 0x79, 0x68, 0x2c, 0x8e, 0x84, 0x49, 0x2c, 0xa8, 0x3c, 0x26, 0x5b, 0xab, 0xcd, 0xb7, + 0x02, 0x8a, 0x65, 0xf8, 0xed, 0x24, 0x63, 0x3e, 0x49, 0x83, 0x6d, 0x5b, 0x6b, 0xbf, 0xc9, 0x77, + 0xc1, 0x4e, 0x13, 0xb0, 0x3b, 0x70, 0xe7, 0x6e, 0xc2, 0x27, 0x5f, 0x49, 0xca, 0x94, 0x0e, 0x44, + 0x57, 0xf8, 0xf4, 0xe5, 0x6f, 0x82, 0x9b, 0x5d, 0x49, 0x70, 0xe8, 0xc3, 0x39, 0xa2, 0x8b, 0x6f, + 0x61, 0xb9, 0x41, 0xe5, 0xf0, 0xa5, 0x26, 0xec, 0x57, 0x79, 0xe6, 0x90, 0xa7, 0x81, 0x88, 0x99, + 0xc7, 0x6f, 0xf4, 0xab, 0x1c, 0xa2, 0x69, 0x6e, 0x76, 0xf8, 0xc9, 0xf9, 0x4a, 0x1d, 0x99, 0x1b, + 0x1a, 0x3c, 0xd7, 0xbc, 0x56, 0x33, 0x83, 0xe2, 0x76, 0x6f, 0xe1, 0x48, 0xdb, 0x74, 0xba, 0xba, + 0x49, 0x49, 0x96, 0xf9, 0x2b, 0x55, 0x15, 0x7c, 0x28, 0x24, 0x44, 0x92, 0xe6, 0x83, 0xf2, 0x40, + 0x8e, 0x83, 0x48, 0xae, 0xf4, 0x4b, 0x57, 0xda, 0x44, 0xa4, 0x1d, 0x83, 0x6d, 0xd8, 0xf1, 0x21, + 0x42, 0x33, 0x3d, 0xbe, 0x73, 0xcd, 0x1e, 0xa4, 0xab, 0x1a, 0x0a, 0xd5, 0x98, 0xe3, 0x81, 0x8c, + 0x4a, 0x1a, 0x62, 0x51, 0xf1, 0xa6, 0xf6, 0x7e, 0x92, 0x6c, 0x15, 0xf7, 0x19, 0xea, 0x4e, 0xe9, + 0x4c, 0xc2, 0x41, 0xd6, 0x37, 0x05, 0xe3, 0x0b, 0xf1, 0x98, 0x87, 0xfe, 0x16, 0x2b, 0xac, 0x78, + 0x71, 0xae, 0x18, 0x5f, 0x1c, 0x13, 0x7e, 0x5d, 0xc6, 0x4b, 0x78, 0x85, 0xfb, 0xdd, 0x3f, 0x04, + 0xf9, 0x2e, 0x34, 0x87, 0x8e, 0xa2, 0xde, 0xf8, 0x7e, 0x9e, 0xb8, 0x7e, 0xed, 0xbf, 0x33, 0x23, + 0xb8, 0x4c, 0xed, 0x16, 0xe3, 0xf0, 0x67, 0x22, 0xaa, 0x35, 0xe2, 0x46, 0x15, 0x6a, 0xb3, 0x82, + 0x02, 0xa4, 0x46, 0x80, 0xe3, 0xa4, 0xad, 0x23, 0x4b, 0x5e, 0xc4, 0xe0, 0x56, 0x24, 0x48, 0xd3, + 0x30, 0x08, 0xea, 0xf0, 0x04, 0xdf, 0x53, 0xdb, 0xbd, 0x29, 0x6a, 0x27, 0xa8, 0x8d, 0xf1, 0x6e, + 0x60, 0x9e, 0x92, 0xb4, 0x35, 0x26, 0xb5, 0xfb, 0x67, 0xbf, 0x11, 0x05, 0xa5, 0xcb, 0x8e, 0xdc, + 0x3e, 0x27, 0xe0, 0x6f, 0xef, 0x12, 0x0a, 0xae, 0x7c, 0x49, 0xb9, 0x74, 0x33, 0xae, 0x96, 0xe8, + 0x36, 0x18, 0x98, 0x52, 0xab, 0xe4, 0xd2, 0xa0, 0x87, 0xaa, 0xa5, 0x0c, 0xd4, 0x44, 0x0c, 0x55, + 0x05, 0x2d, 0x35, 0x70, 0x06, 0xa6, 0x46, 0xf1, 0x21, 0x42, 0x11, 0x1f, 0x75, 0x5c, 0x35, 0x73, + 0xf7, 0xe7, 0x5a, 0x95, 0x7f, 0x6d, 0x07, 0x4b, 0x16, 0x28, 0x5f, 0x81, 0x1e, 0x99, 0x40, 0x26, + 0x4b, 0xfd, 0x46, 0x70, 0x1f, 0x82, 0x50, 0x7f, 0x11, 0x05, 0x79, 0x5e, 0xb9, 0xf6, 0x6f, 0x37, + 0xe3, 0xa7, 0x08, 0xc6, 0xcb, 0x74, 0x30, 0x95, 0x81, 0x8e, 0x16, 0x9a, 0x01, 0xcb, 0x77, 0xe0, + 0x33, 0x0c, 0x8d, 0x30, 0x3a, 0x7e, 0xd5, 0x51, 0xc5, 0x30, 0x95, 0xda, 0xe5, 0x66, 0x7b, 0xa5, + 0x4f, 0x42, 0x55, 0x32, 0xc0, 0xc0, 0x76, 0x3d, 0x08, 0x92, 0xf8, 0xbb, 0xe1, 0x0b, 0x7e, 0xb0, + 0xf4, 0x7e, 0x1f, 0xfc, 0xc9, 0x4f, 0x3c, 0x43, 0x56, 0x0c, 0x2c, 0x0b, 0xda, 0x10, 0x86, 0x01, + 0x45, 0x0a, 0x90, 0x0c, 0x80, 0x6f, 0xb5, 0x6e, 0x24, 0xf0, 0xc5, 0x63, 0xc6, 0xb9, 0xa0, 0x37, + 0x3e, 0xdc, 0xa9, 0x01, 0xdb, 0xf8, 0x76, 0x1d, 0xb7, 0xcf, 0x48, 0xf4, 0x1a, 0x4e, 0xd3, 0x58, + 0xcb, 0xbf, 0xca, 0x58, 0x24, 0x8a, 0x77, 0xdd, 0x09, 0xf9, 0xc5, 0xaa, 0x21, 0xad, 0x5b, 0xfc, + 0xbc, 0xf5, 0xfc, 0x9a, 0x4d, 0x19, 0xc8, 0x67, 0x77, 0x7f, 0x0c, 0x11, 0xee, 0x3a, 0x84, 0x9b, + 0xb7, 0xdc, 0x16, 0xde, 0xf5, 0x9b, 0xf8, 0x50, 0x8f, 0x7e, 0x7f, 0xbb, 0x9f, 0xd6, 0xb5, 0xb5, + 0x2f, 0x8b, 0x12, 0xb1, 0x07, 0xa6, 0x9b, 0xfe, 0x2e, 0xee, 0xee, 0xee, 0xee, 0xb8, 0x50, 0x8d, + 0x26, 0xef, 0xa6, 0x83, 0x0e, 0x56, 0x17, 0x2e, 0x9e, 0xa7, 0x2c, 0x9f, 0xe0, 0xb0, 0x89, 0xea, + 0xf8, 0xf1, 0xf5, 0x3c, 0x2b, 0x95, 0xe9, 0xdb, 0xbe, 0x0a, 0xca, 0xf1, 0x02, 0xe7, 0x33, 0x70, + 0xc5, 0xd4, 0x54, 0x98, 0xe8, 0x4b, 0xef, 0x3a, 0x47, 0xa5, 0x05, 0x59, 0x36, 0x5b, 0xe1, 0x49, + 0x3a, 0xc5, 0xd0, 0x9b, 0xdd, 0x46, 0x6b, 0x70, 0x98, 0x2b, 0xe9, 0xdc, 0x6e, 0x3d, 0x1a, 0xe7, + 0xaf, 0x93, 0x81, 0xc3, 0xc6, 0x68, 0x35, 0x77, 0x97, 0xca, 0x25, 0x07, 0x3b, 0x7a, 0x87, 0x09, + 0xe6, 0x64, 0x6d, 0xf5, 0x75, 0x07, 0x06, 0x3f, 0xc2, 0x85, 0x76, 0xe0, 0xda, 0x6a, 0x58, 0x87, + 0xeb, 0x41, 0x0b, 0xdf, 0x97, 0xa1, 0xb0, 0xf9, 0x2b, 0x50, 0xb4, 0xef, 0xe8, 0xb3, 0xa7, 0x4f, + 0x96, 0x67, 0xc7, 0x15, 0x58, 0xcc, 0x2d, 0x4d, 0xc8, 0xa1, 0xf5, 0x2a, 0xd8, 0x3f, 0x85, 0x2f, + 0x26, 0x72, 0x3a, 0x78, 0xdf, 0xcc, 0xe4, 0x37, 0xb8, 0xa8, 0xe6, 0xa3, 0x76, 0x21, 0x6d, 0xd6, + 0xd0, 0xb4, 0xdd, 0xf0, 0xa5, 0x0d, 0x5d, 0xad, 0xe2, 0xc8, 0xe2, 0x57, 0x41, 0xb3, 0x83, 0x5f, + 0x3a, 0x3d, 0xd4, 0xfa, 0xf8, 0x29, 0xb6, 0x4d, 0x27, 0x2c, 0x8e, 0x3e, 0xdc, 0x38, 0x8e, 0x21, + 0xcf, 0x75, 0xf5, 0xe1, 0x11, 0x84, 0x95, 0xc5, 0xe0, 0xcf, 0x5d, 0x50, 0x38, 0xc4, 0x22, 0xb3, + 0x10, 0x49, 0xfe, 0x62, 0xf8, 0x90, 0x88, 0x2a, 0xc0, 0x72, 0x72, 0x61, 0x3b, 0x40, 0x0a, 0x8a, + 0xb7, 0x18, 0x8e, 0x0d, 0x05, 0x73, 0x09, 0x7c, 0x48, 0x50, 0x9f, 0x42, 0x39, 0x06, 0xd1, 0x88, + 0x70, 0x2a, 0xa1, 0x35, 0x44, 0x2b, 0x24, 0xc9, 0x59, 0xa1, 0x7a, 0x5e, 0x4f, 0x4c, 0x0e, 0xdf, + 0x0a, 0x14, 0xb4, 0x7c, 0xfb, 0x04, 0xfa, 0x59, 0xcd, 0x3f, 0x41, 0x26, 0x8a, 0xef, 0xe3, 0xb4, + 0x85, 0xd5, 0x8d, 0xb3, 0xff, 0x82, 0xca, 0x97, 0x03, 0xd8, 0xae, 0x06, 0x99, 0xf1, 0x7b, 0x7b, + 0x58, 0x31, 0xf1, 0xa4, 0xcc, 0x7d, 0x86, 0xe1, 0x55, 0x70, 0x97, 0x08, 0xd0, 0xf2, 0x08, 0x18, + 0x07, 0x23, 0x38, 0x18, 0x1d, 0x9a, 0x9f, 0x32, 0x42, 0xdb, 0xe6, 0xe9, 0xb3, 0x5f, 0x0a, 0x09, + 0x14, 0xdb, 0xce, 0x99, 0xfa, 0x31, 0xa4, 0xc6, 0xb7, 0x4a, 0x0d, 0x13, 0xdc, 0xb8, 0x72, 0x50, + 0xf0, 0x54, 0x21, 0xec, 0x2a, 0x74, 0x89, 0x48, 0xc4, 0x4d, 0xa8, 0xa1, 0xfd, 0x68, 0xb6, 0xd6, + 0x56, 0x51, 0xfc, 0x40, 0xb1, 0x79, 0x09, 0xba, 0x7f, 0x69, 0x55, 0x71, 0x01, 0x10, 0x90, 0xe5, + 0x4e, 0x0d, 0x7a, 0x78, 0x4c, 0x23, 0x76, 0x9a, 0x61, 0x71, 0x23, 0x2e, 0x6a, 0x3c, 0xb0, 0x1b, + 0xec, 0xfb, 0x79, 0xc1, 0x80, 0x90, 0xe1, 0xa0, 0x71, 0xc0, 0xf4, 0x33, 0x03, 0x2d, 0xf2, 0xd5, + 0x1f, 0x78, 0x0d, 0x63, 0x3d, 0x1e, 0x2f, 0xc2, 0x21, 0x41, 0xa1, 0x62, 0xc8, 0xb3, 0x3f, 0x84, + 0x9a, 0x87, 0xda, 0x87, 0x5a, 0x52, 0xec, 0x50, 0x16, 0x58, 0xba, 0x8b, 0x3c, 0x8c, 0x00, 0x08, + 0x72, 0xd4, 0x0a, 0x59, 0xc9, 0x05, 0x01, 0xd5, 0x82, 0xb0, 0xb1, 0x2e, 0xf5, 0xb1, 0xd8, 0xfe, + 0x26, 0x14, 0x10, 0x7e, 0xb5, 0x92, 0x92, 0x85, 0xd4, 0xbd, 0xaa, 0x98, 0xab, 0x3e, 0x54, 0x97, + 0x86, 0x99, 0x19, 0xc2, 0xcc, 0xf3, 0x4c, 0x9b, 0xe3, 0xf4, 0x24, 0x08, 0x84, 0xc4, 0x31, 0x22, + 0x46, 0xc3, 0x2c, 0x4a, 0x1d, 0x28, 0xb1, 0x8e, 0xf3, 0xce, 0x72, 0x68, 0x60, 0xca, 0xa6, 0xf9, + 0xe8, 0x2c, 0x0f, 0x48, 0x89, 0xf9, 0xec, 0x06, 0x62, 0x08, 0x04, 0xce, 0x6b, 0x5d, 0x60, 0x27, + 0x75, 0xff, 0x0c, 0x08, 0x7a, 0x07, 0x58, 0x72, 0x71, 0xb2, 0xb6, 0x2f, 0xd5, 0x6d, 0x80, 0x10, + 0x90, 0xb1, 0xe0, 0x70, 0x5a, 0x93, 0x5d, 0xbe, 0x80, 0x1b, 0xec, 0x13, 0x30, 0x1a, 0xc7, 0x8d, + 0xc2, 0x95, 0x5b, 0xf9, 0xaa, 0x72, 0x6b, 0x0b, 0xd7, 0x58, 0x3b, 0x04, 0xcb, 0xc6, 0xf9, 0x6a, + 0x0b, 0x2e, 0x5e, 0x16, 0xc2, 0x43, 0xdb, 0xbb, 0x71, 0x2b, 0x1b, 0xb2, 0x0d, 0xdf, 0x2d, 0x29, + 0x21, 0x0c, 0x70, 0x9d, 0xe5, 0xf7, 0xbf, 0xc1, 0x5d, 0xf7, 0x10, 0xb1, 0x15, 0xb9, 0xf9, 0xba, + 0xae, 0xa4, 0x77, 0x3e, 0x0a, 0xa7, 0xca, 0xb5, 0x51, 0xaa, 0x7a, 0xdb, 0x20, 0xbe, 0x10, 0xc7, + 0x4e, 0x6d, 0x56, 0x76, 0x77, 0x7b, 0xf8, 0xcb, 0xbb, 0xef, 0x7b, 0xdd, 0x77, 0xf1, 0xe7, 0x1c, + 0xaf, 0xa3, 0xd8, 0x9c, 0xea, 0x6d, 0xdf, 0xc2, 0x84, 0x8a, 0xee, 0x5e, 0x4a, 0x35, 0x5d, 0xbb, + 0xbb, 0xbb, 0xd2, 0x4a, 0xbc, 0x69, 0x33, 0xbe, 0xbb, 0xb6, 0xc5, 0x2f, 0x1b, 0x5b, 0x7f, 0xdb, + 0x89, 0x25, 0x5e, 0xe4, 0x61, 0xff, 0x0a, 0x51, 0x3b, 0x01, 0x1f, 0xd7, 0x12, 0xf2, 0x4a, 0x28, + 0x2e, 0x67, 0x6b, 0xa8, 0xc8, 0x6f, 0xb6, 0x28, 0x5d, 0xfe, 0x14, 0xac, 0x19, 0xd6, 0x5d, 0xe8, + 0x3f, 0x20, 0xa0, 0xd0, 0xd3, 0x15, 0x43, 0xe8, 0x4d, 0x3a, 0x90, 0x19, 0x4c, 0x5d, 0x6b, 0x82, + 0x31, 0xaf, 0x85, 0x3f, 0x24, 0xb8, 0xe9, 0xfe, 0xdd, 0x7e, 0x09, 0x12, 0x6b, 0x37, 0xc1, 0x5e, + 0xd5, 0xb6, 0x25, 0x96, 0x37, 0xd7, 0xa6, 0xd1, 0x5b, 0xe3, 0x05, 0xa7, 0x57, 0x9b, 0x8a, 0xbb, + 0x2b, 0x13, 0x5e, 0xe7, 0xf3, 0xe3, 0x0d, 0x5c, 0xfe, 0x2b, 0xfa, 0x4d, 0x95, 0x43, 0x6a, 0x58, + 0x5d, 0x8c, 0xfc, 0x29, 0x4a, 0x32, 0xb9, 0xfb, 0x63, 0xe9, 0x8e, 0x29, 0xb6, 0xf4, 0xb6, 0x0d, + 0x99, 0x53, 0xe1, 0x42, 0xaa, 0x82, 0x16, 0xae, 0xde, 0x2a, 0x58, 0xd9, 0xf6, 0xae, 0x82, 0xb2, + 0xb8, 0x68, 0xa8, 0x39, 0x7c, 0x23, 0xc1, 0xe4, 0x45, 0x9e, 0x10, 0x19, 0x10, 0x3d, 0xf2, 0x19, + 0x37, 0x39, 0x99, 0x76, 0x6b, 0xd9, 0xf2, 0x75, 0x8f, 0xc2, 0x9b, 0x19, 0x3c, 0x4d, 0xa7, 0x91, + 0x8b, 0x20, 0xc6, 0x55, 0xdc, 0xcb, 0x8f, 0x25, 0x0b, 0xa8, 0x3b, 0x44, 0xdf, 0x1a, 0x23, 0x26, + 0x2e, 0x34, 0x30, 0x55, 0xe7, 0x30, 0x6c, 0x20, 0x8b, 0x92, 0x79, 0x47, 0x88, 0x18, 0x0b, 0x48, + 0xe2, 0xb5, 0x97, 0xd6, 0x2f, 0x34, 0x3c, 0x14, 0x9e, 0xd8, 0x31, 0x71, 0x9a, 0xed, 0x26, 0x65, + 0xdd, 0xf4, 0x6f, 0x07, 0x61, 0xe2, 0xe6, 0x8d, 0xf7, 0x4f, 0xe1, 0x79, 0xaf, 0x2f, 0x59, 0x8c, + 0xd6, 0x30, 0x46, 0xff, 0x35, 0x8c, 0xde, 0x35, 0xf8, 0x36, 0xc8, 0x3f, 0xc1, 0x05, 0xf1, 0x0f, + 0x3f, 0x1a, 0x14, 0x2a, 0x76, 0xbb, 0x06, 0x5b, 0xb9, 0x5f, 0xba, 0xa1, 0xfb, 0xd9, 0x09, 0xfe, + 0xe4, 0xdd, 0x3f, 0x86, 0x39, 0x74, 0x61, 0x49, 0x8f, 0xb2, 0x7f, 0xe3, 0x3d, 0xf1, 0x20, 0xb0, + 0x8a, 0x9a, 0x32, 0x3d, 0xd0, 0x9d, 0xb9, 0x50, 0xc0, 0xdd, 0xd8, 0x45, 0xf1, 0xa4, 0x29, 0x0a, + 0xc8, 0x44, 0x33, 0xfd, 0x61, 0x8d, 0x26, 0x7f, 0xd2, 0x17, 0x49, 0x31, 0x03, 0x5a, 0xa7, 0x4f, + 0xa3, 0x02, 0x08, 0xf9, 0x2f, 0x7f, 0xd3, 0x27, 0xf1, 0x21, 0x00, 0x52, 0x7f, 0x15, 0xd9, 0x00, + 0x85, 0xec, 0x10, 0xca, 0xa3, 0xa0, 0x02, 0xc3, 0xea, 0x53, 0x3c, 0x72, 0x95, 0xf1, 0x01, 0x42, + 0x2d, 0x08, 0x9f, 0x5c, 0x00, 0x0d, 0x48, 0xf5, 0x90, 0xce, 0x54, 0x38, 0x3d, 0xa5, 0x29, 0xa5, + 0x72, 0x3c, 0x30, 0x60, 0x9a, 0x07, 0x7b, 0xa5, 0x50, 0xf0, 0x48, 0xb1, 0x78, 0x74, 0x90, 0x31, + 0x89, 0x44, 0x7c, 0xf2, 0x2e, 0x20, 0x6d, 0x8b, 0x30, 0x68, 0xc9, 0x08, 0xde, 0x29, 0x25, 0xcb, + 0x6b, 0x3c, 0xf2, 0xc3, 0x75, 0x75, 0x31, 0x02, 0x12, 0xa8, 0x73, 0xc1, 0x64, 0x88, 0x86, 0xd8, + 0xa1, 0x1b, 0x62, 0x6b, 0xcd, 0xbf, 0xaf, 0xd9, 0x3a, 0xe2, 0x23, 0xfd, 0x22, 0x43, 0x48, 0xf5, + 0xbd, 0x48, 0x89, 0x42, 0x04, 0x94, 0x21, 0x67, 0x11, 0x1a, 0x75, 0x92, 0xa9, 0x6b, 0x55, 0x57, + 0x33, 0xa6, 0xa0, 0xd1, 0x01, 0xdd, 0xc5, 0xf2, 0xaf, 0x1f, 0xed, 0x52, 0x08, 0xfd, 0x5a, 0x12, + 0xe3, 0x37, 0x3e, 0x7a, 0x44, 0xdc, 0xb7, 0x3e, 0x79, 0x3a, 0x27, 0x7c, 0x13, 0xda, 0xa6, 0x5f, + 0x76, 0x7d, 0x7c, 0x10, 0x72, 0x62, 0xc6, 0x3a, 0xb5, 0x75, 0x8b, 0xc8, 0x27, 0x16, 0xdb, 0x4d, + 0xff, 0xcb, 0x77, 0x97, 0xf8, 0xfa, 0x53, 0xac, 0x5d, 0xa5, 0x5f, 0x13, 0x08, 0xdd, 0xf6, 0x37, + 0xb6, 0xf5, 0xf8, 0x2c, 0x1b, 0x7b, 0xa6, 0x16, 0x50, 0x27, 0xd1, 0xd3, 0x6f, 0x2f, 0x82, 0xa1, + 0xcf, 0x75, 0x6a, 0xbd, 0x24, 0xfb, 0xe1, 0x42, 0xe5, 0xfb, 0x58, 0x7a, 0x93, 0x35, 0x6a, 0x13, + 0x59, 0x7e, 0x0d, 0xb6, 0xeb, 0xe1, 0x4a, 0xc6, 0x83, 0x25, 0x3c, 0x51, 0x99, 0xcb, 0x12, 0x36, + 0x9d, 0x0e, 0x45, 0x22, 0x7f, 0x46, 0xb9, 0x9d, 0xf6, 0xfb, 0x7e, 0x82, 0x2f, 0xa1, 0xdf, 0x7a, + 0x97, 0xd5, 0xb3, 0xe1, 0x48, 0xd7, 0x3b, 0x4b, 0x6f, 0x2b, 0xb4, 0xa7, 0x19, 0x8a, 0xe8, 0x10, + 0x0b, 0x75, 0x79, 0x61, 0xcb, 0xe0, 0x94, 0xf9, 0x19, 0xf0, 0xa4, 0xa3, 0xe3, 0xc5, 0xda, 0xe4, + 0x23, 0xb4, 0x5f, 0x75, 0x2d, 0x24, 0xc2, 0xab, 0x53, 0x35, 0x9d, 0xab, 0x52, 0xaa, 0xa3, 0xda, + 0xb3, 0x3d, 0x52, 0x4b, 0xbc, 0x40, 0x53, 0x54, 0xef, 0x34, 0x1c, 0xaa, 0x1d, 0x4a, 0x65, 0xf2, + 0xe6, 0x15, 0x00, 0x83, 0x4d, 0xb5, 0xe0, 0x00, 0x7e, 0x5c, 0x44, 0x29, 0xcd, 0x56, 0xa5, 0xa8, + 0xb9, 0xb1, 0xd5, 0xb1, 0x70, 0xa5, 0x46, 0x1a, 0x27, 0xbe, 0x0a, 0x8a, 0x6c, 0x56, 0xd7, 0xc6, + 0x1e, 0x63, 0x77, 0x7a, 0xaf, 0x2f, 0x12, 0x32, 0x49, 0x40, 0x77, 0xbb, 0x23, 0x37, 0x48, 0xe8, + 0xfe, 0x2c, 0x43, 0x59, 0x6c, 0x93, 0xfc, 0x4e, 0xc1, 0xf8, 0xdd, 0x69, 0xab, 0x0a, 0x90, 0x9d, + 0x2d, 0x0b, 0x97, 0x70, 0x71, 0xa0, 0x80, 0xcb, 0xa1, 0x4c, 0x8c, 0x79, 0x22, 0xf7, 0x57, 0xf0, + 0x88, 0x43, 0x1b, 0xd1, 0xbb, 0x1b, 0xbb, 0xbe, 0x97, 0x8d, 0x33, 0xdf, 0x58, 0xcc, 0xd0, 0x52, + 0x62, 0x50, 0x43, 0x18, 0x8c, 0x41, 0x34, 0xb4, 0x7b, 0x70, 0x92, 0x43, 0xff, 0x34, 0x20, 0x8e, + 0xac, 0xf3, 0xe2, 0xf3, 0xff, 0xf1, 0xb4, 0x4d, 0x86, 0xec, 0x6b, 0xcb, 0x90, 0x4e, 0xf0, 0xa9, + 0x5d, 0xc3, 0x27, 0x08, 0x4b, 0x91, 0x54, 0xa8, 0xc6, 0x42, 0xf1, 0x4a, 0xad, 0xb8, 0xe0, 0xea, + 0x6d, 0xf9, 0x19, 0x7c, 0x68, 0x8c, 0x1f, 0xf2, 0x87, 0x31, 0x79, 0x4d, 0x44, 0x87, 0xda, 0x5d, + 0x86, 0xdb, 0xfc, 0x29, 0xbb, 0xf8, 0xcb, 0x6d, 0x83, 0x69, 0x96, 0x9c, 0xe0, 0x3a, 0xa9, 0xb5, + 0xa1, 0x8d, 0x34, 0xa1, 0x63, 0x9e, 0x77, 0xe3, 0x63, 0x8e, 0x5b, 0x14, 0x3a, 0x65, 0x88, 0xdb, + 0x45, 0x4d, 0x50, 0xfc, 0xa9, 0xf9, 0x57, 0x34, 0x92, 0x4b, 0xc6, 0xd4, 0xe9, 0x0a, 0xe3, 0x35, + 0x48, 0x5c, 0xb9, 0xe3, 0x63, 0xad, 0x34, 0x0d, 0x33, 0x14, 0x19, 0xba, 0xa4, 0x41, 0x0e, 0x6e, + 0x4f, 0xbc, 0xa0, 0xe2, 0xfe, 0xaf, 0xee, 0x61, 0x44, 0x41, 0x15, 0xe5, 0xf6, 0xea, 0x1e, 0x0a, + 0x32, 0x9e, 0x75, 0x57, 0x82, 0x3d, 0x9d, 0x99, 0xed, 0xb3, 0xc9, 0x0f, 0x0e, 0xdf, 0xe7, 0x1d, + 0x69, 0xb1, 0x03, 0xdb, 0x87, 0x1c, 0x7a, 0x33, 0x30, 0xaa, 0x92, 0xef, 0xc4, 0x3f, 0xf1, 0xbb, + 0xdc, 0x62, 0x73, 0x4b, 0x77, 0x4c, 0x12, 0xb7, 0x2e, 0x7b, 0x49, 0x59, 0x90, 0xf3, 0xc0, 0x77, + 0xaa, 0x22, 0x5b, 0xaa, 0x22, 0xc4, 0x9c, 0xfa, 0xdf, 0xff, 0x10, 0x20, 0x10, 0x16, 0x54, 0xf4, + 0x8e, 0x0a, 0x33, 0xa0, 0xd6, 0x6f, 0x34, 0x99, 0x88, 0x61, 0xfe, 0x26, 0x34, 0xdf, 0xc9, 0x6c, + 0x9e, 0xc2, 0x86, 0x2e, 0x0c, 0x04, 0x7c, 0x64, 0xc3, 0x52, 0x12, 0xa4, 0x46, 0x98, 0xc3, 0x8d, + 0x92, 0x34, 0xb5, 0x24, 0x6d, 0x72, 0x00, 0xd4, 0x90, 0x92, 0xbf, 0xc4, 0x09, 0x0a, 0x75, 0x08, + 0x59, 0x39, 0x76, 0x50, 0xf2, 0xa3, 0x6d, 0x02, 0xcc, 0x51, 0xa4, 0x1f, 0x34, 0x49, 0x8a, 0x03, + 0xb1, 0xd2, 0xcb, 0x3d, 0x28, 0xd4, 0xc9, 0x5f, 0xcb, 0x6b, 0x4e, 0x55, 0x89, 0x85, 0x25, 0x89, + 0x30, 0x05, 0x86, 0xb5, 0x5c, 0x05, 0x9f, 0x59, 0x74, 0xfb, 0xc5, 0x0f, 0x06, 0x78, 0xdc, 0x70, + 0x28, 0x10, 0x83, 0x51, 0xa8, 0xc4, 0xd1, 0xc8, 0xb1, 0x74, 0xc4, 0x50, 0xf7, 0xbb, 0xaa, 0x28, + 0xf3, 0x13, 0xc7, 0xd1, 0x69, 0x90, 0x73, 0x9e, 0x24, 0x76, 0x22, 0xee, 0x08, 0x6b, 0x7a, 0xa9, + 0x3f, 0xc5, 0x0e, 0xd2, 0x94, 0x66, 0x5e, 0x0a, 0x0f, 0xb9, 0x29, 0x8d, 0x64, 0xb7, 0x79, 0x32, + 0xc2, 0x11, 0xe6, 0xc4, 0x2a, 0x2f, 0x15, 0xcb, 0xd5, 0xe3, 0x14, 0x0d, 0x12, 0x26, 0x46, 0x22, + 0x36, 0x88, 0x76, 0x96, 0x5b, 0xa3, 0x69, 0xdb, 0x16, 0x6c, 0x85, 0xed, 0x9f, 0x64, 0x76, 0x0e, + 0xe4, 0xda, 0x3a, 0xf2, 0x06, 0xcc, 0x7f, 0x9a, 0xd3, 0xb5, 0xe0, 0x83, 0xaa, 0x8a, 0x33, 0xf3, + 0x3d, 0xce, 0x38, 0x48, 0x64, 0x36, 0xac, 0xf3, 0x08, 0x7e, 0x2a, 0xdb, 0xf0, 0xdf, 0x52, 0x6e, + 0x4b, 0xd6, 0xab, 0x71, 0xee, 0xfc, 0x9c, 0x69, 0xc2, 0x76, 0x0e, 0x93, 0xbf, 0x67, 0xda, 0x49, + 0x0e, 0xd5, 0xc7, 0x72, 0xe9, 0x05, 0xa8, 0xd1, 0x63, 0xa6, 0xd8, 0x37, 0x2f, 0xf8, 0x42, 0xdd, + 0xf7, 0x92, 0x75, 0x2b, 0xe0, 0xfc, 0xf7, 0x35, 0x49, 0x2f, 0x2f, 0x21, 0x64, 0xca, 0x42, 0x38, + 0x27, 0x11, 0xaa, 0xcd, 0xab, 0x2d, 0x5c, 0x57, 0x85, 0xeb, 0x95, 0x5f, 0x19, 0xb4, 0x7f, 0x3a, + 0xd4, 0xef, 0x52, 0x4a, 0xca, 0xaf, 0xe4, 0xd6, 0xdf, 0x82, 0xcb, 0x4a, 0x9d, 0x54, 0x53, 0xa7, + 0x7c, 0x1f, 0x0a, 0x66, 0xee, 0xef, 0x51, 0x3a, 0xa5, 0x67, 0xbd, 0xe4, 0xb3, 0x72, 0x64, 0xbe, + 0x0b, 0x8f, 0x1e, 0x37, 0xb6, 0xf3, 0xe7, 0xc2, 0x24, 0xb2, 0x6d, 0x6f, 0x79, 0xbf, 0xe0, 0xa6, + 0x4f, 0xb3, 0xe7, 0x6d, 0x8c, 0xef, 0x93, 0xaf, 0x7c, 0x5f, 0x8a, 0xeb, 0x5f, 0x13, 0xc7, 0x19, + 0xb7, 0x26, 0xf2, 0xba, 0x93, 0xe1, 0x49, 0x59, 0x7c, 0x4d, 0x73, 0xa8, 0x6a, 0xac, 0x85, 0xbb, + 0xa8, 0x58, 0x50, 0x63, 0x8e, 0xb9, 0x7c, 0x29, 0x78, 0x43, 0x42, 0x0f, 0xc8, 0x6a, 0x15, 0x6d, + 0x4a, 0x4f, 0xad, 0x1d, 0x42, 0x2e, 0x57, 0xca, 0x94, 0x0e, 0x50, 0x6d, 0xc9, 0x42, 0xa3, 0x39, + 0x9e, 0xb7, 0xaa, 0x6f, 0x6f, 0x98, 0xf8, 0x52, 0x3e, 0xe5, 0x4d, 0xd4, 0xf4, 0x9c, 0x57, 0x51, + 0xfa, 0xcc, 0x98, 0x41, 0x6e, 0x37, 0xc2, 0x57, 0xae, 0x77, 0xc5, 0x77, 0x78, 0xf1, 0x90, 0x41, + 0xde, 0xc8, 0xdd, 0x3f, 0x17, 0x65, 0x09, 0x45, 0x78, 0x33, 0x6b, 0x9b, 0x95, 0xf1, 0x85, 0x0f, + 0x29, 0x28, 0x50, 0x3b, 0x18, 0xb6, 0xa7, 0x50, 0x55, 0x2e, 0x4a, 0xfa, 0xc6, 0x65, 0x0f, 0x66, + 0x17, 0x10, 0x14, 0x31, 0x58, 0xb6, 0xe3, 0x7b, 0xb1, 0xd3, 0x67, 0x74, 0xcd, 0x19, 0x0d, 0xb0, + 0x3d, 0x76, 0x4c, 0x80, 0x99, 0xf9, 0x1f, 0x54, 0x23, 0xc4, 0x0c, 0x20, 0x55, 0xf4, 0x0a, 0x09, + 0x31, 0x83, 0x6e, 0xef, 0xe4, 0xba, 0x32, 0xb7, 0x37, 0x0c, 0x60, 0xd3, 0x36, 0xf3, 0x5e, 0x94, + 0x2f, 0xd5, 0x20, 0xb7, 0x86, 0x53, 0xc9, 0x43, 0x37, 0x97, 0xf1, 0xb1, 0x2d, 0xff, 0xfd, 0xfb, + 0x91, 0x79, 0xe0, 0xdc, 0x30, 0xef, 0x04, 0x21, 0x3b, 0x0a, 0x1d, 0x2a, 0x54, 0xf5, 0xa7, 0x7f, + 0x0d, 0x76, 0x9a, 0x53, 0x65, 0x09, 0x0d, 0x0b, 0x34, 0x1b, 0x99, 0x7b, 0x6e, 0xcf, 0x1a, 0x53, + 0xaf, 0x79, 0x9d, 0x09, 0x58, 0x23, 0x09, 0xb4, 0xa5, 0x41, 0xd1, 0xb9, 0x86, 0xb2, 0xcd, 0xc7, + 0x73, 0x41, 0xc3, 0x2a, 0x76, 0x89, 0xff, 0xc2, 0x98, 0x55, 0x8f, 0x38, 0x29, 0x36, 0xea, 0x9c, + 0x85, 0x6d, 0x85, 0x4d, 0xad, 0x86, 0xc3, 0xba, 0x8d, 0x91, 0x0a, 0x51, 0xd7, 0x8d, 0xa6, 0x63, + 0xb9, 0x0d, 0x78, 0x16, 0xa9, 0x11, 0x6a, 0xa9, 0xa9, 0xca, 0x1b, 0x2f, 0xaa, 0xd5, 0xf7, 0x48, + 0x3e, 0x9c, 0x26, 0x9b, 0xf6, 0x77, 0xfe, 0x7e, 0x34, 0xd8, 0x2a, 0xff, 0x7c, 0x73, 0x93, 0x77, + 0xb7, 0x91, 0x5b, 0xcd, 0x71, 0x5b, 0xe6, 0xcc, 0x1d, 0xbf, 0x44, 0x95, 0x36, 0x68, 0xab, 0x18, + 0x44, 0xdf, 0xf8, 0xdf, 0x24, 0x72, 0x47, 0xe2, 0x1f, 0x5b, 0x30, 0x77, 0xca, 0x9a, 0x3d, 0xf2, + 0xd0, 0xf7, 0x6a, 0x7c, 0x66, 0xdf, 0xd6, 0x78, 0x34, 0x7c, 0x48, 0x2f, 0x3d, 0xaa, 0x5a, 0x63, + 0xc6, 0x21, 0xfc, 0x44, 0x3b, 0x0f, 0x8e, 0xe6, 0xd8, 0x2a, 0x2d, 0x07, 0x40, 0xa2, 0x25, 0x30, + 0xc9, 0x14, 0x65, 0xe3, 0xdd, 0xec, 0xee, 0xd7, 0x68, 0x98, 0x47, 0xa5, 0xe8, 0xa8, 0xff, 0x11, + 0x11, 0xf7, 0x57, 0x0f, 0xc9, 0x43, 0x9d, 0x2f, 0xe1, 0x08, 0x50, 0xe8, 0x3a, 0x44, 0xf8, 0xee, + 0x22, 0x11, 0xa9, 0x1a, 0xdd, 0xef, 0xfa, 0xda, 0xc0, 0xc2, 0x75, 0x5a, 0x8f, 0x9a, 0x36, 0xfb, + 0xfc, 0x65, 0x8c, 0xd0, 0x40, 0x35, 0x4d, 0xc4, 0xcf, 0xe6, 0xa7, 0x1b, 0xf5, 0xf7, 0xf1, 0xd4, + 0x99, 0x8d, 0x0e, 0xfb, 0xb2, 0x87, 0x93, 0xed, 0xf6, 0xf8, 0x98, 0x7a, 0x30, 0xae, 0x31, 0xab, + 0x52, 0xd3, 0xa1, 0x2e, 0xee, 0xab, 0x9c, 0xcf, 0xb4, 0x8f, 0xa7, 0xdf, 0xc6, 0xf4, 0xb4, 0x8a, + 0xb9, 0xe9, 0x28, 0x92, 0x58, 0x43, 0x4d, 0xbd, 0x53, 0x57, 0x5a, 0x20, 0xb4, 0xeb, 0x49, 0x7f, + 0xb7, 0x24, 0x34, 0xf1, 0xdb, 0x36, 0x33, 0x58, 0x8b, 0xf8, 0x88, 0x50, 0x47, 0x60, 0x81, 0x9f, + 0x47, 0x3d, 0x7e, 0xb0, 0xd0, 0xf1, 0x15, 0xe4, 0xfe, 0x18, 0xce, 0x05, 0x0f, 0xf7, 0x8e, 0x38, + 0x40, 0x12, 0x3d, 0x58, 0x71, 0xda, 0x79, 0x8b, 0x98, 0xeb, 0x46, 0x05, 0x87, 0x9d, 0xf8, 0x53, + 0xea, 0x0f, 0x2a, 0x31, 0x05, 0xab, 0xc9, 0xb4, 0xcb, 0xae, 0x3f, 0x08, 0x4d, 0xb8, 0xc9, 0x91, + 0x7d, 0x09, 0xaa, 0xe6, 0xee, 0xc7, 0xe1, 0x43, 0x36, 0x7a, 0xc6, 0xea, 0x73, 0x2d, 0x01, 0xbd, + 0x74, 0x2a, 0xd4, 0xe6, 0x9b, 0xd9, 0xc7, 0x0f, 0x51, 0xc1, 0xf1, 0xb0, 0x87, 0xee, 0x8d, 0x8f, + 0xf4, 0xe9, 0x81, 0x0f, 0xfe, 0xb6, 0xf6, 0x83, 0x1d, 0x83, 0x2f, 0xd4, 0xa7, 0x5e, 0xc2, 0xe6, + 0x50, 0x56, 0x89, 0x68, 0x8a, 0x61, 0x01, 0xf3, 0x72, 0x9c, 0xf9, 0x8c, 0xdc, 0x11, 0xc7, 0x92, + 0xb6, 0xcd, 0xf9, 0x9b, 0xa7, 0x33, 0xfc, 0x13, 0xe9, 0xaf, 0x27, 0xf5, 0x70, 0x53, 0x8d, 0x53, + 0x5a, 0x57, 0x27, 0x8e, 0xba, 0xae, 0xce, 0x95, 0xb4, 0xbc, 0x11, 0x12, 0x2b, 0x63, 0x78, 0xbe, + 0x32, 0x27, 0xd6, 0x93, 0x1b, 0xbd, 0xed, 0xb3, 0x54, 0x9f, 0xf0, 0xa5, 0x1a, 0x6f, 0x3e, 0x1f, + 0xb7, 0xdd, 0x9b, 0x9f, 0x1e, 0xdd, 0xfe, 0x14, 0x26, 0xac, 0x94, 0xbe, 0xea, 0x3b, 0x8d, 0x49, + 0xae, 0x75, 0xef, 0x84, 0x46, 0xcd, 0xe5, 0x52, 0xd3, 0x5b, 0x5a, 0x19, 0xbf, 0x82, 0x52, 0x71, + 0x7b, 0xe6, 0xf9, 0xfe, 0x14, 0x11, 0x1a, 0x63, 0xa5, 0xbe, 0x27, 0xad, 0x39, 0x68, 0xbb, 0xa5, + 0xb5, 0x7f, 0x85, 0x0a, 0x61, 0xa3, 0xfb, 0x76, 0x4d, 0x7e, 0x8f, 0xa5, 0x8a, 0xf5, 0x38, 0x6a, + 0x44, 0x64, 0xd1, 0x57, 0xc2, 0x69, 0x86, 0x56, 0x28, 0xd9, 0xae, 0xc2, 0x4a, 0xe9, 0xc2, 0xe2, + 0x63, 0x08, 0xb3, 0x32, 0x8e, 0xa8, 0x7f, 0xa6, 0xc4, 0x89, 0x7d, 0x49, 0x5f, 0x93, 0x35, 0x9e, + 0xf1, 0x18, 0x40, 0xd6, 0xa4, 0x90, 0xda, 0x78, 0xd2, 0x43, 0x1d, 0xa0, 0xbf, 0x85, 0x0b, 0xf4, + 0xd6, 0x4b, 0x45, 0xf8, 0x76, 0x36, 0x87, 0x12, 0x77, 0xe0, 0x37, 0x80, 0xe9, 0x34, 0xd3, 0x0f, + 0x68, 0x55, 0xa6, 0x9f, 0x85, 0x0a, 0xb4, 0x4b, 0xc6, 0x20, 0x8b, 0x4b, 0x95, 0x2f, 0x48, 0x34, + 0x72, 0x46, 0x14, 0xd5, 0x5b, 0xc4, 0x15, 0xed, 0x4e, 0x41, 0xf6, 0xa3, 0x8f, 0x0a, 0x15, 0xac, + 0xb5, 0x52, 0x54, 0x2c, 0xa3, 0x2f, 0x1a, 0x52, 0x7a, 0xd1, 0xa1, 0x2e, 0x51, 0x18, 0x72, 0xc4, + 0x4d, 0xb8, 0x0d, 0x47, 0xb8, 0xff, 0x19, 0x64, 0xaa, 0xa6, 0xe4, 0xce, 0x59, 0x50, 0xe3, 0xa5, + 0x1e, 0x12, 0x8e, 0x45, 0x69, 0x82, 0x77, 0x26, 0xc5, 0xa4, 0x26, 0xcf, 0x5a, 0xf1, 0xb4, 0xa9, + 0xc4, 0xa6, 0xf2, 0x6f, 0xc5, 0x6f, 0xc6, 0x0b, 0x3c, 0x82, 0x7b, 0x8a, 0x08, 0xb4, 0x1e, 0xb7, + 0x6e, 0xd6, 0xda, 0x59, 0x52, 0x84, 0xbe, 0x91, 0x35, 0xaa, 0xbc, 0x28, 0x49, 0xa7, 0x6c, 0x99, + 0x6d, 0x62, 0xdd, 0x6b, 0x0d, 0x07, 0x75, 0xb8, 0xd3, 0x6d, 0xca, 0x6f, 0xcd, 0x29, 0xf1, 0xa5, + 0x2d, 0x25, 0x06, 0xe4, 0x4e, 0xe7, 0x1a, 0x61, 0xa5, 0x51, 0x2a, 0xef, 0x64, 0xc7, 0xfb, 0x1e, + 0x91, 0xac, 0x9d, 0xf0, 0x39, 0x58, 0xa9, 0xc2, 0x48, 0xc1, 0x8d, 0x87, 0xe9, 0x77, 0x3f, 0xe0, + 0xae, 0xdc, 0x6b, 0x38, 0xea, 0x55, 0x7a, 0xb8, 0x36, 0x34, 0x47, 0x61, 0xfb, 0xfc, 0x28, 0x55, + 0xa1, 0x99, 0xad, 0x0e, 0x2e, 0xce, 0x87, 0x46, 0x9a, 0x4c, 0x76, 0x69, 0x35, 0x07, 0xef, 0x8c, + 0x14, 0x3f, 0x86, 0xec, 0x05, 0x65, 0x8c, 0xe6, 0x02, 0xbd, 0x8c, 0xcc, 0x0e, 0x66, 0xe4, 0x30, + 0x6d, 0x58, 0xe3, 0x77, 0x87, 0xcb, 0x4b, 0x49, 0x45, 0xd3, 0x94, 0xf7, 0x48, 0xf5, 0xe2, 0xbf, + 0xf8, 0x40, 0x89, 0x22, 0x10, 0xf7, 0xf7, 0xbb, 0x9d, 0x9a, 0xd8, 0x46, 0x5e, 0x0a, 0x65, 0x6f, + 0x77, 0x68, 0x63, 0x1e, 0x36, 0xcf, 0x85, 0xff, 0x70, 0x84, 0x29, 0x89, 0xfe, 0xdb, 0x98, 0x2a, + 0xb6, 0x59, 0xd5, 0xdd, 0x2d, 0x32, 0xd3, 0x61, 0xb3, 0x6c, 0x56, 0xee, 0xdd, 0x48, 0x69, 0xa6, + 0xf8, 0x2a, 0xb3, 0xb1, 0x4c, 0xc1, 0xc7, 0xb1, 0x39, 0xb7, 0x33, 0x0f, 0xdf, 0x0e, 0x1f, 0x52, + 0x98, 0x95, 0x35, 0x49, 0x2f, 0xf0, 0xfe, 0x21, 0xa5, 0xd2, 0x44, 0x16, 0x6f, 0x13, 0xe3, 0x58, + 0x73, 0xfa, 0xe2, 0x13, 0x22, 0x1d, 0xff, 0x04, 0x17, 0x63, 0x77, 0xcc, 0x3d, 0x4c, 0xd8, 0xe6, + 0xa2, 0x19, 0x8b, 0xf6, 0x4d, 0x89, 0xc3, 0xc6, 0x91, 0x08, 0x6e, 0xca, 0x14, 0x0d, 0x51, 0x9b, + 0xf3, 0x8f, 0xca, 0x51, 0xcc, 0x37, 0x1c, 0x72, 0xe3, 0xee, 0xbc, 0xac, 0x71, 0x5f, 0xd7, 0x6f, + 0x82, 0x63, 0xaa, 0x9a, 0x12, 0x84, 0xa1, 0xaa, 0x26, 0x72, 0x51, 0xdc, 0x12, 0x19, 0x55, 0x45, + 0xdb, 0xe1, 0x3b, 0xbe, 0xef, 0xf8, 0x21, 0x97, 0x77, 0x36, 0x77, 0xc1, 0x66, 0xee, 0xf7, 0x88, + 0x7b, 0xdf, 0xf5, 0xf7, 0x3f, 0x9e, 0xff, 0x8f, 0x16, 0xef, 0x77, 0x7b, 0xdd, 0xf8, 0x98, 0xf3, + 0x39, 0x31, 0xee, 0xd3, 0x03, 0x36, 0x49, 0x97, 0xf0, 0x5a, 0x4b, 0xbb, 0xb7, 0x15, 0x97, 0x2b, + 0x89, 0x12, 0x0a, 0xb7, 0x8a, 0xde, 0xd9, 0x7b, 0xed, 0x99, 0x8c, 0xbe, 0x10, 0xa6, 0xec, 0xfa, + 0xef, 0x77, 0x7f, 0x04, 0xa2, 0x47, 0x6c, 0xf5, 0xc4, 0x68, 0x41, 0x4e, 0xbe, 0x14, 0x11, 0x13, + 0xce, 0xa4, 0x7f, 0xd9, 0x3e, 0xa8, 0xed, 0xbb, 0x6b, 0x29, 0x06, 0xc6, 0x54, 0xe4, 0x61, 0x7c, + 0x29, 0x1e, 0xe7, 0x6a, 0xbe, 0x6b, 0x72, 0x8d, 0x83, 0x77, 0xcf, 0xbf, 0x94, 0xc4, 0x96, 0xdf, + 0x4e, 0x04, 0x41, 0x8f, 0x85, 0x31, 0x37, 0x5e, 0xc3, 0xa5, 0x8d, 0x64, 0x89, 0x66, 0xd5, 0xfd, + 0x8a, 0xf1, 0xc5, 0x75, 0x9b, 0xfa, 0x99, 0xf9, 0xc1, 0xe4, 0x9f, 0x0a, 0x4b, 0xc5, 0xd4, 0x3a, + 0xa0, 0x52, 0x0c, 0x14, 0x9e, 0x41, 0xc3, 0x28, 0x81, 0xf9, 0xb6, 0x54, 0x6d, 0xdc, 0x6f, 0x6d, + 0x7f, 0xc3, 0x30, 0x94, 0x95, 0x19, 0x78, 0xca, 0xf0, 0x3c, 0x77, 0x4a, 0xfd, 0x58, 0x72, 0xb5, + 0xb7, 0x4c, 0x85, 0x23, 0xa2, 0xf6, 0xa5, 0x51, 0x22, 0x53, 0x6c, 0x73, 0xc4, 0x8c, 0xb6, 0xc3, + 0x5c, 0xc9, 0x43, 0xc7, 0x76, 0xc5, 0xd4, 0xc4, 0x08, 0x0a, 0xa2, 0x11, 0x9a, 0x89, 0xf8, 0x61, + 0x3b, 0x91, 0x51, 0x28, 0x6b, 0x45, 0xe1, 0x4a, 0xb4, 0xf4, 0x4c, 0x38, 0x71, 0x45, 0xc9, 0x32, + 0xb1, 0x8a, 0xea, 0x6f, 0xd3, 0x3a, 0x1c, 0xf0, 0x0b, 0xb5, 0xdf, 0x17, 0xe6, 0xce, 0x8c, 0x6b, + 0x4a, 0x75, 0x7d, 0xf0, 0xa4, 0xbd, 0x98, 0xc4, 0xea, 0x6b, 0x2d, 0x2d, 0xa6, 0xe9, 0xdc, 0xdd, + 0xd0, 0xd4, 0x48, 0xc7, 0xba, 0x40, 0xd8, 0xea, 0x2f, 0xd6, 0x57, 0xd8, 0xf7, 0x6f, 0x45, 0x47, + 0x03, 0x9f, 0x05, 0x93, 0x36, 0x37, 0xea, 0x9c, 0x28, 0x3c, 0x4c, 0xd4, 0x9b, 0x3d, 0xd1, 0x4f, + 0xc1, 0x05, 0xa3, 0x71, 0xae, 0x81, 0x0c, 0xd2, 0x83, 0x58, 0x99, 0x7d, 0x28, 0x33, 0x0c, 0x6a, + 0xa7, 0xce, 0xc5, 0x58, 0x8e, 0x1a, 0x19, 0x62, 0xbf, 0x8d, 0x9a, 0x36, 0xa6, 0xb1, 0xfa, 0x69, + 0xac, 0xcd, 0x5e, 0xf8, 0x17, 0xdb, 0x65, 0x9e, 0x65, 0xa6, 0x3a, 0x2d, 0x8d, 0x90, 0xf6, 0x0f, + 0x3b, 0x15, 0xdb, 0x48, 0xfe, 0x7d, 0xfb, 0x38, 0xf6, 0xdf, 0xbe, 0x30, 0x46, 0xd9, 0xfe, 0x08, + 0x5b, 0xed, 0x6c, 0x74, 0xcc, 0xd5, 0xfd, 0xf0, 0x98, 0xe3, 0xf4, 0xc3, 0x8a, 0xa8, 0x3a, 0xfa, + 0xa4, 0xc1, 0x2b, 0x4c, 0x4c, 0x4c, 0xf7, 0xf7, 0xba, 0x9a, 0x3f, 0xf8, 0xda, 0x70, 0x66, 0xbd, + 0x66, 0x3e, 0xc9, 0xa6, 0x55, 0x0b, 0x2f, 0x02, 0x25, 0xbd, 0xe7, 0x46, 0x38, 0x2f, 0xd1, 0xc9, + 0x8b, 0x31, 0xbf, 0x44, 0xc2, 0xec, 0xbf, 0x3b, 0x75, 0xc2, 0x94, 0x8e, 0x78, 0x29, 0x6f, 0xc3, + 0x62, 0x78, 0xa3, 0xf7, 0x80, 0x1b, 0xf8, 0x4a, 0xa3, 0x6f, 0xc1, 0x19, 0x2a, 0x39, 0xf5, 0x39, + 0xb5, 0xf1, 0x92, 0x2e, 0xd2, 0x1b, 0x47, 0x80, 0x76, 0x97, 0x8e, 0xd9, 0x33, 0x0a, 0xcc, 0x45, + 0xaa, 0xa4, 0x1e, 0x20, 0x40, 0x50, 0xd9, 0x37, 0xc3, 0x6e, 0x15, 0x2c, 0x5c, 0xc1, 0x54, 0x95, + 0xb8, 0x3f, 0xda, 0xd6, 0x64, 0x01, 0x23, 0x37, 0xc1, 0x9f, 0xad, 0x39, 0xd5, 0x33, 0x4d, 0x93, + 0x87, 0x8f, 0xb2, 0x9f, 0xc2, 0xbd, 0xf0, 0xa5, 0x55, 0xd8, 0x9c, 0xa7, 0x7d, 0xcb, 0xba, 0xc1, + 0x50, 0xef, 0x25, 0x4c, 0x4b, 0x8d, 0x4b, 0x3e, 0x30, 0xa6, 0xa2, 0x71, 0x93, 0x09, 0xaa, 0x62, + 0x7b, 0xbb, 0x67, 0x56, 0x95, 0x2f, 0x13, 0xe3, 0xcc, 0xd6, 0xad, 0x8c, 0x88, 0xde, 0xcf, 0x87, + 0xb8, 0xad, 0xdd, 0x4d, 0xd7, 0x9f, 0x9e, 0x3d, 0xef, 0x06, 0x0a, 0xb0, 0xff, 0xf8, 0x52, 0x33, + 0x4d, 0xe3, 0x24, 0x53, 0x2c, 0x60, 0x39, 0x4f, 0x7c, 0x8c, 0xd1, 0xa9, 0x97, 0xeb, 0xc6, 0xe9, + 0xe5, 0xf0, 0x59, 0x56, 0xc6, 0x39, 0x39, 0x56, 0x9b, 0x96, 0xcc, 0x92, 0xc9, 0x00, 0xf4, 0x5c, + 0x8a, 0xd7, 0xbe, 0x09, 0x8a, 0xa2, 0xe7, 0xca, 0xaa, 0xf6, 0x8e, 0xe4, 0x11, 0x17, 0xfc, 0x49, + 0x16, 0xba, 0xd5, 0xf0, 0x91, 0x55, 0x77, 0xbd, 0x62, 0x08, 0x26, 0xf7, 0xf0, 0x5c, 0x32, 0x9b, + 0xdd, 0xbe, 0xab, 0xb9, 0xfa, 0x6d, 0xfc, 0xa3, 0x6f, 0x75, 0xc1, 0x28, 0xc6, 0xef, 0x77, 0xd8, + 0x78, 0x25, 0x3a, 0x2a, 0xef, 0x8d, 0xdc, 0x7e, 0x0f, 0x82, 0xe2, 0xde, 0xfb, 0xbe, 0x1f, 0x88, + 0x09, 0x18, 0x8c, 0x69, 0x06, 0x78, 0xed, 0x55, 0x7c, 0x28, 0x49, 0xf6, 0xdb, 0x5f, 0xb4, 0x3a, + 0x4e, 0x0d, 0x1f, 0x8f, 0xdc, 0x10, 0x04, 0x9c, 0xbc, 0xba, 0xcb, 0xe1, 0x49, 0x6f, 0x47, 0x8f, + 0x88, 0xe3, 0xfa, 0xac, 0x33, 0x70, 0xc1, 0x39, 0xb8, 0xe2, 0x47, 0x0a, 0xef, 0x5b, 0xe3, 0x2d, + 0xf1, 0x22, 0x6c, 0xb9, 0x3a, 0xb9, 0xd6, 0xbe, 0x26, 0xed, 0xd3, 0xa3, 0x52, 0x7f, 0x05, 0x64, + 0xbd, 0x7a, 0xa7, 0x66, 0xe2, 0xed, 0xf1, 0xd7, 0xaf, 0xaa, 0xac, 0x4f, 0x0d, 0x9e, 0x5d, 0x56, + 0xf1, 0x00, 0xa7, 0x33, 0x31, 0x99, 0xab, 0x1e, 0x6b, 0xef, 0x82, 0x5f, 0x77, 0xa6, 0xdd, 0xfc, + 0x40, 0xd2, 0x0e, 0xbf, 0x83, 0xbf, 0x5b, 0xd3, 0x63, 0x6d, 0x45, 0x75, 0xb9, 0x6b, 0x17, 0xea, + 0xf5, 0xf0, 0x4d, 0x6b, 0x15, 0x47, 0x1a, 0x3a, 0x3a, 0x3a, 0xd5, 0x6c, 0x7c, 0x76, 0x94, 0xe9, + 0x5a, 0xd3, 0x6f, 0xe8, 0xa6, 0x04, 0xdc, 0xb2, 0x3a, 0x73, 0x16, 0xfc, 0x4e, 0xb5, 0xe0, 0x8f, + 0x7d, 0xbc, 0x57, 0x1f, 0xaa, 0xea, 0x62, 0xb5, 0xf5, 0x25, 0x1f, 0xc1, 0x3d, 0x6b, 0x54, 0xd5, + 0x3e, 0xae, 0x4a, 0x7b, 0xfa, 0x35, 0x7d, 0x89, 0x6e, 0xf5, 0xd9, 0x96, 0xaa, 0xb9, 0x45, 0xde, + 0xfe, 0x4d, 0xdd, 0xc9, 0xc1, 0x2c, 0x5e, 0xdb, 0x75, 0x55, 0xd2, 0xaf, 0x5a, 0xe2, 0x62, 0xe9, + 0xba, 0xf2, 0x7f, 0x82, 0x92, 0x3e, 0x8d, 0xa3, 0x76, 0xfc, 0x9e, 0x30, 0xfc, 0xf5, 0xef, 0x84, + 0xca, 0x0a, 0x3e, 0x2f, 0xe2, 0xf5, 0xc7, 0x5b, 0x8a, 0x9e, 0xe8, 0xd2, 0xa5, 0xf1, 0x42, 0x12, + 0x46, 0xce, 0x9d, 0x7e, 0x2e, 0x4c, 0xfc, 0x94, 0xf1, 0x44, 0xe6, 0xc5, 0xd5, 0x7c, 0x59, 0xea, + 0x9d, 0x6b, 0xf5, 0xef, 0x82, 0x7c, 0xde, 0x0e, 0xde, 0x34, 0xbd, 0x9f, 0x04, 0xb5, 0xcb, 0xbb, + 0xec, 0xf8, 0x82, 0x4b, 0xd6, 0x6f, 0x2b, 0x1f, 0x0a, 0x94, 0x3e, 0x4a, 0xcc, 0xf3, 0x79, 0x90, + 0x65, 0xf6, 0xc5, 0xff, 0x05, 0x36, 0x38, 0x82, 0x02, 0xea, 0x66, 0x45, 0x45, 0xb8, 0xdd, 0x23, + 0x84, 0xfa, 0xf5, 0x71, 0x44, 0xe5, 0x87, 0x3c, 0x3d, 0xee, 0xc8, 0x6e, 0x8b, 0xba, 0x77, 0xae, + 0xef, 0xf7, 0x5c, 0x4c, 0xa6, 0x69, 0x4e, 0xda, 0x28, 0x43, 0x84, 0x8e, 0xab, 0xea, 0xa5, 0xe6, + 0x22, 0x75, 0xae, 0xc5, 0xbd, 0xfe, 0x6d, 0xef, 0xc4, 0x49, 0xc4, 0x69, 0x55, 0x3a, 0x4b, 0xe2, + 0xf6, 0xad, 0xae, 0x4f, 0xe6, 0xb7, 0x7a, 0xe4, 0xaa, 0xef, 0xac, 0xbe, 0x09, 0x46, 0x55, 0x69, + 0x0f, 0x20, 0xec, 0x7d, 0xe6, 0xbf, 0x19, 0xe7, 0xd5, 0xd5, 0x8d, 0x2f, 0x72, 0x84, 0x0f, 0x5c, + 0xb6, 0xab, 0x3f, 0x14, 0x59, 0xf7, 0xe2, 0xfe, 0x4e, 0x86, 0xab, 0xb3, 0x5a, 0xb5, 0xe5, 0x2a, + 0x48, 0xdf, 0xe2, 0x6e, 0x33, 0xc8, 0x1c, 0x3a, 0x74, 0xbc, 0x7d, 0x86, 0x13, 0x3f, 0x6c, 0xdd, + 0x3d, 0x69, 0x04, 0x39, 0x2b, 0x5a, 0xc4, 0x7d, 0xdd, 0xf3, 0x74, 0x7a, 0xf9, 0xaf, 0xbb, 0xe8, + 0xad, 0xf2, 0x6c, 0xd6, 0xa2, 0x04, 0x02, 0x3b, 0xeb, 0xea, 0xe5, 0xc9, 0x9a, 0xeb, 0xd5, 0xc1, + 0x51, 0x13, 0x6f, 0x69, 0xfc, 0xd6, 0xee, 0x7d, 0x88, 0xdd, 0xfc, 0x13, 0x49, 0xb2, 0x3e, 0x56, + 0x19, 0xf1, 0x7d, 0xc6, 0x2a, 0xf5, 0x7c, 0x21, 0xe6, 0xc2, 0x64, 0x5f, 0x24, 0x89, 0xc5, 0x15, + 0x76, 0xb9, 0x97, 0x5c, 0x24, 0x6b, 0xdd, 0xdd, 0xfe, 0x6a, 0xeb, 0xe4, 0xbe, 0xfe, 0x63, 0xbb, + 0xfe, 0x33, 0x49, 0xe9, 0xa6, 0xe9, 0xc8, 0x44, 0x67, 0xa3, 0xe2, 0xb7, 0xf0, 0x9c, 0xf2, 0xcf, + 0x1b, 0x5c, 0x21, 0x88, 0xf1, 0x37, 0xc8, 0x5b, 0xdf, 0xcc, 0x23, 0x77, 0xf3, 0x55, 0x7f, 0x65, + 0xc9, 0xfe, 0x3c, 0xbb, 0xbc, 0x57, 0x7b, 0xdd, 0x71, 0xc6, 0xab, 0x7a, 0xd5, 0x57, 0x27, 0x21, + 0xd5, 0x5b, 0x5f, 0x17, 0x59, 0xa8, 0x9b, 0x3b, 0x35, 0xf2, 0xea, 0xef, 0xe4, 0xad, 0x7e, 0x11, + 0x2e, 0x92, 0xec, 0xd7, 0x26, 0x2a, 0xea, 0xdf, 0x05, 0xc4, 0xd5, 0x57, 0x76, 0x7c, 0x50, 0x8b, + 0xaa, 0x72, 0x7f, 0xcb, 0xa6, 0xb7, 0xca, 0x7d, 0x57, 0xc6, 0x5d, 0x7a, 0x49, 0x8c, 0xc4, 0x55, + 0x26, 0x75, 0xa9, 0x8f, 0xec, 0xd4, 0xf4, 0xc9, 0xc4, 0x5e, 0xda, 0x78, 0xaf, 0xe2, 0x8b, 0xc9, + 0xea, 0x6c, 0x9f, 0x04, 0x54, 0x89, 0x9f, 0x7c, 0x64, 0xb8, 0xe5, 0x96, 0xf7, 0x69, 0xba, 0x54, + 0xde, 0xbe, 0x10, 0xbb, 0xb7, 0x79, 0x73, 0x9b, 0x4d, 0x9e, 0x0b, 0x2f, 0xb1, 0xaf, 0x74, 0xdb, + 0xdf, 0xe3, 0xae, 0xa6, 0x9f, 0x49, 0x7c, 0xb4, 0x6a, 0xc2, 0x7c, 0x45, 0xee, 0xf5, 0x55, 0xf2, + 0x9d, 0x75, 0xf2, 0x8a, 0xaa, 0xaa, 0xe5, 0xd6, 0xab, 0x93, 0xc5, 0x6f, 0x8b, 0x1e, 0xed, 0xdd, + 0x56, 0xbc, 0x20, 0x5f, 0x36, 0x3e, 0x11, 0x11, 0x33, 0x06, 0xfa, 0xe6, 0xc5, 0xca, 0xf8, 0xed, + 0x52, 0x49, 0x52, 0xf6, 0x97, 0xc2, 0x67, 0xda, 0x5d, 0xdf, 0xcb, 0x55, 0xfc, 0x9a, 0xaf, 0x13, + 0xf8, 0x48, 0x51, 0x33, 0xd6, 0xbe, 0x32, 0xd0, 0xf2, 0x06, 0xb9, 0xd3, 0x97, 0x5a, 0xc9, 0x93, + 0xfa, 0x3b, 0xa6, 0xe6, 0x10, 0xaf, 0xf8, 0xb2, 0xb7, 0x7f, 0x3f, 0x5c, 0x15, 0x90, 0xb5, 0xe9, + 0x6d, 0x1f, 0x7a, 0xf5, 0x70, 0x96, 0xb1, 0x34, 0x93, 0x7f, 0xdf, 0x3e, 0x6b, 0x88, 0xee, 0x6e, + 0xba, 0x38, 0x4b, 0x94, 0xeb, 0x17, 0x5f, 0x26, 0x6e, 0xff, 0x96, 0xab, 0x93, 0x9b, 0xaa, 0xae, + 0xc4, 0x3d, 0xea, 0x27, 0x5d, 0x8b, 0x55, 0xd7, 0x7d, 0x55, 0x73, 0x15, 0x56, 0xfe, 0x59, 0x33, + 0xf0, 0x8f, 0xc4, 0xdf, 0x09, 0x9a, 0xd2, 0xf2, 0xe7, 0xcd, 0x97, 0x31, 0x7c, 0x26, 0x62, 0x47, + 0x66, 0xf4, 0xe1, 0x4e, 0x24, 0xaa, 0xba, 0xd6, 0x5e, 0x4c, 0x5f, 0x2f, 0x30, 0x95, 0xad, 0xf4, + 0x67, 0xf8, 0x26, 0x2d, 0x53, 0xd6, 0xbd, 0x08, 0x72, 0x0a, 0x6c, 0x99, 0xbe, 0x23, 0x77, 0x6c, + 0xf8, 0xbc, 0x39, 0xc9, 0x5a, 0xd0, 0xb4, 0x3c, 0x35, 0x3d, 0x9c, 0xd2, 0xe2, 0x6b, 0x9b, 0xcb, + 0x62, 0xf9, 0x82, 0x0e, 0xff, 0x82, 0x22, 0xe2, 0xbd, 0xe1, 0xae, 0x43, 0xaa, 0xe0, 0x43, 0xe5, + 0xd8, 0xdb, 0x63, 0x17, 0xc9, 0x6f, 0x50, 0x5f, 0xc2, 0x74, 0x4c, 0xad, 0x35, 0x69, 0x30, 0x8f, + 0x09, 0xd3, 0x63, 0xb1, 0xdb, 0xb6, 0x13, 0xe1, 0x19, 0x64, 0xcb, 0x4c, 0x66, 0xb4, 0x1f, 0xd1, + 0x17, 0x41, 0xaf, 0x11, 0x4a, 0x3b, 0x9f, 0x7b, 0x9b, 0x8c, 0xee, 0xf1, 0xbc, 0xad, 0x91, 0x19, + 0xe8, 0x76, 0x49, 0xb1, 0x82, 0xd8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x3f, 0x1f, 0xb0, 0x5a, + 0xf3, 0x19, 0x6b, 0x5c, 0x11, 0xde, 0xf7, 0xae, 0x4a, 0xea, 0xba, 0x1a, 0xf0, 0x9f, 0x42, 0x72, + 0xfa, 0xf5, 0xf4, 0x67, 0x86, 0x30, 0x20, 0xa0, 0x88, 0xc2, 0x95, 0xc8, 0x1a, 0xba, 0x7f, 0x77, + 0xbd, 0xf1, 0x3a, 0x74, 0xde, 0xff, 0x67, 0x3b, 0x76, 0xdf, 0x28, 0xaa, 0x6b, 0xf2, 0x9e, 0xa2, + 0xff, 0x66, 0x3c, 0x3a, 0xe5, 0x95, 0x84, 0xc2, 0x8d, 0x1c, 0xc7, 0x88, 0x12, 0xb8, 0xc4, 0x62, + 0xaf, 0x15, 0xd0, 0xb7, 0xbe, 0xaf, 0xf4, 0x4e, 0xfa, 0xb4, 0x29, 0xd0, 0xbe, 0xfa, 0xf5, 0xf5, + 0x72, 0x4e, 0x82, 0x95, 0xf0, 0x81, 0xd2, 0xae, 0x59, 0x54, 0x95, 0x1c, 0x6d, 0xe2, 0xf0, 0x55, + 0x6e, 0xd6, 0xe7, 0xa4, 0x66, 0xae, 0x73, 0x57, 0x3e, 0x12, 0xaa, 0xee, 0xba, 0xe8, 0x63, 0x8f, + 0x10, 0x55, 0x5d, 0x6b, 0xf0, 0xa6, 0x45, 0x87, 0x16, 0x10, 0x6d, 0x57, 0x69, 0xf5, 0xa9, 0x0a, + 0x0d, 0x2e, 0xa2, 0xac, 0x86, 0xd3, 0x29, 0x20, 0xfa, 0x20, 0x1c, 0x99, 0xc6, 0xc6, 0xe2, 0xa8, + 0x85, 0x6b, 0x2f, 0x10, 0x14, 0x8d, 0x92, 0x11, 0x22, 0xa4, 0x32, 0xba, 0xa6, 0xa3, 0x05, 0xea, + 0x06, 0x92, 0x1a, 0x20, 0x28, 0xca, 0xae, 0xb6, 0x06, 0x07, 0xab, 0x38, 0xdc, 0x56, 0xd1, 0x2b, + 0x3d, 0xfe, 0x14, 0xa1, 0x80, 0x66, 0x76, 0x20, 0xb9, 0x43, 0x79, 0xcb, 0x30, 0x3f, 0x4c, 0x58, + 0xbe, 0x8c, 0xca, 0xbb, 0xe1, 0x48, 0x3f, 0xcd, 0x44, 0xa4, 0xa1, 0x00, 0x73, 0xfb, 0xc1, 0x7a, + 0x18, 0x0a, 0xc5, 0x7d, 0x91, 0x19, 0x56, 0x9e, 0xb0, 0x3d, 0xb0, 0x4a, 0x74, 0xb3, 0x36, 0xd6, + 0x17, 0xba, 0x83, 0x35, 0x99, 0x33, 0xd3, 0x2f, 0x0a, 0x1d, 0xb5, 0xa9, 0x43, 0xbb, 0x36, 0x17, + 0x84, 0x87, 0x4e, 0xa1, 0xee, 0x3d, 0x34, 0x27, 0x34, 0x65, 0x0e, 0x60, 0x70, 0xf1, 0x86, 0x0c, + 0x61, 0xba, 0x1f, 0xa2, 0x18, 0x6a, 0xc2, 0x78, 0xe6, 0x44, 0xd7, 0x92, 0xd5, 0x67, 0xc4, 0xc6, + 0x49, 0xc6, 0x4d, 0xe8, 0x31, 0xc6, 0xd4, 0x52, 0x7b, 0x79, 0x77, 0x4b, 0xd5, 0xda, 0x7b, 0x8a, + 0xaf, 0x18, 0x42, 0xf0, 0x41, 0xdd, 0x23, 0x2e, 0x5e, 0xb5, 0x08, 0x7f, 0x96, 0x97, 0x5f, 0x47, + 0x3d, 0x13, 0xf0, 0x88, 0xdd, 0x56, 0x39, 0xe0, 0xa5, 0x5b, 0x9c, 0xba, 0xa6, 0xe8, 0xae, 0x7d, + 0x58, 0xae, 0xae, 0x7d, 0x15, 0xbe, 0xac, 0x85, 0x3a, 0x24, 0x73, 0xeb, 0x15, 0x8f, 0x47, 0xf3, + 0xa4, 0xd3, 0x4d, 0x34, 0x12, 0x0b, 0xf1, 0x61, 0xa6, 0x26, 0x3b, 0xa5, 0x7f, 0x8d, 0xcd, 0xd7, + 0x43, 0x4a, 0xd5, 0x09, 0x22, 0xae, 0x84, 0xc6, 0xc4, 0xf4, 0x8f, 0xcd, 0xec, 0xbe, 0x0a, 0xcb, + 0xb6, 0x7d, 0x69, 0xcc, 0x36, 0xe9, 0x5b, 0x43, 0x43, 0x34, 0x9f, 0x21, 0x6d, 0x2f, 0xc6, 0x09, + 0x3c, 0x58, 0xfb, 0x48, 0xab, 0x4a, 0xa6, 0xed, 0x31, 0xc4, 0xfe, 0x34, 0x56, 0x86, 0x74, 0x4d, + 0xee, 0x33, 0x71, 0x59, 0xe9, 0xac, 0xd1, 0xbb, 0x53, 0xd3, 0x5f, 0x9b, 0xd3, 0xf6, 0x25, 0xdb, + 0x76, 0x97, 0x19, 0xb6, 0xd2, 0xbb, 0x6b, 0x7a, 0x75, 0x9b, 0x7e, 0x11, 0xb2, 0x44, 0x34, 0x99, + 0x5c, 0xb6, 0x35, 0xeb, 0x6e, 0x9b, 0x12, 0x5e, 0x2f, 0x18, 0x31, 0x7d, 0x5a, 0x07, 0x14, 0xd7, + 0x6b, 0xcc, 0x62, 0x33, 0x79, 0x8d, 0x3c, 0xe1, 0x02, 0xc4, 0x70, 0x6e, 0x12, 0xa7, 0x43, 0x19, + 0x83, 0xf0, 0xa1, 0x5c, 0x24, 0x70, 0x40, 0x30, 0x06, 0x96, 0xe3, 0x99, 0x0a, 0x14, 0x5e, 0x77, + 0x60, 0x4b, 0xa7, 0xf2, 0x83, 0xcf, 0xfc, 0x23, 0x0f, 0x28, 0x41, 0x7a, 0xa0, 0x1c, 0x11, 0x5b, + 0x5f, 0x0a, 0x72, 0xf4, 0x88, 0x41, 0x42, 0x5f, 0x29, 0x8c, 0x35, 0xb2, 0xb8, 0xaf, 0x82, 0x66, + 0x31, 0x78, 0x13, 0x17, 0x39, 0x21, 0xf1, 0x92, 0x44, 0x68, 0x52, 0xa7, 0x50, 0x72, 0x18, 0x0e, + 0x34, 0x57, 0x13, 0x1b, 0x94, 0x06, 0xaa, 0x41, 0x45, 0x23, 0x26, 0x28, 0x6e, 0xca, 0x95, 0xb6, + 0x78, 0x50, 0xe7, 0x66, 0x27, 0xb3, 0x2b, 0xa2, 0x19, 0x2a, 0xa9, 0x33, 0xf0, 0x18, 0x65, 0xe4, + 0x92, 0xee, 0x7c, 0x12, 0x50, 0xae, 0x8d, 0xfe, 0x3a, 0x2e, 0x9c, 0x99, 0x24, 0x55, 0x32, 0x44, + 0x44, 0x4d, 0x83, 0xab, 0x07, 0xe1, 0x41, 0x85, 0xb4, 0x42, 0x7c, 0x9f, 0x8f, 0xef, 0x20, 0xa5, + 0xa2, 0x69, 0xf9, 0x68, 0x65, 0xa2, 0x03, 0xcf, 0x9d, 0xe2, 0x0a, 0x50, 0xb7, 0x23, 0x4d, 0xff, + 0xa9, 0x2c, 0x89, 0xf0, 0x50, 0x34, 0x1f, 0x61, 0xb2, 0x9e, 0x5f, 0xf9, 0xe1, 0x00, 0x48, 0x4c, + 0x06, 0x3f, 0x7c, 0x24, 0x74, 0x7e, 0x11, 0x94, 0x49, 0xfb, 0xbe, 0x9f, 0xa2, 0x66, 0x3c, 0x31, + 0x5d, 0x16, 0xdf, 0x56, 0xfa, 0x3b, 0xbe, 0x7a, 0xfb, 0x6d, 0xb6, 0xda, 0xe0, 0xb4, 0x34, 0xb7, + 0xa4, 0x9b, 0xd3, 0xfc, 0x20, 0x79, 0xa5, 0x52, 0xcb, 0xf7, 0x37, 0xf1, 0x78, 0x65, 0x1e, 0x9c, + 0x2c, 0xb9, 0xe1, 0x5b, 0xb0, 0x74, 0xac, 0xcb, 0xbc, 0x0a, 0x49, 0x2b, 0x6d, 0x7f, 0x9c, 0x8a, + 0x6b, 0xef, 0xfe, 0x09, 0x6c, 0x91, 0x5e, 0xa9, 0x6b, 0xe3, 0x4a, 0x66, 0x11, 0x1e, 0x14, 0xa9, + 0x52, 0x6d, 0x11, 0xf7, 0x4c, 0xfa, 0x9d, 0x3e, 0xab, 0x68, 0x8d, 0x5f, 0xf1, 0xf6, 0x43, 0xdc, + 0xce, 0x60, 0xd3, 0x26, 0xe9, 0xb2, 0x99, 0x9f, 0x15, 0xc5, 0x55, 0xb4, 0xf7, 0xc2, 0x65, 0xdd, + 0x53, 0xdf, 0xc6, 0xf4, 0xda, 0x44, 0x89, 0x1a, 0x5b, 0x4d, 0x35, 0x3e, 0xd4, 0x94, 0x9a, 0x68, + 0xaa, 0x9b, 0xf9, 0xb5, 0x49, 0x25, 0xc1, 0x07, 0x69, 0xad, 0x49, 0x24, 0xba, 0x4a, 0x83, 0x66, + 0x32, 0x68, 0x2f, 0xff, 0x0f, 0x97, 0x9f, 0x16, 0x3f, 0x9a, 0x4b, 0xe4, 0xe9, 0xfe, 0x28, 0x71, + 0x22, 0x8d, 0xbe, 0x6a, 0x57, 0x04, 0x61, 0x35, 0xde, 0xef, 0xb2, 0xee, 0xfe, 0xb5, 0xe1, 0x15, + 0xe4, 0x47, 0xec, 0x28, 0xe9, 0xa1, 0xd7, 0x31, 0xda, 0xaa, 0x93, 0xb2, 0x7b, 0x0c, 0x6c, 0x72, + 0xf9, 0x8d, 0xaa, 0xf9, 0x74, 0x97, 0x89, 0x89, 0xed, 0x9d, 0xb9, 0xa0, 0x8b, 0x13, 0x29, 0x78, + 0xe7, 0xd7, 0x08, 0xee, 0x9b, 0xee, 0x8b, 0x77, 0xc4, 0xf8, 0x81, 0x0c, 0x55, 0x5b, 0xf1, 0x01, + 0x0c, 0xd8, 0x17, 0xb2, 0x3b, 0xce, 0xe4, 0x5c, 0x9f, 0xe2, 0x18, 0xd9, 0x14, 0xca, 0xcf, 0xf8, + 0x9a, 0xe8, 0x5b, 0xa5, 0xe7, 0x08, 0x2c, 0x9e, 0x48, 0x78, 0x8e, 0x52, 0xcd, 0xbf, 0x9e, 0xb3, + 0xdb, 0x55, 0x7b, 0xe0, 0x8b, 0xb2, 0x7d, 0x42, 0xf8, 0x8b, 0x88, 0xa1, 0x8d, 0xf1, 0xfc, 0xd5, + 0x6a, 0xa6, 0xff, 0x89, 0x97, 0x33, 0x16, 0xf1, 0x02, 0x0c, 0x5c, 0xb8, 0x5c, 0xf1, 0x67, 0xcb, + 0x85, 0xcc, 0xb9, 0xc4, 0xfe, 0x51, 0x8e, 0xe2, 0xbc, 0x6b, 0x0c, 0x9d, 0xad, 0x0f, 0xf4, 0x5e, + 0x84, 0x3a, 0x0d, 0x75, 0xf1, 0x57, 0x2d, 0xad, 0xb4, 0x34, 0x3f, 0x88, 0x96, 0xcb, 0x79, 0x63, + 0x15, 0xdf, 0x08, 0xdc, 0x56, 0x2b, 0x6b, 0xec, 0x58, 0xaf, 0x9f, 0x8a, 0x18, 0xf7, 0xbc, 0xb4, + 0x75, 0xc5, 0xf8, 0x87, 0xe3, 0x6b, 0xae, 0x6c, 0xf9, 0x5f, 0x17, 0x69, 0xa5, 0x51, 0xef, 0x15, + 0x6f, 0x1f, 0xc8, 0x83, 0x3c, 0x13, 0x89, 0xd5, 0x73, 0x47, 0xdf, 0x54, 0xbf, 0x5d, 0x7c, 0x9b, + 0x36, 0x4a, 0xf9, 0x37, 0xb5, 0xe5, 0x2b, 0x1c, 0xcf, 0xae, 0x6b, 0x08, 0x81, 0x93, 0x67, 0xe1, + 0x33, 0x17, 0x1d, 0x17, 0x77, 0x3f, 0x12, 0x74, 0x97, 0x3b, 0xe1, 0xe4, 0x90, 0x79, 0xd5, 0x13, + 0x05, 0x98, 0x87, 0x03, 0x6d, 0x36, 0xa9, 0x93, 0xe7, 0x38, 0x21, 0xc0, 0xdd, 0xe2, 0x05, 0xee, + 0x6e, 0x7f, 0x88, 0x87, 0xc8, 0x2d, 0x17, 0x32, 0xe2, 0xbc, 0x38, 0x73, 0x9b, 0x97, 0x3e, 0x7e, + 0x9c, 0x55, 0xf1, 0x21, 0x48, 0x65, 0xa3, 0xb0, 0xbb, 0x19, 0x9c, 0xe7, 0x61, 0x55, 0x7a, 0x12, + 0x6d, 0x10, 0xa6, 0xaa, 0x26, 0x09, 0xf2, 0xe1, 0x35, 0xbc, 0xa6, 0x36, 0x5c, 0x2d, 0xb1, 0xf0, + 0xa5, 0xac, 0xae, 0x99, 0x68, 0x54, 0xf5, 0xdb, 0xa2, 0x12, 0x71, 0x31, 0x3f, 0xc4, 0xe0, 0xe0, + 0x7e, 0x12, 0xe2, 0x71, 0x31, 0xb3, 0xb0, 0xe4, 0xaf, 0x9b, 0x47, 0x7d, 0x0f, 0x9c, 0x94, 0x24, + 0x45, 0x43, 0x09, 0x74, 0xd3, 0x7f, 0x8b, 0x7f, 0x13, 0x04, 0xe4, 0xaf, 0x23, 0x11, 0x36, 0x28, + 0x1b, 0x8f, 0x04, 0x71, 0xb5, 0xdd, 0x1b, 0x8c, 0x44, 0x27, 0x17, 0x26, 0x25, 0xd0, 0x14, 0xdf, + 0x11, 0x0a, 0x64, 0x7c, 0xd0, 0xa5, 0xc5, 0x64, 0xf9, 0x77, 0x8a, 0xd5, 0xd8, 0x04, 0xb9, 0x42, + 0x35, 0x58, 0x43, 0x90, 0x61, 0xa8, 0xa3, 0xb9, 0x4f, 0x89, 0xe6, 0xc9, 0x30, 0x60, 0x40, 0x5d, + 0x6e, 0x7e, 0xef, 0x77, 0xf0, 0x55, 0x54, 0xec, 0x79, 0x65, 0x54, 0x1d, 0x5a, 0xb9, 0xba, 0x1a, + 0xf8, 0x73, 0xaa, 0xe1, 0xf4, 0xd3, 0x6d, 0xb5, 0xc4, 0xef, 0x0c, 0xab, 0x37, 0xb2, 0xa7, 0x67, + 0xf3, 0x6b, 0x5f, 0x08, 0x91, 0xd2, 0x72, 0x15, 0xca, 0x8e, 0x79, 0x3b, 0x59, 0xe9, 0x9e, 0x24, + 0x40, 0xc2, 0xa5, 0x7d, 0x27, 0xf2, 0x93, 0x58, 0xce, 0x73, 0x2b, 0x5d, 0x2b, 0xf1, 0x01, 0x19, + 0x8d, 0x9c, 0x72, 0xbc, 0xb4, 0xdd, 0xf8, 0x81, 0xbc, 0x86, 0x95, 0xa6, 0x94, 0x47, 0x26, 0x51, + 0xea, 0x89, 0x70, 0x2b, 0x49, 0x9b, 0x73, 0xa5, 0x2e, 0xfe, 0x0b, 0x22, 0xe3, 0x2a, 0x5b, 0x0e, + 0xda, 0xae, 0x92, 0x54, 0x1b, 0xb5, 0x97, 0x12, 0x20, 0x28, 0x4b, 0x30, 0x40, 0x15, 0x65, 0x0b, + 0x21, 0x7b, 0xe4, 0x68, 0xc9, 0x7a, 0xad, 0x5a, 0xe3, 0x9f, 0x19, 0x85, 0x40, 0x86, 0x38, 0xd4, + 0xf2, 0xc0, 0x55, 0xe6, 0x48, 0x36, 0xb5, 0x5a, 0x8d, 0xb7, 0x45, 0xe0, 0xba, 0xc8, 0x47, 0xb0, + 0x6a, 0x14, 0x1a, 0xaa, 0x8a, 0x29, 0x96, 0x49, 0xef, 0x1e, 0x20, 0x65, 0x57, 0x1a, 0xcc, 0x50, + 0x12, 0xad, 0x42, 0x2f, 0xf1, 0x0f, 0x73, 0x62, 0xe4, 0xff, 0x2e, 0x1e, 0x0e, 0x26, 0x48, 0x07, + 0x7b, 0x09, 0x2f, 0xe0, 0xa3, 0x98, 0x6e, 0xef, 0xe5, 0x23, 0xdf, 0xe2, 0x8d, 0x2f, 0x34, 0x78, + 0x87, 0xd7, 0xca, 0x56, 0x51, 0x9e, 0x7f, 0xe2, 0x41, 0x16, 0xf3, 0x3d, 0x8f, 0x12, 0xe5, 0xcb, + 0x7c, 0x3c, 0x48, 0x91, 0x65, 0xcd, 0x8a, 0xbb, 0x5c, 0x48, 0x2a, 0x36, 0x6e, 0x98, 0xad, 0xdc, + 0x56, 0x3c, 0xb5, 0x62, 0x9b, 0xf8, 0x80, 0x81, 0x6d, 0x3a, 0x37, 0x8d, 0xae, 0xf7, 0xe2, 0x60, + 0x97, 0x7b, 0xd4, 0xbe, 0xdb, 0xc4, 0x9b, 0x27, 0x17, 0x59, 0x4e, 0x20, 0x28, 0x61, 0xe7, 0xd7, + 0xae, 0xf7, 0x7d, 0xa1, 0x8b, 0x5c, 0x3a, 0x2c, 0xb8, 0x9e, 0x71, 0x54, 0x22, 0x24, 0x74, 0x39, + 0x1e, 0x69, 0x76, 0xf8, 0x15, 0xbd, 0xc6, 0xb3, 0x6c, 0x92, 0x1b, 0x7d, 0xf1, 0x30, 0x84, 0xd1, + 0x51, 0x49, 0x13, 0x18, 0xd7, 0x49, 0x8b, 0xa5, 0x26, 0x75, 0xa3, 0xd5, 0x1f, 0xda, 0x83, 0x43, + 0x65, 0xc0, 0xea, 0xff, 0x04, 0xd5, 0x9b, 0xab, 0xbc, 0x6e, 0xec, 0xe9, 0xe1, 0xee, 0xca, 0xfb, + 0xfa, 0x27, 0x4f, 0xc7, 0x8b, 0x77, 0xcb, 0x8f, 0x55, 0x7f, 0xc4, 0x5e, 0xb6, 0x9a, 0x4b, 0x89, + 0x12, 0x09, 0xed, 0xd5, 0xa5, 0x9a, 0x9e, 0xf1, 0x20, 0xb4, 0x8e, 0x21, 0x61, 0xec, 0xbd, 0xfc, + 0xbe, 0x37, 0x74, 0x31, 0x2c, 0x2e, 0x21, 0xcb, 0xbb, 0xbe, 0x4f, 0x48, 0xb5, 0xd3, 0xb7, 0xfc, + 0x47, 0x11, 0x11, 0x86, 0xbf, 0x2f, 0xe5, 0xbe, 0x24, 0x29, 0x09, 0xde, 0xb7, 0x0e, 0x0d, 0x9d, + 0xe7, 0x24, 0x10, 0xa8, 0x35, 0xae, 0x60, 0xec, 0x5e, 0xfd, 0x7a, 0x95, 0x87, 0xa9, 0xb6, 0x1e, + 0xce, 0xfc, 0xfe, 0x10, 0x11, 0x1b, 0xdf, 0x77, 0x7b, 0x85, 0x56, 0xcf, 0x04, 0x62, 0xf2, 0x17, + 0xcd, 0x2a, 0xb0, 0xf0, 0x88, 0x50, 0x75, 0x6a, 0x29, 0xc7, 0xc7, 0xcf, 0x6d, 0xaa, 0xab, 0x7a, + 0x1b, 0xfb, 0xc2, 0x21, 0x48, 0xf3, 0xd2, 0xcc, 0x2c, 0x33, 0x8a, 0xb0, 0x77, 0x05, 0x39, 0xd9, + 0x30, 0x0e, 0x53, 0x19, 0xca, 0xd4, 0x6d, 0x8f, 0x09, 0xcc, 0x7c, 0x28, 0x2c, 0x5d, 0x55, 0x56, + 0x94, 0x9e, 0xa3, 0xc3, 0x87, 0x87, 0x15, 0x8c, 0xef, 0x5b, 0xff, 0x1c, 0x48, 0x81, 0x86, 0x8d, + 0xd1, 0x8d, 0xfd, 0x9c, 0x5e, 0x55, 0x8c, 0x77, 0xf2, 0x3b, 0xf9, 0x5d, 0x71, 0x10, 0xa4, 0x05, + 0xee, 0x8c, 0x1d, 0x07, 0x00, 0x10, 0x98, 0xbe, 0x80, 0x68, 0x65, 0xc3, 0xaa, 0xd8, 0xc8, 0xdb, + 0x6b, 0xc9, 0x0a, 0x3a, 0x97, 0x44, 0xa0, 0xb3, 0x7a, 0xea, 0x1c, 0x06, 0xdf, 0x91, 0xad, 0xea, + 0x15, 0x59, 0x68, 0xd5, 0x65, 0x0a, 0xb5, 0x69, 0x8d, 0xa0, 0xba, 0xd6, 0xdb, 0x88, 0x97, 0x36, + 0x31, 0x04, 0x7d, 0xf9, 0xe0, 0x4c, 0x48, 0x93, 0xd5, 0x56, 0xd5, 0x7c, 0x96, 0x3d, 0x71, 0x32, + 0x54, 0x5d, 0x57, 0xc2, 0x22, 0x26, 0xfe, 0x24, 0xe0, 0xa1, 0xa9, 0x7a, 0x57, 0xe2, 0x4e, 0x0f, + 0xec, 0xa4, 0x48, 0x6f, 0x9d, 0xd7, 0x0d, 0x43, 0x43, 0x92, 0x07, 0x46, 0x07, 0x67, 0x92, 0x45, + 0xf0, 0xdf, 0x77, 0xf1, 0x11, 0x70, 0x48, 0xd6, 0xd2, 0x17, 0x9d, 0xe0, 0x70, 0x73, 0x22, 0x20, + 0x80, 0xf1, 0x3e, 0x24, 0x61, 0x20, 0xdd, 0xda, 0xb4, 0xee, 0xe7, 0x81, 0xf3, 0xaf, 0x3b, 0x3e, + 0x14, 0x21, 0xb9, 0xde, 0x5f, 0x12, 0x04, 0xd1, 0x8e, 0xf2, 0x23, 0x34, 0x82, 0x8c, 0x62, 0xa4, + 0xc1, 0x21, 0x59, 0x4c, 0x93, 0x4d, 0xeb, 0x88, 0x0c, 0x05, 0x05, 0xb0, 0xf2, 0xdb, 0xb0, 0xe0, + 0x15, 0x1d, 0x31, 0x03, 0xe4, 0x0b, 0x0b, 0xb9, 0xfe, 0xfb, 0x8e, 0xf3, 0xb8, 0x98, 0x50, 0x55, + 0x44, 0x5d, 0x16, 0x80, 0xb1, 0x1d, 0x91, 0xcb, 0x80, 0x00, 0x61, 0x42, 0x60, 0x0a, 0x9f, 0xc7, + 0x80, 0x03, 0x01, 0xe0, 0xbb, 0x30, 0xe0, 0xe6, 0xd8, 0x7e, 0x4a, 0x48, 0x05, 0x43, 0xd0, 0xea, + 0x3b, 0x83, 0x55, 0x7c, 0x61, 0x65, 0xa9, 0x25, 0xc3, 0x0a, 0xae, 0x06, 0xef, 0x48, 0x79, 0x7a, + 0xd4, 0x2a, 0xe3, 0x81, 0xde, 0x84, 0x76, 0x16, 0x1d, 0xed, 0x9e, 0x14, 0xc9, 0xd8, 0x77, 0x41, + 0xd0, 0x51, 0xcd, 0xf4, 0xea, 0xdc, 0x28, 0xbb, 0x38, 0x88, 0xc2, 0xea, 0xea, 0xb5, 0xbb, 0x60, + 0xd6, 0x97, 0x49, 0x69, 0x1f, 0x87, 0xf9, 0x77, 0x59, 0x39, 0xb4, 0xab, 0xe5, 0xd6, 0xb8, 0x88, + 0x43, 0x7a, 0xaa, 0xd5, 0x55, 0x7e, 0x3a, 0xb5, 0xea, 0xab, 0x55, 0x5c, 0x16, 0x16, 0x9b, 0xbb, + 0xdf, 0x77, 0x79, 0x7c, 0x68, 0x87, 0x7b, 0xc5, 0xc4, 0xfb, 0x22, 0xf7, 0x1e, 0xe8, 0xf1, 0x08, + 0x07, 0x07, 0x49, 0x23, 0x2a, 0x0b, 0xc5, 0x8e, 0x76, 0x83, 0xef, 0x93, 0xf8, 0x52, 0x7c, 0x8c, + 0xe0, 0xd2, 0xe2, 0x93, 0xd8, 0xa2, 0xe8, 0x11, 0xb3, 0x27, 0xed, 0x6e, 0x81, 0x83, 0xf5, 0xd9, + 0x5a, 0x84, 0xa6, 0x15, 0x67, 0x8a, 0xde, 0x8b, 0x4b, 0x49, 0xe4, 0xe0, 0x9e, 0x3a, 0x66, 0xce, + 0xde, 0x65, 0x7b, 0x5d, 0x13, 0x87, 0x45, 0x5f, 0x05, 0x74, 0x6e, 0xa2, 0x8e, 0xdb, 0x3e, 0x66, + 0x26, 0x1a, 0x14, 0xe4, 0x0e, 0xd9, 0x6e, 0x8e, 0x2f, 0x38, 0x62, 0x04, 0x02, 0x72, 0xc1, 0xb6, + 0xb2, 0xa9, 0x2d, 0xba, 0xf9, 0x62, 0x93, 0x12, 0x20, 0x15, 0x99, 0xec, 0x1f, 0xfa, 0x83, 0x3a, + 0xe5, 0x42, 0x29, 0x82, 0x76, 0xb9, 0x32, 0x5d, 0x16, 0xe2, 0x04, 0x85, 0x38, 0x28, 0xa7, 0x50, + 0x98, 0x34, 0x5b, 0xf7, 0x0a, 0xb0, 0xa8, 0xb7, 0x8a, 0x62, 0xf2, 0xe6, 0xa6, 0x47, 0x35, 0xb2, + 0x47, 0xa9, 0x5f, 0x98, 0xf8, 0x52, 0x21, 0x50, 0x70, 0xe0, 0x7c, 0x0d, 0x4f, 0x00, 0x70, 0xc4, + 0x20, 0x3f, 0x0b, 0x96, 0xa3, 0x90, 0x01, 0xc9, 0x94, 0xe8, 0xbf, 0xd8, 0xe5, 0xe0, 0x51, 0xf1, + 0xee, 0x2b, 0xac, 0xa4, 0x64, 0x20, 0xdd, 0x9d, 0x17, 0x38, 0x81, 0x23, 0x23, 0xff, 0x28, 0x2e, + 0xaa, 0x4f, 0x41, 0xf1, 0x7a, 0x75, 0xfd, 0x27, 0x6b, 0x65, 0x4a, 0xf7, 0x7b, 0x62, 0x3e, 0x33, + 0xb6, 0xd2, 0x33, 0x88, 0x90, 0xf5, 0xae, 0x22, 0x14, 0x32, 0xd5, 0x5b, 0xa4, 0xd5, 0x8a, 0xe8, + 0x94, 0x53, 0x15, 0xa4, 0xaa, 0x92, 0xb7, 0x0c, 0x42, 0x92, 0x41, 0x35, 0x92, 0x46, 0x2b, 0x07, + 0x6e, 0x9d, 0x72, 0x6e, 0x14, 0xae, 0x5e, 0x6c, 0x1c, 0x94, 0x71, 0xc6, 0xc3, 0xca, 0x00, 0x66, + 0xb7, 0x5e, 0x4f, 0xef, 0xe9, 0x1b, 0xf6, 0xf6, 0xe4, 0xcd, 0x57, 0x9d, 0x4a, 0x97, 0x9d, 0xe2, + 0x74, 0x07, 0x30, 0x7f, 0x9a, 0x82, 0xdf, 0x82, 0x32, 0x8a, 0xc5, 0x60, 0x35, 0x9a, 0x17, 0x00, + 0xa3, 0x52, 0x7f, 0x48, 0xa5, 0xe2, 0xee, 0xee, 0x0f, 0x3c, 0xdd, 0xc2, 0x3d, 0x62, 0xae, 0xea, + 0xab, 0x5c, 0xa5, 0x17, 0x4d, 0x7e, 0x14, 0xbe, 0xea, 0xb5, 0x49, 0x2f, 0x43, 0x1a, 0x59, 0x7c, + 0x66, 0x9a, 0xab, 0xa7, 0x7a, 0xcf, 0x15, 0xfc, 0x25, 0x9d, 0x9b, 0x1b, 0xbf, 0xe0, 0x8b, 0x41, + 0xa9, 0x49, 0xf5, 0x70, 0x4a, 0x4b, 0xda, 0x77, 0xf5, 0x7c, 0xc5, 0x63, 0x94, 0x51, 0xbe, 0x25, + 0xe8, 0x37, 0x63, 0xe2, 0x06, 0xd9, 0xa6, 0xcf, 0x0a, 0x2e, 0x87, 0x25, 0x4b, 0x0d, 0xe3, 0xca, + 0x1f, 0xad, 0x70, 0x1e, 0xd9, 0x2b, 0xf6, 0xe0, 0xfb, 0xf1, 0x00, 0xa8, 0x41, 0xcc, 0x1f, 0x07, + 0xc7, 0xc0, 0x3d, 0xad, 0x42, 0x1d, 0x39, 0x81, 0x88, 0xfb, 0x01, 0xa7, 0xac, 0xa7, 0xab, 0x68, + 0xc1, 0x61, 0xe3, 0x3b, 0xb1, 0x41, 0xd8, 0x56, 0xb5, 0x26, 0x3f, 0xf9, 0x70, 0x3a, 0xb2, 0xa8, + 0xb9, 0xa1, 0xe5, 0x2d, 0x21, 0x8f, 0x33, 0x3d, 0x65, 0x78, 0x90, 0xa7, 0x66, 0x3b, 0x7d, 0x37, + 0x6f, 0x56, 0x62, 0xf3, 0x19, 0xa9, 0x8b, 0x88, 0x85, 0x25, 0x10, 0x17, 0x68, 0xf0, 0xe0, 0xb2, + 0x93, 0x39, 0xe0, 0x21, 0xc8, 0xb5, 0x7c, 0x15, 0x15, 0xbc, 0x3a, 0x32, 0xe2, 0x21, 0x49, 0x5a, + 0x41, 0x97, 0x4c, 0xc2, 0xad, 0x8a, 0x32, 0x9e, 0x9d, 0xf1, 0x78, 0xc2, 0x04, 0x77, 0xa1, 0x4c, + 0xcb, 0x38, 0xdf, 0x24, 0x63, 0xc7, 0x73, 0xe2, 0x21, 0xe1, 0x23, 0x64, 0x46, 0x6b, 0x06, 0x5b, + 0xf1, 0x03, 0x83, 0xc3, 0xa3, 0xed, 0x3f, 0x5a, 0x3e, 0xff, 0xe1, 0x5f, 0xb1, 0x95, 0x81, 0x86, + 0xb0, 0x1f, 0x79, 0xf5, 0xbf, 0xf1, 0x30, 0xcf, 0x29, 0x22, 0x92, 0xe9, 0xf5, 0xaf, 0xf0, 0x8d, + 0xd1, 0xab, 0xa5, 0xe1, 0x7c, 0x3e, 0xb2, 0x06, 0xe6, 0xfe, 0xf0, 0xb7, 0xbf, 0x04, 0x20, 0x49, + 0x1a, 0x20, 0x28, 0x00, 0x6f, 0xb8, 0x60, 0x0c, 0xc8, 0x2e, 0x0e, 0x3a, 0xbc, 0x00, 0x04, 0x68, + 0x1b, 0x98, 0x58, 0xc9, 0xa0, 0xc3, 0x27, 0x4f, 0x20, 0x63, 0x07, 0x4b, 0x00, 0x02, 0x88, 0x1a, + 0xe4, 0xe0, 0x1e, 0x1c, 0x7f, 0x18, 0xa8, 0xbe, 0xb6, 0x5d, 0x21, 0x08, 0x1f, 0xab, 0x16, 0x19, + 0xc0, 0xc2, 0xd8, 0xb1, 0x00, 0x01, 0x00, 0xac, 0x10, 0x00, 0x50, 0x01, 0xc0, 0x17, 0x6e, 0x15, + 0x4c, 0xcc, 0xc4, 0xcc, 0x59, 0x5e, 0x05, 0x0b, 0x1e, 0x55, 0x6b, 0x5f, 0x05, 0x23, 0x62, 0xf2, + 0x80, 0xf2, 0xcf, 0x38, 0xb4, 0x02, 0x22, 0xc0, 0x97, 0x2b, 0xb5, 0xd0, 0xa3, 0x0b, 0xaa, 0x43, + 0xca, 0x1d, 0xc9, 0x6a, 0x00, 0x01, 0x03, 0x11, 0x31, 0x88, 0x0a, 0x1a, 0x02, 0xaa, 0xd7, 0xb8, + 0x84, 0x1e, 0x16, 0x15, 0x25, 0x90, 0x5b, 0x03, 0x56, 0x20, 0x1f, 0xbb, 0xcf, 0x54, 0x37, 0xe4, + 0x82, 0x01, 0x21, 0x48, 0xa5, 0x04, 0x0e, 0x42, 0x07, 0x05, 0x32, 0xd8, 0x2b, 0x4c, 0x80, 0x15, + 0x69, 0xdc, 0xc1, 0x41, 0x78, 0x2d, 0xd0, 0xa6, 0xb0, 0xed, 0xb0, 0x1b, 0xc2, 0x51, 0xeb, 0x2e, + 0x90, 0x6f, 0xfa, 0x4f, 0xc4, 0x5d, 0x9c, 0x9d, 0x81, 0xc8, 0x93, 0x48, 0x38, 0x30, 0x0c, 0x8d, + 0x90, 0x18, 0x77, 0x6b, 0x7d, 0xa6, 0x00, 0x4a, 0xe8, 0x65, 0x2a, 0x0a, 0x93, 0x50, 0x90, 0x00, + 0x09, 0xd1, 0x92, 0x25, 0x0e, 0x30, 0x6a, 0xff, 0x8b, 0x32, 0xac, 0xca, 0x84, 0xa8, 0x8c, 0x96, + 0xb7, 0x02, 0xa5, 0x1d, 0x55, 0x32, 0xf6, 0xeb, 0xff, 0x12, 0x26, 0xf7, 0x12, 0xc1, 0xed, 0xcb, + 0xdd, 0x29, 0x23, 0x15, 0xc5, 0x11, 0xb1, 0xca, 0xae, 0xf5, 0xb6, 0xb9, 0xbb, 0xb5, 0xec, 0xaa, + 0xb8, 0x8e, 0x1a, 0x23, 0x20, 0xd1, 0xf6, 0x5d, 0xf9, 0x68, 0xf4, 0xfc, 0x41, 0x1d, 0x31, 0xd9, + 0x53, 0x4f, 0x71, 0x54, 0x37, 0xef, 0x1c, 0x44, 0xa3, 0xfa, 0x05, 0x96, 0x8a, 0x38, 0x63, 0x7c, + 0x94, 0x5f, 0xb2, 0xcf, 0xdf, 0x8d, 0x18, 0x7c, 0xa5, 0x39, 0x1a, 0x48, 0x3f, 0x19, 0xee, 0xd1, + 0x69, 0xbd, 0x44, 0xca, 0x6c, 0xca, 0xd4, 0xd8, 0xd2, 0xda, 0xf1, 0xdc, 0xf8, 0xeb, 0xba, 0x3b, + 0x6b, 0xf1, 0x84, 0x70, 0xb3, 0x33, 0x93, 0x3e, 0xf6, 0x9d, 0xef, 0xec, 0xbb, 0xb4, 0x64, 0x44, + 0xe4, 0x2a, 0x60, 0xee, 0xc7, 0x89, 0x85, 0x05, 0x3f, 0xa6, 0x47, 0x52, 0xb7, 0xc1, 0x96, 0x7c, + 0x71, 0xe1, 0x61, 0xea, 0x5b, 0x54, 0x66, 0xc6, 0xdc, 0x7a, 0x4c, 0x90, 0x53, 0x0b, 0x90, 0x40, + 0xff, 0x29, 0x76, 0x7f, 0x82, 0xe2, 0x71, 0xdd, 0x06, 0xe4, 0xda, 0xc6, 0xf2, 0x87, 0x59, 0xc0, + 0x06, 0x07, 0x20, 0x51, 0x87, 0xae, 0xe7, 0xa0, 0x91, 0x88, 0x86, 0x26, 0x8c, 0xab, 0xf9, 0xbd, + 0x89, 0xc5, 0x66, 0x02, 0xdc, 0x52, 0x53, 0xc3, 0x9a, 0x67, 0xb0, 0x0f, 0x43, 0xc0, 0x53, 0x38, + 0x22, 0xc6, 0x88, 0x92, 0xa8, 0x94, 0x28, 0xe6, 0x79, 0x2d, 0x62, 0x47, 0xc3, 0xd8, 0x03, 0xcd, + 0xf1, 0xf8, 0x08, 0x59, 0x7f, 0x40, 0xe9, 0x88, 0x97, 0xc5, 0x8b, 0xe3, 0x8b, 0xee, 0xa6, 0xf3, + 0x38, 0xc0, 0xe3, 0xce, 0x3e, 0x91, 0x66, 0x79, 0x88, 0xf5, 0xcb, 0xce, 0x3c, 0xef, 0x2c, 0x30, + 0x89, 0x26, 0x11, 0x42, 0x09, 0xa7, 0xfd, 0xca, 0xaf, 0xab, 0xfc, 0x18, 0x8d, 0x35, 0x00, 0x3f, + 0xf9, 0x9c, 0xc6, 0x66, 0x52, 0xc0, 0x4b, 0x81, 0xd0, 0x1e, 0x14, 0x1b, 0x21, 0xc1, 0x26, 0x0e, + 0x21, 0x30, 0x1f, 0x9d, 0x0d, 0x4d, 0xfd, 0x29, 0x61, 0xa8, 0x4e, 0x01, 0xc1, 0x58, 0x0a, 0xaa, + 0x21, 0x11, 0xe7, 0x23, 0xa2, 0x2e, 0x9b, 0xa3, 0xfe, 0x24, 0x69, 0xdd, 0xce, 0xf7, 0x60, 0xa3, + 0x72, 0xfe, 0xa2, 0x78, 0x17, 0x9d, 0x8e, 0x26, 0x56, 0x02, 0x6f, 0x87, 0x10, 0xb0, 0x0e, 0x18, + 0xaa, 0x28, 0x1d, 0x52, 0x9e, 0x1d, 0xfe, 0x24, 0x6d, 0xdd, 0xa7, 0x4a, 0xe2, 0xb3, 0x76, 0x71, + 0x80, 0x34, 0x9c, 0x38, 0x24, 0xc9, 0x36, 0x0c, 0x06, 0x98, 0x65, 0x00, 0x44, 0xf0, 0x80, 0x4e, + 0x9b, 0x60, 0xe8, 0x2d, 0x1d, 0x0b, 0x7f, 0x88, 0x0d, 0xf0, 0xb0, 0x00, 0xe1, 0x94, 0xd7, 0x28, + 0x02, 0xb8, 0x18, 0x96, 0x36, 0x7f, 0xc2, 0x30, 0xa1, 0x86, 0x6e, 0xd6, 0x8b, 0xc3, 0x75, 0xfe, + 0x2c, 0x8d, 0x66, 0xda, 0x96, 0x9b, 0x97, 0x3c, 0xf0, 0xa3, 0x41, 0xd5, 0xce, 0x3f, 0x0f, 0xc5, + 0x4c, 0x89, 0xc2, 0x00, 0xa4, 0x15, 0x6b, 0xa8, 0xee, 0xe6, 0x65, 0xf8, 0x7c, 0x07, 0x8b, 0x6f, + 0x2f, 0xa7, 0xdc, 0x54, 0x7e, 0x75, 0x9a, 0x31, 0xcd, 0xcd, 0x7c, 0x15, 0x8b, 0x7f, 0xca, 0xae, + 0x96, 0x1c, 0x43, 0x3d, 0x30, 0x77, 0x03, 0x3a, 0x9b, 0xb1, 0xef, 0x11, 0xc1, 0x4d, 0xa6, 0x32, + 0xb1, 0x6c, 0x9b, 0xb2, 0x4d, 0xaf, 0x1c, 0xdd, 0x9a, 0xb1, 0x77, 0xdd, 0xf7, 0xf2, 0xed, 0xaf, + 0xca, 0x2e, 0x9a, 0xfc, 0x86, 0x44, 0x7c, 0xa7, 0xe5, 0x23, 0xef, 0xe1, 0x3d, 0xdf, 0x76, 0xbe, + 0xe8, 0xeb, 0x5d, 0x58, 0x78, 0x67, 0xba, 0x25, 0xfc, 0x73, 0xa3, 0xf0, 0x8d, 0x63, 0x2c, 0xa8, + 0xcf, 0x94, 0xbb, 0xbb, 0xf8, 0xca, 0xe3, 0x83, 0xc4, 0x39, 0x87, 0x7d, 0x58, 0x61, 0x0c, 0xe8, + 0xfc, 0xd9, 0xaf, 0xbd, 0x74, 0xfe, 0x23, 0xcc, 0xd6, 0x18, 0xe6, 0x50, 0xeb, 0xf1, 0x38, 0x1c, + 0x74, 0xe3, 0xbc, 0x41, 0x63, 0x61, 0x8e, 0x99, 0x78, 0x25, 0x9e, 0x3a, 0x22, 0x86, 0x03, 0x5a, + 0xcb, 0xef, 0x37, 0x1c, 0x42, 0x33, 0xc4, 0x6b, 0xc1, 0x0e, 0x91, 0x4d, 0xb6, 0x5a, 0xf8, 0xec, + 0xa4, 0x58, 0x9f, 0xf4, 0x92, 0x65, 0x13, 0xfc, 0xd3, 0xbf, 0x92, 0x26, 0x14, 0xcc, 0xcc, 0x5c, + 0xd0, 0x06, 0x71, 0x6f, 0xa8, 0x1f, 0xbd, 0x01, 0x4e, 0x49, 0xe4, 0x1e, 0xbe, 0x53, 0xd3, 0xa3, + 0x39, 0x86, 0x9c, 0x17, 0x1a, 0x4c, 0x38, 0xeb, 0x72, 0xf3, 0xb3, 0x1b, 0x90, 0x3d, 0x9d, 0x11, + 0x16, 0xb0, 0xa0, 0x8e, 0x98, 0x95, 0xfd, 0x4d, 0x0e, 0xb3, 0x4f, 0x0f, 0xdd, 0x53, 0xf0, 0x46, + 0x2f, 0x43, 0x0b, 0xa6, 0x3a, 0xf8, 0xb2, 0x6e, 0xad, 0x69, 0xb8, 0x80, 0x42, 0x36, 0x6c, 0x03, + 0xaa, 0x61, 0x74, 0x86, 0x4c, 0x6a, 0x78, 0xe0, 0x16, 0x36, 0xca, 0xb2, 0x6b, 0x00, 0x4a, 0xe2, + 0xc5, 0x28, 0x65, 0xa4, 0xbe, 0x90, 0xcf, 0x79, 0x6d, 0xbe, 0x90, 0x04, 0x72, 0x61, 0x69, 0xa0, + 0xb0, 0x9f, 0x81, 0x9f, 0x55, 0x28, 0xa1, 0x39, 0x87, 0xe0, 0x80, 0x0a, 0x03, 0x4c, 0xb8, 0x12, + 0xd3, 0x08, 0x1b, 0x1d, 0xda, 0x50, 0x04, 0x52, 0x76, 0x3a, 0x2d, 0x8b, 0x00, 0xaa, 0xb8, 0xd3, + 0x80, 0x14, 0x42, 0x89, 0xa5, 0x0e, 0xaf, 0xc0, 0x00, 0x83, 0xc3, 0xce, 0x60, 0x00, 0x20, 0x02, + 0xb1, 0x91, 0x15, 0x00, 0xf9, 0x00, 0xeb, 0xfc, 0xae, 0x08, 0x08, 0xf1, 0xc8, 0x6e, 0x2b, 0x30, + 0x05, 0x82, 0xc0, 0x91, 0x06, 0x01, 0x4a, 0x01, 0x60, 0x78, 0x82, 0x00, 0xa4, 0xfe, 0xcb, 0x3d, + 0xb7, 0x34, 0x70, 0x80, 0x29, 0x19, 0x78, 0x11, 0x82, 0x70, 0x3d, 0xf6, 0x85, 0x08, 0x1a, 0x8f, + 0x66, 0xd6, 0x57, 0x44, 0x17, 0xbf, 0x23, 0x68, 0x3a, 0x12, 0x00, 0xac, 0x22, 0x18, 0x5c, 0xb9, + 0x6b, 0x2a, 0x83, 0xfe, 0x04, 0x00, 0x35, 0x14, 0xaa, 0x05, 0x84, 0xa0, 0x00, 0x51, 0x4c, 0x10, + 0x84, 0x46, 0xc7, 0x56, 0x3f, 0xa0, 0x29, 0x2c, 0x0f, 0x0e, 0x47, 0xc3, 0x74, 0x31, 0xbc, 0x86, + 0x43, 0xb5, 0x60, 0x6f, 0xb2, 0x2d, 0x0c, 0xf0, 0xe5, 0xd8, 0xcb, 0x03, 0x2c, 0xcf, 0x00, 0x3c, + 0x41, 0xe7, 0x70, 0xe9, 0x2d, 0x65, 0xaf, 0xfc, 0x40, 0x64, 0x29, 0xe2, 0x1f, 0x61, 0xcd, 0x0b, + 0x1c, 0x4a, 0x7c, 0x2b, 0xd1, 0x80, 0x68, 0x0e, 0xc4, 0xa7, 0x07, 0x0a, 0x45, 0x93, 0xb2, 0x58, + 0x6b, 0xdc, 0x40, 0x91, 0xb7, 0x40, 0x7c, 0xab, 0x21, 0x97, 0xb7, 0xad, 0xc5, 0x1a, 0xa8, 0xf3, + 0xed, 0x26, 0x32, 0x19, 0xbb, 0xb4, 0x99, 0x52, 0xc3, 0x2c, 0x31, 0x16, 0x97, 0xa5, 0x6e, 0xff, + 0x84, 0x63, 0x0a, 0x56, 0x74, 0x3d, 0x64, 0x58, 0xe4, 0x46, 0xea, 0x70, 0xe8, 0x13, 0xbb, 0xd2, + 0x62, 0xc3, 0xe7, 0xab, 0x14, 0x38, 0x3a, 0x5e, 0x41, 0x64, 0x96, 0x47, 0x82, 0x00, 0x52, 0x37, + 0xf5, 0x26, 0x8f, 0x56, 0x98, 0xa7, 0xae, 0x60, 0x6a, 0xd0, 0xcd, 0x68, 0x00, 0x56, 0x8e, 0x01, + 0x80, 0x2d, 0x66, 0xc5, 0xf6, 0x02, 0x3f, 0x2f, 0x0f, 0x87, 0x91, 0x46, 0x64, 0x48, 0xe6, 0x3a, + 0x05, 0xae, 0x1b, 0xae, 0xd9, 0x5f, 0xf6, 0x55, 0xe9, 0xf7, 0xf1, 0xdc, 0x16, 0x45, 0xdb, 0x3b, + 0x27, 0xfd, 0x35, 0x57, 0x42, 0x6a, 0xf7, 0xc2, 0x46, 0xbc, 0xbd, 0x6b, 0xf0, 0xa5, 0xde, 0xa1, + 0x5e, 0x7f, 0x97, 0xf6, 0xee, 0x2b, 0x4e, 0x1e, 0x2b, 0x74, 0xee, 0xf1, 0x0b, 0x1e, 0x12, 0x2a, + 0x5a, 0xe7, 0xff, 0x18, 0x45, 0x53, 0x40, 0xb3, 0x7d, 0xea, 0x93, 0x6b, 0x5f, 0x82, 0xd1, 0xae, + 0xd3, 0xbb, 0xde, 0xff, 0x0a, 0x0c, 0x77, 0x4d, 0xdb, 0x85, 0x5a, 0x56, 0x5f, 0xbe, 0xed, 0x36, + 0xff, 0x05, 0x71, 0x46, 0xee, 0x7e, 0x6d, 0xad, 0x9f, 0xaa, 0xa7, 0x1c, 0xf8, 0x26, 0xb1, 0x29, + 0x94, 0x33, 0xd7, 0xb7, 0x67, 0xc2, 0x23, 0x73, 0xf5, 0xda, 0x4e, 0x15, 0xd2, 0xa8, 0xe3, 0xe1, + 0x41, 0x53, 0xd5, 0x58, 0xa0, 0x91, 0x3e, 0x55, 0x56, 0xcd, 0x56, 0x2a, 0x43, 0x4e, 0xec, 0xf8, + 0xdc, 0xa8, 0x9b, 0xcd, 0xa9, 0x87, 0x35, 0x55, 0x7e, 0x2b, 0x0b, 0x75, 0xd8, 0x52, 0xb6, 0xde, + 0xae, 0x9a, 0xdd, 0xdb, 0xa6, 0x87, 0xe3, 0x4a, 0x7e, 0x53, 0x17, 0xa5, 0xcd, 0xbb, 0x7a, 0x52, + 0x39, 0x18, 0xbd, 0xb7, 0x6b, 0x95, 0x9c, 0x28, 0xa6, 0x2f, 0x2d, 0x7e, 0xa9, 0xfe, 0x76, 0x09, + 0xeb, 0xe0, 0xa4, 0xaa, 0x21, 0xd7, 0xe9, 0xb7, 0xc2, 0x30, 0x60, 0x6b, 0x84, 0x72, 0x53, 0xa3, + 0x97, 0xc1, 0x51, 0x83, 0x2a, 0x96, 0xfc, 0x61, 0xc1, 0xf1, 0x70, 0x57, 0x38, 0x12, 0xad, 0x6e, + 0xc6, 0x2e, 0x34, 0xa2, 0xe0, 0xe9, 0xa0, 0x4e, 0xeb, 0x9b, 0xd9, 0xcf, 0x85, 0x09, 0x48, 0xd5, + 0xa9, 0xea, 0xc4, 0x86, 0x89, 0x11, 0xc3, 0x74, 0x45, 0x33, 0x44, 0xec, 0x16, 0x7f, 0x8a, 0x2a, + 0x49, 0x29, 0x7b, 0xf7, 0x48, 0x55, 0x58, 0x43, 0x74, 0xae, 0x95, 0xcc, 0xf1, 0x44, 0xab, 0x1a, + 0x66, 0xa3, 0x47, 0x13, 0x1f, 0x1b, 0x46, 0xe5, 0xb4, 0x6d, 0x0a, 0xde, 0x70, 0xed, 0x24, 0xa2, + 0x70, 0xfa, 0x43, 0xaf, 0xbc, 0x54, 0x35, 0x66, 0xaa, 0xd4, 0x59, 0x6d, 0x75, 0x4c, 0xd4, 0xeb, + 0x0f, 0xd4, 0xa4, 0x3f, 0x3c, 0x71, 0xa7, 0x1f, 0xb3, 0x1f, 0xe9, 0xf0, 0xa0, 0x95, 0xe3, 0x06, + 0x09, 0xa7, 0xd7, 0x1b, 0x0a, 0xa4, 0x72, 0xb6, 0x2b, 0x62, 0x5a, 0x9a, 0xd5, 0xf6, 0x19, 0x6f, + 0x4a, 0xbc, 0x29, 0xa3, 0xee, 0x89, 0x11, 0xdb, 0x46, 0x3d, 0x53, 0xce, 0xed, 0x1a, 0x38, 0xdb, + 0x8a, 0xa1, 0xa5, 0xaf, 0x82, 0x22, 0x47, 0xab, 0xac, 0xaa, 0x39, 0xf0, 0xa5, 0xc4, 0x8f, 0xfa, + 0xa7, 0x9f, 0x47, 0x44, 0x9a, 0x15, 0x3e, 0xd0, 0x22, 0x66, 0x06, 0xe9, 0x95, 0x67, 0xcd, 0xaa, + 0xab, 0x89, 0x8d, 0x8c, 0x62, 0x35, 0x68, 0x3e, 0xa0, 0x7c, 0xd3, 0x0a, 0xd0, 0x35, 0x82, 0x03, + 0xbd, 0x66, 0x26, 0xab, 0x28, 0x48, 0x98, 0xa6, 0xb7, 0xcb, 0xf1, 0x0b, 0x14, 0x58, 0x98, 0x52, + 0x28, 0xdc, 0xf6, 0x1b, 0xa1, 0xbb, 0xc2, 0x93, 0x8a, 0x62, 0x89, 0xdd, 0xa6, 0x87, 0xdc, 0x48, + 0x90, 0xa1, 0xab, 0xca, 0x86, 0xc1, 0x26, 0x51, 0xe5, 0xc1, 0x36, 0xd9, 0x26, 0x55, 0x1b, 0x4e, + 0x9d, 0x78, 0x52, 0xf8, 0xda, 0x5b, 0x5b, 0xe5, 0xbc, 0x60, 0xef, 0x50, 0x48, 0xf3, 0x16, 0xa2, + 0xf6, 0xa6, 0x2b, 0xd1, 0x52, 0x38, 0xfc, 0x44, 0x01, 0x48, 0x37, 0x06, 0xd9, 0x53, 0x79, 0xd6, + 0xa2, 0x22, 0x22, 0x46, 0x54, 0x68, 0x4c, 0x8a, 0x3b, 0x92, 0x3e, 0x36, 0xc3, 0x1a, 0x51, 0x9d, + 0x91, 0x06, 0x0e, 0x82, 0x0c, 0x68, 0xfa, 0x44, 0x35, 0x95, 0x34, 0x57, 0xe8, 0xf6, 0x36, 0xca, + 0x2f, 0xb3, 0x92, 0x74, 0xfc, 0x36, 0x70, 0xe2, 0xb7, 0xbe, 0x28, 0x79, 0x70, 0x6a, 0xba, 0xbc, + 0x46, 0x15, 0x13, 0x0e, 0x64, 0x7c, 0x06, 0x4c, 0x0c, 0x44, 0xa2, 0xf0, 0x35, 0x57, 0xbf, 0x83, + 0x11, 0xa4, 0x07, 0x6c, 0x35, 0x5a, 0xc0, 0xa2, 0x03, 0x70, 0x02, 0x0b, 0x8f, 0x41, 0x3a, 0xd4, + 0x6a, 0xe4, 0x6e, 0xd2, 0xb9, 0x46, 0xc0, 0x2e, 0xe2, 0x93, 0x2f, 0xcd, 0x2f, 0x4a, 0xbc, 0xdb, + 0xb9, 0x86, 0x48, 0xbd, 0x68, 0x40, 0x3a, 0x76, 0x1d, 0xa5, 0x7e, 0x0b, 0xf8, 0x90, 0x88, 0xc8, + 0xd4, 0x67, 0x51, 0xf0, 0xe0, 0x71, 0x44, 0x79, 0xe2, 0xb6, 0x95, 0x30, 0x11, 0x9a, 0xc8, 0x8c, + 0xe8, 0x1b, 0xc2, 0xad, 0x0e, 0x79, 0xea, 0x40, 0x20, 0x1d, 0x03, 0x28, 0xd4, 0xf6, 0x10, 0x10, + 0x14, 0x97, 0x43, 0x4a, 0x7b, 0xea, 0x26, 0x35, 0x1b, 0x16, 0x4f, 0x2a, 0x81, 0xea, 0x06, 0x9c, + 0x19, 0x88, 0x11, 0xc0, 0xd4, 0x2e, 0x4a, 0x02, 0x7f, 0x26, 0x60, 0xc4, 0xa1, 0x8b, 0x93, 0x45, + 0x30, 0x40, 0xa8, 0x9e, 0x02, 0xa7, 0x0f, 0x80, 0xd3, 0x0a, 0xd3, 0x30, 0x99, 0x5c, 0x9c, 0x22, + 0xa8, 0xd4, 0x03, 0x01, 0x02, 0x4f, 0xf2, 0x39, 0xc4, 0x86, 0x42, 0x9e, 0x21, 0xbd, 0x70, 0xbf, + 0x54, 0xf8, 0x3c, 0x9b, 0x51, 0xdc, 0x39, 0xc5, 0x6a, 0x59, 0x7d, 0x38, 0xad, 0x59, 0x15, 0xa7, + 0x42, 0x60, 0xf0, 0x1e, 0x58, 0x32, 0xc0, 0x62, 0x83, 0x97, 0x08, 0x89, 0x19, 0x17, 0x1f, 0x7a, + 0xd9, 0xce, 0xe1, 0x28, 0x05, 0x64, 0x98, 0xd5, 0x17, 0x1f, 0xa4, 0xac, 0x8a, 0x18, 0x35, 0x26, + 0x58, 0x98, 0x50, 0xa4, 0x80, 0x01, 0x48, 0x38, 0x0f, 0x25, 0x02, 0xa6, 0x11, 0x25, 0xb4, 0x7e, + 0x8d, 0x22, 0x5e, 0x77, 0x09, 0x68, 0x48, 0xeb, 0x65, 0xfd, 0xe2, 0xf0, 0xc0, 0x5a, 0x1c, 0x70, + 0xd6, 0xbb, 0x66, 0x1b, 0xa3, 0x39, 0xbb, 0xc8, 0xc4, 0x37, 0x0e, 0xf2, 0xa0, 0x08, 0xe8, 0x31, + 0x08, 0xa8, 0x1a, 0xa9, 0x16, 0x4e, 0x7b, 0xf1, 0xfc, 0x29, 0x51, 0x7a, 0xd3, 0xa7, 0x17, 0xeb, + 0x56, 0xae, 0x0a, 0xb7, 0xbd, 0xdd, 0xc5, 0x67, 0xed, 0x55, 0x5f, 0x04, 0xe6, 0xdc, 0x56, 0x9d, + 0x3e, 0x97, 0xe2, 0x44, 0x9d, 0x8d, 0xb6, 0x25, 0xfb, 0xfc, 0x25, 0xac, 0x98, 0xd6, 0x97, 0x90, + 0xca, 0xa2, 0x78, 0xec, 0xf1, 0x7c, 0xcc, 0x5e, 0xc7, 0xc4, 0xc2, 0x82, 0xd6, 0xef, 0x77, 0x77, + 0xbf, 0x77, 0x63, 0xe2, 0xe9, 0xbf, 0x77, 0x7f, 0x08, 0x91, 0x56, 0xd0, 0xdb, 0xe2, 0xba, 0x82, + 0x2d, 0xb2, 0x6f, 0xe1, 0x03, 0x6a, 0x7f, 0xf7, 0x77, 0xbd, 0x0f, 0xc1, 0x3d, 0x96, 0x2f, 0x7b, + 0xdc, 0x78, 0x50, 0x4d, 0x73, 0x57, 0xe9, 0x9f, 0xd6, 0xb9, 0x35, 0x3f, 0x13, 0xe0, 0xb2, 0x7f, + 0xaa, 0x56, 0x6d, 0xe9, 0xab, 0x3e, 0x14, 0xc5, 0xd2, 0x26, 0x76, 0x1d, 0x62, 0x3a, 0xb4, 0xda, + 0x93, 0x25, 0xb4, 0xa1, 0x89, 0x85, 0x3d, 0x48, 0x87, 0x58, 0x1b, 0xa5, 0x7a, 0x6b, 0xd3, 0x09, + 0x2b, 0xc2, 0x34, 0x2a, 0xe7, 0x01, 0xb3, 0x55, 0xc4, 0x50, 0x50, 0x16, 0x76, 0x84, 0xa9, 0xa1, + 0xe3, 0xfe, 0x61, 0x88, 0x8e, 0xe6, 0xbb, 0xed, 0x32, 0xce, 0xc7, 0x57, 0xd2, 0x44, 0x3c, 0x45, + 0x31, 0x6a, 0xd7, 0x85, 0x0b, 0x59, 0x20, 0xed, 0xab, 0x79, 0x7c, 0x25, 0xaa, 0x94, 0x49, 0x12, + 0x89, 0x26, 0xd7, 0x3c, 0x3c, 0xbe, 0x0a, 0xc9, 0xd6, 0x5b, 0xea, 0x4c, 0x27, 0x35, 0x35, 0x7f, + 0x82, 0xb3, 0x17, 0x76, 0xb5, 0x17, 0x55, 0xe1, 0x1f, 0x0f, 0x42, 0x92, 0x80, 0xbc, 0xef, 0x6a, + 0xcf, 0xfa, 0x51, 0xef, 0x16, 0xde, 0x54, 0xe0, 0x40, 0x3f, 0xd4, 0x9f, 0x6f, 0xc1, 0x59, 0x16, + 0x6c, 0x5d, 0x66, 0xf1, 0xc5, 0xba, 0xbc, 0xcb, 0xc1, 0x19, 0xe7, 0x26, 0xdd, 0xbe, 0x2f, 0x55, + 0x36, 0x2e, 0x57, 0x11, 0x04, 0x13, 0x21, 0x2a, 0x95, 0x12, 0x42, 0x50, 0xcd, 0x0d, 0x8c, 0x72, + 0x2b, 0x5e, 0xd8, 0x9b, 0x1f, 0x12, 0x36, 0xa7, 0x0f, 0x53, 0xbf, 0xad, 0x96, 0xa1, 0xac, 0xd8, + 0xab, 0xa1, 0x42, 0x54, 0xa8, 0x8f, 0x0b, 0x8c, 0xd2, 0x63, 0x8e, 0x3c, 0x5e, 0xbf, 0x1a, 0x42, + 0x4f, 0x29, 0xe6, 0x66, 0xb8, 0xe4, 0xe4, 0xca, 0xf5, 0x9d, 0x4b, 0x91, 0x39, 0x8a, 0xf5, 0xb9, + 0xf8, 0xf1, 0x8f, 0xe1, 0xe2, 0xdc, 0xaf, 0x45, 0x9b, 0x61, 0xec, 0xd7, 0x3e, 0x5d, 0x86, 0x95, + 0xbc, 0x0d, 0xcb, 0x65, 0xff, 0xfc, 0x6d, 0xe2, 0x35, 0x01, 0x99, 0x78, 0xce, 0x1c, 0x42, 0xf9, + 0x41, 0x0c, 0x0e, 0xcd, 0xf5, 0xc8, 0xe9, 0x53, 0xa9, 0x3a, 0xe6, 0x66, 0xfa, 0xb2, 0x52, 0x5e, + 0x7f, 0xf0, 0xb6, 0x88, 0x6a, 0xa0, 0xac, 0xd8, 0x82, 0xb4, 0x64, 0xc7, 0x9e, 0xba, 0xe7, 0xb1, + 0x5d, 0x9f, 0x4e, 0x6c, 0xcd, 0xbe, 0xdc, 0xa8, 0x80, 0x62, 0x34, 0x82, 0x83, 0x15, 0x80, 0x7b, + 0x72, 0xa0, 0x1e, 0xfa, 0x5c, 0xcc, 0xb2, 0xea, 0x41, 0x59, 0x51, 0x05, 0xe0, 0x9e, 0x09, 0x8a, + 0x97, 0xfa, 0xaa, 0x03, 0x88, 0x84, 0xfe, 0x41, 0xcc, 0x17, 0xa0, 0xff, 0x8b, 0x9b, 0xc0, 0xec, + 0x77, 0xc2, 0xab, 0x05, 0x81, 0x6d, 0xca, 0xe7, 0xaf, 0xe0, 0x80, 0x22, 0x14, 0xb9, 0x0a, 0x94, + 0x45, 0x55, 0xb6, 0x38, 0x94, 0x7e, 0xf2, 0xa8, 0xd9, 0xbd, 0xda, 0x8c, 0x73, 0x41, 0xa2, 0x28, + 0x6b, 0xd6, 0xe4, 0x03, 0x10, 0x1d, 0xec, 0x83, 0xda, 0xc3, 0x80, 0x39, 0x07, 0x14, 0xd4, 0x98, + 0x03, 0x85, 0x0b, 0xdc, 0x32, 0x24, 0x6f, 0x7c, 0x2d, 0x90, 0x5d, 0x8e, 0x72, 0x6b, 0xcd, 0xc6, + 0xe0, 0x1b, 0x8c, 0x66, 0x65, 0x21, 0x3f, 0x64, 0xc0, 0x00, 0x40, 0x08, 0xdd, 0xc0, 0x8f, 0xa4, + 0x82, 0x84, 0xe8, 0x2e, 0xc8, 0x66, 0xab, 0x85, 0xcf, 0xa7, 0x48, 0xfd, 0x6f, 0xfd, 0x1c, 0x04, + 0xaa, 0x09, 0xe4, 0x55, 0xd5, 0xda, 0xbc, 0x96, 0x02, 0xfe, 0xf2, 0xff, 0x0a, 0x5b, 0x85, 0x00, + 0x10, 0x0c, 0x1f, 0xa2, 0x05, 0x80, 0xb4, 0x78, 0xe6, 0xea, 0x74, 0xa9, 0x65, 0x00, 0x3c, 0x77, + 0xa1, 0xb2, 0x63, 0x4b, 0x3e, 0xd6, 0x26, 0x80, 0x79, 0x6b, 0xb4, 0xe8, 0x1f, 0xc4, 0x0e, 0x12, + 0xaf, 0x94, 0x83, 0x90, 0xb0, 0xac, 0x2f, 0x70, 0xe6, 0x73, 0xb6, 0x93, 0x80, 0x15, 0x66, 0x51, + 0x78, 0xa8, 0x07, 0x38, 0x80, 0x50, 0x14, 0x94, 0xc8, 0x4f, 0x03, 0xcf, 0x60, 0x42, 0x61, 0xe1, + 0xff, 0x2f, 0x8a, 0xd1, 0x5c, 0x09, 0x6d, 0x81, 0xeb, 0x80, 0x00, 0x40, 0x6b, 0xa1, 0x28, 0x54, + 0xca, 0x73, 0xc8, 0xc6, 0xa1, 0xcc, 0x0d, 0x46, 0x2a, 0x71, 0x22, 0x42, 0x9a, 0xd5, 0xcb, 0x80, + 0x29, 0x19, 0xc4, 0x8d, 0x20, 0x86, 0x80, 0x47, 0x0c, 0x32, 0x2d, 0xf4, 0xd9, 0xdf, 0x81, 0xe9, + 0x1c, 0x36, 0x3d, 0x6a, 0xce, 0x7b, 0x79, 0x6d, 0xf5, 0x45, 0x98, 0xc9, 0x85, 0x4f, 0x00, 0x70, + 0x7c, 0x29, 0x31, 0x85, 0x0c, 0xd4, 0x33, 0x86, 0x08, 0x67, 0x0d, 0x04, 0xef, 0x09, 0xf1, 0x27, + 0x24, 0x21, 0xbe, 0x65, 0xd2, 0xc5, 0xe8, 0xd8, 0x56, 0x15, 0x56, 0xe3, 0x95, 0x24, 0x58, 0x13, + 0x82, 0xaf, 0xb0, 0xae, 0x0a, 0xa4, 0xc5, 0x51, 0x94, 0x0b, 0x86, 0x94, 0x21, 0x8e, 0xc1, 0x5e, + 0x19, 0x08, 0x8d, 0xae, 0xa2, 0x94, 0x0b, 0xb4, 0x32, 0x61, 0x69, 0x3f, 0x85, 0x46, 0x99, 0x28, + 0x78, 0x3b, 0xa5, 0xf3, 0x0e, 0xa1, 0xbe, 0x2b, 0x41, 0x54, 0x9c, 0x3e, 0x84, 0xf3, 0xd7, 0x5a, + 0x48, 0x8d, 0x44, 0x9a, 0xff, 0xe3, 0xf8, 0x22, 0x8b, 0xae, 0xdf, 0x04, 0xc5, 0xc9, 0xe4, 0xe9, + 0xec, 0xf8, 0xeb, 0xdd, 0xb5, 0xad, 0xdf, 0xf1, 0x57, 0x7d, 0xef, 0x5c, 0xc7, 0x7d, 0xfc, 0x16, + 0x08, 0x2c, 0x2a, 0xb3, 0x79, 0xbb, 0x14, 0x6c, 0x50, 0xbd, 0x5c, 0x22, 0x2e, 0xee, 0xe2, 0xb7, + 0x7d, 0xc7, 0x71, 0xf8, 0x26, 0x96, 0x9f, 0xbb, 0xcb, 0xe3, 0xb7, 0x77, 0x47, 0x92, 0x8e, 0xe1, + 0x65, 0xad, 0x5e, 0x0b, 0x08, 0xe1, 0x23, 0x3f, 0xb2, 0xf8, 0xaf, 0x5b, 0xbb, 0xbf, 0xc7, 0xd3, + 0xae, 0x5c, 0x7d, 0x75, 0x5a, 0x9b, 0x3c, 0x14, 0xd6, 0xb6, 0xab, 0xad, 0x5f, 0xe3, 0xec, 0x6c, + 0x96, 0xce, 0x4e, 0xda, 0xab, 0x6b, 0xe2, 0x6d, 0xaa, 0xd0, 0xa9, 0xaf, 0x85, 0x29, 0x2f, 0x3a, + 0xde, 0x9d, 0x52, 0x6d, 0x3b, 0xc4, 0x4d, 0x7d, 0x7c, 0x4e, 0xaa, 0xa2, 0x38, 0xcc, 0xfe, 0x3a, + 0x9f, 0x74, 0xaf, 0xad, 0x71, 0x11, 0x57, 0x2a, 0x27, 0x8a, 0xd2, 0xfc, 0x16, 0x66, 0x9d, 0x26, + 0x53, 0xe5, 0x9b, 0x93, 0x34, 0xe3, 0xe1, 0x41, 0x06, 0x85, 0x1e, 0x88, 0xb5, 0x81, 0x2a, 0xb9, + 0x11, 0x98, 0xd8, 0xec, 0x66, 0xb2, 0x7a, 0x6d, 0xf0, 0x55, 0x35, 0x59, 0xad, 0xde, 0x2e, 0xb2, + 0x6b, 0x69, 0x0c, 0xb1, 0xaf, 0x8d, 0xae, 0xd0, 0xd6, 0x96, 0xa5, 0x47, 0x50, 0xe0, 0xdb, 0x8a, + 0xdf, 0x21, 0xc6, 0xb6, 0xc3, 0x7a, 0x5b, 0x4c, 0x8b, 0x42, 0xb8, 0xb6, 0xad, 0xbb, 0x6e, 0xbe, + 0x14, 0x25, 0x1c, 0xd8, 0xa9, 0x2d, 0x1a, 0x8c, 0xa7, 0x48, 0xd9, 0x0d, 0xc4, 0x19, 0x4a, 0x38, + 0x81, 0x01, 0x43, 0x97, 0xc9, 0x32, 0x21, 0x8f, 0x7a, 0x9d, 0xf2, 0x87, 0x1c, 0xb0, 0x82, 0xb6, + 0x73, 0x50, 0x56, 0x5f, 0x1e, 0x74, 0x64, 0xa2, 0xf1, 0x23, 0x0b, 0x4b, 0xaf, 0xb3, 0x17, 0x25, + 0xbb, 0xc4, 0x82, 0xab, 0x79, 0xfc, 0x57, 0x6c, 0xed, 0x33, 0x53, 0x38, 0x0c, 0xe9, 0x62, 0xbc, + 0xab, 0x83, 0x0b, 0x88, 0x10, 0x32, 0x90, 0x0d, 0x70, 0x69, 0xc6, 0x9d, 0xf4, 0x20, 0x5b, 0x87, + 0x15, 0x50, 0x7a, 0xa0, 0x1c, 0xdd, 0x49, 0xa0, 0x62, 0x2f, 0x6b, 0x80, 0x56, 0x36, 0xed, 0xc8, + 0x57, 0x96, 0xc0, 0xa0, 0xce, 0x40, 0xf0, 0x07, 0x93, 0x55, 0xd1, 0xa5, 0x42, 0xd0, 0x77, 0xba, + 0x06, 0x98, 0x60, 0x18, 0x0c, 0xb3, 0x11, 0x91, 0x2e, 0x9e, 0xcc, 0x1e, 0x2e, 0x4a, 0xe4, 0x4a, + 0x07, 0x03, 0xa1, 0x63, 0xd8, 0x2d, 0x96, 0x0c, 0x43, 0xc9, 0xf8, 0x0f, 0xd2, 0x92, 0xaa, 0x3b, + 0xfc, 0x22, 0x08, 0x42, 0x93, 0xc7, 0xde, 0xe7, 0xbe, 0x3b, 0x06, 0x75, 0x6e, 0x3e, 0x05, 0xbb, + 0xdb, 0x2d, 0xf8, 0x64, 0x32, 0x14, 0x9c, 0x34, 0x2d, 0xa3, 0x04, 0x6f, 0xa1, 0xc3, 0xcb, 0x6f, + 0xc3, 0x96, 0xbb, 0x0b, 0x50, 0xa6, 0x28, 0x65, 0x5b, 0xc8, 0xc0, 0x33, 0xa2, 0xc0, 0xca, 0xd2, + 0xc7, 0xe2, 0x42, 0x23, 0x62, 0x80, 0x21, 0x90, 0x80, 0xb8, 0x00, 0x82, 0x06, 0xa8, 0x85, 0xba, + 0x90, 0x41, 0x92, 0xe5, 0x30, 0x05, 0x06, 0xde, 0x6d, 0x34, 0x2d, 0x80, 0x00, 0x80, 0x15, 0x22, + 0x00, 0x58, 0x22, 0x99, 0x8e, 0x96, 0x83, 0x8d, 0xa4, 0xb6, 0x05, 0xd9, 0x6c, 0x6a, 0xe6, 0x56, + 0x27, 0x80, 0x49, 0xf3, 0xa0, 0xa2, 0xe1, 0x20, 0x70, 0xb2, 0xc0, 0x00, 0x40, 0x13, 0x09, 0x63, + 0x00, 0x97, 0x07, 0x81, 0x43, 0x06, 0x51, 0xf6, 0xd3, 0x16, 0xf1, 0x21, 0x90, 0xa4, 0x98, 0x0a, + 0x96, 0x19, 0x30, 0x00, 0x78, 0xeb, 0x06, 0xb1, 0xa0, 0xa2, 0x03, 0xf7, 0x7c, 0x80, 0x60, 0x0b, + 0x61, 0x09, 0x58, 0x95, 0x95, 0x3c, 0x4d, 0x13, 0xdb, 0xc1, 0x6b, 0x24, 0x4c, 0xb8, 0x73, 0xdb, + 0x03, 0x84, 0x17, 0xa6, 0x80, 0x96, 0xd3, 0xfb, 0x38, 0x90, 0xc8, 0xc8, 0xe2, 0x0f, 0x06, 0x8e, + 0x18, 0xcf, 0x96, 0x68, 0xf8, 0x74, 0xc5, 0xfd, 0x61, 0xfc, 0x78, 0xa4, 0x2b, 0x64, 0x23, 0xe4, + 0x9e, 0x0e, 0x1f, 0xa3, 0x2a, 0x73, 0xe6, 0x83, 0xe2, 0x46, 0xd9, 0x2a, 0x45, 0x83, 0x1b, 0x5d, + 0xb6, 0xad, 0x95, 0x56, 0x9a, 0x69, 0x22, 0x0a, 0xb8, 0xa8, 0x75, 0x66, 0x8c, 0x57, 0xe1, 0x0e, + 0x69, 0x98, 0xef, 0x9a, 0xea, 0xff, 0x45, 0x7f, 0x85, 0x08, 0xa5, 0xfc, 0xa6, 0xb1, 0x5b, 0xbd, + 0xd5, 0xdd, 0x8f, 0x89, 0x3d, 0xcc, 0xc7, 0x47, 0x6c, 0xd9, 0xe1, 0x12, 0xa9, 0xf1, 0x6e, 0xcf, + 0x94, 0x95, 0x75, 0x5f, 0x62, 0x0a, 0xc5, 0xf5, 0xc5, 0x77, 0x6f, 0x3e, 0x7c, 0x22, 0x4a, 0xd6, + 0x6c, 0x6d, 0x8a, 0x57, 0x1f, 0xc2, 0x82, 0xe6, 0x86, 0x30, 0x99, 0x98, 0xcb, 0xb5, 0x3a, 0xee, + 0xf9, 0x3a, 0xf7, 0xc7, 0x52, 0x45, 0x8d, 0x28, 0xe2, 0xf9, 0xaf, 0x26, 0xc2, 0xff, 0x05, 0x76, + 0x8f, 0xb2, 0x5f, 0xa4, 0x42, 0x26, 0x5d, 0x25, 0x1e, 0xdf, 0xe3, 0x2d, 0xa9, 0xbe, 0xd3, 0x5c, + 0x5b, 0x4f, 0x6b, 0xe2, 0x75, 0x3e, 0x47, 0x1d, 0x41, 0xfc, 0xd5, 0xdf, 0xc2, 0x1d, 0x57, 0x2d, + 0xb2, 0xd2, 0x5f, 0x09, 0xc5, 0xd6, 0x6e, 0xab, 0xf8, 0xc9, 0x20, 0xb4, 0xb4, 0x92, 0xae, 0x6e, + 0xa8, 0x7b, 0x5e, 0x0a, 0x37, 0x7b, 0xe9, 0x37, 0xc1, 0x65, 0xe3, 0x98, 0xe1, 0x31, 0x22, 0xf3, + 0x72, 0x92, 0xa6, 0xa5, 0xf9, 0x9a, 0x5f, 0x84, 0xc5, 0x35, 0x47, 0x5a, 0x19, 0x7b, 0xa5, 0xf0, + 0xa5, 0x1a, 0x87, 0x52, 0xde, 0xf8, 0x3b, 0x29, 0x8e, 0x02, 0x13, 0x3f, 0x43, 0x60, 0x82, 0x6e, + 0xd5, 0x0e, 0xa2, 0xb4, 0x78, 0xcf, 0x85, 0x3a, 0x6e, 0x29, 0x41, 0x9d, 0xcb, 0xa9, 0xbd, 0x9c, + 0x20, 0x8d, 0xaa, 0x84, 0x20, 0xd1, 0xf0, 0x1a, 0x7d, 0xf1, 0x47, 0x68, 0xf9, 0xee, 0xfe, 0x4e, + 0xa6, 0xfe, 0x0a, 0xc8, 0xd3, 0x4e, 0xcd, 0xb6, 0x74, 0x83, 0x5e, 0x74, 0x62, 0xa7, 0x87, 0xcb, + 0x65, 0x1c, 0x62, 0xd7, 0xf1, 0x20, 0xb0, 0x86, 0x63, 0x78, 0x3c, 0xc9, 0xa6, 0x45, 0x9d, 0x98, + 0x65, 0x5a, 0x5d, 0x99, 0x7a, 0x9e, 0x58, 0x2c, 0xca, 0x0c, 0x35, 0x16, 0x00, 0x10, 0x06, 0x3a, + 0x22, 0x6b, 0x47, 0x26, 0xfe, 0x3c, 0xd1, 0xb5, 0x38, 0xd0, 0xf7, 0x9e, 0x3c, 0x94, 0xe0, 0xf7, + 0x9f, 0xf5, 0xbf, 0xcf, 0xe3, 0xf9, 0x13, 0x0c, 0xa8, 0x01, 0x31, 0xfc, 0xc0, 0xc9, 0xdb, 0x84, + 0x6d, 0x9a, 0xd3, 0x55, 0x1e, 0xf8, 0xe4, 0xfc, 0x67, 0x3e, 0x0e, 0xdc, 0xbf, 0x1d, 0xbb, 0xf8, + 0xab, 0x2c, 0x5c, 0xfc, 0x22, 0x24, 0x29, 0x5f, 0x74, 0xe0, 0x70, 0x85, 0x66, 0x9a, 0x48, 0xbd, + 0x20, 0x75, 0xb0, 0x76, 0x7c, 0x4b, 0x06, 0x63, 0xc9, 0xc8, 0x2a, 0x68, 0x20, 0x19, 0x56, 0x3c, + 0x0d, 0x03, 0xfd, 0x4a, 0x2c, 0xc9, 0xb5, 0x32, 0xc7, 0x74, 0x77, 0x89, 0x08, 0x85, 0x04, 0x6d, + 0xb6, 0xd8, 0xb9, 0xe5, 0x81, 0xaa, 0x8e, 0x39, 0x5e, 0xdc, 0x9b, 0xe4, 0x8c, 0xf7, 0x70, 0xbb, + 0x84, 0x41, 0x08, 0x50, 0xd1, 0xe0, 0x65, 0x08, 0xe7, 0x1f, 0x73, 0x0a, 0xff, 0x13, 0x66, 0x43, + 0x52, 0x1a, 0x0c, 0x7d, 0xf4, 0x92, 0x6c, 0x8a, 0xb7, 0xb0, 0xfb, 0x5e, 0xf0, 0x88, 0xc3, 0xee, + 0x18, 0xe0, 0x65, 0xf9, 0xc6, 0x5c, 0xd7, 0x4e, 0x7b, 0xa7, 0x7a, 0x10, 0x07, 0xa2, 0xa8, 0x80, + 0x01, 0x98, 0x6c, 0x39, 0xc7, 0x72, 0xc0, 0xf6, 0xe7, 0x1c, 0xf1, 0x82, 0x4b, 0x0d, 0x66, 0x09, + 0xbc, 0xc5, 0x2b, 0x9d, 0x0b, 0x58, 0xb0, 0xdb, 0x66, 0x70, 0x60, 0x2f, 0x4a, 0x32, 0xce, 0x39, + 0x2e, 0xa1, 0x7b, 0x88, 0x78, 0x44, 0x28, 0x21, 0xed, 0xe6, 0xfc, 0xd5, 0x5d, 0x8a, 0xcc, 0x95, + 0x27, 0x02, 0xb9, 0xa4, 0x5d, 0xe3, 0xfc, 0x2d, 0x97, 0x00, 0xec, 0x4b, 0x8c, 0xa9, 0x48, 0x67, + 0x0c, 0x07, 0x43, 0x84, 0x5c, 0x45, 0x40, 0x61, 0x45, 0xe1, 0x0e, 0x08, 0x4e, 0x2e, 0xa4, 0x63, + 0x67, 0xc1, 0x1e, 0x5e, 0x4f, 0x6f, 0xe2, 0x07, 0xd3, 0xa7, 0x51, 0x1c, 0xa4, 0xd1, 0xf3, 0xf1, + 0x04, 0x27, 0xb1, 0x4e, 0x2b, 0xfd, 0x1d, 0x8e, 0x26, 0x11, 0x11, 0x74, 0xeb, 0xa4, 0xb4, 0xbe, + 0x2b, 0x6a, 0xa9, 0xb7, 0x26, 0x78, 0x92, 0x93, 0xdd, 0x96, 0x7b, 0xaa, 0x9f, 0x8a, 0x29, 0x7d, + 0xee, 0x8f, 0xf0, 0x44, 0x21, 0xe7, 0xed, 0x77, 0xc7, 0xcf, 0xe2, 0xeb, 0x9f, 0x6a, 0xbf, 0x08, + 0x4b, 0x9a, 0xe5, 0xe5, 0x76, 0x96, 0xbe, 0x0b, 0x86, 0xa4, 0x4c, 0x57, 0x62, 0xc5, 0xf2, 0xf1, + 0x21, 0x4e, 0xab, 0x50, 0x9f, 0x5a, 0xd4, 0x5d, 0x6a, 0xcf, 0xf7, 0xc4, 0x93, 0x35, 0x09, 0xdb, + 0x71, 0xfe, 0x3a, 0xd9, 0x76, 0x7b, 0xb6, 0xeb, 0x3d, 0x0e, 0x45, 0xe4, 0xbc, 0x13, 0xec, 0xcd, + 0xba, 0x59, 0xbf, 0x7c, 0x15, 0xfa, 0x99, 0x86, 0x5c, 0x9b, 0x55, 0x0e, 0xd7, 0xbe, 0x09, 0x4a, + 0x2e, 0x84, 0xb3, 0x7a, 0xfd, 0xf0, 0x94, 0x5c, 0x9f, 0xe3, 0x35, 0xf1, 0x20, 0xb2, 0xcc, 0xf6, + 0x6c, 0xea, 0x6f, 0x31, 0x49, 0xda, 0x73, 0xe1, 0x42, 0x66, 0xf6, 0xe6, 0xb5, 0x17, 0x9b, 0xcb, + 0x8b, 0xb9, 0xf0, 0x80, 0x81, 0xef, 0x4c, 0x88, 0x39, 0xcd, 0xcd, 0x61, 0xda, 0x8f, 0x73, 0x98, + 0xfc, 0x29, 0x8d, 0xd9, 0x6b, 0x54, 0xd5, 0x55, 0xaf, 0xf5, 0x54, 0xd7, 0x19, 0x7a, 0xb7, 0x97, + 0x9f, 0x0f, 0xd6, 0x4b, 0xd3, 0x10, 0x0c, 0x49, 0x84, 0xfc, 0x7f, 0xdd, 0xbe, 0xbe, 0x2a, 0xff, + 0x82, 0x93, 0xad, 0x6e, 0x93, 0xb4, 0x96, 0x92, 0x41, 0xf1, 0x37, 0xb4, 0xc0, 0xeb, 0x5f, 0x0a, + 0x5b, 0x1b, 0x72, 0x58, 0x6b, 0x8f, 0x29, 0x91, 0x06, 0xad, 0x44, 0xdc, 0x6a, 0xd9, 0x49, 0x37, + 0x59, 0x05, 0x24, 0x26, 0x92, 0x75, 0x58, 0xf8, 0x50, 0xdc, 0x7d, 0xb8, 0xe6, 0xb7, 0x0c, 0x3b, + 0xaa, 0xaf, 0xeb, 0x7c, 0x66, 0xfa, 0x8b, 0xf9, 0x14, 0x3f, 0x19, 0x93, 0x0c, 0x91, 0x6c, 0x90, + 0x1c, 0xde, 0x0f, 0x8c, 0xb0, 0xd3, 0x7b, 0x04, 0xec, 0x4f, 0x2c, 0xd3, 0x06, 0x54, 0xa2, 0xcf, + 0x10, 0x08, 0x42, 0x25, 0xba, 0xdc, 0xec, 0x51, 0x75, 0x6f, 0x0c, 0x82, 0x91, 0x99, 0x17, 0x51, + 0x74, 0xc2, 0xbc, 0xac, 0xc1, 0x4c, 0x5c, 0x53, 0x14, 0xf1, 0xc5, 0x76, 0x78, 0x50, 0x45, 0xe0, + 0x07, 0x8f, 0x07, 0x8e, 0x5f, 0x26, 0x00, 0x5d, 0x1e, 0xfe, 0x7a, 0x19, 0x08, 0xef, 0xa7, 0xf9, + 0x66, 0xec, 0xbc, 0xb8, 0xe7, 0x11, 0x19, 0x07, 0x7d, 0xa8, 0xe2, 0x41, 0x50, 0xa2, 0x1e, 0x70, + 0xf6, 0x69, 0x63, 0xdb, 0xcb, 0x87, 0x38, 0x5b, 0x15, 0x96, 0xc5, 0x78, 0x08, 0x00, 0x34, 0x05, + 0x0a, 0x0b, 0xa8, 0xd0, 0x44, 0x00, 0x1e, 0x01, 0x14, 0xf0, 0x06, 0x73, 0xa3, 0x00, 0xc0, 0x09, + 0x21, 0x04, 0x41, 0x14, 0xf0, 0x03, 0xc9, 0x40, 0x39, 0x0a, 0xa6, 0xd0, 0x40, 0x07, 0xa1, 0xa6, + 0x83, 0x9e, 0x52, 0xb0, 0x55, 0x1e, 0xa5, 0xca, 0x38, 0xc6, 0x78, 0x1c, 0x01, 0xc0, 0x50, 0xaa, + 0x18, 0x6a, 0x26, 0x2d, 0x24, 0xa0, 0xa0, 0x63, 0xba, 0x00, 0x04, 0x7c, 0x93, 0xe9, 0x28, 0xcb, + 0x88, 0xb0, 0x74, 0x61, 0x2c, 0x1f, 0x65, 0x60, 0x1a, 0xd4, 0x0f, 0xce, 0xf8, 0x94, 0x00, 0x09, + 0xa9, 0x46, 0x59, 0xc0, 0x00, 0xcb, 0x44, 0xe0, 0x7a, 0xe1, 0x1a, 0xf8, 0x81, 0x84, 0x25, 0x06, + 0xa2, 0xc6, 0x3b, 0xf3, 0xf8, 0x28, 0xce, 0x1a, 0x0e, 0xd9, 0x51, 0x33, 0xa9, 0xe0, 0x71, 0xe3, + 0xc7, 0xac, 0x2c, 0x0c, 0x2c, 0x55, 0x98, 0x1f, 0xcb, 0x86, 0x21, 0x48, 0xe9, 0xe0, 0xe8, 0xed, + 0xb9, 0x16, 0x6d, 0x4f, 0x1a, 0x1f, 0xd4, 0x63, 0xa5, 0x53, 0xf5, 0x97, 0x0f, 0x1c, 0x95, 0x4c, + 0x73, 0xe3, 0x64, 0xa0, 0xa9, 0xe0, 0xe1, 0x68, 0x1f, 0x7f, 0x06, 0xad, 0x75, 0x8b, 0x9e, 0x0e, + 0x25, 0x78, 0x7f, 0xc6, 0x50, 0x1a, 0x8e, 0x1c, 0xe9, 0x96, 0xff, 0x08, 0xb6, 0x9a, 0xfd, 0x51, + 0x13, 0x81, 0xb1, 0xe3, 0x38, 0x82, 0xad, 0x2a, 0xae, 0x4e, 0x4a, 0xaf, 0xe1, 0x32, 0xf5, 0x7b, + 0xdf, 0xca, 0x46, 0xd5, 0xb5, 0xf0, 0xa5, 0xdf, 0x5b, 0x69, 0xbb, 0xdd, 0x54, 0xfd, 0xdc, 0x5a, + 0x6f, 0x8b, 0x39, 0xb6, 0xea, 0xa7, 0xcd, 0xfc, 0x70, 0xa9, 0x7e, 0x4e, 0xd2, 0xf7, 0x56, 0x3f, + 0xe4, 0x17, 0x6d, 0xaf, 0x84, 0x05, 0x32, 0x9a, 0xf5, 0x6c, 0x5d, 0x7f, 0x30, 0xb7, 0x77, 0xf8, + 0x27, 0x10, 0x7c, 0x15, 0xdd, 0xc4, 0x3e, 0x9e, 0xbe, 0x3b, 0x88, 0x1c, 0xae, 0xdb, 0xfb, 0xd9, + 0xff, 0x8a, 0x25, 0x6a, 0xeb, 0x5f, 0x09, 0x04, 0x73, 0x75, 0x66, 0x7a, 0x52, 0xf0, 0x45, 0x6a, + 0xab, 0xef, 0x08, 0x0c, 0x26, 0x98, 0xda, 0xcb, 0xfe, 0xb5, 0x5a, 0xaf, 0xc2, 0x35, 0xda, 0x8a, + 0xf6, 0xcd, 0x85, 0xd6, 0xef, 0x82, 0x92, 0x29, 0x28, 0x93, 0x35, 0x78, 0x69, 0x4b, 0xb3, 0xfb, + 0xe3, 0xe4, 0x63, 0x83, 0x4d, 0x26, 0xe5, 0x12, 0x57, 0x30, 0xd7, 0xe0, 0xac, 0xe4, 0xb5, 0xa3, + 0x6a, 0x29, 0xb1, 0xa2, 0x67, 0xbf, 0xc4, 0x45, 0x7d, 0xd5, 0xa8, 0x9a, 0x4f, 0x19, 0x66, 0x65, + 0xe6, 0xc5, 0xeb, 0x49, 0x69, 0x2a, 0xfd, 0x58, 0xe2, 0x23, 0xc5, 0x48, 0xa6, 0x9b, 0xfc, 0xb6, + 0x51, 0x02, 0x8f, 0x5f, 0x85, 0x23, 0x27, 0x4d, 0x6a, 0x8a, 0x3b, 0xe3, 0xaa, 0x65, 0x1a, 0x1c, + 0x7d, 0xe7, 0xc2, 0x50, 0x95, 0xdc, 0xce, 0x3e, 0x34, 0xfc, 0x6b, 0xab, 0xb7, 0xbb, 0x06, 0x3a, + 0xd9, 0xa9, 0xcf, 0x5f, 0x74, 0xdf, 0xe0, 0xa3, 0xcb, 0x97, 0x7d, 0x7d, 0xd5, 0x7f, 0x36, 0xee, + 0xfe, 0x62, 0x56, 0xbe, 0x5a, 0xd2, 0x4b, 0x82, 0x01, 0xe6, 0x14, 0x31, 0x43, 0x8b, 0x42, 0x39, + 0x93, 0x00, 0x39, 0x07, 0xe6, 0xa3, 0x18, 0xf8, 0x87, 0x35, 0x8a, 0x16, 0x10, 0x8c, 0x28, 0xa6, + 0x23, 0x92, 0xcf, 0xda, 0x15, 0x92, 0x8a, 0xbb, 0x82, 0xc8, 0x19, 0x09, 0xb4, 0x7b, 0x96, 0x92, + 0x1a, 0x58, 0x7a, 0x40, 0x00, 0xa3, 0xed, 0x4c, 0x69, 0x33, 0x47, 0xff, 0xe5, 0x2f, 0x17, 0xc7, + 0x31, 0x39, 0xb8, 0xba, 0x97, 0x93, 0x97, 0xb3, 0x94, 0x5f, 0x1c, 0x0d, 0x4a, 0xce, 0xa6, 0xf5, + 0xef, 0x0e, 0x12, 0x00, 0xbc, 0xd0, 0x8e, 0x61, 0x17, 0xeb, 0x96, 0x73, 0xf7, 0xbd, 0x1d, 0xb7, + 0xc6, 0x2b, 0x11, 0xe2, 0x1e, 0x48, 0x70, 0xff, 0x65, 0x46, 0xc2, 0x42, 0x38, 0xdb, 0x52, 0x60, + 0x3f, 0x1c, 0x03, 0xfa, 0xe9, 0xff, 0x12, 0x18, 0x0a, 0x09, 0x2a, 0x6a, 0x94, 0xc6, 0xa2, 0x61, + 0xe7, 0x81, 0xe7, 0xac, 0x1a, 0xb1, 0xa3, 0xc5, 0x41, 0x63, 0x73, 0xcb, 0x22, 0x82, 0x7e, 0x0f, + 0xc0, 0x93, 0x29, 0x56, 0x3f, 0xe2, 0x52, 0x93, 0x05, 0x96, 0xb4, 0xea, 0x77, 0xa1, 0xc1, 0xf0, + 0x2e, 0x1e, 0x3a, 0x14, 0xf0, 0x24, 0x83, 0x90, 0xa4, 0xa8, 0x21, 0xd9, 0x3e, 0x00, 0xf3, 0x80, + 0x54, 0x16, 0x03, 0xeb, 0x75, 0x62, 0x19, 0x1a, 0xdb, 0x15, 0xd2, 0x9d, 0xd3, 0x6b, 0x11, 0xef, + 0xb5, 0x84, 0xce, 0x44, 0xa4, 0xd8, 0x42, 0x11, 0x83, 0x17, 0x83, 0x44, 0x49, 0x4f, 0x44, 0x11, + 0x9b, 0x54, 0x68, 0xac, 0x32, 0x0a, 0x42, 0x86, 0x3d, 0xe3, 0xfd, 0xb3, 0x81, 0x60, 0xe0, 0xc0, + 0xe0, 0xe3, 0x76, 0x2c, 0xb1, 0x0b, 0x9c, 0x09, 0x1c, 0xb0, 0x71, 0xe5, 0xac, 0x99, 0x26, 0xc8, + 0x98, 0x4e, 0x02, 0xa4, 0x35, 0x0c, 0x48, 0x64, 0x29, 0x0e, 0x85, 0x61, 0xf8, 0xa7, 0x2b, 0x23, + 0x39, 0xe3, 0xaf, 0xab, 0xf2, 0xfb, 0x86, 0xb0, 0x58, 0xc5, 0x18, 0xcb, 0x2e, 0x64, 0xc4, 0xdc, + 0xda, 0x3e, 0x9f, 0xb8, 0x90, 0x72, 0x33, 0x5d, 0x9c, 0xd2, 0xa8, 0x23, 0xf0, 0x50, 0x45, 0xbc, + 0x0e, 0x2f, 0xd8, 0x8b, 0x02, 0x8c, 0x75, 0x71, 0xb1, 0xed, 0xe8, 0x3b, 0x99, 0xac, 0x14, 0x80, + 0xd0, 0x65, 0xd3, 0x01, 0x2e, 0x84, 0xeb, 0xe3, 0x2e, 0xf7, 0xbe, 0xde, 0x7f, 0x7b, 0xfc, 0x14, + 0xc5, 0xc4, 0x1e, 0x6e, 0xce, 0xb2, 0x5e, 0xad, 0xb3, 0xd2, 0xeb, 0xe0, 0xa0, 0xcb, 0x5c, 0x5f, + 0xef, 0x82, 0x32, 0x93, 0xa6, 0xaa, 0xdf, 0x17, 0x6a, 0x24, 0xe1, 0xb2, 0xee, 0xfe, 0x3c, 0xc8, + 0x56, 0xee, 0xab, 0x5d, 0x57, 0xc2, 0x14, 0x9f, 0xba, 0x49, 0x6a, 0xbe, 0x28, 0x5b, 0x6a, 0xde, + 0xad, 0xaf, 0x8e, 0x29, 0x3a, 0xd3, 0x6d, 0x38, 0xb8, 0xd2, 0xf5, 0xfc, 0x59, 0x8a, 0x4a, 0x6c, + 0x4e, 0x95, 0xfc, 0x29, 0x89, 0xe4, 0xdf, 0x3f, 0x0b, 0x55, 0x1a, 0x9e, 0x89, 0xfa, 0xda, 0x65, + 0x77, 0x21, 0x62, 0x96, 0x94, 0x37, 0xaa, 0x35, 0x38, 0xe4, 0x0f, 0x19, 0xa7, 0xa6, 0x9b, 0x64, + 0xff, 0x89, 0x55, 0xa9, 0xb3, 0x11, 0x18, 0x72, 0xea, 0x4d, 0xb1, 0x93, 0x12, 0xed, 0x2f, 0x54, + 0xe8, 0x7e, 0x0a, 0x72, 0x86, 0x92, 0xab, 0x4a, 0x2f, 0x37, 0x0e, 0xe5, 0xde, 0x42, 0xff, 0x0a, + 0x6c, 0x6d, 0x26, 0xaa, 0xda, 0x1c, 0x65, 0x5a, 0xaa, 0xb5, 0xfb, 0xe2, 0x48, 0xdd, 0xb5, 0x6a, + 0xaa, 0xbb, 0xc9, 0x9f, 0x82, 0x59, 0x33, 0x5a, 0x56, 0x93, 0x77, 0xc2, 0x93, 0x67, 0x26, 0xca, + 0xaf, 0xc6, 0xaa, 0x7c, 0xf3, 0x65, 0xdd, 0xf0, 0xa5, 0x75, 0x54, 0x89, 0x8f, 0x6c, 0x62, 0x34, + 0x0a, 0xb3, 0x35, 0x36, 0xdb, 0xea, 0xd7, 0xcb, 0x12, 0xf7, 0xbf, 0x8b, 0xe7, 0xa2, 0x4b, 0x2e, + 0x1f, 0xf9, 0x89, 0xbb, 0xf8, 0x52, 0x3a, 0xc4, 0xe1, 0xe5, 0xb7, 0xe2, 0x43, 0x6b, 0x55, 0xbe, + 0xd3, 0xa1, 0xbe, 0xf5, 0xc7, 0x88, 0x8d, 0x2c, 0xc9, 0x5b, 0x88, 0x3b, 0xda, 0x36, 0x62, 0x44, + 0x8c, 0xe3, 0xca, 0xae, 0xe4, 0xe1, 0xb8, 0x30, 0x98, 0x25, 0x0b, 0xdd, 0x85, 0xea, 0xd7, 0x7e, + 0xe3, 0x86, 0x03, 0x0e, 0xbb, 0x01, 0x8c, 0x20, 0x11, 0x1b, 0x48, 0x44, 0x12, 0x93, 0x1e, 0xa5, + 0x2f, 0xe6, 0x66, 0xa1, 0x41, 0x41, 0x9a, 0x20, 0x05, 0xce, 0xb7, 0xc2, 0xa2, 0x3e, 0x67, 0xb7, + 0xc1, 0x80, 0x7b, 0xb0, 0x70, 0x03, 0xcf, 0x05, 0x97, 0xc0, 0xb0, 0xe1, 0xb8, 0x8a, 0x9b, 0xa2, + 0x00, 0x3e, 0xc1, 0x15, 0x3b, 0x9a, 0x97, 0x1a, 0xef, 0x88, 0x12, 0x14, 0x88, 0xc9, 0x19, 0xe7, + 0x1f, 0xa0, 0x39, 0x8d, 0x2c, 0xb6, 0x7a, 0xc4, 0x02, 0xc0, 0xef, 0xc8, 0xce, 0xe1, 0x3d, 0x5d, + 0x02, 0x71, 0x4e, 0x00, 0x56, 0x86, 0x36, 0xa0, 0xeb, 0xef, 0x16, 0x14, 0xd0, 0x1b, 0xa1, 0x7a, + 0xe2, 0x46, 0xd7, 0x56, 0x70, 0xa8, 0x52, 0xa7, 0x0f, 0xeb, 0x41, 0x63, 0x0d, 0x90, 0xf7, 0x89, + 0x7d, 0x18, 0x00, 0x40, 0x9c, 0x00, 0xe0, 0xe9, 0xf3, 0xc0, 0x1c, 0x42, 0x00, 0xdb, 0x24, 0x83, + 0x61, 0x06, 0xc1, 0x66, 0xb1, 0x99, 0xaa, 0xa1, 0x26, 0x84, 0x9c, 0x45, 0x6a, 0xac, 0xbf, 0x84, + 0x02, 0x92, 0x06, 0x09, 0x45, 0xf7, 0x1a, 0x56, 0x01, 0x66, 0x96, 0x02, 0x60, 0x64, 0x43, 0xdc, + 0x41, 0x1f, 0x62, 0x4e, 0xe9, 0x0a, 0x32, 0x87, 0x03, 0x66, 0xb4, 0xc3, 0xc1, 0x84, 0x01, 0x14, + 0x43, 0x89, 0x6a, 0x90, 0x46, 0x11, 0x9d, 0xd5, 0x95, 0x75, 0x7f, 0x88, 0xea, 0x08, 0xb8, 0x84, + 0xbc, 0x20, 0x14, 0x29, 0xec, 0xb0, 0x6c, 0xe7, 0x3c, 0x56, 0x5c, 0x2c, 0x63, 0xc7, 0x84, 0xfa, + 0x87, 0xfd, 0xd0, 0x06, 0xa8, 0xcf, 0x6a, 0x4f, 0xf9, 0x63, 0x39, 0xa7, 0xf8, 0x81, 0x23, 0x65, + 0x67, 0x42, 0x76, 0xa2, 0xc6, 0xde, 0x3f, 0x66, 0xb2, 0xa0, 0x5f, 0xa0, 0x72, 0x3b, 0x4c, 0x48, + 0x44, 0xe9, 0x99, 0xee, 0x57, 0x9e, 0x0f, 0x3c, 0xf7, 0x77, 0x05, 0x2d, 0x86, 0xe9, 0xe6, 0x97, + 0x84, 0x79, 0x0f, 0x13, 0xf1, 0xec, 0x78, 0x29, 0xf2, 0x4e, 0xa9, 0xc4, 0xad, 0xb3, 0xb6, 0xcf, + 0xaf, 0x90, 0xcf, 0x77, 0xf2, 0x89, 0xcf, 0xe4, 0xe2, 0x04, 0x10, 0x8b, 0x08, 0xe9, 0x25, 0x7f, + 0x1c, 0x49, 0xd5, 0x75, 0x55, 0x17, 0x9b, 0xf8, 0x2a, 0x2d, 0xe7, 0xef, 0xbb, 0xbe, 0xff, 0x04, + 0x55, 0xaa, 0xb1, 0xf0, 0xa0, 0xb5, 0x5f, 0x36, 0x2a, 0x55, 0x55, 0x25, 0x36, 0xf8, 0x29, 0x2b, + 0x4d, 0xa6, 0x92, 0xaa, 0xad, 0xdb, 0x4e, 0x0f, 0x84, 0x02, 0x05, 0xe2, 0x9d, 0x45, 0xd7, 0xcb, + 0x6f, 0xe1, 0x41, 0x28, 0xc9, 0x6c, 0x7b, 0x48, 0x2d, 0x24, 0xbb, 0x06, 0xaa, 0xaa, 0xa2, 0xfe, + 0xf8, 0x2a, 0x2b, 0xbb, 0xbe, 0xde, 0xd9, 0x31, 0x65, 0x64, 0x1d, 0xf0, 0x57, 0x4d, 0x72, 0x74, + 0xba, 0xcd, 0xd3, 0xfb, 0xe2, 0xcb, 0x6a, 0x2e, 0xa9, 0x88, 0xf9, 0xf0, 0x53, 0x55, 0xd5, 0x39, + 0x30, 0xb9, 0xd5, 0xf8, 0x88, 0x28, 0x22, 0xaf, 0x5a, 0xbf, 0xc2, 0x45, 0xbb, 0x4d, 0x2b, 0xeb, + 0x84, 0x8c, 0xe9, 0x77, 0xbf, 0x82, 0xcd, 0x1c, 0xb6, 0xb4, 0x90, 0x3d, 0x23, 0x5f, 0x7d, 0x75, + 0xf3, 0x5f, 0x75, 0xc2, 0xe2, 0x35, 0x56, 0xed, 0xa9, 0x77, 0x8b, 0xff, 0x84, 0x49, 0x49, 0xe3, + 0x8a, 0xde, 0xcf, 0x1b, 0x70, 0xb9, 0x7f, 0x84, 0x87, 0xe5, 0xcd, 0xab, 0xac, 0x40, 0xf1, 0x53, + 0xd3, 0x26, 0x70, 0x70, 0x3e, 0xcf, 0x01, 0xc8, 0x68, 0x7b, 0xe1, 0x11, 0x03, 0x24, 0x80, 0x00, + 0x56, 0x86, 0x51, 0xd4, 0xc3, 0xa0, 0xf1, 0xf0, 0x72, 0x56, 0x3a, 0x50, 0xf0, 0xfc, 0x1e, 0x7b, + 0xe0, 0xfd, 0xb3, 0x33, 0xa9, 0xc1, 0xee, 0x5d, 0x7c, 0x14, 0x05, 0x0a, 0x86, 0xd9, 0xeb, 0x25, + 0x6c, 0x0e, 0x61, 0x4a, 0x9c, 0xe0, 0xdb, 0xb0, 0x3c, 0x07, 0x9c, 0x02, 0xc4, 0x65, 0x66, 0xa2, + 0x3e, 0x33, 0xc5, 0x82, 0x60, 0x57, 0x1f, 0xf1, 0xbb, 0x89, 0x04, 0x21, 0x42, 0x14, 0x83, 0xa5, + 0x41, 0x0c, 0x8a, 0x07, 0xf3, 0x51, 0xca, 0x86, 0x30, 0x55, 0x9b, 0x30, 0x7e, 0x6f, 0xeb, 0x9d, + 0xcf, 0xfd, 0xea, 0x0d, 0x7e, 0x59, 0xe4, 0xc2, 0xb1, 0xd0, 0xd5, 0x12, 0xe5, 0xc0, 0x64, 0xcf, + 0x84, 0x01, 0x48, 0x52, 0xcb, 0xb1, 0xb6, 0xab, 0x16, 0xb2, 0x45, 0x49, 0x05, 0x55, 0x0a, 0xe4, + 0x0e, 0x01, 0xe9, 0xc1, 0x40, 0xf8, 0x78, 0x90, 0x43, 0xed, 0x50, 0x80, 0x2a, 0x3f, 0x2b, 0x6e, + 0x65, 0x07, 0x88, 0x0a, 0x5c, 0x95, 0x51, 0x4c, 0x6b, 0xdd, 0xb8, 0xa3, 0x2d, 0x8a, 0xde, 0xe2, + 0x01, 0xc4, 0xcb, 0x1f, 0x78, 0x28, 0x0a, 0x45, 0x61, 0x51, 0x51, 0x00, 0xf2, 0x76, 0xc5, 0xab, + 0xe3, 0x75, 0x23, 0xc3, 0xf0, 0x74, 0xc9, 0xc6, 0x97, 0x15, 0xe7, 0x15, 0x72, 0x9d, 0x3b, 0xfc, + 0x25, 0xbd, 0xf7, 0x77, 0xcd, 0xa5, 0x4b, 0xcd, 0x7b, 0xc5, 0xc4, 0xc7, 0x11, 0x6f, 0xcc, 0xc6, + 0xf4, 0xd7, 0x0f, 0xcf, 0xe2, 0xb7, 0x77, 0x71, 0x5e, 0xe9, 0x2b, 0x75, 0x5f, 0x27, 0x7b, 0xbf, + 0xc2, 0x64, 0xad, 0x45, 0xd5, 0x57, 0xca, 0x2c, 0x9d, 0x39, 0xf8, 0xb3, 0xe5, 0xc2, 0xea, 0xed, + 0xac, 0x40, 0x80, 0x46, 0x47, 0xde, 0xbe, 0x32, 0xab, 0xae, 0xbc, 0xdd, 0xf5, 0x7d, 0x91, 0x6a, + 0xbe, 0xfa, 0xaf, 0x8a, 0xae, 0xa9, 0x2d, 0x7c, 0x49, 0xe2, 0xf5, 0x4e, 0xab, 0xe2, 0xf9, 0x71, + 0xf1, 0xbf, 0xae, 0x6c, 0xf0, 0x9e, 0xf7, 0xce, 0x41, 0x2d, 0xfb, 0x11, 0x77, 0xf9, 0xaa, 0xba, + 0xe5, 0x3b, 0xbd, 0xd7, 0x26, 0x93, 0xbb, 0xe4, 0x10, 0x6e, 0xe6, 0x3c, 0x44, 0x22, 0x44, 0x81, + 0xba, 0xad, 0x8a, 0xc4, 0x2c, 0x5d, 0xd8, 0xef, 0xe1, 0x42, 0x9c, 0xe1, 0x6c, 0xe7, 0x1b, 0x9a, + 0x4e, 0x58, 0xed, 0xe2, 0xb1, 0x5b, 0xe5, 0xf1, 0x25, 0xdd, 0x21, 0x2f, 0xcf, 0x8e, 0xfa, 0xb9, + 0xe0, 0x48, 0x09, 0x10, 0x1a, 0xc8, 0x62, 0xe2, 0x25, 0x07, 0x8b, 0xb3, 0x2b, 0x37, 0xe0, 0xa0, + 0x41, 0x4b, 0x96, 0x33, 0x62, 0x2d, 0x96, 0xc4, 0xbd, 0xa5, 0xd9, 0x71, 0x20, 0xa8, 0x43, 0x99, + 0x0a, 0x8f, 0x4d, 0xc2, 0xaa, 0xd5, 0x60, 0xb5, 0x3e, 0xca, 0x5b, 0x3f, 0x7b, 0x11, 0xd6, 0xa6, + 0xe1, 0xdb, 0xb0, 0x95, 0x04, 0xf2, 0x20, 0xd9, 0x2b, 0x0d, 0xb1, 0xac, 0x0c, 0x22, 0x7e, 0xb8, + 0x4c, 0xad, 0x34, 0x63, 0x5d, 0x6b, 0xe8, 0xc9, 0x9f, 0xb1, 0x32, 0xed, 0x0f, 0x88, 0x0c, 0x13, + 0x27, 0xd2, 0x6a, 0xdc, 0xbd, 0xff, 0xc1, 0x56, 0xf2, 0xf6, 0xef, 0x82, 0x21, 0x0f, 0x7f, 0x12, + 0xe3, 0xf8, 0xfb, 0xe2, 0x29, 0x5b, 0xa7, 0xaf, 0x82, 0xea, 0xef, 0xa4, 0x9b, 0x3e, 0x2a, 0xba, + 0x8b, 0xd4, 0xac, 0xf8, 0x42, 0xc6, 0x93, 0x1b, 0x73, 0xc8, 0x55, 0xf9, 0xd8, 0x61, 0xf8, 0x25, + 0xca, 0x81, 0x2f, 0x59, 0xa4, 0xc7, 0xc2, 0x64, 0x5c, 0xad, 0xa6, 0x35, 0xf0, 0xb0, 0x96, 0xb7, + 0xbb, 0x1d, 0x37, 0x5d, 0xd1, 0x22, 0xff, 0x0e, 0xde, 0x87, 0xba, 0xe9, 0xdd, 0x53, 0x93, 0xaf, + 0xfa, 0xd7, 0xc9, 0x2e, 0x19, 0x9b, 0x1f, 0x8a, 0xa5, 0x6e, 0xfa, 0x1f, 0x8a, 0xd8, 0xe7, 0x6d, + 0xb9, 0x90, 0x78, 0x6c, 0x99, 0x5e, 0xd2, 0x9a, 0x29, 0xd1, 0x7f, 0x86, 0x67, 0x63, 0xfb, 0x2f, + 0x5f, 0xfc, 0x15, 0x6d, 0xb5, 0x8a, 0x3a, 0x6d, 0x19, 0x17, 0x9d, 0xf1, 0x5a, 0xbe, 0xda, 0x7f, + 0x35, 0xad, 0xaf, 0x09, 0xdd, 0xb3, 0xfd, 0xa6, 0xbf, 0x08, 0x71, 0x5b, 0x6d, 0xd7, 0xcb, 0xbe, + 0x13, 0x3d, 0xde, 0xd6, 0xd7, 0x96, 0xee, 0xcc, 0x6d, 0xa3, 0xc1, 0x0e, 0xef, 0xc3, 0xc4, 0x02, + 0xae, 0x7f, 0x8b, 0xf8, 0xef, 0x96, 0xfd, 0xbe, 0x13, 0x25, 0xbb, 0x77, 0xb6, 0xb8, 0x7e, 0xee, + 0xd3, 0x4f, 0x4e, 0xef, 0xae, 0x0f, 0xa2, 0x9f, 0xf9, 0x77, 0x4e, 0xb9, 0xea, 0x8d, 0x5c, 0x95, + 0xff, 0x26, 0xf6, 0x6b, 0x9b, 0x3b, 0x6c, 0xbc, 0x84, 0xce, 0xcb, 0xae, 0xa6, 0x51, 0xf1, 0x11, + 0xb3, 0x2e, 0x8d, 0xa7, 0x6b, 0xf2, 0x65, 0x7b, 0x0e, 0x97, 0x84, 0x8e, 0x64, 0xb9, 0x37, 0x96, + 0x1e, 0x89, 0x87, 0xc1, 0x39, 0x25, 0xfb, 0xd3, 0x77, 0xf8, 0x9c, 0xca, 0x4e, 0xab, 0x1a, 0x31, + 0x05, 0x5b, 0x5e, 0xed, 0xb1, 0xd3, 0xf2, 0x15, 0x06, 0xd2, 0x0d, 0xfc, 0x56, 0x92, 0x59, 0x97, + 0x7f, 0xd7, 0x0f, 0x84, 0xec, 0x23, 0xf4, 0x3f, 0x3e, 0x1f, 0x3c, 0x6d, 0x5b, 0x44, 0x3f, 0x86, + 0x98, 0xd7, 0x56, 0xce, 0xd2, 0xa3, 0xc9, 0xd2, 0x54, 0xe6, 0x6f, 0x1c, 0xa9, 0xe3, 0xc9, 0x3a, + 0xad, 0x1d, 0x1f, 0xf1, 0x86, 0xa8, 0xe1, 0xc6, 0x96, 0x5c, 0x6d, 0x59, 0xb1, 0xf5, 0x8f, 0x7c, + 0x2e, 0x97, 0x85, 0x0a, 0x7c, 0x2f, 0xe3, 0xeb, 0x55, 0x74, 0xc3, 0x4d, 0x7c, 0x63, 0x4a, 0x39, + 0xa4, 0x4e, 0xd6, 0x4f, 0x33, 0x9f, 0x1b, 0x27, 0x49, 0x27, 0xa4, 0x33, 0xe8, 0x15, 0x6c, 0xe4, + 0xa2, 0xba, 0x50, 0xac, 0x7b, 0x0e, 0x76, 0x64, 0xff, 0xe3, 0x61, 0x33, 0x5c, 0xfa, 0xfb, 0x26, + 0x2d, 0x75, 0x42, 0x77, 0xdb, 0xc1, 0xda, 0xe5, 0xeb, 0xa6, 0x31, 0xcb, 0xa5, 0x57, 0x99, 0x40, + 0xf1, 0xc6, 0x0d, 0x63, 0x29, 0x26, 0xd5, 0x9a, 0xff, 0x8d, 0xa0, 0x60, 0x35, 0xaf, 0x02, 0x1d, + 0xc8, 0x70, 0x7b, 0x27, 0xf9, 0x58, 0x81, 0xe4, 0x48, 0x91, 0xb5, 0xf2, 0x73, 0x34, 0x3c, 0x16, + 0xbb, 0x4f, 0x34, 0x7f, 0xc6, 0xd0, 0xeb, 0xf7, 0xd5, 0xbf, 0x9c, 0xb2, 0x84, 0xc6, 0x35, 0x53, + 0x62, 0x83, 0x6a, 0x0b, 0x7b, 0x38, 0x14, 0xdd, 0x3d, 0x3f, 0xf1, 0xba, 0x46, 0xca, 0x5b, 0x91, + 0xad, 0x6e, 0x10, 0xf4, 0x8e, 0xcf, 0x7c, 0x1e, 0x5d, 0x43, 0x71, 0x8e, 0xe1, 0x46, 0x3f, 0xc6, + 0x95, 0x24, 0x9f, 0x99, 0x9b, 0x2e, 0x97, 0x28, 0x72, 0x37, 0x6e, 0xdb, 0xbf, 0x59, 0x3b, 0x2f, + 0x05, 0x33, 0x61, 0xf2, 0x28, 0xaa, 0x97, 0xe9, 0x91, 0xec, 0x7b, 0x9f, 0x05, 0x93, 0xb3, 0x18, + 0xc6, 0x4e, 0xcb, 0xdd, 0xb9, 0x2a, 0xe8, 0x6b, 0xfd, 0x78, 0x7c, 0x23, 0xb4, 0x9e, 0x56, 0x6a, + 0x89, 0xaf, 0x44, 0xd9, 0x35, 0x9f, 0x0a, 0x6c, 0x67, 0x65, 0xec, 0xa6, 0x93, 0xa2, 0xf6, 0x60, + 0xe3, 0x6a, 0x0d, 0x7e, 0x4b, 0x2f, 0x38, 0xfb, 0x90, 0x6b, 0xe1, 0x4a, 0x69, 0x46, 0xe9, 0x34, + 0xc3, 0x34, 0xb1, 0x0f, 0x4e, 0xb8, 0x35, 0x57, 0xb6, 0x76, 0xf8, 0x52, 0x37, 0x7b, 0xab, 0x97, + 0xbf, 0x95, 0x84, 0x36, 0x38, 0x36, 0x3c, 0xbe, 0x36, 0xd3, 0x0d, 0xb1, 0x93, 0x8a, 0x9d, 0x8d, + 0x4d, 0x28, 0x36, 0xec, 0x97, 0xc5, 0x06, 0x3b, 0x52, 0x79, 0x04, 0x9d, 0x13, 0x31, 0x1f, 0xf8, + 0x77, 0x4c, 0xed, 0x73, 0x16, 0x37, 0xec, 0x72, 0x86, 0x77, 0xc4, 0x60, 0x89, 0x90, 0xff, 0xc2, + 0x90, 0xbb, 0x9d, 0xd1, 0xca, 0xc1, 0xd9, 0x6a, 0x12, 0x72, 0x77, 0x6d, 0xcd, 0xdf, 0xcc, 0xf3, + 0xe1, 0xe9, 0xf8, 0x33, 0xd3, 0xae, 0xbc, 0xec, 0x9f, 0xb3, 0xb5, 0x2e, 0x51, 0x4f, 0xcf, 0xff, + 0xc6, 0xe6, 0xed, 0xd2, 0x55, 0x75, 0x24, 0xc6, 0x59, 0x0a, 0x3c, 0x90, 0x2e, 0x41, 0x9c, 0xe3, + 0x79, 0x42, 0xb2, 0xd6, 0x21, 0x8f, 0xf8, 0x2c, 0x24, 0x75, 0x50, 0xeb, 0xb4, 0x46, 0x3a, 0x18, + 0xdd, 0xd8, 0x1f, 0x33, 0xf0, 0x53, 0xb7, 0x74, 0x4c, 0x91, 0x12, 0x3b, 0xd3, 0x64, 0xff, 0x05, + 0x39, 0x99, 0x3c, 0x34, 0x33, 0xeb, 0x2a, 0x90, 0xcc, 0xdb, 0x1c, 0x5f, 0x04, 0x19, 0x5e, 0xca, + 0x0d, 0xb2, 0xa1, 0x4d, 0xdd, 0x6d, 0x21, 0x6c, 0x37, 0x92, 0x28, 0x95, 0xff, 0xc6, 0xf3, 0xf6, + 0xb7, 0x78, 0x9d, 0xcd, 0x16, 0x58, 0xc6, 0xee, 0x5c, 0xa7, 0x64, 0x33, 0xdf, 0xe3, 0x4b, 0x5a, + 0xa4, 0x34, 0xa9, 0xbe, 0x35, 0xd8, 0xd6, 0x28, 0xd2, 0xae, 0xde, 0x9f, 0xf8, 0xed, 0xf4, 0xa9, + 0xdc, 0xec, 0xd6, 0xc6, 0x3f, 0x05, 0x74, 0xad, 0x5d, 0xb6, 0x9e, 0x9b, 0x78, 0x93, 0xe1, 0x8b, + 0x69, 0x2a, 0x6c, 0x69, 0x31, 0xfb, 0x33, 0x24, 0x8d, 0x2f, 0xf1, 0xb4, 0xb7, 0x49, 0x2e, 0xd2, + 0x23, 0xb0, 0x4c, 0x56, 0xb3, 0xf5, 0x33, 0x44, 0x31, 0x58, 0xc6, 0x7f, 0xc6, 0xd1, 0x5a, 0x77, + 0x3e, 0x8e, 0x59, 0x1b, 0x36, 0x90, 0xd0, 0xcd, 0x84, 0x4a, 0xa3, 0x23, 0x81, 0x55, 0x63, 0x3d, + 0xfe, 0x37, 0x6a, 0xd3, 0x8b, 0xb9, 0x71, 0x8e, 0xe6, 0x26, 0x52, 0xd6, 0x07, 0x90, 0xea, 0x62, + 0xc8, 0x91, 0x74, 0x5d, 0x1f, 0xf1, 0x94, 0x36, 0xa5, 0xab, 0x95, 0x8d, 0xea, 0x5c, 0xcc, 0x1b, + 0x99, 0x91, 0xb3, 0x1b, 0x51, 0x78, 0x20, 0x8f, 0x5d, 0x76, 0x41, 0xcb, 0x19, 0x65, 0xd1, 0x17, + 0xa2, 0xb6, 0x24, 0x5d, 0xac, 0x3b, 0xe7, 0xfe, 0x37, 0x59, 0x23, 0x7c, 0xcc, 0x9d, 0xa9, 0xa1, + 0xdb, 0x57, 0x96, 0xe5, 0x45, 0xc8, 0xed, 0x36, 0x44, 0xff, 0xe3, 0x49, 0x23, 0xd1, 0x35, 0x12, + 0x1b, 0x56, 0x76, 0xa1, 0xf0, 0x61, 0xea, 0xc4, 0x3f, 0x0f, 0x56, 0x98, 0x8e, 0x62, 0xe7, 0xfe, + 0x14, 0x2c, 0xda, 0x4f, 0xb1, 0x8f, 0xdd, 0x44, 0xcc, 0x18, 0xae, 0x8f, 0xd2, 0x33, 0x10, 0x7f, + 0xbe, 0x14, 0xbf, 0xa1, 0xe8, 0x63, 0x37, 0x58, 0xf6, 0xb3, 0x06, 0x79, 0x33, 0x43, 0xdd, 0x38, + 0x37, 0x4b, 0xb2, 0x6b, 0x1f, 0x1b, 0x3e, 0x68, 0x8c, 0x68, 0x89, 0x96, 0x4a, 0xe5, 0xb1, 0x01, + 0xd2, 0x37, 0xb9, 0x54, 0x12, 0xd9, 0xea, 0xa1, 0xda, 0xa6, 0x22, 0xae, 0xa9, 0xaf, 0xfc, 0x29, + 0x3a, 0x26, 0xa8, 0x64, 0x59, 0xb6, 0x1d, 0x78, 0x9b, 0x04, 0xb5, 0xb8, 0x51, 0x56, 0xe9, 0x77, + 0xc2, 0x04, 0x32, 0x89, 0xb1, 0xa5, 0xd4, 0xeb, 0x54, 0x1b, 0x0d, 0x27, 0xf0, 0xa4, 0xfc, 0x76, + 0xe9, 0xd1, 0x39, 0x05, 0x22, 0xeb, 0xa3, 0x76, 0xd4, 0x2b, 0x0b, 0x0a, 0xb8, 0x63, 0x62, 0x04, + 0xcf, 0xc2, 0x96, 0x36, 0xcc, 0xc4, 0x52, 0x35, 0x07, 0xe3, 0x79, 0x37, 0xd1, 0xcc, 0xa5, 0xdf, + 0xe3, 0x67, 0x81, 0xa0, 0x5d, 0xb7, 0x1d, 0xc8, 0xfe, 0xe8, 0x39, 0x75, 0x69, 0xe6, 0x2c, 0x65, + 0x02, 0x92, 0x1b, 0xff, 0x82, 0xbe, 0x58, 0xac, 0x54, 0x3a, 0xda, 0x3b, 0x50, 0xe5, 0x3e, 0xf8, + 0x24, 0x9d, 0x0e, 0xd3, 0xfd, 0x5f, 0xe3, 0x6d, 0x1b, 0x5b, 0x83, 0x5f, 0x71, 0xac, 0x47, 0x59, + 0xe2, 0xa2, 0xa5, 0x67, 0xcd, 0xed, 0xd5, 0xdd, 0x5f, 0xfc, 0x20, 0x47, 0xa1, 0x63, 0xf3, 0xec, + 0x8f, 0xbb, 0xd3, 0x6b, 0xc6, 0x4c, 0xd6, 0xb2, 0x2a, 0x2b, 0x24, 0xcd, 0x0c, 0xe8, 0x28, 0x6e, + 0x6a, 0x6a, 0x6a, 0x8f, 0xc2, 0x85, 0x6d, 0xe3, 0x17, 0x47, 0xd2, 0xb8, 0xc9, 0x21, 0xda, 0xaa, + 0xb6, 0x49, 0xc2, 0x96, 0x13, 0x7c, 0x29, 0x63, 0xc9, 0xdb, 0x99, 0x49, 0xc3, 0x5b, 0x0c, 0x6e, + 0x81, 0x97, 0x2d, 0x88, 0x3a, 0x5e, 0xbe, 0x14, 0xd2, 0x49, 0x11, 0xd3, 0x4a, 0x17, 0x3e, 0x99, + 0x2d, 0x4f, 0x81, 0x92, 0x2e, 0x42, 0x70, 0x60, 0x6d, 0xf0, 0x52, 0x53, 0xb2, 0x76, 0x58, 0x9e, + 0xcf, 0x77, 0x72, 0xea, 0x10, 0xa0, 0x6c, 0x43, 0x97, 0xc1, 0x56, 0x06, 0xc6, 0x3d, 0x5b, 0x7d, + 0xec, 0x1b, 0x2e, 0x54, 0x8c, 0x74, 0x65, 0x4f, 0x85, 0x09, 0x32, 0x74, 0xd8, 0xc7, 0x53, 0x01, + 0xd5, 0x23, 0x96, 0x3e, 0xbc, 0x56, 0xbc, 0xf0, 0xe8, 0xec, 0x3e, 0xf8, 0x52, 0xe4, 0x8f, 0x52, + 0xa2, 0xee, 0xd4, 0x29, 0x9d, 0xcf, 0x41, 0xc3, 0xdd, 0x6d, 0x2a, 0x19, 0x71, 0x32, 0x9e, 0x92, + 0xf8, 0xc2, 0x3c, 0x71, 0x5a, 0xa4, 0x54, 0x4f, 0x7a, 0x19, 0x8d, 0xc6, 0xf6, 0x26, 0x2a, 0x5f, + 0x05, 0x34, 0xea, 0x4d, 0xbb, 0x99, 0xd8, 0xc5, 0x6f, 0x40, 0xda, 0x1f, 0xbe, 0x1f, 0x29, 0x63, + 0x4a, 0x6a, 0x91, 0x72, 0x22, 0xed, 0x55, 0xeb, 0x55, 0xd5, 0xbf, 0xf1, 0x96, 0xc2, 0xdc, 0xb2, + 0x2c, 0x13, 0xba, 0xc5, 0x74, 0xfb, 0x4d, 0xad, 0x96, 0x48, 0x74, 0xbc, 0x11, 0x50, 0xd5, 0x93, + 0x28, 0x3e, 0x12, 0xcc, 0xcb, 0x1f, 0xaa, 0x7e, 0x14, 0x2b, 0xfd, 0x26, 0x1b, 0x0e, 0x99, 0xd8, + 0x7f, 0x2b, 0xd8, 0xdb, 0x56, 0xd6, 0x13, 0x39, 0x63, 0xbe, 0x32, 0x8a, 0xd4, 0x83, 0x26, 0xc8, + 0xf5, 0xf4, 0x83, 0xa3, 0x6c, 0x7a, 0xd3, 0xba, 0x4d, 0x45, 0x7e, 0x14, 0x23, 0xa6, 0x77, 0xc2, + 0x6c, 0x29, 0x78, 0x49, 0x21, 0xd2, 0x76, 0xe6, 0xbe, 0x14, 0xb9, 0xe3, 0x57, 0x35, 0x51, 0xb5, + 0xcc, 0xa8, 0x48, 0x66, 0x60, 0x2a, 0xdc, 0x59, 0x7b, 0x57, 0xca, 0x8f, 0x3f, 0xc1, 0x76, 0xec, + 0x69, 0x39, 0xf8, 0xaf, 0xdf, 0xe1, 0x4b, 0x2a, 0x4d, 0xa5, 0x8f, 0xe7, 0xf3, 0xf6, 0x1d, 0xa1, + 0x99, 0x04, 0x75, 0xf0, 0x55, 0x2b, 0xd5, 0x51, 0x0e, 0x0f, 0x59, 0x8c, 0x66, 0xda, 0x32, 0xca, + 0x8f, 0x19, 0xe2, 0x07, 0xe1, 0x4f, 0xe5, 0x66, 0x86, 0xda, 0x0d, 0xb3, 0x37, 0xf0, 0x51, 0x73, + 0xe0, 0xaf, 0x7d, 0x8d, 0x9f, 0x05, 0xdc, 0xfe, 0xc6, 0x93, 0x1a, 0x59, 0x8f, 0x82, 0xb9, 0x1b, + 0x06, 0x5d, 0x8e, 0xba, 0x1b, 0x1a, 0x1b, 0x43, 0x74, 0x4f, 0x51, 0xfe, 0x0a, 0xb4, 0xdb, 0x2f, + 0xb6, 0xf3, 0x30, 0xbb, 0x10, 0xcd, 0x1b, 0xe1, 0x48, 0xe2, 0x13, 0xd6, 0xa1, 0xab, 0xca, 0x55, + 0x0f, 0x42, 0xc5, 0x03, 0x66, 0x74, 0xa0, 0x61, 0xca, 0xdb, 0x22, 0xa9, 0x26, 0x0e, 0x08, 0xc9, + 0xf0, 0x58, 0x52, 0x62, 0x19, 0xe0, 0xa6, 0xba, 0x31, 0x93, 0x61, 0x92, 0x31, 0x88, 0xd8, 0xcb, + 0x99, 0xcb, 0xcf, 0x8d, 0x91, 0x84, 0x75, 0x1a, 0xf7, 0x32, 0xb0, 0xcf, 0xcd, 0xb1, 0x33, 0x53, + 0xc7, 0xcc, 0xd5, 0xdd, 0x31, 0x3f, 0xa5, 0x9d, 0x42, 0x9a, 0x1b, 0xff, 0xc2, 0x84, 0x0c, 0xf2, + 0xeb, 0xa1, 0xb9, 0x91, 0x3f, 0xa9, 0x30, 0xd9, 0x46, 0x67, 0xba, 0x14, 0x79, 0xd0, 0xb5, 0x06, + 0x8b, 0x7e, 0x0a, 0x66, 0x4b, 0x43, 0x72, 0x2c, 0x75, 0x7a, 0x33, 0xa1, 0x43, 0xd3, 0xe4, 0xac, + 0x3b, 0xe1, 0x49, 0x20, 0x9e, 0xd0, 0xd2, 0xe9, 0x9e, 0xbb, 0x45, 0xcb, 0x7c, 0x9a, 0xc4, 0x1b, + 0x59, 0xcb, 0xe1, 0x4a, 0x4d, 0xb7, 0x27, 0x3f, 0x4a, 0x15, 0x22, 0xe5, 0xeb, 0x2b, 0x89, 0x46, + 0x6d, 0xc6, 0x3e, 0x36, 0xf5, 0x1b, 0xd4, 0xb4, 0xd3, 0x7e, 0xa3, 0xf9, 0x6c, 0x66, 0xc9, 0xb9, + 0x4b, 0x1f, 0xc6, 0x97, 0xf8, 0xd9, 0x59, 0x8e, 0x85, 0x5b, 0x13, 0x66, 0x51, 0x42, 0x97, 0x9d, + 0x9a, 0x3b, 0xe5, 0xe5, 0xd0, 0x6e, 0xbf, 0xf0, 0xad, 0xbb, 0x18, 0xeb, 0x15, 0x6c, 0x65, 0x6a, + 0x6d, 0x7a, 0x28, 0x5f, 0xe1, 0xfe, 0x65, 0x13, 0x2a, 0x78, 0x3a, 0x1b, 0x0c, 0x6e, 0xe5, 0x5d, + 0xd8, 0x2c, 0xf4, 0xa5, 0xff, 0xc2, 0x9b, 0x44, 0x6b, 0x10, 0xb1, 0xb9, 0xba, 0x5f, 0x2e, 0x26, + 0xf6, 0xe7, 0x6f, 0x8f, 0xb4, 0x4d, 0x56, 0xc1, 0xfe, 0xe9, 0x63, 0xf5, 0x0d, 0x66, 0xb6, 0xf7, + 0x84, 0x71, 0x94, 0x3b, 0x36, 0xd7, 0x27, 0x43, 0x7f, 0x83, 0x73, 0x3e, 0x14, 0xb5, 0xf1, 0x2b, + 0x36, 0x4e, 0x23, 0xb0, 0xc6, 0x57, 0x1b, 0x3c, 0xdd, 0xa6, 0x33, 0x8c, 0xd3, 0x2f, 0x85, 0x2c, + 0x6b, 0xc7, 0x2a, 0xe2, 0x97, 0xb7, 0x06, 0xc6, 0xda, 0xf9, 0x7c, 0x14, 0xf4, 0x34, 0xdb, 0x9d, + 0xa5, 0x67, 0xb6, 0x9b, 0x19, 0xd3, 0xe0, 0xab, 0x49, 0x06, 0xdb, 0xe9, 0x1d, 0x98, 0xb3, 0xef, + 0x2f, 0x84, 0x0b, 0x5a, 0xb6, 0x98, 0xb6, 0xb3, 0xb0, 0x5f, 0x3e, 0x36, 0xc7, 0x62, 0x1c, 0xa5, + 0x2c, 0x8d, 0x83, 0xca, 0xc1, 0x98, 0x4c, 0xb8, 0xd9, 0xa5, 0x3d, 0x14, 0xf0, 0x73, 0xc2, 0xff, + 0xc2, 0x92, 0x32, 0xb7, 0x34, 0x0a, 0xdf, 0x07, 0x46, 0xd9, 0x1a, 0x4d, 0xd6, 0x35, 0x8c, 0xb1, + 0xad, 0x94, 0xbd, 0x9a, 0xd9, 0x85, 0xff, 0x05, 0x26, 0x82, 0xb1, 0x45, 0x11, 0xfa, 0x15, 0xe6, + 0xd9, 0x98, 0x7f, 0x8c, 0x2a, 0x74, 0x9b, 0x3b, 0xd7, 0x88, 0x88, 0x58, 0xd8, 0xd2, 0xee, 0xa6, + 0xb5, 0x95, 0xc1, 0xd1, 0xf8, 0xdd, 0xa4, 0x46, 0x52, 0x1c, 0x74, 0x95, 0xe5, 0x05, 0xe3, 0xe9, + 0x96, 0xde, 0xbc, 0x19, 0x59, 0x83, 0xbe, 0x2b, 0x51, 0xdc, 0x58, 0xa7, 0xfc, 0x3b, 0x8d, 0x0d, + 0x4a, 0x88, 0xde, 0x16, 0xdb, 0x91, 0x70, 0x63, 0x89, 0x5a, 0xd2, 0xb2, 0xaf, 0xfe, 0x14, 0xa6, + 0xc7, 0x76, 0x31, 0xdc, 0xd8, 0xba, 0x1a, 0x64, 0x8a, 0x24, 0xb4, 0xb5, 0xf0, 0xa5, 0x0a, 0xb2, + 0x0f, 0x4c, 0xf8, 0xf5, 0x9f, 0xb6, 0x96, 0x7c, 0x69, 0x37, 0xb3, 0xe3, 0xf8, 0x50, 0x88, 0x8f, + 0x20, 0xcf, 0x29, 0xc9, 0x1b, 0x0d, 0x8c, 0xf1, 0x93, 0x9a, 0xfb, 0xd1, 0xf3, 0xf9, 0x7c, 0x14, + 0xcd, 0x2f, 0x84, 0x74, 0x0f, 0xa9, 0x5b, 0x17, 0xdf, 0x05, 0xb4, 0x9a, 0x86, 0x68, 0xc3, 0x14, + 0x9a, 0x51, 0x37, 0xc6, 0xf8, 0x4c, 0x9b, 0xbb, 0xc8, 0xcf, 0x43, 0x2a, 0x50, 0xd3, 0x95, 0xc6, + 0x2c, 0x6c, 0xd0, 0x65, 0x3f, 0xe2, 0x39, 0x51, 0x35, 0x6d, 0x4b, 0x03, 0x7b, 0xe9, 0x78, 0x29, + 0x2a, 0x02, 0x72, 0x83, 0xac, 0xe8, 0x65, 0xc2, 0xe3, 0x5b, 0x63, 0x14, 0xdb, 0xe3, 0x2c, 0x71, + 0xba, 0x46, 0x87, 0xbc, 0x34, 0x8c, 0xfc, 0xed, 0x73, 0x58, 0xff, 0x0a, 0x66, 0xd6, 0xf3, 0xbd, + 0x8c, 0x52, 0x44, 0xad, 0xbd, 0xab, 0xb2, 0x89, 0xb6, 0x47, 0x8a, 0xcb, 0xd5, 0xf1, 0x98, 0x32, + 0xb7, 0x7e, 0x39, 0x24, 0x9b, 0x09, 0x9b, 0xd6, 0xe4, 0x99, 0xb3, 0xc3, 0x0e, 0xb3, 0xfc, 0x29, + 0x5d, 0x73, 0x88, 0xef, 0x2e, 0x19, 0xed, 0x87, 0xb6, 0xac, 0x7b, 0x6f, 0x32, 0x2a, 0xf0, 0xa7, + 0x74, 0xdb, 0xbc, 0x89, 0x4a, 0xc5, 0x0e, 0xc6, 0x3f, 0x9b, 0x63, 0x1d, 0x1a, 0x55, 0xe1, 0x4c, + 0x6d, 0xad, 0xbd, 0x06, 0xd6, 0x3d, 0x0e, 0x86, 0x57, 0x95, 0xf6, 0x66, 0x3b, 0x2b, 0x1a, 0xf8, + 0x53, 0xa1, 0x91, 0xa4, 0x65, 0xc8, 0x5a, 0xc5, 0x24, 0x38, 0x9a, 0xcb, 0xfd, 0x49, 0x79, 0xdf, + 0x19, 0x1a, 0x41, 0x70, 0x4e, 0x1c, 0x53, 0x55, 0x31, 0xea, 0xb2, 0x1c, 0xb9, 0x7a, 0x1d, 0x7a, + 0x18, 0xaf, 0xc1, 0x5d, 0x5f, 0x95, 0x95, 0x83, 0x58, 0xfa, 0xdc, 0xd6, 0xf8, 0x52, 0x58, 0x56, + 0x76, 0x6b, 0x4e, 0x2d, 0x37, 0x2b, 0x53, 0x56, 0xa9, 0x47, 0x71, 0xbf, 0xc6, 0xce, 0xc9, 0x58, + 0x3b, 0x2c, 0x65, 0x6d, 0xdd, 0xec, 0x9e, 0x5b, 0xef, 0x36, 0xf1, 0x68, 0xc9, 0x09, 0x61, 0xfe, + 0x36, 0x76, 0x09, 0x95, 0x41, 0xd1, 0x92, 0x48, 0x97, 0xe0, 0xfb, 0xc6, 0x6f, 0x0f, 0x65, 0x0a, + 0x56, 0x39, 0x2c, 0x36, 0x4f, 0xfe, 0x14, 0xee, 0x6e, 0x56, 0xc9, 0x59, 0x67, 0x74, 0x0e, 0xda, + 0x9f, 0x1a, 0x9e, 0xd5, 0xcb, 0x47, 0x95, 0x5f, 0x0a, 0x50, 0xcf, 0x98, 0x3f, 0x96, 0x3b, 0x79, + 0x0f, 0xd3, 0x8f, 0xd6, 0xc9, 0xbc, 0xaf, 0xdb, 0xe1, 0x4c, 0x4e, 0xc3, 0x32, 0x55, 0x35, 0x45, + 0x06, 0x5c, 0x2b, 0x11, 0xb1, 0x06, 0xd3, 0x1a, 0x77, 0xee, 0xf8, 0x52, 0x91, 0xfc, 0x4c, 0x6a, + 0xcb, 0xb7, 0x47, 0x63, 0x73, 0x44, 0xac, 0xb0, 0xda, 0x56, 0xac, 0x48, 0xc7, 0xc2, 0x99, 0xe0, + 0x56, 0x16, 0x5d, 0x7b, 0x08, 0xa8, 0xcf, 0x07, 0x6d, 0x1b, 0xb7, 0x3c, 0x94, 0xde, 0xe2, 0xbb, + 0xe0, 0xae, 0xda, 0x1a, 0xa3, 0x64, 0xb9, 0x2c, 0x76, 0x1d, 0xb7, 0x23, 0xdf, 0xe1, 0x42, 0x15, + 0x91, 0xfa, 0xde, 0x36, 0x28, 0x89, 0x02, 0x85, 0xb7, 0xb2, 0x75, 0xc7, 0x1f, 0xdf, 0xe0, 0xae, + 0x33, 0x7a, 0x5a, 0xce, 0x77, 0xbd, 0x86, 0x33, 0x76, 0x8f, 0x45, 0x4f, 0xf0, 0x53, 0x61, 0x8f, + 0x57, 0x73, 0x30, 0x36, 0x3e, 0x8f, 0x9d, 0xbc, 0x5f, 0x08, 0x6b, 0x64, 0x68, 0x8a, 0xce, 0xda, + 0x4c, 0x8c, 0xd1, 0x9a, 0x52, 0xf1, 0x96, 0x4d, 0x84, 0xb8, 0xd6, 0x46, 0x4e, 0xe0, 0xdd, 0xa8, + 0x75, 0xa1, 0x95, 0x94, 0x38, 0x59, 0x77, 0xc6, 0xde, 0xd6, 0x37, 0xb5, 0xac, 0x4c, 0x55, 0xb6, + 0xe8, 0xb5, 0x87, 0x45, 0x65, 0x74, 0x89, 0x24, 0x8a, 0xd7, 0x14, 0x57, 0x75, 0xff, 0x0a, 0x1d, + 0xf9, 0x5c, 0x0c, 0xfd, 0xa6, 0x54, 0x8b, 0xaf, 0x61, 0x4d, 0x6d, 0xde, 0xd3, 0x1b, 0x1c, 0xbe, + 0x0b, 0x34, 0xdc, 0x8c, 0x1a, 0x2d, 0xc7, 0x3b, 0x5f, 0xec, 0xb0, 0xf8, 0x7f, 0x9b, 0x07, 0xcc, + 0x52, 0xf1, 0xd4, 0xaa, 0xdb, 0x1e, 0xa8, 0x96, 0xbf, 0xe1, 0x48, 0xe2, 0xd1, 0xb3, 0xe9, 0x95, + 0x23, 0xce, 0xc6, 0x76, 0xc9, 0xa6, 0xda, 0x38, 0xca, 0xa3, 0xbe, 0x14, 0xbe, 0x38, 0xdd, 0xaa, + 0xd0, 0x61, 0x9a, 0xd4, 0x75, 0x75, 0x27, 0xeb, 0x7a, 0xa3, 0x3b, 0xca, 0x9f, 0x0f, 0x90, 0xf1, + 0xbc, 0xbe, 0x5e, 0x87, 0x62, 0xb4, 0x37, 0xe5, 0x75, 0x75, 0xff, 0x0a, 0x50, 0xe5, 0x62, 0xec, + 0x73, 0x3e, 0x76, 0x9b, 0xd7, 0xaf, 0x82, 0xb9, 0xd8, 0x8e, 0x8f, 0x3e, 0x22, 0xa9, 0x0d, 0xa9, + 0x20, 0x4d, 0xf0, 0x51, 0x99, 0x0a, 0xad, 0xcb, 0xb6, 0xf2, 0xf8, 0x89, 0x92, 0xb2, 0xd5, 0xa6, + 0xed, 0x5d, 0x97, 0x8c, 0xbb, 0xde, 0x59, 0x33, 0x18, 0xda, 0x38, 0x31, 0xca, 0x44, 0xe1, 0x33, + 0x60, 0xf6, 0x62, 0x7e, 0x0a, 0x6c, 0x6b, 0xf3, 0x85, 0x57, 0x07, 0x2b, 0x5e, 0x56, 0xe6, 0xf8, + 0x52, 0x37, 0x5a, 0x57, 0x26, 0x8d, 0xc3, 0x1d, 0xa3, 0x21, 0xa1, 0xbd, 0xa5, 0x66, 0x8e, 0x24, + 0xc3, 0x55, 0xa8, 0x1c, 0x7f, 0x82, 0xbb, 0x59, 0x5d, 0x59, 0x5b, 0x47, 0xbb, 0x6a, 0x21, 0xe8, + 0x9a, 0xc6, 0x6c, 0x7c, 0x15, 0x46, 0xcd, 0xb0, 0x9e, 0xcb, 0xd2, 0xee, 0xca, 0xfb, 0x58, 0x7c, + 0x14, 0x5a, 0xb4, 0x39, 0x46, 0xd7, 0x1a, 0x42, 0x8b, 0xe0, 0x9e, 0x9d, 0x18, 0xf5, 0x6b, 0xae, + 0x71, 0x25, 0xef, 0x8c, 0xc4, 0xd8, 0xa1, 0x56, 0xb7, 0x46, 0xb2, 0xb7, 0xa8, 0xba, 0x87, 0xc6, + 0x68, 0x9a, 0x34, 0x7e, 0x14, 0x91, 0x96, 0xb2, 0x95, 0x19, 0x62, 0xc7, 0xf1, 0x9b, 0x98, 0x5b, + 0x8d, 0xdd, 0x73, 0x11, 0x7c, 0x6e, 0xd5, 0x70, 0xea, 0xb1, 0x37, 0xf3, 0x31, 0xb3, 0xa4, 0x76, + 0xb3, 0xd7, 0x72, 0xc3, 0xfc, 0x11, 0x52, 0x97, 0xbe, 0x7f, 0x85, 0x29, 0x72, 0xc2, 0x5d, 0xd6, + 0x8e, 0x49, 0x34, 0x5f, 0xcc, 0x1b, 0xe0, 0xb3, 0x43, 0x2f, 0xba, 0xb2, 0xbd, 0xb4, 0x6d, 0x6b, + 0xe3, 0x73, 0xc7, 0x77, 0x1f, 0xab, 0x95, 0x96, 0xf3, 0xfb, 0xb1, 0xad, 0x64, 0x87, 0xf8, 0x2a, + 0xbb, 0xe9, 0x26, 0x2d, 0xb7, 0x07, 0x29, 0x6b, 0x2b, 0xee, 0x2c, 0x9f, 0xe1, 0x4e, 0x6e, 0x5f, + 0x5a, 0x19, 0x99, 0xe9, 0xbf, 0x93, 0xef, 0xf0, 0x55, 0xa3, 0x54, 0xb2, 0x45, 0x8e, 0x48, 0xd7, + 0x30, 0x87, 0x1c, 0xbe, 0x11, 0x8f, 0xde, 0x8e, 0x93, 0x1c, 0x69, 0x5f, 0x8d, 0xba, 0x7e, 0x33, + 0x73, 0xb3, 0x06, 0x95, 0xc7, 0x8e, 0x35, 0xa4, 0x1a, 0x56, 0xa8, 0x67, 0x5e, 0x91, 0xa7, 0x38, + 0xe6, 0x7c, 0x75, 0xbd, 0x71, 0xbb, 0xcd, 0x4e, 0x4c, 0xa5, 0xe1, 0x4e, 0x46, 0x52, 0xfc, 0xcf, + 0x69, 0xfb, 0x91, 0xbc, 0xbe, 0x14, 0xf6, 0xc9, 0xac, 0x77, 0xa1, 0xb5, 0x09, 0x34, 0x4d, 0x91, + 0x92, 0xb1, 0x15, 0x7c, 0x23, 0x3b, 0x0c, 0xa8, 0x66, 0x67, 0x59, 0xf1, 0x33, 0x65, 0x1d, 0x1f, + 0x85, 0x0a, 0x88, 0xc9, 0x63, 0x15, 0xba, 0x35, 0x67, 0x3d, 0xfd, 0x0d, 0xec, 0xde, 0x0c, 0xac, + 0x4f, 0xf0, 0x5a, 0x4b, 0x0d, 0x8c, 0xf2, 0xb4, 0x57, 0xb6, 0x44, 0x5f, 0xc1, 0x4e, 0x2b, 0x50, + 0x58, 0xeb, 0x77, 0x63, 0x6d, 0x26, 0x49, 0x7e, 0x0a, 0x75, 0xea, 0x87, 0xcd, 0xd3, 0x6f, 0x7f, + 0x82, 0xba, 0x1a, 0xea, 0x4e, 0xc6, 0xd0, 0xd0, 0xd4, 0xbf, 0x3a, 0x7c, 0x12, 0xd3, 0xa7, 0xb1, + 0xce, 0xc6, 0x6f, 0x82, 0xb2, 0xc1, 0x9d, 0x88, 0xfc, 0x66, 0xa7, 0x6d, 0x0e, 0x58, 0x63, 0x3e, + 0x30, 0x94, 0x31, 0xec, 0xfb, 0x18, 0x6e, 0xa4, 0x6d, 0x93, 0x29, 0x23, 0x09, 0xaa, 0x51, 0xd4, + 0x2a, 0x3f, 0x0a, 0x75, 0x55, 0xa2, 0x24, 0x65, 0xc7, 0x72, 0x4e, 0xed, 0x27, 0xa6, 0xf8, 0xce, + 0x48, 0x5f, 0x33, 0x31, 0xca, 0xe4, 0x6a, 0xdb, 0x1b, 0x99, 0x33, 0x14, 0x7e, 0x14, 0xb7, 0xe5, + 0x64, 0xed, 0xa9, 0xcc, 0x4e, 0x86, 0x76, 0x4d, 0xe0, 0xfe, 0x5f, 0x04, 0xba, 0xce, 0xd6, 0xf7, + 0x33, 0x74, 0x39, 0x7c, 0x16, 0x72, 0xf2, 0xb1, 0xd3, 0x7b, 0x58, 0x4d, 0x0d, 0xe0, 0xf8, 0x9b, + 0x23, 0x95, 0x82, 0xee, 0xe6, 0x95, 0x8f, 0x0a, 0x63, 0xf9, 0x21, 0xc1, 0xb9, 0x9d, 0xdd, 0x5b, + 0x4a, 0x87, 0xa1, 0xb9, 0x19, 0x20, 0xbe, 0x2a, 0x96, 0xd5, 0xa2, 0xb3, 0x3e, 0x14, 0xcd, 0xac, + 0xa1, 0x0d, 0x2d, 0x1d, 0x1a, 0x8f, 0x64, 0xf6, 0x68, 0x6e, 0x84, 0x97, 0x60, 0xdf, 0xfb, 0xe0, + 0xae, 0xe9, 0xa1, 0xa6, 0xcd, 0x8a, 0x22, 0xe1, 0x1e, 0xc6, 0xaa, 0x8b, 0x6a, 0xf1, 0xf0, 0x59, + 0x8c, 0x62, 0xb4, 0x98, 0xcb, 0x6d, 0x6c, 0xb2, 0x36, 0x91, 0x78, 0x2a, 0xd7, 0x1d, 0x68, 0x65, + 0x63, 0x64, 0x28, 0xa7, 0x66, 0x77, 0x7c, 0x29, 0xb9, 0xe3, 0x15, 0xb6, 0x55, 0x54, 0x21, 0x42, + 0xed, 0x13, 0x74, 0x31, 0x0b, 0x0f, 0x7b, 0xfc, 0x16, 0x76, 0x33, 0xf8, 0xfe, 0x5f, 0x8f, 0xe3, + 0x29, 0x7c, 0x15, 0x48, 0xc9, 0xdf, 0x0b, 0x23, 0xfa, 0x54, 0x3a, 0xcc, 0xf8, 0xda, 0x27, 0xbd, + 0xa5, 0x95, 0x5e, 0x0c, 0xd1, 0x1e, 0xc3, 0x7d, 0x1c, 0x1b, 0xda, 0xdc, 0x4e, 0xad, 0xda, 0xc9, + 0x09, 0x21, 0xfe, 0x14, 0x99, 0x17, 0x06, 0xc8, 0xc9, 0x07, 0x77, 0xc2, 0x7a, 0x0a, 0x99, 0x34, + 0x5e, 0xd7, 0x46, 0x87, 0x97, 0xc2, 0x05, 0xb6, 0x3f, 0x49, 0x72, 0x5d, 0xed, 0x3a, 0x06, 0x45, + 0xc5, 0xd7, 0x4a, 0xfa, 0xfc, 0x64, 0x9a, 0xe6, 0x21, 0xc5, 0x46, 0x21, 0x4a, 0xcf, 0x12, 0x32, + 0xa6, 0xe5, 0xbf, 0xd6, 0xde, 0xe7, 0xc7, 0xe1, 0x0c, 0xa8, 0x98, 0xdd, 0x28, 0x54, 0x31, 0x83, + 0xbe, 0x1c, 0xd4, 0xd9, 0x30, 0xef, 0x85, 0x08, 0x8a, 0x3f, 0x7b, 0xb6, 0xfd, 0xb4, 0x7e, 0xeb, + 0xbf, 0xbd, 0xaa, 0x7f, 0x82, 0xa2, 0xa7, 0x93, 0xb1, 0xa4, 0x5d, 0x7c, 0xc8, 0x0e, 0xf1, 0xbc, + 0x96, 0x99, 0xa4, 0x5e, 0x14, 0xbc, 0x76, 0x95, 0xa1, 0x43, 0xce, 0x56, 0xf6, 0x6b, 0xd8, 0xd5, + 0x99, 0x28, 0xbb, 0x54, 0x6e, 0xf8, 0xf3, 0x2b, 0x99, 0xb1, 0xe3, 0xb7, 0x90, 0xdc, 0xc2, 0x1a, + 0xdb, 0xa8, 0x7f, 0x85, 0x35, 0x21, 0xd9, 0x72, 0xf2, 0xf6, 0xb6, 0xa5, 0x23, 0x12, 0x44, 0x6a, + 0xa5, 0xd4, 0x7f, 0x8e, 0xbf, 0x37, 0xe3, 0x54, 0x89, 0x27, 0xf4, 0xf6, 0xfc, 0x41, 0x76, 0x31, + 0xd5, 0xda, 0xa9, 0x11, 0x24, 0xf8, 0xf8, 0x52, 0xd8, 0x31, 0xa9, 0x5b, 0x18, 0x83, 0x33, 0x30, + 0x36, 0x7d, 0xb7, 0x4c, 0xf6, 0x94, 0x9f, 0xe3, 0xed, 0x6f, 0x5a, 0xa7, 0xbe, 0x6f, 0xf8, 0x29, + 0xb6, 0xf7, 0x97, 0x52, 0xd0, 0xcd, 0xd0, 0xef, 0x2f, 0x82, 0xbd, 0x22, 0x34, 0xb2, 0xf3, 0xc3, + 0x53, 0xa4, 0xfc, 0xf8, 0x2c, 0xab, 0xaa, 0x65, 0x0d, 0x34, 0xcb, 0xf1, 0x84, 0x0d, 0x66, 0x38, + 0x39, 0x7c, 0x14, 0xc8, 0xc7, 0xa6, 0x3c, 0x77, 0xbd, 0x92, 0xf2, 0x31, 0xec, 0x7d, 0xf1, 0x98, + 0xdd, 0xc2, 0xc6, 0x0f, 0x69, 0xa4, 0x37, 0xa5, 0x56, 0x8e, 0xcb, 0x98, 0xf1, 0x96, 0xb2, 0x41, + 0x92, 0x24, 0x34, 0x43, 0xb4, 0x62, 0xce, 0xd5, 0x27, 0x96, 0xca, 0xbb, 0xc8, 0xcf, 0x85, 0x08, + 0x5e, 0x32, 0x6e, 0x6c, 0x28, 0x6e, 0x64, 0x6e, 0xa8, 0xe7, 0x3c, 0xa1, 0xfa, 0x94, 0x65, 0x95, + 0x1e, 0xe7, 0xc6, 0x6e, 0xc6, 0x5c, 0x2b, 0x0e, 0x62, 0xb9, 0x8e, 0xb5, 0xf2, 0x31, 0xe1, 0x42, + 0xcc, 0xc7, 0x06, 0xc9, 0x0d, 0x39, 0xf9, 0xa0, 0xff, 0x99, 0xf5, 0xaf, 0x85, 0x28, 0x71, 0xaa, + 0xaa, 0xd3, 0x34, 0x69, 0x1e, 0x47, 0x83, 0xe4, 0xc7, 0xc7, 0x81, 0xda, 0xa6, 0xbe, 0x36, 0x46, + 0x8a, 0x8d, 0xcb, 0xd1, 0xd0, 0xcf, 0xe0, 0xd6, 0xa6, 0xeb, 0x93, 0x0e, 0x7b, 0x66, 0x8d, 0x4a, + 0x30, 0xd5, 0x44, 0xa8, 0xbf, 0xc2, 0x92, 0x77, 0xd8, 0xc8, 0xfd, 0xed, 0xb4, 0x78, 0xd4, 0xc8, + 0x49, 0x19, 0x67, 0xcc, 0xbf, 0x85, 0x3a, 0x0d, 0xd3, 0xa5, 0x46, 0x44, 0x51, 0x2b, 0x36, 0x50, + 0xe8, 0x68, 0x3a, 0x31, 0xa3, 0x25, 0x2b, 0x8c, 0x8c, 0x5f, 0x1d, 0x33, 0x2d, 0xa5, 0x0e, 0x91, + 0x68, 0x8e, 0x24, 0xb0, 0x7d, 0xad, 0xce, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x40, 0x20, 0x30, + 0xab, 0xd1, 0x9a, 0x0e, 0x38, 0x23, 0x2b, 0xde, 0xf1, 0x31, 0x31, 0x64, 0xdb, 0x33, 0x0b, 0x62, + 0x84, 0x0b, 0xcb, 0x33, 0x19, 0xe2, 0x65, 0x99, 0x88, 0x9f, 0x4d, 0x72, 0x8b, 0x55, 0xa8, 0xce, + 0x84, 0xbc, 0x2f, 0xd1, 0xfa, 0xfa, 0xb9, 0x17, 0xca, 0x18, 0xe5, 0xfc, 0x40, 0xf2, 0x8e, 0xd1, + 0x18, 0xec, 0xa8, 0xd2, 0xab, 0x1e, 0x20, 0x2e, 0xf4, 0x67, 0xf9, 0xbc, 0xd7, 0x13, 0x13, 0xb3, + 0x8c, 0x1b, 0xb1, 0x5d, 0xfc, 0x40, 0x40, 0x86, 0xf8, 0x3a, 0xbc, 0x14, 0x52, 0x91, 0x9f, 0xf0, + 0xb2, 0xe4, 0x9c, 0xbc, 0x56, 0xe2, 0x3a, 0x0a, 0xb1, 0x27, 0x45, 0x64, 0x11, 0xe2, 0x07, 0x06, + 0x1d, 0xac, 0x3d, 0x9f, 0xfb, 0xbf, 0xe1, 0x02, 0xbe, 0xd5, 0x55, 0x55, 0x57, 0xe2, 0x37, 0x6d, + 0x33, 0xf5, 0x83, 0x5e, 0x24, 0x10, 0xca, 0x0c, 0x41, 0x6f, 0x3f, 0xf6, 0x71, 0x3e, 0x27, 0xe2, + 0x3c, 0x43, 0x32, 0x49, 0x51, 0xe2, 0x75, 0x88, 0x82, 0x0e, 0x83, 0x3d, 0x17, 0xc2, 0x41, 0x2b, + 0x29, 0x61, 0x79, 0xb3, 0x89, 0x08, 0x6c, 0x21, 0xdc, 0xbb, 0xb3, 0x60, 0x6a, 0xb7, 0xe2, 0x41, + 0x09, 0x6c, 0x68, 0x63, 0x29, 0x97, 0xf8, 0xa3, 0x27, 0x22, 0x1a, 0x4d, 0xa1, 0xf1, 0x17, 0x56, + 0x5f, 0x8b, 0xe9, 0x98, 0x6b, 0x4d, 0xfc, 0xa5, 0x36, 0x7f, 0x12, 0x5d, 0xd0, 0xfc, 0x40, 0x23, + 0xee, 0xef, 0xe2, 0x08, 0x20, 0xd8, 0x6c, 0x33, 0x1f, 0x84, 0x38, 0xae, 0x82, 0x69, 0x54, 0xe4, + 0x13, 0x83, 0x3f, 0x8f, 0xe4, 0x3a, 0xf8, 0xcb, 0xe2, 0xff, 0x76, 0xe1, 0x65, 0x13, 0x88, 0x62, + 0xee, 0xf3, 0x44, 0x50, 0x8e, 0xe2, 0x2a, 0xf2, 0xf1, 0x47, 0x1f, 0xcb, 0x8b, 0x2b, 0x1f, 0x87, + 0x69, 0x15, 0x9d, 0x8d, 0xfd, 0xb4, 0xd7, 0x19, 0xef, 0xfc, 0x47, 0x34, 0xb9, 0xff, 0xc9, 0xa4, + 0x9f, 0xc4, 0xe3, 0xff, 0xf6, 0x57, 0x3f, 0x18, 0x7c, 0xfe, 0x8d, 0x1d, 0x5d, 0x2d, 0xdf, 0x5c, + 0x26, 0x47, 0xae, 0xb6, 0x97, 0x09, 0x90, 0xfd, 0x5b, 0x54, 0xb2, 0x73, 0x77, 0xaa, 0xba, 0xe2, + 0xb7, 0x6e, 0x76, 0x38, 0x88, 0x98, 0x26, 0x28, 0x62, 0xa4, 0x7f, 0x03, 0x33, 0x34, 0x38, 0x8b, + 0x9c, 0x44, 0x67, 0x69, 0x34, 0x34, 0x74, 0xd3, 0x39, 0xd6, 0x58, 0x97, 0xe7, 0x8a, 0xf8, 0x50, + 0x94, 0xe4, 0xea, 0xae, 0x61, 0xac, 0xbe, 0xe7, 0xeb, 0x39, 0x3c, 0xbe, 0x13, 0x8d, 0x18, 0xf6, + 0xe9, 0xa2, 0x2f, 0xf1, 0x94, 0xa8, 0xd2, 0x53, 0x9a, 0x8d, 0x22, 0xac, 0x8b, 0xb4, 0x50, 0xdc, + 0x8e, 0xcb, 0xa3, 0xda, 0xe1, 0x01, 0x80, 0x22, 0x8a, 0xec, 0x40, 0x81, 0x84, 0x0b, 0x23, 0xc1, + 0x81, 0xe2, 0x80, 0x27, 0x35, 0xaf, 0x27, 0xc9, 0x6a, 0xf8, 0x37, 0x13, 0xe7, 0x35, 0xf2, 0x4f, + 0x84, 0x3b, 0x94, 0x83, 0xa8, 0xb8, 0x85, 0x87, 0x2b, 0xd7, 0xf0, 0x50, 0x54, 0xa1, 0x55, 0xf1, + 0xab, 0x08, 0xcb, 0x4e, 0x39, 0xc7, 0xf1, 0x22, 0xcb, 0x81, 0x0f, 0xd2, 0x39, 0x64, 0x5d, 0xd9, + 0xe2, 0x41, 0x5d, 0x1d, 0xee, 0xed, 0x0c, 0xef, 0x36, 0x69, 0xd9, 0x19, 0xa1, 0xcf, 0x12, 0x20, + 0x67, 0x17, 0x08, 0x5b, 0x63, 0x02, 0xa8, 0xcb, 0xf0, 0x44, 0x1b, 0xad, 0x5e, 0x4e, 0xac, 0xae, + 0x09, 0xc3, 0x15, 0x7b, 0xa8, 0x85, 0x46, 0xea, 0x1e, 0xc3, 0x71, 0xf1, 0xc7, 0xeb, 0x5b, 0xec, + 0x28, 0x69, 0x36, 0xca, 0xb8, 0x46, 0xca, 0x67, 0xec, 0x8f, 0x18, 0xeb, 0xd3, 0xf0, 0xa5, 0x34, + 0xf8, 0xee, 0x09, 0x7c, 0xfb, 0x67, 0x9e, 0x5c, 0x2f, 0x86, 0xca, 0xa8, 0xa9, 0xad, 0xdb, 0x4f, + 0xcb, 0xc1, 0x75, 0xb4, 0x56, 0x89, 0x1d, 0x0d, 0xaf, 0x86, 0x4b, 0x37, 0x4a, 0x25, 0xf7, 0x5a, + 0x97, 0x82, 0x71, 0x5a, 0x49, 0x59, 0xdd, 0x3f, 0xc1, 0x46, 0x8e, 0x7a, 0xa5, 0xaf, 0x05, 0x74, + 0x19, 0xa8, 0xc8, 0x9b, 0x0d, 0x1e, 0xe6, 0x3f, 0x57, 0xe4, 0xde, 0xfe, 0xef, 0x77, 0xc4, 0xc1, + 0x2d, 0xf4, 0xe7, 0x7d, 0xdf, 0xe2, 0x88, 0xf9, 0x7b, 0xb8, 0xae, 0x5f, 0xc4, 0xd7, 0x24, 0xbc, + 0xbd, 0x8f, 0x84, 0x62, 0x2f, 0x4c, 0x67, 0x2f, 0x13, 0x49, 0xe1, 0x11, 0x00, 0x96, 0x78, 0xe1, + 0x63, 0xf7, 0x53, 0xef, 0xb1, 0x63, 0x09, 0x1f, 0x42, 0x63, 0x43, 0x4f, 0x17, 0x98, 0x34, 0xee, + 0xff, 0x18, 0x7a, 0xd7, 0x56, 0x35, 0x23, 0x76, 0x64, 0xf8, 0x89, 0x6c, 0xb0, 0xeb, 0xf2, 0xe2, + 0xc9, 0xb8, 0xef, 0xbb, 0x7f, 0x17, 0x4a, 0xf9, 0xb0, 0x2a, 0x4c, 0x89, 0xb2, 0xbc, 0xb1, 0x2c, + 0x3c, 0x3f, 0x13, 0x12, 0x72, 0x24, 0xbd, 0xd9, 0x6f, 0xb3, 0x54, 0x79, 0x67, 0x11, 0x88, 0xc2, + 0x20, 0x90, 0xa5, 0xc2, 0xe0, 0x18, 0xdf, 0x03, 0xb4, 0x0f, 0xce, 0xe1, 0x00, 0x88, 0x7f, 0xbb, + 0xda, 0x47, 0x00, 0xe1, 0xc0, 0xe1, 0x30, 0x5c, 0xe1, 0xc1, 0xe7, 0x88, 0xda, 0xfd, 0xb1, 0x57, + 0x84, 0x04, 0x94, 0x8a, 0x4c, 0x6b, 0x1a, 0x88, 0xfc, 0x11, 0x5e, 0x70, 0xc0, 0x6f, 0x71, 0x12, + 0x77, 0x7c, 0x44, 0xdb, 0x51, 0x7c, 0x44, 0x23, 0xa4, 0xdc, 0x52, 0xdd, 0x53, 0x2e, 0xc5, 0x6a, + 0xe0, 0x8f, 0x8b, 0x97, 0x4d, 0x97, 0xc9, 0x8d, 0x1b, 0x12, 0x5b, 0xee, 0xa2, 0x04, 0x9b, 0x17, + 0x8b, 0xe2, 0x61, 0x2f, 0x2d, 0xb6, 0x2e, 0x5e, 0x99, 0xc9, 0x9c, 0x22, 0x20, 0x75, 0x7f, 0xae, + 0x77, 0x6e, 0xe2, 0xeb, 0x5c, 0x40, 0x82, 0x43, 0xbe, 0x14, 0x97, 0x7a, 0xff, 0x11, 0x88, 0x7e, + 0x2b, 0xbb, 0xf9, 0xb2, 0x08, 0x0a, 0xef, 0x82, 0x28, 0xe2, 0x17, 0xae, 0x1c, 0x4c, 0xb3, 0x42, + 0x20, 0x30, 0x82, 0x78, 0x9c, 0x91, 0x02, 0x48, 0x5a, 0x53, 0xfc, 0x44, 0x5f, 0x15, 0xbe, 0xef, + 0x89, 0x13, 0xe2, 0x45, 0xee, 0x98, 0x87, 0x0d, 0x98, 0x92, 0xf2, 0xf3, 0xfa, 0xf2, 0x70, 0x51, + 0x5b, 0x8c, 0x16, 0x4f, 0x79, 0xdf, 0x71, 0x10, 0x5b, 0x13, 0x82, 0x6b, 0x5b, 0x7b, 0x10, 0x51, + 0x84, 0x78, 0x90, 0x8a, 0xf7, 0x84, 0x02, 0x1c, 0x98, 0x9b, 0x97, 0x2e, 0xe7, 0xfa, 0x84, 0x20, + 0x96, 0x5d, 0xbd, 0xde, 0xf8, 0x71, 0x10, 0x4b, 0x9a, 0xdc, 0x9d, 0xf2, 0x43, 0x2a, 0x7b, 0x47, + 0xe3, 0x8c, 0x48, 0x80, 0x4c, 0x70, 0x39, 0x94, 0x60, 0xf6, 0xec, 0xf8, 0xfe, 0xf7, 0x63, 0x88, + 0xfe, 0xb1, 0x1f, 0x17, 0xab, 0xd6, 0x39, 0xf1, 0xfe, 0x2e, 0x20, 0x47, 0x18, 0x94, 0xe8, 0x53, + 0x4f, 0xeb, 0xa8, 0x6b, 0xb2, 0xbb, 0x78, 0xde, 0x62, 0xad, 0x59, 0xf1, 0x05, 0xad, 0x7c, 0x4f, + 0x89, 0x08, 0x88, 0x9b, 0xf5, 0x0b, 0xd4, 0xbd, 0x64, 0xef, 0xc4, 0x33, 0x98, 0x91, 0x6c, 0x94, + 0xd4, 0x40, 0x90, 0xa4, 0x5c, 0x34, 0xf7, 0x42, 0x02, 0xc2, 0xdc, 0x35, 0x9e, 0xc3, 0x16, 0x32, + 0x39, 0x79, 0xfb, 0xb7, 0x7e, 0xde, 0xfe, 0xdf, 0x87, 0x11, 0x05, 0xb7, 0x7e, 0x94, 0x7b, 0xcf, + 0x5c, 0x5d, 0xdb, 0xf9, 0x73, 0xc2, 0x42, 0x0f, 0xed, 0x49, 0xac, 0xae, 0xb8, 0x43, 0x69, 0x8c, + 0xfd, 0x68, 0xe5, 0x5d, 0xf6, 0xfe, 0x2c, 0xae, 0x87, 0x3f, 0x4d, 0x95, 0xd7, 0x29, 0x5d, 0x70, + 0x4b, 0xcd, 0x55, 0x49, 0x5f, 0xe2, 0x44, 0x05, 0x37, 0x77, 0x89, 0xf7, 0x59, 0x25, 0xee, 0x79, + 0x60, 0x3d, 0xd4, 0x58, 0x76, 0xd4, 0xdb, 0x6c, 0x7f, 0x89, 0x30, 0x5c, 0x0e, 0xd8, 0x82, 0x85, + 0x1d, 0x3b, 0x7c, 0x2d, 0xad, 0xef, 0x93, 0x12, 0x27, 0xd5, 0x45, 0xc9, 0xe4, 0xfc, 0x49, 0xb5, + 0x3c, 0x16, 0x5c, 0xc4, 0xc8, 0x7b, 0xdf, 0xeb, 0x8f, 0x10, 0x6f, 0x23, 0xd8, 0x97, 0x7b, 0xcb, + 0xef, 0xec, 0xa4, 0x0c, 0x0d, 0xb5, 0x87, 0x51, 0x44, 0x41, 0x55, 0xcc, 0x89, 0x6a, 0x36, 0x5b, + 0x51, 0x26, 0x8a, 0x31, 0xc9, 0x08, 0xde, 0x94, 0x6e, 0x10, 0x8c, 0xac, 0x75, 0x60, 0xe2, 0xb8, + 0x31, 0x97, 0x6e, 0x9d, 0xa1, 0x79, 0x78, 0x8f, 0x10, 0x60, 0xec, 0x92, 0xff, 0x04, 0x9d, 0xc5, + 0x7f, 0xf9, 0x4a, 0xf1, 0x0e, 0x0a, 0xc9, 0xcd, 0xce, 0xc3, 0x85, 0x3a, 0x37, 0x45, 0xf1, 0x62, + 0x73, 0x51, 0x75, 0x55, 0x89, 0x31, 0x37, 0x10, 0x39, 0xe3, 0xcc, 0x2b, 0x3c, 0x0f, 0x9f, 0xc6, + 0xed, 0x0f, 0xca, 0x6d, 0x3f, 0x9b, 0xaa, 0x96, 0x23, 0xf0, 0xa7, 0x9b, 0x2d, 0xcd, 0xef, 0x74, + 0x87, 0xd8, 0xed, 0xef, 0xf1, 0x57, 0x8a, 0xf1, 0x23, 0x09, 0x7e, 0x27, 0x2f, 0x04, 0xa2, 0xd7, + 0xaa, 0x93, 0x36, 0x30, 0xe6, 0x00, 0x09, 0x3c, 0x51, 0x05, 0x8b, 0xb4, 0x75, 0x1b, 0xea, 0x11, + 0xd0, 0x53, 0x0c, 0x1a, 0xd2, 0x3e, 0x99, 0xe2, 0x53, 0x20, 0xd1, 0xe4, 0x77, 0xac, 0xf9, 0x56, + 0x4e, 0xe0, 0xb5, 0x0e, 0x41, 0x9f, 0x80, 0xd7, 0x88, 0xfe, 0x8f, 0xf0, 0x88, 0x16, 0x42, 0x84, + 0x85, 0x4a, 0xd5, 0x93, 0x7c, 0x4c, 0x1f, 0x5b, 0xf8, 0xed, 0xc1, 0x95, 0x44, 0x6e, 0xb5, 0x09, + 0x6d, 0x29, 0x3f, 0x4a, 0x47, 0x39, 0xd2, 0x07, 0x30, 0x00, 0xd3, 0x60, 0x8a, 0x78, 0x84, 0x04, + 0x7a, 0xfb, 0xbf, 0x32, 0x3f, 0x8b, 0x75, 0x9b, 0x8a, 0x58, 0xe6, 0xf0, 0x76, 0xf1, 0xbe, 0x16, + 0x1f, 0xc3, 0x8d, 0xd1, 0x73, 0x6b, 0x39, 0x65, 0xc0, 0xbe, 0x8a, 0x5b, 0x6e, 0x21, 0xde, 0xde, + 0x10, 0x8d, 0x28, 0x2a, 0xbf, 0x2e, 0x51, 0x3f, 0x0c, 0xea, 0xdb, 0x76, 0x30, 0x0c, 0x3d, 0x24, + 0x7f, 0xd0, 0x9b, 0x67, 0xae, 0x84, 0x75, 0x98, 0x08, 0x88, 0xd5, 0x81, 0x64, 0x42, 0xfb, 0xd7, + 0x9c, 0x38, 0x11, 0x21, 0xb9, 0xe2, 0x1a, 0x45, 0xe3, 0x48, 0xfc, 0x27, 0xd7, 0xa2, 0x38, 0x22, + 0xae, 0xad, 0xc4, 0xc4, 0x19, 0x2b, 0xd5, 0x7f, 0x10, 0x4c, 0x6f, 0xcd, 0xa6, 0xe8, 0xd6, 0x24, + 0xc2, 0x6f, 0x7e, 0x22, 0x78, 0x99, 0x0b, 0x05, 0x7f, 0x7c, 0x48, 0x93, 0x0a, 0x2e, 0x5e, 0xb9, + 0xaf, 0x79, 0x78, 0x70, 0x4c, 0x1d, 0x4c, 0x40, 0x75, 0xa0, 0x4a, 0x04, 0xa2, 0x30, 0x2a, 0xe3, + 0x9d, 0x48, 0x14, 0x8a, 0xc5, 0x3c, 0x22, 0x24, 0x69, 0x85, 0xc7, 0x33, 0x1a, 0x50, 0xcb, 0xcb, + 0xa0, 0xcb, 0x35, 0x88, 0x85, 0x80, 0x58, 0x7c, 0x00, 0xc0, 0xe0, 0x0e, 0x0c, 0x74, 0xa3, 0x80, + 0x0a, 0x91, 0x49, 0x62, 0x2c, 0x32, 0xc3, 0x51, 0x70, 0x96, 0xcc, 0x19, 0x03, 0x4c, 0x9a, 0xfe, + 0x5f, 0xda, 0xb6, 0xdf, 0x12, 0x06, 0x90, 0xa5, 0x80, 0x3b, 0xc9, 0x25, 0xf4, 0x8c, 0x46, 0x5c, + 0xf9, 0x20, 0x0a, 0x96, 0x00, 0xcb, 0x00, 0x18, 0x90, 0x73, 0x06, 0x4d, 0x04, 0xa9, 0x3a, 0x23, + 0x07, 0x65, 0x50, 0xf1, 0xb6, 0xa0, 0xb2, 0x25, 0x84, 0x44, 0xf1, 0x08, 0xa5, 0xae, 0x24, 0x08, + 0x21, 0x43, 0x39, 0x40, 0x59, 0x45, 0x1d, 0x63, 0xe8, 0x2d, 0xcb, 0xc4, 0x4b, 0x20, 0xcf, 0x0f, + 0x3e, 0x48, 0x9e, 0x35, 0x81, 0x27, 0x0f, 0x30, 0x1d, 0x05, 0xce, 0x00, 0xfa, 0xe1, 0x00, 0x20, + 0x85, 0x0a, 0x57, 0x36, 0x45, 0x6d, 0xa6, 0x4b, 0xa1, 0x6e, 0x2f, 0xac, 0xb6, 0xf2, 0xc7, 0x18, + 0x97, 0x0f, 0x33, 0x45, 0x3a, 0x0b, 0x34, 0x45, 0xad, 0x33, 0x29, 0x2d, 0x3a, 0x00, 0xb2, 0x88, + 0xd4, 0xc9, 0x9e, 0x99, 0x07, 0x39, 0x2d, 0xaf, 0xe5, 0xbb, 0x5a, 0xe3, 0xe6, 0xda, 0x4f, 0x97, + 0x2e, 0xeb, 0x5c, 0xb5, 0x97, 0xcf, 0xc6, 0xde, 0x56, 0x25, 0xe5, 0x85, 0xde, 0xf5, 0x10, 0xb0, + 0xab, 0x70, 0x97, 0xf7, 0x96, 0x1c, 0x49, 0xaa, 0xab, 0xc4, 0x89, 0x18, 0x47, 0x70, 0x31, 0xee, + 0xba, 0xc8, 0x62, 0xee, 0xce, 0x6f, 0x1a, 0xcd, 0xfc, 0x11, 0x89, 0x78, 0x35, 0x33, 0x1a, 0x65, + 0xea, 0xd7, 0x82, 0x11, 0xa6, 0x55, 0x37, 0x91, 0x8a, 0xd1, 0x74, 0x17, 0xac, 0xa2, 0xa8, 0xb4, + 0xca, 0x6e, 0xf9, 0x47, 0x57, 0x20, 0xf0, 0xc3, 0x87, 0x4c, 0x2d, 0x84, 0x7f, 0x1f, 0x86, 0x02, + 0x03, 0x6e, 0xc0, 0x00, 0x8a, 0x93, 0xbc, 0xab, 0x63, 0xea, 0xc4, 0x9e, 0xd6, 0x7e, 0x28, 0x7c, + 0x44, 0xc1, 0x01, 0xe2, 0x30, 0x07, 0xf8, 0xb8, 0xf0, 0x0e, 0x0a, 0x63, 0x4a, 0xfd, 0xb7, 0xb7, + 0x84, 0x40, 0xc2, 0x14, 0xa1, 0x3f, 0x01, 0x82, 0x90, 0x13, 0x15, 0x2a, 0xca, 0xe8, 0x02, 0x85, + 0x2a, 0x14, 0x71, 0x17, 0x24, 0xd6, 0x57, 0xe6, 0x60, 0x86, 0x93, 0x99, 0x6f, 0x21, 0x4a, 0x85, + 0x83, 0x63, 0x82, 0x90, 0x24, 0x8d, 0xb3, 0xac, 0x45, 0xc2, 0x70, 0xb1, 0xa9, 0xbc, 0xd1, 0x7c, + 0xb2, 0x50, 0x6e, 0x0a, 0xa7, 0x61, 0xcd, 0x0f, 0x6e, 0xc3, 0xf8, 0x08, 0x65, 0x58, 0xb6, 0x97, + 0xe0, 0x49, 0x02, 0x48, 0xd9, 0xdc, 0xfb, 0xb8, 0x31, 0x25, 0x2f, 0x77, 0x8d, 0xf8, 0xd0, 0x9a, + 0x9d, 0xea, 0x24, 0x69, 0xcb, 0xa2, 0x1d, 0xf8, 0x71, 0x40, 0x08, 0x76, 0x80, 0xd7, 0x7d, 0x83, + 0x7f, 0xba, 0xaf, 0x1a, 0x6e, 0xc8, 0xbe, 0x36, 0xe9, 0xce, 0xd8, 0xff, 0x8f, 0x7a, 0x1f, 0xea, + 0xb5, 0x43, 0xb6, 0xa0, 0x7c, 0xe3, 0xa4, 0x0f, 0x5b, 0xf8, 0x64, 0x48, 0xd9, 0xc0, 0x79, 0xc7, + 0x0b, 0xa4, 0x22, 0xa1, 0xe1, 0xc2, 0x5d, 0x0f, 0x00, 0xf2, 0xc0, 0xcf, 0x1e, 0x1f, 0x01, 0xd4, + 0x78, 0x38, 0x70, 0x00, 0x2c, 0x14, 0x14, 0xa7, 0x01, 0x60, 0x99, 0xac, 0x37, 0x71, 0xc5, 0x79, + 0x6f, 0xfe, 0x36, 0x59, 0x92, 0x81, 0x51, 0x73, 0xcf, 0x78, 0x3c, 0xd4, 0x22, 0xd8, 0x38, 0xf1, + 0xea, 0x18, 0x8b, 0x09, 0x34, 0x96, 0x2a, 0x99, 0x79, 0x50, 0x13, 0x60, 0x72, 0xb0, 0xeb, 0x15, + 0x0e, 0xc4, 0x4b, 0x12, 0xc2, 0x2b, 0xff, 0x04, 0x62, 0x67, 0x2a, 0xc8, 0x43, 0xa3, 0x54, 0x4f, + 0x56, 0x93, 0x8a, 0x2a, 0x56, 0x9c, 0x77, 0x33, 0xb0, 0xfe, 0x11, 0x31, 0x4c, 0xae, 0xd0, 0x67, + 0x50, 0x69, 0x33, 0x2a, 0x8f, 0xb1, 0x22, 0x73, 0x17, 0x9a, 0x9e, 0xae, 0x09, 0x13, 0x1f, 0x4d, + 0xef, 0xb5, 0x75, 0x2f, 0xa5, 0xc4, 0x02, 0x9b, 0xbe, 0xf9, 0xfb, 0xce, 0xc3, 0x73, 0xfc, 0x41, + 0x8d, 0xe3, 0xe2, 0x1e, 0xb2, 0xe6, 0xfc, 0x4c, 0x91, 0x31, 0x03, 0xa3, 0x0e, 0x8e, 0x27, 0xc3, + 0x47, 0x05, 0x98, 0xf0, 0x4f, 0x0a, 0xf2, 0xcb, 0xc2, 0x9c, 0x1b, 0x9f, 0xf5, 0x6f, 0x12, 0x08, + 0xce, 0x4f, 0x2f, 0xa4, 0xac, 0x20, 0x17, 0xba, 0xd2, 0x00, 0x6a, 0x49, 0x80, 0x57, 0xcd, 0x81, + 0x2b, 0x4c, 0xe0, 0x7d, 0x0b, 0xf0, 0xc8, 0x0f, 0x91, 0xa6, 0x3c, 0x00, 0x09, 0xf1, 0xd3, 0xe5, + 0x50, 0x6a, 0xbd, 0x4b, 0xc7, 0xbf, 0x83, 0xdf, 0x27, 0x1c, 0x13, 0xd4, 0xa8, 0x17, 0x52, 0x10, + 0x43, 0x5d, 0xa6, 0x73, 0x81, 0xc7, 0x41, 0x52, 0xb1, 0xe0, 0x3c, 0x81, 0x03, 0xd0, 0xbc, 0xb4, + 0xa6, 0x9a, 0x69, 0xe1, 0x80, 0x80, 0x52, 0x48, 0x0a, 0xba, 0x6a, 0x1c, 0x87, 0xc7, 0x80, 0x78, + 0x58, 0x0c, 0x1d, 0xf0, 0xaa, 0x1a, 0x9f, 0xe1, 0xd2, 0x35, 0x0e, 0x26, 0x1a, 0x9d, 0xfd, 0x52, + 0x2e, 0x4c, 0x6c, 0x35, 0x28, 0x01, 0xf8, 0xe3, 0x1c, 0xf3, 0x22, 0xc8, 0x45, 0x5e, 0x4f, 0xa6, + 0x9b, 0xa7, 0xd8, 0xfe, 0x1b, 0x3f, 0x2d, 0x63, 0xbf, 0x0a, 0xa5, 0x1c, 0x0f, 0x01, 0x91, 0x85, + 0x3b, 0xf5, 0x39, 0xe6, 0xa0, 0x55, 0xb5, 0x4c, 0xb6, 0x50, 0x46, 0xc7, 0x1c, 0x05, 0x78, 0x58, + 0x0a, 0xb8, 0xa0, 0xc7, 0x9f, 0x38, 0x01, 0xf0, 0xea, 0x80, 0x20, 0x31, 0x41, 0xa8, 0xb4, 0xe3, + 0xd5, 0xea, 0x3b, 0x71, 0x0f, 0x7f, 0x39, 0xd2, 0xb6, 0xa5, 0xd9, 0xff, 0x8f, 0xe2, 0x34, 0xeb, + 0x6f, 0xa9, 0xc5, 0xfe, 0x08, 0x44, 0x8c, 0x20, 0x76, 0x09, 0x46, 0xa2, 0x3f, 0x0f, 0x16, 0x07, + 0x95, 0x86, 0x04, 0x35, 0xf3, 0x38, 0x69, 0x16, 0xbb, 0x39, 0xc1, 0x41, 0x96, 0x37, 0x81, 0xe2, + 0xa0, 0xcf, 0x1e, 0x03, 0x89, 0x41, 0xf6, 0x11, 0x12, 0x36, 0x50, 0xaa, 0x3b, 0x94, 0xd4, 0xd3, + 0x01, 0xfb, 0x49, 0x20, 0x07, 0x8e, 0x05, 0x87, 0x26, 0xe9, 0xc0, 0xe3, 0x81, 0x90, 0xb0, 0x06, + 0x6e, 0xbc, 0xe6, 0xfc, 0xb0, 0x19, 0x41, 0xd4, 0x1d, 0x4a, 0xdc, 0x1d, 0xfc, 0xf8, 0x4b, 0x13, + 0xf4, 0x5a, 0x8c, 0xee, 0xf7, 0x9f, 0xab, 0x2a, 0x22, 0x42, 0x4d, 0xed, 0xf1, 0x21, 0x1a, 0xd6, + 0x56, 0x32, 0x43, 0x13, 0xc4, 0xf1, 0x10, 0x53, 0x52, 0xfd, 0xe5, 0x63, 0x5b, 0x6e, 0x97, 0x0c, + 0x82, 0x0e, 0x6e, 0x10, 0x88, 0x92, 0x02, 0x8d, 0x1c, 0x5a, 0xa4, 0x85, 0x30, 0xc6, 0x57, 0x2d, + 0x69, 0x74, 0x37, 0x7d, 0x02, 0xc6, 0x96, 0xc3, 0x1b, 0x27, 0x8d, 0x77, 0xc3, 0xb8, 0x02, 0xc4, + 0x88, 0x54, 0xc6, 0xe0, 0xac, 0xe9, 0x1a, 0x7e, 0x54, 0x91, 0x40, 0x99, 0xa5, 0x51, 0x36, 0xc3, + 0xe3, 0xcb, 0x0f, 0xe5, 0x08, 0xba, 0x33, 0xbc, 0xb0, 0x57, 0xba, 0x99, 0xfe, 0x5f, 0x0c, 0x9b, + 0xce, 0x59, 0x81, 0xb8, 0x80, 0xbe, 0x2e, 0x8f, 0xdf, 0xdd, 0x3f, 0x82, 0x91, 0x84, 0xdc, 0xb8, + 0x5b, 0x14, 0x19, 0xee, 0x0a, 0xd5, 0xd0, 0xf1, 0xf6, 0x3a, 0x7c, 0xb6, 0xeb, 0x53, 0x0d, 0x2c, + 0xc6, 0x24, 0x10, 0x82, 0xcc, 0x4f, 0x05, 0xcb, 0x0d, 0xfa, 0x96, 0x20, 0x6d, 0x44, 0x70, 0xe6, + 0xf4, 0xcb, 0x08, 0x89, 0x19, 0x1d, 0x2e, 0x57, 0x73, 0xbb, 0xb4, 0xf7, 0x3a, 0xe7, 0x81, 0xc2, + 0x60, 0xa8, 0x22, 0x23, 0x30, 0xee, 0x4f, 0x00, 0x1e, 0x5e, 0xa7, 0x9c, 0x2f, 0xe0, 0x84, 0x61, + 0x7a, 0x99, 0x95, 0xdc, 0x5f, 0x5d, 0x25, 0x24, 0xf1, 0x21, 0x91, 0x91, 0x2e, 0x13, 0x02, 0xa5, + 0xef, 0xc3, 0xc1, 0xc1, 0xd7, 0x9e, 0xdb, 0x85, 0x55, 0x98, 0xa2, 0xf1, 0xb7, 0x69, 0xf7, 0x12, + 0x0c, 0x02, 0x97, 0x72, 0xcb, 0x8c, 0x47, 0x39, 0xef, 0x5d, 0x59, 0xee, 0xbb, 0x58, 0xcb, 0xcf, + 0xf2, 0xc0, 0xc9, 0x91, 0x02, 0x8a, 0x28, 0x25, 0xea, 0xd1, 0x3c, 0x39, 0x82, 0xa2, 0x16, 0x00, + 0x63, 0xdc, 0x75, 0x38, 0x42, 0x76, 0x03, 0xe6, 0xd3, 0x89, 0xa8, 0xfc, 0x20, 0x0a, 0x46, 0x11, + 0x55, 0x0a, 0x99, 0x4c, 0xc5, 0x78, 0x7b, 0xae, 0xd5, 0x65, 0x0a, 0xe1, 0xc0, 0xa5, 0x07, 0xa4, + 0xb9, 0x3d, 0x5b, 0x0f, 0xb8, 0xcb, 0x29, 0x66, 0xe6, 0x36, 0x71, 0x5e, 0x18, 0x10, 0x14, 0x29, + 0xcc, 0x0f, 0x70, 0xfb, 0x03, 0xb6, 0x13, 0xaa, 0x70, 0x0f, 0x3f, 0x85, 0xa8, 0x41, 0xc2, 0x4a, + 0xe4, 0x8a, 0xc4, 0x0f, 0xf1, 0xfd, 0xbd, 0x28, 0x62, 0x04, 0x85, 0x08, 0x28, 0x9d, 0xe0, 0x78, + 0xe2, 0x7e, 0xb6, 0xa2, 0x67, 0x02, 0x29, 0x9c, 0x10, 0x51, 0x9a, 0x4d, 0xe9, 0x92, 0x52, 0xb1, + 0x6d, 0x2b, 0x8e, 0xdd, 0x6d, 0xf1, 0xbc, 0xa0, 0x2f, 0x08, 0x02, 0x81, 0xb2, 0xd1, 0xe3, 0xf3, + 0xc6, 0x54, 0xf7, 0x0f, 0x33, 0x81, 0xc2, 0x41, 0xc8, 0xf0, 0x38, 0x1c, 0x64, 0xa5, 0x80, 0x01, + 0x09, 0xc0, 0x07, 0x0b, 0x14, 0x34, 0x71, 0x0c, 0xf0, 0x00, 0xf2, 0xc0, 0x00, 0xa4, 0x60, 0xa1, + 0xa0, 0x57, 0xb6, 0xda, 0x69, 0xc2, 0xee, 0x06, 0xfe, 0x6d, 0xe4, 0xd3, 0xf6, 0xfc, 0xc6, 0x99, + 0xc5, 0xd2, 0x5a, 0x7c, 0x3a, 0x6e, 0xf4, 0x7f, 0x3e, 0xc5, 0x9b, 0xeb, 0xb1, 0xed, 0xc4, 0x82, + 0x10, 0xa0, 0x91, 0x21, 0xc3, 0x44, 0xb0, 0x33, 0xf8, 0x48, 0xe0, 0x1d, 0xb1, 0xe8, 0x63, 0x01, + 0xb2, 0x79, 0x3a, 0x04, 0x1c, 0x2f, 0x2e, 0xf2, 0x4c, 0xaa, 0x4c, 0xa3, 0x8c, 0x33, 0x0a, 0x10, + 0x91, 0xd3, 0x04, 0xa8, 0xe5, 0x22, 0x7d, 0xdd, 0x5e, 0xc7, 0xf8, 0xb9, 0x54, 0x5a, 0xca, 0xb5, + 0x13, 0xc9, 0x68, 0x56, 0x18, 0xc4, 0xf9, 0x37, 0x9b, 0x82, 0x90, 0x10, 0x23, 0x6c, 0xf9, 0x20, + 0x0d, 0x56, 0x62, 0x05, 0x78, 0x90, 0x07, 0x2d, 0xc2, 0x24, 0xee, 0x64, 0x70, 0x1d, 0xc3, 0xde, + 0x41, 0xc0, 0x60, 0x96, 0xbf, 0x6e, 0xeb, 0x28, 0x64, 0x9e, 0xc0, 0x42, 0x4c, 0x47, 0xc3, 0xc0, + 0x29, 0x4a, 0x27, 0xdf, 0xe1, 0xba, 0xc5, 0x1f, 0xb0, 0x85, 0x89, 0x13, 0x56, 0x36, 0xdc, 0x81, + 0x41, 0xf8, 0x53, 0xae, 0x52, 0xf3, 0x16, 0xf7, 0x0a, 0x60, 0x84, 0x60, 0x81, 0x8b, 0x91, 0x92, + 0xcc, 0x33, 0x4b, 0x5f, 0x1b, 0xe3, 0xd2, 0xb1, 0x9a, 0x77, 0x6c, 0x2e, 0x56, 0x17, 0x89, 0x00, + 0x55, 0x29, 0xf2, 0x26, 0x44, 0xa3, 0xbb, 0xb8, 0x83, 0xf3, 0xf0, 0xc4, 0x98, 0x28, 0xb9, 0xaa, + 0x79, 0x83, 0x3a, 0x8e, 0x77, 0xb2, 0xfa, 0xe0, 0x40, 0x05, 0x01, 0x42, 0x0b, 0x93, 0x2a, 0x2f, + 0x96, 0x31, 0xd5, 0xc4, 0xb8, 0x7f, 0xcc, 0x43, 0x82, 0x07, 0x0d, 0x84, 0xe0, 0x05, 0x4a, 0x32, + 0x8f, 0x05, 0x92, 0xe1, 0x90, 0x20, 0x85, 0x0a, 0x78, 0x3d, 0x2b, 0x72, 0xd8, 0xca, 0x89, 0x7b, + 0x7c, 0x31, 0x0f, 0x3c, 0xfc, 0xb1, 0x96, 0xcd, 0xba, 0x75, 0x84, 0x41, 0xc8, 0x52, 0xdc, 0x6e, + 0x16, 0x32, 0xc7, 0x10, 0xb8, 0xa3, 0x19, 0xf1, 0xf2, 0xd6, 0xd3, 0xb1, 0x4e, 0xe2, 0x75, 0x0a, + 0xc8, 0x00, 0xd0, 0x12, 0x71, 0xb4, 0xea, 0x86, 0x3c, 0xc8, 0x7f, 0xc9, 0x3d, 0x1c, 0x65, 0xe2, + 0x7d, 0x5d, 0xcb, 0xcb, 0x03, 0xbd, 0xb0, 0x7c, 0x77, 0xc1, 0x61, 0xcc, 0x00, 0x87, 0xcc, 0xb2, + 0x81, 0x8f, 0x95, 0x08, 0x76, 0xdb, 0x15, 0x9d, 0xe7, 0xa1, 0xde, 0xd8, 0xab, 0x10, 0xfa, 0x47, + 0xe8, 0x5e, 0x5e, 0x0e, 0xdf, 0x45, 0xcb, 0xf3, 0xea, 0xe2, 0x01, 0x08, 0x47, 0x76, 0xd4, 0x1e, + 0xf0, 0x1b, 0x72, 0x83, 0x8e, 0x35, 0x2d, 0x57, 0x36, 0x2e, 0x08, 0x42, 0x01, 0x42, 0xed, 0xc9, + 0xaa, 0x85, 0x53, 0xd3, 0x00, 0x0d, 0x0f, 0x80, 0xe1, 0xca, 0x85, 0xea, 0x5b, 0x81, 0xd9, 0x2c, + 0x79, 0x17, 0x14, 0x37, 0xf8, 0x58, 0x82, 0xe0, 0x25, 0xc8, 0x4d, 0x57, 0x63, 0x91, 0x30, 0x68, + 0xb9, 0x4e, 0xf2, 0x70, 0xe0, 0xe0, 0x3c, 0x2a, 0x21, 0x23, 0x55, 0x33, 0x7b, 0xf8, 0x5b, 0xaf, + 0x4b, 0x88, 0x64, 0x7b, 0xb8, 0x4b, 0x8c, 0xe0, 0xd9, 0x19, 0xce, 0x1e, 0x5a, 0xcb, 0x00, 0xc7, + 0x57, 0x3c, 0x03, 0xe2, 0xbc, 0xf3, 0xce, 0x38, 0x6f, 0xc3, 0x2c, 0x68, 0x01, 0x85, 0xfc, 0x48, + 0xcf, 0x20, 0x5b, 0xfb, 0x44, 0x68, 0x56, 0xe2, 0x7e, 0xb4, 0xa2, 0xbd, 0x35, 0xfb, 0x89, 0x01, + 0x32, 0x32, 0x2e, 0xdc, 0x71, 0x50, 0x5e, 0x59, 0xad, 0xb7, 0x38, 0xf5, 0x14, 0xc5, 0xc9, 0xcb, + 0xe6, 0xab, 0xe1, 0x13, 0x2a, 0xbb, 0xc4, 0x3e, 0x20, 0x79, 0x60, 0xc4, 0x83, 0xcb, 0x19, 0x63, + 0x85, 0x11, 0x40, 0x07, 0xd4, 0x71, 0xaa, 0x30, 0x9b, 0xb7, 0x54, 0x9b, 0x1d, 0xb4, 0xd3, 0xc9, + 0x83, 0x3a, 0x56, 0xde, 0xcd, 0xac, 0x77, 0xf8, 0x21, 0x01, 0x82, 0x14, 0x33, 0xf3, 0xe5, 0xe1, + 0xc6, 0x1a, 0xbe, 0x6c, 0x34, 0xa3, 0x6c, 0xb6, 0xa2, 0xe9, 0xd6, 0x24, 0x14, 0x8c, 0x9e, 0x38, + 0x7b, 0x47, 0xb2, 0x55, 0x71, 0xdf, 0x04, 0x9c, 0x4a, 0x11, 0x89, 0x90, 0xb1, 0x4c, 0xee, 0x0b, + 0xf8, 0x90, 0x42, 0x3c, 0xa5, 0x1c, 0xca, 0x8c, 0xef, 0x92, 0xd8, 0x81, 0xea, 0xb5, 0x76, 0xad, + 0x61, 0x01, 0x01, 0x49, 0x61, 0x88, 0xe1, 0xf6, 0x2c, 0xbb, 0x12, 0x3d, 0x4b, 0x75, 0x09, 0xe0, + 0x51, 0xaa, 0x23, 0x8f, 0xd4, 0xb6, 0x87, 0x71, 0x2f, 0x70, 0x52, 0x05, 0x11, 0xa4, 0x63, 0x3b, + 0xa9, 0x1e, 0xa5, 0x52, 0x46, 0x2e, 0x77, 0xb5, 0x83, 0x73, 0x96, 0x0f, 0xf1, 0x52, 0xd6, 0x01, + 0x5f, 0xcc, 0xb4, 0x5f, 0xc2, 0x3c, 0x82, 0x5d, 0xee, 0xb9, 0x08, 0x6e, 0x9d, 0x7c, 0xa7, 0xaa, + 0xdf, 0x62, 0xab, 0x57, 0xcb, 0x7b, 0xc2, 0x9c, 0x46, 0x2b, 0xc5, 0x19, 0xfb, 0xdc, 0x3a, 0xce, + 0x00, 0x44, 0xe5, 0x25, 0x7e, 0xe9, 0x58, 0xa4, 0xff, 0xf7, 0xee, 0xa5, 0xee, 0x4e, 0x05, 0x90, + 0x6d, 0xf4, 0x7f, 0x2f, 0xf1, 0x2f, 0x35, 0xc9, 0x5f, 0xc3, 0x4c, 0xc0, 0x01, 0xc2, 0xd1, 0x67, + 0x54, 0x13, 0x4b, 0x59, 0x01, 0xbd, 0x77, 0xdb, 0x15, 0x77, 0xd3, 0x70, 0x77, 0xe2, 0xb3, 0x9f, + 0x22, 0xa2, 0x1e, 0x50, 0x0f, 0xa7, 0xb8, 0x1c, 0x60, 0x11, 0xa7, 0xa7, 0x77, 0x6c, 0x1d, 0xf8, + 0xff, 0x97, 0x6d, 0xb6, 0x98, 0xb6, 0x25, 0xac, 0xe9, 0xa7, 0xb6, 0xde, 0x0c, 0x00, 0x2a, 0x03, + 0x62, 0x8c, 0x94, 0x01, 0x42, 0x0c, 0xa9, 0xf6, 0x55, 0x0e, 0x2f, 0x52, 0xa0, 0xa3, 0x21, 0x74, + 0x4a, 0x9c, 0x80, 0x01, 0x25, 0x1e, 0x17, 0x3c, 0x38, 0x58, 0x06, 0x78, 0x00, 0x70, 0xb0, 0xc9, + 0x8e, 0x44, 0x9a, 0x17, 0x61, 0xa9, 0x40, 0xee, 0xb3, 0x73, 0x77, 0xb6, 0xb8, 0x90, 0xc0, 0x52, + 0x40, 0x0f, 0x0e, 0xa4, 0x70, 0x5b, 0xa3, 0x88, 0xb6, 0xc3, 0x61, 0x2d, 0x4e, 0xf2, 0xc1, 0x9f, + 0x86, 0x40, 0x1e, 0xbd, 0x6e, 0xc7, 0x02, 0x40, 0x40, 0x21, 0x11, 0xc1, 0x1e, 0xdc, 0x88, 0xe1, + 0xa1, 0x6d, 0xfa, 0xde, 0xef, 0x62, 0x07, 0x38, 0x91, 0x95, 0x74, 0xfd, 0x65, 0x9b, 0x64, 0xc7, + 0xd9, 0x72, 0x0f, 0x1e, 0x01, 0xf3, 0x51, 0x98, 0x00, 0xd4, 0xc2, 0x01, 0x01, 0x93, 0xb8, 0x48, + 0xd2, 0x91, 0xcc, 0x2f, 0xdb, 0x2d, 0x93, 0xb8, 0xf7, 0x34, 0x71, 0x3e, 0x20, 0x79, 0x51, 0x74, + 0x0f, 0xf3, 0x09, 0xbd, 0xc7, 0x72, 0x11, 0xdf, 0x5c, 0x86, 0x12, 0x70, 0xb0, 0x03, 0x51, 0x1c, + 0xf1, 0x85, 0x0a, 0x00, 0x01, 0x25, 0x24, 0x00, 0x2a, 0x1f, 0x4a, 0x33, 0x31, 0x92, 0xec, 0x1f, + 0xd7, 0x23, 0xc7, 0xe0, 0x5b, 0x38, 0x18, 0x0d, 0x66, 0x4e, 0xb2, 0x4f, 0xcf, 0x0f, 0xd7, 0x84, + 0x42, 0x90, 0x57, 0xe0, 0x00, 0xf8, 0x3e, 0x25, 0x14, 0x68, 0x8b, 0xd2, 0x19, 0x7f, 0x07, 0x0f, + 0x22, 0x99, 0x41, 0x2d, 0x4b, 0x2a, 0xf0, 0xc5, 0x07, 0x30, 0xc6, 0x3c, 0xd8, 0x25, 0xe0, 0xd1, + 0xc9, 0xdc, 0x8d, 0x15, 0x88, 0x01, 0x50, 0x36, 0x3e, 0xc2, 0x88, 0x4a, 0x1f, 0x81, 0xa8, 0xf7, + 0xa3, 0x92, 0xee, 0xd6, 0x64, 0x95, 0x40, 0x0d, 0x47, 0x43, 0xe4, 0x3b, 0x53, 0xc7, 0x6e, 0xae, + 0xf1, 0x78, 0xc0, 0x00, 0x2c, 0x03, 0x0d, 0x57, 0x61, 0x39, 0xf8, 0x76, 0x70, 0x06, 0x50, 0x1b, + 0x57, 0x3b, 0x24, 0x0a, 0xff, 0xf4, 0xb2, 0x77, 0x3f, 0x09, 0xe0, 0x5e, 0x3f, 0xe2, 0x58, 0x17, + 0xb6, 0x05, 0xf5, 0xd3, 0x71, 0xac, 0x12, 0x22, 0xdf, 0xf9, 0xfe, 0x0e, 0x41, 0x80, 0xd1, 0x41, + 0xfc, 0xa4, 0xda, 0x83, 0xf0, 0x1a, 0x8a, 0x43, 0xf9, 0xb8, 0x5b, 0x1d, 0x3f, 0x9e, 0x00, 0x05, + 0x52, 0x07, 0x71, 0xa9, 0x10, 0x10, 0x1f, 0xb2, 0x47, 0xa5, 0xe4, 0xfd, 0x12, 0x72, 0xf8, 0x05, + 0x58, 0xb0, 0x38, 0xb9, 0x3a, 0x79, 0xfb, 0x7c, 0x40, 0xc8, 0xae, 0xc2, 0x55, 0x6c, 0x15, 0xcb, + 0x17, 0x75, 0x5c, 0x0b, 0x59, 0xa7, 0x36, 0x08, 0x24, 0x7e, 0xdb, 0xf1, 0x11, 0x85, 0x3f, 0x8f, + 0xd1, 0xd1, 0x07, 0x8f, 0xb7, 0x9e, 0x39, 0x55, 0x70, 0x23, 0x49, 0xb8, 0x72, 0xc3, 0xb9, 0x63, + 0xac, 0x17, 0x74, 0x2d, 0x82, 0xe2, 0x85, 0x2b, 0x2e, 0x0d, 0xeb, 0xf8, 0x91, 0x98, 0x49, 0x95, + 0x8d, 0xf9, 0x73, 0xa8, 0x06, 0x25, 0x76, 0x58, 0xdd, 0x33, 0xb0, 0xe7, 0xf6, 0xff, 0xe0, 0x94, + 0xac, 0x2f, 0x01, 0xdd, 0xe4, 0x8d, 0x21, 0x3c, 0x11, 0x5c, 0x09, 0x34, 0xbb, 0x96, 0x69, 0x14, + 0x39, 0x80, 0x28, 0x9b, 0x20, 0x96, 0x71, 0x76, 0x54, 0xd9, 0xa2, 0x4d, 0xe0, 0xd2, 0xa6, 0x30, + 0x65, 0x42, 0x16, 0xe3, 0x9a, 0x27, 0x84, 0x70, 0x64, 0xe1, 0x28, 0x44, 0xfc, 0x63, 0x01, 0x28, + 0x6a, 0xb2, 0x95, 0x11, 0xe1, 0x15, 0xcb, 0xe1, 0xe4, 0x60, 0x87, 0x61, 0x63, 0x10, 0x86, 0x10, + 0x7f, 0xe1, 0xe2, 0xe0, 0x5e, 0x70, 0x00, 0x0f, 0x9d, 0x00, 0x01, 0x2c, 0x07, 0x60, 0x7c, 0x2f, + 0xc8, 0x25, 0x0e, 0xd6, 0xaf, 0x00, 0x79, 0xb5, 0xa6, 0x50, 0xc5, 0xed, 0xe9, 0x5b, 0x62, 0x50, + 0x57, 0x10, 0xff, 0x47, 0x20, 0xb6, 0x18, 0x62, 0x5f, 0x1a, 0xe8, 0xad, 0xf1, 0xfc, 0x40, 0x91, + 0x95, 0x21, 0x37, 0x1e, 0xfe, 0xad, 0x4e, 0x2b, 0xf1, 0x08, 0x7b, 0x96, 0xc4, 0x0e, 0x03, 0xcf, + 0x0e, 0x79, 0x63, 0xe0, 0xc0, 0x3b, 0xae, 0x39, 0x70, 0x50, 0x6f, 0x71, 0x03, 0x87, 0x8f, 0x2c, + 0x06, 0x7b, 0xd6, 0x6e, 0xec, 0xa7, 0xf1, 0x1f, 0x20, 0x9d, 0xdf, 0xcd, 0xdd, 0xc1, 0x4f, 0x21, + 0x17, 0x52, 0xf2, 0x5e, 0xfe, 0x20, 0x85, 0x83, 0xcf, 0xc4, 0x3e, 0x1b, 0x50, 0x02, 0xdd, 0xa4, + 0xc6, 0x48, 0xfc, 0xe3, 0x76, 0xbd, 0xa2, 0xc1, 0xd7, 0xc2, 0xea, 0x96, 0x0d, 0x82, 0x64, 0xce, + 0x1b, 0x05, 0xda, 0xdc, 0x30, 0xd4, 0x12, 0x2b, 0x71, 0xcd, 0xdf, 0xfe, 0x04, 0x80, 0x53, 0x07, + 0x40, 0xf0, 0xf0, 0x1c, 0x7e, 0x3d, 0x81, 0xd0, 0x78, 0x78, 0x38, 0x5b, 0xbc, 0xac, 0x5c, 0x89, + 0xf0, 0x4e, 0x22, 0x0f, 0x7d, 0x5d, 0x8d, 0xb3, 0x3e, 0xf1, 0x02, 0x0a, 0x4e, 0x03, 0x96, 0xfc, + 0x77, 0x7c, 0x0c, 0x7c, 0xa5, 0xbd, 0xc7, 0x77, 0x2b, 0x17, 0x70, 0x7f, 0xd9, 0x2f, 0x70, 0x35, + 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x41, 0x20, 0xb0, 0xa8, 0xdc, 0xc2, 0x1e, 0xf0, 0x67, + 0xd9, 0x5e, 0xee, 0x27, 0x98, 0x83, 0xf8, 0x82, 0xbf, 0x97, 0x55, 0xf9, 0x69, 0x9f, 0x83, 0xdf, + 0xaf, 0x89, 0x1c, 0x26, 0xaa, 0xba, 0xb4, 0x95, 0xdc, 0x12, 0x74, 0x13, 0xeb, 0xe8, 0x8e, 0x45, + 0xc4, 0x88, 0x16, 0x16, 0xbd, 0x93, 0x71, 0x83, 0x1e, 0x26, 0xca, 0x9c, 0x72, 0x9f, 0xba, 0xa1, + 0x2f, 0xc4, 0x90, 0x43, 0xeb, 0x07, 0xbf, 0x25, 0xf9, 0x7d, 0x44, 0xf8, 0x9f, 0x88, 0x2d, 0xdd, + 0xa6, 0xb8, 0x88, 0xbe, 0x83, 0x2c, 0x82, 0x3e, 0x40, 0xc4, 0xd9, 0x78, 0x91, 0x67, 0xbd, 0xdc, + 0x56, 0x7a, 0x7c, 0x49, 0x08, 0x9b, 0xdf, 0xdd, 0x6d, 0x3b, 0xb8, 0x98, 0x24, 0x17, 0xc7, 0xae, + 0x3f, 0x12, 0x24, 0x58, 0xee, 0x55, 0xf7, 0xc4, 0xf8, 0x47, 0xe2, 0x0c, 0x26, 0xee, 0x2b, 0xc4, + 0x88, 0x87, 0xfa, 0x08, 0xf4, 0x5f, 0x14, 0x10, 0x76, 0x47, 0x61, 0x2a, 0xeb, 0x35, 0x21, 0x97, + 0x3c, 0x64, 0x5d, 0x5e, 0x2b, 0xdd, 0x59, 0x28, 0x1c, 0x97, 0x26, 0xa9, 0x72, 0x2f, 0xc2, 0x00, + 0x84, 0xab, 0x3a, 0x4b, 0xfc, 0x51, 0xb2, 0x75, 0x58, 0x85, 0x07, 0xcd, 0x9f, 0xea, 0x27, 0xf4, + 0x77, 0xf8, 0x28, 0x23, 0xd2, 0xee, 0xef, 0xf3, 0x08, 0x77, 0xf1, 0x02, 0x02, 0x5d, 0x25, 0x51, + 0x7f, 0x13, 0x1f, 0x2f, 0x7b, 0x3e, 0x1f, 0x3a, 0xd7, 0x89, 0xb1, 0xc4, 0x4d, 0x12, 0x20, 0xd7, + 0x97, 0xb7, 0xc4, 0x02, 0x32, 0xa7, 0x95, 0xee, 0x41, 0x24, 0x40, 0x82, 0x9d, 0xb5, 0x25, 0x3f, + 0x04, 0xf1, 0xd4, 0xc3, 0x03, 0x03, 0x9d, 0x7d, 0xb5, 0x7e, 0x26, 0x0b, 0x23, 0x15, 0xab, 0x28, + 0x14, 0xd2, 0x50, 0x04, 0xbe, 0x9a, 0x94, 0xc5, 0xc1, 0x95, 0x94, 0xfc, 0x4d, 0xf3, 0x7f, 0x11, + 0x16, 0x67, 0xbe, 0xaf, 0xc4, 0x41, 0x54, 0x37, 0x58, 0x7d, 0x89, 0x27, 0x98, 0x17, 0x54, 0x78, + 0x01, 0x7b, 0x19, 0x1e, 0xba, 0x0e, 0x17, 0x8f, 0x82, 0x8c, 0x90, 0x52, 0xd6, 0x86, 0xa6, 0xd9, + 0x7e, 0x26, 0x6e, 0x17, 0xaf, 0x84, 0x61, 0x02, 0xbb, 0xf9, 0xb3, 0x89, 0xe1, 0xb3, 0x13, 0x17, + 0xc3, 0xca, 0x30, 0xff, 0x2a, 0x90, 0x2b, 0xe5, 0xbc, 0x24, 0x28, 0xd0, 0x92, 0x6f, 0x7d, 0xe3, + 0x58, 0x74, 0xed, 0x4f, 0x37, 0x20, 0x69, 0x6a, 0xbe, 0x13, 0xb3, 0xd4, 0xd4, 0x23, 0x23, 0x94, + 0x1c, 0xa2, 0xea, 0x06, 0x3a, 0x0e, 0xd4, 0x67, 0x08, 0x05, 0x85, 0xe2, 0xb7, 0xcd, 0x04, 0x9d, + 0x84, 0xc7, 0xe2, 0x42, 0x85, 0xbc, 0x57, 0x2c, 0x98, 0xa9, 0x20, 0x8d, 0x16, 0xba, 0x0c, 0xe2, + 0x27, 0xdd, 0xce, 0x22, 0x20, 0xc8, 0x6c, 0x69, 0xdf, 0xba, 0xe0, 0x8a, 0x92, 0xb0, 0xad, 0x70, + 0x80, 0x80, 0x59, 0x4c, 0xa8, 0xfc, 0x42, 0x4f, 0x11, 0xa6, 0xb5, 0x3f, 0xd3, 0xaf, 0x97, 0x08, + 0x44, 0x4f, 0x15, 0x02, 0xbc, 0xf6, 0x07, 0x88, 0x20, 0x0f, 0x84, 0x04, 0xb9, 0xc1, 0xc2, 0x6d, + 0x3f, 0x90, 0x59, 0x54, 0x72, 0x0b, 0x42, 0xd3, 0x4c, 0x9c, 0x40, 0x90, 0x88, 0x60, 0x5b, 0x93, + 0xe5, 0xd1, 0x95, 0x3d, 0xea, 0x39, 0xd4, 0x6d, 0x1b, 0x4c, 0x40, 0x81, 0x67, 0x15, 0xb3, 0x9b, + 0xd5, 0x71, 0x10, 0xc4, 0xf0, 0xe1, 0xad, 0x49, 0x75, 0xfb, 0xf8, 0xab, 0xf1, 0x01, 0xc1, 0x2b, + 0xba, 0xf1, 0xce, 0xff, 0x0c, 0x0c, 0x97, 0x41, 0xb7, 0x90, 0xf1, 0xe2, 0x49, 0x1c, 0xd0, 0x51, + 0x71, 0x2d, 0x7f, 0xb6, 0x6d, 0xf0, 0x41, 0xe5, 0xe3, 0x2b, 0x11, 0x6f, 0x81, 0x65, 0xaa, 0x40, + 0x63, 0xae, 0x10, 0xcd, 0x41, 0x8d, 0xc7, 0x81, 0x23, 0x2b, 0xa6, 0x17, 0x1f, 0xa6, 0x4f, 0xeb, + 0x08, 0x9f, 0x94, 0x4a, 0x6d, 0xef, 0x82, 0x62, 0xd2, 0xb4, 0xda, 0x6d, 0xa7, 0x94, 0x57, 0x43, + 0x62, 0x9f, 0x94, 0x2d, 0xba, 0x93, 0x85, 0x0b, 0x18, 0xf5, 0xc4, 0x17, 0x30, 0x68, 0x2d, 0x6b, + 0x00, 0x69, 0xe6, 0xc9, 0xdc, 0x64, 0x18, 0x9d, 0x38, 0xe7, 0x13, 0x1d, 0x86, 0xf7, 0xdd, 0xf7, + 0x7f, 0x97, 0xc8, 0xff, 0x66, 0x40, 0xea, 0x60, 0xc9, 0xb9, 0x8f, 0x6c, 0x70, 0x20, 0x4a, 0x1f, + 0x89, 0xbd, 0x38, 0x42, 0xee, 0x58, 0xf5, 0x05, 0x54, 0x13, 0x6b, 0x8d, 0x61, 0x50, 0xdf, 0x8b, + 0x70, 0x70, 0x05, 0x10, 0x50, 0x14, 0x71, 0x03, 0x90, 0x54, 0x7f, 0xc1, 0x93, 0xc9, 0x6b, 0x25, + 0x56, 0xea, 0x42, 0xf8, 0x28, 0x2e, 0x08, 0xa8, 0x87, 0x11, 0x00, 0x09, 0xbd, 0xd8, 0x93, 0x3a, + 0x9d, 0xfa, 0x69, 0xbb, 0x44, 0x9d, 0x79, 0x32, 0x51, 0xa4, 0x3f, 0xb9, 0xc9, 0x97, 0x2b, 0x01, + 0xb6, 0xd2, 0x06, 0x75, 0x9b, 0x44, 0x35, 0x28, 0x0c, 0x5c, 0x09, 0x02, 0x43, 0x65, 0x1b, 0x1a, + 0x15, 0x91, 0xc8, 0xba, 0x85, 0xa4, 0x88, 0x05, 0x4d, 0xb6, 0x71, 0xae, 0xe9, 0x93, 0x0f, 0xf5, + 0x08, 0x41, 0x39, 0x94, 0xd8, 0xa7, 0x70, 0x5e, 0x35, 0x97, 0x71, 0x10, 0xa7, 0x14, 0x69, 0x8a, + 0x32, 0xc6, 0x4e, 0xc8, 0x28, 0xcb, 0x6f, 0x70, 0x33, 0x06, 0x32, 0xde, 0x30, 0xe0, 0xc6, 0x33, + 0xb1, 0xdf, 0x88, 0x82, 0x99, 0xce, 0x0a, 0xdf, 0x96, 0x2b, 0x10, 0xb0, 0xf6, 0x94, 0x3f, 0xb4, + 0x5d, 0x9b, 0xf1, 0x02, 0x02, 0x99, 0xff, 0xc7, 0x35, 0x15, 0xdd, 0xdd, 0x6e, 0x71, 0x77, 0xe1, + 0x01, 0x20, 0x8e, 0x52, 0x19, 0x71, 0x7b, 0x84, 0x21, 0x7a, 0x5c, 0x28, 0xa9, 0x03, 0x04, 0x51, + 0x77, 0x30, 0x89, 0xf5, 0xa7, 0xc0, 0xe0, 0x57, 0xa7, 0x8f, 0xe3, 0xf1, 0x11, 0xb0, 0xd9, 0xe7, + 0xc9, 0x8d, 0x72, 0xb6, 0x8e, 0xe6, 0xed, 0xa2, 0xdc, 0x92, 0xc7, 0xb5, 0x32, 0xed, 0xb5, 0x10, + 0xf5, 0x6f, 0x3a, 0xe2, 0x7b, 0xaf, 0xe0, 0x87, 0x96, 0xaa, 0xbc, 0x4c, 0x7e, 0xb1, 0xf3, 0x4b, + 0xbb, 0xbd, 0x59, 0x73, 0xe2, 0xfb, 0xa3, 0x6a, 0x58, 0xaa, 0xe1, 0x12, 0xa1, 0xd5, 0xdb, 0x5e, + 0xce, 0x43, 0xbe, 0x1b, 0xd8, 0xd6, 0xbe, 0x65, 0x36, 0xd3, 0xf2, 0xf3, 0x61, 0xa1, 0xe2, 0xc9, + 0x9a, 0x82, 0xfa, 0xaf, 0x8e, 0xbb, 0xef, 0xff, 0x6d, 0xfe, 0x26, 0xa6, 0x9d, 0xcf, 0xed, 0xf0, + 0x8c, 0x15, 0x16, 0xee, 0xee, 0x14, 0x54, 0xf8, 0x51, 0xf2, 0x37, 0x17, 0x10, 0x04, 0xb4, 0x07, + 0x8c, 0x94, 0x72, 0x00, 0x02, 0x00, 0x99, 0x44, 0xeb, 0x0c, 0x82, 0x90, 0xa5, 0xb2, 0xe7, 0x83, + 0x4e, 0x06, 0x85, 0xa2, 0x51, 0x4a, 0x59, 0x9b, 0x09, 0x80, 0x0a, 0xb3, 0x52, 0xb3, 0x98, 0x0e, + 0xac, 0x93, 0xf8, 0x80, 0xa1, 0x38, 0x35, 0x59, 0x07, 0x14, 0x09, 0x5d, 0x1a, 0xb2, 0xa7, 0x00, + 0x01, 0xae, 0x30, 0x48, 0x05, 0xc5, 0x80, 0x01, 0xa9, 0x60, 0x00, 0x5a, 0xae, 0x3a, 0x10, 0xac, + 0x02, 0xe4, 0xde, 0xe3, 0xf8, 0x88, 0x8e, 0x05, 0x8e, 0x4b, 0xc6, 0x06, 0x13, 0x9d, 0x4d, 0x03, + 0xf1, 0x59, 0x70, 0x56, 0x58, 0xef, 0x7c, 0x48, 0x81, 0xf7, 0x61, 0x3a, 0x9b, 0x14, 0x7d, 0xa3, + 0xde, 0x3b, 0xf3, 0xe2, 0x02, 0x91, 0x41, 0xa4, 0x00, 0x04, 0x64, 0x83, 0x28, 0x7a, 0x7c, 0xae, + 0xec, 0x00, 0x56, 0xb0, 0x0f, 0xa7, 0xdf, 0x1f, 0x96, 0xf9, 0x6c, 0xfd, 0x22, 0xf3, 0xaa, 0xc7, + 0x3c, 0x48, 0xce, 0xba, 0x5e, 0x21, 0xf9, 0xa9, 0xe3, 0xde, 0x81, 0x7c, 0xbe, 0x7f, 0x57, 0x98, + 0x85, 0x7d, 0xe9, 0xc5, 0x44, 0x81, 0xbd, 0xcf, 0x88, 0x05, 0x71, 0x58, 0xfa, 0x13, 0xdc, 0x67, + 0x4e, 0x3d, 0xd0, 0x67, 0xc5, 0x24, 0xfa, 0x3f, 0x13, 0x0a, 0x64, 0xf5, 0x06, 0xba, 0x8f, 0x2c, + 0xa2, 0x78, 0x60, 0x3a, 0xaa, 0x0a, 0x55, 0x12, 0x98, 0xf7, 0xc1, 0x54, 0x1f, 0x60, 0x2a, 0x95, + 0x2b, 0xf2, 0x0f, 0x0a, 0xca, 0x99, 0x0e, 0x2f, 0x54, 0xa1, 0x89, 0x86, 0xe6, 0xd8, 0x75, 0x09, + 0x79, 0x28, 0x7e, 0x14, 0x7b, 0x04, 0x7c, 0x97, 0x34, 0xbf, 0x70, 0xb7, 0xce, 0xcb, 0x88, 0x91, + 0x30, 0x89, 0xdc, 0xdd, 0x3e, 0xee, 0xf2, 0xb1, 0xf1, 0x23, 0x0d, 0xbd, 0xd5, 0x8c, 0x4d, 0x8d, + 0xdf, 0x53, 0xf5, 0x8c, 0x5a, 0xc7, 0xe2, 0x4a, 0xdb, 0x7f, 0x2f, 0x10, 0xe6, 0x18, 0x02, 0x08, + 0x52, 0x2b, 0x71, 0x5b, 0xe5, 0xea, 0x4d, 0x77, 0x77, 0x6d, 0xbc, 0x28, 0xd6, 0x4a, 0x6b, 0x4e, + 0x18, 0x80, 0xc8, 0xe2, 0x33, 0x4c, 0x56, 0xa6, 0x40, 0x9e, 0xb2, 0xd0, 0x05, 0x5b, 0x6c, 0x2f, + 0x2f, 0xbe, 0xf6, 0x61, 0x6e, 0xf0, 0x62, 0x0e, 0x44, 0x14, 0x7f, 0xe5, 0xf9, 0x32, 0x69, 0x33, + 0xf8, 0x21, 0x05, 0x21, 0x49, 0xd2, 0x39, 0xf2, 0xcf, 0x87, 0x81, 0xce, 0x71, 0x0f, 0x10, 0xe2, + 0x00, 0x01, 0x5a, 0xb7, 0x27, 0x4c, 0xc2, 0xea, 0x54, 0xa2, 0x50, 0xc4, 0x08, 0x05, 0xa5, 0x4a, + 0xf4, 0xf3, 0xef, 0x8a, 0xbb, 0xbb, 0xcd, 0xfe, 0x24, 0x22, 0x46, 0x87, 0xc4, 0x09, 0x58, 0xfa, + 0xde, 0x78, 0x0b, 0xb8, 0x30, 0x3c, 0x40, 0x52, 0x8d, 0xc7, 0xe0, 0x1e, 0xcf, 0x24, 0x31, 0xfc, + 0x45, 0x62, 0xb9, 0xbd, 0x2e, 0xe1, 0x91, 0x20, 0x8e, 0xd5, 0x57, 0xb8, 0x81, 0x03, 0xc9, 0x09, + 0x8f, 0x4e, 0x4f, 0x0c, 0x3d, 0xb3, 0x5f, 0x53, 0x14, 0x8e, 0x3d, 0x7e, 0x31, 0x08, 0xc2, 0xc4, + 0x42, 0x45, 0x97, 0xd3, 0x83, 0x6c, 0x3b, 0x00, 0x14, 0xa8, 0xdb, 0x84, 0x23, 0x75, 0x8d, 0x52, + 0xbb, 0x06, 0xc4, 0x24, 0x9b, 0x07, 0x1c, 0xb0, 0xfa, 0x3e, 0x7e, 0xaa, 0xa0, 0x9d, 0x15, 0x88, + 0xfb, 0xfc, 0x3d, 0xd6, 0xaf, 0x90, 0x8f, 0x7f, 0x89, 0x2e, 0xee, 0xef, 0x97, 0x12, 0x13, 0x38, + 0xba, 0xa4, 0x95, 0x6b, 0x89, 0x84, 0xea, 0xbd, 0x8c, 0xd9, 0x47, 0xe2, 0x84, 0x5e, 0x71, 0x82, + 0xf7, 0xf8, 0x53, 0xcb, 0x4d, 0xda, 0x72, 0xdb, 0xbb, 0xb6, 0xac, 0x66, 0x63, 0xbc, 0x08, 0x00, + 0x88, 0xb8, 0x2d, 0x18, 0xc6, 0xed, 0x6d, 0x9f, 0x1b, 0x3d, 0x8a, 0x03, 0x2d, 0x0b, 0x62, 0x83, + 0x15, 0x8a, 0x0c, 0x51, 0x81, 0xb6, 0xd8, 0x4e, 0x78, 0xef, 0x8b, 0x54, 0xb1, 0x8e, 0xf8, 0xb1, + 0x96, 0x0f, 0x41, 0x62, 0x3c, 0xf4, 0xfc, 0x38, 0xe0, 0x00, 0x88, 0x86, 0x4a, 0xc1, 0x57, 0x3b, + 0xb8, 0x63, 0xe4, 0x57, 0xc9, 0xe4, 0xef, 0xd6, 0x8c, 0x49, 0xf6, 0x22, 0x96, 0x0f, 0xde, 0x7d, + 0x15, 0x1c, 0x6c, 0x80, 0x03, 0x79, 0x78, 0x0d, 0xa4, 0x88, 0xa5, 0xd3, 0xc1, 0xad, 0xde, 0x08, + 0x41, 0x88, 0x50, 0x87, 0x00, 0x38, 0x31, 0xc7, 0x40, 0x77, 0xd6, 0x56, 0x33, 0x10, 0x68, 0xe3, + 0x4e, 0xe2, 0x63, 0x02, 0x68, 0x13, 0x80, 0x7c, 0x5a, 0x1e, 0x23, 0x44, 0x07, 0xdd, 0x6c, 0x00, + 0x68, 0x21, 0xcd, 0x5f, 0x70, 0xf6, 0x5b, 0x7e, 0x54, 0x01, 0x0b, 0xc4, 0x84, 0x39, 0x16, 0xe4, + 0xdb, 0x57, 0xe7, 0x4a, 0x87, 0xe0, 0x90, 0x4c, 0xbd, 0xd6, 0xd1, 0xfe, 0x38, 0x65, 0xe6, 0xe6, + 0x61, 0xb4, 0x1e, 0xbe, 0xee, 0xe7, 0x0b, 0x0f, 0x53, 0x89, 0x10, 0x10, 0x95, 0xcb, 0x64, 0xbc, + 0x55, 0x21, 0x43, 0x85, 0x32, 0x52, 0x5b, 0xa6, 0x23, 0xbc, 0x44, 0x14, 0x09, 0xce, 0x89, 0xa4, + 0xe1, 0x7f, 0x93, 0x9b, 0xb1, 0xdf, 0x04, 0xe4, 0xa1, 0xaa, 0x1c, 0x6a, 0x95, 0x5d, 0xde, 0x20, + 0x29, 0x0a, 0x8a, 0x2d, 0x98, 0x85, 0x35, 0x54, 0x56, 0x3a, 0x63, 0xb3, 0xd3, 0xb7, 0x8e, 0x3e, + 0x4f, 0x06, 0x4f, 0x25, 0xbe, 0xca, 0x77, 0xbc, 0xb8, 0x6b, 0x88, 0xde, 0xfb, 0x25, 0x19, 0xcb, + 0xd4, 0xed, 0xf1, 0x1a, 0xd5, 0x6b, 0xf2, 0x5d, 0x2b, 0xe2, 0x44, 0x82, 0xed, 0xdb, 0xd9, 0xaa, + 0xbf, 0xc1, 0x61, 0x1d, 0xde, 0xdc, 0x99, 0x13, 0xea, 0x21, 0x60, 0x97, 0x10, 0x70, 0xf7, 0xe2, + 0x44, 0x02, 0x62, 0x97, 0x23, 0xec, 0x18, 0x68, 0x51, 0xa7, 0xdb, 0xe0, 0x8a, 0x3a, 0x60, 0x68, + 0x0b, 0x01, 0x68, 0xf7, 0x18, 0x90, 0x24, 0x8d, 0x23, 0xe3, 0x07, 0x37, 0x90, 0x2c, 0x95, 0xcd, + 0xf0, 0x7e, 0x7f, 0x03, 0x40, 0xe5, 0x05, 0x7a, 0x53, 0xb2, 0x24, 0x04, 0xc0, 0x54, 0x00, 0x15, + 0x38, 0x00, 0x08, 0xfb, 0x20, 0x0f, 0x3b, 0x00, 0x49, 0x09, 0x40, 0x01, 0x1d, 0x18, 0x1f, 0x82, + 0x9e, 0x8c, 0xd4, 0x15, 0x7f, 0xf0, 0xc0, 0x30, 0x04, 0x05, 0x79, 0x79, 0xf9, 0x97, 0xdc, 0x8b, + 0x6d, 0x68, 0xaf, 0x4e, 0xde, 0x94, 0x03, 0x9f, 0x0d, 0xc7, 0xf7, 0x40, 0x39, 0x12, 0xab, 0x43, + 0x0a, 0x8b, 0xf0, 0x1b, 0xd1, 0xf3, 0x01, 0x6f, 0x41, 0xe3, 0xe6, 0xcb, 0x4e, 0x3c, 0x4c, 0x7d, + 0x5b, 0xdb, 0x8c, 0x43, 0xc5, 0xe3, 0x57, 0xf8, 0x81, 0x9c, 0x28, 0x31, 0x14, 0xf1, 0xc6, 0xe0, + 0x71, 0x89, 0x60, 0xcd, 0xdf, 0x95, 0xfe, 0x24, 0x48, 0x82, 0x50, 0x6a, 0xae, 0xe7, 0x51, 0x6f, + 0xe2, 0x84, 0xbb, 0x95, 0xdf, 0xab, 0x48, 0x63, 0xe7, 0x51, 0xe3, 0x08, 0x90, 0x69, 0x92, 0x28, + 0xda, 0xb4, 0x91, 0xc3, 0xce, 0x2d, 0x32, 0x2d, 0xd9, 0x2b, 0x7b, 0xa7, 0x10, 0xff, 0x82, 0xec, + 0x57, 0xa6, 0xfb, 0xfc, 0x13, 0xd5, 0x71, 0x3c, 0x31, 0x08, 0xc7, 0x98, 0x63, 0xdc, 0x4c, 0x28, + 0x75, 0x8a, 0xc7, 0x95, 0x65, 0xf2, 0xdd, 0x65, 0x5b, 0x36, 0x62, 0xf7, 0xfa, 0x09, 0x78, 0xaa, + 0x99, 0x22, 0xca, 0xd5, 0x78, 0x90, 0x53, 0x99, 0xaa, 0xae, 0xab, 0xf7, 0xc4, 0xd6, 0xaa, 0xab, + 0xf1, 0x3c, 0x48, 0x40, 0x28, 0x4e, 0x5c, 0x2e, 0x36, 0x57, 0x49, 0x3b, 0xc6, 0x67, 0x62, 0x01, + 0xaa, 0x94, 0x25, 0x75, 0xe9, 0xab, 0xaf, 0xb3, 0xbc, 0x48, 0xc2, 0x09, 0x30, 0x24, 0xe4, 0x60, + 0xf8, 0xd8, 0x7d, 0xf1, 0x3c, 0xa8, 0x96, 0xb8, 0x73, 0xd8, 0xc8, 0x6b, 0x4d, 0x9e, 0x1c, 0x50, + 0xcf, 0x61, 0xf2, 0x76, 0xff, 0x04, 0x11, 0xb9, 0xac, 0xd9, 0xd7, 0x54, 0x96, 0xc1, 0x5c, 0xba, + 0xd2, 0xd3, 0xcf, 0xbb, 0xb6, 0x58, 0x1c, 0x61, 0x50, 0xac, 0x6e, 0x0e, 0x97, 0x12, 0x58, 0x74, + 0x12, 0x07, 0xbf, 0x52, 0x5a, 0xe5, 0xf8, 0x90, 0x88, 0xd2, 0x9b, 0x07, 0x54, 0x96, 0xa5, 0x69, + 0x4f, 0xf2, 0x73, 0xfd, 0x9c, 0xe3, 0x02, 0x33, 0x25, 0xea, 0x4a, 0x16, 0xd1, 0xbb, 0x34, 0xc0, + 0xfa, 0x53, 0xce, 0x07, 0x19, 0x2a, 0x2f, 0x5e, 0x5f, 0x5c, 0xb0, 0x3c, 0x23, 0x0b, 0xcd, 0xa0, + 0xe0, 0x33, 0xc6, 0xee, 0x5c, 0xcc, 0x1a, 0x5d, 0x13, 0x8f, 0xc7, 0x70, 0x4a, 0xfe, 0x0a, 0xc9, + 0x5a, 0xd8, 0x52, 0x32, 0x5e, 0xd3, 0x47, 0xc2, 0x60, 0x5b, 0xe6, 0x91, 0xa9, 0x38, 0x62, 0x63, + 0x39, 0xf1, 0xf8, 0x47, 0xe5, 0xc4, 0xaf, 0xaa, 0x6d, 0x10, 0x34, 0xcd, 0x63, 0xfc, 0x07, 0x3e, + 0x71, 0x23, 0x3c, 0x60, 0xf7, 0x84, 0x8e, 0xc7, 0x4c, 0x24, 0x62, 0xb6, 0x75, 0x43, 0xb6, 0x27, + 0x06, 0xa5, 0x41, 0x78, 0xce, 0xcd, 0xb3, 0xc2, 0x05, 0x1c, 0xf4, 0x50, 0xbc, 0x1b, 0x76, 0x09, + 0x18, 0x8c, 0x91, 0x08, 0x10, 0xe6, 0x9c, 0x48, 0x2c, 0xe5, 0x96, 0xb7, 0x50, 0x4e, 0x94, 0x30, + 0xbf, 0xdb, 0xf0, 0x80, 0x80, 0xa4, 0x9c, 0x71, 0x02, 0xa8, 0xec, 0x34, 0xe8, 0x1d, 0x4b, 0x3a, + 0x58, 0x65, 0xa5, 0x9a, 0xb7, 0x1f, 0xe1, 0xa1, 0x56, 0x93, 0x3a, 0x5a, 0x65, 0x88, 0x8e, 0xa4, + 0x9a, 0xc9, 0x2a, 0x68, 0xde, 0xdc, 0x8f, 0x1a, 0x0b, 0xcb, 0xfc, 0x16, 0xdd, 0x3f, 0x1f, 0xc9, + 0xbf, 0x62, 0x19, 0xe2, 0x49, 0xaa, 0xae, 0xa4, 0xec, 0xab, 0x59, 0x39, 0xa5, 0x62, 0xdb, 0x27, + 0x10, 0x22, 0xb1, 0x02, 0xb7, 0x77, 0x4f, 0x4f, 0xc7, 0x98, 0xbc, 0x18, 0xe6, 0x1f, 0xef, 0x19, + 0xa7, 0x59, 0xa2, 0x17, 0x58, 0x85, 0xa5, 0xd4, 0x5c, 0x6d, 0x3c, 0xb3, 0xc2, 0xd3, 0x4c, 0x89, + 0x13, 0x20, 0xb8, 0x1f, 0xac, 0xfe, 0x20, 0x22, 0x14, 0x10, 0x35, 0x83, 0x66, 0x54, 0x5e, 0x22, + 0xda, 0x30, 0x1c, 0xaf, 0x1e, 0xb2, 0xed, 0x5d, 0x40, 0xb5, 0x7e, 0x3c, 0x60, 0x5f, 0x74, 0x5e, + 0x24, 0x29, 0x1c, 0xcd, 0xba, 0xc8, 0xbb, 0x15, 0xbf, 0xbf, 0x6e, 0x8c, 0xc8, 0x82, 0xfa, 0x1f, + 0xd3, 0xa7, 0x88, 0x05, 0x91, 0x73, 0x60, 0xe4, 0x63, 0x39, 0x73, 0x7a, 0x5c, 0xbe, 0x0e, 0x24, + 0x49, 0x4b, 0x88, 0x73, 0x84, 0x6c, 0xe0, 0xcd, 0xe2, 0x9b, 0xde, 0xa1, 0x19, 0x39, 0xf3, 0xc4, + 0xc4, 0x4e, 0xe0, 0x3d, 0x67, 0xc5, 0x3a, 0x89, 0x85, 0x2d, 0xcb, 0x7d, 0xd7, 0x71, 0xc5, 0x3d, + 0xc0, 0x65, 0xf3, 0xd8, 0x26, 0x54, 0x11, 0x62, 0x31, 0xd2, 0x47, 0x70, 0xe2, 0x80, 0x0d, 0xf8, + 0x96, 0xcd, 0xa0, 0x64, 0xfc, 0x2a, 0xdb, 0x59, 0x62, 0xd9, 0xf9, 0xef, 0x24, 0x7a, 0x5c, 0x02, + 0x80, 0x72, 0xbc, 0x63, 0xfe, 0x2e, 0x1c, 0x32, 0xa0, 0x6a, 0x80, 0x82, 0x47, 0x93, 0x17, 0xc8, + 0x1b, 0x50, 0x00, 0x94, 0xf5, 0x4b, 0x65, 0x71, 0x13, 0x47, 0xfc, 0x0e, 0x7e, 0x3a, 0xa2, 0x41, + 0xab, 0xad, 0x01, 0x58, 0x49, 0xc2, 0x8c, 0x12, 0x1c, 0x26, 0xbb, 0x08, 0x8b, 0x49, 0xac, 0x94, + 0x6c, 0x28, 0xc3, 0x60, 0x1f, 0x52, 0xa6, 0xcb, 0xbf, 0xf8, 0x5a, 0xb6, 0x55, 0x74, 0x6c, 0x89, + 0x51, 0x09, 0xd9, 0x71, 0x80, 0xd2, 0x4f, 0x0f, 0x8a, 0xe1, 0x7e, 0x61, 0x0b, 0x59, 0x79, 0x34, + 0x9a, 0x6b, 0xc4, 0x12, 0xee, 0xd3, 0x51, 0xbf, 0x3f, 0x3c, 0x26, 0x56, 0x33, 0xfb, 0xdd, 0xaa, + 0xf9, 0x0b, 0x26, 0x7e, 0x2f, 0xb6, 0x5e, 0xf7, 0xe5, 0x73, 0x11, 0xe5, 0xf2, 0xc4, 0x88, 0x21, + 0xf0, 0xd9, 0x84, 0x74, 0xb1, 0xe2, 0x63, 0x04, 0x1a, 0x0b, 0x4a, 0x4f, 0x60, 0xcc, 0x99, 0xe5, + 0xfd, 0xb4, 0xce, 0xc8, 0x87, 0xbf, 0xf9, 0x62, 0xf9, 0xf1, 0x03, 0xad, 0xe9, 0xb4, 0xd6, 0xaa, + 0xaa, 0x5e, 0x84, 0xe2, 0x78, 0x29, 0x0a, 0x19, 0xd3, 0x24, 0x68, 0x4c, 0x58, 0xaf, 0x66, 0xc0, + 0x0a, 0xc3, 0x47, 0x69, 0x9c, 0x2c, 0x6a, 0xa4, 0x58, 0xd5, 0xaf, 0x03, 0xc1, 0x9e, 0x0d, 0x0b, + 0x1e, 0xb8, 0x40, 0x22, 0x14, 0x20, 0xb1, 0xb1, 0x87, 0x57, 0x0b, 0x61, 0xdf, 0xc8, 0x12, 0xb7, + 0x3c, 0xc2, 0xed, 0xf9, 0xa7, 0x2c, 0xff, 0xcd, 0xc3, 0x22, 0xa2, 0x7a, 0x35, 0x8b, 0xe1, 0x21, + 0x2b, 0x7f, 0x17, 0x61, 0xc6, 0x50, 0x01, 0x3c, 0x49, 0xad, 0x0f, 0x20, 0x2a, 0xc9, 0xdc, 0xd4, + 0x2f, 0x2b, 0xfa, 0xb7, 0x73, 0xf3, 0xbe, 0x23, 0x84, 0xe3, 0xa4, 0x25, 0x99, 0x8f, 0xf8, 0x2b, + 0x7a, 0x7b, 0x78, 0x76, 0x60, 0x01, 0xe6, 0xc1, 0x62, 0x1e, 0x8a, 0xb4, 0x33, 0x9e, 0xb2, 0x2e, + 0x6e, 0xdb, 0xdd, 0xbd, 0xd1, 0x01, 0xe6, 0x7c, 0x7e, 0x54, 0x41, 0xe2, 0x1b, 0xc6, 0xfb, 0xfc, + 0x3f, 0xc0, 0xc7, 0x5c, 0x98, 0xf2, 0x23, 0xb0, 0x00, 0x46, 0xa6, 0xa4, 0x00, 0x04, 0x0b, 0x24, + 0x00, 0x04, 0x00, 0x14, 0xb8, 0x05, 0x87, 0x7c, 0x7a, 0xf0, 0x84, 0xc8, 0x80, 0xb9, 0x37, 0x3d, + 0x8b, 0x7e, 0x3f, 0x9b, 0xbb, 0x9f, 0x93, 0x57, 0x97, 0x84, 0xfa, 0x49, 0x3b, 0xfe, 0x5b, 0x5a, + 0x5e, 0x4a, 0x9b, 0xfe, 0x10, 0xed, 0xa7, 0xb0, 0x86, 0xb0, 0x3f, 0x95, 0x7b, 0xae, 0xea, 0xb4, + 0xfc, 0x47, 0x55, 0xda, 0x53, 0x44, 0x88, 0x0a, 0x5c, 0xbe, 0x4e, 0x45, 0xb1, 0xf7, 0x5a, 0x47, + 0xaf, 0x73, 0x53, 0x92, 0x41, 0x57, 0x98, 0xc9, 0xcf, 0x6d, 0x95, 0xb5, 0x63, 0xc2, 0x20, 0xae, + 0x48, 0x44, 0x26, 0xc8, 0x5f, 0xd4, 0xf0, 0x7c, 0xaa, 0xa8, 0x8f, 0x3e, 0x71, 0x30, 0xa4, 0x56, + 0xec, 0x30, 0x63, 0x19, 0x95, 0x81, 0x1e, 0x4a, 0xe4, 0xa6, 0xb1, 0xde, 0x88, 0xad, 0xd1, 0x7a, + 0x63, 0x2d, 0xac, 0x96, 0x3c, 0xff, 0x7c, 0x37, 0x00, 0xec, 0x8c, 0xd2, 0xc7, 0xde, 0x0d, 0x66, + 0x67, 0x38, 0xf7, 0x7f, 0xe5, 0xb5, 0x5b, 0x82, 0x80, 0x38, 0x8d, 0xc4, 0xfb, 0x1b, 0x74, 0x5d, + 0x58, 0xc0, 0xc1, 0x45, 0x94, 0x17, 0xd3, 0x8a, 0x5c, 0x24, 0x70, 0x06, 0x73, 0x5b, 0x2d, 0x16, + 0x0c, 0x18, 0x1f, 0x39, 0x69, 0x0e, 0x0e, 0x4d, 0x41, 0x9f, 0x10, 0xec, 0xa0, 0x0c, 0x81, 0x54, + 0x20, 0x9b, 0x10, 0x0c, 0x4f, 0x39, 0x62, 0x4f, 0x73, 0x31, 0xe9, 0xeb, 0x55, 0x5c, 0x32, 0x49, + 0x8c, 0x00, 0x08, 0x33, 0xee, 0x25, 0xed, 0xdf, 0x08, 0x81, 0x44, 0x69, 0x84, 0x80, 0xe0, 0x21, + 0xf6, 0xd2, 0x2d, 0x8e, 0x06, 0x30, 0x29, 0x7a, 0x19, 0x88, 0x0a, 0x78, 0x7b, 0xc3, 0x62, 0x48, + 0x01, 0x22, 0x94, 0x9a, 0x3d, 0xd4, 0x0e, 0xfe, 0x90, 0x5c, 0x36, 0x31, 0x51, 0x5d, 0x47, 0xf9, + 0xf5, 0x2c, 0xc6, 0xb4, 0xba, 0x1f, 0x0f, 0x22, 0x80, 0x1b, 0xa4, 0x8f, 0x12, 0x6f, 0xc3, 0x7e, + 0x96, 0x7e, 0x9b, 0x7e, 0x58, 0xab, 0xb3, 0x2f, 0x56, 0xf3, 0xa1, 0x2d, 0x57, 0xac, 0x55, 0xff, + 0x0c, 0x8d, 0x89, 0xf1, 0x7a, 0x36, 0xea, 0x9b, 0x64, 0x80, 0xd0, 0x95, 0xa0, 0xe9, 0xe1, 0xa8, + 0xf5, 0x08, 0x05, 0x4b, 0x78, 0x5a, 0x50, 0x06, 0x64, 0x3b, 0x2a, 0xc4, 0xf4, 0x4f, 0x7f, 0x84, + 0x46, 0xc4, 0x9a, 0x0c, 0x2b, 0x70, 0xe7, 0xf1, 0x5b, 0x9c, 0x24, 0x1b, 0x28, 0x00, 0xb7, 0x89, + 0x85, 0xab, 0x8a, 0xd5, 0xfa, 0xb5, 0x6e, 0x7f, 0x7f, 0x0e, 0xe0, 0x01, 0xf4, 0x96, 0x2d, 0x58, + 0x78, 0xf8, 0x6b, 0xe5, 0xaf, 0x77, 0x56, 0xa3, 0xea, 0xfd, 0x19, 0xc3, 0x22, 0xc8, 0xb6, 0x11, + 0xc6, 0xce, 0xde, 0x70, 0x39, 0xa6, 0xdf, 0xe1, 0xe2, 0x18, 0x01, 0xf8, 0xab, 0xd8, 0x27, 0x72, + 0x5a, 0x34, 0xff, 0x5d, 0x4c, 0xbd, 0x46, 0xf0, 0xf9, 0x9e, 0x0f, 0x2c, 0xc9, 0xe1, 0x33, 0x9c, + 0xc0, 0x9d, 0xd0, 0x98, 0xe1, 0xd1, 0x2b, 0x16, 0x00, 0x90, 0x60, 0x2f, 0x96, 0xef, 0xdb, 0xc2, + 0x20, 0xc0, 0x6c, 0x90, 0x28, 0x4c, 0x6b, 0x14, 0x92, 0x00, 0xa8, 0xb5, 0x2c, 0xac, 0x89, 0x9a, + 0xd2, 0x8c, 0x78, 0x1f, 0x6f, 0x38, 0x00, 0x79, 0x44, 0x07, 0x40, 0xc6, 0xc5, 0xea, 0x1d, 0x00, + 0xfd, 0x60, 0x14, 0xf0, 0x06, 0x50, 0x00, 0x20, 0x48, 0x05, 0x13, 0xb7, 0x09, 0x4a, 0x0c, 0x9b, + 0xa7, 0xf8, 0x91, 0xb5, 0x4b, 0x39, 0x85, 0x79, 0x05, 0x5e, 0xe2, 0x38, 0x46, 0x91, 0xb5, 0x2a, + 0x67, 0x91, 0xb1, 0x22, 0xbb, 0xcc, 0xa5, 0x47, 0x71, 0x9f, 0xc2, 0x58, 0xb9, 0xa1, 0x6a, 0xac, + 0x34, 0x91, 0x66, 0x08, 0x89, 0x85, 0x0e, 0xad, 0xe9, 0x5e, 0xce, 0x46, 0x26, 0x37, 0x47, 0x3f, + 0x8c, 0xe3, 0xab, 0xb0, 0x82, 0xc2, 0x8c, 0xf1, 0x01, 0x22, 0x56, 0xa4, 0xf2, 0xb4, 0xa5, 0xbf, + 0x0a, 0x10, 0xad, 0xd0, 0x59, 0x35, 0x07, 0xfc, 0x75, 0xfe, 0x8d, 0xbf, 0x3b, 0x53, 0x25, 0x69, + 0xbd, 0x36, 0x34, 0x52, 0x5e, 0x26, 0x14, 0x9c, 0x0a, 0x41, 0x0e, 0x13, 0x03, 0x84, 0x40, 0x08, + 0xe0, 0x8c, 0x71, 0x61, 0x5b, 0x1d, 0x20, 0x8c, 0x77, 0x83, 0xda, 0xd3, 0x68, 0xd1, 0xcb, 0xb0, + 0x63, 0xdf, 0x36, 0x2b, 0x61, 0xe1, 0xf0, 0x04, 0xa6, 0x24, 0x48, 0xcb, 0xaf, 0x9d, 0x43, 0xf8, + 0xec, 0x0e, 0xd8, 0xdb, 0xb8, 0x26, 0x64, 0xc8, 0x67, 0x36, 0xf8, 0xd0, 0x3b, 0xc4, 0x76, 0xc2, + 0x94, 0xf6, 0x2c, 0x63, 0xca, 0x7a, 0xae, 0x62, 0x83, 0x8a, 0x00, 0x15, 0x98, 0xfe, 0x76, 0x2c, + 0x56, 0x48, 0x4f, 0x39, 0xb8, 0x3b, 0x77, 0xf6, 0xc0, 0x98, 0x1b, 0x8a, 0xb4, 0x35, 0x3a, 0x6b, + 0xbb, 0x97, 0xe2, 0xee, 0x05, 0x30, 0x14, 0x92, 0x67, 0x0c, 0x25, 0xf2, 0x47, 0x1e, 0x1b, 0x70, + 0x03, 0xa2, 0x30, 0x97, 0x71, 0x37, 0xd1, 0x6d, 0xcf, 0xdf, 0x7f, 0x5a, 0x80, 0xd6, 0x81, 0x9b, + 0x56, 0x0f, 0x64, 0x1f, 0xa0, 0x9b, 0xb6, 0xa8, 0x1b, 0x87, 0xfc, 0xbd, 0x3c, 0x48, 0x44, 0x69, + 0x9a, 0xa1, 0xa8, 0x0b, 0x74, 0x66, 0x29, 0xa4, 0x44, 0x5e, 0x8b, 0xc4, 0x0c, 0xa0, 0x05, 0xe8, + 0x75, 0x0f, 0x52, 0x58, 0xc7, 0x5f, 0x25, 0xb8, 0x01, 0x9d, 0x02, 0x05, 0x0e, 0x32, 0x95, 0x42, + 0x89, 0x00, 0x1f, 0x01, 0x97, 0x3c, 0x4b, 0x9f, 0x0e, 0x12, 0x00, 0xa5, 0x46, 0x07, 0x25, 0xcd, + 0x4c, 0xff, 0xdb, 0xa9, 0x32, 0xcf, 0x31, 0x0c, 0x58, 0x2b, 0xc2, 0x8c, 0xa5, 0xad, 0x44, 0x02, + 0x83, 0x0e, 0x81, 0x55, 0x70, 0xfd, 0xe0, 0x77, 0xb7, 0xf2, 0xc1, 0x65, 0x8b, 0x7d, 0xb3, 0x88, + 0x2d, 0x0b, 0xe5, 0xd1, 0xef, 0x63, 0x2e, 0xfe, 0x1c, 0x50, 0x0c, 0x3c, 0x89, 0xb0, 0x74, 0xdf, + 0xff, 0xaa, 0x28, 0xb1, 0xfc, 0x20, 0xfb, 0x68, 0x1e, 0x2c, 0x76, 0xff, 0x16, 0xd1, 0x68, 0xc6, + 0xc7, 0xdb, 0x6d, 0xbf, 0x06, 0x20, 0x49, 0x0a, 0x4f, 0x01, 0xc3, 0xc0, 0x1c, 0x2d, 0x37, 0xd8, + 0x75, 0x86, 0xa7, 0xb2, 0x4e, 0x78, 0xb0, 0xd7, 0x7b, 0xed, 0xa0, 0xb7, 0xfd, 0x71, 0xf7, 0x05, + 0x20, 0x84, 0x6c, 0x75, 0xe1, 0x30, 0xac, 0xc6, 0x4e, 0x0a, 0x9e, 0xfa, 0xb0, 0xa8, 0x7a, 0xa9, + 0xfb, 0x2a, 0x37, 0x87, 0x1f, 0x11, 0x80, 0x1d, 0x0b, 0x13, 0x06, 0xea, 0xf4, 0x47, 0xb4, 0x70, + 0x59, 0x6a, 0xd1, 0xbf, 0xe0, 0x48, 0x04, 0x23, 0x4a, 0x70, 0x59, 0x15, 0x47, 0x80, 0x3c, 0x2e, + 0x72, 0xc0, 0xd9, 0x80, 0x25, 0x18, 0x02, 0x22, 0x8d, 0xe4, 0xa3, 0x35, 0x59, 0xc0, 0x01, 0xe9, + 0x83, 0xcc, 0xc0, 0xa8, 0xf7, 0x77, 0xe3, 0xdf, 0x42, 0x0a, 0x83, 0xcf, 0x84, 0x8c, 0x0a, 0xc0, + 0x85, 0x8c, 0x81, 0x40, 0x1d, 0x1f, 0xca, 0xa1, 0xf5, 0x85, 0x47, 0x19, 0x55, 0xf7, 0x0d, 0xe0, + 0x30, 0x10, 0x7a, 0x47, 0x0a, 0xaa, 0x64, 0x25, 0x46, 0x27, 0xa3, 0xd9, 0x09, 0x64, 0x65, 0xcd, + 0x43, 0xf3, 0xc0, 0xd0, 0x4a, 0x4e, 0x61, 0x6f, 0x7f, 0x82, 0x62, 0x83, 0x08, 0xa9, 0x94, 0x22, + 0xa6, 0xcf, 0xf2, 0x8d, 0xe4, 0xaa, 0xad, 0x72, 0x11, 0xef, 0x1d, 0x88, 0x04, 0x27, 0x53, 0xb8, + 0xed, 0xa3, 0xcb, 0xc2, 0x66, 0x55, 0xaa, 0xad, 0x7c, 0xa4, 0x55, 0x55, 0x71, 0x14, 0x54, 0xa7, + 0xc6, 0xc9, 0x2b, 0x71, 0xbb, 0xa5, 0x86, 0x2b, 0x1f, 0x9f, 0x15, 0xdf, 0xe3, 0xd7, 0x3a, 0x5f, + 0x1f, 0x5b, 0x62, 0x3c, 0x7c, 0xca, 0xa9, 0x58, 0x6c, 0xf3, 0x8f, 0x7b, 0x88, 0xbb, 0x32, 0x2f, + 0xe0, 0x86, 0xf0, 0x64, 0xd6, 0xdb, 0xe0, 0x86, 0x17, 0xd2, 0x4d, 0x17, 0xc7, 0xae, 0x8a, 0x12, + 0xc2, 0x23, 0x2f, 0x69, 0xec, 0x9b, 0x48, 0x99, 0x1d, 0x30, 0xbe, 0x8a, 0x66, 0x57, 0x50, 0x6c, + 0x22, 0xf6, 0x11, 0x05, 0x23, 0x4c, 0x7f, 0x92, 0x07, 0xcf, 0x64, 0x54, 0x0f, 0x56, 0x91, 0x27, + 0xaa, 0xc3, 0x28, 0x16, 0x0e, 0x07, 0xc5, 0x02, 0x60, 0xc5, 0xb2, 0x28, 0x41, 0x9c, 0x5d, 0xc9, + 0xbc, 0x5b, 0x80, 0x21, 0x99, 0x5a, 0x40, 0x27, 0x98, 0x25, 0xb4, 0x7a, 0xf8, 0x78, 0x35, 0xa6, + 0x97, 0x21, 0xe3, 0x93, 0xfe, 0x04, 0x10, 0xa5, 0x5a, 0x61, 0xfa, 0x70, 0x2a, 0x3a, 0xc0, 0x56, + 0xa8, 0xab, 0x80, 0x68, 0x1c, 0x0f, 0x4e, 0x28, 0x5e, 0xd0, 0xe8, 0x6a, 0x66, 0x23, 0xdc, 0x3f, + 0xf1, 0x21, 0xa4, 0x4f, 0xc2, 0x21, 0x11, 0xa7, 0x0e, 0x02, 0xe3, 0xa8, 0xd7, 0xfa, 0x7b, 0xa9, + 0x2d, 0xd4, 0x58, 0xce, 0x06, 0x80, 0xed, 0x87, 0x9c, 0x3f, 0x59, 0x4c, 0xee, 0x33, 0x2c, 0xb6, + 0x28, 0x48, 0x50, 0xff, 0xff, 0xc3, 0x20, 0xae, 0x0b, 0x2f, 0xe8, 0x89, 0x40, 0x00, 0x96, 0x83, + 0x44, 0x8b, 0x83, 0xf9, 0x58, 0x93, 0x23, 0x81, 0xc1, 0xfe, 0x17, 0x8b, 0xc4, 0x15, 0xe1, 0xf0, + 0xc1, 0x0e, 0x00, 0x58, 0xbb, 0x29, 0x13, 0x0c, 0x2d, 0xb7, 0xc5, 0x69, 0xb9, 0x4c, 0x88, 0x4c, + 0xcd, 0x94, 0x79, 0x1a, 0x67, 0xbe, 0x19, 0x44, 0x00, 0xe8, 0x44, 0x84, 0xc2, 0x20, 0xd5, 0xd4, + 0xc5, 0x96, 0x3f, 0xf9, 0xf6, 0x2a, 0x17, 0xf0, 0xee, 0x7d, 0xb9, 0x69, 0x7b, 0x15, 0x67, 0xa6, + 0xec, 0x3d, 0x20, 0x28, 0x26, 0x24, 0xac, 0x19, 0x18, 0x6a, 0x77, 0xc2, 0x19, 0x6b, 0x19, 0x52, + 0xf1, 0x9e, 0xf6, 0x76, 0x70, 0xec, 0x43, 0x43, 0x72, 0x41, 0xc2, 0xec, 0x0e, 0xbe, 0xb7, 0x04, + 0xaf, 0x51, 0xed, 0x74, 0x6c, 0xcb, 0xbf, 0xe1, 0xd9, 0x52, 0x03, 0xa0, 0xba, 0x06, 0xa1, 0xe0, + 0x00, 0x4d, 0x80, 0x77, 0x6d, 0x41, 0xdf, 0xc7, 0xcf, 0x01, 0xf9, 0xef, 0x81, 0x82, 0x41, 0x81, + 0x1c, 0xa5, 0x70, 0x8f, 0xfc, 0x14, 0xf0, 0x90, 0x94, 0xce, 0x1f, 0x6a, 0xd3, 0x5f, 0x12, 0x61, + 0xb5, 0xd3, 0x0d, 0x1e, 0xf5, 0x7c, 0x2e, 0x56, 0x5a, 0xc0, 0x5f, 0x3d, 0x83, 0xc6, 0xa8, 0xbc, + 0x04, 0x21, 0x91, 0x1b, 0xc1, 0x7d, 0xb1, 0xf8, 0x91, 0x01, 0x41, 0x00, 0xd6, 0xa3, 0x58, 0x8e, + 0xe3, 0x02, 0xba, 0x10, 0x79, 0x00, 0xad, 0xe8, 0x1a, 0x68, 0xc6, 0x71, 0xb0, 0x10, 0x6d, 0xf8, + 0xc3, 0x59, 0x32, 0x30, 0x6f, 0xd6, 0x71, 0xf7, 0x12, 0x0c, 0x06, 0x55, 0x75, 0xc7, 0x99, 0xe0, + 0x18, 0x52, 0xa5, 0x76, 0x4f, 0x07, 0x0b, 0x19, 0x82, 0xea, 0x14, 0x29, 0x6e, 0xe2, 0x83, 0x7f, + 0x3e, 0x5e, 0x10, 0x04, 0x21, 0x42, 0xb4, 0x86, 0xef, 0xd6, 0x94, 0xe1, 0xd6, 0x79, 0x79, 0xc0, + 0x91, 0x64, 0x17, 0xde, 0xc1, 0xec, 0xb6, 0x2b, 0xb5, 0xe6, 0x81, 0x03, 0x87, 0x0e, 0x23, 0x5f, + 0x04, 0x21, 0x49, 0x38, 0x02, 0xc8, 0xb0, 0x06, 0x4a, 0x02, 0xc4, 0xb0, 0x62, 0xb9, 0xfc, 0xb1, + 0x89, 0x54, 0x3e, 0x15, 0x4c, 0x1e, 0xf0, 0x1f, 0xe3, 0xf8, 0x39, 0x0a, 0x6c, 0x1c, 0x4c, 0x30, + 0x10, 0xa9, 0x52, 0xcd, 0x98, 0x71, 0x31, 0x1d, 0x4c, 0x22, 0x52, 0x44, 0x83, 0x55, 0x18, 0xf5, + 0x46, 0xe3, 0xbd, 0x80, 0x00, 0x56, 0x9b, 0x57, 0xf8, 0xc8, 0xba, 0xe2, 0xe2, 0x9c, 0x4e, 0x05, + 0xe2, 0xeb, 0x38, 0xcb, 0x71, 0x23, 0x9c, 0x48, 0xe9, 0xf1, 0xf9, 0xb3, 0xbd, 0x99, 0x21, 0xd6, + 0xb8, 0x64, 0x32, 0x14, 0x85, 0x00, 0x72, 0x25, 0x55, 0x10, 0x00, 0x2b, 0x1d, 0x8b, 0x81, 0x99, + 0x60, 0x8d, 0x9a, 0x49, 0x18, 0xdd, 0x84, 0xe3, 0x51, 0x6b, 0x63, 0x0e, 0x80, 0xab, 0x2c, 0x49, + 0x12, 0xff, 0x23, 0x3c, 0xb3, 0x4f, 0xc1, 0x0c, 0x6d, 0x10, 0x1c, 0x07, 0x2f, 0xa9, 0xcb, 0x96, + 0x28, 0xf5, 0x0a, 0xa2, 0x52, 0xd8, 0xde, 0xb9, 0x6d, 0xe5, 0x64, 0x4a, 0x24, 0x44, 0x20, 0xe2, + 0x7d, 0xda, 0xe6, 0x07, 0xdc, 0xfb, 0x01, 0x39, 0x8d, 0x05, 0x93, 0x4a, 0x39, 0x73, 0x58, 0x9b, + 0xa6, 0xaa, 0x3c, 0x29, 0xc9, 0xad, 0x45, 0x72, 0x8b, 0xbb, 0xc7, 0xe2, 0x41, 0x00, 0xe5, 0x36, + 0x59, 0x45, 0x71, 0xdd, 0x05, 0x6d, 0x31, 0x0b, 0x09, 0xd7, 0xdb, 0xb6, 0x0a, 0x6e, 0x14, 0xff, + 0xf8, 0x91, 0x87, 0xac, 0x49, 0x63, 0x13, 0xe4, 0xf9, 0x76, 0xee, 0xee, 0x99, 0xfe, 0x3f, 0xe5, + 0xac, 0xbb, 0x07, 0x7f, 0x0c, 0xa2, 0x80, 0x31, 0xa1, 0xef, 0x8f, 0x26, 0xf3, 0x6d, 0xfa, 0x6d, + 0xdd, 0x9e, 0x31, 0xc4, 0xa8, 0xac, 0x75, 0xfb, 0x93, 0xf0, 0x88, 0x44, 0x28, 0x28, 0x48, 0x0f, + 0x2d, 0x81, 0x67, 0x32, 0x5a, 0x4a, 0x2b, 0x0b, 0x65, 0xac, 0xfe, 0x0f, 0xf0, 0x1a, 0x47, 0x2e, + 0xfc, 0xaa, 0x32, 0x18, 0x4d, 0x4f, 0xd5, 0x8b, 0xa8, 0x94, 0x05, 0x61, 0x52, 0x36, 0x2a, 0xc6, + 0xaa, 0x3b, 0x0f, 0x22, 0x80, 0x2f, 0xf8, 0x35, 0x3a, 0x1c, 0xec, 0x21, 0xbe, 0xf8, 0x70, 0x1b, + 0xc7, 0x06, 0xf5, 0xaa, 0xed, 0x1d, 0xbb, 0xb9, 0x35, 0x49, 0xab, 0xf8, 0x89, 0x8c, 0xf2, 0xa7, + 0xe7, 0x0e, 0x82, 0xd8, 0x15, 0x2e, 0xdb, 0x46, 0xca, 0xc3, 0xce, 0x01, 0x98, 0x59, 0x81, 0x96, + 0xb3, 0x94, 0xff, 0x9f, 0x80, 0xb7, 0xaf, 0x04, 0x31, 0xe1, 0xa0, 0x35, 0x34, 0x32, 0x90, 0xa7, + 0xbe, 0x4e, 0x38, 0x2d, 0xe9, 0x4b, 0x39, 0xa6, 0x07, 0xdd, 0x55, 0x46, 0xd5, 0x81, 0xf9, 0xd7, + 0xc2, 0x70, 0x76, 0xf5, 0xe8, 0xb9, 0xfe, 0xbc, 0x40, 0x90, 0x8d, 0xdf, 0x13, 0xf7, 0x25, 0x6e, + 0xab, 0x4c, 0x5d, 0x3c, 0x48, 0x90, 0xa4, 0xf7, 0xe7, 0xb8, 0x13, 0x36, 0xf2, 0x6c, 0x83, 0x0a, + 0x72, 0x92, 0x9b, 0x3e, 0x41, 0x6c, 0xff, 0x24, 0x28, 0x1d, 0x02, 0xcc, 0xef, 0x1d, 0xdc, 0x48, + 0x0a, 0x10, 0x53, 0x7f, 0xec, 0xe2, 0x02, 0x3b, 0x41, 0x70, 0x20, 0xaa, 0x3d, 0x01, 0x30, 0x02, + 0xb0, 0x96, 0xb4, 0x1e, 0xa9, 0x63, 0x2f, 0xc2, 0x21, 0x91, 0xb2, 0x3b, 0x55, 0x89, 0x08, 0x80, + 0x58, 0x55, 0xbf, 0x06, 0xf7, 0x32, 0x3d, 0xf2, 0xc6, 0xed, 0x44, 0x00, 0xac, 0x50, 0xea, 0xd4, + 0xad, 0xd0, 0xf1, 0xe5, 0x6e, 0x87, 0x8f, 0x10, 0x09, 0x7d, 0x55, 0xc3, 0xc1, 0xa6, 0x0f, 0x70, + 0xf0, 0x9f, 0x2d, 0xef, 0x7c, 0x96, 0x95, 0x55, 0xf2, 0x5d, 0xde, 0x14, 0xc4, 0x02, 0xc2, 0x0a, + 0xdb, 0x15, 0xda, 0x7c, 0x4b, 0xc5, 0xcf, 0x12, 0xf1, 0x7d, 0xc3, 0x20, 0x26, 0x46, 0x89, 0x01, + 0x0b, 0xb0, 0x6e, 0x3e, 0x60, 0xca, 0xfa, 0xc8, 0x3e, 0xb5, 0x8f, 0xc4, 0x2a, 0xaa, 0xf5, 0xd4, + 0xe4, 0x59, 0x94, 0x2c, 0xca, 0xc8, 0x9e, 0x13, 0x95, 0x2b, 0x16, 0x05, 0x0d, 0x17, 0xff, 0x0c, + 0xb2, 0x80, 0x29, 0xfc, 0x1d, 0x9e, 0x37, 0x7b, 0xe8, 0x74, 0xdd, 0x77, 0x27, 0x6f, 0x7c, 0x14, + 0x68, 0x3f, 0xed, 0xee, 0xf6, 0xf8, 0xec, 0xe1, 0x10, 0xc8, 0x50, 0x61, 0xe0, 0x3c, 0xf0, 0xf4, + 0x60, 0x0a, 0x8a, 0x94, 0xe3, 0xc9, 0xea, 0xa1, 0x4b, 0xcb, 0x1d, 0x62, 0x83, 0x10, 0x03, 0x9b, + 0x85, 0x55, 0x39, 0xcc, 0xb0, 0xe2, 0x80, 0x52, 0x8d, 0x42, 0x2d, 0xc3, 0xee, 0x25, 0xdc, 0x6a, + 0x5b, 0xb6, 0x27, 0x46, 0xa2, 0x5c, 0xa6, 0x78, 0xdd, 0xf1, 0x99, 0x21, 0xee, 0x91, 0xfa, 0x7f, + 0x12, 0x24, 0x29, 0xd0, 0x10, 0x11, 0xef, 0xd6, 0xde, 0xf6, 0x64, 0xf5, 0x99, 0x6e, 0x44, 0x39, + 0x5b, 0xbb, 0x39, 0x38, 0x54, 0x98, 0x0a, 0xf7, 0x0c, 0x04, 0x02, 0x87, 0x12, 0x58, 0x92, 0xc0, + 0x31, 0x1e, 0x27, 0x85, 0x99, 0x78, 0xa1, 0x9c, 0x1c, 0x66, 0x22, 0x08, 0xec, 0x91, 0xa8, 0xff, + 0x46, 0x0a, 0x92, 0xf8, 0x71, 0x40, 0x00, 0xa7, 0x71, 0xd3, 0x11, 0xd8, 0xfc, 0xdf, 0xa5, 0x14, + 0x4b, 0x14, 0xd3, 0x7a, 0x6d, 0xf7, 0xe2, 0xd6, 0x9a, 0x7f, 0xe0, 0x84, 0x10, 0x05, 0x0e, 0x4e, + 0x0e, 0x01, 0xde, 0x1a, 0x86, 0xa1, 0xfd, 0x1e, 0x06, 0x81, 0xdc, 0x0d, 0x4a, 0x20, 0x74, 0x6d, + 0x03, 0xf0, 0x3a, 0x0b, 0xc8, 0x4e, 0x93, 0xb0, 0x1a, 0x14, 0x83, 0x30, 0x2a, 0x9c, 0xa1, 0x74, + 0xd4, 0x72, 0x99, 0x38, 0x15, 0x38, 0x1c, 0x7e, 0x20, 0x18, 0x8d, 0x14, 0xff, 0x25, 0xb1, 0xa5, + 0xdb, 0x55, 0x86, 0xb2, 0x78, 0xe4, 0xe6, 0xe7, 0xba, 0xde, 0x79, 0xe3, 0xd7, 0x10, 0x25, 0xb0, + 0x7f, 0x38, 0x80, 0xa8, 0xf0, 0xd7, 0x77, 0xbc, 0x29, 0xc4, 0x4e, 0xe1, 0x7e, 0xcc, 0x38, 0xe0, + 0xcd, 0x0b, 0xf0, 0x42, 0x02, 0x44, 0x61, 0xc9, 0x95, 0x3d, 0x83, 0x71, 0xbd, 0x45, 0x42, 0xb6, + 0x37, 0xf2, 0x6a, 0x89, 0x07, 0xc2, 0x02, 0xa0, 0x00, 0xb0, 0xdd, 0x3a, 0x19, 0xe5, 0x80, 0x7b, + 0xc6, 0x66, 0x11, 0x10, 0x30, 0x87, 0xb8, 0xfc, 0x2f, 0x2f, 0xb7, 0xe6, 0x3a, 0x5c, 0xe0, 0xf1, + 0xfe, 0x87, 0xf2, 0xa8, 0xca, 0xa9, 0x52, 0xc1, 0xc2, 0xca, 0x04, 0x00, 0xed, 0xe8, 0x36, 0xf8, + 0xcd, 0xf6, 0xdb, 0xfd, 0xbd, 0xb6, 0xf8, 0x80, 0xa4, 0xe5, 0x8a, 0xc4, 0x0b, 0x0a, 0xe9, 0x23, + 0x88, 0x2e, 0x48, 0x2a, 0x50, 0x75, 0x10, 0x02, 0xc0, 0xe2, 0xf9, 0x63, 0x26, 0x6b, 0x39, 0xe7, + 0x8f, 0x4c, 0x16, 0x2a, 0x50, 0xc6, 0x20, 0x10, 0x85, 0x25, 0x80, 0x01, 0x48, 0x3c, 0x0b, 0x9c, + 0x00, 0x04, 0x30, 0x78, 0x2e, 0x5e, 0xac, 0xe4, 0x8a, 0x9e, 0x12, 0x09, 0x35, 0x8b, 0x72, 0x2e, + 0xc3, 0xc9, 0xea, 0x44, 0x31, 0x21, 0x7c, 0x00, 0xe2, 0x40, 0x64, 0x8c, 0x2a, 0xa4, 0xad, 0x4e, + 0x60, 0x11, 0xce, 0x9c, 0x4c, 0x28, 0x4e, 0x41, 0xa8, 0xac, 0xf0, 0x90, 0x5e, 0x38, 0xc8, 0x98, + 0xd5, 0x4a, 0xd8, 0xf7, 0xce, 0x70, 0xe7, 0x21, 0x5c, 0x01, 0x0c, 0x24, 0xc7, 0x7d, 0x5f, 0x04, + 0xfb, 0xce, 0xf5, 0xe7, 0xf5, 0xf2, 0xe5, 0xf1, 0xb7, 0x8f, 0xb8, 0xb8, 0x86, 0x98, 0x3a, 0x7f, + 0x08, 0x81, 0x44, 0x28, 0x41, 0x00, 0x3c, 0x5d, 0xd6, 0xc5, 0x10, 0xd4, 0xd2, 0x45, 0x8c, 0xf1, + 0xc2, 0xdc, 0x19, 0x38, 0x03, 0x90, 0xe8, 0x7c, 0xb0, 0x65, 0x8e, 0xc3, 0xc6, 0x36, 0x42, 0x09, + 0x43, 0xa8, 0x9e, 0x78, 0x63, 0x94, 0xab, 0x36, 0x57, 0x12, 0x67, 0x7d, 0xdf, 0x27, 0x28, 0x9d, + 0x49, 0xc2, 0x30, 0x40, 0x02, 0x20, 0x82, 0x85, 0x01, 0x96, 0x00, 0x31, 0x58, 0x3b, 0xec, 0x39, + 0x80, 0x2f, 0x62, 0x71, 0x11, 0x13, 0x90, 0x5e, 0x25, 0xf7, 0xfe, 0x5a, 0xff, 0xb6, 0x0c, 0x75, + 0x16, 0x17, 0x40, 0x58, 0x0f, 0xca, 0x07, 0xf0, 0x3f, 0x68, 0x7b, 0xd4, 0xb0, 0x2c, 0xf0, 0x03, + 0x58, 0xe3, 0x17, 0x31, 0x5f, 0x4d, 0x3d, 0xbe, 0x0c, 0x41, 0x00, 0x52, 0x28, 0xc5, 0x06, 0x55, + 0x59, 0x85, 0x07, 0xd4, 0x50, 0x62, 0xb1, 0xb1, 0xcf, 0xcf, 0x1c, 0x66, 0xb2, 0x20, 0x17, 0x14, + 0x23, 0x51, 0xe7, 0xaa, 0xe0, 0x00, 0x10, 0x00, 0x19, 0x05, 0x20, 0x40, 0x87, 0x30, 0x94, 0xb2, + 0xb4, 0x33, 0x1c, 0x03, 0x0e, 0x04, 0x10, 0x1b, 0x01, 0x48, 0x1a, 0xb0, 0xc6, 0x5a, 0x1e, 0x16, + 0xdf, 0xdf, 0xce, 0x60, 0xab, 0x01, 0x70, 0x63, 0x24, 0xca, 0x59, 0x9a, 0x43, 0x51, 0x94, 0x17, + 0x10, 0x93, 0x57, 0x9d, 0xa8, 0x20, 0x8d, 0x16, 0x00, 0xc5, 0x97, 0xc0, 0x4a, 0x21, 0xa9, 0x86, + 0x30, 0x05, 0xbc, 0x8c, 0x74, 0x67, 0xea, 0x10, 0x70, 0x93, 0xbc, 0x49, 0xe7, 0x78, 0x3d, 0x72, + 0x81, 0x4c, 0x46, 0x9e, 0x34, 0xa7, 0x79, 0x27, 0x49, 0x39, 0x88, 0x8c, 0xd8, 0x70, 0x90, 0x04, + 0x18, 0xcc, 0x1d, 0x3a, 0x71, 0xc3, 0xdb, 0xb7, 0xfa, 0xb8, 0xf4, 0xa3, 0x8d, 0x20, 0x63, 0xac, + 0xdd, 0xc0, 0x64, 0x81, 0x8a, 0x6c, 0x0c, 0x01, 0xea, 0x58, 0xb7, 0xc1, 0x52, 0x38, 0x0c, 0xe0, + 0x7c, 0xc2, 0x8f, 0x9b, 0x51, 0x6e, 0xdb, 0x9f, 0x70, 0xc8, 0x14, 0x02, 0x90, 0xe0, 0xd0, 0x55, + 0x2a, 0x20, 0x06, 0x64, 0x4e, 0xfc, 0x38, 0x39, 0x14, 0x2c, 0x0d, 0x05, 0xa0, 0xb0, 0x4b, 0xae, + 0x5a, 0xca, 0xc2, 0xc8, 0xf6, 0x02, 0xc8, 0x96, 0x59, 0x55, 0x63, 0x4c, 0x38, 0x18, 0x4d, 0xc0, + 0xe7, 0x08, 0x03, 0x11, 0x85, 0x17, 0xaf, 0x1c, 0x3f, 0x0e, 0x2e, 0x0d, 0x4e, 0x02, 0x8d, 0x87, + 0xed, 0x69, 0x97, 0x4f, 0x99, 0x6b, 0x0e, 0x51, 0x95, 0x90, 0xcf, 0x08, 0x91, 0x6b, 0xad, 0x56, + 0xb0, 0x9f, 0x31, 0x75, 0x36, 0x13, 0x8a, 0xd2, 0x87, 0x1e, 0xb6, 0x1e, 0x0e, 0x20, 0xa6, 0xcc, + 0x0f, 0xe5, 0x39, 0x49, 0x63, 0x38, 0x02, 0xe1, 0x92, 0x09, 0x44, 0x31, 0xb8, 0x39, 0xbf, 0x1f, + 0xda, 0xce, 0x85, 0x8b, 0x84, 0x02, 0x85, 0xc3, 0x93, 0xd2, 0x95, 0x06, 0xd2, 0x06, 0x43, 0x00, + 0x63, 0x82, 0x78, 0x0c, 0x8d, 0x60, 0xf7, 0x1e, 0xc2, 0xda, 0x27, 0x96, 0xbb, 0x4d, 0xa4, 0x8b, + 0x02, 0x88, 0x10, 0x02, 0x90, 0x99, 0xbc, 0x62, 0x5c, 0x68, 0x07, 0x5f, 0x55, 0x99, 0x38, 0xac, + 0xeb, 0xe8, 0xf6, 0x47, 0x77, 0xd1, 0x9e, 0x58, 0x9c, 0x70, 0xdc, 0x60, 0x00, 0x1c, 0x01, 0xbe, + 0x24, 0x48, 0x50, 0x41, 0xee, 0x2a, 0xe4, 0x9e, 0x08, 0x58, 0x2a, 0x4a, 0x83, 0xcd, 0x91, 0x4c, + 0xa0, 0x7e, 0x3b, 0xab, 0x0c, 0x98, 0xd1, 0x31, 0xa1, 0x7c, 0xec, 0xfc, 0x1c, 0x14, 0x02, 0x11, + 0xb0, 0x72, 0x40, 0xc6, 0xe9, 0xb0, 0x41, 0x34, 0x97, 0x00, 0x01, 0x34, 0x1b, 0x00, 0x13, 0x2f, + 0xb9, 0x6c, 0xb4, 0x07, 0x18, 0xc0, 0xf8, 0x8d, 0xe4, 0x56, 0x0d, 0x4a, 0xa7, 0xdb, 0xd8, 0xac, + 0x07, 0x10, 0xa8, 0x8b, 0xd6, 0x4f, 0xe2, 0x06, 0x95, 0x7a, 0xe5, 0xb1, 0x2e, 0x4f, 0xc1, 0xbf, + 0x0f, 0x60, 0xec, 0xf4, 0x89, 0xa5, 0x27, 0x83, 0xde, 0x78, 0xf7, 0xf1, 0x48, 0xc1, 0xf4, 0xe5, + 0x87, 0xae, 0x53, 0xbe, 0xe1, 0x7e, 0x41, 0x0b, 0x52, 0x70, 0xc7, 0x21, 0x77, 0x7e, 0x11, 0x16, + 0x57, 0x7b, 0xb8, 0xad, 0xdf, 0x06, 0x10, 0x8d, 0x22, 0x52, 0xa5, 0xce, 0x20, 0x1e, 0x99, 0x6c, + 0xf7, 0xeb, 0xf8, 0x29, 0x97, 0xee, 0xae, 0x2b, 0x3f, 0x77, 0x7b, 0xf8, 0x20, 0x10, 0x21, 0xf8, + 0xd6, 0x31, 0x5e, 0xf1, 0x0f, 0xf6, 0x50, 0xc8, 0x02, 0xb5, 0x46, 0x5b, 0xae, 0x4e, 0xee, 0x0d, + 0xb9, 0x37, 0xb9, 0xb1, 0x10, 0x1b, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x42, 0x21, 0x31, + 0xa2, 0xf1, 0x46, 0x55, 0x5d, 0x6b, 0xe1, 0x2b, 0xde, 0xae, 0xae, 0x7e, 0x8b, 0x50, 0x69, 0xcd, + 0xb6, 0xef, 0x89, 0x89, 0x33, 0xaf, 0xab, 0x1e, 0x26, 0x12, 0x2a, 0xbb, 0x77, 0xdb, 0xc4, 0xc4, + 0xdd, 0xee, 0x9b, 0x68, 0xbe, 0x2c, 0xea, 0xba, 0xae, 0x0b, 0xf9, 0x04, 0x2a, 0xee, 0x24, 0x40, + 0x43, 0x8a, 0xcf, 0xee, 0xa9, 0xe6, 0x63, 0xec, 0xaa, 0x2f, 0x32, 0x47, 0x08, 0xea, 0x26, 0x20, + 0x89, 0xea, 0xfb, 0x7e, 0x26, 0x6f, 0xf8, 0xa3, 0x3d, 0x30, 0x8e, 0x2f, 0xa0, 0xbb, 0xc1, 0x1c, + 0x40, 0x82, 0x05, 0x86, 0x69, 0xff, 0x31, 0x6f, 0x77, 0xca, 0x5d, 0xdf, 0xfe, 0x09, 0x0b, 0x17, + 0xdb, 0x88, 0x10, 0x51, 0xd7, 0x56, 0xb8, 0x8f, 0x11, 0xc4, 0x88, 0xe2, 0x44, 0x4d, 0xcc, 0x17, + 0xdd, 0x43, 0xbc, 0x20, 0x16, 0x55, 0xde, 0xfa, 0xd4, 0xf1, 0x22, 0x38, 0x88, 0x93, 0x9d, 0x23, + 0xd1, 0x6d, 0x2f, 0x90, 0xae, 0xec, 0xab, 0x90, 0x9a, 0xaf, 0x92, 0x7c, 0x6b, 0x27, 0x21, 0xad, + 0x5f, 0x13, 0x12, 0x46, 0x5a, 0x8b, 0x8b, 0xfe, 0x3f, 0x77, 0xb7, 0x5e, 0xab, 0xec, 0x5e, 0x34, + 0x77, 0x9a, 0x11, 0x08, 0x18, 0x97, 0x2f, 0x1d, 0x7f, 0x82, 0x00, 0x57, 0x27, 0xa6, 0x5d, 0x0b, + 0x57, 0x2c, 0xc9, 0xf3, 0x31, 0xd3, 0x08, 0x23, 0xc4, 0x9b, 0xcd, 0x2c, 0x4c, 0x15, 0x9c, 0x5d, + 0x45, 0xd7, 0x08, 0x39, 0x35, 0x73, 0xe7, 0xdf, 0x74, 0x36, 0x49, 0xf1, 0x11, 0xd9, 0x98, 0x7c, + 0x0e, 0xdd, 0xd9, 0x56, 0x99, 0x82, 0x7b, 0xfd, 0xcf, 0x25, 0xd7, 0xc5, 0x1b, 0x63, 0x57, 0x57, + 0x17, 0xc4, 0x47, 0xd4, 0xdd, 0x5d, 0x01, 0x25, 0x20, 0xb9, 0x24, 0xc8, 0xe3, 0xf1, 0xca, 0xbe, + 0x26, 0x2f, 0x88, 0xc2, 0x5d, 0x1b, 0xb9, 0xbf, 0x38, 0x44, 0x48, 0x4e, 0xab, 0xe6, 0xc3, 0x67, + 0x12, 0x2c, 0xba, 0x8e, 0x2e, 0xec, 0x36, 0x62, 0x04, 0x9b, 0x76, 0x9a, 0xf2, 0x8a, 0xb8, 0xad, + 0xfc, 0x10, 0x87, 0x46, 0x07, 0x5f, 0x77, 0x9b, 0x82, 0xc0, 0xd0, 0x3a, 0x5c, 0x92, 0xab, 0x3c, + 0xbd, 0x25, 0x2a, 0xeb, 0x3d, 0xc4, 0x08, 0x0a, 0x64, 0xb6, 0xa6, 0xcb, 0xdd, 0x66, 0xa9, 0xc1, + 0xf7, 0x63, 0xf2, 0x18, 0xe8, 0x3f, 0x53, 0xf2, 0x86, 0xaf, 0x72, 0x72, 0x4d, 0x8c, 0xa4, 0x99, + 0xe1, 0x02, 0xb8, 0x6a, 0xed, 0x5e, 0x38, 0xb5, 0x49, 0x14, 0x5e, 0x20, 0x47, 0x13, 0x04, 0xf4, + 0x63, 0x48, 0xbb, 0x42, 0xa9, 0x35, 0xcf, 0x8f, 0xda, 0xa1, 0xd8, 0xd8, 0xd3, 0xda, 0x31, 0x8f, + 0x88, 0x12, 0x88, 0xff, 0x13, 0x4e, 0x89, 0x54, 0x90, 0x5d, 0x44, 0x49, 0x17, 0x51, 0x2b, 0xe1, + 0x1f, 0x08, 0x5c, 0x1e, 0xb0, 0x4e, 0x8d, 0x5e, 0x22, 0x24, 0x69, 0xf2, 0xaf, 0x22, 0x96, 0xd8, + 0x52, 0x7f, 0xff, 0x21, 0x9d, 0xab, 0x88, 0x08, 0x18, 0x66, 0x5c, 0x19, 0x10, 0xde, 0x10, 0x11, + 0x1a, 0x5a, 0xdf, 0x5a, 0xc2, 0xf6, 0x47, 0xa6, 0x29, 0x16, 0x05, 0x83, 0x39, 0xa6, 0x20, 0x48, + 0x2a, 0x2a, 0x85, 0xf4, 0x8f, 0xb1, 0x3d, 0x60, 0x27, 0xf3, 0x48, 0xbc, 0x91, 0xa1, 0x4c, 0x6b, + 0x3e, 0x5f, 0x70, 0x40, 0x20, 0x25, 0x7b, 0xdd, 0xc4, 0x3d, 0x6c, 0x66, 0x18, 0x10, 0xef, 0x7e, + 0x20, 0x40, 0xc2, 0x45, 0xf2, 0xc8, 0x4b, 0x23, 0x78, 0xb0, 0xe0, 0xcb, 0x2f, 0x65, 0x6a, 0xaf, + 0x82, 0x88, 0x30, 0x2b, 0x90, 0x7b, 0xf0, 0x3a, 0xf4, 0x42, 0x87, 0x43, 0x5b, 0x14, 0x07, 0x79, + 0x20, 0xf8, 0x7a, 0x2c, 0x61, 0xd0, 0xc9, 0x20, 0xdf, 0xea, 0xf0, 0xa7, 0x41, 0x9e, 0x8b, 0x89, + 0x85, 0x02, 0x12, 0x4c, 0x1d, 0xfa, 0x3f, 0xd2, 0xa7, 0x37, 0xad, 0x57, 0xd6, 0x5d, 0x9c, 0x99, + 0x41, 0xfe, 0x7b, 0x88, 0x98, 0x9a, 0xb5, 0x88, 0x9b, 0x88, 0xff, 0xb2, 0x5d, 0xfe, 0xe7, 0xfc, + 0xb8, 0x9f, 0x12, 0x53, 0xe1, 0xe5, 0x33, 0x85, 0xd8, 0x44, 0x12, 0x36, 0x38, 0xbf, 0xa7, 0xfe, + 0x5b, 0x82, 0x01, 0x00, 0xa0, 0x28, 0x5e, 0xe6, 0xb1, 0xa1, 0x8a, 0x33, 0xf3, 0x60, 0xe4, 0x3c, + 0x0a, 0x76, 0xa9, 0x96, 0x10, 0x12, 0x1b, 0xbc, 0xe1, 0xce, 0x88, 0xa5, 0xfb, 0x42, 0xaf, 0x0c, + 0x09, 0xf8, 0x24, 0x2f, 0x1d, 0xa0, 0xb4, 0x86, 0x22, 0x34, 0xd9, 0x31, 0x61, 0xf4, 0xa2, 0xf1, + 0x96, 0x25, 0xe9, 0x5e, 0x53, 0x92, 0xb4, 0x1d, 0xc4, 0xa3, 0xa0, 0x58, 0x34, 0x63, 0xe9, 0xdd, + 0x3f, 0xc3, 0x02, 0x42, 0x93, 0x9e, 0x78, 0x39, 0x4e, 0x99, 0x3a, 0xbd, 0xb8, 0x87, 0x09, 0x87, + 0xc7, 0x3c, 0xa4, 0x01, 0xa9, 0x63, 0x10, 0xd0, 0xa4, 0x00, 0x7e, 0x0a, 0x05, 0x5e, 0x00, 0x39, + 0x8e, 0xfc, 0x11, 0xdd, 0xc9, 0x13, 0x65, 0xd7, 0xc2, 0x99, 0x2a, 0x82, 0x72, 0xc6, 0xd5, 0x2b, + 0xda, 0x0e, 0x22, 0x02, 0x7b, 0xe3, 0x5e, 0x30, 0x4f, 0x9c, 0x44, 0x76, 0x6c, 0x6d, 0x98, 0x2e, + 0x4c, 0x9e, 0x76, 0x62, 0xe2, 0x04, 0x02, 0xcf, 0x15, 0xe1, 0x13, 0xa9, 0x0d, 0xd3, 0xd5, 0x1b, + 0x03, 0x8e, 0x4b, 0xe7, 0x07, 0x0d, 0x7c, 0x14, 0x94, 0x01, 0x90, 0xb0, 0x35, 0xf4, 0x01, 0x3d, + 0x9f, 0x80, 0x1c, 0x43, 0x13, 0x04, 0xc1, 0x84, 0x49, 0x80, 0x65, 0xbe, 0xfd, 0x3f, 0x49, 0x38, + 0xdb, 0x4e, 0x81, 0x07, 0x15, 0x07, 0x7b, 0x3c, 0xba, 0xd7, 0xc7, 0xce, 0x10, 0x12, 0x12, 0x8f, + 0xef, 0x35, 0x26, 0x56, 0x8f, 0xe5, 0x9c, 0x60, 0xc8, 0x18, 0x13, 0x8c, 0xf8, 0x40, 0x99, 0xb2, + 0x92, 0xa6, 0xcb, 0x1c, 0x32, 0xc9, 0xcc, 0x5c, 0xd4, 0x55, 0xcd, 0x28, 0xc2, 0x43, 0x2b, 0x1f, + 0x89, 0xb1, 0x98, 0x0c, 0xdf, 0xe9, 0xe3, 0x88, 0x82, 0x7b, 0x1e, 0x04, 0x11, 0x0b, 0x96, 0x1d, + 0x50, 0x00, 0x44, 0xc8, 0x17, 0x13, 0x55, 0xea, 0xf2, 0x2e, 0x88, 0x5a, 0x71, 0xa6, 0x99, 0x41, + 0x2e, 0x41, 0x99, 0x2e, 0x0f, 0xcc, 0x87, 0xff, 0x1f, 0x1a, 0xa7, 0x5d, 0x4f, 0x4f, 0x08, 0x04, + 0x06, 0x93, 0xb5, 0xd6, 0xb5, 0x6c, 0x3d, 0x18, 0x93, 0x87, 0x80, 0x73, 0x85, 0x82, 0xb8, 0x1d, + 0x22, 0x2b, 0x6e, 0x6e, 0xbf, 0xc2, 0x30, 0x45, 0xbd, 0xd8, 0xe1, 0x00, 0x80, 0x25, 0x89, 0xe1, + 0xb2, 0x28, 0x95, 0xb8, 0xe5, 0xb4, 0x77, 0x84, 0x01, 0x00, 0x52, 0x30, 0xe8, 0x67, 0xeb, 0xb2, + 0x1f, 0x61, 0x38, 0x70, 0x1b, 0xd5, 0x49, 0xb4, 0x57, 0x7f, 0xb3, 0x25, 0x56, 0x5d, 0xe6, 0xf8, + 0x0b, 0xa7, 0x89, 0x10, 0x37, 0x70, 0x18, 0xa5, 0xa0, 0x00, 0x22, 0xa2, 0xe0, 0x3e, 0x5a, 0xe0, + 0x00, 0xc8, 0x91, 0x0c, 0x5b, 0x99, 0x94, 0x03, 0xc9, 0x88, 0x1f, 0x89, 0xc0, 0x01, 0x40, 0xfd, + 0x76, 0x6a, 0x7b, 0x67, 0xb9, 0x24, 0x83, 0x90, 0x92, 0x41, 0xb9, 0xfc, 0x47, 0x53, 0xfc, 0x21, + 0x1d, 0x1f, 0xcf, 0x1f, 0x5e, 0xc7, 0x75, 0x2d, 0xbf, 0xe6, 0x8f, 0x09, 0xc7, 0x66, 0x97, 0x8c, + 0xc9, 0x9a, 0x49, 0x6d, 0x41, 0xf6, 0x16, 0x6e, 0xd6, 0xf8, 0x42, 0x0a, 0x6a, 0x71, 0xfb, 0x9b, + 0x94, 0x41, 0x2e, 0xcc, 0xdd, 0x96, 0x1f, 0x2f, 0x07, 0xde, 0x08, 0xb1, 0x1f, 0x26, 0x84, 0x4b, + 0x7f, 0xc4, 0xc9, 0x04, 0xda, 0xad, 0x6f, 0x82, 0xc1, 0xaa, 0xbe, 0x5a, 0x3a, 0x4e, 0xe7, 0x49, + 0x5f, 0x21, 0xb6, 0x8f, 0xd7, 0x2d, 0x8d, 0x9b, 0x47, 0xf0, 0xec, 0x48, 0x03, 0x08, 0xa5, 0x43, + 0x5e, 0x3f, 0xfe, 0xee, 0x19, 0x1f, 0x0b, 0x18, 0x21, 0x3a, 0x7f, 0x81, 0xa4, 0x0f, 0x23, 0x46, + 0x03, 0xa0, 0x78, 0x24, 0x00, 0x70, 0x4b, 0x83, 0xc3, 0xe2, 0x00, 0x00, 0xaf, 0x14, 0x00, 0x0d, + 0xca, 0x08, 0x07, 0x90, 0x70, 0x69, 0xd5, 0xd8, 0x14, 0x6c, 0xe0, 0x5d, 0x60, 0x12, 0x4e, 0x80, + 0xaf, 0xbb, 0xc9, 0xe1, 0xe2, 0x05, 0x90, 0x89, 0xa2, 0xf4, 0xd9, 0xbf, 0xe0, 0x61, 0x01, 0x02, + 0x36, 0x70, 0x00, 0x19, 0xe4, 0xe0, 0x00, 0x67, 0x03, 0x88, 0xf0, 0x71, 0x0f, 0x08, 0xa4, 0xc7, + 0xc1, 0x80, 0x28, 0xfd, 0x7c, 0x00, 0x7a, 0xf0, 0xec, 0xea, 0xa8, 0xbc, 0x2e, 0x54, 0x76, 0xc1, + 0xdf, 0x0b, 0x00, 0xcb, 0x0c, 0x3d, 0x72, 0x5d, 0x8b, 0x7f, 0xe0, 0x41, 0x07, 0x21, 0x48, 0x56, + 0xc6, 0xb2, 0x9c, 0x18, 0xb8, 0x89, 0x55, 0x8a, 0xe6, 0xf8, 0x00, 0x70, 0x38, 0x38, 0x8a, 0x3c, + 0x01, 0x72, 0x88, 0x01, 0x2f, 0x1a, 0x22, 0x37, 0x65, 0x41, 0xa9, 0x7d, 0x9d, 0xee, 0xf8, 0x98, + 0x2d, 0x8a, 0xcb, 0x19, 0x7d, 0xaa, 0xe9, 0x7c, 0x48, 0x28, 0x33, 0xb8, 0x32, 0x1a, 0x94, 0x10, + 0xd7, 0xc1, 0xff, 0x77, 0xcb, 0xc1, 0xe1, 0xe0, 0x80, 0x73, 0xcd, 0xa6, 0x9a, 0x7e, 0x0a, 0x88, + 0x6a, 0x25, 0xdc, 0x9b, 0xdc, 0xc6, 0x6e, 0xa5, 0x65, 0xd3, 0x83, 0xec, 0xef, 0x97, 0x84, 0x7b, + 0x9e, 0x22, 0x1d, 0x12, 0x4e, 0xa3, 0x98, 0xc2, 0xc7, 0x2b, 0x96, 0x8a, 0x6a, 0x6c, 0xf1, 0x94, + 0x35, 0x96, 0x4a, 0x27, 0xf1, 0x2c, 0x22, 0x58, 0x41, 0x2f, 0x31, 0xf2, 0xb5, 0xb5, 0xdc, 0xfb, + 0x1f, 0xc4, 0x82, 0xea, 0xdf, 0xcb, 0xfb, 0x89, 0x08, 0xfc, 0xa3, 0x0f, 0xf7, 0x87, 0x14, 0x00, + 0x3d, 0x67, 0xc2, 0x0a, 0x56, 0xa5, 0x05, 0xe1, 0xf9, 0x34, 0xf4, 0xc9, 0x40, 0x7a, 0x4e, 0x00, + 0xe3, 0xd3, 0x07, 0x74, 0x7e, 0x4c, 0x1d, 0x97, 0xc3, 0xa7, 0xff, 0x78, 0x63, 0x03, 0x7b, 0x09, + 0x63, 0x78, 0x32, 0x1c, 0xf3, 0x8f, 0xb2, 0xee, 0x30, 0x7d, 0xc5, 0x2c, 0xb2, 0xcb, 0xb0, 0x7d, + 0xfc, 0x69, 0xab, 0xbd, 0x4e, 0xa3, 0x86, 0x40, 0xd2, 0x32, 0x28, 0xed, 0xf9, 0x56, 0x2e, 0xb6, + 0xdb, 0x97, 0x04, 0x7c, 0xc6, 0xf8, 0x39, 0x02, 0x08, 0x50, 0xa0, 0xe7, 0xe2, 0xa8, 0x1a, 0xc2, + 0xec, 0x78, 0x3e, 0xff, 0x01, 0xdf, 0x4a, 0xa2, 0xa1, 0x28, 0x68, 0x98, 0xf0, 0x7c, 0x28, 0x2a, + 0x48, 0x00, 0x04, 0x54, 0x1d, 0x8c, 0x94, 0x70, 0x6a, 0x1e, 0xc6, 0xd4, 0x78, 0x73, 0x88, 0x0a, + 0x71, 0x21, 0x10, 0x51, 0x07, 0x18, 0x33, 0x2c, 0xc1, 0xd8, 0x34, 0x53, 0xc3, 0x2d, 0x1a, 0x0a, + 0xf8, 0x80, 0x49, 0x8a, 0xe2, 0x06, 0x1a, 0xf8, 0x26, 0x30, 0xf0, 0x7c, 0x74, 0x7c, 0x4b, 0x8f, + 0xc7, 0xfc, 0xf0, 0x7b, 0xbf, 0x0c, 0xc6, 0x4f, 0x98, 0x5a, 0xbb, 0xde, 0x94, 0x0e, 0x42, 0x6a, + 0xe4, 0x81, 0xca, 0xdd, 0x62, 0xdf, 0x8a, 0x3d, 0x38, 0xb7, 0x23, 0x25, 0xa5, 0xf9, 0x30, 0x88, + 0x1a, 0xab, 0x75, 0x1e, 0xf0, 0xee, 0x02, 0xbe, 0xba, 0xed, 0xcc, 0xb9, 0x9e, 0x48, 0x6a, 0xe3, + 0x19, 0x3b, 0x31, 0xf6, 0x70, 0x86, 0x67, 0x0d, 0x38, 0xf4, 0x47, 0x82, 0x38, 0xf0, 0x85, 0x75, + 0x0d, 0xf2, 0xd7, 0x51, 0x1c, 0xb5, 0xac, 0x9c, 0x20, 0x79, 0x98, 0xf0, 0xd5, 0x4e, 0xf1, 0x2f, + 0xfa, 0xc4, 0x8c, 0x11, 0x74, 0xee, 0xbd, 0x4e, 0xa7, 0x8c, 0xaa, 0x67, 0x30, 0xe2, 0x07, 0x15, + 0xec, 0xd2, 0x8d, 0xad, 0x49, 0x52, 0x3a, 0x47, 0x8b, 0x82, 0x80, 0x2c, 0x0d, 0xe2, 0xe3, 0x91, + 0xe0, 0xe4, 0xf1, 0x31, 0x41, 0x8f, 0x0f, 0x06, 0xe0, 0x18, 0xc1, 0x68, 0x07, 0x49, 0x08, 0x00, + 0x19, 0xf8, 0x8e, 0x00, 0xd2, 0x52, 0x21, 0x32, 0xcc, 0x71, 0x00, 0x78, 0x0f, 0x80, 0xc0, 0xbf, + 0x12, 0x00, 0x0a, 0x90, 0x70, 0x35, 0x12, 0x24, 0x18, 0x06, 0x0b, 0xc5, 0xbf, 0xc3, 0x58, 0x01, + 0x41, 0x57, 0x10, 0x0e, 0xf8, 0xf2, 0x7f, 0xed, 0xd6, 0xdd, 0x6d, 0xb7, 0x6d, 0xb4, 0x77, 0x0f, + 0x12, 0x00, 0x7b, 0x80, 0xae, 0x77, 0x38, 0x46, 0x16, 0x3f, 0xdf, 0xde, 0x99, 0xdf, 0x04, 0x2f, + 0x99, 0x0a, 0x23, 0xf2, 0xf1, 0x0d, 0x0a, 0x20, 0xd0, 0x05, 0x47, 0x0b, 0xf4, 0x1b, 0x01, 0x7b, + 0xeb, 0xb6, 0xbc, 0x48, 0x29, 0x21, 0x69, 0xb3, 0x5d, 0x72, 0xe7, 0x6a, 0x31, 0x5e, 0x2b, 0x98, + 0xe2, 0x20, 0xb3, 0x0d, 0x00, 0xb0, 0x85, 0xc3, 0xc5, 0x9b, 0xae, 0x66, 0x07, 0x57, 0x29, 0x86, + 0x09, 0xe7, 0xb1, 0x94, 0xde, 0x20, 0x10, 0xc9, 0xc6, 0xee, 0xcf, 0x71, 0xe0, 0x9c, 0x8b, 0x54, + 0xf1, 0xf6, 0x3a, 0x7e, 0x7f, 0x15, 0xbf, 0xc1, 0x5c, 0x4f, 0xa9, 0xff, 0x2b, 0xa9, 0x2b, 0xc4, + 0x4f, 0xcc, 0xc7, 0x7d, 0x97, 0x2f, 0xe2, 0x44, 0x82, 0xe9, 0x9b, 0xbc, 0xba, 0x9d, 0x58, 0x61, + 0x91, 0x22, 0xce, 0xed, 0x82, 0xcf, 0xaf, 0xa0, 0x7c, 0x5c, 0x12, 0xf0, 0x4d, 0xb4, 0x2e, 0xaa, + 0xa2, 0xea, 0xdf, 0x7a, 0x9b, 0x3f, 0x24, 0x9f, 0xfc, 0x51, 0x5d, 0x6f, 0xbb, 0xe2, 0x44, 0x0b, + 0x11, 0x7b, 0xe0, 0x5e, 0x47, 0xb9, 0x07, 0xfc, 0x4f, 0x82, 0x92, 0x01, 0xdc, 0x94, 0x4e, 0x25, + 0x15, 0x82, 0x2a, 0xb9, 0x8a, 0xbe, 0x37, 0x1d, 0xfe, 0xc2, 0xfb, 0xbf, 0x57, 0x04, 0x53, 0x80, + 0x79, 0x60, 0x03, 0x2f, 0xb1, 0x6b, 0x7c, 0x3d, 0x0a, 0x00, 0x0f, 0x1c, 0x00, 0x0d, 0x39, 0x44, + 0x0f, 0xc6, 0xf1, 0xa5, 0x62, 0xd1, 0xe0, 0x3b, 0x4a, 0x10, 0x00, 0x10, 0x01, 0x46, 0x14, 0x14, + 0x00, 0x0d, 0x00, 0x92, 0x0a, 0x84, 0xf1, 0x5f, 0xe0, 0x48, 0x04, 0x23, 0x67, 0x80, 0x01, 0x9c, + 0x12, 0x00, 0x05, 0x70, 0x3a, 0xc3, 0x57, 0xe0, 0x75, 0x8d, 0x6a, 0x27, 0xa9, 0x66, 0x9a, 0xc0, + 0xd5, 0xe7, 0x1c, 0xb9, 0x16, 0xa3, 0xfc, 0xbd, 0xd8, 0x59, 0x89, 0x4c, 0x19, 0x62, 0x69, 0xac, + 0x19, 0xfb, 0x2c, 0x5e, 0x1e, 0x9c, 0x01, 0x9c, 0x96, 0xd2, 0x0c, 0x53, 0xe5, 0xa9, 0xbf, 0x17, + 0x2f, 0x8f, 0x1b, 0xe4, 0xc9, 0xc7, 0x6e, 0x3a, 0xbb, 0xd3, 0xa6, 0x9e, 0xbf, 0x0a, 0x66, 0xf1, + 0x72, 0xc3, 0x84, 0x0f, 0xf3, 0x1f, 0x53, 0xce, 0x3e, 0x0c, 0xb6, 0xb0, 0x1c, 0x9c, 0xca, 0x31, + 0x51, 0x61, 0x93, 0x12, 0x2c, 0x4c, 0x61, 0x85, 0x7f, 0x26, 0x22, 0xf9, 0xa2, 0x80, 0x64, 0xc6, + 0xe7, 0xe3, 0x78, 0xf2, 0x96, 0x70, 0xa0, 0x35, 0x03, 0x12, 0x22, 0x1a, 0x87, 0xc6, 0x8a, 0xd0, + 0x3a, 0xb3, 0xb3, 0x61, 0x7b, 0x14, 0xd3, 0x69, 0xaf, 0xf1, 0x92, 0x55, 0x6d, 0xd8, 0x0e, 0x45, + 0x11, 0xad, 0x3d, 0x3d, 0x5e, 0x4a, 0x79, 0xa2, 0xb6, 0x56, 0x9b, 0x12, 0x6e, 0xf8, 0xbe, 0xab, + 0x8b, 0xaf, 0x10, 0x2a, 0xaa, 0xb5, 0x55, 0x5c, 0x30, 0x20, 0x14, 0xf3, 0xe2, 0xe7, 0xcb, 0xd5, + 0x31, 0x75, 0x73, 0x88, 0x82, 0xcb, 0xb7, 0x6d, 0x62, 0x99, 0xa8, 0x93, 0xdb, 0xf2, 0xaf, 0x04, + 0x65, 0xc5, 0x65, 0xc6, 0x01, 0xae, 0x2b, 0x5a, 0xc9, 0x99, 0xf8, 0x4f, 0xb9, 0xf2, 0xd2, 0xa0, + 0x97, 0x17, 0xd9, 0x8d, 0xdc, 0xd6, 0x1c, 0xcf, 0xb2, 0xad, 0x19, 0x6a, 0xb8, 0xa2, 0x4b, 0x97, + 0x6a, 0x9f, 0xc2, 0x86, 0x71, 0x2e, 0x08, 0x61, 0xfa, 0xa1, 0xa3, 0xaf, 0x9a, 0xc7, 0x55, 0x03, + 0x14, 0xe1, 0x1d, 0xbe, 0x32, 0xf6, 0x77, 0x2b, 0x1f, 0x7a, 0x9a, 0x1e, 0xf9, 0x0f, 0x5a, 0xbf, + 0xc3, 0xd1, 0xa0, 0x28, 0x0b, 0x42, 0x50, 0x00, 0x2f, 0xed, 0x1b, 0xf0, 0x72, 0x61, 0xa9, 0x45, + 0x2a, 0x29, 0xa0, 0x0f, 0x11, 0x01, 0x50, 0xeb, 0x8c, 0x01, 0xc7, 0xee, 0x25, 0x20, 0x81, 0x19, + 0x2e, 0x11, 0x4a, 0x5a, 0xd3, 0x06, 0xfe, 0x15, 0x2c, 0x7f, 0x82, 0x80, 0xc8, 0xd2, 0x05, 0x40, + 0x70, 0x19, 0x47, 0xb4, 0x2f, 0x16, 0x10, 0x26, 0x03, 0xe1, 0x1b, 0x87, 0x82, 0xc3, 0x8e, 0x3d, + 0x0d, 0x81, 0x56, 0x9f, 0x67, 0xba, 0x2a, 0x05, 0x7b, 0xc2, 0xc4, 0x25, 0x2f, 0x0b, 0xbf, 0xf5, + 0xd0, 0xdc, 0xe0, 0x45, 0x7c, 0xab, 0x2f, 0x1f, 0x12, 0x11, 0x0a, 0x54, 0xab, 0x75, 0x6a, 0xd4, + 0xcf, 0x92, 0xe8, 0xc6, 0x47, 0xf4, 0x17, 0xc7, 0x9a, 0x16, 0xd7, 0x29, 0x06, 0x61, 0x64, 0x5c, + 0x99, 0x64, 0x41, 0x54, 0x19, 0xde, 0x7a, 0xee, 0x11, 0x82, 0xaa, 0x8a, 0x21, 0x77, 0x12, 0x22, + 0xa3, 0xb1, 0x46, 0x3c, 0x43, 0x93, 0x6e, 0x67, 0x05, 0x22, 0x42, 0x59, 0x31, 0x7c, 0x2c, 0xa9, + 0x47, 0x5c, 0x10, 0x89, 0x04, 0x23, 0x59, 0x90, 0xf7, 0x2a, 0x19, 0x12, 0x22, 0xa9, 0x70, 0x7d, + 0x89, 0xf8, 0x98, 0x21, 0x8a, 0x69, 0x68, 0x7f, 0x2f, 0xa2, 0x77, 0xc1, 0x75, 0xef, 0xe7, 0x83, + 0x8f, 0x04, 0x7c, 0x43, 0x82, 0xb4, 0xa8, 0xbc, 0xb4, 0xdb, 0x78, 0x57, 0x11, 0x5d, 0x9a, 0xb5, + 0x26, 0x20, 0x49, 0x48, 0x43, 0x76, 0xed, 0xc6, 0xe9, 0xe4, 0x22, 0x56, 0x63, 0x6c, 0xbc, 0x14, + 0xfa, 0xbf, 0x2b, 0xf4, 0x23, 0x33, 0x0f, 0xf6, 0x9a, 0x6f, 0xbd, 0x1b, 0x4d, 0x09, 0x84, 0x44, + 0x8c, 0xb3, 0x38, 0xe9, 0xbb, 0x4d, 0x9e, 0x7c, 0xed, 0xd3, 0x7b, 0xbc, 0xd9, 0x89, 0x10, 0x36, + 0x68, 0xc9, 0x16, 0x97, 0x08, 0x86, 0x86, 0x71, 0x8f, 0xc9, 0x00, 0xa9, 0xf8, 0x7a, 0x4b, 0x5d, + 0xa1, 0xe2, 0x61, 0xb1, 0xa3, 0xfc, 0x70, 0xf3, 0x01, 0x1a, 0x43, 0x51, 0x17, 0x21, 0x60, 0x9f, + 0xa4, 0x42, 0xfa, 0xff, 0x10, 0x0a, 0x61, 0x75, 0x79, 0x4e, 0x2f, 0x53, 0xf8, 0x3e, 0xec, 0xc9, + 0xd9, 0xc2, 0x21, 0x01, 0x9c, 0x96, 0xab, 0xbb, 0x10, 0xc5, 0xd5, 0x6b, 0x34, 0x3b, 0x45, 0xe2, + 0x8b, 0x55, 0x17, 0x81, 0xd1, 0x91, 0x4d, 0x83, 0x5c, 0x00, 0x96, 0x43, 0x93, 0x00, 0x07, 0xa1, + 0xa9, 0x08, 0x3c, 0xf7, 0x3f, 0x1d, 0x2f, 0xcf, 0x39, 0x20, 0x0c, 0x05, 0x78, 0x58, 0x01, 0x4c, + 0x13, 0x67, 0x5d, 0xd5, 0x9e, 0x1a, 0x96, 0x05, 0xca, 0x87, 0x3a, 0xf1, 0xfa, 0x15, 0xfc, 0x34, + 0xff, 0xe0, 0xe0, 0x91, 0x08, 0xa4, 0x5d, 0xc1, 0x8d, 0xdb, 0x66, 0xf8, 0x10, 0x04, 0x85, 0x0a, + 0x78, 0xb3, 0x06, 0x3a, 0x5e, 0xc5, 0x2c, 0x1d, 0x0f, 0x8a, 0xcb, 0x59, 0xf5, 0x1b, 0xfd, 0x6a, + 0x58, 0x11, 0x25, 0x0e, 0xa1, 0x20, 0x02, 0xb2, 0x71, 0xf5, 0x64, 0x67, 0xfe, 0x21, 0xe4, 0xa0, + 0xfe, 0x94, 0x8d, 0xcf, 0xd9, 0xfd, 0x6b, 0x09, 0xdb, 0x2f, 0x8f, 0xdb, 0x6f, 0xe1, 0x95, 0x00, + 0x1b, 0x70, 0x6f, 0xb6, 0x4a, 0x23, 0x7c, 0x3f, 0x82, 0x51, 0xc5, 0x2b, 0x94, 0xc4, 0x7b, 0x22, + 0xc9, 0x38, 0xd3, 0xcf, 0x1f, 0xa1, 0xbe, 0x10, 0x35, 0x5f, 0x97, 0x29, 0x0c, 0xfb, 0xf8, 0xfa, + 0xab, 0x18, 0x87, 0x37, 0x7b, 0xa4, 0x1e, 0x65, 0x79, 0x35, 0xbf, 0x12, 0x28, 0x99, 0xb2, 0xab, + 0xf8, 0x43, 0x7b, 0xe7, 0x7e, 0xb5, 0xf2, 0xd5, 0xbc, 0xf0, 0x88, 0x40, 0x29, 0xc7, 0x12, 0x70, + 0x98, 0x05, 0x50, 0x00, 0x0f, 0xce, 0xd2, 0xaf, 0x54, 0x47, 0x17, 0x8c, 0xe5, 0x93, 0x53, 0x8f, + 0xe0, 0xe0, 0x29, 0x2a, 0x1c, 0xa4, 0xa2, 0xa1, 0xb9, 0x49, 0xce, 0x46, 0xe4, 0x89, 0x0f, 0x77, + 0x2c, 0x3b, 0x6a, 0xd6, 0xda, 0x0d, 0xfe, 0x04, 0x0b, 0xc1, 0xf8, 0xa1, 0xc4, 0x9e, 0x00, 0x11, + 0x13, 0xe1, 0x90, 0xc8, 0x52, 0x5b, 0x14, 0x07, 0x3c, 0x05, 0x18, 0x07, 0xf1, 0xb4, 0x86, 0xa5, + 0x73, 0xa5, 0x57, 0x3c, 0x39, 0xa1, 0x3d, 0x80, 0x63, 0xaa, 0xec, 0xdb, 0x82, 0x90, 0x88, 0x52, + 0x44, 0x4a, 0xdd, 0x3b, 0x54, 0xf2, 0xc9, 0x82, 0x1f, 0xc3, 0xf1, 0xad, 0x99, 0x10, 0x1a, 0x64, + 0xa0, 0x03, 0xca, 0x2f, 0x12, 0x9c, 0xa4, 0x82, 0x88, 0x47, 0x29, 0x74, 0x05, 0x1d, 0x63, 0xcf, + 0x6d, 0x39, 0xb0, 0xdd, 0x92, 0xd7, 0xd7, 0x21, 0x25, 0xc7, 0x0d, 0xca, 0x00, 0x25, 0x14, 0xed, + 0x00, 0x10, 0x0f, 0xb5, 0x43, 0x0c, 0xef, 0x79, 0x0f, 0xc5, 0xac, 0x3f, 0x05, 0xa7, 0xce, 0x00, + 0x30, 0x53, 0x80, 0x30, 0x32, 0x04, 0x9e, 0xef, 0x37, 0xf0, 0x40, 0x11, 0x1a, 0x60, 0x22, 0x1b, + 0xc2, 0x41, 0x87, 0x5a, 0x19, 0x6d, 0x04, 0x5c, 0xa3, 0xf0, 0x97, 0x46, 0x45, 0xaf, 0x25, 0xcb, + 0x14, 0x46, 0x99, 0x89, 0x3c, 0x98, 0x00, 0x72, 0x7b, 0x26, 0xed, 0xea, 0xb5, 0x54, 0x44, 0x72, + 0xce, 0x74, 0x45, 0x46, 0x59, 0xff, 0xa3, 0xf4, 0x81, 0xc4, 0x50, 0x01, 0xf2, 0x65, 0x54, 0x27, + 0xfe, 0x9f, 0x0e, 0x2c, 0x26, 0x66, 0x6d, 0xe9, 0x39, 0x63, 0x9f, 0xe3, 0xd8, 0xb7, 0x2d, 0xff, + 0x86, 0x89, 0x00, 0x1c, 0x77, 0xa0, 0x9e, 0x3e, 0xfb, 0xf1, 0xb6, 0xc5, 0xc9, 0x13, 0xc6, 0x3b, + 0x41, 0x31, 0x4d, 0x5e, 0x03, 0x1f, 0x1e, 0xdd, 0x0d, 0xd0, 0x1b, 0xec, 0xd8, 0x70, 0x82, 0x00, + 0x02, 0x89, 0x60, 0xe8, 0x6e, 0xd4, 0xef, 0x89, 0x8b, 0xce, 0xdb, 0x66, 0xe0, 0xa3, 0x8c, 0x59, + 0xb9, 0xb0, 0x70, 0x57, 0x8e, 0x23, 0xe5, 0x77, 0x03, 0xbf, 0x0e, 0xef, 0xf2, 0xc2, 0x9c, 0xb2, + 0xc0, 0xc0, 0x3d, 0x81, 0x67, 0x83, 0xaf, 0x9e, 0x3f, 0xe5, 0x38, 0xf5, 0xec, 0xf1, 0x9d, 0x5b, + 0xe6, 0x32, 0xd6, 0x68, 0x98, 0x4f, 0x5a, 0xd6, 0xa6, 0xe4, 0x3b, 0xbf, 0xec, 0xae, 0xff, 0x10, + 0x09, 0xc9, 0x38, 0x82, 0x69, 0x3a, 0x91, 0xdd, 0x3f, 0xdf, 0x18, 0x68, 0x69, 0xc1, 0xbd, 0x06, + 0xa5, 0x03, 0x9a, 0xe9, 0x4e, 0xc8, 0x8b, 0xa7, 0x10, 0xd9, 0xa9, 0x78, 0x46, 0x6f, 0x1d, 0xcf, + 0x2c, 0x06, 0xe3, 0xa3, 0x27, 0xc9, 0xcb, 0xd5, 0x49, 0x08, 0x04, 0x42, 0xe7, 0x83, 0x01, 0x4a, + 0x43, 0xc6, 0xd4, 0xaa, 0xa7, 0x2c, 0x02, 0x1f, 0x89, 0x30, 0xae, 0x11, 0x06, 0x01, 0x41, 0x0f, + 0x71, 0x99, 0x89, 0x7c, 0x4f, 0xdb, 0x46, 0x79, 0x75, 0x63, 0xb7, 0x59, 0x42, 0xd9, 0xf9, 0x6c, + 0xb6, 0x83, 0x2f, 0x89, 0x85, 0x25, 0x80, 0x69, 0x8a, 0x01, 0x93, 0xeb, 0x2e, 0xae, 0x70, 0x70, + 0xef, 0x92, 0xf2, 0xf2, 0x71, 0x73, 0xbf, 0xdc, 0x20, 0x08, 0x06, 0xd4, 0x60, 0xf8, 0xb4, 0x07, + 0xe8, 0xc9, 0x80, 0x01, 0xc1, 0x38, 0x98, 0x18, 0x2c, 0x2a, 0x45, 0x51, 0xaf, 0xe7, 0x0c, 0x87, + 0x70, 0x4b, 0x51, 0xd5, 0x83, 0x38, 0x38, 0xfb, 0x1e, 0x41, 0x6c, 0xbd, 0x75, 0x75, 0xe1, 0x98, + 0x53, 0x8f, 0x34, 0x02, 0xaa, 0xc3, 0x96, 0x63, 0xbb, 0x6b, 0xa4, 0x82, 0x53, 0xbc, 0x58, 0x6e, + 0x2e, 0xc7, 0xf9, 0x27, 0xac, 0x39, 0xfa, 0x0a, 0xf1, 0x21, 0x00, 0x4c, 0x56, 0x3a, 0x9b, 0xdb, + 0x03, 0xd3, 0xa2, 0xe5, 0x70, 0xa0, 0xa2, 0x14, 0x8a, 0xb3, 0xbe, 0x24, 0x2c, 0x33, 0x2a, 0x5a, + 0x42, 0xa5, 0xc1, 0xd2, 0xe2, 0xb1, 0xd2, 0xe7, 0x58, 0x53, 0x51, 0x76, 0x2a, 0x43, 0xc9, 0xd8, + 0x6d, 0xc0, 0x04, 0xb7, 0x0e, 0xc8, 0x81, 0x74, 0xc6, 0xf6, 0xfa, 0xba, 0xed, 0x8f, 0x74, 0xad, + 0xd4, 0x1d, 0xf9, 0x6b, 0x90, 0x67, 0x3a, 0xfc, 0x3a, 0xe0, 0x07, 0x61, 0xa3, 0xce, 0x64, 0x01, + 0x64, 0xb8, 0x30, 0x7f, 0xff, 0xa1, 0xbd, 0xae, 0x16, 0x92, 0xad, 0x06, 0xab, 0x58, 0x69, 0xce, + 0x99, 0x05, 0xbf, 0xc3, 0x38, 0x97, 0x0f, 0xf1, 0x79, 0xa4, 0x1e, 0x7a, 0x2f, 0xb4, 0xe2, 0x3f, + 0x90, 0x31, 0xb2, 0xa4, 0x90, 0xac, 0x0c, 0x80, 0xae, 0x0a, 0xba, 0x7a, 0x78, 0x07, 0x63, 0xd3, + 0x6d, 0xe1, 0xe2, 0x40, 0x03, 0xe5, 0xb0, 0x4b, 0xd4, 0xf4, 0x04, 0xdc, 0x7f, 0xb1, 0x91, 0x6a, + 0x1d, 0x9e, 0x09, 0x41, 0x32, 0x07, 0x6e, 0x0e, 0xfc, 0x62, 0xaa, 0x0a, 0x08, 0xa5, 0xe7, 0x35, + 0x67, 0x6f, 0xb6, 0x63, 0x76, 0x1b, 0xb8, 0xe0, 0x91, 0xde, 0x26, 0x6b, 0x16, 0xff, 0x89, 0x19, + 0x5b, 0x74, 0x65, 0x6a, 0xef, 0x0f, 0xcd, 0x87, 0x24, 0x27, 0xcf, 0xd0, 0xfd, 0x0b, 0x0f, 0x10, + 0x24, 0x20, 0x4c, 0x4f, 0x14, 0xb3, 0x11, 0xa0, 0x90, 0x34, 0x2c, 0x37, 0x34, 0x8d, 0x97, 0xc4, + 0x82, 0xcd, 0xd7, 0xbb, 0x23, 0x31, 0x3f, 0x43, 0x30, 0x61, 0xf0, 0xcb, 0x12, 0x00, 0x1c, 0xf2, + 0xa3, 0x1c, 0x7c, 0xa9, 0xfe, 0xff, 0x22, 0x2c, 0x51, 0x67, 0xe0, 0xa7, 0x06, 0x83, 0x60, 0x33, + 0x88, 0xd9, 0x18, 0xd6, 0xe2, 0xdb, 0xc1, 0x6a, 0x31, 0xf0, 0x6d, 0x30, 0xd9, 0x0c, 0x02, 0xe3, + 0x42, 0xa5, 0x34, 0x38, 0xc5, 0xad, 0x56, 0xaf, 0xdf, 0xb2, 0x72, 0x80, 0xaa, 0x00, 0x62, 0x3c, + 0x33, 0xca, 0x8c, 0x2a, 0x3b, 0xef, 0x2c, 0x2d, 0xce, 0x0c, 0x47, 0x37, 0x24, 0x74, 0x26, 0xf0, + 0x60, 0x2a, 0x24, 0x37, 0x2c, 0x1d, 0x7c, 0x1c, 0x5f, 0xed, 0xb7, 0x87, 0xb0, 0x00, 0xb0, 0x09, + 0x49, 0xd0, 0xa0, 0x20, 0xe9, 0x47, 0xbe, 0xfe, 0x5f, 0xc3, 0xcb, 0x8b, 0xef, 0x12, 0x1e, 0x51, + 0xa9, 0x57, 0xc1, 0xef, 0x1d, 0xe2, 0x3d, 0x7e, 0x19, 0xf8, 0x54, 0x70, 0x35, 0xd2, 0xc3, 0xc7, + 0x93, 0x9a, 0x03, 0x56, 0x38, 0x9c, 0x22, 0x4c, 0x1d, 0x6a, 0x37, 0x98, 0xab, 0xa8, 0xce, 0x52, + 0x2d, 0x39, 0x39, 0x84, 0xe7, 0x97, 0xd9, 0x41, 0xd7, 0x94, 0x2d, 0xf2, 0x0a, 0xad, 0x7d, 0xd6, + 0xbf, 0x31, 0x16, 0xab, 0xe5, 0x3d, 0x6a, 0xb8, 0x22, 0xcd, 0xe8, 0x6c, 0xf0, 0x88, 0x50, 0xc7, + 0xf9, 0xf6, 0x15, 0xab, 0x99, 0x8c, 0x51, 0xe2, 0x8c, 0xe1, 0x62, 0x8e, 0xe7, 0xf6, 0x78, 0xc3, + 0x3b, 0x05, 0xa7, 0x10, 0x14, 0x28, 0x97, 0xb2, 0x05, 0xb8, 0x87, 0x6c, 0xa8, 0xbc, 0x1d, 0x17, + 0x12, 0xe1, 0x6f, 0x26, 0x25, 0xf2, 0xad, 0xc6, 0x37, 0x0c, 0x42, 0x58, 0xd2, 0xf3, 0x40, 0x46, + 0x96, 0x58, 0x02, 0x3f, 0xf1, 0x01, 0xd8, 0xf6, 0x84, 0xb0, 0xd5, 0x07, 0xe8, 0x4f, 0xa2, 0x81, + 0xa2, 0xa6, 0x71, 0x98, 0xff, 0x48, 0xcb, 0xbd, 0xf8, 0x2b, 0xd4, 0x57, 0xc4, 0x8a, 0x8f, 0x88, + 0x12, 0x19, 0x8f, 0xe8, 0x1a, 0xc6, 0x46, 0xa1, 0x11, 0xc5, 0xb7, 0xb2, 0xf8, 0x22, 0x14, 0x7c, + 0x48, 0x0c, 0x17, 0x58, 0x90, 0x59, 0xed, 0x93, 0xac, 0x2b, 0x56, 0x62, 0xeb, 0x12, 0x0d, 0xe4, + 0x9d, 0x2e, 0x11, 0x85, 0x0c, 0x0b, 0x37, 0x01, 0x7f, 0xa0, 0xa8, 0xe6, 0x10, 0x49, 0xe9, 0x1e, + 0xc5, 0x68, 0x8e, 0x0d, 0x80, 0x4c, 0x5f, 0x84, 0xee, 0x35, 0xde, 0x0e, 0x01, 0xc8, 0xb2, 0x78, + 0x39, 0x78, 0x3a, 0x1e, 0x1e, 0x00, 0xe0, 0xce, 0xe2, 0x61, 0x49, 0x30, 0xab, 0xe0, 0x0e, 0x59, + 0xcf, 0x3f, 0xcb, 0x0c, 0xf3, 0xd0, 0x47, 0x88, 0x6c, 0x2a, 0x0f, 0x1e, 0x7c, 0x9c, 0xf2, 0xfa, + 0xab, 0x86, 0x42, 0x21, 0x43, 0x85, 0xf8, 0x94, 0x62, 0x21, 0x29, 0xad, 0x06, 0x4c, 0x5e, 0x0b, + 0x98, 0x2c, 0x34, 0xdd, 0xb1, 0xf9, 0x5b, 0x38, 0x1d, 0xd2, 0x9e, 0x07, 0x35, 0x07, 0x4b, 0x0f, + 0xc1, 0xb8, 0x44, 0x32, 0x14, 0x2c, 0x47, 0x0f, 0x7c, 0x96, 0xb7, 0x1e, 0x3e, 0xc3, 0xb9, 0x29, + 0x35, 0x43, 0xa5, 0xa8, 0xb2, 0xfc, 0x3d, 0x61, 0x75, 0x52, 0x97, 0x02, 0x8a, 0xe0, 0x81, 0xcf, + 0x6e, 0x71, 0x21, 0x91, 0x9a, 0xd6, 0xa5, 0x94, 0xb8, 0xa2, 0xb7, 0xa5, 0x14, 0x78, 0x64, 0x32, + 0x14, 0x22, 0x48, 0x93, 0xae, 0xf0, 0xa8, 0x3f, 0x2a, 0x35, 0x4a, 0x90, 0x92, 0xc3, 0xb7, 0x26, + 0xb2, 0x40, 0x1f, 0x16, 0x03, 0xae, 0x10, 0x0c, 0x05, 0x08, 0x14, 0x50, 0xd0, 0x38, 0xbd, 0x93, + 0x50, 0x2c, 0x08, 0x4a, 0x23, 0x43, 0xe0, 0x94, 0x45, 0x50, 0x01, 0x29, 0x01, 0x41, 0x97, 0x49, + 0x6b, 0xdb, 0x8b, 0xd7, 0x24, 0x06, 0xa5, 0xd4, 0x26, 0x15, 0x7b, 0x07, 0x5b, 0x0f, 0x22, 0x80, + 0xb2, 0x85, 0x0e, 0xe7, 0x29, 0x7c, 0x02, 0x9a, 0xdc, 0x86, 0x16, 0x56, 0x04, 0xf9, 0x81, 0x6a, + 0x7b, 0xca, 0xbf, 0x1d, 0xee, 0xa4, 0x37, 0xff, 0x3f, 0x6c, 0xfc, 0x77, 0xe3, 0x8b, 0xe3, 0xc9, + 0x96, 0xdf, 0xe1, 0xb7, 0x00, 0x56, 0x5b, 0x2a, 0x00, 0x37, 0x3d, 0x08, 0x7f, 0xed, 0xdc, 0xfd, + 0x2a, 0xb2, 0xc2, 0xb8, 0x7b, 0xc6, 0x73, 0x59, 0x63, 0xaf, 0xbf, 0xf2, 0x70, 0x2c, 0x12, 0x07, + 0x0b, 0x00, 0x70, 0xb1, 0xc3, 0xa7, 0x92, 0x20, 0xd2, 0xb8, 0x1f, 0x4f, 0xda, 0x6e, 0x13, 0xe0, + 0x93, 0xaa, 0xb4, 0x21, 0xc9, 0x55, 0xaf, 0xba, 0xae, 0xe0, 0x82, 0x49, 0xb4, 0x0e, 0x0c, 0x2a, + 0xfc, 0x10, 0x84, 0x44, 0x1e, 0xdf, 0xd1, 0xd7, 0xc2, 0x66, 0x38, 0x16, 0x0c, 0xc0, 0xef, 0x85, + 0x5f, 0x0b, 0x10, 0x18, 0x27, 0x88, 0xd7, 0x05, 0xc5, 0xa7, 0x6d, 0x4d, 0xe0, 0x51, 0xe5, 0xc3, + 0x89, 0x8c, 0x10, 0x6c, 0x92, 0x6d, 0x58, 0x45, 0x4d, 0x1e, 0x3d, 0x21, 0xcb, 0xe9, 0x3f, 0x49, + 0xf7, 0x4a, 0xe3, 0x15, 0xe9, 0xe4, 0xb0, 0xc5, 0x4b, 0x18, 0x90, 0xf1, 0xf7, 0xe2, 0x46, 0x51, + 0x24, 0x16, 0xf9, 0xeb, 0x53, 0xf0, 0x2e, 0x78, 0xe3, 0xdf, 0x59, 0x2d, 0x96, 0xa5, 0xea, 0x14, + 0xb3, 0x8f, 0x0c, 0x89, 0x18, 0x5c, 0xf8, 0xee, 0x55, 0x41, 0x8b, 0xca, 0xd6, 0x7f, 0x89, 0x3c, + 0xeb, 0x07, 0x7b, 0xbb, 0xb2, 0x70, 0x88, 0x29, 0x1f, 0x87, 0x95, 0x89, 0x79, 0x60, 0xd9, 0x85, + 0x05, 0x67, 0x2c, 0x45, 0x78, 0x21, 0x04, 0x23, 0x0a, 0x55, 0x03, 0x53, 0xde, 0x78, 0xfb, 0x2d, + 0x8a, 0x03, 0x15, 0x8a, 0x3b, 0x8a, 0xde, 0x3a, 0x34, 0x0a, 0x65, 0x5d, 0x58, 0x44, 0x14, 0x85, + 0x22, 0x07, 0x0b, 0x65, 0xb1, 0x5b, 0xdd, 0x64, 0xf8, 0xe4, 0x9e, 0x68, 0x0b, 0x97, 0xf7, 0x0c, + 0x82, 0x90, 0x8f, 0x5b, 0x35, 0x89, 0xc6, 0xef, 0xe0, 0x84, 0x18, 0x85, 0x2e, 0x88, 0x91, 0x61, + 0x17, 0xe7, 0x69, 0x45, 0xf0, 0xe5, 0xf5, 0xf8, 0x29, 0x7d, 0x59, 0x5f, 0x81, 0xae, 0x31, 0x30, + 0x5b, 0x09, 0x56, 0x2a, 0x64, 0x70, 0x02, 0xe0, 0x0b, 0x2a, 0xdd, 0xa9, 0x47, 0x04, 0x00, 0xe0, + 0x3a, 0x60, 0x71, 0x00, 0xf0, 0x3a, 0xc0, 0xd4, 0x3d, 0xbc, 0x86, 0xbf, 0xc7, 0x8e, 0x55, 0x74, + 0x0b, 0x88, 0xd2, 0x1c, 0xe0, 0x60, 0xcc, 0x85, 0xc2, 0x86, 0x49, 0xfd, 0x77, 0xe1, 0x5e, 0x84, + 0xb5, 0x71, 0xe4, 0x77, 0xf3, 0x65, 0x55, 0x6b, 0x9b, 0x7b, 0x85, 0x38, 0xa3, 0x4d, 0x91, 0x29, + 0x59, 0xc0, 0xac, 0xb2, 0x68, 0xaf, 0x08, 0x86, 0x02, 0x67, 0xb2, 0x9f, 0xa3, 0xfd, 0xd3, 0x10, + 0xe6, 0x10, 0x12, 0x32, 0x7e, 0xab, 0xc2, 0xb6, 0x61, 0x66, 0xa5, 0x98, 0xbb, 0xf5, 0xc9, 0x4c, + 0x73, 0x17, 0x88, 0x04, 0x21, 0x4e, 0x21, 0x80, 0xea, 0xdd, 0x6c, 0x1a, 0x34, 0xe4, 0xec, 0x0f, + 0x28, 0x89, 0xf2, 0xdf, 0x5d, 0x89, 0x1a, 0x18, 0x1e, 0x8d, 0x96, 0xf5, 0xd6, 0x1d, 0xbf, 0x89, + 0x08, 0x99, 0x8a, 0x38, 0x98, 0xc5, 0x50, 0x13, 0xae, 0x81, 0x73, 0x03, 0xd7, 0x49, 0x9b, 0xd0, + 0x51, 0x9c, 0x38, 0x70, 0x39, 0x88, 0x8c, 0x2d, 0xb7, 0x7a, 0x9c, 0x24, 0x58, 0x60, 0xe9, 0xe1, + 0xe3, 0x83, 0xcf, 0x0e, 0x68, 0xff, 0x32, 0xba, 0x67, 0xff, 0x0a, 0x17, 0x8a, 0xb5, 0xaa, 0x6d, + 0x46, 0x16, 0xb3, 0xb3, 0x30, 0xde, 0x3a, 0x5d, 0xf8, 0x40, 0x22, 0x32, 0x77, 0xd4, 0x9b, 0x0e, + 0xe2, 0x6f, 0x1d, 0x78, 0x22, 0x09, 0x55, 0x2d, 0x8e, 0x9e, 0x68, 0x87, 0xd6, 0x1f, 0x04, 0x20, + 0xa6, 0x73, 0x5c, 0x6d, 0x76, 0x9d, 0xd4, 0x32, 0xbc, 0x67, 0x2c, 0x0a, 0xc7, 0x98, 0x83, 0x2c, + 0xc0, 0xf1, 0xe4, 0xef, 0x12, 0x14, 0x11, 0xbd, 0x5c, 0x5b, 0x2f, 0xc4, 0x02, 0xc1, 0x2a, 0xa2, + 0x41, 0xc2, 0xc1, 0xc7, 0x4f, 0x28, 0x5b, 0xb2, 0xd6, 0xbc, 0x44, 0x2d, 0xcc, 0x47, 0xc5, 0xfc, + 0x60, 0x93, 0x62, 0xb1, 0x98, 0xf1, 0x7b, 0x9e, 0x70, 0xf2, 0xd6, 0x37, 0x71, 0x9d, 0x8c, 0xc9, + 0xcf, 0x3d, 0x65, 0xda, 0xff, 0x89, 0x8c, 0xbf, 0xf5, 0x2f, 0x55, 0xd2, 0x10, 0xf2, 0xdc, 0xf0, + 0x76, 0xc3, 0x10, 0x24, 0x22, 0x23, 0xcb, 0x6e, 0x21, 0xa0, 0xae, 0x5b, 0x7d, 0xb1, 0xcf, 0x61, + 0x08, 0xc9, 0x44, 0x3f, 0x30, 0x8f, 0xd6, 0x73, 0x83, 0xa1, 0xe0, 0xe9, 0xe1, 0x6d, 0xb9, 0x6a, + 0x25, 0x6a, 0xa1, 0x7e, 0x22, 0x26, 0x78, 0xe5, 0x96, 0xdf, 0x77, 0xc4, 0x08, 0x18, 0x25, 0x4f, + 0xf1, 0x76, 0x77, 0x65, 0xb3, 0xd4, 0x29, 0x97, 0x8b, 0x8b, 0x97, 0x95, 0xaa, 0xcf, 0x88, 0x10, + 0x14, 0x20, 0x87, 0x8b, 0x5f, 0xcc, 0x8a, 0xd1, 0x0f, 0xb5, 0xb3, 0x0a, 0x0f, 0x90, 0xe3, 0xe4, + 0xf2, 0xb3, 0x22, 0x79, 0x0f, 0xb8, 0x88, 0x42, 0xce, 0xed, 0x5b, 0xa5, 0xc7, 0x6f, 0xbb, 0x7c, + 0x1c, 0x8c, 0x9b, 0xc6, 0xda, 0x60, 0xd5, 0xab, 0xb1, 0xa9, 0x4e, 0x39, 0x4d, 0x0c, 0x5b, 0x7e, + 0x16, 0x32, 0xd8, 0x90, 0x1e, 0x13, 0x89, 0x12, 0x6b, 0xdf, 0xc4, 0x5f, 0x04, 0x95, 0xaf, 0xab, + 0x82, 0x2b, 0xbd, 0xeb, 0xe5, 0xbd, 0xfe, 0x62, 0x3d, 0xe1, 0x2e, 0x43, 0xcd, 0xff, 0x1e, 0x48, + 0xab, 0xbd, 0xcf, 0x88, 0x46, 0x8b, 0xf3, 0x08, 0x06, 0x06, 0x1e, 0x24, 0x85, 0x62, 0x5e, 0x1c, + 0x57, 0x2b, 0x2f, 0x45, 0x77, 0x42, 0x68, 0xfd, 0xd9, 0x83, 0xd6, 0x62, 0x41, 0x40, 0xc2, 0x3b, + 0x8a, 0xc4, 0x0e, 0x03, 0x6a, 0xa5, 0x15, 0x2b, 0x56, 0xb1, 0x53, 0xe8, 0xee, 0x57, 0x2b, 0xff, + 0x58, 0xbe, 0x18, 0x10, 0x33, 0x5a, 0x58, 0xad, 0x45, 0xc5, 0x65, 0xc1, 0x58, 0xa3, 0x77, 0x15, + 0x96, 0xdc, 0x57, 0x88, 0x85, 0x3c, 0x43, 0x8d, 0x19, 0x8d, 0x21, 0x59, 0x6c, 0x51, 0x89, 0x7b, + 0x8a, 0x33, 0x9e, 0x58, 0x38, 0xb8, 0x88, 0x2b, 0xc8, 0xbe, 0xf0, 0xa0, 0x02, 0xa3, 0x90, 0x3c, + 0xc3, 0x2f, 0x2d, 0xc3, 0xf0, 0x80, 0x91, 0xfa, 0x8a, 0xe7, 0x70, 0x94, 0xad, 0xb9, 0x2f, 0x07, + 0xba, 0x16, 0x3c, 0x40, 0x64, 0x61, 0xcb, 0xb0, 0xba, 0xa7, 0xbf, 0x24, 0x54, 0x95, 0x4c, 0x5d, + 0x96, 0x31, 0x23, 0xc4, 0x83, 0xcb, 0x7b, 0x57, 0xe0, 0x80, 0x20, 0x65, 0xea, 0xc7, 0xda, 0xb3, + 0x02, 0x06, 0x14, 0x65, 0x8d, 0x1b, 0xde, 0x14, 0xe8, 0xec, 0x5f, 0x14, 0x45, 0x55, 0x27, 0x59, + 0x9b, 0xbe, 0xc8, 0xed, 0xbb, 0x85, 0x78, 0x22, 0xc4, 0x3c, 0xda, 0x58, 0xfb, 0x86, 0x04, 0x85, + 0x2f, 0xed, 0x97, 0x4e, 0x56, 0x78, 0x5e, 0xa3, 0x51, 0xe7, 0x3c, 0x8a, 0x24, 0x01, 0x03, 0xbc, + 0x83, 0xe5, 0x71, 0x29, 0xd2, 0x0c, 0x26, 0x78, 0x78, 0xfb, 0xc0, 0xa0, 0x30, 0x80, 0x7f, 0x29, + 0x61, 0x93, 0x8e, 0x61, 0x63, 0x5d, 0x62, 0xcd, 0x38, 0x35, 0x55, 0x1e, 0x8c, 0x05, 0x6b, 0x53, + 0xf6, 0x22, 0xdf, 0x12, 0x0c, 0x02, 0x85, 0x24, 0x29, 0x1f, 0x84, 0x2c, 0x28, 0xa8, 0x96, 0x07, + 0x9b, 0x07, 0x3c, 0x17, 0x9d, 0x86, 0x80, 0x09, 0xd7, 0x11, 0xce, 0x10, 0xf4, 0x87, 0x6e, 0xe6, + 0xcb, 0x5c, 0x10, 0x02, 0x01, 0x92, 0x41, 0x52, 0xc7, 0x4e, 0x2c, 0x37, 0x2a, 0x60, 0xa4, 0xaa, + 0xf6, 0xce, 0x71, 0xfd, 0x45, 0x1b, 0x98, 0x2c, 0x1e, 0x24, 0x0b, 0x03, 0x08, 0x3c, 0x0b, 0x04, + 0x00, 0x70, 0x96, 0xa7, 0x1c, 0x2c, 0x0c, 0x53, 0x38, 0xe3, 0x30, 0x94, 0x05, 0x49, 0x5c, 0x16, + 0x00, 0x0c, 0x3b, 0xbb, 0xbc, 0xc9, 0xd0, 0xb3, 0xfc, 0x10, 0x0c, 0xe3, 0x98, 0xb9, 0x82, 0x45, + 0x4b, 0x00, 0x69, 0x00, 0x01, 0xd0, 0x1d, 0x66, 0xad, 0xd1, 0xca, 0x64, 0xad, 0x44, 0xc1, 0xcb, + 0xf8, 0x64, 0x28, 0x70, 0xb8, 0xaa, 0xba, 0x97, 0xe1, 0x4d, 0x4f, 0xa6, 0xbe, 0xab, 0x25, 0x1d, + 0x5d, 0xfd, 0x8d, 0xac, 0xc1, 0x9c, 0x10, 0x97, 0x29, 0x6b, 0x53, 0x76, 0x4a, 0xd4, 0xd8, 0x82, + 0xd5, 0x6a, 0x12, 0xe2, 0xb6, 0xf1, 0x5c, 0x75, 0x7f, 0x82, 0xad, 0x34, 0x9c, 0x48, 0x3c, 0xf7, + 0xdd, 0xbb, 0xee, 0xf1, 0x01, 0x42, 0xf5, 0x3c, 0x51, 0x3e, 0xf6, 0xb2, 0xb3, 0x43, 0x2e, 0xe8, + 0xae, 0x78, 0x90, 0x59, 0x2f, 0x26, 0x1a, 0x31, 0xf5, 0x52, 0x30, 0x29, 0x8b, 0x96, 0x62, 0xfd, + 0xc4, 0x08, 0x18, 0x20, 0x98, 0x00, 0x15, 0x0b, 0xa7, 0x9c, 0x2b, 0x35, 0x65, 0xa9, 0xc1, 0xb9, + 0x98, 0x35, 0x18, 0x84, 0xee, 0xbe, 0xcc, 0x59, 0xf1, 0x95, 0x70, 0x93, 0xdf, 0x47, 0x5d, 0x28, + 0x84, 0xc5, 0xd2, 0x19, 0xcc, 0x64, 0xca, 0xef, 0x8a, 0xd5, 0x9c, 0xb7, 0xf0, 0x88, 0xd3, 0x93, + 0x95, 0x6a, 0x5d, 0xbe, 0x1b, 0x7b, 0xd4, 0x56, 0x93, 0xa8, 0x58, 0xce, 0xc1, 0x6f, 0x12, 0xec, + 0x28, 0xdc, 0xb1, 0xbe, 0xb9, 0x8a, 0xef, 0x84, 0x62, 0x71, 0x78, 0x88, 0x43, 0x94, 0x93, 0xe3, + 0xe4, 0xc4, 0x32, 0xee, 0xfe, 0x08, 0xa2, 0x98, 0xa6, 0x97, 0x5f, 0x25, 0x24, 0xaf, 0xe2, 0x04, + 0x5b, 0x33, 0x92, 0xff, 0xd9, 0x5a, 0xc5, 0x0c, 0x7d, 0x7f, 0x04, 0x5b, 0xbe, 0xa2, 0xf9, 0x0b, + 0xbb, 0x82, 0x8e, 0x5b, 0xdd, 0xd7, 0x25, 0xdf, 0xf7, 0x9d, 0x87, 0xd7, 0x21, 0x2f, 0x7f, 0x67, + 0x77, 0x7f, 0x98, 0x8f, 0x7a, 0xe1, 0x3d, 0xdd, 0xce, 0xc5, 0x8e, 0x06, 0xfe, 0x5d, 0xee, 0x0e, + 0xb9, 0x6e, 0xf8, 0x35, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x43, 0x21, 0xb1, 0xa1, 0xf1, + 0x31, 0x93, 0x7d, 0xb8, 0x81, 0x60, 0xe7, 0x04, 0x2c, 0x1c, 0x3d, 0xdb, 0x2f, 0x7f, 0xb2, 0xdb, + 0x79, 0x6f, 0x11, 0x05, 0x7e, 0x28, 0xe2, 0x40, 0x70, 0x51, 0xdb, 0x18, 0x97, 0xcf, 0x7e, 0xa0, + 0xa7, 0x89, 0xbb, 0xbd, 0xdf, 0x11, 0xcd, 0x4a, 0xc6, 0x2b, 0xc4, 0xc2, 0x42, 0x39, 0x7c, 0x9d, + 0xbf, 0xc4, 0xc6, 0xe9, 0xbf, 0xd0, 0xd0, 0xdb, 0xe2, 0x44, 0x88, 0x8a, 0xde, 0xda, 0xc5, 0xf8, + 0x81, 0x20, 0xb0, 0x4b, 0x88, 0x1f, 0xaa, 0x2b, 0xcd, 0xeb, 0xdf, 0x04, 0x75, 0x93, 0xfa, 0x0b, + 0xb1, 0x3f, 0x28, 0x8a, 0xaa, 0xa8, 0x99, 0xab, 0x5f, 0x82, 0x63, 0xad, 0x6a, 0xa8, 0x77, 0xff, + 0x88, 0xa8, 0x9f, 0x13, 0x44, 0xef, 0x10, 0x59, 0x68, 0xed, 0x09, 0x64, 0x09, 0xf9, 0x6b, 0x55, + 0x3c, 0x48, 0x8f, 0x97, 0xa6, 0xdf, 0x10, 0xca, 0x7f, 0x4f, 0xc4, 0x7c, 0x11, 0xf7, 0x7e, 0xae, + 0x08, 0x84, 0x93, 0x35, 0x7a, 0x89, 0x84, 0x07, 0x6e, 0xe4, 0xf7, 0xbb, 0xbb, 0xe1, 0x1f, 0x08, + 0xf8, 0x91, 0x06, 0x2e, 0xe7, 0xdc, 0x4e, 0x0a, 0xf1, 0x01, 0x1a, 0xaf, 0x93, 0xd5, 0x7e, 0x24, + 0x10, 0x95, 0xdf, 0x14, 0xdf, 0x04, 0x64, 0x7b, 0xde, 0xbf, 0xc1, 0x1e, 0xab, 0xef, 0x11, 0xf0, + 0x4c, 0x55, 0xae, 0xce, 0xf2, 0xe2, 0x28, 0x43, 0xf1, 0x11, 0x24, 0xdd, 0xdd, 0xfe, 0x23, 0xc4, + 0x4d, 0x04, 0x02, 0x41, 0x39, 0x71, 0x25, 0x84, 0xc5, 0xf5, 0x77, 0x04, 0x01, 0x11, 0x25, 0xcb, + 0x91, 0x2f, 0xad, 0x70, 0x60, 0x92, 0x20, 0x40, 0x9a, 0xaa, 0xae, 0x5a, 0xaf, 0x82, 0x42, 0xe9, + 0x0a, 0xfb, 0xe3, 0xf7, 0xbe, 0x76, 0x1b, 0x6d, 0x0d, 0x0d, 0xfd, 0x5f, 0xe0, 0x9c, 0xca, 0xb1, + 0x3e, 0xee, 0xee, 0xaa, 0x8f, 0xc4, 0x41, 0x55, 0x45, 0xf1, 0xa5, 0x17, 0x36, 0x33, 0xa3, 0x3a, + 0x15, 0xde, 0x6f, 0x2f, 0x82, 0xbf, 0x58, 0xbe, 0x23, 0x06, 0x8b, 0x58, 0x55, 0xa3, 0x31, 0xbd, + 0xcd, 0xef, 0x9b, 0x85, 0xca, 0xca, 0x88, 0x97, 0x9b, 0x0d, 0x9c, 0x49, 0x0c, 0x2e, 0x2e, 0x23, + 0x8c, 0xcc, 0x46, 0x68, 0x81, 0x23, 0xb3, 0x78, 0xbd, 0x6b, 0x97, 0x9f, 0xe2, 0x04, 0x04, 0x0a, + 0xde, 0xde, 0xeb, 0x56, 0xf1, 0xc6, 0x38, 0x63, 0xa0, 0xed, 0x45, 0xf2, 0x07, 0x2b, 0x4b, 0x88, + 0x08, 0x15, 0x98, 0x77, 0x2f, 0x36, 0x57, 0x41, 0x1a, 0x90, 0x3f, 0x04, 0x65, 0x4b, 0x57, 0xe2, + 0x3e, 0x24, 0x66, 0x9b, 0xb1, 0xa4, 0x0c, 0x63, 0x12, 0x26, 0x7d, 0x84, 0x24, 0x12, 0x46, 0xe3, + 0x96, 0xce, 0x79, 0x6b, 0xe5, 0xb4, 0xc2, 0x58, 0x5c, 0x48, 0x40, 0x43, 0x25, 0xff, 0x67, 0xd6, + 0x4d, 0x40, 0x85, 0xac, 0x44, 0x4e, 0x86, 0xec, 0x9b, 0x4f, 0x51, 0x12, 0x55, 0x2c, 0xe9, 0x62, + 0x6e, 0xab, 0xfb, 0xac, 0xf8, 0x8c, 0xd8, 0x40, 0x13, 0x97, 0x97, 0xc7, 0x68, 0x3b, 0x18, 0xdc, + 0x77, 0x08, 0x03, 0x91, 0xb1, 0x03, 0x0d, 0x1b, 0x25, 0x9f, 0x04, 0xfe, 0x2e, 0xec, 0x0d, 0x44, + 0xfd, 0x0e, 0xc8, 0xaf, 0xf6, 0x6a, 0x15, 0x9f, 0x86, 0xf3, 0x1a, 0x55, 0xeb, 0x27, 0x2f, 0xc4, + 0x04, 0x47, 0x11, 0xd5, 0x3e, 0xcb, 0x3b, 0x99, 0x7f, 0xaf, 0xa7, 0x14, 0x45, 0xb1, 0x5e, 0x18, + 0x0c, 0xfc, 0x14, 0x1f, 0x2e, 0x08, 0x73, 0x3f, 0x0b, 0x96, 0x31, 0x71, 0x22, 0x42, 0x26, 0x6c, + 0x1f, 0x63, 0x2b, 0xce, 0x72, 0x16, 0x54, 0x72, 0x0e, 0x92, 0x78, 0x7f, 0x12, 0x37, 0x57, 0x9a, + 0x43, 0x19, 0x6c, 0x68, 0x7b, 0xcb, 0x26, 0x57, 0x47, 0x40, 0x01, 0x71, 0xb2, 0x01, 0x0d, 0xb9, + 0x2b, 0x3c, 0x3e, 0xc4, 0x49, 0xaf, 0xcd, 0x47, 0x0a, 0xf4, 0x19, 0xa8, 0xbc, 0x40, 0xc0, 0x91, + 0x6a, 0xb3, 0x64, 0x98, 0x82, 0xca, 0x4e, 0x9b, 0xa9, 0xb5, 0x19, 0x7f, 0x10, 0x10, 0xea, 0xb2, + 0xab, 0x5d, 0x1a, 0xc4, 0x0e, 0x35, 0xe5, 0xe2, 0x07, 0x96, 0x0c, 0xb6, 0x3e, 0xa5, 0xcb, 0x7e, + 0x22, 0xe2, 0xbf, 0xf9, 0x7a, 0xaf, 0xba, 0xd6, 0x58, 0x10, 0x26, 0x13, 0x51, 0xdc, 0x78, 0x38, + 0x12, 0x8c, 0x99, 0x61, 0x80, 0x88, 0x24, 0x2b, 0x8a, 0xcd, 0xf3, 0x22, 0xf1, 0x12, 0xca, 0x08, + 0x0d, 0x78, 0x38, 0x85, 0xc9, 0xb6, 0x6c, 0x8b, 0x81, 0xf8, 0xd4, 0xba, 0x5f, 0xcb, 0x01, 0x35, + 0x18, 0x29, 0x08, 0x0d, 0x26, 0xa8, 0xa2, 0x84, 0x1f, 0x08, 0xc1, 0xd6, 0x97, 0xc9, 0x85, 0x47, + 0x80, 0x7c, 0xc3, 0xf4, 0xd0, 0x07, 0x89, 0x74, 0x7d, 0x81, 0xa0, 0x40, 0xea, 0x17, 0x88, 0x05, + 0x2c, 0xaa, 0x4a, 0x41, 0xa8, 0x02, 0x17, 0xea, 0xf9, 0xf3, 0x0c, 0x04, 0x06, 0x47, 0x4f, 0x07, + 0x1f, 0x09, 0x8f, 0x99, 0x85, 0xaa, 0x7f, 0x57, 0x48, 0x43, 0x8e, 0xff, 0x10, 0x20, 0x54, 0xba, + 0xb1, 0x25, 0x89, 0xa1, 0xe0, 0x82, 0x1b, 0xc5, 0x19, 0x72, 0xa9, 0x7e, 0xd9, 0xe9, 0x1e, 0x0c, + 0x04, 0x9b, 0xc6, 0xb1, 0x83, 0x01, 0x20, 0x82, 0x95, 0x86, 0xd4, 0xd1, 0xc0, 0x0d, 0x22, 0x7e, + 0x73, 0x83, 0xc9, 0xcf, 0x82, 0xe1, 0x52, 0xb0, 0xb0, 0x10, 0x5d, 0x59, 0xa4, 0x21, 0x82, 0xec, + 0x7f, 0x10, 0x19, 0x38, 0x69, 0x09, 0x09, 0xd6, 0xf9, 0xc1, 0xe9, 0xff, 0x2d, 0x36, 0xdc, 0x11, + 0x72, 0x73, 0xc3, 0xe2, 0xc8, 0xa8, 0xbd, 0x0c, 0x6a, 0xa5, 0xc7, 0x95, 0x55, 0x57, 0x55, 0x51, + 0x75, 0x5f, 0x2f, 0x13, 0x62, 0xb9, 0x89, 0xaa, 0xf9, 0x36, 0xea, 0xe0, 0x82, 0x0a, 0xb4, 0xae, + 0xda, 0x89, 0x7c, 0x8a, 0xde, 0xe5, 0x24, 0x58, 0x28, 0x12, 0x36, 0xd0, 0x3b, 0xe2, 0x52, 0x72, + 0x45, 0x03, 0x95, 0xc3, 0xc1, 0x93, 0x5a, 0xc5, 0xb0, 0x29, 0x4d, 0x9f, 0x74, 0xc2, 0x99, 0x7f, + 0x12, 0x11, 0x05, 0x5b, 0xdf, 0x71, 0x5b, 0xb9, 0x79, 0x63, 0xcc, 0x7c, 0x29, 0x13, 0xc1, 0x6c, + 0x39, 0xb5, 0x40, 0x00, 0xf1, 0x60, 0x03, 0x07, 0x40, 0xf9, 0x60, 0x03, 0x0e, 0xb3, 0x52, 0xc6, + 0x78, 0xe0, 0x97, 0x2d, 0x7a, 0xbb, 0x35, 0x22, 0x06, 0x5a, 0xc2, 0x02, 0x46, 0x90, 0xa0, 0x28, + 0x61, 0xc0, 0x00, 0x14, 0x68, 0x17, 0x10, 0x2f, 0x2c, 0x40, 0x01, 0x45, 0x1c, 0x00, 0x01, 0x46, + 0x4c, 0x41, 0x2a, 0xd1, 0x0a, 0x24, 0xf0, 0x16, 0x0b, 0xf1, 0x7a, 0x00, 0x64, 0x19, 0x87, 0x2c, + 0x7b, 0x97, 0x91, 0xa2, 0x08, 0xc5, 0x5d, 0x32, 0x64, 0x76, 0xf8, 0x91, 0xa5, 0x41, 0xc7, 0x38, + 0x01, 0xc6, 0x72, 0x90, 0x66, 0x00, 0xa9, 0x61, 0xec, 0x1c, 0xf6, 0x50, 0x1a, 0x02, 0x66, 0x83, + 0x90, 0xf0, 0xe0, 0x60, 0x38, 0x8f, 0x0f, 0x00, 0x60, 0x3a, 0x7c, 0xc8, 0x23, 0x38, 0x70, 0xc2, + 0xf0, 0x8c, 0x61, 0x43, 0x04, 0x3f, 0x2e, 0x37, 0xc4, 0x85, 0x29, 0x36, 0x48, 0x02, 0xa5, 0xae, + 0x4d, 0x72, 0xc7, 0x60, 0x00, 0x0b, 0xa8, 0x4c, 0xd4, 0xa0, 0xb5, 0x8c, 0x7e, 0x85, 0xa6, 0x7e, + 0x28, 0x57, 0xc1, 0x3f, 0x89, 0x19, 0x2d, 0x8a, 0xf1, 0xfc, 0x07, 0xcb, 0x2e, 0x93, 0xcb, 0x6f, + 0x4c, 0x43, 0x84, 0x8e, 0x58, 0x88, 0x8c, 0x45, 0xcc, 0x43, 0x84, 0xae, 0x0b, 0x0a, 0xb1, 0x10, + 0x5f, 0x28, 0x80, 0x94, 0xac, 0x02, 0x52, 0x5a, 0x8e, 0x41, 0x62, 0xea, 0x12, 0x4c, 0x5d, 0x98, + 0xff, 0xa3, 0xfc, 0x13, 0xf1, 0x05, 0x55, 0xe4, 0xcd, 0xf1, 0xc4, 0x77, 0xbb, 0x1e, 0x3b, 0x47, + 0xbb, 0xa8, 0x64, 0x40, 0x28, 0x08, 0x9f, 0xc6, 0x5a, 0x78, 0xae, 0x2b, 0x1b, 0x4c, 0x38, 0x88, + 0x01, 0xf6, 0x83, 0xb9, 0xbf, 0xd3, 0x4d, 0x24, 0x93, 0x4d, 0x24, 0x98, 0xed, 0xff, 0x08, 0x08, + 0x1a, 0x32, 0x20, 0xc6, 0x50, 0x19, 0xc3, 0x53, 0x16, 0x35, 0xa6, 0xd9, 0xc0, 0x00, 0x4f, 0x0a, + 0x23, 0x53, 0xc0, 0x00, 0xaf, 0x3c, 0x01, 0xf2, 0xa3, 0xab, 0x9c, 0x78, 0x62, 0x40, 0x14, 0x0a, + 0x41, 0x8a, 0xb5, 0xaf, 0xe1, 0x08, 0xe3, 0x8e, 0x2d, 0xca, 0x7b, 0xdf, 0x14, 0xf0, 0xc2, 0x28, + 0x1d, 0xb5, 0xa9, 0x15, 0x6d, 0xa7, 0xfd, 0xa6, 0xb4, 0xf2, 0x2f, 0xe2, 0x04, 0x82, 0xa2, 0x09, + 0xe1, 0x7a, 0x5e, 0xf2, 0xe4, 0x51, 0x9b, 0x17, 0x66, 0x97, 0x89, 0x85, 0x04, 0x0e, 0xdd, 0x30, + 0x46, 0xdc, 0x53, 0x9c, 0xd5, 0xa4, 0x70, 0x0f, 0x38, 0x01, 0xc3, 0xc0, 0x58, 0x3c, 0x01, 0xc0, + 0x3e, 0x06, 0xa1, 0xf8, 0x0d, 0x4e, 0x00, 0x03, 0x3c, 0xf0, 0x00, 0x33, 0xc0, 0xce, 0x42, 0x46, + 0xbc, 0x16, 0xf2, 0xcb, 0x0f, 0xc3, 0x5b, 0x25, 0x00, 0x02, 0xaa, 0x51, 0x1a, 0xe4, 0xfc, 0x21, + 0x26, 0x4b, 0xd1, 0x97, 0x84, 0x21, 0x02, 0xdb, 0x8f, 0xc0, 0xed, 0xd9, 0x65, 0x7b, 0x64, 0xa7, + 0x81, 0x47, 0x8c, 0x8f, 0x84, 0x20, 0xaf, 0x84, 0x36, 0x95, 0xaa, 0x42, 0xbb, 0xbb, 0xf0, 0xc8, + 0x80, 0xa1, 0xeb, 0x57, 0xab, 0xb8, 0x18, 0xa0, 0xd3, 0x00, 0x7a, 0x19, 0x79, 0x6b, 0x40, 0x23, + 0x40, 0x0c, 0x0a, 0x91, 0xed, 0xe4, 0x10, 0xb2, 0x87, 0x5e, 0x16, 0x32, 0x76, 0xc2, 0x30, 0x54, + 0x30, 0xa0, 0x03, 0x14, 0x1d, 0x92, 0x22, 0x38, 0x15, 0xaf, 0xf8, 0x4f, 0x4f, 0xec, 0x71, 0x9f, + 0xd3, 0xfa, 0x5d, 0x97, 0x71, 0x17, 0x6b, 0xad, 0xba, 0x73, 0xaf, 0x32, 0x7a, 0x64, 0xeb, 0xc3, + 0x8a, 0x03, 0x4b, 0xdc, 0x12, 0x33, 0xbf, 0x6e, 0xdf, 0xa6, 0x9f, 0x2f, 0xa6, 0x9f, 0xc4, 0x82, + 0xb3, 0x03, 0x12, 0x52, 0xb1, 0x29, 0xf8, 0x13, 0x00, 0x6e, 0x14, 0xaa, 0x1e, 0x05, 0x81, 0x8a, + 0x04, 0xa0, 0xe8, 0x2c, 0x02, 0x24, 0xa7, 0x6d, 0xd4, 0x3f, 0x84, 0xea, 0x49, 0xe3, 0x41, 0xf8, + 0x91, 0x6e, 0x72, 0x0b, 0xd9, 0xf3, 0x59, 0x8f, 0x0c, 0x03, 0x90, 0xa0, 0xc1, 0xf5, 0x99, 0x15, + 0x95, 0x41, 0x50, 0x9c, 0x00, 0xdd, 0x28, 0xa5, 0x0f, 0x02, 0x3a, 0x8c, 0xa9, 0x63, 0x2c, 0x74, + 0xaf, 0x0f, 0xe4, 0x1f, 0x02, 0xb5, 0x0e, 0xd0, 0xf8, 0xe1, 0x97, 0xc2, 0x11, 0xb0, 0xa0, 0xb0, + 0x69, 0x32, 0x02, 0xd5, 0x55, 0xe7, 0xb5, 0x6c, 0x00, 0x12, 0xc0, 0xe0, 0xb1, 0xd4, 0x5a, 0x00, + 0x07, 0xe2, 0x11, 0x19, 0x55, 0x48, 0x0e, 0x4e, 0xc6, 0xc3, 0x32, 0x17, 0x03, 0x66, 0x00, 0x09, + 0x48, 0x48, 0x94, 0x2d, 0x18, 0x32, 0x44, 0x28, 0x00, 0x4a, 0x1a, 0xb4, 0x11, 0x3a, 0x52, 0xf5, + 0x5b, 0xc3, 0xf8, 0x3f, 0xed, 0x57, 0x60, 0x49, 0x0c, 0x0d, 0xbb, 0x72, 0x3c, 0x73, 0x81, 0xd8, + 0xa3, 0x15, 0x9f, 0x0b, 0x18, 0x75, 0x02, 0x57, 0x44, 0x3b, 0x00, 0x00, 0x80, 0x22, 0x87, 0x14, + 0x04, 0xb3, 0x1d, 0x2c, 0x0b, 0x05, 0x45, 0x28, 0x6a, 0x7e, 0xdd, 0xdf, 0xc4, 0x84, 0x0a, 0xe6, + 0x65, 0xe3, 0x74, 0xec, 0x5b, 0x8d, 0x51, 0xe0, 0xf1, 0x31, 0x90, 0x3b, 0x15, 0x1b, 0x01, 0x7c, + 0xa1, 0x38, 0xd0, 0x2e, 0xec, 0x69, 0x1c, 0x25, 0x95, 0x8a, 0xea, 0x16, 0x6f, 0x97, 0x7a, 0xb9, + 0xa5, 0xe1, 0x4b, 0x76, 0x32, 0x55, 0xdc, 0xb8, 0x5b, 0x2d, 0x88, 0xb3, 0x43, 0x81, 0xdc, 0x57, + 0x13, 0xcc, 0xcf, 0x82, 0x6b, 0xde, 0xfd, 0x5e, 0x09, 0x79, 0xba, 0xaa, 0xec, 0xeb, 0x5f, 0x12, + 0x24, 0xd5, 0xb6, 0xad, 0xaf, 0x89, 0x45, 0x7f, 0x84, 0xcd, 0xab, 0x58, 0xba, 0x7e, 0x28, 0xb0, + 0xeb, 0x96, 0x38, 0x8b, 0xa9, 0x7c, 0x53, 0xc1, 0x08, 0x0f, 0x11, 0xa2, 0x0b, 0x00, 0x62, 0x80, + 0x0c, 0xb0, 0x18, 0xa0, 0x33, 0xc0, 0x1c, 0x25, 0x01, 0xf0, 0xe3, 0xe5, 0x06, 0x28, 0x0c, 0x27, + 0x64, 0x81, 0xa0, 0xf5, 0xd3, 0x39, 0xee, 0x06, 0x01, 0x28, 0x29, 0x30, 0x77, 0xe0, 0xeb, 0xff, + 0xe2, 0x40, 0x6c, 0x87, 0x8a, 0x4a, 0x00, 0x04, 0x7c, 0x4e, 0x00, 0xad, 0x3a, 0x89, 0x44, 0xc8, + 0x99, 0xcd, 0xd8, 0xd2, 0x6f, 0x95, 0x87, 0x3a, 0x45, 0x5b, 0x7f, 0xc3, 0xaa, 0x02, 0xeb, 0x50, + 0xb2, 0xa2, 0x20, 0xa4, 0x76, 0xdb, 0xe8, 0xe3, 0x79, 0x8c, 0xab, 0x77, 0x19, 0xb8, 0xa6, 0x0f, + 0xf8, 0xb9, 0x2f, 0x54, 0x5f, 0x24, 0x7d, 0x93, 0x55, 0xb3, 0xf1, 0xd0, 0x96, 0x7c, 0xb5, 0x07, + 0x1b, 0xd1, 0xf1, 0x00, 0xa2, 0x9b, 0xd5, 0xa0, 0xe4, 0x05, 0xe2, 0xc4, 0x60, 0xae, 0xe0, 0x95, + 0x8c, 0xc9, 0x49, 0x96, 0x10, 0x08, 0x84, 0x0c, 0x0a, 0xb7, 0x0b, 0xd7, 0x15, 0x4a, 0x8e, 0x38, + 0x5d, 0x42, 0x8d, 0x45, 0xe2, 0x25, 0xa3, 0xee, 0x55, 0x57, 0x89, 0x05, 0xa2, 0x45, 0xb7, 0xd0, + 0x10, 0x2a, 0x10, 0x71, 0x1e, 0xf9, 0xaa, 0x97, 0xb8, 0x42, 0x14, 0x30, 0xbe, 0x94, 0xb5, 0xc8, + 0x0d, 0x48, 0x98, 0x3a, 0x0f, 0xeb, 0x52, 0x58, 0xb1, 0xf0, 0xf6, 0xc4, 0xd4, 0xf0, 0x78, 0x72, + 0x63, 0xa6, 0x0a, 0x0e, 0x15, 0x61, 0x8c, 0x0e, 0x43, 0xe7, 0x80, 0xf7, 0x69, 0xee, 0x68, 0xf7, + 0xc6, 0x16, 0x4e, 0x20, 0x72, 0xbc, 0xbf, 0x1d, 0x1f, 0x15, 0x75, 0x87, 0xb8, 0x4a, 0x98, 0x1f, + 0x7d, 0xfc, 0x7d, 0xdc, 0xd1, 0x5d, 0x9d, 0xeb, 0x52, 0x7c, 0x20, 0x24, 0x7d, 0xdf, 0x93, 0x1d, + 0xb8, 0x20, 0x79, 0x63, 0x10, 0xf7, 0xe6, 0x22, 0x0a, 0xcf, 0x97, 0x15, 0xf9, 0x8c, 0xe1, 0xf7, + 0xa6, 0xe8, 0x21, 0x40, 0x97, 0x8a, 0xd5, 0x45, 0xd4, 0x5d, 0x7e, 0x3a, 0xb5, 0x55, 0x55, 0x55, + 0x55, 0x57, 0x13, 0x31, 0x1c, 0x6f, 0x30, 0x23, 0xe8, 0xdd, 0xcc, 0x5e, 0x31, 0xf1, 0x84, 0x36, + 0x00, 0xc5, 0xc5, 0x8e, 0x03, 0x75, 0x45, 0x95, 0xda, 0x18, 0x65, 0xdf, 0xfb, 0xbb, 0x77, 0xbd, + 0x44, 0x86, 0x06, 0x90, 0x3a, 0x32, 0xa9, 0xe7, 0x02, 0xe2, 0xc2, 0x59, 0x66, 0x15, 0x02, 0x98, + 0xa6, 0xa8, 0x19, 0xe8, 0x19, 0x40, 0x7f, 0x1b, 0x19, 0x25, 0x90, 0x31, 0xb6, 0x03, 0xa7, 0x87, + 0x80, 0x01, 0x19, 0x38, 0x0a, 0x8e, 0x87, 0x87, 0xbf, 0x44, 0x10, 0x4b, 0xdb, 0x6d, 0x78, 0x80, + 0xc8, 0xd2, 0xd4, 0x67, 0x00, 0x63, 0x19, 0x40, 0x1f, 0xc9, 0x07, 0x89, 0x07, 0x59, 0x82, 0xc1, + 0x84, 0xab, 0xa5, 0x85, 0x88, 0x78, 0x30, 0x58, 0xfb, 0x33, 0x00, 0x51, 0x21, 0xbf, 0xcc, 0x18, + 0x40, 0x54, 0x89, 0x13, 0x14, 0x26, 0x00, 0x12, 0x65, 0x00, 0xa3, 0xc4, 0x1d, 0x04, 0xbd, 0xbc, + 0x5f, 0x12, 0x03, 0x44, 0x15, 0x66, 0x4b, 0xec, 0x50, 0x7f, 0x97, 0x62, 0x10, 0x2c, 0x1c, 0xf1, + 0xba, 0x0f, 0xfe, 0x5c, 0x09, 0x20, 0xc0, 0x6e, 0xa0, 0x80, 0x92, 0xc3, 0xc1, 0xc5, 0x63, 0x2a, + 0x50, 0x01, 0x1a, 0x92, 0x64, 0x02, 0x44, 0x8a, 0x80, 0x02, 0xe8, 0x14, 0x50, 0x70, 0x00, 0x4b, + 0xff, 0x71, 0x58, 0x3d, 0x43, 0xe5, 0xf5, 0x15, 0xa7, 0xc4, 0x04, 0x06, 0xd9, 0x08, 0x06, 0xa1, + 0xd6, 0x5c, 0x00, 0x01, 0xe5, 0x0e, 0x90, 0x12, 0xca, 0xe2, 0xd0, 0x73, 0x81, 0x28, 0xf0, 0x16, + 0x07, 0x4c, 0x12, 0xa2, 0x02, 0xb0, 0x2c, 0x1e, 0x48, 0xfb, 0x27, 0xf4, 0x90, 0xec, 0x73, 0xf6, + 0xe4, 0xff, 0x05, 0x9e, 0x6c, 0x69, 0xa3, 0x49, 0xf8, 0x28, 0xff, 0x17, 0x11, 0x85, 0x9c, 0x59, + 0x72, 0xd8, 0xfc, 0xee, 0x22, 0x14, 0x80, 0xd3, 0x43, 0x3a, 0x72, 0x6a, 0xa4, 0x37, 0xf6, 0x78, + 0x01, 0x95, 0x82, 0x56, 0xaa, 0x24, 0x00, 0x0a, 0xb3, 0x96, 0x56, 0x33, 0x36, 0x92, 0x54, 0x0f, + 0x3b, 0x0a, 0xbc, 0x30, 0x72, 0x18, 0xec, 0x9e, 0x21, 0xe3, 0xe0, 0xdf, 0xcc, 0x7e, 0x5f, 0x89, + 0x12, 0x28, 0xc3, 0x8c, 0x4f, 0xf9, 0x95, 0xb8, 0x81, 0xa6, 0x04, 0x01, 0x21, 0x4c, 0xcd, 0x96, + 0xc5, 0xd4, 0x9c, 0x40, 0x78, 0xb8, 0x7a, 0x4a, 0x5d, 0x69, 0x2b, 0x9c, 0x0a, 0x02, 0x42, 0x85, + 0x18, 0x5d, 0xdb, 0x14, 0xc5, 0x00, 0xd4, 0x47, 0x17, 0x74, 0xed, 0xcd, 0x99, 0x7c, 0xb7, 0xdc, + 0x39, 0xc9, 0xad, 0x45, 0x73, 0x5c, 0xf8, 0xbf, 0xb3, 0x5e, 0x3b, 0x47, 0x0c, 0xc6, 0xc1, 0xa2, + 0x1a, 0x01, 0x8b, 0x17, 0x07, 0x17, 0x2a, 0xf0, 0x93, 0x28, 0x62, 0xc0, 0xa9, 0x9d, 0x9a, 0x66, + 0x70, 0x00, 0x70, 0x60, 0xc2, 0xe0, 0x6c, 0xbc, 0x97, 0x84, 0xa4, 0xeb, 0x67, 0x4e, 0x09, 0x4d, + 0x4e, 0xa4, 0x20, 0x63, 0x4b, 0x9b, 0x44, 0xf4, 0x5b, 0xf8, 0x64, 0x69, 0xc4, 0xba, 0xc0, 0x08, + 0x4a, 0x1f, 0x85, 0x8e, 0x95, 0xba, 0x64, 0x40, 0x08, 0x7d, 0xf0, 0x0a, 0x4a, 0xdb, 0xfe, 0x2b, + 0xef, 0x09, 0x55, 0x75, 0x10, 0xf0, 0x97, 0x8a, 0x59, 0x3c, 0x18, 0xfd, 0x89, 0x08, 0x0d, 0x22, + 0xd7, 0x8a, 0x37, 0x1f, 0x50, 0x1b, 0x21, 0xaa, 0x58, 0xb5, 0x86, 0xf5, 0x21, 0xdb, 0x0b, 0xc3, + 0xa6, 0x25, 0x18, 0x26, 0x2a, 0x1f, 0x00, 0x02, 0x94, 0x44, 0x12, 0x5f, 0x94, 0x06, 0xa9, 0xce, + 0xc3, 0xac, 0xe0, 0x0b, 0xdd, 0xb2, 0xcb, 0x30, 0xa0, 0x33, 0xdd, 0xf0, 0x38, 0x2b, 0xcf, 0xe5, + 0xbd, 0x91, 0x02, 0x84, 0x19, 0x38, 0xff, 0xee, 0xf8, 0xea, 0xed, 0xf8, 0x24, 0x43, 0xa0, 0xa7, + 0x4f, 0x88, 0x7c, 0xf1, 0xfc, 0x10, 0x84, 0x42, 0x86, 0x38, 0xe0, 0xfd, 0x83, 0xf0, 0xb7, 0x32, + 0x72, 0xc1, 0x19, 0xea, 0x31, 0xe3, 0xf2, 0x8a, 0x32, 0x02, 0xea, 0xba, 0x94, 0xae, 0xdc, 0xec, + 0x95, 0xcb, 0xb7, 0x66, 0xc7, 0x06, 0x21, 0x80, 0xa5, 0x28, 0x88, 0x87, 0x1d, 0xaa, 0xa9, 0x60, + 0x58, 0x3a, 0x2a, 0xfb, 0x65, 0x45, 0xfa, 0x2c, 0xf7, 0x11, 0x6d, 0xc6, 0x54, 0xad, 0xf9, 0xb2, + 0x0b, 0x0a, 0x1e, 0x07, 0x63, 0x50, 0xc0, 0x82, 0x10, 0x0e, 0x94, 0x3a, 0x67, 0xe4, 0xe8, 0xff, + 0x87, 0x0d, 0xfd, 0x27, 0xf0, 0xdd, 0xf8, 0xa4, 0xa1, 0x6c, 0xdf, 0xfc, 0x09, 0x21, 0x0e, 0x04, + 0x10, 0x81, 0x0e, 0x7c, 0x7e, 0x78, 0x10, 0x44, 0x38, 0x38, 0x8f, 0x01, 0xd7, 0x9e, 0x04, 0x91, + 0x00, 0x97, 0x3a, 0x88, 0xe1, 0xdc, 0x99, 0x48, 0xbc, 0x12, 0xc1, 0x85, 0x32, 0x28, 0x4b, 0xd3, + 0xc5, 0x7a, 0x41, 0xf0, 0x9e, 0x7c, 0xbd, 0xdd, 0xfc, 0x12, 0x77, 0x78, 0x3e, 0xbd, 0x04, 0x11, + 0x31, 0x22, 0x06, 0x73, 0x97, 0xfd, 0xdf, 0xf2, 0x58, 0x49, 0x1f, 0x3f, 0x09, 0x55, 0x7a, 0x4f, + 0x27, 0x2e, 0x2b, 0xba, 0x88, 0x01, 0xa0, 0x43, 0xeb, 0x57, 0xe2, 0x00, 0x64, 0x05, 0x4c, 0x34, + 0x06, 0x1c, 0x61, 0xc0, 0x06, 0x05, 0x5f, 0x16, 0x00, 0x40, 0xff, 0x0f, 0x66, 0x00, 0xfd, 0xbf, + 0x08, 0x80, 0xf6, 0xbd, 0x32, 0xa7, 0xef, 0x0e, 0x28, 0x13, 0xc6, 0xb0, 0x61, 0x3e, 0x3a, 0x4c, + 0x62, 0x7f, 0xf6, 0x2f, 0xf2, 0xa6, 0x52, 0x51, 0xf8, 0xe0, 0xee, 0xc8, 0x6a, 0x8e, 0x96, 0x9b, + 0x00, 0xc5, 0x2c, 0xbd, 0x8e, 0x5d, 0x59, 0xdb, 0xe7, 0x12, 0x90, 0x1c, 0x35, 0x0f, 0x87, 0xde, + 0x3f, 0x87, 0x94, 0x00, 0x72, 0xf3, 0xf0, 0x4c, 0xa8, 0xdb, 0xe1, 0x5f, 0xb6, 0x51, 0x23, 0xa6, + 0x36, 0x4c, 0x64, 0xc1, 0xcc, 0x16, 0x0a, 0x60, 0x1e, 0xaf, 0xeb, 0x02, 0xdb, 0xf4, 0xab, 0x2b, + 0xe5, 0x40, 0x61, 0x84, 0x4e, 0x31, 0x6c, 0x3c, 0x73, 0x81, 0xc5, 0x01, 0x5d, 0x17, 0x5e, 0x0b, + 0x71, 0x89, 0x74, 0x18, 0x0c, 0xe4, 0x87, 0xff, 0x12, 0x19, 0x19, 0xc3, 0xd9, 0xc6, 0x0b, 0xb5, + 0xfa, 0x58, 0x72, 0x7f, 0x9e, 0x71, 0x20, 0x6e, 0xc8, 0x87, 0xb6, 0xfc, 0xdc, 0x7c, 0x0a, 0x21, + 0x29, 0xc0, 0xf2, 0xd7, 0x89, 0x85, 0x22, 0x83, 0x72, 0xdb, 0xe5, 0xe9, 0x25, 0xa6, 0xb1, 0x58, + 0xad, 0xef, 0xc4, 0x86, 0x06, 0xcf, 0x71, 0x44, 0x8d, 0x6f, 0xc1, 0x6e, 0x82, 0xda, 0xd7, 0x0c, + 0xc4, 0x8e, 0x4f, 0x15, 0x82, 0x83, 0xfe, 0xe4, 0x82, 0x40, 0x06, 0x20, 0xfa, 0x70, 0x76, 0xf4, + 0x12, 0x96, 0xd3, 0x06, 0x0d, 0xb9, 0x7f, 0xf8, 0x6e, 0x2f, 0xdb, 0x5c, 0x7a, 0x86, 0x07, 0xe1, + 0x9d, 0xf0, 0xb0, 0x01, 0xb8, 0xf7, 0x7e, 0x48, 0x91, 0x21, 0x43, 0xab, 0x6c, 0x67, 0xe9, 0xb7, + 0xb6, 0xc7, 0x69, 0x9b, 0x53, 0x09, 0x89, 0xa5, 0x26, 0x80, 0x11, 0xfe, 0x3e, 0x1b, 0x70, 0x01, + 0xa2, 0x1f, 0xc8, 0xed, 0x82, 0xe7, 0xdf, 0xf7, 0x0a, 0xf4, 0x24, 0x4f, 0xf8, 0xc3, 0x55, 0x95, + 0x8a, 0xba, 0xce, 0x15, 0x6a, 0xf1, 0x8a, 0xb4, 0x6a, 0xcb, 0x58, 0x07, 0xeb, 0x3d, 0x7f, 0xc6, + 0xde, 0x43, 0xc6, 0x2c, 0x9d, 0x8a, 0x99, 0x1a, 0xab, 0xc8, 0xf3, 0x0d, 0xa8, 0xfe, 0xe5, 0xcb, + 0xb8, 0xa9, 0xa6, 0xff, 0xf7, 0x49, 0x2b, 0x87, 0xf9, 0xb4, 0x72, 0xe7, 0x84, 0x6a, 0xa8, 0xc6, + 0xd5, 0xac, 0x37, 0x7b, 0x77, 0xf2, 0xc4, 0x2c, 0x0f, 0x8c, 0x28, 0xa2, 0xf0, 0x86, 0xb7, 0xd2, + 0x77, 0x29, 0xcd, 0xf1, 0x24, 0x55, 0x52, 0x76, 0x4c, 0x3b, 0xf8, 0x8e, 0xab, 0xaa, 0x9a, 0x24, + 0x22, 0x14, 0xad, 0x30, 0x1a, 0xc6, 0x3c, 0x75, 0xe6, 0x2f, 0x0a, 0xff, 0xfd, 0x5a, 0x01, 0x09, + 0x85, 0x30, 0x53, 0xd7, 0x38, 0xae, 0x07, 0xc2, 0x29, 0x74, 0xdf, 0x4e, 0x74, 0x30, 0x6c, 0xc3, + 0x11, 0x69, 0xc2, 0x00, 0xae, 0xe2, 0x9e, 0x13, 0x9b, 0xc7, 0x65, 0x16, 0xc7, 0xcd, 0x8b, 0x80, + 0xb3, 0x1a, 0xc2, 0x76, 0xcf, 0x62, 0x1c, 0x7f, 0x07, 0x01, 0x42, 0x4c, 0x81, 0x12, 0x42, 0x5e, + 0x7e, 0x91, 0x0b, 0x78, 0xe1, 0x94, 0x22, 0xc0, 0x1f, 0xd1, 0x8b, 0x68, 0xb0, 0x62, 0x4f, 0x2d, + 0x97, 0xa4, 0x2a, 0x67, 0xc0, 0xff, 0xd8, 0xb6, 0xe1, 0x90, 0x2c, 0x05, 0x21, 0x7a, 0x79, 0xbb, + 0xbe, 0x27, 0x8e, 0x50, 0xb9, 0xed, 0x74, 0x66, 0x94, 0x8c, 0xd4, 0xe9, 0x14, 0x47, 0xcb, 0x6f, + 0x86, 0xa6, 0x78, 0x61, 0xd6, 0xb1, 0xb9, 0x17, 0x40, 0x0e, 0xaf, 0x40, 0x10, 0x2c, 0xec, 0xc8, + 0x8a, 0xa1, 0xc5, 0x00, 0x0e, 0xd5, 0xd9, 0x46, 0x28, 0x3f, 0x7f, 0x7f, 0x10, 0xd0, 0x5d, 0xf4, + 0x55, 0xc9, 0xa6, 0x5a, 0xc4, 0xa6, 0x6f, 0xb0, 0x77, 0xeb, 0x59, 0xe0, 0xe8, 0x55, 0x49, 0x78, + 0xe9, 0xef, 0x4a, 0x4a, 0xf8, 0x7f, 0x83, 0x49, 0xf8, 0xc9, 0xd4, 0xb0, 0x00, 0x3b, 0x1c, 0x40, + 0x7c, 0xe0, 0x00, 0x3f, 0x85, 0x04, 0x01, 0xa8, 0x74, 0xac, 0xd8, 0x75, 0x67, 0x09, 0x34, 0x20, + 0xc0, 0x60, 0x9f, 0x6f, 0x62, 0x4f, 0xf0, 0xb9, 0xd5, 0x60, 0x3c, 0x6a, 0x6e, 0x50, 0xd4, 0x15, + 0x19, 0x25, 0x1c, 0x2f, 0xc0, 0x95, 0x1b, 0xc4, 0x0c, 0x3e, 0x1c, 0x46, 0x00, 0x0b, 0xd4, 0x81, + 0xa4, 0xf7, 0x08, 0x55, 0xa3, 0xdf, 0xdd, 0x6d, 0xbe, 0x0d, 0xde, 0x38, 0xea, 0x0d, 0x08, 0x1a, + 0x3d, 0x8b, 0x90, 0x28, 0xef, 0x08, 0xc5, 0xb8, 0xc4, 0x49, 0x08, 0xa4, 0x5d, 0x6e, 0xbb, 0x7e, + 0x1d, 0xc0, 0x0e, 0x84, 0xb1, 0xc3, 0x17, 0x93, 0xf1, 0xa2, 0x5c, 0xfd, 0xfd, 0xdb, 0x6f, 0x59, + 0xcd, 0x95, 0x07, 0x18, 0x32, 0x00, 0x2b, 0x82, 0x1c, 0x12, 0xe0, 0x2c, 0xc3, 0xf1, 0x7c, 0x88, + 0x9a, 0xf0, 0x57, 0x8e, 0x7d, 0x07, 0x1b, 0xfe, 0x04, 0x00, 0x42, 0x14, 0x13, 0x1d, 0x4c, 0x84, + 0x70, 0x2b, 0xc8, 0xf7, 0xc9, 0x6c, 0x65, 0xec, 0xb3, 0x5c, 0x3b, 0x09, 0xe0, 0x70, 0x9c, 0xb7, + 0x1a, 0x42, 0xb1, 0xf1, 0x3d, 0xcf, 0xdf, 0x96, 0x9c, 0x40, 0x28, 0xea, 0x56, 0xd1, 0xc6, 0x9c, + 0x05, 0x4a, 0xe5, 0xdb, 0x6e, 0xb9, 0xae, 0x21, 0xee, 0x58, 0xe1, 0x94, 0x50, 0x04, 0xb2, 0xc7, + 0xaa, 0x07, 0xf7, 0x21, 0x8c, 0x6a, 0x31, 0x96, 0xa0, 0xed, 0xc7, 0x70, 0xb3, 0x52, 0x8d, 0x85, + 0xd8, 0x8e, 0x1b, 0xe1, 0x70, 0xba, 0xf9, 0x48, 0x7f, 0x6e, 0x10, 0xeb, 0x28, 0xce, 0x11, 0x32, + 0x03, 0x36, 0x14, 0xcc, 0x6d, 0x05, 0xea, 0x5d, 0x66, 0x55, 0x8b, 0xe4, 0xb5, 0x58, 0x98, 0x64, + 0x22, 0x34, 0x8c, 0xec, 0xda, 0xae, 0x7b, 0xcb, 0xde, 0xa7, 0xe6, 0x60, 0xb5, 0x93, 0x15, 0xb3, + 0xc0, 0xb1, 0x1b, 0xea, 0xaf, 0xf8, 0x40, 0x48, 0x29, 0x29, 0x3e, 0x15, 0xab, 0x18, 0xd2, 0x0c, + 0x84, 0xd2, 0x6e, 0xc4, 0x78, 0x3c, 0xb6, 0xd8, 0x71, 0x94, 0x00, 0x7c, 0x07, 0x33, 0x1e, 0x30, + 0x7e, 0x70, 0x69, 0x22, 0x6a, 0x6a, 0x65, 0x75, 0x87, 0x47, 0x15, 0xa6, 0x54, 0x4a, 0x74, 0x6c, + 0x13, 0x27, 0xe0, 0x7b, 0x8e, 0xd1, 0x32, 0x0e, 0xe3, 0x94, 0x03, 0xb8, 0xe5, 0x00, 0xe0, 0x4b, + 0x07, 0x0a, 0x8c, 0xa7, 0x8b, 0x6c, 0x91, 0x09, 0xd3, 0x87, 0x11, 0x00, 0x1f, 0x38, 0x12, 0x14, + 0x42, 0xd9, 0x89, 0x30, 0xff, 0x3f, 0x9d, 0xd3, 0xba, 0x5b, 0x91, 0xb2, 0xb9, 0x49, 0x2e, 0xc7, + 0x9c, 0x44, 0x30, 0x92, 0xda, 0xc9, 0x07, 0xac, 0x0a, 0x50, 0x82, 0xb1, 0x47, 0x2f, 0x8a, 0x38, + 0x1d, 0x47, 0xd8, 0x60, 0x20, 0x36, 0x09, 0x83, 0x50, 0x3a, 0xa5, 0x06, 0x8e, 0x95, 0xf1, 0xcb, + 0xf5, 0xf7, 0xc9, 0x4a, 0xc1, 0x6c, 0xb2, 0xf0, 0xe5, 0xb5, 0x91, 0x36, 0x58, 0xc4, 0x61, 0xf9, + 0xae, 0xbc, 0x5d, 0x96, 0xe1, 0x01, 0xa6, 0x20, 0x89, 0x00, 0xc3, 0x08, 0xc5, 0x1d, 0x97, 0x80, + 0xdc, 0xb4, 0xdb, 0x72, 0xe7, 0xc5, 0xbf, 0xbc, 0x17, 0x9e, 0x0d, 0x26, 0xb5, 0x59, 0x8c, 0x53, + 0x51, 0x4d, 0x25, 0xdb, 0xff, 0xe1, 0xe6, 0x60, 0x02, 0xde, 0xf3, 0x21, 0x52, 0xa1, 0xc2, 0x35, + 0xed, 0x37, 0x77, 0x74, 0xe3, 0xe4, 0xa3, 0xb8, 0xcf, 0x66, 0xea, 0x27, 0xdd, 0xc2, 0x91, 0x98, + 0x12, 0xae, 0x20, 0x79, 0x7e, 0x2b, 0x58, 0x71, 0x40, 0x15, 0x0c, 0x51, 0x1b, 0xc5, 0xec, 0xdd, + 0x09, 0x23, 0x45, 0x6b, 0x79, 0x38, 0xc8, 0x28, 0x11, 0x77, 0xe3, 0x07, 0x93, 0x5e, 0x2a, 0x05, + 0xec, 0x11, 0x27, 0x29, 0xee, 0xaa, 0x71, 0xa5, 0x5b, 0x6d, 0xfe, 0x08, 0x04, 0x8d, 0x9a, 0x9e, + 0x13, 0x6c, 0x3c, 0x67, 0xfd, 0x86, 0xa3, 0x54, 0x50, 0x8d, 0xd0, 0xfd, 0x0e, 0x16, 0x36, 0x60, + 0x90, 0x1a, 0x21, 0x05, 0x47, 0xfc, 0xf0, 0x00, 0x7a, 0x41, 0x5b, 0x06, 0x25, 0xe0, 0x4e, 0xe5, + 0x3e, 0xb4, 0x3c, 0xb6, 0x96, 0x25, 0x60, 0x0b, 0x87, 0x03, 0xc3, 0x34, 0x8f, 0x5f, 0xe2, 0x42, + 0x9e, 0xd9, 0x1b, 0x2c, 0xc1, 0x68, 0x9e, 0xae, 0xc7, 0xc0, 0x0e, 0x1e, 0x18, 0x54, 0x28, 0xa3, + 0xb8, 0xcc, 0x87, 0xf1, 0x3a, 0xdd, 0x72, 0xbc, 0x40, 0x52, 0xf1, 0x0d, 0x9b, 0x5f, 0x52, 0xc6, + 0x54, 0x5c, 0x9a, 0xb2, 0x23, 0x06, 0x7f, 0x2f, 0x10, 0x08, 0xf5, 0x1a, 0xca, 0x1f, 0x9f, 0x05, + 0x1e, 0x3c, 0xb8, 0xc0, 0x06, 0x88, 0x30, 0x60, 0x8e, 0xc0, 0xd8, 0x73, 0x84, 0x00, 0xc2, 0x36, + 0xe9, 0xd3, 0x6e, 0x25, 0xee, 0x5b, 0x39, 0xb3, 0x74, 0x48, 0x26, 0x1c, 0x05, 0x28, 0x38, 0x0f, + 0xca, 0x6f, 0x25, 0x26, 0x3b, 0x49, 0x80, 0xf3, 0x42, 0x02, 0xc8, 0x41, 0x4b, 0x07, 0x1f, 0x85, + 0xfe, 0xf8, 0x70, 0x90, 0x02, 0xdc, 0xc2, 0x99, 0xdd, 0x20, 0x9b, 0xf1, 0xb6, 0xf6, 0xd9, 0x13, + 0xc6, 0xfc, 0x1f, 0x96, 0xcf, 0xe2, 0xa0, 0x19, 0xc5, 0x57, 0x2c, 0x5d, 0xa8, 0x3c, 0x00, 0x3a, + 0x38, 0x00, 0x10, 0x9c, 0xf1, 0x8a, 0x16, 0xd3, 0xa9, 0xaf, 0x86, 0xf0, 0x01, 0x42, 0xaa, 0xb4, + 0x97, 0x02, 0xe1, 0x04, 0x5c, 0xd0, 0xb5, 0x74, 0x62, 0xb2, 0xa0, 0x00, 0xe3, 0x05, 0x60, 0x79, + 0x94, 0x00, 0x0e, 0x90, 0xe0, 0x00, 0x99, 0x0c, 0x51, 0xeb, 0xac, 0x03, 0xfc, 0x8c, 0xa4, 0x2e, + 0x25, 0xd0, 0x76, 0xfb, 0x6d, 0x84, 0x39, 0x4e, 0xf6, 0xfe, 0xb0, 0x42, 0x1c, 0xa4, 0x55, 0xfc, + 0xc4, 0x55, 0xfc, 0xa7, 0x5a, 0xdc, 0x32, 0x24, 0x69, 0x81, 0xdb, 0xd8, 0x97, 0xab, 0xa5, 0x1f, + 0x3f, 0x0a, 0xb5, 0x16, 0xbc, 0xdc, 0x76, 0xa7, 0xf1, 0x5b, 0x48, 0x4a, 0x23, 0x46, 0x3f, 0x16, + 0x32, 0xc2, 0xde, 0x08, 0x64, 0xd6, 0xb8, 0x81, 0x01, 0x42, 0xad, 0x26, 0x42, 0x3b, 0x6b, 0x72, + 0x55, 0xb6, 0x76, 0xa9, 0x60, 0x33, 0x81, 0xe7, 0x00, 0xf5, 0x2a, 0x35, 0x28, 0xeb, 0x09, 0x1a, + 0x1c, 0x0f, 0x3e, 0xd1, 0x0e, 0x0c, 0xf8, 0xd8, 0x44, 0x02, 0x44, 0x8a, 0x04, 0x43, 0x1e, 0x05, + 0x9d, 0x10, 0x46, 0xd4, 0x40, 0xb9, 0x49, 0x27, 0x87, 0x96, 0xdb, 0xed, 0x5a, 0xed, 0x6f, 0x53, + 0x90, 0xdc, 0xfe, 0x15, 0xe3, 0xfc, 0x48, 0x56, 0x78, 0x07, 0x92, 0x34, 0x1b, 0x64, 0xa7, 0x1f, + 0x46, 0x3d, 0x8e, 0x03, 0xa1, 0x02, 0xae, 0xbe, 0x0a, 0xb7, 0xae, 0x08, 0xfd, 0x62, 0x41, 0x04, + 0x14, 0x57, 0x07, 0x14, 0x95, 0x5d, 0x66, 0x24, 0xb3, 0x54, 0xe3, 0x75, 0x4f, 0xb6, 0x12, 0x4c, + 0x82, 0x53, 0x47, 0xa3, 0x2b, 0x1c, 0x30, 0x7a, 0x37, 0xf8, 0x08, 0x00, 0x50, 0x34, 0x83, 0x82, + 0x1f, 0x08, 0xe0, 0xb3, 0xcc, 0xf8, 0x0f, 0x2d, 0x5f, 0xac, 0x39, 0xe2, 0x60, 0xae, 0xbc, 0x0c, + 0x45, 0x71, 0x05, 0x40, 0xaa, 0xe4, 0x0c, 0xd0, 0x00, 0x78, 0xcf, 0x80, 0x01, 0x75, 0x08, 0x36, + 0x09, 0x54, 0x60, 0x09, 0x08, 0x75, 0x80, 0x39, 0x92, 0x80, 0x3d, 0x68, 0x91, 0xd6, 0x3b, 0xfb, + 0x7f, 0xe1, 0x49, 0x44, 0x06, 0x41, 0x2c, 0x1f, 0xc8, 0x42, 0x60, 0xe9, 0x3e, 0xa9, 0x26, 0x2a, + 0x9f, 0x82, 0x38, 0x4c, 0x01, 0xed, 0x31, 0x57, 0x4a, 0x52, 0x92, 0x01, 0x5f, 0x70, 0xb6, 0x17, + 0xc3, 0x36, 0x85, 0xb3, 0xf8, 0xb0, 0x71, 0x17, 0xa8, 0x5e, 0x70, 0x27, 0xd3, 0x5b, 0x67, 0x2d, + 0x93, 0xb6, 0xd3, 0x57, 0x53, 0xda, 0xfe, 0x6f, 0x0f, 0xbb, 0x37, 0x52, 0xb2, 0xfe, 0xcc, 0x93, + 0xfc, 0xbc, 0xe9, 0xe2, 0x46, 0x63, 0xa9, 0xb1, 0xcf, 0x9c, 0xbd, 0x76, 0x84, 0xc0, 0x54, 0xb1, + 0x44, 0xbd, 0x0b, 0xc1, 0xdb, 0x1f, 0xc3, 0xfc, 0xe1, 0x17, 0x2d, 0xfe, 0x22, 0x14, 0xb7, 0x4b, + 0xa2, 0x46, 0xa1, 0x86, 0xe1, 0x56, 0x92, 0xd5, 0xfa, 0xb5, 0xc4, 0x6b, 0x73, 0x62, 0xf0, 0x80, + 0x50, 0xd1, 0x12, 0x14, 0x26, 0xf6, 0x90, 0x70, 0x33, 0xcc, 0xaf, 0xe5, 0xfd, 0xdd, 0x24, 0xa2, + 0x8e, 0x2e, 0x24, 0x40, 0x52, 0x7a, 0x8f, 0xf0, 0x7a, 0xc0, 0xf9, 0xa8, 0xf0, 0xb0, 0xb2, 0x05, + 0x84, 0x80, 0xfa, 0x22, 0xc1, 0x9e, 0x03, 0x82, 0xab, 0x3c, 0x1c, 0x2d, 0x94, 0x82, 0x88, 0x19, + 0x6c, 0xb8, 0x31, 0x85, 0x0a, 0x48, 0x1d, 0x94, 0x97, 0x85, 0xd6, 0x3e, 0x26, 0x61, 0x49, 0xad, + 0x9c, 0x0f, 0x7e, 0xf0, 0x18, 0xd3, 0x43, 0x42, 0xa3, 0x54, 0x8f, 0x98, 0x9d, 0xc4, 0x6d, 0x71, + 0x21, 0xd9, 0xc0, 0x03, 0x85, 0x8c, 0x38, 0xb3, 0x55, 0xd9, 0x3e, 0x21, 0xe8, 0x4b, 0xfa, 0x67, + 0x70, 0xa1, 0x21, 0x00, 0xd8, 0x81, 0x7c, 0x32, 0x86, 0xef, 0xf0, 0x97, 0x35, 0x57, 0x0a, 0x41, + 0x04, 0x9d, 0x6c, 0x9f, 0x12, 0x11, 0x11, 0x6d, 0x03, 0x0a, 0x65, 0x5e, 0x4f, 0x60, 0x57, 0xbe, + 0x24, 0x32, 0x14, 0xb6, 0x35, 0xa5, 0x1b, 0x3b, 0x8c, 0x81, 0x56, 0x52, 0xcc, 0xf3, 0xee, 0xa6, + 0xc0, 0x3f, 0x35, 0x48, 0x15, 0x07, 0x6c, 0x79, 0x32, 0x02, 0x4c, 0x48, 0xc2, 0x78, 0x97, 0x6a, + 0xa2, 0xe4, 0x83, 0xa0, 0x15, 0x9c, 0x20, 0x55, 0x93, 0xcc, 0x63, 0x83, 0x10, 0x88, 0xc9, 0x54, + 0x2c, 0x14, 0x32, 0x96, 0x19, 0x43, 0xa9, 0xe0, 0x03, 0x7c, 0x01, 0xe7, 0x83, 0x87, 0xb8, 0x54, + 0xc4, 0x23, 0xd6, 0x0e, 0x79, 0x60, 0xdb, 0x99, 0x6f, 0x84, 0x44, 0x85, 0x0e, 0x78, 0x0c, 0xf0, + 0x70, 0xb1, 0x96, 0xca, 0xa3, 0xc3, 0xfa, 0x70, 0x54, 0x4f, 0xe8, 0xec, 0x8f, 0xf7, 0xb0, 0x27, + 0xae, 0x11, 0x0c, 0x8e, 0xa0, 0x0a, 0x8d, 0xf9, 0x2c, 0xd8, 0x5d, 0x58, 0xfb, 0x43, 0x01, 0xdc, + 0xa5, 0x71, 0x21, 0x91, 0xfc, 0xf9, 0x92, 0x0d, 0x0b, 0x75, 0x0a, 0xc7, 0x4d, 0x7f, 0xc2, 0x22, + 0x77, 0x77, 0xcc, 0xc7, 0x12, 0x11, 0x27, 0x6d, 0x71, 0x01, 0x01, 0x90, 0xb3, 0x92, 0xb5, 0x18, + 0xaf, 0x9d, 0xb9, 0x62, 0xb2, 0xc6, 0x2b, 0x65, 0xa8, 0xe3, 0x76, 0x76, 0xa8, 0x2c, 0x76, 0x15, + 0x57, 0x89, 0x0e, 0x90, 0x46, 0x8a, 0x1a, 0xa6, 0xba, 0x24, 0xa9, 0xee, 0x1e, 0xe6, 0x5d, 0xfb, + 0x6c, 0x07, 0x51, 0x68, 0x9b, 0xff, 0x9c, 0x49, 0x28, 0x8e, 0xff, 0x05, 0x3c, 0x84, 0x80, 0xe8, + 0x94, 0xdd, 0xfd, 0xc5, 0x09, 0x2c, 0xfa, 0xc4, 0x82, 0xa2, 0x53, 0x52, 0x6b, 0x64, 0x45, 0xb9, + 0x9f, 0x53, 0x62, 0x7f, 0x2e, 0x11, 0x08, 0x0c, 0x38, 0x3e, 0x46, 0xb0, 0xb6, 0x9d, 0xa3, 0x97, + 0x67, 0xe4, 0xd5, 0x67, 0x2c, 0x0c, 0xd6, 0xa3, 0x4d, 0x55, 0xa5, 0xc4, 0x82, 0xa2, 0x37, 0xbe, + 0x9f, 0x51, 0x8c, 0x1f, 0xcd, 0x6a, 0xff, 0x08, 0xd2, 0xd4, 0x46, 0x19, 0x50, 0x83, 0xa5, 0x56, + 0x32, 0xb8, 0x98, 0x52, 0x95, 0xaa, 0x26, 0xdb, 0xba, 0x25, 0x42, 0x44, 0x8a, 0xd5, 0x69, 0x57, + 0x2f, 0xed, 0xf8, 0x91, 0x01, 0x4d, 0xee, 0xef, 0x73, 0x86, 0x02, 0x5b, 0xae, 0x21, 0xc6, 0xe0, + 0xa3, 0x38, 0x71, 0xf8, 0x91, 0x03, 0x0b, 0x54, 0x94, 0xda, 0x5c, 0xb7, 0xbc, 0x56, 0xe2, 0xbc, + 0x4c, 0x21, 0x1a, 0xcf, 0xe7, 0xa3, 0x96, 0xc2, 0xe2, 0xb0, 0x48, 0xf6, 0x0a, 0x3f, 0xaf, 0x87, + 0xbc, 0x29, 0x55, 0x08, 0x07, 0xb1, 0xf7, 0x2f, 0xc8, 0xd7, 0x7b, 0xe9, 0xdb, 0xb6, 0xfe, 0x20, + 0x20, 0x22, 0x2e, 0xc1, 0xea, 0x2e, 0xa9, 0xd3, 0x85, 0x79, 0xaf, 0x79, 0x39, 0x37, 0xb8, 0x53, + 0x8a, 0x8a, 0x65, 0xe2, 0xe2, 0x0f, 0x53, 0xce, 0x24, 0x5f, 0x88, 0x08, 0x8c, 0x12, 0x28, 0x67, + 0xf0, 0xeb, 0x12, 0x30, 0xc7, 0x8c, 0x56, 0xda, 0x3b, 0xcf, 0x62, 0x05, 0x88, 0x81, 0x63, 0x12, + 0x10, 0x19, 0x74, 0xb6, 0xc5, 0xc5, 0xc2, 0xa1, 0xa5, 0xc1, 0xdf, 0xb7, 0xa9, 0xe7, 0xeb, 0x89, + 0x8c, 0x30, 0xa1, 0x8b, 0xcc, 0x7e, 0xab, 0xcb, 0xe5, 0x31, 0x18, 0x48, 0xfd, 0x1d, 0x15, 0x28, + 0x88, 0x41, 0xa5, 0x84, 0x61, 0x4a, 0xd1, 0x84, 0xf0, 0xe1, 0xc0, 0xb0, 0x78, 0xc0, 0xc2, 0x19, + 0x85, 0x80, 0x0d, 0xd0, 0xf8, 0xe1, 0xc7, 0xe2, 0x21, 0xe7, 0x5a, 0xdf, 0x96, 0x9e, 0x0e, 0xbc, + 0xd2, 0xd2, 0xfc, 0x29, 0x0a, 0x03, 0xe1, 0xe7, 0x4d, 0x22, 0x61, 0xe3, 0x98, 0x16, 0xeb, 0x69, + 0xa5, 0xb4, 0x2e, 0xf4, 0xfc, 0x48, 0x81, 0x67, 0xb2, 0x32, 0x8d, 0x75, 0xe1, 0x01, 0xe4, 0x1c, + 0xa8, 0xe7, 0x1c, 0xd5, 0x7a, 0x15, 0xbf, 0x3e, 0xd1, 0xf6, 0x55, 0xfd, 0xdd, 0xae, 0x20, 0x29, + 0x59, 0xe5, 0xff, 0x27, 0x6d, 0xed, 0xee, 0xa1, 0x72, 0xd5, 0xbb, 0xbf, 0x78, 0x40, 0x23, 0x0b, + 0x55, 0xda, 0xcc, 0x3f, 0x47, 0xbb, 0x74, 0x31, 0x3c, 0xc3, 0x5c, 0xb7, 0x77, 0x70, 0xa4, 0x40, + 0x81, 0xf4, 0x10, 0xbd, 0x54, 0x91, 0xa0, 0xd2, 0xb7, 0xdd, 0x15, 0x9f, 0x12, 0x14, 0x28, 0xb2, + 0x7c, 0xde, 0x58, 0xeb, 0x10, 0xe3, 0xc3, 0x02, 0xed, 0x56, 0xad, 0x38, 0x70, 0x63, 0x8b, 0x67, + 0x26, 0x15, 0x6e, 0x1c, 0xe3, 0xf0, 0x60, 0x0c, 0x06, 0x4f, 0x39, 0x1a, 0xc9, 0x5a, 0x31, 0x53, + 0x05, 0x56, 0x70, 0xc1, 0xef, 0x6d, 0xbc, 0x3f, 0xd7, 0xc3, 0x67, 0xb0, 0x88, 0x40, 0x22, 0x69, + 0xa9, 0xde, 0x3d, 0xef, 0x84, 0x44, 0x0f, 0x92, 0x56, 0x65, 0xd5, 0xac, 0x4b, 0xc2, 0x8a, 0x9f, + 0x0e, 0x07, 0xf8, 0x50, 0xa3, 0x74, 0xa6, 0x5b, 0x0a, 0xab, 0x49, 0xb8, 0xbd, 0x47, 0x87, 0x85, + 0x80, 0xc9, 0x00, 0x1c, 0x8e, 0x00, 0x68, 0x58, 0xf2, 0x70, 0x14, 0x0f, 0x67, 0x22, 0x75, 0x89, + 0x82, 0xb8, 0xbf, 0xb6, 0xaa, 0xda, 0x49, 0x6d, 0x56, 0x1f, 0xb5, 0x2d, 0xf7, 0x08, 0x88, 0x09, + 0xc1, 0xa6, 0x5d, 0x46, 0x7a, 0xe7, 0xfc, 0x22, 0x3b, 0x1f, 0x5c, 0xf9, 0x58, 0xc7, 0xaa, 0xc1, + 0x84, 0x22, 0x24, 0x61, 0x25, 0x8e, 0x0e, 0xda, 0xf1, 0x16, 0x31, 0x58, 0x31, 0x78, 0x24, 0xca, + 0x82, 0x4a, 0xe0, 0x17, 0x45, 0x93, 0x12, 0x0f, 0x60, 0x87, 0x2d, 0xf0, 0xc0, 0x50, 0x84, 0xc0, + 0x7f, 0x83, 0x38, 0xf8, 0x9d, 0x50, 0x75, 0x71, 0x83, 0x02, 0xe8, 0x32, 0x95, 0xe7, 0x62, 0xab, + 0x97, 0x4e, 0x06, 0x31, 0x12, 0xb7, 0x91, 0x48, 0xee, 0x83, 0xd7, 0x77, 0x86, 0x02, 0x9a, 0xa7, + 0x78, 0x69, 0x58, 0x69, 0x0f, 0xa1, 0xb4, 0x5f, 0x1d, 0x69, 0x86, 0x55, 0x0e, 0xc0, 0x79, 0xb0, + 0x5f, 0x5e, 0x20, 0x28, 0x51, 0xc5, 0xe1, 0x28, 0xf8, 0xba, 0x88, 0xaa, 0x6c, 0x87, 0x47, 0x9a, + 0x1d, 0x8a, 0x38, 0x87, 0x8a, 0x30, 0x76, 0xe5, 0xb7, 0x74, 0x8b, 0x10, 0x20, 0x28, 0x48, 0x99, + 0x8f, 0x7a, 0xb8, 0x87, 0x2a, 0x36, 0x97, 0xa8, 0x62, 0xd8, 0x16, 0xcb, 0x5a, 0x6e, 0x7c, 0x67, + 0x2e, 0x08, 0xa4, 0x7a, 0xa1, 0x8f, 0x29, 0x60, 0xeb, 0x3e, 0x16, 0xdb, 0x2f, 0x64, 0x6f, 0xc4, + 0x8c, 0x3c, 0xa9, 0xfc, 0xdb, 0x24, 0x6d, 0x1d, 0xed, 0x33, 0x92, 0xf0, 0x7f, 0xbf, 0xb6, 0x18, + 0xe4, 0xaa, 0xfe, 0x13, 0x25, 0x6a, 0x4f, 0x58, 0x62, 0x08, 0x02, 0x22, 0x0a, 0x21, 0x63, 0x15, + 0xca, 0x27, 0x51, 0xf6, 0x3e, 0x10, 0x12, 0x30, 0xaa, 0x74, 0xe9, 0x41, 0x85, 0x29, 0x6f, 0x2b, + 0x55, 0x56, 0xbd, 0x70, 0x40, 0x10, 0x1b, 0x6e, 0xbc, 0x7f, 0x31, 0xc3, 0x33, 0xd4, 0xaf, 0xc4, + 0x3d, 0x00, 0xed, 0xce, 0xff, 0xc8, 0xa1, 0xa9, 0x45, 0x17, 0x71, 0x77, 0xff, 0x0a, 0x18, 0xf3, + 0xea, 0x63, 0x07, 0x96, 0x10, 0xd3, 0x71, 0x8a, 0xca, 0x62, 0xf1, 0xea, 0x4c, 0xc8, 0xa7, 0x97, + 0x89, 0x19, 0x26, 0x6a, 0x3d, 0x50, 0x4a, 0x9a, 0xa1, 0xc4, 0x99, 0xeb, 0x94, 0xe9, 0x0e, 0x7c, + 0x4d, 0x7a, 0x92, 0xab, 0x25, 0xa8, 0xdf, 0xc4, 0xe3, 0x27, 0xdc, 0x7a, 0x32, 0x7e, 0x61, 0x9e, + 0x6d, 0x6b, 0xe5, 0x17, 0x93, 0xc2, 0x9d, 0x9b, 0x77, 0x2e, 0x08, 0x41, 0x11, 0x45, 0xeb, 0xee, + 0x20, 0x23, 0x5d, 0x91, 0x22, 0x66, 0x01, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x44, + 0x22, 0x32, 0x8d, 0xd8, 0x8b, 0xdc, 0x4f, 0x31, 0xdd, 0xdd, 0xfc, 0x15, 0xf7, 0x10, 0x38, 0xe7, + 0x3e, 0xe2, 0x5f, 0x3d, 0xcb, 0xc1, 0x47, 0x26, 0xf2, 0xf7, 0xc8, 0x5a, 0xd7, 0xc4, 0x19, 0x6b, + 0x15, 0xde, 0x5e, 0x62, 0xde, 0x2b, 0xc4, 0xc2, 0x06, 0x75, 0xe4, 0x62, 0xb1, 0x94, 0xc3, 0x7e, + 0x26, 0x3b, 0xba, 0xb6, 0x9e, 0x5b, 0x9b, 0x78, 0x98, 0x42, 0xfb, 0x46, 0x85, 0xe9, 0xbb, 0xbe, + 0x26, 0x28, 0xf7, 0x76, 0xaa, 0xfe, 0x24, 0x49, 0x5a, 0x61, 0x13, 0xf1, 0x9a, 0x84, 0xf8, 0x31, + 0x89, 0x10, 0xc5, 0x6e, 0x5c, 0xf0, 0x4c, 0x52, 0x72, 0x6d, 0x15, 0xc9, 0x16, 0x6b, 0xd5, 0xca, + 0x47, 0xbb, 0xa8, 0x98, 0x48, 0xb5, 0xaa, 0xaa, 0xae, 0x26, 0x20, 0x85, 0xff, 0x6e, 0x7f, 0xe1, + 0x0a, 0xeb, 0x97, 0x1c, 0x51, 0x8a, 0xde, 0x5c, 0xe2, 0x65, 0x17, 0xaa, 0x82, 0x4e, 0x51, 0xdb, + 0xb9, 0x79, 0x84, 0xbb, 0xbd, 0xf6, 0x75, 0x5d, 0x62, 0x3e, 0xcc, 0xb6, 0xeb, 0x8b, 0xb9, 0xe1, + 0x77, 0x7d, 0xf3, 0x0b, 0x4b, 0x26, 0x78, 0xa0, 0x83, 0x3b, 0xbb, 0xdd, 0xd7, 0x28, 0xfc, 0x3a, + 0x8b, 0x81, 0xd4, 0x4e, 0x0a, 0xa2, 0x44, 0x71, 0x11, 0xc2, 0x04, 0xb8, 0x7c, 0x7d, 0xb5, 0xab, + 0xbf, 0xe1, 0x22, 0xbb, 0xde, 0xb5, 0xf0, 0x89, 0x2f, 0x6a, 0xf3, 0x6d, 0x0d, 0x0d, 0xb5, 0xc9, + 0x3e, 0x57, 0x89, 0xd7, 0x37, 0x77, 0x51, 0x30, 0x88, 0x8c, 0xa4, 0x11, 0x46, 0xef, 0xbe, 0xef, + 0xf1, 0xf2, 0xe0, 0xad, 0xfe, 0xdc, 0xd0, 0xaf, 0x36, 0x71, 0x0c, 0xeb, 0x59, 0xa0, 0x80, 0x10, + 0x82, 0xbf, 0x36, 0x56, 0xa4, 0xcc, 0xdf, 0x82, 0x80, 0xc9, 0x47, 0xd5, 0x54, 0x12, 0x44, 0x88, + 0x08, 0x0c, 0x58, 0xba, 0xa4, 0xc2, 0x88, 0xa4, 0xd2, 0x35, 0x3c, 0xc5, 0x6e, 0xef, 0xe1, 0x4d, + 0x8c, 0xec, 0xd0, 0xcf, 0xdc, 0x69, 0xff, 0x76, 0x33, 0xc2, 0xab, 0x19, 0x11, 0x02, 0x56, 0x0b, + 0x6f, 0xf0, 0x49, 0xad, 0x5f, 0x88, 0x8b, 0x11, 0x2f, 0x4f, 0x3c, 0x76, 0xf1, 0x11, 0xd2, 0x41, + 0x55, 0x45, 0xc4, 0x78, 0x9a, 0x45, 0xc6, 0x2b, 0x4f, 0xc5, 0xe4, 0x84, 0xdc, 0x6d, 0x77, 0xe7, + 0xcd, 0xc4, 0x9c, 0x6b, 0xc5, 0x97, 0x89, 0xe6, 0xab, 0xe4, 0xde, 0xfc, 0x40, 0x48, 0x43, 0xb3, + 0x7b, 0x88, 0x1c, 0xbf, 0x61, 0x51, 0xf5, 0xf9, 0xb0, 0x88, 0x26, 0x09, 0x6a, 0x4e, 0x6f, 0x99, + 0x8f, 0x78, 0x44, 0x49, 0xf1, 0x9c, 0xb6, 0xa4, 0xa2, 0x86, 0x3a, 0x0b, 0xd4, 0xdc, 0xa1, 0xc7, + 0xbc, 0xdc, 0x14, 0x9c, 0x7d, 0x59, 0x43, 0xd8, 0x33, 0x35, 0x66, 0x68, 0x35, 0x88, 0xe2, 0x96, + 0xe2, 0x3c, 0x44, 0x45, 0xdd, 0xce, 0xc5, 0xbe, 0xef, 0x84, 0x08, 0x2f, 0x4c, 0xcc, 0x0f, 0xe7, + 0x33, 0xa6, 0xb5, 0x11, 0x26, 0x4c, 0xfe, 0xb1, 0x33, 0x41, 0x00, 0x31, 0xf1, 0x22, 0xaa, 0xbe, + 0x7f, 0xf2, 0xcb, 0xe5, 0x63, 0xe5, 0x1a, 0x9c, 0xaf, 0xe2, 0x01, 0x4f, 0x12, 0x19, 0x1a, 0x30, + 0xd0, 0x14, 0x2a, 0x07, 0x63, 0x51, 0xac, 0x26, 0x00, 0xfc, 0x4c, 0x0e, 0x45, 0xc0, 0xf3, 0x59, + 0xb1, 0xd8, 0x51, 0xb3, 0x1d, 0x78, 0x3f, 0xb5, 0x7f, 0xa2, 0xd5, 0xf2, 0xf4, 0xd9, 0xfc, 0x17, + 0xf6, 0x9a, 0x03, 0xf6, 0xb9, 0x50, 0x05, 0x33, 0x4e, 0x3c, 0x81, 0xad, 0xfe, 0x32, 0xbf, 0x9e, + 0xbf, 0x8a, 0xe1, 0xbe, 0x6b, 0xbe, 0x4e, 0x3c, 0xfc, 0x1e, 0xb1, 0x20, 0xe6, 0xa0, 0x16, 0x78, + 0xb1, 0xbc, 0xa4, 0xbc, 0x5a, 0x2e, 0xe2, 0x62, 0x09, 0x29, 0xee, 0xfb, 0xf8, 0xbd, 0x65, 0x67, + 0x36, 0x7c, 0x11, 0x12, 0xb4, 0x4f, 0xf1, 0xfc, 0xfb, 0x55, 0xeb, 0x5f, 0x21, 0x4d, 0x8a, 0x92, + 0xf8, 0x9e, 0x4f, 0x17, 0x55, 0x92, 0x22, 0x26, 0x9d, 0x39, 0x83, 0x67, 0x64, 0x81, 0x00, 0xf8, + 0x28, 0x0c, 0xa2, 0xf6, 0x1c, 0x7f, 0xfe, 0x63, 0x43, 0xb2, 0xf5, 0xb2, 0xca, 0xf9, 0x65, 0x11, + 0x61, 0xc4, 0x35, 0xc4, 0x3a, 0x39, 0xd8, 0x60, 0x48, 0x63, 0xbb, 0x3c, 0x8b, 0xe4, 0xab, 0x14, + 0x5f, 0x3c, 0xed, 0x44, 0x09, 0x0f, 0x9b, 0x77, 0xe1, 0xc0, 0x1d, 0x2a, 0x03, 0xc7, 0x96, 0x39, + 0x6e, 0x0d, 0xdd, 0xe2, 0x1a, 0xf8, 0x80, 0x50, 0x48, 0x9f, 0xbc, 0x53, 0x17, 0x26, 0x47, 0x2f, + 0x12, 0x0a, 0x8a, 0xe2, 0xb7, 0x12, 0xe1, 0xee, 0x0a, 0xed, 0xa5, 0x5a, 0xc4, 0xeb, 0x10, 0x24, + 0x17, 0x10, 0x7f, 0xcf, 0xf5, 0x16, 0xc5, 0x1b, 0x18, 0x5d, 0x50, 0x0c, 0x80, 0x83, 0x86, 0x21, + 0x88, 0xa3, 0x78, 0xf7, 0x58, 0x9a, 0x2b, 0x1b, 0x93, 0xff, 0x0c, 0x55, 0x8e, 0x08, 0x02, 0x23, + 0x65, 0xc5, 0x3e, 0xec, 0xb1, 0x9e, 0x19, 0xa0, 0x34, 0xde, 0x10, 0xb9, 0x54, 0x71, 0x0d, 0x60, + 0x43, 0xc8, 0xa4, 0x81, 0xc9, 0x94, 0x03, 0x0e, 0x42, 0x9d, 0x9b, 0x85, 0x9d, 0x7f, 0xd9, 0xd4, + 0xa2, 0xef, 0xf8, 0x67, 0xbd, 0xee, 0x7e, 0x4a, 0x57, 0x3e, 0x78, 0x21, 0xcf, 0x6d, 0x72, 0xf8, + 0xfa, 0x77, 0xeb, 0x26, 0x4f, 0x0f, 0x13, 0x16, 0x44, 0x4f, 0xed, 0x02, 0xcb, 0x51, 0x70, 0x44, + 0x55, 0xaf, 0xbe, 0x08, 0xe4, 0xf9, 0xb3, 0xab, 0xa2, 0x31, 0xf2, 0x77, 0x65, 0xe0, 0x9a, 0x5f, + 0x6b, 0x11, 0x2e, 0xdb, 0xf2, 0x70, 0x20, 0x41, 0x11, 0x60, 0x61, 0x62, 0x92, 0x7b, 0x0f, 0x1c, + 0x20, 0x08, 0x41, 0x29, 0x0b, 0x67, 0xb9, 0xb9, 0x6c, 0xf7, 0xbd, 0xb1, 0xc4, 0x06, 0x43, 0x1c, + 0x4f, 0x16, 0xaa, 0xb1, 0xcf, 0x8d, 0xce, 0xc0, 0xeb, 0xe1, 0x80, 0xc8, 0xbd, 0x2a, 0x5b, 0x8a, + 0xf1, 0x22, 0x06, 0xc1, 0x93, 0x52, 0xc4, 0x3e, 0x2b, 0xf8, 0x9d, 0xc8, 0x56, 0x5b, 0x2c, 0x6e, + 0x3d, 0xe1, 0xc0, 0xe1, 0xe3, 0x87, 0x83, 0x88, 0x47, 0x95, 0x64, 0x4e, 0xa9, 0xe6, 0x06, 0x00, + 0xb4, 0xd0, 0xa9, 0x1e, 0x98, 0x7a, 0x91, 0xed, 0xe2, 0x63, 0x60, 0x68, 0x37, 0x73, 0x39, 0x81, + 0x59, 0xaf, 0x4c, 0x28, 0x13, 0x3a, 0x27, 0x0c, 0x71, 0x7c, 0x84, 0x39, 0x8f, 0xf8, 0x3a, 0x98, + 0x2e, 0x22, 0x02, 0x80, 0x54, 0xf1, 0x9d, 0x7a, 0x51, 0x39, 0x0f, 0x3b, 0xf4, 0x20, 0x67, 0xb9, + 0xfa, 0xe2, 0xba, 0x59, 0x77, 0x8b, 0x78, 0x88, 0x2a, 0xcc, 0xbd, 0x3b, 0xc5, 0x6e, 0x20, 0x79, + 0x58, 0x38, 0x07, 0xd2, 0xf8, 0x90, 0xa5, 0x28, 0x81, 0xc9, 0xf1, 0xfe, 0x2b, 0x38, 0x16, 0x0f, + 0xc9, 0x00, 0x68, 0x58, 0xc5, 0x6e, 0x28, 0xde, 0xfc, 0x40, 0x90, 0xa4, 0xe6, 0x02, 0x79, 0xaf, + 0x07, 0xae, 0x3b, 0xe4, 0xb5, 0x0e, 0x39, 0x0b, 0x07, 0xe4, 0xce, 0x21, 0x88, 0x08, 0x8f, 0xbf, + 0x58, 0x9c, 0x10, 0xd4, 0x66, 0x25, 0x85, 0xcf, 0x90, 0xec, 0x58, 0x0e, 0x7b, 0x80, 0x5a, 0x7d, + 0xbf, 0xa7, 0x9a, 0x09, 0xc6, 0x9f, 0xf8, 0x02, 0x00, 0x42, 0x13, 0x31, 0xdb, 0x5c, 0x95, 0xfe, + 0x8c, 0xe8, 0x20, 0xe6, 0x26, 0xaa, 0xe2, 0x65, 0x2b, 0x77, 0xfb, 0x8d, 0x08, 0x39, 0xc6, 0x7e, + 0x4e, 0x12, 0xe5, 0xfd, 0xdf, 0xcc, 0x49, 0x7f, 0xec, 0xa0, 0xee, 0xcf, 0xc1, 0x4d, 0x0d, 0x63, + 0x88, 0x82, 0xc1, 0xcd, 0xeb, 0xbb, 0xe2, 0xb7, 0x7e, 0x22, 0x14, 0x93, 0x0b, 0xf2, 0x60, 0xa6, + 0x29, 0x97, 0x8b, 0x8c, 0x65, 0x2c, 0x23, 0x01, 0x8b, 0x8b, 0xc4, 0x73, 0xc3, 0x08, 0x09, 0x05, + 0x25, 0x9e, 0x99, 0x6c, 0x4b, 0x97, 0x5c, 0xe8, 0xef, 0x05, 0x21, 0x80, 0x59, 0xc5, 0xde, 0x4c, + 0x9b, 0x15, 0xeb, 0x97, 0x04, 0x01, 0x10, 0x55, 0x77, 0xc8, 0x64, 0x21, 0xc8, 0xa9, 0xea, 0xed, + 0xc1, 0xdb, 0x79, 0xe3, 0x02, 0xc8, 0x38, 0x93, 0x50, 0xb9, 0x53, 0xc0, 0xe2, 0x50, 0xc4, 0x88, + 0x1a, 0x65, 0x19, 0x54, 0x4a, 0xf9, 0x6e, 0x43, 0xc3, 0xc3, 0x42, 0x3b, 0x48, 0xf6, 0x9b, 0xd0, + 0x5e, 0x21, 0x96, 0x43, 0xe4, 0x80, 0x01, 0xc0, 0xc1, 0x2f, 0x87, 0x80, 0x0f, 0x03, 0xf0, 0x0d, + 0x43, 0x83, 0x07, 0x53, 0xc0, 0x00, 0xbe, 0x02, 0x67, 0xf7, 0x6e, 0x9e, 0x18, 0x08, 0x82, 0x69, + 0x02, 0xf5, 0x98, 0xa1, 0xf8, 0x6a, 0x5b, 0x25, 0x00, 0x02, 0xea, 0x51, 0x1a, 0xc9, 0x83, 0x08, + 0x09, 0x19, 0x71, 0x46, 0x5c, 0x6a, 0x47, 0x7b, 0x76, 0xa9, 0x0e, 0xa8, 0x8d, 0xbe, 0xdc, 0xf7, + 0x85, 0x8f, 0x82, 0x42, 0xcb, 0xa8, 0x7f, 0x70, 0x61, 0x0d, 0x94, 0x4b, 0xe0, 0xe9, 0xf3, 0xfa, + 0x3b, 0xf2, 0xf4, 0xcb, 0x3f, 0xd5, 0x80, 0x28, 0xe6, 0xde, 0xfe, 0x09, 0x0c, 0x5a, 0x3d, 0xda, + 0xe0, 0xa4, 0x10, 0x18, 0xef, 0x77, 0xc3, 0x01, 0x80, 0x42, 0x47, 0x8a, 0xef, 0xc2, 0x02, 0x02, + 0x55, 0x17, 0xf7, 0x7e, 0x19, 0x36, 0x1b, 0xf4, 0x54, 0x14, 0xec, 0x40, 0x91, 0xa4, 0xc4, 0x3c, + 0x4b, 0xcf, 0xf2, 0xc3, 0x59, 0x98, 0xa2, 0xb8, 0x3b, 0x4a, 0xad, 0x22, 0xb9, 0x00, 0x92, 0xb0, + 0xa4, 0x0f, 0x0f, 0x94, 0x07, 0xab, 0xf1, 0x1b, 0x96, 0xe3, 0x15, 0xd5, 0xc5, 0xde, 0x1e, 0xc0, + 0x17, 0xd2, 0xc7, 0xe9, 0x28, 0xf2, 0x51, 0xfa, 0xfa, 0xf9, 0x79, 0xbf, 0xb6, 0x5d, 0x83, 0xff, + 0x58, 0x3b, 0x7b, 0xac, 0x1e, 0x68, 0x12, 0x55, 0xe9, 0xcd, 0xed, 0xe0, 0xa4, 0x0a, 0x01, 0x49, + 0xc1, 0xc3, 0x83, 0x82, 0xe5, 0xe0, 0xf1, 0x60, 0x28, 0x09, 0x94, 0x66, 0x94, 0x14, 0xac, 0x51, + 0x41, 0xa4, 0xc2, 0x1b, 0x83, 0xcf, 0x8b, 0x2d, 0x42, 0x23, 0x0e, 0x84, 0xe3, 0xc9, 0x68, 0x6a, + 0x7c, 0x31, 0x0a, 0x79, 0x3c, 0xf5, 0x1d, 0x58, 0x78, 0x1c, 0x70, 0xc6, 0x2c, 0x75, 0x73, 0xde, + 0xe1, 0x5e, 0x07, 0xb9, 0x54, 0x36, 0xb5, 0x3f, 0x12, 0x24, 0x15, 0x94, 0xba, 0xa2, 0xd9, 0xab, + 0x62, 0x24, 0x04, 0x2a, 0x2e, 0x32, 0xb3, 0x40, 0x0a, 0xf9, 0xad, 0x8f, 0x71, 0x0f, 0xd6, 0x5d, + 0xc5, 0x9d, 0x66, 0xfe, 0x20, 0x3f, 0x06, 0x2e, 0x9a, 0x37, 0x26, 0xe6, 0x5c, 0x1b, 0x2a, 0x6e, + 0xf5, 0xb8, 0xf4, 0x51, 0x18, 0x41, 0x5f, 0x17, 0x56, 0x3a, 0xaa, 0x9b, 0x1d, 0x0f, 0x09, 0xd9, + 0xa4, 0xcf, 0x15, 0xde, 0x14, 0x50, 0x00, 0x49, 0xb2, 0x41, 0x39, 0x7b, 0xa1, 0x1b, 0x8a, 0xcf, + 0xbf, 0xf8, 0x0d, 0xc1, 0xae, 0x06, 0xa0, 0x00, 0x4d, 0x76, 0x30, 0x52, 0x04, 0x10, 0xa4, 0x41, + 0xe2, 0x98, 0xa6, 0x29, 0x89, 0xe0, 0x93, 0x85, 0x86, 0x78, 0x58, 0x07, 0x9e, 0x0e, 0x7c, 0xce, + 0xab, 0xda, 0x87, 0xe4, 0xa1, 0xf0, 0x96, 0xdb, 0x83, 0x45, 0x19, 0x62, 0x03, 0x01, 0x4c, 0xa4, + 0x70, 0x38, 0xfe, 0xbd, 0x45, 0x5b, 0xe0, 0xb3, 0x35, 0x3c, 0x0d, 0x2e, 0x78, 0xb6, 0x5d, 0x34, + 0x15, 0xb5, 0x76, 0x7f, 0xe2, 0x01, 0x61, 0x01, 0xff, 0x1c, 0x1f, 0xc1, 0xc9, 0xf1, 0xc4, 0xf8, + 0x7b, 0xd6, 0xa3, 0x2a, 0x89, 0x06, 0xe0, 0x3b, 0x10, 0xf0, 0x21, 0xff, 0xb1, 0xcd, 0x40, 0x1e, + 0xea, 0x7f, 0x85, 0x29, 0x70, 0x26, 0x8e, 0x72, 0x82, 0x17, 0xc2, 0xe4, 0x31, 0xba, 0xcf, 0xed, + 0xac, 0xd9, 0x76, 0x1e, 0x24, 0x00, 0x86, 0x84, 0x84, 0x17, 0xdb, 0xce, 0x41, 0xe1, 0xbe, 0xff, + 0x1d, 0xfb, 0x68, 0xd8, 0xae, 0x25, 0xed, 0x9e, 0x8f, 0xc1, 0x56, 0x5a, 0xdf, 0xf1, 0x60, 0x4f, + 0xe3, 0xc0, 0x13, 0x23, 0xe2, 0xbf, 0x54, 0xf2, 0xf8, 0x6e, 0x50, 0x02, 0xa5, 0x91, 0xeb, 0x00, + 0xcf, 0xbe, 0xff, 0xe2, 0xee, 0x11, 0xf9, 0x47, 0xc6, 0xb3, 0xd3, 0x95, 0xa4, 0x86, 0x30, 0x3a, + 0xa3, 0xfe, 0x54, 0x06, 0xc8, 0x2a, 0x0c, 0xf1, 0x4d, 0x72, 0x0e, 0xcd, 0x62, 0x01, 0x58, 0x08, + 0x20, 0x2c, 0x47, 0xbc, 0x9d, 0xe3, 0xe1, 0x88, 0x52, 0x3a, 0xfd, 0x95, 0x4e, 0x85, 0xb2, 0x8a, + 0xc6, 0xba, 0x96, 0x5b, 0x9d, 0x67, 0x3a, 0xa7, 0x38, 0x81, 0x21, 0x4f, 0xbf, 0xfb, 0x97, 0x9c, + 0x38, 0xee, 0x59, 0x58, 0xf1, 0xf2, 0xc0, 0x06, 0x3f, 0x90, 0xe8, 0xf1, 0xde, 0x24, 0x29, 0x8f, + 0xbf, 0x2e, 0x34, 0x7c, 0x1f, 0xe6, 0xe7, 0x0f, 0x76, 0xfa, 0x55, 0xe1, 0xb2, 0xbe, 0xec, 0x7f, + 0x19, 0xec, 0x12, 0x76, 0x43, 0x53, 0x55, 0xd5, 0xab, 0x84, 0xc4, 0xc9, 0xfb, 0xdf, 0xc8, 0x22, + 0xd5, 0x7c, 0x41, 0x15, 0x47, 0x0c, 0xef, 0x9e, 0x55, 0x13, 0x19, 0x02, 0x0e, 0x10, 0x70, 0x52, + 0x00, 0xa8, 0x0f, 0xe2, 0x43, 0x3f, 0x4b, 0xd7, 0xe2, 0x04, 0xda, 0xbb, 0x0a, 0xae, 0x35, 0x4f, + 0x52, 0x12, 0xdd, 0xbb, 0xd4, 0x7f, 0x1e, 0x70, 0xc8, 0x40, 0x7c, 0x94, 0x00, 0xb4, 0x16, 0x00, + 0x1c, 0x93, 0x03, 0x80, 0x11, 0xb2, 0x38, 0x1d, 0xc4, 0xb2, 0xc0, 0x00, 0x84, 0x6a, 0x87, 0x00, + 0x01, 0x0c, 0xc1, 0x88, 0x39, 0x0a, 0x4b, 0x19, 0xee, 0x3b, 0x17, 0x2f, 0x58, 0x18, 0x2b, 0xc0, + 0xf0, 0xd1, 0x28, 0x70, 0x2f, 0x8b, 0x1d, 0xa3, 0x70, 0xe7, 0x09, 0xc5, 0x4f, 0x07, 0x1b, 0x81, + 0x04, 0x0b, 0x23, 0x6a, 0xdb, 0xe2, 0x50, 0x03, 0x8d, 0xf0, 0x6c, 0x87, 0xa6, 0x2d, 0xe2, 0x00, + 0x04, 0x95, 0x00, 0xb4, 0x97, 0x04, 0x65, 0x1d, 0x02, 0x98, 0x67, 0x1d, 0x7e, 0x5a, 0xf6, 0x69, + 0xc0, 0xf5, 0x18, 0x1a, 0x88, 0x55, 0x82, 0x29, 0x0d, 0x29, 0xb9, 0x58, 0x6c, 0xb0, 0x17, 0x73, + 0x78, 0x6e, 0x50, 0x05, 0x3c, 0xb1, 0xe6, 0xb7, 0x90, 0x19, 0x9e, 0x27, 0x75, 0x7c, 0x1d, 0x0a, + 0x3a, 0x57, 0x50, 0x76, 0xcf, 0xe2, 0xfd, 0xad, 0x51, 0xbd, 0x34, 0xce, 0x06, 0xa7, 0x00, 0x3a, + 0x81, 0x14, 0xfa, 0x6b, 0x17, 0xdc, 0x48, 0xff, 0x02, 0x80, 0x31, 0x05, 0x86, 0x0e, 0xb3, 0x52, + 0xa8, 0x25, 0x2c, 0x59, 0x28, 0x01, 0x5a, 0x86, 0x59, 0xb0, 0x86, 0x01, 0x8b, 0x2c, 0x04, 0x4b, + 0x4b, 0x12, 0xc8, 0x4c, 0xf0, 0x5a, 0xb0, 0x76, 0xf8, 0x52, 0x4e, 0x00, 0x59, 0x10, 0xa9, 0x49, + 0x80, 0x02, 0xc8, 0xe0, 0xf7, 0xc1, 0xc0, 0xf1, 0xad, 0x33, 0x11, 0x3f, 0x07, 0x07, 0x0e, 0x3c, + 0x74, 0x59, 0x06, 0xf8, 0x50, 0x6e, 0x7d, 0xf6, 0x24, 0x54, 0x28, 0xa7, 0x63, 0x53, 0xbe, 0x20, + 0x41, 0x2b, 0x5c, 0x49, 0xc8, 0x56, 0xb8, 0x80, 0x52, 0x14, 0x96, 0x18, 0xa6, 0x58, 0x18, 0x58, + 0x0a, 0x8b, 0x9f, 0xc9, 0x38, 0xe1, 0x30, 0xe3, 0x93, 0x7e, 0xad, 0x1d, 0x1c, 0x30, 0x38, 0x09, + 0x19, 0xd2, 0x48, 0x8c, 0x8b, 0x93, 0x66, 0x42, 0xa0, 0xae, 0x54, 0x1b, 0x95, 0xe5, 0xd2, 0xe4, + 0x3c, 0x8a, 0x00, 0xc0, 0xfa, 0x8e, 0x5f, 0xf5, 0x57, 0x7d, 0xe9, 0xe9, 0xbb, 0xb4, 0x9d, 0x36, + 0xdd, 0x3f, 0xf0, 0x47, 0xcb, 0x94, 0xf0, 0xef, 0x2d, 0x6b, 0x11, 0xcc, 0x5e, 0x6f, 0xe4, 0x34, + 0xbf, 0xf0, 0x54, 0x64, 0xdc, 0x66, 0xc6, 0x83, 0x22, 0x57, 0xc7, 0xcb, 0x0f, 0xd9, 0x5c, 0xc5, + 0x83, 0xff, 0xe0, 0xe0, 0x10, 0x85, 0x21, 0x5f, 0x03, 0xe1, 0x93, 0xe3, 0xfc, 0x2a, 0x84, 0x66, + 0xf4, 0x2a, 0x02, 0x4a, 0x60, 0x6b, 0x8d, 0x36, 0x45, 0xc5, 0x8c, 0xd5, 0x07, 0xd9, 0xe1, 0x48, + 0x9d, 0xc9, 0x85, 0xfa, 0x29, 0x30, 0x88, 0x80, 0xa4, 0xb1, 0x44, 0xc3, 0x80, 0xf3, 0xba, 0x43, + 0x1c, 0x99, 0xed, 0x76, 0x1b, 0x8b, 0x2e, 0xed, 0x7b, 0x87, 0x1c, 0x9f, 0xaa, 0xbf, 0x08, 0x42, + 0x3a, 0xc9, 0xea, 0x0f, 0xf0, 0x97, 0x8c, 0x5d, 0x45, 0x6d, 0xd4, 0xc8, 0x62, 0xef, 0x98, 0x30, + 0x04, 0x01, 0x48, 0xd6, 0x12, 0x68, 0xa5, 0xe0, 0xbf, 0xce, 0x06, 0x81, 0xf8, 0xd4, 0x7f, 0xff, + 0xc9, 0x5c, 0x97, 0xbf, 0x15, 0xca, 0xfd, 0x70, 0x7b, 0x97, 0x74, 0xce, 0x59, 0x22, 0x22, 0xc4, + 0x88, 0x0a, 0x41, 0x38, 0x39, 0x14, 0x80, 0x00, 0x23, 0x15, 0x48, 0x0f, 0xca, 0x39, 0x2c, 0x0b, + 0x80, 0x35, 0x55, 0xc8, 0xb5, 0xd7, 0x8c, 0x18, 0x3e, 0x3d, 0xe5, 0xba, 0x42, 0xb3, 0x9c, 0xa6, + 0x5b, 0x7a, 0x3c, 0xe0, 0x49, 0x8d, 0xd3, 0x3d, 0x56, 0x78, 0x50, 0xfb, 0x81, 0x8c, 0xac, 0x06, + 0xd0, 0xa1, 0x27, 0x2c, 0xa6, 0x5c, 0xe0, 0xe0, 0xe8, 0x4d, 0xce, 0xe1, 0x31, 0x1f, 0x46, 0x73, + 0x43, 0x86, 0x85, 0x8f, 0x87, 0x8a, 0x15, 0x02, 0xb5, 0x22, 0xa0, 0x7f, 0xa8, 0xac, 0x46, 0x5d, + 0x6f, 0x25, 0x45, 0x59, 0xff, 0x84, 0x02, 0x21, 0x4b, 0x8c, 0x48, 0x23, 0x96, 0xe2, 0x98, 0x8b, + 0xb8, 0x66, 0xf5, 0x90, 0x4b, 0xbb, 0xb8, 0x37, 0x20, 0x61, 0x78, 0x71, 0x0a, 0x8a, 0x70, 0xf8, + 0xe6, 0xe5, 0xba, 0xdc, 0xdf, 0x27, 0x58, 0x21, 0x8c, 0x9f, 0x05, 0x69, 0x08, 0xcf, 0x90, 0x5f, + 0x8e, 0xf9, 0x9f, 0x2f, 0x59, 0x32, 0xa2, 0xff, 0x12, 0x33, 0xc4, 0x95, 0xc4, 0x39, 0x76, 0xe2, + 0xe6, 0xca, 0x9c, 0xbd, 0xac, 0x22, 0x24, 0x65, 0xdb, 0x4b, 0xc4, 0x4c, 0xdc, 0x56, 0x7d, 0xa9, + 0x72, 0xfc, 0x40, 0x31, 0x08, 0xd6, 0x6f, 0xb6, 0x93, 0x4d, 0x0b, 0x8b, 0xf8, 0x26, 0x38, 0x18, + 0xd8, 0xcf, 0x70, 0x3b, 0x12, 0xec, 0xc2, 0x67, 0x72, 0x15, 0xe4, 0x22, 0xad, 0x7c, 0xb5, 0xd4, + 0x6f, 0x37, 0x77, 0x5d, 0xc3, 0x6b, 0x1a, 0x26, 0x90, 0x75, 0xc2, 0x54, 0xb6, 0xb9, 0x61, 0xef, + 0xbb, 0xf8, 0xa9, 0x31, 0x2e, 0xf7, 0x50, 0x80, 0x29, 0x0a, 0x51, 0x09, 0x07, 0x48, 0xdf, 0x04, + 0xa0, 0x0b, 0x17, 0x00, 0x90, 0x9e, 0xbb, 0xad, 0x6d, 0x71, 0x05, 0xf8, 0x3c, 0x1f, 0x85, 0x47, + 0x23, 0xc0, 0x1f, 0x64, 0xea, 0xd4, 0xe7, 0xc1, 0x01, 0x15, 0x51, 0x80, 0xfe, 0xc6, 0x24, 0x60, + 0x21, 0xa2, 0xd5, 0xad, 0x6b, 0x4f, 0x11, 0x78, 0xa7, 0x97, 0x11, 0xd4, 0xff, 0x88, 0x0a, 0x56, + 0x1c, 0xb0, 0xfc, 0x35, 0xfe, 0x3a, 0xb7, 0x25, 0x6d, 0xf0, 0x2b, 0x2f, 0x11, 0x49, 0x4f, 0x3c, + 0x6a, 0x4a, 0x88, 0x9b, 0xdf, 0xaf, 0xc2, 0x80, 0xe9, 0xc3, 0x22, 0x42, 0x92, 0xcf, 0xd4, 0x9b, + 0x81, 0xc9, 0x61, 0x95, 0xbc, 0x70, 0xd3, 0x28, 0x0c, 0xe6, 0x8d, 0xa3, 0xbf, 0x3d, 0x38, 0x62, + 0x04, 0x05, 0x22, 0xc1, 0x2d, 0x62, 0x71, 0x4c, 0xee, 0x2b, 0x88, 0x78, 0x87, 0x05, 0x62, 0x8d, + 0xc4, 0x8c, 0x0b, 0x75, 0x5a, 0xbf, 0x12, 0x18, 0x0a, 0x15, 0xee, 0xdf, 0x14, 0x65, 0xbc, 0x4d, + 0x8a, 0xdc, 0x56, 0x28, 0xc5, 0x18, 0xa3, 0x14, 0x1b, 0xf0, 0xc8, 0x10, 0x06, 0xc1, 0x82, 0x81, + 0x72, 0x82, 0x70, 0x0a, 0xb5, 0x23, 0x84, 0x31, 0xa9, 0x68, 0x1e, 0x51, 0xc8, 0xfa, 0x44, 0x71, + 0xb1, 0x88, 0x04, 0xb9, 0x66, 0xc4, 0x76, 0xd2, 0x27, 0xf3, 0x85, 0xf3, 0x82, 0xc5, 0xd8, 0x2b, + 0x1a, 0x15, 0x42, 0x32, 0x05, 0x41, 0x95, 0x93, 0x5f, 0x9f, 0x2d, 0xb6, 0x99, 0x7a, 0xbd, 0xf8, + 0x08, 0x80, 0xa1, 0x04, 0x7d, 0xaa, 0x90, 0x2a, 0x0e, 0x06, 0x8d, 0xa6, 0x3b, 0xf8, 0xc7, 0xb2, + 0xff, 0x48, 0x62, 0x66, 0x9e, 0xa6, 0x71, 0x6d, 0x84, 0xaa, 0x97, 0x61, 0xc6, 0x35, 0x5f, 0x99, + 0x91, 0xf8, 0x21, 0x07, 0x00, 0xa0, 0xb8, 0x74, 0x08, 0x5f, 0x03, 0xa1, 0x52, 0x8f, 0x2b, 0xfd, + 0xb9, 0x7c, 0x59, 0x5e, 0xfd, 0xdc, 0x35, 0xcc, 0x65, 0xac, 0xbc, 0xa5, 0x4a, 0x7f, 0x2f, 0x7d, + 0x27, 0x5c, 0xa4, 0xd3, 0x6f, 0xd5, 0xab, 0xba, 0x59, 0xec, 0x90, 0x88, 0x30, 0x20, 0x95, 0x9f, + 0x08, 0x82, 0x80, 0xd0, 0x80, 0x30, 0x14, 0x2f, 0x02, 0x37, 0x00, 0x03, 0x5c, 0x82, 0xde, 0x0e, + 0x2c, 0x1f, 0xff, 0xf1, 0x02, 0x42, 0x96, 0x41, 0xbd, 0x94, 0x71, 0x8a, 0x72, 0xb1, 0x3f, 0x6e, + 0xe7, 0x3c, 0xe1, 0x83, 0x96, 0xf1, 0xd1, 0x02, 0x95, 0x69, 0x44, 0x18, 0xf8, 0xc2, 0xc6, 0xf2, + 0x98, 0xac, 0x48, 0x3c, 0x43, 0x02, 0xc7, 0x30, 0xb7, 0xf1, 0x62, 0x16, 0x0e, 0x78, 0x87, 0x9c, + 0xe6, 0x18, 0x06, 0x01, 0x43, 0x30, 0xaa, 0x30, 0x6a, 0x3b, 0xac, 0xa1, 0xec, 0x51, 0x2a, 0x2e, + 0xb2, 0xd6, 0xea, 0xbf, 0xc6, 0x5b, 0x3f, 0x12, 0x3e, 0xdf, 0xc3, 0x03, 0x63, 0xfb, 0x1a, 0xd3, + 0xb9, 0x20, 0xd0, 0x7f, 0xa9, 0x0f, 0xb8, 0xc6, 0x18, 0x2e, 0x29, 0x1f, 0x37, 0x96, 0x3c, 0xf9, + 0x7b, 0xb1, 0x5e, 0x4d, 0x7f, 0xf0, 0x88, 0x10, 0x02, 0x9a, 0x8f, 0x70, 0x3b, 0x89, 0x46, 0xb2, + 0xe2, 0xd8, 0x2d, 0xbe, 0x7c, 0x0c, 0x5d, 0x54, 0x2f, 0x11, 0x78, 0xaf, 0x33, 0xa3, 0xd3, 0x62, + 0x93, 0x51, 0xf8, 0x90, 0x50, 0x36, 0x3c, 0x74, 0x01, 0xfe, 0xc7, 0xc1, 0x9e, 0x06, 0x95, 0x1b, + 0x07, 0x97, 0x3c, 0x0b, 0x18, 0xca, 0xd9, 0xee, 0x0c, 0xb3, 0xe2, 0x52, 0xa0, 0x81, 0xb7, 0x9d, + 0x2e, 0x0e, 0x89, 0x4b, 0xdd, 0x53, 0x1d, 0xc7, 0x12, 0x1e, 0x12, 0x46, 0x05, 0xe3, 0xf0, 0x37, + 0x3e, 0x86, 0x17, 0x00, 0xd6, 0x35, 0x30, 0xa4, 0x18, 0xe7, 0x8b, 0xff, 0x06, 0x20, 0xe4, 0x28, + 0x61, 0x3d, 0x1f, 0x52, 0xf2, 0xf7, 0xed, 0x45, 0xe2, 0x9c, 0x88, 0xf2, 0x8d, 0xe2, 0x84, 0xf7, + 0x8b, 0x82, 0xf3, 0xd5, 0x17, 0x80, 0x31, 0x2c, 0xc6, 0x1c, 0x50, 0x01, 0xcb, 0x65, 0x66, 0x34, + 0xde, 0xfd, 0xdf, 0xfe, 0x2d, 0xa6, 0x98, 0xd7, 0x0d, 0x2e, 0xc1, 0xbb, 0x7f, 0x04, 0x7c, 0x82, + 0xc4, 0xb9, 0xd7, 0x08, 0x8a, 0x24, 0x3a, 0xa9, 0xa7, 0x15, 0xb4, 0xbe, 0x10, 0xf3, 0x64, 0x98, + 0x94, 0x24, 0xad, 0xc4, 0xc4, 0x86, 0x42, 0x90, 0xc7, 0x80, 0xfa, 0x22, 0x96, 0xf1, 0x52, 0x8e, + 0x0d, 0x67, 0x65, 0x8e, 0xc5, 0x18, 0xba, 0x11, 0x5a, 0xdd, 0x88, 0x1e, 0x08, 0x98, 0x5d, 0x9e, + 0x7c, 0x5c, 0x48, 0x44, 0x29, 0x2d, 0x9f, 0x1f, 0xa7, 0x15, 0x8c, 0xe7, 0x89, 0x48, 0x22, 0xb2, + 0xdb, 0xc8, 0x26, 0x4b, 0x4a, 0xb5, 0xaa, 0x40, 0x70, 0xc8, 0x39, 0x09, 0x15, 0xed, 0x62, 0x92, + 0xab, 0xf0, 0x42, 0x36, 0xb5, 0xb6, 0x2c, 0xc9, 0x06, 0xe1, 0xd3, 0x4a, 0x6e, 0x86, 0x27, 0xfc, + 0xf0, 0xf5, 0x9f, 0xff, 0x85, 0x7d, 0x88, 0x10, 0x36, 0x35, 0x22, 0x4d, 0x12, 0x95, 0x7e, 0xc1, + 0xe7, 0x8f, 0xe1, 0xc5, 0x03, 0x81, 0x8b, 0x44, 0x61, 0xc8, 0xe0, 0x1b, 0x87, 0x58, 0x2c, 0xcb, + 0xcd, 0x03, 0xe9, 0x29, 0x29, 0xa8, 0xa9, 0xa8, 0x35, 0x8b, 0xcf, 0x1e, 0xc2, 0xf4, 0xec, 0xa2, + 0x92, 0x31, 0x00, 0x41, 0x0a, 0x10, 0xe1, 0xe2, 0x83, 0xa8, 0xf8, 0x08, 0x41, 0xd6, 0xe1, 0xf5, + 0x18, 0xb7, 0x92, 0x48, 0xb5, 0xf1, 0x3f, 0x2b, 0x6b, 0x39, 0xc2, 0x9b, 0x0b, 0xf2, 0x6e, 0x51, + 0x02, 0x78, 0xf1, 0x23, 0x25, 0x60, 0xbc, 0x1f, 0x09, 0x79, 0x22, 0x43, 0xe4, 0x43, 0xb0, 0x3a, + 0xe8, 0x87, 0xae, 0x28, 0xdd, 0xcb, 0x6e, 0xf8, 0x88, 0x2a, 0x21, 0x40, 0x02, 0x13, 0xc5, 0x00, + 0x84, 0xcb, 0xf1, 0xeb, 0xe9, 0x0a, 0x38, 0x59, 0xa6, 0xf2, 0xf0, 0x80, 0x52, 0x02, 0x9e, 0x99, + 0x33, 0xa7, 0xca, 0x23, 0x76, 0x56, 0x97, 0xb7, 0x70, 0xa3, 0x83, 0xdc, 0x2d, 0xd9, 0xcb, 0xc4, + 0x02, 0xc2, 0xe2, 0xdb, 0x8a, 0x3c, 0x7b, 0xca, 0xa9, 0xbe, 0x3f, 0x7d, 0xc4, 0x04, 0x06, 0xc4, + 0x38, 0x15, 0x58, 0x8e, 0xaa, 0x53, 0x29, 0x6b, 0x69, 0x84, 0x77, 0xbd, 0xcb, 0x62, 0x1c, 0x73, + 0xc7, 0x06, 0xa9, 0x26, 0xa5, 0xfe, 0x24, 0x20, 0x36, 0x21, 0xc1, 0x59, 0x6d, 0xdc, 0xf0, 0x85, + 0x15, 0x6e, 0x37, 0x0b, 0x65, 0x8d, 0x2c, 0x57, 0xea, 0x44, 0xdf, 0xf8, 0x60, 0x6c, 0xf8, 0xf2, + 0xa2, 0x8d, 0xb1, 0x0f, 0xd2, 0x24, 0x39, 0xa4, 0xcd, 0x53, 0x64, 0x8c, 0xfb, 0xf8, 0x60, 0x10, + 0x0d, 0x8a, 0xe6, 0xc1, 0x71, 0x21, 0x62, 0x68, 0x21, 0x27, 0x14, 0x01, 0x27, 0x85, 0x30, 0x46, + 0xe0, 0x58, 0x6d, 0xc8, 0x70, 0x9c, 0x30, 0x6c, 0x48, 0x55, 0x29, 0x68, 0x16, 0x10, 0xc0, 0x5d, + 0x91, 0x52, 0xc7, 0xa5, 0x9f, 0x33, 0xfc, 0x1c, 0x05, 0x38, 0xc7, 0x21, 0x95, 0x41, 0x78, 0x1b, + 0xbe, 0x54, 0x8f, 0xc0, 0xe2, 0xe1, 0x0d, 0x50, 0x53, 0x8d, 0xc8, 0x01, 0x90, 0x6d, 0x17, 0x07, + 0xa4, 0xaf, 0x00, 0xf6, 0x27, 0x95, 0x10, 0x56, 0x22, 0x70, 0x15, 0xa8, 0xea, 0x01, 0x0e, 0x61, + 0xbc, 0x01, 0x65, 0xce, 0x10, 0xf6, 0x57, 0xd7, 0x9f, 0x47, 0x6d, 0xa8, 0xb0, 0x30, 0x73, 0xac, + 0xbf, 0xc1, 0xf9, 0xa1, 0xac, 0x00, 0x3e, 0x8a, 0x20, 0x05, 0x70, 0x07, 0x63, 0x21, 0xe9, 0x7d, + 0xde, 0x1d, 0x31, 0x71, 0x5f, 0xdb, 0x06, 0xb7, 0x7c, 0x2c, 0xce, 0x00, 0x36, 0x5c, 0x3b, 0xa2, + 0x17, 0x7f, 0x93, 0x96, 0x17, 0x17, 0x46, 0x8c, 0x6f, 0x09, 0xbb, 0xbe, 0x48, 0xe5, 0xac, 0x77, + 0x21, 0x2f, 0x75, 0xd9, 0x5e, 0xf1, 0xbd, 0x9c, 0x7f, 0x14, 0xe1, 0x49, 0xc4, 0x8a, 0xaa, 0xad, + 0x69, 0x79, 0x48, 0xab, 0x92, 0x11, 0x82, 0xaa, 0xbf, 0x8a, 0x12, 0x7b, 0xea, 0x7a, 0x11, 0xe4, + 0x05, 0x0a, 0xa1, 0x46, 0xa1, 0x40, 0xa5, 0x39, 0x78, 0x64, 0x10, 0x82, 0x1b, 0xbc, 0xeb, 0x5c, + 0x32, 0x19, 0x1a, 0x55, 0xb9, 0xc6, 0xde, 0xfe, 0x5e, 0x20, 0x01, 0xed, 0xe7, 0x0f, 0x36, 0xf5, + 0x15, 0x9c, 0x3c, 0x0f, 0xce, 0xe5, 0x9a, 0x2b, 0x7e, 0xb9, 0x14, 0x62, 0x04, 0xab, 0x8f, 0x04, + 0x5d, 0xbf, 0x4e, 0x94, 0x20, 0x0e, 0x46, 0xc5, 0x67, 0xc1, 0x0f, 0x5b, 0x9d, 0xaa, 0xad, 0x29, + 0x71, 0x73, 0x45, 0x75, 0xd2, 0x20, 0x60, 0xc3, 0x1d, 0x85, 0x30, 0x08, 0xa9, 0x84, 0x11, 0x80, + 0x4f, 0x06, 0x0f, 0xe6, 0xd1, 0xbd, 0x6a, 0x5e, 0xb5, 0xc3, 0x6e, 0x00, 0x25, 0xc5, 0x25, 0xc5, + 0x39, 0x59, 0x19, 0x6d, 0xf4, 0x4d, 0xef, 0xa2, 0x06, 0xa3, 0xf2, 0xc6, 0xea, 0xa3, 0xf9, 0x6a, + 0x98, 0x14, 0xbd, 0x8a, 0x58, 0xc0, 0x15, 0x87, 0x51, 0xff, 0x0c, 0xe0, 0x02, 0xba, 0x64, 0x0e, + 0x16, 0x9c, 0xa1, 0x2c, 0xd9, 0x7f, 0x21, 0x50, 0x7a, 0x7b, 0x45, 0x7e, 0x1d, 0xf6, 0xdb, 0xa4, + 0x85, 0xef, 0x20, 0xb4, 0xc4, 0x06, 0x06, 0x59, 0xff, 0xbb, 0x88, 0x1f, 0x52, 0xe5, 0x6d, 0x3f, + 0x12, 0x6c, 0x38, 0x40, 0x65, 0xe5, 0x83, 0x10, 0xd3, 0x14, 0x62, 0xbc, 0x0f, 0x62, 0x53, 0xe5, + 0x83, 0xdc, 0x17, 0x0b, 0x37, 0xc9, 0x4f, 0x38, 0x03, 0x97, 0x05, 0x03, 0x05, 0xd6, 0xcd, 0x54, + 0xb9, 0xd5, 0x64, 0x2f, 0x6f, 0x84, 0x01, 0x00, 0xf1, 0x09, 0x08, 0xe5, 0x8c, 0x3f, 0x95, 0x08, + 0x50, 0xb6, 0xe5, 0xab, 0x78, 0x64, 0x14, 0x8c, 0x22, 0x41, 0x57, 0x2f, 0x75, 0xf8, 0x24, 0x39, + 0x07, 0x73, 0x52, 0x45, 0x4a, 0x65, 0x1e, 0x1f, 0x8d, 0xfc, 0x71, 0x4b, 0x71, 0xbf, 0x06, 0x54, + 0xb1, 0x70, 0xe6, 0x02, 0x28, 0x0c, 0xb3, 0xbd, 0xbf, 0x75, 0x9f, 0x7a, 0xcb, 0x5f, 0xb6, 0x39, + 0xed, 0xc6, 0x87, 0x65, 0x01, 0xbe, 0xe2, 0x7b, 0xe9, 0xc3, 0x8a, 0x00, 0x3b, 0x46, 0x38, 0x73, + 0x0b, 0x5e, 0x87, 0x94, 0xe7, 0xb2, 0xa5, 0xbd, 0xe9, 0x00, 0x05, 0x70, 0x86, 0x16, 0x17, 0x0d, + 0xb3, 0xfb, 0xac, 0xfb, 0xcf, 0xa2, 0x5d, 0x2a, 0x7a, 0x62, 0x7b, 0xfc, 0x30, 0x36, 0x8b, 0x88, + 0x4c, 0x51, 0x0b, 0xe8, 0x25, 0xda, 0xc2, 0xea, 0xb1, 0x4a, 0xf3, 0xc0, 0x01, 0xe3, 0xd9, 0x89, + 0x60, 0x77, 0x6a, 0xf8, 0x58, 0xe8, 0x6a, 0x12, 0x64, 0x59, 0x06, 0x83, 0x3a, 0xb4, 0xde, 0xfc, + 0x6f, 0x29, 0x57, 0x52, 0xf1, 0x5a, 0xb5, 0xd5, 0x30, 0x8f, 0x56, 0x7c, 0xc6, 0x7b, 0xd4, 0x44, + 0x95, 0x4a, 0x0f, 0xab, 0xbf, 0x13, 0x10, 0x57, 0xc9, 0xfc, 0xf8, 0xfc, 0x20, 0x0b, 0xe5, 0xe6, + 0x60, 0x2b, 0x59, 0x06, 0xaf, 0x26, 0xe1, 0x66, 0xec, 0xaf, 0xc7, 0x50, 0x7f, 0x04, 0x70, 0x5e, + 0x5d, 0x82, 0x33, 0x20, 0x02, 0x4a, 0x49, 0x30, 0x3c, 0x48, 0xc2, 0x30, 0x7c, 0xf0, 0x75, 0x7f, + 0xac, 0xf0, 0xf4, 0xea, 0xd7, 0xbe, 0x26, 0x32, 0x79, 0xba, 0xa5, 0x87, 0x3b, 0x1a, 0xed, 0x23, + 0x2a, 0xb2, 0xd8, 0x64, 0x05, 0x68, 0x40, 0xe1, 0xc3, 0x40, 0xef, 0xad, 0x5c, 0x14, 0x0c, 0x38, + 0x1d, 0xc3, 0x52, 0x77, 0xd6, 0xda, 0x16, 0xdf, 0x78, 0xc9, 0xd5, 0x16, 0xeb, 0xa6, 0xd3, 0x23, + 0x7e, 0x18, 0x7d, 0x58, 0x8d, 0x0e, 0x20, 0x92, 0xd5, 0x1f, 0x89, 0x84, 0xf6, 0xfc, 0xdf, 0xc4, + 0x08, 0x2e, 0x6c, 0xf8, 0x60, 0x7d, 0xba, 0xdc, 0x5f, 0x06, 0x08, 0xa9, 0x2d, 0x6a, 0x56, 0x14, + 0x7b, 0xf8, 0x80, 0xc8, 0x78, 0x85, 0x2b, 0x22, 0x9a, 0xbe, 0xd9, 0x9d, 0x88, 0x76, 0x7e, 0xb2, + 0xa7, 0xda, 0xff, 0x84, 0x61, 0x48, 0x9c, 0x9c, 0xc2, 0x6e, 0x5f, 0x61, 0x1e, 0x4c, 0x1c, 0x47, + 0x9f, 0x82, 0x11, 0x09, 0xc9, 0x80, 0x90, 0x66, 0x49, 0x2d, 0x42, 0x80, 0x15, 0x70, 0x8e, 0xdc, + 0x3c, 0xe5, 0x26, 0xd2, 0x19, 0xa4, 0xe7, 0x02, 0xc1, 0x6c, 0xb0, 0x78, 0x90, 0x80, 0x2a, 0x2a, + 0x27, 0x1d, 0x3f, 0xbb, 0xde, 0xdd, 0xeb, 0xc3, 0x23, 0xe2, 0x1e, 0x9c, 0x65, 0xbb, 0xeb, 0x57, + 0x13, 0xe7, 0xef, 0x8a, 0x55, 0xe2, 0x42, 0x01, 0x02, 0x08, 0x3e, 0x4b, 0x00, 0xc4, 0x79, 0xc1, + 0xc2, 0xf3, 0xc3, 0xcb, 0x0c, 0xd0, 0xa9, 0x53, 0x8f, 0xc2, 0x22, 0x02, 0x35, 0x17, 0x26, 0x33, + 0xb7, 0x2f, 0x1e, 0x50, 0x2a, 0xe0, 0xb0, 0x3c, 0x00, 0xcf, 0x31, 0x43, 0xf1, 0x9c, 0x98, 0xb7, + 0x2f, 0x3d, 0xe7, 0x81, 0xc3, 0xf4, 0x3b, 0x87, 0xd9, 0x22, 0x3e, 0xbd, 0xbf, 0xbd, 0x21, 0x7e, + 0x30, 0x5b, 0xd7, 0xab, 0xbc, 0xdd, 0x65, 0xb8, 0xdc, 0x38, 0x16, 0x0b, 0x1e, 0x44, 0x47, 0xf0, + 0x1f, 0x10, 0x14, 0x10, 0xb2, 0x44, 0xd9, 0xa4, 0x94, 0x8e, 0x16, 0xcb, 0x34, 0x47, 0xea, 0xaa, + 0x69, 0x8f, 0x04, 0x05, 0x86, 0xc5, 0x6b, 0xf8, 0x81, 0x20, 0xa6, 0x5e, 0x1d, 0x53, 0x01, 0xd5, + 0x94, 0xb5, 0x55, 0x10, 0x70, 0x5e, 0x4a, 0x01, 0xfb, 0x5b, 0xa0, 0x15, 0xa9, 0x42, 0x3c, 0xc7, + 0x7b, 0xfc, 0x9b, 0xdf, 0xcc, 0x6d, 0x55, 0xf1, 0x5a, 0xd6, 0xb6, 0xdf, 0x08, 0x5d, 0xef, 0x7b, + 0xee, 0xeb, 0xb2, 0x6a, 0xa1, 0x2e, 0x2a, 0x28, 0xc4, 0xbc, 0x51, 0x9e, 0xf1, 0x5b, 0xfb, 0x57, + 0x88, 0x84, 0x4f, 0x15, 0xa6, 0x2b, 0x73, 0xff, 0x15, 0xc4, 0x3f, 0x12, 0x10, 0x08, 0xe2, 0xf1, + 0x27, 0xbd, 0xfe, 0xa7, 0xf2, 0xb0, 0xcb, 0x80, 0x17, 0x9f, 0xac, 0x10, 0xa8, 0xda, 0x43, 0x77, + 0xff, 0xf4, 0xf6, 0x58, 0xdc, 0x1b, 0x7d, 0x72, 0xfe, 0xfe, 0x4e, 0x11, 0x8e, 0x22, 0x6b, 0x8c, + 0x4d, 0x96, 0x62, 0xe9, 0x13, 0x05, 0xd4, 0x49, 0xc6, 0x7c, 0x4c, 0x29, 0x2f, 0x2c, 0xcb, 0xc4, + 0x70, 0xbd, 0xe5, 0x35, 0x9a, 0xdd, 0xec, 0xf1, 0x23, 0x2d, 0xe5, 0xbc, 0x57, 0x77, 0x76, 0x9c, + 0x53, 0x1a, 0xaa, 0x2b, 0xf8, 0x98, 0xf3, 0xb8, 0xad, 0xc5, 0x69, 0x17, 0x05, 0x67, 0x8c, 0x1f, + 0xae, 0x26, 0x32, 0x58, 0x4b, 0x76, 0xf5, 0x55, 0x17, 0x17, 0xc5, 0xc5, 0xe1, 0xb6, 0x60, 0x24, + 0x77, 0x1b, 0x9b, 0x99, 0x17, 0xb1, 0x09, 0xec, 0x22, 0x2c, 0x5b, 0x08, 0x48, 0x9e, 0xc2, 0x23, + 0xd6, 0x21, 0x22, 0x1f, 0x47, 0x07, 0x55, 0x92, 0x11, 0x36, 0x3c, 0x2f, 0xcd, 0xcd, 0xd4, 0x9c, + 0xbb, 0xdc, 0x67, 0x27, 0x55, 0x3f, 0x11, 0x93, 0xd6, 0x6d, 0xfc, 0x61, 0xc9, 0x85, 0x5b, 0x1d, + 0x26, 0x84, 0xb0, 0x26, 0x14, 0xba, 0x6d, 0x9a, 0x83, 0x58, 0x26, 0xa9, 0xdc, 0x67, 0xc1, 0x00, + 0x30, 0x18, 0x48, 0x84, 0x73, 0x51, 0x43, 0x17, 0x37, 0x50, 0xbd, 0x4b, 0x65, 0xca, 0xdf, 0x87, + 0x39, 0x0c, 0x60, 0x0b, 0xb3, 0x48, 0x37, 0xb7, 0x11, 0xeb, 0xfd, 0xfb, 0xef, 0xe6, 0xfb, 0x6d, + 0x8f, 0xbf, 0xf2, 0xe8, 0x2c, 0x03, 0xf9, 0xf0, 0xe3, 0x80, 0x01, 0xba, 0xa2, 0xc2, 0x5e, 0x47, + 0xbf, 0x45, 0xdd, 0x45, 0xc4, 0x0f, 0x06, 0x37, 0x0e, 0xfd, 0xb6, 0xe2, 0x11, 0x4a, 0x4a, 0xa4, + 0x95, 0xa3, 0x21, 0x73, 0x20, 0xec, 0xfd, 0x3a, 0xfd, 0xb7, 0x87, 0x30, 0x07, 0x71, 0x55, 0x4f, + 0x28, 0x26, 0xc9, 0xff, 0x6d, 0x6d, 0xac, 0x67, 0x1d, 0x14, 0x58, 0xf7, 0x1c, 0x75, 0xb6, 0xb1, + 0x47, 0x56, 0x8a, 0x80, 0xc1, 0x96, 0x00, 0xb4, 0x48, 0xd7, 0xec, 0xa8, 0x37, 0x8f, 0xfe, 0x47, + 0xe9, 0xdb, 0xe2, 0x44, 0x85, 0x37, 0x1d, 0xa8, 0x27, 0x45, 0x57, 0x50, 0xb0, 0xde, 0xbf, 0xd9, + 0x03, 0xec, 0x02, 0xf8, 0xd4, 0xb2, 0x07, 0x89, 0x54, 0x2a, 0xca, 0x00, 0x1e, 0xa6, 0x0a, 0x4b, + 0xd6, 0xa6, 0x23, 0xff, 0xfd, 0xab, 0x7b, 0x34, 0xd5, 0xd3, 0x4c, 0x3f, 0x6a, 0x4c, 0x39, 0xa8, + 0x55, 0xc5, 0x8e, 0x9f, 0xc4, 0x47, 0x11, 0x0d, 0x8c, 0x2c, 0xb5, 0x8d, 0xcf, 0xe4, 0x19, 0xe0, + 0x79, 0xde, 0x14, 0xec, 0xeb, 0xab, 0xec, 0x8e, 0xbe, 0x27, 0x36, 0x23, 0xe6, 0x2e, 0xee, 0x10, + 0xe4, 0x14, 0x29, 0xc8, 0xd2, 0x96, 0x70, 0xeb, 0x28, 0x00, 0x23, 0x34, 0x68, 0xc0, 0x1a, 0x3a, + 0x4a, 0x81, 0x79, 0x1b, 0x73, 0x7e, 0xd8, 0x2b, 0xf1, 0xf0, 0x7e, 0x68, 0x60, 0xdf, 0x0e, 0x04, + 0x3d, 0xa7, 0x50, 0x66, 0x66, 0xa9, 0x8c, 0xe9, 0xa7, 0xf8, 0x64, 0x40, 0x50, 0x82, 0x5c, 0x78, + 0xeb, 0xb0, 0xa4, 0xc5, 0x41, 0xcf, 0xc4, 0x0e, 0x4b, 0x06, 0x07, 0x7a, 0x8e, 0xd9, 0xe3, 0xc9, + 0x45, 0x0e, 0xb8, 0x91, 0x03, 0x63, 0x71, 0x50, 0x53, 0x7a, 0x49, 0xeb, 0xc9, 0x61, 0xa4, 0xf8, + 0x94, 0x2a, 0x28, 0x19, 0xe0, 0x1a, 0x07, 0xc4, 0xa7, 0x70, 0x78, 0x5c, 0xa2, 0x94, 0x66, 0x96, + 0xb8, 0xca, 0x23, 0x6b, 0xdd, 0x5d, 0x71, 0x01, 0x00, 0x58, 0x5d, 0xb1, 0x5e, 0x13, 0xc5, 0x62, + 0x12, 0x0b, 0xdb, 0x66, 0x4e, 0x10, 0x12, 0x30, 0xc3, 0x8a, 0xfc, 0x2c, 0x38, 0xf7, 0xcb, 0x7e, + 0x58, 0xa6, 0x03, 0xe7, 0xac, 0x13, 0x60, 0xb1, 0x69, 0x83, 0xce, 0xc1, 0x4a, 0x58, 0x7d, 0x8e, + 0x10, 0x0a, 0x17, 0x43, 0x54, 0x17, 0xd5, 0xc9, 0x66, 0x59, 0x85, 0x0a, 0x93, 0x85, 0x65, 0x3d, + 0x4b, 0x31, 0x69, 0x70, 0x56, 0xaf, 0x1f, 0x07, 0x13, 0x05, 0x33, 0xbf, 0x3b, 0xd4, 0x5f, 0xc9, + 0x3b, 0xa2, 0x1d, 0x95, 0x25, 0x09, 0x76, 0x7d, 0x57, 0x13, 0x9f, 0x90, 0x97, 0xbf, 0xbe, 0xef, + 0xe5, 0x17, 0x59, 0x31, 0xf2, 0x5d, 0xf0, 0x94, 0x30, 0x24, 0x12, 0x8a, 0x3e, 0x5e, 0x2f, 0x35, + 0x8c, 0x83, 0xf0, 0xde, 0x7b, 0xaf, 0xf0, 0x53, 0x67, 0xa3, 0x83, 0x52, 0x80, 0xfa, 0x1d, 0xe3, + 0xbf, 0x92, 0x33, 0xb7, 0x63, 0x88, 0x85, 0x0e, 0xd0, 0x69, 0x51, 0x49, 0x2b, 0x22, 0x0d, 0x2d, + 0xdc, 0xdd, 0x9d, 0x7d, 0x46, 0xb0, 0xec, 0x83, 0x89, 0x12, 0x09, 0x44, 0x1e, 0x78, 0xe1, 0x9e, + 0x92, 0x8c, 0x1b, 0x02, 0xba, 0x5b, 0xd0, 0xff, 0x24, 0x5c, 0x48, 0x53, 0x50, 0x59, 0x84, 0x29, + 0x47, 0x33, 0xd4, 0xbd, 0x0c, 0xd0, 0x66, 0xd1, 0x56, 0xdb, 0x21, 0x77, 0xe2, 0x21, 0xf2, 0xb1, + 0x9a, 0x3b, 0x63, 0x7a, 0x6d, 0xdc, 0x9e, 0xcd, 0x64, 0x85, 0x7c, 0x29, 0xdd, 0xef, 0x15, 0xd1, + 0xde, 0x10, 0xe4, 0x33, 0xdd, 0x2f, 0x29, 0xdd, 0xf2, 0x61, 0x12, 0xf7, 0x7f, 0xf1, 0x30, 0xde, + 0x20, 0xa2, 0x2b, 0x50, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x45, 0x22, 0xb1, 0x27, + 0xca, 0x67, 0xbd, 0x72, 0x56, 0xb1, 0x5c, 0xc7, 0x4d, 0x3f, 0xc1, 0x5f, 0x51, 0x78, 0x93, 0xf1, + 0x07, 0xc5, 0x3b, 0x41, 0x3f, 0x21, 0x16, 0xb1, 0x5c, 0xc7, 0xba, 0x65, 0xf8, 0x46, 0x30, 0xce, + 0xbe, 0xa9, 0xc9, 0xe9, 0xea, 0xab, 0xe3, 0x3b, 0xb1, 0xad, 0x68, 0x6d, 0xa2, 0x0b, 0xee, 0x0f, + 0x53, 0x77, 0xe2, 0x61, 0x18, 0xbf, 0xe3, 0xab, 0x7b, 0x7e, 0x24, 0x51, 0x6e, 0xe5, 0xc8, 0xa3, + 0x71, 0x5f, 0x84, 0x0a, 0xda, 0xf0, 0xca, 0x3e, 0xb4, 0x95, 0x70, 0x5f, 0xcc, 0x31, 0x57, 0x51, + 0x32, 0x5a, 0xeb, 0xc4, 0x0c, 0x3e, 0x7f, 0x7a, 0xa9, 0xd9, 0xb1, 0xeb, 0x5f, 0xf9, 0x49, 0x7b, + 0xe2, 0x75, 0x13, 0xf1, 0x00, 0xa3, 0x77, 0x69, 0xec, 0xfd, 0xc4, 0xe0, 0x93, 0x8b, 0xde, 0xef, + 0x77, 0x2f, 0x29, 0x6f, 0x72, 0x44, 0xd9, 0xef, 0x7f, 0x04, 0xe2, 0x8a, 0xf2, 0x72, 0x42, 0x55, + 0x55, 0x7b, 0xc4, 0x0b, 0x2e, 0x30, 0x63, 0xcb, 0xeb, 0x88, 0xa6, 0xfd, 0xdd, 0xc9, 0x88, 0x08, + 0x91, 0xa6, 0xb5, 0xad, 0xdf, 0xc4, 0xf8, 0x91, 0x1c, 0x4f, 0x89, 0xc1, 0x1f, 0x04, 0x7d, 0xdf, + 0xa7, 0x88, 0x90, 0x4c, 0x51, 0xab, 0x5c, 0x40, 0x2d, 0x26, 0xab, 0x75, 0x5e, 0xf8, 0x48, 0xab, + 0x65, 0x55, 0xfc, 0x20, 0x4d, 0xdd, 0xf7, 0x7b, 0xfc, 0x10, 0xe8, 0xeb, 0xd5, 0x13, 0xbf, 0x5c, + 0x10, 0x9b, 0x77, 0x7f, 0x94, 0xab, 0x18, 0x12, 0x39, 0xa1, 0x80, 0x89, 0x69, 0xca, 0xc4, 0x12, + 0xf0, 0x84, 0x5e, 0x2e, 0xb5, 0xad, 0x5b, 0xf9, 0x8f, 0x22, 0x5a, 0xf8, 0x2c, 0xdd, 0xdd, 0xb6, + 0x1b, 0xab, 0xbb, 0xde, 0xb9, 0x84, 0x56, 0xb8, 0x88, 0xe9, 0xba, 0xb6, 0xa2, 0xea, 0x4c, 0x94, + 0xf5, 0xf1, 0x33, 0x75, 0x74, 0x25, 0x33, 0x31, 0xe2, 0x66, 0xe2, 0x78, 0xda, 0xe8, 0xaf, 0x3c, + 0x20, 0x11, 0x31, 0xe3, 0xa9, 0x8f, 0xe0, 0xa4, 0x50, 0x3c, 0xf8, 0x3b, 0xf1, 0x0c, 0x1f, 0x05, + 0x27, 0xa7, 0x25, 0xbc, 0x6c, 0xd9, 0xb7, 0x08, 0x04, 0x61, 0x8e, 0x83, 0x7d, 0x19, 0x11, 0x1c, + 0x16, 0x11, 0xc5, 0x92, 0x9f, 0x9a, 0xcd, 0x92, 0x7e, 0x22, 0x6e, 0xab, 0x88, 0xbb, 0x19, 0xff, + 0xe0, 0xaf, 0x8a, 0xee, 0xee, 0xfb, 0x9d, 0x87, 0xf1, 0x21, 0x12, 0x63, 0x2b, 0x74, 0xdc, 0xf8, + 0xfc, 0xbf, 0xef, 0x99, 0x13, 0x4f, 0xd7, 0x42, 0xfa, 0x68, 0x90, 0x81, 0x86, 0x56, 0x4f, 0x89, + 0x10, 0x20, 0xb5, 0xeb, 0x05, 0xb2, 0xcb, 0x98, 0xe0, 0x84, 0xb1, 0xf6, 0xdc, 0xf1, 0xf5, 0x12, + 0x08, 0x01, 0x41, 0x75, 0x5d, 0x21, 0x0f, 0x63, 0xe1, 0x83, 0x60, 0x70, 0x30, 0x15, 0x46, 0x1c, + 0x00, 0x63, 0x36, 0x1e, 0x41, 0xe7, 0xaa, 0x85, 0x40, 0xed, 0x7e, 0x2a, 0xd4, 0x10, 0xf1, 0x87, + 0xab, 0x62, 0xeb, 0x5e, 0x9b, 0x8d, 0x2c, 0xb7, 0x4b, 0xf8, 0x92, 0x91, 0x6b, 0x5c, 0x77, 0x37, + 0x4c, 0x56, 0x58, 0xcf, 0x96, 0x1c, 0x70, 0x2d, 0xfc, 0x45, 0x90, 0x48, 0xe3, 0xf2, 0xf3, 0xe1, + 0x1e, 0x0a, 0x04, 0xa1, 0xaf, 0xf4, 0x4a, 0x54, 0xa1, 0x18, 0x6c, 0x9c, 0xb9, 0x1c, 0xfe, 0x37, + 0xd3, 0xc2, 0x20, 0x90, 0x89, 0x3f, 0xdf, 0x26, 0x21, 0xfe, 0x26, 0x0b, 0xa2, 0xa0, 0xf5, 0x8a, + 0x30, 0xf8, 0xe5, 0xe2, 0x5c, 0x2f, 0xb2, 0x01, 0xc3, 0x10, 0x20, 0x16, 0x65, 0xc1, 0x59, 0x60, + 0xe5, 0xe0, 0xda, 0xc3, 0xb9, 0xee, 0x3f, 0x27, 0xc9, 0x5e, 0x24, 0x30, 0x14, 0xc8, 0xba, 0xd6, + 0xa5, 0x52, 0xf5, 0x17, 0x51, 0x72, 0x30, 0xa4, 0x15, 0x96, 0xdb, 0xb8, 0x40, 0x14, 0x05, 0x32, + 0x66, 0x4a, 0x5c, 0x08, 0xe9, 0xa9, 0x99, 0x96, 0xa9, 0xe3, 0x22, 0x6f, 0x8d, 0x63, 0x57, 0x23, + 0x88, 0x2b, 0x1a, 0xdd, 0x1f, 0xfe, 0x49, 0xcf, 0x71, 0xd8, 0xf8, 0x67, 0x94, 0xaf, 0xb8, 0x9e, + 0x13, 0xb9, 0xa8, 0xbd, 0x6b, 0xe4, 0x8d, 0x2c, 0xdb, 0x6b, 0xbb, 0xbf, 0xe1, 0x2b, 0x5a, 0xae, + 0xa4, 0xe2, 0xa9, 0x96, 0x29, 0xb9, 0x86, 0xdc, 0xc9, 0xd9, 0xfc, 0xb7, 0xbf, 0x11, 0x11, 0xbd, + 0xc9, 0x82, 0x9d, 0xa5, 0x89, 0x12, 0x0b, 0x08, 0xef, 0x7d, 0xb5, 0xcd, 0x9c, 0x38, 0x40, 0x4a, + 0xc7, 0x3c, 0x48, 0x62, 0xa6, 0xc4, 0xb6, 0x95, 0x32, 0xfb, 0xd2, 0x93, 0x6d, 0x4f, 0xbf, 0x0a, + 0x67, 0x31, 0x7a, 0xf8, 0x87, 0xae, 0xde, 0xd3, 0x9b, 0xa5, 0x5e, 0x32, 0xd5, 0x6a, 0x17, 0xa4, + 0x91, 0xef, 0x77, 0xf3, 0x98, 0x3b, 0x68, 0xd6, 0x9a, 0xd5, 0xc4, 0xfc, 0x40, 0x53, 0x7b, 0xc4, + 0x44, 0xb3, 0xa0, 0x57, 0x5a, 0xcf, 0xa7, 0x5c, 0x32, 0x14, 0x8a, 0xaf, 0x04, 0x20, 0x0f, 0xd7, + 0x27, 0xb8, 0xff, 0x55, 0x26, 0x0c, 0xfb, 0xd9, 0xc2, 0x00, 0xa4, 0x16, 0x55, 0x74, 0xb0, 0x09, + 0x0b, 0xcd, 0x79, 0xcd, 0x00, 0xbe, 0x0f, 0x60, 0x5d, 0x32, 0x35, 0xe9, 0xf7, 0xdd, 0xc6, 0x11, + 0xc1, 0x57, 0x11, 0xbd, 0x3d, 0x36, 0xd3, 0x7c, 0x92, 0xb0, 0x95, 0xf8, 0x92, 0xc4, 0x60, 0xa9, + 0x2e, 0x20, 0x22, 0x08, 0x8e, 0xfd, 0xdf, 0xee, 0xdb, 0xaf, 0xc5, 0x11, 0x0e, 0x8d, 0x8c, 0x69, + 0xf7, 0x71, 0xa5, 0xf1, 0xb5, 0x1d, 0x54, 0xbb, 0x08, 0x05, 0x7a, 0x05, 0x06, 0xc6, 0xb4, 0x1e, + 0xcc, 0xe1, 0xe5, 0xe5, 0xa8, 0xb0, 0x19, 0x60, 0xda, 0x10, 0xb1, 0x06, 0x9b, 0xb7, 0xf8, 0x81, + 0x21, 0x4c, 0xce, 0xb0, 0x2f, 0x73, 0x65, 0x47, 0x8f, 0x24, 0x6a, 0x3c, 0x00, 0x79, 0x63, 0xd2, + 0x2d, 0x16, 0xb2, 0xc1, 0x3c, 0x48, 0x29, 0xb8, 0xae, 0x21, 0xfb, 0xbb, 0x07, 0x09, 0xb9, 0x1b, + 0x8c, 0x48, 0x92, 0x4d, 0x4d, 0x78, 0x90, 0x42, 0x26, 0xe8, 0x79, 0x3c, 0x15, 0x72, 0x88, 0xbb, + 0xc9, 0x10, 0x10, 0x26, 0xdd, 0xf1, 0x36, 0x55, 0x5f, 0xcd, 0xac, 0xdf, 0xc2, 0x26, 0x10, 0x3c, + 0x95, 0x51, 0x00, 0xf3, 0xc0, 0x7a, 0xe6, 0x7c, 0xa8, 0x1d, 0x2e, 0x88, 0x29, 0x3c, 0x22, 0x18, + 0x08, 0x14, 0x39, 0xc9, 0x4e, 0xf3, 0x81, 0xc6, 0xe9, 0x23, 0x42, 0xc6, 0xe1, 0xc9, 0xf8, 0x2b, + 0x15, 0xbf, 0x0b, 0x7c, 0x20, 0x14, 0x23, 0x36, 0xd6, 0x59, 0xa2, 0xf4, 0xb3, 0x17, 0x51, 0x1c, + 0xd9, 0xdd, 0xe9, 0x7c, 0x48, 0x52, 0xaf, 0x27, 0x4e, 0xfa, 0x8d, 0x64, 0x56, 0xf6, 0xea, 0xfc, + 0xa8, 0x66, 0x49, 0xa6, 0x64, 0x7f, 0x12, 0x08, 0xca, 0x1f, 0xad, 0xd7, 0x59, 0x77, 0xca, 0xe5, + 0xe2, 0x15, 0xc8, 0x2d, 0x82, 0x81, 0x22, 0xae, 0xdf, 0x1e, 0xf0, 0x6a, 0x99, 0xad, 0x30, 0x70, + 0x10, 0x05, 0x7c, 0xb8, 0x90, 0xef, 0x75, 0x0b, 0x0b, 0xf9, 0xf0, 0x67, 0xb0, 0x5d, 0xa9, 0x9f, + 0xc2, 0x02, 0xc8, 0x1c, 0x07, 0xc3, 0x3b, 0xea, 0x22, 0x58, 0x89, 0x98, 0x6d, 0xec, 0xea, 0x58, + 0xfb, 0xe1, 0x01, 0xfd, 0xde, 0x2b, 0x2f, 0xad, 0xce, 0x90, 0x22, 0x27, 0x49, 0x72, 0x6a, 0x71, + 0x24, 0x84, 0x42, 0x49, 0x1e, 0x05, 0xe1, 0x6d, 0xce, 0x20, 0x29, 0x2c, 0x65, 0xbd, 0xcb, 0x6e, + 0xf0, 0xa8, 0x72, 0x76, 0x25, 0x3c, 0x1c, 0xe0, 0x94, 0x75, 0x60, 0x38, 0x96, 0x15, 0x2b, 0x32, + 0x80, 0x1f, 0xe9, 0x0d, 0xee, 0x20, 0x48, 0x50, 0xad, 0xc7, 0x6a, 0x0c, 0x8e, 0x8f, 0xe4, 0x8d, + 0x0b, 0x64, 0xc5, 0x64, 0xa0, 0x76, 0x4c, 0xcb, 0x15, 0xee, 0x9d, 0x78, 0xed, 0xd3, 0x89, 0xb2, + 0xdd, 0x1d, 0x40, 0xfe, 0xbb, 0xf8, 0xce, 0x72, 0x41, 0x77, 0x83, 0xfe, 0x2a, 0x3d, 0x19, 0x7c, + 0x4f, 0x59, 0x35, 0x88, 0xc9, 0xc5, 0x95, 0xfe, 0xe2, 0x3d, 0xf8, 0x25, 0xe4, 0xaa, 0xe5, 0xe6, + 0xf1, 0xff, 0xf8, 0xb2, 0x3e, 0xad, 0x26, 0xfe, 0x4d, 0x6b, 0x82, 0x18, 0x29, 0x81, 0x61, 0x30, + 0x46, 0x93, 0x00, 0x01, 0x4f, 0x07, 0x38, 0x25, 0x78, 0x3d, 0xc1, 0x5c, 0xe3, 0xd3, 0x38, 0xd0, + 0xbd, 0x55, 0xf8, 0x98, 0xf9, 0xcc, 0x06, 0xb0, 0x63, 0xf1, 0xc4, 0x07, 0x87, 0xac, 0xc0, 0xdc, + 0x3e, 0x93, 0x00, 0x0a, 0xcb, 0x1e, 0x18, 0x12, 0x32, 0x5d, 0x61, 0xf4, 0x73, 0xce, 0x01, 0xc6, + 0xf6, 0xcf, 0x7e, 0xfc, 0x7e, 0x69, 0x3f, 0x47, 0x15, 0xdc, 0xbf, 0x0c, 0x09, 0x0a, 0x42, 0x85, + 0x41, 0x85, 0x78, 0x0f, 0xb2, 0xca, 0x28, 0x99, 0xe0, 0xf7, 0x2b, 0xb6, 0x33, 0xe9, 0x5e, 0xc9, + 0x77, 0x75, 0xa4, 0xee, 0x86, 0xec, 0xe2, 0x41, 0x49, 0xc9, 0xd7, 0xaa, 0xe0, 0xdf, 0x96, 0x1d, + 0x46, 0xa7, 0x0e, 0x22, 0xbe, 0x22, 0x14, 0x36, 0xa6, 0x92, 0xde, 0x73, 0xd2, 0xe5, 0xee, 0xde, + 0x4a, 0x0a, 0x9e, 0xa8, 0x2c, 0x00, 0x67, 0x80, 0x2a, 0x25, 0xe2, 0x41, 0x65, 0xee, 0xc7, 0x89, + 0x1e, 0xf9, 0xff, 0xdc, 0x47, 0xe3, 0xeb, 0x56, 0xa2, 0x4e, 0x36, 0x4b, 0x57, 0xdf, 0x88, 0x08, + 0x82, 0x9a, 0xa9, 0xc7, 0x0b, 0x34, 0xd7, 0x8b, 0xd7, 0xfe, 0x24, 0x14, 0x9c, 0xd9, 0x6d, 0x55, + 0x54, 0x9e, 0xe0, 0xd2, 0x7e, 0x1b, 0xf1, 0xfe, 0x1b, 0xe5, 0x32, 0xae, 0xb1, 0x11, 0x5c, 0xa2, + 0xeb, 0x55, 0xca, 0x29, 0x6a, 0xbe, 0x13, 0x8e, 0x8a, 0x5f, 0xea, 0xbe, 0x09, 0x30, 0x39, 0xda, + 0x83, 0x4b, 0xa1, 0xc0, 0x00, 0x67, 0x05, 0x43, 0x88, 0x12, 0x14, 0xb4, 0x27, 0xc4, 0xf9, 0xe0, + 0x1e, 0x20, 0x98, 0x80, 0xb3, 0xcb, 0x04, 0xd5, 0xf2, 0xc0, 0x0c, 0xe0, 0x00, 0xf1, 0x9e, 0xe1, + 0xeb, 0x0e, 0x0f, 0x43, 0x66, 0x7f, 0x38, 0x91, 0x04, 0xbb, 0xb8, 0x87, 0xe2, 0x42, 0x03, 0x34, + 0xe5, 0xe7, 0x3a, 0x70, 0x62, 0xf3, 0x18, 0xd7, 0x5d, 0x13, 0xb7, 0x89, 0x08, 0x85, 0x2d, 0x48, + 0x5b, 0x25, 0x55, 0xf8, 0x2b, 0x15, 0x9e, 0x30, 0x39, 0xcd, 0x47, 0x17, 0x2f, 0x28, 0x8b, 0x28, + 0xe0, 0x9b, 0x98, 0xfc, 0x23, 0x1b, 0x0e, 0x71, 0xaa, 0x27, 0xe2, 0xab, 0xf1, 0x69, 0xe1, 0x69, + 0x98, 0x89, 0x6d, 0x33, 0xf6, 0xee, 0xe2, 0xb4, 0x43, 0xf3, 0x8e, 0x9e, 0x5c, 0x79, 0x76, 0xad, + 0x61, 0x98, 0x52, 0xca, 0x40, 0x76, 0xe1, 0x43, 0x93, 0xb6, 0xb0, 0xfc, 0x96, 0x9c, 0xe1, 0xa0, + 0x81, 0xc6, 0xb1, 0xcb, 0xc0, 0x6f, 0xf1, 0xa0, 0x13, 0xc4, 0x02, 0xb9, 0x3a, 0xb4, 0x62, 0x88, + 0xb2, 0x8e, 0xb2, 0x7f, 0xbb, 0x34, 0x8b, 0xfb, 0x6f, 0xc4, 0x88, 0x15, 0xbb, 0xbd, 0xd7, 0x89, + 0x12, 0x0a, 0xef, 0xba, 0x56, 0x8d, 0x82, 0xe4, 0xf2, 0xec, 0x7f, 0x12, 0x32, 0xee, 0x5f, 0x75, + 0xb1, 0xee, 0xb4, 0x55, 0xf0, 0x88, 0xff, 0x52, 0x49, 0x3e, 0xf6, 0x9f, 0xe2, 0x44, 0xe2, 0xb8, + 0x83, 0xf8, 0x22, 0xe6, 0x8b, 0xd6, 0x5e, 0x42, 0x3a, 0x5f, 0x96, 0xb5, 0xae, 0x4d, 0x85, 0x01, + 0x40, 0x74, 0x7c, 0x30, 0x08, 0x46, 0x13, 0xbb, 0x14, 0x7b, 0x7e, 0xf7, 0x2d, 0x51, 0xd6, 0x0f, + 0x16, 0x60, 0xa4, 0x32, 0x11, 0xe2, 0xb1, 0x58, 0xad, 0xdf, 0x9b, 0x83, 0x7e, 0x60, 0x76, 0xb8, + 0xa3, 0xb2, 0xc2, 0x02, 0x06, 0x52, 0x6c, 0x0e, 0xf2, 0xa6, 0xd4, 0xc6, 0x55, 0x52, 0x9e, 0xeb, + 0x65, 0x34, 0x64, 0x68, 0x91, 0xbb, 0xab, 0xf5, 0xe2, 0x44, 0x0d, 0xcd, 0x2e, 0xa6, 0xa0, 0x48, + 0x43, 0x53, 0x40, 0x46, 0x60, 0x60, 0xd3, 0x5d, 0xfb, 0x60, 0xfc, 0xd7, 0x3f, 0xd3, 0x9b, 0xf1, + 0x10, 0x84, 0x19, 0x97, 0x6d, 0x73, 0x77, 0xd4, 0x5f, 0x12, 0x20, 0x16, 0x16, 0x3b, 0xe7, 0xbb, + 0xbb, 0xc5, 0x6e, 0x71, 0x21, 0x80, 0xa1, 0x01, 0x81, 0xb2, 0xd2, 0xea, 0x87, 0xb8, 0x5b, 0xe1, + 0x57, 0x23, 0x58, 0x6b, 0xb4, 0xdd, 0xf0, 0xe2, 0x02, 0x8e, 0x58, 0xc4, 0x41, 0x31, 0x6d, 0xdd, + 0xe0, 0xc0, 0x6c, 0x4f, 0x15, 0x40, 0xcd, 0xd1, 0x2c, 0x77, 0xca, 0x72, 0x7a, 0x9e, 0xd8, 0x8d, + 0x0b, 0xf8, 0xb3, 0xc4, 0x99, 0x47, 0x93, 0x02, 0xbd, 0xe7, 0x25, 0xca, 0xff, 0x12, 0x0e, 0x01, + 0x67, 0x55, 0x24, 0x7c, 0x3f, 0xd7, 0x67, 0x2b, 0x03, 0x9c, 0x4a, 0x64, 0xf0, 0xc0, 0x60, 0xf8, + 0x54, 0x35, 0x57, 0xa8, 0x17, 0x70, 0x24, 0x07, 0x61, 0x2a, 0x20, 0x92, 0xfc, 0x43, 0xa2, 0x07, + 0x41, 0x07, 0x37, 0x8a, 0xc4, 0xf2, 0x6b, 0x5f, 0x09, 0x73, 0xb6, 0x4c, 0x72, 0x47, 0xf2, 0x71, + 0xef, 0x3a, 0x84, 0x89, 0x10, 0x4a, 0xff, 0x0d, 0x4c, 0xe5, 0xbf, 0x12, 0x24, 0x12, 0x90, 0xb7, + 0xc3, 0xdc, 0xc6, 0xe3, 0x22, 0xb7, 0x22, 0x8e, 0x20, 0x40, 0x2e, 0x8a, 0xc5, 0x62, 0x1c, 0xa3, + 0x93, 0xf5, 0xc2, 0x11, 0x05, 0xb9, 0x3e, 0xf7, 0xe1, 0x08, 0xf3, 0x36, 0x9d, 0x3d, 0x0c, 0x7a, + 0xdd, 0xdf, 0xc4, 0x0c, 0x13, 0xc4, 0xe3, 0x10, 0xb0, 0xe0, 0x7b, 0xc1, 0xc9, 0x60, 0x63, 0x3d, + 0x3f, 0x8f, 0x7c, 0x7b, 0xe5, 0x83, 0x8a, 0xed, 0x56, 0x42, 0x1c, 0xae, 0x1c, 0x46, 0x00, 0x6d, + 0x1d, 0xa0, 0xaf, 0x23, 0xe7, 0xd6, 0xad, 0xf2, 0x4c, 0x0f, 0xa5, 0xeb, 0x71, 0xa7, 0x1a, 0xe7, + 0x32, 0xba, 0x4e, 0x02, 0xe3, 0x4f, 0xa6, 0x9f, 0x83, 0x81, 0xbe, 0x92, 0x80, 0x6b, 0xc1, 0x30, + 0x2c, 0x04, 0xf9, 0x14, 0x5d, 0xc7, 0x70, 0xa9, 0x7f, 0xa8, 0x86, 0xf2, 0x58, 0x00, 0x55, 0x21, + 0x94, 0x01, 0xaa, 0x9c, 0x13, 0xaa, 0xab, 0x5a, 0x4a, 0x22, 0xfa, 0x3c, 0xdc, 0xaf, 0x02, 0x28, + 0x43, 0x00, 0x73, 0x30, 0xeb, 0xe8, 0xdf, 0x06, 0xcd, 0x23, 0xf2, 0x45, 0x21, 0x18, 0x2b, 0x2c, + 0x52, 0x7c, 0x40, 0x7e, 0x14, 0xe3, 0x88, 0x5c, 0x94, 0x01, 0x55, 0x4a, 0x43, 0x0d, 0x49, 0x41, + 0x5c, 0x6b, 0x22, 0xd6, 0x05, 0xc1, 0xe4, 0xcc, 0xc0, 0x17, 0x20, 0xd0, 0x84, 0x9b, 0xe1, 0xb6, + 0x3a, 0xbd, 0x4f, 0x78, 0x29, 0x07, 0x01, 0x4a, 0x6d, 0xa8, 0xb9, 0x3e, 0x3b, 0x28, 0x49, 0x68, + 0x7b, 0x73, 0x19, 0x72, 0xfd, 0xc2, 0x20, 0xc0, 0x66, 0xed, 0x35, 0x77, 0x8f, 0x0f, 0x07, 0x9e, + 0x2f, 0x5c, 0xe7, 0x11, 0x5a, 0xf0, 0xdc, 0x0d, 0x61, 0x51, 0x85, 0xae, 0x48, 0x6e, 0x15, 0x40, + 0x4f, 0x4e, 0x3c, 0x63, 0xf2, 0xc3, 0x20, 0x68, 0x1b, 0xba, 0xac, 0x7d, 0x54, 0xf3, 0xc4, 0xd8, + 0x90, 0xb1, 0x59, 0x27, 0x2f, 0x76, 0x07, 0x70, 0x94, 0x01, 0x7e, 0x2d, 0xfe, 0x1c, 0x50, 0x03, + 0x3f, 0x49, 0xe4, 0x70, 0x5f, 0xff, 0x77, 0x5e, 0xca, 0xa5, 0xd6, 0x72, 0xec, 0x3e, 0x94, 0x58, + 0xc3, 0x2e, 0xdc, 0x6c, 0xca, 0x3b, 0x5f, 0xe0, 0x50, 0x05, 0x93, 0x63, 0x42, 0x6c, 0x16, 0x72, + 0xb2, 0x30, 0xa7, 0xd8, 0x99, 0xf4, 0x35, 0xc8, 0x77, 0x7d, 0xf1, 0xc6, 0x53, 0x9c, 0xd5, 0x97, + 0x2c, 0xa9, 0x09, 0x89, 0x10, 0x43, 0xc0, 0x72, 0x34, 0x2f, 0x7c, 0x48, 0x44, 0x22, 0x21, 0xef, + 0x5b, 0x63, 0x4b, 0x72, 0x6a, 0xb7, 0xe2, 0x20, 0x9e, 0xdc, 0x75, 0x31, 0xd8, 0x55, 0x5b, 0x54, + 0x3b, 0xc4, 0xfc, 0x34, 0x78, 0x0e, 0xe6, 0x00, 0x12, 0xc8, 0xb8, 0x44, 0x5a, 0x00, 0x92, 0xe2, + 0xf5, 0x8b, 0xf0, 0xe2, 0x84, 0x07, 0x82, 0xb6, 0xed, 0xf9, 0xed, 0xe5, 0x3c, 0xf0, 0xb5, 0xec, + 0x8d, 0x4b, 0x45, 0xa0, 0xb7, 0x24, 0xb9, 0x64, 0xb9, 0x74, 0xa5, 0x1d, 0xb7, 0x3e, 0x1d, 0x4f, + 0xa8, 0x63, 0x6a, 0xfc, 0x48, 0x40, 0x6d, 0xd2, 0x60, 0xf0, 0x18, 0x5d, 0x40, 0xa7, 0xc3, 0xdc, + 0x3b, 0xfd, 0x47, 0x94, 0x7f, 0x87, 0x79, 0xfe, 0x4d, 0xa5, 0x65, 0xe4, 0xfc, 0x2e, 0x2d, 0x5a, + 0x3b, 0xd1, 0xe6, 0xef, 0xb4, 0xf8, 0x40, 0x48, 0x6e, 0x52, 0x58, 0xb6, 0x66, 0x51, 0x71, 0xf4, + 0x4f, 0xf8, 0x80, 0x52, 0x58, 0x92, 0x77, 0x81, 0x65, 0x3d, 0x0f, 0x89, 0x79, 0x6e, 0xd3, 0x3c, + 0x18, 0x02, 0x51, 0x5d, 0xee, 0xf1, 0x74, 0x85, 0x19, 0x6e, 0x10, 0x04, 0x00, 0xa6, 0x26, 0xc0, + 0x20, 0x63, 0x05, 0xba, 0x47, 0x4a, 0x16, 0x06, 0x4a, 0x07, 0x7c, 0x53, 0x21, 0xc2, 0x3c, 0x35, + 0x51, 0xaa, 0x70, 0x40, 0x0a, 0x02, 0x96, 0x7a, 0xd9, 0xaf, 0x76, 0x96, 0xf3, 0xa7, 0x08, 0x02, + 0x81, 0x17, 0x66, 0xf3, 0xe1, 0x65, 0x6b, 0x08, 0x46, 0x45, 0x14, 0x13, 0xf4, 0x89, 0x8e, 0x38, + 0x3d, 0xf5, 0xfa, 0xbb, 0xf2, 0xe2, 0x56, 0xb7, 0x34, 0xaa, 0xc1, 0x00, 0x40, 0x29, 0xac, 0x17, + 0xaa, 0x96, 0x7f, 0x09, 0x3a, 0x13, 0x70, 0x5d, 0x20, 0x01, 0xe3, 0xcb, 0x11, 0x97, 0xc5, 0x18, + 0xef, 0x95, 0x6e, 0x20, 0x10, 0x0e, 0x28, 0x73, 0x4a, 0xdc, 0xea, 0xe1, 0xde, 0x5e, 0xa9, 0x70, + 0x50, 0x08, 0x01, 0x49, 0x04, 0x1f, 0xaa, 0x9f, 0x2d, 0x20, 0x8d, 0x63, 0x2e, 0x17, 0x13, 0x2f, + 0x0b, 0x1f, 0x74, 0x60, 0x62, 0x10, 0x98, 0x60, 0xec, 0x80, 0x94, 0xc0, 0x6b, 0x8b, 0xfc, 0x67, + 0x56, 0x85, 0x78, 0x24, 0xaa, 0xaf, 0xa5, 0x89, 0x12, 0x0b, 0x0c, 0x3c, 0xfe, 0x89, 0xc6, 0x69, + 0xfe, 0x07, 0x62, 0xa6, 0x1e, 0x24, 0x11, 0xfc, 0xbd, 0xfc, 0x40, 0x2a, 0x2a, 0x49, 0x1c, 0x82, + 0x7a, 0x63, 0x66, 0x58, 0x61, 0xb0, 0x56, 0x58, 0xf3, 0xed, 0x85, 0x28, 0x92, 0x24, 0x22, 0x0b, + 0x22, 0xf7, 0xdc, 0x3c, 0xcb, 0xa5, 0xc7, 0x49, 0xc3, 0x2f, 0x89, 0xac, 0x53, 0xa6, 0x12, 0xf7, + 0x0c, 0x82, 0x11, 0x9c, 0x36, 0x6b, 0x36, 0x82, 0xf5, 0x10, 0x70, 0xa9, 0x0b, 0xdc, 0x83, 0xa2, + 0xc3, 0x54, 0x24, 0x17, 0x2c, 0x54, 0xda, 0x40, 0x7c, 0x12, 0x87, 0xba, 0x40, 0xe0, 0x25, 0xe1, + 0x00, 0x53, 0xa0, 0xd8, 0x30, 0xec, 0x02, 0xf0, 0xe8, 0x0a, 0x8b, 0x24, 0xaf, 0xd7, 0x24, 0xfc, + 0x4b, 0x1c, 0x48, 0x60, 0x54, 0x2a, 0xe4, 0x3a, 0xf3, 0x17, 0x2e, 0x7e, 0x20, 0x10, 0x0c, 0x87, + 0x1b, 0x53, 0x54, 0x6a, 0x59, 0x93, 0x56, 0xf5, 0x09, 0xe4, 0xee, 0x56, 0x47, 0x45, 0xcd, 0x87, + 0x87, 0xe2, 0x41, 0x47, 0x10, 0x18, 0x08, 0xde, 0xd7, 0x55, 0x55, 0xf8, 0x21, 0x0a, 0x5e, 0x12, + 0xc9, 0x27, 0xf9, 0x30, 0x99, 0x24, 0xe1, 0xa3, 0xb5, 0xdc, 0xe3, 0xc5, 0x55, 0xc3, 0x5a, 0xe7, + 0x71, 0xe2, 0xe0, 0x23, 0xf0, 0x80, 0x64, 0x29, 0xe5, 0xc2, 0xec, 0x4f, 0xc4, 0xfb, 0xbb, 0xf2, + 0xb3, 0x9c, 0x93, 0x6d, 0x57, 0x82, 0x00, 0xa4, 0xe1, 0xcb, 0x5f, 0xed, 0x21, 0x68, 0xd8, 0xec, + 0x2d, 0x9b, 0x8a, 0xeb, 0x3f, 0xce, 0x3c, 0x76, 0xe7, 0x1f, 0x2c, 0x39, 0x38, 0x03, 0x92, 0xf6, + 0xb7, 0x90, 0xcb, 0xf1, 0x2f, 0xc5, 0x8b, 0x8c, 0xf0, 0x07, 0x5f, 0x07, 0x6f, 0xa7, 0x9e, 0x09, + 0xb7, 0xab, 0x6c, 0xf8, 0xbd, 0x52, 0x57, 0xf8, 0x26, 0xc4, 0x10, 0xd3, 0xb9, 0xf9, 0x2e, 0xee, + 0xf8, 0x46, 0x0b, 0x2b, 0x34, 0x9e, 0xad, 0x5a, 0x6a, 0xe3, 0xc3, 0x70, 0xed, 0x66, 0x70, 0x2c, + 0x82, 0xb9, 0x43, 0x92, 0x71, 0x3f, 0xf7, 0x10, 0x11, 0x1c, 0x48, 0xa2, 0x4f, 0x2c, 0xc4, 0xcb, + 0x73, 0x30, 0x6c, 0x9c, 0x48, 0x81, 0x9d, 0x31, 0x98, 0x5b, 0xb1, 0xd5, 0xce, 0x03, 0x85, 0xf0, + 0xad, 0xdb, 0x51, 0x71, 0x27, 0x0f, 0x0e, 0x62, 0x42, 0x00, 0xac, 0xac, 0xf7, 0x31, 0x1e, 0xa4, + 0xc1, 0x53, 0xf8, 0x6f, 0x95, 0xee, 0x24, 0x20, 0x32, 0x2e, 0xaa, 0xc9, 0x55, 0xb4, 0x04, 0xa4, + 0xe6, 0xdc, 0x3a, 0xe5, 0x26, 0x2a, 0x05, 0xd8, 0x16, 0x1e, 0x42, 0x01, 0x47, 0x3a, 0x6c, 0x48, + 0x80, 0x8e, 0xa9, 0xa4, 0xce, 0x88, 0x85, 0x00, 0x4a, 0x30, 0x64, 0xa5, 0xf7, 0xf0, 0x91, 0x78, + 0xd6, 0x4f, 0xbe, 0x11, 0x85, 0x08, 0xab, 0x35, 0xae, 0xcc, 0x76, 0xf0, 0x51, 0x76, 0x43, 0x41, + 0x22, 0x28, 0x95, 0x10, 0xf7, 0x71, 0x21, 0x81, 0x9a, 0xae, 0x43, 0xcc, 0x09, 0x67, 0x9f, 0x52, + 0x74, 0xcb, 0xad, 0xac, 0x10, 0x81, 0x64, 0x23, 0x4d, 0xbb, 0x6a, 0x6d, 0x17, 0xe6, 0xe2, 0xda, + 0xea, 0x62, 0x68, 0xfa, 0x85, 0xb9, 0x09, 0xaa, 0xae, 0x8a, 0xf0, 0x8f, 0x26, 0x1a, 0x1e, 0xfe, + 0xc4, 0x1e, 0xf2, 0x92, 0x31, 0x54, 0xae, 0x24, 0x40, 0x50, 0xb5, 0x3a, 0x59, 0xbd, 0xca, 0xfc, + 0x8c, 0x29, 0x98, 0xe3, 0x78, 0xbc, 0x32, 0x32, 0xe2, 0xbf, 0x0a, 0xd7, 0x2d, 0xcf, 0xee, 0x7e, + 0x25, 0xca, 0xe1, 0x97, 0x00, 0x3d, 0x94, 0xd1, 0x62, 0xce, 0x8c, 0x4f, 0xd9, 0x9d, 0x9e, 0xe4, + 0xe6, 0xa3, 0x8d, 0xe3, 0x39, 0xa3, 0xe1, 0x2d, 0xfc, 0x40, 0xf8, 0x87, 0x8e, 0xc7, 0xf1, 0x22, + 0x02, 0x84, 0x2d, 0x61, 0x4a, 0xd2, 0x6b, 0x2c, 0xa2, 0x68, 0xac, 0x81, 0x62, 0x38, 0x38, 0xf0, + 0x1c, 0x2f, 0xf5, 0xa4, 0xd7, 0xdc, 0x30, 0x24, 0x29, 0x78, 0x00, 0x08, 0x61, 0x60, 0x61, 0xf0, + 0x4a, 0xca, 0x06, 0x05, 0x4b, 0xbc, 0x96, 0x66, 0xf9, 0x3b, 0x76, 0xcf, 0x04, 0x78, 0x90, 0x42, + 0x30, 0xe2, 0x1c, 0x24, 0x15, 0x12, 0xe1, 0x60, 0xce, 0x70, 0xb0, 0x2c, 0x19, 0xee, 0xe2, 0xb1, + 0x95, 0x57, 0x90, 0x85, 0x8d, 0xf8, 0xfc, 0x40, 0x43, 0x17, 0x69, 0x38, 0xac, 0xec, 0x16, 0x31, + 0x00, 0xe0, 0x80, 0x70, 0xf0, 0x70, 0x94, 0x07, 0xd8, 0x88, 0xc9, 0x26, 0xcb, 0x3a, 0x8a, 0xf6, + 0x53, 0xe5, 0xf9, 0x3d, 0x65, 0x4d, 0xc5, 0x39, 0x17, 0xc4, 0x08, 0x18, 0x60, 0xd0, 0x1e, 0xca, + 0x21, 0x2a, 0x22, 0xa0, 0xb6, 0xe6, 0x23, 0x96, 0xe9, 0x21, 0xc5, 0x97, 0xb3, 0xf1, 0xc1, 0x74, + 0x44, 0x71, 0x64, 0xc9, 0x73, 0x79, 0x7a, 0x6d, 0x61, 0x3f, 0x08, 0x86, 0x04, 0xee, 0x5b, 0x3f, + 0x15, 0xdb, 0xbe, 0x10, 0x04, 0x03, 0x22, 0x7c, 0x50, 0xc4, 0xf9, 0x61, 0x88, 0xf3, 0xdc, 0x2c, + 0x33, 0xce, 0x31, 0xc9, 0xae, 0x0c, 0x52, 0x9c, 0x72, 0x35, 0xf7, 0x70, 0xc8, 0x91, 0xdc, 0x5c, + 0xcc, 0x09, 0x70, 0x1d, 0x78, 0x7f, 0x9e, 0x69, 0x25, 0x99, 0x7f, 0x12, 0x10, 0x19, 0x76, 0x4b, + 0xcd, 0x8d, 0x08, 0x7e, 0xd0, 0xbc, 0x8b, 0xad, 0x61, 0x0a, 0xae, 0x31, 0x02, 0x46, 0x5f, 0xcf, + 0x70, 0xf0, 0x60, 0xad, 0x6b, 0x2b, 0x55, 0x2c, 0xbb, 0x4f, 0x1c, 0x21, 0x84, 0xa7, 0xf2, 0xc9, + 0x01, 0xad, 0x28, 0xfd, 0xf1, 0x96, 0x28, 0x2d, 0xce, 0xed, 0x44, 0xf1, 0x90, 0x3e, 0xa8, 0xa2, + 0xa5, 0x62, 0x43, 0xcf, 0x2f, 0x3f, 0xe1, 0x6c, 0x01, 0x8a, 0xeb, 0x33, 0xd4, 0xcb, 0x7b, 0x7b, + 0x32, 0xfd, 0x3a, 0xf2, 0xc3, 0x0c, 0x46, 0xc4, 0x3d, 0xec, 0x47, 0x47, 0x33, 0x31, 0x4d, 0xb4, + 0x95, 0x0b, 0x46, 0x7d, 0x87, 0x7b, 0x36, 0x0c, 0x90, 0xb8, 0x8c, 0x1c, 0xf2, 0xc7, 0x85, 0x31, + 0x1f, 0x21, 0x1d, 0xf2, 0xf2, 0xde, 0xf0, 0xa7, 0x7a, 0xd2, 0xe1, 0x91, 0xe7, 0x3e, 0x5f, 0x4e, + 0x2e, 0xa4, 0xc5, 0x2f, 0xc1, 0x08, 0x91, 0x96, 0xe6, 0xec, 0x36, 0x83, 0xab, 0x94, 0xcb, 0x3c, + 0x96, 0x1a, 0x41, 0x5a, 0xa8, 0xb9, 0x7f, 0x04, 0x22, 0x46, 0x12, 0x44, 0xb8, 0x29, 0x97, 0x8f, + 0xe5, 0x71, 0x97, 0x93, 0x25, 0xdb, 0x88, 0x1e, 0x27, 0x83, 0x07, 0x15, 0x18, 0x90, 0x20, 0x8c, + 0x8a, 0x0c, 0x50, 0x67, 0x83, 0xc3, 0xbe, 0xa0, 0xe2, 0xba, 0xd3, 0x71, 0xe1, 0x81, 0xc7, 0x93, + 0xaa, 0x5e, 0xfb, 0xd2, 0x3c, 0x77, 0x93, 0x81, 0xa2, 0xbc, 0x12, 0x85, 0x70, 0x88, 0x44, 0x79, + 0x1f, 0x1c, 0x3d, 0xca, 0x9b, 0x43, 0xdc, 0x2d, 0x5a, 0xa4, 0xaa, 0xb0, 0xcb, 0x12, 0x00, 0x8e, + 0x2e, 0xe8, 0x6c, 0x52, 0x07, 0x74, 0xc6, 0xb4, 0xe3, 0xcd, 0xcd, 0xeb, 0x1d, 0xbe, 0xa0, 0xe2, + 0xfa, 0x65, 0x89, 0x0c, 0x0c, 0x30, 0x54, 0x55, 0xb8, 0x58, 0x33, 0xc7, 0xb7, 0x1b, 0xbe, 0x21, + 0xe7, 0xbc, 0xb6, 0x2a, 0xae, 0x96, 0x8b, 0xc5, 0xf1, 0x22, 0x01, 0x5e, 0x61, 0xef, 0x65, 0x9a, + 0x6b, 0x7d, 0x3d, 0x43, 0x1c, 0xc7, 0xd5, 0x7c, 0x9b, 0xdf, 0xd9, 0x9d, 0xf0, 0xaf, 0x25, 0x44, + 0x9c, 0x8a, 0x70, 0xeb, 0x80, 0x0f, 0xb8, 0xe1, 0x9f, 0x7d, 0x95, 0xa2, 0x4a, 0xeb, 0xfb, 0x8e, + 0xff, 0x28, 0xdc, 0x64, 0x0c, 0xa6, 0x87, 0x94, 0x65, 0x82, 0x2a, 0x74, 0xff, 0xe1, 0x48, 0x90, + 0x03, 0x87, 0x00, 0x78, 0xf2, 0xc6, 0x69, 0x7f, 0xde, 0x8c, 0x4b, 0xd3, 0x15, 0x8e, 0x0b, 0x34, + 0x41, 0xef, 0x2d, 0x66, 0x4f, 0x12, 0x14, 0x8c, 0xd3, 0xbb, 0x6e, 0x23, 0xfc, 0x5d, 0x8c, 0x0f, + 0xb9, 0x45, 0x61, 0x46, 0x07, 0x05, 0x38, 0xbc, 0x49, 0x05, 0x69, 0x41, 0xf4, 0x96, 0x33, 0x0a, + 0x9c, 0x69, 0x58, 0x80, 0x50, 0x0b, 0x0a, 0x91, 0x30, 0x56, 0x5b, 0xde, 0x31, 0x58, 0xa3, 0x3f, + 0x3e, 0xcd, 0x71, 0x10, 0xa1, 0x8f, 0x00, 0xf1, 0x68, 0xb8, 0x9c, 0x0d, 0x34, 0x7e, 0xa6, 0xd7, + 0xe9, 0x36, 0xa1, 0xc5, 0x79, 0x88, 0x6c, 0x84, 0x31, 0x64, 0x12, 0x84, 0xc6, 0xe6, 0x4c, 0x93, + 0xae, 0x24, 0x64, 0x5c, 0xbc, 0xe2, 0x41, 0x3b, 0x82, 0x98, 0xb9, 0x78, 0x93, 0x87, 0x1f, 0x5b, + 0x3c, 0x8b, 0xa8, 0x55, 0x2f, 0xe2, 0x42, 0x65, 0x17, 0x26, 0xcf, 0x33, 0x30, 0x7f, 0xc3, 0xdd, + 0xd6, 0x2e, 0xa1, 0x2e, 0x4d, 0x9f, 0x3c, 0x20, 0x24, 0x12, 0xef, 0x5c, 0x50, 0x6d, 0x5c, 0xf1, + 0x20, 0x97, 0x83, 0x52, 0xc2, 0xca, 0xcc, 0xa3, 0xa0, 0x34, 0x92, 0x42, 0xad, 0xf0, 0xa1, 0xe5, + 0x28, 0x3d, 0xb6, 0xf5, 0x5d, 0xd3, 0xc8, 0x0f, 0x08, 0x8c, 0x34, 0x56, 0x1c, 0xac, 0x83, 0x63, + 0x3d, 0xbc, 0xd7, 0xcd, 0xf8, 0x90, 0x57, 0x12, 0xc2, 0xcb, 0xb5, 0x13, 0xf9, 0x7d, 0x0d, 0x93, + 0x57, 0x71, 0x31, 0x31, 0x56, 0x0f, 0xbb, 0x7e, 0xaa, 0x19, 0xe4, 0xad, 0x7e, 0x51, 0x2b, 0x58, + 0x67, 0x92, 0xef, 0xe2, 0x44, 0xc2, 0xb8, 0x88, 0x04, 0x22, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x46, 0x23, 0x31, 0x27, 0xd8, 0x8d, 0xdd, 0xf2, 0xee, 0x9c, 0x4f, 0x21, 0xeb, 0x26, 0x79, 0x6a, + 0xb8, 0x32, 0x89, 0x82, 0xd2, 0x2e, 0x56, 0x1d, 0x6b, 0xdc, 0x4c, 0x25, 0x54, 0xf4, 0xdb, 0x7e, + 0x26, 0x13, 0xbe, 0xca, 0x5e, 0xe5, 0xbe, 0x24, 0xa5, 0xd8, 0xdc, 0x18, 0x73, 0x1b, 0x55, 0x51, + 0x22, 0x02, 0x77, 0xbb, 0xb7, 0x6c, 0x9d, 0x77, 0x77, 0xfc, 0x93, 0xfd, 0xf8, 0x9f, 0x13, 0x21, + 0xdb, 0x5f, 0x08, 0xc8, 0x47, 0x6f, 0xe2, 0x02, 0x15, 0xae, 0xf3, 0xdb, 0xbd, 0x38, 0x2f, 0xc4, + 0x0a, 0xbb, 0x3f, 0x5a, 0x3f, 0x04, 0x65, 0x6d, 0x7e, 0xae, 0xef, 0x7b, 0x89, 0x10, 0x61, 0x75, + 0xae, 0x24, 0x48, 0x40, 0x75, 0xee, 0xb5, 0xbd, 0xf8, 0x9b, 0xe5, 0x63, 0x89, 0xf1, 0x3e, 0x27, + 0x05, 0x5c, 0x87, 0x97, 0xd3, 0xe2, 0x07, 0x12, 0x7c, 0xbf, 0x36, 0x5d, 0x7e, 0x20, 0xfa, 0xae, + 0xad, 0xae, 0x42, 0x66, 0xa2, 0xae, 0x5a, 0xae, 0x4e, 0x8d, 0xd3, 0xc0, 0x90, 0x08, 0x0d, 0x3c, + 0x12, 0x36, 0x13, 0x0e, 0x30, 0x51, 0x29, 0x5b, 0xb7, 0x4c, 0x90, 0x3b, 0xdd, 0xdf, 0x11, 0x88, + 0x1d, 0x17, 0x51, 0x27, 0x3c, 0xdd, 0x52, 0x5a, 0xbe, 0x08, 0xcb, 0x9f, 0xbb, 0xfc, 0x51, 0xb8, + 0x5e, 0xae, 0xee, 0xf5, 0xe2, 0x22, 0x31, 0x7e, 0x6e, 0xa2, 0xe4, 0x63, 0xc5, 0xd3, 0x24, 0x1b, + 0xac, 0x57, 0x2f, 0x63, 0xf3, 0x71, 0x78, 0x90, 0xdb, 0x80, 0x3e, 0xfd, 0x61, 0xff, 0x83, 0xbc, + 0x18, 0xc0, 0x3b, 0xc2, 0x0f, 0xc1, 0xde, 0x0c, 0x78, 0xa9, 0x31, 0xf4, 0x63, 0xf5, 0x64, 0xac, + 0xb0, 0x40, 0x10, 0x0a, 0x4a, 0x2d, 0x4b, 0x32, 0xd8, 0x59, 0x33, 0x5c, 0x72, 0xd9, 0xc0, 0xfb, + 0x2d, 0x95, 0xf7, 0x52, 0x8e, 0x82, 0x2c, 0x6f, 0xd9, 0x22, 0x47, 0xe9, 0x25, 0x1c, 0x14, 0x4a, + 0x3f, 0xaf, 0xa6, 0xb8, 0x60, 0x21, 0x03, 0xe3, 0x50, 0x3d, 0x0d, 0x43, 0x94, 0x00, 0x1a, 0x87, + 0x30, 0x06, 0xa5, 0x10, 0xd4, 0x90, 0x00, 0x04, 0x00, 0x6a, 0x17, 0x05, 0xd4, 0x2a, 0x10, 0x44, + 0xbe, 0xd9, 0xfc, 0x85, 0xba, 0x0e, 0xd4, 0x67, 0x05, 0x61, 0x69, 0xb0, 0xf9, 0xda, 0x93, 0x09, + 0x79, 0x5f, 0x7c, 0xb3, 0x7c, 0xfc, 0x56, 0xf4, 0x4b, 0x6c, 0x5f, 0x11, 0x37, 0x48, 0xb9, 0xc3, + 0x21, 0x42, 0x07, 0xeb, 0x4d, 0xf0, 0xb5, 0xf9, 0xc4, 0xdc, 0x39, 0xe1, 0x7a, 0x9d, 0xd1, 0xeb, + 0x4b, 0x01, 0xdd, 0x8a, 0xc2, 0xce, 0x4d, 0xf1, 0x36, 0xee, 0x81, 0x60, 0x80, 0x1e, 0xb7, 0xc7, + 0xea, 0x22, 0x4a, 0x8b, 0xeb, 0xfd, 0x89, 0x25, 0xf3, 0x05, 0xd8, 0xa0, 0x08, 0x75, 0xf5, 0x2f, + 0xff, 0xcf, 0x86, 0xcd, 0x70, 0x43, 0x0a, 0x15, 0x8d, 0xa5, 0xf4, 0x8e, 0xe2, 0x67, 0x38, 0x9d, + 0x9a, 0xe5, 0x80, 0xf1, 0xfa, 0x87, 0xfd, 0xfe, 0x0a, 0xc8, 0x49, 0xc7, 0x14, 0x58, 0x8d, 0x41, + 0x65, 0xa8, 0x1d, 0x2e, 0x8a, 0x96, 0x00, 0xfb, 0xa1, 0x7b, 0x4e, 0x78, 0x08, 0x80, 0xa5, 0xdd, + 0xa6, 0x9c, 0x43, 0xd3, 0x24, 0x01, 0xc0, 0xb8, 0xc2, 0x18, 0x1a, 0xa0, 0xb4, 0x3f, 0xc2, 0xd9, + 0xee, 0x33, 0xd3, 0x3f, 0x18, 0x30, 0x01, 0x10, 0x14, 0xa6, 0x23, 0xfe, 0x28, 0xa8, 0x89, 0x49, + 0xe5, 0x00, 0x00, 0x80, 0x00, 0x26, 0x42, 0x92, 0x52, 0x41, 0x77, 0x84, 0xd6, 0x90, 0x15, 0x52, + 0x43, 0x9d, 0x0f, 0x31, 0x60, 0x64, 0x50, 0x2a, 0x45, 0x98, 0x08, 0x08, 0x5f, 0x5c, 0x48, 0x53, + 0xa5, 0x9b, 0x54, 0x98, 0x5b, 0x2d, 0xd4, 0x1a, 0x09, 0x99, 0x15, 0x04, 0x46, 0x4b, 0x4a, 0x7f, + 0xad, 0x2a, 0x04, 0x31, 0x02, 0x02, 0x87, 0x6e, 0x6a, 0xc8, 0xd8, 0xaf, 0x04, 0x14, 0xcf, 0xd2, + 0xb6, 0x64, 0xa2, 0x4f, 0x9c, 0xf7, 0xde, 0x71, 0xf1, 0x1e, 0x19, 0x10, 0x14, 0x93, 0xe0, 0xff, + 0x93, 0x46, 0xd1, 0xf0, 0x3f, 0xc3, 0x1a, 0x40, 0x61, 0x55, 0xf1, 0xb6, 0x8a, 0x9d, 0x4e, 0xa9, + 0x57, 0xf8, 0x29, 0x30, 0x73, 0x00, 0x6a, 0x51, 0x00, 0x6a, 0x98, 0x70, 0x01, 0xd0, 0xaa, 0xc6, + 0x62, 0x58, 0x0c, 0x9d, 0x64, 0xfc, 0xef, 0x77, 0xe2, 0x52, 0x2f, 0x31, 0xf7, 0x7f, 0x13, 0x43, + 0xa1, 0xa6, 0xc8, 0x9d, 0x0d, 0x45, 0x23, 0x58, 0x21, 0x96, 0xf9, 0x43, 0x59, 0xb0, 0xd8, 0xe2, + 0x44, 0x02, 0x41, 0x4f, 0x7b, 0x70, 0x88, 0x20, 0x0a, 0x53, 0x2d, 0x37, 0xe3, 0xf3, 0x0b, 0x55, + 0xd8, 0x37, 0x04, 0x32, 0x4e, 0x47, 0x34, 0x21, 0xb1, 0xd0, 0xb0, 0x51, 0x0a, 0x5b, 0x0e, 0x19, + 0x06, 0x03, 0x39, 0x30, 0xd8, 0xec, 0x66, 0x47, 0x2e, 0xa3, 0xc5, 0xfd, 0x71, 0x73, 0x60, 0xb9, + 0x7e, 0x19, 0x08, 0x05, 0x33, 0xaf, 0x37, 0x2f, 0x2d, 0x65, 0xe9, 0x0b, 0xa7, 0x8e, 0x2b, 0x94, + 0x52, 0x8d, 0x50, 0xdf, 0x82, 0x91, 0xb8, 0xca, 0x27, 0x90, 0x28, 0xa4, 0xf7, 0xad, 0x6a, 0xd5, + 0xb4, 0x3f, 0x10, 0x6a, 0x15, 0x13, 0x40, 0xa0, 0xa4, 0xa6, 0xd0, 0x3e, 0x41, 0xc9, 0xc3, 0x60, + 0x2b, 0x5a, 0x34, 0x82, 0xf5, 0x73, 0x46, 0x78, 0x13, 0xc3, 0x78, 0x00, 0x3e, 0x50, 0xfc, 0xa4, + 0x65, 0x49, 0x5f, 0xff, 0x2c, 0xaa, 0xd2, 0x8a, 0x95, 0x56, 0x4d, 0xc0, 0xe3, 0xbc, 0x46, 0x0e, + 0x00, 0xdf, 0x7d, 0x89, 0xc8, 0x8c, 0x79, 0xfd, 0x60, 0xbd, 0x36, 0x21, 0xb5, 0x00, 0x66, 0x48, + 0xd7, 0x05, 0x2a, 0x9f, 0xfe, 0xdd, 0x09, 0xa0, 0x3f, 0xe7, 0xe2, 0x3b, 0x7b, 0x4d, 0x9e, 0xad, + 0xa3, 0xb9, 0x6c, 0xbc, 0x60, 0xc0, 0x9b, 0xab, 0x63, 0xd8, 0xf8, 0x73, 0x84, 0xf7, 0xbb, 0xdd, + 0xcb, 0xc9, 0x6d, 0x2f, 0xf7, 0x3f, 0x60, 0xf5, 0xc2, 0x59, 0x73, 0x9a, 0x99, 0x39, 0x4b, 0x9b, + 0x0d, 0x9e, 0x63, 0x63, 0xde, 0x9c, 0x40, 0x92, 0xf1, 0x2f, 0xfb, 0x91, 0x9c, 0x38, 0x91, 0xcf, + 0x84, 0x42, 0x85, 0x93, 0x05, 0x65, 0xb1, 0x27, 0x05, 0xdd, 0xcb, 0xdd, 0xde, 0xdc, 0x25, 0xaf, + 0x1f, 0xf8, 0x64, 0x22, 0x14, 0x24, 0xe2, 0xea, 0xed, 0x2d, 0xfe, 0x66, 0xf9, 0x39, 0x7d, 0x7c, + 0xb5, 0x58, 0xb8, 0x91, 0x00, 0x93, 0xa8, 0x9e, 0x39, 0xc2, 0x22, 0x01, 0x65, 0x0c, 0xd8, 0xa5, + 0xfa, 0xaa, 0xc5, 0xd2, 0x73, 0x88, 0x10, 0x14, 0x82, 0x9e, 0x01, 0xc3, 0x5f, 0x06, 0x4e, 0xae, + 0xda, 0x41, 0x15, 0x45, 0x1f, 0xe6, 0xa3, 0x6d, 0xf5, 0x0b, 0x45, 0x50, 0x54, 0x69, 0xf2, 0xd2, + 0x71, 0x30, 0xa4, 0xb0, 0x62, 0x8c, 0xb5, 0x0a, 0xcb, 0x19, 0xb5, 0x66, 0xda, 0xd5, 0xb8, 0x9f, + 0x02, 0x8f, 0x2a, 0x80, 0x03, 0x41, 0x28, 0x8b, 0x89, 0x10, 0x32, 0x24, 0x3c, 0x72, 0xb9, 0xe1, + 0xe7, 0x79, 0x6e, 0x75, 0x2f, 0x26, 0xd0, 0x6d, 0xff, 0xe9, 0x42, 0xf1, 0x71, 0xf6, 0x1d, 0xcc, + 0x10, 0xc1, 0x4c, 0xf3, 0xcb, 0x39, 0x59, 0xd3, 0xac, 0xfe, 0x0b, 0xb1, 0xe2, 0x01, 0x4c, 0x43, + 0x45, 0xd8, 0x59, 0x54, 0x0e, 0x13, 0x04, 0x86, 0xa5, 0x08, 0x75, 0xc2, 0xb5, 0x6f, 0x85, 0xbc, + 0xb9, 0x06, 0x08, 0x1a, 0xe7, 0x80, 0x01, 0x5e, 0x0c, 0x4d, 0x40, 0x14, 0x25, 0xa5, 0xc4, 0x3e, + 0xce, 0x24, 0xf8, 0x25, 0xee, 0x31, 0x94, 0xf7, 0xd8, 0xd2, 0x5f, 0xf9, 0x8d, 0x77, 0xf9, 0x0c, + 0xb6, 0x37, 0xf6, 0x51, 0xf4, 0xcf, 0x47, 0x50, 0xcc, 0xbd, 0xdf, 0x0c, 0xc1, 0x59, 0x16, 0xf9, + 0xa9, 0x6c, 0x71, 0x6d, 0x09, 0xe0, 0xec, 0x95, 0x8e, 0x11, 0x82, 0x13, 0xcb, 0x69, 0x29, 0xf3, + 0x70, 0x43, 0x05, 0x55, 0xd5, 0x57, 0x5d, 0x63, 0x9c, 0x22, 0x24, 0x16, 0x45, 0x75, 0xb9, 0xf5, + 0xdd, 0x42, 0x82, 0xae, 0xdc, 0x2d, 0x9e, 0x39, 0x67, 0x07, 0x02, 0x46, 0x98, 0x11, 0xca, 0x3c, + 0x03, 0x96, 0xfa, 0x52, 0x06, 0x7d, 0x27, 0x40, 0x7d, 0x70, 0xfc, 0xc1, 0x2f, 0x11, 0xb5, 0x39, + 0xc5, 0xc0, 0x85, 0x40, 0xfa, 0x0e, 0x98, 0x03, 0x52, 0xc1, 0x96, 0xce, 0x07, 0x8a, 0xcb, 0x66, + 0x42, 0x95, 0xf1, 0xae, 0xf8, 0x28, 0x12, 0x14, 0x9e, 0x67, 0x80, 0x70, 0xe0, 0x3c, 0xa5, 0x78, + 0x90, 0x3e, 0x0e, 0x1a, 0x22, 0x8a, 0xc5, 0xf3, 0x02, 0x2c, 0x8b, 0x0c, 0xad, 0x2a, 0x47, 0x1c, + 0xe9, 0x14, 0x75, 0x3c, 0xb2, 0x7b, 0xf8, 0x8b, 0x58, 0x80, 0x80, 0x52, 0x38, 0xf8, 0x47, 0x3b, + 0xcf, 0x26, 0xae, 0xa8, 0x7e, 0x81, 0x97, 0x74, 0x78, 0xee, 0x0f, 0xbb, 0xd6, 0x68, 0xce, 0x7c, + 0xb7, 0x85, 0x9c, 0x49, 0x46, 0x47, 0xde, 0xe4, 0x90, 0x31, 0x30, 0x56, 0x57, 0xdb, 0x67, 0xb2, + 0x95, 0x3b, 0x18, 0x27, 0xf2, 0x51, 0x3c, 0x96, 0xd3, 0x5a, 0xc3, 0x72, 0x00, 0xcc, 0x32, 0x9c, + 0xb7, 0xdf, 0xff, 0xc5, 0x6c, 0x0a, 0xe5, 0x87, 0x1c, 0xd3, 0xe0, 0x8f, 0x11, 0x17, 0x13, 0xe1, + 0x18, 0x21, 0x89, 0x18, 0x6d, 0xb1, 0x86, 0x18, 0xb0, 0x3d, 0x26, 0xff, 0x4d, 0x3d, 0xb6, 0xe9, + 0xb6, 0xda, 0x69, 0xa7, 0xe0, 0xa4, 0x08, 0x23, 0x0c, 0x28, 0xcb, 0x59, 0xfb, 0x70, 0x47, 0x1b, + 0x1b, 0x1c, 0x6f, 0x67, 0x0c, 0x04, 0x30, 0xa8, 0xb6, 0x5a, 0xc2, 0x82, 0xa2, 0xb0, 0xe2, 0x5c, + 0x10, 0x85, 0x21, 0x71, 0x7d, 0x41, 0x32, 0xac, 0xaa, 0x85, 0x99, 0xee, 0x16, 0x3a, 0x9c, 0x5c, + 0x74, 0xc2, 0xf6, 0x40, 0x6d, 0x0b, 0x0c, 0x50, 0xc4, 0xf0, 0x5e, 0x7b, 0xc2, 0x21, 0x48, 0x54, + 0x7a, 0xcf, 0x07, 0xd6, 0x88, 0x79, 0xf8, 0xb9, 0x63, 0x6d, 0xc9, 0xc0, 0x1e, 0x77, 0x9e, 0x05, + 0x86, 0x72, 0xcd, 0x65, 0x1d, 0xc2, 0x22, 0x06, 0x43, 0xc5, 0xe8, 0x3a, 0x7c, 0xa4, 0x74, 0xb2, + 0x52, 0xab, 0xe9, 0x85, 0xba, 0x53, 0x29, 0xc0, 0xb0, 0x73, 0xcb, 0x1b, 0x7b, 0xfc, 0x19, 0xef, + 0x6a, 0x5c, 0x23, 0x19, 0x4c, 0x26, 0x9d, 0x08, 0xad, 0x05, 0xcc, 0xf0, 0x6d, 0x3e, 0xc5, 0xa3, + 0x6c, 0x7a, 0xdd, 0xb1, 0x55, 0x7a, 0xb7, 0xa5, 0xd7, 0x2c, 0xf9, 0xbb, 0x46, 0x9d, 0x6b, 0xd3, + 0x3e, 0x9b, 0x1a, 0xde, 0x24, 0xc3, 0x20, 0xae, 0x84, 0x60, 0xa6, 0x1d, 0xf1, 0xde, 0xf2, 0xb2, + 0xb9, 0x96, 0x71, 0x96, 0x63, 0x34, 0x63, 0xee, 0xab, 0x05, 0x1d, 0x1f, 0xa4, 0xec, 0x9a, 0xb3, + 0xc1, 0xc0, 0x44, 0x16, 0x5a, 0x5c, 0x51, 0x85, 0x07, 0x21, 0x46, 0x2f, 0xfe, 0xb2, 0x8d, 0x16, + 0xce, 0x7f, 0xb8, 0x18, 0x20, 0xb3, 0x0e, 0xfb, 0x85, 0xde, 0x57, 0xe7, 0xd9, 0x38, 0x4d, 0x0c, + 0xa3, 0x34, 0x87, 0x86, 0xf9, 0x29, 0xf3, 0x0e, 0x28, 0x0e, 0x00, 0x19, 0x5c, 0xd0, 0x5e, 0x19, + 0xa4, 0xdc, 0x9a, 0x4a, 0x78, 0xc4, 0x5b, 0x11, 0x60, 0x16, 0x9a, 0x62, 0x80, 0x58, 0xa0, 0x17, + 0xc4, 0xb5, 0xed, 0x35, 0xe1, 0x90, 0x60, 0x14, 0x23, 0xda, 0xb8, 0xaf, 0x5b, 0x75, 0x1a, 0xa0, + 0x9f, 0x11, 0xbe, 0x04, 0x14, 0x5c, 0x10, 0x82, 0x81, 0xb2, 0x7a, 0x91, 0x8d, 0xc7, 0x44, 0x85, + 0x46, 0x85, 0xed, 0x6d, 0xb3, 0x46, 0xff, 0xbc, 0xc1, 0xe8, 0xd3, 0x80, 0xe1, 0xd8, 0x00, 0x12, + 0xc8, 0xd2, 0x2f, 0x15, 0x4b, 0xd5, 0x07, 0xaf, 0xbc, 0x7b, 0xbc, 0x22, 0x18, 0x0a, 0x49, 0x4a, + 0x94, 0x89, 0x97, 0x8e, 0x4b, 0x03, 0x95, 0xa8, 0x54, 0x5d, 0x02, 0xa2, 0xff, 0x13, 0xc5, 0x38, + 0x0f, 0x2c, 0x32, 0xc0, 0x64, 0x8b, 0x30, 0x77, 0xca, 0x8e, 0xae, 0x20, 0x20, 0x32, 0x2c, 0xea, + 0xdb, 0x14, 0xb6, 0xad, 0xea, 0xdf, 0xa4, 0x9c, 0x29, 0xa8, 0xfa, 0x53, 0x45, 0x93, 0xe6, 0x80, + 0x43, 0xf5, 0x70, 0xc8, 0x53, 0x5c, 0xfc, 0x56, 0xdc, 0x1a, 0x6c, 0x1c, 0x0e, 0x42, 0x92, 0x06, + 0xa2, 0x44, 0x6b, 0xb0, 0x79, 0x61, 0x37, 0xbf, 0x67, 0x08, 0x84, 0x01, 0x2d, 0xf8, 0x7e, 0xbd, + 0x79, 0xb7, 0xbb, 0x83, 0x08, 0x7e, 0xff, 0xac, 0x48, 0x78, 0x58, 0xa8, 0x1e, 0xe5, 0x42, 0x00, + 0x1e, 0x98, 0x71, 0x40, 0x95, 0x76, 0x48, 0x1c, 0x16, 0x37, 0x88, 0xc2, 0x2c, 0xd9, 0xfa, 0x3b, + 0x90, 0x49, 0x11, 0xf8, 0x47, 0x63, 0x55, 0x55, 0x55, 0x55, 0x52, 0x67, 0x12, 0x3e, 0xaa, 0xd5, + 0x55, 0x6b, 0x5a, 0xec, 0xab, 0xaa, 0xe2, 0x46, 0x36, 0xac, 0x8b, 0x29, 0xf3, 0xf2, 0x56, 0xa0, + 0x6f, 0x5d, 0x83, 0x98, 0x88, 0xba, 0x9c, 0x28, 0x5c, 0x6b, 0x1c, 0x81, 0xc6, 0x03, 0x5e, 0x0f, + 0xc1, 0x54, 0xa8, 0x21, 0xf2, 0x28, 0x83, 0xeb, 0xbd, 0x2d, 0xf0, 0xcb, 0x28, 0x91, 0x4b, 0x10, + 0x2c, 0x37, 0x04, 0x01, 0x10, 0xa6, 0xbe, 0xae, 0x6f, 0x37, 0x51, 0x73, 0x9c, 0x6e, 0x34, 0x9c, + 0x2b, 0x55, 0x9e, 0x01, 0xc0, 0x6b, 0x89, 0xf0, 0xeb, 0x80, 0x43, 0x4c, 0xd9, 0x19, 0x01, 0x94, + 0x47, 0xd7, 0x73, 0xdb, 0x0a, 0xbd, 0xbc, 0xcf, 0x68, 0x3d, 0x7b, 0xd6, 0x7e, 0x9b, 0x68, 0x3a, + 0xba, 0xde, 0x28, 0x0e, 0x2d, 0xef, 0x79, 0x7c, 0x37, 0x80, 0x29, 0x78, 0x73, 0x94, 0xa2, 0x2f, + 0x31, 0xf9, 0x5c, 0x96, 0xc8, 0xc5, 0x46, 0x2e, 0x33, 0x95, 0x5e, 0x0a, 0x2a, 0x84, 0xc0, 0x38, + 0x28, 0xae, 0x51, 0x71, 0xba, 0x28, 0x32, 0xc3, 0x9d, 0x40, 0x47, 0xe5, 0x75, 0xe0, 0xa4, 0x29, + 0x2c, 0x30, 0x3a, 0x55, 0x0e, 0x38, 0x4d, 0xac, 0x5c, 0x5a, 0x92, 0x5b, 0x72, 0xf6, 0x71, 0x17, + 0x98, 0x27, 0x39, 0xea, 0xf0, 0x7c, 0x1c, 0xfa, 0xa7, 0x07, 0xe7, 0x80, 0x1c, 0x48, 0x1e, 0x14, + 0xd4, 0x41, 0xe9, 0x3c, 0x0d, 0x64, 0x21, 0x77, 0x0a, 0x0e, 0x01, 0xf0, 0x9d, 0x07, 0xdf, 0x65, + 0xf0, 0xfc, 0x49, 0x59, 0x0f, 0x53, 0x85, 0x20, 0xd4, 0xac, 0x0e, 0x87, 0x8e, 0x1d, 0x83, 0xfb, + 0x28, 0x5a, 0x12, 0x3a, 0x71, 0x22, 0x42, 0x87, 0x38, 0x38, 0x62, 0xaf, 0x35, 0xf3, 0xd7, 0xca, + 0xe7, 0x1f, 0x69, 0x7e, 0x0e, 0xd8, 0x93, 0xb6, 0xc3, 0xbc, 0xac, 0xe2, 0x42, 0x00, 0xae, 0xa9, + 0x3b, 0x9e, 0x16, 0x3d, 0xe1, 0xc3, 0x8f, 0x7f, 0xdf, 0x81, 0x04, 0x09, 0x00, 0x9c, 0xcf, 0x82, + 0xbd, 0x6f, 0xcb, 0x9b, 0x07, 0x6c, 0x63, 0x81, 0x24, 0x09, 0x03, 0x2e, 0xc3, 0xe7, 0x71, 0x58, + 0xaa, 0x3e, 0x2f, 0x5a, 0x46, 0xca, 0xb8, 0x80, 0x51, 0x03, 0xb0, 0x4a, 0xec, 0x25, 0x02, 0xa5, + 0x80, 0x79, 0xb1, 0xa4, 0x0e, 0xa4, 0x09, 0xf9, 0x8b, 0xaa, 0xf8, 0x44, 0x96, 0x10, 0xfc, 0x22, + 0x1d, 0x56, 0xd4, 0x49, 0x17, 0x51, 0xd7, 0x05, 0x1d, 0x47, 0x70, 0x6c, 0x07, 0x04, 0x98, 0x54, + 0x27, 0xf8, 0xd3, 0x00, 0x10, 0xf2, 0xf8, 0xcd, 0xa4, 0x65, 0x34, 0xa6, 0xc8, 0xa4, 0x9c, 0xe5, + 0x27, 0x80, 0x62, 0x9c, 0xd8, 0x2e, 0xcc, 0xf1, 0x96, 0x55, 0x8c, 0xa9, 0x60, 0xec, 0xfa, 0xce, + 0x9f, 0xac, 0x5f, 0x04, 0x11, 0xb6, 0xfe, 0x3a, 0x18, 0xb0, 0x8b, 0x0e, 0x4f, 0x51, 0x59, 0x23, + 0x92, 0x5b, 0x13, 0xf2, 0xc4, 0xff, 0xf0, 0xea, 0x12, 0x00, 0xfe, 0xbd, 0x46, 0x4d, 0x8b, 0xff, + 0xff, 0xfd, 0xad, 0xe4, 0xe3, 0xa8, 0x55, 0x21, 0x97, 0xe6, 0xf9, 0xff, 0xed, 0x88, 0xb4, 0x20, + 0x9a, 0x0a, 0x32, 0xd1, 0x34, 0xf5, 0xd6, 0xdd, 0xb6, 0xde, 0x0e, 0x61, 0x41, 0x0e, 0x4f, 0x8d, + 0xa4, 0x9c, 0xdd, 0x74, 0x68, 0x46, 0x4b, 0x14, 0xaa, 0xa8, 0x54, 0xc9, 0x87, 0x29, 0x55, 0xf4, + 0xdf, 0x81, 0x06, 0x14, 0xb6, 0xc2, 0x00, 0x06, 0x53, 0xb5, 0x9b, 0x60, 0x01, 0x9e, 0x28, 0x00, + 0xa7, 0x8a, 0x49, 0xa9, 0x43, 0x79, 0x65, 0x72, 0x55, 0x2f, 0x62, 0xe0, 0xcb, 0x58, 0x14, 0x04, + 0x8d, 0x90, 0xbf, 0x3f, 0x53, 0xe3, 0x81, 0xc9, 0x2d, 0x44, 0x0e, 0x57, 0x83, 0xa7, 0x81, 0x55, + 0x59, 0x03, 0x87, 0x9e, 0xf2, 0x83, 0x64, 0x30, 0x72, 0x1f, 0xff, 0xa4, 0x39, 0xd0, 0xe2, 0x16, + 0x02, 0x28, 0x06, 0xcb, 0x5d, 0x0e, 0xf9, 0x7c, 0x49, 0x96, 0x52, 0x52, 0xfc, 0xa4, 0xa5, 0x8c, + 0x8a, 0xd1, 0xec, 0x28, 0x71, 0xa9, 0x41, 0xc6, 0xa5, 0xc9, 0xc7, 0x18, 0xd0, 0xe3, 0x1a, 0x1d, + 0x8d, 0x14, 0xd8, 0xab, 0x16, 0xc5, 0xb1, 0x56, 0x2a, 0xfc, 0x30, 0xa0, 0x30, 0xfd, 0x13, 0x84, + 0x5f, 0xd3, 0x57, 0xf2, 0xa3, 0x2e, 0xce, 0x7b, 0xa0, 0xd6, 0x56, 0x7d, 0x3e, 0xb1, 0x56, 0x73, + 0x2b, 0x58, 0x31, 0xbb, 0xb8, 0x14, 0x21, 0x49, 0x50, 0x6f, 0x8a, 0xbf, 0xce, 0x74, 0xef, 0x37, + 0xd4, 0x38, 0x57, 0x92, 0xd4, 0x78, 0xf5, 0x2a, 0xf6, 0x96, 0xdf, 0xce, 0xe5, 0x25, 0x2a, 0x8d, + 0x54, 0x3c, 0xa0, 0x23, 0xb3, 0x4f, 0x73, 0xff, 0xfd, 0x97, 0x75, 0xd3, 0x4e, 0xf6, 0x9b, 0x6d, + 0xa7, 0x1d, 0x99, 0x36, 0xde, 0xdb, 0x7f, 0x82, 0x9b, 0x30, 0x92, 0xc9, 0xb9, 0xb3, 0x3c, 0xf1, + 0xce, 0xc4, 0x12, 0x70, 0x98, 0xaa, 0x19, 0x48, 0xdd, 0xee, 0xf9, 0x8a, 0x92, 0xfe, 0x3e, 0xad, + 0x7b, 0xbb, 0x5a, 0x7e, 0x33, 0x57, 0x10, 0xe2, 0x4b, 0xde, 0xed, 0x3b, 0x6f, 0xc1, 0x40, 0x44, + 0x14, 0x90, 0x1d, 0x3e, 0x16, 0xbb, 0xc1, 0xfb, 0x96, 0x9b, 0x6e, 0x80, 0xf6, 0xf6, 0x6f, 0x67, + 0x04, 0x01, 0x11, 0x77, 0x93, 0xb7, 0x9b, 0x0f, 0xb8, 0x29, 0x82, 0xcc, 0x73, 0x31, 0xca, 0x81, + 0xef, 0xb9, 0x9c, 0x65, 0x86, 0xac, 0xfc, 0xe2, 0x9e, 0xcc, 0xb1, 0x84, 0x04, 0x02, 0xbc, 0x23, + 0x7d, 0xe8, 0xdd, 0xd3, 0x47, 0x7d, 0xf0, 0xd9, 0x96, 0x10, 0x38, 0x2a, 0xc2, 0xaf, 0xa9, 0xe3, + 0x27, 0x3c, 0x48, 0x53, 0xa9, 0x37, 0x19, 0xcb, 0x13, 0xe7, 0xf4, 0xad, 0xec, 0xe6, 0xcf, 0x60, + 0x92, 0x21, 0x19, 0x60, 0x36, 0xe1, 0x01, 0x21, 0x48, 0x86, 0xcb, 0x48, 0x0f, 0x96, 0xdf, 0x0e, + 0x2b, 0x77, 0x71, 0xf7, 0xd3, 0x2c, 0x62, 0xb1, 0x46, 0x28, 0x3d, 0x9c, 0x40, 0x90, 0xa1, 0x56, + 0xbe, 0x6c, 0x63, 0x77, 0xac, 0xa8, 0xba, 0x7e, 0x0a, 0x44, 0x82, 0xcd, 0xbd, 0x2c, 0xb8, 0xaa, + 0x2e, 0x68, 0x92, 0x05, 0xaa, 0xbc, 0x5c, 0x31, 0x04, 0xa4, 0x56, 0xae, 0xee, 0x20, 0xe7, 0x7d, + 0x92, 0xf4, 0xe1, 0x84, 0x44, 0x85, 0x36, 0xcb, 0x8e, 0xef, 0x3a, 0x9f, 0x2f, 0x85, 0xf5, 0x65, + 0xb0, 0xe2, 0x80, 0x1a, 0x97, 0x87, 0xbd, 0x83, 0xc5, 0x7f, 0xf3, 0xcf, 0x1d, 0x6d, 0x8a, 0xbc, + 0x2f, 0xd4, 0x0c, 0x53, 0xc2, 0xcf, 0xe2, 0x70, 0x3f, 0x07, 0xe2, 0xe3, 0x21, 0x72, 0xb2, 0xe6, + 0x00, 0x14, 0x0c, 0xb5, 0xf9, 0x74, 0xc6, 0x7c, 0x3e, 0x5c, 0x4f, 0x14, 0x3f, 0x01, 0x28, 0x55, + 0x80, 0x25, 0x0e, 0x71, 0xf1, 0xc6, 0x17, 0x98, 0x4c, 0x7b, 0x1f, 0xc8, 0x2f, 0x8e, 0xf1, 0x72, + 0x03, 0x83, 0x84, 0xf6, 0xe7, 0x36, 0x0d, 0x57, 0x79, 0x8b, 0xaa, 0xf9, 0x78, 0xba, 0x9b, 0x9b, + 0x51, 0x71, 0x7f, 0x17, 0xa8, 0xb8, 0xbd, 0x54, 0x5f, 0xcb, 0xd5, 0x46, 0xf3, 0x11, 0x75, 0x13, + 0xdd, 0x6b, 0x27, 0x10, 0x5c, 0xb9, 0xdd, 0xfc, 0x25, 0xdd, 0xc6, 0xfd, 0x5d, 0xfc, 0x99, 0x21, + 0xe2, 0x22, 0x8d, 0xcb, 0xdc, 0xb7, 0xfb, 0xde, 0xe6, 0xc4, 0x10, 0x4d, 0x5a, 0xf1, 0x21, 0x81, + 0xc4, 0xba, 0xd3, 0xb5, 0xa9, 0xf2, 0xd9, 0xe2, 0xfe, 0x14, 0x26, 0x25, 0xc4, 0xd7, 0x50, 0xf1, + 0x48, 0x78, 0xf5, 0x8a, 0xb7, 0x16, 0xe8, 0x9e, 0x7a, 0xac, 0x66, 0x2f, 0x8e, 0xda, 0x57, 0x8b, + 0xd6, 0x66, 0x61, 0x78, 0x90, 0xa4, 0x5c, 0xad, 0xaa, 0xc7, 0x5c, 0xfe, 0xab, 0x77, 0xda, 0xaa, + 0x32, 0x59, 0x89, 0xf8, 0x42, 0x30, 0x49, 0x8a, 0x2b, 0xcd, 0xc1, 0x86, 0xf6, 0x34, 0xdf, 0x77, + 0x45, 0x2d, 0x7c, 0x79, 0xa1, 0x3b, 0x38, 0xb5, 0x69, 0xda, 0x3e, 0x78, 0x44, 0x40, 0xdc, 0x37, + 0xd4, 0x1d, 0xb9, 0x1c, 0x50, 0x2c, 0xc5, 0x15, 0x90, 0x5c, 0x07, 0x25, 0x24, 0xa3, 0x85, 0x5d, + 0x9a, 0x04, 0x95, 0x29, 0x97, 0xe2, 0x58, 0x70, 0x2a, 0xc7, 0xe7, 0x8b, 0xe6, 0x17, 0x58, 0xb6, + 0x30, 0xea, 0x54, 0xfb, 0xf8, 0x34, 0x6a, 0x4c, 0x97, 0x91, 0x29, 0xb2, 0x5d, 0x85, 0x31, 0x79, + 0xac, 0xc2, 0x02, 0x06, 0xcb, 0x7f, 0xcd, 0xef, 0x62, 0xc9, 0xd6, 0x95, 0x40, 0x36, 0x4e, 0xbc, + 0x23, 0x95, 0x3b, 0x03, 0x42, 0xf3, 0x54, 0x0e, 0xfb, 0x16, 0xd6, 0xc1, 0xf2, 0x1a, 0xc5, 0x5a, + 0x90, 0x47, 0x87, 0x0d, 0x7e, 0xf3, 0xcf, 0xa9, 0x2b, 0xee, 0x5f, 0x04, 0x02, 0x09, 0x57, 0x72, + 0xe2, 0x01, 0x1f, 0x5e, 0x18, 0x04, 0x01, 0x49, 0xce, 0x1e, 0xfe, 0x5c, 0x6d, 0xa6, 0x9a, 0x6b, + 0x74, 0xaf, 0x97, 0x84, 0x05, 0x95, 0x86, 0x62, 0x8e, 0xb8, 0xec, 0x9e, 0x99, 0x3a, 0xd9, 0x5c, + 0x31, 0xcd, 0x63, 0xbe, 0xc7, 0xf8, 0x07, 0x31, 0xae, 0x5d, 0xb2, 0xef, 0xf8, 0x28, 0xe5, 0x42, + 0xfe, 0x1c, 0x9e, 0x63, 0xbe, 0xf2, 0xf8, 0x24, 0xd6, 0x06, 0x26, 0x17, 0x3b, 0x88, 0x02, 0x00, + 0x50, 0x8e, 0xea, 0x6c, 0x70, 0xe0, 0x2a, 0xa7, 0x24, 0xba, 0xa9, 0x88, 0x16, 0x1d, 0xfd, 0xfc, + 0x09, 0x03, 0xe0, 0xf7, 0x83, 0x19, 0x28, 0xfa, 0x72, 0xdd, 0x24, 0x8d, 0x83, 0xb6, 0x29, 0x7e, + 0x24, 0x09, 0x01, 0x48, 0x37, 0xf9, 0xb8, 0x4a, 0xe8, 0x4c, 0x3a, 0x28, 0xe2, 0xbb, 0x97, 0x9e, + 0xa2, 0x27, 0x72, 0x2f, 0x2c, 0xc9, 0x1f, 0x9d, 0x61, 0x38, 0x14, 0x08, 0xc2, 0x26, 0x07, 0xa3, + 0xf9, 0x8a, 0xf7, 0x77, 0xcd, 0x5a, 0xab, 0x89, 0xfd, 0xcf, 0xfa, 0xe5, 0xd6, 0xa5, 0xe1, 0x18, + 0x76, 0xb9, 0x55, 0x32, 0x6a, 0x8f, 0x42, 0x30, 0xf6, 0x89, 0x26, 0x4f, 0xc2, 0x39, 0x35, 0x35, + 0xa3, 0x26, 0x79, 0x96, 0x85, 0x87, 0xc4, 0x41, 0x00, 0x64, 0x85, 0x80, 0xe9, 0x18, 0x5d, 0xf0, + 0xc0, 0x20, 0x0a, 0x08, 0x2b, 0xb2, 0x48, 0x05, 0x61, 0xcd, 0x12, 0x85, 0x46, 0x74, 0xfa, 0xe4, + 0xe0, 0xef, 0xc2, 0xc3, 0x96, 0x57, 0xad, 0xeb, 0x89, 0x82, 0x5b, 0xde, 0x4c, 0xaa, 0xfa, 0x7b, + 0x8e, 0x24, 0x11, 0x94, 0xb1, 0x85, 0xdc, 0x6c, 0xf1, 0x2a, 0xcf, 0x12, 0x19, 0xc4, 0xfe, 0x88, + 0xb5, 0xe3, 0x5d, 0x9f, 0x4f, 0xf0, 0x53, 0xa4, 0x4c, 0xb9, 0xd8, 0x96, 0xac, 0x3b, 0xc1, 0xa5, + 0x55, 0xef, 0x08, 0x9a, 0xb6, 0xc4, 0xf3, 0x10, 0x20, 0x11, 0x95, 0xee, 0xc6, 0xbe, 0x71, 0x02, + 0x01, 0x61, 0xb5, 0x28, 0xc2, 0x97, 0xfb, 0xad, 0x29, 0x67, 0x11, 0xc6, 0x69, 0x41, 0xc4, 0x04, + 0x01, 0x4e, 0x5f, 0x16, 0xee, 0x96, 0xa7, 0xd1, 0x6b, 0xc2, 0x01, 0x1d, 0xf9, 0xda, 0x19, 0x56, + 0xe3, 0xbf, 0xc2, 0x01, 0x81, 0x1a, 0xba, 0x5c, 0xb9, 0xf0, 0xa4, 0xd8, 0x6d, 0x17, 0xe1, 0x8b, + 0x88, 0xf4, 0x3b, 0x95, 0x4e, 0x90, 0xcf, 0x9b, 0x4d, 0x28, 0x16, 0x5c, 0x6b, 0x0e, 0x10, 0x08, + 0x8e, 0xd5, 0x2c, 0xd4, 0x57, 0xe2, 0x9a, 0xa9, 0x69, 0x88, 0x12, 0x14, 0x2a, 0xaa, 0xaa, 0xaf, + 0x8e, 0xf9, 0x6f, 0x95, 0x47, 0xbc, 0x6e, 0xa2, 0xa5, 0x82, 0x00, 0xc0, 0xd2, 0x54, 0xb9, 0x59, + 0x2d, 0x11, 0x7a, 0x5e, 0x3e, 0xc9, 0x2b, 0xc1, 0xdc, 0xd5, 0xd0, 0x3b, 0xf6, 0xfb, 0x14, 0x6e, + 0x0a, 0xeb, 0x69, 0x93, 0xff, 0x88, 0x12, 0x30, 0xec, 0xe9, 0xee, 0xb6, 0xd0, 0xc0, 0xb5, 0x8d, + 0x2b, 0x17, 0x01, 0x15, 0x4b, 0x3c, 0x37, 0x3e, 0x33, 0x93, 0xaa, 0xbe, 0x61, 0x17, 0xb9, 0x7b, + 0x1a, 0x91, 0x33, 0x1b, 0xc1, 0x28, 0x85, 0x55, 0xad, 0x6d, 0xf0, 0x99, 0x35, 0x55, 0x55, 0x5f, + 0x29, 0xd6, 0xb7, 0x11, 0x04, 0xe6, 0x1c, 0x4b, 0xc9, 0xb9, 0x26, 0x9d, 0xb1, 0x0b, 0x1f, 0xa8, + 0x88, 0xf2, 0xdb, 0xad, 0x6b, 0x52, 0x60, 0xbe, 0x4c, 0x48, 0x52, 0xf3, 0xb1, 0x51, 0xeb, 0x1f, + 0xc7, 0x9f, 0x16, 0x66, 0x4c, 0x17, 0xee, 0x24, 0x48, 0xdb, 0x30, 0x55, 0x0b, 0x98, 0xf1, 0xd0, + 0x16, 0x02, 0xe8, 0x05, 0x2c, 0x34, 0xde, 0xa7, 0x21, 0x85, 0xea, 0x47, 0xa7, 0xb4, 0x16, 0x25, + 0xe2, 0x7c, 0x7e, 0x39, 0x1f, 0xf3, 0x1d, 0x2e, 0xd7, 0x06, 0x21, 0x13, 0x6c, 0x55, 0xff, 0xc1, + 0x54, 0x98, 0x02, 0xa5, 0x86, 0xe0, 0xf8, 0xbc, 0xef, 0xf7, 0x8a, 0xde, 0x91, 0x70, 0x40, 0x11, + 0xb4, 0x6c, 0x8b, 0xaa, 0xaa, 0xaa, 0xaa, 0xf0, 0xc0, 0xcb, 0xb4, 0xb5, 0x4a, 0x8a, 0xc5, 0x7d, + 0x9c, 0xd8, 0x42, 0x08, 0x8f, 0x2c, 0xcb, 0x03, 0xe1, 0x01, 0x7b, 0x4b, 0xb7, 0x5e, 0x10, 0x25, + 0xdd, 0xaf, 0x04, 0x23, 0x62, 0x3c, 0xba, 0x1a, 0x57, 0x62, 0x93, 0x0a, 0xec, 0x12, 0xab, 0x59, + 0x7b, 0x69, 0x25, 0x2b, 0x49, 0x5b, 0x4a, 0x23, 0x8f, 0x2d, 0xa7, 0x0e, 0xf6, 0x9f, 0x89, 0x08, + 0x8d, 0x92, 0x3e, 0xd5, 0xd2, 0x0c, 0x47, 0xa9, 0xf4, 0x6b, 0xb3, 0xdf, 0x37, 0x40, 0xb8, 0xa7, + 0x74, 0xbc, 0x91, 0xa0, 0x7a, 0x68, 0xd7, 0xa1, 0xe1, 0x92, 0x05, 0xf0, 0xcc, 0xe0, 0x10, 0xbb, + 0x99, 0x6d, 0xc7, 0xd7, 0x97, 0x59, 0x26, 0x58, 0xb3, 0xbe, 0x0d, 0x8d, 0x22, 0xdc, 0xb9, 0x38, + 0x29, 0x3f, 0x82, 0x18, 0xeb, 0xcf, 0xea, 0x33, 0x90, 0xd5, 0xa8, 0x63, 0xb2, 0x6e, 0xea, 0x20, + 0x49, 0x0b, 0x26, 0x78, 0x99, 0x2a, 0xab, 0xc2, 0x10, 0x45, 0x7b, 0x9b, 0x9a, 0xf8, 0x23, 0x85, + 0x5b, 0x98, 0xa8, 0x07, 0xe4, 0x16, 0x75, 0x1e, 0xf1, 0x22, 0x89, 0x4d, 0x75, 0xa5, 0x86, 0x41, + 0x40, 0x50, 0xa7, 0x82, 0xa2, 0x10, 0xfb, 0x21, 0xd5, 0xce, 0x55, 0x1c, 0xf3, 0xba, 0x58, 0x39, + 0x71, 0xab, 0x67, 0x32, 0x2c, 0x50, 0xe8, 0x5c, 0xf0, 0x00, 0x21, 0x8f, 0xc4, 0x89, 0x19, 0x75, + 0x15, 0x9a, 0xeb, 0x53, 0xe6, 0x5e, 0xb5, 0x5e, 0x26, 0x30, 0x86, 0xcf, 0x56, 0xd3, 0x09, 0x86, + 0xe1, 0xad, 0x7b, 0x58, 0x61, 0x3e, 0xdc, 0x1b, 0xb8, 0x36, 0x21, 0x33, 0x07, 0xbf, 0xa1, 0x39, + 0x5e, 0xde, 0x17, 0xa8, 0x6f, 0x9c, 0xc4, 0xc6, 0x6b, 0x46, 0xea, 0x30, 0xa6, 0x61, 0xb0, 0x2e, + 0x2e, 0x7c, 0xc9, 0x66, 0xec, 0xe5, 0x61, 0xf8, 0x81, 0x87, 0x67, 0xf5, 0x5e, 0xf7, 0xb0, 0x9d, + 0xf8, 0x91, 0x84, 0xc4, 0x3c, 0x30, 0x00, 0x2c, 0x3a, 0xa1, 0x86, 0xb7, 0x41, 0x8c, 0xf9, 0x05, + 0xb7, 0x4b, 0xf4, 0xc9, 0xfc, 0x23, 0x51, 0x64, 0x25, 0x15, 0x52, 0x9e, 0x3f, 0x35, 0xe0, 0xe4, + 0x4e, 0x0e, 0x3d, 0x56, 0x20, 0x3d, 0x30, 0x55, 0xc8, 0x78, 0x56, 0xbf, 0xc4, 0x99, 0x59, 0x4b, + 0x19, 0x11, 0x98, 0x88, 0xf7, 0x1e, 0xf7, 0xc2, 0x25, 0x57, 0x5a, 0x6a, 0x9a, 0xac, 0x98, 0xfc, + 0x32, 0x3f, 0x4d, 0xbb, 0xf6, 0x4b, 0xf2, 0xf3, 0xf6, 0xbf, 0x19, 0x0b, 0x54, 0xbc, 0xbd, 0x55, + 0x79, 0xcd, 0x94, 0xd7, 0xe0, 0x94, 0x92, 0xb7, 0x31, 0x7c, 0xfc, 0xee, 0x6c, 0x70, 0xc4, 0x29, + 0x64, 0xab, 0x69, 0x7b, 0xb6, 0xf9, 0xb0, 0x4b, 0x03, 0xde, 0x7f, 0x49, 0x40, 0x68, 0xc7, 0xc2, + 0x37, 0xbb, 0xdc, 0xf7, 0xfa, 0xae, 0x26, 0x30, 0xe2, 0xb2, 0xe3, 0xad, 0xeb, 0x96, 0xc5, 0x6e, + 0x72, 0xc7, 0x62, 0xba, 0xe1, 0x01, 0x03, 0xee, 0x4f, 0x8e, 0x58, 0x7e, 0x13, 0xcc, 0x17, 0xc9, + 0x98, 0x17, 0xa3, 0xc4, 0x46, 0x90, 0x8d, 0xcb, 0xb7, 0x55, 0xd1, 0x4c, 0x67, 0x33, 0x2c, 0x71, + 0xf5, 0x06, 0x64, 0x05, 0xd2, 0x72, 0x79, 0x29, 0xe1, 0x15, 0xfc, 0x2b, 0x88, 0xac, 0x45, 0x71, + 0x1d, 0xdd, 0xdd, 0xeb, 0x94, 0x95, 0xa8, 0x4f, 0x98, 0xf2, 0xfb, 0xf9, 0x29, 0x16, 0x36, 0xf8, + 0x92, 0x11, 0x45, 0xdf, 0xc2, 0x22, 0x75, 0x27, 0xcf, 0x37, 0xa7, 0x89, 0x12, 0x11, 0x2a, 0x6f, + 0xc5, 0x99, 0x31, 0x05, 0xe3, 0x1f, 0x1b, 0x33, 0x67, 0xe2, 0x46, 0x10, 0xb1, 0x9f, 0xb4, 0xfc, + 0x2f, 0x44, 0xfc, 0x5d, 0xbb, 0xbd, 0xe2, 0x3d, 0xa3, 0xd7, 0xe1, 0x1d, 0x42, 0xdf, 0x4a, 0xd5, + 0x78, 0xba, 0xe2, 0x62, 0x0a, 0xa2, 0xeb, 0x17, 0x5a, 0xf1, 0x03, 0xa7, 0x7e, 0x5e, 0xba, 0xa9, + 0x9b, 0x2d, 0x26, 0x19, 0xc4, 0x7c, 0x4f, 0x3f, 0xf3, 0xf1, 0xbd, 0x93, 0x55, 0x11, 0x84, 0x45, + 0x1d, 0x91, 0x21, 0x53, 0x43, 0xf8, 0x91, 0x9c, 0x5c, 0x5e, 0xa4, 0xf2, 0x46, 0x25, 0xdb, 0x2c, + 0xc4, 0x9c, 0x14, 0xcf, 0x00, 0x3e, 0x18, 0x66, 0x00, 0x0e, 0x7a, 0x56, 0x6c, 0x49, 0xe5, 0xfe, + 0xfe, 0xdb, 0x69, 0xa4, 0x2a, 0xc5, 0x5a, 0x49, 0x69, 0xb6, 0x6e, 0x27, 0xad, 0xa1, 0x80, 0xb5, + 0x55, 0xff, 0xa2, 0x65, 0xc1, 0x08, 0x52, 0xe3, 0xca, 0xac, 0xc3, 0xbc, 0xb0, 0x38, 0x60, 0xc4, + 0xb1, 0xc7, 0x2f, 0x07, 0x1b, 0x9c, 0x59, 0x87, 0x1d, 0xc5, 0xc2, 0x30, 0xa4, 0x1f, 0x40, 0xf1, + 0x95, 0x47, 0x6e, 0x56, 0x67, 0x87, 0x9e, 0x70, 0xe3, 0x87, 0x70, 0xbf, 0x36, 0xc3, 0xd2, 0x80, + 0x12, 0xde, 0xb4, 0x32, 0x67, 0x6c, 0x37, 0xae, 0xbf, 0x37, 0x79, 0x35, 0x0b, 0x40, 0x7d, 0xc3, + 0x2a, 0x2f, 0x93, 0xbf, 0xed, 0xe2, 0x04, 0x04, 0x48, 0xae, 0xd3, 0x44, 0xd1, 0x36, 0x2a, 0x1d, + 0xbc, 0xab, 0xa9, 0xf8, 0xea, 0xc5, 0xf7, 0x9f, 0xb0, 0x6b, 0x50, 0xbf, 0x14, 0x55, 0x5a, 0xd6, + 0xaf, 0x94, 0x82, 0xb7, 0x79, 0x39, 0x4f, 0xaa, 0x61, 0x1e, 0x43, 0x2a, 0xd2, 0xf1, 0xd1, 0x71, + 0x4d, 0x22, 0x60, 0xa6, 0x78, 0x7c, 0x97, 0xe9, 0xbf, 0x82, 0xa8, 0xf0, 0x58, 0x70, 0x7b, 0x30, + 0xee, 0x3c, 0x70, 0x50, 0xb4, 0x22, 0x2b, 0x1a, 0xa2, 0x39, 0xe7, 0x64, 0xf6, 0x9a, 0xe2, 0x61, + 0x49, 0xc0, 0xb0, 0x58, 0xc9, 0x01, 0xa3, 0xfb, 0xbe, 0xe4, 0x8d, 0x10, 0x0c, 0x4c, 0xe6, 0x08, + 0xc1, 0x37, 0xa6, 0x87, 0xc8, 0x66, 0xd5, 0x5e, 0xad, 0x66, 0xa8, 0x8c, 0x87, 0x08, 0x02, 0x72, + 0x89, 0x68, 0xe2, 0xb7, 0x76, 0xdd, 0xeb, 0x88, 0x12, 0x14, 0x30, 0x3b, 0x72, 0xf7, 0x49, 0xa4, + 0x25, 0x86, 0x59, 0xc8, 0x82, 0x41, 0x2d, 0xae, 0xa0, 0x81, 0xf6, 0xc2, 0x24, 0xb5, 0x2d, 0xb9, + 0x8e, 0xf8, 0xf8, 0xb9, 0xfe, 0xce, 0xef, 0x2a, 0x5e, 0x27, 0x86, 0xc6, 0x61, 0x33, 0xf1, 0x25, + 0xcc, 0xc5, 0x90, 0x15, 0xb7, 0x09, 0x76, 0x55, 0x5c, 0xfd, 0x08, 0xe9, 0x39, 0x02, 0x75, 0xaf, + 0x98, 0x20, 0xf7, 0x85, 0x22, 0x04, 0x82, 0x22, 0xa6, 0x1d, 0xd5, 0x01, 0xf7, 0xa1, 0xbb, 0xe0, + 0xa8, 0xb1, 0xba, 0x6d, 0xcf, 0x8f, 0x6f, 0x7d, 0x7c, 0x15, 0x10, 0x56, 0xf9, 0x7e, 0x55, 0xc2, + 0x38, 0x58, 0x73, 0x37, 0x65, 0xf6, 0xf3, 0x27, 0x89, 0x08, 0x42, 0xee, 0x21, 0x55, 0x0f, 0x9f, + 0x30, 0x8a, 0xca, 0x5d, 0x93, 0x44, 0xaf, 0x89, 0xb6, 0x98, 0xd5, 0xce, 0x49, 0xf8, 0x4b, 0xaf, + 0x41, 0x0e, 0x24, 0x85, 0x77, 0xf1, 0x32, 0x69, 0x4f, 0x80, 0x11, 0xd8, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x47, 0x23, 0xb1, 0x22, 0xe2, 0x62, 0xb8, 0xaa, 0xaf, 0x33, 0x1f, 0x96, 0x23, 0x9a, + 0x82, 0x9e, 0x08, 0x6f, 0x7c, 0xa2, 0x62, 0x62, 0x48, 0xea, 0xeb, 0x95, 0x85, 0xf1, 0x9d, 0x8d, + 0xd6, 0xb1, 0x2f, 0xb0, 0x51, 0x69, 0x95, 0xd5, 0x45, 0xfc, 0xd2, 0xe4, 0x0f, 0x67, 0x4d, 0x70, + 0x5c, 0x72, 0xe5, 0x4d, 0xf4, 0x96, 0x28, 0x31, 0x89, 0x84, 0xc4, 0x72, 0xe3, 0x66, 0x8b, 0x26, + 0x7e, 0x20, 0x75, 0x34, 0xf4, 0xdf, 0xac, 0x9f, 0x12, 0x20, 0x10, 0xf7, 0x6b, 0xdc, 0x4c, 0x12, + 0xea, 0xfc, 0xf8, 0xfb, 0xb8, 0x9f, 0x13, 0x04, 0x45, 0xaa, 0xdf, 0x89, 0xfc, 0x59, 0x9d, 0xef, + 0xb9, 0x73, 0x08, 0xe0, 0xb7, 0x98, 0x6a, 0x6f, 0x15, 0xf9, 0x06, 0x6a, 0xbe, 0x12, 0x3a, 0xb5, + 0xbd, 0x57, 0x89, 0x44, 0x79, 0x78, 0x22, 0xbd, 0xfd, 0x51, 0x3e, 0x24, 0x4f, 0x13, 0x82, 0x3e, + 0x3e, 0xab, 0xae, 0xbb, 0x6a, 0x23, 0x97, 0x89, 0xe7, 0xca, 0x7d, 0x5a, 0xf0, 0x45, 0x54, 0x3b, + 0x7d, 0xf0, 0x47, 0x2b, 0x7b, 0xc9, 0xd5, 0xee, 0x20, 0x48, 0xf1, 0x13, 0x41, 0xb9, 0x52, 0xf9, + 0x7d, 0xef, 0x89, 0xba, 0xe6, 0x58, 0x28, 0x08, 0x84, 0x3c, 0xd8, 0x91, 0x31, 0xa8, 0x2c, 0xa9, + 0x2b, 0xd3, 0x40, 0x03, 0x20, 0xe4, 0x0f, 0x38, 0x64, 0xa2, 0x70, 0x65, 0xe4, 0x3f, 0xc5, 0x10, + 0x02, 0xc0, 0x17, 0x11, 0x55, 0x71, 0x0f, 0x12, 0x70, 0xe5, 0xb9, 0x7c, 0x36, 0x40, 0x29, 0x30, + 0x1a, 0x5d, 0x24, 0x00, 0x04, 0x00, 0x52, 0x0b, 0x5e, 0x92, 0x03, 0x7e, 0xaa, 0xa0, 0x87, 0x9b, + 0x5a, 0xe2, 0x04, 0x04, 0x0b, 0x53, 0x73, 0xbf, 0x58, 0xba, 0xc5, 0xda, 0xf4, 0x5e, 0xf8, 0x47, + 0x97, 0xa6, 0xec, 0x4e, 0x88, 0xad, 0x98, 0xb5, 0x34, 0x6a, 0x8f, 0x2d, 0x8f, 0x6f, 0xe0, 0x9c, + 0xdc, 0xdd, 0x22, 0xf6, 0x84, 0xfb, 0xf1, 0x11, 0x9a, 0xd4, 0x5c, 0x47, 0x9b, 0xb3, 0x8b, 0xe5, + 0xb5, 0x9f, 0x11, 0x08, 0x4d, 0xd5, 0xde, 0x59, 0x9a, 0xe4, 0xff, 0x8b, 0xd6, 0xb8, 0x5c, 0xd5, + 0x78, 0x8d, 0x44, 0xd7, 0xa6, 0xc3, 0x20, 0xab, 0x8c, 0x12, 0x1f, 0x7a, 0xa2, 0x00, 0x1a, 0xba, + 0x00, 0x02, 0x2a, 0x3a, 0x1e, 0x1e, 0x38, 0x0a, 0xab, 0x91, 0x95, 0xb2, 0x80, 0x92, 0x84, 0x21, + 0x19, 0x4d, 0x18, 0xf0, 0x42, 0x0c, 0x02, 0x90, 0x46, 0x2c, 0x6a, 0x2f, 0x02, 0x52, 0x62, 0x7c, + 0x1c, 0x74, 0x03, 0xa1, 0x48, 0x12, 0x9c, 0x79, 0x30, 0xe4, 0x30, 0xff, 0x16, 0xce, 0x07, 0xd9, + 0xee, 0x16, 0x0c, 0xdc, 0x80, 0x39, 0xa0, 0xe0, 0x7d, 0x80, 0x01, 0x34, 0x02, 0x68, 0x68, 0x21, + 0x82, 0x10, 0x70, 0x1f, 0x83, 0x61, 0x2e, 0xe4, 0x2b, 0x2a, 0x1d, 0xa8, 0x7c, 0xcb, 0x80, 0x00, + 0x23, 0xc6, 0x82, 0x69, 0x0c, 0xe5, 0xdd, 0x00, 0x07, 0x90, 0xbc, 0x9d, 0xfb, 0xc5, 0x66, 0xf8, + 0x64, 0x0b, 0x03, 0x7c, 0x4f, 0x97, 0x82, 0x69, 0x80, 0x69, 0xc8, 0x2b, 0x1f, 0x72, 0x0e, 0x84, + 0xc1, 0x35, 0x30, 0x2e, 0x40, 0x96, 0x33, 0x29, 0xcd, 0x18, 0x8f, 0xa6, 0xc9, 0x90, 0x9e, 0x03, + 0x00, 0x6c, 0xfc, 0x38, 0x4e, 0x0c, 0xb1, 0x9f, 0x90, 0xc1, 0x04, 0x01, 0x93, 0x06, 0x28, 0x03, + 0x50, 0x30, 0x1c, 0xc0, 0xc7, 0xac, 0xab, 0x7a, 0x60, 0xeb, 0x29, 0x6d, 0x1a, 0x6d, 0x20, 0xe8, + 0x85, 0xa2, 0xa1, 0x38, 0x0b, 0xdc, 0x3d, 0x11, 0x7e, 0x2a, 0xe5, 0xa0, 0x5b, 0xa0, 0xdf, 0x4b, + 0xc8, 0x1c, 0xbd, 0xfc, 0xb7, 0x7b, 0x93, 0x9b, 0x7b, 0xf9, 0xb5, 0xaf, 0x10, 0x30, 0xe4, 0xc3, + 0xb8, 0xf5, 0xce, 0xa2, 0xed, 0x08, 0xf8, 0x96, 0xbc, 0x45, 0x7b, 0x88, 0x88, 0xee, 0xca, 0x0e, + 0x3b, 0xf8, 0x2e, 0xbd, 0xfb, 0xbb, 0xfc, 0x14, 0x12, 0x52, 0x65, 0xcb, 0x77, 0xdd, 0x7d, 0xd6, + 0xdd, 0x72, 0x52, 0x7f, 0xd0, 0x97, 0xc5, 0xb1, 0xe1, 0xc5, 0x31, 0x3b, 0x28, 0x51, 0x04, 0x00, + 0x01, 0x5a, 0x76, 0xb2, 0x34, 0xf2, 0x3f, 0xc5, 0x84, 0x0b, 0xd2, 0x6e, 0x9f, 0x98, 0xe7, 0x43, + 0xcc, 0xc0, 0x0f, 0xcd, 0xa2, 0x91, 0x33, 0x19, 0xc7, 0xff, 0x4e, 0x4a, 0x71, 0xf2, 0xd0, 0x1d, + 0xf8, 0xe8, 0xb8, 0x3b, 0xf1, 0xcd, 0xe3, 0xb2, 0xec, 0x5b, 0x27, 0x03, 0xe0, 0xc1, 0x91, 0x14, + 0xc9, 0xf3, 0xc1, 0xb0, 0xbb, 0xa7, 0x83, 0x90, 0xc8, 0xd9, 0x44, 0xf2, 0x61, 0xfc, 0x9c, 0x00, + 0xfc, 0xe0, 0x35, 0x32, 0xf9, 0xb3, 0xf0, 0xa2, 0xa3, 0x8c, 0x4b, 0x00, 0x38, 0xcb, 0x00, 0x31, + 0x3c, 0xb8, 0xaa, 0x3e, 0x0c, 0x40, 0x45, 0x00, 0xb6, 0x9e, 0xdb, 0xfd, 0x3c, 0x40, 0x30, 0x1b, + 0x0a, 0x1c, 0x00, 0x26, 0x44, 0x41, 0x11, 0x7d, 0x91, 0x1c, 0x9e, 0x0d, 0x28, 0xe9, 0xe1, 0xe0, + 0x0c, 0x23, 0xbc, 0xf7, 0x8e, 0xa8, 0xac, 0xb6, 0x8d, 0x1f, 0xa1, 0xa4, 0x33, 0xfc, 0x1c, 0x83, + 0x10, 0x59, 0xd7, 0x20, 0xd1, 0x33, 0x14, 0x94, 0x01, 0x55, 0x2f, 0x59, 0x94, 0x1d, 0x54, 0x6f, + 0x88, 0xbc, 0xef, 0x85, 0xa1, 0xc8, 0xc7, 0x56, 0xe0, 0xe0, 0x80, 0xbd, 0x13, 0xac, 0x1c, 0x40, + 0x00, 0x40, 0x07, 0x95, 0x17, 0x42, 0xd0, 0x00, 0x3e, 0x3a, 0x7f, 0x22, 0x12, 0xf8, 0xbb, 0x88, + 0xfc, 0x37, 0xc5, 0x75, 0x55, 0xd4, 0xdc, 0x79, 0x54, 0x2b, 0xd3, 0x58, 0xd1, 0xaa, 0x22, 0x91, + 0x75, 0x5a, 0xae, 0x6e, 0x2f, 0xc4, 0x45, 0x45, 0x62, 0xb4, 0x41, 0xf0, 0xa8, 0xb3, 0x5f, 0x04, + 0xa6, 0x39, 0x90, 0xe9, 0x61, 0x60, 0x19, 0xc7, 0x89, 0x0e, 0x08, 0xe3, 0x32, 0x24, 0x5b, 0x16, + 0x10, 0x47, 0x3b, 0x95, 0xb6, 0xff, 0xc0, 0xe3, 0x0a, 0x13, 0x17, 0x50, 0xe3, 0xd6, 0x00, 0x00, + 0x9a, 0xd1, 0x42, 0x0f, 0x0c, 0xa0, 0xd6, 0x0b, 0x5a, 0x91, 0x5b, 0x41, 0xf0, 0x01, 0xe5, 0x5d, + 0x49, 0xd5, 0x0e, 0xb0, 0x94, 0xe8, 0x3b, 0x58, 0x77, 0x00, 0x3a, 0xd9, 0x30, 0x85, 0x5c, 0x18, + 0x41, 0xb1, 0x1f, 0xeb, 0x5c, 0x9d, 0x59, 0xd9, 0x65, 0x8b, 0x9a, 0xf0, 0x60, 0x3f, 0xa8, 0x40, + 0xdd, 0x2c, 0xa8, 0xeb, 0x58, 0xc5, 0x81, 0xe2, 0x5f, 0x8e, 0x39, 0xc3, 0x9b, 0xe0, 0x40, 0x02, + 0x40, 0xd9, 0x42, 0x1e, 0x47, 0x00, 0x01, 0x1e, 0x38, 0x83, 0xc1, 0xa3, 0xb9, 0x09, 0xc0, 0x05, + 0x4b, 0x00, 0x1f, 0x50, 0xea, 0x93, 0x02, 0xd0, 0x47, 0xd4, 0x94, 0x02, 0xa1, 0xaf, 0x05, 0x41, + 0x24, 0x84, 0x5f, 0x78, 0x7c, 0x84, 0x78, 0x70, 0xc4, 0x81, 0x87, 0xdb, 0x26, 0xf8, 0x1a, 0x40, + 0xa2, 0x14, 0x88, 0xfb, 0x3b, 0xe2, 0x50, 0x2b, 0x3f, 0xfb, 0xad, 0xcc, 0x9b, 0x4b, 0x75, 0xc3, + 0xf9, 0xb3, 0x27, 0x2a, 0x78, 0x1c, 0x2f, 0x70, 0x30, 0x84, 0x06, 0xd6, 0x20, 0x97, 0x2b, 0x84, + 0x2c, 0xae, 0x22, 0x43, 0x97, 0x63, 0x88, 0x17, 0xa0, 0xc3, 0xdc, 0xa7, 0xd7, 0x64, 0xcc, 0x70, + 0x6a, 0x21, 0xe3, 0x54, 0x26, 0x47, 0xa2, 0xea, 0x3b, 0xde, 0x1d, 0x50, 0x01, 0xfd, 0x87, 0x68, + 0x9f, 0xfb, 0xbb, 0x62, 0xa5, 0x9b, 0x3d, 0x82, 0xfe, 0x2e, 0xc1, 0x9b, 0x05, 0xdb, 0x3c, 0x71, + 0xa6, 0x5d, 0x8b, 0x71, 0xa6, 0x9d, 0x0a, 0x34, 0x53, 0xed, 0xb9, 0x2f, 0x85, 0x86, 0x1f, 0x1f, + 0x85, 0xa5, 0xa7, 0x83, 0x10, 0x6b, 0x08, 0xf0, 0x07, 0x9c, 0x00, 0xe2, 0x10, 0x8d, 0x13, 0xda, + 0x95, 0xb1, 0xd5, 0xf0, 0xcf, 0x25, 0xef, 0x2f, 0x65, 0x55, 0xdf, 0x10, 0x48, 0xd2, 0xf9, 0x5f, + 0x88, 0x2d, 0xdf, 0xf0, 0x87, 0x17, 0x9a, 0x5b, 0xad, 0x23, 0x62, 0x89, 0x82, 0xad, 0xd3, 0x71, + 0x2b, 0x2d, 0x93, 0x39, 0x1f, 0x7a, 0xd5, 0x4a, 0x0f, 0x67, 0x00, 0xf7, 0xf9, 0x6a, 0xd7, 0x38, + 0x00, 0x70, 0x0f, 0xcd, 0x7c, 0xc5, 0xaa, 0xfc, 0xa6, 0xd5, 0x57, 0x2c, 0x6c, 0xc7, 0x5f, 0x02, + 0x88, 0x8c, 0x3d, 0x38, 0x08, 0x83, 0xaf, 0x47, 0xe1, 0x3f, 0xfb, 0x7d, 0x31, 0x4b, 0x12, 0x90, + 0x80, 0xaa, 0x07, 0x7f, 0xa6, 0x9e, 0xdc, 0x38, 0x88, 0x00, 0xbd, 0x61, 0x6d, 0x38, 0xff, 0xfa, + 0x6d, 0xb6, 0x0e, 0x74, 0x06, 0x1c, 0xb4, 0xc5, 0xbc, 0x55, 0x89, 0x1d, 0x87, 0x14, 0x01, 0x7a, + 0xb5, 0xcd, 0xef, 0xfb, 0x4d, 0xff, 0xe7, 0x4d, 0x3d, 0xb1, 0x99, 0x70, 0xe2, 0x80, 0x0c, 0x7b, + 0xeb, 0xed, 0xfb, 0xfc, 0xff, 0xed, 0xb4, 0x0f, 0xbb, 0x65, 0x8b, 0x14, 0xc0, 0x3e, 0x92, 0x5e, + 0x1f, 0x69, 0xa1, 0xbc, 0x00, 0x3b, 0x48, 0xc8, 0x0b, 0xf6, 0x20, 0x46, 0x9f, 0xf0, 0xb0, 0x3b, + 0x00, 0xaf, 0x51, 0x4f, 0xe7, 0xb1, 0x49, 0x6d, 0x29, 0x32, 0x25, 0xb4, 0xaa, 0xc3, 0xc7, 0xbd, + 0x95, 0xda, 0xd1, 0xac, 0xc0, 0x34, 0xd0, 0xf8, 0x8f, 0x58, 0xd1, 0x89, 0x1e, 0xf5, 0xb3, 0xc2, + 0x02, 0x46, 0xc0, 0xa0, 0x19, 0x15, 0xcd, 0x42, 0xc0, 0x37, 0x2b, 0xe6, 0x07, 0x68, 0x8b, 0x52, + 0x26, 0xe6, 0x46, 0x1a, 0xbc, 0x00, 0x1c, 0x38, 0x3c, 0xe0, 0xe2, 0x85, 0x6f, 0x29, 0x01, 0xb1, + 0x6f, 0x29, 0x00, 0x6a, 0x0e, 0x5b, 0x0c, 0x18, 0x97, 0x36, 0xf2, 0x58, 0xba, 0x70, 0xee, 0x00, + 0x8a, 0xe2, 0x0b, 0xd4, 0x84, 0x6f, 0x18, 0x94, 0x96, 0x26, 0x90, 0x05, 0xb0, 0xa0, 0x01, 0xb8, + 0x30, 0xaf, 0x32, 0xde, 0x71, 0xe6, 0x07, 0xe2, 0x57, 0x87, 0x13, 0xea, 0x38, 0xa0, 0xfc, 0x39, + 0x7c, 0x7b, 0xe2, 0xeb, 0x1c, 0x6d, 0xf1, 0x82, 0x92, 0x64, 0xe9, 0x65, 0xad, 0x9b, 0x40, 0xc6, + 0xec, 0x22, 0x08, 0x02, 0x90, 0xf9, 0x6e, 0x96, 0x7d, 0x2f, 0x2c, 0x0c, 0xfb, 0x05, 0x0a, 0x66, + 0x15, 0x3e, 0xc9, 0x80, 0x00, 0x82, 0x9b, 0x95, 0x40, 0x87, 0x02, 0xab, 0x2c, 0x31, 0xd7, 0x58, + 0x29, 0x28, 0x8d, 0x56, 0x24, 0x30, 0x14, 0xad, 0x08, 0x3c, 0xfd, 0x6c, 0xbe, 0x90, 0x90, 0xf5, + 0xd4, 0xa3, 0xfb, 0xc0, 0x38, 0x7b, 0xd4, 0x08, 0x19, 0x56, 0xc3, 0x99, 0x57, 0x4e, 0x45, 0x80, + 0xa1, 0x03, 0x00, 0x42, 0xc8, 0x99, 0x37, 0xc9, 0x9b, 0xa4, 0xf6, 0x5c, 0x8b, 0xe0, 0x30, 0x40, + 0xc0, 0x1e, 0x8b, 0x97, 0xad, 0x20, 0xb0, 0x2a, 0xa5, 0x7a, 0xa9, 0x76, 0xa5, 0xe0, 0x64, 0x83, + 0x13, 0xe1, 0x7e, 0x2b, 0xb1, 0xc4, 0xe0, 0x08, 0xb9, 0x2b, 0xaa, 0xef, 0x69, 0xaa, 0xec, 0xa0, + 0xd4, 0xfc, 0x35, 0xcf, 0xbc, 0xd0, 0xcc, 0x16, 0x15, 0xcf, 0xbd, 0xdf, 0xb9, 0xf9, 0xc1, 0xc0, + 0x82, 0x19, 0x0a, 0x0a, 0x0a, 0x03, 0xe2, 0xbf, 0xf6, 0x4e, 0xfa, 0x37, 0xa8, 0x1a, 0xd5, 0x77, + 0x74, 0x85, 0x11, 0x48, 0x2b, 0x39, 0xc7, 0xe1, 0x10, 0x80, 0x52, 0x4f, 0x64, 0xaf, 0x77, 0x25, + 0x57, 0x2d, 0xb6, 0x7c, 0xb3, 0xf9, 0x51, 0xd3, 0x82, 0x91, 0x20, 0xa4, 0xa9, 0x13, 0x1b, 0xcb, + 0x31, 0x43, 0x11, 0xc3, 0x8e, 0x3d, 0xdf, 0xd8, 0x61, 0x40, 0x2b, 0x5f, 0x61, 0x1e, 0x6d, 0x5e, + 0x81, 0x40, 0x9d, 0xb5, 0x10, 0xc5, 0x86, 0x3a, 0xda, 0xdb, 0x6f, 0xe4, 0x0c, 0x06, 0x08, 0x1e, + 0x42, 0x85, 0x6f, 0x26, 0x00, 0x55, 0x9c, 0xb6, 0x78, 0x38, 0x48, 0x00, 0xf6, 0xb5, 0x4b, 0x0c, + 0x5c, 0x50, 0xc1, 0x99, 0x49, 0xa7, 0x38, 0x58, 0x37, 0xfd, 0x16, 0x90, 0xf3, 0x10, 0x00, 0xee, + 0x4a, 0x40, 0xde, 0xdd, 0xc8, 0xcb, 0xf7, 0x8c, 0x9e, 0xae, 0x7f, 0xa6, 0xaa, 0x0f, 0x5c, 0xbb, + 0x19, 0x8e, 0xab, 0x5b, 0xe2, 0xbc, 0x38, 0x42, 0x80, 0x2e, 0xd9, 0xb0, 0x88, 0x53, 0x92, 0x35, + 0xed, 0xfd, 0xb3, 0xc4, 0x7c, 0xfc, 0x1d, 0xf9, 0x62, 0xd4, 0xef, 0x07, 0x57, 0x1d, 0x5f, 0x47, + 0xdf, 0x75, 0xfc, 0x30, 0x14, 0x9e, 0x3e, 0x4f, 0x07, 0xe5, 0xe3, 0xfe, 0xa7, 0x3c, 0xf1, 0xec, + 0x65, 0xb0, 0xb3, 0x42, 0xe1, 0xc0, 0xf3, 0x80, 0x70, 0x90, 0x00, 0x15, 0xa0, 0x87, 0x80, 0x70, + 0x00, 0xe2, 0x36, 0x1e, 0x5a, 0x8d, 0x38, 0x3e, 0xc3, 0x5f, 0x05, 0x40, 0xd0, 0x36, 0x8c, 0x31, + 0xa6, 0xb1, 0x84, 0x73, 0x4c, 0x7c, 0x06, 0x47, 0xf8, 0xba, 0xb3, 0x8e, 0x11, 0xef, 0x07, 0xd7, + 0x0e, 0x45, 0x83, 0x30, 0xbb, 0x46, 0x80, 0x00, 0x80, 0x12, 0x2c, 0x09, 0x50, 0x51, 0xbc, 0x1d, + 0x7f, 0x45, 0xb7, 0xe0, 0x32, 0x40, 0xc0, 0x14, 0x93, 0x7a, 0x30, 0xd6, 0x71, 0x0e, 0x89, 0x63, + 0x54, 0xcb, 0xae, 0x80, 0x6a, 0x44, 0xda, 0x2d, 0x4d, 0x4a, 0xd6, 0x57, 0x2f, 0xab, 0x41, 0x64, + 0x09, 0x10, 0x44, 0x53, 0xe2, 0x57, 0xb9, 0xd3, 0xc2, 0x00, 0xa7, 0xcd, 0x91, 0xab, 0xec, 0x63, + 0x42, 0x4a, 0x2b, 0x2d, 0x19, 0xc0, 0x82, 0x19, 0x05, 0x66, 0x3c, 0x7d, 0x33, 0xdc, 0x7e, 0x3e, + 0x6c, 0x52, 0x60, 0x58, 0xab, 0xb0, 0xc9, 0x16, 0x2e, 0x55, 0xe0, 0xb4, 0xaa, 0xab, 0x59, 0xa4, + 0x90, 0x28, 0x01, 0x28, 0xd6, 0x5c, 0x8a, 0x56, 0x04, 0x10, 0x88, 0x52, 0x21, 0xc2, 0xc0, 0x67, + 0xc3, 0xdc, 0x15, 0xf6, 0x2b, 0xbb, 0x8a, 0xe7, 0xc2, 0xc8, 0x9b, 0xd7, 0xc3, 0x88, 0x80, 0x01, + 0x9e, 0x48, 0xcc, 0x36, 0x12, 0x38, 0x4f, 0x38, 0xbe, 0x3f, 0x18, 0x87, 0xd3, 0x18, 0x90, 0x7f, + 0xc9, 0xaa, 0x4c, 0xa8, 0x51, 0x88, 0x2d, 0x67, 0x8e, 0x3f, 0x0c, 0x81, 0xcb, 0x5f, 0xaa, 0x78, + 0x20, 0x0c, 0x85, 0x21, 0xf8, 0x25, 0x26, 0x00, 0x02, 0x95, 0x2b, 0x51, 0xb6, 0x09, 0x42, 0x43, + 0x86, 0x77, 0x05, 0x63, 0xac, 0xb0, 0xcb, 0x58, 0x93, 0x83, 0xef, 0x19, 0xc7, 0x96, 0x33, 0xa1, + 0x95, 0x0c, 0xc4, 0x80, 0x82, 0xc5, 0xb3, 0x30, 0xaf, 0x27, 0xb6, 0x7f, 0x75, 0xd6, 0xba, 0x7c, + 0x45, 0xfc, 0x30, 0x06, 0x81, 0xa4, 0x12, 0x3e, 0x42, 0xaa, 0xc4, 0xde, 0x58, 0xec, 0x48, 0xe3, + 0xfb, 0xf0, 0x2c, 0x39, 0x2d, 0xfd, 0xf1, 0x17, 0x01, 0x20, 0x01, 0x87, 0xc0, 0x05, 0xfc, 0xf4, + 0x83, 0xfe, 0x9e, 0x03, 0x04, 0x48, 0xdc, 0x65, 0xad, 0xcc, 0xbb, 0xa6, 0xdc, 0x89, 0xd0, 0xdd, + 0x9f, 0x2e, 0x56, 0x78, 0x71, 0x96, 0x78, 0x1e, 0x07, 0xbb, 0x13, 0xd2, 0xbe, 0x0a, 0x39, 0x2e, + 0xfb, 0xe0, 0x93, 0xc0, 0xeb, 0x12, 0xb9, 0xc1, 0xc0, 0x90, 0x8d, 0xee, 0x4c, 0x79, 0x32, 0x88, + 0xfc, 0x3f, 0x77, 0x3d, 0xe4, 0x91, 0x02, 0xc1, 0x80, 0x81, 0x70, 0xb7, 0x48, 0x89, 0x2a, 0x58, + 0xd6, 0x1e, 0x1c, 0xb2, 0xf8, 0x51, 0x41, 0x2e, 0x68, 0xdf, 0xfa, 0x54, 0xd3, 0xe1, 0x85, 0x00, + 0x95, 0x92, 0xb9, 0xe7, 0x4f, 0xa6, 0x9e, 0x63, 0x5e, 0xd8, 0xe9, 0x70, 0x20, 0xc2, 0x84, 0x95, + 0xaa, 0xfb, 0xfe, 0x35, 0x87, 0x7b, 0xba, 0x25, 0x68, 0xb0, 0x2d, 0xe6, 0x30, 0xe6, 0x00, 0x2a, + 0x9b, 0xb8, 0x68, 0x83, 0xa0, 0xf4, 0x5b, 0xa8, 0xf8, 0x7b, 0x8e, 0xd7, 0xe5, 0x48, 0xe3, 0x7d, + 0x36, 0xd6, 0xab, 0xb4, 0xb5, 0xd6, 0x29, 0x00, 0xc2, 0x36, 0xf9, 0xf9, 0x7a, 0xdc, 0x70, 0xc0, + 0x52, 0x60, 0x42, 0x34, 0x58, 0x13, 0xf2, 0xc0, 0xcf, 0x03, 0xa3, 0x13, 0x00, 0x3e, 0x1d, 0x0f, + 0x05, 0xd1, 0x98, 0xd9, 0xe0, 0x00, 0x42, 0x80, 0xfd, 0x05, 0xe2, 0x9b, 0xeb, 0x40, 0xf4, 0x91, + 0x6f, 0x87, 0xb8, 0x68, 0x05, 0xc3, 0x12, 0xb4, 0x3f, 0xa0, 0x83, 0xf0, 0xa7, 0x11, 0xca, 0x61, + 0xdc, 0xa8, 0x52, 0x78, 0x05, 0xd9, 0x0b, 0xb2, 0xa6, 0x07, 0xc3, 0x66, 0xc0, 0x81, 0xd3, 0x62, + 0x56, 0x83, 0xc2, 0x5a, 0x80, 0x36, 0xe8, 0x3e, 0x13, 0x07, 0xe3, 0xc0, 0x00, 0xed, 0xf0, 0x00, + 0x3b, 0x84, 0xe0, 0x00, 0x5d, 0x46, 0x98, 0x34, 0x7c, 0x18, 0x04, 0x02, 0x91, 0xc0, 0xfc, 0x07, + 0x0d, 0xc2, 0xc0, 0x01, 0x96, 0x00, 0x30, 0x73, 0xe1, 0x60, 0x78, 0x0f, 0x7e, 0x8a, 0x00, 0xc4, + 0x80, 0xe0, 0x77, 0x35, 0x0e, 0xb2, 0x51, 0xc7, 0xd3, 0xc3, 0x87, 0x80, 0x07, 0x0a, 0x44, 0xa3, + 0x30, 0x64, 0x6b, 0x01, 0xe2, 0x19, 0x0a, 0x09, 0x31, 0x68, 0xe4, 0xf9, 0xc7, 0x2e, 0x64, 0x96, + 0x27, 0x59, 0x7e, 0xea, 0x4f, 0x10, 0x9d, 0x83, 0x54, 0xa3, 0xca, 0x79, 0xc2, 0xc3, 0x2c, 0xcf, + 0x70, 0x88, 0x44, 0x11, 0x1a, 0x6e, 0xe5, 0xb7, 0x18, 0x0d, 0x10, 0x28, 0x02, 0xa2, 0x28, 0xa1, + 0xe2, 0x0e, 0x0b, 0xa4, 0x5c, 0x72, 0xdb, 0xbb, 0x7c, 0x14, 0x40, 0xb0, 0xc1, 0x2c, 0x92, 0x00, + 0x01, 0xec, 0x82, 0xa3, 0x00, 0x02, 0x55, 0x8d, 0x06, 0x1b, 0x9d, 0x88, 0x6c, 0x28, 0x28, 0xe4, + 0x8e, 0x4a, 0x64, 0xef, 0xf0, 0x45, 0x72, 0x88, 0x5c, 0x7d, 0x3b, 0x8e, 0x30, 0x43, 0x1f, 0x1b, + 0x4b, 0x88, 0x14, 0x06, 0x13, 0x61, 0x4e, 0xd4, 0xf0, 0x00, 0x27, 0x1e, 0x0f, 0x09, 0xc7, 0xc5, + 0x8e, 0xc5, 0x77, 0xf1, 0xf1, 0x42, 0xfe, 0x39, 0xa5, 0xd9, 0xce, 0x87, 0xf6, 0x59, 0x55, 0x63, + 0x99, 0x97, 0xc1, 0x04, 0x6c, 0xfe, 0x27, 0x2e, 0xfb, 0x88, 0x7c, 0x67, 0x3e, 0xb6, 0xd3, 0xe6, + 0x5f, 0x2f, 0xf8, 0x60, 0x87, 0x00, 0x65, 0xaf, 0xec, 0x1f, 0xed, 0xb6, 0xde, 0x7e, 0x6e, 0xfb, + 0xac, 0x9b, 0x97, 0x90, 0xb0, 0xd2, 0x80, 0x18, 0x17, 0x4d, 0xd2, 0xe9, 0xbe, 0x7f, 0x7f, 0x24, + 0x36, 0xf1, 0x70, 0x28, 0x82, 0x91, 0xa4, 0x0a, 0xb8, 0x1d, 0xf1, 0x28, 0x03, 0xc2, 0xca, 0x1a, + 0x72, 0xb5, 0xbe, 0x00, 0x1c, 0x07, 0x04, 0x4c, 0x3c, 0x1c, 0x2d, 0xbc, 0x69, 0xcb, 0x88, 0x80, + 0x79, 0xbb, 0x39, 0x91, 0x7c, 0x98, 0x34, 0x8c, 0xc3, 0x4e, 0x93, 0x31, 0xbe, 0x15, 0x75, 0xdf, + 0x84, 0x46, 0xce, 0xd4, 0xc0, 0x81, 0xe8, 0x15, 0x20, 0xb8, 0x80, 0x62, 0xac, 0x6e, 0x80, 0x00, + 0x40, 0x1e, 0x61, 0x1c, 0x00, 0x04, 0x03, 0x7c, 0xbc, 0x13, 0xfc, 0xbc, 0x43, 0x33, 0x29, 0x82, + 0x93, 0x02, 0xb8, 0x3a, 0x3b, 0x3a, 0x65, 0xb6, 0xdd, 0x43, 0x70, 0xc1, 0x84, 0xbe, 0xd3, 0x6e, + 0x7c, 0x07, 0x56, 0xc3, 0x8a, 0x07, 0x26, 0xa0, 0x07, 0x16, 0x0a, 0xef, 0x43, 0xdd, 0xeb, 0x0d, + 0x39, 0xe0, 0xb3, 0xd6, 0x0d, 0x1d, 0x45, 0x40, 0x1a, 0x36, 0x40, 0x07, 0xad, 0xf4, 0x78, 0xa5, + 0xa0, 0x8a, 0x79, 0x69, 0xc6, 0xc5, 0xcb, 0x19, 0x7d, 0x05, 0xdb, 0x7c, 0x83, 0x9d, 0x7b, 0x67, + 0xe5, 0xd0, 0xff, 0x70, 0x18, 0x00, 0x2e, 0x46, 0xc7, 0x4f, 0x33, 0x9c, 0xe5, 0xa0, 0x38, 0x3d, + 0x94, 0xaa, 0xfe, 0x4e, 0x1c, 0x88, 0xd8, 0xf0, 0x90, 0x0d, 0x5b, 0x82, 0xc0, 0x31, 0x48, 0x52, + 0xc1, 0x53, 0xd5, 0x0f, 0x70, 0x70, 0x90, 0x30, 0x00, 0x6a, 0x7a, 0x69, 0x94, 0x3f, 0x78, 0x08, + 0x80, 0x80, 0x52, 0x29, 0x9d, 0xc6, 0xd1, 0xb4, 0x2f, 0x06, 0xcd, 0x62, 0x6f, 0xba, 0xa4, 0x5c, + 0x48, 0xe1, 0x6d, 0xd9, 0x36, 0x18, 0x20, 0x85, 0x3b, 0x41, 0x90, 0x11, 0xb7, 0x49, 0xc6, 0x50, + 0xce, 0xe3, 0x70, 0x75, 0xe3, 0xda, 0x59, 0x96, 0x6e, 0xfc, 0x9b, 0x23, 0x70, 0x88, 0x91, 0xb9, + 0x5b, 0x9e, 0xc9, 0x85, 0x7d, 0x44, 0xf0, 0xfe, 0x2c, 0xfe, 0x0a, 0x1f, 0xfe, 0x98, 0xb6, 0xde, + 0x1c, 0x50, 0x08, 0xff, 0x2c, 0xda, 0x65, 0xbf, 0x9a, 0xdb, 0xdb, 0xae, 0x18, 0xa8, 0x38, 0x76, + 0x19, 0xea, 0xdb, 0xbc, 0x9f, 0x9d, 0x27, 0xdb, 0x06, 0xb2, 0xff, 0x04, 0x25, 0x0e, 0xc2, 0x5c, + 0x3e, 0x12, 0x97, 0xf0, 0x02, 0x08, 0x38, 0x4c, 0x97, 0xb4, 0x7c, 0xfe, 0x2e, 0xd5, 0x2e, 0x6a, + 0x1a, 0x85, 0xe0, 0x9f, 0x0e, 0x56, 0x6b, 0x3c, 0x2d, 0x6c, 0x7c, 0x25, 0x07, 0xec, 0x22, 0x43, + 0x9f, 0x7f, 0x8b, 0xe6, 0xa8, 0x51, 0xcf, 0x0e, 0x24, 0x12, 0x8e, 0xac, 0xc4, 0xc6, 0x6a, 0x2e, + 0xba, 0xaa, 0x2b, 0x98, 0x36, 0x2a, 0xcf, 0xc7, 0xf2, 0x72, 0xf2, 0xfa, 0xdf, 0xac, 0xe0, 0xd5, + 0x28, 0xf2, 0xe3, 0xa2, 0xe5, 0x43, 0x29, 0x82, 0x01, 0x20, 0xae, 0x5b, 0x0f, 0x8a, 0x47, 0x65, + 0xe5, 0xb1, 0xe7, 0xed, 0xb1, 0x77, 0x12, 0x7a, 0x67, 0x82, 0x11, 0x04, 0x3c, 0x0e, 0x74, 0xbf, + 0x03, 0xc8, 0x30, 0x0a, 0x62, 0x13, 0xe0, 0xd5, 0xa9, 0xe7, 0x0e, 0xb0, 0x2e, 0x5e, 0x99, 0x62, + 0xce, 0x38, 0x1f, 0x62, 0x1b, 0x85, 0x87, 0x58, 0x84, 0x64, 0xa0, 0xc4, 0x9f, 0x84, 0x43, 0x23, + 0x44, 0x41, 0x56, 0x58, 0x5e, 0xb7, 0x20, 0x75, 0x20, 0x04, 0xa7, 0x2a, 0xd6, 0xb7, 0xc8, 0x98, + 0x3e, 0xce, 0xad, 0xe0, 0x1f, 0xb3, 0xe7, 0x24, 0x1d, 0xaf, 0x95, 0xb7, 0xd5, 0xe7, 0xf8, 0x44, + 0x6c, 0x38, 0xc6, 0xa5, 0x53, 0xc8, 0xb0, 0xcb, 0xeb, 0x17, 0x07, 0x56, 0x0e, 0x21, 0x60, 0xa1, + 0x88, 0xf1, 0x4e, 0x62, 0x0e, 0x58, 0x4a, 0x5e, 0x58, 0xc5, 0x31, 0x84, 0x3e, 0x7a, 0x4f, 0xe0, + 0xa4, 0xe3, 0x1e, 0x66, 0x76, 0x67, 0x8c, 0xb3, 0xec, 0x69, 0x0c, 0x0f, 0xc6, 0x83, 0xa5, 0x20, + 0x37, 0x88, 0x1e, 0x59, 0x94, 0x92, 0x9d, 0x26, 0xdf, 0x78, 0x67, 0x00, 0x32, 0xbd, 0xae, 0x9d, + 0x7f, 0xfd, 0x6c, 0x43, 0xdf, 0x67, 0x8d, 0x5b, 0x15, 0xa8, 0xff, 0x3b, 0xb7, 0xa4, 0x9c, 0xb8, + 0x0b, 0x00, 0x24, 0x82, 0x2b, 0xdb, 0xba, 0x75, 0xe0, 0x96, 0x5b, 0x3d, 0xc3, 0xfe, 0xee, 0xe9, + 0xd0, 0x25, 0xec, 0x43, 0x19, 0xfe, 0xb9, 0x3b, 0x4e, 0xb9, 0x34, 0x4f, 0xc4, 0x02, 0x11, 0x92, + 0x40, 0x54, 0x13, 0x4c, 0x0d, 0x22, 0xd8, 0x6f, 0xc7, 0x55, 0x16, 0xf8, 0x72, 0xc2, 0xa7, 0x25, + 0x22, 0x3e, 0xf8, 0xba, 0x48, 0xd5, 0xaa, 0xa2, 0x5c, 0x40, 0x64, 0x20, 0x56, 0x3e, 0xae, 0xf0, + 0xd8, 0xfe, 0x51, 0xbd, 0x8c, 0x74, 0x31, 0x66, 0xfb, 0x08, 0x88, 0x04, 0x04, 0x0b, 0x9c, 0x0c, + 0xda, 0xcc, 0x55, 0x2c, 0x8c, 0x94, 0xa1, 0x1e, 0x46, 0x11, 0xa7, 0x1b, 0x0b, 0xd3, 0x79, 0x4a, + 0x91, 0x32, 0x30, 0x82, 0xe7, 0xcf, 0xe9, 0xe2, 0x03, 0x03, 0x68, 0x5e, 0xdf, 0x74, 0x9e, 0x26, + 0xc1, 0x34, 0xe1, 0xc0, 0x71, 0x2c, 0x21, 0x86, 0x2a, 0x4a, 0xca, 0xfc, 0xcb, 0xfa, 0xdf, 0xe3, + 0xc5, 0xbd, 0xc4, 0x74, 0x60, 0xf2, 0xeb, 0x7f, 0x88, 0x0a, 0x4d, 0x47, 0xb6, 0xcb, 0x20, 0x46, + 0x38, 0xb0, 0xcc, 0x79, 0xc8, 0x51, 0x2d, 0x03, 0xea, 0xb4, 0x1b, 0xda, 0x9e, 0xf0, 0xb1, 0x64, + 0xa5, 0x91, 0x43, 0x8a, 0x08, 0x0a, 0xf2, 0xa9, 0x0e, 0x82, 0xea, 0x8a, 0x7f, 0xdf, 0x86, 0x50, + 0x07, 0xf1, 0x32, 0xa7, 0x9d, 0x27, 0xf0, 0xfc, 0xd0, 0xca, 0x4b, 0xbb, 0xad, 0xd5, 0x76, 0x3b, + 0x1d, 0xae, 0xd4, 0xe7, 0x07, 0x54, 0x31, 0x37, 0x06, 0x22, 0x49, 0x8a, 0xdc, 0x6f, 0x81, 0x57, + 0xc0, 0x9a, 0xaa, 0x25, 0xd7, 0x0d, 0x60, 0x32, 0xba, 0x07, 0x6b, 0x5b, 0x85, 0xac, 0xb5, 0xf5, + 0xfe, 0x9e, 0x9c, 0x7c, 0x71, 0xc3, 0x08, 0xa0, 0x08, 0xea, 0xc7, 0x15, 0x6e, 0xd5, 0xdb, 0x3f, + 0xac, 0x1d, 0xbf, 0x6f, 0xe9, 0xc9, 0xfb, 0x0e, 0xe0, 0x07, 0xf8, 0x1f, 0xde, 0xb8, 0x5f, 0xa2, + 0xd1, 0xbf, 0x8f, 0x6a, 0x5c, 0x7c, 0x55, 0xbe, 0xb5, 0x07, 0x9f, 0xf0, 0x73, 0xf0, 0x7f, 0xc1, + 0x8d, 0xaa, 0x9e, 0x65, 0x0d, 0x4b, 0x36, 0x14, 0x20, 0x48, 0x41, 0xae, 0x5d, 0xd9, 0xfe, 0xe1, + 0xb3, 0xe9, 0x99, 0xe3, 0xac, 0x32, 0xca, 0x00, 0x2b, 0xdd, 0xb3, 0x61, 0x6c, 0x5f, 0x57, 0x6c, + 0xff, 0x5e, 0x9d, 0xaa, 0xd7, 0xdc, 0x48, 0x90, 0xc0, 0x8a, 0x60, 0x68, 0xc5, 0xc5, 0x52, 0x50, + 0xab, 0xe3, 0x40, 0x83, 0x50, 0xe6, 0xd5, 0x0f, 0x0f, 0x12, 0x21, 0x0d, 0x7e, 0x2d, 0xa5, 0x0d, + 0xe0, 0x01, 0xc5, 0xc7, 0x90, 0x76, 0x78, 0xb7, 0xe6, 0xb9, 0xe3, 0x64, 0x4b, 0xfe, 0xe0, 0x1c, + 0x1f, 0xef, 0xaf, 0x10, 0x9d, 0x59, 0xbf, 0x12, 0x29, 0x47, 0xb8, 0xfc, 0xc2, 0x6a, 0xbc, 0x48, + 0x10, 0x06, 0x08, 0xad, 0x4d, 0x8f, 0xf8, 0x31, 0x52, 0x85, 0x62, 0x1c, 0xb4, 0xc2, 0x8d, 0x84, + 0x00, 0x80, 0x33, 0x1e, 0x53, 0x61, 0x79, 0xde, 0xb1, 0x89, 0x7e, 0xb1, 0x08, 0x68, 0x5f, 0x8f, + 0x0e, 0x80, 0x67, 0x0c, 0x7e, 0x1b, 0xaa, 0x82, 0x4d, 0x60, 0x25, 0x1a, 0x0e, 0x12, 0x80, 0x1a, + 0xe0, 0xd6, 0xef, 0xc3, 0x3c, 0xa5, 0xcd, 0xc3, 0x75, 0xa2, 0xf0, 0x84, 0xcd, 0x6f, 0xbb, 0xe6, + 0xf5, 0xf7, 0x52, 0x71, 0x78, 0xfc, 0x75, 0x23, 0x59, 0xf2, 0xa5, 0xaa, 0xaa, 0xf8, 0x90, 0xc3, + 0xe6, 0xc3, 0x67, 0x92, 0x55, 0x7e, 0x65, 0x3f, 0x7f, 0xb2, 0x8e, 0x2f, 0x3b, 0xd6, 0x20, 0x84, + 0x68, 0x11, 0x96, 0x95, 0x67, 0x06, 0x20, 0x80, 0x29, 0x7c, 0xe1, 0x35, 0x4b, 0x0c, 0xf0, 0x0f, + 0xcd, 0x99, 0x22, 0xa3, 0x90, 0xb9, 0x63, 0x53, 0x8e, 0x0a, 0x65, 0xe4, 0x9c, 0x97, 0x29, 0x3d, + 0x4b, 0x03, 0xee, 0x0a, 0x01, 0x40, 0x50, 0x89, 0xfa, 0x51, 0xb3, 0x49, 0x24, 0x83, 0x71, 0x20, + 0x1e, 0x7f, 0x9e, 0x00, 0x7d, 0xa0, 0x6b, 0x69, 0xd9, 0x66, 0x3a, 0x0b, 0x85, 0x8d, 0x43, 0xa0, + 0xbc, 0x4f, 0x86, 0xc9, 0x00, 0x10, 0xcf, 0xbe, 0xde, 0x02, 0x27, 0xa6, 0xd7, 0x55, 0x95, 0x44, + 0x2b, 0x14, 0xce, 0x79, 0x7a, 0x88, 0x60, 0xa7, 0x03, 0x01, 0xc6, 0x34, 0xae, 0xb7, 0xbc, 0x3d, + 0x80, 0x16, 0x79, 0x3c, 0x32, 0x5d, 0x78, 0x24, 0xdf, 0x8e, 0x1a, 0x83, 0xa9, 0xc3, 0xa7, 0x19, + 0x65, 0xb3, 0x82, 0xc9, 0x6c, 0x17, 0x73, 0x8f, 0x82, 0xc2, 0x2d, 0x84, 0xe3, 0x09, 0x46, 0x03, + 0x10, 0x81, 0xa1, 0x6d, 0x4f, 0x56, 0xf2, 0x77, 0x7c, 0x08, 0x00, 0x61, 0x1b, 0x1b, 0x30, 0x78, + 0x1c, 0xf1, 0x60, 0x11, 0x7e, 0x4a, 0x00, 0xe0, 0x58, 0x0c, 0x40, 0x03, 0x87, 0xb8, 0x4c, 0x02, + 0xaf, 0x07, 0x06, 0x32, 0xe3, 0x53, 0x6c, 0x2d, 0x2e, 0xe4, 0xfd, 0x29, 0x6a, 0x57, 0xf8, 0x91, + 0x36, 0x00, 0x04, 0x61, 0x73, 0xb6, 0xc4, 0x69, 0xc6, 0x96, 0x1d, 0xc0, 0x05, 0xa1, 0x1d, 0x9c, + 0x82, 0x7f, 0x39, 0x5f, 0x3f, 0x66, 0xe1, 0x11, 0xb0, 0xb9, 0x5e, 0xc1, 0xef, 0xce, 0x60, 0x0c, + 0x17, 0xda, 0x5b, 0xfb, 0xf8, 0xeb, 0xe1, 0xd6, 0xb8, 0x5a, 0x3f, 0x07, 0xb2, 0xe7, 0x6f, 0x09, + 0x98, 0x2a, 0xcf, 0xc7, 0x39, 0x9d, 0x66, 0xa2, 0x5e, 0xbf, 0x6f, 0x9a, 0xec, 0xe1, 0xd5, 0x00, + 0x25, 0x9e, 0x63, 0x5a, 0x2c, 0xc7, 0xbe, 0x63, 0x3f, 0xff, 0x22, 0x7c, 0x4c, 0x75, 0x65, 0x3c, + 0xca, 0x83, 0x15, 0x6e, 0x8c, 0x80, 0xbd, 0xa2, 0x1e, 0xbf, 0x1c, 0x71, 0xa6, 0x90, 0x0e, 0xc9, + 0xd1, 0x92, 0xf0, 0x8b, 0x6c, 0x2c, 0xe5, 0x7f, 0x38, 0x1a, 0xe2, 0x8c, 0xa7, 0x52, 0x89, 0x20, + 0x6e, 0x9b, 0x73, 0x58, 0x38, 0x05, 0x01, 0xe8, 0x2c, 0x00, 0x0b, 0xce, 0x81, 0xc4, 0x1d, 0xe3, + 0x0f, 0xa5, 0xe2, 0x1a, 0x8e, 0xcb, 0x1e, 0xdc, 0x3d, 0x54, 0x4f, 0x27, 0x08, 0x97, 0x5b, 0xff, + 0xe1, 0x80, 0x40, 0x09, 0x62, 0x5b, 0x0a, 0x8e, 0xf1, 0x15, 0x7c, 0xac, 0xeb, 0x0c, 0x50, 0x75, + 0x8e, 0x20, 0x5c, 0x2e, 0xe2, 0xcb, 0x62, 0x5e, 0xba, 0xcd, 0x4f, 0x04, 0x9c, 0x65, 0x47, 0x9e, + 0x6b, 0xc2, 0x00, 0xa2, 0xab, 0xea, 0x33, 0xe3, 0x9a, 0x57, 0x84, 0x05, 0xea, 0xef, 0x53, 0x64, + 0xf0, 0x88, 0x27, 0xaa, 0xa8, 0x35, 0x25, 0x37, 0x4e, 0x00, 0x15, 0x80, 0xe9, 0x70, 0xf2, 0x94, + 0x03, 0x80, 0x67, 0x11, 0x0e, 0xc1, 0xdf, 0xcb, 0xbb, 0x3a, 0x5d, 0xb4, 0x5f, 0x19, 0xdf, 0x06, + 0xa5, 0xf7, 0xfe, 0x22, 0x14, 0x39, 0xb0, 0xfe, 0x17, 0x97, 0xba, 0x84, 0xa9, 0xab, 0x31, 0x98, + 0xa2, 0x78, 0xb3, 0x25, 0x9a, 0x93, 0xb7, 0x05, 0x00, 0x50, 0x0a, 0x1b, 0x23, 0x1c, 0x66, 0xd2, + 0xf8, 0xce, 0xc0, 0x4f, 0x4a, 0xa1, 0x71, 0xde, 0x92, 0x22, 0x8b, 0xc1, 0x38, 0x6e, 0x2a, 0x59, + 0xc5, 0xd3, 0x00, 0x66, 0x26, 0x14, 0x83, 0x15, 0x49, 0xa0, 0x90, 0x16, 0xe1, 0xac, 0xbb, 0x00, + 0x02, 0xd4, 0xe2, 0xb2, 0x53, 0x82, 0x3a, 0xc0, 0x92, 0xbd, 0x06, 0x99, 0xed, 0xf6, 0x26, 0x2b, + 0xc6, 0xe0, 0x50, 0x0a, 0x0a, 0x73, 0x32, 0x7c, 0x6d, 0x09, 0xbb, 0x28, 0xa5, 0x7e, 0x52, 0x13, + 0xc7, 0x71, 0x79, 0x63, 0x04, 0x9b, 0xa5, 0xd9, 0x55, 0xd1, 0xde, 0x0e, 0x42, 0x92, 0x88, 0x25, + 0x2c, 0x00, 0x32, 0x8c, 0xa5, 0x80, 0x60, 0xf1, 0x71, 0xe3, 0x61, 0x42, 0x99, 0x8a, 0x5c, 0x53, + 0xc5, 0xc7, 0x3f, 0x3c, 0x05, 0x97, 0x60, 0xef, 0xc5, 0xe1, 0x03, 0x10, 0x24, 0x22, 0x78, 0xe3, + 0x2f, 0x8e, 0x2d, 0xad, 0x7c, 0x40, 0x25, 0x27, 0x85, 0x81, 0x43, 0xe2, 0xee, 0x80, 0x00, 0xfe, + 0x0f, 0x00, 0x03, 0x7c, 0x28, 0x0a, 0x0e, 0x91, 0x03, 0x83, 0x50, 0x3d, 0xa0, 0x17, 0x89, 0x86, + 0x4a, 0x1c, 0x4c, 0x0d, 0x7e, 0x90, 0x3e, 0x14, 0xf5, 0x17, 0xf0, 0x4b, 0x23, 0x32, 0xcf, 0x15, + 0x55, 0x33, 0x70, 0xc8, 0x21, 0x18, 0x4b, 0x93, 0xd7, 0x9f, 0x31, 0x76, 0x5e, 0x25, 0x81, 0x73, + 0x08, 0x42, 0x25, 0xb5, 0x6f, 0x2e, 0x09, 0xde, 0x35, 0x80, 0xee, 0x25, 0xc4, 0x08, 0x0a, 0x6e, + 0xa2, 0xe2, 0xfa, 0xa7, 0x17, 0x3b, 0xe4, 0x5c, 0xb0, 0x57, 0xac, 0x29, 0x05, 0x9c, 0x44, 0x15, + 0x91, 0x65, 0xa3, 0xf9, 0x73, 0x2e, 0x4e, 0x0f, 0x10, 0x30, 0xa2, 0x7c, 0x2d, 0x62, 0x2e, 0xcf, + 0x1b, 0xf2, 0xf7, 0xb7, 0x15, 0xac, 0xf1, 0xe1, 0x01, 0x01, 0x3d, 0xba, 0x56, 0xab, 0xf1, 0x44, + 0x48, 0xe0, 0x61, 0x2f, 0x49, 0xd9, 0xe2, 0x01, 0x08, 0x50, 0xaf, 0xf7, 0x9b, 0xaa, 0xca, 0xa4, + 0xdc, 0x38, 0x82, 0x7f, 0x22, 0xba, 0x8d, 0x37, 0x12, 0x11, 0x0a, 0x11, 0x57, 0x17, 0x2c, 0xc5, + 0xc5, 0x3c, 0x42, 0xc2, 0x71, 0xc3, 0x3e, 0x2e, 0x57, 0x84, 0x02, 0x87, 0x0c, 0x78, 0x5e, 0xad, + 0x11, 0x26, 0x2e, 0x08, 0x31, 0x95, 0xdb, 0xe7, 0xea, 0x2e, 0x9d, 0x99, 0x90, 0x65, 0xd0, 0xe7, + 0xf7, 0xc1, 0x34, 0xfd, 0xdd, 0xf7, 0x7b, 0xc6, 0x73, 0x6a, 0xaa, 0x7e, 0x53, 0x2a, 0xe5, 0xee, + 0xbd, 0xc4, 0xf0, 0x96, 0xb5, 0x55, 0xa9, 0x61, 0x00, 0x88, 0x52, 0xdd, 0x60, 0x30, 0x63, 0x04, + 0x73, 0xad, 0x2d, 0x4c, 0x8a, 0x5b, 0x97, 0x46, 0xe3, 0xea, 0xca, 0x11, 0xd3, 0x28, 0x38, 0x40, + 0x48, 0x42, 0x28, 0xef, 0xd4, 0x5e, 0x5f, 0x2c, 0x30, 0x60, 0x08, 0x06, 0xc5, 0xdd, 0x61, 0xe7, + 0xe6, 0xe5, 0x24, 0xa1, 0xf1, 0xa9, 0x79, 0xcf, 0x6c, 0xbc, 0x94, 0x56, 0x45, 0xe3, 0x87, 0xaa, + 0x7f, 0xe3, 0x18, 0xe7, 0x89, 0xdf, 0x04, 0xe5, 0x72, 0xab, 0x42, 0x4f, 0xce, 0x59, 0x53, 0xac, + 0x4c, 0x28, 0x62, 0xc1, 0x96, 0x0c, 0xf6, 0xfc, 0x39, 0xa8, 0xf5, 0x91, 0xd6, 0x1f, 0xa8, 0x37, + 0x7c, 0x4d, 0x33, 0x7c, 0x1c, 0x42, 0x03, 0x51, 0x59, 0x60, 0xe5, 0x0d, 0xf0, 0x9c, 0xf3, 0x49, + 0x86, 0xaf, 0x77, 0xe1, 0x81, 0x7c, 0x94, 0x27, 0x5c, 0x25, 0xe2, 0x06, 0x15, 0x62, 0xea, 0xe2, + 0x8d, 0x31, 0x5a, 0x8f, 0x50, 0x5f, 0x6c, 0x8e, 0x58, 0x12, 0x05, 0x86, 0x3f, 0x84, 0x05, 0xcf, + 0x99, 0x6e, 0xb2, 0x67, 0x10, 0x3b, 0x69, 0x77, 0x54, 0xea, 0x8c, 0x86, 0xb8, 0x64, 0x15, 0x55, + 0x62, 0x93, 0xb8, 0xfb, 0xba, 0x87, 0xd1, 0x29, 0xe2, 0xc6, 0x7a, 0xd4, 0x6a, 0x84, 0xc9, 0x18, + 0xdc, 0x48, 0x21, 0x1a, 0x55, 0x1e, 0x66, 0x9c, 0xb0, 0xd6, 0x40, 0xee, 0xd5, 0xfe, 0x3e, 0x96, + 0x62, 0x45, 0x69, 0x94, 0x27, 0x0d, 0x0d, 0x45, 0x5c, 0xb4, 0x6b, 0xf8, 0x66, 0x09, 0x3b, 0x22, + 0xeb, 0xe6, 0x25, 0xee, 0xa1, 0x19, 0x2b, 0x55, 0x3b, 0xdf, 0x86, 0x03, 0x03, 0xce, 0x72, 0x63, + 0x5e, 0xb1, 0xa0, 0xaf, 0x77, 0x87, 0xb0, 0x05, 0xbd, 0xb3, 0x24, 0x1b, 0xff, 0x04, 0x7a, 0x1e, + 0x7a, 0x60, 0x14, 0x82, 0xd5, 0x5e, 0xbf, 0xf0, 0xe6, 0xa8, 0x5f, 0xce, 0x88, 0x6f, 0xa5, 0x75, + 0xe1, 0x16, 0x04, 0x89, 0xfc, 0x36, 0x7c, 0x69, 0xb3, 0x71, 0x18, 0x78, 0x6e, 0x19, 0x1e, 0xd8, + 0x01, 0x0a, 0xb9, 0x09, 0xf9, 0xcf, 0xfb, 0xe2, 0x8d, 0x2e, 0x44, 0x3e, 0x2b, 0x8a, 0xe1, 0x7c, + 0x04, 0x01, 0xdf, 0xbc, 0x4e, 0xe4, 0xfe, 0x51, 0xfb, 0x2c, 0x6f, 0xab, 0xb3, 0x96, 0xee, 0xee, + 0xee, 0x94, 0x56, 0x46, 0x73, 0xc9, 0xfc, 0x20, 0x27, 0x52, 0x57, 0x2f, 0x35, 0x19, 0x09, 0xf0, + 0xa5, 0x66, 0x38, 0x68, 0x00, 0x5b, 0xc9, 0x4e, 0xd5, 0x19, 0xed, 0x96, 0x71, 0xed, 0x22, 0x3d, + 0xd8, 0xdb, 0x58, 0x13, 0xfa, 0x3a, 0xb1, 0xfc, 0x8b, 0xfc, 0xe2, 0x61, 0x49, 0x46, 0xad, 0x87, + 0x7c, 0xd8, 0x79, 0x61, 0x5d, 0x65, 0x9b, 0xa0, 0xa7, 0x70, 0x5e, 0x67, 0x2e, 0x74, 0x5c, 0xbc, + 0x20, 0x73, 0xbf, 0x2f, 0xee, 0xde, 0x2b, 0x15, 0xf8, 0x25, 0x20, 0x04, 0xbf, 0x4c, 0x80, 0xfa, + 0x7e, 0x3d, 0xfe, 0x73, 0xbe, 0xc6, 0x3f, 0x19, 0xee, 0x78, 0x40, 0x7c, 0xe3, 0x96, 0xf1, 0x01, + 0xc5, 0x99, 0x98, 0x65, 0xf0, 0x88, 0xe2, 0xf1, 0x7d, 0xbb, 0x93, 0x15, 0xc9, 0x80, 0xdc, 0x63, + 0x21, 0x4e, 0x12, 0x9b, 0xaf, 0x7b, 0xae, 0x63, 0xea, 0xaf, 0x9b, 0x79, 0x54, 0x04, 0x79, 0x09, + 0x95, 0xb5, 0xfe, 0x08, 0x48, 0x18, 0xbc, 0x03, 0x49, 0x08, 0xf5, 0xde, 0x17, 0x10, 0x24, 0x23, + 0x71, 0x5b, 0x8a, 0xdc, 0xfd, 0xec, 0xb6, 0x21, 0x61, 0xef, 0x12, 0x20, 0x7d, 0xb5, 0xc9, 0x9b, + 0xb0, 0x77, 0xbe, 0x24, 0x48, 0x4e, 0xb5, 0xda, 0x49, 0x7c, 0x64, 0x9d, 0x32, 0x64, 0xb8, 0x3f, + 0xc7, 0xab, 0x93, 0xd5, 0x69, 0x62, 0x04, 0x05, 0x34, 0x19, 0xcc, 0x5e, 0xcb, 0x18, 0xac, 0x51, + 0x8a, 0xd5, 0xab, 0x66, 0xd2, 0xc1, 0xc8, 0x97, 0x35, 0xc4, 0x88, 0x19, 0x15, 0xb9, 0xfd, 0xe7, + 0xfb, 0x67, 0x7f, 0x2c, 0x3c, 0x23, 0x77, 0x77, 0xc1, 0xdb, 0x0d, 0x97, 0x36, 0x4f, 0x08, 0x0f, + 0xd5, 0xeb, 0x5a, 0xaa, 0xaf, 0x82, 0xbb, 0xe3, 0x10, 0x8f, 0x64, 0x0e, 0xfa, 0xf6, 0x4b, 0xbd, + 0x42, 0x7c, 0xb7, 0xbc, 0xfd, 0xc5, 0x7c, 0x29, 0xcd, 0xdd, 0xf1, 0x31, 0x87, 0x95, 0x8b, 0xbe, + 0xde, 0xee, 0xca, 0xd9, 0xab, 0xe3, 0x8c, 0x27, 0x93, 0xaa, 0x23, 0x77, 0x3a, 0x86, 0xee, 0x2a, + 0xff, 0x08, 0x76, 0x6d, 0xa3, 0x63, 0x5d, 0x3a, 0xf8, 0x2e, 0xad, 0x72, 0x42, 0x26, 0xc3, 0xfc, + 0x14, 0x13, 0x13, 0x48, 0xb6, 0x9a, 0x57, 0x38, 0x66, 0x30, 0xe0, 0x3e, 0xf9, 0x45, 0x33, 0x42, + 0x7d, 0xa3, 0x98, 0x6e, 0xaa, 0xd2, 0x19, 0xd4, 0x5c, 0x5c, 0x5c, 0x5f, 0x89, 0x19, 0xb4, 0xfa, + 0xb5, 0x55, 0x4e, 0xa9, 0xc8, 0xcf, 0x10, 0x26, 0xb4, 0x8c, 0xc4, 0xc9, 0x6e, 0x15, 0xe4, 0x26, + 0xee, 0xb1, 0x0e, 0xbb, 0x41, 0x8c, 0x49, 0x0f, 0xb4, 0xd7, 0x82, 0xb3, 0x6a, 0xa9, 0x45, 0x67, + 0xe2, 0x7c, 0x4f, 0x0f, 0xf2, 0xc0, 0xe5, 0xc2, 0x22, 0x42, 0x91, 0x1c, 0x55, 0x55, 0x13, 0xc5, + 0x97, 0x6d, 0x93, 0x01, 0x53, 0x8f, 0x6c, 0xbd, 0x19, 0xe0, 0xd6, 0x95, 0x27, 0x3c, 0x10, 0x8c, + 0x8b, 0x8b, 0x8b, 0xe1, 0x50, 0xad, 0x2e, 0x48, 0xa7, 0xa3, 0x04, 0x48, 0xe2, 0x7d, 0xf0, 0x8c, + 0x29, 0x27, 0x2c, 0x8f, 0xe3, 0xe0, 0x07, 0x8f, 0x05, 0xcf, 0x98, 0xcc, 0xc5, 0x03, 0x48, 0x04, + 0x62, 0x9b, 0x32, 0x45, 0xe7, 0xdc, 0x48, 0x64, 0x28, 0x53, 0xfc, 0x18, 0xf4, 0x9d, 0x45, 0xc5, + 0x5d, 0x46, 0x72, 0xaa, 0x58, 0xdd, 0x21, 0x61, 0x04, 0x33, 0xc1, 0x0c, 0x04, 0x2e, 0x73, 0x5a, + 0xf8, 0xe2, 0x2c, 0x5c, 0x4f, 0x35, 0x56, 0x68, 0x7b, 0xd7, 0xcb, 0x7e, 0x13, 0x88, 0xff, 0x55, + 0x6d, 0x61, 0xae, 0xfb, 0xb8, 0x57, 0x92, 0xda, 0xfc, 0x32, 0x22, 0xa5, 0xfc, 0x8b, 0xa8, 0xc2, + 0xf1, 0x23, 0xe5, 0xe5, 0xfa, 0xb3, 0xbc, 0xfc, 0xbe, 0x9d, 0x3f, 0x0a, 0x4b, 0x1d, 0x65, 0x8d, + 0xb7, 0x3a, 0x49, 0x19, 0x10, 0xb0, 0xcc, 0x7e, 0x57, 0x89, 0xc4, 0xdd, 0xce, 0x10, 0x82, 0xb2, + 0xed, 0xdd, 0xfb, 0xc5, 0x77, 0x92, 0x78, 0x90, 0x81, 0xb4, 0xcf, 0x0a, 0xdb, 0x47, 0x7c, 0x6d, + 0x43, 0x15, 0x12, 0x95, 0x9e, 0x4c, 0xe7, 0xc4, 0x88, 0x93, 0xf7, 0x5d, 0x3f, 0x65, 0xad, 0x43, + 0x18, 0x8e, 0x26, 0x62, 0x3d, 0xe1, 0x9e, 0x43, 0x8d, 0x59, 0x1d, 0xbc, 0xfe, 0x34, 0xe5, 0xfd, + 0xb5, 0x4d, 0xe4, 0xfa, 0xdd, 0xdb, 0x2f, 0x5d, 0x4f, 0x0f, 0xe2, 0x42, 0x86, 0x1d, 0xa1, 0x6f, + 0x77, 0xb3, 0xc2, 0xed, 0xb7, 0xb6, 0xfb, 0xfd, 0xf7, 0x48, 0x27, 0x88, 0x9f, 0x90, 0x95, 0xa8, + 0x04, 0xe2, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x48, 0x24, 0x31, 0xa7, 0xc4, 0x99, 0xdf, 0xbd, + 0xd7, 0x27, 0x74, 0xfc, 0xb2, 0x74, 0xd4, 0xbc, 0x9c, 0xbd, 0xdc, 0x9d, 0x8b, 0x7b, 0xd7, 0x64, + 0xd4, 0xd8, 0x0d, 0x7a, 0x33, 0xc0, 0x73, 0xf4, 0x67, 0x80, 0x2c, 0x6e, 0xbd, 0x5d, 0x5c, 0x80, + 0x26, 0x18, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x49, 0x24, 0xb2, 0xbc, 0xc6, 0xad, 0x49, 0xcd, + 0xe6, 0xfe, 0x6b, 0xc5, 0x71, 0x3c, 0xc5, 0x17, 0x14, 0xc5, 0xc5, 0x30, 0x51, 0xde, 0xb5, 0xf2, + 0x69, 0xdf, 0xdd, 0xef, 0x71, 0x17, 0xcf, 0xe5, 0xe6, 0x2d, 0x37, 0x4b, 0x13, 0x08, 0x9a, 0xea, + 0x86, 0xe4, 0xed, 0xc7, 0x33, 0x43, 0x89, 0x12, 0x11, 0xc4, 0x0f, 0xb4, 0x6f, 0xd4, 0x5e, 0xbe, + 0x3e, 0xd5, 0xda, 0x5a, 0x95, 0x82, 0xb1, 0x10, 0x60, 0x15, 0x23, 0xf2, 0x1c, 0x98, 0x77, 0xd2, + 0xf0, 0x51, 0x74, 0x61, 0x77, 0xb3, 0x51, 0x76, 0xf8, 0xba, 0xdc, 0xa6, 0x3b, 0x32, 0x50, 0x16, + 0xf3, 0x08, 0x55, 0x5f, 0x96, 0xab, 0xa8, 0x98, 0x46, 0xd1, 0xbf, 0x3e, 0x67, 0xe6, 0xd5, 0x72, + 0x4e, 0x20, 0xba, 0xb7, 0xf0, 0x85, 0x37, 0xeb, 0x52, 0x7f, 0xc4, 0xc9, 0xc5, 0x6f, 0xc4, 0xc1, + 0x09, 0x45, 0x7d, 0xf8, 0x99, 0x2d, 0x93, 0x3c, 0x4f, 0x89, 0xb3, 0x03, 0xa5, 0xe6, 0xe9, 0xe2, + 0x70, 0x4b, 0xcd, 0xaa, 0xaf, 0x11, 0x7c, 0x87, 0xdd, 0xc9, 0xc5, 0x09, 0xa7, 0x4d, 0xf4, 0xb8, + 0x80, 0xa0, 0xc7, 0xbd, 0x94, 0xaf, 0x72, 0xd1, 0x57, 0x5e, 0xf1, 0x22, 0x0a, 0x84, 0xc7, 0x5d, + 0x57, 0xc7, 0x55, 0x35, 0x5c, 0xbf, 0x77, 0x7e, 0x20, 0x45, 0x55, 0x38, 0x61, 0x58, 0xb7, 0x5e, + 0xfc, 0x11, 0xdc, 0xff, 0x7e, 0x26, 0x61, 0x6a, 0x97, 0x88, 0xfc, 0x22, 0x32, 0x6a, 0x62, 0xf2, + 0x61, 0x61, 0x9f, 0x2b, 0x89, 0x3a, 0xd8, 0xfc, 0xb9, 0x89, 0x12, 0xaf, 0xc4, 0x89, 0x2d, 0x63, + 0xf0, 0x72, 0x08, 0xb9, 0x84, 0x5e, 0xfe, 0x5b, 0x9f, 0xbd, 0x67, 0xe4, 0x12, 0x66, 0x74, 0xdf, + 0x88, 0x04, 0x86, 0x76, 0xf7, 0x38, 0x98, 0x50, 0xea, 0xb5, 0x28, 0x60, 0xe6, 0x26, 0x63, 0xaa, + 0xa7, 0x5f, 0x7c, 0x29, 0x2f, 0x2d, 0xdd, 0x0c, 0xac, 0x1d, 0x4e, 0x41, 0x1b, 0x1f, 0x1a, 0xfa, + 0x33, 0xb1, 0x7b, 0xfc, 0x75, 0x8d, 0xb3, 0x45, 0x9e, 0xc1, 0x8c, 0x2f, 0x91, 0x82, 0x7f, 0xd9, + 0x9a, 0x6a, 0x43, 0x1c, 0x40, 0x82, 0xf8, 0xc9, 0x23, 0xc8, 0x26, 0xb5, 0xfa, 0x89, 0x12, 0x61, + 0xce, 0x2b, 0xce, 0x22, 0x1d, 0x1e, 0xf6, 0x02, 0x24, 0x0c, 0x28, 0x9c, 0x5d, 0xf4, 0x47, 0xc5, + 0x3a, 0x7c, 0x32, 0x34, 0x20, 0x6b, 0x05, 0x7c, 0xb7, 0x0a, 0x86, 0xca, 0x15, 0x6a, 0x73, 0xcb, + 0x58, 0x2c, 0xa9, 0x6c, 0x8e, 0x08, 0x81, 0xae, 0x9b, 0x40, 0x76, 0xf2, 0x48, 0xa3, 0x66, 0x94, + 0x69, 0xcb, 0xbe, 0x1a, 0xe4, 0x2d, 0x5e, 0x6e, 0x42, 0xee, 0xfe, 0x2c, 0x45, 0xdc, 0x57, 0x6d, + 0xb5, 0xf0, 0x57, 0x14, 0xe2, 0x9a, 0x8b, 0x8b, 0x9b, 0x67, 0x49, 0x7b, 0xe3, 0x04, 0xc5, 0xc9, + 0x0a, 0x19, 0x3a, 0x74, 0x31, 0xe3, 0x14, 0xa5, 0xe3, 0x94, 0x54, 0x30, 0x69, 0x45, 0xe1, 0x4b, + 0x50, 0x31, 0xe9, 0x97, 0xd1, 0xad, 0xa4, 0x50, 0x68, 0x65, 0x86, 0x5d, 0x93, 0x48, 0x18, 0x1b, + 0xcb, 0xe0, 0xa7, 0x08, 0x9c, 0xec, 0xd6, 0x6c, 0x59, 0x4b, 0x2e, 0x11, 0xb9, 0x97, 0xc4, 0x42, + 0x22, 0x29, 0x3b, 0x52, 0x75, 0xf3, 0x76, 0xe7, 0xc2, 0x92, 0xec, 0xbb, 0xc9, 0xb0, 0x5f, 0x0e, + 0x56, 0xab, 0x55, 0xa5, 0x16, 0xef, 0x82, 0xaa, 0xdd, 0xc7, 0x31, 0xc8, 0xb9, 0x33, 0xd9, 0xf0, + 0x86, 0xab, 0x18, 0x65, 0xf6, 0xa1, 0x7d, 0x57, 0xec, 0xae, 0xff, 0x10, 0x2c, 0xb9, 0x73, 0x97, + 0x0b, 0x9c, 0x41, 0x06, 0x5d, 0x83, 0x7e, 0x25, 0x89, 0x7a, 0xca, 0x39, 0x04, 0x42, 0x96, 0x37, + 0xe0, 0x22, 0x40, 0xf2, 0x18, 0x0b, 0x45, 0xc2, 0x82, 0xa3, 0x0b, 0x39, 0x05, 0xc2, 0xc3, 0x93, + 0x24, 0x88, 0x01, 0x1b, 0xfd, 0x34, 0xdb, 0x78, 0x73, 0x00, 0x19, 0x37, 0xf2, 0x6d, 0xdf, 0xf7, + 0xff, 0xd3, 0x6c, 0x43, 0xa2, 0xd9, 0x53, 0xa9, 0x51, 0x03, 0x2e, 0xa5, 0xb4, 0x7d, 0xc0, 0x50, + 0x82, 0x90, 0x81, 0x5d, 0xde, 0xb1, 0x61, 0x0c, 0x45, 0xe9, 0x88, 0x4a, 0xe3, 0x9b, 0x26, 0x71, + 0xe0, 0x61, 0x05, 0x20, 0x80, 0x82, 0x00, 0x58, 0x8c, 0x1a, 0xb5, 0x48, 0x2a, 0x41, 0xdb, 0x0f, + 0xa2, 0xe8, 0x12, 0x8e, 0x83, 0x39, 0x9c, 0x24, 0x3c, 0x78, 0xf4, 0x62, 0xdb, 0xad, 0xe9, 0xc9, + 0xd9, 0x60, 0x71, 0x0c, 0x8d, 0x81, 0x60, 0x44, 0xea, 0x06, 0xac, 0x1f, 0x08, 0xfc, 0xb0, 0x0a, + 0xd9, 0xb9, 0xd8, 0xb0, 0x76, 0x1f, 0xe0, 0x91, 0xc7, 0x00, 0x00, 0x46, 0xa1, 0x50, 0x67, 0xb9, + 0x2f, 0x6e, 0x55, 0x05, 0x60, 0x1f, 0x2b, 0x0c, 0xbc, 0x12, 0x31, 0x84, 0x0a, 0x32, 0x50, 0x2e, + 0x05, 0xd8, 0x05, 0x88, 0x22, 0xd3, 0x30, 0x67, 0xea, 0xfe, 0x1e, 0xe6, 0xd3, 0x6f, 0xc1, 0x19, + 0xe9, 0xe1, 0x2b, 0x90, 0xa7, 0x41, 0x7a, 0x97, 0xb0, 0xf2, 0xad, 0x4b, 0xcb, 0x5d, 0x7d, 0xdd, + 0xff, 0x08, 0x1c, 0xac, 0x4b, 0xd3, 0x37, 0x27, 0xce, 0x6b, 0x17, 0xf1, 0x7a, 0x99, 0x24, 0x6b, + 0x2e, 0x71, 0x1e, 0x22, 0x3f, 0x72, 0x7e, 0xb4, 0x51, 0x71, 0x70, 0xa9, 0xcb, 0x12, 0x04, 0x00, + 0xa1, 0x85, 0x61, 0x41, 0xc8, 0x4b, 0x8f, 0xda, 0x84, 0x9e, 0x4d, 0xc5, 0x67, 0x9c, 0x38, 0xf2, + 0xb1, 0x61, 0x03, 0xec, 0xd8, 0xab, 0x07, 0x58, 0xcb, 0xe3, 0xb2, 0x29, 0x89, 0x38, 0xcc, 0xaa, + 0xc9, 0x82, 0x60, 0xff, 0x2c, 0x0c, 0x92, 0xaf, 0xc4, 0x0b, 0x41, 0x90, 0xfb, 0xcc, 0x71, 0x21, + 0x80, 0xf0, 0x63, 0x18, 0xcf, 0xb6, 0x54, 0x04, 0x59, 0x4e, 0x41, 0xec, 0x62, 0xcb, 0xa3, 0x88, + 0xbd, 0x93, 0x3f, 0x59, 0x29, 0x84, 0x42, 0x21, 0x49, 0xe0, 0x3c, 0xb0, 0x65, 0x53, 0x5b, 0x14, + 0x67, 0x8b, 0x02, 0xb2, 0xd9, 0xd8, 0x63, 0xb7, 0x02, 0x82, 0x80, 0x5d, 0x3b, 0xd4, 0xd5, 0x1d, + 0xe0, 0xa4, 0x40, 0x52, 0x58, 0x34, 0xe7, 0xd2, 0x14, 0x19, 0x60, 0xd8, 0x0c, 0xca, 0x4b, 0x06, + 0x20, 0x1a, 0x0a, 0x0c, 0x48, 0xe3, 0x3e, 0xad, 0xc4, 0x38, 0x44, 0x0b, 0x78, 0x29, 0x04, 0x01, + 0x4b, 0x71, 0x90, 0x24, 0x01, 0xc9, 0x2b, 0x2a, 0x89, 0x0f, 0xc3, 0x28, 0x6a, 0xbc, 0xea, 0x3b, + 0x01, 0xc1, 0xea, 0xa3, 0xce, 0x16, 0x19, 0x61, 0xa4, 0x2b, 0x1d, 0x83, 0x28, 0xbc, 0xe7, 0xe8, + 0xdb, 0xc2, 0x20, 0xc0, 0x29, 0xd5, 0xfc, 0xbf, 0x98, 0xd5, 0x34, 0xec, 0x4c, 0xbc, 0x61, 0xf9, + 0x14, 0x37, 0x08, 0xf3, 0x9e, 0x73, 0x84, 0xc3, 0xd9, 0xf0, 0xe9, 0x20, 0x04, 0x6a, 0x46, 0x03, + 0x4c, 0x02, 0x94, 0x6b, 0xec, 0x0b, 0x16, 0x30, 0xff, 0xfe, 0x73, 0xd5, 0xe8, 0xb3, 0x48, 0x77, + 0x7d, 0xdc, 0xfd, 0xce, 0x78, 0x9e, 0x04, 0xd2, 0xa6, 0xb4, 0x66, 0xa3, 0x9f, 0x80, 0x5f, 0x93, + 0x5a, 0xfb, 0xad, 0x6f, 0x97, 0x77, 0x72, 0xc4, 0x47, 0x9c, 0x86, 0x83, 0x26, 0x8c, 0x8b, 0x2a, + 0xe4, 0x9b, 0x9d, 0xc6, 0x24, 0x9c, 0x64, 0x3a, 0x9f, 0x47, 0xc4, 0x32, 0x4e, 0x55, 0x43, 0x11, + 0x9a, 0x88, 0x70, 0x9e, 0xa1, 0x72, 0xa9, 0xc0, 0x00, 0x97, 0x1c, 0x1c, 0x0e, 0x18, 0x8a, 0x27, + 0x4f, 0xdb, 0x8a, 0xfc, 0x14, 0xcf, 0x00, 0x02, 0xd3, 0x80, 0x0f, 0x0f, 0x81, 0x2b, 0x30, 0xbc, + 0xb3, 0xf2, 0xc2, 0x0d, 0x2a, 0x75, 0xee, 0x23, 0x9e, 0x2e, 0x03, 0x24, 0x49, 0x4b, 0x5a, 0xe0, + 0x41, 0x02, 0x80, 0x73, 0x52, 0x52, 0x48, 0xc5, 0x6f, 0xd3, 0xe2, 0x5f, 0x88, 0x12, 0x34, 0x9d, + 0xd1, 0x0a, 0xb0, 0xa5, 0x5a, 0x52, 0xa1, 0xb7, 0x8f, 0x03, 0x85, 0x51, 0x29, 0xc1, 0xf1, 0x96, + 0xe3, 0x15, 0x41, 0xfc, 0x22, 0x58, 0x3f, 0xa7, 0xf0, 0x80, 0x80, 0xa6, 0xbd, 0xb9, 0xfe, 0xee, + 0xad, 0x1b, 0xab, 0xb0, 0xbc, 0x5c, 0x9c, 0xb2, 0x2c, 0x0d, 0x1b, 0x58, 0x31, 0x08, 0x8c, 0x2a, + 0x1d, 0x55, 0xec, 0x32, 0x9e, 0xaa, 0x89, 0x4c, 0x74, 0xb0, 0x5f, 0x92, 0x8f, 0x81, 0x24, 0x10, + 0x85, 0x08, 0x4b, 0x51, 0xe0, 0xb3, 0x48, 0xb0, 0x32, 0x40, 0x02, 0x88, 0x30, 0x21, 0x14, 0x79, + 0xc5, 0x18, 0xac, 0x7d, 0x55, 0x62, 0x57, 0x65, 0xf8, 0xe0, 0x36, 0x43, 0x21, 0x49, 0x59, 0x78, + 0x78, 0x58, 0x4f, 0x57, 0x40, 0xef, 0x73, 0x2c, 0xa6, 0x5f, 0x3c, 0xdc, 0xdf, 0xcf, 0x86, 0x2c, + 0x89, 0xa4, 0xbc, 0x87, 0xfc, 0x1e, 0xf0, 0xb8, 0x78, 0x03, 0x87, 0x80, 0xe0, 0x08, 0x08, 0x1c, + 0x00, 0x09, 0xc0, 0x4c, 0x78, 0xd0, 0xa5, 0x5b, 0x89, 0x74, 0x1a, 0x0c, 0x5f, 0x0d, 0xf0, 0xb3, + 0x92, 0x9c, 0xd0, 0x1b, 0xfc, 0xaa, 0xbb, 0x0b, 0xf7, 0xbd, 0xd7, 0x2e, 0xf7, 0x2f, 0x26, 0xdf, + 0x7c, 0x5d, 0xd7, 0x6a, 0x92, 0xf9, 0x6e, 0xe6, 0x8f, 0xe2, 0x0a, 0xa4, 0x8d, 0x51, 0xb6, 0x46, + 0x25, 0xf4, 0x43, 0x27, 0xc7, 0xde, 0xf9, 0x58, 0xf6, 0xd3, 0xe2, 0x5d, 0xd8, 0x63, 0xdf, 0xfc, + 0x11, 0x16, 0x6e, 0xfd, 0x7c, 0x39, 0xc4, 0x9c, 0x4e, 0x2f, 0x16, 0xff, 0x88, 0x0c, 0x69, 0x08, + 0x70, 0xe0, 0x72, 0x2e, 0x36, 0xa7, 0x87, 0x85, 0xf8, 0x0e, 0x1c, 0x5f, 0xe2, 0x3b, 0x83, 0x00, + 0x42, 0x14, 0x2d, 0xc5, 0x18, 0xa3, 0x1a, 0x65, 0x01, 0xee, 0x28, 0xc4, 0x83, 0x95, 0x0e, 0xd8, + 0x28, 0xc5, 0x63, 0xb6, 0x0e, 0xd9, 0x96, 0x1a, 0x65, 0x00, 0x7b, 0xa6, 0xd5, 0x4f, 0xf6, 0xf5, + 0xfc, 0xc9, 0x85, 0xb0, 0x82, 0x15, 0x4d, 0xa7, 0xe9, 0xb7, 0xff, 0x0c, 0x82, 0x91, 0xa2, 0x24, + 0xcb, 0xa8, 0x5b, 0x39, 0xe1, 0x4b, 0x34, 0x5e, 0xe7, 0x3d, 0x20, 0x9b, 0x49, 0xa6, 0x33, 0xd6, + 0x0a, 0x80, 0x24, 0x02, 0x50, 0x28, 0x00, 0x44, 0x88, 0x30, 0x85, 0x7d, 0x03, 0xbb, 0xc4, 0x5e, + 0xfd, 0x0e, 0xe0, 0x05, 0x0a, 0x1c, 0x8d, 0x0e, 0x84, 0x70, 0x51, 0x1f, 0xff, 0x7e, 0xdc, 0x6f, + 0x87, 0x06, 0xfe, 0xde, 0x5e, 0x5b, 0x1f, 0xf6, 0xf2, 0xcb, 0x34, 0x0f, 0x23, 0xcf, 0xf2, 0xfc, + 0x1b, 0xbb, 0x28, 0xae, 0xc0, 0x22, 0x00, 0x40, 0x1a, 0x41, 0x20, 0x3c, 0x99, 0x68, 0x27, 0xdc, + 0x15, 0x0e, 0x89, 0x95, 0x0a, 0xe4, 0x43, 0x00, 0x0d, 0xb6, 0x18, 0x02, 0xe4, 0x24, 0x49, 0xc0, + 0x74, 0xc7, 0xe8, 0x62, 0xc6, 0xfc, 0xff, 0xaa, 0x02, 0xb5, 0x32, 0xf1, 0x1f, 0xc7, 0x9b, 0xb6, + 0x41, 0x9d, 0xf8, 0xfb, 0xa6, 0x3b, 0xff, 0x10, 0x19, 0x1b, 0x72, 0x00, 0x74, 0x3c, 0x0e, 0x56, + 0x17, 0x8e, 0x52, 0x5d, 0x39, 0xdf, 0x66, 0x15, 0x29, 0x39, 0x19, 0xfb, 0x3a, 0x42, 0x30, 0xf8, + 0x6a, 0x5c, 0xf1, 0xfc, 0xb0, 0x19, 0xc0, 0x2c, 0x15, 0x08, 0x89, 0x7a, 0x6a, 0xd9, 0xbe, 0x0a, + 0x42, 0x00, 0xaa, 0x5c, 0x26, 0x16, 0xc2, 0x71, 0x57, 0xe1, 0xe9, 0x04, 0x43, 0x8b, 0x79, 0x5e, + 0x44, 0xb9, 0x09, 0xcb, 0x41, 0x32, 0x44, 0x82, 0x63, 0x82, 0x90, 0x88, 0x46, 0x2f, 0x28, 0x12, + 0x86, 0xce, 0x94, 0xa4, 0xc6, 0x11, 0x74, 0xa6, 0x3c, 0xc0, 0xbc, 0xd2, 0xac, 0x88, 0x60, 0xd4, + 0xa0, 0xcb, 0x80, 0x44, 0x41, 0x08, 0xfc, 0xf5, 0xc4, 0xe0, 0x2f, 0x48, 0xb9, 0x78, 0x04, 0x44, + 0x18, 0x8d, 0x2d, 0xed, 0x43, 0x49, 0x20, 0xbe, 0xb3, 0x51, 0xca, 0x92, 0xe2, 0x49, 0x46, 0xd0, + 0x7e, 0x5c, 0x20, 0x41, 0x35, 0xbf, 0xfc, 0xbc, 0xfe, 0x14, 0xe4, 0xde, 0xe2, 0x79, 0x08, 0xab, + 0xbe, 0x42, 0xbb, 0xfe, 0x3e, 0xa2, 0xa5, 0x06, 0x1c, 0x65, 0xf1, 0xe2, 0x3e, 0xba, 0xf8, 0x8a, + 0x57, 0xcf, 0x9f, 0x93, 0x25, 0xfe, 0x61, 0x3c, 0xb9, 0x89, 0x84, 0xcd, 0x55, 0xa5, 0xa7, 0xe3, + 0xcd, 0x2f, 0xbb, 0xd9, 0xf4, 0xe3, 0xb4, 0x7f, 0x89, 0x29, 0x5c, 0xc4, 0x3f, 0xd1, 0xf8, 0x73, + 0x03, 0xe1, 0xa8, 0x2c, 0x4d, 0x43, 0x9b, 0xc0, 0x18, 0x21, 0x28, 0x8c, 0x09, 0x54, 0x73, 0xa5, + 0xfc, 0x57, 0x0f, 0x48, 0x00, 0x0e, 0xeb, 0x36, 0xb2, 0x78, 0x12, 0x82, 0x12, 0xd3, 0x27, 0x27, + 0x67, 0x67, 0xe1, 0x96, 0xb6, 0x41, 0xfc, 0x7f, 0xbb, 0xdd, 0xdb, 0x09, 0x1f, 0x70, 0x30, 0x74, + 0x41, 0x1d, 0xf1, 0xfe, 0x8d, 0x9e, 0x38, 0x50, 0x87, 0x00, 0x3e, 0x4d, 0x90, 0x7d, 0x3a, 0xdf, + 0xe7, 0xee, 0x2d, 0x65, 0xae, 0xda, 0xfe, 0x15, 0x8f, 0x01, 0xdb, 0xd3, 0x6f, 0xfe, 0x06, 0x90, + 0x52, 0x34, 0xc9, 0xd1, 0xd4, 0x2c, 0x20, 0x7c, 0x4a, 0x71, 0x56, 0x5f, 0x1d, 0x0f, 0x11, 0x88, + 0xc0, 0xfd, 0xab, 0x29, 0x74, 0x31, 0x03, 0x85, 0x04, 0x02, 0xc8, 0x38, 0x3b, 0x28, 0x3b, 0x44, + 0x83, 0x47, 0xed, 0x8b, 0x65, 0xe2, 0xd8, 0xb6, 0xde, 0x1c, 0x50, 0x05, 0x86, 0x4b, 0x3f, 0x87, + 0xb7, 0xf1, 0x6c, 0x33, 0x8e, 0xd8, 0x42, 0x85, 0x8a, 0x16, 0x31, 0x82, 0x48, 0x9a, 0x75, 0xb6, + 0x2a, 0xc5, 0x17, 0xe0, 0xa0, 0x10, 0x82, 0x3b, 0xc5, 0x6f, 0x98, 0xf0, 0x88, 0x50, 0xa2, 0x78, + 0xe8, 0x0b, 0xc9, 0x66, 0xf1, 0xc2, 0x63, 0x31, 0x62, 0xeb, 0x78, 0xad, 0xc4, 0x38, 0xa0, 0x0d, + 0xfd, 0x81, 0x7f, 0xc4, 0x22, 0x0f, 0xf7, 0xef, 0x6f, 0x55, 0x2f, 0x8c, 0x97, 0x2c, 0x94, 0xcb, + 0x8e, 0x3a, 0x69, 0xd3, 0xd3, 0x0d, 0x9c, 0x13, 0xb7, 0x5e, 0x9e, 0x9a, 0x70, 0xe2, 0x80, 0x52, + 0x3b, 0x65, 0x26, 0x19, 0x7f, 0xfb, 0x69, 0x24, 0x2a, 0xcb, 0x5b, 0xa5, 0xb6, 0xdb, 0xb8, 0xab, + 0x07, 0x5f, 0x72, 0xdf, 0x4e, 0xd9, 0xfe, 0x19, 0x12, 0x14, 0x8d, 0x50, 0xbb, 0x8c, 0xa4, 0x4a, + 0xdc, 0xc5, 0x6e, 0x77, 0x4b, 0x06, 0xed, 0x1d, 0xf5, 0xee, 0xc5, 0xf7, 0x0c, 0x88, 0x05, 0x73, + 0x06, 0x0a, 0xe9, 0x5d, 0x6e, 0xdb, 0x83, 0xa5, 0xfd, 0xc2, 0x22, 0x01, 0x49, 0x0f, 0xe6, 0xb5, + 0x6b, 0x93, 0x3d, 0x8e, 0x11, 0x08, 0x82, 0xa8, 0x55, 0x62, 0xee, 0x78, 0xf7, 0x76, 0x7c, 0xf0, + 0x24, 0x11, 0x4c, 0x0d, 0x65, 0x56, 0x4a, 0x00, 0x18, 0xec, 0xd2, 0xee, 0x84, 0xdc, 0x22, 0x11, + 0x0a, 0x15, 0xda, 0x91, 0x31, 0x53, 0x9c, 0xc4, 0x39, 0x0f, 0x2b, 0x22, 0xb4, 0xa7, 0x66, 0xa3, + 0xc5, 0x45, 0xf0, 0xf7, 0x03, 0xaa, 0x9d, 0x96, 0x34, 0x59, 0xf0, 0xb4, 0x1d, 0x3f, 0x07, 0x5f, + 0xaf, 0x5c, 0xe7, 0x28, 0x16, 0x16, 0xf0, 0xa9, 0xc6, 0x58, 0x70, 0xdf, 0x75, 0x5a, 0x89, 0xec, + 0xef, 0xaa, 0xe8, 0x47, 0x7c, 0x77, 0xaa, 0x97, 0x34, 0x2a, 0x5b, 0xc3, 0xb8, 0x00, 0x10, 0xdb, + 0x88, 0xa5, 0xf2, 0x2f, 0x41, 0x2e, 0x52, 0x69, 0xe3, 0x74, 0x8c, 0xaa, 0x1b, 0xf8, 0x50, 0x41, + 0xec, 0x73, 0x78, 0xac, 0x9c, 0x1d, 0x19, 0xcf, 0x60, 0xce, 0x0e, 0x2d, 0x0a, 0x81, 0x6f, 0xfc, + 0x2c, 0xe0, 0x59, 0x2d, 0x21, 0x89, 0xd7, 0x6f, 0x33, 0x5c, 0xca, 0xdf, 0xcf, 0x79, 0xf9, 0xef, + 0xfb, 0x96, 0xdd, 0xe1, 0x44, 0x50, 0x02, 0x47, 0x94, 0x44, 0x18, 0x85, 0x97, 0x75, 0xff, 0x6d, + 0xbe, 0x1e, 0xc0, 0x04, 0xa3, 0x99, 0x70, 0xa3, 0xb3, 0x37, 0xe3, 0x54, 0xcb, 0xb1, 0xcd, 0xc9, + 0xf5, 0xab, 0x75, 0x55, 0x18, 0xe7, 0xf7, 0x5c, 0x04, 0x80, 0x14, 0x01, 0x2e, 0xa3, 0x15, 0xa1, + 0x75, 0xe6, 0x1e, 0x31, 0xc2, 0x46, 0x35, 0x87, 0x84, 0x42, 0x9b, 0xb5, 0x41, 0x76, 0xaa, 0x2e, + 0x36, 0xad, 0x0c, 0x1a, 0x9d, 0x88, 0xe5, 0x6b, 0x86, 0x47, 0xe2, 0xea, 0xa8, 0x20, 0x24, 0xe1, + 0x3b, 0x1d, 0xe1, 0x90, 0x88, 0x52, 0xd3, 0x42, 0xe2, 0xe7, 0xc2, 0xdc, 0xc9, 0x87, 0x71, 0xd5, + 0x5d, 0x93, 0xa8, 0xd9, 0x7c, 0x34, 0x8a, 0x00, 0xea, 0xe8, 0x6e, 0x33, 0x5b, 0xfa, 0x7b, 0x7b, + 0x6d, 0xb7, 0x11, 0x1d, 0x43, 0xcc, 0x40, 0x00, 0xf8, 0x8d, 0x6c, 0x2a, 0x50, 0x76, 0x0f, 0x77, + 0x6e, 0xcf, 0xdd, 0xe2, 0xbb, 0x96, 0xcf, 0x3c, 0x51, 0x96, 0x63, 0xd0, 0x61, 0xcf, 0xdf, 0x82, + 0x00, 0x20, 0x85, 0x35, 0x97, 0x8e, 0xfc, 0xfe, 0x17, 0x8a, 0x67, 0x70, 0xba, 0x28, 0xcd, 0xc5, + 0x0f, 0x90, 0xe1, 0xbc, 0x62, 0x67, 0xca, 0x70, 0x3a, 0x78, 0xa0, 0x3c, 0x4e, 0x2a, 0x02, 0x04, + 0xf7, 0x16, 0xac, 0x02, 0x30, 0x0e, 0x42, 0x91, 0x73, 0x60, 0x8e, 0x33, 0x0a, 0x37, 0x8f, 0xe1, + 0x4a, 0xf0, 0xff, 0x0a, 0x0d, 0xf5, 0xba, 0x0d, 0x48, 0x00, 0x2e, 0x2e, 0x2f, 0x85, 0x85, 0x78, + 0xd1, 0x41, 0x9e, 0xf0, 0x80, 0x27, 0x2b, 0xbd, 0xe2, 0xbb, 0xbf, 0x13, 0x0a, 0x12, 0x18, 0xa6, + 0x63, 0x92, 0xf7, 0x49, 0xee, 0x2b, 0x77, 0x15, 0xdb, 0xc4, 0x8c, 0x2a, 0x2f, 0x16, 0x1b, 0x4d, + 0x94, 0x66, 0x9c, 0x0b, 0x04, 0xcd, 0xc3, 0xd3, 0x14, 0xe3, 0x91, 0xf0, 0xbd, 0x7d, 0xe3, 0xde, + 0x25, 0x87, 0x85, 0xa1, 0xdd, 0xaf, 0xf1, 0xf5, 0xf9, 0x21, 0x51, 0x0b, 0xc5, 0x36, 0xc5, 0xe1, + 0xfe, 0x42, 0x56, 0xa5, 0xe1, 0x11, 0x2a, 0xaa, 0x9a, 0xae, 0xb5, 0xac, 0x48, 0xea, 0x47, 0x20, + 0xe5, 0x87, 0x5a, 0xf8, 0x91, 0x42, 0x23, 0xcb, 0xae, 0xf7, 0xf0, 0x55, 0xc4, 0xfa, 0x4a, 0x94, + 0x94, 0x00, 0x0b, 0x29, 0x20, 0x00, 0x14, 0x53, 0x80, 0x38, 0x48, 0x05, 0x52, 0x8a, 0x07, 0xc3, + 0x53, 0x40, 0x53, 0x0f, 0x38, 0x0f, 0x19, 0xc3, 0x54, 0x95, 0x6d, 0xf6, 0xff, 0x6d, 0xde, 0x7e, + 0xbf, 0xbe, 0x1a, 0x94, 0x00, 0x4b, 0x47, 0x8f, 0x24, 0x71, 0x48, 0x79, 0xbe, 0xf7, 0xf8, 0x97, + 0xc1, 0xd1, 0xfe, 0xe0, 0xe2, 0x0a, 0xc8, 0x25, 0xf9, 0xee, 0x89, 0x30, 0x33, 0x12, 0xf4, 0x1f, + 0x24, 0xfa, 0x71, 0x17, 0xda, 0x76, 0x00, 0x2a, 0x5b, 0x96, 0x03, 0x10, 0x38, 0x24, 0xa3, 0x6b, + 0x0c, 0x09, 0x2f, 0x77, 0x87, 0x14, 0x13, 0xd6, 0x8c, 0x9f, 0xff, 0xeb, 0x5b, 0x1b, 0x7f, 0xe0, + 0x50, 0x02, 0xc0, 0xf9, 0x56, 0xf9, 0x50, 0x5f, 0xde, 0x2c, 0xbf, 0x33, 0x31, 0x3c, 0xaa, 0x06, + 0x9c, 0x3d, 0x80, 0x3e, 0x67, 0x54, 0x34, 0xda, 0xee, 0xd1, 0xd7, 0x74, 0x7a, 0x75, 0x1d, 0x5e, + 0xec, 0xd3, 0x06, 0x37, 0x3b, 0xae, 0x9a, 0x7a, 0x65, 0xf0, 0xe6, 0x00, 0x2f, 0xd8, 0x57, 0x3b, + 0x0e, 0x41, 0x65, 0x0f, 0xfa, 0x9a, 0x70, 0x78, 0xfb, 0x38, 0x36, 0xf8, 0xbb, 0xd3, 0x16, 0xf2, + 0xf4, 0xc7, 0xfc, 0x6d, 0x17, 0x37, 0xef, 0x78, 0x6d, 0x90, 0x01, 0x59, 0x5a, 0x20, 0x03, 0xeb, + 0xd8, 0x10, 0xee, 0xb6, 0xdb, 0xac, 0xbc, 0xd0, 0x2f, 0x38, 0x7e, 0x70, 0x3c, 0x1b, 0x94, 0x5c, + 0x5c, 0xae, 0x56, 0x7d, 0x02, 0xc2, 0xb7, 0xc5, 0xe2, 0xfc, 0x02, 0x32, 0x10, 0x0a, 0x50, 0x00, + 0x01, 0x0e, 0x38, 0x3c, 0xb3, 0x24, 0x08, 0x20, 0x4e, 0x58, 0x92, 0x38, 0x27, 0xe0, 0xd8, 0x77, + 0x45, 0xc8, 0x96, 0x1c, 0x02, 0xc0, 0xef, 0xe5, 0xea, 0x7e, 0xf1, 0x20, 0x97, 0x90, 0xb9, 0x86, + 0x6e, 0x73, 0x66, 0x4a, 0xb1, 0x11, 0x82, 0xe3, 0x30, 0x0a, 0x96, 0xb7, 0x94, 0x0d, 0x78, 0xba, + 0xc4, 0x7a, 0xe2, 0x64, 0x21, 0x14, 0x9c, 0x0f, 0xa2, 0xc4, 0x43, 0xfc, 0x2f, 0xcb, 0x0f, 0xc0, + 0x58, 0x0b, 0x0c, 0x12, 0x87, 0x98, 0x95, 0x2d, 0x80, 0x02, 0x59, 0x91, 0x41, 0x40, 0x05, 0x80, + 0x75, 0xa5, 0xc8, 0x48, 0x34, 0x13, 0xf0, 0x63, 0x71, 0x56, 0xef, 0x05, 0x15, 0x85, 0x45, 0x2a, + 0x70, 0xc0, 0x52, 0x4b, 0x54, 0xa0, 0x93, 0x51, 0x5f, 0xf3, 0x41, 0x07, 0x75, 0x5f, 0xc1, 0x26, + 0xb5, 0xef, 0x96, 0xaa, 0xaa, 0xb9, 0x04, 0xd6, 0xbc, 0x41, 0x8c, 0xc2, 0x1c, 0xce, 0xbc, 0x8f, + 0x88, 0x18, 0x66, 0x8a, 0x4d, 0x50, 0x35, 0x44, 0xaf, 0x93, 0xdb, 0x7d, 0x2d, 0x2a, 0xa4, 0xd7, + 0xc4, 0xc1, 0x16, 0x50, 0x86, 0x82, 0x15, 0x61, 0xac, 0x58, 0x6c, 0x90, 0x02, 0xb6, 0x3b, 0xdf, + 0xe0, 0x4c, 0x6e, 0x42, 0x3b, 0x4c, 0xa8, 0x03, 0x94, 0x71, 0x5d, 0xeb, 0x7f, 0x8c, 0x72, 0x2e, + 0x29, 0x86, 0x14, 0xf7, 0x5d, 0xb8, 0xff, 0x37, 0x86, 0xb5, 0xe5, 0xf3, 0xf6, 0xd2, 0x3f, 0x27, + 0x6f, 0x87, 0x89, 0x00, 0x1f, 0x9f, 0x09, 0x0d, 0xc5, 0x79, 0x4b, 0x70, 0x59, 0x96, 0x4c, 0x32, + 0xc9, 0x8f, 0xc2, 0x92, 0xb0, 0xac, 0xe1, 0x7a, 0x14, 0x69, 0xe9, 0x47, 0x7b, 0x2f, 0x99, 0xc9, + 0x41, 0xd1, 0x1f, 0x8c, 0xd2, 0x9c, 0x96, 0x10, 0x18, 0xb8, 0x70, 0x78, 0x0a, 0xb1, 0xa4, 0xd9, + 0xc5, 0xdb, 0x67, 0x18, 0x8f, 0xc3, 0x02, 0x42, 0x97, 0xc0, 0x70, 0xb0, 0x1d, 0x41, 0x65, 0x45, + 0x00, 0x19, 0x60, 0x0c, 0xf0, 0x07, 0x0b, 0x00, 0x06, 0x7a, 0xc9, 0x76, 0x3e, 0x61, 0x9d, 0xf8, + 0x1d, 0x8d, 0x59, 0x8c, 0xe2, 0x14, 0x83, 0x2d, 0x61, 0xbc, 0x00, 0x26, 0x9b, 0x33, 0x09, 0x69, + 0xd8, 0x55, 0xe7, 0xf9, 0x32, 0xfb, 0xef, 0x1d, 0xbb, 0xfd, 0x65, 0x5f, 0x17, 0x1d, 0xb8, 0xe7, + 0x81, 0xf4, 0x2b, 0x18, 0xda, 0x72, 0xd4, 0x51, 0x60, 0xff, 0x8e, 0x7f, 0x0e, 0x4a, 0x00, 0x64, + 0x58, 0xb3, 0xc2, 0x0f, 0x9c, 0xdd, 0xb3, 0x75, 0x6f, 0x6c, 0x52, 0xca, 0xe5, 0x58, 0xb5, 0x32, + 0x3e, 0x3a, 0xa3, 0xa4, 0x60, 0xa4, 0xe2, 0xad, 0xb0, 0x59, 0x87, 0xa2, 0x23, 0x1d, 0xbe, 0x19, + 0x08, 0x0c, 0x8a, 0xc5, 0x1a, 0xa6, 0x3e, 0xae, 0xe7, 0xfa, 0x8a, 0x13, 0x31, 0x9c, 0x3e, 0xb3, + 0x7d, 0xfa, 0x0e, 0xd9, 0x81, 0x44, 0x20, 0x14, 0x93, 0x9f, 0xed, 0xf5, 0x96, 0x65, 0x80, 0xcd, + 0xcb, 0x76, 0x0c, 0xd8, 0x59, 0xc5, 0x69, 0x6b, 0x80, 0x6a, 0x00, 0x40, 0x8d, 0x82, 0x54, 0x41, + 0x01, 0x46, 0xe1, 0x9c, 0x70, 0x05, 0x4d, 0x6f, 0x2f, 0x87, 0xb8, 0x5b, 0x21, 0x40, 0x95, 0x6a, + 0x9f, 0x20, 0xce, 0xb0, 0x28, 0xb0, 0xd8, 0x92, 0x98, 0xd2, 0xc0, 0xad, 0x03, 0xc9, 0x54, 0x00, + 0xa8, 0x7c, 0x39, 0x20, 0x03, 0x3d, 0x24, 0x85, 0xd4, 0x84, 0x13, 0x88, 0x08, 0xb4, 0xdc, 0xb5, + 0x4a, 0x8c, 0x9a, 0xde, 0x5d, 0x5f, 0xd8, 0x0c, 0x00, 0x52, 0x37, 0x64, 0xb5, 0x26, 0x1c, 0x0b, + 0x4f, 0xe0, 0x46, 0x2c, 0x09, 0x56, 0x80, 0x01, 0x20, 0x6a, 0x91, 0x65, 0xe1, 0x20, 0xa8, 0x71, + 0x44, 0xb5, 0x49, 0xab, 0x07, 0xcf, 0x48, 0x9e, 0xcf, 0x72, 0x33, 0xdc, 0x10, 0x49, 0x03, 0x29, + 0x37, 0xac, 0x55, 0xc6, 0xa5, 0xac, 0x51, 0x78, 0x42, 0x14, 0x22, 0xc0, 0x8b, 0x12, 0x1d, 0x1f, + 0x5e, 0x00, 0xac, 0xb1, 0x57, 0xcf, 0x2b, 0xe9, 0x1c, 0xe1, 0x67, 0x1b, 0x6c, 0xb5, 0x05, 0x07, + 0x8f, 0x07, 0x17, 0x79, 0xd4, 0xdc, 0xf1, 0x23, 0xe7, 0x65, 0x5e, 0x4d, 0x6b, 0x25, 0xdd, 0x6a, + 0x24, 0xe6, 0x11, 0x82, 0xbc, 0xeb, 0xcc, 0xa2, 0x1e, 0x29, 0x81, 0x7b, 0x27, 0x51, 0x01, 0xe4, + 0xf5, 0x2a, 0x82, 0xf3, 0x71, 0x10, 0x85, 0x56, 0xb5, 0x1c, 0x4b, 0x07, 0x15, 0x94, 0x39, 0xb7, + 0x00, 0x8c, 0x83, 0x90, 0x87, 0xd5, 0x62, 0x7d, 0xf1, 0x1c, 0xb3, 0xe0, 0x11, 0x90, 0x72, 0x14, + 0x9f, 0x81, 0xdc, 0x76, 0x61, 0xc7, 0x0f, 0x00, 0x3e, 0x45, 0x12, 0x91, 0xf9, 0x31, 0x64, 0xbf, + 0xe7, 0xc1, 0x19, 0xc3, 0xc0, 0x00, 0x40, 0x69, 0x8f, 0x0f, 0x2c, 0x3b, 0x88, 0x17, 0x41, 0x8e, + 0xad, 0x5d, 0xd6, 0xb2, 0x71, 0x84, 0x2f, 0x2e, 0xbe, 0xf7, 0xd3, 0x7c, 0xf8, 0x6e, 0x8a, 0xb6, + 0xb8, 0x42, 0x92, 0x5e, 0xa3, 0x74, 0xd5, 0xab, 0x12, 0x78, 0x40, 0xe4, 0xc6, 0x67, 0x5a, 0xf3, + 0x62, 0xe6, 0x25, 0x12, 0xaf, 0x8e, 0x34, 0xb0, 0x9c, 0xc4, 0xc2, 0x54, 0xd4, 0xf9, 0xa7, 0x5a, + 0xe6, 0xcf, 0x13, 0x1e, 0x4f, 0xe8, 0x5a, 0xa5, 0xf0, 0x5c, 0x53, 0xfe, 0x5c, 0x10, 0xe0, 0x64, + 0x15, 0x62, 0x8f, 0xf0, 0x11, 0x61, 0xc5, 0x00, 0x28, 0xf6, 0x1f, 0xb5, 0xfe, 0x13, 0xc5, 0x58, + 0x2c, 0x2e, 0x90, 0x97, 0xa7, 0x38, 0xec, 0x21, 0x99, 0x8d, 0x43, 0xd8, 0x71, 0x97, 0x71, 0x37, + 0x77, 0x6e, 0xb7, 0x74, 0xc1, 0x00, 0x20, 0x19, 0x8c, 0x62, 0x42, 0x4c, 0xba, 0xcb, 0x5e, 0xde, + 0x1d, 0x50, 0x02, 0xbf, 0x0f, 0xbd, 0xb4, 0x79, 0xdf, 0x66, 0x38, 0x74, 0x94, 0x74, 0xea, 0x2d, + 0x38, 0x61, 0x4f, 0x37, 0xb6, 0xdd, 0x37, 0x7e, 0x64, 0x16, 0x33, 0x7e, 0xad, 0x70, 0x80, 0x90, + 0x56, 0x72, 0x33, 0xc0, 0xd8, 0x16, 0x19, 0x5a, 0x0e, 0xc2, 0x6c, 0x2a, 0xf4, 0x75, 0xd3, 0x1f, + 0xf2, 0xe8, 0xa1, 0xbf, 0x8b, 0xa0, 0x94, 0x3c, 0xfc, 0x14, 0x84, 0x09, 0x71, 0xd1, 0xe7, 0xc0, + 0x92, 0x14, 0x10, 0x1d, 0x83, 0x52, 0xc0, 0x00, 0x9d, 0xd8, 0x38, 0xd8, 0x28, 0x00, 0x11, 0x96, + 0x00, 0x04, 0x61, 0xc6, 0x35, 0x3c, 0x00, 0x1c, 0x14, 0xce, 0xe0, 0x58, 0xd1, 0xb8, 0x5f, 0x1b, + 0xb9, 0x78, 0x1f, 0xa0, 0xf8, 0xb8, 0x0f, 0x00, 0x88, 0xd9, 0x78, 0x1f, 0x92, 0x97, 0xe3, 0xc0, + 0xb0, 0xe0, 0x3d, 0x5d, 0x80, 0x60, 0xa0, 0x21, 0xe5, 0x80, 0x01, 0x48, 0x1d, 0x41, 0x28, 0x93, + 0xcb, 0x03, 0x59, 0x91, 0x2d, 0x43, 0xc3, 0x43, 0xc5, 0xb0, 0x7f, 0xf8, 0xab, 0x7c, 0x38, 0xa0, + 0x04, 0xd2, 0x2d, 0x00, 0xd1, 0x51, 0x48, 0xe3, 0x2f, 0xff, 0xd9, 0x74, 0x6e, 0x20, 0xe9, 0x92, + 0x6f, 0x86, 0x65, 0x43, 0x0c, 0x4e, 0x4c, 0xa8, 0x94, 0xdd, 0xba, 0xdb, 0xb5, 0xf0, 0x75, 0x06, + 0x30, 0x7f, 0xf8, 0xf7, 0xfe, 0x01, 0x89, 0x03, 0x80, 0x50, 0xab, 0x96, 0x28, 0x2e, 0x15, 0x8d, + 0x5b, 0x27, 0x80, 0x58, 0xdf, 0xdb, 0xb8, 0x9e, 0x17, 0xd2, 0x8a, 0xe0, 0xf3, 0xe0, 0x86, 0x37, + 0x86, 0xf0, 0x10, 0x93, 0x46, 0x2e, 0xa3, 0x9f, 0xbe, 0x57, 0x51, 0xd1, 0x48, 0x2b, 0xa4, 0xee, + 0x67, 0x3f, 0x7f, 0x6d, 0x65, 0xd7, 0x45, 0x65, 0xc3, 0xc6, 0x07, 0xbe, 0x4b, 0x60, 0xed, 0xc0, + 0xe6, 0x03, 0x09, 0x84, 0xa0, 0xfb, 0x97, 0x62, 0xf1, 0xce, 0x2c, 0xb2, 0x6e, 0x9e, 0x01, 0x08, + 0x05, 0x01, 0x52, 0x88, 0x1c, 0x26, 0x57, 0xac, 0xa8, 0x9f, 0x8a, 0x89, 0xfb, 0xc8, 0x82, 0xa4, + 0x85, 0xb4, 0xf1, 0x4b, 0x26, 0xf8, 0x04, 0x60, 0x18, 0x02, 0x19, 0x54, 0xfc, 0x55, 0x7e, 0xbd, + 0xf8, 0x04, 0x60, 0x18, 0x12, 0xfc, 0xfc, 0x02, 0x30, 0x0c, 0x15, 0xeb, 0xab, 0x4b, 0xcb, 0xd5, + 0x42, 0xdc, 0x12, 0x08, 0x5d, 0x7a, 0x4e, 0x12, 0x3f, 0x54, 0xed, 0xdf, 0xd9, 0x39, 0x33, 0xc4, + 0x6d, 0x48, 0xf0, 0x1b, 0x5c, 0xa3, 0x3f, 0xf1, 0x15, 0xc6, 0x6e, 0x47, 0xd6, 0x7f, 0x21, 0x6a, + 0x92, 0x5e, 0x33, 0x4a, 0xd2, 0x44, 0x23, 0x69, 0x46, 0x3e, 0xb1, 0x31, 0x89, 0xd7, 0xc6, 0x51, + 0x4b, 0x96, 0x86, 0xc5, 0x87, 0x69, 0xdb, 0xe9, 0xb6, 0xd7, 0x84, 0x64, 0xa2, 0x3e, 0xed, 0x5d, + 0x19, 0xf2, 0xe1, 0xb7, 0x00, 0x1b, 0xe9, 0x39, 0x91, 0x93, 0x39, 0xe1, 0xab, 0x2c, 0xec, 0x62, + 0x5d, 0x12, 0xef, 0x6d, 0x1d, 0x63, 0x62, 0x4a, 0x6c, 0x33, 0xad, 0x90, 0x83, 0x08, 0xfe, 0xf7, + 0x5f, 0x0b, 0x60, 0x03, 0x65, 0x8e, 0x5e, 0x86, 0x57, 0x10, 0x3f, 0xec, 0x89, 0x6f, 0xa9, 0x7b, + 0x3b, 0xab, 0x22, 0xd2, 0xfb, 0xc2, 0xa4, 0x28, 0x00, 0xfa, 0x5e, 0x62, 0x48, 0x5c, 0xbe, 0x2d, + 0x8b, 0x66, 0x8d, 0xb3, 0x45, 0xd1, 0x57, 0xc0, 0xde, 0xdf, 0xeb, 0x75, 0x55, 0x24, 0x42, 0x8a, + 0x00, 0x17, 0x1b, 0x37, 0x4d, 0x18, 0x93, 0xe4, 0x5f, 0x19, 0x6d, 0x4b, 0xb1, 0xff, 0x89, 0x60, + 0x58, 0x9d, 0xcb, 0x77, 0x9a, 0x27, 0xee, 0xf0, 0xc9, 0x20, 0x04, 0x12, 0x96, 0x4a, 0x2c, 0xff, + 0xf7, 0x3a, 0x92, 0x0d, 0xec, 0x83, 0x7d, 0x3d, 0x7c, 0xfc, 0x55, 0xf6, 0x19, 0x50, 0x05, 0xec, + 0x52, 0x8b, 0xd3, 0x71, 0x0c, 0x13, 0xbd, 0x3d, 0xba, 0x63, 0x9c, 0xce, 0xc9, 0x31, 0x79, 0x60, + 0x6d, 0xd2, 0x50, 0x5c, 0x7e, 0x7e, 0x01, 0x09, 0x02, 0x80, 0x50, 0xc0, 0x61, 0xe2, 0x06, 0x86, + 0x3d, 0x1c, 0x00, 0x38, 0xb1, 0xd0, 0x21, 0x4d, 0x46, 0x9c, 0x3e, 0xe4, 0xa9, 0x0d, 0x4b, 0x00, + 0x06, 0x55, 0x78, 0x3d, 0xcf, 0x44, 0x28, 0x37, 0x60, 0xb8, 0xe0, 0x50, 0x12, 0x14, 0xc8, 0xa7, + 0xc4, 0x1c, 0x11, 0xeb, 0x22, 0xb2, 0x52, 0x45, 0x82, 0x6a, 0xc3, 0xbd, 0x24, 0x87, 0xbe, 0x70, + 0x38, 0x35, 0xcc, 0x31, 0x28, 0x02, 0x9d, 0x4c, 0x1a, 0x81, 0x4f, 0x30, 0x3e, 0xe5, 0xdb, 0xb9, + 0x6b, 0x16, 0xce, 0xf1, 0x56, 0x3b, 0x77, 0x19, 0xa1, 0x69, 0x98, 0xcb, 0x8c, 0x97, 0x71, 0x8b, + 0x90, 0x21, 0x50, 0xdb, 0x20, 0x01, 0x59, 0xd5, 0xb1, 0x44, 0xe6, 0xcc, 0x98, 0x88, 0xbe, 0xcf, + 0x3f, 0xba, 0xcf, 0x3c, 0x90, 0x3f, 0x03, 0xb0, 0x9b, 0x3a, 0x62, 0x6b, 0xbe, 0xe2, 0x18, 0x2c, + 0x2a, 0xca, 0x00, 0x2e, 0x14, 0x97, 0xd8, 0xe8, 0x9c, 0xb9, 0x55, 0x64, 0xc8, 0xde, 0xa9, 0x8e, + 0xe0, 0xbe, 0x38, 0xd5, 0x10, 0x9c, 0x31, 0x02, 0x46, 0xda, 0xaa, 0x51, 0xea, 0x19, 0x95, 0xd4, + 0xb8, 0x2e, 0x04, 0x9c, 0x7a, 0xc1, 0x63, 0xac, 0xb6, 0xe0, 0x0a, 0x14, 0x5d, 0xff, 0x07, 0x3f, + 0x2d, 0x3c, 0x39, 0xda, 0x0d, 0x31, 0x0b, 0xc4, 0x3b, 0xfe, 0x08, 0xf9, 0x2a, 0xd1, 0x8b, 0x29, + 0x78, 0xae, 0xaa, 0xa2, 0xea, 0x03, 0x09, 0x86, 0x22, 0x58, 0x20, 0x04, 0x03, 0x04, 0x36, 0x4f, + 0x53, 0xe0, 0xa3, 0x77, 0x1a, 0xe5, 0xe0, 0xf0, 0xd6, 0xa0, 0x59, 0xf3, 0x95, 0x2a, 0xe0, 0x07, + 0xa3, 0xf0, 0x40, 0x0c, 0x06, 0x44, 0xb4, 0xac, 0xa8, 0xdf, 0x3d, 0x90, 0x52, 0xa7, 0x1c, 0xac, + 0xbd, 0x94, 0xd5, 0x4a, 0xab, 0x93, 0x7e, 0x20, 0x15, 0x95, 0x54, 0x0d, 0x51, 0x76, 0x0c, 0x44, + 0xb8, 0x35, 0x3c, 0x9b, 0xc8, 0xc3, 0x57, 0x55, 0x55, 0x2e, 0xbb, 0x14, 0xfd, 0xe4, 0xc8, 0xde, + 0x4a, 0xd6, 0x23, 0x8a, 0xb6, 0xbb, 0xbb, 0xc9, 0xc2, 0x3b, 0x4a, 0x94, 0x2f, 0x50, 0x48, 0xf7, + 0x67, 0x44, 0xc0, 0xa4, 0xbb, 0xff, 0x8a, 0x29, 0xa1, 0x7b, 0x8a, 0xda, 0xe2, 0x21, 0x1e, 0x69, + 0x25, 0x66, 0xcc, 0x77, 0xd6, 0x36, 0x88, 0xb9, 0xac, 0x78, 0x88, 0x46, 0xb4, 0xb5, 0x52, 0xd5, + 0x4c, 0xca, 0xec, 0x9a, 0x6d, 0xf8, 0xec, 0xa8, 0x26, 0x41, 0x69, 0x5b, 0x49, 0xf6, 0xfc, 0x7d, + 0x9d, 0xdf, 0x9b, 0x16, 0x75, 0xc9, 0x0a, 0x7c, 0x3d, 0x67, 0xf6, 0x71, 0xcd, 0x9f, 0xe5, 0xd6, + 0xbe, 0x42, 0x69, 0x37, 0xe1, 0x2c, 0x2d, 0xe5, 0xb1, 0xe8, 0x76, 0xd6, 0x1d, 0x70, 0x33, 0x23, + 0xb3, 0x40, 0x99, 0x59, 0x81, 0x7f, 0xf5, 0xb5, 0x03, 0x21, 0x19, 0x27, 0x1c, 0xa6, 0x01, 0x56, + 0x85, 0xb3, 0x64, 0x25, 0xb3, 0x78, 0x0c, 0x74, 0x12, 0x66, 0xc6, 0x38, 0x09, 0x70, 0xf7, 0x96, + 0x1f, 0x0d, 0xb8, 0x03, 0x04, 0x84, 0xa7, 0xd0, 0x34, 0x09, 0x5e, 0xd4, 0x16, 0x9a, 0xa3, 0xbd, + 0x8c, 0x6c, 0x61, 0x35, 0x58, 0x1a, 0xc9, 0x65, 0x07, 0x72, 0x55, 0x5c, 0x8d, 0x8c, 0x29, 0xd0, + 0x6c, 0x0a, 0x6e, 0xac, 0xab, 0x45, 0x82, 0x11, 0x23, 0x48, 0x24, 0x03, 0xc3, 0x11, 0x44, 0xc0, + 0x9b, 0x50, 0xff, 0x87, 0xce, 0x39, 0x5d, 0x09, 0x24, 0xf5, 0x1f, 0x78, 0xb7, 0xe0, 0x12, 0x5d, + 0xe0, 0xd3, 0xd3, 0x90, 0x9f, 0x8c, 0xd3, 0x7a, 0x1b, 0xe1, 0x80, 0xc8, 0xd9, 0x6c, 0xf1, 0xe1, + 0x5a, 0x79, 0x28, 0x34, 0x2d, 0x88, 0x1c, 0x3f, 0x8e, 0xc2, 0xd6, 0x84, 0xad, 0x91, 0x82, 0xf2, + 0xcc, 0x90, 0x38, 0x01, 0xd9, 0x80, 0x96, 0x92, 0x09, 0x82, 0x48, 0x32, 0x4a, 0x47, 0xe2, 0x1f, + 0xba, 0xa3, 0x18, 0xe0, 0x20, 0x06, 0xc6, 0x19, 0x29, 0x68, 0x40, 0x7c, 0xfc, 0x10, 0x2c, 0x13, + 0x06, 0xaa, 0x8f, 0x3f, 0x7c, 0xdd, 0x55, 0x37, 0xf5, 0x90, 0xb0, 0x06, 0x0f, 0x88, 0x3f, 0x01, + 0xa8, 0x9c, 0x88, 0xed, 0x71, 0x56, 0x7f, 0xc5, 0x5f, 0x05, 0x03, 0x6e, 0x7c, 0x49, 0xf1, 0x61, + 0x96, 0x60, 0xff, 0x2f, 0x91, 0x86, 0xa4, 0x2c, 0x21, 0x71, 0x64, 0xb8, 0xb8, 0xa6, 0x1c, 0x3c, + 0x55, 0x1e, 0xf4, 0xf3, 0xd8, 0xc9, 0x74, 0x2d, 0x0f, 0xe1, 0x82, 0x40, 0xc2, 0x8e, 0xd8, 0xd2, + 0xdb, 0x6a, 0xf5, 0x35, 0x3e, 0x18, 0x0a, 0x14, 0xdd, 0xa9, 0xca, 0x34, 0xd7, 0x2d, 0xd4, 0x0c, + 0x7b, 0x53, 0xdc, 0xec, 0xf7, 0x2a, 0x69, 0x05, 0x84, 0xa8, 0xaf, 0xc2, 0xf4, 0xeb, 0x08, 0x02, + 0x80, 0x54, 0x6e, 0x98, 0x18, 0xda, 0x96, 0x61, 0xc0, 0x98, 0x80, 0xd6, 0xc3, 0xc7, 0x22, 0x3c, + 0xa3, 0x35, 0xc2, 0x5a, 0xb9, 0x3a, 0x67, 0xfa, 0x2f, 0x5c, 0x40, 0x2b, 0xee, 0x4a, 0x0a, 0xe6, + 0xc8, 0x33, 0x44, 0xee, 0x19, 0x9a, 0x82, 0x3c, 0xff, 0x4e, 0xda, 0xcc, 0x2f, 0x10, 0x1c, 0x2d, + 0x42, 0x8f, 0x8e, 0x69, 0x07, 0x8d, 0xf7, 0xf1, 0x01, 0x82, 0x2e, 0x98, 0x87, 0xa4, 0x5c, 0x2c, + 0x6f, 0xa6, 0x5e, 0xb3, 0xef, 0xf1, 0x01, 0x4b, 0x46, 0xc5, 0x95, 0x55, 0x52, 0xeb, 0x4d, 0x9a, + 0xd5, 0x3c, 0x38, 0x40, 0x20, 0x37, 0x75, 0x88, 0x73, 0x75, 0xcf, 0xe1, 0xa1, 0xcb, 0x86, 0xa2, + 0x6e, 0xdf, 0x7a, 0x6c, 0x6d, 0x22, 0xf5, 0xbf, 0x89, 0x04, 0xd9, 0x89, 0xc2, 0x56, 0x58, 0xd9, + 0xff, 0x78, 0x80, 0x4e, 0x58, 0xf5, 0xc5, 0xd5, 0x0c, 0xcc, 0x35, 0x94, 0x56, 0xe1, 0xd2, 0x40, + 0x8b, 0x66, 0xd1, 0x10, 0xed, 0x8c, 0xdb, 0xff, 0x9e, 0x01, 0x81, 0xb8, 0x14, 0x34, 0x17, 0x1d, + 0x34, 0x51, 0xd6, 0x6f, 0x1e, 0x9c, 0xa2, 0xc5, 0x2b, 0xde, 0x9c, 0x2e, 0x6b, 0x47, 0x10, 0x16, + 0xe1, 0x89, 0x7f, 0xf9, 0x4a, 0x7f, 0xc7, 0x70, 0x44, 0x43, 0xfb, 0xdf, 0xe6, 0xde, 0xe4, 0xe6, + 0xbe, 0xdf, 0xbb, 0xed, 0x79, 0x75, 0xaa, 0xe5, 0xad, 0x7e, 0xc8, 0xcc, 0x3b, 0x05, 0x9f, 0x04, + 0x42, 0xc6, 0x7c, 0xd8, 0x7c, 0x2b, 0x82, 0x59, 0xd2, 0xc8, 0x96, 0x6c, 0xcd, 0xd7, 0xdf, 0x18, + 0x22, 0x11, 0x3a, 0x6c, 0x4e, 0x31, 0x4d, 0x52, 0xc0, 0xa1, 0xed, 0x1a, 0x58, 0xe3, 0xae, 0x2f, + 0x8e, 0xbe, 0xdd, 0x92, 0xa0, 0xda, 0x5c, 0x4e, 0x04, 0x01, 0xb0, 0xa2, 0xb1, 0xbf, 0x30, 0x5d, + 0x48, 0x27, 0x24, 0x05, 0xe1, 0x13, 0x97, 0x83, 0x21, 0x75, 0x17, 0x37, 0x48, 0x9b, 0x34, 0xe0, + 0xe5, 0x46, 0xa4, 0x1a, 0x2a, 0x53, 0xfb, 0x7f, 0xc0, 0xc0, 0x37, 0xc6, 0x25, 0xe8, 0xd1, 0xbd, + 0xb6, 0x62, 0x03, 0xba, 0x3c, 0x70, 0x7a, 0xc3, 0x02, 0x28, 0x5e, 0x5e, 0x24, 0x3c, 0xb3, 0xca, + 0x88, 0x01, 0x51, 0x31, 0x61, 0x00, 0xb8, 0x0a, 0x26, 0xe2, 0xf1, 0x4e, 0xca, 0x27, 0x0c, 0x40, + 0x80, 0x4c, 0x5e, 0xb5, 0xfb, 0xa6, 0xf6, 0xfc, 0x18, 0x81, 0x80, 0x69, 0x00, 0x3f, 0x64, 0x03, + 0x48, 0xb0, 0x01, 0x99, 0x08, 0x8f, 0x67, 0x82, 0xc1, 0x50, 0x1e, 0x62, 0xd0, 0x1a, 0x81, 0x89, + 0x01, 0xe5, 0x1c, 0xca, 0x00, 0xf8, 0xc8, 0x1c, 0x02, 0xa0, 0x1d, 0x7c, 0x28, 0xa1, 0x9c, 0x24, + 0x00, 0x02, 0xea, 0xec, 0x00, 0x55, 0x47, 0x01, 0xa9, 0x9e, 0xe0, 0x90, 0x80, 0x01, 0x00, 0x08, + 0xee, 0x14, 0xea, 0x7b, 0x48, 0xdd, 0xb5, 0x77, 0x6c, 0x3b, 0x81, 0x29, 0x04, 0x93, 0x09, 0x65, + 0x5c, 0x0b, 0xb2, 0x7f, 0xaa, 0xe0, 0x01, 0x4e, 0x21, 0x95, 0xce, 0xb7, 0x7f, 0xc6, 0xf8, 0xa8, + 0x37, 0x05, 0x01, 0x53, 0x07, 0x81, 0xed, 0xe7, 0x1a, 0x1c, 0x30, 0xdb, 0x08, 0xc0, 0x90, 0x63, + 0x24, 0xe8, 0xd6, 0x73, 0x22, 0x5e, 0x7a, 0xd3, 0x3b, 0x12, 0xf8, 0x7b, 0x00, 0x86, 0x3e, 0x4c, + 0x39, 0x0d, 0x23, 0x7a, 0xfb, 0x46, 0x54, 0xfc, 0x4e, 0x79, 0x9c, 0xa7, 0xe7, 0x83, 0x41, 0xe3, + 0xf9, 0x31, 0xd1, 0xd4, 0x74, 0x4b, 0x32, 0x47, 0x11, 0xc6, 0x3b, 0x80, 0x24, 0xa0, 0x49, 0x50, + 0xc4, 0x33, 0x2f, 0x2c, 0xe1, 0x8f, 0x71, 0x79, 0x7e, 0x20, 0x22, 0x10, 0xdf, 0x4a, 0xf9, 0x7e, + 0x2b, 0xc2, 0xe4, 0x12, 0x00, 0x68, 0xf5, 0x19, 0xbf, 0x98, 0xaf, 0x72, 0xbe, 0xe3, 0x87, 0x0a, + 0xab, 0x88, 0x6e, 0x46, 0x6e, 0xaa, 0xe1, 0xfa, 0x3a, 0xc4, 0xb8, 0x71, 0x18, 0x00, 0x9f, 0x90, + 0x31, 0x17, 0x73, 0x0b, 0x51, 0xd3, 0xc7, 0xe6, 0x6f, 0xdc, 0x86, 0xf2, 0xd4, 0x5f, 0x0c, 0x5b, + 0x8d, 0x61, 0x87, 0xf1, 0x1f, 0xe9, 0x8a, 0x30, 0x09, 0x18, 0x38, 0x30, 0x6e, 0xff, 0x81, 0x00, + 0x10, 0x07, 0x61, 0xc0, 0xc4, 0x52, 0x4e, 0xdf, 0x00, 0x1e, 0x51, 0x79, 0xb6, 0x8b, 0xb0, 0x3b, + 0x42, 0xc1, 0xc4, 0xf4, 0xf0, 0xc0, 0xf0, 0x0c, 0x14, 0x2f, 0xc9, 0x3b, 0xff, 0xfe, 0x20, 0x40, + 0xf2, 0xe7, 0xc2, 0x90, 0x7b, 0xd6, 0x0d, 0xde, 0xa7, 0x41, 0xa0, 0xf1, 0x11, 0x44, 0x3e, 0x54, + 0x2e, 0x2e, 0x2e, 0xa6, 0xe5, 0xfe, 0x3e, 0x38, 0xac, 0x3f, 0x01, 0xeb, 0x14, 0x33, 0x21, 0xb6, + 0xbd, 0x47, 0x5f, 0x09, 0x93, 0x87, 0x6b, 0x85, 0xe9, 0x5e, 0xc2, 0x30, 0xa6, 0x35, 0x4a, 0x2e, + 0xab, 0x25, 0x7d, 0x7b, 0x6c, 0x48, 0xd8, 0x86, 0x34, 0x9c, 0xb8, 0x40, 0x48, 0x2c, 0x8e, 0x54, + 0x74, 0x30, 0x17, 0xfc, 0x2a, 0xa6, 0x0a, 0x0c, 0xb0, 0x9e, 0x90, 0x92, 0xaf, 0xee, 0xc2, 0xde, + 0x1f, 0x0f, 0x1c, 0x0b, 0x68, 0x98, 0x7b, 0x3e, 0x0b, 0x7f, 0x4b, 0x3b, 0x1d, 0xde, 0x1b, 0xf4, + 0x1d, 0xfd, 0x5f, 0xf8, 0x27, 0xea, 0x5e, 0x87, 0x0a, 0xdc, 0x11, 0xfc, 0x82, 0xaf, 0x7f, 0x29, + 0xcf, 0xef, 0x11, 0xc4, 0x11, 0xa1, 0xdc, 0xd7, 0x29, 0x8c, 0x6c, 0xc9, 0x78, 0x4c, 0x6b, 0x4f, + 0xb5, 0xab, 0xe4, 0x15, 0x37, 0x9b, 0xf8, 0x42, 0xb9, 0x17, 0x55, 0xd5, 0x55, 0x7c, 0xa4, 0xad, + 0x7d, 0x9f, 0x27, 0xb8, 0x60, 0x18, 0x8d, 0x30, 0xf5, 0x28, 0x29, 0x06, 0xfa, 0x1d, 0xfc, 0x8b, + 0x91, 0x98, 0xf4, 0x20, 0x74, 0xba, 0x43, 0xa5, 0xf4, 0x7f, 0xf1, 0x5a, 0xe0, 0xe0, 0x10, 0x07, + 0x8a, 0x17, 0x15, 0x57, 0x4a, 0xf1, 0x89, 0x11, 0xb0, 0xb6, 0xe4, 0xc6, 0x84, 0xe1, 0xc8, 0xf2, + 0xa0, 0xac, 0x0a, 0x84, 0xe6, 0x88, 0x92, 0x01, 0x16, 0x4f, 0x5e, 0x2f, 0x0b, 0xe0, 0x20, 0x2d, + 0x2c, 0x1b, 0x46, 0xec, 0x3a, 0xc2, 0xa1, 0xac, 0x77, 0x4d, 0x5b, 0x03, 0xfd, 0xeb, 0x1b, 0x83, + 0x47, 0xc0, 0xb0, 0x2f, 0xb6, 0xca, 0x86, 0xbc, 0x18, 0x01, 0x87, 0xe1, 0x5c, 0xbd, 0x70, 0xab, + 0x9a, 0x50, 0xba, 0x8a, 0xff, 0xf8, 0x25, 0xe3, 0xab, 0xca, 0x20, 0x75, 0x3e, 0x3d, 0x8f, 0x92, + 0xe3, 0xeb, 0xf1, 0x31, 0xa4, 0x3c, 0x60, 0x58, 0x35, 0x68, 0xa4, 0x07, 0xc4, 0x70, 0x00, 0x7e, + 0x2b, 0xf8, 0x95, 0xd0, 0xcc, 0xb7, 0x0b, 0x0b, 0x2d, 0x8d, 0xa1, 0xf0, 0xf5, 0xdb, 0x00, 0x00, + 0x65, 0x43, 0x46, 0x31, 0xc5, 0x53, 0xca, 0xcc, 0x7f, 0x0b, 0xce, 0x01, 0xfa, 0x44, 0xd0, 0x07, + 0xd1, 0x5d, 0x0f, 0xd4, 0xed, 0x59, 0xee, 0xd4, 0x56, 0x29, 0xe2, 0xbc, 0x56, 0xe1, 0x43, 0xd2, + 0xf9, 0x3f, 0x88, 0x18, 0x4b, 0x95, 0x55, 0x55, 0xc8, 0xba, 0x86, 0xca, 0x06, 0xe1, 0x5a, 0x10, + 0x5f, 0x7d, 0x1b, 0x3d, 0x4b, 0xfb, 0x84, 0x06, 0x77, 0x71, 0xd5, 0x3d, 0x81, 0xcf, 0xb7, 0x63, + 0xf0, 0x8d, 0xfa, 0x22, 0xc6, 0x25, 0xc6, 0xfc, 0x48, 0x81, 0x91, 0x5d, 0xed, 0xad, 0x6d, 0xfd, + 0x59, 0x62, 0x44, 0x04, 0x7b, 0x47, 0x69, 0x90, 0x03, 0xbd, 0x7e, 0x5f, 0x9e, 0x3a, 0x93, 0xdf, + 0xf8, 0x97, 0xa9, 0x2c, 0x22, 0x08, 0x46, 0xdc, 0xc2, 0xfc, 0x3d, 0x97, 0xf7, 0x37, 0x06, 0xd2, + 0xd6, 0xba, 0x94, 0x9d, 0x45, 0x5d, 0x7f, 0xc1, 0x71, 0xd2, 0x51, 0x57, 0xa0, 0xe3, 0x38, 0xd7, + 0x88, 0x8e, 0xee, 0xb5, 0x97, 0x98, 0x8b, 0xa8, 0x43, 0x92, 0xa2, 0xeb, 0xf7, 0xaa, 0xfc, 0xc4, + 0x7b, 0xd4, 0x32, 0x11, 0x21, 0x5c, 0xd8, 0x51, 0xaf, 0x81, 0x20, 0x14, 0x0f, 0xc3, 0x74, 0xfa, + 0x95, 0x37, 0x27, 0xd6, 0xed, 0xc7, 0x2d, 0xc3, 0xac, 0xa0, 0x1b, 0x61, 0xad, 0xc3, 0xf9, 0xe9, + 0x66, 0xa7, 0x0f, 0x7a, 0x8a, 0x76, 0x7e, 0xf6, 0x82, 0x94, 0xdb, 0xd3, 0x4d, 0x94, 0x73, 0x00, + 0x74, 0x84, 0x73, 0x83, 0xb7, 0x37, 0xcd, 0xfe, 0x5e, 0xb0, 0xe6, 0xdf, 0x09, 0x88, 0x47, 0x76, + 0xef, 0x47, 0x0f, 0x31, 0x60, 0x03, 0xe9, 0xd8, 0x96, 0xd4, 0xee, 0xff, 0xb7, 0x2f, 0x6d, 0x20, + 0x3b, 0xff, 0xd1, 0xf0, 0xfd, 0x34, 0xc7, 0x55, 0x9c, 0xe5, 0x42, 0xc5, 0x1f, 0x2f, 0xf5, 0xae, + 0x08, 0x21, 0x41, 0x81, 0x50, 0x01, 0x57, 0xf2, 0xc0, 0x00, 0x9c, 0xa0, 0xb5, 0x06, 0x2f, 0x21, + 0x72, 0x01, 0xe4, 0x2c, 0x30, 0x66, 0x68, 0x60, 0x9e, 0x00, 0x04, 0x78, 0xe9, 0xf2, 0x70, 0x00, + 0x54, 0x77, 0xf8, 0xc5, 0x89, 0x40, 0x75, 0x60, 0x95, 0xa2, 0xb7, 0x0f, 0x8e, 0xf1, 0x30, 0xa1, + 0x4f, 0x3c, 0x5a, 0x93, 0xdb, 0x61, 0x4f, 0x36, 0x66, 0x6f, 0x77, 0xf5, 0xb4, 0x56, 0xad, 0x18, + 0x96, 0x99, 0xc0, 0x4e, 0xfc, 0x7b, 0x98, 0xa9, 0xc5, 0xae, 0xe2, 0x44, 0x85, 0x2f, 0x34, 0x16, + 0x73, 0x6d, 0xc6, 0x2c, 0xc2, 0x72, 0xe0, 0x2f, 0x27, 0x0d, 0x82, 0x73, 0xc9, 0xc8, 0xc3, 0xb5, + 0xd6, 0x73, 0xd4, 0x2c, 0x9c, 0xe6, 0xce, 0x24, 0x48, 0xf3, 0x9b, 0x0e, 0x44, 0xf3, 0x46, 0x78, + 0x93, 0xcd, 0x04, 0xf5, 0x5c, 0x40, 0x80, 0x54, 0x4d, 0xe5, 0x58, 0x78, 0x1e, 0xcf, 0x93, 0x5a, + 0x5d, 0x54, 0xbd, 0xcb, 0xac, 0x71, 0x01, 0x81, 0x98, 0xb5, 0x61, 0x5a, 0xb7, 0x2d, 0x3c, 0x4b, + 0x6d, 0x18, 0xea, 0xf8, 0x2b, 0xe9, 0xa6, 0xe2, 0x4d, 0x3c, 0x8c, 0x35, 0xda, 0xef, 0x13, 0x08, + 0xe2, 0x1d, 0x15, 0x55, 0xf2, 0x9e, 0xb5, 0x5c, 0xc4, 0x55, 0xfc, 0xc5, 0x7d, 0xfc, 0x11, 0x5e, + 0xee, 0xcf, 0x94, 0x41, 0xfa, 0x89, 0x7c, 0x84, 0x39, 0x0e, 0xed, 0x87, 0xe1, 0x02, 0x43, 0xbb, + 0x9f, 0x0f, 0x72, 0xe2, 0xbe, 0xb9, 0x89, 0x58, 0xbf, 0x8c, 0x3c, 0xcc, 0x19, 0x24, 0xe4, 0xea, + 0x5e, 0x2e, 0x23, 0xe4, 0xb3, 0x93, 0xf1, 0x20, 0x80, 0x28, 0x58, 0xac, 0x2a, 0x46, 0x17, 0x98, + 0x84, 0x66, 0x85, 0x75, 0x94, 0xc8, 0x64, 0x8a, 0xc0, 0x9b, 0xcf, 0x1c, 0x7f, 0x7b, 0x3b, 0xfc, + 0x20, 0x42, 0xc4, 0x00, 0xf1, 0x38, 0xf1, 0xee, 0x75, 0xac, 0x84, 0x15, 0x5d, 0xfc, 0x66, 0x66, + 0x5a, 0xd7, 0xb2, 0x3d, 0xcd, 0xa5, 0x55, 0x55, 0xa2, 0xe2, 0x04, 0x0c, 0xe5, 0x20, 0xdc, 0xb1, + 0x8a, 0xda, 0x15, 0xcd, 0xe7, 0xd6, 0x73, 0x95, 0x13, 0x7e, 0x0b, 0x2c, 0x1b, 0x75, 0x77, 0x6e, + 0x5d, 0x83, 0x31, 0x96, 0xe9, 0x3f, 0x13, 0x19, 0xba, 0x6f, 0xbb, 0xa8, 0x3a, 0xb1, 0xb0, 0x56, + 0xc8, 0xdf, 0x26, 0x8b, 0xb6, 0x5c, 0x40, 0xcb, 0x9b, 0x9f, 0x27, 0x3b, 0x8a, 0x7f, 0x22, 0x4b, + 0x59, 0x52, 0x67, 0x12, 0x26, 0x56, 0xd4, 0xb3, 0xab, 0x6a, 0x8d, 0xcc, 0x98, 0xe0, 0x4f, 0x9a, + 0xba, 0x6b, 0x98, 0x8f, 0x77, 0x7c, 0x82, 0xe2, 0xbb, 0xf9, 0x85, 0x3d, 0xeb, 0x10, 0xe7, 0xf6, + 0xa2, 0xf9, 0x66, 0xeb, 0x53, 0xf1, 0x55, 0x14, 0x31, 0x71, 0x4c, 0x5c, 0x5e, 0x2f, 0xe3, 0x8b, + 0xcb, 0x8e, 0xee, 0xc7, 0xde, 0xfc, 0x22, 0x38, 0xb2, 0xf2, 0xb1, 0x77, 0x2e, 0x33, 0x1f, 0x41, + 0xdb, 0xf1, 0x23, 0x0d, 0x4d, 0xa5, 0x9e, 0x1e, 0x7c, 0xbe, 0x6c, 0xf1, 0x85, 0xcf, 0x46, 0x03, + 0xa1, 0x56, 0x6c, 0xb9, 0xbc, 0xac, 0xc1, 0xdc, 0x36, 0x49, 0x2d, 0x67, 0x13, 0x0a, 0x13, 0x93, + 0x4b, 0xfa, 0xe2, 0xf5, 0x2a, 0xaa, 0x8f, 0x31, 0x25, 0xf3, 0xbe, 0x30, 0xcd, 0x88, 0xe0, 0xf4, + 0xa8, 0x71, 0x45, 0xba, 0x19, 0x61, 0x87, 0x88, 0xc9, 0x8b, 0x24, 0xcc, 0x4c, 0x28, 0x2c, 0x92, + 0x20, 0x2e, 0xf0, 0x15, 0x7c, 0x5e, 0x32, 0x9a, 0xec, 0xa2, 0x2f, 0x95, 0x37, 0x3b, 0xeb, 0xe3, + 0x2d, 0xd6, 0xb3, 0xab, 0x2a, 0x95, 0x71, 0x0e, 0x71, 0x03, 0x09, 0x1c, 0xbf, 0x37, 0x5a, 0xca, + 0xc4, 0xe6, 0x13, 0xe6, 0xd6, 0xbe, 0x08, 0xce, 0xb5, 0xbc, 0xdc, 0xa6, 0x73, 0xf7, 0xc2, 0xb8, + 0x91, 0x65, 0xad, 0x6b, 0x17, 0xf0, 0x89, 0x96, 0xb5, 0x57, 0xbb, 0x62, 0x7c, 0xb3, 0x2f, 0x14, + 0x3c, 0x48, 0x90, 0xa7, 0x36, 0x54, 0xbc, 0x5c, 0x5c, 0x5c, 0x4f, 0x24, 0xb0, 0x31, 0x20, 0x68, + 0x17, 0x2a, 0x4c, 0x65, 0x8f, 0x50, 0x15, 0x54, 0x50, 0xa8, 0xcb, 0x82, 0x10, 0xa4, 0x5c, 0x98, + 0x24, 0xe1, 0xe7, 0x19, 0x41, 0xd5, 0xd3, 0x05, 0x71, 0xdc, 0xe0, 0xe1, 0x30, 0x7d, 0xc9, 0xe1, + 0xc8, 0x2c, 0x96, 0x0c, 0xe5, 0x0b, 0xc2, 0x21, 0x48, 0x7e, 0x09, 0x54, 0x30, 0x43, 0x48, 0x1e, + 0xd5, 0x43, 0x30, 0xbf, 0x26, 0x24, 0xbc, 0x33, 0x8b, 0x8b, 0xbb, 0x04, 0x69, 0x01, 0xeb, 0x89, + 0x0c, 0x85, 0x0a, 0x26, 0xa0, 0xfe, 0x37, 0x4b, 0xcb, 0xcf, 0x34, 0x14, 0xcf, 0x03, 0x95, 0x8b, + 0x88, 0x98, 0x92, 0x4c, 0x29, 0x38, 0x1e, 0x48, 0x08, 0xd4, 0xe7, 0x22, 0x70, 0xe2, 0x02, 0x04, + 0x95, 0x3b, 0x92, 0x60, 0x73, 0x06, 0x5f, 0xdd, 0xbc, 0x60, 0xea, 0x46, 0x7f, 0x1f, 0x5a, 0xd6, + 0xb4, 0xdb, 0x44, 0xb8, 0x53, 0x82, 0x21, 0x2b, 0x5e, 0x57, 0xc1, 0x11, 0x35, 0x59, 0x71, 0x3e, + 0x26, 0x5e, 0xab, 0xec, 0x85, 0xee, 0x9b, 0x64, 0xe5, 0x3e, 0xaa, 0x12, 0xc2, 0x23, 0x08, 0x6f, + 0x12, 0x49, 0x49, 0x8b, 0x25, 0x31, 0xee, 0xc9, 0x53, 0xf8, 0x53, 0x13, 0x35, 0x54, 0x6d, 0x64, + 0xad, 0x03, 0x07, 0x60, 0xf9, 0x70, 0x6e, 0x19, 0xc6, 0xfd, 0xc4, 0xc7, 0xc8, 0x4c, 0x3b, 0x59, + 0xa2, 0xf1, 0x82, 0x57, 0x21, 0x6c, 0xc1, 0x3a, 0x0c, 0x65, 0x4a, 0x90, 0x20, 0xc6, 0x18, 0xef, + 0xc6, 0x69, 0x65, 0x83, 0xcf, 0xb6, 0xfe, 0x24, 0x2c, 0x22, 0x0d, 0x92, 0xc2, 0xbb, 0xc4, 0x07, + 0x77, 0x3f, 0x4d, 0xda, 0x5c, 0x20, 0x55, 0x69, 0xaa, 0xb5, 0xb6, 0xed, 0xc2, 0x5c, 0xa5, 0x5a, + 0xcd, 0x11, 0x21, 0x1e, 0xee, 0x6e, 0x10, 0x9b, 0x97, 0xb7, 0x37, 0x4e, 0xfb, 0xb8, 0xee, 0x6d, + 0x6a, 0x5e, 0x4c, 0xf9, 0xac, 0x40, 0x2e, 0x3b, 0xb5, 0xe9, 0x12, 0x81, 0xbd, 0xd2, 0x20, 0xbe, + 0x10, 0x23, 0x8f, 0xb8, 0x6c, 0x66, 0x2b, 0xb9, 0x78, 0xaf, 0x3e, 0xf8, 0x29, 0xb9, 0x51, 0x0c, + 0x9e, 0x5b, 0x03, 0x40, 0x1f, 0x6c, 0x4d, 0x8d, 0x54, 0xa6, 0x9c, 0xf8, 0x8b, 0x91, 0xf9, 0x06, + 0x1c, 0x66, 0x9c, 0x25, 0xc9, 0x5a, 0xcf, 0xc1, 0x71, 0x26, 0xf9, 0xba, 0xfd, 0x2e, 0x22, 0x3f, + 0x8a, 0xdd, 0xde, 0xef, 0xf3, 0x15, 0xdf, 0x2f, 0x21, 0x5a, 0x7f, 0xc9, 0x5d, 0xdf, 0xd8, 0x8b, + 0x6d, 0xfd, 0x95, 0x57, 0x0a, 0x72, 0x5e, 0xf0, 0x08, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x4a, 0x25, 0x32, 0x8b, 0xc4, 0x1a, 0x2f, 0xad, 0x60, 0xf6, 0x26, 0xee, 0xbe, 0x26, 0x09, 0xe6, + 0xe9, 0xef, 0x7b, 0xfc, 0x12, 0x46, 0x57, 0x6f, 0xbc, 0x18, 0x71, 0x1a, 0xd7, 0x55, 0xf1, 0x7d, + 0x54, 0x5d, 0x56, 0xa2, 0x62, 0x2f, 0x73, 0xf6, 0xf1, 0x27, 0xe2, 0x2b, 0x5d, 0xed, 0x78, 0x8b, + 0x88, 0x7d, 0xdb, 0xdf, 0x7c, 0x4c, 0x23, 0x88, 0x7d, 0xdf, 0x7b, 0xd3, 0x51, 0x3a, 0xe0, 0xae, + 0xdd, 0xbc, 0xa4, 0x17, 0xb1, 0x9a, 0xbb, 0x66, 0xd0, 0x4b, 0xca, 0x4b, 0xa6, 0xe2, 0xb8, 0xa2, + 0xd3, 0xab, 0x2a, 0xfd, 0x95, 0x74, 0xd7, 0x15, 0x9e, 0x08, 0xb9, 0x3d, 0x2c, 0x44, 0xb7, 0xd1, + 0xae, 0x61, 0x7a, 0xa5, 0xe4, 0x1c, 0xef, 0x3e, 0x79, 0x88, 0xe7, 0xa7, 0x89, 0xf8, 0x45, 0x04, + 0xdb, 0xc2, 0x25, 0x36, 0x99, 0x70, 0x10, 0xf6, 0x21, 0xc5, 0x7a, 0xe2, 0x7a, 0x4a, 0xf7, 0x77, + 0xd1, 0xe2, 0x97, 0x82, 0x32, 0x2a, 0x62, 0x4e, 0x49, 0x56, 0x09, 0xc1, 0x15, 0x6a, 0xaf, 0xf1, + 0x76, 0xa9, 0x6a, 0x97, 0x13, 0x04, 0x27, 0xbb, 0xfa, 0xf9, 0x86, 0x28, 0xa7, 0xe2, 0x44, 0x16, + 0xe7, 0x63, 0xc4, 0xe2, 0x79, 0x8a, 0xf5, 0x15, 0x86, 0xfb, 0x2a, 0x75, 0xae, 0x4a, 0x9b, 0x72, + 0xc4, 0x08, 0x05, 0x64, 0x88, 0x90, 0x5a, 0x99, 0x20, 0xa5, 0xeb, 0x5f, 0x57, 0x16, 0x54, 0x3b, + 0xa2, 0x19, 0x41, 0x47, 0x1f, 0xdd, 0xed, 0xf8, 0x91, 0x44, 0xad, 0x29, 0xf6, 0xbe, 0x3a, 0xed, + 0x9e, 0x52, 0xaa, 0xab, 0x2b, 0x4f, 0xc6, 0x66, 0xcd, 0x54, 0xcc, 0x62, 0xad, 0x3e, 0x96, 0xaf, + 0x82, 0x81, 0x3b, 0x8c, 0x88, 0x16, 0xdc, 0x06, 0xde, 0x4f, 0xe2, 0x02, 0x23, 0x38, 0x6d, 0xfb, + 0x6e, 0x17, 0x1e, 0xda, 0x41, 0xf8, 0x99, 0x83, 0x04, 0x09, 0x81, 0xf3, 0x5f, 0xff, 0xd3, 0x4f, + 0xb3, 0xca, 0x08, 0x0e, 0x39, 0x94, 0x5a, 0x09, 0xc4, 0xa4, 0x38, 0xe1, 0xc4, 0x08, 0x00, 0x01, + 0xe6, 0x89, 0x91, 0xa6, 0x8c, 0x5c, 0xb3, 0xff, 0xff, 0x92, 0x82, 0xa9, 0x7a, 0x51, 0xbb, 0xfe, + 0x5c, 0x26, 0xfd, 0x78, 0x75, 0xc0, 0x09, 0x86, 0x47, 0x3f, 0x2b, 0x0b, 0x5b, 0x1e, 0xe3, 0x7f, + 0xf6, 0x0e, 0x9f, 0x46, 0x1f, 0x1e, 0x62, 0x0b, 0xc4, 0x90, 0x28, 0xc8, 0x1d, 0xa1, 0xaa, 0x6a, + 0x78, 0x1f, 0x83, 0x15, 0xc3, 0x83, 0xb9, 0xbb, 0x31, 0xf6, 0xfe, 0x13, 0x05, 0x81, 0xf0, 0x3f, + 0xe8, 0x63, 0xb7, 0x5b, 0xcc, 0xc9, 0x33, 0x7a, 0x7e, 0x18, 0xe2, 0x78, 0x16, 0x72, 0x28, 0xa5, + 0x65, 0x44, 0x01, 0xef, 0x00, 0xe9, 0x2f, 0xe0, 0x7b, 0xf9, 0x77, 0x05, 0x3a, 0x0b, 0xf4, 0xbc, + 0xc1, 0xab, 0xdf, 0xc4, 0xf7, 0x77, 0x77, 0xbe, 0x5d, 0x6b, 0xe1, 0x1e, 0xef, 0x55, 0xde, 0xfe, + 0x12, 0xc5, 0xf7, 0xbf, 0x88, 0x0a, 0x14, 0x98, 0x77, 0x0f, 0x4a, 0x32, 0x5c, 0x44, 0xc0, 0x3b, + 0x52, 0x62, 0x4b, 0x90, 0xdf, 0x71, 0x10, 0x53, 0xd4, 0x5e, 0xeb, 0x5b, 0x0c, 0x7a, 0xe2, 0x23, + 0xb7, 0x43, 0x2b, 0x0f, 0xbd, 0x19, 0x3f, 0xe2, 0x34, 0xd9, 0x3b, 0x55, 0xe2, 0x61, 0x23, 0x23, + 0xad, 0x12, 0xab, 0x02, 0xf1, 0x3c, 0x90, 0x5b, 0x4d, 0x2f, 0x90, 0xaa, 0xbf, 0x84, 0x49, 0x26, + 0x2f, 0x5a, 0xad, 0x7e, 0x42, 0xb9, 0x23, 0xc3, 0x0a, 0x85, 0x96, 0x50, 0x66, 0xba, 0x03, 0xd6, + 0xf3, 0x2b, 0xe2, 0x7f, 0xff, 0xbe, 0xef, 0xca, 0xbc, 0x21, 0x90, 0x28, 0x48, 0x00, 0x23, 0x44, + 0x3e, 0x71, 0x15, 0xdd, 0xef, 0x6b, 0x9c, 0xff, 0xff, 0x82, 0xe5, 0x0c, 0x1c, 0x97, 0x28, 0x42, + 0x58, 0x69, 0x18, 0x00, 0x2e, 0x0e, 0x7e, 0x0b, 0xbd, 0x4a, 0x51, 0x8e, 0x4b, 0xe6, 0xdb, 0x6c, + 0x07, 0x72, 0x43, 0x6d, 0xa1, 0x60, 0x0e, 0xc0, 0x29, 0x2b, 0x01, 0x70, 0x2d, 0xb1, 0xa5, 0x3a, + 0xeb, 0xac, 0xb5, 0x8a, 0xb1, 0x57, 0xdc, 0x1c, 0x00, 0x48, 0x06, 0xc1, 0xcd, 0x82, 0x94, 0xc4, + 0x00, 0x3f, 0x07, 0xe0, 0x35, 0x48, 0x98, 0x70, 0x39, 0x61, 0xc7, 0x00, 0x0d, 0x47, 0x40, 0x78, + 0x78, 0xd1, 0xf4, 0x2c, 0x06, 0x24, 0x73, 0x2e, 0x03, 0x8a, 0x00, 0xd2, 0x00, 0x62, 0xb8, 0xff, + 0x62, 0x9c, 0x63, 0xbc, 0x04, 0x08, 0x08, 0x11, 0xa7, 0x3f, 0x9e, 0x3f, 0x51, 0x70, 0xb8, 0x15, + 0x3c, 0x78, 0x2f, 0x7f, 0x1c, 0x00, 0x04, 0x68, 0x14, 0x70, 0x35, 0x15, 0x0f, 0x5a, 0x60, 0x0f, + 0xf1, 0x03, 0xb5, 0x2a, 0x37, 0x80, 0x90, 0x04, 0xa2, 0x41, 0x34, 0xc5, 0x60, 0xc5, 0xf5, 0x6d, + 0x93, 0x83, 0xcb, 0x97, 0x78, 0x08, 0x10, 0x08, 0x08, 0x50, 0xce, 0xe5, 0x44, 0x59, 0x0e, 0x96, + 0x6a, 0x6c, 0x14, 0x20, 0x99, 0x47, 0x1c, 0xdd, 0x48, 0x51, 0xc5, 0xd4, 0x59, 0x6a, 0x74, 0xea, + 0x1c, 0x50, 0x01, 0x94, 0x52, 0xfa, 0xdc, 0xcf, 0xfb, 0xfd, 0x22, 0x6e, 0x2d, 0x83, 0x4e, 0xbe, + 0xfe, 0xdf, 0x4f, 0x01, 0xc2, 0x05, 0x11, 0xbc, 0x28, 0x2a, 0xa5, 0x49, 0xa9, 0x60, 0x0c, 0x9c, + 0x1d, 0x0e, 0x00, 0x02, 0x38, 0x70, 0x00, 0x13, 0xc2, 0x50, 0xb4, 0x07, 0x69, 0x6c, 0x9b, 0x68, + 0x70, 0x71, 0x55, 0x10, 0x00, 0x1b, 0xaa, 0x44, 0x15, 0x63, 0x50, 0xd8, 0x70, 0xd9, 0xd6, 0xdb, + 0xfe, 0x04, 0x98, 0xd8, 0xe1, 0x04, 0xe7, 0x07, 0x07, 0x20, 0x0b, 0xc6, 0x70, 0x70, 0x48, 0x69, + 0x66, 0x91, 0xa9, 0xc0, 0x07, 0xb1, 0x97, 0x40, 0x1a, 0x85, 0x7a, 0xc2, 0xc1, 0x9c, 0x00, 0xf2, + 0xc0, 0x67, 0x00, 0x0f, 0x07, 0x17, 0x10, 0x8d, 0x3c, 0xfd, 0xef, 0x2f, 0x4e, 0x1e, 0xc0, 0x05, + 0xa1, 0x3a, 0x99, 0xde, 0x86, 0x5d, 0xed, 0xff, 0x08, 0x07, 0x43, 0xff, 0x2d, 0x02, 0xb8, 0x99, + 0x2f, 0x6c, 0xa0, 0x96, 0x83, 0x80, 0xee, 0x5a, 0xeb, 0x07, 0x6b, 0x1d, 0x75, 0x99, 0x00, 0x7f, + 0xd2, 0xbf, 0xd6, 0x2d, 0x63, 0x40, 0x37, 0x83, 0xb7, 0x12, 0xa5, 0xe3, 0x7f, 0xf0, 0xd9, 0x78, + 0x3f, 0xd7, 0x9d, 0x04, 0x58, 0x7e, 0xbb, 0xb0, 0xc7, 0x17, 0xad, 0x55, 0x57, 0xe5, 0xbe, 0xfe, + 0x2b, 0x7b, 0xbc, 0x56, 0xef, 0x93, 0x55, 0xf8, 0xce, 0x4c, 0xc0, 0x7f, 0x2f, 0x34, 0xe5, 0x6a, + 0x23, 0x25, 0xcb, 0xd3, 0xdf, 0x89, 0x82, 0xdb, 0xef, 0x75, 0x60, 0xcf, 0x7c, 0x5d, 0x74, 0xb3, + 0x6f, 0xcb, 0x93, 0x17, 0x5d, 0xc9, 0xfd, 0x73, 0x55, 0x55, 0x5f, 0x2f, 0x3b, 0x2e, 0x50, 0xf6, + 0x00, 0x18, 0x83, 0xc8, 0xde, 0x2d, 0x54, 0x13, 0xf3, 0xa6, 0x9a, 0x79, 0x66, 0x98, 0xdf, 0x6f, + 0x6e, 0xd3, 0x71, 0x03, 0xd0, 0xb6, 0x2a, 0xe4, 0xf4, 0xd3, 0xe1, 0xa2, 0x1c, 0x00, 0x33, 0x8e, + 0xd1, 0xb4, 0x61, 0x8d, 0xd5, 0xff, 0x9b, 0x07, 0x7f, 0x5b, 0x3f, 0xa6, 0x4e, 0xce, 0xcf, 0x1a, + 0x69, 0xa6, 0x9e, 0x47, 0x07, 0xc0, 0xe0, 0x36, 0x05, 0xd6, 0x0d, 0x72, 0xe6, 0x4e, 0x21, 0x01, + 0x1e, 0xe0, 0xa6, 0x96, 0x14, 0x37, 0xda, 0xe5, 0x2c, 0x76, 0x2a, 0x95, 0xb3, 0xc3, 0x82, 0xe7, + 0x1c, 0x1f, 0x1a, 0x00, 0x02, 0x01, 0x2b, 0xec, 0xdb, 0x7c, 0x1c, 0x01, 0x00, 0x28, 0x6f, 0x88, + 0x43, 0x9d, 0x49, 0x0b, 0x96, 0x32, 0xdd, 0xdb, 0x12, 0x7a, 0x9e, 0x1e, 0x38, 0x18, 0xc0, 0x00, + 0x3e, 0xb0, 0x14, 0x20, 0xa4, 0x6c, 0xb7, 0x62, 0x80, 0xc4, 0x0e, 0x04, 0x7e, 0xe0, 0xb7, 0xae, + 0x41, 0x16, 0x00, 0x0c, 0xb0, 0x06, 0x58, 0x00, 0x11, 0x8a, 0x00, 0x32, 0xc1, 0xb6, 0x17, 0x15, + 0x3f, 0xc2, 0xe3, 0xc0, 0x79, 0x0f, 0x2c, 0x1e, 0x4e, 0x27, 0xfc, 0x14, 0x83, 0x11, 0xb1, 0x58, + 0xad, 0x37, 0x15, 0x8a, 0xdc, 0x56, 0x05, 0x7d, 0xa8, 0x2d, 0x4f, 0x0e, 0x16, 0x51, 0xb3, 0x1e, + 0xf0, 0x40, 0xe2, 0xe0, 0xcd, 0xd5, 0xe0, 0xd7, 0xe8, 0xf0, 0xc8, 0x90, 0xa4, 0x51, 0x9c, 0xe1, + 0xf0, 0xe7, 0x9c, 0x38, 0xcc, 0xd0, 0x8f, 0x01, 0x20, 0x96, 0x03, 0x0e, 0x34, 0x1c, 0x03, 0x43, + 0x80, 0x1c, 0x2c, 0x06, 0x70, 0x00, 0xb0, 0x78, 0x03, 0xcb, 0x06, 0x78, 0xe0, 0xf8, 0xc1, 0xe0, + 0x22, 0x40, 0xc2, 0x14, 0x99, 0x08, 0x0f, 0x59, 0x74, 0xad, 0x93, 0xbe, 0xe8, 0x47, 0x8f, 0xb3, + 0xc0, 0x60, 0x4e, 0xa0, 0x3d, 0xf9, 0x63, 0x70, 0x7b, 0xe9, 0x40, 0x1f, 0x6a, 0x70, 0xfc, 0x07, + 0x08, 0x1c, 0x42, 0x9f, 0x2e, 0x39, 0x6c, 0xb1, 0x88, 0x07, 0x0b, 0xd6, 0xe0, 0xf6, 0x01, 0xbe, + 0xa5, 0xc4, 0xc0, 0x0d, 0x0e, 0x00, 0x1c, 0x50, 0x66, 0x31, 0xd0, 0x78, 0x68, 0x21, 0xc3, 0xd8, + 0x01, 0x2f, 0xc9, 0x22, 0x1d, 0x2a, 0x38, 0x31, 0x6d, 0x16, 0xd9, 0x5b, 0x39, 0xf5, 0x2d, 0x0f, + 0x34, 0x8c, 0x7f, 0xdd, 0xf1, 0xe7, 0xce, 0x3c, 0x1e, 0x7e, 0x41, 0x38, 0x18, 0xc9, 0x45, 0x5d, + 0x61, 0x86, 0xcf, 0x9c, 0xb0, 0xc2, 0xbc, 0xdb, 0xdf, 0xcb, 0x77, 0x7f, 0x93, 0x77, 0xf9, 0xaa, + 0xab, 0xf0, 0x9d, 0xdf, 0xbb, 0xfc, 0x24, 0x5b, 0xdd, 0xec, 0x72, 0x72, 0x92, 0xeb, 0xf1, 0x19, + 0x29, 0x93, 0x35, 0xf7, 0x57, 0xbf, 0x8b, 0x8d, 0xf3, 0x9f, 0x55, 0xe5, 0x32, 0x31, 0x8f, 0x13, + 0xdd, 0xf7, 0x67, 0x89, 0x1f, 0x89, 0xe5, 0x41, 0xdb, 0x0b, 0x65, 0xe9, 0x0e, 0x32, 0x97, 0xa8, + 0xbf, 0x96, 0x4f, 0x2c, 0x03, 0x0b, 0x57, 0xc2, 0x25, 0x27, 0x95, 0x5a, 0xb4, 0xab, 0x53, 0x67, + 0x8b, 0x22, 0xe5, 0xac, 0x7b, 0x25, 0xda, 0x78, 0xae, 0x66, 0xb6, 0x56, 0x25, 0xd8, 0xfc, 0x4d, + 0x39, 0x60, 0x9d, 0xc6, 0xcc, 0x6a, 0x26, 0x1c, 0x2e, 0xd0, 0x1c, 0x72, 0x50, 0x0e, 0x0a, 0x57, + 0x15, 0x7f, 0x81, 0xa0, 0x48, 0x2d, 0xac, 0xcc, 0x3b, 0x54, 0xc0, 0x54, 0xf3, 0x1c, 0x44, 0x10, + 0x77, 0x0a, 0x02, 0xb9, 0xb1, 0xc4, 0x3c, 0xe0, 0x00, 0x79, 0xc3, 0xce, 0x00, 0x02, 0x3c, 0x4f, + 0x8d, 0x63, 0x92, 0xbf, 0x01, 0x60, 0x03, 0x20, 0x6c, 0x16, 0x20, 0x01, 0x71, 0x4a, 0x52, 0xc2, + 0x6e, 0x70, 0xf2, 0xc1, 0x8a, 0x00, 0xcf, 0x07, 0x0f, 0x1c, 0x1c, 0x24, 0xf9, 0x50, 0x88, 0xb5, + 0x29, 0x7a, 0x8a, 0x62, 0x64, 0x18, 0xc0, 0x00, 0x20, 0x17, 0xfd, 0xb6, 0xd7, 0x0c, 0xc4, 0x80, + 0x8b, 0x3b, 0x62, 0xce, 0xae, 0xef, 0xd3, 0xa7, 0xfe, 0xf8, 0xc2, 0x40, 0x41, 0x99, 0x00, 0x18, + 0x5e, 0x76, 0x1c, 0x21, 0x00, 0x08, 0x0f, 0x9a, 0x4c, 0xc1, 0x0f, 0xfb, 0x6f, 0x7b, 0xfb, 0x62, + 0x5f, 0x12, 0x3c, 0x76, 0x37, 0xfe, 0xf0, 0xf1, 0x0c, 0x00, 0x52, 0xce, 0x07, 0x08, 0x88, 0x5f, + 0x17, 0xd9, 0x6f, 0x2c, 0xea, 0x77, 0xdf, 0xf8, 0x00, 0x00, 0x04, 0xc2, 0x5e, 0x02, 0x35, 0x61, + 0xe0, 0xc7, 0xee, 0xd7, 0x04, 0x11, 0x9b, 0x15, 0x96, 0x0c, 0x48, 0xe1, 0x63, 0x4c, 0xa6, 0x9f, + 0x79, 0xf0, 0x9f, 0xc4, 0xa3, 0xa6, 0x84, 0x30, 0x11, 0xe7, 0x02, 0xbb, 0x89, 0x98, 0x02, 0xfe, + 0xf0, 0xa1, 0x2d, 0xf7, 0x6b, 0x11, 0x58, 0xba, 0x87, 0x03, 0x4a, 0xa1, 0x82, 0x15, 0xb4, 0x10, + 0x83, 0x52, 0xe4, 0xaa, 0x81, 0xd8, 0x95, 0x32, 0x86, 0xd1, 0xc0, 0x0a, 0x9c, 0x7a, 0x60, 0x2e, + 0xe8, 0xa0, 0x87, 0xd8, 0x3b, 0xc2, 0x0e, 0xb8, 0x32, 0x67, 0xa5, 0x22, 0x7c, 0x77, 0x81, 0x44, + 0xa8, 0xf8, 0xd2, 0x17, 0xa4, 0x2e, 0x1b, 0x50, 0x70, 0x9d, 0x56, 0xda, 0x65, 0xea, 0xa5, 0x70, + 0x09, 0x00, 0x12, 0x06, 0x90, 0xa0, 0x3d, 0x6a, 0x82, 0x2a, 0x71, 0x54, 0xd4, 0x8e, 0x4b, 0x78, + 0x3c, 0x51, 0xf2, 0x53, 0x2a, 0x35, 0xca, 0xb1, 0x21, 0xc0, 0x38, 0xc4, 0xa7, 0x03, 0x85, 0x80, + 0x30, 0xb0, 0x3b, 0xd0, 0x4a, 0x00, 0xf8, 0x3f, 0xa0, 0x80, 0x51, 0x5b, 0xcb, 0xc1, 0x85, 0xf5, + 0x74, 0xf0, 0xcc, 0x6c, 0x8a, 0x00, 0x04, 0x51, 0xb0, 0x05, 0x98, 0x3c, 0x3c, 0x45, 0x84, 0x26, + 0x0f, 0xb8, 0x01, 0x7c, 0xa3, 0x80, 0x1a, 0x85, 0xad, 0x78, 0x09, 0x29, 0x87, 0x10, 0xb1, 0x98, + 0x77, 0x37, 0x1e, 0x2c, 0x1c, 0x85, 0x87, 0x38, 0x70, 0xe2, 0x34, 0xc1, 0xff, 0x67, 0xb6, 0x5a, + 0xe9, 0xa7, 0x0e, 0x28, 0x00, 0x15, 0xb1, 0xd9, 0x74, 0xf2, 0x2d, 0x76, 0xea, 0xa9, 0x93, 0xfd, + 0xb7, 0xf6, 0xeb, 0x1e, 0x44, 0x19, 0x8e, 0xf3, 0x2b, 0xdb, 0x6a, 0x1b, 0x8f, 0xc3, 0x65, 0x35, + 0xc3, 0x93, 0x01, 0xab, 0x25, 0xa1, 0x2c, 0x96, 0x1a, 0x47, 0xe5, 0x44, 0xbb, 0x0b, 0xf2, 0x11, + 0xdd, 0xfe, 0xef, 0x7b, 0xe4, 0xaa, 0xfe, 0xea, 0xba, 0xe4, 0xaa, 0x76, 0x37, 0x13, 0xfb, 0xa8, + 0xf5, 0x9f, 0xb1, 0x7b, 0x4d, 0x2e, 0x28, 0x63, 0x24, 0xdb, 0x63, 0xbd, 0xfd, 0x95, 0x7d, 0x37, + 0xb3, 0x84, 0x88, 0x2c, 0x15, 0x4d, 0x64, 0x9f, 0x58, 0xd2, 0x47, 0xc3, 0x8a, 0x01, 0xf3, 0xd5, + 0xcb, 0xff, 0xd3, 0xd3, 0x4e, 0xbe, 0xd7, 0x6e, 0x1c, 0x50, 0xb6, 0x38, 0x0b, 0xff, 0xfd, 0x3c, + 0x3c, 0xd5, 0xd3, 0x19, 0xd2, 0x1b, 0x42, 0x00, 0x0a, 0x7e, 0x9d, 0x3d, 0x11, 0x89, 0x23, 0x13, + 0xea, 0x46, 0x25, 0x45, 0x19, 0xf4, 0xd3, 0x12, 0xe5, 0x59, 0x6d, 0xbe, 0x34, 0xe1, 0xb2, 0x40, + 0x15, 0xf7, 0xe4, 0x8e, 0x18, 0xd8, 0x53, 0x3c, 0x7e, 0xe2, 0x7c, 0x56, 0x4b, 0xeb, 0xd7, 0x3a, + 0x56, 0xbf, 0x8b, 0x20, 0x90, 0x11, 0x0e, 0x60, 0xcc, 0xfe, 0x3d, 0x87, 0x11, 0x80, 0x1f, 0xf8, + 0x86, 0x9f, 0xf7, 0xf6, 0xfd, 0xb6, 0xd3, 0x10, 0xf4, 0x09, 0x6f, 0xe0, 0xc1, 0xfa, 0x1e, 0x21, + 0x80, 0x00, 0xb1, 0x46, 0x45, 0xa5, 0x05, 0xb5, 0x99, 0x75, 0x36, 0xc1, 0xd7, 0xc6, 0x7e, 0x38, + 0x3f, 0xbf, 0xe2, 0x5e, 0xfc, 0x8e, 0x32, 0xec, 0x9d, 0x32, 0xec, 0x35, 0x48, 0x28, 0x7e, 0xc3, + 0x6e, 0x3a, 0x6c, 0xa2, 0x64, 0xb2, 0xc5, 0xbe, 0xe1, 0xd6, 0x50, 0x02, 0x38, 0x66, 0x46, 0x0c, + 0x27, 0xde, 0xb3, 0x6e, 0xb8, 0xad, 0xdf, 0x8b, 0x62, 0x96, 0x5c, 0x8c, 0xb2, 0xc5, 0x2d, 0x0d, + 0x85, 0x3b, 0x0d, 0x6d, 0xd2, 0x59, 0xf1, 0x01, 0x43, 0x33, 0x22, 0xc5, 0x78, 0x55, 0xf5, 0x3e, + 0x75, 0x3b, 0xbe, 0xd2, 0x55, 0x6e, 0x19, 0x08, 0x85, 0x2a, 0x00, 0x35, 0xc6, 0xac, 0x3b, 0xf8, + 0x5b, 0xea, 0x5e, 0xc7, 0xdc, 0x68, 0xc1, 0x85, 0x36, 0xb9, 0x79, 0x3f, 0x26, 0x11, 0x66, 0x68, + 0xfc, 0x38, 0x48, 0x00, 0xdb, 0x1a, 0x46, 0x99, 0x0e, 0x2e, 0xb1, 0x8b, 0x31, 0x3f, 0x14, 0x4e, + 0x19, 0xee, 0x93, 0xbc, 0x78, 0x3a, 0x1d, 0x1d, 0x57, 0x61, 0x99, 0xb0, 0xe3, 0xd9, 0xde, 0xf1, + 0x72, 0xf1, 0x59, 0xa9, 0xa6, 0xd9, 0xfe, 0xb6, 0xf8, 0x18, 0x00, 0x48, 0x8d, 0x8e, 0xbd, 0x25, + 0x0e, 0x5c, 0x97, 0x44, 0x26, 0x5e, 0x18, 0x2c, 0xbe, 0x2e, 0xa2, 0x67, 0x38, 0x7a, 0x8c, 0x8e, + 0x1e, 0x70, 0x0e, 0x1e, 0xf2, 0xc0, 0x06, 0x70, 0x00, 0xe0, 0xd0, 0xc3, 0x07, 0x2b, 0x46, 0x17, + 0x65, 0xde, 0x0e, 0xd6, 0x50, 0x9f, 0x2f, 0x83, 0x80, 0x12, 0x23, 0x61, 0xd0, 0xd7, 0xc1, 0x70, + 0x18, 0x5c, 0x44, 0x2f, 0x5f, 0x3b, 0x07, 0xfd, 0xd0, 0x00, 0x27, 0xf1, 0xc0, 0x00, 0x4f, 0xbc, + 0xcc, 0x68, 0x28, 0x7a, 0x0f, 0xc9, 0xaa, 0xcc, 0xcd, 0x04, 0xf2, 0xd8, 0xe4, 0x15, 0xb5, 0xa5, + 0x79, 0x2e, 0x0c, 0x00, 0xa0, 0x82, 0x42, 0x83, 0x3f, 0xcc, 0x1a, 0x74, 0x0a, 0x7a, 0xb7, 0xd1, + 0xbf, 0x01, 0x32, 0x0c, 0x42, 0x97, 0x10, 0x38, 0x73, 0xcb, 0x1a, 0xb5, 0xcb, 0x06, 0x2b, 0x22, + 0xa4, 0x58, 0x78, 0x05, 0x89, 0xc0, 0xc2, 0xa1, 0x9e, 0xa5, 0x83, 0x14, 0x06, 0x58, 0x0c, 0x2c, + 0x00, 0xaa, 0x27, 0x50, 0xec, 0xa0, 0x06, 0x56, 0x94, 0x79, 0x60, 0x85, 0xc7, 0xed, 0x34, 0xf8, + 0x87, 0xa9, 0x7d, 0xbd, 0xfb, 0x8d, 0x44, 0x60, 0x43, 0x6f, 0x86, 0x1b, 0x3e, 0x2f, 0x27, 0x0e, + 0x03, 0x9c, 0x92, 0x28, 0x26, 0x6a, 0x22, 0x09, 0x25, 0x6f, 0xe9, 0x79, 0x0f, 0x7b, 0x4f, 0x98, + 0x52, 0x7b, 0xc3, 0x88, 0x48, 0x04, 0xd3, 0xc8, 0x80, 0x0e, 0xb4, 0x9a, 0x7a, 0x69, 0xfa, 0x69, + 0x8e, 0x2b, 0xb5, 0x9b, 0x18, 0xe2, 0x41, 0x00, 0xd2, 0x66, 0xdb, 0xe9, 0xc3, 0x8a, 0x00, 0x71, + 0xaa, 0x0e, 0x1c, 0x67, 0xff, 0x6f, 0x6d, 0xb3, 0xa5, 0xb1, 0x57, 0x4d, 0x34, 0xf8, 0x85, 0x01, + 0xfe, 0x2a, 0xe2, 0x18, 0x50, 0x21, 0x56, 0xd1, 0xd7, 0x1d, 0xb6, 0xed, 0xb6, 0xdf, 0xf9, 0xd3, + 0x0e, 0x28, 0x01, 0xa0, 0x32, 0xee, 0xf9, 0xfa, 0x7d, 0xb6, 0xfd, 0x24, 0xbd, 0x5b, 0x6f, 0xfc, + 0x05, 0x88, 0x12, 0x46, 0x90, 0x0e, 0xed, 0x5f, 0x69, 0x63, 0x3f, 0x43, 0xdb, 0x3c, 0x28, 0xf2, + 0xd5, 0x53, 0xe3, 0xc3, 0x8e, 0xc6, 0x0c, 0x7a, 0xa3, 0x58, 0x18, 0x1a, 0x2f, 0xb6, 0x28, 0xbf, + 0x01, 0x40, 0x04, 0x81, 0xa5, 0xce, 0x07, 0x27, 0xca, 0xee, 0x15, 0x7d, 0x7a, 0xe2, 0x38, 0x29, + 0xe4, 0x37, 0xcf, 0x06, 0xba, 0xd5, 0x5f, 0x01, 0x02, 0x0a, 0x41, 0x4c, 0x0f, 0xcd, 0x4b, 0x59, + 0x54, 0xd7, 0x46, 0x4c, 0xcb, 0x06, 0xe7, 0xcc, 0xec, 0x62, 0xbc, 0x29, 0x2f, 0x1a, 0x53, 0xfb, + 0x3b, 0x87, 0x1c, 0xb3, 0x9c, 0x77, 0xdd, 0xf8, 0xb3, 0x4a, 0xf1, 0x22, 0x02, 0x9b, 0x4b, 0x74, + 0xc9, 0x81, 0x45, 0x4f, 0x78, 0xa3, 0x77, 0x72, 0xdb, 0xfd, 0x59, 0xc3, 0x01, 0x10, 0xa1, 0x0f, + 0xc5, 0xec, 0x47, 0x23, 0x10, 0xe4, 0x64, 0x80, 0xa0, 0x3f, 0x8e, 0xd6, 0x60, 0x72, 0x9a, 0xd4, + 0x3b, 0xe0, 0x7e, 0x6b, 0x14, 0x58, 0x71, 0x40, 0x03, 0x5a, 0xd0, 0xdb, 0xe7, 0xcf, 0xbf, 0xfe, + 0xfc, 0xdc, 0x75, 0x78, 0x3b, 0x7a, 0x7a, 0x65, 0xde, 0x54, 0xd3, 0xed, 0xfc, 0x22, 0x36, 0x80, + 0x94, 0x99, 0xe6, 0x96, 0x86, 0x8c, 0xc6, 0xb2, 0xcd, 0x70, 0x25, 0x10, 0x57, 0x4f, 0x0d, 0x48, + 0x74, 0x8a, 0x1c, 0x15, 0x55, 0xde, 0x68, 0x00, 0x31, 0x36, 0xaf, 0x48, 0x60, 0x76, 0xe0, 0xe6, + 0xa7, 0x3f, 0x66, 0x6f, 0x55, 0x86, 0x70, 0x02, 0x7d, 0xc6, 0x57, 0xc1, 0xc3, 0x28, 0xbb, 0x7d, + 0xbd, 0xbd, 0x38, 0xf9, 0x27, 0xd3, 0x4e, 0x77, 0x10, 0x0e, 0x02, 0x95, 0x68, 0xff, 0x23, 0x04, + 0xa5, 0xac, 0x98, 0xa8, 0xaf, 0x54, 0xf0, 0x3d, 0x4a, 0x0e, 0x83, 0x24, 0xd4, 0x18, 0xea, 0x78, + 0x01, 0xe7, 0xbc, 0x74, 0x5c, 0x6f, 0x29, 0xa5, 0x17, 0x60, 0x1c, 0x06, 0x29, 0x16, 0x13, 0x00, + 0xc7, 0xd8, 0x20, 0x0b, 0x54, 0x37, 0x80, 0x1d, 0x9e, 0x8d, 0xb6, 0x40, 0x00, 0x8f, 0x51, 0x3f, + 0xdc, 0x4f, 0xe6, 0xf6, 0x12, 0xe4, 0x67, 0xce, 0x7e, 0x70, 0xf6, 0xfa, 0x41, 0xfe, 0x39, 0x3c, + 0x5a, 0xbb, 0xa8, 0x4a, 0xe9, 0x75, 0x8a, 0xc1, 0x18, 0xd4, 0x6c, 0xeb, 0x59, 0xa2, 0x78, 0x7f, + 0x11, 0xf3, 0x1f, 0x36, 0x29, 0xc3, 0x6c, 0x80, 0x09, 0xcb, 0x22, 0x00, 0xc6, 0x41, 0xad, 0xe6, + 0xd4, 0x0c, 0x75, 0xce, 0xca, 0xdb, 0xe2, 0xb5, 0xd1, 0x97, 0x69, 0xa6, 0x9a, 0x69, 0x8c, 0x01, + 0x8b, 0xa9, 0xa6, 0xdb, 0x7f, 0x0a, 0x28, 0x22, 0x41, 0x5a, 0xeb, 0xfd, 0x3f, 0x4f, 0x87, 0x14, + 0x14, 0x68, 0x4b, 0xff, 0x75, 0xaa, 0x75, 0xfb, 0x7c, 0x30, 0xa0, 0x91, 0xe5, 0xf2, 0x9f, 0xed, + 0xff, 0xcb, 0x80, 0xb8, 0x02, 0x47, 0x08, 0x78, 0x88, 0x2a, 0xce, 0xd4, 0xb4, 0x8f, 0xd4, 0x0f, + 0x13, 0xe3, 0x63, 0x66, 0x92, 0x08, 0x66, 0x6e, 0xc7, 0xe0, 0x26, 0x01, 0x00, 0xdb, 0x30, 0x40, + 0x70, 0x3a, 0x84, 0xb8, 0xa0, 0x62, 0x86, 0x4c, 0x91, 0xeb, 0x13, 0x76, 0x1c, 0xf3, 0x9e, 0x58, + 0xc7, 0x8f, 0x2f, 0x4a, 0x7f, 0x73, 0x78, 0x6e, 0x70, 0x03, 0x27, 0xf5, 0x6b, 0x57, 0xaf, 0x7f, + 0x16, 0xe0, 0x3f, 0xf1, 0x87, 0x6f, 0xf8, 0xff, 0xff, 0xfd, 0x3e, 0x11, 0x84, 0x48, 0xa9, 0xad, + 0x55, 0x45, 0xd5, 0x44, 0x9c, 0x3b, 0xf0, 0xc8, 0x81, 0xa2, 0x1d, 0xa5, 0x8e, 0xd1, 0xc0, 0xd0, + 0xa9, 0x1e, 0x47, 0xb0, 0x1c, 0x21, 0xf9, 0x39, 0xe5, 0x8c, 0x2f, 0xa1, 0x4e, 0x80, 0xa0, 0x40, + 0x75, 0x25, 0xa6, 0x4a, 0x01, 0x00, 0xea, 0xef, 0xc7, 0xff, 0xf0, 0x08, 0x08, 0x64, 0x29, 0x18, + 0xab, 0xe9, 0x1d, 0x01, 0xf2, 0x91, 0xf8, 0x4f, 0x00, 0xed, 0x2c, 0x45, 0xd0, 0xe2, 0x00, 0xf9, + 0x60, 0x31, 0xc4, 0x01, 0xf3, 0xc0, 0x79, 0xfd, 0x54, 0x73, 0x21, 0x2d, 0x60, 0x3c, 0x44, 0x05, + 0x24, 0x34, 0xaf, 0x83, 0x88, 0x01, 0xf8, 0xb1, 0xbe, 0x3d, 0x29, 0x50, 0xb1, 0xc5, 0x41, 0xc5, + 0xe2, 0x5c, 0x7a, 0x80, 0x35, 0xd2, 0x05, 0x04, 0xbd, 0x7e, 0x07, 0x90, 0x2c, 0x82, 0xb1, 0x20, + 0xef, 0x24, 0xce, 0x2a, 0x64, 0x9e, 0x7b, 0x4a, 0x52, 0x45, 0xd5, 0x45, 0xdd, 0xc0, 0x5c, 0x03, + 0x10, 0xa1, 0x00, 0xa8, 0x98, 0x01, 0xa4, 0x7a, 0xcf, 0x1c, 0x1d, 0x5e, 0x6b, 0x26, 0x2a, 0xd6, + 0x2a, 0x74, 0x05, 0xe4, 0x79, 0x62, 0xac, 0x9b, 0xdb, 0x83, 0x00, 0x02, 0x87, 0x00, 0x03, 0x58, + 0x77, 0x00, 0xa2, 0x98, 0xb2, 0x54, 0x86, 0xb6, 0xc4, 0xf9, 0x7b, 0xbd, 0x8a, 0xdf, 0xdd, 0x5d, + 0x31, 0x6f, 0xab, 0xb6, 0x07, 0xd8, 0x4c, 0x5f, 0x27, 0x9a, 0x8e, 0x77, 0xfb, 0x29, 0x3f, 0x87, + 0xb9, 0x08, 0xab, 0xae, 0xea, 0xb5, 0x5c, 0x21, 0xad, 0x6b, 0x5b, 0x69, 0xd7, 0x57, 0x3e, 0x13, + 0x25, 0xab, 0x48, 0xac, 0x32, 0xf5, 0xc1, 0x2c, 0x4f, 0x01, 0xd2, 0xc1, 0x1c, 0x1b, 0xc5, 0xc2, + 0x40, 0xe0, 0xa0, 0x61, 0xcc, 0x25, 0x65, 0x88, 0xea, 0x3e, 0x09, 0x62, 0x81, 0x88, 0x03, 0xf9, + 0xdc, 0x6b, 0xf3, 0x0d, 0x10, 0xa0, 0x0c, 0xb2, 0xe3, 0x83, 0xe9, 0x56, 0xd7, 0xbd, 0x5c, 0x90, + 0xe6, 0x85, 0xf0, 0xd2, 0x80, 0x4e, 0x57, 0xd8, 0x5d, 0xe9, 0x76, 0xfa, 0x97, 0xc7, 0x9f, 0xa6, + 0x4e, 0x3b, 0x73, 0xfc, 0x74, 0xb0, 0xd4, 0xa0, 0x03, 0xb5, 0xe7, 0x4c, 0x6d, 0xab, 0xf6, 0xf5, + 0xcf, 0xef, 0x6d, 0x92, 0x19, 0xcc, 0x5b, 0xc8, 0xd5, 0x79, 0x6c, 0x70, 0x38, 0xc2, 0x57, 0x64, + 0x3d, 0x30, 0x00, 0x1d, 0x4d, 0x46, 0x42, 0x3d, 0x10, 0xfe, 0xba, 0xbc, 0xcf, 0x1d, 0xb3, 0xfb, + 0xc4, 0xfd, 0x79, 0x72, 0xf4, 0xe3, 0x97, 0xdf, 0x0c, 0x00, 0x42, 0x06, 0xc9, 0x41, 0x53, 0x21, + 0x25, 0x2c, 0x06, 0x78, 0xf7, 0x8f, 0x34, 0xb0, 0x3b, 0x4a, 0x7b, 0xcb, 0x69, 0x40, 0x47, 0x85, + 0x6a, 0x59, 0xd6, 0x24, 0xf0, 0x98, 0x47, 0x07, 0x12, 0x6a, 0x2d, 0x8b, 0xab, 0xbb, 0xe6, 0xfc, + 0x48, 0x53, 0x22, 0xe3, 0x89, 0x63, 0xa0, 0x5f, 0x25, 0xea, 0x70, 0x01, 0xc3, 0x80, 0x3c, 0xb0, + 0x03, 0x2c, 0x03, 0xa9, 0x21, 0x43, 0x13, 0xc0, 0xfb, 0xb8, 0x90, 0xc8, 0xd8, 0x87, 0x8e, 0xbf, + 0x75, 0xa3, 0xf2, 0x80, 0x98, 0x74, 0x0f, 0x00, 0x3c, 0x54, 0x0f, 0x43, 0x02, 0xc0, 0xe6, 0xd8, + 0x61, 0x90, 0x74, 0x2e, 0x2a, 0x6e, 0xc7, 0xd8, 0x58, 0x80, 0xef, 0xb6, 0x7f, 0x06, 0xdf, 0x61, + 0x11, 0x21, 0x42, 0x0a, 0xa0, 0x63, 0x1d, 0xfe, 0xda, 0xb9, 0x4e, 0xf2, 0xb2, 0x77, 0xb5, 0x92, + 0xb2, 0x50, 0x76, 0x5f, 0xc7, 0x72, 0x34, 0x21, 0x8b, 0x6b, 0x24, 0xca, 0x8e, 0xbe, 0x2a, 0x80, + 0xcf, 0x08, 0x8c, 0xef, 0x6d, 0xd8, 0x79, 0xc9, 0x3b, 0x8f, 0x39, 0xc1, 0x46, 0x5c, 0xdf, 0xf8, + 0x60, 0x22, 0x3f, 0x2b, 0x92, 0xee, 0x4c, 0x8e, 0xc7, 0x35, 0x30, 0x1c, 0x20, 0xe4, 0x48, 0xb2, + 0x88, 0x0b, 0xf3, 0xe6, 0x20, 0x9a, 0xf0, 0x1d, 0x20, 0x59, 0x21, 0xa0, 0xe9, 0x73, 0xe1, 0x2d, + 0x78, 0x60, 0x6c, 0x1d, 0xf0, 0xf8, 0xa7, 0xd9, 0xf3, 0x94, 0x16, 0xa7, 0x06, 0x04, 0xa0, 0x00, + 0xa8, 0x72, 0xda, 0x85, 0x8a, 0xc6, 0x1f, 0x89, 0x51, 0x80, 0x07, 0xe1, 0x14, 0x82, 0x41, 0xc1, + 0x36, 0xc5, 0x5b, 0x38, 0x31, 0xb8, 0x71, 0xbf, 0x82, 0x32, 0xaa, 0x8e, 0x20, 0xb1, 0x30, 0x79, + 0x32, 0x0f, 0x71, 0x64, 0x68, 0xb4, 0xdd, 0xd2, 0xf9, 0x2a, 0xba, 0xec, 0xf1, 0x7d, 0x71, 0x42, + 0xa6, 0xdc, 0x76, 0x22, 0x1b, 0xb1, 0xd4, 0xf0, 0x49, 0xa6, 0xd3, 0x4c, 0x3c, 0x59, 0x5e, 0x7e, + 0x38, 0xb7, 0xdb, 0xf1, 0x1e, 0x2b, 0x2e, 0x6b, 0xbe, 0x43, 0xa9, 0x30, 0x72, 0xf8, 0x0d, 0x90, + 0x70, 0x33, 0xa9, 0xf2, 0x64, 0x5c, 0x28, 0x35, 0x2b, 0x53, 0xb5, 0xbc, 0x4d, 0x8b, 0x3c, 0x71, + 0xfd, 0xff, 0x87, 0x30, 0x0a, 0xf9, 0x93, 0x30, 0x49, 0xd9, 0xbf, 0xf3, 0x10, 0xf6, 0x64, 0x42, + 0xd8, 0xb6, 0x4d, 0x8b, 0x49, 0xf5, 0xeb, 0x96, 0x2a, 0xff, 0x87, 0x14, 0x04, 0x10, 0x86, 0xd0, + 0xc5, 0xa1, 0x5b, 0xff, 0xe1, 0x44, 0x8c, 0x33, 0x31, 0x8d, 0xa8, 0xed, 0xcb, 0x75, 0x0c, 0x78, + 0xe7, 0x71, 0x6d, 0xd6, 0xa7, 0xd9, 0x6e, 0x2c, 0x5b, 0xff, 0x0c, 0x00, 0xb0, 0x0a, 0x11, 0xb0, + 0x15, 0x95, 0x5a, 0x08, 0xc4, 0x00, 0xe0, 0x7b, 0xd4, 0x98, 0x15, 0x38, 0x00, 0x08, 0xf2, 0x56, + 0x8c, 0xed, 0x61, 0x9e, 0xa0, 0xec, 0x1a, 0xbb, 0x2a, 0x07, 0x9c, 0x3e, 0x2e, 0x03, 0xc0, 0x08, + 0x23, 0x48, 0x18, 0x27, 0x01, 0x28, 0x2e, 0x83, 0xd6, 0xe3, 0x17, 0xde, 0x69, 0x4c, 0x46, 0x9c, + 0xb8, 0x48, 0x76, 0x55, 0xa2, 0xdb, 0x07, 0x97, 0xb0, 0xf9, 0x2b, 0x71, 0xb9, 0xad, 0xfe, 0x18, + 0xee, 0x27, 0x62, 0x8b, 0x14, 0x5e, 0x2a, 0x9a, 0x4f, 0xc1, 0x40, 0xda, 0xa1, 0xbc, 0x65, 0x1b, + 0x62, 0xe9, 0xcb, 0x3e, 0x0e, 0x1e, 0xfb, 0x3c, 0x1e, 0x7b, 0x96, 0x5b, 0x27, 0x1d, 0xb0, 0xb6, + 0xee, 0x1e, 0x77, 0xc9, 0x81, 0xd3, 0x5f, 0x5d, 0xb7, 0xc1, 0x04, 0x29, 0xea, 0xd6, 0x54, 0x6d, + 0x54, 0x58, 0x18, 0x30, 0x41, 0x64, 0x4a, 0x54, 0x78, 0x2c, 0x18, 0x32, 0x1b, 0x6c, 0x72, 0x05, + 0x83, 0xc2, 0xce, 0x34, 0x2b, 0xc1, 0x5c, 0x77, 0xc8, 0x9d, 0x99, 0xe1, 0xc1, 0x27, 0x07, 0xac, + 0x2e, 0x85, 0xf7, 0x41, 0xeb, 0xe0, 0xb3, 0xcb, 0x45, 0xcb, 0x98, 0xac, 0x43, 0x46, 0x3e, 0x0a, + 0xec, 0x28, 0x6a, 0x6c, 0x6d, 0xd9, 0x6c, 0x56, 0x93, 0x31, 0x00, 0x3c, 0xe0, 0x1a, 0x25, 0x5c, + 0x48, 0xb8, 0x87, 0x1c, 0xb6, 0x5e, 0xe9, 0x3f, 0xce, 0x03, 0xc4, 0x0b, 0x20, 0xa3, 0xab, 0x44, + 0xd1, 0x03, 0x8b, 0x54, 0xf1, 0xc6, 0x38, 0x0e, 0x90, 0x2c, 0x85, 0x0a, 0xac, 0x8e, 0x1c, 0xab, + 0x17, 0x52, 0x2a, 0x8b, 0x84, 0xa2, 0xf5, 0x96, 0x53, 0xb3, 0x72, 0xdf, 0x65, 0xc5, 0xfe, 0x2f, + 0xaa, 0xd5, 0x45, 0xfc, 0xdd, 0x54, 0x35, 0xcd, 0xa7, 0x75, 0xc8, 0x22, 0x3d, 0x37, 0xdf, 0x21, + 0x52, 0x5f, 0xc4, 0x48, 0x41, 0x25, 0x2f, 0xcb, 0x9f, 0x11, 0x53, 0x53, 0x89, 0x2c, 0xf1, 0x22, + 0x02, 0x91, 0x70, 0x9f, 0x54, 0x65, 0x09, 0x19, 0x20, 0x01, 0xcb, 0x0a, 0xcd, 0x52, 0x1b, 0x59, + 0x27, 0x70, 0xcc, 0xd8, 0x5f, 0x4c, 0xb6, 0x1d, 0x65, 0x00, 0x3e, 0x91, 0x99, 0xd2, 0x33, 0x55, + 0xfd, 0xab, 0x6e, 0xd5, 0xdd, 0xd1, 0x75, 0x91, 0x4b, 0x91, 0xa4, 0x0b, 0xe6, 0xbc, 0xb4, 0xe1, + 0x97, 0xd0, 0xdb, 0x20, 0x03, 0x41, 0x59, 0x59, 0x79, 0xbb, 0x1e, 0xfe, 0xe3, 0xe1, 0xad, 0xc5, + 0xf9, 0x20, 0xf5, 0xbb, 0x00, 0x1c, 0x3f, 0xf8, 0x2e, 0x86, 0x3d, 0x6b, 0x9c, 0x34, 0xa0, 0x43, + 0x92, 0x34, 0x1f, 0x57, 0x59, 0xbd, 0x63, 0xb6, 0xdd, 0x77, 0xc9, 0xe4, 0x13, 0xc3, 0xc4, 0x80, + 0x04, 0xaa, 0xd5, 0x98, 0x6f, 0xd8, 0xa1, 0x32, 0x96, 0xd4, 0x50, 0x7c, 0xa6, 0xaa, 0x17, 0x1d, + 0x21, 0x3a, 0x31, 0xac, 0x21, 0x70, 0x68, 0x38, 0xe5, 0x57, 0x5b, 0x29, 0xa1, 0xc0, 0x70, 0x01, + 0x80, 0x2b, 0x7e, 0x0e, 0xf9, 0xdf, 0x8f, 0xce, 0x22, 0x52, 0x26, 0x93, 0x4b, 0xf2, 0x68, 0x8e, + 0xa7, 0xe0, 0x3a, 0x00, 0xe1, 0xc0, 0x74, 0x01, 0xa0, 0x37, 0xc0, 0xe8, 0x97, 0xc4, 0xcf, 0xb0, + 0xe2, 0x1d, 0xf9, 0x78, 0x24, 0xc0, 0x64, 0xc6, 0xc9, 0x06, 0xea, 0x0f, 0x47, 0x81, 0x16, 0x26, + 0xe1, 0x00, 0xc0, 0xe3, 0x62, 0x07, 0x04, 0xbe, 0x5e, 0xc0, 0xb2, 0x1f, 0x5f, 0x9e, 0x18, 0x0c, + 0x08, 0x89, 0x70, 0xff, 0x3c, 0xe1, 0x67, 0x5e, 0x24, 0x2c, 0x7c, 0x5d, 0x41, 0x46, 0xa5, 0x06, + 0x0b, 0x8b, 0x09, 0xa9, 0xc9, 0x0e, 0x06, 0x92, 0xe0, 0xfb, 0xfc, 0x35, 0xcc, 0x5d, 0xdf, 0xdd, + 0x77, 0xf7, 0x9b, 0x2b, 0xe2, 0x4d, 0xa2, 0x7a, 0x75, 0x5c, 0x29, 0xe5, 0xc6, 0xe7, 0x38, 0xe0, + 0x8f, 0x61, 0xce, 0x00, 0x74, 0x19, 0x83, 0x5a, 0x7d, 0xc2, 0x75, 0x7e, 0xc4, 0xfc, 0x87, 0xcf, + 0x7f, 0x15, 0xe7, 0x8d, 0xc0, 0x37, 0x63, 0x60, 0xe8, 0x37, 0x60, 0x62, 0x07, 0x60, 0xc4, 0x22, + 0x34, 0x40, 0xdd, 0x03, 0xda, 0xa6, 0x28, 0x24, 0xb1, 0x30, 0x00, 0x16, 0x58, 0xf6, 0x2a, 0xc8, + 0x2c, 0x15, 0x61, 0xbd, 0x29, 0xe5, 0x62, 0x5e, 0x60, 0x4f, 0x1e, 0x3a, 0xb9, 0x3d, 0x4f, 0x03, + 0x00, 0xd1, 0x2c, 0x1c, 0x48, 0xf9, 0xe3, 0xdb, 0x8f, 0x06, 0x00, 0xe4, 0x6c, 0xf0, 0x1c, 0x7f, + 0xab, 0x93, 0x1d, 0x32, 0xb0, 0xbd, 0x6b, 0x01, 0xdf, 0x05, 0xc0, 0xd1, 0x0b, 0x22, 0xe3, 0xec, + 0x57, 0x8e, 0x1e, 0x38, 0xc1, 0x12, 0x9c, 0xfe, 0x6a, 0xf8, 0x80, 0x28, 0x0d, 0x81, 0xbb, 0xe1, + 0xc2, 0xf8, 0xb2, 0x03, 0x58, 0x78, 0x00, 0x11, 0xc0, 0xaa, 0xb6, 0x55, 0x1a, 0xd3, 0x44, 0x00, + 0xa8, 0x34, 0x1b, 0x54, 0x25, 0x68, 0xf8, 0x00, 0x58, 0xf4, 0xc6, 0x29, 0x48, 0x30, 0xdd, 0x16, + 0xb2, 0xf2, 0x75, 0x9d, 0x1f, 0xf0, 0x88, 0xd1, 0x2d, 0x40, 0x4b, 0x37, 0x44, 0x4c, 0xc3, 0x8c, + 0xba, 0xee, 0xb7, 0xb0, 0xfa, 0x01, 0x61, 0xcb, 0xa2, 0x00, 0x61, 0x15, 0x38, 0x45, 0x8b, 0x7f, + 0xe0, 0x80, 0x8d, 0x33, 0x37, 0x63, 0x2b, 0x1a, 0x30, 0x0b, 0x99, 0xd7, 0x6d, 0x25, 0x64, 0x2d, + 0xb7, 0x34, 0xff, 0x88, 0xf1, 0x01, 0x4d, 0x4b, 0x56, 0xee, 0x48, 0xa1, 0x35, 0x26, 0x17, 0x44, + 0x25, 0x27, 0xd1, 0x7b, 0xb3, 0xe3, 0x6f, 0x30, 0x7c, 0x5c, 0xdf, 0xa0, 0x9e, 0x53, 0x85, 0x4f, + 0x70, 0x95, 0x91, 0x6f, 0x00, 0x00, 0x9a, 0x05, 0x4e, 0x1a, 0x26, 0xa4, 0x7f, 0xc4, 0x0a, 0xea, + 0xad, 0xaa, 0x06, 0x33, 0xdc, 0x40, 0xb3, 0x26, 0x4d, 0x24, 0x05, 0x4b, 0x01, 0xa5, 0x0a, 0x0f, + 0x8e, 0x1c, 0xe2, 0x01, 0x46, 0xd8, 0x51, 0xf3, 0x73, 0x2e, 0x3e, 0x5c, 0x40, 0x40, 0x28, 0x58, + 0xad, 0x4b, 0xc9, 0x01, 0xab, 0xc9, 0x00, 0x6e, 0x35, 0x80, 0x74, 0xb0, 0xf3, 0xa8, 0x63, 0x24, + 0xe0, 0xaa, 0x74, 0xf5, 0x00, 0x57, 0x12, 0x21, 0x95, 0x58, 0x1a, 0x2c, 0xe7, 0x88, 0x10, 0x0a, + 0x88, 0xb5, 0x55, 0x37, 0x61, 0x73, 0xb4, 0xb0, 0x4c, 0x72, 0x69, 0xb0, 0xec, 0x48, 0x2e, 0x55, + 0x44, 0xc9, 0x37, 0x7f, 0xe4, 0xe0, 0x38, 0xf2, 0x4e, 0x36, 0xc1, 0xdb, 0xa6, 0xe8, 0xbb, 0xac, + 0x7b, 0xa2, 0x84, 0xb3, 0x03, 0x06, 0x4e, 0xbf, 0xc3, 0x3d, 0x8a, 0x6d, 0x01, 0xdb, 0xf4, 0x2d, + 0x9f, 0x76, 0x9a, 0xfc, 0x27, 0xa4, 0xc9, 0x34, 0xf7, 0xf1, 0xe2, 0x10, 0x46, 0x96, 0x63, 0x1b, + 0x09, 0x31, 0x9e, 0xaa, 0x4b, 0x98, 0x88, 0x50, 0xa0, 0x7d, 0x6f, 0xac, 0x28, 0xa0, 0x0a, 0x2a, + 0x56, 0x03, 0x8c, 0x01, 0x91, 0xea, 0x80, 0x77, 0xb6, 0x4e, 0x8d, 0xd2, 0x0f, 0x8d, 0x7f, 0x28, + 0xc0, 0xd3, 0x82, 0x40, 0x74, 0x4a, 0xe6, 0xc4, 0xd8, 0x98, 0x72, 0x7f, 0x6e, 0x8e, 0xf1, 0x02, + 0x18, 0x9b, 0xe3, 0xdf, 0xdf, 0x28, 0xac, 0xd8, 0x6c, 0x2c, 0x48, 0x44, 0x16, 0x12, 0x79, 0xf3, + 0x72, 0x31, 0x8a, 0xb4, 0xf0, 0x13, 0xe4, 0x81, 0xba, 0xd9, 0xe8, 0x52, 0x77, 0x88, 0x12, 0x14, + 0x8a, 0x4b, 0x9c, 0x00, 0xe0, 0xee, 0x93, 0x8a, 0x8d, 0x4d, 0x28, 0x52, 0x94, 0xfd, 0x8c, 0xbb, + 0xf7, 0x54, 0x21, 0x8c, 0x67, 0x2c, 0xff, 0x3c, 0x30, 0x0a, 0x8a, 0x35, 0x1b, 0xf7, 0xd7, 0xc0, + 0xaa, 0x04, 0x3f, 0x88, 0xc4, 0x27, 0x4c, 0x95, 0xf4, 0xb7, 0xbb, 0x0d, 0xb2, 0x00, 0x58, 0x1b, + 0xa1, 0xed, 0x69, 0x21, 0x77, 0x7b, 0xd8, 0xa4, 0x98, 0x56, 0x31, 0x8b, 0x83, 0xba, 0x07, 0x3c, + 0x3b, 0xac, 0x2b, 0xd1, 0x45, 0xcb, 0x51, 0x45, 0xb8, 0x32, 0x02, 0xcd, 0xdd, 0xb0, 0x76, 0x83, + 0x9e, 0x3c, 0x30, 0x8e, 0x00, 0xd4, 0x44, 0xb9, 0x9d, 0x09, 0x9f, 0xca, 0x6a, 0x48, 0xa6, 0xd8, + 0x3b, 0xc9, 0xdb, 0x91, 0xf6, 0x1d, 0x50, 0x09, 0xab, 0x48, 0x3e, 0x70, 0x6e, 0xba, 0x6e, 0x58, + 0xc2, 0x0a, 0x87, 0xab, 0xac, 0xf0, 0x53, 0x85, 0xb8, 0x53, 0x8f, 0xc6, 0xce, 0x61, 0xa7, 0xd8, + 0xff, 0x89, 0x16, 0x4b, 0xda, 0xcb, 0x82, 0xbf, 0x28, 0x9b, 0xbb, 0xf8, 0xc3, 0x6e, 0xf9, 0x71, + 0xc7, 0x7c, 0xa7, 0x77, 0xdc, 0x18, 0x46, 0xb8, 0x09, 0x01, 0x21, 0x48, 0x18, 0x1d, 0x38, 0xb6, + 0x78, 0xc1, 0x5a, 0x83, 0xbe, 0x1e, 0xe5, 0xe2, 0x1e, 0x58, 0x0c, 0xe0, 0x1c, 0x24, 0x00, 0x54, + 0x2a, 0xab, 0xb0, 0xa2, 0x0d, 0x4f, 0xff, 0xf1, 0x02, 0x06, 0x5f, 0x4b, 0x77, 0x3d, 0xc2, 0xde, + 0xf6, 0xc5, 0x6f, 0xbb, 0xe2, 0x44, 0x0e, 0xdc, 0x36, 0xaf, 0xc2, 0x72, 0xb9, 0x97, 0xc5, 0x7c, + 0x22, 0x3a, 0x79, 0xce, 0x32, 0x83, 0xa1, 0xb8, 0xe2, 0xf2, 0xbc, 0x32, 0x2e, 0x15, 0x64, 0x98, + 0xcf, 0xcd, 0x45, 0x2f, 0xf1, 0x03, 0x26, 0x63, 0x0a, 0x96, 0x21, 0xa2, 0x92, 0xeb, 0xd3, 0xe9, + 0xcd, 0x3e, 0xda, 0x63, 0xb9, 0xab, 0x6e, 0xb9, 0x2e, 0xf9, 0x7b, 0xe2, 0xea, 0x4e, 0x23, 0x26, + 0x6b, 0x5f, 0x8e, 0xb1, 0xab, 0x1d, 0x61, 0xda, 0xcc, 0xcc, 0x56, 0x4c, 0x43, 0x12, 0xb7, 0xe2, + 0x44, 0xab, 0xc4, 0xc4, 0x08, 0x1a, 0x31, 0x75, 0xe3, 0x61, 0x24, 0xf6, 0x66, 0xe5, 0xe7, 0x09, + 0x92, 0xf1, 0x72, 0x70, 0x2a, 0x71, 0xf8, 0x05, 0x13, 0xc4, 0xbe, 0x1f, 0x28, 0xfe, 0x18, 0x8d, + 0x29, 0xd8, 0x42, 0x2b, 0x71, 0xc1, 0x4e, 0x6a, 0x6a, 0x83, 0xcf, 0x2c, 0x97, 0x1c, 0x4b, 0xb8, + 0xe2, 0x5e, 0x4f, 0x00, 0xf1, 0x48, 0x95, 0x29, 0xac, 0xa9, 0x05, 0xc1, 0xfb, 0xa0, 0xa6, 0x70, + 0xf5, 0x47, 0x7f, 0x36, 0x5f, 0x07, 0xbf, 0x0e, 0x38, 0x01, 0xca, 0x77, 0x90, 0x8e, 0x91, 0x0c, + 0x0e, 0x12, 0xfc, 0xce, 0x71, 0xd2, 0x78, 0xd4, 0xab, 0xe0, 0x73, 0xc7, 0xbe, 0xc8, 0x67, 0x60, + 0x24, 0x1e, 0x36, 0xb6, 0x59, 0x97, 0x88, 0x20, 0xa0, 0xc0, 0x00, 0x47, 0x42, 0xae, 0x1f, 0x15, + 0xbc, 0x91, 0xf1, 0x34, 0x3a, 0xfa, 0x70, 0xff, 0x0e, 0xdd, 0x9c, 0x50, 0xa5, 0x7e, 0x07, 0xe1, + 0xae, 0x58, 0x00, 0xc4, 0xbc, 0x0e, 0xa8, 0x0e, 0x92, 0x6e, 0xef, 0x46, 0x7c, 0xab, 0x8f, 0xff, + 0xc9, 0x07, 0x82, 0xc4, 0xff, 0x3d, 0x69, 0x49, 0xfd, 0x41, 0x08, 0x40, 0x28, 0x70, 0xd0, 0x26, + 0xd2, 0x00, 0x00, 0x23, 0xc4, 0x51, 0xd7, 0xdc, 0xf1, 0x8e, 0xfc, 0x9b, 0x9b, 0xfa, 0xd5, 0x58, + 0x17, 0x49, 0x95, 0x38, 0x48, 0x2d, 0x81, 0x28, 0xae, 0x58, 0xc3, 0x42, 0x69, 0x47, 0xe2, 0x44, + 0x85, 0x05, 0x13, 0x80, 0x2a, 0x58, 0x32, 0xc6, 0x7c, 0x2d, 0xef, 0xd5, 0x12, 0x0f, 0xad, 0x38, + 0xaa, 0x1b, 0x83, 0xa0, 0x69, 0xbc, 0x07, 0x23, 0xc6, 0xc3, 0x07, 0xcf, 0xb2, 0x3b, 0xb7, 0x31, + 0xf8, 0x10, 0x23, 0x0a, 0x06, 0x2b, 0x50, 0xa8, 0xcb, 0x27, 0x81, 0xe7, 0x80, 0x58, 0x39, 0xe7, + 0x81, 0x48, 0x89, 0x51, 0x28, 0x84, 0x30, 0x4f, 0x10, 0x83, 0x5f, 0x99, 0x22, 0xca, 0x9f, 0x81, + 0xf4, 0xbd, 0x9e, 0xc5, 0x1f, 0x85, 0x22, 0xb7, 0x39, 0x83, 0xfb, 0xad, 0xcf, 0x7d, 0x96, 0x31, + 0x5b, 0xb1, 0xba, 0x37, 0xe2, 0x44, 0x0c, 0xea, 0xb7, 0x4d, 0x8c, 0x27, 0x3d, 0xf2, 0x05, 0xbf, + 0x2b, 0x48, 0xd8, 0xc5, 0x77, 0xe2, 0x4e, 0xb2, 0xd1, 0x5f, 0x50, 0x5c, 0x41, 0x57, 0x12, 0x11, + 0x19, 0x1d, 0x36, 0x5b, 0xfc, 0x93, 0x13, 0x69, 0x4e, 0x36, 0xcc, 0x0c, 0x15, 0x12, 0xce, 0xce, + 0x06, 0x44, 0xbe, 0x8b, 0x85, 0x75, 0x78, 0xde, 0x5d, 0x56, 0x5e, 0x62, 0x55, 0x61, 0x28, 0x98, + 0xa2, 0x5d, 0xde, 0xab, 0x51, 0x22, 0x08, 0x56, 0xe8, 0xe4, 0xb3, 0xc1, 0x80, 0x60, 0x7f, 0x13, + 0xf4, 0x8e, 0xa8, 0x73, 0x54, 0x21, 0x92, 0x0a, 0xd9, 0x63, 0x71, 0x5f, 0x84, 0xb0, 0x7f, 0xe9, + 0x83, 0x57, 0x8f, 0xf8, 0x7a, 0x52, 0x00, 0x0e, 0x83, 0xa0, 0x3e, 0x1c, 0x50, 0x1a, 0x8d, 0x16, + 0x3e, 0x26, 0x1a, 0x16, 0x00, 0x04, 0x67, 0xb0, 0x78, 0x1f, 0x88, 0x7e, 0x21, 0x24, 0x0c, 0x49, + 0x3a, 0x25, 0xbc, 0xd1, 0x2d, 0xfe, 0x16, 0x8a, 0x00, 0xcf, 0x79, 0x60, 0x00, 0xcf, 0x1e, 0x1d, + 0xc1, 0xab, 0xf3, 0x85, 0x92, 0x0a, 0x84, 0xdf, 0x3f, 0x08, 0x3e, 0xf7, 0xc5, 0x9e, 0x94, 0xbc, + 0xb8, 0x2b, 0x2d, 0x85, 0x01, 0xf4, 0x2e, 0xa0, 0x0c, 0xc0, 0xd3, 0x06, 0x44, 0x1b, 0xfc, 0x8a, + 0xba, 0x63, 0xd8, 0xe0, 0xc7, 0x79, 0x41, 0x93, 0xba, 0xba, 0x95, 0xd8, 0x29, 0xe8, 0xe8, 0x23, + 0x15, 0x8f, 0x87, 0x08, 0x60, 0x04, 0xcd, 0xb0, 0x49, 0x07, 0xea, 0xc4, 0x3f, 0xcc, 0xf8, 0x01, + 0xf5, 0x6f, 0xdc, 0xe8, 0x5e, 0x14, 0x81, 0xb3, 0x73, 0xdd, 0x1b, 0x00, 0x3a, 0x3b, 0x27, 0x4f, + 0x1f, 0x6e, 0xe5, 0x07, 0x53, 0xde, 0x4d, 0xe7, 0xda, 0xc5, 0x3b, 0xec, 0xd1, 0x63, 0xfb, 0x72, + 0x7c, 0x08, 0x01, 0x00, 0xa4, 0xcc, 0x8b, 0xe6, 0x4e, 0xab, 0xa9, 0x19, 0x38, 0xab, 0xf1, 0xde, + 0x49, 0x9a, 0xad, 0x39, 0x51, 0x86, 0x4b, 0xc5, 0xc6, 0xff, 0xa2, 0xee, 0x26, 0xe5, 0x8e, 0xd2, + 0xf9, 0x77, 0x77, 0xc4, 0x04, 0x06, 0x57, 0x53, 0xaf, 0x6d, 0xab, 0x37, 0xa2, 0x8d, 0x9b, 0x2a, + 0xf2, 0xf1, 0x33, 0xa1, 0x9b, 0x24, 0xd9, 0x35, 0xba, 0xc2, 0x0a, 0x71, 0x5a, 0xd5, 0xee, 0xe1, + 0x2e, 0x49, 0xf2, 0x95, 0x76, 0x47, 0x7d, 0x72, 0x09, 0xdd, 0xfc, 0xc4, 0x77, 0x3e, 0x3f, 0x1c, + 0x14, 0x06, 0x42, 0x90, 0x26, 0x08, 0x99, 0x34, 0xda, 0x30, 0x5a, 0x3f, 0x93, 0xba, 0x6e, 0x7f, + 0x14, 0x6f, 0x2e, 0x29, 0xcf, 0x7c, 0x2a, 0x41, 0x20, 0x04, 0x10, 0xed, 0x45, 0x20, 0xcf, 0xfb, + 0xaa, 0x2c, 0x9f, 0xc1, 0xff, 0xde, 0xce, 0xde, 0x04, 0x18, 0xc1, 0x42, 0xb1, 0x47, 0x3e, 0x16, + 0x00, 0xc9, 0xc0, 0x54, 0x75, 0xe5, 0x51, 0x3f, 0x52, 0xf5, 0xb5, 0x0d, 0x60, 0x11, 0x14, 0x86, + 0x90, 0xb1, 0x42, 0x03, 0x7b, 0x3e, 0xde, 0x25, 0xed, 0x96, 0xe9, 0xa6, 0x2d, 0xdc, 0xbd, 0xbf, + 0x5c, 0x44, 0x7c, 0x9c, 0x15, 0xb7, 0xc3, 0xde, 0xf9, 0x35, 0xfc, 0x61, 0x65, 0x9d, 0x21, 0x78, + 0xb4, 0x49, 0xb4, 0x0e, 0xda, 0xd3, 0x89, 0x3e, 0x8e, 0xba, 0x6e, 0x43, 0xe3, 0x2f, 0xb6, 0xb6, + 0x8d, 0x65, 0x73, 0x21, 0xea, 0xdf, 0x28, 0x4d, 0xcb, 0xda, 0xf1, 0x16, 0xd5, 0xc4, 0x62, 0x5d, + 0x57, 0xc4, 0xc9, 0x2b, 0x31, 0x30, 0xf9, 0xf4, 0x29, 0xc8, 0x57, 0x7d, 0x72, 0x1a, 0xad, 0x9b, + 0xbe, 0xee, 0xff, 0x92, 0xab, 0x50, 0x8f, 0x26, 0xb5, 0x5c, 0x46, 0xab, 0xbc, 0xbe, 0x16, 0x70, + 0x04, 0xcb, 0x54, 0x33, 0xb7, 0x5d, 0x9a, 0x77, 0xba, 0xee, 0xf7, 0x78, 0x5e, 0x70, 0x01, 0xbd, + 0x5f, 0xa2, 0xff, 0x7b, 0x77, 0x6f, 0x4e, 0x5e, 0xbc, 0xdd, 0xf6, 0xe0, 0x40, 0x08, 0x09, 0x30, + 0xa3, 0x12, 0x38, 0xef, 0xcb, 0xda, 0x7f, 0x18, 0x70, 0xab, 0x1d, 0x4f, 0x60, 0xa7, 0xb1, 0xaa, + 0x8e, 0x63, 0x23, 0x13, 0x5f, 0x1e, 0x64, 0x52, 0x66, 0xd5, 0x59, 0x87, 0xf0, 0x85, 0x5c, 0x83, + 0x88, 0x1e, 0x64, 0x94, 0x32, 0x7e, 0x25, 0x3e, 0xea, 0xac, 0x1f, 0xc2, 0x02, 0x7a, 0xae, 0xaa, + 0xb5, 0xf8, 0x2b, 0x2e, 0x62, 0x0a, 0x46, 0x82, 0xe7, 0x01, 0x3f, 0x48, 0x80, 0x80, 0x48, 0x50, + 0xb6, 0xfe, 0x20, 0x59, 0xb3, 0x31, 0x4a, 0xb0, 0xbf, 0x17, 0xd5, 0x6a, 0xa9, 0xbe, 0x08, 0x6f, + 0x7c, 0xa3, 0x39, 0x2b, 0xaf, 0x8b, 0xc9, 0x9a, 0xae, 0x78, 0x40, 0x40, 0xe2, 0x03, 0x66, 0xa7, + 0x80, 0x39, 0x6f, 0xc2, 0xc1, 0x8a, 0xcb, 0x62, 0xb7, 0xb7, 0x7e, 0x24, 0x49, 0xc5, 0x6e, 0x25, + 0xcb, 0x15, 0x9f, 0xbf, 0xc4, 0x84, 0x48, 0x9e, 0xb7, 0x76, 0x94, 0x5c, 0xde, 0x71, 0x22, 0x42, + 0x99, 0x5c, 0x5d, 0x54, 0x4f, 0x05, 0xd4, 0x53, 0x17, 0x0b, 0xd4, 0xad, 0x61, 0x90, 0x67, 0x2a, + 0x78, 0x44, 0x29, 0x59, 0x39, 0xc8, 0xb3, 0x54, 0xb4, 0x43, 0x8a, 0xff, 0x0b, 0xc5, 0xf9, 0x66, + 0x77, 0x8c, 0x32, 0x3b, 0xdc, 0x71, 0x23, 0x2a, 0x18, 0x92, 0x2a, 0xc8, 0xbf, 0x0b, 0x6d, 0xbb, + 0x75, 0x80, 0x88, 0xf5, 0x55, 0x55, 0xe1, 0x11, 0x85, 0x51, 0x26, 0x8a, 0x5e, 0x79, 0xc1, 0x72, + 0xcc, 0x2c, 0x1f, 0x2a, 0xa9, 0x98, 0x17, 0x9f, 0xe0, 0xa4, 0x92, 0x4f, 0x31, 0x4a, 0xad, 0x30, + 0x81, 0xe5, 0x5f, 0xfb, 0xc4, 0xc2, 0x9c, 0x10, 0x89, 0x8b, 0xed, 0x15, 0xc1, 0x1d, 0x55, 0x57, + 0xbe, 0x6b, 0xbb, 0x9f, 0x84, 0xf9, 0x05, 0x6b, 0x5e, 0x10, 0x09, 0x89, 0x0b, 0x69, 0xed, 0xde, + 0xfc, 0x48, 0x91, 0x09, 0xc3, 0xb6, 0x56, 0x3f, 0xe4, 0xaa, 0xa6, 0xc6, 0x13, 0xec, 0x4e, 0x6f, + 0x2f, 0x26, 0x6f, 0x86, 0xf8, 0x22, 0xa9, 0xa1, 0x6d, 0x31, 0xf2, 0x77, 0x7f, 0x11, 0x74, 0x06, + 0xc9, 0xca, 0x45, 0x93, 0x12, 0xd1, 0xf9, 0xaa, 0x63, 0xf6, 0x20, 0x9f, 0x13, 0xad, 0x69, 0x5c, + 0x1c, 0x70, 0x9e, 0x5f, 0xbd, 0xdc, 0x0e, 0xbc, 0x95, 0x5c, 0x04, 0x94, 0x00, 0x00, 0x00, 0x01, + 0x41, 0x9a, 0x4b, 0x25, 0xb2, 0x97, 0x36, 0x5f, 0x7f, 0x29, 0x9e, 0xf7, 0xc4, 0xef, 0x7b, 0xab, + 0xbe, 0x5d, 0x6a, 0x0b, 0xf9, 0x0b, 0x7b, 0x93, 0x92, 0xc6, 0xf9, 0xb8, 0x2c, 0xad, 0x50, 0xd0, + 0xe7, 0xfc, 0x18, 0xd8, 0x5f, 0x47, 0x38, 0x98, 0x46, 0x5d, 0x06, 0x7c, 0x1f, 0xe8, 0x5c, 0x4c, + 0x40, 0xbc, 0xf7, 0xf1, 0x30, 0x59, 0x59, 0x3a, 0x49, 0x97, 0x7c, 0xaa, 0x2f, 0x95, 0x71, 0x85, + 0xda, 0x53, 0x62, 0xc9, 0xb3, 0x69, 0x6a, 0xab, 0xe5, 0xad, 0x60, 0xc3, 0x98, 0xce, 0x21, 0x64, + 0xe9, 0x51, 0x0a, 0xce, 0x20, 0x74, 0xea, 0x06, 0x68, 0x7e, 0x72, 0xc3, 0xc3, 0x01, 0x1f, 0xb1, + 0xd7, 0xe3, 0x7e, 0xa7, 0xc4, 0x8f, 0xd1, 0x5e, 0xdd, 0xfa, 0x6f, 0xe0, 0xaa, 0x56, 0x38, 0xb9, + 0x7c, 0x8a, 0x65, 0xfb, 0xf1, 0x37, 0x3e, 0x6f, 0xe4, 0xd6, 0xbe, 0x48, 0xad, 0xdd, 0xfc, 0x59, + 0x2f, 0x7d, 0xdf, 0x13, 0xe2, 0x70, 0x87, 0x37, 0x35, 0x04, 0x73, 0xc1, 0x40, 0x93, 0x62, 0x97, + 0x45, 0xcc, 0x40, 0xe0, 0x87, 0x0c, 0x9f, 0x16, 0x4c, 0x43, 0x82, 0x1c, 0xc4, 0x0e, 0x0a, 0xfc, + 0x11, 0x97, 0x14, 0x62, 0xbc, 0xa1, 0x5e, 0x6b, 0xde, 0x4e, 0x62, 0xf2, 0xff, 0x18, 0x2a, 0xf7, + 0xd1, 0x5a, 0xdf, 0xbb, 0xe5, 0x8f, 0x13, 0x04, 0x65, 0x42, 0x52, 0x31, 0xf7, 0xc2, 0x35, 0x3e, + 0x7a, 0x1b, 0xb7, 0x6f, 0x88, 0x8a, 0xa6, 0xd9, 0x7e, 0xed, 0xbf, 0x13, 0x7d, 0xdf, 0x12, 0x27, + 0x89, 0xfc, 0x23, 0x55, 0xda, 0x69, 0x6f, 0x7a, 0xe5, 0xda, 0x55, 0xe1, 0x1e, 0x24, 0x4c, 0x67, + 0x16, 0x4c, 0x1d, 0x2c, 0x03, 0xb8, 0x12, 0x89, 0xe0, 0x1a, 0x8c, 0x13, 0xc1, 0xd4, 0x02, 0x5b, + 0xa0, 0x7e, 0xc0, 0x68, 0x02, 0x90, 0xa4, 0x36, 0x3e, 0xa8, 0xc4, 0x04, 0xb8, 0x1b, 0xc5, 0x8e, + 0x01, 0x93, 0xd2, 0x94, 0x00, 0x4d, 0x28, 0x8e, 0x00, 0x95, 0x00, 0x00, 0x16, 0xe7, 0xf1, 0x61, + 0x6a, 0x29, 0x3f, 0x32, 0xb6, 0x63, 0xc2, 0xc3, 0x80, 0x39, 0x27, 0x1c, 0x11, 0x51, 0x1b, 0x81, + 0xc2, 0x0a, 0x63, 0xfd, 0x03, 0xf0, 0x4a, 0x78, 0x0f, 0x66, 0x14, 0x81, 0x64, 0x70, 0x71, 0x99, + 0xa7, 0x78, 0xb7, 0xb8, 0x3a, 0x24, 0x0b, 0x90, 0xf2, 0x38, 0x02, 0x94, 0x74, 0xd0, 0x8c, 0x0f, + 0xa7, 0xa8, 0xbb, 0x2e, 0xed, 0x97, 0x71, 0xb6, 0x7e, 0xdb, 0x6d, 0xb6, 0x0e, 0xfc, 0x77, 0xef, + 0xef, 0xe3, 0x0a, 0x32, 0xdb, 0x6f, 0xe1, 0xbc, 0x02, 0xae, 0xb8, 0xdc, 0x1f, 0x6f, 0x7e, 0x2d, + 0xe5, 0xbd, 0xe9, 0xdf, 0x5d, 0x34, 0xc5, 0x51, 0xa1, 0xa9, 0xbf, 0xf0, 0xee, 0x00, 0xa5, 0x44, + 0x4c, 0xc0, 0xb8, 0x9c, 0x5f, 0x6f, 0xde, 0xf7, 0x37, 0x2f, 0x86, 0x21, 0x6a, 0x2f, 0x56, 0x7f, + 0xc4, 0x82, 0x12, 0xb9, 0xf3, 0x68, 0x67, 0x8a, 0x10, 0x1a, 0x5f, 0x47, 0x7d, 0xa5, 0xf6, 0x5d, + 0x24, 0xbc, 0xd2, 0xa8, 0x1b, 0x38, 0x3b, 0xd7, 0xe2, 0x05, 0xef, 0x1b, 0xf2, 0x61, 0xb8, 0x24, + 0x14, 0x2e, 0x29, 0x93, 0x19, 0x9d, 0xf2, 0xc6, 0x92, 0x7f, 0x88, 0x12, 0x26, 0xee, 0xee, 0xed, + 0xb6, 0xe6, 0x0e, 0x20, 0xc9, 0xc8, 0xdb, 0xff, 0xfd, 0x7d, 0xb3, 0xfc, 0xa1, 0xb4, 0x14, 0x00, + 0x1e, 0xda, 0x87, 0x8a, 0xce, 0xa8, 0x34, 0xbf, 0x46, 0x7e, 0x32, 0xad, 0xe2, 0xb3, 0x71, 0x2f, + 0x77, 0xc4, 0xbd, 0x47, 0xfc, 0x53, 0x04, 0xf6, 0xd5, 0xfe, 0x1c, 0x24, 0x03, 0x30, 0x26, 0x86, + 0xb4, 0x22, 0xb4, 0x51, 0xdb, 0xfd, 0x6c, 0xec, 0xf3, 0x25, 0xd8, 0x39, 0xbd, 0x75, 0x8f, 0xb8, + 0xfb, 0xd7, 0x58, 0x74, 0xa4, 0x75, 0xfe, 0x1a, 0x21, 0x40, 0x48, 0xb9, 0x06, 0xe2, 0x56, 0xef, + 0xed, 0xff, 0x6f, 0x12, 0xd0, 0xc5, 0x47, 0x10, 0xe0, 0x4a, 0xe7, 0x4a, 0xc4, 0x44, 0x50, 0xd3, + 0x84, 0x94, 0x93, 0x7f, 0xff, 0xdb, 0x0c, 0x60, 0x0e, 0xe9, 0xc1, 0xc3, 0xfb, 0xfd, 0xee, 0x2a, + 0xb0, 0xce, 0x00, 0x74, 0x33, 0xef, 0x95, 0x65, 0xe7, 0x27, 0xdb, 0xe3, 0xff, 0xc4, 0xb6, 0x7f, + 0x82, 0x63, 0x3b, 0xbb, 0xe2, 0xb7, 0x68, 0x63, 0xb2, 0x5e, 0xfe, 0x14, 0xcd, 0x8b, 0x32, 0x2e, + 0x4f, 0xa3, 0xa9, 0xb1, 0x53, 0x95, 0x6e, 0x20, 0x41, 0x0e, 0xb5, 0xe2, 0x04, 0x82, 0x2d, 0x37, + 0xb1, 0x5c, 0xc6, 0xac, 0x79, 0x71, 0x10, 0x59, 0x55, 0x55, 0x5b, 0xba, 0xa9, 0xba, 0xf0, 0x71, + 0x10, 0x57, 0x24, 0x15, 0xdc, 0xbd, 0x8c, 0x41, 0xea, 0xb6, 0x1e, 0xb8, 0x88, 0xbb, 0x6d, 0x6a, + 0xaa, 0xb8, 0x89, 0xbb, 0xbf, 0x8b, 0x13, 0x97, 0x12, 0xc6, 0x59, 0x3e, 0x98, 0x88, 0x27, 0x19, + 0xc2, 0x8e, 0x1e, 0xf7, 0xf1, 0x31, 0x3c, 0x12, 0x0b, 0xdc, 0x1e, 0x78, 0xe7, 0xc3, 0x04, 0xc1, + 0xa1, 0xfe, 0x3c, 0xde, 0x27, 0x86, 0xc4, 0x44, 0x97, 0xe2, 0x1d, 0x2e, 0xf8, 0xd8, 0xbc, 0xa4, + 0xab, 0x3b, 0x97, 0x24, 0xaf, 0x58, 0xee, 0x45, 0x83, 0x39, 0xe3, 0xe2, 0x75, 0xf8, 0xe7, 0x70, + 0xd1, 0x20, 0x04, 0xf5, 0xc7, 0x29, 0x97, 0xbf, 0xdf, 0xd4, 0xbb, 0x17, 0xf9, 0x2e, 0x1a, 0x21, + 0x40, 0xba, 0xc1, 0x56, 0x7f, 0xff, 0x6d, 0xcc, 0x35, 0x80, 0x76, 0x36, 0x54, 0x7f, 0xed, 0xb7, + 0xfd, 0x85, 0x27, 0x03, 0x54, 0x72, 0x7f, 0xed, 0xb6, 0xdb, 0x6d, 0xb7, 0x0c, 0x60, 0x46, 0x66, + 0x03, 0x4b, 0xaf, 0xbc, 0xff, 0xef, 0x15, 0xb6, 0x17, 0x66, 0x00, 0x1f, 0x3a, 0xcc, 0x8d, 0x86, + 0x82, 0xdc, 0xff, 0x07, 0x6e, 0xdb, 0xb7, 0x9f, 0xd7, 0x1c, 0xff, 0xe7, 0xc1, 0x09, 0x05, 0x62, + 0x47, 0x8a, 0xed, 0x24, 0x6f, 0x41, 0x9e, 0x97, 0x90, 0x34, 0xbb, 0x9b, 0x84, 0xef, 0x7a, 0xe6, + 0xf8, 0x98, 0xc2, 0x96, 0x12, 0x78, 0x7b, 0x0c, 0xaf, 0x6a, 0x77, 0xad, 0x66, 0x87, 0x10, 0x6a, + 0xaa, 0xfc, 0x46, 0x5f, 0x8f, 0x26, 0x7f, 0xe6, 0xde, 0xfe, 0x53, 0x3b, 0xbf, 0xc2, 0x95, 0xcd, + 0x05, 0xea, 0x1a, 0x2c, 0xaf, 0x51, 0x38, 0x7d, 0xdf, 0x10, 0x59, 0x33, 0xad, 0x7c, 0xa4, 0x5a, + 0xd7, 0x11, 0x77, 0x6a, 0x5b, 0x2d, 0xf8, 0x44, 0x44, 0xa3, 0x08, 0x1d, 0xfb, 0x18, 0x4d, 0xb1, + 0x8a, 0x0f, 0x7d, 0x22, 0x88, 0x88, 0x0d, 0xfb, 0x03, 0xc0, 0x18, 0x41, 0x61, 0xa3, 0xb9, 0xf5, + 0x51, 0x75, 0xd4, 0x5c, 0xa9, 0xc1, 0x00, 0x14, 0x41, 0x78, 0xa0, 0x64, 0xf8, 0xa4, 0xfd, 0xd4, + 0xb5, 0x5d, 0x02, 0x95, 0x74, 0x8f, 0xe2, 0x1e, 0xd7, 0x81, 0xa0, 0x32, 0x34, 0x83, 0x84, 0xf8, + 0x51, 0x6a, 0x0c, 0x61, 0xe0, 0xe0, 0x96, 0x21, 0xf3, 0xb8, 0x54, 0x8b, 0xc4, 0xaf, 0x8f, 0x48, + 0x23, 0x04, 0x44, 0xe1, 0x77, 0xe4, 0x40, 0x00, 0x6b, 0xcc, 0xd2, 0xe2, 0xf2, 0xbf, 0x1d, 0xa1, + 0x78, 0x9a, 0x06, 0xa0, 0x5e, 0x3e, 0xf1, 0xa7, 0xc2, 0x00, 0xe4, 0x6e, 0x72, 0x8b, 0x52, 0xf8, + 0x1e, 0x25, 0x58, 0x76, 0x35, 0x2a, 0x83, 0xa2, 0xbe, 0x1d, 0x1f, 0x7e, 0x26, 0x63, 0xe2, 0x1b, + 0xd1, 0x23, 0xfd, 0xb0, 0x3e, 0xa0, 0x01, 0xf7, 0x76, 0xd5, 0x38, 0x6d, 0x94, 0x01, 0x1e, 0xce, + 0x59, 0x06, 0x17, 0x85, 0x74, 0xff, 0xbf, 0x8a, 0xbb, 0x83, 0xb7, 0xf1, 0x5a, 0x9e, 0x2d, 0xcb, + 0x78, 0x9d, 0x01, 0x75, 0xf8, 0x5f, 0xdc, 0x36, 0xc4, 0x80, 0x96, 0x7a, 0xe7, 0x5f, 0xfe, 0x7a, + 0xc4, 0x7a, 0x7a, 0x69, 0xf0, 0x5d, 0x7e, 0x2a, 0xcf, 0x58, 0x69, 0x40, 0x2f, 0xd9, 0x12, 0x19, + 0xdf, 0xfa, 0x69, 0xe9, 0xa6, 0xec, 0x39, 0x80, 0x22, 0xfa, 0xe6, 0xfc, 0xff, 0xa7, 0x6d, 0x3b, + 0x6d, 0xa2, 0x24, 0xbf, 0x6d, 0xb8, 0x6e, 0x40, 0x02, 0x47, 0x4d, 0xc6, 0x03, 0x36, 0x7e, 0xf3, + 0xf7, 0x77, 0x9e, 0xf5, 0x6c, 0xdc, 0x53, 0x22, 0xfe, 0x9c, 0x36, 0x48, 0x13, 0x3b, 0x45, 0xff, + 0xff, 0x1a, 0x7c, 0x64, 0xfa, 0xe6, 0xda, 0xdb, 0x07, 0x68, 0xee, 0xdc, 0xd1, 0xf0, 0xb7, 0x09, + 0x19, 0xef, 0xbd, 0xd7, 0x2d, 0xeb, 0x5c, 0x54, 0x90, 0x53, 0x6a, 0xb3, 0x09, 0x2d, 0x83, 0xae, + 0x6e, 0xab, 0x89, 0x88, 0xae, 0x30, 0x83, 0xcd, 0x4f, 0x1f, 0x64, 0xf1, 0x23, 0x9b, 0xab, 0x14, + 0x2f, 0x4b, 0xc4, 0xd5, 0x3f, 0xab, 0x4b, 0x8e, 0xd6, 0xab, 0x5a, 0xea, 0xb1, 0x26, 0x2d, 0xe5, + 0x63, 0xc4, 0xd8, 0xe9, 0xb6, 0x30, 0x08, 0xeb, 0xc4, 0x05, 0x49, 0xe2, 0xb2, 0x87, 0x14, 0x06, + 0xbd, 0x2f, 0xfe, 0x9a, 0x7a, 0x49, 0x2b, 0x6d, 0xe9, 0xa7, 0xe0, 0x11, 0x18, 0x2d, 0xee, 0xe8, + 0x7a, 0xbf, 0x01, 0x12, 0x10, 0x2d, 0x8f, 0x58, 0x78, 0x90, 0x0e, 0xd6, 0xae, 0x3f, 0xfb, 0x7b, + 0x6d, 0x86, 0xd4, 0x3f, 0x74, 0xda, 0xf8, 0x71, 0x40, 0xf5, 0x7b, 0xf4, 0xd3, 0xd3, 0xe9, 0xef, + 0x49, 0x2a, 0x7f, 0x0f, 0x28, 0x03, 0xda, 0xba, 0xe5, 0xff, 0xf4, 0xed, 0x8c, 0x66, 0xf6, 0xed, + 0xf8, 0x0d, 0x10, 0x40, 0x34, 0x40, 0xd2, 0xc5, 0xc8, 0xd4, 0x00, 0x92, 0x3f, 0x9c, 0xb8, 0xac, + 0xf2, 0xc3, 0x17, 0x17, 0x50, 0x52, 0x63, 0x1c, 0x22, 0xe1, 0x56, 0xac, 0x74, 0x03, 0xc0, 0xc7, + 0xa1, 0xe7, 0xc5, 0x16, 0x24, 0x6a, 0xdc, 0x1a, 0x6c, 0x1d, 0xac, 0x39, 0x12, 0x00, 0xfa, 0xe3, + 0xe2, 0x17, 0xe5, 0xdc, 0xa1, 0x50, 0xba, 0x13, 0xcd, 0xf8, 0x1d, 0xb9, 0x61, 0xd7, 0xc9, 0x06, + 0x3a, 0x8e, 0xe6, 0xc1, 0xd9, 0x54, 0x0b, 0x10, 0x07, 0xe9, 0xdb, 0xb7, 0x0e, 0xe0, 0x0b, 0xd1, + 0xf0, 0x22, 0x1f, 0xbb, 0x89, 0xff, 0xfd, 0x8e, 0x4f, 0xa9, 0xe7, 0x1e, 0xfc, 0xac, 0x67, 0x89, + 0x62, 0xdf, 0x52, 0xec, 0xbb, 0xcd, 0x11, 0x6c, 0xbb, 0x29, 0x0a, 0xb2, 0x37, 0x7d, 0xe8, 0x81, + 0x55, 0x7a, 0x4b, 0xec, 0x06, 0x48, 0x31, 0x1b, 0x91, 0x7f, 0x10, 0xe3, 0x47, 0xb8, 0x1d, 0x05, + 0x45, 0xca, 0x78, 0x3d, 0xdc, 0xbf, 0x59, 0x99, 0x22, 0xc9, 0x11, 0x0d, 0x7e, 0xdd, 0xac, 0x3a, + 0x88, 0x00, 0x50, 0x56, 0x7d, 0xce, 0xc1, 0x2c, 0xd3, 0xc4, 0x3f, 0x83, 0x1f, 0x8a, 0xc7, 0xff, + 0x72, 0xda, 0xcd, 0x45, 0x76, 0x02, 0x20, 0x61, 0xd7, 0x5e, 0x1d, 0xfa, 0x1e, 0x70, 0x00, 0x87, + 0x21, 0x6e, 0xae, 0x94, 0xe8, 0xec, 0x9a, 0x67, 0x3a, 0x38, 0xfd, 0x31, 0xb5, 0x7d, 0x97, 0x71, + 0x97, 0x60, 0xfb, 0x97, 0x71, 0x8d, 0xf0, 0x32, 0xf0, 0xe8, 0x87, 0xcc, 0x0f, 0x07, 0x4d, 0x38, + 0x31, 0x7d, 0x4f, 0xfb, 0x28, 0x71, 0x61, 0xab, 0xf3, 0x84, 0xf9, 0x79, 0xe0, 0xef, 0x90, 0xcf, + 0x7a, 0xe4, 0x1b, 0x37, 0xfd, 0x9a, 0x56, 0xab, 0x90, 0x8d, 0x3f, 0xe2, 0x2e, 0x96, 0xb5, 0xf8, + 0x8c, 0xbe, 0x9e, 0x9a, 0x27, 0xf0, 0x87, 0x1a, 0x38, 0x6a, 0xaf, 0x25, 0x8e, 0xed, 0x62, 0xf1, + 0x13, 0xae, 0x2a, 0xba, 0x33, 0x79, 0x48, 0x5f, 0xc2, 0x55, 0xd5, 0xa8, 0xb8, 0x9e, 0x78, 0x40, + 0xaa, 0xb5, 0xd5, 0x8e, 0xb5, 0x5c, 0x11, 0x12, 0x58, 0x5b, 0x8b, 0xe0, 0x9a, 0xea, 0xb4, 0xca, + 0x9a, 0x6d, 0x63, 0xea, 0xa2, 0x26, 0x2f, 0x36, 0x28, 0x1e, 0x44, 0x2b, 0xf0, 0x34, 0xc1, 0x61, + 0x74, 0x96, 0x2e, 0x2e, 0xb1, 0x75, 0x14, 0xdf, 0x0d, 0x60, 0x05, 0x2f, 0x54, 0xbb, 0x5a, 0x69, + 0xe9, 0xdb, 0xf3, 0xc3, 0x77, 0x08, 0x82, 0x10, 0xa4, 0x3b, 0x56, 0x76, 0x22, 0xc7, 0x7c, 0x56, + 0x24, 0x1f, 0xd5, 0x5a, 0x0e, 0xfa, 0xa9, 0xfe, 0xe6, 0x1a, 0xc1, 0x28, 0x67, 0x56, 0xfd, 0x3f, + 0xf6, 0xdb, 0x1f, 0x61, 0xa5, 0x01, 0xdb, 0xe5, 0x7f, 0xed, 0xb7, 0xb6, 0xde, 0x58, 0x78, 0x90, + 0x3a, 0xe6, 0x8f, 0xff, 0x4f, 0x84, 0xa5, 0x85, 0x6d, 0x70, 0x35, 0x45, 0xee, 0x06, 0x4c, 0x7e, + 0xe0, 0xe4, 0x28, 0x20, 0x53, 0x8a, 0x6a, 0x6a, 0x1e, 0x69, 0x24, 0x0c, 0x75, 0x1d, 0xf0, 0xb1, + 0x3c, 0x17, 0x14, 0xc5, 0x31, 0x1c, 0x3c, 0xe7, 0x11, 0xf4, 0x49, 0x21, 0xde, 0x05, 0x08, 0x52, + 0x5a, 0x79, 0x51, 0xc7, 0xcc, 0xcd, 0x21, 0x68, 0xb9, 0x55, 0x8a, 0xcf, 0x87, 0x21, 0x3f, 0xd1, + 0x8a, 0xc1, 0x8c, 0x28, 0x75, 0x15, 0x49, 0x28, 0x31, 0xc4, 0x08, 0x38, 0xc1, 0xa9, 0x3d, 0x6a, + 0x3c, 0x1c, 0xb3, 0x45, 0xd2, 0x38, 0xc2, 0x54, 0xfe, 0x74, 0x77, 0x82, 0x91, 0x21, 0x43, 0x1e, + 0x38, 0xe9, 0x55, 0x41, 0xb3, 0x4e, 0x01, 0xc2, 0x67, 0x05, 0x04, 0x3c, 0xb9, 0x7b, 0x34, 0x9d, + 0xc1, 0x60, 0xcb, 0x01, 0xdf, 0x81, 0x00, 0x40, 0xd8, 0xb8, 0x3a, 0x58, 0x51, 0x58, 0x3c, 0x03, + 0xc7, 0x6d, 0x3d, 0x89, 0xe0, 0x01, 0xc3, 0xac, 0x56, 0x4b, 0x56, 0xcb, 0x31, 0x52, 0x08, 0x8a, + 0x51, 0x58, 0x76, 0x25, 0x1c, 0x6c, 0xe1, 0x28, 0xc2, 0xf9, 0x6e, 0x5f, 0xe1, 0xfc, 0xe7, 0x34, + 0xc0, 0x00, 0x48, 0x65, 0x50, 0xbd, 0x9e, 0x72, 0x54, 0x22, 0x4b, 0xeb, 0x14, 0x58, 0xc5, 0x98, + 0x61, 0xbe, 0x4e, 0xaa, 0x4c, 0x41, 0x31, 0x7f, 0xdc, 0x62, 0x3a, 0x7a, 0xe2, 0x24, 0xcf, 0x26, + 0x2e, 0xb8, 0x82, 0xae, 0xaa, 0xbf, 0x94, 0xd2, 0xff, 0xc1, 0x19, 0x47, 0xd3, 0x3d, 0x02, 0x9e, + 0xfa, 0x1a, 0xc5, 0xc0, 0xd3, 0x05, 0x86, 0x55, 0x51, 0x75, 0xd2, 0x51, 0x72, 0xe3, 0x72, 0x2c, + 0x38, 0xa0, 0x94, 0xf2, 0xa5, 0xfe, 0x9f, 0xf4, 0xe3, 0x74, 0xd3, 0xf8, 0x51, 0x40, 0x08, 0x5d, + 0x49, 0x32, 0x04, 0x6a, 0xef, 0xbd, 0x34, 0xed, 0xb7, 0x56, 0xdb, 0x87, 0x88, 0x20, 0x00, 0x46, + 0x60, 0xf1, 0x3e, 0xe5, 0x24, 0xff, 0xbf, 0xfb, 0x76, 0x62, 0xda, 0x30, 0x75, 0x70, 0x7f, 0xc5, + 0xb5, 0x9f, 0x1f, 0xf0, 0x7c, 0xc2, 0x8f, 0xb6, 0xbb, 0x65, 0xef, 0xc8, 0x6d, 0x40, 0x0c, 0x50, + 0x56, 0xe3, 0x99, 0xdd, 0xdf, 0x3b, 0xfc, 0xda, 0x99, 0x76, 0x2d, 0xe2, 0xd8, 0xb6, 0x27, 0x42, + 0x32, 0xc4, 0x74, 0x41, 0xd4, 0xd3, 0x38, 0x6a, 0x58, 0x0b, 0x87, 0x51, 0x46, 0x9f, 0x5f, 0xf8, + 0xb6, 0x9e, 0x9a, 0x61, 0xb9, 0x43, 0x0c, 0x7e, 0x0e, 0xda, 0x0e, 0x36, 0xe2, 0xd0, 0x39, 0xb6, + 0x1c, 0x50, 0x02, 0x6e, 0xc4, 0xb6, 0x19, 0xd5, 0xbd, 0xf4, 0xd5, 0x6d, 0xb5, 0x58, 0xd2, 0x9c, + 0xe8, 0x80, 0x11, 0xe0, 0x50, 0x00, 0x21, 0xa7, 0x81, 0xe3, 0x86, 0x41, 0x94, 0x6b, 0x92, 0xc0, + 0x18, 0xd9, 0x90, 0x3a, 0x64, 0xc7, 0x81, 0x84, 0x20, 0x20, 0x81, 0x4a, 0xdf, 0x14, 0x63, 0xbe, + 0xb4, 0xc5, 0x18, 0x10, 0x43, 0x01, 0x49, 0x47, 0x8a, 0x54, 0x1e, 0xd4, 0x9a, 0xae, 0xd1, 0x80, + 0xbc, 0x33, 0x05, 0xc0, 0x67, 0xa4, 0x0b, 0x86, 0x60, 0xb8, 0x40, 0x24, 0xe0, 0xf8, 0x16, 0x19, + 0x66, 0x23, 0x83, 0xd6, 0x39, 0x84, 0x04, 0xe8, 0x15, 0x2a, 0x6f, 0x24, 0x11, 0x8f, 0x8e, 0x0e, + 0x1b, 0x70, 0x22, 0x77, 0x2d, 0x57, 0xa4, 0xdd, 0xdc, 0xdf, 0x62, 0x35, 0x2b, 0xd7, 0x2e, 0xc5, + 0xd5, 0x8b, 0x56, 0xf7, 0x79, 0x8e, 0x77, 0x58, 0xac, 0xd5, 0x2a, 0x11, 0x36, 0xaf, 0x97, 0xab, + 0x78, 0x73, 0x00, 0x08, 0x87, 0x32, 0x46, 0x3c, 0x6c, 0x70, 0xa5, 0x74, 0xf4, 0xe2, 0xac, 0x40, + 0xef, 0x1c, 0x07, 0xf0, 0x3a, 0x0f, 0xa9, 0x79, 0xc4, 0xc8, 0x0b, 0x04, 0x27, 0x4b, 0x6b, 0x80, + 0xb1, 0x02, 0x48, 0x52, 0x24, 0x7d, 0x73, 0x73, 0xc0, 0xf2, 0xa8, 0x26, 0x44, 0xa5, 0x4e, 0x00, + 0xe1, 0x38, 0x1f, 0x15, 0x45, 0xe6, 0x64, 0x4b, 0x32, 0x2b, 0xbc, 0x37, 0x3a, 0x1e, 0x04, 0x30, + 0x11, 0x48, 0x2a, 0xe0, 0x22, 0x40, 0x82, 0x14, 0xe9, 0xec, 0xb3, 0xbf, 0x05, 0x79, 0xf6, 0x9b, + 0xaa, 0x33, 0xbd, 0x24, 0xbb, 0xe1, 0x62, 0xac, 0xb9, 0x78, 0x3c, 0x0f, 0x02, 0xa0, 0xaa, 0x10, + 0x8c, 0x42, 0x3c, 0x1a, 0x97, 0x6b, 0x34, 0x47, 0xf0, 0x73, 0x8a, 0x37, 0x15, 0xbb, 0xe3, 0x61, + 0x1f, 0x01, 0x82, 0x20, 0x14, 0x0d, 0xb4, 0x7c, 0xaa, 0xd1, 0xb1, 0xd9, 0x96, 0x1c, 0x50, 0x06, + 0xff, 0x50, 0x96, 0x79, 0xa9, 0xa4, 0x96, 0x91, 0x37, 0xd8, 0x5a, 0x78, 0xa9, 0xa7, 0xfe, 0x01, + 0x41, 0x05, 0x21, 0x43, 0x0d, 0xab, 0x30, 0xf7, 0x36, 0xc9, 0x7e, 0x59, 0xc4, 0xf0, 0x4f, 0x1e, + 0x3a, 0xb0, 0x4f, 0x01, 0x60, 0xa1, 0x62, 0xc2, 0x11, 0xa4, 0x2c, 0xa0, 0x79, 0x60, 0xea, 0x9c, + 0x0d, 0x0e, 0x00, 0xe1, 0x60, 0x06, 0xdc, 0x25, 0xae, 0x3a, 0xa2, 0x78, 0x3a, 0xb0, 0xb7, 0x5b, + 0xc8, 0xba, 0x65, 0x00, 0x38, 0x01, 0xe1, 0x3c, 0x1f, 0xf2, 0xee, 0x9c, 0x3d, 0x80, 0x38, 0x39, + 0x18, 0x3a, 0xaf, 0x7f, 0xb6, 0x5e, 0x5f, 0xba, 0x69, 0xe7, 0x82, 0x8d, 0xbd, 0xb6, 0xd3, 0xc1, + 0xff, 0x4e, 0x18, 0x50, 0x25, 0xa4, 0xea, 0x6f, 0xf4, 0xff, 0xe9, 0x94, 0x3c, 0xa0, 0x04, 0x9f, + 0x5a, 0x62, 0xef, 0x71, 0xe9, 0xf4, 0x6b, 0x2d, 0x70, 0x76, 0xed, 0xd2, 0x26, 0xdb, 0xfe, 0x1c, + 0x50, 0x06, 0x21, 0xe6, 0x8e, 0x1d, 0xf3, 0xd6, 0xb2, 0x57, 0xe5, 0x83, 0x3c, 0x71, 0xff, 0x3f, + 0x2a, 0x32, 0xa6, 0x9a, 0x7f, 0x82, 0x10, 0x28, 0x85, 0x23, 0x89, 0xe0, 0x90, 0x73, 0x4c, 0xb0, + 0x65, 0x83, 0x14, 0x62, 0x07, 0x9b, 0x93, 0x55, 0xba, 0xa1, 0x6c, 0xe1, 0xed, 0xc2, 0xde, 0x90, + 0x61, 0xd4, 0x70, 0x0b, 0x96, 0xc0, 0x9d, 0x0d, 0xcf, 0xe9, 0xff, 0xee, 0x53, 0x4f, 0x2e, 0xa5, + 0xe0, 0x84, 0x48, 0x50, 0x91, 0xbb, 0x30, 0x3e, 0xd3, 0x0a, 0xf2, 0x27, 0x14, 0x29, 0x71, 0x91, + 0x03, 0x42, 0x05, 0xbd, 0x53, 0xf7, 0xcc, 0xc5, 0xe2, 0xe1, 0x18, 0x50, 0x85, 0xb0, 0xe8, 0xfc, + 0x94, 0x06, 0x9a, 0x93, 0xec, 0x37, 0x1b, 0xa7, 0xbb, 0x92, 0xf1, 0x75, 0x08, 0xad, 0x26, 0xcc, + 0x18, 0x59, 0xab, 0x06, 0xe2, 0x83, 0xb9, 0xe8, 0xc3, 0x03, 0x48, 0x21, 0x1b, 0xf1, 0xb5, 0xe3, + 0x0a, 0xe7, 0x2c, 0x1e, 0xc1, 0x16, 0xb0, 0x25, 0x15, 0x72, 0x40, 0x69, 0xd8, 0xb7, 0xb2, 0x7b, + 0x7f, 0x85, 0x7b, 0x2a, 0xae, 0x37, 0x94, 0xfa, 0xa8, 0xa0, 0xa2, 0x30, 0x2b, 0x97, 0x29, 0xf1, + 0xc7, 0x4f, 0xfa, 0x50, 0xe2, 0x83, 0x18, 0x45, 0xe1, 0xf7, 0x5e, 0xde, 0x7e, 0x73, 0x2b, 0xe4, + 0x6e, 0xb6, 0xf3, 0x3a, 0xdb, 0xa7, 0xf8, 0x0b, 0x90, 0x80, 0x53, 0x07, 0xf8, 0x2e, 0x5a, 0x84, + 0x70, 0x50, 0xea, 0x53, 0x73, 0xbc, 0x5c, 0xa7, 0x52, 0x5a, 0x97, 0x9e, 0x3d, 0xac, 0xa5, 0x58, + 0x1e, 0x00, 0x48, 0x85, 0x2a, 0x6d, 0x16, 0x8e, 0xe1, 0xf0, 0xf9, 0x14, 0x42, 0x5c, 0xb0, 0xec, + 0x4b, 0x53, 0x8a, 0x31, 0x58, 0xac, 0xd1, 0xc0, 0x78, 0x10, 0x61, 0x49, 0xf1, 0xfa, 0xea, 0x49, + 0xe7, 0x8e, 0xd8, 0x78, 0x79, 0xc0, 0x1f, 0x65, 0xd1, 0x46, 0xfe, 0x58, 0x64, 0x95, 0x3f, 0xdb, + 0xc5, 0x10, 0x74, 0xf0, 0xf3, 0x80, 0x05, 0xd9, 0xd3, 0x17, 0x52, 0x23, 0x85, 0x73, 0xe7, 0xf6, + 0xc9, 0xd5, 0xc7, 0xbc, 0x56, 0x0e, 0xbe, 0x4e, 0x1e, 0x2d, 0x9e, 0x06, 0x04, 0x8e, 0xbf, 0xbf, + 0x01, 0x32, 0x18, 0x0a, 0x19, 0x6a, 0x95, 0x83, 0x52, 0x57, 0xd5, 0x0e, 0x80, 0x0f, 0x07, 0x40, + 0x03, 0xc1, 0xd7, 0x87, 0x8d, 0x0b, 0xd5, 0xb9, 0x6b, 0x14, 0x5a, 0x07, 0xd4, 0x85, 0x88, 0x63, + 0xae, 0x02, 0x40, 0x40, 0x50, 0xe0, 0x6b, 0xb9, 0x0b, 0x51, 0x28, 0x12, 0x09, 0xc1, 0xe1, 0x61, + 0x52, 0xc0, 0x1b, 0xc9, 0x13, 0xbe, 0x2c, 0xf8, 0x73, 0x85, 0x80, 0x0c, 0xf0, 0x1f, 0x7e, 0xa0, + 0x3a, 0x06, 0xa5, 0x81, 0x00, 0x18, 0x02, 0xb8, 0x90, 0x7b, 0xf0, 0xf1, 0xfb, 0x4e, 0xbb, 0xcd, + 0x94, 0x77, 0x82, 0x10, 0xc8, 0xc8, 0xb6, 0x21, 0x61, 0x33, 0x85, 0x85, 0xbf, 0x9a, 0xd8, 0x81, + 0xb3, 0x6a, 0x37, 0xf4, 0x6a, 0xa3, 0xf8, 0x1d, 0xc4, 0xa0, 0xdd, 0x47, 0xb2, 0x54, 0x31, 0x4a, + 0x3a, 0xf8, 0x53, 0x11, 0x62, 0xd6, 0xcb, 0x48, 0x35, 0x8f, 0x96, 0x0a, 0x90, 0x6a, 0xaf, 0x07, + 0x3c, 0x5d, 0xd4, 0x38, 0x1e, 0xf4, 0x07, 0x00, 0xf9, 0x3d, 0xc3, 0xd6, 0x4b, 0x75, 0x05, 0xca, + 0xa2, 0xf0, 0x10, 0xf7, 0xd5, 0x5f, 0x37, 0x8c, 0x8f, 0x1f, 0x18, 0x4a, 0x9a, 0x4c, 0x99, 0x3e, + 0xe9, 0x5f, 0x47, 0x1b, 0x41, 0x0f, 0x11, 0xae, 0x10, 0xa4, 0x97, 0x77, 0x71, 0x5b, 0x85, 0x9a, + 0x3f, 0x94, 0x3c, 0x8e, 0x00, 0x68, 0x1a, 0x92, 0x93, 0xf1, 0x1e, 0xeb, 0x2b, 0x78, 0xbf, 0x4a, + 0x78, 0x3c, 0x55, 0xb7, 0xdb, 0xd7, 0xa0, 0xbe, 0x1a, 0x24, 0x00, 0xbe, 0x95, 0xf3, 0xfb, 0xfb, + 0xed, 0xd3, 0x6d, 0xbd, 0x34, 0xee, 0x99, 0x7a, 0x75, 0x0e, 0x22, 0x00, 0x30, 0x84, 0x0f, 0x72, + 0x39, 0x50, 0x22, 0xf7, 0xf4, 0x8a, 0xb6, 0xdc, 0x16, 0x07, 0x60, 0xea, 0x3b, 0x4d, 0x44, 0xb8, + 0x9a, 0x7a, 0xc6, 0xce, 0xd9, 0xde, 0x3a, 0x8a, 0xa9, 0x83, 0xff, 0x7b, 0xde, 0x1d, 0x70, 0x02, + 0xa6, 0xf8, 0x35, 0x94, 0xeb, 0x10, 0xbb, 0x3f, 0x24, 0x07, 0x37, 0xd5, 0x77, 0x46, 0xcf, 0x8e, + 0x6e, 0xce, 0xcf, 0xc6, 0x98, 0x68, 0x14, 0x9e, 0x0c, 0xe0, 0x38, 0x70, 0x9b, 0xb7, 0x3f, 0x58, + 0xf0, 0xdb, 0x80, 0x38, 0x5c, 0x10, 0xad, 0x79, 0xbb, 0xd5, 0xc2, 0x9a, 0x5e, 0xf8, 0x66, 0x8d, + 0x8f, 0x43, 0xbc, 0x57, 0x5e, 0xec, 0xa1, 0xb7, 0x00, 0xb4, 0x72, 0x15, 0xc8, 0x14, 0x8f, 0x06, + 0x26, 0x6e, 0x64, 0xc3, 0x72, 0x5d, 0x8c, 0x3b, 0x18, 0x2a, 0x2e, 0x83, 0xb7, 0x3c, 0x16, 0x26, + 0xb8, 0x35, 0x1b, 0xa0, 0xf8, 0x16, 0x4f, 0xfa, 0xe0, 0x50, 0x02, 0xc0, 0xd8, 0x7b, 0x94, 0x90, + 0xe0, 0xc0, 0x06, 0xa4, 0x78, 0x06, 0x55, 0x55, 0x3b, 0x06, 0x2c, 0x01, 0x60, 0x3a, 0x00, 0x58, + 0x2e, 0x03, 0xe3, 0x12, 0x80, 0x04, 0x81, 0x54, 0x4c, 0x25, 0x1f, 0x00, 0x02, 0x59, 0x64, 0x00, + 0x0b, 0x2c, 0x3c, 0x00, 0x04, 0x00, 0x30, 0x37, 0xb0, 0x02, 0x3a, 0x7c, 0x00, 0x04, 0x01, 0xb8, + 0x28, 0x31, 0x80, 0x00, 0xaf, 0x27, 0x4f, 0xc3, 0x6e, 0x00, 0x4e, 0x68, 0x73, 0x43, 0xe6, 0x5a, + 0x87, 0x7f, 0xa3, 0x79, 0x10, 0xfb, 0x85, 0x1e, 0xb7, 0x7a, 0xc3, 0x5e, 0x4a, 0x50, 0x0e, 0xc2, + 0x61, 0xa6, 0x8d, 0x80, 0xfe, 0x6d, 0x07, 0xa0, 0x43, 0xf5, 0xbd, 0xf8, 0x64, 0x74, 0xb3, 0x2f, + 0x0a, 0x57, 0x24, 0xac, 0x56, 0x2b, 0xcf, 0x9e, 0x22, 0x14, 0xcf, 0xb1, 0x56, 0x59, 0x97, 0x88, + 0xf3, 0x87, 0x26, 0xfc, 0x96, 0x0f, 0xcf, 0xf2, 0x97, 0x06, 0xdf, 0xb0, 0xef, 0x10, 0x4b, 0xd9, + 0xee, 0xef, 0x82, 0x33, 0xda, 0x56, 0x9a, 0xb9, 0x89, 0x6a, 0xbe, 0x1d, 0x33, 0xe3, 0xd5, 0xa0, + 0x9c, 0x7f, 0x45, 0xcd, 0x8a, 0xa8, 0xc9, 0x2a, 0x7f, 0xe2, 0xf5, 0x31, 0xa8, 0x48, 0x8f, 0x08, + 0x87, 0xf8, 0x92, 0xb7, 0x3f, 0xbf, 0xdf, 0xeb, 0x88, 0xbb, 0xe7, 0xb9, 0x7b, 0xe2, 0x44, 0xb3, + 0x6c, 0xea, 0x29, 0xb7, 0x6a, 0xc3, 0xa4, 0x20, 0x00, 0x23, 0x24, 0x3f, 0xe4, 0x42, 0x3b, 0xd8, + 0x27, 0xff, 0xb6, 0xda, 0xa7, 0x03, 0xa8, 0xba, 0x29, 0x0b, 0xc2, 0xa0, 0x54, 0xb9, 0xff, 0x0a, + 0xbd, 0x0e, 0x10, 0xc0, 0x01, 0x20, 0xac, 0x2b, 0x8b, 0xda, 0x43, 0xa9, 0x0f, 0xdd, 0xa8, 0x50, + 0xe0, 0x17, 0x0a, 0x61, 0xc3, 0x91, 0xa5, 0xae, 0xb3, 0xc5, 0x8a, 0x0b, 0x3f, 0xac, 0x1c, 0x65, + 0x88, 0x97, 0xe1, 0x94, 0x6f, 0xaf, 0x1c, 0x70, 0xda, 0x80, 0x16, 0x8e, 0xcc, 0x37, 0x10, 0xd9, + 0x15, 0x3b, 0x5d, 0x8d, 0xf3, 0x83, 0xbc, 0x63, 0x72, 0xe0, 0x54, 0x50, 0xc7, 0xfc, 0x2f, 0xcb, + 0x42, 0xdb, 0x38, 0x9c, 0x2b, 0x2e, 0x58, 0x3f, 0x8b, 0x60, 0x66, 0xc1, 0xa9, 0xb3, 0x93, 0x69, + 0xc3, 0x0e, 0xc7, 0xe1, 0xbc, 0x00, 0x69, 0x9c, 0x9a, 0xaf, 0xa2, 0x72, 0xad, 0x50, 0x94, 0xb1, + 0xb3, 0x8d, 0xbb, 0xe4, 0x67, 0xcc, 0xc5, 0x38, 0xa4, 0x0f, 0xeb, 0xcc, 0xd1, 0x4d, 0xd5, 0x9f, + 0xed, 0xe5, 0x15, 0x87, 0xb0, 0xaf, 0x85, 0x52, 0x0a, 0x9e, 0xbe, 0xde, 0x5d, 0xf0, 0xde, 0x00, + 0xee, 0x50, 0x7f, 0x5c, 0x32, 0x60, 0xd7, 0x7b, 0xf9, 0x28, 0xe2, 0x1a, 0xca, 0xe3, 0xac, 0x5b, + 0x1c, 0x6e, 0x5a, 0xdc, 0xff, 0x0b, 0xaa, 0xec, 0x33, 0x1d, 0x7a, 0x6a, 0xb6, 0xf0, 0x41, 0x1b, + 0xa0, 0xa3, 0x12, 0xf5, 0xf6, 0x11, 0xf8, 0x04, 0xe2, 0xdd, 0x5b, 0x00, 0xfa, 0xc8, 0x01, 0x18, + 0x5b, 0x01, 0x2b, 0xb0, 0x00, 0xaa, 0x70, 0x99, 0xf6, 0x1d, 0x80, 0x00, 0x80, 0x2a, 0x8b, 0x18, + 0x83, 0x0a, 0xa4, 0xe0, 0x00, 0xf9, 0x84, 0x0f, 0x29, 0xf0, 0x53, 0x75, 0xa1, 0x8c, 0x06, 0x9c, + 0x71, 0xde, 0x3c, 0x16, 0x4f, 0x04, 0x80, 0x24, 0x0e, 0x00, 0x8c, 0xbd, 0xb8, 0xa0, 0xb1, 0x2e, + 0xe0, 0x69, 0x07, 0x23, 0x2a, 0x01, 0x30, 0x6e, 0xb0, 0x2a, 0x50, 0xb4, 0xb5, 0x6f, 0x54, 0x0f, + 0x6f, 0x68, 0x33, 0x5b, 0x9b, 0x02, 0x24, 0x2d, 0xe2, 0x04, 0x05, 0x04, 0xd5, 0x55, 0x49, 0xe9, + 0xf1, 0xb5, 0x6e, 0x63, 0xbd, 0x01, 0xe6, 0xe2, 0x44, 0x8c, 0x27, 0x2e, 0x64, 0x93, 0xdc, 0xfd, + 0xbe, 0xc6, 0xd3, 0x36, 0xf0, 0x41, 0xc0, 0xd2, 0x0a, 0x46, 0xf5, 0xb3, 0x26, 0x0c, 0x7f, 0x8f, + 0x3e, 0x24, 0xc5, 0x02, 0x10, 0xc0, 0x6d, 0xd8, 0xec, 0x63, 0x3e, 0xa7, 0xfe, 0x0e, 0x42, 0x23, + 0x68, 0x5e, 0x42, 0x3c, 0x7b, 0x6a, 0xeb, 0xd3, 0x76, 0x1f, 0xda, 0xce, 0xe3, 0xb3, 0x3c, 0xf2, + 0x40, 0xe0, 0xb8, 0x51, 0x4a, 0x64, 0x22, 0x4b, 0xd1, 0xc5, 0xb2, 0x7f, 0x31, 0x56, 0xbf, 0x17, + 0x55, 0x55, 0x5a, 0xc3, 0x5c, 0xb2, 0x47, 0x43, 0x5c, 0xc2, 0x0b, 0x9d, 0x76, 0x7a, 0xdb, 0xf2, + 0x4a, 0x4d, 0x84, 0x5d, 0xbf, 0xc6, 0x61, 0xed, 0x2b, 0x50, 0xca, 0x3b, 0xa4, 0x93, 0x56, 0x97, + 0xc6, 0x67, 0x6f, 0x10, 0x3e, 0x2b, 0x77, 0x3e, 0x3f, 0x1c, 0x56, 0xfc, 0x39, 0xa7, 0x89, 0x8e, + 0x8f, 0xa6, 0x3a, 0x3f, 0x8e, 0xbf, 0xa3, 0x9e, 0x26, 0x3c, 0xe4, 0x62, 0xb9, 0xbc, 0xac, 0xc8, + 0x90, 0xdc, 0x28, 0x21, 0x99, 0x28, 0x78, 0x82, 0x80, 0x25, 0x08, 0xc7, 0x2f, 0x4c, 0xe1, 0x9f, + 0x55, 0xb7, 0xbb, 0x22, 0x7f, 0x03, 0x5b, 0x52, 0xe7, 0x4c, 0x58, 0xa4, 0x83, 0x9e, 0x80, 0xfc, + 0x7b, 0xc7, 0x5f, 0x7f, 0x04, 0xac, 0x31, 0xe5, 0x76, 0xde, 0x2a, 0xe6, 0xa8, 0x42, 0x9c, 0x6c, + 0xe3, 0xd0, 0xf6, 0x01, 0x1e, 0xa9, 0x8f, 0xb6, 0x52, 0xdd, 0xbf, 0xfe, 0x4e, 0x4f, 0x22, 0x84, + 0x30, 0x1f, 0xc7, 0xf8, 0x31, 0x04, 0x20, 0xae, 0x0c, 0xa5, 0x7c, 0x19, 0xf9, 0x17, 0x54, 0x85, + 0x34, 0xc9, 0xea, 0x4e, 0x10, 0xe2, 0x80, 0x07, 0xe8, 0x3c, 0xb6, 0xb5, 0x48, 0xf9, 0xc6, 0x16, + 0xb0, 0x31, 0x27, 0x88, 0x84, 0x2a, 0xb9, 0x51, 0x8c, 0x2d, 0x93, 0x6f, 0xd3, 0xd3, 0x14, 0x11, + 0x4c, 0xe9, 0x83, 0xff, 0xe0, 0x51, 0x02, 0x48, 0x7a, 0x48, 0x0e, 0x42, 0xa2, 0xfe, 0x25, 0x00, + 0x1e, 0x78, 0x70, 0x84, 0x0e, 0xf8, 0x3a, 0x0e, 0xf8, 0x91, 0xf2, 0x11, 0xfb, 0x91, 0xd6, 0x43, + 0xde, 0x03, 0x11, 0x21, 0x00, 0x02, 0x22, 0xf4, 0xcd, 0xbf, 0x10, 0x15, 0x8d, 0x1f, 0xf9, 0x90, + 0xc9, 0x7b, 0xe2, 0xef, 0xd0, 0x81, 0xab, 0x90, 0x01, 0xed, 0xf2, 0xc4, 0xc8, 0x0c, 0x18, 0xc9, + 0xa6, 0x92, 0x65, 0x85, 0x97, 0x7e, 0x06, 0x00, 0x60, 0x09, 0x63, 0x82, 0x2e, 0x03, 0x88, 0xf3, + 0x8f, 0xfa, 0xfb, 0x12, 0x42, 0x21, 0x11, 0xa5, 0xc4, 0xbc, 0xbd, 0xfb, 0x71, 0xba, 0xc7, 0xfd, + 0x52, 0xda, 0xea, 0x8a, 0x10, 0xea, 0x04, 0x74, 0x2e, 0x95, 0xa0, 0x00, 0x37, 0x94, 0x15, 0xb4, + 0xf0, 0x62, 0x68, 0x3f, 0x08, 0x04, 0x07, 0x18, 0x1b, 0xfc, 0x1e, 0x8f, 0x24, 0x20, 0x00, 0x5f, + 0x99, 0x5a, 0x8e, 0x3e, 0x04, 0xe0, 0xf4, 0xe6, 0x67, 0x90, 0x86, 0x3a, 0xbe, 0x6e, 0xdc, 0xda, + 0xc6, 0x10, 0x08, 0x12, 0x4c, 0xb2, 0x15, 0x78, 0x81, 0x00, 0xa4, 0xea, 0x86, 0x4f, 0x8b, 0xee, + 0x04, 0xe4, 0x58, 0xbb, 0xe3, 0x19, 0xc1, 0x60, 0x27, 0x70, 0xbb, 0x3d, 0x0c, 0xf1, 0xd9, 0x58, + 0xf3, 0xca, 0x89, 0x0e, 0x60, 0xc0, 0x97, 0x85, 0x2a, 0xe8, 0x4e, 0xe2, 0x8e, 0x2b, 0x97, 0xbd, + 0x1b, 0x62, 0x1f, 0x05, 0xa3, 0xe7, 0xc3, 0x8a, 0x00, 0x07, 0x9c, 0x24, 0x7b, 0xa9, 0x8a, 0x66, + 0xb8, 0xbd, 0xbd, 0x5e, 0x1a, 0x79, 0x07, 0xe1, 0x6b, 0x18, 0xef, 0xda, 0x68, 0xfd, 0x5b, 0xd4, + 0xc4, 0xb4, 0xc9, 0x77, 0x1b, 0x4c, 0xc0, 0x80, 0xc3, 0xa0, 0x43, 0xcf, 0xfa, 0x7f, 0x11, 0xd4, + 0xf8, 0xaf, 0xcc, 0x8e, 0xfd, 0xf8, 0x9e, 0x2f, 0x26, 0x13, 0x33, 0xe2, 0x42, 0x84, 0xd0, 0xc8, + 0xc1, 0xb1, 0xd0, 0x4c, 0x89, 0xb8, 0x74, 0x5f, 0x63, 0x0f, 0xa9, 0x52, 0xf2, 0x97, 0x89, 0x7b, + 0x79, 0x4e, 0x0c, 0x02, 0x23, 0x65, 0xc0, 0xf9, 0x38, 0x00, 0x2a, 0x70, 0x00, 0x30, 0x0e, 0xed, + 0x6f, 0x7e, 0x9a, 0x21, 0xd6, 0xd5, 0x36, 0xa6, 0xe3, 0x49, 0x01, 0xb4, 0x19, 0x03, 0x1c, 0xd2, + 0x2e, 0x47, 0xee, 0xc0, 0x77, 0x40, 0x6a, 0x2f, 0x9c, 0x9f, 0x88, 0x08, 0x05, 0x27, 0xd5, 0xb1, + 0x0f, 0x59, 0xe1, 0x7d, 0xf1, 0x30, 0x31, 0x99, 0xd5, 0xd8, 0x7f, 0x41, 0x55, 0x90, 0x01, 0x07, + 0x5c, 0xa4, 0x5b, 0x21, 0xa9, 0x59, 0x5f, 0x10, 0x08, 0x4a, 0x80, 0x7e, 0x2a, 0xbc, 0xbe, 0x38, + 0x91, 0xf8, 0x2a, 0xa0, 0x6a, 0xce, 0x1a, 0x9e, 0xe2, 0xe5, 0x4b, 0x68, 0xbc, 0x1a, 0x4f, 0x8b, + 0x20, 0x86, 0xbb, 0x2e, 0xe2, 0x6e, 0x5f, 0xab, 0xe4, 0x20, 0x96, 0x16, 0x8a, 0x93, 0xcb, 0x15, + 0xcb, 0xcb, 0x9e, 0x2f, 0xcb, 0xf2, 0xe0, 0xaf, 0xc2, 0x24, 0xd5, 0x4b, 0x85, 0xcb, 0x2d, 0x9c, + 0xe3, 0x68, 0x5b, 0xbc, 0x4c, 0x23, 0xa7, 0x57, 0x8a, 0xc5, 0x74, 0x85, 0x18, 0x1f, 0x06, 0xbc, + 0x18, 0x0d, 0x2a, 0xca, 0x59, 0x54, 0x15, 0x47, 0x9c, 0x1c, 0x80, 0x7c, 0x54, 0x40, 0xf8, 0xd2, + 0x03, 0xaa, 0x32, 0x9a, 0x8f, 0x01, 0x60, 0xe1, 0xdc, 0xc1, 0xd0, 0x8f, 0x52, 0x4c, 0x23, 0x08, + 0x05, 0xec, 0x32, 0x3a, 0x95, 0xca, 0x1c, 0x7e, 0x2b, 0x42, 0xdc, 0x60, 0xab, 0xfb, 0xfc, 0x22, + 0x10, 0x0a, 0x1f, 0x69, 0x5b, 0x7b, 0xfa, 0x7d, 0x5f, 0xfb, 0xd6, 0xae, 0x7c, 0x86, 0x36, 0x05, + 0xb4, 0xb3, 0xe2, 0x44, 0x82, 0x11, 0x65, 0x8b, 0xf7, 0x5b, 0x9c, 0x10, 0xd7, 0x26, 0xef, 0xf7, + 0x77, 0xd7, 0x14, 0x29, 0x13, 0xed, 0x3f, 0xe4, 0x28, 0x87, 0x9e, 0x38, 0xf5, 0x13, 0xab, 0x4b, + 0x88, 0x21, 0xa0, 0xaa, 0xb0, 0xb3, 0x30, 0xc8, 0x30, 0x1b, 0x64, 0x3e, 0x0e, 0xfa, 0x77, 0x20, + 0x8e, 0xb0, 0xe6, 0x42, 0xe6, 0xc9, 0x1e, 0xba, 0xc4, 0x03, 0x53, 0x60, 0x37, 0x8e, 0x80, 0x00, + 0x99, 0xb0, 0x56, 0xca, 0x37, 0x9f, 0xfe, 0x19, 0x01, 0x10, 0x36, 0x1a, 0xa4, 0x06, 0x93, 0xc0, + 0x00, 0x56, 0x0f, 0x00, 0x01, 0xb8, 0x0c, 0x58, 0x3e, 0x18, 0x2c, 0x7c, 0x9c, 0x00, 0xf3, 0x28, + 0x94, 0xf0, 0x30, 0xb2, 0xc0, 0x0c, 0xd5, 0x71, 0x24, 0x93, 0xb9, 0x9a, 0x74, 0x1a, 0x1e, 0x7c, + 0x43, 0x80, 0x41, 0x20, 0xca, 0x0a, 0xcc, 0x63, 0x8e, 0xfe, 0x4e, 0x4f, 0xe0, 0xe2, 0x0a, 0xcf, + 0xf2, 0x76, 0x62, 0x10, 0xb3, 0x13, 0xf9, 0x76, 0x7f, 0xb3, 0xf4, 0x01, 0x5f, 0x64, 0xc9, 0xfe, + 0x09, 0x04, 0xde, 0xef, 0xf1, 0xc6, 0xbd, 0xcf, 0xc2, 0x2f, 0x4a, 0xdf, 0x97, 0xbf, 0x8c, 0x2a, + 0x9d, 0x2a, 0xa9, 0xec, 0xf0, 0xdd, 0x0e, 0x83, 0xd0, 0xd7, 0xc4, 0xec, 0xf9, 0xed, 0xa5, 0xc4, + 0x0a, 0x20, 0x58, 0x15, 0x26, 0x00, 0x55, 0xbc, 0xb6, 0x4f, 0x62, 0x6c, 0x78, 0x80, 0x88, 0x25, + 0x90, 0xe0, 0xd5, 0xf7, 0x0f, 0x7f, 0xd5, 0x27, 0x7f, 0x12, 0x14, 0xee, 0x5c, 0xdc, 0x84, 0xc3, + 0x6f, 0xd5, 0x64, 0x84, 0x5c, 0xde, 0x4c, 0x5e, 0x20, 0x6e, 0x6e, 0x8d, 0x77, 0x27, 0x9a, 0x6e, + 0xeb, 0x31, 0xa1, 0x1f, 0xfd, 0x4a, 0x31, 0xff, 0xc7, 0x72, 0x55, 0x7f, 0x75, 0xac, 0x9c, 0x85, + 0x55, 0xc6, 0x76, 0x71, 0xb1, 0x89, 0xf2, 0x71, 0x23, 0x15, 0x55, 0x49, 0x93, 0xf8, 0x4f, 0xb4, + 0xd2, 0xc9, 0x8b, 0xe0, 0x8c, 0xba, 0xac, 0x57, 0xc2, 0x86, 0x6c, 0x7a, 0x31, 0x78, 0x3b, 0x33, + 0x30, 0x4e, 0xf2, 0xf5, 0x97, 0x79, 0xe2, 0xcc, 0x3b, 0x80, 0x0a, 0xe6, 0xf9, 0xe2, 0xc0, 0x82, + 0x4b, 0xfd, 0x39, 0x54, 0x60, 0x3b, 0xc5, 0xeb, 0x07, 0xcf, 0x0c, 0x3c, 0x4b, 0xe7, 0x00, 0x7c, + 0x0c, 0x99, 0x79, 0xcb, 0x61, 0xd3, 0xba, 0xcc, 0x03, 0xaf, 0xf7, 0xf0, 0xf9, 0x58, 0x16, 0xb8, + 0xb0, 0x86, 0xa6, 0x38, 0x22, 0xf6, 0x32, 0x80, 0x21, 0x57, 0x9b, 0xc4, 0xf8, 0x17, 0x40, 0xe4, + 0x85, 0x8a, 0x71, 0x27, 0xcb, 0xf0, 0xd6, 0x00, 0x96, 0xa6, 0x8c, 0x33, 0xbf, 0xe0, 0x43, 0xd9, + 0xc5, 0x65, 0xf1, 0xd2, 0x64, 0xca, 0xd7, 0xe4, 0xe4, 0xf3, 0x9f, 0x0d, 0xc2, 0xc0, 0x57, 0x2c, + 0x00, 0xc4, 0x78, 0x10, 0xe0, 0x40, 0xbf, 0x78, 0xae, 0xb9, 0xaf, 0x9b, 0xe2, 0x63, 0x08, 0xf4, + 0xcf, 0xcc, 0xaf, 0x6f, 0x2d, 0x54, 0x97, 0x94, 0x63, 0xd6, 0x16, 0x79, 0xde, 0x3a, 0x89, 0xc4, + 0x09, 0x16, 0x31, 0xb6, 0x11, 0x9c, 0x78, 0xbb, 0xf4, 0xf1, 0x22, 0x02, 0x22, 0x35, 0x4c, 0x2b, + 0x36, 0x31, 0x24, 0x60, 0x3a, 0xc5, 0x7c, 0x34, 0x42, 0xb1, 0xa3, 0x8d, 0x58, 0x9f, 0x30, 0x71, + 0x64, 0xfe, 0x55, 0xee, 0xc4, 0x4b, 0x1b, 0xd7, 0x8f, 0x79, 0x8e, 0x9f, 0xe5, 0xee, 0xfe, 0x2e, + 0x13, 0x59, 0x3f, 0x24, 0x04, 0xc2, 0x56, 0xe4, 0x15, 0xa9, 0x2a, 0xc8, 0xe7, 0x4c, 0x3c, 0xa6, + 0x54, 0xf9, 0x59, 0xe2, 0x4b, 0x27, 0xf7, 0xc4, 0x09, 0x3e, 0x3e, 0xef, 0x82, 0x6e, 0x43, 0x29, + 0xbd, 0xe1, 0xb5, 0x00, 0x03, 0xae, 0x1c, 0x81, 0xab, 0x57, 0x17, 0x3a, 0x32, 0x90, 0x5e, 0x3a, + 0xa3, 0xaf, 0x9a, 0xd6, 0x78, 0x36, 0xf8, 0x96, 0x0c, 0x15, 0x14, 0x32, 0xc1, 0xce, 0x63, 0x7e, + 0x7f, 0xf8, 0x76, 0x8c, 0x00, 0x09, 0xa8, 0x7b, 0xca, 0x20, 0x19, 0x81, 0xdf, 0xcd, 0xed, 0xb2, + 0x23, 0xc8, 0x9d, 0x5f, 0x02, 0x28, 0x08, 0xc2, 0xff, 0xf0, 0x99, 0x0e, 0x00, 0x3e, 0x49, 0x4c, + 0x53, 0x4d, 0xfb, 0xef, 0x0b, 0xf4, 0x24, 0x1d, 0x0e, 0x34, 0x3c, 0x69, 0x0b, 0x6f, 0x71, 0x8d, + 0x29, 0xd8, 0x3e, 0x83, 0x60, 0x7b, 0xc5, 0x16, 0x90, 0xa7, 0x1e, 0x16, 0x8a, 0x00, 0x19, 0xde, + 0x28, 0x00, 0x14, 0x9c, 0x1e, 0x1f, 0x00, 0x95, 0x99, 0xc2, 0x73, 0x30, 0x96, 0x19, 0xfc, 0x40, + 0xc2, 0x2a, 0xef, 0x8c, 0xa7, 0x03, 0xab, 0x3e, 0x7f, 0x02, 0xf5, 0xaa, 0xa7, 0x11, 0xfe, 0x4c, + 0x2f, 0x85, 0x11, 0x00, 0x19, 0x9c, 0x35, 0x82, 0x48, 0x9d, 0x89, 0x37, 0xf3, 0x6a, 0x6e, 0x6a, + 0x0f, 0xf4, 0xb3, 0x8f, 0xfb, 0xbd, 0x70, 0xf6, 0x00, 0x1c, 0x67, 0x0d, 0x35, 0x7d, 0x20, 0x44, + 0x7f, 0xf6, 0x67, 0x25, 0x81, 0x84, 0x27, 0x0d, 0xe8, 0x25, 0xa2, 0x20, 0x5f, 0xc7, 0xe1, 0x51, + 0xae, 0xf3, 0x5e, 0x5e, 0xe5, 0x69, 0x59, 0xf6, 0xcb, 0xb5, 0x1f, 0x3f, 0xbd, 0xbe, 0xed, 0xd3, + 0xf0, 0x57, 0x06, 0x9a, 0xa3, 0x52, 0x88, 0xbc, 0x4f, 0xc8, 0x2b, 0x81, 0x51, 0x4b, 0x2c, 0xa7, + 0xf6, 0x7c, 0x27, 0x14, 0x62, 0x8c, 0x56, 0x2b, 0xb4, 0xff, 0x15, 0x91, 0x01, 0xa9, 0x00, 0xa9, + 0x3b, 0xf9, 0x64, 0x6a, 0x5f, 0xc2, 0xd2, 0x2f, 0x4e, 0x66, 0xe9, 0xea, 0x3a, 0x91, 0xcf, 0xc7, + 0xf5, 0x69, 0x7a, 0xba, 0xfb, 0xbd, 0xeb, 0x98, 0xa9, 0xe2, 0xb0, 0x87, 0x25, 0xdd, 0xfe, 0xee, + 0xff, 0x82, 0x43, 0x3a, 0x5b, 0xd7, 0x0f, 0x6b, 0x7e, 0x2e, 0x6e, 0x4a, 0x1e, 0x0b, 0x85, 0x92, + 0x30, 0x0a, 0xc2, 0xd8, 0x5a, 0x89, 0xa7, 0xf0, 0xf3, 0x80, 0x0a, 0x4f, 0x8c, 0x6f, 0x4a, 0x5b, + 0xf9, 0x01, 0x62, 0x48, 0xd9, 0x7f, 0x1e, 0x0f, 0x7f, 0xf6, 0xd3, 0xbe, 0xff, 0x4f, 0x12, 0xaa, + 0xee, 0xcb, 0xff, 0xe3, 0xca, 0x2f, 0x5c, 0x1d, 0x0b, 0xc1, 0xc4, 0x2f, 0x07, 0x45, 0xe0, 0xe8, + 0xbe, 0x07, 0x88, 0xc2, 0x13, 0x2a, 0x4e, 0x02, 0xa4, 0xae, 0x0f, 0xe5, 0x85, 0x05, 0x63, 0x0e, + 0xc6, 0xa3, 0x88, 0x7e, 0x4f, 0x07, 0xd9, 0xbb, 0x3c, 0x97, 0xc3, 0x2c, 0xa0, 0x0e, 0x9c, 0x5f, + 0xfe, 0x1e, 0x12, 0x92, 0xfd, 0xea, 0xdd, 0xb1, 0xae, 0xde, 0x99, 0x46, 0x41, 0x97, 0xaf, 0xd6, + 0x15, 0x50, 0x0b, 0x2b, 0x94, 0x11, 0x5a, 0xba, 0xda, 0x65, 0x36, 0xd4, 0x43, 0x45, 0x3d, 0xee, + 0x5d, 0x66, 0x5d, 0x96, 0xb1, 0xdf, 0x97, 0x41, 0xdd, 0x21, 0xf8, 0x28, 0x26, 0x51, 0x5e, 0x3f, + 0x96, 0x61, 0x7f, 0x9d, 0x46, 0x2b, 0x10, 0x62, 0x9b, 0xad, 0x42, 0x3c, 0xd5, 0x5c, 0xfc, 0xa4, + 0x5a, 0xd7, 0x26, 0xf7, 0xf7, 0x3f, 0xf0, 0x9f, 0x19, 0x87, 0xc2, 0xa3, 0x65, 0x81, 0x9e, 0x06, + 0x59, 0x8a, 0x61, 0x6d, 0x51, 0x7c, 0x5f, 0x49, 0x28, 0x4f, 0x00, 0x39, 0x8d, 0x28, 0x18, 0xf1, + 0xd7, 0x8c, 0x43, 0xd7, 0x34, 0x56, 0x7f, 0x7f, 0xe1, 0x23, 0xc2, 0xb5, 0xbb, 0xad, 0x78, 0x88, + 0xf2, 0x1c, 0x15, 0x07, 0x79, 0x7c, 0xc0, 0x93, 0xac, 0x89, 0x56, 0x87, 0x89, 0x10, 0x3c, 0xa7, + 0x48, 0x58, 0xf3, 0xe0, 0xa0, 0xc4, 0x8e, 0x5d, 0xbb, 0x5e, 0x26, 0x30, 0xcf, 0xcf, 0x6a, 0x58, + 0xe5, 0xf5, 0x6c, 0x5e, 0x32, 0xb2, 0xdf, 0x82, 0xb3, 0x37, 0x32, 0xd9, 0x70, 0xe0, 0x1c, 0x1e, + 0xf0, 0xf0, 0x04, 0xc4, 0xb0, 0x69, 0x5e, 0xff, 0x28, 0x94, 0xad, 0x78, 0x92, 0x97, 0x55, 0xf6, + 0x67, 0xa1, 0x99, 0x90, 0xa7, 0x04, 0x67, 0x4e, 0xab, 0xdf, 0x20, 0x87, 0x6f, 0x27, 0x04, 0x45, + 0xe5, 0xef, 0x0a, 0x72, 0xf7, 0x7c, 0x4c, 0x79, 0x01, 0x46, 0xa0, 0xf0, 0x03, 0xf0, 0xe9, 0xe1, + 0x00, 0x78, 0xb9, 0xc6, 0x05, 0xee, 0x2b, 0xbf, 0x89, 0x3a, 0xd6, 0xab, 0xf8, 0x25, 0x11, 0x37, + 0xe5, 0x55, 0x5d, 0xe2, 0x47, 0xf5, 0x5d, 0x54, 0x5d, 0x2f, 0x89, 0x08, 0xdc, 0x40, 0x0f, 0x73, + 0x81, 0xe3, 0xbe, 0x24, 0x1c, 0x9a, 0xc3, 0xf9, 0xef, 0x3c, 0x72, 0xfc, 0x48, 0x80, 0xa1, 0x4b, + 0x18, 0x91, 0xc3, 0xdf, 0x51, 0x2b, 0x4e, 0xa5, 0xd6, 0xb5, 0x5b, 0xf8, 0x91, 0x9a, 0xb6, 0xaa, + 0xa9, 0x2d, 0x6a, 0x92, 0xd2, 0xf1, 0xf5, 0x55, 0x53, 0x71, 0x84, 0x11, 0xe4, 0xe8, 0x6b, 0xf1, + 0x38, 0xe9, 0x75, 0x26, 0x06, 0xb8, 0x9e, 0xef, 0x6e, 0xef, 0x98, 0x6c, 0xde, 0xa1, 0x1e, 0xc8, + 0xee, 0xf2, 0x76, 0x31, 0xef, 0xf0, 0x90, 0x94, 0x32, 0x6a, 0x65, 0xb7, 0x7f, 0xc1, 0x28, 0x8b, + 0xbd, 0xde, 0x9c, 0xa1, 0x4e, 0x51, 0x35, 0xa8, 0x9e, 0xcc, 0xf7, 0xfa, 0x1b, 0xd5, 0xcc, 0x31, + 0xdf, 0x1f, 0x11, 0x25, 0xde, 0xe6, 0xe1, 0x31, 0x32, 0xed, 0xa7, 0xdc, 0x39, 0xc8, 0x21, 0x53, + 0x5f, 0x94, 0x4e, 0xaa, 0x14, 0xe2, 0x62, 0xbb, 0xcf, 0x96, 0xa5, 0xe4, 0xbb, 0x58, 0x77, 0xb3, + 0x2e, 0x4e, 0x0e, 0x78, 0xb3, 0xd6, 0xb5, 0x58, 0x0c, 0x88, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x4c, 0x26, 0x32, 0x85, 0x70, 0x99, 0xab, 0x55, 0x5c, 0xdc, 0xa5, 0x5a, 0xc3, 0xdc, 0x13, 0xdc, + 0x56, 0xe2, 0xb7, 0x15, 0xb8, 0xae, 0xb0, 0xec, 0xa0, 0x25, 0x03, 0x60, 0x80, 0xb9, 0xd5, 0xf5, + 0xaf, 0xd6, 0xa0, 0xe8, 0x2d, 0xbd, 0xfe, 0x32, 0x50, 0x47, 0x3a, 0xa8, 0x73, 0x1f, 0x8c, 0xc5, + 0xeb, 0x19, 0x81, 0x1b, 0x21, 0x82, 0xf8, 0xcc, 0x0f, 0x10, 0x74, 0x0d, 0x8c, 0xc0, 0x39, 0xb0, + 0x83, 0x9a, 0x6c, 0x31, 0x14, 0x00, 0x63, 0x40, 0x61, 0x2e, 0xa0, 0x5a, 0x05, 0x78, 0x81, 0xf6, + 0x28, 0xdf, 0xc4, 0x30, 0x2d, 0x88, 0x60, 0x5b, 0x34, 0x7e, 0x19, 0x9c, 0x01, 0xc0, 0x5f, 0x42, + 0x80, 0x00, 0x80, 0x14, 0x67, 0xbf, 0xc5, 0x71, 0x5f, 0xc7, 0xeb, 0xec, 0x8e, 0xf8, 0x8e, 0x62, + 0xbd, 0xc5, 0x78, 0x98, 0x93, 0x3e, 0xaf, 0x6f, 0xe2, 0xec, 0x6e, 0xe3, 0xf4, 0x6d, 0x6b, 0xf9, + 0xbc, 0xff, 0xc2, 0x05, 0xaa, 0x1e, 0xed, 0x4b, 0x0c, 0x9a, 0x1f, 0xe0, 0x9e, 0x2b, 0x14, 0x6e, + 0x2b, 0x71, 0x5d, 0xeb, 0x09, 0xb8, 0x23, 0xe2, 0x4b, 0x4b, 0xaf, 0xff, 0xc2, 0x6c, 0x48, 0x01, + 0xee, 0xc9, 0x71, 0x07, 0x4f, 0xbf, 0xd6, 0xbf, 0x88, 0x52, 0x6c, 0x73, 0x81, 0x98, 0x0e, 0x4e, + 0xc7, 0x38, 0x7d, 0x46, 0x47, 0xe3, 0x94, 0x27, 0x48, 0xca, 0x3f, 0x0b, 0xc7, 0x00, 0x0d, 0x67, + 0xd8, 0xa2, 0x94, 0x97, 0xdf, 0xfd, 0xc7, 0xf1, 0xbe, 0x36, 0xc3, 0x4c, 0x48, 0x06, 0x03, 0x13, + 0x0d, 0x49, 0xef, 0xf7, 0xbf, 0xd1, 0xf1, 0x1c, 0xc2, 0x2b, 0x5f, 0x08, 0xf1, 0x75, 0xad, 0x57, + 0x55, 0xc1, 0x21, 0x61, 0x64, 0xc9, 0x01, 0x0a, 0xda, 0xc7, 0xe2, 0x68, 0x9d, 0xc4, 0xc4, 0x58, + 0xde, 0xc4, 0xaa, 0x2f, 0x7c, 0x4c, 0x56, 0x9c, 0x5b, 0x8b, 0x73, 0x33, 0xe2, 0x79, 0xb3, 0x2b, + 0x3c, 0x4c, 0x11, 0x15, 0x25, 0x6f, 0xd5, 0xc5, 0x99, 0xcb, 0x97, 0x7b, 0xc2, 0x5c, 0xde, 0x2b, + 0xf0, 0x50, 0x25, 0xdc, 0x55, 0x2e, 0x29, 0x8b, 0xf7, 0xc5, 0x93, 0x36, 0x2e, 0x2e, 0x2f, 0xe5, + 0x2e, 0x2e, 0x2e, 0x7e, 0x43, 0xbb, 0xde, 0x1b, 0x50, 0x10, 0xad, 0xb1, 0x79, 0x93, 0xdb, 0xb9, + 0xbd, 0xff, 0x70, 0x5f, 0xd3, 0xb7, 0xf8, 0x5a, 0x20, 0x00, 0xcc, 0x15, 0x9f, 0x81, 0x39, 0x6f, + 0xf3, 0xf1, 0x57, 0x60, 0xfb, 0xaa, 0xb3, 0xcc, 0x53, 0x80, 0xc4, 0xa1, 0xd1, 0x0f, 0x22, 0x80, + 0x8f, 0xf9, 0x3d, 0x7f, 0xff, 0x6e, 0x8b, 0xbf, 0xb6, 0xdc, 0x3c, 0x48, 0x02, 0xde, 0x8d, 0x94, + 0x5f, 0xfb, 0x6d, 0xed, 0xb7, 0x5f, 0xdb, 0xc3, 0x24, 0x80, 0x02, 0x4d, 0x92, 0x26, 0xdb, 0x42, + 0x6e, 0xbb, 0xff, 0xe7, 0xed, 0x8e, 0x0b, 0xf4, 0x7e, 0x1a, 0x8a, 0x00, 0x20, 0x2e, 0x66, 0x81, + 0xd2, 0xfb, 0x8a, 0xf3, 0xff, 0x9f, 0xf5, 0xfe, 0x91, 0x42, 0xcc, 0xe0, 0x1e, 0xe2, 0x55, 0x3b, + 0xdf, 0xff, 0xfe, 0x2c, 0x42, 0x7b, 0xbc, 0xfe, 0x2a, 0x24, 0x41, 0x0b, 0x8e, 0xd6, 0x22, 0xca, + 0x3a, 0x79, 0x6a, 0x70, 0x3a, 0xfc, 0x11, 0xdb, 0x3f, 0x1b, 0xa7, 0xd7, 0xc5, 0x0b, 0xad, 0x5e, + 0xd7, 0x13, 0x57, 0xf9, 0x06, 0x16, 0x8f, 0xb8, 0x9f, 0x84, 0x63, 0x38, 0xbe, 0x0f, 0x3c, 0x03, + 0xe0, 0x1a, 0x88, 0x70, 0x0f, 0x10, 0x3f, 0x07, 0xb0, 0x0d, 0x49, 0x81, 0xf4, 0x3d, 0x80, 0x04, + 0xd9, 0x10, 0x76, 0x25, 0x04, 0xc6, 0xae, 0x5a, 0x69, 0xd3, 0x37, 0x7f, 0xa6, 0x33, 0xa1, 0xfc, + 0x6c, 0x0a, 0x83, 0x70, 0x55, 0x5c, 0x4c, 0x38, 0x3f, 0x81, 0x08, 0x90, 0xa0, 0x84, 0x67, 0x50, + 0x50, 0xfd, 0xf0, 0xea, 0x80, 0x05, 0x47, 0x8e, 0x55, 0x20, 0x89, 0xdf, 0xa1, 0x9d, 0xb7, 0xfe, + 0x07, 0x8f, 0xb5, 0x4c, 0x50, 0xb0, 0xdc, 0x67, 0x83, 0xa2, 0x84, 0xc6, 0xe8, 0xc5, 0x91, 0x72, + 0xb1, 0xa8, 0xe4, 0xbb, 0xe8, 0xa3, 0x83, 0x58, 0x50, 0xce, 0x28, 0xd9, 0x9a, 0xf5, 0xc7, 0xd5, + 0xbb, 0x51, 0x6e, 0x1b, 0xc0, 0x09, 0xb1, 0x4d, 0xaa, 0x7c, 0xd1, 0x88, 0x59, 0x30, 0x46, 0xa3, + 0x8e, 0x34, 0xe3, 0xdc, 0xbb, 0x5e, 0xaf, 0x14, 0x60, 0xcd, 0x2a, 0xfa, 0xfc, 0x0f, 0x20, 0x79, + 0x1b, 0x07, 0x4f, 0x8e, 0xac, 0x2a, 0x2b, 0x8a, 0x44, 0xa3, 0xdf, 0x3c, 0x7b, 0x60, 0x5b, 0x4a, + 0x3c, 0x5c, 0xf2, 0x31, 0xd7, 0x87, 0x38, 0xfc, 0x0b, 0x3f, 0x43, 0xe7, 0x04, 0x6b, 0x8e, 0xaf, + 0xfe, 0x14, 0x29, 0xc0, 0x79, 0x79, 0xc1, 0x81, 0x7a, 0xd6, 0x71, 0xc2, 0xcc, 0xf0, 0xf3, 0x80, + 0xf0, 0xa9, 0xc9, 0xd1, 0x38, 0xe1, 0x78, 0xd1, 0x8d, 0x1f, 0x11, 0x38, 0x78, 0x85, 0x00, 0x21, + 0x3d, 0x2c, 0xf0, 0x8c, 0xb6, 0xff, 0x4d, 0x3b, 0xe1, 0x57, 0x88, 0x1f, 0x6d, 0xbe, 0xdc, 0x38, + 0xc6, 0x00, 0x0a, 0x22, 0x0d, 0xa2, 0x9a, 0x81, 0xda, 0x66, 0x7a, 0xb6, 0xf3, 0x70, 0x77, 0xe3, + 0xab, 0x9f, 0x8e, 0xff, 0x07, 0xbe, 0xfe, 0xef, 0x1c, 0x66, 0x40, 0x48, 0xaf, 0xb6, 0xf8, 0x69, + 0x40, 0x03, 0x5f, 0x83, 0x9a, 0x29, 0xb9, 0x80, 0xfe, 0x89, 0xd3, 0xac, 0x7b, 0x93, 0x4e, 0x34, + 0xf9, 0xc1, 0xdb, 0xa5, 0x8d, 0xb3, 0x86, 0xa4, 0x43, 0xf0, 0xe2, 0x80, 0x34, 0x7c, 0xb4, 0x03, + 0xf9, 0x7f, 0xc6, 0x6d, 0xac, 0x74, 0xf4, 0xda, 0x6d, 0x1c, 0x4f, 0x4a, 0x83, 0xe5, 0xb1, 0xf4, + 0xd3, 0xe1, 0x85, 0x00, 0x03, 0x91, 0x31, 0xc6, 0x53, 0x01, 0x5a, 0x29, 0xff, 0xfe, 0x5f, 0xa6, + 0x9c, 0x13, 0x13, 0xf6, 0x0b, 0x1c, 0x6c, 0x90, 0x2f, 0xcc, 0x20, 0x3f, 0xb1, 0x68, 0x00, 0x3f, + 0x13, 0x01, 0x1a, 0x5b, 0x01, 0x1a, 0x59, 0x94, 0x61, 0xac, 0x00, 0x48, 0xc8, 0x02, 0xd2, 0x8f, + 0xf5, 0xa6, 0xfb, 0xc2, 0xda, 0x64, 0xb7, 0xf7, 0xbe, 0x4e, 0x3f, 0xa8, 0xbb, 0x07, 0xdc, 0xda, + 0x2d, 0x97, 0x64, 0xda, 0x55, 0xe2, 0x0e, 0x07, 0x70, 0x00, 0xd4, 0x9c, 0x00, 0x08, 0xa8, 0x77, + 0x0d, 0x49, 0xd5, 0x3c, 0x1c, 0x7e, 0x4e, 0x53, 0x3d, 0xe2, 0x22, 0x44, 0x7c, 0xc2, 0x6e, 0xbc, + 0x45, 0x7b, 0xc4, 0x89, 0xa1, 0x92, 0x25, 0x67, 0x9b, 0xe6, 0x89, 0x12, 0x13, 0x15, 0x35, 0xda, + 0x92, 0xff, 0x2d, 0x6f, 0xc4, 0xc4, 0xea, 0xab, 0x55, 0x8a, 0xe6, 0x13, 0x55, 0xc3, 0xd8, 0x00, + 0x17, 0x0d, 0x75, 0xca, 0x50, 0xdb, 0x0d, 0xf7, 0xca, 0x20, 0x7a, 0xba, 0xa4, 0xa8, 0xb9, 0x43, + 0xa9, 0x43, 0x74, 0x1d, 0xb9, 0xf9, 0x62, 0xeb, 0x2d, 0x66, 0xee, 0xa8, 0x49, 0x38, 0x55, 0x9b, + 0xac, 0x7f, 0x0e, 0xe0, 0x07, 0xb7, 0x90, 0x8e, 0x58, 0xad, 0xd0, 0x7f, 0xdf, 0x32, 0x09, 0x5f, + 0x2b, 0xee, 0x9e, 0xd4, 0x8c, 0xbf, 0x62, 0x3d, 0x9e, 0x28, 0x66, 0xe2, 0x5e, 0x4a, 0x3f, 0x1e, + 0x85, 0x7e, 0x6d, 0xd7, 0x7c, 0x14, 0x1c, 0x70, 0xe2, 0x80, 0x26, 0x31, 0xae, 0xe2, 0x92, 0x93, + 0x3e, 0x33, 0x1b, 0xc7, 0x2a, 0x7e, 0x28, 0x6e, 0xf4, 0xd3, 0x50, 0xa5, 0x32, 0xba, 0x65, 0x03, + 0x54, 0xe3, 0xa2, 0x29, 0x86, 0x60, 0x7b, 0xf7, 0xca, 0x9b, 0x8f, 0x0e, 0xe0, 0xa4, 0x0a, 0x21, + 0x49, 0x54, 0xfe, 0x66, 0x5a, 0x07, 0x15, 0xd8, 0xd4, 0x76, 0x2a, 0xec, 0x5c, 0xa5, 0x9d, 0xe7, + 0xf3, 0x22, 0xf0, 0xbd, 0x46, 0x00, 0x02, 0x87, 0x07, 0x0b, 0xe0, 0x06, 0x6e, 0x2f, 0x54, 0x4c, + 0xfe, 0xb7, 0xc9, 0xd4, 0xbe, 0xcb, 0xa8, 0xbc, 0x5f, 0x4f, 0x87, 0x54, 0x02, 0x42, 0x61, 0x6e, + 0x77, 0xb0, 0x21, 0xcd, 0xc7, 0x0d, 0x0a, 0xb2, 0x9c, 0xe4, 0x65, 0xb7, 0xae, 0x39, 0x38, 0xe4, + 0x77, 0xc7, 0x37, 0x74, 0xc6, 0x82, 0x88, 0xd9, 0x02, 0xf6, 0xe6, 0xbf, 0x04, 0x21, 0x49, 0xe1, + 0x80, 0x7a, 0x94, 0x40, 0x7b, 0xb3, 0x4a, 0xd0, 0x90, 0x00, 0x21, 0x83, 0xc2, 0xe5, 0x80, 0x19, + 0xc7, 0x8b, 0xf8, 0x32, 0x60, 0x88, 0x7f, 0x04, 0x7d, 0x55, 0xe2, 0x39, 0x2e, 0xff, 0xb8, 0x3b, + 0xe1, 0xf3, 0x11, 0xdc, 0x57, 0xb4, 0x22, 0x20, 0x40, 0x40, 0x95, 0x59, 0x74, 0x46, 0x07, 0xd9, + 0x55, 0x5f, 0x82, 0x63, 0xe9, 0x0c, 0x63, 0xb4, 0x93, 0xfc, 0x7e, 0x31, 0x46, 0x39, 0x83, 0x26, + 0xa1, 0x97, 0x66, 0x5d, 0xac, 0x5f, 0x13, 0x04, 0xdb, 0x4d, 0xf9, 0x72, 0xf5, 0xc7, 0x19, 0xed, + 0xaa, 0xaa, 0x0d, 0x6b, 0x5f, 0x27, 0x53, 0x67, 0xbe, 0xab, 0xe2, 0xcb, 0xcb, 0xf2, 0xe1, 0x37, + 0xcc, 0x7d, 0x4d, 0x98, 0x89, 0x86, 0x26, 0x2b, 0xf0, 0x88, 0x41, 0xd2, 0x44, 0x37, 0x89, 0x13, + 0xcc, 0x27, 0x89, 0xe7, 0x82, 0x82, 0x60, 0xc0, 0x77, 0x8e, 0x1b, 0xc5, 0x6e, 0x8c, 0x57, 0x82, + 0xbb, 0xbd, 0xd2, 0x7b, 0xda, 0x8b, 0x8e, 0xfe, 0x08, 0x43, 0x23, 0x48, 0x07, 0x76, 0xa1, 0xc7, + 0x95, 0xdc, 0xaa, 0x02, 0x54, 0xc1, 0xee, 0x4b, 0x82, 0xf8, 0x71, 0x30, 0x12, 0x9e, 0x00, 0x06, + 0x20, 0x17, 0x0d, 0x08, 0xac, 0x90, 0x0a, 0xa2, 0x84, 0x4a, 0x5b, 0x3b, 0xa5, 0x8c, 0x47, 0x40, + 0x58, 0x02, 0x13, 0xde, 0xdf, 0x0e, 0xe0, 0x0e, 0x29, 0x05, 0x2d, 0xe3, 0x21, 0xbb, 0xfd, 0x97, + 0x6c, 0xa2, 0x71, 0xbe, 0xb1, 0xc6, 0xda, 0x65, 0xef, 0x67, 0xbd, 0xdd, 0xbe, 0x31, 0xa4, 0x81, + 0xeb, 0xf4, 0xa7, 0xd3, 0x8b, 0xc3, 0xac, 0xa0, 0x0e, 0x51, 0x80, 0xb0, 0xbb, 0x8f, 0x8e, 0xb4, + 0xe3, 0x7c, 0x0e, 0xfe, 0x99, 0x5d, 0xcc, 0xa9, 0xb9, 0x44, 0x3e, 0x8c, 0x3a, 0x8f, 0x87, 0x10, + 0xbe, 0x1f, 0x5c, 0x55, 0x5c, 0x31, 0x22, 0x32, 0x6d, 0xb7, 0xee, 0xb8, 0x0a, 0x10, 0x16, 0x23, + 0x4e, 0xee, 0xfd, 0x3d, 0xc1, 0x58, 0x35, 0x25, 0x3d, 0xcc, 0x55, 0x9d, 0xf5, 0xcc, 0xc5, 0x30, + 0x71, 0x0b, 0x00, 0x50, 0x00, 0x2a, 0x38, 0x0d, 0xa4, 0xdb, 0x4f, 0xe1, 0xdc, 0x03, 0x13, 0x13, + 0x4e, 0xc6, 0xef, 0xe9, 0x4e, 0xdd, 0xe2, 0x1f, 0xb7, 0xbd, 0xc6, 0x99, 0xf5, 0x75, 0xf8, 0x75, + 0x10, 0x00, 0x51, 0x6e, 0x89, 0x88, 0x7e, 0x50, 0xff, 0xc9, 0xcb, 0xf4, 0xe1, 0xae, 0x0e, 0x2b, + 0xb6, 0x5d, 0x8e, 0x5f, 0x6e, 0xb2, 0x9b, 0xa3, 0xd4, 0x68, 0xd4, 0xd3, 0x68, 0xff, 0xfd, 0xd4, + 0x45, 0x81, 0x79, 0x1b, 0xd0, 0x5f, 0xab, 0x90, 0x30, 0xfb, 0xbe, 0x6d, 0xdf, 0xe2, 0xc8, 0xf7, + 0x77, 0x77, 0x93, 0x93, 0x7b, 0xae, 0x14, 0x3f, 0x33, 0x09, 0x2f, 0x35, 0x5d, 0x09, 0xb0, 0x5f, + 0xac, 0xdf, 0x04, 0xb6, 0x1c, 0xcc, 0x69, 0xa9, 0x3f, 0x97, 0x89, 0x29, 0xaa, 0xac, 0x44, 0xe4, + 0x89, 0x73, 0xf8, 0x81, 0x17, 0x15, 0xdc, 0x51, 0x9c, 0x34, 0x7f, 0x08, 0xe5, 0xe8, 0x3b, 0xff, + 0xab, 0xde, 0x27, 0x81, 0xa4, 0x14, 0x02, 0x01, 0x55, 0x77, 0x5a, 0xab, 0xb3, 0xc4, 0x9a, 0xbf, + 0x74, 0x92, 0x86, 0xe1, 0x00, 0x05, 0x7e, 0x0c, 0x99, 0x5c, 0x49, 0xc8, 0x6c, 0xc5, 0xb8, 0x9f, + 0x46, 0xd1, 0xfa, 0x97, 0x76, 0xee, 0x3a, 0x5e, 0x49, 0x4f, 0x16, 0x0b, 0x02, 0xd8, 0x16, 0x28, + 0x98, 0xfa, 0xe6, 0xf0, 0xee, 0x00, 0x09, 0xe9, 0x12, 0x36, 0x17, 0x43, 0x30, 0x2f, 0x90, 0x2e, + 0x6e, 0x4e, 0xee, 0x58, 0x1a, 0xb2, 0xd6, 0xdc, 0xb4, 0xef, 0x0a, 0x2d, 0xba, 0x5a, 0xcf, 0x1a, + 0x9e, 0xe2, 0xc5, 0x3c, 0xee, 0x9c, 0x55, 0xee, 0xde, 0x02, 0x44, 0x02, 0x00, 0x34, 0x8f, 0x80, + 0x3a, 0x6c, 0x40, 0x49, 0x1b, 0x80, 0x91, 0x58, 0x09, 0x95, 0xee, 0x9c, 0x0d, 0x0e, 0x79, 0x6e, + 0xe8, 0x7b, 0x4d, 0x7b, 0xce, 0x1c, 0x2c, 0x6e, 0x56, 0x0f, 0xc1, 0xf8, 0xd4, 0x75, 0x11, 0x0e, + 0x7f, 0xba, 0x28, 0xaf, 0x0f, 0x4a, 0x04, 0x03, 0x41, 0xae, 0x0d, 0xb1, 0xfa, 0xdb, 0xfc, 0xb5, + 0x8e, 0xf0, 0x9d, 0x81, 0xd3, 0x05, 0x5d, 0xc4, 0x9e, 0xe7, 0xe1, 0x0e, 0x60, 0x00, 0xb5, 0xbc, + 0x86, 0x6a, 0x39, 0x3c, 0xbe, 0x77, 0x4d, 0x22, 0x71, 0xf1, 0xc6, 0x8c, 0xdc, 0xa2, 0x78, 0x5f, + 0x9a, 0x9c, 0x25, 0x1f, 0x13, 0x1e, 0x2c, 0xb6, 0x00, 0x53, 0x8a, 0x03, 0x30, 0x2d, 0x0a, 0xa9, + 0xdb, 0xe7, 0xc5, 0x87, 0xb0, 0x01, 0xb4, 0xd8, 0x1f, 0x32, 0x25, 0x2d, 0x7d, 0xba, 0xea, 0xed, + 0xa3, 0x10, 0xe8, 0xeb, 0xeb, 0xbc, 0xbf, 0x87, 0xdc, 0x72, 0xb8, 0xe5, 0x71, 0xaa, 0x03, 0x00, + 0x25, 0x19, 0x3d, 0xb8, 0x65, 0x18, 0x30, 0x5f, 0x10, 0xff, 0xe1, 0xbc, 0x00, 0x39, 0x3a, 0xc7, + 0x8a, 0xc1, 0x51, 0x15, 0xf6, 0x58, 0x97, 0x4f, 0xab, 0x3f, 0xd4, 0xbb, 0x2e, 0xcb, 0xb1, 0x5b, + 0x3c, 0xea, 0x0a, 0xc3, 0x0c, 0x97, 0x4d, 0xb9, 0xc0, 0xe8, 0x5f, 0xd1, 0x92, 0x7a, 0x1c, 0x89, + 0x00, 0x33, 0x3f, 0x05, 0x95, 0xab, 0xc0, 0xff, 0x8f, 0xff, 0x13, 0xd6, 0x77, 0x9f, 0x75, 0xb6, + 0x09, 0x20, 0x02, 0xb6, 0x5a, 0xe6, 0x8f, 0xe1, 0x1e, 0x41, 0x15, 0x6e, 0xb9, 0x7a, 0x62, 0xb3, + 0xf1, 0x51, 0x76, 0xaa, 0xda, 0xa0, 0x92, 0xf0, 0x9d, 0x6b, 0xc4, 0xc8, 0x3f, 0x2d, 0x77, 0x5d, + 0xde, 0xff, 0x75, 0x26, 0x65, 0x84, 0x22, 0x76, 0xd8, 0xcf, 0xd2, 0xb9, 0xf8, 0xb0, 0xde, 0x00, + 0xcc, 0x89, 0x71, 0xb8, 0xb7, 0xff, 0xab, 0xce, 0x31, 0x2e, 0xc1, 0xdb, 0xd9, 0x7a, 0x6f, 0x6d, + 0x0a, 0xb2, 0x8a, 0xcb, 0x31, 0x5b, 0x13, 0xea, 0x2a, 0xc1, 0xad, 0x8a, 0x62, 0xda, 0x78, 0x44, + 0x20, 0x36, 0x19, 0xf0, 0x75, 0x25, 0xac, 0xac, 0x5e, 0x24, 0x7c, 0x48, 0xe4, 0x4d, 0xe5, 0xdd, + 0xd8, 0xa0, 0xd9, 0x9c, 0x3c, 0x78, 0x78, 0xb5, 0x4f, 0x01, 0xc0, 0x70, 0x54, 0x0a, 0x24, 0x00, + 0x51, 0x00, 0xfc, 0x3a, 0x7f, 0x62, 0x03, 0xf2, 0x95, 0xdc, 0x36, 0xe0, 0x10, 0x59, 0xf1, 0x58, + 0x81, 0x34, 0xd3, 0x77, 0xf0, 0x8a, 0xa9, 0x9e, 0xc0, 0x56, 0x6f, 0x63, 0x3b, 0x12, 0x4d, 0x31, + 0x98, 0xff, 0x33, 0x00, 0x1f, 0xc0, 0xe8, 0xa8, 0xdd, 0xbe, 0x3a, 0xa7, 0x78, 0x34, 0xa5, 0x35, + 0x4d, 0x31, 0x77, 0x25, 0x1f, 0xe1, 0xb7, 0x00, 0x13, 0xe4, 0x58, 0x95, 0x7b, 0x09, 0xbe, 0xdb, + 0xfa, 0x93, 0xe9, 0xd3, 0x55, 0x18, 0x16, 0xdd, 0x96, 0xfe, 0x99, 0x69, 0x0f, 0x28, 0x01, 0x13, + 0xfa, 0x92, 0x17, 0x83, 0x9b, 0xe6, 0x48, 0x23, 0x42, 0x3c, 0x18, 0x62, 0x83, 0x92, 0x8d, 0x82, + 0x71, 0xeb, 0xab, 0xe2, 0xaf, 0xa1, 0x5f, 0xc5, 0x49, 0x60, 0x73, 0x71, 0xeb, 0xc7, 0x23, 0x98, + 0x30, 0x03, 0x42, 0xc0, 0xf2, 0xa0, 0xbe, 0xb6, 0x61, 0x00, 0xbf, 0xa5, 0x7a, 0xbf, 0x8e, 0x07, + 0x90, 0x28, 0x87, 0x63, 0x70, 0x00, 0x08, 0x02, 0x71, 0x01, 0x40, 0xca, 0x1c, 0x90, 0x12, 0xa9, + 0x51, 0x9a, 0xeb, 0x3d, 0xb9, 0xdf, 0xc6, 0xe0, 0xee, 0xc0, 0xc0, 0x70, 0x27, 0xed, 0x58, 0xcb, + 0xb4, 0xe1, 0xb2, 0x40, 0x0a, 0xb1, 0xfa, 0x1a, 0x31, 0x4e, 0xae, 0xbe, 0x25, 0xe7, 0xf8, 0x81, + 0x81, 0xdf, 0xe5, 0x52, 0xae, 0xae, 0xca, 0xcd, 0x0b, 0x0a, 0x70, 0x95, 0xf7, 0xbd, 0xd4, 0x44, + 0x5e, 0xb5, 0x5a, 0xcd, 0xdd, 0xbd, 0x7c, 0x56, 0xa5, 0xf1, 0x5c, 0xd9, 0xf8, 0x9e, 0x48, 0x2d, + 0xa5, 0x6b, 0xc9, 0xab, 0xdf, 0x29, 0x55, 0x7f, 0x31, 0x35, 0x5f, 0x05, 0x95, 0x61, 0xa6, 0x19, + 0x6e, 0x78, 0xc2, 0xd9, 0x61, 0x35, 0x93, 0x93, 0xbe, 0x26, 0x3d, 0x75, 0xec, 0xec, 0x97, 0x83, + 0x4d, 0xfe, 0xa2, 0x71, 0x67, 0x3e, 0x7d, 0xa5, 0x27, 0x05, 0x16, 0x9a, 0x8b, 0xe2, 0x4e, 0x09, + 0xe7, 0x32, 0x5c, 0xf0, 0x0c, 0x81, 0x57, 0xc2, 0xaf, 0x70, 0x6c, 0xbb, 0x01, 0x43, 0x15, 0xbb, + 0x8a, 0xdc, 0xf9, 0xe1, 0x10, 0x1d, 0x03, 0x4c, 0x0f, 0xf9, 0x28, 0xa9, 0xe1, 0xc3, 0x7a, 0x52, + 0x41, 0xc8, 0xab, 0xe8, 0x78, 0x32, 0xc1, 0x9e, 0x01, 0x85, 0x81, 0xe0, 0x69, 0x02, 0x52, 0xdb, + 0x0f, 0x71, 0xf9, 0x2a, 0x54, 0x42, 0x05, 0x09, 0x1b, 0x81, 0xc7, 0x15, 0xdb, 0x06, 0xd2, 0x0f, + 0x05, 0xd6, 0x30, 0x54, 0x4d, 0x23, 0xf0, 0x50, 0x03, 0xc4, 0x29, 0x20, 0xc0, 0x95, 0xeb, 0x35, + 0x9f, 0xc3, 0xc7, 0x0f, 0x1c, 0x76, 0x6f, 0x89, 0x74, 0x30, 0xe0, 0x72, 0x07, 0x3e, 0xb1, 0x16, + 0x8b, 0x19, 0x33, 0x12, 0x87, 0x8c, 0x38, 0x91, 0xc7, 0xc2, 0x2f, 0x8b, 0x89, 0xf3, 0xf8, 0xe2, + 0xb6, 0x67, 0xab, 0xf0, 0x52, 0x04, 0x11, 0xa6, 0x38, 0x01, 0x61, 0x25, 0x42, 0xc1, 0x8f, 0x1e, + 0x37, 0x59, 0x81, 0xf8, 0x06, 0xa7, 0x38, 0x2b, 0x25, 0x07, 0x21, 0x5b, 0xf8, 0x70, 0x6a, 0xa8, + 0x5d, 0xc9, 0x05, 0x86, 0xe4, 0x52, 0x29, 0x6e, 0xdd, 0x59, 0xe3, 0xf0, 0x73, 0x0a, 0x4e, 0x70, + 0xb6, 0x70, 0xe1, 0x6c, 0x56, 0x2b, 0x15, 0x8a, 0xcf, 0x01, 0x8a, 0x33, 0x15, 0x10, 0xc4, 0xad, + 0xe7, 0x36, 0x07, 0x59, 0x29, 0xe1, 0xc7, 0xf8, 0x58, 0xe1, 0xd0, 0x31, 0x57, 0x1c, 0x1f, 0xf3, + 0x3b, 0xe8, 0x31, 0x11, 0xe2, 0x86, 0xd8, 0x50, 0xe3, 0x0e, 0x72, 0x13, 0x15, 0xfc, 0x92, 0xea, + 0xd5, 0x71, 0x34, 0x98, 0x43, 0x26, 0xc5, 0xe6, 0xce, 0x34, 0x04, 0x4c, 0x2f, 0x1e, 0x4d, 0xee, + 0x76, 0x7d, 0xf9, 0x23, 0xc4, 0x89, 0x2b, 0x76, 0xf9, 0xb8, 0xf6, 0x5e, 0x71, 0x6b, 0xa6, 0x3a, + 0x95, 0xee, 0x10, 0xd4, 0x4c, 0xc6, 0x9b, 0xf8, 0x05, 0x04, 0x22, 0x24, 0xa4, 0xc2, 0x66, 0xb5, + 0x58, 0x72, 0x60, 0x00, 0x27, 0x89, 0x61, 0xd2, 0x11, 0xf1, 0x7f, 0xe3, 0x7c, 0x1a, 0x5f, 0x0a, + 0xf1, 0x9f, 0xe5, 0x7f, 0x7b, 0x63, 0x8a, 0xf8, 0x53, 0x21, 0x84, 0x22, 0x72, 0x0d, 0x72, 0xcf, + 0x78, 0xef, 0x03, 0xf9, 0x8f, 0x5b, 0xd8, 0x0d, 0x90, 0x80, 0xd3, 0x16, 0x18, 0x93, 0x91, 0x44, + 0x2e, 0xa4, 0xc9, 0x2d, 0xb6, 0x6c, 0xcf, 0xe3, 0xb1, 0x4b, 0x0c, 0x35, 0x83, 0x41, 0x68, 0x04, + 0x77, 0x45, 0x2c, 0x1d, 0xbb, 0xea, 0x55, 0x94, 0xb5, 0xc6, 0xb8, 0x30, 0x0c, 0x0d, 0x2a, 0xa8, + 0xba, 0xaa, 0xaa, 0xda, 0x59, 0x33, 0xb8, 0xc5, 0x0c, 0xcd, 0xb9, 0x6b, 0x6c, 0xbb, 0x9d, 0xdc, + 0x38, 0xa0, 0x04, 0x67, 0xb7, 0x24, 0x6e, 0xdf, 0xc9, 0xd3, 0x4d, 0x38, 0xb6, 0xcf, 0x6c, 0x7a, + 0x1a, 0xec, 0x3d, 0x1a, 0x68, 0x78, 0xa1, 0x20, 0xbe, 0xd2, 0xbf, 0xa1, 0xbc, 0x02, 0x8a, 0x46, + 0x0c, 0xd4, 0x5f, 0x43, 0x7f, 0xab, 0xce, 0x1a, 0x36, 0x20, 0xf4, 0x20, 0xf8, 0xf3, 0xc9, 0x47, + 0x07, 0x0f, 0x8c, 0xf1, 0xf5, 0x9d, 0xa0, 0xeb, 0xee, 0xe7, 0xbc, 0x21, 0x3c, 0xc2, 0x2a, 0x17, + 0x1b, 0xe5, 0xfd, 0x62, 0x7f, 0x1a, 0xec, 0x10, 0x84, 0x02, 0x84, 0xac, 0x80, 0x0d, 0x5c, 0x80, + 0xab, 0xe0, 0x00, 0x67, 0x06, 0xaf, 0x19, 0x6c, 0x3c, 0xdf, 0x85, 0xfa, 0xc9, 0x40, 0x06, 0x85, + 0x04, 0xf0, 0x00, 0x2f, 0x87, 0x80, 0x0f, 0x2c, 0x00, 0x67, 0x80, 0x3d, 0x4c, 0x61, 0xb2, 0x71, + 0xd0, 0xad, 0x7a, 0x63, 0x30, 0x5a, 0x61, 0x01, 0x01, 0x48, 0xba, 0xa9, 0x92, 0x3e, 0x71, 0xcb, + 0x8c, 0xb6, 0x25, 0xe2, 0xb3, 0xc6, 0x17, 0xdf, 0xd9, 0x91, 0x1c, 0xe1, 0x28, 0x35, 0x1c, 0x0f, + 0x2c, 0x64, 0xa0, 0xe5, 0x47, 0x78, 0x16, 0x01, 0x80, 0x53, 0x63, 0xa7, 0x95, 0xbb, 0x31, 0x03, + 0xd6, 0xa3, 0xfc, 0xbc, 0x3d, 0xff, 0x3c, 0xe2, 0xe3, 0x0a, 0x0a, 0xc4, 0x74, 0xf1, 0x00, 0xa6, + 0x78, 0xcb, 0x63, 0xaa, 0x5b, 0xea, 0xb4, 0xe7, 0x80, 0x30, 0x2e, 0x77, 0x07, 0x22, 0x41, 0x51, + 0x49, 0xcb, 0x49, 0xdc, 0xde, 0x2e, 0xea, 0xf7, 0x21, 0x9e, 0x13, 0xaa, 0xaa, 0xaa, 0xad, 0xf4, + 0x47, 0xae, 0x24, 0xea, 0xbd, 0x12, 0xa1, 0xae, 0x43, 0xee, 0xeb, 0x93, 0x6a, 0xbe, 0x6e, 0xef, + 0xe6, 0x14, 0xee, 0xff, 0x04, 0xf7, 0x9e, 0x11, 0x5b, 0xbb, 0x6e, 0x49, 0xc8, 0x26, 0x6f, 0xb0, + 0xc2, 0x81, 0x26, 0x25, 0xfc, 0xd4, 0xd3, 0xd3, 0xf6, 0xed, 0x17, 0x4b, 0xbb, 0x51, 0x22, 0xc3, + 0x01, 0x90, 0x89, 0x1d, 0xbd, 0xe6, 0xc1, 0x7a, 0x9b, 0x0b, 0xf0, 0x8c, 0x29, 0x38, 0x38, 0x28, + 0x62, 0xe2, 0x9a, 0x49, 0x0e, 0x29, 0x33, 0x85, 0x17, 0xcb, 0xd1, 0x1e, 0xe4, 0x40, 0x2f, 0x02, + 0x0c, 0x61, 0x10, 0x31, 0x72, 0xdb, 0xaa, 0xd2, 0x58, 0xb6, 0xcc, 0x71, 0x1a, 0xbf, 0x02, 0x44, + 0x15, 0xdd, 0xcb, 0x9d, 0x56, 0xc5, 0xea, 0xaa, 0xd8, 0x68, 0x85, 0x00, 0x4c, 0xfa, 0xdc, 0x6b, + 0x5f, 0xf6, 0xfd, 0xb1, 0x56, 0x31, 0x4e, 0x02, 0x80, 0x32, 0x14, 0x20, 0x80, 0xe1, 0xc0, 0x70, + 0x32, 0xa1, 0x92, 0x56, 0x62, 0x2e, 0x56, 0xb8, 0xac, 0x99, 0x4c, 0x1f, 0x0b, 0x63, 0x41, 0x8c, + 0x2b, 0x0c, 0x04, 0x01, 0x51, 0x40, 0xc1, 0x85, 0xc5, 0x05, 0xca, 0x19, 0xe1, 0xe0, 0x50, 0xe0, + 0xd5, 0x50, 0x47, 0xd8, 0x4b, 0x14, 0x4f, 0x78, 0xd5, 0x07, 0xae, 0x18, 0x12, 0x0a, 0x88, 0xcc, + 0x5e, 0x29, 0x26, 0x57, 0xa9, 0x62, 0x4e, 0xfa, 0xcb, 0x6c, 0x6d, 0x45, 0xf1, 0x0c, 0x23, 0x0a, + 0x54, 0xca, 0x84, 0xde, 0x4e, 0xca, 0x39, 0x04, 0x6d, 0x50, 0xb4, 0x6d, 0xae, 0xc9, 0x3c, 0x0e, + 0x1e, 0x60, 0x3e, 0xe8, 0xdc, 0x18, 0xf9, 0x81, 0xcf, 0x12, 0x10, 0xee, 0x0d, 0xcb, 0x62, 0xfc, + 0x44, 0x95, 0x81, 0x0d, 0x93, 0x21, 0x76, 0xcf, 0x0a, 0x82, 0xc4, 0xf8, 0x64, 0xb4, 0xad, 0x1c, + 0x3c, 0x2c, 0x51, 0x2f, 0x83, 0x88, 0xfc, 0xaa, 0xd7, 0xfa, 0x0f, 0x5f, 0x11, 0x84, 0x41, 0x84, + 0x29, 0xc9, 0xbd, 0xc6, 0x72, 0x6b, 0x55, 0x89, 0x04, 0x75, 0xd7, 0xab, 0x90, 0x93, 0xb3, 0x51, + 0x21, 0x45, 0x0c, 0x68, 0xff, 0xeb, 0xf8, 0x10, 0x44, 0x85, 0x35, 0x8b, 0xab, 0xa8, 0xad, 0xe2, + 0xb1, 0x5e, 0xef, 0x97, 0x04, 0x30, 0x57, 0x0a, 0x82, 0xa3, 0xfc, 0x7e, 0x3f, 0x09, 0xff, 0x57, + 0x56, 0x10, 0xf6, 0x05, 0x8d, 0xf7, 0xe9, 0xa7, 0xa7, 0xfd, 0xb6, 0xd2, 0xfd, 0x34, 0xf8, 0x77, + 0x00, 0x0f, 0xb1, 0x16, 0x92, 0x28, 0x44, 0x13, 0xe6, 0x4a, 0xa7, 0xdb, 0x6f, 0x77, 0x12, 0x3c, + 0x4b, 0x11, 0xee, 0x1d, 0xf9, 0x05, 0xc4, 0x1e, 0x12, 0xd0, 0x82, 0x97, 0x2f, 0xed, 0xc3, 0x6e, + 0x00, 0xc4, 0x01, 0x87, 0xa6, 0xe5, 0x11, 0xde, 0xdf, 0xfb, 0x21, 0x58, 0x57, 0x8a, 0x16, 0x62, + 0xd9, 0x2b, 0xc3, 0xb7, 0x45, 0x6f, 0xa7, 0xdb, 0x87, 0x58, 0x90, 0x01, 0xde, 0x6e, 0x30, 0xa1, + 0x45, 0x6f, 0xcf, 0x2f, 0x1f, 0xfb, 0xe2, 0x7f, 0xb6, 0xd9, 0x46, 0x6b, 0xfe, 0x24, 0x48, 0x50, + 0xc4, 0xa1, 0x56, 0x73, 0x9d, 0x29, 0xf9, 0x72, 0x8a, 0xf5, 0x09, 0xce, 0x3c, 0xff, 0x7f, 0x17, + 0x17, 0x84, 0xb2, 0x22, 0x42, 0xb1, 0xf2, 0x06, 0x10, 0x10, 0x30, 0x8d, 0xc3, 0xe8, 0x08, 0x3b, + 0x5a, 0xf2, 0xaa, 0x5a, 0x5b, 0x7d, 0xd8, 0xb6, 0xf3, 0xc7, 0x93, 0xee, 0x64, 0x95, 0x90, 0x52, + 0xd0, 0x1d, 0x7c, 0x98, 0x70, 0x5a, 0xf1, 0x10, 0xfc, 0x2d, 0xa6, 0x56, 0x2a, 0x62, 0x84, 0x94, + 0xfd, 0x0e, 0x06, 0xdc, 0x98, 0x93, 0xe2, 0x30, 0xe1, 0xee, 0x53, 0xea, 0xbe, 0x2b, 0x9b, 0x2a, + 0xab, 0x27, 0x05, 0xd5, 0xde, 0x4a, 0x4b, 0x26, 0x1e, 0x3c, 0xd4, 0x13, 0x37, 0x35, 0xd7, 0xe5, + 0x5c, 0x09, 0xe7, 0x83, 0xe6, 0xb9, 0xd8, 0x7c, 0xf0, 0x38, 0x46, 0x14, 0xbd, 0xec, 0xb1, 0xd7, + 0x10, 0x1a, 0x58, 0x58, 0x21, 0xbb, 0x09, 0xcb, 0x64, 0xf6, 0x2b, 0xdc, 0x6e, 0x98, 0x18, 0x42, + 0x21, 0x42, 0x16, 0x62, 0x38, 0x71, 0xc8, 0xf8, 0x80, 0x1e, 0x07, 0x38, 0xd4, 0x4b, 0xfb, 0x6c, + 0xf8, 0x30, 0x1d, 0xf8, 0xbc, 0x74, 0x0b, 0xe3, 0x10, 0xdb, 0x28, 0x00, 0x39, 0xab, 0x2e, 0x2a, + 0x90, 0xa2, 0x6a, 0x37, 0xb3, 0xfe, 0xff, 0x73, 0x26, 0xe6, 0x6f, 0xc3, 0x4e, 0x02, 0xcc, 0xd0, + 0x4e, 0x25, 0xfd, 0x92, 0x38, 0x14, 0xbf, 0x83, 0x3f, 0x77, 0x19, 0xeb, 0xc0, 0xd2, 0x08, 0x42, + 0x86, 0x15, 0xaf, 0x56, 0x9d, 0x83, 0xa1, 0x7a, 0xc0, 0x13, 0x78, 0x1d, 0x0b, 0xa1, 0x54, 0x91, + 0xe0, 0x07, 0x0e, 0x03, 0xd3, 0x80, 0x01, 0x65, 0x0a, 0x41, 0x20, 0x50, 0xaf, 0xba, 0x73, 0xdb, + 0xa3, 0x10, 0xce, 0x11, 0x12, 0x14, 0x29, 0x0e, 0x1a, 0xa6, 0x00, 0x47, 0xbf, 0xb4, 0xe9, 0xb2, + 0xe4, 0xab, 0x02, 0x4d, 0xa5, 0xf5, 0xdb, 0x82, 0x1c, 0xb7, 0xc1, 0x69, 0xa8, 0x8d, 0x78, 0x10, + 0x43, 0x23, 0x39, 0x55, 0x7a, 0xbd, 0x20, 0xd3, 0xb6, 0x8d, 0x43, 0xf4, 0xac, 0xfa, 0xf6, 0x4b, + 0x32, 0xdc, 0x6d, 0x06, 0x94, 0xcf, 0x0a, 0x65, 0x54, 0xa8, 0xef, 0xf5, 0x13, 0xc2, 0xec, 0xac, + 0x78, 0x28, 0x2f, 0x0a, 0x88, 0xa0, 0xdf, 0x01, 0xd4, 0x60, 0x1d, 0x61, 0x87, 0x4c, 0x50, 0xa5, + 0xeb, 0x92, 0xbc, 0x40, 0x90, 0xf6, 0x3a, 0x75, 0xab, 0x4b, 0x4c, 0x8c, 0x25, 0xb1, 0xe5, 0xef, + 0xf8, 0x76, 0x93, 0xb6, 0xbe, 0x53, 0xf1, 0x03, 0x82, 0xb0, 0xef, 0x66, 0x4f, 0x68, 0x9c, 0xa7, + 0x73, 0x30, 0xfa, 0xe3, 0xc5, 0x25, 0xbd, 0x32, 0xe6, 0x78, 0x07, 0x13, 0x48, 0xd8, 0xe8, 0x78, + 0xa9, 0x58, 0x8f, 0x7b, 0xb8, 0x9c, 0x4f, 0x89, 0x1b, 0x5d, 0x55, 0x55, 0x02, 0xfd, 0x0a, 0xa2, + 0x40, 0x0e, 0x4f, 0x1f, 0xc1, 0xa8, 0xd6, 0xb0, 0xee, 0x94, 0x98, 0xe4, 0x78, 0x05, 0x82, 0x60, + 0xf0, 0xb4, 0x07, 0x40, 0xbe, 0x5a, 0x8a, 0xb4, 0xf8, 0x1e, 0x44, 0x0d, 0xd5, 0x0e, 0x69, 0x47, + 0x0d, 0xc8, 0x31, 0xa8, 0x0a, 0x5f, 0xca, 0xd9, 0x71, 0xe0, 0x0e, 0x16, 0x0c, 0x76, 0xc2, 0xc1, + 0xd9, 0x20, 0x2a, 0x28, 0x0c, 0xb0, 0x01, 0xa1, 0xc8, 0x2f, 0x85, 0xc7, 0xe3, 0xb7, 0x2f, 0xf0, + 0x50, 0x20, 0x15, 0x48, 0xd2, 0x96, 0x7f, 0xb1, 0x04, 0x59, 0x25, 0xc1, 0x9c, 0xf9, 0xe7, 0xcc, + 0x06, 0x07, 0x93, 0x96, 0x11, 0xca, 0x4a, 0x71, 0x1a, 0xb8, 0x6f, 0x00, 0x72, 0x06, 0x8a, 0x2a, + 0x6d, 0xd2, 0xa4, 0x9a, 0xe9, 0x20, 0xf8, 0xfd, 0xe0, 0x68, 0x98, 0x00, 0xfb, 0x95, 0x0a, 0xd3, + 0x3c, 0x06, 0x09, 0x40, 0x0f, 0x93, 0x00, 0xfb, 0x4a, 0x32, 0xf4, 0x48, 0x8c, 0xe0, 0x1a, 0x9b, + 0x00, 0xcc, 0x01, 0x9e, 0x67, 0x7a, 0x69, 0x92, 0x88, 0xb8, 0x6d, 0x94, 0x00, 0x7a, 0xc0, 0x38, + 0xf9, 0x86, 0x13, 0xb4, 0x8d, 0x32, 0xb6, 0x4f, 0x63, 0x12, 0xc5, 0x6e, 0x4a, 0xd6, 0xba, 0xd7, + 0x7c, 0x28, 0xea, 0x62, 0x2f, 0xb5, 0x0c, 0xc2, 0x1f, 0xf9, 0x13, 0xa0, 0x30, 0xb5, 0xa6, 0x9e, + 0xd8, 0xab, 0xc0, 0x82, 0x08, 0x46, 0xde, 0xa4, 0xb3, 0x2d, 0x62, 0xe2, 0x34, 0x62, 0x92, 0xf4, + 0xd8, 0xc5, 0x6c, 0x5d, 0xd1, 0x43, 0x40, 0x26, 0x08, 0x3a, 0xb1, 0x4a, 0x32, 0xe4, 0x55, 0x1c, + 0x2e, 0x0c, 0x11, 0x73, 0xf9, 0xa8, 0xf8, 0x20, 0x08, 0x02, 0x68, 0x74, 0x41, 0xa8, 0x2c, 0xdc, + 0x8d, 0x08, 0x8d, 0x1f, 0xa0, 0xc3, 0x53, 0x4d, 0xf8, 0x81, 0x26, 0x29, 0x69, 0x76, 0x2c, 0x10, + 0x82, 0x10, 0x52, 0x49, 0x24, 0xfa, 0x44, 0xd7, 0x7e, 0x50, 0x31, 0xaf, 0x36, 0xe2, 0x47, 0x82, + 0x10, 0x42, 0x0a, 0x65, 0xc1, 0x59, 0x3b, 0x91, 0x60, 0xe9, 0x8a, 0xc5, 0x07, 0x97, 0xf7, 0x3e, + 0x63, 0xe0, 0xc6, 0xf0, 0x3c, 0x75, 0x07, 0xc4, 0x04, 0x2b, 0x7f, 0x87, 0x4d, 0x4b, 0x7c, 0x21, + 0xae, 0x3e, 0xf2, 0xf6, 0xcd, 0xfe, 0x95, 0xd7, 0x09, 0x08, 0x41, 0x8c, 0xe5, 0xf6, 0x9a, 0xf1, + 0x1a, 0x49, 0x5e, 0x4c, 0xfc, 0x87, 0xb6, 0xbf, 0x19, 0x8c, 0xab, 0xdc, 0x48, 0x9d, 0xd6, 0x78, + 0xa5, 0x3d, 0xd2, 0xf0, 0x43, 0x26, 0x0c, 0x32, 0xbe, 0xbe, 0x13, 0x9e, 0xfc, 0xbe, 0xe6, 0xe0, + 0x93, 0x8e, 0xd0, 0x58, 0x08, 0xfa, 0x47, 0x62, 0xa3, 0x0c, 0x08, 0x1a, 0x46, 0xe6, 0xe2, 0x4e, + 0x05, 0x28, 0x51, 0x9f, 0x62, 0x30, 0x63, 0xa9, 0x28, 0x05, 0xc0, 0xa7, 0x0d, 0x4a, 0x5a, 0xa0, + 0xe3, 0x81, 0xf0, 0xd4, 0x8c, 0x35, 0x1e, 0x00, 0x7c, 0xc8, 0x0c, 0x00, 0xa0, 0x13, 0x53, 0xf0, + 0x6b, 0x62, 0xba, 0x43, 0xcb, 0x0e, 0x60, 0x01, 0xa3, 0x83, 0x3d, 0x92, 0x84, 0x2a, 0x9f, 0xce, + 0x4e, 0xe5, 0xf1, 0x8b, 0x98, 0x63, 0x9b, 0x94, 0xcb, 0xb7, 0x62, 0xac, 0xe1, 0xd3, 0x80, 0x74, + 0x31, 0xc5, 0x02, 0x1e, 0xd9, 0xf6, 0xae, 0xaf, 0x8d, 0xe8, 0x40, 0x01, 0xeb, 0x86, 0x6b, 0x46, + 0xc4, 0xc7, 0xe2, 0x80, 0x82, 0xad, 0x61, 0xc5, 0x80, 0x6b, 0x6e, 0xc7, 0xe3, 0x33, 0x1b, 0x60, + 0xa0, 0x9e, 0x20, 0x75, 0xb0, 0x6e, 0x41, 0x30, 0xe2, 0x83, 0x6d, 0x1d, 0x34, 0x0e, 0xa6, 0x7e, + 0xe3, 0x16, 0xe6, 0x58, 0x58, 0xe1, 0x9f, 0xcf, 0xb4, 0xc4, 0xba, 0x24, 0x76, 0x38, 0xc6, 0x50, + 0xef, 0xe2, 0x26, 0x69, 0xc3, 0xb8, 0x01, 0xc2, 0x74, 0x55, 0x13, 0xef, 0x3f, 0xf9, 0x05, 0x0d, + 0xe3, 0x8d, 0xc5, 0x1e, 0x5a, 0xc5, 0x5a, 0x89, 0x78, 0x3b, 0x38, 0x65, 0xd9, 0x6b, 0x02, 0xc9, + 0x8b, 0xe8, 0x5b, 0x1c, 0xbf, 0x97, 0x8e, 0x0c, 0x02, 0x02, 0xcd, 0x33, 0x65, 0x6b, 0x74, 0x5d, + 0xc3, 0xff, 0x0f, 0x02, 0x04, 0x3b, 0x89, 0xd3, 0x31, 0x1b, 0x1c, 0x1d, 0x06, 0xde, 0x88, 0x69, + 0xc5, 0xc9, 0x43, 0x96, 0x01, 0xa9, 0xef, 0x33, 0x11, 0x9f, 0xe6, 0xed, 0xf8, 0x66, 0x14, 0x9b, + 0x2e, 0x0b, 0x68, 0x80, 0xf6, 0x55, 0x4e, 0x16, 0x16, 0xbe, 0x14, 0x20, 0x52, 0xd6, 0x00, 0x0f, + 0xcf, 0xb0, 0x1f, 0xe7, 0xc7, 0x8d, 0x0b, 0xaa, 0x88, 0xa6, 0x2f, 0x05, 0xc6, 0x10, 0x12, 0x1d, + 0x9b, 0x0a, 0x41, 0x60, 0x8e, 0xf7, 0xdb, 0x2c, 0x86, 0x0f, 0x73, 0x02, 0xe9, 0x87, 0x73, 0x07, + 0xbc, 0x03, 0x3f, 0xd3, 0x71, 0x57, 0xfc, 0x10, 0x08, 0x0a, 0xcd, 0x25, 0x30, 0x56, 0x38, 0xff, + 0x8c, 0x4a, 0x82, 0x64, 0x5f, 0xbf, 0x89, 0x17, 0x88, 0xec, 0x7e, 0x18, 0x12, 0x23, 0xa4, 0x2e, + 0xa4, 0x18, 0x98, 0x8b, 0xb3, 0xc3, 0x01, 0x00, 0x4a, 0x50, 0x70, 0x4f, 0x80, 0x71, 0xc6, 0xbc, + 0xa8, 0x8f, 0xc3, 0x88, 0x79, 0xe3, 0x1c, 0x10, 0x02, 0x07, 0x7e, 0x5f, 0xc4, 0x02, 0xcd, 0x65, + 0xce, 0x5e, 0xe7, 0x30, 0x2d, 0xbe, 0x02, 0xa2, 0x38, 0x91, 0x00, 0xa4, 0xc4, 0xc1, 0xf1, 0xc8, + 0x48, 0x0e, 0x0f, 0x1c, 0x3d, 0xc7, 0xb2, 0xff, 0xee, 0x2b, 0x6e, 0xb8, 0x40, 0x40, 0x2a, 0x88, + 0xe4, 0xd7, 0x54, 0xdb, 0x4c, 0x76, 0xca, 0x6b, 0x8e, 0x62, 0xf1, 0x21, 0xf1, 0x69, 0xbc, 0xac, + 0x81, 0x4d, 0x03, 0x0b, 0x4f, 0x4e, 0x2d, 0xad, 0x77, 0x39, 0x1b, 0x14, 0xb7, 0x10, 0xd3, 0xe1, + 0xae, 0x3f, 0xc6, 0x7d, 0x5d, 0xcb, 0x8d, 0xa7, 0xec, 0x8b, 0x35, 0xd7, 0x08, 0x11, 0xed, 0x79, + 0xb5, 0xfb, 0xfb, 0xdd, 0xe2, 0x38, 0x22, 0xd1, 0x83, 0xda, 0x00, 0x0d, 0x64, 0x60, 0x2c, 0x5e, + 0x48, 0xa1, 0xe2, 0x40, 0xce, 0xdc, 0x4a, 0x32, 0xb1, 0xdd, 0xfe, 0x3e, 0xcb, 0x0b, 0x1d, 0xbb, + 0x74, 0x70, 0xce, 0x3c, 0x74, 0x2c, 0x58, 0x77, 0x1f, 0x12, 0x13, 0xe3, 0xc3, 0xca, 0x18, 0x77, + 0xb4, 0xec, 0xc5, 0xb1, 0xf7, 0xf8, 0x81, 0xb0, 0x71, 0x1e, 0x0e, 0xbc, 0xef, 0xb3, 0xd3, 0x11, + 0xe9, 0x99, 0x85, 0x1d, 0x0b, 0xeb, 0x5d, 0x18, 0xca, 0xc7, 0xcd, 0x67, 0xcf, 0x1f, 0xe1, 0xec, + 0x01, 0x4a, 0x66, 0xa3, 0x07, 0x45, 0x9e, 0x67, 0xce, 0xa5, 0xb2, 0x87, 0xbe, 0x9b, 0x75, 0xab, + 0xfa, 0xfe, 0x12, 0xf9, 0x9a, 0xc0, 0xe4, 0x8c, 0x30, 0xe1, 0x6e, 0x39, 0xc3, 0x9d, 0xc9, 0x39, + 0x3f, 0x81, 0x20, 0x08, 0x03, 0x4a, 0x1b, 0x54, 0x4d, 0xfb, 0x8d, 0x4a, 0x8f, 0x3c, 0x3c, 0x70, + 0xaa, 0x75, 0x6a, 0xf5, 0xaa, 0xde, 0x21, 0x24, 0x96, 0x58, 0xb7, 0xff, 0x08, 0x87, 0x88, 0xec, + 0xd3, 0xce, 0x06, 0xa4, 0x00, 0xf8, 0xf0, 0x00, 0x10, 0x03, 0xe2, 0xa5, 0xf0, 0x70, 0x60, 0x3a, + 0xe4, 0xae, 0x5c, 0x35, 0xc0, 0x3b, 0x1f, 0x97, 0xd3, 0x86, 0xd4, 0x01, 0xb9, 0xdc, 0x2e, 0x72, + 0xf7, 0xe8, 0xdc, 0xf9, 0x90, 0x3c, 0x60, 0x0f, 0xf5, 0xe2, 0xd9, 0xbb, 0x38, 0xc4, 0x98, 0x39, + 0x0e, 0x1f, 0x42, 0xce, 0xdb, 0xfa, 0x62, 0x1e, 0x58, 0x40, 0x57, 0x83, 0x0b, 0x85, 0x5c, 0x27, + 0xab, 0xe1, 0xc1, 0x9c, 0xa9, 0x7c, 0x89, 0x1e, 0x02, 0x24, 0x14, 0x8d, 0x81, 0xc2, 0x9d, 0x49, + 0x41, 0x53, 0x80, 0x00, 0x8f, 0x15, 0x10, 0xc6, 0x58, 0xc1, 0xb0, 0x35, 0x4e, 0x47, 0xb6, 0x81, + 0x8c, 0x35, 0x17, 0xa9, 0x4c, 0xf0, 0xf3, 0xc3, 0x2c, 0x0c, 0xb0, 0x30, 0x54, 0x44, 0xa0, 0x60, + 0x71, 0x21, 0xac, 0x00, 0x04, 0x00, 0x93, 0xe6, 0x2d, 0xa6, 0x2e, 0xd9, 0xf5, 0xdf, 0x87, 0x54, + 0x00, 0x9e, 0xc3, 0x9d, 0xee, 0x41, 0xe5, 0xb4, 0x4f, 0xee, 0xb0, 0x60, 0xca, 0x50, 0x75, 0x05, + 0xb8, 0xd4, 0xf7, 0xbe, 0x92, 0x3e, 0xe5, 0xe7, 0x35, 0x5c, 0xb5, 0x97, 0x45, 0x08, 0x36, 0x76, + 0x81, 0x56, 0x1a, 0x71, 0x97, 0x4b, 0xbf, 0x82, 0x39, 0x3c, 0x3a, 0x84, 0xbb, 0x2b, 0x94, 0x97, + 0x7f, 0x8b, 0xbe, 0xfb, 0xbf, 0x8c, 0xdd, 0x53, 0x2b, 0x1f, 0x36, 0x46, 0x5d, 0x06, 0x1e, 0x74, + 0xef, 0xe1, 0x11, 0xba, 0x1a, 0xb1, 0xb1, 0xce, 0xcd, 0x57, 0x88, 0x8b, 0x11, 0x6d, 0xdc, 0x28, + 0xdd, 0x8c, 0xf5, 0x98, 0x05, 0xec, 0x5d, 0xde, 0x1a, 0xe4, 0xed, 0x3b, 0xe3, 0x85, 0x22, 0x6e, + 0xd3, 0x1c, 0x5e, 0x5d, 0x20, 0x76, 0xdf, 0xc7, 0x15, 0xf2, 0xa0, 0x63, 0xdd, 0x93, 0x19, 0x43, + 0xdf, 0x36, 0xaa, 0xbe, 0x6e, 0x6c, 0x9b, 0x8d, 0x33, 0x76, 0xf0, 0x6b, 0x2c, 0x3a, 0xc0, 0x95, + 0x9a, 0xd4, 0x21, 0x12, 0xe9, 0xf0, 0x00, 0x38, 0xc1, 0x51, 0x01, 0x29, 0x20, 0x00, 0x1a, 0x50, + 0x2a, 0xc8, 0xd4, 0xd4, 0x88, 0xff, 0x87, 0x67, 0x00, 0x57, 0xa2, 0x90, 0x9d, 0xc4, 0xef, 0x5f, + 0xef, 0xdb, 0xd5, 0x32, 0xf6, 0x78, 0xc9, 0xd9, 0xd9, 0xd9, 0xc0, 0xe3, 0x98, 0x6b, 0x19, 0x0f, + 0xb7, 0xef, 0x86, 0xb0, 0x6b, 0x61, 0x74, 0x05, 0x3f, 0x95, 0xfd, 0xf0, 0x16, 0x20, 0xe4, 0x69, + 0x09, 0x45, 0x59, 0x83, 0x54, 0x63, 0x2c, 0x6c, 0xc6, 0x61, 0x6c, 0xa4, 0x3a, 0xa1, 0x02, 0xf1, + 0xf4, 0x59, 0x96, 0x8e, 0x01, 0xc3, 0x80, 0x01, 0xe9, 0x80, 0x01, 0xe0, 0xf4, 0x00, 0x6a, 0x15, + 0x98, 0x04, 0x18, 0x01, 0xe0, 0xd6, 0xdb, 0x0b, 0x3d, 0x96, 0x16, 0x9a, 0x69, 0xc3, 0x98, 0x05, + 0xd0, 0x96, 0x43, 0x05, 0x5c, 0xb7, 0xb7, 0xbb, 0xee, 0x32, 0x1d, 0x1a, 0x79, 0x4c, 0x45, 0xc6, + 0xa4, 0xb6, 0x3e, 0x32, 0xa7, 0xef, 0xa2, 0x1f, 0x09, 0x4b, 0x20, 0xaf, 0x26, 0x4e, 0x6d, 0xb6, + 0xda, 0x69, 0x8b, 0x62, 0x71, 0xf0, 0xb4, 0xc4, 0x80, 0x01, 0x63, 0x02, 0xcb, 0x13, 0x66, 0x53, + 0x02, 0x19, 0x7b, 0x9e, 0x6c, 0xfc, 0x5f, 0x0b, 0x25, 0xe2, 0x3f, 0x1c, 0x9c, 0x61, 0x76, 0x7a, + 0x58, 0x91, 0xce, 0x73, 0x17, 0x38, 0x20, 0x08, 0x97, 0xf6, 0xca, 0x93, 0xe1, 0x10, 0x81, 0x37, + 0x71, 0x5b, 0xdb, 0x6c, 0x99, 0xf1, 0x10, 0x97, 0x65, 0xcf, 0xe3, 0xfa, 0x2b, 0x97, 0xc1, 0x18, + 0xa5, 0x5f, 0xa5, 0x0d, 0x90, 0xa0, 0x02, 0x08, 0x0f, 0xd3, 0x72, 0xf5, 0x03, 0x56, 0x07, 0xcf, + 0x91, 0x80, 0xa6, 0x16, 0x18, 0xd7, 0x6b, 0x9d, 0xb5, 0xe5, 0xb5, 0x57, 0x05, 0x0d, 0x7d, 0xd1, + 0x4c, 0x6b, 0xcb, 0x0b, 0x1a, 0x8a, 0x37, 0xa8, 0xa0, 0x90, 0xa2, 0xd8, 0xfe, 0x97, 0x49, 0xde, + 0xff, 0x0b, 0x47, 0x2b, 0xe5, 0x08, 0x54, 0xc7, 0x08, 0x9e, 0x38, 0x10, 0x9e, 0x0c, 0xf0, 0x61, + 0x31, 0xe2, 0xb8, 0xae, 0xf2, 0x75, 0xef, 0x8c, 0xa0, 0x4d, 0x99, 0x8e, 0xa3, 0x06, 0x32, 0xd1, + 0x82, 0x9c, 0x92, 0x2d, 0x8f, 0x4e, 0x1f, 0x50, 0x35, 0xc2, 0xe3, 0xc0, 0x03, 0x9c, 0x09, 0x03, + 0x27, 0x78, 0x86, 0x8a, 0x17, 0xba, 0x4e, 0xab, 0x0c, 0xf9, 0x3d, 0x88, 0x70, 0x3b, 0x6a, 0x7b, + 0x9e, 0x3c, 0x9c, 0xd0, 0x5e, 0x96, 0x00, 0xe4, 0x35, 0xb4, 0xda, 0x79, 0x0f, 0x3d, 0xd1, 0xe1, + 0x02, 0x9c, 0x60, 0xa5, 0xc3, 0x59, 0xba, 0x91, 0xdb, 0x4f, 0xdd, 0x3d, 0x3c, 0x5f, 0xcd, 0x98, + 0x30, 0x1a, 0xf8, 0x47, 0x64, 0xc1, 0x88, 0xa4, 0x2c, 0xca, 0x83, 0x6a, 0x8d, 0x81, 0x00, 0x43, + 0xef, 0x40, 0x2f, 0x13, 0x76, 0xa9, 0x12, 0x18, 0xfe, 0x7c, 0x12, 0x72, 0x09, 0x55, 0xfc, 0x82, + 0xab, 0x52, 0xc1, 0x88, 0x44, 0x12, 0xc2, 0x01, 0x15, 0x43, 0xa0, 0x00, 0x29, 0x72, 0x42, 0xc7, + 0x12, 0xa4, 0xa6, 0xcb, 0x96, 0x31, 0x78, 0x28, 0xea, 0x06, 0x53, 0x14, 0x98, 0x81, 0x00, 0xa8, + 0xa3, 0x90, 0x17, 0x23, 0x07, 0x00, 0x7c, 0x6e, 0xdb, 0x66, 0xf0, 0x76, 0xf6, 0x42, 0xf0, 0x07, + 0x4a, 0x1b, 0x46, 0x00, 0x12, 0xad, 0x68, 0x61, 0x6d, 0xb2, 0x43, 0xff, 0xdb, 0x09, 0x60, 0x2c, + 0xb5, 0x42, 0x58, 0x0d, 0x7d, 0x73, 0x16, 0x17, 0xe3, 0x58, 0x9e, 0xf1, 0x2c, 0x1c, 0xc8, 0x96, + 0x0c, 0xe7, 0x62, 0xb7, 0x0a, 0x70, 0x73, 0xe7, 0x53, 0x4f, 0xf8, 0x6b, 0x00, 0x8f, 0x6b, 0x21, + 0x8e, 0x87, 0x73, 0x73, 0xab, 0xaf, 0xd7, 0xb4, 0xda, 0x8e, 0xa7, 0x93, 0x83, 0xee, 0x59, 0x67, + 0x7c, 0x7e, 0xf8, 0xca, 0xd6, 0x21, 0xcd, 0x28, 0x83, 0xce, 0xe7, 0x0f, 0xd6, 0xb4, 0x8b, 0x82, + 0xb2, 0xc1, 0xf8, 0x29, 0x13, 0x5d, 0xf6, 0xbf, 0x48, 0x1c, 0x57, 0x26, 0x00, 0xa9, 0x44, 0x95, + 0x00, 0x18, 0x80, 0x79, 0xe1, 0x6c, 0x9c, 0x05, 0x6f, 0x31, 0xf0, 0x4b, 0x2c, 0xe5, 0x9c, 0xfb, + 0xef, 0xf3, 0x12, 0xf7, 0xf1, 0x77, 0xbb, 0xce, 0x18, 0x0b, 0xe0, 0xb3, 0x82, 0x4e, 0xef, 0x95, + 0x71, 0x5e, 0x3c, 0xb2, 0x70, 0xd0, 0xdc, 0xbf, 0xc4, 0xcd, 0x8a, 0x59, 0x8b, 0x97, 0xc9, 0xfe, + 0x2a, 0x4a, 0x15, 0x1e, 0x05, 0x9a, 0x52, 0xff, 0x08, 0x81, 0x64, 0x29, 0x03, 0x70, 0x04, 0xa0, + 0x7c, 0x94, 0x98, 0xdc, 0x4c, 0x54, 0x24, 0x1c, 0x16, 0x00, 0xcf, 0x50, 0xaa, 0x74, 0x92, 0x84, + 0x60, 0xf3, 0xe7, 0x03, 0x87, 0x1c, 0x2c, 0xce, 0x70, 0xff, 0xcc, 0x78, 0x29, 0x05, 0x25, 0x69, + 0x45, 0xc4, 0xf1, 0xcf, 0x9a, 0x88, 0xa4, 0x88, 0x7f, 0x85, 0xb7, 0xf8, 0xe9, 0x3d, 0x4f, 0xe1, + 0x61, 0x96, 0x1d, 0xd3, 0x8b, 0x8a, 0x6a, 0x2f, 0xe4, 0x26, 0xa8, 0x6b, 0x90, 0xa7, 0xc7, 0xb1, + 0x84, 0xf9, 0xb2, 0xfc, 0xfc, 0xc6, 0xbd, 0xc2, 0x3d, 0x1f, 0xaf, 0x90, 0xca, 0xbb, 0x0c, 0x44, + 0x80, 0x11, 0x16, 0xa9, 0xef, 0x37, 0xf1, 0x3b, 0x3d, 0x6d, 0x8e, 0x99, 0x78, 0xab, 0x2d, 0x69, + 0xa6, 0xdf, 0x58, 0x55, 0xc0, 0x61, 0x19, 0x41, 0xd4, 0x14, 0xb4, 0xea, 0x99, 0x55, 0xc9, 0x4b, + 0x69, 0xa6, 0x8a, 0xb6, 0xcf, 0x1c, 0x44, 0x50, 0x84, 0x35, 0x8f, 0x52, 0xef, 0x37, 0xf1, 0xc4, + 0x69, 0xa7, 0x18, 0xed, 0x55, 0xa3, 0xc0, 0x38, 0x2e, 0x58, 0x01, 0x8a, 0x61, 0x6c, 0x44, 0xfc, + 0x49, 0x77, 0x77, 0xbb, 0xf8, 0x23, 0xcb, 0xfa, 0x8c, 0xe4, 0xaa, 0xac, 0x4f, 0x35, 0xb3, 0x7f, + 0xc1, 0x66, 0x93, 0xbc, 0xbd, 0x3b, 0x2c, 0x18, 0xa0, 0xdc, 0xa6, 0x2e, 0x7c, 0x67, 0x71, 0x5c, + 0x48, 0x7c, 0x49, 0xe2, 0x8c, 0xff, 0x8a, 0xe2, 0x0b, 0xb9, 0x1e, 0xe6, 0x20, 0x48, 0x99, 0xc7, + 0x0e, 0xe1, 0x7c, 0xd5, 0x8d, 0xfc, 0x85, 0xb4, 0x6f, 0xae, 0x3a, 0x72, 0x92, 0x90, 0x74, 0x33, + 0x53, 0x43, 0x93, 0x61, 0x7e, 0x6c, 0x47, 0x29, 0x79, 0x7a, 0x8b, 0xae, 0x52, 0x3b, 0xe1, 0x8e, + 0x5b, 0x0e, 0x10, 0xbd, 0x8b, 0xf4, 0x7a, 0xae, 0x63, 0x26, 0x64, 0x96, 0x83, 0x5c, 0x27, 0x17, + 0xad, 0x69, 0xcb, 0xde, 0x9a, 0x93, 0x85, 0x3b, 0x2d, 0xb7, 0xfb, 0x2d, 0xde, 0x1c, 0xe4, 0x10, + 0xba, 0xfa, 0x13, 0xb4, 0x1b, 0x76, 0x6a, 0xac, 0x1c, 0xf0, 0x48, 0x75, 0xd7, 0xa0, 0x32, 0x20, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x4d, 0x26, 0xb0, 0xab, 0xc1, 0x19, 0xaa, 0xab, 0xd5, 0xc1, + 0x25, 0xef, 0xaa, 0xe0, 0xaa, 0xa3, 0x4b, 0x99, 0x27, 0x6e, 0x35, 0x45, 0x56, 0xf8, 0x2a, 0xc7, + 0x4d, 0xcf, 0xf7, 0xfe, 0x7f, 0xbd, 0xf0, 0x87, 0x55, 0x5a, 0xef, 0x72, 0xf6, 0x2e, 0xf7, 0xf1, + 0x46, 0xb5, 0x52, 0xb3, 0xaf, 0xcd, 0x5a, 0x50, 0xf7, 0x04, 0xf5, 0x17, 0x27, 0x2f, 0x51, 0x75, + 0x17, 0xec, 0x3b, 0x12, 0x00, 0x23, 0xb1, 0x35, 0x3b, 0x10, 0x3b, 0xf6, 0x6e, 0x9a, 0x64, 0xf5, + 0xdb, 0x55, 0x4d, 0x70, 0x66, 0x45, 0x5e, 0x9a, 0xf8, 0x04, 0x86, 0x34, 0x50, 0x3d, 0xb5, 0xc5, + 0xa5, 0x85, 0x05, 0x2a, 0x00, 0xab, 0x05, 0xd3, 0x00, 0x12, 0x4e, 0x80, 0x00, 0xb6, 0x44, 0x06, + 0x19, 0x43, 0x98, 0x25, 0x16, 0x7e, 0xba, 0x00, 0x04, 0x96, 0x1c, 0x00, 0x38, 0x34, 0x8f, 0x76, + 0x2f, 0x94, 0x15, 0xe6, 0x60, 0xbc, 0x18, 0xa3, 0x00, 0x04, 0xa0, 0x18, 0x00, 0x12, 0xa3, 0xf9, + 0xd4, 0xfe, 0x1d, 0x39, 0x7e, 0x1c, 0xc0, 0x13, 0x93, 0x38, 0x8c, 0x7b, 0xc2, 0x60, 0xc8, 0x38, + 0xfd, 0xd8, 0x73, 0xf3, 0x9a, 0x0a, 0xa6, 0x32, 0xa2, 0xd4, 0xb5, 0x8a, 0xb2, 0xc5, 0x8a, 0x2d, + 0xca, 0xa4, 0xc0, 0xf6, 0xba, 0x5d, 0x1e, 0x74, 0xf3, 0xa5, 0xd1, 0x74, 0x22, 0x05, 0x1f, 0x2f, + 0xd7, 0xf7, 0xf1, 0xb0, 0x98, 0x1a, 0xe2, 0xe2, 0x21, 0xa5, 0x46, 0x61, 0xbf, 0x23, 0xf1, 0x98, + 0x77, 0xd1, 0xb1, 0x9f, 0x3e, 0x33, 0x8c, 0x50, 0xca, 0x5c, 0xc1, 0x08, 0x87, 0xfe, 0x27, 0x6d, + 0xdb, 0x7e, 0x7a, 0xe4, 0x2c, 0x49, 0xfb, 0xe0, 0x8c, 0x46, 0xaa, 0xdf, 0x75, 0x55, 0x55, 0xcc, + 0x26, 0x94, 0xbf, 0xc2, 0x06, 0xaa, 0x1c, 0x8d, 0x4a, 0xd3, 0x54, 0x44, 0x61, 0x81, 0x9c, 0x4c, + 0x29, 0xd3, 0x48, 0x1d, 0x5c, 0x29, 0x8d, 0xaf, 0x4f, 0x87, 0x15, 0x35, 0xf4, 0xdf, 0xe1, 0x0d, + 0xda, 0x8f, 0x5c, 0x57, 0x43, 0xbd, 0xaf, 0x81, 0xbc, 0x61, 0x95, 0x67, 0x84, 0x4a, 0xab, 0xb6, + 0x9c, 0xc7, 0x46, 0x2d, 0x2f, 0xe1, 0x3d, 0x27, 0x1a, 0x5a, 0xa5, 0x0f, 0x70, 0x4f, 0x17, 0x14, + 0xd4, 0x5d, 0x45, 0xeb, 0xd8, 0x6e, 0x50, 0x04, 0x52, 0xd9, 0x0b, 0x01, 0x44, 0xcf, 0x5a, 0xdd, + 0x37, 0x7b, 0x77, 0x3d, 0x77, 0x6f, 0xf8, 0x28, 0x8d, 0x20, 0xfa, 0xfb, 0x78, 0xfa, 0x96, 0x06, + 0x6a, 0x00, 0x08, 0x10, 0xe8, 0xbc, 0x85, 0x64, 0x0b, 0xf3, 0x1f, 0xf1, 0x20, 0xe3, 0xb0, 0x92, + 0xaf, 0x59, 0x03, 0x96, 0x9b, 0xc5, 0xb4, 0xfe, 0x1b, 0x64, 0x02, 0x69, 0x01, 0x08, 0x98, 0xb9, + 0x29, 0x26, 0x09, 0x5c, 0xef, 0x70, 0x01, 0xf7, 0xec, 0x90, 0xf0, 0x54, 0xea, 0x57, 0xf1, 0x81, + 0x1a, 0xf7, 0xc2, 0x15, 0x6c, 0x7f, 0x83, 0xff, 0xf8, 0xd2, 0x05, 0xc1, 0xd5, 0x88, 0xc2, 0xa3, + 0x14, 0x3b, 0xe1, 0xdf, 0x8c, 0x50, 0xdf, 0x9b, 0x18, 0xa1, 0xb9, 0xfe, 0xdb, 0x18, 0x49, 0x49, + 0x0e, 0xe8, 0x8e, 0x3c, 0x31, 0x5a, 0x4b, 0x59, 0xbf, 0xf0, 0x43, 0xac, 0x5f, 0xd5, 0xc2, 0x85, + 0xb5, 0x48, 0xe8, 0x59, 0x54, 0xcf, 0x9b, 0xae, 0x2b, 0xbe, 0x20, 0x58, 0x43, 0x17, 0xb2, 0xc1, + 0x73, 0xe1, 0x22, 0x4c, 0x18, 0x15, 0x64, 0x46, 0x81, 0x12, 0xe1, 0x03, 0xb3, 0xeb, 0xf1, 0x34, + 0x36, 0xb1, 0x47, 0xca, 0x18, 0xd7, 0xc5, 0x52, 0x39, 0x82, 0x4b, 0xd6, 0x5a, 0xe5, 0x67, 0x13, + 0x13, 0x2d, 0xcf, 0x7e, 0xf7, 0xf1, 0x85, 0x44, 0x95, 0xeb, 0x26, 0x3b, 0xeb, 0xcc, 0xc6, 0x27, + 0xf0, 0x50, 0x64, 0x88, 0xca, 0x6f, 0xc7, 0x75, 0xeb, 0x6e, 0xfa, 0x16, 0xc9, 0xfa, 0x1a, 0xe4, + 0x5f, 0x43, 0xa2, 0xae, 0xb1, 0x44, 0x07, 0x59, 0xc0, 0x0a, 0x94, 0xbf, 0xda, 0xff, 0xbd, 0x4d, + 0x36, 0xcf, 0xe5, 0xe6, 0xfa, 0x71, 0xf1, 0xf6, 0x53, 0x46, 0xd9, 0xeb, 0xf0, 0xeb, 0x30, 0x0a, + 0xe2, 0x61, 0x9d, 0x08, 0x8d, 0x57, 0xfe, 0x0c, 0x5f, 0x1e, 0x03, 0x52, 0x67, 0x8a, 0x07, 0x2a, + 0xe3, 0x8f, 0x4c, 0xaa, 0xeb, 0xf0, 0xd9, 0x04, 0x00, 0x52, 0x11, 0x47, 0x26, 0x1b, 0x24, 0x0c, + 0x74, 0x9b, 0x43, 0xc5, 0x85, 0x41, 0xc0, 0x77, 0x58, 0x85, 0x64, 0x27, 0x0c, 0x03, 0xb5, 0x81, + 0x0f, 0x2a, 0x19, 0x86, 0x42, 0xa7, 0xb2, 0x20, 0x58, 0x7a, 0xe7, 0xf7, 0xc6, 0xb0, 0xa8, 0x5c, + 0x4b, 0x91, 0x82, 0x86, 0xd4, 0x61, 0x3c, 0xb1, 0x88, 0xe0, 0xf5, 0x83, 0x14, 0x32, 0xa3, 0x17, + 0xcc, 0xa2, 0xd6, 0x54, 0xf9, 0x43, 0x92, 0xe3, 0xfe, 0xeb, 0xaf, 0x94, 0xab, 0xab, 0xe1, 0x42, + 0xbd, 0xde, 0xf3, 0xfb, 0xbb, 0xbd, 0x7b, 0xd7, 0x62, 0x57, 0x55, 0xc5, 0x5b, 0xdd, 0x0c, 0x91, + 0x47, 0xf8, 0xf1, 0x97, 0x7d, 0xbb, 0xdb, 0xb5, 0x89, 0x85, 0x0a, 0xa3, 0x29, 0xd7, 0x61, 0x9f, + 0x86, 0x29, 0x91, 0xed, 0x5d, 0x09, 0x37, 0xf8, 0xca, 0x7b, 0x4a, 0xc9, 0x0d, 0x32, 0xf6, 0x9b, + 0x76, 0x35, 0xf1, 0x76, 0xbc, 0x29, 0x58, 0xf2, 0x08, 0x9d, 0xfd, 0xee, 0xb4, 0x49, 0x9b, 0x33, + 0xf6, 0x16, 0xfc, 0x4c, 0x13, 0x78, 0xad, 0x0c, 0xf9, 0xc3, 0x2e, 0xf7, 0xca, 0x2d, 0x29, 0xaf, + 0x88, 0xaf, 0x7c, 0x24, 0x31, 0xec, 0x1e, 0xe3, 0xbd, 0x25, 0xd4, 0xca, 0x31, 0x30, 0x99, 0x97, + 0x2b, 0x54, 0x6b, 0x89, 0x82, 0x31, 0x2a, 0xa1, 0xe4, 0xfd, 0x7f, 0xfe, 0x51, 0x6b, 0x36, 0x78, + 0x98, 0xce, 0x61, 0x8e, 0x58, 0x64, 0xe1, 0x3d, 0x64, 0xc3, 0xfb, 0x4c, 0x1f, 0xa2, 0x95, 0x3e, + 0x2f, 0x84, 0xba, 0x8f, 0x2e, 0x4e, 0x1e, 0x9c, 0x00, 0x6b, 0xc9, 0xf1, 0x37, 0x9f, 0x7e, 0xb6, + 0xdb, 0xf3, 0x52, 0x32, 0x7e, 0xa6, 0xa8, 0x7e, 0xf8, 0xc9, 0xed, 0xa6, 0x9f, 0xc1, 0x00, 0x50, + 0x71, 0xc0, 0x1c, 0x38, 0x0e, 0x13, 0x62, 0xb0, 0x62, 0x4a, 0x06, 0xac, 0x21, 0x90, 0x28, 0x4a, + 0x7b, 0xcb, 0x05, 0x27, 0x78, 0xa2, 0x09, 0x45, 0xd0, 0xb8, 0xf0, 0x00, 0x21, 0x7c, 0x00, 0x0a, + 0x50, 0xd8, 0x80, 0x4a, 0x22, 0xd0, 0x33, 0x2c, 0x07, 0x00, 0x10, 0x01, 0x2c, 0x60, 0x10, 0x86, + 0xcb, 0x24, 0x0b, 0x03, 0xd3, 0x88, 0x01, 0xe1, 0xd5, 0x51, 0xcc, 0x72, 0x26, 0xe8, 0xfe, 0x03, + 0x82, 0x2e, 0xc2, 0x50, 0xa9, 0x5a, 0x2c, 0x81, 0x83, 0x7b, 0xde, 0xb5, 0xc6, 0x22, 0xf8, 0xc5, + 0x46, 0x13, 0xf1, 0x8c, 0x27, 0x9b, 0x10, 0x4b, 0xae, 0x28, 0x2c, 0x84, 0x4e, 0xc7, 0x03, 0x97, + 0x9d, 0x36, 0xff, 0x0a, 0x4d, 0xd9, 0x9b, 0x1d, 0x49, 0x07, 0x62, 0x46, 0x6f, 0xac, 0xbd, 0x54, + 0xe4, 0xa3, 0xe5, 0x3e, 0x4f, 0x5c, 0xd7, 0xab, 0x2f, 0x67, 0xbb, 0x77, 0xc1, 0x59, 0x33, 0xf9, + 0xfd, 0xcb, 0xc9, 0xaf, 0x68, 0x09, 0xcf, 0x82, 0x61, 0x13, 0xe5, 0x9c, 0xbc, 0x8a, 0x37, 0x3c, + 0x40, 0xe3, 0xa4, 0x43, 0x42, 0x6c, 0x72, 0x89, 0x8e, 0x61, 0x01, 0x30, 0x80, 0x9b, 0xf8, 0x98, + 0xcf, 0x1b, 0x3c, 0xc2, 0xb1, 0xce, 0xc4, 0x79, 0x59, 0xb4, 0x86, 0xfc, 0x40, 0x26, 0xb7, 0x6f, + 0xf0, 0x2a, 0x42, 0xb6, 0x36, 0x37, 0xf8, 0xf2, 0x2b, 0x29, 0x9a, 0x94, 0xa9, 0x29, 0x33, 0xf1, + 0x7a, 0x35, 0xde, 0x5c, 0xc4, 0xca, 0x74, 0x3a, 0x98, 0x8f, 0xc2, 0x9d, 0x53, 0xe5, 0xc2, 0x66, + 0xda, 0x07, 0xb4, 0xfd, 0xf0, 0x58, 0x69, 0x08, 0x28, 0xcc, 0x98, 0x5f, 0x12, 0x59, 0x72, 0x77, + 0x3f, 0xf1, 0x10, 0x99, 0xbd, 0xbd, 0xa9, 0x33, 0x12, 0x24, 0x5d, 0x2d, 0x89, 0x71, 0xd1, 0xff, + 0x08, 0x56, 0x4e, 0x56, 0x23, 0xb2, 0xb1, 0x9a, 0x1f, 0xcc, 0x15, 0x5d, 0x4f, 0x88, 0xf8, 0x26, + 0x08, 0x10, 0xc5, 0x2c, 0x86, 0xea, 0x92, 0x54, 0xf8, 0x70, 0xac, 0x61, 0x46, 0xa0, 0xc0, 0x02, + 0x36, 0x20, 0x07, 0xe4, 0x0f, 0x47, 0xfc, 0x17, 0x30, 0xfc, 0x14, 0x79, 0x44, 0xd5, 0xb8, 0x4c, + 0xee, 0x8a, 0xfe, 0x1f, 0xa2, 0xb2, 0x3d, 0x96, 0x95, 0x6a, 0x3d, 0x8f, 0x37, 0x64, 0x7f, 0x5e, + 0x3f, 0xfa, 0xc5, 0xf0, 0x47, 0x9a, 0xa8, 0xf6, 0x7c, 0x16, 0x5d, 0x93, 0x53, 0x50, 0xd4, 0xf5, + 0x5c, 0x63, 0xe2, 0x32, 0xbb, 0xf2, 0x9c, 0x46, 0x08, 0x41, 0x3d, 0x59, 0x94, 0xad, 0xa4, 0xc9, + 0x3a, 0xf7, 0x07, 0xd8, 0x4c, 0xe4, 0x82, 0x00, 0x8f, 0x88, 0x9b, 0x90, 0x8b, 0x59, 0x38, 0xb2, + 0x6e, 0xfb, 0xb7, 0xe0, 0x8a, 0x38, 0xbc, 0xfb, 0xec, 0xe6, 0xcf, 0x88, 0x96, 0x74, 0x0c, 0x76, + 0x35, 0xf8, 0x8b, 0x33, 0xcf, 0x8c, 0xf1, 0x11, 0x39, 0xb0, 0xc9, 0xe4, 0x8d, 0x2c, 0x44, 0x95, + 0x6b, 0xf3, 0x17, 0x77, 0x5c, 0x51, 0xb9, 0x7b, 0xbf, 0x3f, 0x7b, 0x96, 0x18, 0xc8, 0x46, 0x37, + 0x36, 0x1b, 0x9e, 0x1c, 0x1d, 0x58, 0x38, 0x3b, 0x0b, 0x32, 0x50, 0x02, 0xa1, 0x70, 0x0a, 0x41, + 0x66, 0x71, 0xc3, 0xce, 0x08, 0xa8, 0x28, 0x8a, 0x8e, 0xe1, 0xd1, 0x84, 0x51, 0xd0, 0x0e, 0x05, + 0xcf, 0x97, 0xc4, 0x61, 0x0f, 0x38, 0x02, 0xf7, 0x33, 0xb1, 0x65, 0x38, 0x9a, 0xdd, 0xf3, 0xe9, + 0x27, 0xfe, 0x7a, 0x97, 0x69, 0xb6, 0xf8, 0x09, 0xfa, 0xcf, 0xf3, 0xde, 0xee, 0xea, 0xc6, 0x21, + 0xd9, 0xdb, 0x39, 0x24, 0x93, 0xef, 0xe1, 0xc2, 0xc0, 0xe3, 0x84, 0xa0, 0x1d, 0xe9, 0x29, 0x60, + 0x19, 0x88, 0x56, 0xc5, 0xfc, 0x18, 0x2c, 0xc7, 0x8d, 0xcd, 0x81, 0x70, 0xa9, 0x38, 0x00, 0x12, + 0xf6, 0x56, 0x25, 0xc9, 0x00, 0xa8, 0x7e, 0x25, 0x1c, 0x9e, 0x3f, 0x9c, 0x07, 0xcb, 0xf9, 0x08, + 0x46, 0x40, 0x4f, 0x06, 0x83, 0x70, 0xea, 0x62, 0x0c, 0x02, 0x03, 0x10, 0x67, 0x11, 0xfe, 0x23, + 0xec, 0x2c, 0xc4, 0xef, 0x2f, 0x5e, 0xf9, 0xb7, 0x77, 0xf0, 0x51, 0x55, 0xa4, 0xb5, 0xb7, 0xc5, + 0xd5, 0x55, 0x4b, 0xde, 0x37, 0xf1, 0x04, 0x3e, 0x5f, 0xcd, 0x9e, 0x11, 0x3a, 0xc6, 0xa3, 0xe1, + 0x4b, 0xab, 0x0b, 0x68, 0xd3, 0x5b, 0xff, 0x05, 0xba, 0xb5, 0x5b, 0x03, 0x01, 0x41, 0xb7, 0xc7, + 0xe9, 0xc9, 0x1b, 0xa2, 0x9d, 0x81, 0xa3, 0x26, 0x7f, 0x12, 0x2f, 0x67, 0x20, 0xdd, 0xef, 0xf1, + 0x06, 0xe7, 0x50, 0xf6, 0xa8, 0x45, 0xe2, 0x76, 0xab, 0x18, 0x85, 0x45, 0x4b, 0xc8, 0x55, 0xaf, + 0xd9, 0x22, 0xeb, 0xf2, 0x5d, 0xdd, 0xfc, 0x45, 0xc4, 0xb8, 0xf8, 0x86, 0x82, 0x8c, 0xf8, 0xfc, + 0xc2, 0x22, 0x1e, 0x7b, 0x6b, 0x8d, 0x86, 0x43, 0xde, 0x0d, 0xa8, 0x38, 0xe9, 0x8b, 0x54, 0xfb, + 0xe8, 0xbf, 0xfa, 0xbc, 0xf0, 0x17, 0x20, 0x3a, 0x06, 0x86, 0x80, 0xc1, 0xc0, 0x18, 0xc3, 0x5b, + 0xcd, 0x16, 0x2c, 0x63, 0x17, 0x38, 0x1c, 0x03, 0xb1, 0xdc, 0xfb, 0x2b, 0x1f, 0xc3, 0x90, 0xa9, + 0x52, 0x3c, 0x07, 0x38, 0x1a, 0x87, 0xa4, 0xa1, 0x55, 0x97, 0xc1, 0x17, 0x6c, 0x3c, 0xbe, 0x25, + 0xa0, 0x38, 0x04, 0xe0, 0x70, 0x28, 0x38, 0x56, 0x5e, 0x3b, 0xe6, 0xe3, 0x74, 0xcd, 0x51, 0xca, + 0xf0, 0xf4, 0x80, 0x07, 0x43, 0x7d, 0x04, 0x2b, 0xb5, 0x76, 0x44, 0x46, 0xfe, 0x29, 0x7c, 0x3d, + 0x75, 0xbe, 0x8f, 0x70, 0xca, 0x30, 0xc7, 0xfe, 0x78, 0x28, 0x9e, 0x23, 0x9a, 0x05, 0xd1, 0x27, + 0xd0, 0xf1, 0x62, 0xc3, 0x1f, 0x85, 0x07, 0xa5, 0x6c, 0x2b, 0x64, 0x06, 0x58, 0x51, 0xeb, 0x06, + 0xbf, 0x26, 0x0a, 0x38, 0xcd, 0x05, 0xc3, 0x8c, 0x86, 0x30, 0x1c, 0x20, 0xa0, 0x6c, 0x12, 0x02, + 0x0e, 0xdc, 0x03, 0xbc, 0x00, 0x5f, 0x3e, 0x13, 0x4a, 0x36, 0xa1, 0x42, 0xe6, 0x6f, 0x76, 0x3a, + 0x1f, 0x91, 0xd7, 0xe6, 0xeb, 0x17, 0xa3, 0x7e, 0x0e, 0xfe, 0x3e, 0x7f, 0x0d, 0x90, 0xa0, 0x05, + 0xb8, 0x8d, 0x8f, 0xcb, 0x9d, 0x5b, 0x6b, 0x2d, 0xb8, 0xad, 0xef, 0x12, 0xf9, 0x12, 0xf9, 0x0a, + 0x8f, 0x1c, 0x3a, 0x56, 0x7c, 0x56, 0xd4, 0x2e, 0xb0, 0xeb, 0x5d, 0xb1, 0xed, 0x5b, 0xd3, 0x14, + 0x82, 0xde, 0x0c, 0x01, 0x48, 0x29, 0xe6, 0xc3, 0x60, 0x87, 0x88, 0x1c, 0x39, 0xe7, 0x8e, 0x32, + 0x91, 0x0b, 0x11, 0x0f, 0x38, 0x85, 0x4d, 0x84, 0x3a, 0x0b, 0xf5, 0x72, 0x05, 0x96, 0x83, 0x63, + 0xf7, 0x59, 0x3a, 0xae, 0x4a, 0xd7, 0xe5, 0xee, 0xfe, 0x6b, 0xbb, 0xb6, 0xb8, 0x4b, 0x7b, 0xdd, + 0x4d, 0x9e, 0xef, 0x7f, 0x82, 0x9b, 0x08, 0xdf, 0x69, 0xb5, 0xc3, 0x26, 0x02, 0xa3, 0xb8, 0xb7, + 0x7c, 0x14, 0x6a, 0x62, 0x0b, 0x89, 0x56, 0xac, 0xf8, 0xbd, 0x49, 0xe3, 0x5a, 0x9b, 0x7c, 0x96, + 0x0e, 0xe4, 0x2c, 0xbb, 0xb2, 0xaa, 0xf9, 0xb5, 0x5b, 0xe6, 0x3d, 0x48, 0xc4, 0xf9, 0x48, 0x9a, + 0x19, 0x52, 0xb6, 0x8f, 0x82, 0x82, 0xe5, 0xbb, 0x4c, 0x0a, 0xbd, 0xf5, 0x7a, 0xeb, 0x5f, 0x05, + 0x14, 0xd0, 0xcd, 0x9e, 0xaa, 0xf2, 0xf0, 0x40, 0x4a, 0x39, 0xb9, 0x35, 0xdd, 0xb9, 0xa7, 0x03, + 0x8e, 0x4a, 0x7c, 0x0b, 0x6d, 0xfa, 0x30, 0xa3, 0xa4, 0x3c, 0x88, 0x01, 0x07, 0xe7, 0x5c, 0xe1, + 0x5c, 0x64, 0xef, 0x91, 0x20, 0xfc, 0xf0, 0x6a, 0xbb, 0xe5, 0x37, 0x73, 0xc8, 0x5d, 0xf2, 0xdd, + 0x1f, 0x67, 0xea, 0x3d, 0x72, 0xa5, 0x29, 0x4d, 0xde, 0x1d, 0xa4, 0x0c, 0x20, 0x94, 0xe5, 0xd6, + 0xd5, 0x5f, 0x19, 0xbf, 0x1f, 0xee, 0x06, 0x81, 0x03, 0x60, 0x1d, 0x39, 0x81, 0x24, 0xa6, 0x96, + 0xc8, 0x35, 0x86, 0x55, 0x91, 0x6c, 0x40, 0x0f, 0x28, 0x36, 0x43, 0x00, 0x65, 0x18, 0x53, 0x80, + 0x6b, 0x45, 0x39, 0x49, 0xc0, 0x07, 0xb7, 0xec, 0x22, 0x52, 0xe0, 0x16, 0x32, 0x87, 0x07, 0x30, + 0x3c, 0x7f, 0xa2, 0x6e, 0xb3, 0x62, 0x87, 0xb0, 0x07, 0xfc, 0x80, 0x4b, 0x08, 0x2f, 0xf6, 0xbe, + 0xfd, 0x1a, 0x62, 0xcc, 0x3b, 0x7b, 0xa6, 0x8a, 0x35, 0xde, 0x1f, 0x71, 0xeb, 0x8e, 0x57, 0x25, + 0x52, 0x1b, 0xcb, 0xbe, 0x13, 0x2e, 0xae, 0xb6, 0x6a, 0x20, 0xfe, 0x07, 0x11, 0xb6, 0x45, 0xc2, + 0xf2, 0xc7, 0x59, 0xc1, 0xc1, 0xb5, 0x2f, 0xc4, 0x38, 0x07, 0xc3, 0xc9, 0x7e, 0xa3, 0x01, 0xb3, + 0x8f, 0x00, 0xc0, 0xf2, 0x86, 0x63, 0x19, 0x23, 0x27, 0xd0, 0x7d, 0x19, 0x73, 0xc3, 0x8a, 0x01, + 0xe2, 0xeb, 0x03, 0x12, 0x85, 0x80, 0xad, 0xb1, 0x56, 0x28, 0xb6, 0xdb, 0x14, 0x58, 0xab, 0x59, + 0xc5, 0x97, 0xb7, 0x2c, 0x58, 0x80, 0x99, 0x38, 0x99, 0x2c, 0x59, 0x62, 0xc0, 0x79, 0x16, 0x2a, + 0xc5, 0x5b, 0x6d, 0xa6, 0x2d, 0xc3, 0x8a, 0x00, 0x17, 0x33, 0xa1, 0x29, 0xfe, 0x0c, 0xd4, 0xc7, + 0xfb, 0x60, 0xfb, 0x89, 0x3a, 0xf1, 0x50, 0xda, 0x0a, 0x22, 0x96, 0xaf, 0xe9, 0x40, 0x69, 0xe3, + 0x1f, 0xf7, 0xc0, 0x04, 0xc9, 0xb0, 0x00, 0x13, 0x9b, 0x03, 0x9f, 0x97, 0x7f, 0xfb, 0x2a, 0x74, + 0xdb, 0x05, 0x46, 0x1f, 0x86, 0xce, 0x35, 0x8b, 0x9d, 0x80, 0x87, 0xe0, 0x00, 0x25, 0x5e, 0x42, + 0xed, 0x03, 0xa4, 0x5f, 0x95, 0x15, 0xd8, 0x43, 0x9b, 0x73, 0xa8, 0xb5, 0xde, 0x16, 0x57, 0x7e, + 0x3f, 0x5a, 0xad, 0x6a, 0xb5, 0xf1, 0x04, 0xdd, 0x56, 0xbf, 0x29, 0xd8, 0xe7, 0x51, 0xf2, 0x1d, + 0x56, 0x97, 0x82, 0x53, 0x1b, 0xb3, 0xb3, 0x35, 0xa1, 0xfd, 0xf0, 0x51, 0xaa, 0x8b, 0xd5, 0x55, + 0xbe, 0x09, 0x49, 0x7b, 0xbd, 0xef, 0xf0, 0xc4, 0xd0, 0x55, 0xaa, 0xd2, 0xe9, 0xb5, 0x73, 0xf7, + 0xfc, 0x15, 0x4f, 0xab, 0x57, 0xad, 0xcd, 0x65, 0xcd, 0x32, 0x20, 0xb6, 0xdd, 0xbe, 0xce, 0x26, + 0x10, 0xd7, 0x4c, 0xac, 0x7f, 0x64, 0x1d, 0xb5, 0x1f, 0x31, 0x6c, 0x48, 0x19, 0xf6, 0x73, 0xc2, + 0x53, 0xf2, 0x11, 0x6f, 0xc8, 0xbe, 0xef, 0x7e, 0x2a, 0xd5, 0x46, 0x24, 0xb3, 0xb7, 0x5f, 0x84, + 0x35, 0x9b, 0x18, 0xd3, 0xea, 0x6c, 0xf0, 0x54, 0x56, 0xeb, 0x33, 0x06, 0xe6, 0x49, 0x5a, 0xa1, + 0x99, 0x87, 0x92, 0x63, 0xe5, 0x26, 0x6c, 0x1e, 0xf7, 0x85, 0x33, 0x90, 0xc7, 0x90, 0x50, 0xaf, + 0x85, 0xb8, 0xae, 0x46, 0xdb, 0x2a, 0x7c, 0xde, 0x16, 0x34, 0xe1, 0xe3, 0xa7, 0x1d, 0x6a, 0x40, + 0x90, 0xe6, 0xb7, 0x43, 0xbb, 0xba, 0x44, 0x24, 0xa9, 0x4c, 0x7e, 0xaf, 0xf4, 0x53, 0x27, 0xc1, + 0x67, 0x27, 0x49, 0xdf, 0xdd, 0xef, 0x5d, 0x96, 0x7c, 0xd7, 0x04, 0x77, 0x6e, 0xc7, 0x5c, 0x32, + 0x24, 0x2e, 0x41, 0x1c, 0x06, 0x22, 0xc8, 0x56, 0x39, 0x7b, 0x10, 0x0f, 0x7b, 0x03, 0x29, 0x81, + 0xc8, 0xd9, 0xb3, 0x56, 0x35, 0xce, 0x0a, 0xb8, 0xe2, 0xd6, 0x38, 0x79, 0x10, 0x01, 0xfb, 0x51, + 0x38, 0x08, 0x2e, 0x6d, 0x9f, 0xf6, 0x16, 0xb6, 0xd5, 0x7c, 0xb5, 0xb6, 0xdb, 0x71, 0xff, 0x1f, + 0xf1, 0xc5, 0x72, 0xa7, 0xe8, 0xda, 0x53, 0xd8, 0x68, 0x04, 0x2a, 0x0e, 0x00, 0x64, 0x45, 0xed, + 0x93, 0x7c, 0x4c, 0x1f, 0xb3, 0x09, 0xa1, 0xed, 0xf8, 0xf0, 0x1d, 0xc4, 0x09, 0x0d, 0x95, 0x62, + 0x1c, 0x16, 0x82, 0x20, 0x94, 0x50, 0x84, 0x0d, 0x06, 0x4e, 0x50, 0x00, 0xf3, 0x03, 0x12, 0xc7, + 0x83, 0x40, 0x07, 0x18, 0x16, 0x06, 0x0f, 0x89, 0x0a, 0x1d, 0xaa, 0xe3, 0xd1, 0xe9, 0xc4, 0xb1, + 0x4c, 0xd8, 0xef, 0xcd, 0x16, 0x7c, 0x10, 0x0c, 0x55, 0x1b, 0x10, 0xe5, 0x64, 0x80, 0x54, 0x29, + 0x20, 0x9f, 0x90, 0x2b, 0x09, 0xf1, 0x28, 0x02, 0xa7, 0x0e, 0x3e, 0x00, 0x04, 0x70, 0xf0, 0x70, + 0x15, 0x80, 0xaf, 0xba, 0xed, 0x46, 0xb7, 0xe2, 0x41, 0x00, 0xd9, 0x61, 0xe2, 0x38, 0x48, 0x1a, + 0x8a, 0x7a, 0x31, 0x0e, 0xf2, 0x8f, 0xf0, 0x51, 0xfe, 0x2c, 0x6c, 0xe5, 0x45, 0x64, 0x38, 0x85, + 0x88, 0x45, 0x18, 0x17, 0x93, 0x7c, 0x4a, 0xbf, 0xed, 0x97, 0x70, 0xc8, 0x80, 0xa4, 0xbe, 0x76, + 0xa6, 0x4b, 0x45, 0x6a, 0x1d, 0x6e, 0xa6, 0x5f, 0x19, 0x70, 0x83, 0x42, 0x81, 0x28, 0x12, 0xd7, + 0x2f, 0x54, 0x5a, 0x43, 0x83, 0x10, 0x80, 0xd2, 0xb3, 0x23, 0xb9, 0x2a, 0xa1, 0x25, 0xe3, 0x03, + 0x4b, 0xab, 0x3a, 0xf0, 0xa7, 0x7d, 0xe2, 0x1c, 0x52, 0xaa, 0x55, 0x26, 0xa2, 0xe2, 0x0d, 0x72, + 0x09, 0x2c, 0xff, 0x88, 0xd2, 0xd6, 0x0c, 0x44, 0x0d, 0x22, 0xa1, 0xc2, 0x72, 0xc2, 0xbe, 0x78, + 0x7a, 0x76, 0x28, 0x71, 0xc6, 0x65, 0x96, 0xcc, 0x82, 0x01, 0xb8, 0x69, 0x0e, 0x35, 0x21, 0x22, + 0x80, 0x67, 0x0b, 0x40, 0xfb, 0xce, 0x16, 0x0d, 0x00, 0x9d, 0x60, 0xbb, 0x99, 0x85, 0xec, 0x79, + 0x15, 0x7a, 0x65, 0xda, 0x76, 0xe1, 0xc5, 0x00, 0x59, 0xc4, 0x26, 0x7e, 0xd0, 0x2f, 0x6c, 0xdb, + 0xed, 0xb7, 0xb6, 0xd9, 0x3c, 0xc8, 0x3a, 0x14, 0xe6, 0xc1, 0x82, 0xf8, 0x54, 0x00, 0xf1, 0xaa, + 0x80, 0xb8, 0xd0, 0x50, 0x9d, 0x78, 0x5c, 0xff, 0xc3, 0xb1, 0x40, 0x00, 0xcc, 0xf0, 0x00, 0x2b, + 0xc2, 0xe0, 0x00, 0x45, 0x43, 0x8b, 0x1a, 0x8e, 0x83, 0xc2, 0x77, 0x36, 0x78, 0x82, 0xe9, 0xb4, + 0xb8, 0xff, 0x21, 0x81, 0xc2, 0x7d, 0x47, 0xdc, 0xa6, 0xef, 0xc3, 0x22, 0x59, 0x02, 0x13, 0x25, + 0x31, 0x77, 0x28, 0x1a, 0x97, 0x8a, 0x61, 0xfc, 0x21, 0xc8, 0x47, 0x77, 0xfb, 0x23, 0xbe, 0xf9, + 0x2e, 0xf7, 0xf0, 0x87, 0xbb, 0xbb, 0xfb, 0xbf, 0xb3, 0xbb, 0xeb, 0x88, 0x25, 0x6a, 0xab, 0x4b, + 0xc1, 0x3f, 0x55, 0x9b, 0x15, 0xd0, 0x4a, 0x7c, 0x14, 0xd5, 0xee, 0xfb, 0xe8, 0x9d, 0xbe, 0xbd, + 0xf2, 0x76, 0xc7, 0xf7, 0xb3, 0x91, 0x90, 0xa7, 0x0d, 0x77, 0x46, 0xbf, 0x8c, 0x16, 0x64, 0x44, + 0xbb, 0x07, 0xd5, 0x51, 0xdd, 0xd9, 0x16, 0x09, 0x47, 0x89, 0x8c, 0x25, 0x94, 0xc9, 0xa3, 0xb5, + 0x9d, 0x84, 0x28, 0xf2, 0xea, 0x3d, 0xa6, 0x6d, 0xc4, 0x89, 0x0a, 0x1b, 0x5d, 0x47, 0x0b, 0xf0, + 0x6a, 0x6a, 0x50, 0x8f, 0x08, 0xc7, 0x60, 0xf4, 0xbb, 0x72, 0x91, 0x90, 0x59, 0x46, 0x80, 0x91, + 0x8c, 0x4a, 0x03, 0x1e, 0x3b, 0xc3, 0x21, 0xd2, 0xbb, 0x11, 0x89, 0xaa, 0x1e, 0x9b, 0x38, 0xd8, + 0xbc, 0x5a, 0x68, 0xe3, 0x3b, 0x5e, 0xca, 0x3b, 0x4a, 0xa4, 0x4b, 0x09, 0xe1, 0x11, 0x85, 0x67, + 0xe0, 0x88, 0xf7, 0xbb, 0x98, 0x71, 0x44, 0xc4, 0x07, 0xff, 0xdb, 0xb7, 0x5f, 0xb5, 0x57, 0x81, + 0xc4, 0x30, 0x34, 0x50, 0xb8, 0xc1, 0x4f, 0xa5, 0xe3, 0xd7, 0x00, 0x0f, 0x89, 0x40, 0x00, 0xaa, + 0x81, 0x7e, 0xd7, 0x04, 0xac, 0x00, 0x69, 0x62, 0x78, 0x2f, 0xe7, 0xac, 0x09, 0xe1, 0xfc, 0x15, + 0x23, 0x86, 0xaf, 0xed, 0xb7, 0x70, 0x67, 0x5f, 0x86, 0x40, 0xb0, 0x36, 0xcf, 0xf0, 0x1a, 0xe6, + 0xc6, 0x9c, 0xce, 0x4c, 0x01, 0x55, 0x8a, 0xab, 0x8b, 0x8b, 0x9d, 0x8f, 0x5d, 0xdf, 0xf0, 0xf2, + 0x28, 0x01, 0x89, 0x9c, 0x46, 0x84, 0x75, 0x4f, 0x16, 0xc1, 0xf7, 0xb6, 0xdb, 0x74, 0xf3, 0x6b, + 0x42, 0x06, 0xb1, 0x06, 0x40, 0xb7, 0x19, 0x27, 0xfc, 0x65, 0xa9, 0xed, 0xb6, 0xee, 0x10, 0x08, + 0x8d, 0xe9, 0xa8, 0x00, 0x01, 0x59, 0x9e, 0xe0, 0xc4, 0xc7, 0x21, 0x15, 0x23, 0x9a, 0x84, 0xe1, + 0x5a, 0xa0, 0x04, 0x55, 0x10, 0x0e, 0x1c, 0x38, 0x58, 0x32, 0xc1, 0x87, 0xe9, 0x58, 0x0f, 0xc1, + 0xc0, 0xe1, 0x94, 0x0e, 0x70, 0x5e, 0x82, 0xa6, 0x59, 0x23, 0x2c, 0x6a, 0x0b, 0x3a, 0xe3, 0xff, + 0xc2, 0x03, 0x4c, 0xe4, 0x01, 0xa0, 0x83, 0xb9, 0x5f, 0xba, 0x00, 0x02, 0x6d, 0x04, 0x59, 0xa9, + 0xd7, 0xdc, 0x84, 0xea, 0xd8, 0x11, 0x3b, 0xda, 0x40, 0x86, 0x6a, 0x78, 0xf3, 0xdb, 0x7c, 0x7b, + 0x68, 0x51, 0x4c, 0x97, 0x65, 0x25, 0x9b, 0x05, 0xe4, 0xd6, 0xf9, 0xa8, 0xfb, 0x88, 0x8d, 0xcb, + 0x30, 0x34, 0xc7, 0x86, 0x32, 0x9c, 0x01, 0xb5, 0xa5, 0xa2, 0x6b, 0x0f, 0x02, 0x90, 0xaf, 0x27, + 0x0a, 0x01, 0xe9, 0x97, 0x20, 0x35, 0x3e, 0x3c, 0xa3, 0x66, 0x88, 0x05, 0x70, 0x9e, 0x81, 0x4d, + 0x55, 0x02, 0x0c, 0x8b, 0x0b, 0xaf, 0x0d, 0x4c, 0x81, 0x62, 0x37, 0x8d, 0x71, 0xee, 0xbc, 0x18, + 0x04, 0x46, 0xc7, 0x27, 0xdf, 0xca, 0x13, 0xa3, 0xf8, 0xd7, 0x63, 0xca, 0xae, 0xe5, 0xe7, 0xb4, + 0x9f, 0x2d, 0x03, 0xac, 0x25, 0x0e, 0xc0, 0x25, 0x1f, 0xd8, 0x74, 0xad, 0x04, 0xcc, 0x47, 0x49, + 0xaa, 0x76, 0xcf, 0xc7, 0xff, 0x56, 0x11, 0x10, 0x14, 0xd1, 0x26, 0x69, 0x7c, 0x01, 0xf4, 0x32, + 0xb3, 0x55, 0xe8, 0x1e, 0xc7, 0x5d, 0x51, 0x0c, 0xe3, 0xba, 0x45, 0x35, 0xe6, 0x8b, 0xc7, 0x70, + 0x55, 0xa5, 0xbb, 0x6c, 0x8e, 0x67, 0x1e, 0x6b, 0x08, 0x1c, 0x30, 0xc8, 0x80, 0xf1, 0x7a, 0x88, + 0xc3, 0x3a, 0x71, 0xeb, 0xbe, 0xb7, 0x31, 0x7b, 0xa4, 0x3e, 0x9c, 0xa7, 0xf0, 0xd9, 0x70, 0x62, + 0x35, 0xd0, 0x1b, 0xfc, 0x36, 0x7d, 0x85, 0xbb, 0xbe, 0xfe, 0x41, 0x15, 0x9b, 0xf8, 0x22, 0xaa, + 0xd7, 0xbe, 0x6d, 0xd6, 0xb8, 0xad, 0xdf, 0xbb, 0xf8, 0xc2, 0xe7, 0xee, 0xa4, 0xca, 0xb8, 0xfa, + 0x27, 0xb5, 0xaf, 0x93, 0x69, 0x7e, 0x20, 0xaa, 0x99, 0x18, 0xf6, 0xc8, 0xdc, 0x4d, 0x96, 0xf7, + 0xc4, 0xc8, 0x4b, 0x97, 0xfe, 0xf7, 0x27, 0xfc, 0x27, 0xcc, 0xc5, 0x6b, 0xe2, 0x04, 0x11, 0xc5, + 0x6d, 0x1d, 0x25, 0x71, 0xbf, 0xcf, 0x82, 0x99, 0x63, 0x25, 0x14, 0x21, 0xf8, 0xab, 0x64, 0xdd, + 0xa6, 0xed, 0xf1, 0xcb, 0x65, 0x50, 0xdf, 0x29, 0x4f, 0x43, 0xd3, 0x27, 0x05, 0x85, 0x4a, 0x99, + 0x69, 0x37, 0xb6, 0xec, 0x87, 0xfb, 0xe6, 0xa9, 0x89, 0x7e, 0x89, 0x5f, 0x0d, 0x66, 0x93, 0x59, + 0x6d, 0x34, 0xcd, 0xbf, 0x0e, 0x28, 0x95, 0x78, 0xa5, 0x47, 0x4d, 0x1d, 0x35, 0x9d, 0x34, 0xc3, + 0x5b, 0x6d, 0xda, 0x6c, 0x55, 0x9b, 0x63, 0x1e, 0x54, 0xa2, 0xd3, 0xfc, 0x09, 0x20, 0x49, 0x0a, + 0x18, 0xb0, 0xca, 0x52, 0x02, 0x61, 0x66, 0x5b, 0x12, 0x03, 0xcb, 0xdf, 0x9d, 0x25, 0x88, 0x07, + 0x15, 0x4e, 0x04, 0xc8, 0xeb, 0x08, 0x81, 0x20, 0x14, 0x5c, 0xb8, 0x9b, 0xd9, 0x31, 0x62, 0xe2, + 0xdb, 0x84, 0x02, 0x01, 0x43, 0xbd, 0xe7, 0xcd, 0x7c, 0xbd, 0xcf, 0x93, 0x76, 0xa4, 0xf3, 0x03, + 0xb8, 0x94, 0xe1, 0x01, 0x23, 0x88, 0x7b, 0xe8, 0xc9, 0x97, 0x91, 0x3d, 0x04, 0x0c, 0xf9, 0x12, + 0x47, 0xb6, 0x35, 0x04, 0x12, 0xe7, 0x89, 0x0c, 0x82, 0x99, 0xe3, 0x7b, 0x2a, 0xf4, 0xcf, 0x14, + 0x34, 0x58, 0x43, 0x26, 0x28, 0xf5, 0x51, 0x75, 0x3b, 0x8e, 0x20, 0x48, 0xda, 0x72, 0x69, 0x1e, + 0x69, 0xf1, 0xc9, 0x61, 0x90, 0x6d, 0xa8, 0xa9, 0xe6, 0xfb, 0xb6, 0xea, 0xcf, 0x14, 0x3b, 0x3f, + 0x19, 0xbf, 0x88, 0x12, 0x37, 0x4e, 0xd0, 0xec, 0x56, 0x9b, 0x15, 0xc9, 0x41, 0xa0, 0xf1, 0xd3, + 0x86, 0x8d, 0x8e, 0xbf, 0xc7, 0xb2, 0xab, 0x5e, 0xa6, 0x99, 0x32, 0xcd, 0x33, 0x18, 0x6c, 0x9d, + 0xdc, 0xd9, 0x38, 0x3a, 0x63, 0x45, 0x09, 0x63, 0x75, 0xe0, 0x0a, 0xaa, 0x6a, 0xf5, 0x25, 0x7e, + 0xe7, 0xd6, 0xe3, 0xc4, 0x88, 0x0a, 0x10, 0xd1, 0xd2, 0x6f, 0x36, 0x8f, 0xff, 0xd6, 0xda, 0xee, + 0xd8, 0x66, 0x07, 0x88, 0x4f, 0xbc, 0xa7, 0xfa, 0x7a, 0x4a, 0x95, 0x67, 0xcf, 0x6b, 0x0a, 0xf0, + 0xf3, 0x25, 0x7a, 0x3f, 0x08, 0xd9, 0x6e, 0xf0, 0xa7, 0x26, 0xf7, 0xf2, 0xc5, 0x77, 0x9f, 0x82, + 0x4c, 0xde, 0xae, 0xf9, 0x2a, 0x66, 0x28, 0x9c, 0x45, 0xd6, 0xbc, 0x44, 0xc7, 0x57, 0xf1, 0x10, + 0x91, 0x9a, 0xd3, 0x4e, 0x9d, 0x70, 0x59, 0xa2, 0x2b, 0x0d, 0x7d, 0x27, 0x7b, 0xb0, 0xa8, 0xa9, + 0xcb, 0x0e, 0xfb, 0xe1, 0x9c, 0xb7, 0xeb, 0x53, 0xf1, 0x55, 0x4e, 0xd6, 0x7c, 0xc3, 0x8a, 0x08, + 0x44, 0x54, 0x65, 0x34, 0xfe, 0x7d, 0x7b, 0x0a, 0xa9, 0xa6, 0xdb, 0x7f, 0x81, 0x04, 0x1c, 0x8d, + 0xa6, 0xa6, 0x94, 0xa0, 0x93, 0xbc, 0x95, 0xb0, 0x4e, 0x3e, 0xf4, 0x39, 0x78, 0x59, 0xc5, 0x9c, + 0x30, 0x23, 0xe0, 0x76, 0x70, 0xbc, 0xc9, 0xe9, 0xde, 0xdc, 0x57, 0x88, 0x08, 0x02, 0x83, 0xa5, + 0xf3, 0x53, 0x4c, 0xcd, 0xd2, 0xf1, 0x21, 0x91, 0xa2, 0x05, 0x06, 0x7c, 0x6a, 0x45, 0xd5, 0x54, + 0x5c, 0x2c, 0x70, 0x49, 0x50, 0xf5, 0xab, 0x34, 0xf7, 0xa1, 0x01, 0xe0, 0x50, 0x8c, 0x5c, 0xec, + 0xe7, 0xea, 0xe8, 0xf0, 0x88, 0x44, 0x15, 0xc5, 0xd4, 0x9d, 0xdc, 0x58, 0x0b, 0xf0, 0xc9, 0xbe, + 0x42, 0xe0, 0xd2, 0xa6, 0xe9, 0x6e, 0x7f, 0x43, 0xe0, 0x35, 0x4a, 0xb0, 0x80, 0x44, 0x41, 0xdd, + 0x7b, 0xcb, 0x2e, 0x19, 0x05, 0x84, 0xcf, 0x2c, 0x8c, 0xdd, 0x8e, 0x4a, 0xa7, 0x75, 0x92, 0x2d, + 0xbb, 0x9e, 0x47, 0x88, 0x10, 0x30, 0x88, 0xb7, 0x7a, 0xae, 0x00, 0xfe, 0xea, 0x56, 0xa0, 0x44, + 0xef, 0xd4, 0xaa, 0xfa, 0x3b, 0xcb, 0x94, 0x4a, 0x00, 0x50, 0x65, 0xa8, 0x88, 0x05, 0x47, 0x7c, + 0x78, 0x23, 0xc1, 0xaf, 0x62, 0x1d, 0xe1, 0x02, 0x8c, 0x62, 0xad, 0x5a, 0xb9, 0x90, 0xa5, 0xcb, + 0xbe, 0x13, 0xad, 0x56, 0xb5, 0xf0, 0x95, 0x75, 0xad, 0x7c, 0x5e, 0x9a, 0xe4, 0xff, 0x9a, 0x9b, + 0xfc, 0x48, 0x21, 0x13, 0x51, 0xea, 0x77, 0xf8, 0x2c, 0x33, 0x18, 0xac, 0x56, 0x7e, 0xe2, 0xb2, + 0xf2, 0xc6, 0x28, 0xc9, 0x40, 0x5b, 0x03, 0xc0, 0x9c, 0x89, 0x6b, 0xe3, 0xda, 0x7f, 0x85, 0x0c, + 0x2b, 0x10, 0xa4, 0x32, 0xb6, 0x53, 0x03, 0x00, 0xf2, 0xb4, 0x0c, 0x04, 0xe8, 0x00, 0x13, 0x2b, + 0xa3, 0x29, 0xc8, 0x00, 0x39, 0x36, 0x75, 0x00, 0x0d, 0xf3, 0xaf, 0x0e, 0x0b, 0x48, 0x03, 0x41, + 0xc0, 0x00, 0x9b, 0x18, 0x71, 0x83, 0x54, 0x10, 0x69, 0x39, 0x00, 0x68, 0x71, 0x7c, 0x9d, 0x23, + 0xe7, 0x8e, 0xe7, 0x9b, 0x35, 0x9a, 0x92, 0x64, 0x55, 0xf0, 0xa4, 0xa4, 0x83, 0x03, 0x23, 0xa7, + 0x19, 0x6c, 0x40, 0x2c, 0x16, 0xcb, 0x6f, 0x66, 0x64, 0xb6, 0x0b, 0x10, 0xd4, 0x17, 0x16, 0x98, + 0x4e, 0x35, 0x5f, 0x1e, 0x7f, 0xb2, 0xb9, 0x73, 0x5c, 0xa5, 0x5b, 0x5f, 0x05, 0x96, 0xcd, 0x8d, + 0xcd, 0x31, 0x3c, 0x4e, 0x62, 0x52, 0x30, 0xaa, 0xa9, 0x4c, 0xbc, 0x15, 0x52, 0xdd, 0x50, 0xd2, + 0x6a, 0xd9, 0x36, 0x27, 0x3e, 0x09, 0x24, 0xc2, 0x37, 0xef, 0x85, 0x09, 0x9b, 0x71, 0xa8, 0x07, + 0xdd, 0xa4, 0xca, 0xce, 0x8e, 0xe7, 0x07, 0x22, 0x42, 0x98, 0xc3, 0x82, 0x22, 0x45, 0x90, 0x76, + 0x6a, 0x3d, 0xe6, 0xa8, 0x8b, 0x00, 0x18, 0xe4, 0xf4, 0x15, 0x49, 0x31, 0xfb, 0x0a, 0x95, 0x09, + 0x49, 0x1e, 0x0e, 0x07, 0x5b, 0x5a, 0x9d, 0x07, 0x3c, 0x10, 0x05, 0x08, 0x53, 0x58, 0x39, 0xe1, + 0x7d, 0x32, 0xe4, 0x48, 0x39, 0x6c, 0x56, 0xa2, 0x25, 0x0f, 0x8d, 0xea, 0xd4, 0xdc, 0x91, 0xb1, + 0xe8, 0xef, 0x04, 0x21, 0x01, 0xb2, 0xc0, 0x32, 0xc0, 0x32, 0x50, 0xa9, 0xc7, 0x10, 0x05, 0x02, + 0xd7, 0x90, 0x40, 0x8f, 0xb0, 0x49, 0x12, 0xd6, 0x3c, 0x28, 0x00, 0xd4, 0x35, 0x42, 0x04, 0x41, + 0xa8, 0x70, 0x02, 0xc8, 0xb0, 0x11, 0x10, 0xe1, 0xc5, 0x7f, 0x27, 0x2f, 0x1e, 0x50, 0xe1, 0x11, + 0xb9, 0x0e, 0xe2, 0xd7, 0x55, 0x89, 0x60, 0xc1, 0x12, 0xbe, 0x34, 0x80, 0xee, 0x58, 0x2e, 0x1e, + 0xad, 0xe8, 0xb1, 0x00, 0xb1, 0x66, 0x0f, 0x00, 0x03, 0x0c, 0x15, 0x24, 0xba, 0x5f, 0x4f, 0x11, + 0x05, 0x3f, 0x6c, 0x6f, 0x0c, 0x51, 0xf0, 0xc8, 0x2b, 0xca, 0xbb, 0x0a, 0x92, 0x79, 0x2c, 0x69, + 0xb0, 0x5d, 0x70, 0x4d, 0x8d, 0x12, 0x5e, 0x45, 0xd1, 0xd6, 0xb5, 0xcf, 0xbe, 0x14, 0x28, 0x71, + 0x19, 0xcf, 0x3d, 0xe9, 0x18, 0xc5, 0xc8, 0x63, 0x1e, 0xcc, 0xd7, 0x05, 0x00, 0xb8, 0xc6, 0xb9, + 0x54, 0x9c, 0x29, 0x22, 0x8e, 0x3d, 0x56, 0x83, 0x14, 0x8d, 0x66, 0xac, 0xc8, 0xbf, 0x84, 0x23, + 0x21, 0xf2, 0xca, 0x93, 0xc3, 0x4b, 0x6c, 0x26, 0x09, 0x87, 0x8a, 0xf7, 0x6e, 0xc6, 0x36, 0x73, + 0xe0, 0x8c, 0xb7, 0x86, 0x89, 0x2a, 0x08, 0x74, 0x67, 0x4b, 0xcb, 0x77, 0xd7, 0x29, 0x5a, 0xad, + 0x77, 0x7b, 0xc9, 0xc2, 0x04, 0x67, 0x96, 0x09, 0xb6, 0xad, 0x4b, 0x03, 0x9a, 0x61, 0x7e, 0x32, + 0x4c, 0xeb, 0x4a, 0x79, 0x35, 0x1c, 0xf7, 0x24, 0xcf, 0x17, 0xd9, 0x84, 0x9b, 0xff, 0x55, 0x54, + 0xc2, 0x7b, 0x5b, 0xe3, 0xcf, 0x5a, 0x4b, 0xae, 0x6c, 0xf8, 0xbf, 0x33, 0x0a, 0x3b, 0x49, 0x39, + 0xf8, 0x91, 0x21, 0x4e, 0x1f, 0x53, 0x26, 0x9c, 0x69, 0xc3, 0xd7, 0x7b, 0x29, 0x57, 0x0c, 0x21, + 0x03, 0x16, 0x2a, 0xef, 0x8c, 0x14, 0xf8, 0x24, 0x17, 0x78, 0x70, 0xc2, 0x96, 0x70, 0x49, 0xe9, + 0x3c, 0x4d, 0x5a, 0x67, 0x92, 0x85, 0xb1, 0x82, 0x72, 0xd3, 0x4c, 0x3f, 0xc2, 0x94, 0x56, 0xb8, + 0xf1, 0xf4, 0x0d, 0xc5, 0xc1, 0x7e, 0x70, 0x27, 0x03, 0xc1, 0xc3, 0xdf, 0x43, 0x68, 0x72, 0x51, + 0xcd, 0x0b, 0x19, 0xef, 0x2c, 0x6f, 0xef, 0xf6, 0x57, 0xb1, 0xfe, 0xed, 0x17, 0x2d, 0x78, 0x25, + 0xb9, 0x7d, 0xa7, 0xfd, 0x7e, 0x2b, 0x84, 0x3c, 0x14, 0x9e, 0x46, 0x4c, 0x08, 0x0d, 0x8d, 0xf7, + 0x9b, 0x65, 0xec, 0x74, 0xce, 0x27, 0xf8, 0x22, 0xa4, 0x92, 0x32, 0x55, 0xfe, 0x17, 0x90, 0x82, + 0x2f, 0x17, 0x37, 0x16, 0xbd, 0x28, 0x38, 0x1d, 0x00, 0x55, 0x0a, 0x42, 0xb1, 0xa7, 0x0a, 0xbd, + 0xc1, 0x03, 0x87, 0xcc, 0x10, 0x46, 0x98, 0x3a, 0x60, 0x4a, 0x95, 0x49, 0x21, 0xc0, 0x41, 0x3b, + 0x20, 0x46, 0x5f, 0x52, 0x5e, 0x13, 0x01, 0xe0, 0xf3, 0x02, 0x50, 0xf4, 0x04, 0xac, 0xde, 0x61, + 0xca, 0x6a, 0x0e, 0xcc, 0x5c, 0x82, 0x16, 0xd4, 0x28, 0x18, 0x0a, 0x37, 0x80, 0x00, 0x40, 0x07, + 0x03, 0xf2, 0x0c, 0x00, 0x14, 0x01, 0xac, 0xb8, 0x3b, 0xf0, 0x3b, 0xd8, 0xaf, 0x7d, 0x37, 0x63, + 0x50, 0xf2, 0x80, 0x08, 0x68, 0x9b, 0x62, 0x28, 0xb9, 0xac, 0xbf, 0x96, 0xef, 0x3f, 0x2d, 0x62, + 0x5f, 0x59, 0x0d, 0x28, 0xed, 0xbb, 0x64, 0xe7, 0xe7, 0x1a, 0xd6, 0xad, 0x41, 0x78, 0xe0, 0x38, + 0xb7, 0x69, 0x34, 0xf4, 0xe1, 0xc5, 0x00, 0x26, 0xa1, 0xfe, 0xe5, 0x20, 0x8b, 0xb9, 0x96, 0xad, + 0xdf, 0x2d, 0x83, 0xd7, 0x8a, 0x44, 0x74, 0x5b, 0x7e, 0x3b, 0x05, 0x68, 0x1e, 0x17, 0x78, 0x59, + 0x97, 0x96, 0x16, 0x8f, 0xc6, 0xd5, 0x54, 0x3b, 0x18, 0x9e, 0x02, 0xea, 0x46, 0x51, 0xbc, 0x37, + 0x80, 0xf8, 0x7a, 0x59, 0x18, 0x9a, 0xf4, 0x0f, 0x9e, 0xa0, 0xe0, 0x58, 0x2f, 0x10, 0x01, 0x2b, + 0x14, 0x40, 0x4a, 0xba, 0x00, 0x95, 0x82, 0x64, 0xc1, 0x61, 0x31, 0x72, 0x68, 0x55, 0x52, 0xd5, + 0xf8, 0x60, 0x6c, 0xb5, 0x61, 0xa6, 0x52, 0x70, 0x0b, 0x45, 0xb0, 0x3c, 0x53, 0x7c, 0xc8, 0xe6, + 0xea, 0x6a, 0x21, 0xd9, 0x14, 0x7a, 0x84, 0xdc, 0xe4, 0x2a, 0x58, 0x00, 0x6f, 0x0a, 0x4c, 0xe9, + 0x3a, 0x02, 0xa5, 0x80, 0x6f, 0x07, 0x0e, 0x0e, 0x70, 0x45, 0x79, 0xd4, 0xc3, 0x5f, 0x47, 0x84, + 0x42, 0x03, 0x64, 0x01, 0xa3, 0x2b, 0x53, 0x02, 0x81, 0x1f, 0xb3, 0xb9, 0xfc, 0xc1, 0x75, 0x3c, + 0x38, 0xd8, 0x7e, 0x59, 0xca, 0x49, 0x81, 0x40, 0xb6, 0x34, 0xc4, 0xb3, 0x90, 0xb1, 0x43, 0x38, + 0x4f, 0x8a, 0xb2, 0x49, 0x38, 0xf0, 0x52, 0x08, 0x02, 0x84, 0x14, 0xd2, 0x81, 0xe1, 0x79, 0x2e, + 0x33, 0x6c, 0x68, 0x68, 0xc2, 0xf0, 0x35, 0x4d, 0x52, 0x64, 0xe0, 0x70, 0x71, 0x17, 0x0e, 0xa0, + 0x25, 0x26, 0x1c, 0x82, 0xa0, 0x1f, 0x36, 0x05, 0x64, 0x30, 0x52, 0x0c, 0x02, 0x99, 0x60, 0x34, + 0x4e, 0x94, 0x4a, 0x40, 0xe8, 0xa2, 0xd7, 0x24, 0x98, 0x5c, 0x3d, 0xff, 0x8b, 0xf4, 0x4a, 0xcb, + 0x4b, 0x62, 0x7e, 0x14, 0x26, 0xac, 0x4a, 0xf8, 0x3f, 0x1f, 0x98, 0x87, 0xe1, 0xc8, 0x1d, 0x0e, + 0xc5, 0x3e, 0x24, 0x15, 0xc5, 0x00, 0x53, 0x61, 0x61, 0x49, 0x82, 0x82, 0x90, 0xd1, 0x4e, 0xab, + 0x70, 0x7d, 0xcf, 0x9d, 0xf0, 0xa4, 0xf7, 0xb7, 0xca, 0x91, 0x1d, 0x9c, 0x38, 0x70, 0xe0, 0x87, + 0x96, 0x03, 0x0a, 0x03, 0x2c, 0x87, 0x00, 0xd9, 0x60, 0xcf, 0x70, 0xa0, 0x33, 0xc3, 0x8d, 0x91, + 0x1a, 0xf0, 0x80, 0x80, 0x58, 0x7d, 0x0a, 0x45, 0x0f, 0xcb, 0x47, 0xa4, 0x5b, 0x0f, 0x22, 0x0a, + 0xcb, 0x88, 0x12, 0x14, 0xb9, 0x72, 0xf2, 0x59, 0x7b, 0x09, 0x6b, 0x23, 0x60, 0x9e, 0x0c, 0x78, + 0x63, 0xab, 0x13, 0x98, 0x8b, 0xba, 0xa3, 0x39, 0xce, 0x48, 0x98, 0x70, 0xc0, 0x91, 0x91, 0xda, + 0xda, 0x41, 0x2a, 0x35, 0x47, 0x0b, 0x0c, 0x3d, 0x83, 0xfe, 0xea, 0x65, 0xb7, 0x46, 0x34, 0xa6, + 0x2d, 0x7e, 0xaf, 0xc5, 0xf9, 0x63, 0x82, 0x40, 0x75, 0x40, 0xe2, 0x2c, 0xf0, 0x51, 0xc0, 0x39, + 0x1f, 0xad, 0x40, 0x32, 0x6e, 0x29, 0x87, 0xf1, 0xdc, 0x8e, 0xee, 0x4f, 0xa9, 0x3a, 0x2b, 0x15, + 0xc2, 0x64, 0x5b, 0xc9, 0xfa, 0xe0, 0x86, 0x4c, 0xa5, 0x69, 0x38, 0xbb, 0xdd, 0xd2, 0x72, 0xff, + 0xc2, 0x92, 0xdb, 0xe0, 0x93, 0x4c, 0xc4, 0xa9, 0x43, 0xbd, 0xe6, 0x91, 0x10, 0xb1, 0x58, 0x6d, + 0xc2, 0xa7, 0x55, 0xb9, 0xb4, 0xc7, 0xc7, 0x13, 0x71, 0xd6, 0xaa, 0xe3, 0x71, 0x96, 0x8b, 0x75, + 0xf8, 0xc9, 0x44, 0x9b, 0xdb, 0x66, 0x5d, 0xc9, 0xf7, 0x3e, 0x5e, 0x68, 0xf8, 0xa3, 0xa9, 0x32, + 0xa9, 0xed, 0x32, 0x27, 0xf1, 0x10, 0xa6, 0x32, 0x69, 0x68, 0x58, 0xf5, 0x15, 0xf1, 0xdb, 0x81, + 0x05, 0xc5, 0x2f, 0x95, 0xc6, 0xac, 0xf1, 0xbe, 0x21, 0xe3, 0x2a, 0x1a, 0x21, 0xb6, 0x8a, 0x1a, + 0xa9, 0xf5, 0xb9, 0xd5, 0x52, 0x22, 0x6b, 0xc8, 0x2e, 0xb8, 0xc4, 0xf8, 0xde, 0xa5, 0xa5, 0x8f, + 0x9a, 0x16, 0xf2, 0xbc, 0x90, 0x8a, 0xb1, 0x9b, 0xd3, 0xb8, 0x4d, 0x5e, 0xf8, 0xbe, 0x23, 0xbf, + 0xc1, 0x35, 0xbb, 0xa8, 0x8d, 0x6b, 0x3e, 0xdd, 0xf7, 0xdc, 0xb8, 0x4e, 0x17, 0xc3, 0x23, 0x40, + 0xfe, 0x3e, 0x35, 0x41, 0x50, 0x10, 0xda, 0x51, 0x0d, 0xb5, 0xf9, 0x33, 0xde, 0x1c, 0x44, 0x04, + 0x92, 0x20, 0x47, 0x98, 0x29, 0x2d, 0x61, 0xca, 0xc5, 0x06, 0xe0, 0x3f, 0x57, 0xf2, 0x50, 0x07, + 0xe7, 0xd9, 0x41, 0xf8, 0xf0, 0x01, 0xda, 0xec, 0x9d, 0xf2, 0xbc, 0x15, 0xd8, 0x7e, 0x54, 0x52, + 0x6a, 0x5d, 0x86, 0x19, 0xa2, 0x64, 0x27, 0xa5, 0x71, 0x8e, 0x5d, 0xac, 0x31, 0xf8, 0x12, 0x46, + 0x94, 0x68, 0x03, 0xce, 0x31, 0xd0, 0xed, 0xdd, 0x9c, 0x58, 0x41, 0xc5, 0xa7, 0x11, 0xda, 0x7a, + 0xa5, 0xd1, 0x93, 0xc3, 0x42, 0xf8, 0x8b, 0x4d, 0x30, 0x3b, 0xca, 0x4e, 0x59, 0x0f, 0x24, 0x4c, + 0xd8, 0xa9, 0xb3, 0x59, 0xbe, 0x20, 0x48, 0xd2, 0x1e, 0xd8, 0x74, 0xcf, 0xc3, 0x54, 0x10, 0xf6, + 0xc0, 0x33, 0x60, 0xf9, 0x42, 0xbd, 0x1a, 0xaf, 0x67, 0x62, 0x3f, 0x0c, 0x42, 0x19, 0x20, 0xa6, + 0xca, 0x10, 0x50, 0x2d, 0x39, 0x3e, 0xc1, 0x96, 0xc8, 0xf7, 0x07, 0xf8, 0x3c, 0xf3, 0x41, 0x9f, + 0xe5, 0x3f, 0x33, 0x93, 0xbd, 0xe1, 0x00, 0xc8, 0xd9, 0xf8, 0xf7, 0xc9, 0x6a, 0x5d, 0x8f, 0xf4, + 0x72, 0x0b, 0x0b, 0x71, 0x93, 0x9f, 0x0a, 0xf5, 0x51, 0x0b, 0x93, 0x50, 0xf7, 0xe4, 0xa0, 0x00, + 0xf1, 0x48, 0x3f, 0x03, 0xf0, 0x2e, 0xeb, 0x69, 0x8b, 0x74, 0xcf, 0xcf, 0x63, 0x81, 0x80, 0x14, + 0x8d, 0x86, 0x48, 0x82, 0x4a, 0xd8, 0x00, 0x62, 0x05, 0x05, 0xa9, 0x42, 0x34, 0xc0, 0x9b, 0x20, + 0x54, 0xe5, 0x4e, 0x00, 0x5c, 0x91, 0x6d, 0x76, 0x80, 0x59, 0x7a, 0x14, 0x13, 0xba, 0x7b, 0x80, + 0x04, 0x0d, 0xc0, 0x0f, 0xab, 0xa1, 0x6d, 0x85, 0xcb, 0xf0, 0x64, 0xda, 0x02, 0x88, 0x0d, 0x48, + 0x1d, 0x7c, 0x1a, 0xae, 0x2a, 0x7e, 0x51, 0xcc, 0xa6, 0x49, 0xba, 0xca, 0xc3, 0x73, 0x81, 0x73, + 0x6d, 0xd8, 0x17, 0xf9, 0x92, 0xfc, 0xff, 0xd6, 0x59, 0xcf, 0xc6, 0xae, 0x58, 0x58, 0x2e, 0xb8, + 0x58, 0x69, 0xaa, 0xe1, 0xdb, 0x9c, 0xc1, 0x31, 0x58, 0x5b, 0x3e, 0xc0, 0x3a, 0xd8, 0x43, 0x9f, + 0x1f, 0xfc, 0x3a, 0xa0, 0x93, 0x72, 0x81, 0x68, 0x17, 0x18, 0x7f, 0xfd, 0xf1, 0x8a, 0xbd, 0x69, + 0x4c, 0x9c, 0xd5, 0x4b, 0x6e, 0x8b, 0xa2, 0xb7, 0x30, 0xa8, 0xd6, 0x0c, 0xae, 0x42, 0xc0, 0xbe, + 0x54, 0x00, 0x09, 0x49, 0x00, 0xc3, 0x90, 0xd3, 0xa6, 0x12, 0x03, 0xf0, 0xac, 0x1c, 0xba, 0x69, + 0x37, 0x88, 0x8d, 0x20, 0x68, 0x1d, 0x4a, 0xa5, 0x80, 0x5a, 0xd3, 0x81, 0xaa, 0x0a, 0xd2, 0xb0, + 0x19, 0x53, 0xed, 0x83, 0xd0, 0xe9, 0x86, 0xb3, 0x4b, 0x29, 0xa9, 0x7b, 0xcd, 0xae, 0xa6, 0x26, + 0x7d, 0x1e, 0xb6, 0xe6, 0x35, 0x22, 0x02, 0x55, 0xf4, 0x86, 0x97, 0xc3, 0xaa, 0x00, 0xb3, 0x85, + 0xed, 0xd5, 0x5c, 0x8e, 0xeb, 0x7e, 0x26, 0x07, 0x85, 0x43, 0x46, 0x5a, 0xf8, 0xed, 0xce, 0x68, + 0x0d, 0x68, 0x80, 0x5e, 0xc6, 0x65, 0x69, 0xde, 0x6a, 0xff, 0x3a, 0xe2, 0x97, 0x8c, 0x73, 0x79, + 0xee, 0x89, 0x77, 0xe2, 0x06, 0x74, 0xb5, 0x0c, 0xae, 0xb7, 0x41, 0x99, 0x57, 0x37, 0xd9, 0x4f, + 0x89, 0x8e, 0x28, 0x8e, 0x32, 0x19, 0x45, 0xb2, 0xfd, 0x72, 0x11, 0x21, 0x0e, 0x24, 0x40, 0x6a, + 0x7c, 0xbd, 0x13, 0x2f, 0x4c, 0x5b, 0xf1, 0x10, 0xf1, 0x2a, 0x9a, 0x8f, 0x2c, 0x9c, 0xbe, 0xee, + 0x7e, 0x80, 0x1f, 0x10, 0x74, 0x1f, 0x7f, 0x84, 0x02, 0x90, 0xe7, 0x72, 0x40, 0x5b, 0x47, 0x90, + 0x0a, 0x4b, 0x3a, 0x4e, 0x7d, 0x48, 0xaa, 0x26, 0x36, 0xaf, 0xd4, 0x9e, 0x94, 0x10, 0xa8, 0x0b, + 0xd5, 0x49, 0x8f, 0xc4, 0x08, 0x05, 0x84, 0x3f, 0xa8, 0x2d, 0xe8, 0xd5, 0xa6, 0x22, 0x55, 0x08, + 0xb7, 0x05, 0x5f, 0x08, 0x0b, 0x63, 0x1b, 0x54, 0x23, 0xdd, 0xbe, 0xfd, 0xa1, 0x05, 0x89, 0xf6, + 0x86, 0xf1, 0x24, 0x55, 0xd5, 0x6b, 0xe4, 0xee, 0xfe, 0x5c, 0x99, 0xf9, 0x09, 0x7b, 0x9b, 0xb2, + 0xa7, 0x4d, 0xdf, 0x04, 0x12, 0x7a, 0x94, 0x83, 0x6d, 0xa3, 0x9c, 0x1c, 0x31, 0xc7, 0x55, 0x5b, + 0x7f, 0xe5, 0x9a, 0x9a, 0x03, 0xf0, 0x57, 0xac, 0xbd, 0xaa, 0x92, 0x8f, 0xb5, 0x85, 0xf2, 0xfa, + 0xe1, 0xf1, 0x84, 0xd3, 0x2e, 0x29, 0x7b, 0x73, 0x8e, 0xa9, 0xa0, 0xca, 0x73, 0xa8, 0xf8, 0xef, + 0x1d, 0x57, 0x3e, 0x5f, 0xc8, 0xf4, 0xd7, 0x11, 0x1c, 0xf4, 0xbf, 0x2d, 0x5a, 0x46, 0xbe, 0x13, + 0xf3, 0x62, 0xaa, 0xef, 0x94, 0x4b, 0x69, 0xaf, 0xc7, 0x90, 0x56, 0xd9, 0x5b, 0x9a, 0x0b, 0xea, + 0x2f, 0x89, 0x10, 0x14, 0x91, 0x96, 0x87, 0x0e, 0x2e, 0x20, 0xb7, 0x41, 0x1d, 0x00, 0xc1, 0xb8, + 0xaa, 0xa3, 0x8d, 0x07, 0x81, 0x83, 0x3b, 0x8b, 0xb3, 0xea, 0x43, 0xa7, 0x50, 0xd4, 0xa1, 0xb0, + 0x00, 0xc9, 0x88, 0xcd, 0x9d, 0x7a, 0xcd, 0xc7, 0x98, 0x38, 0x38, 0x3f, 0x02, 0xc1, 0xa2, 0x7d, + 0x30, 0xf9, 0x64, 0x5e, 0x72, 0xa4, 0xa3, 0x76, 0xa5, 0xac, 0x51, 0x79, 0x78, 0x81, 0xa2, 0x01, + 0xc8, 0xb0, 0xac, 0x90, 0x89, 0xb4, 0x51, 0x33, 0x9b, 0x09, 0xf7, 0x31, 0x3e, 0x27, 0xce, 0x29, + 0x13, 0x81, 0xe2, 0xeb, 0x46, 0xe4, 0xa0, 0xcc, 0x35, 0xc1, 0xde, 0x7e, 0x19, 0x51, 0x16, 0x94, + 0xb1, 0x22, 0x43, 0xb2, 0x1e, 0xc8, 0xb7, 0xb9, 0x30, 0x0e, 0x48, 0xc0, 0x46, 0x30, 0x73, 0xee, + 0x87, 0x36, 0xbb, 0x24, 0x58, 0xca, 0x15, 0x27, 0xff, 0xc3, 0x78, 0x01, 0x7f, 0x3c, 0xc6, 0xc0, + 0x97, 0x58, 0x11, 0x8d, 0xc5, 0x47, 0xa6, 0xd4, 0xc4, 0x07, 0xc7, 0x0a, 0x31, 0x0c, 0x0d, 0xcf, + 0x03, 0x01, 0x72, 0x50, 0xf6, 0x20, 0x60, 0x5a, 0xce, 0x18, 0x01, 0xc0, 0x56, 0x86, 0x99, 0x43, + 0x07, 0xfa, 0xdb, 0x0c, 0xb0, 0x8c, 0x76, 0xe5, 0x3c, 0x0d, 0x20, 0xe0, 0x69, 0xda, 0x46, 0xb1, + 0xf9, 0x9c, 0x8f, 0x22, 0xc3, 0x53, 0xce, 0xa0, 0x67, 0xb7, 0xdc, 0x6a, 0x85, 0xc0, 0x95, 0x9d, + 0x4e, 0xc0, 0xd1, 0x7a, 0x6b, 0x16, 0xf8, 0x9c, 0x6a, 0x38, 0x1e, 0xcd, 0x20, 0xdd, 0x68, 0x2d, + 0x96, 0x8f, 0x8a, 0x99, 0x73, 0x5d, 0xb6, 0x42, 0x7c, 0x39, 0x20, 0x2f, 0x35, 0x10, 0x27, 0x98, + 0x4a, 0x5f, 0x3d, 0xbc, 0x27, 0x4e, 0x39, 0xc3, 0x78, 0x17, 0x81, 0x24, 0x3e, 0x35, 0xba, 0x2a, + 0x70, 0xfa, 0x12, 0x00, 0x74, 0x64, 0x07, 0x45, 0xc0, 0x90, 0x14, 0x06, 0x56, 0x0c, 0x47, 0xd4, + 0xc0, 0x28, 0xbb, 0xe0, 0x26, 0x00, 0x54, 0x0d, 0x8a, 0x44, 0x8e, 0xc1, 0x01, 0xb2, 0xbb, 0x89, + 0xaa, 0x0e, 0x2d, 0x04, 0x12, 0xce, 0x8c, 0xec, 0xa3, 0x24, 0xc0, 0x0e, 0x6f, 0x22, 0xdb, 0x3b, + 0x96, 0x85, 0x84, 0xc1, 0x50, 0x51, 0x0b, 0xca, 0x05, 0xda, 0xca, 0x8f, 0x2c, 0xd1, 0x01, 0x20, + 0x4f, 0xa8, 0x0c, 0xca, 0x18, 0x00, 0x35, 0xfc, 0x6c, 0xed, 0xd9, 0x15, 0x60, 0xc4, 0xf9, 0x1a, + 0xfe, 0x87, 0x14, 0x0d, 0x3d, 0x55, 0xc8, 0xe4, 0x0b, 0xc3, 0x15, 0xf3, 0xfd, 0x35, 0xf7, 0xe3, + 0xbc, 0x0e, 0xc4, 0xc6, 0x0b, 0x78, 0xfc, 0x5b, 0x63, 0x4c, 0xaf, 0xe9, 0x28, 0x9a, 0x69, 0xa6, + 0x96, 0xf9, 0x67, 0x1b, 0x4d, 0x2b, 0x88, 0x06, 0x74, 0x5c, 0x0f, 0x35, 0xdf, 0xfe, 0x24, 0x15, + 0xe8, 0x54, 0xaa, 0x9d, 0xb1, 0x58, 0xa4, 0x20, 0x26, 0x10, 0x6a, 0xaf, 0x9f, 0x2d, 0x03, 0xe3, + 0x78, 0x90, 0xc6, 0xd2, 0x63, 0x8d, 0x63, 0xb9, 0x43, 0xf7, 0xe5, 0xed, 0xff, 0x84, 0xcc, 0xde, + 0xab, 0x2e, 0x36, 0xfe, 0xb8, 0xdc, 0xb9, 0x09, 0xcf, 0xb8, 0x1c, 0x7e, 0xe0, 0x80, 0x77, 0x8a, + 0xda, 0x4e, 0x68, 0xca, 0xfb, 0x19, 0x65, 0x47, 0x15, 0xd5, 0xff, 0x88, 0x84, 0xc6, 0x8f, 0xbf, + 0x47, 0x31, 0x58, 0xe3, 0xde, 0x24, 0x40, 0x5c, 0x40, 0x2e, 0x88, 0xa4, 0x28, 0xf8, 0x0e, 0xf6, + 0x28, 0x9a, 0xab, 0x54, 0x1a, 0xd6, 0x31, 0xdf, 0xe0, 0x8c, 0x59, 0x58, 0x7e, 0xf1, 0xbc, 0x86, + 0x99, 0x8f, 0xd9, 0x35, 0x52, 0x75, 0xef, 0x94, 0x6e, 0xad, 0x2e, 0x2c, 0x62, 0x75, 0xb4, 0xd2, + 0xa4, 0xf8, 0x21, 0xf3, 0x78, 0xbe, 0x14, 0xb1, 0x31, 0x2a, 0x51, 0x4c, 0xe7, 0x30, 0xb6, 0xac, + 0xa8, 0xc4, 0x50, 0x95, 0x9f, 0x10, 0x25, 0xa3, 0x47, 0x71, 0xd5, 0xfe, 0x13, 0xf6, 0xda, 0x4d, + 0xbf, 0xc7, 0x55, 0x66, 0xc2, 0x72, 0xb0, 0x91, 0x76, 0xda, 0xaa, 0x78, 0x53, 0xf1, 0x82, 0x1a, + 0x1b, 0x5a, 0x3a, 0x61, 0x7b, 0x9d, 0xf8, 0xeb, 0xe5, 0x51, 0xc2, 0x36, 0x90, 0xbd, 0x20, 0x4f, + 0xe8, 0x86, 0xea, 0xf8, 0x50, 0xb4, 0x92, 0x66, 0xe7, 0x83, 0x14, 0x07, 0x42, 0x97, 0x93, 0x5e, + 0x3a, 0x35, 0x14, 0xe3, 0xaf, 0x19, 0x3b, 0x2f, 0xae, 0x1f, 0x29, 0x35, 0x52, 0xe2, 0x42, 0x94, + 0xf6, 0xa6, 0xa4, 0xc8, 0x2f, 0x24, 0x33, 0xc3, 0x4c, 0xea, 0x3b, 0xe1, 0xea, 0x90, 0xc3, 0x01, + 0xca, 0x06, 0xe3, 0x28, 0x50, 0x85, 0x39, 0x2b, 0xf4, 0x8f, 0x5c, 0xa1, 0x93, 0x8b, 0xd7, 0xdc, + 0x5e, 0xbc, 0x40, 0x21, 0x2a, 0xfb, 0xb4, 0x79, 0x98, 0xc4, 0x61, 0xb6, 0x40, 0x00, 0xe1, 0x2e, + 0xcb, 0xb8, 0x5e, 0xea, 0x4f, 0x07, 0x60, 0xe6, 0x02, 0xb5, 0x5a, 0x96, 0x6d, 0x98, 0xfb, 0x96, + 0x62, 0x07, 0xa1, 0x1f, 0x08, 0x1e, 0x48, 0x0e, 0x17, 0x71, 0xf8, 0x2a, 0xe3, 0xcd, 0x04, 0xb8, + 0x38, 0x18, 0xee, 0xa5, 0xe7, 0x30, 0x65, 0x08, 0xc8, 0xb1, 0x1a, 0x2e, 0x19, 0x0e, 0xdf, 0xea, + 0x28, 0x08, 0xab, 0x5d, 0xd6, 0x78, 0x00, 0x13, 0x81, 0x41, 0x35, 0x3c, 0x01, 0xc1, 0xd0, 0x3e, + 0x0f, 0x80, 0x84, 0xc4, 0x4f, 0x1e, 0xed, 0x85, 0x77, 0xc4, 0x82, 0x02, 0xd3, 0x72, 0xb2, 0xaa, + 0x01, 0xdc, 0x93, 0x50, 0x79, 0x63, 0xea, 0xd6, 0xa8, 0x6d, 0xff, 0x10, 0xd4, 0xbb, 0xe0, 0xa0, + 0x18, 0x0d, 0x23, 0xe0, 0xe1, 0xe3, 0x4d, 0x1b, 0xf9, 0x6c, 0x3b, 0x06, 0xaf, 0xc0, 0xed, 0xac, + 0x63, 0x19, 0xad, 0x05, 0x5c, 0x55, 0x64, 0xf1, 0xcf, 0xa5, 0x86, 0x2d, 0x8e, 0x01, 0xa9, 0x14, + 0x84, 0x0a, 0xac, 0x60, 0xbb, 0x20, 0x67, 0x74, 0xc4, 0x30, 0x2a, 0x31, 0x8a, 0xcb, 0x5f, 0x0c, + 0xb1, 0x20, 0x0c, 0x4f, 0x95, 0x46, 0x04, 0x3e, 0x7f, 0xd6, 0x6e, 0x6e, 0x5e, 0xff, 0x6d, 0xb9, + 0x2a, 0xc4, 0x46, 0x98, 0x25, 0x1a, 0x30, 0x00, 0x10, 0x05, 0x8c, 0xa2, 0x83, 0x6b, 0x17, 0xa0, + 0x63, 0xe8, 0xd2, 0xb8, 0x23, 0xd3, 0x3f, 0x1c, 0x90, 0xb1, 0xa8, 0xf2, 0x9d, 0xf7, 0xd6, 0xa0, + 0xd8, 0x09, 0xdb, 0xf1, 0x2f, 0xb7, 0xf1, 0x3b, 0xaa, 0x95, 0xf5, 0xe2, 0x01, 0x26, 0xec, 0x1b, + 0xbf, 0xc6, 0x5d, 0xda, 0xcf, 0x88, 0x7a, 0x52, 0xa4, 0x63, 0xb1, 0xa9, 0x02, 0x3e, 0x5b, 0xf6, + 0x3f, 0x1b, 0x6b, 0x07, 0xf9, 0x88, 0x4b, 0x4a, 0x63, 0xdf, 0xab, 0x5a, 0x98, 0xd4, 0xd9, 0x18, + 0xe6, 0xa9, 0x2b, 0xfe, 0x36, 0x36, 0xa8, 0xf5, 0x47, 0xc6, 0x07, 0x35, 0x56, 0x32, 0xc2, 0x0c, + 0xf7, 0x6e, 0x00, 0x2a, 0xbf, 0xdc, 0x7f, 0xe1, 0x43, 0x96, 0x0c, 0x25, 0x63, 0x0b, 0xca, 0xa9, + 0xb6, 0x75, 0x6e, 0xc6, 0x61, 0x7b, 0xfc, 0x4d, 0xf4, 0x43, 0xa9, 0x35, 0xf1, 0x9d, 0x12, 0x77, + 0xc2, 0x5a, 0xd5, 0x69, 0xfc, 0x13, 0xd3, 0xdb, 0x3e, 0x5f, 0x82, 0x9f, 0x66, 0x5d, 0x4b, 0xc8, + 0x34, 0x9f, 0xc4, 0x70, 0x9d, 0x00, 0x93, 0xca, 0xbb, 0x6e, 0xdf, 0xe5, 0x92, 0xd1, 0xb5, 0x7d, + 0x08, 0x9b, 0xe0, 0xaf, 0x55, 0x4d, 0x64, 0xc3, 0x71, 0x75, 0x8b, 0xef, 0x82, 0xc2, 0x62, 0x78, + 0xba, 0x4a, 0xaa, 0xb6, 0xf8, 0x28, 0x39, 0x3a, 0xb5, 0xd5, 0x53, 0x27, 0xc2, 0x26, 0x97, 0xe3, + 0x23, 0x7c, 0x2c, 0xd4, 0xa7, 0x6b, 0xc4, 0xdc, 0xe6, 0x36, 0xd3, 0x6e, 0xdf, 0x82, 0x93, 0xa1, + 0xcd, 0xb6, 0xd2, 0x6a, 0x9d, 0xa9, 0x41, 0xf0, 0x45, 0xa3, 0x24, 0x1c, 0x34, 0xec, 0xc3, 0x0d, + 0xc8, 0x00, 0x46, 0x30, 0xd5, 0x7f, 0x46, 0x2a, 0x01, 0x43, 0xab, 0xd4, 0xa9, 0x15, 0x12, 0xc6, + 0x0f, 0xf8, 0x34, 0xdc, 0xb5, 0x8e, 0xd3, 0x06, 0xa5, 0xc3, 0xb8, 0x4b, 0xf5, 0x62, 0xac, 0xab, + 0x74, 0x60, 0xc8, 0x20, 0x23, 0x8c, 0x31, 0x7b, 0x63, 0xbd, 0x92, 0x3c, 0x28, 0xc9, 0x08, 0x87, + 0xdb, 0xe4, 0x3a, 0xa0, 0x9c, 0x6c, 0x5b, 0xe8, 0xbd, 0xa4, 0xac, 0x60, 0xfb, 0x90, 0x74, 0x1d, + 0xfd, 0x62, 0xa7, 0xa0, 0x5c, 0x33, 0x0f, 0xfc, 0x77, 0xb5, 0x83, 0x50, 0x19, 0x9e, 0x25, 0xde, + 0x18, 0xab, 0x89, 0x70, 0x52, 0x0e, 0x46, 0xc8, 0xe3, 0x52, 0xef, 0x0f, 0x00, 0x02, 0xbc, 0x28, + 0x2c, 0x03, 0x46, 0x4b, 0x71, 0x69, 0xd5, 0xa5, 0x00, 0x02, 0x23, 0x4b, 0xcd, 0x49, 0xc0, 0x00, + 0x8e, 0x19, 0x10, 0xfb, 0xa3, 0xf1, 0x9d, 0x48, 0x0e, 0x05, 0xa2, 0x01, 0x24, 0xab, 0x2d, 0x32, + 0xd6, 0x6a, 0x01, 0xde, 0x5c, 0x76, 0xeb, 0xe1, 0x4a, 0x7d, 0x68, 0xee, 0x66, 0x92, 0xc6, 0x34, + 0x1b, 0x26, 0x14, 0x72, 0xe9, 0x91, 0x6c, 0xe6, 0x04, 0x57, 0x73, 0x8e, 0x14, 0x59, 0x10, 0x99, + 0x40, 0x16, 0x46, 0xee, 0xc0, 0x08, 0x1a, 0x50, 0x0a, 0x83, 0x13, 0x28, 0x58, 0x90, 0x06, 0x02, + 0x9b, 0x87, 0xf2, 0xbb, 0xfe, 0x8e, 0xeb, 0x2f, 0xdc, 0xf6, 0x9c, 0x69, 0xab, 0xe5, 0xde, 0xf6, + 0x78, 0xf6, 0x8f, 0xc6, 0x55, 0x0c, 0x8c, 0x2a, 0x08, 0x05, 0x46, 0x29, 0x2e, 0xa0, 0xb9, 0x66, + 0x24, 0x98, 0xaa, 0x19, 0x08, 0xa1, 0x54, 0x41, 0x01, 0xf5, 0xff, 0x95, 0xf4, 0x00, 0xaf, 0x05, + 0xb2, 0xa9, 0x83, 0xf4, 0xea, 0x3a, 0x5e, 0xf1, 0x06, 0xc7, 0x02, 0x08, 0xc3, 0xf8, 0x90, 0x8c, + 0xe8, 0x90, 0x35, 0x30, 0x41, 0x60, 0xb1, 0x41, 0x01, 0x37, 0x34, 0x77, 0x8d, 0x35, 0x23, 0x9b, + 0xbc, 0xbe, 0x24, 0x27, 0x6d, 0xb9, 0xb3, 0xa6, 0x97, 0x12, 0x0a, 0xcf, 0x2f, 0x41, 0x6c, 0xca, + 0xe4, 0x1f, 0xb6, 0xd7, 0x7d, 0x7b, 0xeb, 0x94, 0x5f, 0x35, 0xdf, 0x5d, 0x5a, 0x5e, 0x11, 0x26, + 0xab, 0x5a, 0xf3, 0x63, 0xe5, 0x17, 0x89, 0x7c, 0x9c, 0xda, 0xa6, 0xbe, 0x5b, 0x1b, 0xdc, 0xfc, + 0x96, 0xf6, 0xd4, 0x4d, 0x8a, 0x6e, 0xdf, 0xc4, 0x5d, 0xfb, 0xbd, 0x62, 0x09, 0x8d, 0x4e, 0x7f, + 0x04, 0x11, 0x85, 0xd8, 0xcd, 0x25, 0xea, 0x6b, 0x61, 0x15, 0x76, 0xff, 0xcf, 0x51, 0x5f, 0xf5, + 0xc3, 0x45, 0x7e, 0x05, 0x41, 0x85, 0x5e, 0x71, 0x38, 0xff, 0x4c, 0xff, 0xe2, 0x02, 0xa4, 0x1a, + 0x0e, 0x1d, 0x40, 0x46, 0x36, 0x01, 0xaf, 0x19, 0x58, 0x00, 0xd4, 0xaa, 0x00, 0xf0, 0x31, 0x41, + 0xa0, 0xe4, 0x00, 0x19, 0x40, 0x70, 0xd4, 0x09, 0x17, 0x61, 0x6c, 0x6b, 0xf9, 0x14, 0xb0, 0x57, + 0x8f, 0xf8, 0xd8, 0x97, 0xe0, 0x1b, 0xe7, 0x10, 0x26, 0x1a, 0xd0, 0x04, 0x00, 0xca, 0xd1, 0x6f, + 0xba, 0x1b, 0xe3, 0x72, 0x47, 0x62, 0xba, 0x9a, 0x18, 0xa0, 0x4f, 0x74, 0xbd, 0x89, 0x09, 0x40, + 0x2c, 0x9d, 0x02, 0x60, 0xca, 0x0f, 0x48, 0x08, 0xc5, 0xed, 0x52, 0x5a, 0x67, 0xe9, 0xf8, 0x88, + 0x50, 0x99, 0x2b, 0x58, 0x5f, 0x58, 0x3a, 0xf4, 0xb0, 0x8c, 0x09, 0x4f, 0x0f, 0x88, 0x62, 0xe1, + 0xe1, 0xc1, 0xf7, 0x2c, 0x38, 0xef, 0x12, 0xf2, 0x6b, 0x61, 0xa4, 0x50, 0x00, 0xbe, 0x2c, 0xc4, + 0x55, 0x1a, 0x0f, 0xbf, 0x2a, 0xe1, 0x9f, 0xbb, 0xd7, 0x96, 0xb3, 0xf0, 0xba, 0xa6, 0x80, 0x3f, + 0xb0, 0xc7, 0x53, 0xa4, 0x98, 0xff, 0x96, 0x43, 0xf1, 0x95, 0x9f, 0x45, 0x87, 0x70, 0x03, 0xd8, + 0xe8, 0xb8, 0xd1, 0x18, 0x6e, 0x33, 0x2c, 0xdf, 0xd8, 0x28, 0xec, 0xfb, 0x25, 0x83, 0x09, 0x44, + 0xc4, 0xb1, 0x7b, 0xf8, 0x6e, 0xec, 0x08, 0x82, 0x67, 0xc1, 0x98, 0xbf, 0xa6, 0x87, 0x65, 0xe3, + 0xec, 0x9c, 0xe4, 0xca, 0x5c, 0x59, 0x64, 0x9e, 0x2f, 0x18, 0x52, 0xfa, 0xc4, 0x78, 0x08, 0x76, + 0xed, 0xb6, 0x9a, 0x7e, 0x30, 0xb9, 0xdd, 0xa6, 0x53, 0x76, 0x33, 0xc1, 0x4a, 0x16, 0x5c, 0x36, + 0xaf, 0x97, 0x71, 0x59, 0x4c, 0xf8, 0xe8, 0xcb, 0x18, 0x45, 0xbd, 0xa2, 0x94, 0xdd, 0x07, 0x9c, + 0x57, 0xc4, 0x91, 0x99, 0xfb, 0xb7, 0xfb, 0xbb, 0x0a, 0x86, 0xb9, 0xce, 0xa2, 0xaf, 0xf8, 0xee, + 0x20, 0x89, 0x2e, 0xaa, 0xc6, 0xbe, 0x53, 0xe6, 0xc9, 0x79, 0x88, 0xb5, 0xae, 0x08, 0x7b, 0xb7, + 0x2f, 0x98, 0xb9, 0x7f, 0xc1, 0x26, 0x91, 0x71, 0x8c, 0xd8, 0xf9, 0x45, 0x65, 0xc9, 0x39, 0x46, + 0xaa, 0xd4, 0x6f, 0x04, 0x62, 0xa5, 0xfe, 0xab, 0x84, 0x7c, 0x35, 0x7a, 0x85, 0x39, 0x0c, 0x7e, + 0x14, 0xde, 0x75, 0xc2, 0x02, 0x41, 0x5c, 0x1a, 0xc4, 0x45, 0xb5, 0xc3, 0xc7, 0x46, 0x42, 0x93, + 0xf8, 0xa5, 0xdb, 0xbd, 0xf5, 0xf1, 0xf1, 0x3e, 0x3e, 0xe6, 0xfb, 0x99, 0xeb, 0x37, 0x4c, 0xe5, + 0x98, 0x65, 0xc0, 0x02, 0x44, 0x44, 0x85, 0xb7, 0x63, 0xca, 0x13, 0xff, 0x03, 0x76, 0x35, 0x3c, + 0x55, 0xb1, 0x6f, 0x2d, 0x65, 0xac, 0xb1, 0xc7, 0x69, 0x8c, 0xe2, 0x37, 0x56, 0x3b, 0xe1, 0x92, + 0x14, 0x01, 0x36, 0x8a, 0x6f, 0x03, 0x60, 0x93, 0xde, 0x8f, 0x6d, 0xb3, 0x72, 0xc5, 0xca, 0x64, + 0x50, 0xe8, 0x8f, 0xb8, 0xb9, 0x5b, 0x0a, 0x39, 0x9f, 0x2e, 0x34, 0xdf, 0x05, 0x64, 0x3c, 0xe3, + 0x39, 0x60, 0x19, 0xc7, 0x96, 0x01, 0x92, 0x1c, 0x08, 0x0e, 0x4c, 0xad, 0x2f, 0x3e, 0x1b, 0x96, + 0xf9, 0x4d, 0x65, 0xf3, 0xe2, 0xfe, 0x49, 0xc8, 0x2f, 0x2b, 0x3e, 0x38, 0xaf, 0xd5, 0x88, 0xad, + 0x62, 0x71, 0x05, 0x1a, 0xb0, 0x6f, 0xe3, 0x08, 0x9a, 0x77, 0x5b, 0x1b, 0x17, 0x3b, 0x11, 0xd4, + 0x26, 0x3c, 0x25, 0x88, 0xf8, 0x9b, 0xc5, 0x6d, 0xbe, 0x2b, 0x5c, 0x13, 0xde, 0x7c, 0xa4, 0xfe, + 0x63, 0xe0, 0xaa, 0xb5, 0x9b, 0xf9, 0xbd, 0x58, 0xfb, 0xac, 0x47, 0xfc, 0x82, 0x69, 0xc7, 0x57, + 0xc7, 0x0a, 0xed, 0xde, 0xde, 0xef, 0xfb, 0xd4, 0x6e, 0xff, 0x84, 0x29, 0x5b, 0x55, 0xda, 0x27, + 0xcc, 0xfd, 0x8d, 0xbd, 0xc9, 0xd0, 0xcf, 0x49, 0xc4, 0x15, 0x55, 0x7a, 0xaf, 0x82, 0x2a, 0xaa, + 0xaa, 0x71, 0xf6, 0x45, 0x51, 0x75, 0xf1, 0x5a, 0x6b, 0x99, 0x8f, 0x11, 0x08, 0x14, 0x47, 0x6e, + 0x20, 0x1c, 0x06, 0x1e, 0x85, 0x80, 0xce, 0x79, 0x38, 0x0a, 0x89, 0x7a, 0xbf, 0xce, 0x26, 0x28, + 0xb3, 0x7d, 0x55, 0x2e, 0x0c, 0x40, 0xb2, 0x14, 0x21, 0xc0, 0x01, 0xc3, 0xce, 0x01, 0xf2, 0x50, + 0xe7, 0x95, 0xda, 0x2a, 0x94, 0x44, 0x65, 0x15, 0xc3, 0xc7, 0xc9, 0x40, 0x01, 0xe0, 0x63, 0x64, + 0x3a, 0xf0, 0x94, 0x1c, 0x0b, 0xd4, 0x24, 0xf8, 0x67, 0x8a, 0x38, 0x60, 0x18, 0x0c, 0x28, 0x73, + 0x00, 0x25, 0x2c, 0x22, 0x61, 0x66, 0x70, 0x78, 0xe4, 0x2c, 0x02, 0x15, 0x22, 0xd0, 0x56, 0xf0, + 0xb7, 0xb4, 0x13, 0x81, 0x6c, 0x48, 0x78, 0xa9, 0x90, 0xe8, 0xf2, 0x1d, 0x42, 0xfd, 0x1c, 0x0e, + 0x99, 0xd5, 0x75, 0xdf, 0x04, 0x82, 0x22, 0x7c, 0x37, 0x94, 0x59, 0xce, 0xf8, 0xc2, 0x2b, 0x28, + 0x4a, 0x28, 0xf2, 0xe2, 0xcc, 0x8c, 0x2a, 0xc2, 0x84, 0x9d, 0x76, 0xfc, 0x24, 0x25, 0x35, 0x35, + 0xc9, 0x03, 0x01, 0xb9, 0x47, 0xc7, 0x95, 0x71, 0xd7, 0x93, 0x64, 0xb7, 0x90, 0xca, 0x54, 0xfe, + 0x0b, 0x4d, 0x78, 0xba, 0x1d, 0x9b, 0x7d, 0x08, 0xf0, 0x4a, 0x75, 0xd5, 0xe5, 0xee, 0xff, 0x31, + 0x16, 0xbf, 0x04, 0x96, 0xd5, 0xb5, 0x77, 0xca, 0x55, 0x5f, 0xc1, 0x10, 0x8b, 0xb5, 0x8a, 0xb8, + 0xbd, 0x69, 0x2e, 0xab, 0x82, 0x72, 0xa7, 0x4f, 0x79, 0x7e, 0xbe, 0x24, 0x85, 0xde, 0x86, 0xf1, + 0xfc, 0x23, 0xc4, 0xbf, 0xbb, 0xbc, 0xff, 0xec, 0x79, 0x33, 0xe2, 0x31, 0x3c, 0x83, 0xaa, 0xab, + 0xeb, 0xd3, 0x71, 0x45, 0x9a, 0x5e, 0xef, 0xe3, 0xcc, 0xc5, 0x25, 0x8d, 0x13, 0xbf, 0x3e, 0x99, + 0x76, 0xd7, 0x82, 0x21, 0x2e, 0xc6, 0x6e, 0xf6, 0x2b, 0xe6, 0x11, 0xcd, 0xfc, 0x67, 0x99, 0x3f, + 0xa8, 0x9d, 0x14, 0xb3, 0xd4, 0x50, 0x32, 0xc0, 0x30, 0xa7, 0xca, 0x04, 0x0b, 0x10, 0x20, 0x29, + 0xb4, 0x27, 0x87, 0x9c, 0x3e, 0xc1, 0xcf, 0x46, 0x06, 0xb4, 0xf1, 0x04, 0x2c, 0x89, 0x3c, 0xd4, + 0x90, 0x95, 0xc8, 0xd3, 0x2c, 0x24, 0xf0, 0x03, 0x38, 0x3c, 0x98, 0x26, 0x44, 0xc6, 0x8e, 0xf8, + 0x42, 0xc4, 0x93, 0x49, 0x26, 0x78, 0x1f, 0xa6, 0xbf, 0x05, 0x67, 0x26, 0x71, 0xa9, 0x5d, 0x23, + 0x48, 0xa7, 0x1b, 0x41, 0x8d, 0xd3, 0x83, 0xe0, 0x94, 0x99, 0x1a, 0x61, 0xac, 0xc8, 0x9f, 0x08, + 0x4f, 0x94, 0x4a, 0xaa, 0xd7, 0x09, 0xd6, 0x4c, 0x93, 0x15, 0x6f, 0x82, 0x72, 0x28, 0x8f, 0x6d, + 0xd8, 0x95, 0x76, 0x2f, 0xbe, 0x6e, 0x6c, 0x36, 0x79, 0xae, 0xff, 0x89, 0x23, 0x9f, 0xbe, 0xd5, + 0xa9, 0x38, 0x23, 0x2a, 0xa6, 0x6f, 0x3a, 0x84, 0x79, 0x09, 0x6d, 0x7e, 0x11, 0xac, 0xaa, 0xa7, + 0x0e, 0xab, 0xe0, 0xc9, 0x48, 0x70, 0xbe, 0x13, 0xab, 0x1a, 0x44, 0x21, 0xb1, 0xbf, 0xc5, 0x76, + 0x66, 0x42, 0x0a, 0x9b, 0x1b, 0x1f, 0x08, 0x9c, 0xd4, 0xd3, 0x9e, 0x49, 0xc0, 0x6f, 0x1f, 0xa7, + 0xe3, 0x04, 0x24, 0xf5, 0x28, 0xfd, 0xb3, 0xe3, 0xd6, 0xa0, 0xce, 0xfb, 0x70, 0xe3, 0x02, 0x02, + 0xa0, 0x24, 0x41, 0xf8, 0x2b, 0xcb, 0xa8, 0x75, 0xf2, 0x49, 0x95, 0x27, 0x27, 0x3a, 0x7c, 0xa5, + 0xaa, 0x43, 0xd7, 0x42, 0x5d, 0x97, 0x93, 0xfa, 0x23, 0xfc, 0xa2, 0x4b, 0x91, 0x5c, 0x9c, 0x40, + 0x84, 0x92, 0xe7, 0x5f, 0x98, 0x95, 0x5f, 0x90, 0xaf, 0x7f, 0xbd, 0xef, 0xe6, 0x16, 0xb2, 0x7f, + 0x8a, 0x2d, 0xb5, 0x43, 0x9b, 0xd7, 0xc4, 0x84, 0x25, 0x75, 0x4a, 0xfe, 0x0b, 0x45, 0xb9, 0xff, + 0xbb, 0x4d, 0x1d, 0xcc, 0x31, 0x75, 0xf2, 0x8f, 0x7d, 0xd7, 0x20, 0xcb, 0xd7, 0xdd, 0xa6, 0x97, + 0xe2, 0x8a, 0x34, 0x34, 0x5c, 0xed, 0x8c, 0xcc, 0x7f, 0x87, 0x4b, 0x19, 0x5f, 0xd8, 0xce, 0x9d, + 0x0d, 0x8d, 0xea, 0x57, 0xbf, 0xfe, 0x34, 0x88, 0x18, 0xe1, 0xf0, 0x8f, 0x5b, 0x27, 0x08, 0x87, + 0x35, 0x23, 0x39, 0xf2, 0xbe, 0x25, 0x59, 0x97, 0xe1, 0x48, 0xc0, 0xf2, 0x68, 0x41, 0xcb, 0x5a, + 0xa0, 0x52, 0x86, 0x83, 0xa7, 0x1c, 0x79, 0xb3, 0x3d, 0xe3, 0xac, 0x5f, 0xe1, 0x4b, 0x69, 0xfb, + 0x68, 0x1e, 0xff, 0xd8, 0xc1, 0xa9, 0xb9, 0x98, 0xc5, 0xca, 0x12, 0xe4, 0xd6, 0xab, 0x82, 0xbb, + 0xee, 0xed, 0x4b, 0x99, 0x73, 0x52, 0xf0, 0x4e, 0x4c, 0xbb, 0xad, 0x5b, 0xe5, 0x12, 0xb5, 0x93, + 0x8a, 0x29, 0xf1, 0x77, 0x7c, 0x77, 0x20, 0x8a, 0xd2, 0x37, 0x21, 0x79, 0x7f, 0x93, 0x72, 0xaa, + 0xfd, 0xd8, 0x3e, 0x5f, 0xe1, 0x21, 0x0a, 0xc6, 0x3b, 0xdd, 0xf4, 0x5a, 0x8a, 0xe4, 0x2b, 0xbe, + 0x2f, 0x9a, 0xda, 0xd5, 0x72, 0x66, 0xff, 0xa3, 0x34, 0x14, 0x74, 0x5a, 0x88, 0xe4, 0x23, 0xbd, + 0xc4, 0xf3, 0x1d, 0x0d, 0xb4, 0x34, 0xc6, 0xf5, 0xe8, 0x43, 0x88, 0xa6, 0x83, 0xb6, 0xdb, 0x0d, + 0x93, 0x60, 0xb3, 0x92, 0x7f, 0xc3, 0x9c, 0x9b, 0xdc, 0x0a, 0x7c, 0xdd, 0xdc, 0x21, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x9a, 0x4e, 0x27, 0x30, 0xeb, 0xcc, 0x65, 0xaf, 0xd9, 0x6b, 0x5f, 0x10, 0x47, + 0x77, 0x6d, 0xee, 0xeb, 0x9a, 0xcc, 0xd9, 0xf8, 0xcd, 0xe9, 0xde, 0xe9, 0xbd, 0xdb, 0xa5, 0x27, + 0x09, 0x56, 0xba, 0xbd, 0xf2, 0x16, 0xf7, 0xf2, 0x9d, 0xef, 0xf2, 0x99, 0x3a, 0x71, 0x7d, 0x04, + 0x72, 0xfa, 0xf4, 0x2b, 0xc1, 0x00, 0x4a, 0x86, 0x8d, 0x67, 0x72, 0x3d, 0x8c, 0xc3, 0xb7, 0x0c, + 0xbc, 0xb2, 0xff, 0x96, 0xf5, 0x7f, 0x41, 0x36, 0xfa, 0xb7, 0xd7, 0x3f, 0xd6, 0x23, 0xfc, 0x10, + 0xa2, 0xd5, 0xf4, 0x12, 0x75, 0x70, 0x45, 0x37, 0x59, 0x75, 0xbe, 0x20, 0x97, 0x59, 0xf2, 0xc7, + 0x5c, 0xb5, 0x5b, 0x4b, 0xbb, 0xbe, 0xb8, 0x2c, 0xde, 0x87, 0x62, 0x97, 0xb6, 0x56, 0xad, 0x4c, + 0x0a, 0x99, 0x64, 0x7f, 0x8c, 0xa5, 0xb7, 0x2b, 0x1c, 0xff, 0x1b, 0xa3, 0xae, 0xbe, 0x30, 0xb4, + 0x83, 0x2a, 0xb3, 0x1b, 0xc3, 0x72, 0x1b, 0x51, 0xe2, 0x6a, 0xcb, 0x03, 0xb4, 0x30, 0x24, 0x0c, + 0x1e, 0x85, 0xe1, 0xde, 0xa2, 0xfe, 0x78, 0xbf, 0x72, 0xb6, 0xad, 0x5f, 0xc1, 0x65, 0x1c, 0x61, + 0x72, 0x11, 0x61, 0x30, 0xe3, 0xcc, 0xab, 0xff, 0x29, 0x67, 0x7c, 0x5e, 0xb3, 0x1a, 0xaa, 0x36, + 0x61, 0xde, 0xbd, 0x5c, 0x12, 0xf4, 0x9d, 0x8f, 0x1a, 0xb8, 0xe5, 0xf4, 0x13, 0x7f, 0x08, 0xab, + 0x63, 0x16, 0xdf, 0x56, 0x88, 0xe2, 0x03, 0x06, 0xfa, 0xaa, 0x7b, 0x5e, 0x2e, 0xad, 0xd2, 0x55, + 0x26, 0x44, 0xb8, 0x2a, 0x3e, 0x6d, 0xd2, 0x84, 0x3f, 0xfe, 0x07, 0xd8, 0xc9, 0x4d, 0xac, 0xaa, + 0x95, 0x3f, 0xe2, 0x5f, 0x0a, 0x12, 0x0b, 0xf5, 0x14, 0xd3, 0x35, 0xd7, 0x29, 0x96, 0x21, 0xa2, + 0x6c, 0x3d, 0x87, 0xdb, 0xec, 0xcb, 0x65, 0xaf, 0x0e, 0x3d, 0x76, 0xeb, 0x16, 0x54, 0x63, 0x5e, + 0x9e, 0xfe, 0x20, 0x15, 0x4f, 0x15, 0x08, 0xc5, 0x69, 0xcf, 0x69, 0x51, 0x19, 0x6b, 0x3b, 0xad, + 0x37, 0xf8, 0xfa, 0x99, 0x74, 0xe0, 0xf0, 0xfd, 0xd0, 0x7e, 0x86, 0x02, 0x7f, 0xcc, 0x75, 0xf8, + 0x3f, 0x63, 0xc1, 0x66, 0xd2, 0xc8, 0xa3, 0x3a, 0xd3, 0x2a, 0x57, 0x24, 0x75, 0x13, 0xfe, 0x24, + 0x85, 0x5e, 0x46, 0xee, 0xe9, 0xf8, 0x28, 0x16, 0x8e, 0x72, 0x4c, 0xda, 0x68, 0x6d, 0xac, 0xbc, + 0xfd, 0x0d, 0x62, 0x4e, 0xad, 0x11, 0xc5, 0x84, 0x35, 0x36, 0x6a, 0x8c, 0x47, 0x28, 0xbb, 0xa7, + 0xf5, 0xcb, 0xe6, 0x35, 0x6e, 0xba, 0x17, 0xf3, 0xeb, 0x1f, 0xc4, 0xa2, 0x8e, 0xde, 0x25, 0x47, + 0x7e, 0x2d, 0x71, 0x47, 0x44, 0xc8, 0x1a, 0xe4, 0xe0, 0x9f, 0x08, 0xa0, 0xab, 0xcb, 0xd8, 0xea, + 0xad, 0xf4, 0x7a, 0x93, 0x90, 0x63, 0xd8, 0xd2, 0xf4, 0x77, 0xae, 0x2e, 0x87, 0x2a, 0x4c, 0xc3, + 0x52, 0x49, 0x72, 0x91, 0xdd, 0x29, 0x38, 0xa3, 0x3d, 0x96, 0x6e, 0xa5, 0xfc, 0x49, 0x6e, 0xc0, + 0xc4, 0x0d, 0x2f, 0x89, 0x82, 0x1e, 0x51, 0x7b, 0x88, 0x58, 0x5c, 0x12, 0xda, 0xa6, 0xf3, 0x79, + 0x32, 0x0f, 0x82, 0x1e, 0x46, 0xdc, 0xf8, 0x29, 0x2b, 0x69, 0xfa, 0x4f, 0xc9, 0xbd, 0xf0, 0x4b, + 0x6c, 0x94, 0xda, 0xd3, 0x62, 0xbb, 0x12, 0xd5, 0x9b, 0x3f, 0x66, 0x5b, 0x5f, 0x0a, 0x08, 0xa4, + 0xf7, 0x69, 0xc7, 0x95, 0xe8, 0x9d, 0xf7, 0xbb, 0xe3, 0x2d, 0x8d, 0x62, 0xa5, 0x82, 0x03, 0x48, + 0xb5, 0x59, 0x56, 0x5a, 0xb2, 0x55, 0x27, 0xb6, 0x46, 0xcf, 0x3e, 0x30, 0xe9, 0x87, 0x3a, 0x81, + 0xf0, 0x00, 0xba, 0x42, 0x43, 0xcb, 0x91, 0xe1, 0x3f, 0x29, 0x1d, 0xf9, 0xb2, 0x86, 0x4a, 0x31, + 0x9f, 0x19, 0x7a, 0x13, 0x28, 0x8d, 0x9c, 0xbc, 0x91, 0x8d, 0x44, 0x2b, 0x1b, 0x98, 0xa3, 0xe8, + 0x9a, 0xa0, 0x25, 0x74, 0x64, 0x45, 0xf1, 0x97, 0x8c, 0x27, 0xf4, 0x74, 0x49, 0xbd, 0xeb, 0xd1, + 0x11, 0xee, 0x0c, 0x0c, 0x72, 0xf1, 0x2f, 0xf0, 0x56, 0x69, 0x73, 0xac, 0x5d, 0x73, 0x7c, 0xff, + 0x0a, 0x47, 0x6e, 0x3d, 0x4b, 0xfc, 0x0a, 0x84, 0x2e, 0x39, 0x90, 0xd2, 0xa8, 0x5d, 0x85, 0x60, + 0x06, 0x75, 0x4c, 0x1e, 0x32, 0xc7, 0x50, 0x22, 0x28, 0x66, 0x63, 0x5b, 0x0d, 0x41, 0xa5, 0xcc, + 0xc1, 0x41, 0x56, 0x83, 0x2c, 0xa2, 0xf0, 0x57, 0x5a, 0x7a, 0x74, 0xf2, 0xc0, 0x2e, 0xbe, 0x3f, + 0x70, 0x84, 0x15, 0x95, 0x36, 0xb5, 0xb2, 0x00, 0x7c, 0xd7, 0x6c, 0x4b, 0x8f, 0xe2, 0x41, 0x58, + 0x94, 0xaf, 0xcd, 0x9e, 0x18, 0x8a, 0x78, 0xe3, 0xc1, 0x40, 0xc5, 0xd5, 0x20, 0x7c, 0xf2, 0x17, + 0x44, 0x55, 0x9e, 0xba, 0x0b, 0xf4, 0xdc, 0x16, 0x12, 0xb5, 0x77, 0x7d, 0x6a, 0x92, 0xb8, 0x48, + 0x63, 0x4f, 0x7b, 0xdf, 0xce, 0x45, 0xfc, 0x4f, 0x45, 0xbf, 0x0f, 0x5e, 0xd5, 0xde, 0x94, 0x62, + 0xf8, 0xda, 0xd7, 0x02, 0x81, 0x3e, 0xec, 0xe9, 0x8c, 0xf7, 0x8d, 0x9f, 0x43, 0x72, 0xa2, 0xd9, + 0x3d, 0x4b, 0x88, 0x23, 0xcd, 0xae, 0xf1, 0x39, 0xcc, 0xd2, 0x36, 0x83, 0xa4, 0xbd, 0x5a, 0xa5, + 0xb3, 0x25, 0x0b, 0x12, 0x05, 0x14, 0x6f, 0x9d, 0xf2, 0x76, 0xc3, 0x35, 0x93, 0x07, 0xe1, 0xde, + 0x59, 0x0e, 0xdc, 0x5b, 0xa6, 0xe7, 0xa3, 0x6c, 0x63, 0xad, 0x8f, 0x59, 0xf5, 0x28, 0x5f, 0xf0, + 0x61, 0x49, 0x3e, 0x06, 0x98, 0x1f, 0x00, 0xe6, 0xdf, 0xc7, 0x80, 0x02, 0x90, 0x94, 0x43, 0xfe, + 0x0d, 0x28, 0xc4, 0x3a, 0xe0, 0x01, 0x2b, 0x88, 0x2a, 0xf2, 0x91, 0x88, 0xb3, 0xff, 0xfa, 0x62, + 0x3d, 0xb7, 0x78, 0xfe, 0x31, 0xb7, 0x97, 0xf6, 0xe0, 0xa0, 0xb1, 0x99, 0x80, 0x0d, 0xe4, 0x81, + 0x87, 0x16, 0xda, 0x7e, 0x03, 0x71, 0xfc, 0xf0, 0xdc, 0xd8, 0xaa, 0xa8, 0x00, 0x86, 0x77, 0xa1, + 0x2d, 0x2f, 0xc3, 0xa6, 0xbb, 0x2f, 0x0e, 0x1f, 0x76, 0xdc, 0xba, 0x69, 0xff, 0xcb, 0xda, 0x49, + 0x70, 0x8d, 0xbb, 0xd3, 0xa7, 0xe7, 0x97, 0x85, 0xf6, 0xed, 0x9f, 0xd4, 0xdd, 0x7d, 0xb1, 0x57, + 0xf8, 0x67, 0xb4, 0x6e, 0xbe, 0x7a, 0x8b, 0x6b, 0xf2, 0x5b, 0x3c, 0x69, 0x2e, 0x08, 0xcd, 0x2c, + 0x3d, 0x57, 0x41, 0x9e, 0x97, 0x90, 0x10, 0x5e, 0xfe, 0xf4, 0x9e, 0x4e, 0xba, 0xf8, 0x43, 0x3e, + 0x6f, 0x7d, 0x69, 0x17, 0x92, 0xf7, 0x72, 0x71, 0x14, 0xc9, 0x1c, 0x6c, 0xb6, 0x5b, 0x69, 0xae, + 0x20, 0x41, 0x0b, 0x62, 0xbb, 0x8a, 0xcb, 0x77, 0xc4, 0x5d, 0x57, 0x2f, 0x41, 0xff, 0xfd, 0x5e, + 0x23, 0x84, 0x43, 0xdc, 0x43, 0x2d, 0xa1, 0x95, 0x8b, 0x47, 0x34, 0xbc, 0x14, 0xc3, 0xba, 0x60, + 0x35, 0xa9, 0x4c, 0x86, 0xe1, 0x80, 0x24, 0x98, 0x58, 0x04, 0x22, 0x4a, 0xb8, 0x04, 0xd8, 0xe5, + 0x21, 0x37, 0xc3, 0x07, 0x0e, 0x8e, 0xee, 0x2d, 0xbe, 0x6e, 0x78, 0xef, 0x83, 0x90, 0x42, 0x1e, + 0x85, 0x45, 0xbc, 0x03, 0x47, 0xc4, 0xb6, 0x46, 0x57, 0x75, 0xc2, 0x16, 0x38, 0x8d, 0x2d, 0x96, + 0x31, 0xbc, 0x8a, 0xb6, 0x44, 0xe7, 0x04, 0xa0, 0x00, 0x41, 0x5d, 0xf6, 0xae, 0xfe, 0x19, 0x3d, + 0xd0, 0x0a, 0x92, 0x4f, 0xb9, 0x28, 0x45, 0x4b, 0xc5, 0x25, 0xec, 0x7f, 0xe1, 0x4e, 0x6e, 0xed, + 0xbe, 0x5d, 0xee, 0xbb, 0xc9, 0x9f, 0x93, 0x5a, 0xf9, 0xb9, 0x71, 0xbf, 0x7a, 0x98, 0x6b, 0x08, + 0xe2, 0x43, 0x93, 0x63, 0x40, 0xff, 0x49, 0x43, 0xa1, 0x50, 0x19, 0xee, 0x2d, 0xe7, 0xe2, 0x8b, + 0xf0, 0x47, 0xc7, 0x4b, 0x17, 0x99, 0x3e, 0x1c, 0x83, 0x52, 0x53, 0x80, 0x3c, 0x3f, 0x4a, 0x39, + 0x5a, 0x84, 0x46, 0xe6, 0xf9, 0x70, 0x32, 0xf8, 0xa8, 0xfa, 0xf0, 0x60, 0x0a, 0x48, 0x0c, 0x05, + 0x72, 0x2a, 0x3e, 0x44, 0x85, 0x66, 0x42, 0xae, 0xd5, 0x99, 0x3b, 0x77, 0x38, 0x20, 0x05, 0x00, + 0x96, 0x13, 0x30, 0x50, 0x30, 0xf2, 0x9a, 0x8a, 0xfc, 0xd4, 0x7c, 0xa9, 0xd1, 0x14, 0x3d, 0x80, + 0x12, 0xcd, 0x79, 0x87, 0x60, 0x94, 0xbd, 0xa4, 0x05, 0x98, 0x79, 0x2f, 0xc3, 0xb7, 0xdb, 0xb3, + 0xb3, 0xa6, 0xcf, 0x20, 0xa2, 0xf6, 0x14, 0xe3, 0x8e, 0x41, 0x4a, 0x2f, 0xc9, 0xc1, 0xad, 0xdc, + 0x61, 0x69, 0x96, 0x22, 0x36, 0x24, 0x00, 0x1c, 0x06, 0xad, 0x41, 0xa8, 0xd7, 0xdd, 0xe5, 0xce, + 0xd4, 0x23, 0x0c, 0x6f, 0x28, 0x4f, 0x24, 0xdf, 0x87, 0x39, 0x62, 0x80, 0x4a, 0xf8, 0x7a, 0x8b, + 0xe9, 0xb5, 0x81, 0x00, 0x48, 0x2c, 0xad, 0x56, 0x89, 0x65, 0xb0, 0x7f, 0x63, 0x03, 0x9d, 0x2a, + 0x0d, 0x80, 0x94, 0x07, 0x5c, 0x48, 0x31, 0x05, 0x85, 0x37, 0x14, 0x38, 0xb4, 0x6c, 0xaa, 0x76, + 0xa0, 0x06, 0xee, 0x24, 0xfd, 0xdc, 0x3f, 0x6a, 0x4c, 0xf8, 0xa4, 0x58, 0x78, 0x6c, 0xa1, 0x55, + 0x70, 0x76, 0x80, 0x03, 0xf8, 0xa2, 0x6a, 0x81, 0x0b, 0xfc, 0x1e, 0xfc, 0x23, 0xc1, 0x1d, 0xcb, + 0x8f, 0x75, 0x11, 0xca, 0x44, 0xdd, 0x6b, 0x93, 0x32, 0x8b, 0x9b, 0x9b, 0xb4, 0xbe, 0x2b, 0x2f, + 0x95, 0x2c, 0x78, 0xe0, 0x35, 0x89, 0xf1, 0x31, 0xf8, 0x7a, 0xd9, 0xbb, 0x58, 0xc1, 0xcf, 0xd8, + 0x9c, 0xff, 0x81, 0x66, 0x1a, 0x85, 0x95, 0x07, 0x4b, 0x0f, 0xb0, 0xe9, 0x01, 0xa8, 0x57, 0x30, + 0x84, 0x86, 0x90, 0x71, 0x5d, 0x3e, 0x0a, 0x85, 0x71, 0x35, 0xe2, 0x01, 0x80, 0x28, 0x14, 0xe1, + 0x64, 0x84, 0xd5, 0xf0, 0xaa, 0xb5, 0x8b, 0x77, 0x12, 0x0a, 0x01, 0x67, 0x17, 0x5b, 0xad, 0x24, + 0xaf, 0xec, 0x38, 0xa0, 0x04, 0xf4, 0xb6, 0xd1, 0x0c, 0xb7, 0xfe, 0x9e, 0x4f, 0x26, 0x0d, 0xa3, + 0xad, 0x34, 0x79, 0xf4, 0x7f, 0xd8, 0x60, 0x10, 0x05, 0x21, 0x61, 0x55, 0xf4, 0x98, 0xfb, 0x88, + 0x52, 0x37, 0x1b, 0x96, 0xfc, 0xd9, 0x3b, 0xeb, 0xe0, 0xb2, 0x5b, 0xa8, 0xba, 0x6e, 0x2b, 0x12, + 0x98, 0xca, 0x84, 0x5a, 0x8b, 0x45, 0xbc, 0x4c, 0x29, 0x2f, 0x15, 0x92, 0xf4, 0x4c, 0xf0, 0xa3, + 0x15, 0x9c, 0xe1, 0x6e, 0x14, 0x97, 0x23, 0x76, 0xdb, 0xd7, 0xd3, 0xf1, 0x00, 0x80, 0x71, 0x6c, + 0xdf, 0x58, 0x15, 0x0c, 0x25, 0x2a, 0x9e, 0x15, 0x99, 0x81, 0x5f, 0xc1, 0x00, 0x50, 0x8c, 0x19, + 0x94, 0x9e, 0xc1, 0xb8, 0xcc, 0x8a, 0x27, 0xda, 0x71, 0x03, 0x43, 0x81, 0xa7, 0x7e, 0x0a, 0x44, + 0x02, 0xcd, 0xdd, 0xc0, 0xb0, 0x0e, 0x22, 0xe1, 0xc0, 0x00, 0x86, 0x22, 0x85, 0x40, 0xca, 0xaf, + 0x42, 0x3c, 0xdb, 0x86, 0x38, 0x31, 0x1b, 0x0b, 0xb8, 0x3a, 0x45, 0xb7, 0xb6, 0xe0, 0xa8, 0x09, + 0x3e, 0x8b, 0x06, 0x9e, 0xc1, 0xa1, 0xbb, 0x87, 0xf0, 0x8d, 0xf3, 0x4b, 0x54, 0x1d, 0xd0, 0x2f, + 0x17, 0xb6, 0xac, 0x3a, 0x14, 0x58, 0xc6, 0xff, 0xcb, 0x08, 0xe7, 0xfc, 0x2a, 0xfc, 0xdb, 0xf1, + 0x01, 0x63, 0xb2, 0x2d, 0x95, 0x49, 0x81, 0x40, 0x9b, 0x12, 0xc8, 0x20, 0xd4, 0x33, 0x02, 0x64, + 0x8a, 0x1b, 0xd6, 0x3f, 0x64, 0x0e, 0x91, 0x7c, 0x3a, 0x77, 0x61, 0xe4, 0xbb, 0x08, 0x71, 0x5b, + 0xde, 0xf7, 0x7c, 0x95, 0x5c, 0xdd, 0x90, 0x9f, 0xae, 0x6b, 0x0c, 0x73, 0x2f, 0xe6, 0x2d, 0xef, + 0xe3, 0x21, 0x9b, 0xa1, 0x4b, 0xb7, 0x43, 0x8e, 0x7a, 0x3a, 0xeb, 0x95, 0xa7, 0xe1, 0x2a, 0x32, + 0x67, 0xcc, 0xdf, 0x2e, 0xf7, 0x7c, 0x51, 0x0f, 0x2c, 0x62, 0x9c, 0x5d, 0x7f, 0x08, 0x1d, 0x6b, + 0x33, 0x15, 0xbb, 0xe6, 0xee, 0x4f, 0xdc, 0x32, 0x0a, 0x41, 0x11, 0x15, 0x66, 0x1c, 0x50, 0x0d, + 0x62, 0xa8, 0xd2, 0xf0, 0xc0, 0x30, 0x0b, 0x74, 0xde, 0x6d, 0x89, 0x00, 0xe0, 0x37, 0x28, 0x1d, + 0xa5, 0xb8, 0x5e, 0x63, 0xfc, 0x20, 0x18, 0x04, 0x45, 0xb6, 0xd6, 0x2f, 0x10, 0x0a, 0xaf, 0x56, + 0x5e, 0xbd, 0x8e, 0x0a, 0xc1, 0x2a, 0x27, 0xf1, 0x01, 0xd2, 0x5b, 0x69, 0x37, 0x2c, 0x62, 0x5e, + 0x5e, 0xfc, 0x59, 0xd4, 0x9a, 0x9f, 0xfc, 0x48, 0x52, 0x73, 0x8d, 0xc2, 0x70, 0x05, 0x8b, 0xd8, + 0xdc, 0xb8, 0xf3, 0x18, 0x45, 0x17, 0xe0, 0xa3, 0xee, 0xa9, 0x17, 0x17, 0x8b, 0xc4, 0x85, 0x09, + 0x96, 0x85, 0xbb, 0x6d, 0x21, 0x26, 0x03, 0xe2, 0x4a, 0xb2, 0x87, 0xf0, 0xbd, 0x4b, 0x31, 0x7e, + 0xf8, 0x50, 0xb3, 0xe2, 0x05, 0xbc, 0x57, 0x32, 0xb4, 0xb5, 0x91, 0x00, 0x96, 0x10, 0xa0, 0x70, + 0xc3, 0x01, 0x80, 0x94, 0xb1, 0x96, 0xb7, 0xae, 0x6f, 0xc4, 0x94, 0xf8, 0xbc, 0x31, 0xcc, 0x65, + 0xd4, 0xbc, 0x79, 0x5b, 0xca, 0xca, 0x96, 0x19, 0x8c, 0x56, 0x93, 0x1a, 0x9a, 0x26, 0x2a, 0x5d, + 0x0b, 0x48, 0x42, 0x8c, 0xb6, 0x2b, 0x10, 0x34, 0x3e, 0xb5, 0xb8, 0x88, 0x50, 0x81, 0xec, 0x6b, + 0x67, 0x80, 0x01, 0x1e, 0x70, 0x0e, 0x67, 0xc9, 0xe0, 0x00, 0xe1, 0x60, 0x03, 0x3c, 0x70, 0xb0, + 0x19, 0x2a, 0xb9, 0x28, 0x3c, 0x4e, 0x6a, 0x60, 0x4e, 0x84, 0xb4, 0xbc, 0x11, 0xdd, 0xf7, 0xe0, + 0x84, 0x18, 0x82, 0x51, 0x12, 0x5a, 0xf7, 0x68, 0x97, 0x27, 0xc9, 0x2f, 0xc2, 0x5b, 0xdf, 0x0b, + 0x7b, 0xf0, 0x5c, 0x56, 0xda, 0xdc, 0x57, 0x7c, 0xbc, 0x20, 0x33, 0x55, 0x52, 0xcc, 0xf0, 0xb8, + 0xd0, 0xee, 0xa6, 0xdc, 0xa4, 0x4a, 0xd6, 0x30, 0xc0, 0x40, 0x45, 0x20, 0xa6, 0x7c, 0x98, 0x3d, + 0x67, 0xc4, 0x8c, 0xe0, 0xb3, 0x6c, 0x98, 0xd1, 0xd2, 0x24, 0x3c, 0x55, 0x17, 0xa1, 0x90, 0x8c, + 0x6c, 0xcd, 0x35, 0x23, 0xb4, 0xe9, 0x79, 0x0e, 0x07, 0x31, 0x02, 0x42, 0x84, 0x9a, 0x6c, 0xa7, + 0x4c, 0x3b, 0xe3, 0xc2, 0x08, 0x03, 0x6a, 0x46, 0x1e, 0x4d, 0x12, 0x3c, 0xb7, 0xa3, 0x15, 0xd6, + 0x48, 0x6e, 0x41, 0x2b, 0xc2, 0x01, 0x81, 0xb2, 0xe6, 0xe3, 0x1c, 0x2c, 0xa0, 0xd8, 0x30, 0x57, + 0x60, 0xa5, 0x73, 0x4e, 0x69, 0x41, 0xd9, 0xa0, 0x2f, 0x42, 0xfa, 0xa0, 0x63, 0x0a, 0x3d, 0x2e, + 0xff, 0x15, 0xe1, 0x88, 0x2a, 0x2f, 0x27, 0xca, 0xcd, 0x0f, 0x97, 0xb1, 0x0a, 0x71, 0x1a, 0xd6, + 0x45, 0x32, 0xa8, 0x19, 0xc1, 0x24, 0xd2, 0x26, 0x7e, 0xae, 0x2f, 0x3b, 0x2b, 0x9b, 0xf5, 0x89, + 0x05, 0x44, 0xbd, 0xed, 0xde, 0xdf, 0x2f, 0x61, 0xe5, 0x29, 0x3e, 0x3f, 0xab, 0x92, 0x71, 0x1a, + 0x56, 0xd2, 0x5d, 0x70, 0x95, 0xf6, 0x8f, 0x9f, 0xde, 0x92, 0xd4, 0x32, 0x0a, 0x47, 0x11, 0xdc, + 0x89, 0x55, 0x75, 0x77, 0x7f, 0xd6, 0x8f, 0xc4, 0x41, 0x61, 0x6d, 0xd6, 0xb4, 0xd5, 0x46, 0x57, + 0xc4, 0xe2, 0x61, 0x43, 0x0b, 0x8a, 0x79, 0xde, 0x73, 0xdc, 0xb7, 0x79, 0xd8, 0x0b, 0x2c, 0x5a, + 0x94, 0x90, 0x11, 0x01, 0x0d, 0x01, 0xfc, 0x43, 0xd6, 0x8a, 0x96, 0x20, 0x22, 0x0a, 0xca, 0xd8, + 0xb8, 0xfa, 0x0e, 0xa1, 0xa1, 0x09, 0x99, 0xc8, 0x14, 0xe5, 0xd3, 0x26, 0xa5, 0x79, 0x70, 0x80, + 0x60, 0x15, 0x1d, 0x56, 0xac, 0x81, 0x0c, 0x6d, 0x9c, 0x40, 0x2b, 0x1d, 0x23, 0x2e, 0x5b, 0x8a, + 0xdf, 0xc2, 0x21, 0x43, 0x3e, 0x2a, 0x0b, 0x62, 0xed, 0x4e, 0xfe, 0x71, 0x85, 0x55, 0x3a, 0xe3, + 0x36, 0x72, 0xc9, 0x15, 0x8f, 0xbc, 0xe8, 0x53, 0xfc, 0x6d, 0x4a, 0xf4, 0x28, 0xc5, 0x5e, 0x5b, + 0x3d, 0x81, 0x50, 0xf5, 0x96, 0xc3, 0x8a, 0x9b, 0x8c, 0xa8, 0x5c, 0x72, 0x23, 0x03, 0x53, 0x81, + 0xe4, 0xe0, 0xfa, 0xff, 0x8a, 0xfc, 0x4c, 0x15, 0xc1, 0xdf, 0xc7, 0x11, 0xf8, 0xe9, 0xf3, 0x7b, + 0xad, 0xa4, 0x38, 0xca, 0x65, 0x3c, 0x11, 0x76, 0x25, 0x74, 0xfc, 0x13, 0x9b, 0x8f, 0x2a, 0x96, + 0x19, 0xba, 0x96, 0xa6, 0x2f, 0x8e, 0x32, 0x8b, 0x97, 0x84, 0x88, 0x99, 0xc2, 0x70, 0x9e, 0x48, + 0x70, 0x50, 0xc9, 0x83, 0x2a, 0x91, 0x66, 0xf8, 0xac, 0x5f, 0x63, 0x9d, 0x8a, 0xe8, 0xe9, 0xd7, + 0x82, 0x7c, 0xfb, 0x5a, 0xa9, 0xb8, 0xa7, 0x78, 0x80, 0xa1, 0x1f, 0x57, 0xac, 0x05, 0xac, 0x6c, + 0x1c, 0x3c, 0x4c, 0x46, 0xe1, 0xad, 0xe8, 0x32, 0x04, 0x52, 0x04, 0x37, 0x6f, 0xba, 0x03, 0x05, + 0x70, 0x47, 0xc4, 0xf0, 0x4f, 0x22, 0x64, 0xb1, 0x20, 0x83, 0x05, 0x91, 0x61, 0xea, 0x0e, 0xac, + 0x3c, 0xe6, 0x3d, 0xb0, 0xb8, 0x07, 0x1d, 0x51, 0x05, 0x26, 0xcd, 0xfc, 0x1b, 0x39, 0x65, 0x67, + 0x2f, 0x84, 0x42, 0x96, 0x79, 0x16, 0x89, 0x2c, 0xb9, 0x3e, 0x06, 0xc0, 0x54, 0xa4, 0xeb, 0xd5, + 0x4f, 0x95, 0x67, 0x08, 0xc2, 0x84, 0x11, 0xf2, 0x59, 0x97, 0x24, 0x11, 0x4d, 0x06, 0x72, 0xb5, + 0xaa, 0xee, 0xdc, 0xd3, 0xcf, 0xc4, 0x7d, 0x00, 0x60, 0x0d, 0x23, 0x78, 0x38, 0xce, 0x10, 0x10, + 0x14, 0xf9, 0x35, 0x64, 0x2c, 0xd9, 0x81, 0xdd, 0x2a, 0x30, 0xd2, 0x76, 0x00, 0x78, 0x78, 0x5e, + 0x56, 0x37, 0x16, 0x64, 0xba, 0x1e, 0x07, 0x0a, 0x25, 0x42, 0xc0, 0x00, 0x94, 0x63, 0x1c, 0xf1, + 0x01, 0x10, 0x56, 0x52, 0x60, 0x2b, 0x25, 0x20, 0x12, 0x03, 0xbc, 0x6a, 0x40, 0x5c, 0x4b, 0x42, + 0x16, 0x81, 0x21, 0xca, 0x91, 0x11, 0x06, 0x69, 0xcb, 0x4c, 0x2f, 0x68, 0x3c, 0x9c, 0x21, 0x1f, + 0x71, 0x9b, 0x8f, 0x5c, 0x93, 0x38, 0x56, 0xf6, 0xf3, 0x53, 0xe0, 0xaa, 0xdc, 0xbb, 0x7a, 0x8a, + 0xda, 0x9a, 0x0c, 0xd4, 0xc9, 0x01, 0x52, 0x75, 0xaa, 0xce, 0x11, 0xc2, 0x3c, 0xa5, 0xc9, 0xef, + 0xbd, 0xd3, 0xae, 0x08, 0xac, 0x6f, 0x6a, 0x5e, 0x25, 0x5e, 0x6e, 0x32, 0x5c, 0x1f, 0x10, 0x42, + 0xb6, 0x9d, 0xc6, 0xee, 0x40, 0x8a, 0xed, 0x18, 0xf5, 0xc6, 0xb2, 0xc7, 0xa1, 0x90, 0xc8, 0x7e, + 0x2b, 0x9a, 0xb4, 0x0d, 0x23, 0x92, 0x5c, 0xd1, 0xe1, 0x6a, 0xaf, 0x3a, 0x2c, 0x6f, 0x97, 0xf3, + 0x69, 0x6f, 0xd9, 0x4c, 0xa3, 0x40, 0xfc, 0x4d, 0xbd, 0x72, 0xb1, 0xf1, 0x64, 0x63, 0xcb, 0xe8, + 0x85, 0x7f, 0x18, 0x6e, 0x32, 0x82, 0xa8, 0xcd, 0xe1, 0x80, 0xb8, 0x41, 0x3e, 0xb6, 0x55, 0x7c, + 0x17, 0x3e, 0xaa, 0x54, 0xd1, 0xe1, 0x0a, 0x83, 0x46, 0xd5, 0x2e, 0xff, 0x02, 0xa6, 0x33, 0x80, + 0xc2, 0xa5, 0x67, 0x83, 0x63, 0x5c, 0x22, 0x53, 0x13, 0x7e, 0x58, 0x7a, 0x49, 0xf9, 0xf9, 0x7f, + 0x6c, 0xfb, 0xe0, 0xbc, 0xef, 0x43, 0xd9, 0x1f, 0xb4, 0x83, 0xd7, 0x9f, 0xfd, 0x70, 0xbd, 0x45, + 0x55, 0xd2, 0x82, 0x96, 0x05, 0x95, 0x93, 0xb0, 0xac, 0x90, 0x0f, 0x01, 0x2a, 0x44, 0x12, 0x2a, + 0x7f, 0x1c, 0xe8, 0x0b, 0xc8, 0xc6, 0x1e, 0x82, 0xc0, 0xc6, 0xde, 0x70, 0x70, 0x34, 0x43, 0x96, + 0xa7, 0xcc, 0x8b, 0xb1, 0xc8, 0x0f, 0x81, 0x6c, 0x2c, 0x49, 0x40, 0x02, 0xa5, 0x41, 0x1a, 0xb2, + 0x18, 0xc9, 0xd0, 0x78, 0x2a, 0xa3, 0x51, 0xa3, 0x01, 0x0c, 0xb6, 0xd3, 0xc1, 0xa1, 0x01, 0xf1, + 0xc3, 0x40, 0x1a, 0xae, 0xde, 0x31, 0x02, 0x5b, 0x6d, 0xbf, 0xff, 0x10, 0x0e, 0x06, 0xc7, 0x80, + 0xb0, 0x1e, 0x02, 0xc2, 0x9b, 0xd1, 0x05, 0x4e, 0x43, 0x47, 0x02, 0x51, 0xba, 0x39, 0x2c, 0xb2, + 0xcb, 0x7c, 0x45, 0xc4, 0xa2, 0xb9, 0xd1, 0xc4, 0x55, 0xff, 0xe0, 0xe0, 0x6d, 0x30, 0x01, 0xe2, + 0x53, 0xe1, 0x99, 0x73, 0x9a, 0xb3, 0x89, 0x3f, 0x03, 0x13, 0x5c, 0x14, 0xe5, 0x41, 0x18, 0x25, + 0x73, 0x07, 0x1c, 0x16, 0xf4, 0x89, 0x19, 0x0e, 0x6c, 0x50, 0xb6, 0x1c, 0xfa, 0x19, 0x5f, 0xcd, + 0x51, 0x8e, 0x35, 0x10, 0x08, 0xf1, 0x02, 0x06, 0xed, 0x15, 0x7c, 0xd9, 0xab, 0xca, 0xce, 0x91, + 0x7e, 0x17, 0xc1, 0x14, 0x30, 0x25, 0x21, 0xab, 0x6c, 0x5e, 0x1a, 0x88, 0x22, 0xbc, 0x76, 0xef, + 0xf0, 0x84, 0x29, 0x36, 0x3f, 0x07, 0x85, 0xce, 0x90, 0x4a, 0x02, 0xb9, 0x27, 0x01, 0xaa, 0x61, + 0x79, 0x61, 0xb3, 0xb7, 0x5b, 0xcb, 0x59, 0x66, 0x29, 0xa8, 0x98, 0x80, 0xe4, 0x50, 0xb1, 0x10, + 0xa4, 0xfd, 0x46, 0x19, 0x49, 0x32, 0x55, 0x44, 0x05, 0xcd, 0x28, 0x71, 0x7a, 0xd4, 0x4b, 0x52, + 0xea, 0xa0, 0xea, 0x94, 0x18, 0x4e, 0xa1, 0xcf, 0x9e, 0x70, 0x42, 0x20, 0x6c, 0xd8, 0xe9, 0x54, + 0x0c, 0x9e, 0x47, 0xf8, 0x9b, 0xec, 0x30, 0x61, 0x8f, 0x1e, 0xf3, 0xdb, 0x15, 0x68, 0x6c, 0xb7, + 0x87, 0x8f, 0x07, 0xfa, 0x5b, 0x62, 0x49, 0x4a, 0x1f, 0x63, 0x37, 0x39, 0xf8, 0xc2, 0x15, 0x6f, + 0x70, 0xc0, 0xdd, 0x50, 0xde, 0x84, 0xcf, 0x87, 0xc7, 0x09, 0xc8, 0x28, 0x35, 0x4e, 0x30, 0x07, + 0xfe, 0x14, 0x80, 0x84, 0x08, 0x8a, 0x68, 0xa4, 0xf1, 0x01, 0x60, 0x24, 0x64, 0x93, 0x12, 0x96, + 0xac, 0xb1, 0x2e, 0x50, 0x41, 0x64, 0x68, 0x07, 0x0f, 0x65, 0x10, 0x52, 0x03, 0xa8, 0x5e, 0xe3, + 0x49, 0x95, 0x7f, 0x3b, 0x31, 0x10, 0xa5, 0x88, 0x4a, 0xc0, 0xc0, 0x49, 0x09, 0x88, 0xb6, 0x52, + 0x18, 0xf4, 0x45, 0x25, 0x49, 0xf7, 0x33, 0xc8, 0xf0, 0x17, 0xbd, 0x1b, 0x2b, 0x39, 0x68, 0x09, + 0x25, 0x99, 0x88, 0x10, 0x12, 0xcd, 0x82, 0x38, 0x00, 0x8f, 0x10, 0x0a, 0xe8, 0xce, 0x48, 0x99, + 0xaf, 0x50, 0x51, 0x59, 0x2c, 0xd4, 0x94, 0x2a, 0x50, 0xdd, 0x11, 0x71, 0xfd, 0xd9, 0x08, 0x78, + 0x47, 0x9a, 0xd4, 0x47, 0xca, 0x74, 0xc2, 0x8b, 0x46, 0x0a, 0x03, 0x01, 0x4d, 0x6a, 0x07, 0xe2, + 0x52, 0x63, 0xe8, 0xe0, 0xf6, 0xdc, 0x71, 0x9d, 0x76, 0x7e, 0x52, 0x2a, 0x7e, 0x14, 0x3c, 0x4d, + 0xcd, 0x1a, 0x6d, 0xb8, 0x25, 0xad, 0x84, 0xc7, 0xd1, 0x0d, 0x29, 0x58, 0xd6, 0x5a, 0x07, 0xe3, + 0x54, 0x0e, 0x59, 0x50, 0x1b, 0x9e, 0x24, 0x40, 0x2c, 0xa0, 0x68, 0x70, 0xa3, 0x08, 0x41, 0x3a, + 0xd1, 0xca, 0xf4, 0x22, 0xb8, 0xdf, 0x0f, 0x77, 0xc3, 0x73, 0xf8, 0x38, 0x24, 0xb0, 0x35, 0x55, + 0x38, 0x0d, 0xb8, 0xab, 0xf8, 0xde, 0x2b, 0x19, 0x4f, 0xc1, 0x24, 0xb9, 0xf8, 0xca, 0xa6, 0x96, + 0xef, 0xb2, 0xac, 0xbe, 0xe6, 0xe1, 0x4a, 0x4d, 0x8d, 0x83, 0xc9, 0xc7, 0xb2, 0x94, 0x26, 0x11, + 0xe6, 0xdd, 0x9b, 0xdb, 0x71, 0xe6, 0x23, 0xda, 0xf8, 0x7a, 0x5d, 0x81, 0xba, 0x38, 0x72, 0xbc, + 0x84, 0x9f, 0x19, 0x43, 0x01, 0x6a, 0x35, 0x0d, 0x7f, 0xab, 0x4c, 0x55, 0xbc, 0x61, 0xa5, 0xe2, + 0x6b, 0x4c, 0x2c, 0x16, 0x15, 0x00, 0xd2, 0xd5, 0xad, 0xa3, 0x07, 0xc4, 0x41, 0x61, 0x62, 0x16, + 0x18, 0x9a, 0xc6, 0xab, 0xa8, 0x9d, 0x1c, 0xf8, 0x52, 0x5c, 0x2c, 0x6d, 0xe7, 0x8e, 0x0d, 0xa8, + 0xfb, 0x0b, 0x19, 0x6f, 0x23, 0x67, 0xcd, 0x0a, 0x6f, 0xf1, 0xf1, 0x8f, 0x28, 0xf4, 0x1d, 0xb0, + 0xdf, 0x0d, 0x1b, 0x2a, 0x9b, 0x3c, 0x64, 0xf2, 0xa7, 0x73, 0xe5, 0xa3, 0x4e, 0xf7, 0xbd, 0xfd, + 0xd8, 0x66, 0x54, 0x7f, 0x93, 0x82, 0x32, 0xde, 0xfd, 0xf1, 0xb1, 0x79, 0xb6, 0x68, 0x03, 0xa1, + 0x38, 0x11, 0x46, 0xa2, 0x4b, 0x5b, 0xa2, 0x6a, 0x44, 0xf4, 0xf9, 0x7c, 0xbf, 0xc1, 0xc0, 0x40, + 0x28, 0x4c, 0x95, 0x64, 0xc0, 0x35, 0x0b, 0x09, 0xac, 0xeb, 0x8f, 0x6a, 0x35, 0x42, 0xc0, 0x01, + 0x8b, 0x8b, 0x58, 0x0c, 0x1e, 0xa7, 0xf1, 0x4a, 0x52, 0x26, 0xbd, 0x98, 0xa0, 0x0e, 0x90, 0x8c, + 0xa9, 0x5c, 0x48, 0x31, 0x0a, 0x14, 0x1e, 0x85, 0xa5, 0x86, 0x15, 0x4b, 0x6d, 0x75, 0x21, 0x8d, + 0xd3, 0x63, 0x11, 0xe0, 0x63, 0x1b, 0xc8, 0xd4, 0x52, 0xd5, 0xa4, 0x14, 0x71, 0x83, 0xc6, 0xa9, + 0xc5, 0xbc, 0x48, 0xd1, 0x03, 0x34, 0x32, 0x95, 0xe7, 0x94, 0xc4, 0xd0, 0xb3, 0x04, 0x58, 0x97, + 0xe3, 0x28, 0x0e, 0x5e, 0x2f, 0x2c, 0x8f, 0xd4, 0xed, 0xbd, 0xe4, 0x62, 0x31, 0x7e, 0x89, 0x7a, + 0x32, 0xa8, 0xf0, 0x80, 0x91, 0xb2, 0xa4, 0x2a, 0x16, 0x32, 0xb0, 0x8c, 0x35, 0xa4, 0x4d, 0xab, + 0xf3, 0xa6, 0x3d, 0x50, 0xde, 0x3d, 0x64, 0x92, 0x03, 0xd1, 0x49, 0x45, 0x19, 0x00, 0xfb, 0x6a, + 0x8b, 0x20, 0x5c, 0x68, 0xc3, 0x64, 0x79, 0xff, 0x64, 0x39, 0xd8, 0x44, 0x40, 0x52, 0x55, 0x4a, + 0x57, 0x60, 0x9c, 0x03, 0x92, 0x02, 0xb8, 0xee, 0x48, 0x6b, 0x1d, 0x14, 0x24, 0xd0, 0x22, 0xa6, + 0x65, 0x2e, 0x20, 0xc2, 0x52, 0x5a, 0x8f, 0xbc, 0x94, 0xea, 0xf6, 0x25, 0xc4, 0x82, 0x1f, 0x05, + 0x20, 0xb0, 0xae, 0xa9, 0x7e, 0xe5, 0xcc, 0xb4, 0x7a, 0x75, 0x83, 0x10, 0xc8, 0x76, 0x29, 0x24, + 0xd2, 0xc1, 0xa6, 0xbc, 0x43, 0x5a, 0x3c, 0x4e, 0x0f, 0xba, 0x38, 0x58, 0x49, 0xdc, 0x6e, 0x20, + 0xb4, 0x12, 0x1f, 0x29, 0xf8, 0xab, 0x35, 0xbb, 0x94, 0x01, 0xbc, 0x38, 0xff, 0xc3, 0x8a, 0x00, + 0x15, 0x64, 0x8a, 0x90, 0x1e, 0x44, 0xff, 0x82, 0xf2, 0x0d, 0x50, 0xc4, 0x94, 0xb6, 0xc8, 0x3d, + 0xc8, 0xa4, 0xf2, 0x2f, 0x8f, 0x4e, 0x35, 0x91, 0x44, 0x5b, 0x4f, 0xb4, 0xd7, 0x82, 0x10, 0xc8, + 0x8c, 0x06, 0xcd, 0xea, 0x7e, 0x52, 0xbd, 0x7e, 0x08, 0x43, 0x20, 0x96, 0x50, 0xaf, 0x0f, 0x59, + 0xca, 0x05, 0xbc, 0x50, 0x97, 0xbf, 0x39, 0xf0, 0x4b, 0x66, 0x2d, 0x8d, 0x59, 0x97, 0x73, 0x88, + 0x82, 0x09, 0x6d, 0xfc, 0x6b, 0x0a, 0x09, 0x01, 0xb5, 0x43, 0xec, 0xae, 0xc1, 0xd8, 0x16, 0xb3, + 0xa9, 0x17, 0x24, 0x25, 0x2e, 0x0d, 0x3a, 0x96, 0xa4, 0xf4, 0xff, 0x11, 0x08, 0x90, 0x48, 0x38, + 0x1d, 0x01, 0x9d, 0x39, 0xee, 0x26, 0xb3, 0xad, 0x71, 0x02, 0x03, 0xd8, 0x04, 0xba, 0xdf, 0x4a, + 0x9e, 0xb8, 0xd9, 0x83, 0x39, 0x8f, 0x46, 0xda, 0x6c, 0x6b, 0x17, 0xff, 0x0a, 0x09, 0xe8, 0xcf, + 0x02, 0xfe, 0x86, 0x3a, 0x8b, 0x45, 0x63, 0x23, 0xc1, 0x49, 0x2f, 0xf4, 0x27, 0xcd, 0x7d, 0xfc, + 0x59, 0x9d, 0xb1, 0x5d, 0x3a, 0xfc, 0x12, 0xef, 0x7d, 0x23, 0x78, 0x44, 0xbc, 0x69, 0x54, 0xd8, + 0x8e, 0xdd, 0x63, 0x35, 0xf4, 0x5a, 0x45, 0xf0, 0x96, 0xd9, 0x5a, 0x63, 0xa9, 0xd4, 0x8a, 0xb1, + 0x64, 0x9f, 0xae, 0x12, 0x90, 0x30, 0x10, 0xac, 0x62, 0x62, 0x30, 0x8d, 0x86, 0xbe, 0x3c, 0xdd, + 0x36, 0xe6, 0x0c, 0x1b, 0xbe, 0xcb, 0xc2, 0x5b, 0xcb, 0xe7, 0xc3, 0xff, 0xc4, 0x15, 0xb3, 0xba, + 0x03, 0xa7, 0x71, 0x11, 0x25, 0x5e, 0x32, 0xcd, 0xb7, 0x0e, 0xb4, 0x9a, 0x64, 0xd3, 0x3f, 0x92, + 0x04, 0xb2, 0x65, 0x4c, 0xaf, 0x8a, 0xe3, 0xd9, 0x32, 0x1b, 0x36, 0x6d, 0x78, 0xea, 0x37, 0xe9, + 0x0c, 0x69, 0xd4, 0x8c, 0x2e, 0xf9, 0xb3, 0x43, 0x78, 0x44, 0x69, 0x1a, 0xdb, 0x5d, 0x97, 0xc3, + 0x08, 0xd4, 0x78, 0xe7, 0xe1, 0x0a, 0x93, 0xb6, 0x21, 0x35, 0x75, 0xd3, 0x77, 0x1a, 0x39, 0xf9, + 0x37, 0xee, 0x8c, 0x9f, 0x84, 0x46, 0xcd, 0x46, 0xb2, 0xbb, 0xd3, 0x6c, 0xe5, 0x10, 0xe8, 0x58, + 0x0f, 0xd8, 0xb8, 0x35, 0x50, 0x17, 0x45, 0x83, 0x0a, 0x80, 0xe4, 0x4c, 0x00, 0x2a, 0x6e, 0x3a, + 0x59, 0x32, 0x72, 0xa6, 0x3c, 0x18, 0xf0, 0x45, 0x0e, 0x98, 0x54, 0xf3, 0x57, 0x82, 0xff, 0xc1, + 0x80, 0x91, 0xb1, 0x72, 0x25, 0x9b, 0x01, 0xcb, 0x63, 0xc6, 0xc1, 0x20, 0xa9, 0x3a, 0xa7, 0x83, + 0x91, 0xf7, 0xe6, 0xe4, 0xfc, 0x96, 0x29, 0x48, 0xa8, 0x59, 0xe0, 0xe3, 0xf3, 0xc1, 0xc2, 0x03, + 0xe2, 0x61, 0x13, 0xdb, 0x08, 0x27, 0x24, 0xf5, 0x30, 0x63, 0x0e, 0x28, 0x7b, 0x67, 0xba, 0x5e, + 0x42, 0x21, 0x90, 0xb2, 0x2f, 0xc2, 0x85, 0x2c, 0x64, 0x2f, 0xe1, 0x05, 0xaa, 0x2b, 0xae, 0x47, + 0xc2, 0xa6, 0x18, 0xab, 0xec, 0xc2, 0x03, 0x2b, 0xc5, 0x4b, 0x8d, 0x67, 0x4a, 0xeb, 0xec, 0xd5, + 0x27, 0xdc, 0x4c, 0x6e, 0x23, 0x50, 0xed, 0xe3, 0x47, 0x3d, 0x17, 0x74, 0x52, 0xd1, 0x4d, 0xd7, + 0x63, 0xac, 0xb2, 0x41, 0xed, 0x86, 0x12, 0x17, 0x4b, 0x32, 0x61, 0xac, 0x74, 0x4e, 0x53, 0x51, + 0xdb, 0x90, 0xdd, 0x7f, 0xf8, 0xc1, 0x2b, 0x19, 0x6c, 0x04, 0x05, 0xd3, 0x90, 0x84, 0xa0, 0x85, + 0xd5, 0xa1, 0x50, 0x78, 0xd6, 0x80, 0x8d, 0x82, 0x9c, 0x48, 0xf1, 0x15, 0x9b, 0x94, 0x40, 0xbf, + 0x15, 0x8c, 0x3d, 0xc2, 0x03, 0x32, 0x4f, 0xb1, 0x77, 0x6e, 0x76, 0x07, 0xf0, 0x48, 0x22, 0xdd, + 0xb8, 0x3e, 0x6a, 0x7a, 0x6b, 0x89, 0xf2, 0x41, 0xb9, 0x93, 0x3c, 0xc2, 0xdd, 0xeb, 0xe5, 0x18, + 0xfb, 0x7e, 0x4b, 0xbf, 0xee, 0xf3, 0xfb, 0xe7, 0xaf, 0x96, 0x97, 0xae, 0x12, 0x16, 0xc2, 0x15, + 0xbc, 0xfb, 0x5e, 0x22, 0x13, 0x21, 0x73, 0x7d, 0x14, 0x7c, 0x3c, 0x03, 0xe1, 0xd3, 0x13, 0xf1, + 0xed, 0x18, 0x00, 0x03, 0x92, 0x2c, 0x31, 0xe9, 0x7b, 0x2d, 0x7f, 0x6c, 0xbb, 0x88, 0x85, 0x0f, + 0x68, 0x79, 0x68, 0x0c, 0xf9, 0x29, 0x29, 0xa9, 0x47, 0x10, 0x4e, 0xac, 0xbe, 0xa3, 0xdd, 0x68, + 0xf9, 0xda, 0xa2, 0x94, 0x3c, 0x49, 0xde, 0x08, 0x3b, 0x44, 0x52, 0x3b, 0x7f, 0x31, 0x9e, 0xef, + 0xe6, 0x26, 0xcc, 0xdf, 0xc1, 0x1f, 0x54, 0xc5, 0x29, 0xf5, 0xef, 0x97, 0x55, 0xae, 0x30, 0xa9, + 0xa1, 0xdf, 0x8f, 0xa4, 0xc9, 0x3d, 0x96, 0xac, 0x7c, 0x22, 0x30, 0xc3, 0x39, 0x44, 0xfc, 0x7c, + 0x8d, 0xd6, 0x82, 0xaa, 0xe0, 0x40, 0x51, 0x70, 0x09, 0x8e, 0xfe, 0x14, 0x9c, 0x71, 0x35, 0x42, + 0x49, 0x9b, 0x19, 0x38, 0x09, 0x09, 0x4f, 0x8e, 0x61, 0x9f, 0x97, 0x15, 0xe2, 0x86, 0x95, 0x2a, + 0x24, 0x5d, 0xbc, 0x71, 0xdf, 0x8b, 0x87, 0x84, 0x03, 0xd0, 0xc8, 0xca, 0x7d, 0x8f, 0xdd, 0x06, + 0x2e, 0x01, 0x3e, 0x88, 0x39, 0x44, 0x00, 0x35, 0x21, 0x41, 0x08, 0x3f, 0x8a, 0x27, 0x86, 0x50, + 0x27, 0x06, 0x4b, 0x05, 0xbc, 0xbd, 0x44, 0x0c, 0x23, 0xbd, 0x81, 0x20, 0x32, 0x14, 0xbb, 0xab, + 0x42, 0x26, 0x50, 0x85, 0x19, 0x22, 0xb1, 0x78, 0x32, 0x6b, 0xef, 0x7c, 0x0f, 0x06, 0x16, 0x63, + 0x5d, 0x61, 0xa0, 0x74, 0xd5, 0x14, 0x18, 0x33, 0x04, 0x38, 0x71, 0x14, 0x02, 0x10, 0x1a, 0x67, + 0x21, 0x5c, 0x5d, 0x86, 0xc2, 0x4e, 0xaf, 0x24, 0x2a, 0xb6, 0x32, 0xb2, 0x57, 0x0b, 0x95, 0xb1, + 0xac, 0x13, 0xb9, 0xaa, 0xc3, 0x7f, 0x4c, 0xdb, 0xc4, 0x82, 0xcb, 0x41, 0x5e, 0x3e, 0xeb, 0x6f, + 0x0c, 0x74, 0x34, 0xba, 0x72, 0x50, 0xf0, 0x81, 0x1d, 0xaf, 0xc2, 0x42, 0x85, 0x26, 0xc8, 0x62, + 0x81, 0xa4, 0xb1, 0xe9, 0x01, 0xf8, 0x2b, 0x12, 0x9a, 0x7e, 0xa2, 0x79, 0x9b, 0x01, 0x8d, 0xe6, + 0x3e, 0x34, 0xc1, 0x27, 0x69, 0xd8, 0x1b, 0xae, 0xb4, 0x95, 0x0e, 0xdc, 0xbf, 0xaa, 0xbe, 0x3c, + 0xbf, 0xfc, 0x21, 0x2b, 0x5b, 0xb3, 0xaa, 0xad, 0x55, 0x7c, 0xb4, 0x09, 0xe7, 0x15, 0xf0, 0x51, + 0x7b, 0x6a, 0xa6, 0xf5, 0x7f, 0x8f, 0xde, 0xc7, 0x95, 0x84, 0x08, 0xd3, 0xc2, 0xef, 0xb1, 0xb7, + 0x89, 0x85, 0x2b, 0x86, 0x4f, 0xba, 0xea, 0x29, 0xb3, 0x63, 0x9c, 0xfa, 0xaf, 0x16, 0x8f, 0x10, + 0x14, 0xb3, 0x64, 0x1f, 0x31, 0xa6, 0x42, 0x6c, 0xe4, 0x84, 0x6e, 0x60, 0x9e, 0x60, 0xdd, 0xdf, + 0xe8, 0x47, 0x88, 0x23, 0x1a, 0xd2, 0xa6, 0x9d, 0xf2, 0xeb, 0x55, 0xc1, 0x10, 0xd4, 0xab, 0xca, + 0x4e, 0x51, 0x58, 0xec, 0xad, 0xf2, 0x0b, 0xbe, 0xff, 0x1d, 0x26, 0xd7, 0x93, 0xd0, 0x9a, 0x8a, + 0xff, 0x18, 0x51, 0xf5, 0xbd, 0x3b, 0x1d, 0x24, 0x1e, 0x96, 0x3c, 0x3d, 0x28, 0x36, 0xa7, 0xc6, + 0x78, 0x53, 0x5d, 0x99, 0x2b, 0x55, 0xc7, 0x88, 0x35, 0x29, 0xaa, 0xad, 0x56, 0xab, 0xf0, 0x85, + 0x4d, 0x95, 0x66, 0xda, 0xa5, 0x56, 0xd7, 0xd1, 0x7a, 0xf8, 0xd3, 0x4c, 0x85, 0xd7, 0x31, 0x08, + 0x58, 0xf5, 0xfc, 0xf4, 0x61, 0x88, 0x2c, 0x9f, 0xc3, 0xab, 0xa4, 0x5c, 0x9b, 0x33, 0x7d, 0x10, + 0xc6, 0x81, 0x7e, 0xbe, 0x24, 0x40, 0x2c, 0xb1, 0x46, 0xa6, 0x61, 0xd5, 0xd5, 0x77, 0x3f, 0x97, + 0x88, 0x39, 0xd2, 0xbf, 0x4e, 0xb7, 0xe0, 0x58, 0x05, 0x23, 0x60, 0xe9, 0x3c, 0x50, 0x43, 0x18, + 0x34, 0x5e, 0x05, 0xf6, 0x4f, 0xa7, 0x02, 0x90, 0x96, 0xae, 0x78, 0xc1, 0xde, 0x4a, 0xc9, 0x01, + 0xc1, 0x16, 0x97, 0xac, 0xe0, 0x05, 0x87, 0x80, 0x68, 0x3a, 0x3e, 0x4c, 0x9b, 0x00, 0xb3, 0x50, + 0x0c, 0x27, 0xc1, 0xa9, 0x00, 0x0e, 0xbf, 0xcf, 0x55, 0x52, 0xc2, 0x1d, 0x50, 0x3c, 0x57, 0x38, + 0x12, 0x92, 0x25, 0x2c, 0xc6, 0x1b, 0xce, 0x9e, 0x65, 0x66, 0x12, 0xb8, 0xc7, 0x53, 0xf0, 0x88, + 0x6b, 0x35, 0xc1, 0xc5, 0x72, 0xc0, 0x17, 0xe5, 0x41, 0x9c, 0x9c, 0x7e, 0x7f, 0x8e, 0xe6, 0xa8, + 0x03, 0x73, 0x27, 0xad, 0x97, 0x2c, 0x32, 0x2e, 0x84, 0x02, 0xd6, 0xc1, 0x7c, 0x32, 0x6e, 0x08, + 0x11, 0xfd, 0x95, 0x54, 0x6e, 0xde, 0x2e, 0x6d, 0x10, 0xdb, 0x80, 0x2a, 0x4a, 0xf1, 0x87, 0xbe, + 0xbd, 0xa6, 0x51, 0xc3, 0x03, 0xcd, 0x0a, 0x2f, 0x05, 0x50, 0xb0, 0x5a, 0x17, 0x9e, 0x3d, 0xdd, + 0x0e, 0x15, 0xc6, 0x56, 0x57, 0x8e, 0x92, 0x1b, 0xfc, 0x1b, 0x83, 0x55, 0x38, 0xfa, 0x36, 0x9e, + 0xe0, 0xec, 0x82, 0x13, 0xa8, 0xd4, 0x3c, 0x68, 0xf9, 0xa9, 0x5b, 0x1c, 0x3a, 0xa0, 0x00, 0x70, + 0xd6, 0x7c, 0x40, 0xb2, 0x95, 0x2b, 0xfb, 0x5c, 0xdf, 0x48, 0x1f, 0x1a, 0x80, 0x31, 0x5b, 0x57, + 0xf4, 0x84, 0x6a, 0x01, 0xf3, 0xd0, 0xe3, 0x0a, 0x47, 0x18, 0x16, 0x91, 0x21, 0xc0, 0x1e, 0x6b, + 0xc0, 0x75, 0x13, 0x1e, 0xff, 0xc2, 0x84, 0x25, 0xa9, 0x5a, 0x65, 0xe3, 0xcb, 0x22, 0x22, 0x44, + 0x7a, 0x24, 0x34, 0xe1, 0x85, 0xf8, 0x9d, 0x78, 0xcf, 0x33, 0xe3, 0x05, 0x46, 0x4e, 0xf1, 0x01, + 0x02, 0x81, 0xf1, 0x29, 0x4d, 0x99, 0xfc, 0x83, 0xe8, 0x27, 0xff, 0x15, 0x39, 0xaa, 0xf8, 0x93, + 0x2a, 0x25, 0x60, 0xcd, 0x99, 0xd8, 0x13, 0xf8, 0x44, 0xaa, 0x5e, 0x67, 0x3a, 0x34, 0x06, 0x36, + 0x20, 0x8a, 0x0b, 0x0e, 0x8e, 0xa2, 0xff, 0x08, 0xf9, 0x75, 0xa7, 0x6e, 0x73, 0xea, 0x37, 0xad, + 0xe1, 0x4b, 0x4a, 0xd2, 0x13, 0x26, 0x15, 0xb3, 0x88, 0x3d, 0x51, 0x68, 0x53, 0xce, 0x31, 0xa1, + 0x45, 0xd2, 0xdc, 0x10, 0x05, 0x5b, 0xe7, 0x52, 0x1c, 0x6d, 0x13, 0x33, 0xe3, 0x68, 0x9c, 0x77, + 0x33, 0x8e, 0xfc, 0x11, 0x83, 0x49, 0xc1, 0xac, 0x19, 0xa2, 0x0e, 0x75, 0xde, 0x3a, 0x34, 0x0b, + 0x4b, 0x57, 0x95, 0x5f, 0xf8, 0x70, 0xb1, 0x94, 0x2f, 0x95, 0x99, 0xf6, 0x97, 0xeb, 0x84, 0x79, + 0xa5, 0x5d, 0x8c, 0xbf, 0xa4, 0x33, 0x98, 0x91, 0x7d, 0x71, 0x1b, 0x6f, 0x5a, 0xfc, 0x56, 0xf7, + 0xdd, 0xdf, 0x74, 0xeb, 0xf1, 0x39, 0x75, 0x3d, 0x77, 0xf3, 0x0b, 0xd3, 0x48, 0xfc, 0x96, 0x8c, + 0x92, 0x86, 0xb9, 0x2d, 0x5e, 0x4e, 0x09, 0x26, 0xdf, 0xdf, 0x10, 0x32, 0x4c, 0xe2, 0xd2, 0xf7, + 0x5a, 0x5f, 0x09, 0xf7, 0x7b, 0xbf, 0xc5, 0x93, 0x15, 0xf9, 0x73, 0x88, 0x47, 0x6e, 0x24, 0x48, + 0x25, 0x8c, 0x5a, 0xcc, 0xc3, 0x8c, 0xb1, 0x6d, 0x7b, 0x61, 0xcd, 0x2e, 0x73, 0xc4, 0x02, 0xeb, + 0x9b, 0x8b, 0xc9, 0x87, 0x5f, 0xc3, 0x53, 0xa7, 0x1a, 0x38, 0x23, 0xc5, 0x18, 0x00, 0x7f, 0x7e, + 0x00, 0x5c, 0x1b, 0xfb, 0xc1, 0xbf, 0xbe, 0x04, 0x00, 0x62, 0x36, 0xe0, 0x00, 0x36, 0x85, 0x03, + 0x52, 0x90, 0x23, 0x3d, 0xd3, 0x97, 0x8d, 0x4c, 0xf0, 0x1c, 0x41, 0x19, 0x45, 0x47, 0x4a, 0xb2, + 0xed, 0xc6, 0x05, 0x9c, 0x24, 0x8b, 0xb1, 0x60, 0x23, 0xac, 0x16, 0xb8, 0x62, 0xa6, 0x17, 0x86, + 0xa3, 0xa0, 0x04, 0xc1, 0x4e, 0xfc, 0xa5, 0x7d, 0x61, 0xae, 0xfa, 0x60, 0x49, 0x02, 0xc0, 0xd9, + 0x13, 0x0d, 0x76, 0x93, 0x2f, 0xf4, 0x8e, 0xb0, 0x16, 0x52, 0x82, 0xa1, 0x12, 0x5b, 0xad, 0x8c, + 0xec, 0xc3, 0xf9, 0x68, 0xca, 0x3d, 0x0b, 0x47, 0x69, 0x8a, 0xa4, 0xaa, 0x4c, 0x64, 0x42, 0xca, + 0x24, 0xf3, 0xbe, 0x4e, 0xc1, 0x5c, 0xda, 0xff, 0x05, 0x44, 0x66, 0x01, 0x64, 0x14, 0x28, 0x55, + 0x03, 0xc0, 0x17, 0xd1, 0x8f, 0x89, 0xb0, 0xa5, 0xe9, 0x0b, 0x8b, 0xd0, 0x3b, 0xfc, 0x66, 0xd8, + 0xb9, 0xbf, 0x2b, 0x11, 0xf2, 0xa1, 0x58, 0xa1, 0x8c, 0xcc, 0x52, 0xd7, 0x1b, 0x59, 0x50, 0xb8, + 0x57, 0x67, 0x9b, 0x9e, 0x07, 0xa9, 0x66, 0x70, 0x07, 0x89, 0x38, 0x58, 0x19, 0x61, 0xb7, 0xdd, + 0x9d, 0x7c, 0x24, 0x74, 0xc9, 0x80, 0x70, 0x5e, 0x78, 0x39, 0x8a, 0x6b, 0xe2, 0x67, 0x8f, 0x96, + 0xef, 0x5f, 0x82, 0x8f, 0x3d, 0xb0, 0x23, 0x04, 0x01, 0xae, 0x72, 0xf8, 0xcd, 0x76, 0x4d, 0x96, + 0x6a, 0x41, 0x62, 0xb4, 0x01, 0x69, 0x51, 0x66, 0x0f, 0x88, 0x0b, 0x8e, 0xae, 0xca, 0x78, 0x03, + 0x34, 0x16, 0xb7, 0xf8, 0xea, 0x99, 0x7f, 0x51, 0xe2, 0x66, 0x08, 0xb5, 0xc1, 0xa0, 0x6e, 0x3a, + 0xa4, 0x17, 0xff, 0x04, 0x25, 0x2b, 0x2b, 0xfa, 0x3b, 0x8a, 0x26, 0xa9, 0x9a, 0x1a, 0x52, 0xf2, + 0x52, 0x96, 0xb5, 0xc5, 0x1e, 0x9d, 0xdb, 0xb6, 0xd3, 0xe4, 0xe9, 0xa4, 0x33, 0x9a, 0x95, 0xd0, + 0x3f, 0x10, 0x2a, 0xf7, 0xbb, 0xa1, 0x97, 0x9a, 0x36, 0xbf, 0x5c, 0xd9, 0x7c, 0xbf, 0xc2, 0x85, + 0x0f, 0xc3, 0x78, 0xd2, 0x25, 0x06, 0x47, 0xf3, 0x40, 0xe3, 0x91, 0xe5, 0x8d, 0xf0, 0x2c, 0x64, + 0xed, 0x35, 0x77, 0x2f, 0x7f, 0x82, 0x5b, 0x33, 0x55, 0xc9, 0x0c, 0x9b, 0xe2, 0x6b, 0xab, 0xdf, + 0xe4, 0x8b, 0x88, 0xe7, 0xe0, 0xa6, 0xcf, 0x2b, 0x27, 0x46, 0xb4, 0xd2, 0x55, 0xd7, 0xc1, 0x54, + 0xe6, 0x46, 0x47, 0xa3, 0x0a, 0x2c, 0xa6, 0x27, 0x25, 0x5b, 0x1b, 0x6c, 0x9d, 0xdf, 0x19, 0xb0, + 0x67, 0x31, 0xbb, 0x10, 0xd4, 0x6d, 0xd0, 0x30, 0x08, 0x3d, 0x51, 0xd3, 0xe4, 0x7d, 0x1f, 0x41, + 0xb0, 0x66, 0xa7, 0xe4, 0xac, 0xfe, 0xea, 0xef, 0xfc, 0x23, 0xca, 0x55, 0x7f, 0xc9, 0x99, 0x47, + 0xe2, 0xcc, 0x84, 0xee, 0xdc, 0x9d, 0x67, 0xc8, 0x74, 0xea, 0xd2, 0xe2, 0x0d, 0x69, 0x24, 0xaa, + 0x93, 0x17, 0x96, 0xba, 0xae, 0x09, 0x2f, 0x7d, 0xfe, 0x22, 0xf3, 0xcb, 0x8d, 0x2d, 0x64, 0xe4, + 0x3d, 0x3a, 0x89, 0xe2, 0xc4, 0x73, 0x66, 0x6c, 0xf9, 0x32, 0x5d, 0xfc, 0x87, 0x55, 0x55, 0x5c, + 0x13, 0x91, 0x57, 0xaa, 0x5e, 0xf8, 0x2f, 0xea, 0x6c, 0x17, 0x55, 0xb7, 0xdb, 0x54, 0xfe, 0x18, + 0x99, 0x10, 0xe0, 0xc3, 0xde, 0x9c, 0xe7, 0x54, 0x33, 0x48, 0xe9, 0xbf, 0xf1, 0x03, 0x22, 0xba, + 0xdc, 0xdc, 0xbe, 0x5f, 0x10, 0x3c, 0x76, 0xe5, 0x8c, 0xb5, 0x96, 0x71, 0x4d, 0x7d, 0x9d, 0x72, + 0x67, 0x82, 0xd2, 0x27, 0x9c, 0x9d, 0xbb, 0x59, 0x7c, 0x49, 0x54, 0xab, 0x43, 0xd5, 0x0f, 0xf1, + 0x02, 0x07, 0x23, 0x3f, 0x64, 0xd8, 0x72, 0x1e, 0xc7, 0xc1, 0x51, 0x14, 0xd8, 0xed, 0x65, 0x19, + 0x4a, 0xa1, 0xa3, 0x92, 0x35, 0x71, 0xec, 0x49, 0xd2, 0xba, 0x94, 0x0b, 0xf0, 0x91, 0x50, 0x8b, + 0x19, 0x50, 0xd0, 0x21, 0xc7, 0x4f, 0xe1, 0x33, 0x49, 0x4d, 0x8d, 0x70, 0xaf, 0x1b, 0xe5, 0xef, + 0xba, 0x76, 0x9d, 0xdf, 0x73, 0xea, 0xeb, 0xf1, 0x02, 0x5e, 0xf7, 0x5f, 0xd8, 0xa9, 0x37, 0x27, + 0x13, 0xd3, 0x15, 0xa7, 0x4d, 0x3f, 0x28, 0xfd, 0x25, 0x5c, 0x12, 0x6f, 0x4f, 0xd3, 0x77, 0x77, + 0xdf, 0x09, 0x8e, 0x59, 0x55, 0x54, 0xb3, 0xf1, 0xd1, 0x59, 0xbb, 0x54, 0x99, 0xe3, 0x75, 0xef, + 0x3e, 0x3f, 0x84, 0x0e, 0x88, 0xed, 0xf2, 0x06, 0x09, 0x75, 0x8d, 0xa6, 0xb3, 0x05, 0xe0, 0xa8, + 0x42, 0xd4, 0xdf, 0x53, 0x51, 0x75, 0x96, 0xf8, 0x22, 0xe5, 0x8c, 0xf9, 0xf1, 0x32, 0xb3, 0xa3, + 0x98, 0xd3, 0xfe, 0x08, 0xb6, 0xd1, 0x34, 0x93, 0xe2, 0x0e, 0xda, 0xe6, 0xcd, 0x07, 0xe1, 0x22, + 0x10, 0xfd, 0x15, 0x8e, 0x72, 0x11, 0xd9, 0xaf, 0x35, 0x26, 0x96, 0x12, 0xe5, 0x13, 0xc9, 0xd7, + 0x1d, 0xdb, 0x5d, 0x33, 0x65, 0x2a, 0x4f, 0xa2, 0x7b, 0xe5, 0xab, 0x5a, 0xe0, 0x84, 0x89, 0xef, + 0x3f, 0xc9, 0x3f, 0xe4, 0xe6, 0x12, 0x9d, 0x34, 0x9f, 0x29, 0xde, 0xf2, 0xf0, 0x8e, 0x7d, 0x7e, + 0x6e, 0xf5, 0xd4, 0x6c, 0xb6, 0x23, 0xb1, 0xce, 0xa9, 0x7f, 0x8a, 0xa5, 0x49, 0x66, 0x45, 0x6f, + 0xc3, 0x58, 0xc4, 0x49, 0x19, 0xa3, 0x5b, 0x66, 0xa7, 0xfe, 0x10, 0xed, 0x91, 0xad, 0x04, 0x27, + 0x04, 0x01, 0x68, 0x20, 0xd1, 0x63, 0x65, 0x3f, 0xc7, 0x9e, 0xaf, 0xd0, 0xdd, 0xf4, 0xbc, 0x18, + 0x08, 0x90, 0x7c, 0xa0, 0xc8, 0x08, 0xe9, 0x25, 0xf5, 0x59, 0x21, 0xff, 0x24, 0x8d, 0x4f, 0xf0, + 0xf1, 0x79, 0xa2, 0x62, 0x0e, 0x89, 0x8e, 0x99, 0x58, 0xa1, 0xac, 0x63, 0x44, 0x50, 0x7e, 0x12, + 0xe0, 0x8c, 0xad, 0xa7, 0x56, 0x9b, 0x98, 0x8b, 0x59, 0xb8, 0x2c, 0xe9, 0x97, 0x12, 0x4e, 0x5e, + 0x5c, 0xcb, 0x6f, 0xa8, 0xde, 0x41, 0x2b, 0x59, 0xb8, 0x50, 0x43, 0x06, 0x64, 0xda, 0xc3, 0xcd, + 0x63, 0xb6, 0x9d, 0x10, 0xf2, 0x5f, 0xd1, 0x5e, 0xca, 0xec, 0xeb, 0x46, 0x7e, 0xb9, 0x89, 0x99, + 0x43, 0x20, 0x9f, 0x35, 0x2d, 0x57, 0x7b, 0xbc, 0xbc, 0x15, 0x69, 0x5b, 0x45, 0x9b, 0x56, 0x32, + 0xec, 0x53, 0xa5, 0xe2, 0x04, 0xbd, 0xd5, 0xb6, 0xbf, 0x2e, 0xaf, 0x1b, 0xd8, 0x87, 0xbf, 0xd9, + 0x2e, 0x97, 0xc7, 0x9d, 0xbb, 0x74, 0x34, 0x36, 0xce, 0xa2, 0x65, 0xcf, 0x8f, 0xcf, 0x29, 0x5f, + 0x77, 0xc1, 0x15, 0xef, 0x7f, 0x87, 0xef, 0xa5, 0x52, 0xa5, 0x93, 0xb2, 0xbb, 0x25, 0xb3, 0x75, + 0xf5, 0xd0, 0xac, 0xbe, 0x24, 0xab, 0xa1, 0xde, 0x86, 0x4e, 0xef, 0xb8, 0xee, 0x43, 0xc5, 0xd4, + 0x99, 0xec, 0xcb, 0xd7, 0xc9, 0x7a, 0x1c, 0xdc, 0x16, 0x55, 0x56, 0xb5, 0x24, 0x15, 0x39, 0xb0, + 0x09, 0xf2, 0x95, 0xf7, 0xf7, 0xdb, 0x6f, 0xc4, 0x6e, 0xfb, 0xa5, 0x3f, 0x17, 0x19, 0xa5, 0xdb, + 0xc8, 0xa9, 0x0f, 0xf0, 0x59, 0x2a, 0x24, 0x18, 0xf1, 0xb7, 0xa2, 0x76, 0xd5, 0x26, 0xde, 0x95, + 0x44, 0x70, 0x9e, 0xf7, 0xbc, 0xc8, 0x02, 0x9d, 0x5a, 0x5e, 0x4a, 0x72, 0xa2, 0xf8, 0x2a, 0x95, + 0x86, 0xad, 0xe5, 0xfc, 0xfd, 0x87, 0x51, 0x9c, 0xbb, 0xbc, 0x5f, 0x08, 0x4f, 0x0d, 0x87, 0x45, + 0x3a, 0x9e, 0x34, 0x98, 0xf0, 0x5b, 0x9d, 0x0a, 0xc4, 0x87, 0xa9, 0x5d, 0x37, 0x15, 0x7b, 0xa2, + 0x94, 0x31, 0xb8, 0x9e, 0x2f, 0xca, 0xc6, 0x3c, 0x65, 0xf8, 0x5a, 0xca, 0x86, 0xe4, 0x43, 0x0b, + 0x54, 0x4a, 0x89, 0x7c, 0xbc, 0x25, 0xe7, 0x60, 0xe8, 0xa8, 0x6c, 0xbc, 0x23, 0xe4, 0xc2, 0x32, + 0x6f, 0x49, 0x8e, 0xf7, 0xc1, 0x1d, 0x15, 0xf2, 0xae, 0x4e, 0xec, 0x62, 0x38, 0xee, 0xe9, 0x52, + 0x34, 0x20, 0xd0, 0xd1, 0x1f, 0x71, 0x1c, 0x10, 0xda, 0x6e, 0x93, 0x9f, 0x08, 0x52, 0xa7, 0xa4, + 0xec, 0x98, 0xe7, 0x63, 0xe0, 0xa3, 0xa1, 0x9e, 0x57, 0x76, 0x9c, 0x93, 0x97, 0x77, 0x89, 0xec, + 0xce, 0xc9, 0xa8, 0x1c, 0x20, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x4f, 0x27, 0xb0, 0x6a, 0x5c, + 0x84, 0x4d, 0xef, 0xe0, 0x98, 0x9b, 0xbd, 0xb7, 0x79, 0xeb, 0x82, 0xaa, 0x5b, 0x68, 0xa2, 0xf9, + 0x59, 0x59, 0xf1, 0xf0, 0x86, 0x9d, 0xda, 0xa6, 0xef, 0x6f, 0xe8, 0x6b, 0x57, 0x09, 0x8a, 0x55, + 0xf4, 0xdf, 0xc2, 0x5d, 0x57, 0x77, 0xf2, 0xdf, 0x75, 0xc9, 0x7b, 0xfd, 0x89, 0x7b, 0xfc, 0x61, + 0xaa, 0xb1, 0xe3, 0x58, 0xea, 0x37, 0x64, 0x8a, 0x5d, 0x65, 0x4d, 0xcf, 0xa5, 0xe0, 0x9f, 0x56, + 0xe9, 0xaa, 0x77, 0x4d, 0xd0, 0xf7, 0x93, 0xaf, 0x7d, 0x7a, 0xfa, 0xb4, 0x21, 0xc1, 0x20, 0xc4, + 0x33, 0x35, 0x17, 0xdf, 0x67, 0x6d, 0xaf, 0xc1, 0x70, 0xab, 0x49, 0x2b, 0x06, 0x62, 0x64, 0x63, + 0xcb, 0xe0, 0x9b, 0x5b, 0x45, 0x66, 0x8d, 0xbb, 0x7d, 0x05, 0x5f, 0xea, 0xff, 0x5e, 0x3b, 0xe2, + 0x54, 0x76, 0xc2, 0x1f, 0x91, 0x26, 0x9a, 0x69, 0xff, 0xb0, 0xa2, 0xaf, 0xe2, 0x2e, 0xf7, 0x97, + 0xbc, 0x7e, 0x09, 0x8a, 0xf2, 0x0d, 0xd6, 0xed, 0xb6, 0xd0, 0xf9, 0x9d, 0x7d, 0xef, 0x7f, 0x04, + 0xfe, 0x46, 0x1b, 0xcd, 0x97, 0x7c, 0x12, 0x91, 0x5f, 0x97, 0xf7, 0xae, 0x6e, 0xac, 0x9f, 0x05, + 0xc7, 0x49, 0x3f, 0x9d, 0xef, 0xf0, 0xa1, 0x29, 0x39, 0x57, 0x9a, 0x68, 0x6f, 0x0c, 0x04, 0x65, + 0x14, 0xbb, 0x7b, 0x0d, 0xe8, 0x68, 0xab, 0x1a, 0x1d, 0x23, 0xd5, 0x79, 0x77, 0xc6, 0x50, 0x92, + 0xc3, 0xcc, 0x7f, 0x18, 0x1f, 0xab, 0xcb, 0x0f, 0x69, 0x51, 0x39, 0xab, 0x08, 0x44, 0x21, 0x2c, + 0xb1, 0x25, 0x42, 0x47, 0x03, 0x84, 0xdf, 0x7f, 0x9f, 0x17, 0xa3, 0x1d, 0x18, 0x9f, 0x2e, 0xa5, + 0x63, 0xc2, 0x85, 0x4d, 0xf5, 0x22, 0x9a, 0xe8, 0x90, 0xe4, 0x7a, 0xb3, 0x44, 0x03, 0xa1, 0xa1, + 0xa0, 0xac, 0xe9, 0x3c, 0xc7, 0xc2, 0x90, 0xf7, 0x45, 0xe7, 0x9b, 0x6c, 0xe0, 0xcc, 0x69, 0x04, + 0xfa, 0x0d, 0xf9, 0xf1, 0x81, 0xbe, 0x0c, 0x67, 0x9c, 0xf8, 0x43, 0xcc, 0xc0, 0xd4, 0x4b, 0xa2, + 0xcc, 0xbb, 0x63, 0x73, 0xb6, 0x23, 0xa1, 0x6f, 0x7d, 0x5b, 0xe8, 0x95, 0xf5, 0x78, 0x43, 0x8d, + 0x21, 0x3c, 0x90, 0x2d, 0x8c, 0x46, 0x2e, 0xf7, 0x36, 0xad, 0x66, 0xa5, 0x4d, 0xe9, 0xff, 0xc4, + 0x75, 0x6e, 0x9e, 0xfe, 0x0a, 0xc9, 0x43, 0x4d, 0x19, 0x7b, 0xe0, 0xd4, 0x19, 0x1a, 0x87, 0x06, + 0x86, 0xdf, 0x04, 0xc4, 0x63, 0xbf, 0x3b, 0x17, 0x78, 0x94, 0x17, 0x7f, 0xaa, 0x3b, 0xf5, 0x6f, + 0xab, 0x61, 0xc2, 0x48, 0x41, 0x4d, 0x3d, 0x34, 0xf4, 0xd3, 0xd3, 0x4f, 0x1c, 0x77, 0xf6, 0xdb, + 0x11, 0xc1, 0x40, 0x72, 0xaa, 0xab, 0x55, 0x6f, 0x82, 0x8d, 0x57, 0x4d, 0x6e, 0x7c, 0xb5, 0xaf, + 0xc5, 0x1d, 0x3c, 0xa9, 0x1b, 0x89, 0x61, 0x36, 0xf8, 0x48, 0xd4, 0x54, 0xf3, 0x46, 0xc6, 0xc6, + 0x48, 0xa4, 0xbf, 0xf1, 0x01, 0x42, 0x93, 0x0d, 0x1c, 0xa2, 0x42, 0xd6, 0xd3, 0x9a, 0xd3, 0x1f, + 0x31, 0x02, 0xcf, 0xad, 0xa9, 0xd4, 0x8c, 0xf3, 0x0f, 0x1f, 0xd3, 0x55, 0x3d, 0x31, 0x40, 0xc3, + 0x36, 0xcf, 0x1c, 0x33, 0xec, 0xe5, 0xac, 0x78, 0xea, 0x7e, 0x8a, 0x2d, 0x14, 0x73, 0xa3, 0xe7, + 0x3f, 0x05, 0x3c, 0xd0, 0xa4, 0xe3, 0x1d, 0x9e, 0x3b, 0xaa, 0x45, 0xe2, 0x08, 0x9b, 0x26, 0x43, + 0xda, 0x5f, 0x84, 0x3b, 0xb3, 0xda, 0x2c, 0x1d, 0xb3, 0x94, 0x8f, 0xeb, 0x94, 0x22, 0xb1, 0x79, + 0xba, 0x2b, 0xc9, 0xd5, 0xe1, 0x4e, 0xb6, 0x3e, 0xb9, 0xab, 0xab, 0xfd, 0x48, 0x95, 0xcc, 0x1c, + 0x55, 0xcf, 0xd8, 0xf2, 0x61, 0x33, 0x51, 0x31, 0x42, 0x97, 0x93, 0xac, 0xaa, 0xe2, 0x63, 0x0a, + 0x8f, 0x00, 0xd8, 0x92, 0x46, 0x73, 0xf9, 0xb2, 0xee, 0xf8, 0x98, 0xae, 0xe9, 0x71, 0xb4, 0x1e, + 0x5d, 0xdb, 0xff, 0x09, 0xc6, 0x97, 0x9e, 0x18, 0xf7, 0xe5, 0x16, 0xf5, 0xe2, 0x66, 0xd6, 0x6a, + 0x78, 0x48, 0x53, 0x92, 0x2d, 0x1d, 0xdf, 0x52, 0x62, 0x45, 0x8f, 0x77, 0xf7, 0x50, 0x47, 0xca, + 0x14, 0x7b, 0xfc, 0xa2, 0x57, 0x53, 0xc4, 0x48, 0x66, 0x4d, 0xcf, 0xf1, 0x14, 0x7e, 0xac, 0x49, + 0x76, 0xa9, 0x7b, 0x27, 0x2e, 0x78, 0xbc, 0xe4, 0x1b, 0xbd, 0xef, 0x9a, 0x4c, 0xbf, 0xcc, 0x6b, + 0x53, 0x7c, 0x4c, 0x11, 0xcd, 0x93, 0xf4, 0x57, 0xf1, 0x30, 0x47, 0xc3, 0x22, 0xe3, 0xab, 0xd7, + 0xc9, 0xd3, 0xfc, 0xb7, 0xd4, 0x67, 0x64, 0xbb, 0x4d, 0x2e, 0x2e, 0x33, 0x4f, 0x97, 0x21, 0x65, + 0x49, 0x9d, 0x3c, 0xa7, 0xdb, 0x85, 0xce, 0x24, 0x11, 0x1e, 0x7a, 0x6f, 0xf3, 0x0c, 0x46, 0x27, + 0x86, 0xa1, 0xd2, 0x0f, 0x94, 0x86, 0x31, 0x4e, 0x7e, 0x83, 0x7d, 0x1b, 0xca, 0x14, 0xd5, 0x7c, + 0x31, 0x6e, 0x35, 0xe1, 0x46, 0xfb, 0x2a, 0x96, 0x43, 0xfe, 0xbf, 0xc7, 0xbb, 0x84, 0x46, 0x1d, + 0xdd, 0xd5, 0x11, 0xf6, 0x0f, 0xb1, 0xa9, 0x50, 0xff, 0x37, 0x15, 0x6a, 0xc5, 0x10, 0xfe, 0x82, + 0x7d, 0x5c, 0x78, 0x58, 0xfd, 0xd7, 0xa5, 0x66, 0x64, 0xf8, 0x7a, 0x69, 0xd3, 0xf8, 0x2e, 0xb5, + 0x69, 0x8f, 0x53, 0x64, 0x0c, 0x3e, 0x52, 0xdb, 0x36, 0x7e, 0x28, 0xcc, 0x72, 0x46, 0x9b, 0xdf, + 0xc1, 0x35, 0xef, 0x71, 0x59, 0xf2, 0xb9, 0xfe, 0x5d, 0xde, 0xb9, 0x6d, 0x19, 0x20, 0xc9, 0x9c, + 0xf8, 0x28, 0x9b, 0x0d, 0xab, 0x29, 0xbd, 0xd9, 0xf0, 0xad, 0xe7, 0x83, 0xcf, 0x16, 0xb5, 0xf7, + 0xcb, 0xfc, 0x61, 0x4b, 0x91, 0xa1, 0xcb, 0x52, 0x8c, 0x82, 0x1d, 0x95, 0x0a, 0x6a, 0x30, 0x30, + 0x55, 0x93, 0xc4, 0x61, 0x78, 0xca, 0xe0, 0x42, 0x57, 0x02, 0x37, 0x53, 0x0f, 0xc2, 0x62, 0x43, + 0x3e, 0x83, 0x59, 0x89, 0x58, 0x5f, 0x8d, 0x8e, 0x27, 0xe9, 0x69, 0xb7, 0xe3, 0x1b, 0x16, 0x76, + 0x16, 0x53, 0xa0, 0xd8, 0x4d, 0xe4, 0x95, 0x64, 0xf5, 0x9f, 0xdf, 0xc1, 0x55, 0x0f, 0x04, 0xed, + 0xb5, 0x24, 0xb7, 0x77, 0x3e, 0x10, 0x34, 0x65, 0x8a, 0x03, 0xd0, 0xe5, 0xc4, 0x16, 0x63, 0x84, + 0x51, 0xe1, 0x4b, 0x44, 0x3e, 0x39, 0x26, 0x68, 0x69, 0xab, 0x35, 0x84, 0xca, 0xd5, 0x92, 0x57, + 0xf8, 0x50, 0xab, 0x4a, 0x95, 0x0c, 0x8d, 0x63, 0x68, 0x86, 0x2f, 0x29, 0x55, 0x54, 0x5e, 0x78, + 0xc2, 0x36, 0xde, 0xb1, 0x5e, 0x87, 0xab, 0x1c, 0x98, 0x87, 0x88, 0x88, 0xe7, 0x54, 0xcf, 0x14, + 0x61, 0xd6, 0x24, 0xf7, 0x82, 0x18, 0x89, 0x06, 0xf6, 0x51, 0x84, 0x3e, 0x92, 0x6a, 0x4c, 0x9c, + 0x48, 0x81, 0x11, 0x96, 0x84, 0x03, 0x8c, 0xf8, 0x68, 0x46, 0x97, 0xf8, 0x84, 0x19, 0x7a, 0x0c, + 0x63, 0x87, 0x1f, 0xfe, 0x53, 0x5a, 0x09, 0x2e, 0xc5, 0xa8, 0x4a, 0x7e, 0x77, 0xd1, 0x4e, 0xbf, + 0xab, 0xd7, 0x42, 0x3b, 0xe7, 0x33, 0x9b, 0xa6, 0x9f, 0xf8, 0xe2, 0xa7, 0x4e, 0x92, 0x59, 0xab, + 0x6b, 0xe4, 0x08, 0x33, 0x34, 0x7f, 0x05, 0xbd, 0xb7, 0xcd, 0x16, 0xdc, 0xf8, 0x20, 0x99, 0xf9, + 0xd4, 0xa4, 0x5d, 0xb6, 0x64, 0x23, 0x1a, 0xa9, 0x20, 0x6b, 0x66, 0xe5, 0x84, 0xfb, 0x48, 0x44, + 0xcc, 0x53, 0x6c, 0xfd, 0x94, 0xb5, 0x07, 0x17, 0xf0, 0x60, 0x18, 0x0a, 0x18, 0x18, 0x80, 0x04, + 0xa3, 0x64, 0x00, 0x21, 0x95, 0x25, 0x95, 0x43, 0x10, 0xf3, 0xaa, 0x16, 0x1b, 0x5a, 0x37, 0x1f, + 0x86, 0x01, 0xde, 0xd4, 0x1c, 0x56, 0x76, 0xe3, 0xb6, 0x74, 0x8f, 0x05, 0x01, 0x00, 0xa1, 0x41, + 0xda, 0xc8, 0x42, 0xf5, 0x4e, 0x03, 0x1c, 0x68, 0x65, 0x21, 0x99, 0x89, 0x53, 0x14, 0x10, 0x51, + 0x1c, 0x6d, 0xeb, 0xdc, 0x1f, 0x7b, 0xbc, 0x1c, 0x10, 0x46, 0xc5, 0x00, 0x2b, 0xf6, 0x0d, 0x9e, + 0xf8, 0x89, 0x3e, 0x38, 0x38, 0xc9, 0x8f, 0xb0, 0xf7, 0x09, 0xf9, 0x0c, 0x07, 0x8d, 0x83, 0x80, + 0x29, 0x21, 0xf7, 0x9a, 0x05, 0x70, 0xaa, 0x01, 0xe0, 0x84, 0x68, 0xa8, 0x1b, 0xe7, 0xd5, 0xf8, + 0x3e, 0xe5, 0x10, 0x1f, 0x1a, 0x52, 0x84, 0x74, 0x2d, 0xa0, 0x56, 0x69, 0x36, 0x59, 0x7c, 0x34, + 0x6e, 0x20, 0xb5, 0x4d, 0xe7, 0xa1, 0x0b, 0x6c, 0x77, 0x95, 0x7e, 0xaa, 0xc2, 0xe3, 0xda, 0xbc, + 0x7e, 0x3c, 0xea, 0x4d, 0xd4, 0xd4, 0x4f, 0x3e, 0x5b, 0xfa, 0x27, 0x57, 0x39, 0x5d, 0xfa, 0x97, + 0xcf, 0x82, 0x5d, 0x15, 0x5b, 0x9b, 0x7a, 0xae, 0x11, 0xa7, 0x7b, 0xbf, 0x54, 0xfe, 0x0a, 0x3c, + 0xd5, 0x4d, 0x16, 0xd7, 0x7c, 0x96, 0xd1, 0x35, 0xf3, 0x95, 0x5d, 0xb7, 0xfa, 0xe2, 0x04, 0x56, + 0x96, 0x49, 0x7c, 0x41, 0x19, 0x27, 0x49, 0x12, 0x48, 0xbe, 0x43, 0xbb, 0xbf, 0xd0, 0xf4, 0xa7, + 0xd6, 0xab, 0x84, 0xc2, 0xc5, 0x52, 0x87, 0xa2, 0x69, 0x09, 0x8f, 0xcd, 0x4a, 0x9b, 0x5e, 0x4f, + 0x2f, 0xf1, 0x9e, 0x27, 0x0b, 0x4a, 0xb5, 0x51, 0x8c, 0x88, 0xc4, 0xff, 0x2d, 0xcb, 0x8f, 0xf8, + 0xcd, 0xef, 0x77, 0x77, 0x7a, 0x6f, 0xbf, 0xbd, 0xdf, 0xe6, 0xdc, 0xac, 0x6b, 0x92, 0x5d, 0xa1, + 0x6b, 0x84, 0xf9, 0xa1, 0xc7, 0xa9, 0x4b, 0xde, 0xec, 0x4e, 0xb9, 0x2e, 0xf7, 0xf1, 0x3b, 0xc5, + 0x71, 0x5f, 0x7c, 0xc7, 0xbc, 0xff, 0x11, 0x12, 0x4c, 0x71, 0x6b, 0x58, 0x6d, 0xa1, 0xb5, 0x94, + 0x29, 0x30, 0xb8, 0x28, 0x12, 0x94, 0xc4, 0x1a, 0x57, 0xb1, 0xf0, 0x48, 0x47, 0xd3, 0xc2, 0xba, + 0xb1, 0x51, 0x10, 0x4f, 0xd4, 0xcc, 0x52, 0xb4, 0x75, 0xb8, 0x28, 0x10, 0x08, 0x3a, 0x89, 0xe1, + 0x32, 0x4a, 0x37, 0x0a, 0x7c, 0x89, 0x46, 0x63, 0xa7, 0x08, 0x49, 0xa1, 0x14, 0xb4, 0xc5, 0xbf, + 0xf0, 0xdd, 0x62, 0xba, 0xe2, 0xda, 0x56, 0x84, 0x3b, 0x5f, 0x84, 0x3a, 0x49, 0x6d, 0x35, 0x56, + 0xbe, 0x1e, 0x23, 0x76, 0xf3, 0x31, 0x49, 0x9d, 0x43, 0x83, 0xc9, 0x97, 0xf0, 0x2c, 0x7c, 0xdb, + 0x05, 0x01, 0x81, 0xb1, 0x93, 0x21, 0xa0, 0x00, 0x23, 0x4e, 0x00, 0x7c, 0x46, 0x02, 0x50, 0x58, + 0xa4, 0xf8, 0x14, 0x58, 0xf0, 0x7b, 0xdd, 0xd9, 0x07, 0xc1, 0x29, 0xd8, 0x62, 0x42, 0x8d, 0x55, + 0x8a, 0x23, 0x9c, 0x40, 0x9a, 0x90, 0x1b, 0x0f, 0xb9, 0x56, 0x34, 0x78, 0x98, 0x52, 0x3a, 0xf1, + 0xd9, 0xae, 0xbd, 0x0b, 0x9a, 0xdb, 0x81, 0xb1, 0xdf, 0x43, 0x23, 0xe6, 0x2d, 0x01, 0xbb, 0x19, + 0xed, 0x09, 0x5d, 0x10, 0x36, 0xb1, 0x02, 0x06, 0x6e, 0x26, 0x26, 0xb1, 0xb4, 0x69, 0xfc, 0xb6, + 0x21, 0xcc, 0x4a, 0xa3, 0x88, 0x10, 0x34, 0x91, 0xbc, 0x66, 0xe0, 0xac, 0x22, 0x07, 0xcb, 0x0c, + 0x05, 0xc4, 0xc2, 0xa8, 0x16, 0xc1, 0xc7, 0x01, 0x27, 0x84, 0x80, 0xca, 0x34, 0x30, 0x13, 0x94, + 0x03, 0xa7, 0x68, 0xf7, 0xe0, 0x2c, 0x26, 0xc1, 0xde, 0x25, 0x81, 0x4d, 0xdf, 0x84, 0x01, 0x00, + 0x53, 0xf5, 0xaf, 0x37, 0x30, 0x30, 0x13, 0xfc, 0xb0, 0x03, 0xc8, 0x47, 0x65, 0x11, 0x4a, 0xdc, + 0xbe, 0xcc, 0xf1, 0x83, 0x00, 0x40, 0x14, 0xb2, 0x93, 0x15, 0x55, 0xb3, 0x7d, 0xdc, 0xca, 0x1e, + 0x4d, 0x60, 0x83, 0x20, 0xf1, 0x63, 0x73, 0xe1, 0x82, 0xa6, 0x9b, 0xa5, 0xb0, 0x5e, 0x38, 0x95, + 0xca, 0x5e, 0x56, 0x95, 0x47, 0xb1, 0x7c, 0x71, 0x3a, 0x05, 0x7f, 0xf0, 0x46, 0x54, 0x8f, 0xdd, + 0x5e, 0x1e, 0x10, 0xe6, 0x35, 0xef, 0xe5, 0xbd, 0xfe, 0x49, 0xfc, 0xff, 0xe2, 0xf5, 0xae, 0xab, + 0xe1, 0x3a, 0x7b, 0xee, 0xfe, 0x42, 0xbd, 0xeb, 0xba, 0xeb, 0xe2, 0xeb, 0x5e, 0xab, 0xec, 0x97, + 0xba, 0xe2, 0x3c, 0xbd, 0x3b, 0x93, 0x7e, 0x7c, 0x5c, 0x6f, 0xcd, 0xdd, 0xd7, 0x24, 0x3c, 0x4d, + 0xdf, 0xc7, 0x17, 0x7c, 0xa5, 0xcd, 0x86, 0xcf, 0x44, 0x87, 0xf1, 0xd7, 0x6f, 0x58, 0x39, 0x63, + 0x55, 0x4f, 0xc2, 0xd4, 0x31, 0x64, 0x73, 0xaa, 0x24, 0x89, 0xf6, 0x82, 0x1b, 0xa6, 0xcf, 0xac, + 0x5e, 0x78, 0x47, 0xc0, 0x80, 0x18, 0x05, 0xda, 0xa6, 0xa9, 0x12, 0x95, 0xd2, 0xf0, 0x60, 0x10, + 0x0a, 0x5d, 0x2d, 0x57, 0x0e, 0x89, 0x8f, 0x52, 0x3d, 0xd2, 0xcc, 0x70, 0x60, 0x10, 0x0a, 0xd6, + 0x97, 0x55, 0x1d, 0xa9, 0xa7, 0x3e, 0xfe, 0x26, 0x1e, 0xad, 0x55, 0x4c, 0x26, 0x90, 0x1f, 0x6a, + 0xaa, 0xf4, 0x2a, 0x3c, 0xf5, 0x26, 0x0f, 0x80, 0x99, 0x84, 0xa6, 0x52, 0x50, 0xfb, 0x5a, 0x44, + 0xee, 0x85, 0xf1, 0xe2, 0x02, 0x01, 0x49, 0xe1, 0x93, 0x49, 0x83, 0x82, 0xda, 0x8c, 0x6f, 0xaa, + 0x86, 0x0b, 0x18, 0x32, 0xd4, 0x44, 0x7a, 0x8f, 0x84, 0xba, 0x28, 0xf3, 0x68, 0x3d, 0xd0, 0xa4, + 0x0a, 0xbf, 0x0a, 0x6d, 0x00, 0x1a, 0x5c, 0x63, 0xcb, 0xc9, 0xcf, 0x2c, 0x61, 0x57, 0x94, 0x58, + 0x57, 0xe0, 0xfd, 0x2f, 0x8a, 0xe5, 0x25, 0x01, 0xe5, 0x4a, 0x9b, 0xf5, 0x14, 0xa4, 0x7a, 0xd3, + 0xf5, 0xe0, 0xab, 0x13, 0x0a, 0x45, 0x65, 0x8c, 0xf5, 0x82, 0xd9, 0x63, 0x71, 0x47, 0xec, 0xfd, + 0xda, 0xcd, 0xed, 0xdf, 0x89, 0x85, 0x0a, 0xd9, 0x7a, 0x18, 0xeb, 0xb2, 0x64, 0x23, 0x40, 0x46, + 0xdd, 0xb0, 0xcb, 0x9d, 0x98, 0x57, 0xe8, 0x18, 0x47, 0xc1, 0x02, 0x2d, 0xb8, 0x31, 0x3c, 0x46, + 0x0b, 0xfb, 0xcc, 0x60, 0x06, 0xba, 0x55, 0x89, 0x87, 0x4d, 0xae, 0x75, 0x18, 0x30, 0x1b, 0xb0, + 0x33, 0x67, 0x2d, 0x1e, 0x77, 0xe5, 0xd7, 0x8f, 0xc1, 0x5d, 0xdf, 0x74, 0xa2, 0x5c, 0x6c, 0x30, + 0xf1, 0x3a, 0xb7, 0x5d, 0xdc, 0x14, 0x04, 0x02, 0x9b, 0x96, 0x92, 0x4e, 0xa4, 0xd9, 0xd0, 0x9e, + 0x55, 0x74, 0x79, 0x72, 0xc6, 0x90, 0xa8, 0x48, 0x00, 0xd0, 0x3b, 0xa5, 0x2a, 0x97, 0x8a, 0x89, + 0x51, 0x42, 0x8e, 0xa1, 0xf8, 0xc1, 0x44, 0x68, 0xbb, 0xbc, 0x43, 0xc2, 0xe6, 0x91, 0x8e, 0xdc, + 0x9a, 0xaa, 0xcf, 0x16, 0x5a, 0x85, 0x51, 0x6b, 0x24, 0xaa, 0x6a, 0xd4, 0x21, 0x86, 0xb1, 0x11, + 0x80, 0x1d, 0x5e, 0x82, 0x7c, 0x5a, 0x1a, 0x46, 0xc8, 0x51, 0x84, 0xbb, 0x11, 0x77, 0xae, 0x4b, + 0xbb, 0xbf, 0x97, 0x7b, 0xbe, 0x08, 0xaa, 0xab, 0xca, 0xb9, 0xa2, 0xbd, 0xfc, 0x95, 0x1c, 0x5c, + 0x2f, 0x26, 0xef, 0x2f, 0x29, 0x5e, 0xee, 0xb1, 0x20, 0xa6, 0xd5, 0x11, 0x00, 0xb1, 0xdd, 0xc1, + 0x44, 0x69, 0x96, 0x95, 0xb1, 0xed, 0x11, 0x07, 0x21, 0x1f, 0x82, 0xc3, 0x5c, 0xd9, 0x1e, 0x2e, + 0x6c, 0x92, 0x02, 0xe5, 0xf4, 0xbe, 0x20, 0x14, 0xd6, 0xaa, 0xab, 0xd2, 0x53, 0x66, 0xc7, 0x0c, + 0x89, 0x18, 0x73, 0x67, 0x5e, 0x5c, 0x7b, 0xbd, 0x37, 0x6b, 0x08, 0xc7, 0xcd, 0x06, 0x67, 0xc7, + 0x90, 0x98, 0x29, 0xab, 0xf1, 0x31, 0x84, 0x63, 0x12, 0xcf, 0xc6, 0xfb, 0x3d, 0x71, 0x3e, 0xd4, + 0x58, 0x98, 0x52, 0x2b, 0x25, 0x68, 0x58, 0x8e, 0xd8, 0xa6, 0x8c, 0x93, 0x7b, 0xf9, 0x3f, 0x41, + 0x9a, 0xe6, 0x66, 0xaf, 0x30, 0xee, 0x4a, 0xee, 0x59, 0x98, 0xe7, 0x08, 0x89, 0x1b, 0x2d, 0x49, + 0x1f, 0x03, 0xa5, 0x00, 0x87, 0x56, 0x58, 0x8e, 0x73, 0x1e, 0xbb, 0xe8, 0x01, 0xc0, 0x34, 0x2d, + 0x86, 0x42, 0xf2, 0xcd, 0xf0, 0x0d, 0x13, 0x91, 0x01, 0x48, 0x1e, 0x79, 0xd7, 0x7d, 0x39, 0xf7, + 0xe0, 0xaf, 0x4c, 0xd7, 0x8e, 0xb3, 0x42, 0x13, 0x1c, 0x19, 0x6a, 0xf4, 0x23, 0xd4, 0x71, 0xc7, + 0x82, 0x5a, 0x6f, 0xb9, 0xbb, 0xfa, 0xe0, 0xa4, 0x22, 0x1b, 0x3e, 0x4f, 0x45, 0x7f, 0xc5, 0x70, + 0xa7, 0x28, 0x8a, 0xaa, 0x93, 0xbd, 0x55, 0x7d, 0xef, 0x3f, 0x27, 0x1c, 0x7a, 0x54, 0x9a, 0x4d, + 0x97, 0x8f, 0xca, 0x3f, 0x05, 0x64, 0xba, 0xaa, 0xae, 0xaa, 0xa6, 0xc6, 0x8a, 0x86, 0x21, 0x48, + 0xa6, 0x1e, 0xa1, 0x3b, 0x96, 0x7c, 0xef, 0x79, 0xfa, 0x18, 0xb8, 0x54, 0xe8, 0x4b, 0x86, 0x02, + 0x03, 0x8b, 0xd5, 0x2a, 0x34, 0x92, 0xd5, 0x0c, 0x4f, 0x11, 0x05, 0x96, 0x1b, 0x62, 0xb6, 0xef, + 0x79, 0xbc, 0x4f, 0xd3, 0xf1, 0x00, 0x80, 0x28, 0x6b, 0xcd, 0x8e, 0xfc, 0x1c, 0x57, 0x17, 0x80, + 0x4a, 0x14, 0x49, 0x58, 0x81, 0x28, 0xab, 0x26, 0x46, 0xb0, 0x00, 0x72, 0x40, 0xae, 0x53, 0x8c, + 0xf0, 0x84, 0x40, 0xbb, 0x66, 0xe7, 0x20, 0xe6, 0xe6, 0x2a, 0x9a, 0x66, 0xf0, 0xa1, 0xbb, 0xb0, + 0x62, 0x92, 0xa0, 0xad, 0x8b, 0x58, 0x3e, 0x4c, 0x7b, 0x4b, 0xf0, 0xa5, 0xfc, 0x52, 0xca, 0x38, + 0x56, 0x0c, 0x64, 0xb6, 0x72, 0x8c, 0x33, 0xf6, 0xf7, 0xa5, 0x3a, 0xc8, 0x03, 0x0b, 0x69, 0xc4, + 0x2e, 0xd8, 0xa3, 0x18, 0x73, 0xa1, 0xf6, 0x1d, 0xed, 0x42, 0x03, 0x1a, 0x87, 0x52, 0x49, 0x0f, + 0x44, 0x3e, 0xdb, 0xc9, 0x71, 0x22, 0x41, 0x61, 0x14, 0x0f, 0xb5, 0x17, 0x4c, 0x47, 0xc6, 0x3d, + 0x4c, 0x2a, 0x9c, 0xa8, 0x5e, 0x5e, 0x77, 0xce, 0x0b, 0xf0, 0xc9, 0xc7, 0xde, 0x49, 0xa7, 0xa7, + 0xfb, 0xb2, 0x12, 0xc3, 0x0a, 0x77, 0x27, 0xd7, 0xe2, 0x6f, 0x77, 0x7d, 0xcd, 0xc4, 0xea, 0xcd, + 0x26, 0x52, 0x7f, 0x82, 0x3e, 0x57, 0xbe, 0x5f, 0x04, 0xde, 0x93, 0x54, 0x86, 0xa3, 0xe5, 0x9f, + 0x29, 0xf5, 0x1a, 0xf3, 0xee, 0x76, 0x73, 0x75, 0xc2, 0x91, 0xf7, 0x05, 0xc0, 0xaf, 0x65, 0xaa, + 0x8b, 0x93, 0xfe, 0x5f, 0x62, 0x13, 0xda, 0xf0, 0x42, 0x5b, 0x46, 0x9e, 0xe7, 0xd5, 0xaf, 0x9a, + 0xb4, 0x68, 0xfd, 0x60, 0xbe, 0x2b, 0xb6, 0x98, 0xda, 0xef, 0x21, 0x39, 0x15, 0x12, 0x11, 0x05, + 0x70, 0x91, 0xbb, 0x6b, 0xdd, 0x05, 0x5f, 0xc7, 0xd9, 0x83, 0x7d, 0x05, 0x07, 0x90, 0xf2, 0x6a, + 0x2f, 0x87, 0x82, 0x72, 0x5b, 0x7a, 0x4e, 0xbe, 0xe2, 0x01, 0x00, 0x50, 0xc7, 0x2c, 0xa4, 0x0e, + 0x53, 0x64, 0xbc, 0x2d, 0x49, 0x62, 0xf2, 0x2a, 0x39, 0x2b, 0x01, 0x5c, 0x7e, 0x56, 0x54, 0xa0, + 0x26, 0xa1, 0x86, 0x3d, 0xe2, 0x54, 0xdc, 0x10, 0x06, 0x03, 0x07, 0x27, 0x14, 0x2c, 0x47, 0x7c, + 0x53, 0x32, 0x89, 0x44, 0x9c, 0x36, 0x1e, 0x00, 0x04, 0x30, 0x56, 0x25, 0x0a, 0x84, 0x65, 0x93, + 0xa7, 0x8a, 0xb6, 0xf1, 0x01, 0x80, 0xa1, 0x75, 0x23, 0x37, 0x2f, 0x5f, 0x7b, 0x40, 0x94, 0x38, + 0x13, 0x03, 0x10, 0x84, 0x15, 0x98, 0x8a, 0x12, 0x1d, 0xde, 0x39, 0xc4, 0xbe, 0x20, 0x65, 0x9c, + 0xe8, 0x80, 0xa1, 0x6a, 0x84, 0x8a, 0x10, 0xa1, 0xbb, 0x74, 0xbb, 0x29, 0x5a, 0x99, 0x72, 0xc2, + 0x15, 0x99, 0x82, 0x7a, 0xd1, 0xb7, 0x6c, 0xdf, 0x16, 0x11, 0x6c, 0x31, 0x01, 0x10, 0xa4, 0xa6, + 0xc9, 0xf0, 0xd0, 0x63, 0x89, 0x40, 0x77, 0x14, 0xf0, 0xa6, 0x51, 0xca, 0x18, 0x4f, 0x0c, 0xd3, + 0x24, 0x16, 0x42, 0x6a, 0x88, 0xf6, 0xca, 0xd4, 0xa3, 0xa0, 0x79, 0xd0, 0x3e, 0x0a, 0xd0, 0x77, + 0x02, 0x88, 0x0d, 0x58, 0xb4, 0x78, 0x52, 0x50, 0x0a, 0x72, 0x91, 0x50, 0xf2, 0xf3, 0x69, 0xbc, + 0xbc, 0x9d, 0x34, 0xbc, 0x49, 0x72, 0x6b, 0xcd, 0xaa, 0x9f, 0xc1, 0x65, 0x16, 0x79, 0x37, 0x2e, + 0xec, 0xeb, 0x1b, 0xe0, 0xae, 0x4c, 0xf5, 0xd3, 0x36, 0x7e, 0xcf, 0x82, 0x7c, 0xde, 0xdd, 0x0e, + 0xec, 0xfb, 0x39, 0x9b, 0x9f, 0x98, 0xc4, 0x1b, 0x34, 0x91, 0xc2, 0xf1, 0xa6, 0x41, 0x1b, 0x17, + 0x51, 0x8b, 0xc1, 0x86, 0xb8, 0xfd, 0x1b, 0xba, 0x0e, 0x5b, 0xce, 0xf5, 0xfe, 0x3b, 0xde, 0x6c, + 0x75, 0x33, 0x95, 0xc4, 0xd2, 0xa7, 0xc6, 0x70, 0xaa, 0x1b, 0xc1, 0x29, 0x52, 0xdd, 0x26, 0xf7, + 0xae, 0x08, 0x4a, 0x7d, 0xb1, 0x9b, 0x13, 0x7c, 0x30, 0x68, 0x2d, 0x12, 0xc1, 0xdc, 0x3a, 0xdc, + 0x8b, 0xb4, 0xe7, 0xf0, 0x77, 0x87, 0xc3, 0x9a, 0xc2, 0xe5, 0x50, 0x5f, 0xfc, 0x6f, 0xb8, 0x80, + 0x41, 0xdd, 0xc6, 0xbd, 0x50, 0x5c, 0xc4, 0xa3, 0x43, 0x97, 0x8d, 0x98, 0xa8, 0x01, 0x2f, 0xc1, + 0x5f, 0xaa, 0x12, 0x64, 0x2f, 0xc7, 0x47, 0xa0, 0xed, 0xf8, 0x90, 0x49, 0xcf, 0xa0, 0x63, 0xae, + 0x45, 0x4b, 0x12, 0x24, 0x29, 0xd5, 0x9b, 0x9a, 0x27, 0xd4, 0x29, 0x35, 0x11, 0x29, 0xeb, 0x81, + 0xc6, 0x7c, 0x87, 0x6a, 0x4d, 0x4d, 0x75, 0x51, 0x9e, 0xc8, 0x38, 0xee, 0x04, 0x03, 0xe9, 0x02, + 0x3c, 0xd1, 0xaf, 0x12, 0x14, 0xe9, 0x12, 0xea, 0xd8, 0x8d, 0x48, 0x4e, 0xe5, 0x49, 0x2e, 0x09, + 0x06, 0xdf, 0xa9, 0x07, 0x40, 0xd8, 0x56, 0x6b, 0x7f, 0x08, 0x82, 0xc3, 0x4e, 0xa4, 0x82, 0x38, + 0x6c, 0x9b, 0xeb, 0x4d, 0x8d, 0x72, 0xde, 0x5c, 0x30, 0x24, 0x29, 0xda, 0x41, 0xfc, 0xa3, 0xfe, + 0xad, 0x47, 0x85, 0x81, 0xf0, 0x96, 0x63, 0x4c, 0x54, 0x78, 0x16, 0x03, 0xb8, 0x2a, 0x91, 0x0a, + 0x8e, 0xf1, 0xbf, 0xfc, 0x8b, 0x0c, 0x04, 0x46, 0x89, 0x1f, 0x6a, 0xa4, 0xd2, 0x18, 0xd8, 0x5b, + 0xa5, 0x7b, 0x20, 0xc3, 0x31, 0xde, 0xc4, 0xc8, 0x80, 0xd7, 0x00, 0x51, 0x79, 0x77, 0x1c, 0x06, + 0xe7, 0x82, 0x16, 0xb0, 0xea, 0x80, 0xd5, 0x23, 0x4e, 0xc0, 0xe4, 0xbe, 0xae, 0x8f, 0x88, 0x08, + 0x05, 0x0a, 0xc2, 0x66, 0x0d, 0x1b, 0xb5, 0xd7, 0x1d, 0xf3, 0xdc, 0x50, 0x1a, 0xdb, 0xa1, 0x9f, + 0xba, 0x89, 0x42, 0x67, 0xf0, 0x23, 0x09, 0x7d, 0xe3, 0xb4, 0x46, 0x3c, 0x48, 0x20, 0x0a, 0x1b, + 0x53, 0x43, 0xaf, 0xcb, 0xc3, 0x35, 0x3b, 0x5f, 0x02, 0x45, 0x57, 0x9c, 0x56, 0x18, 0xf9, 0xde, + 0xf8, 0x7c, 0xb3, 0x64, 0xcf, 0x05, 0x50, 0x5f, 0x13, 0x9c, 0x95, 0x5d, 0x9a, 0x2c, 0x30, 0x76, + 0xfc, 0x1a, 0xdd, 0x85, 0x78, 0x26, 0x25, 0xdd, 0xdd, 0xf6, 0x5f, 0x27, 0x9f, 0x8b, 0xe0, 0x9c, + 0x84, 0x61, 0xe7, 0x12, 0x84, 0xf5, 0x21, 0x8e, 0x5f, 0x2d, 0xa6, 0x9d, 0x28, 0x13, 0xe0, 0x94, + 0xf4, 0xaf, 0x3d, 0x2f, 0x8c, 0xbe, 0x09, 0xcb, 0x35, 0x28, 0x71, 0x0c, 0x98, 0x73, 0x87, 0x88, + 0x1a, 0x21, 0xd1, 0x95, 0x9d, 0x9b, 0x69, 0x23, 0x6a, 0x55, 0x53, 0xb6, 0x5b, 0x7e, 0xaf, 0x87, + 0xdf, 0x35, 0xcc, 0x4b, 0x56, 0x24, 0x40, 0xd8, 0x5c, 0xf9, 0x64, 0xbe, 0x4c, 0x5e, 0xe1, 0x2e, + 0xa8, 0x18, 0x38, 0xb9, 0x20, 0x0a, 0x8d, 0x73, 0x38, 0x86, 0x8c, 0x86, 0xda, 0x6b, 0x44, 0xeb, + 0xf1, 0xf6, 0xc7, 0x55, 0x7e, 0x18, 0x1b, 0xc1, 0x4c, 0x94, 0x74, 0xe4, 0x90, 0x56, 0x71, 0xa4, + 0x7f, 0x0c, 0x64, 0x3c, 0x72, 0x36, 0x36, 0x36, 0x28, 0xe6, 0x7d, 0x55, 0x88, 0xe1, 0x8b, 0xa4, + 0x75, 0x6c, 0x8b, 0x04, 0x32, 0xc9, 0xe7, 0xc4, 0x0e, 0x6e, 0x3d, 0x8f, 0xfc, 0x21, 0x1b, 0x34, + 0x11, 0xaa, 0x17, 0x2a, 0x7e, 0x08, 0x12, 0xfe, 0x3e, 0xcf, 0xd1, 0x5a, 0xf8, 0x33, 0x38, 0x07, + 0x2c, 0xe0, 0x01, 0xe7, 0x83, 0xc1, 0x8e, 0xa8, 0xc0, 0x10, 0x80, 0xbe, 0xc0, 0x90, 0x42, 0xbe, + 0x31, 0xdf, 0xc4, 0xc2, 0x9c, 0x51, 0x97, 0x96, 0x32, 0xdd, 0x95, 0x8f, 0x15, 0x88, 0x61, 0xbf, + 0x54, 0x67, 0x55, 0x98, 0x61, 0xc4, 0x85, 0x37, 0x10, 0x0c, 0x0e, 0xc0, 0xd4, 0x84, 0xe0, 0x79, + 0x98, 0xcd, 0xaa, 0xcb, 0xee, 0xc3, 0xdb, 0x03, 0xfd, 0x59, 0x8c, 0xe2, 0x44, 0x8d, 0x29, 0x5a, + 0x7e, 0xed, 0xed, 0x24, 0xe0, 0x55, 0x38, 0x32, 0x12, 0x20, 0x88, 0x02, 0xfb, 0x6a, 0x3a, 0xe3, + 0x60, 0x48, 0x32, 0x6c, 0x21, 0xc6, 0xd1, 0xaf, 0x0c, 0xba, 0x28, 0xcb, 0x78, 0x23, 0xce, 0x6a, + 0xa1, 0x85, 0x43, 0x9d, 0xa5, 0x43, 0xcb, 0x8d, 0x2e, 0x2f, 0xc2, 0x11, 0xb2, 0xa9, 0xe3, 0x60, + 0x60, 0xb5, 0xe7, 0x43, 0x44, 0x82, 0x81, 0xb1, 0x6c, 0x2b, 0x91, 0xb1, 0xe9, 0x1b, 0xaa, 0x29, + 0x24, 0x06, 0x2f, 0x6b, 0x2d, 0x05, 0xa1, 0x71, 0x72, 0x25, 0x08, 0x66, 0xd4, 0x13, 0x87, 0x22, + 0xf0, 0xa0, 0x3e, 0x60, 0x78, 0x18, 0x91, 0xa1, 0x9a, 0xf8, 0x8e, 0x22, 0x57, 0xf1, 0x11, 0xa4, + 0x59, 0x53, 0xeb, 0xbe, 0xae, 0x53, 0xcd, 0x98, 0x4f, 0x52, 0x82, 0x2f, 0x57, 0x42, 0x2b, 0x1d, + 0x81, 0x42, 0x1d, 0x05, 0xc9, 0x00, 0x0a, 0x9e, 0x18, 0x07, 0xe0, 0x94, 0x3c, 0xa5, 0x2a, 0x95, + 0x07, 0x19, 0x66, 0xd1, 0xa9, 0x75, 0xbc, 0xcf, 0xe1, 0x91, 0x21, 0x4f, 0x76, 0x7b, 0x46, 0x60, + 0xb0, 0x31, 0x1e, 0xc6, 0x8b, 0xc1, 0x29, 0xae, 0xa3, 0xbd, 0xc4, 0x08, 0x05, 0x9b, 0x35, 0x9f, + 0x0d, 0xcf, 0x38, 0xaa, 0xa3, 0xba, 0x07, 0xe3, 0x52, 0xbd, 0x43, 0xb8, 0xd5, 0x8e, 0x08, 0x01, + 0x40, 0x53, 0xb8, 0x30, 0x1a, 0x9a, 0x2a, 0x00, 0x1f, 0x4b, 0xbf, 0x2c, 0x1d, 0x2c, 0x7e, 0x9d, + 0xc3, 0x6f, 0x1a, 0xf8, 0xf1, 0x01, 0xf3, 0x96, 0x64, 0x5c, 0xbf, 0x01, 0xd9, 0x07, 0xf2, 0x10, + 0x78, 0xfe, 0x85, 0x46, 0x0c, 0xd5, 0x62, 0xb2, 0xda, 0x22, 0xb0, 0xa5, 0x9b, 0x4d, 0xbf, 0x0c, + 0x07, 0xf6, 0xff, 0x0f, 0xd6, 0x70, 0x00, 0x15, 0xe3, 0x59, 0x0e, 0x22, 0xcc, 0x0d, 0x19, 0x7c, + 0x2a, 0x84, 0x79, 0x53, 0x2e, 0x2a, 0xff, 0xc1, 0x1f, 0x2a, 0x01, 0xbf, 0x2b, 0x51, 0xd5, 0x09, + 0x72, 0x17, 0x4d, 0xd6, 0x25, 0x9a, 0xae, 0x6e, 0xb9, 0x88, 0xf6, 0xe4, 0xe5, 0x2c, 0xff, 0xf1, + 0xb4, 0x0d, 0x26, 0x49, 0x26, 0xce, 0x7b, 0x97, 0x10, 0xf4, 0xb7, 0x46, 0xbe, 0x7d, 0xd2, 0xf6, + 0x49, 0xe1, 0x75, 0xd9, 0xd0, 0x9e, 0xfe, 0x2a, 0xda, 0x36, 0xba, 0xa5, 0xe3, 0xaa, 0x31, 0xe0, + 0xe3, 0xf7, 0x16, 0xd1, 0x08, 0xb7, 0x15, 0xe5, 0x57, 0xf0, 0x95, 0x9d, 0xf9, 0x5a, 0xe2, 0x30, + 0x88, 0x25, 0x39, 0x2d, 0x29, 0xa8, 0x42, 0x4c, 0x20, 0xf7, 0xf1, 0x23, 0x45, 0x68, 0xcd, 0x0f, + 0x03, 0x5c, 0x09, 0x35, 0x07, 0x6c, 0x02, 0x58, 0xb0, 0x10, 0xbf, 0x16, 0x3a, 0xc8, 0x94, 0x39, + 0x0d, 0x94, 0x7b, 0xef, 0xe3, 0xb0, 0x66, 0xcd, 0x09, 0xa0, 0xd1, 0xd4, 0x22, 0x1f, 0xc3, 0x13, + 0x1b, 0x91, 0xdf, 0x0e, 0x38, 0x59, 0x9e, 0xc9, 0x10, 0x2a, 0x28, 0x53, 0xc6, 0x5e, 0xb1, 0x97, + 0xc6, 0x0d, 0x7c, 0x0a, 0xb7, 0x3b, 0x38, 0x28, 0x8b, 0x27, 0x84, 0xb7, 0x59, 0xff, 0xc4, 0xc6, + 0x51, 0x02, 0x72, 0x49, 0x34, 0x05, 0x5f, 0x2e, 0xc4, 0x7b, 0x04, 0xe6, 0x91, 0x1d, 0xf1, 0xdc, + 0x0a, 0xe1, 0x69, 0x7b, 0x07, 0x9d, 0xe3, 0x1c, 0xa1, 0xcf, 0xa3, 0xc1, 0x48, 0x47, 0x82, 0x90, + 0x42, 0x08, 0xfc, 0xb9, 0x95, 0x43, 0x20, 0x85, 0x94, 0x4b, 0x85, 0x57, 0x97, 0x50, 0x42, 0x0a, + 0x5e, 0xcb, 0xf8, 0x95, 0x7f, 0x87, 0xbc, 0xac, 0x26, 0x37, 0x52, 0xfc, 0xf1, 0x89, 0x85, 0xc0, + 0x4d, 0x66, 0xa6, 0xca, 0xb0, 0x01, 0x2c, 0xa2, 0x00, 0x23, 0x6c, 0x29, 0x11, 0x39, 0x0d, 0x7f, + 0xcb, 0x58, 0xef, 0xec, 0xb1, 0x11, 0xc4, 0x1d, 0x58, 0xc6, 0x47, 0x8b, 0xc0, 0xcb, 0x65, 0xb6, + 0xa7, 0x7e, 0x5e, 0x40, 0xc0, 0xe2, 0x04, 0x0c, 0xec, 0xc4, 0x2a, 0x08, 0xe9, 0xa7, 0x58, 0x61, + 0xe4, 0x5b, 0x89, 0x7d, 0x44, 0xa0, 0xa1, 0xfe, 0xc4, 0xde, 0xdc, 0x2d, 0xca, 0x4c, 0x92, 0x57, + 0xcd, 0x66, 0x7b, 0xd7, 0x11, 0xa7, 0x31, 0xab, 0x36, 0x8c, 0x18, 0x7c, 0x15, 0xed, 0x94, 0x83, + 0x96, 0xdf, 0x5c, 0xfa, 0xc3, 0xc4, 0x91, 0x05, 0x1a, 0x32, 0xe5, 0x07, 0x02, 0x5f, 0x13, 0x3a, + 0x03, 0xf4, 0xeb, 0x4a, 0x89, 0x0d, 0x77, 0xad, 0xcb, 0xc6, 0x9e, 0xc4, 0x9b, 0x6d, 0x9c, 0x56, + 0x8a, 0xac, 0x23, 0x38, 0xf9, 0xf5, 0x8f, 0x2f, 0xff, 0x09, 0x58, 0x19, 0xc7, 0x0a, 0xb5, 0x01, + 0x91, 0x29, 0x67, 0x63, 0x58, 0x44, 0x69, 0x31, 0x8a, 0xc9, 0x72, 0x47, 0x1e, 0x90, 0xc5, 0x55, + 0xc4, 0xe8, 0xc2, 0x5a, 0x30, 0x89, 0xaa, 0x9a, 0x35, 0x24, 0xc7, 0x16, 0xcc, 0xdc, 0xa9, 0xcc, + 0xa5, 0x7f, 0x89, 0x1b, 0xb1, 0xea, 0x4f, 0x98, 0x28, 0xbb, 0x6b, 0xb6, 0xfc, 0x05, 0xd4, 0x02, + 0x0b, 0x99, 0x05, 0x4e, 0xcb, 0x60, 0xb2, 0xdc, 0x0a, 0xce, 0xc5, 0x94, 0x40, 0x40, 0x1d, 0x2a, + 0x41, 0xce, 0x0f, 0x29, 0x80, 0x00, 0x80, 0x6a, 0xc0, 0x67, 0x60, 0x98, 0x9b, 0xa6, 0x84, 0x4a, + 0xa0, 0x6c, 0x7b, 0x82, 0x96, 0x3c, 0x21, 0x1b, 0x40, 0x05, 0x41, 0xc3, 0x7d, 0x8a, 0x84, 0x83, + 0x71, 0x7d, 0xd7, 0x36, 0x12, 0x65, 0x4e, 0x43, 0xfe, 0x90, 0x27, 0x19, 0xc5, 0xb2, 0xc2, 0xd5, + 0x99, 0x10, 0x03, 0xfd, 0x88, 0xd1, 0x9f, 0x89, 0x12, 0x8a, 0xff, 0x31, 0x1d, 0x52, 0x5f, 0x04, + 0x25, 0x6a, 0xfa, 0xf9, 0x0c, 0xaa, 0x92, 0xfa, 0xca, 0xb8, 0x28, 0x23, 0x22, 0xe5, 0x19, 0xc8, + 0x2f, 0x57, 0x2f, 0x8b, 0xa3, 0x2e, 0x69, 0x22, 0x9d, 0x27, 0x8c, 0x2c, 0x66, 0x49, 0x22, 0x41, + 0x65, 0x02, 0xa3, 0x82, 0x20, 0x68, 0xc0, 0xc7, 0x9a, 0x32, 0x46, 0x3c, 0xfa, 0x59, 0xe5, 0xff, + 0x04, 0xc2, 0x54, 0x2f, 0xa1, 0x67, 0xea, 0xfc, 0x48, 0x40, 0x16, 0x08, 0x8e, 0x45, 0x13, 0x92, + 0x55, 0x0e, 0x32, 0x2e, 0xa4, 0x7c, 0xd3, 0x30, 0xdf, 0x42, 0x5e, 0xb8, 0x8d, 0x83, 0x22, 0x57, + 0xa9, 0x3a, 0x3d, 0x85, 0xbe, 0x20, 0x41, 0x66, 0x64, 0xdb, 0x1d, 0xc2, 0x05, 0xf1, 0x58, 0x44, + 0x29, 0x2e, 0x4f, 0x95, 0x17, 0x72, 0xe0, 0x5a, 0x70, 0x83, 0x52, 0xca, 0xb4, 0xd5, 0xca, 0x2c, + 0xf9, 0x7c, 0x3b, 0x51, 0x2b, 0x8f, 0x11, 0xf6, 0x32, 0x5c, 0x36, 0xdf, 0xca, 0xa1, 0x03, 0x56, + 0xcb, 0x0b, 0x3f, 0xc1, 0x04, 0x6c, 0x12, 0x4c, 0x60, 0x54, 0x95, 0x72, 0x5c, 0x44, 0x58, 0xd5, + 0x2f, 0xc4, 0x99, 0x3d, 0x8b, 0x1f, 0x01, 0xd1, 0xf6, 0xf3, 0xf2, 0xf3, 0xde, 0x80, 0x14, 0xc2, + 0xc6, 0x31, 0x57, 0x16, 0xc3, 0x30, 0x91, 0x04, 0x98, 0xa0, 0xaf, 0x34, 0xf8, 0xe5, 0x8c, 0x20, + 0x24, 0x29, 0x01, 0xba, 0x1f, 0xa6, 0xd8, 0x3c, 0xec, 0xd4, 0x2e, 0xf9, 0xfa, 0x68, 0x95, 0xb2, + 0xec, 0xb6, 0x91, 0x6c, 0xac, 0x1f, 0xdb, 0x15, 0xc4, 0x9e, 0xf5, 0xce, 0x65, 0xa5, 0xd6, 0xbe, + 0x13, 0x25, 0x8d, 0x89, 0x53, 0x65, 0x7f, 0x37, 0x55, 0x5c, 0x92, 0x7a, 0x0c, 0xd9, 0x3e, 0x12, + 0xad, 0xbd, 0x81, 0xb2, 0x31, 0x7f, 0x1b, 0xd4, 0x6b, 0x28, 0xba, 0x30, 0xe0, 0x9c, 0x3e, 0x56, + 0x63, 0xeb, 0x3d, 0xc5, 0xa1, 0xf6, 0xc9, 0x49, 0x9f, 0xc4, 0x02, 0xa9, 0x24, 0x60, 0xcf, 0x71, + 0xd0, 0xe6, 0x02, 0xa9, 0x98, 0x26, 0xed, 0xac, 0x1f, 0x47, 0xef, 0x8d, 0xb3, 0x23, 0x3d, 0x11, + 0xae, 0x90, 0xc9, 0x79, 0xd2, 0x64, 0x54, 0x8c, 0x65, 0x82, 0x06, 0x8a, 0x2e, 0x21, 0xa7, 0xc6, + 0x70, 0x99, 0x2b, 0x6d, 0xb5, 0xfc, 0xdd, 0xdf, 0xc3, 0x3b, 0xd3, 0x5f, 0x56, 0xd6, 0x2b, 0x94, + 0x8f, 0x78, 0x8e, 0xae, 0xf8, 0xae, 0xad, 0x2e, 0xbe, 0x2f, 0x56, 0xeb, 0xa9, 0x38, 0xdb, 0x5a, + 0xde, 0x1c, 0x69, 0x3c, 0xcb, 0x48, 0x2d, 0x4b, 0x01, 0x20, 0x7a, 0x8c, 0xc9, 0x0d, 0x38, 0x71, + 0xb9, 0x88, 0xb8, 0x42, 0x88, 0x8d, 0xbc, 0xc2, 0x29, 0x7f, 0x25, 0x02, 0xf4, 0x59, 0xc4, 0x88, + 0x05, 0x94, 0x03, 0x0c, 0xa6, 0x71, 0x8c, 0x66, 0xc2, 0x45, 0x53, 0x67, 0xfc, 0xf6, 0x15, 0x69, + 0xfe, 0x08, 0x44, 0x02, 0x2c, 0x81, 0xd4, 0x35, 0xc7, 0xae, 0x18, 0x08, 0x8d, 0x9c, 0xc1, 0xe8, + 0x0f, 0x1e, 0xfe, 0x2f, 0x71, 0x05, 0x1c, 0xe4, 0xe0, 0xa5, 0x13, 0x4b, 0x3b, 0x02, 0xe9, 0xc0, + 0xb7, 0x61, 0x46, 0x89, 0x87, 0x58, 0x8a, 0xf6, 0x91, 0xec, 0x61, 0x43, 0x40, 0x81, 0x1f, 0x9f, + 0xd3, 0xc1, 0xc0, 0x91, 0xb5, 0x74, 0x2f, 0x5b, 0xd5, 0x95, 0x50, 0x1a, 0x1d, 0x43, 0xd6, 0x07, + 0x22, 0xee, 0xc6, 0x11, 0xe4, 0xbf, 0x0e, 0x45, 0x72, 0x9b, 0x22, 0xcd, 0x4f, 0x81, 0x49, 0x36, + 0x0d, 0x15, 0x2f, 0x19, 0x43, 0xf3, 0xef, 0x86, 0xca, 0x0b, 0x00, 0x20, 0x24, 0x48, 0x68, 0x90, + 0x5c, 0x71, 0x20, 0xa0, 0x35, 0x07, 0x32, 0x45, 0x80, 0x37, 0x61, 0x66, 0x6d, 0x42, 0xac, 0x9e, + 0x1b, 0x6e, 0x35, 0xc7, 0x90, 0xf8, 0x25, 0xcc, 0x48, 0xe3, 0x52, 0xe3, 0x96, 0x31, 0x59, 0xf3, + 0x10, 0x24, 0x75, 0xcb, 0x4b, 0xd1, 0xde, 0x37, 0x21, 0x7e, 0x4c, 0xf1, 0x93, 0x25, 0x37, 0x6a, + 0x5d, 0x9c, 0xec, 0x31, 0x59, 0xf9, 0x88, 0x21, 0xf9, 0xbd, 0x61, 0xc3, 0x1c, 0x4d, 0xbe, 0x2f, + 0xac, 0x48, 0xef, 0x75, 0xc1, 0x6d, 0xad, 0x5a, 0x67, 0x2a, 0x2e, 0xbe, 0x38, 0x4e, 0xea, 0xa5, + 0x67, 0xcb, 0x0f, 0x82, 0x4e, 0x46, 0x58, 0xfa, 0x08, 0xf8, 0x4c, 0xcb, 0x63, 0xd6, 0x97, 0x82, + 0x7b, 0xab, 0x9f, 0xbd, 0x9d, 0x8b, 0x7a, 0xc4, 0x13, 0x8a, 0xeb, 0xe3, 0xae, 0x51, 0xe8, 0xf6, + 0x52, 0xa8, 0xe1, 0x05, 0x99, 0xea, 0xaa, 0x19, 0x85, 0x29, 0x83, 0x4e, 0x3c, 0xe0, 0xf3, 0x80, + 0x0e, 0x8a, 0x0b, 0x84, 0x38, 0x96, 0x9d, 0x61, 0x70, 0x61, 0x60, 0x1b, 0x4d, 0x75, 0x70, 0x4e, + 0x63, 0x0e, 0xe0, 0x4b, 0x4c, 0x3d, 0x75, 0x30, 0x16, 0x8b, 0x5f, 0xfb, 0x8b, 0xfd, 0x31, 0xe2, + 0x83, 0x41, 0x8f, 0x7c, 0xa7, 0x57, 0x0f, 0x2e, 0xcd, 0x4a, 0x02, 0xf1, 0x88, 0xe0, 0xcb, 0x53, + 0xf4, 0xee, 0x4a, 0x2d, 0x04, 0x21, 0x40, 0x1a, 0x8c, 0x3a, 0x20, 0xb5, 0x01, 0x7e, 0x0c, 0xfc, + 0x2d, 0x24, 0x17, 0x1a, 0x78, 0xbc, 0x3c, 0x56, 0x60, 0x08, 0xc6, 0x4c, 0x0a, 0x65, 0x6c, 0x38, + 0x86, 0x3e, 0x79, 0x78, 0x7b, 0xd0, 0x87, 0xb8, 0x07, 0x40, 0x74, 0xf7, 0xb7, 0x96, 0xbe, 0x6c, + 0xfe, 0x09, 0xc4, 0x25, 0xbe, 0xab, 0xaf, 0xbe, 0xec, 0xfc, 0x85, 0x5d, 0x7c, 0x29, 0x10, 0x00, + 0xf3, 0x87, 0x09, 0x81, 0x54, 0x00, 0x00, 0x55, 0x47, 0x88, 0x1c, 0xd6, 0x09, 0x5e, 0x8c, 0xa4, + 0x78, 0x74, 0x00, 0x05, 0xd4, 0xb1, 0x9e, 0x38, 0x30, 0x46, 0x28, 0xca, 0x09, 0x7a, 0xb3, 0x83, + 0x92, 0x7c, 0x34, 0xe0, 0x07, 0xd0, 0x51, 0x1a, 0xae, 0xfc, 0x8e, 0xa9, 0x7f, 0xcf, 0xe1, 0x77, + 0x0c, 0x57, 0x3d, 0x65, 0x07, 0x51, 0xde, 0x85, 0xdb, 0x39, 0x77, 0x2e, 0xc4, 0x3c, 0x5d, 0x00, + 0x3e, 0x13, 0xac, 0x5c, 0x9d, 0x56, 0x81, 0x85, 0x7b, 0xbb, 0x54, 0xdf, 0x29, 0x52, 0xb7, 0x5c, + 0x54, 0xea, 0xaa, 0x9e, 0x92, 0xae, 0x6b, 0xee, 0x12, 0xe0, 0x94, 0x83, 0xf9, 0x7e, 0x56, 0x37, + 0x2b, 0x84, 0xe1, 0xc4, 0x21, 0xdf, 0x4d, 0xc4, 0x00, 0xf6, 0x33, 0x80, 0x7f, 0x8c, 0x84, 0xdf, + 0x61, 0xfc, 0x91, 0x36, 0x3f, 0xc9, 0x3c, 0x97, 0x9e, 0x0f, 0x77, 0x3d, 0xe5, 0xe5, 0x9a, 0x8b, + 0xdf, 0x21, 0x52, 0x2f, 0x5f, 0x84, 0xc8, 0xb5, 0x27, 0x4f, 0x2b, 0x0f, 0xb2, 0xd2, 0x31, 0x18, + 0x66, 0xee, 0x95, 0xa4, 0x20, 0xb7, 0x28, 0x89, 0xbe, 0x3f, 0x94, 0xf7, 0x77, 0xf2, 0x75, 0x5f, + 0x44, 0xef, 0x92, 0x78, 0x13, 0x03, 0x47, 0x39, 0xfc, 0x40, 0x50, 0xb5, 0x89, 0xe1, 0xfe, 0x58, + 0x73, 0x59, 0x18, 0x2c, 0x33, 0x72, 0x42, 0xaa, 0x9a, 0xc3, 0xc6, 0xf2, 0x72, 0x90, 0xb7, 0xfc, + 0x22, 0x46, 0x8d, 0x05, 0x95, 0x30, 0x60, 0x2c, 0x7b, 0x33, 0xfd, 0x89, 0x7a, 0x71, 0xdd, 0x62, + 0x93, 0x93, 0x5a, 0xfb, 0x29, 0x3f, 0x88, 0xe0, 0x88, 0x97, 0x77, 0x8b, 0xe0, 0x98, 0x8f, 0x7b, + 0xa4, 0xe7, 0xf5, 0xf3, 0x4f, 0xdb, 0xc9, 0xcc, 0x2d, 0xdf, 0x5c, 0xbd, 0x99, 0xb0, 0xfc, 0x45, + 0x6b, 0x77, 0xb9, 0xbb, 0x14, 0xa7, 0x1f, 0x55, 0xc9, 0xca, 0x42, 0x42, 0x1f, 0x17, 0xb6, 0xc1, + 0xad, 0x31, 0xf2, 0x66, 0x83, 0xf1, 0xfc, 0xf2, 0xcf, 0x8c, 0x05, 0x54, 0xe0, 0x82, 0x50, 0x01, + 0x8b, 0xc1, 0x2e, 0xce, 0x10, 0x05, 0x3e, 0x60, 0xc1, 0x58, 0x05, 0xd0, 0xdf, 0x31, 0x55, 0xaf, + 0xcb, 0x5a, 0xcb, 0xcb, 0x5a, 0x9a, 0x81, 0x2e, 0x37, 0x57, 0xed, 0x87, 0x9f, 0xda, 0x3a, 0x49, + 0xcb, 0x39, 0x03, 0x3b, 0x84, 0xe8, 0xdc, 0x7d, 0xcd, 0xff, 0x0a, 0x74, 0x14, 0x4e, 0x48, 0xa4, + 0x7a, 0x28, 0x2e, 0xf7, 0x0c, 0x38, 0x7b, 0xc6, 0x1a, 0x82, 0x6a, 0x5d, 0x89, 0x8c, 0x95, 0x18, + 0x49, 0xc1, 0x31, 0x0d, 0x06, 0x69, 0x4a, 0xc2, 0x04, 0xde, 0x08, 0x6b, 0x93, 0x99, 0x44, 0xbc, + 0x17, 0x57, 0x5b, 0xdd, 0xb6, 0x42, 0x5c, 0x93, 0xe7, 0xae, 0xca, 0x74, 0x4d, 0xa1, 0x7c, 0x85, + 0xb4, 0xf3, 0x72, 0x5e, 0xf1, 0xfc, 0x14, 0xd5, 0x56, 0xc7, 0x54, 0xef, 0x69, 0xa2, 0x39, 0x69, + 0xad, 0x33, 0xf3, 0x1d, 0x27, 0xb8, 0x6f, 0x94, 0x43, 0xef, 0xe5, 0xbe, 0xe3, 0x78, 0x47, 0xbb, + 0xad, 0x6e, 0xde, 0x09, 0x38, 0xbd, 0x86, 0xec, 0x9d, 0xed, 0x78, 0xbd, 0x07, 0x3f, 0x7e, 0xfe, + 0x42, 0xee, 0xe1, 0x3e, 0x4a, 0x8b, 0xd4, 0xdc, 0x5c, 0xcc, 0x13, 0x23, 0x39, 0xa7, 0x98, 0x9e, + 0xba, 0x87, 0x39, 0xbb, 0xb8, 0x13, 0x3a, 0x33, 0xc0, 0xaf, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x50, 0x28, 0x30, 0xeb, 0x02, 0x88, 0x64, 0x68, 0xf1, 0x40, 0x00, 0x40, 0xea, 0x28, 0x00, 0x08, + 0x1d, 0x40, 0xe9, 0x80, 0x00, 0x82, 0xb3, 0x20, 0xe9, 0x80, 0x00, 0x82, 0xb3, 0x21, 0x40, 0x00, + 0x40, 0xda, 0x07, 0x40, 0x00, 0x40, 0x0c, 0x00, 0x04, 0x19, 0xa8, 0x1d, 0x30, 0x00, 0x10, 0x54, + 0x64, 0x07, 0x4d, 0x90, 0x00, 0xc0, 0x00, 0x41, 0xc8, 0x10, 0xe6, 0x00, 0x01, 0x04, 0x8f, 0x07, + 0x30, 0x00, 0x08, 0x24, 0x78, 0x3a, 0x00, 0xc0, 0x00, 0x41, 0x51, 0x90, 0x74, 0x01, 0x80, 0x00, + 0x82, 0xa3, 0x20, 0xe6, 0x00, 0x01, 0x04, 0xaf, 0x18, 0x93, 0x40, 0xb8, 0x00, 0x08, 0x21, 0x56, + 0x83, 0xa0, 0x18, 0x00, 0x08, 0x2a, 0x32, 0x9e, 0x21, 0x00, 0x00, 0x81, 0xf0, 0x40, 0xd0, 0x00, + 0x10, 0x2a, 0x01, 0xd0, 0x00, 0x10, 0x05, 0x1b, 0x0b, 0x9c, 0x08, 0x3a, 0x53, 0x72, 0x61, 0x40, + 0x70, 0x24, 0x74, 0xab, 0xf4, 0x6e, 0x3a, 0xb8, 0xd0, 0x14, 0x65, 0x1b, 0x20, 0x03, 0x67, 0xa1, + 0x83, 0x47, 0x87, 0x31, 0xc0, 0x71, 0xb1, 0x21, 0xb0, 0x03, 0xc8, 0xee, 0x32, 0x28, 0x00, 0xe3, + 0xf4, 0x8f, 0x97, 0xf1, 0xe5, 0x87, 0x30, 0x26, 0x62, 0x9f, 0x9d, 0xfe, 0xdb, 0x6d, 0xb7, 0xe5, + 0x4e, 0x9a, 0x7f, 0x08, 0xa8, 0x22, 0x50, 0x0c, 0x38, 0x76, 0x22, 0x4b, 0xf6, 0xdb, 0x87, 0x62, + 0x80, 0x34, 0x00, 0x92, 0x81, 0x80, 0x13, 0xaa, 0x51, 0x75, 0x17, 0xf5, 0x17, 0x17, 0x5f, 0x07, + 0x04, 0x12, 0x0c, 0x40, 0x3b, 0xde, 0xb5, 0xc6, 0xc2, 0x60, 0xf7, 0x03, 0xa1, 0x80, 0x00, 0xa8, + 0x8f, 0x1b, 0x81, 0xa3, 0xdc, 0x8f, 0xc4, 0x78, 0x8f, 0x11, 0x20, 0x3a, 0xb2, 0x26, 0x70, 0xd3, + 0xd1, 0x3e, 0x27, 0xc4, 0xe1, 0xbf, 0x44, 0xf8, 0x9c, 0x34, 0xf4, 0x4e, 0x1b, 0xf4, 0x6c, 0x80, + 0x68, 0xf7, 0x0e, 0xd8, 0x9c, 0x0d, 0x1e, 0xe8, 0x8f, 0x1b, 0x81, 0xa3, 0xdc, 0x3b, 0x1f, 0x89, + 0x94, 0x3e, 0x1e, 0x89, 0x8d, 0x14, 0x00, 0x09, 0x62, 0x63, 0x81, 0xd7, 0x91, 0x98, 0x6f, 0xc3, + 0xb6, 0x37, 0x05, 0xc4, 0x01, 0x72, 0x3f, 0x1b, 0x83, 0xa0, 0x5c, 0x76, 0xc4, 0xe0, 0xeb, 0xc8, + 0xdc, 0x0e, 0xb1, 0x2a, 0x3f, 0x13, 0x87, 0xbd, 0x13, 0x20, 0xa2, 0xa3, 0x70, 0x35, 0x97, 0x0f, + 0x2c, 0x66, 0x1e, 0x1e, 0x1d, 0x2c, 0x46, 0x0e, 0xbc, 0x8c, 0xc0, 0x4f, 0xfb, 0x7e, 0x23, 0xb8, + 0x8c, 0x0d, 0xcf, 0xa2, 0x30, 0xf0, 0xf4, 0x44, 0xe1, 0xc7, 0xa2, 0x7c, 0x4e, 0x0e, 0xac, 0x8c, + 0xe8, 0xfc, 0x64, 0xc0, 0x75, 0x1a, 0xa3, 0xb8, 0x9c, 0x0d, 0x61, 0xf4, 0x46, 0x0f, 0x0f, 0xc6, + 0x4b, 0x1f, 0x63, 0x38, 0xed, 0x8c, 0x90, 0x37, 0xe1, 0xe5, 0x8d, 0xc0, 0xd7, 0x17, 0x0e, 0x96, + 0x23, 0xc6, 0x4b, 0x47, 0xe3, 0x58, 0x80, 0x75, 0x0c, 0x49, 0x6e, 0x29, 0xc3, 0x48, 0xc0, 0x05, + 0x27, 0xe8, 0x83, 0x56, 0xed, 0x7f, 0xfb, 0x6d, 0xb6, 0xdc, 0x89, 0xd4, 0x34, 0xa0, 0x4a, 0x1e, + 0x0d, 0xc7, 0xfb, 0x6d, 0xfe, 0x25, 0xa3, 0xa8, 0x61, 0x42, 0xb6, 0xbf, 0xfa, 0x69, 0xd3, 0xa7, + 0xf3, 0x1a, 0x8e, 0x01, 0x3b, 0x47, 0x55, 0x78, 0x34, 0x50, 0x6e, 0x16, 0x39, 0x14, 0x05, 0x1a, + 0x39, 0x55, 0x11, 0x69, 0x8d, 0xc0, 0x41, 0x9a, 0x51, 0xe0, 0xd4, 0xe4, 0x50, 0xe4, 0x70, 0x00, + 0x15, 0x40, 0xee, 0x66, 0x70, 0x57, 0x04, 0xdf, 0xc6, 0xee, 0xf1, 0x57, 0x8a, 0xb6, 0xff, 0xc4, + 0x27, 0x07, 0x54, 0xbc, 0x5b, 0xb9, 0xb9, 0xbf, 0x0e, 0xe0, 0x02, 0xfc, 0x39, 0x74, 0x56, 0x0b, + 0xda, 0x2f, 0xf6, 0xed, 0x8a, 0xb6, 0xe2, 0xad, 0xb0, 0xd9, 0x40, 0xc7, 0x69, 0xd3, 0x4f, 0x6d, + 0xb8, 0xd8, 0xd0, 0x13, 0x33, 0xc4, 0xfc, 0x01, 0xa0, 0x6b, 0xe3, 0x08, 0x50, 0xe3, 0xd1, 0x8c, + 0x66, 0x1a, 0x79, 0x2b, 0x8c, 0x45, 0x0e, 0xf8, 0x68, 0xa1, 0xf8, 0x85, 0x07, 0x56, 0x44, 0x2e, + 0x30, 0x86, 0x07, 0x5e, 0x09, 0x69, 0x8c, 0x24, 0x3b, 0xec, 0xb1, 0x0a, 0x0e, 0xac, 0x88, 0x50, + 0xef, 0xa2, 0x14, 0x34, 0xf4, 0x52, 0x86, 0xcc, 0x44, 0x62, 0x28, 0x80, 0xd0, 0x71, 0x8f, 0xc6, + 0x28, 0x42, 0x84, 0xbd, 0x8c, 0x50, 0xe3, 0xff, 0x63, 0x14, 0x2b, 0xc7, 0x63, 0x14, 0x1c, 0x96, + 0x0e, 0x31, 0xf8, 0xc5, 0x0b, 0x87, 0x1d, 0x8c, 0x54, 0xbb, 0x18, 0xa9, 0x76, 0x2d, 0x43, 0xde, + 0xec, 0x41, 0x20, 0xea, 0xf1, 0xe8, 0x7c, 0x70, 0x1b, 0xfa, 0x69, 0xc5, 0xa1, 0xc2, 0x86, 0x3b, + 0x1f, 0x84, 0x10, 0xfa, 0x55, 0xfb, 0x4d, 0x4e, 0x86, 0x06, 0xc0, 0x0f, 0x44, 0x28, 0x63, 0xd1, + 0x4a, 0x1b, 0x61, 0x88, 0x59, 0x0d, 0x07, 0x24, 0x45, 0x34, 0xf4, 0xd3, 0xf4, 0xd3, 0xd3, 0x4e, + 0x21, 0x0c, 0x0d, 0xfa, 0x38, 0x84, 0x29, 0x54, 0x7e, 0x39, 0x46, 0xdd, 0x28, 0xee, 0x29, 0x47, + 0xd0, 0xe2, 0x14, 0x20, 0x55, 0x36, 0x00, 0xb0, 0x00, 0x60, 0x82, 0x9b, 0xbb, 0xbb, 0xbb, 0xbe, + 0x6c, 0x36, 0x0c, 0x00, 0x01, 0x00, 0xc8, 0xc1, 0xc4, 0xa2, 0x87, 0xbd, 0x10, 0xa1, 0xa7, 0xa2, + 0x97, 0x1c, 0x42, 0x51, 0xf8, 0x85, 0x07, 0x7c, 0x8c, 0x5a, 0x3b, 0x8e, 0x50, 0xc8, 0x61, 0x21, + 0xe4, 0x7e, 0x39, 0x42, 0xb6, 0xc1, 0x16, 0x98, 0x82, 0x10, 0x10, 0x0f, 0xc8, 0xa2, 0x94, 0x1f, + 0x11, 0x86, 0xd8, 0x80, 0x05, 0x47, 0x33, 0x1f, 0x00, 0x06, 0x9a, 0x6d, 0xb6, 0xdb, 0x6c, 0x55, + 0xff, 0xe1, 0xe0, 0xe3, 0x83, 0x4d, 0x3f, 0xe1, 0xc4, 0x50, 0x04, 0x24, 0xd9, 0x94, 0x9f, 0xbc, + 0x9a, 0x78, 0xb6, 0x29, 0x7f, 0xf9, 0xd6, 0xb6, 0xdf, 0xf1, 0x8a, 0x0a, 0x23, 0x9b, 0x0e, 0x8c, + 0xa3, 0x94, 0x2c, 0xe4, 0x8d, 0xa8, 0xb6, 0x70, 0x06, 0x8b, 0xa6, 0xa3, 0xc8, 0x97, 0x8a, 0x7c, + 0xe8, 0xc0, 0x58, 0x90, 0x64, 0x88, 0xe5, 0x01, 0x89, 0x35, 0x59, 0xec, 0x3a, 0xa0, 0x02, 0x17, + 0x5d, 0xd8, 0xa3, 0x7e, 0x79, 0xb8, 0xed, 0xd3, 0xff, 0xc3, 0x98, 0x28, 0x6a, 0x77, 0x77, 0xfc, + 0x3d, 0x10, 0x00, 0x65, 0x01, 0x54, 0x48, 0x2a, 0xb1, 0x7d, 0xd1, 0xbe, 0x6f, 0xfe, 0x6f, 0x9b, + 0x9c, 0xc4, 0xbf, 0x2f, 0x6d, 0x55, 0xb8, 0x5d, 0x8b, 0x00, 0x33, 0xfa, 0xe3, 0x11, 0x7f, 0xdf, + 0xed, 0xdd, 0xd7, 0xfb, 0x1a, 0x82, 0xb4, 0x70, 0x71, 0x08, 0x60, 0x3a, 0xb2, 0x75, 0x0d, 0xfa, + 0x75, 0x07, 0x57, 0x8c, 0x8d, 0xa3, 0x87, 0x10, 0x86, 0x07, 0xc3, 0xd1, 0x88, 0x80, 0x63, 0xae, + 0x1d, 0xb1, 0x0a, 0x19, 0x3d, 0x10, 0xb8, 0x85, 0x14, 0xe2, 0x14, 0x32, 0x7a, 0x31, 0x41, 0xd5, + 0xc7, 0x63, 0xf1, 0x0a, 0x02, 0x27, 0xf4, 0xfc, 0x87, 0x10, 0xe0, 0x02, 0x12, 0x46, 0x51, 0xb0, + 0x62, 0x1f, 0x97, 0xe3, 0x78, 0x17, 0x6f, 0x79, 0xcc, 0x0f, 0x0c, 0x10, 0x85, 0x89, 0xa2, 0x09, + 0x48, 0xc0, 0x95, 0x49, 0xe2, 0x9f, 0x15, 0xc3, 0x72, 0x00, 0x0e, 0x03, 0xa1, 0xbe, 0x73, 0x79, + 0x8d, 0x1f, 0xfb, 0x15, 0xaf, 0x14, 0xfd, 0xf1, 0x44, 0xb8, 0x86, 0xfc, 0x5b, 0x72, 0xa9, 0x60, + 0x72, 0xfc, 0xfd, 0x01, 0x84, 0x7c, 0xd2, 0xfb, 0xaa, 0x33, 0xc6, 0xf8, 0x66, 0xf1, 0x6c, 0x26, + 0x0e, 0x20, 0x58, 0x38, 0xd8, 0x92, 0x14, 0x3d, 0xe8, 0xb5, 0x07, 0xae, 0x3b, 0x67, 0x5c, 0xea, + 0x1c, 0x7a, 0x75, 0x07, 0x5f, 0x9d, 0x90, 0x3e, 0xf4, 0x5a, 0x81, 0xd6, 0x4a, 0x3b, 0x63, 0x94, + 0xf2, 0x1e, 0x58, 0xe4, 0x50, 0xad, 0x90, 0x8b, 0x4c, 0x74, 0xc5, 0x22, 0x46, 0xc4, 0x12, 0x3f, + 0x9c, 0x6a, 0x38, 0x7b, 0xd9, 0x22, 0x8d, 0x8d, 0x81, 0xc4, 0xa6, 0x31, 0x0c, 0x07, 0x5e, 0x0e, + 0xd8, 0x84, 0x40, 0x75, 0x64, 0x52, 0x86, 0x58, 0x67, 0x01, 0x00, 0x02, 0x45, 0x46, 0x00, 0x00, + 0x80, 0x02, 0x18, 0xe3, 0x54, 0x1d, 0x5a, 0x44, 0xce, 0xa0, 0xf5, 0xe7, 0x52, 0xca, 0x29, 0x48, + 0x41, 0x88, 0x27, 0x18, 0xa1, 0x50, 0x38, 0xcb, 0x14, 0xa1, 0x0d, 0x57, 0x11, 0x8a, 0x1f, 0x3c, + 0x25, 0xa1, 0xf8, 0xc2, 0x40, 0xeb, 0x25, 0xec, 0x42, 0xe2, 0xe4, 0x00, 0x60, 0x6a, 0xc8, 0x03, + 0xef, 0xb1, 0xe3, 0x42, 0xa3, 0x94, 0x11, 0x15, 0xd5, 0xc8, 0x2f, 0x8e, 0x45, 0x00, 0x89, 0xad, + 0xb1, 0xd2, 0x25, 0x28, 0xc9, 0x40, 0xc0, 0x6e, 0xe1, 0xf2, 0x28, 0xa9, 0x07, 0xb2, 0x8e, 0x50, + 0x46, 0x6e, 0xa8, 0x7d, 0x8e, 0x21, 0x80, 0x45, 0xe3, 0xe7, 0xf5, 0x0f, 0xb1, 0x64, 0x81, 0x61, + 0x44, 0x48, 0x22, 0x62, 0xd1, 0x40, 0x4b, 0xbe, 0x8f, 0x0d, 0xd8, 0x6d, 0xc0, 0x0c, 0x3d, 0x97, + 0x80, 0xc2, 0x17, 0xe7, 0x77, 0x78, 0xae, 0x2b, 0x77, 0x77, 0x8a, 0xe2, 0xb1, 0x83, 0x11, 0xf5, + 0xab, 0xdf, 0x0f, 0x46, 0x00, 0x8f, 0x22, 0x3d, 0x80, 0x9c, 0x27, 0x5f, 0xad, 0x7c, 0x54, 0x8a, + 0x9e, 0xff, 0x8e, 0x61, 0x38, 0xec, 0x7e, 0x21, 0x71, 0x0b, 0x88, 0x44, 0x0d, 0xfa, 0x29, 0x43, + 0x26, 0x22, 0x39, 0x43, 0x39, 0x11, 0xf8, 0xa5, 0x21, 0x18, 0xc4, 0x51, 0x2e, 0x0e, 0xd8, 0xa5, + 0x03, 0xd8, 0x96, 0x39, 0x49, 0x01, 0xd8, 0xfc, 0x52, 0x85, 0x2e, 0x88, 0xa5, 0x0c, 0x06, 0x18, + 0x8a, 0x50, 0xa1, 0xca, 0x1d, 0x63, 0x80, 0x02, 0x10, 0x7b, 0x8d, 0x32, 0xdc, 0xfe, 0x62, 0x91, + 0xb5, 0x29, 0xf7, 0xfc, 0x41, 0x51, 0xec, 0x4b, 0x08, 0x96, 0x14, 0x54, 0x50, 0xf3, 0x14, 0x04, + 0xc9, 0x91, 0x12, 0x18, 0x07, 0xca, 0x64, 0x0d, 0x7e, 0x60, 0x87, 0xdd, 0xa0, 0x7d, 0x62, 0x7c, + 0x91, 0xc1, 0x66, 0xa7, 0x10, 0x80, 0xec, 0x78, 0x52, 0x60, 0x1c, 0x16, 0x70, 0x8b, 0xc9, 0x01, + 0x3c, 0x6f, 0xcd, 0x56, 0xd5, 0xe1, 0xb7, 0x00, 0x31, 0x12, 0x22, 0x20, 0x0c, 0x2a, 0x98, 0x25, + 0x9f, 0xef, 0x12, 0x0f, 0x67, 0x03, 0xfe, 0x48, 0xe0, 0x99, 0xd2, 0xce, 0x07, 0xfc, 0x01, 0x04, + 0x15, 0xbd, 0xeb, 0x5c, 0x20, 0x40, 0xb8, 0x1c, 0x01, 0xcc, 0xa8, 0x87, 0x5f, 0xa6, 0x9c, 0x71, + 0x08, 0x6c, 0x8b, 0x10, 0xa3, 0x45, 0x9c, 0x42, 0xe3, 0x94, 0x30, 0xc4, 0xdb, 0x1c, 0x48, 0x65, + 0x86, 0x72, 0xc7, 0x22, 0x8a, 0x63, 0x8c, 0xaa, 0x31, 0x4a, 0x41, 0xec, 0x5a, 0x82, 0x3b, 0x73, + 0xcf, 0xc7, 0xe3, 0x94, 0x6d, 0xd3, 0xd8, 0xc2, 0x41, 0xff, 0x3a, 0x62, 0x14, 0x6b, 0x38, 0x85, + 0x1c, 0xce, 0x21, 0x71, 0x0a, 0x0f, 0xfc, 0x52, 0xe1, 0x14, 0x3e, 0xbf, 0xa6, 0x9c, 0xf0, 0x80, + 0x7b, 0xd1, 0x78, 0x3a, 0xb1, 0x22, 0x88, 0x50, 0x7b, 0xf1, 0x0b, 0x8c, 0x50, 0x75, 0x71, 0xdb, + 0x1c, 0xa2, 0x00, 0x90, 0x51, 0xf8, 0x85, 0x00, 0x71, 0xe6, 0xd3, 0xf1, 0x1c, 0x88, 0x14, 0x3a, + 0x76, 0x29, 0x46, 0x9a, 0x23, 0x14, 0x77, 0xc9, 0x94, 0x5c, 0xe1, 0x80, 0x00, 0x78, 0xf1, 0xc0, + 0x38, 0x59, 0x0d, 0x01, 0xc7, 0x0c, 0x54, 0x2f, 0xff, 0xbd, 0xf1, 0x91, 0x81, 0xf7, 0x87, 0xc7, + 0xe3, 0x18, 0xd8, 0xe0, 0xd8, 0xc4, 0x30, 0x1e, 0xfa, 0x3f, 0x1c, 0xc8, 0x3e, 0x70, 0x6c, 0x51, + 0x20, 0x76, 0x34, 0x28, 0xd7, 0x04, 0x4d, 0x27, 0xed, 0xf1, 0xa4, 0x82, 0xeb, 0xed, 0x3a, 0x8e, + 0x90, 0x4f, 0x9d, 0x15, 0xc2, 0xe4, 0x14, 0x00, 0x39, 0x3e, 0xc6, 0xc7, 0x28, 0x61, 0xfe, 0xfd, + 0x77, 0xbc, 0xde, 0x6e, 0x55, 0x98, 0x65, 0x8b, 0x00, 0x33, 0xfa, 0x8d, 0x19, 0x7e, 0xff, 0xd5, + 0x7f, 0x8f, 0xc6, 0x4b, 0x4a, 0xe2, 0x14, 0x32, 0xf4, 0x72, 0x85, 0x2d, 0x9d, 0x8c, 0x50, 0xd3, + 0xfb, 0x63, 0x94, 0xa4, 0x7b, 0x14, 0xa5, 0x21, 0x8a, 0x54, 0x0e, 0x31, 0x46, 0x98, 0xf6, 0x29, + 0x41, 0x55, 0x44, 0xa3, 0x09, 0x35, 0x95, 0x58, 0xe9, 0x43, 0x01, 0x84, 0x65, 0x8c, 0xc4, 0xc8, + 0x23, 0x83, 0x22, 0x87, 0x98, 0xc0, 0x37, 0xc9, 0x9f, 0x7b, 0xfc, 0x43, 0x08, 0x81, 0x87, 0x7e, + 0xb5, 0x87, 0x58, 0xc0, 0x00, 0xb8, 0x7f, 0x68, 0x81, 0xc8, 0x45, 0xde, 0x93, 0xfb, 0x85, 0xce, + 0x01, 0xe2, 0xe0, 0xfe, 0x3f, 0x1e, 0x79, 0xe7, 0xc9, 0xe1, 0xe5, 0xea, 0xb4, 0x2c, 0xcb, 0x30, + 0x75, 0x4f, 0xc7, 0x9e, 0x56, 0x06, 0x80, 0xff, 0x1d, 0x92, 0xea, 0xeb, 0xbe, 0x17, 0x24, 0x02, + 0xb9, 0xd0, 0x68, 0x68, 0xee, 0xfb, 0x79, 0x0b, 0x84, 0xbe, 0x8c, 0x3e, 0x93, 0xc0, 0xf6, 0x73, + 0xc2, 0x78, 0xc2, 0x69, 0x71, 0xd0, 0xa8, 0x21, 0xa2, 0x9e, 0x63, 0xa1, 0xf8, 0xa5, 0x04, 0x0f, + 0x48, 0xd1, 0x48, 0x83, 0x0c, 0x62, 0x15, 0x02, 0x8a, 0xc6, 0x5d, 0x11, 0x88, 0xa0, 0x6f, 0xbb, + 0xb1, 0xc8, 0xa0, 0x83, 0x2a, 0xa4, 0x7e, 0x31, 0x10, 0x2e, 0x5a, 0x3b, 0x10, 0x8a, 0x00, 0xf3, + 0xaa, 0xe8, 0x89, 0x50, 0xf7, 0xa2, 0x08, 0x40, 0x35, 0xbe, 0x8c, 0x41, 0x10, 0x70, 0xb6, 0x0e, + 0x0c, 0x8a, 0x21, 0x04, 0x05, 0x15, 0x10, 0x48, 0x2d, 0x7d, 0x1c, 0xa3, 0x4e, 0x87, 0xc6, 0xa0, + 0x8d, 0x22, 0x89, 0x43, 0x03, 0xde, 0x89, 0x50, 0x75, 0x6c, 0x62, 0x31, 0x64, 0xd8, 0x85, 0xc5, + 0x29, 0x29, 0x18, 0xa6, 0xfd, 0x8a, 0x50, 0x3e, 0x99, 0x60, 0x38, 0x00, 0x6c, 0x82, 0x1e, 0xee, + 0x30, 0x00, 0x0c, 0x21, 0xc7, 0x81, 0x44, 0x0e, 0x00, 0x86, 0xef, 0x8c, 0x00, 0x03, 0x48, 0x68, + 0x0a, 0xc0, 0x54, 0x81, 0x80, 0x10, 0xdd, 0xf1, 0xc0, 0x00, 0xd4, 0x70, 0x07, 0xea, 0x38, 0x00, + 0x1c, 0x8d, 0x00, 0x15, 0x17, 0x28, 0x64, 0x07, 0x84, 0x52, 0x63, 0x30, 0x75, 0x64, 0x58, 0xb4, + 0x3e, 0x22, 0x93, 0x3a, 0xe2, 0x17, 0x3a, 0x1c, 0x0d, 0xc8, 0x51, 0xa4, 0x80, 0xf6, 0x9c, 0xae, + 0xc4, 0xb3, 0x02, 0x01, 0x58, 0x74, 0x76, 0x0b, 0xb5, 0x4e, 0x63, 0x1a, 0x48, 0xab, 0xcb, 0x0b, + 0xe0, 0x1c, 0x06, 0x5e, 0x63, 0x9e, 0xf6, 0xef, 0xf1, 0x5c, 0x56, 0x04, 0x9d, 0x87, 0xa2, 0x80, + 0x1d, 0x93, 0xc4, 0x76, 0x72, 0xd7, 0xf5, 0xaf, 0x99, 0x15, 0x6f, 0xf8, 0xc2, 0x0f, 0x24, 0x72, + 0x55, 0x1c, 0xa0, 0x7f, 0x37, 0x76, 0x33, 0x36, 0x24, 0x51, 0xca, 0x30, 0xc4, 0x6a, 0xac, 0x62, + 0x8d, 0x31, 0x8b, 0x1c, 0xa0, 0x48, 0xce, 0x74, 0xf3, 0xa6, 0x31, 0x14, 0x98, 0x74, 0x3f, 0x10, + 0x88, 0x0e, 0xd9, 0x1c, 0xa4, 0x27, 0xd8, 0x85, 0x2e, 0x45, 0x29, 0x49, 0xc5, 0x22, 0x9a, 0x10, + 0xdb, 0x08, 0x00, 0x3d, 0x56, 0xc8, 0x3b, 0xff, 0xfb, 0x2f, 0x7e, 0xca, 0xca, 0x1b, 0x62, 0x80, + 0x00, 0xe1, 0xde, 0x95, 0xb3, 0x90, 0x04, 0x12, 0xf7, 0xdb, 0xcc, 0xe1, 0x1d, 0x3a, 0x74, 0x3c, + 0x00, 0xc0, 0x1d, 0x90, 0x1f, 0xbc, 0x48, 0x01, 0x82, 0x40, 0x00, 0x2a, 0x90, 0x24, 0x00, 0xc0, + 0x34, 0xf0, 0x1a, 0x6e, 0x3f, 0xf5, 0xac, 0x37, 0x80, 0x36, 0x61, 0xca, 0x04, 0x2e, 0x28, 0x33, + 0x3e, 0xd3, 0xbb, 0x21, 0x88, 0x0c, 0x14, 0xe3, 0x64, 0x4f, 0x0c, 0x48, 0x1f, 0x67, 0x80, 0x7a, + 0x8c, 0x13, 0x0e, 0x0e, 0xc0, 0xe0, 0x79, 0x93, 0x7e, 0xbc, 0x5b, 0x0b, 0x82, 0x17, 0x09, 0x3f, + 0x5c, 0x67, 0x10, 0xa1, 0xa7, 0xa2, 0x14, 0x3b, 0xe8, 0xc5, 0x36, 0x76, 0x21, 0x14, 0x1e, 0xb2, + 0x1a, 0x42, 0x01, 0x13, 0x94, 0xcb, 0xff, 0xf8, 0xab, 0xf6, 0x1d, 0x43, 0x00, 0x05, 0xe9, 0x86, + 0x42, 0x62, 0x95, 0x98, 0xa6, 0xed, 0x7f, 0xe3, 0xde, 0x17, 0x30, 0xdb, 0x68, 0x70, 0x33, 0x8e, + 0x06, 0x70, 0x3e, 0x62, 0x29, 0x62, 0xda, 0x7b, 0x6d, 0xc3, 0x84, 0x30, 0x00, 0xaf, 0x53, 0xc8, + 0x18, 0x0c, 0xc1, 0xef, 0xf5, 0xf9, 0xb4, 0x5b, 0x07, 0xdc, 0x1c, 0xdd, 0xdd, 0xdc, 0xa1, 0x94, + 0xa1, 0x94, 0xb5, 0x96, 0xb7, 0x3b, 0x6d, 0xdb, 0xa7, 0x0d, 0x28, 0x02, 0x71, 0xd2, 0x14, 0x44, + 0xda, 0x15, 0x62, 0xac, 0x1f, 0x72, 0xec, 0x55, 0x8a, 0xb1, 0x6c, 0xbf, 0x6f, 0xdb, 0x6f, 0x31, + 0x86, 0xf0, 0x00, 0xd9, 0x20, 0x05, 0x23, 0xf1, 0x09, 0x0a, 0xf9, 0x37, 0xb2, 0xff, 0x83, 0x97, + 0xc1, 0xcb, 0xed, 0xe5, 0x7f, 0x17, 0xc7, 0x0d, 0xe0, 0xe1, 0xbd, 0x7a, 0x7d, 0xb8, 0x5d, 0x8f, + 0x00, 0x0c, 0x3e, 0xbb, 0xd6, 0x65, 0xff, 0xf7, 0xfe, 0x07, 0x91, 0xf7, 0xe3, 0xb3, 0x28, 0xc4, + 0x26, 0xc6, 0x31, 0x14, 0x0d, 0x35, 0xc3, 0xb1, 0xf8, 0xd2, 0x41, 0xd5, 0xa7, 0x4c, 0x4a, 0x86, + 0x9e, 0x8a, 0x50, 0x7a, 0x84, 0x62, 0x35, 0xcc, 0x42, 0x84, 0x4d, 0x02, 0x71, 0x4a, 0x11, 0x34, + 0x0a, 0x47, 0x2b, 0x8e, 0xec, 0x42, 0xbc, 0x42, 0x84, 0x7e, 0x9f, 0xe0, 0x96, 0xee, 0x2b, 0x15, + 0xbb, 0xe3, 0x80, 0x01, 0x48, 0xd1, 0x5c, 0x0f, 0x00, 0x92, 0xab, 0x8d, 0x00, 0x03, 0x48, 0x60, + 0x2b, 0x0c, 0x82, 0x00, 0x49, 0x55, 0x55, 0x1c, 0x00, 0x0c, 0x46, 0x00, 0xae, 0x04, 0x00, 0x49, + 0xd5, 0x46, 0x80, 0x01, 0xc4, 0x30, 0x00, 0x15, 0x18, 0x49, 0xb3, 0x36, 0x7c, 0x04, 0xcc, 0xf6, + 0xfc, 0x84, 0x48, 0x13, 0xeb, 0x7b, 0xfc, 0x5f, 0x1c, 0x1b, 0x3b, 0xe2, 0xf8, 0xe0, 0xd8, 0xe4, + 0x12, 0x0a, 0xc4, 0xea, 0x6c, 0x5a, 0x80, 0x9b, 0xd1, 0xc7, 0xa3, 0x63, 0x1c, 0x32, 0xf6, 0xb1, + 0xae, 0x04, 0x5f, 0x27, 0xe6, 0x1a, 0x63, 0x8e, 0x30, 0x90, 0x35, 0x6b, 0xab, 0x1b, 0x80, 0x91, + 0x69, 0x38, 0xf1, 0x50, 0xbd, 0xc2, 0x71, 0x40, 0x5e, 0x68, 0xf3, 0xfe, 0xf7, 0xf8, 0xe6, 0x2c, + 0x39, 0x3f, 0xdc, 0x6c, 0x73, 0x90, 0x86, 0x2c, 0x72, 0x38, 0xa6, 0x22, 0xd3, 0x14, 0x88, 0x52, + 0x71, 0x98, 0x17, 0x75, 0x49, 0xb1, 0x8a, 0x34, 0xcb, 0xb1, 0x0a, 0x19, 0x0f, 0xa2, 0x14, 0x34, + 0xc4, 0xe3, 0x30, 0x62, 0xbd, 0xec, 0x42, 0x88, 0x24, 0x18, 0x85, 0x40, 0xe2, 0x11, 0x19, 0xc3, + 0x8c, 0x40, 0x00, 0xa7, 0xe9, 0xaf, 0x46, 0x27, 0x9f, 0x3c, 0x2c, 0xbe, 0x68, 0x44, 0x98, 0x02, + 0x19, 0x95, 0x6b, 0xf0, 0xdb, 0x30, 0x04, 0x18, 0x06, 0x9d, 0xd3, 0xbd, 0xde, 0xf8, 0xe9, 0x42, + 0x0c, 0x04, 0x97, 0x1d, 0xed, 0xdc, 0xa0, 0x24, 0xb8, 0xe5, 0x01, 0x25, 0xc9, 0x37, 0xef, 0x78, + 0x5c, 0x84, 0x00, 0xf3, 0x41, 0x07, 0x99, 0x67, 0x23, 0x4c, 0x4c, 0xe9, 0x58, 0xd6, 0x0d, 0x72, + 0xd9, 0x0c, 0xbc, 0x90, 0x64, 0x40, 0xee, 0x58, 0xe8, 0x07, 0x0b, 0x14, 0xe4, 0x53, 0x57, 0xc2, + 0xec, 0x68, 0x10, 0xa9, 0xc9, 0x70, 0xf0, 0xbe, 0x1f, 0x1d, 0x1c, 0x23, 0xa3, 0x87, 0xc7, 0x76, + 0x21, 0x71, 0x0b, 0x8e, 0x43, 0xc6, 0x19, 0x23, 0xf0, 0xe2, 0x08, 0x00, 0x08, 0x9e, 0xfe, 0x21, + 0xb9, 0x3f, 0xbd, 0xff, 0xf0, 0x77, 0xe2, 0x5e, 0x56, 0xb8, 0x04, 0x73, 0xc9, 0xff, 0x02, 0xc8, + 0x29, 0x0a, 0x0a, 0x08, 0x90, 0x09, 0x4f, 0x00, 0x02, 0xdc, 0x55, 0x04, 0x31, 0xa6, 0x00, 0xb8, + 0x2c, 0x00, 0x05, 0xb8, 0x78, 0x05, 0x8c, 0x06, 0x7c, 0xb2, 0x89, 0x80, 0x00, 0x85, 0x4e, 0x0d, + 0x0b, 0x28, 0xb2, 0x87, 0x8f, 0x96, 0x00, 0x0c, 0xe0, 0x78, 0xb4, 0x03, 0xe0, 0x68, 0x00, 0x90, + 0xd3, 0x86, 0x9c, 0x00, 0xc4, 0x87, 0xa1, 0x63, 0x10, 0x1c, 0xd5, 0xd8, 0xbb, 0x8e, 0xfb, 0x9f, + 0xbf, 0xb6, 0x7e, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x3b, 0xf3, 0x28, 0xc3, 0x11, 0x60, 0x12, 0x07, + 0x24, 0x68, 0x2e, 0x12, 0x5b, 0x37, 0xcb, 0x58, 0xab, 0xdb, 0x6f, 0xb6, 0xdf, 0x45, 0xe4, 0x32, + 0x8a, 0x00, 0xab, 0x44, 0xc3, 0x38, 0x4f, 0x4d, 0x3f, 0xfd, 0x98, 0x66, 0x30, 0x01, 0xe2, 0x67, + 0x72, 0x85, 0x41, 0x4a, 0x34, 0x7a, 0xc2, 0x8e, 0x3e, 0x3b, 0x9f, 0xfb, 0x98, 0x80, 0x9f, 0xe8, + 0x20, 0x01, 0x3f, 0xd7, 0xee, 0x21, 0x76, 0x50, 0x0f, 0x01, 0xb6, 0x94, 0xb4, 0xfa, 0xbf, 0x71, + 0x5b, 0xc6, 0x2a, 0x03, 0xf1, 0x7e, 0x79, 0xc5, 0x3f, 0xf6, 0x31, 0x02, 0x10, 0x70, 0xb6, 0x23, + 0x87, 0x1a, 0x87, 0x03, 0xab, 0x51, 0xf8, 0x85, 0xc7, 0x22, 0x03, 0x55, 0x93, 0x9c, 0x01, 0xe8, + 0x00, 0x50, 0x54, 0x68, 0x00, 0x18, 0x43, 0x47, 0x18, 0xa1, 0xf7, 0x8a, 0x98, 0xc5, 0x36, 0x15, + 0x31, 0x8a, 0x1d, 0xf7, 0x70, 0x04, 0xf0, 0x03, 0x04, 0x11, 0x1d, 0x57, 0x1a, 0x00, 0x02, 0x00, + 0x88, 0x70, 0x01, 0xc2, 0x08, 0x84, 0x8a, 0xfa, 0x69, 0xf1, 0x0a, 0x09, 0x9d, 0x4f, 0x46, 0x02, + 0x80, 0x10, 0x28, 0xd0, 0x00, 0x38, 0x86, 0x00, 0x0a, 0xe0, 0x40, 0x04, 0x95, 0x55, 0x51, 0xa0, + 0x00, 0x20, 0x04, 0x87, 0x00, 0x1c, 0x72, 0x85, 0x40, 0x0b, 0x61, 0xd1, 0x54, 0x62, 0x9e, 0xd2, + 0xa8, 0x85, 0x47, 0x17, 0x9a, 0x5d, 0x8a, 0xca, 0x4a, 0x39, 0x41, 0x17, 0xa4, 0x55, 0x8e, 0x53, + 0x90, 0xdf, 0x17, 0x86, 0x5e, 0x8b, 0x16, 0xe3, 0x79, 0x96, 0x6c, 0x5c, 0x9f, 0x62, 0xc8, 0x70, + 0x7b, 0xe0, 0xd7, 0x62, 0xc8, 0x20, 0x06, 0xb3, 0x55, 0xb3, 0x31, 0xca, 0x00, 0xa6, 0xf3, 0x60, + 0xa5, 0x40, 0xd7, 0xf0, 0x8a, 0x81, 0x30, 0x39, 0x29, 0x4e, 0x34, 0xd3, 0x4f, 0xf8, 0x75, 0x10, + 0x00, 0x93, 0xba, 0x63, 0x66, 0x2f, 0xbd, 0xb6, 0xdb, 0xff, 0x8b, 0x81, 0x52, 0xfb, 0x7c, 0x24, + 0x48, 0x16, 0x6b, 0x60, 0x4e, 0xcc, 0xd3, 0xd3, 0xed, 0xc3, 0xb8, 0x06, 0x8e, 0x83, 0xd3, 0x3f, + 0xfd, 0xb6, 0xdb, 0x6f, 0xc4, 0x52, 0x15, 0xf4, 0xd3, 0xdb, 0x6e, 0x32, 0x70, 0xd3, 0x2e, 0x87, + 0xfc, 0x66, 0x6e, 0x55, 0x63, 0x89, 0x2d, 0x7d, 0x8c, 0x56, 0xf2, 0xc7, 0x2a, 0x3f, 0x63, 0x09, + 0x6c, 0xab, 0x31, 0xc4, 0xb0, 0x5d, 0x88, 0x52, 0x11, 0x8a, 0x24, 0x7b, 0xd1, 0x8a, 0xa7, 0x51, + 0xc0, 0xf0, 0x03, 0x84, 0x2e, 0x68, 0x39, 0x7d, 0x47, 0x27, 0xe2, 0x07, 0xc4, 0x3c, 0x1a, 0x00, + 0x10, 0x22, 0x01, 0xe2, 0xf1, 0x7b, 0xc5, 0x70, 0xf3, 0x30, 0x08, 0x63, 0x29, 0x8f, 0xdd, 0x76, + 0xfb, 0xdf, 0xfd, 0x53, 0xfd, 0x6b, 0x84, 0xd9, 0x80, 0x40, 0xa6, 0x07, 0x11, 0x4f, 0xab, 0xd0, + 0xa0, 0xfa, 0x15, 0x44, 0xa8, 0x81, 0xcd, 0x08, 0xe6, 0x85, 0x49, 0x09, 0x21, 0x0b, 0x90, 0xe0, + 0x0d, 0x2a, 0x43, 0x7d, 0x16, 0x9e, 0xaf, 0x5d, 0xfe, 0x73, 0x09, 0xc3, 0x0f, 0xa7, 0xc4, 0x20, + 0x89, 0xb2, 0x31, 0x4d, 0xfb, 0x10, 0x88, 0x51, 0xfc, 0x1c, 0x46, 0x84, 0x9d, 0xb8, 0x9f, 0x2c, + 0xc3, 0xf1, 0x2b, 0x39, 0x23, 0xc6, 0xe5, 0x98, 0x5c, 0x2a, 0x5d, 0x94, 0x9a, 0x95, 0x8f, 0xc5, + 0x20, 0x0d, 0x4a, 0x40, 0x00, 0xfc, 0x0d, 0x09, 0x03, 0xa7, 0xfb, 0xb6, 0xf8, 0x0c, 0x80, 0x08, + 0x00, 0xd2, 0xa6, 0xd4, 0xd0, 0x04, 0xfa, 0xf1, 0x8c, 0x78, 0xc4, 0x54, 0x9f, 0x3b, 0x15, 0xdb, + 0x03, 0xb9, 0x28, 0xc1, 0x41, 0x61, 0xc9, 0x70, 0x02, 0xe4, 0x21, 0x82, 0xec, 0x60, 0x21, 0x52, + 0x7c, 0x00, 0x08, 0x63, 0x3b, 0x41, 0x60, 0xc5, 0x60, 0x08, 0x02, 0x1c, 0xc0, 0x3f, 0x83, 0xfe, + 0x9e, 0x5f, 0x1a, 0xc7, 0x82, 0x94, 0x64, 0x9b, 0x84, 0x5e, 0xc7, 0x32, 0x02, 0x35, 0x8b, 0x67, + 0x61, 0x68, 0xe0, 0x00, 0xe1, 0x52, 0x0b, 0xfa, 0x9c, 0x29, 0x47, 0x9a, 0x2a, 0x7f, 0xf0, 0x63, + 0xf0, 0x65, 0x19, 0x40, 0x55, 0x4b, 0x11, 0xf7, 0xd6, 0x1a, 0x24, 0x00, 0x39, 0x93, 0x04, 0x73, + 0x9b, 0x8f, 0x24, 0x10, 0x7c, 0x27, 0x15, 0x8d, 0xf5, 0x37, 0x54, 0x1e, 0xb8, 0xf5, 0xc7, 0xaf, + 0x4c, 0x1e, 0xb8, 0xf5, 0xd9, 0xc7, 0xaf, 0xfa, 0x50, 0x8e, 0x20, 0x6c, 0x13, 0x22, 0xeb, 0x08, + 0xc4, 0xee, 0x39, 0x63, 0x83, 0xb1, 0x8b, 0x7c, 0x62, 0xdf, 0x18, 0x88, 0x25, 0xc7, 0xc6, 0x28, + 0x87, 0xb6, 0x31, 0x46, 0x8b, 0x36, 0xc6, 0x28, 0x71, 0x3f, 0xdb, 0xe3, 0x11, 0x41, 0xf6, 0x0e, + 0xec, 0x62, 0x20, 0x7c, 0xf3, 0xe3, 0x14, 0xd8, 0xd8, 0xc5, 0x1d, 0xcd, 0xf1, 0xca, 0x15, 0xb6, + 0x36, 0x31, 0x4d, 0xff, 0x8e, 0x52, 0x15, 0x6c, 0x24, 0x82, 0x20, 0xe4, 0xb1, 0x1d, 0xfa, 0x69, + 0xa6, 0x9c, 0x4a, 0x18, 0x0e, 0xac, 0x8b, 0x8c, 0x05, 0x08, 0x73, 0xa1, 0xd8, 0xda, 0x8e, 0x50, + 0xa0, 0xf4, 0x6c, 0x61, 0x20, 0xed, 0xce, 0xe3, 0x18, 0x42, 0x81, 0xde, 0x57, 0xc5, 0x92, 0x1d, + 0x65, 0x4b, 0x18, 0xa0, 0x31, 0x1d, 0x32, 0xf1, 0x26, 0xa3, 0x08, 0x60, 0x07, 0xab, 0x73, 0xa1, + 0x2a, 0x8c, 0x50, 0xab, 0x2d, 0x98, 0xc5, 0x00, 0xc6, 0x05, 0x49, 0x42, 0x35, 0x51, 0xa8, 0xa0, + 0x7f, 0x66, 0x8b, 0x94, 0x76, 0x0b, 0xb9, 0xc3, 0x47, 0xb1, 0x84, 0x82, 0xe7, 0xa1, 0xf1, 0x64, + 0x82, 0xca, 0x4d, 0x53, 0x28, 0x71, 0x40, 0x18, 0x7d, 0xe8, 0xfb, 0xeb, 0xe6, 0xff, 0xf8, 0x0b, + 0x28, 0x7f, 0x6e, 0x12, 0x98, 0x10, 0xab, 0xf5, 0x23, 0xaa, 0x74, 0xdf, 0xe3, 0x08, 0x52, 0x11, + 0xa2, 0x5a, 0x8c, 0x24, 0x99, 0x96, 0x39, 0x59, 0xa5, 0x51, 0x0a, 0x41, 0x98, 0xe2, 0x14, 0x58, + 0x3c, 0xd8, 0x85, 0x58, 0xa2, 0x47, 0xa5, 0x45, 0x29, 0x29, 0x10, 0xb8, 0xc5, 0x10, 0x92, 0xec, + 0x36, 0xc2, 0x40, 0x06, 0xb8, 0x76, 0xf2, 0x0c, 0x93, 0xdd, 0x75, 0x57, 0xea, 0xaa, 0xa2, 0xc8, + 0x33, 0xd6, 0xb7, 0xbe, 0x1b, 0x70, 0x12, 0x83, 0x63, 0xa1, 0x72, 0x27, 0x44, 0xf5, 0xaa, 0x27, + 0x44, 0xf1, 0x78, 0xba, 0xfa, 0xd7, 0x09, 0xb8, 0x14, 0x13, 0x87, 0x52, 0xe5, 0xdf, 0xe5, 0x85, + 0xb0, 0xfc, 0x64, 0x2a, 0x4c, 0x1c, 0x76, 0x31, 0x41, 0x37, 0xa7, 0x93, 0x61, 0xc4, 0x30, 0x00, + 0x6d, 0x6e, 0xbb, 0x31, 0x1f, 0xf7, 0xaf, 0x9f, 0xc7, 0xf1, 0xee, 0xb3, 0x9c, 0xe3, 0xc0, 0xf4, + 0x65, 0x3d, 0x7f, 0x06, 0x02, 0x46, 0x8c, 0x38, 0x03, 0xd9, 0xa7, 0x07, 0x96, 0xe5, 0xbc, 0xec, + 0xe7, 0x07, 0xd9, 0x49, 0x29, 0xc3, 0x97, 0x1e, 0x3c, 0x10, 0x38, 0x12, 0x3e, 0x81, 0x10, 0xa0, + 0x53, 0xfd, 0x72, 0x78, 0x69, 0x27, 0x1b, 0x09, 0x84, 0x3a, 0xc7, 0x47, 0xe2, 0x5b, 0x11, 0x27, + 0x1c, 0xa1, 0x70, 0x0a, 0x0e, 0xc2, 0xd0, 0x80, 0x00, 0x48, 0x5d, 0x8e, 0xaa, 0x76, 0x0d, 0xc2, + 0x59, 0x71, 0xfc, 0xff, 0x9f, 0x8d, 0xf1, 0x51, 0x3e, 0x2a, 0x27, 0xde, 0x00, 0xae, 0x40, 0x34, + 0x21, 0x48, 0x5c, 0x00, 0x04, 0x00, 0x54, 0x38, 0x2a, 0x2a, 0x87, 0x05, 0x45, 0x5a, 0xfa, 0xae, + 0xaa, 0xaa, 0xaa, 0xa3, 0x80, 0x63, 0x83, 0x8d, 0x61, 0x70, 0x35, 0xee, 0x91, 0x27, 0x8c, 0x52, + 0xf6, 0xc4, 0x2e, 0x29, 0x04, 0x41, 0xc9, 0x64, 0x6a, 0x09, 0x01, 0x8e, 0xbb, 0xb0, 0xe2, 0x14, + 0x00, 0x51, 0xaf, 0x81, 0xf1, 0xb7, 0xef, 0xdb, 0x6f, 0xfc, 0x0e, 0x63, 0x69, 0xd3, 0xf8, 0x40, + 0x90, 0x27, 0x72, 0xa4, 0xf2, 0x6e, 0xdb, 0x7f, 0x1b, 0x82, 0x61, 0x1e, 0xbd, 0x3c, 0xf8, 0xd6, + 0x2c, 0x55, 0x0e, 0xd8, 0xcc, 0xdf, 0xb1, 0x8f, 0xec, 0x42, 0xe3, 0x94, 0x44, 0x60, 0xfb, 0x14, + 0xa1, 0xbc, 0x91, 0x0a, 0x4c, 0x88, 0x47, 0x26, 0x44, 0x2e, 0x31, 0x0d, 0x07, 0x25, 0x83, 0x8d, + 0x89, 0x84, 0x00, 0xc6, 0x7d, 0x18, 0xcc, 0x09, 0x1e, 0xa1, 0x2a, 0x8e, 0x24, 0x0b, 0xac, 0x0a, + 0x9c, 0x58, 0xc1, 0x51, 0x8a, 0x04, 0xb7, 0xc9, 0x72, 0x3e, 0x18, 0x45, 0x00, 0x79, 0xa9, 0x8a, + 0xe3, 0xff, 0xd3, 0x4f, 0x3a, 0x11, 0x6a, 0x35, 0x42, 0xf8, 0xaf, 0x8c, 0xe9, 0x94, 0x42, 0x85, + 0x16, 0x88, 0x85, 0xc4, 0x12, 0x1c, 0xf4, 0x71, 0x20, 0xba, 0xe1, 0x36, 0xcf, 0x81, 0xfe, 0xb1, + 0x6a, 0x0a, 0x16, 0x98, 0x8e, 0x07, 0x18, 0x8e, 0x19, 0x78, 0x7d, 0x8c, 0x46, 0x03, 0xd8, 0x59, + 0x51, 0xdc, 0x22, 0xcc, 0x01, 0x3e, 0xdd, 0xcb, 0xc0, 0x42, 0x62, 0xcb, 0xdf, 0xf1, 0x8c, 0xa0, + 0xd6, 0xf2, 0x3b, 0x88, 0xc9, 0x91, 0x12, 0x90, 0x94, 0x62, 0x87, 0x7d, 0xd8, 0x85, 0xc4, 0x29, + 0xb2, 0x21, 0x43, 0xbe, 0x88, 0x50, 0xdf, 0xa3, 0x24, 0x3e, 0x76, 0x1b, 0x84, 0x00, 0x18, 0x5c, + 0x91, 0x8c, 0x9d, 0x79, 0xef, 0xf7, 0x77, 0x7b, 0xde, 0x2a, 0xea, 0xfb, 0xc2, 0xf8, 0x01, 0x9d, + 0x09, 0x65, 0xf0, 0x42, 0x32, 0x73, 0x42, 0xd4, 0xd0, 0x57, 0x40, 0xfc, 0x2c, 0xf3, 0x02, 0xdc, + 0x4e, 0x11, 0x38, 0x64, 0xf8, 0x5c, 0x90, 0x04, 0x92, 0xb3, 0x30, 0xa1, 0x00, 0xa7, 0x93, 0x3b, + 0x9c, 0x79, 0xe3, 0x0f, 0x2c, 0x33, 0xc0, 0x60, 0x58, 0x19, 0x60, 0x0f, 0xd1, 0x8a, 0x8e, 0x20, + 0x54, 0x2a, 0x05, 0x96, 0x6c, 0x72, 0x21, 0xbf, 0x61, 0xb2, 0x04, 0x80, 0x00, 0xf4, 0x62, 0xa6, + 0x70, 0xb2, 0x40, 0x43, 0xab, 0xde, 0xac, 0xe2, 0x3c, 0x7d, 0xf8, 0x8f, 0x10, 0x7c, 0x67, 0x1f, + 0x19, 0x46, 0xf7, 0xfc, 0x08, 0x00, 0xe0, 0x28, 0x51, 0xc8, 0x5f, 0x3b, 0xcb, 0xc5, 0x1d, 0x96, + 0x33, 0xf6, 0x72, 0xc7, 0x8a, 0xa1, 0x41, 0xbf, 0x8a, 0xa7, 0x60, 0x24, 0x00, 0x09, 0x46, 0x80, + 0x01, 0xf5, 0x0d, 0x31, 0x20, 0x4f, 0xfa, 0x79, 0xff, 0xfd, 0xbf, 0x98, 0x59, 0x8c, 0x00, 0x0f, + 0x85, 0xc8, 0x17, 0xe7, 0xc8, 0x60, 0xb5, 0x5e, 0xbf, 0xbf, 0xf6, 0xc0, 0x7c, 0x1a, 0x8c, 0x32, + 0x8c, 0x50, 0x01, 0xf8, 0x87, 0xb8, 0xf8, 0xfe, 0x1a, 0xc0, 0x05, 0xc8, 0x12, 0x9d, 0x14, 0xf8, + 0x4e, 0x12, 0xa2, 0x72, 0x41, 0xd0, 0x63, 0x89, 0xde, 0x67, 0x07, 0xae, 0xce, 0xce, 0xec, 0x7e, + 0xb3, 0x87, 0xae, 0xce, 0xa3, 0xbf, 0x7c, 0x73, 0x09, 0x98, 0x1e, 0xb3, 0xb1, 0xc4, 0x28, 0xb0, + 0x69, 0xf1, 0x88, 0x8c, 0x19, 0x53, 0x08, 0x23, 0x00, 0x3c, 0x19, 0x16, 0xea, 0x00, 0x45, 0xe9, + 0xfc, 0x62, 0x84, 0x5e, 0x92, 0x65, 0x0f, 0x28, 0x15, 0x8f, 0x6b, 0x3f, 0xff, 0x78, 0x3f, 0x95, + 0x56, 0x6f, 0xf1, 0xb1, 0xe1, 0xe0, 0x00, 0x21, 0xc1, 0x0b, 0x1a, 0x95, 0x45, 0x90, 0xdd, 0x63, + 0x54, 0x35, 0xe2, 0x2f, 0x09, 0x4c, 0x0d, 0x66, 0x52, 0xe9, 0xa7, 0xf1, 0x92, 0x81, 0xeb, 0x64, + 0x67, 0x18, 0xc4, 0x50, 0xc3, 0x2c, 0x64, 0x75, 0x10, 0xa0, 0x95, 0xea, 0x23, 0x14, 0x31, 0x96, + 0xec, 0x42, 0x28, 0x3d, 0x64, 0x52, 0x8c, 0x67, 0x10, 0xb8, 0x85, 0xc6, 0x10, 0x98, 0xb1, 0x72, + 0x01, 0x61, 0xc0, 0x2b, 0x8a, 0x3b, 0x8e, 0x65, 0x00, 0x97, 0xea, 0x10, 0xe9, 0x1c, 0x1c, 0x5e, + 0x01, 0x0f, 0xd4, 0xc7, 0x47, 0x47, 0x71, 0xc8, 0xa0, 0xb2, 0x0e, 0x24, 0x89, 0x4a, 0x34, 0x84, + 0x0f, 0xbd, 0xd8, 0xb4, 0x50, 0x5a, 0x0f, 0x91, 0xf8, 0xe4, 0x40, 0xef, 0x9c, 0xc5, 0x67, 0x23, + 0x19, 0x28, 0xee, 0x12, 0x28, 0x61, 0x0d, 0x07, 0x01, 0x2e, 0x6d, 0xb7, 0xb6, 0xdf, 0xfa, 0x39, + 0xc4, 0xf8, 0xb4, 0x14, 0x06, 0x4d, 0x79, 0xb1, 0x64, 0x82, 0xc9, 0xac, 0x1d, 0xd8, 0xe7, 0x07, + 0x6f, 0xbe, 0x39, 0xc4, 0x15, 0x03, 0xfe, 0x12, 0x70, 0x62, 0x8c, 0x86, 0x39, 0x5a, 0xfe, 0x28, + 0x85, 0x0a, 0x5b, 0x23, 0x14, 0xa4, 0x9b, 0x12, 0x8a, 0x0e, 0xac, 0x88, 0x44, 0x0f, 0x9e, 0x88, + 0x5c, 0x42, 0x28, 0xa7, 0x18, 0x88, 0x1b, 0xf0, 0xed, 0x88, 0x5c, 0x42, 0xe1, 0xc8, 0x40, 0x00, + 0x43, 0x32, 0x6c, 0x4e, 0x8a, 0x23, 0x7f, 0xbd, 0xe1, 0x5f, 0x4e, 0x17, 0x3d, 0xf2, 0x73, 0x8b, + 0xba, 0x5d, 0x7b, 0xdf, 0x03, 0xc0, 0x0c, 0x90, 0xa4, 0xe0, 0x58, 0x3f, 0xce, 0x07, 0xd6, 0x98, + 0xe4, 0x01, 0xf2, 0xf1, 0xe0, 0x3e, 0x4c, 0x2a, 0x78, 0xf5, 0x8b, 0x51, 0x6c, 0xe0, 0x1e, 0xd3, + 0xf0, 0x68, 0x00, 0x08, 0x00, 0xc4, 0x80, 0x02, 0xc3, 0x73, 0x00, 0x2f, 0x6c, 0x78, 0xce, 0x21, + 0x45, 0xb3, 0x8d, 0x5f, 0xf6, 0x39, 0x75, 0x51, 0x1f, 0x7b, 0xae, 0xc3, 0xe1, 0xeb, 0xb0, 0x78, + 0x1e, 0x54, 0xbc, 0x15, 0xeb, 0xeb, 0xa6, 0x9f, 0xc3, 0x88, 0xa0, 0x01, 0x07, 0xc7, 0xde, 0x88, + 0x07, 0xc4, 0xff, 0xac, 0x43, 0xa0, 0xb7, 0x19, 0x40, 0xd5, 0x10, 0xe8, 0x87, 0x4b, 0x0b, 0x2c, + 0x2d, 0x7f, 0x6d, 0xb8, 0x63, 0x00, 0x3a, 0xf4, 0x72, 0x83, 0x5d, 0x7f, 0xdf, 0xe5, 0xaa, 0x64, + 0xe5, 0xac, 0x75, 0x72, 0xd8, 0x6a, 0x40, 0x02, 0x19, 0xd6, 0xc2, 0x37, 0x31, 0xff, 0xde, 0x56, + 0x4f, 0x2f, 0xb9, 0x3f, 0xdc, 0xfd, 0xcf, 0x79, 0xdb, 0x0b, 0xa1, 0x20, 0x02, 0x92, 0x3d, 0xa1, + 0x42, 0x8a, 0xe2, 0xbb, 0xdf, 0x7d, 0xd1, 0x3b, 0xb6, 0x7e, 0x19, 0x8d, 0xa9, 0x13, 0x0d, 0x31, + 0x40, 0x00, 0x59, 0x60, 0x61, 0x14, 0xb9, 0x91, 0xec, 0x94, 0x7e, 0x7d, 0xf0, 0x91, 0xf8, 0x0a, + 0x02, 0xb8, 0xab, 0xbf, 0x1c, 0x18, 0x0a, 0x98, 0x15, 0x05, 0x71, 0x7f, 0xc7, 0xbf, 0x00, 0x57, + 0x20, 0x1c, 0x10, 0xa0, 0x91, 0x0a, 0x06, 0x51, 0x6c, 0x3f, 0x3c, 0xc5, 0x0c, 0xb3, 0x14, 0xc5, + 0x0c, 0x50, 0xc5, 0x31, 0x43, 0x12, 0x00, 0x70, 0xf0, 0x0e, 0x0a, 0x18, 0xa6, 0x58, 0x18, 0xa1, + 0x87, 0xc5, 0x1a, 0x0a, 0x8d, 0x63, 0xc7, 0x11, 0x67, 0xf1, 0x0a, 0x4c, 0x8c, 0x5f, 0x63, 0x11, + 0x81, 0x12, 0x32, 0x7c, 0x06, 0x9d, 0x84, 0x08, 0x24, 0x04, 0x8e, 0x51, 0x47, 0x83, 0x46, 0xb4, + 0xfe, 0xdc, 0xff, 0xe3, 0xb0, 0x27, 0xdc, 0x8d, 0x50, 0x28, 0x60, 0xae, 0x38, 0x84, 0x01, 0xfa, + 0xd0, 0xd2, 0xe2, 0xd8, 0x90, 0xdf, 0x91, 0xdc, 0x72, 0xb1, 0x23, 0x9c, 0x69, 0x08, 0x1e, 0xf1, + 0x53, 0x16, 0x88, 0x07, 0xd2, 0x9d, 0x0d, 0x38, 0xd2, 0x14, 0x31, 0xe1, 0x82, 0xac, 0x44, 0x82, + 0xaa, 0x31, 0x94, 0x38, 0xf0, 0xe3, 0x62, 0x17, 0x10, 0xb9, 0xd4, 0xdb, 0x10, 0xb8, 0x85, 0xc5, + 0xc2, 0x34, 0x73, 0x8b, 0x8c, 0x0f, 0x9e, 0x47, 0x1c, 0x42, 0xe1, 0x76, 0x34, 0x0e, 0x50, 0x34, + 0x1f, 0x5a, 0xfd, 0x6a, 0x8e, 0x71, 0x68, 0x60, 0x3d, 0xe8, 0xe3, 0x63, 0x09, 0xf6, 0x33, 0x99, + 0xb1, 0x9f, 0xb3, 0xae, 0x75, 0x07, 0xbd, 0x9d, 0x10, 0x0d, 0xcf, 0xa3, 0x94, 0x26, 0x8e, 0x00, + 0x99, 0x46, 0x90, 0xa1, 0x81, 0xef, 0x31, 0x8a, 0x0e, 0xbc, 0xa3, 0xf1, 0xcc, 0x40, 0x31, 0x24, + 0x2b, 0xe2, 0xd9, 0x42, 0xfc, 0x92, 0xe1, 0x02, 0x40, 0xc7, 0xf8, 0x63, 0x1d, 0x7e, 0xee, 0xf1, + 0x6c, 0xc0, 0x98, 0x14, 0xa8, 0x8b, 0x1c, 0x43, 0x94, 0x84, 0xe9, 0x88, 0x21, 0x07, 0x99, 0x47, + 0x28, 0x0e, 0xcc, 0xa5, 0x86, 0x0a, 0x62, 0x49, 0x07, 0x12, 0xc8, 0xe4, 0x70, 0x3d, 0x6c, 0xf2, + 0xc5, 0x12, 0x42, 0x71, 0xca, 0x30, 0xcb, 0xb0, 0xe2, 0x1c, 0x00, 0x36, 0xcc, 0x49, 0x95, 0xd9, + 0x1c, 0xdd, 0xaf, 0xfe, 0x0d, 0xdd, 0x1c, 0x53, 0xba, 0xce, 0x02, 0x20, 0x1f, 0x4d, 0x3e, 0xdc, + 0x34, 0x43, 0x00, 0x0d, 0x53, 0xc5, 0xd5, 0xc4, 0x65, 0xf3, 0xdb, 0x3b, 0xd5, 0x94, 0x67, 0x16, + 0xf9, 0x39, 0x77, 0x57, 0xc3, 0x2e, 0x00, 0x33, 0xe5, 0x23, 0x3d, 0x20, 0x30, 0xd6, 0x96, 0x52, + 0xbe, 0xdd, 0x78, 0xa5, 0x8a, 0x5a, 0xc5, 0xb8, 0xac, 0x4b, 0xcb, 0x36, 0x16, 0x50, 0x05, 0xf5, + 0x8d, 0x92, 0xd9, 0x41, 0x55, 0xdf, 0xf5, 0x75, 0xf8, 0x31, 0xf8, 0xb1, 0x67, 0xe0, 0xe3, 0xf7, + 0xf8, 0xfa, 0xbc, 0x30, 0xe0, 0x0f, 0xe6, 0x32, 0x46, 0x53, 0x8c, 0x43, 0xcd, 0xd7, 0xbc, 0xda, + 0x9a, 0x69, 0x83, 0xee, 0x3e, 0xed, 0xe4, 0xea, 0xce, 0xce, 0xce, 0xc6, 0x1a, 0x24, 0x00, 0x67, + 0x0f, 0xae, 0x44, 0x8f, 0x54, 0xf4, 0xd9, 0xd3, 0xfe, 0xde, 0x64, 0xe0, 0x68, 0x06, 0x03, 0x60, + 0xf1, 0x72, 0xb0, 0x20, 0x0f, 0x6f, 0x42, 0x1e, 0x3c, 0x03, 0xc9, 0x45, 0x47, 0x41, 0x71, 0x69, + 0x29, 0x63, 0xcf, 0x0e, 0x1c, 0x3d, 0xc2, 0xaa, 0xc3, 0xb8, 0x2f, 0x33, 0x05, 0x54, 0x06, 0x60, + 0x04, 0x01, 0x1a, 0xb6, 0xdf, 0xc3, 0x53, 0x00, 0x12, 0x73, 0xb7, 0x51, 0x95, 0xf2, 0xd9, 0x59, + 0x3f, 0x46, 0x9e, 0x37, 0xca, 0xf9, 0x55, 0x9f, 0x85, 0xd3, 0x1e, 0x9d, 0x5f, 0x15, 0x5f, 0x5f, + 0x47, 0xc7, 0xa7, 0x67, 0x67, 0x67, 0xec, 0x6b, 0x0c, 0xaa, 0xcb, 0xbf, 0x88, 0x50, 0xdf, 0xa3, + 0x94, 0x20, 0xca, 0x55, 0xe1, 0x04, 0x60, 0x3b, 0x92, 0x87, 0x9d, 0x4d, 0x34, 0xd3, 0xf8, 0xe2, + 0x46, 0x9a, 0x4a, 0x98, 0xcc, 0x11, 0x1c, 0xa8, 0x16, 0x8c, 0x76, 0x1c, 0x54, 0xe6, 0xc7, 0x33, + 0x81, 0xbc, 0x34, 0x1b, 0x16, 0xe0, 0x85, 0x8d, 0x3f, 0x55, 0x8a, 0x50, 0xe3, 0xd1, 0xd2, 0x84, + 0xe3, 0xd6, 0x76, 0x2d, 0x08, 0x08, 0x8e, 0x71, 0x36, 0x39, 0x94, 0x08, 0xb6, 0xd1, 0xaa, 0x49, + 0x9d, 0x14, 0x32, 0xf4, 0x5a, 0x31, 0x70, 0x4a, 0x4c, 0x69, 0x32, 0x2c, 0xc6, 0x2f, 0x3e, 0x32, + 0x58, 0xb9, 0xc6, 0x31, 0x40, 0x47, 0xbe, 0x7e, 0x26, 0x50, 0x82, 0x10, 0x1b, 0xcb, 0x09, 0x34, + 0xa6, 0x9a, 0x69, 0xfc, 0x25, 0x86, 0x98, 0x8e, 0xa7, 0x4f, 0xf1, 0xd1, 0x70, 0x71, 0x9b, 0x17, + 0x1b, 0x1c, 0x00, 0x63, 0x9c, 0xe8, 0x60, 0x3d, 0xe4, 0x76, 0x72, 0x08, 0xed, 0x88, 0x51, 0x12, + 0x18, 0xc4, 0x60, 0xe3, 0xcd, 0x8c, 0x51, 0x5f, 0x32, 0x8c, 0x53, 0xeb, 0x18, 0xa7, 0x31, 0x06, + 0x3a, 0x70, 0xb8, 0x0b, 0x24, 0x7e, 0x39, 0x18, 0xbd, 0xb1, 0xc8, 0xe0, 0xd7, 0x64, 0x8f, 0xce, + 0x88, 0x0e, 0x27, 0xe2, 0xd4, 0x0c, 0x58, 0x2e, 0x05, 0x86, 0x38, 0xe3, 0xb0, 0x83, 0x57, 0x04, + 0x8e, 0x38, 0xe4, 0x43, 0x64, 0x46, 0x2a, 0x39, 0x42, 0xe1, 0xe1, 0x8a, 0x1d, 0xc2, 0x0a, 0x18, + 0x1e, 0x4e, 0x93, 0x4f, 0xf8, 0xc4, 0x40, 0xe8, 0xc5, 0x06, 0x53, 0x18, 0xa7, 0x8c, 0xb1, 0xaa, + 0x07, 0xad, 0x44, 0x5a, 0x1b, 0x51, 0x84, 0x28, 0x1e, 0xd6, 0x42, 0x3d, 0x8d, 0x65, 0x03, 0x59, + 0x77, 0x62, 0x17, 0x0e, 0x47, 0x00, 0x04, 0x56, 0x32, 0xa2, 0x31, 0xd6, 0x31, 0xfe, 0xce, 0x4f, + 0xe4, 0xf8, 0x83, 0xd3, 0x2e, 0xd7, 0xf8, 0x6b, 0x00, 0x49, 0x8c, 0x7c, 0x2a, 0x83, 0x3a, 0x09, + 0x5f, 0x73, 0xfa, 0xdf, 0xeb, 0xba, 0x65, 0xfc, 0xbd, 0x33, 0xc4, 0xd8, 0x69, 0x40, 0x27, 0x15, + 0x30, 0x90, 0xd7, 0x4f, 0xfa, 0xff, 0x58, 0x5d, 0x18, 0x00, 0xd9, 0xa5, 0x90, 0x1a, 0x8e, 0x1f, + 0xc7, 0xee, 0xbe, 0xe4, 0xf1, 0x1f, 0x2c, 0x34, 0xa0, 0x06, 0xfc, 0xac, 0x10, 0xc5, 0xdb, 0x77, + 0xac, 0x9d, 0x3a, 0xd7, 0xf5, 0x86, 0x89, 0x00, 0x14, 0x89, 0xc1, 0xc2, 0x67, 0x1d, 0xc5, 0x73, + 0xc6, 0x9f, 0x6d, 0xcf, 0xdd, 0xdc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfc, 0x7f, 0xc3, 0x11, 0x61, 0x90, + 0x36, 0xc6, 0x9a, 0x76, 0xff, 0xfc, 0x47, 0x1c, 0x26, 0x41, 0x40, 0x21, 0xd3, 0x4f, 0x20, 0x1a, + 0xbb, 0xf9, 0xb5, 0x72, 0xdf, 0x58, 0xaf, 0x7b, 0x88, 0x60, 0x4f, 0x93, 0xc2, 0xec, 0x78, 0xc2, + 0x80, 0x93, 0x24, 0x5d, 0x45, 0xee, 0xdd, 0xe4, 0x5d, 0xf0, 0x2f, 0x77, 0x77, 0x1d, 0x8e, 0xe2, + 0x50, 0xb0, 0xf7, 0xa3, 0x11, 0x81, 0xd5, 0x82, 0x9b, 0x1c, 0x48, 0x5c, 0x22, 0x10, 0x60, 0x00, + 0xc7, 0x71, 0x73, 0x82, 0xd7, 0xc0, 0xb1, 0x40, 0xae, 0x21, 0x18, 0xa4, 0xa3, 0x14, 0x07, 0xc8, + 0x63, 0x4d, 0x8e, 0x24, 0x40, 0x34, 0x41, 0x5c, 0x6c, 0xe1, 0xbf, 0x31, 0x8a, 0x21, 0x87, 0x2b, + 0x8b, 0x9c, 0x3a, 0x00, 0x3c, 0x8e, 0x70, 0xb2, 0x1a, 0x0e, 0x27, 0x9b, 0x7f, 0xfb, 0x7c, 0x71, + 0x02, 0x00, 0x1d, 0xad, 0x9a, 0x47, 0xe2, 0x17, 0x10, 0xf9, 0xfc, 0x62, 0x08, 0xc7, 0x1b, 0x10, + 0xb8, 0xb4, 0x10, 0x2e, 0x91, 0x31, 0xca, 0x18, 0xa0, 0x44, 0x38, 0xe3, 0xa4, 0x2e, 0x7c, 0xc7, + 0x22, 0x84, 0xcf, 0x5c, 0x51, 0x85, 0x47, 0x13, 0x04, 0x3c, 0xc5, 0xe0, 0x69, 0x81, 0xf7, 0x32, + 0x8c, 0x50, 0x31, 0x9f, 0x72, 0x28, 0xc4, 0x50, 0xf0, 0xf2, 0x3f, 0x1c, 0xa1, 0xdc, 0x48, 0x7d, + 0x8c, 0x50, 0x1f, 0x6f, 0xe1, 0xdb, 0x0a, 0x23, 0x7f, 0xf6, 0xdb, 0xf8, 0xbc, 0xda, 0xd8, 0xd2, + 0x1c, 0x3e, 0xf3, 0x67, 0x50, 0xcb, 0xd1, 0x18, 0x69, 0xe8, 0x87, 0xc7, 0x45, 0x02, 0x88, 0xbe, + 0x34, 0x10, 0xe3, 0xb0, 0xc9, 0x46, 0x47, 0x71, 0x84, 0x8c, 0xb3, 0x88, 0xee, 0x34, 0x91, 0xe8, + 0xa3, 0x1e, 0x63, 0x11, 0xc0, 0x4a, 0xd6, 0xdf, 0x99, 0x1f, 0x8c, 0x45, 0x00, 0x7b, 0xb3, 0x9d, + 0x0d, 0x8c, 0x5b, 0xe3, 0x14, 0x1e, 0xbb, 0x63, 0xb0, 0x11, 0x6d, 0x87, 0x39, 0x8b, 0x1c, 0xe2, + 0xc8, 0x63, 0xe5, 0x2e, 0x33, 0x17, 0x7c, 0x61, 0x0f, 0x11, 0xd3, 0x09, 0xc3, 0x80, 0x01, 0x10, + 0x16, 0x6b, 0x20, 0x94, 0x5a, 0x60, 0x41, 0x3a, 0xc4, 0xe1, 0x1a, 0x71, 0xa7, 0x34, 0x38, 0xc1, + 0xf7, 0x07, 0x4b, 0x96, 0x70, 0xa2, 0x80, 0x0e, 0x5d, 0x31, 0x55, 0x75, 0xdc, 0xdf, 0xe2, 0x7a, + 0x6d, 0x77, 0x14, 0x11, 0x8d, 0xdb, 0x0e, 0xeb, 0x87, 0x3f, 0xc3, 0x10, 0xa0, 0x91, 0x40, 0xd3, + 0x14, 0x31, 0x1e, 0x5a, 0x8b, 0xbb, 0x97, 0xa5, 0x8c, 0x38, 0x0f, 0x89, 0x45, 0x55, 0x3a, 0xd0, + 0xc7, 0x00, 0x01, 0x00, 0x68, 0xe7, 0x81, 0x24, 0x18, 0x02, 0xc8, 0x8e, 0x2c, 0xca, 0x3d, 0xf2, + 0x69, 0x61, 0x2e, 0xc8, 0x3c, 0x7d, 0xce, 0x01, 0xe3, 0x80, 0x00, 0x80, 0x34, 0x73, 0x86, 0x94, + 0x05, 0x6b, 0x8b, 0x30, 0x01, 0x81, 0xef, 0xee, 0xf6, 0xdb, 0xf8, 0xfb, 0x0c, 0x28, 0x00, 0xd6, + 0x37, 0xd1, 0x6e, 0x27, 0xad, 0xd3, 0xdb, 0x4d, 0x3b, 0x78, 0x87, 0x62, 0xb6, 0xf8, 0x67, 0x00, + 0x1d, 0xa4, 0xb6, 0x08, 0x44, 0xc6, 0xff, 0x96, 0x9a, 0x7e, 0x0f, 0xfc, 0x6e, 0xf7, 0xbd, 0xb0, + 0xaa, 0x80, 0x1b, 0x2e, 0x46, 0x8c, 0x63, 0x8b, 0xbf, 0x7e, 0x20, 0x18, 0x44, 0x30, 0xf9, 0x7d, + 0xe1, 0x36, 0x40, 0x03, 0x14, 0x88, 0xa0, 0x18, 0xec, 0x60, 0xd6, 0xff, 0xbc, 0x4c, 0x28, 0x31, + 0x5f, 0xef, 0xe3, 0x0e, 0x03, 0xe4, 0xc9, 0x80, 0x50, 0x7f, 0x1b, 0x04, 0xb1, 0xc6, 0x38, 0xe2, + 0xc8, 0x12, 0x0b, 0xd4, 0x60, 0xd8, 0xc7, 0x07, 0xad, 0x1d, 0x8f, 0xc7, 0x32, 0x85, 0xc0, 0x17, + 0x42, 0x39, 0xc6, 0x28, 0x4b, 0x39, 0xe8, 0x6c, 0x72, 0x84, 0xcb, 0xae, 0x4d, 0x8d, 0xc3, 0x7e, + 0x4c, 0xe2, 0x54, 0x37, 0xe8, 0xd2, 0x41, 0x76, 0xe4, 0xd9, 0xf0, 0xdf, 0xa2, 0x30, 0xef, 0xa2, + 0x89, 0x0e, 0x52, 0x53, 0xe1, 0xef, 0x4e, 0xb9, 0xd7, 0x17, 0x97, 0xf6, 0x21, 0x43, 0xbe, 0x89, + 0x7c, 0x62, 0x93, 0x3b, 0x14, 0xa1, 0x61, 0x58, 0xb5, 0x3e, 0xb6, 0x3a, 0x3c, 0x1c, 0x96, 0x08, + 0xa6, 0x38, 0xe2, 0xe3, 0x01, 0x44, 0x1f, 0x0e, 0xc7, 0xe2, 0xd1, 0x00, 0xc7, 0xf8, 0xc9, 0x8c, + 0x66, 0x04, 0x4b, 0x14, 0xc9, 0x04, 0x38, 0xc5, 0x02, 0x8a, 0x15, 0xcc, 0xf8, 0xa2, 0x41, 0xbb, + 0xa3, 0x95, 0x1d, 0xb1, 0xc4, 0x81, 0x22, 0xd8, 0x53, 0xf1, 0x18, 0xe3, 0x14, 0x1d, 0x56, 0xf8, + 0x82, 0x41, 0x89, 0xfa, 0x28, 0x91, 0xb8, 0xb1, 0x4b, 0x8e, 0x50, 0x0f, 0xb2, 0xab, 0x9a, 0x01, + 0x03, 0x08, 0xa8, 0x23, 0x0c, 0x74, 0x37, 0xdb, 0x6d, 0xb6, 0xe3, 0x94, 0x4a, 0x41, 0x6c, 0x24, + 0x85, 0x81, 0xd3, 0x36, 0x48, 0xca, 0xf4, 0xd3, 0x4d, 0x38, 0xc2, 0x4f, 0x63, 0x2a, 0x31, 0x98, + 0x28, 0xc3, 0x2b, 0x36, 0x39, 0x10, 0x32, 0x9f, 0xef, 0xb1, 0x48, 0xa6, 0xd8, 0x92, 0x41, 0xef, + 0xc5, 0x90, 0x81, 0xc7, 0x8b, 0x3e, 0x38, 0x93, 0x90, 0x82, 0x07, 0xb1, 0x78, 0x64, 0xf0, 0xe9, + 0xf0, 0xb9, 0x02, 0xc0, 0x01, 0xcc, 0x88, 0xe1, 0x8a, 0xc4, 0x5a, 0x42, 0x49, 0x6b, 0xdb, 0x6c, + 0xfd, 0xff, 0xc5, 0x67, 0xbc, 0x50, 0x65, 0xb0, 0x11, 0x36, 0x1c, 0x50, 0x02, 0x47, 0x0a, 0xa9, + 0x51, 0xc2, 0x3d, 0xbc, 0x62, 0x9f, 0xfe, 0x2d, 0x64, 0x71, 0xaf, 0x6c, 0x8c, 0x06, 0x57, 0x96, + 0x0b, 0xd0, 0x77, 0xe8, 0xd9, 0x1a, 0xeb, 0x06, 0x8b, 0x44, 0x1e, 0x59, 0xb6, 0xb2, 0x46, 0xe3, + 0x6d, 0x81, 0x0c, 0x05, 0x84, 0x46, 0xc5, 0xd0, 0x2c, 0xac, 0x83, 0xc2, 0x6f, 0xef, 0xc4, 0xcb, + 0xfb, 0xc3, 0x44, 0x80, 0xbe, 0x44, 0x33, 0xc4, 0x58, 0x12, 0xb8, 0xf8, 0xf2, 0x51, 0xed, 0x8d, + 0xae, 0x00, 0x12, 0xa9, 0xed, 0x09, 0x19, 0x69, 0x87, 0x36, 0x95, 0xdd, 0x52, 0x9d, 0xc7, 0x29, + 0x53, 0x9a, 0xe4, 0x3e, 0x69, 0xde, 0xca, 0x58, 0xf6, 0x38, 0x52, 0x89, 0xa0, 0x3b, 0xe7, 0xc3, + 0x6e, 0x00, 0x23, 0xa4, 0xd8, 0x43, 0x4c, 0xa0, 0xa5, 0xbc, 0xdc, 0xa9, 0x3a, 0xf3, 0x17, 0x2f, + 0x3b, 0xcb, 0xfb, 0xe9, 0x3b, 0xfe, 0x16, 0x70, 0x00, 0x48, 0xc8, 0xc3, 0x94, 0x4a, 0xb6, 0x66, + 0xdb, 0x6f, 0xaa, 0x6e, 0x04, 0xc6, 0xd8, 0x6a, 0x60, 0x0b, 0xc9, 0x5a, 0x9a, 0x27, 0x87, 0x13, + 0x99, 0x21, 0x19, 0xe5, 0xb0, 0x46, 0x45, 0xbd, 0xb0, 0x60, 0x01, 0x20, 0x1b, 0x1d, 0x6a, 0x56, + 0xda, 0x0b, 0x80, 0x17, 0x2b, 0x05, 0x80, 0xbc, 0x83, 0xe8, 0xb0, 0x00, 0x2f, 0xb2, 0x00, 0xa4, + 0x83, 0xb0, 0x06, 0xa0, 0xd2, 0x85, 0x51, 0x90, 0xb0, 0x97, 0x09, 0x46, 0x81, 0x32, 0xfb, 0x1c, + 0x15, 0x07, 0xf3, 0x5b, 0x50, 0x74, 0x2b, 0xf1, 0x83, 0x80, 0x84, 0x83, 0x8b, 0xc4, 0xbc, 0x4b, + 0xf7, 0x7b, 0xc2, 0xec, 0x48, 0x03, 0x91, 0xde, 0x2b, 0x20, 0xd0, 0x6f, 0xd3, 0xf9, 0xfe, 0xb7, + 0x99, 0x4b, 0x3f, 0xa6, 0xde, 0xef, 0x1e, 0x17, 0xf2, 0xde, 0xe9, 0x30, 0x9e, 0x01, 0x4f, 0x02, + 0xb1, 0xab, 0xad, 0x75, 0xaa, 0xd7, 0x0d, 0x45, 0x00, 0x01, 0x7a, 0x28, 0x69, 0xad, 0x31, 0x5f, + 0xdf, 0xf6, 0x4a, 0x70, 0xbc, 0xa9, 0xe1, 0x3e, 0x20, 0x7c, 0x8e, 0xf4, 0x7d, 0x8b, 0x61, 0x90, + 0xc9, 0xe1, 0x23, 0x4c, 0x5b, 0x87, 0x1e, 0x2d, 0x8b, 0x21, 0x41, 0xd7, 0xf5, 0x9d, 0x90, 0x0c, + 0x75, 0xd1, 0x98, 0x69, 0x3f, 0xda, 0x55, 0x11, 0x20, 0x65, 0x96, 0x88, 0x52, 0xe4, 0x62, 0x28, + 0x77, 0xc9, 0xd4, 0x71, 0x0a, 0x4c, 0x76, 0x2e, 0x36, 0x8e, 0x39, 0xd8, 0xc0, 0x7b, 0xf3, 0xb8, + 0xce, 0x51, 0x3e, 0x23, 0xcf, 0x83, 0xd7, 0x8b, 0x5a, 0x3f, 0x3a, 0x83, 0xab, 0xce, 0xe1, 0xc7, + 0xa7, 0x50, 0xcb, 0xd1, 0x0f, 0x8c, 0x43, 0x63, 0x9b, 0x3f, 0x8b, 0x84, 0x00, 0x47, 0xbc, 0x51, + 0xe7, 0xc7, 0x23, 0x05, 0x4f, 0x88, 0x84, 0xb5, 0x1d, 0x82, 0x5c, 0xe2, 0x48, 0xbd, 0x45, 0xce, + 0x18, 0x1e, 0x4d, 0x8c, 0x45, 0x0d, 0xf9, 0x1f, 0x8b, 0x62, 0x80, 0x3b, 0xb3, 0x23, 0x9c, 0x63, + 0x88, 0x42, 0x42, 0x82, 0xb1, 0x6a, 0x1e, 0x1e, 0x47, 0x38, 0x85, 0x2e, 0x46, 0xe7, 0xf0, 0x63, + 0x30, 0xe3, 0xc5, 0x44, 0x51, 0x8a, 0x02, 0x0d, 0x41, 0xbf, 0x3d, 0x8c, 0x50, 0x31, 0x9f, 0x36, + 0x77, 0x2c, 0xa2, 0xdc, 0x38, 0xf5, 0x67, 0x50, 0xcb, 0xd1, 0x0a, 0x1a, 0x7a, 0x28, 0x93, 0x6c, + 0x43, 0xe2, 0x5c, 0x37, 0xe8, 0x45, 0x8f, 0x89, 0x3f, 0x55, 0x55, 0x7b, 0xe2, 0x10, 0xc0, 0xdf, + 0xa1, 0xb2, 0x0e, 0x00, 0x15, 0xd2, 0xac, 0xd9, 0x11, 0x8b, 0xff, 0xe3, 0x1c, 0x0d, 0xae, 0x6f, + 0x30, 0xbd, 0x7e, 0x19, 0xc0, 0x03, 0x4a, 0x2e, 0x84, 0xa9, 0x79, 0x2f, 0xff, 0xaa, 0xed, 0x9b, + 0xb6, 0xef, 0xfa, 0xd4, 0x07, 0x58, 0x70, 0x82, 0x80, 0x0f, 0x51, 0x23, 0xe8, 0x0b, 0x87, 0x40, + 0xdf, 0xb6, 0x11, 0x22, 0x32, 0xb7, 0x65, 0x9f, 0xa1, 0x7a, 0xe0, 0xa8, 0x0c, 0x19, 0xe0, 0x2f, + 0xf9, 0x69, 0x1f, 0xe6, 0x69, 0xf6, 0xeb, 0x0e, 0x60, 0x5e, 0x18, 0xaa, 0x5a, 0x70, 0xb1, 0x33, + 0x3d, 0xcf, 0x5b, 0x34, 0x4c, 0xc9, 0x0f, 0x7b, 0x21, 0x01, 0xd9, 0x1e, 0x05, 0x90, 0x45, 0x14, + 0x39, 0x16, 0x51, 0xc0, 0x33, 0x8e, 0x01, 0xdd, 0xd5, 0x1f, 0x7d, 0x4e, 0xf1, 0xeb, 0x97, 0x97, + 0xd3, 0xaf, 0xdf, 0x0d, 0xb8, 0x0c, 0x06, 0x62, 0x87, 0x15, 0xbd, 0x76, 0xf7, 0xf7, 0x15, 0xb8, + 0xaf, 0xd7, 0x5f, 0xc3, 0x0a, 0x00, 0x0f, 0x71, 0x57, 0x70, 0x12, 0x94, 0xaf, 0xff, 0xab, 0xa2, + 0x00, 0x77, 0x11, 0xa8, 0x33, 0x5d, 0x0b, 0x0d, 0xb0, 0xb6, 0x2d, 0x9d, 0xf2, 0xd8, 0xa8, 0xc3, + 0x7e, 0x77, 0x05, 0x20, 0x10, 0x91, 0xb1, 0xa2, 0x73, 0xc0, 0x00, 0x40, 0x16, 0x42, 0x23, 0x83, + 0xa7, 0x82, 0x29, 0x43, 0xe1, 0x6c, 0xf8, 0xc3, 0x6b, 0xe9, 0x1b, 0x37, 0x59, 0x56, 0x52, 0x10, + 0x3b, 0x98, 0x33, 0x98, 0xf8, 0x0f, 0x66, 0xf9, 0x91, 0x01, 0x54, 0x81, 0xa6, 0xae, 0x5f, 0x96, + 0x20, 0x58, 0x70, 0x1e, 0x1e, 0x00, 0x14, 0x18, 0x09, 0x75, 0x27, 0xd4, 0x1b, 0x48, 0x04, 0x7a, + 0xbc, 0x42, 0xec, 0xe0, 0x06, 0xab, 0x30, 0x9b, 0x9f, 0x29, 0x46, 0xbf, 0xee, 0xe3, 0x10, 0x34, + 0xea, 0x51, 0x7c, 0x78, 0xf2, 0x77, 0x8f, 0x7d, 0x55, 0x47, 0x76, 0x17, 0x65, 0x00, 0x83, 0x29, + 0x80, 0x18, 0xaf, 0x75, 0x75, 0xbd, 0xdd, 0x5d, 0x5f, 0x80, 0x2b, 0x10, 0x05, 0x12, 0x34, 0x40, + 0x90, 0x1c, 0x12, 0x38, 0x58, 0xee, 0xb0, 0x3c, 0x61, 0x95, 0xb3, 0xc3, 0xc5, 0x18, 0xac, 0x40, + 0xe1, 0xce, 0x39, 0xfe, 0x73, 0x91, 0x08, 0x81, 0x21, 0xc0, 0xdb, 0x15, 0x7f, 0xc2, 0xec, 0x80, + 0x03, 0x34, 0x82, 0xc2, 0x44, 0xae, 0xca, 0xd1, 0xcd, 0x9b, 0x6f, 0x8f, 0x3f, 0xf5, 0xbc, 0x50, + 0x9f, 0x6e, 0xab, 0x7c, 0x72, 0x7c, 0x67, 0xa6, 0xc6, 0x90, 0x2e, 0x06, 0x7b, 0x85, 0x76, 0x11, + 0x61, 0x1c, 0xb7, 0xbf, 0xc4, 0x10, 0x60, 0x7d, 0xe8, 0xc7, 0x0f, 0x9e, 0x46, 0x38, 0xd4, 0x36, + 0x38, 0xd8, 0xc4, 0x30, 0x1d, 0x78, 0x8f, 0xc4, 0x2e, 0x35, 0x41, 0xd7, 0x88, 0xfc, 0xeb, 0x9d, + 0xc3, 0xef, 0x45, 0xe3, 0xd9, 0xa6, 0x71, 0x04, 0x86, 0x9e, 0x9d, 0xc3, 0xde, 0x9f, 0x0d, 0xfa, + 0x25, 0x71, 0x0a, 0x0e, 0xac, 0x88, 0xc3, 0x8f, 0x44, 0x61, 0xa7, 0xa7, 0x5c, 0xf8, 0x7b, 0xd3, + 0xf8, 0x76, 0x30, 0x15, 0x45, 0x2b, 0xff, 0x4d, 0x3d, 0x34, 0xc4, 0x52, 0x18, 0xac, 0x43, 0xa2, + 0x1d, 0xf8, 0x6d, 0xc0, 0x7b, 0x5c, 0xb7, 0xfe, 0x9a, 0x7a, 0x69, 0x88, 0x29, 0x0e, 0xf1, 0x03, + 0xa2, 0x07, 0x7e, 0x1e, 0xc2, 0x25, 0x40, 0xa7, 0xfe, 0x9a, 0x7e, 0xb8, 0xab, 0x2e, 0xfc, 0x5b, + 0x16, 0x1b, 0xf6, 0x49, 0x8e, 0x44, 0x12, 0x7a, 0x5c, 0x23, 0x8b, 0x42, 0xb7, 0xf6, 0xc5, 0x17, + 0xf0, 0xf2, 0x33, 0x3f, 0xfd, 0x3f, 0x8d, 0xa7, 0x2e, 0x97, 0x7e, 0x11, 0x58, 0x07, 0x1b, 0x39, + 0xb5, 0xae, 0x9c, 0x61, 0x31, 0x16, 0xa3, 0x1e, 0xa5, 0x25, 0xea, 0x69, 0xb6, 0xdb, 0x6d, 0xa6, + 0x9c, 0x24, 0x4a, 0x41, 0xbf, 0x1f, 0x4f, 0x4f, 0xe1, 0x15, 0x13, 0xe9, 0x52, 0x49, 0x7f, 0x08, + 0x28, 0xef, 0x37, 0x6d, 0xbf, 0x84, 0x14, 0x9a, 0xfd, 0x34, 0xfe, 0x12, 0x50, 0x5f, 0xfc, 0x8f, + 0xed, 0xb7, 0xf0, 0x82, 0x88, 0x72, 0xfc, 0xda, 0x6d, 0xf8, 0x71, 0x10, 0x36, 0x19, 0x5f, 0xfe, + 0x9a, 0x7f, 0x76, 0xdb, 0xf8, 0xa5, 0x35, 0xc2, 0x0a, 0x11, 0x32, 0x8b, 0x66, 0x54, 0xff, 0x8f, + 0x62, 0x45, 0x30, 0x38, 0xa2, 0x1c, 0x7b, 0x66, 0xff, 0x08, 0x23, 0x86, 0xfc, 0x3e, 0xe9, 0xa7, + 0xf0, 0xc2, 0x14, 0x00, 0x22, 0x3f, 0x55, 0xfd, 0xff, 0xff, 0xff, 0xd9, 0xc4, 0x78, 0xaa, 0xc3, + 0x44, 0x30, 0x01, 0x9b, 0x31, 0x64, 0xfd, 0x57, 0xd1, 0xce, 0x67, 0xee, 0xee, 0x4a, 0x63, 0xdd, + 0x32, 0xf8, 0x8d, 0xa8, 0x60, 0x90, 0x03, 0x73, 0x26, 0xc5, 0x9f, 0xaf, 0x7f, 0x5d, 0xb6, 0xc9, + 0xd9, 0xe6, 0x6b, 0x0d, 0xa3, 0x00, 0x03, 0x99, 0x1a, 0x7e, 0x84, 0xc3, 0x97, 0x0c, 0x56, 0xfe, + 0xa6, 0x98, 0x55, 0xe1, 0x2f, 0xe3, 0x4d, 0xca, 0xd7, 0xea, 0x51, 0x1a, 0x0c, 0x31, 0x89, 0x28, + 0xb1, 0x7e, 0x28, 0x25, 0xc8, 0x0d, 0xa5, 0x61, 0xfa, 0xbc, 0x2f, 0x80, 0x1a, 0x80, 0x01, 0x49, + 0x14, 0x50, 0x88, 0x1f, 0x10, 0x96, 0x9a, 0x79, 0x7a, 0x73, 0x28, 0x06, 0xf1, 0x50, 0xce, 0x8b, + 0x69, 0x03, 0x8e, 0x3f, 0xc3, 0xb2, 0x28, 0x5d, 0x94, 0x00, 0x12, 0x58, 0xba, 0x6e, 0x82, 0xeb, + 0xb5, 0x84, 0xa7, 0x4f, 0xe0, 0xff, 0x97, 0x8f, 0x78, 0x78, 0xff, 0xac, 0x26, 0xe0, 0x0d, 0x7e, + 0xc0, 0x9a, 0x69, 0x6b, 0xff, 0xbd, 0xe1, 0x94, 0x2c, 0x09, 0xff, 0x44, 0x9f, 0xcd, 0x71, 0xb7, + 0x8f, 0x4f, 0xfe, 0x8e, 0xe1, 0x45, 0x01, 0x3b, 0xee, 0x28, 0x0d, 0xff, 0xad, 0x7e, 0x39, 0xc0, + 0x23, 0xd8, 0xfa, 0x49, 0xd8, 0xd5, 0x00, 0x9a, 0xef, 0x18, 0xe5, 0x61, 0x94, 0x30, 0x00, 0x1f, + 0x4c, 0x6d, 0xd9, 0x51, 0xee, 0x30, 0xad, 0xff, 0xe7, 0xdd, 0xc7, 0x78, 0x70, 0x2b, 0xe5, 0x6f, + 0x4b, 0xef, 0xee, 0xbc, 0x8a, 0x1a, 0x90, 0x00, 0x1e, 0xe4, 0x2d, 0xd9, 0xc7, 0x92, 0x2c, 0x25, + 0xef, 0xff, 0x8b, 0x46, 0xc7, 0xbe, 0xde, 0xdb, 0x75, 0xb7, 0x07, 0xbe, 0xdd, 0x92, 0x3d, 0x59, + 0xc3, 0xd4, 0xf7, 0x32, 0x9d, 0x85, 0xc0, 0x43, 0xe7, 0x3f, 0x23, 0x11, 0x43, 0xef, 0x0e, 0xd9, + 0xd7, 0x15, 0xe7, 0x5c, 0xef, 0x9d, 0x43, 0x1e, 0x9d, 0x43, 0x8f, 0x47, 0x46, 0x82, 0xe2, 0x70, + 0x98, 0x0c, 0x08, 0x0d, 0x89, 0x5c, 0x31, 0x09, 0x02, 0x45, 0x39, 0xe5, 0xff, 0xf8, 0xb6, 0x2d, + 0xf6, 0x17, 0x64, 0x0d, 0x32, 0xff, 0xf8, 0x9e, 0x89, 0xef, 0x8a, 0x53, 0x3a, 0xe2, 0x17, 0x3b, + 0xe2, 0x3c, 0x64, 0x2f, 0x1c, 0x6c, 0x42, 0xe2, 0x17, 0x10, 0xb8, 0x6e, 0x1a, 0x00, 0xe4, 0xc2, + 0xa0, 0x5a, 0x3f, 0xd3, 0x4d, 0x34, 0xf4, 0xd3, 0x05, 0x00, 0x01, 0x08, 0xe0, 0x03, 0xed, 0xb7, + 0xf0, 0x82, 0x28, 0x03, 0xd9, 0x1e, 0x54, 0x45, 0xd3, 0x4f, 0xe1, 0xd5, 0x04, 0xbb, 0x9e, 0x7f, + 0x4d, 0x3f, 0xfc, 0x10, 0x96, 0x2a, 0xff, 0x87, 0x11, 0x01, 0x19, 0xba, 0x3f, 0xff, 0x4d, 0x3c, + 0x91, 0x7a, 0x69, 0xf1, 0x8a, 0x00, 0xff, 0xaf, 0xb8, 0x33, 0xf0, 0xe2, 0x81, 0x10, 0xb9, 0x3f, + 0x1e, 0xdb, 0x7f, 0xf8, 0xb8, 0x85, 0x3b, 0x6d, 0xb7, 0xc2, 0x4a, 0x01, 0x2f, 0x62, 0xde, 0x68, + 0xd1, 0xdf, 0x4d, 0x3f, 0x86, 0x11, 0x00, 0x7a, 0x9c, 0xb6, 0x9a, 0x7a, 0x69, 0xff, 0x99, 0x78, + 0xc2, 0x5d, 0xb1, 0x4a, 0x5b, 0x8c, 0x50, 0x99, 0x2a, 0x3b, 0x10, 0xa3, 0x5e, 0x8a, 0xc6, 0xbd, + 0x1c, 0xa4, 0xbc, 0xb1, 0x04, 0x83, 0x5d, 0xac, 0x41, 0x23, 0x6d, 0x63, 0x89, 0x06, 0xe9, 0x66, + 0x4c, 0x52, 0x98, 0x83, 0x10, 0xad, 0xc3, 0xca, 0x05, 0xf7, 0x2e, 0xff, 0xdb, 0x6f, 0xcb, 0xb6, + 0xff, 0x87, 0x89, 0x00, 0x64, 0x52, 0xde, 0x21, 0xf0, 0xf8, 0xff, 0xdb, 0xb7, 0x93, 0x83, 0xd3, + 0xd6, 0xdb, 0x4c, 0x1f, 0x74, 0xed, 0xb7, 0x0e, 0x38, 0x00, 0xfc, 0x3b, 0x11, 0x50, 0xca, 0x62, + 0x8a, 0xde, 0x2f, 0xe4, 0xf7, 0xf1, 0x56, 0xda, 0x8a, 0xb3, 0x70, 0x45, 0x8d, 0xa5, 0xff, 0x86, + 0xb0, 0x90, 0x5d, 0xf1, 0xfd, 0xab, 0xfe, 0xd8, 0x5b, 0x00, 0x0d, 0x62, 0x64, 0xc6, 0x14, 0x85, + 0x24, 0xb3, 0x3f, 0xbd, 0xea, 0x06, 0x73, 0xf4, 0xa2, 0x0d, 0x07, 0x86, 0x5f, 0x3b, 0x07, 0x43, + 0xc1, 0xf7, 0x0b, 0xa3, 0x04, 0x70, 0x0d, 0x7a, 0x0d, 0x27, 0x41, 0x7e, 0x7c, 0xf6, 0x13, 0x83, + 0x02, 0x7c, 0xf0, 0x60, 0x99, 0xe0, 0xc0, 0x90, 0x38, 0x67, 0x24, 0x0e, 0x19, 0xdb, 0xcf, 0x06, + 0x16, 0x78, 0x30, 0x1f, 0x05, 0xaa, 0x19, 0x24, 0x00, 0x79, 0x41, 0x25, 0xf5, 0x9c, 0x07, 0x94, + 0xcc, 0xb0, 0x88, 0x3a, 0xf6, 0x49, 0x1f, 0xfa, 0x3c, 0xc3, 0x5f, 0x34, 0xce, 0xc7, 0xe7, 0xf9, + 0xf9, 0x78, 0xf5, 0x0d, 0xe0, 0x54, 0xd7, 0x25, 0x9e, 0x65, 0x52, 0x0c, 0x33, 0x16, 0x03, 0x38, + 0x96, 0xf1, 0x27, 0x58, 0x76, 0xef, 0xfd, 0x57, 0xff, 0x20, 0x8d, 0x70, 0xba, 0x80, 0x59, 0xf2, + 0x28, 0xe5, 0x75, 0x75, 0x55, 0x5f, 0x55, 0x55, 0x4a, 0xa1, 0x64, 0x50, 0x12, 0xb6, 0x90, 0xdf, + 0xef, 0x7f, 0xc6, 0xa1, 0x20, 0x22, 0x6a, 0xa3, 0xc5, 0x4c, 0x42, 0x21, 0xf6, 0x39, 0x98, 0x52, + 0xfb, 0x0a, 0x22, 0x00, 0x0a, 0x7e, 0x90, 0xd9, 0xc8, 0x51, 0x1f, 0x7b, 0xc4, 0x3d, 0x94, 0x88, + 0x7f, 0xc5, 0x74, 0xf0, 0x16, 0x20, 0xe4, 0x28, 0x42, 0xc1, 0x88, 0x1e, 0x3b, 0x61, 0xfd, 0x1c, + 0x7e, 0x34, 0xb0, 0xb8, 0xf1, 0xd8, 0x8b, 0x0c, 0xef, 0x03, 0x96, 0xd4, 0xa5, 0xad, 0x6e, 0x70, + 0x0e, 0x1c, 0x03, 0x83, 0x80, 0x00, 0x80, 0x14, 0x7e, 0x1a, 0x98, 0x00, 0xb5, 0x50, 0x27, 0x3d, + 0x4a, 0xc0, 0x52, 0x2c, 0x48, 0xf5, 0x64, 0xcf, 0x0f, 0x7d, 0xb6, 0xf6, 0xdf, 0xef, 0x88, 0x7d, + 0xc1, 0xef, 0xb6, 0x17, 0x62, 0xc0, 0x02, 0x0f, 0x49, 0xde, 0x9a, 0x67, 0xfe, 0x9c, 0xa0, 0x7f, + 0x47, 0xe8, 0xb3, 0x10, 0xf8, 0xc8, 0x76, 0x8e, 0x73, 0xae, 0x78, 0xc0, 0xc0, 0xf4, 0xf8, 0x71, + 0xe8, 0xe8, 0xd0, 0x5c, 0x4e, 0x13, 0x47, 0x38, 0x98, 0xc0, 0xe3, 0xd0, 0xdc, 0x28, 0x00, 0x19, + 0x01, 0x65, 0x22, 0x30, 0xf9, 0x88, 0x7f, 0x7f, 0xe9, 0xa6, 0x98, 0x3e, 0xe4, 0xe3, 0xd7, 0x08, + 0x48, 0x87, 0x66, 0xa2, 0x63, 0xcb, 0xfc, 0x3c, 0x42, 0x00, 0x16, 0xcf, 0x89, 0x08, 0x21, 0xf7, + 0xfa, 0xcd, 0xc9, 0xc9, 0xc9, 0xcb, 0xbf, 0x2e, 0xfb, 0x79, 0xbb, 0x87, 0x1f, 0x51, 0x27, 0x96, + 0xb1, 0x57, 0xf0, 0xe2, 0x80, 0x39, 0x9b, 0x74, 0xc9, 0xeb, 0xf3, 0x47, 0xb7, 0x2f, 0x2d, 0x1b, + 0x2b, 0xf9, 0xb6, 0xed, 0xb6, 0x3b, 0x76, 0xe4, 0x58, 0x96, 0xff, 0xc3, 0x78, 0x00, 0x4b, 0x21, + 0x31, 0xa1, 0xdc, 0x34, 0x88, 0x74, 0xaf, 0xfb, 0x28, 0x5f, 0x37, 0xfb, 0xe8, 0x3c, 0xfe, 0x0d, + 0xbe, 0xc7, 0xbe, 0x98, 0x24, 0xa4, 0xbe, 0xff, 0x9d, 0x86, 0x43, 0x7e, 0x88, 0x5c, 0xee, 0x1e, + 0xf4, 0xeb, 0x9d, 0x73, 0xbe, 0x78, 0xd1, 0x40, 0x07, 0x17, 0x09, 0x03, 0x20, 0x01, 0xa8, 0xaa, + 0xc2, 0x88, 0x80, 0x1c, 0xe4, 0xc1, 0x52, 0x4d, 0x3d, 0x34, 0xff, 0xf8, 0xc5, 0x01, 0xeb, 0x0a, + 0x4f, 0xe1, 0x45, 0x00, 0xe3, 0x4f, 0xa7, 0x7b, 0x6d, 0xff, 0xf1, 0xca, 0x1e, 0x4d, 0x46, 0xc7, + 0x22, 0x04, 0x66, 0xa9, 0xdf, 0x1c, 0xa1, 0x94, 0x83, 0x0d, 0xc1, 0x0e, 0x18, 0x42, 0x40, 0xe8, + 0xeb, 0x2f, 0xfd, 0xb6, 0xf6, 0xdb, 0x44, 0x5a, 0x86, 0x14, 0x2f, 0x64, 0xdb, 0x6d, 0xb7, 0xff, + 0xed, 0x8e, 0x24, 0x38, 0xe3, 0xf6, 0x23, 0x06, 0x66, 0x71, 0x88, 0xc1, 0xc1, 0x3e, 0x4f, 0x88, + 0x50, 0x42, 0x60, 0xc3, 0xa2, 0x94, 0x25, 0x6a, 0x51, 0x4a, 0x10, 0xa4, 0xb1, 0xde, 0xb1, 0xd2, + 0x8f, 0x3e, 0x51, 0xdc, 0x62, 0x85, 0x96, 0xe7, 0xc2, 0xf2, 0x01, 0x3d, 0x74, 0xea, 0xff, 0xdb, + 0x6e, 0xdb, 0x62, 0xac, 0x53, 0x61, 0xd2, 0x18, 0x00, 0x4d, 0x8e, 0x11, 0x27, 0x79, 0x33, 0x5f, + 0xdf, 0xf8, 0xab, 0x6a, 0x0f, 0xb8, 0x3e, 0xec, 0xe0, 0x72, 0x83, 0x0d, 0x65, 0xc9, 0xd3, 0xed, + 0xc3, 0xc4, 0x20, 0x00, 0x4a, 0x4e, 0xde, 0xf5, 0x10, 0xac, 0xdf, 0x56, 0x6e, 0x4e, 0x4e, 0x4e, + 0xda, 0x60, 0xe9, 0xf6, 0x7f, 0x6c, 0x2a, 0xf1, 0x3b, 0xc7, 0xbd, 0xfc, 0x19, 0xd8, 0xb1, 0xed, + 0x9f, 0xe9, 0x93, 0xc2, 0xee, 0x00, 0xaf, 0xf6, 0xe0, 0xaa, 0x04, 0xb7, 0x9f, 0xd5, 0xf5, 0x5d, + 0x72, 0xb2, 0xab, 0xbb, 0xb0, 0xd2, 0x38, 0x03, 0x2f, 0xe5, 0x03, 0x05, 0xf4, 0xd3, 0xfe, 0x9a, + 0x77, 0xc2, 0x68, 0x80, 0x04, 0xcd, 0x91, 0x02, 0x1f, 0xd0, 0xf7, 0xd7, 0x75, 0x7f, 0x58, 0x8f, + 0xbd, 0xcd, 0x03, 0xbc, 0xfc, 0x0e, 0xf8, 0x69, 0x88, 0x00, 0x0e, 0x56, 0x12, 0xa4, 0x72, 0x86, + 0xe2, 0xff, 0xbf, 0x54, 0xc9, 0xe4, 0xe2, 0x3c, 0x7d, 0xe3, 0x8e, 0x32, 0xe5, 0x3e, 0x17, 0x21, + 0x40, 0x07, 0xd9, 0x68, 0x85, 0x6d, 0x43, 0x51, 0x89, 0x0d, 0x8e, 0xe8, 0x9e, 0x1e, 0x51, 0xae, + 0x86, 0xb4, 0x69, 0x8a, 0x0f, 0x71, 0x78, 0x4a, 0x99, 0xbb, 0x69, 0xcf, 0x86, 0x90, 0xb0, 0x11, + 0x63, 0xd0, 0x08, 0x5a, 0xff, 0xdb, 0x6f, 0xec, 0x2e, 0xe0, 0x9d, 0x16, 0xcd, 0xfe, 0xeb, 0xaf, + 0x7c, 0x2e, 0xce, 0x08, 0xc8, 0xe2, 0x7c, 0x2d, 0x7f, 0xff, 0xd8, 0xa9, 0x00, 0x76, 0x65, 0x2d, + 0x13, 0x38, 0x35, 0xb2, 0x89, 0x70, 0x11, 0x1d, 0xdb, 0xf8, 0x9e, 0x40, 0x5e, 0x88, 0x18, 0x51, + 0x40, 0x19, 0x8a, 0x3d, 0x94, 0x2a, 0x6c, 0xb8, 0xe5, 0xff, 0xff, 0x85, 0x10, 0x80, 0x02, 0xdc, + 0x9c, 0x68, 0x09, 0xf7, 0x4f, 0x2f, 0x6f, 0xa7, 0xff, 0x80, 0x2c, 0x00, 0x1a, 0x23, 0x44, 0x0e, + 0x40, 0xb0, 0x38, 0x68, 0x45, 0x8e, 0x4f, 0x00, 0x03, 0x5c, 0x50, 0x00, 0x31, 0x0e, 0x71, 0x28, + 0x73, 0x80, 0x4b, 0x54, 0x35, 0x39, 0xed, 0xd2, 0x66, 0x87, 0x8b, 0x00, 0x77, 0x00, 0x43, 0x98, + 0x38, 0xff, 0xfc, 0x2f, 0x80, 0x0b, 0xc9, 0x40, 0x09, 0xe8, 0xcf, 0x0e, 0x44, 0xde, 0xe6, 0x5d, + 0xfc, 0x70, 0xfe, 0x0c, 0x3f, 0x63, 0xff, 0x1c, 0x70, 0xfe, 0x0e, 0x7e, 0x65, 0x61, 0xb8, 0xb0, + 0x01, 0xa1, 0x59, 0x6c, 0x76, 0xa7, 0x17, 0xfe, 0x29, 0x62, 0xde, 0x9a, 0x6b, 0x8a, 0xb1, 0x57, + 0xf0, 0xec, 0x48, 0x56, 0xd7, 0xff, 0x4d, 0x3d, 0x34, 0xe2, 0xed, 0xb7, 0xf0, 0xc3, 0x28, 0x71, + 0x8a, 0xff, 0xed, 0xb7, 0xb6, 0xdb, 0x62, 0x57, 0x11, 0x28, 0x71, 0xe8, 0x7a, 0x14, 0x00, 0x23, + 0x30, 0x9d, 0xe3, 0x04, 0x24, 0x5f, 0x27, 0x58, 0xfc, 0x5e, 0x2f, 0x03, 0xc2, 0x38, 0xde, 0x0f, + 0x2f, 0x11, 0x87, 0xc3, 0xc8, 0x80, 0x19, 0xcb, 0xe5, 0x09, 0x83, 0xde, 0x8d, 0x3a, 0xb3, 0xf1, + 0xa6, 0x9a, 0x6a, 0xf6, 0xd6, 0x22, 0xd1, 0x75, 0x96, 0xbd, 0xbf, 0x87, 0x59, 0xc0, 0x09, 0x20, + 0x88, 0xca, 0xc8, 0xca, 0xe7, 0xb4, 0x1f, 0x71, 0x6f, 0x3b, 0xf0, 0x76, 0xf2, 0xf2, 0xf7, 0xf1, + 0x71, 0x6c, 0x1e, 0xb8, 0xf4, 0x63, 0xa6, 0xa7, 0xff, 0x0f, 0x28, 0x00, 0x57, 0xe8, 0x5e, 0xe2, + 0xac, 0xc8, 0x9f, 0x33, 0x2f, 0x5b, 0x8c, 0x9d, 0x65, 0xf6, 0x4e, 0x2f, 0x8e, 0x53, 0xc5, 0x58, + 0x3b, 0xff, 0xf8, 0x64, 0x10, 0x85, 0x08, 0x76, 0x0b, 0x1b, 0xd8, 0x2c, 0x61, 0xfc, 0xa3, 0x84, + 0x6c, 0x5e, 0xae, 0x65, 0xc5, 0x19, 0xf9, 0x48, 0xd4, 0xb5, 0x9f, 0x65, 0xef, 0x24, 0x07, 0x06, + 0x8d, 0x0e, 0x1b, 0x70, 0x00, 0xc0, 0x14, 0x45, 0x20, 0x18, 0xa5, 0x14, 0x3c, 0x8f, 0xff, 0x82, + 0x8f, 0x63, 0xcf, 0x97, 0xf8, 0xff, 0x92, 0x0f, 0x16, 0xce, 0x1f, 0xde, 0x04, 0x26, 0x97, 0xdf, + 0xf1, 0x70, 0x98, 0x6f, 0xc4, 0x65, 0x51, 0x6a, 0x1b, 0xf2, 0x55, 0x08, 0x10, 0x40, 0x77, 0x2c, + 0x02, 0x2e, 0x6d, 0x16, 0xfe, 0x10, 0x50, 0x75, 0x60, 0xc1, 0x45, 0x59, 0xb4, 0xdb, 0xf0, 0xe2, + 0x30, 0x71, 0x3f, 0xdf, 0xff, 0xe9, 0xa6, 0x12, 0x2c, 0xee, 0x4e, 0x0e, 0x6f, 0xf0, 0x82, 0x81, + 0xd5, 0xf8, 0x48, 0xd6, 0x53, 0x4d, 0xba, 0xdd, 0xf8, 0xb8, 0x90, 0x28, 0x60, 0x03, 0xa0, 0x60, + 0xaf, 0x18, 0xa0, 0x66, 0x39, 0x1f, 0x18, 0xa1, 0x10, 0xd5, 0xe1, 0x13, 0x1c, 0xa0, 0x1f, 0xfd, + 0x4d, 0x96, 0x3b, 0x0e, 0x99, 0x59, 0xf1, 0xc4, 0x82, 0xdf, 0x30, 0xab, 0xc6, 0x28, 0x35, 0xda, + 0x08, 0x8e, 0xa1, 0x82, 0x42, 0x45, 0x50, 0xdb, 0x7b, 0x6d, 0xff, 0xed, 0x8a, 0x53, 0x52, 0x30, + 0x92, 0x63, 0xe2, 0x94, 0x73, 0xa2, 0x94, 0x38, 0xc5, 0xc5, 0xa2, 0x84, 0xeb, 0x38, 0xc6, 0x75, + 0x15, 0xc5, 0x12, 0x18, 0x69, 0xa3, 0x88, 0x52, 0xc0, 0xc9, 0x8b, 0x21, 0x03, 0x60, 0x78, 0xab, + 0xc3, 0x44, 0x20, 0x01, 0x8f, 0x7d, 0x73, 0xfb, 0xaa, 0xff, 0xfe, 0xe9, 0x94, 0x3c, 0x41, 0x40, + 0x01, 0xdc, 0x9a, 0x49, 0x30, 0x35, 0x62, 0x3c, 0xfd, 0xb1, 0xce, 0x7c, 0x9c, 0x9c, 0x7d, 0xd9, + 0xe4, 0x32, 0x40, 0xe1, 0xac, 0x59, 0x39, 0x3f, 0x3f, 0x6f, 0x86, 0xb0, 0x01, 0x4a, 0xe6, 0x89, + 0x18, 0xe1, 0x5d, 0x4f, 0xed, 0xfe, 0xd8, 0xda, 0xbd, 0x81, 0xdd, 0x8a, 0x1c, 0x35, 0x20, 0x03, + 0x55, 0x41, 0xb9, 0x8e, 0x36, 0x2f, 0x3f, 0x97, 0x5a, 0xed, 0xdd, 0x6b, 0xac, 0x26, 0xca, 0x12, + 0x8b, 0x34, 0xb5, 0xff, 0xfc, 0x53, 0xbc, 0x2d, 0x20, 0x00, 0x9c, 0x29, 0x0a, 0x3a, 0x39, 0x57, + 0x1f, 0xf6, 0xea, 0xc8, 0xef, 0x07, 0xdc, 0x58, 0xc9, 0x75, 0xa9, 0x78, 0x67, 0x30, 0x1f, 0xd0, + 0x19, 0x37, 0xec, 0xe8, 0x98, 0x05, 0x60, 0x18, 0x85, 0x20, 0xb9, 0x48, 0x00, 0x04, 0x00, 0x76, + 0xe4, 0x80, 0x0f, 0x17, 0x60, 0x5b, 0xe6, 0x03, 0x52, 0xef, 0x46, 0x80, 0xd8, 0x31, 0xa0, 0x32, + 0x48, 0x78, 0x01, 0xe5, 0x80, 0x01, 0x49, 0xe3, 0x2c, 0x19, 0xc0, 0xf2, 0xc0, 0x00, 0x8c, 0x7b, + 0xd2, 0x88, 0x12, 0x92, 0x80, 0xa9, 0x46, 0x50, 0xd8, 0x28, 0xca, 0xc4, 0x86, 0x42, 0x95, 0x41, + 0xcb, 0xd7, 0x80, 0x00, 0x8f, 0x15, 0x20, 0x25, 0x66, 0x6a, 0x1c, 0x98, 0xd6, 0x32, 0x60, 0x00, + 0x27, 0x81, 0x93, 0x3e, 0x29, 0x01, 0x28, 0xf7, 0xce, 0x0f, 0x8c, 0x98, 0x00, 0x15, 0x21, 0x80, + 0x07, 0x91, 0x30, 0x0a, 0x87, 0x50, 0x03, 0x51, 0xce, 0x61, 0x37, 0x00, 0x04, 0xa6, 0x59, 0x13, + 0x43, 0xe6, 0xe2, 0x34, 0x9f, 0xf8, 0xb5, 0xfb, 0x4c, 0x33, 0x97, 0x37, 0xee, 0xf1, 0xc4, 0x12, + 0x00, 0xc3, 0xe9, 0x9d, 0xda, 0xec, 0x76, 0x17, 0x0d, 0x3b, 0x0b, 0x28, 0x45, 0xea, 0xbf, 0xff, + 0xd3, 0xc2, 0xca, 0x1b, 0x1f, 0xbf, 0xfa, 0x7f, 0x3e, 0x02, 0xce, 0x52, 0x34, 0x4b, 0x38, 0x44, + 0x24, 0x7b, 0x8b, 0x94, 0x03, 0x7b, 0x12, 0xa5, 0x95, 0x85, 0x91, 0x01, 0x02, 0x52, 0x71, 0xff, + 0x57, 0xfc, 0x6a, 0x87, 0x00, 0x52, 0x7d, 0x86, 0x11, 0x00, 0x02, 0x2b, 0x34, 0x77, 0x32, 0xbb, + 0xcb, 0xc7, 0x2f, 0xff, 0xe7, 0x44, 0x58, 0x38, 0x01, 0xd0, 0x14, 0x18, 0x3c, 0x00, 0xb0, 0x90, + 0x00, 0x0b, 0x28, 0x8e, 0x12, 0x15, 0x29, 0x4a, 0x3a, 0xbd, 0x8b, 0xa5, 0xc2, 0x8c, 0xe7, 0x8a, + 0x32, 0xc6, 0x58, 0x32, 0xd6, 0x24, 0x70, 0xb7, 0xbe, 0x1d, 0x45, 0x00, 0x10, 0x87, 0x20, 0x4b, + 0x9d, 0x4c, 0xe1, 0x9b, 0x9f, 0xf8, 0x3d, 0xf8, 0xe5, 0xf0, 0x72, 0xfe, 0x9a, 0x63, 0xff, 0x4f, + 0xf0, 0xf2, 0x38, 0x0d, 0xee, 0x9b, 0xce, 0xdf, 0xff, 0x4e, 0x0b, 0x6d, 0xa7, 0x4d, 0x3e, 0x1e, + 0x50, 0x1c, 0xe5, 0xcb, 0x7f, 0xa6, 0x9f, 0xe3, 0xa6, 0x2d, 0xb7, 0xfc, 0x62, 0x80, 0x24, 0x79, + 0x36, 0x15, 0x68, 0xbb, 0x0d, 0x90, 0xc0, 0x11, 0xf2, 0x99, 0x8e, 0xf7, 0xd6, 0xbe, 0xe2, 0x99, + 0xf8, 0xea, 0xe3, 0x0b, 0x8b, 0xc2, 0x2f, 0x2f, 0xf8, 0x7b, 0x00, 0x20, 0x01, 0x7d, 0x79, 0xe2, + 0x94, 0xf7, 0x7d, 0xdb, 0x4c, 0x51, 0xcf, 0xc4, 0xff, 0x12, 0xd0, 0x1d, 0xfd, 0x71, 0xdb, 0x15, + 0x65, 0x0c, 0xe9, 0xa7, 0xf0, 0xe2, 0x80, 0x27, 0x4c, 0x9b, 0xd9, 0x08, 0x71, 0x1f, 0xf7, 0x2d, + 0xe1, 0xf7, 0xc6, 0x97, 0xe7, 0xe2, 0xb9, 0x76, 0xcf, 0xcb, 0x5b, 0xfd, 0x83, 0x93, 0x59, 0xe9, + 0xed, 0xb7, 0x0e, 0x22, 0x00, 0x24, 0x7a, 0x1c, 0x75, 0xfc, 0x93, 0x87, 0xbf, 0xad, 0xb6, 0xed, + 0xb7, 0x8a, 0x9e, 0x9f, 0xc3, 0x84, 0x80, 0x0b, 0xb2, 0x24, 0xd4, 0x61, 0x94, 0x32, 0x27, 0x1f, + 0x1e, 0x7e, 0x7f, 0x6e, 0x9d, 0xe2, 0xd8, 0xb6, 0x07, 0x35, 0xf4, 0xff, 0x0d, 0xa8, 0x00, 0xab, + 0x3f, 0x12, 0x07, 0xf7, 0x98, 0x41, 0x5b, 0x15, 0x62, 0xad, 0xf9, 0xb9, 0xff, 0x27, 0x7a, 0xd9, + 0xd3, 0x05, 0x2c, 0x8d, 0xa6, 0xa9, 0x7c, 0x38, 0x8a, 0x04, 0xb2, 0x9b, 0xc7, 0xff, 0xa6, 0x9d, + 0x30, 0xd8, 0x7c, 0x93, 0x8b, 0x75, 0x8a, 0xbf, 0x87, 0x14, 0x04, 0xdc, 0xa3, 0x8f, 0x7e, 0x9a, + 0x7d, 0xbd, 0xb6, 0xc7, 0x4a, 0x4d, 0x26, 0xd5, 0x57, 0xc2, 0x0a, 0x02, 0x99, 0x07, 0x50, 0x0c, + 0x0c, 0x7b, 0x97, 0x7d, 0x34, 0xe1, 0x25, 0x01, 0x17, 0x21, 0x70, 0xbc, 0x38, 0x98, 0x96, 0xb2, + 0xd7, 0xfc, 0x3c, 0xa0, 0x43, 0x8e, 0x43, 0x3b, 0xfb, 0x7f, 0xf9, 0xaf, 0xd2, 0xd7, 0xfc, 0x62, + 0x85, 0x00, 0x57, 0x31, 0x8f, 0x94, 0x1d, 0xb4, 0x40, 0x00, 0x87, 0x4e, 0x28, 0x58, 0xa1, 0x7f, + 0x18, 0xa7, 0xc2, 0xa6, 0x21, 0x43, 0x4e, 0x94, 0x22, 0xb0, 0x1a, 0xa7, 0xfe, 0x39, 0x4b, 0x86, + 0x4c, 0x30, 0xa5, 0x25, 0xff, 0xa6, 0x9e, 0x9a, 0x6e, 0x61, 0x45, 0x36, 0x7f, 0xed, 0xb7, 0xf0, + 0xc2, 0x97, 0x3f, 0xff, 0xb7, 0x2c, 0x5a, 0xb8, 0xfb, 0x18, 0xa2, 0xab, 0x2c, 0x42, 0xac, 0x24, + 0xa2, 0x38, 0x22, 0x92, 0x9a, 0x6d, 0x35, 0xf0, 0x82, 0x29, 0x08, 0x8a, 0x8e, 0xde, 0x2a, 0xfe, + 0x10, 0x52, 0x78, 0xc5, 0xb6, 0xc9, 0xac, 0xdf, 0x8b, 0x52, 0x28, 0xf6, 0x10, 0x58, 0x07, 0x7b, + 0x7f, 0x08, 0xa9, 0xf5, 0x76, 0xdb, 0xf8, 0x78, 0x84, 0x00, 0x0f, 0xf6, 0x9d, 0x56, 0x07, 0xf3, + 0x7f, 0xef, 0xbd, 0x99, 0x3b, 0x73, 0xf1, 0xce, 0x27, 0xd9, 0xe0, 0xc5, 0xc3, 0x58, 0x59, 0x3a, + 0xf3, 0xf3, 0xfe, 0x1a, 0xc1, 0x02, 0xce, 0x5e, 0x7d, 0xdb, 0x6f, 0xff, 0x03, 0xbf, 0x18, 0x57, + 0x00, 0x64, 0xe1, 0x34, 0xaa, 0x77, 0xb5, 0x27, 0x9f, 0xc5, 0x6b, 0xef, 0x74, 0xe1, 0x76, 0x60, + 0x20, 0x64, 0x9e, 0x1f, 0x29, 0x4d, 0x5d, 0xbe, 0xae, 0x4e, 0x5b, 0xf6, 0x63, 0x98, 0x90, 0x07, + 0xae, 0x8c, 0x1d, 0x76, 0x93, 0x1c, 0xa0, 0x44, 0x0d, 0x80, 0x45, 0xba, 0xf6, 0x15, 0x44, 0x00, + 0x19, 0x45, 0x1a, 0x80, 0x1d, 0x30, 0x58, 0x7f, 0xfd, 0x26, 0x5a, 0x37, 0x64, 0xe3, 0xd1, 0x96, + 0xc4, 0x7f, 0x8b, 0x63, 0xd7, 0x96, 0xb0, 0xc2, 0x80, 0x20, 0x08, 0x68, 0xd4, 0xbf, 0x82, 0xc4, + 0x92, 0xfb, 0xfa, 0xcf, 0xc7, 0x17, 0xcf, 0x7b, 0xaa, 0xee, 0xd8, 0xfb, 0x97, 0x63, 0x72, 0xe1, + 0x72, 0x10, 0x00, 0xc3, 0x43, 0xb2, 0x73, 0xef, 0x7f, 0x3c, 0x33, 0xc3, 0x76, 0xe2, 0xb3, 0xd8, + 0x39, 0xec, 0x2e, 0xee, 0xf4, 0x6b, 0x85, 0x19, 0x40, 0x13, 0xfb, 0x98, 0x4f, 0x1c, 0x79, 0x42, + 0x82, 0x5c, 0x58, 0xe4, 0xf5, 0x77, 0xb7, 0xf3, 0xfb, 0xf0, 0x2c, 0x80, 0x48, 0x01, 0x49, 0x6b, + 0x5d, 0x54, 0x51, 0xc5, 0x18, 0xac, 0x70, 0x31, 0xdc, 0xec, 0xe0, 0x4c, 0x4e, 0x14, 0xda, 0x33, + 0x0a, 0x55, 0xb0, 0xaa, 0x80, 0xaf, 0x21, 0xef, 0xc4, 0xf4, 0xff, 0xe6, 0xa2, 0x3e, 0x76, 0x43, + 0x64, 0x53, 0x12, 0x20, 0x91, 0x9d, 0x10, 0x2b, 0x4c, 0xc2, 0xce, 0x01, 0xde, 0x51, 0xed, 0xef, + 0xff, 0xf8, 0xa5, 0x04, 0xcf, 0xd6, 0x42, 0xce, 0x04, 0x73, 0x60, 0x24, 0x55, 0xfb, 0x6d, 0xff, + 0xc7, 0x22, 0x02, 0x77, 0xab, 0x3d, 0xc0, 0x92, 0x02, 0x00, 0x28, 0x20, 0x47, 0x03, 0xe1, 0x29, + 0x68, 0x80, 0x46, 0x1f, 0x1a, 0x96, 0x2c, 0xf0, 0x06, 0x0c, 0x1b, 0x02, 0x83, 0x2c, 0x60, 0x2b, + 0x13, 0x8b, 0xb5, 0xe2, 0x41, 0xc4, 0xaf, 0x5d, 0x82, 0xd6, 0x31, 0x08, 0x6d, 0x40, 0x02, 0x52, + 0x84, 0x37, 0x41, 0x74, 0x83, 0x70, 0x5e, 0xf2, 0x69, 0xbf, 0x96, 0xbc, 0x55, 0x8a, 0xb1, 0xc8, + 0xfa, 0x9e, 0x5b, 0xc5, 0x02, 0xb2, 0x71, 0xcf, 0xc5, 0xb0, 0x81, 0x0c, 0x83, 0x46, 0xd0, 0x9e, + 0x89, 0x3a, 0x1d, 0x0e, 0x0a, 0x17, 0xe1, 0xc5, 0x00, 0xd7, 0x05, 0x72, 0x1f, 0xb7, 0x4d, 0x34, + 0xf4, 0xd3, 0x6d, 0xb0, 0x50, 0xf2, 0x98, 0xb7, 0x1d, 0xb6, 0xf8, 0x71, 0x40, 0x5c, 0xe8, 0x12, + 0xda, 0xdb, 0x6d, 0x34, 0xf4, 0xc5, 0xbf, 0xf0, 0xc1, 0x8f, 0xa4, 0xd2, 0x69, 0xf5, 0xfb, 0xf0, + 0xe2, 0x80, 0x1b, 0xfb, 0x05, 0x37, 0xaa, 0xd4, 0xf8, 0xe3, 0xff, 0xc0, 0xc0, 0x0c, 0x29, 0x13, + 0xb8, 0xa3, 0x0f, 0xfe, 0x1d, 0x50, 0x1c, 0xa8, 0xc0, 0x58, 0xcf, 0x55, 0xb6, 0x9a, 0x62, 0xac, + 0x55, 0xa6, 0x9a, 0x74, 0xd3, 0xf1, 0xc4, 0x8c, 0xa2, 0xd6, 0x2a, 0xf4, 0xd3, 0xe1, 0xc4, 0x50, + 0x03, 0xaa, 0xd9, 0x2f, 0x0d, 0x78, 0x9a, 0x79, 0x76, 0x2d, 0xff, 0x4e, 0xb9, 0x4f, 0xaf, 0xdf, + 0xe1, 0xc5, 0x04, 0x02, 0x5d, 0xee, 0xa6, 0x9e, 0x9a, 0x7f, 0xf4, 0xf3, 0xdb, 0x6f, 0xf8, 0x68, + 0x90, 0x43, 0x9f, 0xdb, 0xff, 0xf6, 0xe6, 0x8c, 0x54, 0x3c, 0x48, 0x02, 0xd4, 0x89, 0xa0, 0x71, + 0x7f, 0xed, 0xb6, 0xdb, 0x6d, 0xb7, 0x3b, 0xa6, 0x9f, 0xc3, 0x0a, 0x00, 0x7e, 0xec, 0xa0, 0xe5, + 0x73, 0xc9, 0xa7, 0xf6, 0xf7, 0xf8, 0xf3, 0xe1, 0x85, 0x00, 0x77, 0xc4, 0xb0, 0xef, 0xff, 0xae, + 0x3e, 0xc3, 0x0a, 0x04, 0x8d, 0x86, 0x8f, 0x9b, 0x4d, 0x3d, 0x34, 0xfd, 0xb6, 0xf1, 0xff, 0x0a, + 0x28, 0x11, 0x83, 0x26, 0x0e, 0xdb, 0x7f, 0xe9, 0xa7, 0xc6, 0x28, 0x12, 0x29, 0x21, 0xca, 0x56, + 0x1a, 0x50, 0x4b, 0xdd, 0xe5, 0xff, 0xb7, 0xfb, 0x98, 0x6f, 0x00, 0x58, 0x0c, 0xa4, 0x79, 0x24, + 0xbf, 0xf1, 0x45, 0x8a, 0x2f, 0x14, 0x58, 0xa2, 0xc4, 0x21, 0xa1, 0xb5, 0x89, 0xe8, 0x9e, 0xed, + 0xb7, 0x0c, 0x28, 0x4e, 0x3b, 0xef, 0xef, 0xff, 0xd3, 0x5e, 0x7c, 0x30, 0xa0, 0x59, 0xc4, 0xcb, + 0xfe, 0xde, 0xdb, 0x74, 0xe2, 0xc3, 0x0a, 0x09, 0x17, 0x8e, 0x93, 0xfd, 0xbf, 0xfe, 0x58, 0x71, + 0x40, 0x28, 0xbf, 0x4e, 0x5f, 0x5f, 0xeb, 0x55, 0xcb, 0xa5, 0xdd, 0x34, 0xe1, 0xa2, 0x43, 0xc0, + 0xc9, 0xff, 0xb7, 0xdb, 0x6c, 0xc9, 0x87, 0x14, 0x00, 0xc4, 0xd6, 0x4a, 0x57, 0xb7, 0xff, 0x6f, + 0xe2, 0xe9, 0xa7, 0xf0, 0xe2, 0x28, 0x01, 0xdd, 0x5e, 0x90, 0xef, 0xff, 0xd3, 0x27, 0xaa, 0x69, + 0xf9, 0xfb, 0x6d, 0xfc, 0x2e, 0xa1, 0x20, 0x72, 0x9a, 0x3f, 0xf6, 0xdb, 0xf1, 0x52, 0x2a, 0x87, + 0x11, 0x40, 0x91, 0xa0, 0xe3, 0x55, 0x7f, 0xb6, 0xda, 0x69, 0xb6, 0xd9, 0x13, 0xb6, 0xdf, 0xc3, + 0x2a, 0x01, 0xff, 0x3f, 0xf2, 0x9a, 0x6d, 0xb7, 0xfb, 0x6d, 0xa6, 0x9b, 0x6d, 0x95, 0x30, 0xd2, + 0x81, 0x6e, 0xa9, 0x7f, 0xed, 0x8a, 0xba, 0x6d, 0xb7, 0x58, 0x5d, 0x40, 0x22, 0xdf, 0xaa, 0xfd, + 0xff, 0xe9, 0xb7, 0xe9, 0xa7, 0x96, 0x17, 0x50, 0x03, 0x00, 0xb9, 0xa7, 0xe5, 0xff, 0xff, 0xfe, + 0x9b, 0x7d, 0x86, 0x11, 0x00, 0x16, 0xf3, 0x48, 0xa7, 0xcb, 0xff, 0x6d, 0xbf, 0x8b, 0x08, 0xa8, + 0x19, 0xef, 0xd5, 0x34, 0xff, 0x87, 0x91, 0x00, 0x0c, 0x61, 0x2f, 0x7b, 0x2c, 0xfc, 0x9f, 0xb9, + 0xff, 0x76, 0xcf, 0xeb, 0x27, 0x67, 0xc0, 0x91, 0x08, 0x1d, 0x15, 0x22, 0xe4, 0x4b, 0xfe, 0x3b, + 0x30, 0x41, 0x91, 0x86, 0x93, 0x3b, 0x80, 0x63, 0x4c, 0x38, 0xa4, 0x28, 0xa0, 0x03, 0xa5, 0x6c, + 0x9e, 0xb6, 0x39, 0x3f, 0xfd, 0x3a, 0x78, 0x4d, 0x88, 0x03, 0x07, 0xc9, 0x0f, 0xfd, 0xff, 0x1d, + 0x16, 0x09, 0xc7, 0x2a, 0x1f, 0x0b, 0xe0, 0x24, 0x16, 0x89, 0x4c, 0xff, 0xf9, 0x3e, 0x99, 0x60, + 0x12, 0x00, 0x30, 0x8d, 0x30, 0x81, 0xe0, 0xf7, 0x80, 0xf3, 0xe7, 0x00, 0x30, 0x07, 0x45, 0xc9, + 0xc0, 0x00, 0xa2, 0x8e, 0xae, 0x3a, 0x00, 0x2e, 0x51, 0x59, 0x96, 0xa2, 0x88, 0x05, 0x90, 0x76, + 0x02, 0x52, 0xcc, 0x94, 0x00, 0x2a, 0x4e, 0x07, 0x22, 0xc0, 0xc3, 0xe1, 0x20, 0x10, 0x1b, 0x65, + 0xff, 0xc2, 0x78, 0x0c, 0xe0, 0x05, 0xa5, 0x54, 0x0d, 0x50, 0x7f, 0xe5, 0x9f, 0xcb, 0x38, 0xa7, + 0xad, 0x61, 0x92, 0x14, 0x00, 0x40, 0xf6, 0x2b, 0xaf, 0x0c, 0xbb, 0x56, 0xaa, 0x6f, 0x37, 0xff, + 0x97, 0x01, 0x62, 0x07, 0x10, 0x4b, 0x71, 0x5c, 0x76, 0xc5, 0xde, 0x38, 0x18, 0xef, 0x04, 0x21, + 0x80, 0x58, 0x55, 0x26, 0x5f, 0x55, 0xba, 0xc7, 0x03, 0x1d, 0xc5, 0x12, 0x01, 0x0f, 0xad, 0x81, + 0x45, 0xca, 0x00, 0x3e, 0xae, 0x9a, 0xe8, 0xbf, 0xfe, 0xc2, 0x6e, 0x02, 0x06, 0x90, 0x31, 0x7a, + 0xd6, 0xaa, 0xaa, 0xb5, 0xc5, 0x38, 0x4a, 0xd5, 0x13, 0xb8, 0x28, 0x43, 0x42, 0x32, 0x70, 0x12, + 0x2b, 0xa8, 0xf5, 0x61, 0x4c, 0x04, 0xea, 0xf3, 0x8f, 0x7a, 0xba, 0xbf, 0xfc, 0x74, 0x50, 0x11, + 0xde, 0x27, 0xa7, 0x63, 0xb0, 0x4d, 0xc8, 0x2f, 0x63, 0x30, 0x28, 0x23, 0x84, 0x3f, 0xd8, 0x69, + 0x44, 0xa3, 0x8d, 0x91, 0xb8, 0xff, 0xe9, 0xa7, 0xf7, 0xc3, 0x88, 0x40, 0x01, 0xb6, 0x32, 0x2e, + 0xe8, 0x2f, 0x3b, 0xd1, 0x6d, 0xbf, 0x1c, 0xbe, 0x3f, 0xe9, 0x8f, 0x7f, 0xfc, 0x2b, 0x4c, 0x8b, + 0x28, 0x2b, 0xbf, 0xc3, 0xd8, 0x00, 0x72, 0xa3, 0xe3, 0x62, 0xa7, 0x39, 0x8d, 0xdb, 0xdb, 0x6c, + 0x56, 0xed, 0xbb, 0x6d, 0xdb, 0x03, 0xdb, 0xa5, 0x5b, 0xab, 0x28, 0xdc, 0x55, 0x5d, 0xf0, 0xd2, + 0x28, 0x2c, 0x02, 0xe8, 0xd5, 0xaf, 0x6f, 0xfc, 0x79, 0x63, 0x94, 0x04, 0x2f, 0xdb, 0xff, 0xfa, + 0xf8, 0x71, 0x43, 0x80, 0x0c, 0xb7, 0xff, 0xae, 0xea, 0x9a, 0x7f, 0xc3, 0x0a, 0x01, 0x0f, 0xfb, + 0x97, 0xff, 0xab, 0xad, 0xb6, 0xee, 0xae, 0xbf, 0x30, 0xd1, 0x20, 0x89, 0x20, 0xae, 0x1d, 0x5d, + 0x7d, 0xd5, 0xd7, 0xcf, 0x61, 0x89, 0x40, 0x18, 0xa3, 0x96, 0xee, 0x38, 0xbf, 0x7d, 0x5f, 0xdb, + 0x6d, 0xb6, 0xd5, 0xdb, 0x3f, 0x14, 0x2f, 0x0a, 0xe0, 0x07, 0xd5, 0x38, 0x15, 0xc7, 0x7e, 0xaa, + 0x5f, 0xc5, 0xcb, 0xe7, 0xab, 0xfc, 0x32, 0xa0, 0x06, 0x60, 0xfe, 0x60, 0x5c, 0xbb, 0x8f, 0xfa, + 0x6a, 0x9a, 0x69, 0xf7, 0xc3, 0x58, 0x03, 0xd7, 0x1f, 0x52, 0xff, 0xf5, 0x9b, 0xb6, 0x36, 0x98, + 0x78, 0x90, 0x02, 0x20, 0xb2, 0x1e, 0x45, 0x95, 0xbb, 0xff, 0x6d, 0xb9, 0xbb, 0x6e, 0xf1, 0x74, + 0xd3, 0xf8, 0x65, 0x40, 0x17, 0xd5, 0xb1, 0x54, 0xea, 0xeb, 0xf7, 0x7f, 0x6f, 0xdb, 0x0c, 0xa8, + 0x09, 0x4f, 0x95, 0xaf, 0x7d, 0xef, 0x5e, 0x5f, 0x7f, 0x61, 0x9c, 0x00, 0x8a, 0xc9, 0x46, 0xc9, + 0x38, 0x6f, 0x9f, 0xff, 0xfb, 0x0d, 0xe0, 0x0f, 0x0a, 0x39, 0x29, 0x29, 0x7f, 0xe2, 0xd8, 0xb7, + 0x8b, 0x62, 0xd8, 0xc0, 0x00, 0x10, 0x01, 0x43, 0x42, 0xa3, 0x8d, 0xb6, 0xf6, 0xdb, 0x8c, 0x44, + 0x06, 0x13, 0x65, 0x9c, 0xc2, 0x0a, 0x1c, 0x65, 0x88, 0x94, 0xd3, 0xfe, 0x14, 0x50, 0x6a, 0x99, + 0x7f, 0xa6, 0x9b, 0x6d, 0xa6, 0x9b, 0x6d, 0xc3, 0x0a, 0x1a, 0x4f, 0x37, 0xff, 0xdb, 0x6f, 0x63, + 0x0c, 0x28, 0xd9, 0x1f, 0xb6, 0xdf, 0xff, 0x1f, 0x0a, 0x28, 0x33, 0xb2, 0x4d, 0x3d, 0x3e, 0x9a, + 0x7f, 0xc3, 0x8a, 0x0b, 0x0f, 0x12, 0xf6, 0xdb, 0xff, 0xc8, 0x94, 0xd3, 0x4d, 0x3f, 0x86, 0x14, + 0x00, 0x83, 0xed, 0x1f, 0x31, 0x7a, 0xff, 0xf2, 0x26, 0x1c, 0x50, 0x05, 0x07, 0xaa, 0x6f, 0xf7, + 0x7f, 0xa7, 0x9f, 0xed, 0xb6, 0x32, 0xb2, 0x9a, 0x7b, 0x6d, 0xa6, 0x9c, 0x30, 0xa0, 0x0e, 0xfa, + 0x0a, 0xbf, 0xf4, 0xfa, 0x69, 0xa7, 0xed, 0xb7, 0xb1, 0x87, 0x14, 0x04, 0x0e, 0x44, 0x61, 0xaf, + 0xf4, 0xd3, 0xd3, 0x4f, 0x17, 0x56, 0xdb, 0xfe, 0x1c, 0x50, 0x04, 0x8d, 0x63, 0x4a, 0xbf, 0xac, + 0xdb, 0x7b, 0x6d, 0xe9, 0xa7, 0xa6, 0x9f, 0x72, 0x9a, 0x7f, 0xc3, 0x8a, 0x00, 0x22, 0xb3, 0x5c, + 0x8c, 0x5d, 0xff, 0xed, 0xef, 0xa7, 0xe9, 0xa7, 0x94, 0xb3, 0x7b, 0x7f, 0x0e, 0x28, 0x1f, 0x71, + 0xc9, 0xa7, 0xf6, 0xdb, 0xed, 0xb6, 0x9a, 0x6c, 0x4b, 0xa9, 0x7f, 0x87, 0x14, 0x02, 0x3d, 0xee, + 0x19, 0xff, 0xf2, 0xf9, 0xf9, 0xaf, 0x7f, 0x87, 0x9c, 0x01, 0x9d, 0x2a, 0x40, 0x22, 0x55, 0x70, + 0xab, 0x99, 0x3f, 0xff, 0xc3, 0x58, 0x90, 0xc3, 0x10, 0x0d, 0x25, 0x38, 0xf8, 0xbf, 0xe1, 0x6c, + 0x09, 0xfb, 0x29, 0xcb, 0xff, 0xe7, 0xfc, 0x73, 0x84, 0x13, 0xac, 0x7c, 0x32, 0x8a, 0x00, 0x6d, + 0xb0, 0xae, 0x51, 0xc1, 0xf2, 0xd6, 0xe7, 0xef, 0x6b, 0x5b, 0xa6, 0x9b, 0xd6, 0x13, 0x62, 0x9c, + 0x30, 0xcd, 0x7f, 0xff, 0x14, 0xce, 0x05, 0x24, 0x75, 0x90, 0x9b, 0x80, 0x54, 0x14, 0xab, 0x75, + 0x9f, 0xef, 0xef, 0x78, 0x5f, 0x00, 0x4d, 0xaf, 0x23, 0x1f, 0x40, 0x34, 0x8e, 0x6b, 0x06, 0xa4, + 0x62, 0x6a, 0xa4, 0xe7, 0x58, 0x92, 0x4d, 0x25, 0xf1, 0xc4, 0x80, 0x8d, 0xb3, 0x14, 0xda, 0xcc, + 0x34, 0x48, 0x06, 0xb5, 0x0d, 0x5a, 0xbf, 0x7b, 0xff, 0xbb, 0x0c, 0xc4, 0x80, 0x64, 0x95, 0xa7, + 0x45, 0x5f, 0xfe, 0xf7, 0xec, 0x72, 0x9c, 0xc5, 0xf1, 0x38, 0x2c, 0xc9, 0x91, 0x4a, 0x01, 0x28, + 0xe9, 0x6a, 0x54, 0x54, 0x81, 0x12, 0xb5, 0x28, 0xa7, 0x08, 0xe4, 0x77, 0x8e, 0x65, 0x0a, 0xb4, + 0xbe, 0x77, 0x03, 0xa9, 0xa6, 0x61, 0x8c, 0x01, 0x9d, 0xd6, 0xe8, 0x1f, 0x7f, 0xfe, 0xef, 0xfc, + 0x34, 0xe0, 0x56, 0x28, 0x6d, 0xff, 0x6e, 0xdf, 0xfb, 0x09, 0xe0, 0x97, 0x72, 0xf3, 0xf4, 0xf6, + 0xff, 0xe1, 0x37, 0x08, 0x58, 0x44, 0xf4, 0xf6, 0xfd, 0x3d, 0xb8, 0x51, 0x40, 0x16, 0xdd, 0xa7, + 0x1d, 0xa6, 0x9e, 0x9a, 0x5a, 0x69, 0xe9, 0xa7, 0x09, 0xb8, 0x04, 0x7f, 0xcc, 0x83, 0x2f, 0x5f, + 0xea, 0xbf, 0xc3, 0x88, 0xc0, 0x01, 0xbe, 0x65, 0xa6, 0x83, 0xcc, 0x5d, 0x6f, 0x2f, 0x6f, 0x9a, + 0xbf, 0xe0, 0x12, 0xe5, 0x15, 0xdf, 0xe1, 0xb9, 0x00, 0x07, 0xa8, 0xa7, 0x0c, 0xd0, 0xaa, 0x7e, + 0xed, 0x3d, 0x6a, 0xef, 0x10, 0xf3, 0x7a, 0xf8, 0x62, 0x23, 0xac, 0x93, 0xfb, 0x28, 0x97, 0x3a, + 0x9f, 0x0f, 0x60, 0x04, 0x22, 0xf5, 0xac, 0x32, 0x8c, 0x9a, 0x7d, 0x31, 0x59, 0xbc, 0xde, 0xa5, + 0xbd, 0xe4, 0x66, 0x5a, 0x6b, 0xf0, 0xa1, 0x20, 0x0d, 0x1a, 0xcb, 0x3e, 0x79, 0xf4, 0xd3, 0x6c, + 0xfe, 0xf7, 0xbe, 0xb8, 0x70, 0x85, 0x01, 0xda, 0x7c, 0xa0, 0x9a, 0xa6, 0x9b, 0xa9, 0x7b, 0x3a, + 0x6a, 0x5f, 0x31, 0xc7, 0xe6, 0x3b, 0x6d, 0xfc, 0x30, 0xa0, 0x0c, 0x4f, 0x65, 0x85, 0x7a, 0x5b, + 0x77, 0x6d, 0xb2, 0x76, 0xfe, 0x9e, 0x9a, 0x79, 0xf0, 0xde, 0x00, 0xce, 0x01, 0x92, 0x35, 0xd4, + 0x9b, 0xca, 0x7a, 0x64, 0xea, 0xab, 0x72, 0xf7, 0x17, 0x33, 0x5e, 0xff, 0x85, 0xdc, 0x00, 0xc3, + 0x9a, 0x43, 0xaf, 0xbd, 0x7e, 0xae, 0xe6, 0xef, 0xd6, 0xde, 0x2a, 0xb0, 0xe6, 0x00, 0x32, 0xa9, + 0x98, 0x95, 0x55, 0xdb, 0xa5, 0x76, 0xdb, 0x9f, 0xcf, 0xf4, 0xc9, 0xd3, 0x6f, 0x8d, 0xbc, 0x3c, + 0xec, 0x9e, 0xbf, 0x0c, 0x92, 0x00, 0x32, 0x0f, 0xa3, 0x98, 0x74, 0x82, 0xea, 0x2b, 0x98, 0xbb, + 0x97, 0x8a, 0xcb, 0xdd, 0x75, 0x6c, 0x30, 0xa0, 0x35, 0xf0, 0x02, 0xf3, 0x36, 0xdb, 0x6d, 0xae, + 0xbf, 0x57, 0xc7, 0x63, 0xf0, 0xe2, 0x80, 0x10, 0x2f, 0x1d, 0x5b, 0x41, 0x3f, 0xc3, 0x6d, 0x9f, + 0xd6, 0x2a, 0xdb, 0x6c, 0xdf, 0x7b, 0xae, 0x2e, 0xe3, 0xb4, 0x9c, 0xbc, 0xdd, 0xff, 0xe1, 0x84, + 0x40, 0x0d, 0x53, 0x7a, 0xba, 0x9e, 0xdb, 0x7a, 0xfd, 0x34, 0xfb, 0x18, 0xa0, 0x7e, 0x3f, 0x56, + 0x1b, 0xc0, 0x12, 0x00, 0x07, 0xe4, 0x01, 0x3c, 0x00, 0x4d, 0x68, 0x5b, 0x16, 0xd3, 0x4c, 0x5b, + 0x16, 0xd3, 0x4d, 0x34, 0xf7, 0xbc, 0x41, 0x00, 0x4a, 0x2d, 0xb6, 0xdb, 0x7f, 0x0e, 0x28, 0x01, + 0x0b, 0xf5, 0x7b, 0x37, 0x7c, 0x37, 0x3f, 0x9b, 0x37, 0x3f, 0x9b, 0xd3, 0xff, 0x74, 0xd3, 0xf8, + 0x60, 0x90, 0x07, 0x18, 0xd9, 0x8b, 0x1f, 0xe9, 0xa7, 0xa6, 0x4f, 0xa6, 0x50, 0xd2, 0x80, 0x1c, + 0xbf, 0x93, 0x0c, 0x1f, 0xfc, 0xfd, 0xbd, 0xbf, 0x61, 0xec, 0x01, 0xee, 0xa7, 0xdb, 0xc5, 0xaf, + 0xf6, 0xdb, 0xdb, 0x6f, 0x6b, 0x76, 0xff, 0x0d, 0x12, 0x02, 0x3a, 0xe5, 0xd5, 0xad, 0xff, 0xff, + 0x9b, 0x0a, 0x28, 0x11, 0x1a, 0xd3, 0xa7, 0xff, 0xdb, 0xe1, 0x42, 0x40, 0x1a, 0x2b, 0x9c, 0x1b, + 0x7f, 0xa6, 0x9e, 0x9f, 0x86, 0x14, 0x00, 0xe3, 0xd7, 0x83, 0x20, 0xcf, 0x6d, 0xbc, 0x9c, 0xbd, + 0x6d, 0x34, 0xf9, 0xcc, 0x31, 0x80, 0xbb, 0x43, 0x2b, 0xca, 0xea, 0xf5, 0xae, 0xbd, 0xee, 0xc3, + 0x48, 0xa0, 0x8e, 0x46, 0x9f, 0x44, 0xfa, 0x69, 0xfb, 0x6d, 0xed, 0xb6, 0x3e, 0xc3, 0x28, 0xa0, + 0x05, 0xd2, 0xdd, 0x33, 0x5b, 0xf2, 0x69, 0xfe, 0xf7, 0xbc, 0xbd, 0x31, 0x2d, 0x15, 0x43, 0x0a, + 0x00, 0x29, 0xd3, 0x43, 0x5a, 0x6c, 0xe5, 0xd3, 0x67, 0xed, 0xbf, 0x9b, 0xb6, 0xcf, 0x1f, 0xa8, + 0xba, 0x6a, 0x7f, 0x86, 0x88, 0x60, 0x5c, 0x03, 0x0a, 0x9b, 0x6d, 0xa6, 0x9b, 0x6d, 0xf4, 0xcd, + 0xeb, 0x27, 0x4e, 0xb6, 0xc7, 0x4d, 0x87, 0x54, 0x00, 0xfd, 0x58, 0x4a, 0x49, 0x5d, 0x74, 0xdd, + 0x3f, 0xdb, 0x16, 0xd3, 0xcb, 0xe3, 0xca, 0x9d, 0xbf, 0xc3, 0xc4, 0x80, 0x4a, 0x48, 0x8c, 0x3f, + 0x55, 0xde, 0xef, 0xa0, 0xad, 0xd4, 0x4d, 0x35, 0x71, 0x5c, 0x8a, 0xd4, 0x29, 0x81, 0x92, 0xc3, + 0x20, 0x3e, 0x99, 0xa1, 0x9b, 0x7c, 0x76, 0x02, 0x9a, 0x07, 0x35, 0x02, 0xca, 0x2a, 0x8b, 0x21, + 0xc3, 0x83, 0x92, 0xf8, 0x5d, 0x90, 0x02, 0xeb, 0xf4, 0x81, 0xd6, 0xdb, 0xff, 0xfd, 0x61, 0x7c, + 0x02, 0x5c, 0x9a, 0x06, 0x19, 0xf7, 0x2a, 0xd5, 0xff, 0x5f, 0xbe, 0x1a, 0x62, 0x00, 0x26, 0x45, + 0x6a, 0x44, 0x3b, 0xb5, 0x75, 0x7a, 0xd5, 0x6b, 0xad, 0x5d, 0x8b, 0x42, 0x40, 0x17, 0xbc, 0x8c, + 0x0e, 0x55, 0x4d, 0x86, 0x94, 0x01, 0x18, 0x52, 0x36, 0x00, 0xa1, 0x9a, 0xad, 0xef, 0xfe, 0x74, + 0xc2, 0xc8, 0x80, 0x16, 0x06, 0xee, 0x44, 0x4b, 0xf5, 0xad, 0xef, 0x55, 0xc2, 0xe4, 0x80, 0x34, + 0xb4, 0x11, 0x47, 0xad, 0x5f, 0xee, 0xee, 0xef, 0x7a, 0x55, 0x16, 0xca, 0x07, 0x56, 0x87, 0x2c, + 0x27, 0x16, 0x6c, 0xfa, 0xd7, 0xeb, 0x59, 0xd1, 0x83, 0xf4, 0x22, 0x25, 0x15, 0x58, 0x10, 0x40, + 0x80, 0x14, 0x22, 0x69, 0x13, 0x9c, 0xf2, 0x60, 0xa7, 0xc5, 0xcf, 0x38, 0x2e, 0x59, 0xac, 0x5e, + 0x38, 0x06, 0x38, 0x38, 0xe6, 0x40, 0xc0, 0xfc, 0xfc, 0x0a, 0x20, 0x10, 0x80, 0x58, 0x52, 0xf1, + 0x41, 0xa6, 0x2b, 0xcb, 0x85, 0xc7, 0x96, 0xe3, 0x80, 0x06, 0x38, 0x38, 0x96, 0x24, 0x09, 0xbc, + 0x6f, 0xc4, 0x5b, 0x20, 0xbf, 0x67, 0x42, 0x00, 0x21, 0x14, 0x4c, 0x0d, 0xab, 0x74, 0x34, 0xe0, + 0x95, 0xe6, 0x7b, 0x3d, 0x7f, 0xff, 0xb1, 0x2c, 0xa0, 0x1a, 0xc3, 0x9a, 0x88, 0xd6, 0x70, 0xa2, + 0x45, 0x7c, 0x2a, 0xe0, 0x0c, 0xcd, 0x75, 0xf7, 0xd7, 0xff, 0x9f, 0x5b, 0x6c, 0xbb, 0x0d, 0x33, + 0x00, 0x57, 0x37, 0xaa, 0x6d, 0xbd, 0xb6, 0xff, 0xfe, 0xc2, 0x6e, 0x01, 0x31, 0x8d, 0x20, 0xeb, + 0x7b, 0xd3, 0x4f, 0x6d, 0xbf, 0xf0, 0x28, 0x00, 0x5c, 0x46, 0x88, 0x12, 0x3d, 0x5a, 0x89, 0x1f, + 0x67, 0x70, 0x48, 0x01, 0x63, 0x03, 0xf2, 0x56, 0xde, 0xee, 0xdc, 0x14, 0x64, 0x80, 0x0d, 0x41, + 0x96, 0x00, 0x09, 0x0d, 0x35, 0xf7, 0x0a, 0x09, 0x71, 0xec, 0x3f, 0x86, 0xdc, 0x00, 0x5d, 0x4c, + 0x98, 0x36, 0x2a, 0x52, 0x08, 0xfe, 0xbb, 0xad, 0x63, 0xdf, 0x19, 0xe6, 0xf1, 0xef, 0xce, 0x61, + 0x00, 0x94, 0xcd, 0xab, 0xba, 0xca, 0x09, 0x72, 0xf4, 0x5f, 0x84, 0xc8, 0x70, 0x09, 0xb1, 0x1b, + 0xdf, 0xb9, 0x6b, 0xf1, 0x7a, 0xdd, 0xb1, 0x5e, 0x1a, 0x50, 0x02, 0x16, 0xf2, 0xc6, 0xa2, 0x3c, + 0x75, 0x7d, 0x6b, 0x79, 0x7b, 0x6b, 0x19, 0x39, 0x79, 0x86, 0x94, 0x04, 0x66, 0xc6, 0xc1, 0x79, + 0xfa, 0x7b, 0xf4, 0xf4, 0xd3, 0x23, 0xf0, 0xe2, 0x20, 0x03, 0x65, 0x99, 0xb0, 0xe4, 0x2b, 0xab, + 0xd6, 0xb7, 0xfd, 0x53, 0x4f, 0xf8, 0x68, 0x90, 0x01, 0xdf, 0xe6, 0x15, 0x5c, 0x3f, 0xfa, 0xa5, + 0x2f, 0x13, 0xf6, 0x99, 0x3c, 0x5d, 0x5b, 0x4f, 0x17, 0x4d, 0x6b, 0x0e, 0x28, 0x07, 0x25, 0xea, + 0xd4, 0x95, 0x97, 0xba, 0xcb, 0xee, 0x7f, 0x5d, 0xdb, 0x6e, 0x9c, 0x56, 0xdb, 0xfe, 0x1a, 0x50, + 0x0d, 0xe5, 0x0d, 0xb5, 0xe7, 0x3e, 0x5e, 0xce, 0x5e, 0xce, 0xdb, 0x7f, 0x58, 0xe9, 0x61, 0x85, + 0x00, 0x65, 0x91, 0xe8, 0x83, 0x8f, 0xef, 0xd6, 0xe6, 0xe5, 0xfe, 0x6f, 0x53, 0x26, 0x1c, 0x50, + 0x01, 0xda, 0xbd, 0xb5, 0x00, 0xb5, 0xfa, 0xbb, 0xc5, 0xd3, 0x5b, 0x7a, 0x7d, 0x3b, 0xea, 0xb7, + 0xfc, 0x30, 0xa0, 0x06, 0xd2, 0xa8, 0x02, 0x41, 0xfa, 0x55, 0x32, 0x7d, 0x34, 0xc9, 0xe3, 0x5a, + 0x69, 0xb6, 0x6e, 0x3a, 0x4a, 0xa1, 0x85, 0x00, 0x5b, 0xf0, 0xe9, 0x23, 0x7f, 0xbe, 0xff, 0x58, + 0x5f, 0x00, 0x1d, 0xf5, 0x8a, 0xc6, 0xc0, 0x3b, 0x75, 0x9f, 0xd6, 0xb5, 0xaf, 0x8f, 0x8c, 0x05, + 0x43, 0x0a, 0x00, 0xe2, 0xf8, 0x36, 0xae, 0x4c, 0xbe, 0xff, 0x7f, 0xf2, 0xc3, 0x04, 0x80, 0x95, + 0x34, 0x2a, 0xfa, 0xe9, 0x7c, 0xbd, 0x34, 0xe3, 0x4f, 0xf4, 0xf9, 0xf0, 0xd1, 0x24, 0x31, 0x16, + 0xb7, 0xab, 0x57, 0xb6, 0xdf, 0xff, 0x98, 0xc3, 0x44, 0x84, 0x26, 0x6d, 0xad, 0xed, 0xfe, 0xb5, + 0xae, 0xd8, 0x51, 0x40, 0x9b, 0x06, 0x93, 0xe6, 0xb7, 0xfb, 0xab, 0xae, 0xdb, 0x70, 0xce, 0x00, + 0x29, 0x51, 0x27, 0x90, 0x47, 0x2e, 0xef, 0x26, 0xbf, 0xc5, 0x71, 0x5e, 0x9c, 0x50, 0xa6, 0x18, + 0x21, 0x40, 0x09, 0xfa, 0xd7, 0x18, 0xcb, 0xfb, 0xde, 0xf6, 0xdb, 0x4d, 0x3e, 0x98, 0xa1, 0x1b, + 0x0d, 0x48, 0x02, 0x4b, 0x7a, 0xb7, 0x1f, 0xed, 0xb6, 0x9a, 0x75, 0x4c, 0x9d, 0xcc, 0x38, 0xa0, + 0x0c, 0x0c, 0x98, 0xeb, 0xae, 0xd7, 0x6e, 0xed, 0xfe, 0xfc, 0x5d, 0xb6, 0xfe, 0x1a, 0x24, 0x01, + 0x38, 0x62, 0x4a, 0x47, 0x3b, 0xb6, 0xa6, 0xbf, 0x59, 0x3f, 0xf2, 0xc3, 0x8a, 0x00, 0x98, 0x64, + 0x2c, 0x85, 0xa9, 0xa4, 0xf2, 0x78, 0xd3, 0x8d, 0x3a, 0xaf, 0x6d, 0xb7, 0xdb, 0xfe, 0x18, 0x50, + 0x03, 0xfb, 0x28, 0x54, 0xeb, 0x37, 0xd5, 0xaf, 0xa7, 0x97, 0xb6, 0xdb, 0x7f, 0x58, 0x71, 0x40, + 0x18, 0x4f, 0x0d, 0x87, 0x54, 0xe7, 0x76, 0xcd, 0xde, 0x55, 0xd5, 0xdc, 0x9d, 0xd9, 0xc5, 0x36, + 0x9f, 0xf0, 0xa6, 0x05, 0xda, 0xaf, 0xc3, 0xf6, 0xff, 0xbe, 0xfd, 0x61, 0xb2, 0x10, 0x00, 0xa1, + 0xd6, 0x1d, 0xa4, 0x30, 0x99, 0xcd, 0xbd, 0xc5, 0xe2, 0xf7, 0x71, 0x5c, 0x5e, 0x2f, 0x03, 0xae, + 0x2d, 0x69, 0x06, 0x47, 0xc5, 0xff, 0x09, 0xb2, 0x81, 0x11, 0x69, 0xb9, 0xbe, 0xfe, 0x9e, 0xef, + 0x85, 0xd9, 0x43, 0xf1, 0x7e, 0x0b, 0xec, 0xee, 0xff, 0xfa, 0xc3, 0x4e, 0x02, 0xbb, 0xe6, 0x77, + 0xa6, 0x9f, 0xff, 0x7c, 0x2f, 0x80, 0xc1, 0xac, 0xe9, 0xdd, 0xde, 0x9d, 0x7f, 0xef, 0x86, 0xa2, + 0x80, 0x17, 0x56, 0x2e, 0x3c, 0x77, 0xfa, 0xd6, 0xfd, 0xb0, 0xc4, 0x48, 0x02, 0x45, 0x0f, 0x1c, + 0x87, 0xad, 0xde, 0xaa, 0xaa, 0xf7, 0xfb, 0x62, 0xdc, 0x03, 0x6f, 0x2d, 0x29, 0x7c, 0x30, 0x8a, + 0x00, 0xef, 0xc8, 0x43, 0xa2, 0x7a, 0x5f, 0x4e, 0x34, 0xff, 0xfa, 0x3b, 0x86, 0x88, 0x40, 0x67, + 0x47, 0xf5, 0x7f, 0xed, 0xb7, 0x27, 0xe0, 0xe0, 0x10, 0x85, 0x0a, 0x29, 0x93, 0x88, 0xfe, 0xaf, + 0xd5, 0x6a, 0x2e, 0x2e, 0x38, 0x1f, 0x85, 0x9c, 0x22, 0x47, 0xf7, 0xff, 0xfb, 0xf1, 0x58, 0x24, + 0xa4, 0xaf, 0x1c, 0xf1, 0x20, 0xbd, 0x74, 0x72, 0x10, 0x13, 0x0a, 0xaa, 0x9f, 0x1d, 0x80, 0xf9, + 0xea, 0xef, 0x8a, 0x50, 0x46, 0xb2, 0xbd, 0x91, 0xa4, 0x1a, 0x1d, 0x1e, 0x4f, 0x8d, 0x66, 0x15, + 0x4f, 0x8a, 0x63, 0x01, 0x65, 0xc0, 0x71, 0x6c, 0xe0, 0x85, 0x3d, 0x4c, 0xbd, 0x85, 0x89, 0x04, + 0x4e, 0x51, 0x2f, 0xff, 0x6f, 0x6e, 0x25, 0x94, 0x0b, 0xa6, 0xa6, 0x9c, 0x4a, 0x83, 0xdf, 0x8a, + 0xc1, 0x0b, 0x76, 0x22, 0x91, 0x03, 0x60, 0x7a, 0x31, 0x40, 0x36, 0xc9, 0xbe, 0xd7, 0xc3, 0xc8, + 0x50, 0x00, 0x9b, 0x78, 0xa2, 0x16, 0x04, 0xa2, 0xff, 0x29, 0xe5, 0xe6, 0xe9, 0xb7, 0xaa, 0xaa, + 0xcb, 0xf0, 0x89, 0x91, 0x82, 0x7c, 0x74, 0x5e, 0x8f, 0xe1, 0xb6, 0x50, 0x04, 0x13, 0x93, 0x9c, + 0x19, 0xa4, 0xfb, 0xed, 0x6b, 0xe5, 0xec, 0xe2, 0x07, 0x9d, 0xe9, 0x97, 0xc6, 0xde, 0x12, 0x64, + 0x4e, 0x0d, 0x11, 0x75, 0x7f, 0x0c, 0xb3, 0x80, 0x18, 0x9a, 0xd9, 0xa3, 0xaf, 0xf6, 0xb7, 0x97, + 0x58, 0xf1, 0xf5, 0xed, 0x85, 0x54, 0x00, 0x5d, 0x64, 0x4c, 0xe1, 0xe9, 0x7b, 0x5b, 0x7c, 0xbc, + 0xde, 0xdd, 0xcb, 0xdb, 0xe6, 0x77, 0x8b, 0x70, 0xd1, 0x20, 0x22, 0xe3, 0xc4, 0x8e, 0x5e, 0xbf, + 0x4c, 0x9d, 0xb6, 0xe3, 0x4c, 0x6e, 0xc2, 0x84, 0x20, 0x03, 0x33, 0x36, 0x29, 0x7a, 0x7f, 0xf5, + 0x4d, 0x3e, 0x1a, 0x50, 0x03, 0x35, 0x39, 0xdd, 0xfb, 0x8e, 0xbf, 0x52, 0x78, 0xdd, 0x5e, 0x64, + 0xc3, 0xc4, 0x80, 0x81, 0x8c, 0xba, 0xfb, 0xef, 0xad, 0x7e, 0x6e, 0x9e, 0xfb, 0xff, 0x0c, 0x28, + 0x48, 0x39, 0x90, 0x8d, 0xaf, 0x45, 0xbb, 0xeb, 0x17, 0xb5, 0xab, 0xab, 0xab, 0xe1, 0xc5, 0x00, + 0x3a, 0xa6, 0xd8, 0x22, 0xa0, 0x69, 0xbd, 0xef, 0xba, 0xbd, 0x3c, 0x67, 0xf4, 0xd3, 0xf8, 0x5d, + 0xc0, 0x0e, 0xe7, 0x44, 0xbe, 0x75, 0x6b, 0x78, 0xad, 0xef, 0x8a, 0x38, 0xaf, 0x2c, 0x38, 0xa0, + 0x05, 0x1a, 0x9b, 0x19, 0x02, 0x5f, 0x7b, 0x9d, 0xb7, 0xb6, 0xdf, 0x4d, 0x53, 0x4d, 0x34, 0xd3, + 0x1a, 0xab, 0xb6, 0xdf, 0xc2, 0xf2, 0x80, 0x50, 0x7a, 0x69, 0x72, 0xf7, 0xfb, 0xde, 0xb5, 0x05, + 0xd7, 0x86, 0x54, 0x03, 0x6e, 0x0f, 0x5b, 0x6f, 0xf7, 0x8a, 0xfe, 0xf8, 0x75, 0x40, 0x0c, 0x94, + 0xd2, 0x32, 0x00, 0x06, 0x52, 0xba, 0xba, 0xba, 0xb8, 0xb8, 0xac, 0x5c, 0x56, 0xb5, 0x8f, 0xac, + 0x99, 0x32, 0x65, 0xf0, 0xe9, 0x20, 0x17, 0x85, 0x3d, 0x34, 0xaa, 0x9a, 0xf7, 0x7a, 0xd7, 0xc7, + 0xfd, 0x6b, 0xf0, 0xca, 0x80, 0x2e, 0xd3, 0x13, 0x3c, 0xd7, 0xbe, 0xfa, 0xba, 0x8a, 0xd4, 0x57, + 0x9b, 0x0a, 0x92, 0x01, 0x69, 0xa7, 0x0e, 0x08, 0x7d, 0xfa, 0xdd, 0xff, 0x80, 0x7c, 0x01, 0x88, + 0x50, 0xc2, 0x41, 0xca, 0xe3, 0x8b, 0x8b, 0xd4, 0xfe, 0xd7, 0x88, 0x1e, 0x09, 0x00, 0x03, 0xa8, + 0x70, 0x1e, 0x01, 0x21, 0x06, 0x01, 0x48, 0xba, 0xe4, 0xc8, 0x95, 0xf7, 0x75, 0x15, 0xab, 0x8d, + 0x00, 0x03, 0xe8, 0x62, 0xa1, 0xc5, 0x00, 0x30, 0x86, 0xcd, 0x82, 0xf1, 0xbb, 0xd2, 0x7d, 0xe5, + 0xd5, 0x34, 0xdb, 0x6d, 0x34, 0xfc, 0x91, 0x36, 0xdf, 0xf0, 0xd1, 0x20, 0x25, 0x53, 0x1f, 0x92, + 0x4d, 0x3f, 0xf7, 0xf8, 0xa2, 0xe0, 0xc4, 0x04, 0x48, 0x29, 0x88, 0x0e, 0x29, 0xbb, 0x3a, 0x42, + 0x1f, 0x6f, 0xc3, 0x79, 0x06, 0x36, 0x0f, 0x38, 0x34, 0x00, 0x04, 0x00, 0xd0, 0x20, 0x1c, 0x34, + 0x48, 0x5b, 0xe4, 0xb3, 0xaf, 0xfd, 0xfd, 0x70, 0x80, 0x90, 0x59, 0x17, 0x03, 0x78, 0xba, 0xe9, + 0x67, 0xf9, 0x39, 0xb0, 0xf3, 0x80, 0xc2, 0x00, 0x1a, 0x1c, 0xe1, 0xec, 0x04, 0x46, 0xf2, 0xc7, + 0x7d, 0xd5, 0xbd, 0xea, 0xea, 0xde, 0xbd, 0x5d, 0x45, 0xd5, 0xb6, 0xff, 0x86, 0xf0, 0x01, 0x2a, + 0x51, 0x99, 0x05, 0x10, 0x74, 0xbc, 0xdf, 0xbb, 0xab, 0xad, 0xc2, 0x80, 0xe8, 0xe9, 0xc0, 0x7c, + 0x2a, 0x16, 0xf0, 0x51, 0x3f, 0x7c, 0x36, 0xe0, 0x02, 0x3b, 0xfb, 0x02, 0xcb, 0x42, 0x67, 0xef, + 0x8f, 0xd6, 0xb5, 0xf2, 0xf5, 0x2f, 0x5f, 0x09, 0x60, 0x84, 0x1a, 0xc1, 0xd6, 0xd7, 0xb7, 0xc0, + 0x30, 0xfc, 0x34, 0x42, 0x80, 0x3a, 0xc7, 0xb2, 0x46, 0xaa, 0xdf, 0xff, 0xe6, 0xb0, 0xb1, 0x20, + 0x20, 0x2b, 0x8e, 0x84, 0x9c, 0x9f, 0x5f, 0xff, 0x1a, 0x48, 0x0d, 0xc6, 0x55, 0xbb, 0xe1, 0x32, + 0x40, 0x37, 0x98, 0x8d, 0x54, 0xfb, 0xd6, 0xbf, 0x5a, 0xc2, 0x71, 0x00, 0x04, 0xf5, 0xc4, 0x61, + 0x18, 0x0a, 0x5f, 0xdf, 0xa6, 0x9d, 0x6a, 0x9a, 0x69, 0x97, 0xc2, 0xec, 0x48, 0x02, 0x4f, 0x61, + 0x38, 0xf5, 0xad, 0x5e, 0xb5, 0xff, 0xec, 0x34, 0xe0, 0x0a, 0x2d, 0x63, 0x71, 0x26, 0xbf, 0xf7, + 0xfa, 0x5c, 0x34, 0xe0, 0x91, 0x95, 0x57, 0xfa, 0xff, 0x7c, 0x76, 0x1d, 0x2b, 0x18, 0xc5, 0x38, + 0x42, 0xa3, 0xdc, 0x2c, 0x48, 0x03, 0x5f, 0xab, 0x0b, 0xbd, 0x75, 0xff, 0x8d, 0x65, 0x03, 0x46, + 0x52, 0x76, 0x74, 0x50, 0x91, 0x44, 0xfc, 0x45, 0xb8, 0x48, 0xc6, 0xbb, 0x14, 0x8c, 0x30, 0xb1, + 0x4e, 0x11, 0x18, 0xc9, 0xe5, 0x05, 0x02, 0xe9, 0x90, 0x9c, 0x80, 0x0b, 0x4e, 0x86, 0xe4, 0x8b, + 0xfd, 0xef, 0xf8, 0x5f, 0x00, 0x23, 0xbd, 0x3b, 0x04, 0x85, 0xe7, 0x5f, 0xdb, 0x6f, 0x55, 0xf6, + 0x13, 0x24, 0x0c, 0xfe, 0xc2, 0xff, 0xff, 0x8e, 0x70, 0xd3, 0x3a, 0xec, 0x56, 0x0b, 0x78, 0xf2, + 0x14, 0x67, 0x25, 0xff, 0xfb, 0x6c, 0xeb, 0x3c, 0x40, 0x17, 0xae, 0x64, 0x46, 0xce, 0x01, 0xf4, + 0x99, 0xa7, 0xce, 0xe0, 0x16, 0xb9, 0x85, 0x2d, 0xe2, 0x51, 0x00, 0x60, 0xa0, 0xf7, 0xc8, 0x7a, + 0x28, 0x00, 0x4f, 0xc9, 0x1e, 0xe2, 0x1d, 0x7d, 0xfd, 0x25, 0x63, 0xbd, 0xf5, 0xf8, 0x87, 0x97, + 0xd1, 0x80, 0x25, 0x4b, 0xf1, 0xaa, 0x8d, 0xb2, 0x89, 0x77, 0xc3, 0x92, 0x80, 0x19, 0xc0, 0xca, + 0x8f, 0x4c, 0x57, 0xaf, 0xb4, 0xbe, 0x5f, 0x24, 0xf1, 0xc7, 0x93, 0x97, 0xd4, 0x5b, 0x27, 0x06, + 0x2d, 0x99, 0xd6, 0xdf, 0xf8, 0x61, 0x40, 0x27, 0xb3, 0xa8, 0xbb, 0xe7, 0xff, 0x6f, 0x5a, 0xfc, + 0xdf, 0x1f, 0x61, 0x85, 0x00, 0x21, 0x6d, 0xc3, 0x25, 0x23, 0xb9, 0xf1, 0x5d, 0x6d, 0xb7, 0x1a, + 0x6b, 0x4d, 0x3e, 0x2c, 0x30, 0xa0, 0x0a, 0x63, 0x4a, 0x18, 0x14, 0x2e, 0x45, 0xd3, 0x57, 0xba, + 0xff, 0x7a, 0xc3, 0x0a, 0x00, 0x36, 0xfa, 0x8c, 0x69, 0xc2, 0x9e, 0x99, 0x5d, 0x6d, 0xbd, 0xd6, + 0xbb, 0x93, 0xdb, 0xe1, 0xc5, 0x01, 0x3e, 0x31, 0x07, 0x7f, 0x62, 0xba, 0xba, 0xba, 0xba, 0xd6, + 0x2e, 0x2b, 0x17, 0x15, 0xe5, 0x4f, 0xfc, 0x28, 0xa0, 0x11, 0xaa, 0xc9, 0xa1, 0xfa, 0xb7, 0xf4, + 0xd5, 0xee, 0xba, 0xc3, 0x0a, 0x00, 0xa0, 0xf4, 0x61, 0xac, 0xff, 0xd7, 0xfb, 0xef, 0xe3, 0x29, + 0x85, 0x14, 0x01, 0xad, 0xf3, 0x10, 0x1b, 0xbc, 0xdb, 0xfd, 0x6a, 0xea, 0xeb, 0x82, 0x00, 0x72, + 0x14, 0x2a, 0xbe, 0xef, 0xb7, 0x12, 0xe8, 0x3a, 0x2c, 0xc1, 0xd1, 0x60, 0x3a, 0x2c, 0x1c, 0x00, + 0x18, 0xe0, 0x00, 0x63, 0x0c, 0xe0, 0x22, 0x6e, 0x39, 0x5f, 0xff, 0xef, 0xef, 0x86, 0xb0, 0x03, + 0x31, 0xda, 0x0a, 0x7d, 0xfa, 0xb9, 0xd5, 0xc5, 0xff, 0xdd, 0xb1, 0x5b, 0x22, 0xec, 0x30, 0x48, + 0x03, 0x34, 0x72, 0xf9, 0xca, 0x57, 0xd6, 0xad, 0xab, 0xc5, 0x6b, 0x59, 0x53, 0x0c, 0x92, 0x02, + 0x3b, 0xc6, 0x6e, 0xe7, 0xdb, 0xb7, 0xfd, 0x35, 0xab, 0xd6, 0x18, 0xc0, 0x0d, 0x73, 0x9e, 0x69, + 0x6c, 0xae, 0xaf, 0xea, 0xea, 0x2b, 0x6f, 0xc5, 0x86, 0x70, 0x09, 0x84, 0xc2, 0xab, 0x93, 0x5a, + 0xfd, 0xfe, 0xff, 0xb0, 0xd2, 0x80, 0x4a, 0x17, 0x34, 0x66, 0x5d, 0xf4, 0xd5, 0x56, 0xbf, 0x15, + 0x7c, 0x34, 0xa1, 0x3d, 0xeb, 0xbf, 0x4f, 0xff, 0xac, 0x3c, 0xa0, 0x0c, 0x82, 0x3d, 0xac, 0xf5, + 0xbe, 0x75, 0x75, 0xbd, 0xfe, 0xf1, 0x5a, 0xd6, 0xbf, 0x81, 0x40, 0x0d, 0x03, 0x77, 0x97, 0x22, + 0xf5, 0x1c, 0x57, 0xe1, 0x30, 0x01, 0xa4, 0x6e, 0xa2, 0x5f, 0x58, 0x62, 0xc0, 0x07, 0x0d, 0xfb, + 0x6d, 0xbf, 0xf0, 0x24, 0x81, 0x04, 0x13, 0x57, 0x2c, 0xea, 0xf1, 0x0e, 0x43, 0x16, 0x00, 0x07, + 0x1a, 0x38, 0xcc, 0x01, 0x87, 0x67, 0x37, 0x5d, 0xbe, 0x9d, 0x43, 0x58, 0x02, 0x2e, 0xc6, 0xef, + 0xa7, 0x62, 0xba, 0x8a, 0xf1, 0x78, 0xbd, 0xef, 0x5a, 0x91, 0xf8, 0x69, 0x40, 0x18, 0x55, 0xb4, + 0x97, 0xfd, 0x6a, 0xbf, 0xf6, 0xea, 0xf9, 0x11, 0xb0, 0xf1, 0x05, 0x00, 0x07, 0x67, 0x46, 0x62, + 0x34, 0x29, 0xce, 0x9f, 0xfe, 0x96, 0xa7, 0xe3, 0x7d, 0xca, 0x77, 0xd3, 0x06, 0x09, 0xa0, 0x05, + 0x13, 0xf7, 0x27, 0xea, 0x2e, 0xa0, 0x71, 0x39, 0x93, 0xbc, 0x36, 0x82, 0x7e, 0x19, 0x89, 0x00, + 0x50, 0xe7, 0x02, 0x45, 0x9c, 0xcf, 0x7a, 0xd6, 0xea, 0xeb, 0xe6, 0x5e, 0x2c, 0x90, 0x07, 0xf5, + 0xa1, 0xd6, 0xd2, 0xc2, 0xb3, 0x80, 0x19, 0x5a, 0x8b, 0xb5, 0xf3, 0xd6, 0x6c, 0xff, 0xff, 0x0d, + 0x22, 0x00, 0xde, 0x99, 0x24, 0xcf, 0x47, 0xff, 0xef, 0x8e, 0x24, 0x04, 0x4c, 0xda, 0x9d, 0x5d, + 0x86, 0x5c, 0x00, 0x45, 0x1b, 0x68, 0x8e, 0xc8, 0x7f, 0xb7, 0xc4, 0x3e, 0x5f, 0xeb, 0x7a, 0x5c, + 0x2d, 0x10, 0x00, 0x60, 0xe6, 0x74, 0x06, 0x22, 0xe7, 0xcf, 0xbf, 0xbb, 0xdf, 0x7c, 0x2e, 0x41, + 0x20, 0x0e, 0x2f, 0x5b, 0x8d, 0x7b, 0xfd, 0xef, 0xee, 0x63, 0x67, 0x02, 0x3d, 0xc9, 0x71, 0xf0, + 0xb2, 0x20, 0x74, 0x31, 0xaf, 0xff, 0x7b, 0xe3, 0x88, 0x50, 0x84, 0x9d, 0x4c, 0xf8, 0xd7, 0x05, + 0x84, 0xc8, 0xe7, 0x63, 0x5c, 0x1e, 0xb7, 0xb1, 0x4e, 0x1b, 0x49, 0xfc, 0x53, 0x20, 0x03, 0x22, + 0xfc, 0xa6, 0x0d, 0x1d, 0x87, 0xe3, 0x7c, 0x73, 0x86, 0x00, 0x61, 0x2a, 0xc4, 0xc8, 0x00, 0x49, + 0xc7, 0x14, 0x33, 0xb1, 0x68, 0xec, 0x0a, 0x94, 0x54, 0xbd, 0x86, 0xb0, 0x0c, 0x75, 0xd6, 0xcf, + 0xfe, 0x9f, 0xfb, 0x10, 0x8e, 0x00, 0x7b, 0xda, 0x65, 0xf2, 0xf4, 0x2c, 0xa1, 0x07, 0x07, 0x0f, + 0x5b, 0xff, 0xf7, 0xc2, 0xd8, 0x69, 0x53, 0xaf, 0xa1, 0x68, 0x5f, 0x0a, 0x3f, 0xe8, 0xdb, 0x35, + 0x6d, 0xd3, 0xf8, 0x5a, 0x43, 0x3f, 0xfe, 0x9f, 0xb3, 0xc5, 0xb3, 0x80, 0xb3, 0x40, 0x61, 0xd5, + 0x88, 0xc0, 0x84, 0xe7, 0x20, 0xdd, 0x1b, 0x80, 0x33, 0xf4, 0x39, 0xff, 0x6f, 0xfb, 0x0c, 0xa3, + 0x00, 0x33, 0xce, 0x32, 0x0e, 0xdd, 0xbb, 0xdd, 0xdd, 0xff, 0xfd, 0x86, 0xe6, 0x00, 0xe5, 0x4b, + 0x6b, 0x9f, 0x9f, 0xc3, 0x91, 0x03, 0xcb, 0x3f, 0x15, 0x92, 0x8f, 0xdc, 0x4f, 0xd8, 0x62, 0x86, + 0x90, 0x74, 0x5e, 0x1d, 0xf9, 0x1f, 0xdd, 0xe1, 0xa6, 0x70, 0x02, 0xb9, 0x7e, 0x34, 0xbb, 0xfc, + 0xeb, 0xdf, 0xf2, 0x72, 0x72, 0x76, 0x7e, 0xc3, 0x38, 0x01, 0x83, 0xa2, 0x1a, 0x31, 0xf7, 0x78, + 0xbf, 0x55, 0xf5, 0x55, 0x5c, 0x95, 0x43, 0xa4, 0x80, 0x0f, 0xf5, 0x96, 0x35, 0x33, 0x55, 0xff, + 0x1f, 0x75, 0x77, 0xbc, 0x9e, 0x35, 0x15, 0x8a, 0x8f, 0x5f, 0xe1, 0xa2, 0x10, 0x02, 0xda, 0x60, + 0xe3, 0xcb, 0x5d, 0xef, 0xb7, 0xbb, 0x67, 0xfa, 0xc2, 0xee, 0x04, 0x48, 0xaf, 0x83, 0xdf, 0xef, + 0xbf, 0x5d, 0x61, 0x89, 0x40, 0x16, 0xdd, 0x85, 0x21, 0xf3, 0x7f, 0xc9, 0xcb, 0xd6, 0xdf, 0x0b, + 0xa8, 0x00, 0x85, 0xf8, 0x7b, 0xf8, 0xfb, 0xf6, 0xfd, 0xc4, 0xfd, 0x6a, 0xf3, 0xcb, 0x0d, 0x90, + 0x80, 0x25, 0x1f, 0x15, 0x96, 0xeb, 0xdd, 0x5d, 0x5d, 0x11, 0xe0, 0x8a, 0x94, 0x62, 0x1f, 0x15, + 0xcf, 0xad, 0x7e, 0x1c, 0x50, 0x15, 0x3b, 0x7e, 0x05, 0xe5, 0xfd, 0xfe, 0xb6, 0xf8, 0xeb, 0xad, + 0x34, 0xfa, 0xfc, 0x46, 0x44, 0x5b, 0x6d, 0xfc, 0x2f, 0x80, 0x37, 0x19, 0x9a, 0x8f, 0x4f, 0xb6, + 0xed, 0xcd, 0xf5, 0xad, 0x53, 0x2d, 0x2e, 0x6b, 0x0e, 0xca, 0x00, 0x7a, 0xe4, 0x39, 0x3d, 0xa5, + 0xef, 0xc7, 0xbb, 0x51, 0xdd, 0x35, 0x3f, 0x32, 0x7b, 0x7f, 0x0c, 0xe0, 0x01, 0xde, 0xec, 0xf3, + 0x92, 0xdf, 0x97, 0xc9, 0xd5, 0x3b, 0xeb, 0xf8, 0xa5, 0xb0, 0xce, 0x00, 0x63, 0x28, 0xa9, 0xb3, + 0x53, 0xaa, 0xbd, 0xeb, 0x37, 0x6d, 0xf5, 0x8f, 0x85, 0x70, 0x03, 0x77, 0x43, 0x8b, 0x10, 0x5d, + 0x6b, 0xdd, 0x55, 0x56, 0xf7, 0x5a, 0xe1, 0x75, 0x00, 0x6c, 0xf3, 0xf0, 0x7d, 0xdd, 0xdf, 0x5b, + 0xdf, 0x7c, 0x32, 0xa0, 0x08, 0xe9, 0x28, 0x0c, 0x51, 0xf9, 0x6b, 0x75, 0x75, 0x5a, 0xc5, 0x6a, + 0x2b, 0x52, 0x58, 0x57, 0x00, 0x03, 0xff, 0xd6, 0x6a, 0x04, 0xeb, 0xbd, 0x5d, 0x5e, 0xb5, 0xba, + 0xbc, 0x2e, 0x48, 0x04, 0xdf, 0x78, 0x43, 0xcf, 0x75, 0x75, 0x7b, 0xdc, 0x5d, 0xc5, 0xe3, 0xe1, + 0xa9, 0x00, 0x1c, 0xa9, 0xc6, 0x58, 0x77, 0x17, 0xbb, 0x5f, 0x7b, 0xbc, 0x56, 0xb7, 0x8a, 0xfb, + 0x0b, 0x29, 0x18, 0x30, 0x6b, 0xd6, 0xfa, 0xde, 0xf5, 0xe2, 0xbb, 0x93, 0xc2, 0xca, 0x01, 0x6d, + 0x6e, 0x76, 0xff, 0xd7, 0x96, 0x1f, 0x0c, 0x23, 0x80, 0x06, 0xfe, 0x9b, 0xf7, 0x02, 0x82, 0x69, + 0xef, 0xd3, 0x4f, 0x5f, 0x9d, 0x5c, 0x04, 0x48, 0x04, 0x00, 0x68, 0xe3, 0x75, 0xad, 0x34, 0x86, + 0xf3, 0x15, 0x87, 0x46, 0x22, 0xb6, 0xae, 0x0a, 0xa5, 0xc0, 0x51, 0x39, 0x27, 0xc0, 0x00, 0xc7, + 0xbe, 0x00, 0x04, 0xb8, 0xb0, 0x00, 0x31, 0x06, 0x13, 0x63, 0x81, 0xc6, 0xfa, 0xbf, 0xbe, 0x19, + 0x94, 0x19, 0xdb, 0x61, 0x25, 0x60, 0x11, 0x77, 0xf9, 0x55, 0xbf, 0x4f, 0x88, 0xf5, 0xcb, 0xa9, + 0x7a, 0x8b, 0xea, 0xe1, 0x64, 0x56, 0x1a, 0x21, 0xc0, 0x11, 0xeb, 0x15, 0x81, 0x2b, 0x5f, 0xff, + 0x14, 0x7c, 0x51, 0x20, 0x15, 0xd4, 0xd2, 0x68, 0x4d, 0xc2, 0x54, 0x63, 0x5e, 0x7f, 0xdf, 0xfc, + 0x2d, 0x82, 0xe2, 0xa5, 0xbf, 0x6f, 0xff, 0x1c, 0xe1, 0x4e, 0x8f, 0x8a, 0x70, 0x33, 0x0d, 0x38, + 0xe0, 0x22, 0x42, 0x95, 0x11, 0x48, 0xb2, 0x65, 0x15, 0x4c, 0x14, 0x26, 0x54, 0x1e, 0x7e, 0xac, + 0xa8, 0x39, 0xb9, 0x59, 0x2b, 0x54, 0x63, 0x58, 0xca, 0xba, 0x15, 0x24, 0xa3, 0x80, 0x00, 0x80, + 0x34, 0x70, 0x38, 0x55, 0xc0, 0x1f, 0x21, 0x59, 0x55, 0xa8, 0xd3, 0x02, 0xfa, 0xd6, 0x21, 0xe9, + 0xb7, 0xb7, 0xfc, 0x26, 0xca, 0x1b, 0x07, 0x4f, 0xde, 0xff, 0x7d, 0xe1, 0x6c, 0x11, 0x35, 0x75, + 0xbf, 0xfe, 0xb5, 0x8b, 0x70, 0x5a, 0xf9, 0xf0, 0xbb, 0x86, 0x1d, 0x8f, 0xf5, 0xad, 0x6b, 0x7c, + 0x2c, 0xe0, 0x5b, 0x0c, 0xac, 0xff, 0xba, 0xfe, 0x39, 0xc2, 0xc0, 0x0a, 0x13, 0xe2, 0xb0, 0xfd, + 0x39, 0x8e, 0x70, 0x43, 0x95, 0xbf, 0xaf, 0x84, 0xf0, 0x01, 0x4b, 0x5e, 0x68, 0x2d, 0x4a, 0x5f, + 0x7f, 0xfe, 0x9e, 0x7e, 0xef, 0x6f, 0x0d, 0x48, 0x00, 0x6f, 0xe7, 0x8b, 0x6e, 0xb7, 0xd6, 0xbf, + 0xfe, 0xc5, 0x4a, 0x08, 0x71, 0xd6, 0xa2, 0x1c, 0x13, 0x29, 0xc5, 0xb9, 0xe5, 0x01, 0xae, 0x34, + 0xfe, 0x43, 0x52, 0x01, 0x22, 0xf5, 0x38, 0xff, 0x5f, 0xfd, 0x85, 0x94, 0x22, 0xf7, 0x6f, 0xd3, + 0xff, 0xf0, 0xcb, 0x80, 0x4b, 0xbc, 0xb3, 0x39, 0x66, 0x8f, 0xfe, 0x8d, 0xb4, 0xfd, 0x85, 0x94, + 0x02, 0x6d, 0xc5, 0x87, 0xfc, 0xf9, 0x7f, 0xd3, 0x6f, 0xf1, 0x44, 0x80, 0x21, 0xea, 0x1e, 0x81, + 0xea, 0x14, 0x67, 0x01, 0xfa, 0x73, 0xbf, 0xff, 0x6e, 0xde, 0x25, 0x90, 0x04, 0x0b, 0x8c, 0x15, + 0x5f, 0x11, 0x8e, 0x0d, 0xad, 0x1f, 0x86, 0x41, 0x00, 0xd1, 0x41, 0x7d, 0x0f, 0x0b, 0x15, 0x9f, + 0x62, 0xb0, 0x0f, 0xf5, 0xa5, 0x9a, 0x92, 0x4a, 0xa2, 0xe3, 0x94, 0x9e, 0x1e, 0x3a, 0xf9, 0x66, + 0x04, 0xc0, 0x01, 0x0d, 0x0f, 0x25, 0x28, 0x3f, 0xe0, 0x82, 0x36, 0x58, 0xb1, 0x4c, 0xb5, 0xae, + 0x14, 0x1a, 0x4e, 0x79, 0x99, 0xba, 0x7b, 0x24, 0x81, 0xc0, 0xef, 0x21, 0x7e, 0x54, 0x25, 0xcc, + 0x70, 0x03, 0xe0, 0xd5, 0x77, 0xf0, 0xc9, 0x0e, 0x01, 0xb7, 0x65, 0xa2, 0xd5, 0xf3, 0xea, 0xbe, + 0x9a, 0x6b, 0x57, 0x7c, 0x32, 0xa0, 0x06, 0x23, 0xa2, 0x87, 0x55, 0x72, 0xf5, 0x15, 0xab, 0xab, + 0xad, 0xb7, 0x97, 0xc5, 0x87, 0x14, 0x00, 0x40, 0xce, 0xa2, 0x46, 0x77, 0xbf, 0xca, 0x6f, 0x6d, + 0xfd, 0xfe, 0xf5, 0xcb, 0xf8, 0xd4, 0x0c, 0xa9, 0xff, 0x0c, 0x28, 0x0b, 0xd5, 0x48, 0x75, 0x2f, + 0xf3, 0xff, 0xdb, 0x6d, 0x8c, 0x30, 0xa0, 0x0e, 0x94, 0xc5, 0x22, 0x36, 0x7f, 0xea, 0xfa, 0xc7, + 0x6c, 0x28, 0xa0, 0x12, 0x89, 0x43, 0xb5, 0x19, 0xda, 0xef, 0x7d, 0x34, 0xe2, 0xb4, 0xc4, 0x3e, + 0x19, 0x50, 0x03, 0xdf, 0x15, 0x29, 0x5b, 0x01, 0x8d, 0xdd, 0xdd, 0xdd, 0xdf, 0x79, 0x96, 0x76, + 0x7d, 0x34, 0xdc, 0xc3, 0x0a, 0x28, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xff, 0xe3, 0xe1, 0x9c, + 0x00, 0x5f, 0xfb, 0x44, 0x6e, 0xc2, 0x7c, 0x6e, 0x6f, 0x6d, 0xb7, 0x59, 0xad, 0x34, 0xf8, 0x78, + 0x61, 0x40, 0x1b, 0x7a, 0x85, 0x64, 0x94, 0xf5, 0xfb, 0x8d, 0x3c, 0x5b, 0x39, 0xf2, 0xf5, 0x75, + 0x76, 0xfc, 0xc4, 0xaa, 0x17, 0x70, 0x10, 0x0c, 0x8f, 0x04, 0x5a, 0xbb, 0xc6, 0x7c, 0x6f, 0x6f, + 0x7b, 0xfc, 0x10, 0x21, 0x54, 0x33, 0x80, 0xc8, 0x29, 0x30, 0xa3, 0x97, 0xd2, 0xeb, 0x5e, 0x2e, + 0xea, 0xe9, 0x97, 0x8b, 0x96, 0xfb, 0x0c, 0x28, 0x00, 0xfa, 0xdb, 0x07, 0xa7, 0x39, 0x8b, 0x28, + 0xa3, 0x51, 0x46, 0xae, 0xaf, 0x59, 0xfd, 0xeb, 0x6d, 0xd4, 0x63, 0x61, 0xe2, 0x40, 0x0e, 0x39, + 0x0a, 0x2f, 0x57, 0x76, 0x2c, 0x5e, 0xf7, 0x51, 0x73, 0xf2, 0x7b, 0xd7, 0x45, 0x6d, 0xf7, 0xf8, + 0x65, 0x40, 0x0c, 0x23, 0xde, 0x3a, 0x87, 0xc5, 0x6d, 0x5b, 0xf5, 0x75, 0x75, 0x7b, 0x87, 0x9c, + 0x4e, 0xa1, 0xec, 0x00, 0x7d, 0x23, 0x49, 0x30, 0x2f, 0xcb, 0x6f, 0xbd, 0xd6, 0x2e, 0xe9, 0xba, + 0x6e, 0x35, 0x2b, 0xff, 0x86, 0x9c, 0x02, 0x00, 0xfa, 0x9a, 0xef, 0xa9, 0xaa, 0x77, 0xbe, 0xff, + 0x8e, 0xd8, 0x61, 0x40, 0x23, 0x04, 0x85, 0xf6, 0x17, 0xce, 0xae, 0xb7, 0xbf, 0xdd, 0xe5, 0x56, + 0x19, 0x50, 0x03, 0x15, 0xb6, 0xe0, 0xc8, 0xfb, 0xbe, 0xbb, 0x7a, 0xf5, 0xfb, 0x76, 0xf5, 0x85, + 0x89, 0x00, 0x39, 0x97, 0xa6, 0x37, 0x0e, 0x64, 0xf4, 0xfe, 0x7f, 0xee, 0xae, 0xb0, 0xe1, 0x05, + 0x00, 0x02, 0x5e, 0x28, 0x8e, 0xaa, 0xec, 0x46, 0x1d, 0xaa, 0x57, 0xff, 0xdc, 0x14, 0x13, 0xf0, + 0x55, 0xeb, 0xe3, 0xe8, 0x1b, 0xc2, 0xaf, 0x7c, 0x3c, 0x48, 0x00, 0x4e, 0xe6, 0x02, 0x28, 0xac, + 0x4a, 0xec, 0x63, 0xc9, 0x89, 0xd1, 0x8a, 0x20, 0xc8, 0x28, 0xb4, 0xe5, 0xd7, 0x1e, 0xb8, 0xf5, + 0xc7, 0xaf, 0xb5, 0x47, 0xae, 0x3d, 0x71, 0xeb, 0x8f, 0x5e, 0x75, 0x11, 0x85, 0x3f, 0x67, 0xd7, + 0xe1, 0xac, 0x2c, 0x70, 0x07, 0x69, 0x6b, 0x5b, 0xdf, 0xef, 0xef, 0x86, 0x88, 0x24, 0x04, 0x4c, + 0x38, 0x69, 0xcb, 0xff, 0x7f, 0xd1, 0xc7, 0x0a, 0x12, 0x00, 0x60, 0x2e, 0x4d, 0x33, 0x3a, 0x7d, + 0xdb, 0x3f, 0x6d, 0xfd, 0x5f, 0xbd, 0xe1, 0x37, 0x00, 0x68, 0xd9, 0xc2, 0x39, 0xff, 0x8f, 0xbf, + 0xbd, 0xdf, 0xe1, 0x99, 0xc0, 0x1d, 0x7a, 0x34, 0x8d, 0xee, 0xdb, 0x7f, 0xff, 0xec, 0x74, 0x82, + 0x79, 0xd8, 0x58, 0x91, 0xb1, 0x25, 0xff, 0x77, 0xfc, 0x51, 0x20, 0x0c, 0xaa, 0xf8, 0x25, 0x07, + 0xe8, 0x51, 0x10, 0x00, 0x6f, 0xb2, 0xf8, 0x61, 0x13, 0x85, 0xef, 0x4b, 0xf4, 0xd3, 0x4d, 0x3f, + 0x72, 0xfe, 0x29, 0xc1, 0x28, 0xe0, 0x2a, 0x23, 0xb0, 0x45, 0x47, 0x6f, 0x4f, 0x84, 0xd9, 0xc0, + 0x1a, 0x36, 0x58, 0xc2, 0xbf, 0xfe, 0xf7, 0x8a, 0x70, 0x33, 0xb9, 0x23, 0x94, 0x12, 0x1d, 0xcb, + 0xd1, 0xf1, 0xd8, 0x21, 0x30, 0x0e, 0x99, 0xf1, 0xc8, 0x81, 0x2e, 0x4a, 0xb0, 0xcb, 0x80, 0x1a, + 0x37, 0x0b, 0x2f, 0xed, 0xff, 0xf6, 0xff, 0xeb, 0x14, 0xe1, 0xed, 0x4e, 0x13, 0x65, 0x00, 0xb3, + 0x0f, 0x10, 0x0e, 0xe0, 0xaa, 0xab, 0xff, 0xaa, 0xc2, 0xf8, 0x21, 0xe1, 0x01, 0x37, 0x56, 0xd3, + 0xae, 0xbf, 0x5f, 0xd8, 0xac, 0x11, 0x3b, 0x9d, 0x58, 0x57, 0x02, 0x2f, 0xc3, 0xfb, 0xdf, 0xf9, + 0xb9, 0x7f, 0xf0, 0xb3, 0x81, 0x0a, 0xa4, 0x93, 0x7a, 0x7a, 0x7f, 0xf0, 0xae, 0x13, 0x05, 0xa3, + 0xec, 0xeb, 0xff, 0x09, 0xb8, 0x08, 0x40, 0xd8, 0x82, 0xbf, 0xb4, 0xba, 0xfd, 0x35, 0x4f, 0xe1, + 0x99, 0x41, 0x05, 0x06, 0xb6, 0x61, 0x34, 0xff, 0xff, 0xac, 0x26, 0xe0, 0x0b, 0xbe, 0x59, 0x5e, + 0x3b, 0x72, 0xff, 0x6f, 0xb7, 0xf0, 0xab, 0x80, 0xa4, 0xd7, 0xf9, 0xff, 0xed, 0xa7, 0xc2, 0x6e, + 0x01, 0x03, 0x5c, 0xab, 0xe6, 0x66, 0x8d, 0x1b, 0x3f, 0x4e, 0xff, 0x8b, 0x70, 0x27, 0x46, 0xe1, + 0xa3, 0x76, 0x18, 0x44, 0x00, 0x67, 0x77, 0x34, 0x62, 0x3b, 0xdc, 0xed, 0xef, 0x7f, 0xf6, 0xe0, + 0xc4, 0x0c, 0x23, 0x46, 0x12, 0xd4, 0x56, 0x2e, 0xac, 0xa2, 0x4a, 0x73, 0xcb, 0x64, 0xa6, 0xb3, + 0x96, 0x0d, 0xe4, 0x4f, 0x96, 0x67, 0x06, 0x08, 0x85, 0x61, 0x28, 0x68, 0xa2, 0x22, 0x60, 0x04, + 0x84, 0x61, 0xcf, 0x58, 0x9f, 0xf8, 0x62, 0x2c, 0x01, 0xc0, 0x35, 0x53, 0x95, 0x14, 0x4d, 0x3e, + 0x9a, 0x79, 0x6b, 0x15, 0x71, 0xa6, 0x0e, 0xfc, 0x55, 0xc6, 0x5e, 0x57, 0x30, 0xa1, 0x20, 0x20, + 0x5c, 0x50, 0x5a, 0xbd, 0xef, 0xa6, 0x9a, 0xc9, 0xd3, 0x86, 0x14, 0x00, 0xcb, 0xeb, 0x78, 0x97, + 0xd7, 0x7f, 0xd7, 0x7b, 0xd8, 0xc3, 0x0a, 0x00, 0x90, 0x55, 0xc6, 0x40, 0xff, 0xfb, 0xfc, 0xe6, + 0x16, 0x50, 0x04, 0xe9, 0x76, 0xc0, 0x1b, 0xde, 0x57, 0x57, 0x5d, 0x56, 0xaf, 0x5a, 0xc3, 0x0a, + 0x04, 0xcc, 0x49, 0x1b, 0x6f, 0xba, 0xbf, 0xf9, 0x2c, 0x34, 0x88, 0x23, 0x36, 0xde, 0xbf, 0xf7, + 0xff, 0xf2, 0xc6, 0x90, 0xe0, 0x14, 0xd0, 0x58, 0x70, 0xcc, 0x54, 0xc3, 0x32, 0x00, 0x2c, 0x4c, + 0xa8, 0x18, 0x12, 0x4f, 0x5b, 0xa7, 0xe6, 0xf5, 0xcd, 0xb6, 0xf0, 0x43, 0x32, 0x86, 0x94, 0x00, + 0xff, 0x79, 0x0d, 0x65, 0xb6, 0x57, 0x57, 0xad, 0xb5, 0x7b, 0xe9, 0xa6, 0x29, 0xec, 0x3c, 0xa0, + 0x02, 0x2a, 0x02, 0xce, 0xda, 0x9c, 0xd8, 0xaf, 0x17, 0xa6, 0xff, 0x83, 0xee, 0x2d, 0x96, 0x85, + 0xad, 0x32, 0x70, 0x7d, 0xcb, 0xb6, 0xf6, 0x72, 0xec, 0x7d, 0xfd, 0xdb, 0x6d, 0xb6, 0xf8, 0x61, + 0x10, 0x01, 0x1f, 0xc4, 0xb2, 0x6b, 0x4f, 0xd3, 0xe4, 0xfe, 0x9d, 0xed, 0x3b, 0x7f, 0x61, 0xc4, + 0x50, 0x02, 0x6f, 0xe3, 0x21, 0x53, 0xaf, 0xa2, 0x69, 0x93, 0x97, 0x69, 0x93, 0x83, 0xfe, 0x5d, + 0xff, 0x6e, 0x36, 0x9d, 0x34, 0xd3, 0x4f, 0x86, 0x70, 0x0d, 0xf3, 0xcd, 0xbb, 0xb7, 0xb7, 0x7f, + 0xea, 0xe9, 0xd6, 0x95, 0x42, 0xf8, 0x01, 0xb5, 0xa5, 0x92, 0x3b, 0x7c, 0x5a, 0xf5, 0xd5, 0xd5, + 0x57, 0x1b, 0xb0, 0xbe, 0x00, 0x6b, 0x99, 0xc6, 0x39, 0xbf, 0x3a, 0xbf, 0xc5, 0x71, 0x5e, 0xf7, + 0x25, 0x85, 0xf0, 0x09, 0xe2, 0x5d, 0x14, 0xf9, 0xd7, 0x57, 0xb7, 0x4d, 0x5d, 0x5c, 0x5d, 0xc5, + 0xdf, 0xb0, 0x9e, 0x01, 0x12, 0x89, 0x98, 0x6e, 0xff, 0xc5, 0xaf, 0xd5, 0xd5, 0xd6, 0xb8, 0x4d, + 0x40, 0x06, 0xbd, 0x48, 0xa1, 0x57, 0xfd, 0xea, 0xab, 0x77, 0xc5, 0xdc, 0x5d, 0xfe, 0x1b, 0x50, + 0x03, 0x26, 0xa1, 0xd4, 0xeb, 0xef, 0xaa, 0xd7, 0xab, 0xde, 0x4e, 0xc8, 0x88, 0xf1, 0x45, 0xf8, + 0xa2, 0x2e, 0xea, 0xff, 0x0f, 0x10, 0x40, 0x00, 0x4d, 0x09, 0xfe, 0xcc, 0x50, 0xb3, 0xe8, 0xde, + 0x54, 0x6a, 0x0c, 0x4d, 0x01, 0x57, 0xee, 0x64, 0x9c, 0x95, 0xed, 0xdb, 0xd2, 0xb2, 0x23, 0xce, + 0xf0, 0x96, 0xd4, 0x96, 0xaf, 0xab, 0xff, 0xf1, 0x48, 0xa4, 0xa0, 0x72, 0x85, 0xc9, 0x00, 0x39, + 0x7a, 0x62, 0x7a, 0x33, 0xff, 0xf7, 0x7a, 0x08, 0x1c, 0x30, 0x43, 0x80, 0x1d, 0x3e, 0xd0, 0xaa, + 0x4a, 0x7d, 0xff, 0xfd, 0x3b, 0xc0, 0x70, 0x80, 0x98, 0x0a, 0x46, 0xa8, 0x77, 0xb5, 0x98, 0xc4, + 0x9e, 0x78, 0x01, 0xee, 0xe7, 0x9e, 0x37, 0x46, 0xf2, 0x56, 0x8d, 0xf5, 0xc4, 0x7b, 0xc9, 0x01, + 0x51, 0xc0, 0x00, 0x40, 0x3a, 0x38, 0x70, 0xbc, 0x50, 0x00, 0x5e, 0x41, 0x2a, 0xa1, 0xb8, 0x63, + 0xc4, 0xff, 0x74, 0xd3, 0xf4, 0xcb, 0xd9, 0xc7, 0xfc, 0x43, 0xe7, 0x0f, 0xf6, 0x19, 0x63, 0xc0, + 0x66, 0x7f, 0xf4, 0xb5, 0xfa, 0xd7, 0xfd, 0x8a, 0x51, 0xc8, 0xc8, 0xe6, 0x40, 0x45, 0x6a, 0x37, + 0x3e, 0x39, 0x42, 0xca, 0x4b, 0xe3, 0x9c, 0x03, 0x3c, 0x27, 0xaa, 0x7c, 0x30, 0xe0, 0x05, 0xb8, + 0xad, 0x54, 0x34, 0x5e, 0xd2, 0x69, 0xe9, 0xa6, 0x9a, 0x7f, 0xf7, 0xc6, 0x60, 0x44, 0xb6, 0x61, + 0x87, 0xc7, 0x70, 0xd2, 0x80, 0x2b, 0xb1, 0x92, 0xd9, 0xf4, 0x7b, 0xd6, 0xbf, 0x27, 0x4d, 0x7d, + 0x8a, 0x53, 0x91, 0x86, 0xb0, 0x04, 0x8e, 0x89, 0xf5, 0x71, 0xff, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, + 0xe1, 0x5c, 0x01, 0x23, 0x91, 0x07, 0xe5, 0x6b, 0xff, 0xdb, 0x6f, 0x88, 0x64, 0x09, 0x46, 0xb9, + 0xa1, 0x64, 0x70, 0x04, 0x15, 0xf8, 0x04, 0xce, 0x13, 0xfe, 0xb5, 0xe9, 0xc2, 0xea, 0x15, 0xd5, + 0xfe, 0xb5, 0xfb, 0x63, 0x30, 0x10, 0xb9, 0x8c, 0xd5, 0xa7, 0x61, 0x57, 0x01, 0x3a, 0xdc, 0x55, + 0xcb, 0xfe, 0xb5, 0xf8, 0xc9, 0x41, 0x2d, 0x39, 0xe7, 0xfe, 0x15, 0x50, 0x06, 0x46, 0xbd, 0x0b, + 0xbe, 0xff, 0xfe, 0xba, 0xc2, 0x6c, 0x80, 0x20, 0xe4, 0xda, 0x6d, 0xff, 0xfa, 0xe2, 0xb0, 0x94, + 0x2f, 0xf1, 0x0b, 0x38, 0x04, 0x1e, 0x48, 0xc3, 0xfe, 0x0f, 0x15, 0xb4, 0xff, 0xff, 0x12, 0xce, + 0x16, 0x62, 0x21, 0x66, 0x40, 0xc8, 0x93, 0xcf, 0xfb, 0xee, 0xfe, 0x16, 0x70, 0x78, 0x7f, 0xfb, + 0x3f, 0xf8, 0x5a, 0x60, 0x04, 0xaa, 0x54, 0x6e, 0x1f, 0xff, 0xbb, 0xc7, 0x32, 0x81, 0xae, 0x09, + 0x31, 0xb1, 0x59, 0x61, 0x0a, 0x23, 0x00, 0x01, 0xfb, 0x28, 0x6c, 0x58, 0x22, 0xf9, 0x7b, 0xdb, + 0xca, 0xa9, 0x2c, 0xbc, 0xe7, 0xfc, 0xbe, 0x9e, 0x05, 0x88, 0xd2, 0x06, 0x3c, 0x49, 0x4b, 0x00, + 0x49, 0x4d, 0x3a, 0xc4, 0xd8, 0xb1, 0x62, 0x25, 0x95, 0x93, 0x6a, 0x7e, 0x96, 0x62, 0xb9, 0x15, + 0x81, 0x74, 0x39, 0xac, 0x53, 0xfc, 0x2e, 0xc4, 0x80, 0x86, 0xe6, 0x15, 0x75, 0x5f, 0xf7, 0xbf, + 0xc5, 0x85, 0xa5, 0x08, 0x02, 0x55, 0xc9, 0xd5, 0xd5, 0xd5, 0xd7, 0xdd, 0x78, 0x65, 0xc2, 0xe9, + 0xc2, 0xf7, 0xff, 0xf7, 0xc3, 0x68, 0x80, 0x23, 0x0b, 0xb7, 0x4b, 0xdf, 0xde, 0xb5, 0x71, 0x5b, + 0x8a, 0xc0, 0x0a, 0xff, 0xe3, 0x70, 0x10, 0x80, 0xd9, 0x65, 0x56, 0xf5, 0x86, 0x9c, 0x02, 0x1c, + 0x6a, 0x67, 0xeb, 0xdd, 0x6a, 0xf7, 0xd7, 0x7e, 0xf8, 0x65, 0xc0, 0x72, 0xc1, 0x59, 0x6f, 0xfa, + 0x74, 0xd3, 0x4d, 0x34, 0xf2, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x51, 0x28, 0xb1, 0xac, + 0x0a, 0x21, 0x11, 0x61, 0x12, 0x91, 0x29, 0x1e, 0x52, 0x25, 0x23, 0xe0, 0x40, 0xae, 0xbe, 0x8c, + 0xf5, 0xd6, 0x29, 0xf0, 0x43, 0x0d, 0x62, 0x11, 0x5e, 0x2f, 0x08, 0xa2, 0xc5, 0x36, 0x10, 0xe1, + 0x00, 0x84, 0xbd, 0x1b, 0xa4, 0xe8, 0xbf, 0xfa, 0xb9, 0x26, 0x18, 0xf8, 0x22, 0xbb, 0xf1, 0x57, + 0x5e, 0x8d, 0x16, 0x8b, 0x18, 0xa4, 0x40, 0xe4, 0x44, 0x0c, 0x65, 0x3e, 0xb1, 0x7d, 0x62, 0x9b, + 0xac, 0x51, 0xbc, 0x86, 0x55, 0xc3, 0x7d, 0x1e, 0x29, 0x71, 0x0b, 0x94, 0xbd, 0x48, 0x97, 0x13, + 0x26, 0xb5, 0x58, 0x43, 0xeb, 0x17, 0xd6, 0x28, 0x9e, 0xba, 0x8f, 0xe6, 0xaa, 0xe0, 0xe3, 0x08, + 0xa8, 0xed, 0x15, 0xdf, 0x55, 0xc3, 0x18, 0x4f, 0xa2, 0x3d, 0xf4, 0x5c, 0xa6, 0xe4, 0x33, 0xbf, + 0xe6, 0xbb, 0xeb, 0x93, 0x75, 0xfa, 0x10, 0x4a, 0xba, 0x1b, 0x51, 0x38, 0x47, 0xe5, 0x2d, 0xdd, + 0xfc, 0xc1, 0x0e, 0x2e, 0x26, 0x23, 0x08, 0x76, 0x25, 0xdf, 0x26, 0x25, 0x62, 0x90, 0x5b, 0x17, + 0xca, 0xa2, 0x28, 0x43, 0x4b, 0xd4, 0xa9, 0x43, 0x9e, 0x55, 0x45, 0xf1, 0x17, 0x7d, 0xdf, 0x27, + 0x62, 0x2e, 0xf2, 0x73, 0x6c, 0x95, 0x3f, 0x05, 0xa3, 0x19, 0xd0, 0xde, 0x9b, 0xa2, 0x4d, 0xf4, + 0x5d, 0x44, 0xf4, 0x13, 0x7f, 0xa9, 0x52, 0xfa, 0x2b, 0xdc, 0x47, 0xc4, 0x42, 0x5d, 0x08, 0x60, + 0xfa, 0xc5, 0x37, 0x58, 0xa7, 0xc4, 0x57, 0x63, 0x86, 0x2d, 0x81, 0x31, 0xf9, 0xba, 0x0a, 0xc7, + 0xfa, 0xbf, 0x84, 0x7c, 0x4d, 0x62, 0x51, 0x1e, 0xb1, 0x28, 0xaf, 0xf5, 0x6f, 0xab, 0xf8, 0x9f, + 0xab, 0xfd, 0x5b, 0x1c, 0xb7, 0x97, 0xa3, 0x54, 0xdc, 0x45, 0xab, 0x4b, 0x57, 0x75, 0xd5, 0xd1, + 0x5c, 0x10, 0xf5, 0x58, 0xa7, 0xec, 0x21, 0x95, 0x8a, 0xe8, 0x27, 0xd5, 0xd8, 0x5b, 0x26, 0xc9, + 0xd9, 0x79, 0xe4, 0x5e, 0x60, 0x8f, 0x17, 0xe2, 0x10, 0x8e, 0xae, 0xb9, 0x7c, 0xc2, 0xf5, 0x57, + 0x88, 0x93, 0x08, 0xcf, 0xc4, 0x74, 0x92, 0xdd, 0xd7, 0x27, 0x77, 0x58, 0x65, 0x6d, 0xf5, 0x69, + 0x79, 0x38, 0xbc, 0xd8, 0x62, 0x27, 0xad, 0x57, 0x28, 0xe2, 0x6d, 0x39, 0xb8, 0xa1, 0xae, 0xfb, + 0xbf, 0xe8, 0xdd, 0xf5, 0x7f, 0x93, 0x5a, 0xa3, 0x90, 0xe3, 0x28, 0x3c, 0x9b, 0xac, 0x57, 0x47, + 0xca, 0x6e, 0xb1, 0x4f, 0xd1, 0x2c, 0x85, 0x79, 0xc7, 0x2e, 0x2d, 0xa7, 0xe4, 0xe4, 0x12, 0xef, + 0xbe, 0x08, 0x8b, 0x5a, 0xd4, 0xbd, 0x5a, 0x20, 0xeb, 0x5d, 0x0b, 0x95, 0xf4, 0x4b, 0x93, 0xf5, + 0xa9, 0x79, 0x44, 0x5d, 0x6b, 0x82, 0x4e, 0xab, 0xd2, 0xf4, 0x26, 0xbc, 0x4f, 0x89, 0x20, 0x52, + 0xf7, 0xe2, 0x42, 0x75, 0xae, 0xeb, 0xc4, 0x89, 0x17, 0x77, 0xbe, 0x2b, 0x7c, 0x40, 0x44, 0x66, + 0x2b, 0xb4, 0x2b, 0x15, 0xb4, 0xd3, 0xbb, 0xed, 0xb7, 0xf1, 0x3b, 0xb5, 0x11, 0xea, 0xab, 0xe2, + 0xad, 0xd0, 0xd1, 0x23, 0x6d, 0x14, 0xbd, 0x0d, 0xea, 0x89, 0x12, 0xbd, 0x2e, 0x19, 0x9b, 0xa2, + 0xd7, 0xd1, 0x6b, 0xe0, 0x93, 0xbb, 0xd5, 0xf5, 0x8a, 0x4e, 0xb9, 0x47, 0x74, 0x2a, 0x2f, 0x10, + 0x4d, 0x6b, 0xe5, 0xae, 0xfe, 0x08, 0x8b, 0x75, 0xe5, 0x7c, 0x13, 0x8a, 0xe4, 0xf4, 0xe9, 0xbb, + 0x84, 0x04, 0x97, 0x7b, 0xe1, 0x01, 0x3e, 0x24, 0xc6, 0x58, 0xb9, 0x33, 0xc7, 0xdd, 0xfa, 0xb6, + 0xaa, 0xbf, 0x8b, 0xab, 0xee, 0xee, 0xf8, 0x81, 0x01, 0x21, 0x77, 0x7b, 0xdd, 0xc2, 0xdd, 0x1d, + 0xab, 0xab, 0x15, 0x84, 0x25, 0xc4, 0x98, 0xee, 0xff, 0x12, 0xaf, 0x11, 0xc1, 0x15, 0xdf, 0x6f, + 0xab, 0xfd, 0x5b, 0xc2, 0x15, 0xd1, 0x2a, 0xba, 0x2c, 0x5e, 0x24, 0x58, 0x6a, 0x9d, 0x37, 0x8a, + 0xc5, 0x1f, 0x10, 0x2f, 0xcb, 0x1c, 0x1a, 0x24, 0xc9, 0xdb, 0x86, 0x44, 0x04, 0x04, 0xdd, 0x78, + 0xe2, 0xef, 0xbe, 0x22, 0x3b, 0x7b, 0xd6, 0xaa, 0x5e, 0x14, 0x6a, 0xbf, 0x35, 0xc5, 0x50, 0x5c, + 0x2a, 0x4e, 0x00, 0x15, 0x86, 0x70, 0x03, 0x41, 0x4b, 0x02, 0x7a, 0xee, 0xb8, 0x9a, 0x7f, 0xb6, + 0xd8, 0xef, 0xcb, 0x5b, 0x6d, 0xb7, 0x7c, 0x2b, 0x38, 0x00, 0xed, 0x3d, 0x48, 0x2e, 0x78, 0xd3, + 0x4f, 0xff, 0x77, 0xf2, 0x12, 0x92, 0xfc, 0xa6, 0xab, 0xd4, 0x4d, 0x04, 0xe5, 0xf5, 0xa8, 0x57, + 0xad, 0x5e, 0x10, 0x9b, 0x11, 0xf0, 0x43, 0x7d, 0x5b, 0xeb, 0xd5, 0xd1, 0x6a, 0xba, 0xca, 0x4e, + 0xb2, 0xbe, 0x40, 0xc3, 0x8a, 0xfe, 0x20, 0x29, 0x3f, 0x20, 0x02, 0x31, 0x36, 0x81, 0x8f, 0x43, + 0x08, 0x0f, 0xad, 0x89, 0x68, 0x25, 0xf1, 0x61, 0x36, 0x8d, 0x62, 0xad, 0x23, 0x2d, 0x63, 0xc3, + 0x93, 0xa8, 0x00, 0x5b, 0x51, 0xc3, 0x8b, 0x10, 0x3a, 0x81, 0x46, 0x78, 0x30, 0x2d, 0x7c, 0x8f, + 0x29, 0xe3, 0xce, 0x52, 0x65, 0xe2, 0x02, 0x94, 0xc7, 0x02, 0xb9, 0x93, 0x01, 0x19, 0x38, 0x2c, + 0x61, 0xba, 0xa2, 0x0b, 0x11, 0xc4, 0x99, 0xc1, 0x60, 0xd0, 0x03, 0x94, 0x58, 0xd8, 0x25, 0x28, + 0x2b, 0x91, 0xf5, 0xb4, 0xcb, 0x87, 0xc0, 0x07, 0x9e, 0x38, 0x60, 0x27, 0x9a, 0xea, 0xae, 0x22, + 0x13, 0xde, 0xef, 0x7c, 0x28, 0x8a, 0x00, 0x55, 0x28, 0x80, 0x7c, 0x09, 0x4f, 0x66, 0x7e, 0xfe, + 0x5e, 0x57, 0xae, 0x4e, 0x0f, 0x5c, 0x1b, 0xb8, 0x3e, 0xd4, 0xa4, 0xf4, 0x0d, 0x98, 0x2c, 0xcd, + 0x0b, 0xa8, 0x02, 0xb5, 0x34, 0x1b, 0x52, 0xc1, 0x14, 0xff, 0xfd, 0xfa, 0xe7, 0x9d, 0x12, 0x75, + 0x55, 0x9e, 0x40, 0x6f, 0xb2, 0x1d, 0x76, 0x9f, 0x00, 0x52, 0x88, 0x4c, 0x36, 0xa0, 0x45, 0x06, + 0x35, 0x07, 0x42, 0x87, 0x81, 0xd4, 0xe1, 0x97, 0x6f, 0xf8, 0xe2, 0x5f, 0xb0, 0xb2, 0x38, 0x00, + 0x41, 0xe8, 0xf4, 0x69, 0x30, 0xdd, 0x5b, 0x6f, 0x6c, 0xff, 0x19, 0xec, 0xb4, 0xdf, 0xfd, 0xc7, + 0xd7, 0xe3, 0x61, 0x8a, 0x1e, 0xf2, 0x0b, 0x5a, 0x37, 0xf5, 0x64, 0xd1, 0x1a, 0xe6, 0x35, 0xdd, + 0xd7, 0x47, 0x62, 0x58, 0x47, 0x7d, 0xf7, 0x78, 0xe7, 0x2c, 0x19, 0x78, 0x62, 0x5e, 0xba, 0xae, + 0x11, 0x1c, 0xef, 0xae, 0xaa, 0xaa, 0xb8, 0x90, 0x80, 0x2a, 0x10, 0x3e, 0xa3, 0x14, 0xf0, 0xe3, + 0x84, 0x30, 0x06, 0x7e, 0x73, 0x86, 0x8e, 0xd8, 0x17, 0xd7, 0xdf, 0x70, 0xe5, 0xff, 0x0e, 0xbb, + 0x20, 0xe6, 0x25, 0x89, 0x44, 0x02, 0x01, 0x98, 0x59, 0x5e, 0x1b, 0xcf, 0x77, 0x0d, 0xd6, 0x0d, + 0x85, 0xda, 0x9b, 0xe6, 0x59, 0xef, 0x14, 0xcb, 0x0c, 0x53, 0x14, 0x3c, 0x22, 0x24, 0x14, 0xe2, + 0x8c, 0xc7, 0xf9, 0x4c, 0xd9, 0xb8, 0xaa, 0xed, 0xa2, 0x4b, 0x1e, 0x81, 0x5d, 0xd3, 0x7b, 0xbd, + 0xfb, 0x8a, 0xbb, 0xe4, 0x59, 0x97, 0xb3, 0x88, 0x8c, 0x28, 0xea, 0x95, 0x1e, 0x85, 0x4b, 0xf1, + 0xe3, 0xf8, 0xac, 0x56, 0xed, 0x2d, 0xa6, 0x2b, 0x15, 0xb8, 0xae, 0xb8, 0x25, 0xb7, 0x6d, 0xcd, + 0x8c, 0xfc, 0xa1, 0x8e, 0xc4, 0xbd, 0xe4, 0xe8, 0xb5, 0xf4, 0x46, 0x2b, 0xae, 0x62, 0x82, 0x44, + 0xa4, 0x1b, 0xf1, 0x94, 0x9e, 0x9f, 0x89, 0xe5, 0xd5, 0xef, 0x98, 0xca, 0xbe, 0x22, 0x13, 0xd5, + 0x57, 0x77, 0xc4, 0x88, 0x04, 0x86, 0x70, 0x99, 0x16, 0x69, 0xc1, 0x8c, 0xbc, 0x16, 0x1e, 0x69, + 0xa4, 0x2b, 0x0a, 0x3b, 0x2a, 0x37, 0xb8, 0x82, 0x94, 0xb9, 0xa6, 0xcb, 0x11, 0x25, 0x45, 0x3a, + 0xc2, 0xc8, 0x48, 0x11, 0x86, 0x34, 0x8a, 0xef, 0xdb, 0xff, 0xc3, 0x08, 0xa0, 0x0b, 0x1f, 0xb3, + 0xa7, 0xda, 0xdb, 0x6d, 0xb6, 0xdb, 0x7f, 0xdb, 0xde, 0x37, 0xb0, 0xaf, 0x17, 0x50, 0x8f, 0xe5, + 0x0b, 0x6e, 0xe2, 0x79, 0x09, 0xbb, 0xf9, 0x8b, 0x5a, 0x85, 0x3a, 0x11, 0xdc, 0x44, 0x9d, 0xcb, + 0x4c, 0x22, 0x10, 0x15, 0x72, 0xc1, 0xf7, 0x37, 0x8b, 0xe2, 0x04, 0x89, 0x31, 0xe5, 0xea, 0x9f, + 0xc2, 0x39, 0x9c, 0x9f, 0x63, 0x2f, 0xdf, 0xeb, 0xb1, 0xee, 0xfa, 0xc4, 0xfd, 0xdd, 0xee, 0xb9, + 0x85, 0x53, 0xa4, 0x23, 0xb0, 0x43, 0xc5, 0xd7, 0x30, 0x20, 0xa6, 0x9b, 0x8b, 0xe6, 0x1f, 0xbb, + 0xae, 0x8d, 0x95, 0xf5, 0xca, 0x23, 0xbe, 0xee, 0x4c, 0x21, 0xf3, 0x78, 0xbf, 0x86, 0xcc, 0xbb, + 0x26, 0x14, 0xd3, 0x5f, 0x26, 0x24, 0x55, 0xef, 0x7b, 0xf8, 0x93, 0x08, 0x78, 0xac, 0xac, 0x79, + 0x6b, 0x2f, 0x17, 0x5f, 0xec, 0x26, 0xab, 0x9f, 0x98, 0x25, 0x3b, 0x18, 0xbe, 0x30, 0xb7, 0x7b, + 0x6d, 0xe9, 0xb2, 0xba, 0xa5, 0x93, 0x98, 0x5e, 0x6c, 0x36, 0x2e, 0x8d, 0x15, 0x62, 0x3c, 0x41, + 0x8f, 0xbb, 0xf9, 0xaa, 0xb8, 0xbe, 0x43, 0xaa, 0xfe, 0xad, 0x8e, 0x45, 0x2c, 0x32, 0x74, 0x7e, + 0x60, 0x83, 0xbf, 0xe2, 0x89, 0xb9, 0x4e, 0x47, 0x64, 0x37, 0x2f, 0xe2, 0x42, 0x86, 0x71, 0x5d, + 0x9f, 0x02, 0xc2, 0xc8, 0xe7, 0x1f, 0x87, 0xb9, 0x41, 0xd6, 0xb5, 0xcb, 0x3a, 0xb7, 0x84, 0x46, + 0x64, 0x91, 0x7e, 0x52, 0x0a, 0x8a, 0xcc, 0x65, 0xd9, 0x4c, 0x5c, 0x9e, 0x21, 0xf6, 0xbc, 0xa7, + 0x55, 0x02, 0xdf, 0xeb, 0xfb, 0xe6, 0x13, 0x7b, 0x9f, 0x84, 0x06, 0x49, 0xbd, 0xde, 0xe9, 0x6b, + 0xb1, 0x69, 0x25, 0x8e, 0xe3, 0x89, 0xa4, 0x96, 0x92, 0x57, 0xb8, 0x9e, 0x8b, 0x94, 0x9d, 0x6a, + 0x4e, 0x62, 0xd6, 0xbe, 0x63, 0x2a, 0x57, 0x2f, 0x77, 0xbf, 0x89, 0x1e, 0x47, 0x4b, 0x3b, 0x8c, + 0xcf, 0x55, 0xe2, 0x42, 0x57, 0x7e, 0xa2, 0xe9, 0xfb, 0xac, 0xaa, 0xe2, 0x2e, 0xb5, 0x5f, 0xe6, + 0xac, 0x20, 0x11, 0x96, 0x11, 0xcd, 0xc2, 0xdd, 0x23, 0x29, 0xa2, 0xba, 0xfe, 0x5e, 0xef, 0xaf, + 0x57, 0x16, 0x5a, 0x4f, 0x49, 0x24, 0x92, 0x11, 0xc9, 0x7a, 0xaa, 0xea, 0xc4, 0x47, 0x21, 0x6b, + 0x71, 0x5c, 0x10, 0xc9, 0x8e, 0xfa, 0xf8, 0xab, 0x7b, 0x69, 0x36, 0xda, 0x5e, 0x12, 0xd2, 0xa5, + 0x26, 0x93, 0x75, 0xd5, 0xf8, 0x9f, 0x08, 0x88, 0x18, 0x22, 0xb5, 0x27, 0xf6, 0x25, 0x13, 0x80, + 0xbb, 0x08, 0x2c, 0x4f, 0x6f, 0xc4, 0xd7, 0x05, 0x07, 0x17, 0x8b, 0xae, 0xaa, 0xfe, 0x08, 0x01, + 0x09, 0x79, 0x3b, 0xcb, 0xc9, 0x55, 0xc5, 0xe2, 0x2f, 0x93, 0x36, 0x6f, 0x97, 0xb4, 0xd1, 0x38, + 0xed, 0xed, 0x6d, 0x34, 0x4d, 0xd6, 0x27, 0x82, 0x23, 0x3e, 0xa4, 0x49, 0xfa, 0xd4, 0xf1, 0x17, + 0xbd, 0xf0, 0x88, 0x80, 0x8e, 0xee, 0xeb, 0x17, 0x57, 0x7f, 0x89, 0xa0, 0xc9, 0x05, 0x80, 0x80, + 0xae, 0xa9, 0x7f, 0xff, 0xef, 0x76, 0x38, 0x40, 0x47, 0xcb, 0xd5, 0x71, 0x33, 0x13, 0x77, 0x27, + 0x36, 0xb5, 0x19, 0xc2, 0x76, 0xe9, 0x53, 0xd3, 0xf0, 0x86, 0x9d, 0x34, 0xb6, 0xb6, 0x9a, 0xf0, + 0x84, 0x9a, 0x95, 0x37, 0xbe, 0xdd, 0x27, 0xc6, 0x6d, 0xb7, 0xb5, 0x68, 0xdd, 0x5b, 0xe9, 0x17, + 0x46, 0x74, 0x23, 0xa2, 0xfa, 0x3d, 0xef, 0x13, 0xe2, 0x4c, 0x4a, 0xd7, 0x13, 0x57, 0xa0, 0x9a, + 0x1a, 0x1e, 0x14, 0x8f, 0xff, 0xaf, 0x84, 0x3c, 0x20, 0x23, 0xe8, 0xc9, 0x85, 0x62, 0x78, 0x89, + 0x44, 0xaa, 0xe5, 0xe4, 0xee, 0xe6, 0xe6, 0x15, 0xaa, 0xf9, 0x79, 0x72, 0x5e, 0x0b, 0xa9, 0x97, + 0x52, 0xe9, 0xcb, 0x90, 0x8f, 0xab, 0x17, 0xd1, 0x3a, 0x2b, 0xab, 0x12, 0x75, 0xc2, 0x4e, 0x24, + 0xbc, 0x90, 0xad, 0x57, 0x5a, 0x93, 0x93, 0x5a, 0xac, 0x49, 0xba, 0xa8, 0xb8, 0x8b, 0x2d, 0xee, + 0xb9, 0x8a, 0xb5, 0x93, 0xa0, 0x87, 0x46, 0xf2, 0x89, 0xdd, 0x4b, 0xc8, 0x4d, 0x57, 0xc7, 0xc9, + 0xa9, 0x4d, 0x57, 0x4d, 0x3c, 0xbc, 0x33, 0x63, 0x6e, 0xda, 0xb6, 0x2a, 0xff, 0x5d, 0x72, 0xae, + 0x62, 0xa7, 0x4e, 0xb9, 0x2e, 0xe7, 0xcc, 0xbd, 0x5e, 0xe2, 0x44, 0xfd, 0x95, 0xdf, 0xf3, 0x15, + 0x6b, 0x11, 0xc9, 0xa5, 0x7f, 0x31, 0x2f, 0x5f, 0x14, 0x5b, 0xa5, 0xd5, 0xd7, 0x2e, 0xaf, 0x27, + 0x30, 0xcb, 0xbc, 0xbc, 0x25, 0xd2, 0x49, 0x6b, 0x26, 0x20, 0x41, 0x4d, 0x8d, 0x2d, 0xa6, 0xbf, + 0x5b, 0xc9, 0xd6, 0x52, 0xf0, 0x9e, 0xd2, 0x57, 0x6f, 0xf0, 0x45, 0x17, 0x4e, 0x9b, 0xfd, 0x5e, + 0x7e, 0xaf, 0x58, 0x9f, 0x13, 0x5c, 0x87, 0xd5, 0x78, 0x8a, 0xef, 0xaa, 0xf9, 0xaa, 0xbe, 0x24, + 0x23, 0xc4, 0xeb, 0x13, 0x27, 0x25, 0x5b, 0x9f, 0xf9, 0x72, 0xfd, 0x72, 0xd5, 0x75, 0xc2, 0x5d, + 0xdc, 0x9e, 0x4f, 0x27, 0x28, 0xcd, 0xd2, 0xf0, 0x44, 0x77, 0xdf, 0xa4, 0xea, 0x64, 0x5f, 0x92, + 0xb7, 0xbe, 0x42, 0x2a, 0xfe, 0xb0, 0x4b, 0xd1, 0x6a, 0xba, 0xea, 0xfa, 0xcd, 0xf0, 0x9f, 0x2f, + 0xae, 0xab, 0x94, 0x63, 0xdb, 0x8e, 0x89, 0x08, 0xf8, 0x88, 0x9e, 0xc2, 0x3b, 0xaa, 0xef, 0x77, + 0x75, 0xcc, 0x5a, 0xdc, 0x9c, 0x11, 0x8e, 0xca, 0xbf, 0xbe, 0x43, 0xe9, 0xa7, 0xeb, 0x8c, 0xbe, + 0x6e, 0xa9, 0x2e, 0x2a, 0xd6, 0xd3, 0x7b, 0x6b, 0x82, 0x3e, 0xee, 0xf3, 0xf5, 0x65, 0x75, 0xef, + 0x93, 0x4d, 0x36, 0x89, 0xd0, 0x8a, 0x88, 0xe4, 0x2d, 0x62, 0xfc, 0x4f, 0x89, 0xf0, 0x8d, 0x73, + 0x1e, 0xf7, 0x78, 0x91, 0x35, 0xdf, 0x92, 0x85, 0xe4, 0xd5, 0x38, 0x8e, 0x12, 0xbb, 0xef, 0x7a, + 0xe2, 0x86, 0x26, 0x92, 0x7b, 0x54, 0xc4, 0x74, 0x2f, 0xa7, 0xe4, 0xa7, 0x54, 0xc5, 0x70, 0x45, + 0xa5, 0x48, 0x59, 0x7c, 0x82, 0xae, 0xdf, 0xc8, 0x3d, 0xdf, 0x5d, 0x13, 0xaa, 0x23, 0x5d, 0xee, + 0xf5, 0xf8, 0x43, 0xc4, 0x67, 0xe6, 0x2a, 0xd6, 0xb9, 0xb9, 0x3f, 0xdf, 0x52, 0xff, 0x29, 0x57, + 0x5c, 0x47, 0x88, 0xcb, 0xc1, 0x08, 0x40, 0x70, 0xe3, 0xfc, 0x2b, 0x94, 0x6d, 0x39, 0x7f, 0xbb, + 0xde, 0xb8, 0x21, 0xab, 0xd7, 0x55, 0x88, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x52, 0x29, + 0x30, 0xa9, 0xf4, 0x2e, 0xa1, 0x4e, 0x8b, 0x17, 0x84, 0x61, 0x9e, 0x8b, 0xd1, 0x58, 0x84, 0x67, + 0x93, 0x94, 0x52, 0x7a, 0x6f, 0xa1, 0xec, 0x4f, 0xd6, 0xab, 0xaf, 0x48, 0x31, 0x47, 0x19, 0x74, + 0xbd, 0x17, 0xa8, 0x5a, 0xc6, 0x29, 0x11, 0xd1, 0x3b, 0xeb, 0x97, 0xd7, 0x29, 0xba, 0xe5, 0x0f, + 0xc0, 0x82, 0x21, 0x1a, 0x2c, 0x41, 0x21, 0x5f, 0x08, 0xe8, 0xf9, 0x7d, 0xd5, 0x56, 0x4e, 0xb1, + 0x49, 0xde, 0xab, 0x08, 0xf0, 0x45, 0xbb, 0xbc, 0xbe, 0x8d, 0xd1, 0xfc, 0xc7, 0xaa, 0xd8, 0x74, + 0x82, 0x80, 0x0b, 0x72, 0x68, 0xe2, 0x6b, 0x3e, 0x0c, 0x5f, 0x4a, 0xdf, 0x7e, 0x71, 0x27, 0x1b, + 0xc4, 0xe1, 0x17, 0xbd, 0xf1, 0x20, 0xc4, 0x28, 0x30, 0x6f, 0x2e, 0x0e, 0x1a, 0x65, 0xc8, 0xae, + 0xe4, 0x80, 0x15, 0x92, 0xc3, 0x56, 0x61, 0x66, 0xd8, 0xa6, 0x4f, 0x5e, 0x6f, 0x1f, 0x89, 0x07, + 0x25, 0x2b, 0xdd, 0xb0, 0xd6, 0x22, 0x2b, 0xa0, 0x8b, 0x2f, 0x94, 0x95, 0xb8, 0xae, 0x8e, 0xff, + 0x5e, 0xa0, 0xe3, 0x10, 0x72, 0x3f, 0xff, 0x13, 0x84, 0x4e, 0x06, 0x22, 0xed, 0xfe, 0xf8, 0x60, + 0x08, 0x01, 0x41, 0xc2, 0xe2, 0xae, 0x6e, 0x20, 0xe1, 0x79, 0x78, 0x8e, 0x0a, 0xc9, 0xea, 0x58, + 0xdd, 0xcb, 0x36, 0x72, 0x08, 0xa0, 0x53, 0x27, 0xbe, 0x7e, 0x10, 0x89, 0xc7, 0xce, 0xa1, 0x79, + 0x17, 0xf4, 0x17, 0xea, 0xec, 0x9a, 0xaf, 0xbe, 0xee, 0xf8, 0x24, 0xee, 0x20, 0x73, 0xb0, 0xc1, + 0x0c, 0x00, 0xe6, 0xd6, 0xde, 0x3f, 0xf1, 0x6c, 0x5b, 0xc5, 0xb4, 0xdb, 0xc4, 0x05, 0x83, 0x39, + 0x70, 0xb8, 0x2b, 0x2d, 0x88, 0x68, 0x73, 0x43, 0x23, 0x2c, 0xba, 0x5d, 0xcb, 0xa5, 0xd1, 0xfd, + 0x04, 0xa9, 0xd7, 0x92, 0xef, 0xae, 0x8a, 0xf0, 0xcc, 0x21, 0x14, 0x14, 0x97, 0xd3, 0x93, 0xac, + 0xf1, 0x23, 0x04, 0x16, 0xf7, 0xd6, 0x5e, 0x1d, 0xa6, 0x4f, 0x4d, 0xca, 0x2a, 0x8a, 0x28, 0x2c, + 0xc9, 0x8c, 0x12, 0xa6, 0x10, 0x0c, 0x09, 0x88, 0xf9, 0x3b, 0xe4, 0xbf, 0x35, 0x84, 0x6f, 0x82, + 0x40, 0x9e, 0x6c, 0x1c, 0xcc, 0x5a, 0xb3, 0x81, 0xc0, 0x10, 0x04, 0x42, 0x19, 0x70, 0x43, 0x85, + 0xe2, 0xb7, 0xeb, 0xb0, 0xf7, 0x0f, 0x73, 0x5c, 0x0f, 0x00, 0x80, 0x7d, 0xdc, 0xb1, 0x8a, 0x31, + 0x46, 0x58, 0xcf, 0x95, 0x2a, 0xaf, 0x01, 0x00, 0x18, 0x11, 0x12, 0xe1, 0xee, 0x4e, 0xfc, 0xb5, + 0xe0, 0x58, 0x10, 0x6f, 0x17, 0xc0, 0xe0, 0x20, 0xa7, 0xc7, 0x90, 0xbc, 0x08, 0x18, 0x50, 0x5b, + 0x0a, 0xf2, 0x85, 0x62, 0x20, 0x9c, 0x28, 0x2e, 0x24, 0x3d, 0x49, 0x6a, 0x9e, 0x9f, 0xdc, 0x44, + 0x60, 0x83, 0xbf, 0x97, 0xb3, 0xd6, 0x66, 0xf7, 0x5b, 0xf2, 0x7e, 0x10, 0x13, 0x9c, 0xad, 0x57, + 0x83, 0x8d, 0xc0, 0xb0, 0x23, 0x89, 0x0c, 0x0e, 0xf1, 0x58, 0x51, 0x53, 0xc7, 0x96, 0xea, 0x77, + 0xf0, 0x42, 0x23, 0x83, 0x91, 0x00, 0xb4, 0x79, 0xb2, 0xaa, 0xab, 0xb9, 0xc2, 0x37, 0x69, 0xaf, + 0x84, 0x4c, 0x6e, 0x06, 0xc4, 0xbd, 0x88, 0x0c, 0x89, 0x10, 0x4e, 0xad, 0xed, 0x10, 0xc4, 0x91, + 0xc8, 0x1f, 0x47, 0xce, 0xd5, 0x8c, 0x41, 0x5b, 0x44, 0xf4, 0x77, 0xae, 0x63, 0x6a, 0xa6, 0xe8, + 0xb5, 0x0c, 0x44, 0x41, 0x70, 0x4a, 0xb5, 0xbd, 0xfd, 0xc4, 0x49, 0x83, 0xbf, 0x8a, 0xbf, 0x1c, + 0x62, 0xf1, 0x71, 0x75, 0x4d, 0xf5, 0x55, 0xf1, 0x28, 0x2a, 0x9e, 0xf8, 0x27, 0x19, 0x4e, 0xf0, + 0x91, 0xeb, 0x76, 0xa6, 0x5c, 0x10, 0x82, 0x80, 0x80, 0x82, 0xd3, 0xcb, 0xd7, 0x5a, 0xe1, 0x98, + 0x44, 0x00, 0xc0, 0xd2, 0xbd, 0x37, 0x51, 0x3f, 0xff, 0xf4, 0x9c, 0x45, 0xd5, 0x7c, 0x22, 0x11, + 0x14, 0x65, 0xd6, 0xa4, 0xe4, 0x82, 0xb8, 0x66, 0x30, 0x55, 0x56, 0xa5, 0xf7, 0x8e, 0xf8, 0xe7, + 0x9e, 0x3c, 0xb1, 0x9f, 0xdf, 0xc4, 0x82, 0x11, 0x64, 0x0a, 0xdc, 0xe1, 0xef, 0xf7, 0xbe, 0x82, + 0x2d, 0x17, 0xd5, 0xfe, 0xad, 0x2e, 0x10, 0x8b, 0xe8, 0x53, 0x91, 0x70, 0x84, 0x51, 0x1b, 0x3e, + 0x4d, 0xb5, 0x99, 0x46, 0x22, 0x28, 0x54, 0x18, 0xba, 0x4a, 0x27, 0x49, 0x44, 0xe9, 0x28, 0x8e, + 0x9c, 0x14, 0xaf, 0x70, 0x80, 0x84, 0x13, 0xeb, 0xc1, 0x40, 0x48, 0x28, 0x5f, 0x77, 0xad, 0x78, + 0x61, 0x89, 0xa2, 0x39, 0x0d, 0xe0, 0x83, 0xc1, 0x08, 0x81, 0x75, 0xd5, 0x6b, 0xe1, 0x11, 0xc2, + 0x2a, 0xa2, 0xf2, 0xa9, 0x24, 0xd1, 0x6c, 0x04, 0xf1, 0x9c, 0xc9, 0x3f, 0x12, 0x34, 0x68, 0xb1, + 0xf5, 0x5d, 0x55, 0x78, 0x39, 0xc2, 0x23, 0x90, 0xf8, 0xed, 0x0c, 0xc1, 0x08, 0x94, 0x29, 0xc7, + 0x8c, 0x18, 0xee, 0x2b, 0x76, 0xe3, 0x6d, 0x32, 0xfb, 0x4f, 0x27, 0xaf, 0x12, 0x28, 0x8f, 0x7b, + 0xdf, 0xc2, 0x35, 0x06, 0x11, 0x43, 0xed, 0xd7, 0x4d, 0xf8, 0x21, 0x1c, 0x10, 0x88, 0x7e, 0x2b, + 0x77, 0xea, 0xb8, 0x42, 0xc2, 0x24, 0xc6, 0x21, 0xe5, 0xbc, 0x48, 0x44, 0xc2, 0xb1, 0x95, 0x48, + 0x0c, 0x4b, 0x13, 0x10, 0x65, 0x58, 0xba, 0xd5, 0xf1, 0x22, 0x01, 0x08, 0xb1, 0xbe, 0xe2, 0x77, + 0x82, 0xdc, 0x4f, 0xc8, 0x67, 0x77, 0xf1, 0x02, 0xee, 0xaf, 0xd2, 0x5c, 0x22, 0x11, 0x16, 0x27, + 0x26, 0x25, 0x97, 0x04, 0x39, 0xc4, 0xa1, 0x0d, 0xe1, 0x91, 0x37, 0x6b, 0xd5, 0x71, 0x22, 0x46, + 0x75, 0x55, 0x55, 0xd6, 0xaa, 0xc4, 0x13, 0x1f, 0x52, 0xf1, 0x31, 0x15, 0x51, 0xa4, 0xc6, 0xcc, + 0xff, 0x0d, 0x84, 0xe3, 0xac, 0xcf, 0x1e, 0x9d, 0x7a, 0x73, 0xec, 0x2d, 0xd0, 0x99, 0x42, 0xe3, + 0x11, 0x02, 0x3d, 0x4f, 0xe6, 0x5c, 0x22, 0x11, 0x0a, 0x07, 0x68, 0x4d, 0xf5, 0x36, 0x62, 0x78, + 0x24, 0xe6, 0x19, 0x08, 0x82, 0xb2, 0xaa, 0xaa, 0xd4, 0x49, 0xc7, 0x64, 0xac, 0x5d, 0xbc, 0x32, + 0x14, 0x88, 0x0e, 0x08, 0xf1, 0x1c, 0x88, 0x2a, 0xda, 0x8b, 0x80, 0xac, 0xb7, 0xd9, 0xf9, 0xf1, + 0xe4, 0x1c, 0x4b, 0x80, 0xef, 0x8d, 0xc3, 0x11, 0x71, 0x20, 0xf1, 0x41, 0xd6, 0x6c, 0x14, 0x67, + 0xe5, 0x51, 0x54, 0x79, 0xce, 0x24, 0x59, 0x29, 0x1b, 0x2a, 0xa9, 0xf3, 0xf3, 0x12, 0xa2, 0x1c, + 0xf8, 0x91, 0x3a, 0x4e, 0xe7, 0xcf, 0x50, 0x62, 0x27, 0x83, 0x1c, 0x21, 0xd0, 0x5c, 0x76, 0x86, + 0xf8, 0x27, 0x1d, 0x45, 0x13, 0xe9, 0xb7, 0x1f, 0x31, 0x70, 0x60, 0x0e, 0x42, 0x52, 0xe2, 0x23, + 0x79, 0x15, 0x9f, 0x8a, 0x32, 0xde, 0x24, 0x32, 0xc8, 0x25, 0xcb, 0xf8, 0x40, 0x22, 0x3b, 0x8b, + 0xad, 0x53, 0xaa, 0xfc, 0x22, 0x30, 0xb1, 0x6e, 0x5c, 0xb8, 0x51, 0x52, 0xdb, 0xdf, 0x51, 0xf1, + 0x67, 0x82, 0x91, 0x64, 0xd5, 0xee, 0xef, 0xc4, 0x84, 0x0a, 0x2e, 0x2f, 0x79, 0xf3, 0x69, 0xe2, + 0xbc, 0x23, 0x18, 0x2b, 0x55, 0x5a, 0xe2, 0xf3, 0x7c, 0x9e, 0xa0, 0xc4, 0x4c, 0x13, 0xf4, 0x1d, + 0x79, 0xa0, 0x80, 0x1c, 0x84, 0x83, 0x0e, 0xef, 0xbb, 0xf0, 0xc0, 0x97, 0x15, 0xc5, 0x7c, 0x40, + 0x90, 0x46, 0x77, 0xd5, 0xcf, 0x13, 0x86, 0x88, 0x60, 0xa5, 0x07, 0xff, 0xf6, 0xfb, 0x82, 0x91, + 0x23, 0x84, 0xc5, 0x7b, 0xbe, 0x94, 0x56, 0x2b, 0xc4, 0xc5, 0x15, 0xdd, 0xde, 0xf7, 0xe2, 0x06, + 0x0c, 0xdd, 0xc2, 0xc6, 0x96, 0x7f, 0xee, 0xef, 0xac, 0x8c, 0xab, 0x3f, 0x08, 0x41, 0x76, 0x20, + 0x61, 0x2b, 0x51, 0x71, 0x20, 0x72, 0x4b, 0x89, 0xf8, 0x9f, 0x5a, 0x45, 0xe9, 0xe1, 0x18, 0x40, + 0xb7, 0x07, 0x56, 0x32, 0xaa, 0x33, 0xc2, 0xc0, 0xf2, 0x24, 0x2c, 0x22, 0xd2, 0x15, 0x8a, 0xc7, + 0x11, 0x60, 0x58, 0x65, 0x46, 0x11, 0x12, 0x30, 0xae, 0xe2, 0xb1, 0x5d, 0xdd, 0xee, 0xdc, 0x6c, + 0x5f, 0x85, 0x05, 0x70, 0x84, 0xdb, 0x4a, 0xb8, 0x10, 0x01, 0x48, 0xfc, 0xf9, 0x9f, 0x2a, 0xab, + 0x96, 0xad, 0x12, 0x9f, 0x62, 0x01, 0x08, 0x26, 0xaa, 0xae, 0xe3, 0x8a, 0xc6, 0xbb, 0x84, 0x43, + 0x22, 0xca, 0xef, 0xee, 0xfc, 0x48, 0xf9, 0xff, 0x93, 0xf4, 0xe6, 0xae, 0x24, 0x20, 0xc5, 0x28, + 0x8f, 0xa8, 0x2d, 0xc4, 0x98, 0x7d, 0xcd, 0x95, 0x78, 0x27, 0x18, 0xa5, 0xe9, 0x9c, 0x3e, 0x28, + 0xee, 0xd8, 0x6f, 0x03, 0x0e, 0xa0, 0xcf, 0x36, 0x06, 0xbc, 0x6d, 0xb5, 0xf1, 0xd3, 0x14, 0xb9, + 0x1e, 0xb8, 0x39, 0x5c, 0x7a, 0xe2, 0xe0, 0xed, 0xd7, 0x2a, 0x32, 0x95, 0x1d, 0x5d, 0xc6, 0x4c, + 0x7e, 0x6f, 0xb7, 0xfc, 0x14, 0x90, 0xc0, 0x31, 0xc2, 0x26, 0x35, 0x5e, 0x47, 0x91, 0xa5, 0x8c, + 0x6a, 0x37, 0x7e, 0xfd, 0x5c, 0xf7, 0xe2, 0x44, 0x04, 0x4f, 0xbb, 0xaa, 0x6a, 0x9b, 0xba, 0x6f, + 0xc0, 0xf0, 0x32, 0x4c, 0x48, 0x78, 0xf0, 0x39, 0xc3, 0x51, 0x72, 0xc3, 0x1f, 0xe3, 0x30, 0x9c, + 0x54, 0xa8, 0xbf, 0x1e, 0xf3, 0xfc, 0x71, 0x3c, 0x3c, 0x70, 0xbe, 0x61, 0xac, 0x03, 0x51, 0x5c, + 0x8b, 0x1c, 0xed, 0xff, 0xa6, 0xd8, 0xab, 0x4c, 0xbc, 0x55, 0x96, 0xb4, 0xca, 0x15, 0x67, 0x00, + 0x80, 0x2e, 0x24, 0x1a, 0x27, 0xbd, 0x3b, 0xbe, 0x5d, 0xc5, 0x5b, 0xff, 0x08, 0x96, 0xee, 0xfe, + 0x10, 0x04, 0xe6, 0x94, 0x83, 0x0d, 0x0c, 0x9b, 0xbd, 0x70, 0x80, 0x41, 0x13, 0xa0, 0xb2, 0x10, + 0x0c, 0x94, 0x4d, 0xdc, 0xbf, 0x10, 0x24, 0x9b, 0xab, 0xe2, 0x43, 0x23, 0x08, 0x2b, 0x14, 0x65, + 0xc2, 0xc6, 0x70, 0x2c, 0x3a, 0x05, 0x5d, 0x71, 0x46, 0x15, 0x1c, 0x85, 0x1d, 0x29, 0xaa, 0xe2, + 0x62, 0xae, 0xfa, 0xaa, 0x4b, 0x84, 0x44, 0x82, 0x2d, 0xee, 0xfc, 0x40, 0x12, 0x44, 0x6b, 0xdb, + 0xcd, 0xeb, 0xc1, 0x03, 0x3e, 0xc6, 0xbc, 0x48, 0x21, 0x7b, 0xbd, 0x42, 0x21, 0x92, 0x1e, 0x7b, + 0xf1, 0x01, 0x01, 0x82, 0xa2, 0xb8, 0xae, 0xc4, 0x2b, 0xae, 0xa2, 0xb7, 0x2f, 0x6e, 0x61, 0x00, + 0x87, 0xc1, 0x18, 0xdc, 0x6d, 0x7e, 0x82, 0x88, 0x8f, 0x13, 0x16, 0x31, 0xdc, 0x57, 0x7b, 0xfc, + 0x49, 0x5e, 0xef, 0x77, 0x7c, 0x22, 0x20, 0x84, 0xbb, 0xbf, 0x12, 0x3c, 0x80, 0xd7, 0x58, 0x53, + 0x06, 0xab, 0x2a, 0x43, 0xec, 0x35, 0x91, 0xaa, 0xb4, 0x9f, 0xc4, 0x8c, 0xdd, 0xd9, 0xbb, 0xb4, + 0x0d, 0x57, 0x99, 0xbb, 0xe5, 0xfc, 0x20, 0x20, 0xeb, 0xbe, 0x9b, 0xe2, 0x6e, 0xf7, 0x78, 0xb6, + 0x2c, 0x35, 0xa8, 0x7c, 0x6a, 0x28, 0x4e, 0x95, 0xd2, 0xaa, 0x84, 0x3c, 0x48, 0x21, 0x14, 0x32, + 0x2b, 0x8a, 0xe5, 0x55, 0x7c, 0x40, 0x40, 0x49, 0x25, 0x61, 0xf2, 0xdb, 0x9b, 0x6f, 0x08, 0x04, + 0x38, 0x80, 0x81, 0x78, 0x1f, 0xcd, 0x18, 0x25, 0xe6, 0x3e, 0xab, 0x88, 0xf1, 0x31, 0xc2, 0x24, + 0xd7, 0xdd, 0xdd, 0xdd, 0xfc, 0x20, 0x0a, 0x78, 0x9f, 0x12, 0x24, 0xd5, 0xaa, 0xf9, 0x3c, 0xd4, + 0xe1, 0x01, 0x33, 0x29, 0xd8, 0xcc, 0xca, 0x64, 0x66, 0xf0, 0x50, 0x24, 0x6e, 0xaa, 0xaa, 0xab, + 0xc4, 0x04, 0xaa, 0xbe, 0xef, 0x11, 0x28, 0x25, 0x65, 0x5a, 0x34, 0x40, 0x43, 0x86, 0x7f, 0x04, + 0x7d, 0xdf, 0xa0, 0x87, 0x10, 0x84, 0x77, 0x88, 0x46, 0xee, 0x23, 0xc4, 0x84, 0x6a, 0x22, 0x8b, + 0x7e, 0x11, 0x08, 0x82, 0xc2, 0x5b, 0x49, 0xeb, 0x17, 0x73, 0xf3, 0x60, 0x2a, 0x29, 0x7d, 0xab, + 0x84, 0x01, 0x48, 0x50, 0xd1, 0x5c, 0x40, 0xf1, 0x46, 0x0c, 0x64, 0xc0, 0xf0, 0x78, 0x73, 0x11, + 0xc5, 0x26, 0x55, 0x92, 0xbe, 0x3d, 0xe0, 0xe9, 0xe0, 0xe2, 0xf9, 0x23, 0xe1, 0xd3, 0xf5, 0xe2, + 0x41, 0x5d, 0x4d, 0x31, 0xd5, 0x8a, 0x70, 0x60, 0x7f, 0x03, 0x87, 0xba, 0x9d, 0xca, 0x8f, 0x66, + 0xdd, 0x7a, 0xc3, 0x0c, 0x6a, 0xaf, 0xc2, 0x3e, 0x19, 0xe2, 0x42, 0x3c, 0x48, 0x44, 0xa5, 0x4d, + 0xd3, 0x92, 0x10, 0xe1, 0x45, 0x00, 0x08, 0xad, 0xae, 0xed, 0x58, 0x5e, 0x98, 0x39, 0xff, 0xff, + 0x88, 0x08, 0x02, 0x11, 0xd3, 0x51, 0x58, 0x41, 0xc3, 0x88, 0x08, 0x41, 0x04, 0x47, 0x88, 0x90, + 0xf5, 0x5f, 0x13, 0xc4, 0xcd, 0x7b, 0xfc, 0x61, 0x37, 0x7b, 0x9f, 0x37, 0x69, 0xfb, 0xbb, 0xe2, + 0x01, 0x0b, 0x3d, 0x6b, 0xc4, 0x82, 0x4d, 0x4d, 0xc9, 0x4a, 0x0a, 0xe1, 0x91, 0x01, 0x11, 0x0a, + 0xc9, 0x74, 0x17, 0x55, 0x93, 0xbe, 0xea, 0x79, 0xf6, 0xf8, 0x21, 0x0a, 0x4f, 0xd0, 0x9c, 0xb4, + 0x4c, 0xcd, 0x42, 0xe2, 0x43, 0xcb, 0xf1, 0x5a, 0x4e, 0xe2, 0xb7, 0xfc, 0xb8, 0x44, 0x22, 0x38, + 0x83, 0xa0, 0x3c, 0x27, 0x07, 0x05, 0xe3, 0xab, 0x1b, 0xa4, 0xc0, 0xe1, 0xf9, 0x6c, 0xc9, 0xd7, + 0x13, 0x08, 0x17, 0x85, 0x15, 0x6e, 0x12, 0xb9, 0x13, 0xab, 0xf2, 0xaa, 0x9f, 0x12, 0x51, 0x3b, + 0xbe, 0x10, 0x08, 0x70, 0xc8, 0x20, 0xf8, 0x40, 0xb6, 0x6b, 0xaa, 0xd5, 0x35, 0xf9, 0xaa, 0xb9, + 0x61, 0x00, 0x87, 0x08, 0x84, 0x38, 0x88, 0x2a, 0x14, 0xab, 0xd2, 0x88, 0x79, 0xb3, 0x55, 0xc3, + 0x84, 0x65, 0xab, 0xaa, 0x87, 0xfa, 0x2e, 0x5e, 0x22, 0xb1, 0x0f, 0x7b, 0xf8, 0xa3, 0x3b, 0xbb, + 0xde, 0xea, 0x11, 0x89, 0x12, 0xf7, 0xbb, 0x8a, 0xc5, 0x78, 0x98, 0xcc, 0xfe, 0x7d, 0xb6, 0x6c, + 0x94, 0x32, 0xf8, 0xb9, 0x7a, 0x46, 0x64, 0xe0, 0x7e, 0x10, 0x8c, 0x93, 0x96, 0xd9, 0xcb, 0x65, + 0xef, 0xfd, 0x4a, 0xbf, 0x96, 0x0e, 0xb5, 0x2f, 0x5b, 0xc2, 0x22, 0x02, 0x06, 0xab, 0xcb, 0x6e, + 0xef, 0x57, 0xe2, 0x23, 0x0e, 0xa2, 0xea, 0xb5, 0x8b, 0xaa, 0x77, 0x15, 0xf8, 0x4f, 0x1c, 0xf7, + 0xbf, 0xff, 0xc1, 0x80, 0x10, 0x45, 0x54, 0x5d, 0x45, 0xeb, 0x58, 0x84, 0x50, 0x0f, 0xf6, 0x11, + 0xef, 0x08, 0xea, 0x11, 0x13, 0xf1, 0x25, 0x55, 0x55, 0xad, 0x50, 0xa7, 0xe0, 0x83, 0xf2, 0x92, + 0xaa, 0xbc, 0x21, 0xe2, 0x38, 0x9c, 0x3b, 0x11, 0x93, 0x8e, 0xdc, 0x56, 0xee, 0xfd, 0xef, 0x09, + 0xb1, 0x81, 0xb3, 0xb9, 0xff, 0xeb, 0xf8, 0x20, 0x0c, 0x18, 0xf7, 0x71, 0x5c, 0x52, 0x81, 0xf0, + 0x1f, 0x61, 0x90, 0x88, 0xcb, 0x8b, 0xd4, 0xf3, 0x44, 0x0a, 0x91, 0x96, 0x37, 0x64, 0x7f, 0x18, + 0xac, 0x51, 0x8a, 0xc5, 0x1e, 0x20, 0x32, 0x26, 0x5b, 0x71, 0x2f, 0xcb, 0x77, 0x7c, 0x22, 0x19, + 0xc2, 0x8c, 0xa0, 0x62, 0xc2, 0x53, 0x6d, 0xbf, 0xff, 0xc0, 0xd2, 0x01, 0x60, 0x08, 0x71, 0x78, + 0xb8, 0xb9, 0x32, 0x56, 0xab, 0x12, 0x8a, 0x02, 0x76, 0x8e, 0xa2, 0xc4, 0x81, 0xa4, 0x45, 0x57, + 0x55, 0x55, 0x36, 0x10, 0xe1, 0x0f, 0x07, 0x11, 0x82, 0xd4, 0x47, 0x0d, 0x98, 0xb8, 0xba, 0xac, + 0x98, 0xb3, 0x2a, 0xab, 0xe0, 0x98, 0x55, 0x55, 0x6a, 0xab, 0xd5, 0xd9, 0x95, 0x6b, 0xe8, 0x95, + 0x0e, 0x73, 0x4f, 0xf9, 0x70, 0xc8, 0x82, 0x55, 0xf7, 0xbc, 0x51, 0x04, 0x80, 0x2d, 0xe8, 0x76, + 0x47, 0x46, 0xb8, 0x02, 0xf5, 0xc1, 0x70, 0x6b, 0x84, 0x44, 0x0e, 0x9f, 0x9c, 0xfb, 0x96, 0x31, + 0x58, 0xad, 0xed, 0x57, 0x86, 0x3e, 0x4a, 0xaf, 0x1c, 0x8e, 0x01, 0xf5, 0xb4, 0x3f, 0x03, 0xc0, + 0x0e, 0x92, 0x6b, 0x59, 0xd8, 0x90, 0x5b, 0x74, 0x30, 0xc4, 0x00, 0x1f, 0xaf, 0xd1, 0x30, 0x1f, + 0xfd, 0x3e, 0xb5, 0xc3, 0x3a, 0x84, 0x42, 0x13, 0x42, 0x21, 0x17, 0x55, 0xaf, 0x0c, 0x70, 0x80, + 0x60, 0xd9, 0x7d, 0xfc, 0x10, 0x8a, 0x7b, 0x53, 0x03, 0xe0, 0x8e, 0xef, 0x70, 0x57, 0xc3, 0x7c, + 0x11, 0xde, 0xfd, 0xfe, 0x08, 0x4b, 0x55, 0xbd, 0xf3, 0x79, 0x7f, 0x08, 0x94, 0x45, 0xb7, 0xf0, + 0x8b, 0x12, 0xef, 0x7c, 0x22, 0x19, 0x04, 0x33, 0xf9, 0xfd, 0xeb, 0x08, 0xf0, 0x88, 0x64, 0xb7, + 0xb7, 0x9c, 0x87, 0x08, 0x91, 0x4d, 0x2c, 0x33, 0x15, 0xad, 0x55, 0x55, 0x62, 0x19, 0x41, 0x4c, + 0x86, 0x19, 0x82, 0x32, 0x2d, 0x57, 0xb8, 0x99, 0xb5, 0xac, 0x52, 0x81, 0x56, 0x47, 0x3c, 0x49, + 0xd5, 0x75, 0xaf, 0x13, 0x2e, 0xad, 0x2a, 0x84, 0x43, 0x37, 0xc9, 0x5d, 0x49, 0xd0, 0x4b, 0x08, + 0x6a, 0x23, 0xc4, 0x84, 0x38, 0x9a, 0x12, 0xff, 0x57, 0xae, 0x6d, 0xef, 0xec, 0x43, 0xee, 0xf0, + 0x40, 0x41, 0x2a, 0xbe, 0x24, 0x14, 0x08, 0xad, 0x75, 0x5e, 0x06, 0x00, 0x40, 0x22, 0x29, 0x8b, + 0xeb, 0x5e, 0x08, 0x7c, 0x20, 0x0a, 0x08, 0x71, 0x71, 0x7a, 0xcf, 0x86, 0xc3, 0xbc, 0x60, 0x51, + 0x03, 0x46, 0x2a, 0x45, 0xc1, 0x8c, 0xdb, 0xbb, 0xaf, 0xc4, 0x68, 0x28, 0x43, 0x83, 0x5d, 0x7f, + 0xf4, 0xd3, 0x79, 0x7a, 0x78, 0x40, 0x4f, 0x84, 0x4d, 0x9f, 0xe5, 0xc4, 0x45, 0x74, 0x23, 0x28, + 0xfc, 0x21, 0x58, 0x8e, 0x27, 0x78, 0x8f, 0x0c, 0x70, 0x85, 0x5f, 0x84, 0x02, 0x02, 0xca, 0xaa, + 0xaa, 0xaa, 0xab, 0x84, 0x66, 0x26, 0xab, 0x83, 0x9a, 0xb7, 0x03, 0x08, 0x40, 0x50, 0x91, 0x71, + 0x73, 0x72, 0xce, 0x2f, 0x37, 0x88, 0x50, 0x2a, 0xac, 0xe6, 0x20, 0x0c, 0x3f, 0x04, 0x84, 0xdc, + 0x57, 0xde, 0x23, 0x82, 0x8b, 0x22, 0xd5, 0x71, 0x02, 0x2b, 0x08, 0x71, 0x21, 0x0b, 0x12, 0xc5, + 0x80, 0x97, 0x76, 0x6a, 0xae, 0x11, 0xac, 0x31, 0xe1, 0x08, 0x67, 0x08, 0x4f, 0x11, 0xf9, 0x87, + 0x5d, 0xf8, 0x91, 0x1c, 0x20, 0x27, 0x0b, 0x44, 0x85, 0x76, 0x37, 0xb7, 0xff, 0xac, 0x2e, 0xa0, + 0x0f, 0x7e, 0xd0, 0x77, 0xfb, 0xbb, 0xbd, 0xee, 0xff, 0x1f, 0xbd, 0xde, 0xb7, 0xbb, 0xbb, 0xc5, + 0x69, 0xf8, 0xbd, 0xdc, 0x56, 0xf7, 0xe0, 0x68, 0x05, 0x3e, 0x27, 0x84, 0x04, 0x57, 0x2d, 0x57, + 0x78, 0x8c, 0x56, 0x12, 0x36, 0x6f, 0x10, 0x10, 0xe2, 0x03, 0x15, 0x08, 0x78, 0x8d, 0xe2, 0x01, + 0x18, 0xa4, 0xeb, 0x68, 0x57, 0x10, 0x09, 0x09, 0x37, 0xf2, 0xfb, 0xbb, 0x65, 0x49, 0xac, 0x4d, + 0x44, 0xe4, 0x84, 0x3c, 0x48, 0x40, 0x49, 0xf7, 0x49, 0xf7, 0xe2, 0x7c, 0x33, 0xc4, 0x82, 0x16, + 0x75, 0xaa, 0xf0, 0x52, 0x22, 0x46, 0x08, 0xc7, 0x35, 0xf0, 0x53, 0xc4, 0x06, 0x38, 0x80, 0x87, + 0x88, 0x9b, 0x8b, 0x2a, 0xd5, 0x56, 0xb7, 0x08, 0x04, 0x3c, 0x45, 0xc2, 0x01, 0x0e, 0x10, 0x08, + 0x78, 0x91, 0x61, 0x0a, 0xad, 0xad, 0xc2, 0x9c, 0xc2, 0x78, 0x9f, 0xf1, 0x22, 0x2b, 0x5d, 0x53, + 0xe2, 0x51, 0x5f, 0xe6, 0xbd, 0xeb, 0x98, 0xaf, 0x7f, 0x08, 0x18, 0x46, 0x20, 0x70, 0xfd, 0x44, + 0x09, 0xfd, 0x62, 0x7c, 0x20, 0xc4, 0xbb, 0x7e, 0x24, 0x10, 0x0b, 0xbd, 0xdd, 0xdd, 0xdf, 0x10, + 0x08, 0x0b, 0x7b, 0xbc, 0x52, 0x9a, 0x9c, 0x41, 0x6f, 0x77, 0xe2, 0x38, 0x81, 0x12, 0xe1, 0x93, + 0x09, 0x54, 0xfe, 0x11, 0xf9, 0x49, 0xc5, 0x6a, 0x23, 0x3c, 0x20, 0x18, 0xf0, 0x8c, 0x44, 0x00, + 0x00, 0x00, 0x01, 0x41, 0x9a, 0x53, 0x29, 0xb0, 0xa8, 0x2f, 0xd0, 0xfc, 0xbc, 0x42, 0xf6, 0x1d, + 0x84, 0x80, 0x03, 0x94, 0x64, 0x8d, 0xa0, 0x0d, 0x58, 0x27, 0x9f, 0xe2, 0x5e, 0x24, 0xd0, 0x56, + 0x71, 0xe2, 0x31, 0x19, 0xe5, 0x18, 0x1e, 0x7c, 0x42, 0x34, 0x20, 0x89, 0x62, 0x3c, 0xbf, 0x3f, + 0x37, 0xc1, 0x0c, 0xa1, 0x3d, 0xde, 0x23, 0xac, 0x5f, 0x2d, 0xdf, 0x1d, 0xd7, 0xa2, 0xfa, 0xb7, + 0xcb, 0x5a, 0xa9, 0x7a, 0xbc, 0xfd, 0x7a, 0xba, 0xf4, 0x81, 0xe6, 0x14, 0x00, 0x0e, 0xb4, 0x5b, + 0x5b, 0x09, 0x9d, 0x01, 0xc7, 0x9d, 0x90, 0x38, 0x78, 0x9f, 0x2d, 0xdd, 0xee, 0xf5, 0xb8, 0x3b, + 0x70, 0x7b, 0x37, 0xae, 0xef, 0x81, 0x80, 0x02, 0x00, 0x14, 0x9e, 0xe0, 0xac, 0x99, 0xba, 0x95, + 0xf9, 0xde, 0xdc, 0xaa, 0xe9, 0xc9, 0xee, 0x5b, 0xb9, 0x58, 0xba, 0x3b, 0x30, 0xb4, 0x17, 0x0d, + 0xf8, 0x62, 0x9f, 0x0e, 0x1b, 0x55, 0x0f, 0x73, 0x2e, 0x2d, 0xfc, 0x36, 0x41, 0xc0, 0x01, 0x3b, + 0x8c, 0x14, 0x8d, 0xc2, 0xa4, 0xe2, 0x0f, 0xdf, 0xd3, 0xc9, 0xc1, 0xf7, 0x07, 0xdc, 0x7d, 0xc7, + 0xae, 0xce, 0x1e, 0x38, 0x6e, 0x2d, 0x34, 0xf6, 0xdb, 0xc3, 0x78, 0x01, 0x71, 0x34, 0x75, 0x04, + 0x30, 0x25, 0xfe, 0xbd, 0x8b, 0x65, 0xfe, 0x5d, 0x9c, 0x0f, 0xc5, 0x07, 0xe2, 0x32, 0x2a, 0x4e, + 0xfd, 0x65, 0xe8, 0x27, 0xdf, 0x5e, 0xfa, 0xf4, 0xdd, 0x7a, 0x61, 0xca, 0x5c, 0x8a, 0x18, 0xe6, + 0x25, 0x6b, 0x81, 0x20, 0x02, 0x00, 0x14, 0x1d, 0x0a, 0x00, 0xd2, 0x48, 0x0d, 0x16, 0xdd, 0x44, + 0x00, 0x04, 0x54, 0x2d, 0x60, 0xf6, 0x83, 0x59, 0x2c, 0x6d, 0xbb, 0x62, 0xe1, 0xea, 0x46, 0x32, + 0x4f, 0x36, 0x71, 0x00, 0x84, 0x64, 0xf0, 0x70, 0xf6, 0x19, 0x7e, 0xe1, 0x40, 0x15, 0x7f, 0x56, + 0xa7, 0xd9, 0x2d, 0x0f, 0xbd, 0x83, 0x80, 0x01, 0xc2, 0x88, 0xd4, 0xe0, 0x01, 0xe2, 0x82, 0x03, + 0x50, 0xd0, 0x50, 0x18, 0x04, 0x87, 0x51, 0x26, 0x02, 0x43, 0xce, 0x3a, 0x07, 0xa3, 0x02, 0x55, + 0x0f, 0x10, 0x50, 0x00, 0x67, 0x1c, 0xc0, 0x4b, 0xc4, 0x8d, 0x0a, 0x78, 0x4f, 0xff, 0xdb, 0x30, + 0x7a, 0xe4, 0xe3, 0xee, 0x3e, 0xe3, 0xee, 0x77, 0xb3, 0x9d, 0xec, 0xec, 0xec, 0xec, 0xec, 0xe3, + 0x01, 0x01, 0xa1, 0x04, 0xff, 0xc3, 0x0c, 0xa0, 0x0a, 0x51, 0x03, 0x89, 0x1b, 0x83, 0xa8, 0x25, + 0x7d, 0x33, 0x5b, 0x65, 0xac, 0xb5, 0x8a, 0xb1, 0x57, 0xfb, 0x6d, 0xb7, 0xd8, 0x5c, 0x84, 0x00, + 0x60, 0x01, 0xb2, 0x47, 0x17, 0x3d, 0xef, 0x7b, 0xde, 0xf4, 0xb2, 0x74, 0x19, 0xe8, 0x27, 0xe0, + 0x8a, 0xab, 0x96, 0xf8, 0x50, 0x2c, 0xda, 0x72, 0xb1, 0x21, 0x29, 0x87, 0x50, 0xea, 0x51, 0x02, + 0xc3, 0x9c, 0x0b, 0x0d, 0xc9, 0x57, 0x41, 0x35, 0xc4, 0x03, 0x00, 0xa6, 0xa9, 0x03, 0xf4, 0x2d, + 0x03, 0xe4, 0x42, 0x5a, 0x1c, 0x00, 0xa8, 0x38, 0x79, 0x60, 0x0c, 0xe6, 0x07, 0x8e, 0x14, 0x02, + 0xa4, 0x12, 0xc0, 0x06, 0x50, 0x2e, 0xa5, 0x80, 0x03, 0x3c, 0x7d, 0x9e, 0x3e, 0xe6, 0xe1, 0x08, + 0x26, 0x39, 0xfc, 0xf7, 0xd5, 0xd5, 0xb2, 0x9f, 0x48, 0x1a, 0x20, 0x90, 0x23, 0xdc, 0x96, 0xbf, + 0xff, 0xbb, 0x70, 0x15, 0x00, 0x30, 0x02, 0x83, 0x85, 0x6d, 0x8a, 0xcd, 0xe3, 0x29, 0x03, 0x52, + 0x93, 0x53, 0x80, 0x00, 0xaf, 0x06, 0xb2, 0x9d, 0xe1, 0x71, 0xc0, 0x15, 0x22, 0x18, 0x09, 0x4a, + 0xc3, 0x62, 0x98, 0x00, 0x0b, 0xc8, 0xed, 0x26, 0x01, 0x50, 0x08, 0x10, 0x14, 0xe1, 0x80, 0x24, + 0x02, 0x9d, 0x44, 0xa3, 0x51, 0xc1, 0xf5, 0x1c, 0x00, 0xf3, 0xc0, 0x01, 0xc3, 0xc7, 0x0b, 0x06, + 0x70, 0x7b, 0x39, 0x7e, 0xd8, 0x5d, 0x89, 0x00, 0x74, 0x15, 0x8a, 0x72, 0x47, 0x7f, 0xbe, 0xee, + 0xee, 0xe3, 0xec, 0x2e, 0x41, 0x00, 0x05, 0x16, 0xb0, 0xdc, 0xa3, 0x1d, 0xd7, 0xad, 0xbb, 0x7e, + 0xf1, 0x5a, 0xad, 0x6e, 0x82, 0x2e, 0x82, 0xb1, 0x4b, 0x88, 0x58, 0xab, 0xab, 0xfd, 0x7b, 0xc2, + 0x18, 0x5d, 0x85, 0x00, 0x1d, 0x60, 0xa4, 0x52, 0x7a, 0x65, 0xb2, 0xfc, 0xaf, 0x95, 0xff, 0x7c, + 0x3b, 0x80, 0x5b, 0x8d, 0x1b, 0xe0, 0x14, 0xae, 0x1c, 0x7b, 0xfc, 0x24, 0x07, 0x14, 0x9b, 0x02, + 0x67, 0x07, 0x9f, 0x9e, 0x79, 0x21, 0x38, 0x7a, 0xa2, 0x1f, 0x17, 0x97, 0xd2, 0x12, 0x7b, 0xfd, + 0x7e, 0x10, 0x07, 0x01, 0x08, 0x3a, 0xba, 0x1d, 0x71, 0x09, 0x04, 0xa4, 0x13, 0xdf, 0x6e, 0xef, + 0x24, 0x0e, 0x00, 0x32, 0x06, 0x94, 0x51, 0x8a, 0xc5, 0x62, 0xb1, 0x58, 0x35, 0x25, 0x6d, 0x98, + 0x28, 0xc5, 0x62, 0x8c, 0x1d, 0x3e, 0xe6, 0x7c, 0xe9, 0xb5, 0x79, 0xe4, 0x11, 0x1b, 0x59, 0xf6, + 0xf1, 0x5c, 0x34, 0xcc, 0x06, 0xc2, 0xac, 0xb5, 0xc8, 0x12, 0x92, 0xf1, 0x0b, 0xef, 0xfb, 0xfc, + 0xfe, 0x3e, 0x7e, 0x25, 0xe7, 0xbc, 0xf7, 0x9e, 0xfc, 0xce, 0x0e, 0x01, 0x08, 0x2c, 0x1b, 0x69, + 0x45, 0xee, 0xef, 0x17, 0x8b, 0xfb, 0x0b, 0x38, 0x11, 0x92, 0x17, 0x9f, 0x9f, 0xff, 0x2c, 0x25, + 0x86, 0x01, 0x10, 0x00, 0x84, 0x05, 0x05, 0x03, 0x8f, 0x95, 0x05, 0xc2, 0xa5, 0x69, 0x05, 0xed, + 0xc6, 0xfe, 0x4e, 0x31, 0xc4, 0x3f, 0x6e, 0xee, 0xf7, 0xc6, 0xc3, 0x21, 0xef, 0x06, 0xdc, 0x4b, + 0x61, 0x2e, 0x88, 0xfe, 0x21, 0x7a, 0x23, 0xa2, 0x3f, 0xd6, 0xbe, 0xaf, 0x5c, 0x85, 0x55, 0xcb, + 0x11, 0x53, 0xa4, 0xe1, 0xe6, 0x14, 0x01, 0x52, 0x90, 0xa2, 0xd0, 0x96, 0x0a, 0xeb, 0xff, 0x7b, + 0xe8, 0x9e, 0xf7, 0xfc, 0x3c, 0xe0, 0x03, 0xe7, 0x05, 0x4a, 0x24, 0xc3, 0xc8, 0x7f, 0xe9, 0x97, + 0x55, 0x0b, 0x0e, 0x0f, 0x0f, 0x38, 0x07, 0x9e, 0x1e, 0xaa, 0xaa, 0x70, 0x30, 0x3f, 0x03, 0x98, + 0x52, 0x5f, 0xad, 0x70, 0x80, 0x38, 0x19, 0x3c, 0x7e, 0x78, 0xf7, 0x7b, 0xcf, 0x1e, 0x5b, 0x38, + 0x54, 0x16, 0x0c, 0x51, 0xb8, 0x80, 0x16, 0x2f, 0xca, 0x15, 0x5a, 0xd0, 0xe5, 0x43, 0xef, 0x08, + 0x8c, 0x0b, 0x0a, 0xec, 0x57, 0x27, 0x17, 0x41, 0x60, 0xdf, 0x87, 0xb4, 0x3b, 0x11, 0x71, 0x21, + 0xcc, 0x39, 0xe9, 0xc0, 0x60, 0x01, 0x04, 0x15, 0x8f, 0x07, 0xde, 0xdd, 0x98, 0xa7, 0x17, 0xd5, + 0xe9, 0x02, 0x39, 0x90, 0x10, 0xd8, 0x96, 0xd2, 0xf6, 0x1a, 0x46, 0x00, 0x1a, 0xab, 0x30, 0xc9, + 0x3b, 0xc3, 0xdc, 0xf7, 0xc5, 0x70, 0xc8, 0x0f, 0xbd, 0x4d, 0x10, 0x34, 0xca, 0x58, 0x00, 0x3d, + 0x71, 0x20, 0x84, 0x28, 0x74, 0x34, 0x18, 0xcb, 0xeb, 0x05, 0xbb, 0x77, 0x73, 0xd9, 0xd8, 0x12, + 0x3e, 0xed, 0xdd, 0xc7, 0xc7, 0x70, 0xe1, 0x06, 0x88, 0x1f, 0xf6, 0xff, 0xff, 0xbd, 0x3f, 0xc0, + 0xd0, 0x08, 0x3e, 0xfa, 0xaf, 0xab, 0x97, 0x84, 0x6b, 0x10, 0xaf, 0x78, 0x84, 0x47, 0x97, 0x11, + 0x30, 0xb6, 0x2f, 0x94, 0x9d, 0x08, 0x8a, 0x20, 0x52, 0x9a, 0x02, 0x43, 0x4c, 0x20, 0x00, 0x68, + 0xea, 0x41, 0x95, 0x15, 0x3e, 0xee, 0xed, 0xdd, 0xb7, 0x9f, 0xef, 0x85, 0xdc, 0x00, 0xd9, 0x72, + 0x58, 0x61, 0x87, 0x15, 0xfe, 0xfa, 0x8a, 0xc5, 0xc5, 0x1f, 0x89, 0x30, 0x38, 0x1e, 0x24, 0x30, + 0x24, 0x01, 0xc1, 0x63, 0xae, 0x20, 0x06, 0x00, 0xf2, 0x16, 0x0d, 0xdf, 0x6e, 0x7f, 0x88, 0x58, + 0x89, 0x7b, 0xbc, 0x40, 0x27, 0x09, 0xc1, 0x8a, 0xa4, 0xa2, 0xa9, 0xae, 0x6f, 0xd8, 0x5d, 0x85, + 0x02, 0x11, 0x24, 0x86, 0xfb, 0xad, 0x75, 0xd6, 0xb5, 0xad, 0x5d, 0x7b, 0x0b, 0xb0, 0x88, 0x04, + 0x2c, 0xbc, 0x55, 0xec, 0xba, 0xde, 0xf5, 0xef, 0x77, 0xc3, 0x53, 0x02, 0x60, 0x46, 0x25, 0x57, + 0xff, 0xf6, 0xfb, 0x0d, 0xb2, 0x00, 0x11, 0x04, 0xdd, 0x43, 0xc1, 0x17, 0xdf, 0x58, 0xbd, 0x6b, + 0x13, 0xe2, 0x5e, 0x2e, 0x97, 0x9f, 0x7b, 0xd6, 0xb0, 0xdb, 0x1e, 0x0b, 0x5a, 0x2a, 0xc1, 0xde, + 0x18, 0xef, 0x0f, 0x8e, 0xf0, 0x96, 0x97, 0xe4, 0x1d, 0x7f, 0xdf, 0x10, 0x42, 0xac, 0x30, 0xa1, + 0xf6, 0x5b, 0xb7, 0xff, 0xef, 0xe1, 0x07, 0xdd, 0xc9, 0xd5, 0xfe, 0x08, 0xae, 0xee, 0xe6, 0x18, + 0x17, 0xbb, 0xbe, 0xb9, 0xab, 0x5f, 0x82, 0x7a, 0xae, 0xab, 0xb3, 0xea, 0x95, 0x13, 0x97, 0xaa, + 0x88, 0xc4, 0x46, 0x72, 0x75, 0x55, 0xd1, 0x2b, 0x88, 0x06, 0x00, 0xa8, 0x54, 0x2c, 0x2b, 0xdf, + 0xdd, 0x53, 0xa7, 0x71, 0xcc, 0x77, 0x0b, 0xa2, 0x00, 0x15, 0x4c, 0x0a, 0x96, 0x50, 0x35, 0x09, + 0x8a, 0xaa, 0xf0, 0x95, 0x12, 0xaa, 0xaa, 0x92, 0x0a, 0x76, 0x0c, 0xf0, 0x14, 0x03, 0x27, 0xee, + 0xff, 0x6a, 0xe9, 0x04, 0x70, 0xb1, 0x63, 0xaf, 0xd9, 0x44, 0x35, 0x39, 0x81, 0xc3, 0xc9, 0x06, + 0xa7, 0xe1, 0x20, 0x0d, 0x3c, 0x11, 0x84, 0x4b, 0x72, 0xde, 0x55, 0xc3, 0x98, 0xae, 0x20, 0x7c, + 0x9b, 0x59, 0xa1, 0xf8, 0x10, 0x00, 0x44, 0x0c, 0x0a, 0x05, 0xc5, 0x4e, 0x15, 0x0d, 0x52, 0xd5, + 0x4f, 0xf3, 0x5a, 0x93, 0x85, 0x4a, 0xee, 0x46, 0x00, 0x14, 0x45, 0xd7, 0x91, 0x7d, 0x70, 0xc4, + 0x78, 0xb5, 0xa7, 0x51, 0x27, 0xa9, 0x66, 0x2e, 0x28, 0x62, 0x7c, 0xb0, 0x38, 0x69, 0xc0, 0x24, + 0x3f, 0xc2, 0x8f, 0xdf, 0xff, 0x11, 0xe9, 0xc3, 0xf7, 0x03, 0x40, 0x0b, 0x80, 0xa0, 0xa1, 0x00, + 0x07, 0x9c, 0x70, 0x28, 0x15, 0x88, 0x9b, 0x2b, 0xee, 0x71, 0xf6, 0xa2, 0xab, 0x77, 0x77, 0x66, + 0x35, 0x85, 0x40, 0xd7, 0x29, 0x06, 0xbb, 0x19, 0x28, 0xc7, 0x8b, 0x3a, 0x8c, 0xc3, 0x8f, 0x24, + 0x5c, 0x20, 0xaf, 0x8e, 0x27, 0xc8, 0xbd, 0x5e, 0x7e, 0xaf, 0xf5, 0x6a, 0xea, 0xdf, 0x56, 0xfa, + 0xbc, 0x77, 0x30, 0xab, 0xaf, 0xd1, 0xdc, 0xae, 0x71, 0x0b, 0xe6, 0xed, 0xb6, 0x6e, 0xfa, 0x3d, + 0x57, 0x2d, 0xdf, 0x2c, 0x14, 0x89, 0x04, 0xe4, 0x88, 0x7c, 0xbe, 0x9d, 0xe0, 0xe1, 0x10, 0x72, + 0x14, 0x19, 0x22, 0x1f, 0x19, 0xcf, 0x2c, 0x01, 0x93, 0x00, 0x0d, 0x0f, 0x01, 0xc2, 0x60, 0x1a, + 0x3d, 0xde, 0xca, 0x9e, 0x86, 0xe7, 0x96, 0x46, 0x90, 0x18, 0x2b, 0x80, 0xb8, 0x19, 0x1d, 0x03, + 0xe4, 0xea, 0x01, 0xd0, 0x7e, 0xf9, 0xa9, 0x51, 0x1a, 0xc9, 0xe3, 0xa7, 0x9c, 0x4f, 0x18, 0x85, + 0x8c, 0x22, 0x02, 0x00, 0x4e, 0xf7, 0x21, 0x0d, 0x9c, 0xfb, 0x41, 0xb2, 0x09, 0x00, 0x74, 0x9b, + 0x80, 0xbb, 0x3b, 0xf5, 0xf8, 0xb8, 0x9c, 0x11, 0x96, 0x60, 0xde, 0x22, 0xb5, 0xad, 0xef, 0x0b, + 0xc4, 0x00, 0x24, 0xa4, 0xbc, 0xa1, 0x05, 0xf7, 0x99, 0x9e, 0xd4, 0x57, 0xbd, 0x9c, 0xb7, 0x22, + 0xbd, 0xf9, 0x70, 0x2c, 0x81, 0x40, 0x15, 0x1e, 0xaa, 0x2e, 0x59, 0x88, 0x0e, 0x29, 0x66, 0x68, + 0x16, 0x1a, 0x40, 0x48, 0x02, 0x44, 0x28, 0xb9, 0x37, 0x02, 0x80, 0x29, 0x0a, 0x08, 0x14, 0xc5, + 0x0c, 0x50, 0xc5, 0x0c, 0x5c, 0x0c, 0x46, 0x13, 0x82, 0xe1, 0x55, 0x44, 0x41, 0x2a, 0x42, 0x03, + 0x81, 0x50, 0x32, 0xa1, 0x21, 0x20, 0x19, 0xa2, 0x13, 0x0d, 0x58, 0xbc, 0xbe, 0xec, 0xe0, 0x30, + 0x00, 0xc2, 0x08, 0x42, 0x37, 0xc1, 0xeb, 0xee, 0xef, 0x0c, 0xa3, 0xbf, 0x05, 0x00, 0x81, 0x5f, + 0xc4, 0xf8, 0x99, 0x7a, 0x15, 0xd0, 0xbf, 0x42, 0x58, 0x13, 0xa3, 0x32, 0x27, 0xf8, 0x10, 0x02, + 0x83, 0x22, 0x8f, 0xb2, 0xa4, 0xe8, 0xe5, 0x6e, 0x93, 0x7b, 0x6c, 0xe2, 0xdd, 0x61, 0x31, 0xb8, + 0xfb, 0x95, 0xe1, 0x10, 0xa4, 0x74, 0xfe, 0x7b, 0xef, 0x62, 0x5f, 0x67, 0x39, 0x2c, 0x1b, 0x8a, + 0xc5, 0x62, 0x8c, 0x56, 0xfc, 0x4c, 0x29, 0xdd, 0xb2, 0xb1, 0x77, 0x76, 0xd2, 0x0a, 0x63, 0x96, + 0x36, 0xd2, 0xf3, 0x91, 0xaf, 0x8b, 0x1f, 0x70, 0x34, 0xe1, 0x8c, 0x99, 0xf3, 0xb9, 0xce, 0x1c, + 0xe6, 0x0c, 0x02, 0x03, 0x07, 0x5e, 0x2b, 0x15, 0x8a, 0x03, 0xdc, 0x56, 0x48, 0x2a, 0x4a, 0x02, + 0xb2, 0x6b, 0x77, 0xc4, 0x01, 0xa0, 0x28, 0x50, 0xa0, 0x2d, 0x07, 0x24, 0x17, 0xe5, 0x07, 0x44, + 0x2f, 0x52, 0xf5, 0x14, 0xda, 0x55, 0x51, 0x78, 0xb8, 0x91, 0x03, 0x0c, 0xa2, 0xea, 0xa2, 0x99, + 0xe0, 0x6a, 0x17, 0x0e, 0x38, 0x70, 0x15, 0x04, 0x38, 0xdc, 0x2a, 0x8d, 0x6f, 0x02, 0x08, 0x40, + 0x28, 0x70, 0x9f, 0x17, 0xf4, 0x77, 0x7c, 0x1e, 0xdd, 0xf2, 0xd8, 0xad, 0xdd, 0xdd, 0xdc, 0x7f, + 0xf0, 0xca, 0x1e, 0x8e, 0xe1, 0x25, 0x76, 0xf2, 0xef, 0xc4, 0x28, 0x25, 0xf4, 0xf5, 0x57, 0x37, + 0x55, 0x2f, 0x75, 0xad, 0x74, 0x67, 0x7c, 0xa5, 0xd5, 0x44, 0x62, 0x51, 0xfa, 0x4e, 0xae, 0x17, + 0x5c, 0xa7, 0xe8, 0x8e, 0x8d, 0x89, 0x04, 0x02, 0x87, 0x62, 0x1f, 0xca, 0xa1, 0xd6, 0xe5, 0xc3, + 0x23, 0x25, 0x83, 0x77, 0xd6, 0xb5, 0x34, 0x3d, 0xe0, 0xf3, 0xca, 0x88, 0x1c, 0x39, 0xcc, 0x20, + 0x0a, 0x06, 0x44, 0x80, 0xe1, 0x60, 0x32, 0xd9, 0xf5, 0xdb, 0x93, 0xd4, 0x2b, 0xb0, 0xa1, 0x54, + 0x5e, 0x17, 0x05, 0x20, 0x60, 0x0a, 0x54, 0x79, 0x90, 0xef, 0xcb, 0xc4, 0x87, 0x04, 0x9c, 0x0a, + 0x81, 0x54, 0x05, 0x01, 0x71, 0x12, 0x09, 0x74, 0x75, 0x53, 0xf0, 0x8c, 0x49, 0x2f, 0xa8, 0xba, + 0xca, 0xe2, 0x60, 0xaa, 0xb4, 0xea, 0x2e, 0xa2, 0xf0, 0x6a, 0x94, 0x22, 0xbe, 0x99, 0xec, 0xd9, + 0xc4, 0x02, 0x10, 0x4d, 0x9f, 0xa0, 0x71, 0xa1, 0x92, 0x3d, 0xdd, 0xef, 0xc0, 0x20, 0x00, 0x20, + 0x7c, 0x4e, 0x21, 0x7e, 0x82, 0xb5, 0x7c, 0x12, 0x5e, 0xfa, 0xae, 0x89, 0x2b, 0x89, 0xfd, 0x5e, + 0xf0, 0x84, 0x47, 0x42, 0xfa, 0xfa, 0x23, 0x13, 0xf5, 0xe9, 0x31, 0x12, 0xf3, 0x19, 0xdf, 0x5c, + 0xa5, 0xd5, 0x7c, 0xd9, 0x59, 0x9a, 0x38, 0x12, 0x40, 0x44, 0x05, 0x07, 0x3b, 0xee, 0x20, 0x61, + 0x36, 0x21, 0xdf, 0xd4, 0x53, 0x2c, 0xc5, 0xd2, 0x3f, 0x38, 0x31, 0x07, 0x02, 0x88, 0xe5, 0xb7, + 0x15, 0xbb, 0xb5, 0xc4, 0x88, 0x0a, 0x6a, 0xab, 0xba, 0xde, 0xda, 0xa8, 0xa6, 0x34, 0x86, 0x5b, + 0x8f, 0x5e, 0x18, 0x1f, 0x2d, 0xd4, 0xd9, 0x38, 0xb8, 0xbc, 0xa0, 0x71, 0x5f, 0x0b, 0x12, 0x10, + 0xbc, 0x41, 0x57, 0xf6, 0x57, 0xff, 0xf7, 0xbe, 0x24, 0x32, 0x14, 0x3b, 0xc5, 0x6f, 0x0a, 0xc1, + 0x81, 0xfc, 0x5d, 0x54, 0x5d, 0x72, 0xe1, 0x11, 0x01, 0x11, 0x4d, 0x64, 0xef, 0xa6, 0xab, 0x59, + 0x78, 0xb9, 0x5b, 0xc6, 0x01, 0x08, 0x01, 0x12, 0x50, 0x8e, 0x50, 0x46, 0xbe, 0x01, 0x19, 0x11, + 0x3c, 0x46, 0x5e, 0x8e, 0x92, 0xba, 0x9a, 0xae, 0xa9, 0x12, 0xeb, 0xd3, 0xf5, 0x8a, 0xb9, 0x7a, + 0xaf, 0xab, 0x91, 0xbd, 0x1b, 0xa4, 0x83, 0x90, 0x3c, 0x02, 0x41, 0x8e, 0xfc, 0xb8, 0x91, 0x01, + 0x1d, 0x39, 0x7f, 0x2d, 0xa7, 0xd0, 0x66, 0xcf, 0x08, 0x15, 0xed, 0xa3, 0xd0, 0xc4, 0xf2, 0x5e, + 0x2e, 0x29, 0xf8, 0xc8, 0xa0, 0x61, 0x60, 0xd0, 0x50, 0x31, 0x59, 0x11, 0x2d, 0xcb, 0x67, 0xe2, + 0x00, 0xe0, 0xfb, 0x96, 0x07, 0x09, 0xab, 0xc9, 0x61, 0x8a, 0x1c, 0x2c, 0x42, 0x00, 0x24, 0x5a, + 0x24, 0x1b, 0xd6, 0xff, 0xff, 0xf3, 0xf3, 0xfc, 0x0d, 0x00, 0x41, 0x05, 0x02, 0x71, 0x4d, 0x66, + 0xf1, 0x76, 0xe2, 0x03, 0x21, 0x19, 0x14, 0x33, 0x1b, 0x91, 0x7a, 0xbe, 0xef, 0x86, 0x43, 0x03, + 0xc4, 0x6e, 0xea, 0x39, 0x3e, 0xd9, 0xcf, 0x6d, 0xcc, 0xda, 0xc4, 0x80, 0xa8, 0x08, 0x5d, 0x99, + 0x77, 0x28, 0x3d, 0x85, 0x63, 0xff, 0x77, 0x73, 0xf2, 0x8f, 0x7b, 0xc6, 0xf3, 0x77, 0x7e, 0x18, + 0xfa, 0xc5, 0x37, 0x2f, 0x55, 0x5d, 0x1d, 0xa6, 0xe6, 0x36, 0xee, 0xba, 0x2b, 0xd7, 0x45, 0x6a, + 0xe8, 0x8e, 0xae, 0xa9, 0x5a, 0xc4, 0x8f, 0x0a, 0x6e, 0xed, 0xa8, 0xea, 0x64, 0xa2, 0x04, 0x30, + 0x6c, 0x59, 0x48, 0x3b, 0xd4, 0xc3, 0x0a, 0x00, 0x72, 0x42, 0xce, 0x70, 0x15, 0xe2, 0xc1, 0x5a, + 0xc4, 0x71, 0x31, 0x42, 0x35, 0x00, 0xc5, 0xa9, 0x6b, 0x2d, 0xf9, 0x6b, 0x3b, 0x87, 0x38, 0x77, + 0x92, 0x38, 0x6e, 0x33, 0x5b, 0xd9, 0xe2, 0xc3, 0x28, 0xe0, 0x22, 0x83, 0x0c, 0x9e, 0x05, 0x8b, + 0xef, 0x7f, 0xb9, 0xbd, 0xdd, 0x67, 0xf1, 0x47, 0x97, 0x05, 0x20, 0xa0, 0x61, 0x05, 0x03, 0x17, + 0x10, 0x7e, 0x46, 0x19, 0x46, 0xce, 0xd0, 0x5c, 0x26, 0xe6, 0xe0, 0x88, 0x22, 0x26, 0x9b, 0x1e, + 0xdd, 0xcb, 0x03, 0x2a, 0xca, 0x58, 0x1c, 0x32, 0x84, 0x80, 0x0a, 0x52, 0xf4, 0x15, 0xa3, 0xd1, + 0x71, 0x7f, 0xf4, 0xd3, 0x7b, 0xef, 0xc1, 0x08, 0x08, 0x01, 0xc4, 0x11, 0xc2, 0xe8, 0x56, 0x28, + 0xd5, 0x71, 0x20, 0x3e, 0xc1, 0xd7, 0xfe, 0x18, 0x08, 0x1c, 0x4f, 0x24, 0x5e, 0x30, 0xa5, 0xb8, + 0xe7, 0xcc, 0x79, 0x0f, 0x82, 0x90, 0x59, 0x76, 0x62, 0x8c, 0x28, 0xd8, 0x57, 0x88, 0x40, 0xf3, + 0xfe, 0xfd, 0xe0, 0x60, 0x18, 0x3a, 0x9b, 0x59, 0xc2, 0xad, 0x3b, 0xaa, 0xaa, 0xb4, 0xd2, 0x85, + 0x4a, 0x63, 0xc1, 0x18, 0xd7, 0x8c, 0x0b, 0x8b, 0xdb, 0x57, 0x04, 0x22, 0xdd, 0xdd, 0xd3, 0xdf, + 0x57, 0x2f, 0xab, 0xa1, 0xce, 0xbd, 0x5d, 0x75, 0x27, 0x5d, 0x5c, 0x1c, 0x81, 0x80, 0x81, 0x01, + 0xda, 0x51, 0x37, 0xad, 0xaf, 0x88, 0x0a, 0x4f, 0xf2, 0x70, 0x35, 0x25, 0xa2, 0x72, 0x1e, 0x24, + 0xb2, 0x0a, 0xf1, 0x50, 0xec, 0xf5, 0x3e, 0x3a, 0x46, 0xc9, 0x5a, 0x8c, 0x92, 0x51, 0xd1, 0x63, + 0xb7, 0x05, 0x0e, 0xcb, 0xde, 0x24, 0x61, 0x9e, 0x38, 0x77, 0x1e, 0xb1, 0x3e, 0x58, 0x01, 0x93, + 0x80, 0x78, 0x63, 0x80, 0x05, 0x80, 0x77, 0x4a, 0x78, 0x70, 0xa6, 0xf2, 0x8f, 0x91, 0xf8, 0x26, + 0xf0, 0x5b, 0x84, 0x83, 0x6c, 0x11, 0xcd, 0x7f, 0xc7, 0xde, 0x00, 0x3c, 0xbc, 0x79, 0x7b, 0x9a, + 0xd7, 0x5c, 0x23, 0x14, 0x52, 0x50, 0xd8, 0x9b, 0x78, 0x38, 0x96, 0x07, 0x19, 0x28, 0x37, 0x64, + 0x39, 0x2c, 0xc4, 0xc1, 0x5f, 0x9c, 0x60, 0xb6, 0x4a, 0x59, 0x54, 0xdc, 0x89, 0xa6, 0x84, 0x70, + 0xbd, 0xcf, 0x10, 0x24, 0x4a, 0xdb, 0x9b, 0x11, 0x93, 0x07, 0xc7, 0x73, 0xcb, 0xaa, 0xaf, 0x05, + 0x02, 0x88, 0xb2, 0xb9, 0xdb, 0xe2, 0x40, 0x4c, 0x02, 0xb1, 0x07, 0xb8, 0x7f, 0x39, 0x77, 0xad, + 0xdc, 0x7d, 0x94, 0x52, 0xd1, 0x13, 0x81, 0x04, 0x0e, 0x00, 0xa0, 0x5b, 0x6a, 0x1b, 0x65, 0x45, + 0x5a, 0x89, 0x2a, 0x6e, 0x86, 0xb1, 0x10, 0x2d, 0x68, 0xdf, 0xd5, 0xd1, 0x1d, 0x11, 0x8f, 0xa2, + 0xa6, 0xfa, 0xb9, 0x13, 0xc1, 0x15, 0x57, 0x74, 0x9c, 0xa5, 0xbb, 0xb9, 0x3a, 0xcb, 0x83, 0x90, + 0x34, 0x20, 0x97, 0x70, 0x88, 0x80, 0x4b, 0x77, 0xdd, 0xf6, 0x78, 0x90, 0x8e, 0xaa, 0xb4, 0x31, + 0x5e, 0x2b, 0x10, 0xe3, 0x82, 0x34, 0x81, 0xf5, 0x89, 0x84, 0x0d, 0x79, 0x65, 0xb5, 0xee, 0x2b, + 0xbf, 0x13, 0xc4, 0x04, 0x38, 0x44, 0x22, 0x0a, 0x44, 0x8f, 0x7d, 0xf9, 0x03, 0x80, 0x7a, 0x49, + 0xb8, 0x7a, 0xaa, 0x65, 0x7b, 0x88, 0xf8, 0x60, 0x5e, 0xb5, 0x5a, 0xd4, 0x10, 0x82, 0x10, 0x4f, + 0x15, 0x87, 0x63, 0x15, 0xaf, 0xe9, 0xcd, 0x18, 0x4d, 0xa3, 0xfc, 0x40, 0xa2, 0xd3, 0xc3, 0x9c, + 0xc4, 0xb9, 0x89, 0x7f, 0x04, 0x20, 0x20, 0x21, 0x6e, 0x82, 0x2e, 0x44, 0x04, 0x88, 0x44, 0x83, + 0x7e, 0x32, 0x93, 0xd3, 0xf1, 0x70, 0x72, 0x06, 0x80, 0x46, 0x41, 0x71, 0x71, 0x72, 0x68, 0x10, + 0x83, 0x71, 0x02, 0x41, 0x0e, 0x91, 0x33, 0x6e, 0x11, 0x11, 0xc4, 0x88, 0x14, 0x63, 0xa4, 0xdf, + 0x4f, 0xdb, 0x82, 0xb3, 0x9e, 0xed, 0xf8, 0x80, 0x88, 0x42, 0xf4, 0x65, 0x6e, 0x20, 0xf4, 0x16, + 0x0e, 0x68, 0x4b, 0x51, 0x12, 0x70, 0x41, 0x08, 0x07, 0x02, 0x41, 0x74, 0xca, 0x0f, 0xa8, 0x3d, + 0xf0, 0x5e, 0xf1, 0x96, 0xaa, 0xd1, 0x71, 0xea, 0x95, 0x41, 0x64, 0x78, 0x1a, 0x31, 0x59, 0x65, + 0xff, 0x11, 0x12, 0x25, 0xef, 0x55, 0xf0, 0xc0, 0x0a, 0x80, 0xa1, 0x45, 0x31, 0x1c, 0x59, 0x17, + 0x14, 0xd4, 0x53, 0x89, 0xf5, 0x3f, 0xcb, 0xc5, 0xcb, 0x31, 0x4f, 0xd8, 0xc9, 0xc3, 0x43, 0xf3, + 0xf0, 0x88, 0x18, 0x04, 0x54, 0x98, 0xbd, 0xbf, 0x14, 0x43, 0x07, 0xea, 0xf8, 0x20, 0x02, 0x41, + 0x31, 0x91, 0x10, 0xfc, 0x32, 0xa0, 0x0b, 0x5d, 0xa1, 0x9b, 0xfa, 0x9b, 0x6f, 0xdd, 0xcd, 0xdc, + 0x1c, 0x9f, 0xd3, 0x2f, 0x92, 0xf8, 0xd6, 0x4a, 0x58, 0xe0, 0xc4, 0x0e, 0x00, 0xa8, 0x75, 0x95, + 0x73, 0x64, 0x47, 0x36, 0xdb, 0x83, 0x10, 0x38, 0x14, 0xf7, 0x9f, 0x85, 0x7a, 0x1a, 0xc4, 0x5f, + 0x42, 0x2a, 0xf8, 0x23, 0xab, 0xed, 0x41, 0x82, 0x58, 0x36, 0xdb, 0xdb, 0x6f, 0xfe, 0xdd, 0x7c, + 0x31, 0xd4, 0x4f, 0x22, 0x7c, 0x1d, 0x0b, 0x0e, 0xf0, 0x40, 0xcd, 0xd3, 0x07, 0x37, 0xfc, 0x18, + 0x81, 0xc0, 0x12, 0x88, 0x10, 0x07, 0x04, 0x01, 0xc1, 0x4c, 0xbc, 0x41, 0xc1, 0x4e, 0x62, 0x26, + 0x9f, 0x0a, 0x16, 0x21, 0x62, 0x75, 0x5a, 0xa7, 0x4a, 0x9b, 0xde, 0x2f, 0x4e, 0x26, 0xca, 0xeb, + 0xe2, 0x61, 0x2d, 0xed, 0x58, 0xeb, 0xe0, 0xa4, 0xcd, 0xe9, 0x65, 0x62, 0x90, 0xac, 0xbd, 0xff, + 0xb8, 0x44, 0x30, 0x33, 0x67, 0xb4, 0xcb, 0xc3, 0xb5, 0x65, 0xd8, 0x0a, 0x87, 0x19, 0x51, 0x7f, + 0x4b, 0xe5, 0xe1, 0xc1, 0xda, 0x95, 0x8d, 0x07, 0x21, 0x11, 0xff, 0x13, 0xf1, 0x20, 0x9c, 0x48, + 0xae, 0xed, 0xd5, 0x55, 0xf0, 0xbe, 0x00, 0xc0, 0xfd, 0x07, 0x39, 0xf7, 0xd7, 0xff, 0xef, 0x08, + 0xba, 0xc9, 0xf8, 0x39, 0x93, 0x56, 0xd6, 0x29, 0x14, 0x11, 0xce, 0xd2, 0x8a, 0x70, 0x8e, 0xa9, + 0xf8, 0x80, 0x81, 0x6b, 0x5f, 0x8e, 0x23, 0xbe, 0x5c, 0xb7, 0x49, 0x3d, 0x3c, 0x44, 0x78, 0xa9, + 0x0c, 0x5d, 0x99, 0x48, 0x98, 0xe6, 0x23, 0x95, 0x27, 0xe1, 0x90, 0x38, 0x02, 0xbe, 0x2b, 0xc2, + 0x12, 0xe2, 0x9d, 0x80, 0x37, 0xa1, 0x45, 0x53, 0xc6, 0xe1, 0x90, 0x38, 0x02, 0x33, 0xe1, 0xa6, + 0x12, 0xca, 0x9e, 0x0c, 0x21, 0x6e, 0x8e, 0xf5, 0xd0, 0x93, 0x27, 0xcc, 0x4b, 0xdc, 0xbd, 0x5b, + 0xea, 0xd5, 0xd5, 0xb8, 0x39, 0x01, 0x10, 0x0b, 0x05, 0x52, 0x7e, 0xa2, 0xf5, 0x58, 0xfd, 0xc4, + 0x84, 0x19, 0x05, 0xe5, 0x1f, 0x0c, 0x82, 0x80, 0x8c, 0x56, 0xdb, 0x9b, 0xb8, 0x97, 0x05, 0x65, + 0xbc, 0x4f, 0xc4, 0x9f, 0x88, 0x10, 0x10, 0x2b, 0x16, 0xdd, 0xda, 0x5b, 0xb1, 0x46, 0xf7, 0xc3, + 0x4c, 0xa0, 0x47, 0xc7, 0x73, 0x7f, 0xff, 0x65, 0xbf, 0x08, 0xc1, 0x57, 0x55, 0xba, 0x6e, 0x39, + 0x42, 0xde, 0x21, 0xef, 0xc4, 0x88, 0x05, 0x03, 0x1d, 0xed, 0xb9, 0xb2, 0x9b, 0xf1, 0x02, 0x42, + 0x94, 0x7d, 0xc5, 0x40, 0xfd, 0x82, 0xaf, 0x40, 0x77, 0x24, 0xa3, 0x91, 0x51, 0xce, 0x2d, 0xc4, + 0x2b, 0x4a, 0x56, 0x30, 0xaa, 0xc9, 0x6a, 0x88, 0x03, 0xe7, 0xc2, 0x71, 0x20, 0x0c, 0x01, 0xed, + 0xa1, 0x92, 0x94, 0x4f, 0xaf, 0xa3, 0x4c, 0xbb, 0x07, 0x37, 0xc5, 0xbe, 0x11, 0x02, 0x47, 0x88, + 0x09, 0x6b, 0x57, 0xde, 0x3a, 0x70, 0x4a, 0x95, 0x33, 0xbd, 0xc4, 0x41, 0x45, 0x57, 0x59, 0xb8, + 0xa7, 0xee, 0x24, 0x22, 0x52, 0x2a, 0xaa, 0xc2, 0xb1, 0x60, 0x89, 0x28, 0x3b, 0xff, 0x6f, 0xf8, + 0x64, 0x1c, 0x14, 0xca, 0xbe, 0x0a, 0x00, 0x80, 0x13, 0x99, 0x8f, 0xdd, 0xf0, 0x80, 0x38, 0xf0, + 0x3c, 0x02, 0x5a, 0xce, 0x15, 0x2a, 0x1f, 0x81, 0x2c, 0x4c, 0xcf, 0x7c, 0x28, 0x33, 0x8c, 0xea, + 0x0b, 0xcb, 0xcd, 0xc4, 0x87, 0x22, 0x2e, 0x85, 0xc2, 0x85, 0x90, 0xb9, 0xda, 0x1f, 0x04, 0x01, + 0x67, 0x2c, 0xcb, 0xc6, 0x8a, 0x22, 0xc3, 0x20, 0x40, 0x0a, 0x44, 0x9c, 0x13, 0xc1, 0xe5, 0x85, + 0x86, 0x2e, 0x27, 0x82, 0x86, 0x58, 0x74, 0x81, 0xfe, 0x8e, 0x2d, 0x9c, 0x1c, 0x2c, 0x32, 0xbf, + 0x22, 0x43, 0x90, 0xc0, 0x05, 0x0d, 0x2b, 0xc3, 0x61, 0x1d, 0x6f, 0xb5, 0xcb, 0xad, 0xf9, 0xf8, + 0x28, 0x1c, 0x67, 0xfd, 0x4a, 0xa1, 0xd5, 0xd0, 0x4d, 0x2a, 0x09, 0x77, 0x7b, 0xfc, 0x25, 0xd5, + 0x75, 0x54, 0x39, 0x4b, 0x0c, 0x9d, 0x7a, 0xa3, 0xf8, 0x29, 0x01, 0x00, 0x0a, 0x87, 0x55, 0x6a, + 0xa6, 0xf8, 0xba, 0x88, 0x98, 0xe0, 0xa0, 0x08, 0x3b, 0xe1, 0x01, 0x95, 0x17, 0x17, 0x49, 0x69, + 0x55, 0x3a, 0x6e, 0x2b, 0x71, 0x5e, 0x20, 0x40, 0x52, 0xb5, 0xdd, 0xc5, 0x1d, 0xdd, 0xc5, 0x62, + 0x8c, 0x51, 0x8a, 0x37, 0xf1, 0x01, 0x02, 0x0a, 0x30, 0xb8, 0xa8, 0xa0, 0xec, 0x56, 0xef, 0x13, + 0xe3, 0x0a, 0x2e, 0xcf, 0x1c, 0x42, 0x82, 0x02, 0xba, 0xce, 0x2e, 0xc2, 0xec, 0xa3, 0xb4, 0xfa, + 0x2a, 0x2f, 0xa2, 0xa2, 0x1f, 0x61, 0x34, 0x40, 0x06, 0x3f, 0x26, 0x4f, 0x6f, 0xad, 0x7e, 0xdb, + 0x7c, 0x22, 0x19, 0x18, 0x20, 0x51, 0x89, 0x72, 0xa2, 0x41, 0xc3, 0xc1, 0x22, 0x05, 0x07, 0xb2, + 0xa9, 0x78, 0x00, 0x75, 0x3c, 0x3d, 0x5a, 0x8f, 0x1f, 0x53, 0x0e, 0xa0, 0xb0, 0x4b, 0x87, 0x00, + 0xe2, 0xb5, 0xc2, 0x22, 0x46, 0x47, 0x56, 0x48, 0x3d, 0x84, 0x49, 0x60, 0xa2, 0x82, 0xa7, 0x6c, + 0x54, 0x71, 0xe1, 0xda, 0x53, 0xc0, 0x70, 0xf0, 0x6b, 0xd9, 0x3f, 0x02, 0xbf, 0xac, 0xb0, 0x06, + 0x25, 0x7d, 0x40, 0xff, 0x12, 0x0a, 0x02, 0x92, 0x4b, 0x21, 0x5b, 0xc0, 0xf7, 0xe5, 0x80, 0xc4, + 0xbc, 0x0a, 0x2b, 0xe8, 0xf0, 0x61, 0xdf, 0x5a, 0xc9, 0xc0, 0xd5, 0x19, 0x2d, 0x5d, 0xad, 0x62, + 0x5c, 0xe1, 0x00, 0x88, 0x50, 0xe2, 0xb7, 0x06, 0x23, 0x57, 0xfa, 0xc5, 0xca, 0xad, 0x77, 0x72, + 0x75, 0x14, 0xe4, 0x48, 0x7f, 0x70, 0x11, 0x02, 0x04, 0x89, 0x3e, 0xc9, 0x79, 0x38, 0xbc, 0xcf, + 0x02, 0x08, 0x95, 0xf7, 0x03, 0xcc, 0x14, 0xd7, 0x7a, 0x97, 0x3b, 0xac, 0x76, 0x3f, 0x81, 0xa6, + 0x14, 0x25, 0x35, 0x88, 0x78, 0xa0, 0xc5, 0x62, 0x83, 0x5a, 0xac, 0x56, 0xbe, 0xe0, 0xc4, 0x0b, + 0x14, 0x16, 0x9c, 0x0c, 0x7a, 0x1d, 0xff, 0xf5, 0x75, 0x75, 0x10, 0x0a, 0x01, 0x21, 0x15, 0x55, + 0x7d, 0x86, 0x14, 0x09, 0x99, 0xa9, 0xd7, 0xff, 0xfb, 0x7b, 0xf0, 0x88, 0x0d, 0x01, 0x06, 0xc5, + 0xf0, 0xfc, 0x09, 0x43, 0x96, 0x00, 0x02, 0x00, 0x4a, 0x5e, 0x4a, 0x05, 0x70, 0x80, 0x0a, 0x81, + 0xa6, 0x1f, 0x60, 0x39, 0xb2, 0xa2, 0xc1, 0x83, 0xec, 0x16, 0x8b, 0x18, 0xad, 0x5a, 0x55, 0x9b, + 0x16, 0x40, 0xd0, 0x30, 0x37, 0x05, 0x56, 0x33, 0xc0, 0x75, 0x6f, 0x0e, 0x1f, 0xff, 0xc1, 0x19, + 0xee, 0x21, 0xcb, 0xaa, 0xe0, 0xa2, 0xf7, 0xdd, 0xb5, 0x77, 0xc1, 0x15, 0xad, 0xb8, 0xbe, 0x0b, + 0x25, 0xcf, 0xba, 0x2b, 0x75, 0xef, 0x98, 0xcd, 0x6a, 0x5e, 0x8b, 0x04, 0x9d, 0x17, 0xa4, 0xea, + 0x61, 0x5f, 0x5c, 0x27, 0xe8, 0xb5, 0x50, 0x60, 0x20, 0x13, 0xd2, 0xc2, 0xd6, 0x4d, 0x49, 0x20, + 0x66, 0xd5, 0x16, 0x71, 0x02, 0x43, 0x24, 0x36, 0x09, 0xc0, 0xee, 0x44, 0x04, 0x49, 0x14, 0xff, + 0xc5, 0x12, 0x11, 0x35, 0x66, 0x10, 0x04, 0x00, 0xbb, 0x15, 0xe9, 0x97, 0xb9, 0xc3, 0x95, 0xc4, + 0x80, 0x80, 0x05, 0x06, 0xb7, 0x6c, 0x5e, 0x20, 0xff, 0x70, 0x50, 0x01, 0x41, 0x1e, 0x7a, 0xb6, + 0xab, 0x5e, 0xef, 0x1c, 0xca, 0x00, 0xbd, 0xe2, 0xfe, 0x71, 0x3e, 0x18, 0x50, 0x02, 0xe8, 0xd6, + 0xb1, 0xb1, 0xfa, 0x7b, 0x66, 0xf5, 0xff, 0xf7, 0x86, 0x06, 0x10, 0x4d, 0x92, 0xda, 0xa4, 0xc9, + 0xe3, 0x8f, 0x20, 0x92, 0x54, 0xb5, 0x9d, 0xdd, 0x31, 0x22, 0x20, 0x2a, 0xd0, 0x29, 0x49, 0xaa, + 0x96, 0x47, 0x00, 0x3f, 0x84, 0x01, 0x4c, 0x7a, 0xc1, 0xe5, 0x87, 0x0e, 0x1c, 0xe0, 0xf0, 0xb0, + 0x78, 0x59, 0x75, 0x96, 0x03, 0xb2, 0xc0, 0x6e, 0x89, 0x4b, 0x08, 0x83, 0x00, 0x53, 0x24, 0xad, + 0x3c, 0x77, 0x9f, 0x95, 0x7e, 0x2b, 0x7e, 0x45, 0x0b, 0xe0, 0x2d, 0xa5, 0x0d, 0x4c, 0x1e, 0x4d, + 0x8b, 0xbf, 0x8b, 0xb8, 0xb8, 0xae, 0xb5, 0xec, 0x30, 0x84, 0x80, 0x29, 0xb2, 0x1f, 0x1a, 0xb5, + 0x7d, 0xbb, 0x7f, 0xe8, 0xfc, 0x72, 0x20, 0x46, 0x10, 0x8e, 0xbb, 0x12, 0xca, 0x00, 0xb6, 0xd8, + 0x79, 0x23, 0xa2, 0x88, 0x60, 0x28, 0xd7, 0xf5, 0x86, 0x40, 0xa0, 0xe2, 0x9a, 0x8b, 0xae, 0x0c, + 0x23, 0xc4, 0x8b, 0xaa, 0xea, 0xd8, 0x9e, 0x37, 0xae, 0x16, 0x90, 0x01, 0x6f, 0xf4, 0x83, 0x7d, + 0xef, 0xf7, 0xbe, 0x11, 0x06, 0x0e, 0xf7, 0xf8, 0x22, 0xaa, 0xa8, 0xbf, 0xb1, 0x68, 0x48, 0x03, + 0xc6, 0xa1, 0x98, 0x38, 0x76, 0x3f, 0xc0, 0xd0, 0x14, 0x10, 0xb1, 0x7a, 0x32, 0xd2, 0xd0, 0xb8, + 0xb8, 0xb8, 0xba, 0xa8, 0xbf, 0xde, 0x07, 0x00, 0x4f, 0x2e, 0x87, 0x2c, 0x04, 0xb6, 0xed, 0xcf, + 0x9b, 0x70, 0x88, 0x1e, 0x06, 0x8e, 0x3c, 0x7d, 0x45, 0xb0, 0x62, 0x94, 0x1d, 0x58, 0x0e, 0x96, + 0x1e, 0x00, 0x04, 0x39, 0xe0, 0x00, 0x53, 0x3a, 0xa8, 0x31, 0x12, 0x9c, 0x00, 0x04, 0xb2, 0x49, + 0x40, 0x2a, 0x0e, 0x00, 0x05, 0x01, 0x90, 0x8b, 0x40, 0xe0, 0x7f, 0x07, 0x03, 0x3d, 0x7f, 0xd1, + 0x4c, 0x9f, 0x56, 0x9f, 0x82, 0xd3, 0xbe, 0x9b, 0x5b, 0x5a, 0xf8, 0xea, 0x49, 0x69, 0xb6, 0x9b, + 0x69, 0x9f, 0x5a, 0xfc, 0x16, 0x5a, 0xb5, 0x49, 0x2d, 0x37, 0xeb, 0xe0, 0x8a, 0x6c, 0xfa, 0xf8, + 0xbf, 0x3e, 0x6d, 0x35, 0xeb, 0xd7, 0xc2, 0x76, 0xb6, 0xa3, 0x8b, 0xfd, 0x6b, 0xe4, 0xa6, 0xdf, + 0xe1, 0x3e, 0x92, 0x54, 0x9a, 0x52, 0xf3, 0x17, 0x17, 0xae, 0x2b, 0x4d, 0x3b, 0x5a, 0xf8, 0x4e, + 0xf6, 0xad, 0x35, 0xe2, 0x60, 0x92, 0xad, 0x6d, 0xc1, 0x84, 0x61, 0x94, 0x5d, 0xd4, 0xbf, 0xcf, + 0xcb, 0xc5, 0x58, 0xb9, 0x3f, 0x7c, 0x48, 0x08, 0x85, 0xd5, 0x44, 0x01, 0x20, 0x5f, 0x27, 0x8a, + 0xde, 0xf0, 0xbb, 0x30, 0x03, 0x42, 0x1c, 0xbd, 0x8e, 0x4d, 0x45, 0x2c, 0x35, 0xad, 0xe2, 0xba, + 0xa8, 0xbe, 0x93, 0x1c, 0xce, 0x09, 0x05, 0x3a, 0xcd, 0x61, 0xa6, 0x50, 0x2c, 0x28, 0x75, 0x9f, + 0xfe, 0xbe, 0xf8, 0x5a, 0x50, 0x0a, 0xb7, 0x8e, 0x5e, 0xff, 0xff, 0x7e, 0x0c, 0x41, 0x48, 0x82, + 0xe2, 0xe5, 0x1f, 0x62, 0x4a, 0x50, 0x1d, 0xf6, 0x5f, 0x7f, 0xda, 0x21, 0x1b, 0x70, 0x27, 0xc3, + 0x58, 0x09, 0xbb, 0x65, 0x4d, 0xfd, 0x7f, 0xfa, 0x79, 0x61, 0xac, 0x03, 0x2e, 0x9d, 0x2f, 0xfd, + 0x34, 0xfd, 0x2a, 0x85, 0x94, 0x00, 0xfe, 0x5e, 0xc4, 0x4e, 0x05, 0xfd, 0x7a, 0x69, 0xaa, 0x69, + 0xc5, 0xb1, 0x20, 0xbc, 0x24, 0x5d, 0x89, 0x9c, 0x1d, 0x26, 0x27, 0x42, 0x00, 0x15, 0xab, 0x14, + 0x79, 0xb4, 0x34, 0xcc, 0x00, 0x8e, 0xbc, 0x12, 0x0a, 0x17, 0x7d, 0x7f, 0xf7, 0xe1, 0x00, 0x14, + 0x22, 0x4a, 0x20, 0xf8, 0x8f, 0xad, 0x7c, 0x04, 0x07, 0xc6, 0x6e, 0xe2, 0xb1, 0x5b, 0x8a, 0x0d, + 0xdc, 0x51, 0xc5, 0x62, 0x5f, 0x25, 0xb3, 0x7e, 0x10, 0x25, 0xb5, 0xf8, 0x61, 0x7d, 0xc4, 0x82, + 0x14, 0x56, 0xc6, 0xb8, 0x2a, 0x14, 0x8d, 0x7b, 0x83, 0x90, 0x70, 0x89, 0xee, 0x10, 0x10, 0x32, + 0xab, 0xd5, 0x2a, 0x4f, 0xfa, 0xb8, 0xa3, 0xb7, 0x78, 0x78, 0x82, 0x00, 0x30, 0x61, 0xa9, 0xa7, + 0x17, 0x8d, 0x53, 0x7c, 0xb7, 0xdb, 0x6d, 0xdd, 0xb7, 0xb6, 0xf0, 0x74, 0x27, 0x10, 0x75, 0x7a, + 0x30, 0x6a, 0xbb, 0xcd, 0xd8, 0x96, 0xd6, 0x9f, 0xad, 0x44, 0xf1, 0x77, 0xbf, 0x55, 0xf0, 0x49, + 0x5a, 0xe2, 0xf8, 0xcb, 0x4d, 0x7b, 0xba, 0x49, 0x6d, 0xdf, 0xe1, 0xca, 0x49, 0x55, 0x52, 0x49, + 0x34, 0xff, 0xc1, 0x15, 0xdf, 0xc3, 0xe8, 0x9a, 0xfa, 0xc5, 0x34, 0x44, 0x12, 0x6a, 0xd8, 0xbc, + 0x1c, 0x1c, 0x80, 0xa0, 0x04, 0xb1, 0x43, 0x27, 0x0a, 0x15, 0xf7, 0x74, 0xff, 0x16, 0x77, 0xbe, + 0xf7, 0x85, 0x9c, 0x09, 0x47, 0x53, 0x3f, 0xb7, 0xff, 0xa6, 0x9f, 0x16, 0xc8, 0x10, 0x43, 0x85, + 0x57, 0xc2, 0xec, 0x50, 0x01, 0xdb, 0xec, 0x57, 0xa9, 0xb7, 0xff, 0x4f, 0x77, 0x25, 0xc1, 0x00, + 0x1a, 0x05, 0x8b, 0x8b, 0x9b, 0x97, 0xac, 0x5c, 0x53, 0xc1, 0x08, 0x0b, 0x05, 0x1d, 0xb0, 0x99, + 0x20, 0x0a, 0x43, 0x44, 0xa0, 0xba, 0xe7, 0x27, 0xde, 0xff, 0x15, 0xc5, 0x7c, 0x10, 0x81, 0xa0, + 0x64, 0x51, 0x96, 0x31, 0x41, 0x88, 0x1c, 0x10, 0xb1, 0xad, 0x12, 0xbf, 0x8b, 0xfb, 0x76, 0xf0, + 0xcf, 0x1c, 0x48, 0x04, 0x65, 0x5f, 0xc8, 0xec, 0x76, 0x05, 0x70, 0xcd, 0x76, 0x2d, 0x94, 0x0b, + 0x5f, 0x4f, 0xf6, 0x17, 0x45, 0x00, 0x67, 0xa7, 0xdd, 0xdb, 0xff, 0xad, 0x7e, 0xb5, 0x67, 0x07, + 0x31, 0x82, 0x85, 0x31, 0x71, 0x75, 0x11, 0xc2, 0x66, 0xe2, 0xf1, 0x07, 0xdc, 0x56, 0xe2, 0x8f, + 0xc2, 0x05, 0x17, 0x5b, 0xbb, 0xbb, 0xea, 0x2f, 0x09, 0xb2, 0x89, 0x15, 0x3f, 0xfd, 0xbf, 0x85, + 0x27, 0x05, 0x94, 0x4d, 0x9e, 0xf7, 0xfd, 0x6b, 0xe1, 0x40, 0x83, 0x8a, 0xdd, 0xeb, 0x57, 0x8a, + 0xdf, 0x55, 0x97, 0x02, 0x00, 0x38, 0x05, 0x42, 0xdd, 0xbe, 0x2f, 0x5a, 0x9b, 0x9e, 0x70, 0x77, + 0x61, 0xac, 0x21, 0x49, 0x2f, 0xfe, 0x9f, 0xb7, 0x86, 0x15, 0xb0, 0xa2, 0x12, 0x36, 0xd1, 0xfd, + 0xbf, 0xf8, 0xa6, 0x20, 0x2f, 0x5c, 0x22, 0x0e, 0x05, 0x12, 0xab, 0xbd, 0xf8, 0x0a, 0x80, 0x4a, + 0x41, 0xda, 0xfb, 0xb6, 0xd1, 0x59, 0x83, 0xee, 0x22, 0x16, 0x85, 0x8a, 0xad, 0xc1, 0x28, 0x15, + 0x1e, 0xb8, 0x7b, 0x35, 0x42, 0x1e, 0x25, 0x00, 0x02, 0xea, 0x45, 0x8d, 0x42, 0x10, 0x18, 0x41, + 0x00, 0x96, 0x0d, 0x57, 0x63, 0xb7, 0x06, 0xa5, 0xde, 0x27, 0x89, 0xb6, 0xd6, 0x7f, 0xfd, 0xdd, + 0xff, 0x5e, 0xae, 0xb1, 0x7d, 0x58, 0xbe, 0xbf, 0x3e, 0xae, 0x7c, 0xd6, 0xcb, 0xbf, 0x9b, 0x9f, + 0xcf, 0xc1, 0x39, 0x24, 0xf5, 0x27, 0x94, 0xd4, 0x45, 0x67, 0x04, 0x21, 0x8e, 0x27, 0x8e, 0x21, + 0xc3, 0x42, 0x62, 0xf8, 0xa7, 0x04, 0xf3, 0xea, 0xfc, 0x14, 0x86, 0x06, 0x0a, 0x14, 0x18, 0x97, + 0x88, 0x1e, 0x78, 0xf9, 0x59, 0x51, 0x59, 0x6d, 0xc5, 0x6d, 0xad, 0x70, 0x88, 0x64, 0x12, 0x0d, + 0xad, 0x47, 0x77, 0x05, 0x20, 0x40, 0x04, 0x44, 0x15, 0x8a, 0xdd, 0xc7, 0x6e, 0x24, 0x48, 0x2a, + 0x89, 0x70, 0x57, 0xc5, 0x6f, 0x51, 0x71, 0x4c, 0x53, 0x14, 0x31, 0xdd, 0x85, 0x19, 0x40, 0x1c, + 0x7a, 0x30, 0x4f, 0x3d, 0xb6, 0xde, 0xdb, 0x6d, 0xb7, 0xb6, 0xdf, 0x0b, 0x92, 0x00, 0xc1, 0x6b, + 0x21, 0x8a, 0x26, 0xd1, 0xe0, 0xf6, 0xee, 0xee, 0xe5, 0xf6, 0x78, 0x16, 0xdd, 0xc5, 0x6f, 0x2c, + 0x32, 0xa0, 0x03, 0x00, 0x3f, 0x90, 0xa0, 0xb6, 0x85, 0x6b, 0xff, 0x6d, 0xb7, 0x3f, 0x2a, 0xcc, + 0x34, 0x88, 0x04, 0x85, 0x90, 0x37, 0xdc, 0x7f, 0xfe, 0xbf, 0x63, 0x91, 0x40, 0x17, 0x7e, 0x29, + 0x20, 0xc6, 0x1a, 0x24, 0x09, 0x01, 0x45, 0x3d, 0x9f, 0x5a, 0xff, 0x99, 0x31, 0x6c, 0x83, 0x46, + 0x29, 0x3b, 0x82, 0x10, 0x15, 0x20, 0xa8, 0xe2, 0xb1, 0x5d, 0xea, 0xab, 0x17, 0x75, 0xee, 0x19, + 0x00, 0xa8, 0x17, 0xca, 0xc4, 0x2b, 0x80, 0x0f, 0xaf, 0xf9, 0x5c, 0x5f, 0xf7, 0xff, 0xde, 0xf0, + 0xd1, 0x0c, 0x01, 0xbd, 0xca, 0x2d, 0xff, 0xfd, 0x6a, 0xd8, 0x5e, 0x2c, 0x03, 0xfc, 0xa3, 0x8b, + 0x5f, 0xff, 0xa3, 0x9c, 0x6b, 0x28, 0x1a, 0x63, 0xe2, 0xdc, 0x33, 0x46, 0xf6, 0x76, 0x24, 0x3c, + 0x0f, 0x62, 0x3c, 0x30, 0x08, 0x3c, 0x14, 0x02, 0x41, 0x17, 0x77, 0xae, 0x24, 0x04, 0x81, 0x06, + 0x3b, 0xda, 0xf0, 0xd9, 0x41, 0x82, 0xd7, 0x28, 0x20, 0x35, 0xb0, 0x80, 0x5c, 0xc4, 0xe3, 0xdd, + 0x94, 0x10, 0x90, 0x7e, 0x23, 0xae, 0x53, 0xf5, 0xaf, 0xba, 0xbf, 0xe1, 0x3d, 0x2b, 0x6a, 0xff, + 0x84, 0xca, 0x9c, 0x9a, 0x93, 0xd2, 0xfa, 0x24, 0x57, 0xd4, 0xed, 0x5c, 0x9b, 0x55, 0xf0, 0x49, + 0xd4, 0x21, 0x04, 0x92, 0xcb, 0x86, 0x40, 0x48, 0x05, 0xa0, 0xe4, 0xbc, 0x39, 0xcb, 0xdf, 0xf9, + 0xb2, 0xc2, 0x59, 0x9a, 0x07, 0xde, 0x99, 0x3b, 0xa7, 0xf8, 0x44, 0x21, 0xc1, 0x08, 0x30, 0xe1, + 0x80, 0x52, 0x24, 0xab, 0x5a, 0xad, 0x71, 0x21, 0x02, 0x12, 0xf7, 0xf1, 0x84, 0x77, 0x77, 0x8b, + 0xc5, 0xdd, 0xee, 0xe6, 0xee, 0xef, 0x84, 0x40, 0xc2, 0x09, 0x8e, 0x5f, 0x76, 0xe5, 0x75, 0xee, + 0x24, 0x22, 0x08, 0x6b, 0xa7, 0xdc, 0x14, 0x01, 0x60, 0x14, 0x44, 0xf1, 0x45, 0x0c, 0x53, 0xc5, + 0xc5, 0xc7, 0x76, 0x19, 0x94, 0x02, 0x65, 0x98, 0xba, 0x8f, 0x75, 0xef, 0xfb, 0x6d, 0xfa, 0x65, + 0x0b, 0x28, 0x03, 0x51, 0xd1, 0x35, 0x37, 0xbf, 0xdd, 0xcf, 0xdf, 0xd1, 0x5b, 0x16, 0xe2, 0x91, + 0x00, 0x0f, 0x6b, 0xb0, 0xde, 0x01, 0xf4, 0x32, 0xc4, 0x80, 0x6b, 0x34, 0xa9, 0x9e, 0xf5, 0xaf, + 0xfc, 0xec, 0x8e, 0x19, 0x24, 0x01, 0x9a, 0xcf, 0x23, 0x2e, 0xcf, 0xff, 0xad, 0x47, 0xfc, 0x71, + 0x04, 0x00, 0x88, 0x71, 0x6e, 0x17, 0x56, 0x16, 0x70, 0x4c, 0x2d, 0x56, 0x7b, 0x6d, 0xff, 0xf8, + 0x64, 0x06, 0x47, 0x05, 0x02, 0x42, 0x65, 0x1a, 0x41, 0x3e, 0xaa, 0xb8, 0x1c, 0x00, 0x54, 0x84, + 0x8c, 0x2b, 0x15, 0xdc, 0xdd, 0x4b, 0x31, 0x7c, 0x31, 0x09, 0xc5, 0x18, 0xac, 0x57, 0x55, 0x55, + 0x8d, 0x62, 0xc0, 0x4f, 0xce, 0x0a, 0x7b, 0x76, 0x29, 0xc0, 0xdd, 0xa7, 0xb8, 0x98, 0x23, 0x22, + 0xd7, 0xef, 0x08, 0x23, 0xfa, 0xa1, 0x00, 0x20, 0x70, 0x84, 0x59, 0x1d, 0xdd, 0xdd, 0xdd, 0xf0, + 0xcf, 0xc0, 0x44, 0x0a, 0x1c, 0x20, 0x38, 0x28, 0x06, 0xa2, 0x40, 0x0f, 0x44, 0x38, 0x97, 0xaf, + 0x85, 0x85, 0x97, 0xbf, 0xbb, 0x6d, 0x80, 0xd7, 0x03, 0x16, 0x2f, 0x7e, 0xfa, 0xe5, 0x5c, 0x16, + 0x46, 0x16, 0xf7, 0xd2, 0x49, 0x6e, 0xa6, 0x07, 0xc3, 0x34, 0x92, 0x3f, 0xd5, 0x69, 0xa7, 0xef, + 0x94, 0x82, 0xbf, 0xe8, 0xf5, 0xf2, 0xdb, 0x4f, 0xf0, 0xcf, 0x4d, 0xb5, 0x96, 0x12, 0xc3, 0xfc, + 0x12, 0x5b, 0xdb, 0x8a, 0xba, 0xf4, 0xbc, 0x61, 0x09, 0x14, 0xf4, 0x0c, 0xb9, 0xf3, 0x6e, 0x38, + 0xb7, 0xe0, 0x86, 0x9b, 0xe6, 0x6f, 0x82, 0x4d, 0xa6, 0xf9, 0x54, 0x20, 0x04, 0x80, 0xa1, 0x85, + 0x0c, 0x47, 0x8a, 0x67, 0x7b, 0x99, 0xcf, 0x9f, 0x8a, 0x72, 0x43, 0x17, 0x71, 0x3e, 0x99, 0x66, + 0x5e, 0x01, 0x8d, 0xc4, 0x09, 0x12, 0x76, 0x7a, 0xd3, 0xb9, 0x4b, 0x35, 0xc6, 0x16, 0xaa, 0xb5, + 0x55, 0xd5, 0x6a, 0xbf, 0x17, 0xad, 0x73, 0x67, 0x08, 0x78, 0x31, 0x03, 0x88, 0x53, 0x15, 0xac, + 0xb8, 0x7f, 0xa6, 0x1f, 0x6a, 0xaa, 0x95, 0x32, 0xda, 0x6f, 0x17, 0x12, 0x10, 0x1e, 0x28, 0x5c, + 0x5f, 0x55, 0xdd, 0xdf, 0x85, 0xc8, 0x2c, 0x00, 0xc1, 0xad, 0x4d, 0xbe, 0xbb, 0x13, 0xee, 0xe9, + 0xbe, 0x5f, 0xbb, 0xbb, 0xe1, 0x85, 0x00, 0x80, 0x51, 0xb1, 0x82, 0x5e, 0x5d, 0xdb, 0x6f, 0xff, + 0xf6, 0x18, 0x70, 0x04, 0x83, 0x58, 0x68, 0x2d, 0x66, 0xdb, 0x7b, 0x6d, 0xff, 0x5f, 0xe1, 0xac, + 0x06, 0x0c, 0x81, 0x51, 0xff, 0xa6, 0x9e, 0x99, 0x7f, 0x61, 0x97, 0x00, 0x2a, 0xb9, 0xc3, 0xe9, + 0x04, 0xdb, 0xe7, 0xef, 0x7d, 0x6b, 0x4e, 0x9a, 0x55, 0x18, 0x42, 0x00, 0x85, 0xd4, 0xc2, 0x0f, + 0xf8, 0xe5, 0x04, 0x0c, 0xaa, 0xfb, 0xe3, 0x89, 0x04, 0xa3, 0xf5, 0x57, 0xf1, 0x22, 0x62, 0xea, + 0xb5, 0x5f, 0x04, 0x02, 0x4d, 0x77, 0x7f, 0x8a, 0xd6, 0xa8, 0x6b, 0xe0, 0xa0, 0x18, 0x70, 0x24, + 0x80, 0xe8, 0x47, 0xf7, 0x06, 0x00, 0xe0, 0x14, 0xea, 0x95, 0x6b, 0xba, 0x6f, 0xc7, 0xe1, 0x4c, + 0x01, 0x0f, 0x58, 0xca, 0x40, 0x9e, 0xff, 0x6d, 0xbd, 0xb6, 0xe1, 0xa7, 0x0d, 0x19, 0x6a, 0xff, + 0xff, 0xdc, 0x22, 0x0a, 0x15, 0xb0, 0xd3, 0x82, 0x95, 0x95, 0xfe, 0x9a, 0x7f, 0xf7, 0x10, 0x0a, + 0x31, 0x18, 0x08, 0x99, 0x36, 0x12, 0x16, 0x45, 0x00, 0x48, 0xf2, 0x1d, 0xa9, 0xbd, 0x7f, 0xfb, + 0x7f, 0x04, 0x20, 0x22, 0x05, 0x08, 0x6c, 0x5d, 0xef, 0x7f, 0x87, 0xc4, 0x0d, 0xac, 0x67, 0xbc, + 0xbc, 0x4b, 0xdd, 0xc4, 0x80, 0xf6, 0xe1, 0x3c, 0xb0, 0xc9, 0xc3, 0x10, 0x10, 0x12, 0x22, 0xe5, + 0x11, 0x77, 0x83, 0x52, 0xef, 0x5d, 0x1f, 0xbe, 0x4b, 0xd0, 0xd8, 0xfc, 0x13, 0x6e, 0xad, 0xb4, + 0xd5, 0xeb, 0xea, 0x6b, 0xe0, 0x96, 0x6d, 0x74, 0xad, 0xa7, 0xd7, 0xcb, 0xcb, 0x9f, 0x04, 0x94, + 0xa5, 0x61, 0x8e, 0x55, 0xca, 0x54, 0x9c, 0x56, 0xd9, 0x38, 0x2c, 0xa6, 0xd5, 0xab, 0x56, 0xb2, + 0x7d, 0x7d, 0x5e, 0xb8, 0x8b, 0xde, 0x4d, 0x74, 0xdc, 0x9c, 0x11, 0xf3, 0xf9, 0x01, 0x50, 0x88, + 0x1c, 0x01, 0x48, 0xc5, 0xac, 0x4f, 0x8a, 0x6a, 0xa6, 0xe2, 0xe2, 0x7c, 0xef, 0x28, 0x5c, 0x48, + 0x41, 0xc3, 0xe9, 0x22, 0x97, 0x51, 0x02, 0x78, 0x42, 0x24, 0x4d, 0xee, 0x9d, 0xf8, 0x47, 0xc1, + 0x07, 0xc1, 0x48, 0x27, 0xbd, 0xef, 0x69, 0x7b, 0x86, 0x43, 0x03, 0x2e, 0xaf, 0x5a, 0x62, 0xb7, + 0x4b, 0x15, 0x8a, 0x31, 0x58, 0x81, 0xf8, 0x20, 0x06, 0x00, 0x98, 0x82, 0xea, 0x6e, 0x77, 0xec, + 0x62, 0xb3, 0xb1, 0xd8, 0xa9, 0xc1, 0x07, 0x1c, 0x74, 0x86, 0x08, 0x50, 0xe4, 0xae, 0xfe, 0xb5, + 0xf8, 0xbc, 0x5f, 0x5c, 0x04, 0xc8, 0x0c, 0x80, 0xa1, 0x84, 0x07, 0x97, 0x9d, 0xf8, 0xb9, 0x7f, + 0x35, 0xc5, 0x77, 0x6f, 0x8c, 0x8b, 0x88, 0xf5, 0xea, 0xfd, 0x5d, 0xef, 0xe0, 0x80, 0x41, 0x54, + 0x5f, 0x51, 0x74, 0xdb, 0xc2, 0x01, 0x10, 0x85, 0x6b, 0x4d, 0xcb, 0xcb, 0x7b, 0x88, 0x72, 0x16, + 0x21, 0x07, 0x2a, 0xff, 0xfd, 0x78, 0x88, 0xae, 0xee, 0xf7, 0xe1, 0x18, 0x9b, 0xb8, 0xaf, 0x9b, + 0xf0, 0x10, 0x00, 0x2a, 0x78, 0x10, 0x21, 0x02, 0xc5, 0x6e, 0xf5, 0x51, 0x75, 0x52, 0x79, 0x85, + 0x9c, 0x10, 0x32, 0xb7, 0xaf, 0xff, 0xeb, 0x1a, 0x84, 0x80, 0xeb, 0x6b, 0x91, 0xdc, 0x34, 0x43, + 0x00, 0xc1, 0x2b, 0xa8, 0xdf, 0xff, 0xfd, 0x8a, 0xc1, 0x1f, 0xbf, 0x91, 0xcc, 0x81, 0xc7, 0x49, + 0xfc, 0x14, 0x0c, 0x3a, 0x62, 0xb4, 0xc5, 0x75, 0x7c, 0x57, 0xbd, 0xfc, 0x10, 0x70, 0x24, 0x80, + 0xb1, 0x08, 0x5d, 0xf5, 0x57, 0xd2, 0x15, 0x88, 0x73, 0x82, 0x0f, 0x97, 0xab, 0x58, 0x90, 0x11, + 0x00, 0xa8, 0x61, 0x58, 0xa5, 0xc4, 0x61, 0x53, 0xfd, 0x85, 0xaf, 0x85, 0xab, 0x03, 0xa8, 0x25, + 0xce, 0x00, 0x02, 0x50, 0x05, 0xeb, 0x81, 0x88, 0x04, 0xac, 0x90, 0x09, 0x42, 0x11, 0x90, 0x82, + 0xb8, 0x6c, 0xfb, 0x28, 0x89, 0x07, 0xfe, 0x8f, 0xaf, 0x82, 0xdd, 0x27, 0xd2, 0xa6, 0xff, 0x21, + 0x13, 0xdb, 0x5d, 0x94, 0xdb, 0xa6, 0x4e, 0x0a, 0xf9, 0x3b, 0x71, 0xcb, 0x9e, 0x5d, 0xcf, 0x5c, + 0xd7, 0x7d, 0x77, 0xcb, 0xfe, 0x2e, 0xf5, 0x4e, 0xed, 0xcb, 0xc1, 0x0f, 0x97, 0x22, 0xf8, 0xba, + 0xef, 0xb6, 0xdf, 0x82, 0x72, 0x2a, 0xd6, 0x1b, 0x0f, 0x0b, 0x8c, 0x04, 0x51, 0x5c, 0x9b, 0xe2, + 0x4c, 0x5f, 0x1f, 0x77, 0xf4, 0xd4, 0x44, 0x58, 0x94, 0xeb, 0xd5, 0x71, 0x31, 0x75, 0xd7, 0x53, + 0x31, 0xc4, 0x14, 0x86, 0xff, 0x89, 0x04, 0x06, 0x13, 0x7b, 0xe0, 0x82, 0xad, 0xc3, 0x22, 0x42, + 0x97, 0x7e, 0xaa, 0x27, 0xed, 0xbe, 0x6e, 0xf8, 0xc7, 0x70, 0xcc, 0x28, 0x4d, 0x56, 0xf1, 0x5c, + 0xaf, 0x1f, 0xc9, 0xef, 0xb8, 0x18, 0x43, 0x23, 0x22, 0xb8, 0x85, 0x62, 0xb0, 0x7a, 0xc4, 0x6d, + 0xc8, 0x47, 0x0b, 0x0b, 0xea, 0x68, 0x80, 0xe5, 0xb8, 0x74, 0x06, 0xd0, 0x58, 0xf0, 0x88, 0x80, + 0xa1, 0x08, 0xc2, 0x19, 0x7a, 0x1c, 0xde, 0xa2, 0xe9, 0xc5, 0xc5, 0x78, 0xad, 0xf0, 0xb2, 0x80, + 0x3f, 0xa9, 0x82, 0xb7, 0xdf, 0xad, 0x56, 0x4f, 0x4e, 0x9f, 0x01, 0xa0, 0x03, 0x84, 0x61, 0xc5, + 0x03, 0x14, 0x31, 0x71, 0x75, 0xaa, 0x97, 0x64, 0x18, 0x8d, 0x62, 0xdc, 0x57, 0x0d, 0x60, 0x19, + 0xd4, 0xea, 0x6b, 0xf5, 0xaf, 0xdf, 0x84, 0x20, 0xb6, 0xf7, 0xd5, 0x57, 0xb0, 0xd6, 0x1e, 0x11, + 0x32, 0x1b, 0xaf, 0xff, 0xb6, 0xff, 0x15, 0xbd, 0xdd, 0xdf, 0xc4, 0x9a, 0xab, 0xf8, 0x2d, 0xd6, + 0xa4, 0xf5, 0xb7, 0xd7, 0xb8, 0x60, 0x1c, 0x02, 0xa2, 0x9f, 0xcb, 0xe5, 0x6d, 0xb6, 0x97, 0xd8, + 0x69, 0x42, 0x03, 0xbc, 0x4b, 0xff, 0xeb, 0xbe, 0x13, 0x70, 0x48, 0x32, 0xdf, 0xbf, 0xd6, 0xfd, + 0xb5, 0xae, 0x11, 0x01, 0xd0, 0x4d, 0x57, 0xe2, 0xf9, 0x73, 0xbb, 0xc2, 0xce, 0x0b, 0x2d, 0x34, + 0xeb, 0xb7, 0xff, 0xbc, 0x4b, 0x38, 0x20, 0xa6, 0x9f, 0x91, 0x4c, 0xc5, 0x43, 0x86, 0x00, 0x48, + 0x70, 0x80, 0x12, 0x2a, 0x22, 0x49, 0xba, 0x74, 0xf0, 0x62, 0x04, 0x00, 0xa0, 0xce, 0x56, 0x0d, + 0xd2, 0x4e, 0xd8, 0xbd, 0x66, 0x52, 0xaa, 0x8a, 0xb7, 0x04, 0x6f, 0xb1, 0x36, 0xd7, 0xe4, 0xbb, + 0x76, 0xfc, 0x11, 0x6d, 0x5a, 0x8b, 0xe4, 0xdd, 0xd5, 0x77, 0xdd, 0x27, 0xcd, 0x6f, 0x6f, 0xc5, + 0x6d, 0x9f, 0x3d, 0x34, 0xc9, 0xc1, 0x0c, 0x9f, 0xfb, 0xe6, 0xe9, 0x9b, 0xf8, 0xba, 0x49, 0x75, + 0xbf, 0xcb, 0x7d, 0xb5, 0xcb, 0xc9, 0xd3, 0xf7, 0x75, 0xb7, 0x86, 0x40, 0xf0, 0x38, 0x60, 0xa3, + 0x14, 0x6e, 0x3e, 0xa2, 0xbe, 0xe6, 0xc7, 0x60, 0xbb, 0x19, 0xe2, 0x3c, 0x40, 0xb3, 0xee, 0xfb, + 0xbf, 0x82, 0x91, 0x2d, 0xad, 0x56, 0xbd, 0xc5, 0x6f, 0xe1, 0x13, 0x12, 0xaf, 0xc4, 0x84, 0x42, + 0x22, 0x1b, 0xaf, 0x2e, 0x08, 0x1c, 0xc2, 0x82, 0xa3, 0xcf, 0x3c, 0x14, 0x0b, 0x6e, 0x54, 0x5d, + 0x38, 0xae, 0x2b, 0x6c, 0xea, 0x04, 0x5f, 0xd9, 0xd1, 0x44, 0x82, 0x61, 0x65, 0x55, 0xe0, 0x8e, + 0xed, 0x8a, 0xdb, 0xee, 0x0a, 0x20, 0xaa, 0xef, 0x5d, 0xd3, 0xf2, 0x7e, 0xc2, 0x98, 0x01, 0x9c, + 0x49, 0x8d, 0x92, 0x57, 0x77, 0x89, 0x17, 0x32, 0x6c, 0x74, 0xff, 0xf0, 0x0b, 0x40, 0x0a, 0x81, + 0x96, 0xe1, 0x70, 0xb6, 0x7b, 0xcf, 0xf1, 0x00, 0x1c, 0x92, 0xcd, 0xac, 0x40, 0x7e, 0x94, 0x57, + 0x0b, 0x22, 0x00, 0xbd, 0xc1, 0xe6, 0xe1, 0xf6, 0xbb, 0xa7, 0xff, 0xb2, 0xc2, 0xd8, 0x26, 0xe7, + 0x57, 0x2d, 0x7f, 0xfd, 0xbc, 0x02, 0x70, 0x02, 0x44, 0x49, 0x45, 0xd6, 0xfa, 0xae, 0x01, 0x40, + 0x06, 0x23, 0xe2, 0x0e, 0x08, 0x38, 0xbc, 0x57, 0xea, 0xbe, 0x0a, 0xbb, 0xbe, 0xef, 0x8b, 0x8b, + 0xf7, 0x01, 0xc0, 0x02, 0xa4, 0x14, 0x49, 0xf1, 0xe9, 0x5f, 0xdc, 0x30, 0x11, 0x04, 0x3e, 0x7f, + 0xd8, 0xa7, 0x26, 0xc2, 0x91, 0x20, 0x08, 0x3d, 0xc5, 0x41, 0x79, 0xef, 0xf7, 0xd6, 0xb5, 0x89, + 0x50, 0x42, 0xff, 0x6c, 0x02, 0x20, 0x02, 0x64, 0x11, 0x13, 0x6c, 0xcc, 0xbf, 0x01, 0xe0, 0x02, + 0xe4, 0x64, 0x57, 0x2d, 0xb6, 0xa2, 0xeb, 0x10, 0xfa, 0xde, 0xaa, 0xab, 0x14, 0xa0, 0x30, 0x2f, + 0x88, 0xd0, 0x3f, 0x43, 0x58, 0x7c, 0x61, 0x1f, 0x7b, 0xff, 0xd6, 0x33, 0x07, 0x45, 0x8f, 0x8a, + 0xc2, 0x39, 0x1b, 0x47, 0x48, 0x02, 0xbc, 0x4b, 0x69, 0x9f, 0x88, 0x03, 0x80, 0xc3, 0x3b, 0xbb, + 0xbb, 0xe2, 0xbb, 0x9b, 0xaa, 0x97, 0x8b, 0xc5, 0x33, 0x81, 0x2d, 0xca, 0x36, 0x04, 0x10, 0x40, + 0x5e, 0x29, 0x8b, 0xe0, 0xc0, 0x0a, 0x06, 0x23, 0xdc, 0x57, 0x83, 0x18, 0x29, 0x83, 0x92, 0xf0, + 0x58, 0x26, 0x59, 0xad, 0x61, 0x68, 0xe2, 0x4c, 0xe4, 0x53, 0x81, 0x87, 0x52, 0x8b, 0xd3, 0x13, + 0xe8, 0xb9, 0x49, 0x88, 0x04, 0x5a, 0xaf, 0xaf, 0x92, 0x6d, 0xf7, 0xca, 0x6a, 0xd3, 0x5c, 0x59, + 0xf4, 0x92, 0x4e, 0x46, 0xb1, 0xf8, 0x4a, 0xf7, 0x49, 0x2a, 0x5f, 0x75, 0x77, 0xf9, 0xb6, 0xef, + 0xef, 0x59, 0xba, 0xe1, 0x71, 0x0a, 0x27, 0x8a, 0x1d, 0x18, 0x45, 0x03, 0xa6, 0x12, 0xa7, 0x00, + 0x01, 0x00, 0x05, 0x06, 0xa3, 0x04, 0x50, 0x89, 0x00, 0x04, 0xa1, 0x59, 0x95, 0x8d, 0xf4, 0xf7, + 0xfe, 0x07, 0x00, 0x24, 0x8d, 0x39, 0x1c, 0x43, 0x14, 0x3b, 0xaf, 0xab, 0xaa, 0xc5, 0x38, 0x70, + 0x51, 0xa8, 0xbd, 0x46, 0x8d, 0x5f, 0xdf, 0xfc, 0x0b, 0x00, 0x59, 0x0a, 0x5d, 0xf8, 0xb9, 0xf4, + 0xbf, 0x77, 0x6d, 0x21, 0x23, 0xcb, 0x68, 0xc5, 0x43, 0x44, 0x20, 0x13, 0x5b, 0x38, 0xef, 0xef, + 0xff, 0x4e, 0xe3, 0xa5, 0x09, 0x5a, 0xa2, 0xb0, 0xb2, 0x80, 0x58, 0x7c, 0x52, 0xbb, 0xd5, 0x55, + 0x5e, 0xf5, 0xae, 0x17, 0x62, 0x00, 0x0c, 0x2c, 0x83, 0x47, 0x51, 0x90, 0x25, 0x38, 0x6f, 0x4c, + 0x7e, 0x89, 0xb6, 0xe7, 0xee, 0x7b, 0xc7, 0x7e, 0x3a, 0xbd, 0x6e, 0xe4, 0x62, 0xee, 0x02, 0xa0, + 0x1c, 0x85, 0x0e, 0x54, 0x01, 0x7a, 0x16, 0x65, 0x40, 0x12, 0xd0, 0xbc, 0x50, 0xc5, 0xc5, 0xe2, + 0xe2, 0x6b, 0x33, 0xde, 0xf7, 0x71, 0x5f, 0xb1, 0xac, 0x48, 0x0a, 0x12, 0x63, 0x99, 0x33, 0x81, + 0xc0, 0x09, 0x00, 0x9b, 0xb6, 0x5f, 0x7b, 0xf1, 0xfc, 0x0d, 0x00, 0x60, 0x51, 0xd8, 0xfe, 0x24, + 0x0b, 0x00, 0x9f, 0xcd, 0xd4, 0xb3, 0x51, 0x4c, 0x76, 0x3f, 0x0c, 0x28, 0x0a, 0x59, 0x38, 0x15, + 0x65, 0x7f, 0xfd, 0xf1, 0x88, 0xc0, 0x0f, 0x64, 0x34, 0xb5, 0x4f, 0x85, 0x89, 0x00, 0xcf, 0x08, + 0xf5, 0xaf, 0x4d, 0x3f, 0xe8, 0xa8, 0xa1, 0x45, 0x04, 0x48, 0xad, 0x6d, 0xf6, 0xff, 0xf8, 0x62, + 0x50, 0x79, 0x11, 0xff, 0xfb, 0xdd, 0xdc, 0x02, 0xf1, 0x05, 0x3d, 0xb5, 0xbd, 0xd5, 0x45, 0xc9, + 0xfd, 0x8c, 0x45, 0x00, 0xc7, 0x99, 0x7a, 0xec, 0x28, 0xa0, 0x17, 0x63, 0x54, 0xe5, 0x5a, 0xff, + 0xfc, 0x56, 0x24, 0x39, 0x0b, 0x60, 0x0a, 0x7f, 0x44, 0x61, 0x3f, 0xfe, 0xb5, 0x85, 0xb0, 0x1f, + 0x72, 0x6f, 0xdd, 0x5d, 0x7f, 0xe1, 0x3c, 0x01, 0xbd, 0x6a, 0x71, 0xe5, 0x75, 0xff, 0xfe, 0x0c, + 0x02, 0x00, 0x92, 0xb5, 0xbb, 0x1c, 0xe0, 0x4f, 0xfd, 0x84, 0x77, 0x80, 0x60, 0x01, 0xc0, 0x2a, + 0x30, 0xba, 0xac, 0x5c, 0x53, 0xab, 0xb8, 0xac, 0x57, 0xd8, 0xa5, 0x01, 0x8c, 0xd6, 0x88, 0xc9, + 0x40, 0x3b, 0x0f, 0x92, 0x8a, 0xc7, 0x48, 0x05, 0x68, 0x07, 0x49, 0xf0, 0xce, 0x00, 0x53, 0x96, + 0x11, 0xa3, 0x85, 0x13, 0xe7, 0x97, 0x5b, 0xc5, 0x6b, 0x57, 0x77, 0x77, 0x1c, 0xd8, 0xe6, 0x60, + 0xd8, 0x75, 0x93, 0x62, 0x90, 0x90, 0x46, 0x70, 0xa9, 0x43, 0x18, 0x03, 0x08, 0x4d, 0x66, 0x13, + 0xf4, 0xf5, 0x55, 0x5f, 0x5f, 0xdc, 0x18, 0x81, 0x40, 0x16, 0x90, 0x56, 0xee, 0x2b, 0x14, 0xc5, + 0xc5, 0x03, 0x10, 0x1f, 0x58, 0x72, 0x40, 0x53, 0x12, 0x2e, 0x28, 0x49, 0xd7, 0x69, 0xac, 0xd7, + 0xdd, 0x3e, 0xbd, 0x1f, 0xd6, 0x3a, 0x5f, 0xbf, 0x0c, 0x1d, 0x5e, 0x35, 0xc3, 0x21, 0xc6, 0xb9, + 0x77, 0x67, 0x9f, 0xe4, 0xe6, 0x3d, 0x3a, 0x64, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x54, + 0x2a, 0x30, 0xa8, 0x2f, 0xd0, 0xf8, 0xaa, 0x02, 0x04, 0x30, 0x4a, 0xaa, 0xaf, 0x08, 0x08, 0x0a, + 0x72, 0x62, 0xa9, 0x66, 0xbc, 0x48, 0xb1, 0x78, 0xcb, 0xa3, 0xdd, 0xf0, 0x10, 0x00, 0xa7, 0xc2, + 0x1f, 0xe1, 0x91, 0x37, 0xc1, 0x20, 0x9c, 0x4f, 0x04, 0xf3, 0xa2, 0xf1, 0x08, 0xa8, 0xef, 0x13, + 0xbe, 0xb5, 0x08, 0xf5, 0x69, 0xfa, 0xd4, 0xdd, 0x52, 0xae, 0x10, 0x05, 0x81, 0x4b, 0xaf, 0x77, + 0x17, 0x18, 0x56, 0xe3, 0x15, 0xef, 0x89, 0xdc, 0x4b, 0x04, 0x4e, 0x61, 0xff, 0xf1, 0x38, 0xc4, + 0x17, 0x4b, 0xaf, 0xaf, 0x78, 0x20, 0x05, 0x01, 0x29, 0xb0, 0x6f, 0x33, 0xc0, 0xc0, 0x1d, 0x2c, + 0x12, 0x07, 0x03, 0x99, 0x29, 0x65, 0x15, 0x1d, 0xe2, 0x01, 0x00, 0xc1, 0x55, 0x37, 0x2c, 0xcb, + 0x33, 0xb8, 0x14, 0xa8, 0xf7, 0x85, 0x98, 0x3e, 0xd0, 0x3e, 0x6a, 0x58, 0x03, 0x24, 0x05, 0x4b, + 0x01, 0x96, 0x00, 0xc5, 0x07, 0x84, 0x01, 0x40, 0x92, 0x93, 0x93, 0x96, 0xd7, 0x26, 0x05, 0x06, + 0x55, 0x49, 0x81, 0x46, 0x4e, 0x53, 0x05, 0xe8, 0x2b, 0x5f, 0x5a, 0xfa, 0xd4, 0xdd, 0x6a, 0x6e, + 0xb9, 0x43, 0x3f, 0x84, 0x01, 0x40, 0xc0, 0x93, 0x76, 0xe6, 0x20, 0xc1, 0x8b, 0xa1, 0xc5, 0xea, + 0x2e, 0x0b, 0x73, 0x81, 0x57, 0x26, 0x78, 0x20, 0x13, 0x22, 0x82, 0x28, 0x62, 0x86, 0x28, 0xd6, + 0xf8, 0x10, 0x28, 0x11, 0x88, 0xba, 0x48, 0x31, 0x02, 0xc0, 0x27, 0x0f, 0x71, 0xae, 0x6e, 0x48, + 0x41, 0x62, 0x93, 0x0b, 0x83, 0x10, 0x2c, 0x0e, 0x10, 0x4e, 0x1c, 0x1c, 0x07, 0x0b, 0x36, 0x28, + 0x38, 0xe3, 0x32, 0xdf, 0xc9, 0xed, 0x9a, 0x7b, 0xf1, 0x20, 0x40, 0x16, 0x2e, 0xdb, 0xe2, 0x7e, + 0x2f, 0x84, 0x22, 0x45, 0x39, 0x39, 0x4c, 0x49, 0xe9, 0x89, 0x7c, 0x4d, 0x82, 0x74, 0x19, 0xe8, + 0x27, 0x14, 0xa1, 0x8c, 0x23, 0xcc, 0x2a, 0xb3, 0x7f, 0x30, 0xc9, 0xbf, 0xc2, 0x23, 0x2f, 0x1f, + 0x5d, 0x75, 0x7e, 0xfa, 0xd7, 0x03, 0x88, 0x60, 0x11, 0x8b, 0x3f, 0xc0, 0x77, 0x93, 0x85, 0x07, + 0x6e, 0xda, 0x92, 0x0a, 0xa6, 0x58, 0x0c, 0xb1, 0x2f, 0x0f, 0x95, 0x19, 0xc4, 0x3c, 0xb0, 0x19, + 0x60, 0xc2, 0xea, 0xbf, 0x08, 0x08, 0x12, 0x35, 0xd5, 0xaa, 0xb5, 0x6e, 0xe2, 0x0e, 0x16, 0x70, + 0x03, 0x1e, 0xb3, 0x16, 0x75, 0xd7, 0xbf, 0xff, 0x55, 0x86, 0xd8, 0x80, 0x28, 0xb8, 0x9f, 0xe2, + 0xb9, 0x15, 0xaf, 0x8a, 0xe2, 0x06, 0x0b, 0xeb, 0xfa, 0xc1, 0x5e, 0x11, 0xe2, 0x20, 0x9c, 0x6c, + 0xcb, 0xf6, 0x39, 0x99, 0xee, 0x22, 0x61, 0x8b, 0x5e, 0x10, 0x05, 0x0f, 0x6e, 0x73, 0x38, 0x46, + 0x26, 0xdd, 0xfa, 0xab, 0x84, 0x62, 0x8b, 0x58, 0x4d, 0xd2, 0x8f, 0x3e, 0xb1, 0xe1, 0x11, 0x0c, + 0xc7, 0x01, 0xc8, 0xdc, 0x57, 0xf1, 0x23, 0x4d, 0x9f, 0x6d, 0xf8, 0x40, 0x15, 0x56, 0xb5, 0xdf, + 0x17, 0x0b, 0x95, 0x47, 0xf8, 0x91, 0x22, 0x84, 0xaa, 0x37, 0xfb, 0x7a, 0xe0, 0xb2, 0x20, 0x20, + 0x28, 0x5b, 0xd1, 0xcf, 0xe5, 0xa7, 0x89, 0x04, 0x00, 0xb8, 0xca, 0xb3, 0x5d, 0x7b, 0x88, 0x12, + 0x11, 0xaa, 0x46, 0x63, 0x55, 0x55, 0x2f, 0x66, 0x2e, 0xfc, 0x20, 0x24, 0xce, 0x7e, 0x9b, 0xf6, + 0x6c, 0x89, 0x3d, 0x42, 0x3e, 0x0c, 0x40, 0x50, 0x0c, 0xf3, 0x7b, 0xc5, 0x73, 0x77, 0x77, 0x52, + 0xf9, 0x76, 0xf8, 0x26, 0x12, 0x45, 0x19, 0xca, 0xcd, 0x25, 0x61, 0x00, 0x49, 0xaa, 0x8e, 0x66, + 0xdc, 0x10, 0x81, 0x40, 0x13, 0x10, 0x48, 0x58, 0x85, 0x83, 0x57, 0x32, 0xde, 0x9d, 0x0c, 0xe6, + 0x1e, 0xef, 0xc6, 0x2c, 0xa9, 0x14, 0x2d, 0x8b, 0xe5, 0x08, 0x76, 0x6d, 0x54, 0xb0, 0x88, 0x9e, + 0x10, 0x08, 0x10, 0x24, 0xab, 0xe2, 0x03, 0x02, 0xaa, 0x2e, 0xb5, 0xa9, 0x19, 0xe1, 0x0a, 0x0c, + 0x20, 0x9f, 0xfd, 0xbf, 0xfd, 0xc2, 0x21, 0x01, 0xe1, 0x69, 0xbd, 0x64, 0xe7, 0xe2, 0x64, 0x18, + 0xe5, 0x3c, 0x4c, 0x15, 0x8b, 0xac, 0xac, 0x1b, 0x61, 0x85, 0xaa, 0xc5, 0xcf, 0xb0, 0xd6, 0x2e, + 0xee, 0x9f, 0x89, 0x11, 0xc2, 0x22, 0x46, 0x08, 0x17, 0x17, 0x17, 0x55, 0x8c, 0x98, 0x52, 0xee, + 0x29, 0x14, 0x2c, 0x95, 0xb3, 0x0b, 0xd2, 0x57, 0xaf, 0xec, 0xa2, 0x83, 0x6d, 0x77, 0xbf, 0x04, + 0x21, 0x1d, 0x56, 0xaf, 0xa2, 0xa3, 0xe4, 0xe8, 0x8e, 0x04, 0x75, 0x74, 0x37, 0x84, 0x38, 0x21, + 0xfc, 0x14, 0x04, 0x37, 0x77, 0xb9, 0x18, 0x97, 0xc6, 0x11, 0xee, 0xe6, 0x62, 0x37, 0x31, 0x1b, + 0xbf, 0x3e, 0xc1, 0xde, 0x2e, 0x77, 0xf8, 0x43, 0x55, 0x97, 0xe7, 0x93, 0x3c, 0x33, 0xc1, 0x48, + 0x43, 0x89, 0x12, 0x14, 0xee, 0x6e, 0xe6, 0x5b, 0x59, 0x66, 0xb8, 0x92, 0xc1, 0xb9, 0x61, 0xc7, + 0x4d, 0x7b, 0x86, 0x43, 0x02, 0x05, 0xda, 0x95, 0x6d, 0xbc, 0x95, 0xc6, 0xff, 0xc4, 0x84, 0x41, + 0x39, 0xaa, 0xa2, 0xfa, 0x65, 0x8f, 0xbe, 0x14, 0x24, 0xb1, 0x19, 0x54, 0x6c, 0x32, 0xce, 0xfb, + 0xbd, 0x4c, 0x71, 0xbb, 0xbd, 0xeb, 0x82, 0x00, 0x28, 0xdf, 0x41, 0x57, 0xfa, 0xf7, 0xd1, 0x5e, + 0x7e, 0x88, 0xff, 0x57, 0xac, 0x4a, 0xbf, 0xd5, 0xfe, 0xaf, 0x1f, 0xcd, 0xbd, 0xcf, 0xc9, 0xd5, + 0x4a, 0x21, 0x90, 0xf4, 0x87, 0x10, 0x80, 0x01, 0xaa, 0xb6, 0x25, 0x45, 0x67, 0x3d, 0x5e, 0xf5, + 0x2f, 0x89, 0xff, 0xae, 0x08, 0x40, 0x17, 0x5e, 0xff, 0x04, 0x00, 0x9c, 0xc1, 0x73, 0x42, 0x4a, + 0xb7, 0x54, 0xa8, 0xac, 0xe1, 0x81, 0xf0, 0x9c, 0x72, 0xef, 0x12, 0x32, 0x5e, 0x9e, 0xad, 0x60, + 0xcb, 0x41, 0x97, 0x85, 0x45, 0x64, 0xf0, 0x79, 0xfe, 0xa1, 0x42, 0xd8, 0x7f, 0x20, 0xf0, 0x50, + 0x19, 0x0c, 0x09, 0xe2, 0xac, 0x9a, 0xb3, 0x9c, 0x03, 0xe0, 0xd4, 0x42, 0x68, 0x46, 0x58, 0xb6, + 0x2d, 0xfc, 0x38, 0x88, 0x00, 0x29, 0x4f, 0xe2, 0xd0, 0xe8, 0xbf, 0xd3, 0x4e, 0x31, 0x6e, 0xe5, + 0xf1, 0xe5, 0xe6, 0xfb, 0x7e, 0x08, 0x04, 0x8a, 0x37, 0x2f, 0x17, 0x11, 0xeb, 0x34, 0xbc, 0x50, + 0xbd, 0x54, 0x5d, 0x61, 0x19, 0xcf, 0x31, 0x11, 0x82, 0x25, 0x58, 0xd4, 0xb4, 0x00, 0x91, 0xca, + 0x54, 0x9f, 0x0f, 0xd2, 0x4a, 0x8d, 0x9f, 0xbb, 0xbe, 0x01, 0x38, 0x02, 0x4b, 0x09, 0x85, 0xd5, + 0xbe, 0x16, 0xe6, 0xd6, 0x2e, 0x17, 0x83, 0x18, 0x24, 0x93, 0x04, 0xf2, 0x28, 0x7d, 0xc0, 0x92, + 0x03, 0x60, 0x28, 0x20, 0x56, 0x2b, 0x15, 0xb9, 0xf4, 0xbe, 0x22, 0x47, 0x16, 0x2b, 0x12, 0x3f, + 0x65, 0x20, 0x7d, 0xab, 0x1a, 0x2a, 0x6e, 0x0e, 0x40, 0x64, 0x0c, 0x20, 0xb8, 0x59, 0x59, 0xc7, + 0x43, 0xc0, 0xee, 0x1a, 0xea, 0x5b, 0x3e, 0x27, 0xc5, 0xcf, 0x3f, 0x80, 0xd8, 0x0a, 0x43, 0xb6, + 0xa1, 0xd8, 0x1a, 0x9e, 0x1c, 0x5d, 0xf2, 0x80, 0x8f, 0x90, 0x5c, 0x58, 0x6b, 0xd6, 0x4c, 0x01, + 0x56, 0x73, 0x80, 0x3e, 0x5c, 0xdd, 0xf8, 0xb8, 0x14, 0x40, 0x21, 0x00, 0xaa, 0x59, 0x9c, 0x78, + 0xbb, 0x7b, 0x37, 0x2c, 0x6e, 0x25, 0xfb, 0x42, 0x87, 0x2e, 0x20, 0x1c, 0x0e, 0x88, 0x38, 0xcf, + 0x16, 0xa9, 0x4a, 0x20, 0x4b, 0x75, 0x8a, 0x31, 0xf5, 0x15, 0xfc, 0x20, 0x30, 0x91, 0x3b, 0xe4, + 0xcd, 0x0c, 0x5d, 0x45, 0xdc, 0x43, 0x84, 0xd3, 0x95, 0x1e, 0x11, 0x24, 0xe5, 0x20, 0xae, 0xef, + 0x1e, 0xa8, 0x2e, 0xad, 0xdb, 0xe0, 0x13, 0x00, 0x38, 0x82, 0x10, 0xa8, 0xba, 0x7d, 0xf7, 0xf0, + 0xc2, 0x2b, 0xc6, 0xe2, 0x27, 0x18, 0xa0, 0xed, 0x91, 0x4d, 0xd7, 0xbe, 0xb1, 0x4d, 0xd7, 0x29, + 0x46, 0x2d, 0x1f, 0x36, 0x21, 0x7b, 0x81, 0x80, 0x1c, 0x02, 0xc0, 0x85, 0x32, 0x72, 0x41, 0x59, + 0xb8, 0x1d, 0xd2, 0xa7, 0x00, 0xad, 0x33, 0xbf, 0x37, 0x11, 0x99, 0x54, 0x35, 0x80, 0xa8, 0xf2, + 0xa0, 0xf7, 0x6f, 0x7f, 0xff, 0x6f, 0x6f, 0x33, 0x0c, 0xb3, 0x80, 0x09, 0x25, 0x44, 0xc2, 0x90, + 0xce, 0xf3, 0x13, 0xaa, 0x7f, 0xfa, 0xd5, 0xb8, 0x80, 0xc8, 0xc3, 0x0b, 0x62, 0x8c, 0x5b, 0x3e, + 0x09, 0x71, 0xee, 0x2f, 0x22, 0x86, 0x20, 0xfd, 0x45, 0xe1, 0x99, 0xc0, 0x09, 0x15, 0x52, 0x80, + 0x80, 0xa5, 0xff, 0x13, 0xa7, 0xff, 0xfa, 0x75, 0x1c, 0x48, 0x05, 0x9f, 0xd4, 0x9a, 0xfc, 0x22, + 0x10, 0x0a, 0x79, 0x38, 0x59, 0x10, 0x85, 0x59, 0x52, 0xa7, 0x01, 0x6a, 0xf7, 0x9e, 0x0e, 0xf2, + 0x7f, 0x97, 0xd7, 0x10, 0x24, 0x48, 0xc3, 0xb0, 0x8d, 0xdf, 0xae, 0x20, 0x1c, 0xf0, 0xca, 0x0a, + 0xd6, 0x21, 0x63, 0x3a, 0xe1, 0xf5, 0xca, 0x27, 0xa1, 0x3d, 0x7d, 0x11, 0xe7, 0xeb, 0xd1, 0x90, + 0xc8, 0x9c, 0x26, 0x40, 0xb0, 0x06, 0x7c, 0x29, 0xe6, 0x0c, 0x69, 0x5b, 0x98, 0xb9, 0x21, 0x1c, + 0xe2, 0xf5, 0x5a, 0xe1, 0x74, 0x70, 0x02, 0x00, 0x0c, 0xc7, 0x0f, 0x45, 0xe8, 0xaf, 0xbe, 0x77, + 0x14, 0x67, 0xfe, 0x24, 0x1e, 0xfe, 0x24, 0x07, 0xd6, 0xdd, 0x71, 0x32, 0xc0, 0x40, 0x00, 0x44, + 0x42, 0x91, 0x40, 0x18, 0xa0, 0xc1, 0xac, 0xcb, 0x6c, 0x9a, 0x98, 0xf1, 0xf1, 0xe0, 0xbc, 0x1e, + 0x17, 0x71, 0xac, 0xdf, 0x87, 0x9c, 0x1e, 0xb8, 0xca, 0x1a, 0xa8, 0x4c, 0x84, 0x01, 0x3f, 0x11, + 0x3b, 0x64, 0x3b, 0x76, 0x43, 0x64, 0x3e, 0x5e, 0x99, 0x27, 0x11, 0xe9, 0x97, 0xc2, 0xe8, 0x58, + 0x00, 0xba, 0xfc, 0xd5, 0x39, 0x8b, 0xfd, 0xd6, 0xee, 0xe7, 0xef, 0xef, 0xc0, 0xd0, 0x07, 0x91, + 0x86, 0xaa, 0xa8, 0xb8, 0x57, 0xa2, 0xe2, 0x9a, 0x67, 0x01, 0xe5, 0xdb, 0xdf, 0x0a, 0xce, 0x04, + 0x05, 0x8a, 0x43, 0xa2, 0x6f, 0xff, 0xee, 0xfb, 0xae, 0x08, 0x40, 0x4c, 0x0e, 0x1c, 0x28, 0x03, + 0x15, 0x62, 0x01, 0xe3, 0xbf, 0xbd, 0xc1, 0xe7, 0xdf, 0xc7, 0x9f, 0x1d, 0x7c, 0x67, 0x41, 0x36, + 0x9f, 0xa2, 0xd4, 0xfd, 0x72, 0xbe, 0xac, 0x42, 0x23, 0x14, 0x4c, 0x83, 0xd8, 0x5c, 0x81, 0x40, + 0x0c, 0x77, 0x89, 0x22, 0xba, 0x1a, 0x24, 0x37, 0xf9, 0x61, 0x44, 0x8b, 0xb0, 0xbe, 0x01, 0xd5, + 0x88, 0x8a, 0x53, 0x09, 0x62, 0x6d, 0x3f, 0xd7, 0x7a, 0xd6, 0x92, 0x64, 0xe5, 0xda, 0x64, 0xe2, + 0xd8, 0xf5, 0xf5, 0x85, 0xf0, 0x02, 0x50, 0xbe, 0x58, 0xd4, 0x8a, 0x3a, 0x08, 0x58, 0x9f, 0xff, + 0x41, 0xb8, 0xc5, 0x0b, 0x7a, 0xaa, 0x94, 0xaa, 0x24, 0x01, 0x54, 0x60, 0x52, 0x63, 0x51, 0xcc, + 0x0c, 0x3d, 0x2a, 0x7e, 0xa5, 0xb8, 0x12, 0x40, 0x6c, 0x39, 0x7a, 0xaa, 0x3c, 0x08, 0x20, 0x30, + 0x06, 0x55, 0x54, 0x5e, 0x4b, 0xc4, 0xc8, 0x25, 0x9a, 0x89, 0xd1, 0xf2, 0xf1, 0x72, 0x64, 0xe0, + 0x49, 0x01, 0x80, 0xcf, 0x35, 0xc2, 0xf8, 0x0a, 0x36, 0x55, 0xff, 0xf5, 0xaf, 0xdf, 0x82, 0x10, + 0x12, 0x03, 0x0c, 0x21, 0xe3, 0xaf, 0xa6, 0x3a, 0xfd, 0xd3, 0x3e, 0x97, 0x9e, 0xf1, 0x0f, 0xbc, + 0xde, 0xb0, 0x9b, 0x38, 0x00, 0x24, 0x98, 0xbe, 0xdd, 0x9d, 0xdb, 0xb1, 0x4b, 0xfe, 0x06, 0xe1, + 0xfb, 0x2a, 0x40, 0x68, 0x3f, 0x0e, 0xf4, 0x11, 0x78, 0x8e, 0xad, 0x5d, 0x5a, 0xba, 0xb2, 0xba, + 0xe5, 0x41, 0xd8, 0x80, 0x00, 0xc8, 0xfd, 0x57, 0xf3, 0xff, 0xfb, 0xff, 0xe6, 0xa1, 0xa9, 0x18, + 0xb4, 0x79, 0x3f, 0xe0, 0x49, 0x01, 0x80, 0x38, 0x62, 0x85, 0x2a, 0x2f, 0xd8, 0xaf, 0x9a, 0xf1, + 0x01, 0x81, 0x93, 0xd8, 0x9d, 0xc9, 0x2c, 0xe3, 0x81, 0xf2, 0x58, 0x6d, 0x35, 0x8b, 0x8b, 0x9b, + 0xa0, 0xc8, 0x79, 0x83, 0x7f, 0x88, 0x21, 0xef, 0xae, 0xea, 0x4c, 0xf1, 0x30, 0x99, 0x5f, 0x77, + 0x57, 0xe2, 0x02, 0x03, 0xae, 0xdb, 0x4a, 0x5e, 0x23, 0x8b, 0x35, 0x8b, 0xf1, 0x04, 0xee, 0xf8, + 0x64, 0x08, 0x01, 0x11, 0x2a, 0xb7, 0xb7, 0x5b, 0xdf, 0x88, 0x1d, 0xb2, 0x1e, 0xbc, 0x5e, 0x66, + 0x16, 0x2f, 0xc2, 0x20, 0x70, 0x05, 0x63, 0x8b, 0x1e, 0xc7, 0xfc, 0xf5, 0xbb, 0xad, 0x56, 0xb8, + 0x44, 0x0d, 0x02, 0xc7, 0xa5, 0x6a, 0xab, 0x93, 0xa1, 0x6c, 0x5f, 0x56, 0x46, 0x75, 0x62, 0x10, + 0xeb, 0x55, 0xd6, 0x52, 0x75, 0x95, 0x70, 0x48, 0x6e, 0x07, 0xa0, 0xd5, 0xb8, 0x39, 0x01, 0x01, + 0xe1, 0x10, 0x88, 0xa8, 0xbd, 0x25, 0xae, 0xe2, 0x1c, 0x57, 0x8c, 0x48, 0x28, 0x0a, 0x44, 0x80, + 0x07, 0x01, 0xd8, 0x14, 0xc0, 0x87, 0x40, 0x41, 0xce, 0x13, 0xc2, 0xfc, 0xb3, 0x02, 0x31, 0x32, + 0x42, 0x28, 0x54, 0xad, 0x4c, 0xbb, 0xfb, 0xe4, 0x6a, 0x2c, 0x3e, 0x3c, 0x06, 0xf8, 0x13, 0xa6, + 0x8e, 0xe2, 0x01, 0x40, 0xc3, 0x72, 0x2e, 0xb4, 0x92, 0x2e, 0x5a, 0xbc, 0xc9, 0xf9, 0x1f, 0x0b, + 0x71, 0x8a, 0xf8, 0x60, 0x58, 0xb3, 0x18, 0xde, 0x49, 0x55, 0x57, 0xc2, 0x3c, 0x48, 0x30, 0x1e, + 0x70, 0xa5, 0x6f, 0xbb, 0xfa, 0xaf, 0x04, 0x01, 0x0a, 0x49, 0x7a, 0xaa, 0xef, 0x82, 0x10, 0xc7, + 0x83, 0x02, 0x08, 0x13, 0xe7, 0x80, 0x7c, 0x48, 0x7f, 0x84, 0x04, 0x5a, 0x4b, 0x16, 0xce, 0x0c, + 0x1d, 0xa0, 0xc5, 0x29, 0x30, 0x55, 0xf4, 0xf8, 0x44, 0x0c, 0x00, 0x8c, 0x7e, 0x25, 0xfa, 0x97, + 0xa1, 0x2e, 0x44, 0x0b, 0x5a, 0x37, 0xf5, 0x64, 0x57, 0x56, 0x22, 0x7a, 0xb2, 0x23, 0xac, 0xb8, + 0x21, 0x03, 0x00, 0xb0, 0x86, 0x46, 0x15, 0xad, 0xf8, 0x41, 0x95, 0x48, 0xc5, 0x2c, 0x40, 0x81, + 0xe4, 0x5a, 0xd4, 0xaa, 0x16, 0x0d, 0xcf, 0xc0, 0x4e, 0x11, 0x93, 0x0b, 0x7c, 0x22, 0x2c, 0xcb, + 0x5d, 0xe2, 0xbe, 0x20, 0x66, 0xb9, 0x6d, 0x5a, 0xac, 0x42, 0xcb, 0x39, 0xcb, 0x33, 0x35, 0xe2, + 0x62, 0x86, 0xae, 0xc6, 0xba, 0xe1, 0x80, 0x81, 0x88, 0xab, 0x5c, 0x30, 0x08, 0x01, 0x49, 0xd5, + 0x54, 0x53, 0x55, 0x55, 0x51, 0x07, 0x05, 0xcb, 0xdb, 0x83, 0x80, 0xc0, 0x21, 0x8b, 0xc5, 0xfe, + 0xc7, 0x38, 0x0c, 0xf3, 0x20, 0xf7, 0x0c, 0x81, 0x40, 0xb5, 0x8a, 0x62, 0xf8, 0x29, 0x8f, 0x35, + 0x67, 0x80, 0x7c, 0x49, 0xe7, 0x05, 0x81, 0x20, 0x1e, 0x70, 0x07, 0x96, 0x18, 0x80, 0xe1, 0x7c, + 0x5f, 0xd8, 0x83, 0xdf, 0xdb, 0xc2, 0x20, 0x60, 0x28, 0xb4, 0xe5, 0xd8, 0x74, 0x24, 0x4a, 0x41, + 0xbf, 0x19, 0x49, 0xe9, 0xf8, 0xa8, 0x90, 0x24, 0x06, 0x08, 0x2e, 0xa2, 0x98, 0x53, 0xc6, 0x61, + 0x1f, 0x03, 0x58, 0xea, 0x69, 0xcf, 0xff, 0x08, 0x88, 0x05, 0x9a, 0xc5, 0x33, 0xe3, 0xd8, 0xcd, + 0xcb, 0x32, 0xf2, 0x73, 0x99, 0xc3, 0x20, 0xe0, 0x7c, 0xbd, 0x3e, 0xb5, 0xad, 0x70, 0xcc, 0xa7, + 0x55, 0x55, 0xe0, 0xa0, 0x20, 0x61, 0x4e, 0x2f, 0x17, 0x8b, 0xac, 0xfd, 0x8f, 0xf1, 0x82, 0x17, + 0x77, 0x77, 0xad, 0x62, 0xb0, 0x68, 0xa5, 0x71, 0xc4, 0x5f, 0x84, 0x46, 0x1c, 0xa2, 0x74, 0x95, + 0xfe, 0xad, 0x62, 0xe9, 0x8e, 0x4b, 0x96, 0xb1, 0xe0, 0xbb, 0x14, 0x8b, 0x93, 0xc4, 0xc8, 0x78, + 0x44, 0x5d, 0x6a, 0x9c, 0xae, 0x5a, 0xdf, 0x5c, 0x40, 0x47, 0xe1, 0x0a, 0xab, 0xb8, 0xac, 0x56, + 0x28, 0xc5, 0x1d, 0x5f, 0x82, 0x10, 0xc0, 0x53, 0x36, 0x0b, 0xca, 0xd6, 0x29, 0x8b, 0x8b, 0xa8, + 0xba, 0xaf, 0xdc, 0x32, 0x05, 0x00, 0x45, 0xba, 0xc7, 0x6c, 0x51, 0x21, 0x70, 0x98, 0xc1, 0xc8, + 0x91, 0x95, 0xae, 0xb5, 0x17, 0x8b, 0xeb, 0x5e, 0x20, 0x20, 0x41, 0x72, 0x71, 0x4f, 0x17, 0x55, + 0x5b, 0xdf, 0x13, 0x08, 0x0a, 0x55, 0xa4, 0xf7, 0xd5, 0xf8, 0x44, 0x0c, 0x05, 0xaa, 0x25, 0xc3, + 0x6c, 0x2e, 0x10, 0x9e, 0x9d, 0xff, 0xa7, 0xf4, 0xcb, 0xf6, 0xe7, 0xe4, 0xd6, 0xa1, 0xc8, 0x12, + 0x20, 0x9c, 0x63, 0xbf, 0x36, 0x49, 0x91, 0x70, 0x52, 0x07, 0x00, 0xa9, 0x85, 0x03, 0x14, 0xc5, + 0x35, 0x10, 0x70, 0x5e, 0x54, 0xe9, 0x6c, 0xfb, 0xfe, 0x19, 0x04, 0x01, 0x4a, 0xb0, 0x83, 0xac, + 0x65, 0x4e, 0x71, 0xc5, 0x62, 0xb1, 0x46, 0x58, 0xcf, 0x78, 0x97, 0x17, 0x21, 0x77, 0x82, 0x81, + 0x17, 0x3c, 0x4f, 0x7c, 0xf5, 0x5c, 0x32, 0x06, 0x80, 0x4e, 0x26, 0xb5, 0x55, 0x17, 0x56, 0xe1, + 0x10, 0x72, 0xeb, 0x5f, 0x10, 0x30, 0xc2, 0x98, 0xb8, 0xa1, 0x8a, 0x6a, 0xcc, 0xd4, 0x39, 0xe2, + 0x98, 0xba, 0xf6, 0xa3, 0x08, 0x31, 0x02, 0x46, 0x08, 0xb8, 0xac, 0x43, 0x8e, 0xfe, 0x73, 0x85, + 0x8e, 0x25, 0xcd, 0xcf, 0x07, 0x0f, 0x01, 0xcf, 0x82, 0x08, 0xc9, 0x31, 0xa9, 0x9c, 0x3f, 0x35, + 0x8b, 0x2e, 0x0a, 0xcb, 0x01, 0x9e, 0x00, 0x38, 0x4a, 0x00, 0xf0, 0x2c, 0xb8, 0x99, 0x63, 0x61, + 0x63, 0x12, 0x0e, 0x1f, 0xc3, 0xf9, 0x89, 0x12, 0x10, 0x2c, 0xc4, 0x38, 0xa7, 0x89, 0x04, 0xe7, + 0x4f, 0x58, 0x1d, 0xfd, 0x45, 0xd7, 0x0c, 0x06, 0x41, 0x10, 0x9b, 0xdf, 0xdc, 0x32, 0x06, 0x10, + 0x54, 0x71, 0x7a, 0x45, 0xcd, 0xdc, 0x56, 0xe6, 0xc7, 0x76, 0xf0, 0x62, 0xa3, 0xbb, 0xe0, 0xb6, + 0xa2, 0x38, 0x94, 0x55, 0x2e, 0x63, 0xbb, 0x0b, 0xc8, 0x04, 0xe3, 0xd2, 0x19, 0x7f, 0xeb, 0xfa, + 0xc5, 0x39, 0x5d, 0x09, 0xe1, 0x22, 0x32, 0xb3, 0xfd, 0x6b, 0x5a, 0xf0, 0x88, 0x10, 0x09, 0x88, + 0xe5, 0x7c, 0x79, 0x99, 0x9e, 0x68, 0x34, 0xaa, 0xa2, 0xea, 0x2f, 0x84, 0x40, 0xc0, 0x10, 0x32, + 0xae, 0x2e, 0x46, 0x05, 0xcb, 0xda, 0x15, 0x89, 0xe5, 0x58, 0x18, 0x41, 0x80, 0xbd, 0x69, 0x64, + 0x84, 0x10, 0xc0, 0xa1, 0x30, 0xb5, 0x52, 0xe5, 0xe0, 0x20, 0x40, 0x44, 0x71, 0x01, 0x80, 0x81, + 0x05, 0xd4, 0x94, 0xf8, 0x87, 0xb8, 0xac, 0xb6, 0x2b, 0xe1, 0x01, 0x98, 0xac, 0x56, 0x28, 0xcb, + 0x78, 0x86, 0x91, 0x58, 0xac, 0x56, 0x7f, 0xaa, 0x18, 0x9f, 0xc4, 0x47, 0xcf, 0x8d, 0xe2, 0xea, + 0xb5, 0xae, 0x17, 0x89, 0x00, 0xe0, 0xac, 0xb4, 0xe3, 0xde, 0xb5, 0xbb, 0xbb, 0xad, 0x7e, 0x70, + 0x73, 0x05, 0x5b, 0xbc, 0x56, 0x2b, 0xc5, 0xc5, 0x31, 0x71, 0x79, 0x70, 0x84, 0x28, 0x20, 0x5d, + 0x0d, 0x63, 0x2e, 0x87, 0x0d, 0x3b, 0x0b, 0xc5, 0xc5, 0x31, 0x71, 0x3e, 0x58, 0x62, 0x99, 0x25, + 0x65, 0xbc, 0x48, 0x27, 0x86, 0x72, 0x12, 0x50, 0xbe, 0xf2, 0xf3, 0xa7, 0x08, 0x89, 0x04, 0xa4, + 0xe5, 0x74, 0x83, 0x0b, 0xcb, 0x18, 0xfb, 0xc3, 0x02, 0x0a, 0x4c, 0xaf, 0x31, 0x71, 0x75, 0x17, + 0xc3, 0x01, 0x03, 0x1e, 0xaa, 0xb8, 0x30, 0x0c, 0x05, 0x2e, 0xfd, 0xde, 0xaa, 0xab, 0xaa, 0xfb, + 0xc4, 0x02, 0x4e, 0xab, 0xc7, 0xf1, 0x20, 0xa0, 0x10, 0xde, 0xff, 0x7c, 0x11, 0x93, 0x77, 0xef, + 0x94, 0xee, 0xee, 0xf0, 0x9a, 0x83, 0x06, 0x3b, 0xff, 0xbf, 0xfc, 0x09, 0x00, 0x90, 0x9a, 0xab, + 0x63, 0x89, 0x12, 0x30, 0xf7, 0x05, 0x00, 0x2c, 0x01, 0x59, 0x5d, 0xfa, 0xd4, 0x5c, 0x4f, 0x05, + 0xcb, 0xdb, 0x0c, 0x44, 0x00, 0x02, 0x69, 0x8e, 0x14, 0x8e, 0xce, 0xc2, 0xa8, 0x86, 0xb2, 0x9e, + 0x2c, 0x1e, 0x31, 0xc0, 0xaf, 0xc1, 0xb7, 0xdf, 0xfd, 0x70, 0x28, 0x83, 0x00, 0x56, 0x6c, 0xe7, + 0x12, 0x36, 0xd8, 0x83, 0xdd, 0x84, 0x27, 0xcd, 0xc6, 0x28, 0x6d, 0x70, 0xc0, 0x23, 0x09, 0x8a, + 0xe5, 0xb9, 0x52, 0x16, 0xeb, 0xd7, 0xd5, 0x89, 0x07, 0x23, 0x96, 0x19, 0x3a, 0xc4, 0x81, 0x80, + 0x13, 0x8c, 0xd5, 0x6e, 0x9b, 0x63, 0x40, 0xa2, 0xaf, 0x04, 0xa6, 0x9b, 0x57, 0x76, 0x48, 0x8e, + 0x48, 0xa2, 0xc7, 0x62, 0x5c, 0xcc, 0xe2, 0x01, 0x07, 0x86, 0x02, 0x15, 0xee, 0xe2, 0xb7, 0x76, + 0xf5, 0xc4, 0x81, 0x60, 0x61, 0x55, 0x75, 0x55, 0x53, 0x75, 0x94, 0xd4, 0x5e, 0x2f, 0x86, 0x43, + 0x2f, 0x5a, 0xf8, 0xea, 0xae, 0xab, 0xdd, 0xdf, 0x10, 0x10, 0x05, 0x31, 0x4c, 0xf2, 0xa0, 0x53, + 0x2c, 0xe6, 0xaa, 0x2e, 0x46, 0x17, 0x37, 0xf1, 0x01, 0x02, 0x5e, 0xfa, 0xad, 0xd5, 0xf0, 0xc8, + 0x90, 0x53, 0x7b, 0xf5, 0x57, 0x8a, 0x37, 0xfe, 0x1a, 0xc0, 0x65, 0xe3, 0xf2, 0xf7, 0xff, 0xec, + 0x70, 0x70, 0x19, 0x05, 0xc7, 0x15, 0xbb, 0xeb, 0x5f, 0x63, 0x88, 0x24, 0x27, 0x80, 0x93, 0x71, + 0xa5, 0x45, 0x32, 0x00, 0x9a, 0xf9, 0x56, 0xbf, 0x12, 0x11, 0x04, 0xc6, 0xd5, 0x55, 0x56, 0xdc, + 0x18, 0x01, 0x44, 0x26, 0x41, 0x4d, 0x45, 0xee, 0xee, 0xfc, 0x30, 0x2c, 0x59, 0xfe, 0xf6, 0xed, + 0xf0, 0x40, 0x11, 0x25, 0xdd, 0xdc, 0x51, 0xb8, 0xad, 0xc5, 0x6e, 0x7a, 0x62, 0x40, 0x90, 0x0a, + 0x08, 0xfb, 0xe2, 0xeb, 0xee, 0x02, 0x80, 0x08, 0x00, 0xac, 0xe2, 0x8c, 0x56, 0x2b, 0x7c, 0x5c, + 0x5d, 0x6b, 0x1d, 0xd8, 0x55, 0x89, 0x04, 0x4e, 0x2f, 0x5f, 0xef, 0x7f, 0xc7, 0x38, 0x04, 0x0f, + 0x13, 0x63, 0xd2, 0x3d, 0xc0, 0xb2, 0x03, 0xe0, 0x16, 0x8a, 0x37, 0x1a, 0x15, 0x1b, 0xbd, 0xd6, + 0x3b, 0x1f, 0xc0, 0xc2, 0x20, 0x68, 0xa6, 0x5a, 0xa6, 0x7e, 0x2e, 0x2f, 0x5a, 0x89, 0x38, 0x3b, + 0x60, 0xa6, 0x58, 0x72, 0x6e, 0x2f, 0x8e, 0xd2, 0xdb, 0x76, 0x3f, 0xf2, 0x9f, 0x12, 0xf8, 0xbe, + 0xa7, 0x51, 0xf1, 0x7d, 0xa6, 0xb6, 0x9a, 0x1d, 0xd1, 0x7a, 0xe2, 0x04, 0x86, 0xc8, 0xb3, 0x41, + 0x41, 0xc0, 0x02, 0x08, 0x1e, 0x0e, 0x37, 0x17, 0x07, 0x2b, 0xb2, 0x9f, 0x84, 0x41, 0x83, 0x93, + 0x3b, 0x88, 0x84, 0x44, 0x3d, 0xd6, 0xf7, 0xad, 0x61, 0x36, 0x2c, 0x03, 0x7e, 0x4b, 0x50, 0x90, + 0xe7, 0xeb, 0x5f, 0xe0, 0x80, 0x0d, 0x01, 0x3a, 0xae, 0xee, 0x2b, 0x15, 0xe2, 0x43, 0x01, 0x1c, + 0xdc, 0x57, 0x8a, 0xc5, 0x62, 0xb1, 0x46, 0x2b, 0x71, 0x5f, 0x08, 0x06, 0x78, 0x44, 0x48, 0xea, + 0xaa, 0xee, 0xef, 0x32, 0x8a, 0xe1, 0x01, 0x04, 0xaa, 0xfc, 0x14, 0x02, 0x1a, 0xaa, 0xf8, 0xfc, + 0x5e, 0x02, 0x5c, 0xdc, 0x14, 0x31, 0x43, 0x4a, 0x8e, 0x62, 0xc2, 0x27, 0xa4, 0x0c, 0xf7, 0x84, + 0x41, 0x58, 0xc1, 0x7a, 0xd6, 0xbd, 0xdf, 0xdc, 0x1c, 0x04, 0x5d, 0x54, 0x69, 0x0a, 0x70, 0x85, + 0x9c, 0x5f, 0xf0, 0x72, 0xca, 0x7f, 0xf0, 0x80, 0x21, 0x0a, 0x0c, 0xbb, 0xbb, 0xdb, 0xdd, 0xdd, + 0xcf, 0xc4, 0xfb, 0xf9, 0xfe, 0xec, 0x34, 0x48, 0x02, 0x0d, 0xec, 0x48, 0x30, 0x4f, 0xfd, 0x34, + 0xd3, 0x4e, 0x98, 0xe3, 0x1f, 0x8e, 0x21, 0x42, 0x21, 0x2b, 0xcb, 0x58, 0xd6, 0x70, 0xf0, 0x0c, + 0x13, 0xd8, 0x4d, 0x94, 0x02, 0x67, 0x9a, 0x84, 0xf4, 0xd3, 0xfe, 0xb5, 0xc3, 0x00, 0x3e, 0x01, + 0x2d, 0x6e, 0xed, 0x34, 0x97, 0xd8, 0x51, 0x0a, 0x00, 0x1d, 0xd9, 0x68, 0x34, 0x09, 0x7a, 0xdd, + 0x13, 0x4d, 0x34, 0xd3, 0x07, 0xfc, 0xbd, 0xbf, 0xd3, 0x8f, 0xc0, 0xd2, 0x10, 0x0a, 0x0a, 0xd6, + 0xb8, 0xbc, 0x9f, 0x55, 0x55, 0xe2, 0xbe, 0x51, 0x29, 0x69, 0x3e, 0xb5, 0x0b, 0x43, 0x10, 0x99, + 0x6d, 0xdb, 0x5d, 0x0f, 0x84, 0x43, 0x64, 0x15, 0xc4, 0xb9, 0x27, 0xe1, 0x8f, 0xbf, 0xf2, 0x9d, + 0xdd, 0xae, 0x20, 0x20, 0x5b, 0xdf, 0xe5, 0x23, 0xdd, 0xf8, 0x40, 0x20, 0x2a, 0xf7, 0xbd, 0xea, + 0xda, 0xc3, 0x31, 0xe0, 0x04, 0x03, 0x4d, 0x71, 0x00, 0x45, 0xe7, 0xfb, 0xcb, 0xd3, 0xf8, 0xfe, + 0x0c, 0x41, 0x58, 0x81, 0x78, 0xbc, 0x5d, 0x45, 0xc5, 0xd3, 0x7f, 0xbc, 0x32, 0x0a, 0x0e, 0xf7, + 0xb8, 0xac, 0x56, 0x28, 0xfb, 0xc2, 0x00, 0x97, 0x56, 0xa2, 0xe2, 0xfb, 0x78, 0x44, 0x65, 0x57, + 0x27, 0x21, 0x0d, 0x3d, 0xc5, 0x6e, 0xee, 0xfc, 0x30, 0x22, 0xab, 0xbd, 0xdf, 0x06, 0x21, 0x00, + 0x4a, 0x47, 0x77, 0x7a, 0xd7, 0xdc, 0x18, 0x06, 0x02, 0x85, 0xab, 0xc5, 0xd4, 0x5d, 0x75, 0x55, + 0x5c, 0x76, 0x39, 0xe1, 0x90, 0x60, 0x0b, 0x0f, 0x57, 0xee, 0x2b, 0x15, 0xb6, 0x25, 0xf5, 0x8e, + 0xc7, 0x3c, 0x14, 0xc1, 0x38, 0xab, 0xdd, 0x5e, 0xed, 0xf2, 0x95, 0x55, 0x6b, 0x07, 0x02, 0x8b, + 0x7b, 0x8a, 0xc5, 0x18, 0xa3, 0x15, 0xe2, 0x04, 0x85, 0x06, 0x3b, 0xbb, 0xeb, 0x57, 0xbd, 0x45, + 0xea, 0xd8, 0x55, 0x8b, 0x01, 0x28, 0x2d, 0x03, 0x34, 0xea, 0x7d, 0xff, 0xfe, 0x25, 0x94, 0x00, + 0xc1, 0xa9, 0xd6, 0x48, 0x58, 0x84, 0x00, 0x77, 0x7e, 0x2a, 0xff, 0xff, 0x4f, 0xf1, 0x2c, 0xa1, + 0x12, 0x23, 0xec, 0x2c, 0x42, 0x04, 0xb5, 0x1b, 0xf6, 0xff, 0xff, 0x02, 0x40, 0x09, 0x05, 0x6e, + 0x19, 0x06, 0x01, 0x23, 0x52, 0x5e, 0xef, 0x81, 0xe6, 0x0a, 0x88, 0x2b, 0x8a, 0xcd, 0xd7, 0x3d, + 0xb1, 0x27, 0x07, 0xd1, 0x3c, 0x10, 0x8b, 0x4d, 0xd6, 0xdf, 0x26, 0xa9, 0xfd, 0x65, 0x17, 0xc8, + 0x47, 0xdf, 0xc9, 0x5d, 0x7c, 0xdc, 0xf9, 0x70, 0xc4, 0x2e, 0x47, 0x77, 0x76, 0xaa, 0xd8, 0x8a, + 0xe6, 0x55, 0x11, 0xfd, 0x7f, 0x0c, 0x81, 0x21, 0xe5, 0x57, 0xc4, 0x04, 0x8f, 0x75, 0xaa, 0xf0, + 0x99, 0x21, 0x8a, 0x7f, 0xff, 0xbf, 0xe1, 0xa2, 0x41, 0x2f, 0xad, 0x37, 0xff, 0xeb, 0x77, 0x82, + 0x90, 0x58, 0x21, 0xbb, 0x7b, 0xdd, 0xef, 0x97, 0x13, 0x0a, 0x1e, 0xe9, 0x09, 0x54, 0x2a, 0xca, + 0xe2, 0x2c, 0x2a, 0xa9, 0x30, 0xbf, 0x58, 0x5f, 0x01, 0xc7, 0x61, 0x2a, 0xee, 0xab, 0xd0, 0xe8, + 0x75, 0xfe, 0xe1, 0x00, 0x50, 0x09, 0xf7, 0x77, 0xbb, 0x4d, 0x71, 0xff, 0x04, 0xdb, 0xd0, 0xdd, + 0xff, 0x70, 0x87, 0x84, 0x04, 0x92, 0xab, 0xe2, 0x04, 0x82, 0x21, 0x31, 0x75, 0x51, 0xdd, 0xc2, + 0x01, 0x90, 0x57, 0x51, 0x7d, 0xef, 0xd5, 0x47, 0x18, 0xfe, 0x11, 0x08, 0xa2, 0x7b, 0x89, 0x82, + 0x23, 0x29, 0x98, 0xdb, 0x84, 0x41, 0x41, 0xbb, 0xbe, 0x23, 0xc4, 0x86, 0x46, 0x6f, 0x71, 0x5d, + 0xe9, 0xbe, 0xfa, 0xf0, 0x50, 0x09, 0xea, 0xba, 0xaa, 0x8b, 0xfb, 0x0b, 0x90, 0x48, 0x03, 0x5e, + 0x72, 0x34, 0x6d, 0xdf, 0xbd, 0xbf, 0xa7, 0x36, 0x62, 0x94, 0x10, 0xb0, 0xe1, 0xa1, 0xa2, 0x41, + 0x30, 0xfd, 0x67, 0xef, 0xff, 0xbb, 0x0d, 0x10, 0xa0, 0x4f, 0xc6, 0xb3, 0x9f, 0xff, 0xef, 0xb7, + 0x13, 0xa9, 0xc8, 0x20, 0x69, 0x33, 0x88, 0x03, 0x40, 0x21, 0xaa, 0xed, 0xc1, 0x80, 0x12, 0x08, + 0x57, 0x7f, 0x0c, 0x80, 0x80, 0x10, 0x21, 0x53, 0x5d, 0x15, 0x7c, 0x2d, 0x55, 0x6e, 0x07, 0xb0, + 0x35, 0xc9, 0x40, 0x00, 0xda, 0x87, 0xb0, 0xd4, 0x20, 0x13, 0x8c, 0xe1, 0x5c, 0x2f, 0xec, 0xa0, + 0x85, 0xdf, 0x86, 0xa2, 0x40, 0x40, 0x09, 0xb6, 0xe1, 0x6e, 0x33, 0xbe, 0x30, 0x85, 0xe2, 0x61, + 0x13, 0xad, 0x6f, 0x75, 0x37, 0xd7, 0xe1, 0x00, 0x47, 0x55, 0x51, 0x7f, 0xf0, 0x41, 0x04, 0x31, + 0x75, 0x55, 0x1d, 0xde, 0x04, 0x00, 0x91, 0x05, 0xea, 0xef, 0xbe, 0x24, 0x48, 0xf8, 0xac, 0x56, + 0xe2, 0xb1, 0x2f, 0x96, 0xc4, 0x38, 0x2b, 0x2c, 0x71, 0x5e, 0x20, 0x10, 0x02, 0x61, 0x0a, 0xb3, + 0xc5, 0x6d, 0xb7, 0x08, 0xc5, 0x8b, 0x76, 0xed, 0x6a, 0xb8, 0x1a, 0x03, 0x00, 0xba, 0xaf, 0x7a, + 0xd7, 0xb8, 0x81, 0x00, 0x8e, 0xaa, 0x2e, 0x2f, 0xef, 0x82, 0x2e, 0xaa, 0xdc, 0x44, 0x14, 0x55, + 0x55, 0x6a, 0xa2, 0xed, 0xe0, 0x84, 0xa5, 0x55, 0x55, 0xe0, 0xa4, 0xbc, 0x43, 0x8f, 0x1c, 0x43, + 0x06, 0xab, 0x6f, 0x8e, 0xc3, 0x03, 0xcf, 0xe2, 0x0b, 0xad, 0x70, 0xc8, 0x60, 0x27, 0xdd, 0xbb, + 0x55, 0xc1, 0xc0, 0x21, 0x05, 0x71, 0x58, 0xad, 0xea, 0x2e, 0xba, 0xaa, 0xfb, 0x82, 0x08, 0x25, + 0xbb, 0xea, 0x2f, 0xfb, 0x82, 0x00, 0x2c, 0x02, 0x11, 0x22, 0x3e, 0xaa, 0x38, 0xc7, 0x3c, 0x09, + 0x20, 0xe4, 0x15, 0x55, 0x7a, 0xba, 0x57, 0x58, 0xee, 0xe2, 0x01, 0x80, 0x2a, 0xaa, 0xea, 0xbb, + 0x9b, 0xbf, 0xc7, 0x3c, 0x18, 0x82, 0x00, 0x55, 0x6e, 0xf3, 0x40, 0xbf, 0x77, 0xaf, 0x1f, 0x9e, + 0x40, 0xfa, 0xdc, 0xe2, 0x41, 0xc0, 0xc2, 0x2d, 0x6e, 0xf7, 0x5a, 0xdd, 0xdd, 0xf0, 0xc0, 0x10, + 0x04, 0x09, 0x77, 0xdd, 0xdd, 0xf0, 0x43, 0x77, 0xbb, 0xe0, 0xc4, 0x0c, 0x00, 0x9c, 0x71, 0x30, + 0x40, 0xf1, 0x78, 0xe3, 0x88, 0x3c, 0xbe, 0x1b, 0x2b, 0x61, 0x06, 0x08, 0x6b, 0x84, 0x2d, 0x2d, + 0xc0, 0xe9, 0x85, 0xdf, 0x8c, 0xe6, 0x93, 0x13, 0xc6, 0x70, 0x41, 0x85, 0xc0, 0xa8, 0x6c, 0xf3, + 0xe0, 0x01, 0xca, 0xa8, 0x1d, 0x30, 0x25, 0x1a, 0xb0, 0x0b, 0x8e, 0x00, 0x0f, 0x2e, 0x00, 0xb8, + 0xb1, 0xb8, 0x22, 0x0c, 0x14, 0x41, 0x1c, 0x20, 0x04, 0x19, 0xb0, 0x19, 0x6f, 0xc9, 0xd6, 0xcd, + 0xbf, 0xcb, 0x63, 0x4e, 0x8f, 0xe0, 0x8c, 0xa6, 0x62, 0xa9, 0xbf, 0x89, 0x5e, 0xe2, 0x02, 0x38, + 0xec, 0x15, 0x76, 0x47, 0xe1, 0x80, 0x40, 0x3e, 0xb6, 0x3c, 0x43, 0xef, 0x2f, 0x7b, 0xc4, 0xc2, + 0x22, 0x15, 0xbe, 0xee, 0xf2, 0xd2, 0xfe, 0x62, 0xdd, 0xdf, 0x05, 0x00, 0xe4, 0x79, 0x74, 0xde, + 0xae, 0xae, 0xb5, 0x85, 0xe7, 0x08, 0x50, 0x0a, 0x5b, 0xd5, 0x95, 0x95, 0x5f, 0x34, 0x26, 0x86, + 0xce, 0x19, 0x05, 0x23, 0x0c, 0x4f, 0x8e, 0xbb, 0xc7, 0x8c, 0xdd, 0x65, 0xfc, 0x22, 0x08, 0x42, + 0x75, 0x5e, 0xcd, 0x53, 0xc1, 0x00, 0x80, 0x8d, 0xdd, 0xaa, 0xaa, 0xd5, 0x7e, 0x10, 0x37, 0x77, + 0x8e, 0x90, 0x3c, 0xc7, 0xcf, 0x8e, 0x50, 0x4c, 0xa7, 0xfa, 0xa3, 0xbc, 0x20, 0x08, 0x42, 0x9c, + 0x56, 0xee, 0xee, 0xe2, 0x8c, 0x56, 0x2b, 0x77, 0xbe, 0xab, 0x02, 0x40, 0x2c, 0x2b, 0x6a, 0xa2, + 0xed, 0xdc, 0xdd, 0x54, 0xbc, 0x5f, 0x8f, 0xe0, 0xa0, 0x18, 0x05, 0x0e, 0xfa, 0xaa, 0xaa, 0xa4, + 0xab, 0x55, 0xc7, 0x18, 0xe1, 0xf0, 0xc0, 0x24, 0xab, 0x8a, 0x7e, 0x3f, 0xc0, 0x82, 0x08, 0xeb, + 0x5f, 0xb8, 0x44, 0x18, 0xaf, 0xb8, 0x44, 0x48, 0x25, 0x24, 0x5f, 0x17, 0x68, 0x5d, 0x5b, 0x84, + 0x42, 0x25, 0xee, 0xf8, 0x81, 0x2e, 0x2e, 0xbe, 0x11, 0x05, 0x21, 0x43, 0x8a, 0xdc, 0x56, 0xee, + 0xe2, 0xb7, 0x77, 0xdd, 0xef, 0x7e, 0x19, 0x04, 0x2e, 0xec, 0x4f, 0xc3, 0x22, 0x45, 0x1a, 0xaf, + 0xbd, 0xf0, 0x62, 0x05, 0x00, 0x4e, 0x31, 0x62, 0xea, 0x27, 0xce, 0xf3, 0x72, 0xc3, 0x94, 0x2f, + 0x89, 0x0f, 0x5e, 0xf7, 0xcd, 0x90, 0x3a, 0x31, 0x14, 0x0a, 0x2c, 0x49, 0x2f, 0x40, 0x00, 0x40, + 0x03, 0x80, 0x32, 0xf0, 0x62, 0xfb, 0xf1, 0x20, 0x22, 0x03, 0x30, 0xc6, 0x4f, 0xb8, 0x0e, 0xa7, + 0xbf, 0xff, 0xe1, 0x08, 0x91, 0x2f, 0x4d, 0x6b, 0x5c, 0x40, 0x93, 0x55, 0x6b, 0xe6, 0x8b, 0xaa, + 0xfc, 0x16, 0x6f, 0x7d, 0xa5, 0x5c, 0xbf, 0xbc, 0x4a, 0xfb, 0xc4, 0xf0, 0xc4, 0x7d, 0xc5, 0x6e, + 0xe2, 0x8c, 0x50, 0x1b, 0x8a, 0x38, 0xae, 0x2b, 0xc4, 0x03, 0x01, 0x86, 0xdd, 0xf9, 0xb0, 0x56, + 0x2b, 0x15, 0x8a, 0xea, 0xe5, 0xce, 0x08, 0x01, 0x61, 0x55, 0x6b, 0x77, 0x7a, 0xdb, 0xec, 0x2c, + 0x48, 0x06, 0xe9, 0x84, 0xab, 0xef, 0xff, 0xd6, 0xb8, 0x21, 0x08, 0x1a, 0x9a, 0x69, 0x97, 0xc3, + 0x44, 0x84, 0x41, 0xad, 0x93, 0xff, 0x65, 0xa5, 0xf7, 0xe2, 0x43, 0x00, 0x88, 0xaf, 0x7d, 0x71, + 0x21, 0x8c, 0x34, 0x88, 0x11, 0xc8, 0xa3, 0x3f, 0xff, 0xb7, 0x5c, 0x44, 0x75, 0xc5, 0x62, 0xb7, + 0x71, 0x46, 0x2b, 0x77, 0x3e, 0x3f, 0x89, 0xf8, 0x80, 0x5a, 0x55, 0xd5, 0xe9, 0xfd, 0x84, 0xc8, + 0x50, 0x02, 0x1b, 0xd2, 0xf2, 0x97, 0xf9, 0xb9, 0xaf, 0xf5, 0x5f, 0x0c, 0xa8, 0x08, 0xcf, 0x61, + 0x0d, 0xff, 0x7b, 0xfb, 0xe2, 0x67, 0x04, 0xa3, 0xd1, 0x76, 0x19, 0x90, 0x02, 0xab, 0xbe, 0x58, + 0xf7, 0xff, 0xfd, 0x2a, 0xf2, 0x93, 0x55, 0xc3, 0x01, 0x13, 0x5d, 0xde, 0x48, 0x30, 0x03, 0x0b, + 0x2b, 0xbf, 0x88, 0x0c, 0x78, 0x80, 0x54, 0x32, 0xee, 0xf8, 0x57, 0x4c, 0xd0, 0xd5, 0x0e, 0xbe, + 0x1f, 0xb3, 0xc9, 0x00, 0x38, 0x8c, 0xa2, 0x04, 0xa1, 0xd1, 0x08, 0xa5, 0x12, 0x53, 0x80, 0x00, + 0xb4, 0x38, 0x2f, 0x5d, 0x84, 0x0b, 0x88, 0xc0, 0x05, 0x0b, 0xfb, 0x16, 0x4b, 0xd3, 0xe1, 0x5c, + 0x49, 0xaa, 0x2e, 0xa0, 0x32, 0xcc, 0x24, 0xb0, 0x88, 0x09, 0x00, 0x4c, 0x65, 0xab, 0x97, 0x3e, + 0xae, 0x15, 0x08, 0x04, 0x41, 0x68, 0xd7, 0x7d, 0x69, 0xd8, 0xf1, 0x2a, 0xfc, 0x44, 0x24, 0x6a, + 0xd7, 0x55, 0xf0, 0xa1, 0xc5, 0xd4, 0x5e, 0x99, 0x6e, 0xeb, 0x5d, 0xee, 0xdc, 0x14, 0x03, 0x0c, + 0x2c, 0x49, 0x33, 0xfb, 0xff, 0xe0, 0x41, 0x03, 0x0b, 0xa8, 0x8f, 0x92, 0x18, 0x09, 0x00, 0x28, + 0x0c, 0xb8, 0xac, 0xf9, 0x88, 0x1a, 0x3f, 0xca, 0xc6, 0x2e, 0xb7, 0x4d, 0xf8, 0x40, 0x61, 0x32, + 0x13, 0x7c, 0x9e, 0x77, 0x71, 0x5b, 0xbd, 0xdf, 0x84, 0x02, 0x15, 0x5d, 0xc5, 0x6e, 0xe2, 0xb7, + 0x7e, 0x24, 0x21, 0xe2, 0x3c, 0x49, 0xae, 0xfe, 0x22, 0x28, 0xaf, 0x7b, 0xbf, 0xe2, 0x08, 0x2b, + 0x15, 0xbb, 0xbb, 0xda, 0xe2, 0x0a, 0x54, 0xe4, 0x8f, 0x89, 0x5e, 0xf8, 0x22, 0xc5, 0xda, 0x56, + 0xe2, 0x01, 0x40, 0x23, 0x3d, 0x5f, 0xc7, 0x38, 0x69, 0x40, 0x4a, 0xdb, 0x8e, 0xdd, 0x3f, 0xfd, + 0xf7, 0x7c, 0x26, 0xa0, 0x1b, 0xeb, 0xf4, 0xfa, 0xff, 0xff, 0x08, 0x82, 0x62, 0x2a, 0x9b, 0xe9, + 0x3e, 0xdc, 0x40, 0x43, 0xc3, 0x1f, 0x30, 0x95, 0x5f, 0x0c, 0x83, 0x16, 0x47, 0x77, 0xa8, 0x90, + 0x41, 0xc4, 0x7c, 0x20, 0x14, 0xaa, 0xe4, 0xc7, 0x19, 0xde, 0xef, 0x66, 0xef, 0x5c, 0x18, 0x81, + 0x00, 0x13, 0x8e, 0x8d, 0xe7, 0xd9, 0x32, 0x63, 0x91, 0xfe, 0x53, 0xe1, 0x1d, 0x25, 0xae, 0x5e, + 0x4e, 0xd1, 0x38, 0x2d, 0xa1, 0xb1, 0xa1, 0xb1, 0xbd, 0x37, 0xcb, 0xea, 0xd1, 0x9d, 0x7b, 0x84, + 0x40, 0x40, 0x02, 0x11, 0x42, 0x8e, 0x2b, 0xdb, 0xc4, 0xa3, 0xc5, 0xf5, 0x7e, 0x20, 0x48, 0x4c, + 0xeb, 0x5d, 0x6b, 0x89, 0x12, 0xaf, 0xc4, 0x84, 0x47, 0x8a, 0x5a, 0xdf, 0x7b, 0xdf, 0x08, 0x03, + 0x81, 0xc2, 0x69, 0xd3, 0x77, 0x77, 0x15, 0x70, 0x90, 0x00, 0x4a, 0x97, 0x16, 0x8e, 0x08, 0xf3, + 0x4b, 0x7d, 0xc0, 0xd0, 0x04, 0x80, 0x47, 0x71, 0x5b, 0x4e, 0xdc, 0x0c, 0x20, 0x41, 0x04, 0x95, + 0xa6, 0x76, 0x3d, 0x8e, 0x90, 0x11, 0xed, 0x3f, 0xeb, 0xf1, 0x01, 0x1f, 0x12, 0x42, 0x3b, 0xbb, + 0xe0, 0x22, 0x04, 0x8c, 0x28, 0xa3, 0x71, 0x5b, 0xad, 0x27, 0xcd, 0x98, 0xae, 0xf0, 0xc2, 0x81, + 0x4f, 0x66, 0xbe, 0xdb, 0xfb, 0x7e, 0xf8, 0x6b, 0x12, 0xa9, 0xdf, 0xff, 0xed, 0x8e, 0x50, 0x18, + 0xf7, 0x4e, 0xf7, 0xd1, 0x7d, 0xf5, 0xf7, 0x89, 0x04, 0xb9, 0x58, 0xd5, 0x3f, 0xde, 0x25, 0x7d, + 0x85, 0x14, 0x07, 0xf7, 0x06, 0x7f, 0xfd, 0xf5, 0x85, 0x65, 0x0a, 0x88, 0xd0, 0x3c, 0x28, 0xbd, + 0x56, 0x2e, 0xf5, 0xfc, 0x17, 0x08, 0x17, 0x17, 0xad, 0xef, 0xdc, 0x14, 0x04, 0x02, 0x65, 0x93, + 0x3a, 0xd7, 0x0c, 0x49, 0x55, 0xf8, 0x9f, 0x9a, 0xb5, 0xe1, 0x10, 0x40, 0x5e, 0xef, 0xc4, 0x78, + 0x8f, 0x0c, 0x10, 0xce, 0xee, 0xfe, 0x08, 0xfa, 0x8b, 0xd7, 0x08, 0xc5, 0x5e, 0xba, 0xbb, 0x8a, + 0xc5, 0x7c, 0x22, 0x16, 0x20, 0xe4, 0x0b, 0xc9, 0x80, 0x03, 0x4c, 0x9c, 0x03, 0x42, 0x4d, 0x0a, + 0x24, 0xa5, 0x61, 0x28, 0x4e, 0x11, 0x0f, 0x10, 0x61, 0x0a, 0x85, 0x07, 0xe1, 0x38, 0x28, 0x05, + 0x03, 0x25, 0xc1, 0x58, 0x90, 0x1e, 0x5b, 0x12, 0xb1, 0x7b, 0x0d, 0x05, 0xc1, 0x52, 0xc7, 0x50, + 0x87, 0x96, 0xb0, 0x5b, 0x50, 0x0c, 0x7d, 0xc1, 0xe6, 0x3a, 0xf8, 0x98, 0xfa, 0x16, 0xbc, 0x49, + 0x7c, 0xe2, 0xe2, 0x26, 0xee, 0xf8, 0x8f, 0x88, 0xf0, 0x8f, 0x89, 0x05, 0x97, 0x12, 0xb0, 0x2b, + 0x2c, 0x71, 0x5b, 0xb8, 0xa3, 0x6e, 0x28, 0x66, 0x06, 0x17, 0x70, 0x4e, 0x72, 0xc7, 0x9d, 0xe4, + 0x3b, 0xdd, 0xf5, 0xe0, 0x56, 0x64, 0xef, 0x7e, 0x4f, 0xec, 0xb0, 0x3f, 0xfb, 0x89, 0x02, 0x40, + 0x50, 0x4d, 0xdc, 0x56, 0xef, 0x8a, 0xdc, 0x57, 0xbd, 0xc7, 0x76, 0x39, 0xc0, 0xed, 0xe4, 0xfc, + 0x0c, 0x00, 0x48, 0x0a, 0x17, 0x8a, 0xcf, 0xfa, 0xd5, 0xdc, 0x56, 0xea, 0xaa, 0xad, 0x86, 0x94, + 0x03, 0x86, 0xd7, 0xc9, 0x7d, 0xef, 0xf7, 0xbf, 0x61, 0xa2, 0x40, 0x20, 0x69, 0x99, 0x5f, 0x9b, + 0xff, 0x57, 0xbd, 0xca, 0x98, 0xc4, 0x40, 0x16, 0x14, 0x85, 0xe3, 0x61, 0x82, 0x40, 0x10, 0xeb, + 0xdc, 0x30, 0xbb, 0xb6, 0xdb, 0x7f, 0xff, 0x71, 0x20, 0x36, 0x01, 0x1d, 0x55, 0x57, 0xd8, 0xe5, + 0x09, 0x05, 0x6e, 0x55, 0xc0, 0x28, 0x00, 0x2e, 0x41, 0x2d, 0x0d, 0x39, 0xd8, 0x51, 0x4f, 0x26, + 0x0e, 0xec, 0xee, 0x12, 0x03, 0xd4, 0xf0, 0xb4, 0xa1, 0xd9, 0x41, 0x57, 0xff, 0xfe, 0x19, 0x04, + 0x9b, 0xdc, 0x71, 0x8e, 0x78, 0x44, 0x30, 0xa3, 0x8c, 0x73, 0x85, 0x1c, 0x01, 0xbd, 0x1d, 0x14, + 0xbc, 0xfa, 0xaf, 0xd7, 0x5c, 0x32, 0x0a, 0x41, 0x45, 0xd8, 0xd8, 0xee, 0xee, 0xfd, 0xc4, 0x57, + 0xfc, 0x44, 0xc4, 0xab, 0xf0, 0xc0, 0x64, 0x14, 0x77, 0x7c, 0x56, 0xef, 0xc3, 0x10, 0x59, 0x55, + 0xf1, 0x0e, 0x08, 0x73, 0x15, 0x8a, 0xef, 0x8a, 0x70, 0xc2, 0x6f, 0x70, 0x87, 0x88, 0x12, 0x4b, + 0xbf, 0x88, 0xf0, 0x87, 0x86, 0x01, 0x01, 0xaa, 0xaa, 0xbc, 0x08, 0x03, 0xcd, 0xaa, 0xbb, 0xf7, + 0x5e, 0x24, 0x04, 0x40, 0x53, 0xcb, 0xc2, 0xb5, 0x26, 0x0d, 0x5c, 0x4f, 0xbc, 0x43, 0xde, 0x11, + 0xd6, 0x3c, 0xbc, 0x1b, 0x25, 0xc2, 0x50, 0x51, 0x0a, 0x11, 0x5b, 0xe2, 0xb3, 0xfb, 0x17, 0xb8, + 0x97, 0x41, 0x56, 0xe3, 0x8f, 0x2c, 0xd4, 0xfa, 0x89, 0x39, 0x70, 0x70, 0x19, 0x05, 0x22, 0x41, + 0xff, 0x15, 0x83, 0xdf, 0x2c, 0x71, 0x71, 0x5d, 0xbf, 0x2f, 0x17, 0xee, 0x04, 0x80, 0x30, 0x8b, + 0x36, 0xef, 0xbb, 0xc7, 0x60, 0x35, 0xc7, 0xab, 0x07, 0xd8, 0xc9, 0xc0, 0x90, 0x4d, 0x05, 0x2c, + 0x7c, 0x39, 0x20, 0x00, 0x24, 0xf1, 0x46, 0xbd, 0xfc, 0x12, 0xbe, 0x6f, 0xd7, 0xfb, 0x60, 0xeb, + 0xed, 0x8e, 0x8f, 0xe1, 0xeb, 0xf8, 0x12, 0x00, 0x92, 0x38, 0xd4, 0x42, 0xb8, 0x50, 0x01, 0xa1, + 0x3a, 0xa5, 0xbc, 0xf7, 0x47, 0x14, 0x9c, 0x0a, 0x8f, 0x17, 0x85, 0x98, 0xb0, 0x08, 0xab, 0xc1, + 0x24, 0x4e, 0x0a, 0x1e, 0xb7, 0x77, 0x5a, 0xdd, 0xdd, 0xe1, 0x96, 0x50, 0x11, 0x8e, 0x29, 0x82, + 0xe7, 0xbf, 0xff, 0xdd, 0xc0, 0xc0, 0x07, 0x90, 0x51, 0xbb, 0xbd, 0x6a, 0xd8, 0x6d, 0x9c, 0x36, + 0x07, 0x63, 0xde, 0xf7, 0x77, 0x7f, 0x2d, 0xad, 0x7e, 0x19, 0x21, 0x01, 0x11, 0x23, 0x9d, 0x77, + 0xdd, 0xfa, 0xbf, 0xb6, 0x13, 0x50, 0x56, 0x4b, 0x75, 0xab, 0xab, 0xab, 0x8b, 0xb8, 0xbb, 0xab, + 0xac, 0x26, 0xa0, 0x42, 0xed, 0x1a, 0xa7, 0xfb, 0xdf, 0xf0, 0xb3, 0x80, 0x7e, 0xe2, 0x38, 0xf7, + 0xd1, 0x49, 0x0f, 0xaa, 0xe1, 0x39, 0x00, 0x3f, 0x34, 0x8d, 0x32, 0xd2, 0xd6, 0xac, 0xac, 0xbf, + 0x3b, 0x80, 0x55, 0xb7, 0x25, 0xcc, 0x10, 0x54, 0x71, 0x8e, 0x78, 0x29, 0x82, 0x2d, 0xee, 0x38, + 0xc7, 0x38, 0xa5, 0x19, 0x63, 0x80, 0xb0, 0x01, 0x72, 0x09, 0x0b, 0xaa, 0x8e, 0x31, 0xce, 0x14, + 0x94, 0x03, 0x6d, 0x91, 0xcc, 0xef, 0xff, 0x4d, 0x3e, 0x14, 0x62, 0x00, 0x71, 0xd0, 0x96, 0xbe, + 0xb5, 0xfa, 0xd7, 0x02, 0x00, 0x08, 0x90, 0x47, 0x56, 0xef, 0xdc, 0x10, 0x00, 0xe1, 0x04, 0xf5, + 0x10, 0xf1, 0x7e, 0x98, 0xac, 0x43, 0xfb, 0x81, 0x80, 0x05, 0x48, 0x40, 0x8a, 0xaa, 0xa4, 0xfc, + 0x6f, 0xb8, 0xaf, 0x00, 0xb0, 0x00, 0x89, 0x05, 0x66, 0x55, 0x17, 0x93, 0xb9, 0x22, 0xa7, 0x00, + 0x38, 0x21, 0xc1, 0x00, 0xe1, 0xc0, 0x00, 0xe1, 0xc0, 0x00, 0x4f, 0x32, 0xc5, 0x12, 0x08, 0x5f, + 0x06, 0x15, 0x45, 0x00, 0x68, 0x18, 0xe8, 0x10, 0x9a, 0xee, 0x69, 0xd3, 0xbd, 0xe9, 0xcb, 0xdd, + 0xef, 0x8e, 0x51, 0xac, 0xc5, 0x77, 0x08, 0x06, 0x44, 0xde, 0x2b, 0x89, 0x7c, 0x4b, 0xfe, 0x2f, + 0x5a, 0xea, 0xb1, 0x6c, 0xa0, 0xb8, 0xa4, 0xc6, 0xc3, 0x11, 0x20, 0x46, 0x3c, 0x56, 0xef, 0x6d, + 0xbf, 0xff, 0xb8, 0x29, 0x02, 0x08, 0xa1, 0x5b, 0xb6, 0xe6, 0xf1, 0x3f, 0x81, 0x24, 0x18, 0x8e, + 0x2b, 0xbb, 0xbc, 0x51, 0xc4, 0xb8, 0xff, 0x96, 0xbe, 0x05, 0x90, 0xc0, 0x2c, 0x14, 0x98, 0xa3, + 0x8a, 0xeb, 0x37, 0x10, 0xb1, 0x63, 0x7c, 0x9a, 0xfa, 0x6e, 0x61, 0x2a, 0xbc, 0x00, 0x00, 0x00, + 0x01, 0x41, 0x9a, 0x55, 0x2a, 0xb0, 0xe8, 0x2f, 0xd0, 0xfc, 0xae, 0x02, 0x04, 0x09, 0x01, 0xc1, + 0x95, 0x05, 0x41, 0x4e, 0x0e, 0x82, 0xd8, 0x01, 0x11, 0x5b, 0xe0, 0xdd, 0xdf, 0x80, 0x80, 0x02, + 0x48, 0x9a, 0xaa, 0xaa, 0xc1, 0x2d, 0x21, 0xa4, 0xa7, 0x33, 0xe1, 0x94, 0x3d, 0xc8, 0xfe, 0xbd, + 0x13, 0xcc, 0x33, 0x8a, 0xd7, 0x42, 0x5e, 0xbb, 0x1c, 0xba, 0x6b, 0xa1, 0xbd, 0x13, 0xd1, 0x7a, + 0xba, 0xd5, 0xe2, 0x68, 0x3a, 0x40, 0x80, 0x01, 0xe5, 0x9e, 0xb1, 0xee, 0x7f, 0x75, 0xf9, 0xc3, + 0xc9, 0x80, 0x3a, 0x33, 0x2b, 0xb4, 0xf1, 0xdd, 0x4d, 0x48, 0xcd, 0xac, 0x92, 0x90, 0x26, 0x88, + 0x25, 0x72, 0xf7, 0x17, 0x8a, 0xe2, 0xbc, 0x18, 0x82, 0x10, 0xa1, 0x0b, 0x97, 0x48, 0x52, 0x44, + 0xc0, 0x15, 0x1e, 0xf5, 0xdc, 0xc6, 0xa1, 0x8d, 0xf0, 0x00, 0x29, 0xca, 0xc0, 0x25, 0x0f, 0x61, + 0x29, 0x60, 0x01, 0xf3, 0x11, 0xe3, 0x1a, 0x7a, 0xfa, 0x0c, 0xf5, 0x75, 0xe6, 0x5c, 0x08, 0x20, + 0x96, 0xaa, 0xaa, 0xaa, 0xaa, 0x22, 0xd0, 0x09, 0x8b, 0x8b, 0xa2, 0x2b, 0x3a, 0x1c, 0x07, 0xb1, + 0x60, 0xbd, 0x7b, 0xeb, 0xdf, 0x5e, 0x9b, 0xaf, 0x45, 0x62, 0x50, 0x86, 0x85, 0x7a, 0x2b, 0xb8, + 0x10, 0x41, 0x00, 0xa1, 0x92, 0x7a, 0x07, 0x5e, 0x80, 0x66, 0x85, 0xb6, 0x33, 0x7c, 0x10, 0x8c, + 0x31, 0xfe, 0x58, 0x1c, 0x18, 0xa1, 0x8f, 0x2e, 0xef, 0x1d, 0x68, 0x62, 0x3e, 0x0f, 0x17, 0xb6, + 0xec, 0xdf, 0x06, 0x20, 0xc4, 0xa7, 0x3e, 0xc9, 0xf9, 0x64, 0x82, 0x90, 0x10, 0x28, 0x22, 0x3b, + 0x1f, 0xc1, 0x08, 0x64, 0x22, 0x12, 0xcb, 0x82, 0x1c, 0x9a, 0xed, 0xd9, 0x3a, 0xc9, 0x7c, 0x10, + 0x88, 0x18, 0x69, 0x70, 0x40, 0x38, 0x58, 0x31, 0x59, 0xf5, 0x03, 0x46, 0x01, 0x90, 0xb0, 0x67, + 0xc1, 0x47, 0x96, 0x67, 0x07, 0x05, 0xcb, 0xf0, 0x52, 0x07, 0x80, 0xa4, 0x0f, 0x80, 0x00, 0x40, + 0x09, 0x43, 0xd0, 0x00, 0x94, 0x8c, 0x04, 0xa1, 0xe9, 0x28, 0xa1, 0x2e, 0xf5, 0xcb, 0x30, 0xaf, + 0xa5, 0x93, 0x34, 0x3c, 0x7c, 0x74, 0x3f, 0xa9, 0x3a, 0x0c, 0x95, 0x24, 0xeb, 0x14, 0x77, 0x56, + 0xbe, 0xbd, 0x5d, 0x13, 0x2b, 0xe8, 0x53, 0x11, 0xb8, 0x67, 0x16, 0x40, 0x98, 0x63, 0xc2, 0xfc, + 0xe1, 0x10, 0x60, 0x08, 0x02, 0xc4, 0x66, 0xc9, 0xef, 0x89, 0xf2, 0x42, 0xa2, 0xcc, 0x47, 0x8c, + 0x63, 0x7b, 0xab, 0xff, 0x12, 0x14, 0x8d, 0xd9, 0x2b, 0x04, 0xae, 0x5c, 0x2c, 0xc0, 0x43, 0x19, + 0x63, 0x8d, 0xd7, 0x32, 0xaf, 0x36, 0x11, 0x78, 0x4c, 0x0f, 0xeb, 0xc1, 0x7c, 0x03, 0x92, 0xe4, + 0x00, 0x23, 0x40, 0xef, 0xec, 0x2e, 0xe0, 0x06, 0x25, 0x68, 0xcc, 0xb4, 0x3b, 0xaa, 0x3b, 0x1f, + 0xcc, 0xcd, 0xcc, 0x9e, 0x1f, 0xeb, 0x14, 0x41, 0xe8, 0xf8, 0x28, 0x0b, 0x8c, 0x85, 0x1c, 0x8b, + 0xc5, 0x5f, 0x03, 0xa8, 0x77, 0x03, 0x77, 0x21, 0x84, 0x3a, 0xd8, 0xd6, 0x79, 0xbf, 0xfc, 0x20, + 0x30, 0xce, 0x81, 0xc1, 0xc6, 0x6c, 0x47, 0x1c, 0x11, 0xc9, 0x92, 0x41, 0xcb, 0x3c, 0x1d, 0x45, + 0xd5, 0x70, 0x88, 0x44, 0x28, 0x34, 0x95, 0xe2, 0x7d, 0x55, 0x97, 0x97, 0xaa, 0x51, 0x71, 0x75, + 0xdd, 0xc5, 0x6f, 0x84, 0xd8, 0xc0, 0x06, 0x32, 0x74, 0xdc, 0xb9, 0x7f, 0xfb, 0xac, 0x4f, 0xfd, + 0x05, 0xde, 0x19, 0x88, 0xd7, 0x57, 0x45, 0x75, 0xef, 0xae, 0x57, 0xd6, 0xa8, 0x28, 0xa1, 0xf6, + 0x59, 0xbf, 0xff, 0xf8, 0x44, 0x14, 0x07, 0xc2, 0x51, 0x21, 0x62, 0x24, 0xb0, 0x6e, 0x71, 0xe6, + 0xe7, 0x7b, 0xf7, 0x1c, 0x18, 0xd0, 0xd5, 0xd5, 0xff, 0x04, 0x00, 0x58, 0x0a, 0x44, 0x7f, 0x88, + 0xf8, 0xc6, 0x00, 0xb4, 0x17, 0x60, 0x83, 0x46, 0x09, 0x21, 0xf7, 0x52, 0xfb, 0x8f, 0x60, 0xd9, + 0x46, 0x73, 0x40, 0x07, 0x78, 0xc0, 0x80, 0x6b, 0x19, 0xe1, 0x10, 0x50, 0x24, 0x93, 0xc6, 0xc6, + 0xcf, 0xa8, 0x41, 0xb8, 0x29, 0x8a, 0x1b, 0x77, 0xcf, 0xa4, 0x10, 0x68, 0xf8, 0x60, 0x20, 0x3a, + 0x60, 0xc1, 0x34, 0x1a, 0x30, 0x5b, 0xee, 0xd0, 0x3a, 0xa8, 0xbc, 0x33, 0x09, 0x80, 0x10, 0x3e, + 0xaa, 0x20, 0xcf, 0x3f, 0x13, 0xff, 0x5f, 0x7b, 0x85, 0x54, 0x03, 0x8c, 0x2d, 0x80, 0x3b, 0xb3, + 0x08, 0xf1, 0xca, 0xab, 0xff, 0xfc, 0x10, 0x89, 0x1c, 0x10, 0x15, 0xc5, 0x19, 0x48, 0x69, 0x27, + 0x14, 0x74, 0x42, 0x47, 0xb5, 0x2a, 0xc2, 0x08, 0x2e, 0x3e, 0xfa, 0xb1, 0x2e, 0x19, 0x45, 0x79, + 0x7a, 0x34, 0x57, 0xdd, 0xdd, 0xfe, 0x13, 0xbb, 0xea, 0xbf, 0xab, 0x93, 0xf3, 0x56, 0xb5, 0x88, + 0x56, 0x3e, 0xb9, 0x7c, 0x11, 0xea, 0xaa, 0xe7, 0xc1, 0x1e, 0xdd, 0xb4, 0xac, 0x74, 0x0c, 0x20, + 0xc3, 0x88, 0x06, 0x20, 0x98, 0x20, 0xb8, 0xba, 0x6b, 0x57, 0x1a, 0x03, 0x1c, 0x0f, 0x84, 0x02, + 0x95, 0xac, 0x72, 0x36, 0x49, 0x02, 0x80, 0x1a, 0x4d, 0x32, 0x52, 0x12, 0x0a, 0xa8, 0xb8, 0xde, + 0x49, 0x8f, 0x00, 0x07, 0x9e, 0x07, 0x92, 0x00, 0x14, 0x1c, 0x67, 0xe1, 0x02, 0x17, 0xb4, 0x5e, + 0x65, 0x07, 0x7e, 0x59, 0xee, 0x9b, 0xbe, 0x09, 0xc4, 0xb6, 0x26, 0xc0, 0x57, 0x42, 0xf3, 0xcf, + 0x24, 0xa0, 0x0b, 0x86, 0x85, 0x32, 0x02, 0xdf, 0x05, 0x26, 0x93, 0x61, 0x39, 0x7c, 0x8b, 0xd6, + 0xd6, 0xfd, 0xe0, 0x85, 0x8b, 0x17, 0xf8, 0x44, 0x0a, 0x23, 0xa2, 0xe9, 0x8b, 0xa8, 0xac, 0x57, + 0x75, 0x52, 0x7f, 0x08, 0x01, 0x44, 0x48, 0xcb, 0x7f, 0x7a, 0x30, 0xea, 0x8e, 0xa3, 0x87, 0x4b, + 0xb1, 0x8f, 0x04, 0x61, 0x75, 0x5e, 0xcf, 0xab, 0xd7, 0x56, 0x23, 0x39, 0x89, 0x5a, 0x9c, 0x7b, + 0x17, 0xca, 0xdb, 0x6d, 0xb7, 0xeb, 0xa1, 0x0e, 0xf8, 0x23, 0xbd, 0xf5, 0x2f, 0x38, 0xa8, 0x2f, + 0x2f, 0xff, 0xa1, 0x71, 0x46, 0x75, 0x1d, 0xb8, 0x20, 0x10, 0x0a, 0x87, 0x0d, 0x29, 0xc7, 0x2d, + 0xf8, 0x2e, 0x29, 0xd9, 0xbd, 0xb5, 0x8e, 0xec, 0x37, 0x20, 0x01, 0x1f, 0x9e, 0x46, 0x40, 0x22, + 0xe7, 0xf3, 0xee, 0x39, 0x77, 0x59, 0x77, 0xad, 0x59, 0xf2, 0xfd, 0xfa, 0xd7, 0x08, 0x89, 0x08, + 0x45, 0x37, 0x17, 0x75, 0xad, 0x1d, 0x6b, 0xa0, 0xad, 0x70, 0x80, 0x14, 0x41, 0x38, 0x48, 0xff, + 0x38, 0x0e, 0x09, 0xf6, 0x71, 0x75, 0x08, 0x62, 0x98, 0xa5, 0xa6, 0x09, 0x73, 0x70, 0x84, 0x4c, + 0xe0, 0x3d, 0x39, 0x7a, 0x0d, 0xf7, 0x8a, 0x67, 0x02, 0xc3, 0xd4, 0xb0, 0x88, 0x44, 0x28, 0x4b, + 0xdc, 0x56, 0x20, 0x70, 0x56, 0x78, 0x39, 0x13, 0xc5, 0x3c, 0xf3, 0xf8, 0x73, 0xca, 0x65, 0x04, + 0xc3, 0x58, 0xae, 0xe2, 0x03, 0x05, 0x26, 0xa9, 0x13, 0x5d, 0x04, 0xc7, 0xd2, 0xf5, 0x6f, 0xab, + 0x02, 0x76, 0x75, 0x5c, 0x9d, 0x19, 0x91, 0x42, 0xd4, 0x3d, 0xe1, 0xd8, 0xfa, 0xe8, 0x9a, 0xf9, + 0xaf, 0x7a, 0xe8, 0x95, 0xf2, 0xd5, 0x7f, 0x56, 0x23, 0x20, 0x84, 0x48, 0x2a, 0xde, 0xe2, 0x6c, + 0x27, 0x59, 0xb5, 0xd9, 0xe1, 0xd7, 0x40, 0xc6, 0x22, 0xb0, 0xbb, 0x14, 0x00, 0x9d, 0x4a, 0x1e, + 0x6f, 0xda, 0xaa, 0xb6, 0x4a, 0x25, 0x84, 0xb7, 0x2d, 0xc4, 0x8c, 0x0d, 0xcb, 0x1d, 0x70, 0x88, + 0x44, 0x64, 0x5d, 0x32, 0xfe, 0x6f, 0x2c, 0xe2, 0x9a, 0x83, 0xb7, 0x4e, 0x7c, 0x4a, 0x09, 0xf5, + 0x70, 0xa0, 0x52, 0xdc, 0xdc, 0x48, 0x58, 0x38, 0xf3, 0x83, 0xe6, 0x0e, 0x97, 0x89, 0x2c, 0x33, + 0xd6, 0x5b, 0x3f, 0xef, 0x89, 0x12, 0x20, 0xfc, 0xbe, 0x4e, 0xf1, 0x96, 0x30, 0xb6, 0x12, 0x11, + 0xe7, 0x3f, 0xfb, 0x7b, 0x7c, 0x48, 0x30, 0x1c, 0x20, 0x51, 0xe2, 0xb1, 0x59, 0x23, 0x45, 0x5d, + 0xf2, 0x31, 0x43, 0xc4, 0xb0, 0xb3, 0xaa, 0xf1, 0x01, 0x0b, 0xe8, 0x2e, 0xdf, 0x5a, 0xfa, 0x2b, + 0xcb, 0xd1, 0x9a, 0xba, 0xb7, 0xd5, 0xaf, 0x13, 0xf4, 0x56, 0xf8, 0x81, 0xfa, 0x49, 0x69, 0x24, + 0xba, 0x0b, 0x74, 0xd1, 0x1f, 0x90, 0x95, 0x3e, 0x54, 0x23, 0xa2, 0xe5, 0x15, 0x12, 0x18, 0x16, + 0x4d, 0xde, 0x8d, 0xb1, 0x1c, 0xe0, 0xa0, 0x28, 0x21, 0x5c, 0x57, 0x7f, 0x3f, 0x8d, 0x1e, 0x05, + 0x81, 0xd5, 0x27, 0xf4, 0x96, 0x67, 0x87, 0x9d, 0xe5, 0xe5, 0xe2, 0xf1, 0xc4, 0x03, 0x01, 0x92, + 0xc0, 0x31, 0x01, 0xe5, 0x80, 0x65, 0x9c, 0xe3, 0xd5, 0x37, 0x4b, 0x39, 0x17, 0x99, 0x88, 0xa9, + 0x8b, 0x87, 0xd7, 0x06, 0x01, 0x1b, 0xda, 0xe9, 0x53, 0xdc, 0x57, 0xc1, 0x40, 0x47, 0xb8, 0xae, + 0x4a, 0x3f, 0x41, 0x83, 0x54, 0xca, 0x2c, 0xae, 0xe0, 0xe0, 0x13, 0x1a, 0x95, 0x71, 0x79, 0xf7, + 0xc1, 0x50, 0xd1, 0x9a, 0xa3, 0x7f, 0xdc, 0x56, 0x5e, 0xfc, 0x97, 0x06, 0x7d, 0x4e, 0x5c, 0x40, + 0x44, 0x70, 0xc7, 0x72, 0xd8, 0xac, 0x56, 0x2b, 0x1f, 0x5e, 0xc6, 0xcc, 0xc0, 0x7b, 0x6b, 0xa7, + 0xd1, 0x33, 0x8f, 0x61, 0x13, 0x07, 0x98, 0x2f, 0xbe, 0x84, 0xb2, 0x6e, 0x08, 0x85, 0x34, 0xd5, + 0x72, 0xfb, 0xbc, 0xd9, 0x5c, 0xa2, 0x5d, 0xd5, 0x57, 0x35, 0x55, 0x54, 0x5f, 0x57, 0xae, 0x6e, + 0xef, 0xea, 0x44, 0xf9, 0x2a, 0xbb, 0xe0, 0x8a, 0xaf, 0x74, 0xcb, 0xd5, 0xd5, 0xc1, 0x15, 0x5e, + 0xb5, 0x15, 0x88, 0x31, 0x22, 0xaf, 0xc2, 0x20, 0x80, 0x48, 0xa7, 0xb5, 0xbb, 0xf0, 0x42, 0x10, + 0x19, 0x15, 0x8a, 0xdc, 0x56, 0x7c, 0xab, 0x5a, 0xd5, 0x6b, 0xc4, 0xc6, 0x45, 0x31, 0xca, 0x0a, + 0x71, 0x96, 0xdb, 0x15, 0x9b, 0xaa, 0x6c, 0x73, 0xf9, 0x7e, 0x11, 0x88, 0xcb, 0xee, 0x58, 0xc4, + 0xb8, 0xdd, 0x2c, 0x48, 0x90, 0xa1, 0x42, 0x8b, 0x7c, 0x81, 0xb9, 0x92, 0x75, 0xc2, 0xd5, 0xc8, + 0x1d, 0xa5, 0x3b, 0x15, 0xa7, 0x14, 0xce, 0x3d, 0x65, 0xfe, 0x10, 0x30, 0xad, 0xf8, 0xbe, 0xa3, + 0x95, 0x3f, 0x3e, 0x10, 0x12, 0x30, 0xce, 0xee, 0xe5, 0xb1, 0x03, 0xdc, 0xf7, 0xf1, 0x21, 0xc0, + 0xad, 0x08, 0x6d, 0x0b, 0xfc, 0x20, 0xc6, 0x89, 0xd6, 0xdb, 0xc7, 0xff, 0xc8, 0x36, 0xa9, 0x24, + 0xba, 0xd4, 0x5f, 0x58, 0xa7, 0xeb, 0x95, 0x62, 0x2b, 0xab, 0xd7, 0x5a, 0xfa, 0xe5, 0x8a, 0xce, + 0x47, 0x88, 0xf1, 0x17, 0xd6, 0x2e, 0x11, 0xad, 0x57, 0x31, 0xb5, 0x5f, 0x47, 0x79, 0xf1, 0x0b, + 0x5c, 0x48, 0x40, 0x58, 0x42, 0x68, 0x79, 0xa9, 0xc4, 0x02, 0x11, 0x97, 0x76, 0xee, 0x5f, 0x4f, + 0x51, 0x7c, 0x5d, 0x71, 0x01, 0x81, 0x85, 0x17, 0x17, 0x55, 0x14, 0xd4, 0xdc, 0xbe, 0x6c, 0x55, + 0x47, 0x06, 0x28, 0xe8, 0x8b, 0xf1, 0x22, 0x01, 0x59, 0x16, 0xaa, 0x8d, 0x5d, 0xd8, 0xc2, 0xe6, + 0xdc, 0x30, 0x11, 0xf0, 0x42, 0x28, 0x4a, 0xd5, 0xc5, 0xd6, 0xfc, 0x10, 0x04, 0x67, 0x31, 0x78, + 0xd7, 0xb3, 0x75, 0x53, 0xfe, 0xbc, 0x30, 0x30, 0x77, 0x44, 0xd6, 0x1c, 0xa1, 0xde, 0xdc, 0x91, + 0xa3, 0xbc, 0x67, 0x0b, 0x37, 0x8f, 0x88, 0xdf, 0x41, 0x71, 0xc6, 0xbe, 0x7f, 0x49, 0xb6, 0xff, + 0xea, 0x74, 0x93, 0x82, 0x3e, 0xab, 0xd5, 0xd6, 0x08, 0xa1, 0xf3, 0xc0, 0x4a, 0xaa, 0xab, 0xfe, + 0x30, 0x5a, 0x74, 0xe9, 0xd3, 0xa7, 0x4e, 0x9d, 0x3a, 0xc4, 0xa1, 0xdf, 0x9b, 0xa2, 0x26, 0x5e, + 0x8b, 0xd7, 0x88, 0x44, 0xd9, 0x27, 0x58, 0xbe, 0x89, 0x14, 0xbc, 0xc3, 0x89, 0xe4, 0xfc, 0x48, + 0x28, 0x1f, 0x5d, 0xdb, 0xd5, 0x55, 0x57, 0xc6, 0x44, 0xfc, 0x97, 0xaa, 0xea, 0xa2, 0x9a, 0x8a, + 0x62, 0x4a, 0x81, 0x79, 0x66, 0xbe, 0x26, 0xb2, 0xda, 0xaa, 0xd2, 0xc4, 0x02, 0x00, 0x81, 0xd5, + 0xfa, 0xa1, 0xac, 0xc3, 0x04, 0x81, 0x99, 0xe1, 0x81, 0x91, 0xae, 0x66, 0x4e, 0x6a, 0x4d, 0x29, + 0xae, 0xef, 0xc2, 0x10, 0x99, 0x65, 0x49, 0x9d, 0x54, 0x53, 0xf1, 0x83, 0x89, 0x52, 0xc6, 0x98, + 0xa3, 0x27, 0xce, 0x2b, 0x88, 0x58, 0x3c, 0x37, 0x5d, 0x06, 0x62, 0x93, 0xb3, 0x3d, 0xeb, 0xb3, + 0xad, 0x64, 0xe8, 0x8e, 0x4f, 0xd1, 0x7b, 0xe0, 0x8c, 0xda, 0xa9, 0x69, 0xba, 0x3c, 0x57, 0xd5, + 0xcb, 0xe5, 0xbb, 0xe3, 0xba, 0x8f, 0xbe, 0x28, 0x28, 0xb2, 0x7e, 0xab, 0x88, 0x08, 0x85, 0x2d, + 0xaa, 0xa4, 0xa2, 0xe5, 0xc8, 0x80, 0x35, 0x84, 0x61, 0xf0, 0xc8, 0x83, 0x54, 0xc2, 0x40, 0x3a, + 0x49, 0x66, 0x07, 0x88, 0x6a, 0x83, 0x64, 0x12, 0x07, 0x80, 0x3e, 0x29, 0xcc, 0xfb, 0xcb, 0x04, + 0x38, 0xd3, 0x9e, 0x24, 0x29, 0x53, 0xea, 0x12, 0x28, 0x93, 0x13, 0xbe, 0x31, 0xe5, 0xf3, 0x4b, + 0x03, 0xa1, 0xd6, 0xeb, 0x90, 0xdf, 0x8d, 0x3a, 0x69, 0xf7, 0x71, 0x5b, 0x9f, 0x17, 0xdd, 0xd6, + 0xdf, 0x0c, 0x84, 0x42, 0x90, 0x71, 0x17, 0x3c, 0x00, 0xe0, 0x31, 0x12, 0x87, 0x30, 0x4a, 0x58, + 0x06, 0x23, 0xc7, 0x0c, 0xd2, 0xa4, 0xc4, 0x08, 0x2c, 0x63, 0x5a, 0x30, 0xd4, 0xe1, 0x90, 0xf6, + 0x6b, 0xf0, 0xe8, 0x63, 0x2a, 0x88, 0xb3, 0x74, 0x4c, 0x13, 0x7e, 0x2e, 0x78, 0x73, 0x23, 0x1a, + 0x00, 0xa1, 0x73, 0x1a, 0xf0, 0x0c, 0x50, 0xf3, 0x71, 0x21, 0x80, 0x87, 0x97, 0x52, 0xc0, 0x19, + 0x80, 0x58, 0x6d, 0x59, 0x85, 0xe7, 0x8e, 0x19, 0x2f, 0x11, 0x27, 0x2b, 0x7f, 0xe6, 0x9c, 0x3e, + 0xdc, 0x22, 0x12, 0x13, 0x58, 0xbf, 0xad, 0x78, 0x81, 0x86, 0x25, 0x4e, 0x58, 0x67, 0x6a, 0x86, + 0xe3, 0x74, 0x65, 0x65, 0x3b, 0xbb, 0x6e, 0xf6, 0x78, 0x99, 0x61, 0x4a, 0x0d, 0x8a, 0xbe, 0x50, + 0x8b, 0xdf, 0xe0, 0x86, 0xfa, 0xc0, 0xd5, 0xc9, 0x55, 0x55, 0xf0, 0x5d, 0xd5, 0x55, 0xd5, 0xdc, + 0xbe, 0x4d, 0xee, 0xe2, 0x73, 0xf5, 0x72, 0xba, 0xea, 0xb8, 0x23, 0xbb, 0xbb, 0xa6, 0x44, 0xe1, + 0x22, 0xed, 0x35, 0xb4, 0xd3, 0xea, 0xf3, 0xf6, 0x67, 0xd7, 0xd1, 0x5e, 0xba, 0x2b, 0xd7, 0x44, + 0x7a, 0xeb, 0xd5, 0x12, 0x18, 0xe2, 0x44, 0x09, 0x1d, 0x24, 0xba, 0x8b, 0xae, 0x22, 0x14, 0x21, + 0xfe, 0x3d, 0x72, 0x18, 0xe6, 0x4f, 0x71, 0x91, 0xbd, 0xc6, 0x69, 0x25, 0x64, 0x9d, 0x85, 0x98, + 0xa6, 0x38, 0x10, 0x0a, 0x0a, 0x7d, 0x53, 0xba, 0xc7, 0x97, 0x10, 0x24, 0x21, 0x75, 0x05, 0x46, + 0xa8, 0x8c, 0xf7, 0x1e, 0xde, 0xa2, 0xf1, 0x1c, 0xc4, 0x42, 0x14, 0x35, 0x43, 0x76, 0xb2, 0xa9, + 0x25, 0xe1, 0x00, 0xc0, 0x8b, 0xd4, 0xe5, 0xa3, 0x22, 0xfc, 0x40, 0xc1, 0xaf, 0xf0, 0x52, 0x3e, + 0x4a, 0x3e, 0x29, 0x36, 0x8f, 0x62, 0x6d, 0x09, 0x1c, 0x68, 0x64, 0x39, 0x51, 0x75, 0x5e, 0x18, + 0x29, 0xd5, 0x55, 0x78, 0x82, 0x5b, 0x5a, 0xe2, 0x61, 0x31, 0x8f, 0xcd, 0xea, 0xdf, 0xca, 0x35, + 0x9c, 0x16, 0x5a, 0x99, 0x3a, 0x1a, 0xe5, 0xf5, 0x75, 0xc4, 0x09, 0x57, 0x89, 0xea, 0xe7, 0xc4, + 0x04, 0x74, 0x92, 0xd2, 0x49, 0x74, 0x10, 0xcb, 0xe5, 0x33, 0xea, 0x4c, 0x4a, 0xff, 0xe0, 0xb6, + 0xb5, 0xea, 0xbf, 0xfa, 0xf7, 0xd7, 0xbe, 0xbd, 0x27, 0x42, 0x7b, 0x1c, 0xa7, 0x20, 0xa3, 0xbe, + 0x25, 0x75, 0x27, 0x5d, 0x7d, 0x62, 0xf0, 0x81, 0x85, 0x71, 0x9c, 0xbc, 0x13, 0x99, 0xb5, 0x55, + 0xbd, 0x0f, 0xbe, 0x10, 0xaa, 0x99, 0x8e, 0x8f, 0x54, 0x78, 0x7c, 0x8f, 0xc2, 0x86, 0x22, 0x48, + 0xf1, 0xa6, 0x00, 0xf8, 0x1a, 0x74, 0xd8, 0x22, 0xa0, 0x37, 0xe1, 0x60, 0xc5, 0x82, 0xaa, 0xd9, + 0xe5, 0x99, 0xde, 0x94, 0x4c, 0x78, 0x81, 0x97, 0xf8, 0x0d, 0x4b, 0xc9, 0x43, 0xd7, 0x21, 0x9f, + 0x22, 0x41, 0x81, 0xc6, 0x66, 0x37, 0x3c, 0x64, 0x44, 0xc0, 0xfc, 0x6c, 0x20, 0xd3, 0x8c, 0xcf, + 0x66, 0xc3, 0xf1, 0x6c, 0x83, 0x9e, 0x25, 0xc0, 0x08, 0x87, 0x05, 0x4f, 0x39, 0x2f, 0x5e, 0x24, + 0x15, 0x9d, 0x8d, 0xe9, 0x82, 0xf4, 0x4f, 0x55, 0xd5, 0x5f, 0xee, 0x9b, 0xae, 0x15, 0x42, 0xc0, + 0x43, 0x4d, 0x40, 0x53, 0x1f, 0x5d, 0xba, 0x64, 0xa6, 0xdf, 0x84, 0x05, 0x91, 0x75, 0x97, 0x2f, + 0xe4, 0xa6, 0xf7, 0xe1, 0x82, 0x19, 0x21, 0x18, 0x47, 0xbb, 0x13, 0x08, 0x08, 0xe4, 0xbc, 0x9f, + 0x05, 0x4a, 0xcf, 0x8b, 0xba, 0x4d, 0x3e, 0x27, 0x27, 0x41, 0x54, 0xab, 0xd5, 0x88, 0x81, 0x68, + 0xb4, 0x6f, 0xea, 0xe8, 0x8e, 0xcc, 0xf7, 0xae, 0x8e, 0xe4, 0x4f, 0x57, 0x44, 0x43, 0x20, 0xc0, + 0x14, 0x0c, 0x7b, 0xb7, 0x71, 0x0e, 0x35, 0x03, 0x7c, 0x59, 0x0b, 0x97, 0xf3, 0x75, 0xcf, 0xc7, + 0x96, 0xcd, 0xdd, 0x2c, 0xc6, 0xd6, 0x7f, 0x14, 0x69, 0xe6, 0x0a, 0x90, 0xf0, 0xba, 0x2c, 0x27, + 0xf8, 0x80, 0x99, 0x27, 0xad, 0x2b, 0x7c, 0x48, 0xea, 0x55, 0x33, 0x4e, 0x72, 0xc4, 0x72, 0xaa, + 0xa9, 0x05, 0x30, 0x7a, 0xe3, 0x93, 0xe4, 0xda, 0x78, 0x91, 0x69, 0xaf, 0x75, 0xf8, 0xb8, 0xbf, + 0xe6, 0xf8, 0x91, 0x22, 0x4a, 0x7d, 0x76, 0xb7, 0x1e, 0x46, 0x38, 0x9f, 0xc5, 0x99, 0x56, 0xad, + 0x35, 0x5e, 0x20, 0xba, 0xd7, 0x10, 0x18, 0x1e, 0x48, 0xf2, 0x05, 0x81, 0xb3, 0xca, 0xcb, 0x92, + 0x7b, 0x16, 0x7f, 0x84, 0x07, 0x99, 0x25, 0x36, 0x79, 0x21, 0xab, 0xf8, 0x40, 0x11, 0x9c, 0x9e, + 0x42, 0x0a, 0xd4, 0x11, 0x62, 0x4e, 0x7b, 0xdb, 0x6d, 0x34, 0xff, 0xd7, 0x2a, 0xe5, 0xa4, 0x97, + 0x84, 0x20, 0x93, 0x93, 0x41, 0xc8, 0x78, 0x62, 0x40, 0xc3, 0x20, 0x40, 0x04, 0x62, 0x95, 0x62, + 0x48, 0xf7, 0x11, 0x1d, 0xbb, 0xbd, 0xe2, 0xbb, 0x8a, 0x37, 0x7f, 0x04, 0x27, 0x27, 0xd1, 0x7a, + 0xb8, 0x29, 0xcc, 0xc5, 0xdb, 0x22, 0x9b, 0xad, 0x57, 0xbe, 0x30, 0x55, 0xee, 0x2b, 0x88, 0x70, + 0x48, 0x3a, 0xa9, 0xb2, 0x3f, 0x7c, 0x0e, 0x59, 0xb4, 0x4e, 0xf1, 0xe1, 0x42, 0x82, 0x11, 0xbf, + 0x17, 0xcf, 0x4d, 0xe9, 0x04, 0xe1, 0xa1, 0x31, 0x5c, 0x50, 0x57, 0x15, 0xa5, 0x24, 0xd2, 0x02, + 0x39, 0xec, 0x40, 0xac, 0x42, 0x2a, 0x44, 0xa0, 0xdc, 0x0d, 0xd8, 0x92, 0x61, 0x8c, 0x90, 0x56, + 0x34, 0x98, 0x70, 0x88, 0x26, 0x17, 0x7d, 0xe3, 0x82, 0xca, 0xed, 0xd1, 0xa2, 0x03, 0xd5, 0x88, + 0x04, 0xc5, 0xcb, 0x8e, 0xde, 0xdb, 0x78, 0x81, 0x7a, 0xbd, 0x32, 0xe2, 0x53, 0x89, 0x10, 0x3a, + 0xf1, 0x72, 0x6a, 0x76, 0xcd, 0x0e, 0xdc, 0x4a, 0x5e, 0xa2, 0x44, 0x84, 0x88, 0xaa, 0xab, 0x5a, + 0xf8, 0xc9, 0x3d, 0xcc, 0x53, 0xbe, 0x4f, 0xdb, 0xf8, 0x8f, 0x10, 0x10, 0xf1, 0x05, 0x2e, 0x37, + 0x08, 0xc2, 0x3c, 0xa4, 0xab, 0xdf, 0x04, 0x7d, 0x24, 0xb2, 0xae, 0xfa, 0xab, 0xe8, 0x8f, 0x5c, + 0x25, 0x69, 0xaf, 0x69, 0xa3, 0xf0, 0x49, 0xd5, 0x5b, 0x81, 0x20, 0x40, 0x8e, 0xaa, 0x8d, 0x1a, + 0x35, 0xe0, 0xa0, 0x61, 0x15, 0x76, 0x61, 0x7e, 0xf7, 0x6d, 0xa6, 0x95, 0x70, 0xc8, 0x38, 0x19, + 0x55, 0xd4, 0x9a, 0x5a, 0x1c, 0x2a, 0x37, 0x15, 0x88, 0x78, 0x77, 0x6a, 0xfd, 0x2c, 0xfc, 0x14, + 0xce, 0x61, 0x5a, 0xf1, 0x82, 0x5f, 0x5a, 0xd2, 0x4a, 0xcb, 0xb8, 0x91, 0x06, 0x12, 0xba, 0xe1, + 0x19, 0x2e, 0xf7, 0xe2, 0x02, 0x86, 0x17, 0x17, 0x55, 0x32, 0x42, 0x79, 0x8d, 0x57, 0x37, 0x2c, + 0xd2, 0x17, 0xf7, 0x10, 0x24, 0x28, 0x29, 0x65, 0x36, 0xc8, 0x05, 0xfa, 0x0e, 0x86, 0xc7, 0xfc, + 0xb0, 0x8b, 0x83, 0x84, 0xb8, 0x5e, 0xe0, 0x39, 0x2b, 0xa0, 0x1d, 0x65, 0xe0, 0xe8, 0xe7, 0xcb, + 0xcb, 0x34, 0xbc, 0x4c, 0x29, 0xb0, 0x00, 0xaa, 0x2e, 0x1d, 0x0a, 0x90, 0x7e, 0x32, 0x4e, 0xb0, + 0xf1, 0xe7, 0x8e, 0xf0, 0xa3, 0x59, 0x50, 0x05, 0xfc, 0x58, 0x02, 0xf8, 0x58, 0x65, 0x98, 0x78, + 0xcb, 0xe1, 0xb3, 0x35, 0x62, 0x42, 0xbc, 0x4e, 0xe2, 0x04, 0x02, 0xb2, 0xa0, 0xa6, 0xd2, 0xa7, + 0x5e, 0x43, 0xc7, 0xc5, 0xb2, 0x3f, 0xa2, 0xa2, 0x33, 0x2a, 0x60, 0x9a, 0x53, 0x6c, 0xeb, 0x47, + 0x6e, 0x20, 0x48, 0xf1, 0xa9, 0xed, 0x69, 0xba, 0x97, 0xdf, 0x84, 0x4d, 0x5a, 0x25, 0xe2, 0x45, + 0x45, 0x77, 0x75, 0xda, 0xc4, 0x5d, 0x6c, 0xbb, 0xf1, 0x3f, 0x75, 0x5d, 0x42, 0x3e, 0x22, 0x0a, + 0x61, 0xd2, 0x57, 0x42, 0xfd, 0x4d, 0x01, 0xac, 0xcb, 0xcb, 0xde, 0xf1, 0xdb, 0x89, 0x85, 0x05, + 0x5d, 0x4e, 0x6b, 0x15, 0x94, 0x04, 0xb2, 0xaa, 0xaf, 0x00, 0x02, 0x45, 0x05, 0xfd, 0xe1, 0x05, + 0xef, 0x08, 0x14, 0x27, 0x88, 0x72, 0x6e, 0x1e, 0x08, 0x3e, 0x9c, 0xf7, 0xbe, 0xd5, 0x6e, 0xd1, + 0xb7, 0xfc, 0x11, 0x93, 0x49, 0xda, 0x23, 0x8b, 0x0a, 0xaa, 0xee, 0xff, 0x90, 0x95, 0x7f, 0x89, + 0xbd, 0xee, 0xf9, 0x39, 0xba, 0xaf, 0xb2, 0xaa, 0xeb, 0x82, 0x2d, 0x5e, 0xe9, 0xc3, 0x0a, 0x00, + 0xc2, 0x3f, 0x53, 0xef, 0xff, 0xff, 0xdb, 0x6c, 0x88, 0x70, 0x78, 0x14, 0x04, 0x82, 0x21, 0x92, + 0xd2, 0x87, 0xae, 0x0e, 0x41, 0x87, 0x08, 0x02, 0x10, 0x55, 0x7d, 0x9d, 0x69, 0xde, 0xfb, 0x3c, + 0x48, 0x2b, 0x8a, 0x0c, 0x56, 0x28, 0xdc, 0x56, 0xed, 0x1b, 0x1f, 0x95, 0x84, 0xf5, 0x08, 0xf8, + 0x21, 0x12, 0x08, 0x8e, 0xef, 0xcb, 0x88, 0x8c, 0x30, 0xbd, 0x6a, 0x65, 0x0b, 0x3a, 0xaa, 0xd3, + 0xf1, 0x20, 0xb4, 0x8e, 0x6b, 0x72, 0xc7, 0x77, 0x4d, 0xf8, 0x98, 0xc9, 0x21, 0x52, 0xe9, 0xb8, + 0x5b, 0xdb, 0x8d, 0xa8, 0x55, 0xa9, 0xf9, 0xde, 0xfc, 0x48, 0x81, 0x05, 0x5b, 0x98, 0xcd, 0x95, + 0xe2, 0x2b, 0xa2, 0xbf, 0x86, 0x44, 0xd5, 0x6e, 0xef, 0xf1, 0x1f, 0x31, 0x77, 0x49, 0x60, 0x80, + 0x71, 0xb3, 0x75, 0x77, 0xe9, 0x3b, 0xe2, 0x02, 0x02, 0xfa, 0xae, 0xab, 0x0d, 0x10, 0xe0, 0x24, + 0x77, 0xcf, 0xf9, 0xdb, 0x6f, 0xff, 0xda, 0xd8, 0xf8, 0x29, 0x30, 0xb8, 0xa6, 0xa2, 0xe2, 0x78, + 0x3c, 0x90, 0x5e, 0x7f, 0x15, 0x7e, 0xf8, 0x28, 0x14, 0x23, 0x84, 0xe4, 0xc2, 0xfa, 0x4b, 0x61, + 0x84, 0x60, 0x8c, 0x6d, 0x30, 0xb2, 0x85, 0xb9, 0x5d, 0x18, 0xc2, 0xf9, 0x08, 0x95, 0x3f, 0x82, + 0xd3, 0xdb, 0x9e, 0x3b, 0x63, 0xd9, 0xb1, 0xf0, 0x43, 0x43, 0x26, 0x73, 0x63, 0xe0, 0x88, 0x86, + 0x96, 0xcb, 0x0f, 0x82, 0x3c, 0xbb, 0xea, 0x16, 0xe0, 0x9c, 0x26, 0xef, 0xaa, 0xaa, 0x8e, 0xdc, + 0x0a, 0x01, 0x12, 0x0e, 0xc9, 0xfc, 0x48, 0x2e, 0xbd, 0xf1, 0x75, 0x5e, 0xa8, 0x98, 0xa8, 0xba, + 0xae, 0x5f, 0x15, 0xf0, 0x88, 0xc2, 0x67, 0xe7, 0xa3, 0xf7, 0xda, 0x74, 0x6f, 0x7f, 0x08, 0x89, + 0x39, 0xf2, 0xc7, 0x3b, 0x0f, 0xe2, 0x25, 0xbb, 0xd8, 0x3c, 0x20, 0x11, 0x04, 0x55, 0x5d, 0xf8, + 0x46, 0x3a, 0xb2, 0x77, 0x74, 0xc7, 0xff, 0x36, 0xd3, 0xf8, 0x82, 0x34, 0xfb, 0xbf, 0xc4, 0x9a, + 0xab, 0x5c, 0x20, 0x24, 0xa5, 0x27, 0x7f, 0x84, 0x22, 0x4e, 0x59, 0x7a, 0xaa, 0xe2, 0x04, 0x02, + 0x42, 0xaa, 0xaa, 0xa3, 0xbe, 0x0a, 0x3c, 0x21, 0xf1, 0x03, 0x33, 0x7b, 0xbf, 0x89, 0x08, 0x02, + 0x11, 0x2e, 0xee, 0xef, 0xc4, 0x09, 0x05, 0x44, 0x7d, 0xf7, 0x77, 0x1b, 0x42, 0x2f, 0x6a, 0xf5, + 0xe2, 0x02, 0x04, 0x7d, 0x6d, 0x7d, 0x49, 0x9e, 0x04, 0x80, 0x60, 0x08, 0x8f, 0x25, 0x24, 0xce, + 0xc3, 0x2a, 0x00, 0xc8, 0x34, 0xcd, 0x05, 0x7d, 0x04, 0xde, 0xde, 0xdf, 0x4d, 0x39, 0x75, 0x38, + 0xed, 0x85, 0x51, 0x40, 0x6b, 0x94, 0x55, 0x54, 0xc9, 0xb6, 0x93, 0xed, 0xb7, 0xd2, 0x4d, 0xac, + 0x33, 0x14, 0x45, 0x57, 0x37, 0xb6, 0x7c, 0xbc, 0x4c, 0x15, 0x8c, 0xd5, 0x62, 0xe2, 0xf5, 0x4e, + 0x2e, 0xbe, 0xe1, 0x18, 0x26, 0x2a, 0x6f, 0xe5, 0xcf, 0x5f, 0x0c, 0xdb, 0x89, 0x15, 0x51, 0xd5, + 0x7f, 0xc1, 0x11, 0xb4, 0x9e, 0x2f, 0xab, 0x95, 0xc5, 0x97, 0x97, 0x34, 0x9f, 0xd6, 0x0f, 0xae, + 0x5f, 0x53, 0xa5, 0xf0, 0x46, 0x5d, 0x55, 0x32, 0xf5, 0x4c, 0xbc, 0x13, 0x5d, 0xfb, 0xdb, 0x4c, + 0xbc, 0x12, 0x6a, 0xf7, 0x3e, 0x09, 0x35, 0xbb, 0x9f, 0x5d, 0x7d, 0x4c, 0x97, 0xd6, 0xc7, 0xd6, + 0x2f, 0xab, 0xc9, 0x06, 0x15, 0x83, 0x82, 0x10, 0xc0, 0x2e, 0xac, 0x9d, 0xba, 0xd7, 0x5e, 0x20, + 0x24, 0x5c, 0x65, 0x66, 0xeb, 0xc4, 0x04, 0x44, 0xd5, 0x7c, 0x99, 0x86, 0x9c, 0x27, 0x51, 0x28, + 0x74, 0xff, 0xff, 0xd7, 0x86, 0x07, 0x8a, 0x6d, 0x3d, 0xdc, 0xbe, 0xdd, 0xfc, 0x44, 0x20, 0x2c, + 0x57, 0x77, 0x12, 0xa8, 0xdd, 0xf9, 0x69, 0x84, 0x44, 0x88, 0x23, 0xde, 0xd2, 0xf8, 0x90, 0x80, + 0xf2, 0x88, 0xe0, 0xc2, 0xf9, 0x5d, 0x45, 0xd4, 0x49, 0xf8, 0x81, 0x2c, 0xce, 0xff, 0x12, 0x20, + 0xab, 0x32, 0x8a, 0xa4, 0x9f, 0xc4, 0x5b, 0xaa, 0x9b, 0xff, 0x08, 0xf8, 0x90, 0x8a, 0xf7, 0x08, + 0xc1, 0x18, 0x9a, 0x95, 0x4c, 0xdf, 0x88, 0x11, 0xf0, 0x98, 0xa3, 0x91, 0x6b, 0x77, 0xf0, 0x84, + 0xc2, 0x73, 0xfe, 0x11, 0x08, 0x84, 0xef, 0x7b, 0xbb, 0x97, 0xf1, 0x24, 0x14, 0xfb, 0x6b, 0x88, + 0x08, 0x88, 0x2b, 0x59, 0x20, 0xa2, 0x7e, 0xaf, 0x04, 0x22, 0x01, 0x19, 0x69, 0x5b, 0xec, 0x33, + 0x28, 0x03, 0x77, 0x8f, 0x09, 0x0a, 0x8f, 0xff, 0xa7, 0x15, 0x61, 0xb5, 0x8e, 0x11, 0x02, 0x80, + 0x52, 0x9e, 0xb2, 0xe2, 0xd4, 0xb5, 0x17, 0x4b, 0x69, 0xbc, 0x30, 0x0a, 0x65, 0xc4, 0xaa, 0x51, + 0xf6, 0x44, 0xed, 0x7e, 0x36, 0x23, 0x8f, 0x17, 0x71, 0x01, 0x06, 0x22, 0x93, 0xbe, 0x26, 0x0a, + 0x85, 0x4b, 0xb7, 0x51, 0x72, 0x90, 0xf4, 0xaf, 0x07, 0xc2, 0xc5, 0x5d, 0xde, 0x15, 0x15, 0xc1, + 0x5a, 0x94, 0x2f, 0xef, 0xd7, 0x05, 0x65, 0x9a, 0x9d, 0x24, 0xa9, 0x6e, 0xc7, 0xcd, 0x55, 0x5b, + 0xea, 0x60, 0x46, 0xf4, 0x5c, 0xab, 0xb2, 0xdb, 0xb7, 0xe5, 0xba, 0x4b, 0xf0, 0x47, 0xcb, 0x68, + 0xe2, 0xf9, 0xa9, 0xc9, 0xfe, 0xb1, 0x56, 0x20, 0x28, 0x65, 0x54, 0x94, 0xd0, 0x44, 0xc4, 0xaa, + 0x7c, 0xf3, 0x5b, 0x32, 0xf5, 0xeb, 0x6e, 0xa5, 0x9c, 0x22, 0x08, 0x02, 0x37, 0x7f, 0x0b, 0x7c, + 0xfe, 0x9d, 0x2f, 0x13, 0x77, 0x15, 0x8a, 0xdf, 0x5f, 0x7b, 0xbf, 0x08, 0x03, 0x00, 0x96, 0xb5, + 0xdd, 0xf1, 0x31, 0x86, 0x73, 0xf7, 0xd5, 0xec, 0x6f, 0x7d, 0x8d, 0xfc, 0x14, 0x0c, 0x3b, 0xbe, + 0xf7, 0x70, 0xad, 0x58, 0xd8, 0xb1, 0x5f, 0xc4, 0x46, 0x5d, 0xb7, 0x8b, 0x8e, 0x7b, 0x8a, 0xde, + 0x3b, 0x41, 0xb4, 0x9f, 0x36, 0x61, 0x11, 0x21, 0x4f, 0x12, 0xe2, 0x8a, 0x65, 0x99, 0x30, 0xee, + 0x3f, 0x58, 0xba, 0xaf, 0x78, 0x9f, 0x12, 0x5b, 0xbb, 0x4d, 0x70, 0x80, 0xbd, 0x45, 0xc5, 0xd5, + 0x7f, 0x5e, 0xe1, 0x10, 0x87, 0x0c, 0x08, 0xe2, 0x44, 0x92, 0x9b, 0xa7, 0xc4, 0x84, 0x78, 0x80, + 0x40, 0x6d, 0xd7, 0x0d, 0x4a, 0x00, 0x62, 0xb7, 0xf4, 0x9f, 0x6e, 0xff, 0xff, 0xbc, 0x4b, 0xeb, + 0xe0, 0x9c, 0x55, 0x56, 0xaa, 0xbe, 0xe2, 0x02, 0x25, 0x16, 0x9d, 0x53, 0x85, 0x14, 0x20, 0x58, + 0xaa, 0xff, 0x6d, 0xbf, 0x4d, 0x3b, 0x3c, 0x10, 0x01, 0x07, 0x0d, 0x28, 0x40, 0xc0, 0x87, 0xfb, + 0x7f, 0xfd, 0x7c, 0x75, 0x5a, 0x2e, 0xcd, 0x59, 0x24, 0xd5, 0x57, 0xc4, 0x72, 0x62, 0xae, 0xf8, + 0x80, 0x80, 0xa2, 0x2b, 0x7b, 0xdb, 0xe1, 0x98, 0x2e, 0x36, 0xb4, 0xa6, 0xc9, 0x30, 0x49, 0x03, + 0x89, 0x82, 0x33, 0xb1, 0xcf, 0x2c, 0x5c, 0xf8, 0x27, 0xad, 0x2b, 0x56, 0xb6, 0xfa, 0xb9, 0x37, + 0x29, 0x6b, 0x4f, 0xc5, 0xd7, 0x4d, 0x2a, 0x77, 0xcc, 0x64, 0x92, 0xfc, 0xd4, 0x92, 0xcf, 0xcb, + 0x97, 0x32, 0x75, 0x97, 0xd5, 0xb8, 0x20, 0x85, 0x22, 0xb7, 0xf9, 0xb9, 0x79, 0xf8, 0xaf, 0x8b, + 0xa1, 0x28, 0xd1, 0xff, 0x14, 0x57, 0x93, 0x9b, 0x8a, 0xfa, 0xc2, 0xce, 0x04, 0x55, 0x4e, 0xf3, + 0xdb, 0xff, 0xf8, 0x62, 0x11, 0xd2, 0x6b, 0x55, 0xf1, 0xdf, 0x45, 0x60, 0x4a, 0xd7, 0x1e, 0xc4, + 0x04, 0x02, 0x86, 0x7b, 0xcf, 0x43, 0xd2, 0xee, 0xe2, 0xb7, 0x9b, 0xd5, 0xfc, 0x22, 0x0a, 0xe5, + 0xb1, 0x5b, 0xbc, 0xc9, 0x04, 0xde, 0xdf, 0xbc, 0x20, 0x13, 0x2f, 0x77, 0x5a, 0x5c, 0x48, 0x63, + 0xc1, 0x00, 0x8a, 0xae, 0xa2, 0xe5, 0xcf, 0x12, 0x24, 0x79, 0x49, 0x93, 0x4d, 0x55, 0xed, 0x34, + 0x6f, 0x38, 0x91, 0x0c, 0x82, 0xe2, 0xff, 0x8c, 0x3d, 0xd8, 0xdd, 0x57, 0x5a, 0xdd, 0xfc, 0x4c, + 0x4f, 0x77, 0x77, 0xbe, 0x11, 0xfd, 0x88, 0x77, 0xba, 0xe5, 0x3b, 0xbb, 0xf1, 0x11, 0x06, 0xbb, + 0xbb, 0xee, 0xc7, 0x88, 0x82, 0xeb, 0xda, 0xad, 0x49, 0x8d, 0xc4, 0x42, 0x82, 0x56, 0xb5, 0x52, + 0xdc, 0xd4, 0x46, 0x1e, 0xb5, 0xe3, 0xf8, 0x42, 0x10, 0xe9, 0xba, 0xec, 0xaa, 0xab, 0xc4, 0x8e, + 0xb4, 0xf7, 0x9f, 0x2a, 0xd1, 0xe0, 0x68, 0x70, 0xca, 0x80, 0x48, 0xf4, 0xf0, 0xff, 0x3d, 0xdb, + 0x48, 0xbb, 0xa3, 0x73, 0xe0, 0xed, 0xd3, 0xd0, 0x74, 0xd1, 0x8d, 0x2f, 0x71, 0x1e, 0x20, 0x32, + 0x6b, 0xbf, 0xc2, 0x04, 0xbb, 0xdf, 0x08, 0xca, 0x6b, 0x1b, 0xf0, 0x8c, 0x16, 0x18, 0xda, 0xda, + 0x66, 0xe9, 0xee, 0x9e, 0x21, 0xc7, 0x32, 0x7c, 0x49, 0xee, 0xa9, 0xae, 0xa4, 0xe5, 0xd2, 0xa7, + 0xe0, 0x8a, 0xd5, 0xab, 0x57, 0x11, 0xe7, 0xd9, 0xb7, 0x5c, 0x44, 0x98, 0x96, 0x92, 0x58, 0xae, + 0x1e, 0xa7, 0x6b, 0x49, 0x5a, 0x54, 0xdd, 0x4a, 0x2e, 0x7e, 0x6f, 0xfe, 0x13, 0xd2, 0x5b, 0xb7, + 0x6f, 0xc8, 0x55, 0xb4, 0xd7, 0x97, 0xa4, 0x97, 0x82, 0xd3, 0x27, 0x4d, 0x2b, 0x6b, 0xb9, 0xf0, + 0x41, 0x83, 0x50, 0x94, 0xfa, 0x70, 0x1c, 0xb6, 0x3c, 0xa1, 0xd3, 0x25, 0x1d, 0x0b, 0x0e, 0xf3, + 0x80, 0x0f, 0x8c, 0x20, 0x9c, 0x0a, 0x21, 0x81, 0x49, 0x83, 0x36, 0x0e, 0x29, 0x44, 0xeb, 0x34, + 0xdf, 0x84, 0x40, 0xa0, 0x4d, 0x5a, 0x5e, 0x0a, 0x0a, 0x77, 0xdf, 0x88, 0x04, 0x7a, 0x57, 0xac, + 0x76, 0x14, 0xf7, 0x61, 0x6c, 0x10, 0x9d, 0x2c, 0xa7, 0xfe, 0x9f, 0xf1, 0x10, 0xa1, 0x1c, 0xfd, + 0xcb, 0x6e, 0x18, 0x01, 0x48, 0x72, 0xd9, 0xf2, 0xf7, 0x7a, 0x6f, 0xc4, 0x08, 0x05, 0x82, 0x37, + 0x77, 0xbc, 0xd9, 0x52, 0xfb, 0xe0, 0xac, 0x6e, 0x37, 0xdd, 0x65, 0x6b, 0xe1, 0x7a, 0xcc, 0xfd, + 0xc2, 0x31, 0xf6, 0xed, 0xdf, 0x57, 0xbf, 0xd5, 0xbc, 0x4d, 0x73, 0x6f, 0x4f, 0x89, 0xac, 0x4d, + 0x62, 0x42, 0x26, 0x8a, 0xde, 0xee, 0x2b, 0x6e, 0xa2, 0xe2, 0xf8, 0x89, 0xba, 0x49, 0x78, 0x82, + 0xb5, 0xa5, 0x5a, 0xf9, 0x8a, 0xaa, 0xa6, 0xfc, 0x20, 0x0b, 0x32, 0x77, 0xf1, 0xc5, 0xcd, 0x8d, + 0x2a, 0xb7, 0x08, 0x06, 0x04, 0x59, 0x02, 0x7e, 0x9a, 0xa7, 0x88, 0x85, 0x2d, 0x8b, 0xdd, 0x66, + 0x94, 0x92, 0x9b, 0x35, 0x5f, 0x71, 0x31, 0xda, 0x56, 0x9a, 0x96, 0xeb, 0x44, 0xd2, 0xe4, 0xbb, + 0xea, 0x20, 0x20, 0x08, 0x85, 0x1e, 0x1e, 0x94, 0xe1, 0x98, 0x52, 0xa9, 0x91, 0x88, 0xdb, 0x4d, + 0xd3, 0x71, 0x76, 0x31, 0x0e, 0xa6, 0xe7, 0x7b, 0x7e, 0x7f, 0x8b, 0x2d, 0x0d, 0x24, 0x35, 0x5f, + 0xc7, 0x54, 0xf9, 0x69, 0xab, 0x5d, 0x36, 0xdf, 0x09, 0xd2, 0xd5, 0xad, 0x3f, 0x17, 0xe4, 0xd6, + 0x32, 0xb1, 0xfc, 0x13, 0xd2, 0x6e, 0xf7, 0x76, 0x8e, 0x11, 0xf0, 0x51, 0xcd, 0x9a, 0x6d, 0xf5, + 0x5c, 0x13, 0xe9, 0x52, 0xa7, 0x27, 0x15, 0x3d, 0xf0, 0x4f, 0x93, 0x16, 0x24, 0x9d, 0x29, 0x65, + 0x7e, 0x10, 0xa4, 0xa9, 0x74, 0x92, 0x97, 0x13, 0x88, 0x9c, 0x13, 0x56, 0x95, 0x29, 0x73, 0x8c, + 0xae, 0x09, 0xf5, 0x68, 0x9d, 0xbc, 0x98, 0x5c, 0x63, 0xe0, 0x96, 0x9e, 0xad, 0x27, 0x3e, 0xe5, + 0x27, 0x0e, 0x12, 0x06, 0x2c, 0x2e, 0x0a, 0xf0, 0xbd, 0x00, 0x0b, 0x82, 0xb6, 0x9e, 0x06, 0x58, + 0xfd, 0xf8, 0x20, 0x02, 0x40, 0xd9, 0x67, 0x8d, 0x2e, 0x4a, 0xd6, 0xc7, 0xe9, 0x3e, 0x92, 0xd5, + 0x75, 0x39, 0x51, 0xff, 0xfc, 0x61, 0xd3, 0x15, 0xac, 0x51, 0xbb, 0xd6, 0x4f, 0xad, 0x78, 0x90, + 0x9e, 0x7f, 0x79, 0xbf, 0xe0, 0xb3, 0x63, 0x7d, 0xee, 0xde, 0xf2, 0xc2, 0xce, 0x64, 0xbf, 0xaf, + 0xfe, 0x29, 0xc2, 0x32, 0xcf, 0x50, 0xb6, 0x33, 0x6f, 0xdd, 0x3f, 0xff, 0x08, 0x84, 0x8c, 0xc6, + 0x3e, 0xcb, 0xde, 0xf8, 0x81, 0x22, 0xe4, 0xcc, 0x90, 0xba, 0x49, 0x78, 0xa3, 0xc5, 0x7d, 0x53, + 0xe2, 0x61, 0x12, 0xbb, 0x6f, 0x27, 0xee, 0xef, 0xc4, 0xcc, 0x4e, 0x4f, 0x0d, 0x28, 0x0a, 0xae, + 0x93, 0xfd, 0xfd, 0x57, 0xb2, 0xaa, 0x74, 0xbc, 0x48, 0x92, 0xea, 0x56, 0x27, 0xdc, 0x7a, 0x92, + 0xef, 0xf1, 0x26, 0xad, 0x5f, 0x11, 0x66, 0x5a, 0xfc, 0x71, 0x5c, 0x56, 0xee, 0x2b, 0x3f, 0x3f, + 0xdd, 0xc5, 0x6f, 0x86, 0x04, 0x82, 0x99, 0xef, 0xdb, 0x17, 0x43, 0xab, 0xd5, 0xfe, 0xe1, 0x01, + 0x00, 0xa0, 0xad, 0x28, 0x5d, 0xc0, 0x7f, 0x2a, 0xd4, 0x2f, 0xdf, 0x08, 0xd5, 0x3d, 0x22, 0x62, + 0xeb, 0x4b, 0xe0, 0x8f, 0x5a, 0xb7, 0x10, 0x19, 0x0a, 0x66, 0xab, 0x56, 0x99, 0x2a, 0xd3, 0x88, + 0xc1, 0x15, 0xb7, 0x0c, 0x89, 0x26, 0xd5, 0x2c, 0x47, 0x88, 0x12, 0x3e, 0x5c, 0xd9, 0x29, 0x21, + 0xeb, 0x7f, 0x08, 0x97, 0xb6, 0xab, 0x08, 0x10, 0xae, 0xf7, 0xc4, 0x89, 0xf1, 0x04, 0x08, 0x0b, + 0xf4, 0xfc, 0x36, 0x27, 0x57, 0x39, 0x70, 0x55, 0x5e, 0xaf, 0xdf, 0x2e, 0x9d, 0xcb, 0xc1, 0x25, + 0x57, 0x6f, 0x8f, 0x2a, 0x7a, 0xbc, 0x4d, 0x26, 0x9d, 0x3a, 0xe4, 0xd2, 0x36, 0xfe, 0x3e, 0x96, + 0x9b, 0x6d, 0xf6, 0xef, 0xe5, 0xa4, 0x92, 0x49, 0x2e, 0x0a, 0x8d, 0x6e, 0xda, 0x4c, 0x73, 0x32, + 0xb1, 0x3f, 0x2f, 0x96, 0xf7, 0xfa, 0xcb, 0xe1, 0x29, 0x77, 0x4c, 0xf8, 0xd3, 0x4d, 0x3e, 0x09, + 0xea, 0xa2, 0xf6, 0xc5, 0xd4, 0x53, 0x45, 0xdc, 0x10, 0x01, 0x20, 0x14, 0x98, 0x50, 0xc5, 0x0c, + 0x2d, 0xf1, 0x79, 0x7c, 0xed, 0x1a, 0xb6, 0xc3, 0x38, 0xce, 0x20, 0x23, 0xf2, 0x89, 0xd5, 0x57, + 0x09, 0x44, 0xbe, 0x5b, 0x5c, 0xb9, 0xc4, 0x04, 0x4b, 0x6a, 0xab, 0xc4, 0x0a, 0xea, 0xb6, 0xda, + 0xe2, 0x04, 0x16, 0x5c, 0x71, 0x5b, 0x78, 0x40, 0x4f, 0xc2, 0x44, 0x20, 0x80, 0x97, 0xfb, 0xbe, + 0x20, 0x48, 0xbd, 0x4a, 0xc7, 0xaa, 0xf1, 0x22, 0x2b, 0xa6, 0xf7, 0x7e, 0x24, 0x61, 0x45, 0x19, + 0xf8, 0xae, 0xb3, 0xf9, 0xf8, 0xf2, 0x97, 0x9b, 0x89, 0xb0, 0x5e, 0x7d, 0x8c, 0x44, 0x25, 0x7b, + 0xf3, 0x7f, 0x13, 0x50, 0x84, 0x29, 0xaa, 0xa6, 0xa9, 0xdf, 0x77, 0xdd, 0xaa, 0xf8, 0x8c, 0x56, + 0x7c, 0xee, 0xdf, 0x0c, 0x41, 0x16, 0xea, 0x9f, 0x7c, 0x14, 0x5a, 0x6e, 0x86, 0xb5, 0xb7, 0xc1, + 0x29, 0xf8, 0x12, 0xa7, 0x2d, 0xfe, 0xe2, 0x04, 0x82, 0xea, 0x8b, 0xaa, 0xaa, 0xfd, 0xc3, 0x32, + 0xf3, 0x41, 0x71, 0x01, 0x91, 0x7a, 0xde, 0xd5, 0x7c, 0x15, 0x5a, 0xb6, 0xb4, 0x9a, 0xd2, 0xbb, + 0x7c, 0x49, 0x33, 0x68, 0xa3, 0x2f, 0x9e, 0x3f, 0x10, 0x7a, 0x54, 0x9a, 0x6a, 0xbe, 0x58, 0xbd, + 0x53, 0xc2, 0x22, 0x0d, 0xad, 0x70, 0x84, 0xb7, 0xbb, 0xe1, 0x01, 0x1c, 0x23, 0x05, 0x86, 0x1b, + 0x5e, 0x26, 0xf5, 0x57, 0xd3, 0x8b, 0x86, 0x44, 0x07, 0x84, 0x2e, 0xaa, 0x2b, 0x37, 0x6f, 0x1d, + 0x4f, 0x73, 0x32, 0x7d, 0x89, 0x3e, 0x6e, 0xbf, 0xe1, 0x33, 0xb7, 0xda, 0xa6, 0xa9, 0xf8, 0x24, + 0xcd, 0x9e, 0x1f, 0x04, 0x94, 0xdd, 0xf0, 0x7c, 0x13, 0x5a, 0xdf, 0x49, 0x28, 0x3e, 0xee, 0x9d, + 0x7c, 0x7c, 0xda, 0x7d, 0x6a, 0xad, 0xa4, 0xf2, 0x7f, 0x93, 0xb4, 0xd0, 0xce, 0x0c, 0x34, 0xdb, + 0xb6, 0x9c, 0x5f, 0xb1, 0x56, 0xdb, 0x7e, 0xa0, 0x80, 0x09, 0x01, 0x41, 0x49, 0xb6, 0x9b, 0x6a, + 0x31, 0x85, 0x91, 0x46, 0xe2, 0x83, 0x6d, 0x75, 0x63, 0x88, 0x08, 0xa3, 0xb9, 0x51, 0x11, 0x27, + 0x6b, 0x55, 0xaf, 0x11, 0x04, 0xbd, 0x56, 0x9a, 0xdb, 0x89, 0x10, 0x53, 0x5e, 0xf8, 0x90, 0x8f, + 0x08, 0x41, 0x10, 0x95, 0xaf, 0xb8, 0x89, 0xb4, 0xe9, 0xf8, 0x9f, 0x3e, 0x8a, 0xf7, 0xe2, 0x22, + 0x73, 0xe2, 0xc9, 0x99, 0xbb, 0xf8, 0xaa, 0x49, 0x24, 0xee, 0x2b, 0x77, 0xc2, 0x02, 0x06, 0x10, + 0x47, 0x3d, 0x34, 0x9c, 0x66, 0xab, 0xbb, 0x9f, 0xff, 0x84, 0x06, 0x13, 0x26, 0x37, 0x32, 0xcc, + 0xbd, 0x48, 0xd7, 0x7e, 0xf7, 0xf1, 0x99, 0xca, 0xd6, 0xaf, 0x7b, 0xdf, 0x88, 0x8e, 0x2a, 0xd7, + 0xbb, 0xbb, 0xf8, 0x62, 0x09, 0x6a, 0xbd, 0xe6, 0xed, 0xc2, 0x10, 0x4b, 0x3e, 0x3f, 0x35, 0xba, + 0xdb, 0xe1, 0x12, 0xaa, 0xb7, 0x24, 0xb9, 0x97, 0xfe, 0x0b, 0xa4, 0xc5, 0x3f, 0xcb, 0xfb, 0x71, + 0x10, 0x45, 0x37, 0x55, 0x5f, 0x71, 0x00, 0xc0, 0x27, 0x57, 0x17, 0xd5, 0x47, 0xa9, 0x0b, 0x4a, + 0x04, 0xdf, 0x43, 0x87, 0xcf, 0xff, 0xeb, 0x62, 0xc4, 0x7e, 0x30, 0xd5, 0xa7, 0x6e, 0x37, 0x72, + 0x9d, 0xa7, 0xed, 0xe2, 0x04, 0x8b, 0x97, 0x7b, 0x7a, 0x6e, 0xb8, 0xf1, 0x2b, 0x8b, 0xaa, 0xa8, + 0xbc, 0x5d, 0x57, 0x0c, 0x89, 0x09, 0x11, 0xd5, 0x59, 0x2d, 0x78, 0x98, 0x4b, 0xbb, 0xd5, 0x7c, + 0x48, 0x28, 0xda, 0x37, 0x2f, 0xaa, 0xad, 0x7c, 0xc4, 0x58, 0xba, 0xf0, 0x87, 0xc1, 0x11, 0xb7, + 0x37, 0xae, 0x24, 0x14, 0x02, 0x6a, 0xba, 0x52, 0xb2, 0x5d, 0x09, 0x17, 0x17, 0xf5, 0xf2, 0x95, + 0x24, 0xb7, 0xc2, 0x74, 0x36, 0x34, 0x33, 0x36, 0xb7, 0xf1, 0x7d, 0x52, 0xd2, 0x48, 0x57, 0x05, + 0xdb, 0x56, 0xad, 0xae, 0x2a, 0x83, 0x00, 0x50, 0x30, 0xc9, 0xb8, 0xb6, 0x28, 0xc5, 0x62, 0x41, + 0x60, 0x43, 0xd3, 0x82, 0x82, 0x62, 0x05, 0x88, 0x85, 0x8d, 0x3d, 0x60, 0x9f, 0x66, 0xf8, 0xf8, + 0xa8, 0xea, 0x33, 0xf1, 0x69, 0x97, 0xbd, 0xde, 0xef, 0x08, 0x90, 0x4a, 0x06, 0xd2, 0xaf, 0x98, + 0x8b, 0xaf, 0x84, 0x04, 0x5b, 0x78, 0xae, 0xfa, 0xd7, 0x84, 0x4a, 0x35, 0x22, 0xed, 0x54, 0x44, + 0x61, 0x73, 0xe5, 0x4a, 0xc1, 0x32, 0xde, 0xf5, 0x36, 0x1b, 0xb3, 0xf8, 0xe9, 0x6f, 0x55, 0x4d, + 0x2c, 0x9f, 0xc4, 0x08, 0x36, 0x4c, 0x5f, 0x0c, 0x4a, 0x45, 0xdf, 0x04, 0x1f, 0x08, 0x8b, 0x27, + 0x2d, 0x6a, 0x8d, 0x2c, 0x14, 0x08, 0xf0, 0xc0, 0xa3, 0xdd, 0xe7, 0xfa, 0xe1, 0x88, 0x52, 0xef, + 0xb6, 0xb5, 0x5a, 0xea, 0x66, 0x2b, 0x6e, 0x08, 0x20, 0x8b, 0x43, 0x5b, 0x71, 0x02, 0x01, 0x25, + 0x55, 0x55, 0xbe, 0x09, 0xa9, 0xef, 0xaa, 0xfb, 0xe0, 0x8e, 0xba, 0xfb, 0x82, 0x10, 0x70, 0x0a, + 0x8a, 0xe2, 0x7e, 0xdd, 0x56, 0x9d, 0x71, 0x7f, 0x61, 0x97, 0x00, 0x62, 0x54, 0xf2, 0x37, 0x5e, + 0xac, 0x53, 0x7f, 0x3c, 0x38, 0x4a, 0x85, 0x9a, 0x89, 0x7e, 0x43, 0x2a, 0xeb, 0x10, 0xef, 0xbf, + 0x9b, 0xaa, 0xe2, 0x43, 0x3c, 0x31, 0xf9, 0xb7, 0xbe, 0x22, 0x10, 0x22, 0xaf, 0xbb, 0x6d, 0xaa, + 0xaf, 0x0c, 0x71, 0x1f, 0x8a, 0x3c, 0x65, 0x09, 0xf3, 0xf7, 0x77, 0xc4, 0x88, 0x05, 0x42, 0x0b, + 0xc6, 0x90, 0x1a, 0x13, 0x1b, 0xa6, 0xfc, 0x2b, 0xc0, 0xf5, 0xf4, 0x78, 0xbe, 0x12, 0x99, 0x8b, + 0x7b, 0x76, 0xbd, 0xd2, 0x4b, 0xf7, 0x5a, 0x49, 0x2e, 0xef, 0x5a, 0xe0, 0x8a, 0xdb, 0x7e, 0x55, + 0xdd, 0x50, 0xd3, 0xfb, 0xb5, 0x97, 0x7c, 0x94, 0xf6, 0x89, 0xdd, 0x52, 0xd6, 0x20, 0xdd, 0x57, + 0x10, 0x20, 0x70, 0xa1, 0x59, 0x6c, 0x48, 0x3d, 0xff, 0xca, 0xc0, 0x97, 0xfd, 0xe2, 0x6b, 0x0c, + 0x94, 0xaf, 0x7f, 0x8e, 0x33, 0xbb, 0xbb, 0xb6, 0x7f, 0x58, 0xad, 0xdd, 0xf8, 0x64, 0x20, 0x2e, + 0xab, 0xd5, 0xdb, 0xb6, 0x87, 0xe0, 0x8c, 0xaa, 0x2e, 0xa2, 0xed, 0xc3, 0x22, 0x5f, 0x9a, 0x18, + 0x90, 0xc0, 0x40, 0xa9, 0xed, 0xd5, 0x75, 0x55, 0xc2, 0x01, 0x02, 0x54, 0x5d, 0x7e, 0x0a, 0x08, + 0x9e, 0xba, 0x8b, 0xb7, 0x84, 0x02, 0x65, 0xd5, 0x55, 0x54, 0x9f, 0x12, 0x10, 0x04, 0x44, 0xb6, + 0xbe, 0xc3, 0x24, 0x28, 0x05, 0x4c, 0xe0, 0xaf, 0x6f, 0x53, 0x43, 0xaa, 0xe5, 0x84, 0xb0, 0x6c, + 0x2c, 0xc8, 0x04, 0x27, 0xb4, 0x74, 0xf7, 0x57, 0xfd, 0xd7, 0xe0, 0x9e, 0x96, 0xaa, 0xbb, 0x71, + 0x22, 0x17, 0xdf, 0x05, 0xc5, 0x5a, 0xd7, 0x76, 0xe1, 0x0a, 0xb7, 0x06, 0x02, 0x41, 0x16, 0xab, + 0xf6, 0x15, 0xc0, 0x13, 0xa9, 0xf8, 0x24, 0x1e, 0xd5, 0xaf, 0xfe, 0xbe, 0x08, 0x44, 0x91, 0x62, + 0xf3, 0x7e, 0xa2, 0x04, 0x7c, 0xdd, 0xdd, 0x72, 0xde, 0x2b, 0xe1, 0x11, 0x0e, 0xee, 0xfc, 0x40, + 0x91, 0x5c, 0xcc, 0xb7, 0x36, 0x56, 0x39, 0x88, 0x09, 0x58, 0x95, 0x3b, 0xc1, 0xc3, 0x3b, 0xc5, + 0x7c, 0x30, 0x04, 0x82, 0x14, 0x57, 0x6b, 0x89, 0x08, 0x94, 0x42, 0xac, 0x99, 0x89, 0x12, 0x2a, + 0xdf, 0x2f, 0xa2, 0xbe, 0x08, 0x61, 0xe8, 0xb9, 0x79, 0xa0, 0xc9, 0x7d, 0xbb, 0x65, 0xef, 0xe5, + 0xef, 0xfb, 0x5e, 0x7a, 0xfc, 0xbc, 0xd6, 0xdb, 0x6f, 0xc4, 0x82, 0x12, 0xa5, 0x7b, 0xfc, 0x27, + 0x69, 0x56, 0xdd, 0x64, 0xe0, 0xa3, 0xcf, 0x8d, 0x9b, 0xf7, 0xfa, 0xb0, 0x5c, 0x14, 0x69, 0xc9, + 0xdf, 0xab, 0xfd, 0x72, 0xf9, 0x2d, 0xa5, 0xe0, 0x40, 0x10, 0x34, 0x50, 0xb9, 0x7a, 0xd9, 0x63, + 0x71, 0xda, 0x56, 0x9b, 0x69, 0xb7, 0x54, 0x2e, 0x6a, 0x63, 0x19, 0x64, 0xa4, 0xff, 0xf8, 0x80, + 0x56, 0x71, 0x74, 0x46, 0x62, 0x8d, 0x8c, 0xec, 0xbd, 0x87, 0xb2, 0x23, 0xd4, 0xef, 0x92, 0x5c, + 0x40, 0x90, 0x49, 0x6e, 0x7e, 0x2b, 0x7e, 0x10, 0x12, 0x5b, 0xc5, 0x62, 0xbc, 0x44, 0xc5, 0x27, + 0xa6, 0xf8, 0x88, 0x46, 0xf7, 0x7d, 0xde, 0xa8, 0x6b, 0x84, 0x61, 0x41, 0x0e, 0x2b, 0x77, 0x7b, + 0x87, 0x05, 0x21, 0xc5, 0x71, 0x0f, 0x14, 0x6b, 0xd0, 0x3d, 0x42, 0x7a, 0x09, 0xde, 0x26, 0x14, + 0xb7, 0xae, 0xb5, 0xcc, 0xbd, 0x6f, 0x15, 0xf7, 0x04, 0x00, 0xe4, 0x48, 0x94, 0xdf, 0xd5, 0xf8, + 0x29, 0x11, 0x27, 0xd7, 0xaa, 0xc2, 0xa8, 0xe0, 0x10, 0x52, 0x93, 0x03, 0xef, 0xb3, 0x47, 0x5a, + 0xfe, 0x13, 0xc0, 0x08, 0x8f, 0xcf, 0x89, 0x1b, 0x9f, 0x23, 0xb3, 0xd5, 0x7f, 0xd6, 0x14, 0xc0, + 0x0e, 0x89, 0x2f, 0x8f, 0x0a, 0x7f, 0x6d, 0x54, 0xb4, 0x75, 0xf9, 0x69, 0xfc, 0x20, 0x0e, 0x44, + 0x55, 0x56, 0xb7, 0xc2, 0xd8, 0x21, 0x70, 0x43, 0xfe, 0xa3, 0xd6, 0x1a, 0x37, 0x64, 0xea, 0x78, + 0x4d, 0x07, 0x9c, 0x45, 0x13, 0xbc, 0x48, 0x24, 0xad, 0x6f, 0xc2, 0x11, 0xd4, 0xf4, 0xd5, 0x58, + 0xeb, 0x5e, 0x08, 0x20, 0x90, 0xab, 0x5b, 0x7c, 0x16, 0x6b, 0x53, 0x30, 0x6e, 0x66, 0x1d, 0xd3, + 0xc7, 0xef, 0x13, 0xc3, 0x30, 0x51, 0x51, 0x75, 0x13, 0x62, 0xb5, 0xf7, 0x83, 0x91, 0x15, 0xad, + 0x3a, 0xf0, 0x80, 0x40, 0x15, 0x12, 0xb5, 0x5d, 0x53, 0x37, 0xfb, 0x88, 0x84, 0xea, 0xaa, 0xbb, + 0x9f, 0xf8, 0x52, 0xaa, 0xba, 0xdb, 0x5e, 0xe9, 0xcb, 0xdd, 0xfe, 0x62, 0x55, 0xcb, 0x9e, 0x53, + 0x6e, 0xef, 0x13, 0xf0, 0x91, 0xda, 0xae, 0xb5, 0xe0, 0x50, 0x29, 0x16, 0x2f, 0xc4, 0x41, 0x41, + 0xdf, 0x7a, 0xd5, 0xb0, 0xcc, 0xe0, 0x4a, 0x2a, 0x56, 0xdf, 0xa7, 0xff, 0xef, 0x82, 0x41, 0x18, + 0xbd, 0xb8, 0x91, 0x3e, 0x24, 0x15, 0x12, 0x18, 0xfd, 0xaf, 0x15, 0x8e, 0xe2, 0xe1, 0x1f, 0x29, + 0xcb, 0xe6, 0x17, 0x4d, 0xdd, 0x72, 0x12, 0xd9, 0xfe, 0xb9, 0x7b, 0xb1, 0xa8, 0x00, 0x00, 0x00, + 0x01, 0x41, 0x9a, 0x56, 0x2b, 0x30, 0xe8, 0x2f, 0xd0, 0xfe, 0xb1, 0xb2, 0x87, 0xc3, 0xc9, 0x17, + 0x04, 0x21, 0x4a, 0xd6, 0x2e, 0xa2, 0xeb, 0xaa, 0xaa, 0xaa, 0xc5, 0x3f, 0x57, 0x23, 0xfa, 0xf4, + 0x5f, 0x46, 0x69, 0xba, 0xbc, 0xfd, 0x7a, 0xba, 0xf4, 0x9d, 0x7b, 0x81, 0x24, 0x20, 0xbd, 0x87, + 0x08, 0x38, 0x00, 0x6c, 0x38, 0x4f, 0x85, 0xb8, 0x64, 0xdf, 0x7f, 0x8d, 0xf3, 0xa8, 0x78, 0x38, + 0x3a, 0x0b, 0x83, 0x7a, 0xeb, 0x7c, 0x38, 0x6f, 0x10, 0x9a, 0x11, 0x4b, 0x06, 0xee, 0x29, 0xfb, + 0x07, 0x7e, 0x0e, 0xdd, 0xf4, 0x15, 0xea, 0xeb, 0xd7, 0xcb, 0x55, 0x55, 0x2f, 0x44, 0xef, 0xaf, + 0x7d, 0x7a, 0x6e, 0xbd, 0x0f, 0xe2, 0x78, 0x12, 0x42, 0x08, 0x9d, 0xc1, 0x48, 0x31, 0x0a, 0x04, + 0x01, 0x88, 0x94, 0xb0, 0xca, 0xa5, 0x42, 0x5d, 0x0a, 0xa0, 0x94, 0x98, 0x0d, 0x0f, 0x00, 0xf3, + 0x80, 0x3c, 0x75, 0x72, 0x53, 0x50, 0x3a, 0xb9, 0x44, 0x2a, 0x14, 0x95, 0x22, 0x28, 0x1d, 0x42, + 0xd8, 0xf4, 0x45, 0xf0, 0x52, 0x0c, 0x4b, 0x27, 0xb9, 0x83, 0xe9, 0x43, 0x64, 0x09, 0x87, 0x54, + 0x87, 0xff, 0xdf, 0xe9, 0xbf, 0xdb, 0x8c, 0xc1, 0xd5, 0xc6, 0x29, 0x8e, 0xe9, 0x13, 0xea, 0xd2, + 0xf5, 0xe8, 0xbe, 0x0a, 0x2e, 0xfb, 0xbe, 0x99, 0x7a, 0xa6, 0x4b, 0xab, 0xdf, 0x5e, 0xbe, 0xbb, + 0x21, 0x0e, 0x8e, 0xce, 0x08, 0x42, 0x1e, 0x08, 0x42, 0x81, 0x85, 0x15, 0x49, 0x42, 0x72, 0x82, + 0x2a, 0x2d, 0x32, 0x87, 0xb0, 0xa2, 0x01, 0x21, 0xcf, 0x11, 0xee, 0xe2, 0x0f, 0xdc, 0x00, 0x07, + 0x07, 0x78, 0xb2, 0x20, 0x00, 0x4a, 0xc2, 0x62, 0xf8, 0x5d, 0xd4, 0x26, 0x2d, 0x90, 0x10, 0xc1, + 0x90, 0xf6, 0xc0, 0xec, 0x19, 0x06, 0x43, 0xfb, 0xc4, 0xa0, 0x99, 0xda, 0xc3, 0xc8, 0xc0, 0x22, + 0xff, 0x01, 0xf6, 0xc6, 0xff, 0xff, 0x81, 0x6b, 0x69, 0xa5, 0xe3, 0x9d, 0xf8, 0x90, 0x2c, 0x85, + 0x07, 0x72, 0xf7, 0x2c, 0x06, 0x2f, 0xe4, 0xe0, 0x57, 0x27, 0xd7, 0xcc, 0x3e, 0xd4, 0xee, 0x6f, + 0xf7, 0xf0, 0x88, 0x53, 0x9c, 0xe0, 0x87, 0x0b, 0x60, 0x71, 0xc2, 0x55, 0x4a, 0x3c, 0x05, 0x82, + 0x80, 0xce, 0x16, 0x05, 0x19, 0x6f, 0x49, 0xdc, 0x88, 0xeb, 0x12, 0x02, 0x44, 0x29, 0xcd, 0x85, + 0xc1, 0xd1, 0x7c, 0x1b, 0x12, 0xe5, 0x80, 0xc9, 0x55, 0x12, 0xe1, 0x6d, 0x9b, 0x2d, 0xe2, 0xfa, + 0x0a, 0xbc, 0x7e, 0x23, 0xeb, 0x15, 0x0a, 0x57, 0x13, 0xd5, 0xfe, 0x09, 0x6b, 0x5d, 0x6a, 0x9c, + 0x04, 0xf5, 0xef, 0xaf, 0x5f, 0x5e, 0xb8, 0x66, 0x09, 0xc6, 0x45, 0x5c, 0x5c, 0x6a, 0xa3, 0x8f, + 0x1d, 0x0b, 0x97, 0x95, 0x3c, 0x0d, 0x21, 0x41, 0x07, 0x1f, 0x3b, 0xe0, 0xe7, 0x36, 0xb1, 0xe0, + 0x0f, 0x0e, 0x7e, 0x87, 0x07, 0xb3, 0x8a, 0xe3, 0x71, 0x65, 0x26, 0x0a, 0x94, 0xb0, 0x6c, 0x68, + 0x99, 0x25, 0x01, 0x08, 0x1d, 0xe7, 0x05, 0x20, 0x69, 0x19, 0x63, 0x05, 0xfd, 0x6b, 0xcb, 0xde, + 0xa1, 0xcc, 0xd7, 0xaf, 0xc2, 0x14, 0x1a, 0x84, 0xc6, 0xca, 0x1f, 0xff, 0xef, 0xdc, 0x22, 0x04, + 0x00, 0x88, 0x48, 0x1e, 0xe1, 0x5c, 0x48, 0xd3, 0x29, 0xaa, 0xaa, 0x67, 0x65, 0x83, 0x9c, 0x32, + 0x0e, 0x06, 0x14, 0xbf, 0xa3, 0xa5, 0xcb, 0x59, 0x66, 0x58, 0x64, 0xe4, 0xf7, 0x2b, 0x7b, 0x77, + 0x7c, 0x22, 0x18, 0x04, 0xc2, 0xc9, 0x9a, 0x77, 0x77, 0x77, 0x73, 0xc1, 0x88, 0xc1, 0xcf, 0x7b, + 0x6a, 0x0e, 0xaf, 0x2e, 0xee, 0xf5, 0xa9, 0xbc, 0xf0, 0x8a, 0x0b, 0xbc, 0xfd, 0x15, 0xe5, 0xe8, + 0xd9, 0x47, 0x75, 0x73, 0xeb, 0x17, 0xd5, 0x88, 0x42, 0x11, 0x82, 0xc1, 0xc2, 0x86, 0xa2, 0x0f, + 0xe2, 0x4f, 0x8a, 0x63, 0xef, 0x83, 0x2f, 0x04, 0x0c, 0x17, 0xc3, 0x6c, 0xc0, 0x0e, 0x47, 0xea, + 0xa1, 0x39, 0x77, 0x79, 0xdd, 0xe2, 0x70, 0x5f, 0x70, 0x56, 0xe5, 0xb7, 0x3f, 0x02, 0x76, 0xe1, + 0xe6, 0x04, 0xed, 0xc7, 0xfd, 0x6b, 0x09, 0xb8, 0x2f, 0xc8, 0x13, 0x28, 0xff, 0x4b, 0x34, 0x1f, + 0x7c, 0xd0, 0xd6, 0xfb, 0x84, 0x43, 0x3c, 0x40, 0x64, 0x15, 0x43, 0x1d, 0x17, 0x28, 0x1d, 0x35, + 0x2f, 0xbd, 0xcf, 0x61, 0x86, 0x15, 0x00, 0xc0, 0x64, 0x8f, 0x33, 0x1b, 0x5d, 0xbd, 0xda, 0xed, + 0x29, 0x96, 0x99, 0x10, 0x99, 0x10, 0x99, 0xe5, 0xac, 0xb5, 0xed, 0xc2, 0x20, 0xc4, 0xc6, 0x15, + 0xc5, 0x6f, 0xc1, 0xc0, 0x91, 0xce, 0xe2, 0xbb, 0xa9, 0xfc, 0xf0, 0x82, 0x0b, 0xff, 0xea, 0xf5, + 0xd5, 0xe3, 0x78, 0x28, 0xaa, 0xea, 0xba, 0x54, 0xe1, 0x0c, 0xbd, 0x59, 0xf5, 0xef, 0xae, 0x5f, + 0x52, 0x52, 0x75, 0xca, 0x33, 0x10, 0xb5, 0xc4, 0x82, 0x00, 0x54, 0x10, 0x37, 0x26, 0x03, 0x56, + 0x26, 0x31, 0x37, 0x26, 0xe7, 0xfd, 0xe0, 0xa4, 0x28, 0x41, 0x75, 0x17, 0x17, 0x2f, 0x38, 0xf1, + 0x3e, 0x5e, 0x2e, 0x2e, 0x59, 0x8a, 0x65, 0xe1, 0x40, 0xd0, 0x53, 0x29, 0x15, 0x1b, 0x89, 0x0c, + 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x91, 0x8e, 0xf2, 0x66, 0x27, 0x2b, 0x1b, 0x75, 0xd0, 0x57, 0xbc, + 0x30, 0x11, 0x1c, 0x86, 0xb2, 0x28, 0xaa, 0xd5, 0x9a, 0x2f, 0x1f, 0xb3, 0x2e, 0x78, 0x90, 0x20, + 0x8c, 0x1a, 0xd8, 0xbb, 0x62, 0x9a, 0x97, 0x93, 0xda, 0xd7, 0x7b, 0xf0, 0x72, 0x0a, 0x0d, 0x58, + 0xa7, 0x71, 0x27, 0x1d, 0xaf, 0xc4, 0x41, 0x31, 0x9e, 0x0e, 0xdd, 0x32, 0xaa, 0xa4, 0xae, 0xa3, + 0x3f, 0x4f, 0xd0, 0x4d, 0xfe, 0xae, 0x04, 0x75, 0x74, 0x2d, 0xc1, 0x0f, 0x77, 0x8a, 0x4c, 0x42, + 0xbd, 0xc4, 0xc1, 0x38, 0x85, 0x62, 0x41, 0x3e, 0x77, 0xc5, 0xe0, 0xc6, 0xa1, 0x6c, 0x36, 0xc5, + 0x00, 0x9d, 0xd1, 0x64, 0x41, 0xbc, 0xce, 0xab, 0xee, 0xab, 0x2d, 0xbb, 0x9f, 0xb6, 0x08, 0xa4, + 0xfa, 0xf8, 0x90, 0x88, 0xca, 0xb6, 0x2f, 0x13, 0xf0, 0x76, 0xe4, 0x64, 0x53, 0xf9, 0x3c, 0xc1, + 0x80, 0xbc, 0x20, 0x09, 0xe2, 0xea, 0xa6, 0xeb, 0xca, 0x47, 0xbc, 0x40, 0x92, 0xa3, 0x7c, 0x57, + 0xbb, 0xc2, 0xd3, 0x82, 0x6c, 0x7a, 0xb7, 0xff, 0xf3, 0xfc, 0x14, 0x81, 0x60, 0x83, 0x20, 0x6c, + 0x47, 0xe4, 0x82, 0x83, 0x03, 0x4b, 0x83, 0x16, 0x72, 0x3b, 0x56, 0x47, 0x7f, 0xbe, 0x82, 0x2f, + 0xf5, 0xef, 0xa2, 0xbc, 0xbd, 0x19, 0xeb, 0xab, 0xfd, 0x5e, 0x4e, 0x8a, 0xdf, 0x10, 0x3f, 0x3d, + 0x0f, 0x4c, 0xf4, 0x3d, 0x03, 0x78, 0x80, 0x48, 0x1a, 0x9b, 0xaf, 0x87, 0x84, 0x07, 0x88, 0x37, + 0x8d, 0xd6, 0xe5, 0x44, 0x48, 0x3a, 0xaf, 0x08, 0x05, 0x22, 0x98, 0x8f, 0x54, 0xc4, 0xbd, 0x6a, + 0xae, 0xab, 0x0c, 0x32, 0x37, 0x0b, 0x77, 0xde, 0x10, 0x08, 0xf9, 0x32, 0x92, 0xee, 0xef, 0xe2, + 0xe7, 0xa3, 0x3b, 0xb2, 0x37, 0x60, 0xfc, 0x40, 0x91, 0xc6, 0x3b, 0x1c, 0x5e, 0x56, 0x6a, 0x5f, + 0xc3, 0x23, 0x86, 0xbb, 0x8a, 0xef, 0x1b, 0x4c, 0x5b, 0xdb, 0xe2, 0x02, 0x23, 0x06, 0x3b, 0xb8, + 0x95, 0x20, 0xae, 0xec, 0xf8, 0xef, 0xd4, 0x47, 0xe0, 0xf9, 0x40, 0x5f, 0x05, 0x20, 0x80, 0x10, + 0x89, 0x2a, 0x77, 0x02, 0xef, 0x7d, 0x04, 0x5e, 0x12, 0xeb, 0xd2, 0x70, 0x49, 0xd2, 0x49, 0xa6, + 0xeb, 0x5f, 0x57, 0x03, 0x7b, 0x36, 0xef, 0xe4, 0x15, 0x9d, 0x47, 0x13, 0x09, 0xdf, 0x7a, 0xaa, + 0xe2, 0x6e, 0xaa, 0xa8, 0xfc, 0xda, 0xd7, 0x13, 0x0a, 0x15, 0x73, 0xf6, 0x12, 0x6c, 0x49, 0x2a, + 0xee, 0xb3, 0x35, 0xbf, 0xc2, 0x26, 0x61, 0x32, 0x37, 0x6d, 0x27, 0x9f, 0x15, 0xdf, 0x86, 0x02, + 0x26, 0x87, 0x15, 0x12, 0x24, 0x6e, 0x4e, 0xc5, 0xa3, 0x98, 0x77, 0xe2, 0x6f, 0x12, 0x82, 0xfd, + 0x5d, 0x6a, 0x5e, 0x4b, 0xde, 0xf9, 0xae, 0xf8, 0x8e, 0xbd, 0xf5, 0x98, 0x97, 0xa2, 0xf4, 0xfd, + 0x13, 0xbe, 0xbd, 0x15, 0xd7, 0xbc, 0x41, 0x87, 0x2d, 0x7e, 0x2f, 0x71, 0x0d, 0x09, 0x00, 0x15, + 0x14, 0x62, 0x8c, 0xf0, 0x07, 0x96, 0xfc, 0x5c, 0x56, 0xa2, 0xb3, 0x75, 0x4e, 0x4d, 0x9e, 0x09, + 0x37, 0x77, 0xef, 0x08, 0x04, 0x4b, 0x54, 0x94, 0x56, 0x28, 0xc4, 0x03, 0xcb, 0x00, 0x62, 0x07, + 0x2c, 0xb0, 0x18, 0xa3, 0xe1, 0x11, 0xda, 0xd6, 0xeb, 0x75, 0xf1, 0x12, 0xd6, 0xab, 0xc4, 0x84, + 0x05, 0x44, 0x79, 0x5e, 0x49, 0xc7, 0x9b, 0xe5, 0xbb, 0xe8, 0x2b, 0x5f, 0x5e, 0xbe, 0xb2, 0x97, + 0xaf, 0x57, 0x5e, 0x8b, 0xe2, 0x42, 0x67, 0x62, 0x76, 0x27, 0x62, 0x76, 0x2b, 0xa1, 0xdf, 0x9f, + 0xaf, 0x5f, 0x44, 0x9d, 0x37, 0x17, 0x77, 0x55, 0xdd, 0xc9, 0x13, 0xc3, 0x64, 0x08, 0x00, 0x03, + 0xb5, 0x04, 0xa4, 0x36, 0x73, 0x85, 0x25, 0x57, 0x22, 0x7b, 0x51, 0x2f, 0xad, 0xba, 0xdb, 0x52, + 0x70, 0x70, 0x19, 0x7c, 0x71, 0x6c, 0x23, 0x47, 0xa0, 0x75, 0x8b, 0x0c, 0xa2, 0x14, 0xb4, 0x84, + 0x23, 0xfd, 0xde, 0x00, 0x02, 0x7b, 0x26, 0x5a, 0xf3, 0xf6, 0xb1, 0x02, 0x02, 0x91, 0x5c, 0xd6, + 0xaa, 0x29, 0x99, 0x0e, 0xac, 0xe2, 0xc1, 0x45, 0xe3, 0xa8, 0xfd, 0xfc, 0x5e, 0x23, 0xcb, 0xe5, + 0x9f, 0x14, 0x48, 0xae, 0xf2, 0xff, 0x05, 0x20, 0xa0, 0x28, 0x5d, 0x36, 0xd3, 0x14, 0x19, 0xf8, + 0x97, 0x2e, 0xb1, 0x4d, 0xb0, 0xa5, 0x68, 0xc5, 0x18, 0x58, 0xa0, 0xd2, 0x16, 0x20, 0x1d, 0x53, + 0xb8, 0x81, 0x21, 0x4a, 0xad, 0x69, 0x5d, 0xb1, 0x70, 0xa0, 0x07, 0x81, 0x70, 0x0a, 0x01, 0xa7, + 0xa4, 0xb6, 0xe3, 0xb7, 0x84, 0x06, 0x1d, 0x56, 0xaa, 0xaa, 0xb5, 0x9b, 0xd5, 0x57, 0x10, 0x10, + 0x18, 0x2a, 0xf7, 0x9a, 0xd3, 0xd3, 0x93, 0xd7, 0x04, 0x12, 0x86, 0x6e, 0xef, 0x0c, 0x29, 0x88, + 0x3f, 0xfa, 0x69, 0xff, 0x42, 0x3d, 0x7a, 0x7e, 0xbd, 0x7d, 0x11, 0xe6, 0xe0, 0x86, 0xef, 0xb1, + 0x5c, 0xda, 0xd5, 0x70, 0x4f, 0x4d, 0xfd, 0xdc, 0xe2, 0x93, 0x87, 0x2e, 0xee, 0xed, 0x77, 0x77, + 0xf2, 0x44, 0x84, 0x05, 0x04, 0x9e, 0xed, 0x8a, 0xd6, 0x5d, 0x87, 0x70, 0x00, 0xe0, 0x00, 0x2c, + 0xf8, 0x0f, 0xe6, 0x0b, 0x9a, 0x53, 0x53, 0x23, 0x17, 0x3e, 0x12, 0x19, 0x18, 0x3d, 0x58, 0xa2, + 0xae, 0x2a, 0xe3, 0x5c, 0x88, 0xbe, 0xd5, 0xcd, 0x7c, 0xc0, 0x0b, 0x05, 0x86, 0xab, 0xe4, 0x00, + 0x59, 0x9f, 0x68, 0x8a, 0x6d, 0x79, 0xce, 0x82, 0x61, 0x58, 0x55, 0xb0, 0xcf, 0x41, 0x19, 0x4c, + 0x05, 0xab, 0x36, 0x02, 0x37, 0x66, 0xce, 0x34, 0xc2, 0xec, 0x35, 0xd3, 0xb2, 0x2a, 0x96, 0x57, + 0xc4, 0x85, 0x28, 0x86, 0xb8, 0x89, 0x91, 0x47, 0x89, 0x48, 0x35, 0x4c, 0x93, 0x0b, 0x84, 0xf4, + 0x83, 0xe0, 0x20, 0x32, 0x69, 0xea, 0xde, 0xce, 0x5b, 0xa1, 0x26, 0x48, 0xac, 0xc8, 0x33, 0x73, + 0xeb, 0x46, 0xfc, 0x40, 0x64, 0x56, 0x6d, 0x37, 0x67, 0x6c, 0xbe, 0xbc, 0x40, 0xc8, 0xe4, 0x03, + 0xe0, 0x35, 0x48, 0x94, 0x00, 0x02, 0x01, 0xae, 0xb8, 0x5c, 0x81, 0xa8, 0x61, 0x0b, 0x19, 0x4a, + 0xf7, 0x4c, 0x4c, 0xe0, 0x0d, 0xc2, 0xcc, 0x76, 0x2d, 0x5a, 0x4c, 0x17, 0xe8, 0x1e, 0x18, 0x86, + 0xa6, 0x60, 0x11, 0x72, 0xce, 0x45, 0xa1, 0x7c, 0x0f, 0x46, 0xa2, 0x7e, 0x0b, 0x8b, 0xb0, 0x33, + 0x32, 0x90, 0xc4, 0xb4, 0xf3, 0x61, 0x4a, 0x1c, 0x1f, 0x4d, 0xc5, 0xb2, 0xa4, 0xc6, 0xcf, 0xc1, + 0x62, 0x40, 0xa2, 0x14, 0xaa, 0x34, 0x35, 0x41, 0xca, 0x33, 0xc0, 0x33, 0x8f, 0x0e, 0xc0, 0x7a, + 0x12, 0xaa, 0xab, 0x32, 0x50, 0x06, 0xe3, 0xc7, 0xce, 0x4b, 0x10, 0xec, 0xe0, 0x7b, 0x9c, 0x3d, + 0x36, 0x17, 0x62, 0x40, 0x42, 0x2b, 0xc3, 0xd1, 0xd3, 0xfb, 0xda, 0xdb, 0xed, 0x5f, 0xe6, 0x99, + 0x3b, 0x3b, 0x78, 0x86, 0x69, 0x7d, 0xf8, 0x8f, 0x12, 0x82, 0x3d, 0xf5, 0xc2, 0xfa, 0xb1, 0x1b, + 0xd5, 0x8a, 0xeb, 0x28, 0x9e, 0x8a, 0xf1, 0x1d, 0x5e, 0xba, 0xbd, 0x44, 0x55, 0xeb, 0xaf, 0x54, + 0x48, 0x40, 0xc2, 0xa8, 0x98, 0x44, 0xa2, 0xe3, 0x05, 0x48, 0x54, 0x01, 0x9d, 0x72, 0x50, 0x00, + 0x4b, 0xe5, 0xc0, 0xae, 0xc9, 0x31, 0x5a, 0xe2, 0x60, 0xc5, 0xc5, 0xd6, 0x14, 0x0e, 0xcb, 0x34, + 0x8b, 0x2f, 0xc1, 0x3d, 0x54, 0x7a, 0x93, 0x2a, 0xaf, 0xef, 0x08, 0x16, 0xb4, 0xf8, 0x21, 0x0c, + 0x0c, 0xbf, 0xa3, 0x32, 0x69, 0x03, 0xaf, 0xf4, 0x64, 0xc0, 0xa3, 0x50, 0xb3, 0x10, 0x41, 0x52, + 0xab, 0x91, 0xd2, 0x68, 0x0c, 0x16, 0x81, 0x23, 0xdd, 0x8e, 0x7f, 0x9e, 0xe3, 0xe3, 0x8e, 0xce, + 0x14, 0x24, 0x21, 0x00, 0x55, 0xa6, 0x41, 0xdb, 0xa7, 0xde, 0xf5, 0x9d, 0x03, 0x8d, 0xfa, 0xeb, + 0x34, 0x06, 0xe2, 0x90, 0x7c, 0x6d, 0xc2, 0xbf, 0xa3, 0x4d, 0xbc, 0x7b, 0x6d, 0xe2, 0x01, 0x40, + 0x2c, 0x39, 0x3b, 0x71, 0x32, 0xd8, 0x9e, 0x0b, 0x96, 0x62, 0x99, 0x3d, 0xeb, 0xef, 0x10, 0xe9, + 0xbf, 0xe0, 0x9c, 0x66, 0x2f, 0x51, 0x78, 0xbb, 0xf1, 0x32, 0x8b, 0xc9, 0xe4, 0xe8, 0x7b, 0xcd, + 0xd5, 0xe2, 0x7a, 0xbf, 0xc4, 0x04, 0x73, 0xd0, 0xf4, 0xcf, 0x43, 0xd1, 0x74, 0x10, 0xe8, 0xae, + 0x09, 0x08, 0x96, 0x97, 0x56, 0x23, 0xe8, 0xfd, 0x5d, 0x75, 0x27, 0x5d, 0x7d, 0x62, 0xf1, 0x1f, + 0x08, 0x84, 0x16, 0x56, 0xd2, 0xeb, 0x5e, 0x20, 0x48, 0xaa, 0xad, 0x66, 0xcf, 0xc1, 0x51, 0x97, + 0x53, 0x5a, 0x48, 0x7a, 0xe3, 0xe3, 0xb8, 0x71, 0xc6, 0xe6, 0xaf, 0xf1, 0x92, 0x9f, 0x28, 0x8a, + 0xb6, 0x68, 0xf4, 0xc8, 0xc5, 0x67, 0x98, 0x1f, 0x85, 0x1d, 0x60, 0x75, 0x74, 0xae, 0x65, 0x78, + 0x98, 0x2e, 0x38, 0x24, 0xf2, 0x4b, 0xc7, 0xde, 0xab, 0xdf, 0x08, 0x57, 0x58, 0xbb, 0x42, 0xfd, + 0x57, 0x89, 0x05, 0x42, 0xda, 0x93, 0x14, 0x79, 0x4f, 0x03, 0xe6, 0x55, 0x7e, 0xe1, 0x10, 0xc0, + 0x82, 0x47, 0x27, 0xad, 0x2a, 0xe1, 0x22, 0x51, 0xac, 0x9f, 0xe2, 0x62, 0x05, 0x68, 0x97, 0x9a, + 0xf8, 0x9c, 0xbd, 0x05, 0xdc, 0x88, 0x16, 0xb4, 0x6f, 0xea, 0xe8, 0xae, 0xae, 0x44, 0xf5, 0x77, + 0x0c, 0xef, 0xa2, 0xa4, 0x5c, 0x4f, 0xd5, 0x2d, 0x42, 0x21, 0x81, 0x61, 0x4b, 0xbb, 0xa2, 0x77, + 0xa8, 0x81, 0x25, 0x38, 0xf5, 0x53, 0xaf, 0x8f, 0x32, 0xaa, 0xe9, 0x5d, 0x91, 0xff, 0xe1, 0x22, + 0x2a, 0xdb, 0x5d, 0x7c, 0x64, 0xa9, 0x74, 0x69, 0x09, 0x50, 0xda, 0x3d, 0x9f, 0x33, 0x04, 0xe6, + 0xb1, 0xdf, 0xac, 0xba, 0x6c, 0x0b, 0x4a, 0xc7, 0x3c, 0x44, 0x24, 0x2e, 0xdd, 0x71, 0x84, 0x1e, + 0x26, 0x6b, 0xdf, 0xc4, 0x94, 0xa4, 0xfd, 0xe2, 0x11, 0x9a, 0xb9, 0x85, 0x38, 0xad, 0xf8, 0x46, + 0x52, 0xea, 0xa0, 0x9a, 0x10, 0x08, 0x22, 0xf7, 0x08, 0x84, 0x11, 0xbb, 0xc4, 0x0e, 0xa5, 0x48, + 0xb9, 0x41, 0xbb, 0xbd, 0xfe, 0xce, 0xef, 0xe2, 0x44, 0x7c, 0xda, 0xa8, 0x57, 0x8f, 0x08, 0x8a, + 0x8c, 0xd2, 0x3d, 0xf5, 0x4c, 0xfe, 0x67, 0x79, 0x59, 0xd2, 0xdf, 0xc4, 0x04, 0x2f, 0xce, 0x0f, + 0xc0, 0xda, 0xa4, 0x1a, 0x0f, 0xca, 0x2e, 0x77, 0x10, 0xe5, 0xb1, 0x22, 0x4a, 0x24, 0x3f, 0x65, + 0xd7, 0x13, 0x73, 0xa5, 0xbc, 0xb8, 0x82, 0xd7, 0x7f, 0x12, 0x2e, 0x91, 0xfe, 0x7e, 0xd3, 0xf1, + 0x10, 0x86, 0xa8, 0x7d, 0xdd, 0x53, 0xae, 0x26, 0x08, 0xe9, 0x5a, 0xf7, 0xc8, 0x4d, 0x57, 0x84, + 0x09, 0x75, 0xae, 0x10, 0x08, 0x71, 0x01, 0x00, 0x44, 0x28, 0x60, 0x43, 0xd2, 0xfd, 0xc4, 0x04, + 0x05, 0xce, 0xde, 0xa9, 0x96, 0xfc, 0x48, 0x82, 0x89, 0xc3, 0xe8, 0x7b, 0x17, 0x12, 0x9d, 0xe1, + 0x7e, 0xad, 0xf2, 0x76, 0x9a, 0x2f, 0x24, 0xf8, 0x7c, 0xaf, 0xaf, 0x7d, 0x7b, 0xe4, 0xcf, 0x9e, + 0x08, 0x3e, 0x10, 0x04, 0x24, 0xd5, 0x4a, 0xb3, 0xe0, 0xba, 0x9d, 0x37, 0xaa, 0xaf, 0x78, 0x81, + 0x94, 0xe5, 0x93, 0x49, 0x5c, 0x1e, 0x79, 0xbb, 0x97, 0x88, 0x78, 0x77, 0x6b, 0x5f, 0xec, 0x8e, + 0xd6, 0xb8, 0x98, 0x21, 0x16, 0xf6, 0x13, 0xb3, 0xe0, 0xb6, 0xfb, 0xaa, 0xfd, 0xf0, 0xa1, 0x95, + 0x54, 0x5d, 0x4b, 0xd5, 0x2a, 0xcd, 0x19, 0x09, 0x3b, 0xe3, 0xdc, 0x44, 0x40, 0xa2, 0x42, 0xbe, + 0x5b, 0xc2, 0xc2, 0xd0, 0x73, 0x9e, 0x10, 0xf0, 0x34, 0xe6, 0x31, 0x5b, 0x96, 0x3d, 0xc1, 0xd7, + 0x8a, 0x5e, 0x0d, 0x7f, 0x3e, 0xe6, 0x71, 0x11, 0x25, 0xdf, 0x16, 0xa1, 0xa0, 0x22, 0x56, 0x95, + 0x5d, 0x3c, 0x46, 0xf8, 0xe1, 0xb5, 0xae, 0x9a, 0xea, 0xb8, 0x8f, 0xcb, 0x2e, 0x25, 0xfb, 0xcd, + 0xff, 0x09, 0x55, 0x75, 0xa5, 0xc4, 0x41, 0x6d, 0x46, 0x0b, 0x0e, 0x5f, 0x74, 0x65, 0x71, 0x01, + 0x41, 0x5b, 0x10, 0x64, 0xbd, 0x56, 0x6a, 0x20, 0x35, 0x5c, 0xbd, 0x76, 0xf0, 0x81, 0x63, 0x8b, + 0x00, 0x32, 0xbc, 0x20, 0x51, 0xb8, 0xda, 0xbb, 0x86, 0xf8, 0x8a, 0x49, 0x7a, 0x49, 0x12, 0x08, + 0x2a, 0xdf, 0x09, 0x08, 0x5b, 0xee, 0xff, 0x25, 0xf4, 0xf8, 0x90, 0x47, 0x5b, 0xdf, 0xc4, 0x82, + 0x92, 0xbe, 0x25, 0xe8, 0xd6, 0xac, 0xc5, 0x6e, 0xfa, 0x7f, 0x10, 0xcc, 0xaa, 0xb8, 0x6a, 0x2c, + 0x24, 0x17, 0x1f, 0xdf, 0xe8, 0x7f, 0xf6, 0xe0, 0x86, 0x08, 0xe6, 0xca, 0x56, 0xf8, 0x44, 0xd1, + 0x76, 0xc8, 0xc2, 0xa6, 0xb4, 0x0e, 0x24, 0x4f, 0xe3, 0xa2, 0xe3, 0x08, 0x26, 0x64, 0x5d, 0x52, + 0xb6, 0x21, 0xa1, 0x6f, 0xc1, 0x5c, 0x4e, 0x04, 0x95, 0xee, 0xee, 0x2b, 0x78, 0xad, 0xb6, 0x2f, + 0x90, 0xb5, 0x5f, 0x10, 0x6e, 0xef, 0xc4, 0x16, 0xb7, 0x7c, 0x48, 0x81, 0x26, 0xdd, 0xe7, 0xca, + 0xfb, 0x16, 0x93, 0xfe, 0x30, 0x8f, 0x7d, 0xee, 0xf7, 0xde, 0x5f, 0xc2, 0x02, 0xc8, 0xfb, 0xda, + 0xae, 0x18, 0x10, 0x2f, 0xaa, 0xcd, 0x8b, 0x3c, 0x09, 0x01, 0x41, 0x78, 0xb3, 0x5c, 0x1d, 0x16, + 0x09, 0xe5, 0x83, 0xd6, 0x0b, 0xd8, 0xe4, 0xb0, 0xe3, 0x96, 0xc2, 0x0f, 0x61, 0x59, 0x00, 0x06, + 0x76, 0x77, 0x0f, 0x75, 0x6b, 0xfb, 0x6e, 0xe3, 0xbc, 0xf1, 0xff, 0xf0, 0xcc, 0x48, 0xc7, 0x33, + 0xe7, 0xc5, 0x76, 0x57, 0x0c, 0xca, 0x5c, 0x4b, 0x02, 0xe1, 0xba, 0xb1, 0x0b, 0xc4, 0x08, 0xf8, + 0x22, 0xcb, 0xdf, 0xcb, 0xe2, 0x8b, 0x9b, 0x1a, 0x49, 0x7f, 0x13, 0x7b, 0x5d, 0xda, 0xc4, 0x88, + 0xf8, 0x44, 0x8f, 0x76, 0xeb, 0x5d, 0x37, 0xf2, 0xee, 0x2b, 0x7e, 0x10, 0xf1, 0x25, 0x2e, 0xab, + 0x89, 0x84, 0x77, 0xba, 0x57, 0x76, 0x25, 0x7e, 0x24, 0x4f, 0x89, 0x05, 0x39, 0xf3, 0xb7, 0x35, + 0x35, 0xd7, 0xb8, 0x91, 0x2e, 0x5f, 0x77, 0x50, 0x88, 0x84, 0x26, 0x8e, 0xfc, 0x82, 0x1d, 0xfc, + 0x4d, 0x91, 0xee, 0xe8, 0x2e, 0xc5, 0x80, 0xed, 0xb4, 0x8f, 0x65, 0xfe, 0xf7, 0xee, 0x24, 0x41, + 0x8c, 0xed, 0xb9, 0x9b, 0xc4, 0x02, 0x9b, 0xb2, 0x6f, 0xaa, 0xba, 0xb7, 0x3f, 0x70, 0x24, 0x03, + 0x81, 0x45, 0x26, 0x2a, 0xca, 0xcc, 0xaa, 0xe1, 0x8c, 0x08, 0xf7, 0xa2, 0xad, 0x7c, 0x9b, 0x1a, + 0x5f, 0x49, 0x3f, 0xd8, 0x5d, 0xc0, 0xb2, 0x68, 0x94, 0xdb, 0xfa, 0x69, 0xb4, 0xd3, 0x4d, 0x1f, + 0x6b, 0xd3, 0xd7, 0x88, 0x08, 0xd2, 0xd7, 0x73, 0x53, 0x13, 0xa0, 0x9d, 0x3c, 0x70, 0xcd, 0x55, + 0x29, 0xf1, 0xf5, 0x5c, 0x33, 0x93, 0x8e, 0xe6, 0xdd, 0x24, 0xef, 0xb7, 0xe5, 0xdb, 0x7f, 0xbd, + 0xea, 0x15, 0xe8, 0x5b, 0xf1, 0x01, 0x84, 0x40, 0x74, 0x48, 0xbc, 0x22, 0x10, 0x74, 0xdb, 0x7f, + 0x11, 0xe2, 0x42, 0x45, 0xdd, 0xa9, 0xa9, 0xe2, 0x62, 0x65, 0xcf, 0x7b, 0xfc, 0x50, 0x87, 0x7b, + 0xde, 0x21, 0x63, 0x88, 0x08, 0x1c, 0x4b, 0xdf, 0xcb, 0x76, 0xee, 0xc9, 0x5b, 0xbb, 0xbe, 0x24, + 0x32, 0x5b, 0xdd, 0x1e, 0x24, 0x10, 0x0f, 0xaa, 0xd5, 0x45, 0xeb, 0x58, 0xba, 0xee, 0x82, 0x74, + 0xfc, 0x40, 0x22, 0xee, 0xfd, 0xf0, 0x9c, 0xdf, 0xde, 0xfc, 0x48, 0x92, 0xee, 0xbe, 0x24, 0x59, + 0xea, 0xf5, 0x5f, 0x11, 0x42, 0x3a, 0xba, 0x3d, 0x7c, 0x79, 0x5d, 0xde, 0xee, 0xee, 0xef, 0x7c, + 0x40, 0x44, 0x16, 0x0e, 0xab, 0xee, 0xe2, 0xba, 0xd7, 0xb8, 0x40, 0x22, 0x0a, 0x84, 0xed, 0x54, + 0x8c, 0x08, 0xb1, 0x27, 0x58, 0x59, 0x51, 0x76, 0xe0, 0xc4, 0x30, 0x10, 0x29, 0x98, 0x3e, 0x1f, + 0x62, 0x59, 0xfe, 0xb5, 0xc3, 0x2c, 0xa0, 0x8e, 0xdc, 0xe8, 0xff, 0xb6, 0xdd, 0xb3, 0x5a, 0x70, + 0xd3, 0x7c, 0x61, 0x94, 0xd9, 0x49, 0x62, 0x39, 0x55, 0xf4, 0xef, 0x89, 0x89, 0x9e, 0xea, 0xb6, + 0xe7, 0xd0, 0xab, 0xef, 0x88, 0x13, 0x77, 0x9d, 0xa6, 0xce, 0xbc, 0x41, 0x06, 0x51, 0xc9, 0xf0, + 0x88, 0x83, 0xc1, 0x53, 0xa6, 0xa0, 0xed, 0xff, 0x13, 0xc1, 0x10, 0x9d, 0xdd, 0xbe, 0x0b, 0xad, + 0xdb, 0xa5, 0xb4, 0xd7, 0xc1, 0x3c, 0x9b, 0x9f, 0x57, 0x96, 0xe3, 0x1f, 0x5c, 0xbe, 0x12, 0xbb, + 0xf6, 0xdb, 0x5f, 0x35, 0x56, 0x97, 0x97, 0x5b, 0x42, 0x7a, 0xb7, 0x10, 0x24, 0x67, 0x96, 0x8e, + 0xed, 0x85, 0xbd, 0x97, 0x2e, 0xee, 0x5f, 0x89, 0x96, 0x95, 0xff, 0x89, 0x12, 0xe2, 0xb7, 0x76, + 0xf1, 0x12, 0xf5, 0x5c, 0x47, 0xe0, 0xab, 0x10, 0xd2, 0xe4, 0x75, 0xb2, 0xaf, 0x22, 0x5f, 0x63, + 0xb2, 0x77, 0xf0, 0x80, 0x40, 0x97, 0xb9, 0x54, 0x7b, 0x8a, 0xdf, 0x10, 0x19, 0x05, 0x27, 0xdd, + 0xe8, 0xde, 0xee, 0xef, 0x5c, 0x48, 0x81, 0x44, 0x55, 0x55, 0x55, 0x55, 0xe1, 0x11, 0x7a, 0x51, + 0x0f, 0x4a, 0x73, 0x9e, 0x27, 0x89, 0x8b, 0x2d, 0x56, 0xb5, 0xf1, 0x05, 0x25, 0xef, 0x84, 0x42, + 0x00, 0x94, 0x4a, 0xb1, 0xda, 0x77, 0xbd, 0x71, 0x15, 0xbf, 0x11, 0x10, 0x23, 0x77, 0xad, 0x57, + 0x25, 0xdf, 0xf0, 0x89, 0xd6, 0x9b, 0xbd, 0xef, 0x2e, 0x7c, 0x15, 0x0a, 0x15, 0xde, 0xab, 0x55, + 0xd7, 0xb8, 0x88, 0xf1, 0x7c, 0xd8, 0xab, 0x2a, 0x6f, 0xaa, 0xf8, 0xf9, 0x0e, 0x73, 0x75, 0xca, + 0xa6, 0x91, 0x75, 0xf2, 0xe2, 0x1d, 0x6d, 0x3e, 0x20, 0x4f, 0x11, 0x15, 0x26, 0x2d, 0x5f, 0x7c, + 0x44, 0x4c, 0xd4, 0xe7, 0x5a, 0xe2, 0x02, 0x00, 0x9f, 0xb6, 0x65, 0x46, 0x5f, 0xbf, 0x70, 0x8c, + 0x82, 0x97, 0x17, 0xf0, 0xc1, 0x45, 0x0e, 0x06, 0x5f, 0xc5, 0xfb, 0xb1, 0x84, 0xb2, 0x4b, 0x70, + 0xb8, 0x7b, 0xf2, 0x73, 0x15, 0x69, 0xfc, 0x13, 0x5e, 0xf4, 0xa4, 0xd6, 0xf2, 0x9b, 0xaf, 0x5f, + 0x3d, 0x8a, 0x49, 0x26, 0x9f, 0xfa, 0xd7, 0xc1, 0x1e, 0x5f, 0x4d, 0xbe, 0x0b, 0x26, 0xa3, 0x3f, + 0x68, 0xf9, 0xb4, 0xd3, 0x7c, 0x25, 0xd2, 0x49, 0x22, 0x63, 0x55, 0x3e, 0x15, 0xa7, 0x26, 0xa4, + 0x93, 0x69, 0xdc, 0xa4, 0x5d, 0xff, 0xc1, 0x75, 0x5a, 0x76, 0x89, 0xa9, 0x26, 0xe9, 0x01, 0xc3, + 0x10, 0xe1, 0xaa, 0x6e, 0x3d, 0x73, 0xb7, 0x8d, 0xf7, 0xf0, 0x80, 0x29, 0x28, 0x35, 0x79, 0x16, + 0xd4, 0x2d, 0xbf, 0x53, 0x9c, 0xae, 0xdb, 0xd7, 0xc7, 0x14, 0x56, 0x76, 0x65, 0xc9, 0xa0, 0xfc, + 0xbd, 0x26, 0xe7, 0xa2, 0x23, 0xbf, 0x25, 0xdf, 0xf0, 0x9d, 0xef, 0x5a, 0xfc, 0x29, 0x7b, 0xba, + 0xaa, 0xbd, 0xa7, 0xbe, 0x5a, 0x75, 0xe1, 0x01, 0xc6, 0xb8, 0xbe, 0xef, 0x66, 0x33, 0xaf, 0x10, + 0x41, 0x35, 0x68, 0xd9, 0x84, 0x44, 0x71, 0x20, 0x83, 0x89, 0x08, 0x39, 0x31, 0x7e, 0x20, 0x10, + 0xd2, 0x26, 0x7d, 0xc4, 0xc1, 0x26, 0xef, 0xef, 0x88, 0x2b, 0xbb, 0xbb, 0xbb, 0xfc, 0xa4, 0xdb, + 0x5c, 0x48, 0x83, 0x11, 0x57, 0xc4, 0x88, 0x26, 0xee, 0xfe, 0x13, 0x3d, 0x69, 0xd3, 0x32, 0x97, + 0xa8, 0xe2, 0x42, 0x62, 0x2f, 0x75, 0xb3, 0xf8, 0x27, 0xad, 0x55, 0x57, 0xf7, 0x89, 0x0a, 0x0b, + 0x17, 0x55, 0x51, 0x75, 0x55, 0x11, 0xc9, 0x11, 0x84, 0xd6, 0x6c, 0xef, 0x12, 0x3f, 0x33, 0x1d, + 0x4d, 0xd5, 0x2f, 0x34, 0x25, 0x45, 0xfc, 0x55, 0x75, 0x55, 0x5e, 0x10, 0x10, 0x11, 0x93, 0xc5, + 0xe4, 0xc1, 0x75, 0x55, 0xaf, 0x10, 0x20, 0x25, 0x77, 0xb9, 0xa7, 0x4b, 0xc4, 0xb2, 0x6d, 0xaf, + 0x93, 0x7b, 0xf0, 0x87, 0x08, 0x84, 0x02, 0xa2, 0x22, 0x5c, 0x43, 0xeb, 0x4d, 0xcd, 0xf7, 0x96, + 0xfd, 0xf0, 0x46, 0x26, 0xf7, 0xa5, 0x7e, 0x08, 0xa4, 0xd2, 0xef, 0x55, 0xcb, 0xe5, 0xc1, 0xfc, + 0xba, 0x6b, 0x26, 0x10, 0x0a, 0x19, 0xa1, 0x36, 0x05, 0xe6, 0x72, 0x77, 0x26, 0x17, 0x9f, 0xc5, + 0xbb, 0x8a, 0xce, 0x5c, 0x22, 0x08, 0x04, 0x17, 0x4d, 0xbd, 0x27, 0xc4, 0x84, 0x02, 0x25, 0xbd, + 0xf7, 0x79, 0xb1, 0xa9, 0xf0, 0x51, 0xdd, 0xdd, 0xdd, 0xea, 0xb8, 0x4a, 0xab, 0x5b, 0xb8, 0xae, + 0x39, 0x10, 0x11, 0x2e, 0x60, 0xe7, 0xac, 0x47, 0xcc, 0x7b, 0x9a, 0xbe, 0x24, 0x48, 0xbd, 0xdd, + 0xdd, 0xdd, 0xf8, 0x44, 0x25, 0x55, 0x33, 0x1b, 0xdf, 0xe1, 0x4d, 0xef, 0x93, 0xde, 0xf9, 0x7e, + 0x64, 0x3b, 0xe2, 0x11, 0x1e, 0xa2, 0x7c, 0x4d, 0x91, 0xef, 0xf0, 0x9e, 0xab, 0x77, 0x7f, 0x10, + 0x5b, 0xda, 0x6b, 0x10, 0x20, 0x15, 0x97, 0x31, 0x05, 0x52, 0xb4, 0x6c, 0x49, 0x9c, 0xfd, 0xf0, + 0x5b, 0xad, 0x76, 0xcd, 0xad, 0xe1, 0x01, 0xc5, 0x99, 0xa0, 0x2f, 0xab, 0x25, 0x89, 0xf5, 0xc2, + 0x01, 0x00, 0x5d, 0x47, 0x5a, 0xd4, 0x99, 0xdf, 0x1d, 0xe7, 0x82, 0xab, 0x30, 0xbf, 0x4d, 0x7c, + 0x23, 0x52, 0x66, 0x6c, 0x50, 0xad, 0x59, 0x05, 0x5a, 0xbc, 0x48, 0xf2, 0x55, 0x59, 0x33, 0x57, + 0xbf, 0xc4, 0xde, 0xec, 0xd6, 0xbf, 0x16, 0x77, 0xbb, 0xee, 0xfe, 0x6a, 0xa7, 0xe2, 0x44, 0x10, + 0x44, 0x6a, 0x4b, 0x77, 0x0c, 0xc2, 0x86, 0x77, 0x4e, 0xd8, 0xc4, 0xbd, 0x3d, 0x37, 0x78, 0xad, + 0x5e, 0x21, 0xe4, 0xf0, 0x8f, 0x62, 0x52, 0x49, 0xe6, 0x86, 0x02, 0x01, 0x41, 0x02, 0x98, 0xcd, + 0x02, 0x95, 0xba, 0xc3, 0xc5, 0x42, 0xb2, 0x80, 0x28, 0x17, 0x62, 0x8c, 0x5b, 0x3e, 0x16, 0xb9, + 0x95, 0x29, 0x71, 0x21, 0x85, 0xef, 0x12, 0x13, 0x12, 0x5e, 0xef, 0x5d, 0x78, 0x44, 0x96, 0x66, + 0x63, 0xc2, 0x21, 0x00, 0x4f, 0xbd, 0xf7, 0x7a, 0xac, 0x33, 0xc4, 0x86, 0x3e, 0x0a, 0x73, 0xfb, + 0x61, 0x6d, 0x50, 0xe4, 0xb8, 0x98, 0xcd, 0x8d, 0xbf, 0xc1, 0x38, 0x87, 0x76, 0xab, 0xaf, 0x71, + 0x10, 0x54, 0x25, 0x3b, 0xbb, 0x97, 0xbd, 0xd6, 0xad, 0xc4, 0x08, 0x09, 0xf2, 0xfd, 0x37, 0x77, + 0xe2, 0x01, 0x75, 0xee, 0xf5, 0xaf, 0x78, 0x91, 0x37, 0xdb, 0x53, 0x75, 0x77, 0xf7, 0x9f, 0x6d, + 0xae, 0x11, 0xd6, 0xeb, 0x55, 0x54, 0x39, 0x7e, 0x10, 0x8f, 0x22, 0x8b, 0xf7, 0xb9, 0x7d, 0xf8, + 0x9b, 0xbd, 0xf8, 0x8b, 0xbd, 0xbf, 0x8c, 0x2d, 0x6d, 0xaa, 0xe9, 0x2e, 0xaa, 0xab, 0xe0, 0xa4, + 0xa2, 0xf2, 0x23, 0x8e, 0xc5, 0x18, 0xc7, 0xe9, 0x2d, 0xb8, 0x88, 0x43, 0xdd, 0x25, 0xc5, 0xd3, + 0xaf, 0x12, 0x24, 0x12, 0xc5, 0xd4, 0x5d, 0x58, 0x72, 0xbe, 0xf8, 0x29, 0xcf, 0x02, 0xe4, 0x66, + 0xeb, 0xaa, 0x9b, 0x24, 0xc6, 0xe2, 0x44, 0xfc, 0x84, 0x24, 0x2a, 0x8b, 0xc2, 0x25, 0xd2, 0x56, + 0xc6, 0xac, 0x7e, 0xa4, 0xfc, 0x20, 0xef, 0x63, 0xa8, 0x90, 0x88, 0x4b, 0xbb, 0xaa, 0xaa, 0xf1, + 0x01, 0x11, 0x8d, 0xc6, 0xd9, 0x63, 0x7b, 0xbd, 0x6f, 0xf0, 0xd9, 0x43, 0x2f, 0x65, 0x04, 0x6b, + 0x21, 0x09, 0x89, 0x85, 0x62, 0xc1, 0x82, 0x09, 0x07, 0xe7, 0xe2, 0x8b, 0x97, 0x2f, 0xa8, 0xce, + 0x13, 0xae, 0xb3, 0x53, 0x50, 0x40, 0x20, 0x28, 0x20, 0x1e, 0xbc, 0x1f, 0x7a, 0x8a, 0x6b, 0x07, + 0xde, 0x0d, 0xdc, 0xff, 0x36, 0x89, 0x6a, 0x77, 0x8c, 0x6f, 0x8e, 0x91, 0x4a, 0xa6, 0x23, 0x07, + 0x85, 0x0d, 0x1a, 0xec, 0x73, 0x7f, 0x10, 0x24, 0x49, 0x76, 0xdb, 0x5a, 0xf8, 0x8f, 0x8a, 0xbb, + 0xc5, 0x72, 0xff, 0x12, 0x26, 0x83, 0x44, 0x28, 0x21, 0xb9, 0x4b, 0x3f, 0xef, 0xfb, 0x1c, 0x40, + 0x92, 0x56, 0x6f, 0xe2, 0x7c, 0x48, 0x25, 0xbd, 0xd0, 0x08, 0xbe, 0xec, 0x7c, 0xc7, 0x78, 0x92, + 0x08, 0xd1, 0xae, 0x26, 0x26, 0xaa, 0x2e, 0x2e, 0xa4, 0xeb, 0xe2, 0x22, 0xb5, 0x55, 0x55, 0xac, + 0x35, 0x38, 0x08, 0x7c, 0xba, 0x85, 0xb5, 0x65, 0xea, 0x68, 0x22, 0x9f, 0x7f, 0x12, 0x6a, 0xaf, + 0xc4, 0x84, 0xab, 0x55, 0x76, 0xca, 0xc7, 0x88, 0x88, 0xaa, 0xae, 0xee, 0xf8, 0x88, 0x2a, 0xbb, + 0xee, 0x7c, 0xaa, 0xad, 0x5b, 0x88, 0x82, 0xbb, 0xb7, 0xaa, 0xf1, 0x78, 0xbb, 0x7c, 0x27, 0xab, + 0xa9, 0x3b, 0xfe, 0x14, 0x38, 0x9c, 0x0d, 0x8a, 0x5e, 0x5f, 0x64, 0x4e, 0xa2, 0xea, 0xa8, 0xa5, + 0x6f, 0xf0, 0x55, 0x8b, 0xad, 0x35, 0x55, 0x55, 0x55, 0x6c, 0x2a, 0xe0, 0x95, 0x2a, 0x25, 0x67, + 0xfd, 0x9d, 0x1e, 0xa9, 0xf0, 0x88, 0x2b, 0x8b, 0xa8, 0xa6, 0xab, 0x4a, 0xb4, 0x92, 0xef, 0xb2, + 0x2c, 0xaa, 0xe2, 0x21, 0x3b, 0xb7, 0x75, 0xd7, 0xc6, 0x09, 0x6d, 0xb6, 0xaa, 0xaa, 0xab, 0x27, + 0x6d, 0x55, 0x57, 0xc2, 0x06, 0x5a, 0xf5, 0x53, 0x62, 0xca, 0xc5, 0x61, 0x1b, 0x6b, 0x30, 0x80, + 0x63, 0x84, 0x02, 0x0e, 0x5f, 0x7e, 0x24, 0x20, 0xef, 0xbe, 0x19, 0x10, 0x0a, 0x85, 0x62, 0x70, + 0xc4, 0x70, 0x66, 0x8a, 0x3f, 0xeb, 0xbb, 0x1c, 0xa1, 0x4e, 0x09, 0x04, 0xa8, 0xb8, 0xb8, 0x18, + 0xb0, 0x5d, 0xee, 0x24, 0x30, 0x24, 0x64, 0x75, 0xa7, 0x24, 0x7f, 0x12, 0x10, 0xe2, 0x04, 0x90, + 0x49, 0x14, 0xd7, 0xe2, 0xca, 0xd6, 0x5a, 0x5d, 0xdf, 0xc5, 0xef, 0x7a, 0x6c, 0x65, 0xf8, 0x91, + 0x00, 0xa0, 0x43, 0xae, 0xba, 0xaf, 0x61, 0x66, 0x24, 0x31, 0x39, 0xff, 0xeb, 0x5f, 0xfb, 0xbb, + 0xbb, 0x6b, 0xb9, 0x72, 0xfc, 0x40, 0x81, 0x55, 0xae, 0xb5, 0x5c, 0x9b, 0xcb, 0x0f, 0x31, 0x1d, + 0xef, 0xc4, 0x08, 0xd0, 0xde, 0xa2, 0xfe, 0x20, 0x41, 0x0b, 0xbb, 0xf9, 0x6a, 0xbe, 0x10, 0x85, + 0x3c, 0xdf, 0x55, 0xad, 0x55, 0x69, 0xfb, 0xe1, 0x2d, 0x6a, 0x87, 0xbf, 0x10, 0xe9, 0xd2, 0xe1, + 0x08, 0x25, 0x9b, 0xa7, 0xd5, 0x4d, 0xdb, 0xc4, 0x05, 0x0a, 0x23, 0xe0, 0xcb, 0x32, 0x73, 0x66, + 0x5a, 0x93, 0xfa, 0xdb, 0xf7, 0xc1, 0x65, 0x56, 0xab, 0xaa, 0xaa, 0xaf, 0x57, 0x09, 0x4d, 0xb9, + 0x62, 0xeb, 0xaf, 0xf8, 0x45, 0xef, 0x7c, 0x40, 0x91, 0xd1, 0x71, 0x7d, 0x45, 0xc5, 0xc5, 0xeb, + 0x5c, 0x10, 0x89, 0x13, 0xad, 0x69, 0xaa, 0xe0, 0x87, 0xe1, 0x90, 0x57, 0xd5, 0x31, 0x71, 0x07, + 0xac, 0xb5, 0x51, 0x7e, 0xf8, 0xb3, 0x56, 0xe4, 0xeb, 0x2b, 0x15, 0x38, 0x4e, 0x6c, 0xd6, 0x11, + 0x0c, 0x71, 0x20, 0xa0, 0x15, 0x8c, 0x63, 0x74, 0x29, 0xba, 0xc5, 0xee, 0xbe, 0x89, 0xe0, 0x84, + 0x4e, 0xea, 0xe3, 0xc4, 0xf9, 0x73, 0x6d, 0xfc, 0xbb, 0xdb, 0xf0, 0x49, 0x6a, 0xd7, 0xaf, 0x82, + 0x4a, 0x6d, 0xfd, 0x24, 0x20, 0x08, 0x07, 0x0c, 0xa7, 0x2f, 0x12, 0xfe, 0xb5, 0x8a, 0xf5, 0xc1, + 0x11, 0xef, 0x66, 0xfe, 0x21, 0xde, 0xef, 0x88, 0x10, 0x63, 0xea, 0xb8, 0x8a, 0x23, 0xfc, 0x60, + 0x8a, 0xb6, 0xab, 0x5b, 0xdf, 0x13, 0x61, 0xbf, 0x89, 0x30, 0xbd, 0x37, 0xf3, 0x1f, 0x9b, 0x57, + 0x77, 0x6e, 0xdf, 0x84, 0xef, 0x7b, 0x6b, 0xf8, 0x27, 0xaa, 0xfa, 0xa7, 0xdf, 0x04, 0x46, 0x77, + 0xbf, 0x7c, 0xdd, 0x36, 0xf1, 0x02, 0x1d, 0xdd, 0xdf, 0x10, 0x20, 0x85, 0xce, 0xc7, 0x08, 0x41, + 0x5e, 0x9b, 0x69, 0xad, 0x39, 0xba, 0x1f, 0xdc, 0x14, 0x02, 0x00, 0xa1, 0xf5, 0x55, 0x07, 0x6f, + 0x1a, 0xa0, 0xbd, 0x5c, 0x9f, 0x8f, 0xef, 0x10, 0x09, 0x08, 0xda, 0xb7, 0xf5, 0x62, 0x15, 0xbc, + 0x40, 0x27, 0xea, 0x4e, 0xb2, 0xaa, 0xdc, 0x48, 0x44, 0x75, 0x56, 0x55, 0x6b, 0x55, 0x5f, 0x90, + 0x8f, 0xbc, 0x34, 0xa1, 0x23, 0xdc, 0xdf, 0xfd, 0xbf, 0x7f, 0x93, 0x5a, 0xf1, 0x1e, 0x24, 0x59, + 0x5e, 0xd3, 0xe5, 0x63, 0x88, 0x10, 0xea, 0xaa, 0xb8, 0x60, 0x49, 0x0c, 0xbb, 0xe2, 0x21, 0x1a, + 0xdb, 0xb9, 0xfd, 0xe9, 0x2a, 0xf1, 0x20, 0x80, 0x21, 0xbd, 0xa4, 0xdb, 0xd6, 0xab, 0xc4, 0x16, + 0xaa, 0xbc, 0x22, 0x11, 0xe2, 0x61, 0x12, 0x13, 0x5c, 0x5b, 0x7d, 0xdd, 0x8f, 0x17, 0x09, 0x42, + 0x01, 0x80, 0xa4, 0x56, 0x7d, 0x77, 0x75, 0x4f, 0xd6, 0xa5, 0xf6, 0xf5, 0x6f, 0x82, 0xee, 0x3f, + 0x4b, 0x7b, 0xbd, 0x71, 0x02, 0x49, 0xbd, 0xd4, 0x40, 0x96, 0x7b, 0x75, 0x58, 0x44, 0x12, 0x1a, + 0x5c, 0x41, 0x16, 0xef, 0xe2, 0x02, 0x06, 0x15, 0xdd, 0xec, 0xf9, 0x69, 0xa5, 0x6b, 0xc4, 0xb1, + 0x6a, 0xbe, 0x26, 0x52, 0xad, 0x6b, 0x10, 0x42, 0x9b, 0xaa, 0x6b, 0xe1, 0x2a, 0xaa, 0xeb, 0x5f, + 0x19, 0x55, 0xaa, 0x4e, 0xeb, 0x5a, 0xd5, 0x7c, 0x40, 0x2e, 0xaa, 0xaa, 0xd3, 0x6f, 0xdf, 0x11, + 0x6d, 0x6a, 0xb5, 0x4f, 0x12, 0x11, 0xf8, 0x28, 0x26, 0xab, 0xab, 0x7e, 0xe1, 0x19, 0xad, 0xab, + 0x78, 0xe7, 0x1f, 0xa1, 0x53, 0xe2, 0x0a, 0x6e, 0xaa, 0xab, 0x5e, 0x18, 0x9a, 0xb5, 0xc7, 0x66, + 0x4a, 0xff, 0x19, 0x55, 0x55, 0xd5, 0x56, 0xb4, 0x35, 0x55, 0xc2, 0x21, 0x92, 0x91, 0xbb, 0x7c, + 0x23, 0x1d, 0xa6, 0xde, 0xeb, 0xad, 0x78, 0x60, 0x27, 0xad, 0x78, 0x85, 0x4f, 0x11, 0xe2, 0x3c, + 0x21, 0xc2, 0x3f, 0x8b, 0x25, 0x6b, 0xc5, 0xf8, 0x43, 0x84, 0x03, 0x0e, 0xef, 0xf1, 0x03, 0xc4, + 0xd5, 0x63, 0xbb, 0x87, 0x22, 0x0c, 0x16, 0x55, 0x71, 0x3e, 0x24, 0x4b, 0x35, 0xd0, 0xf8, 0x64, + 0x40, 0x2a, 0x30, 0x9b, 0x0e, 0x66, 0x39, 0xbd, 0xb7, 0x6c, 0xbd, 0xff, 0x28, 0x47, 0x10, 0x34, + 0x82, 0xe4, 0xe2, 0x9e, 0xfc, 0xe9, 0x8b, 0xc9, 0xc1, 0xa2, 0x4a, 0x23, 0xec, 0xa1, 0x48, 0x2c, + 0x5d, 0xb7, 0x72, 0x43, 0xfc, 0x20, 0x2d, 0xd5, 0xf5, 0x51, 0x7c, 0x9d, 0xf1, 0x01, 0x11, 0x62, + 0x34, 0xdf, 0x15, 0x8a, 0xfc, 0x22, 0x75, 0x4d, 0x6f, 0x77, 0x54, 0xe9, 0xf8, 0x23, 0x2e, 0xef, + 0x5f, 0x05, 0x15, 0x62, 0xba, 0xaf, 0x5c, 0x23, 0x0a, 0x0a, 0xbd, 0xdd, 0xc5, 0x62, 0x5c, 0x71, + 0x59, 0x79, 0xea, 0x87, 0xb7, 0xe9, 0xfc, 0x8b, 0xe0, 0x86, 0xee, 0xfc, 0xdb, 0xe2, 0x44, 0xad, + 0x64, 0xdf, 0xec, 0xa6, 0x62, 0xbe, 0x23, 0x89, 0x96, 0xb5, 0xf8, 0x4b, 0x55, 0x5c, 0x4f, 0xf1, + 0x11, 0x75, 0x53, 0x79, 0xd5, 0x71, 0x02, 0x45, 0xd6, 0x2e, 0xba, 0xae, 0x26, 0x26, 0xaa, 0xda, + 0xaa, 0xaa, 0xf8, 0x28, 0x8b, 0xc5, 0xd5, 0x62, 0xea, 0xd8, 0x4d, 0xc0, 0x0f, 0x7b, 0xae, 0x75, + 0x78, 0x8a, 0xff, 0xfd, 0x17, 0x10, 0x10, 0x05, 0x17, 0x6d, 0xdb, 0x17, 0x51, 0x75, 0xef, 0x82, + 0xce, 0xaa, 0x2e, 0x4e, 0x2e, 0xcf, 0x2b, 0x2b, 0xd8, 0xcc, 0x07, 0x9f, 0xa8, 0x66, 0xe0, 0x84, + 0x40, 0x26, 0xc9, 0x98, 0xba, 0x8b, 0xaf, 0xbc, 0x49, 0xaa, 0x9d, 0xf8, 0x40, 0x84, 0x8b, 0xcc, + 0xc6, 0x10, 0xf8, 0x40, 0xdc, 0x56, 0xfc, 0x48, 0xbe, 0x2b, 0x8f, 0xae, 0x73, 0x85, 0xce, 0x24, + 0x14, 0x08, 0xb4, 0x36, 0xbb, 0xbf, 0x5f, 0x37, 0x51, 0x27, 0x30, 0x88, 0x44, 0xbc, 0x3d, 0xe7, + 0xfe, 0x20, 0xa7, 0xdd, 0xf1, 0x00, 0xa4, 0x25, 0x8b, 0xb6, 0xab, 0x7f, 0x94, 0x97, 0xa7, 0xe5, + 0x3a, 0xbd, 0x38, 0x65, 0x89, 0x00, 0x23, 0x2a, 0xbc, 0xa1, 0x17, 0xbd, 0xff, 0xe9, 0xac, 0x9f, + 0x5f, 0x08, 0x08, 0x55, 0xea, 0xf5, 0xad, 0x70, 0x4e, 0x42, 0xfb, 0x72, 0xa8, 0x9b, 0x5f, 0x83, + 0xe0, 0x8e, 0x1e, 0xf6, 0x1d, 0x10, 0xcb, 0xe1, 0xf1, 0x42, 0xd7, 0x74, 0xf6, 0xcb, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x9a, 0x57, 0x2b, 0xb0, 0x4a, 0x3f, 0x04, 0x82, 0xef, 0x77, 0x21, 0x0e, 0x8b, + 0xd5, 0x08, 0xff, 0xc2, 0x14, 0x78, 0xae, 0x26, 0x8d, 0x14, 0x9d, 0x5c, 0x8f, 0xeb, 0xd1, 0x3d, + 0x0a, 0xaa, 0xe8, 0x4b, 0xd7, 0x20, 0xee, 0x6d, 0x27, 0x41, 0x16, 0x9f, 0xad, 0x57, 0x5a, 0x97, + 0x98, 0x9a, 0x4b, 0x88, 0x08, 0x0b, 0x1c, 0x21, 0x64, 0x61, 0x7c, 0xe0, 0x1c, 0x3f, 0x0a, 0xb9, + 0x27, 0x70, 0xf2, 0x84, 0x70, 0x1c, 0xfa, 0x4f, 0x8f, 0x7f, 0xa3, 0xf7, 0xd7, 0xab, 0xaf, 0x4b, + 0xc2, 0x77, 0xdd, 0xf7, 0x58, 0x47, 0xe8, 0x9d, 0xf5, 0xef, 0xaf, 0x4d, 0xd7, 0xa5, 0x89, 0x13, + 0xf5, 0x8a, 0x61, 0xc4, 0x2d, 0x25, 0xf4, 0x31, 0xfe, 0x8c, 0xff, 0x28, 0xbc, 0x5e, 0x37, 0x12, + 0x6a, 0xd7, 0xea, 0xca, 0x88, 0x08, 0x07, 0xc2, 0x16, 0x33, 0x75, 0xa2, 0x38, 0x9f, 0x67, 0x12, + 0x79, 0x66, 0x91, 0x63, 0x79, 0x56, 0x2f, 0xfc, 0x40, 0x40, 0xbc, 0xb8, 0xd9, 0x3a, 0x0b, 0xfb, + 0x88, 0xfc, 0x12, 0x5d, 0xdd, 0xeb, 0xea, 0x3b, 0x5f, 0x44, 0x78, 0x47, 0xae, 0xab, 0xab, 0x5f, + 0x5a, 0xae, 0xb1, 0x7d, 0x67, 0x7d, 0x5f, 0xec, 0x63, 0x53, 0x64, 0x4f, 0x41, 0x31, 0xda, 0xfb, + 0xae, 0xbe, 0x4a, 0xdf, 0xea, 0x8f, 0x7c, 0x50, 0xee, 0x6f, 0x2b, 0x32, 0xb3, 0xc3, 0x20, 0xac, + 0x50, 0xa1, 0x89, 0xb0, 0x4c, 0x1a, 0x1d, 0x50, 0x70, 0x7b, 0x51, 0x9c, 0x1e, 0x7d, 0x99, 0x18, + 0xaf, 0x7c, 0x4d, 0xcf, 0xd0, 0xd5, 0xd3, 0x7f, 0x8d, 0xd3, 0xd0, 0x4f, 0xaf, 0x10, 0x61, 0x1a, + 0x8d, 0x34, 0x62, 0x43, 0x01, 0x11, 0x92, 0xac, 0x45, 0x25, 0xba, 0x67, 0xf3, 0x2d, 0xd7, 0xc3, + 0x02, 0x2c, 0xc9, 0x8f, 0x5a, 0x32, 0xaa, 0x76, 0xb0, 0x80, 0x20, 0x19, 0x0a, 0x96, 0x85, 0x4d, + 0x10, 0xd4, 0x7e, 0x0e, 0xdc, 0xa2, 0xee, 0x3e, 0xbb, 0xfd, 0x74, 0x19, 0xe9, 0xb0, 0xcc, 0x4f, + 0x46, 0xca, 0x1c, 0xc4, 0x78, 0x96, 0x18, 0x17, 0xc4, 0x7f, 0x88, 0x2d, 0xdd, 0xe4, 0xfe, 0x11, + 0x04, 0x27, 0x12, 0xe3, 0x55, 0x7e, 0x23, 0xc4, 0x09, 0x82, 0xec, 0x47, 0x89, 0x97, 0xd6, 0x10, + 0x12, 0x6a, 0xd5, 0x94, 0x56, 0xd8, 0x67, 0xa0, 0xbb, 0xd7, 0x5e, 0x97, 0xaf, 0x46, 0xe2, 0x0c, + 0x31, 0xef, 0xf1, 0x86, 0x5a, 0xa9, 0xb7, 0x1d, 0x45, 0xd4, 0x5c, 0x5b, 0x6c, 0x5b, 0x3a, 0x9e, + 0x0a, 0x06, 0x45, 0xd0, 0xc5, 0xd5, 0xe8, 0x71, 0x75, 0x95, 0x7b, 0xd7, 0x41, 0x5e, 0xbe, 0x61, + 0x0e, 0xff, 0x08, 0xf8, 0x42, 0x23, 0xa1, 0x2c, 0x1f, 0x5a, 0x97, 0xab, 0x21, 0xde, 0x09, 0xc5, + 0x56, 0xb6, 0xe4, 0xa3, 0xf1, 0x30, 0x88, 0xa0, 0x63, 0x50, 0xbb, 0x28, 0xd4, 0x2e, 0xd7, 0x37, + 0x76, 0x76, 0xe7, 0x84, 0x49, 0x5a, 0xc9, 0xcc, 0x57, 0xbd, 0x44, 0x84, 0x02, 0x46, 0x97, 0x97, + 0xee, 0xe1, 0x44, 0x60, 0x9e, 0xf2, 0x74, 0x17, 0x7f, 0xaf, 0x7d, 0x15, 0xe7, 0xe8, 0x8d, 0xf5, + 0x69, 0x3a, 0xb4, 0x39, 0x89, 0x20, 0xa8, 0x9f, 0xf8, 0x82, 0x08, 0x6d, 0x4f, 0x29, 0xf0, 0x49, + 0x52, 0x66, 0xdf, 0x27, 0x49, 0xf8, 0x80, 0x9f, 0x53, 0x62, 0xaf, 0xe5, 0x35, 0xdf, 0xe2, 0xc6, + 0xee, 0xee, 0xff, 0x10, 0x38, 0x65, 0xef, 0x77, 0xbb, 0x87, 0x1d, 0x27, 0xfe, 0x24, 0xa2, 0xcf, + 0xfb, 0xe8, 0x7b, 0xc2, 0x5d, 0x7a, 0x4e, 0xaf, 0x37, 0x5e, 0x8f, 0xc4, 0x30, 0x83, 0xb4, 0xd7, + 0xd7, 0xbe, 0x6e, 0xee, 0xf1, 0x04, 0xd5, 0x9b, 0xf1, 0x25, 0x11, 0xcd, 0x4f, 0x62, 0xcd, 0xd6, + 0x00, 0x1f, 0xfe, 0x08, 0x47, 0xa6, 0xfc, 0x5e, 0x19, 0x84, 0xc6, 0x2e, 0x29, 0xba, 0xf4, 0x25, + 0xd6, 0xa8, 0x35, 0x0a, 0x00, 0x03, 0x1b, 0x85, 0x27, 0x5a, 0xdf, 0xb2, 0x1f, 0xed, 0xf5, 0x83, + 0xd7, 0x07, 0xdc, 0xb4, 0x53, 0xe1, 0xd3, 0xe6, 0x4e, 0x24, 0x20, 0x26, 0xb7, 0x72, 0xc0, 0x6e, + 0x58, 0x0c, 0x48, 0xfe, 0x20, 0xdb, 0xdf, 0x12, 0x08, 0x02, 0x27, 0x55, 0x55, 0x77, 0x15, 0x88, + 0x58, 0x2e, 0x1c, 0xe1, 0x60, 0xcb, 0x01, 0xe2, 0x44, 0x8b, 0x88, 0x1c, 0x48, 0xb0, 0x62, 0x83, + 0x59, 0x72, 0xb1, 0x1e, 0x26, 0xfa, 0x1f, 0x51, 0x5d, 0x6a, 0x37, 0xab, 0xc5, 0x75, 0xd9, 0x16, + 0x1d, 0x85, 0x80, 0x02, 0xd6, 0x16, 0x10, 0xbb, 0x72, 0x31, 0x47, 0x85, 0xcd, 0xfe, 0x0b, 0x78, + 0x66, 0xbc, 0x78, 0x60, 0x28, 0x8f, 0xc5, 0xa7, 0xed, 0xff, 0x14, 0x33, 0x31, 0x0c, 0xd8, 0x33, + 0xf0, 0xdd, 0xe4, 0xdb, 0x7c, 0xbc, 0xa3, 0xaa, 0x48, 0x00, 0x32, 0xd7, 0xb8, 0xfa, 0xe7, 0x3f, + 0x6e, 0x9e, 0x24, 0x30, 0x32, 0x24, 0x07, 0x96, 0x31, 0x20, 0xe1, 0x60, 0xf6, 0xd7, 0x14, 0x60, + 0x34, 0x43, 0x42, 0x10, 0x91, 0x3c, 0x3d, 0x4d, 0xfb, 0x1e, 0x24, 0x56, 0xf7, 0x4d, 0xe5, 0xf8, + 0x44, 0x20, 0x30, 0xa2, 0xbb, 0x15, 0xc5, 0x62, 0x83, 0x10, 0xf3, 0x80, 0x07, 0x8a, 0x31, 0x03, + 0x85, 0x80, 0x31, 0x44, 0x6b, 0x08, 0x8f, 0xbb, 0x4e, 0x2c, 0x35, 0xbd, 0xe8, 0x26, 0x53, 0x24, + 0xc0, 0xc3, 0xdc, 0x60, 0x40, 0x85, 0x0a, 0xed, 0x14, 0x5a, 0x97, 0xad, 0xc3, 0x75, 0x62, 0x93, + 0x00, 0x38, 0x1e, 0xc6, 0x0c, 0x6f, 0xab, 0x73, 0x83, 0x82, 0x05, 0x2a, 0x0c, 0x9c, 0x5e, 0x3c, + 0xf9, 0x30, 0xe0, 0xe0, 0x71, 0xbe, 0x58, 0x97, 0xce, 0x1f, 0x7d, 0x0f, 0xe8, 0x47, 0xaf, 0x4f, + 0xd7, 0xaf, 0xab, 0x42, 0x58, 0x83, 0x04, 0xa6, 0xef, 0x17, 0x12, 0x30, 0x84, 0xa3, 0x52, 0x77, + 0x05, 0xe8, 0x2a, 0xca, 0x1e, 0x1b, 0xc1, 0xc2, 0x4f, 0x89, 0x38, 0x51, 0xc5, 0xe2, 0xea, 0xa7, + 0xd8, 0x48, 0x67, 0x52, 0x77, 0x31, 0x01, 0x91, 0xd7, 0x35, 0x59, 0x17, 0x20, 0xe7, 0xe6, 0x57, + 0x7e, 0x30, 0x64, 0xef, 0xf1, 0x01, 0x92, 0x65, 0xff, 0x8c, 0x9c, 0x03, 0xc0, 0x70, 0xef, 0x18, + 0xaa, 0x18, 0x2a, 0xe4, 0x55, 0xf8, 0x44, 0xbc, 0x98, 0x00, 0x70, 0x98, 0x7b, 0x8e, 0x56, 0x44, + 0x1f, 0xce, 0xb2, 0xcb, 0xae, 0x28, 0xc3, 0x12, 0xc9, 0xa8, 0x50, 0x56, 0x75, 0xdc, 0xd3, 0x19, + 0xa3, 0xf8, 0x80, 0x95, 0x10, 0x7e, 0x5f, 0x97, 0x32, 0x4e, 0xb3, 0x89, 0x08, 0x09, 0x13, 0x77, + 0xbe, 0xbe, 0x42, 0x3b, 0xfe, 0x5b, 0xcf, 0x08, 0x77, 0xa0, 0xab, 0xc4, 0x75, 0x7a, 0xea, 0xf5, + 0xd5, 0xeb, 0xaf, 0x5c, 0x45, 0x0e, 0x7f, 0x8c, 0x34, 0x12, 0x31, 0xec, 0xc4, 0x3c, 0xac, 0x63, + 0x29, 0x71, 0x1e, 0xde, 0x99, 0x3c, 0x90, 0x58, 0x99, 0x2d, 0x5e, 0x11, 0x19, 0x10, 0xf9, 0xa5, + 0x9c, 0x30, 0x97, 0x1d, 0x00, 0xaa, 0xb0, 0x26, 0xa6, 0x10, 0x54, 0xdc, 0xc9, 0x68, 0x1f, 0x73, + 0x24, 0xd9, 0x39, 0x6e, 0xe4, 0xc0, 0xa9, 0xe0, 0x39, 0x65, 0xbc, 0x20, 0x19, 0x19, 0xed, 0xc3, + 0xb7, 0xe5, 0xbe, 0xdf, 0xe5, 0x83, 0x2c, 0x62, 0x5c, 0x2d, 0x96, 0xef, 0xe1, 0x81, 0x67, 0xa8, + 0xb8, 0xba, 0xba, 0xab, 0xe5, 0xe1, 0x95, 0x4a, 0x64, 0xe8, 0x6b, 0xcd, 0xd5, 0xe2, 0x7a, 0xbd, + 0xf5, 0xe8, 0xde, 0xbd, 0x37, 0x5d, 0x4b, 0xc8, 0x14, 0x27, 0xf9, 0x7a, 0xaa, 0x7a, 0x0d, 0x37, + 0x10, 0x3b, 0x22, 0x74, 0xc3, 0x23, 0x52, 0x16, 0x92, 0x7e, 0x62, 0xde, 0x9f, 0xd9, 0xcf, 0x95, + 0xf0, 0x40, 0x12, 0xbb, 0xbb, 0xcd, 0xad, 0x7c, 0x48, 0xf3, 0x96, 0x31, 0x23, 0x97, 0xb5, 0xd5, + 0x55, 0x70, 0x88, 0x38, 0x19, 0x55, 0x55, 0x5d, 0xd4, 0x5d, 0x22, 0x7b, 0xdf, 0x13, 0xae, 0x61, + 0xd7, 0x9f, 0x3c, 0xa2, 0x4f, 0xef, 0x51, 0x2f, 0x43, 0xde, 0x20, 0x5a, 0xd1, 0xbf, 0xab, 0xc5, + 0x75, 0x78, 0x9e, 0xaf, 0x30, 0x45, 0x84, 0x69, 0x7f, 0x5a, 0xa8, 0x91, 0x00, 0x90, 0x10, 0x25, + 0x46, 0x43, 0xcd, 0xc4, 0x88, 0xbe, 0x63, 0x6e, 0xfc, 0x40, 0x23, 0xd8, 0x86, 0x71, 0x0b, 0xab, + 0x90, 0x5d, 0xd7, 0xe4, 0x39, 0x14, 0x4f, 0xec, 0xcb, 0x2a, 0xab, 0x96, 0xab, 0x5f, 0x25, 0x3e, + 0xf8, 0x98, 0x91, 0x4a, 0xb2, 0x63, 0x7b, 0xfc, 0xa5, 0xdd, 0xc1, 0x34, 0x47, 0x88, 0x96, 0x7f, + 0xfc, 0x27, 0x4b, 0x49, 0x62, 0xf5, 0x88, 0x20, 0x9b, 0xb7, 0xe2, 0x3c, 0x49, 0x07, 0x1e, 0x16, + 0xe8, 0x3f, 0x17, 0xcf, 0x82, 0x1a, 0x44, 0xb0, 0x2c, 0x3e, 0x23, 0xc4, 0xff, 0xc4, 0x84, 0xc2, + 0x2b, 0x5a, 0xea, 0xbb, 0xae, 0xda, 0x89, 0x9a, 0xf7, 0x7c, 0x4f, 0x89, 0xf1, 0x02, 0x0a, 0x6c, + 0xfe, 0x08, 0xe1, 0x0a, 0xe1, 0xf3, 0x6a, 0xbc, 0x4c, 0x12, 0x5e, 0xfb, 0xf1, 0x01, 0x19, 0x30, + 0x80, 0x21, 0x18, 0x0f, 0x78, 0x5c, 0x39, 0x05, 0x5e, 0x4f, 0xe2, 0x05, 0x77, 0x10, 0xe3, 0xdf, + 0xe3, 0x0b, 0x76, 0x9c, 0xbf, 0xe5, 0xfd, 0xdd, 0xf8, 0x44, 0x70, 0xda, 0x9d, 0x46, 0xb5, 0x5b, + 0xbb, 0xa8, 0x81, 0x12, 0xc2, 0x02, 0x2a, 0x20, 0x40, 0x4c, 0x45, 0x6a, 0x6a, 0x2f, 0xc4, 0x14, + 0x86, 0xc6, 0xab, 0xc4, 0x43, 0xf1, 0x1f, 0xdc, 0x4c, 0xc2, 0xd3, 0x77, 0xf0, 0x8b, 0x31, 0x72, + 0xfc, 0x48, 0x9e, 0x11, 0x12, 0x41, 0x7a, 0xaf, 0x84, 0x8c, 0xf7, 0xea, 0xbe, 0xaf, 0x51, 0x3f, + 0x12, 0xee, 0xf9, 0xb8, 0x21, 0x3e, 0xdb, 0xbf, 0xc1, 0x21, 0x95, 0x7e, 0xe2, 0x22, 0xea, 0xba, + 0xaa, 0xaf, 0x10, 0x30, 0x5a, 0x8b, 0xd5, 0x6a, 0x4e, 0xa2, 0x38, 0x2f, 0x33, 0x2a, 0xbe, 0x11, + 0xa9, 0x77, 0xd5, 0x55, 0x57, 0xe0, 0xa8, 0x21, 0x2d, 0x17, 0x7b, 0xe2, 0x58, 0x7d, 0xe2, 0x3e, + 0x50, 0xcb, 0xbb, 0xb8, 0x73, 0x08, 0x21, 0x15, 0xc4, 0x84, 0x10, 0xaa, 0xa8, 0x9d, 0x44, 0xc1, + 0x26, 0xdb, 0xdf, 0xc4, 0x3a, 0xa6, 0xb5, 0x89, 0x16, 0x5b, 0x4a, 0xad, 0x57, 0x88, 0xb2, 0x2a, + 0xfe, 0x5a, 0xaa, 0xfc, 0x95, 0xaf, 0x10, 0x22, 0xb9, 0x06, 0xbb, 0xdc, 0x9c, 0x41, 0x1d, 0xef, + 0x77, 0xf1, 0x06, 0x10, 0xda, 0xd7, 0xc7, 0xde, 0xf2, 0x62, 0xd5, 0x55, 0x57, 0x08, 0x04, 0x01, + 0x19, 0xd5, 0x7e, 0xc3, 0x18, 0x25, 0x15, 0x54, 0x6d, 0xb4, 0xf3, 0x1f, 0xfd, 0xae, 0xdc, 0x33, + 0x35, 0x6e, 0xfe, 0x0b, 0x35, 0x55, 0xd5, 0x75, 0x4b, 0xbe, 0x09, 0x45, 0x2a, 0x75, 0x7d, 0xfb, + 0x84, 0x65, 0xaa, 0xcf, 0x00, 0xe7, 0x0e, 0x1d, 0xf4, 0x41, 0x27, 0x13, 0x56, 0x85, 0xfe, 0x1a, + 0xc1, 0x5d, 0x0f, 0x7f, 0xdb, 0xfb, 0x81, 0xdc, 0xc6, 0x64, 0xe2, 0x89, 0x57, 0x5a, 0xd7, 0xd9, + 0x49, 0xf1, 0xe2, 0xb0, 0xc3, 0x9b, 0x09, 0xa8, 0x04, 0x62, 0x2d, 0x16, 0x98, 0xfd, 0xfb, 0xbf, + 0x9f, 0xbf, 0xbd, 0xe1, 0x00, 0x88, 0x21, 0xd3, 0x6e, 0xde, 0x11, 0x25, 0x2a, 0x13, 0xf9, 0x6b, + 0x30, 0x60, 0x3e, 0x11, 0xa8, 0x8f, 0xcb, 0xdd, 0xf1, 0x1a, 0xe2, 0xc4, 0xbb, 0xdd, 0xdd, 0xfe, + 0x41, 0xd5, 0xaf, 0x82, 0xe1, 0x68, 0x29, 0xb1, 0x55, 0x6b, 0xdc, 0x23, 0x35, 0x6b, 0xc4, 0x42, + 0x85, 0x55, 0xd5, 0x56, 0xab, 0xae, 0xbd, 0xf0, 0x42, 0x45, 0x5d, 0xb0, 0xd3, 0x84, 0x85, 0xd6, + 0x69, 0x9b, 0x7d, 0x3d, 0xb6, 0xfe, 0xb8, 0x91, 0x04, 0xaa, 0xfc, 0x42, 0x19, 0x5c, 0x48, 0x80, + 0x53, 0xb4, 0xb3, 0x63, 0x44, 0xcd, 0xed, 0x49, 0x43, 0x78, 0x80, 0x44, 0x26, 0xef, 0xac, 0x34, + 0xe0, 0x10, 0x3f, 0xff, 0xff, 0xaf, 0xfe, 0x9f, 0x7e, 0xe2, 0x6e, 0xef, 0xbe, 0x5d, 0xee, 0xe2, + 0x44, 0x12, 0xa2, 0x9c, 0x5f, 0xc4, 0x46, 0x10, 0x73, 0x55, 0x17, 0x5e, 0x24, 0x5d, 0xde, 0xef, + 0x15, 0xfc, 0xd7, 0xbf, 0x13, 0xf9, 0x4f, 0xbb, 0xa8, 0x8d, 0x72, 0x1b, 0x77, 0xf2, 0x15, 0xdf, + 0xf3, 0x0a, 0x55, 0xf1, 0x10, 0x80, 0xba, 0x64, 0xf3, 0x2a, 0xaa, 0xb5, 0xf8, 0xfa, 0xad, 0x69, + 0x56, 0xab, 0x5d, 0xd5, 0x56, 0xa2, 0x37, 0x13, 0x05, 0x06, 0xc5, 0x72, 0xff, 0x50, 0xcf, 0x0e, + 0x73, 0xea, 0x60, 0x4a, 0x9e, 0x36, 0x89, 0xfe, 0x27, 0x96, 0x0d, 0x6e, 0xfc, 0x41, 0x8e, 0xf7, + 0xb8, 0x99, 0x6f, 0x7f, 0x82, 0x8b, 0xbd, 0xde, 0xef, 0xbd, 0x71, 0xd7, 0x71, 0x59, 0xe0, 0xfb, + 0xb7, 0xdb, 0xc4, 0x08, 0xe2, 0x7f, 0x77, 0x7f, 0xd1, 0x1f, 0xe5, 0x2e, 0xe7, 0xfe, 0x5d, 0xba, + 0x93, 0x9b, 0x77, 0x7e, 0x20, 0x48, 0x87, 0xbb, 0xbd, 0xf8, 0x8f, 0x13, 0x12, 0x25, 0x6b, 0xaa, + 0xf1, 0x11, 0xd5, 0x55, 0xae, 0xb2, 0x61, 0xb2, 0xaf, 0x25, 0x6b, 0xf0, 0x85, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x6b, 0x88, 0xaa, 0xeb, 0x5a, 0xe4, 0xbb, 0xbf, 0x88, 0x86, 0x62, 0x21, 0x31, 0x0b, + 0xad, 0xef, 0xc4, 0x14, 0xbb, 0x9f, 0xe2, 0x6c, 0xae, 0xf7, 0x7d, 0xdd, 0xde, 0xb8, 0x81, 0x8f, + 0x7b, 0xda, 0xf9, 0x44, 0xb7, 0xb7, 0xc4, 0x04, 0xcb, 0xa6, 0x7d, 0x77, 0xba, 0xe6, 0xee, 0xeb, + 0x8a, 0xdb, 0xa7, 0xb6, 0xa4, 0xec, 0xcb, 0xaf, 0x84, 0xf7, 0xbd, 0x64, 0xfe, 0x08, 0x8a, 0xaa, + 0xab, 0xdc, 0x44, 0xba, 0xd7, 0x13, 0x05, 0x85, 0x5a, 0xd5, 0x6b, 0x5a, 0xb7, 0xcd, 0x5a, 0xfc, + 0x7e, 0xab, 0xe6, 0xc5, 0x95, 0x5f, 0x17, 0x55, 0xaa, 0xd7, 0xe6, 0x25, 0xb5, 0x96, 0x24, 0x41, + 0x05, 0x3b, 0xbb, 0x85, 0xe2, 0x3f, 0x14, 0x57, 0x77, 0xbd, 0xfe, 0x09, 0x0f, 0x33, 0x15, 0x7f, + 0x82, 0x1d, 0xb7, 0x6d, 0xfe, 0x22, 0xee, 0xee, 0xf7, 0xaf, 0xf7, 0xbd, 0xf8, 0x8f, 0x13, 0xe2, + 0x1d, 0x3b, 0x55, 0xd5, 0xfe, 0x13, 0xab, 0xad, 0x0d, 0x0d, 0x0d, 0x0c, 0xdc, 0x16, 0xd7, 0x5d, + 0x6b, 0xdf, 0x04, 0x95, 0x5f, 0xbe, 0x5d, 0x55, 0x7d, 0x17, 0xbe, 0x12, 0xd5, 0x55, 0x75, 0xf1, + 0x75, 0x55, 0xaa, 0x93, 0x35, 0xcc, 0x45, 0xaa, 0xe2, 0x66, 0x2a, 0xea, 0xb0, 0x85, 0x71, 0x02, + 0xaf, 0x77, 0x2a, 0xa7, 0xf1, 0x30, 0x47, 0x3f, 0x57, 0x80, 0xd4, 0x2b, 0x11, 0x1f, 0x97, 0xae, + 0xab, 0xd4, 0x82, 0xdf, 0x8c, 0xaa, 0x3e, 0xaa, 0xa9, 0x6f, 0x5a, 0xe2, 0x44, 0x2f, 0x78, 0x9f, + 0x10, 0x13, 0x29, 0xb3, 0xb5, 0xbe, 0x26, 0xfb, 0x4b, 0xff, 0x5e, 0x93, 0x11, 0xe2, 0x3c, 0x41, + 0x89, 0xaa, 0x9b, 0x94, 0xab, 0x55, 0xe1, 0x05, 0xf7, 0xc2, 0x87, 0xaa, 0xad, 0x55, 0x55, 0x55, + 0x31, 0x75, 0xaf, 0xbe, 0x5a, 0xd3, 0xfa, 0xf7, 0xc1, 0x26, 0xb5, 0x6f, 0x90, 0x8d, 0x2d, 0x2c, + 0x4d, 0xd3, 0x3f, 0x27, 0xf1, 0x11, 0x42, 0x55, 0x55, 0x55, 0x55, 0x54, 0x22, 0x27, 0x84, 0x25, + 0x22, 0xd7, 0x88, 0xf8, 0x8f, 0x10, 0x41, 0x8b, 0xbf, 0x94, 0xf8, 0x2f, 0x5d, 0x84, 0xe2, 0x3f, + 0x62, 0xa7, 0xe9, 0xfe, 0x8f, 0xde, 0x23, 0xf5, 0x88, 0x36, 0xaa, 0xab, 0x94, 0x4d, 0xef, 0xc4, + 0x78, 0x8f, 0x12, 0xbd, 0x5c, 0x23, 0x7b, 0xbd, 0xab, 0x4d, 0x35, 0x7c, 0x4c, 0x41, 0x9e, 0xee, + 0xa2, 0xff, 0x89, 0xee, 0xee, 0xee, 0xf8, 0x91, 0x15, 0x12, 0x23, 0x89, 0x08, 0x02, 0x22, 0xbe, + 0xbd, 0xc4, 0xd7, 0xdf, 0x04, 0x59, 0xbf, 0xdc, 0x4c, 0x26, 0x79, 0x61, 0xad, 0x54, 0x94, 0x9c, + 0x4c, 0x15, 0xd5, 0x56, 0xbb, 0x7a, 0xab, 0x70, 0xcc, 0xdd, 0xb4, 0xf1, 0x32, 0x91, 0x75, 0xf1, + 0x7a, 0xd9, 0x3a, 0xaf, 0x11, 0x27, 0x75, 0xf1, 0x25, 0x46, 0xba, 0xaf, 0xe1, 0x2d, 0x92, 0xaa, + 0xd5, 0x54, 0x48, 0x21, 0x0a, 0x56, 0x6f, 0x7b, 0xd4, 0x2f, 0xb1, 0xfa, 0xaf, 0x71, 0x1f, 0x08, + 0x17, 0x54, 0xbc, 0x47, 0x12, 0x22, 0x13, 0xe2, 0x42, 0x5c, 0xbe, 0x37, 0x97, 0xe2, 0x2a, 0x23, + 0xe2, 0x7f, 0xf0, 0x8e, 0xb5, 0x7b, 0xdd, 0x7f, 0x16, 0x2f, 0x18, 0xa6, 0x9b, 0xfc, 0x20, 0x53, + 0xbe, 0xfe, 0xf7, 0xbf, 0x9b, 0x6a, 0xb8, 0x9f, 0xcb, 0xaa, 0xfc, 0x86, 0xb4, 0xee, 0xb9, 0x2f, + 0xaf, 0xa2, 0xf7, 0xcd, 0xad, 0x78, 0x81, 0x05, 0x55, 0x55, 0x55, 0x5f, 0x08, 0x02, 0xca, 0x1b, + 0xe6, 0xfe, 0xb5, 0xec, 0x53, 0xaf, 0xbe, 0xd2, 0xf9, 0xaa, 0xaa, 0xbe, 0x14, 0xaa, 0xaa, 0xad, + 0x6b, 0x5a, 0xaa, 0xaf, 0x5c, 0x40, 0x8f, 0x90, 0x8a, 0xaa, 0xbe, 0x4a, 0xaa, 0xab, 0x88, 0xf8, + 0x8e, 0x10, 0xf8, 0x98, 0x4f, 0x10, 0x13, 0x11, 0x77, 0xcd, 0xe6, 0x67, 0x89, 0x25, 0xee, 0xfe, + 0x6d, 0x56, 0xb1, 0x3e, 0x23, 0xe6, 0xdd, 0xdf, 0xc2, 0x46, 0xad, 0x5f, 0x53, 0x44, 0xf8, 0x91, + 0x1f, 0x14, 0x13, 0xd5, 0x55, 0x7f, 0x1f, 0x55, 0x55, 0x59, 0x98, 0xad, 0x57, 0x12, 0x20, 0x45, + 0x6a, 0xa9, 0xcd, 0xac, 0x78, 0x9f, 0xd1, 0x1a, 0xb8, 0x26, 0x2e, 0x92, 0xb9, 0xbb, 0xbb, 0xb7, + 0xc1, 0x25, 0x6b, 0xe3, 0xfc, 0x48, 0x2b, 0xd6, 0xb5, 0xa8, 0xba, 0xaa, 0xb7, 0xca, 0x4a, 0xaa, + 0xf9, 0xaf, 0xbe, 0x23, 0x24, 0x40, 0x9f, 0x12, 0x3f, 0x5a, 0xad, 0x75, 0x5f, 0x94, 0x45, 0x56, + 0xa2, 0x20, 0xa4, 0x6a, 0xea, 0xb8, 0xbe, 0xaa, 0xdc, 0x4d, 0x08, 0xea, 0xc2, 0x03, 0x88, 0x2e, + 0xaa, 0xb5, 0xad, 0x6e, 0x11, 0x88, 0x12, 0x12, 0x23, 0x6c, 0xe6, 0x86, 0xad, 0xab, 0x7c, 0x21, + 0xe2, 0x5e, 0xb5, 0x51, 0x22, 0x0c, 0x36, 0x93, 0xba, 0xc4, 0x8a, 0x14, 0xef, 0xb9, 0xfd, 0xa5, + 0xc2, 0x62, 0xd3, 0x7e, 0xee, 0xeb, 0x98, 0xab, 0x5f, 0x12, 0x2f, 0x93, 0xea, 0xbc, 0x48, 0x82, + 0xea, 0xda, 0x70, 0x9e, 0x18, 0x12, 0x1f, 0x45, 0xff, 0x7f, 0xe2, 0xfa, 0x6a, 0x2e, 0xa2, 0xeb, + 0x86, 0x41, 0x80, 0xad, 0xee, 0xb5, 0xf8, 0xb2, 0x56, 0xba, 0xaf, 0x96, 0xb5, 0xe2, 0x22, 0xab, + 0x5a, 0xd7, 0x89, 0x0c, 0x02, 0x42, 0x99, 0x85, 0x33, 0x12, 0x8f, 0xf1, 0x00, 0xa2, 0xaa, 0xaa, + 0xaa, 0xab, 0xee, 0x19, 0x05, 0x01, 0x0d, 0xbb, 0x6b, 0x58, 0x8f, 0x55, 0x58, 0xd7, 0x04, 0xa3, + 0x53, 0x97, 0x7f, 0x88, 0x22, 0xae, 0xb5, 0xf8, 0x9d, 0x6a, 0xad, 0xf8, 0x8d, 0xc4, 0xd8, 0x85, + 0xaf, 0xc5, 0xf0, 0x6a, 0xaa, 0x6f, 0xdd, 0xfc, 0xa5, 0xdd, 0xd7, 0x09, 0x91, 0x5f, 0x7b, 0xbf, + 0x84, 0xc4, 0xaa, 0xef, 0xbf, 0x13, 0xf1, 0x7e, 0x5c, 0x5d, 0xb1, 0xc7, 0x32, 0x0f, 0x2f, 0x71, + 0x32, 0x5b, 0xd7, 0x12, 0x21, 0x4e, 0x53, 0x40, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x58, 0x2c, + 0x30, 0x36, 0xbc, 0x10, 0x0f, 0x10, 0xf2, 0xc6, 0xe2, 0x5c, 0x49, 0x26, 0x9a, 0x4a, 0x26, 0x9a, + 0xc8, 0xed, 0x34, 0xd3, 0x4d, 0xb6, 0xc1, 0xb3, 0x96, 0x56, 0x72, 0xfc, 0x37, 0x0c, 0xa7, 0xdd, + 0x80, 0x81, 0xaf, 0xbc, 0xff, 0x5e, 0x27, 0xa2, 0x46, 0x16, 0x7b, 0x0b, 0xff, 0x8d, 0x23, 0x11, + 0x3b, 0x13, 0x3c, 0x11, 0x3e, 0x4f, 0x36, 0xc9, 0xc7, 0x92, 0x1c, 0xb2, 0xc4, 0x0e, 0xee, 0xad, + 0x53, 0x1f, 0xb9, 0xa7, 0x56, 0x7e, 0x18, 0x3c, 0x4f, 0xc4, 0xff, 0x1a, 0xc0, 0x0b, 0x62, 0xbb, + 0x3f, 0xf0, 0xc0, 0x86, 0x9a, 0x3d, 0xc3, 0xdc, 0x07, 0x7d, 0x1f, 0x55, 0xca, 0xb9, 0x72, 0x3a, + 0x71, 0x4b, 0x14, 0xb4, 0xd3, 0x15, 0x62, 0xaf, 0xc3, 0xf3, 0xe3, 0xf0, 0xd8, 0xec, 0xec, 0xc2, + 0x63, 0x4d, 0x54, 0xd7, 0x1d, 0x71, 0x6c, 0x5b, 0x2f, 0x6f, 0x7f, 0x7f, 0xf0, 0x4f, 0x4d, 0x34, + 0xd3, 0x4d, 0x34, 0xd3, 0xe2, 0x75, 0xe1, 0x61, 0x4a, 0x46, 0x18, 0xe0, 0xa7, 0xf2, 0xa8, 0xf2, + 0x2b, 0x8a, 0xfe, 0xb9, 0x82, 0x78, 0xd7, 0x95, 0x7b, 0x0c, 0x45, 0xc7, 0xfc, 0xfc, 0xe2, 0x5c, + 0x3b, 0x44, 0xf1, 0xd8, 0xf8, 0xb8, 0xff, 0x97, 0xfb, 0xd7, 0xf9, 0x7f, 0xbd, 0xe2, 0x0e, 0x52, + 0xa7, 0x36, 0x9b, 0x7d, 0x70, 0xe7, 0x1a, 0xf2, 0xaf, 0x15, 0x39, 0xb4, 0xdb, 0xfc, 0x40, 0x2f, + 0x20, 0xc5, 0x3f, 0xad, 0xf2, 0xdf, 0x15, 0x39, 0xb4, 0xdb, 0xef, 0x86, 0xe3, 0xfe, 0x5f, 0xef, + 0x1c, 0x6a, 0x69, 0xa6, 0x9f, 0xf9, 0xb8, 0xef, 0x96, 0xfb, 0xc1, 0x21, 0x0d, 0xc4, 0x70, 0xbc, + 0xf4, 0x82, 0x89, 0x6b, 0xc3, 0xe5, 0xd4, 0x6b, 0xc7, 0x7f, 0x8d, 0x7b, 0x55, 0xe5, 0x5e, 0x5f, + 0xd2, 0x2e, 0xf9, 0xe2, 0x16, 0x92, 0x6b, 0x35, 0x36, 0x6f, 0xae, 0x2b, 0x8e, 0xf9, 0x6f, 0xbc, + 0x6b, 0xca, 0xbd, 0xe1, 0x58, 0xc5, 0x37, 0x58, 0xef, 0x86, 0x29, 0xf1, 0xc9, 0x15, 0xd3, 0x4d, + 0x34, 0xcf, 0x0e, 0x6d, 0x27, 0x0e, 0x59, 0x22, 0x18, 0xc2, 0xec, 0x19, 0x08, 0x2d, 0x62, 0x5d, + 0x12, 0xe9, 0x75, 0xba, 0x5d, 0x6e, 0xf8, 0xd8, 0xc5, 0x39, 0x1a, 0xf6, 0xab, 0xca, 0xbd, 0xcb, + 0x18, 0x55, 0xf7, 0xaa, 0xf2, 0xaf, 0x15, 0x19, 0x66, 0xd3, 0x6f, 0x2e, 0x97, 0x7c, 0x3e, 0x41, + 0x2e, 0x1e, 0xe5, 0x55, 0x34, 0xd7, 0x69, 0xad, 0x44, 0x4c, 0x9d, 0x32, 0x74, 0xc9, 0xd3, 0x3e, + 0xbb, 0xe9, 0x25, 0xe3, 0xe6, 0xd7, 0xe1, 0xf1, 0xf9, 0xc6, 0x29, 0x8e, 0xbc, 0x07, 0x5e, 0x78, + 0x40, 0x20, 0x4d, 0x0a, 0x3a, 0xd1, 0x84, 0x42, 0x24, 0x9f, 0x1f, 0x86, 0xc7, 0x63, 0xc4, 0x18, + 0xb8, 0xef, 0x96, 0xfa, 0x21, 0x7e, 0x20, 0x9a, 0x49, 0x69, 0x25, 0x88, 0xd7, 0x39, 0x47, 0x1a, + 0x9a, 0x69, 0xa7, 0xeb, 0x10, 0x72, 0x55, 0x34, 0xd3, 0x4f, 0xd6, 0x26, 0xb8, 0x60, 0x53, 0x4d, + 0x1b, 0x1d, 0x98, 0x3b, 0x60, 0x3b, 0x61, 0xaf, 0xc7, 0x1a, 0x69, 0xf9, 0x4d, 0x3e, 0x34, 0xfd, + 0xf0, 0xf4, 0xb9, 0x12, 0x49, 0x45, 0x12, 0x49, 0x38, 0xae, 0xf1, 0x2d, 0x34, 0xd3, 0x4f, 0xfe, + 0x36, 0xf7, 0xac, 0xaa, 0x9f, 0x1a, 0xa8, 0x4f, 0x17, 0x1d, 0x53, 0x4d, 0x34, 0xff, 0xc1, 0x48, + 0x9d, 0x46, 0x9a, 0x0b, 0xd9, 0x48, 0x7e, 0x31, 0x1e, 0x9b, 0x3b, 0x7c, 0x10, 0xee, 0xf4, 0x77, + 0xe1, 0x9a, 0x69, 0xa6, 0x99, 0x12, 0x4d, 0x26, 0xff, 0xe1, 0xe1, 0x89, 0xc6, 0x99, 0x60, 0x6d, + 0xb7, 0xcd, 0xa6, 0xd6, 0x9d, 0xa6, 0x30, 0x5b, 0xd7, 0xa7, 0x6e, 0x6f, 0xe3, 0x6e, 0xfa, 0xab, + 0xdc, 0xf8, 0xed, 0xdb, 0x94, 0xc4, 0x0f, 0xab, 0x72, 0xf7, 0x6f, 0x2b, 0xe1, 0xb1, 0xed, 0x35, + 0x53, 0x40, 0x0d, 0x4d, 0x34, 0xd3, 0x6d, 0xb6, 0xdb, 0xf5, 0x48, 0xbc, 0x35, 0x3e, 0x1f, 0x0d, + 0x8e, 0xc0, 0x11, 0x1f, 0x4d, 0x34, 0xd3, 0x6d, 0xb6, 0xdb, 0xe1, 0x8b, 0xea, 0x95, 0x78, 0x22, + 0xee, 0xe7, 0x4f, 0xa9, 0x53, 0xea, 0x32, 0x9f, 0x52, 0xac, 0xf8, 0x23, 0xe4, 0xa0, 0xd7, 0x86, + 0x53, 0xe3, 0x4a, 0x92, 0x4c, 0x1b, 0x06, 0x92, 0x4c, 0x1b, 0x06, 0x92, 0x4d, 0x34, 0x92, 0x4d, + 0x35, 0xd6, 0xdb, 0x6d, 0xbf, 0xf1, 0xbc, 0xb8, 0x5c, 0xcb, 0x85, 0xc8, 0xbb, 0x67, 0xa3, 0xe9, + 0xca, 0xbf, 0xb6, 0xda, 0x69, 0xf8, 0xde, 0x92, 0x55, 0x54, 0x6a, 0x3a, 0x8f, 0xc7, 0xe3, 0x55, + 0x76, 0x9a, 0x2a, 0xfe, 0xdb, 0x69, 0xa7, 0xe3, 0x69, 0x17, 0x5f, 0x8f, 0xc7, 0x51, 0xd4, 0xed, + 0x55, 0xb4, 0xd2, 0x06, 0x52, 0x1a, 0xa6, 0x9b, 0x6d, 0xe4, 0xd4, 0xbc, 0x3c, 0x65, 0x9c, 0xee, + 0x41, 0xae, 0x1c, 0x75, 0xa4, 0x20, 0x90, 0x55, 0xf7, 0xc1, 0x44, 0x87, 0x0f, 0x1f, 0x55, 0x04, + 0x06, 0x7f, 0xd8, 0x80, 0x80, 0xd1, 0xd7, 0x04, 0x89, 0xaa, 0x1f, 0x31, 0x15, 0xb8, 0xa8, 0x8e, + 0x33, 0x58, 0xfa, 0x09, 0x0f, 0xea, 0x71, 0xd6, 0xb9, 0x6b, 0x66, 0xe0, 0x57, 0x40, 0x00, 0xa9, + 0xb4, 0x66, 0x99, 0x2c, 0xbe, 0x25, 0x4b, 0x29, 0x24, 0x6b, 0x24, 0x9f, 0xaf, 0xff, 0x05, 0xe3, + 0x75, 0x5e, 0x04, 0xe2, 0xb4, 0x32, 0xc6, 0xf1, 0x5d, 0xc3, 0x4a, 0x53, 0xc6, 0xb4, 0xfc, 0x68, + 0xb4, 0x92, 0x26, 0x33, 0x22, 0x89, 0x98, 0xcc, 0x4a, 0x2e, 0x28, 0xb1, 0xda, 0xdb, 0x6d, 0xb7, + 0xfe, 0x78, 0xed, 0x6d, 0xb6, 0xdb, 0xf5, 0xcf, 0x1c, 0x6a, 0x69, 0xa6, 0x9f, 0xf9, 0xeb, 0x88, + 0x4c, 0x98, 0xd6, 0x26, 0x64, 0x4c, 0xc9, 0x38, 0xc8, 0xd2, 0xf8, 0xd2, 0xc5, 0xff, 0x15, 0xc6, + 0x97, 0xc6, 0x96, 0x75, 0xf8, 0xbe, 0x91, 0x77, 0x49, 0x2f, 0x39, 0x07, 0x6a, 0x69, 0xa6, 0x9f, + 0xf8, 0x66, 0xfb, 0x8e, 0xd4, 0xd3, 0x4d, 0x3f, 0xf3, 0xc7, 0x6a, 0x69, 0xa6, 0x9f, 0xe2, 0x04, + 0xde, 0x18, 0x53, 0x27, 0x11, 0xf9, 0xe3, 0xb5, 0x34, 0xd3, 0x4f, 0xfd, 0x5f, 0xc4, 0x2a, 0x55, + 0xe1, 0x9d, 0xc5, 0x78, 0xb8, 0x89, 0x91, 0x13, 0x3f, 0xe0, 0xb7, 0xcb, 0x99, 0x71, 0xef, 0xf0, + 0x43, 0x48, 0xb9, 0x4e, 0x9a, 0x45, 0xe1, 0x89, 0x28, 0x4a, 0x64, 0xa1, 0x29, 0x8f, 0x35, 0x34, + 0xd3, 0x4f, 0xfc, 0x10, 0x84, 0x2e, 0xf8, 0x38, 0x88, 0x22, 0x2e, 0xa5, 0xc7, 0xf8, 0x4f, 0xa4, + 0x92, 0xaf, 0xe0, 0x8b, 0x7b, 0xe5, 0xf6, 0x74, 0xe3, 0x4d, 0x32, 0x76, 0x21, 0x57, 0xf0, 0xf9, + 0x9a, 0x9b, 0x55, 0x5a, 0xed, 0x35, 0x4a, 0xfd, 0x5e, 0xa3, 0xf8, 0x22, 0x16, 0xf1, 0x6e, 0xc2, + 0x58, 0x69, 0x56, 0x04, 0x38, 0x65, 0x35, 0xb6, 0x0d, 0xde, 0x20, 0x40, 0x50, 0x24, 0x1d, 0xbb, + 0xcc, 0x3a, 0x95, 0x52, 0x9c, 0xb1, 0xc0, 0x1c, 0x68, 0xef, 0x23, 0x1d, 0xb9, 0x32, 0x70, 0x12, + 0x4c, 0x52, 0xad, 0x0f, 0xcc, 0x53, 0xf0, 0x3f, 0xc1, 0x1d, 0x47, 0xa2, 0x15, 0x9d, 0xe4, 0xe8, + 0x33, 0xef, 0x08, 0x07, 0x04, 0x60, 0x18, 0xfd, 0xcf, 0x74, 0x48, 0xfa, 0x02, 0xca, 0x9a, 0x2d, + 0x5c, 0x0b, 0x4f, 0xc3, 0x85, 0x72, 0xf1, 0x01, 0x00, 0x51, 0x49, 0xea, 0x24, 0x36, 0x41, 0x32, + 0x59, 0x3b, 0xb0, 0x23, 0xc3, 0x43, 0x5c, 0x22, 0x10, 0x0c, 0x74, 0x83, 0xa5, 0x5e, 0x50, 0xd1, + 0xb0, 0x7e, 0x3f, 0x8d, 0x4b, 0x8f, 0xc4, 0x0b, 0x26, 0x13, 0x32, 0x61, 0x33, 0xf0, 0xa9, 0xaf, + 0x57, 0xba, 0xaa, 0x69, 0xa6, 0x9f, 0xf1, 0x0b, 0x11, 0xdf, 0xa2, 0xa7, 0x44, 0xe8, 0x95, 0xf3, + 0x95, 0x53, 0x4d, 0x34, 0xff, 0xcf, 0x54, 0xd3, 0x4d, 0x3f, 0x9d, 0x7e, 0x1c, 0x95, 0x89, 0x58, + 0xaa, 0x69, 0xa6, 0x9f, 0xf9, 0xea, 0x9a, 0x69, 0xa7, 0xfe, 0x22, 0xab, 0xaa, 0xfc, 0x48, 0x25, + 0xea, 0xba, 0xa9, 0xd3, 0xe0, 0x97, 0x7a, 0xde, 0xa7, 0x4f, 0x12, 0xa5, 0x4e, 0x23, 0xe2, 0x3e, + 0x86, 0x75, 0x75, 0x7b, 0xeb, 0xdf, 0x57, 0x7d, 0x7b, 0xeb, 0xff, 0xab, 0xc7, 0xf4, 0x25, 0xdc, + 0x44, 0x12, 0x04, 0x28, 0x71, 0x9b, 0xaf, 0xe2, 0x02, 0x02, 0x85, 0xf1, 0x4e, 0x29, 0x92, 0xa5, + 0x99, 0xd5, 0x2d, 0xef, 0xe2, 0x6b, 0x35, 0xab, 0x66, 0x63, 0xd0, 0x57, 0xd7, 0x88, 0x04, 0x82, + 0xa1, 0xbf, 0x0d, 0xe6, 0xa2, 0xa0, 0x82, 0x8e, 0x0f, 0x84, 0x86, 0x67, 0xb7, 0x7c, 0xd8, 0x5e, + 0xc8, 0x61, 0x08, 0x83, 0xb9, 0x92, 0x45, 0xb0, 0xfd, 0x33, 0xc7, 0x1e, 0x69, 0xe2, 0x04, 0x09, + 0x24, 0x65, 0xe9, 0x9c, 0xf9, 0x7c, 0x56, 0xba, 0x0c, 0xf4, 0x7f, 0x46, 0x8a, 0x1c, 0xc4, 0x98, + 0x21, 0x43, 0xbf, 0x08, 0x0c, 0x30, 0xbc, 0x62, 0x9c, 0xfe, 0x7f, 0x17, 0x88, 0xf9, 0x54, 0x44, + 0x2c, 0x71, 0x01, 0x00, 0x47, 0xbb, 0xbf, 0x49, 0xc2, 0x38, 0x9b, 0x07, 0xee, 0x9b, 0xba, 0xfc, + 0x48, 0x83, 0xaf, 0x5d, 0xdd, 0x3b, 0xdd, 0x71, 0xc2, 0x22, 0x1f, 0x2f, 0x1f, 0xa7, 0x7b, 0x53, + 0xe0, 0x2d, 0xc4, 0xf1, 0x31, 0x50, 0xad, 0x01, 0xcf, 0x77, 0x6f, 0x37, 0xb3, 0x7f, 0x83, 0x12, + 0xdd, 0xb7, 0x6d, 0xe1, 0x0f, 0x11, 0x51, 0x3f, 0x08, 0x42, 0xe3, 0xd8, 0x23, 0xe5, 0x6d, 0xb6, + 0xdb, 0xf7, 0xd0, 0x8e, 0xfa, 0xd5, 0xf0, 0x49, 0x7b, 0xd3, 0x2f, 0x30, 0xad, 0x54, 0x6f, 0x42, + 0xfb, 0xe0, 0xb0, 0x62, 0x7b, 0x71, 0x5e, 0xe7, 0x53, 0x57, 0xf8, 0x27, 0x20, 0x9f, 0x2a, 0x81, + 0x3e, 0xde, 0x0e, 0xdd, 0xbc, 0x55, 0xb7, 0xeb, 0xc4, 0x89, 0x21, 0x63, 0x6e, 0xf7, 0xbf, 0x94, + 0x2e, 0xee, 0xef, 0xeb, 0x5f, 0x14, 0x3a, 0x66, 0x29, 0xd2, 0x3b, 0x2d, 0x0e, 0x7b, 0x32, 0xaa, + 0xf1, 0x11, 0x43, 0x74, 0x6f, 0x2f, 0xbf, 0x12, 0x09, 0xcd, 0x59, 0xbb, 0x7a, 0xb0, 0x37, 0xf1, + 0x02, 0x48, 0x13, 0xc8, 0xd5, 0x27, 0x01, 0xc6, 0x4b, 0x5a, 0xd5, 0x34, 0x67, 0xe8, 0x22, 0xdf, + 0x57, 0x04, 0xe7, 0x3a, 0x45, 0xe9, 0x8b, 0x79, 0x3a, 0x32, 0x78, 0x98, 0x46, 0xb2, 0x9b, 0xa1, + 0x1a, 0xf9, 0xb3, 0xe5, 0x4d, 0xd1, 0xf2, 0xf9, 0xba, 0xa9, 0xf8, 0x44, 0x20, 0x6e, 0xa1, 0x32, + 0xda, 0x0a, 0x66, 0x9a, 0x65, 0x65, 0x9f, 0x4f, 0x89, 0x37, 0x4c, 0xe1, 0x80, 0xae, 0x50, 0x9b, + 0xbd, 0xf8, 0x91, 0x41, 0x24, 0x75, 0xaa, 0xab, 0x31, 0x91, 0x0c, 0xb1, 0x78, 0x45, 0x15, 0xfe, + 0x63, 0xbd, 0xbf, 0x84, 0x86, 0x1a, 0x2d, 0x8f, 0x40, 0xc7, 0x62, 0x3f, 0x63, 0x50, 0x13, 0x1f, + 0xbe, 0x85, 0xb7, 0xd6, 0xbe, 0x8a, 0xf2, 0xf4, 0x66, 0xfa, 0x2b, 0x7d, 0x5f, 0xea, 0xff, 0x56, + 0xfa, 0xb5, 0x75, 0x79, 0x3a, 0x35, 0x7c, 0xdd, 0xcb, 0x8f, 0x82, 0x6a, 0xab, 0xbb, 0xab, 0xac, + 0xab, 0xb3, 0x6d, 0x35, 0xec, 0xae, 0x6c, 0xdf, 0x7b, 0xdf, 0xd1, 0x58, 0x93, 0x82, 0x4e, 0xef, + 0x9f, 0xef, 0xbb, 0xae, 0xfa, 0xaa, 0xeb, 0x14, 0x9c, 0x12, 0x08, 0x85, 0x71, 0x9b, 0x61, 0xe1, + 0x11, 0x14, 0xd4, 0x9e, 0x57, 0x6b, 0xb7, 0xe3, 0x2f, 0xbd, 0x62, 0xe6, 0x20, 0xac, 0xa6, 0xaa, + 0x52, 0xdf, 0x84, 0xef, 0xa4, 0x2b, 0x3f, 0xb5, 0xe0, 0x9a, 0xd3, 0x54, 0x0e, 0x6f, 0xeb, 0xe1, + 0x13, 0x57, 0x9d, 0x45, 0xe5, 0xa7, 0x75, 0xf1, 0x23, 0x5d, 0xf7, 0xd0, 0xf8, 0x91, 0xc3, 0x1e, + 0xfa, 0xad, 0x16, 0x30, 0xbe, 0x08, 0x46, 0xa9, 0x34, 0x71, 0x37, 0x74, 0x31, 0x11, 0xfa, 0x16, + 0xd2, 0xf1, 0x17, 0x7f, 0x49, 0x2f, 0x5a, 0xfa, 0xbf, 0xc1, 0x0d, 0x6b, 0x65, 0xf4, 0x68, 0xa2, + 0x79, 0xb4, 0xd5, 0xd7, 0x04, 0x46, 0x4c, 0x99, 0xb7, 0xc6, 0x74, 0x0d, 0xdb, 0xee, 0xe7, 0xde, + 0xd5, 0xd9, 0x7c, 0x77, 0x4d, 0xca, 0xa1, 0x7e, 0x75, 0x39, 0x49, 0xff, 0xae, 0x28, 0x96, 0xe9, + 0x26, 0x62, 0x1a, 0x0b, 0xc2, 0x26, 0xe2, 0xeb, 0x35, 0x22, 0xf5, 0xfb, 0x16, 0x1e, 0x25, 0x85, + 0xfe, 0x12, 0x43, 0xc4, 0xc8, 0x95, 0x3a, 0x69, 0xf9, 0x3a, 0x27, 0x7c, 0xa6, 0xab, 0x4a, 0xb9, + 0x2d, 0xb6, 0xdc, 0xdd, 0x09, 0xe9, 0xf1, 0x28, 0xb9, 0x4d, 0xd1, 0x2a, 0x2f, 0xab, 0xc5, 0x72, + 0x05, 0x16, 0xb5, 0xcc, 0x57, 0xdf, 0xd5, 0xe6, 0xe8, 0x7f, 0x45, 0x75, 0xe8, 0xde, 0xad, 0x15, + 0xd6, 0x74, 0x12, 0x75, 0xa9, 0xfa, 0x2d, 0x5e, 0x10, 0x57, 0x93, 0xb2, 0xbe, 0xab, 0xa1, 0x0e, + 0x78, 0x8a, 0xea, 0xca, 0xc4, 0xa2, 0x74, 0xfc, 0x17, 0x0a, 0x7b, 0xbe, 0x86, 0xb2, 0xf8, 0xc2, + 0x19, 0x66, 0x3a, 0x6b, 0x59, 0xb3, 0x66, 0x36, 0x18, 0xb3, 0x20, 0x1c, 0x55, 0xc5, 0x6f, 0x4f, + 0x27, 0xf8, 0x47, 0x46, 0x33, 0x1f, 0x02, 0xb1, 0x1a, 0x34, 0x09, 0x58, 0x42, 0x15, 0x84, 0x11, + 0x58, 0x4a, 0xfc, 0x46, 0x4c, 0xac, 0xbe, 0x9f, 0x88, 0x12, 0xe7, 0xef, 0xde, 0xd7, 0xb2, 0x2a, + 0x5b, 0xe8, 0x22, 0x28, 0x6b, 0xea, 0xe7, 0xcd, 0xad, 0x46, 0x75, 0x72, 0xba, 0xeb, 0xeb, 0xd1, + 0x1d, 0x5e, 0x2b, 0xab, 0xc6, 0xf2, 0x04, 0x2f, 0x77, 0xd6, 0x50, 0x9f, 0x43, 0xda, 0x10, 0xeb, + 0x53, 0x75, 0x94, 0x9c, 0xc1, 0x29, 0xbc, 0xdf, 0xd9, 0x16, 0xb2, 0x74, 0x35, 0xbe, 0xeb, 0xa8, + 0x44, 0x5a, 0x17, 0x46, 0xfe, 0xad, 0x11, 0xd5, 0xeb, 0xa2, 0xb4, 0x4f, 0x56, 0x88, 0xe8, 0x24, + 0xe7, 0xcb, 0x2b, 0x1f, 0x88, 0x47, 0xef, 0x10, 0x53, 0x2a, 0xef, 0xa3, 0xbd, 0x62, 0x02, 0x85, + 0x3f, 0xbe, 0xb5, 0xa4, 0xb2, 0x64, 0xef, 0xf1, 0x84, 0xaa, 0x4d, 0x2a, 0xaf, 0x17, 0xcb, 0x4f, + 0xc5, 0xc9, 0x05, 0xd6, 0xb0, 0xbf, 0x04, 0x62, 0x6b, 0x5c, 0xcf, 0x82, 0x2d, 0xef, 0x55, 0xce, + 0x25, 0x71, 0x29, 0x91, 0x29, 0x9f, 0x5c, 0x30, 0x45, 0x55, 0x55, 0x57, 0x74, 0xe3, 0x4d, 0xdf, + 0xf8, 0x80, 0xd9, 0x26, 0xca, 0x43, 0x05, 0x5d, 0x22, 0x6f, 0xf9, 0xfb, 0x6e, 0xd9, 0x7f, 0xf9, + 0x2e, 0xff, 0x9a, 0xee, 0xef, 0x09, 0x12, 0x08, 0x9a, 0x91, 0xc1, 0x83, 0xec, 0x61, 0x44, 0xd4, + 0x9a, 0x36, 0xff, 0x86, 0xae, 0xea, 0xa5, 0x51, 0xf6, 0x9a, 0x49, 0x28, 0x41, 0x41, 0x22, 0x9c, + 0xf2, 0x47, 0xcd, 0xa6, 0xd3, 0xeb, 0xf7, 0xfc, 0x6f, 0x55, 0x55, 0xd5, 0x7d, 0xde, 0x31, 0xf6, + 0x9a, 0x49, 0x2f, 0x0c, 0xd5, 0x75, 0xcd, 0xa6, 0xdf, 0xf2, 0x55, 0x52, 0x49, 0x70, 0xaf, 0x55, + 0xd5, 0x73, 0x72, 0x69, 0x37, 0xfc, 0x12, 0x12, 0xaf, 0x4a, 0xbc, 0x13, 0x93, 0x77, 0x83, 0xfc, + 0x29, 0x05, 0xec, 0x18, 0xbe, 0x09, 0x89, 0x36, 0x7b, 0x96, 0x89, 0x17, 0x8c, 0xb1, 0x95, 0x43, + 0xbe, 0x8c, 0x8b, 0xd6, 0xdc, 0xde, 0xe3, 0x48, 0x8d, 0x51, 0xbf, 0x82, 0x13, 0xe5, 0xfe, 0xf8, + 0x2a, 0x2b, 0x51, 0x7d, 0x32, 0xe6, 0xf1, 0x2e, 0x09, 0x52, 0x0e, 0xdf, 0x05, 0x84, 0x99, 0x83, + 0x28, 0x50, 0xe0, 0xb4, 0xf5, 0x43, 0x05, 0xe6, 0x35, 0x93, 0x28, 0x4d, 0xe2, 0x06, 0x0a, 0x63, + 0x62, 0xa1, 0xa8, 0xb9, 0x22, 0x42, 0x0c, 0x68, 0xd4, 0xcd, 0xf4, 0x10, 0x04, 0x23, 0x66, 0xa2, + 0x8b, 0x67, 0xcc, 0x50, 0xcb, 0xc9, 0xe1, 0x4a, 0x42, 0x11, 0x82, 0x21, 0x10, 0x1b, 0x0e, 0xaa, + 0x4a, 0x21, 0xc1, 0x4e, 0x67, 0x8f, 0x39, 0xc5, 0x60, 0xb4, 0xfc, 0x2d, 0x9a, 0x4e, 0xd0, 0xbc, + 0x89, 0xa9, 0x07, 0xbc, 0x40, 0x40, 0xed, 0xdf, 0xda, 0x6d, 0xf9, 0x2f, 0x9b, 0xe5, 0xae, 0x1d, + 0x2c, 0x27, 0x5f, 0x1c, 0x99, 0x32, 0x7f, 0xe2, 0x48, 0x5e, 0x5f, 0xe1, 0x41, 0x29, 0xd0, 0xb2, + 0x56, 0x9b, 0xa7, 0x82, 0x2d, 0x5f, 0xd1, 0xbd, 0xfe, 0x13, 0xa4, 0x4c, 0x66, 0xea, 0x5a, 0x0e, + 0x7e, 0x24, 0xef, 0xc6, 0x67, 0xa1, 0x7f, 0x19, 0xe8, 0x5d, 0x79, 0xa8, 0x43, 0xd9, 0x4c, 0x53, + 0x24, 0xcf, 0xc2, 0x3b, 0x4b, 0xbd, 0xe4, 0xc7, 0xfc, 0x84, 0x43, 0x9f, 0xfc, 0x65, 0xf1, 0x58, + 0xdf, 0xaf, 0x36, 0xa1, 0xbd, 0xd2, 0x8f, 0xf1, 0x82, 0x9d, 0x05, 0xb9, 0x01, 0x0b, 0x01, 0x2e, + 0x1a, 0x96, 0x08, 0x1c, 0xac, 0x6f, 0x65, 0xd8, 0xae, 0xcf, 0x05, 0x71, 0xf1, 0x03, 0xda, 0x49, + 0x9a, 0x91, 0x25, 0x01, 0xb0, 0x40, 0x64, 0x22, 0xf4, 0x2f, 0xea, 0x9b, 0x85, 0x94, 0x3c, 0xa5, + 0xe5, 0xc1, 0x0e, 0x17, 0x84, 0x41, 0x0f, 0x1e, 0x5e, 0x3c, 0xa1, 0x75, 0x7e, 0xba, 0x09, 0x37, + 0xce, 0x4e, 0xe2, 0x7a, 0xd7, 0x89, 0xe4, 0x31, 0x71, 0x2d, 0x74, 0x7e, 0x73, 0xe1, 0xc3, 0x2a, + 0xdd, 0x4f, 0xaf, 0xdf, 0xfc, 0x37, 0x49, 0x26, 0x9a, 0x53, 0xe9, 0xf7, 0xf5, 0xc2, 0x56, 0xb4, + 0x95, 0x77, 0xc1, 0x2f, 0x55, 0x69, 0xa4, 0xaf, 0xf4, 0x47, 0xf8, 0x25, 0xb4, 0xd6, 0xd3, 0x5b, + 0xfc, 0x12, 0x6e, 0xb2, 0x95, 0x77, 0xdd, 0xdf, 0x04, 0x96, 0xa0, 0xea, 0xcf, 0x7c, 0x17, 0xdd, + 0x54, 0x8a, 0x2d, 0x9a, 0x9d, 0x85, 0x33, 0x5f, 0xfe, 0x14, 0xdc, 0x2e, 0xe2, 0x8e, 0xee, 0x86, + 0x72, 0xc3, 0x7d, 0x1a, 0x95, 0x1c, 0x8c, 0x77, 0xc1, 0x66, 0xee, 0x0b, 0x71, 0xa4, 0x5c, 0x8e, + 0xec, 0xe4, 0xc4, 0x4a, 0xa3, 0x7f, 0x12, 0x38, 0xd9, 0xcf, 0xd3, 0xa8, 0x8e, 0xde, 0xdd, 0xf1, + 0x22, 0x02, 0x02, 0xc7, 0xee, 0x70, 0x90, 0xcc, 0xc4, 0xb1, 0xac, 0x8a, 0x3c, 0x4c, 0x75, 0xec, + 0x7b, 0xde, 0x57, 0xf0, 0x58, 0x23, 0x51, 0x78, 0xea, 0xeb, 0x27, 0xcd, 0x01, 0xf5, 0xfe, 0x31, + 0x21, 0x00, 0xa1, 0x04, 0xb8, 0x31, 0xf7, 0xd5, 0x35, 0x0d, 0xe2, 0x76, 0xdb, 0xc4, 0xa2, 0x44, + 0xc6, 0x4c, 0x0c, 0x22, 0x72, 0xa0, 0x5c, 0xdb, 0xc8, 0xe4, 0x9b, 0xb6, 0xb0, 0x6d, 0x3d, 0xce, + 0xe2, 0x03, 0x01, 0x4b, 0xb5, 0xe8, 0x60, 0x4c, 0x72, 0x23, 0xd2, 0x0b, 0xe0, 0xe3, 0x01, 0x38, + 0x81, 0x05, 0xc0, 0x35, 0xf8, 0x54, 0x4f, 0xd5, 0x44, 0xec, 0x69, 0x92, 0xf1, 0x78, 0xf5, 0xf7, + 0x88, 0x19, 0xe4, 0x87, 0x4d, 0xa4, 0x65, 0x4b, 0x31, 0x4f, 0x37, 0x65, 0xb7, 0x6d, 0x2e, 0x3e, + 0xdc, 0x56, 0x78, 0xfe, 0xf8, 0x91, 0x21, 0x01, 0xa2, 0x9a, 0xb1, 0x9a, 0xdd, 0xac, 0x26, 0x5b, + 0x9f, 0x1f, 0xc4, 0xc1, 0x3d, 0xed, 0xcd, 0x41, 0x3a, 0x57, 0xab, 0xb9, 0xe0, 0xf2, 0x96, 0xfc, + 0xd4, 0xe9, 0xf1, 0x3f, 0x0c, 0x1a, 0xed, 0xbd, 0x70, 0x59, 0x9b, 0x39, 0xbb, 0xd8, 0xba, 0xa4, + 0x75, 0x32, 0xf8, 0xc1, 0x0e, 0x13, 0xd4, 0x70, 0x15, 0x4e, 0xa1, 0xd8, 0xc4, 0x3a, 0x0a, 0xc5, + 0xe0, 0x06, 0xab, 0xe2, 0xc9, 0x93, 0x2f, 0x5b, 0xe6, 0x04, 0xe2, 0xbe, 0xb8, 0x78, 0x10, 0x6a, + 0xee, 0xfa, 0x74, 0xb1, 0x3b, 0x8d, 0x21, 0xb5, 0x45, 0xfe, 0x15, 0x24, 0x9b, 0x74, 0xad, 0x35, + 0x2d, 0x0c, 0x67, 0xfb, 0xf5, 0xc2, 0x1d, 0x22, 0x43, 0x91, 0xb9, 0x24, 0xd8, 0x9e, 0x08, 0xc7, + 0xbb, 0xe7, 0x4f, 0x82, 0x7a, 0x49, 0x69, 0x24, 0x92, 0x5e, 0x3e, 0x08, 0xee, 0xf9, 0x94, 0x7c, + 0x10, 0xeb, 0x53, 0xa5, 0x70, 0x49, 0x3e, 0x66, 0xc3, 0x37, 0xc2, 0x25, 0xda, 0x69, 0xa6, 0xbb, + 0x4d, 0x7e, 0x10, 0xa4, 0x96, 0xd3, 0x5b, 0x4d, 0x7e, 0xac, 0xfa, 0x22, 0x47, 0xe0, 0xa6, 0xab, + 0xe9, 0x24, 0xab, 0x91, 0x15, 0x2e, 0x0b, 0xaa, 0xbb, 0xea, 0x44, 0x55, 0xe0, 0x92, 0xef, 0x91, + 0x3e, 0x08, 0xba, 0xa9, 0x5b, 0xe6, 0x24, 0x69, 0xa8, 0x47, 0x8e, 0x77, 0xc4, 0x02, 0x53, 0x47, + 0x58, 0xbd, 0x6b, 0xf2, 0x9d, 0x62, 0xf8, 0xfe, 0xf7, 0x7d, 0x54, 0x9a, 0xba, 0xe0, 0x94, 0xa2, + 0xb7, 0x72, 0xc3, 0xcf, 0xdf, 0xc2, 0x21, 0x03, 0x3b, 0xab, 0xa7, 0x6e, 0x14, 0x79, 0x4d, 0x8a, + 0xd6, 0xb8, 0x99, 0x45, 0xa7, 0x27, 0xe1, 0x91, 0x20, 0xb2, 0x7c, 0x6b, 0xdd, 0xb7, 0x46, 0xb7, + 0xf1, 0x01, 0x42, 0x62, 0xb5, 0x79, 0x1b, 0x44, 0x58, 0x25, 0x51, 0x4d, 0x54, 0x53, 0x12, 0x52, + 0x16, 0x1f, 0x71, 0x30, 0xa5, 0xcc, 0x3f, 0x56, 0x58, 0x2f, 0x3c, 0x24, 0x16, 0x10, 0x4e, 0x0e, + 0x1f, 0xec, 0x0c, 0x04, 0xbc, 0xf2, 0x30, 0x49, 0x25, 0xc2, 0xc1, 0x01, 0xd8, 0xa0, 0x28, 0xab, + 0xfc, 0x29, 0x25, 0x0d, 0x09, 0x8a, 0x9c, 0x68, 0x58, 0x6b, 0x99, 0x9e, 0xf3, 0xa9, 0x2c, 0x5c, + 0x53, 0x2f, 0x11, 0x60, 0xbd, 0x63, 0x6d, 0x9e, 0x24, 0x41, 0x0e, 0x79, 0x63, 0x62, 0x82, 0x60, + 0x55, 0xdb, 0xbf, 0x12, 0x38, 0xa9, 0x8a, 0xc1, 0x9a, 0x85, 0xb7, 0xbb, 0xb9, 0x4d, 0x8a, 0x6d, + 0x62, 0x44, 0x98, 0xaf, 0x77, 0xc4, 0x46, 0x57, 0x5b, 0x48, 0xd6, 0xee, 0xe9, 0x69, 0x78, 0x9c, + 0xd4, 0x36, 0xe5, 0xef, 0xbf, 0x82, 0xc1, 0x17, 0x63, 0x77, 0x40, 0xce, 0xa7, 0x9f, 0x3e, 0xf8, + 0x28, 0x16, 0xee, 0xef, 0xbb, 0xed, 0xf2, 0x10, 0xbe, 0x2b, 0xf8, 0xc2, 0x65, 0x62, 0xba, 0xbd, + 0xcd, 0xf5, 0x17, 0xf1, 0x3d, 0x4d, 0xba, 0x9b, 0x3c, 0x26, 0x2c, 0xc4, 0x13, 0x12, 0x11, 0x18, + 0x2e, 0x20, 0x8c, 0x7a, 0x1b, 0x29, 0xf8, 0x52, 0xa2, 0xe8, 0xd5, 0x35, 0x4e, 0x8d, 0x1a, 0xaa, + 0x34, 0x68, 0xd1, 0xf1, 0xff, 0x04, 0xa1, 0x04, 0xc7, 0x5d, 0x15, 0x43, 0x0e, 0x2b, 0x54, 0x5b, + 0xc4, 0x02, 0x3a, 0xc6, 0x04, 0x09, 0x83, 0x04, 0xa9, 0x5c, 0x11, 0x16, 0xa3, 0x99, 0x46, 0x9d, + 0xf8, 0x27, 0x25, 0xb4, 0x36, 0xda, 0xb4, 0xdc, 0x1f, 0x0a, 0x1d, 0x9c, 0xb5, 0x44, 0x48, 0x35, + 0xf2, 0xca, 0xd1, 0xdf, 0x96, 0xf8, 0xce, 0x35, 0x5f, 0xaa, 0x1c, 0x1b, 0x1a, 0x0c, 0x97, 0x96, + 0x0d, 0xfb, 0x26, 0x99, 0x63, 0xe0, 0x8a, 0xb7, 0xc4, 0x97, 0xce, 0x2d, 0x5a, 0xb6, 0x6d, 0xff, + 0x59, 0x7c, 0x14, 0x19, 0xa6, 0xb3, 0xe6, 0xf2, 0xfa, 0xc5, 0xf1, 0x62, 0x5d, 0xfd, 0xdd, 0xf1, + 0x7d, 0x24, 0xb4, 0x92, 0xf0, 0x45, 0xdd, 0xd2, 0x3e, 0x23, 0xe7, 0xaf, 0xb6, 0xdb, 0x6d, 0xfa, + 0xfc, 0xfa, 0xb9, 0xf5, 0x63, 0xe0, 0xbb, 0xbb, 0xde, 0xec, 0x5e, 0x25, 0x14, 0x76, 0xfa, 0xa7, + 0x5e, 0x6c, 0xdd, 0xa5, 0x22, 0x93, 0xc1, 0x68, 0xc5, 0x88, 0xad, 0xac, 0x0e, 0x24, 0x90, 0xdf, + 0x17, 0x10, 0xa7, 0x4b, 0x82, 0x4b, 0x4f, 0x77, 0xf8, 0xeb, 0xa3, 0x7a, 0xd4, 0x9d, 0xef, 0xf0, + 0xa4, 0xf8, 0xdd, 0xbc, 0x6d, 0x00, 0xad, 0xfd, 0xee, 0xa5, 0xf6, 0xea, 0x96, 0xef, 0xe1, 0x11, + 0x9a, 0x89, 0x5c, 0x9e, 0xa3, 0x7c, 0x8b, 0xfd, 0xd9, 0xb5, 0x23, 0x15, 0x8e, 0x24, 0x8a, 0xac, + 0x67, 0x93, 0xf0, 0xcc, 0x28, 0x57, 0x71, 0x58, 0xae, 0xb1, 0x3c, 0x60, 0xde, 0xd2, 0x9c, 0x48, + 0x24, 0xa1, 0xff, 0xf7, 0x04, 0x10, 0xa1, 0x05, 0xc4, 0x79, 0x79, 0x26, 0xd3, 0xc8, 0x40, 0x12, + 0xce, 0x22, 0x9c, 0x67, 0x2d, 0xb3, 0x4b, 0x19, 0x84, 0x04, 0xeb, 0x0a, 0xde, 0x92, 0xfe, 0x20, + 0x76, 0x83, 0xa6, 0xac, 0xe7, 0xee, 0xfc, 0x5c, 0xdf, 0xc1, 0x34, 0x98, 0x5f, 0xa1, 0xdc, 0xaa, + 0x37, 0xe2, 0x23, 0x8a, 0x23, 0xe2, 0x86, 0xb7, 0xba, 0xd4, 0x5f, 0x88, 0xf0, 0x52, 0x12, 0x13, + 0xbb, 0xbb, 0x89, 0x54, 0x5e, 0x20, 0x48, 0x21, 0x10, 0xee, 0xf7, 0xf8, 0xa3, 0x5a, 0x7e, 0xd3, + 0xbe, 0x08, 0xb3, 0x76, 0x3f, 0xbe, 0x08, 0x79, 0xa4, 0xdd, 0x36, 0xf8, 0x50, 0x4d, 0x6a, 0xaa, + 0xaa, 0xb4, 0x92, 0x5a, 0xab, 0x71, 0x3f, 0x8e, 0xaa, 0xb3, 0x55, 0x59, 0xb1, 0x4d, 0x8b, 0xf8, + 0xba, 0x31, 0x8f, 0x6b, 0xcd, 0x82, 0xd4, 0x5e, 0x14, 0x15, 0xbd, 0x98, 0x5d, 0x48, 0x53, 0x94, + 0x2b, 0x55, 0xc8, 0x63, 0x4e, 0xec, 0x3c, 0x37, 0x3c, 0x3d, 0x56, 0x4f, 0xff, 0x0c, 0xf2, 0xe1, + 0x71, 0x64, 0xf5, 0xff, 0x05, 0x34, 0x48, 0xca, 0xcf, 0x9d, 0xac, 0x8f, 0xcb, 0x46, 0xaa, 0x67, + 0xc1, 0x6e, 0x4d, 0x6b, 0x73, 0x6b, 0x5b, 0xfc, 0x16, 0x10, 0xf9, 0x4b, 0x49, 0xbd, 0x1d, 0x9b, + 0x5c, 0xeb, 0xc2, 0xf6, 0xdb, 0xab, 0x49, 0x6a, 0xdb, 0x4a, 0x97, 0xf8, 0xbb, 0x4a, 0x96, 0x95, + 0x2f, 0x0d, 0x95, 0x22, 0x6a, 0x51, 0xa9, 0x35, 0x26, 0x9a, 0xff, 0x04, 0xdd, 0x24, 0xb6, 0x94, + 0xb7, 0xc2, 0xf4, 0x92, 0xdd, 0xf6, 0x24, 0xc9, 0xff, 0xc1, 0x55, 0xaa, 0xd6, 0x92, 0x49, 0x25, + 0xc1, 0x5d, 0xef, 0x75, 0xc3, 0x05, 0x69, 0xa2, 0xe3, 0x31, 0xa3, 0xe4, 0xea, 0x9a, 0x69, 0x25, + 0xeb, 0x84, 0xef, 0x7e, 0x92, 0x4f, 0x9a, 0xf7, 0x3f, 0x5c, 0x39, 0xd5, 0x55, 0x34, 0xdf, 0xfe, + 0x6c, 0xf9, 0x5f, 0x09, 0x6b, 0x53, 0xe1, 0xf2, 0x67, 0xc9, 0x55, 0xfc, 0xe5, 0x5b, 0x63, 0x32, + 0xd8, 0x6b, 0xdf, 0x05, 0x9a, 0xb2, 0xd8, 0xc6, 0x51, 0x35, 0x45, 0x55, 0xc2, 0x6d, 0x1a, 0x6b, + 0x04, 0xff, 0x44, 0x67, 0x88, 0x10, 0x5a, 0x57, 0x76, 0x90, 0x5f, 0x05, 0x9e, 0x2b, 0xe3, 0xf9, + 0x21, 0xef, 0xde, 0x25, 0xf3, 0xfe, 0x26, 0x30, 0xd4, 0x4f, 0x7e, 0x1e, 0x7c, 0x49, 0xf7, 0x67, + 0x6c, 0xbe, 0xbc, 0x30, 0x10, 0x93, 0xab, 0x7c, 0xb1, 0xef, 0xbb, 0xf0, 0x80, 0xa1, 0x2a, 0x2e, + 0x6e, 0x59, 0x9b, 0x97, 0x9a, 0x85, 0x9c, 0x36, 0xa0, 0x06, 0x11, 0xc0, 0xb4, 0xae, 0xcb, 0xc5, + 0x3b, 0x17, 0x67, 0x27, 0x71, 0x9e, 0xc1, 0x58, 0xd6, 0xe4, 0xee, 0x1c, 0x99, 0xc7, 0xbd, 0x3f, + 0xc1, 0x00, 0x31, 0x18, 0x63, 0xe1, 0x00, 0x79, 0xaa, 0x58, 0xab, 0x43, 0x65, 0x23, 0xfc, 0x10, + 0xa8, 0x7d, 0x5c, 0x40, 0x21, 0x08, 0xd2, 0xdc, 0xdb, 0x17, 0x57, 0x15, 0xa9, 0x51, 0x62, 0x43, + 0x0b, 0x5f, 0x05, 0xc5, 0xab, 0x72, 0x7a, 0x77, 0xe1, 0x08, 0x24, 0xbe, 0x95, 0xfe, 0x2c, 0xf5, + 0xaa, 0xaf, 0xe2, 0x05, 0x5b, 0xb7, 0x2e, 0xeb, 0x82, 0xb3, 0xd3, 0xa7, 0x8c, 0xd8, 0xde, 0xee, + 0xff, 0x05, 0x25, 0xbd, 0xdc, 0xac, 0x5e, 0xef, 0xa3, 0xbf, 0x05, 0x83, 0x8d, 0xcd, 0xbf, 0x3d, + 0x05, 0xd6, 0x56, 0x6f, 0x82, 0x91, 0x2f, 0x2a, 0x9a, 0xa9, 0x21, 0x25, 0xea, 0xaa, 0xdc, 0x48, + 0x91, 0xc5, 0x1c, 0x10, 0x1e, 0x92, 0x0e, 0x8d, 0xb4, 0x75, 0x42, 0x5c, 0x21, 0x19, 0x55, 0xd9, + 0xea, 0xaa, 0xab, 0x5a, 0xf8, 0x52, 0x31, 0x7a, 0xa7, 0x51, 0xd0, 0x1c, 0xe7, 0x64, 0xb8, 0xcc, + 0xc8, 0x78, 0xf4, 0xaf, 0x5e, 0xf8, 0x89, 0x29, 0x3d, 0xa6, 0xbf, 0x08, 0x10, 0x7f, 0x27, 0xff, + 0x36, 0x77, 0xa5, 0xe0, 0x88, 0x55, 0xe3, 0x83, 0x49, 0xc5, 0xf0, 0x57, 0xe2, 0x48, 0x57, 0x77, + 0x5a, 0xa9, 0x81, 0xf0, 0x4a, 0x56, 0x9a, 0xcf, 0x6c, 0xff, 0x1f, 0x04, 0x33, 0xd5, 0xbe, 0x0f, + 0x82, 0x8b, 0xb7, 0xe4, 0xd4, 0xd2, 0x2f, 0x04, 0x9e, 0x6d, 0x32, 0x9f, 0x19, 0xa6, 0xe9, 0xd2, + 0x7b, 0x7a, 0xf2, 0x6d, 0x3f, 0x56, 0xf8, 0xf2, 0xa5, 0x49, 0x24, 0xf4, 0xb7, 0x4f, 0xc1, 0x4e, + 0xdd, 0xb4, 0x92, 0xda, 0xda, 0x6f, 0x93, 0x6a, 0xd7, 0x8c, 0xd6, 0xba, 0x69, 0xb6, 0x9b, 0x69, + 0x97, 0xc7, 0xfc, 0x12, 0x5d, 0xf7, 0xae, 0x10, 0xd5, 0xbb, 0x6a, 0xdd, 0x39, 0x29, 0xf0, 0x8c, + 0x99, 0xb5, 0xc9, 0x8e, 0xb1, 0x7c, 0x27, 0x77, 0xf4, 0x92, 0xf0, 0x95, 0xa6, 0x9a, 0x36, 0xb5, + 0x49, 0x2f, 0x09, 0xdf, 0xad, 0xbb, 0x7e, 0x08, 0xad, 0x55, 0xb9, 0x5c, 0xa5, 0x77, 0x2d, 0xc3, + 0xf2, 0x69, 0x4b, 0x84, 0xe1, 0x29, 0xf3, 0x69, 0x24, 0x92, 0x4b, 0xc5, 0x53, 0x93, 0xdd, 0xff, + 0x05, 0x64, 0x5a, 0x19, 0xa0, 0xdb, 0x79, 0xfc, 0x67, 0xec, 0xab, 0x9c, 0xbe, 0x10, 0xdd, 0xb7, + 0x77, 0x4a, 0xd5, 0x2f, 0x12, 0xaf, 0xe2, 0x1f, 0x6f, 0xfe, 0x26, 0x10, 0x83, 0xfe, 0xe9, 0x9e, + 0xaf, 0x6e, 0xee, 0xdb, 0x87, 0x70, 0x0c, 0x48, 0x64, 0x17, 0x1a, 0x9a, 0xdd, 0xfe, 0xf1, 0x22, + 0x84, 0xa4, 0x2e, 0xe4, 0x61, 0xe7, 0xc2, 0x21, 0x81, 0xc4, 0x63, 0xe5, 0xc1, 0x72, 0xcf, 0x17, + 0x77, 0xe0, 0xaf, 0xe1, 0x81, 0x92, 0xf9, 0x58, 0xa6, 0x28, 0x19, 0x08, 0x25, 0xfa, 0xa2, 0x15, + 0xbb, 0x41, 0x55, 0x96, 0x11, 0x84, 0x22, 0x9a, 0x8b, 0xad, 0xf1, 0x5c, 0x56, 0xe2, 0xb8, 0x5e, + 0x50, 0x01, 0xc4, 0xaf, 0x60, 0x88, 0xae, 0xdd, 0xeb, 0xf4, 0xe5, 0xfb, 0x78, 0xfe, 0x0f, 0xe9, + 0x17, 0xf0, 0x8c, 0x51, 0x2b, 0x5b, 0x9f, 0xf8, 0x46, 0x0a, 0x4e, 0x9a, 0x45, 0xe5, 0xb4, 0xad, + 0x4b, 0x6e, 0x2b, 0x2e, 0x3f, 0x08, 0x06, 0x1f, 0x77, 0xf0, 0x56, 0x67, 0x77, 0x72, 0xfe, 0xf5, + 0xa5, 0xde, 0x24, 0x28, 0x53, 0xb3, 0x63, 0xe9, 0xbb, 0x19, 0xfb, 0x7d, 0x8a, 0xea, 0xff, 0x19, + 0xae, 0xdd, 0xb7, 0x3b, 0x39, 0xf4, 0xd9, 0xad, 0xb1, 0xfe, 0xee, 0xee, 0xfe, 0x20, 0x44, 0xf4, + 0x7a, 0xb5, 0x55, 0xf1, 0xe2, 0xde, 0xca, 0x31, 0x93, 0x18, 0xd6, 0xb5, 0xc4, 0x4b, 0x55, 0x52, + 0x66, 0x11, 0x82, 0x5c, 0xdd, 0x8f, 0x5b, 0x7e, 0xf8, 0x46, 0x92, 0x4b, 0xc7, 0x74, 0xd5, 0x6b, + 0xe4, 0x90, 0xd5, 0x1f, 0x88, 0x08, 0x58, 0x36, 0x95, 0x12, 0x3b, 0x6a, 0x2f, 0xd7, 0x38, 0xa0, + 0x17, 0x29, 0xa3, 0x93, 0x7f, 0xc1, 0x31, 0x46, 0xd0, 0x67, 0xf1, 0x4b, 0x92, 0x55, 0x0f, 0x68, + 0xb9, 0xab, 0x82, 0x4d, 0x6b, 0x1f, 0xe1, 0x12, 0xd3, 0x4a, 0x9b, 0x6d, 0xa7, 0x6a, 0xd7, 0x82, + 0xcd, 0xa6, 0xb4, 0x8d, 0xbb, 0x69, 0x52, 0xcb, 0xe5, 0x93, 0xff, 0x9a, 0x6f, 0x5f, 0x82, 0x7a, + 0x7a, 0x77, 0xb5, 0xaf, 0x88, 0xdb, 0xbb, 0x76, 0xfe, 0xee, 0xbf, 0xaf, 0xeb, 0x82, 0x32, 0x4d, + 0xd3, 0xb8, 0xc7, 0xc1, 0x37, 0x49, 0x2b, 0xae, 0xc4, 0xdc, 0x11, 0xd2, 0x49, 0x78, 0x7c, 0xb5, + 0xa7, 0x7c, 0x11, 0xf5, 0x69, 0xbe, 0x3b, 0xb4, 0xd5, 0xb7, 0xa4, 0x97, 0xe1, 0xec, 0x2d, 0xab, + 0xce, 0xb3, 0x69, 0x20, 0xe4, 0x0d, 0xe1, 0x97, 0x63, 0xf8, 0x80, 0x43, 0x0b, 0xab, 0x6c, 0x89, + 0x2b, 0x47, 0x7c, 0x14, 0x9c, 0xb0, 0x69, 0xd9, 0x8b, 0x65, 0x34, 0x77, 0x46, 0x9b, 0xef, 0xf6, + 0x4b, 0xbf, 0x89, 0x36, 0x5f, 0x7e, 0x27, 0x88, 0x82, 0x92, 0xb9, 0x68, 0x2b, 0xbc, 0xf4, 0x83, + 0x15, 0x8f, 0x99, 0x7d, 0xf8, 0x98, 0xb1, 0x95, 0xad, 0xef, 0x88, 0x08, 0x02, 0xe1, 0x68, 0x04, + 0x86, 0x57, 0x53, 0x93, 0x13, 0x84, 0xfc, 0x4c, 0x75, 0xb4, 0xed, 0x2e, 0x21, 0xf2, 0x5f, 0x88, + 0x12, 0x12, 0x22, 0x5d, 0xf1, 0x75, 0xc4, 0x09, 0x04, 0xb1, 0x5b, 0xe2, 0xb1, 0x5b, 0xdf, 0xc4, + 0x88, 0x89, 0x1c, 0x2c, 0x7e, 0x93, 0xfc, 0x41, 0xc7, 0x6c, 0x47, 0xb1, 0x96, 0xe2, 0xb7, 0xc4, + 0x41, 0x0e, 0xed, 0x34, 0xfe, 0x20, 0xa4, 0x6d, 0x7f, 0x1f, 0x0b, 0x2a, 0x7b, 0x97, 0x6e, 0xef, + 0xd5, 0x7c, 0x21, 0x15, 0xde, 0xaa, 0xa2, 0xed, 0x57, 0xe3, 0x0a, 0x76, 0x63, 0x63, 0xa6, 0xee, + 0x5f, 0x77, 0xd5, 0x4d, 0x9c, 0x48, 0x44, 0x41, 0xfb, 0x33, 0xb3, 0x33, 0x76, 0xfa, 0xb5, 0xe2, + 0x41, 0x5d, 0xed, 0xcf, 0xf6, 0xd9, 0xae, 0xea, 0x2f, 0x78, 0x91, 0x82, 0xf5, 0x5c, 0x94, 0x17, + 0x12, 0xca, 0x28, 0x8d, 0x49, 0x5f, 0xc4, 0x82, 0x7c, 0x86, 0x34, 0x4c, 0x8d, 0x01, 0xa8, 0x43, + 0xbb, 0x7c, 0x13, 0x64, 0xc1, 0xec, 0xa7, 0x6c, 0xf2, 0xfd, 0xc4, 0x42, 0x36, 0x66, 0xa2, 0xcb, + 0xa0, 0x3b, 0x56, 0xed, 0x78, 0xc2, 0x1a, 0x82, 0x74, 0x99, 0xba, 0xe5, 0x32, 0x33, 0x5c, 0x29, + 0xad, 0x70, 0x9d, 0xef, 0x55, 0xfd, 0xef, 0x37, 0xf0, 0xb8, 0x87, 0xbb, 0x63, 0xa8, 0x3c, 0x56, + 0x2a, 0x5e, 0x6a, 0x26, 0xdb, 0xff, 0x0d, 0x9d, 0xb4, 0xa9, 0x65, 0x7a, 0x3f, 0xa3, 0xff, 0x09, + 0x6a, 0xb9, 0x77, 0x5c, 0xba, 0x69, 0x7c, 0x16, 0x5a, 0xb4, 0xb4, 0xdb, 0xd5, 0xb6, 0xdc, 0xf8, + 0x8b, 0xb4, 0xd3, 0x4e, 0x7d, 0xb5, 0xe4, 0xb5, 0x69, 0xfc, 0x5f, 0x49, 0x24, 0x8b, 0xa9, 0x45, + 0xe0, 0xa4, 0x96, 0xed, 0x27, 0xa6, 0xd3, 0x6a, 0xf0, 0x57, 0x0a, 0x6a, 0xfb, 0x76, 0xee, 0x36, + 0xb5, 0xa4, 0x92, 0x49, 0x0b, 0x9f, 0xf0, 0x47, 0x7d, 0x26, 0xf8, 0x24, 0xed, 0xa7, 0x2f, 0x82, + 0xc9, 0xbc, 0xbb, 0xbd, 0x6d, 0x2b, 0x52, 0xf8, 0xe9, 0xb1, 0xa4, 0x92, 0x69, 0xad, 0x3a, 0x7f, + 0x04, 0xd6, 0x8b, 0xc9, 0x9c, 0xbb, 0xe1, 0xf0, 0x47, 0xa7, 0x4e, 0x2f, 0x84, 0x6b, 0x6c, 0xde, + 0xeb, 0xdb, 0x6f, 0xc1, 0x37, 0x4d, 0xb5, 0xdd, 0x95, 0xc4, 0x16, 0x9d, 0x35, 0xda, 0xf6, 0x5d, + 0xdf, 0xc4, 0x52, 0x55, 0x4b, 0x69, 0xfc, 0x61, 0xad, 0xdb, 0xb6, 0x4c, 0xad, 0x35, 0xf3, 0xf6, + 0xaa, 0xe2, 0x03, 0xb3, 0xe6, 0x51, 0xd3, 0x4d, 0x1a, 0xc9, 0x79, 0x47, 0x31, 0x9f, 0xc3, 0x94, + 0xa6, 0xca, 0x1a, 0xa3, 0xff, 0x17, 0xa5, 0x33, 0xd3, 0x42, 0xb1, 0xb4, 0x1c, 0x48, 0x2b, 0x38, + 0xef, 0x55, 0xa1, 0xbb, 0xdf, 0x25, 0x11, 0x33, 0xe3, 0xae, 0x93, 0xa6, 0x1a, 0x9a, 0x76, 0xe8, + 0xef, 0x39, 0xaa, 0xc4, 0x82, 0x4e, 0xea, 0x8e, 0xf1, 0x02, 0x51, 0x2b, 0x89, 0x84, 0x44, 0x5d, + 0xb4, 0xdd, 0xde, 0xb9, 0x08, 0x38, 0x88, 0x26, 0x13, 0x8f, 0xa1, 0x7a, 0x43, 0xc8, 0x3e, 0xf8, + 0x24, 0x2b, 0xdd, 0xfb, 0x86, 0x42, 0x22, 0xb7, 0x4c, 0xbd, 0xcb, 0x62, 0x1e, 0x5b, 0xe2, 0x01, + 0x0e, 0xb6, 0xdf, 0xe4, 0xbb, 0x53, 0x67, 0x08, 0x0a, 0x25, 0xb5, 0x4e, 0x92, 0x4b, 0xe0, 0x8e, + 0xfa, 0xbf, 0x12, 0x24, 0x7d, 0xef, 0x4d, 0xbd, 0x56, 0xb8, 0x98, 0x2e, 0xdd, 0xdd, 0x55, 0x24, + 0xbb, 0x89, 0x82, 0x3a, 0xdd, 0x27, 0xf1, 0x22, 0x88, 0xf0, 0xea, 0xaa, 0xbf, 0x18, 0x7a, 0xd5, + 0x98, 0x8e, 0x35, 0xb3, 0x4a, 0x98, 0x5f, 0xe9, 0xd1, 0xe2, 0x21, 0x4f, 0x2e, 0x23, 0x49, 0x5f, + 0xb6, 0xdd, 0x29, 0x20, 0xcb, 0xff, 0x04, 0xc5, 0x92, 0x0d, 0x46, 0x9b, 0x0d, 0x9a, 0x4f, 0xf2, + 0x92, 0xb5, 0xc4, 0x48, 0x54, 0x96, 0x87, 0xe0, 0xab, 0x55, 0x55, 0x13, 0x82, 0xcd, 0x3a, 0x6f, + 0xf0, 0xa6, 0x13, 0x4d, 0x69, 0x9b, 0xe8, 0xd9, 0x96, 0x27, 0x72, 0x0d, 0x75, 0xef, 0x89, 0x32, + 0x4f, 0xc9, 0xf7, 0x88, 0xf1, 0x01, 0x71, 0x1b, 0x8a, 0xee, 0xda, 0x6f, 0xae, 0x58, 0x1a, 0x9f, + 0xe2, 0x04, 0xcb, 0xf6, 0xf5, 0xf1, 0x3d, 0x5b, 0x6b, 0x7f, 0x0a, 0x10, 0x9a, 0xde, 0xab, 0x74, + 0xeb, 0x7c, 0xcc, 0x45, 0xf2, 0x66, 0xf9, 0xf8, 0x40, 0xaf, 0x4d, 0xb4, 0xde, 0xda, 0x7b, 0x7e, + 0x08, 0x7a, 0x6f, 0x02, 0x2f, 0x05, 0xa4, 0xa6, 0x91, 0x34, 0xfe, 0x6f, 0xef, 0x8b, 0xe6, 0xcb, + 0x76, 0xfe, 0xb5, 0x5c, 0x11, 0x1d, 0xef, 0x37, 0x2b, 0xbd, 0x53, 0xf8, 0x70, 0xd4, 0x92, 0xab, + 0x6d, 0xb6, 0xdf, 0xf8, 0xed, 0x49, 0x9b, 0x74, 0x92, 0x88, 0xb9, 0xf8, 0x25, 0x9f, 0x3d, 0xf4, + 0xf0, 0xf8, 0x2f, 0x23, 0x6a, 0x58, 0xb1, 0xb1, 0x2f, 0x63, 0x7e, 0x9a, 0xdb, 0x1d, 0x44, 0x72, + 0x8f, 0xf1, 0xc5, 0x71, 0x05, 0xa9, 0x27, 0x34, 0x5f, 0x7a, 0x69, 0x37, 0xe0, 0xb8, 0xe7, 0x84, + 0x56, 0xec, 0x1b, 0x63, 0x89, 0x85, 0xf5, 0xff, 0xe1, 0x48, 0xac, 0xf8, 0xf7, 0x29, 0xa9, 0x38, + 0xaf, 0x7a, 0xba, 0x13, 0xf8, 0x93, 0x71, 0xba, 0xaf, 0xc5, 0x73, 0x31, 0xe6, 0xfe, 0x09, 0xbb, + 0xbe, 0xa9, 0xbd, 0x44, 0xc2, 0x35, 0x2f, 0xef, 0x43, 0x99, 0x8a, 0x3e, 0x24, 0x58, 0x89, 0x32, + 0xda, 0x71, 0x85, 0xfc, 0x28, 0x25, 0xde, 0x52, 0x0d, 0xca, 0x41, 0xb4, 0xec, 0xa4, 0x1b, 0xcf, + 0x96, 0xbf, 0xc4, 0xc6, 0x45, 0x6e, 0xef, 0x6e, 0xee, 0xef, 0x2e, 0xc6, 0xaa, 0x4d, 0xbd, 0xbe, + 0x24, 0x7f, 0x55, 0x7b, 0xcf, 0xdb, 0xf8, 0x81, 0xd7, 0x77, 0x15, 0xbb, 0xf4, 0xcd, 0xfe, 0x24, + 0x45, 0xe9, 0xdd, 0x8d, 0xaf, 0x12, 0x0a, 0x35, 0x53, 0x74, 0xf3, 0xef, 0x08, 0x82, 0xad, 0xd3, + 0xbe, 0xd2, 0x44, 0xd8, 0x87, 0xbf, 0xc6, 0x1b, 0x55, 0x49, 0x27, 0xb7, 0x62, 0x8b, 0x7b, 0xf8, + 0xbb, 0x56, 0x37, 0x51, 0x7a, 0xf1, 0x00, 0x94, 0xa3, 0xea, 0xef, 0xab, 0x33, 0x36, 0xe2, 0x21, + 0x4a, 0x88, 0xc2, 0x35, 0x45, 0x59, 0x53, 0xd2, 0x5d, 0x22, 0x7d, 0x98, 0x93, 0x71, 0x30, 0xa1, + 0xc7, 0xa5, 0x1e, 0x68, 0x4f, 0xa9, 0x94, 0x3f, 0x42, 0xf9, 0x34, 0x10, 0x63, 0xac, 0x23, 0xcb, + 0xce, 0xf5, 0x91, 0xdb, 0xe3, 0x2d, 0xe3, 0xa7, 0xa9, 0x7d, 0x93, 0x32, 0xbd, 0x9e, 0x7f, 0x0a, + 0x63, 0x58, 0xd2, 0x7c, 0x90, 0xb4, 0xcb, 0x29, 0x54, 0x46, 0xd6, 0x24, 0xef, 0xc4, 0x89, 0x11, + 0x5a, 0xd8, 0x25, 0x9a, 0x1e, 0x10, 0x24, 0x98, 0xbb, 0xde, 0xb5, 0xf8, 0xed, 0x6d, 0x8b, 0xda, + 0x57, 0x7f, 0x11, 0x04, 0xe5, 0x6f, 0x25, 0x16, 0x77, 0xf9, 0x36, 0x94, 0xd9, 0xe1, 0x02, 0xea, + 0xa4, 0xe5, 0xb4, 0xec, 0xa4, 0x9b, 0x5e, 0xc9, 0x7b, 0xf8, 0x25, 0x14, 0xf7, 0x8d, 0x31, 0x64, + 0x20, 0x3f, 0xbe, 0x1b, 0x8d, 0xae, 0xde, 0x3b, 0x74, 0x59, 0x3c, 0x6f, 0x5d, 0x61, 0xef, 0xff, + 0x04, 0x07, 0xd3, 0x68, 0xda, 0xd6, 0x9d, 0x37, 0x5c, 0xfd, 0xbf, 0xf1, 0xd5, 0x37, 0xb6, 0xdf, + 0x4e, 0x93, 0x7f, 0x44, 0xca, 0xf9, 0x77, 0xb7, 0xe3, 0x0a, 0xa7, 0xed, 0xed, 0xa7, 0xe5, 0xc9, + 0xb7, 0x4b, 0xc5, 0x92, 0xa9, 0x77, 0x75, 0xc8, 0x54, 0x92, 0x69, 0xaf, 0x04, 0xf4, 0x97, 0x3e, + 0x78, 0xab, 0x92, 0x9d, 0x3f, 0x8a, 0xc9, 0xb4, 0x8b, 0xe3, 0xfc, 0x79, 0x13, 0x9c, 0x82, 0xf5, + 0xa5, 0x4d, 0x34, 0xbc, 0x66, 0x9a, 0x5a, 0x46, 0xcb, 0x6f, 0x75, 0xcd, 0xbe, 0x3e, 0xad, 0xdb, + 0x26, 0x66, 0xda, 0x6d, 0xb5, 0xe0, 0x96, 0xef, 0xc9, 0xcf, 0xbb, 0xd7, 0x04, 0xf6, 0xed, 0xe4, + 0xed, 0xc7, 0xdf, 0x0a, 0x19, 0x68, 0xb9, 0x18, 0x58, 0xdd, 0x03, 0xe1, 0x72, 0xa1, 0x7a, 0xa8, + 0x58, 0x5e, 0x23, 0xe0, 0x84, 0xf7, 0x3f, 0xfb, 0xe4, 0x2b, 0xbf, 0x63, 0xe2, 0x02, 0x9c, 0x72, + 0xad, 0x8c, 0x65, 0x53, 0x52, 0xad, 0xec, 0x7e, 0xa5, 0xce, 0xf8, 0x25, 0xe5, 0x50, 0xad, 0x8d, + 0x07, 0xd5, 0xfb, 0xe1, 0x1d, 0x55, 0x5b, 0x36, 0x2b, 0x3a, 0x85, 0x9f, 0xc4, 0x8b, 0xbe, 0xb5, + 0xaf, 0x82, 0x7d, 0x24, 0xe8, 0x92, 0x36, 0x7d, 0xc4, 0x89, 0x15, 0xac, 0xea, 0x25, 0x63, 0xf0, + 0x57, 0xac, 0x6a, 0x47, 0xb7, 0x2e, 0x3d, 0xf8, 0xef, 0xe2, 0x41, 0x28, 0x8d, 0xdb, 0x27, 0xff, + 0x54, 0x4c, 0x5d, 0x8f, 0x5a, 0xd2, 0xc4, 0xc2, 0x67, 0x55, 0xd4, 0x8c, 0x21, 0xf8, 0x46, 0x27, + 0x76, 0x9a, 0x95, 0x5f, 0x08, 0x89, 0xae, 0x9b, 0x69, 0xb6, 0x5c, 0x2d, 0xe1, 0x10, 0x80, 0x88, + 0xba, 0xa9, 0xb9, 0xfc, 0x7f, 0xc1, 0x21, 0x07, 0x16, 0xb2, 0xf5, 0xee, 0x22, 0x0a, 0xca, 0xd1, + 0xb2, 0xad, 0x28, 0xba, 0xea, 0x8b, 0xb8, 0x88, 0x26, 0x8a, 0xe7, 0xda, 0x73, 0x10, 0x7d, 0xc4, + 0xc6, 0x1d, 0xa2, 0x60, 0x67, 0xd3, 0x2a, 0xde, 0xb5, 0x6c, 0x5c, 0x9d, 0xb9, 0xf1, 0x23, 0xea, + 0x30, 0xd8, 0xae, 0xfa, 0xaa, 0xb2, 0x24, 0x3f, 0x25, 0x57, 0xf0, 0x4f, 0x55, 0x5a, 0xdd, 0x06, + 0xff, 0x29, 0x23, 0x0a, 0xbf, 0x12, 0x0a, 0x65, 0xa7, 0xa6, 0x56, 0x33, 0x88, 0x17, 0xdd, 0xf3, + 0x09, 0xe5, 0xcc, 0x44, 0xc4, 0xad, 0x57, 0x25, 0x56, 0xbe, 0x3a, 0x90, 0xca, 0xdc, 0xa6, 0xde, + 0xeb, 0x29, 0xf8, 0x92, 0x91, 0x6a, 0xbe, 0x34, 0x45, 0xb4, 0xba, 0xb2, 0x1a, 0x56, 0x55, 0xdf, + 0x6a, 0x89, 0x76, 0xd7, 0x1a, 0xd3, 0x4b, 0xfc, 0x14, 0x97, 0x57, 0xe5, 0xe7, 0x94, 0xce, 0x5f, + 0x15, 0xdd, 0x4a, 0xda, 0x34, 0x36, 0x37, 0xc2, 0x5b, 0xa5, 0xaa, 0x75, 0xcb, 0x6d, 0x7f, 0x12, + 0x55, 0x21, 0x05, 0x96, 0x62, 0x0c, 0x84, 0x5f, 0xdd, 0x6b, 0xf0, 0x85, 0xbd, 0x2a, 0x74, 0xe7, + 0x6b, 0xcf, 0x82, 0x9d, 0xdd, 0xbd, 0xa6, 0xf3, 0xe1, 0x36, 0x5c, 0xf8, 0x25, 0xcb, 0x86, 0xce, + 0xda, 0x7d, 0x7c, 0x96, 0x9b, 0x69, 0x7c, 0x5c, 0x9d, 0x34, 0x95, 0x0c, 0xec, 0xb7, 0x5f, 0x82, + 0xca, 0x65, 0xed, 0x7a, 0x49, 0x39, 0x5a, 0xb5, 0x57, 0xc2, 0x74, 0x92, 0xdd, 0xff, 0x26, 0xdd, + 0x7c, 0x3b, 0xc9, 0xed, 0xcb, 0x8d, 0xac, 0xed, 0x2f, 0x87, 0x71, 0x5b, 0x67, 0xf3, 0xf6, 0xe9, + 0xf8, 0x52, 0xdb, 0x5e, 0x4c, 0x72, 0xb7, 0x33, 0x5d, 0x76, 0x36, 0x1e, 0x0a, 0xe5, 0xc6, 0x3b, + 0x63, 0x1f, 0xab, 0xe9, 0x8f, 0x55, 0x0a, 0x38, 0xbf, 0x84, 0x79, 0xe2, 0x04, 0x8c, 0x26, 0x8c, + 0xe4, 0x32, 0x84, 0xbd, 0x89, 0x6f, 0x6a, 0x5f, 0x82, 0xe3, 0xaa, 0x7a, 0xd4, 0xe4, 0x7b, 0xe0, + 0x8f, 0x6d, 0xab, 0xfc, 0x14, 0x9d, 0x38, 0xd7, 0xa4, 0x8a, 0x3b, 0x53, 0x5b, 0xf1, 0x10, 0x59, + 0x71, 0x5b, 0xe4, 0xf5, 0xe5, 0xbf, 0xfe, 0x51, 0x1b, 0xba, 0xe4, 0x16, 0x56, 0x65, 0xdb, 0xf0, + 0x5b, 0x55, 0x5b, 0x9f, 0x5a, 0xfb, 0xe1, 0x49, 0x31, 0x2c, 0x99, 0x43, 0xbd, 0xae, 0x5e, 0xe5, + 0xb8, 0x91, 0x21, 0x29, 0xbc, 0xcd, 0xf5, 0x7c, 0x33, 0x09, 0x68, 0xe2, 0x16, 0x15, 0x7c, 0x4c, + 0x14, 0xc6, 0x3d, 0x16, 0xed, 0xb1, 0x29, 0x20, 0xd1, 0x91, 0x7a, 0xe2, 0x21, 0x23, 0x52, 0xbe, + 0xab, 0x88, 0x12, 0x10, 0x8e, 0xf5, 0x3a, 0x6c, 0xd3, 0x75, 0x57, 0x7a, 0xe1, 0x11, 0x02, 0x66, + 0xe9, 0xa5, 0x5a, 0xf0, 0x84, 0x17, 0x49, 0x9e, 0xb6, 0x33, 0x76, 0xe1, 0x01, 0x22, 0xea, 0xac, + 0xf2, 0x2e, 0xa2, 0xe2, 0x6c, 0x62, 0x21, 0x42, 0xe4, 0xda, 0x56, 0x67, 0xd6, 0xf6, 0xeb, 0x9b, + 0x96, 0x62, 0x7e, 0x5b, 0x88, 0x8f, 0x85, 0x28, 0x26, 0xa7, 0x88, 0xe2, 0x7a, 0xbd, 0xf8, 0x90, + 0x55, 0x63, 0x00, 0xf5, 0xd6, 0x64, 0x60, 0xde, 0x06, 0x34, 0xac, 0x63, 0xb7, 0xc1, 0x59, 0x57, + 0x4a, 0x2f, 0x3b, 0x8c, 0xe7, 0x1e, 0x5e, 0xa6, 0xf5, 0x49, 0x5a, 0xb1, 0x22, 0x24, 0x87, 0x52, + 0xe5, 0xfc, 0x41, 0x15, 0x2d, 0x3b, 0x19, 0xff, 0x9a, 0xca, 0x49, 0xfc, 0x97, 0xb6, 0xdf, 0x8a, + 0x3d, 0xed, 0x5e, 0xfe, 0x2a, 0x35, 0x97, 0x4a, 0x89, 0xb7, 0x45, 0x88, 0x8a, 0xdc, 0xd9, 0xad, + 0x27, 0xe2, 0x06, 0x58, 0xed, 0x26, 0x95, 0xf8, 0xdf, 0xe1, 0xe4, 0xa1, 0x33, 0x89, 0x16, 0x21, + 0x1e, 0xef, 0x6e, 0xb8, 0xad, 0x0c, 0xf0, 0x1f, 0x32, 0xe7, 0xbe, 0xfc, 0x40, 0x5c, 0xd7, 0xbd, + 0xee, 0x2d, 0x0d, 0x35, 0x26, 0x9b, 0xff, 0x85, 0xce, 0x9b, 0x74, 0xa7, 0xe9, 0x6a, 0x99, 0xe2, + 0xf4, 0xbf, 0xc7, 0xed, 0xdb, 0xd3, 0x76, 0x32, 0xb2, 0xc6, 0xc6, 0x3c, 0x7e, 0xd2, 0x53, 0xe7, + 0x49, 0x26, 0xeb, 0x9a, 0x96, 0x97, 0x8f, 0xda, 0xb9, 0xf4, 0xfb, 0x5d, 0xad, 0xfe, 0x09, 0xba, + 0xb5, 0x2b, 0x1e, 0x2f, 0x85, 0xf3, 0x62, 0xdd, 0xaa, 0xae, 0x7e, 0xff, 0xe0, 0xc3, 0x4d, 0xb9, + 0xa3, 0xa2, 0xc2, 0xb3, 0x7f, 0xf9, 0x74, 0x98, 0xc8, 0xd5, 0xc9, 0xb7, 0x6f, 0xc9, 0xa7, 0x4f, + 0xcb, 0x4d, 0xb4, 0xfe, 0x4a, 0x49, 0x24, 0x5c, 0x5c, 0x55, 0xa6, 0x9a, 0xda, 0xb5, 0xe1, 0x7d, + 0x38, 0xed, 0x13, 0x8f, 0x59, 0x3a, 0x73, 0xfc, 0x40, 0x48, 0x50, 0xdb, 0x46, 0x7e, 0x7f, 0xe1, + 0xc6, 0xa1, 0x35, 0x75, 0x78, 0x27, 0x12, 0x46, 0x3a, 0xaa, 0xaf, 0xfc, 0x48, 0xed, 0xdc, 0xac, + 0x4b, 0x8b, 0xca, 0x41, 0x2e, 0x57, 0xc4, 0xbc, 0x49, 0x2f, 0x13, 0x65, 0x99, 0x8f, 0xc5, 0x19, + 0x49, 0xd7, 0x51, 0xcb, 0xbf, 0x88, 0x18, 0x6b, 0x23, 0x0e, 0xee, 0x46, 0x04, 0x79, 0xdc, 0x64, + 0x2e, 0x0f, 0xc2, 0x16, 0xd8, 0x70, 0xed, 0x19, 0x78, 0xb1, 0xbd, 0x8a, 0x23, 0xde, 0xd9, 0xfe, + 0x13, 0x2d, 0xde, 0xb4, 0x7c, 0x48, 0x91, 0x5a, 0x54, 0xe9, 0xda, 0xe2, 0x42, 0x92, 0x6b, 0x6f, + 0x63, 0xcd, 0x9d, 0x1d, 0x56, 0x8c, 0x8a, 0xb2, 0xde, 0x24, 0x12, 0xec, 0x57, 0xa9, 0x37, 0xef, + 0x89, 0x23, 0x6c, 0x4c, 0xdf, 0x4c, 0xcc, 0x62, 0x23, 0x24, 0xaa, 0x3a, 0x99, 0xc8, 0xe2, 0x75, + 0x51, 0xab, 0x79, 0xf3, 0x86, 0x88, 0x40, 0xa0, 0xa2, 0x7f, 0xfe, 0xeb, 0x17, 0x89, 0x35, 0x9e, + 0xb8, 0x90, 0x80, 0xf3, 0xba, 0x9e, 0x52, 0x27, 0xcb, 0xd9, 0xfb, 0x6a, 0x3d, 0x8f, 0x0a, 0x45, + 0x63, 0xea, 0xd9, 0xff, 0x99, 0x85, 0x3f, 0xc2, 0xf5, 0x38, 0xd0, 0xf3, 0x09, 0x92, 0xf1, 0x3e, + 0x77, 0xb6, 0x1a, 0x45, 0x20, 0x83, 0x24, 0x99, 0xdd, 0xfe, 0x6d, 0xb1, 0x47, 0xf3, 0x67, 0x29, + 0xa9, 0xcf, 0x9b, 0xbc, 0x76, 0xf0, 0x50, 0x14, 0xea, 0x27, 0x0d, 0xbc, 0xe1, 0x48, 0x74, 0x96, + 0xaa, 0x4c, 0x2f, 0xc5, 0xdd, 0x4a, 0x9f, 0x05, 0x32, 0xb0, 0x07, 0xee, 0xaf, 0xcc, 0xcd, 0x35, + 0x17, 0x51, 0x7f, 0x7c, 0x15, 0xed, 0x4d, 0xd8, 0xdd, 0xf5, 0x5f, 0xdc, 0x48, 0x92, 0x72, 0x7f, + 0x82, 0xba, 0xd5, 0x6a, 0xa9, 0xcd, 0x09, 0x20, 0x8f, 0xae, 0x88, 0xfe, 0x20, 0x16, 0xd5, 0x4d, + 0x4f, 0x55, 0xae, 0x22, 0x6a, 0xaf, 0xc4, 0x71, 0x02, 0x09, 0x5d, 0x17, 0x13, 0xf0, 0x5a, 0x22, + 0xef, 0x71, 0x5b, 0xbd, 0x71, 0x3f, 0x93, 0xa4, 0xab, 0x10, 0x1a, 0xa1, 0xb9, 0x12, 0xda, 0xf1, + 0x38, 0x7f, 0x84, 0x0e, 0x91, 0x7a, 0x4e, 0xe7, 0xcc, 0xd9, 0x76, 0x89, 0xbf, 0x84, 0xf9, 0x3a, + 0x67, 0xd5, 0x6b, 0xe0, 0x8e, 0xd4, 0xd8, 0x6c, 0x3b, 0x7c, 0x15, 0x5b, 0x4f, 0xb5, 0x49, 0xdb, + 0xbe, 0x5f, 0x05, 0x5d, 0x26, 0xf4, 0x9b, 0x55, 0xf2, 0xae, 0x10, 0x93, 0x7a, 0xd5, 0xad, 0xa6, + 0xbc, 0x5c, 0x9a, 0x9c, 0x57, 0x56, 0x9a, 0xf1, 0xda, 0x49, 0x27, 0xcf, 0x13, 0xe3, 0xf6, 0xaa, + 0xfc, 0x7c, 0xed, 0xe8, 0xe6, 0x61, 0x8c, 0x69, 0x5e, 0xce, 0x94, 0x6d, 0x7c, 0x10, 0x67, 0xc4, + 0xfd, 0xb9, 0x27, 0xea, 0xac, 0xa6, 0x87, 0xf8, 0x22, 0xb1, 0x8d, 0xd4, 0xc7, 0x07, 0x17, 0xc7, + 0x74, 0xed, 0x9f, 0x75, 0x77, 0x6f, 0xc7, 0x55, 0xed, 0xb7, 0x9b, 0xe6, 0xcf, 0x85, 0x23, 0xd4, + 0x83, 0x59, 0x46, 0x34, 0x7a, 0xb8, 0x35, 0x95, 0xb1, 0x8d, 0x0d, 0x24, 0xbb, 0x65, 0xd9, 0x7c, + 0x56, 0x4d, 0x6a, 0xdb, 0x6d, 0x8d, 0xfc, 0x55, 0x39, 0xb5, 0xa6, 0x9a, 0xaf, 0x82, 0x71, 0x14, + 0xa1, 0x23, 0x9e, 0xee, 0x51, 0x25, 0x0a, 0x2f, 0xb9, 0x61, 0xbb, 0x57, 0xe2, 0x55, 0xfe, 0xaf, + 0xf1, 0xc2, 0x5b, 0xb1, 0xb3, 0xd9, 0xab, 0xb1, 0xbf, 0xc9, 0x55, 0xa7, 0xe1, 0x43, 0x55, 0xd6, + 0x3b, 0xdd, 0xe2, 0xbc, 0x8a, 0x92, 0x24, 0x48, 0x2c, 0xf8, 0xc3, 0x5d, 0xdc, 0xfd, 0xa9, 0x61, + 0xd5, 0xbb, 0xfd, 0x2a, 0x11, 0xf3, 0x51, 0x34, 0x3d, 0x3f, 0xc1, 0x6c, 0x74, 0x4e, 0xc7, 0xb5, + 0x64, 0xad, 0x77, 0x13, 0x18, 0x56, 0x47, 0x83, 0xf7, 0x63, 0x22, 0x19, 0xb8, 0x77, 0x01, 0x39, + 0x87, 0x31, 0x5b, 0xbb, 0x33, 0x88, 0x13, 0xbb, 0xd3, 0xcf, 0x11, 0x0a, 0x56, 0x32, 0xd0, 0xff, + 0x17, 0x52, 0xfa, 0x78, 0xe5, 0x15, 0xe0, 0xd8, 0xd1, 0x78, 0xbf, 0x7c, 0x65, 0x8f, 0x69, 0x90, + 0xb8, 0xba, 0x62, 0xe4, 0xe2, 0x98, 0x8f, 0x13, 0xe5, 0xf3, 0x31, 0x78, 0x61, 0x41, 0x12, 0x8c, + 0x76, 0x4b, 0xab, 0x32, 0x41, 0x14, 0x98, 0xd4, 0x56, 0xd9, 0x60, 0xa3, 0x15, 0xbb, 0x91, 0x4e, + 0x19, 0x08, 0x82, 0xc2, 0x09, 0xf6, 0x75, 0x9d, 0x6a, 0xa2, 0xea, 0xaf, 0xc4, 0x09, 0x19, 0xa8, + 0x5a, 0x83, 0x57, 0x7c, 0xbc, 0x5c, 0x90, 0x2f, 0xb1, 0x8b, 0xf8, 0x65, 0xd9, 0x91, 0xfc, 0x48, + 0x23, 0xde, 0xef, 0xc4, 0x84, 0x41, 0x51, 0xd5, 0x53, 0x0a, 0xd5, 0x55, 0x98, 0xcc, 0xd2, 0x2f, + 0xf6, 0x1e, 0x70, 0x13, 0xb6, 0xfb, 0xfb, 0xc4, 0xf0, 0xd1, 0x22, 0x2c, 0xe1, 0x3b, 0xef, 0x25, + 0xeb, 0xff, 0xfb, 0xfc, 0x46, 0x7f, 0xd4, 0x9d, 0x9f, 0x88, 0x21, 0x2a, 0xab, 0xe3, 0xf2, 0x7a, + 0xa3, 0xcb, 0x65, 0xb3, 0x79, 0xaf, 0x82, 0xac, 0x90, 0x3b, 0x32, 0xda, 0xad, 0xb2, 0x65, 0xd9, + 0xc4, 0xc1, 0x19, 0x1e, 0x5d, 0xbf, 0x12, 0x24, 0x27, 0xa9, 0xff, 0x9b, 0x18, 0x3c, 0x48, 0x91, + 0x77, 0xb5, 0xcf, 0x87, 0xcc, 0x48, 0x91, 0x7b, 0xab, 0x37, 0xb3, 0xe2, 0x42, 0x02, 0x6b, 0x5a, + 0xb7, 0xf8, 0xce, 0xd9, 0x72, 0xa9, 0x5f, 0x7c, 0xfd, 0xdf, 0xf1, 0x22, 0x01, 0x71, 0x93, 0x7e, + 0xb2, 0x67, 0x71, 0x16, 0x71, 0x5b, 0xfe, 0x0a, 0x8f, 0x63, 0x5b, 0x19, 0xb2, 0x56, 0x6d, 0xd5, + 0xdf, 0x62, 0x9f, 0xa7, 0xc4, 0x0c, 0x2d, 0x53, 0xa6, 0x33, 0x11, 0xb2, 0x74, 0xd7, 0x9f, 0xf8, + 0x80, 0xa1, 0xab, 0x94, 0x41, 0xaa, 0x93, 0xf1, 0xd3, 0x77, 0xba, 0x06, 0xe7, 0x4f, 0x82, 0x72, + 0xd5, 0x19, 0x29, 0x4e, 0x9e, 0x5f, 0x08, 0x75, 0x46, 0x8e, 0xaf, 0xd5, 0xfc, 0xd7, 0xb7, 0xf3, + 0x4d, 0x5a, 0x7f, 0x05, 0x5b, 0x8a, 0xee, 0xb3, 0xf6, 0xaa, 0x68, 0x79, 0x63, 0x1f, 0x2c, 0xff, + 0x5d, 0x70, 0x59, 0x4d, 0x26, 0x9a, 0x9f, 0x13, 0xdf, 0xaf, 0xd6, 0xb8, 0xbe, 0x36, 0x95, 0xae, + 0xb4, 0xd9, 0x47, 0xab, 0x69, 0x52, 0x52, 0x74, 0xdf, 0xfe, 0x38, 0x95, 0x2b, 0x6a, 0xd4, 0x65, + 0x7a, 0x6f, 0xf1, 0xc5, 0x97, 0x76, 0xf4, 0xd3, 0x4f, 0xf0, 0xbd, 0x5b, 0xb7, 0x4a, 0x92, 0xad, + 0xb6, 0xff, 0xc9, 0xa5, 0x7f, 0x25, 0xbd, 0xa6, 0xbc, 0x9d, 0x93, 0xac, 0x40, 0x2f, 0x10, 0x56, + 0x20, 0x43, 0xee, 0x3a, 0x61, 0xa7, 0xb0, 0x7a, 0xe5, 0x82, 0xff, 0x82, 0xa1, 0x6c, 0x65, 0xa3, + 0x1e, 0x56, 0x99, 0x41, 0x18, 0x72, 0xe8, 0x7a, 0x1a, 0x6c, 0xf8, 0x40, 0x42, 0xe5, 0x09, 0x34, + 0x27, 0x2a, 0x8c, 0xb8, 0x5c, 0xf0, 0x4c, 0x77, 0xa5, 0x9d, 0x97, 0xad, 0xfe, 0x13, 0x2c, 0xcc, + 0x50, 0x92, 0x5f, 0x89, 0x09, 0x71, 0xe4, 0xc4, 0xbc, 0x56, 0xc5, 0xe3, 0x05, 0x3b, 0xb8, 0xad, + 0xdf, 0x07, 0x39, 0xc2, 0xf3, 0x9e, 0xf6, 0xfa, 0x59, 0x6d, 0xfc, 0x14, 0xe2, 0x61, 0x57, 0xb3, + 0x7d, 0xdb, 0xfb, 0x89, 0x82, 0xa1, 0x29, 0xa5, 0x39, 0x23, 0x31, 0xf9, 0x21, 0xef, 0x0c, 0x8c, + 0x38, 0x70, 0xd1, 0x05, 0xbb, 0x31, 0x72, 0xa2, 0xd6, 0x86, 0x9a, 0x64, 0xf4, 0xf1, 0x30, 0x9e, + 0x9b, 0xba, 0xaa, 0xaf, 0x8c, 0xeb, 0x23, 0x11, 0x4c, 0xf1, 0x72, 0x30, 0xac, 0x79, 0x12, 0x78, + 0x47, 0x89, 0x73, 0x45, 0x59, 0x52, 0x30, 0x77, 0xf8, 0xfb, 0x99, 0x3f, 0xd4, 0xbc, 0xb3, 0x0b, + 0x06, 0x82, 0xe5, 0xf2, 0x67, 0xe3, 0x25, 0x9a, 0x8b, 0x89, 0xb0, 0xa1, 0xc3, 0x83, 0x18, 0x67, + 0xc5, 0xea, 0xff, 0x7f, 0x13, 0x0a, 0x73, 0x45, 0xb7, 0x29, 0x9e, 0x6a, 0xe5, 0x13, 0x28, 0x59, + 0x48, 0x35, 0x94, 0xf5, 0xc4, 0x42, 0x64, 0x9f, 0x2d, 0xb6, 0xb6, 0xf1, 0x01, 0x91, 0x95, 0x4d, + 0x6a, 0x4f, 0x27, 0x4c, 0x9d, 0x0c, 0xef, 0x7f, 0x63, 0xe2, 0x02, 0x19, 0x98, 0xdc, 0x5d, 0xd6, + 0xb5, 0xf1, 0x76, 0x33, 0x30, 0x9b, 0x98, 0x55, 0xaf, 0x89, 0x82, 0x3a, 0xd6, 0xde, 0x24, 0x23, + 0x4e, 0x46, 0x75, 0xae, 0xaa, 0xbc, 0x48, 0x27, 0x3c, 0xd4, 0xdb, 0xbf, 0xb8, 0x91, 0x21, 0x23, + 0x73, 0xa8, 0x55, 0xf8, 0x92, 0x56, 0xab, 0xc4, 0x85, 0x3a, 0xa7, 0x75, 0xe9, 0x13, 0x0b, 0x89, + 0x77, 0xf9, 0x49, 0x6d, 0x26, 0xf1, 0x36, 0x64, 0xdf, 0xf3, 0x75, 0x17, 0xf0, 0x56, 0x5a, 0x4b, + 0x43, 0x37, 0x0d, 0x54, 0xd6, 0x4c, 0xf7, 0x88, 0x04, 0x65, 0x36, 0xe9, 0x77, 0x13, 0x29, 0x2f, + 0x15, 0xc3, 0x4e, 0x11, 0xa8, 0xb2, 0x5f, 0xd7, 0xaf, 0xb7, 0x13, 0x12, 0x5a, 0xdb, 0x93, 0xd7, + 0xc1, 0x41, 0xf2, 0xe1, 0x72, 0xaf, 0x97, 0xc2, 0x06, 0xad, 0x69, 0xbd, 0x8c, 0x7a, 0x9b, 0xff, + 0x8d, 0xcb, 0xdb, 0x75, 0x72, 0xb5, 0x15, 0x4b, 0x1a, 0x97, 0xc3, 0x93, 0x88, 0xea, 0x54, 0xf7, + 0x88, 0x69, 0xfc, 0x40, 0x6c, 0x8e, 0x53, 0x36, 0x63, 0xc9, 0x97, 0x1e, 0xef, 0xfc, 0x16, 0x8b, + 0xab, 0xd3, 0x6d, 0x36, 0xca, 0xdf, 0x0a, 0x1a, 0x4d, 0x6d, 0xdb, 0x5f, 0x5a, 0x74, 0xde, 0xfa, + 0xf9, 0x65, 0x62, 0x56, 0x3e, 0x2a, 0xdd, 0x7e, 0xda, 0xf8, 0xba, 0x32, 0x65, 0xa4, 0x92, 0x69, + 0xa8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x59, 0x2c, 0xb0, 0x36, 0xbc, 0x22, 0x11, 0x19, 0x4c, + 0x65, 0xb1, 0xd6, 0x81, 0x8f, 0x28, 0xf2, 0xaf, 0x2a, 0xf2, 0x8f, 0x28, 0xf2, 0xaf, 0x2a, 0xf7, + 0x86, 0x63, 0xc9, 0x8f, 0xa4, 0xfe, 0x13, 0x34, 0x2a, 0xfc, 0x86, 0x2b, 0x1e, 0xb8, 0xbe, 0xd3, + 0x56, 0x9a, 0x6b, 0xd7, 0xbe, 0x7f, 0xbe, 0x9a, 0x62, 0xac, 0x55, 0xf8, 0xd1, 0x43, 0x69, 0xb5, + 0x74, 0xd3, 0x4d, 0x33, 0xb0, 0x86, 0x76, 0x74, 0xd3, 0x4d, 0x33, 0xa2, 0x3f, 0x55, 0xa8, 0xce, + 0x40, 0x9e, 0x31, 0x4c, 0xbd, 0x11, 0x32, 0x5c, 0x14, 0x17, 0x1a, 0xf2, 0xaf, 0x6a, 0xbd, 0xa6, + 0x47, 0xc4, 0x1a, 0x6c, 0x36, 0x2c, 0xac, 0x48, 0x26, 0x26, 0xd3, 0x49, 0x25, 0x8e, 0x37, 0xcb, + 0x49, 0x2f, 0x88, 0x7d, 0x24, 0x84, 0x71, 0x1d, 0x24, 0xb4, 0x92, 0x13, 0xc1, 0x41, 0x10, 0x34, + 0x0d, 0xa6, 0x90, 0x34, 0x0d, 0xa6, 0x8b, 0x01, 0x7e, 0x0c, 0x0d, 0x7b, 0x8c, 0xfe, 0x5f, 0xdf, + 0x56, 0xad, 0x48, 0xc4, 0x69, 0x8b, 0x62, 0xdf, 0x82, 0x09, 0x48, 0x37, 0x40, 0xd1, 0xa3, 0x7d, + 0x29, 0xcf, 0x86, 0xca, 0x98, 0xfe, 0x2d, 0x8b, 0x7e, 0x14, 0xa4, 0x93, 0xba, 0x49, 0x56, 0x1a, + 0x39, 0xeb, 0x68, 0x98, 0xed, 0x2a, 0x7c, 0x2a, 0x74, 0x0c, 0x6e, 0x84, 0xcf, 0x35, 0x12, 0xda, + 0x9a, 0xa7, 0x7b, 0x9f, 0xf1, 0x21, 0xdb, 0x33, 0xd7, 0xcb, 0xad, 0xe8, 0xcb, 0x53, 0xa1, 0xc3, + 0x0f, 0xe8, 0x5f, 0x2f, 0xff, 0xc5, 0xe2, 0xfb, 0x4d, 0x7e, 0x1e, 0x18, 0x45, 0x48, 0x4d, 0x18, + 0x8c, 0xf9, 0xda, 0x4f, 0xd9, 0x6e, 0x6b, 0xff, 0x05, 0x65, 0x69, 0xa6, 0x9a, 0x31, 0x26, 0x54, + 0x6f, 0x45, 0xed, 0x15, 0x67, 0x7c, 0x87, 0x81, 0x6a, 0xf1, 0x02, 0xda, 0x6b, 0x69, 0xaf, 0xc2, + 0xa5, 0x1f, 0xf2, 0xff, 0x7a, 0xff, 0x2f, 0xf7, 0x99, 0x0d, 0x57, 0xa6, 0x98, 0x89, 0x98, 0xcb, + 0xd1, 0x12, 0xaf, 0x0a, 0x76, 0x9a, 0xc4, 0xb8, 0x25, 0xcd, 0xa6, 0xb6, 0x9a, 0x11, 0x69, 0xf0, + 0x57, 0x69, 0xae, 0xd3, 0x5b, 0x4d, 0x65, 0x4f, 0x85, 0x36, 0xda, 0x5d, 0xa6, 0xb6, 0x9a, 0xda, + 0x6b, 0x2f, 0x82, 0xeb, 0x4d, 0x6d, 0x35, 0x95, 0x0e, 0x9f, 0x0a, 0x49, 0x99, 0x68, 0x2e, 0x4c, + 0x7e, 0xf4, 0x9a, 0xc5, 0x17, 0x25, 0x32, 0xf8, 0x50, 0xb8, 0x3d, 0xd0, 0x1e, 0xe9, 0x83, 0xdd, + 0x01, 0xee, 0x80, 0xeb, 0xa0, 0xeb, 0xa7, 0x1d, 0x74, 0x1d, 0x74, 0xca, 0x9f, 0x04, 0x70, 0x75, + 0xd1, 0x9e, 0x25, 0xa7, 0xc6, 0xf0, 0x75, 0xd0, 0x1d, 0x74, 0x07, 0x5d, 0x01, 0xd7, 0x4f, 0x83, + 0xae, 0x80, 0xeb, 0xa6, 0x0e, 0xba, 0x03, 0xae, 0x82, 0x5a, 0x72, 0xe9, 0x77, 0xfc, 0x3f, 0x07, + 0x5d, 0x10, 0xf0, 0x75, 0xd0, 0x1d, 0x74, 0xe0, 0xeb, 0xa1, 0xe8, 0x0f, 0x74, 0x83, 0x22, 0x7f, + 0x8b, 0x5e, 0x34, 0xc9, 0x24, 0xc1, 0xb0, 0x66, 0x20, 0x99, 0x96, 0xe7, 0x01, 0xca, 0x48, 0xa4, + 0x86, 0x38, 0xc9, 0x5a, 0xc2, 0x71, 0x6b, 0x9c, 0xe7, 0x03, 0x68, 0x9d, 0x93, 0x63, 0x87, 0x06, + 0xc8, 0xc3, 0x49, 0xd5, 0x6f, 0x1a, 0x3a, 0xf3, 0xa5, 0x1c, 0x3c, 0x6d, 0xc0, 0x23, 0x47, 0xa0, + 0x9c, 0x11, 0x5a, 0x52, 0x72, 0x05, 0xe2, 0x18, 0xc7, 0xbd, 0xee, 0x83, 0x23, 0x7c, 0xf5, 0x93, + 0x53, 0xa2, 0x66, 0xfc, 0x55, 0x89, 0x6a, 0xea, 0xb2, 0xbe, 0x34, 0x7b, 0x76, 0x61, 0x33, 0x2e, + 0x17, 0x36, 0xb8, 0xbf, 0x14, 0x59, 0x51, 0xce, 0x02, 0x06, 0xed, 0x3f, 0x3a, 0xed, 0x86, 0x9d, + 0xe6, 0x3f, 0x1a, 0x24, 0x63, 0xca, 0x3d, 0xea, 0x3c, 0xa3, 0xde, 0x3b, 0xe5, 0xbe, 0xf5, 0xbe, + 0x5b, 0xef, 0x22, 0x2a, 0xfc, 0xda, 0x6d, 0xf3, 0xc8, 0x8a, 0xbf, 0x36, 0x9b, 0x7c, 0xf4, 0xab, + 0xf3, 0x69, 0xb7, 0xcf, 0x4a, 0xbf, 0x36, 0x9b, 0x7c, 0xf4, 0xcb, 0xf2, 0xe9, 0x74, 0x9c, 0x25, + 0x96, 0x1e, 0x68, 0x57, 0x0c, 0x71, 0xdf, 0x35, 0xd8, 0xef, 0x96, 0xf8, 0xd6, 0x58, 0x4b, 0x0f, + 0xf1, 0x98, 0x8e, 0x16, 0x1e, 0x20, 0x73, 0x11, 0xc6, 0xc3, 0xe2, 0x07, 0x3e, 0x36, 0x15, 0x57, + 0xc2, 0xaa, 0xcb, 0x0f, 0xcd, 0x08, 0xd2, 0xf8, 0xd2, 0xa5, 0x5f, 0x9b, 0x4d, 0xbe, 0x37, 0xc4, + 0x8f, 0x9b, 0xfb, 0xfc, 0x49, 0xfd, 0x2a, 0xfc, 0xda, 0x6d, 0xf6, 0x4d, 0xa6, 0xbc, 0xb4, 0x92, + 0x12, 0x91, 0x3d, 0x22, 0xb9, 0xca, 0x22, 0x93, 0x8a, 0xb1, 0x57, 0xfe, 0x33, 0x33, 0x63, 0xb4, + 0xc9, 0x55, 0xcd, 0x02, 0x63, 0x4b, 0xdf, 0x99, 0x8f, 0xc6, 0xe6, 0x81, 0x61, 0xe2, 0x46, 0x1c, + 0x41, 0x87, 0x9a, 0x05, 0x86, 0x95, 0x7e, 0x6d, 0x36, 0xf9, 0xc8, 0xff, 0x6d, 0xb8, 0xd3, 0xf0, + 0x51, 0x49, 0x24, 0x92, 0x49, 0x24, 0x92, 0x4a, 0xbc, 0x66, 0x5a, 0x78, 0xae, 0x5a, 0x72, 0xe7, + 0x2e, 0x78, 0x5a, 0x92, 0x5d, 0xa8, 0x87, 0x2f, 0xf6, 0xdb, 0x4d, 0x3f, 0x0a, 0x4e, 0x41, 0x8a, + 0x98, 0x3b, 0xde, 0x52, 0xe0, 0xf8, 0x8e, 0xd3, 0x5b, 0x4d, 0x24, 0x5e, 0xa8, 0xff, 0xa0, 0xb6, + 0x1f, 0x45, 0x7a, 0xeb, 0x94, 0xbc, 0xf5, 0x4f, 0x2f, 0x37, 0x37, 0xc2, 0x1d, 0x5d, 0x5c, 0x81, + 0x06, 0xfd, 0xa4, 0xcb, 0xd0, 0x67, 0xdf, 0x42, 0x35, 0xf0, 0x47, 0x55, 0x5d, 0x49, 0xd1, 0x63, + 0x7d, 0x15, 0x22, 0x27, 0x44, 0xa8, 0xee, 0x8c, 0xd7, 0xd6, 0xaf, 0xab, 0x7d, 0x5a, 0x3f, 0xa3, + 0xba, 0x4e, 0x8d, 0xd1, 0x1d, 0x17, 0xa3, 0xfa, 0x36, 0x50, 0x29, 0xe2, 0x60, 0x57, 0xeb, 0xd7, + 0xc4, 0xd5, 0xd5, 0xdd, 0xdd, 0xc5, 0x75, 0x8a, 0x13, 0xe8, 0xad, 0xf5, 0xaf, 0xa2, 0xbc, 0xbd, + 0x19, 0xfe, 0x8a, 0xdf, 0x57, 0xfa, 0xbf, 0xd5, 0xbe, 0xad, 0x5d, 0x5e, 0x4e, 0x86, 0x0e, 0xd0, + 0x73, 0xd1, 0xde, 0x6e, 0xbd, 0x5d, 0x5e, 0x11, 0xe2, 0x04, 0x39, 0x48, 0x2c, 0x1e, 0xcd, 0x8d, + 0xb2, 0x48, 0x39, 0xd0, 0xb7, 0xae, 0xbd, 0x11, 0xd6, 0xaf, 0xab, 0xcf, 0xd7, 0xaf, 0x82, 0x40, + 0x96, 0xa9, 0xd5, 0x72, 0x17, 0x49, 0x2f, 0x2e, 0xdd, 0xfc, 0x41, 0x5d, 0xe8, 0x6a, 0xcd, 0x5a, + 0x2f, 0x42, 0xea, 0xfa, 0xea, 0x5e, 0xb5, 0x5d, 0x6a, 0x37, 0xaf, 0xeb, 0x08, 0xcb, 0xd7, 0xaf, + 0xae, 0x97, 0xeb, 0x28, 0xde, 0x3c, 0x24, 0x7f, 0xf7, 0x48, 0xf8, 0xd1, 0x01, 0x33, 0x0c, 0x0c, + 0x3e, 0x09, 0x4a, 0xde, 0xde, 0x99, 0x1a, 0xe7, 0xc4, 0xf6, 0xd5, 0xf2, 0xe7, 0x90, 0x43, 0xde, + 0x12, 0xc4, 0xa0, 0xc8, 0xe3, 0x7d, 0x7a, 0x2b, 0xa1, 0x0f, 0x0e, 0x75, 0xe8, 0x6f, 0xa2, 0xbc, + 0x47, 0x57, 0xae, 0xaf, 0x5d, 0x5e, 0x12, 0xea, 0xd1, 0xfd, 0x5e, 0x5c, 0x45, 0x70, 0x47, 0x7b, + 0xe5, 0x37, 0x36, 0x92, 0x5f, 0x54, 0xed, 0x74, 0x5e, 0xae, 0xba, 0x93, 0xae, 0xbe, 0xb1, 0x5f, + 0x61, 0x27, 0x7f, 0xc1, 0x69, 0x25, 0xb2, 0x94, 0xd3, 0xb1, 0x34, 0xe7, 0xc2, 0x72, 0xce, 0xfa, + 0xaf, 0xc2, 0x67, 0x3c, 0x7a, 0xaf, 0xe3, 0xab, 0x33, 0x69, 0xbf, 0x5e, 0xbe, 0x2c, 0xe6, 0xca, + 0xaa, 0xaa, 0xaf, 0x84, 0xb4, 0xe9, 0x1b, 0xaf, 0x7c, 0x58, 0xeb, 0x4f, 0x74, 0x59, 0xba, 0x0b, + 0xb4, 0x40, 0xb5, 0xa3, 0x7f, 0x57, 0x8a, 0xea, 0xd1, 0x3d, 0x5a, 0x7e, 0x62, 0xbb, 0xbb, 0xf8, + 0xb0, 0xa6, 0xc6, 0x5a, 0x6e, 0xfe, 0x5b, 0xde, 0xb8, 0xad, 0x33, 0x7c, 0xb4, 0xdd, 0x72, 0x91, + 0x05, 0x39, 0x8b, 0x6b, 0xb1, 0x2a, 0xbf, 0x10, 0xcf, 0x5a, 0xf8, 0x21, 0x22, 0xd5, 0x7b, 0xe5, + 0xde, 0xe0, 0xaa, 0x23, 0xf0, 0x90, 0xad, 0xdd, 0xdd, 0xe4, 0xc4, 0x18, 0xf4, 0x9d, 0xf1, 0x21, + 0x00, 0x88, 0xa0, 0xbf, 0x06, 0x88, 0xbd, 0x30, 0xf3, 0x2a, 0x17, 0x25, 0x83, 0x3f, 0xbb, 0x81, + 0xdd, 0x28, 0xea, 0xcf, 0x19, 0xfd, 0xbb, 0xdc, 0x6d, 0x4b, 0x62, 0xb0, 0x44, 0x81, 0xc2, 0x50, + 0x45, 0x9d, 0x73, 0xdd, 0x33, 0x46, 0xf9, 0xf9, 0x4e, 0x4a, 0xad, 0x93, 0x2a, 0x33, 0x9f, 0x2e, + 0x86, 0xbf, 0x88, 0x26, 0xe5, 0xcd, 0x77, 0x7b, 0xa4, 0x18, 0xe7, 0x13, 0xd2, 0x50, 0x94, 0xfc, + 0xdc, 0x40, 0xaa, 0x56, 0x92, 0x4b, 0x27, 0x25, 0xa6, 0xbf, 0x3d, 0x5b, 0x6d, 0xb6, 0xfd, 0xf1, + 0xd7, 0xac, 0xf9, 0xd2, 0xda, 0xc4, 0x41, 0x41, 0x75, 0x34, 0x29, 0xae, 0x0f, 0x87, 0xcd, 0x97, + 0xb1, 0xb6, 0x4e, 0xa2, 0xe4, 0x51, 0xd4, 0xfd, 0x9f, 0xf8, 0x9b, 0xb9, 0x69, 0x7f, 0x04, 0x99, + 0xfa, 0x70, 0xeb, 0xe0, 0x98, 0x8e, 0x50, 0xc0, 0x74, 0xc6, 0x52, 0x1f, 0xef, 0x82, 0xb1, 0x79, + 0x32, 0x7d, 0x5e, 0xaa, 0xbd, 0xf0, 0x51, 0x69, 0xa4, 0xe2, 0xeb, 0x56, 0xf8, 0xa1, 0x0e, 0x1f, + 0x4c, 0x4e, 0x92, 0x4a, 0x20, 0x68, 0xe5, 0xce, 0x20, 0x64, 0x35, 0x31, 0xbd, 0x29, 0x7b, 0x19, + 0xb8, 0x77, 0xfb, 0x36, 0x13, 0xb8, 0x5b, 0x2d, 0xb8, 0xc7, 0x31, 0xd5, 0x3c, 0x73, 0x5c, 0x40, + 0x40, 0x28, 0x46, 0x08, 0xaa, 0x60, 0x85, 0xe3, 0xda, 0x41, 0x24, 0x31, 0x10, 0x2f, 0xa8, 0xba, + 0x8b, 0xd5, 0xf3, 0x1e, 0x20, 0x29, 0x0e, 0x32, 0x52, 0xff, 0x66, 0x1d, 0xa8, 0x97, 0xb9, 0xef, + 0xb4, 0x76, 0xee, 0xfa, 0x5d, 0xbb, 0xf1, 0x22, 0x46, 0x0d, 0x53, 0x04, 0x01, 0x6e, 0x34, 0xe5, + 0xc2, 0xe5, 0xee, 0xdf, 0x76, 0xfe, 0x10, 0xbb, 0xdb, 0x8d, 0xa0, 0x89, 0xaa, 0x34, 0xa9, 0x7c, + 0x9b, 0x51, 0x9a, 0x78, 0xbe, 0xef, 0x4e, 0xeb, 0x82, 0x3b, 0xbf, 0xea, 0xe0, 0x8e, 0xb2, 0x11, + 0xf5, 0x71, 0x02, 0x10, 0x0e, 0x7a, 0xf3, 0xef, 0xc1, 0x39, 0x32, 0x4a, 0x5a, 0x12, 0xe7, 0xc6, + 0xf9, 0x45, 0xe2, 0x5e, 0xeb, 0x84, 0x43, 0xbc, 0x79, 0x78, 0xf2, 0x8f, 0x2f, 0xdf, 0x20, 0x24, + 0x4d, 0x34, 0x5f, 0x05, 0xf6, 0x7a, 0xd5, 0xba, 0xd2, 0x27, 0xff, 0xc1, 0x1c, 0x8d, 0xf0, 0xc8, + 0x8c, 0x42, 0x09, 0xd5, 0x74, 0x6b, 0x9f, 0x57, 0x2b, 0x82, 0x1d, 0xef, 0xd5, 0xc1, 0x21, 0xf5, + 0x53, 0x25, 0x75, 0x64, 0xbd, 0x11, 0xeb, 0x82, 0x42, 0x4c, 0xa2, 0x41, 0x84, 0xa9, 0xc4, 0xc1, + 0x49, 0xb3, 0x10, 0x59, 0x5d, 0xf6, 0x5e, 0x8d, 0x8d, 0x7d, 0xe2, 0x05, 0x69, 0xd6, 0xb5, 0xf3, + 0x6e, 0xd3, 0x3f, 0x08, 0x94, 0x8a, 0x23, 0x1c, 0xc2, 0xc8, 0x13, 0xdf, 0x45, 0x71, 0x5f, 0x8c, + 0x33, 0xb1, 0xdb, 0xaa, 0x9b, 0xc9, 0xfd, 0xb9, 0x55, 0xd6, 0xb5, 0x85, 0xc8, 0x2c, 0x00, 0xc7, + 0xab, 0xed, 0x77, 0xe1, 0x1f, 0x85, 0x5a, 0xfd, 0x62, 0xf6, 0x38, 0x66, 0x23, 0x69, 0x45, 0xda, + 0x4c, 0x8a, 0x23, 0xc4, 0x88, 0x0a, 0x10, 0x7e, 0xed, 0xe8, 0xc8, 0xa3, 0x52, 0x08, 0x2b, 0x88, + 0x22, 0xea, 0x29, 0x8a, 0x6b, 0x01, 0xff, 0x2f, 0x0a, 0x17, 0xa7, 0x1f, 0xc4, 0xc6, 0x5b, 0x31, + 0x42, 0x78, 0x24, 0x1d, 0x10, 0x11, 0x1e, 0xe6, 0x0e, 0xfe, 0x51, 0x1d, 0x05, 0xea, 0x1a, 0x0e, + 0xd3, 0x1b, 0xf8, 0xcc, 0xd4, 0x9c, 0xbc, 0xf6, 0x8c, 0xef, 0x82, 0x97, 0xae, 0x3a, 0x60, 0xcb, + 0x59, 0xf0, 0x52, 0x46, 0xf3, 0x96, 0x19, 0xf2, 0x56, 0x9d, 0x79, 0x9a, 0x8a, 0xfc, 0x4c, 0x49, + 0x46, 0x0c, 0x71, 0xd5, 0xaf, 0x13, 0x14, 0x5a, 0xa6, 0x93, 0x9e, 0x8f, 0x7e, 0x23, 0x3e, 0x25, + 0xa3, 0xcb, 0x5c, 0x45, 0xcf, 0x97, 0xbf, 0xb1, 0x0f, 0x7f, 0xa1, 0x73, 0xfc, 0x26, 0x46, 0xdf, + 0xd3, 0x3a, 0x9f, 0x29, 0x17, 0x3f, 0x26, 0x2e, 0xd3, 0x07, 0xe0, 0x94, 0x5a, 0x54, 0xa4, 0xa2, + 0x8b, 0xd1, 0xff, 0x5e, 0xe2, 0x62, 0xc2, 0x0a, 0xa9, 0x4e, 0x54, 0x85, 0xe8, 0xbd, 0x62, 0xbe, + 0xbc, 0xa8, 0xbc, 0xe1, 0x55, 0x4d, 0x34, 0xd3, 0x4d, 0x34, 0xd3, 0xf3, 0xd5, 0x34, 0xd3, 0x4d, + 0x34, 0xd3, 0x4d, 0xf3, 0x8e, 0x5d, 0x32, 0x67, 0xf9, 0xeb, 0xf8, 0xab, 0x15, 0x62, 0x3a, 0x3b, + 0x1f, 0x56, 0x24, 0xe8, 0xee, 0x7d, 0x5c, 0xfb, 0xa4, 0x97, 0xe6, 0xd4, 0x71, 0x92, 0x80, 0x00, + 0x3e, 0x20, 0x2a, 0x32, 0x67, 0x5b, 0xa3, 0x59, 0x1b, 0x51, 0xe4, 0x9f, 0xfc, 0xd5, 0x17, 0x5f, + 0x12, 0x08, 0xad, 0xee, 0xdf, 0x34, 0xcc, 0x7f, 0x05, 0x96, 0x31, 0x5c, 0xaa, 0x2d, 0xda, 0x48, + 0x91, 0x32, 0x53, 0x87, 0x9b, 0x8e, 0x24, 0x66, 0x88, 0x7d, 0x94, 0x2e, 0x52, 0x4b, 0x07, 0xbc, + 0xdf, 0xc4, 0xdf, 0x55, 0xc2, 0x22, 0x01, 0x49, 0xf7, 0x3f, 0x3e, 0x89, 0xfe, 0xeb, 0x5f, 0x2c, + 0x70, 0x5f, 0x70, 0x80, 0x90, 0x54, 0x20, 0xbe, 0xae, 0x86, 0x5f, 0x17, 0x6d, 0x6b, 0xdf, 0x08, + 0x49, 0xe2, 0x2f, 0x55, 0x55, 0x21, 0x06, 0xf3, 0xe6, 0x22, 0x28, 0xbd, 0x8d, 0xd5, 0x0c, 0x4f, + 0x3f, 0x1e, 0x55, 0x11, 0xe6, 0x25, 0x29, 0xba, 0x62, 0xb6, 0xdd, 0xfe, 0x2f, 0x9b, 0x35, 0xac, + 0x3c, 0xce, 0x01, 0x03, 0xeb, 0x41, 0xba, 0xf3, 0xff, 0xfb, 0xeb, 0xdf, 0xfc, 0x78, 0x87, 0xbe, + 0xf6, 0xa2, 0x74, 0xa5, 0x88, 0xfc, 0x41, 0x06, 0xdd, 0x5f, 0x7d, 0xfc, 0x17, 0x09, 0x4a, 0xf7, + 0x76, 0x37, 0xb7, 0xc1, 0x20, 0x8b, 0x49, 0x10, 0x30, 0x5b, 0xe2, 0xaa, 0x92, 0xda, 0xa5, 0xc4, + 0x46, 0x1e, 0x4b, 0xc7, 0x2a, 0x71, 0x07, 0x37, 0x8b, 0xf3, 0x7f, 0x11, 0x0a, 0x67, 0x25, 0x35, + 0x03, 0xb9, 0x66, 0xb1, 0x0e, 0x1a, 0xcd, 0x49, 0x49, 0x95, 0xef, 0xb8, 0xba, 0xaa, 0xf8, 0xe9, + 0x5b, 0x55, 0x66, 0x6b, 0xc9, 0x4a, 0x87, 0x36, 0xcb, 0xf0, 0x54, 0x2a, 0x7c, 0xcb, 0x44, 0x8d, + 0xaf, 0x84, 0x75, 0x7b, 0x7c, 0x14, 0x5a, 0xc1, 0x24, 0x7c, 0x6a, 0x8a, 0xa4, 0xbe, 0xf8, 0xbd, + 0xed, 0x6e, 0x9f, 0x83, 0x0a, 0x1b, 0x72, 0xcc, 0x91, 0x4d, 0x18, 0x65, 0xfd, 0x6c, 0xcb, 0x38, + 0xff, 0xc2, 0x1d, 0xa7, 0x67, 0x6d, 0x69, 0xed, 0x3e, 0x36, 0x1c, 0xf9, 0x8e, 0x76, 0xc6, 0xc7, + 0x69, 0xa6, 0x6c, 0xd5, 0x32, 0xef, 0x15, 0x51, 0x32, 0x2e, 0xc7, 0x27, 0x4f, 0xf0, 0x47, 0x57, + 0xe0, 0xf8, 0x24, 0xde, 0xed, 0xf1, 0x17, 0xb5, 0xdd, 0xd7, 0x25, 0x2b, 0x5f, 0x04, 0x9d, 0xde, + 0xa3, 0x3a, 0x3d, 0x49, 0xd5, 0xbe, 0x0a, 0x69, 0xe4, 0xeb, 0xdd, 0xf4, 0x76, 0xf1, 0x21, 0x2b, + 0xbd, 0xd1, 0xaf, 0xc4, 0x96, 0xdc, 0xab, 0xfc, 0x5d, 0xdf, 0x55, 0xfc, 0x13, 0xd0, 0x8f, 0x11, + 0x82, 0x66, 0x0b, 0x19, 0x14, 0x96, 0xd0, 0x85, 0x69, 0x7c, 0x40, 0x92, 0x16, 0x38, 0xae, 0x7c, + 0x57, 0xc2, 0xf8, 0x80, 0x88, 0x95, 0x55, 0x57, 0x77, 0x76, 0x77, 0x58, 0x6f, 0x00, 0x2f, 0xb1, + 0x8d, 0x13, 0x6f, 0x2a, 0x82, 0x31, 0x6c, 0x62, 0xcd, 0x01, 0x5e, 0x24, 0x79, 0x18, 0xb3, 0xac, + 0x5b, 0x67, 0x8d, 0x22, 0x1e, 0x3b, 0x32, 0xfe, 0xde, 0x10, 0x85, 0x08, 0x25, 0x18, 0x23, 0xad, + 0x09, 0x60, 0x47, 0xbd, 0xc9, 0x98, 0xd1, 0x63, 0x49, 0x83, 0x4f, 0xcc, 0x10, 0x04, 0x7b, 0x42, + 0xf7, 0x38, 0x98, 0xcc, 0x4b, 0x2a, 0x61, 0x6c, 0x10, 0xc3, 0x39, 0x8d, 0xf5, 0x33, 0x0c, 0x1e, + 0x32, 0x88, 0x0f, 0x82, 0x68, 0xac, 0xfc, 0xf9, 0x8d, 0xa1, 0xcc, 0xe8, 0xef, 0xc2, 0x85, 0x3b, + 0x35, 0xd6, 0xda, 0xc9, 0x86, 0x25, 0x49, 0xce, 0x41, 0xa5, 0x5e, 0x2e, 0x26, 0xa0, 0x5e, 0x88, + 0xc6, 0x3a, 0x4f, 0x88, 0x11, 0xf0, 0x99, 0x95, 0x6a, 0xaa, 0xa1, 0xca, 0x9e, 0x0a, 0x8a, 0x3c, + 0x98, 0xde, 0xbf, 0x9b, 0xbb, 0x74, 0xac, 0x6f, 0x5d, 0x1f, 0xbe, 0x28, 0x71, 0x65, 0x8f, 0x76, + 0xbf, 0xbf, 0xe2, 0x84, 0xa2, 0xa9, 0xb1, 0xad, 0x1a, 0x3f, 0x08, 0x96, 0xaa, 0x4a, 0x55, 0x29, + 0x2b, 0xf8, 0x99, 0xaa, 0xaa, 0x6f, 0xe3, 0x23, 0x31, 0xbe, 0x93, 0x55, 0x2d, 0x09, 0xdd, 0x08, + 0x1c, 0xcf, 0x5f, 0x05, 0xb7, 0x1d, 0x5e, 0x82, 0x49, 0x13, 0x27, 0xf8, 0x82, 0x68, 0x92, 0x44, + 0x7c, 0x79, 0xf8, 0xa1, 0x49, 0x94, 0x60, 0xdd, 0x9b, 0xfe, 0x1d, 0xdc, 0xff, 0xa7, 0x4a, 0x94, + 0xb0, 0x2d, 0x15, 0x32, 0x51, 0x1c, 0xff, 0xb2, 0xb3, 0x7d, 0xf0, 0x43, 0xaa, 0x56, 0xf8, 0x4f, + 0xa4, 0x96, 0xaf, 0xe5, 0x9b, 0xff, 0x84, 0x4b, 0xa6, 0xf7, 0xba, 0xbf, 0xe6, 0xe4, 0xff, 0x09, + 0xd3, 0x6d, 0x36, 0xf4, 0xdd, 0x77, 0x77, 0x7f, 0x82, 0x49, 0x68, 0x8f, 0x7f, 0x82, 0x39, 0x68, + 0x8f, 0x6f, 0x86, 0xee, 0x8d, 0x1a, 0x35, 0x4d, 0x36, 0xdb, 0xf5, 0xc2, 0x1b, 0xd6, 0xd5, 0xdb, + 0x92, 0xfe, 0x2e, 0xde, 0x9a, 0x74, 0xd7, 0xcd, 0x4a, 0x99, 0xb7, 0xc5, 0xed, 0xdf, 0x15, 0xb7, + 0xe0, 0x94, 0xaf, 0xba, 0xb9, 0x76, 0x5f, 0xe0, 0x8f, 0x49, 0x6f, 0xf0, 0x59, 0x77, 0xcb, 0xad, + 0xfb, 0x4d, 0x37, 0xc1, 0x75, 0xb4, 0xe9, 0xed, 0x26, 0x99, 0x78, 0x28, 0xdd, 0xdb, 0xb7, 0x76, + 0xfa, 0xb7, 0xd5, 0x32, 0xf0, 0xb9, 0x07, 0x9d, 0x9a, 0xfe, 0xce, 0xe5, 0x62, 0x52, 0x49, 0x4f, + 0x59, 0xff, 0x11, 0xbb, 0xe5, 0xd7, 0xfc, 0x15, 0x4f, 0x87, 0x85, 0x0f, 0x77, 0xa6, 0xfb, 0xf8, + 0x90, 0xa5, 0xe9, 0xb6, 0xec, 0x7b, 0xbf, 0xaa, 0xa3, 0xbf, 0x08, 0x74, 0x8b, 0x8d, 0x55, 0x9f, + 0x17, 0xf0, 0xa5, 0xa6, 0x8f, 0x8f, 0xc8, 0x84, 0x30, 0x13, 0xc5, 0xac, 0x47, 0xd6, 0x19, 0x55, + 0x93, 0xf4, 0xbf, 0x1c, 0x6b, 0x7b, 0x77, 0x7b, 0xf9, 0x54, 0x71, 0x21, 0x11, 0x71, 0xac, 0x31, + 0x56, 0x87, 0x79, 0x1a, 0xb3, 0xc5, 0x62, 0xf1, 0x21, 0x01, 0x84, 0x51, 0x89, 0xe2, 0x2c, 0x1c, + 0x1c, 0x6e, 0x72, 0xe3, 0xed, 0xd6, 0x64, 0xb9, 0xe3, 0x89, 0x31, 0x1f, 0xc4, 0xfd, 0x67, 0x3f, + 0x0a, 0x4f, 0xb1, 0x32, 0xab, 0xaa, 0xbb, 0xee, 0x2b, 0xbb, 0xf1, 0x02, 0x42, 0x87, 0x17, 0xee, + 0x21, 0xe2, 0xb2, 0xc6, 0xe2, 0x8c, 0x42, 0xc5, 0x8a, 0x0c, 0x56, 0x28, 0xde, 0xbc, 0x22, 0x0a, + 0x09, 0x32, 0xa6, 0xa3, 0xbd, 0xeb, 0xe0, 0xac, 0xef, 0x6e, 0x21, 0xc1, 0x59, 0x6c, 0x56, 0xea, + 0xd2, 0x1d, 0xfc, 0x30, 0x13, 0xcb, 0xee, 0xe5, 0x5d, 0x03, 0x80, 0xf8, 0x40, 0x41, 0x9d, 0xec, + 0x3c, 0x74, 0xfc, 0x49, 0x74, 0xdd, 0x52, 0xa7, 0xef, 0xcb, 0xd7, 0x05, 0x82, 0x29, 0xda, 0x66, + 0xad, 0xea, 0xab, 0x26, 0xf1, 0x21, 0x31, 0x65, 0xdd, 0xb1, 0x93, 0x3e, 0x24, 0x48, 0x99, 0x44, + 0x2a, 0xc1, 0xa2, 0xe0, 0xff, 0xf1, 0x20, 0x9b, 0xbb, 0xbd, 0xf5, 0xf5, 0xef, 0x8e, 0xaa, 0xe8, + 0xd2, 0x53, 0x5d, 0xa4, 0x6f, 0xe2, 0x26, 0xb6, 0x7f, 0x2d, 0xfc, 0x75, 0xdd, 0xdc, 0xa4, 0x16, + 0x0f, 0x2e, 0x3b, 0xbf, 0x13, 0x04, 0xa2, 0xa5, 0xcc, 0x51, 0x48, 0xbc, 0x98, 0x2f, 0xdf, 0x05, + 0xa5, 0xaa, 0x74, 0x47, 0xa9, 0x0a, 0x53, 0xaa, 0xe1, 0x2a, 0xba, 0x5b, 0x6c, 0x6d, 0xae, 0x52, + 0x9a, 0x5f, 0xc4, 0x5b, 0x6d, 0xb6, 0xdb, 0x4d, 0xb4, 0xfd, 0xcd, 0xff, 0xe5, 0xa5, 0xb6, 0xb8, + 0x4a, 0x9e, 0xdc, 0xdd, 0xbd, 0xf3, 0x91, 0x49, 0xa4, 0xdf, 0xc9, 0xcd, 0x49, 0x26, 0xeb, 0x9b, + 0x9b, 0x3e, 0x6a, 0x49, 0x7e, 0x5e, 0x7c, 0xf9, 0x6f, 0x7a, 0xe4, 0xb4, 0xd5, 0x7c, 0xf5, 0x6e, + 0x7f, 0xfc, 0x44, 0x11, 0xda, 0x2e, 0x5a, 0x2d, 0xf0, 0x5f, 0x3b, 0x18, 0xfa, 0xdb, 0xbc, 0xf0, + 0x51, 0x7f, 0xfe, 0x11, 0x3b, 0x0d, 0xca, 0x92, 0x11, 0xe8, 0x78, 0x3d, 0xd6, 0xdc, 0xf0, 0x86, + 0x88, 0x40, 0x8b, 0x8a, 0x4b, 0x47, 0xfa, 0x6b, 0x75, 0xdb, 0xc4, 0xf8, 0x64, 0x5d, 0xdf, 0xd4, + 0x5f, 0x89, 0x0a, 0x15, 0xdd, 0xc5, 0x63, 0x30, 0x86, 0xf6, 0x28, 0x39, 0xee, 0x8d, 0xf5, 0x46, + 0xa3, 0xe2, 0x04, 0xcf, 0x10, 0x20, 0x62, 0x6d, 0x51, 0x39, 0x58, 0x3e, 0x5f, 0xc6, 0x0d, 0x6a, + 0x40, 0xf3, 0x3a, 0x56, 0x31, 0x37, 0x84, 0x76, 0x59, 0x0a, 0x5b, 0x7b, 0x4d, 0xcd, 0x52, 0x60, + 0xb1, 0x22, 0x49, 0x5d, 0x7c, 0x4a, 0x33, 0xfc, 0x16, 0xdc, 0x56, 0x9b, 0xaa, 0xae, 0xb8, 0x98, + 0x4e, 0xd6, 0x2e, 0xbb, 0xdf, 0xe0, 0xa4, 0xee, 0xf6, 0x33, 0xfb, 0xee, 0xfa, 0x3b, 0xe1, 0x00, + 0x8d, 0xdf, 0x4d, 0xd6, 0xf2, 0xf1, 0x0f, 0x58, 0x44, 0xc4, 0x55, 0x55, 0xf1, 0x36, 0x39, 0xb3, + 0x2d, 0x28, 0xbf, 0x8f, 0x2d, 0x59, 0x55, 0x55, 0x56, 0xc6, 0x9f, 0x8b, 0x11, 0x77, 0xb1, 0xa4, + 0x5b, 0xfc, 0x45, 0x24, 0x99, 0xbc, 0x99, 0xf8, 0xc1, 0x6d, 0x15, 0x15, 0x1e, 0xc6, 0xa1, 0xac, + 0x4a, 0x07, 0xdb, 0x5f, 0xc1, 0x55, 0xdf, 0xd8, 0xf3, 0x98, 0x9a, 0x46, 0x86, 0x91, 0x5e, 0xb4, + 0x38, 0xbe, 0x14, 0xd4, 0xdb, 0x2a, 0xac, 0xde, 0x93, 0x23, 0x53, 0x5e, 0x6f, 0x7f, 0x84, 0x64, + 0xa5, 0x1a, 0x34, 0x67, 0xb8, 0x13, 0xcd, 0x65, 0x36, 0x43, 0x6d, 0x9a, 0xe1, 0x32, 0x20, 0xa9, + 0x24, 0xf7, 0xae, 0x2a, 0x64, 0x5b, 0x45, 0x63, 0xb7, 0xe1, 0x01, 0x0e, 0xf1, 0x0f, 0xbd, 0xde, + 0x72, 0x8c, 0xbc, 0x26, 0x75, 0x6f, 0xd2, 0x4b, 0xc4, 0xda, 0xd3, 0x6d, 0xff, 0x11, 0x75, 0xe9, + 0xbd, 0x70, 0xdd, 0xab, 0xd5, 0x3a, 0x6f, 0xfe, 0x09, 0x35, 0x5b, 0x97, 0xd9, 0x36, 0x9b, 0x27, + 0x2d, 0xb6, 0xdb, 0x37, 0x7c, 0xd7, 0xd5, 0x75, 0x73, 0xee, 0xd3, 0x4d, 0x35, 0xea, 0x90, 0x57, + 0x04, 0xa2, 0x5d, 0xf4, 0x9d, 0xe2, 0xc7, 0x3e, 0x2b, 0x7b, 0xde, 0xcf, 0xcc, 0x69, 0x32, 0xd7, + 0x82, 0xcc, 0xb4, 0x7a, 0x0c, 0xde, 0x77, 0xba, 0x68, 0x67, 0x20, 0xe6, 0x0f, 0xc4, 0x08, 0xd9, + 0x8e, 0x40, 0x6b, 0xaa, 0x6e, 0xa2, 0x64, 0x2d, 0xed, 0x2c, 0x4f, 0xc1, 0x15, 0x68, 0x56, 0xd9, + 0xe2, 0x41, 0x10, 0xa7, 0x7b, 0xd7, 0xc2, 0x82, 0x57, 0x34, 0x59, 0xbd, 0x36, 0xd2, 0x25, 0x02, + 0x76, 0xad, 0x70, 0xad, 0x7e, 0x7f, 0x8b, 0x2a, 0xc6, 0x73, 0x53, 0x42, 0xf7, 0xb7, 0xc4, 0xc5, + 0xdd, 0xdd, 0x9b, 0xbb, 0xbf, 0x89, 0xb1, 0xab, 0x1a, 0xb1, 0xef, 0xc4, 0x0f, 0xde, 0x6a, 0x3e, + 0x6f, 0x77, 0xf1, 0xe4, 0x2e, 0xf3, 0x10, 0x4d, 0xd6, 0x53, 0xbf, 0x10, 0x24, 0x5f, 0x55, 0x5a, + 0xae, 0x26, 0x11, 0xb1, 0xd5, 0xba, 0xaa, 0xcd, 0xd2, 0x77, 0xc4, 0xfe, 0x33, 0x33, 0x0b, 0xd6, + 0xad, 0x96, 0xa9, 0x51, 0xd2, 0x4b, 0xe6, 0x25, 0x2a, 0xe2, 0x04, 0x84, 0x0a, 0xf1, 0x2d, 0x16, + 0x54, 0xe3, 0x07, 0x68, 0x5e, 0x4c, 0xf3, 0x49, 0xff, 0x85, 0x0f, 0x8e, 0x46, 0x4c, 0x7a, 0xe3, + 0x26, 0x43, 0x37, 0x4e, 0x66, 0x83, 0x56, 0x36, 0xf8, 0xa2, 0x6a, 0xa4, 0xa7, 0x5f, 0x16, 0x50, + 0xbd, 0x5d, 0xae, 0x95, 0x19, 0x84, 0x29, 0x3e, 0x4a, 0x63, 0xfc, 0x29, 0x53, 0xb9, 0x6a, 0x75, + 0x57, 0x1b, 0x93, 0x85, 0xad, 0x26, 0x93, 0x93, 0x1b, 0xed, 0x7e, 0x09, 0x49, 0xbb, 0xfa, 0x69, + 0x25, 0xf8, 0x44, 0x52, 0x44, 0xda, 0x4e, 0xf3, 0xb0, 0xd3, 0xff, 0x04, 0xa2, 0x73, 0xfd, 0xed, + 0x77, 0xc1, 0x57, 0x69, 0x5b, 0x69, 0x9b, 0x54, 0xdd, 0xeb, 0xe5, 0x26, 0x9a, 0x6b, 0x87, 0x4b, + 0xba, 0x4c, 0x69, 0xdc, 0xcc, 0xc1, 0xb1, 0xd4, 0xbd, 0xdf, 0xfe, 0x2a, 0x3b, 0x48, 0xa8, 0xed, + 0x3a, 0x49, 0xf8, 0xcf, 0x17, 0xc9, 0x95, 0x4f, 0xd3, 0xaf, 0x82, 0xc8, 0xad, 0x7a, 0xa7, 0xa4, + 0xfc, 0xbe, 0x2f, 0x9f, 0xa5, 0xa4, 0x97, 0x84, 0xf4, 0x9b, 0x4a, 0xef, 0xf1, 0x3b, 0xaf, 0x57, + 0xf0, 0x47, 0x2f, 0x3f, 0x4e, 0xbe, 0xf8, 0x21, 0x21, 0xbe, 0x93, 0x9f, 0x73, 0x6b, 0x7f, 0x84, + 0xb8, 0xba, 0x5b, 0x4d, 0x7a, 0xa7, 0x1f, 0x21, 0xd2, 0x4a, 0x97, 0x8e, 0x22, 0x6d, 0x67, 0xdf, + 0x26, 0x6b, 0x82, 0x98, 0xca, 0xfd, 0xb6, 0xd6, 0x4d, 0xdb, 0x4a, 0xbc, 0x12, 0x69, 0x55, 0x8f, + 0x82, 0xcc, 0x9a, 0xbe, 0x4d, 0xde, 0x92, 0x55, 0xc4, 0x0e, 0x30, 0xbc, 0x99, 0x69, 0x90, 0xd2, + 0xf4, 0xe9, 0xa5, 0xff, 0x08, 0x8b, 0x76, 0xf2, 0x10, 0x48, 0x41, 0xcd, 0x4d, 0x7c, 0x29, 0x77, + 0x7b, 0x4a, 0xdc, 0xb4, 0xde, 0xb4, 0xe5, 0xe2, 0x42, 0x76, 0x49, 0x0d, 0x57, 0xa7, 0x4f, 0xc4, + 0x82, 0x3e, 0xab, 0x5f, 0x1f, 0x49, 0xfa, 0xc9, 0x8f, 0xda, 0xf1, 0x3d, 0x0d, 0x74, 0x35, 0xc4, + 0x84, 0x41, 0x56, 0x3a, 0x9b, 0x70, 0x64, 0xb3, 0x0a, 0x45, 0x83, 0x31, 0xaa, 0xc8, 0x41, 0xae, + 0x20, 0x48, 0x50, 0x46, 0xaa, 0x2e, 0xe9, 0xb9, 0x69, 0x74, 0x11, 0xbe, 0xd5, 0xf3, 0x38, 0x42, + 0x18, 0x0f, 0x7c, 0x16, 0x09, 0x72, 0xfb, 0xa5, 0x3f, 0x46, 0x79, 0x83, 0x01, 0x11, 0xa1, 0xee, + 0x20, 0x48, 0x8d, 0xbb, 0xbb, 0xbb, 0xbe, 0x20, 0x48, 0x4b, 0x4d, 0xb4, 0x54, 0x20, 0xca, 0xa3, + 0x15, 0x70, 0x88, 0xab, 0xbf, 0x93, 0xf8, 0x91, 0x33, 0xe3, 0xbd, 0x3b, 0x1b, 0x7c, 0x22, 0x33, + 0x70, 0xda, 0xaa, 0xdd, 0xe9, 0xbf, 0x75, 0x13, 0xf6, 0x62, 0x3e, 0x78, 0x93, 0x77, 0x7f, 0x1c, + 0x65, 0x5a, 0xe9, 0xba, 0xd7, 0xe0, 0x8b, 0x67, 0x17, 0x6f, 0x84, 0x4a, 0xa1, 0x52, 0xd1, 0x55, + 0x51, 0xb9, 0x31, 0xaa, 0xd5, 0xd4, 0x36, 0x55, 0xc4, 0x8c, 0xca, 0xa5, 0xfd, 0x89, 0xd2, 0x4d, + 0x45, 0x9d, 0xa4, 0x90, 0x9d, 0x37, 0xd5, 0x3f, 0x89, 0x1c, 0x55, 0x59, 0x93, 0xa7, 0xb2, 0xc9, + 0x05, 0xf8, 0x97, 0x92, 0xbf, 0x84, 0xfc, 0xad, 0x54, 0x7f, 0x97, 0x9f, 0xb5, 0xe0, 0x8a, 0x9e, + 0x93, 0x7c, 0x75, 0xa6, 0xd2, 0xb9, 0xb4, 0x95, 0xdd, 0xf2, 0xf0, 0x58, 0x21, 0x76, 0x56, 0x37, + 0xa1, 0x91, 0xf6, 0x0e, 0xbe, 0x08, 0xe5, 0x61, 0x8e, 0xdb, 0x62, 0x4e, 0x11, 0x2c, 0x9a, 0x9d, + 0x4d, 0xed, 0xb4, 0xe9, 0xfc, 0x23, 0x59, 0xbb, 0x74, 0x9b, 0x4a, 0x24, 0xcb, 0xbf, 0x82, 0x5b, + 0xb7, 0x5d, 0x52, 0x32, 0x57, 0x35, 0x24, 0xbf, 0x08, 0x97, 0x4d, 0xed, 0xdb, 0x97, 0xcb, 0xfc, + 0x15, 0x52, 0x48, 0xfa, 0xed, 0x6d, 0xba, 0xdb, 0x69, 0xae, 0x2f, 0x82, 0x6a, 0x49, 0x24, 0x93, + 0xbf, 0x87, 0xc2, 0x7a, 0x6d, 0xdb, 0xb7, 0xf0, 0x49, 0xa5, 0x2e, 0x19, 0x3e, 0x1a, 0xd5, 0xea, + 0xae, 0xaf, 0xfe, 0x73, 0x2c, 0xba, 0xdd, 0x7e, 0xb9, 0xeb, 0xe9, 0xa6, 0x9a, 0x7e, 0x1c, 0xb7, + 0xba, 0xac, 0x9d, 0x3f, 0xf2, 0x52, 0x0c, 0x4f, 0xf6, 0x6d, 0x6f, 0x58, 0x80, 0xa1, 0x94, 0xd8, + 0xb2, 0xaa, 0xa9, 0x2d, 0x5d, 0x8c, 0xb4, 0x08, 0x3c, 0xcc, 0x7f, 0x7c, 0x10, 0xd3, 0x6d, 0xfd, + 0xf0, 0x91, 0xc9, 0xf9, 0x7b, 0x7f, 0x84, 0x4b, 0x37, 0x5d, 0x6b, 0x45, 0x52, 0x33, 0xe0, 0xb3, + 0x56, 0x89, 0x02, 0xb0, 0xbd, 0x03, 0xa4, 0xb7, 0x38, 0x89, 0x65, 0xa3, 0x07, 0x49, 0xf0, 0x97, + 0x92, 0x6b, 0x54, 0xfc, 0x13, 0xf9, 0xba, 0x7a, 0xfb, 0xe3, 0xe2, 0xeb, 0xce, 0xc2, 0x42, 0xe4, + 0x90, 0xc1, 0x82, 0xcf, 0x4f, 0xf1, 0x62, 0x27, 0x24, 0xbd, 0x1a, 0xfc, 0x23, 0xd2, 0x2e, 0x24, + 0x93, 0x7d, 0x57, 0xc4, 0xef, 0x2d, 0xee, 0x9a, 0x5c, 0x49, 0x8e, 0xaa, 0xab, 0xe3, 0x3a, 0xaa, + 0x44, 0xc6, 0xa5, 0x53, 0xa6, 0x2e, 0xae, 0xf8, 0x64, 0x40, 0x52, 0xef, 0x07, 0x2f, 0xad, 0x53, + 0x3f, 0x76, 0xb0, 0xb6, 0x7b, 0xf1, 0x31, 0x95, 0x55, 0x4a, 0x56, 0x31, 0x36, 0x24, 0x5d, 0x55, + 0xaf, 0xc2, 0x96, 0x65, 0x33, 0x29, 0x36, 0x9f, 0x39, 0xd8, 0x7f, 0x6b, 0x76, 0x93, 0x6a, 0xbe, + 0x32, 0xf5, 0x91, 0x97, 0x43, 0x4f, 0x3d, 0xd5, 0x54, 0x4d, 0x46, 0x22, 0x10, 0x9f, 0x2e, 0xea, + 0xd3, 0x1b, 0x9a, 0x22, 0xb5, 0x10, 0xff, 0x0a, 0x1c, 0x4c, 0x82, 0xcc, 0x17, 0x73, 0x13, 0x61, + 0x06, 0x2f, 0x38, 0x9f, 0xac, 0xcc, 0x4c, 0xb7, 0xc2, 0x55, 0xad, 0x01, 0xc4, 0xcc, 0xfc, 0x13, + 0x6a, 0xb9, 0xa3, 0xb7, 0xc1, 0x1e, 0xab, 0x6f, 0x8f, 0x8d, 0xd0, 0xed, 0x55, 0x5d, 0x88, 0xe6, + 0x86, 0xfa, 0x1d, 0x73, 0x93, 0x92, 0x1e, 0x13, 0x26, 0xad, 0x1f, 0xb9, 0x75, 0xbf, 0x11, 0x1c, + 0x2d, 0xcb, 0x8e, 0xf2, 0x08, 0x84, 0x82, 0x2b, 0x2d, 0x83, 0x5d, 0x74, 0xcd, 0x5f, 0x10, 0x20, + 0x13, 0x99, 0xde, 0xd5, 0xca, 0x41, 0xde, 0xb1, 0x00, 0x8e, 0x7a, 0x0a, 0xd3, 0x95, 0x2f, 0x87, + 0x86, 0x4e, 0x10, 0x05, 0x3b, 0x24, 0x38, 0xc1, 0x8c, 0xbd, 0x5c, 0x70, 0xf1, 0x5a, 0x89, 0xfe, + 0x16, 0x2a, 0x49, 0xfc, 0xda, 0xde, 0x1c, 0xbf, 0x7f, 0xf0, 0xb5, 0xbd, 0x24, 0xe9, 0x37, 0x96, + 0x9a, 0xaf, 0xf8, 0x7a, 0xd3, 0x5b, 0x74, 0xed, 0x25, 0xca, 0x68, 0xad, 0xff, 0xc6, 0x5e, 0x9d, + 0xb7, 0xdb, 0xb7, 0x49, 0x2f, 0xc5, 0xd2, 0x4b, 0xd3, 0x49, 0x71, 0x1d, 0xda, 0xa7, 0x4f, 0xca, + 0x5a, 0xa2, 0xf9, 0x79, 0x72, 0xf8, 0xb9, 0xb2, 0x95, 0x36, 0xff, 0x37, 0x93, 0x7c, 0x99, 0x7a, + 0x1e, 0xf9, 0x2d, 0x5a, 0xf8, 0x4f, 0x3d, 0x3a, 0x4f, 0xf0, 0x49, 0xb1, 0xb4, 0xd4, 0x1f, 0x04, + 0x84, 0xa2, 0x50, 0xf8, 0x12, 0x06, 0xdf, 0x05, 0x26, 0x8c, 0xe1, 0x35, 0x26, 0xcc, 0x46, 0x8f, + 0xa0, 0x75, 0xeb, 0x87, 0xc2, 0x45, 0x2f, 0xfa, 0xaf, 0x8a, 0xd5, 0x53, 0x5a, 0xf1, 0x02, 0x78, + 0x98, 0xf2, 0xbd, 0xeb, 0x56, 0x25, 0x25, 0x3c, 0x40, 0x81, 0x26, 0x7d, 0xbb, 0x73, 0x31, 0xe0, + 0x88, 0xf7, 0x7f, 0x78, 0x91, 0x65, 0xcc, 0xc6, 0xb6, 0xfc, 0x11, 0xca, 0xc3, 0xd4, 0xd3, 0x71, + 0x30, 0x43, 0x52, 0x62, 0x4f, 0xa7, 0x71, 0x22, 0x44, 0xdc, 0xb8, 0xd3, 0xf2, 0xf7, 0xf0, 0x8d, + 0x49, 0x73, 0x71, 0x9d, 0x28, 0xe9, 0x11, 0x23, 0x4a, 0xd1, 0x97, 0xc7, 0x84, 0x63, 0x27, 0x71, + 0x39, 0x4d, 0xb1, 0x4c, 0x4f, 0x0f, 0x2c, 0x65, 0x66, 0xee, 0x60, 0x98, 0xd1, 0xb9, 0x1f, 0x84, + 0x0c, 0xaa, 0x7f, 0x16, 0x2c, 0xca, 0xaa, 0xa9, 0xa9, 0x3c, 0x40, 0x46, 0xb5, 0x66, 0xaa, 0x2e, + 0xaa, 0xaa, 0xb8, 0x98, 0xad, 0x6a, 0xaa, 0xbc, 0x21, 0x05, 0x75, 0x2f, 0x31, 0x06, 0x79, 0xbe, + 0x66, 0x18, 0xec, 0x76, 0xf8, 0x2a, 0xa3, 0x2d, 0x31, 0x0d, 0x1c, 0xdb, 0xd6, 0x9f, 0x71, 0x11, + 0xe5, 0x6a, 0x68, 0x28, 0xb8, 0x8e, 0x20, 0xb7, 0x37, 0x2b, 0x2c, 0xce, 0x24, 0x7c, 0xbc, 0x5c, + 0x47, 0xc9, 0xb7, 0xd7, 0x57, 0xf1, 0x95, 0xa9, 0x3c, 0x70, 0x42, 0x2c, 0xac, 0xd0, 0xc6, 0x98, + 0xcc, 0xaf, 0x12, 0x09, 0xab, 0x90, 0x72, 0x44, 0x93, 0x66, 0x3b, 0x78, 0x91, 0xe7, 0xb7, 0x6d, + 0x6b, 0x5c, 0x89, 0x38, 0x80, 0x43, 0x4e, 0x43, 0x1b, 0x7c, 0x49, 0xab, 0x46, 0xef, 0x7e, 0x20, + 0x4c, 0xf1, 0x4d, 0x6a, 0x6d, 0x45, 0x38, 0x88, 0xaf, 0x2b, 0x0e, 0x5b, 0xa7, 0x89, 0x88, 0x3b, + 0xa2, 0xee, 0xee, 0xc1, 0xe2, 0x04, 0x0b, 0xa2, 0x73, 0xec, 0x2b, 0x64, 0x8f, 0xfe, 0x27, 0xe4, + 0x11, 0xc5, 0xfc, 0xa7, 0xbb, 0xfc, 0xa6, 0x7d, 0xaf, 0x08, 0x1a, 0xd5, 0xa4, 0x06, 0x9d, 0xbb, + 0xa7, 0xf1, 0x67, 0x72, 0xf4, 0x9b, 0x85, 0xcf, 0xf0, 0xad, 0xa6, 0xf9, 0xfe, 0xae, 0xc9, 0xd9, + 0x7a, 0xe3, 0xee, 0x6c, 0xe6, 0x56, 0x58, 0xf4, 0xd7, 0xc2, 0x56, 0x31, 0xab, 0xa4, 0x96, 0xf7, + 0xfa, 0xeb, 0xe0, 0x82, 0x92, 0x5e, 0x86, 0xfb, 0xba, 0xfa, 0x69, 0xa6, 0x9f, 0x96, 0x92, 0x5f, + 0x82, 0x2b, 0x69, 0x1b, 0xc5, 0xaf, 0x85, 0xa8, 0x69, 0x5b, 0xda, 0x4d, 0x4d, 0xcf, 0xff, 0xf2, + 0x6d, 0x5a, 0xf3, 0x55, 0xd3, 0x75, 0xc4, 0x5f, 0x6e, 0xdd, 0x7c, 0x4f, 0x6d, 0x37, 0xab, 0xae, + 0x15, 0xe6, 0xe9, 0xee, 0xd2, 0xba, 0x74, 0xff, 0xc2, 0x14, 0xd2, 0xc9, 0xe9, 0xbe, 0x92, 0xf8, + 0x2c, 0x15, 0x2f, 0x52, 0xb1, 0x55, 0x0b, 0x72, 0x18, 0x5b, 0xf4, 0x9e, 0x24, 0xc2, 0x6f, 0x7f, + 0xa8, 0x81, 0x06, 0x2b, 0x9b, 0xf8, 0x99, 0x0d, 0xc9, 0x98, 0x81, 0x23, 0x0c, 0x2b, 0xed, 0xd3, + 0xbc, 0xaa, 0x2e, 0xdb, 0x84, 0x89, 0xb4, 0x03, 0x3a, 0xd1, 0x1c, 0xba, 0xcf, 0x09, 0x8d, 0x6d, + 0x55, 0x3b, 0x26, 0x97, 0xc1, 0x11, 0x5d, 0xbd, 0x9f, 0x11, 0xa4, 0xef, 0x1a, 0x93, 0xf8, 0xca, + 0xc9, 0x2b, 0x88, 0xb5, 0x3e, 0x3d, 0x2b, 0x1f, 0x79, 0x0b, 0xb5, 0x7c, 0x48, 0xca, 0x1b, 0xbb, + 0xcd, 0x92, 0x66, 0xed, 0x4b, 0xc7, 0x7e, 0xd3, 0xb3, 0x10, 0x24, 0xa4, 0x2f, 0xda, 0x2e, 0x11, + 0x1d, 0x5d, 0x45, 0xd4, 0x47, 0x3a, 0xa8, 0xbf, 0x12, 0x32, 0x2e, 0x2f, 0xc8, 0xbd, 0x77, 0x77, + 0x89, 0x60, 0xfe, 0x14, 0xaa, 0xbb, 0xcc, 0xc3, 0xd6, 0xe2, 0xb6, 0x39, 0xf9, 0x3f, 0x9a, 0xc7, + 0x6e, 0x26, 0x32, 0x86, 0x6e, 0xb3, 0x29, 0xab, 0x50, 0x6a, 0xc4, 0xa2, 0x3c, 0xfb, 0x18, 0x5c, + 0xd3, 0xc2, 0x9b, 0x2c, 0x23, 0xf5, 0xed, 0x66, 0x62, 0x7d, 0x89, 0x38, 0xe0, 0xb9, 0xfe, 0x5e, + 0x5f, 0xdc, 0x40, 0x90, 0xa1, 0x56, 0x5e, 0xa9, 0xd0, 0xc3, 0xc7, 0x8b, 0xc5, 0xd4, 0x53, 0x52, + 0xf1, 0x3f, 0x28, 0xff, 0x8c, 0x8a, 0xb9, 0x3d, 0x65, 0x14, 0x1c, 0x90, 0x2f, 0x5a, 0xac, 0xaa, + 0xe2, 0x62, 0x66, 0xe6, 0xe5, 0xfa, 0xd3, 0xf1, 0x20, 0x92, 0xee, 0xef, 0xdf, 0x13, 0x54, 0x73, + 0x7b, 0xdf, 0x88, 0x1f, 0xab, 0x1f, 0x54, 0x4a, 0xc7, 0xf8, 0x40, 0x8b, 0x5e, 0x89, 0xd2, 0xbd, + 0x71, 0x7c, 0xd4, 0xd5, 0xae, 0x23, 0xe2, 0x09, 0x77, 0xfc, 0x9b, 0x27, 0xf9, 0xb8, 0xe7, 0x4e, + 0x24, 0x40, 0xb2, 0x64, 0xd9, 0x3d, 0x7e, 0xe8, 0x72, 0xbf, 0x89, 0xf1, 0x3f, 0x86, 0x6e, 0x5c, + 0xd5, 0x99, 0xbf, 0xef, 0x90, 0xb3, 0xee, 0xf9, 0x36, 0x9a, 0xae, 0x23, 0x4d, 0x92, 0x7a, 0x8d, + 0x2f, 0x9a, 0xf9, 0x31, 0xf5, 0xa9, 0x79, 0x64, 0xc4, 0x92, 0x4b, 0x88, 0x06, 0x02, 0x0b, 0xed, + 0xdb, 0x43, 0x68, 0xd5, 0xa1, 0x2d, 0xe7, 0x87, 0xf1, 0x00, 0xa8, 0xa1, 0x95, 0x57, 0x45, 0x44, + 0xc4, 0x54, 0x18, 0x8b, 0x93, 0xe1, 0xc8, 0x37, 0x2f, 0x8c, 0x8c, 0x54, 0xcc, 0x89, 0x99, 0x4d, + 0x03, 0x27, 0xf1, 0xb4, 0x59, 0x7f, 0xf5, 0xef, 0x12, 0x24, 0xaf, 0x67, 0x7b, 0xfd, 0x6b, 0xe6, + 0x32, 0xd0, 0x86, 0x50, 0xbc, 0x51, 0xb1, 0xd1, 0x78, 0x8e, 0x27, 0xaa, 0xf1, 0x21, 0x01, 0x63, + 0x09, 0x9d, 0x05, 0x33, 0x67, 0x5f, 0x66, 0x6f, 0xf8, 0xf2, 0xb0, 0xd6, 0x86, 0x98, 0xae, 0xf5, + 0x4d, 0x71, 0x30, 0xa1, 0x4f, 0xf5, 0xc7, 0x12, 0x32, 0xad, 0x71, 0x41, 0xda, 0xe5, 0xf9, 0xf8, + 0x32, 0x67, 0x1d, 0x9f, 0xe0, 0xaa, 0xa6, 0xff, 0x1e, 0x96, 0xba, 0x8d, 0x61, 0x67, 0xbc, 0x40, + 0xcd, 0x55, 0x2e, 0x0b, 0x96, 0x19, 0x66, 0x29, 0xdb, 0xe1, 0x6d, 0xde, 0x5e, 0x85, 0xd0, 0xe1, + 0x10, 0xa5, 0x55, 0x45, 0xc6, 0x32, 0x92, 0xf0, 0xb1, 0xca, 0x26, 0xc4, 0x4d, 0x89, 0x9e, 0x38, + 0xdf, 0x0a, 0x44, 0x70, 0xfb, 0x1a, 0xa4, 0x2e, 0xa9, 0x1d, 0x2b, 0x98, 0x12, 0x70, 0xeb, 0x25, + 0x9a, 0xfc, 0xbc, 0x48, 0x2a, 0x23, 0x19, 0xd8, 0xb1, 0xe5, 0x63, 0x27, 0x55, 0x35, 0x3b, 0x89, + 0x08, 0x85, 0x2c, 0x0c, 0x04, 0x47, 0x23, 0xd4, 0x95, 0x63, 0x07, 0x54, 0x47, 0x6e, 0xc8, 0xfc, + 0x24, 0xea, 0x87, 0x72, 0xcc, 0x76, 0xe2, 0x02, 0x23, 0xa9, 0xdc, 0xa5, 0x35, 0x2f, 0x2d, 0x66, + 0x52, 0x27, 0xf8, 0x44, 0x29, 0x11, 0x61, 0x45, 0x0b, 0xe0, 0xf3, 0x30, 0xae, 0x60, 0xac, 0x5e, + 0x94, 0xd4, 0x76, 0xf0, 0xc8, 0x25, 0x9e, 0xfd, 0xde, 0xdd, 0x56, 0x5c, 0x48, 0x64, 0x14, 0x96, + 0x4f, 0x33, 0x0d, 0xc5, 0x0b, 0xca, 0x97, 0xa8, 0xbf, 0x7d, 0xe5, 0x7f, 0x09, 0xd8, 0xde, 0xd9, + 0xb2, 0x9f, 0xdf, 0x8d, 0xd3, 0xcd, 0x68, 0xdb, 0xf1, 0x24, 0x23, 0xa7, 0x40, 0xf8, 0x91, 0xdb, + 0xde, 0xb4, 0xee, 0xe7, 0x96, 0x24, 0x22, 0x6e, 0x5a, 0x17, 0x31, 0x22, 0x5d, 0xdf, 0xc4, 0x89, + 0x1d, 0xdb, 0x49, 0xef, 0x59, 0xa8, 0xbe, 0x3f, 0x19, 0xa7, 0xbd, 0x0d, 0x37, 0xfc, 0x5e, 0xee, + 0x7f, 0x15, 0xbb, 0xe2, 0x65, 0x11, 0xcb, 0x4f, 0x31, 0x55, 0x6b, 0x88, 0x82, 0x31, 0x3b, 0xbb, + 0xf1, 0x31, 0x62, 0x10, 0xf7, 0xdb, 0x2b, 0x1e, 0x12, 0xdb, 0xbe, 0xad, 0x7a, 0x23, 0x7c, 0x15, + 0x97, 0x46, 0x4a, 0xe6, 0xe9, 0xd5, 0xa6, 0x9b, 0xe0, 0x9e, 0x87, 0x23, 0x8c, 0xea, 0xd3, 0x6f, + 0x96, 0x9b, 0x7f, 0x82, 0x7a, 0x9b, 0xea, 0xcf, 0x6f, 0x82, 0x3b, 0x76, 0xd5, 0xab, 0x84, 0xef, + 0x6a, 0xae, 0xdf, 0xc4, 0x66, 0xef, 0x17, 0x2f, 0xf0, 0x47, 0x63, 0x2f, 0xa7, 0x97, 0xc1, 0x21, + 0x13, 0x75, 0xd7, 0xc1, 0x19, 0x67, 0xcd, 0xcf, 0x82, 0x6b, 0xda, 0x68, 0x9e, 0x78, 0x3e, 0x0a, + 0xeb, 0xae, 0xec, 0x77, 0x4d, 0x3d, 0x57, 0x7a, 0x4d, 0x57, 0x08, 0x08, 0x55, 0xa1, 0xdd, 0x31, + 0xea, 0xbc, 0xff, 0xc5, 0x8b, 0x3b, 0x1a, 0x39, 0xa0, 0x8a, 0xfe, 0x11, 0x10, 0xb4, 0xbb, 0x97, + 0x13, 0x7f, 0xe1, 0x23, 0xea, 0x4f, 0xb6, 0x76, 0x38, 0x8f, 0x10, 0x8b, 0x5e, 0x24, 0x60, 0xa7, + 0x71, 0x0f, 0x2d, 0xbd, 0x4f, 0x3e, 0x3f, 0x1e, 0xec, 0xf2, 0xfc, 0xd5, 0x59, 0xbe, 0x20, 0x22, + 0x08, 0x84, 0xa8, 0xbe, 0xfc, 0x40, 0x64, 0x15, 0x1d, 0x47, 0xeb, 0x11, 0x08, 0x03, 0x01, 0xb6, + 0x8e, 0xea, 0xd8, 0xaa, 0x63, 0x32, 0x63, 0x17, 0x28, 0x2f, 0xf1, 0x22, 0xad, 0x76, 0xd4, 0x4f, + 0xa9, 0x7c, 0x2a, 0xa0, 0x07, 0xb5, 0xbe, 0x8a, 0x33, 0xee, 0x7f, 0xec, 0x9b, 0x1c, 0x40, 0x6a, + 0x56, 0xd5, 0x0a, 0x3a, 0x89, 0xca, 0x31, 0x22, 0x47, 0xec, 0x8d, 0x29, 0xd6, 0xad, 0x91, 0x43, + 0x17, 0xc3, 0x23, 0x24, 0x51, 0x32, 0x2e, 0xa2, 0xea, 0x2f, 0x2a, 0xaa, 0xaa, 0xa6, 0x20, 0xf0, + 0xc8, 0x99, 0xf6, 0x23, 0x9a, 0x8b, 0xca, 0xf8, 0x53, 0x74, 0x33, 0x29, 0xb2, 0x97, 0xf2, 0x75, + 0xe5, 0x7b, 0x89, 0x88, 0x24, 0x84, 0x14, 0xdf, 0xb8, 0xbd, 0x78, 0x44, 0x66, 0x0e, 0x56, 0x56, + 0xa6, 0x51, 0x2a, 0xb3, 0x31, 0x2b, 0x2b, 0xc4, 0x0e, 0x91, 0x8f, 0x8b, 0xa6, 0x4e, 0xa2, 0xe4, + 0x62, 0x78, 0x81, 0x36, 0x9a, 0xe9, 0xd7, 0xc4, 0xad, 0x78, 0x45, 0x7b, 0x89, 0x08, 0xf8, 0x91, + 0x55, 0xdb, 0xcb, 0xfe, 0x12, 0xa1, 0xae, 0x4f, 0x63, 0xf8, 0xad, 0x35, 0x53, 0x76, 0x6b, 0x7e, + 0x26, 0x09, 0x09, 0x26, 0xfd, 0xe2, 0x01, 0x41, 0xb1, 0x8a, 0x67, 0xe7, 0x21, 0xf5, 0xf0, 0x9d, + 0x3a, 0xcb, 0xdd, 0x45, 0xfc, 0x20, 0x55, 0xdb, 0xa4, 0x17, 0xca, 0xa4, 0xd6, 0x97, 0x98, 0xb5, + 0x7e, 0x24, 0x20, 0x12, 0xb7, 0x7e, 0x9b, 0x70, 0x9b, 0x30, 0x46, 0xb2, 0x54, 0xff, 0xdf, 0xad, + 0xf2, 0x1c, 0x5f, 0xb1, 0x2e, 0x6d, 0x27, 0xf8, 0x92, 0x67, 0x52, 0x9c, 0xcd, 0xd9, 0x2e, 0x72, + 0xa9, 0xa2, 0x89, 0xfe, 0x48, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5a, 0x2d, 0x30, 0x2a, 0x8b, + 0x13, 0x28, 0xbe, 0x7a, 0x62, 0x2b, 0xdf, 0x5e, 0x85, 0x3a, 0x12, 0x99, 0x09, 0xe8, 0x83, 0xb4, + 0x27, 0xd1, 0x0b, 0x49, 0x10, 0x24, 0x11, 0x50, 0x37, 0x79, 0xd2, 0xb9, 0xa7, 0xa1, 0xe9, 0xfa, + 0x19, 0xaf, 0xa2, 0xe1, 0x3f, 0x42, 0xd2, 0xa5, 0xd4, 0xa9, 0xf5, 0xcb, 0xea, 0x55, 0x9f, 0x5c, + 0xab, 0xa9, 0x92, 0xf8, 0x7a, 0x7a, 0x1e, 0x85, 0xa3, 0x68, 0x7e, 0x48, 0xbe, 0x04, 0xa7, 0x0d, + 0x0d, 0xb2, 0xe0, 0xaa, 0xba, 0xf6, 0xfb, 0x6d, 0xc4, 0x4c, 0xf8, 0x50, 0x21, 0x82, 0xa3, 0xc1, + 0x67, 0xc8, 0x80, 0x68, 0x5c, 0xd9, 0x6e, 0xc1, 0x78, 0x4e, 0x0b, 0x92, 0x88, 0x41, 0x7f, 0x10, + 0x8e, 0xf6, 0x02, 0xa0, 0x41, 0xd5, 0x4b, 0x6e, 0x08, 0xb8, 0xa3, 0xe0, 0xa0, 0x78, 0xac, 0x4b, + 0x42, 0xd9, 0x6c, 0xf4, 0x3d, 0x3b, 0xc2, 0xdd, 0x15, 0x2a, 0x5d, 0x6b, 0xea, 0x91, 0x7a, 0xb7, + 0xc3, 0x42, 0x01, 0xdf, 0x46, 0x97, 0x10, 0xad, 0xaa, 0x2f, 0x37, 0xff, 0x05, 0x3c, 0xcc, 0xcd, + 0xea, 0x9a, 0x1a, 0xd6, 0xad, 0xa3, 0xbf, 0x0f, 0x77, 0x7d, 0x24, 0xa9, 0x52, 0x5f, 0x39, 0x91, + 0x29, 0x9f, 0x88, 0x04, 0xb7, 0x7e, 0x5f, 0x9d, 0x0d, 0x53, 0x88, 0x8c, 0x2f, 0x1a, 0xa3, 0xee, + 0x46, 0x14, 0x78, 0x8c, 0x7b, 0xca, 0xc7, 0x92, 0x2e, 0xeb, 0xf0, 0xb1, 0x34, 0x92, 0x49, 0x2d, + 0x20, 0x7e, 0x6c, 0x5f, 0x04, 0x26, 0x9e, 0x5e, 0x61, 0xe0, 0x8c, 0x58, 0xca, 0xcb, 0x56, 0x7e, + 0x39, 0xe2, 0x0c, 0x37, 0x8d, 0x78, 0x44, 0x40, 0x8b, 0x88, 0x11, 0xf4, 0x30, 0x88, 0xeb, 0xc1, + 0x3d, 0x22, 0xd2, 0xeb, 0x59, 0x50, 0x8f, 0xe2, 0x43, 0xd9, 0x68, 0xbd, 0xcd, 0x60, 0xed, 0xdc, + 0xa0, 0xd4, 0x18, 0x28, 0x19, 0x45, 0xa4, 0x86, 0xae, 0x5e, 0x0f, 0xe1, 0xc4, 0x8d, 0x1c, 0x0b, + 0x63, 0x78, 0x40, 0xc3, 0xc1, 0x00, 0x6c, 0xa6, 0xe4, 0x20, 0x2e, 0xdc, 0x32, 0x8f, 0x8f, 0xb0, + 0xad, 0x80, 0xc0, 0x04, 0x31, 0x10, 0x8b, 0x0a, 0xa7, 0x34, 0xd2, 0xe0, 0x00, 0x21, 0x4d, 0x8d, + 0x21, 0xa6, 0x72, 0x7a, 0x98, 0x00, 0x14, 0xa0, 0xe2, 0x17, 0x80, 0x09, 0x50, 0x76, 0x00, 0x13, + 0xc3, 0xb0, 0x51, 0x4a, 0xc0, 0x54, 0x46, 0x95, 0x5b, 0x5f, 0xe2, 0x01, 0x5d, 0x21, 0xa5, 0xac, + 0xa0, 0xb1, 0x42, 0xa1, 0x68, 0x9b, 0xc7, 0x84, 0x30, 0x1e, 0x03, 0x26, 0x00, 0x53, 0x09, 0x5f, + 0xf9, 0x49, 0xce, 0x15, 0x1d, 0x99, 0x7d, 0xb7, 0x4f, 0xc1, 0x00, 0x8d, 0xdc, 0xd8, 0x4e, 0xbf, + 0x09, 0x14, 0x0a, 0xf8, 0x88, 0xcc, 0xfd, 0xf4, 0x01, 0x41, 0x39, 0x6d, 0xe1, 0x69, 0x9b, 0x6d, + 0x8f, 0x74, 0x0f, 0x12, 0x20, 0x14, 0x19, 0xde, 0xea, 0x90, 0x68, 0x39, 0x43, 0xe6, 0x0f, 0x2f, + 0x30, 0x66, 0xde, 0x2f, 0x10, 0x0a, 0x0b, 0x80, 0x6c, 0xce, 0x48, 0x0c, 0x45, 0xde, 0xc1, 0x95, + 0xea, 0x72, 0x77, 0x7c, 0x78, 0xf1, 0xcf, 0xf1, 0x63, 0x74, 0x92, 0xd2, 0x4b, 0xc1, 0x29, 0xa7, + 0xc3, 0x67, 0x53, 0x66, 0x80, 0xbf, 0x58, 0xdf, 0x39, 0x53, 0xac, 0xda, 0x6d, 0xf7, 0xc6, 0x5a, + 0x6b, 0x69, 0xad, 0xa6, 0xb6, 0x9a, 0xfc, 0x6c, 0x9e, 0x4a, 0xd2, 0xb9, 0x28, 0xcd, 0xa6, 0x4a, + 0x52, 0x93, 0x2a, 0x9a, 0x62, 0xd8, 0xb7, 0xe5, 0xe3, 0xbc, 0x98, 0x5c, 0xf2, 0xe7, 0xf8, 0x89, + 0xf0, 0xf9, 0x9f, 0x0f, 0x9f, 0x88, 0xe5, 0xc2, 0xe6, 0x5c, 0x2e, 0x78, 0xcc, 0xd9, 0x3e, 0x4d, + 0x93, 0xe1, 0x73, 0xb9, 0x73, 0xfe, 0x09, 0x7b, 0x4d, 0x24, 0x93, 0x4d, 0x19, 0x3e, 0x89, 0x17, + 0xc2, 0xb3, 0x90, 0x4e, 0x41, 0xce, 0x41, 0x39, 0x07, 0x7e, 0x6d, 0x36, 0xff, 0x12, 0x09, 0xa9, + 0x8f, 0x7c, 0x9d, 0x9f, 0x53, 0x92, 0x79, 0x26, 0xf8, 0x2c, 0x23, 0xe2, 0xee, 0xef, 0xba, 0xba, + 0x2e, 0x38, 0x90, 0x54, 0x59, 0x7a, 0xee, 0xef, 0xad, 0x69, 0x57, 0x8c, 0x12, 0x7c, 0x3e, 0x1f, + 0x1f, 0x87, 0xc3, 0xe3, 0xf1, 0xf9, 0x55, 0x4d, 0x35, 0x55, 0x4d, 0x35, 0xe1, 0x32, 0x65, 0xc4, + 0xa4, 0xcf, 0xc1, 0x85, 0x75, 0x79, 0x39, 0x70, 0x76, 0xbb, 0xbb, 0xff, 0x85, 0x0c, 0xaa, 0xaa, + 0xf6, 0xd1, 0xb0, 0x53, 0xee, 0xfb, 0xc8, 0x87, 0xbe, 0x14, 0xbb, 0xdb, 0xad, 0x67, 0xbe, 0xb7, + 0x57, 0xaf, 0x86, 0xad, 0xb6, 0xdb, 0x79, 0x1d, 0xbb, 0xbb, 0xff, 0x82, 0x0b, 0x1b, 0x4e, 0x6c, + 0x5a, 0xd5, 0x75, 0x15, 0x75, 0x11, 0x8d, 0xd5, 0xd7, 0xfc, 0x68, 0xab, 0x5a, 0xb1, 0xbb, 0x7b, + 0xbe, 0x5e, 0xff, 0xde, 0xa7, 0xf4, 0xe9, 0xba, 0xaa, 0xaf, 0x11, 0x87, 0x10, 0x4c, 0x34, 0xcb, + 0x7f, 0xe6, 0xd3, 0x6e, 0x6d, 0x36, 0xa5, 0x5f, 0x9b, 0x4d, 0xb1, 0x0b, 0xf1, 0x94, 0x92, 0xd2, + 0x4b, 0x49, 0x2d, 0x24, 0xbf, 0x19, 0xd2, 0x4b, 0x49, 0x22, 0x63, 0x31, 0x28, 0x99, 0x8c, 0xc8, + 0xa2, 0xf2, 0x44, 0x70, 0x98, 0x93, 0x73, 0xc6, 0x4b, 0x82, 0xbc, 0x43, 0x91, 0x0e, 0x52, 0xa4, + 0x95, 0x29, 0x33, 0xe3, 0x29, 0x24, 0x4c, 0x66, 0x24, 0x93, 0x31, 0x98, 0x94, 0x5c, 0x51, 0x70, + 0xde, 0x56, 0x66, 0x84, 0xd0, 0x3e, 0x86, 0xde, 0xdb, 0x09, 0xa1, 0x34, 0x25, 0x84, 0xb0, 0x18, + 0x02, 0x92, 0x69, 0x37, 0xff, 0x09, 0xd9, 0x9f, 0x93, 0x3e, 0xe3, 0x2b, 0xff, 0x71, 0x95, 0xff, + 0x8a, 0x8e, 0xf9, 0xdd, 0x94, 0xe5, 0xe5, 0xa7, 0xe7, 0x94, 0x41, 0x9b, 0xea, 0xaa, 0xb8, 0x88, + 0x27, 0x08, 0x31, 0x98, 0x38, 0x12, 0x4e, 0x51, 0xf8, 0xf0, 0x71, 0xd8, 0xca, 0x61, 0x2f, 0x88, + 0x1a, 0x20, 0xd7, 0x8f, 0xfe, 0x42, 0x30, 0x0a, 0x81, 0x1c, 0xaa, 0xac, 0xf0, 0xc7, 0x5e, 0x01, + 0x50, 0xf7, 0x26, 0x06, 0x62, 0x2e, 0x42, 0xe7, 0x42, 0x2a, 0x3c, 0xad, 0x16, 0x48, 0x4b, 0x11, + 0x69, 0x58, 0xc8, 0xe8, 0x15, 0x61, 0x04, 0x23, 0x08, 0x78, 0x5c, 0x20, 0x55, 0x01, 0x0d, 0x95, + 0xba, 0x00, 0x96, 0x02, 0xc9, 0x0c, 0x90, 0xb2, 0x9e, 0x02, 0xb8, 0x5d, 0xc2, 0x26, 0x29, 0x81, + 0xbf, 0x7e, 0xd6, 0xc8, 0x49, 0x0f, 0xd9, 0xd8, 0x29, 0xc1, 0xd8, 0x6f, 0x18, 0xa3, 0x2f, 0x0c, + 0x05, 0x4b, 0x85, 0xc3, 0xe3, 0xf1, 0xc4, 0x39, 0xc6, 0x03, 0x1d, 0xfd, 0xb3, 0x6f, 0xe0, 0xa3, + 0x9b, 0x0d, 0x9b, 0x4d, 0x65, 0xf0, 0x4f, 0x9b, 0xe2, 0xb7, 0x2b, 0x30, 0x74, 0xdc, 0x44, 0x68, + 0xab, 0xdd, 0x91, 0x24, 0xd7, 0xb4, 0x1b, 0xc4, 0x89, 0x20, 0x12, 0x3f, 0x6b, 0xcf, 0x06, 0xe1, + 0x62, 0x32, 0x32, 0x02, 0x4a, 0x33, 0x8f, 0xf2, 0x32, 0x8b, 0x34, 0xe6, 0xa7, 0xf8, 0x50, 0x64, + 0x8f, 0x16, 0x61, 0xdc, 0xaa, 0xa9, 0x17, 0x92, 0xd2, 0xea, 0xb8, 0xa0, 0xbe, 0xe9, 0x16, 0x60, + 0x3b, 0x9a, 0x5f, 0xfa, 0xe5, 0xa5, 0x62, 0xef, 0x1f, 0x73, 0x16, 0xfa, 0xc4, 0x97, 0x61, 0x01, + 0xc5, 0xf9, 0x61, 0x08, 0x7f, 0x46, 0x0e, 0x24, 0x69, 0x56, 0x83, 0x25, 0xa9, 0x80, 0xcd, 0x9c, + 0x7e, 0xe8, 0x23, 0xee, 0xc0, 0x18, 0xe5, 0xa0, 0x36, 0x9a, 0x25, 0x04, 0x2a, 0xc6, 0x56, 0x7d, + 0x2e, 0x2e, 0x2b, 0xc1, 0x3e, 0xb7, 0xfe, 0x26, 0x30, 0x8f, 0x8a, 0xac, 0x75, 0x28, 0xa8, 0x84, + 0xe4, 0xda, 0x46, 0xa9, 0x1a, 0xd0, 0xa2, 0xce, 0x5f, 0x3e, 0x13, 0x02, 0x23, 0x85, 0x0d, 0x4b, + 0x39, 0xa2, 0x50, 0xdd, 0xf8, 0x28, 0x0b, 0x9f, 0x0f, 0x8e, 0xc7, 0x63, 0x4d, 0x7e, 0xf8, 0x23, + 0xbd, 0x63, 0x14, 0x93, 0x8c, 0x2e, 0x92, 0x5a, 0x49, 0x69, 0x25, 0xa4, 0x97, 0x8c, 0xe9, 0x25, + 0xa4, 0x96, 0x92, 0x5a, 0x49, 0x78, 0x4e, 0x5a, 0x7c, 0xb4, 0x10, 0xd3, 0xe2, 0x0e, 0x54, 0x77, + 0xe6, 0xd3, 0x69, 0xf5, 0xfb, 0xe8, 0xc0, 0x34, 0x05, 0xbc, 0x47, 0x88, 0xf8, 0xfb, 0x8a, 0xf6, + 0x9d, 0x7a, 0xb7, 0xe8, 0x8e, 0x7c, 0x33, 0x3d, 0x1c, 0xb8, 0xdc, 0x1e, 0x54, 0xd3, 0x4d, 0x3f, + 0xf0, 0x8f, 0x55, 0x3e, 0x3b, 0xbe, 0x5c, 0x7f, 0x05, 0x1d, 0xdf, 0x77, 0x8e, 0x71, 0x22, 0x3e, + 0x38, 0x6f, 0x1f, 0xa6, 0xaa, 0x9f, 0x1a, 0xa6, 0x4e, 0x11, 0x08, 0x27, 0xa6, 0x9b, 0xde, 0xf7, + 0xf8, 0x2e, 0xe7, 0x61, 0xcc, 0xc5, 0x54, 0xb8, 0xf8, 0xaa, 0x69, 0xa6, 0x9a, 0xba, 0xbf, 0xac, + 0xd5, 0xc6, 0x8e, 0xdb, 0x6c, 0xdb, 0xd5, 0x77, 0x75, 0x36, 0xf4, 0xb0, 0x50, 0xa6, 0xa9, 0xff, + 0x94, 0x5b, 0x53, 0x63, 0x6f, 0x82, 0x42, 0xee, 0xf9, 0x78, 0x92, 0xd5, 0x7f, 0x2d, 0xdf, 0xf2, + 0x6f, 0x7f, 0x19, 0xdd, 0xf7, 0x7d, 0xdf, 0x77, 0xf0, 0x57, 0xdd, 0xf7, 0x72, 0x50, 0x94, 0xf5, + 0x58, 0x8f, 0xad, 0x35, 0x62, 0x41, 0x17, 0x49, 0x2e, 0xf0, 0x80, 0x20, 0x1c, 0xda, 0xd4, 0xc1, + 0x98, 0x2b, 0x31, 0x83, 0x33, 0x33, 0x32, 0x40, 0x69, 0xa7, 0x56, 0x1c, 0x45, 0x76, 0x2a, 0xc1, + 0x01, 0x12, 0xf0, 0x8b, 0xff, 0xe3, 0x4c, 0x55, 0x90, 0x3a, 0x03, 0x91, 0x57, 0xcc, 0xac, 0x49, + 0x82, 0xc2, 0xec, 0x1a, 0x8a, 0x6f, 0x06, 0x01, 0x62, 0x9b, 0x1f, 0x46, 0x17, 0x8e, 0x15, 0x95, + 0x0b, 0x0d, 0x01, 0x50, 0x6e, 0xae, 0x04, 0xa7, 0x9b, 0x61, 0x4a, 0xc0, 0x07, 0x9c, 0x76, 0xa0, + 0x3c, 0x9f, 0xba, 0xbf, 0x84, 0x06, 0x7a, 0x32, 0x47, 0x95, 0xc2, 0x66, 0xb4, 0xd0, 0xb6, 0xce, + 0xb2, 0xc0, 0x6d, 0x06, 0x8d, 0x20, 0x7f, 0x20, 0x4e, 0xcd, 0xfe, 0x33, 0xd5, 0x35, 0xdd, 0x6b, + 0x5d, 0xfc, 0x38, 0x68, 0xba, 0x81, 0x45, 0x89, 0x21, 0x63, 0xcf, 0x1c, 0xef, 0xf0, 0xa0, 0xeb, + 0xb1, 0x4d, 0xe9, 0xc5, 0xeb, 0xe9, 0x8b, 0x24, 0xee, 0x5a, 0xcf, 0xcd, 0x0f, 0xfa, 0x52, 0xd8, + 0x88, 0xc5, 0x45, 0x5a, 0x91, 0x8a, 0x7c, 0x15, 0x9e, 0xd0, 0x13, 0x4b, 0xc8, 0x9a, 0x0b, 0x7b, + 0x84, 0x89, 0x7e, 0xee, 0xf7, 0x7c, 0x10, 0x9c, 0xcc, 0x17, 0xc9, 0x68, 0xc7, 0xe0, 0xa4, 0x63, + 0x9f, 0x66, 0x3d, 0x5b, 0x2b, 0x41, 0x62, 0xe2, 0xd4, 0xd8, 0xe3, 0x1a, 0x38, 0xa3, 0x15, 0x5a, + 0xf1, 0x08, 0x2e, 0x45, 0xc9, 0xc5, 0xdd, 0xd5, 0x5d, 0xd5, 0x7d, 0x52, 0x2e, 0x11, 0x0d, 0xd6, + 0xaa, 0x91, 0x79, 0xf4, 0xfb, 0xfa, 0x2b, 0xcb, 0x89, 0x46, 0x8a, 0xb8, 0xbd, 0xd7, 0xaa, 0xc2, + 0x4a, 0x03, 0xe9, 0x58, 0x08, 0x74, 0x20, 0xa4, 0x9a, 0x69, 0xa7, 0xb6, 0xdf, 0x82, 0x8e, 0x6c, + 0x5d, 0x54, 0xab, 0xfa, 0xc4, 0x8b, 0x84, 0x14, 0x8b, 0x2c, 0x7a, 0xea, 0xdb, 0x6d, 0xb7, 0xe4, + 0xc4, 0x7d, 0x08, 0xd8, 0xfa, 0xe5, 0xf5, 0x72, 0xbb, 0x10, 0x2b, 0xdc, 0x46, 0x26, 0x6e, 0x3c, + 0x93, 0x33, 0x4f, 0x54, 0xa5, 0x61, 0x8c, 0x0f, 0xab, 0xbe, 0x2f, 0xe3, 0xc9, 0x3c, 0xc1, 0x41, + 0x96, 0xdd, 0x1d, 0xb4, 0x1c, 0x53, 0x24, 0xed, 0x01, 0x8a, 0x4c, 0x93, 0xb4, 0x28, 0xc9, 0x92, + 0x76, 0x9e, 0x0a, 0xbb, 0x47, 0x2c, 0x6b, 0xd0, 0x64, 0xea, 0x0d, 0xac, 0x47, 0x53, 0x1f, 0x5e, + 0x21, 0x1d, 0xfe, 0x51, 0x08, 0x52, 0xaa, 0x5e, 0x21, 0x84, 0xd7, 0x7f, 0x16, 0x6d, 0xde, 0xad, + 0x99, 0x9f, 0x28, 0xc0, 0x7f, 0xde, 0xfe, 0x82, 0xff, 0xfa, 0xbd, 0x75, 0x79, 0xba, 0x23, 0x57, + 0x04, 0x9d, 0xdf, 0xab, 0x10, 0xbd, 0xf3, 0x55, 0x77, 0xc5, 0x5d, 0xdd, 0xf5, 0x51, 0x1d, 0x7b, + 0xeb, 0xd0, 0x9f, 0x14, 0x12, 0x6a, 0xef, 0xe5, 0x5e, 0xb5, 0x6c, 0xcc, 0x57, 0xe4, 0x25, 0xde, + 0x6e, 0x61, 0x35, 0x7f, 0x89, 0x23, 0xc5, 0x77, 0xb5, 0x05, 0xdc, 0x55, 0x6a, 0xda, 0xbf, 0xe6, + 0x27, 0x3f, 0x36, 0x24, 0x25, 0x6c, 0x5d, 0x5e, 0x68, 0x1a, 0x16, 0x5e, 0x83, 0x35, 0xf5, 0x79, + 0xfa, 0xbf, 0xd5, 0xe4, 0xea, 0xf2, 0x75, 0xaf, 0x82, 0x3f, 0x2e, 0x3f, 0xcd, 0x7d, 0x7d, 0x75, + 0xf5, 0xd4, 0x9c, 0x55, 0x5d, 0x5d, 0xdd, 0x55, 0xf5, 0x79, 0x3a, 0xbc, 0xbd, 0x7a, 0x48, 0x91, + 0x20, 0x90, 0xdc, 0x30, 0x0f, 0x0a, 0x6f, 0x12, 0x14, 0x14, 0x65, 0x15, 0x2e, 0x2b, 0x94, 0xbc, + 0x97, 0xa8, 0xac, 0xb7, 0xcb, 0x19, 0xfe, 0xff, 0xbc, 0x48, 0x2c, 0xa6, 0x5b, 0x13, 0xca, 0x85, + 0x3a, 0x45, 0x50, 0x0e, 0x6c, 0x18, 0x6f, 0x8e, 0x00, 0x78, 0xe8, 0x3e, 0x9f, 0xc4, 0x85, 0x3b, + 0xbe, 0x21, 0xa0, 0xae, 0xdd, 0xa4, 0x1d, 0x7b, 0x2a, 0x0c, 0xbc, 0x53, 0x77, 0x12, 0x24, 0x21, + 0x7b, 0xb8, 0xf2, 0xe5, 0x98, 0x8e, 0x2a, 0x72, 0x1b, 0xfd, 0xc4, 0x82, 0xb2, 0x2b, 0xa4, 0x21, + 0x48, 0x20, 0x70, 0xf7, 0x0b, 0x14, 0xb9, 0x47, 0xeb, 0xe6, 0xde, 0x11, 0x28, 0xd4, 0x14, 0xfd, + 0xfc, 0x22, 0x31, 0xe5, 0x42, 0x18, 0x05, 0x6b, 0x68, 0x06, 0xe8, 0x3e, 0x82, 0xc2, 0x6c, 0xde, + 0x07, 0xbf, 0x89, 0x67, 0x02, 0x76, 0x44, 0x9e, 0xbf, 0x81, 0x26, 0x18, 0xe8, 0x5a, 0x75, 0xe8, + 0xed, 0xe2, 0x65, 0xeb, 0x5f, 0x57, 0xe2, 0x04, 0xab, 0x46, 0x70, 0x54, 0x47, 0x7f, 0x8d, 0x61, + 0xdb, 0x91, 0x0f, 0x23, 0x7c, 0x28, 0x2a, 0x2b, 0xb7, 0xd5, 0x57, 0xa8, 0xe1, 0x6b, 0x5e, 0xf0, + 0x88, 0xab, 0xda, 0xaa, 0xf8, 0x98, 0x50, 0xa2, 0x47, 0x0f, 0x60, 0x0e, 0xda, 0x72, 0xa9, 0x10, + 0x0a, 0x01, 0xdc, 0x35, 0xde, 0x62, 0xf6, 0x59, 0x46, 0xce, 0xd0, 0xb9, 0x67, 0x3e, 0xae, 0xe1, + 0x00, 0x88, 0x29, 0x22, 0xbe, 0xa2, 0xae, 0xa4, 0x20, 0xdc, 0x4f, 0xac, 0xab, 0xf1, 0x22, 0x46, + 0x1d, 0x61, 0x09, 0xac, 0x3f, 0x18, 0xa2, 0x03, 0x30, 0x64, 0x59, 0xc3, 0x89, 0xe9, 0xab, 0x56, + 0xbe, 0x24, 0x60, 0x82, 0x52, 0x84, 0x58, 0xa2, 0xb1, 0x54, 0x49, 0x42, 0x36, 0x34, 0xa2, 0xa3, + 0xce, 0x39, 0x11, 0xf3, 0x1d, 0xa0, 0x80, 0x23, 0x39, 0x49, 0x39, 0x10, 0x1f, 0x05, 0x84, 0x8f, + 0x31, 0x52, 0xba, 0xa2, 0xcc, 0x34, 0x11, 0x8f, 0x7a, 0x43, 0x32, 0xe8, 0x9b, 0x51, 0x20, 0xa4, + 0x1c, 0xf4, 0x30, 0x4f, 0x6c, 0x7d, 0x9c, 0x07, 0x57, 0xf0, 0x91, 0xd7, 0xea, 0x88, 0xec, 0x28, + 0x21, 0x80, 0xa3, 0xf8, 0x42, 0x4e, 0x86, 0xd7, 0xc3, 0x86, 0xad, 0x62, 0xe2, 0xdf, 0xd7, 0x34, + 0xdf, 0x97, 0xa3, 0xe1, 0xf5, 0xe9, 0xfa, 0x3e, 0x5f, 0x46, 0xdc, 0xbe, 0x8a, 0xff, 0x04, 0x37, + 0xbb, 0xb7, 0xd7, 0x91, 0x7a, 0xf8, 0x97, 0x82, 0x22, 0x2d, 0x5d, 0xeb, 0xaf, 0x57, 0x26, 0xaf, + 0xf4, 0x57, 0xf8, 0xbe, 0xef, 0xbb, 0xf1, 0x0b, 0x95, 0xe2, 0x6b, 0x10, 0xbd, 0xf1, 0xe1, 0x0b, + 0xbd, 0xec, 0xe9, 0x29, 0xb8, 0xe7, 0x06, 0xea, 0x73, 0xc4, 0x05, 0x26, 0xc6, 0xb5, 0x69, 0x29, + 0x77, 0x2e, 0x0c, 0xab, 0xf4, 0x0e, 0xf2, 0x9e, 0x01, 0x82, 0x70, 0x00, 0x21, 0xf1, 0x4a, 0x57, + 0xf8, 0x52, 0x3b, 0x59, 0x7b, 0xca, 0x3b, 0xaa, 0xc9, 0x39, 0x67, 0x06, 0xc9, 0x58, 0x9d, 0x22, + 0x93, 0x04, 0x02, 0xff, 0x19, 0x43, 0x79, 0x25, 0x52, 0x2a, 0x70, 0xc8, 0xa7, 0x93, 0x36, 0xc0, + 0xac, 0x5b, 0xee, 0x21, 0xf8, 0x81, 0x03, 0xe2, 0xeb, 0x37, 0xbb, 0x9b, 0xd4, 0xa9, 0x62, 0x02, + 0x00, 0xb0, 0xaa, 0xaa, 0x2e, 0x66, 0x05, 0x78, 0xd2, 0x67, 0x39, 0xc2, 0xeb, 0xfc, 0x15, 0xf5, + 0x5b, 0x68, 0x4b, 0x33, 0x24, 0xfb, 0xf8, 0x81, 0x02, 0x85, 0x1a, 0xe4, 0x07, 0x01, 0x0e, 0xd1, + 0xf0, 0x7b, 0xb1, 0x5f, 0xf1, 0x17, 0xd0, 0x5c, 0xf5, 0xf5, 0xef, 0x84, 0xbc, 0xde, 0xaf, 0xf4, + 0x42, 0xb5, 0xf5, 0xef, 0xaa, 0x65, 0xeb, 0xdf, 0x58, 0xa3, 0x3a, 0x3f, 0xeb, 0xab, 0x4b, 0xd4, + 0xe8, 0xdf, 0x56, 0x2a, 0x22, 0x89, 0xdf, 0x5e, 0xbe, 0xb9, 0x7c, 0xa4, 0xdd, 0xd7, 0x28, 0x97, + 0x7d, 0x61, 0x15, 0xef, 0x84, 0x42, 0xd4, 0x76, 0x34, 0xdc, 0xec, 0xbe, 0x5b, 0xfc, 0x48, 0x52, + 0x3f, 0xe2, 0x55, 0x98, 0x29, 0x8d, 0x61, 0x3d, 0x00, 0x92, 0x62, 0x12, 0x9c, 0xe4, 0x8c, 0x1d, + 0x0f, 0x03, 0x40, 0x3a, 0xd2, 0xdc, 0x00, 0xe5, 0x93, 0x9c, 0x0f, 0x94, 0x77, 0x68, 0xf8, 0x35, + 0xd4, 0x0e, 0x00, 0x23, 0x51, 0x20, 0x1c, 0xb4, 0x16, 0x10, 0xf8, 0x95, 0xc3, 0x6e, 0x00, 0xbc, + 0x3b, 0xc9, 0xc6, 0xab, 0xaf, 0xfe, 0x56, 0xaa, 0x4e, 0x3f, 0x88, 0x31, 0xd7, 0x06, 0x30, 0x3a, + 0xb9, 0xd8, 0x1f, 0xe4, 0xa7, 0x03, 0x89, 0xc1, 0x45, 0xc1, 0xc5, 0xc0, 0x93, 0x71, 0x2f, 0xf4, + 0xd1, 0x78, 0xf9, 0x6d, 0xee, 0xfd, 0x35, 0x4c, 0xc9, 0x20, 0x5c, 0x40, 0x50, 0xab, 0x40, 0xc3, + 0xaa, 0x70, 0x1a, 0x55, 0x89, 0x01, 0x53, 0xc1, 0x92, 0x8a, 0x15, 0x6b, 0xc8, 0x53, 0x01, 0x98, + 0xdb, 0xd8, 0x05, 0xef, 0x81, 0xd0, 0xe9, 0xa4, 0x1f, 0x1e, 0x10, 0x63, 0x66, 0x80, 0x02, 0xd3, + 0xb6, 0x19, 0x34, 0x85, 0x5d, 0x98, 0xfc, 0x4c, 0x64, 0xf5, 0x45, 0x6b, 0xd0, 0xb3, 0x8c, 0x19, + 0xc6, 0x94, 0xe0, 0x30, 0x1f, 0x70, 0x86, 0xca, 0x16, 0x7c, 0x1c, 0x96, 0x12, 0x2a, 0xdc, 0x2f, + 0x1e, 0x7f, 0xc6, 0x16, 0x56, 0x56, 0x57, 0xd5, 0x13, 0xb3, 0xbf, 0x84, 0x06, 0x0a, 0x75, 0xc8, + 0x43, 0x57, 0x54, 0x3c, 0xc6, 0x3a, 0xb2, 0xe2, 0x30, 0xc2, 0x0b, 0xff, 0xf4, 0xd3, 0xd8, 0x4c, + 0x2e, 0xfa, 0xc5, 0xf2, 0x99, 0xdf, 0xc4, 0x84, 0x54, 0x76, 0x8a, 0xe7, 0x2a, 0xa6, 0x9a, 0x69, + 0xfb, 0xe8, 0xa5, 0x4f, 0xaf, 0x7c, 0x78, 0x87, 0x7d, 0xdf, 0x55, 0xf8, 0x95, 0xe9, 0x38, 0x48, + 0x4a, 0xaf, 0xbb, 0xfa, 0xd4, 0x9d, 0xf7, 0x72, 0xf4, 0x66, 0x3e, 0x8a, 0x8e, 0xd7, 0x46, 0x75, + 0x72, 0x75, 0x55, 0xc9, 0x55, 0x59, 0x38, 0x24, 0x3a, 0xaf, 0x17, 0xc7, 0x84, 0xa7, 0x63, 0x3f, + 0x3a, 0x13, 0xec, 0x9a, 0x13, 0x0c, 0x32, 0xd8, 0x98, 0x52, 0x4e, 0xdc, 0x25, 0x07, 0xd9, 0x12, + 0x7c, 0x5e, 0xd6, 0x32, 0x1e, 0x82, 0x80, 0x01, 0x01, 0x58, 0x8a, 0x12, 0x44, 0x01, 0x8a, 0x24, + 0x11, 0x68, 0xa3, 0x8a, 0x7a, 0x31, 0x80, 0x16, 0xfd, 0x41, 0x8c, 0x47, 0x0f, 0x3d, 0x50, 0x5b, + 0x06, 0xb3, 0x62, 0x0e, 0x11, 0xe6, 0x90, 0xc3, 0xd1, 0xa0, 0x01, 0x6d, 0xb4, 0xaf, 0xe6, 0xa4, + 0x09, 0x1e, 0xd3, 0x91, 0x8f, 0x8e, 0x4c, 0xb1, 0x01, 0x11, 0x92, 0x9b, 0xa0, 0x6a, 0x2d, 0xb3, + 0x64, 0x1c, 0x8e, 0xa3, 0x07, 0x4f, 0xc4, 0x38, 0xab, 0x1c, 0x15, 0xe7, 0x52, 0x0e, 0x0b, 0xfd, + 0x04, 0x7c, 0x41, 0x1f, 0xc9, 0xd4, 0x0b, 0x75, 0xa5, 0x00, 0x2d, 0xda, 0x2c, 0x80, 0x02, 0xb1, + 0x85, 0xf7, 0xd6, 0x24, 0xb1, 0x89, 0x85, 0x2c, 0x08, 0xae, 0x3c, 0x1b, 0xb0, 0x2a, 0xc4, 0xd8, + 0x65, 0x4a, 0x5e, 0xe6, 0x25, 0x9e, 0x93, 0xba, 0xca, 0x7f, 0x0d, 0x92, 0x00, 0x2a, 0x56, 0xb0, + 0xfd, 0xb0, 0x8e, 0x6f, 0xb3, 0x5d, 0x2f, 0xd1, 0x49, 0x4d, 0xc3, 0x88, 0x92, 0x9f, 0x4c, 0xad, + 0xad, 0xb5, 0x82, 0xc0, 0x0f, 0x91, 0xd5, 0x00, 0xc8, 0xe9, 0x88, 0xc0, 0x2a, 0x2b, 0xa3, 0x66, + 0xb2, 0x40, 0xf6, 0xaa, 0x81, 0xb1, 0x7a, 0xa7, 0x35, 0xc5, 0x4a, 0x4b, 0x29, 0x73, 0xc9, 0x75, + 0xba, 0xd7, 0x10, 0x24, 0x29, 0x74, 0xb2, 0x58, 0xc9, 0xf7, 0xd4, 0x71, 0x82, 0x2e, 0x14, 0x8b, + 0x3b, 0xbf, 0x35, 0x9b, 0xbb, 0xe3, 0x8b, 0x75, 0xed, 0x3a, 0xa1, 0x97, 0xa5, 0xe3, 0x08, 0x8e, + 0xb8, 0x63, 0x08, 0xc1, 0x8b, 0xc9, 0xe6, 0xfd, 0x78, 0x82, 0xc9, 0xe6, 0x74, 0x0d, 0x05, 0xe5, + 0xcb, 0xd0, 0xf7, 0xae, 0x84, 0xa0, 0x1c, 0x4e, 0x26, 0xba, 0x33, 0xd7, 0x04, 0x3c, 0x9f, 0xd8, + 0xe2, 0x61, 0x87, 0x2d, 0x27, 0x21, 0xd5, 0x7f, 0x19, 0xd5, 0x75, 0x5d, 0x57, 0x77, 0x5c, 0xd4, + 0x68, 0xd5, 0x7d, 0x53, 0x49, 0xc8, 0x2a, 0xeb, 0xe2, 0x56, 0x2a, 0xe6, 0xee, 0xfe, 0x8e, 0xdf, + 0x58, 0xdf, 0x45, 0x8d, 0x5d, 0x11, 0xab, 0xaf, 0x54, 0x20, 0x20, 0x16, 0x0a, 0x7d, 0xad, 0xda, + 0x07, 0x7e, 0xa1, 0x8a, 0xec, 0xb2, 0xdc, 0x20, 0x10, 0x0a, 0x41, 0xeb, 0xa7, 0x1b, 0x8f, 0xd4, + 0xcf, 0xc1, 0xcd, 0x06, 0x35, 0x1b, 0xb7, 0x9d, 0xa5, 0xac, 0xf5, 0x22, 0xa5, 0x24, 0xdc, 0xec, + 0x39, 0x20, 0x01, 0xe4, 0x22, 0x85, 0xae, 0xba, 0x5a, 0x3d, 0x82, 0xde, 0xd9, 0x07, 0x6a, 0xc5, + 0xde, 0x27, 0x8b, 0x2a, 0x75, 0x5a, 0xb9, 0x56, 0x90, 0xd0, 0x7c, 0x57, 0x86, 0xa6, 0x95, 0xaa, + 0xbc, 0xf9, 0xb3, 0x2c, 0x5d, 0xd0, 0x00, 0x08, 0xc8, 0x7a, 0x74, 0xfc, 0x20, 0x30, 0xc1, 0xd6, + 0x00, 0x6b, 0x9d, 0x49, 0xc5, 0x74, 0xe5, 0x30, 0xb3, 0x88, 0x46, 0xdb, 0xa9, 0x1c, 0x03, 0x43, + 0xc4, 0x82, 0x20, 0x07, 0x0e, 0x00, 0x1a, 0x06, 0xc3, 0xb2, 0x85, 0x60, 0x6d, 0x2d, 0xe3, 0x8a, + 0x90, 0xc9, 0x30, 0x72, 0xf9, 0x9b, 0x9e, 0x03, 0xe5, 0x45, 0x64, 0x4d, 0x5c, 0x48, 0x40, 0x64, + 0xb1, 0x82, 0xea, 0x1b, 0x23, 0x1c, 0x3e, 0xb2, 0xd2, 0x0f, 0xf8, 0x5c, 0xa8, 0x4e, 0x27, 0x89, + 0x03, 0x56, 0x79, 0xfc, 0x9a, 0x8a, 0x96, 0x04, 0x80, 0xa3, 0x2d, 0x8a, 0x31, 0x22, 0x41, 0xc6, + 0xaf, 0xc8, 0x96, 0x0c, 0xb0, 0x1c, 0x31, 0x28, 0x22, 0x84, 0xd7, 0x73, 0x0d, 0x3e, 0xa3, 0x76, + 0xfa, 0xf6, 0x82, 0x7c, 0xa6, 0x25, 0x2c, 0x64, 0xaa, 0x17, 0xcb, 0x17, 0x7a, 0x18, 0xa9, 0x76, + 0x1a, 0x20, 0x50, 0x26, 0x13, 0x09, 0xa6, 0x27, 0x26, 0x2f, 0x31, 0x3d, 0x31, 0x7e, 0x24, 0x48, + 0x42, 0xa2, 0xcc, 0xff, 0x68, 0xa4, 0x6f, 0x2f, 0xc4, 0x44, 0x49, 0xe8, 0xb0, 0xbc, 0xe1, 0x77, + 0xc4, 0x04, 0x06, 0x0a, 0xd9, 0x8a, 0x0e, 0x0d, 0x70, 0x9d, 0x8e, 0xc9, 0x1f, 0x29, 0xbc, 0x5c, + 0xfe, 0x44, 0x79, 0x93, 0x25, 0xc2, 0x05, 0x38, 0xee, 0x51, 0x49, 0x14, 0x54, 0x3e, 0xc3, 0xd0, + 0x44, 0xf5, 0xf5, 0x79, 0xba, 0xa6, 0x89, 0xea, 0xd7, 0xd6, 0xab, 0xb2, 0x3b, 0xbd, 0x75, 0xd7, + 0xd1, 0x18, 0xf9, 0xeb, 0xe9, 0xa6, 0xdb, 0x7e, 0x7a, 0xfa, 0x69, 0xb6, 0xdb, 0xe7, 0x29, 0x13, + 0xea, 0x4c, 0xb6, 0xb9, 0x2e, 0xff, 0xa3, 0xf7, 0x84, 0x3e, 0xba, 0xf9, 0x69, 0x24, 0x92, 0x58, + 0x43, 0xf5, 0x67, 0xd7, 0x4b, 0xf0, 0x5d, 0x55, 0xf1, 0x58, 0xae, 0x25, 0xf0, 0x80, 0x27, 0x1d, + 0x7b, 0x88, 0x7e, 0xeb, 0x2e, 0x11, 0x85, 0x27, 0xe8, 0xc9, 0x09, 0x5c, 0xfc, 0xeb, 0xf5, 0x5c, + 0x5c, 0x5d, 0xbc, 0x22, 0x14, 0xbd, 0x9d, 0x42, 0xd4, 0x04, 0xa3, 0x93, 0xf6, 0xcc, 0x44, 0x45, + 0xc2, 0xd6, 0xaa, 0x0d, 0x52, 0xdb, 0x00, 0x02, 0x15, 0x42, 0xa8, 0x5d, 0x05, 0x84, 0x49, 0x33, + 0x61, 0xb4, 0x60, 0x27, 0xce, 0xc9, 0x80, 0x23, 0xad, 0x18, 0xc4, 0xdf, 0xb7, 0xfb, 0xec, 0x34, + 0x96, 0x61, 0x90, 0xfb, 0x8e, 0xf0, 0x4f, 0xa4, 0x4e, 0x39, 0x83, 0x8f, 0x74, 0x4e, 0x0b, 0x07, + 0x62, 0x27, 0x76, 0xf5, 0x7f, 0x10, 0x0a, 0x02, 0x90, 0x2d, 0x79, 0x00, 0x00, 0x80, 0x22, 0x7d, + 0x4d, 0x46, 0x16, 0x96, 0x0d, 0x81, 0x86, 0x0d, 0x14, 0x70, 0x27, 0x0e, 0x21, 0xfe, 0x16, 0xce, + 0x1e, 0x40, 0x80, 0x8d, 0x42, 0x8f, 0x80, 0xc6, 0x00, 0x22, 0x04, 0x43, 0xd6, 0xed, 0x39, 0xe7, + 0x7b, 0x78, 0xe3, 0x1c, 0xe1, 0xd6, 0x2c, 0x09, 0x60, 0x72, 0xa2, 0x01, 0xf7, 0xea, 0xaa, 0xb7, + 0xfc, 0x4f, 0x28, 0xfe, 0xfc, 0x40, 0x29, 0x04, 0xc6, 0x21, 0x8b, 0x4a, 0x4e, 0xb5, 0xbf, 0x12, + 0x24, 0x79, 0x44, 0xb8, 0xfc, 0xef, 0x9b, 0x14, 0xee, 0x78, 0x80, 0x80, 0x2d, 0xb5, 0x7a, 0x6c, + 0x1a, 0xfb, 0x89, 0x08, 0xba, 0xd7, 0xc2, 0x23, 0xf5, 0x55, 0x38, 0x30, 0x74, 0xe0, 0xff, 0xa9, + 0x42, 0xc6, 0xc4, 0xee, 0x70, 0x80, 0xc1, 0x97, 0x78, 0x12, 0x78, 0xcf, 0xa4, 0xe4, 0xe0, 0xe7, + 0x29, 0xb2, 0x3f, 0xe4, 0x55, 0x77, 0x4b, 0xcc, 0x7a, 0x1c, 0x06, 0x30, 0x76, 0xc2, 0x2e, 0x52, + 0xcf, 0x84, 0x01, 0x31, 0x56, 0xc1, 0x83, 0x3d, 0xf0, 0xa0, 0xd5, 0x24, 0xa0, 0xfc, 0xef, 0x94, + 0x2a, 0xe2, 0xb7, 0x7f, 0x44, 0x7b, 0xea, 0xff, 0x47, 0x45, 0xb7, 0xc1, 0x3c, 0xac, 0x4a, 0xc4, + 0xac, 0x4a, 0xc5, 0xa4, 0x1e, 0xb4, 0x69, 0xfb, 0xbb, 0xbf, 0xab, 0xcf, 0xca, 0x2a, 0xef, 0xf5, + 0x6a, 0xe8, 0x4b, 0xfc, 0x13, 0x08, 0x77, 0x77, 0x77, 0x55, 0x62, 0x7c, 0x4b, 0x3d, 0xef, 0xea, + 0xf3, 0xc1, 0x40, 0x40, 0x58, 0xcc, 0xb8, 0xf7, 0x15, 0x42, 0x06, 0x58, 0x62, 0x14, 0x36, 0xef, + 0x71, 0x58, 0xfd, 0x42, 0xb0, 0xe8, 0xad, 0x3f, 0x66, 0xa4, 0xdc, 0x70, 0xf1, 0x5b, 0x78, 0x01, + 0xcf, 0x7c, 0x20, 0x51, 0x58, 0x51, 0xd1, 0xf9, 0x51, 0xb5, 0x10, 0x4b, 0x6e, 0x04, 0x61, 0x5b, + 0xa8, 0xdd, 0xa5, 0xfc, 0x10, 0x84, 0x0a, 0x7c, 0xaa, 0xb7, 0xbb, 0xbc, 0xb4, 0xc4, 0x89, 0x05, + 0x44, 0x77, 0xc7, 0x4b, 0xcd, 0xa0, 0xb4, 0x84, 0xd4, 0x5d, 0x36, 0xc8, 0xb8, 0xf7, 0xc4, 0xd8, + 0x28, 0x5a, 0xf7, 0x12, 0x10, 0x0a, 0x08, 0xec, 0xff, 0x7f, 0x3f, 0xcb, 0x36, 0xfd, 0xeb, 0xf1, + 0x2e, 0x0a, 0xc1, 0x8f, 0xf1, 0xd7, 0xa1, 0x40, 0x5c, 0x4a, 0x5d, 0xe1, 0x11, 0x97, 0xec, 0x13, + 0x8a, 0x9f, 0x60, 0xa8, 0xe8, 0x27, 0x2c, 0xd5, 0x18, 0x05, 0x34, 0xf8, 0xf3, 0x76, 0x80, 0x5d, + 0xa7, 0x2b, 0x67, 0x05, 0x98, 0xb9, 0x1c, 0xd6, 0x78, 0x44, 0x12, 0x8d, 0x15, 0xbf, 0xb6, 0x4c, + 0xee, 0x20, 0x20, 0x27, 0x79, 0x3d, 0x2b, 0xfb, 0x2b, 0x47, 0x50, 0xc0, 0x3e, 0x11, 0x12, 0x14, + 0x22, 0xea, 0xd5, 0x55, 0x45, 0xd5, 0x2b, 0xb8, 0xaf, 0xb0, 0xb6, 0x41, 0x82, 0xbf, 0xf5, 0xf5, + 0xc4, 0x44, 0xd5, 0x52, 0x48, 0x56, 0x21, 0x63, 0xc1, 0x00, 0x40, 0x64, 0x64, 0x7c, 0xa5, 0x50, + 0x1a, 0x45, 0x9a, 0xeb, 0x24, 0x79, 0x4f, 0x0b, 0x03, 0xa1, 0xf3, 0x83, 0x82, 0xe5, 0xea, 0x23, + 0x83, 0xfe, 0x2c, 0x97, 0x15, 0xd4, 0xeb, 0xf0, 0xa0, 0xa3, 0xcd, 0x45, 0xd2, 0xf3, 0x8b, 0x07, + 0x3c, 0x43, 0x88, 0xbc, 0xb5, 0x5d, 0xcb, 0x3a, 0xc5, 0xce, 0x39, 0x48, 0xf0, 0xf3, 0xce, 0x37, + 0x10, 0x18, 0x05, 0x7b, 0x96, 0xdc, 0x75, 0x4b, 0x19, 0x78, 0x6f, 0xf3, 0xbb, 0xe4, 0x5b, 0x6f, + 0x0c, 0x02, 0x80, 0x8b, 0xce, 0xc3, 0xbb, 0x9e, 0x99, 0x52, 0x78, 0x80, 0xc7, 0x86, 0x23, 0x39, + 0xea, 0x94, 0x98, 0xbe, 0x10, 0xe0, 0x90, 0x45, 0x21, 0x58, 0x81, 0xc1, 0x6a, 0x87, 0x04, 0x00, + 0xb0, 0xd7, 0x15, 0x9f, 0x1c, 0xf9, 0xac, 0xca, 0x8b, 0x8e, 0xc7, 0xe1, 0xec, 0x02, 0xd5, 0xf0, + 0x88, 0xba, 0x32, 0xd5, 0xe3, 0x52, 0x79, 0xff, 0x6e, 0x7e, 0x36, 0x87, 0x9e, 0xdf, 0xc2, 0xf8, + 0x02, 0x94, 0x51, 0x01, 0x87, 0xe8, 0xb1, 0x3d, 0x79, 0x1f, 0x66, 0x0c, 0xec, 0x16, 0xf7, 0xcf, + 0x58, 0x39, 0x81, 0x3b, 0x70, 0xb1, 0xb7, 0xe2, 0xc2, 0xc4, 0x38, 0x0d, 0xcb, 0xe0, 0x90, 0xe3, + 0x3e, 0xef, 0x67, 0xfe, 0x4f, 0xf8, 0x91, 0x0e, 0xab, 0xf0, 0x80, 0x2c, 0x93, 0x20, 0xdb, 0x41, + 0xc5, 0x69, 0x3b, 0x61, 0xb3, 0xc5, 0x64, 0x6a, 0x30, 0x88, 0x76, 0x17, 0x88, 0x00, 0x09, 0x29, + 0x1c, 0x5e, 0x10, 0x41, 0xed, 0xab, 0x81, 0xeb, 0x96, 0x5c, 0x9f, 0x95, 0xf4, 0x56, 0xb5, 0x85, + 0x5e, 0x8a, 0xf9, 0x65, 0x67, 0xbe, 0xb3, 0xde, 0x55, 0x74, 0x2d, 0x5c, 0xaa, 0xe8, 0x3a, 0x5c, + 0x96, 0x19, 0x65, 0x00, 0x7d, 0x87, 0x4e, 0x96, 0xb2, 0x80, 0x56, 0x41, 0x1b, 0xc8, 0xf7, 0x80, + 0xfc, 0x5a, 0xcf, 0x1a, 0x1f, 0x62, 0xd9, 0x76, 0x29, 0x6f, 0xe8, 0xfe, 0x27, 0x70, 0xf9, 0xe5, + 0xe2, 0xe5, 0xea, 0x68, 0x2f, 0xc3, 0x02, 0x42, 0x12, 0x64, 0x95, 0x5b, 0x27, 0x00, 0x06, 0x83, + 0xa7, 0xc0, 0xb0, 0x31, 0xd0, 0xa1, 0x30, 0x83, 0x59, 0x34, 0x3e, 0xd4, 0xe7, 0x31, 0x01, 0x92, + 0x95, 0x6f, 0xcf, 0x84, 0xce, 0x84, 0xb5, 0xd4, 0xc4, 0x18, 0x5d, 0xc0, 0x35, 0xb1, 0xcf, 0x51, + 0x9b, 0x95, 0x37, 0x3f, 0x33, 0x0a, 0x6e, 0x39, 0x85, 0x37, 0x3f, 0xd7, 0x12, 0x08, 0x47, 0x4b, + 0xa1, 0xa3, 0xf3, 0xde, 0xca, 0x31, 0x8a, 0x62, 0xe6, 0xcf, 0x15, 0xdd, 0xf7, 0x6f, 0x11, 0x1f, + 0xab, 0x1b, 0x27, 0x28, 0x62, 0x94, 0xf4, 0xce, 0x25, 0xf8, 0x21, 0x05, 0x24, 0xac, 0x7b, 0xe0, + 0xef, 0xcb, 0xd9, 0xcf, 0x72, 0x66, 0xdb, 0xa1, 0xbf, 0x08, 0x46, 0x08, 0x3e, 0xc4, 0x65, 0xe2, + 0xe1, 0xd8, 0xd4, 0x94, 0x00, 0x08, 0xfa, 0x5f, 0x6a, 0xaa, 0xab, 0x3e, 0x22, 0x14, 0x21, 0xc3, + 0x4b, 0x2f, 0x3e, 0x71, 0x46, 0x2b, 0x13, 0xa1, 0x7a, 0xa8, 0x8f, 0x28, 0xfe, 0x93, 0xb8, 0xde, + 0x18, 0x05, 0x05, 0x0b, 0x33, 0x52, 0xdb, 0x80, 0x39, 0x15, 0x45, 0xe2, 0xe1, 0x70, 0x35, 0x75, + 0x48, 0xf7, 0xcc, 0xb1, 0x20, 0x80, 0x58, 0xd7, 0x72, 0x2b, 0x73, 0x38, 0xdf, 0x67, 0xeb, 0x94, + 0x4f, 0x04, 0x14, 0x65, 0xa6, 0x7b, 0x3d, 0xfa, 0xd5, 0x22, 0xf2, 0x69, 0x37, 0xbe, 0x08, 0xee, + 0xff, 0x7c, 0x97, 0x7f, 0xcf, 0x8a, 0xcc, 0xd5, 0x6e, 0x3f, 0xf5, 0xaf, 0xa2, 0x57, 0xcd, 0xab, + 0xd7, 0x13, 0x3e, 0x35, 0xea, 0xab, 0xbe, 0x92, 0x5e, 0xe7, 0xc6, 0xbf, 0x25, 0xdf, 0xf3, 0xd5, + 0x34, 0xdb, 0x6f, 0xfd, 0xda, 0xb5, 0xc2, 0x22, 0x43, 0x17, 0x69, 0x45, 0xcd, 0x95, 0x0a, 0x36, + 0x87, 0xc1, 0x08, 0x90, 0xa0, 0x61, 0x65, 0x4c, 0x9c, 0x73, 0x7b, 0x6e, 0x7f, 0xc1, 0x00, 0x52, + 0x6a, 0x0a, 0x30, 0x7f, 0x88, 0xc5, 0x00, 0x3b, 0x9a, 0xce, 0x6c, 0x1f, 0xe0, 0x6b, 0xf2, 0x6f, + 0x1e, 0x4b, 0xdc, 0x41, 0x92, 0xcc, 0x5f, 0x0f, 0x08, 0x85, 0x21, 0xd0, 0x14, 0x67, 0xe6, 0x42, + 0x0d, 0x64, 0xa5, 0x12, 0xe1, 0xe3, 0x1d, 0xd1, 0xba, 0xcb, 0x59, 0x78, 0x93, 0x87, 0xf1, 0xb0, + 0xd9, 0x0a, 0x00, 0x1c, 0x58, 0x89, 0xa0, 0xf2, 0xca, 0x28, 0x79, 0x78, 0x9a, 0x71, 0xa6, 0xf6, + 0x2b, 0x74, 0xc5, 0x6d, 0xe5, 0xb1, 0x5b, 0x8a, 0x37, 0x1b, 0x11, 0x7e, 0xb5, 0xbd, 0xf0, 0x88, + 0x10, 0x01, 0x48, 0xa0, 0xf9, 0xaa, 0xf4, 0x33, 0xc7, 0xe7, 0x0f, 0x12, 0x3c, 0x28, 0xc2, 0x37, + 0xe1, 0x98, 0x27, 0xaa, 0x60, 0x2a, 0x77, 0xd8, 0x92, 0xd3, 0x64, 0x73, 0x9e, 0x4c, 0x6f, 0x2f, + 0x0c, 0xb8, 0x03, 0xf8, 0x69, 0x38, 0x06, 0x89, 0x2e, 0xfc, 0x52, 0x2e, 0xa2, 0xe4, 0xae, 0x33, + 0xe0, 0x95, 0xc2, 0xfc, 0x09, 0xf3, 0xfc, 0x4f, 0x9f, 0xe5, 0x8e, 0xcb, 0x6e, 0x89, 0x5c, 0x18, + 0x00, 0x90, 0x1a, 0x41, 0x79, 0x28, 0x88, 0x01, 0x51, 0xe0, 0xe3, 0x19, 0x2c, 0x40, 0x3c, 0x0e, + 0x30, 0x03, 0x52, 0x7a, 0x87, 0x52, 0x55, 0x6a, 0xdd, 0x25, 0x15, 0x88, 0xf0, 0x03, 0xce, 0x00, + 0x3c, 0x9c, 0x0d, 0x0e, 0x0f, 0x18, 0x30, 0x64, 0x17, 0xde, 0xef, 0x0f, 0x10, 0x80, 0x13, 0x17, + 0xcb, 0xa0, 0xc2, 0xa0, 0x9c, 0x4c, 0x38, 0x2f, 0x2d, 0x88, 0xf1, 0x74, 0xce, 0xf8, 0xed, 0x9c, + 0x7f, 0xe6, 0x62, 0xf3, 0x4b, 0xf5, 0xf0, 0xdb, 0x81, 0x76, 0xc7, 0x94, 0xc3, 0x6e, 0x35, 0x0c, + 0x73, 0x83, 0x70, 0x7f, 0x33, 0xb0, 0x3b, 0x0c, 0xec, 0x22, 0xb0, 0xa9, 0xa1, 0x66, 0x3a, 0x2e, + 0x84, 0x0a, 0xc4, 0x47, 0x61, 0xb1, 0x27, 0x68, 0xaf, 0xff, 0x12, 0x11, 0x09, 0x89, 0x78, 0x15, + 0xdb, 0xb7, 0x5a, 0xc3, 0x4a, 0x00, 0xc4, 0x3d, 0x0e, 0xa7, 0xfb, 0x7f, 0x6f, 0xdb, 0x7c, 0xab, + 0x38, 0x80, 0x40, 0x0a, 0x8a, 0xb3, 0x51, 0x4c, 0x53, 0x51, 0x71, 0x0b, 0x16, 0xe2, 0xba, 0xe2, + 0x42, 0x23, 0xed, 0x25, 0xf0, 0x83, 0xc9, 0x9c, 0x1d, 0xa2, 0x2c, 0xe3, 0x06, 0xf7, 0xf0, 0x99, + 0x35, 0x55, 0xaa, 0xf8, 0x23, 0xab, 0x4d, 0x5f, 0xe6, 0xdd, 0x37, 0xc2, 0x01, 0x90, 0x59, 0x1d, + 0x52, 0xdc, 0xbd, 0x44, 0xbf, 0x36, 0x4a, 0x56, 0x71, 0x01, 0x91, 0x3e, 0x7b, 0xc6, 0x19, 0x4e, + 0x10, 0x8c, 0xa7, 0x81, 0x68, 0xe4, 0x20, 0xa8, 0x8c, 0x83, 0x80, 0xb3, 0x3d, 0x13, 0x09, 0x41, + 0x08, 0x68, 0x0c, 0x39, 0x89, 0x0e, 0xa1, 0x0e, 0x40, 0xc4, 0x45, 0x10, 0xae, 0xcc, 0x60, 0xc7, + 0xf0, 0xa0, 0x84, 0xc3, 0xc7, 0x8c, 0x0f, 0x0c, 0x2c, 0xc8, 0x44, 0x1f, 0xe7, 0x7c, 0x0f, 0x02, + 0x71, 0x1c, 0x41, 0x7b, 0x8b, 0x25, 0x86, 0xbb, 0xea, 0x5e, 0x3b, 0x19, 0x0e, 0x18, 0x08, 0x17, + 0x2d, 0xb9, 0x63, 0x0a, 0xb8, 0x03, 0x18, 0x94, 0x2d, 0xf3, 0x87, 0x86, 0x02, 0xbf, 0x04, 0x61, + 0x5c, 0x56, 0x2b, 0x47, 0x0f, 0xd8, 0xd9, 0x20, 0x48, 0x6f, 0x82, 0xb0, 0x48, 0xac, 0x8d, 0x1d, + 0xa7, 0x52, 0x46, 0x86, 0xc8, 0x8c, 0xb8, 0xf1, 0x19, 0x75, 0xaa, 0xb7, 0x47, 0xe1, 0x8b, 0x7b, + 0x6d, 0xc7, 0xec, 0xf9, 0x51, 0xd9, 0x8c, 0xf7, 0x88, 0xe8, 0x27, 0x5f, 0x09, 0x91, 0xed, 0x34, + 0x92, 0x49, 0x25, 0xe0, 0xb6, 0x81, 0xa0, 0x6d, 0x34, 0x92, 0x49, 0x25, 0xe3, 0xea, 0xc5, 0x74, + 0x4a, 0xbe, 0x30, 0x5b, 0xba, 0xaa, 0xab, 0xbe, 0xef, 0xbb, 0xfa, 0x23, 0x3c, 0x41, 0x24, 0xa1, + 0x29, 0xae, 0x8c, 0x44, 0x54, 0xba, 0x2b, 0xd0, 0x6d, 0x10, 0x00, 0x44, 0x7a, 0x54, 0xb3, 0x0b, + 0xbf, 0xef, 0xf7, 0xbd, 0xf2, 0x70, 0x81, 0x11, 0x86, 0x85, 0x1b, 0xb4, 0x1b, 0x5c, 0x0d, 0xae, + 0x1c, 0x29, 0xe7, 0xe7, 0xe3, 0xaf, 0xf0, 0xc0, 0x50, 0x86, 0xb3, 0x81, 0xe2, 0x80, 0xd3, 0x8c, + 0x87, 0x8e, 0x6f, 0xd8, 0x91, 0xc7, 0x73, 0x37, 0x65, 0xe5, 0xe2, 0xea, 0xbe, 0xc7, 0x38, 0x2e, + 0xa8, 0x91, 0xf1, 0xc1, 0x08, 0x40, 0x29, 0x3e, 0x56, 0xc3, 0x97, 0x97, 0xa4, 0x92, 0x72, 0xf7, + 0x4a, 0x2b, 0x12, 0xc1, 0xf0, 0xd4, 0xa0, 0x50, 0x41, 0x4a, 0x74, 0x16, 0x33, 0xf3, 0x9f, 0xcb, + 0x46, 0xd7, 0xc5, 0x71, 0x47, 0x3b, 0x88, 0x8c, 0x10, 0x4e, 0x2a, 0x7b, 0x37, 0x63, 0x09, 0x05, + 0x01, 0xfe, 0xec, 0xd2, 0xdb, 0x79, 0xef, 0x75, 0xd7, 0x11, 0x62, 0x56, 0xbc, 0x31, 0xc3, 0x4e, + 0x00, 0x29, 0x3c, 0x98, 0x02, 0x4e, 0x53, 0x8e, 0x25, 0x95, 0x51, 0x58, 0xad, 0xc5, 0x7a, 0x71, + 0x5b, 0xbf, 0xb0, 0xd1, 0x20, 0x0e, 0xe5, 0xa1, 0x3a, 0xb1, 0x8c, 0xe2, 0xb5, 0x75, 0x8e, 0x34, + 0xd3, 0x7e, 0xaa, 0xab, 0x46, 0x3c, 0x22, 0x19, 0x0a, 0x18, 0x98, 0x32, 0x1d, 0x31, 0x2c, 0x32, + 0xc3, 0x26, 0x55, 0xfb, 0x97, 0x44, 0x86, 0x85, 0x81, 0xb3, 0x0b, 0x33, 0x66, 0xa1, 0x77, 0xe2, + 0x02, 0x03, 0x2c, 0x60, 0x9e, 0xb9, 0x2d, 0x4f, 0xe4, 0x97, 0xb3, 0x96, 0xd3, 0x73, 0xd0, 0xb6, + 0x58, 0xc5, 0x1e, 0x20, 0x48, 0x26, 0x2b, 0x05, 0x27, 0xb9, 0x22, 0xfe, 0xc7, 0x12, 0x01, 0x13, + 0xed, 0x2f, 0x9f, 0x4b, 0x82, 0x01, 0x21, 0x42, 0x8f, 0x35, 0xf1, 0xd6, 0x5e, 0x2e, 0x7e, 0x5b, + 0xb8, 0x55, 0xa4, 0x9e, 0xe4, 0xd7, 0x86, 0x01, 0x46, 0xee, 0x21, 0xc7, 0xe9, 0x45, 0xe1, 0x10, + 0x56, 0x6b, 0xcb, 0xcb, 0xdb, 0xdb, 0x9e, 0xab, 0x5e, 0x19, 0x04, 0x42, 0x5a, 0xac, 0xe8, 0x77, + 0xe1, 0x12, 0x2c, 0x8a, 0x29, 0x9d, 0x45, 0xfb, 0x87, 0x05, 0x4c, 0x23, 0x10, 0x47, 0x6f, 0x79, + 0x77, 0x89, 0x85, 0x3e, 0x66, 0x2e, 0x27, 0x8e, 0xc7, 0x5f, 0xce, 0xfa, 0x32, 0x9b, 0xef, 0xdc, + 0x10, 0xc2, 0x82, 0x40, 0xd6, 0xa4, 0xba, 0x06, 0xd0, 0x87, 0x04, 0x38, 0x3b, 0xe1, 0x6a, 0x43, + 0x11, 0xa2, 0x51, 0x33, 0xbb, 0x19, 0x72, 0x75, 0x61, 0xd5, 0x01, 0xd5, 0x61, 0xb7, 0xd5, 0xab, + 0xf4, 0xe9, 0xff, 0x8d, 0x05, 0x11, 0x6d, 0xb7, 0xf8, 0x66, 0x14, 0x19, 0x2d, 0x54, 0x2e, 0x5e, + 0x35, 0x8f, 0x8f, 0x07, 0x9a, 0xc8, 0x3c, 0xe5, 0x33, 0x8a, 0x0a, 0xaa, 0x2f, 0x28, 0x09, 0x70, + 0x56, 0x5b, 0x84, 0x42, 0x00, 0xae, 0x7b, 0xfc, 0xb4, 0x2d, 0xda, 0x03, 0xc1, 0x55, 0x3e, 0x89, + 0x8e, 0x4f, 0x01, 0x81, 0xc3, 0x8d, 0xa7, 0xcb, 0x8d, 0xef, 0xb8, 0xd2, 0xb0, 0xcc, 0xa1, 0x17, + 0xa5, 0x3b, 0x9b, 0xf3, 0x0e, 0x4d, 0x24, 0x8b, 0x9e, 0x24, 0x8d, 0x4f, 0xee, 0x8a, 0x2f, 0xe1, + 0xd3, 0xbb, 0xe6, 0x8a, 0xe2, 0xd0, 0xce, 0xc3, 0x47, 0xcd, 0x5c, 0xe9, 0x51, 0x42, 0xff, 0x0b, + 0xc7, 0x28, 0xd6, 0x1c, 0xcc, 0x53, 0xea, 0x6f, 0xc5, 0x18, 0xed, 0x94, 0xff, 0x82, 0x02, 0x6c, + 0x71, 0x9b, 0x71, 0xb3, 0x84, 0x56, 0xa8, 0x2a, 0x08, 0x51, 0xc3, 0x97, 0x7f, 0xf8, 0x9a, 0x5a, + 0xd1, 0x31, 0xaf, 0x7b, 0xfb, 0xbf, 0x98, 0x26, 0xee, 0xaa, 0xba, 0x11, 0x07, 0xcf, 0x16, 0xb7, + 0x1a, 0x96, 0xc3, 0x3f, 0xe8, 0xdf, 0x3e, 0x7f, 0x5a, 0x15, 0x48, 0x24, 0x17, 0xbe, 0x63, 0xe9, + 0x25, 0xef, 0x5a, 0xae, 0xa9, 0xd2, 0xea, 0xe7, 0xc1, 0x1d, 0xf5, 0x73, 0xea, 0xe5, 0xf4, 0x77, + 0x3e, 0x08, 0xee, 0xfb, 0x9f, 0x05, 0xb4, 0xaf, 0x5d, 0xac, 0xb8, 0x88, 0x27, 0x35, 0x55, 0x54, + 0x4d, 0x91, 0xae, 0x8c, 0x1e, 0x60, 0x8d, 0xc4, 0x06, 0x02, 0x86, 0x10, 0xf1, 0x20, 0x38, 0x48, + 0x0e, 0x17, 0xa9, 0xfb, 0xa1, 0xa9, 0xe0, 0xfc, 0xb7, 0x53, 0x62, 0x97, 0xbb, 0xc3, 0x23, 0x3b, + 0xa4, 0xdd, 0x4d, 0x85, 0xc8, 0x7e, 0x6e, 0xfd, 0x78, 0x90, 0x4d, 0x8a, 0xf6, 0xab, 0xee, 0x11, + 0x08, 0x04, 0xb6, 0xd5, 0x74, 0xdf, 0x86, 0x42, 0x91, 0x23, 0x82, 0xbc, 0x79, 0x59, 0x9b, 0xb3, + 0xb5, 0x0b, 0x1a, 0xcf, 0x49, 0x84, 0x62, 0x0f, 0xf2, 0xc9, 0xc1, 0x80, 0x7d, 0xe1, 0x96, 0x48, + 0xdf, 0xfe, 0x24, 0x20, 0x61, 0x2a, 0x2e, 0xa2, 0x39, 0x86, 0x44, 0x8f, 0x8a, 0xdf, 0x67, 0x55, + 0xa8, 0xdd, 0x0b, 0xf0, 0xc0, 0x80, 0x56, 0x43, 0xe3, 0x19, 0x66, 0x20, 0x84, 0x01, 0x10, 0x01, + 0x0c, 0x05, 0x01, 0x6c, 0x13, 0x04, 0x60, 0xf1, 0xd1, 0x9e, 0x17, 0xd7, 0x08, 0x42, 0x96, 0x71, + 0x2f, 0x3f, 0xa9, 0x3e, 0x5b, 0xa0, 0xcf, 0x9e, 0x6c, 0x35, 0x27, 0xb0, 0xbb, 0x84, 0xf0, 0xad, + 0x43, 0xd7, 0x9b, 0x6d, 0xe7, 0x7f, 0xe5, 0xf2, 0xcd, 0xc3, 0x21, 0x90, 0xa1, 0xc2, 0xcb, 0x39, + 0x25, 0x15, 0x7b, 0x01, 0xd8, 0xd1, 0x13, 0x35, 0xd9, 0x60, 0xcf, 0x1e, 0x7e, 0x5b, 0x2d, 0x8a, + 0xdd, 0xd2, 0xac, 0x33, 0x05, 0x54, 0xa8, 0x84, 0xa2, 0xb9, 0x61, 0xe6, 0xc8, 0xbb, 0xb8, 0x44, + 0x33, 0xe2, 0x01, 0x5d, 0xc6, 0xd0, 0x37, 0x06, 0x7f, 0x5d, 0xb4, 0xc0, 0xed, 0xd1, 0xd6, 0xd3, + 0xb0, 0xd1, 0x0c, 0x00, 0x9f, 0xac, 0x4d, 0x2b, 0xe4, 0xdf, 0xd3, 0x4f, 0xae, 0xa9, 0xa7, 0x8e, + 0xde, 0x24, 0x74, 0xb6, 0xd0, 0x84, 0xc6, 0x55, 0x4d, 0x93, 0x5a, 0x8f, 0xe9, 0x38, 0x91, 0x20, + 0x84, 0x5e, 0x6c, 0x5f, 0xf8, 0x80, 0xa0, 0xa8, 0x8e, 0x5f, 0x25, 0xfa, 0x33, 0xc3, 0x77, 0x69, + 0x35, 0x58, 0xd2, 0xcd, 0x52, 0xcb, 0xe3, 0x38, 0xd6, 0x19, 0xea, 0xcc, 0xc2, 0xf9, 0xb2, 0x63, + 0x74, 0xad, 0xfc, 0x40, 0x60, 0x28, 0x7b, 0xdc, 0x6f, 0x34, 0xde, 0xad, 0x63, 0x27, 0xb2, 0xf1, + 0x75, 0x17, 0xec, 0x36, 0xc4, 0x80, 0xba, 0x25, 0xe9, 0xfb, 0xf1, 0xdb, 0x84, 0xcd, 0xc5, 0xb7, + 0x09, 0x9b, 0x94, 0x54, 0x4b, 0x6e, 0x13, 0x37, 0x16, 0xdc, 0x26, 0x6e, 0x1e, 0xbd, 0xff, 0x0b, + 0xcc, 0x27, 0x0e, 0x62, 0x42, 0xbd, 0x7e, 0xeb, 0xe9, 0x7e, 0x4e, 0xd1, 0x92, 0x6a, 0x34, 0xc7, + 0x71, 0xca, 0x00, 0xce, 0xa7, 0x4c, 0x1f, 0x44, 0x62, 0xb1, 0x30, 0xa0, 0xa2, 0xf3, 0xf4, 0x53, + 0xb4, 0x1a, 0xab, 0x05, 0x06, 0x06, 0x81, 0x35, 0xf1, 0xf1, 0x1c, 0x3b, 0xce, 0x41, 0xd9, 0x87, + 0x28, 0x8f, 0xcb, 0x88, 0x08, 0x05, 0x09, 0xd4, 0xa4, 0xef, 0x80, 0xb9, 0xb2, 0x26, 0x61, 0x7c, + 0x8b, 0xa8, 0xae, 0x21, 0x6c, 0x1e, 0x3c, 0x1a, 0xac, 0x78, 0xbe, 0x25, 0xef, 0x7b, 0xbe, 0x1f, + 0x8e, 0x61, 0x6e, 0x3a, 0xa8, 0xcb, 0x37, 0x51, 0xc7, 0x5a, 0x68, 0x3a, 0x78, 0x69, 0x9a, 0xb1, + 0x7f, 0x87, 0xf6, 0x99, 0x6b, 0xaf, 0x5e, 0x9e, 0x6a, 0x33, 0xdc, 0x35, 0x49, 0x7c, 0xdc, 0x15, + 0x96, 0xae, 0xd5, 0xa6, 0x9a, 0x6e, 0xde, 0x0f, 0x9e, 0xa2, 0xa8, 0x55, 0x7e, 0x27, 0x82, 0x32, + 0xad, 0xfa, 0x9b, 0x9e, 0xa9, 0xa6, 0x53, 0x50, 0x2f, 0xe0, 0x80, 0x6e, 0xb5, 0x29, 0xd4, 0xf0, + 0x79, 0xc3, 0xcf, 0x58, 0xb9, 0xb8, 0xff, 0xa5, 0x01, 0x34, 0x59, 0xef, 0xc2, 0x01, 0x39, 0x86, + 0xe0, 0xdd, 0x2a, 0x23, 0xf8, 0x71, 0xff, 0x0f, 0x38, 0x12, 0x3c, 0x66, 0x80, 0xe8, 0x6f, 0xef, + 0xed, 0xb7, 0xe2, 0x3c, 0x43, 0xfd, 0x97, 0x86, 0x89, 0x05, 0x07, 0xfb, 0x6f, 0xff, 0x7e, 0x77, + 0x88, 0x04, 0x55, 0x51, 0x4c, 0x47, 0xd7, 0xcd, 0xaa, 0xaf, 0x06, 0x01, 0x4e, 0xb2, 0x6d, 0x72, + 0x0e, 0x4f, 0x88, 0xe2, 0x41, 0x84, 0x33, 0x6b, 0xcd, 0xdd, 0x8d, 0xec, 0x51, 0x02, 0x9f, 0xe3, + 0x88, 0x17, 0x06, 0x85, 0xb3, 0xc1, 0x89, 0x7a, 0x9b, 0xf6, 0xb7, 0x3c, 0xe0, 0xbe, 0x20, 0x22, + 0x3c, 0x49, 0x3a, 0xac, 0x5f, 0xde, 0x32, 0x99, 0x6d, 0x7c, 0x16, 0x75, 0x27, 0xea, 0xda, 0xee, + 0x5c, 0xba, 0xe1, 0x11, 0x01, 0x02, 0x17, 0xd8, 0xdd, 0xdc, 0x79, 0xd0, 0xec, 0x3f, 0xda, 0x5e, + 0x0b, 0x2e, 0xed, 0x49, 0x8a, 0x91, 0xe5, 0x39, 0x6c, 0x54, 0x6b, 0x9f, 0xe0, 0xab, 0x56, 0xd4, + 0xb3, 0x17, 0x52, 0x77, 0xb7, 0x7e, 0xe0, 0xa0, 0x20, 0x09, 0x2b, 0xb7, 0xdc, 0x30, 0x20, 0x16, + 0x55, 0x6a, 0x96, 0x96, 0x5c, 0xbf, 0x12, 0x20, 0x17, 0x09, 0xd5, 0x63, 0xc9, 0x1d, 0x18, 0xaf, + 0x05, 0x82, 0xb9, 0x14, 0x19, 0x46, 0xb4, 0xa5, 0xcc, 0x57, 0xb8, 0x44, 0x48, 0x25, 0xbb, 0x57, + 0x31, 0x05, 0x6b, 0xd8, 0x5e, 0x70, 0xcf, 0x32, 0x92, 0x2d, 0xc3, 0x3d, 0xfe, 0x78, 0x44, 0xb0, + 0x57, 0xf5, 0xf0, 0x58, 0x5a, 0x74, 0xdc, 0xb8, 0xef, 0xce, 0x5f, 0xdf, 0x04, 0x23, 0xa5, 0xf7, + 0xee, 0x26, 0x14, 0x16, 0x31, 0x52, 0x8a, 0xa3, 0x5f, 0xeb, 0x38, 0x80, 0x9c, 0xb0, 0x5b, 0xa9, + 0x79, 0x19, 0x83, 0xb0, 0x83, 0x41, 0xbe, 0xb1, 0xe5, 0xf0, 0x54, 0x5b, 0x0e, 0xb2, 0x08, 0x48, + 0x25, 0xbd, 0xb7, 0x2b, 0x28, 0x52, 0xa6, 0xfd, 0x84, 0xe5, 0x00, 0x9b, 0xb3, 0xce, 0xbf, 0xe9, + 0xfc, 0x2a, 0x2f, 0x4c, 0x91, 0xa2, 0x86, 0xd8, 0x80, 0x21, 0x64, 0xdf, 0x49, 0x37, 0xa4, 0x57, + 0xd1, 0x5b, 0x67, 0xfe, 0x4f, 0x6d, 0xc7, 0xcb, 0xed, 0xe9, 0xf0, 0x50, 0x18, 0x05, 0x11, 0x85, + 0xcb, 0x6e, 0x96, 0xdb, 0x61, 0xa5, 0x00, 0x2d, 0xca, 0x28, 0x33, 0x10, 0x2f, 0x5e, 0xfa, 0x74, + 0xeb, 0x5a, 0xd5, 0xf8, 0x66, 0x34, 0x42, 0x99, 0x81, 0x4c, 0xb3, 0xc1, 0x58, 0xd0, 0x0c, 0xcf, + 0x57, 0x62, 0x98, 0xbc, 0x5c, 0xbc, 0x27, 0xaa, 0xc1, 0x3c, 0x3f, 0x18, 0xa6, 0x10, 0xbf, 0x5f, + 0xf0, 0x88, 0x40, 0x69, 0x0f, 0x00, 0x71, 0xb0, 0x25, 0xb3, 0x26, 0x1c, 0x81, 0xaa, 0xa8, 0xb5, + 0x0f, 0xb0, 0xee, 0x72, 0xa6, 0x82, 0x9c, 0x9c, 0xb1, 0xc6, 0x2b, 0x06, 0x02, 0x89, 0x1e, 0xf8, + 0x3d, 0x76, 0x6c, 0x4b, 0xfe, 0x0b, 0xca, 0x9e, 0x5f, 0xa4, 0xb9, 0xed, 0x35, 0x12, 0x7e, 0xb8, + 0x4f, 0xa4, 0x93, 0x5b, 0xf8, 0x47, 0xcb, 0x9b, 0x4d, 0x3c, 0x6f, 0xf2, 0xf6, 0x9a, 0x5c, 0x20, + 0x56, 0xd3, 0x6d, 0x34, 0xf4, 0xed, 0x5a, 0x27, 0x2c, 0xf9, 0xcb, 0xdf, 0x6d, 0xbf, 0x27, 0x4d, + 0xb5, 0xcb, 0x6a, 0xbf, 0x0a, 0x16, 0x95, 0x24, 0x9d, 0xdb, 0xb5, 0x6a, 0xd5, 0x5b, 0xe0, 0x8f, + 0x93, 0x6d, 0xf5, 0x7a, 0xe0, 0x8f, 0xb6, 0xaf, 0xf0, 0x49, 0x5d, 0x27, 0xf8, 0x7b, 0x4a, 0xd3, + 0xb7, 0x54, 0xd5, 0x38, 0x77, 0x1b, 0xa6, 0x5f, 0xf0, 0xdb, 0x80, 0x8c, 0xcc, 0xbc, 0x2a, 0xff, + 0xd3, 0x7c, 0xd0, 0x07, 0x5c, 0x0d, 0x01, 0xd7, 0x0a, 0xc5, 0xdd, 0x01, 0xd7, 0x07, 0x40, 0x75, + 0xc0, 0x24, 0xc6, 0x50, 0x96, 0x80, 0x41, 0x71, 0xc1, 0x6c, 0x3b, 0x9e, 0x0e, 0x60, 0xdc, 0xdd, + 0x61, 0x79, 0x00, 0x85, 0xd6, 0x3f, 0x56, 0xbb, 0x7f, 0xbd, 0xa7, 0xb6, 0x7e, 0x28, 0x0b, 0x85, + 0xdc, 0x05, 0xd9, 0xd6, 0x75, 0xdb, 0xfd, 0x6b, 0xb7, 0x1b, 0xfe, 0x10, 0x7d, 0xb5, 0xc4, 0x89, + 0x04, 0x37, 0x7f, 0xfe, 0x19, 0x1f, 0xac, 0xb8, 0xc5, 0x27, 0x20, 0x00, 0x1e, 0xd4, 0xa6, 0xdf, + 0xc2, 0x66, 0x3b, 0xff, 0x17, 0x4f, 0xc2, 0x82, 0xdd, 0x27, 0x77, 0x90, 0xcc, 0x89, 0xc1, 0xde, + 0x56, 0x2d, 0x97, 0x1b, 0x9d, 0xc4, 0x84, 0x42, 0x04, 0xaa, 0xd3, 0x10, 0xc1, 0xac, 0x59, 0xd4, + 0x21, 0x62, 0x4e, 0x60, 0x84, 0x22, 0x14, 0xd5, 0x05, 0x50, 0xf4, 0x65, 0x8e, 0x27, 0x1b, 0x40, + 0x88, 0xea, 0x32, 0xf3, 0xf8, 0x79, 0x61, 0x18, 0x07, 0x48, 0xe0, 0x30, 0xff, 0xc2, 0x96, 0xf2, + 0xde, 0xd3, 0x52, 0x5d, 0x97, 0x88, 0xe1, 0xc6, 0x84, 0x87, 0x07, 0x98, 0x17, 0xe5, 0xe2, 0x9d, + 0xfc, 0x40, 0x52, 0xfa, 0x9a, 0x7a, 0xa4, 0x2e, 0x2e, 0x2e, 0xa2, 0x99, 0x54, 0x2d, 0x06, 0xfc, + 0x48, 0x44, 0x15, 0x4d, 0xc4, 0x1a, 0x1f, 0xc2, 0x6a, 0x10, 0x99, 0x07, 0x97, 0x71, 0x0f, 0x14, + 0x7a, 0x3b, 0xc4, 0x89, 0x05, 0x25, 0x32, 0x4e, 0xef, 0x43, 0x96, 0xf8, 0xff, 0xc4, 0x06, 0x06, + 0x5c, 0x4b, 0x8f, 0x6e, 0x9d, 0x5a, 0xd6, 0x54, 0x49, 0x43, 0xc4, 0x04, 0x01, 0x61, 0x96, 0xb6, + 0xd7, 0x56, 0xfe, 0xe2, 0x04, 0x02, 0x72, 0xb5, 0x9e, 0x0d, 0xad, 0x5f, 0xdc, 0x40, 0x91, 0x33, + 0xfd, 0xac, 0x2e, 0x8d, 0xb5, 0xf1, 0x85, 0xe5, 0xe6, 0xad, 0x58, 0x9e, 0x4b, 0xe5, 0xe2, 0x99, + 0x79, 0xd1, 0x01, 0x65, 0xf8, 0x81, 0x9a, 0xba, 0xaf, 0x84, 0x22, 0x45, 0xd2, 0x63, 0x23, 0x2a, + 0xd8, 0xf2, 0xe3, 0xc5, 0x32, 0x84, 0xa1, 0x2a, 0xcc, 0x40, 0x90, 0xa5, 0xb5, 0x66, 0x35, 0x90, + 0xb8, 0xbb, 0x75, 0x65, 0x42, 0x05, 0x45, 0x66, 0xde, 0xbd, 0xa3, 0x67, 0xfc, 0x40, 0x29, 0xa1, + 0xda, 0xc7, 0x6d, 0x35, 0x9e, 0x70, 0x5e, 0x95, 0x43, 0x44, 0x20, 0x03, 0x33, 0x6f, 0x26, 0xce, + 0xea, 0x3c, 0x78, 0xc7, 0xd3, 0xb7, 0x37, 0x41, 0x93, 0x67, 0x23, 0xbc, 0x10, 0x06, 0x02, 0x19, + 0xf3, 0x25, 0x1a, 0x8e, 0x6d, 0xaa, 0xe2, 0x01, 0x88, 0x52, 0x1e, 0x62, 0x90, 0xf5, 0x28, 0xb6, + 0x41, 0xd8, 0x35, 0x3f, 0x8f, 0x10, 0x11, 0x5c, 0x51, 0xb4, 0x45, 0x0b, 0x07, 0x83, 0x28, 0x90, + 0x99, 0x16, 0x8e, 0x26, 0x14, 0x10, 0xe4, 0x99, 0x78, 0xb8, 0x81, 0xe4, 0xa0, 0x03, 0x55, 0x44, + 0xc0, 0xa9, 0x61, 0x8a, 0x67, 0x1c, 0x2c, 0xc5, 0xe3, 0x13, 0xa3, 0x39, 0x8b, 0x84, 0x04, 0x0d, + 0xe4, 0xc4, 0x23, 0xd5, 0xc5, 0xd4, 0x98, 0x28, 0x80, 0x6a, 0x3f, 0x91, 0x94, 0x00, 0xe8, 0x64, + 0x43, 0x40, 0xcc, 0xf8, 0x62, 0x02, 0x04, 0xe8, 0x3a, 0x2f, 0x83, 0x9e, 0x81, 0x73, 0xde, 0xb8, + 0xb2, 0xb1, 0xae, 0xd3, 0x4d, 0x34, 0x6e, 0x11, 0x2d, 0xaa, 0xb6, 0x9f, 0xaa, 0xf8, 0x30, 0xb6, + 0xdd, 0x49, 0xcd, 0x9e, 0xa4, 0xe9, 0x9b, 0xbb, 0xff, 0x82, 0x6e, 0x76, 0xe6, 0x4d, 0x7a, 0x93, + 0x9c, 0x8b, 0xed, 0xb6, 0x9a, 0x7e, 0x19, 0xb4, 0xd2, 0x49, 0x29, 0x0d, 0x10, 0xd2, 0x71, 0xff, + 0x85, 0x6c, 0xd9, 0xaa, 0x9e, 0x87, 0xa7, 0x52, 0x69, 0x36, 0x38, 0xff, 0xc4, 0x5a, 0xbe, 0x5f, + 0xf8, 0x4e, 0xfb, 0x3d, 0xe9, 0xba, 0x6d, 0x78, 0x5f, 0x7a, 0x77, 0x5a, 0x8c, 0xaa, 0x89, 0x75, + 0xed, 0xb6, 0x9a, 0x7e, 0x4d, 0xb8, 0xaf, 0xc1, 0x05, 0xed, 0x5a, 0x6b, 0xd4, 0x9a, 0xa8, 0x2a, + 0x97, 0xff, 0x82, 0x19, 0xed, 0xd1, 0xf2, 0xf8, 0x7b, 0xa6, 0xda, 0x34, 0x6c, 0xcf, 0x6f, 0x14, + 0x6f, 0xca, 0x92, 0x4d, 0x35, 0xea, 0x10, 0x8d, 0x21, 0xe8, 0x23, 0x8f, 0xc4, 0x14, 0x05, 0x45, + 0x19, 0xe0, 0xe3, 0xc7, 0x95, 0x62, 0x88, 0x7d, 0xb5, 0x8c, 0x25, 0xb0, 0x59, 0x10, 0xd4, 0xab, + 0xea, 0x28, 0xca, 0x56, 0x3f, 0x84, 0x02, 0x87, 0x46, 0x93, 0x5b, 0x59, 0x8b, 0xb4, 0xf2, 0x50, + 0x66, 0x0b, 0x3a, 0x0c, 0x7c, 0x54, 0x2f, 0x6e, 0x7f, 0x2c, 0x86, 0xb1, 0xcf, 0x08, 0x84, 0x46, + 0x68, 0xd6, 0x30, 0x20, 0x24, 0xcd, 0xc9, 0x0e, 0x41, 0x57, 0x51, 0x03, 0xa7, 0x75, 0xbe, 0x1e, + 0xc0, 0x8a, 0x7c, 0x8a, 0x7f, 0x55, 0x3f, 0xfc, 0x5d, 0xff, 0xdb, 0xc4, 0x89, 0x04, 0xfb, 0x49, + 0x72, 0xfb, 0xf8, 0x44, 0x10, 0xdd, 0xdf, 0xfe, 0x26, 0x30, 0xaf, 0x7c, 0xa6, 0x4b, 0x8b, 0xd8, + 0xb6, 0x78, 0x6e, 0xd7, 0xa1, 0x75, 0xf9, 0x71, 0x00, 0xa4, 0x71, 0xe0, 0x40, 0x80, 0xab, 0xab, + 0x66, 0xc0, 0x67, 0x18, 0x2d, 0xe5, 0x99, 0x39, 0x79, 0x7f, 0x78, 0x80, 0x4e, 0x34, 0xaa, 0x0b, + 0x7d, 0x62, 0xfd, 0xc4, 0x04, 0x06, 0x5e, 0xc4, 0xac, 0x19, 0x26, 0x44, 0xda, 0xa2, 0x6e, 0x4a, + 0xa3, 0x2d, 0x96, 0xc4, 0x38, 0x58, 0xe1, 0xa5, 0x03, 0xb4, 0xd1, 0xec, 0x67, 0xfd, 0x32, 0xef, + 0x9b, 0x97, 0xfb, 0x76, 0x61, 0xa5, 0x01, 0xaa, 0xa2, 0xc0, 0x68, 0x1e, 0x61, 0x92, 0xef, 0x4f, + 0xb7, 0xcb, 0x13, 0xf6, 0xec, 0x88, 0xcb, 0x13, 0x0a, 0x44, 0x16, 0x0f, 0xa8, 0x56, 0x73, 0xbe, + 0xf1, 0x96, 0x2d, 0x62, 0x26, 0xe1, 0x6c, 0xb4, 0x39, 0xef, 0xe7, 0x3c, 0x65, 0x3c, 0x48, 0x52, + 0xa3, 0x8f, 0x8d, 0x1d, 0x1d, 0x6d, 0x65, 0xb1, 0x2b, 0x0f, 0xf6, 0x7f, 0x2c, 0x62, 0x8c, 0x7c, + 0x71, 0xe0, 0xa0, 0x14, 0x02, 0xc8, 0xad, 0xb1, 0x5b, 0x62, 0xb1, 0x58, 0xae, 0x7c, 0x77, 0x6e, + 0x62, 0xe2, 0x42, 0x21, 0x4b, 0xb7, 0xe6, 0xd6, 0x8e, 0xca, 0xe4, 0xc8, 0xd6, 0x44, 0x73, 0xb8, + 0x98, 0x2a, 0x23, 0xdf, 0xb4, 0xd2, 0xaa, 0xaf, 0xf8, 0x90, 0x88, 0xb9, 0x14, 0x2c, 0xf1, 0x75, + 0xf0, 0x81, 0x5f, 0x67, 0x23, 0x0a, 0xe5, 0x1a, 0x85, 0x4b, 0x2c, 0x40, 0x91, 0x86, 0x68, 0xff, + 0x14, 0xc9, 0xea, 0xcf, 0xa8, 0xa3, 0x78, 0x9f, 0x3a, 0xc3, 0x3b, 0x79, 0x6e, 0xef, 0x84, 0x42, + 0x03, 0x25, 0xc1, 0xa5, 0xb9, 0x91, 0x07, 0x08, 0xde, 0xa3, 0x6b, 0x2f, 0x46, 0x3f, 0xef, 0x87, + 0x58, 0xd0, 0x0c, 0xe3, 0xb4, 0xc6, 0xd4, 0xa7, 0xff, 0xe5, 0x6f, 0xa6, 0x9f, 0x35, 0xa6, 0x9e, + 0x30, 0x1b, 0x5a, 0xfc, 0x3d, 0x80, 0x46, 0x49, 0x63, 0x1e, 0x57, 0xe9, 0x7c, 0x57, 0x3f, 0x80, + 0xc0, 0x04, 0x60, 0xaf, 0x4d, 0x34, 0xd3, 0x86, 0xdc, 0x1e, 0x13, 0x0e, 0x86, 0xe8, 0x6f, 0x49, + 0xd9, 0x3a, 0x1b, 0xa1, 0xbb, 0x27, 0x64, 0x48, 0xef, 0xde, 0xf8, 0x57, 0x01, 0x90, 0xbf, 0xd0, + 0xc1, 0xbe, 0xb5, 0xfd, 0x55, 0x61, 0x72, 0x08, 0x02, 0x83, 0x71, 0xea, 0x6f, 0xfc, 0xd4, 0xc7, + 0xd2, 0x46, 0xee, 0x24, 0x10, 0x02, 0x99, 0x54, 0xb4, 0x36, 0x81, 0xd9, 0x75, 0x92, 0xa2, 0x02, + 0xdd, 0x27, 0x14, 0x15, 0xf6, 0x17, 0x20, 0x90, 0x14, 0x12, 0x03, 0xe9, 0xf0, 0x56, 0x24, 0xac, + 0x4a, 0x2d, 0x14, 0x57, 0x15, 0xd1, 0x51, 0x41, 0x61, 0x9d, 0x61, 0x81, 0x01, 0x43, 0x0f, 0x21, + 0x65, 0xec, 0x71, 0xf2, 0x34, 0xe4, 0x47, 0x0b, 0xcd, 0xcb, 0xd3, 0x4a, 0xfd, 0xc1, 0x48, 0x90, + 0xa0, 0x8e, 0x75, 0x27, 0x0f, 0x00, 0xf0, 0xf7, 0xa2, 0xa7, 0x40, 0x3b, 0x87, 0x81, 0x72, 0xf1, + 0x75, 0x61, 0x89, 0x1d, 0x5d, 0x23, 0xce, 0x6d, 0x80, 0x2a, 0xf8, 0x7c, 0xb9, 0xe3, 0xdc, 0xb4, + 0x00, 0xf9, 0x2a, 0xa8, 0x40, 0x00, 0x40, 0x0f, 0x8b, 0x40, 0x7e, 0xb4, 0xdf, 0xdb, 0xc2, 0x01, + 0x38, 0xc5, 0x02, 0x58, 0x5f, 0xd9, 0x51, 0x0b, 0x91, 0x9f, 0x7f, 0x9e, 0xbf, 0x4d, 0x34, 0xd3, + 0xf3, 0x6d, 0xd5, 0x73, 0x6d, 0xd2, 0xf5, 0x95, 0xf0, 0x91, 0x33, 0x63, 0x5a, 0x69, 0x2e, 0xfa, + 0x49, 0x3e, 0x26, 0x93, 0xa5, 0x6f, 0x4f, 0xcb, 0xb7, 0x6f, 0xc2, 0x5a, 0x69, 0xd2, 0x97, 0xfc, + 0x27, 0xa7, 0x27, 0x69, 0x27, 0xf9, 0x36, 0xad, 0x78, 0x6b, 0x9f, 0x5a, 0x54, 0xd3, 0xaf, 0xf8, + 0x72, 0xdd, 0x36, 0x97, 0xdb, 0x6d, 0xb6, 0xfc, 0x49, 0x5b, 0x76, 0xf7, 0xa7, 0xe0, 0x88, 0xbb, + 0x6d, 0xbb, 0xe1, 0x3b, 0xd7, 0x74, 0x4d, 0x78, 0x20, 0x32, 0xd9, 0xb3, 0x4b, 0x6c, 0x2f, 0x51, + 0xd0, 0xb0, 0xb0, 0x33, 0xc0, 0x00, 0x87, 0x08, 0x0b, 0xbb, 0x32, 0xec, 0x15, 0x10, 0xc7, 0xf8, + 0x42, 0x36, 0x79, 0x81, 0x63, 0x24, 0x15, 0x7e, 0xad, 0x4f, 0xa6, 0xd6, 0xe4, 0xa0, 0x0c, 0x95, + 0x95, 0x7f, 0x93, 0x86, 0x52, 0xcd, 0x1b, 0xc7, 0xde, 0xc7, 0x1d, 0x48, 0x14, 0x5b, 0xf7, 0xd8, + 0x7f, 0x84, 0x21, 0x42, 0xbd, 0x9a, 0xab, 0x42, 0x39, 0x13, 0x46, 0x3c, 0x46, 0x68, 0xfa, 0xdd, + 0xbf, 0x71, 0x01, 0x00, 0xa1, 0x4c, 0xc7, 0x94, 0x82, 0x21, 0xc9, 0xe3, 0xd8, 0x39, 0xa1, 0xb7, + 0x73, 0xe0, 0x9f, 0x1d, 0xff, 0x05, 0x44, 0x63, 0xdd, 0xdc, 0xa0, 0x80, 0x3a, 0xd7, 0x3f, 0x08, + 0x41, 0x1e, 0xb5, 0x7e, 0x22, 0x08, 0xf7, 0x49, 0xdf, 0xe1, 0x4a, 0x21, 0xa3, 0x0f, 0x93, 0x95, + 0x2f, 0x2f, 0x11, 0x62, 0xf7, 0xab, 0xbf, 0xf8, 0x88, 0x50, 0x41, 0x39, 0x6a, 0xc2, 0x99, 0x47, + 0x9b, 0x5a, 0x5a, 0x37, 0x71, 0x1a, 0x47, 0xcb, 0xf8, 0x88, 0xa3, 0xe9, 0x24, 0xfb, 0xf1, 0x03, + 0xca, 0xd3, 0x8c, 0x21, 0xbd, 0x8b, 0x75, 0x55, 0x3b, 0x18, 0xa2, 0x54, 0x8c, 0x42, 0xea, 0x02, + 0x0f, 0x0d, 0x2a, 0x8a, 0x41, 0x7d, 0xbd, 0xdb, 0x6d, 0xb6, 0xef, 0x7f, 0x4a, 0xb0, 0x50, 0x11, + 0x0a, 0x58, 0x33, 0x10, 0x5e, 0x2a, 0x0f, 0x10, 0xe0, 0xec, 0x99, 0x6e, 0x21, 0xa3, 0x73, 0x1f, + 0x61, 0x79, 0x40, 0x16, 0x3a, 0x78, 0x91, 0x04, 0xca, 0x87, 0xa1, 0xe8, 0x98, 0xd1, 0x0b, 0xa1, + 0x8b, 0xa1, 0x9a, 0x10, 0xb4, 0x48, 0x93, 0xf8, 0x50, 0x87, 0x2c, 0x1e, 0x90, 0x4b, 0x19, 0x3b, + 0xc5, 0x8c, 0x4b, 0xdf, 0x6b, 0xac, 0x3b, 0x54, 0xd0, 0x8b, 0x32, 0xf0, 0xa6, 0xa2, 0xf6, 0xc3, + 0x52, 0x0a, 0xec, 0xbf, 0xfe, 0x68, 0x74, 0xea, 0x8c, 0x7c, 0x48, 0xba, 0xa9, 0x32, 0x73, 0x67, + 0xc1, 0x5d, 0xe4, 0xfe, 0x5e, 0xf7, 0xe5, 0xf8, 0x81, 0x23, 0x29, 0x25, 0x75, 0xbc, 0x56, 0x2b, + 0x69, 0xa9, 0xb0, 0x2e, 0x54, 0xb0, 0x0f, 0x10, 0x24, 0x29, 0x9b, 0x04, 0x9c, 0x2c, 0xc9, 0xca, + 0xa2, 0x0c, 0xb1, 0x31, 0xa8, 0xbf, 0xcc, 0x51, 0x66, 0x24, 0x23, 0x24, 0x0a, 0xb1, 0xd5, 0x5c, + 0xc6, 0x70, 0xc0, 0xf0, 0x18, 0xe2, 0xf9, 0x6e, 0x24, 0x48, 0x52, 0x90, 0x23, 0xed, 0xca, 0x4c, + 0x2c, 0xfb, 0x1d, 0xb5, 0xf9, 0x0c, 0xf3, 0x40, 0xec, 0x25, 0x56, 0x61, 0xfc, 0x76, 0x76, 0x17, + 0x94, 0x02, 0x38, 0xdc, 0x27, 0x90, 0x9d, 0xdd, 0x27, 0xef, 0xe5, 0xa1, 0xa9, 0x66, 0xf7, 0xea, + 0x22, 0x41, 0xbc, 0xf3, 0xe9, 0x1a, 0xc3, 0xa8, 0x48, 0x0c, 0x0f, 0x65, 0x97, 0x7f, 0xfd, 0x6b, + 0x4d, 0x3f, 0xca, 0xaf, 0xa6, 0x9a, 0x69, 0xe2, 0x44, 0x0c, 0x10, 0x6a, 0x2d, 0x22, 0xf5, 0x26, + 0x72, 0x10, 0xd6, 0xdd, 0xc5, 0x70, 0xb9, 0x0e, 0x00, 0xf6, 0x41, 0xc3, 0x54, 0xff, 0xfd, 0xb6, + 0xcc, 0x8f, 0xc4, 0x82, 0x80, 0xa1, 0x12, 0x64, 0x2b, 0x0b, 0x26, 0x41, 0x4a, 0xc6, 0xf4, 0x9d, + 0x6a, 0xb5, 0xbf, 0x2c, 0x4f, 0xff, 0x08, 0x0c, 0x23, 0xbb, 0x57, 0x15, 0xdd, 0x49, 0xc9, 0xd7, + 0x51, 0x1d, 0x93, 0xc2, 0xe4, 0x91, 0x39, 0x6e, 0xb8, 0xf5, 0x23, 0xdd, 0x8f, 0xe4, 0x83, 0xc2, + 0x63, 0xdd, 0x8f, 0xb2, 0x26, 0x19, 0x63, 0x41, 0x34, 0x4e, 0x9f, 0xaf, 0xf5, 0xaf, 0xc4, 0xab, + 0x0b, 0x12, 0x03, 0x4b, 0x5d, 0x65, 0x57, 0xff, 0x55, 0xe2, 0x21, 0x41, 0x4a, 0x2e, 0x66, 0x19, + 0xe3, 0x11, 0x2d, 0x03, 0x7e, 0x16, 0x2b, 0xcf, 0xcd, 0xea, 0x59, 0x93, 0xd4, 0x53, 0x67, 0xe5, + 0xe1, 0x98, 0xd1, 0x5e, 0x06, 0x30, 0x72, 0x2a, 0xc3, 0x69, 0xb0, 0x83, 0xfe, 0x33, 0xe8, 0xe4, + 0x01, 0xb8, 0x3c, 0x3c, 0x2f, 0x92, 0xf5, 0x22, 0x2b, 0x81, 0xe0, 0x00, 0x26, 0xc7, 0x23, 0x12, + 0x07, 0x20, 0x29, 0x7f, 0x87, 0x2f, 0xfe, 0x24, 0x30, 0x71, 0xb5, 0xd8, 0x41, 0xa9, 0xcd, 0x33, + 0xf3, 0xf0, 0x87, 0x44, 0xcd, 0x80, 0xd4, 0xba, 0x7f, 0xcd, 0x4d, 0x24, 0xfe, 0x24, 0x8e, 0x96, + 0xd2, 0x5f, 0x86, 0x29, 0x69, 0x5b, 0x4d, 0xa5, 0xaa, 0xa7, 0xfe, 0x52, 0xe9, 0x11, 0x87, 0xcf, + 0x5f, 0x4d, 0x34, 0xd3, 0xf1, 0x15, 0xda, 0xda, 0x69, 0x70, 0xd5, 0xbd, 0x35, 0xf4, 0xd3, 0x4d, + 0x35, 0xcc, 0x44, 0x8b, 0x9f, 0x82, 0x8d, 0x3b, 0x49, 0x25, 0xbd, 0x70, 0x41, 0x6d, 0x2a, 0x54, + 0xa9, 0x27, 0xb6, 0xad, 0xa9, 0xbf, 0xfe, 0x53, 0xc9, 0x8b, 0x7e, 0x62, 0x55, 0xbf, 0x97, 0x72, + 0xe7, 0xe0, 0xb3, 0x26, 0x52, 0x91, 0xb2, 0x35, 0xf3, 0x97, 0xc9, 0xcf, 0xfe, 0x09, 0x2a, 0x6c, + 0x85, 0xc0, 0x2a, 0xdc, 0x31, 0x1b, 0x0d, 0x96, 0x96, 0x76, 0x83, 0x43, 0x44, 0x38, 0xe0, 0x9c, + 0x05, 0x63, 0x90, 0x65, 0x6f, 0x82, 0xf0, 0x4b, 0x0a, 0x35, 0x21, 0xce, 0xc9, 0xb0, 0x46, 0xf2, + 0xd8, 0x0e, 0x47, 0x84, 0xc4, 0x75, 0x7b, 0x2a, 0x89, 0x00, 0x3d, 0x05, 0x00, 0x47, 0xd8, 0x4e, + 0x3c, 0x2f, 0x47, 0x07, 0x0b, 0xe1, 0xac, 0x30, 0x83, 0x45, 0x87, 0x40, 0xf7, 0xdb, 0x9e, 0x4f, + 0xcf, 0xef, 0xbb, 0xd6, 0xef, 0x5f, 0x90, 0xcf, 0x08, 0x05, 0x0a, 0x36, 0xc7, 0x42, 0xc9, 0xcb, + 0xef, 0x77, 0xa0, 0xd3, 0xaf, 0xb0, 0xf1, 0x20, 0x0a, 0x96, 0xb2, 0x8c, 0xb9, 0xa7, 0x9f, 0xfe, + 0x4e, 0x9b, 0xf2, 0x23, 0xff, 0xbc, 0x2b, 0x38, 0x02, 0x29, 0x78, 0x5b, 0xd7, 0x73, 0x4d, 0x34, + 0xd3, 0x55, 0xff, 0xe3, 0xa2, 0x01, 0x3a, 0xe0, 0x15, 0x36, 0x3e, 0x13, 0x2b, 0x43, 0xca, 0x4c, + 0x77, 0x74, 0x9c, 0xf7, 0x84, 0x01, 0x00, 0x2c, 0xb5, 0x18, 0xf7, 0xb6, 0x4c, 0x9e, 0x8b, 0xfc, + 0x22, 0x19, 0x0a, 0x5d, 0xa6, 0x70, 0xb1, 0x32, 0x29, 0xb0, 0xc0, 0xca, 0xc3, 0x42, 0xc5, 0xd8, + 0xa7, 0x70, 0xd4, 0x38, 0xb0, 0x59, 0x43, 0x11, 0x18, 0x21, 0xbc, 0x56, 0x88, 0xfb, 0x43, 0xbc, + 0xf0, 0xf0, 0xb5, 0x4f, 0x3c, 0xf0, 0xf5, 0x68, 0x59, 0x30, 0x56, 0x9f, 0x12, 0x30, 0xfa, 0x25, + 0xaa, 0xa7, 0x26, 0x3f, 0xbc, 0x57, 0x89, 0x0c, 0x05, 0x2e, 0xef, 0x2f, 0x15, 0x8a, 0x39, 0xf1, + 0xad, 0xa0, 0xba, 0xb4, 0x65, 0xb1, 0xa6, 0x5d, 0xe1, 0x00, 0x4d, 0x77, 0x73, 0xf7, 0xaa, 0x42, + 0xf2, 0xe1, 0x6f, 0x84, 0x3a, 0x93, 0xad, 0xd3, 0x1f, 0xad, 0xcc, 0xae, 0xa4, 0x7c, 0x48, 0xcc, + 0x60, 0xa4, 0xf9, 0xcb, 0x1f, 0x76, 0x8d, 0xb1, 0x75, 0x13, 0xfc, 0x22, 0x6b, 0x6b, 0xf8, 0xae, + 0xa5, 0xe5, 0xc2, 0xdb, 0xb5, 0xc2, 0x23, 0x08, 0x21, 0xc2, 0xc6, 0x78, 0xe1, 0x63, 0x2d, 0xb4, + 0x6e, 0x58, 0x19, 0x6d, 0xa5, 0x0b, 0x81, 0x53, 0xc3, 0x87, 0x80, 0x79, 0xe0, 0x60, 0x58, 0x07, + 0x0c, 0xca, 0x00, 0x1a, 0x44, 0x1c, 0x87, 0x44, 0x40, 0xe5, 0x8a, 0xb7, 0xd9, 0xfb, 0xbf, 0x9f, + 0x9f, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xc8, 0x6f, 0x7c, 0x29, 0x24, 0x2a, 0xdc, 0x6f, 0x25, + 0x72, 0x2d, 0x93, 0x88, 0x80, 0xef, 0x35, 0x69, 0x95, 0x77, 0x75, 0xd9, 0x13, 0xfc, 0xd2, 0x13, + 0x8e, 0x2a, 0xab, 0xb8, 0x98, 0x53, 0x32, 0xdb, 0xf1, 0x1c, 0x1f, 0xf1, 0xea, 0x4c, 0x47, 0x06, + 0x32, 0x19, 0x8c, 0xf3, 0x52, 0xbb, 0xc7, 0xbe, 0x2e, 0xc6, 0x90, 0xe1, 0x30, 0xb0, 0xc9, 0x9e, + 0xe2, 0xa6, 0x1a, 0x50, 0x42, 0x37, 0x6e, 0x5f, 0xfe, 0xae, 0xae, 0x64, 0x3b, 0x85, 0x70, 0x08, + 0xc5, 0xe1, 0x76, 0x00, 0xee, 0xef, 0xff, 0xf8, 0x80, 0x88, 0x53, 0x12, 0x90, 0x9a, 0xdd, 0x26, + 0xc2, 0xaa, 0xde, 0x3f, 0x50, 0x8e, 0x51, 0x37, 0x23, 0xa9, 0xae, 0xf0, 0xc9, 0x4c, 0xdb, 0x55, + 0xf1, 0x92, 0xf5, 0xf4, 0xec, 0x9a, 0x09, 0xdd, 0x75, 0x8e, 0xa0, 0xf8, 0x20, 0x12, 0x14, 0x29, + 0xef, 0xe4, 0xf3, 0x65, 0x21, 0x57, 0xc2, 0x99, 0x7d, 0xb9, 0xf2, 0xfb, 0x88, 0x05, 0x03, 0xa2, + 0xf1, 0xc6, 0x79, 0xf1, 0xed, 0x58, 0xaf, 0xc1, 0x48, 0x20, 0xe0, 0x80, 0x48, 0xfc, 0x99, 0xca, + 0xac, 0x92, 0x3c, 0xf9, 0x76, 0x7f, 0x0e, 0xa2, 0x00, 0x0f, 0xad, 0xcd, 0x34, 0x03, 0x67, 0xcc, + 0x05, 0xaf, 0x88, 0x78, 0xf1, 0xf7, 0x38, 0x7f, 0xbd, 0xe0, 0x4c, 0xca, 0xeb, 0x6f, 0xf0, 0x88, + 0x60, 0x68, 0x82, 0x2a, 0x8e, 0x98, 0xf0, 0x1d, 0xcc, 0xda, 0x58, 0x32, 0x50, 0x54, 0xa2, 0x94, + 0xb0, 0x06, 0x7b, 0xcf, 0xc0, 0xaf, 0x51, 0x4d, 0x91, 0x2c, 0x19, 0x56, 0x54, 0xe0, 0xc5, 0x16, + 0x89, 0x78, 0x52, 0xf8, 0x76, 0x68, 0x25, 0x8a, 0x0a, 0xed, 0x7f, 0xc3, 0x22, 0x79, 0x3d, 0x4f, + 0xdb, 0xff, 0xe0, 0x9e, 0x86, 0x9b, 0x53, 0x74, 0xdb, 0x2f, 0x97, 0xc1, 0x61, 0x09, 0xf6, 0xd5, + 0xb7, 0xb9, 0x77, 0xea, 0x4e, 0x1a, 0x2c, 0xb3, 0xd4, 0xfe, 0xeb, 0xef, 0xae, 0x5f, 0x58, 0x44, + 0x9c, 0x49, 0x2f, 0x68, 0x43, 0x95, 0xcd, 0x9e, 0xb9, 0x7c, 0xb2, 0xb0, 0xc7, 0x63, 0xf2, 0x5c, + 0xcd, 0xfc, 0x2b, 0x61, 0x30, 0x82, 0xde, 0xe7, 0x5e, 0xbe, 0x39, 0x88, 0xdd, 0x0f, 0xd7, 0xb8, + 0x20, 0x12, 0x34, 0xc0, 0xfb, 0x8a, 0x30, 0x7d, 0xcb, 0x58, 0x55, 0xac, 0x1a, 0xf2, 0x04, 0x08, + 0x77, 0x02, 0x56, 0xe3, 0xa2, 0x34, 0x81, 0x8c, 0x15, 0x10, 0x95, 0x18, 0x1e, 0x35, 0x52, 0x17, + 0x62, 0x38, 0x45, 0xbb, 0x3e, 0x3e, 0xc8, 0x0a, 0xc2, 0xd8, 0x2e, 0xb1, 0x37, 0x79, 0xfc, 0x32, + 0x08, 0x02, 0x85, 0x49, 0x22, 0x26, 0xb7, 0xc6, 0x07, 0x8c, 0x91, 0x40, 0x70, 0x90, 0x5f, 0xcb, + 0x6b, 0x95, 0xf9, 0x79, 0xec, 0xf1, 0x2c, 0x32, 0xcc, 0x50, 0xdd, 0xc4, 0x82, 0x10, 0xa4, 0x75, + 0xf2, 0xc3, 0xac, 0x53, 0x07, 0xae, 0x21, 0xe3, 0xd7, 0x2d, 0xb6, 0x29, 0xc5, 0xc7, 0xae, 0xde, + 0x77, 0xc6, 0xfe, 0x10, 0x08, 0x9e, 0xad, 0xa5, 0x36, 0xbf, 0x97, 0x6b, 0x84, 0x04, 0x85, 0x21, + 0xb5, 0x45, 0xd8, 0x9c, 0xbc, 0x8a, 0x45, 0xdc, 0xa4, 0x7a, 0xe2, 0xb9, 0x66, 0x6e, 0x53, 0xe3, + 0x52, 0xbf, 0xe1, 0x11, 0x23, 0x2b, 0x99, 0x36, 0x52, 0x09, 0x73, 0x2b, 0x18, 0xad, 0x79, 0xb2, + 0x83, 0xf0, 0xd2, 0x82, 0x8e, 0xe4, 0xfb, 0x7d, 0xec, 0xeb, 0xff, 0xf1, 0x1b, 0xde, 0xae, 0xbe, + 0x11, 0xd1, 0xc9, 0x82, 0xb3, 0xeb, 0xec, 0x3c, 0x43, 0x01, 0x57, 0xe1, 0x3b, 0xb7, 0xe8, 0xdd, + 0xbc, 0x48, 0x64, 0x29, 0x40, 0x32, 0x7d, 0x08, 0xf2, 0xf2, 0x72, 0x70, 0x18, 0x96, 0x40, 0x9c, + 0x70, 0xac, 0xa8, 0x7d, 0x85, 0x92, 0x17, 0x9d, 0x84, 0x9e, 0x54, 0x1d, 0x20, 0x9c, 0x71, 0xcc, + 0x2c, 0x43, 0x00, 0xd6, 0xdc, 0x40, 0x35, 0xb7, 0xa3, 0xef, 0xa7, 0x57, 0xaf, 0x59, 0x3c, 0x38, + 0xa0, 0x09, 0xc3, 0x75, 0xa2, 0x69, 0xdf, 0x67, 0x27, 0x5d, 0x9d, 0x34, 0xd9, 0xee, 0x59, 0xe3, + 0xe6, 0x4f, 0x6f, 0xfc, 0x16, 0x5e, 0xf2, 0x18, 0x9b, 0x45, 0x33, 0xf9, 0xa5, 0x10, 0xb0, 0xfc, + 0x40, 0x81, 0xc5, 0x74, 0xe8, 0x72, 0x2e, 0x2e, 0x2e, 0x56, 0x60, 0xff, 0x08, 0x02, 0xb9, 0x3e, + 0xcc, 0xee, 0x5a, 0x0a, 0xc5, 0x7d, 0xf8, 0x60, 0x22, 0x0a, 0xfb, 0x9f, 0xbb, 0xfc, 0xed, 0x8b, + 0x8a, 0x18, 0x90, 0x38, 0xdc, 0x1c, 0x83, 0x01, 0x91, 0x2c, 0x1c, 0xf9, 0xb8, 0xba, 0x8a, 0x19, + 0xfc, 0x36, 0x1c, 0x7a, 0xcd, 0xc8, 0xb9, 0x4b, 0x64, 0x48, 0xb2, 0xc0, 0x82, 0x08, 0x06, 0x4c, + 0xa0, 0xf3, 0x85, 0x86, 0x58, 0x65, 0x86, 0xa2, 0x3f, 0x17, 0x22, 0x46, 0xe5, 0xf2, 0xf6, 0xf8, + 0x44, 0x12, 0xcb, 0xe2, 0x8a, 0xe2, 0xed, 0xb7, 0x12, 0x23, 0x88, 0x10, 0x14, 0x16, 0x15, 0x39, + 0x4a, 0xb6, 0x01, 0x4e, 0x09, 0x05, 0x30, 0xc2, 0x95, 0x81, 0x80, 0xba, 0xa3, 0x54, 0x5c, 0x76, + 0x08, 0x2b, 0x1e, 0x07, 0xa5, 0xa5, 0xa2, 0x11, 0x92, 0x72, 0x25, 0x6e, 0x6b, 0x52, 0x4e, 0x38, + 0xee, 0x1d, 0x24, 0x00, 0xba, 0xa6, 0x2b, 0x27, 0xec, 0x4d, 0x3f, 0xff, 0xab, 0xab, 0x91, 0x67, + 0xf6, 0xdb, 0xf0, 0x57, 0x26, 0x62, 0xe9, 0x66, 0x63, 0x6d, 0x27, 0xf8, 0x2a, 0xd3, 0x4e, 0x5a, + 0x0f, 0x12, 0xf8, 0x87, 0x03, 0xd9, 0x61, 0x2c, 0x8b, 0x06, 0x78, 0xef, 0x84, 0x41, 0x49, 0x99, + 0xb4, 0x48, 0x8b, 0x44, 0x17, 0x2e, 0x3a, 0x9c, 0x1d, 0xfc, 0x30, 0x3e, 0x21, 0xe5, 0x6f, 0x35, + 0x8a, 0x7b, 0xd9, 0x8b, 0x34, 0x75, 0xe0, 0xe0, 0x40, 0xc1, 0x63, 0x14, 0x24, 0x50, 0x0f, 0x5e, + 0xcb, 0x60, 0xea, 0xe1, 0xf5, 0x38, 0x36, 0x65, 0xc1, 0x8b, 0xc6, 0x73, 0x0e, 0xdf, 0x86, 0x43, + 0x20, 0xb4, 0xca, 0xa4, 0xc6, 0x42, 0xc6, 0xff, 0xfc, 0x74, 0xbe, 0x5b, 0x76, 0xd5, 0xdb, 0x2f, + 0xbe, 0x13, 0xc0, 0x18, 0x9e, 0x75, 0x8e, 0x93, 0xc7, 0xfb, 0xdf, 0x7a, 0x97, 0xcb, 0x69, 0xe2, + 0x6c, 0x8b, 0x27, 0xe0, 0x49, 0x0c, 0x04, 0x62, 0xe1, 0x70, 0xe1, 0xb2, 0xfb, 0xb1, 0xd2, 0xbb, + 0xc3, 0xa8, 0xc0, 0x0e, 0xdb, 0x11, 0x4a, 0xb9, 0x80, 0x2f, 0x6e, 0xd6, 0x73, 0xee, 0xde, 0x3e, + 0xe7, 0x0f, 0x2c, 0xfc, 0x43, 0xe1, 0xb8, 0x87, 0x84, 0x05, 0xcc, 0x28, 0x0a, 0x18, 0xa0, 0x26, + 0x45, 0x4a, 0x51, 0x5f, 0xc4, 0x46, 0xd0, 0xcc, 0xc8, 0x8b, 0x0c, 0xeb, 0x95, 0x38, 0x03, 0xce, + 0xf4, 0xa0, 0x01, 0x50, 0xe3, 0xe7, 0xa8, 0x42, 0x31, 0x14, 0x79, 0x29, 0xc6, 0x5a, 0x17, 0x5f, + 0xf1, 0x59, 0xb6, 0xdd, 0xb4, 0x92, 0x5c, 0x39, 0x5d, 0xe2, 0xb2, 0x4e, 0x78, 0xff, 0x82, 0x2b, + 0x55, 0x95, 0xbe, 0x1e, 0xee, 0xf4, 0xd3, 0x6b, 0x3b, 0x6a, 0x99, 0x7d, 0xff, 0xcf, 0x58, 0xd3, + 0x44, 0xbf, 0xe1, 0xe2, 0xcd, 0x55, 0xca, 0x48, 0xa4, 0xb5, 0x52, 0x90, 0x5a, 0x41, 0x68, 0xab, + 0x6d, 0x24, 0xbf, 0xcb, 0xb7, 0x7f, 0x05, 0xb4, 0x92, 0xb5, 0x43, 0x6d, 0x0f, 0x1b, 0xe4, 0xa6, + 0xff, 0x8a, 0xd6, 0xb7, 0x5f, 0x9f, 0x87, 0x64, 0x5f, 0xfe, 0xa6, 0x17, 0xc5, 0x52, 0xdd, 0x8e, + 0xbf, 0x04, 0xd6, 0xcd, 0xdb, 0x7e, 0xde, 0xf5, 0xf0, 0x5d, 0x43, 0xad, 0x33, 0xfc, 0xe9, 0xf5, + 0x67, 0xc3, 0x33, 0xb1, 0x26, 0x55, 0xbb, 0x6f, 0x10, 0x99, 0x6f, 0xc2, 0x01, 0x00, 0xa0, 0x81, + 0x1e, 0xfa, 0x83, 0x50, 0x4a, 0x15, 0xd1, 0x38, 0x00, 0x14, 0x58, 0x25, 0xea, 0xd8, 0x5c, 0x2a, + 0x78, 0x07, 0x85, 0xe0, 0x53, 0xe0, 0x63, 0xa0, 0x2f, 0x44, 0x2a, 0x0d, 0x22, 0x97, 0x08, 0x84, + 0x02, 0x94, 0x07, 0x80, 0x05, 0x4e, 0x4f, 0xa0, 0xe2, 0xe2, 0x91, 0x13, 0x1f, 0x69, 0xd8, 0xdc, + 0xdf, 0xed, 0x0c, 0x0a, 0x9e, 0xd7, 0xa9, 0xc3, 0x4a, 0xdd, 0x87, 0x9c, 0x2f, 0x2c, 0x39, 0x78, + 0x64, 0x14, 0xdf, 0xaa, 0x8b, 0xad, 0x6b, 0x63, 0x89, 0x12, 0x14, 0x2a, 0x19, 0xbe, 0x59, 0xa6, + 0x2e, 0xae, 0xd3, 0x46, 0xa1, 0xb9, 0x7c, 0x8b, 0xbf, 0x88, 0x08, 0x15, 0xee, 0xf7, 0x52, 0xf5, + 0xef, 0xe1, 0x18, 0xbc, 0x99, 0x46, 0xd8, 0xbd, 0x52, 0x48, 0x1a, 0x2c, 0x36, 0x87, 0xc0, 0xf8, + 0x50, 0x45, 0xdc, 0xb4, 0xcf, 0xef, 0xbf, 0xb2, 0xba, 0x30, 0xb2, 0x84, 0xfe, 0x11, 0x10, 0x7d, + 0x25, 0x26, 0x7e, 0x22, 0x0a, 0x8b, 0xc7, 0xba, 0xca, 0xd4, 0xf8, 0xd6, 0xd7, 0xb0, 0xd6, 0x01, + 0x1b, 0xcd, 0xb0, 0xff, 0x24, 0xdf, 0x27, 0x7f, 0x6e, 0xff, 0xbe, 0xc7, 0x89, 0x0a, 0x73, 0x97, + 0x31, 0x05, 0xd5, 0x64, 0xe4, 0xe7, 0x54, 0xfd, 0x35, 0xa7, 0x58, 0x42, 0x14, 0x8b, 0x97, 0xf3, + 0x16, 0xef, 0x7a, 0xaa, 0x19, 0x53, 0x0c, 0xe0, 0x0c, 0xe3, 0xe0, 0xd3, 0xb8, 0x8e, 0x9f, 0xbf, + 0x4e, 0x9b, 0x6d, 0xb6, 0xdf, 0x8b, 0x94, 0x61, 0xac, 0x04, 0x68, 0x52, 0x07, 0x0b, 0x9d, 0x32, + 0xf8, 0xd3, 0xfb, 0x6d, 0xb7, 0xc5, 0xb1, 0x8f, 0x84, 0x42, 0x84, 0x12, 0x1c, 0x3b, 0xc4, 0x00, + 0x58, 0x2c, 0x30, 0xb0, 0xa9, 0xe0, 0x38, 0xf6, 0x9e, 0xb4, 0x53, 0x14, 0xc5, 0xd4, 0xb3, 0x3c, + 0x0d, 0x05, 0x32, 0xcd, 0xb0, 0xe3, 0x80, 0x10, 0x00, 0x6d, 0x9b, 0x8b, 0x5e, 0x3f, 0x8d, 0x8d, + 0x57, 0x68, 0xd8, 0x6f, 0x5f, 0x1c, 0x92, 0x3d, 0x84, 0xc2, 0x35, 0xbf, 0xf0, 0xc4, 0xe0, 0x14, + 0x1c, 0x4d, 0x12, 0x87, 0x71, 0xa0, 0xef, 0x5b, 0xbb, 0xb8, 0xab, 0x15, 0x67, 0xa6, 0x4b, 0x58, + 0x94, 0xc9, 0xe9, 0x98, 0xe3, 0x2a, 0xd2, 0x15, 0x69, 0x19, 0xd9, 0xce, 0x85, 0xd8, 0x65, 0x40, + 0x0b, 0x29, 0x8f, 0x1b, 0x28, 0x73, 0xba, 0x7f, 0xfc, 0xb1, 0x0b, 0xb8, 0xbf, 0x8c, 0x55, 0x86, + 0x08, 0x60, 0x03, 0x40, 0x65, 0xbb, 0x9e, 0x1d, 0xff, 0x5b, 0x67, 0xed, 0xda, 0xd5, 0x62, 0xbd, + 0xef, 0x23, 0xcb, 0x91, 0x54, 0xcb, 0x12, 0x11, 0x05, 0x1d, 0x53, 0x55, 0x5f, 0xfc, 0x40, 0x60, + 0x28, 0x53, 0x35, 0xd8, 0xa5, 0x0c, 0x13, 0xe2, 0xe4, 0xa9, 0xff, 0xa5, 0x7e, 0xe2, 0x44, 0x85, + 0x2d, 0x22, 0xb2, 0x4c, 0x38, 0x21, 0x12, 0xbb, 0x54, 0x5d, 0x48, 0xc2, 0xb1, 0x27, 0xe7, 0x58, + 0x91, 0x21, 0x4f, 0x00, 0x99, 0x8f, 0x51, 0x97, 0xc6, 0x6e, 0xcf, 0x63, 0x75, 0x7d, 0x37, 0x63, + 0x3d, 0xc4, 0xfe, 0x09, 0x28, 0x9f, 0x6e, 0x26, 0x14, 0xaa, 0x2b, 0x12, 0xdc, 0xc5, 0x19, 0x69, + 0x7b, 0x2c, 0x44, 0x15, 0x33, 0x05, 0x0c, 0x05, 0x23, 0xb2, 0x80, 0xee, 0x93, 0xbf, 0x08, 0x41, + 0x45, 0x34, 0x98, 0x62, 0xb0, 0xe6, 0xe3, 0x7a, 0x4b, 0xf1, 0x21, 0x10, 0x95, 0x5d, 0x36, 0x27, + 0x4a, 0xf8, 0x64, 0x41, 0x8a, 0xfa, 0x5e, 0x14, 0xdd, 0xe2, 0xb2, 0xed, 0xcf, 0x41, 0x0a, 0x47, + 0xa8, 0xb4, 0x1b, 0xa2, 0x35, 0x1f, 0x88, 0x08, 0x84, 0x39, 0x3f, 0x96, 0xda, 0xda, 0x2b, 0x18, + 0x81, 0x03, 0x24, 0xc9, 0x14, 0xc5, 0xd3, 0xad, 0x03, 0xaf, 0x5c, 0xd4, 0x6e, 0xfc, 0x23, 0xf2, + 0xf3, 0xc3, 0x0c, 0xe0, 0x03, 0xae, 0xed, 0x0f, 0xc1, 0x5b, 0xff, 0xfa, 0xbb, 0xbb, 0xc4, 0x3e, + 0xee, 0xff, 0x8e, 0xdc, 0x48, 0x60, 0x68, 0xc1, 0x2d, 0x84, 0x58, 0xe3, 0x8e, 0x86, 0x5d, 0xc3, + 0xf6, 0x54, 0x70, 0x1a, 0xd3, 0x3d, 0x65, 0xe2, 0xac, 0x41, 0xe6, 0x20, 0x5e, 0xc0, 0x40, 0x7a, + 0xfe, 0x32, 0x82, 0xd7, 0x2c, 0x4f, 0xa8, 0xa8, 0x5d, 0x6c, 0xbd, 0xf3, 0x95, 0x4f, 0x07, 0xc2, + 0xfe, 0xb9, 0xea, 0xb3, 0x76, 0xff, 0xcd, 0x43, 0x63, 0x43, 0x63, 0x5c, 0xdd, 0xd9, 0x3e, 0x2a, + 0xed, 0xf4, 0xcd, 0xff, 0x2e, 0x9b, 0x19, 0x18, 0xf0, 0xdc, 0xdb, 0x6a, 0xae, 0xa5, 0xec, 0xfe, + 0xb8, 0xbd, 0xda, 0xe7, 0x63, 0xe1, 0xbd, 0x3a, 0x6b, 0x17, 0xaf, 0xf9, 0x36, 0xed, 0xf8, 0x5f, + 0x33, 0x1c, 0x1a, 0x84, 0xa6, 0xe1, 0xd1, 0x86, 0x5c, 0x9b, 0x9e, 0x05, 0x87, 0xf0, 0xc0, 0xd3, + 0x1c, 0x31, 0x33, 0x40, 0x8d, 0x02, 0xa2, 0x8d, 0x06, 0xa9, 0x05, 0x1d, 0x89, 0x7c, 0x9c, 0xcb, + 0xe2, 0x90, 0xe4, 0x19, 0x39, 0x51, 0x29, 0x22, 0x91, 0x06, 0xf1, 0x84, 0x30, 0xba, 0x4c, 0xa7, + 0x82, 0xdf, 0x4b, 0xcb, 0x31, 0x20, 0x70, 0x51, 0x5c, 0x9f, 0xff, 0x08, 0x82, 0x93, 0xa7, 0x01, + 0x1a, 0xfc, 0x5c, 0xca, 0xea, 0x30, 0xbc, 0x5e, 0x31, 0xc4, 0x20, 0x2b, 0xe1, 0x36, 0x71, 0x22, + 0x41, 0x31, 0x4a, 0xc7, 0x37, 0x99, 0x87, 0xdf, 0x88, 0x10, 0x6b, 0xe5, 0xfc, 0x40, 0xcb, 0xb6, + 0xfb, 0xb8, 0xac, 0xbd, 0xd8, 0xcb, 0x61, 0x66, 0xa8, 0x54, 0xab, 0x68, 0xba, 0x9e, 0x14, 0x14, + 0xf6, 0x0b, 0x76, 0xec, 0x67, 0x8f, 0x0c, 0x9a, 0x82, 0x41, 0xa7, 0x95, 0x17, 0x10, 0x25, 0x18, + 0x00, 0xfa, 0x0b, 0x88, 0x12, 0xc5, 0xa0, 0x1f, 0x45, 0x71, 0x20, 0xa0, 0x60, 0xb7, 0xbc, 0xde, + 0xf6, 0x83, 0xd1, 0xd5, 0x91, 0x80, 0x3a, 0x9e, 0xa1, 0xb1, 0x7d, 0x71, 0x02, 0x41, 0x11, 0xeb, + 0x54, 0x77, 0x88, 0x82, 0x8a, 0x64, 0xec, 0x29, 0x99, 0x45, 0x3e, 0xe1, 0x01, 0x00, 0xb3, 0x77, + 0x57, 0xbe, 0xaa, 0x2f, 0xde, 0x20, 0x15, 0x6b, 0x5a, 0x1b, 0xcd, 0x04, 0x43, 0x0c, 0x4b, 0x6f, + 0x87, 0x89, 0x02, 0x51, 0x4d, 0x19, 0xb9, 0x1e, 0x16, 0xce, 0xad, 0xdf, 0xfb, 0x8e, 0xf7, 0x4f, + 0xf8, 0x91, 0x00, 0x98, 0xca, 0xaa, 0xbc, 0xb9, 0xde, 0x20, 0x76, 0xaa, 0xaa, 0xaa, 0xaf, 0x77, + 0x85, 0x09, 0x02, 0x50, 0xf1, 0x30, 0xa4, 0x8f, 0x9b, 0x6a, 0x7a, 0xd7, 0xdf, 0x10, 0x24, 0x14, + 0x94, 0x63, 0x2f, 0x2e, 0x0a, 0xe5, 0xfd, 0xcc, 0x1f, 0xed, 0x20, 0xfb, 0x84, 0x63, 0x2a, 0xb1, + 0x03, 0xb3, 0x49, 0x2b, 0xa3, 0x2f, 0x72, 0xc1, 0x8f, 0xa0, 0x79, 0x04, 0x7c, 0x44, 0x3f, 0x99, + 0x39, 0x52, 0x3b, 0xf1, 0x9d, 0xde, 0xd3, 0x97, 0x2d, 0xcf, 0x0b, 0xc7, 0x69, 0xe2, 0x04, 0xac, + 0x5c, 0x48, 0x95, 0xff, 0x10, 0x20, 0x14, 0x96, 0xa8, 0xf5, 0x93, 0xa6, 0xee, 0x7f, 0xdc, 0x44, + 0x27, 0x55, 0x91, 0x1c, 0x93, 0x7f, 0x2e, 0x7c, 0x30, 0xd7, 0xe1, 0x23, 0x06, 0x91, 0xaf, 0xc4, + 0xbf, 0x0c, 0xc1, 0xf8, 0xf6, 0x27, 0x08, 0x84, 0x1e, 0xef, 0xf1, 0x23, 0xaa, 0xa6, 0xa4, 0xee, + 0xed, 0x36, 0xce, 0xb8, 0x88, 0x2d, 0xed, 0x37, 0xab, 0x5f, 0xe1, 0x18, 0x28, 0x2d, 0x54, 0x5e, + 0xd5, 0x7b, 0x89, 0x90, 0x95, 0x47, 0x86, 0x89, 0x0f, 0x26, 0xbf, 0xef, 0xfe, 0x64, 0xf1, 0x03, + 0x09, 0xa9, 0xb0, 0xfe, 0x2a, 0xd3, 0x51, 0x3e, 0x58, 0x62, 0x38, 0x5e, 0x86, 0x6a, 0x7c, 0x48, + 0x26, 0xac, 0x5d, 0x3e, 0x45, 0x1e, 0xc2, 0xc4, 0x80, 0xc7, 0x89, 0xa5, 0xdb, 0xdb, 0xbe, 0xf6, + 0xfe, 0x11, 0x18, 0x5d, 0x54, 0x41, 0xc1, 0x4e, 0x45, 0xc3, 0x42, 0xd9, 0x32, 0xcb, 0x06, 0x78, + 0xc3, 0x97, 0x0b, 0x90, 0xee, 0x00, 0xe6, 0xb5, 0x03, 0x4b, 0xb1, 0x4f, 0x77, 0xb6, 0xde, 0xb1, + 0xb3, 0x96, 0x71, 0x8b, 0xf8, 0x87, 0xaa, 0xed, 0x83, 0x00, 0x02, 0x24, 0x5b, 0x83, 0x88, 0x17, + 0x81, 0xf9, 0x75, 0xef, 0xe1, 0xd9, 0xb2, 0x4c, 0x57, 0xcf, 0xa7, 0xc2, 0xc0, 0xc2, 0xd5, 0x14, + 0x0c, 0xe2, 0xc0, 0x49, 0x89, 0x8a, 0x23, 0xdc, 0xce, 0x78, 0x7f, 0xfe, 0x08, 0xe9, 0xb5, 0xdd, + 0xf3, 0x6d, 0xbf, 0xc1, 0x5e, 0xaa, 0xe4, 0xd8, 0x92, 0x63, 0x93, 0x39, 0x7c, 0x13, 0xcb, 0x9e, + 0xaf, 0x97, 0xc5, 0x5d, 0x75, 0xb7, 0xf0, 0x8d, 0x24, 0xb4, 0xdd, 0x3b, 0xbe, 0xb9, 0xea, 0xea, + 0xaf, 0xfe, 0x10, 0xdb, 0x74, 0x98, 0xca, 0xc1, 0xd8, 0x83, 0xb6, 0x9f, 0xd7, 0x38, 0xf0, 0x53, + 0xbb, 0xcd, 0x97, 0x91, 0x93, 0xb2, 0x87, 0x47, 0xaf, 0x85, 0xee, 0x96, 0x76, 0x4a, 0xc5, 0x39, + 0x7d, 0x56, 0xda, 0xe1, 0x6e, 0x93, 0xdb, 0x91, 0x97, 0xdc, 0xfe, 0x7f, 0xc1, 0x0c, 0xde, 0x6e, + 0x29, 0xbe, 0x09, 0xef, 0xab, 0x75, 0xe2, 0xc3, 0xd1, 0x00, 0x01, 0x49, 0x64, 0x39, 0x05, 0x53, + 0x25, 0xe2, 0x7c, 0x53, 0x75, 0xdf, 0xd0, 0x83, 0xe3, 0xf3, 0xc7, 0xab, 0xa3, 0x3f, 0x7f, 0x5f, + 0xa1, 0xe0, 0xf7, 0x50, 0x22, 0x0c, 0x72, 0x01, 0xd2, 0xc2, 0x44, 0x69, 0x86, 0x74, 0x2d, 0x0f, + 0xef, 0xc3, 0x00, 0x58, 0x0a, 0x09, 0xbe, 0x0a, 0xdb, 0x06, 0x66, 0xb2, 0x83, 0xc7, 0xca, 0x06, + 0xb2, 0x0f, 0xc4, 0xa7, 0x80, 0x3d, 0xfe, 0x33, 0x9f, 0x35, 0x16, 0xea, 0x50, 0x3b, 0x89, 0x46, + 0x88, 0x6f, 0x82, 0xb3, 0x6f, 0x71, 0x0f, 0x7f, 0x2d, 0x92, 0x8a, 0xb6, 0xb7, 0xef, 0x12, 0x13, + 0x85, 0x9a, 0x9b, 0x97, 0xad, 0x78, 0x91, 0x06, 0x3d, 0xef, 0xe3, 0x2b, 0x59, 0x3d, 0xaa, 0x6e, + 0x5a, 0xbd, 0x7a, 0x62, 0xfc, 0x22, 0x18, 0x08, 0xeb, 0x4d, 0x68, 0xca, 0x21, 0x7d, 0xb1, 0xe5, + 0x5e, 0x81, 0x71, 0x38, 0x05, 0x6d, 0x80, 0x01, 0xa2, 0x45, 0x82, 0x11, 0x01, 0x41, 0x45, 0xb0, + 0xbd, 0x49, 0xea, 0x4e, 0x04, 0x61, 0x30, 0x80, 0x95, 0x90, 0x20, 0x6c, 0x8a, 0xd7, 0x8b, 0xa7, + 0x60, 0x05, 0x47, 0x82, 0xef, 0x80, 0x01, 0x4c, 0x28, 0x44, 0x80, 0xe1, 0xe5, 0x83, 0x2d, 0x85, + 0x45, 0x0b, 0x23, 0xbc, 0x33, 0x0a, 0x09, 0x11, 0x21, 0x08, 0xc6, 0x1e, 0x71, 0x4e, 0x0d, 0x71, + 0xf8, 0x2b, 0xd8, 0xd2, 0x8e, 0x87, 0xd5, 0xaa, 0xf5, 0xbc, 0xbc, 0xd8, 0x5f, 0xdf, 0x0a, 0x09, + 0x1c, 0x48, 0xcf, 0xf5, 0x51, 0x7b, 0x65, 0x9a, 0x41, 0x4e, 0x0f, 0x58, 0xb6, 0x7f, 0x5f, 0xf8, + 0x98, 0x72, 0x2a, 0xd1, 0xb2, 0x8f, 0xad, 0xb6, 0xff, 0x85, 0x54, 0x00, 0xbd, 0xea, 0x8c, 0x57, + 0xb4, 0xaa, 0xab, 0xff, 0xf8, 0x90, 0x88, 0x2c, 0xb7, 0x2d, 0xc5, 0x72, 0x75, 0x72, 0x47, 0xef, + 0xfb, 0x88, 0x12, 0x14, 0xbb, 0x6e, 0xe4, 0xfb, 0x68, 0x3a, 0x6d, 0x55, 0x5d, 0x65, 0xe8, 0x1f, + 0xb8, 0x40, 0x22, 0x0a, 0x2e, 0xe5, 0x21, 0xd5, 0xaa, 0xe5, 0xe1, 0x90, 0x58, 0x45, 0x17, 0x4a, + 0xd3, 0x74, 0x0d, 0xc5, 0x6c, 0x6e, 0xfc, 0x40, 0x64, 0x17, 0x5a, 0x68, 0x6c, 0x98, 0xcf, 0x85, + 0x62, 0x47, 0xf7, 0x12, 0x20, 0x16, 0x55, 0xee, 0x9e, 0x6c, 0x90, 0x89, 0xb9, 0xee, 0x10, 0x08, + 0x05, 0x2d, 0xa5, 0x52, 0xb2, 0xb5, 0x17, 0xe9, 0xa8, 0xed, 0x2f, 0xfc, 0x40, 0x81, 0xa5, 0xc5, + 0xd0, 0xc9, 0x8a, 0x96, 0x75, 0xbd, 0xe5, 0xff, 0xce, 0xd9, 0xbf, 0xf0, 0x80, 0x2d, 0xa6, 0xc7, + 0x56, 0xdf, 0xef, 0x82, 0x2d, 0xd3, 0xff, 0x89, 0x82, 0x49, 0x3f, 0xef, 0x13, 0xc4, 0xc1, 0x5e, + 0xb5, 0x6a, 0xa8, 0x4f, 0x7b, 0xf1, 0x01, 0x80, 0x54, 0x4b, 0x43, 0xee, 0x2b, 0x79, 0x7e, 0xef, + 0x08, 0xfc, 0x14, 0x47, 0x69, 0xda, 0x6f, 0x37, 0x36, 0x77, 0x08, 0xc5, 0xe2, 0xb1, 0xb4, 0x5a, + 0x9c, 0xae, 0x65, 0x3c, 0x48, 0x28, 0xb6, 0x65, 0x0c, 0x5a, 0x6e, 0xa4, 0x20, 0xeb, 0x89, 0x08, + 0x04, 0xe5, 0x60, 0xbe, 0xc7, 0x69, 0xfc, 0x40, 0x47, 0x18, 0x5f, 0x35, 0x2a, 0x30, 0x80, 0x91, + 0xe2, 0xff, 0xc2, 0x62, 0x26, 0x2f, 0xdd, 0xd4, 0x10, 0x86, 0x01, 0x60, 0xd2, 0xf1, 0x20, 0x39, + 0x15, 0x89, 0xb1, 0x26, 0x53, 0x7d, 0xf8, 0x60, 0x48, 0xc1, 0x1a, 0x4e, 0xe7, 0xe8, 0x75, 0x46, + 0x2f, 0x56, 0x59, 0x03, 0x01, 0xae, 0x20, 0x18, 0x05, 0x0a, 0x6e, 0x24, 0xf1, 0x9f, 0x50, 0x98, + 0xca, 0x14, 0xcd, 0x85, 0x86, 0x5e, 0x5b, 0x7c, 0x76, 0x61, 0xff, 0x13, 0xff, 0xe1, 0x90, 0x88, + 0xd3, 0x1e, 0x30, 0xac, 0xe7, 0x86, 0x28, 0xda, 0x49, 0x83, 0xbf, 0x44, 0x4d, 0x95, 0xc6, 0x4e, + 0x20, 0x81, 0x4e, 0xe9, 0xac, 0xf3, 0x81, 0xdc, 0xf4, 0x2a, 0x21, 0x50, 0x2c, 0xc1, 0x70, 0x53, + 0xd1, 0x2b, 0x7a, 0x97, 0xf9, 0x79, 0xe7, 0x1a, 0x2f, 0x04, 0xc5, 0xcf, 0x57, 0x6a, 0x76, 0x35, + 0xf0, 0x5b, 0xbb, 0xb4, 0xc7, 0xba, 0x54, 0xf8, 0x5c, 0xd7, 0xa5, 0x4d, 0x2e, 0x54, 0xc9, 0xe9, + 0xff, 0x98, 0xb4, 0xa7, 0xc5, 0xdd, 0x53, 0xfc, 0x75, 0x2d, 0x2d, 0xb3, 0x7d, 0xa6, 0x9a, 0x6b, + 0xcd, 0x49, 0xff, 0x17, 0x2f, 0xf0, 0x62, 0xa8, 0xa5, 0x1a, 0x98, 0x42, 0x34, 0xc0, 0xb8, 0x88, + 0x63, 0x58, 0x00, 0x96, 0x15, 0x10, 0x09, 0x48, 0x82, 0x65, 0x48, 0x0d, 0x41, 0x6b, 0x76, 0xd0, + 0xbc, 0x28, 0xe0, 0x05, 0xaf, 0x05, 0xd4, 0x46, 0x92, 0x82, 0x40, 0x09, 0x31, 0xe0, 0x05, 0x8c, + 0xe8, 0x0b, 0xeb, 0x51, 0x25, 0x5f, 0x0c, 0xdd, 0x97, 0xf8, 0x93, 0x8b, 0x8b, 0x8b, 0x89, 0xb0, + 0x2f, 0x8b, 0xe1, 0xa2, 0x10, 0x02, 0x5c, 0xc4, 0x98, 0x6e, 0x6f, 0xf5, 0xa6, 0x4f, 0x27, 0xe9, + 0xbb, 0x30, 0xf1, 0x0a, 0x04, 0x5b, 0x34, 0xde, 0x5f, 0xfe, 0xf7, 0xbb, 0xfb, 0xf1, 0x22, 0x46, + 0x17, 0x3e, 0xd9, 0xbd, 0xe4, 0xa5, 0x62, 0xbb, 0xf1, 0x20, 0xaa, 0xed, 0xdb, 0x54, 0xf8, 0x55, + 0xaa, 0xd6, 0x3b, 0x82, 0x00, 0x52, 0x14, 0x10, 0x15, 0x56, 0x6c, 0x5c, 0xf0, 0x30, 0x29, 0x09, + 0x4f, 0x00, 0x02, 0x18, 0x17, 0x85, 0x8d, 0x13, 0xd4, 0x74, 0x0b, 0x9e, 0x79, 0xc0, 0x13, 0x10, + 0xd5, 0x10, 0x16, 0x24, 0x90, 0x40, 0xaa, 0xb4, 0x84, 0x93, 0xa0, 0x04, 0x03, 0xa5, 0x67, 0x05, + 0x00, 0x49, 0x0a, 0x46, 0x12, 0x00, 0x0a, 0x45, 0x31, 0x71, 0x12, 0x12, 0xbb, 0x18, 0xc2, 0xc1, + 0x96, 0x33, 0xc4, 0x30, 0x13, 0xde, 0xa5, 0x3e, 0x7c, 0x04, 0x82, 0xe8, 0x00, 0x08, 0x99, 0x13, + 0x8d, 0x0b, 0x77, 0x6c, 0x6f, 0xe2, 0x46, 0x09, 0x3d, 0xf3, 0x89, 0xf2, 0xf1, 0x1c, 0x92, 0xf6, + 0xcb, 0xc5, 0xc9, 0xef, 0x7c, 0x48, 0x28, 0x0a, 0x1c, 0xe1, 0x50, 0xbd, 0x6d, 0xb6, 0xc6, 0x38, + 0xf1, 0x1a, 0x45, 0xdc, 0xc4, 0x9b, 0x43, 0xaa, 0x13, 0xa8, 0x59, 0x90, 0x00, 0x45, 0xd7, 0x11, + 0x56, 0x6b, 0x54, 0xf9, 0xfa, 0xac, 0xab, 0xd6, 0xf8, 0x4e, 0x70, 0x40, 0x09, 0x24, 0xfc, 0xf5, + 0xae, 0xf7, 0x5a, 0xf1, 0x02, 0x06, 0x10, 0x5f, 0x5e, 0x1f, 0x95, 0x86, 0xd5, 0x64, 0xdd, 0xdd, + 0xf1, 0x21, 0x01, 0x93, 0x74, 0xeb, 0x77, 0x71, 0x58, 0xaf, 0x32, 0x46, 0xa9, 0xa6, 0xbc, 0x14, + 0x04, 0xa4, 0x51, 0x5a, 0x15, 0x05, 0x27, 0x62, 0xe1, 0x80, 0x4d, 0xd3, 0x33, 0x16, 0x19, 0x7e, + 0x3b, 0x71, 0x21, 0x11, 0xe4, 0xd8, 0xcd, 0xcd, 0x99, 0xd6, 0x15, 0x55, 0xb5, 0xe2, 0x41, 0x2c, + 0x41, 0xf5, 0x94, 0x6b, 0x27, 0x61, 0xe3, 0xf7, 0x08, 0x89, 0x05, 0x5a, 0xdf, 0x57, 0xd5, 0x8d, + 0xbe, 0xf1, 0x20, 0x86, 0xef, 0xbb, 0xee, 0xa9, 0x7e, 0x0b, 0x39, 0x32, 0xe5, 0x62, 0x56, 0x39, + 0x21, 0xaf, 0xa2, 0xf7, 0xcc, 0x46, 0xdc, 0xac, 0xbb, 0x7c, 0x23, 0xd5, 0x3b, 0x66, 0x49, 0x06, + 0xb4, 0xfe, 0x2f, 0x4d, 0xe7, 0x61, 0xd4, 0xd9, 0xe1, 0x22, 0x4b, 0x89, 0xb7, 0xd6, 0x3c, 0x83, + 0xc6, 0x1a, 0x7a, 0x3d, 0xc5, 0x1b, 0xcd, 0x96, 0x0c, 0xf8, 0xb3, 0x88, 0x12, 0x33, 0xc5, 0x6e, + 0xf3, 0xc1, 0xea, 0x3e, 0x8b, 0x97, 0xbb, 0x0f, 0xe4, 0xb3, 0x31, 0x11, 0x87, 0x0c, 0x53, 0x34, + 0x05, 0x32, 0x4f, 0x58, 0xeb, 0x4c, 0x36, 0xe0, 0x09, 0x20, 0x46, 0x1e, 0x45, 0x6e, 0x62, 0x38, + 0x14, 0xa9, 0x00, 0x02, 0xfe, 0x3c, 0x9c, 0x7e, 0xfe, 0x10, 0xde, 0xf8, 0x81, 0xc4, 0x9e, 0xf8, + 0x5d, 0xc0, 0x0c, 0x1c, 0x72, 0xeb, 0x26, 0xf3, 0x7a, 0xa2, 0xef, 0x44, 0xa8, 0xa5, 0x86, 0x99, + 0x03, 0xc1, 0x5a, 0xff, 0xfd, 0x55, 0xb8, 0x98, 0x93, 0xae, 0x6e, 0xf9, 0xd4, 0x71, 0x01, 0x03, + 0x17, 0x15, 0xbe, 0x10, 0x10, 0x3c, 0x95, 0xa4, 0xa2, 0xe9, 0x44, 0x2a, 0x22, 0x05, 0x41, 0x58, + 0x85, 0x94, 0x25, 0x5e, 0x5b, 0x6f, 0xff, 0xf0, 0xe2, 0x28, 0x00, 0x4b, 0x4e, 0x93, 0xb3, 0x0a, + 0x7f, 0xfd, 0xf9, 0xe1, 0xf2, 0xd7, 0xe5, 0xea, 0xde, 0x17, 0x4c, 0x77, 0x18, 0x54, 0xf6, 0x7f, + 0x86, 0x06, 0x88, 0x27, 0x00, 0xd4, 0xb1, 0x48, 0x44, 0x7a, 0x99, 0x98, 0x4b, 0xbc, 0xa6, 0x58, + 0x87, 0xc9, 0xc0, 0xa6, 0x0a, 0x21, 0xd0, 0x6b, 0x80, 0x93, 0x45, 0x9a, 0x67, 0x7e, 0x05, 0x84, + 0x89, 0xff, 0xa5, 0xf5, 0xd9, 0x43, 0x4a, 0x6b, 0x5f, 0x57, 0xea, 0x2e, 0x4f, 0x84, 0x69, 0x67, + 0xe5, 0x66, 0x87, 0xb1, 0xc9, 0xd4, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5b, 0x2d, 0xb0, 0x7a, + 0x3f, 0x42, 0xfa, 0x1d, 0xe8, 0xbd, 0x0b, 0xf2, 0x52, 0xac, 0x5f, 0x54, 0xa9, 0x75, 0x2a, 0x7d, + 0x72, 0xfa, 0x95, 0x67, 0xd7, 0x2a, 0xea, 0x54, 0xb8, 0x46, 0x17, 0xde, 0xc6, 0x1a, 0xc6, 0x26, + 0x77, 0x34, 0x77, 0xcb, 0xfa, 0xa6, 0x5a, 0x43, 0x38, 0x26, 0x99, 0x4f, 0x37, 0xff, 0x6d, 0xbf, + 0x07, 0x19, 0x81, 0x80, 0xd9, 0x81, 0x00, 0x42, 0xa7, 0x85, 0xba, 0xa5, 0x4f, 0xa8, 0xe3, 0x7d, + 0x5a, 0x17, 0xeb, 0x15, 0xc1, 0x4d, 0x6b, 0x80, 0xa1, 0x82, 0xea, 0xae, 0x2b, 0x15, 0xbb, 0xd7, + 0x02, 0x40, 0x20, 0x05, 0xd5, 0x8d, 0x99, 0xe6, 0xcd, 0x47, 0xdf, 0x04, 0x77, 0x71, 0x1e, 0x70, + 0x3e, 0x2b, 0xeb, 0xde, 0x11, 0x0a, 0x42, 0xad, 0x3f, 0xaa, 0xd8, 0xc5, 0x67, 0xc3, 0x18, 0xc8, + 0x3f, 0x7f, 0x93, 0xff, 0x63, 0x81, 0x00, 0x1c, 0x82, 0xcb, 0xbe, 0x6c, 0xbb, 0x1a, 0x5a, 0xc1, + 0x0e, 0xc3, 0xca, 0x1b, 0x0c, 0x31, 0xff, 0xa7, 0xb7, 0xdb, 0x27, 0xb6, 0xd3, 0x4d, 0xdf, 0x58, + 0xdf, 0x54, 0xe9, 0xf1, 0x93, 0xd0, 0xf4, 0xcf, 0x43, 0xd3, 0x3d, 0x0f, 0x4c, 0xf4, 0x3d, 0x31, + 0x5c, 0x12, 0xf3, 0xd0, 0xf4, 0xcf, 0x43, 0xd0, 0xc9, 0x5d, 0x5f, 0xea, 0xd5, 0xc1, 0x3d, 0xef, + 0xbd, 0xd2, 0xa2, 0x74, 0x47, 0x57, 0x56, 0x84, 0x07, 0x90, 0x48, 0x0e, 0xa4, 0xd3, 0x01, 0xde, + 0x08, 0x3d, 0xdf, 0xf0, 0x34, 0xd4, 0x79, 0x61, 0xc6, 0x5f, 0xfb, 0xdf, 0xe8, 0xfd, 0x0e, 0x86, + 0xae, 0xaf, 0x80, 0x48, 0x42, 0x03, 0x45, 0x5d, 0xb8, 0xac, 0x56, 0x7c, 0xe2, 0xea, 0x29, 0x97, + 0xc5, 0xc7, 0x30, 0x3b, 0x78, 0x65, 0xf7, 0xe0, 0x12, 0x10, 0x70, 0x34, 0x20, 0x39, 0x07, 0xca, + 0x00, 0xaa, 0x83, 0x08, 0x0e, 0x85, 0x44, 0x1a, 0x01, 0x70, 0x03, 0x14, 0x16, 0x01, 0x74, 0x07, + 0x83, 0xa3, 0x2c, 0x47, 0x98, 0x07, 0xe8, 0x1f, 0x87, 0x51, 0x48, 0x1d, 0x0a, 0x2f, 0x06, 0xe4, + 0x75, 0x8b, 0x17, 0xc4, 0x70, 0x0e, 0xe1, 0x68, 0x7c, 0x81, 0xc0, 0xf7, 0xf8, 0x19, 0x18, 0x0d, + 0x07, 0x20, 0x00, 0x20, 0x03, 0x14, 0x77, 0xc1, 0xc4, 0x16, 0x22, 0x9f, 0xc1, 0x18, 0x44, 0xb6, + 0x2b, 0xed, 0xf2, 0xf8, 0x24, 0xde, 0x86, 0xdc, 0x18, 0xc1, 0x25, 0xd1, 0x28, 0x40, 0xe0, 0xfb, + 0x82, 0x46, 0x4c, 0x3a, 0x8c, 0x00, 0x16, 0x6c, 0xca, 0xff, 0x32, 0x3d, 0x5a, 0x4f, 0xdf, 0x7f, + 0xff, 0x3f, 0xb3, 0x03, 0xa0, 0x8d, 0xc0, 0x5f, 0x14, 0xbd, 0x22, 0x66, 0x6d, 0x36, 0xc2, 0xee, + 0x00, 0x08, 0x88, 0xc2, 0x54, 0xca, 0x42, 0xb9, 0x3a, 0x1e, 0xff, 0x8a, 0x59, 0x68, 0x32, 0x43, + 0xf1, 0xec, 0x3e, 0x20, 0x31, 0xc0, 0xe1, 0x04, 0xc2, 0x73, 0xfa, 0x57, 0xcb, 0xeb, 0xdf, 0x5c, + 0xa3, 0x79, 0x27, 0xa3, 0xfe, 0xae, 0x57, 0x29, 0x2f, 0x7f, 0x05, 0x1d, 0xdf, 0x77, 0x8e, 0x4f, + 0xd5, 0x8f, 0x98, 0xae, 0xae, 0xbe, 0xb3, 0x49, 0xd4, 0xc2, 0xae, 0xb9, 0x49, 0xc5, 0xf5, 0x5d, + 0x57, 0xd6, 0xaf, 0xad, 0x2d, 0x75, 0xee, 0x03, 0x46, 0x09, 0x2a, 0xaa, 0xa3, 0x8d, 0xc4, 0x06, + 0x01, 0x47, 0x2d, 0x36, 0x22, 0xb0, 0x91, 0x45, 0x06, 0x1c, 0x98, 0x00, 0xb6, 0xd2, 0x23, 0xef, + 0xfe, 0xeb, 0xf2, 0x99, 0x3f, 0x53, 0x4b, 0x26, 0xc7, 0x60, 0x62, 0x08, 0xa0, 0x45, 0x8f, 0x4e, + 0x3d, 0x4e, 0x3e, 0x25, 0xf1, 0x23, 0xf0, 0x09, 0x48, 0x30, 0x1a, 0x38, 0x71, 0x3e, 0xc9, 0x35, + 0x37, 0x00, 0x1e, 0x71, 0x93, 0x2a, 0x70, 0x00, 0x64, 0x92, 0xd1, 0x74, 0xde, 0x01, 0x61, 0xc2, + 0xa5, 0x82, 0xc7, 0x21, 0x72, 0xc0, 0x59, 0x40, 0x91, 0x01, 0xc0, 0x3c, 0x3a, 0x87, 0x41, 0xe0, + 0x7c, 0xaa, 0x0c, 0xe0, 0x20, 0x80, 0xa0, 0xc4, 0x00, 0xcb, 0x7b, 0x72, 0xce, 0x5f, 0xc1, 0x48, + 0x64, 0xa3, 0x41, 0x1a, 0x19, 0x52, 0xb3, 0xad, 0x00, 0x61, 0xc3, 0xbb, 0xf4, 0x57, 0xe1, 0x98, + 0x2a, 0x15, 0x55, 0x8b, 0x90, 0x8a, 0x61, 0x93, 0x49, 0x40, 0x65, 0x1e, 0x02, 0x65, 0x1b, 0x4d, + 0x01, 0xcf, 0xd3, 0x11, 0x18, 0x19, 0x5c, 0xa8, 0x0e, 0x56, 0x30, 0x87, 0x88, 0x60, 0x02, 0xde, + 0x12, 0xc7, 0x39, 0x05, 0xae, 0x0e, 0x63, 0xdf, 0x8b, 0x5b, 0x75, 0xa6, 0x16, 0x3c, 0x28, 0x49, + 0x51, 0x48, 0xa9, 0xc3, 0xd2, 0xb4, 0x9c, 0x8f, 0x16, 0x64, 0x81, 0xe7, 0xf9, 0x7f, 0x0f, 0xec, + 0x45, 0x12, 0x77, 0xf2, 0xd5, 0xfd, 0xe3, 0x4d, 0x38, 0x6d, 0x94, 0x1c, 0xa4, 0x1b, 0xeb, 0x05, + 0xb5, 0xc3, 0xe3, 0x0c, 0x9c, 0x6e, 0x51, 0xfa, 0x60, 0x05, 0x73, 0x4e, 0x00, 0xae, 0x7e, 0x34, + 0x75, 0xf7, 0x5a, 0xf0, 0x38, 0x41, 0x20, 0x44, 0x5d, 0x45, 0xc5, 0xdf, 0xea, 0x75, 0xdf, 0x16, + 0x27, 0x69, 0xad, 0xa6, 0xbc, 0x58, 0x85, 0x57, 0x75, 0x57, 0x75, 0xcb, 0x7d, 0xfd, 0x15, 0xe5, + 0xc4, 0x82, 0x83, 0x34, 0xd6, 0xd3, 0x5c, 0x52, 0x75, 0x7f, 0xac, 0x5f, 0x57, 0x3e, 0xb5, 0xf4, + 0x50, 0x06, 0xc7, 0xa2, 0xc7, 0x6b, 0x6d, 0xb6, 0xdf, 0xbe, 0x30, 0x8f, 0x7b, 0xde, 0xb5, 0xde, + 0xfe, 0x0a, 0x24, 0xa1, 0x29, 0xc9, 0x42, 0x53, 0x25, 0xf4, 0x69, 0xcf, 0x82, 0x4e, 0xee, 0x43, + 0x7d, 0x79, 0x1f, 0x10, 0x09, 0x67, 0xed, 0xb6, 0xdc, 0xec, 0x79, 0xc7, 0x85, 0x84, 0x34, 0xe6, + 0xdc, 0x9d, 0xea, 0x52, 0x97, 0xd3, 0xff, 0x85, 0x06, 0xee, 0xe9, 0x24, 0xab, 0xa4, 0x91, 0xe8, + 0xfa, 0x45, 0x11, 0x2c, 0x20, 0xa1, 0x7e, 0x3a, 0xdb, 0x6d, 0xb7, 0xfe, 0xa2, 0x91, 0xf2, 0x57, + 0x7f, 0x0f, 0xf7, 0x75, 0x57, 0x75, 0x55, 0x55, 0x4d, 0x34, 0xd3, 0xff, 0x2e, 0xe2, 0xb7, 0x5c, + 0xb7, 0x77, 0x7e, 0x20, 0x5d, 0x6b, 0xbd, 0x1f, 0x8b, 0xea, 0xba, 0xaf, 0x9a, 0xb5, 0x5f, 0x09, + 0x1f, 0x2e, 0x0a, 0xcb, 0x9f, 0xe6, 0x35, 0xef, 0xc0, 0x80, 0x6d, 0x55, 0x70, 0x72, 0x0e, 0x02, + 0x9c, 0xd8, 0x6c, 0xf1, 0x55, 0x8e, 0x53, 0xdb, 0x2e, 0x45, 0xdc, 0x32, 0x0c, 0x06, 0x8c, 0x6c, + 0x5b, 0x50, 0xed, 0xb3, 0x46, 0x02, 0xa0, 0xea, 0xf6, 0xc5, 0x90, 0x94, 0xa8, 0xb9, 0x7a, 0x8a, + 0x69, 0x9f, 0x24, 0xe7, 0x50, 0x50, 0x3f, 0xa4, 0xd8, 0x63, 0x90, 0x19, 0x8e, 0x20, 0xa5, 0x93, + 0x83, 0xff, 0xb8, 0x3a, 0xbc, 0x2e, 0xc4, 0x00, 0x57, 0x92, 0x05, 0xd8, 0x85, 0x07, 0x6f, 0xf7, + 0x4e, 0x59, 0x8a, 0xf3, 0x17, 0x2c, 0x31, 0x03, 0xcf, 0x00, 0xce, 0x1f, 0x14, 0xdc, 0x50, 0xd9, + 0x86, 0xd9, 0xc1, 0xfa, 0x06, 0x2d, 0x44, 0xb6, 0x78, 0x74, 0xe3, 0x2c, 0x7f, 0x14, 0x07, 0x14, + 0x07, 0xf1, 0xc7, 0x4f, 0x09, 0xe1, 0x5a, 0xe1, 0xe2, 0x0d, 0x04, 0x0c, 0x79, 0xed, 0xbf, 0xab, + 0xfe, 0x2d, 0x1e, 0xbb, 0x7e, 0x0a, 0x02, 0x81, 0x21, 0x58, 0x80, 0x05, 0x87, 0x38, 0x01, 0x60, + 0xf5, 0x89, 0x33, 0x01, 0x4d, 0x12, 0x8f, 0x30, 0x20, 0x54, 0x33, 0x25, 0x80, 0x03, 0x13, 0x64, + 0xb0, 0x00, 0x23, 0x2a, 0x8f, 0x8c, 0xc0, 0x11, 0xb8, 0x3a, 0x1f, 0x21, 0x60, 0x2a, 0x0e, 0xc7, + 0xe1, 0xa2, 0x14, 0x0e, 0xc2, 0xa4, 0xd0, 0x71, 0x0b, 0x53, 0x4e, 0xb7, 0xbf, 0x90, 0xef, 0x41, + 0xeb, 0x95, 0x97, 0x32, 0xa5, 0xb3, 0x80, 0x61, 0x65, 0x83, 0x2e, 0xbd, 0xee, 0x2b, 0x0e, 0x80, + 0xac, 0x15, 0xa5, 0x00, 0x56, 0x71, 0x1d, 0x42, 0xee, 0x04, 0x31, 0xbc, 0x57, 0x35, 0xd7, 0x6f, + 0x72, 0xc7, 0xf2, 0xc1, 0xcb, 0x07, 0xff, 0x70, 0x34, 0x08, 0x04, 0x21, 0x13, 0xa8, 0xca, 0x4b, + 0x8d, 0x57, 0x82, 0xe9, 0xb2, 0x4f, 0xdd, 0xa1, 0x4c, 0xeb, 0xc1, 0x0d, 0x9a, 0xef, 0xf0, 0x43, + 0x55, 0xd2, 0x87, 0xab, 0xd7, 0x58, 0xbe, 0xa5, 0x4f, 0x10, 0xbd, 0x84, 0x17, 0xc4, 0x5a, 0xdb, + 0x6d, 0xb6, 0xff, 0x44, 0x2a, 0xfe, 0xb1, 0x7d, 0x6b, 0xea, 0xdf, 0x5a, 0xfa, 0xb1, 0xf0, 0x53, + 0x7b, 0xbd, 0x6d, 0x55, 0xdd, 0xeb, 0x97, 0xa8, 0xbb, 0xe7, 0x09, 0x9e, 0x9e, 0x13, 0xc3, 0xe5, + 0xc2, 0x08, 0x24, 0x3e, 0xfa, 0xd7, 0x11, 0xfa, 0xc5, 0x5c, 0x36, 0x29, 0xf3, 0x64, 0xb7, 0x97, + 0xad, 0x4d, 0xfc, 0x12, 0x8b, 0xdd, 0xf7, 0x7a, 0xac, 0x4f, 0xc9, 0xdd, 0xf8, 0x9f, 0x9b, 0xaa, + 0xae, 0x6e, 0xaa, 0x4e, 0x6a, 0xaf, 0xc4, 0x02, 0x3a, 0xa7, 0xb1, 0xe1, 0x1c, 0x24, 0x42, 0x06, + 0x5f, 0xc4, 0x9c, 0x5d, 0xad, 0x6d, 0xf0, 0xd9, 0x05, 0x00, 0x07, 0xeb, 0x15, 0x2a, 0x82, 0x5c, + 0xb8, 0xc3, 0xf1, 0x51, 0x6a, 0x30, 0x7b, 0x67, 0x3c, 0x61, 0x11, 0xe6, 0x81, 0xc7, 0xc9, 0xe0, + 0x30, 0xc4, 0x80, 0x0b, 0x00, 0x42, 0xc0, 0x60, 0x0c, 0x65, 0xb8, 0xad, 0xcf, 0xc1, 0xcf, 0x0c, + 0x21, 0x32, 0x10, 0x00, 0xb1, 0x40, 0xe8, 0x32, 0x22, 0x1e, 0xd5, 0x14, 0xe4, 0x89, 0xe1, 0x65, + 0xb7, 0xa2, 0x23, 0x10, 0x84, 0x8c, 0x09, 0xc6, 0x87, 0x83, 0x02, 0x70, 0x69, 0x0d, 0xb3, 0x80, + 0x0e, 0xfb, 0x64, 0x4c, 0x64, 0x36, 0xaf, 0x66, 0x87, 0xcb, 0x0e, 0x58, 0x1f, 0xca, 0xa9, 0x21, + 0x24, 0x2f, 0x7e, 0x24, 0x32, 0x17, 0x13, 0x1e, 0x5a, 0x9a, 0xee, 0xe5, 0x61, 0x8c, 0x03, 0x96, + 0x00, 0x7a, 0xc4, 0x98, 0x5e, 0x2b, 0xc4, 0x01, 0x80, 0x28, 0x10, 0x38, 0x1e, 0x78, 0xc4, 0xe0, + 0x16, 0x05, 0x1d, 0xa0, 0xe0, 0x0c, 0x0a, 0xc0, 0x2a, 0x15, 0x42, 0x40, 0x50, 0x84, 0xa7, 0x80, + 0x2a, 0x0b, 0x59, 0x38, 0x2a, 0xee, 0x78, 0x7a, 0x8a, 0x1e, 0x16, 0x2f, 0x23, 0x38, 0x5d, 0x09, + 0x00, 0x60, 0xd0, 0x3f, 0x24, 0x14, 0x93, 0x5d, 0xbd, 0xef, 0x84, 0x4b, 0x02, 0xdc, 0x56, 0xee, + 0xf8, 0x3b, 0xe0, 0xf8, 0xb6, 0x42, 0x0e, 0x51, 0xf2, 0xe3, 0x7c, 0x0a, 0x01, 0x00, 0x46, 0x13, + 0x2e, 0x6e, 0x30, 0x54, 0x3d, 0x4a, 0x9f, 0x05, 0xb7, 0x9f, 0x25, 0x62, 0xf4, 0x5c, 0x78, 0x21, + 0xbb, 0xee, 0x3c, 0x12, 0x95, 0xdf, 0x77, 0xc8, 0x95, 0x89, 0xfa, 0x33, 0xfd, 0x6a, 0x4e, 0x8f, + 0x97, 0xc1, 0x09, 0x37, 0x74, 0x8b, 0x89, 0x53, 0xa7, 0xc1, 0x75, 0xdd, 0xf5, 0xac, 0x77, 0xc2, + 0x14, 0xa2, 0xbd, 0x6b, 0xaa, 0x97, 0x8b, 0xee, 0xfa, 0xab, 0xe7, 0xaa, 0xaa, 0xaf, 0xfa, 0xb5, + 0x73, 0xf5, 0x54, 0xc9, 0xff, 0xf4, 0x69, 0x7c, 0x96, 0x76, 0xd7, 0xc1, 0x2d, 0xa3, 0xe1, 0xb2, + 0xa9, 0xf3, 0x8b, 0xe7, 0x22, 0xbd, 0xb7, 0x37, 0xd3, 0xf8, 0x22, 0xde, 0xee, 0x7c, 0x14, 0x52, + 0x2e, 0x2e, 0xd5, 0xa7, 0x30, 0xa5, 0xe8, 0xf9, 0x4f, 0x01, 0x92, 0x10, 0x56, 0x30, 0xe9, 0x0c, + 0x00, 0x22, 0x0f, 0x22, 0x33, 0xd1, 0x3f, 0x5f, 0xff, 0x11, 0xea, 0x59, 0x81, 0x41, 0x70, 0x24, + 0x14, 0x8b, 0xc5, 0xef, 0x15, 0xc3, 0x6c, 0xc0, 0x03, 0x94, 0x27, 0xda, 0x04, 0x48, 0x3d, 0xba, + 0x08, 0xfb, 0x27, 0xb7, 0x6c, 0x0b, 0x06, 0xc1, 0x90, 0xb9, 0x73, 0x98, 0x0f, 0xe0, 0x70, 0xc0, + 0x7f, 0x01, 0x05, 0xc4, 0x2a, 0xf7, 0xae, 0xb8, 0x5c, 0x84, 0x00, 0x6a, 0x8b, 0x30, 0x60, 0x8c, + 0xb0, 0xfa, 0x1e, 0xaf, 0x17, 0xcf, 0x30, 0x9d, 0x85, 0xf8, 0x12, 0xb0, 0xbf, 0x05, 0x86, 0x58, + 0x16, 0x1b, 0x60, 0x7a, 0xc0, 0xef, 0x12, 0x66, 0xe0, 0xef, 0x11, 0xf7, 0x02, 0x80, 0x21, 0x12, + 0x34, 0x70, 0x4f, 0xe5, 0x41, 0x7a, 0x64, 0xea, 0xdb, 0xfc, 0xc3, 0xa4, 0x30, 0x00, 0x7f, 0x0d, + 0x74, 0x43, 0x1c, 0x5e, 0x30, 0xd7, 0x9f, 0xdf, 0x17, 0x51, 0x07, 0xfa, 0x9c, 0x07, 0xa9, 0x20, + 0x01, 0xa0, 0x35, 0x47, 0x57, 0x2f, 0x7d, 0xef, 0xc4, 0x82, 0x93, 0x1e, 0x3c, 0x9f, 0x42, 0x88, + 0xe8, 0x7f, 0x92, 0x58, 0xdb, 0x3e, 0xfd, 0x3c, 0xb0, 0x5e, 0x71, 0x50, 0xd8, 0x5c, 0x87, 0x1e, + 0xaf, 0xeb, 0x5f, 0xab, 0xa9, 0xd6, 0xc2, 0xec, 0xc0, 0x10, 0x82, 0x6a, 0x1f, 0xa9, 0xdd, 0xfd, + 0x13, 0xa2, 0x7f, 0x1d, 0x93, 0x80, 0x80, 0x82, 0x10, 0xab, 0xbe, 0x3a, 0xab, 0xa2, 0x80, 0xd7, + 0xd1, 0x1b, 0xeb, 0xdf, 0x45, 0x47, 0x6b, 0xa2, 0x37, 0x89, 0x57, 0xfa, 0xb7, 0xd5, 0xfe, 0xad, + 0xf5, 0x7f, 0xab, 0xfd, 0x5b, 0xea, 0xde, 0x27, 0xea, 0xf2, 0x74, 0x4e, 0xfa, 0xbd, 0x75, 0xea, + 0xe0, 0x94, 0xcd, 0x34, 0xd3, 0x5b, 0x4d, 0x38, 0xf0, 0x95, 0xa6, 0xb6, 0x9a, 0xdf, 0x04, 0x85, + 0xd5, 0x4d, 0x7c, 0xb7, 0x75, 0x5f, 0x0c, 0x1e, 0x2b, 0x8a, 0xde, 0xf9, 0xfe, 0xdb, 0x6d, 0xb7, + 0xe0, 0xbc, 0xc3, 0x8b, 0xea, 0xee, 0xee, 0xcb, 0x97, 0xd3, 0x53, 0x7f, 0xce, 0x45, 0x74, 0xd9, + 0xa7, 0xfe, 0x72, 0xaf, 0xa6, 0x9a, 0x69, 0xfa, 0xbd, 0xf4, 0x58, 0xc7, 0xd5, 0x8f, 0x10, 0x0a, + 0x6e, 0xfe, 0xee, 0xd3, 0x5f, 0x2a, 0xe2, 0x55, 0x8a, 0xea, 0xe7, 0x01, 0x92, 0x25, 0x47, 0x6c, + 0x36, 0x41, 0x80, 0x26, 0x23, 0x50, 0xda, 0xef, 0x3d, 0x5d, 0x5e, 0xf8, 0xbb, 0x8b, 0xc4, 0xf1, + 0xc5, 0xd9, 0x6f, 0xc3, 0x6e, 0x00, 0x6f, 0x42, 0x62, 0x30, 0x38, 0x9f, 0xf7, 0x11, 0xec, 0x86, + 0x48, 0x96, 0xdd, 0x02, 0xd9, 0xf8, 0x58, 0xc9, 0x1c, 0x48, 0xc0, 0xf0, 0xc0, 0x48, 0xc0, 0x94, + 0x37, 0x05, 0xd0, 0x6f, 0xf5, 0x45, 0x45, 0x0b, 0x90, 0x40, 0x04, 0x89, 0x20, 0x1f, 0x25, 0x07, + 0xc7, 0xd3, 0xd1, 0xde, 0x2b, 0xbd, 0xf1, 0x5d, 0x89, 0x60, 0xe6, 0x81, 0x6c, 0xfc, 0x25, 0x86, + 0xa1, 0x50, 0x06, 0xbe, 0x82, 0x40, 0xdb, 0xfa, 0xfe, 0xb1, 0x27, 0x61, 0xb2, 0x04, 0x80, 0x05, + 0xe7, 0x32, 0x80, 0x47, 0x29, 0x00, 0x82, 0xcb, 0xde, 0xac, 0xd0, 0xb3, 0xb2, 0x3b, 0xe2, 0xf1, + 0x4c, 0x4e, 0x07, 0x79, 0x37, 0x07, 0x7c, 0x0e, 0xef, 0x7f, 0xc1, 0x40, 0x09, 0x90, 0xa1, 0x49, + 0xd4, 0x28, 0xe8, 0x34, 0xcf, 0xef, 0xf7, 0xeb, 0x3a, 0x52, 0x68, 0x1f, 0x7e, 0x2b, 0x10, 0xe4, + 0xd8, 0x5d, 0xc1, 0x2b, 0x0a, 0xb3, 0xff, 0xd6, 0x6e, 0xdf, 0xf0, 0xd9, 0x08, 0x00, 0x29, 0x71, + 0x0d, 0xe4, 0xa2, 0xfb, 0x15, 0xc4, 0xe8, 0x4c, 0xd8, 0xf8, 0xa6, 0x4e, 0x37, 0x02, 0xa7, 0x04, + 0xed, 0xcf, 0xd7, 0xd5, 0xfe, 0x11, 0xae, 0x82, 0xad, 0x24, 0x40, 0x9f, 0x10, 0x71, 0x8b, 0x93, + 0x9b, 0xff, 0x88, 0xcf, 0x9e, 0x92, 0x5e, 0x7a, 0xa7, 0x2f, 0xf9, 0x78, 0xb1, 0x7a, 0xaa, 0xaa, + 0xa8, 0x8e, 0x53, 0x3d, 0xfe, 0x4b, 0x1b, 0x4c, 0x7f, 0x04, 0xa7, 0x55, 0xdd, 0xf6, 0xae, 0x6b, + 0xbe, 0xba, 0x95, 0x7f, 0x52, 0x27, 0xd6, 0xbe, 0xaf, 0xf0, 0x5d, 0xe4, 0x61, 0x6b, 0x6a, 0xe7, + 0xaa, 0x69, 0xb6, 0xdf, 0xf8, 0xa3, 0x3b, 0xea, 0xb9, 0xf1, 0x3e, 0x27, 0x82, 0x1f, 0x01, 0x52, + 0x24, 0x10, 0x95, 0xdd, 0xdf, 0xb0, 0xdb, 0x18, 0x00, 0xb6, 0x04, 0x5a, 0x48, 0x97, 0x3d, 0x49, + 0xab, 0xb7, 0xc5, 0xd5, 0x54, 0xbd, 0xa2, 0xef, 0x78, 0x6e, 0x50, 0x0b, 0xf4, 0x08, 0x80, 0x7e, + 0x97, 0xb3, 0xe3, 0x18, 0x0b, 0x37, 0x08, 0xc1, 0x30, 0xdc, 0xcf, 0xc2, 0x4f, 0x30, 0x3a, 0xc1, + 0x30, 0x0d, 0xc6, 0x30, 0x4c, 0x03, 0x71, 0xd0, 0x0e, 0xc0, 0xb0, 0x5e, 0x1c, 0x60, 0x16, 0x01, + 0xda, 0x0c, 0x4f, 0x7b, 0xc5, 0xe2, 0xf0, 0xbb, 0x14, 0x01, 0x11, 0x60, 0x94, 0x0a, 0xa8, 0xd1, + 0xbc, 0x9a, 0x8e, 0xde, 0xc5, 0x9f, 0xe5, 0xb2, 0x40, 0x98, 0x6e, 0x16, 0xd2, 0x02, 0xb0, 0xb6, + 0x17, 0x70, 0x76, 0x04, 0xee, 0x0e, 0xc0, 0x96, 0x39, 0x85, 0x41, 0x12, 0x58, 0x63, 0xc7, 0xe1, + 0xb6, 0x14, 0x00, 0x99, 0x2e, 0x47, 0x5d, 0x5f, 0x3a, 0xfd, 0x64, 0x83, 0xd9, 0xfa, 0xd6, 0x1b, + 0x62, 0xc5, 0x12, 0x39, 0x9c, 0x8c, 0x48, 0xc6, 0xb5, 0x88, 0xb0, 0xec, 0x62, 0xae, 0x2f, 0xa3, + 0xbb, 0xdf, 0xac, 0x2e, 0xc8, 0x00, 0x18, 0xca, 0x3d, 0x8f, 0x12, 0x14, 0x56, 0x7b, 0xd8, 0xcf, + 0xef, 0x79, 0xf9, 0xd8, 0x7f, 0x27, 0x68, 0x19, 0x98, 0xd5, 0x33, 0xc0, 0x58, 0x81, 0x00, 0x15, + 0xcd, 0x40, 0x22, 0x00, 0x54, 0x90, 0x31, 0x19, 0x08, 0x09, 0x18, 0x03, 0x40, 0xd9, 0x2f, 0x2f, + 0x00, 0x04, 0x1d, 0x67, 0x6b, 0xc0, 0x11, 0x54, 0xde, 0xef, 0x9f, 0xe8, 0x7f, 0x57, 0x09, 0x75, + 0x57, 0x7f, 0xc1, 0x37, 0x55, 0x77, 0xfb, 0xe8, 0x44, 0x1f, 0x5d, 0x89, 0xba, 0x3f, 0x7d, 0x7a, + 0x7e, 0x8f, 0x97, 0xd1, 0xbf, 0x7d, 0x15, 0xfe, 0xad, 0xf5, 0xef, 0xaf, 0x8f, 0x9e, 0xbe, 0xdb, + 0x6d, 0xb6, 0xb9, 0xc2, 0x26, 0x4e, 0x5d, 0x2e, 0xfa, 0xe8, 0x28, 0xf5, 0xd7, 0xab, 0x9e, 0xbe, + 0xaa, 0xab, 0xe8, 0xb9, 0xeb, 0xae, 0x52, 0xe2, 0x17, 0xb0, 0x87, 0x17, 0x8e, 0x9a, 0x7f, 0x0e, + 0x29, 0x0a, 0xfe, 0x92, 0x5e, 0xe8, 0xb0, 0x11, 0x7a, 0xfc, 0x36, 0xc2, 0x40, 0x0f, 0xfb, 0xc0, + 0x83, 0x7b, 0x29, 0xa1, 0xf6, 0x56, 0x5d, 0x2f, 0xf5, 0xc2, 0xe4, 0x28, 0x00, 0xeb, 0xe4, 0x04, + 0x7f, 0x0c, 0x76, 0xeb, 0xdd, 0x73, 0xb0, 0x88, 0x0c, 0x16, 0xb8, 0x3c, 0x50, 0x72, 0x84, 0x57, + 0x3c, 0xc2, 0xf1, 0x00, 0x1e, 0x5a, 0x04, 0x03, 0xca, 0xe4, 0x52, 0xb6, 0xb3, 0xb1, 0x67, 0x8b, + 0x0e, 0xf0, 0x89, 0xf8, 0x84, 0x5b, 0x27, 0x01, 0xa1, 0x63, 0x27, 0x01, 0xa1, 0x66, 0x31, 0x70, + 0xb0, 0xd4, 0x5c, 0x96, 0x18, 0x43, 0x40, 0x09, 0xca, 0xc9, 0xee, 0x63, 0x96, 0xff, 0x8d, 0x38, + 0xd3, 0x16, 0xc5, 0xb1, 0x6c, 0x5b, 0xcd, 0x85, 0xd8, 0xc0, 0x04, 0x87, 0x58, 0x2e, 0x3d, 0x79, + 0x45, 0x45, 0xf4, 0xc6, 0x70, 0x9a, 0x9c, 0x47, 0xe7, 0x99, 0xc3, 0x6c, 0x58, 0x11, 0xd9, 0x09, + 0xe6, 0x9a, 0x15, 0x9e, 0x78, 0x49, 0xe1, 0x3e, 0x9f, 0xf7, 0xbc, 0x26, 0xc5, 0x00, 0x01, 0x44, + 0xc4, 0x2c, 0x92, 0xc2, 0x06, 0x97, 0x16, 0x6f, 0x7b, 0xbe, 0x5a, 0xcf, 0xcc, 0xc1, 0xcf, 0x2e, + 0xee, 0x51, 0x3e, 0x1e, 0xee, 0xf0, 0xe8, 0x7c, 0x3b, 0x8b, 0x1e, 0x24, 0x22, 0x54, 0x13, 0xd1, + 0xfd, 0xda, 0xb7, 0xdb, 0xdb, 0x93, 0x87, 0xef, 0x75, 0x7b, 0xeb, 0x5a, 0xc9, 0xd3, 0x67, 0xff, + 0x45, 0xea, 0x89, 0x82, 0x3a, 0x74, 0xe3, 0x10, 0x5f, 0x04, 0x75, 0x5f, 0xab, 0xaf, 0x46, 0xf4, + 0x53, 0xae, 0xba, 0xb4, 0xdc, 0xfc, 0xc7, 0xc9, 0xa4, 0xdd, 0x74, 0x4e, 0xfa, 0xf7, 0xca, 0x46, + 0x9a, 0x69, 0xaf, 0x04, 0x27, 0xd5, 0x52, 0x7d, 0x13, 0x2b, 0xe8, 0xe4, 0x4a, 0xc4, 0x02, 0x8a, + 0x46, 0xa6, 0x6a, 0x7e, 0xe0, 0x20, 0x44, 0x82, 0x3a, 0xaf, 0xd8, 0x5c, 0x82, 0x00, 0x07, 0xfc, + 0x93, 0x1d, 0x86, 0xa5, 0x7d, 0x15, 0x17, 0xaa, 0xa9, 0x20, 0x8d, 0xe1, 0xb8, 0xa0, 0x02, 0x92, + 0xcc, 0x90, 0x12, 0x87, 0x12, 0xbd, 0xe9, 0xfd, 0x3d, 0xde, 0x35, 0x00, 0x0b, 0x5e, 0xf7, 0x85, + 0xc9, 0x00, 0x6d, 0x66, 0x81, 0x0a, 0xf7, 0x79, 0xa1, 0x62, 0x70, 0xbf, 0x0a, 0x9b, 0x85, 0xb2, + 0x50, 0xdc, 0x2c, 0x7e, 0xc3, 0x6c, 0x80, 0x01, 0xb7, 0x0d, 0xa2, 0x38, 0x5b, 0x60, 0x47, 0x6f, + 0xd7, 0xf7, 0x7c, 0x0b, 0xf3, 0xbd, 0x37, 0xa4, 0xe2, 0x70, 0x38, 0xf1, 0xf7, 0x38, 0x3d, 0x9c, + 0x65, 0x9b, 0xed, 0xf8, 0x79, 0x40, 0x22, 0xa6, 0x04, 0x60, 0x74, 0x3a, 0xbe, 0xe9, 0xa7, 0x4f, + 0x27, 0x8d, 0x6d, 0x4f, 0xb7, 0xe1, 0xb5, 0x00, 0x04, 0x56, 0x0a, 0xb0, 0x93, 0x45, 0xdb, 0x24, + 0x52, 0xe2, 0x69, 0xc6, 0x4e, 0xde, 0x9d, 0xd1, 0x72, 0xec, 0x99, 0xc0, 0x8c, 0x49, 0x87, 0x11, + 0x8a, 0xec, 0x57, 0x98, 0xab, 0xff, 0x0d, 0xb1, 0x20, 0x04, 0xd6, 0xd8, 0x26, 0x51, 0xf3, 0x57, + 0xbb, 0xdd, 0xc5, 0x6c, 0x9d, 0x90, 0xad, 0xc5, 0x62, 0x5e, 0x7b, 0xcc, 0x22, 0xb3, 0x5e, 0xf8, + 0x69, 0x8c, 0x00, 0x0f, 0x29, 0x3b, 0xa0, 0x46, 0x25, 0x24, 0xa6, 0x2f, 0xf8, 0x5d, 0x45, 0x30, + 0x51, 0xfc, 0x3a, 0x7c, 0xbd, 0x7f, 0x16, 0x62, 0xe3, 0xa7, 0xeb, 0x3d, 0xee, 0xe5, 0x99, 0x78, + 0xa7, 0xe7, 0xd0, 0x64, 0x76, 0xf8, 0x22, 0xae, 0xe5, 0x4f, 0xa3, 0x45, 0xf5, 0xeb, 0xe6, 0x3d, + 0x6b, 0xeb, 0xfb, 0xe8, 0x89, 0x51, 0xfa, 0x2f, 0x49, 0x81, 0xe0, 0x14, 0x05, 0x00, 0xd0, 0x00, + 0x21, 0xc1, 0xc6, 0x15, 0x03, 0x4e, 0xa4, 0x06, 0x80, 0x00, 0x80, 0x4a, 0x90, 0x06, 0x80, 0x00, + 0x80, 0x1a, 0x95, 0x27, 0xe2, 0xbf, 0xc1, 0xc0, 0x34, 0x00, 0x75, 0x0e, 0x06, 0x80, 0x2a, 0x88, + 0x5a, 0x2a, 0x87, 0x11, 0x40, 0x08, 0x44, 0x0d, 0x6b, 0x08, 0x4e, 0x94, 0x6e, 0xd7, 0xfd, 0x62, + 0xad, 0xa6, 0x2a, 0xe4, 0x15, 0x62, 0xae, 0xb1, 0x56, 0x23, 0x23, 0x2c, 0x5b, 0x16, 0xfe, 0x1c, + 0x94, 0x01, 0x40, 0x06, 0xe3, 0x1f, 0xb3, 0xf3, 0xfe, 0xdb, 0x62, 0xad, 0xb6, 0xc5, 0x58, 0xab, + 0x73, 0xfb, 0x6d, 0xf0, 0x40, 0x0b, 0x0e, 0xab, 0xe0, 0xf1, 0xe0, 0x3c, 0x79, 0xba, 0x55, 0xf2, + 0x97, 0x2e, 0x17, 0x3d, 0x5b, 0xea, 0xd5, 0xc2, 0x45, 0x55, 0x77, 0x77, 0xf8, 0x8b, 0xe8, 0xcf, + 0xf5, 0x65, 0x70, 0xd6, 0xb5, 0x65, 0x34, 0xd3, 0x4f, 0xfc, 0xf5, 0x72, 0xff, 0xdf, 0x56, 0xfa, + 0xde, 0xb0, 0x80, 0xb3, 0xee, 0xfb, 0xbf, 0x12, 0x08, 0xaa, 0xb8, 0xa2, 0xe0, 0x10, 0x10, 0x80, + 0xbe, 0xef, 0xbb, 0xc2, 0xe4, 0x08, 0x00, 0x0a, 0xb6, 0x14, 0x12, 0x7e, 0xca, 0x28, 0x34, 0xae, + 0xff, 0x55, 0x55, 0x4c, 0x1e, 0xb9, 0x3b, 0x38, 0xec, 0x16, 0x70, 0xd6, 0x00, 0x1a, 0xa2, 0x3b, + 0x66, 0x0a, 0x14, 0x0e, 0x19, 0xa7, 0x4d, 0x37, 0x64, 0x6e, 0x78, 0x3b, 0xe2, 0xb8, 0xae, 0xeb, + 0x15, 0xb6, 0x2f, 0x00, 0x0c, 0x26, 0x48, 0x01, 0x05, 0x63, 0x6f, 0x39, 0x90, 0xac, 0xe6, 0x85, + 0xec, 0x8b, 0xd8, 0x44, 0xf6, 0x05, 0x62, 0xe2, 0xb1, 0x74, 0x47, 0xac, 0x16, 0x07, 0xac, 0x43, + 0x44, 0x80, 0x1f, 0x6c, 0x66, 0xaa, 0x30, 0xde, 0xc1, 0x62, 0x5f, 0xd3, 0x20, 0x78, 0x30, 0x92, + 0x67, 0x07, 0x1e, 0x71, 0xe7, 0x1e, 0x71, 0xf3, 0x19, 0x7a, 0x67, 0x1e, 0x71, 0xe7, 0x1e, 0x71, + 0xed, 0x86, 0x94, 0x01, 0x41, 0x1f, 0xc2, 0xb5, 0xcf, 0x73, 0xf7, 0x57, 0xb6, 0x7f, 0x7b, 0x9f, + 0xd7, 0xc7, 0x3f, 0x0d, 0xa8, 0x0b, 0x48, 0x63, 0x4a, 0xb0, 0x59, 0x73, 0x49, 0xbf, 0x4c, 0xc9, + 0x75, 0xd7, 0x47, 0x74, 0x5d, 0x94, 0x6c, 0x95, 0x6e, 0x0b, 0x6f, 0x81, 0x6d, 0x67, 0xfd, 0x7c, + 0x22, 0x04, 0x80, 0xa1, 0x1b, 0x10, 0x0f, 0x1e, 0xa1, 0xcf, 0x27, 0x1a, 0x87, 0x43, 0xca, 0x83, + 0xba, 0x5a, 0xce, 0x1e, 0x7e, 0x58, 0xc9, 0xea, 0x16, 0x10, 0xc1, 0x0e, 0x0e, 0x21, 0x75, 0x50, + 0x30, 0x01, 0x10, 0x2c, 0x44, 0x2e, 0x01, 0x80, 0x01, 0x72, 0x0a, 0x63, 0x10, 0x30, 0x00, 0x10, + 0x0b, 0xe0, 0xe8, 0x30, 0x55, 0x54, 0x40, 0xc0, 0x02, 0xa0, 0xc8, 0x25, 0x57, 0xef, 0xaa, 0xa8, + 0x60, 0x3a, 0x05, 0xaf, 0xd7, 0x01, 0x0e, 0x75, 0xe3, 0x54, 0x33, 0xf0, 0x48, 0x11, 0xb7, 0x37, + 0xc3, 0xe4, 0xaa, 0xef, 0xab, 0xc6, 0xf0, 0x43, 0xba, 0xde, 0xba, 0xfe, 0x83, 0x71, 0xc0, 0x02, + 0x56, 0x60, 0x02, 0xf1, 0x96, 0x88, 0x1c, 0xe0, 0x00, 0xa8, 0xe6, 0xe3, 0x9b, 0xb3, 0xb3, 0x96, + 0x16, 0x50, 0x03, 0x64, 0x8e, 0x39, 0x95, 0x52, 0x78, 0xe6, 0x23, 0x20, 0xf8, 0x00, 0x08, 0x00, + 0xdb, 0x6f, 0x4d, 0x3e, 0x1e, 0xc0, 0x30, 0x04, 0x80, 0xdf, 0x03, 0x16, 0x26, 0x66, 0xe4, 0x59, + 0x71, 0x8d, 0xab, 0x71, 0x34, 0xf8, 0xeb, 0xef, 0xe0, 0xeb, 0xe3, 0xbf, 0x15, 0x62, 0xac, 0xb5, + 0x8a, 0xbd, 0x0d, 0x97, 0xc1, 0xff, 0x4d, 0xf0, 0xd3, 0x80, 0x1c, 0xb0, 0xf1, 0x8a, 0x3f, 0x56, + 0x93, 0xa6, 0x9f, 0x9f, 0xbf, 0xbf, 0xbf, 0xb6, 0xdb, 0xfb, 0xf8, 0xc1, 0x88, 0xac, 0x34, 0x8a, + 0x00, 0x48, 0xe3, 0xd0, 0x94, 0xf0, 0xbb, 0xfd, 0xb6, 0xeb, 0x6d, 0xb6, 0xdb, 0x6c, 0x55, 0x16, + 0xf0, 0x18, 0x00, 0x41, 0x05, 0x67, 0x15, 0xe2, 0x83, 0x15, 0x8a, 0x00, 0xc5, 0x18, 0x90, 0x07, + 0x0f, 0x1c, 0x7e, 0xa9, 0x85, 0x73, 0x09, 0x66, 0xcd, 0xdc, 0xbc, 0xc2, 0x1f, 0x5f, 0x04, 0x7d, + 0x57, 0x5e, 0x25, 0x58, 0xae, 0x08, 0x8e, 0x92, 0x49, 0x24, 0xdf, 0x58, 0xdf, 0x45, 0x88, 0xfa, + 0xe8, 0x8d, 0xc4, 0x54, 0x76, 0xfa, 0xf7, 0x10, 0x25, 0x72, 0xe0, 0x36, 0x6b, 0x97, 0x10, 0x19, + 0x05, 0x54, 0x92, 0xef, 0x78, 0xae, 0x21, 0xa1, 0xd3, 0x0f, 0x10, 0x24, 0x00, 0x47, 0x00, 0x35, + 0xd0, 0x9c, 0x08, 0xe0, 0x17, 0x9f, 0xd4, 0xe4, 0xec, 0xf1, 0xb3, 0xeb, 0x25, 0xe4, 0xf1, 0x97, + 0xc7, 0x7a, 0x47, 0xf5, 0xe1, 0x84, 0x70, 0x01, 0x88, 0x06, 0x55, 0x92, 0xa8, 0x3b, 0x9e, 0x1b, + 0x3f, 0x97, 0xd6, 0xdd, 0xdb, 0xaf, 0x9f, 0x97, 0x96, 0xd2, 0xa8, 0x5d, 0x90, 0x03, 0xa4, 0x38, + 0x1a, 0xa1, 0xd5, 0xd7, 0xf6, 0xae, 0xbe, 0xec, 0x32, 0x8e, 0x00, 0x1b, 0x9d, 0xa4, 0xe8, 0x52, + 0xf0, 0xd8, 0x6e, 0xf5, 0xe9, 0xb3, 0xcc, 0x93, 0xe4, 0xf4, 0xd9, 0xc9, 0xce, 0xf4, 0x51, 0x86, + 0x14, 0x00, 0xc0, 0xac, 0x88, 0x38, 0x1d, 0xba, 0x7d, 0x6b, 0xed, 0xb7, 0xa6, 0x78, 0x38, 0x85, + 0x22, 0x38, 0x3a, 0x02, 0xf6, 0x4a, 0x15, 0x24, 0x00, 0x02, 0x0a, 0x53, 0x29, 0x67, 0x18, 0x80, + 0x71, 0xfc, 0x32, 0x00, 0x0a, 0x85, 0x8d, 0x4a, 0x96, 0xcb, 0x18, 0x80, 0x73, 0x2c, 0x36, 0xc6, + 0x00, 0x28, 0x88, 0x7a, 0x8f, 0x4c, 0xb2, 0xc3, 0xcf, 0x2b, 0x6f, 0x7f, 0x2d, 0x61, 0xd0, 0x15, + 0x43, 0xb7, 0xbd, 0xcf, 0x01, 0x60, 0xff, 0x3c, 0x05, 0x83, 0xf0, 0xef, 0xbf, 0xc0, 0x35, 0x00, + 0x2e, 0x01, 0x48, 0xf2, 0xa0, 0x21, 0xd6, 0xc5, 0xc4, 0x6a, 0x6a, 0xaa, 0xb0, 0xf7, 0x1c, 0x00, + 0x0d, 0x7c, 0x24, 0xca, 0x0c, 0x4c, 0x10, 0x11, 0x02, 0xb1, 0x8e, 0x4e, 0xb3, 0xef, 0x90, 0xa9, + 0x24, 0x92, 0x5e, 0x08, 0x75, 0xbb, 0xdf, 0x57, 0x8c, 0xea, 0xd4, 0x13, 0x8a, 0x01, 0xbb, 0x1d, + 0x4d, 0xef, 0x7f, 0xbd, 0xf1, 0x64, 0x30, 0x24, 0x05, 0x2a, 0x8d, 0x8e, 0x24, 0x09, 0xa6, 0x60, + 0xa2, 0x2d, 0x8e, 0x21, 0x40, 0x8c, 0x56, 0x02, 0xad, 0xc7, 0x78, 0x10, 0x00, 0x92, 0x14, 0x38, + 0x90, 0x70, 0xf7, 0x04, 0xb9, 0x52, 0x34, 0x75, 0x48, 0x98, 0x28, 0xec, 0xd4, 0x9e, 0x3b, 0x2f, + 0xd7, 0xbe, 0x09, 0x24, 0xce, 0xe7, 0xcd, 0x49, 0x24, 0x92, 0x7c, 0xb5, 0x5c, 0x9c, 0x16, 0x09, + 0x77, 0xd5, 0x75, 0x5c, 0xa9, 0x5c, 0x10, 0xda, 0x69, 0x1a, 0x3d, 0x57, 0x27, 0x55, 0xf5, 0x67, + 0xc1, 0x0d, 0xd5, 0xd7, 0x5f, 0x58, 0xb1, 0xb8, 0x64, 0x03, 0xc6, 0x4c, 0x64, 0x7c, 0x41, 0x26, + 0xc3, 0x88, 0x20, 0x00, 0xff, 0xb2, 0x30, 0xcd, 0xb7, 0x9b, 0xca, 0xab, 0x74, 0xfc, 0x3d, 0xf1, + 0x55, 0xd3, 0x4d, 0x34, 0xf8, 0x5d, 0x84, 0x80, 0x1a, 0x9a, 0xc6, 0x70, 0x45, 0xf1, 0x75, 0xbd, + 0xc5, 0xe5, 0xf7, 0x64, 0xe6, 0x85, 0x61, 0x76, 0x50, 0x02, 0x97, 0x38, 0x15, 0x30, 0xe0, 0xff, + 0x65, 0x81, 0x21, 0x15, 0x8b, 0x8a, 0x34, 0x95, 0x81, 0xf2, 0xc1, 0xde, 0xb2, 0xe9, 0x78, 0xa0, + 0xcb, 0xc5, 0x07, 0x58, 0x5e, 0x40, 0x03, 0x3b, 0x13, 0x3c, 0x04, 0x46, 0xeb, 0xc7, 0xf3, 0xae, + 0xba, 0xd5, 0x6b, 0x63, 0x80, 0x24, 0x00, 0x09, 0x00, 0x50, 0xa2, 0x03, 0x82, 0x0e, 0x08, 0xf6, + 0xe1, 0x21, 0x53, 0x8e, 0x0f, 0x78, 0x3c, 0xf0, 0x29, 0x52, 0x40, 0x56, 0x31, 0xe0, 0xf8, 0xf0, + 0x3c, 0x3c, 0x01, 0xe5, 0x80, 0x01, 0x78, 0xe8, 0x0f, 0xb6, 0x17, 0x50, 0x02, 0x92, 0x04, 0xa7, + 0x5c, 0xea, 0x38, 0x3f, 0x27, 0xdf, 0xa8, 0x51, 0xd0, 0xab, 0x60, 0x90, 0x70, 0xe8, 0x56, 0xb8, + 0xbb, 0x61, 0x89, 0xc0, 0x13, 0x4e, 0x71, 0x23, 0xc1, 0x1e, 0xb5, 0xaf, 0xea, 0xbb, 0xba, 0x3b, + 0x85, 0xc8, 0x38, 0x00, 0xd5, 0x54, 0x1d, 0x46, 0xaf, 0xdf, 0xf7, 0x9f, 0xc4, 0x60, 0x98, 0xa6, + 0x21, 0xe5, 0xb0, 0xd9, 0x02, 0x60, 0x10, 0x69, 0x4a, 0x9e, 0x43, 0xa1, 0xef, 0xa1, 0xd4, 0xf7, + 0xe1, 0xf1, 0xc4, 0x7e, 0x5e, 0x9f, 0xc2, 0x12, 0x87, 0xde, 0x08, 0x7b, 0x01, 0xac, 0x95, 0x92, + 0xfc, 0xec, 0xa0, 0xe2, 0x7f, 0xca, 0x45, 0x55, 0x5f, 0x54, 0x76, 0xb9, 0xeb, 0xe9, 0xa6, 0x9a, + 0x7e, 0xaf, 0xf4, 0x57, 0x0f, 0xab, 0x4b, 0xd5, 0x1d, 0x98, 0x37, 0x0a, 0x00, 0x06, 0xb1, 0x01, + 0xda, 0x56, 0x32, 0x01, 0xc9, 0x1d, 0xaf, 0xbc, 0xfd, 0xb6, 0xdb, 0x6d, 0xb1, 0xd7, 0xc1, 0xd7, + 0xc7, 0x7e, 0x8d, 0xaf, 0xe7, 0xf0, 0xd1, 0x20, 0x08, 0x29, 0xe4, 0x22, 0x38, 0x44, 0xd3, 0xd3, + 0x4d, 0x34, 0xff, 0xf1, 0xcc, 0x3c, 0x48, 0x01, 0xb8, 0x77, 0x58, 0x66, 0x02, 0xf4, 0xa7, 0xa6, + 0x4e, 0x9c, 0x7e, 0x4f, 0x24, 0xf3, 0xc3, 0xdf, 0xe9, 0xf1, 0xcc, 0xe0, 0x07, 0x77, 0xc8, 0x80, + 0x39, 0x28, 0xa7, 0x1c, 0xce, 0x00, 0xf3, 0xe4, 0xd5, 0x30, 0xf4, 0x53, 0xf5, 0x72, 0x23, 0x82, + 0x33, 0xea, 0xaf, 0x7c, 0x11, 0xf5, 0x52, 0xa5, 0xf3, 0x8f, 0x4b, 0xf9, 0x1f, 0x23, 0xe1, 0x12, + 0x68, 0x38, 0x0c, 0xfb, 0x9e, 0x16, 0xf6, 0x21, 0x04, 0x38, 0x00, 0x82, 0xfd, 0x5f, 0x08, 0x75, + 0x6f, 0x7f, 0x8f, 0x66, 0x01, 0x75, 0xb4, 0x1c, 0x7c, 0xbd, 0xff, 0x18, 0x82, 0xb4, 0x70, 0x01, + 0xc3, 0x10, 0x80, 0x0f, 0x64, 0x69, 0x9e, 0xba, 0xfd, 0x6b, 0x01, 0x60, 0x36, 0x1e, 0x61, 0x20, + 0x02, 0xa3, 0xd8, 0x09, 0x4e, 0x80, 0x50, 0x7e, 0x12, 0x7b, 0x62, 0x7e, 0xb7, 0xb2, 0xcc, 0xb6, + 0xb5, 0x52, 0x40, 0xf7, 0xc9, 0x6c, 0x76, 0x6d, 0xfd, 0xd6, 0x17, 0xc0, 0x35, 0x5a, 0x29, 0x0c, + 0x4b, 0x5f, 0xa5, 0xab, 0x28, 0xe3, 0xc1, 0xf0, 0x84, 0x7b, 0x09, 0x83, 0x28, 0xbb, 0x84, 0x81, + 0x2b, 0x70, 0xf1, 0x83, 0x20, 0x78, 0x30, 0x38, 0xc1, 0xb0, 0xdb, 0x80, 0x4c, 0x77, 0x05, 0x6b, + 0x71, 0xdf, 0xd2, 0x43, 0xfa, 0x4b, 0x4a, 0xb5, 0x9e, 0xfd, 0x78, 0x5d, 0xc0, 0x1b, 0x58, 0x89, + 0x00, 0x53, 0x8d, 0x1a, 0xae, 0x58, 0x2a, 0x1a, 0xaa, 0xb6, 0x1c, 0x2d, 0xd8, 0x5f, 0x02, 0x08, + 0xcf, 0x0a, 0xee, 0xec, 0x6f, 0x3d, 0x85, 0x9e, 0xc3, 0x5c, 0x48, 0xc2, 0x24, 0x58, 0xeb, 0x4f, + 0xc0, 0x35, 0x00, 0x12, 0x00, 0xa0, 0xb1, 0x58, 0xa0, 0xcb, 0xcb, 0x18, 0x90, 0x54, 0x1e, 0x79, + 0xe2, 0xa0, 0xb3, 0x2f, 0x2c, 0x19, 0x79, 0x60, 0xce, 0x58, 0x2f, 0x57, 0x43, 0xfe, 0x46, 0x1c, + 0x27, 0x18, 0x00, 0x2f, 0x86, 0xac, 0xc3, 0x35, 0x6e, 0x1c, 0x44, 0xf5, 0x7b, 0xc4, 0x79, 0x76, + 0x23, 0xd9, 0x1e, 0xa2, 0x3c, 0x3d, 0x16, 0x0b, 0xc3, 0xe1, 0x63, 0x00, 0xa8, 0x01, 0x44, 0x15, + 0x9c, 0xa2, 0x35, 0xca, 0x08, 0x1a, 0xbf, 0x8e, 0x08, 0xfe, 0xc6, 0x8b, 0x3e, 0x76, 0x65, 0x26, + 0xe9, 0x30, 0xc9, 0x02, 0x20, 0x82, 0x47, 0x3c, 0xc9, 0xa7, 0xff, 0xf8, 0x8d, 0x8c, 0x6b, 0x1f, + 0x1c, 0x00, 0x6c, 0x61, 0x06, 0x00, 0xeb, 0x6f, 0x84, 0x52, 0x78, 0x64, 0x29, 0x55, 0xc2, 0xdf, + 0x13, 0x7d, 0xf8, 0xbf, 0x17, 0x54, 0xe8, 0xfd, 0x53, 0xaf, 0x54, 0xc8, 0x54, 0x08, 0x20, 0x2a, + 0x46, 0x86, 0x84, 0x80, 0x00, 0x81, 0xbe, 0x07, 0x70, 0x00, 0x10, 0x33, 0x50, 0xe0, 0xd0, 0x00, + 0x10, 0x09, 0x50, 0xe0, 0xd0, 0x00, 0x75, 0x0e, 0xe0, 0x00, 0x20, 0x46, 0xa1, 0xdc, 0x00, 0x04, + 0x05, 0xd4, 0x38, 0xe0, 0x00, 0x20, 0x1e, 0xa1, 0xdc, 0x00, 0x04, 0x01, 0xd4, 0x3a, 0x06, 0x2f, + 0x83, 0xa0, 0x67, 0xf3, 0x72, 0x22, 0xa0, 0x0b, 0xf8, 0xa8, 0x0b, 0xfa, 0x64, 0x70, 0x48, 0x0e, + 0x03, 0x8a, 0xb1, 0x57, 0xf0, 0xe2, 0x28, 0x07, 0x45, 0x80, 0xab, 0x8a, 0x31, 0x12, 0xc2, 0x6e, + 0xab, 0x7b, 0x72, 0xf2, 0xf8, 0xdb, 0xe3, 0x4d, 0x31, 0x6c, 0x52, 0xcb, 0x2c, 0x5b, 0x4f, 0x22, + 0x49, 0x6d, 0xb7, 0xa6, 0x9c, 0x3c, 0x8a, 0x00, 0x5a, 0x02, 0xad, 0x5d, 0x46, 0x62, 0x76, 0xf4, + 0xd3, 0x27, 0x8c, 0xdd, 0x47, 0x0c, 0xe5, 0x96, 0xce, 0xce, 0x3e, 0xe3, 0xee, 0x07, 0xd8, 0xca, + 0xd3, 0x16, 0xe9, 0xf0, 0xe4, 0xe0, 0x09, 0xc3, 0x6b, 0x99, 0xc6, 0xaf, 0x95, 0x3d, 0x3a, 0x69, + 0xa6, 0x9f, 0x4d, 0x3b, 0x60, 0x62, 0xe0, 0x50, 0xed, 0xb7, 0x4e, 0x9c, 0x9d, 0x6a, 0xfa, 0xb4, + 0x47, 0x0e, 0x13, 0x51, 0x4d, 0x55, 0xa8, 0xd2, 0xfe, 0x03, 0x44, 0x02, 0x42, 0x1b, 0x3e, 0x15, + 0x56, 0x20, 0x38, 0x28, 0x62, 0xa5, 0x8e, 0x0c, 0xed, 0xfc, 0x23, 0x12, 0x1b, 0xf0, 0x02, 0x27, + 0x4d, 0xb6, 0xdb, 0x7f, 0x09, 0x10, 0x81, 0x9a, 0xe1, 0xc4, 0x1e, 0x7a, 0x69, 0xd6, 0xb8, 0xf6, + 0x13, 0x01, 0xc9, 0x00, 0x20, 0xc9, 0x82, 0x00, 0x6c, 0x70, 0x01, 0x88, 0x30, 0x88, 0x30, 0xfc, + 0xe8, 0x60, 0x0f, 0x49, 0x74, 0x34, 0x8c, 0x02, 0xad, 0xab, 0x7d, 0xff, 0xf7, 0xbc, 0x10, 0xc6, + 0xd4, 0x34, 0x40, 0x80, 0x01, 0xc5, 0x32, 0xb0, 0xd9, 0x4f, 0xcd, 0x9b, 0xd6, 0xb1, 0x5c, 0x57, + 0xf7, 0x6d, 0xf8, 0x26, 0x43, 0x48, 0xa0, 0x14, 0xc3, 0x98, 0x46, 0x69, 0x76, 0x6c, 0xfe, 0x25, + 0x0d, 0x09, 0x5c, 0x16, 0x1b, 0x60, 0x4e, 0x38, 0x84, 0x58, 0xc9, 0x01, 0x3e, 0xd8, 0xbb, 0x9d, + 0x84, 0x29, 0x84, 0xac, 0x61, 0xb6, 0x60, 0x42, 0x50, 0xeb, 0x0e, 0xc2, 0xda, 0xc9, 0xea, 0xea, + 0xeb, 0x5a, 0xe9, 0x3f, 0x5e, 0x13, 0x65, 0x06, 0x0c, 0xa0, 0x03, 0xa9, 0xfb, 0xdf, 0x7b, 0x1b, + 0xce, 0xc4, 0x2e, 0x48, 0x04, 0xa1, 0xa4, 0xc0, 0x72, 0x8c, 0xc3, 0x58, 0x96, 0xb1, 0x1f, 0x4d, + 0x4b, 0x1b, 0xa0, 0x58, 0xf5, 0xb6, 0x1b, 0x89, 0x00, 0x88, 0xf2, 0x0a, 0xa0, 0xbe, 0xd9, 0x1a, + 0x2f, 0x3c, 0x14, 0xe3, 0xe9, 0x16, 0xfd, 0x70, 0xbb, 0x30, 0x01, 0x3e, 0xa2, 0x66, 0x21, 0x8f, + 0x6e, 0xbd, 0xe4, 0x69, 0x37, 0x04, 0x61, 0x11, 0x59, 0xd6, 0x46, 0x09, 0xb8, 0x11, 0x60, 0xf3, + 0x0d, 0x9c, 0x32, 0x05, 0x90, 0xa1, 0x8b, 0x01, 0x00, 0xfc, 0xf0, 0x1e, 0x15, 0x4c, 0x00, 0x04, + 0x00, 0x52, 0x7c, 0x07, 0xdc, 0xb7, 0x21, 0xc6, 0xa4, 0xc2, 0xd5, 0xdc, 0x2c, 0xe0, 0x09, 0x2a, + 0x9c, 0x38, 0xc0, 0x12, 0x87, 0x62, 0x52, 0x30, 0x41, 0x21, 0xb6, 0x17, 0x04, 0x29, 0x92, 0x7e, + 0x7f, 0xdf, 0x7f, 0x1c, 0x06, 0x38, 0xef, 0x7f, 0xc0, 0x2a, 0x00, 0x79, 0x1a, 0x3e, 0x27, 0xc6, + 0xbc, 0x7f, 0x8a, 0x62, 0x99, 0x66, 0x29, 0x9e, 0x60, 0x59, 0x89, 0x08, 0x00, 0x04, 0xbc, 0x53, + 0x14, 0xc2, 0xdf, 0x16, 0x60, 0x3a, 0x00, 0xbf, 0x82, 0xa7, 0x1f, 0x08, 0x2d, 0x2a, 0xfc, 0xda, + 0x6d, 0x88, 0x5c, 0x54, 0x60, 0x24, 0x5a, 0xbf, 0x9c, 0xeb, 0x37, 0x46, 0x6f, 0xa2, 0x45, 0x13, + 0x07, 0x00, 0x2a, 0x11, 0x2b, 0xe0, 0x84, 0xb7, 0xbf, 0x71, 0x02, 0x04, 0xdd, 0xfc, 0x6b, 0xca, + 0xbc, 0x3b, 0x98, 0xd7, 0xb5, 0x0e, 0x28, 0x4b, 0x76, 0x14, 0xf4, 0xd3, 0xfd, 0xbe, 0x95, 0x73, + 0x6f, 0xc3, 0x8a, 0x02, 0x3d, 0xb5, 0x37, 0x7f, 0xfd, 0x2e, 0x37, 0xa4, 0x97, 0xc3, 0x8a, 0x03, + 0x37, 0xe4, 0x62, 0x3b, 0x7d, 0x34, 0xd3, 0xb4, 0xd6, 0xd3, 0x58, 0x19, 0x43, 0x38, 0x9b, 0x8e, + 0xdf, 0x6e, 0x9f, 0x0f, 0x28, 0x03, 0x9a, 0xf9, 0x19, 0x7f, 0x4f, 0xfc, 0x60, 0xe9, 0xee, 0x96, + 0xbc, 0xc9, 0x13, 0x4e, 0xdc, 0x3c, 0x48, 0x04, 0x57, 0xb8, 0x01, 0x2b, 0x66, 0xfb, 0x6d, 0xf6, + 0xe3, 0xdf, 0x6e, 0xce, 0x98, 0xb6, 0x31, 0x6d, 0x88, 0x76, 0x38, 0xd3, 0xb6, 0xdc, 0x38, 0xa0, + 0x0f, 0x64, 0xf0, 0xae, 0x3f, 0xdb, 0x6e, 0xdb, 0x76, 0xdb, 0x1d, 0xba, 0x69, 0xa6, 0xd3, 0x54, + 0xe1, 0xcc, 0x03, 0x5a, 0xc9, 0x5e, 0xaf, 0xdb, 0xb7, 0x6b, 0x27, 0xc6, 0x08, 0x9a, 0x5d, 0x2e, + 0xbf, 0x57, 0x2f, 0xc3, 0xce, 0x00, 0x3b, 0xfb, 0x22, 0x6b, 0x68, 0x6d, 0xb3, 0x7d, 0xb3, 0xff, + 0xae, 0xed, 0xb8, 0x69, 0x93, 0x1a, 0x06, 0xdd, 0xdd, 0x5d, 0xb7, 0xc3, 0x6c, 0x80, 0x02, 0x54, + 0xbf, 0x01, 0xa1, 0x28, 0x76, 0x3c, 0xfe, 0x15, 0xc5, 0x7e, 0x58, 0x0a, 0xe2, 0xb7, 0x7b, 0x71, + 0x2f, 0x6a, 0x7d, 0xbf, 0x0e, 0xa3, 0x80, 0x0a, 0xbe, 0xe0, 0x08, 0xab, 0xe8, 0xc2, 0x1f, 0xc1, + 0xfe, 0xbf, 0x07, 0xfb, 0xd8, 0x97, 0xb1, 0x38, 0xba, 0x8b, 0x9e, 0xc1, 0xd1, 0x74, 0x43, 0xb7, + 0x8e, 0xfb, 0xab, 0xac, 0x2e, 0x41, 0x40, 0x0a, 0xdd, 0x04, 0x83, 0x97, 0x66, 0x8b, 0xfa, 0xca, + 0xef, 0x66, 0x1b, 0x67, 0x00, 0xc1, 0x1c, 0xe7, 0xf9, 0xeb, 0x49, 0x59, 0x5e, 0xe6, 0x83, 0xe0, + 0xe8, 0x3e, 0x03, 0xfd, 0xef, 0xf8, 0x6d, 0xc0, 0x94, 0x0b, 0x49, 0xec, 0x7d, 0x24, 0x78, 0xbb, + 0x1f, 0x6f, 0xcb, 0xd8, 0xf2, 0xf6, 0x3e, 0xf7, 0x7f, 0xeb, 0x86, 0xd9, 0xc0, 0x7b, 0x5a, 0xcf, + 0x64, 0x89, 0x92, 0x2f, 0x64, 0x89, 0x92, 0x25, 0x5a, 0xfe, 0x17, 0x21, 0x00, 0x06, 0x7f, 0x08, + 0xb6, 0x33, 0x07, 0x53, 0xdd, 0x91, 0x3c, 0x73, 0xb2, 0x76, 0x44, 0x60, 0xac, 0x4c, 0x1a, 0x3b, + 0xc1, 0x40, 0x64, 0x28, 0x28, 0x38, 0xc0, 0x6a, 0x43, 0x81, 0xab, 0xf1, 0xe4, 0x52, 0x80, 0xfc, + 0x78, 0xc3, 0xb8, 0x94, 0x68, 0xc1, 0x48, 0xed, 0x92, 0xf1, 0x71, 0xc4, 0x0b, 0xa3, 0x00, 0x03, + 0xdc, 0x78, 0x79, 0x41, 0x00, 0x02, 0x59, 0x1b, 0xe0, 0xa0, 0x0d, 0x20, 0xac, 0x58, 0x80, 0x73, + 0x25, 0x00, 0x54, 0xb6, 0x78, 0x00, 0x30, 0x74, 0x7c, 0xdc, 0x06, 0x01, 0x37, 0x3b, 0xec, 0x3d, + 0x6f, 0xba, 0x25, 0x61, 0xa6, 0x11, 0x01, 0xd9, 0xa9, 0xb2, 0xdf, 0xff, 0xdb, 0x8e, 0x7e, 0x77, + 0xe0, 0x18, 0x00, 0x13, 0x20, 0x86, 0x2e, 0x2e, 0x2e, 0x2e, 0x8e, 0x38, 0xc8, 0xda, 0x38, 0x01, + 0xce, 0xbc, 0x04, 0x00, 0x08, 0x1f, 0xa1, 0x88, 0xe3, 0x1d, 0x11, 0x46, 0xab, 0xe8, 0x8c, 0x5f, + 0x36, 0xd3, 0x57, 0xd5, 0x92, 0xf5, 0x7a, 0x80, 0x81, 0x0c, 0x02, 0x7b, 0xbb, 0xbb, 0xbd, 0xc7, + 0xc6, 0x0f, 0x01, 0x52, 0x10, 0x04, 0x9b, 0x55, 0x1c, 0x31, 0xc1, 0xe0, 0xc6, 0x08, 0x31, 0x75, + 0xcf, 0x82, 0x78, 0x7f, 0x38, 0xe6, 0x09, 0x1a, 0x03, 0x22, 0x40, 0xa1, 0x56, 0xe2, 0xbf, 0xc0, + 0x54, 0x81, 0x24, 0x15, 0xd5, 0xf6, 0xa5, 0xe2, 0x4e, 0x62, 0x4e, 0x09, 0x39, 0x1f, 0x0e, 0x28, + 0x11, 0x38, 0x5d, 0x37, 0x9b, 0x6f, 0x6d, 0xb4, 0xd3, 0xd3, 0xec, 0x26, 0x10, 0xa6, 0x54, 0x4f, + 0xc7, 0x39, 0x34, 0xe7, 0xf0, 0xf2, 0x80, 0xd3, 0x98, 0xcc, 0x4e, 0x3e, 0x34, 0xd3, 0x2f, 0x6d, + 0xbf, 0xb8, 0x63, 0x51, 0x2d, 0x27, 0x2c, 0x59, 0xbe, 0x9b, 0xc3, 0x8a, 0x00, 0x30, 0x1b, 0x34, + 0x51, 0x06, 0x8a, 0x4b, 0xb7, 0x4c, 0x55, 0x8a, 0xbf, 0xb8, 0x3b, 0xf5, 0xfc, 0x13, 0xa6, 0x09, + 0x89, 0xa7, 0x58, 0x93, 0x0d, 0x30, 0xab, 0xd0, 0xe1, 0x20, 0x19, 0x88, 0x10, 0xf5, 0x1b, 0x6f, + 0x6d, 0xbf, 0xad, 0xbf, 0x02, 0x88, 0x42, 0x0f, 0xae, 0x64, 0x47, 0xfe, 0x1c, 0x24, 0x00, 0xb7, + 0xb4, 0x66, 0x44, 0x1f, 0x63, 0x6d, 0xf1, 0x5a, 0x62, 0x1f, 0xeb, 0x78, 0x45, 0x9c, 0x30, 0x02, + 0xa4, 0x1d, 0x7e, 0xcf, 0x7d, 0x6b, 0x0e, 0xe0, 0x03, 0x48, 0xa8, 0x50, 0x44, 0x23, 0x0f, 0x5e, + 0x93, 0x17, 0x8d, 0x7d, 0xef, 0x55, 0x55, 0x33, 0x0a, 0xa7, 0xee, 0xfc, 0x36, 0xcc, 0x00, 0xfb, + 0x71, 0x04, 0x1a, 0xf7, 0x55, 0x86, 0xc1, 0x90, 0x6c, 0x15, 0xee, 0x5e, 0xd8, 0x0b, 0xb6, 0x17, + 0x7e, 0xf7, 0x85, 0xd8, 0x80, 0x52, 0xa0, 0x3a, 0xc8, 0x58, 0x5b, 0xdf, 0xd0, 0xef, 0x76, 0xc2, + 0x6c, 0xe0, 0x22, 0x06, 0xc6, 0x8f, 0x9b, 0xe8, 0x74, 0x3b, 0xde, 0x87, 0x43, 0x87, 0x59, 0x40, + 0x06, 0xf9, 0x36, 0x06, 0x5c, 0x81, 0x5d, 0x72, 0x95, 0x87, 0xca, 0x58, 0xd9, 0xe6, 0x35, 0xbd, + 0xfd, 0x7d, 0xef, 0x86, 0x48, 0x70, 0x0e, 0x49, 0x8b, 0xf8, 0xad, 0x5d, 0xdd, 0xdd, 0x5d, 0x7c, + 0x77, 0xf0, 0x24, 0x80, 0x48, 0x02, 0x95, 0x8a, 0x6a, 0x6e, 0x78, 0x07, 0xd6, 0x78, 0x78, 0xb9, + 0x38, 0xa6, 0x59, 0x97, 0x92, 0xd0, 0x21, 0x8e, 0xae, 0x74, 0xe0, 0xe0, 0x10, 0x85, 0x05, 0x1e, + 0xe2, 0x70, 0x1d, 0x93, 0xb2, 0x08, 0x85, 0x63, 0x9e, 0x94, 0xf0, 0x1a, 0xb4, 0xad, 0x21, 0x8c, + 0x2f, 0x50, 0x0c, 0x2f, 0x52, 0xcc, 0x53, 0xcb, 0x35, 0x17, 0x1b, 0x8e, 0xf0, 0x04, 0x80, 0x01, + 0x30, 0x05, 0x66, 0x3c, 0x06, 0x78, 0xcf, 0x7d, 0x47, 0x83, 0xcf, 0x0f, 0x3c, 0x07, 0x8e, 0x25, + 0xc1, 0x64, 0x95, 0x87, 0x6d, 0x3c, 0x00, 0x0a, 0x60, 0x75, 0x00, 0x94, 0x44, 0x48, 0x49, 0xaf, + 0x0a, 0x1d, 0x56, 0xaa, 0xaa, 0xa5, 0xe5, 0xb3, 0xea, 0x0b, 0xb1, 0x00, 0xe1, 0xce, 0x16, 0x0c, + 0xb0, 0x63, 0x4a, 0x18, 0xe1, 0xc5, 0x06, 0xa4, 0x89, 0xfe, 0x9a, 0x65, 0x31, 0xd3, 0x4c, 0xbf, + 0x3a, 0xfd, 0xad, 0x24, 0xa1, 0xc5, 0x00, 0xce, 0x6c, 0x48, 0x7f, 0xed, 0xed, 0xb6, 0x9a, 0x62, + 0x4d, 0x5c, 0xba, 0x5d, 0xfc, 0x02, 0x60, 0x02, 0x44, 0x30, 0x55, 0x85, 0xba, 0x92, 0x0b, 0x2c, + 0xe1, 0xc1, 0x00, 0xe0, 0x82, 0x91, 0x43, 0x14, 0x58, 0xa2, 0xf1, 0x6f, 0x80, 0x88, 0x87, 0xce, + 0xab, 0xe0, 0xf7, 0x80, 0xf7, 0x99, 0x70, 0xb8, 0x36, 0x87, 0x4e, 0x2a, 0xc5, 0x5f, 0xf8, 0x23, + 0x28, 0xac, 0x56, 0x5b, 0x15, 0xb9, 0x9d, 0x7c, 0x10, 0xc4, 0xf4, 0x23, 0xa2, 0xfa, 0xbf, 0xd5, + 0xe4, 0xe8, 0xee, 0x7d, 0x5c, 0xa1, 0xc8, 0xa1, 0xa7, 0x8c, 0x98, 0x49, 0x43, 0x43, 0xc5, 0x43, + 0x8f, 0x49, 0x2f, 0x85, 0x51, 0x80, 0x15, 0xb8, 0x1c, 0x89, 0x3f, 0x5f, 0xfa, 0x69, 0xfc, 0x38, + 0xa0, 0x0e, 0x3f, 0x92, 0x99, 0xff, 0x8b, 0x69, 0xff, 0x93, 0x03, 0x6d, 0xff, 0x0f, 0x28, 0x04, + 0x63, 0x74, 0x7f, 0xd9, 0xbf, 0x55, 0xfe, 0xdd, 0x32, 0xe9, 0xf6, 0xe1, 0xe4, 0x40, 0x10, 0x09, + 0xc2, 0xa1, 0xaf, 0x6d, 0xbf, 0xd3, 0x4f, 0x8a, 0x9c, 0x7e, 0x9a, 0x70, 0xf2, 0x80, 0x10, 0xad, + 0xf5, 0xb2, 0x37, 0x76, 0xff, 0xfd, 0xb3, 0xfc, 0x94, 0x5b, 0xaf, 0xed, 0xc3, 0x6e, 0x00, 0xd3, + 0x1f, 0x16, 0xf3, 0x2f, 0x7d, 0xad, 0xdd, 0xfe, 0xbc, 0xd4, 0x46, 0x07, 0x0c, 0x1c, 0x74, 0xaa, + 0xad, 0x49, 0xc9, 0x31, 0xb9, 0x6c, 0xdf, 0x01, 0x02, 0x07, 0x10, 0xe9, 0x0d, 0xcf, 0x3d, 0xb3, + 0xfc, 0x53, 0x17, 0x2f, 0x9f, 0xca, 0xfc, 0xe2, 0x03, 0x01, 0x11, 0xc1, 0x89, 0x9c, 0xef, 0x1e, + 0xb8, 0xf5, 0xe5, 0xcf, 0xdf, 0xf8, 0x79, 0x94, 0x03, 0x56, 0xd5, 0x4d, 0xfe, 0xf7, 0xfd, 0xf7, + 0xbe, 0xf7, 0xc0, 0xa2, 0x02, 0x40, 0x29, 0x09, 0xb8, 0x38, 0x53, 0x59, 0x24, 0x01, 0xb0, 0xae, + 0x5a, 0x90, 0x02, 0x2b, 0x5e, 0x21, 0x1d, 0xcf, 0x01, 0x10, 0x13, 0xd5, 0x23, 0xe0, 0xc1, 0x35, + 0x51, 0x6e, 0x25, 0xb2, 0xd6, 0xb5, 0xd4, 0x7f, 0x8e, 0x31, 0x15, 0xc4, 0xc2, 0x86, 0xba, 0xb9, + 0x28, 0x38, 0x20, 0x9f, 0x07, 0x04, 0x37, 0x27, 0xb2, 0xf7, 0x2e, 0x15, 0x00, 0x44, 0x40, 0x73, + 0xc7, 0x01, 0x4e, 0x30, 0x63, 0x40, 0xe1, 0x32, 0x18, 0x08, 0x69, 0x83, 0x7a, 0x89, 0x0e, 0x7f, + 0x2c, 0x6c, 0x83, 0xd8, 0xbf, 0x0b, 0x90, 0x48, 0x05, 0xa3, 0x7a, 0x24, 0xb1, 0xef, 0x72, 0x42, + 0x48, 0x3b, 0xbb, 0xb9, 0xd8, 0x39, 0xd8, 0x39, 0x8e, 0x62, 0x40, 0x1a, 0x2a, 0x24, 0x08, 0x22, + 0x31, 0xc2, 0xe4, 0x80, 0x54, 0x78, 0xc1, 0x22, 0x7b, 0xfe, 0xff, 0xbe, 0x21, 0xc1, 0x2f, 0x34, + 0xff, 0x61, 0x74, 0x60, 0x12, 0x1f, 0x26, 0x5f, 0x6b, 0xd1, 0xcd, 0x16, 0x5e, 0xc9, 0x97, 0xee, + 0x0e, 0x40, 0xb2, 0x14, 0x10, 0x28, 0x00, 0x31, 0xd3, 0xe2, 0x80, 0x0c, 0xf0, 0x7a, 0x13, 0xf1, + 0x0a, 0x6a, 0x3a, 0xb9, 0x30, 0x54, 0x48, 0x00, 0xf2, 0xc1, 0x85, 0x40, 0x06, 0x85, 0x8c, 0x76, + 0xe5, 0x80, 0x19, 0xfe, 0x78, 0x00, 0x10, 0xe0, 0xc8, 0x05, 0x18, 0x00, 0x38, 0x79, 0x9c, 0x02, + 0xe8, 0x3b, 0xd9, 0x01, 0xee, 0x3a, 0x46, 0x9d, 0x6d, 0xed, 0xb6, 0xdb, 0x75, 0xb6, 0xd8, 0xab, + 0x6c, 0x55, 0x83, 0x20, 0x10, 0x54, 0x7d, 0x1f, 0x57, 0xbf, 0x87, 0x14, 0x02, 0x46, 0x42, 0xed, + 0x1e, 0xff, 0xf4, 0xd3, 0xc4, 0x74, 0x31, 0x4d, 0xd6, 0xef, 0xf8, 0x78, 0x90, 0x03, 0x53, 0xfc, + 0x83, 0xe0, 0xf3, 0xef, 0xfb, 0x6d, 0xed, 0xb6, 0x36, 0xdd, 0x34, 0xdb, 0xf8, 0x78, 0x90, 0x26, + 0xa6, 0x39, 0x40, 0xbf, 0xff, 0xb7, 0x87, 0xdc, 0x6a, 0x93, 0x4d, 0xbf, 0xc3, 0x88, 0xa0, 0x4f, + 0x74, 0xf1, 0xb6, 0xda, 0x71, 0xb6, 0xdf, 0xe9, 0xa6, 0x55, 0x74, 0xd3, 0xf8, 0x79, 0x10, 0x01, + 0x85, 0x65, 0x66, 0x6f, 0xff, 0x58, 0x2d, 0xa6, 0xdb, 0x69, 0xa7, 0xe9, 0xa7, 0x4c, 0x9c, 0x7d, + 0xf2, 0x54, 0xd8, 0xab, 0x49, 0x24, 0xd3, 0xe1, 0xe5, 0x01, 0x81, 0xad, 0x67, 0x64, 0xd3, 0xfd, + 0x53, 0x9a, 0x69, 0xe3, 0x80, 0x91, 0xe5, 0xb6, 0xcf, 0xaf, 0xdf, 0xc0, 0xa0, 0x24, 0x6f, 0x3e, + 0x0a, 0xe0, 0xe8, 0xb8, 0xa3, 0x39, 0xd2, 0x6d, 0x0e, 0x78, 0xd1, 0x40, 0x4a, 0x15, 0xe8, 0x0b, + 0x76, 0x58, 0x31, 0x03, 0x80, 0xc8, 0x40, 0xc6, 0xd8, 0x54, 0x71, 0x12, 0xbd, 0x13, 0x5a, 0xf9, + 0x4d, 0x9b, 0x21, 0xb1, 0xe8, 0x48, 0x7b, 0xc2, 0xb7, 0x76, 0x81, 0xae, 0xbf, 0x08, 0x2c, 0x0c, + 0xf4, 0x5b, 0xd6, 0x2a, 0xf6, 0xdb, 0x84, 0x11, 0x40, 0xc1, 0xfe, 0x1c, 0x31, 0xde, 0x0d, 0xb9, + 0x65, 0x6e, 0x5f, 0xe0, 0x08, 0x04, 0x10, 0x82, 0x8a, 0xaf, 0xbb, 0x8e, 0x03, 0xb0, 0xda, 0x80, + 0x4a, 0x94, 0x84, 0x28, 0xf8, 0xb5, 0xfa, 0xd7, 0xe3, 0x8f, 0x8b, 0x62, 0xd9, 0x8d, 0x38, 0xd7, + 0xc3, 0x4a, 0x03, 0x1c, 0x67, 0xd4, 0x26, 0x9b, 0x6d, 0xff, 0xfb, 0x61, 0xe2, 0x10, 0x00, 0x80, + 0xf8, 0xa7, 0xce, 0x62, 0xb2, 0xff, 0xfb, 0xb8, 0xac, 0x65, 0x8a, 0xd6, 0xa3, 0x98, 0xed, 0xc3, + 0xc4, 0x80, 0x11, 0x1c, 0x88, 0x72, 0xd0, 0x87, 0xfc, 0xfd, 0xff, 0xf1, 0x75, 0x17, 0x11, 0x04, + 0x84, 0x4e, 0xf5, 0xbf, 0xd7, 0xdf, 0x04, 0x00, 0x41, 0x0f, 0x4b, 0x0e, 0x2f, 0x7d, 0x18, 0xbd, + 0x62, 0x95, 0x85, 0x18, 0xf9, 0xff, 0x4f, 0x02, 0xc8, 0x09, 0x10, 0xa5, 0xd4, 0xfc, 0xbd, 0x2a, + 0xb9, 0x76, 0x44, 0x39, 0xd3, 0x2e, 0x1c, 0x38, 0x09, 0x51, 0xb8, 0x40, 0x32, 0x14, 0x25, 0xa9, + 0x6b, 0x65, 0x2e, 0xce, 0x65, 0x50, 0xb9, 0x29, 0xf1, 0x79, 0x61, 0x93, 0x15, 0xb6, 0x72, 0xdf, + 0xbc, 0x30, 0x14, 0xaa, 0x4a, 0x2b, 0xa3, 0x28, 0x0c, 0xa0, 0xe5, 0x09, 0x01, 0xad, 0x31, 0x46, + 0x28, 0xc5, 0x01, 0xb9, 0x80, 0xf8, 0x3a, 0x8e, 0x70, 0x3e, 0x00, 0xea, 0x11, 0xd0, 0xca, 0x85, + 0xd9, 0x00, 0x10, 0x0a, 0x44, 0x0c, 0xe4, 0xa4, 0x0a, 0x5f, 0xb7, 0x6f, 0xde, 0xed, 0xe2, 0x1e, + 0xde, 0x73, 0xf5, 0xce, 0xc2, 0xe4, 0x12, 0x01, 0x0d, 0xa1, 0x8a, 0x8a, 0xe6, 0xff, 0xfa, 0xd5, + 0xf1, 0xcc, 0xa0, 0x4b, 0x3c, 0x00, 0x04, 0x00, 0xa6, 0xcf, 0x8c, 0xc2, 0x08, 0x52, 0xc9, 0xf1, + 0xcf, 0x1d, 0xb0, 0x9a, 0x80, 0x7c, 0x34, 0xa7, 0x9f, 0x5a, 0xfd, 0x6b, 0x09, 0xa1, 0x00, 0x0f, + 0xf2, 0xe0, 0x25, 0xf0, 0x83, 0x09, 0x13, 0xe1, 0xbe, 0x14, 0x4b, 0xae, 0xdc, 0xcd, 0x27, 0x64, + 0xf0, 0xbe, 0xe5, 0x75, 0xc8, 0x7b, 0x00, 0x92, 0xb6, 0xb2, 0x33, 0x2d, 0xff, 0x6f, 0x4f, 0x2f, + 0xf1, 0xa5, 0x8e, 0xcb, 0xe3, 0x4f, 0xf0, 0xda, 0x80, 0x08, 0x21, 0xc5, 0xf9, 0x46, 0x64, 0x1e, + 0xdf, 0xf4, 0x9a, 0x69, 0xa7, 0xe9, 0xbb, 0x83, 0xaf, 0xb9, 0xf8, 0xe3, 0xf1, 0xdf, 0x84, 0x20, + 0x90, 0xe0, 0x67, 0x2c, 0x17, 0x0c, 0x18, 0x55, 0x00, 0xa6, 0x1b, 0x62, 0xae, 0x1e, 0x44, 0x00, + 0x30, 0x80, 0xcb, 0x70, 0x84, 0xde, 0xe7, 0xff, 0x4d, 0x3d, 0xb1, 0x56, 0xff, 0x62, 0xac, 0x51, + 0x74, 0xc2, 0x41, 0x63, 0xb9, 0x4c, 0xa5, 0x0c, 0xbf, 0x0e, 0x28, 0x24, 0x5d, 0x3c, 0x7f, 0xff, + 0x4c, 0x0a, 0xbb, 0xe3, 0x0b, 0xf0, 0xe2, 0x80, 0x54, 0x0a, 0x50, 0xfc, 0x37, 0xd4, 0xdb, 0x6f, + 0x15, 0x62, 0xac, 0xda, 0x7f, 0x79, 0xe7, 0x4f, 0x3a, 0x9c, 0x60, 0x70, 0x28, 0x1c, 0x69, 0x43, + 0x8a, 0x51, 0x29, 0x65, 0x06, 0x53, 0x80, 0x77, 0xe1, 0xc5, 0x01, 0x53, 0x99, 0x4f, 0x5e, 0xdb, + 0x7b, 0x62, 0xae, 0x34, 0xf1, 0x6c, 0x5b, 0xc1, 0x00, 0x0e, 0xb3, 0x96, 0x5d, 0x62, 0x8b, 0x6d, + 0xb4, 0xd3, 0x87, 0x14, 0x00, 0xf1, 0xbc, 0xcc, 0x00, 0x2f, 0x6b, 0xc6, 0xdb, 0x4d, 0x36, 0xc5, + 0x16, 0x2d, 0x8a, 0x5f, 0x93, 0x62, 0xc0, 0xca, 0x0f, 0x25, 0x77, 0x0e, 0x6e, 0x3b, 0x72, 0x51, + 0xff, 0xc3, 0x8a, 0x03, 0x38, 0x81, 0x7e, 0xc0, 0x48, 0x11, 0xde, 0x75, 0x78, 0xb6, 0x2d, 0xcb, + 0xc5, 0xb2, 0xcb, 0x4d, 0x3d, 0x34, 0xf0, 0x30, 0x00, 0xe1, 0xc6, 0x14, 0x53, 0x2a, 0x85, 0xae, + 0xbf, 0x87, 0x14, 0x03, 0x29, 0xe2, 0xc0, 0x51, 0x0e, 0xef, 0x9d, 0xa6, 0xdd, 0x31, 0x6c, 0x1f, + 0x74, 0xe3, 0xb7, 0xb6, 0x6f, 0x50, 0x88, 0x07, 0x85, 0x19, 0x41, 0xfc, 0xa0, 0xf4, 0x1e, 0x1d, + 0x4f, 0xce, 0x98, 0x53, 0xa1, 0x6f, 0xf5, 0x7f, 0xab, 0xd7, 0x57, 0xfa, 0xbf, 0xd4, 0xc3, 0xf0, + 0x08, 0x48, 0x29, 0x1b, 0xc5, 0x62, 0xb9, 0x70, 0xb8, 0x5b, 0x10, 0xb1, 0x63, 0x5f, 0x7e, 0xdb, + 0x3a, 0x34, 0x60, 0x70, 0x00, 0x2b, 0x40, 0x58, 0x88, 0x00, 0x1d, 0x2c, 0x01, 0x6d, 0x7f, 0x82, + 0x01, 0xa4, 0x17, 0x97, 0x05, 0x6e, 0xe2, 0xb1, 0x59, 0x6c, 0x50, 0x76, 0x61, 0x75, 0x5d, 0xcf, + 0xe1, 0x78, 0x6d, 0xa5, 0xc5, 0xba, 0x7f, 0x80, 0x81, 0x08, 0x0d, 0xd4, 0x57, 0xa7, 0x2f, 0x25, + 0x7d, 0xa2, 0x65, 0x9b, 0x9b, 0x62, 0x78, 0x12, 0x28, 0x21, 0x50, 0xf0, 0xb4, 0x90, 0x03, 0x2d, + 0x6c, 0xb9, 0xf8, 0x71, 0x40, 0x06, 0x6a, 0x7e, 0x10, 0x95, 0xbf, 0xfe, 0x69, 0xa6, 0x9e, 0x9a, + 0xba, 0x18, 0xca, 0x3a, 0x9d, 0x97, 0x72, 0x83, 0xa9, 0x30, 0xcb, 0x06, 0x26, 0x86, 0xbd, 0xb1, + 0xc5, 0x2b, 0xd7, 0xe1, 0xd5, 0x00, 0x15, 0xb8, 0xc1, 0x93, 0xa8, 0x89, 0x93, 0x7f, 0xef, 0x69, + 0xbf, 0xd7, 0x1c, 0x01, 0x9c, 0x18, 0x03, 0x17, 0x38, 0x74, 0x18, 0x32, 0x87, 0x16, 0x5c, 0xf9, + 0x95, 0x92, 0x47, 0xfc, 0x3c, 0x48, 0x01, 0xe0, 0xd9, 0xec, 0x55, 0x60, 0x3f, 0x9b, 0x6c, 0xfe, + 0xb6, 0xdb, 0x6e, 0x5f, 0x18, 0xef, 0xcb, 0x5a, 0x69, 0x8a, 0x2c, 0x51, 0x61, 0xad, 0xc6, 0xe3, + 0xfe, 0x0f, 0xf8, 0xa2, 0xca, 0xba, 0xfc, 0x36, 0x48, 0x01, 0x3b, 0xed, 0x60, 0xd4, 0x20, 0xfc, + 0xdb, 0x7a, 0x25, 0xb6, 0x4e, 0xe3, 0xb7, 0x1d, 0xfc, 0xd4, 0x8b, 0x81, 0x81, 0x38, 0xc0, 0xa3, + 0x6f, 0xa4, 0x54, 0x75, 0x14, 0x07, 0x8e, 0xbe, 0x10, 0x01, 0x22, 0x14, 0x8b, 0x63, 0x7f, 0x06, + 0xd2, 0x96, 0x67, 0x81, 0x60, 0xe3, 0xce, 0x0f, 0x92, 0x40, 0xa0, 0x2c, 0xca, 0x44, 0xa5, 0xe5, + 0x9c, 0x41, 0xc8, 0x21, 0x5e, 0x1e, 0x70, 0x13, 0x75, 0x0f, 0xf3, 0x75, 0x4f, 0xaf, 0xf4, 0xdd, + 0xef, 0xe1, 0xa5, 0x00, 0xb4, 0x6c, 0x91, 0x16, 0x79, 0x3c, 0xd7, 0xeb, 0x5d, 0xf0, 0xd2, 0x80, + 0x0e, 0x7c, 0x20, 0xb1, 0x89, 0xef, 0x0b, 0xdc, 0xbe, 0x2f, 0x6c, 0xf0, 0x6c, 0xb6, 0xee, 0x58, + 0xbb, 0xbb, 0xed, 0x87, 0x9c, 0x00, 0xfb, 0x64, 0x07, 0x62, 0xbc, 0xbf, 0xfb, 0x25, 0x18, 0x64, + 0x4b, 0xc3, 0x9b, 0xbf, 0xc9, 0x6c, 0xb3, 0x15, 0x8a, 0x74, 0x6a, 0xaf, 0x7f, 0xc0, 0x35, 0x00, + 0x10, 0x80, 0xa5, 0x7d, 0x1f, 0xde, 0xcb, 0x58, 0x1e, 0xf8, 0x80, 0x00, 0x27, 0xdb, 0xcb, 0x00, + 0x60, 0xec, 0x72, 0xc7, 0x68, 0x74, 0x36, 0xa1, 0x58, 0x4b, 0x53, 0x47, 0x87, 0x0f, 0x38, 0x54, + 0x0f, 0x01, 0x61, 0x82, 0x14, 0x02, 0x00, 0x18, 0xa8, 0x42, 0x86, 0xdd, 0xd8, 0xfa, 0xae, 0x57, + 0xf5, 0x4b, 0x58, 0x35, 0xd6, 0x25, 0x6a, 0xd3, 0x14, 0x3a, 0x09, 0xd9, 0x5d, 0x0a, 0xbb, 0x61, + 0x0f, 0xc8, 0x29, 0xb1, 0xce, 0x06, 0xef, 0x24, 0x8b, 0xb7, 0xc7, 0x61, 0x9d, 0x30, 0xed, 0x8a, + 0x50, 0x30, 0x79, 0x3d, 0x85, 0x59, 0x40, 0x0f, 0x7e, 0x26, 0x19, 0x05, 0xad, 0xdf, 0xea, 0xaa, + 0xbf, 0x0f, 0x44, 0x00, 0x3f, 0x30, 0x58, 0x3d, 0x52, 0xa7, 0xe3, 0xaf, 0xc9, 0xd3, 0x92, 0xda, + 0xff, 0x80, 0x38, 0x80, 0x20, 0x8d, 0x30, 0xa6, 0x51, 0x04, 0xa1, 0x42, 0xa3, 0xec, 0x3c, 0x00, + 0x0a, 0x60, 0x90, 0x00, 0x2d, 0x81, 0xce, 0x09, 0x4a, 0x10, 0x26, 0x44, 0x85, 0x6d, 0x9c, 0xb6, + 0x5b, 0x2d, 0x8a, 0x31, 0x46, 0x09, 0x52, 0x98, 0x3d, 0x6f, 0xfe, 0x36, 0x15, 0x18, 0x00, 0xa8, + 0x21, 0x80, 0x94, 0x83, 0x00, 0x94, 0x90, 0x0a, 0xa8, 0x56, 0x63, 0x7a, 0x51, 0xc0, 0xe7, 0x0e, + 0x70, 0xb0, 0x19, 0x60, 0x33, 0x87, 0x9c, 0x03, 0x85, 0x80, 0x33, 0x80, 0x01, 0xe1, 0x80, 0xf1, + 0x44, 0x72, 0x5a, 0xc0, 0x57, 0x81, 0xdb, 0xa2, 0x7e, 0xf8, 0x4b, 0x21, 0x04, 0xce, 0xa0, 0x19, + 0x61, 0x8a, 0xaa, 0x95, 0x52, 0x96, 0x37, 0x1c, 0x6f, 0xa6, 0x9c, 0x38, 0xa0, 0x04, 0x2a, 0x37, + 0xb2, 0x23, 0x3d, 0xff, 0xdd, 0xbf, 0xf8, 0xab, 0x15, 0x76, 0xc5, 0x58, 0xa2, 0xc0, 0x40, 0x12, + 0x2a, 0xdf, 0xb3, 0x1f, 0xe0, 0x0d, 0xc0, 0x0c, 0x21, 0x48, 0xa6, 0x2e, 0x23, 0x8c, 0xc4, 0xc5, + 0x64, 0x8a, 0x96, 0x35, 0x2a, 0x5b, 0x6f, 0x2c, 0x19, 0xc3, 0xc9, 0xd5, 0xeb, 0xc4, 0x61, 0xc4, + 0x50, 0x20, 0x43, 0xa2, 0x21, 0x5e, 0x5e, 0xeb, 0x37, 0x6f, 0x3f, 0x6e, 0xe6, 0x6e, 0xdd, 0xcf, + 0xed, 0xb7, 0x0c, 0x28, 0x01, 0x63, 0x54, 0x1f, 0xe4, 0x14, 0x1b, 0xdc, 0x5d, 0xc5, 0xdd, 0x5d, + 0x53, 0x4d, 0x53, 0x15, 0x0e, 0x01, 0x40, 0x0c, 0x8d, 0x8e, 0xb5, 0x67, 0x3f, 0x8e, 0xd1, 0x59, + 0x70, 0xb1, 0x96, 0x32, 0xc3, 0x2c, 0xc5, 0x0c, 0x47, 0xaf, 0x0a, 0x2a, 0x08, 0x5f, 0xc2, 0x8f, + 0x7f, 0x0d, 0x28, 0x01, 0x5c, 0xdb, 0xd3, 0xfb, 0xf4, 0xe9, 0xbb, 0x93, 0xc7, 0xf8, 0xd3, 0x6d, + 0xbc, 0x46, 0x5f, 0x02, 0x04, 0x6c, 0x9e, 0xad, 0x24, 0xb5, 0x11, 0xf8, 0x58, 0x2a, 0xcd, 0x2f, + 0x39, 0xc3, 0x87, 0x09, 0xd5, 0x0f, 0x36, 0x2b, 0xe1, 0x41, 0xef, 0xc5, 0x74, 0x5e, 0x8f, 0x0e, + 0x23, 0x00, 0x19, 0x25, 0xeb, 0x3f, 0xf5, 0x79, 0x31, 0x6f, 0x27, 0xb6, 0xdb, 0x7c, 0xfe, 0xb2, + 0xf1, 0xf7, 0x34, 0x65, 0x17, 0x52, 0xd3, 0x4d, 0xb6, 0xe1, 0xc5, 0x13, 0xf6, 0x96, 0x27, 0xba, + 0x17, 0xe8, 0x23, 0x42, 0x28, 0xa4, 0xf9, 0x17, 0x41, 0x20, 0xb6, 0xfc, 0x38, 0xa0, 0x11, 0xcf, + 0x05, 0x25, 0xfe, 0xb7, 0xa6, 0x9a, 0x69, 0xdb, 0xb6, 0xdb, 0x6d, 0xb6, 0x31, 0x0d, 0xb6, 0xd3, + 0xb7, 0xe1, 0xc5, 0x01, 0x3f, 0xf0, 0xab, 0x56, 0xeb, 0xa9, 0xed, 0x55, 0x6e, 0xcb, 0x4d, 0x39, + 0x70, 0x77, 0xe3, 0xcb, 0x46, 0xfc, 0x38, 0xa0, 0x4a, 0x74, 0xdc, 0x7e, 0xd3, 0xa7, 0x51, 0xff, + 0x3b, 0xb7, 0xab, 0x75, 0x34, 0xdb, 0x78, 0xc4, 0x2f, 0x5a, 0x76, 0xfc, 0x38, 0xa0, 0x48, 0x6a, + 0x80, 0x7f, 0xf3, 0xbe, 0x99, 0xf4, 0xf1, 0xdf, 0xb4, 0x7f, 0x5b, 0x41, 0xa6, 0xb1, 0x61, 0x09, + 0x4c, 0x4b, 0xcb, 0x7f, 0x0e, 0x12, 0x01, 0x3f, 0x11, 0x8a, 0x1d, 0x8e, 0xcb, 0xa6, 0x98, 0xb6, + 0x0f, 0xba, 0xcd, 0xf6, 0xcd, 0xe4, 0xe1, 0x10, 0x18, 0xba, 0x32, 0x99, 0xa8, 0x47, 0x87, 0x7e, + 0x54, 0x4f, 0xba, 0x70, 0xf6, 0x00, 0xe2, 0xc8, 0x3b, 0x46, 0x75, 0x35, 0x65, 0xef, 0xe7, 0xfd, + 0x6c, 0xec, 0xf3, 0xf7, 0x7f, 0x2f, 0xe5, 0xb3, 0xf7, 0xf1, 0xd7, 0xdf, 0xc3, 0xc2, 0x00, 0x02, + 0x5a, 0xfb, 0x4c, 0x6b, 0xfa, 0xe2, 0x42, 0x21, 0x43, 0x94, 0x21, 0x2e, 0x80, 0x29, 0x99, 0x57, + 0xaa, 0x9d, 0x52, 0x5d, 0xfa, 0xaa, 0x8e, 0x0e, 0x70, 0x28, 0x00, 0xf8, 0x0a, 0x10, 0x41, 0xea, + 0xcf, 0x8b, 0x93, 0x2b, 0x1b, 0xa9, 0x78, 0xad, 0xce, 0x1e, 0x70, 0x39, 0xfc, 0x34, 0x42, 0x80, + 0x46, 0xd0, 0xdc, 0xc3, 0x3f, 0xfb, 0xed, 0xeb, 0x0d, 0x38, 0x01, 0x9a, 0xc4, 0x78, 0xca, 0x66, + 0xdf, 0x12, 0x17, 0x7d, 0x55, 0x55, 0xd7, 0x17, 0x8b, 0xce, 0xc2, 0xee, 0x00, 0xe5, 0x16, 0x64, + 0x58, 0x12, 0xb9, 0x5b, 0xdf, 0x4e, 0x98, 0x87, 0xcb, 0xf7, 0xbb, 0x30, 0xb9, 0x20, 0x28, 0x60, + 0x0e, 0x66, 0x1c, 0x90, 0xd6, 0xe1, 0xfc, 0x23, 0x03, 0xef, 0x11, 0x29, 0xc6, 0x48, 0xe5, 0x96, + 0x4a, 0x28, 0x4a, 0x4c, 0x37, 0x33, 0x86, 0x1f, 0xe1, 0xac, 0x03, 0x47, 0x35, 0x07, 0xc1, 0x19, + 0x6b, 0x6d, 0xff, 0xde, 0xdd, 0xf2, 0xc5, 0x12, 0x09, 0x56, 0x02, 0x00, 0x7d, 0x43, 0x44, 0x87, + 0xc0, 0xc6, 0xbf, 0xb7, 0xda, 0xad, 0x4f, 0x98, 0xa6, 0x50, 0x0a, 0x3a, 0x94, 0x74, 0x26, 0x88, + 0x00, 0x75, 0x2d, 0xe3, 0x60, 0x41, 0x8d, 0xb7, 0xfd, 0xbd, 0x7c, 0x30, 0xe0, 0x03, 0x3a, 0x59, + 0xa6, 0x80, 0x83, 0xf3, 0xcd, 0x2f, 0x5b, 0xb2, 0xf2, 0xff, 0x5b, 0xde, 0x6d, 0x85, 0xd4, 0x06, + 0x0e, 0xd2, 0x06, 0xfd, 0x7b, 0x5a, 0x8a, 0x8e, 0x2a, 0x3b, 0xde, 0x2a, 0x38, 0xa8, 0xff, 0xe0, + 0x84, 0x06, 0x00, 0x2a, 0x38, 0xac, 0x56, 0x2b, 0x15, 0x97, 0x07, 0xac, 0x3c, 0x72, 0xea, 0x2e, + 0x2e, 0x52, 0xf0, 0x14, 0x23, 0x45, 0x38, 0xac, 0x40, 0xb0, 0xd9, 0x09, 0x1e, 0x7d, 0x58, 0xb1, + 0x3f, 0x3c, 0xdf, 0x34, 0x63, 0xaa, 0x18, 0xe3, 0x5d, 0xb1, 0xe7, 0xe5, 0x8f, 0xc3, 0xd8, 0x05, + 0x3c, 0x39, 0x0a, 0xe1, 0x08, 0xed, 0x3e, 0x1d, 0xf9, 0x6b, 0xbb, 0x72, 0x71, 0x6d, 0xbd, 0x3e, + 0x5e, 0x98, 0x9f, 0x2d, 0x61, 0x42, 0x73, 0xd3, 0xfc, 0x76, 0xe3, 0x89, 0x7a, 0xff, 0x0c, 0xc6, + 0xc1, 0xae, 0x81, 0x8a, 0x4e, 0x70, 0xa4, 0xd4, 0xfa, 0x59, 0xbf, 0xa9, 0x51, 0xd0, 0x1f, 0x1e, + 0x0f, 0x95, 0x10, 0x0d, 0x4e, 0x1e, 0x51, 0x35, 0x6f, 0x1d, 0xfc, 0x81, 0x64, 0x23, 0xdb, 0x8f, + 0x74, 0xfc, 0x3b, 0x80, 0x54, 0x60, 0x02, 0x44, 0x4e, 0x79, 0x7b, 0xaa, 0x73, 0xe3, 0x1f, 0x76, + 0xf6, 0x71, 0xef, 0x96, 0xd4, 0x1d, 0x7c, 0x76, 0xee, 0xe7, 0xbc, 0x76, 0xe3, 0xaf, 0x8a, 0xe2, + 0xdb, 0x6d, 0xa6, 0x9f, 0xc3, 0x64, 0x80, 0x70, 0xc7, 0x90, 0x43, 0xa6, 0x04, 0xd9, 0x36, 0x74, + 0xfe, 0x4f, 0xdd, 0xec, 0xdd, 0xb7, 0x77, 0xf1, 0x3a, 0x2f, 0x4d, 0x3f, 0x87, 0x30, 0x01, 0x92, + 0xbc, 0x11, 0x66, 0x30, 0x14, 0xff, 0xc9, 0xf9, 0x39, 0xde, 0x6e, 0x5e, 0xaf, 0x2e, 0x5e, 0x6e, + 0xb8, 0xb1, 0x0e, 0x9e, 0x9a, 0x7f, 0x0f, 0x28, 0x03, 0xee, 0x09, 0xfb, 0x2b, 0x28, 0x28, 0xd1, + 0x8b, 0xb1, 0x6f, 0x2f, 0x35, 0x44, 0x03, 0x43, 0xfd, 0xb1, 0x3e, 0xee, 0xe5, 0x83, 0x93, 0xda, + 0x46, 0x04, 0x57, 0x8c, 0x61, 0x39, 0xf8, 0x60, 0x90, 0x10, 0x12, 0x59, 0x93, 0x17, 0x7c, 0xae, + 0xb8, 0xe3, 0xb7, 0x1d, 0x7d, 0x4b, 0x77, 0x51, 0x5a, 0x97, 0x89, 0xff, 0xcf, 0x85, 0xba, 0xb4, + 0x70, 0x01, 0xeb, 0x14, 0x2c, 0x00, 0x05, 0x94, 0xe0, 0x0f, 0x08, 0x24, 0x38, 0xe9, 0x7c, 0x18, + 0x12, 0xf5, 0xf8, 0x4b, 0x9b, 0x6a, 0xdb, 0xe8, 0xef, 0x5c, 0x38, 0x61, 0x0e, 0x08, 0x01, 0xc1, + 0x41, 0x9c, 0x00, 0x0f, 0x08, 0x14, 0x65, 0x78, 0x3c, 0x5f, 0xf0, 0x1b, 0x00, 0x51, 0x1b, 0x06, + 0xaa, 0xac, 0xff, 0x57, 0x85, 0x14, 0xc7, 0x9e, 0x37, 0x0f, 0x00, 0x1c, 0x3c, 0x71, 0x21, 0x1c, + 0xbc, 0x68, 0x00, 0x08, 0x32, 0x80, 0x89, 0x23, 0xd0, 0x9f, 0x6f, 0xe1, 0xd4, 0x50, 0x03, 0x6d, + 0x32, 0x00, 0x33, 0x3b, 0xf6, 0xd9, 0xbb, 0x66, 0xee, 0x2a, 0xcf, 0x7d, 0x63, 0xee, 0x5d, 0x8b, + 0x97, 0x8f, 0xf9, 0x77, 0xbd, 0x1c, 0xfe, 0xdb, 0x78, 0x71, 0x10, 0x00, 0x4f, 0xe5, 0x21, 0x3a, + 0x8a, 0xa3, 0x9a, 0xff, 0x9f, 0x9f, 0xcb, 0x8a, 0x69, 0xe9, 0x8f, 0x66, 0xa3, 0x03, 0xee, 0x76, + 0x20, 0x90, 0x53, 0x2c, 0x27, 0xe9, 0xa6, 0xdb, 0x78, 0x0c, 0x90, 0x3c, 0x8d, 0x81, 0xdc, 0x0d, + 0x47, 0x13, 0xc2, 0x77, 0xe5, 0x81, 0x89, 0x07, 0x09, 0xd5, 0xa8, 0x9e, 0xa4, 0xcf, 0xcb, 0x03, + 0x28, 0x3a, 0x97, 0x8a, 0x67, 0x81, 0xe9, 0x07, 0xf2, 0x8e, 0x00, 0x02, 0x0d, 0x31, 0x74, 0x9e, + 0xeb, 0xfc, 0x38, 0xa0, 0x44, 0xa0, 0xff, 0x67, 0x15, 0x54, 0x49, 0x37, 0x5b, 0x89, 0x25, 0xb3, + 0xde, 0xcf, 0xd5, 0x5d, 0xeb, 0x18, 0x28, 0xc0, 0x9a, 0x63, 0x4a, 0xff, 0xf0, 0xe3, 0x80, 0x4e, + 0x16, 0xc3, 0x62, 0xd6, 0x96, 0x30, 0x76, 0xe5, 0x8b, 0xdb, 0x6f, 0xb6, 0xde, 0xdb, 0x62, 0x2d, + 0xd6, 0xfd, 0xfd, 0xbf, 0xc0, 0x24, 0x20, 0x36, 0x06, 0xc4, 0x01, 0xe2, 0x40, 0xf3, 0x80, 0xf3, + 0xc0, 0xf1, 0x00, 0x07, 0x0e, 0x0e, 0x12, 0x15, 0x88, 0x40, 0x07, 0x9c, 0x1e, 0x58, 0x67, 0x75, + 0x4a, 0x9c, 0x03, 0x84, 0x80, 0x02, 0xa7, 0x00, 0x01, 0x1c, 0x03, 0x80, 0x85, 0x1e, 0x38, 0x18, + 0x91, 0xef, 0xe3, 0xa3, 0xff, 0xc2, 0xf2, 0x01, 0x01, 0x1a, 0xc2, 0xb8, 0x7e, 0x5c, 0xee, 0xff, + 0x6e, 0x5b, 0x7f, 0x15, 0x58, 0x5d, 0x8b, 0x00, 0xfd, 0x20, 0xcd, 0x29, 0x9e, 0xae, 0x7c, 0x1e, + 0x0e, 0xae, 0x7a, 0xb9, 0xec, 0x62, 0xc6, 0x2e, 0xe0, 0x80, 0x04, 0x88, 0x50, 0xcb, 0x2b, 0x6f, + 0x38, 0x7b, 0x9c, 0xfb, 0xdd, 0xec, 0x56, 0x2b, 0xd1, 0xdc, 0x33, 0x1a, 0x02, 0x0a, 0x6d, 0xd5, + 0x25, 0xce, 0xb5, 0xf7, 0x57, 0x52, 0x0b, 0x0b, 0x31, 0x00, 0x1a, 0x05, 0x5f, 0x82, 0x56, 0x2c, + 0xde, 0x78, 0x17, 0xb8, 0xa7, 0xf7, 0x14, 0xdc, 0x53, 0x86, 0xd9, 0x40, 0x1c, 0x00, 0x49, 0x29, + 0xce, 0xae, 0x5d, 0x6a, 0x2b, 0x8a, 0x3f, 0x33, 0x05, 0x83, 0x33, 0x05, 0x83, 0x6d, 0x6b, 0xf0, + 0x9b, 0x30, 0x01, 0x57, 0xf7, 0x30, 0x2c, 0x26, 0xf0, 0x5e, 0x20, 0xc2, 0xa2, 0x1e, 0xb6, 0x58, + 0x6c, 0x85, 0x0e, 0x2e, 0x2b, 0x14, 0xde, 0x17, 0xc0, 0x5b, 0xf2, 0x30, 0xc6, 0x0b, 0xd2, 0xea, + 0x7f, 0xf7, 0xbf, 0xb9, 0xc0, 0x32, 0x00, 0x3a, 0x02, 0x85, 0x55, 0x27, 0x66, 0x42, 0xc0, 0x98, + 0x1c, 0xa1, 0xc3, 0xd0, 0x92, 0xbc, 0x8c, 0xe7, 0xec, 0xc2, 0xde, 0x5b, 0x59, 0x76, 0x38, 0x63, + 0x01, 0xc3, 0x0e, 0x0a, 0x24, 0x41, 0x0c, 0x4c, 0xaa, 0x5b, 0xb6, 0x28, 0xc6, 0xa5, 0xbb, 0x74, + 0xa3, 0xdb, 0xdb, 0x6d, 0xd8, 0x95, 0x00, 0x74, 0x49, 0x81, 0x91, 0x5e, 0xac, 0x01, 0xe8, 0x01, + 0x20, 0x29, 0x0f, 0x83, 0x94, 0x7b, 0x8e, 0xdc, 0x56, 0xf7, 0x11, 0x80, 0x56, 0x80, 0x2c, 0x05, + 0x4f, 0x38, 0xce, 0xdf, 0x45, 0x75, 0x85, 0xd1, 0x40, 0x98, 0x50, 0x08, 0x54, 0x32, 0x7b, 0xff, + 0x5a, 0xde, 0xe9, 0x94, 0x26, 0x88, 0x00, 0xb7, 0x49, 0x18, 0x30, 0xf7, 0xfd, 0x0e, 0x87, 0xf0, + 0xd3, 0x80, 0x63, 0x61, 0x8c, 0xd2, 0xfe, 0xf6, 0xbe, 0xd9, 0x6c, 0x31, 0x28, 0x06, 0x2d, 0x30, + 0xa9, 0xdf, 0xfd, 0x34, 0xf4, 0xd3, 0x1d, 0x47, 0xb0, 0xf4, 0x50, 0x00, 0xd4, 0x9b, 0xbc, 0x5e, + 0x08, 0x5e, 0x31, 0x37, 0x4c, 0xbe, 0xb3, 0xf2, 0xed, 0xbe, 0x9e, 0x0f, 0xf8, 0xff, 0xa6, 0xde, + 0x20, 0xac, 0x83, 0x12, 0xe2, 0xaa, 0xec, 0xa0, 0xae, 0xa7, 0xf1, 0x23, 0x63, 0x89, 0xf3, 0xbc, + 0xaa, 0xf8, 0xef, 0x77, 0x3c, 0x0f, 0x3f, 0xc9, 0x40, 0xa8, 0x7e, 0x0d, 0x43, 0xe1, 0xaa, 0x10, + 0x00, 0x3e, 0xa1, 0xe0, 0x00, 0x4e, 0x4a, 0xab, 0x1a, 0x38, 0x83, 0xe7, 0x0f, 0x03, 0x80, 0x08, + 0x82, 0x8f, 0x3f, 0xcf, 0xf1, 0xd5, 0xcf, 0xff, 0x87, 0x19, 0x40, 0x0c, 0xc4, 0x01, 0xba, 0x3f, + 0x0c, 0xc0, 0xbe, 0xb8, 0xe6, 0xeb, 0x33, 0x6d, 0xba, 0x73, 0x8d, 0xd2, 0x55, 0x52, 0x1b, 0x56, + 0xf2, 0xd9, 0xce, 0x9c, 0xef, 0x0d, 0x20, 0x18, 0x0e, 0x85, 0xe2, 0x7c, 0x9f, 0xe1, 0xc5, 0x00, + 0x60, 0x3a, 0x98, 0x4e, 0x0f, 0x26, 0x5e, 0x2f, 0x10, 0xf9, 0x3c, 0x79, 0xff, 0x93, 0xd5, 0xfb, + 0x25, 0xb4, 0xc4, 0x3d, 0xdf, 0xd5, 0xec, 0xb4, 0xbf, 0x0e, 0x28, 0x00, 0x76, 0xb6, 0xbd, 0x8c, + 0x2e, 0x7d, 0xb4, 0xfc, 0xfc, 0xb5, 0x8e, 0xbe, 0x0e, 0x97, 0x2d, 0x9f, 0xee, 0x4f, 0x11, 0xed, + 0xec, 0xed, 0xec, 0xf0, 0x32, 0x16, 0xc5, 0xb6, 0xdb, 0xfc, 0x03, 0xa0, 0x18, 0x0a, 0x49, 0xd5, + 0xbc, 0xbc, 0xee, 0x17, 0x42, 0x91, 0xcb, 0x1c, 0x00, 0x39, 0x10, 0x03, 0x01, 0x27, 0x0b, 0x19, + 0x60, 0x0c, 0xb0, 0x01, 0x8a, 0x0c, 0x48, 0x03, 0x83, 0x4d, 0x86, 0xd4, 0x00, 0x43, 0xcf, 0xc8, + 0x22, 0x0b, 0x64, 0x7b, 0xf9, 0x56, 0x56, 0xee, 0xd8, 0xb9, 0x61, 0xa2, 0x7f, 0xac, 0xb0, 0x71, + 0x6a, 0xf6, 0xa9, 0xfc, 0x38, 0x48, 0x01, 0xae, 0x57, 0x0c, 0xc5, 0x5a, 0x02, 0x5f, 0xc5, 0xb2, + 0xf7, 0x6c, 0xfc, 0x4f, 0xd6, 0x7f, 0xc4, 0x3d, 0x4e, 0x7d, 0x6e, 0xf1, 0x9d, 0xe2, 0xd1, 0xeb, + 0xff, 0x0e, 0xcd, 0x4b, 0xb3, 0x58, 0xe5, 0x0f, 0x39, 0x26, 0x00, 0x2b, 0x21, 0x66, 0x77, 0x10, + 0xf6, 0xfc, 0x2b, 0xc1, 0x21, 0xaf, 0x14, 0x1b, 0xf0, 0x08, 0x00, 0x16, 0x46, 0xc9, 0x80, 0xea, + 0xe2, 0x00, 0x70, 0x3f, 0x35, 0x27, 0x02, 0xa5, 0x61, 0x28, 0x7e, 0x4a, 0x48, 0x15, 0x38, 0x00, + 0x1e, 0x4e, 0x00, 0xb1, 0x2b, 0x1f, 0x0e, 0x9f, 0x7e, 0x97, 0x67, 0xf9, 0x76, 0x1a, 0x80, 0x00, + 0x41, 0x5e, 0x38, 0x01, 0xb7, 0x59, 0xa0, 0xd8, 0x7c, 0x38, 0x8a, 0x11, 0x20, 0xe2, 0x3a, 0x0b, + 0xf7, 0x50, 0xff, 0xc6, 0x6d, 0x36, 0xc7, 0xab, 0x58, 0x9a, 0x62, 0xd3, 0x12, 0xe9, 0x32, 0x04, + 0xa2, 0x41, 0x0b, 0x44, 0xb2, 0xcf, 0xf0, 0x38, 0x01, 0xe4, 0x29, 0x5d, 0x58, 0x75, 0xb5, 0x51, + 0x90, 0xed, 0xc7, 0x6c, 0x0e, 0xe4, 0xa5, 0x86, 0x58, 0x19, 0x2a, 0xa7, 0xf9, 0x60, 0xd5, 0xa9, + 0xc1, 0xec, 0xc5, 0x2a, 0x3c, 0xf0, 0x1e, 0x00, 0x02, 0x10, 0x31, 0xc0, 0x00, 0x87, 0x82, 0x11, + 0xb3, 0xc1, 0xc3, 0xc1, 0xc8, 0xea, 0x3c, 0x00, 0x70, 0x3b, 0x8d, 0x47, 0x1b, 0x07, 0x45, 0x98, + 0xb8, 0x54, 0x01, 0x5a, 0x33, 0xc0, 0xf2, 0xc0, 0x03, 0x28, 0xa5, 0x3c, 0x00, 0x3c, 0x14, 0x00, + 0x02, 0x10, 0x60, 0xd0, 0x00, 0x21, 0x4e, 0x33, 0x7f, 0xe1, 0xd5, 0x01, 0x51, 0xd1, 0x20, 0x78, + 0x60, 0xdb, 0x6e, 0x4e, 0xe2, 0x5f, 0x09, 0xdb, 0x7d, 0x53, 0x27, 0x54, 0xce, 0xf1, 0xff, 0x3b, + 0x1c, 0xde, 0xff, 0x87, 0x54, 0x00, 0x99, 0x03, 0x87, 0x73, 0x78, 0x20, 0xff, 0xef, 0x48, 0xfd, + 0xd0, 0x29, 0xb0, 0x3f, 0xe7, 0x60, 0x5b, 0x6f, 0x8e, 0x32, 0xf7, 0x7e, 0x54, 0x0c, 0x21, 0x93, + 0xd6, 0x3a, 0xfb, 0x67, 0xbf, 0xe1, 0xe2, 0x40, 0x48, 0x32, 0x84, 0xce, 0x8d, 0xff, 0x31, 0xa6, + 0xbd, 0xde, 0x6e, 0xf5, 0x9e, 0xf9, 0xb5, 0x0a, 0x61, 0x82, 0x07, 0x9d, 0xfc, 0x75, 0xfb, 0x3d, + 0xf5, 0xac, 0x35, 0x20, 0x06, 0xd4, 0x8c, 0x3e, 0xfd, 0xef, 0xfe, 0x16, 0x42, 0x18, 0x2a, 0x17, + 0x24, 0x00, 0xc0, 0xd8, 0xf4, 0xf0, 0xbf, 0xae, 0xee, 0xbd, 0xde, 0x78, 0x75, 0x6c, 0x36, 0xce, + 0x04, 0xff, 0x11, 0xce, 0xbb, 0x32, 0xc3, 0xfb, 0xfd, 0xdb, 0x32, 0x49, 0xbd, 0x95, 0x96, 0x13, + 0x21, 0x02, 0xed, 0xaa, 0x86, 0x6e, 0xae, 0x8e, 0xaf, 0x84, 0xab, 0x59, 0xa1, 0xbe, 0x1b, 0xe0, + 0x8a, 0x17, 0x62, 0xc0, 0x75, 0x19, 0x26, 0x7d, 0xef, 0xf1, 0x5c, 0x56, 0x31, 0x8d, 0xe1, 0xd9, + 0x80, 0x14, 0x40, 0xbd, 0xe2, 0x5c, 0xdd, 0x55, 0x58, 0xa7, 0x14, 0xe6, 0xed, 0xcc, 0x5e, 0x2f, + 0xc5, 0x4f, 0xdb, 0xf0, 0xbb, 0x80, 0x2c, 0x7d, 0x01, 0xa0, 0x1a, 0x6c, 0xad, 0xaf, 0x76, 0xcf, + 0xf5, 0x7e, 0x7f, 0xf6, 0x17, 0x21, 0x00, 0x1d, 0x45, 0x5c, 0x81, 0x11, 0x55, 0xd9, 0x0a, 0xfd, + 0x90, 0xaf, 0x15, 0xad, 0x71, 0x61, 0x62, 0x40, 0x3a, 0x5b, 0x08, 0xe7, 0xbd, 0xff, 0xf8, 0x80, + 0xc8, 0x50, 0xad, 0x35, 0x83, 0x78, 0xe2, 0x4c, 0x6f, 0xb6, 0xd4, 0xc4, 0x12, 0xcf, 0x71, 0x3c, + 0xa8, 0x73, 0x1c, 0x1c, 0x34, 0xa0, 0x2c, 0xf0, 0x14, 0x53, 0xfa, 0xfd, 0x55, 0x6b, 0x0b, 0xe0, + 0x09, 0xcc, 0xfc, 0x46, 0x91, 0xba, 0xaa, 0xaa, 0xa9, 0xbc, 0xce, 0xb5, 0xd8, 0xc3, 0x59, 0x1d, + 0x69, 0x5d, 0x3f, 0xff, 0xf6, 0xbc, 0x61, 0x76, 0x50, 0x09, 0x40, 0xdb, 0x88, 0x51, 0xdc, 0xbd, + 0x54, 0x5f, 0xea, 0xaa, 0xbb, 0x30, 0xbb, 0x20, 0x03, 0x03, 0x1a, 0xc3, 0xc2, 0x6e, 0xaf, 0x9f, + 0x59, 0x3f, 0xbd, 0xec, 0xab, 0x12, 0xc2, 0xe4, 0xd8, 0xa5, 0x0d, 0x85, 0x37, 0x1a, 0xc4, 0x81, + 0x30, 0xb4, 0x24, 0x74, 0x2c, 0xdc, 0x03, 0xf2, 0x03, 0xa0, 0x29, 0x71, 0x5b, 0x89, 0x1e, 0xd8, + 0xe8, 0x2f, 0x89, 0xc2, 0x20, 0x72, 0x5e, 0x8b, 0x25, 0x54, 0xfe, 0x76, 0x1e, 0x8e, 0x00, 0xcf, + 0x4e, 0x70, 0x12, 0x97, 0xfc, 0xeb, 0xc6, 0x9c, 0x9e, 0x2f, 0xad, 0x35, 0x75, 0x09, 0x2d, 0x99, + 0x83, 0x11, 0x71, 0xfe, 0xee, 0x79, 0xe9, 0x97, 0xde, 0x1a, 0x24, 0x09, 0x7f, 0xa6, 0x8d, 0xfd, + 0x77, 0xd7, 0xdb, 0xfc, 0x63, 0xb0, 0xe2, 0x80, 0x06, 0x31, 0xcb, 0x80, 0x94, 0xac, 0x1a, 0x86, + 0x95, 0xbd, 0x74, 0xc9, 0xc1, 0xff, 0x1e, 0xba, 0xb7, 0x6f, 0x14, 0xcd, 0xcf, 0x3c, 0xac, 0xc8, + 0xbd, 0xe5, 0xff, 0x81, 0x80, 0x30, 0x36, 0x28, 0x06, 0x48, 0x15, 0x38, 0xf4, 0x9a, 0x9b, 0xb9, + 0x60, 0x07, 0x85, 0x42, 0xad, 0x0c, 0x36, 0x5a, 0xad, 0x48, 0x5c, 0x0a, 0x9e, 0x07, 0x02, 0x20, + 0x20, 0x70, 0xd0, 0x3a, 0x41, 0x02, 0xc4, 0x3f, 0x66, 0x64, 0x79, 0x44, 0x39, 0x1e, 0x72, 0xd5, + 0x78, 0x40, 0x6c, 0xe3, 0xe5, 0x01, 0x52, 0x4d, 0x83, 0xb6, 0x33, 0x0f, 0x0f, 0xe9, 0x81, 0xae, + 0x94, 0x73, 0xcf, 0xa8, 0x9c, 0xa8, 0x41, 0x21, 0x47, 0x03, 0xb2, 0x0a, 0x3d, 0xb2, 0x43, 0xa4, + 0x79, 0xbb, 0x70, 0xe4, 0xa0, 0x02, 0xe7, 0x38, 0x6c, 0xb8, 0xea, 0x20, 0x96, 0xee, 0xd9, 0x7a, + 0x71, 0x17, 0x36, 0xdc, 0x67, 0x8a, 0xcc, 0x64, 0x99, 0x92, 0x95, 0xed, 0x9b, 0xfc, 0x3a, 0x42, + 0x80, 0x06, 0x8f, 0x21, 0xa4, 0xae, 0x76, 0xa7, 0xc3, 0x77, 0xf7, 0x7a, 0xcb, 0x65, 0x98, 0xac, + 0x5e, 0x38, 0xff, 0x97, 0xc9, 0xc5, 0xd9, 0xc6, 0x22, 0xa6, 0xfb, 0xfc, 0x38, 0xa0, 0x07, 0x55, + 0x93, 0x09, 0xc5, 0xa9, 0xba, 0x73, 0x58, 0xd7, 0x3d, 0x29, 0x2f, 0x17, 0xb3, 0xdc, 0x5f, 0x84, + 0x4d, 0x26, 0x2e, 0x43, 0xff, 0x1e, 0x5c, 0x41, 0x32, 0x3b, 0x75, 0x04, 0x3d, 0x03, 0xae, 0xf8, + 0xae, 0xb1, 0x7d, 0x71, 0x91, 0x50, 0x15, 0x21, 0x01, 0xa6, 0x10, 0x79, 0x58, 0x11, 0xd2, 0x40, + 0x6a, 0x07, 0x8b, 0x03, 0xe4, 0xad, 0xc1, 0x69, 0xa8, 0x0f, 0xf9, 0x60, 0xc5, 0x60, 0xc1, 0xf3, + 0x37, 0x73, 0x8c, 0x96, 0xab, 0xd1, 0x24, 0x99, 0x92, 0xb9, 0xd4, 0xbf, 0xe1, 0xe2, 0x40, 0x32, + 0x29, 0xcc, 0x54, 0xa2, 0xfa, 0xf3, 0x3d, 0xc6, 0xf6, 0x29, 0xb8, 0xa7, 0x5e, 0xb3, 0x77, 0x5b, + 0x96, 0x39, 0xad, 0xc7, 0xfc, 0x1c, 0x02, 0x80, 0xa7, 0x85, 0x55, 0xc5, 0x5c, 0x62, 0x78, 0x4d, + 0x52, 0xc0, 0x62, 0x5e, 0x28, 0x31, 0xdf, 0x97, 0x9c, 0x71, 0x11, 0x4c, 0xa4, 0x1a, 0x80, 0x00, + 0x41, 0x66, 0x38, 0x00, 0x10, 0xe0, 0x36, 0x40, 0x90, 0x14, 0x9f, 0xf5, 0x9a, 0x27, 0x38, 0xad, + 0x4b, 0x01, 0x9e, 0x0f, 0x1d, 0x2e, 0x77, 0x87, 0xb6, 0xa5, 0xef, 0xc7, 0xe9, 0x7b, 0xa0, 0x38, + 0x00, 0x08, 0x26, 0xc7, 0x00, 0xf0, 0x38, 0x86, 0x46, 0xcb, 0x18, 0xa6, 0x4a, 0x00, 0xd3, 0x66, + 0x1c, 0x00, 0x70, 0x56, 0x79, 0xe5, 0x80, 0x33, 0xf2, 0xc0, 0x6e, 0xed, 0xea, 0x95, 0x65, 0x16, + 0xa6, 0x03, 0x60, 0x00, 0x10, 0x55, 0x8e, 0x00, 0x19, 0xbb, 0x6b, 0xfc, 0x40, 0x44, 0x6c, 0xe3, + 0x91, 0x62, 0x8d, 0x42, 0xab, 0x56, 0xf1, 0xd1, 0xf2, 0xf0, 0xab, 0x52, 0x42, 0xa3, 0xc0, 0xe6, + 0x37, 0x4e, 0x18, 0xb0, 0x00, 0x10, 0x57, 0x8e, 0x00, 0x1b, 0x6d, 0xb6, 0xdf, 0xc3, 0xc4, 0x80, + 0x7a, 0x41, 0xd2, 0x7e, 0x6a, 0xa7, 0xef, 0x5a, 0x8a, 0xd7, 0x27, 0x53, 0xbc, 0xe7, 0xc7, 0x6e, + 0x1b, 0x8a, 0x54, 0xdd, 0x6d, 0xb7, 0xf0, 0xd9, 0x20, 0x05, 0xbb, 0x40, 0xd7, 0xd1, 0x94, 0x0d, + 0x6e, 0xda, 0x93, 0x8b, 0xef, 0x78, 0xba, 0x88, 0xf9, 0x08, 0x50, 0x4e, 0x74, 0x89, 0x31, 0xf1, + 0xa8, 0x70, 0x7f, 0xc3, 0x44, 0x81, 0x89, 0x96, 0xc7, 0xde, 0xff, 0xfa, 0xc2, 0x6c, 0xc0, 0x0d, + 0x18, 0x48, 0x15, 0xef, 0x72, 0x2b, 0xbd, 0xee, 0xa2, 0xb5, 0x15, 0xde, 0xf0, 0xdc, 0x48, 0x1b, + 0x58, 0x44, 0x56, 0xbb, 0x2d, 0x6a, 0xca, 0xcb, 0x3a, 0x9a, 0x26, 0x53, 0xfb, 0xe1, 0xe2, 0x40, + 0x97, 0x90, 0xd2, 0x5f, 0xaf, 0xed, 0xe2, 0xda, 0xbf, 0xe1, 0x96, 0x24, 0x02, 0x50, 0x0d, 0x88, + 0xa3, 0xc9, 0xee, 0xee, 0xea, 0xaa, 0xae, 0xee, 0xfe, 0xc3, 0x2e, 0x00, 0x7e, 0xd0, 0xf7, 0x66, + 0xad, 0xce, 0xae, 0xb1, 0x78, 0xbb, 0xbb, 0xbd, 0x6a, 0x97, 0x0e, 0x90, 0x80, 0x06, 0xe0, 0x33, + 0x4e, 0x1e, 0x9f, 0xdb, 0x85, 0x38, 0xbd, 0xba, 0xdb, 0x6c, 0x5d, 0xb1, 0x3f, 0x5f, 0xa3, 0xdf, + 0x5f, 0x0d, 0x4c, 0x00, 0x91, 0x63, 0x65, 0xe4, 0xad, 0xcf, 0x78, 0xb8, 0xac, 0xde, 0xdd, 0xdd, + 0xff, 0x92, 0xb8, 0x58, 0x90, 0x14, 0x72, 0x3b, 0x72, 0xfb, 0xdd, 0xfa, 0xba, 0xbc, 0x34, 0x43, + 0x88, 0xda, 0x0a, 0x69, 0xff, 0xfa, 0x5f, 0xf1, 0xd9, 0x54, 0x38, 0x48, 0x16, 0x61, 0x57, 0x9f, + 0x37, 0x5e, 0xef, 0xad, 0x55, 0x7f, 0xc2, 0xec, 0x80, 0x37, 0x36, 0xc2, 0x24, 0xdd, 0xa9, 0xe3, + 0x3f, 0x8b, 0xd5, 0x6b, 0x2d, 0x8b, 0x70, 0x1a, 0xec, 0xab, 0x35, 0x84, 0xc8, 0x50, 0x07, 0x3b, + 0x45, 0xc7, 0x7d, 0x74, 0xfa, 0xf8, 0x4d, 0x90, 0x01, 0xa8, 0xf3, 0x0c, 0x93, 0x77, 0x75, 0xf7, + 0x8f, 0xd2, 0xdf, 0x8e, 0x94, 0x03, 0xb5, 0x09, 0x21, 0xdb, 0x15, 0x81, 0x20, 0xb1, 0x74, 0x5c, + 0x85, 0xd1, 0x40, 0x6f, 0x46, 0x4b, 0x17, 0x5b, 0x9f, 0x99, 0xf5, 0xac, 0xcf, 0x99, 0xf4, 0x77, + 0x81, 0x60, 0x04, 0xc0, 0x5c, 0x40, 0x54, 0xa9, 0x28, 0x00, 0x12, 0x5a, 0xc7, 0x41, 0x78, 0xbd, + 0x42, 0xb4, 0x6c, 0x18, 0x97, 0x7f, 0x87, 0x88, 0x40, 0x26, 0x1e, 0x88, 0x1a, 0x34, 0x7e, 0xb5, + 0xab, 0x6a, 0xeb, 0x81, 0x73, 0x1a, 0x73, 0x52, 0x7f, 0x87, 0x30, 0x02, 0x18, 0x18, 0xfb, 0xff, + 0x07, 0x3f, 0x9f, 0x5e, 0xee, 0x81, 0xff, 0x19, 0x7b, 0x9b, 0x9f, 0x9f, 0xfb, 0x67, 0xef, 0xe0, + 0xd6, 0x8c, 0x8d, 0xeb, 0x95, 0xf8, 0x76, 0x24, 0x02, 0x76, 0x98, 0xcf, 0xd9, 0x59, 0xba, 0x16, + 0xc9, 0x01, 0x5b, 0x21, 0x77, 0x68, 0x9e, 0x79, 0xa2, 0xc8, 0xa7, 0x18, 0xa5, 0x33, 0xea, 0xff, + 0x0e, 0x28, 0x00, 0xc6, 0xe1, 0x7a, 0x7f, 0xcc, 0x7b, 0x85, 0x32, 0xc6, 0x2e, 0x2b, 0x45, 0x48, + 0x91, 0x59, 0x8d, 0xd3, 0x10, 0xf7, 0x50, 0xef, 0x2c, 0x39, 0x0e, 0xd6, 0xea, 0x6f, 0x5f, 0xc3, + 0xc8, 0x80, 0x06, 0x59, 0x7b, 0x4c, 0x57, 0xd2, 0xff, 0xd5, 0x7a, 0xd5, 0xf1, 0x46, 0x2e, 0x5b, + 0x12, 0x78, 0xac, 0xf3, 0xcb, 0x18, 0xb9, 0x6c, 0xb4, 0x04, 0x18, 0xc5, 0x37, 0x29, 0xaf, 0xe0, + 0x14, 0x80, 0x42, 0x36, 0x2b, 0x1d, 0x5d, 0xdd, 0xc7, 0x97, 0x7f, 0x26, 0xd0, 0xb5, 0xc3, 0x60, + 0x78, 0x9c, 0x74, 0x17, 0xbc, 0x00, 0x15, 0x0f, 0x0e, 0x1e, 0x00, 0x16, 0x07, 0xae, 0x0f, 0xd3, + 0x71, 0x72, 0xff, 0x87, 0x14, 0x00, 0x98, 0xd8, 0x52, 0xf1, 0xf2, 0xaa, 0x17, 0x95, 0xe8, 0xe3, + 0x37, 0xd9, 0xce, 0xf7, 0x3c, 0xf5, 0x98, 0x67, 0x3f, 0x19, 0x6f, 0x55, 0xca, 0x70, 0xf8, 0x6b, + 0xc6, 0xd8, 0x2b, 0xc3, 0xa8, 0x82, 0x41, 0x7e, 0x16, 0x89, 0x7c, 0xf0, 0x7c, 0xb0, 0x01, 0x89, + 0x1e, 0x4a, 0x00, 0x0e, 0x0b, 0x01, 0x84, 0x48, 0x19, 0xe2, 0x21, 0xf2, 0x40, 0x1c, 0x7e, 0x13, + 0x0e, 0x28, 0x01, 0x2a, 0x9b, 0x0f, 0xe7, 0x61, 0xc4, 0xef, 0x72, 0xf4, 0xf4, 0xcf, 0xf2, 0xf4, + 0xf4, 0xc5, 0xb0, 0xf5, 0x57, 0xed, 0x97, 0x61, 0xec, 0x00, 0x52, 0xa3, 0x26, 0x0e, 0x1c, 0x7c, + 0xdd, 0xe1, 0x72, 0xda, 0x89, 0x1f, 0x59, 0x7e, 0x29, 0xa2, 0x3d, 0x82, 0x27, 0xc0, 0xfc, 0xb3, + 0x7f, 0x90, 0x22, 0xce, 0x96, 0x55, 0x7e, 0x1d, 0x50, 0x02, 0xe9, 0xa2, 0x19, 0xd0, 0xcb, 0xff, + 0x5c, 0x5f, 0x2d, 0xf9, 0x79, 0x7a, 0x67, 0x3e, 0xcf, 0xc4, 0xbf, 0x2f, 0xb5, 0x64, 0x08, 0x28, + 0x55, 0xad, 0x53, 0x4f, 0xc0, 0x6c, 0x09, 0x0a, 0x5b, 0xcf, 0xf6, 0xf1, 0xdb, 0x9c, 0x07, 0x9c, + 0xf2, 0xb0, 0xa8, 0x5b, 0x3d, 0xe3, 0xa5, 0xcf, 0x79, 0x66, 0x2d, 0x09, 0x4c, 0xa6, 0x5c, 0x44, + 0x00, 0x04, 0x16, 0x50, 0xc0, 0x02, 0xb0, 0x2c, 0x02, 0x80, 0xa5, 0x99, 0x27, 0x3e, 0xb1, 0x40, + 0xd9, 0xa2, 0x00, 0xf3, 0x9e, 0x28, 0xc5, 0x58, 0xa3, 0x6c, 0xa4, 0x4a, 0x73, 0x46, 0x69, 0xe3, + 0xc6, 0x80, 0x00, 0x82, 0xba, 0x12, 0x04, 0xb0, 0x70, 0x0c, 0x06, 0xc7, 0x5f, 0x27, 0x00, 0xd0, + 0xf7, 0x9e, 0x07, 0x9c, 0x1f, 0x64, 0x81, 0x5f, 0x13, 0xe1, 0x41, 0x62, 0x4a, 0xac, 0x67, 0xdb, + 0x1d, 0x5c, 0x31, 0xc0, 0x00, 0x41, 0x66, 0x30, 0x02, 0xa7, 0xed, 0xdf, 0xc3, 0xc4, 0x80, 0x16, + 0x85, 0x61, 0x69, 0x82, 0x77, 0x1e, 0x4a, 0xb7, 0xe7, 0x41, 0x90, 0x64, 0xd8, 0xb9, 0xe0, 0x5b, + 0x7f, 0xa5, 0x5a, 0xfc, 0x3f, 0x89, 0x7d, 0x63, 0xbf, 0xac, 0x40, 0x4d, 0x05, 0x3b, 0x9f, 0xfe, + 0x1b, 0x24, 0x00, 0xea, 0x1d, 0xfc, 0x81, 0x24, 0xbd, 0xaf, 0x6b, 0xff, 0xf8, 0xcb, 0x78, 0xa3, + 0x71, 0x2f, 0x1b, 0xc3, 0xe6, 0xd8, 0x91, 0xe7, 0xe3, 0x88, 0xfb, 0xea, 0xce, 0x79, 0xa3, 0x38, + 0xd0, 0x0c, 0x17, 0xcf, 0xe6, 0xa7, 0xc3, 0x38, 0x07, 0x24, 0x50, 0x83, 0xa9, 0x4a, 0x13, 0x77, + 0x7d, 0x38, 0xb8, 0xba, 0xab, 0x79, 0x7b, 0x7b, 0x7c, 0xac, 0x8b, 0x89, 0x21, 0x8c, 0xec, 0x80, + 0x0e, 0xfe, 0x2c, 0x3d, 0x0b, 0x90, 0xc0, 0x25, 0x0c, 0x40, 0xcf, 0x39, 0xaf, 0x77, 0xea, 0x58, + 0x2c, 0x27, 0x51, 0x5a, 0xb6, 0x1b, 0x43, 0x41, 0x06, 0x6a, 0xcb, 0xed, 0xa2, 0x8c, 0x63, 0x27, + 0x74, 0x61, 0xf0, 0xbd, 0x3b, 0x65, 0x3f, 0x9b, 0xf8, 0x4d, 0x90, 0x04, 0x79, 0xb0, 0x9f, 0x37, + 0xeb, 0xff, 0x8b, 0x62, 0x40, 0x1e, 0xf0, 0x1a, 0x35, 0x07, 0xd8, 0x4d, 0xc0, 0x14, 0x6f, 0x0d, + 0x43, 0x3f, 0xe3, 0xf9, 0xff, 0x6f, 0xb7, 0x0d, 0x4c, 0x00, 0xc7, 0x5e, 0x60, 0xae, 0xfc, 0xdb, + 0x75, 0xaf, 0xfe, 0xb7, 0x10, 0xce, 0x00, 0x90, 0x70, 0xa1, 0xc4, 0x8a, 0xea, 0x5a, 0xcd, 0xcd, + 0xe6, 0xfa, 0xac, 0xde, 0xdb, 0x8c, 0x03, 0x60, 0x04, 0x80, 0xa4, 0x50, 0x19, 0xf9, 0xe0, 0xe3, + 0xfe, 0xb6, 0xdb, 0xeb, 0xeb, 0xa8, 0xb0, 0xf0, 0xbc, 0xa1, 0x05, 0x7a, 0x7f, 0xbd, 0xfe, 0x9b, + 0x0b, 0xb3, 0x87, 0xab, 0x4b, 0x5a, 0xd6, 0xb5, 0xde, 0xe3, 0xb6, 0x1a, 0x63, 0x01, 0x93, 0x5f, + 0xe9, 0xfd, 0x7e, 0xc3, 0x52, 0x80, 0x95, 0xd3, 0x9e, 0x5f, 0xff, 0x4d, 0x3e, 0xc6, 0x17, 0xc0, + 0x53, 0x63, 0xa6, 0xff, 0xfe, 0xf9, 0x61, 0xa2, 0x40, 0x1e, 0xc4, 0x66, 0x03, 0xb4, 0x2c, 0xdb, + 0x3f, 0xff, 0x6f, 0x71, 0x5e, 0xc3, 0xc4, 0x81, 0x1e, 0xe9, 0x2a, 0x7f, 0xff, 0x97, 0x5b, 0xff, + 0x14, 0xe0, 0x34, 0x7c, 0x08, 0xe4, 0x26, 0xa0, 0x85, 0x08, 0x81, 0xda, 0xd7, 0xaf, 0x45, 0x45, + 0x86, 0x10, 0xb0, 0x06, 0x51, 0x5c, 0xb1, 0x83, 0x7b, 0xdd, 0xfe, 0xf7, 0x47, 0x1c, 0x3d, 0x18, + 0x04, 0xc7, 0x10, 0x28, 0xff, 0x92, 0xf6, 0x65, 0xeb, 0x4f, 0xfc, 0x38, 0x66, 0x8c, 0x6a, 0x3a, + 0x2f, 0x0a, 0x9e, 0xbd, 0xe1, 0xc2, 0x40, 0x64, 0x5f, 0x04, 0x12, 0x3f, 0x9c, 0x5b, 0x3f, 0x07, + 0x74, 0x2b, 0xfb, 0xc7, 0xea, 0xd8, 0xc0, 0x01, 0x53, 0xa7, 0x24, 0xff, 0x80, 0x4c, 0x40, 0x64, + 0x8d, 0x88, 0x00, 0x3c, 0x1e, 0x0b, 0x02, 0x95, 0x38, 0x70, 0x78, 0x2c, 0x1e, 0x02, 0xc3, 0x9c, + 0x89, 0x6a, 0x9e, 0x0e, 0x1e, 0x71, 0x62, 0x96, 0x37, 0x76, 0x37, 0x83, 0x82, 0x00, 0x02, 0x07, + 0x68, 0x12, 0x00, 0x05, 0xa2, 0xad, 0xbf, 0xf8, 0x02, 0x78, 0x01, 0x10, 0x14, 0x9c, 0x70, 0xe0, + 0x03, 0x84, 0xaa, 0x9d, 0xc3, 0x8e, 0x93, 0x03, 0x51, 0xcf, 0x3c, 0x05, 0x82, 0xc1, 0xb7, 0x4b, + 0x01, 0x8e, 0xfc, 0xb6, 0x78, 0xe6, 0x6c, 0x1a, 0x00, 0x02, 0x0b, 0x20, 0x38, 0x00, 0x18, 0xc3, + 0x0a, 0x01, 0x6c, 0x4b, 0x01, 0x91, 0x07, 0xce, 0xf8, 0xd8, 0x17, 0xe7, 0x80, 0x3b, 0xf1, 0xd7, + 0xec, 0xb7, 0xf1, 0x46, 0xe5, 0xe0, 0xcc, 0xfc, 0x3c, 0xca, 0x00, 0xcc, 0x44, 0x74, 0xd1, 0x50, + 0xbe, 0x32, 0x0d, 0xfa, 0x7a, 0xb8, 0x3b, 0x71, 0x74, 0xd9, 0xcb, 0xc2, 0xcd, 0x37, 0xb0, 0x5e, + 0x03, 0x53, 0x4d, 0xf4, 0x3c, 0x3f, 0xc3, 0x01, 0x80, 0xa5, 0xfe, 0x39, 0x53, 0xc1, 0xc3, 0x24, + 0x65, 0x1a, 0x3f, 0x8e, 0xcf, 0xa2, 0x98, 0x3d, 0xe2, 0xa5, 0x38, 0x38, 0x49, 0x58, 0x94, 0xa8, + 0xc0, 0x00, 0x10, 0x75, 0x01, 0xc0, 0x00, 0xf7, 0x01, 0xc0, 0x04, 0x10, 0xa4, 0x7e, 0x29, 0x41, + 0xc4, 0x5d, 0x80, 0xda, 0x0e, 0x25, 0xc2, 0x80, 0x05, 0x55, 0xa8, 0xf0, 0xba, 0x30, 0x54, 0x1e, + 0xf9, 0x62, 0xd6, 0x29, 0x50, 0x59, 0x4a, 0x91, 0x2d, 0xb0, 0x54, 0x26, 0x00, 0x02, 0x0a, 0x5b, + 0x60, 0x62, 0x9c, 0x58, 0x89, 0xc1, 0x14, 0x8d, 0xc9, 0x87, 0x69, 0x78, 0xb9, 0xf6, 0xdb, 0x59, + 0x33, 0xe4, 0xdb, 0x4f, 0xea, 0x40, 0x7c, 0x4c, 0xdb, 0x6b, 0x2b, 0x6d, 0x7a, 0xc5, 0x7c, 0x10, + 0xef, 0x7e, 0xac, 0x48, 0x24, 0x34, 0x28, 0xab, 0x94, 0x81, 0xaf, 0xf0, 0xf6, 0x00, 0xc8, 0x71, + 0x64, 0x71, 0xfb, 0xf2, 0x4e, 0xac, 0xfa, 0xbc, 0xbe, 0x14, 0x96, 0x07, 0x86, 0x37, 0xff, 0x7f, + 0xc3, 0x33, 0x80, 0x03, 0xfc, 0x3e, 0xa5, 0x7b, 0x4f, 0x6a, 0x02, 0x78, 0x1d, 0x3f, 0x58, 0x97, + 0xfb, 0x93, 0xc6, 0x7a, 0x93, 0x9f, 0x87, 0xf0, 0xdd, 0xb0, 0x7f, 0x87, 0x94, 0x01, 0xca, 0x81, + 0x29, 0x49, 0x31, 0x1a, 0xeb, 0x17, 0x06, 0x5f, 0x3a, 0x08, 0x8d, 0x08, 0x47, 0x98, 0x5d, 0x23, + 0xfa, 0x51, 0x7a, 0x9c, 0x63, 0x7f, 0xe1, 0xc5, 0x00, 0x1f, 0xe0, 0x77, 0x1f, 0x45, 0x86, 0xa2, + 0xc2, 0x89, 0x1c, 0x15, 0xd8, 0xb2, 0xf2, 0x9b, 0x05, 0xb6, 0xc4, 0xf0, 0x79, 0xfe, 0x3b, 0xf3, + 0x73, 0xc4, 0x94, 0x70, 0xbf, 0x0a, 0xf0, 0x23, 0xa1, 0x16, 0x95, 0x53, 0x4f, 0xe1, 0xe2, 0x40, + 0x05, 0x7e, 0xd9, 0x5e, 0xff, 0xf3, 0x4b, 0xdb, 0xe6, 0x9b, 0x8b, 0xce, 0x6e, 0x2e, 0x2b, 0x17, + 0x1f, 0xcb, 0xa2, 0x74, 0x5f, 0x0d, 0x90, 0xc0, 0x0d, 0x21, 0xc7, 0x84, 0xc3, 0x8f, 0xe0, 0xf7, + 0xf7, 0x3f, 0xad, 0xe7, 0xed, 0x89, 0x7d, 0x67, 0x8f, 0x77, 0x1b, 0x9f, 0x7b, 0xfc, 0x3c, 0x42, + 0x00, 0x38, 0x91, 0xb0, 0xfb, 0x61, 0xc9, 0x18, 0x56, 0xde, 0xfe, 0xdb, 0xef, 0x12, 0xf3, 0xfa, + 0x60, 0x4a, 0x43, 0xf2, 0xf7, 0xfc, 0x14, 0x42, 0x90, 0x68, 0x9a, 0xac, 0xc1, 0x39, 0x53, 0x8f, + 0x2d, 0x9e, 0xf3, 0x87, 0x96, 0x0c, 0xe0, 0x00, 0xf3, 0x8f, 0x38, 0x00, 0x08, 0x73, 0x83, 0xce, + 0x1e, 0x58, 0x00, 0xc7, 0xbe, 0x58, 0x00, 0x30, 0x5b, 0x61, 0x76, 0x70, 0x0b, 0xc5, 0x83, 0x8c, + 0x60, 0xe3, 0x7a, 0xf6, 0xee, 0x5e, 0xfb, 0xb9, 0x6c, 0xbe, 0xc5, 0x6e, 0x2b, 0x99, 0x30, 0xd1, + 0x20, 0x21, 0x6c, 0xc8, 0x0a, 0x55, 0x7f, 0x7f, 0xfd, 0x61, 0x36, 0x20, 0x00, 0x77, 0x53, 0x10, + 0x9f, 0xca, 0x34, 0xbf, 0xba, 0xfc, 0x5e, 0x2e, 0xe5, 0xe9, 0xb7, 0xc3, 0x71, 0xa0, 0x04, 0x23, + 0xc3, 0xe8, 0xc2, 0xa4, 0x7f, 0xca, 0x78, 0x2d, 0xe8, 0xac, 0x8d, 0xc6, 0xe8, 0xbb, 0xc6, 0x3f, + 0xbe, 0x16, 0xdb, 0xe1, 0x79, 0x00, 0x31, 0xbc, 0x51, 0x2d, 0xbf, 0xdb, 0x7e, 0xd9, 0xfb, 0x63, + 0x58, 0x90, 0x0b, 0xa5, 0x8d, 0x90, 0xd3, 0x25, 0xc2, 0x6e, 0x00, 0x71, 0x62, 0xdf, 0xc1, 0x25, + 0xbd, 0x6b, 0xff, 0x86, 0x48, 0x40, 0x06, 0xc9, 0x36, 0x01, 0x38, 0x7c, 0xf5, 0x55, 0x5f, 0x55, + 0x55, 0xc8, 0xaf, 0x0d, 0x60, 0x5c, 0xeb, 0xfd, 0xfe, 0xfd, 0x6f, 0x79, 0x17, 0x90, 0xd6, 0x03, + 0x4b, 0x09, 0x49, 0x67, 0xff, 0xaa, 0xaa, 0xdf, 0x0d, 0x38, 0x07, 0xb0, 0x58, 0x7a, 0x8d, 0x2f, + 0xbd, 0xf5, 0xcb, 0x2e, 0x18, 0x65, 0x00, 0x78, 0x77, 0xf1, 0xeb, 0x64, 0xd3, 0x4d, 0x34, 0xd3, + 0x4e, 0x9a, 0x69, 0xa6, 0x9a, 0x69, 0xa6, 0x8e, 0xe3, 0x88, 0x28, 0x22, 0xfe, 0x8f, 0x8a, 0x21, + 0x43, 0xe9, 0x31, 0x0b, 0xce, 0x00, 0xbc, 0x69, 0x81, 0x91, 0x2a, 0xff, 0xa1, 0xd0, 0xfc, 0xcd, + 0x86, 0x98, 0x80, 0x26, 0xf8, 0x6f, 0x2f, 0xff, 0xdb, 0x6e, 0x73, 0x0d, 0x4a, 0x12, 0x93, 0x2a, + 0xd5, 0xe9, 0xa7, 0xff, 0xe3, 0xe1, 0x52, 0x40, 0x69, 0x61, 0x50, 0x9c, 0xf5, 0xaa, 0xfd, 0x6b, + 0x09, 0xe0, 0x72, 0x40, 0x90, 0x2d, 0x6b, 0x55, 0x5e, 0xbe, 0x13, 0x62, 0x40, 0x24, 0x12, 0xf2, + 0x01, 0x8f, 0xdb, 0xeb, 0x55, 0xae, 0xb5, 0x86, 0x90, 0xa0, 0x41, 0x41, 0xfc, 0xff, 0x5f, 0xe3, + 0x1b, 0x0d, 0xe0, 0x06, 0x44, 0x88, 0x3f, 0xae, 0x7f, 0x1e, 0xdd, 0x6e, 0xf7, 0xb8, 0xad, 0xc9, + 0xc7, 0xba, 0x41, 0xdc, 0x41, 0xd2, 0xe7, 0xf8, 0x77, 0xe2, 0x8a, 0xc7, 0xc3, 0x78, 0x02, 0x49, + 0x21, 0x14, 0x59, 0x7b, 0x30, 0xa7, 0xf5, 0x09, 0xfc, 0x1f, 0xc1, 0xfd, 0xde, 0xbe, 0xa7, 0x0b, + 0x70, 0x48, 0xe0, 0xe7, 0x9d, 0xe0, 0xff, 0x9c, 0x7c, 0x61, 0x41, 0x29, 0x45, 0x95, 0x37, 0x1d, + 0x5c, 0xb5, 0xfc, 0x3d, 0x20, 0x01, 0x51, 0x25, 0xc0, 0xce, 0x32, 0x3b, 0xbf, 0xdb, 0xf8, 0xbb, + 0x8a, 0x62, 0xd8, 0xb6, 0x98, 0xb6, 0x0d, 0x36, 0x47, 0xb6, 0xdf, 0xc3, 0x98, 0x01, 0x88, 0x47, + 0x9f, 0x4a, 0x2e, 0xbf, 0xdb, 0x1e, 0xc1, 0x62, 0xbb, 0x0f, 0xff, 0xb9, 0x2f, 0xdb, 0x6d, 0xb6, + 0xc4, 0x78, 0xfe, 0x0e, 0xdc, 0x55, 0xe9, 0xa7, 0x0f, 0x10, 0xa0, 0x02, 0xdf, 0x33, 0x11, 0x27, + 0x0a, 0x94, 0x0f, 0x36, 0xad, 0xf3, 0xf9, 0xf8, 0xf6, 0x1b, 0x12, 0xbb, 0x0c, 0x8b, 0x64, 0xa3, + 0x8a, 0x47, 0x0c, 0x22, 0x3b, 0x4c, 0x77, 0x0f, 0x4b, 0xf0, 0x1a, 0x00, 0x51, 0x1b, 0x69, 0x4d, + 0x75, 0x20, 0xc1, 0xe1, 0xf3, 0x50, 0x73, 0x47, 0xb8, 0x42, 0xc4, 0xac, 0xc6, 0x30, 0x4a, 0xaf, + 0x23, 0x88, 0x05, 0xe0, 0xc4, 0x12, 0x87, 0xb6, 0xda, 0x82, 0xd1, 0xfb, 0xf8, 0x67, 0x01, 0x77, + 0x38, 0x5d, 0xcd, 0x65, 0x61, 0x21, 0xdb, 0x7d, 0x26, 0x44, 0xef, 0x93, 0xbe, 0x5d, 0x06, 0xc0, + 0xbb, 0x29, 0xf0, 0x5e, 0xec, 0xf6, 0x29, 0x62, 0xf5, 0xe1, 0x6b, 0xdd, 0xc5, 0x01, 0x8a, 0xc5, + 0x01, 0x8a, 0xc0, 0xd3, 0x1a, 0xf1, 0x47, 0xf0, 0x8c, 0x04, 0xcc, 0x29, 0x13, 0xc3, 0x68, 0xa6, + 0x71, 0xed, 0x64, 0x5b, 0x28, 0xae, 0x8f, 0xd9, 0x07, 0x8b, 0x97, 0x88, 0x0f, 0x2f, 0xaa, 0x36, + 0xc4, 0xf7, 0x58, 0x70, 0x90, 0x02, 0xd5, 0xc2, 0xab, 0x56, 0x02, 0x7f, 0x36, 0xd8, 0x33, 0xa9, + 0xcf, 0x6c, 0xfe, 0x36, 0x76, 0xc7, 0x7f, 0x52, 0xf9, 0x2d, 0x88, 0xfc, 0xe9, 0xbe, 0x33, 0xa7, + 0x78, 0x79, 0x40, 0x18, 0x21, 0xaa, 0xdc, 0x81, 0xc9, 0xe6, 0xb8, 0xbc, 0x2a, 0x38, 0x93, 0xda, + 0x52, 0xdd, 0xba, 0xed, 0xb0, 0x77, 0xed, 0x9e, 0xf7, 0x70, 0xcc, 0x3f, 0x64, 0xf1, 0xa7, 0xf0, + 0xc9, 0x20, 0x04, 0x50, 0x1c, 0xba, 0xe1, 0x6f, 0xb3, 0xea, 0x2a, 0x2f, 0x37, 0xae, 0xb3, 0x77, + 0xdc, 0x6d, 0x30, 0xde, 0x00, 0xa7, 0x41, 0x52, 0x86, 0xac, 0xe3, 0x41, 0x90, 0x13, 0x84, 0x22, + 0xd9, 0x61, 0xb8, 0xa1, 0x89, 0xc0, 0xb6, 0x29, 0x88, 0x18, 0x38, 0xbe, 0x2e, 0x2c, 0x91, 0x3a, + 0x23, 0xc2, 0xfe, 0x1a, 0xc0, 0x0d, 0x66, 0x03, 0x04, 0x9d, 0x24, 0x40, 0xe0, 0xe7, 0xbd, 0xee, + 0x17, 0x70, 0xea, 0xea, 0x58, 0x1e, 0x30, 0x53, 0x83, 0xc1, 0x80, 0x90, 0xd3, 0x0f, 0x33, 0x00, + 0x5e, 0x4d, 0x80, 0x6d, 0xe2, 0xcb, 0xef, 0xe5, 0xf2, 0xfe, 0xee, 0x0c, 0xc0, 0xd2, 0xb7, 0xfc, + 0x3c, 0x48, 0x00, 0x5b, 0x64, 0x1b, 0x48, 0x18, 0xb1, 0x73, 0xf1, 0x2c, 0xce, 0x7f, 0x10, 0x78, + 0x8f, 0x1e, 0x5c, 0xb5, 0xa6, 0xfe, 0x71, 0xe7, 0x1e, 0x71, 0xe7, 0x1e, 0x71, 0xe1, 0xb8, 0x90, + 0x23, 0x6e, 0xda, 0xfc, 0x35, 0x81, 0x0d, 0xa7, 0x81, 0xd7, 0x57, 0xef, 0x7f, 0xbd, 0xcd, 0x1d, + 0xc3, 0x58, 0x0c, 0x83, 0x8d, 0x18, 0x72, 0x95, 0x7b, 0xf1, 0x78, 0xba, 0xd5, 0xdd, 0x6a, 0x8e, + 0xe1, 0x7c, 0x0b, 0x26, 0x05, 0x4b, 0xef, 0xdf, 0xdf, 0xd8, 0x5f, 0x00, 0x3a, 0x0e, 0xc8, 0x3a, + 0x87, 0x33, 0x5b, 0xa2, 0xf1, 0x74, 0xf4, 0xd3, 0x8a, 0x6a, 0x24, 0xc0, 0x9d, 0xd1, 0x98, 0xcc, + 0x8a, 0x10, 0xdb, 0x28, 0x00, 0x92, 0x22, 0x87, 0xc9, 0x46, 0x2c, 0x2d, 0xe6, 0x4e, 0x9b, 0xfb, + 0x7b, 0xe0, 0xa7, 0x07, 0xb0, 0xbd, 0xc9, 0x24, 0x90, 0x92, 0x1f, 0x87, 0x94, 0x53, 0xa6, 0xfb, + 0x74, 0x7f, 0x67, 0xe9, 0x7f, 0xae, 0x17, 0x20, 0xb0, 0x54, 0x82, 0x4c, 0x55, 0x55, 0xf5, 0x55, + 0x5f, 0x1f, 0x1d, 0xc6, 0xa8, 0x23, 0xa6, 0x9f, 0xb4, 0xca, 0x16, 0x90, 0x20, 0x77, 0xd1, 0xa6, + 0xfa, 0xd3, 0x4d, 0xaf, 0xc2, 0xee, 0x0d, 0x14, 0xc9, 0xbf, 0xd7, 0xbf, 0x9b, 0xe3, 0x99, 0xc0, + 0x14, 0xd6, 0x88, 0x14, 0xee, 0x23, 0x8e, 0x15, 0x44, 0x00, 0x66, 0x7c, 0xe0, 0xef, 0x5e, 0x77, + 0x77, 0xff, 0xf8, 0x6b, 0x01, 0x60, 0xa1, 0x87, 0x55, 0x95, 0x1d, 0x97, 0x5a, 0xda, 0x36, 0x4d, + 0x75, 0x93, 0xa3, 0x8e, 0x16, 0x62, 0x00, 0x35, 0xb6, 0x08, 0x86, 0xfe, 0xbf, 0x5e, 0x39, 0xc0, + 0x6f, 0x1b, 0x1c, 0xac, 0x30, 0xce, 0x00, 0x68, 0x39, 0x92, 0x01, 0x9c, 0x4e, 0xbd, 0xfb, 0x6d, + 0xfb, 0xbb, 0x9f, 0x8e, 0xd8, 0x68, 0x86, 0x01, 0x5e, 0x83, 0x31, 0xc7, 0xed, 0xfe, 0x9f, 0x58, + 0x5e, 0x70, 0x0b, 0x78, 0x27, 0x0f, 0x2d, 0x7e, 0xaa, 0xab, 0xef, 0x84, 0xdc, 0x09, 0x3a, 0x21, + 0xbb, 0xd5, 0xf5, 0x7f, 0xa6, 0xa8, 0x69, 0xa1, 0xc2, 0xe8, 0x81, 0x4b, 0xab, 0xd5, 0x57, 0xae, + 0xba, 0x3b, 0xc0, 0x92, 0x0a, 0x42, 0x85, 0x71, 0x29, 0x07, 0x10, 0x34, 0xde, 0xdd, 0x6e, 0x6c, + 0x6c, 0xbf, 0x47, 0xe1, 0x79, 0x00, 0x1c, 0x5a, 0x87, 0x43, 0xdf, 0xd5, 0x13, 0xa2, 0x7f, 0x15, + 0xd8, 0x75, 0x40, 0x01, 0x26, 0x42, 0x59, 0x50, 0xaa, 0xb9, 0x68, 0x71, 0x9e, 0xb9, 0x2d, 0x18, + 0x7c, 0x5b, 0x14, 0x49, 0x17, 0xbd, 0xbb, 0x81, 0x33, 0x73, 0xfe, 0xbf, 0x80, 0x5c, 0x40, 0x60, + 0x85, 0x09, 0xdc, 0x55, 0x0a, 0xcb, 0x62, 0x80, 0x31, 0x58, 0x80, 0x1e, 0x0d, 0x20, 0x95, 0xbc, + 0x5c, 0x80, 0x09, 0x42, 0x6a, 0xd6, 0x73, 0xcf, 0x3d, 0x62, 0x81, 0xd1, 0x00, 0x1e, 0xe0, 0x36, + 0x00, 0x50, 0x05, 0x24, 0xc3, 0x83, 0x87, 0xf0, 0xf3, 0x98, 0x9f, 0xb6, 0x78, 0x1c, 0x3c, 0x03, + 0x87, 0x80, 0x01, 0x2c, 0x3c, 0x00, 0x09, 0x60, 0x80, 0xf9, 0x38, 0x0f, 0x2f, 0x1c, 0x00, 0x04, + 0x09, 0xe3, 0x9c, 0x3a, 0x42, 0x80, 0x46, 0xd9, 0x61, 0x05, 0x62, 0xbc, 0x93, 0xc6, 0xf0, 0x7f, + 0xee, 0x47, 0xfc, 0xbb, 0x1e, 0xf9, 0x76, 0x2b, 0x12, 0x78, 0xac, 0xff, 0xb2, 0xfa, 0xf0, 0x6c, + 0x87, 0x74, 0x42, 0xd9, 0x23, 0xf0, 0xe2, 0x80, 0x30, 0x39, 0x43, 0x9c, 0xea, 0xd6, 0x97, 0xf6, + 0xc7, 0x5f, 0xaf, 0x77, 0x6f, 0x74, 0xc4, 0x3f, 0x37, 0x27, 0x91, 0xa0, 0xa2, 0xac, 0xdd, 0xbf, + 0x87, 0x14, 0x07, 0x28, 0x28, 0xd9, 0xfd, 0xeb, 0x9a, 0x24, 0x8b, 0x7f, 0xd1, 0x2a, 0x24, 0xd5, + 0xd6, 0xb7, 0x3e, 0x35, 0xf8, 0x05, 0x80, 0x10, 0x05, 0x22, 0xb3, 0xc6, 0x83, 0x6b, 0x13, 0xa9, + 0x47, 0x10, 0x8e, 0x94, 0x43, 0x58, 0xc5, 0x10, 0x06, 0xa5, 0x89, 0x1e, 0x58, 0xce, 0x01, 0xe5, + 0x56, 0xb7, 0xc3, 0x84, 0x80, 0x10, 0x04, 0x5b, 0x55, 0x86, 0x4f, 0x6d, 0x57, 0x37, 0x96, 0x0a, + 0x73, 0x0d, 0xd7, 0x17, 0xb1, 0x1e, 0xde, 0x0c, 0xd2, 0x5d, 0xcd, 0x46, 0xff, 0xf0, 0x47, 0xc5, + 0x72, 0x02, 0xb8, 0x4e, 0x87, 0x74, 0x3d, 0x5a, 0xf2, 0xd9, 0xb3, 0x66, 0xcc, 0x67, 0x36, 0x2b, + 0x88, 0x7e, 0x02, 0x24, 0x10, 0x8c, 0x8a, 0x01, 0x88, 0x24, 0x10, 0xa1, 0x32, 0x38, 0xe3, 0xfb, + 0x30, 0xbb, 0x2c, 0x71, 0x96, 0xb2, 0x46, 0x85, 0xac, 0x5b, 0x14, 0x62, 0x1e, 0x70, 0x03, 0xe1, + 0xbc, 0x01, 0xb6, 0x44, 0x10, 0xc6, 0xa6, 0xcc, 0x2c, 0xe7, 0xfd, 0xad, 0x4f, 0x13, 0xb0, 0xa4, + 0x49, 0xc3, 0xee, 0x16, 0xe0, 0xa6, 0xc1, 0x61, 0xb3, 0x80, 0x77, 0x6a, 0x2b, 0xf8, 0x79, 0x40, + 0x29, 0xa3, 0x41, 0x16, 0x99, 0x41, 0x3e, 0xbf, 0x72, 0xf7, 0x72, 0xce, 0x29, 0xd6, 0x7e, 0xff, + 0x5c, 0x49, 0xed, 0x8e, 0xae, 0xf6, 0xdb, 0x6d, 0xbf, 0x86, 0x89, 0x00, 0x0c, 0x05, 0xb2, 0x46, + 0xf2, 0x03, 0xc1, 0x4e, 0x5e, 0x21, 0xf2, 0xe9, 0xba, 0x9e, 0x3d, 0xdc, 0x74, 0xf9, 0xff, 0xa9, + 0x3e, 0x44, 0xc3, 0x6e, 0x00, 0x30, 0x62, 0x00, 0xd5, 0xf6, 0x95, 0xe1, 0x3a, 0x42, 0x07, 0xba, + 0x11, 0xfc, 0x49, 0x9c, 0x16, 0x0c, 0x9f, 0x81, 0x41, 0x9f, 0x84, 0x9e, 0xc2, 0x13, 0xe0, 0x36, + 0xf5, 0x54, 0x46, 0x13, 0xf0, 0xde, 0x00, 0x6b, 0x8c, 0x90, 0x05, 0xe7, 0x7e, 0x6d, 0x8b, 0xd4, + 0xbd, 0x6b, 0xcf, 0xc4, 0x60, 0xf8, 0x49, 0x3b, 0x82, 0x53, 0x83, 0xc6, 0x04, 0xa0, 0x74, 0x3c, + 0x18, 0x1c, 0x01, 0x80, 0x6b, 0x4c, 0x15, 0x45, 0xe9, 0x8b, 0x80, 0xcf, 0x23, 0xfa, 0x7e, 0x6f, + 0xc3, 0xcc, 0x40, 0x00, 0x72, 0xb2, 0x03, 0x30, 0xbe, 0xaf, 0x16, 0xe8, 0xa7, 0x75, 0xb7, 0x6c, + 0xfc, 0x75, 0xf1, 0xdf, 0x95, 0x7c, 0x16, 0xc5, 0x76, 0x24, 0x7b, 0xfc, 0xd6, 0xa0, 0x64, 0x31, + 0x07, 0xdc, 0xff, 0x3f, 0xf8, 0x66, 0x70, 0x1f, 0x02, 0x58, 0x40, 0x10, 0x6c, 0x76, 0xba, 0xcc, + 0xaa, 0xfa, 0xaa, 0xa8, 0x55, 0x47, 0x50, 0xd3, 0x20, 0x0e, 0xf3, 0x5a, 0xef, 0xff, 0xe3, 0xe5, + 0xc3, 0xd8, 0x0e, 0x88, 0x77, 0xe8, 0x5a, 0xbb, 0xab, 0xd6, 0x2f, 0x15, 0xdf, 0x3b, 0xd7, 0xf0, + 0x52, 0x0c, 0x01, 0x51, 0x53, 0x15, 0xad, 0xc4, 0x00, 0x3c, 0x56, 0x70, 0x0f, 0x73, 0x81, 0xf1, + 0x0f, 0x1f, 0x1c, 0x70, 0xbb, 0x80, 0x26, 0x79, 0xa4, 0x0a, 0x9d, 0x00, 0x31, 0x2f, 0x77, 0xb4, + 0x54, 0x42, 0x3d, 0xd1, 0x2c, 0xe3, 0xa2, 0x2f, 0x64, 0x05, 0x0d, 0x32, 0xc3, 0x27, 0x34, 0xb8, + 0x5d, 0x90, 0x06, 0x85, 0x90, 0x11, 0xc0, 0x2d, 0x6a, 0x8d, 0xbd, 0xf7, 0xbd, 0x32, 0xff, 0x77, + 0xd6, 0x17, 0x21, 0xc1, 0x1d, 0x83, 0x23, 0x34, 0xf4, 0xa4, 0xfa, 0x6e, 0x97, 0xbe, 0x2d, 0x89, + 0x04, 0x7c, 0x93, 0xf1, 0x36, 0x33, 0x04, 0xed, 0xcf, 0xb8, 0x76, 0xc5, 0x48, 0x1e, 0x70, 0x86, + 0x89, 0x04, 0x94, 0x0e, 0xd4, 0x54, 0x5c, 0x6f, 0xb4, 0xab, 0x5d, 0x68, 0xee, 0x13, 0x67, 0x0e, + 0xbd, 0x30, 0xd8, 0x2b, 0x61, 0x3f, 0x63, 0xb1, 0xfe, 0x10, 0x03, 0x80, 0x52, 0x20, 0xf0, 0x35, + 0x92, 0x60, 0x83, 0xc6, 0xb2, 0x4c, 0x2a, 0x95, 0x0b, 0x36, 0x5a, 0x85, 0xe2, 0x3c, 0x6b, 0x49, + 0x82, 0x3c, 0x6b, 0x49, 0x8f, 0xac, 0xe5, 0x5e, 0x96, 0x38, 0x00, 0x63, 0x00, 0x07, 0x0d, 0x33, + 0x09, 0x2c, 0x7f, 0xbd, 0xfe, 0x8e, 0xe1, 0xa2, 0x18, 0x19, 0x36, 0x7f, 0x6f, 0xff, 0xac, 0x2c, + 0xca, 0x01, 0x8a, 0x8d, 0x45, 0x9d, 0x3b, 0xdf, 0xa7, 0x77, 0x78, 0x59, 0xc0, 0x21, 0x42, 0x96, + 0xcf, 0x79, 0x53, 0x5d, 0xde, 0xb5, 0xbe, 0x78, 0x43, 0x58, 0x03, 0x78, 0xe9, 0xf3, 0x3d, 0xde, + 0xaa, 0xab, 0xea, 0xaa, 0xa7, 0x99, 0xc2, 0xe8, 0xe0, 0x1b, 0x98, 0x17, 0x4b, 0x3f, 0xfd, 0x59, + 0x2b, 0x21, 0xdb, 0x0b, 0xb2, 0x00, 0x2b, 0xa0, 0x75, 0x3f, 0x5d, 0x7a, 0xc9, 0xcb, 0xf4, 0xf0, + 0xf2, 0xab, 0x47, 0xec, 0x2e, 0xc8, 0x03, 0xe4, 0xe2, 0x5e, 0xab, 0x34, 0x3e, 0xb2, 0x4f, 0x35, + 0x85, 0xd9, 0x40, 0xb0, 0x4f, 0xce, 0x32, 0xd2, 0x9d, 0x8c, 0xec, 0x7d, 0x8c, 0xf0, 0x63, 0x7c, + 0x04, 0xd6, 0x13, 0x66, 0x0d, 0x8c, 0x31, 0x56, 0x5f, 0xff, 0xc3, 0xac, 0xe0, 0x16, 0x06, 0xc1, + 0x71, 0x2a, 0xfb, 0xbf, 0xfc, 0xd1, 0xfb, 0xdf, 0xe1, 0xc8, 0x80, 0x01, 0x92, 0x52, 0x1d, 0x66, + 0x53, 0x70, 0x52, 0x93, 0x0c, 0xf3, 0xdc, 0x94, 0xf5, 0x73, 0x5a, 0xee, 0xe6, 0xee, 0xee, 0xe5, + 0xe0, 0x7a, 0x74, 0x5d, 0x54, 0x53, 0xf8, 0x79, 0xc0, 0x66, 0x8f, 0x3d, 0x19, 0xbd, 0x7d, 0xad, + 0x5b, 0x06, 0xfd, 0xeb, 0x54, 0x4e, 0x48, 0x46, 0x08, 0x00, 0x6a, 0xaf, 0xf8, 0x06, 0xa4, 0x06, + 0x48, 0x52, 0x3a, 0x1f, 0x26, 0x05, 0x47, 0x5f, 0x76, 0x1e, 0x03, 0x82, 0x41, 0xc7, 0xed, 0x4b, + 0x94, 0xf0, 0x0e, 0x0e, 0x8b, 0x96, 0x00, 0x04, 0xa5, 0xe2, 0x98, 0x3c, 0xb8, 0xe9, 0x70, 0xf8, + 0x00, 0x08, 0x1b, 0xc7, 0xe1, 0xe2, 0x40, 0x65, 0x44, 0xb3, 0x2a, 0xf5, 0xfe, 0x6c, 0x5c, 0x57, + 0x2b, 0x17, 0x17, 0x15, 0x97, 0xbc, 0x53, 0x71, 0x43, 0x22, 0xfd, 0xfe, 0x1e, 0x50, 0x02, 0x45, + 0xf4, 0x3a, 0x16, 0x1d, 0xf7, 0xe7, 0x8a, 0xc5, 0xc5, 0x6a, 0x8a, 0x58, 0x5e, 0xf1, 0xb6, 0xea, + 0xbf, 0x0c, 0xb3, 0x80, 0x4f, 0xb3, 0x9e, 0x60, 0x62, 0xbb, 0xbf, 0xfe, 0x85, 0x2c, 0x72, 0xde, + 0x6e, 0xdb, 0x6e, 0xb1, 0x71, 0x58, 0xc5, 0x58, 0x6f, 0x00, 0x48, 0xae, 0x19, 0x52, 0x39, 0x53, + 0xd5, 0x9e, 0x0e, 0x7b, 0x0d, 0x6a, 0x2b, 0x3d, 0x83, 0x9e, 0xc1, 0x12, 0xeb, 0x12, 0x75, 0xfc, + 0x2e, 0xe0, 0x0a, 0xde, 0xb0, 0xf0, 0x6f, 0x3d, 0xfe, 0xb5, 0xea, 0xe3, 0x1a, 0xfa, 0xca, 0xe0, + 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5c, 0x2e, 0x30, 0x4a, 0x0c, 0x74, 0x11, 0x1f, 0x46, 0x75, + 0xe8, 0x26, 0xea, 0xe4, 0x13, 0x76, 0x21, 0x57, 0x09, 0xf4, 0x58, 0xa6, 0xe0, 0x8c, 0xab, 0x75, + 0x8a, 0xfa, 0xf5, 0x74, 0x4c, 0x5f, 0x59, 0x43, 0x5d, 0x5d, 0x5d, 0x5a, 0x11, 0xe8, 0xbd, 0x84, + 0x19, 0xed, 0xf5, 0xaf, 0x04, 0x30, 0x46, 0x21, 0x55, 0x63, 0xee, 0x03, 0x60, 0x40, 0x25, 0xaa, + 0xaf, 0x77, 0x32, 0x78, 0x43, 0xea, 0xd5, 0x82, 0x95, 0x1a, 0xfe, 0x06, 0x08, 0x23, 0xbd, 0xef, + 0x0d, 0xf5, 0x62, 0xba, 0xb4, 0x5f, 0x5a, 0xbe, 0xb5, 0x5d, 0x7a, 0xc3, 0x98, 0x10, 0x3a, 0xe4, + 0xf7, 0xf4, 0xf6, 0x9a, 0x45, 0x2c, 0x9a, 0x07, 0x53, 0x00, 0xc6, 0xca, 0x68, 0x3e, 0x7f, 0x80, + 0x4e, 0x41, 0x00, 0x22, 0xbb, 0xec, 0x61, 0xa9, 0x0a, 0x47, 0xfd, 0xb6, 0xff, 0x3a, 0x54, 0x09, + 0x31, 0x75, 0x5f, 0x8e, 0xd5, 0x80, 0x60, 0x00, 0xf2, 0x09, 0xfc, 0xd8, 0x94, 0x58, 0x20, 0x63, + 0xf0, 0xf2, 0x28, 0x4f, 0x93, 0x7d, 0xbf, 0x7f, 0xd5, 0xaf, 0xfe, 0xaf, 0xf5, 0x79, 0xfa, 0x2b, + 0xc2, 0x7d, 0x08, 0x9c, 0x84, 0xfa, 0xbe, 0x18, 0x47, 0x18, 0x2c, 0xb4, 0xd3, 0xff, 0xf4, 0x8a, + 0x14, 0xc0, 0x4b, 0xb9, 0xbf, 0x3f, 0x4d, 0x3f, 0xf8, 0x69, 0x13, 0xff, 0x6f, 0xbf, 0xd8, 0x61, + 0x43, 0xcc, 0x27, 0xff, 0x7f, 0xc1, 0x0d, 0x86, 0x14, 0x3c, 0x99, 0xff, 0x77, 0xff, 0xc1, 0x97, + 0x82, 0x48, 0xb8, 0xb9, 0x30, 0xbc, 0x76, 0x65, 0x0d, 0x12, 0x1f, 0x52, 0x7f, 0xfe, 0xfe, 0x27, + 0xfa, 0xf5, 0x75, 0x7a, 0xea, 0xf3, 0x75, 0x7a, 0xeb, 0x55, 0xc1, 0x15, 0xdd, 0xf5, 0xf5, 0x62, + 0x33, 0xad, 0x42, 0x3d, 0x58, 0xa0, 0xc1, 0x22, 0x7f, 0xfd, 0x34, 0xf4, 0xf4, 0xcc, 0x39, 0x8c, + 0x51, 0xb5, 0xcf, 0x8c, 0x50, 0x6f, 0xcb, 0xfc, 0x09, 0x1c, 0x6c, 0xe0, 0xe2, 0x58, 0x82, 0x4f, + 0x03, 0xc0, 0x1a, 0x41, 0x39, 0x35, 0x5a, 0xd4, 0x71, 0x8f, 0xe0, 0x20, 0x03, 0x00, 0x84, 0xee, + 0xe2, 0xb7, 0x1a, 0xa3, 0x1c, 0x01, 0x0c, 0x51, 0xa8, 0xed, 0xf5, 0x72, 0xb8, 0x25, 0x3a, 0xae, + 0xab, 0x9d, 0x2f, 0xa1, 0x0f, 0x0a, 0xf5, 0xef, 0x98, 0x97, 0xbf, 0xaf, 0x47, 0x84, 0x51, 0xc0, + 0x71, 0xdf, 0x2c, 0x31, 0x4a, 0x7d, 0xb6, 0xd3, 0x4e, 0x31, 0x7f, 0xc3, 0x0a, 0x08, 0x5a, 0xb5, + 0x7f, 0xfb, 0x5f, 0xfe, 0x1c, 0x24, 0x03, 0xe7, 0xd4, 0x6d, 0xb7, 0xff, 0xb6, 0xda, 0x01, 0xbd, + 0x6d, 0xf8, 0x66, 0xa3, 0xab, 0x0e, 0x12, 0x01, 0xdb, 0x6e, 0xdb, 0xdb, 0xfe, 0xdd, 0xbc, 0x37, + 0x4a, 0x0b, 0x41, 0x8b, 0xec, 0xb9, 0x61, 0xe0, 0xb8, 0x8e, 0xff, 0x34, 0x7b, 0xeb, 0xdc, 0x14, + 0x04, 0x51, 0x5e, 0x4e, 0xad, 0xf5, 0xef, 0xa2, 0xb5, 0xf4, 0x67, 0xae, 0xaf, 0xf4, 0x56, 0xfa, + 0xbe, 0x31, 0x43, 0xde, 0x7f, 0xab, 0x7d, 0x5a, 0xba, 0xbc, 0x9d, 0x1b, 0xaf, 0xaf, 0x42, 0xc2, + 0x97, 0x80, 0x81, 0x04, 0x20, 0x9c, 0x54, 0xdf, 0x4c, 0x40, 0xe0, 0x3d, 0xf2, 0x50, 0x00, 0x54, + 0x40, 0x49, 0x10, 0x87, 0xc0, 0xc1, 0x13, 0x05, 0x00, 0x91, 0x33, 0x28, 0x06, 0x51, 0xfc, 0x1f, + 0x10, 0x35, 0x07, 0x4f, 0x8f, 0x34, 0x00, 0x6a, 0x0e, 0x23, 0xf0, 0xe2, 0x1a, 0x3e, 0x3c, 0x7f, + 0xff, 0xa7, 0x2f, 0x34, 0x3b, 0xf0, 0x24, 0x02, 0x4e, 0xab, 0x58, 0x71, 0x10, 0x00, 0x22, 0x3b, + 0xa9, 0x37, 0xa2, 0x3f, 0xe6, 0x87, 0xb3, 0x26, 0xe1, 0x49, 0x8e, 0x01, 0x0c, 0x75, 0xeb, 0x7b, + 0xf8, 0x26, 0x26, 0x2b, 0x6c, 0xe0, 0x01, 0xc7, 0xf3, 0xc0, 0x00, 0x9f, 0x5f, 0x46, 0x70, 0x0c, + 0x08, 0x60, 0xc2, 0x55, 0x70, 0xcf, 0x56, 0x9b, 0xad, 0x7d, 0x5f, 0xea, 0xd5, 0xcd, 0x77, 0x77, + 0x43, 0x16, 0x22, 0x90, 0xf3, 0xe5, 0xbb, 0xbb, 0xfa, 0xf4, 0xf8, 0x85, 0x1d, 0xb0, 0xf2, 0x8d, + 0x33, 0xed, 0x7f, 0xfe, 0x5d, 0x6d, 0xfc, 0x0c, 0x20, 0x84, 0x28, 0x14, 0x89, 0x3e, 0x0e, 0xae, + 0x71, 0xd2, 0x50, 0x15, 0x1c, 0x3f, 0x9c, 0x00, 0x04, 0x72, 0x27, 0xe6, 0xe3, 0x81, 0x7e, 0x58, + 0x00, 0x15, 0x8e, 0x17, 0xe5, 0x80, 0x01, 0x58, 0xe6, 0x30, 0x1e, 0x0e, 0x03, 0x20, 0x9a, 0xe0, + 0x00, 0x09, 0x29, 0x4a, 0xa1, 0xc7, 0x23, 0x59, 0xf2, 0x56, 0x83, 0xc7, 0xca, 0x21, 0xab, 0x38, + 0x39, 0x05, 0x06, 0x0a, 0xcb, 0xf8, 0x71, 0x40, 0x19, 0xb7, 0xbe, 0x12, 0xbf, 0xb6, 0xde, 0xdf, + 0xf9, 0xab, 0x52, 0xa6, 0x57, 0xa5, 0x15, 0xe6, 0xac, 0x34, 0x40, 0x80, 0x00, 0x1b, 0x98, 0x28, + 0x11, 0xad, 0xb1, 0x0c, 0x2e, 0xbd, 0xf3, 0xbd, 0x4e, 0x3f, 0x93, 0x93, 0x9c, 0x7b, 0x3a, 0x0f, + 0x81, 0x03, 0x05, 0x87, 0x0d, 0xb8, 0x03, 0x4a, 0x90, 0x0c, 0x5a, 0x82, 0x7c, 0xf4, 0xf9, 0xbf, + 0x3c, 0x58, 0xf9, 0xe0, 0x2c, 0x39, 0xe0, 0x0b, 0x17, 0xe7, 0xdf, 0x5a, 0xf0, 0x10, 0x01, 0x04, + 0x13, 0xa3, 0xb2, 0x75, 0xe8, 0x9e, 0xbd, 0x11, 0xd1, 0x3f, 0x7d, 0x15, 0xeb, 0xaf, 0x7d, 0x7a, + 0x4e, 0x0a, 0x05, 0x62, 0xb1, 0x46, 0x5c, 0x2e, 0x1c, 0x00, 0xe1, 0xc0, 0x00, 0xe4, 0x4c, 0xa1, + 0xe2, 0x10, 0x01, 0x9c, 0x0e, 0x51, 0x58, 0x89, 0x6b, 0x5f, 0xe9, 0x9b, 0x63, 0x8c, 0x5b, 0x16, + 0xd3, 0x4c, 0xa8, 0x37, 0x5f, 0xdb, 0x6e, 0x1a, 0x90, 0x01, 0x6a, 0x86, 0x29, 0x18, 0x8a, 0xf6, + 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb1, 0x6d, 0x34, 0xd3, 0x4d, 0x34, 0xd3, 0xf6, 0x1e, 0x90, 0x00, + 0x0c, 0xf5, 0xdc, 0x94, 0x2a, 0x41, 0x0b, 0x2e, 0x7e, 0x6d, 0xbb, 0x4d, 0xb6, 0x0d, 0xca, 0x35, + 0x0a, 0x0c, 0x9d, 0x9d, 0x9c, 0xef, 0x1e, 0xbb, 0x3c, 0xc8, 0x1f, 0x37, 0xfa, 0x70, 0xe2, 0x80, + 0x07, 0xfb, 0xc0, 0x96, 0x6c, 0x0d, 0x3c, 0x37, 0x7f, 0x62, 0xd5, 0x80, 0x70, 0xe8, 0xb9, 0x40, + 0x29, 0x2c, 0x61, 0x15, 0xc3, 0xaf, 0xae, 0xb6, 0xdb, 0x3a, 0x44, 0xf4, 0x4f, 0x76, 0xdb, 0xe1, + 0xe2, 0x40, 0x00, 0xf2, 0x22, 0x61, 0x39, 0x16, 0x8a, 0x43, 0xff, 0xc8, 0x51, 0x62, 0x8b, 0x1c, + 0xfd, 0x95, 0x14, 0x58, 0xa2, 0xf6, 0xcf, 0x1a, 0x2d, 0x52, 0xc1, 0x67, 0x0e, 0xbf, 0x2b, 0x28, + 0xea, 0xb7, 0xcd, 0xfb, 0x69, 0xa7, 0x0a, 0x28, 0x00, 0xd6, 0x40, 0x77, 0xb2, 0x02, 0xa4, 0x61, + 0xbb, 0x5e, 0x9d, 0xb6, 0xf7, 0xe0, 0x35, 0xd6, 0xd9, 0xee, 0x9e, 0x3b, 0x0e, 0x22, 0x80, 0x24, + 0x01, 0xba, 0x1d, 0x42, 0x56, 0x93, 0x4f, 0x4d, 0x36, 0xdb, 0xff, 0x11, 0x49, 0xf4, 0xd3, 0xe1, + 0x8c, 0x01, 0x20, 0x2b, 0x2b, 0x9c, 0x09, 0x5a, 0xf6, 0xdb, 0xff, 0x6d, 0xb3, 0x32, 0x28, 0x5c, + 0x82, 0x40, 0x05, 0xc8, 0xb9, 0xe2, 0x52, 0x15, 0xc5, 0xfe, 0x9a, 0x65, 0xed, 0xfe, 0xd2, 0x74, + 0x27, 0xae, 0x03, 0x07, 0x86, 0xc8, 0x14, 0x00, 0xd3, 0xc8, 0xfb, 0x7d, 0xef, 0xf7, 0xbe, 0x93, + 0x7b, 0xfc, 0x26, 0x48, 0x48, 0xa8, 0x19, 0x6b, 0x93, 0x18, 0xb3, 0xac, 0x5f, 0x9d, 0x62, 0xce, + 0xb0, 0xa7, 0x0f, 0xf8, 0x02, 0x40, 0x06, 0x20, 0x88, 0x2a, 0xef, 0xd6, 0x1b, 0x63, 0x80, 0x03, + 0x66, 0x65, 0x20, 0x47, 0x1e, 0x58, 0x21, 0x1d, 0x7e, 0x4e, 0x4f, 0xe2, 0x3c, 0xef, 0x10, 0x78, + 0xf5, 0xc5, 0x30, 0x75, 0x7a, 0xde, 0xf0, 0xf6, 0x00, 0x50, 0x99, 0x9a, 0x81, 0xbb, 0x09, 0x4b, + 0xde, 0x55, 0xe1, 0x5f, 0xee, 0xee, 0xa7, 0xbd, 0x4f, 0x78, 0x38, 0xf0, 0x6d, 0xbd, 0xfe, 0x1b, + 0x64, 0x0d, 0x5e, 0x3a, 0xf7, 0xc5, 0x7f, 0x2d, 0xcb, 0x7f, 0xef, 0xef, 0xc0, 0xf1, 0x41, 0x3e, + 0x97, 0xaf, 0x57, 0x5e, 0xbe, 0xbd, 0x5d, 0x7a, 0x37, 0xa2, 0xbc, 0xb0, 0x38, 0x04, 0x01, 0x60, + 0x87, 0x15, 0xdd, 0x6b, 0x8a, 0x37, 0x14, 0x68, 0x8d, 0xc0, 0xf0, 0x00, 0xa0, 0x46, 0x9a, 0xdb, + 0xb6, 0x58, 0x65, 0xe2, 0xfc, 0x56, 0x2b, 0xb8, 0xa3, 0x14, 0x06, 0x1a, 0x20, 0x03, 0xc3, 0x8c, + 0x06, 0xac, 0xdd, 0x5e, 0xef, 0x0d, 0x48, 0x00, 0x11, 0x07, 0x30, 0x92, 0x37, 0x52, 0xb0, 0xc1, + 0xbf, 0xfa, 0x62, 0xde, 0x0f, 0xb8, 0x4c, 0x12, 0x51, 0xd9, 0x1c, 0x34, 0x48, 0x01, 0xa8, 0x58, + 0xa8, 0x0b, 0x9a, 0xc1, 0x0f, 0xcd, 0xb6, 0xdb, 0x6d, 0xb6, 0xc1, 0x08, 0xab, 0x63, 0x9f, 0xf4, + 0xa1, 0x5b, 0xe8, 0xd3, 0x6f, 0xf8, 0x20, 0x70, 0xf1, 0x20, 0x17, 0x83, 0x3e, 0x6a, 0x70, 0x51, + 0x9d, 0x2b, 0xaf, 0x3f, 0x7f, 0x7b, 0xdd, 0xcf, 0xdf, 0xdf, 0xdf, 0xc3, 0x5d, 0x1d, 0xdd, 0xff, + 0x09, 0x22, 0x81, 0x35, 0xa0, 0x29, 0xa1, 0xfc, 0xed, 0xb7, 0xf0, 0xd2, 0x28, 0x03, 0x41, 0x90, + 0x79, 0xab, 0x1f, 0xfe, 0xdb, 0x7b, 0x6d, 0x8f, 0x8c, 0x70, 0xc1, 0x05, 0x00, 0x04, 0xed, 0x98, + 0x2f, 0x0a, 0x82, 0xf1, 0x86, 0x99, 0xa3, 0xff, 0x8e, 0x5f, 0x6f, 0x1d, 0xe1, 0xef, 0xfe, 0x5f, + 0xbe, 0x1a, 0x70, 0x01, 0x49, 0x0e, 0x16, 0xa4, 0x1c, 0x91, 0x45, 0x6f, 0xf7, 0x77, 0x76, 0xdb, + 0x3f, 0x7f, 0x34, 0xaa, 0x39, 0x40, 0x16, 0xf4, 0x63, 0x12, 0x28, 0x8b, 0xb0, 0xd2, 0x28, 0x02, + 0x07, 0xe4, 0x1f, 0x0c, 0x13, 0xff, 0x6d, 0xb6, 0xdb, 0x6d, 0xb8, 0x8d, 0xa8, 0xb9, 0xc0, 0x0c, + 0x13, 0x75, 0x01, 0xd2, 0xe0, 0xda, 0x89, 0x69, 0xf4, 0x27, 0xbe, 0xbd, 0xc0, 0x5c, 0xd7, 0x8f, + 0xc7, 0x2c, 0x76, 0xc3, 0x6c, 0x2c, 0x04, 0x41, 0x50, 0x0e, 0x59, 0x44, 0xa5, 0x86, 0x8a, 0xa7, + 0x2c, 0x0b, 0x9c, 0xb1, 0x7b, 0xec, 0xfd, 0x6b, 0x09, 0xe0, 0x06, 0x6e, 0x82, 0x4c, 0x3b, 0x5b, + 0xaf, 0x7a, 0x21, 0x2c, 0x37, 0x51, 0x37, 0xac, 0x27, 0xc2, 0xf8, 0x70, 0x20, 0x84, 0x10, 0x64, + 0x7c, 0x77, 0x80, 0x20, 0x90, 0x16, 0x21, 0x40, 0xb2, 0x89, 0x3d, 0x64, 0x53, 0xa8, 0x50, 0x14, + 0x54, 0x00, 0x0a, 0x8c, 0x83, 0x90, 0x28, 0x3f, 0xe2, 0xe5, 0x02, 0x55, 0x38, 0x00, 0x0a, 0xb0, + 0x2e, 0x03, 0x13, 0x0a, 0x20, 0x03, 0xa3, 0x20, 0xc4, 0x1d, 0x86, 0x88, 0x50, 0x08, 0xe5, 0x8c, + 0xa1, 0x39, 0x1e, 0xb9, 0xfd, 0x69, 0xf5, 0x2c, 0x71, 0x41, 0xd2, 0xba, 0x17, 0x14, 0x1b, 0x8a, + 0x03, 0xfe, 0x17, 0x90, 0x15, 0x92, 0x15, 0xff, 0xff, 0xeb, 0xe8, 0x7f, 0x47, 0xf4, 0x7e, 0x90, + 0x5c, 0x23, 0x1c, 0x00, 0x0b, 0xc7, 0x00, 0xf0, 0x70, 0x06, 0x10, 0x46, 0x39, 0xdf, 0x1c, 0x6c, + 0x24, 0x48, 0xcc, 0xa2, 0x83, 0xa7, 0xfc, 0x09, 0x01, 0x15, 0xe9, 0x60, 0x20, 0x04, 0x82, 0xc1, + 0x4a, 0xbd, 0xdc, 0x56, 0x2b, 0x10, 0x38, 0x28, 0xcb, 0x07, 0xc5, 0xd8, 0x68, 0x84, 0x00, 0x84, + 0x64, 0x12, 0x1e, 0xbe, 0x6f, 0xfd, 0xb6, 0xed, 0xb6, 0x2a, 0xc7, 0x18, 0xda, 0x86, 0xb0, 0x05, + 0x1c, 0x80, 0x42, 0xc8, 0xf9, 0x9e, 0x9a, 0x7b, 0x6d, 0xb6, 0xd8, 0xab, 0x15, 0x78, 0xbc, 0x00, + 0x30, 0xbb, 0x20, 0x01, 0x00, 0xb2, 0x0d, 0x30, 0x14, 0xfe, 0x37, 0x6e, 0x4d, 0x3f, 0x25, 0x70, + 0x2a, 0xca, 0x23, 0xc3, 0x6d, 0xf3, 0x81, 0x84, 0x40, 0x30, 0x47, 0xb0, 0xd3, 0x80, 0x11, 0xb6, + 0x8f, 0x64, 0x01, 0x38, 0x2d, 0x84, 0x11, 0xff, 0xc2, 0xea, 0xc5, 0xa6, 0x16, 0xdc, 0xa8, 0xca, + 0x5d, 0x8b, 0x61, 0xd1, 0xc5, 0x4f, 0x1b, 0x3b, 0x3b, 0x3b, 0x3b, 0x39, 0xde, 0xce, 0x3d, 0x7a, + 0x38, 0xe1, 0x79, 0x40, 0x13, 0xfc, 0xc3, 0x69, 0x5f, 0xbd, 0xb6, 0xff, 0xd3, 0x4e, 0x53, 0x4d, + 0x34, 0xd3, 0x34, 0x77, 0x0c, 0x32, 0x80, 0xdc, 0x86, 0xbf, 0xa6, 0x9b, 0x6d, 0xb6, 0xdb, 0x6d, + 0xb6, 0xdb, 0xe3, 0x9c, 0x0b, 0x95, 0x21, 0x3e, 0x31, 0xc0, 0x58, 0xf0, 0x1e, 0x86, 0x61, 0xa4, + 0x28, 0x01, 0x30, 0xd5, 0x01, 0x8a, 0xd9, 0x4b, 0xd6, 0xfe, 0xb5, 0xbd, 0xe2, 0xc4, 0x6c, 0x2e, + 0x48, 0x18, 0x23, 0x4d, 0x8f, 0x7e, 0xee, 0xef, 0xe5, 0x86, 0xe2, 0xc7, 0xa2, 0x81, 0x53, 0x77, + 0x03, 0x54, 0x30, 0x2b, 0x6d, 0xbf, 0x85, 0xc8, 0x50, 0x20, 0x52, 0x1a, 0x15, 0x3c, 0xbd, 0xfd, + 0xdd, 0xdf, 0xc6, 0xb2, 0xfc, 0x48, 0xb7, 0x7d, 0xdf, 0x20, 0x60, 0x93, 0x10, 0x7f, 0xf4, 0xd3, + 0xd3, 0x4c, 0xa8, 0x9c, 0x07, 0x4c, 0x12, 0x12, 0x9a, 0x99, 0x91, 0xdd, 0x86, 0xd8, 0x48, 0x00, + 0xa5, 0x40, 0x7e, 0x22, 0x87, 0x12, 0xbc, 0xa3, 0xbc, 0x05, 0xcb, 0x4b, 0xea, 0x0d, 0x6b, 0x90, + 0x8a, 0x8a, 0xb9, 0x0a, 0xd8, 0x4f, 0x25, 0xef, 0x5a, 0xe1, 0x3c, 0x10, 0x27, 0x9c, 0xf1, 0x1c, + 0xb9, 0x73, 0xef, 0xe6, 0x7c, 0x76, 0xe3, 0xfe, 0x00, 0x80, 0x20, 0x9c, 0x2e, 0xee, 0xef, 0x49, + 0xcb, 0xc1, 0x78, 0xee, 0x17, 0x61, 0x60, 0x01, 0x9c, 0x62, 0xc0, 0x46, 0x42, 0x38, 0x0a, 0xff, + 0x5e, 0xb2, 0x2a, 0xa7, 0x1f, 0xc2, 0xa6, 0xe1, 0xc3, 0x02, 0x88, 0xae, 0x1c, 0x0c, 0x3d, 0x9c, + 0x10, 0x84, 0x02, 0x87, 0x0b, 0x1a, 0x16, 0xcb, 0xb1, 0x00, 0xb0, 0x4c, 0x1c, 0x42, 0xf5, 0x8e, + 0x8b, 0x83, 0x27, 0x42, 0xc0, 0x06, 0x1e, 0x43, 0xa1, 0x60, 0x00, 0xc4, 0xbc, 0x58, 0x6e, 0x3c, + 0x7b, 0xfb, 0x61, 0x76, 0x40, 0x86, 0xc9, 0xf2, 0xb9, 0xfc, 0xe7, 0xfd, 0x2f, 0x41, 0x17, 0x8d, + 0xea, 0xf5, 0xd7, 0xa8, 0x5e, 0x08, 0x40, 0xc1, 0xee, 0x43, 0xb1, 0xb5, 0x1c, 0x8a, 0x09, 0xbf, + 0x57, 0x0e, 0xfc, 0x72, 0x28, 0x03, 0xdf, 0x3f, 0xaa, 0x48, 0xa1, 0x1c, 0x31, 0xe0, 0x12, 0x02, + 0xd3, 0x4d, 0x34, 0xfe, 0x2e, 0x40, 0x46, 0x67, 0x3d, 0x63, 0xb4, 0x90, 0x34, 0x49, 0x3e, 0x3f, + 0x38, 0xe2, 0x08, 0x03, 0x0f, 0x90, 0x5e, 0x3a, 0x8c, 0x71, 0x6c, 0x82, 0x2a, 0xae, 0xc7, 0x12, + 0x10, 0x16, 0x60, 0xde, 0x61, 0xa2, 0x18, 0x02, 0xc2, 0xba, 0x8d, 0xf5, 0xaf, 0xd6, 0x6e, 0xf8, + 0x5c, 0x85, 0x00, 0xe1, 0xe1, 0xb4, 0x09, 0xac, 0x4d, 0x34, 0xd3, 0xbd, 0xd3, 0x4c, 0x9f, 0xdd, + 0xee, 0x8e, 0xe3, 0x91, 0x44, 0x0d, 0x1f, 0x0c, 0x38, 0x03, 0xde, 0xea, 0xe5, 0xff, 0xb6, 0xde, + 0xdb, 0x6f, 0x86, 0x88, 0x50, 0x01, 0x74, 0x3b, 0x7c, 0xc8, 0xeb, 0x85, 0xff, 0xb6, 0xdc, 0xfd, + 0xb1, 0xdf, 0xbb, 0x0f, 0x10, 0x70, 0x00, 0xd4, 0x1c, 0x6b, 0x21, 0x80, 0xe9, 0xc1, 0x2d, 0x65, + 0xf0, 0x77, 0xed, 0xd6, 0x0e, 0xfc, 0x71, 0xf9, 0x6b, 0xad, 0xb1, 0x56, 0x2a, 0xd0, 0xdd, 0x7f, + 0xb7, 0x0d, 0x12, 0x01, 0x23, 0x95, 0x00, 0x31, 0x89, 0xa7, 0xa6, 0x9f, 0xb7, 0xfe, 0xc2, 0xec, + 0xe0, 0x0f, 0x06, 0x60, 0xb4, 0xaa, 0x5f, 0xed, 0xb6, 0xdb, 0x6d, 0xb7, 0xf9, 0x8e, 0x24, 0x01, + 0xbe, 0x6c, 0xba, 0xdd, 0x51, 0xdf, 0xa1, 0xfd, 0xf5, 0xca, 0xa0, 0x71, 0x12, 0xa7, 0x4e, 0x07, + 0x91, 0x2a, 0x7b, 0x84, 0x04, 0x02, 0x70, 0x84, 0x5b, 0x8b, 0x71, 0x0f, 0x73, 0x9f, 0xcd, 0x84, + 0xd9, 0x80, 0x25, 0x54, 0x43, 0x0a, 0xa7, 0x9d, 0x90, 0x15, 0x9d, 0x87, 0x79, 0x63, 0x1e, 0x50, + 0x2c, 0x18, 0xf1, 0x41, 0xf0, 0x9e, 0xc1, 0xe1, 0x7c, 0x00, 0x80, 0xe8, 0xc7, 0x7c, 0x21, 0xea, + 0xf6, 0xe2, 0xbf, 0x8a, 0x38, 0x91, 0x86, 0xb7, 0xe0, 0x51, 0x06, 0x00, 0x9c, 0x33, 0x7b, 0xdd, + 0xc5, 0x77, 0xc2, 0xec, 0x30, 0x02, 0x59, 0x07, 0x19, 0xc1, 0x53, 0x4c, 0x77, 0xd9, 0xc7, 0x96, + 0xfc, 0xb0, 0x31, 0x2c, 0x02, 0x80, 0x1c, 0x16, 0x39, 0x5f, 0x06, 0x35, 0xc1, 0xd5, 0x85, 0xe7, + 0x01, 0x03, 0x30, 0xf2, 0x38, 0x15, 0xba, 0xf2, 0x9a, 0x67, 0x2c, 0x79, 0xa0, 0x78, 0xc2, 0x78, + 0xc3, 0x57, 0x52, 0x48, 0x70, 0x72, 0x04, 0x81, 0x24, 0x48, 0x9c, 0xb7, 0x21, 0x51, 0xab, 0x7e, + 0x93, 0x97, 0xa0, 0xab, 0xc7, 0xf5, 0x6a, 0x17, 0x28, 0x64, 0x00, 0x1e, 0x1c, 0x6c, 0x5c, 0x80, + 0x58, 0x74, 0x90, 0xda, 0x70, 0x1e, 0x00, 0x78, 0x04, 0xa6, 0x4d, 0xd3, 0x8a, 0xc5, 0x6e, 0xe4, + 0xc7, 0x08, 0x03, 0x90, 0x51, 0x5a, 0xdd, 0xc5, 0x62, 0xb7, 0xe0, 0x48, 0x0c, 0x02, 0xba, 0xd6, + 0x2e, 0x2f, 0xde, 0x2b, 0x91, 0xac, 0xa1, 0x29, 0x01, 0x30, 0x0d, 0x25, 0x34, 0x8b, 0x7f, 0xa6, + 0x9c, 0x35, 0x20, 0x02, 0x47, 0x90, 0xee, 0xaf, 0x3f, 0xfe, 0xdd, 0xb8, 0x8b, 0x30, 0xf2, 0x80, + 0x0c, 0x04, 0x75, 0x6e, 0x20, 0xeb, 0x72, 0xfb, 0x77, 0xf7, 0x73, 0xf7, 0xfc, 0x1c, 0x7e, 0x0e, + 0x03, 0x7f, 0x33, 0xfd, 0x3c, 0x35, 0x10, 0x00, 0x1f, 0x64, 0x40, 0x1f, 0xae, 0x60, 0xc7, 0xbd, + 0x8d, 0x7d, 0xff, 0x70, 0x71, 0xf8, 0xe0, 0xde, 0x7e, 0x0e, 0xfc, 0xa8, 0xea, 0x55, 0xd5, 0x2b, + 0x86, 0x11, 0x00, 0x14, 0x29, 0xd7, 0xe4, 0xc3, 0x02, 0x74, 0xed, 0xff, 0x12, 0xf9, 0xd4, 0x77, + 0x28, 0xae, 0xc5, 0x98, 0x7b, 0x74, 0xe1, 0xd8, 0xcb, 0xb2, 0x60, 0x18, 0x91, 0x64, 0x07, 0x4e, + 0x77, 0x4e, 0xee, 0x4e, 0xa1, 0xc2, 0x40, 0x04, 0x4b, 0x21, 0x5b, 0x8a, 0xa5, 0x35, 0xfb, 0xf0, + 0xb0, 0xcb, 0x26, 0x65, 0xd6, 0x16, 0x7b, 0xc9, 0x03, 0x2c, 0xb0, 0xbf, 0xdf, 0xd3, 0xc3, 0x18, + 0x03, 0x0e, 0xf9, 0xcf, 0x5f, 0xe6, 0xaa, 0x5a, 0xa9, 0x7a, 0xa9, 0x6a, 0xa5, 0x95, 0x79, 0x65, + 0x45, 0xcb, 0xf2, 0xa2, 0xe5, 0x85, 0xd5, 0xe1, 0xf9, 0xd8, 0x71, 0x40, 0x02, 0x00, 0x03, 0x88, + 0x2a, 0x21, 0x30, 0x58, 0xd7, 0x15, 0x35, 0x82, 0xf4, 0x6f, 0x61, 0x10, 0x80, 0xfe, 0xc1, 0xbe, + 0x1c, 0x1f, 0xd7, 0x80, 0x0f, 0xa4, 0x38, 0x0d, 0xe4, 0x48, 0xa5, 0x91, 0x13, 0x4b, 0xf2, 0x22, + 0x69, 0x61, 0xe2, 0x69, 0x7f, 0xef, 0xb6, 0xdf, 0x0c, 0x4a, 0x00, 0x6d, 0xb0, 0x17, 0xab, 0x4e, + 0x60, 0x04, 0x58, 0x65, 0x9b, 0xc7, 0xfc, 0x7f, 0xcf, 0x3a, 0x39, 0xf9, 0x65, 0x9e, 0x07, 0x4f, + 0x00, 0xec, 0x71, 0xa6, 0x9f, 0xd0, 0x36, 0xa1, 0xc4, 0x70, 0x01, 0xbe, 0xc1, 0x7a, 0xa6, 0x0d, + 0xa6, 0x1b, 0xb4, 0x5c, 0x26, 0xb3, 0x4e, 0xea, 0x62, 0xd9, 0xdd, 0x38, 0xea, 0x71, 0xa6, 0x9c, + 0x71, 0xa6, 0x9e, 0x56, 0xdb, 0xd3, 0x4f, 0xf0, 0x4a, 0x70, 0x71, 0x01, 0xe0, 0xe8, 0x1e, 0x55, + 0x62, 0x47, 0x1f, 0xa2, 0x65, 0xe8, 0x5e, 0xbe, 0xb1, 0x5e, 0x08, 0x0a, 0x55, 0x5f, 0x82, 0x0e, + 0x08, 0x00, 0xb2, 0x0a, 0x83, 0x15, 0x91, 0x81, 0x4d, 0xbc, 0xbd, 0xbd, 0x63, 0x88, 0x7f, 0x11, + 0x58, 0x5d, 0xc0, 0x66, 0x18, 0x29, 0x8a, 0x15, 0x97, 0xae, 0x11, 0x6c, 0x0f, 0xac, 0x7e, 0x28, + 0xce, 0xbc, 0xf0, 0x60, 0x53, 0x5c, 0x7d, 0xec, 0xf0, 0x42, 0x10, 0x20, 0x36, 0x74, 0x28, 0x09, + 0x68, 0xb6, 0x83, 0x8f, 0xec, 0x5d, 0x25, 0x20, 0xef, 0x80, 0x4a, 0x17, 0xce, 0xfc, 0x36, 0xc2, + 0xa1, 0x21, 0x22, 0x78, 0xff, 0xf9, 0xa1, 0x12, 0x61, 0xa3, 0xaf, 0xbd, 0xf0, 0x9c, 0x20, 0x01, + 0xca, 0x41, 0x14, 0x15, 0x52, 0x34, 0x70, 0xec, 0x1c, 0xd1, 0xa4, 0x28, 0x48, 0xf0, 0x34, 0x0b, + 0xdd, 0x02, 0x63, 0x70, 0x38, 0x18, 0xb8, 0xa4, 0x38, 0x12, 0xc2, 0x91, 0x79, 0x59, 0x5c, 0x17, + 0x2a, 0x55, 0xc8, 0x6d, 0x94, 0x87, 0xcd, 0x2c, 0x7c, 0x2f, 0x83, 0xfb, 0xe1, 0x6f, 0x87, 0xf5, + 0xad, 0x7e, 0x17, 0x64, 0x00, 0x6f, 0x5e, 0x85, 0x1e, 0x65, 0xb2, 0xfb, 0x29, 0xa1, 0xf2, 0xa9, + 0x3f, 0x41, 0x57, 0xfa, 0x2b, 0x87, 0xd5, 0xa5, 0xea, 0xd3, 0x0b, 0x90, 0x07, 0xb6, 0x05, 0xc8, + 0xc7, 0x86, 0x02, 0x01, 0xe3, 0x0a, 0x18, 0x5b, 0x45, 0xf7, 0xbe, 0x2e, 0xa1, 0x9a, 0x9c, 0x29, + 0x8b, 0x69, 0xff, 0x82, 0x6b, 0xdf, 0xaa, 0xc7, 0xc5, 0xb3, 0x80, 0x34, 0xaa, 0x11, 0x63, 0xc8, + 0x80, 0xb6, 0x31, 0x40, 0x47, 0xbe, 0x7e, 0x31, 0x2f, 0x25, 0xdd, 0xdf, 0x81, 0x84, 0x11, 0x18, + 0x1d, 0xf0, 0x77, 0xce, 0x77, 0x02, 0x40, 0x18, 0x01, 0x29, 0x47, 0x4f, 0x0a, 0xaf, 0xdf, 0xaa, + 0xb1, 0xc0, 0x93, 0x04, 0xb7, 0xbe, 0xed, 0xdd, 0xbe, 0x08, 0x6e, 0xee, 0xe9, 0x57, 0x10, 0x42, + 0xbb, 0xbb, 0xfb, 0xbb, 0xbb, 0xf1, 0x3c, 0x18, 0x41, 0x0f, 0x77, 0x37, 0x4b, 0xc1, 0x19, 0xb5, + 0x56, 0x51, 0xfe, 0x0c, 0x41, 0x47, 0x08, 0x00, 0x91, 0x0a, 0x04, 0xa2, 0xfa, 0x9c, 0xf8, 0x81, + 0xfc, 0x56, 0xe7, 0x00, 0xf1, 0x46, 0x70, 0x00, 0xfe, 0x22, 0xb0, 0x9b, 0x82, 0xe4, 0x99, 0x93, + 0xe5, 0x2b, 0xa4, 0xff, 0x49, 0xcb, 0x49, 0xfe, 0x17, 0x24, 0x02, 0xeb, 0x62, 0x08, 0xf3, 0x3b, + 0xb8, 0xac, 0xbf, 0xe2, 0x06, 0x05, 0x98, 0x80, 0x60, 0x58, 0x6b, 0x5e, 0xf8, 0x4d, 0x9c, 0x00, + 0x5e, 0x87, 0xf3, 0x08, 0xdf, 0xe6, 0x3c, 0xf5, 0x7b, 0xe0, 0x63, 0xa5, 0xc8, 0x3c, 0xf0, 0x97, + 0x3e, 0x0f, 0x1c, 0x19, 0x64, 0x60, 0xc0, 0x04, 0xb2, 0x17, 0x64, 0x01, 0x86, 0x33, 0xf4, 0x40, + 0xa2, 0x6d, 0xc7, 0x8c, 0x31, 0xd0, 0xe1, 0xda, 0xb9, 0x51, 0x03, 0xb9, 0xb2, 0x20, 0x77, 0x25, + 0x45, 0x1a, 0x8a, 0x33, 0x49, 0x85, 0xdc, 0x77, 0xff, 0xbd, 0xfe, 0xf7, 0x96, 0x1b, 0x73, 0x09, + 0x82, 0xb2, 0xff, 0xa2, 0x96, 0x1f, 0x1d, 0xdd, 0x6b, 0xc9, 0xd0, 0x65, 0x88, 0x48, 0x37, 0x18, + 0x01, 0x0b, 0x7e, 0x08, 0x07, 0xfe, 0x2d, 0xa7, 0x8b, 0x62, 0xd8, 0x38, 0x2c, 0x86, 0x0a, 0xc4, + 0x03, 0xa2, 0x07, 0x7e, 0x1b, 0x70, 0x05, 0x97, 0x19, 0x54, 0x6f, 0xfc, 0x5b, 0x16, 0xf1, 0x6c, + 0x5b, 0x0c, 0x06, 0x68, 0xe3, 0xc4, 0x03, 0xa2, 0x01, 0xdf, 0x87, 0x30, 0x0c, 0x79, 0x73, 0xd4, + 0xff, 0xfc, 0x55, 0x8a, 0xb4, 0x07, 0xe2, 0x8b, 0x10, 0xef, 0xc7, 0xb1, 0x60, 0x20, 0xdf, 0x47, + 0xb2, 0x3d, 0xdb, 0x6f, 0xc2, 0x5d, 0x11, 0xcb, 0x3a, 0xe3, 0x25, 0x0c, 0x76, 0x62, 0x74, 0x6c, + 0x34, 0xc3, 0x00, 0x07, 0x6e, 0x0a, 0xb1, 0x8a, 0xa7, 0x85, 0x6a, 0x2b, 0x5b, 0xdc, 0xf0, 0x93, + 0xc0, 0xbe, 0x2b, 0x8a, 0xd2, 0x61, 0x72, 0x43, 0x4a, 0x45, 0xff, 0x64, 0xe2, 0xa5, 0xef, 0xd8, + 0x5c, 0x90, 0x8c, 0x22, 0x4b, 0x75, 0xf7, 0x24, 0x1d, 0x90, 0xf2, 0xa6, 0x1b, 0x24, 0x00, 0x6d, + 0xe9, 0x02, 0x3a, 0xb0, 0x8d, 0x3d, 0x5e, 0xfa, 0x8c, 0x43, 0xeb, 0x1f, 0x2c, 0x92, 0x83, 0x86, + 0xc1, 0x7f, 0xbc, 0x26, 0xe0, 0xbf, 0x17, 0xfc, 0xfd, 0x6a, 0xe7, 0x82, 0xd2, 0x55, 0x64, 0xa7, + 0x84, 0x2e, 0xca, 0x04, 0x5d, 0xa6, 0x77, 0x7e, 0xb7, 0xbb, 0xac, 0xb5, 0xec, 0x36, 0xe0, 0x02, + 0xfc, 0xdb, 0x30, 0x44, 0x72, 0x98, 0x63, 0xd5, 0xe3, 0xf8, 0xef, 0x1f, 0x95, 0x1e, 0x36, 0x10, + 0xc1, 0xe5, 0x93, 0xee, 0xbd, 0xff, 0xe5, 0x0a, 0xaa, 0xaa, 0x8c, 0xe8, 0x47, 0x45, 0xf5, 0x1d, + 0xa1, 0x0e, 0x8c, 0xf2, 0xf0, 0x4f, 0x5d, 0x6b, 0x53, 0x27, 0x03, 0x88, 0x90, 0x51, 0xc5, 0x18, + 0x81, 0xca, 0x8a, 0xe2, 0x29, 0x15, 0x43, 0x8a, 0x19, 0x0c, 0x53, 0xfd, 0xa6, 0xb6, 0x9a, 0xa6, + 0x0b, 0xbd, 0xc5, 0x58, 0x3b, 0x7d, 0x32, 0xf8, 0x5d, 0x8a, 0x00, 0x39, 0xe2, 0x85, 0xc3, 0x8d, + 0xef, 0xf5, 0x44, 0x9a, 0x27, 0xbf, 0x24, 0xc2, 0xee, 0x01, 0x72, 0xb5, 0x25, 0xc6, 0x4e, 0x77, + 0xfe, 0x3d, 0x73, 0x27, 0xdc, 0xec, 0x76, 0x3a, 0xc2, 0x6e, 0x00, 0xe6, 0xf4, 0x71, 0xef, 0xf7, + 0xba, 0x7d, 0x38, 0x5d, 0xc0, 0x32, 0x70, 0x45, 0xac, 0xf1, 0xab, 0x85, 0x8d, 0x55, 0xc2, 0xc7, + 0xea, 0xae, 0x16, 0x03, 0x28, 0xab, 0x85, 0x80, 0xd3, 0x61, 0x37, 0x01, 0xfc, 0x94, 0xff, 0xfa, + 0xf0, 0xbb, 0x80, 0x0d, 0x6b, 0x63, 0x44, 0x52, 0x90, 0xf5, 0x7b, 0xe8, 0x9c, 0x76, 0xe7, 0xce, + 0x18, 0x3a, 0x50, 0x15, 0x92, 0xe0, 0x2c, 0x20, 0x98, 0x58, 0x68, 0xb0, 0x18, 0x73, 0x96, 0x88, + 0xe1, 0x94, 0xf3, 0xae, 0x2d, 0x2f, 0x35, 0x3a, 0x43, 0x08, 0xb0, 0xec, 0x91, 0xc0, 0x19, 0x61, + 0x2c, 0x3e, 0x15, 0xe8, 0x25, 0x51, 0x3d, 0x5e, 0x27, 0xa2, 0x3f, 0xd7, 0xf7, 0x0c, 0xf8, 0x20, + 0x86, 0xef, 0x77, 0x03, 0x02, 0x70, 0x10, 0x39, 0x00, 0x73, 0xf3, 0xf7, 0x3d, 0xff, 0x81, 0x04, + 0x30, 0x37, 0xbb, 0x97, 0x0b, 0x85, 0x8e, 0xee, 0xa2, 0xef, 0x36, 0x28, 0x1c, 0x11, 0xc0, 0x28, + 0x38, 0x80, 0x3c, 0x4b, 0xc1, 0xd7, 0xc7, 0x5f, 0xfe, 0x1c, 0x50, 0x15, 0x9c, 0xc3, 0x7a, 0x69, + 0xb6, 0xdf, 0xf8, 0xb2, 0x38, 0xea, 0xa9, 0xa6, 0xbe, 0x1b, 0x61, 0x00, 0x0d, 0x68, 0xc0, 0x7f, + 0x1e, 0xfa, 0x29, 0x61, 0xbe, 0x16, 0x6e, 0x4a, 0xce, 0xe0, 0xcd, 0x24, 0x2c, 0x85, 0xef, 0x85, + 0xdc, 0x0a, 0x94, 0x88, 0x39, 0x63, 0x20, 0xe7, 0x18, 0x5d, 0x0e, 0x86, 0x52, 0x2b, 0x96, 0x52, + 0x15, 0xcb, 0xf7, 0xe0, 0x0a, 0xa0, 0x08, 0x01, 0x48, 0x4a, 0x00, 0x87, 0x39, 0x23, 0x82, 0x2f, + 0x2f, 0xbd, 0xc1, 0xa0, 0x2a, 0xa4, 0xc5, 0x4b, 0x01, 0x64, 0xc0, 0x15, 0xe7, 0x1e, 0xa3, 0x0f, + 0xc3, 0x8a, 0x00, 0x39, 0x5b, 0x00, 0x01, 0x00, 0x00, 0x1e, 0xbc, 0x14, 0x65, 0xba, 0xf6, 0xdc, + 0xa2, 0x57, 0x0e, 0xc1, 0x19, 0x58, 0xab, 0x1e, 0x7e, 0x0a, 0xb0, 0x27, 0x06, 0x40, 0x53, 0x35, + 0x32, 0x7a, 0xde, 0xf0, 0xbb, 0x84, 0x20, 0x91, 0xa7, 0xff, 0xff, 0x5b, 0xe1, 0xbc, 0x00, 0xc0, + 0xe3, 0x6d, 0xce, 0x66, 0xeb, 0xdf, 0xbb, 0x2f, 0x70, 0x3b, 0xd8, 0x3f, 0x1d, 0x50, 0xaf, 0xf5, + 0xc1, 0xc0, 0x80, 0x56, 0x27, 0x8a, 0xc4, 0x34, 0xcf, 0x64, 0x62, 0x71, 0x1a, 0x0f, 0x32, 0x18, + 0x7e, 0x1c, 0x24, 0x07, 0x4a, 0x39, 0x6f, 0xf6, 0xdb, 0xed, 0xb7, 0x9d, 0x11, 0x36, 0xda, 0x69, + 0xff, 0xad, 0x5f, 0x45, 0xaa, 0xe8, 0x5b, 0x90, 0x49, 0x13, 0x28, 0x8b, 0xbb, 0xe0, 0x12, 0x90, + 0x88, 0x2c, 0x29, 0x30, 0x4f, 0xd6, 0x91, 0xb1, 0xd9, 0x9b, 0x02, 0xf5, 0xcb, 0x0e, 0x22, 0x0b, + 0x49, 0x6a, 0x04, 0x82, 0xd0, 0x44, 0x33, 0xff, 0xc7, 0x71, 0xcb, 0xa5, 0xdf, 0x87, 0x15, 0x02, + 0x65, 0x5d, 0x34, 0xce, 0x66, 0xb8, 0xff, 0xeb, 0xa7, 0xfc, 0x05, 0x48, 0x90, 0x5d, 0x5d, 0x5d, + 0xde, 0x34, 0x00, 0x04, 0x0a, 0x80, 0x60, 0x00, 0x08, 0x08, 0xa8, 0x6d, 0x8e, 0x00, 0x35, 0xd8, + 0x32, 0x62, 0xc1, 0xc4, 0xf1, 0x93, 0x2e, 0x5b, 0x8a, 0x3e, 0xf1, 0x41, 0xc5, 0x01, 0xcb, 0xec, + 0xac, 0xb0, 0xbb, 0x88, 0x12, 0x03, 0xa8, 0x3e, 0x0e, 0xc3, 0x1e, 0xa1, 0xf1, 0xea, 0x0e, 0x3c, + 0xa0, 0x5b, 0xfa, 0xc3, 0x6c, 0xa0, 0x0d, 0xd4, 0x61, 0x10, 0x80, 0x7d, 0x6f, 0x58, 0xf6, 0x3f, + 0x89, 0xb0, 0x98, 0x9b, 0x19, 0x7d, 0x0e, 0x46, 0x7b, 0xab, 0x8b, 0xfc, 0x37, 0x80, 0x1b, 0x16, + 0xc2, 0x84, 0xa5, 0x65, 0xef, 0xff, 0xec, 0x84, 0xfb, 0x17, 0xad, 0xef, 0x0b, 0xb8, 0x05, 0x15, + 0x8c, 0xcd, 0x67, 0xfb, 0xdd, 0xef, 0xbc, 0xb6, 0x1b, 0x66, 0x00, 0x26, 0xee, 0x48, 0xcc, 0x13, + 0xeb, 0xab, 0xc7, 0x6e, 0x17, 0x93, 0x37, 0x0b, 0x3d, 0x64, 0xc3, 0x70, 0xb0, 0x32, 0x71, 0xa1, + 0x60, 0x18, 0x8d, 0x13, 0xef, 0x7f, 0x86, 0x10, 0xf1, 0x3b, 0x1b, 0x7e, 0x77, 0xd3, 0x8d, 0x34, + 0xfd, 0x34, 0xf1, 0xc0, 0xca, 0xb0, 0x18, 0x10, 0x5b, 0x2e, 0x17, 0x1e, 0xee, 0x6c, 0xcc, 0x58, + 0x41, 0x4b, 0x1c, 0xad, 0x69, 0xff, 0x96, 0xaa, 0xaa, 0x09, 0x3a, 0x2f, 0x7d, 0x7a, 0xc3, 0x48, + 0x80, 0x44, 0x22, 0xcb, 0x25, 0xff, 0x4f, 0x4f, 0x74, 0xea, 0x10, 0x94, 0x03, 0x2b, 0x65, 0x33, + 0x01, 0x7c, 0xaa, 0x9a, 0x69, 0xfc, 0x24, 0xa0, 0xc6, 0xdf, 0x1f, 0xfe, 0xdb, 0x71, 0x4a, 0x12, + 0xb7, 0x88, 0x75, 0x40, 0x16, 0xd4, 0x77, 0x29, 0xff, 0xfd, 0xbe, 0xed, 0x35, 0xa6, 0x9c, 0x2e, + 0xc7, 0x00, 0x0e, 0xd7, 0x86, 0xd9, 0x4e, 0x13, 0x57, 0xac, 0x99, 0x63, 0xf8, 0xbe, 0x3f, 0x14, + 0x49, 0xc5, 0x12, 0x3f, 0xe0, 0x80, 0x08, 0x23, 0x27, 0x07, 0xd8, 0xf2, 0xf7, 0x15, 0x70, 0x76, + 0xe3, 0xd7, 0xc7, 0xaf, 0x51, 0xd2, 0xe2, 0xe3, 0xa1, 0x7c, 0x01, 0x4c, 0x02, 0x90, 0xa1, 0xd3, + 0x8a, 0x87, 0x8e, 0x27, 0x2a, 0x59, 0xe0, 0xf1, 0x47, 0x6e, 0x4c, 0x06, 0x8d, 0xe4, 0x81, 0x40, + 0xde, 0xff, 0xea, 0x0c, 0x1b, 0x17, 0xe1, 0xa2, 0x10, 0x00, 0xc3, 0xe0, 0x77, 0x60, 0x8d, 0xd7, + 0x9d, 0xef, 0xf7, 0xe8, 0x96, 0x7c, 0xc2, 0x6e, 0x01, 0x23, 0x94, 0x1e, 0x5e, 0xe4, 0x5e, 0x8a, + 0x8a, 0xfb, 0xa2, 0xe1, 0x76, 0x60, 0x03, 0x10, 0xa2, 0x0f, 0x15, 0x41, 0x35, 0x7b, 0xbd, 0xa2, + 0x3f, 0x63, 0xe2, 0xb8, 0xad, 0xfe, 0x15, 0x22, 0x3d, 0xf0, 0x92, 0x08, 0x82, 0xed, 0x60, 0x21, + 0xd1, 0xd2, 0x69, 0xa6, 0x9f, 0xc3, 0x88, 0x80, 0x3a, 0x8c, 0xa5, 0xbf, 0xf6, 0xdb, 0xc5, 0x58, + 0xab, 0x18, 0xa7, 0x4d, 0x3f, 0x87, 0x14, 0x65, 0x9f, 0xfe, 0x9a, 0x7a, 0x71, 0x46, 0xf1, 0xa9, + 0x7f, 0x81, 0xe0, 0x22, 0x08, 0x88, 0xee, 0xee, 0x61, 0xf8, 0x63, 0x04, 0x1d, 0x1f, 0xa6, 0xe0, + 0x9c, 0x8e, 0xfd, 0x4d, 0x85, 0x98, 0x1f, 0x3f, 0x0e, 0x28, 0x02, 0xd6, 0x88, 0x3a, 0x93, 0x36, + 0xdb, 0x4d, 0x36, 0xdb, 0x56, 0xcd, 0xdf, 0xdb, 0x6e, 0xb6, 0xc1, 0xcb, 0x67, 0x45, 0xed, 0x26, + 0x2d, 0xfc, 0x38, 0xa0, 0xd2, 0x28, 0x8f, 0xfd, 0xb6, 0xdb, 0x6d, 0xb6, 0xc4, 0xe9, 0xc4, 0x4c, + 0xa7, 0xb6, 0xdc, 0x38, 0xa0, 0x23, 0x2d, 0x0d, 0x1c, 0xb4, 0xd3, 0xb6, 0x9a, 0x69, 0xa7, 0xe6, + 0xd3, 0x68, 0x78, 0xb9, 0x6d, 0xb1, 0x1d, 0x38, 0xef, 0xc3, 0x8a, 0x09, 0x44, 0xa5, 0x4e, 0xff, + 0xd3, 0x4f, 0xa6, 0x0c, 0xa2, 0xb6, 0xde, 0x5f, 0xf0, 0xe2, 0x81, 0x0e, 0xd3, 0xf0, 0x9a, 0x7d, + 0x3e, 0x9a, 0x4d, 0xa6, 0x9b, 0x6d, 0x88, 0x92, 0x1d, 0xb6, 0x5d, 0x76, 0xbb, 0x7e, 0x1b, 0x66, + 0x00, 0x19, 0x51, 0xeb, 0x6e, 0x16, 0x44, 0x35, 0xd5, 0xd8, 0xc4, 0xe0, 0xc6, 0x79, 0x85, 0x45, + 0x59, 0xb9, 0xd9, 0x3c, 0x0c, 0x1e, 0xc9, 0xe0, 0x18, 0x04, 0x48, 0xc7, 0xd9, 0x46, 0xc4, 0xfe, + 0xff, 0x00, 0xc8, 0x00, 0xd8, 0x0a, 0x1c, 0x70, 0x08, 0x27, 0x4c, 0x70, 0x21, 0x3d, 0x8a, 0x32, + 0x8b, 0xa1, 0x78, 0xef, 0xc7, 0x08, 0x9f, 0x1c, 0x26, 0xf8, 0xab, 0x9b, 0xa3, 0x0f, 0x01, 0xd0, + 0x02, 0xa4, 0x28, 0x43, 0x8f, 0x6f, 0x3b, 0xa7, 0x00, 0xe5, 0x5b, 0x51, 0xcf, 0xce, 0x00, 0x02, + 0x3c, 0xb2, 0xce, 0x00, 0x07, 0x8e, 0x2f, 0xe3, 0x89, 0xf5, 0x12, 0xe3, 0xf0, 0xd3, 0x80, 0x0e, + 0x5c, 0x32, 0x36, 0xaf, 0x8b, 0xbe, 0xf7, 0xf3, 0xfb, 0x73, 0xf1, 0xac, 0x98, 0x4d, 0x14, 0x00, + 0xc9, 0xc3, 0x6d, 0x87, 0xdd, 0x5e, 0x9d, 0x8b, 0xba, 0x21, 0x5a, 0x29, 0xe1, 0x72, 0xdc, 0x51, + 0xbc, 0x3c, 0x85, 0x00, 0x0e, 0x64, 0x40, 0x25, 0x8e, 0x70, 0x3c, 0x40, 0xa6, 0xe2, 0x98, 0xac, + 0x4b, 0x02, 0xf2, 0x77, 0x03, 0xab, 0x8a, 0x62, 0x06, 0x02, 0x99, 0xc3, 0x07, 0xc0, 0xb3, 0x4d, + 0xf1, 0xde, 0x10, 0x00, 0x8c, 0xe2, 0xc5, 0x4a, 0x27, 0xa2, 0x70, 0x30, 0x29, 0x2f, 0xc0, 0x14, + 0x80, 0x14, 0x46, 0x9f, 0x3e, 0x54, 0x5e, 0x94, 0xe7, 0x5a, 0xca, 0x5a, 0xcb, 0x18, 0xff, 0x87, + 0x14, 0x02, 0x70, 0xfa, 0x14, 0x73, 0xe7, 0xed, 0xda, 0x6b, 0xff, 0x03, 0x03, 0x1f, 0xcd, 0xb6, + 0xff, 0x00, 0xc8, 0x01, 0x04, 0x17, 0x45, 0x0c, 0x5f, 0x9b, 0x2a, 0x2f, 0xb8, 0x09, 0x00, 0x88, + 0x20, 0xdc, 0x56, 0x2b, 0x27, 0x73, 0x83, 0xe7, 0x55, 0x0f, 0x69, 0x25, 0x2f, 0xf8, 0x71, 0x40, + 0x17, 0xb1, 0xa2, 0x2c, 0x5f, 0xd7, 0x4d, 0x3d, 0x34, 0xc5, 0x6b, 0xb6, 0x25, 0xdf, 0xf0, 0x84, + 0x11, 0xd5, 0x56, 0x7a, 0x09, 0x38, 0x72, 0xee, 0xee, 0x29, 0xb5, 0x93, 0xfe, 0x01, 0x49, 0x82, + 0xa9, 0xf0, 0xf9, 0xe4, 0xcd, 0x45, 0xc5, 0xc5, 0xce, 0x98, 0x71, 0x41, 0x75, 0x4a, 0xe3, 0xff, + 0xa6, 0x9e, 0x4e, 0xfe, 0x2d, 0xb7, 0xfe, 0x01, 0x99, 0x82, 0xdc, 0x99, 0x7e, 0x4c, 0x2d, 0xc4, + 0x84, 0x01, 0x05, 0x29, 0x77, 0x17, 0x17, 0x17, 0x17, 0x13, 0xc7, 0x61, 0x61, 0x9e, 0x70, 0x0e, + 0x12, 0x00, 0xaa, 0xc9, 0x38, 0xf5, 0xfe, 0x1c, 0x50, 0x09, 0x3c, 0xac, 0x75, 0x93, 0xa7, 0xa6, + 0x9f, 0xfe, 0x2a, 0x71, 0xff, 0x87, 0x14, 0x01, 0x9a, 0xf6, 0x02, 0xd3, 0xa7, 0x4f, 0x4d, 0x34, + 0xd3, 0x4d, 0x34, 0xd3, 0x4d, 0x3c, 0xf8, 0xe3, 0xb7, 0xf8, 0x03, 0x09, 0x01, 0x12, 0x36, 0x20, + 0x00, 0x0c, 0x61, 0xc0, 0x54, 0x8f, 0x16, 0x0f, 0xf9, 0x28, 0x00, 0x34, 0x0e, 0xe2, 0xa1, 0x28, + 0x00, 0xd0, 0xf0, 0x2c, 0x56, 0xde, 0x7f, 0x19, 0x28, 0x34, 0x3c, 0x0b, 0x04, 0xa3, 0x43, 0xc0, + 0xb0, 0x20, 0x00, 0x1b, 0x03, 0xd3, 0x80, 0x06, 0x13, 0x80, 0x61, 0xfc, 0x22, 0x02, 0xc0, 0x28, + 0x71, 0xc9, 0x77, 0x1c, 0xaf, 0x69, 0xeb, 0x1f, 0x7a, 0xe3, 0x37, 0x17, 0x4c, 0xb0, 0xd3, 0x46, + 0x70, 0xb9, 0x20, 0x1a, 0xa3, 0x01, 0x1d, 0x67, 0x1f, 0x64, 0xa6, 0x82, 0x1a, 0x1a, 0x1a, 0x18, + 0xbe, 0x2f, 0xa7, 0xe0, 0x09, 0x60, 0x08, 0x21, 0x48, 0x3d, 0x77, 0x1e, 0xbd, 0x67, 0xcb, 0x96, + 0x30, 0x6d, 0x2b, 0xd9, 0x38, 0x3f, 0x9a, 0xdb, 0x0c, 0x92, 0x00, 0x73, 0xa0, 0x3c, 0x84, 0x83, + 0x7a, 0xee, 0xe2, 0xf1, 0x75, 0x7b, 0xd6, 0xba, 0xc3, 0x6c, 0x50, 0x02, 0x06, 0xc6, 0x2f, 0x05, + 0x7d, 0xee, 0xba, 0x23, 0xc2, 0x3d, 0x91, 0x4d, 0x15, 0x24, 0x40, 0xed, 0x06, 0x46, 0x38, 0x50, + 0x66, 0x0d, 0xbd, 0x85, 0x27, 0x6e, 0x7c, 0x3c, 0x85, 0x80, 0x1c, 0x87, 0x48, 0x81, 0x5b, 0x75, + 0x8a, 0xe6, 0xf7, 0xb6, 0xde, 0xe2, 0xac, 0x1d, 0xfb, 0x6d, 0xbf, 0x8e, 0xdf, 0xb5, 0xff, 0xc3, + 0x04, 0x80, 0x18, 0x42, 0x9f, 0x06, 0x62, 0xd9, 0xdb, 0x4d, 0xcd, 0xf3, 0xfd, 0xbd, 0x35, 0x52, + 0x76, 0x71, 0x29, 0x38, 0x06, 0x60, 0x1c, 0x85, 0x24, 0xf5, 0x17, 0xc9, 0xe4, 0xc6, 0x65, 0x4e, + 0xc8, 0xb8, 0xa6, 0x38, 0xdc, 0x07, 0xc0, 0x30, 0x1b, 0x07, 0x97, 0xb0, 0x78, 0x5d, 0x9e, 0x21, + 0xe0, 0xe8, 0xb0, 0xfe, 0x83, 0x22, 0x53, 0xb8, 0x1e, 0x9a, 0x8f, 0x1e, 0x12, 0x81, 0x53, 0x8e, + 0x87, 0xfa, 0x94, 0x8d, 0x45, 0xf8, 0xbc, 0xfc, 0xbb, 0xf0, 0xee, 0x00, 0xdb, 0xda, 0x20, 0x37, + 0xbe, 0x1e, 0xec, 0x92, 0xf2, 0xd6, 0x7b, 0xdf, 0xcb, 0x5f, 0xfd, 0x31, 0x6c, 0xde, 0x45, 0x08, + 0xea, 0x9f, 0xf0, 0xe2, 0x80, 0x0a, 0xb9, 0xc0, 0xf3, 0xb9, 0xb0, 0x23, 0xfb, 0xee, 0xae, 0xa9, + 0xa6, 0x0f, 0xb9, 0x65, 0x9f, 0xcd, 0xcf, 0x3f, 0x13, 0xe2, 0xac, 0x0c, 0xf4, 0x62, 0xae, 0xff, + 0xe0, 0x8f, 0x8b, 0x89, 0xe0, 0x21, 0x48, 0x7b, 0xa9, 0xca, 0xfa, 0xba, 0xb8, 0x77, 0x7b, 0xb8, + 0xae, 0xd3, 0xee, 0x19, 0x08, 0x16, 0xab, 0x3a, 0xcf, 0xc3, 0x8a, 0x00, 0xa9, 0xb0, 0xe4, 0xaf, + 0xa9, 0x5d, 0x5d, 0x34, 0xd4, 0x57, 0xbc, 0x47, 0x9c, 0xf5, 0x2d, 0x8c, 0x10, 0xcc, 0x6b, 0xb4, + 0xbf, 0x03, 0x00, 0x91, 0xb1, 0x0f, 0x7f, 0xed, 0xe7, 0x8e, 0x5a, 0x10, 0x38, 0x16, 0x6a, 0x3c, + 0x70, 0xb6, 0x5a, 0xc4, 0x81, 0xc1, 0x56, 0x78, 0x01, 0xe1, 0x0a, 0x08, 0xae, 0xaa, 0x23, 0xfe, + 0x1c, 0x50, 0x06, 0xc1, 0xfd, 0x17, 0xa1, 0x04, 0xe3, 0x6c, 0xff, 0xfa, 0x69, 0xd5, 0x34, 0xde, + 0x9a, 0x7f, 0xe1, 0x9c, 0x00, 0xb7, 0xf4, 0xa0, 0xc5, 0xef, 0xef, 0x7b, 0x6d, 0x97, 0xc7, 0x76, + 0xdb, 0x4d, 0x36, 0xd4, 0x9e, 0x44, 0x74, 0x6c, 0x3d, 0x80, 0x09, 0x2b, 0x91, 0xa6, 0xd0, 0x7d, + 0xea, 0xdb, 0xab, 0x6d, 0xde, 0xea, 0x5e, 0xb6, 0x0b, 0xd7, 0x7f, 0xe1, 0xc4, 0x40, 0x00, 0xd5, + 0x38, 0x3b, 0xb3, 0x30, 0x1e, 0x99, 0x7e, 0xdb, 0x37, 0x5d, 0x60, 0xef, 0xeb, 0x1d, 0xbb, 0xd6, + 0x5a, 0xcb, 0x59, 0xfd, 0x60, 0xe5, 0xa5, 0x34, 0xe9, 0xfe, 0x01, 0x79, 0x8d, 0x83, 0x88, 0xf9, + 0xee, 0x07, 0x4d, 0xad, 0x4a, 0xe8, 0x58, 0x6d, 0x64, 0xb0, 0xc9, 0xea, 0x58, 0x67, 0x9e, 0x58, + 0x1d, 0x62, 0x9a, 0xa8, 0x80, 0x00, 0x74, 0x05, 0xd2, 0xc0, 0x67, 0x80, 0x90, 0x01, 0xf7, 0xf8, + 0x06, 0x60, 0x05, 0x80, 0x50, 0xe9, 0x9f, 0xf1, 0x3e, 0x70, 0x7c, 0x67, 0x1f, 0x1c, 0x5c, 0x51, + 0xba, 0x85, 0xbb, 0x76, 0xc2, 0xee, 0x00, 0x50, 0x5d, 0x05, 0xca, 0x09, 0x2d, 0x5e, 0x56, 0xaa, + 0x68, 0x2b, 0xa1, 0x17, 0x8b, 0x8b, 0x9f, 0x80, 0xb9, 0xf8, 0x23, 0x1e, 0x22, 0x14, 0x9c, 0x78, + 0xbb, 0x37, 0x97, 0xc5, 0x6d, 0xf3, 0x9e, 0x2b, 0xbc, 0x57, 0x6e, 0x0a, 0x61, 0x42, 0xc8, 0xbc, + 0xdc, 0x9d, 0xe4, 0x4b, 0xd3, 0x7b, 0x2e, 0xff, 0x1d, 0xc6, 0x28, 0xd1, 0xf8, 0x6d, 0x8e, 0x01, + 0x71, 0x81, 0x80, 0x97, 0x69, 0xf2, 0xda, 0xd6, 0xa2, 0x8c, 0x5c, 0x51, 0x8b, 0xb6, 0xb5, 0x1a, + 0xd2, 0x31, 0xaf, 0xe1, 0xc8, 0x90, 0x03, 0x3a, 0x50, 0xcd, 0xb0, 0xa5, 0xde, 0x5f, 0x19, 0x7c, + 0x6d, 0xb6, 0xdb, 0x75, 0x9b, 0x9b, 0xd6, 0x3c, 0x8d, 0xad, 0x34, 0xfe, 0x1e, 0xc0, 0x3d, 0x99, + 0x98, 0xa4, 0x60, 0x3a, 0xef, 0x9f, 0xa6, 0xde, 0x7b, 0xc5, 0xcb, 0x62, 0x7e, 0xed, 0x9f, 0xe5, + 0xd3, 0x4f, 0xe1, 0x42, 0x40, 0x26, 0xec, 0x5a, 0xaa, 0xab, 0xef, 0x54, 0xf2, 0xdb, 0x97, 0xb7, + 0xa8, 0xae, 0x5f, 0xe1, 0xb7, 0x00, 0xd4, 0x78, 0xc2, 0xa6, 0x6e, 0xae, 0x5f, 0xf4, 0xd3, 0x12, + 0xf3, 0x71, 0x2f, 0x77, 0xad, 0xba, 0xdb, 0x15, 0x4b, 0xd3, 0x4f, 0xe1, 0xe7, 0x00, 0x25, 0xf4, + 0xec, 0x16, 0x55, 0xf7, 0xbd, 0xc9, 0xdb, 0xfa, 0x6b, 0x5d, 0x6d, 0xb6, 0x2b, 0x53, 0xf2, 0xfa, + 0xb6, 0xdf, 0xf8, 0x03, 0x50, 0x03, 0x08, 0xda, 0xb8, 0x28, 0xbe, 0xad, 0xd8, 0x7f, 0x0b, 0x0c, + 0x9c, 0x00, 0x08, 0x28, 0xe8, 0x3e, 0x5e, 0x38, 0x80, 0xfb, 0x70, 0x2a, 0x54, 0x3f, 0x09, 0x4e, + 0x70, 0x78, 0xf0, 0x46, 0x71, 0xa6, 0x6e, 0x73, 0x5f, 0xc0, 0xa0, 0x24, 0x29, 0x71, 0x04, 0xbc, + 0xf0, 0xe1, 0xde, 0x6c, 0x12, 0x1c, 0x54, 0xa7, 0x87, 0x9c, 0x07, 0xb3, 0x62, 0x76, 0x96, 0xc7, + 0xbc, 0x7e, 0x0f, 0x0f, 0x83, 0x08, 0x63, 0xe0, 0x8e, 0x2f, 0x2f, 0x5d, 0x41, 0x0f, 0x04, 0xfb, + 0xb8, 0xac, 0x56, 0x2b, 0x15, 0x8a, 0x0c, 0x49, 0xdc, 0x0b, 0x11, 0xb1, 0x1c, 0x53, 0x56, 0x48, + 0x00, 0xd4, 0x3a, 0x0b, 0x83, 0xa0, 0x02, 0xe3, 0xde, 0x87, 0xb0, 0x12, 0xc9, 0x80, 0x54, 0x2a, + 0x2a, 0x5b, 0x1d, 0xf9, 0xfe, 0x3b, 0xf8, 0x30, 0x8c, 0x40, 0x00, 0x20, 0x8e, 0x34, 0x0c, 0x46, + 0x8e, 0xeb, 0x5f, 0xe0, 0x2c, 0x41, 0x48, 0xd2, 0x13, 0x8a, 0xf6, 0xa7, 0xc2, 0xc6, 0x5e, 0x99, + 0xc0, 0xe0, 0xf3, 0xc1, 0xe0, 0x07, 0x87, 0x00, 0x01, 0x3c, 0x56, 0xb1, 0x87, 0xe0, 0x6a, 0x70, + 0xe0, 0x38, 0x04, 0x72, 0x2b, 0x13, 0xe2, 0xff, 0x83, 0x90, 0x52, 0x37, 0x5c, 0x4b, 0xd4, 0x4f, + 0x9c, 0x1c, 0x99, 0x3c, 0x7d, 0x65, 0x80, 0xc4, 0x0e, 0x65, 0xc8, 0x64, 0x04, 0x00, 0x2d, 0x53, + 0x8f, 0x27, 0x2f, 0xf8, 0x60, 0x90, 0x12, 0x59, 0xe4, 0x40, 0x07, 0x2e, 0xd7, 0xf4, 0x54, 0x4c, + 0xbd, 0x1c, 0xe1, 0xa2, 0x40, 0x08, 0x6f, 0x68, 0xd3, 0x2d, 0xdf, 0xf7, 0xf7, 0x73, 0x73, 0xfa, + 0xd4, 0xbc, 0xdd, 0xfc, 0x85, 0x87, 0x30, 0x00, 0xc7, 0xe3, 0x33, 0xab, 0x17, 0xff, 0x9b, 0xba, + 0xab, 0x69, 0xdf, 0xcf, 0xfd, 0x6b, 0x6d, 0xcf, 0xe1, 0xed, 0xb7, 0xf8, 0x78, 0x90, 0x02, 0x6a, + 0x72, 0x04, 0x24, 0xfe, 0x73, 0xd3, 0x2f, 0x4d, 0x63, 0x4e, 0xe6, 0xf6, 0xa7, 0xf1, 0x5e, 0x47, + 0xdb, 0xdf, 0xe1, 0xe7, 0x03, 0x1b, 0x78, 0x10, 0xfe, 0xae, 0xd4, 0x56, 0xbe, 0x7b, 0xe6, 0xd5, + 0x6b, 0x09, 0x62, 0x21, 0x18, 0xab, 0x8f, 0x62, 0x7e, 0x14, 0x65, 0x00, 0x1c, 0xe4, 0x3e, 0x27, + 0x5a, 0x54, 0xfa, 0x7b, 0xf7, 0xd6, 0xae, 0x7e, 0x2b, 0x3d, 0xf8, 0x16, 0x41, 0x40, 0x40, 0x80, + 0xf1, 0x7b, 0x07, 0x85, 0xec, 0x78, 0x2f, 0x18, 0xf0, 0x2f, 0xde, 0xf0, 0xbb, 0x16, 0x01, 0x08, + 0xb2, 0x80, 0xca, 0x37, 0x93, 0x78, 0xad, 0x75, 0x8a, 0xe2, 0xb7, 0x51, 0x2c, 0x0e, 0xb1, 0xd8, + 0x59, 0xc0, 0x13, 0x30, 0x56, 0x28, 0xa2, 0xf9, 0x75, 0xef, 0x5c, 0xab, 0xdf, 0x0d, 0x90, 0x70, + 0x00, 0x9f, 0x5e, 0x41, 0x5c, 0x81, 0x8f, 0x14, 0x52, 0x41, 0x34, 0xd9, 0xed, 0x93, 0x20, 0xc9, + 0x90, 0x97, 0x83, 0x4c, 0x12, 0x05, 0x0a, 0xa7, 0xe7, 0xee, 0xff, 0xf0, 0xeb, 0x38, 0x00, 0xd2, + 0x44, 0x8c, 0x4e, 0x31, 0xe4, 0x1b, 0xb4, 0x5f, 0xdb, 0xb6, 0xdb, 0xba, 0x65, 0xe4, 0xe7, 0x3d, + 0xbd, 0xbd, 0xbd, 0xbc, 0x17, 0x77, 0xb6, 0xbf, 0x0e, 0x28, 0x01, 0xdc, 0x4f, 0x84, 0x2c, 0xdb, + 0x37, 0x3f, 0x5d, 0xdd, 0xb9, 0xff, 0x9d, 0xf4, 0xd3, 0x6d, 0xbf, 0x87, 0x14, 0x11, 0x42, 0x1d, + 0x6c, 0x8f, 0xff, 0xd6, 0x0b, 0x37, 0xbf, 0xc3, 0x8a, 0x00, 0x51, 0xd4, 0xd0, 0x82, 0x7b, 0x2e, + 0x79, 0x75, 0xd6, 0xea, 0xea, 0xa9, 0xaa, 0x8a, 0xef, 0x7f, 0x87, 0x51, 0x40, 0x07, 0xc5, 0xcf, + 0x68, 0x1e, 0x11, 0xbf, 0xe7, 0x8d, 0xdf, 0xd6, 0xdd, 0xc7, 0x57, 0xcd, 0xd3, 0x4d, 0xdd, 0x3f, + 0x1c, 0x9f, 0x74, 0xd3, 0xf8, 0x71, 0x40, 0x45, 0x9f, 0x8f, 0x67, 0xd3, 0xff, 0x10, 0xfb, 0xe2, + 0xee, 0xaa, 0xed, 0xb6, 0x9e, 0xe1, 0xe5, 0x17, 0x7a, 0x7f, 0x87, 0x30, 0x00, 0xdd, 0xec, 0x2b, + 0xf2, 0xb8, 0x8c, 0x33, 0xdf, 0xf3, 0xb7, 0xa6, 0x5d, 0xb7, 0x8f, 0x5e, 0x31, 0xeb, 0xbb, 0x6e, + 0x6f, 0x13, 0xf1, 0x3e, 0x35, 0xd5, 0xdf, 0xf0, 0x80, 0x91, 0xb9, 0x15, 0xcb, 0xa7, 0x79, 0x66, + 0xa5, 0x81, 0x89, 0x0e, 0x3b, 0x79, 0xb8, 0x61, 0x73, 0xeb, 0xb9, 0x7c, 0x7f, 0xe5, 0x22, 0x78, + 0xe1, 0xce, 0xad, 0x7c, 0x12, 0x6e, 0x2b, 0x15, 0xf6, 0x1e, 0x50, 0x00, 0xbe, 0xf0, 0xb3, 0xd4, + 0x77, 0x1a, 0x1a, 0xd4, 0xdd, 0x62, 0x7d, 0xe6, 0x4f, 0x11, 0xed, 0xf1, 0xb7, 0xc6, 0x35, 0x45, + 0x5b, 0xfe, 0x1c, 0x50, 0x06, 0x9d, 0x90, 0xdb, 0xb8, 0xd2, 0x2d, 0x5b, 0x37, 0x92, 0x41, 0xde, + 0xb7, 0xde, 0xb2, 0x72, 0xf0, 0x3f, 0xea, 0x62, 0xdb, 0x7f, 0x87, 0x14, 0x02, 0xda, 0xf5, 0x78, + 0x05, 0x7b, 0x67, 0xfe, 0xbe, 0x5e, 0x6e, 0xff, 0xea, 0x7b, 0xe2, 0x5e, 0x46, 0x75, 0xdb, 0xfc, + 0x38, 0xa0, 0x19, 0x84, 0x94, 0xd3, 0x58, 0xa7, 0x77, 0x52, 0xf2, 0x7f, 0x2d, 0xc6, 0x99, 0xbb, + 0x6c, 0xed, 0xe3, 0xc9, 0x95, 0xbf, 0xe1, 0xc5, 0x00, 0x6c, 0x7d, 0x50, 0xe5, 0x83, 0xad, 0x26, + 0xfa, 0x99, 0x0b, 0x0a, 0xf1, 0x67, 0xe0, 0xef, 0xee, 0xc7, 0x6f, 0x5d, 0x6d, 0xd3, 0x15, 0x6d, + 0x90, 0x5a, 0xa7, 0xf8, 0x71, 0x40, 0x2d, 0xad, 0x09, 0x22, 0x14, 0xdf, 0xd6, 0xa9, 0x83, 0xef, + 0x5d, 0x6d, 0xf6, 0xb3, 0x6e, 0xee, 0xe2, 0xfd, 0xa7, 0xfc, 0x38, 0xa0, 0x03, 0xbf, 0xc4, 0x49, + 0x01, 0x99, 0xcb, 0xf9, 0xbf, 0x2f, 0xdc, 0x5c, 0x56, 0x2e, 0x78, 0x1b, 0x9e, 0xc2, 0x44, 0xb4, + 0x97, 0xdf, 0xf0, 0xc6, 0x02, 0x71, 0x8c, 0x44, 0x0f, 0xc3, 0xf7, 0x9e, 0x0f, 0xb8, 0xe4, 0x7c, + 0x46, 0x05, 0x83, 0x3e, 0x9f, 0x6e, 0x5d, 0xc9, 0x47, 0x19, 0xcc, 0x07, 0x5b, 0x0d, 0xb2, 0x11, + 0x8e, 0x24, 0xff, 0x69, 0x59, 0x7c, 0xbe, 0x5f, 0xee, 0x0e, 0x44, 0x73, 0xf0, 0xc5, 0x3f, 0xc2, + 0x6e, 0x05, 0x4e, 0x64, 0xbc, 0xad, 0x5d, 0xf0, 0x9e, 0x15, 0xac, 0x4b, 0x08, 0x91, 0x84, 0x26, + 0x48, 0x98, 0x58, 0x11, 0x9e, 0xad, 0x6b, 0xf5, 0x8b, 0xfc, 0x26, 0xce, 0x00, 0xa2, 0x24, 0x90, + 0x2a, 0xd9, 0x5a, 0x96, 0xf1, 0x47, 0x55, 0x55, 0x14, 0x71, 0x41, 0xe1, 0x7c, 0x06, 0x9e, 0x67, + 0x9f, 0x7b, 0xfd, 0xef, 0xb3, 0x0d, 0xcc, 0x00, 0x4f, 0x5c, 0x0a, 0xd2, 0x0f, 0x9f, 0xed, 0x7d, + 0xd5, 0x55, 0x7a, 0x60, 0x50, 0xc9, 0xb9, 0xe1, 0xf1, 0x21, 0xf7, 0xbe, 0x00, 0xf6, 0x03, 0x21, + 0x42, 0x83, 0xcf, 0x95, 0x4e, 0x91, 0x8e, 0xbe, 0x58, 0x19, 0xc0, 0x70, 0x98, 0x0d, 0x4c, 0xc4, + 0xee, 0xeb, 0xa9, 0x55, 0x62, 0x4e, 0x0e, 0x03, 0xb0, 0xf1, 0x20, 0x04, 0x26, 0x66, 0x33, 0x64, + 0x73, 0xdf, 0xdd, 0xb7, 0xd3, 0xb7, 0x7a, 0xb6, 0x6e, 0x5f, 0x63, 0xbf, 0x5f, 0x83, 0x0d, 0xe4, + 0xff, 0x0d, 0x12, 0x00, 0x55, 0xe3, 0x82, 0x45, 0x1d, 0xd7, 0x9a, 0xdb, 0xba, 0x8b, 0xa7, 0x2d, + 0x88, 0x7c, 0x96, 0xdb, 0xc8, 0xa7, 0x0e, 0x60, 0x05, 0x64, 0x78, 0x1f, 0x66, 0x33, 0xc7, 0x1f, + 0xd6, 0x48, 0xe3, 0x37, 0x77, 0x27, 0x8c, 0xf7, 0xa7, 0x93, 0xb3, 0xfb, 0x62, 0xb1, 0x6d, 0xbf, + 0xe1, 0xc5, 0x00, 0x98, 0xad, 0x5f, 0xb8, 0xd4, 0x6f, 0xf5, 0xdf, 0x75, 0x74, 0xcd, 0x14, 0xcb, + 0xb9, 0x15, 0x8b, 0x60, 0xf7, 0xcc, 0xbe, 0xdf, 0xe1, 0xa5, 0x00, 0x37, 0x5d, 0x22, 0x11, 0xc4, + 0x67, 0x3e, 0x9d, 0xd3, 0x4d, 0x56, 0x55, 0xd5, 0xd5, 0xb0, 0xe2, 0x80, 0x2d, 0x44, 0xc5, 0xbf, + 0x76, 0xd3, 0x2e, 0xe9, 0xa6, 0xe8, 0x3d, 0x2e, 0xdb, 0x9a, 0x37, 0x32, 0xed, 0xed, 0xfc, 0x34, + 0x48, 0x03, 0xb2, 0xcc, 0xe2, 0x68, 0xc5, 0x6c, 0xd0, 0x7a, 0x4d, 0xcb, 0xaf, 0x5b, 0xa8, 0xad, + 0xbe, 0xf8, 0x26, 0xad, 0x6b, 0x17, 0x36, 0x07, 0x31, 0xd0, 0xfc, 0x06, 0x08, 0x40, 0x29, 0x1c, + 0xab, 0xa3, 0x72, 0x64, 0x9c, 0xe5, 0xd3, 0x6e, 0xbd, 0x6a, 0x2a, 0xa5, 0x1e, 0xb9, 0xb6, 0x1e, + 0x50, 0x01, 0xf7, 0x34, 0xa4, 0x1b, 0x8b, 0xda, 0xd5, 0xde, 0xde, 0xdb, 0xb6, 0xdb, 0x67, 0xf5, + 0xf4, 0xfe, 0x9f, 0xe1, 0xa5, 0x00, 0x24, 0xf4, 0x37, 0x87, 0x4b, 0xcf, 0xc2, 0x1e, 0xa2, 0xb3, + 0x76, 0x76, 0xf7, 0x77, 0xf1, 0x5d, 0x27, 0xbb, 0xed, 0xca, 0xc6, 0xd4, 0x3c, 0x48, 0x06, 0x20, + 0x14, 0x51, 0x57, 0x55, 0x27, 0x6c, 0xbd, 0x3b, 0x73, 0xf8, 0xbb, 0x8b, 0xbd, 0xbb, 0x91, 0xb5, + 0xaf, 0xe0, 0x41, 0x05, 0x21, 0x48, 0x1f, 0x92, 0x8f, 0x0b, 0x2f, 0x24, 0x00, 0x0a, 0x8a, 0x05, + 0x54, 0x3c, 0xf2, 0x80, 0x5e, 0x8f, 0x10, 0x0e, 0x5b, 0x1c, 0x09, 0x7b, 0x63, 0x81, 0x2f, 0x05, + 0x80, 0x00, 0x81, 0x6c, 0x10, 0x70, 0xc1, 0x20, 0x38, 0x59, 0xa8, 0x23, 0xbe, 0x7e, 0x37, 0x8c, + 0xbe, 0xa9, 0x93, 0xcd, 0x97, 0x8a, 0xd3, 0x67, 0xa8, 0xcd, 0x86, 0x89, 0x09, 0xc4, 0x66, 0xb3, + 0xfd, 0xdf, 0x7d, 0xd6, 0x23, 0xfc, 0x61, 0xe2, 0x40, 0x05, 0x16, 0xe6, 0x81, 0x2d, 0x70, 0x30, + 0x85, 0x62, 0x4f, 0x15, 0x96, 0x77, 0x3f, 0x6c, 0x56, 0xad, 0xfd, 0xde, 0x2e, 0x63, 0xfb, 0x7f, + 0x87, 0x08, 0x40, 0x01, 0x0c, 0x34, 0xc3, 0x06, 0x55, 0x41, 0xfb, 0x99, 0x3a, 0x71, 0x00, 0xc1, + 0xce, 0x06, 0x02, 0xf1, 0x73, 0xf7, 0x2c, 0x19, 0x6c, 0x48, 0x0f, 0x07, 0x4b, 0x62, 0x18, 0x39, + 0xcc, 0x3e, 0x1b, 0x71, 0x47, 0xde, 0xff, 0xf7, 0xf8, 0xcf, 0x4e, 0xc2, 0x76, 0x1f, 0x85, 0xd4, + 0x05, 0x41, 0x44, 0x89, 0xf8, 0xea, 0xeb, 0xee, 0xae, 0xa5, 0x82, 0x2b, 0x45, 0x3b, 0x0b, 0xb8, + 0x03, 0xbf, 0x62, 0x23, 0x3b, 0xd6, 0xbf, 0x5a, 0xd9, 0x84, 0xd9, 0x40, 0xed, 0xa6, 0x7d, 0x15, + 0x15, 0x6b, 0x44, 0xa8, 0xb0, 0xbb, 0x28, 0x32, 0x49, 0x9f, 0xf5, 0x55, 0x5f, 0x6c, 0x36, 0x8c, + 0x00, 0xfc, 0xb2, 0x07, 0x5d, 0x50, 0xe8, 0x6b, 0xba, 0xa1, 0xad, 0x8d, 0xee, 0x0f, 0x1f, 0x62, + 0x70, 0xff, 0x00, 0x21, 0x0c, 0x2e, 0x51, 0x21, 0xe7, 0x80, 0x01, 0x2e, 0x15, 0x2a, 0x4a, 0x00, + 0x04, 0x17, 0x3c, 0xfa, 0x81, 0xc0, 0x11, 0x80, 0x3c, 0x19, 0x05, 0x07, 0x57, 0x13, 0xe2, 0x4f, + 0x77, 0xf8, 0x73, 0x00, 0xe0, 0xde, 0x28, 0xa7, 0xad, 0xde, 0xf9, 0x77, 0xdb, 0xbb, 0x6e, 0x9a, + 0x69, 0xa6, 0x99, 0x3a, 0x67, 0x78, 0x1a, 0xcc, 0xcf, 0x6d, 0xbf, 0xc0, 0x1d, 0x00, 0x10, 0x42, + 0x98, 0x59, 0x54, 0xf3, 0xc0, 0x07, 0x0f, 0x1e, 0x20, 0x1e, 0x78, 0xfa, 0xd4, 0x75, 0x72, 0xc3, + 0x8f, 0x12, 0x1c, 0x10, 0x78, 0xc2, 0xbc, 0x39, 0x80, 0x4c, 0x12, 0x87, 0xcc, 0x57, 0xb1, 0xe2, + 0xef, 0xab, 0xab, 0x6a, 0xe4, 0x85, 0xce, 0x23, 0xd3, 0x2f, 0xd0, 0x1b, 0x8a, 0xb6, 0xfe, 0x17, + 0x24, 0x00, 0x60, 0x2b, 0x81, 0xe5, 0x12, 0x3d, 0xfd, 0xf2, 0x9b, 0xd6, 0xe5, 0xe9, 0xa7, 0x8c, + 0x61, 0xbd, 0x90, 0xbb, 0xe1, 0xbc, 0x00, 0x75, 0xf6, 0x64, 0x0b, 0x93, 0x37, 0xde, 0xcf, 0x3f, + 0xf7, 0x74, 0x09, 0x17, 0x42, 0x14, 0x56, 0x6f, 0x71, 0x3a, 0xdf, 0xf0, 0xb9, 0x20, 0x06, 0x8a, + 0x13, 0xae, 0x48, 0x6f, 0x37, 0xb6, 0xb5, 0x5a, 0x64, 0xf1, 0x93, 0xce, 0x27, 0xe7, 0xc3, 0xb8, + 0x00, 0x6c, 0x6b, 0x95, 0xb9, 0x82, 0xc6, 0x5c, 0xe9, 0x6b, 0x15, 0x88, 0x7a, 0x67, 0x0f, 0x79, + 0x6d, 0x45, 0xce, 0x78, 0xbd, 0x8a, 0xcf, 0x5f, 0xf8, 0x90, 0xf4, 0xb3, 0x2c, 0xcb, 0xc5, 0xf7, + 0x71, 0x0f, 0x2c, 0x6e, 0xe1, 0xc1, 0x81, 0xe3, 0xef, 0x2f, 0x2f, 0xff, 0x04, 0x77, 0xbb, 0xf4, + 0x3a, 0x1c, 0x47, 0x00, 0x4d, 0xe3, 0xc6, 0x16, 0xc0, 0xbb, 0xdc, 0xdd, 0xff, 0xb8, 0xbb, 0x8b, + 0x8f, 0x95, 0x5e, 0xff, 0x0e, 0xc8, 0x01, 0x40, 0x00, 0x27, 0x74, 0xf6, 0xeb, 0xdf, 0x17, 0x8b, + 0xbb, 0xbb, 0xaa, 0x8b, 0xc5, 0x0d, 0x57, 0x57, 0xf8, 0x68, 0x90, 0x00, 0xdf, 0xb8, 0xc4, 0x55, + 0xd9, 0x95, 0xf8, 0xbf, 0xbd, 0x54, 0x9d, 0xbe, 0x2f, 0x8b, 0xdf, 0x0c, 0xa8, 0x00, 0xcc, 0x19, + 0xc6, 0x44, 0x2f, 0xe2, 0x65, 0xff, 0x17, 0xaf, 0xba, 0xba, 0x8d, 0xe3, 0x0e, 0x92, 0x00, 0x2e, + 0xeb, 0x17, 0x16, 0x21, 0x75, 0xaf, 0x84, 0x3e, 0x4b, 0x7a, 0x7b, 0xbc, 0x56, 0x27, 0x02, 0xc0, + 0xf3, 0x03, 0x98, 0x08, 0x95, 0xbc, 0x57, 0xf0, 0xe2, 0x84, 0xe0, 0xb5, 0x23, 0xdf, 0xf3, 0xba, + 0xd4, 0xb6, 0xa2, 0xbf, 0xa8, 0x97, 0xc4, 0x8f, 0x12, 0xd5, 0xd3, 0x4f, 0xe1, 0xc5, 0x00, 0x1b, + 0xd8, 0xa8, 0x49, 0xb5, 0x98, 0xf2, 0xf7, 0xe5, 0x15, 0xab, 0xf4, 0xcb, 0xd3, 0x2f, 0x4c, 0xbc, + 0xef, 0x6f, 0x3b, 0xc6, 0xa9, 0x8a, 0xe7, 0xff, 0x0d, 0x12, 0x00, 0x46, 0x1b, 0x25, 0x07, 0x04, + 0x5f, 0xaf, 0xd6, 0xa2, 0x58, 0x16, 0x25, 0xb6, 0xc6, 0x6f, 0x37, 0x30, 0x0e, 0xe1, 0xd4, 0x40, + 0x0b, 0x03, 0xe9, 0xef, 0x40, 0x8f, 0x68, 0x5b, 0xd3, 0x8c, 0xbc, 0x1f, 0xf4, 0xe3, 0x4f, 0x2f, + 0xbc, 0x8a, 0xe2, 0xbc, 0xea, 0x8d, 0xf4, 0xb7, 0x7b, 0xc3, 0x64, 0x30, 0x00, 0x61, 0x63, 0x90, + 0x65, 0x4c, 0x29, 0x26, 0x1f, 0x15, 0xf9, 0xb8, 0xad, 0xb1, 0x5b, 0x67, 0xe5, 0x9b, 0xf9, 0x67, + 0xa2, 0xec, 0xdd, 0xfe, 0x1a, 0x70, 0xe8, 0x18, 0x97, 0xde, 0xff, 0xf2, 0x6c, 0x26, 0x8a, 0x00, + 0xf6, 0xd8, 0x61, 0x2d, 0xeb, 0xd1, 0x51, 0x7b, 0xa2, 0x92, 0x18, 0x4c, 0x84, 0x00, 0xde, 0xd0, + 0x2a, 0xaf, 0xaf, 0xff, 0x0b, 0xb2, 0x83, 0x4e, 0x71, 0xba, 0xbd, 0x6a, 0xae, 0xaf, 0x5a, 0xb6, + 0x2d, 0x9c, 0x07, 0xf9, 0x26, 0xb9, 0x30, 0xd4, 0x80, 0x07, 0x79, 0x07, 0x53, 0x3c, 0xbd, 0x15, + 0xab, 0xa9, 0x19, 0x59, 0xba, 0xba, 0xaa, 0xa9, 0x5f, 0xc1, 0x40, 0x64, 0x31, 0x7b, 0xf5, 0x17, + 0x0a, 0x33, 0x0e, 0x2a, 0x89, 0xf1, 0xd5, 0xe2, 0x7f, 0xf0, 0x24, 0x83, 0x81, 0xb9, 0xb9, 0x7b, + 0xf9, 0x28, 0x05, 0x4e, 0x00, 0xf3, 0xc3, 0xce, 0x0f, 0x7b, 0x79, 0x79, 0x7d, 0x20, 0x38, 0x88, + 0x00, 0x04, 0x00, 0xc4, 0x84, 0x9d, 0xf7, 0x7f, 0xc3, 0x44, 0x81, 0x24, 0x74, 0xdd, 0x07, 0x57, + 0xee, 0xee, 0xec, 0xf5, 0xa9, 0x79, 0xdf, 0x65, 0xe4, 0x13, 0x61, 0xc2, 0x40, 0x70, 0x1f, 0x23, + 0xd4, 0x00, 0x2d, 0xec, 0xf7, 0x5f, 0xb7, 0x77, 0xdb, 0xcf, 0x75, 0xfc, 0x38, 0xa0, 0x0c, 0xe0, + 0x00, 0x93, 0x5a, 0x8a, 0x3d, 0x3a, 0x97, 0x9d, 0xf8, 0x81, 0xe8, 0x8b, 0x71, 0xc7, 0xa2, 0x1d, + 0xc5, 0xf0, 0x5e, 0xbf, 0x0f, 0x28, 0x06, 0x03, 0xc4, 0x2f, 0x28, 0x53, 0xfb, 0xde, 0x5e, 0x58, + 0x2b, 0x61, 0x6d, 0xbe, 0x1e, 0xdf, 0x6a, 0xeb, 0x95, 0xf7, 0xf8, 0x68, 0x90, 0x22, 0xb8, 0xc3, + 0x24, 0xf5, 0x2e, 0xaf, 0xf7, 0x6c, 0xfd, 0xd6, 0xd4, 0x53, 0x61, 0x42, 0x40, 0x12, 0x64, 0xb7, + 0xd5, 0x73, 0xad, 0x5b, 0x6c, 0xff, 0xfd, 0xf0, 0xc2, 0x80, 0x1a, 0x66, 0x90, 0x14, 0x4e, 0xec, + 0xfd, 0x5f, 0xd3, 0xba, 0xbc, 0xea, 0xe2, 0x02, 0x00, 0xa6, 0x2b, 0x15, 0xbb, 0xbb, 0xe2, 0xb6, + 0xc4, 0x00, 0x38, 0x3b, 0xf0, 0x61, 0x03, 0xd0, 0xe6, 0x27, 0x81, 0xc4, 0x08, 0x23, 0x4a, 0x2b, + 0x10, 0x0f, 0x36, 0x9e, 0xe1, 0x54, 0xd4, 0xff, 0xc3, 0x3a, 0x01, 0xe2, 0xf2, 0x20, 0x3e, 0x6a, + 0xd4, 0xbc, 0x94, 0x05, 0x47, 0x69, 0x3c, 0xff, 0x0e, 0x60, 0x42, 0x8e, 0x47, 0xd5, 0xcf, 0x6f, + 0x11, 0x70, 0x5e, 0xcc, 0x2e, 0xcb, 0xfe, 0xf5, 0x4d, 0x46, 0x2a, 0x1d, 0xfe, 0x1c, 0x50, 0x01, + 0x80, 0xbc, 0x86, 0xac, 0x7c, 0xcf, 0x3f, 0xad, 0xdc, 0x4f, 0x8a, 0xcb, 0x31, 0x46, 0x58, 0x3f, + 0xa9, 0xc9, 0xf0, 0x27, 0xe0, 0xf1, 0xf2, 0x5b, 0x13, 0xa5, 0x6b, 0xf8, 0x79, 0x40, 0x13, 0x73, + 0x54, 0x00, 0xc6, 0x0b, 0xb8, 0xbb, 0xa7, 0x59, 0x79, 0xe0, 0x2e, 0x5b, 0x98, 0xbb, 0xa5, 0x5a, + 0x7f, 0x87, 0x14, 0x00, 0x45, 0x45, 0xee, 0x5f, 0xcc, 0xc5, 0x54, 0xd3, 0xac, 0xc2, 0x9c, 0x0f, + 0xb9, 0xcf, 0x4d, 0x32, 0x76, 0xf2, 0xfb, 0x2f, 0x76, 0xf6, 0x5f, 0x0f, 0x60, 0x09, 0x9a, 0xb1, + 0x45, 0xa8, 0x40, 0x57, 0xaf, 0xad, 0x6f, 0x75, 0xbf, 0x5d, 0x45, 0xe9, 0x9a, 0x1f, 0xc3, 0xae, + 0x00, 0x1e, 0xab, 0x68, 0x24, 0xcc, 0xfc, 0x7f, 0x78, 0x47, 0x97, 0xaa, 0x96, 0xcb, 0xdd, 0x54, + 0xfd, 0xb1, 0xd7, 0xd7, 0xe1, 0x90, 0x5d, 0x86, 0x40, 0x4c, 0x8b, 0x79, 0x4d, 0x3f, 0x87, 0x94, + 0x01, 0x63, 0x90, 0x17, 0x6b, 0xcf, 0x24, 0xeb, 0x22, 0x1f, 0x27, 0x3e, 0x71, 0xac, 0x5d, 0xed, + 0xcb, 0x5b, 0xce, 0xd1, 0x7f, 0x0f, 0x10, 0x40, 0x00, 0xd5, 0x46, 0x63, 0x12, 0xb1, 0xaf, 0x3d, + 0x5f, 0xd5, 0xd7, 0x7b, 0xa9, 0xf9, 0xbb, 0xfc, 0x48, 0xf3, 0xf1, 0xd3, 0xe0, 0x1c, 0xee, 0x7f, + 0x7f, 0xc0, 0x31, 0x30, 0xa4, 0x48, 0x00, 0x1f, 0xc0, 0xeb, 0x00, 0x35, 0x1d, 0x00, 0xf0, 0x9c, + 0x15, 0x3c, 0x79, 0xfe, 0x5b, 0x3f, 0xcb, 0x56, 0x78, 0x07, 0x04, 0x7c, 0x53, 0x43, 0x14, 0xc0, + 0xe9, 0x83, 0xb0, 0x99, 0x20, 0x09, 0x13, 0x68, 0x35, 0x06, 0xad, 0xcf, 0xbf, 0xbd, 0xfb, 0x78, + 0x6d, 0x40, 0x34, 0x60, 0x68, 0x06, 0x55, 0x9f, 0xfa, 0xfa, 0xfb, 0xf5, 0xac, 0x26, 0xe0, 0x48, + 0xe8, 0x4c, 0xef, 0xae, 0xb5, 0xfc, 0x2e, 0xe0, 0xb1, 0xb7, 0x96, 0x56, 0x5f, 0x65, 0x65, 0xbd, + 0xf9, 0xb0, 0xbb, 0x16, 0x08, 0x84, 0x63, 0x17, 0x4b, 0x7f, 0xbd, 0xde, 0xb5, 0xf6, 0x13, 0x64, + 0x00, 0x33, 0x9d, 0x4c, 0x88, 0x0d, 0xba, 0xf7, 0xd3, 0xeb, 0x5f, 0x8d, 0x42, 0x40, 0x20, 0x94, + 0x50, 0xeb, 0x70, 0x29, 0x8e, 0xe1, 0xe2, 0x0a, 0x00, 0x18, 0x23, 0xfa, 0xee, 0x2f, 0x11, 0x7e, + 0x6d, 0xbb, 0x76, 0xdb, 0xfb, 0x6b, 0x17, 0x02, 0xcb, 0xeb, 0xaf, 0xe0, 0x49, 0x85, 0x2d, 0xcd, + 0xee, 0x20, 0x78, 0x5a, 0xa7, 0x03, 0xc7, 0x6e, 0x2d, 0x96, 0xb0, 0x7d, 0xcf, 0x0b, 0x03, 0xdf, + 0x27, 0x03, 0x41, 0xcb, 0xe0, 0x7c, 0x00, 0x02, 0x05, 0xa3, 0xf0, 0xe6, 0x00, 0xdf, 0xde, 0xd8, + 0x4f, 0xc2, 0x7f, 0xef, 0x65, 0xb5, 0x7f, 0x2f, 0x77, 0xb9, 0x6c, 0x50, 0xcb, 0x18, 0xa1, 0xbb, + 0xb8, 0xac, 0x6a, 0x46, 0x35, 0xff, 0x0e, 0x10, 0xa0, 0x06, 0x51, 0xe0, 0x5f, 0xe6, 0x7f, 0xaa, + 0xeb, 0x7d, 0x92, 0x9a, 0x32, 0xe2, 0xee, 0x2f, 0xd7, 0xbf, 0xe1, 0x55, 0x00, 0x43, 0xc2, 0xce, + 0xa9, 0xdc, 0x97, 0x57, 0x13, 0xe2, 0xb3, 0xfd, 0xc5, 0xdc, 0x5c, 0x51, 0x96, 0x62, 0x8c, 0x53, + 0xc1, 0x88, 0x16, 0x02, 0x92, 0x70, 0x01, 0x52, 0x70, 0x54, 0x9c, 0x56, 0xa2, 0xdc, 0xbd, 0xc7, + 0x7e, 0x59, 0x8e, 0xfc, 0xb3, 0x8c, 0x56, 0x4f, 0x8c, 0x00, 0x01, 0x03, 0x55, 0x61, 0x85, 0x01, + 0x38, 0x0e, 0x76, 0x0e, 0xfb, 0x3f, 0xd6, 0xd9, 0xbd, 0xee, 0x37, 0x61, 0xa5, 0x02, 0x62, 0x38, + 0x54, 0x68, 0xfa, 0x6d, 0xff, 0xf5, 0xc0, 0x5c, 0x42, 0x91, 0x71, 0x93, 0x0e, 0x00, 0x38, 0x9c, + 0x28, 0x16, 0x18, 0x3c, 0xbb, 0x97, 0xcb, 0x31, 0x70, 0xb8, 0x1a, 0xb1, 0x7a, 0xc6, 0x83, 0x9f, + 0x04, 0xd3, 0xf8, 0x97, 0xb8, 0x91, 0xef, 0xe2, 0x47, 0xd8, 0xee, 0x85, 0x79, 0xb4, 0xe9, 0x9b, + 0x10, 0x6d, 0xe5, 0xf0, 0xee, 0x00, 0x20, 0x06, 0x23, 0x12, 0x98, 0x75, 0xa6, 0xbf, 0xb0, 0x8c, + 0x25, 0x10, 0x3b, 0x71, 0xdf, 0x96, 0xb1, 0xdf, 0x96, 0xb2, 0xf8, 0xe3, 0x2f, 0xbd, 0xc7, 0x6d, + 0x36, 0xff, 0x0f, 0x28, 0x00, 0x55, 0xb9, 0x96, 0xc4, 0x55, 0x76, 0x12, 0x67, 0x76, 0xde, 0x23, + 0xc5, 0xce, 0x3e, 0x9a, 0x64, 0xe4, 0xe5, 0xe3, 0xd7, 0x8c, 0x6e, 0x5d, 0xef, 0xf0, 0xd9, 0x20, + 0x0f, 0xe3, 0xe2, 0x1a, 0x5f, 0x8f, 0xfb, 0xbe, 0x5b, 0x64, 0x2d, 0x90, 0xb1, 0x72, 0xd8, 0x9f, + 0x8c, 0x60, 0xd0, 0x3b, 0x03, 0x87, 0x97, 0x9c, 0x3c, 0xef, 0x05, 0x35, 0x6d, 0x97, 0x7e, 0x1d, + 0x50, 0x05, 0x1e, 0x90, 0xf1, 0xde, 0xb0, 0x5d, 0xe6, 0xad, 0xdb, 0x5b, 0x3b, 0xf5, 0x8b, 0xb4, + 0xd7, 0xc3, 0x8a, 0x00, 0xc0, 0x03, 0x69, 0x7b, 0x63, 0xf2, 0x9a, 0x6c, 0x90, 0x7c, 0x05, 0xde, + 0x68, 0xa9, 0x77, 0xbf, 0x75, 0x4f, 0xe1, 0xc5, 0x00, 0x3c, 0xed, 0x30, 0xfc, 0x95, 0xbd, 0x4e, + 0xdb, 0x8b, 0xb8, 0xbd, 0xba, 0x75, 0x58, 0x25, 0xa9, 0xff, 0x87, 0x24, 0x00, 0x0e, 0xf7, 0xf8, + 0x41, 0xe7, 0x31, 0xdd, 0x1e, 0xdd, 0xcb, 0xe1, 0x0b, 0x8c, 0x61, 0xb3, 0xd1, 0xf2, 0xcf, 0x52, + 0x40, 0x6a, 0x9b, 0xdf, 0xe1, 0xe5, 0x01, 0x42, 0x40, 0xc3, 0x01, 0xf3, 0x83, 0x27, 0xfd, 0xdd, + 0xec, 0xbd, 0xdc, 0x57, 0x6e, 0x2e, 0xe2, 0xf1, 0xda, 0xae, 0xbf, 0x87, 0x99, 0x80, 0x18, 0x98, + 0x4a, 0xc9, 0x54, 0x2e, 0xd4, 0xeb, 0x3f, 0x5f, 0x81, 0x5b, 0xe2, 0xbb, 0x8a, 0xe6, 0xa0, 0x48, + 0x38, 0x7e, 0xe8, 0x8f, 0x0f, 0x86, 0xd8, 0x91, 0xf3, 0x07, 0x58, 0xce, 0xb1, 0xf3, 0xac, 0x4e, + 0xb1, 0xbd, 0xe4, 0x66, 0xfb, 0xfc, 0x38, 0x48, 0x02, 0x41, 0x09, 0x72, 0x80, 0xcf, 0xad, 0xd5, + 0xaa, 0x9b, 0xab, 0xbb, 0xab, 0xaa, 0xca, 0xac, 0x9f, 0xf7, 0xbc, 0x36, 0x88, 0x03, 0x88, 0x5a, + 0x94, 0xa0, 0x11, 0xeb, 0xb2, 0xbc, 0x57, 0x5a, 0xc4, 0xb0, 0x51, 0x5a, 0xa5, 0xfd, 0x6b, 0x09, + 0x90, 0xc0, 0x66, 0x93, 0x3f, 0xeb, 0x5f, 0x84, 0xd8, 0x90, 0x04, 0xf0, 0x9e, 0xd6, 0xd2, 0xf7, + 0xac, 0x5e, 0xee, 0xee, 0x24, 0xc1, 0xcf, 0x0c, 0x2f, 0x00, 0xb0, 0x01, 0xe4, 0x28, 0x26, 0x21, + 0xeb, 0x1b, 0xbe, 0xb1, 0x78, 0x9f, 0x4c, 0x2e, 0x79, 0x9c, 0x68, 0x31, 0x20, 0xb0, 0xbb, 0x20, + 0x1b, 0x12, 0xf7, 0xfa, 0xac, 0xaf, 0xd6, 0x39, 0x94, 0x06, 0x34, 0x1c, 0x7e, 0x9a, 0xc3, 0xb3, + 0x00, 0x0d, 0x6b, 0x6d, 0x26, 0x60, 0x47, 0xab, 0xde, 0x7e, 0x3a, 0x5d, 0xcb, 0x3f, 0x71, 0xae, + 0x15, 0xe2, 0xd7, 0x54, 0x48, 0x07, 0xc2, 0xe0, 0x1c, 0x7c, 0x3a, 0xe0, 0x0e, 0xcf, 0x73, 0xb0, + 0xff, 0xff, 0xde, 0xeb, 0xdb, 0x96, 0xcb, 0x37, 0x51, 0xdb, 0x9f, 0x88, 0xfb, 0xe2, 0xef, 0xcb, + 0x57, 0xdf, 0xe1, 0x75, 0x00, 0x26, 0xe9, 0x56, 0x60, 0x37, 0xbe, 0xde, 0xa5, 0xe2, 0x86, 0x5b, + 0xf5, 0x14, 0x31, 0x46, 0x20, 0x3c, 0xb0, 0x6a, 0xa2, 0xeb, 0x58, 0x71, 0x40, 0x08, 0x64, 0xda, + 0x11, 0x66, 0x4f, 0xf7, 0xe7, 0x8a, 0xc5, 0xe2, 0x9f, 0xc5, 0x38, 0xbf, 0x1f, 0xa2, 0xa2, 0xf8, + 0x5d, 0xc0, 0x0b, 0x37, 0x8f, 0xa6, 0x59, 0xd7, 0xf7, 0xbb, 0xab, 0xab, 0xc5, 0x71, 0x5a, 0x9f, + 0x89, 0xfb, 0xac, 0x35, 0x80, 0x4b, 0x43, 0xba, 0x35, 0x45, 0x22, 0xda, 0x88, 0x7b, 0x3c, 0x6f, + 0x18, 0xae, 0xfb, 0xde, 0xe5, 0xb0, 0xe2, 0x80, 0x13, 0xbd, 0x65, 0x80, 0x30, 0x20, 0xc2, 0xfe, + 0x72, 0xf1, 0x2f, 0x3c, 0xfb, 0xdc, 0xb1, 0x96, 0x18, 0xa0, 0xc5, 0x0f, 0xa8, 0xc5, 0xa8, 0xa8, + 0xbf, 0x0e, 0x12, 0x00, 0x35, 0xf4, 0xc6, 0xb9, 0xc2, 0x65, 0xbd, 0x5d, 0x5d, 0xe2, 0xb6, 0x42, + 0xee, 0x29, 0xb8, 0x89, 0xde, 0xff, 0x0e, 0x12, 0x01, 0xc9, 0x07, 0xb4, 0x0b, 0x7c, 0x38, 0x76, + 0x17, 0xac, 0xdd, 0xd6, 0xd7, 0x7f, 0x82, 0x5b, 0xab, 0xff, 0x08, 0x82, 0x99, 0xe3, 0xf3, 0xc7, + 0xd5, 0x6a, 0x2b, 0x8a, 0xe3, 0x46, 0x97, 0xaf, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5d, + 0x2e, 0xb0, 0xa8, 0x12, 0x74, 0x3f, 0xa0, 0x5f, 0xeb, 0xd3, 0x75, 0x8a, 0x5e, 0xaf, 0x0e, 0xf5, + 0x78, 0x47, 0xaf, 0x4f, 0xc1, 0x1d, 0x57, 0x78, 0x73, 0xab, 0x15, 0xd5, 0xa4, 0xe6, 0xbb, 0xe7, + 0xeb, 0x52, 0xf5, 0xe9, 0x07, 0x38, 0xeb, 0x70, 0xc5, 0x26, 0xea, 0xf0, 0x63, 0xd7, 0xa8, 0x62, + 0x87, 0x93, 0x3e, 0x15, 0xd7, 0xa5, 0xea, 0xf3, 0x75, 0x79, 0x7a, 0x23, 0xc6, 0x74, 0x5e, 0x84, + 0x7a, 0xbd, 0xf5, 0x7f, 0xab, 0xcb, 0xd6, 0xa2, 0x3a, 0xbc, 0x13, 0xf5, 0x7f, 0xab, 0xfc, 0xb5, + 0x55, 0x52, 0xf5, 0x79, 0x7a, 0x2f, 0x7d, 0x5a, 0xfa, 0x23, 0xd7, 0x57, 0xae, 0xaf, 0xf5, 0x79, + 0x3a, 0xbc, 0x3d, 0x02, 0x88, 0x28, 0xe0, 0x58, 0xd8, 0x43, 0x67, 0xce, 0x34, 0x5d, 0x97, 0x08, + 0x28, 0xf7, 0x1d, 0x5a, 0xf7, 0xc3, 0x5d, 0x5e, 0x6e, 0xbd, 0x3f, 0x2d, 0x55, 0x57, 0xd7, 0xa7, + 0x0c, 0xa8, 0x2e, 0xd2, 0xdf, 0xff, 0xa6, 0x9e, 0x63, 0x0c, 0x10, 0xc0, 0x3d, 0x93, 0x96, 0xff, + 0xd3, 0x4f, 0x4d, 0x36, 0xc3, 0x28, 0xe0, 0xea, 0xff, 0xf9, 0xb4, 0xdb, 0xf9, 0x63, 0x11, 0x41, + 0xd5, 0x91, 0x57, 0x31, 0xab, 0x13, 0xf8, 0x04, 0xc0, 0x32, 0xae, 0x70, 0x12, 0x01, 0x15, 0x78, + 0x67, 0xa2, 0xbd, 0x75, 0xe9, 0x46, 0x76, 0x38, 0x38, 0x03, 0x0a, 0x33, 0xf0, 0x40, 0x07, 0x95, + 0x1c, 0x6c, 0x5e, 0x12, 0xa8, 0xe1, 0x91, 0x71, 0xce, 0x17, 0x03, 0x4d, 0xf0, 0xf1, 0x20, 0x4b, + 0x79, 0x4a, 0x9f, 0xff, 0xf8, 0x21, 0xb4, 0xd7, 0xf0, 0x92, 0x28, 0x0f, 0xae, 0x27, 0x93, 0x26, + 0xdb, 0xfe, 0x21, 0x5e, 0x25, 0x14, 0x1d, 0x59, 0x80, 0x90, 0x10, 0x6d, 0xee, 0x4e, 0x89, 0xdc, + 0x22, 0x05, 0x10, 0x58, 0x4d, 0xc5, 0x6a, 0xaa, 0xb7, 0xb8, 0xec, 0xdc, 0x04, 0x08, 0x0d, 0x90, + 0x58, 0x64, 0x8b, 0x82, 0xb2, 0xc0, 0x6b, 0x58, 0xac, 0x50, 0x18, 0xac, 0x50, 0x18, 0x20, 0x00, + 0x08, 0xc6, 0x80, 0x70, 0xc2, 0x20, 0x0c, 0xcc, 0x17, 0x20, 0x20, 0x1f, 0xde, 0xbe, 0x98, 0xb6, + 0x9a, 0x6a, 0xaa, 0xaa, 0xaa, 0xa3, 0xbb, 0x0e, 0x23, 0x00, 0x2a, 0x3e, 0x67, 0x6d, 0x1c, 0x64, + 0x1c, 0x0b, 0x56, 0x27, 0x5a, 0x85, 0xc0, 0xfc, 0xa9, 0xd6, 0x4a, 0xcf, 0x1e, 0x29, 0xad, 0xe5, + 0x77, 0x18, 0x35, 0x34, 0xeb, 0x6f, 0x87, 0x14, 0x01, 0x95, 0x30, 0x96, 0xce, 0x6d, 0x5f, 0xef, + 0x55, 0xb7, 0xc5, 0x58, 0xa2, 0xd3, 0x06, 0x69, 0x73, 0x8d, 0x36, 0xf4, 0xc5, 0xb2, 0x26, 0x9f, + 0xd3, 0x87, 0x11, 0x00, 0x02, 0x8b, 0x62, 0x51, 0x27, 0xf1, 0x29, 0x53, 0x55, 0x36, 0xde, 0x0d, + 0x3f, 0x17, 0x4b, 0xa1, 0x41, 0x17, 0xe3, 0x03, 0xfb, 0x5f, 0x59, 0xc3, 0xee, 0x6e, 0x6d, 0xff, + 0x81, 0x80, 0x04, 0xc8, 0x2c, 0x2a, 0xca, 0x8b, 0x81, 0xcb, 0x00, 0x1a, 0x87, 0x38, 0x6a, 0x51, + 0x00, 0x01, 0x00, 0xb5, 0x25, 0x00, 0x03, 0x6a, 0x3f, 0xd3, 0xcf, 0x25, 0x00, 0x05, 0x4a, 0x3a, + 0x8a, 0xf3, 0x0b, 0xb1, 0x60, 0x02, 0x10, 0x48, 0xef, 0x21, 0xa2, 0xad, 0xbf, 0xf1, 0xcf, 0xc1, + 0xcf, 0xf4, 0xe5, 0x4e, 0x07, 0x8a, 0x17, 0xdf, 0x5e, 0x97, 0xaf, 0x57, 0x44, 0xeb, 0xe8, 0xbd, + 0x5d, 0x7a, 0x37, 0xab, 0xca, 0x1b, 0xc0, 0x48, 0x3a, 0x4e, 0x6b, 0xff, 0xe9, 0xf2, 0x51, 0xfe, + 0xdc, 0x24, 0xa0, 0xf1, 0xf3, 0xa7, 0xf4, 0xd3, 0x8d, 0x52, 0x45, 0x19, 0x51, 0x88, 0xb4, 0x7e, + 0x39, 0x88, 0x09, 0x44, 0x55, 0xc8, 0x6e, 0x31, 0x51, 0xcc, 0xa0, 0x1f, 0x64, 0xeb, 0x92, 0x31, + 0xc6, 0x60, 0x18, 0xd1, 0xf3, 0x3c, 0x52, 0x1f, 0x16, 0xc8, 0x09, 0x80, 0x51, 0x28, 0x15, 0xfc, + 0x73, 0x28, 0x65, 0x88, 0x18, 0xa6, 0x28, 0x84, 0x1e, 0x58, 0xe5, 0x09, 0x6a, 0xb0, 0x62, 0x98, + 0xa2, 0x41, 0xb7, 0x93, 0xe8, 0xbd, 0x8b, 0x20, 0xa0, 0x0d, 0xe8, 0x23, 0xa4, 0x86, 0x31, 0xbc, + 0x71, 0x08, 0x01, 0x31, 0xf0, 0x88, 0x05, 0xad, 0xc7, 0x43, 0xf1, 0xcc, 0x80, 0x94, 0x24, 0x03, + 0x49, 0x76, 0x1a, 0x24, 0x01, 0xbd, 0x94, 0x04, 0x0a, 0x71, 0xaa, 0xff, 0x4d, 0x35, 0xfe, 0x8c, + 0x54, 0x30, 0x42, 0x80, 0x30, 0xe2, 0xc0, 0x68, 0x7e, 0x9e, 0xdb, 0x7f, 0xf8, 0xda, 0x2a, 0x86, + 0x89, 0x00, 0x8f, 0x36, 0x47, 0xd5, 0xf1, 0xde, 0xff, 0xf2, 0xc3, 0x51, 0x00, 0x08, 0x51, 0x6f, + 0xfe, 0xc1, 0x17, 0xa1, 0x4f, 0xda, 0xde, 0x6f, 0xfe, 0x4e, 0x7a, 0xdf, 0xf6, 0x39, 0x1c, 0x05, + 0x6f, 0x95, 0x21, 0xb8, 0xd2, 0xb0, 0xc0, 0x18, 0x41, 0x5c, 0x61, 0x71, 0xef, 0x8a, 0x31, 0x00, + 0xf2, 0xc1, 0x88, 0x00, 0x79, 0x60, 0x31, 0x5c, 0x57, 0x1d, 0x8f, 0x84, 0xba, 0x08, 0xf4, 0x64, + 0x04, 0x08, 0x12, 0x0b, 0x55, 0x55, 0x8e, 0x50, 0x92, 0xcd, 0xcd, 0x8d, 0x94, 0x1e, 0xfa, 0x45, + 0x11, 0x20, 0x38, 0x97, 0x8b, 0x44, 0x02, 0xeb, 0x05, 0x70, 0x0b, 0x0c, 0x10, 0x38, 0xe2, 0x14, + 0x20, 0xaa, 0xe0, 0x8c, 0xea, 0x12, 0x44, 0x09, 0x5a, 0x90, 0x21, 0x97, 0xd3, 0xf8, 0xe2, 0x42, + 0x55, 0x15, 0x50, 0x60, 0xfc, 0x38, 0xa0, 0x45, 0xa6, 0xfc, 0xb4, 0xd3, 0xb6, 0x9f, 0xfc, 0x5a, + 0xf2, 0x9a, 0x7f, 0xc7, 0x10, 0x80, 0x60, 0xd2, 0x2e, 0xc4, 0x28, 0x13, 0x36, 0x90, 0x6d, 0x80, + 0x40, 0x00, 0x22, 0x00, 0xac, 0xba, 0xaa, 0xee, 0xee, 0xe2, 0xbf, 0x61, 0x12, 0x40, 0x44, 0x7a, + 0x4f, 0xc1, 0xab, 0x76, 0xdb, 0xf2, 0x06, 0xa6, 0x00, 0x34, 0x7f, 0x20, 0x75, 0xbb, 0x77, 0xff, + 0xb6, 0xde, 0x56, 0xc3, 0x44, 0x30, 0x02, 0x47, 0xd0, 0x8b, 0x6b, 0xe7, 0xff, 0xb6, 0xde, 0xdb, + 0x7a, 0x47, 0x0d, 0x12, 0x00, 0xa3, 0xe0, 0x4b, 0x07, 0x7e, 0x93, 0x4f, 0x4d, 0x3d, 0xb6, 0xf6, + 0xdb, 0xb6, 0x9d, 0x42, 0xe4, 0x20, 0x00, 0x55, 0x66, 0xc0, 0x39, 0xb5, 0x38, 0x63, 0x55, 0xd9, + 0x53, 0x5d, 0xee, 0x2a, 0xc1, 0x8a, 0x53, 0xf2, 0xac, 0xbc, 0x5c, 0x06, 0x50, 0x54, 0x6e, 0x47, + 0x70, 0xc1, 0x06, 0x81, 0xa0, 0x61, 0xcf, 0xf6, 0x9a, 0x7f, 0xd3, 0x2e, 0xc5, 0xba, 0x62, 0x96, + 0x29, 0x63, 0x28, 0x19, 0x78, 0x61, 0x41, 0x8c, 0x47, 0xff, 0xed, 0xb6, 0x9a, 0x7c, 0xca, 0x17, + 0x8c, 0x01, 0x86, 0x80, 0x0c, 0xed, 0x5a, 0xba, 0x6f, 0xae, 0xfd, 0x3a, 0x8b, 0x21, 0x40, 0x5f, + 0xb3, 0x0d, 0x26, 0xc5, 0x63, 0x3f, 0x8f, 0x63, 0x43, 0x42, 0x4a, 0x81, 0x0d, 0xeb, 0xe1, 0x6e, + 0x8a, 0xf3, 0xc1, 0x0c, 0x71, 0x6b, 0x59, 0x33, 0x7b, 0xe1, 0x45, 0x0a, 0x72, 0xf6, 0xdb, 0xff, + 0xe1, 0x47, 0xa6, 0x9e, 0x9a, 0x7f, 0xfc, 0x74, 0x50, 0x44, 0x08, 0xa6, 0x91, 0xa0, 0x87, 0x1d, + 0x84, 0xca, 0x4e, 0x46, 0x0a, 0x87, 0x14, 0x10, 0xfa, 0xe3, 0xff, 0xf4, 0xd3, 0xbf, 0xf4, 0xf1, + 0xa4, 0x28, 0x37, 0x4b, 0x1a, 0x31, 0x5a, 0x8c, 0x53, 0xc7, 0x23, 0x2a, 0x31, 0x1c, 0x13, 0x80, + 0xcf, 0x44, 0x4a, 0xa3, 0x09, 0xa4, 0xc5, 0x22, 0x31, 0xe0, 0x10, 0x10, 0x34, 0x86, 0x2e, 0xee, + 0xfb, 0xbe, 0xdf, 0x3f, 0x6d, 0xf1, 0x78, 0x97, 0x4c, 0xc6, 0x28, 0xb8, 0x21, 0x04, 0x42, 0x04, + 0x8e, 0x09, 0x00, 0x1c, 0x9f, 0x3d, 0x85, 0x22, 0x80, 0x0b, 0xce, 0x42, 0xe1, 0xd0, 0x5f, 0x6b, + 0x6d, 0xbb, 0x62, 0xac, 0x55, 0xff, 0xc3, 0x08, 0x80, 0x09, 0x52, 0x1d, 0x6a, 0x6a, 0x07, 0x60, + 0xd7, 0x9a, 0x65, 0xb6, 0xe4, 0xff, 0x37, 0x77, 0xf3, 0xe9, 0xee, 0xf9, 0x61, 0xe9, 0x00, 0x08, + 0x63, 0xb5, 0x82, 0xe7, 0x46, 0xb8, 0x92, 0x0b, 0xfd, 0x18, 0xb6, 0x7f, 0xba, 0x82, 0xda, 0x65, + 0xda, 0x6f, 0xd1, 0x50, 0x60, 0xc5, 0xb2, 0xec, 0x58, 0x00, 0x76, 0x01, 0x7b, 0xb0, 0x2e, 0xdd, + 0xbf, 0x7b, 0x7f, 0x0e, 0x28, 0x04, 0x9f, 0x0b, 0x05, 0x1d, 0x53, 0x4d, 0x34, 0xd3, 0x4d, 0x35, + 0x52, 0xca, 0x2a, 0x58, 0xbb, 0x50, 0xca, 0x72, 0xd5, 0x4b, 0x76, 0x93, 0x83, 0x2c, 0xb0, 0x5a, + 0xff, 0x6f, 0x01, 0x41, 0x0a, 0x14, 0x50, 0x06, 0x0d, 0x75, 0x0b, 0xaa, 0x4e, 0x15, 0x8c, 0x1a, + 0x11, 0x54, 0xe3, 0xc7, 0x09, 0x78, 0x71, 0x30, 0x94, 0xf0, 0x00, 0x25, 0x83, 0x80, 0x20, 0x03, + 0x60, 0x70, 0x60, 0x03, 0x29, 0x30, 0x01, 0x51, 0xc3, 0xf8, 0x71, 0x40, 0x01, 0x28, 0xa8, 0x06, + 0x20, 0x38, 0x30, 0x58, 0xe1, 0xa2, 0x1c, 0x04, 0xf4, 0xe1, 0x20, 0x2d, 0x6b, 0xf4, 0xe9, 0xff, + 0xeb, 0x16, 0xe0, 0x08, 0x6f, 0x86, 0x82, 0x04, 0x97, 0x86, 0x58, 0xd7, 0xbc, 0x9d, 0x15, 0xe3, + 0xfa, 0xb5, 0xf5, 0xa8, 0x81, 0xd1, 0x00, 0xbb, 0x7c, 0x95, 0x44, 0x2b, 0x58, 0x30, 0x01, 0xf0, + 0x34, 0xa2, 0xbb, 0xd4, 0x5e, 0xb5, 0x55, 0x55, 0xc4, 0x00, 0x02, 0x40, 0x3a, 0x0c, 0x06, 0x35, + 0x34, 0xd3, 0x16, 0xfe, 0x18, 0xc0, 0xdc, 0xfb, 0x4d, 0x34, 0xd3, 0x4d, 0x3f, 0xf0, 0x53, 0x11, + 0xdc, 0x72, 0x83, 0xb7, 0xac, 0x6a, 0x28, 0x87, 0x0e, 0xc4, 0xa5, 0x18, 0x42, 0xc6, 0x51, 0x54, + 0x64, 0x80, 0xea, 0xf1, 0x62, 0x09, 0x29, 0x28, 0x99, 0x41, 0xef, 0xc5, 0xe1, 0xef, 0x16, 0x67, + 0xe8, 0x9a, 0x98, 0x62, 0xeb, 0x1a, 0x82, 0x31, 0x16, 0x98, 0xc4, 0x30, 0x37, 0xe1, 0xdb, 0x80, + 0xb1, 0x82, 0x32, 0x27, 0x27, 0x93, 0xe1, 0x44, 0x28, 0x00, 0x40, 0x2d, 0x76, 0x86, 0xba, 0xdb, + 0x5e, 0x54, 0x18, 0xac, 0x80, 0x31, 0x7f, 0xfe, 0x18, 0x46, 0x03, 0x5d, 0x9c, 0x37, 0xe3, 0x26, + 0xe2, 0x3a, 0x20, 0xeb, 0x75, 0xff, 0x8e, 0xe3, 0x81, 0x20, 0x04, 0xc8, 0x21, 0x38, 0x90, 0x07, + 0x05, 0x06, 0xfc, 0xb1, 0xa3, 0x4f, 0xd0, 0xb7, 0x89, 0xea, 0xd3, 0x70, 0x49, 0x7d, 0x5e, 0x4e, + 0xac, 0x4b, 0xc9, 0x55, 0x55, 0x9c, 0x90, 0xe3, 0xd8, 0x31, 0x01, 0xf2, 0x09, 0x60, 0xf1, 0x61, + 0xc7, 0x2b, 0x55, 0x54, 0x6a, 0xbc, 0x95, 0x55, 0x5f, 0x75, 0x55, 0x59, 0xc8, 0x53, 0xc1, 0xc0, + 0x80, 0x21, 0x76, 0xe0, 0x41, 0x13, 0x10, 0x2c, 0x9c, 0x9d, 0x43, 0xc8, 0x60, 0x00, 0x8a, 0xd4, + 0x9b, 0xd2, 0x7a, 0xff, 0xfa, 0xc4, 0x7a, 0x6f, 0xf7, 0x86, 0xf0, 0x01, 0x49, 0x73, 0xc2, 0xa6, + 0x38, 0xa2, 0x7f, 0xe9, 0xbc, 0x62, 0x1f, 0xe5, 0x4e, 0x9f, 0xe3, 0x22, 0xc3, 0x8f, 0x20, 0x85, + 0x43, 0x71, 0x40, 0x05, 0x2f, 0x2f, 0x0b, 0x1f, 0x5f, 0xff, 0xdc, 0x10, 0x03, 0x11, 0x96, 0xbd, + 0xf1, 0xc4, 0x38, 0xe4, 0x68, 0x89, 0xa2, 0xbc, 0x0c, 0x00, 0x58, 0x05, 0x07, 0x15, 0xbd, 0xdc, + 0x56, 0xe2, 0xb1, 0x1d, 0xd0, 0x57, 0xd1, 0x9e, 0xce, 0xb8, 0xc9, 0xe3, 0x14, 0xc7, 0xa8, 0x71, + 0xe2, 0xa5, 0x34, 0xd3, 0x4f, 0xf0, 0x16, 0x20, 0xa4, 0x16, 0x06, 0x20, 0xe8, 0x5c, 0xfc, 0xf0, + 0xf8, 0x32, 0xd6, 0x50, 0x80, 0xd4, 0x94, 0x01, 0x53, 0x87, 0x49, 0x40, 0x00, 0xaa, 0x8e, 0x0f, + 0xfd, 0x85, 0xf0, 0x0c, 0x1a, 0x1b, 0xe4, 0x28, 0xe7, 0xab, 0xd7, 0xdf, 0xcb, 0x6e, 0x5b, 0x7f, + 0x4a, 0xa1, 0xe6, 0x3c, 0x23, 0x31, 0xd7, 0xff, 0xf0, 0xae, 0xe0, 0x79, 0xcd, 0xfe, 0xf0, 0xf1, + 0x05, 0x00, 0x0e, 0x9d, 0x68, 0x62, 0xd0, 0xc5, 0x03, 0xdb, 0xa7, 0xa8, 0xad, 0x44, 0x0f, 0x52, + 0x79, 0x3b, 0xd9, 0xc9, 0x1c, 0x4d, 0x8b, 0xe3, 0x0e, 0xfd, 0x7c, 0x09, 0x00, 0x79, 0x04, 0x67, + 0x16, 0x75, 0x32, 0x80, 0x27, 0x5f, 0xb1, 0x84, 0x16, 0x17, 0x7e, 0xef, 0x9a, 0xaa, 0xaa, 0x0b, + 0xc3, 0x08, 0x70, 0x00, 0xff, 0xa4, 0x9b, 0xe2, 0x2f, 0xff, 0xfd, 0xb6, 0xfa, 0xc4, 0x79, 0x84, + 0xfc, 0x03, 0x90, 0x01, 0x40, 0x1a, 0x60, 0x6c, 0x05, 0x48, 0xca, 0x10, 0x96, 0xcf, 0x3e, 0x5d, + 0xf1, 0xf7, 0x2d, 0xc6, 0x21, 0xee, 0xe9, 0xd6, 0x98, 0x16, 0x20, 0x63, 0x00, 0xdb, 0x7b, 0xfc, + 0x36, 0xe0, 0x0a, 0x4e, 0xc8, 0x61, 0xde, 0xb7, 0xbd, 0xef, 0x2f, 0x4d, 0xe5, 0xe9, 0xfb, 0xb7, + 0xeb, 0x82, 0x18, 0x27, 0x12, 0xeb, 0x53, 0x37, 0xf2, 0xf2, 0x50, 0x68, 0x20, 0x78, 0x3e, 0xc1, + 0xa8, 0x58, 0x8a, 0xc3, 0x52, 0x00, 0x39, 0x6b, 0x0c, 0x13, 0x26, 0x1e, 0x79, 0x72, 0x79, 0xdd, + 0x10, 0xac, 0xbe, 0x77, 0xbc, 0x50, 0x6e, 0x28, 0x33, 0x45, 0x86, 0x0e, 0x40, 0xf0, 0x0a, 0xe6, + 0x80, 0x50, 0xe6, 0x0f, 0x85, 0x54, 0xac, 0x39, 0x21, 0xd0, 0xf7, 0x83, 0xf9, 0xa8, 0xff, 0x9b, + 0x0d, 0x82, 0x5a, 0x05, 0x71, 0xb0, 0x43, 0x02, 0x84, 0x82, 0x21, 0x51, 0xc4, 0x1f, 0x8e, 0xe8, + 0x25, 0xd0, 0xc4, 0x21, 0x57, 0xa0, 0xf4, 0x60, 0x06, 0x0e, 0x49, 0xd3, 0x93, 0x4f, 0x4e, 0x3d, + 0xff, 0x8d, 0x91, 0x76, 0xb1, 0x7b, 0xdf, 0x11, 0x0a, 0x62, 0x1f, 0x15, 0x9f, 0xe3, 0xdf, 0x3f, + 0xcb, 0xb2, 0xf7, 0xf1, 0xc5, 0x2a, 0xaf, 0x0e, 0x8b, 0x96, 0x59, 0xe1, 0xe3, 0x9b, 0x8e, 0x31, + 0x81, 0xc3, 0xc4, 0x30, 0x1e, 0x38, 0x4a, 0x7a, 0x56, 0x9b, 0xe3, 0x5a, 0xe4, 0x86, 0xb5, 0x07, + 0x10, 0x0a, 0x3b, 0x7b, 0xfe, 0x1e, 0xc0, 0x1d, 0x87, 0x61, 0x33, 0x3a, 0x9e, 0xce, 0xce, 0xb3, + 0xea, 0xaa, 0xa2, 0x52, 0xcd, 0x62, 0xf7, 0xbe, 0x02, 0x84, 0x20, 0x34, 0xa7, 0x03, 0xa5, 0x99, + 0x40, 0x7a, 0xcb, 0x83, 0x00, 0x42, 0x28, 0x80, 0x1c, 0x28, 0x02, 0xca, 0x38, 0x2f, 0xf1, 0xc4, + 0x3e, 0xe2, 0x80, 0x0c, 0xb0, 0x58, 0x80, 0x00, 0x78, 0xa0, 0x2a, 0xa0, 0x38, 0x87, 0x04, 0x06, + 0x2b, 0x8a, 0xff, 0x81, 0x80, 0x32, 0x14, 0xac, 0x00, 0x88, 0x85, 0xa4, 0x8a, 0x1c, 0x2d, 0xea, + 0x21, 0xc8, 0x8c, 0x09, 0x9c, 0x7f, 0xa1, 0x00, 0xce, 0x3e, 0x3e, 0xa6, 0xa5, 0x47, 0x06, 0x3f, + 0x84, 0x33, 0xf4, 0x11, 0x72, 0x0a, 0x60, 0x59, 0x06, 0x00, 0x9c, 0x71, 0x78, 0x31, 0x3a, 0x43, + 0xf7, 0x45, 0x0f, 0xce, 0x8a, 0x3c, 0x36, 0x04, 0xb8, 0x2f, 0x86, 0xdc, 0x20, 0x43, 0x47, 0x72, + 0xec, 0xef, 0x7d, 0x6b, 0x6f, 0x6e, 0xea, 0xe4, 0x80, 0xfd, 0xfe, 0xb0, 0xb9, 0x0c, 0x05, 0xb2, + 0x30, 0x68, 0xb3, 0x7b, 0xfd, 0xd9, 0x3e, 0xfa, 0xe0, 0xc0, 0x1c, 0x82, 0xc9, 0x58, 0x2c, 0xca, + 0xc1, 0x7d, 0x62, 0xf0, 0x6a, 0x9a, 0x88, 0x1b, 0x10, 0x6c, 0x2e, 0x43, 0x80, 0x36, 0xfa, 0x04, + 0xf5, 0x08, 0x0a, 0x7a, 0xbd, 0xa1, 0xd1, 0x32, 0x12, 0xc8, 0x4d, 0x0e, 0x86, 0x5e, 0xa2, 0xe2, + 0xec, 0xe0, 0xc0, 0x10, 0x04, 0x0c, 0x3c, 0x02, 0xea, 0x68, 0x39, 0x0b, 0x92, 0x8d, 0x0a, 0x65, + 0x1d, 0x1f, 0x1c, 0x9f, 0x1d, 0x07, 0xf3, 0xf8, 0x31, 0x81, 0x06, 0x08, 0x31, 0x43, 0x19, 0xa1, + 0xe7, 0xd6, 0xa3, 0xcf, 0xbd, 0x92, 0x90, 0x74, 0x2a, 0xf4, 0x1c, 0x63, 0x9f, 0xba, 0xba, 0xc2, + 0xc4, 0x38, 0x05, 0x82, 0x5e, 0xed, 0x2c, 0x5c, 0xc5, 0x65, 0xe7, 0x83, 0x21, 0x2f, 0xbd, 0x29, + 0x65, 0x85, 0xd8, 0x80, 0x24, 0x16, 0x34, 0x96, 0x5e, 0xeb, 0x5c, 0x57, 0x15, 0x8b, 0xc5, 0xfd, + 0x86, 0xd9, 0x41, 0x3a, 0x24, 0x89, 0x7a, 0xba, 0xbf, 0x8b, 0xb8, 0xbb, 0xc7, 0x6b, 0x59, 0xe1, + 0x3c, 0x21, 0x77, 0x0e, 0xab, 0x2b, 0x5a, 0xd6, 0xb5, 0x75, 0x75, 0xec, 0x2e, 0x42, 0x01, 0x41, + 0x64, 0x1a, 0xa0, 0xb3, 0xfe, 0xae, 0xa2, 0xbf, 0x78, 0x28, 0xe8, 0x5f, 0x44, 0xc3, 0x20, 0xe4, + 0x28, 0x28, 0x5c, 0x4f, 0xac, 0x96, 0x19, 0x61, 0x8b, 0x8b, 0x8b, 0x97, 0x88, 0x0f, 0x40, 0x02, + 0xa6, 0x66, 0x4b, 0x6b, 0x68, 0x0c, 0xb0, 0x98, 0x4d, 0x89, 0x00, 0xa8, 0x3e, 0xe8, 0x82, 0xce, + 0xe2, 0xf1, 0x7d, 0xf8, 0x8c, 0x22, 0x30, 0xc3, 0x68, 0x40, 0x00, 0xd1, 0x0d, 0x05, 0x7d, 0x51, + 0xb2, 0x14, 0x79, 0x5e, 0xfe, 0x88, 0x1a, 0xf8, 0x2c, 0x1f, 0x02, 0xd6, 0x2a, 0xf8, 0x42, 0x0b, + 0x1c, 0x5b, 0xc1, 0xb5, 0xc5, 0x81, 0x7f, 0x0d, 0xe0, 0x03, 0x6f, 0x68, 0x4a, 0x51, 0xd8, 0x71, + 0xea, 0xf7, 0xeb, 0x15, 0x62, 0xaf, 0x13, 0xf1, 0x4f, 0xad, 0x45, 0x02, 0xc1, 0x97, 0xd7, 0xe1, + 0x66, 0x24, 0x2e, 0x53, 0x17, 0xbf, 0xff, 0xe2, 0x21, 0x01, 0x42, 0x43, 0xcb, 0x00, 0xc4, 0xf9, + 0x66, 0xb6, 0x31, 0x00, 0xfc, 0xfe, 0x0c, 0x21, 0x18, 0x5c, 0xfc, 0xde, 0x0e, 0x8b, 0xc2, 0xe0, + 0x1a, 0x01, 0x2a, 0x62, 0x18, 0x44, 0x03, 0x0f, 0xc0, 0x70, 0x01, 0x80, 0x29, 0x06, 0x40, 0x01, + 0x2b, 0x80, 0xd0, 0xa4, 0x02, 0x58, 0x8b, 0xe6, 0xa5, 0x21, 0x2d, 0x94, 0x92, 0x96, 0x0f, 0x12, + 0xf5, 0x01, 0xc0, 0x46, 0x81, 0xc2, 0x6c, 0xa0, 0x17, 0x2a, 0x98, 0x15, 0x47, 0xba, 0xdf, 0x7e, + 0xb5, 0xc3, 0xcc, 0x40, 0x00, 0x7b, 0xa3, 0x32, 0x00, 0x3e, 0x23, 0x06, 0x2e, 0x84, 0xb7, 0x08, + 0x9d, 0x11, 0xeb, 0x83, 0xd7, 0x3b, 0xce, 0xf2, 0x43, 0x44, 0x78, 0x8b, 0x97, 0xbb, 0x9f, 0xe2, + 0xf9, 0xa5, 0xed, 0xaf, 0xe1, 0xe7, 0x00, 0x18, 0xa9, 0x81, 0x96, 0x25, 0x52, 0x3c, 0x84, 0x3c, + 0x43, 0xcb, 0x65, 0xb2, 0xcd, 0xc5, 0xc5, 0x62, 0xb7, 0x3d, 0xf6, 0xa2, 0xb5, 0x15, 0x86, 0xb2, + 0x8c, 0xdb, 0x7c, 0x5e, 0x97, 0xc2, 0xf1, 0x20, 0x80, 0x05, 0x07, 0x56, 0xc9, 0xef, 0xee, 0xee, + 0xe7, 0x85, 0xee, 0x40, 0xf8, 0x46, 0x34, 0x41, 0xf9, 0x66, 0xff, 0xc7, 0x15, 0xcf, 0x79, 0x79, + 0x63, 0x1e, 0xf9, 0xe3, 0xe3, 0xa3, 0xf0, 0x67, 0x6c, 0xfe, 0x66, 0x3c, 0x18, 0x44, 0x08, 0x0b, + 0x9c, 0x4f, 0x83, 0xb4, 0x01, 0x28, 0xd8, 0xdc, 0x4a, 0x47, 0xfd, 0xc7, 0x9f, 0x02, 0x40, 0x00, + 0x88, 0x46, 0x24, 0x01, 0xf1, 0x40, 0x1f, 0xc2, 0xee, 0x1f, 0xbe, 0x11, 0x43, 0x85, 0xee, 0x51, + 0x68, 0xbe, 0xb9, 0x77, 0xbe, 0xb0, 0x9b, 0x80, 0x0d, 0x2f, 0x41, 0x8f, 0x77, 0x08, 0x3d, 0x5e, + 0x96, 0x11, 0x5f, 0x5b, 0x88, 0x06, 0x0e, 0x58, 0x39, 0xae, 0x1b, 0x64, 0x00, 0x70, 0x56, 0xe0, + 0x81, 0xf5, 0xd7, 0xa7, 0x5e, 0x3b, 0x35, 0x6b, 0xf8, 0x6d, 0xc0, 0x15, 0x18, 0xe6, 0x15, 0x67, + 0x64, 0x89, 0xd1, 0x55, 0x95, 0x90, 0x3f, 0x86, 0x14, 0x18, 0x62, 0x62, 0xf1, 0x7f, 0x85, 0xc8, + 0x70, 0x81, 0x31, 0x3e, 0x28, 0xa8, 0xbe, 0x58, 0x3b, 0x61, 0x55, 0xdf, 0x0d, 0xb1, 0x00, 0x18, + 0x35, 0xe9, 0x6d, 0xf7, 0xbf, 0x7b, 0xf7, 0x71, 0xba, 0x58, 0x3a, 0x08, 0x87, 0x68, 0x7f, 0xa1, + 0x6f, 0x05, 0xfc, 0x2e, 0x48, 0x39, 0x1f, 0x83, 0xcf, 0xc1, 0xa4, 0xe9, 0x1c, 0x9f, 0x10, 0x00, + 0x09, 0x86, 0xb1, 0x40, 0x1c, 0x50, 0x07, 0xf0, 0xbb, 0x90, 0x02, 0xc0, 0xe6, 0x5a, 0x2a, 0x2a, + 0xd7, 0x45, 0x45, 0x5a, 0x8f, 0xb0, 0x9b, 0x20, 0x03, 0x0c, 0x65, 0xf4, 0x4e, 0x69, 0xe7, 0x64, + 0xe0, 0xed, 0x04, 0x5e, 0x2b, 0x1d, 0x28, 0x05, 0x86, 0xe0, 0xe8, 0x50, 0xf8, 0x6d, 0xc0, 0x0a, + 0xbc, 0xb1, 0x39, 0x85, 0x8f, 0x2e, 0xa4, 0xe9, 0xea, 0xe6, 0xe7, 0xee, 0xe6, 0xf5, 0xbb, 0xd6, + 0x31, 0x77, 0x24, 0x53, 0xf8, 0x6d, 0xc0, 0x19, 0xc3, 0xc1, 0x28, 0xa9, 0xfb, 0x49, 0x92, 0x34, + 0xfb, 0xbb, 0x65, 0x8b, 0x6d, 0x8d, 0x77, 0x77, 0x23, 0x6c, 0x64, 0x8d, 0x1f, 0xc2, 0xe4, 0x28, + 0x02, 0xdc, 0x2e, 0xb8, 0x88, 0xb2, 0xb5, 0x24, 0x15, 0x90, 0xeb, 0x17, 0x2f, 0x89, 0xc2, 0xf8, + 0x6d, 0x98, 0x01, 0x24, 0x76, 0x5d, 0x19, 0x65, 0x65, 0xae, 0xca, 0xc9, 0x6a, 0xa5, 0x4f, 0x2c, + 0x3f, 0xd0, 0x9e, 0x93, 0xa2, 0xc5, 0x04, 0x7c, 0xdd, 0x24, 0x84, 0x70, 0xb9, 0xa1, 0x73, 0x5a, + 0x9e, 0x59, 0x81, 0xd1, 0x2d, 0x25, 0x42, 0xf4, 0x10, 0x00, 0x46, 0xb1, 0x40, 0x1c, 0x50, 0x07, + 0xf0, 0xbb, 0x88, 0x52, 0xc0, 0x1c, 0x9b, 0xff, 0xfd, 0x77, 0xc2, 0x6c, 0xc0, 0x1d, 0x4e, 0xc3, + 0x41, 0x2d, 0x43, 0x8f, 0x7f, 0xa5, 0xb3, 0xb0, 0x14, 0x19, 0xd8, 0x78, 0x5c, 0x07, 0x07, 0x60, + 0x38, 0x8e, 0x07, 0x60, 0xfb, 0x78, 0x6d, 0xc0, 0x04, 0xef, 0x8c, 0x46, 0x7e, 0x27, 0x43, 0xcc, + 0x24, 0x7b, 0x20, 0x28, 0xd9, 0x0e, 0x9a, 0x60, 0xeb, 0x82, 0x8c, 0x16, 0x93, 0x21, 0x1a, 0x7c, + 0x09, 0x5d, 0x23, 0xf0, 0xa3, 0x73, 0xf8, 0x6d, 0xc0, 0x14, 0xcc, 0x11, 0x02, 0xcd, 0x66, 0x5d, + 0x34, 0xd7, 0xa6, 0x5f, 0x7d, 0xe0, 0xbb, 0xb7, 0x34, 0x2f, 0xe1, 0x36, 0x50, 0x13, 0x00, 0x55, + 0x70, 0xd3, 0xb3, 0xd9, 0x41, 0xd7, 0x0d, 0x6a, 0x78, 0x30, 0x44, 0x70, 0x0b, 0x0c, 0x84, 0x36, + 0x48, 0x02, 0x6e, 0x0d, 0x6b, 0x10, 0x5f, 0x8b, 0x0b, 0x2c, 0x2c, 0x8c, 0x6c, 0x62, 0x73, 0x0b, + 0x39, 0x85, 0x9d, 0x62, 0x71, 0x61, 0x31, 0x00, 0xcd, 0x3c, 0x19, 0x03, 0xc3, 0xff, 0x45, 0x02, + 0x13, 0xa0, 0x9f, 0xaf, 0x44, 0x42, 0x22, 0x06, 0xf7, 0x73, 0x73, 0xc2, 0xcb, 0xb9, 0xe1, 0x64, + 0x43, 0xcf, 0x79, 0x7b, 0xfc, 0x8e, 0x93, 0x31, 0x0e, 0xa6, 0x40, 0xa0, 0x16, 0x5c, 0x50, 0x1b, + 0x21, 0x41, 0xfc, 0x26, 0xc8, 0x00, 0x17, 0x31, 0x4b, 0x5c, 0xe4, 0xd1, 0x7e, 0xd7, 0xde, 0x1c, + 0x05, 0x71, 0xf7, 0x86, 0xec, 0x1a, 0x6a, 0x50, 0x00, 0x26, 0xb3, 0x01, 0x40, 0x03, 0xe0, 0x69, + 0x03, 0x47, 0x0d, 0x0f, 0x18, 0x29, 0x47, 0xbe, 0x4b, 0x0b, 0xfc, 0xb0, 0x62, 0x05, 0x92, 0xc0, + 0x67, 0x00, 0xb2, 0xf7, 0x9c, 0x0f, 0x2e, 0xce, 0x00, 0x79, 0x60, 0x0c, 0xa0, 0x0e, 0xa1, 0x60, + 0x0c, 0x70, 0x16, 0xfe, 0xd6, 0x27, 0x0f, 0x87, 0x59, 0xc0, 0x4e, 0x01, 0xb3, 0x83, 0x27, 0x83, + 0x5c, 0x13, 0x8d, 0xc9, 0x7c, 0x23, 0x7b, 0xe3, 0x4c, 0xef, 0x6f, 0x2f, 0x4d, 0xbe, 0x30, 0xd3, + 0x14, 0x8c, 0xaa, 0x77, 0x31, 0xa3, 0x86, 0xb2, 0xbf, 0xc0, 0x2b, 0x00, 0x3a, 0x06, 0xc4, 0x00, + 0x79, 0x60, 0x62, 0x03, 0xcf, 0x3c, 0x52, 0xc1, 0xd7, 0xc7, 0xfc, 0xf7, 0x94, 0xa5, 0x6e, 0x8f, + 0xf9, 0xef, 0x39, 0xe3, 0xaf, 0x9c, 0x3d, 0xfc, 0x0b, 0x00, 0x03, 0x20, 0x0e, 0x08, 0x00, 0xdc, + 0x1a, 0x8e, 0xe4, 0xaa, 0x3b, 0x9f, 0x09, 0xb8, 0x02, 0x9d, 0x86, 0xdc, 0x60, 0x29, 0xbd, 0x79, + 0x60, 0x49, 0xb8, 0x0d, 0xf7, 0x0e, 0x0c, 0x3c, 0xfb, 0xce, 0x03, 0x01, 0x25, 0xe5, 0x81, 0xe2, + 0x23, 0x63, 0xa0, 0x7e, 0xb1, 0xd0, 0xf9, 0xfe, 0x3f, 0xe7, 0xbc, 0xbb, 0x2d, 0x8e, 0x23, 0xe5, + 0x86, 0x38, 0x37, 0x93, 0x06, 0x8b, 0x8a, 0x0c, 0x00, 0x05, 0x00, 0x3c, 0x68, 0x18, 0x93, 0x02, + 0xc0, 0x49, 0x84, 0x2f, 0xc4, 0x43, 0x27, 0x3f, 0x5a, 0xe0, 0x62, 0x0c, 0x0a, 0x30, 0xc4, 0x3d, + 0xcb, 0x6f, 0xe0, 0xbb, 0x98, 0x91, 0x5c, 0x40, 0xfc, 0x0d, 0x22, 0x06, 0xc1, 0xf7, 0x2d, 0x83, + 0xee, 0xfe, 0x25, 0xe4, 0xe0, 0x01, 0xa6, 0x4e, 0x00, 0x69, 0x19, 0x6e, 0xa7, 0x94, 0x44, 0xa2, + 0xb5, 0x4a, 0x0b, 0x24, 0xb6, 0x14, 0x1c, 0x4e, 0x61, 0xf0, 0xbb, 0x30, 0x0c, 0x42, 0x60, 0x90, + 0xa1, 0x45, 0x57, 0xbb, 0x5d, 0x63, 0xbc, 0x5c, 0x38, 0xe5, 0xa6, 0xba, 0x87, 0x41, 0x58, 0x58, + 0x82, 0x81, 0x30, 0x0d, 0xc1, 0xc4, 0x02, 0x81, 0x6e, 0x05, 0x80, 0x72, 0x36, 0x39, 0x00, 0xb8, + 0xf2, 0xe3, 0x90, 0x2e, 0xcf, 0x9b, 0xd4, 0xa1, 0x2a, 0x67, 0x16, 0x5c, 0xdd, 0x9c, 0x75, 0x72, + 0xec, 0x42, 0x79, 0x89, 0x30, 0x89, 0x0c, 0x3f, 0x03, 0xc0, 0x20, 0x0a, 0x09, 0x1e, 0xbe, 0x77, + 0xd5, 0x54, 0x50, 0xe7, 0x4e, 0x20, 0xe0, 0xae, 0x21, 0xc0, 0x00, 0x40, 0x7e, 0x39, 0xe0, 0x22, + 0x63, 0x63, 0xcb, 0x9e, 0x1e, 0x3d, 0x77, 0x71, 0xeb, 0xbb, 0x8f, 0xbb, 0xb8, 0xfb, 0x9e, 0xfc, + 0x57, 0x63, 0xb7, 0x14, 0x63, 0xab, 0x83, 0x80, 0x01, 0x30, 0x05, 0x8e, 0x72, 0xa8, 0x77, 0x25, + 0x51, 0xdc, 0xf8, 0x5d, 0x10, 0x01, 0x89, 0x19, 0x25, 0xec, 0x38, 0x3d, 0xeb, 0x34, 0x19, 0x78, + 0x9c, 0x07, 0x5c, 0x04, 0xe0, 0x3a, 0x70, 0x6e, 0x05, 0x80, 0x14, 0x03, 0x60, 0xe0, 0x2f, 0xca, + 0xc5, 0x41, 0xc0, 0x7f, 0x1e, 0xbc, 0x43, 0x4a, 0x58, 0xdb, 0x83, 0x80, 0xce, 0x59, 0x65, 0x41, + 0x4a, 0x14, 0xf4, 0x14, 0x65, 0x83, 0x2d, 0x8a, 0x03, 0x06, 0x00, 0x08, 0x07, 0x01, 0x26, 0x28, + 0x71, 0x43, 0xfc, 0x34, 0x48, 0x07, 0x19, 0xae, 0x3e, 0x8b, 0xd6, 0xf7, 0x79, 0xfa, 0xdd, 0xb9, + 0xae, 0x20, 0x40, 0x2d, 0x2a, 0xa6, 0xa9, 0x8a, 0x0c, 0x56, 0x28, 0x03, 0x14, 0x62, 0x27, 0x41, + 0x68, 0x61, 0x40, 0x4c, 0x99, 0x3d, 0xfe, 0xe9, 0x7a, 0xda, 0xfa, 0x9f, 0x9b, 0xbf, 0xdd, 0x44, + 0xbd, 0xf8, 0x29, 0x8d, 0xa8, 0xa6, 0xa4, 0xc8, 0xb2, 0x09, 0x49, 0xe1, 0xe2, 0x3f, 0x1e, 0x5f, + 0x4c, 0xb8, 0x1e, 0x43, 0x50, 0x7e, 0x85, 0x39, 0x7d, 0x17, 0xc3, 0x6c, 0xc0, 0x15, 0xb7, 0x88, + 0x31, 0xbb, 0xa7, 0x3f, 0xdd, 0x9f, 0x7f, 0x24, 0xdc, 0x1f, 0xc1, 0x26, 0xe7, 0x65, 0x81, 0x69, + 0x12, 0x6e, 0x0e, 0xa8, 0x28, 0xb8, 0x7b, 0xbf, 0xe1, 0xb7, 0x00, 0xc2, 0x2a, 0x3e, 0x19, 0x49, + 0xde, 0xfb, 0xc9, 0x09, 0x21, 0x6f, 0x79, 0x20, 0xb0, 0x97, 0xbf, 0xc3, 0xca, 0x00, 0x29, 0x23, + 0xc1, 0xe4, 0x82, 0xa5, 0x85, 0x77, 0xde, 0x7f, 0xdc, 0x6f, 0x0f, 0xef, 0xef, 0xe7, 0xbd, 0xfe, + 0x1d, 0x24, 0x00, 0x55, 0x87, 0x25, 0x31, 0x60, 0x57, 0x50, 0xab, 0x57, 0x2d, 0xc5, 0x6d, 0x9b, + 0x96, 0xb1, 0xdb, 0xc5, 0x64, 0x85, 0x8d, 0x10, 0x56, 0x92, 0x9a, 0x1f, 0x09, 0x90, 0xa0, 0x0a, + 0x30, 0x53, 0x75, 0x0b, 0xdf, 0x15, 0x9e, 0x05, 0x8d, 0x6b, 0x3c, 0x0e, 0x01, 0x83, 0x23, 0x80, + 0x61, 0x0d, 0xb8, 0x52, 0xd1, 0x3c, 0x3a, 0x99, 0xe1, 0x83, 0xd5, 0xd4, 0xb0, 0x0c, 0xf0, 0x2c, + 0x03, 0x3d, 0x86, 0xb5, 0x03, 0x4c, 0x72, 0x8a, 0x8b, 0xf0, 0xc2, 0x38, 0x03, 0x8a, 0xed, 0x65, + 0xc0, 0x8a, 0xfe, 0xb5, 0x15, 0xd9, 0x6d, 0xba, 0x9f, 0xca, 0xee, 0x8e, 0xe1, 0x85, 0x00, 0x75, + 0x3f, 0xd2, 0x77, 0x3f, 0xfd, 0xb3, 0x73, 0xf3, 0xfe, 0xa0, 0xb4, 0x38, 0x48, 0x01, 0x8f, 0x0d, + 0x33, 0x6c, 0xbf, 0x9d, 0xa6, 0x4e, 0x48, 0x16, 0xe1, 0x6b, 0x8a, 0xd3, 0xa6, 0x0a, 0x77, 0x6c, + 0xb1, 0xf8, 0x79, 0x40, 0x31, 0x1c, 0x52, 0xae, 0x21, 0xff, 0xe6, 0x6e, 0xf2, 0xff, 0x09, 0xd0, + 0x84, 0xc9, 0x13, 0x24, 0x47, 0x7d, 0x9d, 0xf6, 0x5d, 0xbf, 0xf0, 0xdb, 0x14, 0x00, 0x4a, 0xbc, + 0x39, 0x3c, 0x11, 0xf2, 0xf3, 0xdb, 0xbc, 0xea, 0xef, 0x15, 0xb2, 0x51, 0x5a, 0x8a, 0x30, 0x20, + 0x4d, 0x3c, 0x22, 0x58, 0x5e, 0xfc, 0x05, 0x00, 0x18, 0x06, 0xc4, 0x80, 0x01, 0x1c, 0x0b, 0x80, + 0x2a, 0x4e, 0x02, 0xa7, 0xb8, 0x3a, 0xb9, 0x29, 0xa1, 0xfe, 0x4a, 0x1a, 0x3f, 0x5d, 0x85, 0x51, + 0x29, 0xe0, 0x1c, 0x2c, 0xcf, 0x3c, 0xb0, 0xcb, 0xc6, 0x45, 0x89, 0xff, 0xe1, 0xb2, 0x40, 0x08, + 0xdd, 0x70, 0x28, 0x7d, 0xe8, 0x14, 0x77, 0x6f, 0xb9, 0x45, 0xf3, 0xea, 0x7b, 0xcb, 0xd3, 0x14, + 0x71, 0x41, 0xe2, 0xf1, 0x73, 0x80, 0xe6, 0xdb, 0xd3, 0xf8, 0x5f, 0x01, 0xf8, 0x29, 0x9a, 0xce, + 0xd6, 0x4e, 0xb3, 0x35, 0xaa, 0xaa, 0xec, 0xa2, 0x81, 0x86, 0xd9, 0x40, 0x14, 0xac, 0xc8, 0x06, + 0xa6, 0x3c, 0xba, 0xbd, 0xe2, 0xb5, 0x15, 0xc5, 0x6c, 0x84, 0x30, 0x34, 0x0e, 0x60, 0xfa, 0xd7, + 0xe1, 0xc7, 0x00, 0x8c, 0x29, 0x0c, 0x46, 0x8e, 0xe1, 0x7c, 0x5f, 0x56, 0xdb, 0x97, 0x74, 0x2c, + 0xde, 0xb7, 0x7a, 0xc1, 0x60, 0x02, 0x23, 0x38, 0x8d, 0x5d, 0x3f, 0xc0, 0x54, 0x01, 0x84, 0x6c, + 0x75, 0xfc, 0x75, 0xfc, 0xac, 0xc2, 0xad, 0x37, 0x52, 0xfb, 0xfb, 0x19, 0x6b, 0x03, 0x40, 0x61, + 0x68, 0x87, 0xb8, 0x81, 0xef, 0x87, 0xc3, 0x44, 0x28, 0x01, 0x51, 0xf6, 0x9e, 0x41, 0x35, 0x6c, + 0xba, 0xee, 0x5f, 0x5e, 0xab, 0x5a, 0x82, 0x9b, 0xe2, 0x62, 0x5f, 0xb8, 0x81, 0xc2, 0xe1, 0xe3, + 0x96, 0x14, 0x80, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5e, 0x2f, 0x30, 0xe8, 0x12, 0x74, 0x36, + 0xa0, 0x5f, 0xeb, 0x53, 0x74, 0x5c, 0xaf, 0xaf, 0x5f, 0x5e, 0x87, 0x3a, 0x23, 0x41, 0xb7, 0x57, + 0x8b, 0xeb, 0xd2, 0xf5, 0xa8, 0xae, 0xad, 0x11, 0xd1, 0xde, 0x0a, 0xf8, 0x24, 0x23, 0xbf, 0x05, + 0xf5, 0xea, 0xea, 0xf5, 0xd5, 0xa1, 0x7e, 0xb5, 0x0a, 0x75, 0xef, 0x82, 0x2b, 0xbe, 0xd1, 0x1d, + 0x5c, 0x97, 0xab, 0x41, 0x3f, 0x5e, 0xfa, 0xf4, 0xbc, 0x12, 0x57, 0x63, 0x62, 0x5e, 0xad, 0xf5, + 0xef, 0xa2, 0xb4, 0xbd, 0x19, 0xab, 0xab, 0x7d, 0x5a, 0x4e, 0x8a, 0xd0, 0x47, 0xd1, 0x12, 0xa0, + 0xd7, 0x56, 0x88, 0xea, 0xf2, 0x62, 0x05, 0xd5, 0x75, 0x5c, 0x48, 0x61, 0x4d, 0x7f, 0xfe, 0xc2, + 0x61, 0x52, 0xcc, 0x61, 0xc5, 0x3c, 0x7f, 0xf6, 0x9a, 0xda, 0x69, 0xce, 0xdb, 0x7f, 0x1d, 0x8c, + 0x31, 0x3a, 0x7c, 0x5d, 0x55, 0x57, 0x55, 0x2f, 0x5a, 0x93, 0xaf, 0x42, 0x3d, 0x6d, 0x2f, 0x45, + 0xef, 0xaf, 0x49, 0xd5, 0xfe, 0x8c, 0x90, 0x46, 0x8c, 0xf9, 0x63, 0x17, 0x16, 0x23, 0xc4, 0x2e, + 0x21, 0x71, 0x84, 0x2a, 0xeb, 0x80, 0x60, 0x20, 0x8e, 0xf7, 0x8f, 0xb1, 0x8a, 0x19, 0x7a, 0xb1, + 0x8b, 0xef, 0xad, 0x45, 0x75, 0xaa, 0xeb, 0x51, 0xbd, 0x5a, 0x6c, 0x4f, 0xc9, 0x5a, 0xcd, 0xd6, + 0xbe, 0xc9, 0xbb, 0xfa, 0xc5, 0x27, 0x45, 0xae, 0x02, 0x06, 0xb5, 0xc0, 0xe2, 0x11, 0x54, 0x7e, + 0x38, 0x90, 0xbd, 0x90, 0xb7, 0x18, 0xc5, 0x25, 0x3f, 0x8c, 0x5f, 0xf1, 0x8b, 0x1c, 0x7f, 0x84, + 0x14, 0x73, 0x1d, 0xc6, 0x29, 0x08, 0x8e, 0xdc, 0x04, 0x06, 0x12, 0xeb, 0x50, 0x8f, 0x51, 0xf5, + 0xf2, 0x11, 0x5f, 0x7d, 0x53, 0xb2, 0xf0, 0x44, 0x57, 0x77, 0x71, 0xdb, 0x80, 0xa9, 0x12, 0xa3, + 0xb6, 0x30, 0x91, 0xf6, 0x25, 0xb1, 0xca, 0xb1, 0x63, 0x15, 0x2e, 0xc7, 0x2f, 0xb1, 0xc4, 0xa6, + 0x54, 0xce, 0xca, 0x0e, 0xac, 0x88, 0x7e, 0x18, 0xa1, 0x06, 0xa1, 0x6e, 0x8a, 0xd1, 0xbc, 0x13, + 0x5f, 0x55, 0x55, 0x5e, 0xae, 0x8b, 0x14, 0xbd, 0x13, 0xbe, 0xb9, 0x57, 0xa8, 0x0c, 0x10, 0x82, + 0xf6, 0x30, 0x9a, 0x65, 0x10, 0xb8, 0xc5, 0xeb, 0x18, 0x49, 0x88, 0x27, 0xb1, 0x44, 0x28, 0x51, + 0x65, 0x08, 0xa1, 0xb3, 0xa5, 0xb6, 0xff, 0xc3, 0x14, 0x14, 0xab, 0xe8, 0xa9, 0x97, 0x82, 0x3b, + 0xee, 0xd1, 0xfd, 0x5e, 0xfa, 0xf7, 0xc8, 0x6b, 0xdc, 0x47, 0x2d, 0x57, 0x37, 0x47, 0xca, 0x4e, + 0xb2, 0xbc, 0x33, 0xc0, 0xf0, 0x11, 0xbe, 0x8a, 0x3b, 0x63, 0x16, 0x95, 0x46, 0x2c, 0x76, 0xe0, + 0x15, 0x9a, 0x12, 0x34, 0x6c, 0x20, 0x87, 0x0f, 0xb2, 0x10, 0x9a, 0x74, 0xd3, 0xf8, 0xd2, 0x69, + 0x93, 0x3b, 0x8e, 0x2c, 0x36, 0xc8, 0x00, 0x8d, 0x78, 0x98, 0x50, 0xb7, 0xff, 0xe9, 0xa6, 0x29, + 0x8b, 0xbf, 0xb6, 0xdc, 0x39, 0x30, 0x00, 0x88, 0x8a, 0x7b, 0xa2, 0xa7, 0xeb, 0xfe, 0x9e, 0x9c, + 0x1f, 0xf2, 0xf2, 0xa3, 0x2d, 0x34, 0xf6, 0xdb, 0x86, 0x58, 0xb0, 0x10, 0xfd, 0xa7, 0xe7, 0xfe, + 0x2d, 0x8b, 0x7e, 0x8e, 0xfc, 0x11, 0xdd, 0xdd, 0xda, 0x27, 0xa2, 0xbc, 0xfd, 0x08, 0x82, 0xfa, + 0x12, 0xe4, 0x6e, 0x25, 0x76, 0x89, 0x1e, 0xcb, 0x4b, 0xe9, 0xfa, 0x1f, 0xca, 0x9d, 0x34, 0xfe, + 0x3f, 0x80, 0xa8, 0xe6, 0x9a, 0x69, 0xa7, 0xf1, 0xe4, 0x34, 0x18, 0x87, 0x55, 0x6b, 0xeb, 0xa2, + 0xb5, 0x86, 0xd8, 0xc0, 0x05, 0x6f, 0xb2, 0x18, 0x4f, 0x5f, 0xeb, 0x53, 0x72, 0xc4, 0x6f, 0xde, + 0xf0, 0xd1, 0x0c, 0x00, 0x9e, 0x46, 0x82, 0x30, 0x07, 0xad, 0x7d, 0x3a, 0x7f, 0xe3, 0x8c, 0x70, + 0x38, 0x71, 0x40, 0x04, 0xdb, 0x0b, 0x36, 0x5e, 0x10, 0xa0, 0x35, 0xae, 0xff, 0x55, 0x52, 0x74, + 0xc5, 0xb6, 0x71, 0xf7, 0x5f, 0xe9, 0xc3, 0x88, 0xc0, 0x06, 0xe3, 0xb0, 0x28, 0x29, 0xd0, 0x38, + 0xff, 0x48, 0xbd, 0xbe, 0x9e, 0x2d, 0x8b, 0x7c, 0x5b, 0xa6, 0x0f, 0xb9, 0x43, 0x2b, 0xfd, 0xb6, + 0xf8, 0x73, 0x00, 0x07, 0x8c, 0x82, 0x1b, 0x91, 0x65, 0xe9, 0xde, 0x58, 0x24, 0xc7, 0xeb, 0x60, + 0x86, 0x4b, 0x0c, 0xcf, 0x46, 0xdb, 0x2c, 0x58, 0xa2, 0xc8, 0xd6, 0x09, 0xc1, 0xc8, 0xf1, 0xd5, + 0x71, 0x0f, 0xe5, 0xac, 0x83, 0x04, 0xbb, 0x0d, 0x26, 0x25, 0xd9, 0xd4, 0xf4, 0xdb, 0xfe, 0x08, + 0xc2, 0x2f, 0x22, 0xc3, 0x53, 0x9c, 0xa8, 0x26, 0x3a, 0xfd, 0x09, 0xec, 0x7a, 0xca, 0x94, 0xd3, + 0x4d, 0x3f, 0x8b, 0x21, 0x88, 0x44, 0x10, 0xd8, 0x7b, 0x2c, 0x7f, 0xff, 0x4f, 0x47, 0xf4, 0xff, + 0x0d, 0x92, 0x0a, 0xf9, 0x6f, 0xfd, 0x3e, 0x9c, 0x4b, 0x4f, 0x4f, 0xe1, 0x22, 0x14, 0x11, 0xa9, + 0xa7, 0x01, 0xa6, 0xac, 0xfc, 0xfd, 0xff, 0xf0, 0x20, 0x41, 0x1e, 0xaa, 0xb9, 0x1b, 0xf8, 0x22, + 0xee, 0xec, 0xac, 0x10, 0xf8, 0x29, 0x04, 0xe4, 0x72, 0xc7, 0x77, 0x77, 0x7e, 0xc3, 0x44, 0x18, + 0x00, 0x71, 0xbb, 0x38, 0x43, 0x9e, 0xde, 0xdf, 0xf9, 0x66, 0xc3, 0x44, 0x20, 0x01, 0xd1, 0x8b, + 0x12, 0x98, 0x14, 0x9e, 0xa7, 0xe9, 0xd3, 0xf3, 0x77, 0x79, 0xb9, 0xa5, 0xc3, 0x6a, 0x00, 0x37, + 0x88, 0x8b, 0x40, 0x42, 0x24, 0x00, 0xf3, 0xf5, 0x60, 0x69, 0x5c, 0x53, 0x71, 0xc7, 0xe3, 0xfe, + 0x3f, 0xe5, 0xf6, 0x76, 0x09, 0x94, 0x10, 0x90, 0x57, 0x6e, 0xee, 0x2e, 0x87, 0x83, 0xfa, 0x69, + 0xf0, 0xe2, 0x28, 0x03, 0x6f, 0x2b, 0x36, 0x0b, 0xe3, 0xd5, 0xab, 0xad, 0x34, 0xfa, 0xf7, 0xa2, + 0x71, 0xa7, 0xd3, 0x4f, 0xc8, 0xdd, 0xb6, 0xfd, 0x34, 0xe1, 0xe6, 0x28, 0x01, 0xd6, 0x24, 0x13, + 0x44, 0xff, 0xde, 0x13, 0xc2, 0xfe, 0x0d, 0x60, 0x4e, 0x62, 0x3d, 0x6b, 0x94, 0x86, 0xb5, 0xb6, + 0x52, 0xfa, 0x1c, 0x9c, 0x1c, 0x0d, 0xe0, 0xf7, 0xd9, 0x7b, 0xfe, 0x35, 0x00, 0x48, 0x57, 0xdb, + 0x7e, 0x03, 0xc4, 0x02, 0x40, 0x18, 0x12, 0x07, 0x38, 0x6a, 0xdc, 0x3c, 0x00, 0x0b, 0xf2, 0x50, + 0x05, 0x76, 0xe4, 0x42, 0x68, 0x0e, 0xcb, 0x16, 0xc5, 0xbf, 0x04, 0xf0, 0x43, 0x05, 0x15, 0xae, + 0xd5, 0x5f, 0x80, 0xa1, 0x12, 0x8a, 0x0a, 0x46, 0x1d, 0x45, 0x01, 0xc9, 0x97, 0x2d, 0xff, 0x8b, + 0x69, 0xe2, 0xda, 0x62, 0x13, 0x57, 0x4c, 0x9b, 0xb6, 0xdc, 0x3b, 0x38, 0x0f, 0x69, 0xcb, 0xff, + 0xe9, 0xa7, 0xa6, 0x98, 0xae, 0x57, 0xb6, 0xdf, 0xc4, 0xb3, 0x86, 0x53, 0xfd, 0xc6, 0x28, 0x3a, + 0xf1, 0x1d, 0x97, 0x82, 0x21, 0xc1, 0x60, 0x54, 0x3b, 0x00, 0x6b, 0xda, 0x09, 0xe1, 0xe8, 0xa0, + 0x00, 0xb3, 0x23, 0x1c, 0xbd, 0x81, 0x74, 0x3b, 0xff, 0xdd, 0xb6, 0xfc, 0xbe, 0xdd, 0xc5, 0x58, + 0x3b, 0x77, 0xce, 0xaf, 0x6d, 0x3d, 0x38, 0x6d, 0xc0, 0x1d, 0xc3, 0x0a, 0x8b, 0xc7, 0xf0, 0xd5, + 0x02, 0x05, 0x7c, 0xd8, 0xbb, 0xb7, 0x35, 0xb7, 0x94, 0x7c, 0x23, 0x3e, 0x14, 0x07, 0xfa, 0x6c, + 0x33, 0x68, 0xfc, 0x60, 0xa3, 0x3e, 0x9a, 0xd7, 0x0d, 0x33, 0x80, 0x10, 0xf3, 0xeb, 0x11, 0x4f, + 0xfb, 0xcf, 0xff, 0x5c, 0x0f, 0x33, 0xe1, 0x5c, 0x60, 0xe1, 0xb2, 0x18, 0x00, 0x9f, 0x86, 0xaf, + 0x39, 0x10, 0x5e, 0x79, 0x8c, 0xf7, 0x3f, 0x5f, 0x06, 0xaf, 0x07, 0xf9, 0xec, 0x4f, 0xf5, 0xbb, + 0xd3, 0x7d, 0xed, 0xe1, 0xa4, 0x50, 0x02, 0x7b, 0x5e, 0x48, 0x41, 0x4b, 0xbe, 0x9a, 0x7f, 0xfa, + 0x30, 0x84, 0x3d, 0x28, 0x00, 0xc0, 0x72, 0xc7, 0xf6, 0x1d, 0x87, 0xff, 0x27, 0x7f, 0xed, 0xb7, + 0xe6, 0x41, 0xf7, 0xf3, 0x7d, 0x41, 0x34, 0x33, 0x0a, 0x71, 0x58, 0xad, 0x44, 0x9f, 0x57, 0x77, + 0xbb, 0x76, 0xf3, 0xe1, 0xc5, 0x00, 0xd7, 0x51, 0x2a, 0x34, 0xd3, 0xd3, 0x4f, 0xfe, 0xf1, 0x56, + 0xdf, 0xf8, 0x14, 0x21, 0x49, 0x3c, 0x45, 0x32, 0x96, 0xd1, 0x1b, 0x26, 0xec, 0xe5, 0xb0, 0x79, + 0x7e, 0x27, 0xe0, 0xe9, 0x71, 0xa5, 0x0e, 0xe1, 0xc5, 0x07, 0xe4, 0x0a, 0x75, 0xf4, 0xd3, 0xb7, + 0xfb, 0x6d, 0x8c, 0x28, 0x6a, 0x8d, 0xcf, 0x75, 0xba, 0xd3, 0xf0, 0xe2, 0x20, 0x06, 0xd4, 0xc5, + 0x31, 0xd3, 0xd3, 0x4f, 0xfc, 0x6a, 0x9f, 0x4d, 0x3e, 0x1a, 0x24, 0x11, 0xdb, 0xad, 0xff, 0xfe, + 0xde, 0x46, 0x9f, 0x88, 0x35, 0xda, 0x1e, 0xe0, 0x8c, 0x01, 0x90, 0x05, 0xd8, 0x09, 0x06, 0x68, + 0x00, 0x04, 0x07, 0x43, 0x32, 0x62, 0xc3, 0x47, 0x99, 0x0f, 0x28, 0x1d, 0x9a, 0x44, 0x1b, 0x61, + 0x4b, 0x5d, 0xff, 0xbc, 0x7d, 0x8b, 0x73, 0xa0, 0x1a, 0x46, 0x9f, 0x06, 0xa1, 0x94, 0x6f, 0xb4, + 0xd3, 0x2c, 0xb6, 0x71, 0x4b, 0x2c, 0xb3, 0x77, 0x50, 0xb2, 0xcb, 0xb1, 0xaa, 0xdf, 0x6d, 0xbe, + 0x1c, 0x21, 0x40, 0x0d, 0xb3, 0x00, 0x14, 0xb6, 0x17, 0x80, 0x6b, 0x8d, 0x5d, 0xd3, 0x8d, 0x34, + 0xd3, 0xcd, 0xdb, 0x4d, 0x3c, 0x12, 0xc1, 0xb7, 0xea, 0x9e, 0x1a, 0x65, 0x00, 0x6e, 0x45, 0xc6, + 0x60, 0xba, 0xd5, 0xe9, 0xa6, 0x9a, 0x7a, 0xaa, 0x69, 0x93, 0xb3, 0x8f, 0x8c, 0x70, 0xee, 0x00, + 0x26, 0xde, 0x88, 0x0c, 0x78, 0xe5, 0x6b, 0xcb, 0xe4, 0xe4, 0xec, 0xfe, 0x29, 0xe2, 0x9c, 0x25, + 0x00, 0x43, 0x8a, 0xf0, 0x5c, 0x89, 0x14, 0xe3, 0x0f, 0x04, 0xbd, 0x1e, 0xb0, 0xe6, 0x0a, 0x74, + 0x5f, 0xd3, 0xb7, 0xfc, 0x47, 0x7f, 0x7e, 0x1a, 0x24, 0x06, 0x54, 0xcc, 0xff, 0xfd, 0xb6, 0xff, + 0x85, 0x14, 0xe4, 0xbf, 0xff, 0x4d, 0x38, 0x84, 0x50, 0x54, 0x19, 0xa5, 0x0a, 0x22, 0x03, 0x37, + 0xbf, 0xf6, 0xdb, 0xdb, 0x6e, 0x1a, 0x50, 0xa2, 0xbf, 0xfb, 0xff, 0xd2, 0x70, 0x51, 0xdd, 0xf7, + 0x71, 0x8a, 0x4b, 0x08, 0x88, 0x04, 0x46, 0x07, 0x4f, 0x04, 0x80, 0x39, 0x3e, 0x64, 0x8a, 0x1b, + 0x24, 0x0f, 0xeb, 0xaf, 0x71, 0xdb, 0xfa, 0x7f, 0xc9, 0x1d, 0xb6, 0xda, 0x69, 0xa6, 0x9b, 0x6d, + 0xfb, 0x23, 0xde, 0x08, 0x79, 0x84, 0xf2, 0xfe, 0x20, 0xbd, 0xdc, 0x81, 0x24, 0x53, 0xe2, 0xe9, + 0x13, 0x39, 0xfc, 0x72, 0x8e, 0xe0, 0xc8, 0xaa, 0x31, 0x41, 0x2b, 0x78, 0x63, 0x10, 0x48, 0x16, + 0x75, 0x4a, 0x1e, 0x24, 0x3e, 0x06, 0xc5, 0xff, 0xfd, 0xbe, 0xf3, 0x6f, 0x6f, 0x03, 0x00, 0x90, + 0x47, 0x2d, 0x1f, 0x8e, 0xef, 0x97, 0x55, 0xa8, 0x64, 0x0a, 0x20, 0xa0, 0x8b, 0x17, 0x2f, 0x10, + 0x3c, 0x50, 0x19, 0x60, 0x0c, 0x50, 0x00, 0x61, 0x98, 0x07, 0x10, 0x52, 0x87, 0x89, 0x00, 0x30, + 0xcf, 0x44, 0x41, 0xbe, 0xff, 0xdd, 0xff, 0xb9, 0xfb, 0x6d, 0xd4, 0xd0, 0x1c, 0xa0, 0x61, 0xb9, + 0x70, 0x7d, 0xc5, 0xbd, 0xb6, 0xe1, 0xb4, 0x60, 0x00, 0xb8, 0xd1, 0x22, 0x1b, 0xe1, 0x2e, 0x09, + 0xbd, 0xef, 0xfb, 0x8b, 0x62, 0xd9, 0x68, 0x2a, 0xc7, 0x2f, 0x92, 0x3c, 0x1a, 0x53, 0x33, 0xe0, + 0xb5, 0x0f, 0xc9, 0xd7, 0x28, 0x22, 0x84, 0x44, 0x82, 0x0e, 0x2e, 0x4f, 0x13, 0xf5, 0x38, 0x3c, + 0x7b, 0xe3, 0xd6, 0x87, 0xa0, 0x35, 0x08, 0x86, 0xe8, 0x0b, 0xf7, 0x07, 0x7f, 0xf0, 0xf2, 0x80, + 0x32, 0x94, 0x98, 0x04, 0xc0, 0xa0, 0x9b, 0xff, 0x27, 0x16, 0xe5, 0xb4, 0xed, 0xc1, 0x54, 0x65, + 0x6f, 0xf8, 0x75, 0x40, 0x08, 0x45, 0x38, 0xf2, 0x20, 0xcd, 0xdf, 0xbf, 0xf2, 0xfa, 0x65, 0xfe, + 0x07, 0x03, 0x14, 0x77, 0x4e, 0x9f, 0xf0, 0x88, 0x28, 0x88, 0x1c, 0x15, 0x8a, 0x31, 0x5e, 0xd8, + 0xb8, 0x28, 0x10, 0xc9, 0x87, 0x14, 0x08, 0xe0, 0x3a, 0x88, 0xab, 0xfd, 0xb6, 0xd3, 0x16, 0xc5, + 0x58, 0xab, 0x16, 0xc5, 0xb1, 0x26, 0x8c, 0xb4, 0xcb, 0xfe, 0x1c, 0x50, 0xdb, 0xef, 0xb7, 0xff, + 0xe6, 0x39, 0x4d, 0x20, 0xbe, 0x18, 0x50, 0x24, 0x1f, 0x9c, 0x7f, 0xe9, 0xf4, 0xd3, 0x03, 0xe6, + 0xc3, 0x8a, 0x01, 0x37, 0xde, 0x41, 0x7f, 0x36, 0xdb, 0x7b, 0x6d, 0xff, 0x81, 0xf3, 0x74, 0x89, + 0x9f, 0x80, 0x48, 0x41, 0x00, 0x52, 0x2e, 0x2e, 0x91, 0x32, 0xad, 0x8b, 0xe0, 0xd4, 0x4c, 0x8a, + 0x88, 0x99, 0x6e, 0xc3, 0x60, 0x74, 0xf9, 0xc0, 0xc0, 0x24, 0x2b, 0xc5, 0xd6, 0xf7, 0x11, 0x7e, + 0x33, 0xd5, 0xd6, 0xfe, 0xb8, 0x20, 0xb8, 0xae, 0x2b, 0xc5, 0xe2, 0xb1, 0x40, 0x71, 0x20, 0xe0, + 0x50, 0x6e, 0x13, 0x5b, 0x15, 0x6e, 0x0e, 0xbf, 0xf0, 0xf1, 0x08, 0x00, 0x65, 0x07, 0x16, 0xe6, + 0x08, 0xb5, 0x5e, 0x15, 0x65, 0xad, 0x49, 0xdb, 0xb3, 0xa7, 0x55, 0xfc, 0x30, 0x05, 0xec, 0x3c, + 0xa0, 0xa7, 0x1c, 0x45, 0x47, 0xea, 0xfa, 0x70, 0xc4, 0xa0, 0x15, 0xd0, 0xc7, 0x1c, 0x56, 0x4c, + 0xbb, 0xb6, 0x2d, 0xdb, 0x6d, 0xb6, 0xdb, 0x6f, 0x6f, 0xa3, 0xce, 0x05, 0x00, 0x08, 0xc0, 0xdd, + 0x31, 0x5b, 0x95, 0x9e, 0x41, 0xc9, 0x89, 0x4e, 0x00, 0x79, 0x57, 0xc0, 0x3c, 0x1e, 0x16, 0x30, + 0xa8, 0x00, 0x17, 0x52, 0x88, 0xd4, 0xf1, 0xcb, 0x7d, 0x0e, 0x1c, 0x02, 0x80, 0x20, 0x00, 0xc5, + 0x53, 0xcc, 0x0d, 0x45, 0x1d, 0xfe, 0x08, 0xc8, 0x2b, 0xdc, 0x4d, 0x41, 0x28, 0x6f, 0x00, 0x03, + 0x54, 0x59, 0x08, 0x69, 0x21, 0x4d, 0x3f, 0x1b, 0xbb, 0x83, 0xee, 0xcf, 0x31, 0xcd, 0x38, 0xd7, + 0xbc, 0x35, 0x52, 0x21, 0x0f, 0x39, 0xee, 0x73, 0xfe, 0x1b, 0x62, 0xc0, 0x08, 0xa7, 0x2b, 0xc1, + 0x51, 0xcd, 0xff, 0x8f, 0x10, 0xff, 0x4d, 0xd3, 0x54, 0xf4, 0xd3, 0x04, 0xae, 0x38, 0x86, 0x8d, + 0xfc, 0x38, 0x88, 0x00, 0x19, 0x59, 0xae, 0x99, 0x0a, 0xff, 0xfb, 0xc5, 0xb0, 0x70, 0xdf, 0xff, + 0x99, 0x76, 0xc1, 0xdb, 0xa7, 0xfe, 0x02, 0x44, 0x02, 0x40, 0x34, 0xc1, 0xfc, 0xa7, 0x07, 0x07, + 0x47, 0xdb, 0x84, 0xa0, 0x05, 0x4e, 0x00, 0x02, 0x18, 0xdd, 0x25, 0x0a, 0x83, 0xa1, 0xf3, 0x81, + 0xe0, 0xeb, 0xf1, 0x8e, 0xbe, 0xee, 0xff, 0x61, 0x41, 0xb0, 0x03, 0x0e, 0xc1, 0xc6, 0xe0, 0xed, + 0xe5, 0xaf, 0xe0, 0xe0, 0x40, 0x77, 0x5b, 0x49, 0x6b, 0x2c, 0x18, 0xa3, 0x12, 0x03, 0xcb, 0x18, + 0x48, 0xd0, 0x9d, 0xb8, 0xea, 0xe6, 0xff, 0x86, 0x61, 0x3a, 0xaa, 0xac, 0xbd, 0xcb, 0x70, 0xe2, + 0x80, 0x3f, 0xb5, 0x0e, 0x8f, 0xed, 0xfa, 0x69, 0xb6, 0xd8, 0xc5, 0x36, 0xff, 0x86, 0x14, 0x09, + 0x4b, 0x21, 0xc6, 0x4f, 0x4d, 0x34, 0xd3, 0xb6, 0xde, 0xd9, 0xbe, 0x56, 0xe0, 0xc2, 0x14, 0x8b, + 0xa9, 0x32, 0x53, 0x8c, 0xa9, 0x2a, 0xb0, 0x49, 0xc4, 0x3c, 0xe1, 0xe4, 0xe2, 0xa7, 0xbe, 0xac, + 0xdc, 0x08, 0x22, 0x42, 0x85, 0xc9, 0xec, 0x8b, 0xc5, 0x62, 0xbb, 0x44, 0xe0, 0x1f, 0x16, 0x06, + 0x52, 0x12, 0x97, 0x55, 0x8d, 0x70, 0xd4, 0x07, 0xe1, 0x85, 0x05, 0x16, 0x08, 0xff, 0x5f, 0x9b, + 0xeb, 0xb7, 0xcd, 0xeb, 0x3f, 0xe0, 0x48, 0x12, 0x1d, 0x83, 0xee, 0xa9, 0xd5, 0x55, 0x53, 0x15, + 0x8b, 0x67, 0xc0, 0x64, 0xc4, 0x4b, 0x0c, 0x48, 0xc3, 0xf0, 0xe9, 0x0a, 0x00, 0x52, 0x96, 0x12, + 0x20, 0xa9, 0xea, 0x27, 0x4e, 0x69, 0xa7, 0x93, 0xbb, 0x67, 0xef, 0xb8, 0x19, 0x0c, 0x61, 0xf8, + 0x97, 0xb9, 0xe3, 0xfe, 0x1e, 0x21, 0x80, 0x04, 0xe9, 0x8a, 0xb2, 0x9e, 0x88, 0x40, 0x95, 0xe4, + 0xd3, 0xe4, 0xea, 0xce, 0xf9, 0x39, 0x3b, 0x3b, 0x3c, 0x61, 0x34, 0x4e, 0xcd, 0x99, 0x3f, 0xc3, + 0x52, 0x80, 0x48, 0xc9, 0x07, 0xb0, 0xe2, 0x6d, 0xcf, 0xde, 0x7e, 0x7e, 0x7e, 0xfe, 0xfe, 0xdb, + 0xf9, 0xfb, 0xfb, 0xfd, 0xdb, 0x90, 0x8c, 0x15, 0x0f, 0x28, 0x03, 0x92, 0xdb, 0xc8, 0x29, 0xc8, + 0x57, 0xfb, 0xfe, 0xbe, 0x7e, 0x25, 0xef, 0xe1, 0xa9, 0x31, 0xdf, 0x06, 0xd7, 0x7c, 0x3c, 0x48, + 0x07, 0x1e, 0x53, 0x1b, 0x7b, 0xef, 0xab, 0x8f, 0xff, 0xa6, 0x2d, 0x9b, 0xc9, 0x48, 0xed, 0x7d, + 0xff, 0xc1, 0x34, 0x56, 0x2b, 0x15, 0x8a, 0x31, 0x5b, 0xbc, 0x10, 0x1a, 0x09, 0x78, 0x7a, 0xe2, + 0xbc, 0x50, 0x18, 0xa0, 0x03, 0x14, 0x62, 0x80, 0xdc, 0x56, 0xee, 0x12, 0x46, 0x4c, 0x43, 0xe9, + 0xfc, 0x3d, 0x20, 0x01, 0x1c, 0x07, 0x26, 0x98, 0xe6, 0x1d, 0x8a, 0x99, 0xbb, 0xba, 0x69, 0xf9, + 0xf3, 0x73, 0x79, 0xb8, 0x1c, 0x18, 0xc8, 0xf3, 0xf8, 0xf7, 0xc1, 0xc9, 0xff, 0x86, 0x58, 0xb0, + 0x01, 0xdb, 0x62, 0xf1, 0x73, 0x0a, 0xee, 0xaf, 0x27, 0x4f, 0xfc, 0x1d, 0xbb, 0x65, 0xfd, 0x31, + 0xe8, 0xda, 0x86, 0x14, 0x00, 0xcc, 0x37, 0x19, 0x23, 0x2f, 0xfb, 0xd3, 0x4d, 0x34, 0xfe, 0x9d, + 0xba, 0xc3, 0xc8, 0x40, 0x90, 0x50, 0xd3, 0xb8, 0xd3, 0xf7, 0xfd, 0x3c, 0x22, 0x19, 0x0e, 0x54, + 0x35, 0xc3, 0x89, 0x7d, 0xbf, 0xc1, 0xc8, 0x04, 0x00, 0x6c, 0x41, 0xc2, 0x65, 0xd4, 0xa9, 0xce, + 0x5b, 0xf8, 0x81, 0xc2, 0xc1, 0x8a, 0x00, 0x31, 0x20, 0x3d, 0xf7, 0x60, 0x3a, 0xb0, 0x20, 0x12, + 0x98, 0x41, 0xc1, 0x8a, 0xb8, 0x38, 0x97, 0x5f, 0x87, 0x88, 0x50, 0x03, 0x70, 0x0c, 0x62, 0x94, + 0x26, 0x37, 0xaf, 0x08, 0x7a, 0x65, 0xb5, 0x64, 0x88, 0xd1, 0x64, 0x5d, 0x63, 0x4e, 0x35, 0x18, + 0x27, 0x64, 0x41, 0x2b, 0xb6, 0xe7, 0xff, 0x0c, 0x28, 0x01, 0x2f, 0x38, 0x51, 0x71, 0x17, 0xcf, + 0x9e, 0xf8, 0x49, 0xf7, 0x6f, 0x27, 0xd6, 0x2b, 0xc7, 0x7e, 0x18, 0x50, 0x01, 0x1d, 0xdf, 0xa8, + 0x2f, 0x92, 0xdb, 0x6a, 0x9a, 0x6d, 0xea, 0x99, 0x3e, 0x9a, 0x7d, 0x87, 0xb1, 0x11, 0x1f, 0x44, + 0xce, 0xbf, 0x56, 0x4f, 0x76, 0xcf, 0x1a, 0x71, 0x86, 0x9a, 0x7f, 0x0e, 0x22, 0x00, 0x12, 0x31, + 0x7a, 0x87, 0x1d, 0x65, 0x27, 0x7d, 0xb1, 0x56, 0x2a, 0xef, 0x7d, 0x34, 0xc0, 0xe6, 0x32, 0xaa, + 0x6b, 0xfc, 0x0e, 0x00, 0x40, 0x1b, 0x9b, 0xe4, 0xed, 0x97, 0xbf, 0x88, 0x3e, 0x77, 0x88, 0x7e, + 0x2b, 0x84, 0x59, 0xa7, 0x6e, 0x0e, 0xbf, 0xf0, 0xe9, 0x20, 0x01, 0xf8, 0xd1, 0x49, 0x08, 0xe0, + 0x5d, 0x20, 0x85, 0xaf, 0x9f, 0xde, 0x6a, 0xb3, 0x1e, 0xbb, 0x6c, 0xe0, 0xf5, 0xc1, 0xeb, 0x9d, + 0xe7, 0x7b, 0x38, 0x4b, 0x60, 0x24, 0xfd, 0x7f, 0x2f, 0xe9, 0xf8, 0x6b, 0x00, 0x18, 0x26, 0xa1, + 0xec, 0x71, 0xe1, 0x7f, 0xde, 0x7e, 0xfe, 0x7e, 0xff, 0xb7, 0xbb, 0xb8, 0x26, 0x81, 0x03, 0x86, + 0x09, 0x00, 0x0b, 0x28, 0xfd, 0x40, 0x90, 0x74, 0x1f, 0xed, 0x6a, 0xab, 0xb6, 0xdb, 0x6d, 0xb6, + 0x2a, 0xdb, 0x07, 0x1f, 0xdf, 0x0f, 0x12, 0x00, 0xc0, 0x00, 0x2e, 0xa8, 0x1d, 0xac, 0xbe, 0x4b, + 0xbb, 0xef, 0x3f, 0xad, 0xfe, 0xb3, 0xf6, 0xdf, 0xeb, 0x03, 0x01, 0x43, 0x8d, 0xa3, 0x56, 0x30, + 0x7a, 0xf1, 0xfc, 0x38, 0x42, 0x80, 0x11, 0xd1, 0x6b, 0xd4, 0xc5, 0x08, 0x5f, 0xb5, 0xe5, 0xfd, + 0xd7, 0xcb, 0xd9, 0xdc, 0xef, 0x03, 0x26, 0x87, 0xe7, 0xf1, 0x5f, 0x82, 0x78, 0x81, 0x01, 0xe9, + 0xf0, 0x75, 0x78, 0x76, 0x0d, 0x4f, 0x00, 0x73, 0x12, 0xe7, 0x13, 0xc0, 0x84, 0x4a, 0xda, 0x5e, + 0x39, 0x7e, 0x5f, 0xf0, 0xf4, 0x80, 0x09, 0x68, 0x3e, 0x9f, 0x50, 0xf4, 0x57, 0x79, 0xde, 0xbd, + 0xb6, 0xed, 0xed, 0xa2, 0xb7, 0xb6, 0x11, 0x07, 0x06, 0xd0, 0x64, 0xfb, 0x15, 0x9f, 0x9b, 0x4f, + 0x85, 0xe7, 0x00, 0x1f, 0xbd, 0xa1, 0x3b, 0x71, 0x0d, 0x2f, 0xa9, 0x9b, 0xca, 0x69, 0xa6, 0x9a, + 0xaa, 0xab, 0x73, 0x75, 0xb6, 0x1c, 0xc0, 0x05, 0xda, 0xb3, 0x90, 0xd0, 0xa1, 0x83, 0xee, 0xdb, + 0x69, 0xa7, 0xa6, 0x5e, 0x5f, 0x6b, 0x5f, 0xf0, 0x28, 0x82, 0x01, 0xa2, 0x05, 0x19, 0x60, 0xc4, + 0x83, 0xce, 0x1e, 0x50, 0x1c, 0xa3, 0xc0, 0x2c, 0x3c, 0x7b, 0x30, 0x9d, 0x57, 0x69, 0x66, 0x4c, + 0x15, 0xb2, 0xc7, 0x8a, 0xc2, 0x0d, 0x60, 0x00, 0x83, 0x55, 0x83, 0x04, 0x5c, 0x9f, 0xf0, 0xee, + 0x00, 0xa0, 0x90, 0x8b, 0x1c, 0xa6, 0x83, 0x5f, 0x29, 0xbe, 0x33, 0x9f, 0x3d, 0x34, 0xc7, 0x9f, + 0x86, 0x73, 0xc7, 0xbf, 0x6f, 0x09, 0x05, 0x07, 0x34, 0xab, 0x76, 0x38, 0x8b, 0x9a, 0x9f, 0x0e, + 0x45, 0x80, 0x0a, 0x4a, 0x8e, 0x6b, 0x21, 0x1b, 0xff, 0xd8, 0xbe, 0x76, 0xd3, 0x56, 0xc1, 0xdb, + 0xd3, 0x75, 0x4e, 0x36, 0xd4, 0xac, 0xcb, 0x4d, 0x3f, 0xc1, 0x44, 0x69, 0x04, 0x16, 0x23, 0x25, + 0x34, 0x53, 0x47, 0xd1, 0xa1, 0xb1, 0xab, 0x10, 0x8e, 0x05, 0x87, 0xa9, 0x26, 0xd6, 0xae, 0x8b, + 0x68, 0xae, 0x87, 0x8d, 0xa7, 0x64, 0xdb, 0xfc, 0x38, 0xa0, 0x03, 0x6d, 0xe6, 0x85, 0x76, 0xe6, + 0xf7, 0xdb, 0x6a, 0x9a, 0x7e, 0xb9, 0xb9, 0xfb, 0xbf, 0xca, 0x44, 0xdb, 0x7f, 0xe0, 0x19, 0x10, + 0x24, 0x8d, 0x86, 0x00, 0x2a, 0x41, 0xc1, 0x85, 0x06, 0xa1, 0x1c, 0x38, 0x39, 0x59, 0x7c, 0x88, + 0xe6, 0x1c, 0xdf, 0x07, 0x7f, 0xc4, 0xa0, 0x68, 0xcd, 0x14, 0x49, 0x41, 0xd8, 0xf8, 0xfe, 0x2b, + 0x6e, 0x45, 0xf0, 0xe9, 0x08, 0x00, 0xba, 0xd3, 0x82, 0x20, 0xab, 0xed, 0x9f, 0xf7, 0x17, 0x71, + 0x97, 0xdb, 0xdc, 0x9c, 0x77, 0xe7, 0xbd, 0xfe, 0xe4, 0xbd, 0x45, 0xc3, 0x00, 0x4a, 0x02, 0x64, + 0x55, 0x95, 0x17, 0xc1, 0x51, 0xe9, 0xf8, 0x6a, 0x40, 0x08, 0x55, 0x0a, 0x00, 0xa3, 0xd7, 0xfa, + 0xd7, 0xdc, 0x64, 0x06, 0x0e, 0x18, 0x20, 0x90, 0x00, 0xd2, 0x43, 0xd2, 0x23, 0x70, 0x16, 0x8f, + 0xb0, 0x8f, 0x55, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb6, 0xdb, 0x6d, 0xb1, 0x44, 0x6b, 0x87, 0x99, + 0x80, 0x05, 0x38, 0xd4, 0x0c, 0xc4, 0x0e, 0x25, 0x25, 0xfe, 0xf9, 0xf8, 0x97, 0xbf, 0xf7, 0x12, + 0xfb, 0xb7, 0x08, 0x48, 0x10, 0xa2, 0x36, 0x16, 0xf4, 0x90, 0xf7, 0xe0, 0x60, 0x08, 0x8d, 0x29, + 0x54, 0x03, 0x53, 0xc1, 0xc1, 0xd0, 0x7e, 0xb2, 0xde, 0xa7, 0x83, 0xe4, 0xab, 0xa9, 0xfc, 0x88, + 0x71, 0x32, 0xc1, 0x81, 0xa4, 0x09, 0x3b, 0xe5, 0x9f, 0xf0, 0x53, 0xc2, 0xf5, 0x10, 0x3e, 0x20, + 0x1f, 0x14, 0x1d, 0xc2, 0x44, 0x14, 0xe2, 0xdb, 0xc7, 0x87, 0xe0, 0xc8, 0xf1, 0xf1, 0xce, 0x63, + 0x55, 0xbe, 0x8e, 0x38, 0x66, 0x50, 0x02, 0x7e, 0x49, 0xc0, 0xcc, 0x29, 0x6f, 0xbf, 0xfe, 0xdc, + 0x10, 0x01, 0x24, 0x69, 0x04, 0x8e, 0x16, 0xa7, 0x37, 0x0b, 0x00, 0xa9, 0x30, 0x00, 0x13, 0x51, + 0xd5, 0x81, 0xc6, 0x6b, 0x37, 0x5c, 0xf0, 0x03, 0xc7, 0x40, 0xb0, 0x1d, 0x02, 0xe4, 0xe0, 0x00, + 0x61, 0xa0, 0x1e, 0x00, 0x02, 0x04, 0x08, 0x31, 0x95, 0x34, 0xea, 0xdb, 0x75, 0xc2, 0x01, 0x11, + 0xa6, 0x1d, 0x3e, 0x4a, 0x54, 0x9d, 0xc9, 0xba, 0x71, 0xe0, 0xe0, 0x84, 0xe5, 0xe3, 0x82, 0x13, + 0x93, 0x15, 0xb3, 0x80, 0x03, 0xd6, 0x2b, 0x10, 0xe2, 0x02, 0xf6, 0x51, 0x09, 0x42, 0x0f, 0x01, + 0x1c, 0x73, 0x85, 0x40, 0x00, 0x86, 0x26, 0x48, 0x09, 0x37, 0xe0, 0x2c, 0x04, 0x85, 0x0b, 0x97, + 0xb9, 0xcf, 0x2c, 0x62, 0xb5, 0xea, 0x70, 0xb1, 0xdb, 0x8e, 0xee, 0x5b, 0x88, 0x40, 0xe5, 0x1f, + 0xc2, 0x31, 0xb5, 0x14, 0xab, 0x7a, 0x9f, 0xae, 0x4f, 0xa2, 0xf7, 0x93, 0xe8, 0xf4, 0x68, 0xcc, + 0xf0, 0xcf, 0xdb, 0xfc, 0x0c, 0x30, 0xa4, 0x41, 0xfb, 0x34, 0x56, 0x6c, 0x2d, 0xe2, 0xdc, 0x6e, + 0x9b, 0xa8, 0x83, 0xc9, 0x8a, 0x15, 0x1f, 0x86, 0xe5, 0x00, 0x18, 0xc3, 0x2f, 0x98, 0x46, 0xaf, + 0xfc, 0x9e, 0xf6, 0x59, 0xa0, 0xed, 0x82, 0x92, 0x38, 0x3b, 0xd6, 0x62, 0xe3, 0x14, 0x61, 0xc3, + 0x80, 0xfc, 0x56, 0x88, 0x14, 0x47, 0xef, 0x86, 0xd8, 0x80, 0x01, 0xbb, 0x32, 0xc0, 0x47, 0xa6, + 0x01, 0x8d, 0x3d, 0x5a, 0x2e, 0xe2, 0xea, 0x4e, 0xac, 0xf1, 0x75, 0x14, 0xc4, 0x7b, 0x39, 0xde, + 0xce, 0x07, 0x44, 0x20, 0xed, 0x3f, 0xdb, 0xe6, 0x1f, 0xc0, 0xa0, 0x01, 0x20, 0x1a, 0x71, 0xc8, + 0x5c, 0x40, 0x3c, 0x78, 0xb9, 0xc3, 0xc5, 0x00, 0x06, 0x16, 0x00, 0x02, 0xaa, 0x70, 0x0f, 0x38, + 0x00, 0x7b, 0x39, 0xcf, 0x2d, 0x96, 0x33, 0x81, 0xe5, 0x83, 0x2c, 0x18, 0x97, 0x8c, 0x00, 0x01, + 0x01, 0x84, 0x36, 0xa5, 0xed, 0xff, 0x0d, 0x60, 0x4c, 0xb8, 0xd8, 0x08, 0xa7, 0x7f, 0xee, 0xfe, + 0xd9, 0x6c, 0x3c, 0x42, 0x00, 0x0d, 0xba, 0x65, 0x86, 0x4c, 0x1c, 0x7f, 0xd7, 0x5d, 0x62, 0x3e, + 0xa6, 0xf2, 0x5e, 0x59, 0xea, 0x06, 0xc3, 0x1f, 0x1c, 0xc3, 0x7c, 0x77, 0xe0, 0xac, 0x3b, 0x28, + 0x00, 0x12, 0x8a, 0xf8, 0x15, 0xde, 0x2f, 0x7f, 0xd3, 0x4e, 0xf2, 0xf8, 0x41, 0xb1, 0xb8, 0x32, + 0x3e, 0xc6, 0x37, 0xe1, 0xb4, 0x7e, 0xf8, 0x6b, 0x00, 0x33, 0x54, 0x74, 0x10, 0xa5, 0x7f, 0xf5, + 0xd6, 0x65, 0xf0, 0x40, 0x19, 0x0a, 0x5c, 0xf9, 0x8e, 0xae, 0x3a, 0x00, 0x17, 0x07, 0x1b, 0x94, + 0x40, 0x12, 0xe2, 0x3d, 0x31, 0xfc, 0x14, 0x10, 0x94, 0xe0, 0x1e, 0x58, 0xb0, 0x40, 0x00, 0x08, + 0x0c, 0x03, 0x81, 0xc3, 0xaa, 0x00, 0xf5, 0xbb, 0x02, 0x50, 0x64, 0xd0, 0x88, 0x5f, 0xe9, 0x3c, + 0xfc, 0x49, 0xe4, 0x8e, 0x09, 0x87, 0x10, 0x8e, 0x07, 0x9c, 0xf3, 0xcf, 0x2c, 0x67, 0x68, 0xc8, + 0x1c, 0x03, 0xcb, 0x33, 0x80, 0x78, 0xa4, 0x18, 0xe4, 0xfc, 0x7e, 0xb8, 0x1c, 0x04, 0x8d, 0xa0, + 0x05, 0x41, 0x76, 0x1a, 0x21, 0x50, 0xb6, 0xeb, 0x14, 0x74, 0xf0, 0xf3, 0x47, 0x50, 0x54, 0xa5, + 0x1b, 0xa2, 0xe4, 0x09, 0x42, 0xc7, 0xc4, 0xbe, 0x07, 0x69, 0x75, 0x1c, 0x1e, 0x28, 0x7f, 0x84, + 0x60, 0x9b, 0x55, 0x27, 0x4f, 0xb9, 0xd3, 0x0f, 0x12, 0x00, 0x39, 0x69, 0xb2, 0xa2, 0x06, 0xdf, + 0x6f, 0x29, 0x78, 0xbd, 0xc7, 0x1a, 0xb8, 0xa6, 0xe2, 0x3e, 0xd4, 0x56, 0x6e, 0x5b, 0x17, 0x05, + 0x4f, 0x7f, 0xc3, 0xc4, 0x20, 0x03, 0x08, 0x8b, 0xe0, 0xe4, 0x31, 0xe7, 0xf7, 0xef, 0x1c, 0xf2, + 0xfb, 0x17, 0x89, 0x07, 0x85, 0x5c, 0x13, 0x8e, 0x3c, 0xf1, 0xef, 0x80, 0x90, 0x7e, 0x04, 0x80, + 0xbe, 0x54, 0xf1, 0xea, 0x4e, 0x37, 0x3e, 0x1e, 0x64, 0x01, 0x50, 0x35, 0x74, 0x0c, 0xa4, 0xab, + 0x6b, 0x4f, 0x4d, 0x9f, 0x67, 0x4d, 0x32, 0x79, 0x3c, 0x6f, 0xb9, 0x3d, 0x90, 0xb2, 0x1f, 0x86, + 0x58, 0xd0, 0x04, 0x63, 0x13, 0x40, 0xf7, 0x47, 0x96, 0xb7, 0xb7, 0x7e, 0xee, 0xee, 0xf6, 0xe0, + 0x70, 0x03, 0x00, 0xd3, 0x09, 0x00, 0x70, 0x48, 0x03, 0x85, 0x8c, 0xf7, 0x85, 0xc1, 0x57, 0xed, + 0x52, 0x2b, 0xae, 0x2e, 0x29, 0xa8, 0xa0, 0x18, 0x8f, 0x09, 0x02, 0x10, 0x28, 0x5f, 0x4c, 0x1e, + 0xb8, 0x5b, 0x86, 0x7f, 0xf0, 0xc9, 0x4f, 0x00, 0x70, 0xf1, 0xcb, 0xb0, 0x35, 0x4b, 0x3f, 0x3f, + 0x05, 0x78, 0x90, 0xae, 0xf7, 0xc1, 0xa0, 0x21, 0x3a, 0x50, 0x49, 0x45, 0xad, 0xca, 0xdf, 0x7f, + 0xc2, 0x00, 0x59, 0x1a, 0x61, 0xdb, 0x1d, 0xa5, 0x04, 0x58, 0x0e, 0xa0, 0x4a, 0x56, 0x03, 0x53, + 0xc0, 0x00, 0xbe, 0x15, 0xb5, 0x2c, 0x00, 0x18, 0xac, 0x6b, 0x6a, 0xe0, 0x04, 0xb0, 0xb0, 0x61, + 0xe3, 0x22, 0xb3, 0x25, 0x0e, 0xcd, 0x49, 0x80, 0x00, 0x82, 0x9e, 0x07, 0x02, 0x82, 0x28, 0x00, + 0x61, 0xaa, 0x29, 0xfb, 0x1e, 0x3e, 0x9f, 0xc2, 0xec, 0xa0, 0x06, 0xbb, 0x70, 0x04, 0x5f, 0x94, + 0x26, 0xef, 0x7e, 0x4e, 0xa5, 0xfd, 0xba, 0x8a, 0x6a, 0x29, 0xeb, 0x80, 0xc1, 0x02, 0x40, 0x74, + 0x83, 0xa2, 0xe7, 0x07, 0x94, 0x52, 0x96, 0x1e, 0x0c, 0x04, 0xca, 0xa3, 0x88, 0xb8, 0xeb, 0xe5, + 0x99, 0xe0, 0xf9, 0x07, 0x00, 0x21, 0x22, 0x78, 0xa7, 0x17, 0xfe, 0x05, 0x88, 0xdb, 0x24, 0x0a, + 0x8f, 0xe4, 0xa0, 0x05, 0x31, 0x65, 0xfb, 0x95, 0x01, 0x12, 0x85, 0x35, 0x07, 0x00, 0x13, 0x72, + 0x85, 0x53, 0x15, 0xe5, 0xe0, 0xe5, 0x55, 0x89, 0xc3, 0xf8, 0x98, 0x28, 0x3d, 0x6e, 0x95, 0x27, + 0xcc, 0x7c, 0x10, 0x44, 0xfc, 0x89, 0xf9, 0x26, 0xa4, 0x73, 0xcb, 0x1c, 0x41, 0x45, 0x44, 0x38, + 0x48, 0x00, 0xa8, 0x38, 0x00, 0x14, 0x02, 0xc5, 0x58, 0x50, 0x0d, 0xc9, 0x20, 0x1b, 0x9f, 0x0d, + 0x90, 0x40, 0x00, 0xb5, 0xdc, 0x0a, 0x07, 0x88, 0x5f, 0xff, 0x7a, 0x2b, 0x51, 0x47, 0x2a, 0x2e, + 0x2f, 0x22, 0x80, 0x3c, 0x48, 0x00, 0xf1, 0x4c, 0x5c, 0xb0, 0xc5, 0x30, 0x1c, 0x11, 0xb4, 0xef, + 0xc2, 0x5f, 0x86, 0x89, 0x00, 0x29, 0x4c, 0x62, 0x67, 0xbc, 0x91, 0x36, 0xe5, 0xf7, 0x15, 0xb8, + 0xaf, 0xdc, 0x56, 0xe2, 0x47, 0xbe, 0x1e, 0x67, 0x00, 0x11, 0x07, 0xdc, 0x25, 0x53, 0xd4, 0xff, + 0xb7, 0x6f, 0xf7, 0xb6, 0x4e, 0xa5, 0xe1, 0x28, 0x8d, 0xac, 0x41, 0xff, 0xe1, 0xba, 0x54, 0xa1, + 0x12, 0x49, 0x1f, 0x7e, 0x3f, 0x82, 0x5e, 0x8b, 0x15, 0x75, 0xe9, 0xa2, 0x21, 0xe1, 0x15, 0x4a, + 0xb9, 0xa0, 0x80, 0x01, 0x24, 0xf0, 0x00, 0x1a, 0xe1, 0xc9, 0x82, 0x53, 0xc0, 0x00, 0xe3, 0x12, + 0x1e, 0xc0, 0x97, 0x10, 0x42, 0x43, 0x20, 0xde, 0x1c, 0x1f, 0x49, 0x9e, 0xf8, 0x65, 0xc0, 0x43, + 0x01, 0xb8, 0x6b, 0x2c, 0x2a, 0x3e, 0xbc, 0x77, 0x37, 0x77, 0x99, 0x55, 0x5c, 0xdd, 0xdd, 0xe5, + 0x4f, 0xf2, 0xf2, 0xab, 0x0b, 0xe0, 0x1f, 0x68, 0xca, 0x18, 0x2d, 0x0c, 0xdd, 0x5e, 0x15, 0xdc, + 0x72, 0x5d, 0xc2, 0x42, 0xd9, 0x0c, 0xfd, 0x18, 0x56, 0x0a, 0xc9, 0x4d, 0xc4, 0xbc, 0x08, 0x01, + 0x01, 0xb3, 0x83, 0x8c, 0xec, 0xc2, 0x70, 0xd4, 0x27, 0xcb, 0xb2, 0xcc, 0x28, 0xa9, 0x23, 0x41, + 0x70, 0x42, 0x28, 0x70, 0x3c, 0xa8, 0x02, 0x1a, 0x87, 0x05, 0x81, 0xe7, 0xca, 0x10, 0xa8, 0x39, + 0x1f, 0x0d, 0xe6, 0xba, 0x62, 0xb2, 0x43, 0xe1, 0xc6, 0x70, 0x01, 0x11, 0xb8, 0xde, 0x46, 0x16, + 0xa4, 0xfb, 0x69, 0x83, 0xfe, 0xb6, 0x5e, 0x7e, 0x3d, 0x9d, 0xbc, 0x4c, 0xc5, 0xe6, 0x31, 0xfd, + 0x3f, 0x86, 0xf0, 0x04, 0xb2, 0x0e, 0xbe, 0x26, 0x05, 0x24, 0xc6, 0xbb, 0xd7, 0x2e, 0xb6, 0xed, + 0x9f, 0x92, 0x3a, 0xd6, 0x84, 0x07, 0xc5, 0xeb, 0xb3, 0xc6, 0x74, 0xf8, 0x6c, 0x82, 0x00, 0x01, + 0xff, 0x06, 0x2c, 0xce, 0x95, 0x23, 0x63, 0x31, 0xcb, 0x3c, 0x19, 0x7c, 0x9c, 0x3e, 0x28, 0x86, + 0x80, 0xf0, 0x3c, 0x9d, 0x59, 0xd3, 0x83, 0xe2, 0xc0, 0x37, 0xde, 0x58, 0x00, 0x62, 0x3d, 0x9c, + 0xe3, 0xe3, 0x02, 0xca, 0xb6, 0xb2, 0xbf, 0x0b, 0xb2, 0x80, 0x07, 0xdc, 0x51, 0x30, 0x0e, 0x9b, + 0x01, 0xf5, 0xff, 0xdf, 0x26, 0xed, 0xf7, 0xbb, 0x96, 0xdc, 0x56, 0xe2, 0xb3, 0xf1, 0x22, 0xc3, + 0xfc, 0x8e, 0xfc, 0x3b, 0x1f, 0x52, 0xa8, 0x94, 0x9c, 0xa9, 0x30, 0x1c, 0x1c, 0x7c, 0x6c, 0xf9, + 0x60, 0x19, 0x21, 0x52, 0x40, 0x2b, 0x85, 0x20, 0x20, 0x88, 0x5b, 0xcc, 0xe3, 0xcb, 0xfe, 0x0a, + 0x7a, 0x13, 0xd3, 0x70, 0xf0, 0x80, 0x75, 0x72, 0xc0, 0x03, 0x89, 0x03, 0xc7, 0x25, 0xc7, 0x20, + 0x7c, 0xe0, 0xf1, 0xc8, 0xf8, 0xa0, 0x63, 0x87, 0xf0, 0x74, 0xb9, 0x65, 0x85, 0x10, 0x70, 0xc0, + 0x49, 0x83, 0x61, 0xa0, 0xd5, 0xe8, 0x90, 0x7d, 0xf0, 0xbb, 0x20, 0x03, 0xfe, 0xa1, 0x99, 0xba, + 0x0f, 0x1b, 0xa9, 0x72, 0xf1, 0x5b, 0xcb, 0xcb, 0x31, 0x0f, 0x0a, 0x9b, 0x8d, 0xf6, 0xc8, 0xe7, + 0xd2, 0x97, 0x0c, 0x81, 0x04, 0x6c, 0x90, 0xa9, 0x44, 0x95, 0x9a, 0x72, 0xc8, 0xf0, 0xbc, 0x9c, + 0x1f, 0x24, 0x82, 0xa7, 0x8f, 0x38, 0x07, 0x8e, 0x83, 0xe5, 0xe2, 0x9a, 0xb5, 0x2e, 0x84, 0x27, + 0xf4, 0xe2, 0x07, 0x7e, 0x1d, 0x47, 0x00, 0x1a, 0xf2, 0xd0, 0x2c, 0x2c, 0x61, 0xad, 0xfc, 0xdd, + 0xcf, 0xc3, 0x97, 0xf5, 0x7f, 0x94, 0x42, 0x85, 0x8b, 0x72, 0xf1, 0x6d, 0xbd, 0x2a, 0xcb, 0xa5, + 0xd4, 0xd3, 0xe1, 0xc4, 0x40, 0x03, 0x51, 0x01, 0x86, 0x8e, 0x49, 0xea, 0x5c, 0x2b, 0x97, 0xbc, + 0xb0, 0x07, 0x14, 0x06, 0xef, 0x5d, 0x6d, 0x9f, 0x9e, 0x3c, 0xf7, 0x96, 0xc3, 0x46, 0x4e, 0xc5, + 0x10, 0xfc, 0xd0, 0x3a, 0xc8, 0xc7, 0xf0, 0xd4, 0x80, 0x11, 0xc0, 0x5c, 0xb7, 0x70, 0x18, 0xc2, + 0xa7, 0x8b, 0x1c, 0x56, 0x4e, 0x23, 0xf6, 0x7b, 0x78, 0xfb, 0xc6, 0x3e, 0xec, 0xef, 0x1a, 0x64, + 0x33, 0x80, 0xc0, 0x02, 0xc8, 0xd2, 0xa6, 0x20, 0x07, 0x04, 0x0f, 0x2c, 0x01, 0x96, 0xb2, 0xc0, + 0xc5, 0x58, 0xa6, 0x70, 0x03, 0xc9, 0xc1, 0x52, 0x50, 0x00, 0x70, 0x55, 0x4a, 0x4e, 0x54, 0xb0, + 0xce, 0x00, 0xf2, 0xc3, 0x08, 0x44, 0x30, 0x45, 0x85, 0x8f, 0x2a, 0x03, 0xef, 0xf0, 0x56, 0x56, + 0x6f, 0xd3, 0xbb, 0x7b, 0xc5, 0x0b, 0x40, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x5f, 0x2f, 0xb0, + 0x4a, 0x04, 0x9d, 0x0d, 0xe8, 0x17, 0xfa, 0xf4, 0xdd, 0x17, 0x2b, 0xeb, 0xd5, 0xd1, 0x3d, 0xf5, + 0xe8, 0x73, 0xab, 0xc3, 0x1d, 0x7b, 0xea, 0xf0, 0xdf, 0x57, 0x2b, 0xab, 0x45, 0xf5, 0xab, 0xeb, + 0x55, 0xd7, 0xaf, 0xae, 0x4a, 0x9f, 0x57, 0xae, 0xad, 0x5d, 0x5f, 0xea, 0xf3, 0xf4, 0x77, 0x84, + 0xfa, 0x11, 0xb1, 0x0c, 0x75, 0xe9, 0xfa, 0xbc, 0xdd, 0x5a, 0xba, 0xf5, 0x75, 0xe8, 0xde, 0xbd, + 0x0a, 0xf5, 0x78, 0xde, 0xaf, 0x0f, 0xf5, 0xca, 0x37, 0xad, 0x7d, 0x5e, 0x5e, 0x8a, 0xff, 0x5e, + 0xfa, 0xb5, 0xf5, 0x6a, 0xea, 0xf5, 0xd5, 0xfe, 0xaf, 0x27, 0x56, 0x93, 0xa2, 0x57, 0xc9, 0x7b, + 0xc1, 0xc7, 0x57, 0x85, 0x7a, 0xb9, 0xf5, 0x62, 0x7e, 0xbd, 0x27, 0x5a, 0x84, 0x3a, 0x3e, 0x5f, + 0x46, 0xfd, 0xf4, 0x57, 0xae, 0xbd, 0xf5, 0xe9, 0x3a, 0x2b, 0xd7, 0x04, 0xa6, 0x6d, 0x7b, 0xbd, + 0xe2, 0xfa, 0xd7, 0xd6, 0x29, 0x71, 0x0b, 0xd5, 0x89, 0x5e, 0xfa, 0xf7, 0xd7, 0xa2, 0xba, 0xf5, + 0x75, 0xe8, 0xde, 0xaf, 0x3c, 0x4d, 0x97, 0x77, 0x30, 0xe6, 0x42, 0x91, 0x18, 0xa4, 0xdd, 0x7b, + 0xeb, 0xd5, 0xd7, 0xfe, 0x25, 0x47, 0x7f, 0xd7, 0xff, 0x5f, 0xc2, 0xbd, 0x7a, 0x16, 0xe8, 0xcc, + 0x5f, 0x21, 0xdd, 0xf3, 0x75, 0xef, 0xaf, 0x7d, 0x7a, 0x4e, 0xaf, 0x27, 0x56, 0x8d, 0xea, 0xd5, + 0xd6, 0xab, 0xab, 0xfd, 0x5e, 0x6e, 0x8a, 0xc4, 0xb1, 0x1a, 0xe8, 0x9d, 0x5d, 0x1e, 0x29, 0x7a, + 0x37, 0x7d, 0x7a, 0x4e, 0xbd, 0x78, 0x85, 0xea, 0xec, 0xbb, 0xb9, 0xba, 0x23, 0xc7, 0xf4, 0x57, + 0xbe, 0x09, 0x35, 0xaf, 0x7c, 0xe2, 0x15, 0x68, 0x97, 0xc7, 0x74, 0x7e, 0x93, 0xaf, 0x7d, 0x62, + 0x89, 0xe8, 0x59, 0x6b, 0xe8, 0x67, 0x57, 0x35, 0x62, 0xeb, 0x0c, 0x28, 0x2a, 0x97, 0xdf, 0xfe, + 0xdf, 0x63, 0x1c, 0xa1, 0x00, 0x34, 0x06, 0x48, 0xa1, 0x22, 0x40, 0xfa, 0x66, 0xe3, 0xf6, 0xfe, + 0x08, 0xea, 0xaa, 0xaf, 0x13, 0xd1, 0x5e, 0x23, 0x82, 0x43, 0x5d, 0xdd, 0x82, 0xe8, 0xee, 0x44, + 0x77, 0x55, 0xd1, 0xc9, 0x3c, 0x1f, 0x5d, 0xa3, 0xfa, 0xb5, 0x8c, 0x24, 0x3e, 0xf1, 0xd3, 0x18, + 0xe1, 0xf0, 0xf2, 0x38, 0x0e, 0x35, 0x0f, 0x8e, 0x00, 0xd8, 0x85, 0xc6, 0xa0, 0x80, 0x1d, 0xa5, + 0x34, 0x6f, 0x82, 0x08, 0x2d, 0xde, 0xf8, 0x9e, 0x7a, 0x3a, 0x22, 0x51, 0x0b, 0x78, 0x60, 0xeb, + 0xf4, 0x34, 0x76, 0xa1, 0xe4, 0x31, 0x08, 0x87, 0x8e, 0xfe, 0xdf, 0xc1, 0x1d, 0x57, 0xeb, 0xeb, + 0x9b, 0xea, 0xcb, 0x10, 0xb9, 0xd7, 0x15, 0x28, 0x7d, 0x8a, 0xcf, 0xe3, 0x23, 0xe2, 0x13, 0x88, + 0x4b, 0x12, 0x86, 0x06, 0x3d, 0x0d, 0xff, 0xfd, 0x34, 0xfd, 0x39, 0xf5, 0x8d, 0x2e, 0x0a, 0x3a, + 0x08, 0x3a, 0xba, 0x17, 0x04, 0xf8, 0x20, 0x04, 0xa7, 0xd5, 0x62, 0x9e, 0x89, 0x0f, 0x19, 0x2c, + 0x4a, 0x80, 0xe1, 0x8b, 0x58, 0x8a, 0xb3, 0xb2, 0x06, 0x00, 0x7a, 0x7f, 0x80, 0x80, 0x01, 0x03, + 0x89, 0xc3, 0x8f, 0x0c, 0xe8, 0xd5, 0x08, 0xf3, 0x6a, 0xaa, 0x7e, 0x49, 0x71, 0x29, 0xf5, 0x72, + 0x88, 0x7d, 0xcd, 0x13, 0xae, 0x52, 0x69, 0xb9, 0x03, 0x91, 0x20, 0x3a, 0xba, 0x5b, 0xff, 0xf6, + 0xdb, 0x14, 0xab, 0xb6, 0xdf, 0xc6, 0x32, 0x80, 0x3d, 0x97, 0xd4, 0x23, 0x6a, 0x12, 0x20, 0x4c, + 0x1c, 0x01, 0x39, 0x14, 0x4e, 0xbc, 0x9a, 0x4d, 0x4e, 0x38, 0x88, 0xc0, 0xe3, 0xd8, 0x09, 0x00, + 0x12, 0x21, 0x70, 0xa4, 0x28, 0x2a, 0x5e, 0x70, 0x00, 0xf0, 0x72, 0x1f, 0x0e, 0x98, 0x35, 0x36, + 0x07, 0x74, 0xa1, 0x59, 0x19, 0xb0, 0xb1, 0x30, 0xd8, 0xef, 0xfc, 0x11, 0xf4, 0x27, 0x28, 0x98, + 0x47, 0xf7, 0x52, 0x66, 0xb9, 0xba, 0xaa, 0x89, 0xaf, 0x58, 0x79, 0x08, 0x01, 0xf9, 0x72, 0xde, + 0xd7, 0x4d, 0x3d, 0x34, 0xf1, 0xc4, 0xc5, 0xb6, 0xed, 0xfc, 0x38, 0x48, 0x08, 0xe8, 0x6a, 0x47, + 0xaf, 0xf6, 0xdb, 0xdb, 0x6d, 0xb6, 0xcb, 0x8b, 0x6d, 0xd3, 0x4f, 0x6f, 0xdd, 0x55, 0x60, 0x8b, + 0x82, 0x31, 0x28, 0xc9, 0x45, 0x97, 0xac, 0x42, 0x2b, 0xfc, 0x10, 0xd5, 0x7a, 0xae, 0xac, 0x7c, + 0xb7, 0xd4, 0xc1, 0x84, 0x60, 0xd3, 0x2d, 0xff, 0xa6, 0x9e, 0x9a, 0x6d, 0x87, 0x91, 0x80, 0x06, + 0x05, 0x07, 0x6a, 0x18, 0xea, 0x8f, 0x7a, 0xff, 0xc1, 0xdf, 0x83, 0x8f, 0xdb, 0x6c, 0xb5, 0x8a, + 0xb0, 0x90, 0xb1, 0x4c, 0xb0, 0x5f, 0x0c, 0x54, 0x0c, 0xa3, 0xb7, 0x81, 0xa0, 0x48, 0x2c, 0xb9, + 0xf3, 0xc3, 0xc7, 0xb5, 0xaf, 0x1f, 0xd7, 0xb8, 0x8c, 0x4c, 0x44, 0x14, 0x65, 0xee, 0x73, 0xc5, + 0x62, 0xb2, 0xd8, 0xac, 0x5d, 0x70, 0x42, 0x20, 0x15, 0xd5, 0x70, 0x75, 0xf9, 0x44, 0x35, 0x38, + 0x71, 0xe3, 0xcf, 0x0b, 0x82, 0xca, 0x1a, 0x81, 0x44, 0x48, 0xde, 0xaa, 0xee, 0xb2, 0x63, 0x31, + 0xe7, 0x83, 0xa5, 0x80, 0xe2, 0x2c, 0x16, 0xa5, 0xd3, 0xaf, 0xc3, 0x8a, 0x00, 0xdd, 0x92, 0xdf, + 0x7b, 0x7f, 0xd2, 0xba, 0x49, 0x60, 0xfd, 0xf6, 0xdb, 0x36, 0x97, 0x7f, 0x0e, 0x28, 0x25, 0x03, + 0x49, 0x69, 0xbf, 0x4d, 0x3b, 0x7b, 0x6d, 0xe3, 0xca, 0xd3, 0x49, 0xa7, 0xb6, 0xde, 0x04, 0x08, + 0x46, 0xee, 0xef, 0x8e, 0x2d, 0xbe, 0xa7, 0xe1, 0xae, 0x93, 0x6b, 0x4c, 0x5b, 0xff, 0x82, 0x4e, + 0xab, 0x17, 0xc1, 0x16, 0x6d, 0x26, 0x70, 0x70, 0x43, 0x1b, 0x0b, 0x55, 0xd4, 0xdd, 0x9a, 0xfb, + 0x8a, 0xdd, 0x5e, 0x10, 0xa4, 0x03, 0x69, 0x8b, 0x8e, 0x77, 0xc3, 0x8a, 0x01, 0x29, 0x9a, 0x23, + 0xb9, 0xdf, 0xb7, 0xea, 0x99, 0x0c, 0x6d, 0x8c, 0x41, 0x16, 0xc1, 0x99, 0x7f, 0xe1, 0xc5, 0x00, + 0x27, 0x05, 0x6e, 0x86, 0x42, 0x02, 0xcf, 0xc2, 0xd9, 0x65, 0x93, 0xc6, 0x28, 0x58, 0xa1, 0x69, + 0xe6, 0xbf, 0x0a, 0x00, 0xe0, 0xa1, 0xfb, 0x50, 0x06, 0x60, 0xf8, 0x00, 0x99, 0xab, 0xa7, 0xc3, + 0xca, 0x03, 0xcd, 0xe1, 0x27, 0x8b, 0xff, 0xa6, 0x9a, 0x64, 0xf8, 0xc4, 0xc5, 0xb1, 0x23, 0xa3, + 0xeb, 0xff, 0x82, 0x38, 0xbc, 0x5d, 0x31, 0x05, 0xd1, 0x3d, 0x1f, 0x58, 0x68, 0x90, 0x01, 0x45, + 0x5e, 0xc2, 0xad, 0xfb, 0x8e, 0xee, 0x21, 0xf3, 0xad, 0x5e, 0xa2, 0xb7, 0xcb, 0xc6, 0x94, 0x35, + 0x50, 0xe2, 0x80, 0x3f, 0x87, 0xc8, 0x90, 0xe8, 0x00, 0x84, 0x00, 0xb3, 0xd4, 0xea, 0x2d, 0xa6, + 0x59, 0x69, 0xa6, 0x2e, 0xa5, 0xe6, 0xe9, 0x8b, 0x63, 0xb7, 0x77, 0x03, 0x2c, 0x04, 0x27, 0x56, + 0xe7, 0xe9, 0xe9, 0xc3, 0x91, 0x00, 0x01, 0xda, 0x6c, 0x22, 0x5b, 0x54, 0x13, 0x59, 0xf7, 0xe2, + 0xf6, 0xf0, 0x7f, 0xdb, 0x6e, 0x3e, 0x9a, 0x69, 0x83, 0xfe, 0x4e, 0x5d, 0x85, 0xd9, 0x64, 0x55, + 0xb7, 0x88, 0x6b, 0xfe, 0x18, 0x89, 0x1e, 0x2b, 0x1a, 0x01, 0xa0, 0x17, 0x82, 0xa0, 0x78, 0x55, + 0x79, 0xc0, 0x0e, 0x01, 0x40, 0x3c, 0x74, 0x80, 0xe3, 0x13, 0x83, 0x8d, 0xc4, 0x3b, 0xfe, 0x13, + 0x16, 0x4c, 0x97, 0x67, 0xfc, 0x67, 0x66, 0x7b, 0xc5, 0x86, 0x11, 0x00, 0x27, 0x56, 0xcc, 0x10, + 0xaf, 0x4e, 0x3f, 0xf4, 0xd3, 0x04, 0x0d, 0x85, 0x14, 0x72, 0x27, 0xd3, 0x4f, 0xfd, 0x70, 0xe2, + 0x80, 0x2f, 0x52, 0x8e, 0x37, 0xff, 0xed, 0xf2, 0xdb, 0xff, 0x01, 0x80, 0x24, 0x6e, 0x54, 0x47, + 0xe9, 0x17, 0x05, 0x65, 0x83, 0x4a, 0xa2, 0x79, 0x68, 0x2f, 0x64, 0x79, 0xc0, 0x48, 0x96, 0xd9, + 0x7f, 0xf8, 0x12, 0x20, 0xa6, 0x4e, 0xf1, 0xbc, 0x57, 0x15, 0xac, 0x9c, 0x2a, 0x4c, 0x54, 0x01, + 0x17, 0x11, 0x17, 0x49, 0x4b, 0x9f, 0x0e, 0x29, 0x9e, 0xb1, 0x7d, 0x6b, 0xe1, 0xba, 0xdb, 0xae, + 0x78, 0x2f, 0x92, 0x04, 0x90, 0x80, 0x2c, 0x3d, 0xdc, 0x43, 0xc9, 0xf7, 0x37, 0x1e, 0xfe, 0x14, + 0x15, 0x16, 0x8c, 0x31, 0x80, 0x0c, 0x26, 0x25, 0xe6, 0x33, 0x07, 0x9e, 0x99, 0x79, 0xbe, 0x7e, + 0xdd, 0xab, 0xba, 0xca, 0x87, 0x15, 0x62, 0xbc, 0x34, 0xa0, 0x02, 0x59, 0x2d, 0xb3, 0x44, 0x3a, + 0xf7, 0xfa, 0x4e, 0x7e, 0xde, 0xdb, 0x6d, 0xec, 0xff, 0x3f, 0x3f, 0x7f, 0x0d, 0xe8, 0xef, 0x01, + 0x20, 0x02, 0xa0, 0x6c, 0x28, 0x00, 0x06, 0x14, 0x72, 0x0b, 0x8f, 0x02, 0xc2, 0x91, 0x29, 0x30, + 0x29, 0x5e, 0xa6, 0x60, 0xfb, 0x49, 0x05, 0x4e, 0x01, 0xc6, 0xc5, 0x0c, 0x94, 0x56, 0x20, 0x96, + 0xcc, 0xa8, 0x4b, 0xcb, 0x03, 0xfa, 0xfe, 0x1d, 0x50, 0x0d, 0x1d, 0xa2, 0x06, 0xfd, 0xfe, 0xf6, + 0xb3, 0xb7, 0x8e, 0xdd, 0xfe, 0xd9, 0xff, 0xee, 0x98, 0xb6, 0xaa, 0x50, 0xf1, 0x93, 0xfd, 0x3f, + 0x05, 0xd1, 0x71, 0x71, 0x71, 0x4d, 0xf7, 0x05, 0x80, 0xd1, 0x3c, 0x9b, 0xdf, 0xc1, 0x56, 0x2b, + 0x71, 0x58, 0xa3, 0x2c, 0x06, 0x28, 0xc5, 0x01, 0x89, 0x70, 0xb0, 0x1c, 0x4b, 0x81, 0xf2, 0x97, + 0x0e, 0x92, 0x00, 0x12, 0xcf, 0x32, 0x38, 0x86, 0xa0, 0xbd, 0xde, 0x5d, 0xb9, 0xb8, 0xed, 0xdb, + 0xad, 0xb3, 0x7c, 0x5f, 0xd3, 0x20, 0xe5, 0x65, 0x3f, 0xc3, 0xcc, 0xc0, 0x0b, 0xee, 0x06, 0x84, + 0x9a, 0x1c, 0x19, 0xa4, 0xef, 0xc8, 0x9f, 0x14, 0xb4, 0xdd, 0xd6, 0x7d, 0x74, 0xd3, 0x37, 0x1d, + 0xbc, 0x78, 0xd0, 0x30, 0x50, 0x0a, 0x7c, 0x56, 0xb4, 0xf8, 0x71, 0x40, 0x07, 0xec, 0x6c, 0x1d, + 0x97, 0x52, 0x86, 0xf8, 0x64, 0x57, 0x77, 0xda, 0xb5, 0x1e, 0xe8, 0xb0, 0x1e, 0x83, 0x08, 0x7e, + 0x3d, 0xa8, 0xd6, 0x78, 0x96, 0x71, 0x61, 0x6e, 0xe3, 0xab, 0x96, 0x59, 0x77, 0x4c, 0x5b, 0x06, + 0x19, 0x81, 0x09, 0x46, 0xbb, 0xdb, 0x2f, 0x8f, 0x10, 0x03, 0x60, 0x69, 0x2e, 0x42, 0x00, 0x25, + 0x1f, 0x68, 0x9c, 0xa9, 0xb2, 0x4c, 0x15, 0x76, 0x3b, 0x00, 0x01, 0x00, 0xbc, 0x0d, 0x09, 0xca, + 0xa1, 0x60, 0x00, 0x20, 0x13, 0x1c, 0x40, 0x00, 0xfa, 0xd9, 0x7c, 0x79, 0xe1, 0xf8, 0x35, 0x0f, + 0x72, 0x84, 0x98, 0x4c, 0x9f, 0xa2, 0x61, 0x53, 0xce, 0xff, 0xe5, 0x12, 0xf2, 0xdb, 0x85, 0x38, + 0x5f, 0xc5, 0xe0, 0xe2, 0x5e, 0xab, 0xc6, 0x71, 0xf8, 0x16, 0x63, 0x65, 0xe2, 0x8c, 0x74, 0xb0, + 0xfe, 0x0a, 0x37, 0xc9, 0x87, 0x00, 0x79, 0x66, 0x5d, 0x03, 0x9f, 0x1a, 0x7e, 0x0f, 0x78, 0xad, + 0x40, 0xe0, 0x00, 0x20, 0x03, 0xc0, 0x00, 0x40, 0x21, 0x05, 0x00, 0x15, 0x18, 0xf0, 0x1e, 0xdf, + 0x07, 0xbf, 0x86, 0xd4, 0x00, 0x6f, 0xc1, 0xc6, 0x8e, 0x5c, 0x21, 0xef, 0xdf, 0xe3, 0xcb, 0x56, + 0x9a, 0x6a, 0x96, 0xb2, 0xb9, 0x47, 0xdd, 0x54, 0xb2, 0xc5, 0xb0, 0xd6, 0xbd, 0xb1, 0x2e, 0xfd, + 0x38, 0x71, 0x40, 0x07, 0xdd, 0x84, 0xf6, 0x11, 0x7b, 0xef, 0xf3, 0x8d, 0xcf, 0xcb, 0xb2, 0xed, + 0x99, 0x2c, 0xb6, 0xad, 0xe2, 0xad, 0xb3, 0xf2, 0xc5, 0x90, 0x7b, 0x64, 0xdf, 0xb7, 0x0e, 0xe0, + 0x01, 0x6e, 0xa0, 0x33, 0x5b, 0x30, 0x5c, 0x5d, 0x5e, 0x4e, 0x15, 0x7e, 0x38, 0x37, 0xe2, 0xad, + 0xb5, 0x9f, 0x16, 0x03, 0xc6, 0x55, 0x94, 0xb6, 0xe6, 0x20, 0x1f, 0xc6, 0xde, 0x5f, 0x8b, 0x71, + 0x86, 0x58, 0xda, 0x03, 0x54, 0x6b, 0x0d, 0xdc, 0x06, 0xcc, 0x0f, 0x61, 0xf0, 0xeb, 0x80, 0x05, + 0x2c, 0xe4, 0xc5, 0x2a, 0xd3, 0xc1, 0x3b, 0x6c, 0xde, 0x3f, 0xd6, 0x3b, 0x71, 0xc0, 0xde, 0x2b, + 0xc6, 0xda, 0xca, 0x84, 0x23, 0xd0, 0x67, 0x86, 0xa8, 0x03, 0x4e, 0x22, 0x71, 0xfe, 0x1b, 0x45, + 0x00, 0x49, 0x54, 0x87, 0x72, 0xc9, 0xdf, 0xfb, 0x22, 0x51, 0x2b, 0x88, 0x86, 0x3c, 0xb3, 0xbb, + 0xb6, 0x48, 0x94, 0x6b, 0xb0, 0x8e, 0x5e, 0x77, 0x92, 0x38, 0x2f, 0x39, 0x80, 0x32, 0xa6, 0x6e, + 0xff, 0xf0, 0x84, 0x69, 0x84, 0xfc, 0xbd, 0x35, 0x1e, 0xfc, 0x2c, 0xa9, 0x60, 0x18, 0x3d, 0x73, + 0xc0, 0x00, 0x96, 0x13, 0x00, 0x55, 0xfd, 0x42, 0x21, 0x14, 0xe9, 0x7c, 0x26, 0x08, 0xce, 0xaf, + 0xc9, 0xca, 0x54, 0x37, 0xd7, 0x0f, 0x5e, 0xb9, 0x58, 0x8a, 0x37, 0x14, 0x62, 0x1c, 0x24, 0x05, + 0x42, 0x12, 0x4c, 0x77, 0x4e, 0x0f, 0x5f, 0xe1, 0xc5, 0x00, 0x67, 0x0c, 0x34, 0x48, 0x17, 0xd6, + 0x99, 0x39, 0x7c, 0x94, 0xea, 0x5d, 0xff, 0x4d, 0x5b, 0x14, 0xac, 0xb7, 0x8f, 0xf0, 0xda, 0x80, + 0x16, 0xcf, 0x12, 0xb5, 0xec, 0x1b, 0xf7, 0x4c, 0x43, 0xcf, 0xd6, 0xb3, 0x78, 0xad, 0xb1, 0x2f, + 0x1b, 0x4e, 0x9a, 0x7f, 0x0c, 0x12, 0x00, 0x36, 0xef, 0x16, 0xbd, 0x79, 0xef, 0xa8, 0xdd, 0xb9, + 0x6d, 0xfe, 0xeb, 0xa8, 0xae, 0x4b, 0xf4, 0xe4, 0xb0, 0xba, 0x80, 0x4a, 0xfc, 0x8c, 0x2e, 0x64, + 0x2d, 0x5f, 0x27, 0xe5, 0xe9, 0x9f, 0x9f, 0xe7, 0xe7, 0xfa, 0xbc, 0x57, 0x08, 0xfc, 0x46, 0xf8, + 0x79, 0x40, 0x08, 0xaa, 0x76, 0x09, 0x97, 0x9b, 0xde, 0xba, 0x60, 0xff, 0xe9, 0x93, 0xb7, 0x5d, + 0x6d, 0x8a, 0xe4, 0xfc, 0xbf, 0x25, 0x4d, 0x9f, 0xdf, 0xc6, 0x70, 0xd1, 0x85, 0x18, 0x58, 0x01, + 0x56, 0x8e, 0x07, 0x81, 0x4a, 0xe9, 0x83, 0xff, 0xfc, 0x36, 0xe0, 0x04, 0xac, 0xc6, 0x73, 0x92, + 0xb2, 0x03, 0xb0, 0xd1, 0x18, 0x7f, 0xc1, 0x60, 0x77, 0x81, 0xdb, 0x43, 0xa4, 0x1b, 0xc7, 0x97, + 0x86, 0xa4, 0x1a, 0x61, 0x84, 0x12, 0x39, 0x40, 0xea, 0x5c, 0x21, 0x03, 0x7b, 0x24, 0x71, 0x66, + 0xf8, 0x77, 0x00, 0x1c, 0x11, 0x8b, 0x5f, 0x02, 0x35, 0x18, 0xdd, 0xea, 0x6f, 0x8e, 0xdd, 0xdd, + 0x55, 0x77, 0x0a, 0x3f, 0x8e, 0xbe, 0x38, 0xfe, 0xb0, 0x11, 0x04, 0x27, 0x93, 0xf6, 0xe1, 0xdc, + 0x00, 0x7f, 0x63, 0xea, 0x73, 0xf3, 0xa8, 0x2a, 0x06, 0xaa, 0xc3, 0x79, 0x60, 0xc7, 0x01, 0xbd, + 0x7f, 0x46, 0x3d, 0xf6, 0xf8, 0xdf, 0xcb, 0x5d, 0x72, 0xd6, 0xdb, 0x62, 0xac, 0x1c, 0x86, 0xcc, + 0xce, 0xfa, 0xd9, 0xe3, 0x2f, 0xfc, 0x20, 0x03, 0xc0, 0x6c, 0x39, 0x72, 0x87, 0xc2, 0x52, 0xc1, + 0x9c, 0x38, 0x4a, 0x54, 0xb3, 0x6e, 0x9d, 0xe2, 0x83, 0x3c, 0x70, 0x3c, 0xf5, 0x65, 0x8e, 0xd3, + 0x68, 0x36, 0xa9, 0xbb, 0x7f, 0xf1, 0x30, 0x50, 0x57, 0x85, 0x41, 0x52, 0xc7, 0x8a, 0x31, 0x47, + 0x94, 0x27, 0xcf, 0x55, 0x9a, 0xfe, 0x01, 0x58, 0x04, 0x23, 0x48, 0x16, 0x32, 0x0d, 0x97, 0xf4, + 0xd9, 0x60, 0x14, 0x1c, 0x03, 0x51, 0x40, 0xe3, 0x0d, 0x45, 0x90, 0x3f, 0x9c, 0xf8, 0x25, 0xe5, + 0xf5, 0xee, 0x90, 0x40, 0x0b, 0x20, 0x0b, 0x41, 0xd9, 0x43, 0x18, 0xa6, 0x33, 0xfc, 0xa3, 0x69, + 0xfc, 0x10, 0x0d, 0x8e, 0x01, 0x6c, 0x1c, 0x03, 0xb0, 0x94, 0x00, 0x08, 0xf8, 0xf0, 0x01, 0xc2, + 0xc0, 0xa1, 0x40, 0xa3, 0xc0, 0x70, 0x74, 0xf0, 0x75, 0xe0, 0xef, 0x95, 0x9f, 0xc7, 0xe6, 0xec, + 0x17, 0x08, 0x24, 0x75, 0x1c, 0x1f, 0x1c, 0x0f, 0xe9, 0xfc, 0x39, 0x80, 0x06, 0x70, 0x1a, 0xa2, + 0x5d, 0x49, 0x66, 0x1d, 0xac, 0xff, 0xc5, 0x31, 0x0d, 0xb4, 0x6c, 0xd1, 0x57, 0xa0, 0x71, 0xf9, + 0x40, 0xd5, 0x16, 0x00, 0x34, 0x73, 0x7b, 0x73, 0xb7, 0x4c, 0xed, 0xff, 0x0f, 0x28, 0x03, 0xe1, + 0x55, 0x09, 0xa9, 0x9e, 0x18, 0xbd, 0xfb, 0xeb, 0xac, 0x70, 0xfe, 0x39, 0xf9, 0x6b, 0x2d, 0x77, + 0x15, 0x6b, 0x7c, 0x28, 0xb2, 0xd6, 0x50, 0xea, 0x54, 0x3d, 0x4b, 0x59, 0x6b, 0xcd, 0x8f, 0xfe, + 0x1c, 0x50, 0x05, 0xb4, 0x50, 0x0e, 0x78, 0x46, 0x02, 0xac, 0x41, 0xce, 0xee, 0xab, 0x75, 0x8e, + 0x06, 0xf2, 0x5f, 0xc7, 0x6e, 0xeb, 0x1d, 0xf9, 0x60, 0xb6, 0x69, 0x40, 0xd5, 0x2c, 0x05, 0x9c, + 0x00, 0xe8, 0xe1, 0xfc, 0x73, 0xf0, 0x33, 0x1c, 0x72, 0x22, 0xd6, 0xcf, 0xf0, 0xf1, 0x20, 0x16, + 0x4b, 0x36, 0x09, 0xe9, 0x8c, 0xf7, 0xfe, 0x45, 0x8b, 0xac, 0xa8, 0x6f, 0x0a, 0xf1, 0xdb, 0xf5, + 0xd7, 0x58, 0x3b, 0x70, 0x73, 0xf0, 0xd2, 0x31, 0xdb, 0xd3, 0x0a, 0x19, 0x34, 0x4a, 0x80, 0xe3, + 0x08, 0xb8, 0xc5, 0xda, 0x13, 0x8d, 0xf8, 0x1e, 0x04, 0x8d, 0xaf, 0xa6, 0xe8, 0x85, 0x45, 0x45, + 0xc2, 0xc0, 0x1a, 0xb3, 0xcb, 0x01, 0x45, 0x11, 0xab, 0x60, 0x2b, 0x45, 0x94, 0xc8, 0x59, 0xfe, + 0x99, 0xea, 0xc7, 0x6e, 0x1e, 0xac, 0xf5, 0xfe, 0x1e, 0x9c, 0x01, 0x45, 0x56, 0x61, 0xd2, 0x3f, + 0xcb, 0xfc, 0xdf, 0x39, 0xfd, 0x32, 0x44, 0xf7, 0x9b, 0xb7, 0xb3, 0xd6, 0x3b, 0xfb, 0xb8, 0x1a, + 0xdb, 0x6b, 0xf5, 0xc1, 0x3d, 0xab, 0x6b, 0x77, 0x3e, 0x6a, 0xb8, 0x4b, 0xb1, 0xad, 0xa9, 0xd4, + 0xe0, 0x26, 0x63, 0x62, 0x03, 0xe5, 0xe2, 0x98, 0xd2, 0x19, 0xe3, 0x84, 0x81, 0x56, 0x30, 0x86, + 0x0e, 0x8b, 0x9b, 0xb3, 0x49, 0x82, 0xb1, 0xb1, 0x51, 0x20, 0xaf, 0xb2, 0xf9, 0xff, 0xe1, 0x00, + 0x62, 0x36, 0x0b, 0xa0, 0xd3, 0x0f, 0x79, 0xe0, 0x03, 0xc7, 0x4f, 0xb0, 0x83, 0xca, 0x9e, 0xe3, + 0xfc, 0x63, 0xc7, 0x8c, 0xc5, 0x58, 0x29, 0x1e, 0x45, 0x8b, 0x08, 0x40, 0x10, 0x18, 0x25, 0xa8, + 0x18, 0x45, 0x20, 0xf2, 0xe2, 0x84, 0x2a, 0xcf, 0x87, 0x09, 0x00, 0x37, 0x93, 0xfc, 0x45, 0xdb, + 0x37, 0x3f, 0x37, 0xdd, 0xdb, 0xed, 0xb6, 0x9a, 0x6d, 0xb6, 0x35, 0x8f, 0xc6, 0x9d, 0x6d, 0xfc, + 0x39, 0x80, 0x66, 0xc2, 0x0e, 0x3e, 0xca, 0x5f, 0xe9, 0x90, 0xce, 0x82, 0x4c, 0x36, 0xe6, 0xd3, + 0x6d, 0xbf, 0x87, 0x14, 0x00, 0xa3, 0x92, 0x32, 0x04, 0x19, 0x6c, 0x79, 0xe5, 0xd7, 0x5b, 0xa9, + 0xfb, 0xba, 0xc7, 0x6e, 0x0e, 0xdc, 0x5d, 0x2a, 0xef, 0xe3, 0xb8, 0x22, 0xb6, 0x40, 0x31, 0x0e, + 0x1d, 0x79, 0x5b, 0x0e, 0x10, 0x80, 0x08, 0xc7, 0xc7, 0x3c, 0xe5, 0x61, 0xdf, 0xd1, 0x33, 0x5c, + 0x76, 0xe7, 0x74, 0x79, 0x6d, 0x72, 0xec, 0xf5, 0xb1, 0x3e, 0x2b, 0x91, 0x01, 0x7c, 0x97, 0xd9, + 0xfb, 0xe9, 0xf0, 0xec, 0xe0, 0x0f, 0xcd, 0xba, 0x61, 0xa3, 0x9f, 0x15, 0xf7, 0xde, 0xe9, 0x8f, + 0x75, 0x9f, 0xef, 0xed, 0xf8, 0x62, 0x94, 0x01, 0x7a, 0x69, 0xfc, 0x3a, 0xa0, 0x1a, 0xa4, 0x82, + 0x8b, 0x4c, 0x9f, 0x8f, 0xf1, 0xdb, 0xeb, 0x7b, 0xfb, 0x62, 0x5f, 0x71, 0x8c, 0x4e, 0xea, 0xda, + 0xfc, 0x36, 0xe0, 0x02, 0xf1, 0xa6, 0x16, 0x56, 0x65, 0x38, 0x4c, 0x97, 0x42, 0xba, 0x4e, 0xdb, + 0x79, 0xe6, 0x03, 0xfe, 0x3a, 0x28, 0x46, 0x2d, 0x8b, 0x69, 0xa6, 0x3a, 0x6a, 0xcb, 0x56, 0xfc, + 0x25, 0xc7, 0xd3, 0xa7, 0xa1, 0xa6, 0xef, 0xbb, 0xe1, 0xa2, 0x0e, 0xa8, 0x76, 0x1a, 0xf6, 0x12, + 0x9c, 0xc0, 0x75, 0x0b, 0x8f, 0xfe, 0x02, 0x00, 0x0e, 0x21, 0xf2, 0x16, 0x03, 0x15, 0x8a, 0x28, + 0xf8, 0x28, 0x01, 0x9e, 0x1c, 0x12, 0x00, 0x58, 0x26, 0x39, 0x05, 0x8a, 0x96, 0x61, 0xf0, 0x94, + 0xee, 0x03, 0x80, 0x01, 0x01, 0xd2, 0x4a, 0x7f, 0xbb, 0x82, 0x38, 0xbf, 0x9f, 0x1c, 0xe0, 0x0d, + 0x3d, 0xa3, 0x17, 0x8c, 0x30, 0x8e, 0x00, 0x23, 0xd8, 0xac, 0xcb, 0x04, 0x41, 0x37, 0xfb, 0xe9, + 0x95, 0x3f, 0x27, 0x1f, 0x4c, 0x9f, 0x9d, 0xb8, 0x21, 0x12, 0x30, 0x83, 0x39, 0x71, 0x60, 0x65, + 0x83, 0x07, 0xbd, 0x48, 0x65, 0x1c, 0xf2, 0xc3, 0x76, 0x8a, 0x0c, 0xb0, 0x62, 0xb1, 0x58, 0x55, + 0x52, 0x4a, 0x41, 0xc3, 0xca, 0x2d, 0x78, 0x44, 0x6c, 0xb0, 0x63, 0xde, 0x9e, 0xe1, 0x60, 0xc3, + 0xe1, 0x61, 0xf0, 0x0f, 0xf5, 0x42, 0x1f, 0xa6, 0x77, 0x05, 0x33, 0x87, 0x9a, 0x0c, 0xab, 0x90, + 0x8f, 0x62, 0x61, 0x1d, 0xc9, 0x97, 0xf8, 0x6d, 0xc0, 0x35, 0x51, 0x0c, 0x7b, 0x98, 0x7d, 0xa6, + 0x72, 0xd9, 0x6b, 0x07, 0x7e, 0xae, 0xef, 0xa2, 0x52, 0x98, 0x3a, 0x88, 0x0f, 0xca, 0x30, 0x99, + 0x3b, 0x79, 0xde, 0x12, 0x64, 0x44, 0x3c, 0x07, 0x98, 0xc9, 0xea, 0xf7, 0xfb, 0xbd, 0xd1, 0xae, + 0x7a, 0xbd, 0xb6, 0xff, 0xc2, 0xfb, 0xc4, 0x0f, 0x85, 0x00, 0x15, 0x2f, 0x28, 0x10, 0x55, 0x2f, + 0xd6, 0x2f, 0xf0, 0xe4, 0xa0, 0x0c, 0x10, 0x72, 0x59, 0x05, 0xc6, 0xbc, 0xd1, 0xcf, 0xfe, 0xe5, + 0xbe, 0xae, 0x14, 0xb3, 0x8d, 0x5b, 0x6f, 0xe1, 0xe5, 0x00, 0x04, 0x46, 0x36, 0x99, 0x4a, 0xe8, + 0x4a, 0x49, 0xc5, 0x17, 0xb1, 0x4f, 0xaa, 0x69, 0x8b, 0xad, 0x53, 0x48, 0x1d, 0xf8, 0xb0, 0x02, + 0xb4, 0x86, 0x10, 0xed, 0xa5, 0x74, 0xc6, 0xfb, 0xe1, 0xd2, 0x10, 0x00, 0x4f, 0x66, 0x33, 0x68, + 0x31, 0xb0, 0x87, 0xef, 0x54, 0xd3, 0x4d, 0x3e, 0x0c, 0x7e, 0x2c, 0x16, 0xec, 0x7e, 0xee, 0x0e, + 0xfd, 0xbc, 0x9c, 0x28, 0x06, 0xa2, 0x11, 0x52, 0x1c, 0x1f, 0xca, 0x8e, 0xba, 0x78, 0x79, 0x40, + 0x0e, 0x95, 0x79, 0xc0, 0xca, 0x29, 0xaf, 0xab, 0x67, 0xd2, 0xec, 0xbb, 0x3e, 0xae, 0x52, 0xec, + 0xbb, 0x1b, 0xad, 0xe3, 0x4f, 0xe1, 0xb5, 0x02, 0x4b, 0x69, 0x7e, 0x37, 0x72, 0xf6, 0xfe, 0x9c, + 0xb5, 0xbf, 0xa6, 0xdf, 0x5b, 0x71, 0xc6, 0x28, 0x76, 0x6f, 0xff, 0x87, 0x14, 0x00, 0xf6, 0xff, + 0x00, 0x93, 0x4b, 0xcf, 0x2f, 0x4d, 0x5c, 0x9d, 0xbf, 0x4d, 0x34, 0xd9, 0xe3, 0xe2, 0x5a, 0xfb, + 0x6d, 0xff, 0x86, 0x35, 0x37, 0x3c, 0xe2, 0xcf, 0x38, 0x27, 0x80, 0x70, 0x07, 0x08, 0xb7, 0x14, + 0x16, 0x28, 0x2f, 0xfd, 0x4c, 0x35, 0x70, 0x46, 0x5a, 0x6d, 0x5a, 0x2f, 0x8a, 0x85, 0x85, 0x4f, + 0x07, 0x37, 0x7d, 0xf8, 0x40, 0x29, 0xbb, 0x9f, 0xbf, 0x4a, 0xf7, 0x57, 0x3f, 0xb4, 0xeb, 0x84, + 0x44, 0x45, 0x18, 0xad, 0xdc, 0x56, 0x2b, 0x77, 0x09, 0x72, 0xd7, 0x4c, 0x9c, 0x35, 0xde, 0xea, + 0xdf, 0xbb, 0x7f, 0xc4, 0x07, 0x89, 0x10, 0x3d, 0x71, 0x20, 0x0e, 0x09, 0x01, 0xc3, 0xe3, 0xb2, + 0x24, 0xfa, 0x84, 0x80, 0x41, 0xc2, 0x01, 0x43, 0x03, 0x51, 0x3a, 0x26, 0xfc, 0x1a, 0x12, 0xa0, + 0xfc, 0x08, 0x00, 0x49, 0x0a, 0x45, 0x62, 0xbd, 0xa7, 0x7d, 0x60, 0xf7, 0x95, 0x55, 0x14, 0xdf, + 0x81, 0x04, 0x0a, 0x21, 0x43, 0x9f, 0xe7, 0x60, 0xb4, 0x2f, 0x3c, 0x73, 0x2f, 0x87, 0x99, 0x8b, + 0xdc, 0x40, 0xf7, 0xe0, 0xa2, 0x14, 0x10, 0x51, 0x4a, 0x71, 0xeb, 0xf0, 0x7f, 0xdb, 0x37, 0x6e, + 0xd5, 0x07, 0x3b, 0x0c, 0xe6, 0x8c, 0xea, 0xf6, 0x4f, 0xfe, 0xe0, 0x40, 0x04, 0x23, 0x64, 0x52, + 0x61, 0x76, 0x64, 0x39, 0x70, 0x75, 0x41, 0x2c, 0x7e, 0x97, 0x65, 0xe0, 0xc3, 0xaa, 0x65, 0x06, + 0x52, 0xb2, 0xa1, 0x33, 0x90, 0xf0, 0xb8, 0xe4, 0xf8, 0x60, 0xd8, 0x17, 0xa9, 0x99, 0xa8, 0x3b, + 0x64, 0xfc, 0x2e, 0x59, 0xfe, 0x22, 0x0a, 0x6f, 0xba, 0xd6, 0x5b, 0x71, 0xc4, 0x7f, 0xeb, 0x0e, + 0x4e, 0x00, 0x6a, 0x4f, 0x60, 0x94, 0x23, 0xab, 0xf9, 0x09, 0x1e, 0x24, 0xf1, 0x23, 0xcf, 0xf7, + 0x72, 0xd6, 0xee, 0xbf, 0x0e, 0xee, 0x5f, 0x8e, 0xae, 0x7b, 0xee, 0x06, 0xec, 0x06, 0x12, 0xc7, + 0x6d, 0x97, 0xc3, 0xca, 0x00, 0x08, 0x86, 0xa8, 0xcd, 0x54, 0x54, 0xf3, 0xa1, 0x29, 0x87, 0xee, + 0x2e, 0xe2, 0x7d, 0xfd, 0x5c, 0x47, 0xc7, 0x83, 0x1f, 0x8b, 0xc6, 0xc1, 0x85, 0x55, 0x91, 0x77, + 0x84, 0x03, 0xaf, 0xe0, 0x30, 0x41, 0x48, 0xd1, 0x02, 0x40, 0x70, 0x98, 0x00, 0x15, 0x1d, 0xf4, + 0x38, 0x36, 0x28, 0x70, 0x5c, 0xea, 0xca, 0x02, 0x52, 0x70, 0x02, 0xa7, 0x80, 0x01, 0x4e, 0x1c, + 0x15, 0x04, 0x52, 0xb0, 0x05, 0x86, 0x60, 0x00, 0x20, 0x11, 0x81, 0x92, 0x04, 0xa1, 0xe0, 0x1a, + 0x1c, 0x00, 0x70, 0x7f, 0x83, 0xfc, 0x10, 0x53, 0x04, 0x88, 0x4a, 0x1e, 0xd7, 0x37, 0x7f, 0x0f, + 0x60, 0x16, 0x90, 0x7c, 0xc9, 0x01, 0x8e, 0x7c, 0x7c, 0xef, 0xc9, 0x3a, 0xec, 0xe9, 0x9d, 0xec, + 0xec, 0xf3, 0xdb, 0x6c, 0x2d, 0xa9, 0xeb, 0xb7, 0xd3, 0x86, 0x09, 0x00, 0x1c, 0x3b, 0x26, 0xc8, + 0x17, 0x07, 0x81, 0x3c, 0x73, 0x4d, 0x3e, 0xdb, 0x6d, 0xb6, 0xd8, 0xab, 0x15, 0x73, 0xe1, 0x62, + 0x40, 0x0e, 0x09, 0x63, 0x25, 0x1d, 0x25, 0x71, 0x3d, 0x32, 0xfd, 0xf8, 0xab, 0x15, 0x77, 0x07, + 0x7e, 0xff, 0x81, 0x04, 0x04, 0x00, 0x29, 0x28, 0x80, 0x03, 0x87, 0x00, 0x70, 0x53, 0x3b, 0x81, + 0x40, 0x0a, 0x9c, 0x1c, 0x97, 0x71, 0xb5, 0x88, 0xb0, 0x62, 0x07, 0x07, 0x00, 0x01, 0x01, 0xcd, + 0x86, 0x14, 0x15, 0x70, 0x61, 0x95, 0x6b, 0xf5, 0xfe, 0xf7, 0xf9, 0xc1, 0xc8, 0x44, 0x69, 0x42, + 0xc5, 0x4f, 0xe1, 0xde, 0x71, 0xc1, 0x6c, 0xfc, 0xef, 0x6f, 0x67, 0x9b, 0x97, 0xd8, 0x5f, 0x54, + 0x18, 0x44, 0x03, 0x30, 0x00, 0x08, 0x03, 0x0e, 0x30, 0x71, 0x5c, 0x1c, 0x57, 0x8d, 0x77, 0xf8, + 0x62, 0x9d, 0x39, 0xb8, 0xb8, 0x9f, 0x2f, 0x08, 0x41, 0xb0, 0xcb, 0x6d, 0x8e, 0x2b, 0x9f, 0xfe, + 0x09, 0xa1, 0x80, 0x20, 0x0d, 0x31, 0xf1, 0x70, 0x7b, 0xe7, 0x83, 0xc7, 0x12, 0x1f, 0x97, 0xbe, + 0x5d, 0x52, 0x61, 0xc0, 0x85, 0x2e, 0x20, 0xa5, 0x23, 0x11, 0xe2, 0x2f, 0xf0, 0x80, 0x42, 0x5b, + 0x96, 0xeb, 0x16, 0x90, 0xa0, 0xdc, 0xce, 0x85, 0x62, 0x8e, 0x11, 0x08, 0x02, 0x78, 0x4c, 0x22, + 0x31, 0x7c, 0xa8, 0xa2, 0x38, 0x30, 0x72, 0x8c, 0xa5, 0xe8, 0x41, 0x50, 0xd7, 0xc6, 0xfd, 0xdc, + 0x8a, 0x24, 0xb1, 0x02, 0x61, 0xab, 0x25, 0x0a, 0x02, 0xb4, 0x81, 0xc1, 0x50, 0x59, 0x92, 0x81, + 0x40, 0x70, 0x7a, 0xed, 0x07, 0xb4, 0x25, 0x85, 0xd8, 0x63, 0x0d, 0x0f, 0x05, 0x6f, 0xdb, 0x8e, + 0xe9, 0xf8, 0x20, 0x10, 0x34, 0x5b, 0x99, 0x14, 0x07, 0x46, 0x16, 0x54, 0x48, 0xf0, 0x59, 0x04, + 0xa1, 0xe3, 0xc7, 0x4b, 0x95, 0x5a, 0x65, 0xbd, 0x56, 0x69, 0xe9, 0x76, 0x8d, 0x1e, 0x55, 0x54, + 0x8f, 0x8f, 0xba, 0xdf, 0xfc, 0x11, 0x13, 0x37, 0xcb, 0xe0, 0xba, 0x86, 0xda, 0xd2, 0xbb, 0xf7, + 0x01, 0x02, 0x0e, 0x42, 0x90, 0x6b, 0xa9, 0x66, 0xee, 0x5e, 0x24, 0x0f, 0x2e, 0xd5, 0x2b, 0x79, + 0x76, 0xc9, 0x45, 0x73, 0xc7, 0x8f, 0x3e, 0x25, 0xe7, 0x0f, 0x46, 0x21, 0x88, 0x8d, 0x14, 0xde, + 0x58, 0x0e, 0xc2, 0xa3, 0x91, 0x00, 0x70, 0x60, 0xaa, 0x98, 0x2e, 0x54, 0x58, 0x5c, 0x78, 0x00, + 0x6d, 0x89, 0x0c, 0x05, 0x46, 0xec, 0x0f, 0x18, 0xa4, 0x71, 0x09, 0x00, 0x00, 0x80, 0x06, 0x18, + 0x80, 0x94, 0x90, 0xa9, 0x42, 0x25, 0x0f, 0x8d, 0x41, 0xf4, 0x77, 0xac, 0xfe, 0x7e, 0x1e, 0x24, + 0x0a, 0x61, 0x64, 0xd8, 0x82, 0x75, 0x4e, 0x7e, 0xde, 0xce, 0x4e, 0xce, 0xcf, 0xee, 0xcf, 0xcb, + 0x9f, 0xbf, 0xbf, 0x8e, 0xbe, 0x32, 0xd9, 0xd7, 0xf0, 0x15, 0x20, 0x41, 0x0a, 0x0b, 0x07, 0xbc, + 0x6e, 0x1c, 0x00, 0xe1, 0x63, 0x2d, 0x88, 0x07, 0xb9, 0xc3, 0xd3, 0x80, 0x0a, 0x96, 0x4e, 0x02, + 0xaf, 0xc7, 0x2d, 0xe2, 0xba, 0x7c, 0x34, 0xa0, 0x34, 0x78, 0x74, 0xc6, 0x7e, 0x3f, 0xff, 0xb6, + 0xb1, 0x61, 0xa5, 0x09, 0x46, 0xd7, 0x1f, 0xf4, 0xff, 0x3a, 0x22, 0x86, 0x14, 0x00, 0x74, 0xad, + 0xf2, 0xc3, 0x14, 0x40, 0xa7, 0xa6, 0x9f, 0xe9, 0xa6, 0x9a, 0x7c, 0x59, 0x85, 0x51, 0x40, 0x07, + 0x5f, 0xb8, 0x64, 0x87, 0x3b, 0x7e, 0x26, 0xf4, 0xfd, 0xb6, 0xdb, 0x6f, 0x6d, 0xb8, 0x69, 0x40, + 0x24, 0x01, 0xd2, 0x1d, 0x91, 0x97, 0xff, 0x6f, 0xdd, 0xf0, 0xea, 0x20, 0x00, 0xc8, 0x09, 0x33, + 0x01, 0x55, 0x43, 0xa7, 0x8b, 0x5b, 0x62, 0xac, 0x43, 0xd5, 0xf2, 0xad, 0x6c, 0xe1, 0xf1, 0x03, + 0xc2, 0x23, 0x61, 0xc8, 0x8d, 0xc7, 0x12, 0xf5, 0xfe, 0x24, 0x3e, 0x4c, 0x3b, 0x04, 0xb1, 0x8f, + 0x00, 0x2e, 0x3e, 0xe3, 0xc0, 0x0b, 0x8f, 0xbd, 0xde, 0x05, 0xd2, 0xb1, 0x7f, 0x86, 0x38, 0xa2, + 0xb2, 0x26, 0x68, 0x6f, 0x8b, 0xe8, 0xbd, 0xf2, 0xef, 0x5c, 0x18, 0x88, 0x5e, 0xe1, 0x18, 0x50, + 0x51, 0x47, 0xba, 0x4d, 0xb9, 0x19, 0x51, 0xf1, 0x1d, 0x9e, 0x4f, 0xa8, 0x5c, 0xa9, 0xd9, 0x4d, + 0x6e, 0x14, 0xe6, 0xdc, 0x23, 0x1f, 0x7b, 0xf4, 0xee, 0xa9, 0xd3, 0xc4, 0xc6, 0x49, 0x83, 0x4c, + 0xfb, 0x15, 0x2c, 0x38, 0x8b, 0x15, 0xa8, 0xab, 0xae, 0xbe, 0x20, 0x29, 0x3d, 0x89, 0x76, 0xb3, + 0x03, 0xfe, 0x5a, 0xc5, 0xb1, 0xdb, 0x8f, 0xb9, 0xd8, 0x0e, 0x7e, 0x65, 0x05, 0x85, 0x96, 0x2c, + 0xbb, 0x12, 0xb2, 0x73, 0xc5, 0xeb, 0xac, 0x48, 0x24, 0x2c, 0x65, 0x63, 0x91, 0xf2, 0xaf, 0x83, + 0x80, 0xc0, 0xd1, 0x07, 0x1f, 0x10, 0x7e, 0x05, 0x89, 0x00, 0x1f, 0xa0, 0x32, 0x35, 0x50, 0x43, + 0x5c, 0x0e, 0x0f, 0x17, 0x2c, 0x0c, 0x0e, 0xe0, 0x4a, 0x4c, 0x2e, 0x2e, 0xc0, 0x37, 0x0f, 0x00, + 0x02, 0x10, 0x24, 0x02, 0xa0, 0x81, 0x19, 0x32, 0xff, 0xc1, 0x48, 0x52, 0x9d, 0x1b, 0x24, 0x78, + 0x00, 0x10, 0x9e, 0x00, 0x62, 0x00, 0xe1, 0x20, 0x00, 0x10, 0x52, 0x40, 0xa9, 0x20, 0x56, 0x23, + 0x83, 0xd9, 0x87, 0x74, 0xb1, 0xb3, 0x4e, 0x07, 0x0e, 0x1e, 0x58, 0x03, 0x4f, 0x86, 0x62, 0xc0, + 0x0f, 0x50, 0x92, 0xec, 0xc2, 0x76, 0xe8, 0x9f, 0x78, 0x79, 0x76, 0x73, 0xbf, 0xff, 0xb9, 0xf9, + 0xfb, 0xfb, 0xf8, 0xd2, 0xd8, 0x78, 0x90, 0x0c, 0x7a, 0x46, 0xa0, 0x43, 0xdf, 0xb4, 0xff, 0x9b, + 0xdb, 0xd4, 0x9d, 0xfc, 0x73, 0xbf, 0x13, 0x1b, 0xb6, 0xe7, 0x52, 0x29, 0x8a, 0x6a, 0x2a, 0x2c, + 0x34, 0xcf, 0x7e, 0x25, 0xc2, 0x46, 0x8a, 0xd5, 0xda, 0x70, 0xb0, 0x12, 0x04, 0x80, 0x00, 0x47, + 0x17, 0x03, 0x86, 0x58, 0x00, 0x5f, 0xe2, 0x02, 0x21, 0xd8, 0x3c, 0x5c, 0x56, 0x3c, 0x5e, 0xc4, + 0x9c, 0x1c, 0x52, 0xf9, 0x97, 0xe1, 0x80, 0x01, 0x84, 0x00, 0x35, 0x83, 0x72, 0x8a, 0x01, 0x65, + 0x0d, 0xdf, 0xc4, 0x06, 0xaa, 0xf7, 0x10, 0x00, 0x0c, 0x00, 0xca, 0x9e, 0x74, 0x49, 0xd8, 0xcb, + 0xbf, 0xe2, 0x02, 0xb5, 0x5a, 0xc4, 0x9f, 0x17, 0x10, 0x00, 0x0b, 0x00, 0xc9, 0x14, 0xb1, 0x42, + 0xd3, 0x4f, 0xe1, 0xd2, 0x40, 0x03, 0x5b, 0x26, 0xb1, 0xc2, 0x11, 0xff, 0xef, 0xcb, 0xe9, 0xba, + 0xba, 0xad, 0x60, 0x92, 0x2d, 0x34, 0xdb, 0x7f, 0x0e, 0x28, 0x03, 0x08, 0x2a, 0x70, 0x4b, 0x49, + 0xd5, 0x35, 0x97, 0xcb, 0xe9, 0xf4, 0xee, 0x1b, 0xdf, 0x4b, 0xff, 0x0b, 0x43, 0xd0, 0x00, 0x94, + 0xa6, 0x53, 0x80, 0x03, 0xce, 0xf2, 0xcf, 0xc1, 0xb0, 0x8b, 0xc9, 0xfe, 0x08, 0x39, 0xb5, 0x55, + 0x7d, 0x60, 0xb8, 0x21, 0x10, 0x1a, 0xc6, 0x94, 0x3c, 0xf9, 0x81, 0x81, 0x8a, 0x7e, 0xff, 0x84, + 0x42, 0x20, 0xa4, 0xdc, 0xfd, 0x37, 0xbc, 0xb4, 0xef, 0x6f, 0x0c, 0x0c, 0xbc, 0x7d, 0x78, 0x9e, + 0x29, 0xd5, 0x0d, 0x65, 0x45, 0x8c, 0x3c, 0x53, 0x4a, 0x58, 0x65, 0xe2, 0x0a, 0x8c, 0x22, 0x0e, + 0x46, 0xd8, 0xc0, 0xe6, 0xf9, 0x99, 0xad, 0xdd, 0x72, 0xca, 0xd1, 0x46, 0x36, 0xe9, 0x3f, 0xd9, + 0xda, 0xcb, 0x38, 0xdb, 0x59, 0x26, 0x37, 0xd5, 0xff, 0x12, 0x34, 0xe2, 0xf5, 0x4a, 0xaa, 0x2f, + 0x2d, 0x13, 0x54, 0xfe, 0x52, 0x69, 0xa1, 0x82, 0xa3, 0x83, 0x12, 0x96, 0x51, 0x52, 0xff, 0x08, + 0x88, 0x1a, 0x42, 0xf6, 0xdb, 0xdd, 0xd4, 0xbd, 0x9d, 0xcc, 0x37, 0xee, 0xc3, 0x64, 0x24, 0x9f, + 0x01, 0xd5, 0x89, 0x01, 0x76, 0x48, 0x30, 0x30, 0x5d, 0x81, 0xde, 0xd0, 0xb0, 0xb1, 0xb5, 0x22, + 0xfc, 0x14, 0x03, 0x11, 0xa4, 0x0e, 0x07, 0x02, 0x13, 0x02, 0x53, 0x14, 0x49, 0x3c, 0x00, 0x05, + 0x39, 0x60, 0x00, 0x42, 0x58, 0x00, 0x14, 0x96, 0x00, 0x18, 0xa0, 0x00, 0x42, 0xca, 0x00, 0x2c, + 0x8e, 0x00, 0x02, 0x1c, 0xb2, 0x00, 0x05, 0xc9, 0x00, 0x0a, 0x9c, 0x00, 0x70, 0xe0, 0x03, 0x87, + 0x01, 0xc3, 0x8e, 0x0b, 0xd2, 0xad, 0x07, 0xff, 0xc1, 0x48, 0x30, 0x0a, 0x4b, 0xd3, 0x4c, 0x51, + 0x9c, 0x00, 0xf3, 0xc1, 0xc3, 0xc0, 0x79, 0x63, 0xc2, 0xc3, 0xca, 0x70, 0x30, 0x3c, 0x79, 0x63, + 0xa8, 0x28, 0x00, 0xaa, 0x6c, 0x3c, 0x8e, 0x00, 0xc8, 0xd7, 0x08, 0x51, 0xf1, 0x4e, 0xff, 0xf6, + 0xe2, 0x1e, 0x0b, 0xb7, 0x89, 0x1c, 0x04, 0x0a, 0x32, 0x8a, 0x75, 0x1c, 0xe1, 0x70, 0x0b, 0x6c, + 0x69, 0xa7, 0x88, 0x12, 0x15, 0xb7, 0x6e, 0xf7, 0x84, 0x04, 0x64, 0x31, 0x01, 0xdc, 0x88, 0x63, + 0xf1, 0x21, 0xf0, 0xff, 0xe2, 0x22, 0x39, 0x75, 0x78, 0xc8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, + 0x60, 0x30, 0x30, 0x5a, 0x0b, 0x74, 0x3e, 0x28, 0xee, 0xbd, 0x04, 0x9d, 0x5c, 0xae, 0xae, 0x41, + 0x17, 0x56, 0x85, 0xfa, 0xf4, 0xdd, 0x72, 0xbe, 0xbd, 0x5d, 0x7f, 0xf5, 0xe8, 0x6b, 0xa3, 0x3d, + 0x74, 0x57, 0x84, 0x7a, 0x2d, 0x4b, 0xd1, 0x1a, 0xba, 0xf7, 0xd5, 0xe1, 0xbe, 0xaf, 0x5d, 0x5e, + 0x2f, 0xaf, 0x5f, 0x5e, 0xae, 0xbd, 0x7d, 0x7a, 0xfa, 0xbd, 0x70, 0x45, 0xcd, 0x97, 0xae, 0xaf, + 0xf5, 0x79, 0xfa, 0x3b, 0xc6, 0x74, 0x4a, 0x9f, 0xa2, 0x4e, 0x57, 0x5e, 0xfa, 0xe5, 0x0c, 0x75, + 0xea, 0xe8, 0xaf, 0x5d, 0x5a, 0x4e, 0xbd, 0x5d, 0x11, 0xeb, 0xad, 0x57, 0x5a, 0x8d, 0xeb, 0x5f, + 0x56, 0x42, 0x7d, 0x7b, 0xea, 0xd1, 0x5c, 0x12, 0x89, 0x77, 0xdd, 0xf2, 0x25, 0xf4, 0x21, 0xa1, + 0x5e, 0xbd, 0x15, 0xd6, 0x28, 0x8e, 0xbd, 0x87, 0x09, 0x5f, 0xfd, 0xaf, 0x95, 0x3f, 0xdb, 0x7d, + 0x7b, 0xe0, 0x86, 0xf7, 0xf5, 0x73, 0x95, 0xa9, 0xd3, 0x7f, 0x27, 0x57, 0xfa, 0xf7, 0xd1, 0x5a, + 0xfa, 0x33, 0x57, 0x57, 0xfa, 0x2b, 0x7d, 0x5f, 0xea, 0xff, 0x56, 0xfa, 0xb5, 0x75, 0x69, 0x3a, + 0x37, 0x7d, 0x5e, 0x2a, 0x10, 0x10, 0x8b, 0xd2, 0x74, 0x47, 0x8c, 0xeb, 0x95, 0xf5, 0xa8, 0x6f, + 0xab, 0x4d, 0xd6, 0xbe, 0xaf, 0xf5, 0x68, 0xde, 0xac, 0x7d, 0x5c, 0xae, 0x8b, 0x15, 0x70, 0x49, + 0x51, 0xac, 0xbd, 0x7d, 0x6c, 0x7c, 0x11, 0x75, 0x6d, 0x32, 0xf5, 0xaf, 0xaf, 0x5f, 0x44, 0xe8, + 0x8e, 0xbd, 0xf5, 0xe9, 0xfa, 0x3e, 0x5f, 0x46, 0xb5, 0xf4, 0x57, 0xfa, 0xb7, 0xd7, 0xbe, 0xbe, + 0x24, 0xe8, 0xa6, 0x5f, 0xc2, 0x02, 0x1d, 0xfd, 0xa6, 0xae, 0xa9, 0xfa, 0xbd, 0xf0, 0x43, 0xdd, + 0xd2, 0x92, 0x62, 0x64, 0xeb, 0xdf, 0x5e, 0x97, 0xaf, 0x57, 0x5e, 0xfa, 0xf7, 0xd7, 0xa2, 0xba, + 0xf5, 0x75, 0xe8, 0xde, 0x8e, 0xf5, 0xd5, 0xa2, 0x3a, 0xcd, 0x5c, 0xa2, 0x2e, 0xbe, 0x19, 0x45, + 0xeb, 0xeb, 0xab, 0xeb, 0xdf, 0x5e, 0xae, 0xbf, 0xfa, 0xbf, 0xd7, 0xff, 0x5f, 0xc2, 0xbd, 0x7a, + 0x1d, 0xe8, 0x8d, 0x7d, 0x7b, 0xeb, 0xd0, 0xaf, 0x57, 0xae, 0xbd, 0x0c, 0x74, 0x4e, 0x9f, 0xaf, + 0x40, 0xc1, 0xd7, 0x68, 0xfe, 0xad, 0x7d, 0x6a, 0x5e, 0xbd, 0x05, 0xbd, 0x7a, 0x03, 0x2f, 0xa2, + 0xbf, 0xd5, 0xfe, 0xaf, 0x5d, 0xf5, 0x5f, 0x35, 0xdf, 0x5d, 0x7a, 0x6e, 0x08, 0x67, 0xce, 0xcf, + 0xaf, 0x7c, 0xa4, 0x78, 0xae, 0x3a, 0x11, 0x8b, 0x35, 0xd6, 0x2f, 0x11, 0xeb, 0x82, 0x01, 0x20, + 0xa6, 0xed, 0x71, 0x41, 0xc2, 0xca, 0xa5, 0x36, 0x09, 0xf8, 0xf1, 0xfd, 0x0b, 0x6f, 0xab, 0x57, + 0x56, 0xfa, 0xb4, 0xdc, 0x82, 0x2b, 0x5f, 0x08, 0x6f, 0x5d, 0xb6, 0x96, 0xda, 0x6f, 0x82, 0xeb, + 0xbb, 0xbd, 0xda, 0xc5, 0x17, 0xd1, 0x3b, 0xe5, 0xde, 0xe3, 0x20, 0x49, 0x0c, 0x85, 0x04, 0x9f, + 0xb4, 0x36, 0xb9, 0xde, 0xce, 0x4c, 0x9b, 0x8e, 0x29, 0x7b, 0x46, 0xc5, 0x2f, 0x07, 0xbf, 0xc0, + 0x70, 0x02, 0x91, 0xb1, 0xdf, 0x92, 0x81, 0x53, 0xde, 0xee, 0x70, 0x01, 0xc1, 0x00, 0x18, 0x16, + 0x19, 0x61, 0xcb, 0x30, 0x0b, 0x24, 0x4b, 0x9f, 0x22, 0xfb, 0xb2, 0x38, 0xc7, 0x3c, 0x75, 0x67, + 0xe1, 0xac, 0x00, 0xc6, 0x0d, 0x1a, 0x1f, 0x27, 0xd7, 0x3e, 0xff, 0xb6, 0x7e, 0xb7, 0x76, 0xc5, + 0x43, 0x0f, 0x28, 0x00, 0x29, 0xaa, 0x1a, 0xc2, 0x0b, 0x88, 0x4c, 0x47, 0xa8, 0x67, 0x53, 0x55, + 0x18, 0x74, 0x60, 0xef, 0xc7, 0x7e, 0xc8, 0xa3, 0x60, 0xb5, 0x94, 0x1b, 0x03, 0x29, 0xb7, 0x4f, + 0xc2, 0xfc, 0x2e, 0x21, 0xa8, 0x9f, 0x17, 0x07, 0x40, 0xb9, 0x30, 0x01, 0x50, 0xe8, 0x11, 0x91, + 0x81, 0x28, 0x41, 0x28, 0xee, 0x60, 0xa3, 0x8e, 0x4e, 0x03, 0x97, 0xf1, 0x03, 0x67, 0xc3, 0xdc, + 0x6e, 0x0f, 0xf1, 0xf9, 0xc4, 0x90, 0x76, 0x4a, 0x7b, 0x87, 0x1c, 0x92, 0xc0, 0x62, 0x83, 0x15, + 0x40, 0xef, 0x80, 0x60, 0x00, 0x3f, 0x00, 0x01, 0x10, 0xf0, 0xe2, 0x87, 0x9c, 0xbf, 0xf0, 0xe2, + 0x80, 0x13, 0x34, 0xa6, 0x1b, 0x45, 0x73, 0xab, 0x6d, 0xf6, 0xdb, 0x4d, 0x3a, 0x93, 0x16, 0xc5, + 0xb2, 0x78, 0xc1, 0x40, 0x34, 0xf9, 0x90, 0xb9, 0x96, 0x17, 0x19, 0x64, 0xe0, 0xcb, 0xfc, 0x44, + 0x31, 0x07, 0xf9, 0x2c, 0x00, 0x18, 0x3c, 0x1e, 0x35, 0x29, 0x79, 0x61, 0x02, 0x0b, 0xc5, 0x35, + 0xc6, 0x20, 0x70, 0x62, 0xc0, 0x0e, 0x1f, 0xfb, 0xe6, 0x61, 0x35, 0xdd, 0x6a, 0x97, 0x97, 0x2f, + 0x9f, 0x3c, 0x35, 0xe4, 0xd5, 0xd3, 0x2f, 0xff, 0x09, 0xd3, 0x42, 0xd2, 0x4f, 0x6f, 0xc1, 0x35, + 0xda, 0xb5, 0x66, 0x92, 0x5e, 0x5f, 0x0a, 0x9f, 0x36, 0x5f, 0x77, 0xed, 0x93, 0xfb, 0xe2, 0xfc, + 0xbd, 0x2e, 0x5d, 0x5d, 0x4a, 0x28, 0xac, 0x30, 0x0a, 0xba, 0xaa, 0x8a, 0x62, 0x86, 0x29, 0x8a, + 0x18, 0x8e, 0x16, 0x1c, 0x47, 0x01, 0x40, 0xec, 0x38, 0x48, 0x01, 0x7b, 0xcc, 0x8c, 0x31, 0x3d, + 0x7e, 0xd7, 0x38, 0xff, 0x1d, 0xf8, 0xed, 0xeb, 0x2d, 0x60, 0xe3, 0xf3, 0xf5, 0xf8, 0x7e, 0xb3, + 0xe2, 0x9b, 0x79, 0x59, 0xe2, 0x32, 0x61, 0xc0, 0x00, 0x03, 0x74, 0xdc, 0xdf, 0xe1, 0xd5, 0x00, + 0x2f, 0xc8, 0xdb, 0x20, 0xf2, 0x8f, 0x6e, 0x8e, 0xe7, 0xbc, 0xf3, 0xcf, 0x1e, 0x7f, 0xbf, 0x9e, + 0x7b, 0xf9, 0x66, 0x58, 0xce, 0x3c, 0xe7, 0x97, 0xf8, 0xbd, 0x32, 0x64, 0xc9, 0xd1, 0x8f, 0xf0, + 0x0b, 0x80, 0x81, 0xb2, 0x9d, 0x90, 0xcf, 0x48, 0x51, 0x0f, 0x8f, 0x63, 0x0c, 0xa4, 0x63, 0xb2, + 0x38, 0x79, 0xe0, 0x3c, 0x74, 0xfd, 0xaf, 0x5a, 0x8b, 0x67, 0x8f, 0x1c, 0x57, 0xed, 0xcb, 0x6d, + 0xa6, 0x9f, 0xe0, 0x24, 0x04, 0x05, 0x2e, 0xe9, 0xbf, 0xb6, 0x43, 0x0c, 0x98, 0x45, 0x57, 0xf7, + 0xf3, 0xcf, 0x57, 0xe2, 0xa2, 0x12, 0x9d, 0xe2, 0x7c, 0x6a, 0x40, 0xa4, 0x2a, 0x92, 0x95, 0x67, + 0xd1, 0x3a, 0x14, 0x89, 0x8b, 0x2d, 0x6b, 0x0b, 0x34, 0xde, 0x0e, 0x04, 0x8d, 0x9b, 0x33, 0xe4, + 0x8b, 0x10, 0x3e, 0x66, 0x0a, 0x97, 0xc7, 0xac, 0xe3, 0xb6, 0x08, 0x1e, 0x17, 0x3c, 0xf8, 0x68, + 0x7b, 0x98, 0x40, 0x80, 0x06, 0xb0, 0x04, 0xa0, 0xc4, 0x05, 0x2c, 0x30, 0x58, 0x00, 0x22, 0xe1, + 0x1c, 0x7f, 0x81, 0x84, 0x0e, 0x03, 0x44, 0x0e, 0x23, 0xc5, 0xea, 0xb7, 0x45, 0x4a, 0x51, 0x99, + 0x0e, 0x96, 0x16, 0x06, 0x4a, 0x00, 0x54, 0x9c, 0x00, 0x3e, 0x0e, 0xa2, 0x52, 0x50, 0x2a, 0x48, + 0x00, 0x04, 0x30, 0x48, 0xfa, 0x20, 0xec, 0x94, 0xb6, 0x10, 0x6f, 0x47, 0x86, 0x9f, 0x0d, 0xfd, + 0x3f, 0xe0, 0xe4, 0x0b, 0x03, 0x3d, 0xe4, 0x4d, 0x8d, 0x09, 0x72, 0x64, 0xb3, 0x2c, 0xc5, 0xc5, + 0xc4, 0x86, 0x87, 0x81, 0xa1, 0x7c, 0xe0, 0x79, 0x06, 0x01, 0x49, 0x63, 0x2c, 0x18, 0xa3, 0x12, + 0x38, 0x58, 0x0c, 0x50, 0x19, 0x60, 0xc4, 0x00, 0x3c, 0x94, 0x05, 0x6c, 0xf1, 0xb3, 0xd6, 0xb4, + 0x4c, 0x2a, 0x7f, 0x0f, 0x38, 0x8b, 0xd6, 0x04, 0x90, 0x70, 0x36, 0x1c, 0x00, 0x1f, 0x8e, 0x1c, + 0x2c, 0x01, 0x9e, 0x3c, 0x40, 0xe0, 0x3f, 0xc1, 0x45, 0xad, 0x26, 0x01, 0xe2, 0xc0, 0x19, 0x60, + 0x00, 0xdf, 0x87, 0x8e, 0x07, 0xe0, 0xd5, 0x6f, 0xfc, 0x74, 0x1e, 0x1e, 0x00, 0x30, 0x0b, 0x57, + 0x25, 0x0d, 0x4f, 0xfc, 0x36, 0x54, 0x7f, 0x9d, 0xa3, 0x40, 0xf0, 0xbc, 0x1b, 0xc5, 0x53, 0xc2, + 0x00, 0x11, 0xd8, 0xe1, 0x5f, 0x01, 0xd8, 0x03, 0x6d, 0x81, 0x56, 0xc5, 0xfe, 0x5b, 0x46, 0xc5, + 0x8d, 0x71, 0x67, 0x63, 0xb1, 0x95, 0x83, 0xfd, 0xb6, 0xb8, 0x22, 0xa5, 0x9b, 0xe1, 0x7d, 0xe9, + 0x93, 0xca, 0xe6, 0x8e, 0x2f, 0xd7, 0x7c, 0x9b, 0x7d, 0x4a, 0x91, 0x3c, 0x34, 0x61, 0x4c, 0x94, + 0x00, 0xac, 0xf0, 0x3c, 0x35, 0x3b, 0x15, 0x7f, 0xc3, 0x72, 0x80, 0x49, 0x99, 0x90, 0x18, 0x85, + 0xb2, 0xbd, 0xe1, 0x6d, 0x9c, 0xf1, 0x81, 0x78, 0xee, 0x33, 0x9f, 0x06, 0xaf, 0x05, 0x05, 0x60, + 0xf6, 0x0a, 0xb0, 0x5a, 0xcf, 0xdd, 0xf1, 0x70, 0xdb, 0xa6, 0x9f, 0xc3, 0x8a, 0x00, 0xa7, 0xfa, + 0x04, 0x3d, 0xb2, 0x59, 0xfc, 0x8d, 0x34, 0xd3, 0x59, 0x82, 0xed, 0xd0, 0x8d, 0xfd, 0xdc, 0x57, + 0x34, 0x82, 0xbc, 0x4f, 0xf1, 0x19, 0x76, 0xcf, 0xef, 0xf0, 0xea, 0x80, 0x08, 0xc0, 0xc8, 0x8a, + 0xae, 0x56, 0x06, 0x44, 0x17, 0x19, 0xcf, 0x10, 0xf8, 0xc7, 0x97, 0x1c, 0xfc, 0x7a, 0xf1, 0xde, + 0xed, 0x8a, 0xb3, 0xf2, 0xd6, 0x3a, 0x55, 0x3f, 0x5f, 0xf0, 0x08, 0xc4, 0x29, 0x14, 0x0c, 0x41, + 0xe2, 0x9b, 0x3e, 0xee, 0x20, 0x3e, 0xc7, 0x85, 0xee, 0x20, 0x79, 0xb9, 0x5e, 0xa7, 0xb8, 0x42, + 0x0a, 0x2f, 0x91, 0x75, 0x51, 0x71, 0x7e, 0x84, 0xfa, 0xf6, 0x1e, 0x50, 0x01, 0x0c, 0x1c, 0x59, + 0x88, 0x2a, 0x08, 0xc6, 0xbf, 0x1a, 0x31, 0x9a, 0x0c, 0xf1, 0xc7, 0xfc, 0x1f, 0xf6, 0x47, 0x9e, + 0x5e, 0x5f, 0x71, 0xb9, 0x20, 0x09, 0x85, 0xbc, 0xbd, 0x3f, 0xc0, 0x40, 0x86, 0x06, 0x90, 0xf3, + 0x83, 0x5c, 0x04, 0xa1, 0xdc, 0x4a, 0x00, 0x04, 0x14, 0x20, 0x1c, 0x22, 0x87, 0x06, 0x55, 0x23, + 0x00, 0x94, 0xe0, 0xe6, 0x94, 0xa8, 0x6d, 0x69, 0x0f, 0xe2, 0x78, 0x0b, 0x46, 0x41, 0xd8, 0x8c, + 0x79, 0xfc, 0x4c, 0x6d, 0x7e, 0x45, 0xb3, 0x32, 0x04, 0xa9, 0xbd, 0x7c, 0x42, 0x41, 0x1e, 0xb0, + 0xb0, 0x33, 0x87, 0xa9, 0xfa, 0x63, 0xcf, 0xc2, 0x2a, 0x4d, 0x43, 0x00, 0x02, 0x07, 0x00, 0x80, + 0xa6, 0x0e, 0x1b, 0xb8, 0xc6, 0xc1, 0xc1, 0x9a, 0x3f, 0xe8, 0x6a, 0x71, 0x17, 0xcf, 0xc1, 0x84, + 0x29, 0x2c, 0xcb, 0xcb, 0x35, 0x81, 0x0d, 0x75, 0x2d, 0xe5, 0x29, 0x8a, 0xcb, 0x8e, 0x5b, 0x6e, + 0x04, 0x88, 0x52, 0x1f, 0x81, 0xaa, 0x17, 0x8a, 0x8b, 0xf2, 0xaf, 0xf6, 0xd4, 0x89, 0xe4, 0xb3, + 0xf8, 0x7f, 0x29, 0x65, 0xf8, 0x44, 0x18, 0x0c, 0x9e, 0xe1, 0xee, 0x5a, 0x0d, 0x86, 0x51, 0xe0, + 0x07, 0x2b, 0x0f, 0xc4, 0xa8, 0xb0, 0x82, 0xf9, 0x21, 0x04, 0x5e, 0x83, 0xc9, 0x0c, 0x22, 0x0a, + 0x03, 0xc4, 0x2c, 0x00, 0xc5, 0x00, 0x33, 0x83, 0x83, 0xd6, 0x0a, 0x00, 0x62, 0x00, 0x0f, 0x24, + 0x35, 0x14, 0x89, 0x73, 0xc3, 0x8e, 0x51, 0x09, 0x43, 0x1c, 0xe8, 0xe7, 0xae, 0xb6, 0x5f, 0xe0, + 0x98, 0x4d, 0x2a, 0x93, 0xd3, 0x26, 0xe3, 0x8a, 0xb8, 0x9a, 0x5a, 0x6d, 0xa1, 0x97, 0x75, 0xc1, + 0x15, 0xb4, 0xad, 0x65, 0xf0, 0x59, 0x9f, 0x08, 0xa6, 0xa5, 0xa5, 0xa6, 0x4d, 0xf3, 0x3e, 0x16, + 0xa5, 0x3c, 0x37, 0x97, 0xac, 0x6c, 0xd6, 0xb0, 0xd3, 0xe1, 0x1e, 0x08, 0xac, 0x81, 0x60, 0x26, + 0xfb, 0x1f, 0x61, 0xd2, 0x40, 0x1f, 0xc8, 0x4f, 0x4f, 0x51, 0xa9, 0x75, 0x1c, 0xf8, 0xcb, 0x74, + 0xd9, 0xd3, 0x3b, 0xc4, 0xbd, 0x64, 0xe2, 0xb3, 0xcf, 0x38, 0x79, 0x79, 0x3d, 0x5e, 0xcf, 0xe1, + 0xc5, 0x00, 0x99, 0x92, 0x33, 0x18, 0x84, 0xf3, 0xe5, 0xbd, 0xcf, 0xfb, 0xdd, 0x45, 0x69, 0xa6, + 0x9a, 0x60, 0x66, 0x9d, 0xb6, 0xfe, 0x1b, 0x70, 0x03, 0x08, 0x74, 0x3c, 0x4f, 0xd7, 0xdc, 0xcb, + 0xc9, 0xf6, 0x4e, 0x70, 0xf2, 0xde, 0x21, 0xe9, 0x9b, 0x96, 0x03, 0x91, 0x23, 0x41, 0x6d, 0xb7, + 0xfc, 0x38, 0xa0, 0x00, 0xbc, 0xd6, 0x89, 0xf9, 0x81, 0x86, 0x91, 0x82, 0x5e, 0x5a, 0xcb, 0x6d, + 0x8a, 0xb1, 0x56, 0xdb, 0x71, 0x6d, 0x53, 0x16, 0xc5, 0xb4, 0xd3, 0x11, 0x1a, 0x1f, 0x4d, 0x36, + 0xdb, 0xf0, 0xac, 0x04, 0x00, 0x16, 0x42, 0xbb, 0x56, 0x86, 0x94, 0x3f, 0x12, 0xd5, 0x85, 0x6b, + 0x60, 0x3d, 0x87, 0x87, 0xfe, 0x1c, 0x50, 0x0c, 0xe0, 0x91, 0x4d, 0x35, 0x8e, 0x67, 0x67, 0x13, + 0xee, 0xe3, 0xdf, 0x3b, 0xf5, 0x36, 0x3f, 0x53, 0x8c, 0x1a, 0xa5, 0x5e, 0xac, 0xed, 0xe2, 0xbe, + 0x73, 0xae, 0x3d, 0x35, 0xb9, 0x7e, 0x06, 0x10, 0x62, 0x34, 0xc4, 0xa5, 0x4f, 0x38, 0x2b, 0x1c, + 0x49, 0x28, 0x04, 0x6a, 0xbc, 0xec, 0xb0, 0x01, 0x90, 0xee, 0x3e, 0x0e, 0x56, 0x7f, 0x03, 0xb8, + 0x94, 0xbe, 0x49, 0x8a, 0xe2, 0x26, 0xf0, 0x5b, 0xb1, 0x60, 0x9f, 0xfb, 0x7f, 0x13, 0x45, 0xef, + 0x82, 0x79, 0x48, 0x32, 0x72, 0x0d, 0xd6, 0xa8, 0xc8, 0x78, 0x52, 0x23, 0x98, 0x17, 0x11, 0x98, + 0x38, 0x79, 0x69, 0xb6, 0xd2, 0x40, 0xc2, 0x05, 0xd6, 0xb1, 0x22, 0xf8, 0x29, 0x10, 0x14, 0x32, + 0x40, 0xad, 0x6a, 0x7f, 0xc4, 0xfe, 0x7b, 0x15, 0xe3, 0xec, 0x84, 0xbc, 0x9d, 0x7e, 0x07, 0xdc, + 0x97, 0xcc, 0x52, 0x28, 0xa1, 0x37, 0xe1, 0x0a, 0x29, 0x33, 0x62, 0x4d, 0xf4, 0x9b, 0xf2, 0x66, + 0xdb, 0x5e, 0xa4, 0x6f, 0xa2, 0xf7, 0x13, 0x04, 0x12, 0x78, 0x52, 0xbb, 0xb8, 0xac, 0x57, 0x88, + 0x1c, 0x10, 0x38, 0x15, 0x22, 0x02, 0x9a, 0x83, 0xcb, 0xd9, 0xfc, 0x38, 0x88, 0x00, 0x21, 0x31, + 0x1e, 0x04, 0x97, 0x41, 0x77, 0xa9, 0xd7, 0xda, 0x36, 0x1d, 0x32, 0x74, 0xc9, 0xf0, 0xf8, 0x53, + 0xc8, 0x3d, 0xf0, 0x7e, 0xdd, 0xd3, 0xfc, 0x06, 0x80, 0x30, 0x1b, 0x14, 0x31, 0x43, 0x48, 0x5a, + 0x03, 0xb1, 0x29, 0xe7, 0x03, 0xf4, 0xa3, 0xec, 0x29, 0x7c, 0x58, 0x0c, 0x3b, 0x09, 0x43, 0x8d, + 0xa9, 0x45, 0xac, 0x61, 0xdf, 0x51, 0xd2, 0xc0, 0xc0, 0x0d, 0x00, 0x01, 0x00, 0x78, 0xf8, 0x80, + 0x09, 0x91, 0x00, 0x4c, 0xff, 0x87, 0x14, 0x00, 0xac, 0x8f, 0x03, 0xe4, 0x62, 0x3c, 0x73, 0xb6, + 0x5b, 0x9f, 0x4d, 0x95, 0x12, 0xfd, 0x64, 0xea, 0xde, 0xda, 0xa6, 0x9f, 0xf8, 0x1e, 0x23, 0x62, + 0x5e, 0xd1, 0xef, 0x2f, 0xac, 0xdc, 0x94, 0x06, 0x8d, 0xc3, 0xc0, 0x07, 0x0f, 0x00, 0x1e, 0x4d, + 0x38, 0x59, 0x2c, 0x18, 0xe9, 0xf0, 0xc0, 0x0f, 0x1f, 0xd3, 0x8b, 0x62, 0x97, 0xfe, 0x18, 0xe5, + 0xe2, 0x8f, 0x14, 0x62, 0xb0, 0x30, 0x01, 0xe3, 0xc5, 0x38, 0xa1, 0x62, 0x97, 0xef, 0x86, 0x4a, + 0x9d, 0x6a, 0xee, 0x2b, 0xff, 0xa2, 0xc5, 0x15, 0xc8, 0x41, 0x71, 0x4e, 0xbc, 0x22, 0x14, 0xb3, + 0x0e, 0x39, 0xa8, 0xf5, 0x87, 0x73, 0x4a, 0xa5, 0xde, 0xa7, 0x87, 0xe3, 0xc2, 0x02, 0x25, 0x9a, + 0xac, 0x5c, 0x5f, 0x09, 0x71, 0x73, 0xb2, 0x8f, 0x69, 0x3f, 0xcb, 0x76, 0xf7, 0xc2, 0x34, 0xb4, + 0xb4, 0xdb, 0xd3, 0xbe, 0x18, 0x12, 0x1e, 0x8b, 0x9e, 0x07, 0xd4, 0x90, 0x00, 0x08, 0x29, 0xe0, + 0x01, 0xec, 0xc1, 0xf6, 0x44, 0x0f, 0x58, 0x61, 0x20, 0x61, 0x03, 0xc6, 0xe0, 0x61, 0x06, 0x64, + 0x53, 0x85, 0x01, 0xc4, 0xd9, 0x40, 0x4c, 0x83, 0xf8, 0x44, 0x6c, 0x41, 0xea, 0x5e, 0xaa, 0xa4, + 0xa1, 0x7b, 0x3c, 0x9c, 0x79, 0xfc, 0x92, 0x7a, 0x94, 0xb2, 0x00, 0x57, 0x92, 0x08, 0x2a, 0x4f, + 0xf1, 0x20, 0xb3, 0xaa, 0xb7, 0x26, 0x74, 0xd2, 0xbd, 0xfe, 0x30, 0xc6, 0x64, 0xb7, 0x33, 0x72, + 0xf0, 0x59, 0xd0, 0x2f, 0x24, 0x15, 0x44, 0x7b, 0x72, 0x65, 0x78, 0x28, 0x1b, 0x5b, 0x1c, 0x67, + 0xa1, 0x09, 0x88, 0xf2, 0xe6, 0x60, 0xa8, 0xf0, 0xf0, 0xd4, 0xae, 0x72, 0xc5, 0x19, 0x90, 0x97, + 0x21, 0x79, 0x53, 0x60, 0xb6, 0x48, 0x4c, 0x93, 0xfc, 0x37, 0xaf, 0x44, 0xeb, 0x89, 0x61, 0xf2, + 0x42, 0x30, 0xa0, 0x93, 0x7d, 0x41, 0x96, 0xae, 0x68, 0xf3, 0xeb, 0xe8, 0x2d, 0x8d, 0x28, 0x39, + 0xf9, 0xce, 0x0f, 0x7c, 0xe1, 0xe7, 0x0e, 0x05, 0xc9, 0x06, 0x97, 0x61, 0xc8, 0x80, 0x01, 0xc9, + 0xd5, 0x98, 0x64, 0xb5, 0x2d, 0x73, 0x19, 0x26, 0xf7, 0xd3, 0xe9, 0x97, 0xd3, 0x67, 0x8c, 0xbc, + 0x6d, 0x3c, 0x60, 0xcc, 0x1b, 0xa9, 0xb8, 0xe1, 0xbe, 0x02, 0x2f, 0x2f, 0x58, 0x0f, 0x87, 0xc7, + 0xf8, 0x0f, 0x90, 0x11, 0x23, 0x62, 0x40, 0x07, 0x07, 0x40, 0x3c, 0x2c, 0x62, 0x89, 0xad, 0x07, + 0x58, 0x0d, 0x43, 0xbb, 0x55, 0x41, 0x5d, 0xd5, 0xa0, 0x4a, 0x4a, 0x36, 0xbe, 0x1e, 0x41, 0x89, + 0x4e, 0xe1, 0x20, 0x54, 0xf3, 0x3b, 0x8c, 0xc1, 0xcc, 0x76, 0x9a, 0x54, 0xd3, 0xfc, 0x10, 0x81, + 0xa4, 0x29, 0x28, 0x0a, 0xf8, 0x70, 0x7e, 0x11, 0x84, 0xa1, 0xf1, 0x28, 0xe2, 0x78, 0x78, 0x0e, + 0x07, 0xd2, 0x96, 0xe6, 0xa1, 0xe7, 0x91, 0x4b, 0xe1, 0x98, 0x2f, 0x87, 0x70, 0x01, 0x5e, 0xb9, + 0x90, 0xa7, 0x57, 0x37, 0xd4, 0x55, 0x89, 0xf7, 0xeb, 0x8a, 0x5a, 0x63, 0x7f, 0x16, 0x50, 0xe4, + 0x9b, 0xf0, 0x30, 0x9f, 0x10, 0x36, 0xe1, 0xf5, 0x82, 0x64, 0x1e, 0xb1, 0xf0, 0xdb, 0x38, 0x00, + 0x4e, 0x88, 0x35, 0x4a, 0x54, 0x2c, 0xc6, 0xfd, 0x12, 0x79, 0xd8, 0x2f, 0x7c, 0x3a, 0x4e, 0xb6, + 0x83, 0xee, 0x30, 0x9b, 0x33, 0x86, 0x28, 0x68, 0xa7, 0x7a, 0x40, 0x15, 0x9c, 0x93, 0x03, 0x70, + 0x24, 0x77, 0xf3, 0xc2, 0xc7, 0x8c, 0x0f, 0x0d, 0xf1, 0xf8, 0x6d, 0x40, 0x00, 0xce, 0xc9, 0x5d, + 0x82, 0x4a, 0x2b, 0xd7, 0xfb, 0x6d, 0x3d, 0x5d, 0xd0, 0x64, 0x5d, 0x08, 0x4c, 0xf7, 0x5b, 0x8e, + 0x97, 0x2f, 0x5f, 0xc0, 0xa0, 0x18, 0x1b, 0x9b, 0x95, 0x49, 0x7a, 0x7b, 0x6d, 0x60, 0xf2, 0xc1, + 0xec, 0x22, 0x70, 0xa2, 0xa7, 0xc1, 0xe7, 0xc3, 0x00, 0x02, 0x43, 0x81, 0x71, 0xf0, 0x58, 0x2a, + 0xb0, 0x7f, 0xd1, 0x0f, 0x87, 0x27, 0xff, 0xc3, 0x97, 0x15, 0xb8, 0xac, 0x22, 0x13, 0x8a, 0xa7, + 0x1f, 0xf1, 0x5f, 0x9b, 0xb2, 0xde, 0xa1, 0xae, 0xba, 0x9b, 0x12, 0x14, 0x10, 0x20, 0xf9, 0x10, + 0x07, 0xeb, 0x50, 0x68, 0xf2, 0xfd, 0x44, 0x96, 0x0a, 0xc1, 0xbe, 0x5f, 0x22, 0xf3, 0xa7, 0x84, + 0x46, 0x63, 0x4d, 0xa3, 0xd1, 0xbd, 0x9a, 0x9b, 0x0e, 0x72, 0x3a, 0xc4, 0xf2, 0xa5, 0xff, 0x12, + 0x11, 0xd2, 0x85, 0x56, 0x38, 0xcf, 0x9b, 0x89, 0xbf, 0x1b, 0x97, 0xe3, 0x2c, 0x60, 0x47, 0x97, + 0x93, 0x1a, 0x12, 0xf3, 0x4f, 0xd0, 0xc3, 0x12, 0xd6, 0xba, 0x85, 0xe6, 0xec, 0x63, 0x32, 0x33, + 0x73, 0x4f, 0xea, 0xe7, 0x08, 0x88, 0x19, 0x8d, 0xb0, 0x56, 0x94, 0xb1, 0x36, 0x16, 0x45, 0xc9, + 0x0a, 0xe8, 0xb7, 0x22, 0xed, 0x66, 0xe5, 0xfe, 0x09, 0x0a, 0x86, 0xdb, 0xdb, 0xeb, 0x2f, 0x87, + 0xbb, 0x49, 0x69, 0x3b, 0x88, 0x70, 0x56, 0x48, 0xd1, 0x56, 0xa8, 0xbf, 0x07, 0x22, 0x02, 0x82, + 0x94, 0xe7, 0x8b, 0xc6, 0x78, 0x2a, 0x36, 0x91, 0x6c, 0xa4, 0x0d, 0x8c, 0xf0, 0xdf, 0x13, 0x43, + 0x5f, 0x40, 0xce, 0x15, 0x36, 0x23, 0x22, 0x83, 0x82, 0x80, 0x2c, 0x85, 0x24, 0x8a, 0x8a, 0x21, + 0xe5, 0x2b, 0x39, 0xd3, 0xb2, 0xbc, 0xcf, 0x0e, 0x25, 0xe2, 0xb2, 0xd8, 0xa0, 0xdd, 0xc4, 0x00, + 0xe1, 0x60, 0xc9, 0xf8, 0x20, 0x12, 0x14, 0x9c, 0x1c, 0x2c, 0xe2, 0x16, 0x89, 0x0a, 0xa8, 0x50, + 0xfb, 0x52, 0xc6, 0x20, 0x1e, 0x58, 0x32, 0xc1, 0x8a, 0x0c, 0xb0, 0x62, 0x5c, 0x7b, 0xa3, 0xbf, + 0x18, 0x51, 0xf6, 0x17, 0x45, 0x83, 0x14, 0x60, 0xfb, 0x01, 0xf6, 0x16, 0x0c, 0xe0, 0x68, 0xfc, + 0xfb, 0x96, 0xef, 0x86, 0x42, 0x23, 0x27, 0x38, 0x94, 0xac, 0x38, 0x00, 0x68, 0x1f, 0x86, 0xa3, + 0xa2, 0xc0, 0xea, 0x4a, 0x30, 0xb2, 0xeb, 0x60, 0x00, 0x53, 0x8f, 0x70, 0xb1, 0xee, 0x78, 0xe0, + 0xd2, 0x6b, 0x8b, 0x67, 0x0b, 0x18, 0x18, 0x01, 0xc8, 0xd9, 0xe0, 0xc6, 0x06, 0xfa, 0x17, 0x7c, + 0x86, 0x35, 0x0a, 0x8c, 0xd5, 0x57, 0xf9, 0xf0, 0x60, 0x15, 0x3c, 0xa3, 0xfa, 0x7f, 0x96, 0x85, + 0x80, 0xea, 0x60, 0x03, 0xe1, 0x81, 0x79, 0xc3, 0xb6, 0xba, 0x15, 0x3c, 0x03, 0x81, 0xd8, 0x94, + 0x00, 0x08, 0xd5, 0x46, 0x94, 0xe2, 0xff, 0x0f, 0x60, 0x0a, 0xa8, 0xb0, 0xcc, 0xd7, 0x94, 0xaf, + 0x7f, 0xc4, 0xdc, 0x42, 0x5c, 0xaf, 0x2b, 0xd5, 0xf7, 0x66, 0xf8, 0x3f, 0xff, 0x5a, 0xde, 0x3d, + 0xaa, 0x94, 0xfc, 0x2c, 0x0a, 0x62, 0x1d, 0xf1, 0x8c, 0x78, 0xf5, 0xa3, 0x8c, 0xd4, 0x01, 0xdf, + 0x5f, 0x81, 0x00, 0x0d, 0x03, 0x4e, 0x23, 0xcb, 0x69, 0x89, 0x72, 0xd5, 0x2b, 0xf2, 0xb1, 0x41, + 0xd6, 0x58, 0x33, 0xf2, 0x7a, 0xf2, 0x4e, 0x20, 0x00, 0x19, 0x00, 0x02, 0xa1, 0x85, 0x16, 0xb2, + 0xd6, 0x58, 0x2c, 0x51, 0x7f, 0x0c, 0x12, 0x01, 0x4a, 0x49, 0x24, 0xdb, 0x6e, 0xee, 0xb1, 0x7e, + 0xef, 0x4d, 0x3a, 0xdb, 0x2f, 0xdf, 0xce, 0x08, 0x04, 0x05, 0x2d, 0x89, 0xf6, 0xf0, 0x7d, 0xcf, + 0x05, 0x26, 0x54, 0xba, 0x99, 0x77, 0x1b, 0x51, 0xff, 0x3d, 0xf1, 0xf7, 0xc3, 0x12, 0xe6, 0xb4, + 0x4a, 0xdd, 0xca, 0x97, 0xa6, 0x9f, 0xf9, 0x69, 0x25, 0xfa, 0xf4, 0x35, 0xcb, 0xad, 0x57, 0x57, + 0x9f, 0x12, 0x34, 0xcf, 0x5b, 0xb7, 0xcc, 0xc5, 0x33, 0xf1, 0x6e, 0xb6, 0xe8, 0xb9, 0x6c, 0x2e, + 0x50, 0x1a, 0xf1, 0xbb, 0x9f, 0xc3, 0x22, 0xf5, 0xd5, 0x1b, 0xfc, 0x48, 0xfd, 0xcb, 0xad, 0xa7, + 0x88, 0x58, 0x6c, 0x56, 0x7f, 0x84, 0x01, 0x00, 0xda, 0x2d, 0x7c, 0x73, 0x83, 0x89, 0xb0, 0x4e, + 0xd2, 0xef, 0x72, 0x61, 0x3c, 0x1b, 0x8e, 0x95, 0xc1, 0x52, 0x2e, 0x0f, 0xa9, 0x76, 0x71, 0x43, + 0x1e, 0xff, 0xf9, 0x8f, 0xba, 0x5e, 0x3e, 0x7c, 0xf7, 0x97, 0xa5, 0xdf, 0x08, 0x84, 0x42, 0x82, + 0x1d, 0x75, 0xb8, 0x84, 0xac, 0x13, 0x38, 0x37, 0x2f, 0x3f, 0xce, 0xfa, 0xc3, 0x1e, 0x39, 0xc7, + 0x95, 0xe1, 0x27, 0x58, 0x46, 0x14, 0x9c, 0x82, 0x9e, 0x7e, 0x80, 0xbb, 0x8a, 0xb2, 0xc1, 0xee, + 0x4b, 0x3c, 0x5e, 0xb0, 0x41, 0x4e, 0x61, 0x62, 0xcd, 0x2c, 0x7d, 0xc5, 0x79, 0xf8, 0x21, 0x02, + 0x00, 0x26, 0x8a, 0x62, 0x38, 0x96, 0x21, 0xee, 0x58, 0xdf, 0xbe, 0x30, 0x48, 0x5c, 0x15, 0x3c, + 0x73, 0x63, 0xb6, 0xa2, 0xb1, 0x3c, 0xb1, 0x43, 0x03, 0xb1, 0x28, 0x81, 0xc2, 0xdd, 0x4f, 0x81, + 0x00, 0x10, 0x85, 0x2a, 0xd6, 0xab, 0x7c, 0x40, 0xe0, 0x97, 0xcf, 0x89, 0x68, 0xc1, 0xc3, 0x58, + 0x04, 0x47, 0x76, 0x03, 0x4d, 0x4f, 0x7e, 0x7f, 0xa6, 0x5f, 0x4d, 0x76, 0xc3, 0x12, 0x00, 0x15, + 0x63, 0x15, 0x8d, 0xef, 0xa2, 0xca, 0x73, 0xce, 0xf6, 0x3f, 0xf4, 0xca, 0x00, 0x17, 0x90, 0x94, + 0xfe, 0x33, 0x20, 0x0a, 0xe1, 0x6f, 0x6f, 0xe3, 0x9c, 0x18, 0x00, 0xf9, 0x0a, 0x4a, 0xc4, 0xa4, + 0xca, 0xd9, 0x0f, 0x10, 0xa4, 0xa5, 0x8d, 0xba, 0x7b, 0x85, 0xb4, 0xa0, 0x03, 0xca, 0x58, 0xb8, + 0xf0, 0x1c, 0x0e, 0xc0, 0xf2, 0x0e, 0x30, 0x4a, 0x1d, 0xa5, 0x19, 0x60, 0xb8, 0xb8, 0x17, 0x4c, + 0xf0, 0x20, 0x80, 0x80, 0x1b, 0x18, 0x21, 0x13, 0x89, 0xc7, 0x07, 0x00, 0x07, 0x06, 0x0c, 0x17, + 0x5b, 0x36, 0xa1, 0xef, 0x9e, 0x06, 0x01, 0xec, 0x04, 0xa7, 0x00, 0x1e, 0x59, 0x95, 0x0a, 0x29, + 0x60, 0xca, 0xc0, 0x57, 0x0a, 0x5d, 0x02, 0x41, 0x84, 0x08, 0xa0, 0xe2, 0x2f, 0xa3, 0x06, 0xa2, + 0xef, 0x86, 0xd0, 0x90, 0x27, 0x48, 0x4a, 0x40, 0x28, 0xdd, 0xf4, 0xd3, 0xba, 0xeb, 0x37, 0x57, + 0x97, 0x0d, 0xc2, 0x8c, 0x57, 0x1a, 0x7f, 0x0f, 0x28, 0x11, 0xbc, 0x87, 0xdf, 0x3f, 0x26, 0x74, + 0xeb, 0x6e, 0x34, 0xdb, 0xef, 0x5e, 0x35, 0xc7, 0x4f, 0xfe, 0x1b, 0x9f, 0x72, 0x78, 0xb7, 0x2f, + 0xbf, 0xf0, 0x45, 0xa4, 0x4f, 0xe1, 0x0b, 0x72, 0x5e, 0x6c, 0x97, 0x90, 0x9c, 0xbc, 0xfc, 0xba, + 0x26, 0x90, 0xd4, 0x21, 0x04, 0x5e, 0x35, 0x8e, 0x0e, 0x10, 0x08, 0x05, 0x0c, 0x66, 0x36, 0x0d, + 0x51, 0xaa, 0x91, 0x43, 0x61, 0x3b, 0x6f, 0x46, 0xe0, 0xcb, 0xcb, 0xc5, 0x31, 0x15, 0x10, 0xde, + 0x10, 0x19, 0x0a, 0x03, 0x4b, 0x63, 0x2f, 0xca, 0x77, 0x97, 0x61, 0x5f, 0x82, 0x8c, 0xb6, 0x39, + 0x1e, 0x4c, 0x62, 0x41, 0x08, 0x2b, 0x8a, 0xe7, 0xd4, 0x2a, 0x35, 0x7a, 0xee, 0xed, 0x93, 0x96, + 0xb8, 0x8b, 0x7c, 0x12, 0x1c, 0xba, 0xde, 0x7b, 0x89, 0x08, 0x85, 0x30, 0xbd, 0x49, 0xc9, 0x4a, + 0x9d, 0xf2, 0xcf, 0x36, 0xee, 0xd7, 0x85, 0x15, 0x96, 0x3c, 0xbc, 0x40, 0x50, 0x43, 0x18, 0x2e, + 0xe5, 0x3b, 0xd7, 0x22, 0x92, 0x78, 0x27, 0x37, 0x85, 0xf4, 0x09, 0xfe, 0x70, 0x80, 0x91, 0x9a, + 0xd1, 0xac, 0xb8, 0x5c, 0x74, 0xae, 0xdc, 0xad, 0xd7, 0xc1, 0x81, 0xce, 0xaa, 0xaf, 0x56, 0x30, + 0x75, 0x71, 0x68, 0xe8, 0x87, 0x3b, 0xf1, 0x20, 0x40, 0x04, 0x17, 0x10, 0xf0, 0x76, 0xc9, 0x12, + 0x72, 0x71, 0xf5, 0xaa, 0x87, 0x86, 0x98, 0x3a, 0x92, 0x98, 0x3e, 0xcb, 0xff, 0x86, 0x03, 0xd2, + 0x57, 0xc3, 0xaf, 0x27, 0x15, 0x11, 0xfc, 0x17, 0xb0, 0x78, 0xee, 0xd3, 0x6e, 0xe1, 0x9d, 0x50, + 0x64, 0xbe, 0x15, 0x22, 0xb8, 0x7f, 0xc3, 0xca, 0x00, 0xbf, 0x98, 0xe1, 0x7e, 0x67, 0x53, 0x37, + 0xfb, 0xc4, 0xb3, 0xe7, 0xd2, 0xf2, 0xed, 0x36, 0xc4, 0x3b, 0x1a, 0x93, 0xc7, 0x2f, 0x97, 0x84, + 0x20, 0x12, 0x86, 0x42, 0xc8, 0xae, 0xc1, 0x40, 0x1b, 0xef, 0xd7, 0x0f, 0x60, 0x01, 0x75, 0xb9, + 0x27, 0xec, 0x88, 0x6f, 0xff, 0xd3, 0x2f, 0x6f, 0x6f, 0xf7, 0x76, 0xec, 0x71, 0x97, 0x97, 0xbb, + 0xd3, 0x0c, 0x60, 0x53, 0x3e, 0x03, 0x14, 0x12, 0xe0, 0x0f, 0xc1, 0x28, 0xfe, 0x1c, 0x70, 0x00, + 0x4d, 0x61, 0xc7, 0x8e, 0x42, 0x90, 0x54, 0x31, 0x2e, 0xf8, 0xc5, 0x0f, 0xc2, 0xdf, 0xd9, 0x52, + 0x3e, 0xb6, 0xed, 0xf6, 0xe4, 0x02, 0xbe, 0x3f, 0xc3, 0xb8, 0x01, 0xd4, 0x4d, 0xe5, 0x22, 0x6c, + 0x10, 0x12, 0xe7, 0x73, 0xff, 0x17, 0x38, 0x78, 0xe2, 0x2f, 0x08, 0xfc, 0x02, 0x8f, 0x49, 0x63, + 0x13, 0xf6, 0x54, 0x41, 0xc3, 0x6b, 0x4a, 0x01, 0xf5, 0x2f, 0xdf, 0xe1, 0xb9, 0x3c, 0x78, 0xbd, + 0xba, 0x67, 0x61, 0xfb, 0xeb, 0xa8, 0xc8, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x61, 0x30, 0xb0, + 0x7a, 0x3f, 0x42, 0xfa, 0x3f, 0xa2, 0xc5, 0x1d, 0xd7, 0xa0, 0x65, 0xe8, 0x56, 0x52, 0xf4, 0x47, + 0x80, 0x17, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x62, 0x31, 0x30, 0x22, 0x9f, 0x20, 0xb5, + 0x55, 0x52, 0x75, 0xe8, 0xfe, 0x8a, 0x3c, 0xa3, 0xba, 0x8e, 0xd1, 0x9d, 0xdd, 0xd5, 0x45, 0xf2, + 0x6a, 0xf1, 0x7d, 0x53, 0x25, 0xd4, 0xcb, 0x3e, 0xb9, 0x7d, 0x4c, 0xb3, 0xeb, 0x95, 0x75, 0x32, + 0x5f, 0x5e, 0xfa, 0x2a, 0x01, 0xfd, 0x52, 0x42, 0xdd, 0x11, 0x32, 0x5d, 0x6b, 0xea, 0x91, 0x7a, + 0xb5, 0x74, 0x46, 0xae, 0xfa, 0xa9, 0xfa, 0xb9, 0x19, 0xd7, 0xbe, 0xea, 0xaa, 0xab, 0xad, 0x7c, + 0x11, 0x14, 0x98, 0xbd, 0x7c, 0x11, 0xeb, 0x50, 0x1d, 0xdf, 0x0d, 0x97, 0x3f, 0x51, 0xe5, 0x4d, + 0x34, 0xd3, 0xf7, 0xd7, 0xbe, 0x17, 0x36, 0xef, 0x48, 0xe1, 0x03, 0x46, 0xc5, 0xa4, 0xc7, 0xe2, + 0x6b, 0xff, 0x04, 0x72, 0xd5, 0x6b, 0x48, 0xaa, 0xfa, 0xf5, 0xf5, 0x8d, 0xf4, 0x54, 0x88, 0x6f, + 0x52, 0xa5, 0x74, 0x47, 0xfa, 0xb7, 0xcd, 0xab, 0xd7, 0x16, 0x25, 0xa6, 0x9a, 0x69, 0xa6, 0x9a, + 0x69, 0xf4, 0x29, 0xab, 0xab, 0xc2, 0x3d, 0x1e, 0xbe, 0x8e, 0x6b, 0xe0, 0x9c, 0x43, 0xbb, 0xf1, + 0x58, 0xed, 0x23, 0x9f, 0x05, 0x11, 0x75, 0xef, 0x77, 0xdf, 0xe0, 0x92, 0xee, 0xee, 0x95, 0x7a, + 0xd3, 0x7c, 0xc4, 0x77, 0x15, 0xfc, 0x11, 0x67, 0xbf, 0xd8, 0x79, 0x94, 0x83, 0x7b, 0x2d, 0xff, + 0xf6, 0x5f, 0x06, 0x68, 0xf9, 0xcd, 0x32, 0x4c, 0xf0, 0xba, 0xbf, 0xac, 0xbe, 0xbd, 0xf0, 0x47, + 0x7a, 0xf2, 0x8e, 0xea, 0xe5, 0xf4, 0x48, 0xe4, 0xfd, 0x11, 0xeb, 0xab, 0xc5, 0xf5, 0xeb, 0xeb, + 0xd5, 0xd7, 0xaf, 0xaf, 0x5f, 0x57, 0xf8, 0x21, 0xd6, 0xae, 0xfa, 0xbd, 0x75, 0x7f, 0xab, 0xcf, + 0xd1, 0xde, 0x16, 0xe8, 0x77, 0x40, 0x1b, 0x56, 0x24, 0x30, 0x4c, 0x1c, 0x42, 0xc1, 0x21, 0x84, + 0xb8, 0x07, 0x57, 0xe0, 0xed, 0xf8, 0x70, 0x13, 0x71, 0x56, 0x2a, 0xf6, 0xcd, 0xfc, 0x14, 0x12, + 0xe7, 0x39, 0x77, 0x7d, 0x88, 0x73, 0xa3, 0xe5, 0x0b, 0x75, 0x63, 0xeb, 0xf7, 0x02, 0x4c, 0x29, + 0x27, 0x93, 0x45, 0x60, 0xd7, 0xf1, 0x55, 0xfa, 0x29, 0x71, 0x0f, 0x72, 0xdd, 0xbb, 0x85, 0x05, + 0x4e, 0x2e, 0x0c, 0x41, 0xc0, 0xd2, 0x1e, 0x1c, 0x45, 0x40, 0x5a, 0x10, 0xf4, 0xc7, 0x40, 0x0a, + 0x96, 0x00, 0x3c, 0x1d, 0xf1, 0x90, 0x37, 0x23, 0xa4, 0x39, 0x78, 0x73, 0xda, 0xc0, 0x7e, 0x6b, + 0x0c, 0x86, 0x6a, 0x4e, 0xa0, 0x06, 0x0f, 0x7c, 0x0f, 0x27, 0xd1, 0x8c, 0x6d, 0x5d, 0xb9, 0xf8, + 0x29, 0x06, 0x03, 0x64, 0xa0, 0x02, 0xa3, 0xfd, 0x1c, 0x4f, 0x0f, 0x1c, 0x0e, 0xa0, 0x5e, 0x1d, + 0x02, 0xa1, 0x63, 0x6d, 0x36, 0x8f, 0x79, 0x7b, 0x58, 0x93, 0x82, 0xe0, 0x6c, 0x90, 0xc6, 0xe6, + 0xe4, 0x5f, 0xf0, 0x62, 0x08, 0x06, 0xc2, 0xe7, 0xc3, 0xa1, 0x62, 0x10, 0x11, 0x8e, 0x7c, 0x07, + 0x41, 0x60, 0x3a, 0x0b, 0x03, 0x9c, 0x4a, 0x70, 0x01, 0xcb, 0x2c, 0x6e, 0xe5, 0x83, 0x2b, 0xd0, + 0x84, 0xa4, 0x13, 0xc7, 0x02, 0xd1, 0x0e, 0xe0, 0xfb, 0x3f, 0xf0, 0xfe, 0x92, 0x12, 0x44, 0x13, + 0xf4, 0x6d, 0x89, 0x38, 0x00, 0x08, 0x00, 0xd0, 0x40, 0x15, 0x15, 0x74, 0x4f, 0xef, 0x22, 0x10, + 0x02, 0x15, 0x84, 0x38, 0x0d, 0xe0, 0x34, 0xe0, 0x60, 0xa3, 0x2e, 0x7f, 0x86, 0xca, 0xc1, 0xa7, + 0x41, 0x86, 0xe9, 0xee, 0xce, 0x48, 0xe2, 0x2f, 0xf0, 0x43, 0x6d, 0xa6, 0xef, 0xf1, 0x76, 0xd2, + 0x1b, 0x66, 0xc2, 0x1a, 0x06, 0x42, 0x16, 0x90, 0x7c, 0x15, 0xe9, 0x24, 0xe6, 0xa7, 0xee, 0xa9, + 0xd7, 0xc6, 0xc9, 0x25, 0x2a, 0x96, 0x79, 0x74, 0xd1, 0xae, 0x0e, 0x5e, 0xb1, 0x2d, 0x7a, 0x04, + 0x2a, 0xd6, 0xca, 0x05, 0xe1, 0x23, 0xfd, 0xd1, 0x9a, 0x3f, 0xe0, 0x82, 0x9b, 0x87, 0xf2, 0xf4, + 0x1e, 0xd2, 0x10, 0xc2, 0x26, 0x37, 0x01, 0x67, 0xf2, 0xb6, 0x7d, 0xc5, 0xff, 0xc6, 0x79, 0xae, + 0xd1, 0xaf, 0x5d, 0xee, 0xbb, 0x06, 0x72, 0x57, 0xf0, 0x57, 0x66, 0x78, 0xa7, 0xb9, 0x93, 0xa9, + 0xaa, 0xd2, 0x49, 0xfa, 0xf8, 0x2b, 0x2f, 0x36, 0x25, 0x28, 0xcd, 0x2a, 0x14, 0xbe, 0x33, 0xee, + 0x4d, 0x4f, 0xf1, 0xdb, 0xda, 0x2e, 0x3f, 0xdb, 0x4f, 0xc1, 0x74, 0x92, 0x49, 0x03, 0xe5, 0xc5, + 0xcf, 0xf0, 0x45, 0x6d, 0xae, 0x5f, 0x17, 0x11, 0x20, 0xaa, 0x48, 0xae, 0xbf, 0x05, 0x76, 0xaf, + 0x24, 0x93, 0x2b, 0x7d, 0x57, 0xbe, 0xad, 0x5d, 0x58, 0xbe, 0x08, 0xe6, 0xce, 0x29, 0x6a, 0xe4, + 0xbd, 0xfe, 0x0b, 0x7b, 0x65, 0x6b, 0x54, 0x34, 0x47, 0x2f, 0x82, 0x4a, 0x26, 0x67, 0xfc, 0x5f, + 0x27, 0x75, 0xf2, 0xf6, 0xd7, 0xc3, 0x95, 0x6c, 0xf2, 0xd4, 0x90, 0x73, 0x42, 0xff, 0xc5, 0x90, + 0xde, 0xb9, 0x3e, 0x37, 0xa1, 0x2d, 0x7c, 0x79, 0x24, 0xe6, 0x63, 0xbb, 0x4c, 0xdb, 0x5d, 0xf0, + 0xa5, 0xed, 0x73, 0x52, 0xd9, 0x06, 0x59, 0x39, 0x86, 0x33, 0x83, 0xc5, 0xf1, 0x5d, 0x31, 0x2a, + 0x4d, 0xb5, 0xc1, 0x04, 0x6d, 0xdd, 0x58, 0x80, 0xdc, 0x95, 0x43, 0x47, 0x38, 0xea, 0x18, 0x7a, + 0x81, 0xef, 0xa6, 0x5a, 0x07, 0x46, 0x65, 0xa0, 0x94, 0x49, 0x7f, 0xe0, 0xe4, 0x10, 0x8d, 0x21, + 0x33, 0xeb, 0x40, 0x3f, 0x0e, 0x87, 0x85, 0x50, 0xd4, 0xd1, 0xe6, 0x12, 0xa0, 0x03, 0x0a, 0x37, + 0xd8, 0x0d, 0xfa, 0x8d, 0x97, 0xd6, 0xd1, 0x4f, 0x83, 0xc5, 0x9e, 0x90, 0x47, 0x4f, 0x8f, 0x39, + 0xf0, 0xf0, 0xa7, 0x39, 0xfc, 0x48, 0x40, 0x69, 0x1f, 0x95, 0x33, 0xcc, 0x85, 0x42, 0xa6, 0x51, + 0xa8, 0xc4, 0x44, 0xea, 0x01, 0xdf, 0x22, 0x4a, 0xe1, 0xb2, 0xae, 0xf5, 0xa8, 0x0f, 0x6b, 0xfe, + 0x14, 0xbf, 0xd8, 0x3b, 0xe1, 0xcf, 0xcf, 0x95, 0x9d, 0x55, 0xa1, 0xcf, 0x77, 0x38, 0x21, 0x04, + 0x01, 0x4b, 0xe3, 0x02, 0xc1, 0xad, 0x52, 0x65, 0x49, 0xc0, 0x79, 0x6d, 0x65, 0x83, 0x32, 0x4e, + 0x93, 0x64, 0xed, 0x0e, 0xf8, 0xa3, 0x60, 0x3b, 0x35, 0x2e, 0x1f, 0x3f, 0x8b, 0xfc, 0xfc, 0x22, + 0x08, 0x06, 0xdd, 0x03, 0x9e, 0x96, 0xf2, 0x0e, 0x90, 0x10, 0x38, 0x28, 0xc9, 0x95, 0x0e, 0xfa, + 0xbc, 0x0d, 0x15, 0xa9, 0x6c, 0xf0, 0x48, 0x2d, 0x90, 0xea, 0xea, 0xdd, 0x29, 0x4a, 0x48, 0x67, + 0xdd, 0xf8, 0x46, 0xa1, 0x2a, 0xff, 0x0c, 0x15, 0xee, 0xd1, 0xe4, 0x2d, 0xd8, 0x76, 0xa9, 0x95, + 0x8e, 0xaf, 0x0a, 0x3f, 0xf0, 0x4a, 0x55, 0xb5, 0xb1, 0x9f, 0x5c, 0x57, 0xef, 0x88, 0xd2, 0xa7, + 0x3f, 0xfd, 0x67, 0x7d, 0xd6, 0x25, 0xf8, 0x44, 0x87, 0xcf, 0x69, 0xa9, 0x70, 0xdf, 0xfc, 0x11, + 0xf2, 0x2a, 0x4a, 0x5f, 0x29, 0x53, 0xda, 0xf2, 0xed, 0x1f, 0x72, 0x71, 0xb3, 0xb3, 0xcd, 0x87, + 0xd6, 0x9d, 0x98, 0x71, 0x49, 0xd7, 0x4b, 0xa1, 0x26, 0x78, 0x55, 0xb3, 0x51, 0x1d, 0x7f, 0xe3, + 0x75, 0x53, 0xd6, 0x91, 0x35, 0x36, 0x43, 0x2e, 0x5b, 0xb4, 0xa5, 0xf2, 0xdf, 0xfd, 0xf2, 0x74, + 0xc4, 0xf4, 0x48, 0x25, 0xe6, 0xea, 0xa3, 0x79, 0xb4, 0xd3, 0x4f, 0xdf, 0x49, 0xd7, 0x04, 0xc5, + 0x4e, 0x9f, 0x3f, 0xf3, 0x7d, 0xda, 0x6b, 0x5c, 0x12, 0x6f, 0x4a, 0x2a, 0x83, 0x80, 0x88, 0x78, + 0x8d, 0xb7, 0x2e, 0xa1, 0x38, 0x07, 0x0f, 0x0c, 0xae, 0x62, 0x56, 0x42, 0x90, 0x64, 0xd3, 0x03, + 0xcd, 0x73, 0x7f, 0xe0, 0x41, 0x04, 0x23, 0x6c, 0xee, 0x90, 0xff, 0x96, 0xd2, 0x61, 0x21, 0x44, + 0xb9, 0x5a, 0x0f, 0x36, 0x8e, 0xdc, 0x1b, 0x09, 0x49, 0xca, 0x96, 0x62, 0x99, 0x60, 0x62, 0x0f, + 0x08, 0x44, 0xf9, 0x7f, 0x08, 0x01, 0xd4, 0x7b, 0xb7, 0x64, 0xbf, 0x88, 0x87, 0xe5, 0x9a, 0x88, + 0xe3, 0x32, 0x29, 0x24, 0x1a, 0x8f, 0x02, 0xc3, 0x6f, 0x1b, 0xcb, 0x9b, 0xb8, 0x7f, 0xc4, 0x42, + 0x9d, 0xe4, 0x69, 0x1f, 0xe5, 0x81, 0xb3, 0x09, 0x4a, 0xae, 0xab, 0xd2, 0x48, 0x18, 0x88, 0xc9, + 0xb3, 0x3b, 0x82, 0x30, 0x4a, 0xc0, 0x5a, 0xed, 0x57, 0x1c, 0xc9, 0x64, 0x93, 0x94, 0xe3, 0x06, + 0x58, 0x64, 0x20, 0x1e, 0x30, 0x7e, 0x94, 0x90, 0x0b, 0x66, 0x28, 0xa5, 0x0b, 0x31, 0xe5, 0xc9, + 0x02, 0xc4, 0x96, 0x98, 0x66, 0x1f, 0x61, 0xd0, 0x9e, 0x06, 0xb1, 0x1c, 0xd1, 0xca, 0x72, 0xd7, + 0xfc, 0x36, 0x24, 0x1d, 0xb2, 0x0e, 0x50, 0x3f, 0xcb, 0x14, 0x20, 0x12, 0xb3, 0x42, 0xe0, 0x60, + 0x83, 0x13, 0xd4, 0xbf, 0xc1, 0x61, 0xde, 0xd5, 0x76, 0x92, 0xdf, 0x26, 0x3e, 0x62, 0x5b, 0xb7, + 0xe0, 0x9b, 0x2e, 0x67, 0x69, 0x19, 0xfa, 0xf8, 0x7e, 0x42, 0xac, 0x2d, 0x62, 0x43, 0x96, 0x47, + 0x91, 0xda, 0xd6, 0x91, 0xf4, 0xec, 0xb2, 0x64, 0xff, 0xe3, 0x2d, 0x6d, 0x0d, 0x38, 0x3f, 0x53, + 0x2f, 0xa6, 0x95, 0x3f, 0x0c, 0x6c, 0xd3, 0x64, 0x4d, 0x4a, 0x86, 0x52, 0xad, 0x1c, 0xe6, 0x3e, + 0x97, 0xfe, 0x59, 0x08, 0x90, 0x8c, 0x07, 0xfb, 0xa6, 0xd1, 0xb2, 0xa2, 0xf0, 0x5b, 0xbc, 0xfa, + 0x7d, 0x4d, 0xa5, 0x28, 0x4f, 0x86, 0x7c, 0xb8, 0xb9, 0xaa, 0xff, 0xe4, 0x21, 0x59, 0x56, 0x2a, + 0xe8, 0xb9, 0x49, 0xde, 0xd3, 0x5f, 0x3d, 0x73, 0xf3, 0x7f, 0xf0, 0x4f, 0xb7, 0x25, 0x36, 0xcb, + 0x8f, 0x0a, 0x77, 0xe5, 0xa2, 0xe0, 0xb7, 0x7a, 0x18, 0xf5, 0x7e, 0x56, 0x18, 0xbe, 0x08, 0x67, + 0x62, 0xc7, 0xee, 0x0a, 0x28, 0x8d, 0xc0, 0xa2, 0x0a, 0x46, 0xd0, 0x00, 0x01, 0x35, 0x87, 0xbc, + 0x90, 0x00, 0x1a, 0x13, 0xb4, 0x6c, 0x0d, 0xc9, 0xa4, 0x4a, 0xd9, 0x9a, 0xc8, 0x13, 0x81, 0xe4, + 0xaa, 0x8a, 0xd7, 0xad, 0xb3, 0xf2, 0x7b, 0x49, 0x95, 0x03, 0x84, 0x14, 0x71, 0x60, 0x1e, 0xe5, + 0xa8, 0x88, 0x10, 0xbe, 0x6d, 0xb6, 0xd5, 0x62, 0x0e, 0xdf, 0x7f, 0x12, 0x10, 0xc1, 0xaf, 0xa5, + 0xa4, 0xcf, 0x65, 0xc7, 0xdf, 0x08, 0x08, 0x1e, 0x51, 0x1f, 0x14, 0xbe, 0x5b, 0x7d, 0x22, 0x7f, + 0x84, 0x07, 0x88, 0x22, 0xa4, 0xc2, 0xee, 0x5b, 0xd2, 0x2b, 0x16, 0x87, 0xae, 0x11, 0x08, 0x0d, + 0xaf, 0x8d, 0x49, 0x56, 0xb7, 0xb0, 0x73, 0x89, 0x21, 0x06, 0x34, 0x9d, 0x5a, 0x4c, 0xe5, 0x40, + 0x71, 0x23, 0x1d, 0x69, 0xb0, 0x80, 0x6d, 0xb8, 0x4b, 0xae, 0x28, 0x4a, 0xd4, 0x4a, 0x74, 0xd7, + 0xc9, 0xcc, 0x5a, 0x67, 0x63, 0x7c, 0x31, 0xaa, 0x82, 0x89, 0x7d, 0x50, 0xb0, 0x00, 0xd0, 0x4a, + 0x07, 0x00, 0x41, 0xb2, 0x03, 0xef, 0x4d, 0xbf, 0xf0, 0x41, 0xa0, 0x72, 0x73, 0x61, 0x15, 0x8d, + 0x01, 0x80, 0x24, 0x81, 0xc0, 0x60, 0x19, 0x56, 0xa1, 0x60, 0x11, 0x3e, 0x28, 0x22, 0xf0, 0x6b, + 0x48, 0xc8, 0xb9, 0x38, 0x74, 0x43, 0xbf, 0xe5, 0xee, 0xcf, 0x87, 0xed, 0x46, 0xd7, 0x6e, 0x5d, + 0x2d, 0x24, 0x97, 0x2f, 0x4f, 0xfc, 0x25, 0xcf, 0x96, 0xdf, 0xf2, 0xe9, 0xcb, 0xc1, 0x34, 0x31, + 0x0d, 0x52, 0x2e, 0x92, 0x70, 0xa3, 0x23, 0x8a, 0xb6, 0x10, 0x90, 0x5d, 0xff, 0x89, 0x1b, 0x3f, + 0xce, 0xfd, 0x54, 0x5d, 0x62, 0xe4, 0xe2, 0xe5, 0xee, 0x20, 0xaf, 0x03, 0x4c, 0x69, 0x23, 0xda, + 0x57, 0x6a, 0xa9, 0x2f, 0xf1, 0x21, 0x10, 0x4d, 0x5a, 0x5b, 0xb8, 0xae, 0xbc, 0x48, 0xf2, 0x2b, + 0xe7, 0xee, 0xee, 0xbb, 0x16, 0x65, 0x7c, 0x29, 0x92, 0x19, 0x98, 0xc9, 0x5a, 0x12, 0x16, 0xd6, + 0xb0, 0x90, 0x42, 0xc6, 0x46, 0x7c, 0x42, 0x0f, 0x93, 0xee, 0xd5, 0x0c, 0x5e, 0xf8, 0x2c, 0xb7, + 0x6f, 0xca, 0x55, 0x22, 0x49, 0xb6, 0xd6, 0x11, 0xf2, 0xef, 0x77, 0x11, 0x1e, 0x25, 0x2d, 0x53, + 0xdb, 0x55, 0x4c, 0x3d, 0xde, 0xe2, 0x01, 0x40, 0x50, 0x65, 0x6a, 0xa2, 0xe2, 0xe2, 0x40, 0xf8, + 0x2f, 0x5f, 0x8d, 0xa6, 0x35, 0xa8, 0xfa, 0xb9, 0x76, 0x3b, 0x00, 0x14, 0xc3, 0xc1, 0x80, 0x52, + 0x06, 0x3a, 0xe7, 0xf0, 0x29, 0x48, 0x48, 0x06, 0x55, 0x81, 0xe2, 0xd9, 0xec, 0x57, 0xd4, 0x2e, + 0x4e, 0x52, 0x0d, 0x59, 0x08, 0x32, 0xf0, 0x61, 0xc2, 0x20, 0xc0, 0x66, 0x7b, 0xc2, 0xff, 0x0e, + 0xac, 0xad, 0x66, 0x8a, 0xb4, 0x94, 0xbe, 0x94, 0x3a, 0x8e, 0x01, 0x1a, 0x80, 0xdf, 0x60, 0x5b, + 0xe6, 0x3f, 0x78, 0xee, 0xee, 0x51, 0xbe, 0x31, 0x38, 0x76, 0x7e, 0x4c, 0x0f, 0xdf, 0xe9, 0xba, + 0xa9, 0xc8, 0xe7, 0xe3, 0x9f, 0xd6, 0xea, 0x85, 0xc4, 0x58, 0x86, 0xf7, 0x41, 0x88, 0x06, 0x6c, + 0xb4, 0xad, 0x3f, 0xc3, 0x78, 0x00, 0x5c, 0x46, 0x32, 0x53, 0xc8, 0xd3, 0xe4, 0xef, 0xf6, 0xda, + 0x7a, 0xba, 0xdd, 0x8a, 0x0d, 0xc5, 0x4b, 0xe2, 0xcb, 0xea, 0x96, 0xdb, 0x65, 0x8b, 0x06, 0x20, + 0x69, 0xe4, 0x61, 0x07, 0x36, 0x19, 0x00, 0x0a, 0x2f, 0xf8, 0x2d, 0x3a, 0xaa, 0xcf, 0xd4, 0xbb, + 0x2e, 0xb3, 0xe0, 0xbb, 0xa6, 0xe9, 0xd3, 0x71, 0x5d, 0x7c, 0x10, 0xd5, 0x8f, 0xcb, 0xe0, 0xa6, + 0xda, 0xa4, 0x89, 0xb5, 0xdf, 0x7c, 0xa1, 0xae, 0x8a, 0xc7, 0xc1, 0x77, 0x2f, 0xf2, 0xf7, 0xbe, + 0x3a, 0xde, 0x95, 0xd2, 0x77, 0x77, 0x72, 0x70, 0xa0, 0x80, 0xa5, 0x03, 0xb9, 0x20, 0x50, 0x3b, + 0x93, 0xab, 0x3c, 0x0c, 0xb3, 0x6b, 0x23, 0x4b, 0x9d, 0xf0, 0x0c, 0x5d, 0x3e, 0xe2, 0x04, 0x82, + 0xb2, 0x0b, 0xc4, 0x3a, 0x99, 0x3a, 0x10, 0x47, 0x28, 0x6c, 0x9f, 0xbc, 0xb8, 0xe7, 0x89, 0x1e, + 0x59, 0x33, 0x94, 0xdc, 0xaa, 0xa5, 0x3b, 0x7c, 0x40, 0x60, 0x15, 0x91, 0x64, 0x25, 0xbb, 0x28, + 0xe9, 0x05, 0xe5, 0xe3, 0x6a, 0x5f, 0x37, 0x63, 0xf2, 0xe2, 0x42, 0x03, 0x2c, 0xf9, 0x99, 0x71, + 0x72, 0x65, 0x4b, 0xdc, 0x60, 0x10, 0x13, 0x92, 0x0b, 0x6f, 0xa5, 0xe2, 0x4f, 0x6d, 0x36, 0x92, + 0xbf, 0xc2, 0xbd, 0x32, 0x31, 0x18, 0xa2, 0x4c, 0x6a, 0x9b, 0x92, 0x14, 0x5f, 0xe0, 0x93, 0x43, + 0x2d, 0xf5, 0xc4, 0x82, 0x00, 0xa0, 0xa1, 0x43, 0x17, 0x10, 0x70, 0xb3, 0x11, 0xc0, 0xae, 0x23, + 0x8c, 0xdc, 0x30, 0xa5, 0xe4, 0x20, 0xc4, 0x0c, 0x2d, 0xca, 0x26, 0x47, 0x71, 0xc2, 0x22, 0x06, + 0xdc, 0xcc, 0x7d, 0x27, 0x7d, 0xf6, 0xe5, 0x83, 0xe8, 0x7d, 0x5f, 0x14, 0x7d, 0x3f, 0xff, 0x89, + 0x8e, 0x28, 0x89, 0x07, 0x23, 0x0a, 0xd6, 0x93, 0xa8, 0x5e, 0xdf, 0x88, 0x05, 0x47, 0x03, 0x35, + 0x22, 0x96, 0x5e, 0xa5, 0x94, 0x07, 0x6e, 0xab, 0xf9, 0xc3, 0x00, 0x80, 0x74, 0x48, 0x90, 0x4f, + 0x48, 0x27, 0xb9, 0x51, 0x75, 0x25, 0x0b, 0x2d, 0xeb, 0x5e, 0x18, 0x18, 0x60, 0x4e, 0xa0, 0x04, + 0xa4, 0x61, 0x45, 0x43, 0x71, 0x4f, 0x77, 0x88, 0xe4, 0x67, 0x38, 0x2b, 0xbe, 0x20, 0x1e, 0xd3, + 0xb7, 0x08, 0x81, 0xa0, 0x29, 0xbe, 0xea, 0xbc, 0x6f, 0x88, 0x60, 0x11, 0x0c, 0xa5, 0x9d, 0x62, + 0x19, 0xb8, 0x73, 0xeb, 0x61, 0xd9, 0x40, 0x03, 0xea, 0x05, 0x6e, 0x4a, 0x4a, 0x23, 0x1e, 0xf7, + 0x80, 0xfe, 0xe2, 0xad, 0xc3, 0xfe, 0xca, 0xea, 0x0e, 0xae, 0xea, 0x69, 0xb6, 0x6e, 0x3f, 0xe3, + 0xa2, 0xed, 0xf8, 0x60, 0x69, 0x04, 0x15, 0x00, 0x50, 0x61, 0x8c, 0xe5, 0xc3, 0xc6, 0x9d, 0xfe, + 0x08, 0xed, 0x26, 0x06, 0xa4, 0x05, 0xd9, 0xca, 0x6e, 0xca, 0xda, 0x4c, 0x38, 0x4f, 0x92, 0x75, + 0x28, 0xff, 0x76, 0xcf, 0xb9, 0x38, 0x9d, 0x4d, 0x9a, 0xd7, 0xe1, 0x4b, 0xbe, 0x96, 0xd5, 0xa6, + 0x93, 0x4d, 0x48, 0x79, 0x28, 0x39, 0xfe, 0x6d, 0xd0, 0xd3, 0xf5, 0xd5, 0x72, 0xd7, 0x72, 0x70, + 0xa0, 0x88, 0x87, 0xdb, 0x6f, 0x1d, 0xc9, 0x9d, 0x33, 0xb2, 0x4f, 0xf1, 0x0e, 0x2b, 0x1f, 0x1d, + 0xd5, 0x75, 0x55, 0xaf, 0x89, 0x05, 0x72, 0xdc, 0xec, 0x64, 0x51, 0x4d, 0xd2, 0x2f, 0xeb, 0xc2, + 0x21, 0x49, 0xcb, 0x29, 0x18, 0xc1, 0xba, 0x65, 0xc6, 0xee, 0x62, 0xee, 0xdd, 0x82, 0x59, 0x53, + 0x79, 0x7b, 0x58, 0x25, 0xf0, 0x5a, 0x74, 0xad, 0x58, 0x3c, 0x46, 0x69, 0x53, 0xea, 0xcf, 0x10, + 0x09, 0xc5, 0x56, 0x27, 0xdb, 0x3c, 0xf5, 0xe0, 0xf1, 0x23, 0xe5, 0x66, 0x2a, 0xd3, 0x8a, 0xdc, + 0x57, 0x73, 0x10, 0xf8, 0x80, 0x88, 0xc3, 0xb3, 0x62, 0xee, 0xef, 0x2c, 0x7b, 0xbb, 0xbe, 0x18, + 0x0c, 0x8b, 0xee, 0xee, 0xf5, 0x87, 0x94, 0x00, 0xcb, 0x9a, 0x3d, 0x82, 0x75, 0x4d, 0xff, 0xa6, + 0x5d, 0xc1, 0x80, 0xd5, 0x4a, 0x46, 0x02, 0x0d, 0xc1, 0x8c, 0x68, 0x2b, 0xd7, 0xe1, 0xc4, 0x50, + 0x00, 0xdf, 0x79, 0x07, 0x11, 0x58, 0x24, 0xfb, 0xaf, 0xf8, 0xb8, 0x9d, 0x49, 0x07, 0xe3, 0x83, + 0xb8, 0x9e, 0x89, 0xeb, 0xfb, 0xf8, 0xb4, 0x16, 0xbe, 0xbf, 0xc3, 0x8a, 0x00, 0x64, 0x0b, 0xa5, + 0x30, 0xbe, 0x6f, 0xaf, 0x71, 0x56, 0x6e, 0x5c, 0x2e, 0xb7, 0x9f, 0xd0, 0x32, 0xd0, 0x26, 0xb0, + 0x63, 0xf0, 0xc8, 0x74, 0x7a, 0x7c, 0x33, 0x05, 0x32, 0xd0, 0xb7, 0x72, 0xd6, 0x05, 0xb6, 0x9e, + 0xb3, 0xeb, 0xc7, 0x7c, 0xfc, 0x09, 0x20, 0x58, 0x0a, 0x68, 0x94, 0x73, 0x29, 0xa0, 0x45, 0xa0, + 0xba, 0xe1, 0xe5, 0x8b, 0x26, 0x1c, 0xe3, 0xf9, 0xf9, 0x3d, 0x98, 0xbc, 0x96, 0x0c, 0x74, 0xf8, + 0x43, 0xce, 0x67, 0x5b, 0xf0, 0x28, 0x81, 0x00, 0x69, 0x0f, 0x71, 0x32, 0x47, 0x02, 0xaf, 0xc1, + 0x55, 0x59, 0xa7, 0x83, 0x2c, 0x71, 0x99, 0x23, 0x4a, 0xce, 0x01, 0xe1, 0xb7, 0x12, 0x45, 0x51, + 0xe4, 0x58, 0x2d, 0xc3, 0xa4, 0x25, 0x08, 0x99, 0x81, 0x26, 0x72, 0x88, 0x60, 0x4a, 0xa4, 0xff, + 0x82, 0x91, 0x33, 0xe1, 0xfe, 0xe7, 0xcf, 0x51, 0xe5, 0xf7, 0x3e, 0x09, 0x24, 0x5d, 0x50, 0x9f, + 0xbe, 0x09, 0xfb, 0x4a, 0x6d, 0xda, 0xb1, 0x08, 0xf7, 0x49, 0x2f, 0xc3, 0x72, 0x32, 0x92, 0x1a, + 0x46, 0x05, 0xdb, 0x6d, 0xfd, 0xf5, 0x23, 0x7c, 0x17, 0x62, 0x6c, 0xf9, 0x58, 0xf4, 0xbc, 0x51, + 0x25, 0xfc, 0xcc, 0xd8, 0xdf, 0x7a, 0xaa, 0x5e, 0x09, 0xcb, 0xb4, 0xaa, 0x97, 0x29, 0x38, 0x23, + 0x26, 0xd9, 0xd8, 0x6e, 0x22, 0x7b, 0xaa, 0x15, 0xf2, 0xff, 0xc4, 0x87, 0x8d, 0x17, 0xaa, 0xaa, + 0x59, 0x71, 0x4b, 0x6d, 0xb8, 0xd6, 0xbf, 0xf0, 0x88, 0x46, 0x9d, 0x75, 0xab, 0x1e, 0x55, 0x1e, + 0x36, 0xdb, 0x05, 0x2a, 0xe7, 0x3a, 0x73, 0x17, 0xb2, 0x3a, 0xbc, 0xcc, 0x4d, 0x85, 0x47, 0xa1, + 0x78, 0xef, 0xd1, 0x95, 0x45, 0xae, 0xe8, 0x8f, 0x0f, 0xf3, 0x9d, 0x52, 0x49, 0xbe, 0x3f, 0xf0, + 0xd5, 0x69, 0x53, 0xb8, 0xf6, 0x2e, 0x82, 0x45, 0xdf, 0xc2, 0x82, 0x0a, 0xa5, 0xa2, 0xc6, 0x37, + 0x12, 0xa8, 0x10, 0xb0, 0x7a, 0xa1, 0x8d, 0xc2, 0xcd, 0x0e, 0x1c, 0x6e, 0x1e, 0xa8, 0x2d, 0xdd, + 0x7c, 0x15, 0xcc, 0xc2, 0xcc, 0xbd, 0x4b, 0x87, 0x38, 0x8a, 0xf5, 0x1d, 0x78, 0x90, 0xc1, 0xd5, + 0x4d, 0x93, 0x50, 0x60, 0xa4, 0x27, 0x72, 0xde, 0x11, 0x2b, 0x53, 0xff, 0x04, 0x58, 0x75, 0x93, + 0x64, 0x07, 0xc1, 0x51, 0x49, 0xd5, 0x8d, 0xff, 0x26, 0xb6, 0x5c, 0x27, 0xca, 0xbb, 0x96, 0xe9, + 0x65, 0xe0, 0x80, 0x6d, 0x87, 0x51, 0xeb, 0x70, 0x78, 0xf9, 0x2a, 0xa3, 0x0e, 0x86, 0x58, 0x37, + 0x71, 0x78, 0xd2, 0x8a, 0x32, 0xf1, 0x5e, 0x13, 0x03, 0xae, 0x5f, 0xfc, 0x18, 0x0d, 0xee, 0x2e, + 0xa7, 0x03, 0xa3, 0x9f, 0x8e, 0x3f, 0x38, 0x7a, 0x89, 0xf9, 0xbe, 0x20, 0x1e, 0x6e, 0xde, 0x20, + 0x00, 0x10, 0x0f, 0xf9, 0xc0, 0x18, 0x44, 0x00, 0x61, 0xf0, 0xf2, 0x80, 0x0a, 0xd6, 0xd8, 0xe3, + 0x5b, 0x1e, 0x84, 0xbd, 0xd4, 0x39, 0xec, 0xa1, 0x7a, 0x78, 0x3e, 0xf7, 0xdd, 0xcf, 0x3c, 0xfe, + 0x42, 0x01, 0x09, 0xa8, 0xe0, 0x31, 0x42, 0xaa, 0x1b, 0x60, 0x2f, 0xb1, 0xf1, 0xfc, 0x38, 0x42, + 0x00, 0x01, 0x4f, 0x62, 0xac, 0xf9, 0xca, 0x0d, 0xff, 0xf6, 0xdb, 0xb5, 0x2d, 0xe5, 0xe2, 0xbf, + 0xa9, 0x7a, 0xe1, 0x97, 0x50, 0xed, 0xa9, 0x47, 0xf1, 0x62, 0xca, 0x0e, 0xbf, 0x0e, 0xa8, 0x00, + 0xc4, 0x03, 0x52, 0x30, 0x7c, 0xee, 0xbe, 0x85, 0xf5, 0x51, 0x46, 0x4d, 0xc1, 0x78, 0xf5, 0xc9, + 0x5e, 0x27, 0x3c, 0x58, 0x0c, 0xb0, 0x3e, 0xea, 0x17, 0x48, 0xb4, 0x28, 0xd5, 0xe2, 0x1b, 0xe0, + 0x6a, 0x1e, 0x97, 0x7f, 0x82, 0x19, 0xc1, 0xe9, 0xcb, 0x50, 0xab, 0x96, 0x5d, 0xe2, 0x7a, 0x3e, + 0xae, 0x00, 0x00, 0x00, 0x01, 0x41, 0x9a, 0x63, 0x31, 0xb0, 0x26, 0x8f, 0xd0, 0xbe, 0x8f, 0xe7, + 0x28, 0xe9, 0x53, 0x4d, 0x34, 0xfc, 0x77, 0x51, 0xf4, 0x67, 0x73, 0x63, 0xb0, 0xf8, 0xfc, 0x3f, + 0x44, 0x35, 0x27, 0x26, 0xeb, 0x17, 0xd5, 0x2a, 0x5d, 0x14, 0xab, 0x3e, 0xb9, 0x7d, 0x4a, 0xb3, + 0xeb, 0x95, 0x75, 0x2a, 0x5f, 0x0d, 0x6b, 0x2b, 0x7a, 0x86, 0xf1, 0xc3, 0x87, 0x86, 0x3a, 0xa5, + 0x4b, 0xad, 0x7d, 0x53, 0xaf, 0x56, 0xae, 0x8c, 0xd1, 0x1d, 0x08, 0x7f, 0xa1, 0x6e, 0x46, 0x75, + 0xef, 0xa9, 0xd3, 0xeb, 0x97, 0xd6, 0xbe, 0xb5, 0xf0, 0x4c, 0x7e, 0x4f, 0x7b, 0xba, 0x4e, 0xbd, + 0xf0, 0x44, 0x6d, 0x55, 0x8f, 0xab, 0x7d, 0x14, 0xa9, 0xf1, 0x65, 0xd2, 0x4b, 0x49, 0x25, 0xd1, + 0xa3, 0x7d, 0x15, 0x3a, 0x1b, 0xd4, 0xa9, 0xf4, 0x48, 0xbe, 0xaf, 0xf5, 0x6a, 0xe0, 0x9e, 0xae, + 0xba, 0xd6, 0xbe, 0x2c, 0xe7, 0xa1, 0xe8, 0xfa, 0x3e, 0x87, 0xa1, 0xe8, 0xfa, 0x3e, 0x8f, 0xa1, + 0x4d, 0x5d, 0x15, 0x1d, 0xf8, 0x23, 0xbd, 0xee, 0x89, 0xe3, 0x0e, 0x92, 0x5a, 0x49, 0x69, 0x25, + 0xa4, 0x96, 0x6e, 0xac, 0x3d, 0x6b, 0xe8, 0xa6, 0xbe, 0x85, 0x47, 0x3e, 0xbb, 0xfd, 0x53, 0x2f, + 0x5b, 0x3e, 0x0a, 0xeb, 0xa3, 0x4f, 0x25, 0x27, 0x66, 0xf9, 0x7c, 0x18, 0x74, 0x8b, 0x9c, 0x77, + 0x4f, 0x53, 0xcf, 0xff, 0xc1, 0x26, 0xaa, 0xa9, 0xcf, 0xac, 0xbe, 0xbd, 0xf4, 0x5c, 0xa3, 0xba, + 0x33, 0x97, 0xd6, 0x39, 0x37, 0x16, 0x5c, 0xdf, 0x9b, 0xfc, 0x39, 0xdd, 0xcd, 0x1d, 0xfa, 0x69, + 0xa6, 0x9f, 0x9a, 0x4e, 0x5e, 0x4e, 0xdf, 0xe7, 0xc8, 0xef, 0xd5, 0x55, 0x7c, 0x17, 0x91, 0xb6, + 0xdb, 0x6d, 0x6b, 0x00, 0x2b, 0xbb, 0xba, 0xaa, 0xaf, 0xa1, 0x51, 0x7c, 0x58, 0xbd, 0x91, 0x58, + 0xc6, 0xbd, 0x57, 0x82, 0x42, 0xee, 0xe5, 0x15, 0x73, 0xf2, 0xa6, 0x9a, 0x69, 0xfb, 0xe2, 0xa5, + 0xce, 0x7a, 0x3f, 0xe2, 0xf9, 0x70, 0xb9, 0x97, 0x0b, 0x9e, 0x78, 0xed, 0x4d, 0x34, 0xd3, 0xff, + 0x2e, 0x7a, 0x6b, 0x82, 0x7f, 0x3e, 0x1f, 0x3c, 0x76, 0x6f, 0x88, 0x92, 0xc9, 0x7e, 0x7c, 0xfc, + 0x12, 0x4f, 0x9c, 0x76, 0x75, 0xeb, 0x2f, 0x82, 0xae, 0x5b, 0x2d, 0xf3, 0x42, 0x46, 0x24, 0x64, + 0x56, 0x9f, 0x05, 0x7e, 0x5c, 0xd4, 0xd9, 0xb4, 0x7c, 0x1c, 0x70, 0xf0, 0xde, 0xe6, 0xc9, 0x34, + 0x92, 0xf4, 0xcb, 0xe3, 0xff, 0x04, 0x64, 0xd5, 0x52, 0xbf, 0x52, 0xaf, 0xe1, 0xea, 0xeb, 0x67, + 0xaa, 0x8c, 0x59, 0x75, 0x49, 0x22, 0xb8, 0xad, 0xe4, 0xec, 0xbf, 0xc1, 0x35, 0xdf, 0xed, 0xb1, + 0xaf, 0x27, 0x5e, 0x08, 0xef, 0x49, 0xee, 0x7d, 0x5f, 0xe8, 0xa4, 0x5c, 0x9c, 0x5c, 0xf8, 0x7c, + 0x36, 0x3b, 0x0f, 0x87, 0xc7, 0x63, 0xb1, 0x72, 0xcd, 0x99, 0xb3, 0xce, 0x57, 0xfb, 0x6d, 0xb6, + 0xd9, 0x38, 0x21, 0x10, 0xee, 0xaa, 0x9d, 0x78, 0x25, 0xaa, 0xea, 0xbc, 0x7f, 0x12, 0x0a, 0x2d, + 0x35, 0xb4, 0xd6, 0xff, 0x57, 0x3e, 0x08, 0xab, 0x7b, 0x9f, 0x04, 0x3d, 0xdd, 0xfe, 0x08, 0x6d, + 0x35, 0x58, 0xbe, 0x8a, 0x99, 0xfa, 0xd7, 0xcf, 0x01, 0x95, 0xb6, 0xdb, 0x6f, 0xc9, 0xc6, 0x4d, + 0xe6, 0xf3, 0x79, 0xbc, 0xfe, 0x7f, 0x93, 0xc9, 0xd7, 0x04, 0xc4, 0x4d, 0x34, 0xd3, 0x4d, 0x34, + 0xd3, 0xff, 0xc1, 0x57, 0x69, 0xa7, 0x7d, 0xa6, 0xad, 0x37, 0xc1, 0x24, 0xfd, 0x5d, 0x4f, 0xfe, + 0x14, 0xdd, 0xdc, 0xd5, 0x67, 0x36, 0xdd, 0xbb, 0x66, 0x63, 0xa6, 0x0f, 0x0d, 0x88, 0x63, 0x6a, + 0xd2, 0xf9, 0xbd, 0x7e, 0x09, 0x46, 0xe4, 0xc2, 0x66, 0x5c, 0x2e, 0x1e, 0xbe, 0x0b, 0xb3, 0xd3, + 0x35, 0x3d, 0x7c, 0x5c, 0xb8, 0x5c, 0x26, 0x33, 0x0b, 0x85, 0xc6, 0xe3, 0x73, 0xc5, 0xdf, 0xae, + 0xaa, 0x4e, 0x2f, 0x97, 0x0b, 0x99, 0x70, 0xb9, 0xe6, 0x9f, 0x27, 0xc3, 0xe2, 0xe3, 0xf3, 0xe6, + 0x7c, 0xf2, 0x52, 0x97, 0x9a, 0xb2, 0xe1, 0x73, 0xc2, 0xf6, 0xf6, 0xd8, 0x73, 0xf6, 0xf2, 0xdf, + 0xe2, 0xbf, 0x08, 0xf2, 0x90, 0x4a, 0x41, 0x2d, 0x96, 0xf6, 0xdb, 0x6f, 0x85, 0x14, 0x01, 0x5e, + 0xad, 0x37, 0xe7, 0xe9, 0xa7, 0xff, 0xe0, 0xb6, 0x5c, 0x2e, 0x1e, 0xea, 0x3e, 0x72, 0x2d, 0xe2, + 0x41, 0x55, 0x2b, 0x4d, 0x2e, 0xaf, 0x97, 0x79, 0x97, 0x85, 0x26, 0x20, 0x98, 0x83, 0x7b, 0x71, + 0xba, 0x2b, 0xac, 0x94, 0x47, 0xf2, 0x50, 0x94, 0xa2, 0xef, 0x82, 0x9d, 0xd9, 0xb1, 0xd8, 0xee, + 0xec, 0x76, 0x65, 0xc2, 0xe3, 0x30, 0xf3, 0x20, 0x6d, 0x11, 0xaf, 0xdf, 0x5d, 0xf9, 0x50, 0x6b, + 0x55, 0xef, 0x7f, 0x82, 0xe9, 0x7f, 0x17, 0x17, 0x17, 0x5f, 0x1f, 0x45, 0xf1, 0xf0, 0x59, 0x3d, + 0xf2, 0xe7, 0xe7, 0xc2, 0xae, 0xb1, 0x15, 0xd6, 0x2f, 0xa9, 0x93, 0xeb, 0xca, 0xbd, 0x7b, 0xe0, + 0x8c, 0x8e, 0xfb, 0xfc, 0x10, 0xd5, 0x78, 0xbe, 0x0a, 0x2e, 0xfb, 0xbe, 0x54, 0xf8, 0x62, 0xab, + 0xaa, 0xf1, 0xbf, 0x97, 0x4b, 0xbe, 0x09, 0x39, 0x71, 0xca, 0x9c, 0x44, 0x74, 0xd4, 0x67, 0xdd, + 0xae, 0xef, 0xe1, 0x7a, 0xc6, 0xfc, 0xda, 0x4e, 0xb4, 0xab, 0xe9, 0x1a, 0xd9, 0xbe, 0x2f, 0xa9, + 0x33, 0x1c, 0xf2, 0xcf, 0x79, 0xbb, 0x4d, 0x7a, 0x9d, 0x48, 0x8e, 0x89, 0xd5, 0xd6, 0x2b, 0xeb, + 0x51, 0xfd, 0x7b, 0xe0, 0x8e, 0xf7, 0xff, 0xe5, 0xd4, 0x5e, 0xbb, 0xee, 0xfe, 0x09, 0x0f, 0x8b, + 0xd2, 0x82, 0xe8, 0x91, 0x82, 0xea, 0xff, 0x57, 0x1e, 0x09, 0x4a, 0xab, 0xaa, 0xe7, 0x4b, 0xe8, + 0xcf, 0xf5, 0xa9, 0x3a, 0x3e, 0x57, 0xd1, 0x9d, 0x0f, 0xf4, 0x4e, 0x8b, 0xea, 0xff, 0x5e, 0xfa, + 0x2b, 0x4b, 0xd1, 0x9e, 0xba, 0xbf, 0xd5, 0xe4, 0xe8, 0xad, 0x00, 0x5a, 0xb0, 0xcc, 0x14, 0x07, + 0xa2, 0xf0, 0xad, 0x55, 0x23, 0xbc, 0x98, 0x54, 0x03, 0x36, 0x1b, 0x50, 0x06, 0xd4, 0x68, 0xf5, + 0x8f, 0x57, 0xfd, 0x3e, 0x2d, 0xe2, 0xdc, 0x46, 0x3f, 0x6d, 0x7c, 0x1a, 0xc1, 0x48, 0x20, 0x1b, + 0x15, 0x45, 0xa8, 0x50, 0x31, 0x20, 0x1a, 0x78, 0x5a, 0xb8, 0xb9, 0x7e, 0x59, 0xa6, 0xb5, 0x16, + 0xff, 0xe0, 0x84, 0x10, 0x0f, 0xbb, 0xe2, 0xb7, 0x7a, 0xac, 0x99, 0x89, 0x04, 0x04, 0x89, 0xd0, + 0x5f, 0xc1, 0x08, 0x40, 0x75, 0x55, 0x2a, 0xaa, 0xab, 0xdd, 0xc1, 0x98, 0x72, 0x34, 0x01, 0x4e, + 0x69, 0x54, 0xd6, 0xaf, 0x93, 0xbf, 0x6c, 0x9d, 0xbd, 0xdd, 0xfc, 0xeb, 0x29, 0xa7, 0xfe, 0x11, + 0x89, 0x11, 0x91, 0x85, 0x3b, 0xf9, 0x7c, 0x44, 0x85, 0x53, 0x62, 0x6c, 0xcc, 0x40, 0x80, 0x59, + 0x8a, 0x3b, 0x8e, 0xe1, 0xbb, 0x35, 0x6d, 0x90, 0x83, 0x5c, 0x48, 0x60, 0x79, 0x0f, 0x09, 0x6d, + 0xdd, 0xda, 0x7a, 0xd7, 0xc3, 0x65, 0xc1, 0x9f, 0x3c, 0x06, 0xb8, 0x1d, 0x6b, 0xbf, 0x06, 0x58, + 0x21, 0x0e, 0xcc, 0xa3, 0xc6, 0x94, 0x78, 0x2c, 0xd6, 0xb5, 0x03, 0x33, 0x60, 0xc5, 0x77, 0xff, + 0x04, 0xd5, 0xd5, 0xb1, 0x07, 0x9b, 0x93, 0x01, 0x52, 0x8b, 0x89, 0xf8, 0x9e, 0x24, 0x20, 0x08, + 0x88, 0x2e, 0xaa, 0x98, 0xa4, 0x71, 0x22, 0x0a, 0x5c, 0x56, 0xa1, 0xbe, 0x6b, 0xbe, 0x17, 0x88, + 0x0c, 0x85, 0x4a, 0x7e, 0xce, 0x7f, 0x22, 0x47, 0x8b, 0xe2, 0x7c, 0x1e, 0x3a, 0xd8, 0x75, 0x4a, + 0x58, 0xa3, 0xf1, 0x35, 0xc3, 0xe0, 0x84, 0xeb, 0xab, 0x7c, 0x82, 0x18, 0xde, 0x2b, 0xe2, 0x07, + 0xeb, 0x52, 0xfb, 0x58, 0x6a, 0xa5, 0xa3, 0x39, 0xb9, 0x8b, 0x55, 0x5c, 0x20, 0x18, 0x0a, 0x45, + 0x31, 0x43, 0x14, 0x0c, 0x50, 0x0c, 0x47, 0xa9, 0xde, 0x59, 0x89, 0x0f, 0x38, 0xe4, 0x4a, 0x5a, + 0x22, 0x1a, 0x52, 0x57, 0xb1, 0xae, 0xe2, 0x42, 0x03, 0x75, 0x8b, 0xac, 0x53, 0x97, 0xea, 0x28, + 0x61, 0xa8, 0xc0, 0xfc, 0x4a, 0x5c, 0x2c, 0x10, 0x52, 0xb8, 0xdc, 0xb5, 0x72, 0xff, 0xc3, 0x17, + 0x64, 0x74, 0x02, 0xa0, 0x35, 0x01, 0x7b, 0x2a, 0x08, 0x9e, 0x0e, 0x0c, 0x32, 0x83, 0x82, 0xc9, + 0xc7, 0x83, 0xd0, 0x79, 0xef, 0xf9, 0x78, 0xc0, 0x63, 0x0c, 0x59, 0x5f, 0x02, 0x88, 0x8a, 0x80, + 0x4b, 0xc4, 0x82, 0x0d, 0x55, 0x4d, 0xd5, 0x4d, 0xf1, 0x75, 0x1a, 0xe9, 0xe9, 0x57, 0xfe, 0x27, + 0xc4, 0xfc, 0x41, 0x15, 0x7b, 0xbb, 0xe2, 0x6f, 0x9f, 0xa9, 0x39, 0x84, 0xc4, 0xfa, 0x96, 0x7c, + 0x10, 0x06, 0x06, 0x09, 0x60, 0x10, 0x2f, 0x68, 0x48, 0x3a, 0x73, 0xaa, 0xca, 0x0d, 0xc6, 0xfb, + 0xfc, 0x44, 0x45, 0x22, 0xdb, 0xbd, 0xdf, 0x89, 0x08, 0x71, 0x20, 0x80, 0x45, 0x75, 0x59, 0x95, + 0x5e, 0x0c, 0x06, 0x14, 0xbd, 0xd4, 0x59, 0x35, 0x02, 0xf6, 0x89, 0xc6, 0xbd, 0x8f, 0xb2, 0xa4, + 0xc1, 0x03, 0x97, 0x89, 0x07, 0x03, 0xf5, 0x0f, 0x2c, 0x96, 0xae, 0xc5, 0x2c, 0x31, 0x4e, 0xaa, + 0xb8, 0x90, 0x28, 0x05, 0x39, 0xd0, 0x8b, 0x9f, 0x1b, 0x67, 0xcb, 0x31, 0x4c, 0x98, 0x77, 0x37, + 0x11, 0xf5, 0x0d, 0x07, 0x41, 0x3c, 0x44, 0x12, 0x96, 0xa4, 0xfc, 0x23, 0x9f, 0x58, 0x5e, 0xf1, + 0x2c, 0xd3, 0x49, 0x78, 0x92, 0x9d, 0x0e, 0xee, 0xb8, 0xb2, 0x26, 0xf7, 0x5d, 0xc9, 0x84, 0x02, + 0x84, 0x55, 0x17, 0x55, 0x14, 0xc4, 0xfe, 0xab, 0xef, 0x76, 0x7c, 0xd5, 0xaf, 0xd8, 0x97, 0x6a, + 0xb8, 0x8f, 0x12, 0x23, 0x89, 0x10, 0x13, 0xbb, 0xbb, 0xea, 0xbc, 0x20, 0x32, 0x16, 0x0d, 0x44, + 0x96, 0x37, 0x14, 0xee, 0xef, 0x77, 0x7f, 0x13, 0x19, 0xba, 0x6f, 0x8b, 0xbc, 0xaa, 0x0b, 0x77, + 0x15, 0xc5, 0x6f, 0x0f, 0x60, 0x01, 0x92, 0x46, 0x62, 0x99, 0xb3, 0xf8, 0x3d, 0x55, 0x18, 0x9f, + 0x9f, 0xbe, 0xce, 0x1a, 0xb8, 0x96, 0xb3, 0x9a, 0x03, 0x45, 0x18, 0x01, 0x46, 0x41, 0xa2, 0x5d, + 0xaa, 0xe2, 0xa0, 0xee, 0xff, 0x2f, 0x1d, 0x59, 0x04, 0xdc, 0x21, 0x75, 0x76, 0xed, 0xa7, 0x43, + 0x17, 0x71, 0x3e, 0xb0, 0x88, 0x46, 0xe7, 0x53, 0xa8, 0x8f, 0x37, 0x1e, 0xbb, 0xcb, 0x62, 0xbe, + 0x24, 0x66, 0x2b, 0xba, 0xba, 0x97, 0xcf, 0x0a, 0x65, 0xf6, 0x66, 0x2d, 0xe2, 0x01, 0x61, 0x38, + 0x9f, 0x77, 0xbc, 0x3b, 0x54, 0x5c, 0xf2, 0xf8, 0x4a, 0xe2, 0xb7, 0x15, 0x97, 0xaa, 0xf8, 0x90, + 0x42, 0x2c, 0x4b, 0xef, 0xcb, 0xf0, 0x80, 0x44, 0x3f, 0xd5, 0x6a, 0xfc, 0xd8, 0x38, 0x20, 0x42, + 0xb7, 0x78, 0x3b, 0xff, 0xe1, 0x11, 0xb5, 0x55, 0x17, 0x14, 0xc5, 0x31, 0x4c, 0x53, 0x55, 0x80, + 0xdc, 0x73, 0x21, 0xf6, 0x3d, 0xea, 0x5c, 0x23, 0x62, 0xad, 0x1f, 0x12, 0xc9, 0x3f, 0x10, 0x24, + 0x6e, 0xaa, 0x2e, 0xaa, 0xaa, 0x38, 0x76, 0x0e, 0x6c, 0x4f, 0x19, 0x35, 0x71, 0x7b, 0x2e, 0x04, + 0xf4, 0xe5, 0x55, 0x2c, 0x9a, 0x68, 0xfe, 0x24, 0x6f, 0x55, 0x51, 0x72, 0xe4, 0x43, 0x8a, 0x7b, + 0x08, 0x9b, 0xde, 0xce, 0x5b, 0x12, 0xf9, 0x7c, 0x55, 0xfe, 0x10, 0x10, 0x36, 0x4e, 0xfc, 0x66, + 0x45, 0x6a, 0x94, 0x40, 0xf5, 0x6f, 0x12, 0xea, 0xec, 0xc5, 0x9b, 0x98, 0xd8, 0x02, 0xba, 0x2a, + 0xe4, 0xd2, 0x67, 0xe1, 0x10, 0x80, 0xc9, 0x7d, 0xf2, 0xa8, 0xdd, 0xf9, 0x6b, 0x16, 0xe2, 0x01, + 0xe1, 0x45, 0x08, 0x98, 0x05, 0x61, 0xc4, 0x40, 0x02, 0x8b, 0x05, 0xc4, 0xdb, 0xfd, 0x53, 0xf9, + 0x56, 0x27, 0xc7, 0xbe, 0x4c, 0xe2, 0xb2, 0xd8, 0xea, 0xbb, 0x35, 0xcb, 0xd3, 0xca, 0x1f, 0x77, + 0x9a, 0x1f, 0xe1, 0x69, 0x50, 0x20, 0x22, 0x93, 0x54, 0xa0, 0x10, 0x22, 0xb3, 0x94, 0x89, 0x77, + 0xf8, 0x00, 0x51, 0x7c, 0xfc, 0x13, 0x44, 0x41, 0x10, 0x99, 0xf2, 0xdf, 0x78, 0x90, 0x80, 0xa5, + 0x55, 0x55, 0x6d, 0x5b, 0x4d, 0xd5, 0xf1, 0x00, 0x80, 0x13, 0x47, 0x55, 0x5a, 0x0f, 0xaa, 0xab, + 0x78, 0x81, 0x17, 0x2e, 0x3d, 0xb3, 0xec, 0xf7, 0xc6, 0xe5, 0x61, 0xed, 0xaa, 0x36, 0xe3, 0xf0, + 0x02, 0xd9, 0x6d, 0xdd, 0xcf, 0xce, 0x71, 0x4b, 0x48, 0xfa, 0x5f, 0xfe, 0x5d, 0x4b, 0x8d, 0xce, + 0x24, 0x14, 0x17, 0x9b, 0x29, 0x1b, 0x28, 0xb1, 0xfc, 0xf5, 0x35, 0x21, 0x91, 0x1f, 0xfc, 0x22, + 0x0b, 0x4b, 0x74, 0xf3, 0xf7, 0xb7, 0x15, 0x60, 0xc4, 0x11, 0x6b, 0x19, 0x50, 0x6e, 0x3c, 0x09, + 0x21, 0x5a, 0xf9, 0x37, 0x1e, 0x1f, 0x83, 0x67, 0xc1, 0x10, 0x68, 0x74, 0x48, 0xe9, 0xa8, 0x00, + 0x33, 0x0d, 0x7f, 0x0d, 0x92, 0x01, 0x16, 0xe1, 0xed, 0x8a, 0xf9, 0x4a, 0xd6, 0xf9, 0x6d, 0xc4, + 0xac, 0x59, 0x29, 0xe0, 0x76, 0x4f, 0x58, 0xad, 0x6d, 0xcf, 0xeb, 0x0e, 0x23, 0xff, 0x0e, 0x10, + 0x80, 0x03, 0x38, 0x0d, 0xd5, 0x3d, 0x1c, 0x42, 0x00, 0xfc, 0xff, 0x3d, 0xe7, 0x9f, 0xdb, 0x3f, + 0x3c, 0x1e, 0x78, 0x79, 0x60, 0x32, 0xc3, 0xbd, 0xd4, 0x55, 0x98, 0xf4, 0x5f, 0xf7, 0x12, 0x3f, + 0x71, 0xd0 +}; +#endif \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source_modules/sample_jpeg.h b/USDK/component/common/media/framework/mmf_source_modules/sample_jpeg.h new file mode 100644 index 0000000..e7ea6c9 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/sample_jpeg.h @@ -0,0 +1,1429 @@ +#ifndef _SAMPLE_JPEG_H_ +#define _SAMPLE_JPEG_H_ + +#include "section_config.h" +SDRAM_DATA_SECTION static const unsigned char PIC_320x240_1[] = { +0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x0a, 0x06, 0x06, 0x04, 0x04, 0x06, 0x0c, 0x08, 0x08, 0x06, +0x0a, 0x0e, 0x0c, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, 0x0c, 0x10, 0x12, 0x16, 0x12, 0x10, 0x10, 0x14, +0x10, 0x0c, 0x0e, 0x14, 0x1a, 0x14, 0x14, 0x16, 0x18, 0x18, 0x1a, 0x18, 0x0e, 0x12, 0x1c, 0x1e, +0x1c, 0x18, 0x1e, 0x16, 0x18, 0x18, 0x18, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x04, 0x04, 0x04, 0x06, +0x04, 0x06, 0x0a, 0x06, 0x06, 0x0a, 0x18, 0x10, 0x0e, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xc0, 0x00, 0x11, +0x08, 0x00, 0xf0, 0x01, 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, +0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, +0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, +0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, +0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, +0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, +0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, +0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, +0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, +0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, +0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, +0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, +0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, +0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, +0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, +0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, +0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, +0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, +0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, +0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, +0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, +0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, +0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, +0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, +0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, +0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xcd, 0x0b, 0xdf, +0xbf, 0x4a, 0x76, 0x3f, 0x3a, 0xe6, 0xb9, 0xe9, 0x3d, 0x47, 0x6c, 0x39, 0xc6, 0x4f, 0x3e, 0xb4, +0xe0, 0x9d, 0x7b, 0x7f, 0x5a, 0xab, 0x5d, 0x6a, 0x43, 0x64, 0xa2, 0x3e, 0xff, 0x00, 0xa9, 0xa9, +0x44, 0x5c, 0x53, 0xb5, 0xc9, 0x6c, 0x53, 0x6f, 0x93, 0xb9, 0x78, 0x3d, 0x33, 0xeb, 0x4f, 0x48, +0xc1, 0xc8, 0xc6, 0x18, 0x75, 0x15, 0x6d, 0x19, 0x39, 0x0a, 0x61, 0xeb, 0xc7, 0x4a, 0x8d, 0xa2, +0x1c, 0x9f, 0xcc, 0xd0, 0xd1, 0x3c, 0xdd, 0x4a, 0x2d, 0x17, 0x98, 0x4f, 0xfc, 0xf3, 0x53, 0xf9, +0xd3, 0x99, 0x3d, 0x8d, 0x44, 0x90, 0xe3, 0x22, 0x26, 0x41, 0xe9, 0x50, 0xb2, 0xd2, 0x7e, 0x43, +0xbe, 0xa4, 0x2d, 0x1e, 0x7a, 0xf0, 0xc3, 0xa1, 0xf4, 0xa6, 0x03, 0x92, 0x55, 0x86, 0xd6, 0x1f, +0xad, 0x1a, 0xb4, 0x26, 0xf5, 0x1c, 0x7f, 0x0f, 0xf0, 0xa4, 0xce, 0x79, 0xfc, 0xc9, 0xa5, 0xe4, +0x3e, 0x62, 0x29, 0x18, 0x01, 0xea, 0xc7, 0x80, 0x3d, 0xe9, 0x80, 0x6d, 0x07, 0x9c, 0xb1, 0xe4, +0x9a, 0x18, 0xaf, 0x71, 0x8c, 0x7f, 0x1c, 0xd5, 0x39, 0x06, 0xd2, 0x58, 0x67, 0x69, 0xea, 0x29, +0x58, 0x2e, 0x46, 0x79, 0xe7, 0xf5, 0xa8, 0x1b, 0xb9, 0xf5, 0xa7, 0xb6, 0xa0, 0xf5, 0x2b, 0xb0, +0xeb, 0x54, 0xa5, 0x1e, 0x63, 0x84, 0x03, 0xe5, 0x1c, 0xb7, 0xf8, 0x52, 0x7a, 0x82, 0xdc, 0x8e, +0x45, 0x23, 0xe6, 0x19, 0xdc, 0x3f, 0x5a, 0x8b, 0x01, 0x86, 0x7d, 0x7d, 0x7b, 0x51, 0xab, 0x1a, +0xd3, 0x72, 0xbc, 0xca, 0x76, 0x3e, 0xdc, 0x16, 0x2a, 0x70, 0x7d, 0x38, 0xaf, 0x29, 0xbe, 0xc9, +0x76, 0x2c, 0x7e, 0x62, 0x72, 0xd9, 0xef, 0x5a, 0xd2, 0x25, 0xf6, 0x46, 0x5e, 0x39, 0xf5, 0xaf, +0x5a, 0xf0, 0x15, 0xd4, 0x4c, 0x92, 0xda, 0x38, 0x3b, 0xce, 0x08, 0x3e, 0x95, 0x55, 0x55, 0xe3, +0x60, 0x83, 0xb4, 0x93, 0x3d, 0x56, 0x65, 0x8a, 0xde, 0x1e, 0x00, 0xdc, 0x47, 0x27, 0xd6, 0xb8, +0x99, 0x75, 0x43, 0x1d, 0xcf, 0x98, 0x18, 0x87, 0x53, 0xc1, 0x15, 0xc4, 0xd7, 0x2e, 0xc7, 0x7c, +0x65, 0xcc, 0xee, 0x73, 0xfe, 0x34, 0x61, 0x77, 0xf6, 0x0d, 0x72, 0x06, 0x0d, 0x71, 0x01, 0x02, +0x42, 0x39, 0xe9, 0x82, 0x0f, 0xe9, 0x5d, 0x7d, 0x94, 0x76, 0xf7, 0xfa, 0x6d, 0xbd, 0xfd, 0xb8, +0xc3, 0x5c, 0x42, 0x19, 0x80, 0xec, 0x7a, 0x11, 0xf9, 0xd5, 0xd4, 0xfe, 0x1a, 0x6b, 0xb9, 0x14, +0x65, 0xcb, 0x55, 0xa7, 0xd8, 0x8d, 0x21, 0x44, 0xb5, 0x72, 0x06, 0x6b, 0x91, 0xbf, 0x38, 0x66, +0xc7, 0xe6, 0x7b, 0xd7, 0x1e, 0xcc, 0xf4, 0xa0, 0xee, 0x62, 0xf5, 0x27, 0x24, 0xd0, 0x54, 0x70, +0x7a, 0xd6, 0x92, 0x65, 0x36, 0xb6, 0x3e, 0x8c, 0xdb, 0xff, 0x00, 0xd7, 0x34, 0xe0, 0xbf, 0xad, +0x77, 0x2b, 0x9e, 0x43, 0x68, 0x78, 0x4f, 0xff, 0x00, 0x5f, 0xad, 0x4a, 0xa9, 0xec, 0x79, 0xa6, +0x43, 0xd4, 0x9c, 0x25, 0x4e, 0xb1, 0xe6, 0xa9, 0x2b, 0x99, 0xb6, 0x91, 0x60, 0x45, 0x9e, 0xdf, +0x8d, 0x38, 0xdb, 0x6e, 0xc1, 0xc7, 0xcc, 0x3a, 0x1a, 0xd1, 0x45, 0xee, 0x64, 0xe4, 0x02, 0x16, +0x3f, 0x2b, 0x0c, 0x37, 0xf3, 0xaa, 0xf2, 0xc0, 0x5c, 0x95, 0xc6, 0x17, 0xb9, 0xf5, 0xa6, 0xd5, +0x88, 0x72, 0xb9, 0x5d, 0xe1, 0xdb, 0xc0, 0x18, 0xc5, 0x55, 0x74, 0x39, 0xac, 0xe4, 0x8a, 0x52, +0x2b, 0xba, 0xfe, 0x35, 0x0b, 0x2f, 0x53, 0x50, 0xd1, 0xa2, 0x91, 0x0b, 0x29, 0xe6, 0xa1, 0x74, +0x0c, 0x39, 0xea, 0x39, 0x0c, 0x3b, 0x52, 0xb8, 0x3d, 0x48, 0x77, 0x10, 0x76, 0xb7, 0x0d, 0xfc, +0xe9, 0x58, 0xe0, 0x12, 0x78, 0xf5, 0xa0, 0x2e, 0xc8, 0x17, 0x2c, 0x4c, 0x8d, 0xdf, 0xa7, 0xb0, +0xa5, 0x63, 0x53, 0xa8, 0x5c, 0x89, 0xaa, 0x16, 0xa7, 0xd4, 0x45, 0x37, 0x05, 0x09, 0x23, 0x95, +0x3d, 0x47, 0xa7, 0xbd, 0x35, 0xb9, 0x19, 0xeb, 0x9e, 0x73, 0x45, 0x87, 0x72, 0xb4, 0xad, 0xb5, +0x49, 0x23, 0x9e, 0xc3, 0xd6, 0xab, 0x84, 0x2a, 0x39, 0xc1, 0x66, 0x39, 0x27, 0xd4, 0xd1, 0x7d, +0x44, 0xb6, 0xd4, 0x63, 0x2e, 0x72, 0x7b, 0xd5, 0x59, 0x14, 0x82, 0x59, 0x7a, 0xf7, 0x1e, 0xb4, +0x93, 0x6f, 0x71, 0xb6, 0x44, 0xc4, 0x6d, 0xc8, 0xe7, 0x3c, 0x9a, 0xf3, 0x2d, 0x66, 0x17, 0xfb, +0x54, 0xa7, 0x69, 0x03, 0x39, 0xe6, 0xb5, 0x86, 0x8d, 0x8a, 0x4f, 0x63, 0x00, 0xe4, 0x31, 0xae, +0x93, 0xc3, 0xb7, 0xcd, 0x65, 0x74, 0x24, 0x56, 0xc1, 0x23, 0xb7, 0x7a, 0xd2, 0x5a, 0x89, 0x3b, +0x9e, 0x9d, 0x2f, 0x88, 0xa3, 0x96, 0xd8, 0x87, 0x65, 0xdf, 0x8e, 0x31, 0xda, 0xbc, 0xea, 0xfb, +0x53, 0x63, 0x2b, 0x38, 0x3f, 0x31, 0x35, 0xce, 0xa0, 0xa4, 0xcd, 0x54, 0xdc, 0x76, 0x19, 0x06, +0xaf, 0xe6, 0xc3, 0x2d, 0xb4, 0xe4, 0x14, 0x99, 0x70, 0x41, 0xf5, 0xf5, 0xae, 0x8f, 0xc2, 0x3a, +0xe0, 0xb5, 0x86, 0xeb, 0x4d, 0x99, 0xd7, 0x6c, 0x64, 0xbc, 0x65, 0x8f, 0x63, 0xd4, 0x7e, 0x67, +0xf5, 0xa4, 0xe0, 0xf9, 0x65, 0x12, 0xd5, 0x5f, 0x7e, 0x33, 0x66, 0x8d, 0x9e, 0xbf, 0x6d, 0x1b, +0x5c, 0xc1, 0x3c, 0xa0, 0x64, 0xfc, 0xa4, 0xf3, 0x58, 0x3a, 0x8e, 0xa9, 0x6c, 0xd2, 0x36, 0xc7, +0xde, 0x33, 0xc5, 0x72, 0xaa, 0x72, 0x5d, 0x0f, 0x42, 0x38, 0x88, 0xa6, 0xdb, 0x2b, 0xc2, 0x5a, +0x71, 0xb9, 0x54, 0xfb, 0x55, 0xf5, 0x89, 0xb8, 0xcf, 0x07, 0x1c, 0x52, 0x9f, 0xbb, 0xa1, 0xac, +0x3d, 0xf5, 0x73, 0xe8, 0x4c, 0x73, 0xcd, 0x3c, 0x0e, 0xfe, 0x95, 0xdc, 0x79, 0x97, 0x25, 0x0a, +0x4e, 0x33, 0x53, 0xa2, 0x66, 0xab, 0x73, 0x37, 0xa1, 0x61, 0x63, 0xcd, 0x5b, 0x48, 0xba, 0x75, +0xad, 0x22, 0xae, 0x63, 0x26, 0x5d, 0x8e, 0x1c, 0x9e, 0x9f, 0xa5, 0x68, 0x43, 0x66, 0x5c, 0x8e, +0x3f, 0x4a, 0xdd, 0x44, 0xe6, 0x9c, 0xec, 0x75, 0xba, 0x37, 0x82, 0xae, 0xf5, 0xb6, 0xdb, 0x18, +0x58, 0xd1, 0x46, 0x5a, 0x69, 0x41, 0xda, 0xb5, 0x57, 0x5a, 0xf0, 0x6d, 0xf6, 0x92, 0x59, 0x26, +0x84, 0x94, 0x1d, 0x27, 0x45, 0x25, 0x5f, 0xf1, 0xa7, 0x65, 0x7e, 0x53, 0x9d, 0xd4, 0x76, 0xe6, +0xe8, 0x70, 0xb7, 0x36, 0x8c, 0x84, 0x82, 0x31, 0x8f, 0x51, 0x59, 0x12, 0xc5, 0x83, 0xd3, 0xf4, +0xac, 0x64, 0x8e, 0x98, 0xca, 0xe5, 0x17, 0x5a, 0xac, 0xeb, 0xff, 0x00, 0xd7, 0x35, 0x93, 0xd7, +0x43, 0x64, 0xc8, 0x58, 0x54, 0x2c, 0x06, 0x7f, 0x0a, 0xcd, 0xa2, 0xba, 0x15, 0xe4, 0x40, 0xc3, +0x0d, 0xf5, 0x07, 0xd2, 0xaa, 0x65, 0x9d, 0xb6, 0x33, 0x02, 0x07, 0x56, 0xfe, 0xf5, 0x00, 0x89, +0x9a, 0xa2, 0x6e, 0x68, 0x68, 0x08, 0xdb, 0xf5, 0xa8, 0x58, 0xf3, 0x49, 0xea, 0x17, 0x21, 0x6e, +0x73, 0xd7, 0xf3, 0xaa, 0xad, 0xfb, 0xb2, 0x4f, 0x55, 0x27, 0x90, 0x4f, 0xdd, 0xa3, 0x71, 0x3d, +0x08, 0x0f, 0xef, 0x1b, 0x3f, 0xc2, 0xa3, 0x8f, 0x7a, 0x6b, 0x73, 0x9a, 0x6f, 0x61, 0xde, 0xe5, +0x77, 0xee, 0x49, 0xe9, 0xde, 0xa1, 0x6e, 0x79, 0xea, 0x68, 0xf5, 0x1d, 0xfa, 0x15, 0x9d, 0x4a, +0x92, 0xc0, 0x70, 0x7e, 0xf0, 0xf5, 0xf7, 0xac, 0x5d, 0x52, 0xc1, 0x6f, 0x23, 0x0f, 0x11, 0x02, +0x4e, 0x83, 0xfd, 0xaf, 0x6a, 0x77, 0x7b, 0x89, 0xeb, 0xa1, 0xe7, 0xf7, 0xfa, 0x7d, 0xc5, 0xab, +0x9f, 0x36, 0x36, 0x18, 0xef, 0x8a, 0x75, 0xa4, 0x64, 0x90, 0xca, 0x48, 0xc7, 0x3c, 0xd6, 0xcd, +0xdd, 0x5c, 0x9e, 0xa5, 0xd9, 0xa7, 0x71, 0x90, 0xaf, 0x9e, 0x3b, 0x1a, 0xc6, 0x9a, 0x42, 0x49, +0xce, 0x73, 0x49, 0x2d, 0x6e, 0x53, 0x95, 0xca, 0xa4, 0x90, 0x72, 0x09, 0xc9, 0xab, 0x31, 0xc8, +0xe9, 0xba, 0x60, 0xc4, 0x32, 0x8d, 0xac, 0x01, 0xc1, 0x20, 0xf7, 0xfc, 0xea, 0x85, 0x7d, 0x0a, +0xbf, 0x68, 0x7c, 0xe4, 0x93, 0x93, 0xd7, 0x26, 0xb7, 0xb4, 0x98, 0x56, 0xea, 0x6d, 0xf3, 0x90, +0xa8, 0x3a, 0x06, 0xfe, 0x2a, 0xc6, 0x76, 0x51, 0xb9, 0xbd, 0x3f, 0x7a, 0x69, 0x1e, 0x86, 0x96, +0xa1, 0x2d, 0xd6, 0x48, 0xa2, 0x2c, 0xbd, 0xb0, 0x29, 0xf6, 0x3a, 0x46, 0xa1, 0xa9, 0x4f, 0x84, +0x85, 0xe1, 0x80, 0x7c, 0xd2, 0x5d, 0x4a, 0x36, 0xc7, 0x1a, 0xfa, 0x93, 0x5c, 0x30, 0x8b, 0x93, +0x3d, 0x49, 0x55, 0x8d, 0x38, 0xf3, 0x1e, 0xd2, 0x8d, 0x93, 0x86, 0xc8, 0x61, 0xd4, 0x55, 0x95, +0x1d, 0x7e, 0xbd, 0x6b, 0xbb, 0x73, 0xcd, 0x26, 0x55, 0xcf, 0x35, 0x69, 0x13, 0x15, 0x69, 0x19, +0xb7, 0xd4, 0xb9, 0x1c, 0x64, 0xf5, 0xad, 0x08, 0xa1, 0xce, 0x38, 0xeb, 0x5b, 0x41, 0x1c, 0xf3, +0x91, 0xaf, 0x6f, 0x6a, 0x49, 0x18, 0x1d, 0x6b, 0xbf, 0xf0, 0xef, 0x87, 0x25, 0xd4, 0x26, 0x41, +0xb7, 0x11, 0xa9, 0x05, 0xdc, 0xf4, 0x02, 0xb7, 0x49, 0x25, 0x76, 0x71, 0x55, 0x9b, 0x7a, 0x23, +0xdb, 0x2c, 0xac, 0xa0, 0xb0, 0x81, 0x2d, 0xed, 0xd0, 0x22, 0x2f, 0x53, 0xdd, 0x8f, 0xad, 0x3a, +0xee, 0xd6, 0x0b, 0xd8, 0x24, 0xb6, 0xb8, 0x41, 0x24, 0x72, 0x8c, 0x10, 0x7b, 0x7b, 0xd7, 0x2b, +0x93, 0x72, 0xe6, 0x3a, 0x63, 0x4d, 0x28, 0x72, 0x33, 0xc1, 0x7c, 0x53, 0xe1, 0x19, 0xec, 0x26, +0x92, 0x44, 0x8f, 0x7d, 0xb3, 0x92, 0x52, 0x55, 0xe7, 0x8f, 0x7f, 0x7a, 0xf2, 0xbb, 0xeb, 0x43, +0x1b, 0x30, 0x60, 0x41, 0x1c, 0x73, 0x5b, 0xce, 0xd2, 0x5c, 0xc8, 0xe4, 0xa5, 0x27, 0x16, 0xe1, +0x2d, 0xcc, 0x19, 0x50, 0x8e, 0x4d, 0x51, 0x61, 0x5c, 0xcc, 0xee, 0x4e, 0xe5, 0x77, 0x07, 0xdb, +0xeb, 0x50, 0x37, 0x7c, 0xf5, 0x35, 0x9b, 0x65, 0xa2, 0xac, 0xac, 0x7e, 0xea, 0xf2, 0xcd, 0xfa, +0x54, 0x46, 0x30, 0x17, 0x6f, 0xe3, 0x9e, 0xf4, 0x9f, 0x72, 0x88, 0xf7, 0x90, 0x76, 0xb9, 0xeb, +0xd0, 0xfa, 0xd2, 0x1a, 0x1a, 0xd4, 0x2f, 0x72, 0x26, 0xa8, 0xdb, 0xf5, 0xa3, 0x71, 0x6e, 0x44, +0xd9, 0xaa, 0x93, 0x31, 0xc6, 0xd1, 0x92, 0x5b, 0x8f, 0xa5, 0x21, 0x90, 0x11, 0xe5, 0xf4, 0xc9, +0x4f, 0x4f, 0x4a, 0x69, 0xf5, 0xea, 0x0d, 0x0f, 0x52, 0x51, 0x56, 0xe6, 0x23, 0x34, 0x52, 0x47, +0xb8, 0xa9, 0x75, 0xc6, 0x47, 0x6a, 0xa9, 0x6b, 0x6d, 0xf6, 0x58, 0x56, 0x22, 0xc5, 0xd8, 0x1c, +0x97, 0x27, 0x24, 0xd3, 0xe6, 0xba, 0xb0, 0xf7, 0x77, 0x24, 0x6e, 0x73, 0x9c, 0x56, 0x3b, 0xdc, +0xc6, 0xb7, 0x66, 0x3c, 0x9e, 0x06, 0x7d, 0xb3, 0xfe, 0x34, 0xe2, 0xae, 0x37, 0x2e, 0xe5, 0x2d, +0x6e, 0xdc, 0x5c, 0x5a, 0xb4, 0xea, 0x55, 0x99, 0x07, 0x20, 0x0e, 0xa2, 0xb8, 0x38, 0x1d, 0xd2, +0x62, 0xb9, 0xc6, 0x4e, 0x32, 0x47, 0x15, 0x70, 0x7c, 0xca, 0xc4, 0x3f, 0x23, 0x4a, 0xe6, 0xcd, +0xb0, 0x1c, 0xf9, 0x64, 0x30, 0xce, 0x51, 0xb3, 0x58, 0x72, 0xa8, 0x04, 0xf7, 0x1e, 0xb5, 0x43, +0x8b, 0xb9, 0x5f, 0x1d, 0xf1, 0x8a, 0x42, 0x71, 0x9e, 0x48, 0xcf, 0x5e, 0x69, 0x36, 0xef, 0x64, +0x5d, 0x95, 0x86, 0x2a, 0x19, 0x1d, 0x42, 0x82, 0x49, 0x38, 0xae, 0xba, 0x04, 0x8a, 0xca, 0x34, +0x59, 0x0e, 0x65, 0x61, 0xf7, 0x54, 0x73, 0x58, 0xd6, 0x6d, 0x2b, 0x1d, 0x98, 0x45, 0xcd, 0x2b, +0xb3, 0xab, 0xf0, 0xc7, 0x8a, 0xed, 0xf4, 0x8b, 0xff, 0x00, 0xf8, 0x9a, 0x5a, 0xcb, 0x75, 0x60, +0x41, 0x53, 0x17, 0x04, 0xa1, 0xf5, 0x19, 0xfa, 0x7e, 0xb5, 0xd3, 0x6a, 0x9e, 0x2b, 0xb6, 0xd7, +0xc5, 0xdd, 0xbe, 0x9f, 0x13, 0xd9, 0x58, 0xa1, 0x5f, 0x2e, 0x0c, 0x01, 0xb8, 0x13, 0xdf, 0x07, +0xe9, 0x59, 0xbd, 0x21, 0xa6, 0xe6, 0xae, 0x84, 0xa5, 0x5f, 0x99, 0xed, 0xd8, 0xf5, 0x76, 0x8c, +0x3f, 0x5e, 0xbd, 0x8f, 0xa5, 0x2a, 0x31, 0x43, 0xb6, 0x4f, 0xc1, 0xbb, 0x1a, 0xd9, 0x76, 0x39, +0x19, 0x75, 0x47, 0x35, 0x6d, 0x17, 0x9a, 0xb5, 0xab, 0x32, 0x93, 0x34, 0xa1, 0x8c, 0x9c, 0x7a, +0x7a, 0xd6, 0xcd, 0xbc, 0x05, 0x88, 0xfe, 0x82, 0xba, 0x62, 0x8e, 0x3a, 0x92, 0x47, 0x77, 0xa0, +0x68, 0x72, 0xdf, 0x4d, 0x1a, 0x2a, 0x9c, 0x67, 0x25, 0xb1, 0xc0, 0x15, 0xed, 0xd6, 0x16, 0x30, +0xd8, 0x5b, 0xa4, 0x11, 0x0e, 0x83, 0xe6, 0x6c, 0x72, 0xc6, 0x9d, 0x69, 0x59, 0x72, 0x98, 0x51, +0x5e, 0xd2, 0x7c, 0xdd, 0x8b, 0xb4, 0x57, 0x31, 0xda, 0x32, 0x48, 0xd2, 0x54, 0x68, 0xe4, 0x50, +0xe8, 0xe3, 0x05, 0x58, 0x64, 0x1a, 0xf9, 0xff, 0x00, 0xe2, 0x0f, 0x86, 0x46, 0x95, 0x22, 0xde, +0xc0, 0xac, 0xd6, 0x57, 0x0c, 0x40, 0x20, 0x71, 0x1b, 0x7f, 0x74, 0x9a, 0xd6, 0x94, 0xbe, 0xcb, +0xea, 0x73, 0x62, 0x21, 0xaa, 0x9a, 0xe8, 0x78, 0xc5, 0xc0, 0xe4, 0xf7, 0xf7, 0xcd, 0x65, 0x48, +0x39, 0xe7, 0xd6, 0xa6, 0x46, 0xb0, 0x7a, 0x5c, 0xa8, 0xfd, 0xff, 0x00, 0x9d, 0x57, 0x91, 0x82, +0x82, 0xc4, 0xf4, 0x1f, 0x9d, 0x63, 0x2d, 0x5e, 0x86, 0xaa, 0x45, 0x55, 0x07, 0x97, 0x61, 0xf3, +0x3f, 0x6f, 0x4a, 0x46, 0xef, 0xfc, 0xea, 0x47, 0xb9, 0x0b, 0x0d, 0xc0, 0x83, 0xd0, 0xd4, 0x1b, +0xb6, 0x1d, 0xae, 0x78, 0xe8, 0x24, 0x3d, 0xfd, 0xa9, 0xdf, 0x41, 0x3b, 0xa1, 0x18, 0xfb, 0xd4, +0x4d, 0x49, 0xea, 0x3b, 0xf6, 0x23, 0x63, 0xc1, 0x27, 0xf1, 0xcd, 0x55, 0x50, 0x58, 0xb3, 0x9e, +0xfd, 0x01, 0xf4, 0xa5, 0xd0, 0x1b, 0x1a, 0xdc, 0x93, 0xde, 0xab, 0x30, 0x28, 0x4f, 0xf7, 0x73, +0x93, 0xfe, 0xcd, 0x3b, 0x09, 0xb1, 0x1b, 0xb9, 0xcf, 0xe3, 0xeb, 0x50, 0x30, 0xfc, 0xa8, 0x1a, +0x65, 0x5b, 0x87, 0x11, 0xc6, 0xec, 0x4e, 0x38, 0xae, 0x3b, 0xe6, 0xb8, 0xb8, 0xc1, 0x52, 0xac, +0x5b, 0x27, 0x27, 0x18, 0xf4, 0x3f, 0x95, 0x54, 0x5d, 0x93, 0x62, 0x7a, 0xe8, 0x6b, 0x5b, 0xdc, +0xc7, 0x3b, 0xcb, 0x6e, 0xc0, 0xc6, 0xa4, 0xe3, 0x0d, 0xce, 0x7d, 0xeb, 0x94, 0xd4, 0x6c, 0xc5, +0x9d, 0xd9, 0x68, 0xcf, 0x7d, 0xca, 0x08, 0xea, 0x2a, 0x95, 0xd4, 0x95, 0xfa, 0x83, 0x77, 0x4d, +0x22, 0xf2, 0xb2, 0x4b, 0x08, 0x91, 0xe7, 0x88, 0xc8, 0xc3, 0x8b, 0x78, 0x63, 0x24, 0x9f, 0xa9, +0xed, 0x59, 0x17, 0x36, 0xa3, 0x99, 0x30, 0xde, 0xbb, 0x4a, 0xf3, 0x5a, 0x35, 0x67, 0xa9, 0x10, +0x6c, 0xc5, 0x90, 0x10, 0xc7, 0x8c, 0x7b, 0x54, 0x4d, 0x83, 0xeb, 0x9e, 0xf5, 0x26, 0xa9, 0xdc, +0xe9, 0xbc, 0x23, 0x61, 0x0d, 0xfe, 0xa7, 0x32, 0xb9, 0x1b, 0xed, 0xed, 0xa4, 0xb8, 0x8e, 0x36, +0x3f, 0xeb, 0x19, 0x47, 0x00, 0x7b, 0xf3, 0x9f, 0xc2, 0xaf, 0xcc, 0xa8, 0xd3, 0x91, 0x3a, 0xed, +0xc1, 0xc1, 0x2c, 0x2b, 0x8e, 0xbb, 0xb4, 0xd2, 0x67, 0xb3, 0x80, 0x87, 0x35, 0x39, 0x49, 0x16, +0xe6, 0xb3, 0xb4, 0x94, 0xab, 0x79, 0xd1, 0x1c, 0x8c, 0x6e, 0x5e, 0x4d, 0x32, 0x79, 0xec, 0x74, +0xab, 0x57, 0x02, 0x42, 0x59, 0xf0, 0x48, 0x7c, 0x6e, 0x6c, 0x76, 0x03, 0xd2, 0xb2, 0xd6, 0x5e, +0xea, 0x3a, 0x65, 0x52, 0x30, 0x5c, 0xc7, 0xd3, 0x20, 0x7e, 0x34, 0xf2, 0x81, 0xf8, 0x6e, 0x45, +0x77, 0x23, 0xc4, 0x96, 0xa3, 0xd0, 0x34, 0x47, 0x07, 0x2c, 0x9d, 0x8f, 0x75, 0xad, 0x48, 0x54, +0x1c, 0x77, 0xcf, 0x20, 0xe6, 0xb4, 0x89, 0x84, 0x8d, 0x9b, 0x68, 0xf2, 0x45, 0x76, 0x5a, 0x36, +0x99, 0x25, 0xdc, 0xc9, 0x1a, 0x21, 0x66, 0x73, 0x81, 0x5d, 0x30, 0x5d, 0x0e, 0x1a, 0xee, 0xc7, +0xbc, 0xe9, 0x3a, 0x5c, 0x5a, 0x65, 0xb0, 0x89, 0x00, 0x32, 0x1e, 0x5d, 0xfd, 0x6b, 0x56, 0xb9, +0xea, 0x4b, 0x9e, 0x4d, 0x9b, 0x51, 0x87, 0x24, 0x12, 0x0a, 0x2a, 0x0d, 0x46, 0x49, 0x22, 0x44, +0x8f, 0x2c, 0x8c, 0x15, 0x23, 0x52, 0xcc, 0xc7, 0xb0, 0x1d, 0xeb, 0xe7, 0x1f, 0x1c, 0x78, 0xaa, +0xf3, 0x51, 0xbc, 0x9f, 0xec, 0xb2, 0x81, 0x61, 0x0a, 0x18, 0xfe, 0xcf, 0x26, 0x36, 0xba, 0xf1, +0x9c, 0x8e, 0xe4, 0x91, 0x9f, 0x51, 0x81, 0x8e, 0x95, 0xbd, 0x18, 0x73, 0x5e, 0x4c, 0xe4, 0xc5, +0x55, 0x71, 0xe5, 0x82, 0xea, 0x78, 0xcb, 0x5e, 0x2b, 0xc8, 0xfb, 0x46, 0x17, 0x3f, 0x70, 0x9c, +0x91, 0x50, 0xb9, 0x0c, 0x37, 0x75, 0xcd, 0x4c, 0xe3, 0x63, 0x4a, 0x72, 0xb9, 0x4d, 0xfa, 0x9c, +0xfe, 0x35, 0x48, 0xfe, 0xf1, 0xb3, 0xfc, 0x08, 0x78, 0xf7, 0x35, 0x83, 0xee, 0x6d, 0x7e, 0xc2, +0x30, 0xe3, 0xfa, 0x54, 0x4d, 0x50, 0x59, 0x0b, 0x77, 0xeb, 0x50, 0x38, 0x07, 0x20, 0x8c, 0xe7, +0xd6, 0x80, 0xdc, 0x87, 0x26, 0x3e, 0x09, 0xca, 0xf6, 0x6f, 0x4a, 0x0f, 0xf3, 0xa7, 0x62, 0x53, +0x2a, 0xc9, 0xf3, 0x1f, 0x2f, 0xb1, 0xe5, 0x8d, 0x23, 0x0e, 0x3d, 0xbf, 0x95, 0x21, 0xbd, 0x51, +0x1b, 0x7f, 0x3a, 0x8c, 0xf7, 0xcf, 0x34, 0xf5, 0x61, 0x74, 0x55, 0x60, 0x54, 0x9e, 0xeb, 0xed, +0xda, 0x90, 0x8c, 0xf5, 0x39, 0x34, 0x68, 0x23, 0x1b, 0x52, 0x90, 0xec, 0xd8, 0x30, 0xcc, 0xc7, +0x68, 0x04, 0x70, 0x7d, 0xb3, 0x54, 0x60, 0x85, 0x22, 0x88, 0xc9, 0x8c, 0x82, 0x36, 0xa9, 0x65, +0xc9, 0xe4, 0xf4, 0x3f, 0x8d, 0x5f, 0x4b, 0x13, 0x7f, 0x79, 0xb3, 0xd1, 0x7e, 0x1a, 0x7c, 0x3f, +0x9b, 0xc6, 0x3e, 0x20, 0xb6, 0xd3, 0x79, 0x82, 0x06, 0x0d, 0x24, 0xf7, 0x5b, 0x37, 0x79, 0x08, +0x07, 0x27, 0x1c, 0x67, 0xb0, 0xfa, 0x91, 0x5b, 0xbf, 0x15, 0x7e, 0x14, 0xae, 0x81, 0x7d, 0x35, +0xa5, 0xa8, 0x95, 0xed, 0xd5, 0x3c, 0xcb, 0x69, 0xa6, 0x1c, 0xa8, 0x3c, 0x60, 0xb0, 0xec, 0x48, +0xeb, 0xeb, 0xc7, 0xd6, 0x5b, 0xd3, 0x98, 0xa6, 0xdd, 0xec, 0x78, 0x25, 0xbe, 0x9f, 0x3c, 0x33, +0xb5, 0xab, 0xb8, 0x86, 0x41, 0xc9, 0x57, 0x38, 0xcf, 0xd2, 0x8b, 0xab, 0x49, 0xd1, 0xe4, 0x57, +0x55, 0x25, 0x7b, 0x8e, 0x47, 0xe9, 0x5a, 0xde, 0xea, 0xe4, 0x3d, 0x24, 0x73, 0x17, 0x30, 0xe1, +0x98, 0x9f, 0xbc, 0x4f, 0x61, 0xd2, 0xb3, 0xd9, 0x08, 0x39, 0xeb, 0x52, 0xee, 0x8d, 0xe2, 0xee, +0x3a, 0xda, 0xee, 0x7b, 0x1b, 0x88, 0xee, 0xad, 0x9d, 0xa1, 0x9e, 0x16, 0xdc, 0x92, 0x2f, 0x63, +0x5b, 0xcf, 0xe2, 0x68, 0xee, 0x4e, 0xeb, 0xdb, 0x14, 0x79, 0x4f, 0xde, 0x96, 0xdd, 0xb6, 0x6e, +0xf7, 0xc7, 0x23, 0xf2, 0xc5, 0x65, 0x52, 0x92, 0xa9, 0xab, 0xdc, 0xec, 0xc3, 0x62, 0xe5, 0x86, +0x77, 0x5b, 0x33, 0x3a, 0xe3, 0x59, 0x04, 0x9f, 0xb1, 0xc0, 0x60, 0x27, 0xf8, 0xdd, 0xb7, 0x11, +0x58, 0x32, 0xcb, 0x2c, 0xee, 0x64, 0x95, 0xda, 0x47, 0x3d, 0x59, 0x8d, 0x54, 0x29, 0xf2, 0x6a, +0xc5, 0x88, 0xc5, 0xbc, 0x43, 0xb6, 0xc8, 0xfb, 0x94, 0x2f, 0xe7, 0x4f, 0x00, 0xf5, 0xa6, 0xb5, +0x30, 0x6c, 0xb2, 0xa3, 0xf5, 0xf5, 0xab, 0x30, 0xa9, 0x46, 0xca, 0xf2, 0x0f, 0x55, 0xad, 0x22, +0x63, 0x33, 0xa7, 0xd3, 0x10, 0xcf, 0x22, 0x2a, 0x0d, 0xcc, 0xe7, 0x01, 0x40, 0xea, 0x6b, 0xe8, +0x8f, 0x0c, 0xe8, 0x4b, 0xa6, 0x5a, 0xac, 0xd3, 0x2f, 0xfa, 0x5c, 0xab, 0xce, 0x7f, 0x80, 0x7a, +0x56, 0xee, 0x5c, 0xb0, 0x38, 0x9a, 0xf6, 0x93, 0x48, 0xea, 0xa8, 0xae, 0x63, 0xac, 0x28, 0xa0, +0x0f, 0x2d, 0xf1, 0xdf, 0x89, 0x04, 0x51, 0x3e, 0x9d, 0x6b, 0x20, 0xe3, 0x3e, 0x73, 0x0f, 0x5f, +0x4a, 0xf9, 0xbb, 0x57, 0xb9, 0xf3, 0x9d, 0xf6, 0xb6, 0x18, 0xf5, 0x15, 0xe8, 0x42, 0x3c, 0x90, +0x48, 0xf2, 0x27, 0x3f, 0x6b, 0x55, 0xc9, 0x7a, 0x1c, 0x65, 0xcc, 0x8c, 0xae, 0x16, 0x3c, 0xe7, +0xf8, 0x8f, 0xa7, 0xb5, 0x2c, 0x57, 0x60, 0xb1, 0x52, 0x46, 0xfc, 0x72, 0x0f, 0x43, 0x58, 0x54, +0xf7, 0xb4, 0x3a, 0xe0, 0xed, 0xa9, 0x34, 0x92, 0x79, 0xbf, 0x22, 0xe7, 0x9e, 0xa4, 0xf6, 0xa6, +0x9e, 0x06, 0x07, 0x41, 0x5c, 0xb2, 0xec, 0x75, 0x27, 0x72, 0x23, 0xed, 0x51, 0x30, 0xcf, 0xd6, +0xa4, 0xb2, 0x16, 0x1d, 0x7d, 0xea, 0x13, 0x4b, 0x70, 0x18, 0xd8, 0x39, 0x07, 0x9f, 0x5c, 0xd5, +0x56, 0x26, 0x20, 0x49, 0xe5, 0x3b, 0x7a, 0x8a, 0x62, 0x18, 0xaa, 0x71, 0xb8, 0xf2, 0xcd, 0xc9, +0xa4, 0x39, 0x20, 0xd2, 0x7a, 0x85, 0xc8, 0xcd, 0x46, 0x79, 0xe6, 0x81, 0x5d, 0x5c, 0x89, 0xbb, +0xf7, 0xcf, 0x5a, 0xae, 0xf9, 0x8c, 0x31, 0x1c, 0xa9, 0xe0, 0x67, 0xb1, 0xaa, 0x4c, 0x6c, 0xc5, +0x65, 0x13, 0x92, 0x46, 0xfe, 0x5b, 0x66, 0x4f, 0x0a, 0x79, 0xfe, 0x7c, 0xd6, 0xcd, 0xae, 0x9e, +0xf3, 0xbc, 0x51, 0x84, 0xe3, 0x76, 0x08, 0x2c, 0x0e, 0xe3, 0xf4, 0xa7, 0x2b, 0x19, 0xa4, 0xd1, +0xf7, 0x87, 0xc1, 0xdf, 0x09, 0xc7, 0xe1, 0xff, 0x00, 0x0e, 0x8b, 0xf9, 0x62, 0xdb, 0x7d, 0xaa, +0xfc, 0xc1, 0xdb, 0xef, 0x24, 0x23, 0xee, 0xaf, 0xb6, 0x4e, 0x4f, 0xe5, 0xe9, 0x5d, 0xfd, 0xf6, +0x81, 0xa6, 0x6a, 0xc6, 0xe6, 0x5d, 0x4a, 0xd1, 0x2e, 0x1a, 0x54, 0x30, 0x81, 0x36, 0x58, 0x2a, +0xf2, 0x38, 0x5e, 0x98, 0x3d, 0x7a, 0x50, 0xb6, 0x45, 0x35, 0xcd, 0xa1, 0xf0, 0x47, 0xc4, 0x9f, +0x09, 0x47, 0xa5, 0xea, 0x17, 0x2b, 0x12, 0xa1, 0xb6, 0xfb, 0x43, 0xc7, 0x6b, 0x70, 0xad, 0x9d, +0xe1, 0x7d, 0x3d, 0x57, 0x9e, 0xb5, 0xe5, 0x50, 0xc3, 0x3a, 0x9f, 0x26, 0x45, 0x7f, 0x98, 0xe0, +0xca, 0x39, 0xc0, 0xa7, 0x4e, 0x56, 0xba, 0x64, 0xce, 0x2e, 0x4a, 0xe8, 0xc3, 0xbf, 0xd3, 0x65, +0x72, 0xf2, 0x88, 0x9b, 0x60, 0x6d, 0xaa, 0x47, 0x3c, 0xf7, 0xcd, 0x73, 0x57, 0x16, 0x4d, 0x19, +0xc6, 0x09, 0x3e, 0xfd, 0x6a, 0x9d, 0xd1, 0xac, 0x25, 0xcc, 0x65, 0xbc, 0x0e, 0x58, 0xe5, 0x08, +0x1e, 0xf5, 0x1b, 0x5a, 0x38, 0xe7, 0x38, 0xe7, 0x39, 0x34, 0x91, 0x72, 0x7a, 0x88, 0x96, 0x8f, +0x21, 0xda, 0xa0, 0xb1, 0xf6, 0x19, 0xab, 0xf0, 0xe8, 0xce, 0xc7, 0x74, 0xc7, 0x62, 0x83, 0xd3, +0x3c, 0x9a, 0x4d, 0xea, 0x2b, 0xea, 0x7d, 0x9d, 0xb7, 0xf5, 0xa7, 0x01, 0xf8, 0xd2, 0x46, 0x8d, +0x93, 0x2d, 0x5a, 0x47, 0x0b, 0xc9, 0xad, 0x11, 0x94, 0xf5, 0x3a, 0x4d, 0x0f, 0x50, 0x5b, 0x3b, +0xdb, 0x7b, 0x82, 0x62, 0x12, 0x2c, 0x81, 0x96, 0x39, 0x31, 0xce, 0x0e, 0x6b, 0xe9, 0xad, 0x1f, +0x59, 0xb6, 0xd5, 0xed, 0xd2, 0x58, 0xd9, 0x16, 0x6c, 0x65, 0xe0, 0xdd, 0x92, 0xbf, 0xfd, 0x6a, +0xd6, 0x6b, 0x9a, 0x37, 0xec, 0x71, 0xa9, 0xf2, 0x54, 0xd7, 0xa9, 0xb1, 0x45, 0x73, 0x9d, 0x41, +0x5c, 0xb7, 0x89, 0xf5, 0xe8, 0xf4, 0xab, 0x47, 0x8e, 0x37, 0x53, 0x75, 0x20, 0xe0, 0x67, 0xee, +0x8f, 0x5a, 0xd2, 0x94, 0x3d, 0xa4, 0xd2, 0x30, 0xc4, 0xd5, 0xf6, 0x54, 0xdb, 0x5b, 0xf4, 0x3e, +0x6c, 0xd7, 0x75, 0x36, 0x99, 0xe4, 0x7d, 0xe4, 0xc8, 0xd9, 0x27, 0x2d, 0xd7, 0xde, 0xbc, 0xf2, +0xea, 0x66, 0x39, 0x6e, 0xb2, 0x3f, 0x41, 0xfd, 0x6b, 0xbe, 0xa3, 0xb9, 0xe7, 0x50, 0x8a, 0x49, +0x58, 0xc5, 0x99, 0x82, 0x83, 0x8c, 0x89, 0x3d, 0x7d, 0x4d, 0x53, 0xb7, 0xb7, 0x2c, 0xc5, 0xce, +0x7a, 0xd7, 0x24, 0x8e, 0xf4, 0xae, 0x6b, 0xf9, 0x3b, 0x06, 0x41, 0x21, 0xff, 0x00, 0x9d, 0x47, +0xbb, 0x39, 0x1d, 0x18, 0x75, 0x06, 0xb9, 0x9b, 0xb9, 0xba, 0xd0, 0x89, 0xb3, 0xff, 0x00, 0xeb, +0xa8, 0x8d, 0x4b, 0xb8, 0xd3, 0x23, 0x22, 0xa2, 0x6e, 0xbd, 0xe8, 0x28, 0x8c, 0xfe, 0xb5, 0x59, +0xfe, 0x77, 0xc7, 0x55, 0x5e, 0x49, 0x3d, 0xcd, 0x3f, 0x52, 0x48, 0x88, 0x31, 0x9e, 0x39, 0x4e, +0xe3, 0xfb, 0xb4, 0x1e, 0x79, 0x1c, 0xe7, 0xb8, 0xa4, 0x1d, 0x48, 0xc8, 0xa8, 0xc8, 0xa2, 0xc2, +0x18, 0x47, 0xa9, 0xa8, 0x71, 0xbd, 0xf1, 0xd4, 0x28, 0xe7, 0xdc, 0xd3, 0xf5, 0x01, 0xcb, 0x66, +0x0c, 0xa8, 0xea, 0x06, 0x09, 0xf9, 0x97, 0x1e, 0xbd, 0xeb, 0xd6, 0xfe, 0x1c, 0xf8, 0x40, 0xeb, +0xda, 0xed, 0xbd, 0xb2, 0xa9, 0x36, 0xe1, 0xb7, 0xc9, 0x38, 0x4e, 0x04, 0x60, 0xf2, 0x7d, 0x8f, +0xf5, 0x34, 0x9b, 0x06, 0x7d, 0xd0, 0x91, 0xa4, 0x51, 0xa4, 0x51, 0x22, 0xa4, 0x71, 0xa8, 0x45, +0x45, 0x18, 0x0a, 0x07, 0x18, 0x1f, 0x85, 0x29, 0xe1, 0x70, 0x30, 0x38, 0xc0, 0xcd, 0x58, 0xcf, +0x87, 0x3e, 0x30, 0x5e, 0xa4, 0xfe, 0x28, 0xba, 0xd3, 0xed, 0xa5, 0x66, 0xd3, 0xf4, 0x7f, 0xf4, +0x78, 0x21, 0xdd, 0xb9, 0x63, 0x63, 0xf3, 0x49, 0x81, 0xfe, 0xfb, 0x37, 0xe4, 0x2b, 0xc3, 0xe7, +0xca, 0xb1, 0x20, 0x9c, 0x7f, 0x2a, 0x82, 0xa3, 0xb1, 0x1a, 0xdc, 0xa8, 0x56, 0x59, 0x50, 0x4a, +0xad, 0xdb, 0xa1, 0xfa, 0xe6, 0xa8, 0xdc, 0x0b, 0x06, 0x05, 0xbe, 0xcc, 0xa5, 0xcf, 0xf1, 0x37, +0x3f, 0x8d, 0x36, 0xdb, 0xd0, 0x49, 0x72, 0xbd, 0x0e, 0x7e, 0xe6, 0xca, 0xda, 0x4e, 0x23, 0x26, +0x27, 0x3d, 0x49, 0x19, 0xcd, 0x65, 0x9d, 0x2d, 0x55, 0xb2, 0xd2, 0x97, 0x19, 0xe9, 0x8c, 0x66, +0x9a, 0x93, 0x2f, 0xd4, 0xb6, 0x90, 0xc6, 0x80, 0x04, 0x45, 0x19, 0xee, 0x05, 0x2b, 0x8e, 0x09, +0xce, 0x69, 0x6a, 0xca, 0x76, 0x3e, 0xaf, 0x2a, 0x7a, 0xfa, 0xd1, 0xb7, 0xf1, 0xfa, 0xd3, 0x5a, +0x95, 0x2b, 0x0b, 0x8d, 0xbc, 0x9a, 0x86, 0x6b, 0x94, 0x81, 0x0c, 0xd2, 0x93, 0xb4, 0x70, 0x17, +0xb9, 0xad, 0x23, 0xb9, 0x8c, 0x9e, 0x87, 0x3f, 0xfd, 0xa1, 0x2c, 0xd3, 0x89, 0x9d, 0xc8, 0x60, +0x7e, 0x50, 0xbf, 0xc3, 0x5e, 0x9b, 0xe1, 0x9f, 0x17, 0x4f, 0x6b, 0x24, 0x62, 0x49, 0x9d, 0x1c, +0x70, 0xb3, 0xfa, 0xfb, 0x1a, 0xed, 0x4b, 0x44, 0x79, 0x95, 0x3d, 0xeb, 0xdc, 0xfa, 0x3b, 0xc3, +0xfe, 0x24, 0x83, 0x55, 0x8d, 0x63, 0x95, 0xb6, 0xdd, 0x63, 0xa9, 0xc0, 0x0f, 0x5d, 0x55, 0x72, +0x55, 0x87, 0x23, 0xf5, 0x3a, 0xb0, 0xf5, 0x7d, 0xa4, 0x6c, 0xf7, 0x46, 0x2e, 0xb9, 0xac, 0xc1, +0xa3, 0x59, 0xbc, 0xf2, 0x30, 0x32, 0x9e, 0x12, 0x2c, 0xf2, 0xc7, 0xe9, 0x5f, 0x39, 0x6b, 0xfe, +0x20, 0x96, 0xfa, 0x59, 0x6e, 0x24, 0x94, 0x97, 0x63, 0xc8, 0x3f, 0xca, 0xba, 0x70, 0xd1, 0xe5, +0x8b, 0x9f, 0x73, 0x93, 0x17, 0x3f, 0x69, 0x51, 0x41, 0x6c, 0xbf, 0x33, 0xce, 0x6e, 0xee, 0x7c, +0xd6, 0x69, 0x1b, 0x39, 0x1d, 0xbd, 0x6b, 0x0e, 0x56, 0x62, 0x59, 0x9f, 0x01, 0xcf, 0xad, 0x29, +0xbd, 0x34, 0x2a, 0x9a, 0xd4, 0xcb, 0xc3, 0x5c, 0x49, 0x93, 0xc0, 0x53, 0xc9, 0xad, 0x58, 0x61, +0xda, 0x01, 0xc0, 0xf6, 0x15, 0x84, 0xd9, 0xd4, 0xb7, 0x1e, 0xff, 0x00, 0x5f, 0xce, 0xaa, 0x48, +0xbb, 0xb9, 0xe8, 0xdd, 0x9a, 0xb1, 0x35, 0xd8, 0xad, 0xbb, 0x27, 0x6b, 0x70, 0xff, 0x00, 0xce, +0x91, 0xb9, 0x1e, 0xf5, 0x23, 0x22, 0x23, 0xff, 0x00, 0xaf, 0x51, 0x9a, 0x5e, 0x61, 0xd0, 0x82, +0x43, 0xb4, 0x1e, 0x79, 0x3c, 0x01, 0x4c, 0x0b, 0xb4, 0x60, 0xf2, 0x7b, 0x9f, 0x5a, 0x61, 0x7b, +0x8c, 0x23, 0xaf, 0xbf, 0x5a, 0xae, 0xca, 0x50, 0xee, 0x5e, 0x57, 0xb8, 0xf4, 0xa6, 0x26, 0x27, +0x0d, 0x82, 0x0e, 0x41, 0xef, 0x4c, 0x23, 0x19, 0xcd, 0x26, 0x82, 0xfd, 0x48, 0xe4, 0xe0, 0x16, +0xa6, 0xa2, 0x90, 0x06, 0x79, 0x24, 0xe4, 0xd3, 0xdc, 0x37, 0xd4, 0xd1, 0xb6, 0xdb, 0xbc, 0x16, +0x3d, 0xf9, 0xcd, 0x7d, 0x2b, 0xf0, 0x73, 0x59, 0xd1, 0x74, 0xeb, 0xbb, 0xb8, 0x6f, 0x26, 0x4b, +0x5b, 0x9b, 0xb8, 0x84, 0x71, 0x4f, 0x31, 0x01, 0x3a, 0xe4, 0xa9, 0x3d, 0xb3, 0x81, 0xd7, 0xd2, +0xa7, 0x4b, 0x89, 0xbb, 0xea, 0x7d, 0x39, 0x9c, 0xf3, 0xd7, 0x3d, 0xfd, 0x6b, 0x13, 0xc4, 0x9a, +0xb2, 0xe8, 0x7a, 0x16, 0xab, 0xaa, 0xb4, 0x91, 0xa3, 0x59, 0xdb, 0xbb, 0xc4, 0x65, 0x19, 0x56, +0x93, 0x18, 0x45, 0xc7, 0xbb, 0x10, 0x2a, 0xd9, 0x5b, 0x9f, 0x9d, 0x9a, 0xbd, 0xd3, 0x4d, 0x3c, +0xb2, 0x33, 0x97, 0x67, 0x6d, 0xc5, 0x89, 0xe4, 0x93, 0x5c, 0xac, 0xcc, 0x4e, 0x73, 0xfa, 0xd6, +0x68, 0xab, 0x99, 0xb2, 0x1d, 0xb9, 0x39, 0x3b, 0x4d, 0x55, 0x76, 0xc8, 0x3d, 0xe9, 0xde, 0xe5, +0xdd, 0x6e, 0xca, 0x0d, 0x96, 0x66, 0x6c, 0xe4, 0x74, 0xc6, 0x71, 0x4d, 0x23, 0xae, 0x72, 0x49, +0xa7, 0x7b, 0x06, 0xe4, 0x04, 0x6d, 0x39, 0xed, 0xfc, 0xa9, 0x8f, 0xc9, 0x51, 0xd7, 0x27, 0xa7, +0xad, 0x1b, 0x8d, 0x68, 0xec, 0x7d, 0x6e, 0x53, 0x3c, 0x9a, 0x42, 0xbc, 0x67, 0xd3, 0xa9, 0xab, +0x29, 0x95, 0x27, 0x95, 0x15, 0x1a, 0x59, 0x0e, 0xd8, 0xe3, 0x19, 0xc9, 0xef, 0x5c, 0x75, 0xe5, +0xec, 0x97, 0x72, 0x97, 0x3f, 0x2c, 0x6b, 0xc2, 0x27, 0xa5, 0x6b, 0x04, 0xee, 0x72, 0xd5, 0x7d, +0x08, 0x90, 0xe4, 0xfa, 0x1f, 0xe7, 0x5a, 0x10, 0xcc, 0x57, 0xa9, 0x23, 0xd6, 0xba, 0x62, 0xce, +0x39, 0xa3, 0xb5, 0xd1, 0x3c, 0x53, 0x71, 0x60, 0xe8, 0xae, 0xe4, 0xc4, 0xa7, 0x20, 0xf3, 0x95, +0xfa, 0x57, 0xba, 0x69, 0x1f, 0x12, 0xa3, 0xf2, 0x51, 0x2f, 0x11, 0x26, 0x42, 0xb8, 0x4b, 0x84, +0x27, 0x23, 0x8e, 0x33, 0xeb, 0xfc, 0xe9, 0x54, 0x8a, 0x92, 0xb3, 0x31, 0x84, 0x9c, 0x24, 0xa4, +0x8f, 0x2f, 0xf1, 0x37, 0x89, 0x6f, 0x75, 0x1b, 0xf9, 0xa7, 0x9a, 0x44, 0xf3, 0x0b, 0x64, 0x47, +0x19, 0xca, 0x6d, 0xc7, 0x18, 0xae, 0x06, 0xe6, 0xf1, 0xae, 0x1b, 0x20, 0x95, 0x23, 0xa8, 0x26, +0xab, 0x99, 0x72, 0xab, 0x02, 0x83, 0x4d, 0xb9, 0x75, 0x32, 0x8c, 0xbe, 0x73, 0x1c, 0x82, 0xa2, +0x33, 0xc6, 0x7b, 0xfb, 0xd5, 0x09, 0xe4, 0x69, 0x9f, 0xca, 0x03, 0x90, 0x78, 0x3e, 0xb5, 0x8c, +0x9b, 0x3a, 0x60, 0x8b, 0x76, 0xf0, 0x00, 0x30, 0x72, 0x40, 0xe4, 0x93, 0xde, 0xad, 0x35, 0x61, +0x27, 0x76, 0x6f, 0x05, 0x7d, 0x4a, 0xef, 0x50, 0x1a, 0xcd, 0x9a, 0x22, 0x09, 0x10, 0x30, 0xe7, +0x3e, 0xc7, 0xd2, 0xab, 0x65, 0x81, 0xda, 0xe7, 0x93, 0xd1, 0xbd, 0x68, 0xd5, 0x8a, 0xe0, 0x7d, +0x69, 0x84, 0x63, 0x34, 0x98, 0x5c, 0xab, 0xcc, 0x8e, 0x5b, 0xf8, 0x57, 0x85, 0xcf, 0x7a, 0x71, +0x5a, 0x76, 0xb8, 0xae, 0x46, 0x47, 0x73, 0xf9, 0xd4, 0x4c, 0x3f, 0x5f, 0x7a, 0x1a, 0xd0, 0x2e, +0x57, 0x65, 0x2a, 0x4b, 0x28, 0xce, 0x7a, 0xad, 0x27, 0x07, 0x90, 0x72, 0x28, 0xdc, 0x57, 0xd4, +0x81, 0xbe, 0x67, 0xc7, 0x64, 0xe4, 0xff, 0x00, 0x4a, 0x7f, 0x7a, 0x60, 0x98, 0xf5, 0x62, 0x0e, +0x7b, 0x8f, 0x7a, 0xdc, 0xd3, 0xef, 0xda, 0x07, 0x07, 0x79, 0x00, 0x54, 0xbb, 0xb1, 0xde, 0xc7, +0xd3, 0xdf, 0x0f, 0xfe, 0x2b, 0x69, 0xab, 0x6b, 0x06, 0x8f, 0xaf, 0xdc, 0x18, 0x0c, 0x58, 0x8e, +0xde, 0xf9, 0x81, 0x61, 0x8e, 0xca, 0xd8, 0xe7, 0xe8, 0x7f, 0x3f, 0x5a, 0xa7, 0xf1, 0xe7, 0xc4, +0x6b, 0x6f, 0x6f, 0xa5, 0x68, 0x50, 0xdc, 0x7e, 0xf2, 0x65, 0x6b, 0xcb, 0x98, 0x57, 0xa1, 0x1c, +0x2c, 0x67, 0x3f, 0x84, 0x9c, 0x7d, 0x0f, 0xa5, 0x0d, 0xe8, 0x17, 0xb6, 0x87, 0xc8, 0x57, 0x53, +0x97, 0x62, 0x73, 0xd4, 0xf7, 0xac, 0x99, 0x5f, 0x3d, 0xfe, 0xb4, 0x96, 0xc5, 0xdf, 0xa1, 0x4d, +0xce, 0x7f, 0xad, 0x51, 0x95, 0x8a, 0x02, 0x7b, 0x75, 0xe2, 0x9e, 0xee, 0xc5, 0x73, 0x22, 0x0c, +0x7c, 0xbc, 0x91, 0xc5, 0x30, 0x8c, 0x92, 0x69, 0xdb, 0x4d, 0x0a, 0xd2, 0xf7, 0x18, 0x47, 0x6a, +0xae, 0x4e, 0x1f, 0x9e, 0xde, 0xbd, 0xa8, 0xd3, 0x41, 0x9f, 0x61, 0x98, 0xfb, 0xe2, 0xaa, 0x4a, +0x41, 0x0c, 0xc4, 0x85, 0x8d, 0x79, 0x2c, 0x4e, 0x01, 0xab, 0x41, 0x23, 0x8c, 0xd4, 0xaf, 0x1a, +0xed, 0xca, 0x26, 0x56, 0x14, 0x3f, 0x28, 0xcf, 0xde, 0xf7, 0xac, 0xbd, 0xbf, 0x9d, 0x74, 0x45, +0x59, 0x1c, 0x95, 0x1f, 0x33, 0x01, 0x9f, 0x6f, 0xc6, 0xa5, 0x12, 0x71, 0x86, 0xe7, 0xdf, 0xbd, +0x5a, 0x66, 0x32, 0x24, 0x59, 0x4a, 0xf2, 0x39, 0x07, 0xb8, 0x35, 0xa3, 0x6b, 0xaa, 0xcd, 0x6c, +0x7e, 0x56, 0x25, 0x0f, 0xde, 0x46, 0x3c, 0x35, 0x53, 0x77, 0x46, 0x4d, 0x6b, 0x73, 0x6f, 0xed, +0x70, 0xdf, 0x21, 0x91, 0x18, 0x6e, 0x1d, 0x54, 0x9c, 0xb2, 0xff, 0x00, 0xf5, 0xab, 0x12, 0xe8, +0x3a, 0xee, 0x50, 0x76, 0x13, 0xc9, 0x94, 0xf4, 0xac, 0xdc, 0xba, 0x33, 0x47, 0x1e, 0xa8, 0xce, +0x7b, 0xb3, 0x2c, 0x66, 0xdd, 0xd7, 0xc9, 0x9c, 0x71, 0xe6, 0x03, 0xc3, 0xfb, 0x8a, 0x9a, 0xd6, +0x07, 0xe0, 0xbf, 0xcc, 0xfe, 0xa6, 0xa2, 0x4e, 0xc8, 0xb8, 0xea, 0x6b, 0xed, 0x08, 0xb8, 0x1d, +0x7d, 0x6a, 0x07, 0xcf, 0x5e, 0x6b, 0x16, 0x6c, 0x88, 0x1b, 0xbf, 0xad, 0x42, 0xdd, 0x73, 0xde, +0xa5, 0xea, 0x3b, 0x91, 0xb7, 0x27, 0x15, 0x0b, 0xa0, 0x60, 0x41, 0xe6, 0x90, 0x15, 0x89, 0x68, +0xce, 0x18, 0xe5, 0x4f, 0x47, 0x3d, 0xbe, 0xb4, 0xd9, 0x09, 0x20, 0x2a, 0xe0, 0x97, 0xe3, 0x23, +0xb5, 0x1b, 0xe8, 0x1b, 0x09, 0xb4, 0x00, 0x00, 0xa6, 0x11, 0xfe, 0x4d, 0x31, 0x5e, 0xe4, 0x67, +0xde, 0xa2, 0x61, 0x4f, 0x70, 0x64, 0x67, 0xdf, 0xf3, 0xaa, 0xf2, 0x0d, 0xb9, 0x70, 0x78, 0xea, +0x57, 0xd6, 0x81, 0x3d, 0xc8, 0xd0, 0x64, 0x16, 0xea, 0x58, 0xe4, 0xe6, 0x83, 0xc5, 0x0c, 0x06, +0xee, 0xc1, 0xa0, 0x48, 0x47, 0x3c, 0xe7, 0xd4, 0x50, 0x31, 0xe2, 0xed, 0xd7, 0xa3, 0x10, 0x47, +0x42, 0x0d, 0x54, 0xba, 0xd4, 0x2e, 0x6e, 0x18, 0xc9, 0x34, 0xb2, 0xcd, 0x80, 0x13, 0x32, 0x31, +0x62, 0xa0, 0x0c, 0x0e, 0x4f, 0x6c, 0x52, 0xb2, 0x0b, 0xeb, 0xa9, 0x9a, 0xef, 0xbf, 0x24, 0x1f, +0xc4, 0x55, 0x47, 0x6e, 0xb9, 0x3c, 0xf7, 0xa4, 0xd6, 0x85, 0xa7, 0xd8, 0xa9, 0x21, 0xe4, 0x9f, +0xce, 0xa9, 0x4d, 0xf3, 0x60, 0x67, 0x39, 0x3c, 0x83, 0x49, 0x16, 0xbc, 0xc8, 0x4f, 0xca, 0x7a, +0xe5, 0x4f, 0xb7, 0x4a, 0x09, 0xe4, 0x1c, 0xd1, 0xba, 0x29, 0x6c, 0x30, 0xf3, 0x9a, 0x87, 0x19, +0x2c, 0x48, 0xcf, 0x38, 0xe6, 0x8b, 0xdc, 0x7d, 0x4f, 0xb2, 0x24, 0x52, 0xd9, 0x55, 0x20, 0x28, +0xfb, 0xcc, 0x6b, 0x95, 0xd5, 0x2e, 0x8c, 0xc7, 0xc8, 0x87, 0x88, 0x57, 0xef, 0x1f, 0xef, 0x9a, +0xde, 0x2b, 0xb9, 0x13, 0x68, 0xc0, 0x78, 0xba, 0x9a, 0x81, 0xa3, 0x23, 0x93, 0xd2, 0xb6, 0xb9, +0xce, 0xfb, 0x91, 0x15, 0xea, 0x7f, 0x5a, 0x88, 0x8c, 0xd3, 0x33, 0x63, 0x37, 0x15, 0xef, 0xc7, +0xb5, 0x31, 0x9f, 0x3c, 0x82, 0x78, 0xec, 0x69, 0xdc, 0x87, 0x71, 0xb1, 0xdd, 0x4b, 0x0c, 0x82, +0x48, 0xdc, 0xab, 0x0f, 0x4a, 0xe8, 0x20, 0xbe, 0xb7, 0xd4, 0x10, 0xc5, 0x22, 0x85, 0x98, 0xf5, +0x56, 0xe8, 0xde, 0xe2, 0xb3, 0x9f, 0x74, 0x54, 0x5f, 0x46, 0x42, 0xd6, 0x6a, 0xb2, 0x02, 0x7e, +0x65, 0x07, 0x8c, 0x8f, 0xbb, 0x5a, 0x91, 0x47, 0xb5, 0x72, 0x7e, 0xf1, 0xf5, 0xac, 0xe5, 0x23, +0x48, 0xc7, 0x5d, 0x41, 0x8f, 0xae, 0x4d, 0x40, 0xdc, 0xe6, 0xb3, 0x7a, 0x9a, 0x59, 0x22, 0x13, +0xee, 0x7a, 0xd4, 0x2d, 0xf9, 0xd4, 0xbd, 0x43, 0xa9, 0x1f, 0x43, 0xce, 0x72, 0x69, 0xa6, 0x8b, +0x83, 0x77, 0x20, 0x70, 0x30, 0xd9, 0xc1, 0x18, 0xe6, 0xa9, 0x2e, 0x53, 0x32, 0x10, 0x4a, 0x37, +0x4f, 0x50, 0x29, 0x88, 0x9c, 0xf3, 0xc8, 0x39, 0x07, 0xbd, 0x31, 0x86, 0x7a, 0xd3, 0xb7, 0x60, +0xb9, 0x11, 0x1d, 0xe9, 0x8c, 0x33, 0xeb, 0xf8, 0xd3, 0xd7, 0xa0, 0x99, 0x11, 0x15, 0x5e, 0x5f, +0x99, 0x82, 0x75, 0x1d, 0x4d, 0x02, 0xb9, 0x13, 0x29, 0x07, 0x72, 0xe3, 0x3d, 0xc7, 0xad, 0x46, +0x5b, 0x70, 0xcf, 0x7f, 0xe5, 0x40, 0x5d, 0x8c, 0x3f, 0xad, 0x44, 0x4f, 0xff, 0x00, 0xae, 0x97, +0x52, 0x96, 0xa4, 0x12, 0xb6, 0x01, 0x03, 0x39, 0x3c, 0x03, 0x55, 0xce, 0x02, 0xe2, 0x87, 0xb6, +0xa1, 0xaa, 0xd8, 0xa7, 0x26, 0x54, 0x96, 0x1c, 0xa9, 0xe4, 0xad, 0x42, 0x48, 0x23, 0x23, 0xbf, +0x7a, 0x4c, 0xb8, 0xea, 0xac, 0x56, 0x7e, 0xa7, 0x3e, 0xb9, 0xaa, 0x6d, 0x96, 0x72, 0xd9, 0xfb, +0xbc, 0x0c, 0x54, 0x94, 0x44, 0xc3, 0x39, 0x15, 0x16, 0x76, 0x9c, 0x1e, 0x94, 0x5c, 0xab, 0x3d, +0x85, 0x63, 0xd7, 0x9a, 0x8c, 0x74, 0xf7, 0xea, 0x69, 0x8e, 0xf7, 0x3e, 0xc2, 0xd4, 0xdc, 0x80, +0xd6, 0xd0, 0x9e, 0x3a, 0x3b, 0x8e, 0xfe, 0xd5, 0xcd, 0x3d, 0xb9, 0xf7, 0xcd, 0x74, 0x47, 0x63, +0x09, 0xbb, 0xb2, 0xa3, 0x40, 0x73, 0xd3, 0x39, 0xfd, 0x2a, 0xab, 0xc3, 0xd7, 0xaf, 0xd6, 0xaa, +0xe2, 0xe8, 0x53, 0x92, 0x33, 0x55, 0x1d, 0x7b, 0x9f, 0xe5, 0x55, 0x76, 0xf5, 0x32, 0x7e, 0x65, +0x77, 0x5f, 0x5a, 0xae, 0xdf, 0xe4, 0xd0, 0xdb, 0x42, 0xb5, 0xc8, 0x58, 0xe7, 0x39, 0xce, 0x69, +0xd6, 0x90, 0x49, 0x71, 0x3a, 0xc7, 0x19, 0x20, 0xe7, 0x25, 0xc7, 0xf0, 0x8f, 0x5a, 0x4d, 0xa5, +0xa8, 0x92, 0xd4, 0xec, 0x84, 0x65, 0xc0, 0x05, 0x89, 0x08, 0x36, 0x87, 0x3c, 0x96, 0xf7, 0xa5, +0xf3, 0x4a, 0x90, 0xb2, 0x70, 0x7b, 0x3e, 0x78, 0x35, 0xce, 0x6e, 0x81, 0xb2, 0x7f, 0xc6, 0xa2, +0x63, 0x53, 0xbb, 0x1f, 0x42, 0x16, 0xef, 0x50, 0x9e, 0x7d, 0x69, 0x30, 0xbd, 0x86, 0x9a, 0x61, +0xc9, 0xcd, 0x03, 0x65, 0x59, 0x7e, 0x66, 0x08, 0x3a, 0x75, 0x6c, 0x52, 0x91, 0xf9, 0x7d, 0x2a, +0x96, 0xa4, 0x36, 0x40, 0x55, 0x90, 0x92, 0xa3, 0x2a, 0x7a, 0xaf, 0xf8, 0x52, 0xe4, 0x11, 0x91, +0xcd, 0x3b, 0x5c, 0x9b, 0x8d, 0x20, 0xf5, 0xef, 0xef, 0x4c, 0x22, 0x80, 0x6e, 0xe4, 0x4e, 0x3a, +0xe4, 0xfe, 0x95, 0x58, 0x29, 0x21, 0x98, 0xf5, 0x6e, 0x7f, 0x0a, 0x7b, 0x3b, 0x0a, 0xf7, 0x18, +0xc3, 0x3d, 0xea, 0xb3, 0xa9, 0xc9, 0x65, 0xe5, 0xbd, 0x0f, 0x7a, 0x43, 0xdf, 0x52, 0x2c, 0x83, +0x9f, 0x5f, 0x4a, 0x89, 0x8f, 0x5a, 0x19, 0x48, 0xa8, 0xf9, 0x32, 0xfa, 0x85, 0x1f, 0xad, 0x31, +0xb9, 0xef, 0xcd, 0x16, 0xb8, 0xef, 0x76, 0x57, 0x72, 0x79, 0xe7, 0x35, 0x49, 0xf2, 0xb9, 0x20, +0xe4, 0x77, 0x14, 0x99, 0x5a, 0x90, 0x39, 0x1b, 0x4b, 0x75, 0xef, 0x9a, 0xa8, 0x01, 0xc6, 0x58, +0xf5, 0xe6, 0xa4, 0xbf, 0x42, 0x36, 0xfd, 0x4f, 0xaf, 0x7a, 0x85, 0xb2, 0x7f, 0x1a, 0x57, 0xd4, +0xbe, 0xba, 0x11, 0x92, 0x71, 0x8e, 0x39, 0xe9, 0x4e, 0x39, 0x23, 0xb5, 0x1d, 0x46, 0xbb, 0xb3, +0xef, 0x6d, 0x53, 0xc2, 0xd3, 0x5b, 0x97, 0x78, 0xd0, 0xb2, 0x83, 0xca, 0x60, 0xee, 0x5f, 0xf1, +0xae, 0x3e, 0x7d, 0x38, 0xa9, 0x3f, 0x2f, 0x35, 0xbc, 0x65, 0x73, 0x9e, 0x6a, 0xcc, 0xc9, 0x9a, +0xd0, 0xae, 0x78, 0xcf, 0xbd, 0x66, 0x4b, 0x07, 0x5c, 0x71, 0xef, 0x57, 0xe6, 0x4c, 0x9f, 0x43, +0x3e, 0x58, 0xb3, 0x9c, 0x8f, 0xc6, 0xb3, 0xe4, 0x8b, 0xd7, 0xf3, 0xa1, 0x79, 0x12, 0xf5, 0x28, +0xc8, 0xbd, 0x40, 0xe6, 0xa9, 0x38, 0x3c, 0xe7, 0x8f, 0xeb, 0x56, 0xdd, 0xc8, 0xb5, 0x99, 0x5f, +0x69, 0x62, 0x00, 0x04, 0x93, 0xd0, 0x0e, 0x6b, 0xac, 0xb1, 0xb2, 0xfb, 0x34, 0x41, 0x0e, 0x0c, +0xd2, 0x72, 0xee, 0x3b, 0x0f, 0x4a, 0xca, 0xa3, 0xd0, 0xb8, 0xad, 0x6e, 0x69, 0x90, 0x00, 0xc0, +0xe3, 0x15, 0x03, 0xa8, 0x60, 0x43, 0x72, 0x0f, 0xad, 0x63, 0x73, 0x42, 0xa3, 0x6f, 0x88, 0x9d, +0xc4, 0xb4, 0x7d, 0x9b, 0xba, 0xd2, 0x96, 0x04, 0x64, 0x72, 0x0f, 0x7a, 0x1b, 0xd6, 0xe8, 0x4b, +0x54, 0x44, 0xc7, 0x3e, 0xbc, 0xd3, 0x0d, 0x27, 0xa8, 0x37, 0xa9, 0x19, 0xe7, 0x9e, 0xf5, 0x1b, +0xb0, 0x55, 0x24, 0xd1, 0xe8, 0x0d, 0x95, 0xd1, 0x4f, 0x2c, 0x7e, 0xf3, 0x9c, 0x9a, 0x93, 0x1f, +0xfe, 0xba, 0xa2, 0x6e, 0x30, 0x8e, 0x79, 0xa8, 0x9a, 0x32, 0x09, 0x64, 0x3c, 0x9e, 0xa0, 0xf7, +0xaa, 0x48, 0x96, 0xc5, 0x18, 0x71, 0xf4, 0x38, 0xc1, 0xed, 0x48, 0x57, 0x9a, 0xbb, 0x10, 0xd9, +0x04, 0x8b, 0xbb, 0xe4, 0x19, 0xf9, 0xba, 0xfd, 0x29, 0x8c, 0x87, 0xff, 0x00, 0xd7, 0x40, 0x9c, +0xae, 0x57, 0x65, 0xf5, 0x35, 0x5d, 0x94, 0xf3, 0x52, 0xee, 0x5a, 0x65, 0x59, 0x10, 0xfd, 0xe5, +0x38, 0x6f, 0x5f, 0x5a, 0xae, 0x58, 0x60, 0x92, 0x39, 0x1d, 0x7d, 0xa8, 0xb3, 0x1a, 0x76, 0x2b, +0x80, 0x71, 0x93, 0xd5, 0x8e, 0x4d, 0x44, 0xd8, 0xcf, 0xbf, 0xad, 0x49, 0x45, 0x69, 0x33, 0xcf, +0x26, 0xab, 0x38, 0xce, 0x79, 0xa4, 0xed, 0xb3, 0x2d, 0x36, 0x50, 0x9f, 0x20, 0x0d, 0xbd, 0xfa, +0x8a, 0x88, 0x90, 0x47, 0xbe, 0x2a, 0x4d, 0x17, 0x99, 0x0b, 0x7d, 0x79, 0x15, 0x19, 0x07, 0xa9, +0xe9, 0x45, 0xae, 0xc7, 0x75, 0xd0, 0x84, 0x9c, 0x9c, 0x13, 0x9c, 0x51, 0x9c, 0x1e, 0x7a, 0x1e, +0x94, 0x7a, 0x17, 0xe4, 0x7e, 0xbf, 0x5d, 0xd8, 0x41, 0x76, 0xa7, 0x7a, 0x80, 0xe4, 0x7d, 0xf0, +0x2b, 0xce, 0xb5, 0xaf, 0x09, 0xe4, 0xbc, 0x91, 0xa6, 0xd6, 0x3d, 0x08, 0xe8, 0xd4, 0xd3, 0xb3, +0xb9, 0x8b, 0x3c, 0xc7, 0x51, 0xd2, 0x25, 0x81, 0xd9, 0x64, 0x46, 0x04, 0x67, 0xa8, 0xae, 0x5a, +0xe6, 0xcc, 0x8c, 0xe4, 0x1a, 0xdd, 0x3b, 0x99, 0x3d, 0x59, 0x89, 0x3c, 0x07, 0xbe, 0x7d, 0x70, +0x2b, 0x2a, 0x68, 0xba, 0xfb, 0xd3, 0x7a, 0xee, 0x45, 0xda, 0x33, 0x26, 0x43, 0xcf, 0x19, 0xac, +0xe9, 0x13, 0x9a, 0x77, 0xee, 0x3e, 0xa6, 0xa6, 0x99, 0x63, 0x8c, 0x5d, 0xc8, 0x32, 0x4f, 0x11, +0xa9, 0x1f, 0xad, 0x6f, 0x2a, 0x15, 0x07, 0x27, 0xe6, 0x3d, 0x6b, 0x09, 0xbb, 0xb2, 0xd6, 0x84, +0x4d, 0xd4, 0xd4, 0x4d, 0xdf, 0xde, 0xa0, 0xa2, 0x16, 0xe7, 0x39, 0xe8, 0x6a, 0xa3, 0xa1, 0x8f, +0x26, 0x3e, 0x54, 0xf5, 0x4f, 0xf0, 0xa3, 0xa8, 0x86, 0xab, 0xab, 0x82, 0x54, 0xe7, 0xb1, 0xf6, +0xa0, 0xfd, 0x3f, 0x1a, 0x7e, 0x62, 0xdc, 0x61, 0xcd, 0x56, 0x6c, 0xc9, 0x26, 0x3a, 0xaa, 0xf5, +0x3e, 0xa6, 0x8b, 0xea, 0x0c, 0x7e, 0x3f, 0xce, 0x68, 0xc5, 0x5a, 0x44, 0x31, 0x76, 0xe7, 0xd7, +0x8a, 0x5d, 0x99, 0xab, 0x44, 0x36, 0x34, 0xc2, 0x49, 0xdc, 0xb9, 0xdd, 0xfc, 0xe9, 0xe2, 0x32, +0xc3, 0x9c, 0x82, 0x3a, 0x8a, 0xd6, 0x31, 0xb9, 0x8b, 0x97, 0x72, 0x3f, 0x20, 0x92, 0xcc, 0x47, +0x5f, 0xe5, 0x50, 0xc9, 0x11, 0xe6, 0x93, 0x5a, 0x04, 0x65, 0x77, 0xa9, 0x51, 0xe3, 0xeb, 0x9a, +0xa8, 0xe8, 0x46, 0x6a, 0x1a, 0x34, 0x4f, 0xb1, 0x51, 0xd4, 0xf5, 0xaa, 0x33, 0xa6, 0xec, 0x01, +0xc1, 0x63, 0xd6, 0xa5, 0x6e, 0x5d, 0xd5, 0x88, 0x89, 0xcf, 0x07, 0x86, 0x1d, 0x8d, 0x57, 0x6e, +0xbd, 0x3f, 0x13, 0x4a, 0xd7, 0x2c, 0xae, 0xfe, 0x95, 0x55, 0xb9, 0xc9, 0x26, 0xa5, 0xee, 0x5a, +0x57, 0x2a, 0x1f, 0x99, 0x98, 0xfa, 0x77, 0xaa, 0xd3, 0x26, 0x0e, 0xe5, 0xeb, 0xdc, 0x7a, 0xd2, +0xb2, 0x7b, 0x96, 0xb6, 0x20, 0xc8, 0x39, 0x39, 0x3c, 0xfa, 0xd3, 0x1b, 0x8a, 0x5e, 0x65, 0xa6, +0x43, 0xd4, 0xb1, 0xc7, 0x7c, 0x66, 0x91, 0x87, 0xaf, 0x6e, 0x73, 0x41, 0x47, 0xec, 0x65, 0x23, +0x28, 0x60, 0x43, 0x00, 0xc0, 0xf6, 0x34, 0x19, 0x9c, 0xc6, 0xaf, 0xe1, 0xf8, 0x2f, 0x11, 0x8a, +0xa0, 0x24, 0xf6, 0x03, 0x91, 0xf4, 0xaf, 0x23, 0xd6, 0x3c, 0x3d, 0x35, 0xab, 0x31, 0xd8, 0x5d, +0x33, 0xf7, 0xf6, 0xf4, 0xfa, 0xd5, 0x45, 0xdb, 0x43, 0x29, 0xf7, 0x38, 0x3b, 0xdb, 0x22, 0xa4, +0x9d, 0xbf, 0xa5, 0x73, 0x77, 0x10, 0x10, 0x4e, 0x41, 0xad, 0xd6, 0xc6, 0x46, 0x1c, 0xf1, 0x7d, +0x78, 0xfd, 0x6a, 0x3b, 0x5b, 0x13, 0x73, 0x2e, 0x58, 0x11, 0x1a, 0x72, 0xc7, 0x1f, 0xa5, 0x26, +0xec, 0x8a, 0x8f, 0x63, 0xa1, 0x58, 0xc7, 0x5c, 0x00, 0x8a, 0x30, 0xa3, 0xd2, 0xa3, 0x6a, 0xe7, +0x6c, 0xd0, 0xae, 0xdd, 0x6a, 0xbb, 0x7a, 0x9a, 0x40, 0xc8, 0x49, 0xeb, 0x9a, 0x8d, 0x8f, 0x3f, +0x5f, 0x5a, 0x00, 0xac, 0xf1, 0xf3, 0xbd, 0x4e, 0x1b, 0xaf, 0xb1, 0xa8, 0xd5, 0xf7, 0x12, 0x1b, +0x2a, 0xdd, 0xd4, 0xd5, 0x6e, 0x4b, 0x1b, 0x23, 0x15, 0x1e, 0xa4, 0xf0, 0x28, 0x44, 0xda, 0x30, +0x7a, 0xf7, 0xf7, 0xa0, 0x4c, 0x78, 0x1f, 0x89, 0xa3, 0x1c, 0xe6, 0xad, 0x2b, 0x92, 0xd9, 0x20, +0x5f, 0xf2, 0x6a, 0x65, 0x88, 0x9f, 0xc7, 0xd6, 0xb6, 0x48, 0xc6, 0x6f, 0x42, 0xdc, 0x76, 0xc5, +0x8f, 0x4c, 0x92, 0x7d, 0x2b, 0xb3, 0xd0, 0x3c, 0x15, 0x7d, 0xe2, 0x09, 0xc4, 0x16, 0xc8, 0xa1, +0xb1, 0xb9, 0xa5, 0x93, 0x85, 0x41, 0xea, 0x4d, 0x6a, 0x95, 0x95, 0xce, 0x49, 0xc9, 0xb6, 0xa2, +0xb7, 0x64, 0x5a, 0xef, 0x83, 0xef, 0xf4, 0x49, 0xda, 0x0b, 0xb8, 0x4a, 0xb0, 0xe8, 0xc0, 0x65, +0x58, 0x7a, 0x83, 0xde, 0xb8, 0xc9, 0xec, 0xd9, 0x49, 0xc8, 0x3f, 0x95, 0x3b, 0x29, 0x2b, 0xa1, +0x46, 0x4d, 0x36, 0xa5, 0xb9, 0x93, 0x34, 0x07, 0x9e, 0x2b, 0x3a, 0x58, 0xc8, 0xcf, 0x04, 0xfe, +0x15, 0x94, 0xa2, 0x74, 0x42, 0x45, 0x19, 0x16, 0xa8, 0xb2, 0x92, 0xcc, 0x7b, 0x74, 0x04, 0xd6, +0x6f, 0x53, 0xa1, 0x3b, 0x95, 0x65, 0x5d, 0xde, 0xbb, 0xbb, 0x37, 0xa5, 0x53, 0x62, 0x79, 0x0c, +0x30, 0xc3, 0xbf, 0xad, 0x4b, 0x2b, 0xcc, 0x85, 0xf2, 0x73, 0xce, 0x73, 0x55, 0x5f, 0x82, 0x49, +0xfd, 0x6a, 0x59, 0xaa, 0x65, 0x51, 0xf7, 0x73, 0xce, 0x5f, 0x93, 0xcd, 0x42, 0xfd, 0xff, 0x00, +0xad, 0x4b, 0x65, 0xad, 0x4a, 0x72, 0xab, 0x64, 0xba, 0x8e, 0x47, 0x6f, 0x5a, 0x8b, 0x39, 0x52, +0x7f, 0x3a, 0x3a, 0x58, 0xa4, 0x31, 0x7a, 0x7b, 0x9a, 0x8d, 0xa5, 0x50, 0x4a, 0xb3, 0x0d, 0xc7, +0xa0, 0x34, 0x9e, 0xac, 0xd1, 0x3e, 0xe7, 0xec, 0x75, 0x14, 0x19, 0x05, 0x50, 0xbd, 0xd3, 0xe0, +0xbc, 0x46, 0x0c, 0xa3, 0x71, 0xef, 0x8e, 0xb4, 0x09, 0xab, 0xa3, 0xc9, 0xb5, 0xff, 0x00, 0x0b, +0xb4, 0x65, 0xde, 0x14, 0x00, 0xf3, 0x94, 0x3d, 0xfe, 0x95, 0xe5, 0x7a, 0x85, 0x83, 0x46, 0xcc, +0x19, 0x70, 0xc3, 0x8c, 0x1a, 0xde, 0x2e, 0xe8, 0xe7, 0x92, 0xb3, 0x39, 0x59, 0x6d, 0x1e, 0x49, +0x04, 0x68, 0xb9, 0x67, 0x38, 0x15, 0xa3, 0x1d, 0xa2, 0xc2, 0x82, 0x25, 0xfa, 0xbb, 0x7a, 0x9a, +0x53, 0x77, 0xd0, 0xa8, 0xae, 0xa3, 0x5d, 0x71, 0x91, 0x54, 0xe4, 0x1d, 0x6b, 0x26, 0x8b, 0xd0, +0xa8, 0xe3, 0xbf, 0x39, 0x3d, 0xea, 0xbb, 0x77, 0xa4, 0xd7, 0x51, 0xb2, 0x06, 0x1f, 0xfe, 0xba, +0x85, 0xbf, 0x3a, 0x09, 0xb8, 0xd2, 0x7f, 0x5a, 0x81, 0xd4, 0x36, 0x49, 0xe0, 0x8e, 0x8d, 0xe9, +0x4e, 0xe0, 0xf5, 0x2a, 0xa3, 0x96, 0x7c, 0xb9, 0xce, 0x38, 0x53, 0x8e, 0xb5, 0x67, 0x9f, 0xff, +0x00, 0x5d, 0x56, 0xc4, 0x0e, 0x15, 0x20, 0x5c, 0x9c, 0xd5, 0xa2, 0x24, 0xc9, 0xd1, 0x32, 0x7d, +0xea, 0xf4, 0x51, 0x6e, 0x3e, 0xb5, 0xb4, 0x55, 0xce, 0x7a, 0x8c, 0xe9, 0xf4, 0x9d, 0x38, 0xcf, +0x2a, 0x2e, 0x33, 0xce, 0x2b, 0xe9, 0xff, 0x00, 0x08, 0xe8, 0xd1, 0xe9, 0x5a, 0x72, 0xbe, 0xd0, +0x27, 0xba, 0x01, 0x99, 0xbd, 0xbb, 0x0f, 0xd6, 0xb4, 0xac, 0xf9, 0x29, 0xfa, 0x9c, 0xd8, 0x75, +0xed, 0x71, 0x09, 0x76, 0xd4, 0xd5, 0xd6, 0x34, 0x4b, 0x0d, 0x72, 0xdc, 0xc1, 0x7b, 0x16, 0xe2, +0x07, 0xc9, 0x2a, 0x9c, 0x32, 0x1f, 0x5a, 0xf9, 0xdf, 0xc5, 0xde, 0x0d, 0x9b, 0x47, 0x9b, 0x07, +0x12, 0x45, 0x20, 0xdc, 0x92, 0xae, 0x70, 0xc3, 0xfc, 0x6a, 0x30, 0xb5, 0x2f, 0xee, 0x33, 0x7c, +0x7d, 0x2f, 0x66, 0xfd, 0xb4, 0x7e, 0x7f, 0xe6, 0x79, 0x75, 0xe5, 0x8b, 0x21, 0x60, 0x46, 0x3d, +0x6b, 0x9f, 0xb8, 0x80, 0x8c, 0xf1, 0x5a, 0xce, 0x36, 0x31, 0xa7, 0x3e, 0x63, 0x1a, 0x74, 0xda, +0x09, 0xac, 0xe6, 0x4d, 0xa3, 0x9e, 0x4f, 0x73, 0x5c, 0xf2, 0x47, 0x6c, 0x59, 0x55, 0xd7, 0x39, +0xaa, 0x72, 0xa6, 0xef, 0xa8, 0xef, 0xe9, 0x59, 0xb4, 0x68, 0x99, 0x49, 0xb2, 0x1b, 0x6b, 0x75, +0xec, 0x7d, 0x6a, 0xac, 0xdc, 0x8d, 0xbc, 0xfc, 0xe7, 0x15, 0x06, 0xa8, 0x85, 0x86, 0x72, 0x01, +0xaa, 0xed, 0xc6, 0x7d, 0x73, 0x4b, 0x73, 0x55, 0x62, 0x17, 0xe4, 0x1e, 0x73, 0xef, 0x54, 0x65, +0x53, 0xd4, 0x1e, 0x4f, 0x50, 0x3b, 0xd2, 0x93, 0xb9, 0x49, 0x09, 0x9c, 0xf4, 0xec, 0x3a, 0x54, +0x4e, 0x8a, 0x5b, 0x7e, 0x06, 0x7a, 0x64, 0xd2, 0x96, 0xd6, 0x45, 0xa7, 0xd4, 0xfd, 0x8f, 0xa2, +0x83, 0x20, 0xa2, 0x80, 0x21, 0x9e, 0xde, 0x3b, 0x94, 0x29, 0x2a, 0xe4, 0x76, 0x3d, 0xc5, 0x79, +0x9f, 0x89, 0xbc, 0x32, 0xa5, 0x5a, 0x50, 0x38, 0x3f, 0x76, 0x50, 0x3f, 0x43, 0x4d, 0x3d, 0x48, +0x9a, 0xb9, 0xe4, 0xf2, 0x69, 0x9f, 0x64, 0x67, 0x66, 0x01, 0xa6, 0x62, 0x40, 0xe7, 0xa0, 0xac, +0xd9, 0x63, 0xda, 0x08, 0xee, 0x7a, 0x93, 0x56, 0xdd, 0xc9, 0x8e, 0x88, 0xca, 0x98, 0x72, 0x7a, +0xe7, 0xd6, 0xb3, 0xe4, 0xa8, 0x96, 0xa3, 0x2a, 0x3f, 0x7a, 0xaa, 0xdc, 0xfb, 0xd2, 0x60, 0x42, +0xf5, 0x0b, 0x7a, 0xf7, 0xa2, 0xe2, 0xf3, 0x22, 0x26, 0xab, 0xca, 0xc4, 0xe1, 0x17, 0xef, 0x37, +0x5f, 0x61, 0x47, 0x5d, 0x49, 0x7a, 0x86, 0xc5, 0xdb, 0xb7, 0xa8, 0xed, 0x4c, 0xcb, 0x47, 0xc1, +0x25, 0x93, 0xfb, 0xdd, 0xc5, 0x68, 0xb5, 0x13, 0x65, 0x85, 0x39, 0xc1, 0xcf, 0x5e, 0xf5, 0x61, +0x06, 0x4f, 0x26, 0xad, 0x19, 0x49, 0xdc, 0xb9, 0x12, 0xe6, 0xb6, 0x6d, 0x20, 0x2c, 0x46, 0x46, +0x73, 0xd2, 0xba, 0x60, 0x8e, 0x4a, 0x92, 0xd0, 0xf6, 0x4f, 0x04, 0x68, 0x7f, 0x69, 0xb9, 0x89, +0x9d, 0x4f, 0x96, 0xa7, 0x2c, 0xdf, 0x85, 0x7b, 0xc0, 0x01, 0x40, 0x51, 0xc0, 0x03, 0x00, 0x54, +0x63, 0x1d, 0x9a, 0x88, 0xf2, 0xb5, 0xcc, 0xe7, 0x3f, 0x90, 0xb5, 0x52, 0xf6, 0xc6, 0xd7, 0x50, +0x85, 0xe0, 0xbb, 0x85, 0x66, 0x8d, 0xc6, 0x30, 0xc3, 0x91, 0xee, 0x0d, 0x71, 0xa9, 0x38, 0xbb, +0xa3, 0xd5, 0x9c, 0x23, 0x52, 0x2e, 0x32, 0x57, 0x47, 0x81, 0x78, 0xd3, 0xc1, 0xad, 0xa7, 0x4a, +0xd2, 0xdb, 0x24, 0x92, 0xda, 0x48, 0x7e, 0x59, 0x31, 0x9d, 0xbe, 0xc7, 0xde, 0xbc, 0x66, 0xfe, +0xc9, 0xa3, 0x66, 0x04, 0x11, 0x83, 0x5e, 0xa2, 0x97, 0xb5, 0x87, 0x31, 0xe0, 0xa4, 0xe8, 0xd4, +0x74, 0xdf, 0x43, 0x94, 0xba, 0x84, 0xee, 0xc7, 0x3e, 0xa6, 0xb2, 0x66, 0x4e, 0x7f, 0xc6, 0xb9, +0xe5, 0xa1, 0xdd, 0x4d, 0xdd, 0x19, 0xf2, 0x03, 0xcd, 0x52, 0x93, 0xbd, 0x60, 0xd5, 0xce, 0x85, +0x2d, 0x35, 0x29, 0xca, 0xa0, 0x8f, 0x9b, 0xa5, 0x66, 0xb9, 0xfd, 0xe8, 0x46, 0xcf, 0x4e, 0x0f, +0xad, 0x4b, 0x57, 0xdc, 0xd1, 0x3b, 0xec, 0x31, 0x8f, 0xe8, 0x2a, 0x06, 0xf5, 0xa9, 0xb5, 0xf7, +0x34, 0x4f, 0xb9, 0x5c, 0xf5, 0x3c, 0xf3, 0x50, 0x3e, 0x4b, 0x76, 0xa4, 0x68, 0xb6, 0xb9, 0x5d, +0x87, 0x3b, 0x86, 0x72, 0x7b, 0x7a, 0xd4, 0x6c, 0xd9, 0xe6, 0xa6, 0xe5, 0xec, 0xcf, 0xd8, 0xfa, +0x29, 0x99, 0x05, 0x14, 0x00, 0x55, 0x6b, 0xc1, 0x19, 0xb6, 0x9f, 0xcd, 0x0a, 0xc9, 0xb0, 0xe7, +0x70, 0xcd, 0x02, 0x7b, 0x1f, 0x3f, 0xeb, 0x09, 0xb6, 0x56, 0x60, 0x32, 0x3d, 0x3d, 0x2b, 0x93, +0x9d, 0x95, 0xb7, 0x11, 0xcf, 0xa8, 0xf4, 0xad, 0x08, 0x46, 0x34, 0xdd, 0xeb, 0x36, 0x4e, 0xa6, +0xa1, 0xb1, 0x94, 0xdf, 0x3c, 0xf7, 0xaa, 0xcd, 0x40, 0x75, 0x20, 0x63, 0x50, 0xb7, 0x5e, 0x7f, +0x5a, 0x4d, 0x88, 0x85, 0xdb, 0x00, 0xb1, 0x3c, 0x63, 0xa9, 0xaa, 0xe9, 0x92, 0x5a, 0x46, 0xea, +0xdd, 0x3d, 0x85, 0x52, 0xee, 0x49, 0x26, 0x47, 0xe3, 0x49, 0xd7, 0xdc, 0x1a, 0xa4, 0x43, 0xd7, +0x51, 0x14, 0x14, 0x24, 0xae, 0x48, 0xcf, 0x2b, 0x57, 0x22, 0x60, 0xdc, 0x8f, 0xcb, 0xd2, 0xb6, +0x89, 0x8c, 0x9e, 0x86, 0xa4, 0x03, 0x27, 0xeb, 0xeb, 0x5d, 0x7e, 0x91, 0x68, 0x66, 0x91, 0x06, +0x09, 0xcf, 0xb5, 0x75, 0x52, 0x8f, 0x63, 0x83, 0x11, 0x3d, 0x0f, 0xa5, 0xfc, 0x2d, 0xa7, 0x2d, +0x8d, 0x82, 0xb9, 0x5c, 0x49, 0x2f, 0x39, 0xc7, 0x38, 0xae, 0xa2, 0xb8, 0xb1, 0x32, 0xe6, 0xa8, +0xcf, 0x47, 0x2f, 0xa7, 0xec, 0xe8, 0x47, 0xcf, 0x5f, 0xbc, 0x28, 0xac, 0x0e, 0xd2, 0x39, 0x62, +0x8a, 0x74, 0x68, 0xa6, 0x8d, 0x25, 0x8d, 0xc6, 0x19, 0x24, 0x19, 0x07, 0xf0, 0xaf, 0x04, 0xf8, +0x83, 0xe0, 0xcf, 0xb1, 0xef, 0xd4, 0x2c, 0x20, 0x66, 0xb2, 0x7e, 0x5c, 0x22, 0x93, 0xe4, 0x1f, +0x7f, 0x6c, 0xd7, 0x56, 0x1a, 0xa7, 0x2c, 0xb9, 0x5e, 0xcc, 0xe0, 0xc7, 0xd1, 0xe7, 0x8f, 0xb4, +0x4b, 0x55, 0xf9, 0x1f, 0x3e, 0x5e, 0x41, 0x86, 0x72, 0x47, 0x5f, 0x6a, 0xe7, 0x67, 0x8f, 0x04, +0xff, 0x00, 0x2a, 0xda, 0xa2, 0xd4, 0xc6, 0x93, 0xba, 0x32, 0xa5, 0x53, 0xcf, 0x7f, 0x7a, 0xcf, +0x90, 0x75, 0xfe, 0xb5, 0xce, 0xce, 0x94, 0x52, 0x93, 0xf1, 0xaa, 0x05, 0x77, 0x06, 0x2c, 0x33, +0xb8, 0xe7, 0x9a, 0x89, 0x36, 0xd9, 0xb4, 0x7c, 0x8a, 0xaf, 0xb9, 0x09, 0x0c, 0x72, 0xa4, 0xf0, +0xd5, 0x1b, 0x63, 0xaf, 0xaf, 0x7a, 0x86, 0xcd, 0x11, 0x03, 0x1f, 0xff, 0x00, 0x5d, 0x57, 0xea, +0xcc, 0x73, 0xed, 0x93, 0x49, 0xbe, 0xa6, 0xa8, 0x89, 0xbb, 0xf2, 0x33, 0x55, 0x25, 0xc8, 0xcb, +0x0c, 0x73, 0xd4, 0x52, 0x77, 0xb9, 0x49, 0xf3, 0x68, 0xcf, 0xd9, 0x2a, 0x28, 0x32, 0x0a, 0x28, +0x00, 0xae, 0x73, 0xc4, 0x37, 0xc2, 0x0b, 0x73, 0x10, 0x3f, 0x33, 0x72, 0x71, 0x4d, 0x6a, 0xc5, +0x27, 0xa1, 0xe3, 0x1a, 0x94, 0x9b, 0x8b, 0x9c, 0xfe, 0x75, 0xc6, 0xdd, 0xaf, 0xcc, 0x59, 0x4e, +0xd6, 0xfe, 0x75, 0x77, 0x26, 0xdd, 0x4c, 0x69, 0x25, 0xc9, 0xda, 0xfc, 0x37, 0xe8, 0x6a, 0x94, +0x8d, 0xd7, 0x9a, 0x96, 0x0c, 0xa8, 0xe7, 0x39, 0xcd, 0x56, 0x63, 0xc9, 0xfe, 0xb4, 0xae, 0x27, +0x72, 0xbb, 0x1c, 0x9a, 0x88, 0xf5, 0xa5, 0xd2, 0xec, 0x1e, 0xac, 0xab, 0x29, 0xde, 0xe2, 0x3c, +0xe4, 0x75, 0x63, 0x4a, 0x71, 0x54, 0x4e, 0xe3, 0x0d, 0x00, 0xd5, 0x22, 0x1e, 0x84, 0xaa, 0x7b, +0xd4, 0xea, 0xbc, 0xee, 0x5e, 0x18, 0xf5, 0xf7, 0xad, 0xa2, 0x63, 0x37, 0x74, 0x6c, 0x59, 0xb0, +0x66, 0x00, 0xf0, 0xde, 0x86, 0xbd, 0x6f, 0xc1, 0x9a, 0x7f, 0xda, 0xee, 0xe0, 0x4c, 0x67, 0x71, +0xfc, 0xb9, 0xae, 0xca, 0x56, 0x5a, 0x9e, 0x5e, 0x25, 0xb6, 0xac, 0x8f, 0xa3, 0x91, 0x16, 0x34, +0x54, 0x51, 0x85, 0x51, 0x80, 0x29, 0xd5, 0xe5, 0x49, 0xf3, 0x3b, 0xb3, 0xe8, 0x21, 0x05, 0x08, +0xa8, 0xae, 0x81, 0x45, 0x22, 0xc2, 0xb8, 0xef, 0x1d, 0x5e, 0x0b, 0x6d, 0x02, 0xe2, 0x1c, 0xfc, +0xf7, 0xa4, 0x44, 0x07, 0xb7, 0x53, 0xfc, 0xb1, 0xf8, 0xd6, 0x94, 0xa3, 0xcd, 0x34, 0x8c, 0x71, +0x33, 0xf6, 0x74, 0xa5, 0x2f, 0x23, 0xe4, 0x3d, 0x51, 0x30, 0xee, 0x47, 0x4c, 0x9e, 0x2b, 0x92, +0xb9, 0x5e, 0xbe, 0xfe, 0xb5, 0xe8, 0x54, 0x5a, 0x9e, 0x65, 0x0b, 0xa4, 0x8c, 0x79, 0x81, 0xe6, +0xb3, 0x65, 0x15, 0xc9, 0x25, 0xa9, 0xda, 0xb5, 0x46, 0x6c, 0xfc, 0x29, 0x23, 0xf3, 0x35, 0x55, +0x87, 0x6e, 0xb5, 0x9b, 0x46, 0xdd, 0x34, 0x2a, 0xb8, 0x07, 0x20, 0xf3, 0x54, 0xdb, 0x29, 0xdf, +0x29, 0xd8, 0xfa, 0x54, 0x34, 0xde, 0xc6, 0x8b, 0x5d, 0x08, 0xdf, 0xb9, 0xeb, 0xef, 0x50, 0x0e, +0x99, 0xcf, 0xde, 0xe6, 0x94, 0x9e, 0xa6, 0x91, 0xb3, 0x22, 0x60, 0x7b, 0x1a, 0xa7, 0x31, 0x38, +0x27, 0xd0, 0x75, 0xa4, 0x5f, 0x99, 0xfb, 0x25, 0x45, 0x06, 0x41, 0x45, 0x00, 0x43, 0x3c, 0xcb, +0x04, 0x6f, 0x23, 0x9e, 0x14, 0x67, 0xeb, 0x5e, 0x57, 0xae, 0x6a, 0x06, 0x79, 0x64, 0x62, 0xdd, +0x4f, 0x1c, 0xd3, 0x44, 0xc8, 0xf3, 0xdb, 0xd9, 0x72, 0x5b, 0x9c, 0xd7, 0x39, 0x70, 0xfd, 0x6a, +0xb7, 0x11, 0x89, 0x70, 0x03, 0x67, 0x3d, 0x3d, 0x7d, 0x2b, 0x31, 0xdd, 0xe3, 0x38, 0x7c, 0xb2, +0xff, 0x00, 0x7b, 0xd2, 0x90, 0x3d, 0x88, 0x99, 0xc3, 0x72, 0x0e, 0x47, 0xad, 0x42, 0xcd, 0xf5, +0xa9, 0xbe, 0xa1, 0x62, 0x06, 0x39, 0xea, 0x6a, 0xbc, 0x8e, 0x14, 0x16, 0x3f, 0xfe, 0xba, 0x62, +0x20, 0x40, 0x40, 0xc9, 0xfb, 0xcc, 0x72, 0x69, 0x58, 0x9f, 0xeb, 0x4f, 0x72, 0x06, 0x13, 0xeb, +0xff, 0x00, 0xeb, 0xa0, 0x75, 0xeb, 0x54, 0x26, 0x99, 0x2a, 0x9a, 0xb3, 0x19, 0xe7, 0xff, 0x00, +0xaf, 0x5a, 0xc5, 0x98, 0xcf, 0x63, 0x5a, 0xdf, 0x1b, 0x81, 0x27, 0x07, 0x3c, 0x1f, 0x4a, 0xf7, +0x9f, 0x86, 0x37, 0x36, 0xdf, 0x6d, 0x91, 0x27, 0x74, 0x59, 0x4c, 0x24, 0x44, 0x58, 0xe3, 0x73, +0x6e, 0x1c, 0x0f, 0x7c, 0x66, 0xba, 0x53, 0x6e, 0x0e, 0xc7, 0x0c, 0xd4, 0x79, 0xe2, 0xe7, 0xb5, +0xcf, 0x73, 0xa2, 0xbc, 0xd3, 0xdc, 0x0a, 0x28, 0x00, 0xaf, 0x1b, 0xf8, 0x8f, 0xa9, 0x17, 0x98, +0x5a, 0x06, 0x05, 0x2d, 0x87, 0x40, 0x7b, 0x91, 0x93, 0xfe, 0x7d, 0xab, 0xab, 0x09, 0x1e, 0x6a, +0x89, 0x9c, 0x39, 0x8c, 0xad, 0x46, 0xdd, 0xda, 0xff, 0x00, 0x33, 0xe7, 0xad, 0x41, 0xb7, 0x13, +0x5c, 0x95, 0xd0, 0x39, 0x62, 0x3f, 0x11, 0x5d, 0x75, 0x1e, 0xa7, 0x25, 0x1d, 0x91, 0x8b, 0x29, +0xeb, 0x8e, 0xbe, 0x9d, 0xeb, 0x36, 0x5e, 0xe6, 0xb9, 0x27, 0x73, 0xb6, 0x2f, 0x43, 0x36, 0x5e, +0x58, 0x7e, 0x75, 0x52, 0x4c, 0xfa, 0xf5, 0xac, 0x9b, 0xb9, 0xb2, 0x2b, 0x37, 0x5f, 0x5f, 0x7a, +0xac, 0xe3, 0xf5, 0xf5, 0xa8, 0x66, 0x89, 0x5f, 0x62, 0x93, 0x86, 0x8c, 0x1e, 0xa5, 0x5b, 0x81, +0xed, 0x48, 0x47, 0x03, 0xbf, 0x6a, 0x4c, 0xd6, 0x3d, 0x99, 0x13, 0xf4, 0x24, 0x9e, 0x47, 0xeb, +0x54, 0x2e, 0x0f, 0xca, 0x79, 0xeb, 0x52, 0xf4, 0x2d, 0x6a, 0x7e, 0xc9, 0xd1, 0x4c, 0xc4, 0x28, +0x27, 0x19, 0x24, 0xfe, 0x34, 0x01, 0xc4, 0xeb, 0xda, 0xa0, 0x20, 0xc7, 0x1b, 0x1d, 0xab, 0x9f, +0xc6, 0xbc, 0xc2, 0xfe, 0xeb, 0x71, 0x6e, 0x4f, 0x3d, 0xea, 0x91, 0x3e, 0x67, 0x29, 0x75, 0x36, +0x73, 0xcd, 0x61, 0xcf, 0x21, 0x39, 0xe6, 0x95, 0xc3, 0x63, 0x32, 0x46, 0xc9, 0xe7, 0x35, 0x49, +0xd8, 0x1e, 0xbd, 0xe8, 0x60, 0x67, 0xb8, 0x64, 0x25, 0xa3, 0xe4, 0x13, 0x92, 0xbe, 0xb5, 0x18, +0x99, 0x5f, 0x38, 0xc8, 0x6e, 0xea, 0x7a, 0x8a, 0x1e, 0xa4, 0x8c, 0x63, 0x55, 0x19, 0xbc, 0xc7, +0xe7, 0xee, 0xa7, 0x3f, 0x53, 0x4e, 0xf7, 0x01, 0xc4, 0x9a, 0x8d, 0x9a, 0x86, 0x4b, 0x76, 0x1a, +0x4f, 0x7f, 0x6a, 0xc9, 0x37, 0xf2, 0x0b, 0xcf, 0x23, 0x63, 0x15, 0xce, 0x3a, 0x7e, 0xb5, 0x69, +0x73, 0x11, 0x27, 0x63, 0x69, 0x4f, 0xad, 0x58, 0x46, 0xad, 0x11, 0x9c, 0x8b, 0xf1, 0xcb, 0xb4, +0x67, 0xf2, 0xae, 0xb3, 0x46, 0xd4, 0xe4, 0xb5, 0x64, 0x21, 0xc8, 0x60, 0x73, 0x9c, 0xf3, 0x5d, +0x34, 0x99, 0xc3, 0x5e, 0x1c, 0xca, 0xc7, 0xd0, 0x7e, 0x18, 0xf1, 0x9a, 0x5d, 0xaa, 0xdb, 0x6a, +0x32, 0xe5, 0xd8, 0xe1, 0x6e, 0x1b, 0xe9, 0xd0, 0xff, 0x00, 0x8d, 0x7a, 0x38, 0x21, 0x80, 0x20, +0xe4, 0x1e, 0x41, 0x1d, 0xeb, 0x9b, 0x13, 0x4b, 0x92, 0x5c, 0xcb, 0x66, 0x75, 0xe0, 0x31, 0x0e, +0xac, 0x39, 0x25, 0xba, 0x16, 0x8a, 0xe6, 0x3d, 0x02, 0x29, 0xe5, 0x10, 0x43, 0x34, 0xcd, 0xc8, +0x89, 0x0b, 0x9e, 0x7a, 0xe0, 0x66, 0xbe, 0x63, 0xf1, 0x4d, 0xfb, 0x5c, 0xdd, 0x4d, 0x23, 0x36, +0x4b, 0x31, 0x26, 0xbd, 0x0c, 0x0a, 0xf8, 0xa4, 0x79, 0x39, 0x94, 0xb9, 0xa5, 0x08, 0x7a, 0xb3, +0xcc, 0x6f, 0x1f, 0x25, 0x8e, 0x7f, 0x3a, 0xe6, 0xae, 0x4f, 0xde, 0xe7, 0xa9, 0xad, 0x2a, 0x6e, +0x2a, 0x68, 0xc3, 0xb9, 0xe7, 0x24, 0x1f, 0x9b, 0xd4, 0xf7, 0xac, 0x99, 0x1b, 0x39, 0x07, 0xae, +0x79, 0x15, 0xcb, 0x2d, 0x8e, 0xb8, 0xab, 0x94, 0x1b, 0x96, 0x66, 0xcf, 0xb7, 0x35, 0x59, 0xcf, +0xe7, 0x8a, 0xce, 0x5e, 0x46, 0xe9, 0x15, 0x98, 0xf5, 0xfe, 0x75, 0x55, 0xb3, 0x8a, 0x86, 0x5a, +0xd1, 0x95, 0xa4, 0xf9, 0x99, 0x47, 0xe3, 0xcf, 0x6a, 0x88, 0xe5, 0x09, 0xc6, 0x4a, 0xe7, 0x3f, +0x4a, 0x89, 0x3b, 0xbd, 0x0d, 0x63, 0xaa, 0xbb, 0x22, 0x73, 0x9e, 0x6b, 0x2e, 0xe5, 0xb2, 0x54, +0x73, 0xc9, 0xcf, 0x34, 0x5e, 0xdb, 0x94, 0xde, 0xb7, 0x3f, 0x66, 0x28, 0xa0, 0xc8, 0x2b, 0x9d, +0xd6, 0xb5, 0x44, 0xb7, 0x8c, 0xc4, 0xae, 0x37, 0x1e, 0xa6, 0x80, 0x3c, 0xa7, 0x51, 0xd4, 0x37, +0x96, 0x25, 0xba, 0xd7, 0x23, 0x75, 0x73, 0x9d, 0xd9, 0x35, 0x57, 0x13, 0xf2, 0x30, 0x2e, 0x26, +0xce, 0x7b, 0xd6, 0x5c, 0xb2, 0x67, 0x27, 0xf9, 0xd3, 0xd3, 0x70, 0xd4, 0xa2, 0xef, 0xd7, 0x9a, +0xa8, 0xed, 0xd7, 0x9a, 0x86, 0x22, 0xb3, 0x37, 0x7c, 0xd5, 0x39, 0x10, 0x39, 0xdd, 0xd1, 0xbb, +0x30, 0xa7, 0xd4, 0x4c, 0xaa, 0xd3, 0x48, 0x99, 0x57, 0x1f, 0x31, 0xe1, 0x5c, 0x74, 0x34, 0xe5, +0xc2, 0xa8, 0x1d, 0x7b, 0xe7, 0xd6, 0x9f, 0x91, 0x3b, 0xea, 0x21, 0x6e, 0xbf, 0xd6, 0x98, 0x48, +0xfa, 0xd1, 0x7b, 0x89, 0xab, 0x6a, 0x26, 0x73, 0x93, 0x51, 0xf9, 0x48, 0x5f, 0xcd, 0x2a, 0x3c, +0xc0, 0x31, 0xbb, 0x1c, 0xd5, 0x27, 0xd4, 0x52, 0x57, 0xd0, 0xb2, 0xbe, 0xb5, 0x2a, 0xb7, 0x3e, +0xf5, 0xa2, 0x66, 0x52, 0xd0, 0x95, 0x1b, 0x73, 0x81, 0x9e, 0x07, 0x26, 0xb4, 0xe2, 0x9c, 0x82, +0x39, 0xad, 0xe2, 0xce, 0x69, 0xc6, 0xe7, 0x4d, 0x61, 0xa9, 0xb4, 0x25, 0x48, 0x6c, 0x57, 0xb2, +0xf8, 0x53, 0xc6, 0x7e, 0x41, 0x4b, 0x7b, 0xb7, 0xdf, 0x6c, 0xf8, 0x19, 0x39, 0x26, 0x3f, 0x71, +0x5d, 0x2e, 0x2a, 0xac, 0x5c, 0x19, 0xe7, 0xb9, 0x3a, 0x15, 0x15, 0x58, 0xf4, 0xfc, 0x8f, 0x60, +0xb7, 0xb9, 0x82, 0xee, 0x25, 0x9e, 0xde, 0x55, 0x9a, 0x27, 0xe8, 0xe8, 0x6a, 0x7a, 0xf2, 0x65, +0x17, 0x17, 0x66, 0x7d, 0x14, 0x2a, 0x46, 0xac, 0x54, 0xa2, 0xf4, 0x67, 0x1b, 0xe3, 0x5d, 0x49, +0x6c, 0xb4, 0xc3, 0x08, 0x60, 0x24, 0xb9, 0xce, 0x46, 0x7f, 0x84, 0x7f, 0xf5, 0xff, 0x00, 0x95, +0x7c, 0xcd, 0xaa, 0xdd, 0x79, 0x8e, 0xec, 0x4e, 0x49, 0x3d, 0x6b, 0xd3, 0xc2, 0x2b, 0x52, 0xf5, +0x67, 0x91, 0x8b, 0x6a, 0x78, 0x8f, 0x45, 0x6f, 0xd4, 0xe3, 0xae, 0xa4, 0xc9, 0x26, 0xb0, 0xae, +0x1f, 0x93, 0xeb, 0x53, 0x37, 0x7d, 0x4d, 0x69, 0xa3, 0x1a, 0x76, 0xc9, 0x35, 0x91, 0x71, 0x8e, +0x4f, 0x71, 0xde, 0xb9, 0x64, 0xce, 0xb8, 0xa4, 0x50, 0xde, 0x00, 0xc1, 0xe1, 0xba, 0xf3, 0xde, +0xa0, 0x7a, 0xce, 0x4f, 0x5d, 0x4d, 0xa2, 0xb4, 0xb1, 0x5d, 0x8f, 0x3d, 0xaa, 0xb3, 0x72, 0x7a, +0xfd, 0x2a, 0x1a, 0x5b, 0x9a, 0x26, 0x56, 0xe1, 0x9c, 0x9e, 0x0e, 0x38, 0xcd, 0x04, 0x70, 0x79, +0xeb, 0xda, 0xa5, 0xab, 0x1a, 0x2e, 0xc5, 0x29, 0x06, 0xde, 0x47, 0x2b, 0xdc, 0x77, 0x15, 0x95, +0x3b, 0x03, 0x27, 0x07, 0xa7, 0x71, 0x43, 0xec, 0x57, 0xa9, 0xfb, 0x37, 0x45, 0x06, 0x26, 0x3e, +0xad, 0xa9, 0xc7, 0x63, 0x0b, 0x00, 0xc3, 0xcd, 0x61, 0xd3, 0x3d, 0x2b, 0xc9, 0x35, 0x4d, 0x51, +0xa5, 0x76, 0x62, 0xe4, 0x93, 0xea, 0x68, 0xdc, 0x67, 0x1d, 0x75, 0x76, 0x58, 0x9f, 0x9b, 0xf1, +0xcd, 0x61, 0x4f, 0x3f, 0x5e, 0x7f, 0x5a, 0x68, 0x19, 0x93, 0x2c, 0xd9, 0xce, 0x4f, 0x5a, 0xa0, +0xef, 0xd7, 0x9a, 0x6c, 0x94, 0x54, 0x77, 0xe4, 0xd5, 0x67, 0x7f, 0x7c, 0xe6, 0x90, 0x8a, 0xcc, +0xdf, 0xcb, 0xbd, 0x42, 0xcd, 0xfe, 0x4d, 0x0c, 0x2e, 0x54, 0xcf, 0x9a, 0x4b, 0x30, 0xca, 0xf4, +0x50, 0x7f, 0x9d, 0x34, 0xef, 0x8f, 0x91, 0x97, 0x4f, 0x4e, 0xe2, 0x82, 0x58, 0x07, 0x0d, 0xc8, +0x39, 0xfe, 0x94, 0x12, 0x7e, 0xb4, 0xfd, 0x49, 0x6c, 0x4e, 0x73, 0xd7, 0x9a, 0x90, 0x77, 0xaa, +0x4f, 0x52, 0x5e, 0xa8, 0x50, 0x79, 0xfe, 0xb4, 0xf2, 0xd8, 0x19, 0x26, 0xaa, 0x3a, 0x91, 0x21, +0xf1, 0x92, 0x06, 0x7f, 0x88, 0xf2, 0x4d, 0x59, 0x59, 0x31, 0xd4, 0xfd, 0x2b, 0x54, 0xcc, 0x24, +0x8b, 0xb1, 0x5c, 0x60, 0xfd, 0xee, 0x7d, 0xeb, 0x6e, 0xd3, 0x51, 0x68, 0x88, 0x21, 0xbf, 0x5a, +0xe9, 0x84, 0x8e, 0x69, 0xc3, 0x98, 0xf4, 0xbf, 0x0d, 0xf8, 0xd6, 0x7d, 0x36, 0x45, 0x3e, 0x61, +0x92, 0x26, 0x1f, 0x3c, 0x2e, 0xdf, 0x2b, 0x7f, 0xf5, 0xfd, 0xeb, 0xdd, 0xb4, 0x8d, 0x7f, 0x4d, +0xd6, 0xe3, 0xdf, 0x67, 0x70, 0x86, 0x55, 0x19, 0x7b, 0x77, 0x61, 0xbd, 0x3d, 0xf1, 0xdc, 0x73, +0xd6, 0xb2, 0xc5, 0x53, 0xe6, 0x5c, 0xe8, 0xd3, 0x03, 0x55, 0xd2, 0x97, 0xb2, 0x96, 0xcf, 0x63, +0xc2, 0xbc, 0x77, 0xe2, 0x4f, 0xb7, 0xea, 0x37, 0x08, 0x92, 0x2b, 0x41, 0x6e, 0xcd, 0x0c, 0x66, +0x36, 0xca, 0xb2, 0x83, 0xd7, 0x3e, 0xfd, 0x7f, 0x1a, 0xf2, 0x2b, 0xbb, 0x92, 0xec, 0xc7, 0x35, +0xd1, 0x1f, 0x72, 0x9a, 0x4b, 0xb1, 0x8f, 0xc7, 0x52, 0x52, 0xee, 0xcc, 0x09, 0xe5, 0xce, 0x4e, +0x6b, 0x1e, 0x77, 0xeb, 0x58, 0x4d, 0x9d, 0x90, 0x5d, 0x4c, 0x89, 0x9b, 0x39, 0xe7, 0xa5, 0x65, +0xce, 0xd9, 0xc0, 0xfe, 0xf1, 0xae, 0x69, 0x35, 0x73, 0xa6, 0x25, 0x59, 0x4e, 0x73, 0xfc, 0xfd, +0x2a, 0xa1, 0x7c, 0x1c, 0x37, 0xe7, 0x52, 0xf5, 0x35, 0x8b, 0x22, 0x63, 0xdf, 0x3d, 0x2a, 0xbb, +0xfa, 0xff, 0x00, 0x33, 0x50, 0xee, 0xcb, 0xd1, 0x15, 0xd7, 0x95, 0xdd, 0xce, 0x5b, 0x9f, 0x5a, +0x46, 0xe3, 0xff, 0x00, 0xaf, 0xda, 0x93, 0xf2, 0x2f, 0x47, 0xb1, 0x5e, 0x41, 0xc1, 0xf7, 0x1d, +0xab, 0x0e, 0x55, 0x3e, 0x63, 0xe4, 0x63, 0x9e, 0xf5, 0x09, 0xdf, 0x43, 0x47, 0x63, 0xf6, 0x76, +0xb3, 0x35, 0x4d, 0x4e, 0x1d, 0x3a, 0x06, 0x77, 0x60, 0x65, 0x61, 0xf2, 0x27, 0xaf, 0xbd, 0x36, +0xcc, 0x0f, 0x1d, 0xd5, 0xf5, 0xb7, 0xb9, 0x91, 0xd9, 0x9c, 0x92, 0x49, 0xe7, 0x35, 0xc5, 0xdd, +0x5e, 0x13, 0xb8, 0xee, 0xcd, 0x38, 0xa1, 0xdb, 0x53, 0x0e, 0x6b, 0x82, 0x73, 0xc9, 0xac, 0xb9, +0x66, 0xce, 0x49, 0x26, 0xa8, 0x1f, 0x99, 0x46, 0x49, 0x0f, 0x27, 0xf5, 0xaa, 0x8e, 0xf9, 0xcf, +0x5a, 0x2e, 0x22, 0xab, 0xbf, 0x3d, 0x6a, 0xbb, 0x3e, 0x73, 0xdb, 0xde, 0x90, 0x99, 0x0b, 0x3f, +0x3d, 0x79, 0xf5, 0xaa, 0xb3, 0x31, 0x62, 0x10, 0x1f, 0x99, 0x8f, 0x27, 0xd0, 0x50, 0x21, 0x72, +0x00, 0x00, 0x7d, 0x38, 0xa4, 0x27, 0xde, 0x87, 0xb8, 0x5c, 0x89, 0x93, 0x9d, 0xc8, 0x70, 0xdd, +0xfd, 0x0d, 0x22, 0xc9, 0x9e, 0x18, 0x10, 0xdd, 0xc5, 0x51, 0x0f, 0x42, 0x41, 0x9a, 0x93, 0xaf, +0x34, 0xc9, 0x17, 0x1d, 0xe9, 0x87, 0xe6, 0x70, 0xb9, 0xe0, 0x72, 0x6a, 0x93, 0xe8, 0x43, 0xbf, +0x52, 0x6d, 0xd8, 0x34, 0x6e, 0xe6, 0xad, 0x10, 0xd5, 0xc7, 0x89, 0x31, 0xd6, 0xac, 0x2d, 0xc6, +0x0e, 0x73, 0xff, 0x00, 0xd6, 0xad, 0x53, 0xd0, 0xca, 0x51, 0xea, 0x5b, 0x8e, 0xf5, 0x97, 0xa3, +0x1a, 0xd1, 0x4d, 0x6a, 0x78, 0x72, 0xd1, 0xcc, 0xe8, 0xd8, 0xc6, 0xe5, 0x38, 0xad, 0xa3, 0x36, +0x73, 0xce, 0x17, 0x28, 0x4b, 0xa8, 0xb4, 0x84, 0xef, 0x63, 0x93, 0xdc, 0xf7, 0xac, 0xd9, 0x67, +0xea, 0x73, 0x4e, 0x52, 0x2e, 0x11, 0x32, 0xe5, 0x97, 0x3d, 0xeb, 0x2e, 0x69, 0x3a, 0xf3, 0x93, +0x5c, 0xf2, 0x67, 0x54, 0x51, 0x99, 0x2b, 0x7a, 0x9f, 0x7a, 0xcf, 0x73, 0xb9, 0xcf, 0x39, 0xda, +0x3f, 0x2a, 0xc4, 0xdd, 0x2d, 0x6c, 0x57, 0x63, 0x93, 0x90, 0x4f, 0xe3, 0x55, 0x9f, 0x04, 0x60, +0x8c, 0xe7, 0xd6, 0xa1, 0xdf, 0xa9, 0xa2, 0x65, 0x66, 0x3b, 0x49, 0xce, 0x71, 0xd0, 0x54, 0x12, +0x9c, 0x21, 0xc6, 0x70, 0x7d, 0x69, 0x3d, 0x75, 0x45, 0x68, 0x84, 0xc1, 0x0b, 0x81, 0xd7, 0x18, +0xcf, 0xad, 0x44, 0xdd, 0x79, 0xe9, 0xd0, 0x83, 0x53, 0x6e, 0x86, 0x8b, 0x62, 0x07, 0xef, 0x59, +0xb3, 0xa1, 0x73, 0x8e, 0x84, 0x56, 0x6e, 0xe6, 0xbb, 0x9f, 0xa9, 0x47, 0xc7, 0xb1, 0x8b, 0x79, +0x16, 0x54, 0x58, 0xee, 0x40, 0xca, 0xc8, 0x80, 0x90, 0xde, 0xd8, 0xec, 0x7f, 0x4a, 0xf3, 0xdd, +0x53, 0x5f, 0xb8, 0xbe, 0x91, 0xe5, 0x9a, 0x4c, 0xb3, 0xf4, 0x03, 0x38, 0x03, 0xd2, 0xa8, 0xcb, +0x95, 0x26, 0x72, 0x97, 0x17, 0x84, 0xe4, 0xe7, 0x39, 0xf7, 0xac, 0x89, 0xae, 0x72, 0x4f, 0x35, +0x5e, 0x62, 0x7a, 0x19, 0xf2, 0x4c, 0x4f, 0x7a, 0xa4, 0xf2, 0x7b, 0xf2, 0x69, 0xef, 0xb8, 0x8a, +0xcf, 0x27, 0xe7, 0x55, 0x5d, 0xfa, 0xf5, 0xf7, 0xa1, 0xf6, 0x0b, 0x6a, 0x56, 0x76, 0xff, 0x00, +0xf5, 0xd4, 0x2c, 0xde, 0xe4, 0xd1, 0xd7, 0x52, 0x59, 0x0b, 0xbe, 0x01, 0x3e, 0x95, 0x02, 0x64, +0xe6, 0x46, 0xfb, 0xcf, 0xc7, 0xd0, 0x50, 0xc9, 0x7a, 0x21, 0xe4, 0x9c, 0xe7, 0xbd, 0x26, 0xe2, +0x73, 0xeb, 0x43, 0x62, 0xd8, 0x32, 0x4d, 0x21, 0x45, 0x6e, 0xb9, 0x3e, 0xf4, 0x6a, 0xc4, 0xf5, +0xdc, 0x06, 0xe4, 0x38, 0x6c, 0x95, 0xec, 0xd5, 0x65, 0x46, 0x79, 0xce, 0x78, 0xeb, 0x54, 0x4d, +0xee, 0x38, 0x8c, 0x02, 0x4f, 0x6a, 0x8d, 0x54, 0xe0, 0xb3, 0x0e, 0x5b, 0x9a, 0x77, 0x23, 0xcc, +0x3b, 0xf7, 0xf6, 0x34, 0xd2, 0x70, 0x7a, 0xd5, 0x21, 0x31, 0x85, 0xfd, 0xff, 0x00, 0x3a, 0x68, +0x93, 0x1d, 0xfa, 0xfe, 0x95, 0x68, 0x96, 0x83, 0xcf, 0x3e, 0xb9, 0xa6, 0xb5, 0xcf, 0x21, 0x7f, +0x13, 0x57, 0x7e, 0xc4, 0x5a, 0xe0, 0xf3, 0x67, 0x20, 0x9f, 0xfe, 0xb5, 0x54, 0x7b, 0x82, 0xbc, +0x13, 0x91, 0xd9, 0xa9, 0xde, 0xe0, 0xa2, 0x57, 0x92, 0x5c, 0xf7, 0xce, 0x6b, 0x3e, 0x57, 0xce, +0x6b, 0x27, 0x23, 0x58, 0xc7, 0x52, 0x8c, 0x8f, 0xd4, 0xf3, 0x54, 0x19, 0xba, 0x9e, 0x7e, 0x63, +0xde, 0xa1, 0xbe, 0x86, 0xa9, 0x58, 0x89, 0xc9, 0xcf, 0xe9, 0x50, 0x39, 0xeb, 0xcf, 0xe3, 0x52, +0xcd, 0x56, 0xc4, 0x0d, 0x83, 0x9e, 0x7b, 0x75, 0x35, 0x52, 0x4e, 0x0a, 0x8e, 0xab, 0x9c, 0xf4, +0xe6, 0xa7, 0x71, 0xab, 0x6e, 0x38, 0x9c, 0xe4, 0x83, 0x9e, 0x3a, 0xd4, 0x6d, 0x9e, 0x87, 0x38, +0xa8, 0xbd, 0xf5, 0x34, 0x57, 0xe8, 0x57, 0x72, 0x48, 0x23, 0x93, 0xc7, 0x5a, 0xa2, 0xc7, 0x2c, +0xe4, 0xf6, 0xe3, 0x9a, 0x93, 0x4b, 0x9f, 0x68, 0xcb, 0x7a, 0x65, 0x27, 0xe7, 0x20, 0x0e, 0xf5, +0x9f, 0x25, 0xdc, 0xa9, 0x9e, 0x77, 0x2f, 0x7c, 0x9a, 0xd1, 0x12, 0xd1, 0x51, 0xae, 0x83, 0xe7, +0x9e, 0x7b, 0x8c, 0xd5, 0x69, 0x26, 0x3c, 0xd3, 0xb1, 0x2f, 0xcc, 0xaa, 0xd2, 0xfb, 0xd5, 0x56, +0x7c, 0xf7, 0x39, 0xa7, 0xea, 0x4b, 0xd4, 0x81, 0x9f, 0xd7, 0xad, 0x57, 0x67, 0x3e, 0xb4, 0xb7, +0x13, 0xdc, 0x80, 0xb7, 0x7f, 0x5a, 0x85, 0x8f, 0x7a, 0x42, 0x68, 0xae, 0xe4, 0xbb, 0x04, 0x19, +0x23, 0xab, 0x53, 0xb3, 0xd7, 0xaf, 0xd6, 0x99, 0x2c, 0x4d, 0xd9, 0xa5, 0xfa, 0xd2, 0x13, 0x62, +0x83, 0xef, 0x9a, 0x95, 0x47, 0xb6, 0x78, 0xaa, 0x25, 0xea, 0x4c, 0xa9, 0xbb, 0x8c, 0x54, 0xab, +0x03, 0x29, 0xca, 0x02, 0x72, 0x79, 0x5a, 0x68, 0x96, 0x59, 0x36, 0xec, 0xe1, 0x70, 0xa7, 0x9f, +0xbd, 0x91, 0x4c, 0x92, 0x26, 0x5f, 0xc3, 0xda, 0x9e, 0xa4, 0x15, 0x59, 0x4f, 0xbd, 0x56, 0x7f, +0xf2, 0x69, 0x81, 0x03, 0x1a, 0x85, 0x9b, 0xad, 0x34, 0xc5, 0xa1, 0x0b, 0x3d, 0x40, 0x25, 0xc9, +0x63, 0xf8, 0x03, 0x42, 0x76, 0x13, 0xd5, 0x01, 0x96, 0xa2, 0x79, 0x3a, 0xe4, 0xe6, 0xa9, 0xc8, +0x76, 0x45, 0x39, 0x24, 0x65, 0xe4, 0x65, 0x87, 0x70, 0x6a, 0xbb, 0x48, 0x1b, 0x27, 0x3d, 0x7d, +0xea, 0x5b, 0x2d, 0x27, 0x6b, 0x14, 0xe5, 0x73, 0xb4, 0xe3, 0xa9, 0xe0, 0x55, 0x66, 0xfd, 0x47, +0x7a, 0x4f, 0xba, 0x34, 0x48, 0x85, 0xc9, 0xcf, 0x5f, 0xce, 0xa2, 0x6e, 0x87, 0xfa, 0x54, 0x3b, +0x17, 0xa9, 0x13, 0x1f, 0x5c, 0xd5, 0x62, 0x73, 0x21, 0xee, 0x14, 0x60, 0x9a, 0x96, 0xca, 0x49, +0x11, 0xb6, 0x50, 0x92, 0x32, 0x41, 0xea, 0x29, 0xa5, 0xb7, 0x72, 0x0e, 0x45, 0x43, 0x35, 0xbf, +0x62, 0xb3, 0x9e, 0xa3, 0x26, 0xa9, 0x93, 0xd7, 0x9e, 0xa4, 0xfd, 0x6a, 0x5e, 0xae, 0xe5, 0xdf, +0xb1, 0xf5, 0xab, 0x4d, 0x81, 0x80, 0x4d, 0x57, 0x79, 0xbd, 0xeb, 0x45, 0xd8, 0x4c, 0xa3, 0x29, +0xce, 0x4a, 0x92, 0x1b, 0xd6, 0xab, 0x1b, 0x96, 0x52, 0x56, 0x4c, 0xe7, 0x3f, 0x7a, 0xaf, 0x73, +0x31, 0x0c, 0xa1, 0xb9, 0x1c, 0xfe, 0x35, 0x0b, 0x48, 0x72, 0x79, 0xa4, 0xad, 0xd0, 0x19, 0x0b, +0x3f, 0x7e, 0xf5, 0x0b, 0x3f, 0xa9, 0xfa, 0xe6, 0x8d, 0x5e, 0x84, 0xb6, 0x42, 0x4f, 0x27, 0x9a, +0x89, 0xdf, 0x6a, 0x93, 0xd7, 0x1d, 0x05, 0x02, 0x64, 0x48, 0x30, 0x0b, 0x31, 0xe5, 0xb9, 0x39, +0xa7, 0x67, 0xf3, 0xa1, 0xe8, 0x4b, 0xde, 0xc1, 0x4a, 0x0e, 0x7f, 0xc6, 0x97, 0x52, 0x1f, 0x72, +0x45, 0xeb, 0xd2, 0xad, 0x22, 0xf7, 0xaa, 0x13, 0xec, 0x5d, 0x8d, 0x33, 0xcf, 0x3f, 0x5a, 0xde, +0xd3, 0xf4, 0xf7, 0xb9, 0x91, 0x54, 0x2e, 0x49, 0x38, 0xa6, 0xd9, 0x2c, 0xf7, 0x1d, 0x23, 0xe1, +0x7c, 0x57, 0x5a, 0x3b, 0x5c, 0x5c, 0x4a, 0x60, 0xbf, 0x9d, 0x77, 0x5b, 0x8e, 0xa9, 0x8c, 0x7f, +0x10, 0xeb, 0xcf, 0xb7, 0x4f, 0x7a, 0xf2, 0x8d, 0x73, 0xc3, 0x57, 0x7a, 0x65, 0xdc, 0xd6, 0xb3, +0xc2, 0xc9, 0x2c, 0x5d, 0x53, 0xae, 0x47, 0xa8, 0x3d, 0xc5, 0x42, 0x6c, 0x4f, 0x45, 0x73, 0x8e, +0xb8, 0xb7, 0x29, 0x90, 0x45, 0x65, 0x49, 0x19, 0xe6, 0xb4, 0x5b, 0x12, 0xd9, 0x46, 0x40, 0x72, +0x4d, 0x54, 0x73, 0x8c, 0xd0, 0xd8, 0xca, 0x92, 0x39, 0x00, 0xf5, 0xc9, 0xe9, 0x50, 0x67, 0x03, +0x19, 0xe9, 0x45, 0xc7, 0xe6, 0xc6, 0x33, 0x9f, 0x5a, 0x8c, 0xbf, 0xbd, 0x3b, 0x8c, 0x81, 0xdb, +0xa9, 0xcd, 0x53, 0x7d, 0xc0, 0xee, 0x43, 0x86, 0x1d, 0xbd, 0x6a, 0x4b, 0x4b, 0xb1, 0x51, 0xe4, +0x2e, 0xea, 0x3d, 0x39, 0x20, 0xd3, 0x58, 0x9e, 0x7f, 0x9d, 0x12, 0xb9, 0x48, 0x84, 0x92, 0x79, +0x27, 0xb5, 0x46, 0x4e, 0x41, 0xef, 0x53, 0xb6, 0x86, 0x8b, 0x5d, 0x48, 0x89, 0xea, 0x79, 0xeb, +0x50, 0x83, 0x9d, 0xcc, 0x7b, 0x9c, 0x8a, 0x9d, 0xd1, 0x49, 0x6a, 0x46, 0xe4, 0xfd, 0x01, 0xf6, +0xaa, 0xaf, 0x90, 0x4b, 0x0f, 0xc4, 0x7a, 0xd4, 0x5d, 0x96, 0xfb, 0x10, 0x34, 0x81, 0x95, 0x8e, +0x39, 0xc7, 0x39, 0xaa, 0xa4, 0x90, 0x06, 0x7b, 0xf3, 0xd6, 0x95, 0xca, 0xb2, 0x7a, 0x9f, 0x53, +0x99, 0x7d, 0xea, 0xbb, 0xc9, 0xeb, 0xcd, 0x68, 0x98, 0x32, 0x13, 0x21, 0xe7, 0x93, 0xcd, 0x41, +0x23, 0x06, 0x04, 0x11, 0x9c, 0xf5, 0xaa, 0xb9, 0x2f, 0x56, 0x52, 0x70, 0xd1, 0x92, 0xc8, 0xdb, +0x94, 0xf5, 0x14, 0xd1, 0x38, 0x7e, 0x0f, 0xca, 0xc3, 0xb1, 0xa7, 0xae, 0xe4, 0x3e, 0xc2, 0x16, +0xc8, 0xe4, 0xd3, 0x0b, 0x7e, 0x94, 0x74, 0x13, 0xee, 0xc8, 0x99, 0xaa, 0x0c, 0x97, 0x7f, 0x55, +0x4f, 0xd4, 0xd2, 0x13, 0x63, 0xc9, 0xfa, 0xfe, 0x74, 0x64, 0xf3, 0x47, 0x52, 0x5e, 0xa2, 0xe7, +0x3c, 0x77, 0xa5, 0x1f, 0xce, 0x86, 0x4b, 0xd4, 0x99, 0x79, 0xf5, 0xe6, 0xaf, 0x44, 0xb9, 0x23, +0x9a, 0x64, 0x49, 0x1b, 0x36, 0xb0, 0x96, 0x23, 0x03, 0xad, 0x7b, 0x4f, 0x80, 0xbc, 0x3f, 0xf6, +0xcb, 0xb8, 0x9a, 0x45, 0xfd, 0xd4, 0x67, 0x7b, 0x92, 0xbd, 0xb1, 0x53, 0x21, 0x3d, 0x5d, 0x8f, +0xa1, 0x40, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x76, 0xac, 0xfd, 0x4b, 0x4a, 0xb0, 0xd5, 0xa0, +0xf2, 0x2f, 0xa0, 0x59, 0x94, 0x72, 0xaf, 0xd1, 0x90, 0xfa, 0x83, 0xda, 0x91, 0xa3, 0x49, 0xab, +0x33, 0xe7, 0xef, 0x19, 0xf8, 0x12, 0xe7, 0x4d, 0x73, 0x71, 0x0a, 0xb5, 0xc5, 0xa3, 0xe4, 0x8b, +0x98, 0xe3, 0xe1, 0x7d, 0x9f, 0xd0, 0xfb, 0xf4, 0x35, 0xe3, 0xf7, 0xb6, 0x32, 0x40, 0x58, 0x3a, +0x32, 0xb7, 0xfb, 0x42, 0xa9, 0x3d, 0x35, 0x30, 0x6a, 0xcf, 0x53, 0x9d, 0x9a, 0x32, 0x0b, 0x56, +0x6c, 0xa0, 0xf3, 0xef, 0x55, 0x71, 0xa3, 0x3e, 0x5e, 0x58, 0x0f, 0x4e, 0x4d, 0x42, 0xcd, 0xd6, +0x9d, 0xfa, 0x0c, 0x88, 0xb7, 0xaf, 0xe7, 0xeb, 0x50, 0xb1, 0x23, 0x9e, 0xff, 0x00, 0xca, 0x91, +0x7b, 0xea, 0x40, 0xcc, 0x4f, 0xff, 0x00, 0xae, 0xa0, 0x66, 0x39, 0xef, 0x43, 0x76, 0x1d, 0xd1, +0x4d, 0x80, 0x90, 0xb3, 0x64, 0x86, 0xcf, 0x0d, 0x51, 0x6f, 0xea, 0xad, 0xc3, 0x7f, 0x3a, 0x1e, +0x85, 0xda, 0xfa, 0x88, 0x4f, 0xaf, 0x7a, 0x8d, 0x8f, 0x1f, 0x87, 0x7a, 0x84, 0xd5, 0x8a, 0x57, +0xbe, 0xa4, 0x12, 0x1c, 0x29, 0xc1, 0xc1, 0xe8, 0x33, 0xde, 0x98, 0x78, 0x00, 0x1c, 0x9e, 0x39, +0xf7, 0xa1, 0xf9, 0x94, 0x9b, 0x4c, 0x81, 0xb9, 0xc9, 0xef, 0xe9, 0x55, 0x9d, 0xba, 0x8c, 0x9e, +0x7d, 0xfa, 0xd6, 0x4e, 0xed, 0x97, 0xb3, 0xbb, 0x29, 0x4d, 0x9c, 0x1e, 0x48, 0xc8, 0xc7, 0xd6, +0xa1, 0x2d, 0x9e, 0x0e, 0x73, 0xef, 0x4d, 0xda, 0xe3, 0xd4, 0xfa, 0x81, 0x9b, 0x3f, 0xfd, 0x7a, +0x81, 0x9f, 0xf1, 0xab, 0x1b, 0x7a, 0xe8, 0x42, 0xcf, 0xe8, 0x71, 0x50, 0xb3, 0x9f, 0x5e, 0x4d, +0x50, 0xba, 0x5d, 0x91, 0x17, 0xf5, 0x35, 0x5a, 0x45, 0x56, 0xc9, 0xee, 0x7b, 0xd2, 0x57, 0x44, +0xee, 0x57, 0xf3, 0x1e, 0x3e, 0x1f, 0x2c, 0xbd, 0x9b, 0xd2, 0x9f, 0xe6, 0x2b, 0x0c, 0x83, 0x9c, +0xd3, 0xea, 0x46, 0xe8, 0x8e, 0x49, 0x0a, 0x8f, 0x52, 0x78, 0x03, 0xbd, 0x08, 0x36, 0x8c, 0x67, +0x9e, 0xa4, 0xd1, 0xea, 0x26, 0xfa, 0x0a, 0x4f, 0xeb, 0xdf, 0xd6, 0x8c, 0xe7, 0x26, 0x9b, 0x27, +0x71, 0x47, 0xad, 0x48, 0xbc, 0xfd, 0x68, 0x25, 0x96, 0x50, 0x64, 0x8a, 0xd3, 0x81, 0x72, 0x47, +0xf3, 0xa6, 0x43, 0x3a, 0xed, 0x1e, 0xcc, 0xcd, 0x2a, 0x00, 0x33, 0xcd, 0x7d, 0x51, 0xe1, 0x1d, +0x2c, 0x69, 0xda, 0x62, 0x31, 0x5c, 0x4b, 0x71, 0xf3, 0x13, 0xed, 0xda, 0xa2, 0x5d, 0x84, 0xb5, +0x67, 0x55, 0x45, 0x23, 0x51, 0xae, 0xab, 0x22, 0xb2, 0x3a, 0xab, 0xa3, 0x8d, 0xac, 0x8e, 0x32, +0x18, 0x7a, 0x11, 0x5e, 0x45, 0xe3, 0x4f, 0x87, 0xd1, 0xdd, 0x44, 0xf7, 0x9a, 0x3d, 0xbe, 0xe2, +0xa3, 0x32, 0x59, 0x21, 0xe4, 0x7b, 0xa7, 0xaf, 0xfb, 0xbf, 0x95, 0x04, 0x4d, 0x5d, 0x5c, 0xf9, +0xc3, 0x55, 0xd2, 0x26, 0xb4, 0x2d, 0xbd, 0x18, 0x60, 0xe3, 0x90, 0x46, 0x0f, 0xa7, 0xd6, 0xb8, +0xfb, 0x94, 0x20, 0xb6, 0x78, 0xad, 0x13, 0x21, 0x6b, 0xa9, 0x8e, 0xc3, 0x25, 0x9b, 0xd4, 0xd5, +0x77, 0xf5, 0xcd, 0x36, 0x0b, 0xcc, 0x81, 0x89, 0xf7, 0x35, 0x13, 0x13, 0x9f, 0x5a, 0x46, 0x8b, +0xb1, 0x03, 0x7d, 0x3f, 0x11, 0x55, 0xdd, 0xf0, 0x09, 0x3f, 0x95, 0x17, 0x1f, 0x52, 0x0c, 0x61, +0x70, 0x79, 0xee, 0x6a, 0x37, 0x50, 0xf9, 0xcf, 0x41, 0xdf, 0xd2, 0xa6, 0x45, 0x2b, 0xee, 0x57, +0x25, 0x97, 0x86, 0xc9, 0x5e, 0xcd, 0x41, 0xce, 0x32, 0x4f, 0xe7, 0x4b, 0x76, 0x52, 0x65, 0x79, +0x4e, 0x59, 0x07, 0x5c, 0x9c, 0xd3, 0x49, 0xeb, 0xd7, 0x3e, 0xa6, 0xa5, 0xe8, 0x52, 0xb1, 0x59, +0xc9, 0xf5, 0xeb, 0x55, 0x5d, 0xb1, 0xc9, 0x3c, 0x9f, 0x5a, 0x86, 0x55, 0xfa, 0x94, 0xe5, 0x6c, +0xe3, 0x24, 0xf2, 0x7a, 0x1a, 0x86, 0x4c, 0x9c, 0x9e, 0x4e, 0x0f, 0x0d, 0xe9, 0x4e, 0xe5, 0x2b, +0xdc, 0xff, 0xff, 0xd9 +}; + +static unsigned int PIC_LEN_1 = 11508; + + SDRAM_DATA_SECTION static const unsigned char PIC_320x240_2[] = { +0xff, 0xd8, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x0a, 0x06, 0x06, 0x04, 0x04, 0x06, 0x0c, 0x08, 0x08, 0x06, +0x0a, 0x0e, 0x0c, 0x0e, 0x0e, 0x0e, 0x0c, 0x0e, 0x0c, 0x10, 0x12, 0x16, 0x12, 0x10, 0x10, 0x14, +0x10, 0x0c, 0x0e, 0x14, 0x1a, 0x14, 0x14, 0x16, 0x18, 0x18, 0x1a, 0x18, 0x0e, 0x12, 0x1c, 0x1e, +0x1c, 0x18, 0x1e, 0x16, 0x18, 0x18, 0x18, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x04, 0x04, 0x04, 0x06, +0x04, 0x06, 0x0a, 0x06, 0x06, 0x0a, 0x18, 0x10, 0x0e, 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xc0, 0x00, 0x11, +0x08, 0x00, 0xf0, 0x01, 0x40, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, +0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, +0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, +0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, +0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, +0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, +0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, +0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, +0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, +0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, +0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, +0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, +0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, +0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, +0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, +0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, +0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, +0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, +0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, +0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, +0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, +0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, +0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, +0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, +0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, +0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xf3, 0xc8, 0x9b, +0x7a, 0x29, 0x07, 0x24, 0xd5, 0x80, 0x3d, 0x6b, 0x04, 0x77, 0x31, 0xe0, 0x1f, 0xad, 0x58, 0x5f, +0x4a, 0xb5, 0xae, 0xe4, 0x48, 0x9d, 0x7f, 0xce, 0x6a, 0xca, 0x7e, 0xa6, 0xb4, 0x4c, 0xc5, 0x97, +0x22, 0x6c, 0x1e, 0xf5, 0xab, 0x6f, 0x2e, 0xd2, 0x3e, 0xb5, 0xb4, 0x1b, 0x39, 0xe7, 0xaa, 0x3d, +0x57, 0xc0, 0x1e, 0x2e, 0x8b, 0x40, 0xd4, 0xc7, 0xda, 0xf7, 0x1b, 0x1b, 0xb4, 0x31, 0xc9, 0xb7, +0x19, 0x4e, 0x41, 0x0d, 0xf8, 0x1f, 0xd0, 0x9a, 0xf5, 0x2d, 0x7f, 0xe2, 0x86, 0x9b, 0x6a, 0xb2, +0xc1, 0xa3, 0xee, 0xba, 0x9b, 0xa0, 0xbc, 0x71, 0x88, 0xd7, 0xdc, 0x03, 0xc9, 0xfc, 0x70, 0x3e, +0xb5, 0x6e, 0x1e, 0xd2, 0x57, 0x39, 0xfd, 0xa3, 0xa7, 0x16, 0x96, 0xe7, 0xce, 0xde, 0x21, 0xf1, +0x8c, 0xb7, 0x57, 0x13, 0xcd, 0x34, 0xcd, 0x73, 0x75, 0x2b, 0x16, 0x66, 0x24, 0x60, 0x1f, 0x7f, +0xf0, 0xaf, 0x33, 0xd4, 0x35, 0x09, 0xae, 0xdc, 0xbc, 0xaf, 0xb9, 0xbb, 0x03, 0xdb, 0xf0, 0xae, +0x95, 0x15, 0x6b, 0x9c, 0xba, 0xb7, 0x66, 0x61, 0x48, 0xdb, 0x8e, 0x07, 0x5e, 0xe6, 0xa9, 0xb2, +0xa8, 0x18, 0x00, 0x12, 0x78, 0xcf, 0xa5, 0x44, 0xb7, 0x36, 0x87, 0x91, 0x5c, 0xc7, 0xce, 0x48, +0xe7, 0xd6, 0x8f, 0x2b, 0x24, 0x9c, 0x7e, 0x39, 0xac, 0xdf, 0x73, 0xa2, 0xf7, 0xd0, 0x92, 0x34, +0x78, 0xdd, 0x64, 0x4c, 0x86, 0x53, 0x90, 0x6b, 0xb8, 0xb5, 0x90, 0x4f, 0x1a, 0x4e, 0xbf, 0x75, +0xf8, 0x71, 0xfd, 0xd3, 0x58, 0xcd, 0x76, 0x2e, 0x32, 0xbe, 0xe5, 0xff, 0x00, 0x2b, 0xf5, 0xe9, +0x4d, 0x31, 0x1e, 0x4f, 0x27, 0xde, 0xb1, 0x77, 0x66, 0xb7, 0x20, 0x68, 0xb9, 0xf5, 0xa8, 0x5a, +0x3e, 0xa7, 0x14, 0xd7, 0x61, 0x5f, 0x4d, 0x4a, 0xec, 0x9d, 0xea, 0xac, 0x85, 0x53, 0xaf, 0x5e, +0xc0, 0x75, 0xa7, 0xe8, 0x27, 0xdc, 0xaa, 0xd1, 0xbc, 0xb9, 0x2f, 0xf2, 0xaf, 0xf7, 0x7b, 0xd2, +0x6c, 0x54, 0xe0, 0x00, 0x05, 0x17, 0x0b, 0xf5, 0x18, 0xcb, 0x54, 0xe5, 0x5d, 0x8d, 0xe6, 0x63, +0x23, 0xa1, 0xa7, 0x7d, 0x4a, 0x42, 0x91, 0x90, 0x4f, 0x5c, 0xf3, 0x4d, 0x20, 0x67, 0xbd, 0x24, +0xc7, 0x7b, 0xe8, 0x37, 0x03, 0x9f, 0xad, 0x03, 0x83, 0xdf, 0xeb, 0x4d, 0x6c, 0x3b, 0xdf, 0x71, +0x7f, 0x5c, 0xd4, 0x8a, 0x45, 0x1d, 0x0a, 0xdf, 0x42, 0x75, 0x6c, 0x9e, 0xdf, 0x8d, 0x59, 0x49, +0x39, 0xf5, 0xe2, 0xa5, 0xbb, 0x8e, 0xd6, 0x2f, 0xc5, 0x36, 0xd3, 0xe9, 0x5b, 0x76, 0x97, 0xbe, +0x5b, 0x0e, 0x4f, 0x3d, 0xea, 0x65, 0xb0, 0x26, 0xcf, 0x5f, 0xf0, 0x3f, 0x8e, 0x4e, 0x89, 0x7b, +0x11, 0x99, 0x9e, 0x4b, 0x49, 0x4e, 0xc9, 0xa2, 0x5c, 0x64, 0x8f, 0x5f, 0xa8, 0xaf, 0xa8, 0x22, +0xd5, 0xb4, 0xe9, 0xb4, 0xe1, 0xab, 0x25, 0xe4, 0x3f, 0xd9, 0xfe, 0x5f, 0x9a, 0x6e, 0x99, 0x80, +0x55, 0x5c, 0x73, 0x9f, 0x42, 0x3d, 0x28, 0x86, 0xa8, 0xce, 0xa6, 0x8f, 0x53, 0xf2, 0xeb, 0x4b, +0x9c, 0x02, 0x60, 0x2c, 0xcc, 0xa0, 0x7c, 0x8c, 0xdc, 0xe5, 0x7b, 0x7e, 0x5d, 0x2b, 0x7c, 0x03, +0xd6, 0xa4, 0xeb, 0x6e, 0xee, 0xe4, 0xca, 0x3f, 0x3a, 0x95, 0x7e, 0xb4, 0xef, 0x72, 0x24, 0xc9, +0xd7, 0xfc, 0xf3, 0x53, 0x2e, 0x7b, 0x9e, 0xb5, 0x69, 0x19, 0x3d, 0x4b, 0x68, 0x79, 0xe6, 0xac, +0x09, 0x82, 0x63, 0x27, 0x93, 0xd0, 0x7a, 0xd6, 0xa8, 0xc5, 0xea, 0x5a, 0x8e, 0x59, 0x1b, 0x92, +0x76, 0xe3, 0xa0, 0xaa, 0x7a, 0xa5, 0xdd, 0xcf, 0xd9, 0x37, 0xc2, 0xe5, 0x51, 0x4e, 0x24, 0x1d, +0x09, 0x15, 0xb4, 0x64, 0xae, 0x73, 0x54, 0x8b, 0x69, 0x9c, 0x83, 0x4e, 0x58, 0x93, 0x92, 0x7f, +0x1a, 0x89, 0x9b, 0x20, 0x92, 0x78, 0xf7, 0xef, 0x5b, 0xb6, 0xac, 0x73, 0xa4, 0x57, 0x61, 0x93, +0xfe, 0xcd, 0x33, 0x61, 0xf7, 0x35, 0x93, 0xee, 0x6c, 0x90, 0xe1, 0x16, 0x4f, 0x4e, 0x6a, 0x51, +0x01, 0xe3, 0x8e, 0xb5, 0x2c, 0xb5, 0xa9, 0x32, 0xdb, 0x93, 0x8e, 0x0e, 0x6b, 0x63, 0x4c, 0x3e, +0x4c, 0xbe, 0x53, 0xff, 0x00, 0xaa, 0x98, 0xe0, 0xfb, 0x1e, 0xc6, 0xb2, 0x68, 0xd7, 0xd4, 0xea, +0x63, 0x83, 0xaa, 0x91, 0xd3, 0xa5, 0x39, 0xad, 0xcf, 0x3e, 0xf5, 0x9b, 0x2e, 0xe4, 0x0f, 0x01, +0xeb, 0x8a, 0xa7, 0x2c, 0x58, 0x04, 0x9c, 0x7d, 0x4d, 0x16, 0x15, 0xcc, 0xe7, 0x0e, 0xc4, 0xec, +0x1c, 0x7f, 0x7c, 0xd5, 0x7f, 0x20, 0x29, 0x24, 0xe5, 0x89, 0xea, 0x4d, 0x3b, 0x05, 0xef, 0xa8, +0xc6, 0x4f, 0xd7, 0xbd, 0x40, 0xeb, 0xcf, 0x4a, 0x5e, 0x61, 0xb9, 0x5d, 0x94, 0xd4, 0x2e, 0xb9, +0xce, 0x79, 0xfe, 0xb4, 0x21, 0x95, 0x17, 0x2a, 0xc5, 0x09, 0xcf, 0x70, 0x7b, 0xd3, 0x8f, 0x71, +0xd7, 0xeb, 0x4d, 0x0d, 0x31, 0x84, 0x7a, 0xf7, 0xa6, 0x9e, 0xbf, 0xd6, 0x93, 0x2e, 0xe2, 0x67, +0x3d, 0x4d, 0x38, 0x9c, 0x1c, 0xfe, 0xb4, 0xb7, 0x29, 0x32, 0x40, 0xdf, 0x5c, 0xd4, 0xca, 0xe4, +0x77, 0xed, 0x46, 0xc3, 0x5a, 0x92, 0x89, 0x39, 0xce, 0x6a, 0xd2, 0x5c, 0x11, 0xd0, 0x9f, 0xc6, +0xa4, 0xa2, 0x71, 0xa8, 0x34, 0x7d, 0x18, 0xe7, 0xd2, 0x9d, 0x2e, 0xbd, 0x7c, 0xf0, 0x1b, 0x36, +0xb9, 0x94, 0x5b, 0x93, 0xbf, 0xc8, 0x0c, 0x76, 0x93, 0xd3, 0x38, 0xf5, 0xa9, 0x4e, 0xd7, 0x13, +0x8a, 0x7b, 0x9c, 0x6c, 0x44, 0x95, 0x46, 0x85, 0x09, 0x28, 0x4b, 0x61, 0xb8, 0x3e, 0xe2, 0xba, +0x4b, 0x79, 0x04, 0xa8, 0x18, 0x1c, 0xfb, 0xfa, 0xd0, 0xf4, 0x34, 0x6d, 0xb7, 0x72, 0xda, 0x8f, +0xf2, 0x6a, 0x51, 0xf9, 0xd0, 0x85, 0x2b, 0x93, 0x2f, 0xf3, 0xa9, 0x94, 0x8c, 0x64, 0xfe, 0xb5, +0xa2, 0xd4, 0xcd, 0x8e, 0x59, 0x19, 0xce, 0x23, 0x19, 0xff, 0x00, 0x6c, 0xf4, 0x15, 0x6a, 0x28, +0xf6, 0x92, 0x49, 0x2c, 0xdf, 0xde, 0x6a, 0xab, 0x99, 0x35, 0xd4, 0xb8, 0xa6, 0x99, 0x2a, 0x86, +0xca, 0xb0, 0xca, 0x4a, 0x36, 0xb0, 0x3d, 0x2a, 0x93, 0xb2, 0x32, 0x96, 0xba, 0x9c, 0x55, 0xdc, +0x0d, 0x6b, 0x3b, 0xc4, 0xc1, 0x8f, 0x39, 0x56, 0xf5, 0x1e, 0xb5, 0x57, 0x39, 0xeb, 0xce, 0x7b, +0x9a, 0xe9, 0xbf, 0x32, 0xb9, 0xce, 0xd5, 0x99, 0x20, 0x5c, 0xd4, 0xcb, 0x11, 0x3c, 0xe3, 0xf1, +0xa9, 0x6f, 0x41, 0xa4, 0xcb, 0x29, 0x01, 0x3e, 0xbf, 0x5a, 0xb8, 0x96, 0xa4, 0xf2, 0x47, 0xe9, +0x50, 0xdb, 0x35, 0x8a, 0xee, 0x5a, 0x4b, 0x42, 0x7b, 0x1f, 0xca, 0xac, 0xa5, 0x91, 0xe0, 0x80, +0x73, 0xf4, 0xa5, 0xb8, 0xef, 0x73, 0xaa, 0xb2, 0x89, 0xa6, 0x88, 0x12, 0x3f, 0x7b, 0x17, 0x0d, +0xee, 0x3d, 0x6b, 0x40, 0xda, 0x1c, 0x67, 0x1e, 0xfd, 0x2a, 0x1a, 0x29, 0x14, 0x66, 0x87, 0x19, +0x0a, 0x0b, 0x37, 0xa0, 0x15, 0x9b, 0x2d, 0xa1, 0x6c, 0x99, 0x32, 0x7d, 0x07, 0x61, 0x49, 0xea, +0x2b, 0x94, 0x65, 0x87, 0x1c, 0x62, 0xa8, 0xc9, 0x1f, 0x27, 0x22, 0x96, 0xe3, 0x45, 0x57, 0x4e, +0xb5, 0x55, 0xd6, 0x81, 0xee, 0x57, 0x70, 0x6a, 0xbb, 0x0e, 0xbf, 0xd6, 0x92, 0xd4, 0x6d, 0x95, +0x66, 0x42, 0x46, 0xe1, 0xf7, 0x97, 0x91, 0x51, 0xa9, 0x0c, 0x01, 0xee, 0x7d, 0x69, 0x85, 0xc4, +0x3e, 0xff, 0x00, 0x95, 0x46, 0x7a, 0xd2, 0xd8, 0xa4, 0xdb, 0x57, 0x1b, 0xd7, 0x34, 0x99, 0x3d, +0xff, 0x00, 0x0c, 0xd2, 0x66, 0x88, 0x5d, 0xdc, 0x9c, 0xf7, 0xa7, 0x6f, 0xc6, 0x39, 0xcf, 0x3e, +0xb4, 0x3b, 0x6e, 0x55, 0x85, 0x33, 0x05, 0xe4, 0x9f, 0xd6, 0x9a, 0x26, 0x91, 0xcf, 0x04, 0xaa, +0x9f, 0xe2, 0xa4, 0xc6, 0x96, 0xa4, 0x81, 0x80, 0xe7, 0x24, 0xf7, 0x24, 0xd4, 0x53, 0x3e, 0x41, +0xc1, 0xf9, 0x87, 0x3d, 0x6a, 0x6d, 0xd4, 0xad, 0xde, 0xa4, 0x36, 0x88, 0x44, 0x82, 0x05, 0x91, +0x5d, 0x66, 0xdc, 0xc9, 0xcf, 0x2a, 0x7b, 0xf3, 0xdf, 0xbd, 0x68, 0xdb, 0x37, 0x93, 0x2b, 0x47, +0xbb, 0x23, 0xaf, 0x1d, 0xbd, 0x47, 0xf9, 0xf5, 0xa6, 0xf4, 0x08, 0xbb, 0xde, 0xe6, 0xc8, 0xe7, +0x07, 0xd6, 0xa4, 0x19, 0xff, 0x00, 0xeb, 0x54, 0xf4, 0x13, 0x43, 0x8b, 0xaa, 0xf0, 0x72, 0x49, +0xe8, 0x07, 0x53, 0x52, 0x24, 0x6d, 0x21, 0x06, 0x4f, 0xbb, 0xfd, 0xc1, 0x57, 0xb1, 0x0f, 0x52, +0xea, 0x00, 0x38, 0x03, 0x18, 0xa9, 0xd7, 0x3e, 0xf5, 0x57, 0x21, 0xdc, 0x95, 0x6a, 0x6d, 0xbb, +0xc1, 0x07, 0xbd, 0x34, 0x64, 0xfc, 0x8c, 0x8d, 0x52, 0xcc, 0xdc, 0x40, 0x5c, 0x7f, 0xae, 0xb6, +0xe7, 0xea, 0x3b, 0xd7, 0x2e, 0x88, 0x49, 0xfa, 0xd6, 0xd0, 0x66, 0x33, 0x5d, 0x0b, 0x91, 0xc5, +0x93, 0xeb, 0x9f, 0x5a, 0xd0, 0x8e, 0xdc, 0x9e, 0xd5, 0x57, 0x05, 0xa9, 0xa7, 0x15, 0xb7, 0xa0, +0xc9, 0xf5, 0xad, 0x38, 0xac, 0x89, 0xc6, 0x46, 0x6a, 0x5f, 0x72, 0xbc, 0x91, 0xa5, 0x16, 0x9e, +0x58, 0xf4, 0xeb, 0x5a, 0x70, 0xe9, 0x4c, 0x7a, 0x26, 0x73, 0x49, 0xea, 0x17, 0xb1, 0xd4, 0xe9, +0x9e, 0x1b, 0xba, 0x67, 0x59, 0x02, 0x6d, 0x56, 0xec, 0x41, 0xf9, 0xbf, 0x0a, 0xd8, 0xba, 0xf0, +0xdd, 0xd4, 0x00, 0x79, 0x90, 0xbc, 0x6a, 0xdc, 0x8d, 0xc0, 0x8c, 0xd4, 0xb7, 0x71, 0xa6, 0x73, +0xd7, 0x1a, 0x6f, 0x97, 0x9c, 0x26, 0x3d, 0xeb, 0x0e, 0xe2, 0xd7, 0x6e, 0x78, 0xa5, 0xe8, 0x3b, +0xf7, 0x31, 0x67, 0x83, 0x19, 0xac, 0x99, 0xa2, 0xc6, 0x7f, 0x40, 0x6a, 0x74, 0x02, 0x84, 0x89, +0xf8, 0xd5, 0x37, 0x5e, 0xff, 0x00, 0xce, 0x9b, 0x02, 0xa3, 0xaf, 0x5a, 0xaa, 0xcb, 0xcd, 0x03, +0x20, 0x61, 0xf8, 0x9a, 0xa8, 0xc3, 0xcb, 0x72, 0x7f, 0x85, 0xf8, 0xfa, 0x54, 0xf5, 0x2b, 0x51, +0x48, 0xe4, 0xe7, 0xbf, 0x7a, 0x88, 0x8f, 0x5a, 0x65, 0x75, 0x18, 0x4e, 0x29, 0xa4, 0xd2, 0xb9, +0x7a, 0x8c, 0x2f, 0x8e, 0x4f, 0x00, 0x77, 0x3d, 0xaa, 0x23, 0x31, 0x62, 0x42, 0x73, 0xfe, 0xd1, +0x1d, 0x29, 0x6f, 0xa1, 0x69, 0x8e, 0x55, 0x19, 0x0c, 0xc7, 0x71, 0x1e, 0xbd, 0xaa, 0x4d, 0xdc, +0xf7, 0xa4, 0xdb, 0x29, 0x0a, 0x5c, 0xf7, 0xfc, 0x7d, 0xea, 0x36, 0x6e, 0xbc, 0xd4, 0xb6, 0x8b, +0x4a, 0xda, 0x33, 0xa4, 0xd5, 0x3c, 0x25, 0xab, 0xc0, 0xa6, 0x24, 0x84, 0x98, 0xa2, 0x1b, 0x96, +0xe6, 0x20, 0x4d, 0x60, 0xcd, 0x7d, 0x08, 0x7b, 0x78, 0x6d, 0xe2, 0x96, 0x5b, 0xe7, 0x03, 0xcc, +0xf9, 0x7f, 0xd5, 0xe3, 0xae, 0xe3, 0x5a, 0x4e, 0x2d, 0x1c, 0xd4, 0xea, 0x29, 0xea, 0x8d, 0xfb, +0x79, 0x43, 0x47, 0xf3, 0x10, 0xb8, 0x19, 0xe4, 0xf4, 0xa9, 0x83, 0x34, 0xa4, 0x84, 0x18, 0x5f, +0xf9, 0xe8, 0x45, 0x66, 0x6c, 0xdd, 0xf6, 0x2d, 0x45, 0x12, 0xa7, 0x23, 0x25, 0x8f, 0x56, 0x3d, +0x6a, 0xc0, 0xf5, 0xf5, 0xa6, 0x43, 0xd7, 0x52, 0x65, 0xe6, 0xa7, 0x5f, 0xc6, 0xaa, 0xe4, 0x35, +0x72, 0x60, 0x33, 0xf4, 0xab, 0x2a, 0x09, 0xe7, 0xad, 0x17, 0x33, 0x64, 0x8d, 0x19, 0xe1, 0xb9, +0x3d, 0x88, 0xae, 0x56, 0xfa, 0xc4, 0xdb, 0x5c, 0x1d, 0x83, 0xf7, 0x72, 0x9d, 0xcb, 0xfe, 0x15, +0xa4, 0x5e, 0xa4, 0x4b, 0x62, 0x48, 0x20, 0xe7, 0x91, 0xcd, 0x6c, 0xdb, 0xdb, 0x16, 0xed, 0xef, +0xd2, 0xb4, 0xb8, 0x91, 0xb7, 0x6f, 0x64, 0x49, 0x1c, 0x13, 0xf5, 0xae, 0x86, 0xd7, 0x4c, 0x66, +0xc7, 0xca, 0x7f, 0x2a, 0x4d, 0x91, 0x73, 0xad, 0xd3, 0xbc, 0x3d, 0x3d, 0xc9, 0x02, 0x38, 0x98, +0x82, 0x7e, 0xf1, 0x1c, 0x0a, 0xf4, 0xbd, 0x23, 0xc1, 0x3b, 0x76, 0xbc, 0xab, 0xb7, 0xbe, 0xf7, +0x5f, 0xe4, 0x2a, 0x66, 0xfb, 0x0f, 0x73, 0xd0, 0xac, 0xb4, 0xbb, 0x3b, 0x25, 0x51, 0x1c, 0x48, +0xd2, 0x0f, 0xf9, 0x6a, 0xc3, 0x9a, 0xb1, 0x79, 0x67, 0x0d, 0xec, 0x2d, 0x0c, 0xe8, 0x18, 0x1e, +0x87, 0x1c, 0xa9, 0xf5, 0xac, 0x9b, 0xb9, 0xaa, 0x5a, 0x1e, 0x3d, 0xaf, 0xe8, 0x2d, 0x6b, 0x23, +0x8d, 0xbc, 0x67, 0x21, 0xb1, 0xd6, 0xbc, 0xea, 0xfa, 0xcc, 0x82, 0xdc, 0x7e, 0x95, 0xa2, 0xd5, +0x19, 0xdc, 0xe6, 0x2e, 0xad, 0xf1, 0x9a, 0xc2, 0x9e, 0x23, 0xcf, 0x7a, 0x18, 0x26, 0x64, 0xcb, +0x1f, 0x35, 0x9f, 0x22, 0xe7, 0x3d, 0x73, 0x9a, 0x4f, 0x52, 0x8a, 0x52, 0x2f, 0x27, 0xaf, 0x35, +0x51, 0xc7, 0x5e, 0x69, 0x5c, 0x69, 0x95, 0x98, 0x7f, 0xfa, 0xea, 0xb4, 0x8b, 0xb8, 0x10, 0x7b, +0xf7, 0xa0, 0x68, 0xae, 0x8c, 0x4e, 0x51, 0xcf, 0xcc, 0xbf, 0xa8, 0xa4, 0x6a, 0x65, 0x6c, 0x46, +0xc7, 0x19, 0x39, 0xfc, 0xea, 0xab, 0xcb, 0xce, 0x10, 0x6f, 0x3e, 0xd5, 0x2e, 0xed, 0x9a, 0x2d, +0x08, 0xf6, 0x97, 0x39, 0x90, 0xe7, 0x1d, 0x85, 0x49, 0xd3, 0x20, 0x77, 0xf6, 0xa4, 0xca, 0x42, +0xe7, 0xd4, 0xf3, 0xf5, 0xa5, 0x04, 0xf5, 0xef, 0x4b, 0xa1, 0xa2, 0x0c, 0x9f, 0xff, 0x00, 0x55, +0x34, 0x9c, 0xf2, 0x79, 0xa9, 0xd8, 0xbd, 0xcf, 0xa4, 0xb7, 0x49, 0x19, 0xe4, 0x82, 0x3a, 0x10, +0x46, 0x73, 0x59, 0x97, 0x7a, 0x16, 0x87, 0xa8, 0x82, 0x65, 0xb6, 0xfb, 0x1d, 0xcb, 0x1c, 0xfd, +0xa6, 0xd4, 0x63, 0x3f, 0x51, 0x5d, 0xb7, 0x4f, 0x49, 0x1e, 0x3b, 0xbc, 0x5f, 0x34, 0x77, 0x39, +0x0d, 0x4b, 0xc1, 0x97, 0x7a, 0x78, 0x6b, 0x8b, 0x67, 0x4b, 0xfb, 0x50, 0x77, 0x96, 0x88, 0xe5, +0x80, 0xf5, 0x22, 0xb1, 0xd4, 0x01, 0x81, 0x8c, 0x7b, 0x57, 0x2d, 0x58, 0x3a, 0x6c, 0xed, 0xa1, +0x51, 0x54, 0x44, 0xc3, 0xf5, 0xa7, 0x8f, 0xd6, 0xb3, 0x46, 0xae, 0xfd, 0x49, 0xd7, 0xaf, 0xa9, +0xab, 0x0a, 0x39, 0xaa, 0x4c, 0x89, 0x16, 0x14, 0x7f, 0x93, 0x56, 0x90, 0x74, 0xa7, 0x76, 0x67, +0x72, 0xda, 0x26, 0x7a, 0xf3, 0xf5, 0xa6, 0x5c, 0x59, 0x7d, 0xa6, 0x16, 0x8b, 0xfe, 0x5a, 0x27, +0xcc, 0x8c, 0x4d, 0x51, 0x26, 0x55, 0xbd, 0xb1, 0xc8, 0xc8, 0xe7, 0xde, 0xba, 0x5b, 0x3b, 0x2d, +0xd8, 0xe3, 0xf1, 0xad, 0xae, 0x65, 0x73, 0xb1, 0xd3, 0xb4, 0x87, 0x95, 0x94, 0x2a, 0x16, 0x24, +0xf0, 0x00, 0xcd, 0x7a, 0x8e, 0x89, 0xe0, 0xd9, 0x24, 0xdb, 0x24, 0xea, 0x02, 0xf0, 0x70, 0x6a, +0x5c, 0x84, 0xf5, 0x67, 0xa6, 0x58, 0xe9, 0x56, 0x96, 0x28, 0xa2, 0x38, 0xd4, 0xb0, 0x1d, 0x71, +0xd2, 0xb4, 0xeb, 0x26, 0xee, 0x6d, 0x18, 0xd8, 0x28, 0xa4, 0x51, 0x97, 0xaa, 0xd8, 0x25, 0xf5, +0xb3, 0x82, 0x33, 0x22, 0x82, 0x54, 0xd7, 0x8b, 0xea, 0xfa, 0x71, 0x8d, 0xdc, 0x15, 0xe4, 0x1a, +0xb8, 0xbe, 0x86, 0x35, 0x34, 0x67, 0x05, 0x7d, 0x6c, 0x41, 0x6e, 0x38, 0xf7, 0xae, 0x62, 0xea, +0x1c, 0x13, 0x4c, 0x57, 0xd4, 0xc3, 0x9e, 0x3e, 0x49, 0xac, 0xb9, 0x14, 0xf2, 0x68, 0x28, 0xcf, +0x90, 0x55, 0x39, 0x07, 0x5a, 0x5a, 0x14, 0x9b, 0xb1, 0x51, 0x87, 0x5a, 0xae, 0xc3, 0xa9, 0xef, +0x48, 0xa5, 0xdc, 0xa7, 0x32, 0xe0, 0xf9, 0x83, 0xaa, 0xf5, 0xc7, 0x7a, 0x85, 0xe6, 0x55, 0x5c, +0x8f, 0x98, 0xb0, 0xe1, 0x45, 0x17, 0xd0, 0x64, 0x0c, 0xb2, 0x49, 0xcb, 0x1d, 0xa0, 0xf6, 0x1d, +0x69, 0x00, 0x0b, 0xc0, 0x00, 0x0a, 0x6d, 0x75, 0x46, 0x89, 0xdf, 0x71, 0x18, 0xf5, 0xa6, 0x93, +0x8a, 0x9f, 0x32, 0xc4, 0xe7, 0xd4, 0xd2, 0x67, 0x9e, 0xf9, 0x35, 0x3a, 0x6c, 0x5a, 0xbe, 0xe3, +0xb2, 0x3a, 0xe6, 0x90, 0x9c, 0x93, 0xf4, 0xa4, 0xec, 0xdd, 0x8d, 0x16, 0xba, 0x1f, 0x45, 0x45, +0xab, 0x5a, 0x5c, 0x80, 0x55, 0xd4, 0x13, 0xd8, 0xd5, 0xe0, 0xaa, 0xff, 0x00, 0x30, 0x39, 0x07, +0xa6, 0x0d, 0x6d, 0x1a, 0xca, 0x5a, 0x33, 0xcc, 0x95, 0x37, 0x1d, 0x50, 0xe4, 0xf3, 0x22, 0x6f, +0x94, 0x95, 0xcf, 0x15, 0xcd, 0xeb, 0xba, 0x48, 0xb8, 0x2d, 0x77, 0x6f, 0x18, 0x13, 0x1e, 0x64, +0x45, 0xe0, 0x1f, 0x7c, 0x55, 0xcd, 0xb9, 0x47, 0x94, 0x88, 0x49, 0x46, 0x7c, 0xcc, 0xe2, 0x88, +0x2a, 0x76, 0xb0, 0x20, 0x8e, 0xa2, 0xa4, 0x1f, 0x9e, 0x6b, 0x97, 0xa1, 0xde, 0xda, 0x64, 0xa3, +0xf5, 0x35, 0x65, 0x39, 0xa7, 0xa3, 0x21, 0x96, 0x52, 0xad, 0xc7, 0x55, 0xa9, 0x9b, 0x2f, 0x44, +0xbd, 0xeb, 0x4e, 0x28, 0xb7, 0x6d, 0x60, 0x39, 0x5e, 0x69, 0x92, 0x49, 0x26, 0x9b, 0xfb, 0xd5, +0x9a, 0x35, 0x25, 0x66, 0x3f, 0x36, 0x3b, 0x1a, 0xee, 0xb4, 0x0f, 0x0d, 0xdc, 0x5e, 0x14, 0xc4, +0x6c, 0x15, 0xbf, 0x8b, 0x1d, 0x6a, 0xf9, 0xb4, 0x32, 0x96, 0xe7, 0xb6, 0x68, 0xde, 0x1a, 0xb7, +0xb0, 0x40, 0xd2, 0x2e, 0x5f, 0xd0, 0xf2, 0x6b, 0xaa, 0x00, 0x00, 0x00, 0x18, 0x03, 0xa5, 0x43, +0x77, 0x34, 0x84, 0x6d, 0xab, 0x16, 0x8a, 0x45, 0x85, 0x14, 0x00, 0x57, 0x15, 0xe2, 0x5d, 0x30, +0x3a, 0x9b, 0x84, 0x5f, 0xbd, 0xd7, 0xd8, 0xd3, 0x4f, 0x53, 0x3a, 0x8a, 0xe8, 0xf1, 0xdd, 0x4e, +0xd7, 0x05, 0xb8, 0xae, 0x2e, 0xf6, 0x1c, 0x16, 0x35, 0x66, 0x48, 0xe7, 0x2e, 0x13, 0x93, 0xf5, +0xac, 0x59, 0x93, 0xad, 0x2d, 0xcb, 0x33, 0x65, 0x18, 0xcd, 0x52, 0x90, 0x77, 0xa5, 0x72, 0x91, +0x51, 0xc7, 0xe3, 0x54, 0xe5, 0x65, 0x5c, 0xe4, 0xf3, 0xe9, 0x49, 0x94, 0x51, 0x6f, 0x32, 0x4f, +0xf6, 0x13, 0xf5, 0x35, 0x0e, 0xdf, 0x29, 0xc7, 0x70, 0xdd, 0x18, 0xf6, 0xa7, 0x7e, 0xc5, 0x2d, +0x58, 0xe7, 0xe6, 0xa0, 0x6c, 0xe3, 0xd6, 0x93, 0xd4, 0xd1, 0x0c, 0xe4, 0xd4, 0x64, 0xfa, 0xf3, +0x4b, 0x42, 0xfc, 0xd8, 0x99, 0xe9, 0x9f, 0xff, 0x00, 0x5d, 0x2e, 0x7b, 0xd2, 0xbd, 0xcd, 0x16, +0xa1, 0x93, 0xcf, 0xaf, 0x5a, 0x50, 0x4f, 0xb7, 0xd6, 0x93, 0xd7, 0x42, 0xcf, 0x46, 0x36, 0x77, +0x51, 0x1c, 0xa9, 0x7e, 0x3b, 0x8c, 0xd5, 0xdb, 0x7d, 0x5a, 0xfe, 0xd0, 0xf2, 0x5c, 0x80, 0x79, +0x0d, 0x9a, 0x8d, 0xce, 0x79, 0x1d, 0x25, 0xa7, 0x8a, 0x21, 0x6c, 0x2d, 0xdc, 0x65, 0x49, 0xfe, +0x30, 0x7a, 0x56, 0xec, 0x17, 0xf6, 0x17, 0x67, 0x6c, 0x53, 0xc6, 0x4b, 0x7f, 0x0b, 0x11, 0x9a, +0xd2, 0x35, 0x1a, 0xd1, 0x9c, 0xd5, 0x29, 0xdf, 0x54, 0x73, 0xfa, 0xe6, 0x8f, 0x90, 0x6e, 0xad, +0x94, 0x6e, 0xea, 0xea, 0xa3, 0xad, 0x72, 0x03, 0x39, 0xe7, 0xaf, 0x4e, 0x68, 0x9e, 0x8f, 0x43, +0x4a, 0x52, 0xe6, 0x5a, 0x93, 0x2f, 0xe3, 0x9a, 0xb0, 0xb9, 0xcf, 0xd6, 0xa6, 0xf7, 0x2d, 0xf7, +0x2c, 0x21, 0xab, 0xb1, 0xf2, 0x47, 0xf3, 0xaa, 0xf2, 0x21, 0xf7, 0x34, 0x61, 0xeb, 0xde, 0xb7, +0xad, 0x07, 0x4f, 0x7a, 0x08, 0x67, 0x6f, 0xa0, 0xd8, 0x2d, 0xed, 0xd4, 0x30, 0x60, 0x30, 0x96, +0x45, 0x03, 0x70, 0xc8, 0xce, 0x6b, 0xdf, 0xf4, 0xfd, 0x3a, 0xdf, 0x4f, 0x85, 0x63, 0x89, 0x41, +0x60, 0x30, 0xd2, 0x63, 0x93, 0x55, 0x7b, 0xa2, 0x22, 0xae, 0xcd, 0x0a, 0x29, 0x1a, 0x85, 0x14, +0x00, 0x51, 0x40, 0x05, 0x43, 0x3c, 0x2b, 0x71, 0x13, 0xc6, 0xe3, 0x21, 0x87, 0x7a, 0x04, 0xd5, +0xd5, 0x8f, 0x1b, 0xd7, 0xf4, 0xf3, 0x04, 0xb2, 0x29, 0x5e, 0x87, 0xad, 0x79, 0x96, 0xa1, 0x16, +0xd2, 0xdc, 0x55, 0x5c, 0xe7, 0xf2, 0x39, 0x4b, 0xa5, 0xeb, 0x58, 0x33, 0xaf, 0x26, 0x82, 0xae, +0x65, 0x4a, 0x3f, 0xfd, 0x75, 0x9d, 0x29, 0x0b, 0xc9, 0x38, 0x1e, 0xf4, 0xac, 0x5d, 0xcc, 0xf7, +0x77, 0x7e, 0x10, 0x1c, 0x7f, 0x78, 0x8a, 0x80, 0xc6, 0x07, 0x2d, 0xf3, 0x31, 0xee, 0x69, 0x96, +0xa5, 0xa9, 0x13, 0x0a, 0xab, 0x2a, 0x87, 0x04, 0x1c, 0x67, 0xd7, 0xd2, 0x93, 0x02, 0xba, 0x9d, +0xc0, 0xab, 0x1f, 0x99, 0x7a, 0xfb, 0xd3, 0x5f, 0xad, 0x06, 0x8b, 0x62, 0x2f, 0xd6, 0x98, 0x69, +0x32, 0xd6, 0xa8, 0x69, 0xe3, 0xfc, 0x73, 0x4b, 0xcf, 0x3e, 0xfe, 0xa2, 0x93, 0x77, 0x2d, 0x0e, +0x1d, 0x79, 0xe6, 0x9c, 0x07, 0xa6, 0x79, 0xa9, 0x6d, 0x5f, 0x53, 0x4e, 0x87, 0xa1, 0x43, 0xaf, +0x38, 0xe2, 0x65, 0x0e, 0x0f, 0x5e, 0x2b, 0x52, 0x3d, 0x46, 0xc2, 0x71, 0x89, 0x17, 0x69, 0x3d, +0xcf, 0x35, 0x16, 0xd4, 0xc1, 0xdc, 0x92, 0x4b, 0x1b, 0x4b, 0x88, 0xcb, 0x41, 0x22, 0xee, 0x23, +0xd6, 0xb9, 0x4b, 0xa3, 0x75, 0xa7, 0xcf, 0x86, 0x2c, 0x9c, 0xf0, 0xcb, 0xde, 0x9a, 0x7d, 0xc9, +0x5a, 0x9d, 0xa6, 0x81, 0xe2, 0x3f, 0x3b, 0x6d, 0x9d, 0xf3, 0x16, 0x0c, 0x76, 0xac, 0xa7, 0xfa, +0xd2, 0x6b, 0x7a, 0x6f, 0xd9, 0x66, 0xfb, 0x44, 0x43, 0xf7, 0x13, 0x1c, 0x82, 0x3b, 0x1a, 0xbb, +0xf3, 0x2d, 0x48, 0x71, 0xf6, 0x73, 0xf5, 0x31, 0x54, 0xfd, 0x6a, 0x75, 0x26, 0xa4, 0xb7, 0xa9, +0x69, 0x7f, 0x5f, 0x5a, 0xb7, 0x1f, 0xd6, 0xa8, 0xcd, 0xea, 0x5f, 0x49, 0x00, 0x20, 0x72, 0x4f, +0xa0, 0xad, 0xdb, 0x2d, 0xce, 0xc0, 0xb9, 0xc0, 0xfe, 0xe8, 0xaa, 0x44, 0x49, 0xdc, 0xf4, 0xef, +0x0d, 0x48, 0x23, 0xb8, 0x85, 0xc7, 0x05, 0x1c, 0x10, 0x7d, 0x39, 0xaf, 0x7a, 0x8a, 0x41, 0x2c, +0x69, 0x22, 0x9c, 0x87, 0x19, 0xa1, 0x93, 0x0d, 0xc7, 0xd1, 0x41, 0xa8, 0x51, 0x40, 0x05, 0x14, +0x00, 0x51, 0x40, 0x1c, 0x8f, 0x8a, 0x2c, 0x04, 0xd6, 0xe6, 0xe1, 0x57, 0x90, 0x30, 0xd5, 0xe1, +0x5a, 0xb4, 0x5b, 0x59, 0xf8, 0xee, 0x69, 0xa3, 0x9a, 0x7a, 0x48, 0xe1, 0xee, 0xd7, 0x96, 0xae, +0x7a, 0xe3, 0xa9, 0xcf, 0xe7, 0x45, 0x8a, 0x46, 0x1c, 0xf2, 0xe4, 0x90, 0x9f, 0x31, 0xfe, 0x55, +0x9e, 0xf1, 0x93, 0xf3, 0x39, 0xc9, 0xf4, 0xa6, 0x55, 0xee, 0x8a, 0xef, 0xc5, 0x56, 0x72, 0x28, +0x29, 0x15, 0xdf, 0xeb, 0x55, 0x9b, 0xdc, 0xf5, 0xa4, 0xca, 0x45, 0x29, 0x72, 0xad, 0xe6, 0x2e, +0x4f, 0x63, 0xef, 0x4a, 0x4e, 0xe0, 0x18, 0x74, 0x3c, 0x8a, 0x1b, 0x2d, 0x6a, 0x46, 0x7f, 0x3a, +0x69, 0xc1, 0xfc, 0xbb, 0xd4, 0xec, 0x68, 0x98, 0xde, 0x3d, 0xfe, 0xb4, 0x7f, 0x5a, 0x2f, 0x72, +0xf4, 0x1e, 0x38, 0xa7, 0x0e, 0x4e, 0x7f, 0x3a, 0x5b, 0x95, 0x75, 0xb1, 0xbe, 0xcb, 0xb3, 0xef, +0x1c, 0x54, 0x06, 0xe9, 0x14, 0xf5, 0x26, 0x84, 0x46, 0xe3, 0xd7, 0x51, 0x91, 0x71, 0xe5, 0xb1, +0x1e, 0xf9, 0xab, 0x6f, 0x7e, 0xd7, 0x90, 0x98, 0x67, 0xc3, 0xe3, 0xee, 0xb1, 0xea, 0x2a, 0x5b, +0x05, 0x0e, 0xa5, 0x18, 0x19, 0xa2, 0x7e, 0x49, 0xe3, 0xa1, 0xaf, 0x57, 0xd0, 0x6e, 0xd3, 0x58, +0xb0, 0x7d, 0x3e, 0xe5, 0xb7, 0x4a, 0x8b, 0xc1, 0xef, 0x8e, 0xc6, 0xa6, 0x9b, 0xf7, 0xb5, 0x1e, +0x22, 0x37, 0x85, 0xd7, 0x43, 0x9d, 0xb9, 0xb6, 0x96, 0xd2, 0x77, 0x82, 0x55, 0x21, 0xd0, 0xfa, +0x75, 0xf7, 0xa4, 0x43, 0xff, 0x00, 0xeb, 0xad, 0x3a, 0xd8, 0xc2, 0xf7, 0x57, 0x2c, 0x06, 0x00, +0x65, 0x88, 0xfa, 0x9a, 0x9a, 0x37, 0x79, 0x0f, 0xc9, 0xf2, 0xaf, 0xf7, 0x8f, 0x53, 0x41, 0x2c, +0xd5, 0xb7, 0x50, 0xbd, 0x32, 0x58, 0xf5, 0x26, 0xb7, 0xed, 0x1b, 0x91, 0x9a, 0xa5, 0xb9, 0x94, +0x8e, 0xdf, 0x49, 0x9f, 0x63, 0xa1, 0xcf, 0x39, 0x1c, 0xd7, 0xba, 0xe8, 0x17, 0xa2, 0xe6, 0xd1, +0x10, 0x9f, 0x99, 0x07, 0x15, 0x4d, 0x19, 0xa9, 0x5a, 0x46, 0xfd, 0x15, 0x27, 0x48, 0x51, 0x40, +0x05, 0x14, 0x00, 0x51, 0x40, 0x10, 0x5c, 0xc2, 0xb7, 0x10, 0x4b, 0x0b, 0x74, 0x91, 0x71, 0xf4, +0xaf, 0x9d, 0xbc, 0x45, 0x17, 0x93, 0x71, 0x3c, 0x64, 0x60, 0xa3, 0x30, 0x23, 0xd3, 0x9a, 0x6b, +0x73, 0x1a, 0xbb, 0xdc, 0xf3, 0x3b, 0xe9, 0x15, 0x4b, 0x0c, 0xe4, 0xe7, 0xa0, 0xae, 0x6a, 0xe1, +0x5a, 0x42, 0x77, 0x9c, 0x29, 0xfe, 0x11, 0x55, 0xe6, 0x4a, 0x33, 0x24, 0x00, 0x64, 0x01, 0x54, +0x24, 0xf7, 0xa0, 0xa5, 0xa9, 0x4d, 0xcf, 0x7a, 0xa8, 0xff, 0x00, 0xe7, 0x34, 0x99, 0x77, 0xbe, +0xe4, 0x0d, 0xcd, 0x57, 0x61, 0xeb, 0xde, 0x9b, 0x1a, 0x2b, 0xb0, 0xe3, 0x18, 0xcd, 0x55, 0x19, +0x8d, 0x8a, 0x37, 0x43, 0xc8, 0xcd, 0x4f, 0x91, 0xa2, 0xee, 0x38, 0xf5, 0x39, 0xeb, 0x4c, 0x3e, +0xf4, 0x17, 0x11, 0x9c, 0xe7, 0xfc, 0x29, 0x79, 0xcf, 0xd7, 0xf5, 0xa9, 0xd8, 0xb1, 0xfd, 0xc5, +0x48, 0x06, 0x4d, 0x26, 0x5a, 0x76, 0x26, 0x9a, 0xe1, 0xe4, 0x39, 0x24, 0xe0, 0xd4, 0x0b, 0xf3, +0x1e, 0x73, 0x53, 0xcc, 0x5c, 0x21, 0xa1, 0x61, 0x57, 0x3d, 0x3b, 0x55, 0xb4, 0xe3, 0xbf, 0x3e, +0xb5, 0x37, 0xb9, 0x4d, 0x58, 0x95, 0xc6, 0x40, 0x71, 0xd5, 0x7f, 0x5a, 0xdb, 0xd1, 0xef, 0xde, +0xce, 0xe6, 0x29, 0xd0, 0x9f, 0x94, 0xf2, 0x33, 0xd4, 0x77, 0x15, 0x17, 0x69, 0xdc, 0x25, 0x69, +0x2b, 0x33, 0xd3, 0xf5, 0xcd, 0x3c, 0x6a, 0x36, 0x29, 0xaa, 0xdb, 0x00, 0xcd, 0x0a, 0x03, 0x20, +0x41, 0x92, 0xc9, 0xeb, 0xf8, 0x66, 0xb8, 0x2f, 0x33, 0x9d, 0xa8, 0x37, 0x1e, 0x9f, 0x4a, 0xe8, +0xdf, 0x53, 0xcf, 0x83, 0xd1, 0xa7, 0xd0, 0xb3, 0x1c, 0x79, 0x3b, 0xa4, 0x3b, 0x8f, 0xa7, 0x61, +0x5a, 0x11, 0xf0, 0x73, 0x45, 0xc6, 0xcd, 0x18, 0x8d, 0x6c, 0xdb, 0x1e, 0x9d, 0x6a, 0xa2, 0x65, +0x23, 0xa9, 0xb0, 0x97, 0x6b, 0x0e, 0x79, 0xcd, 0x7a, 0x97, 0x86, 0xf5, 0x13, 0x14, 0x89, 0xc9, +0xc1, 0xe0, 0xf3, 0x5a, 0xdb, 0x43, 0x09, 0x6e, 0x7a, 0x9a, 0xb0, 0x75, 0x0c, 0x0e, 0x41, 0x19, +0xa7, 0x56, 0x4c, 0xea, 0x4e, 0xea, 0xe1, 0x45, 0x21, 0x85, 0x14, 0x00, 0x51, 0x40, 0x19, 0xfa, +0x86, 0xa9, 0x65, 0xa6, 0x44, 0xd2, 0xdd, 0x4c, 0xaa, 0x40, 0xc8, 0x88, 0x10, 0x5d, 0xbe, 0x82, +0xbe, 0x70, 0xf1, 0x56, 0xa8, 0x97, 0xd7, 0xd7, 0x37, 0x11, 0x46, 0x60, 0x8e, 0x67, 0x27, 0x66, +0xec, 0x91, 0xef, 0x9a, 0xa4, 0x61, 0x56, 0x49, 0xb4, 0x91, 0xe7, 0x97, 0x45, 0x46, 0xe2, 0x3a, +0xfa, 0xf7, 0xac, 0x19, 0xd8, 0x92, 0x79, 0x3c, 0xd5, 0x12, 0x8c, 0xa9, 0x7b, 0xf3, 0x54, 0x24, +0xfe, 0xb4, 0x8b, 0x2a, 0x3d, 0x55, 0x71, 0xfe, 0x49, 0xa4, 0xca, 0x45, 0x76, 0xe7, 0x35, 0x03, +0x77, 0xa4, 0xca, 0xb9, 0x03, 0x8f, 0xce, 0xab, 0xc8, 0xbb, 0x94, 0x81, 0xd7, 0xa8, 0xf5, 0xa3, +0xcc, 0xd0, 0x89, 0x1b, 0x70, 0xe7, 0xef, 0x0e, 0x08, 0x34, 0x11, 0xf8, 0xd0, 0xca, 0x5a, 0x8c, +0xe8, 0x49, 0xfe, 0x74, 0xa3, 0xf3, 0x34, 0xac, 0x5a, 0x44, 0x83, 0x1f, 0x8d, 0x4c, 0xbc, 0x9a, +0x4c, 0xb5, 0xa9, 0x54, 0xb7, 0xbd, 0x3d, 0x0e, 0x4f, 0xe3, 0x58, 0x36, 0x75, 0x5a, 0xdb, 0x9a, +0x11, 0x1f, 0x6e, 0x7d, 0x6a, 0x6c, 0xf3, 0x40, 0x49, 0x5c, 0x9d, 0x1b, 0xb7, 0x5c, 0xd3, 0xe3, +0x3b, 0x1f, 0x1d, 0x8f, 0x22, 0x91, 0x1a, 0xdc, 0xf6, 0x3f, 0x00, 0xeb, 0x31, 0x97, 0x16, 0x17, +0x60, 0x4a, 0x9c, 0x90, 0x8d, 0xd1, 0xd0, 0x8c, 0x15, 0xaa, 0x1e, 0x2a, 0xf0, 0xf9, 0xf0, 0xf6, +0xad, 0x2c, 0x11, 0xaf, 0xfa, 0x0d, 0xd8, 0x17, 0x36, 0x72, 0x0e, 0x8d, 0x13, 0x72, 0x07, 0xd4, +0x74, 0xff, 0x00, 0xf5, 0xd6, 0xf1, 0x7e, 0xe9, 0xe7, 0xcd, 0x72, 0xd5, 0x6b, 0xb9, 0x82, 0xb5, +0x6d, 0x3a, 0xff, 0x00, 0x5a, 0x60, 0xfc, 0xcb, 0xd1, 0x1a, 0xd5, 0xb7, 0x6c, 0x1f, 0x5a, 0xd2, +0x3a, 0x99, 0x48, 0xdf, 0xb5, 0x93, 0x04, 0x73, 0x5d, 0xae, 0x97, 0x75, 0xb5, 0x94, 0xe7, 0x9a, +0xd5, 0x18, 0x4b, 0x73, 0xd9, 0x34, 0x3b, 0xf1, 0x73, 0x00, 0x42, 0xd9, 0x75, 0xe9, 0x9a, 0xdf, +0xac, 0x66, 0xb5, 0x36, 0xa4, 0xef, 0x1b, 0x05, 0x15, 0x26, 0xa1, 0x45, 0x00, 0x23, 0x32, 0xa0, +0x2c, 0xec, 0x15, 0x47, 0x25, 0x98, 0xf4, 0xae, 0x4b, 0x57, 0xf1, 0x3c, 0x76, 0xaa, 0xc9, 0x68, +0x43, 0x38, 0xff, 0x00, 0x96, 0xac, 0x32, 0x07, 0xd0, 0x53, 0x4a, 0xe6, 0x55, 0x6a, 0x72, 0x2d, +0x0f, 0x22, 0xd5, 0xf5, 0x79, 0x6e, 0x5d, 0xde, 0x49, 0x59, 0xdd, 0xb9, 0x2c, 0xc7, 0xad, 0x70, +0x57, 0xf3, 0x99, 0x37, 0x02, 0x7a, 0xfa, 0xd6, 0x9b, 0xad, 0x0e, 0x74, 0xf5, 0xd4, 0xe5, 0xe5, +0x94, 0x92, 0x50, 0x9e, 0x47, 0xaf, 0x7a, 0xcb, 0x98, 0xf2, 0x79, 0xe6, 0x91, 0xa9, 0x99, 0x29, +0xce, 0x7d, 0x6a, 0x93, 0xfa, 0xfa, 0xd2, 0x28, 0xa8, 0xff, 0x00, 0x9f, 0xd6, 0xaa, 0xbf, 0x7f, +0x4f, 0x7a, 0x95, 0x66, 0x59, 0x03, 0xd4, 0x0d, 0x54, 0xc0, 0x81, 0x81, 0xe7, 0xf3, 0xe6, 0xa3, +0x27, 0xaf, 0xad, 0x06, 0x89, 0xd9, 0x94, 0xe4, 0x05, 0x1b, 0xcc, 0xed, 0xfc, 0x54, 0xec, 0xe7, +0xbf, 0x5e, 0x86, 0x97, 0x91, 0x7d, 0x46, 0x9c, 0xe7, 0x9a, 0x51, 0x9e, 0xbd, 0x2a, 0x6e, 0xed, +0x73, 0x4d, 0x6f, 0xa8, 0xfc, 0x81, 0xc9, 0xe9, 0xde, 0x95, 0x5c, 0xb1, 0xc2, 0x0f, 0xf8, 0x11, +0xa5, 0xd4, 0x7b, 0xd8, 0x81, 0x94, 0x82, 0x47, 0x5a, 0x72, 0x67, 0x3c, 0xf3, 0x93, 0x5c, 0xf7, +0x3b, 0x2e, 0x5f, 0x88, 0x9a, 0xb9, 0x8c, 0x8c, 0xff, 0x00, 0x5a, 0x13, 0xd4, 0x24, 0xf4, 0x1c, +0xbc, 0x1f, 0x7a, 0x9c, 0x8d, 0xcb, 0x91, 0xd5, 0x68, 0xb9, 0x95, 0xcd, 0x6d, 0x26, 0xf9, 0xed, +0x2e, 0x61, 0xb8, 0x8c, 0xe1, 0xa3, 0x6c, 0xf5, 0xeb, 0x5f, 0x48, 0xdf, 0xda, 0xa7, 0x8d, 0x7c, +0x12, 0x25, 0xb6, 0x2a, 0xfa, 0x8e, 0x81, 0x1b, 0x5d, 0xdb, 0x80, 0x37, 0x34, 0x91, 0x11, 0xfb, +0xc8, 0xfe, 0xbc, 0x64, 0x7b, 0x81, 0x5a, 0xd3, 0x7d, 0x0e, 0x4c, 0x4a, 0xb3, 0x52, 0x3c, 0x31, +0x4d, 0x5a, 0x43, 0xcf, 0x5a, 0xd3, 0x73, 0x36, 0x5c, 0x8d, 0xba, 0x56, 0x8c, 0x2f, 0xd3, 0x9e, +0x6a, 0xd1, 0x94, 0xb5, 0x36, 0x6d, 0xe4, 0x1c, 0x57, 0x49, 0x65, 0x71, 0x86, 0x1c, 0xd6, 0xa8, +0xc5, 0xd8, 0xf4, 0x4d, 0x07, 0x53, 0x30, 0xca, 0x87, 0x77, 0x19, 0xf5, 0xaf, 0x58, 0x82, 0x65, +0x9e, 0x24, 0x91, 0x48, 0x3b, 0x86, 0x4f, 0xb5, 0x4d, 0x45, 0xa5, 0xc7, 0x49, 0xda, 0x56, 0x26, +0xa2, 0xb1, 0x3a, 0x42, 0xb2, 0xaf, 0x75, 0x7b, 0x5b, 0x40, 0x7e, 0x75, 0x91, 0xc7, 0x65, 0x3c, +0x0f, 0xc6, 0x9a, 0x57, 0x22, 0x73, 0x50, 0x57, 0x67, 0x9f, 0x6a, 0xfe, 0x23, 0x92, 0xe3, 0x23, +0x7e, 0x14, 0x74, 0x50, 0x78, 0x15, 0xc0, 0x5f, 0x6a, 0x0c, 0xe4, 0x92, 0xd9, 0xf7, 0xcd, 0x6a, +0x95, 0x8e, 0x46, 0xdc, 0x9d, 0xd9, 0xcb, 0x5d, 0xdd, 0x67, 0x3c, 0xe6, 0xb9, 0xf9, 0xe6, 0xc9, +0x3e, 0xf4, 0x99, 0x51, 0x46, 0x1d, 0xd1, 0xc1, 0xde, 0x39, 0x23, 0xad, 0x67, 0xc8, 0xdb, 0xbe, +0x61, 0x4b, 0xcc, 0xd3, 0xa9, 0x4a, 0x43, 0xf5, 0xaa, 0x4f, 0xce, 0x4e, 0x73, 0x4a, 0xe5, 0x15, +0x1e, 0xab, 0x3d, 0x22, 0x91, 0x03, 0x67, 0xf1, 0xa8, 0x1b, 0x9f, 0xad, 0x0d, 0xe8, 0x5e, 0xfa, +0x10, 0xbf, 0xbd, 0x42, 0xd4, 0x5c, 0xab, 0x5f, 0x52, 0x17, 0x00, 0xe4, 0x1e, 0xe3, 0x15, 0x55, +0x49, 0x46, 0x31, 0x9f, 0xf8, 0x09, 0x34, 0x3d, 0xcb, 0xb1, 0x29, 0xc7, 0x24, 0x9c, 0x7b, 0x9a, +0x88, 0xca, 0x49, 0x21, 0x06, 0xe3, 0xeb, 0xda, 0xa5, 0xea, 0x5a, 0x1e, 0x23, 0x24, 0xe6, 0x46, +0xc9, 0x3f, 0xa5, 0x5b, 0x5c, 0x0f, 0x4c, 0xd2, 0xd8, 0xaf, 0x53, 0x24, 0xdc, 0x9f, 0xc7, 0xb9, +0xa9, 0x52, 0x66, 0x63, 0xc7, 0xe6, 0x6b, 0x36, 0x91, 0xd1, 0xab, 0x2f, 0xc4, 0xcd, 0xd7, 0x75, +0x5d, 0x49, 0x0f, 0x19, 0xa9, 0x63, 0x7d, 0xd9, 0x3a, 0x9c, 0xd5, 0x88, 0xdb, 0x07, 0x9e, 0x94, +0x9a, 0xd2, 0xc4, 0xf5, 0x24, 0x43, 0xe5, 0xc9, 0x8e, 0xcd, 0xc8, 0xaf, 0x6f, 0xf8, 0x57, 0xe2, +0x57, 0xd3, 0xf5, 0x18, 0xed, 0x24, 0x62, 0x51, 0xd8, 0x15, 0x53, 0xdc, 0x7f, 0x10, 0xfc, 0x45, +0x54, 0x74, 0x66, 0x38, 0x85, 0xcd, 0x16, 0x33, 0xe2, 0x17, 0x87, 0x57, 0x40, 0xd7, 0xe5, 0x6b, +0x54, 0xc6, 0x97, 0xaa, 0x2f, 0xda, 0xec, 0xd9, 0x7a, 0x00, 0x7e, 0xf2, 0x7f, 0xc0, 0x5b, 0x3c, +0x7a, 0x11, 0x5c, 0x52, 0x9f, 0x7a, 0xd9, 0xea, 0xce, 0x48, 0xca, 0xf1, 0x2d, 0x21, 0xfc, 0x6a, +0xf4, 0x4f, 0xce, 0x7f, 0x5a, 0xa5, 0xe4, 0x4c, 0x8d, 0x48, 0x64, 0xad, 0x9b, 0x79, 0xb1, 0x8c, +0x1f, 0xce, 0xb5, 0x4c, 0xc6, 0x47, 0x4b, 0x63, 0x78, 0x51, 0x81, 0xdc, 0x6b, 0xd4, 0x3c, 0x3f, +0xaf, 0xaa, 0x62, 0x29, 0x5b, 0xe4, 0x38, 0x07, 0xda, 0x9c, 0xb5, 0x46, 0x77, 0x71, 0x77, 0x3d, +0x09, 0x24, 0x49, 0x50, 0x48, 0x8c, 0x1d, 0x18, 0x64, 0x30, 0x3d, 0x6a, 0x9d, 0xe6, 0xa7, 0x69, +0x62, 0x3f, 0x7d, 0x27, 0xcf, 0xd4, 0x46, 0xbc, 0x93, 0x58, 0x5a, 0xfa, 0x1d, 0x6e, 0x69, 0x2e, +0x63, 0x88, 0xd4, 0xfc, 0x52, 0xef, 0xb9, 0x22, 0x3e, 0x5c, 0x67, 0x23, 0x68, 0xef, 0xf8, 0xd7, +0x0f, 0x7b, 0xab, 0x3c, 0x85, 0xb2, 0xe6, 0xb4, 0x4a, 0xc8, 0xe5, 0x93, 0x73, 0x77, 0x39, 0xab, +0x9b, 0xe2, 0xc0, 0xfc, 0xc7, 0x26, 0xb0, 0xae, 0x2e, 0x49, 0xc9, 0xcd, 0x0d, 0x85, 0x8c, 0x69, +0xa6, 0x27, 0x3c, 0xd6, 0x5c, 0xd2, 0x67, 0x3c, 0xd2, 0xdc, 0xad, 0x8c, 0xc9, 0x5b, 0x3e, 0xf5, +0x98, 0x58, 0xab, 0x94, 0x27, 0x83, 0xc8, 0xa3, 0x72, 0x93, 0xb9, 0x03, 0x9a, 0xa8, 0xf4, 0x8b, +0x2b, 0x3f, 0x35, 0x59, 0xe8, 0xb9, 0x45, 0x76, 0xcf, 0x35, 0x0b, 0x54, 0xfa, 0x8f, 0x76, 0x40, +0xdc, 0xf5, 0xa8, 0x4f, 0xff, 0x00, 0xab, 0x8a, 0x11, 0xa2, 0xf2, 0x21, 0x62, 0x3a, 0x9a, 0xa1, +0x3c, 0x81, 0x8e, 0x13, 0x71, 0x61, 0xfc, 0x5e, 0x94, 0x6f, 0xb1, 0x4b, 0xbb, 0x15, 0x15, 0xa6, +0xe5, 0xdb, 0x23, 0xfb, 0xb5, 0x38, 0x50, 0xbf, 0x77, 0x03, 0xfa, 0xd0, 0xca, 0x4f, 0xb9, 0x20, +0x3f, 0x9d, 0x4a, 0x0f, 0x7e, 0xf5, 0x17, 0x34, 0xdf, 0x53, 0x94, 0x31, 0x49, 0xce, 0x1c, 0xe7, +0xd6, 0xae, 0xd9, 0xcc, 0xc4, 0x98, 0xa5, 0x03, 0x78, 0xe4, 0x1f, 0x51, 0x49, 0xb3, 0xa7, 0x5e, +0xa6, 0xca, 0x1c, 0xf3, 0x57, 0x10, 0xf6, 0xc9, 0xac, 0x9e, 0xc0, 0xf4, 0x2d, 0x29, 0x3d, 0x2a, +0x71, 0x9a, 0x49, 0xb2, 0x19, 0x60, 0xe5, 0xd7, 0xbe, 0xe1, 0xd3, 0x35, 0xa7, 0xa5, 0xdf, 0x49, +0x6b, 0x71, 0x05, 0xcc, 0x64, 0x89, 0x20, 0x70, 0xe0, 0xfb, 0x83, 0x4e, 0xe2, 0x69, 0x49, 0x1f, +0x53, 0xcc, 0xb1, 0xfc, 0x41, 0xf0, 0x3f, 0x91, 0x06, 0x1f, 0x55, 0xd3, 0x87, 0xda, 0xed, 0x02, +0xf0, 0x58, 0x80, 0x43, 0xc7, 0xcf, 0xa8, 0x27, 0xf1, 0xc7, 0xa5, 0x7c, 0xf2, 0x38, 0x27, 0x39, +0x07, 0xde, 0xba, 0x13, 0xbd, 0x99, 0xe6, 0xc7, 0x4b, 0xc5, 0x93, 0x2b, 0x7b, 0xd5, 0xb8, 0xdf, +0xde, 0xa9, 0x30, 0x7b, 0x97, 0xe2, 0x7f, 0x73, 0x5a, 0x50, 0xcd, 0x83, 0x9c, 0xfe, 0x75, 0x71, +0x7d, 0xcc, 0xe7, 0xa9, 0xab, 0x05, 0xd6, 0xde, 0xf5, 0xb3, 0x6f, 0xa9, 0xf9, 0x44, 0x12, 0xf8, +0xc7, 0xbf, 0x5a, 0xb6, 0xcc, 0xac, 0x74, 0x36, 0xde, 0x2b, 0xbe, 0xb7, 0x88, 0xc3, 0x15, 0xc3, +0xc5, 0x13, 0x9c, 0x9c, 0x1c, 0x55, 0x39, 0xf5, 0x89, 0x24, 0xc9, 0x67, 0x24, 0x9e, 0xe4, 0xf5, +0xa8, 0xd0, 0x66, 0x4c, 0xda, 0x81, 0x6c, 0xfc, 0xd5, 0x95, 0x2d, 0xe1, 0x39, 0xcb, 0x73, 0x43, +0x03, 0x3a, 0x5b, 0x92, 0x7f, 0x8b, 0xf1, 0xac, 0xe9, 0x67, 0xce, 0x79, 0xa5, 0x71, 0xaf, 0x33, +0x3e, 0x49, 0x09, 0xc9, 0xcd, 0x51, 0x91, 0xb3, 0xef, 0x9a, 0x2e, 0x36, 0x52, 0x91, 0xaa, 0x84, +0xe0, 0xb0, 0xc8, 0xfb, 0xc3, 0x91, 0x4a, 0xe5, 0x22, 0xb6, 0xed, 0xcb, 0x9e, 0x73, 0xdf, 0x35, +0x0b, 0x77, 0xa5, 0x72, 0xd1, 0x55, 0x87, 0xd7, 0x9a, 0xae, 0xe3, 0xad, 0x2d, 0xf7, 0x19, 0x5d, +0xaa, 0x06, 0xef, 0x4e, 0xf7, 0x29, 0x95, 0xdf, 0xeb, 0x8c, 0x77, 0xaa, 0x52, 0x4c, 0x37, 0x61, +0x01, 0x66, 0xf6, 0xa9, 0x2e, 0xe8, 0x81, 0xa3, 0x67, 0x39, 0x90, 0x9f, 0x65, 0x14, 0xe0, 0xa1, +0x7a, 0x0c, 0x55, 0x3b, 0x6c, 0x87, 0xbe, 0xa5, 0x62, 0x7c, 0xb9, 0x33, 0xfc, 0x0f, 0xda, 0xac, +0x67, 0xf5, 0x15, 0x2c, 0xd2, 0xe3, 0xb3, 0xf5, 0xe2, 0xa4, 0x0d, 0x9f, 0xfe, 0xb5, 0x0b, 0x52, +0xaf, 0x63, 0x1c, 0xa1, 0xeb, 0xd7, 0xf5, 0xa8, 0x24, 0x52, 0x8c, 0xb2, 0x8c, 0xee, 0x43, 0x9f, +0xad, 0x67, 0xdc, 0xec, 0x6e, 0xe8, 0xd9, 0x81, 0xf7, 0x2a, 0xb0, 0x39, 0x0c, 0x33, 0x9a, 0xba, +0xa7, 0xa7, 0xaf, 0xad, 0x67, 0xb3, 0xd4, 0x4f, 0x52, 0xd2, 0xb7, 0xf8, 0x54, 0xea, 0xde, 0xbf, +0x9d, 0x08, 0xcd, 0x96, 0x11, 0xb9, 0x15, 0x22, 0x9f, 0x2e, 0x4e, 0x0f, 0x0c, 0x69, 0xa1, 0x74, +0x3d, 0x8f, 0xe1, 0x97, 0x8a, 0x1f, 0x4a, 0xd4, 0x52, 0xd9, 0xe4, 0xc2, 0x48, 0xdb, 0x90, 0x96, +0xc0, 0x07, 0xb8, 0xfc, 0x45, 0x69, 0xfc, 0x4a, 0xf0, 0xfc, 0x3a, 0x3e, 0xb4, 0xb7, 0xf6, 0x11, +0x91, 0xa5, 0x6b, 0x49, 0xf6, 0x88, 0x4a, 0x2e, 0x12, 0x37, 0xcf, 0xcf, 0x1e, 0x7d, 0x8f, 0x38, +0xf7, 0xad, 0x62, 0xee, 0x8e, 0x0a, 0xbe, 0xed, 0x4f, 0x53, 0xcf, 0x15, 0xaa, 0xc2, 0x3f, 0x35, +0x77, 0x27, 0x62, 0xe2, 0x3f, 0xbf, 0xeb, 0x56, 0x96, 0x5c, 0x72, 0x5b, 0x03, 0xd4, 0x9a, 0xa2, +0x19, 0x3a, 0xdd, 0x31, 0xe1, 0x7f, 0xef, 0xaa, 0xb5, 0x14, 0xe4, 0x72, 0xcc, 0x58, 0xfb, 0x9a, +0xae, 0x6e, 0xa4, 0x34, 0x5b, 0x37, 0x64, 0xaf, 0x53, 0x91, 0xc8, 0xe6, 0x8f, 0xb6, 0x96, 0x5c, +0xe4, 0xe7, 0xbf, 0x35, 0x2d, 0xdc, 0x4d, 0x10, 0x35, 0xd1, 0x39, 0xe7, 0xf5, 0xaa, 0xb2, 0x5c, +0x1c, 0x9e, 0x68, 0xbe, 0xa1, 0x62, 0xb3, 0x4c, 0x7d, 0x6a, 0xab, 0xc9, 0x9c, 0xf3, 0x40, 0x3d, +0x4a, 0xec, 0xf9, 0xcf, 0xf5, 0xaa, 0x8e, 0x72, 0x68, 0x02, 0xb3, 0xd5, 0x59, 0x29, 0x14, 0x8a, +0x4e, 0x36, 0x3e, 0x7b, 0x3f, 0x07, 0xda, 0x9a, 0xe0, 0xff, 0x00, 0xf5, 0xe8, 0x63, 0x2b, 0xb0, +0xef, 0x55, 0x9c, 0x54, 0xf4, 0x2d, 0x15, 0x9f, 0xa9, 0x35, 0x46, 0x49, 0x46, 0x48, 0x5c, 0xb1, +0xf6, 0x14, 0xdb, 0x28, 0xac, 0xd1, 0xbb, 0x92, 0x64, 0x38, 0x1f, 0xdd, 0x14, 0xc2, 0xa1, 0x7a, +0x00, 0x28, 0x29, 0x11, 0x92, 0x6a, 0x23, 0xcd, 0x2b, 0x96, 0xb7, 0x22, 0x75, 0x0c, 0x08, 0x3f, +0x99, 0xa8, 0xe1, 0x72, 0x09, 0x8d, 0x8f, 0x2b, 0xd3, 0x3d, 0xe8, 0xdc, 0xb4, 0x58, 0x07, 0x9e, +0x79, 0x34, 0xf0, 0xc3, 0xaf, 0x5f, 0xad, 0x2f, 0x52, 0xd3, 0xea, 0x50, 0xef, 0x9a, 0x6b, 0x00, +0xc0, 0xd6, 0x76, 0xe8, 0x75, 0xad, 0x85, 0xb3, 0x72, 0x8e, 0xf0, 0xb1, 0xe3, 0xaa, 0x56, 0xb2, +0xb0, 0xfa, 0xd4, 0x4b, 0x71, 0x37, 0x72, 0xc2, 0x9f, 0xd7, 0xa5, 0x4e, 0xa7, 0x93, 0x4b, 0xa9, +0x9c, 0x8b, 0x0a, 0x7f, 0xfd, 0x75, 0x3e, 0x77, 0x29, 0x19, 0xe5, 0x79, 0x14, 0xdb, 0xd0, 0x5e, +0x65, 0xdb, 0x1b, 0xa7, 0x86, 0x44, 0x95, 0x18, 0xab, 0xc6, 0x72, 0x08, 0xec, 0x6b, 0xe9, 0xbb, +0x2b, 0xa8, 0xbc, 0x73, 0xe0, 0xdb, 0x8d, 0x35, 0x80, 0x37, 0xf0, 0x8f, 0x3e, 0xd1, 0xdb, 0xf8, +0x25, 0x50, 0x37, 0x2f, 0xd1, 0x94, 0x1a, 0xd2, 0x0f, 0x53, 0x93, 0x14, 0xac, 0xb9, 0x8f, 0x0a, +0x70, 0xd1, 0xbb, 0xa3, 0x82, 0xae, 0x8d, 0xb5, 0x94, 0x8e, 0x41, 0x1d, 0xa9, 0xca, 0xfc, 0x55, +0xa3, 0x26, 0x3c, 0x5c, 0x8c, 0xe1, 0x01, 0x63, 0xed, 0x53, 0xa1, 0x62, 0x73, 0x23, 0x64, 0xfa, +0x7a, 0x55, 0xb6, 0x43, 0x45, 0xa5, 0x97, 0x8a, 0x98, 0x4d, 0xf5, 0xcd, 0x17, 0x15, 0x87, 0x89, +0xcf, 0xad, 0x30, 0xcd, 0xb5, 0xb3, 0x9e, 0x1a, 0x95, 0xc4, 0xc5, 0x33, 0x67, 0xbd, 0x46, 0xd2, +0x75, 0xa0, 0x44, 0x06, 0x43, 0xc8, 0x26, 0xa3, 0x67, 0xce, 0x79, 0xeb, 0xeb, 0x4e, 0xe2, 0x22, +0x27, 0x35, 0x1b, 0x67, 0xeb, 0x47, 0x41, 0x7a, 0x10, 0xb0, 0xcd, 0x42, 0xc8, 0x48, 0xe6, 0x93, +0x63, 0x2b, 0x49, 0x1e, 0xe0, 0x41, 0xef, 0x55, 0xd4, 0x1e, 0x55, 0xbe, 0xf2, 0xfa, 0xd0, 0x55, +0xc8, 0x9d, 0x31, 0xff, 0x00, 0xd7, 0xaa, 0x12, 0xb8, 0x04, 0x81, 0x92, 0x7d, 0xbb, 0x54, 0xef, +0xa1, 0x49, 0x94, 0x9e, 0x37, 0x7c, 0x97, 0x6c, 0x0f, 0xee, 0x8a, 0x85, 0x95, 0x57, 0x3b, 0x40, +0xa7, 0xb2, 0xd4, 0xb2, 0x06, 0xf5, 0xe4, 0xe6, 0xab, 0x39, 0x1e, 0xff, 0x00, 0x41, 0x47, 0x4d, +0x0a, 0x5d, 0x88, 0x18, 0xfa, 0x1a, 0x84, 0x9c, 0x9e, 0x4f, 0xe3, 0x4b, 0x72, 0xd7, 0x71, 0x84, +0xf3, 0xda, 0xa1, 0x94, 0x1c, 0x87, 0x5f, 0xbc, 0xbd, 0x69, 0x97, 0xa9, 0x32, 0x48, 0x18, 0x02, +0x3b, 0xd4, 0x99, 0xf7, 0x04, 0xd2, 0x5a, 0xea, 0x53, 0x65, 0x5c, 0xf4, 0xef, 0x4d, 0x3c, 0xf2, +0x47, 0x3e, 0xb5, 0x12, 0xd0, 0xeb, 0x4d, 0x15, 0xe4, 0xca, 0x95, 0x94, 0x64, 0xb4, 0x67, 0x3f, +0x85, 0x6b, 0xc3, 0x20, 0x91, 0x15, 0xc1, 0xce, 0xe1, 0x90, 0x45, 0x43, 0xd8, 0x1b, 0xd4, 0xb4, +0xad, 0xfa, 0xd4, 0xea, 0xdd, 0xcd, 0x49, 0x0c, 0x9d, 0x5b, 0x9e, 0xbc, 0xd5, 0x84, 0x6c, 0x7b, +0xd3, 0xdc, 0x8d, 0x87, 0xe7, 0x63, 0xee, 0xe8, 0xad, 0x5e, 0x97, 0xe0, 0x1f, 0x11, 0x3e, 0x97, +0xa8, 0xc7, 0x09, 0x7d, 0xb0, 0xdc, 0x1e, 0xbf, 0xdd, 0x6e, 0xc6, 0x88, 0xe8, 0xcc, 0xaa, 0xc7, +0x9e, 0x2c, 0xd8, 0xf1, 0xfd, 0x9c, 0x56, 0xba, 0x92, 0xea, 0x96, 0xc9, 0xfb, 0x8d, 0x5f, 0x32, +0x14, 0x41, 0xc2, 0xc9, 0xfc, 0x43, 0xf5, 0xcd, 0x70, 0x43, 0xcc, 0x90, 0xfe, 0xf0, 0xed, 0x5e, +0xbb, 0x41, 0xad, 0xce, 0x28, 0x3b, 0xc4, 0xb4, 0xac, 0x17, 0x85, 0xe2, 0xa6, 0x59, 0x28, 0xb8, +0xd9, 0x27, 0x9b, 0xf5, 0xa9, 0x44, 0xbf, 0x8d, 0x36, 0x4b, 0x1d, 0xe6, 0xe7, 0xbd, 0x0c, 0xfb, +0x81, 0x19, 0xe7, 0xb5, 0x31, 0x0d, 0x59, 0x49, 0xc8, 0x3d, 0x47, 0x5a, 0x53, 0x21, 0xf7, 0xfc, +0x68, 0x42, 0x63, 0x4b, 0x77, 0xcf, 0x4e, 0xd4, 0x99, 0xcf, 0x35, 0x56, 0x21, 0xb1, 0x40, 0xfa, +0xfe, 0x34, 0xbb, 0x73, 0x93, 0x43, 0x0b, 0x87, 0x96, 0xde, 0x94, 0x79, 0x04, 0xf6, 0xe6, 0xa1, +0x8f, 0x71, 0x0d, 0xa3, 0x1e, 0xdd, 0x7b, 0xd5, 0x39, 0xac, 0xdd, 0x5b, 0x7a, 0xa9, 0xc8, 0xeb, +0x52, 0xd9, 0x48, 0xce, 0x96, 0xdd, 0xdb, 0x96, 0xe0, 0x7a, 0x0a, 0xa4, 0xf0, 0x84, 0xc8, 0x03, +0x9f, 0x7a, 0x11, 0x69, 0xdc, 0xa5, 0x22, 0xf5, 0xaa, 0x6e, 0x3a, 0xfa, 0xd1, 0x72, 0xfd, 0x0a, +0x8f, 0xf8, 0xd5, 0x46, 0xf5, 0xf7, 0xef, 0x4e, 0xeb, 0x62, 0x96, 0xa4, 0x2d, 0xd7, 0xde, 0xa2, +0x3d, 0x7a, 0x75, 0xef, 0x41, 0x44, 0x64, 0x9f, 0x73, 0x4c, 0xfa, 0xfa, 0xd0, 0xcd, 0x11, 0x00, +0x26, 0x39, 0x36, 0x9f, 0xb8, 0xdc, 0xe4, 0x55, 0x9c, 0xf4, 0xcf, 0xa7, 0x43, 0x49, 0xb7, 0x72, +0xa2, 0xec, 0x43, 0xf8, 0xd0, 0x7b, 0xe6, 0x93, 0x3a, 0x48, 0xd8, 0x7e, 0x39, 0xa5, 0xb4, 0x93, +0x63, 0xb4, 0x2c, 0x78, 0xea, 0xa6, 0xa5, 0xec, 0x56, 0xdb, 0x9a, 0xc1, 0xbf, 0xc8, 0xa9, 0x43, +0x7b, 0xe6, 0xa2, 0xf7, 0x21, 0xf7, 0x2c, 0x2b, 0x73, 0xd7, 0xf3, 0xa9, 0xd5, 0xb9, 0xeb, 0x4f, +0x72, 0x1e, 0x84, 0xe3, 0xe7, 0x52, 0x09, 0xe9, 0xd0, 0xd4, 0xd6, 0xb3, 0xb2, 0x38, 0x6d, 0xc4, +0x32, 0x1e, 0xa3, 0xb5, 0x2f, 0x21, 0x37, 0x74, 0x7b, 0x25, 0xb5, 0xda, 0x78, 0x8b, 0x40, 0x30, +0x48, 0xc0, 0xdc, 0xc2, 0x99, 0x52, 0x79, 0x2a, 0xc0, 0x7f, 0x5c, 0x57, 0x9e, 0xb6, 0xe4, 0x76, +0x46, 0xc8, 0x64, 0x38, 0x20, 0xd6, 0xd7, 0xbe, 0xa7, 0x02, 0x56, 0x6e, 0x22, 0x87, 0xa9, 0x03, +0xd3, 0x19, 0x2e, 0xfe, 0xf9, 0xa7, 0x09, 0x0f, 0xd7, 0x3d, 0xf3, 0x4c, 0x87, 0xdc, 0x7f, 0x99, +0xef, 0x4b, 0xbf, 0xdf, 0xf3, 0xa0, 0x4c, 0x61, 0x72, 0xad, 0xb8, 0x74, 0x3c, 0x1a, 0x9c, 0x36, +0x7d, 0x7e, 0xb5, 0x6b, 0x52, 0x24, 0x28, 0xc9, 0xff, 0x00, 0x13, 0x4f, 0x1f, 0xcf, 0xd6, 0xa8, +0x8b, 0x93, 0x2a, 0x13, 0xef, 0x56, 0x12, 0x22, 0x7d, 0xe9, 0x34, 0xc5, 0x74, 0x5c, 0x8e, 0xd5, +0x9f, 0xa0, 0x27, 0xdf, 0x15, 0xa9, 0x0e, 0x93, 0x24, 0xa4, 0x00, 0x8c, 0x49, 0xed, 0x8c, 0xd6, +0x53, 0x76, 0x29, 0x3b, 0x9e, 0x8d, 0xe1, 0xff, 0x00, 0x87, 0x37, 0x3a, 0xa2, 0xf9, 0xd7, 0x04, +0xd9, 0xdb, 0xf0, 0x7c, 0xc9, 0x23, 0x39, 0x7f, 0xa0, 0xef, 0x5e, 0x89, 0x6d, 0xf0, 0xcb, 0xc3, +0x70, 0xda, 0xcb, 0x14, 0xf1, 0x3d, 0xd5, 0xcc, 0x8a, 0x54, 0x5d, 0xb1, 0x2b, 0xe5, 0x9f, 0x50, +0xa0, 0xe3, 0xf3, 0xcd, 0x64, 0xa2, 0xe5, 0xab, 0x37, 0x8a, 0xd0, 0xf9, 0xb3, 0xc4, 0x9e, 0x1c, +0x9f, 0x46, 0xbf, 0xb8, 0xb3, 0x99, 0x30, 0xd1, 0x39, 0x19, 0x03, 0x83, 0xee, 0x3d, 0x8d, 0x70, +0xb7, 0x36, 0xe4, 0x13, 0x90, 0x68, 0x8b, 0x7b, 0x30, 0x32, 0x65, 0x8f, 0x04, 0xe6, 0xb3, 0xe5, +0x5c, 0x7f, 0x8d, 0x69, 0x72, 0xad, 0x72, 0x8c, 0x8a, 0x79, 0xaa, 0x92, 0x0a, 0x37, 0x29, 0x6f, +0xa9, 0x5d, 0xbb, 0xfa, 0xd4, 0x27, 0x39, 0xf5, 0xcf, 0xad, 0x17, 0x6d, 0x6a, 0x5a, 0x22, 0x3e, +0xfd, 0xfd, 0xa9, 0x84, 0x9a, 0x35, 0x34, 0xbd, 0xc8, 0xdc, 0x6e, 0x07, 0xb9, 0xec, 0x7d, 0x28, +0x8d, 0xcb, 0x03, 0x9e, 0xa3, 0x82, 0x0d, 0x22, 0x98, 0x9f, 0x9d, 0x19, 0xce, 0x72, 0x73, 0x9a, +0x1e, 0xbb, 0x1d, 0x23, 0x7d, 0x73, 0xd7, 0xb1, 0xaa, 0xf2, 0x02, 0x08, 0x91, 0x73, 0x95, 0x39, +0xcf, 0xad, 0x27, 0xa2, 0x1b, 0xd4, 0xd4, 0x8a, 0x42, 0xfb, 0x1d, 0x79, 0x56, 0x19, 0xfa, 0x55, +0xb0, 0x7d, 0xce, 0x6b, 0x2b, 0x6a, 0x4b, 0x6c, 0x99, 0x5b, 0xde, 0xa6, 0x56, 0xe7, 0xaf, 0x3e, +0xb5, 0x48, 0xcd, 0xec, 0x4e, 0xaf, 0x8e, 0xf4, 0xe7, 0x6d, 0xae, 0x1c, 0x1e, 0x0f, 0x5a, 0x4d, +0xea, 0x2d, 0xce, 0xbb, 0xc3, 0x5a, 0xab, 0x59, 0xdd, 0xaa, 0x16, 0x22, 0x29, 0xc8, 0x56, 0x1e, +0x95, 0xb9, 0xe2, 0x1b, 0x41, 0x1d, 0xc0, 0xbc, 0x8b, 0xfd, 0x55, 0xc7, 0x5c, 0x0e, 0x86, 0xb4, +0x8b, 0xe8, 0x71, 0xd5, 0x56, 0x9a, 0x67, 0x38, 0x09, 0xa7, 0x86, 0xf5, 0xaa, 0x25, 0x8f, 0xdf, +0x4f, 0xdf, 0xef, 0x4d, 0x31, 0x3d, 0x45, 0xdd, 0xef, 0x4e, 0x0c, 0x4d, 0x51, 0x9b, 0xd8, 0x97, +0x39, 0x04, 0x1e, 0xe2, 0x96, 0x22, 0x7e, 0xe9, 0x39, 0x23, 0xbd, 0x52, 0x21, 0xb2, 0xda, 0x8c, +0xd5, 0xa5, 0x8f, 0x77, 0xf3, 0xad, 0x12, 0x31, 0x6c, 0xbf, 0x0d, 0xb9, 0x7e, 0xdf, 0x9d, 0x6d, +0x5b, 0xe9, 0xcc, 0xd8, 0xc2, 0x92, 0x4d, 0x5b, 0x85, 0xcc, 0xe5, 0x3b, 0x1e, 0x8d, 0xe1, 0xaf, +0x04, 0xdd, 0xea, 0x4c, 0xb2, 0x48, 0x9e, 0x4d, 0xa8, 0xfb, 0xd3, 0x3e, 0x79, 0xfa, 0x7a, 0x9a, +0xf6, 0x3d, 0x3f, 0xc2, 0xda, 0x36, 0x9c, 0x06, 0xcb, 0x55, 0x9d, 0xfb, 0xbd, 0xc8, 0x0f, 0xfa, +0x74, 0xae, 0x49, 0xab, 0xbb, 0x33, 0xae, 0x8a, 0xba, 0xe6, 0x3a, 0x10, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x0e, 0xd4, 0xb4, 0xce, 0x83, 0xce, 0x3e, 0x21, 0xf8, 0x69, 0x35, 0x6d, 0x3c, 0xea, +0x10, 0xc6, 0x0d, 0xdd, 0x9a, 0x9d, 0xe4, 0x0e, 0x5d, 0x3f, 0xfa, 0xdf, 0xc8, 0x9f, 0x4a, 0xf9, +0x67, 0x50, 0xb2, 0x64, 0x66, 0x04, 0x10, 0x41, 0xe7, 0x35, 0x8b, 0xd2, 0x44, 0xb3, 0x97, 0xb8, +0x87, 0x04, 0xd6, 0x3c, 0xd1, 0xe3, 0x3e, 0xb5, 0x41, 0x73, 0x36, 0x45, 0xf5, 0xfc, 0xea, 0x93, +0x8e, 0xbf, 0xce, 0x9d, 0xee, 0x59, 0x51, 0xc7, 0x7c, 0xe6, 0xa1, 0x3e, 0xe6, 0x9d, 0xf4, 0x2d, +0x10, 0xb7, 0x6e, 0x45, 0x30, 0xf7, 0xe9, 0xf8, 0xd3, 0xf5, 0x2e, 0xfa, 0xe8, 0x34, 0x9f, 0xa8, +0xaa, 0xd2, 0x1d, 0x8e, 0x1c, 0x13, 0x83, 0xc1, 0xf6, 0xa9, 0xba, 0xea, 0x5e, 0xe4, 0xf2, 0x29, +0x46, 0x6f, 0xad, 0x33, 0x3d, 0x7d, 0xea, 0xad, 0xa1, 0xba, 0x7a, 0xd8, 0x3d, 0xf3, 0x93, 0x4c, +0x63, 0xd7, 0x8a, 0x9b, 0x5f, 0x52, 0x97, 0x98, 0xdb, 0x47, 0xf2, 0xe4, 0x68, 0xdb, 0xa3, 0x1c, +0xae, 0x6b, 0x59, 0x4e, 0x6b, 0x29, 0x6f, 0xa8, 0x32, 0x6d, 0xc7, 0xf5, 0xa9, 0x03, 0x1e, 0x29, +0x99, 0xbf, 0x32, 0x75, 0x7f, 0x7c, 0xd4, 0xe3, 0xe7, 0x5d, 0x86, 0x9f, 0x99, 0x1d, 0x6c, 0x3a, +0xde, 0x52, 0x8d, 0x83, 0x90, 0x50, 0xf0, 0x6b, 0xd3, 0xb4, 0xeb, 0x94, 0xd5, 0xf4, 0xb6, 0xb7, +0x94, 0xe6, 0x58, 0xc7, 0x53, 0xd7, 0xd8, 0xd1, 0x17, 0xa9, 0x8e, 0x21, 0x69, 0x74, 0x72, 0xee, +0x1a, 0x39, 0x19, 0x1c, 0x61, 0x94, 0xe0, 0xe6, 0x9b, 0xba, 0xb4, 0xdc, 0xc5, 0xeb, 0xa8, 0xed, +0xdd, 0x79, 0xa5, 0xdd, 0xdf, 0x39, 0xc8, 0xa6, 0xc4, 0xc7, 0x86, 0xa7, 0x83, 0x9e, 0x46, 0x0d, +0x51, 0x12, 0x26, 0x53, 0xcf, 0x5a, 0x9b, 0x1d, 0x18, 0x1e, 0x9d, 0x6a, 0xd6, 0xa6, 0x52, 0xd0, +0xd2, 0x85, 0x77, 0x73, 0xeb, 0x5b, 0xf6, 0x76, 0x12, 0xca, 0x46, 0x15, 0x9b, 0x3e, 0x82, 0xba, +0x21, 0x1b, 0x9c, 0x95, 0x27, 0xca, 0x8f, 0x40, 0xd0, 0x7c, 0x1b, 0xa8, 0xea, 0x52, 0x2f, 0x97, +0x03, 0xa4, 0x59, 0xe6, 0x79, 0x14, 0x85, 0x1f, 0x8d, 0x7b, 0x76, 0x91, 0xe1, 0x2d, 0x2f, 0x4c, +0x8a, 0x3d, 0xf0, 0xa5, 0xcd, 0xca, 0x80, 0x5a, 0x59, 0x07, 0x19, 0xf6, 0x14, 0xea, 0xd4, 0x54, +0xd7, 0x2a, 0xdc, 0x9c, 0x3d, 0x07, 0x88, 0x97, 0x3c, 0xbe, 0x1f, 0xcc, 0xea, 0x40, 0x00, 0x60, +0x00, 0x00, 0xe8, 0x07, 0x6a, 0x5a, 0xe2, 0x3d, 0x6d, 0x82, 0x8a, 0x00, 0x42, 0x03, 0x02, 0xac, +0x03, 0x06, 0x18, 0x20, 0xf3, 0x9a, 0xf9, 0xb3, 0xe2, 0x07, 0x86, 0x8e, 0x9b, 0xa8, 0x4b, 0x2c, +0x51, 0x9f, 0xb2, 0x5c, 0x1d, 0xd1, 0x36, 0x38, 0x03, 0x1d, 0x3f, 0x03, 0x59, 0x55, 0xd9, 0x30, +0x67, 0x8c, 0x5e, 0xdb, 0x90, 0x4f, 0x15, 0xce, 0x5c, 0x47, 0x8c, 0xff, 0x00, 0x3a, 0x49, 0x89, +0x23, 0x1e, 0x64, 0xe4, 0xd6, 0x7c, 0xaa, 0x73, 0x9c, 0x9a, 0xa5, 0x72, 0xf6, 0x29, 0x38, 0xef, +0xdf, 0xde, 0xab, 0x30, 0xe7, 0x8e, 0x69, 0x96, 0x44, 0xd9, 0xe7, 0x83, 0x9a, 0x67, 0x7e, 0x94, +0xfa, 0x97, 0x74, 0x31, 0xba, 0xf5, 0xeb, 0x51, 0x38, 0xdc, 0x08, 0x3d, 0xc7, 0x6e, 0xd4, 0xf7, +0x29, 0x2d, 0x2c, 0x69, 0x6a, 0x11, 0x6d, 0x6c, 0x8e, 0x06, 0x6b, 0x28, 0x30, 0xfe, 0x95, 0x6d, +0x36, 0xcd, 0x21, 0x25, 0x60, 0x07, 0x39, 0x39, 0x1f, 0x85, 0x27, 0xe1, 0x93, 0x59, 0xb3, 0x44, +0xd3, 0x20, 0x90, 0x11, 0x87, 0x5c, 0xee, 0x43, 0x90, 0x6b, 0x4a, 0x19, 0x44, 0x88, 0xae, 0x3b, +0xd6, 0x72, 0x57, 0x2b, 0x72, 0xd0, 0x63, 0xeb, 0xd6, 0xa4, 0x04, 0xf0, 0x79, 0x3f, 0x5a, 0x49, +0xdc, 0xce, 0x44, 0xa1, 0x8d, 0x4e, 0xae, 0x41, 0x1c, 0xf3, 0x55, 0x7b, 0xb2, 0x07, 0xc9, 0xf2, +0x91, 0x20, 0x3d, 0x7a, 0xd7, 0x43, 0xa1, 0x6a, 0x2d, 0x69, 0x72, 0xac, 0x09, 0xd9, 0x27, 0xca, +0xc2, 0xa7, 0x66, 0x4c, 0xd7, 0x34, 0x6c, 0x74, 0xba, 0xe5, 0xb0, 0xca, 0x5e, 0x46, 0x06, 0xc9, +0x3e, 0xf6, 0x3f, 0x9d, 0x73, 0xc1, 0xab, 0x54, 0x71, 0xc7, 0x55, 0xa8, 0xb9, 0xcf, 0x39, 0xa7, +0x86, 0xeb, 0x4c, 0x18, 0xa0, 0xf2, 0x73, 0xf8, 0x54, 0xaa, 0xde, 0xe6, 0xaa, 0xe4, 0xb4, 0x89, +0x95, 0xb2, 0x7a, 0xd5, 0xc8, 0xd8, 0x77, 0x3c, 0x7d, 0x6b, 0x44, 0x63, 0x3b, 0x9d, 0x06, 0x8b, +0x6a, 0xd7, 0x97, 0x71, 0x5b, 0x29, 0x51, 0xe6, 0x30, 0x50, 0x5c, 0xe3, 0xf5, 0xaf, 0xab, 0x3c, +0x3b, 0xe0, 0x6b, 0x0d, 0x22, 0x35, 0x92, 0xf0, 0x47, 0x7b, 0x75, 0x8e, 0x41, 0x1f, 0xbb, 0x53, +0xec, 0x0f, 0x5f, 0xc6, 0xb7, 0x95, 0x4f, 0x67, 0x1d, 0x37, 0x39, 0x63, 0x47, 0xeb, 0x13, 0xb4, +0xb6, 0x47, 0x74, 0xaa, 0xa8, 0x02, 0xa2, 0x85, 0x51, 0xc0, 0x55, 0x18, 0x02, 0x96, 0xb9, 0x1b, +0xbe, 0xac, 0xf4, 0x92, 0x49, 0x59, 0x05, 0x14, 0x86, 0x14, 0x50, 0x01, 0x58, 0x3e, 0x23, 0xd1, +0x93, 0x5b, 0xd3, 0x65, 0xb5, 0x21, 0x7c, 0xe5, 0xf9, 0xe1, 0x66, 0xec, 0xde, 0x99, 0xf7, 0xff, +0x00, 0x0a, 0x99, 0xae, 0x68, 0xb4, 0x0c, 0xf9, 0x27, 0x5a, 0xd3, 0xde, 0xda, 0x69, 0x62, 0x91, +0x4a, 0xb2, 0x1c, 0x60, 0xf5, 0xae, 0x1e, 0xee, 0x1e, 0x4e, 0x6b, 0x08, 0x36, 0xd0, 0x6e, 0x60, +0x4f, 0x1f, 0x26, 0xb2, 0xe5, 0x53, 0xcf, 0x7f, 0x7a, 0xd4, 0xb4, 0x51, 0x91, 0x7e, 0xb9, 0x3d, +0xea, 0xab, 0xd3, 0x5a, 0x6e, 0x56, 0xe4, 0x0c, 0x3f, 0xfd, 0x66, 0x99, 0x8e, 0xbc, 0xe7, 0x8a, +0x6d, 0xdd, 0xdd, 0x16, 0x91, 0x0b, 0x75, 0xaa, 0xf2, 0x4a, 0x17, 0x23, 0x24, 0x93, 0xc6, 0x3b, +0xd1, 0xb1, 0x49, 0xdd, 0xdd, 0x9d, 0x46, 0xa9, 0x6f, 0xbd, 0x1b, 0x00, 0xe4, 0x74, 0x39, 0xae, +0x0e, 0x42, 0xf1, 0xb9, 0x52, 0x48, 0xc1, 0xae, 0xaa, 0x69, 0x5d, 0xdc, 0xc2, 0x52, 0x6b, 0x54, +0x3a, 0x19, 0xc8, 0x7c, 0x33, 0x75, 0xe9, 0x9a, 0xbe, 0x1b, 0x23, 0xfc, 0x6a, 0x6b, 0xc7, 0x95, +0xdc, 0xe8, 0xa1, 0x27, 0x25, 0x66, 0x21, 0xe7, 0x83, 0xe9, 0x4d, 0xb7, 0x7f, 0x2e, 0x46, 0x8c, +0xfd, 0xd6, 0xe4, 0x1a, 0xe4, 0x6a, 0xe7, 0x4e, 0x9b, 0xb3, 0x4c, 0x37, 0x35, 0x28, 0x6f, 0x7c, +0xd4, 0x26, 0x4c, 0x91, 0x28, 0x7f, 0x7a, 0x90, 0x37, 0x3d, 0x72, 0x71, 0xde, 0xae, 0xe6, 0x7d, +0x4b, 0x4a, 0xdb, 0x95, 0x94, 0xf7, 0x14, 0x40, 0xe5, 0x58, 0xa9, 0x27, 0xe5, 0xe9, 0x4a, 0xe9, +0x3d, 0x45, 0x6d, 0x0f, 0x4b, 0xd1, 0xee, 0x97, 0x52, 0xb0, 0x92, 0xd2, 0x52, 0x0b, 0xa2, 0xe3, +0x9e, 0xbf, 0x5a, 0xe7, 0x2e, 0x22, 0x7b, 0x79, 0xa4, 0x85, 0xc6, 0x19, 0x0e, 0x39, 0xef, 0x54, +0x9e, 0x87, 0x13, 0x5c, 0xb2, 0x68, 0x60, 0x3e, 0xa6, 0x94, 0x1f, 0xf2, 0x6a, 0xae, 0x03, 0x83, +0x71, 0xeb, 0xf5, 0xa7, 0xee, 0x03, 0x9c, 0xf1, 0xeb, 0x54, 0x45, 0x81, 0x65, 0xc9, 0xc2, 0x0c, +0x9f, 0x53, 0xda, 0xaf, 0xc2, 0xa4, 0x9c, 0xb9, 0xc9, 0xf4, 0xad, 0xa2, 0xf5, 0x32, 0x9e, 0xc7, +0x51, 0xa7, 0x4b, 0xb1, 0xd1, 0xd7, 0x82, 0xa7, 0x22, 0xbe, 0xb7, 0xf0, 0x56, 0xbc, 0x9a, 0xde, +0x91, 0x08, 0x79, 0x37, 0x5e, 0x5a, 0x28, 0x8e, 0x50, 0x7a, 0xb0, 0xfe, 0x16, 0xfc, 0x87, 0x3e, +0xe3, 0xde, 0xb5, 0xa9, 0x1b, 0xd3, 0xb9, 0xcd, 0x4a, 0x4e, 0x35, 0xad, 0xdc, 0xec, 0x68, 0xae, +0x43, 0xd1, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x28, 0x03, 0xc5, 0xfe, 0x26, 0x78, 0x6f, 0x70, +0x3a, 0xc5, 0xba, 0x7c, 0x92, 0x7c, 0xb3, 0x01, 0xfc, 0x2d, 0xeb, 0xf8, 0xff, 0x00, 0x3f, 0xad, +0x7c, 0xe1, 0x7f, 0x06, 0xd2, 0xdc, 0x57, 0x3f, 0xc3, 0x26, 0x86, 0x8e, 0x5a, 0xe1, 0x39, 0x35, +0x8d, 0x32, 0xf2, 0x6a, 0xd3, 0x2b, 0xcc, 0xa1, 0x20, 0xff, 0x00, 0xf5, 0xd5, 0x27, 0xeb, 0xeb, +0x57, 0x72, 0x88, 0x1b, 0xbe, 0x3b, 0xd5, 0x79, 0x1d, 0x54, 0x1c, 0x9e, 0x7d, 0x28, 0xd5, 0x95, +0xa2, 0x2b, 0x11, 0x24, 0x87, 0x3c, 0x2a, 0xfb, 0xf5, 0xa0, 0x20, 0x5c, 0xf1, 0x92, 0x7b, 0x9a, +0x2c, 0x69, 0xd3, 0x53, 0xd0, 0x2f, 0xad, 0xfe, 0xf1, 0xfe, 0x95, 0xe7, 0x5a, 0xb5, 0xb9, 0x8e, +0x52, 0xe0, 0x60, 0x1e, 0xb5, 0xd5, 0x49, 0xfb, 0xda, 0x9c, 0xf2, 0xf8, 0x4e, 0x36, 0xf2, 0xee, +0x48, 0xe4, 0xda, 0x84, 0x82, 0x3b, 0xd5, 0xfd, 0x3f, 0x53, 0x77, 0x61, 0x1c, 0xdd, 0x4f, 0x47, +0x27, 0xad, 0x74, 0x55, 0x83, 0x94, 0x48, 0xa5, 0x3e, 0x49, 0x6a, 0x74, 0x04, 0xe4, 0x64, 0x54, +0x32, 0x03, 0xc1, 0x07, 0x95, 0x39, 0x15, 0xe6, 0x33, 0xd4, 0x45, 0xf8, 0x66, 0x0e, 0xbb, 0x81, +0x3f, 0x9d, 0x58, 0x0d, 0xf5, 0xac, 0x85, 0x25, 0x72, 0x55, 0x72, 0x7a, 0xd4, 0xc0, 0xff, 0x00, +0xfa, 0xe9, 0xae, 0xe6, 0x6f, 0xcc, 0x95, 0x1c, 0x83, 0x9e, 0xb8, 0xa9, 0x24, 0x3f, 0x76, 0x45, +0xcf, 0xbe, 0x29, 0xbd, 0x50, 0x5f, 0x53, 0x77, 0x45, 0xd4, 0x4d, 0xad, 0xd4, 0x52, 0x64, 0xec, +0x27, 0x0c, 0x33, 0xd4, 0x57, 0x6b, 0xae, 0x5a, 0x09, 0xa1, 0x8f, 0x51, 0x84, 0x6e, 0xc8, 0x1b, +0xb0, 0x3b, 0x7a, 0xd3, 0x4c, 0xe4, 0xae, 0xb9, 0x64, 0x99, 0xc9, 0xee, 0xf5, 0xa5, 0xdd, 0xd7, +0x27, 0xf1, 0x35, 0x77, 0x22, 0xe4, 0x66, 0x7e, 0x70, 0x83, 0x73, 0x7a, 0xf6, 0x14, 0xf5, 0x04, +0x9c, 0xbb, 0x13, 0xed, 0x56, 0x99, 0x0f, 0xb1, 0x71, 0x48, 0x00, 0x63, 0xb5, 0x5c, 0x89, 0xfa, +0x56, 0x89, 0xdc, 0xca, 0x68, 0xd8, 0xb5, 0x97, 0x0c, 0x39, 0x35, 0xea, 0xde, 0x07, 0xf1, 0x0b, +0xe8, 0xfa, 0x94, 0x52, 0xb3, 0x6e, 0x86, 0x41, 0xb2, 0x44, 0xcf, 0x55, 0x24, 0x7f, 0xfa, 0xeb, +0xaa, 0x1e, 0xf2, 0xb3, 0x38, 0x2b, 0x37, 0x06, 0xa4, 0x8f, 0xa8, 0x91, 0xd6, 0x45, 0x59, 0x11, +0x83, 0xa3, 0x8d, 0xca, 0xea, 0x72, 0x18, 0x1e, 0xf4, 0xea, 0xe1, 0x6a, 0xce, 0xcc, 0xf5, 0x53, +0xba, 0xba, 0x0a, 0x29, 0x0c, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0xab, 0x7d, 0x67, 0x0e, 0xa1, 0x69, +0x71, 0x67, 0x70, 0x37, 0x45, 0x70, 0x85, 0x1b, 0x23, 0x38, 0xf4, 0x3f, 0x81, 0xe6, 0xbe, 0x3e, +0xf1, 0x76, 0x8d, 0x2e, 0x91, 0xa9, 0x5d, 0xda, 0x4a, 0xa7, 0x28, 0xec, 0x15, 0x88, 0xc0, 0x61, +0x9e, 0x08, 0xf6, 0x23, 0x9a, 0xc6, 0xa2, 0xd5, 0x31, 0xad, 0xcf, 0x37, 0xbb, 0x4c, 0x13, 0xeb, +0x58, 0x33, 0xaf, 0x53, 0x8e, 0xd4, 0xd1, 0x56, 0xd6, 0xc6, 0x64, 0xa3, 0x26, 0xa8, 0x4a, 0xc1, +0x32, 0x58, 0xf3, 0xe9, 0x56, 0xb5, 0x2a, 0xfa, 0x14, 0xc9, 0x77, 0x3c, 0x0d, 0x83, 0xd4, 0xf7, +0xa6, 0x08, 0xd5, 0x72, 0x7e, 0xf3, 0x7a, 0xb7, 0x5a, 0x2f, 0x6d, 0x8b, 0xdf, 0x46, 0x23, 0x60, +0x54, 0x2d, 0xdc, 0xff, 0x00, 0x2a, 0x6f, 0x4d, 0x46, 0x8f, 0x51, 0xbc, 0x8f, 0x20, 0xd7, 0x0d, +0xab, 0x5a, 0xef, 0x46, 0x20, 0x64, 0x8a, 0xdd, 0x3b, 0x3b, 0x98, 0xea, 0xd5, 0x8f, 0x2b, 0xd4, +0x21, 0x29, 0x72, 0xbb, 0x87, 0x0c, 0x70, 0x6a, 0x23, 0x88, 0xcb, 0x29, 0xe0, 0xaf, 0xcc, 0xad, +0xe9, 0x5d, 0xad, 0xb9, 0x2b, 0x18, 0xab, 0x2d, 0xce, 0xa2, 0xca, 0xe3, 0xcf, 0x81, 0x5c, 0x9c, +0xf1, 0x83, 0x56, 0x8f, 0x71, 0x5e, 0x64, 0xd7, 0x2c, 0x9a, 0x3d, 0x3a, 0x6d, 0xca, 0x37, 0x23, +0x81, 0xcc, 0x72, 0x94, 0x3f, 0x75, 0xf9, 0x1e, 0xd5, 0xa4, 0x1b, 0xdf, 0xa5, 0x64, 0xde, 0xa6, +0x9d, 0x09, 0x37, 0x7b, 0xf5, 0xa9, 0xd5, 0xfd, 0x6a, 0x76, 0x33, 0x6b, 0x52, 0x40, 0xde, 0xf9, +0xf5, 0xab, 0x08, 0xe0, 0xe5, 0x49, 0xe0, 0xd0, 0xf5, 0x25, 0x04, 0x52, 0x14, 0x7d, 0xa4, 0xf4, +0x3c, 0x66, 0xbd, 0x6b, 0xc2, 0x97, 0xd1, 0xea, 0x16, 0xad, 0xa7, 0xdc, 0x61, 0xcc, 0x6b, 0xc0, +0x3d, 0xc5, 0x3b, 0xf5, 0x32, 0xc4, 0x46, 0xf1, 0x39, 0x5d, 0x5a, 0xdd, 0xf4, 0xdb, 0xd9, 0x6d, +0x8a, 0x92, 0x7e, 0xf2, 0x7b, 0x8a, 0xcd, 0x01, 0xe4, 0xe6, 0x53, 0xc7, 0xf7, 0x45, 0x68, 0x8e, +0x7b, 0xdd, 0x5c, 0x9d, 0x70, 0xbd, 0x2a, 0x40, 0x7e, 0xb5, 0x4a, 0xe4, 0xbf, 0x32, 0x75, 0x6a, +0xb1, 0x1b, 0xf3, 0x8c, 0xd6, 0xb1, 0x66, 0x32, 0x34, 0x61, 0x93, 0x06, 0xba, 0x4b, 0x0b, 0x9d, +0xac, 0x39, 0xe4, 0x57, 0x45, 0x36, 0x72, 0x56, 0x8d, 0xd5, 0x8f, 0xa7, 0xbe, 0x1e, 0x78, 0x81, +0x75, 0x1d, 0x3f, 0xfb, 0x3a, 0x79, 0x09, 0xb9, 0xb5, 0xc9, 0x8f, 0x77, 0xf1, 0x27, 0x1c, 0x7e, +0x07, 0xf9, 0xfb, 0x57, 0xa4, 0x57, 0x3d, 0x65, 0x69, 0xb3, 0xab, 0x0b, 0x3e, 0x7a, 0x6b, 0xcb, +0x40, 0xa2, 0xb2, 0x3a, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0xbc, 0x7f, 0xe2, 0xc7, 0x87, 0x6e, +0x75, 0x1b, 0x18, 0x75, 0x6b, 0x28, 0x04, 0x8d, 0x63, 0x1b, 0x0b, 0xad, 0xbf, 0x78, 0x27, 0x50, +0xd8, 0xee, 0x07, 0xcd, 0x9f, 0x63, 0x51, 0x51, 0x36, 0xb4, 0x1a, 0xdc, 0xf9, 0x4e, 0xec, 0x1c, +0xb0, 0x3d, 0x41, 0xe6, 0xb0, 0x2e, 0x48, 0x19, 0xce, 0x6a, 0x22, 0x68, 0x63, 0x4a, 0x1d, 0xb3, +0xb7, 0xe5, 0x07, 0xb9, 0xaa, 0x4d, 0x12, 0x83, 0x96, 0xf9, 0x8f, 0xa9, 0xab, 0x4c, 0xab, 0x5c, +0x89, 0xb8, 0xe4, 0xf7, 0xa8, 0x09, 0xef, 0xcf, 0xd6, 0xa9, 0x76, 0x2b, 0x5b, 0x10, 0x37, 0x53, +0x83, 0xce, 0x2a, 0x17, 0x38, 0xfa, 0x9a, 0x57, 0x1e, 0xb6, 0x3d, 0x82, 0xe1, 0x03, 0xae, 0x49, +0xae, 0x57, 0x50, 0x87, 0x86, 0xe3, 0xaf, 0x4a, 0xdb, 0x53, 0x04, 0xcf, 0x2e, 0xd7, 0x6c, 0xce, +0xe7, 0x20, 0x72, 0x0e, 0x41, 0xae, 0x59, 0xb3, 0x32, 0x6d, 0xc1, 0x32, 0xa7, 0x04, 0x57, 0x74, +0x1d, 0xe2, 0x63, 0x3d, 0xce, 0x8b, 0x4e, 0x53, 0x14, 0x00, 0x37, 0x52, 0x73, 0xf4, 0xab, 0xfe, +0x62, 0xb6, 0x40, 0x20, 0x91, 0xd4, 0x57, 0x0d, 0x65, 0x79, 0x33, 0xd0, 0xa2, 0xed, 0x15, 0x72, +0x29, 0x46, 0x46, 0x47, 0x51, 0xc8, 0x35, 0x76, 0x19, 0x77, 0xa2, 0x9c, 0xe4, 0xf4, 0x39, 0xed, +0x5c, 0xb2, 0x77, 0x37, 0xe9, 0x62, 0xd0, 0x6f, 0xae, 0x6a, 0x40, 0xdc, 0x75, 0xa5, 0xea, 0x4b, +0xd4, 0x98, 0x37, 0xe7, 0x9a, 0x91, 0x5b, 0xde, 0x9d, 0xcc, 0xd9, 0x23, 0x9e, 0x03, 0x83, 0x92, +0x3a, 0x9a, 0xdb, 0xd1, 0x75, 0x27, 0xb2, 0xbb, 0x86, 0xe1, 0x4e, 0x00, 0x6f, 0x9b, 0xdc, 0x54, +0xfa, 0x84, 0x95, 0xe2, 0x7a, 0xf6, 0xbf, 0xa7, 0x26, 0xb3, 0xa4, 0x2e, 0xa5, 0x6d, 0xf3, 0xdc, +0x5b, 0xa8, 0x6f, 0x97, 0xab, 0x2f, 0x71, 0x5e, 0x57, 0x9c, 0x7d, 0x6b, 0x54, 0xf4, 0x38, 0x23, +0xd8, 0x76, 0xee, 0x6a, 0x40, 0xc3, 0xf2, 0xa6, 0x8a, 0x7a, 0x92, 0x06, 0xa9, 0x95, 0xbd, 0xeb, +0x48, 0x99, 0x48, 0xb9, 0x1c, 0xbd, 0x3e, 0xb5, 0xaf, 0x6d, 0x36, 0x0e, 0x73, 0x5d, 0x11, 0x7a, +0x9c, 0xf3, 0x47, 0xa1, 0xf8, 0x5b, 0x5d, 0x97, 0x4b, 0xd4, 0x2d, 0xae, 0xe3, 0x61, 0x98, 0x9f, +0x24, 0x1e, 0x84, 0x77, 0x1f, 0x88, 0xaf, 0xad, 0x2c, 0xaf, 0x21, 0xbf, 0xb4, 0xb7, 0xbc, 0xb7, +0x6d, 0xd1, 0x5c, 0xa0, 0x75, 0x3e, 0x9e, 0xdf, 0x51, 0x46, 0x21, 0x5d, 0x29, 0x19, 0xe1, 0x1f, +0x2c, 0xe5, 0x1e, 0xe5, 0xaa, 0x2b, 0x94, 0xf4, 0x02, 0x8a, 0x00, 0x29, 0xad, 0xbb, 0x1f, 0x2e, +0x09, 0xcf, 0x3b, 0xbb, 0x8a, 0x1f, 0x90, 0x11, 0x5c, 0xdd, 0x5b, 0x59, 0xc2, 0xf7, 0x17, 0x73, +0xc5, 0x6f, 0x04, 0x7c, 0xb4, 0xb3, 0x30, 0x55, 0x1f, 0x89, 0xaf, 0x24, 0xf1, 0x3f, 0xc5, 0x6d, +0x2a, 0xda, 0x0b, 0x8b, 0x4d, 0x26, 0x0f, 0xed, 0x19, 0x24, 0x46, 0x8c, 0xcf, 0x70, 0x0a, 0xc4, +0x32, 0x31, 0xf7, 0x7a, 0xb7, 0xe9, 0x51, 0x39, 0xa8, 0x8d, 0x2b, 0x9f, 0x29, 0xea, 0x52, 0xb4, +0x92, 0xbb, 0x8f, 0x94, 0x39, 0xea, 0x3b, 0x56, 0x14, 0x88, 0xa3, 0x27, 0xa9, 0x3d, 0xcd, 0x66, +0xb6, 0x36, 0xb1, 0x9f, 0x2f, 0x7a, 0xcf, 0x90, 0x0e, 0x4f, 0xad, 0x5a, 0x57, 0x0b, 0x95, 0x1b, +0xf5, 0xa8, 0x18, 0xe3, 0x39, 0x38, 0x35, 0x57, 0xb1, 0x65, 0x76, 0xcf, 0x3c, 0xe0, 0x1e, 0xf4, +0xd4, 0x8d, 0x9d, 0xc2, 0x80, 0x49, 0x26, 0x9b, 0xd8, 0x1d, 0x96, 0xa7, 0xb1, 0x9f, 0x98, 0x11, +0xfc, 0xeb, 0x0e, 0xfa, 0x22, 0x43, 0x0c, 0x75, 0xf6, 0xad, 0x13, 0x30, 0xf3, 0x38, 0x2d, 0x5e, +0xd4, 0xb2, 0xb9, 0xc0, 0xe3, 0x9a, 0xe1, 0x5e, 0x24, 0x8d, 0xd9, 0xb0, 0x01, 0x3d, 0x6b, 0xaa, +0x94, 0xae, 0x8c, 0xe6, 0xb5, 0x2a, 0x4d, 0xa8, 0x79, 0x2a, 0x51, 0x0e, 0x58, 0xf7, 0x07, 0xa5, +0x37, 0x4d, 0x9a, 0x76, 0x9c, 0xb3, 0x6e, 0x65, 0x71, 0xc9, 0xf4, 0xa2, 0x71, 0x5c, 0xad, 0xb2, +0xe3, 0x39, 0x36, 0x92, 0x3a, 0x42, 0x49, 0xef, 0x8a, 0x8e, 0x27, 0xf2, 0xe5, 0x2a, 0x7e, 0xeb, +0xf4, 0xaf, 0x39, 0xbe, 0xe7, 0xa2, 0xae, 0x69, 0x06, 0xe3, 0xad, 0x48, 0x1b, 0x3d, 0xeb, 0x3b, +0xdc, 0x4c, 0x95, 0x5b, 0x3d, 0x7b, 0x54, 0xaa, 0xd8, 0xe7, 0xd6, 0x9d, 0xc8, 0x64, 0xe8, 0xc3, +0x18, 0x3d, 0x08, 0xef, 0x48, 0x8e, 0x62, 0x72, 0xa7, 0xa1, 0x3c, 0x1a, 0x4d, 0xeb, 0x74, 0x1b, +0x9e, 0xd7, 0xf0, 0xff, 0x00, 0x5b, 0x8e, 0x45, 0x6d, 0x36, 0xe4, 0xee, 0xdd, 0xf7, 0x43, 0x1e, +0xa3, 0x1d, 0x2b, 0x07, 0xc5, 0x7a, 0x43, 0xe9, 0x1a, 0xa4, 0xb8, 0x52, 0x2d, 0xae, 0x98, 0xc9, +0x0b, 0x63, 0x03, 0x04, 0xf4, 0xfc, 0x33, 0xfa, 0xd5, 0xc5, 0xea, 0x70, 0xcd, 0x72, 0xd4, 0x67, +0x31, 0xbb, 0x93, 0x9a, 0x70, 0x7e, 0xf9, 0xab, 0xb8, 0x31, 0xe1, 0xaa, 0x60, 0xfe, 0xf9, 0x35, +0xa2, 0xd8, 0x89, 0x13, 0x2c, 0xb8, 0x3c, 0x9e, 0xb5, 0x7e, 0x29, 0xc8, 0xc7, 0x3f, 0xad, 0x69, +0x16, 0x63, 0x35, 0x74, 0x6f, 0xd9, 0xdd, 0x10, 0x41, 0xc9, 0xeb, 0xeb, 0x5f, 0x45, 0xfc, 0x2e, +0xf1, 0x42, 0x3e, 0xfd, 0x16, 0xea, 0x5f, 0xf5, 0x9f, 0x35, 0xb9, 0x76, 0xfe, 0x2e, 0xeb, 0xf8, +0xff, 0x00, 0x4f, 0x7a, 0xde, 0x5e, 0xf4, 0x1a, 0x38, 0xef, 0xc9, 0x52, 0x32, 0x3d, 0xba, 0x8a, +0xe2, 0x3d, 0x40, 0xa0, 0xf2, 0x0f, 0x24, 0x67, 0xbf, 0xa5, 0x00, 0x52, 0xbb, 0xd4, 0x2c, 0xb4, +0xf8, 0x8c, 0xb7, 0xf7, 0x96, 0xf6, 0xca, 0xa3, 0x25, 0xa6, 0x70, 0xb9, 0xfa, 0x0e, 0xa6, 0xbc, +0xab, 0x5e, 0xf8, 0xb3, 0x67, 0x6a, 0x64, 0x87, 0x47, 0xb7, 0x17, 0x2c, 0x0e, 0x05, 0xdd, 0xc1, +0xc2, 0x9f, 0xa2, 0x7f, 0x89, 0xfc, 0x2a, 0x64, 0xfb, 0x0a, 0xfd, 0xcf, 0x0c, 0xd6, 0xbc, 0x51, +0xaa, 0x6a, 0xf2, 0xb4, 0x97, 0xb7, 0xb7, 0x13, 0x72, 0x48, 0x59, 0x24, 0x25, 0x53, 0x27, 0xb0, +0xe8, 0x07, 0xb0, 0xae, 0x4a, 0x6b, 0x92, 0x49, 0x24, 0xe4, 0xfa, 0x9e, 0xf5, 0x95, 0x9f, 0x53, +0x55, 0xdc, 0xc8, 0xb8, 0x70, 0xfb, 0xbd, 0xfd, 0xeb, 0x21, 0x9f, 0xaa, 0x9e, 0xa2, 0xa9, 0x16, +0xd9, 0x51, 0xce, 0x79, 0xaa, 0x32, 0x9c, 0x7b, 0xd3, 0xd4, 0x69, 0x26, 0x51, 0x72, 0x49, 0x3c, +0x11, 0xee, 0x6a, 0x16, 0xfc, 0x7a, 0x75, 0xc5, 0x3f, 0x52, 0x93, 0xea, 0x45, 0x8c, 0x9e, 0xbc, +0xd7, 0xb5, 0xfc, 0x29, 0xf8, 0x6d, 0x3f, 0x89, 0xef, 0xc6, 0xa5, 0x7c, 0x8d, 0x16, 0x91, 0x60, +0x44, 0xb3, 0x4b, 0x22, 0xf0, 0xf8, 0xe7, 0x68, 0x27, 0xb9, 0xc5, 0x5c, 0x12, 0x6f, 0x53, 0x3c, +0x45, 0x4b, 0x47, 0x4f, 0x42, 0x81, 0xce, 0x73, 0x55, 0x2e, 0x17, 0x72, 0x93, 0x56, 0x4e, 0xfb, +0x9c, 0x96, 0xa1, 0x6e, 0xd2, 0x6e, 0x55, 0x19, 0x2d, 0x5e, 0x77, 0xae, 0x69, 0xf3, 0x5b, 0xee, +0xcf, 0x05, 0xf9, 0xc8, 0xad, 0xe8, 0xc9, 0x5e, 0xc4, 0x54, 0x56, 0x57, 0x38, 0xc8, 0xed, 0xe4, +0x91, 0xfe, 0x61, 0xc0, 0x3c, 0xe6, 0xba, 0x48, 0x12, 0x38, 0x23, 0x5d, 0xb8, 0x19, 0xea, 0x6b, +0x4c, 0x45, 0xed, 0x64, 0x3a, 0x1f, 0x15, 0xcb, 0x11, 0x4e, 0x93, 0x64, 0x23, 0x67, 0x69, 0xc5, +0x12, 0x82, 0x46, 0x7b, 0x8e, 0x45, 0x79, 0xf2, 0x8d, 0x99, 0xdd, 0x09, 0x73, 0x2b, 0xa2, 0xdc, +0x32, 0xee, 0x40, 0x73, 0xcf, 0xbd, 0x5a, 0x53, 0x9f, 0xc7, 0xd6, 0xb2, 0xea, 0x5b, 0xda, 0xec, +0x90, 0x31, 0xe7, 0x9a, 0x78, 0x7e, 0xf9, 0xe6, 0x96, 0xc4, 0xbd, 0x74, 0x26, 0x57, 0xc1, 0xeb, +0x9a, 0x96, 0x43, 0xb9, 0x77, 0x03, 0xc8, 0xe6, 0x9e, 0xe4, 0xdf, 0x53, 0x63, 0x46, 0xd4, 0xa4, +0xb1, 0xbb, 0x86, 0xe5, 0x18, 0x82, 0x8d, 0xce, 0x3b, 0xd7, 0xbf, 0x6a, 0xd6, 0xf1, 0x78, 0xaf, +0xc3, 0x71, 0xdc, 0xc3, 0xf3, 0xde, 0x5b, 0x47, 0xe6, 0x21, 0xee, 0x78, 0xe9, 0x42, 0xd1, 0x9c, +0x98, 0x85, 0x6b, 0x49, 0x1e, 0x1c, 0xdb, 0x91, 0x8a, 0xb0, 0x20, 0x83, 0x82, 0x0f, 0x51, 0x49, +0xbb, 0xdf, 0xf3, 0xad, 0x93, 0x44, 0xbd, 0x87, 0x86, 0xa7, 0x86, 0x39, 0xeb, 0x9a, 0xad, 0x48, +0x96, 0xe4, 0xc1, 0xb3, 0xf5, 0xcd, 0x58, 0x49, 0x73, 0x5a, 0x27, 0xd0, 0xc9, 0x9a, 0x30, 0xcf, +0x8c, 0x73, 0x5d, 0x4e, 0x91, 0xac, 0x4d, 0x63, 0x73, 0x6f, 0x75, 0x04, 0xad, 0x1c, 0xb0, 0xba, +0xba, 0xb8, 0xea, 0x08, 0x39, 0x06, 0xb7, 0x84, 0x8e, 0x4a, 0xb1, 0x6c, 0xfb, 0x2b, 0xc2, 0x9e, +0x24, 0xb6, 0xf1, 0x36, 0x93, 0x0d, 0xec, 0x2e, 0xbf, 0x68, 0x40, 0x12, 0xe6, 0x11, 0xd5, 0x1f, +0xd7, 0x1e, 0x87, 0xa8, 0xff, 0x00, 0xeb, 0x57, 0x4d, 0x5c, 0xd3, 0x8f, 0x2c, 0x9a, 0x3b, 0x69, +0x4f, 0xda, 0x41, 0x36, 0x65, 0x6a, 0x5a, 0xbe, 0x99, 0xa2, 0x44, 0x66, 0xd4, 0x6f, 0x12, 0xdd, +0x1f, 0x73, 0x22, 0xc8, 0x72, 0xcd, 0x8e, 0xa1, 0x47, 0x53, 0xd7, 0xf5, 0xaf, 0x20, 0xf1, 0x0f, +0xc5, 0xc5, 0x08, 0xf0, 0x68, 0x70, 0x3c, 0x2e, 0x4f, 0xfc, 0x7e, 0x5c, 0x85, 0x66, 0xfc, 0x13, +0x90, 0x3f, 0x1c, 0xd5, 0x53, 0x87, 0x3e, 0xaf, 0x63, 0x2a, 0xb5, 0x7d, 0x9a, 0xe5, 0x8e, 0xe7, +0x8a, 0x6a, 0x9e, 0x21, 0xd4, 0x75, 0x49, 0x9e, 0xe2, 0xfa, 0xee, 0x6b, 0x89, 0x5b, 0xf8, 0xe5, +0x6c, 0x9c, 0x56, 0x0b, 0xdd, 0x13, 0x9e, 0x72, 0x7d, 0x4d, 0x4c, 0xd2, 0xb9, 0x54, 0xdb, 0xb1, +0x42, 0x59, 0xc9, 0xcf, 0x24, 0x56, 0x7c, 0x93, 0x7b, 0xd6, 0x2f, 0xcc, 0xea, 0x4e, 0xe5, 0x47, +0x97, 0x39, 0xe6, 0xb3, 0xa7, 0x6e, 0x77, 0xe7, 0xa7, 0xeb, 0x48, 0xbd, 0xde, 0xa5, 0x66, 0x6d, +0xc3, 0x22, 0xaa, 0x49, 0xea, 0x7f, 0x5a, 0x65, 0x24, 0x55, 0x7e, 0x33, 0xff, 0x00, 0xeb, 0xcd, +0x57, 0x63, 0xcf, 0xa9, 0xee, 0x28, 0xdc, 0xa3, 0xa7, 0xf0, 0x97, 0x87, 0x2f, 0x3c, 0x4b, 0xac, +0xd9, 0xe9, 0xd6, 0x91, 0x99, 0x1e, 0x79, 0x30, 0x73, 0xd0, 0x0e, 0xe4, 0x9e, 0xd5, 0xf7, 0x44, +0x90, 0x41, 0xe1, 0x4f, 0x0c, 0x59, 0xe8, 0xf6, 0x41, 0x61, 0x8d, 0x21, 0xdb, 0x2b, 0xa0, 0xc7, +0x98, 0x70, 0x32, 0x73, 0xef, 0xff, 0x00, 0xd6, 0xad, 0x22, 0xad, 0x1f, 0x53, 0x8b, 0x13, 0x3f, +0x7d, 0x25, 0xd0, 0xf9, 0x1f, 0xaf, 0x7e, 0x4d, 0x74, 0xbe, 0x1d, 0xf0, 0x96, 0xa5, 0xe2, 0x4b, +0x81, 0x1d, 0xbc, 0x4e, 0x20, 0xcf, 0xcf, 0x29, 0x53, 0x81, 0x54, 0xda, 0xdc, 0xdb, 0x53, 0x3f, +0xc5, 0x5a, 0x15, 0x86, 0x8f, 0x7a, 0xd6, 0xb6, 0xb7, 0x09, 0x75, 0x24, 0x5f, 0x2c, 0x8c, 0x9c, +0x85, 0x3e, 0x99, 0xaf, 0x2a, 0xf1, 0x0d, 0x88, 0xb8, 0xb6, 0x66, 0x00, 0x97, 0x8c, 0xe7, 0x81, +0xd6, 0x94, 0x1e, 0xa9, 0xb2, 0xad, 0xcd, 0x16, 0x8f, 0x2c, 0x91, 0x44, 0x65, 0x89, 0x00, 0x63, +0xa9, 0xac, 0xbb, 0x9b, 0xd6, 0x20, 0xc6, 0x98, 0x1e, 0xf5, 0xda, 0xe3, 0x7d, 0x0c, 0x13, 0x68, +0xb3, 0xa5, 0x47, 0x2a, 0xb3, 0x3b, 0x13, 0xb5, 0xbb, 0x1e, 0xf5, 0xba, 0xc7, 0x35, 0xc9, 0x88, +0x69, 0xca, 0xc8, 0xed, 0xc3, 0xdd, 0x42, 0xec, 0x8a, 0x27, 0xf2, 0xa5, 0x20, 0x9f, 0x95, 0xfa, +0x66, 0xb4, 0x95, 0xb8, 0xeb, 0xf8, 0xd7, 0x2c, 0xb5, 0x3a, 0x11, 0x28, 0x6f, 0xcc, 0xd4, 0x81, +0xb3, 0xdc, 0x9a, 0x48, 0x97, 0x72, 0x55, 0x39, 0xe7, 0xd6, 0xa6, 0x47, 0x1d, 0x0f, 0x23, 0xeb, +0x4d, 0xd9, 0xa2, 0x1e, 0x9a, 0x82, 0x37, 0x97, 0x21, 0xea, 0x43, 0x74, 0xaf, 0x69, 0xf8, 0x71, +0xe2, 0x21, 0x6f, 0x21, 0xb0, 0x9d, 0x81, 0x47, 0xc6, 0xd5, 0x63, 0xd4, 0x77, 0x14, 0x8c, 0xeb, +0xae, 0x68, 0x94, 0xbc, 0x6f, 0xa4, 0xfd, 0x8b, 0x55, 0x9e, 0xea, 0x21, 0xb6, 0xda, 0xec, 0xf9, +0x8b, 0x91, 0x81, 0x9c, 0x73, 0x5c, 0x3e, 0xef, 0xcf, 0xd6, 0xb5, 0x5a, 0xa4, 0xd9, 0xcd, 0x09, +0x5d, 0x06, 0xee, 0x69, 0xc1, 0xb9, 0x27, 0x35, 0x60, 0x4d, 0xbe, 0x9e, 0x24, 0xc1, 0xc9, 0x3d, +0x78, 0xaa, 0x4f, 0x53, 0x39, 0x2e, 0xac, 0xb4, 0x92, 0xf3, 0xd6, 0xaf, 0xc3, 0x73, 0xb7, 0xbf, +0x5a, 0xd2, 0x2c, 0xc6, 0x4a, 0xfa, 0x1e, 0xad, 0xf0, 0xdf, 0xc6, 0xf6, 0xfe, 0x18, 0xd5, 0xdd, +0xef, 0x96, 0x59, 0x6c, 0xae, 0xe1, 0x30, 0xc9, 0xe5, 0x30, 0xdc, 0x9c, 0x82, 0x1f, 0x1d, 0xf1, +0x8c, 0x7d, 0x09, 0xaf, 0x47, 0xd7, 0x7e, 0x33, 0x96, 0xf3, 0x21, 0xd0, 0xed, 0x52, 0x24, 0x61, +0x85, 0xbb, 0xb9, 0x3b, 0xa4, 0x3e, 0xe1, 0x7a, 0x0f, 0xc7, 0x35, 0x6e, 0x0a, 0xa3, 0x4d, 0x99, +0x46, 0x6e, 0x94, 0x5a, 0x47, 0x8a, 0xea, 0x3a, 0xed, 0xe6, 0xa5, 0x3c, 0x97, 0x17, 0x57, 0x12, +0xcb, 0x24, 0x84, 0x92, 0xf2, 0x39, 0x62, 0x6b, 0x1d, 0xae, 0x7d, 0xce, 0x7d, 0x73, 0x56, 0xec, +0xb6, 0x21, 0x45, 0xcb, 0x56, 0x53, 0x92, 0xe0, 0xf3, 0x93, 0x55, 0x5a, 0x6f, 0x7c, 0xd6, 0x13, +0xd4, 0xea, 0x82, 0x2b, 0xbc, 0xb9, 0xcd, 0x54, 0x79, 0x32, 0x0e, 0x4d, 0x73, 0xb4, 0x75, 0x26, +0x57, 0x69, 0x3a, 0xf3, 0x55, 0xe4, 0x6f, 0x53, 0x9f, 0xad, 0x22, 0xcc, 0xf2, 0xfb, 0x18, 0xa9, +0x3c, 0x1e, 0x46, 0x6a, 0x39, 0x18, 0x1e, 0xfe, 0xf4, 0xed, 0x72, 0xb5, 0xdc, 0xae, 0xe7, 0x3d, +0x69, 0x11, 0x0b, 0xb8, 0x03, 0x92, 0x4d, 0x26, 0xee, 0x55, 0xee, 0xac, 0x7d, 0xb7, 0xf0, 0x5f, +0xc1, 0xcb, 0xa1, 0xe8, 0x12, 0x6b, 0x37, 0xd1, 0x01, 0x79, 0xa9, 0x0c, 0xc6, 0xce, 0x30, 0xd1, +0xc5, 0xc7, 0x4f, 0xa9, 0xc8, 0xfc, 0x3d, 0xea, 0x7f, 0x18, 0x6a, 0x0f, 0x73, 0x72, 0xf1, 0x23, +0x1d, 0x80, 0x91, 0xc1, 0xe8, 0x2b, 0x77, 0xad, 0x91, 0xe6, 0x49, 0xb7, 0x27, 0x27, 0xd4, 0xf9, +0xea, 0xce, 0xd8, 0xcf, 0x20, 0x0f, 0xf2, 0xc7, 0xd4, 0xb3, 0x57, 0xa3, 0xcb, 0xe3, 0x43, 0x63, +0xa3, 0x0d, 0x1b, 0x47, 0x87, 0xec, 0x85, 0x86, 0x26, 0xbb, 0x1f, 0x7d, 0xfd, 0x81, 0xec, 0x2a, +0x25, 0x1b, 0xb3, 0xb6, 0xfd, 0x0f, 0x35, 0xba, 0x2d, 0x36, 0xe7, 0x72, 0x59, 0x9b, 0x92, 0x4f, +0x7a, 0xe7, 0x6e, 0xe2, 0xce, 0xe0, 0xc3, 0x21, 0xb8, 0x35, 0x4c, 0xa8, 0xb3, 0xc7, 0x7c, 0x47, +0x60, 0xd6, 0xd2, 0xc8, 0x17, 0x85, 0x6c, 0x91, 0x5c, 0x7c, 0x16, 0xe5, 0xe4, 0xcb, 0x8f, 0x94, +0x1c, 0xd7, 0x6c, 0x1d, 0xe2, 0x9b, 0x39, 0x5e, 0xf6, 0x3a, 0x45, 0x2b, 0x14, 0x7c, 0x63, 0x00, +0x71, 0x4b, 0x0c, 0xeb, 0x38, 0x24, 0x67, 0x23, 0xae, 0x6b, 0x82, 0xad, 0xf9, 0xb5, 0x3d, 0x5a, +0x5a, 0xc7, 0x41, 0x25, 0x04, 0xae, 0xef, 0x43, 0x9a, 0xb5, 0x04, 0xbe, 0x62, 0xee, 0xcf, 0xb6, +0x6b, 0x27, 0xb1, 0x57, 0xb9, 0x6c, 0x1c, 0xf7, 0xe6, 0x9f, 0x9c, 0x1e, 0xf9, 0xa9, 0x6b, 0xa8, +0x9d, 0xd9, 0x20, 0x6e, 0x33, 0x52, 0xab, 0x9e, 0xc7, 0xff, 0x00, 0xaf, 0x47, 0x99, 0x16, 0xb1, +0x23, 0x9d, 0xeb, 0x9e, 0xe3, 0xd6, 0xb4, 0xb4, 0xbb, 0xf9, 0x2d, 0x6e, 0x61, 0x9d, 0x18, 0x86, +0x8d, 0xc1, 0xa2, 0xe9, 0xea, 0x0d, 0x5d, 0x58, 0xfa, 0x0a, 0x61, 0x07, 0x8a, 0xfc, 0x34, 0x42, +0x85, 0x6b, 0xa8, 0x97, 0xcc, 0x47, 0x3d, 0x46, 0x33, 0xc5, 0x78, 0x84, 0x8a, 0xd1, 0xbb, 0x23, +0x64, 0x32, 0x1c, 0x11, 0xdc, 0x55, 0xc7, 0x55, 0x63, 0x82, 0x1a, 0x49, 0xa1, 0x99, 0xee, 0x4e, +0x69, 0xe1, 0xaa, 0xca, 0x63, 0x83, 0xf3, 0xd7, 0x34, 0xfd, 0xd9, 0x07, 0xbf, 0xd6, 0xad, 0x33, +0x39, 0x58, 0x7a, 0x49, 0xeb, 0xd6, 0xa6, 0x17, 0x01, 0x7d, 0xcf, 0xb5, 0x52, 0x21, 0xa2, 0x54, +0xb9, 0xf9, 0xf1, 0xbc, 0x09, 0x31, 0x90, 0x33, 0xce, 0x2b, 0x52, 0x3b, 0xaf, 0x94, 0x10, 0x7a, +0xf5, 0x26, 0xb4, 0x52, 0x32, 0x94, 0x6e, 0x48, 0x6e, 0x4f, 0x72, 0x7e, 0xb4, 0xc3, 0x39, 0x27, +0xa9, 0xfa, 0xd5, 0x36, 0x34, 0x88, 0x5e, 0x52, 0x79, 0xcd, 0x56, 0x32, 0xf3, 0xd6, 0xb3, 0x96, +0xa6, 0x91, 0x22, 0x69, 0x7a, 0xf3, 0xcd, 0x57, 0x67, 0x27, 0x26, 0xb1, 0x69, 0x1b, 0x26, 0xc8, +0x59, 0xff, 0x00, 0xc9, 0xa8, 0x19, 0xfa, 0xf3, 0x52, 0xcd, 0x0a, 0x53, 0x65, 0x81, 0x3d, 0xc7, +0x23, 0x35, 0x18, 0x93, 0x72, 0xe7, 0x9c, 0xf7, 0xf6, 0xa5, 0xea, 0x69, 0xe6, 0x86, 0x12, 0x4f, +0x39, 0x39, 0x3c, 0x1a, 0xf5, 0x2f, 0x85, 0xde, 0x08, 0x93, 0xc5, 0xfa, 0xe2, 0x24, 0xbf, 0xbb, +0xb2, 0xb4, 0x1e, 0x75, 0xc4, 0xc7, 0x3c, 0x28, 0x23, 0x8f, 0xa9, 0xcd, 0x54, 0x15, 0xe5, 0x63, +0x2a, 0xf3, 0x70, 0x83, 0x67, 0xdb, 0x97, 0xd2, 0xc7, 0x65, 0xa6, 0x25, 0xbd, 0xb8, 0xf2, 0xe2, +0x8a, 0x30, 0x8a, 0xaa, 0x38, 0x55, 0x1c, 0x01, 0xfa, 0x57, 0x85, 0x6b, 0x17, 0x8f, 0x24, 0xf2, +0x60, 0xf0, 0xc4, 0xe4, 0xfa, 0xd6, 0xcf, 0x57, 0x73, 0xcb, 0x84, 0xba, 0x1f, 0xff, 0xff, 0xd9 +}; + +static unsigned int PIC_LEN_2 = 11584; + + #endif //_SAMPLE_JPEG_H_ \ No newline at end of file diff --git a/USDK/component/common/media/framework/mmf_source_modules/sample_pcmu.h b/USDK/component/common/media/framework/mmf_source_modules/sample_pcmu.h new file mode 100644 index 0000000..3bf6ca7 --- /dev/null +++ b/USDK/component/common/media/framework/mmf_source_modules/sample_pcmu.h @@ -0,0 +1,14596 @@ +#ifndef SAMPLE_PCMU_H +#define SAMPLE_PCMU_H + +const int pcmu_sample_size=466652; + +#include "section_config.h" +SDRAM_DATA_SECTION const unsigned char pcmu_sample[]={ +0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff +,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff +,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff +,0xff,0xff,0xff,0xff,0xff,0xff,0xff +,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xfe,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff +,0xff,0xff,0xff,0xff,0xfe,0xff,0x7e,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x7e,0xff,0x7e,0xfe,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff +,0xfe,0x7e,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xfe,0xff,0xfe,0xfe,0xfe,0xff +,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff +,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0x7e,0x7e,0xff,0xff +,0xff,0xff,0x7e,0xff,0xff,0x7e,0xfe,0xff,0xff,0x7e,0x7e,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xff,0xff,0xff,0x7e,0xff +,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0xfe,0xff +,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0x7e,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0x7e,0xff,0xff +,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xff,0x7e,0xfe,0x7e,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff +,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0x7e,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0xff,0xff +,0xff,0xff,0xff,0xfe,0xff,0x7e,0xff,0xfe,0xff,0xfe,0xff,0xff,0xfe,0xff,0x7e,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xfe,0xff +,0x7e,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0x7e,0xff,0x7e +,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xfe,0xfe,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff +,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xff,0xff,0xfe,0xff,0xfe,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff +,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff +,0xff,0xff,0xff,0xff,0xff,0x7e,0x7e,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff +,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0x7e,0xff,0xff,0xff,0xff,0xfe,0xff,0x7e,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0x7e +,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x7e +,0xfe,0x7e,0xff,0x7e,0xfe,0x7e,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0x7e,0xff,0x7d,0xfe,0xfe,0xfe,0x7d,0xfc,0x7c,0xfd,0x7d,0xfc,0x7b,0xfc,0x7d,0xfc,0x7c,0xfc,0x7c,0xfb +,0x7c,0xfe,0x7e,0xff,0xfe,0x7e,0xfb,0xfb,0xf9,0x79,0xfb,0x6c,0xfa,0x75,0xef,0x6e,0xeb,0x69,0xe6,0x60,0xdd,0x36,0x44,0xb7,0x23,0x2e,0xbd,0x4b,0xaf,0xb8,0x20,0x48 +,0xde,0x2b,0xc2,0x41,0x1f,0x77,0x63,0x60,0xa0,0xe6,0x47,0xa6,0xde,0xf0,0xae,0x2c,0x44,0xaf,0x4a,0xac,0xb0,0x26,0x74,0xd1,0x32,0xae,0xd4,0x2c,0xaf,0xc1,0xf0,0xa5 +,0x44,0x3a,0xad,0x3f,0x5c,0xb3,0x27,0x3c,0xbc,0x3b,0xab,0xaf,0x2b,0xc3,0xc5,0x33,0xb6,0x3d,0x24,0xc2,0xdd,0xe6,0xa7,0x35,0x2c,0xc4,0x33,0x55,0xba,0x26,0x2f,0xcb +,0x2f,0xc5,0x77,0x24,0xc3,0xc5,0x38,0xb1,0x44,0x27,0xb9,0xc5,0xb6,0xa5,0x3d,0xf1,0xac,0x3e,0xc8,0xaf,0x45,0xbd,0xb0,0xd8,0xae,0x54,0x2d,0xb4,0xc4,0x4e,0xb1,0x56 +,0x3d,0xae,0xc3,0xc6,0xbc,0x2f,0xe1,0xb3,0x38,0xe4,0xdb,0x29,0x3b,0x45,0x40,0xb2,0x62,0x44,0xb4,0x3a,0x2e,0xcd,0x3f,0x3e,0xd6,0x38,0x49,0x52,0x2c,0x5e,0xe6,0x34 +,0xc9,0xbf,0x3b,0x3e,0x30,0x32,0xc8,0x6d,0xdd,0xb8,0x3d,0x5c,0xad,0xc1,0xbf,0xbb,0xed,0xb1,0xb0,0xcc,0xb0,0xd6,0x3e,0xb1,0xb4,0x5b,0xf0,0x4d,0xce,0xb2,0x69,0xd9 +,0xc2,0x4a,0xb5,0xa6,0xd5,0x3f,0x33,0x30,0xd4,0xcb,0xdb,0xc0,0x40,0x44,0xbf,0x46,0x2c,0x32,0x36,0x50,0xda,0x38,0x3e,0x3e,0x39,0xb7,0xb0,0x61,0x38,0x33,0x3a,0x51 +,0x3a,0x34,0x5a,0x3c,0x4f,0xbc,0x62,0x3e,0x44,0x5a,0xbe,0xbf,0x6f,0xc3,0xc0,0xbd,0xab,0xb7,0x5f,0x4d,0x68,0xb8,0xae,0xc7,0x7b,0x63,0x51,0xb5,0xa8,0xb7,0xd3,0x4c +,0x6b,0xc2,0xdf,0xe9,0xcf,0xdf,0xbd,0xac,0xc4,0x3d,0x2d,0x2f,0xd9,0xcf,0x58,0x45,0x2d,0x2f,0xcb,0xbb,0x5d,0x3d,0x31,0x42,0xdb,0x6e,0x60,0x32,0x2e,0xf1,0xc0,0xd4 +,0x4e,0x3b,0x3d,0xcf,0xfc,0x3d,0x35,0x29,0x4d,0xae,0xad,0xbf,0x37,0x30,0xd9,0xb8,0xb6,0xb1,0x49,0x33,0xbf,0xb0,0xaf,0xc1,0x3f,0xec,0xc5,0xe7,0xd5,0x41,0x2f,0xbc +,0xa3,0xa8,0xb3,0x40,0x38,0xe7,0xc8,0xb5,0xc2,0x2f,0x32,0xbd,0xb7,0xb6,0xec,0x2f,0x42,0x4d,0x47,0xd2,0x3a,0x29,0x6c,0xba,0xc3,0xc9,0x3a,0x40,0xc1,0xd0,0xc5,0x43 +,0x21,0x36,0xb9,0xaf,0xaf,0x48,0x26,0x2d,0x3c,0xd4,0xbe,0x3a,0x35,0xc5,0xbd,0xbb,0xbe,0x3b,0x49,0xc6,0xbe,0xb1,0x58,0x27,0x45,0xb4,0xb5,0xb2,0x4d,0x2e,0x4b,0x54 +,0xc4,0xbc,0x35,0x35,0xc5,0xb9,0xad,0xb0,0x42,0x5d,0xd9,0xd7,0xb5,0x4c,0x36,0xcd,0xc7,0xd6,0xd7,0x34,0x30,0xd9,0xbb,0xad,0xc5,0x27,0x2d,0xcc,0xb4,0xa4,0xad,0x3e +,0x3e,0x4b,0xe7,0xc7,0x38,0x2f,0x65,0xd6,0xc7,0xbd,0x36,0x2d,0x59,0xcb,0xb3,0xd8,0x2a,0x39,0xc5,0xb7,0xa8,0xbe,0x31,0x37,0x4a,0xc5,0xb8,0x35,0x29,0x44,0x4f,0xba +,0xaf,0x3e,0x37,0x58,0x59,0xc4,0x63,0x2c,0xea,0xb2,0xaf,0xa7,0x6d,0x29,0x3c,0xc6,0xae,0xaf,0x33,0x29,0x49,0x5c,0xad,0xab,0x39,0x35,0x59,0xd5,0xaf,0x50,0x27,0xdf +,0xb7,0xae,0xa0,0x65,0x27,0x3f,0xd7,0xb2,0xb5,0x2d,0x32,0xdd,0xfa,0xaa,0xbc,0x25,0x32,0xf0,0xbd,0xa9,0x52,0x28,0x6e,0xd7,0xb6,0xa5,0x3a,0x2d,0xd6,0xee,0xba,0x69 +,0x20,0x37,0xbf,0xbe,0xa3,0x5f,0x1a,0x33,0xc7,0xaf,0xa7,0x31,0x2a,0xdb,0x65,0xa8,0xa4,0x29,0x2d,0xca,0xcd,0xa9,0x5f,0x1e,0x39,0x5a,0xc0,0xa2,0x3a,0x20,0xef,0xe3 +,0xb4,0xaa,0x29,0x34,0xb6,0xc1,0x9e,0xae,0x22,0x3e,0xcd,0xe9,0xaa,0x3a,0x26,0xbc,0x46,0xcf,0xab,0x21,0x28,0xac,0xba,0xa6,0xb9,0x1e,0x43,0xcb,0xbf,0x99,0xce,0x1e +,0x74,0x62,0xd7,0xaa,0x26,0x27,0xca,0x3a,0xa8,0xab,0x1c,0x37,0xac,0xbf,0x9e,0xc7,0x1f,0xd5,0x57,0xc3,0x9d,0x29,0x1e,0xbf,0x42,0xb7,0xad,0x1b,0x2b,0xcc,0x3e,0x9d +,0xbf,0x19,0xba,0xad,0xbf,0x9d,0x2e,0x1d,0xba,0x6a,0xa6,0x9e,0x18,0x20,0xb5,0x5f,0x9e,0xb9,0x16,0x3a,0x64,0xf6,0x98,0x3e,0x1a,0xb2,0xc0,0xa9,0x9a,0x1f,0x21,0xcf +,0x3e,0x99,0xa3,0x16,0x38,0xb7,0x4c,0x9d,0x51,0x18,0x5c,0x41,0xb0,0x9b,0x1f,0x20,0xa9,0xd3,0x9f,0xa3,0x18,0x2e,0xc3,0x60,0x98,0x4e,0x14,0xcf,0xd2,0xbd,0x9b,0x22 +,0x19,0xda,0x43,0x9c,0x9c,0x18,0x2f,0xaa,0xc2,0x97,0xbe,0x13,0x32,0x46,0xbb,0x97,0x25,0x18,0xbf,0x42,0xa8,0x9d,0x1c,0x24,0xc1,0xd8,0x98,0xbc,0x15,0x5f,0xaf,0xb2 +,0x98,0x37,0x18,0x63,0x4c,0xa7,0xa2,0x17,0x1f,0xb0,0xc6,0x9e,0xbe,0x14,0x2e,0xb8,0xa8,0x96,0x30,0x16,0xc3,0xb7,0xa4,0x9a,0x23,0x1d,0xd3,0xc1,0x9d,0xbd,0x12,0x25 +,0xbf,0xb7,0x9a,0xdf,0x1b,0x3c,0xda,0xa1,0x9c,0x21,0x1e,0xba,0xb6,0x9e,0xac,0x19,0x20,0x59,0xb7,0x9e,0x36,0x17,0x3e,0xc3,0xa9,0x9e,0x33,0x20,0x6f,0xac,0x99,0xaf +,0x18,0x1f,0xec,0xad,0x9b,0xda,0x19,0x23,0x4b,0xa6,0xa2,0x26,0x1c,0x4a,0xb3,0x9a,0xa4,0x22,0x20,0x4a,0xa5,0x97,0xce,0x1a,0x2c,0xe5,0xa9,0x9f,0x3e,0x1e,0x2e,0xd5 +,0xa3,0xbd,0x1c,0x1f,0x4f,0xa7,0x99,0xb2,0x27,0x2d,0xca,0xa2,0xa6,0x29,0x1d,0x3b,0xb4,0x9d,0xa9,0x26,0x1e,0x31,0xac,0x9d,0x43,0x1c,0x26,0x51,0xa2,0x9b,0xd7,0x2c +,0x3c,0xbf,0xa0,0xbf,0x1d,0x1d,0x34,0xb0,0x9c,0xb7,0x28,0x2b,0x59,0xa7,0xab,0x27,0x1e,0x3a,0xb6,0x9b,0xa0,0x39,0x2f,0x47,0xb5,0xa5,0x37,0x1c,0x29,0x41,0xb2,0xa5 +,0x52,0x2f,0x69,0xb6,0xa7,0x76,0x1b,0x1f,0x56,0xac,0x9d,0xa9,0x3e,0x47,0xc9,0xb1,0xb5,0x2c,0x20,0x2d,0x4b,0xb3,0xb3,0x4a,0x38,0xe2,0xaf,0xac,0xfb,0x29,0x2d,0x55 +,0xb7,0xac,0xba,0x5b,0x53,0xc5,0xb0,0x5a,0x24,0x22,0x29,0xec,0xad,0xb9,0xba,0xcb,0xdf,0xab,0xbb,0x33,0x32,0x35,0x70,0xae,0xc4,0x5e,0xe8,0x46,0xbd,0xad,0x3d,0x2a +,0x28,0x29,0xda,0xbd,0xdc,0xbb,0xd9,0xc2,0xa5,0xdb,0x38,0x3c,0x30,0xc9,0xb9,0xeb,0xb9,0xe6,0x41,0xb7,0xdb,0x40,0x3f,0x27,0x47,0xc8,0x63,0xaf,0xbb,0xdd,0xb4,0xce +,0x2f,0x39,0x2c,0x2c,0xc7,0x3b,0xbf,0x97,0xa0,0xb3,0xa9,0x29,0x34,0xb7,0x19,0x26,0xab,0xa9,0x97,0xa9,0x18,0x27,0x22,0x17,0x2b,0x3f,0x43,0xbe,0x9f,0xa9,0xa8,0xaa +,0x9c,0xbe,0x27,0x3b,0x1a,0x11,0xa5,0x8b,0x9b,0x9f,0x4b,0x1f,0x0e,0x0b,0x41,0xaf,0xca,0xb9,0x3c,0x1e,0x3f,0x9a,0x95,0x8d,0x86,0xa8,0x24,0xd3,0x28,0x0b,0x0c,0x2e +,0x99,0x8e,0x3d,0x17,0x2b,0xdc,0x2d,0x0b,0x07,0x12,0x98,0x82,0x84,0x8e,0x39,0x2b,0x97,0xaf,0x15,0x18,0x24,0xa3,0x8a,0x9a,0x0b,0x06,0xbc,0xd3,0x1b,0x38,0x21,0x09 +,0x14,0x8c,0x86,0x91,0xb3,0xaa,0x91,0x8e,0xe3,0x05,0x05,0x2d,0x8d,0x92,0x2f,0x28,0xaf,0xae,0xb4,0x35,0x0d,0x13,0x33,0xad,0xa8,0xb7,0xbf,0xb9,0x8f,0x85,0x9a,0x0f +,0x0a,0x08,0x09,0x41,0x8f,0x91,0x9f,0x98,0x9c,0x23,0x0b,0x07,0x15,0x9d,0x91,0x91,0x8d,0x8b,0x94,0xb4,0x36,0x0e,0x08,0x16,0x2b,0x1c,0x49,0x98,0x9d,0x2e,0x17,0x27 +,0x1a,0x3f,0x8d,0x8e,0x1d,0x0e,0x9a,0x84,0x8b,0x9b,0x9c,0xb8,0x6a,0x12,0x04,0x03,0x0f,0xa8,0xa7,0xa9,0xa5,0x21,0x17,0x9e,0x8e,0x9e,0xbe,0x31,0x24,0xa3,0x91,0xce +,0x26,0x9c,0x8e,0xc7,0x17,0x0c,0x0c,0x32,0x8e,0x88,0xa8,0x11,0x12,0xa0,0x93,0x1e,0x0d,0x14,0x6d,0x93,0x94,0xd0,0x23,0x1e,0x18,0x2f,0x3c,0x18,0x2d,0x97,0x8c,0x94 +,0x61,0x0f,0x14,0x98,0x83,0x8e,0x5c,0x55,0xca,0x2b,0x1d,0x1e,0x14,0x15,0x37,0xb4,0x48,0x1c,0x1d,0xcd,0x8d,0x8c,0xc7,0x16,0x52,0x9f,0xca,0xaf,0x9e,0xae,0xe2,0xaa +,0xa4,0xa5,0x49,0x1a,0x0c,0x0a,0x24,0xb5,0x2f,0x12,0xc6,0x97,0xa1,0xa7,0x96,0x9e,0xbe,0xc9,0x23,0x35,0x28,0x2b,0xdf,0xa6,0x9a,0xa6,0xf0,0x1f,0x0d,0x16,0xa1,0x8d +,0xa0,0x22,0x3d,0xa5,0x98,0xc1,0x13,0x0c,0x2a,0x8e,0x8d,0x9e,0x54,0x1f,0x13,0x15,0x2e,0x2e,0x5d,0xcd,0xbc,0x9e,0x36,0x0a,0x0c,0xa6,0x85,0x85,0x92,0xd8,0x23,0x25 +,0x39,0xa3,0xd8,0x12,0x1a,0xe0,0x9a,0xae,0x5c,0x25,0x1d,0x4c,0x27,0x10,0x11,0x9f,0x88,0x8e,0x99,0xac,0xc8,0xb3,0x59,0xbf,0xbf,0x24,0x16,0x1a,0xc3,0xad,0xb6,0x39 +,0x21,0x14,0x0f,0x25,0xd8,0x9e,0x8f,0x8c,0x94,0x4f,0x1a,0x18,0x4e,0x9f,0xa5,0xb7,0x2b,0x27,0x31,0x24,0xb7,0x90,0x8c,0xa7,0x11,0x0d,0x1e,0xbb,0x45,0x22,0xfb,0x97 +,0x91,0xab,0xb1,0x32,0x13,0x16,0x20,0x22,0x2a,0xb0,0x97,0x93,0x98,0x3d,0x10,0x18,0xd2,0x95,0x94,0x9b,0xae,0xeb,0xbd,0xb6,0xb6,0x2b,0x15,0x11,0x21,0x49,0x27,0x1e +,0x51,0x9c,0x9b,0x37,0x14,0x18,0x40,0x9f,0x97,0x99,0xa3,0xa4,0x9e,0x9c,0xa2,0x41,0x1f,0x1f,0x31,0xd7,0x44,0x2e,0x1e,0x16,0x18,0x2e,0xb4,0xa7,0xa8,0xb8,0xac,0xab +,0x39,0x18,0x24,0x9a,0x8d,0x9b,0xe2,0x2c,0x28,0x29,0x2a,0xb8,0x9a,0x99,0xc0,0x1e,0x1b,0x36,0xe7,0x29,0x25,0x54,0xa6,0x9c,0xa6,0xbf,0x7c,0x53,0x35,0x1c,0x11,0x1a +,0xb3,0x98,0x99,0xce,0x16,0x15,0x56,0x99,0x8f,0x93,0xa3,0x38,0x27,0xbd,0x9e,0xaf,0x28,0x15,0x17,0x33,0x5c,0x2f,0x5c,0xa2,0x9f,0xc7,0x1c,0x0e,0x17,0xb7,0x92,0x8e +,0x95,0xad,0x52,0x4b,0xfe,0x4e,0x2e,0x2c,0x31,0x2f,0x35,0x79,0xc8,0x43,0x25,0x21,0x39,0xc2,0xaf,0xa7,0x9e,0x98,0x9f,0x2a,0x11,0x21,0xa8,0x9c,0xb0,0x2a,0x1f,0x25 +,0x2a,0x4e,0xa7,0x98,0x95,0xaf,0x23,0x24,0x36,0x3c,0x40,0x33,0xde,0x9c,0x9a,0xb5,0x2d,0x22,0x32,0xe3,0x2a,0x17,0x1d,0xc7,0x9c,0x9e,0xc1,0x4c,0x46,0x43,0x7a,0xaf +,0x9c,0x9d,0xef,0x2d,0xcd,0xa8,0xb9,0x22,0x11,0x18,0x34,0x46,0x5c,0xb1,0xa2,0x9f,0xb3,0x29,0x18,0x22,0xbb,0x9d,0xa0,0xae,0xad,0xb1,0xb3,0xc6,0x2d,0x25,0x34,0x34 +,0x3c,0xb5,0xaf,0x68,0x20,0x13,0x1e,0xae,0x9a,0x9f,0xaf,0xaf,0xa6,0xb6,0x2e,0x20,0x2f,0xb5,0xac,0xdb,0x32,0x2c,0x35,0x51,0x6f,0xc3,0x9f,0xa0,0x4e,0x24,0x21,0x3b +,0xab,0xaf,0x3e,0x4b,0xb2,0xa5,0xb2,0x37,0x2f,0x48,0x3c,0x24,0x1c,0x2b,0xaa,0x9f,0xdb,0x2b,0x33,0x4e,0xb8,0xac,0xa7,0x9e,0xa6,0xc1,0xbe,0xac,0xaf,0x4e,0x1c,0x12 +,0x1b,0x2a,0x33,0x47,0xb1,0x9c,0x9b,0xbb,0x1f,0x14,0x1f,0xb0,0x9d,0x9c,0x9c,0xa2,0xac,0xbb,0x2b,0x24,0x55,0x4f,0x2c,0x2a,0x33,0x62,0x7a,0x2e,0x24,0x32,0x52,0xbf +,0xae,0xaa,0x9e,0xa6,0xc0,0x53,0x3d,0xc3,0xac,0xd5,0x28,0x1c,0x1e,0x46,0xcf,0x43,0xee,0xa5,0x9c,0xab,0x39,0x21,0x2a,0xe9,0xb0,0xad,0xa5,0xa0,0xb0,0x38,0x2f,0x46 +,0x41,0x3b,0x27,0x19,0x24,0x59,0xcb,0xb4,0xb8,0xc7,0xbb,0xc0,0x46,0xb9,0x9e,0x9f,0xa5,0xb7,0xd6,0xbf,0x47,0x1d,0x13,0x13,0x1c,0x2b,0xce,0x9f,0x99,0xa3,0xd3,0x24 +,0x1f,0x45,0xb6,0xb4,0xaf,0xa3,0x9d,0x9f,0x5e,0x29,0x32,0x6a,0xc9,0x41,0x27,0x2b,0x42,0x5b,0xe7,0x43,0xf8,0xb6,0xcb,0x73,0xc6,0xca,0xc4,0xb5,0xcd,0xf8,0xad,0xac +,0xc0,0x3c,0x1f,0x1b,0x26,0x38,0x43,0xb9,0xa2,0xa5,0xe7,0x2f,0x3e,0xbc,0xac,0xdd,0x29,0x2b,0x50,0xb6,0xa2,0xa5,0xc4,0xce,0xde,0x27,0x1d,0x1e,0x25,0xec,0xb8,0xd0 +,0xb6,0xaf,0xba,0xaf,0xad,0xaa,0xac,0xc9,0x4d,0xbe,0xaa,0xaf,0x3d,0x1c,0x1b,0x20,0x2c,0x57,0xb6,0xb8,0xed,0x2f,0x20,0x29,0xc2,0x9c,0x96,0x9e,0xbc,0x37,0x2e,0x46 +,0xc3,0xac,0xaa,0x51,0x1e,0x22,0x43,0xad,0xb1,0x26,0x17,0x1e,0x35,0xbe,0xa2,0xa9,0xac,0xa1,0xa7,0xc5,0x51,0x40,0x51,0xf6,0x3a,0x27,0x29,0x44,0xb9,0xae,0xb8,0xd7 +,0x34,0x25,0x23,0x38,0xad,0x9b,0x9e,0xa8,0xaf,0x69,0x68,0x5b,0x3f,0x60,0xef,0x2b,0x1c,0x18,0x25,0xad,0x9d,0xa6,0x52,0x26,0x2d,0xcc,0xb5,0xa9,0x9f,0xa7,0xae,0xaa +,0xa9,0xac,0x3c,0x1a,0x14,0x17,0x1c,0x2c,0xc7,0xa8,0x9d,0xa3,0xcc,0x26,0x20,0x34,0xc7,0xae,0xaa,0xb3,0xb9,0xab,0xb2,0xb9,0xab,0xb3,0x31,0x1b,0x15,0x1f,0x74,0xb8 +,0xb2,0xaf,0xcc,0x3c,0x2d,0x2d,0xcd,0xa3,0xa0,0xba,0x34,0x2b,0xc3,0x9e,0x9f,0xc3,0x1d,0x15,0x1d,0x47,0xb5,0xa8,0xaf,0xf3,0x48,0x5f,0xb1,0xab,0xb8,0x72,0x3b,0x36 +,0x3a,0x56,0xb2,0x9f,0x9e,0xac,0x3c,0x16,0x0f,0x1b,0x4b,0xac,0xad,0x6d,0x3f,0xcf,0xae,0xa3,0xa4,0xb0,0xd0,0x66,0x6d,0xd8,0xe0,0x67,0xcc,0xda,0x4c,0x26,0x1a,0x21 +,0x63,0xa9,0xb7,0x29,0x19,0x29,0xaa,0x97,0x96,0xad,0x30,0x2b,0x53,0xb5,0xb3,0xbb,0xbe,0xd4,0x4b,0xf0,0xdc,0x32,0x23,0x28,0x33,0x40,0x32,0x28,0x40,0xab,0x97,0x94 +,0xa4,0x3e,0x2e,0x47,0xd2,0x5f,0x2d,0x26,0x3a,0xc0,0xb1,0x74,0x31,0x38,0x47,0xcd,0xea,0x3b,0x3c,0xb0,0x9d,0x9c,0xa3,0x5a,0x2b,0x3a,0xc2,0xbe,0x47,0x1f,0x14,0x1b +,0x58,0x9e,0x9b,0xca,0x20,0x23,0x68,0xae,0xbb,0x7a,0xbb,0xa2,0x97,0x99,0xaf,0x3c,0x27,0x25,0x2e,0x2f,0x1e,0x1c,0x3d,0xab,0x9e,0xb0,0x2c,0x1d,0x2a,0xaf,0xa8,0xf7 +,0x28,0x3c,0xa0,0x92,0x96,0xb5,0x36,0x2d,0x2e,0x2f,0x29,0x23,0x2d,0xd1,0xad,0xa9,0xc4,0x29,0x20,0x46,0xa4,0xa3,0x54,0x1f,0x27,0xac,0x94,0x99,0x6c,0x1e,0x1f,0x4f +,0xab,0xc5,0x1e,0x18,0x2c,0xad,0x99,0x9c,0xc6,0x2d,0x2d,0x66,0xb9,0xba,0x47,0x5b,0xac,0xa6,0xaf,0x57,0x2f,0x28,0x34,0x4c,0x2d,0x1c,0x1c,0x5c,0x9d,0x98,0xb1,0x2c +,0x2d,0xb9,0x9b,0x99,0xbd,0x20,0x21,0xc2,0x9f,0xa0,0xc1,0x23,0x1a,0x29,0xcc,0xdf,0x24,0x18,0x23,0xaf,0x9a,0xa8,0x39,0x2c,0xb7,0x95,0x95,0xeb,0x18,0x20,0xb3,0x9c +,0xa3,0x44,0x23,0x27,0x41,0xc5,0x62,0x20,0x14,0x23,0xaa,0x98,0x9d,0xbd,0x3f,0x6b,0xa4,0xa6,0x34,0x1a,0x22,0xba,0xa4,0xb4,0x2a,0x22,0xd5,0xa3,0xa9,0x35,0x17,0x19 +,0xcf,0x96,0x94,0xa8,0x2f,0x27,0xbf,0x9b,0x9d,0x37,0x12,0x13,0x37,0xa5,0xa7,0x40,0x2b,0x37,0xd1,0xaf,0xb8,0x2c,0x1d,0x63,0x9f,0x9c,0xab,0xda,0xc1,0xa6,0xa3,0xce +,0x20,0x14,0x1b,0x52,0xac,0xae,0x5a,0x35,0x3a,0x58,0xc0,0x70,0x2a,0x23,0x4a,0xa3,0x9c,0xa9,0x4d,0xf7,0xa5,0xa1,0xc6,0x24,0x18,0x27,0xae,0xa1,0xc1,0x29,0x27,0x38 +,0xc2,0xae,0xbe,0x2c,0x1f,0x30,0xb1,0x9c,0xa2,0x54,0x36,0xcd,0xad,0xae,0x3c,0x19,0x1b,0xef,0xa6,0xae,0x43,0x32,0x5d,0xb4,0xa9,0xb2,0x4e,0x2d,0x3d,0xaf,0xa7,0xbd +,0x52,0xcb,0xd7,0x42,0x30,0x1e,0x19,0x2e,0xad,0xa2,0xb6,0x30,0x2a,0xc6,0x9c,0x9a,0xac,0x2f,0x20,0x34,0xb0,0xa5,0xbc,0x38,0x30,0x47,0xdf,0x52,0x2d,0x28,0x41,0xc8 +,0xcf,0x4c,0x3e,0xcc,0xa9,0xa5,0xac,0xca,0x2d,0x1b,0x2b,0xa6,0x9e,0xbe,0x2f,0x37,0xce,0xae,0xae,0x5d,0x28,0x22,0x2a,0x4f,0xbc,0xac,0xa2,0xad,0x45,0x2e,0x37,0x3c +,0x53,0xc2,0xb5,0xc0,0x43,0x2d,0x36,0xaf,0xa1,0xad,0x36,0x1c,0x1e,0x62,0xa4,0xa1,0xae,0xcf,0x4b,0x3c,0xcc,0xbc,0x5c,0x35,0x2d,0x30,0x33,0x3f,0xc7,0xab,0xa8,0xc4 +,0x34,0x29,0x2b,0x3f,0xb1,0x9d,0xa2,0xcd,0x3b,0x3f,0xe4,0xb3,0xae,0x3b,0x1f,0x25,0x68,0xb6,0xc7,0xcf,0xbc,0xdc,0x2c,0x2a,0x3f,0xd4,0xbb,0xb7,0xc1,0xca,0xba,0xbb +,0x47,0x3e,0xc2,0xc4,0x38,0x29,0x42,0xb5,0xae,0xc6,0x4e,0x3d,0x30,0x47,0xbc,0xc1,0xc9,0xc0,0x4e,0x31,0x42,0xb6,0xab,0xbb,0x5d,0x46,0x3f,0x37,0x2c,0x2d,0xbb,0xab +,0x6e,0x33,0x3b,0xd3,0xb6,0xa7,0xa5,0xbf,0x3d,0x39,0x53,0xcd,0xbb,0xc2,0x38,0x25,0x2b,0x3e,0x51,0xfb,0xc9,0xcd,0x3d,0x39,0xc9,0xb5,0xb8,0xac,0xa6,0xbe,0x2a,0x26 +,0x3e,0xbe,0xb0,0xb7,0x55,0x27,0x26,0xd1,0xa6,0xac,0xcc,0x3f,0x2a,0x1f,0x35,0xaa,0xa4,0xb6,0x66,0x37,0x33,0x41,0x57,0xdb,0xbd,0xb6,0xbd,0xda,0x53,0xcf,0xb0,0xbc +,0x35,0x29,0x3b,0xda,0xbe,0xb5,0xbd,0x48,0x43,0xc9,0xb7,0xbe,0x43,0x2b,0x2c,0x3c,0xcd,0xae,0xb6,0x35,0x22,0x38,0xc8,0xce,0xc3,0xab,0xa3,0xad,0xb3,0xac,0xe7,0x31 +,0x3a,0xd3,0xc8,0x42,0x3a,0x2e,0x22,0x25,0x3f,0xff,0x3c,0x35,0x3d,0x30,0x35,0xbe,0xae,0xb5,0xba,0xad,0xa4,0xa9,0xa8,0xa8,0xca,0x36,0x2d,0x44,0xad,0xa3,0xa9,0xbd +,0x28,0x1b,0x23,0x46,0xc7,0x67,0x39,0x2e,0x30,0x36,0xdc,0xaf,0xdf,0x3d,0xec,0xb2,0xbd,0x41,0x4d,0xbe,0xb7,0xaa,0x9f,0xb0,0x3a,0x2c,0x2f,0x3b,0xe6,0xb6,0xb9,0x71 +,0x35,0x2e,0x2c,0x27,0x30,0x3f,0x40,0x3d,0x3c,0xc7,0xb3,0xbd,0xae,0xab,0xbd,0xc0,0xaa,0xa1,0xb2,0x49,0x50,0xce,0xc5,0xbf,0xb0,0xbe,0x27,0x1b,0x23,0x2e,0x2e,0x32 +,0x59,0xea,0xf6,0xb8,0xbb,0x3b,0x29,0x2f,0xbf,0xa3,0x9e,0xa0,0xb3,0x5a,0x4d,0xb1,0xa8,0xba,0x60,0x32,0x2d,0x31,0x68,0xb6,0xc6,0x44,0x37,0x32,0x26,0x25,0x31,0x46 +,0x4a,0x58,0xbe,0xb2,0xd2,0x63,0xb9,0xda,0x37,0x57,0xb8,0xb6,0xcf,0xc5,0xb3,0xb9,0xb8,0xac,0xb8,0x3c,0x36,0x4e,0xcc,0xdd,0x37,0x2f,0x34,0x33,0x4c,0xb3,0xd6,0x2b +,0x24,0x2d,0xc7,0xac,0xa2,0xa0,0xb6,0xee,0xe8,0xc3,0xcf,0xe9,0xbf,0xca,0x47,0x38,0xdf,0xdc,0x2e,0x32,0x43,0x36,0x2c,0x2f,0x59,0x49,0x37,0xcf,0xab,0xb0,0xcf,0xb9 +,0xb9,0x5b,0x47,0xc5,0xb5,0x5c,0x3d,0x6d,0xc3,0xc4,0xdc,0x71,0x32,0x26,0x39,0xaf,0xa4,0xc1,0x3b,0x35,0x3c,0xc6,0xa7,0xa3,0x6a,0x1f,0x1f,0x3d,0xbe,0xb6,0xaf,0xca +,0x2f,0x39,0xbe,0xbd,0x44,0x37,0x57,0xcc,0xc2,0xa6,0x9d,0xab,0x48,0x30,0x3f,0x4b,0x4a,0xcd,0x7d,0x25,0x1f,0x38,0xc4,0xc4,0x70,0x4e,0x2e,0x26,0x3d,0xaa,0xa6,0xc7 +,0x58,0xcc,0xb1,0xaa,0xa2,0xac,0x31,0x1f,0x32,0xbd,0xbd,0xde,0x51,0x34,0x29,0x34,0xc2,0xbc,0x40,0x2a,0x35,0xe0,0xbb,0xa4,0x9b,0xa7,0x57,0x58,0xbf,0xdf,0x3e,0x43 +,0x3b,0x2a,0x34,0xb9,0xad,0xd8,0x36,0x2f,0x30,0x37,0xcc,0xa9,0xb6,0x42,0x70,0xae,0xb2,0xde,0x6c,0x4c,0x2f,0x28,0x4a,0xbe,0x50,0x3a,0x42,0x7c,0xc3,0xbb,0xb7,0xfb +,0x2c,0x2f,0xba,0xac,0xc0,0xbe,0xc3,0x46,0x3c,0xbf,0xaf,0x68,0x2d,0x27,0x2c,0x3a,0xc7,0xab,0xaf,0x57,0x32,0x5b,0xba,0xc2,0xce,0xc6,0x4a,0x30,0xd0,0xa4,0xa1,0xad +,0xdd,0x35,0x2f,0x33,0x5b,0xbe,0x45,0x30,0x3c,0xe4,0x71,0x56,0x75,0x47,0x2f,0x36,0xb3,0xb5,0xc4,0xbe,0xc1,0xbf,0xba,0xb3,0xc6,0x32,0x23,0x2e,0x48,0x56,0x53,0x54 +,0x3e,0x34,0x54,0xac,0xa8,0xd0,0x47,0x3f,0x3e,0xc8,0xa3,0x9c,0xa7,0x4e,0x26,0x2e,0x38,0x33,0x46,0x46,0x2f,0x3e,0xb5,0xa9,0xae,0xbd,0xd8,0x43,0x44,0x5a,0x5c,0x47 +,0x3e,0xf0,0xb2,0xb1,0x5e,0x45,0x62,0x3f,0x3b,0x6b,0xc9,0xe8,0x79,0xd9,0xbb,0xb9,0xc8,0xce,0x3e,0x28,0x2b,0x42,0xcd,0xb6,0xb0,0xbe,0x4a,0x33,0x4a,0xb9,0xb7,0xea +,0x2f,0x1e,0x21,0xca,0xa5,0xa4,0xbb,0x3f,0x3f,0xe6,0xbc,0xc2,0x4f,0x43,0x68,0xb8,0xa0,0xa3,0xbf,0x3a,0x28,0x25,0x35,0x4a,0x45,0x4f,0x55,0xcc,0xab,0xad,0xd5,0x56 +,0x30,0x2d,0x4e,0xc6,0xc5,0xc5,0xc0,0xcc,0x5a,0xe6,0xb2,0xbb,0x46,0x2c,0x27,0x34,0xc3,0xa9,0xaa,0xc9,0x30,0x2e,0x44,0xda,0xc5,0x3e,0x23,0x2a,0x6a,0xa5,0x9b,0xa8 +,0xd6,0x72,0x4d,0x48,0x55,0x34,0x35,0x3a,0x37,0x47,0xb5,0xa9,0xac,0xb9,0x3d,0x35,0x4c,0xcf,0xc1,0xc4,0xdb,0xcf,0xcd,0xe9,0x64,0x40,0x30,0x23,0x23,0x5d,0xa9,0xa2 +,0xa8,0x73,0x3e,0xb3,0xa7,0xbf,0x48,0x27,0x20,0x3a,0xbe,0xb3,0xc1,0x3f,0x3a,0xca,0xbe,0xd1,0x34,0x21,0x2b,0xc4,0xa6,0xa8,0xbd,0x6e,0x6f,0x5d,0x4a,0x3d,0x2e,0x37 +,0x5a,0xe3,0xb9,0xae,0xab,0xa6,0xad,0x61,0x2d,0x1f,0x28,0xcd,0xb8,0xce,0x41,0x31,0xca,0xa2,0xa9,0xf9,0x25,0x1c,0x2d,0xae,0xa0,0x9f,0xae,0x42,0x3e,0xcf,0xd1,0x38 +,0x26,0x2b,0x4c,0xbb,0xab,0xbf,0xf9,0xc8,0xba,0xbf,0x57,0x29,0x23,0x2d,0x33,0xc9,0xa8,0xab,0xb9,0xc7,0x60,0x3b,0x43,0x3c,0x3b,0x60,0xcf,0xc6,0xc5,0xb2,0xa7,0xac +,0x4e,0x1f,0x17,0x1f,0xc1,0xa2,0xa4,0xb4,0xf4,0x68,0xb6,0xa4,0xb3,0x2d,0x1b,0x22,0x57,0xb5,0xb2,0xc8,0x66,0xc9,0xb1,0xbc,0x3a,0x24,0x2e,0xc6,0xb0,0xaa,0xad,0x5c +,0x3c,0x7e,0xc2,0xc9,0x34,0x20,0x29,0x61,0xc2,0xc0,0xbf,0xaf,0xab,0xaf,0x7e,0x2d,0x26,0x33,0xd3,0x68,0x39,0x2d,0x48,0xac,0xa1,0xa2,0xc6,0x1f,0x19,0x3b,0xa2,0x9c +,0xad,0x39,0x2b,0x49,0xb1,0xbc,0x2b,0x1d,0x27,0x71,0xb5,0xb1,0xaf,0xaf,0xaa,0xa8,0xad,0xe8,0x26,0x1f,0x32,0xc3,0xbd,0x76,0x41,0x3f,0xd3,0xb4,0xc5,0x3d,0x2c,0x33 +,0xd7,0xc5,0xc9,0xc3,0xb7,0xb5,0xb6,0xc0,0x3c,0x25,0x2a,0xbf,0xaf,0x5d,0x29,0x26,0xcf,0x9f,0xa0,0xbf,0x29,0x1b,0x24,0xc5,0xa8,0xad,0xc8,0x76,0xcd,0xb4,0xae,0xdf +,0x24,0x20,0x4c,0xa9,0xab,0x70,0x40,0xcb,0xb0,0xb2,0x62,0x22,0x1d,0x2f,0xd8,0xbd,0xb3,0xb3,0xae,0xaf,0xad,0xaa,0xd5,0x26,0x1f,0x2f,0x4b,0x48,0x32,0x3d,0xae,0x9e +,0xa1,0xde,0x21,0x1d,0x41,0xa8,0xa7,0xdf,0x2f,0x36,0xc7,0xaa,0xa6,0xcf,0x1e,0x1a,0x2c,0xc0,0xad,0xbb,0xcc,0xb8,0xae,0xa8,0xb2,0x2c,0x1a,0x24,0xef,0xb3,0xbc,0x61 +,0xc8,0xb1,0xa8,0xa7,0x59,0x1f,0x20,0x4f,0xbc,0xbe,0xe6,0xdf,0xbe,0xc2,0xbc,0xcf,0x30,0x26,0x33,0xea,0xbd,0xde,0x48,0xc9,0xa7,0x9c,0x9f,0x50,0x1b,0x1d,0x3e,0xb9 +,0x7e,0x28,0x2f,0xd6,0xae,0xa5,0xb2,0x36,0x29,0x37,0xdc,0xb2,0xba,0xf6,0xe6,0xd1,0xaf,0xa9,0x3f,0x1a,0x18,0x30,0xb9,0xb3,0xda,0xc6,0xac,0xa7,0x9f,0xaa,0x3e,0x26 +,0x2d,0x49,0x4b,0x3b,0x4f,0xb3,0xb3,0xb0,0xb3,0x36,0x1e,0x26,0xc6,0xae,0x77,0x2b,0x36,0xc2,0xa1,0x9a,0xaa,0x2e,0x1e,0x2b,0xd8,0xb6,0x68,0x3f,0x5c,0xcc,0xba,0xc3 +,0x5a,0x39,0x3d,0x5d,0x56,0x45,0x4e,0xc6,0xca,0x35,0x32,0x6b,0xbc,0xab,0xad,0x61,0x3f,0xc3,0xab,0xa6,0x4e,0x1a,0x1b,0x30,0xaf,0x9e,0xae,0x3d,0x57,0xb0,0xa8,0xb9 +,0x1f,0x15,0x28,0xce,0xad,0xad,0x3e,0x3d,0xa4,0x9a,0xa3,0x33,0x12,0x1e,0xad,0x9e,0xa6,0x2c,0x19,0x4f,0x9c,0x9c,0xe7,0x12,0x11,0x4e,0xa1,0x9d,0xbb,0x24,0x3e,0x9d +,0x98,0xa9,0x20,0x11,0x27,0xa9,0x9e,0xb7,0x1f,0x1c,0xb2,0x96,0x9c,0x3e,0x12,0x1b,0xac,0x9c,0xa5,0x35,0x1a,0x3c,0x9f,0x9e,0xbc,0x1d,0x19,0xc5,0x9f,0xac,0x3b,0x1a +,0x31,0x99,0x94,0xaa,0x1f,0x10,0x25,0xa8,0xa4,0xd0,0x22,0x1e,0xb0,0x97,0x9d,0x68,0x1a,0x1e,0xa9,0x9e,0xc4,0x2a,0x1d,0x6b,0x98,0x9d,0x4b,0x1a,0x17,0xd4,0x9c,0xb0 +,0x36,0x1f,0x2e,0x9e,0x96,0xac,0x35,0x1b,0x28,0xad,0xc0,0x2e,0x25,0x2a,0xa9,0x96,0xab,0x38,0x20,0x26,0xa7,0x9e,0x59,0x2a,0x1f,0x36,0x9e,0x9d,0xc8,0x30,0x1f,0x45 +,0xa1,0xc4,0x2f,0x28,0x2d,0xa4,0x98,0xb1,0x36,0x1e,0x20,0xaf,0xac,0x2f,0x22,0x20,0xbf,0x92,0x97,0xb9,0x28,0x19,0x47,0x9d,0xb2,0x3a,0x24,0x24,0xaa,0x9d,0xd1,0x28 +,0x1b,0x2e,0x9e,0xa6,0x2d,0x1e,0x23,0xa8,0x8d,0x96,0xfb,0x1c,0x16,0xcc,0x9c,0xee,0x1d,0x18,0x2e,0x97,0x93,0xc2,0x22,0x1b,0x47,0x98,0xa6,0x26,0x1c,0x29,0x9e,0x8e +,0xab,0x1d,0x12,0x1c,0xa0,0x98,0x4e,0x1e,0x24,0xad,0x94,0x9f,0x2e,0x1d,0x33,0xb6,0xbf,0x30,0x29,0xc9,0x98,0xa0,0x2d,0x19,0x1b,0xdb,0x9b,0xab,0x35,0x2b,0x4b,0x9b +,0x97,0xba,0x25,0x18,0x21,0xb2,0xaf,0x32,0x29,0x3d,0x9e,0x91,0xa9,0x27,0x1a,0x21,0xb0,0xa2,0x33,0x1a,0x22,0xb1,0x8e,0x93,0x34,0x15,0x17,0xe0,0x97,0xa8,0x27,0x21 +,0x3f,0x9e,0x99,0x5c,0x1e,0x24,0x4d,0xa7,0xb9,0x1d,0x1a,0x49,0x9c,0x90,0xa4,0x23,0x1e,0x33,0xaf,0xa4,0x3b,0x18,0x26,0xa9,0x93,0x98,0x2d,0x17,0x26,0xc0,0xa7,0xe1 +,0x18,0x1c,0xb3,0x94,0x91,0xbf,0x15,0x1b,0xbe,0x9c,0xa1,0x22,0x0f,0x26,0x9f,0x8f,0x9a,0x22,0x15,0x2f,0xad,0xa7,0x41,0x18,0x28,0x9e,0x91,0x9a,0x2c,0x10,0x1f,0xae +,0x9f,0xb6,0x1c,0x14,0xdf,0x95,0x93,0xae,0x1a,0x19,0xc1,0x9f,0xaf,0x2b,0x16,0x2a,0x9d,0x96,0xa1,0x2c,0x16,0x2e,0xa7,0xa8,0x3e,0x18,0x1a,0xab,0x8e,0x90,0xb5,0x18 +,0x16,0x4a,0xa7,0xb3,0x2d,0x18,0x2b,0x9f,0x97,0xa3,0x2e,0x1a,0x3a,0xa3,0xa6,0x5f,0x1e,0x1f,0xab,0x94,0x9a,0x69,0x15,0x15,0x47,0xa7,0xad,0x2d,0x18,0x2f,0x9b,0x90 +,0x9b,0x36,0x16,0x20,0xbb,0xa6,0xc5,0x1f,0x1e,0xb3,0x94,0x99,0x48,0x11,0x17,0xb3,0x97,0xa3,0x21,0x10,0x25,0x9a,0x8d,0x98,0x24,0x0e,0x1c,0xae,0x9b,0xb0,0x1f,0x1d +,0xb5,0x92,0x96,0x46,0x13,0x17,0xcf,0x9d,0xa9,0x22,0x15,0x37,0x96,0x8c,0x9f,0x19,0x0c,0x1e,0x9f,0x94,0xaf,0x19,0x18,0xba,0x92,0x93,0x6f,0x13,0x16,0xf7,0xa0,0xaf +,0x1f,0x18,0xc6,0x91,0x8e,0xb2,0x12,0x0e,0x2f,0x99,0x94,0xc9,0x15,0x16,0xb6,0x8f,0x91,0x67,0x11,0x16,0x51,0xa1,0xac,0x27,0x1c,0xe4,0x97,0x91,0xab,0x18,0x11,0x2d +,0x9f,0x9b,0x51,0x15,0x1e,0xa2,0x8d,0x91,0x2e,0x0c,0x10,0x49,0x97,0x99,0x35,0x19,0x2c,0xa3,0x93,0xa5,0x1e,0x16,0x2c,0xa5,0x9b,0x5f,0x18,0x1e,0xa6,0x8d,0x91,0x2e +,0x0b,0x0e,0x44,0x94,0x96,0x37,0x17,0x24,0x9f,0x8e,0x9d,0x1f,0x0f,0x1d,0xa9,0x95,0xb2,0x1e,0x1e,0xb6,0x93,0x9a,0x24,0x0d,0x14,0xb8,0x8f,0x9b,0x21,0x12,0x28,0x94 +,0x89,0x9d,0x16,0x0a,0x16,0xa4,0x90,0xaa,0x23,0x1d,0xbd,0x93,0x9d,0x1f,0x0d,0x15,0xab,0x8d,0x9a,0x21,0x11,0x29,0x92,0x8a,0xac,0x12,0x0a,0x1b,0x9a,0x8e,0xac,0x1a +,0x15,0xbf,0x8e,0x97,0x2a,0x0e,0x12,0xc3,0x93,0x9f,0x2b,0x1a,0x45,0x92,0x8e,0xeb,0x0e,0x0a,0x29,0x8f,0x8d,0xb9,0x14,0x11,0xbf,0x8e,0x94,0x2f,0x0d,0x0e,0xd1,0x91 +,0x98,0x39,0x19,0x32,0x94,0x8e,0xcc,0x0f,0x0a,0x25,0x93,0x8d,0xac,0x16,0x12,0xba,0x8d,0x94,0x29,0x0a,0x0d,0xae,0x8b,0x91,0x3c,0x11,0x21,0x9a,0x90,0xb2,0x14,0x0c +,0x2c,0x93,0x8f,0xe0,0x10,0x16,0x9f,0x89,0x96,0x1a,0x05,0x0e,0x9e,0x88,0x91,0x25,0x0c,0x24,0x92,0x8d,0xc4,0x0c,0x09,0x48,0x8b,0x8d,0x6c,0x0e,0x14,0x9d,0x8a,0x9a +,0x13,0x04,0x12,0x97,0x87,0x98,0x19,0x0c,0x46,0x8d,0x8c,0x4f,0x09,0x07,0x43,0x8b,0x8b,0xda,0x0f,0x18,0x9e,0x8e,0xab,0x10,0x08,0x26,0x8c,0x88,0xa5,0x10,0x0c,0xd6 +,0x8b,0x8e,0x2a,0x07,0x0a,0xb5,0x89,0x8f,0x2d,0x0d,0x1f,0x95,0x8c,0xad,0x0d,0x06,0x2a,0x8b,0x87,0xa5,0x0f,0x0d,0xc0,0x8c,0x92,0x1e,0x05,0x0d,0x9f,0x87,0x8e,0x29 +,0x0a,0x1a,0x99,0x8b,0xa4,0x0f,0x09,0x2c,0x8f,0x8b,0xae,0x11,0x13,0xab,0x8e,0x9a,0x19,0x05,0x11,0x99,0x86,0x8f,0x1e,0x0a,0x1f,0x99,0x8e,0xb6,0x0c,0x0b,0xcc,0x8b +,0x89,0xbd,0x0b,0x0f,0xaf,0x8c,0x95,0x19,0x05,0x14,0x9a,0x87,0x93,0x1b,0x0c,0x2d,0x93,0x8b,0xc5,0x08,0x08,0x58,0x8a,0x86,0xb2,0x0b,0x0e,0xcc,0x90,0x9a,0x16,0x08 +,0x1f,0x94,0x87,0x96,0x15,0x0b,0x2a,0x94,0x8c,0xff,0x08,0x0c,0xba,0x8b,0x8a,0x4e,0x0c,0x19,0xaa,0x8f,0xa1,0x0e,0x07,0x24,0x8f,0x85,0x97,0x14,0x0d,0x2e,0x99,0x91 +,0x2e,0x08,0x12,0xa3,0x88,0x8b,0x2f,0x0b,0x1a,0xa6,0x8e,0xa3,0x0d,0x09,0x28,0x93,0x88,0x9c,0x15,0x11,0x48,0x95,0x93,0x22,0x08,0x14,0x9f,0x88,0x8b,0x2f,0x0c,0x18 +,0xb9,0x94,0xb5,0x0d,0x0c,0x51,0x8d,0x87,0xa0,0x10,0x11,0x7d,0x92,0x94,0x1d,0x07,0x14,0xa1,0x88,0x8c,0x27,0x0c,0x1d,0xa3,0x8f,0xbc,0x0b,0x0a,0x50,0x8c,0x85,0x9f +,0x0f,0x10,0x44,0x96,0x99,0x1a,0x08,0x1b,0x99,0x86,0x8e,0x1b,0x0a,0x1d,0x9f,0x8e,0xbb,0x0a,0x0c,0x60,0x8d,0x87,0xaa,0x0f,0x15,0xd5,0x94,0x9b,0x13,0x08,0x1f,0x96 +,0x85,0x8e,0x1b,0x0c,0x1e,0xa5,0x90,0x47,0x09,0x0e,0xca,0x8b,0x87,0xb6,0x0f,0x18,0xc5,0x93,0x9a,0x16,0x0a,0x1d,0xa0,0x89,0x95,0x1a,0x0f,0x26,0x9f,0x92,0x35,0x0b +,0x13,0xb5,0x8a,0x87,0xba,0x12,0x15,0x37,0x9a,0xa1,0x17,0x0e,0x22,0x9d,0x88,0x98,0x1c,0x14,0x27,0xa2,0x98,0x2b,0x0d,0x16,0xc2,0x8b,0x89,0xbc,0x18,0x19,0x46,0x98 +,0xaa,0x15,0x0e,0x1d,0x9c,0x88,0x98,0x22,0x17,0x20,0xa9,0x9b,0x2e,0x13,0x1a,0xb7,0x8b,0x8d,0x46,0x16,0x19,0xcb,0x95,0xb3,0x15,0x0e,0x1e,0x99,0x89,0x9b,0x25,0x18 +,0x25,0xa2,0xa0,0x22,0x13,0x1c,0xa9,0x8a,0x90,0x3a,0x1b,0x1d,0xbf,0x9c,0x37,0x10,0x11,0x2d,0x91,0x8b,0xa6,0x28,0x1e,0x3e,0x9b,0xa9,0x1b,0x13,0x1c,0xab,0x8e,0x9f +,0x34,0x2d,0x37,0xa9,0xa7,0x1f,0x12,0x1a,0xd6,0x8e,0x8f,0xdf,0x25,0x1f,0x41,0x9f,0xcf,0x1b,0x1b,0x27,0xa4,0x8f,0xa5,0x45,0x3d,0x39,0xab,0xb7,0x1b,0x18,0x20,0xe2 +,0x93,0x98,0x74,0x39,0x2d,0xcd,0x9f,0x38,0x16,0x1a,0x2a,0x9e,0x8f,0xa5,0x7e,0x4d,0x39,0xb3,0xcd,0x1b,0x1b,0x22,0xfe,0x96,0x9f,0x40,0x39,0x3b,0xa9,0x9a,0x3a,0x16 +,0x18,0x2a,0x9b,0x90,0xb1,0x3a,0x38,0x4b,0xad,0x5c,0x1a,0x1a,0x21,0xb8,0x93,0x9d,0x5e,0x43,0xec,0xa4,0xa8,0x1f,0x12,0x1a,0x69,0x95,0x97,0xff,0x2e,0x3e,0xb0,0x9f +,0x52,0x16,0x14,0x21,0xae,0x96,0xa7,0x5f,0xc3,0xaa,0x9f,0xc1,0x17,0x11,0x20,0xb9,0x96,0x9e,0x3d,0x2f,0x4a,0xab,0xa0,0x3a,0x17,0x1a,0x2d,0xa8,0x99,0xb4,0x54,0xbf +,0xae,0xa5,0x5f,0x19,0x17,0x23,0xd1,0x9c,0xa7,0x41,0xe6,0xad,0x9f,0xaf,0x1f,0x14,0x1b,0x32,0xa0,0x97,0xad,0xcf,0x77,0xc6,0xab,0x4d,0x1c,0x1b,0x27,0xc3,0x9f,0xb9 +,0x53,0xbc,0xad,0x9f,0xad,0x25,0x18,0x1a,0x2b,0xa3,0x9b,0xb5,0xfd,0xfe,0xb0,0xa9,0x36,0x1a,0x1e,0x2a,0xc5,0x9e,0xab,0xc8,0xbb,0xba,0xab,0xc5,0x1d,0x19,0x26,0x67 +,0x9f,0xa5,0x3d,0x5d,0xb0,0xa4,0xa6,0x30,0x18,0x1c,0x26,0xcd,0x9e,0xaf,0xd8,0xab,0xa5,0xa6,0x5f,0x15,0x16,0x2e,0xd1,0xa3,0xaa,0x44,0xc0,0xa5,0xa7,0xad,0x28,0x15 +,0x1f,0x3d,0xb4,0xa5,0x6b,0x3f,0xa9,0xa4,0xaa,0x4e,0x1c,0x22,0x39,0x44,0xb0,0xac,0x55,0xb7,0xa0,0xa6,0xc4,0x1c,0x13,0x28,0x5a,0xbf,0xa7,0xbd,0xdf,0xa7,0xa6,0xa9 +,0x79,0x1d,0x1f,0x30,0x3b,0xbf,0xc8,0x3d,0xac,0x9c,0xa6,0xc5,0x20,0x1b,0x31,0x41,0xd3,0xab,0xcf,0xe1,0xa7,0xa8,0xac,0x43,0x19,0x1d,0x31,0x47,0xb3,0xb4,0xee,0xa8 +,0xa3,0xb5,0xcf,0x25,0x1f,0x44,0x47,0xf9,0xb0,0x46,0x5b,0xa5,0xa9,0xae,0x3d,0x19,0x26,0x45,0x43,0xaf,0xb2,0x6a,0xac,0xa7,0xbf,0xf4,0x21,0x20,0xf2,0x57,0xec,0xb6 +,0x42,0xda,0xa4,0xb0,0xbc,0x3c,0x1c,0x37,0xc8,0x48,0xb9,0xd6,0x36,0xa9,0xa7,0xd4,0xd4,0x27,0x2a,0xbb,0x43,0x49,0xbd,0x3a,0xc1,0xa1,0xce,0x4c,0x2e,0x1d,0x7c,0xb4 +,0x4e,0xaf,0xbd,0xe4,0x9e,0xa6,0xd5,0xd1,0x27,0x2a,0xbf,0x2e,0x2e,0x6b,0x2d,0xc6,0xa5,0x4d,0x43,0x2f,0x1e,0xf6,0xcd,0x33,0xbc,0xcc,0xd0,0x9d,0xa8,0xc4,0xba,0x2b +,0x39,0xab,0x59,0xcc,0xac,0x45,0xb1,0xa1,0x66,0xf4,0x36,0x1e,0x68,0x41,0x24,0xdb,0x3e,0x3a,0xa4,0xbf,0x3b,0x3f,0x1a,0x25,0xc0,0x35,0xdd,0xb3,0x3f,0xa7,0x9e,0x4d +,0xdd,0x39,0x27,0xb1,0xc4,0x43,0xa6,0xbd,0xbd,0x9a,0xba,0x3c,0x4f,0x1f,0x38,0xaf,0x2d,0x45,0xc3,0x32,0xa8,0xa4,0x36,0xd7,0x32,0x20,0xb4,0xff,0x2f,0xad,0xda,0xbe +,0x9d,0x3c,0x27,0x3a,0x1e,0x44,0xaf,0x2d,0xca,0xae,0x49,0xa1,0xa6,0x36,0xdb,0x2f,0x29,0xb0,0x35,0x24,0xbb,0x47,0xd4,0xa2,0x36,0x2f,0x4e,0x22,0xd6,0xa9,0x38,0xb5 +,0xac,0x67,0x9d,0xa8,0x2f,0xcb,0x37,0x38,0xa2,0xf7,0x3b,0xad,0x3c,0xd1,0xa5,0x2f,0x35,0x4e,0x20,0xcf,0xb7,0x27,0xd7,0xd0,0x39,0xa1,0xb8,0x2a,0xc9,0x2b,0x2b,0xa9 +,0x3b,0x33,0xb0,0x37,0xbc,0xa0,0x30,0x42,0x6c,0x27,0xad,0xab,0x2d,0xbe,0xfa,0x34,0xa0,0xbd,0x2b,0xc8,0x2e,0x3b,0xa7,0x2c,0x29,0xbb,0x37,0xae,0x9d,0x33,0x44,0x63 +,0x2a,0xa7,0xa8,0x37,0xab,0xb7,0x4d,0x9f,0x66,0x25,0xc0,0x34,0x4e,0xa3,0x32,0x37,0xb3,0x35,0xb4,0xa4,0x2b,0x42,0x7e,0x28,0xbf,0x53,0x1e,0x67,0x48,0x2f,0xab,0x3e +,0x25,0xca,0x35,0x5c,0xac,0x28,0x31,0xb1,0x45,0xb2,0xad,0x28,0x5e,0xbd,0x53,0xa5,0xbe,0x2c,0xbd,0xdc,0x78,0xa5,0x69,0x35,0xb8,0x50,0xca,0xae,0x31,0x46,0xb2,0xea +,0xa9,0xa7,0x3a,0x7c,0xcf,0x60,0xa7,0xc4,0x31,0xc2,0x6a,0x64,0xaf,0x3b,0x2e,0x6b,0x3c,0xc7,0xbb,0x29,0x2f,0x4e,0x3b,0xb8,0xbf,0x2b,0x3b,0x4b,0x4c,0xbe,0x33,0x23 +,0x3f,0x3d,0x64,0xb5,0x31,0x26,0x43,0x66,0xab,0xaa,0x36,0x45,0xc7,0xff,0xaf,0xbb,0x37,0xf0,0xbf,0xb2,0xa5,0xe5,0x35,0xc6,0xbd,0xb0,0xad,0x47,0x3c,0xce,0xc4,0xaf +,0xbc,0x3b,0xd5,0xb5,0xba,0xae,0xca,0x37,0x55,0xbe,0xb1,0xb6,0x34,0x2f,0xe4,0x55,0x45,0x36,0x29,0x32,0xdb,0xb4,0xb9,0x3b,0x25,0x34,0x5e,0xdf,0xf9,0x2f,0x29,0x39 +,0xd8,0xcd,0x44,0x31,0x39,0x60,0x7d,0x54,0x35,0x2e,0x45,0xbe,0xaa,0xb2,0x74,0x5d,0xbd,0xb0,0xb4,0xc5,0x4b,0x62,0xc7,0xad,0xa9,0xdb,0x42,0xcf,0xbe,0xb5,0xbc,0x4e +,0x6d,0xc7,0xb0,0xa5,0xc1,0x38,0x49,0xd7,0xbc,0xb8,0x47,0x2c,0x2f,0x42,0xaf,0xab,0x44,0x39,0x3e,0x3f,0xce,0x4a,0x33,0x33,0x2e,0x5f,0xae,0x51,0x2e,0x49,0x44,0xc9 +,0xbe,0x38,0x2e,0x2c,0x34,0xbb,0xc3,0x32,0x3f,0x44,0x4a,0xb4,0xdc,0x38,0x3b,0x3a,0xb6,0xa6,0xc1,0xe9,0xcb,0xd5,0xae,0xad,0x46,0x42,0x3e,0x6e,0xa3,0xaf,0x3a,0x40 +,0x57,0xbb,0xa4,0xb8,0x47,0x36,0x2d,0xb1,0xa1,0xc9,0xcd,0xc7,0x5d,0xb7,0xb8,0x36,0x2d,0x28,0x3d,0xaa,0xdf,0x37,0x61,0x4d,0xc3,0xb1,0x44,0x2c,0x2c,0x34,0xac,0xac +,0x3d,0x49,0x48,0x3d,0xbc,0xd8,0x2c,0x26,0x25,0x58,0xaa,0x62,0x39,0xdd,0x4f,0xbe,0xaf,0x3f,0x2d,0x2b,0x4e,0xa0,0xa4,0x7b,0x4a,0x3e,0x52,0xa9,0xb3,0x3a,0x2d,0x27 +,0x59,0xaa,0xc8,0xfe,0xc0,0xfd,0xb7,0xa9,0xc9,0x3c,0x34,0x66,0xa3,0xac,0x4b,0xd9,0x49,0x4f,0xac,0xc7,0x2e,0x28,0x2c,0xbf,0xa8,0xd6,0xd4,0xdb,0x2e,0xbc,0xa8,0x56 +,0x38,0x31,0x64,0xae,0x62,0x35,0x58,0x35,0x4b,0xa6,0xc6,0x28,0x21,0x27,0xb9,0xaa,0xcd,0xcd,0x3e,0x2c,0xae,0xa3,0x53,0x3a,0x2f,0x3d,0xb4,0xd1,0x53,0x79,0x2d,0x53 +,0xa4,0xd9,0x2e,0x2f,0x32,0xb7,0xb7,0x4f,0xbf,0x49,0x43,0x9e,0xa5,0x3d,0x2e,0x2b,0x55,0xaa,0xbb,0xbb,0xe1,0x26,0x73,0xa8,0x46,0x30,0x2f,0x39,0xaf,0xb9,0xd4,0xbc +,0x2f,0x40,0x9c,0xa7,0x4b,0x35,0x26,0x77,0xad,0xbd,0xb0,0x3e,0x1f,0xc3,0xa9,0x54,0x3d,0x27,0x2e,0xb3,0xb7,0xac,0xb9,0x26,0x52,0xa3,0xc9,0x48,0x3c,0x2c,0xc6,0xba +,0xde,0xca,0x1f,0x1f,0xa6,0xa6,0xe2,0x38,0x1e,0x30,0xb4,0xb8,0xa3,0xbf,0x20,0xbc,0xa3,0x70,0x58,0x28,0x28,0xb7,0xb8,0xb5,0xc7,0x1a,0x2a,0xa2,0xb9,0xbe,0x46,0x1f +,0x63,0xb4,0xb1,0xa1,0x3c,0x22,0xa6,0xa5,0xbf,0xbe,0x24,0x2d,0xbb,0x58,0xb2,0x76,0x1b,0xc4,0x9f,0x51,0xec,0x2c,0x20,0xaf,0xab,0xa8,0xa5,0x1f,0x26,0x9d,0xb3,0xc5 +,0xd4,0x1c,0x3e,0xba,0x4f,0xab,0x2d,0x19,0xa6,0xa1,0xf3,0xba,0x1f,0x22,0xa9,0xb9,0xa3,0xad,0x19,0x4d,0x9f,0x48,0xc4,0x36,0x18,0xd6,0xbb,0xc7,0xa7,0x1c,0x1b,0xa1 +,0xb8,0xbf,0xac,0x21,0x3d,0xa8,0xed,0xa6,0x4d,0x15,0xac,0x9e,0xdc,0xaf,0x1f,0x19,0xb3,0xd6,0xb1,0xa7,0x16,0x27,0x9e,0xda,0xad,0xbb,0x1b,0xdd,0xa9,0xb4,0x9b,0x2a +,0x17,0xa2,0xad,0xba,0xa1,0x1c,0x1e,0xae,0x47,0xaa,0xbf,0x10,0x59,0x9f,0xe8,0x9d,0x4f,0x1a,0xb0,0xc2,0xb4,0x9d,0x1b,0x25,0x9e,0x52,0xae,0xb1,0x14,0x37,0xae,0x54 +,0x9f,0x27,0x0f,0xae,0xac,0xac,0x97,0x22,0x1e,0xa9,0x74,0xa4,0xaf,0x12,0x3c,0xac,0x3e,0x9f,0x4f,0x13,0xd3,0xdd,0xca,0x9a,0x1d,0x1d,0xa1,0xdb,0xa4,0x9c,0x1c,0x37 +,0xaf,0x44,0x9a,0x59,0x11,0xb9,0xc3,0x48,0x9b,0x25,0x1a,0xaa,0x7b,0xb0,0xaa,0x13,0x30,0x9f,0xea,0x97,0xae,0x14,0xc6,0xb1,0xc4,0x97,0x28,0x16,0xac,0x43,0xbf,0x9f +,0x18,0x24,0xaf,0x4d,0x9c,0xc0,0x13,0xcd,0xb1,0xe6,0x96,0x3f,0x1a,0xab,0x66,0xba,0x9f,0x19,0x26,0xa9,0x31,0xab,0xb4,0x16,0x4b,0xbd,0x48,0x9e,0x34,0x1e,0xa4,0xc4 +,0xb6,0x9b,0x1e,0x1d,0xb1,0x41,0xa2,0xab,0x14,0x35,0xe0,0x31,0x9d,0xce,0x1a,0xbf,0xc9,0xb9,0x9c,0x25,0x26,0xa6,0x4b,0xa2,0x9b,0x1d,0x2f,0xe1,0x30,0xa1,0xd4,0x19 +,0xc7,0x4d,0x44,0x9b,0x2d,0x20,0xb3,0x4a,0xaa,0x9f,0x1f,0x3e,0xac,0x3f,0x9e,0xb1,0x1c,0xc3,0xb8,0xe8,0xa6,0x21,0x18,0xc9,0x46,0xb1,0x9f,0x26,0x30,0xbe,0x3a,0xa3 +,0xae,0x21,0xbf,0xb9,0x49,0xa1,0x5e,0x1e,0xcc,0x49,0xd8,0xa9,0x1f,0x22,0xcc,0x2f,0xb1,0xa6,0x2e,0xb7,0xa7,0xdc,0xa7,0x48,0x1b,0xef,0xda,0x54,0xa7,0x3a,0x2e,0xac +,0x4a,0x40,0xdc,0x21,0x43,0xad,0x42,0xb4,0xcc,0x23,0xac,0xa0,0xbf,0xa5,0x40,0x1f,0xbb,0x40,0x33,0xac,0x3a,0x44,0xa5,0x3f,0x3d,0x76,0x1d,0x41,0xae,0x35,0xbc,0xad +,0x4c,0xa1,0xab,0x2e,0xb7,0x3d,0x29,0xab,0x3d,0x2c,0xb7,0x2c,0x42,0xa6,0x3a,0xcc,0xaf,0x27,0x54,0xe3,0x27,0xb5,0xba,0x4d,0x9d,0xab,0x40,0xb6,0x2d,0x26,0xb7,0x2b +,0x35,0xb0,0x2b,0xec,0xaa,0x31,0xbc,0xb3,0x2f,0xb4,0x60,0x26,0xb9,0x6d,0x3f,0x9e,0xb1,0x49,0xae,0x2e,0x2b,0xd4,0x25,0x43,0xad,0x38,0xb9,0xac,0x28,0x4d,0xe2,0x29 +,0xb4,0x71,0x26,0xa4,0x96,0x9e,0xaa,0x39,0x1c,0xe4,0xd6,0x24,0x45,0xb6,0xaa,0x9d,0x4f,0x1b,0x1e,0x19,0x2f,0xbd,0xcf,0x37,0x3f,0xac,0xa7,0xa2,0xa3,0x94,0x99,0x2c +,0x19,0x11,0x26,0xa5,0xa2,0x36,0x12,0x0e,0x39,0x99,0x8b,0x8c,0x2b,0x0e,0x1a,0x3d,0xd1,0x9b,0x99,0x8f,0x8d,0xe2,0x0d,0x07,0x07,0x1c,0xa8,0xd5,0x20,0xaf,0x90,0x98 +,0x8b,0xb7,0x13,0x0a,0x0d,0x32,0xa2,0x87,0x84,0x8e,0xa0,0xae,0xaa,0xb3,0x16,0x09,0x03,0x03,0x19,0x69,0x2e,0x77,0x88,0x85,0xa6,0x13,0x0a,0x19,0x65,0xa4,0x8b,0x86 +,0x8e,0x9e,0x9c,0x9e,0x1f,0x0a,0x01,0x0b,0x2c,0xa3,0x90,0x99,0xae,0x28,0x1a,0x26,0x39,0x1e,0x1d,0xdd,0x89,0x89,0xaf,0x2c,0xb6,0x94,0x99,0x54,0x06,0x02,0x05,0x4e +,0x85,0x80,0x93,0x15,0x23,0x9d,0xa8,0x1e,0x0c,0x1d,0xa2,0x38,0xd5,0xc2,0x3e,0xb3,0x93,0x92,0x2b,0x0e,0x0f,0x21,0xae,0x92,0xba,0x10,0x0f,0xaa,0x98,0x97,0x91,0x9f +,0xd9,0x13,0x2e,0x8f,0x89,0x9c,0x42,0x1c,0x0d,0x0d,0x05,0x07,0x27,0x9b,0x92,0xb5,0x17,0x28,0xac,0x8b,0x83,0x8a,0xa7,0x26,0x20,0x29,0x75,0x1a,0x16,0xa9,0x90,0x9e +,0xd3,0xdc,0x30,0x14,0x11,0x1b,0xe0,0x53,0x21,0xb0,0x8a,0x84,0x9a,0x1e,0x10,0x0f,0x18,0x45,0x2a,0x18,0x19,0x47,0x8f,0x88,0x98,0x1a,0x10,0x28,0xa1,0xbe,0x24,0x9f +,0x85,0x85,0xa4,0x1c,0x0b,0x0a,0x0b,0x16,0xc3,0x4c,0x2a,0xb0,0x90,0x8c,0x9c,0x19,0x0c,0x16,0x1f,0x3d,0x92,0x87,0x89,0x8d,0x8d,0x8f,0x63,0x10,0x0a,0x0b,0x0c,0x05 +,0x06,0x12,0x8f,0x81,0x84,0xa1,0x0b,0x0c,0x1c,0xae,0x96,0x8a,0x8d,0x95,0xa4,0x58,0x38,0x0f,0x0e,0x0f,0x0a,0x0b,0x3d,0x95,0x8c,0x92,0x9e,0xa2,0x4f,0x18,0x0d,0x1a +,0x2c,0x9d,0x8e,0x94,0xa1,0xa6,0x99,0xbd,0x41,0x1b,0x0a,0x0a,0x19,0xb1,0x93,0x97,0xaf,0x9f,0x8f,0xaa,0x1c,0x30,0x5d,0x37,0x33,0x42,0x27,0x16,0x1a,0x24,0x9c,0x90 +,0xa4,0x30,0x1d,0x21,0x3a,0xa8,0xc3,0x6d,0xa4,0x91,0x8e,0xa3,0xbe,0x2d,0x1b,0xf9,0xab,0xbd,0x2a,0x16,0x1e,0x1a,0x13,0x15,0x2d,0xb5,0x42,0x34,0x2b,0x27,0x3b,0x94 +,0x84,0x87,0x8c,0x95,0xa6,0x40,0x18,0x0f,0x1a,0x34,0x2a,0x2a,0xaf,0x9e,0x9a,0x9e,0x2c,0x13,0x10,0x1b,0x17,0x1d,0xb0,0x99,0x8f,0x95,0xa5,0xbc,0x3d,0x1b,0x1a,0x2e +,0x1c,0x16,0xf2,0x93,0x8a,0x8b,0x96,0x4d,0x13,0x10,0x19,0x49,0x96,0x8e,0x91,0xa4,0x22,0x0e,0x0c,0x0f,0x18,0x40,0xb1,0xd9,0x35,0xcc,0xa7,0xa6,0x9e,0xa3,0x33,0x1b +,0x1f,0x40,0xa6,0x93,0x8e,0x8c,0x8d,0xa3,0x2f,0x21,0x19,0x0e,0x0b,0x0e,0x19,0x37,0xa2,0x98,0x9d,0x3f,0x14,0x1b,0xca,0xa4,0xa0,0xa0,0x9c,0x99,0xa4,0x2e,0x16,0x26 +,0xbb,0xd0,0x3b,0x52,0xaf,0xa3,0xa9,0xb7,0xac,0xc1,0x21,0x11,0x12,0x1b,0x30,0xb7,0x9e,0x97,0x97,0x9d,0x5a,0x14,0x0d,0x18,0x3a,0xa6,0x9d,0xa1,0x9e,0xa0,0x57,0x27 +,0x2e,0x46,0xb0,0xa0,0x9d,0xa9,0x56,0x20,0x1a,0x28,0xba,0xd5,0x26,0x24,0x2f,0xbc,0xa9,0xe5,0x3f,0xb8,0xda,0x36,0x46,0x48,0x47,0xbf,0xa3,0x9a,0x97,0x9c,0xad,0xbe +,0x39,0x19,0x0f,0x0d,0x15,0x2b,0xcc,0xa2,0xa4,0x4e,0x23,0x26,0xb5,0x91,0x8e,0x9c,0xad,0xae,0xba,0x2d,0x18,0x1a,0x37,0xcc,0x3a,0x23,0x29,0xbf,0x9d,0x97,0x9b,0xb9 +,0x30,0x1e,0x12,0x16,0x46,0xa2,0x96,0x9a,0xae,0xaa,0xad,0x28,0x0f,0x0e,0x1d,0xd5,0xa2,0xa6,0xa9,0x9e,0xa2,0xd2,0x2b,0x30,0xfd,0xbc,0xb4,0xaa,0x9c,0xa0,0x2e,0x13 +,0x12,0x1c,0x2a,0x28,0x28,0x50,0xa7,0xa2,0xa3,0xa6,0xa8,0xa8,0xb2,0x3c,0x1f,0x1d,0x3e,0x9d,0x91,0x92,0x9a,0xbe,0x22,0x15,0x0f,0x0f,0x17,0x25,0x2b,0x61,0xa2,0x9f +,0xab,0xc3,0xcc,0x9e,0x93,0xa7,0x3c,0x3f,0xba,0xa7,0xb4,0x2b,0x18,0x1b,0x21,0x27,0x32,0x3f,0xb1,0x98,0x9a,0xaa,0xaf,0xba,0x37,0x1d,0x17,0x1d,0x5e,0xa9,0xa8,0xa4 +,0x9c,0xa6,0x38,0x17,0x14,0x28,0xb7,0xb3,0xcc,0xb3,0xa5,0xa9,0xf1,0x28,0x3b,0xa3,0x9c,0xa6,0xb2,0xe8,0x30,0x29,0x20,0x21,0x2c,0x22,0x1e,0x2b,0x72,0xa4,0x9c,0xb1 +,0xd3,0xb1,0xb4,0x6e,0x30,0x27,0x41,0xa0,0x93,0x99,0xa5,0xb4,0xfe,0x3b,0x1d,0x10,0x15,0x1e,0x1f,0x28,0x67,0xb5,0xaf,0xb8,0x47,0xd9,0xa0,0x9f,0x9d,0x9a,0x9d,0xa3 +,0xbc,0x2a,0x1b,0x1d,0x24,0x29,0x23,0x1c,0x2c,0x9f,0x8f,0x95,0xaa,0x3d,0x29,0x26,0x1a,0x17,0x25,0xb8,0x98,0x93,0x96,0x9c,0xbb,0x1e,0x13,0x19,0x23,0x2b,0x36,0x61 +,0xad,0x9b,0x9f,0x64,0x27,0x32,0xbb,0xa4,0xa7,0xc0,0xa9,0xa1,0xc5,0x36,0x21,0x1a,0x1b,0x1c,0x16,0x1d,0x53,0xb3,0x9f,0x94,0x91,0x9c,0xbe,0x27,0x1f,0x4c,0xa7,0xa2 +,0xa9,0xa9,0x9f,0x9a,0xae,0x1b,0x0f,0x10,0x16,0x1f,0x20,0x1f,0x3a,0xac,0xa2,0x9e,0x9c,0x99,0x9d,0xac,0xb9,0xe3,0x3f,0x34,0x39,0x31,0x2c,0x33,0x2f,0x21,0x1f,0x37 +,0xae,0x9e,0xa6,0xc4,0xbf,0xb2,0xda,0x2b,0x23,0x2d,0xc2,0xb0,0x66,0xc4,0xad,0xb1,0xc8,0x71,0x2f,0x29,0xd8,0xb0,0xba,0xee,0x2e,0x1d,0x25,0xc8,0x9e,0x92,0x98,0xad +,0xed,0x68,0xea,0x3b,0x23,0x18,0x1c,0x25,0x20,0x23,0xde,0x9d,0x9c,0xa5,0xd2,0x33,0x2c,0x34,0x4a,0xbc,0xa6,0xa4,0x9c,0x9f,0xab,0xb1,0xda,0x2b,0x1b,0x16,0x1e,0x32 +,0x31,0x31,0x5b,0xb7,0xb3,0x40,0x1f,0x29,0xb2,0x9a,0x94,0x97,0xaa,0xb0,0xaa,0xb4,0x43,0x23,0x1a,0x12,0x14,0x1f,0xbe,0x97,0x8e,0x94,0xae,0x3b,0x22,0x1d,0x18,0x18 +,0x2a,0xaf,0xa2,0xa4,0x9c,0x9e,0xb0,0xe2,0x2a,0x1d,0x1f,0x2d,0x42,0xf6,0xe5,0xb5,0xac,0xd5,0x41,0x38,0xdd,0xaf,0xaf,0xbb,0xad,0xa4,0xb1,0xb8,0xdd,0x37,0x1c,0x0d +,0x0b,0x18,0x4d,0xa8,0x9d,0xa4,0xa3,0x9f,0xa3,0xac,0xce,0xcf,0xc5,0x61,0x4f,0xba,0xa7,0x9e,0xa1,0x3f,0x1c,0x1a,0x18,0x18,0x1d,0x26,0x40,0xc6,0xe6,0xac,0x98,0x95 +,0x9a,0xb6,0x2f,0x2f,0xd0,0xae,0xb3,0x5a,0x36,0x46,0x3f,0x30,0x23,0x1f,0x38,0xad,0xa9,0xc0,0xe4,0x44,0xe1,0xbf,0xad,0xa4,0xee,0x23,0x1c,0x25,0x63,0xad,0xaf,0xb7 +,0xbe,0xff,0xcc,0xca,0x36,0x2d,0x2f,0x2b,0x31,0x4b,0xc1,0xa0,0x96,0x98,0x9e,0xb6,0x35,0x27,0x25,0x27,0x26,0x1f,0x1f,0x2d,0xe6,0xac,0xb7,0x48,0x39,0xe5,0xba,0xd1 +,0x53,0xd7,0x9d,0x93,0x94,0x9d,0x6f,0x28,0x2c,0x34,0x2e,0x2a,0x23,0x24,0x2a,0x41,0xb0,0xb2,0x2f,0x1e,0x28,0x6a,0xad,0xa8,0xaf,0xab,0x9e,0x98,0x9a,0xb1,0x28,0x1c +,0x1f,0x20,0x1f,0x25,0x51,0xa2,0x97,0x9e,0xf8,0x2a,0x24,0x2d,0x3f,0x2d,0x25,0x2f,0xb4,0x9c,0x95,0x9a,0xc5,0x26,0x22,0x2c,0x37,0x35,0x25,0x25,0x44,0xac,0x9d,0xa5 +,0x55,0x2b,0x5d,0xaa,0xa6,0xaf,0xc2,0xba,0xac,0xa5,0xb2,0x2e,0x15,0x0f,0x15,0x22,0x31,0x2f,0x37,0xb1,0x99,0x95,0x9e,0xbc,0x4c,0xbe,0xa6,0xb2,0x40,0x32,0xc8,0xa7 +,0xa2,0xb3,0x3d,0x2a,0x23,0x1d,0x19,0x19,0x1b,0x2d,0xb4,0x9d,0x98,0x9e,0xca,0x39,0xb7,0x9d,0x9f,0xd9,0x20,0x1f,0xe0,0xa6,0xae,0x3d,0x22,0x29,0xc3,0xad,0x5e,0x23 +,0x21,0x4d,0xa5,0x9b,0xa4,0xfd,0x23,0x22,0x39,0xe8,0xe6,0x43,0x5d,0xbb,0xae,0xb7,0xc9,0x58,0x42,0x67,0x42,0x20,0x15,0x21,0xa8,0x92,0x92,0xa0,0xbc,0xc6,0xb0,0xaf +,0x67,0x1c,0x0f,0x16,0x2e,0xc1,0xaf,0xbc,0x30,0x29,0x7c,0xab,0xc3,0x2c,0x26,0xbc,0x94,0x90,0x9e,0xe0,0x3e,0xb9,0xa3,0xbc,0x23,0x19,0x28,0x5f,0xea,0x3f,0x2e,0x34 +,0x3b,0x3e,0x4a,0x39,0x21,0x24,0xb7,0x97,0x90,0x96,0xa9,0x70,0xef,0xd6,0x31,0x1b,0x1a,0x3d,0xa9,0xb0,0x41,0x33,0xeb,0xa6,0x9e,0xbd,0x20,0x14,0x19,0xea,0x9a,0x99 +,0xae,0x4e,0x3c,0xc3,0xa6,0xbe,0x1f,0x14,0x1d,0x4a,0xae,0xb8,0x51,0x7c,0xbd,0xab,0xa5,0xb2,0x3c,0x3f,0xae,0xa7,0xae,0xc2,0x56,0x40,0x3d,0x29,0x1e,0x1a,0x17,0x24 +,0xde,0xba,0xba,0xab,0xa3,0xa3,0x9e,0xa4,0x6a,0x27,0x2d,0xb3,0x9e,0xa7,0x5a,0x38,0xec,0xb0,0xbf,0x28,0x15,0x15,0x2a,0xda,0xcd,0x48,0x54,0xb4,0xa8,0xa2,0xa1,0xaf +,0x34,0x29,0x3c,0xc6,0xb5,0xca,0x41,0x5e,0xaf,0xad,0xc6,0x2c,0x1d,0x2d,0xb7,0xb9,0xe6,0xcf,0xcc,0xcc,0xc6,0xd5,0x67,0x3d,0x2c,0x3d,0xba,0xce,0x46,0xbd,0xac,0xb3 +,0xc7,0x30,0x18,0x19,0x43,0xaa,0xa3,0xad,0xbc,0xb7,0xa6,0x9e,0xa2,0xc6,0x23,0x1c,0x24,0x2d,0x2d,0x31,0x39,0x66,0xc1,0xcb,0x5a,0x35,0x30,0x4c,0xb9,0xae,0xab,0xa7 +,0xa5,0xa3,0xa6,0xb3,0xfd,0x27,0x1b,0x2c,0xbc,0xdc,0x2f,0x2f,0x3e,0x6f,0xcd,0xfb,0x36,0x2f,0x3f,0xd9,0xb1,0xa9,0x9f,0x9c,0xb3,0x34,0x39,0x3e,0x27,0x25,0x3d,0xec +,0xe2,0xc8,0xca,0xbb,0xa9,0xac,0xf7,0x2b,0x21,0x2d,0xd0,0xbd,0xbf,0xbd,0xc2,0x4a,0x41,0xcf,0xfd,0x3d,0x3a,0x3b,0x39,0x3b,0x5c,0xbb,0xad,0xac,0xb7,0xc8,0x78,0x6b +,0xc3,0xad,0xaa,0xc2,0x4e,0x3f,0x35,0x2e,0x34,0x2f,0x21,0x23,0x42,0xb0,0xae,0xba,0xbf,0xbd,0x67,0x3f,0xbd,0xab,0xb1,0xcd,0x48,0x3f,0xbf,0xa4,0xac,0x38,0x2d,0x4a +,0x45,0x2c,0x2a,0x3d,0x46,0x36,0x3a,0xce,0xb8,0xc2,0xb8,0xae,0xc0,0xc9,0xb7,0x74,0x3a,0x70,0xbf,0x49,0x29,0x33,0xbf,0xb5,0xc9,0x3f,0x2e,0x49,0xcb,0xfa,0x54,0xf7 +,0xbd,0xb6,0xb5,0xc7,0x45,0x4b,0x42,0x3c,0x6b,0xb9,0xbd,0x3d,0x32,0x4f,0xf1,0x45,0x3c,0x42,0x75,0xd4,0xb4,0xa1,0xa5,0xae,0xab,0xad,0x44,0x26,0x28,0x26,0x24,0x39 +,0xf1,0x51,0x37,0x46,0xb7,0xb1,0xc2,0xbf,0xc9,0x49,0x3e,0xbe,0xa3,0xae,0xed,0x6f,0x42,0x33,0x33,0x2f,0x36,0x65,0xb6,0xb5,0x68,0x39,0x41,0xdd,0x4b,0x33,0x53,0xb4 +,0xbb,0xb7,0xaa,0xbc,0x38,0x36,0xc3,0xbc,0xe0,0x3f,0x25,0x1f,0x38,0xa7,0x9a,0xa7,0x32,0x1d,0x24,0x3c,0xbd,0xa1,0x9f,0xac,0xe2,0xc0,0xaf,0xbe,0xd3,0x57,0x37,0x2a +,0x30,0x58,0x4e,0x38,0x2f,0x30,0x2a,0x25,0x42,0xb8,0xc5,0xe5,0xb5,0xbd,0xed,0xb4,0xa6,0xa8,0xbf,0xcf,0xc8,0x37,0x2e,0x55,0xc3,0xae,0xa8,0xa6,0xb3,0x2d,0x1f,0x27 +,0x3c,0xed,0xb9,0xaf,0x5e,0x26,0x21,0x2f,0x64,0x53,0x67,0xc8,0xdc,0x3b,0x3d,0xd4,0xcb,0xbb,0xa9,0x9e,0xab,0xca,0xb9,0xea,0x38,0x5c,0xb8,0xb8,0xd9,0x4c,0x2f,0x1f +,0x1c,0x28,0x3f,0x54,0x55,0x40,0x3e,0x3e,0xd3,0xa4,0xa6,0xd4,0x5c,0xaf,0x9f,0xa1,0xa9,0xc1,0x37,0x2e,0x52,0xa8,0xa7,0x48,0x25,0x21,0x22,0x27,0x3f,0xd7,0x4c,0x3f +,0xc7,0xc4,0x36,0x2e,0x40,0xcc,0xaf,0xa7,0xad,0x6d,0x36,0x46,0xb7,0xad,0xb1,0xb3,0xd2,0x4a,0x42,0x7a,0xcd,0xc7,0xb3,0xb3,0xe1,0x29,0x21,0x29,0x2e,0x3f,0x48,0x3d +,0x34,0x2b,0x67,0xa8,0xb4,0x4d,0x44,0x5b,0xe2,0xb6,0xa6,0xa9,0xbf,0xc3,0xa6,0xa9,0xcb,0xe9,0x4d,0x3c,0x33,0x32,0x35,0x35,0x2f,0x48,0xb0,0xbd,0x36,0x25,0x21,0x34 +,0xcb,0xa6,0x9e,0xab,0xc0,0xd1,0xc9,0xd1,0xd9,0xc9,0xd5,0x42,0x2d,0x3e,0xef,0x52,0xc5,0xbe,0x42,0x2c,0x2b,0x3b,0x41,0x4e,0xc4,0xb7,0xbd,0xbe,0xab,0xbc,0x35,0x28 +,0x28,0x44,0x7e,0x50,0x7a,0xc4,0xb7,0xb5,0xb5,0xed,0x33,0x3c,0xb9,0xa2,0xab,0xcb,0x5a,0x40,0x68,0xb9,0xae,0xf0,0x22,0x1a,0x24,0x42,0xcc,0xae,0xb5,0xe5,0x74,0xf9 +,0x4a,0x44,0x63,0xc5,0xb6,0xbe,0xb1,0xa6,0xa5,0xae,0x49,0x29,0x2a,0x34,0xe9,0xbf,0x46,0x2b,0x27,0x2e,0x56,0xb3,0xae,0x67,0x25,0x1e,0x45,0xa9,0xa5,0xb3,0x5b,0x50 +,0xcb,0xad,0xab,0x78,0x2b,0x29,0x3f,0xd8,0xb1,0xaa,0xc5,0x34,0x2b,0x3e,0xbf,0xaf,0xcd,0x3d,0x3f,0x51,0xc4,0xac,0xab,0xc7,0x63,0x4f,0x37,0x30,0x43,0xd3,0x4f,0x3c +,0x52,0xbd,0xae,0xaf,0xd5,0x38,0x39,0x56,0xb2,0xad,0xda,0x53,0xf7,0x4a,0x3c,0x7d,0xca,0x51,0x2a,0x29,0x39,0x44,0x4e,0x4a,0x5f,0xc0,0xb8,0xb2,0xb6,0xde,0x3a,0x69 +,0xc1,0x51,0x5f,0xbb,0xb2,0xbe,0x59,0x3f,0x4c,0x4a,0x37,0x28,0x2b,0x61,0xb8,0xab,0xa9,0xc5,0x50,0xee,0xfd,0xec,0xbe,0x72,0x29,0x28,0x56,0xa5,0x9b,0xa8,0x3d,0x2b +,0x2c,0x43,0xb3,0xbb,0x52,0x3e,0xdd,0xb9,0xbd,0xc8,0x69,0x32,0x1f,0x29,0x3d,0xce,0xb3,0xbd,0xbe,0xba,0xb9,0xdb,0x48,0x2f,0x2f,0x3e,0x41,0x40,0x4e,0xbd,0xb6,0xbb +,0xc1,0xbd,0xcf,0x43,0x36,0x2a,0x4b,0xa9,0x9d,0x9d,0xb3,0x29,0x22,0x2d,0x2b,0x36,0x5e,0x52,0x4d,0xd2,0xaf,0xa4,0xa5,0xb5,0x39,0x29,0x2e,0x45,0xc0,0xbe,0xcf,0xc5 +,0xbf,0x5d,0x41,0xc6,0xbc,0x50,0x2e,0x2b,0x38,0xc1,0xab,0xa9,0xaf,0xd5,0x4f,0x3c,0x30,0x2a,0x2a,0x3d,0xcd,0xb8,0xb6,0xb4,0x52,0x33,0x4e,0xb9,0xb3,0x77,0x25,0x1c +,0x47,0xa5,0x9b,0xa5,0x3c,0x22,0x2f,0xca,0xc0,0xe7,0x47,0x41,0xfd,0xa6,0x9d,0xa8,0xc9,0x32,0x20,0x24,0x37,0x5c,0xd2,0xd6,0xcd,0xa9,0xae,0x3e,0x3f,0x5b,0x4b,0x45 +,0x38,0x2f,0x46,0xb3,0xa8,0xb5,0x4f,0xed,0xb5,0xb9,0xfc,0x30,0x26,0x33,0xbf,0xad,0xaf,0xce,0x36,0x2e,0x38,0x51,0x59,0x30,0x25,0x2b,0xb7,0x9a,0x98,0xaa,0xeb,0x39 +,0x31,0x35,0x2c,0x31,0x48,0x41,0x39,0xb9,0xa6,0xa2,0xa2,0xd7,0x28,0x28,0x3b,0xc1,0xae,0xb8,0xbe,0xb9,0x7c,0x59,0xdd,0x3d,0x23,0x1c,0x26,0x56,0xa6,0x9e,0xb0,0x4f +,0xc4,0xa8,0xae,0xde,0x2b,0x1f,0x2b,0xce,0xaf,0xb0,0xcc,0xd8,0xba,0xd6,0x39,0x29,0x1f,0x25,0x50,0xb1,0xa4,0xa4,0xae,0xbb,0xd7,0x2f,0x27,0x23,0x25,0x3e,0xbf,0xb3 +,0xae,0xa6,0xa4,0xa2,0xb6,0x2d,0x19,0x1d,0x4f,0xac,0xab,0xd0,0x37,0x63,0xa8,0xa2,0xb5,0x28,0x15,0x1a,0x63,0x9f,0x97,0x9e,0x58,0x2d,0x57,0xde,0x3f,0x32,0x2b,0x2d +,0x50,0xb0,0xad,0xb0,0xae,0xa8,0xb9,0x2d,0x1d,0x1d,0x2a,0x41,0xba,0xaa,0xae,0xaf,0xae,0xb3,0x46,0x2a,0x23,0x23,0x34,0xdd,0xb6,0xb3,0xaa,0x9f,0x9f,0xc9,0x20,0x13 +,0x17,0x53,0xa0,0x9e,0xaa,0x70,0x51,0xaa,0x9c,0xaa,0x2e,0x15,0x15,0x2b,0xbe,0xa9,0xa9,0xb7,0xcc,0xc5,0xdb,0x35,0x2c,0x39,0xd6,0xd1,0xc0,0xad,0xaf,0xae,0xa9,0xb5 +,0x31,0x1b,0x19,0x27,0x51,0xcb,0xbb,0xbb,0xab,0x9e,0x9b,0xb8,0x25,0x1a,0x1e,0x2f,0x40,0x4f,0x41,0xee,0xa6,0x99,0x9d,0x70,0x19,0x11,0x23,0xaa,0x9b,0x9e,0xbb,0x46 +,0xea,0xac,0xb4,0x2a,0x1b,0x1e,0x2f,0x69,0xb9,0xaa,0xa4,0xa1,0xa2,0xb1,0x38,0x1c,0x1d,0x42,0xc7,0xeb,0x6f,0x6b,0xc6,0xa6,0x9f,0xc1,0x25,0x1c,0x25,0x4b,0xe9,0xc1 +,0xb7,0xab,0xa1,0x9f,0xae,0x2b,0x19,0x1e,0x7d,0xc3,0x3b,0x29,0x2b,0xb4,0x94,0x94,0xb9,0x1b,0x0f,0x1b,0x6e,0xa5,0xa1,0xb0,0xe5,0xcd,0xad,0xab,0x5c,0x21,0x20,0x37 +,0xd1,0xbd,0xba,0xae,0xa0,0xa1,0xbc,0x29,0x17,0x19,0x37,0xb8,0xd1,0xed,0xc3,0xaa,0x9f,0x9b,0x9e,0x4d,0x1a,0x18,0x27,0x37,0x45,0x41,0x6f,0xa5,0x98,0x9b,0xd1,0x1b +,0x19,0x3a,0xb9,0xbe,0x61,0x3a,0x69,0xab,0x9e,0xa7,0x32,0x15,0x17,0x2b,0xd3,0xad,0xb0,0xae,0xa1,0x9f,0xa7,0x6b,0x1e,0x19,0x29,0x59,0xd7,0xe1,0x76,0xad,0x9d,0x9c +,0xa8,0x2b,0x17,0x1e,0x44,0xc2,0xc6,0x63,0xc0,0xa7,0xa3,0xa7,0xef,0x21,0x1c,0x28,0x38,0x39,0x37,0x51,0xa3,0x93,0x8f,0x9c,0x2a,0x12,0x19,0x3d,0xc4,0x48,0x21,0x2d +,0xb4,0x9e,0x9b,0xba,0x23,0x1c,0x28,0x44,0xb9,0xb2,0xb4,0xaa,0xa7,0xa5,0xb5,0x25,0x13,0x19,0x38,0xc7,0x55,0x3a,0xaf,0x97,0x95,0x9a,0xbe,0x22,0x1f,0x28,0x35,0x3a +,0x34,0x4f,0xa7,0x9d,0x9e,0xae,0x29,0x19,0x1f,0x54,0xc9,0x34,0x22,0x5c,0x9d,0x92,0x93,0xbb,0x1d,0x19,0x26,0x49,0xd7,0x45,0x4a,0xb5,0xac,0xac,0xbb,0x3d,0x2a,0x2c +,0x33,0x44,0x63,0xe4,0xb1,0xae,0xe3,0x38,0x2f,0x3e,0xb7,0xbc,0x42,0xe7,0xad,0xa0,0xa1,0x3b,0x1a,0x1e,0x3d,0xaa,0xa4,0x51,0x2e,0xbf,0xa3,0x9e,0xb9,0x19,0x13,0x20 +,0x72,0xa5,0xb2,0x2e,0x63,0x9e,0x99,0x9e,0x34,0x16,0x29,0xb4,0xa9,0xc7,0x1b,0x1d,0xa9,0x98,0xa1,0x2d,0x0d,0x17,0xb2,0x9e,0xa5,0x38,0x22,0xad,0x90,0x97,0xce,0x13 +,0x10,0xd3,0x9b,0xa7,0x2d,0x14,0x27,0x95,0x8f,0xaa,0x19,0x0b,0x23,0x98,0x96,0xb6,0x1c,0x19,0xab,0x8f,0x9c,0x30,0x0f,0x17,0xa7,0x9a,0xbe,0x1d,0x17,0xbc,0x8c,0x90 +,0x4d,0x0f,0x0e,0x5f,0x96,0xa5,0x27,0x16,0x27,0x96,0x8c,0xa8,0x1c,0x0f,0x27,0x96,0x99,0x34,0x17,0x1b,0xa4,0x8c,0x9e,0x1f,0x0e,0x17,0x9f,0x92,0xc5,0x1c,0x19,0xcf +,0x8e,0x8e,0xc9,0x19,0x12,0x35,0x9d,0xc0,0x1e,0x18,0x2b,0x99,0x8e,0xac,0x21,0x1a,0x31,0x9a,0x9d,0x2b,0x19,0x1f,0xb0,0x8f,0x9b,0x3a,0x1e,0x1d,0xba,0x9d,0x43,0x1b +,0x1d,0x5b,0x93,0x92,0xca,0x22,0x19,0x2e,0xa2,0xb8,0x1f,0x1c,0x2d,0x9d,0x8d,0x9d,0x3f,0x1e,0x1c,0xbd,0x9c,0x65,0x20,0x1c,0x33,0x99,0x98,0xde,0x22,0x18,0x31,0x9c +,0xb4,0x1f,0x1a,0x2c,0x96,0x89,0x97,0x3e,0x15,0x14,0xba,0xa0,0x2f,0x16,0x16,0xc9,0x8c,0x90,0x6d,0x1b,0x17,0xca,0x94,0xb0,0x1c,0x16,0x31,0x90,0x8b,0xad,0x19,0x0d +,0x1a,0x9e,0x9b,0x33,0x1b,0x22,0x9d,0x8d,0xa1,0x2c,0x1e,0x23,0xc2,0xb9,0x2d,0x3c,0xad,0x9c,0x9e,0x28,0x14,0x21,0x47,0xb6,0xb5,0x34,0x37,0xaa,0x99,0x92,0xac,0x16 +,0x18,0x38,0xc3,0xc0,0x22,0x1a,0xb4,0x94,0x91,0xa7,0x16,0x13,0x7e,0xa5,0xaa,0x30,0x14,0x33,0x96,0x8d,0x97,0x1f,0x09,0x1a,0xb8,0xa5,0xb7,0x1f,0x29,0x9c,0x93,0x99 +,0xc5,0x15,0x1d,0xbb,0xb9,0xf8,0x1d,0x13,0x79,0x98,0x96,0x9c,0x28,0x16,0x4c,0xa9,0xab,0x59,0x19,0x2d,0x99,0x97,0xa3,0x2e,0x0f,0x1f,0xb2,0xb5,0x5e,0x1b,0x1c,0x9c +,0x8d,0x93,0xad,0x16,0x11,0xda,0xa3,0xad,0x2d,0x11,0x2b,0x99,0x99,0xa3,0x2b,0x13,0x33,0xa7,0xb3,0x4b,0x1e,0x2c,0x96,0x8f,0x9d,0x54,0x12,0x16,0xdd,0xc0,0x6b,0x26 +,0x1b,0xb1,0x92,0x9c,0xac,0x27,0x18,0xed,0xae,0xcf,0x41,0x1f,0x36,0x99,0x9c,0xbb,0x2f,0x16,0x29,0xa7,0xaa,0xc2,0x26,0x1a,0xad,0x8f,0x97,0xac,0x1c,0x0f,0x2d,0xdf +,0xd5,0x5d,0x1f,0x3e,0x99,0x99,0xa0,0x7b,0x17,0x27,0xae,0xae,0xb8,0x26,0x1a,0xb2,0x98,0x9f,0xbb,0x18,0x11,0x3c,0xb4,0xab,0xc4,0x1d,0x37,0x9a,0x95,0x9a,0x58,0x13 +,0x1e,0xcc,0xbb,0xbc,0x23,0x1d,0xa3,0x93,0x9d,0x5a,0x0f,0x10,0xca,0x9c,0x99,0xcd,0x15,0x28,0x9d,0x94,0x9b,0x2b,0x0e,0x1d,0xbb,0xa5,0xab,0x25,0x1e,0xa9,0x97,0x99 +,0xcd,0x11,0x13,0x4c,0xa8,0xa4,0x44,0x19,0x46,0x99,0x93,0x9c,0x21,0x0d,0x1d,0xb3,0x9c,0xa1,0x2a,0x1e,0xbb,0x9f,0x9f,0x60,0x16,0x1d,0xd1,0xab,0xab,0x32,0x1c,0xda +,0x96,0x90,0x9f,0x1d,0x0d,0x1c,0xbc,0x9b,0x9f,0x2d,0x1f,0xcb,0xa0,0x9d,0xcf,0x16,0x17,0x3d,0xa6,0x9e,0xcf,0x23,0x3c,0xa1,0x9a,0xa9,0x21,0x12,0x27,0xab,0x9d,0xb3 +,0x22,0x1f,0xb4,0x97,0x97,0xcd,0x13,0x11,0x2e,0xa8,0x9f,0xc9,0x2d,0x6b,0xa0,0x9d,0xc4,0x1b,0x12,0x33,0x9e,0x97,0xae,0x1e,0x1b,0xc6,0x97,0x97,0x48,0x10,0x12,0x37 +,0x9f,0x9c,0xbe,0x2c,0x3e,0xa3,0x9a,0xaf,0x1d,0x10,0x25,0xab,0x9d,0xaf,0x2c,0x33,0xae,0x9c,0xae,0x1d,0x0e,0x19,0xad,0x93,0x97,0x7e,0x1f,0x31,0xa5,0x9a,0xb9,0x1b +,0x15,0x30,0xa8,0xa2,0xff,0x23,0x36,0xa5,0x97,0xa6,0x1d,0x0d,0x19,0xac,0x91,0x99,0x49,0x22,0x39,0xa6,0x9e,0xf2,0x18,0x15,0x35,0x9e,0x99,0xb6,0x28,0x26,0xce,0xa0 +,0xab,0x29,0x18,0x2a,0xab,0x9f,0xb8,0x2b,0x26,0xd1,0x9a,0x97,0xea,0x13,0x10,0x32,0x9c,0x97,0xb0,0x29,0x25,0xcc,0xa2,0xae,0x24,0x16,0x27,0xa4,0x94,0xa3,0x2d,0x1c +,0x39,0x9d,0x98,0x7a,0x13,0x12,0x42,0x9a,0x98,0xd4,0x1d,0x22,0xb0,0x96,0x9f,0x21,0x0f,0x1c,0xa8,0x94,0x9d,0x3f,0x27,0xf0,0xa6,0xac,0x23,0x11,0x1c,0xad,0x8f,0x98 +,0x33,0x15,0x21,0xa5,0x94,0xaa,0x1a,0x0f,0x29,0x9d,0x95,0xac,0x24,0x24,0xb2,0x96,0xa4,0x1a,0x0c,0x19,0xa1,0x8d,0x97,0x2e,0x17,0x2d,0xa0,0x9a,0x3e,0x0f,0x10,0x7a +,0x90,0x8e,0xad,0x1b,0x1a,0xdd,0x9c,0xa7,0x24,0x14,0x23,0xab,0x9a,0xa7,0x2b,0x22,0xce,0x9a,0x9d,0x27,0x0d,0x15,0xaf,0x8e,0x8e,0xbb,0x1b,0x1d,0xde,0xa3,0xcd,0x18 +,0x13,0x42,0x96,0x8e,0xac,0x19,0x15,0x48,0x96,0x98,0x33,0x11,0x1b,0xad,0x8f,0x95,0x38,0x13,0x1b,0xaa,0x93,0xb0,0x13,0x0d,0x24,0x99,0x8c,0x9b,0x29,0x17,0x29,0xa8 +,0xa3,0x35,0x18,0x22,0xa5,0x8d,0x98,0x25,0x0f,0x1a,0xa8,0x93,0xb2,0x1b,0x15,0x31,0x98,0x92,0xc2,0x19,0x19,0xbb,0x93,0xa0,0x1b,0x0e,0x1d,0x9a,0x89,0x99,0x22,0x0f +,0x1d,0xa0,0x98,0x3f,0x12,0x12,0xc7,0x8b,0x8d,0x47,0x0f,0x0f,0xce,0x8e,0x97,0x2f,0x12,0x18,0xa5,0x8d,0x9f,0x23,0x11,0x25,0x99,0x98,0x2c,0x11,0x11,0xce,0x8b,0x8d +,0xc2,0x17,0x13,0xc9,0x95,0xaf,0x1e,0x14,0x2a,0x92,0x8c,0xb9,0x17,0x0e,0x2b,0x93,0x99,0x35,0x16,0x13,0xba,0x8c,0x97,0x38,0x16,0x19,0xa1,0x91,0xcb,0x19,0x0e,0x1f +,0x8f,0x89,0x9e,0x23,0x0f,0x24,0x99,0xa5,0x28,0x15,0x15,0xa4,0x8a,0x98,0x32,0x0f,0x14,0x9d,0x8f,0xac,0x1f,0x0d,0x23,0x8f,0x8e,0xaf,0x1c,0x0f,0x3d,0x94,0xaa,0x1f +,0x0e,0x12,0x9a,0x86,0x91,0x4e,0x0f,0x15,0x9f,0x96,0x5a,0x17,0x0c,0x39,0x8a,0x8c,0xb2,0x15,0x09,0x32,0x90,0x9b,0x3a,0x0f,0x12,0x9a,0x88,0x99,0x2f,0x0e,0x1a,0x98 +,0x96,0x49,0x12,0x09,0x3f,0x87,0x89,0xa8,0x14,0x0a,0x48,0x92,0xa8,0x25,0x0d,0x18,0x91,0x87,0x9d,0x23,0x0a,0x19,0x92,0x92,0xde,0x15,0x0c,0xbd,0x87,0x8f,0x75,0x0f +,0x0b,0xb5,0x8e,0xac,0x1d,0x0a,0x16,0x8d,0x86,0x98,0x26,0x0b,0x1f,0x90,0x98,0x3d,0x12,0x0c,0xac,0x88,0x94,0x39,0x0c,0x0b,0xa1,0x8b,0xa1,0x24,0x0a,0x1b,0x8c,0x8a +,0x9e,0x22,0x0b,0x27,0x92,0x9e,0x39,0x10,0x0c,0xa4,0x89,0x94,0xce,0x0e,0x0f,0x9f,0x95,0xbd,0x1e,0x0c,0x2c,0x8b,0x8c,0x9f,0x1c,0x09,0x2d,0x93,0x9a,0xda,0x10,0x0e +,0xa4,0x8d,0x98,0xd5,0x0e,0x14,0x9f,0x9a,0xb3,0x1d,0x0a,0x38,0x8b,0x8b,0x9d,0x19,0x0a,0x49,0x95,0x9e,0x58,0x0d,0x0e,0xa0,0x8d,0x94,0xff,0x0b,0x16,0x9c,0x97,0xab +,0x1a,0x0b,0xf3,0x8d,0x8f,0xa6,0x14,0x0d,0xb1,0x94,0xa1,0x28,0x08,0x12,0x96,0x8a,0x8f,0x4a,0x0c,0x1e,0x9d,0x9d,0xbe,0x14,0x0c,0xb5,0x8e,0x95,0xbe,0x12,0x16,0x9d +,0x93,0xa7,0x1e,0x09,0x1d,0x92,0x8d,0x9c,0x20,0x0c,0x32,0x97,0x9d,0x59,0x10,0x0e,0xa8,0x8d,0x94,0xbc,0x15,0x20,0x9b,0x9d,0x46,0x16,0x0d,0x44,0x8f,0x93,0xb2,0x18 +,0x0f,0xc8,0x93,0x9d,0x3a,0x0f,0x16,0x9d,0x8f,0x9c,0x56,0x19,0x33,0x9d,0xaa,0x2e,0x12,0x0f,0xbf,0x8f,0x98,0xc5,0x1c,0x1c,0xa5,0x96,0xaa,0x24,0x0c,0x1c,0x98,0x8e +,0x9e,0x2a,0x12,0x37,0x9d,0xa6,0x48,0x18,0x16,0xb5,0x96,0x9e,0xf2,0x1b,0x2a,0x99,0x96,0xce,0x13,0x0a,0x26,0x90,0x8d,0x9f,0x21,0x14,0xda,0x98,0xa4,0x2d,0x0e,0x12 +,0xa6,0x91,0x9e,0x41,0x19,0x3b,0x95,0x9a,0x40,0x12,0x0c,0x53,0x8d,0x92,0xcd,0x17,0x17,0xa5,0x8f,0xa7,0x1e,0x0b,0x14,0x9b,0x8e,0x9f,0x40,0x1c,0x4b,0x98,0xa7,0x29 +,0x14,0x11,0xad,0x8c,0x9e,0x32,0x17,0x1f,0x97,0x90,0xd8,0x19,0x0c,0x1b,0x95,0x92,0xad,0x36,0x1a,0xdc,0x95,0xaf,0x25,0x13,0x14,0xa3,0x8f,0xa9,0x3a,0x21,0x35,0x96 +,0x9b,0x2d,0x17,0x0e,0x2a,0x8f,0x94,0xce,0x23,0x19,0xb1,0x94,0xb7,0x29,0x18,0x18,0xa3,0x93,0xbb,0x3a,0x26,0x4e,0x96,0xa5,0x22,0x17,0x11,0xee,0x8d,0x9d,0x38,0x21 +,0x1f,0x9f,0x92,0xea,0x1e,0x14,0x1b,0x9b,0x94,0xd9,0x35,0x27,0xe9,0x95,0xac,0x1f,0x1a,0x19,0xb2,0x8f,0xb4,0x27,0x28,0x3b,0x95,0x93,0x2d,0x16,0x11,0x1f,0x95,0x94 +,0x44,0x2a,0x29,0xb4,0x94,0xce,0x1d,0x21,0x20,0xa8,0x94,0x53,0x21,0x2b,0xcf,0x91,0x9c,0x1c,0x15,0x17,0x3b,0x90,0x9d,0x2b,0x2e,0x31,0xa0,0x8f,0xd4,0x1d,0x19,0x1a +,0xaa,0x9a,0x2e,0x28,0x4a,0xad,0x90,0xab,0x19,0x1a,0x1c,0xbb,0x8f,0xac,0x21,0x2a,0x32,0x9c,0x93,0x33,0x1b,0x19,0x1b,0x9f,0x99,0x38,0x38,0x4c,0xab,0x90,0xc0,0x19 +,0x1f,0x22,0xb5,0x96,0x4b,0x1f,0x2f,0x45,0x96,0x98,0x21,0x1b,0x1d,0x2e,0x93,0x99,0x2c,0x2c,0x2e,0xb2,0x94,0x4b,0x18,0x26,0x28,0xa9,0x97,0x31,0x24,0x54,0xbd,0x95 +,0xa4,0x19,0x1b,0x23,0x68,0x90,0xa6,0x1c,0x29,0x3d,0xa6,0x95,0x33,0x1b,0x33,0x32,0x9f,0x99,0x29,0x25,0x46,0xe6,0x9b,0xc2,0x13,0x21,0x42,0xad,0x94,0x6d,0x1c,0x4e +,0xb8,0x97,0x94,0x28,0x1a,0x2c,0x30,0xa3,0xac,0x1b,0x28,0x6c,0xc2,0x9b,0x47,0x14,0x2d,0x40,0xb6,0x9d,0x2c,0x1d,0xc3,0xa9,0x94,0x9a,0x1f,0x20,0x4e,0xd9,0x98,0xa2 +,0x25,0x3f,0xbc,0xa6,0x98,0x39,0x16,0x2c,0x2e,0xd8,0xac,0x1f,0x1e,0xc4,0xb6,0x9e,0xb2,0x15,0x1b,0x39,0xd7,0x9c,0xbe,0x1b,0x36,0xba,0xa6,0x9c,0x2f,0x1a,0x44,0xd4 +,0xa6,0x9e,0x32,0x3b,0xa3,0x9f,0x9a,0xb5,0x19,0x23,0xc7,0xb6,0xa5,0x3d,0x1a,0x50,0xa8,0xa1,0xa2,0x25,0x17,0x3a,0xcb,0xab,0xac,0x24,0x29,0xb6,0xbc,0xb7,0x33,0x14 +,0x27,0xc3,0xd3,0xb4,0x37,0x22,0xb3,0x9e,0xa0,0xad,0x1e,0x1b,0xcb,0xb2,0xab,0xb9,0x24,0x3a,0xa9,0xab,0xa8,0x70,0x1f,0x51,0xab,0xad,0xa7,0x48,0x2a,0xb3,0xa9,0xb4 +,0xdb,0x1e,0x22,0xb1,0xab,0xaf,0xd6,0x1e,0x2c,0xaf,0xb4,0xb7,0x38,0x1a,0x2c,0xd0,0x63,0xc7,0x38,0x2a,0xb3,0xaa,0xbb,0xd0,0x21,0x25,0xae,0xab,0xb5,0xd5,0x23,0x3d +,0xa6,0xb3,0xbe,0x3e,0x1f,0x5b,0xa8,0xb5,0xb4,0x40,0x28,0xb1,0xa2,0xb2,0xc8,0x27,0x2d,0xab,0xaf,0xed,0x44,0x23,0x3e,0xa0,0xac,0xd0,0x39,0x1f,0xde,0xa0,0xb1,0xc4 +,0x33,0x23,0xbb,0xab,0x48,0x42,0x2a,0x2e,0xae,0xbf,0x43,0x4c,0x2b,0x5b,0xa1,0xba,0x3d,0x2e,0x23,0x5e,0xaf,0x42,0x36,0x2d,0x2a,0xb1,0xa7,0xef,0x50,0x2e,0x3a,0xa6 +,0xac,0x56,0x44,0x30,0xcc,0xa2,0xc7,0x44,0x50,0x3e,0xae,0xa1,0xbd,0x6f,0x3b,0x3e,0xa5,0xa3,0xed,0x45,0x2f,0x34,0xb4,0xbb,0x55,0x5f,0x2e,0x3f,0xb0,0x5e,0x3e,0x48 +,0x33,0xbb,0xa9,0x50,0x3a,0x2e,0x2e,0xb4,0xbb,0x34,0x37,0x29,0x2f,0xb8,0xd8,0x3a,0x38,0x2e,0xc0,0xa3,0xc9,0x45,0x3e,0x31,0xbc,0xae,0x5b,0x5d,0x43,0x5c,0xa8,0xb3 +,0x3e,0x3e,0x37,0xc3,0x9d,0xac,0x74,0x3d,0x31,0xc0,0xaf,0xeb,0xdb,0x50,0x44,0xad,0xad,0xf2,0x4e,0x48,0xbb,0xaa,0x5c,0x2c,0x2f,0x31,0xd5,0xad,0x5e,0x33,0x2f,0x3a +,0xb8,0xbf,0x40,0x3a,0x2f,0x4e,0xab,0xc7,0x30,0x34,0x32,0x73,0xc6,0x35,0x30,0x33,0x3a,0xb5,0xad,0x4d,0x38,0x33,0xe3,0xa7,0xc6,0x43,0x43,0x36,0xcb,0xa9,0xb1,0xba +,0xd5,0x40,0xc9,0xdc,0x3a,0xfe,0xcd,0xb7,0xa3,0xb1,0xeb,0xca,0x72,0xb4,0xa9,0x58,0x59,0x4a,0x34,0xb7,0xab,0xce,0x50,0x38,0x45,0xb1,0xe2,0x38,0x4d,0x2c,0x3c,0xbc +,0x48,0x3d,0x31,0x2a,0xdc,0xc7,0x32,0x3a,0x2e,0x2e,0xac,0xb4,0x51,0x44,0x27,0x31,0xbd,0x6c,0xf4,0x69,0x21,0x3a,0xba,0x4d,0xbd,0xc8,0xda,0xa4,0xb8,0x40,0xdf,0x33 +,0x47,0xa5,0xb0,0xbc,0xe0,0x2d,0xb8,0xa3,0xea,0xcc,0x4c,0x2a,0xae,0xa1,0xb7,0xb0,0x45,0x4b,0xa7,0xc6,0xdb,0xe5,0x26,0x4f,0xa9,0xda,0x55,0x33,0x25,0xae,0xab,0x49 +,0xf9,0x21,0x1d,0xb8,0xaf,0xb8,0xba,0x27,0x34,0xc5,0x2f,0x55,0x44,0x1e,0x50,0xbd,0x36,0x5c,0x34,0x33,0xa5,0xbb,0x3e,0x70,0x1f,0x2a,0xa6,0xb8,0xb6,0xba,0x26,0xc1 +,0xa8,0x58,0xb2,0x3f,0x1f,0xb2,0xad,0xce,0xad,0x3b,0x3f,0xa6,0x63,0xc8,0xae,0x20,0x7e,0x9c,0xba,0xaf,0x4e,0x24,0xb1,0xac,0xbd,0xa3,0x2b,0x17,0x5c,0x46,0xd6,0xa8 +,0x32,0x4e,0xb7,0x2d,0xc0,0xcc,0x1d,0xc6,0xac,0x40,0xb0,0x43,0x28,0xae,0xdd,0xdb,0xaa,0x1c,0x1d,0xb4,0x3f,0xbd,0xaf,0x25,0x62,0xbc,0x3f,0xa1,0xe4,0x1b,0xbe,0xef +,0x48,0x9e,0x46,0x36,0xab,0x3a,0xbf,0xaf,0x17,0x2c,0xa8,0xea,0xa1,0xb5,0x1c,0x40,0x47,0xc9,0x95,0x6b,0x1e,0xc7,0x2f,0xdb,0x9c,0x3b,0xd3,0xad,0x2d,0xa9,0xbc,0x17 +,0x40,0xc5,0x43,0x9d,0xd6,0x20,0xbf,0x44,0xb2,0x9b,0x20,0x22,0xaf,0x4c,0x9f,0x9e,0x22,0x37,0x3b,0x34,0x9b,0xe0,0x19,0x5e,0x35,0x44,0x9d,0x3c,0x2d,0xb5,0x3d,0xa0 +,0x9e,0x1a,0x29,0x6e,0x40,0x96,0xa2,0x23,0x33,0x1f,0x30,0x9a,0x46,0x27,0xbf,0x26,0xcc,0xa1,0x29,0x4c,0xcc,0x38,0x9a,0xac,0x1d,0x4e,0x31,0x38,0x9a,0xdd,0x29,0xcf +,0x2b,0xa9,0x9a,0x1e,0x25,0x43,0x27,0x9d,0x9c,0x2c,0x64,0x2d,0x3a,0x96,0xdd,0x23,0xb4,0x32,0xbb,0x98,0x2a,0x29,0x45,0x28,0x99,0x9c,0x1a,0x2f,0x28,0x23,0x95,0xa5 +,0x2e,0xbb,0x27,0xc0,0x95,0x29,0x2e,0xbd,0x23,0xa2,0x9b,0x1e,0x35,0x2e,0x24,0x96,0xb8,0x1a,0xce,0x28,0x41,0x93,0x4b,0x22,0x5e,0x24,0x9d,0x8f,0x24,0x2d,0x32,0x1b +,0x9a,0x9e,0x1f,0xd6,0x29,0x2e,0x92,0x44,0x19,0xd4,0x22,0xaf,0x8e,0x2f,0x26,0x2f,0x1b,0x98,0x95,0x26,0xe2,0x26,0x1d,0x93,0xad,0x1f,0xcc,0x21,0xc4,0x8e,0x31,0x23 +,0x4e,0x1a,0xa0,0x92,0x20,0x39,0x32,0x27,0x8f,0x9f,0x1e,0x49,0x1b,0x32,0x8d,0xd0,0x20,0x38,0x16,0xa7,0x8e,0x32,0x35,0x29,0x19,0x95,0x95,0x20,0x36,0x23,0x38,0x8c +,0xa7,0x22,0x2f,0x12,0xe9,0x8e,0x40,0x27,0x2a,0x16,0x9f,0x95,0x2d,0x53,0x23,0x26,0x90,0xa6,0x24,0x3a,0x1b,0xc2,0x8c,0xd4,0x23,0x28,0x15,0x9f,0x8f,0x29,0x21,0x1e +,0x21,0x8f,0x97,0x2f,0x3a,0x17,0x3e,0x8d,0xb7,0x22,0x28,0x15,0xa9,0x8d,0xfd,0x2f,0x1e,0x17,0x95,0x94,0x2f,0x2f,0x17,0x28,0x90,0x9f,0x4b,0x37,0x17,0xb0,0x8f,0x45 +,0x2a,0x20,0x19,0x97,0x95,0x32,0x30,0x1b,0x29,0x8f,0xa1,0x21,0x28,0x16,0xc3,0x8e,0xb0,0x3a,0x21,0x17,0x99,0x8e,0x4f,0x2c,0x16,0x1b,0x96,0x9a,0x42,0x2b,0x11,0x44 +,0x8f,0xab,0x2b,0x1a,0x12,0xaa,0x8f,0xac,0xca,0x1d,0x1b,0x98,0x9a,0x4a,0x35,0x15,0x29,0x97,0xaf,0x39,0x26,0x14,0xa7,0x8f,0xb5,0x55,0x1a,0x19,0x9a,0x99,0xdc,0x3b +,0x13,0x2f,0x8d,0xa2,0x37,0x21,0x0f,0xc9,0x91,0xaa,0x48,0x1b,0x17,0x9a,0x95,0xc0,0x67,0x17,0x26,0x97,0xa4,0xee,0x29,0x10,0xc7,0x8f,0xa2,0xbb,0x1e,0x0f,0xbe,0xa5 +,0x6a,0x6f,0x1a,0x2b,0x93,0x9f,0xcd,0x5a,0x19,0x63,0x97,0xba,0x51,0x22,0x17,0xa4,0x99,0xc7,0xcd,0x1d,0x1c,0xa3,0xaf,0x45,0x37,0x13,0x47,0x93,0xa3,0xa3,0xd6,0x17 +,0xd9,0xa9,0x3b,0xcc,0x22,0x1e,0x9b,0xa6,0x53,0xcb,0x1b,0x29,0x9e,0xbe,0xc0,0x52,0x17,0xc6,0x9c,0xbb,0xa0,0xd7,0x1e,0xb7,0xe7,0x27,0x73,0x1d,0x2b,0x99,0xac,0xb1 +,0xad,0x1c,0x3f,0xa2,0x3b,0xcf,0x33,0x18,0xa7,0x9f,0xcc,0xa2,0x32,0x22,0xa5,0xd1,0x44,0xdc,0x18,0x2d,0xa5,0x54,0xad,0xae,0x23,0xbe,0xb0,0x2e,0xdb,0x22,0x1d,0x9b +,0xa0,0xae,0x9f,0x24,0x2a,0xb2,0x2d,0xde,0x6d,0x19,0xc5,0xac,0x3f,0xa1,0xd1,0x29,0xa5,0xd0,0x38,0xc6,0x19,0x26,0x9f,0xd2,0xaa,0xa0,0x27,0xc6,0xb0,0x29,0xc5,0x3b +,0x1b,0xb9,0xb8,0x7d,0x9f,0x56,0x2f,0xb1,0x3e,0xde,0xb1,0x23,0x69,0xad,0x37,0xbb,0xba,0x28,0xad,0xac,0x3f,0xac,0x27,0x1c,0x6a,0x2d,0x4b,0xaf,0x3e,0xc1,0x44,0x3f +,0x9b,0x9d,0xac,0xb9,0x23,0x2f,0xbb,0x20,0x21,0x38,0xa3,0x8d,0x9c,0x24,0x1c,0x10,0x15,0x2f,0x24,0x3e,0xd1,0xb9,0x8e,0x8b,0xa9,0xaf,0xa4,0x9f,0xbc,0x0a,0x02,0x0b +,0x25,0x8b,0x80,0x87,0x29,0x0b,0x15,0x28,0xb0,0x28,0x1d,0x1b,0xa7,0xa7,0x0b,0x0a,0x3d,0x9a,0x90,0x8e,0x21,0x0d,0x1d,0x97,0x87,0x87,0x9b,0x1a,0x1f,0xad,0xaf,0x21 +,0x09,0x0d,0x0d,0x49,0x81,0x81,0x87,0x9d,0xb3,0x2d,0x0d,0x03,0x02,0x08,0xa7,0x85,0x2d,0x02,0x09,0x2a,0xe5,0x89,0x87,0xa6,0xb6,0x26,0xa5,0x84,0x80,0x8a,0xa2,0xb5 +,0xbe,0x11,0x01,0x03,0x0f,0x16,0xbb,0xa3,0x15,0x18,0x36,0xcd,0x6a,0x9c,0xb3,0x1e,0x2c,0x8b,0x85,0xbe,0x1e,0x3f,0xa1,0x96,0x8f,0xb4,0x1d,0x08,0x0f,0x9f,0x8a,0x94 +,0xcf,0x54,0x4c,0x26,0x05,0x00,0x08,0x15,0x9c,0x80,0x85,0x9f,0xa1,0x94,0xa9,0xbc,0x34,0x09,0x08,0x58,0x8c,0x9e,0x25,0x23,0x3d,0x2f,0xaa,0x8f,0x8d,0xc0,0x10,0x33 +,0x98,0x98,0x35,0x22,0x57,0xaf,0x11,0x00,0x02,0x04,0x47,0x84,0x81,0x8a,0x9c,0xa6,0xa3,0x97,0x8a,0x8e,0xbd,0x1c,0x26,0x3f,0x0f,0x17,0x99,0x98,0x33,0x0f,0x09,0x07 +,0x10,0xcb,0x93,0x87,0x96,0x2b,0x32,0x98,0x98,0x2c,0x17,0x10,0x0f,0xd2,0x8d,0x90,0x94,0xa1,0x2a,0x11,0x16,0x2f,0xc8,0xa3,0x9b,0x95,0x21,0x06,0x0e,0x4d,0xa1,0x9c +,0x99,0xc9,0x2b,0x18,0x1e,0xa4,0x98,0xae,0xcf,0xab,0xac,0x2a,0x0e,0x1f,0x4b,0x3e,0xa7,0x8a,0x85,0x8b,0x8b,0x97,0x31,0x0e,0x0a,0x09,0x0e,0x17,0x0c,0x04,0x05,0x48 +,0x8b,0x87,0x91,0xa0,0x9f,0xa9,0xba,0xae,0x8f,0x8c,0x88,0x8f,0xa4,0x18,0x03,0x0a,0x11,0x15,0x1a,0x35,0x29,0x1c,0x36,0xa1,0x95,0x99,0xc5,0x2c,0x1d,0x17,0xbb,0x97 +,0x9c,0xa3,0x9e,0x96,0x8f,0x92,0xb5,0xdf,0x24,0x0c,0x0c,0x1e,0xca,0x9b,0x88,0x8a,0x23,0x04,0x03,0x03,0x0c,0xaa,0x89,0x8d,0x96,0xb2,0xd9,0xa4,0x99,0x97,0xdf,0x17 +,0x0f,0x12,0x17,0x2a,0xa3,0x8c,0x85,0x8d,0xc0,0x41,0x40,0x20,0x41,0xaf,0xc8,0x20,0x13,0x1c,0x1e,0x10,0x09,0x0f,0x18,0x2a,0xad,0x98,0x94,0x8d,0x85,0x8a,0x93,0x96 +,0x97,0xa3,0xce,0x1a,0x0a,0x17,0x4d,0x40,0xaa,0x9d,0x2b,0x1c,0x15,0x0b,0x0a,0x20,0xaf,0xa9,0x9d,0x9c,0x9e,0xae,0x3a,0x23,0x28,0x37,0xae,0x95,0x94,0x9d,0xa3,0xb1 +,0x48,0x26,0x2e,0xc5,0xb2,0xbe,0x22,0x12,0x0f,0x17,0x59,0x9b,0x99,0xac,0x3b,0x20,0x19,0x22,0xa9,0x8e,0x94,0xc6,0x2b,0x18,0x11,0x2a,0xb4,0xae,0xa0,0x9e,0xb2,0xa0 +,0x8f,0x8f,0x8f,0x99,0x2f,0x14,0x10,0x0f,0x0e,0x11,0x11,0x11,0x1f,0xca,0xa4,0x9e,0xa8,0xb0,0x9d,0x9e,0xbc,0xb9,0xa4,0x92,0x8b,0x96,0x1b,0x08,0x0f,0x2f,0xa1,0x92 +,0x9b,0xd3,0x22,0x0d,0x0b,0x1d,0xc1,0xa9,0xb6,0x52,0x2d,0x2a,0x2c,0x55,0xa6,0x9a,0x91,0x98,0xbe,0xe3,0xb0,0xb5,0xb0,0xd2,0x1f,0x22,0x50,0xe0,0x52,0x30,0x1d,0x1a +,0x27,0x56,0xc5,0xb8,0xad,0xa4,0x9c,0xa0,0x3c,0x28,0x46,0xbf,0xad,0x32,0x0e,0x0f,0x27,0xbd,0x96,0x8e,0x9a,0xaa,0xa9,0xb2,0xaf,0xa1,0xad,0x4a,0x31,0x1b,0x11,0x0d +,0x0a,0x0c,0x15,0x3e,0x9f,0x98,0xa2,0xa9,0x9d,0x94,0x8f,0x93,0xa0,0xa3,0x9a,0xa7,0x21,0x0d,0x0c,0x21,0xad,0xa3,0xb9,0x48,0x3e,0x27,0x19,0x15,0x1d,0xc9,0xa7,0xbc +,0xce,0xc8,0xd2,0xb7,0xc6,0xd4,0x9f,0x99,0xac,0x68,0xda,0xb6,0xa6,0xb1,0x23,0x17,0x1f,0x47,0xb5,0xb3,0x5d,0x21,0x1c,0x27,0xbb,0x98,0x9c,0x51,0x26,0x2a,0x4e,0xb7 +,0xc3,0xbe,0xaa,0xc5,0x1d,0x11,0x16,0x4e,0x91,0x8a,0x8f,0x9f,0xd8,0x45,0xbf,0xa5,0x9d,0xa4,0x3e,0x16,0x0c,0x0b,0x0e,0x12,0x15,0x1e,0xbc,0x9b,0x9e,0xa1,0x9f,0x94 +,0x8b,0x93,0xdf,0x2a,0xec,0xa2,0xa0,0x40,0x10,0x0d,0x26,0xad,0x9f,0xa5,0xea,0x31,0x27,0x18,0x17,0x2b,0xd4,0xb6,0xb5,0x50,0x3f,0x56,0x3b,0x5d,0xa1,0x96,0x96,0x9d +,0xb8,0xbb,0xa7,0xad,0x33,0x1c,0x20,0x2e,0x30,0x28,0x20,0x34,0xaf,0xaa,0xba,0xc3,0x5b,0x2d,0x2b,0x38,0xba,0xa8,0xc0,0x65,0xbd,0xb0,0xcc,0x1d,0x0c,0x16,0xaa,0x92 +,0x93,0x9d,0xac,0xa1,0x97,0x9d,0xbe,0x58,0x3d,0x2c,0x1d,0x11,0x0f,0x14,0x11,0x12,0x20,0xd1,0xa2,0x9f,0xa7,0xa8,0x99,0x93,0x9a,0x9d,0x9b,0x9b,0xa3,0x43,0x17,0x11 +,0x20,0xcf,0xaf,0xc4,0x46,0xf9,0xbc,0x3c,0x1b,0x14,0x16,0x26,0x4a,0x3d,0x44,0x78,0xb4,0x9d,0x94,0x90,0x94,0xa1,0xd4,0x4d,0xd7,0xed,0x37,0x23,0x1c,0x27,0x45,0x36 +,0x22,0x1d,0x2e,0xb4,0xab,0xbb,0xb3,0xa4,0xb1,0x47,0x3c,0x51,0xd8,0x73,0x2f,0x1f,0x26,0x2b,0x20,0x24,0xb2,0x94,0x90,0x95,0xa6,0xab,0x9c,0x9f,0xbc,0x47,0xe8,0xaa +,0xb2,0x1f,0x0d,0x0c,0x0d,0x11,0x18,0x1d,0x38,0xab,0x9d,0x99,0x93,0x8f,0x8f,0x9c,0xb1,0xbd,0xdc,0x37,0x29,0x21,0x28,0xdd,0xae,0xb4,0xf0,0x59,0x3f,0x2d,0x1d,0x14 +,0x17,0x2b,0x5d,0x4f,0x43,0xe6,0xe4,0xc0,0xb5,0xb1,0x9c,0x93,0x93,0x9a,0xa4,0xca,0xcd,0xaf,0x62,0x22,0x15,0x0f,0x10,0x1e,0xdf,0x9a,0x94,0xa5,0xc9,0xfe,0x56,0x37 +,0x24,0x25,0x33,0xcf,0xbb,0x4b,0x3a,0xb4,0xa9,0x43,0x1f,0x1d,0x35,0xa7,0x97,0x9a,0x9d,0x9f,0xa0,0x9f,0xae,0xcb,0x3f,0x1f,0x14,0x0f,0x10,0x1b,0x25,0x20,0x2e,0xbb +,0xaa,0xaf,0x4a,0x40,0xaa,0x97,0x94,0x96,0x9d,0xae,0xa6,0xad,0x51,0x2b,0x2d,0x37,0x2f,0x2f,0x3e,0xc6,0xba,0xc8,0x2a,0x1a,0x15,0x14,0x19,0x1d,0x24,0x77,0x9d,0x99 +,0x97,0x8e,0x8d,0x91,0x9e,0xef,0x36,0x3a,0x3a,0x28,0x1d,0x1a,0x26,0x28,0x1d,0x25,0x46,0xab,0xa6,0xb2,0xbb,0xa7,0xad,0xbe,0xb6,0xb9,0xca,0x27,0x12,0x0f,0x1e,0x3a +,0xdc,0xd4,0xba,0x9d,0x91,0x8e,0x97,0xae,0xb2,0xba,0x39,0x2e,0x49,0xc6,0xae,0xe3,0x19,0x10,0x11,0x13,0x1a,0x27,0x38,0xca,0xc3,0xc1,0x9c,0x8f,0x8e,0x99,0xbd,0x3e +,0x4a,0xbc,0xaf,0xbe,0x6b,0xbe,0xab,0xaf,0xd2,0x2b,0x1d,0x1f,0x21,0x1c,0x18,0x1c,0x25,0x3b,0xe9,0xa9,0xa0,0xb7,0x4b,0x4b,0xab,0x97,0x93,0x9b,0xa4,0xad,0xb8,0xba +,0x37,0x19,0x17,0x18,0x14,0x19,0x24,0xcd,0x97,0x8f,0x9a,0xad,0x52,0x2a,0x29,0x4a,0xf3,0x39,0x26,0x1f,0x26,0x59,0xac,0xbf,0x3d,0x39,0xbd,0xa2,0x9e,0xa6,0xa2,0x96 +,0x95,0x9b,0xbd,0x26,0x1f,0x24,0x20,0x1a,0x15,0x17,0x1f,0x2d,0xcf,0xa5,0xa6,0x46,0x2a,0x33,0xc9,0xa5,0xa1,0xa4,0xa4,0xa4,0x9f,0x9c,0xa7,0xe2,0xf4,0xc4,0x3a,0x22 +,0x1f,0x2f,0xc3,0xba,0x2a,0x14,0x11,0x14,0x1c,0x27,0x2d,0x35,0xb2,0x97,0x8f,0x8b,0x8c,0x98,0xb0,0xef,0x48,0x54,0x39,0x1c,0x15,0x1a,0x2e,0xc8,0xd3,0x2c,0x2c,0xbd +,0xa6,0xab,0xc4,0xbf,0xb4,0xae,0xad,0xb8,0xed,0x29,0x18,0x14,0x18,0x1d,0x2a,0xbe,0x9e,0x96,0x92,0x97,0xa2,0xb9,0xab,0xa3,0xbd,0x2d,0x25,0x3f,0xba,0xae,0x3e,0x21 +,0x20,0x1f,0x1b,0x1b,0x1b,0x1c,0x31,0xba,0xa4,0x9c,0x9a,0xa4,0xb3,0xaf,0xaa,0xa8,0xb0,0xde,0xdf,0xa7,0x9c,0x9f,0xcb,0x24,0x1d,0x29,0x2b,0x18,0x0e,0x10,0x1c,0x37 +,0xb8,0xac,0xaa,0xb1,0xb8,0xb5,0xaa,0xa3,0x9e,0x9b,0x9f,0xa8,0xad,0xac,0x58,0x20,0x18,0x18,0x14,0x13,0x23,0xb0,0x98,0x99,0xab,0xe2,0xb9,0xa6,0xa6,0xe9,0x1a,0x10 +,0x19,0x38,0xca,0xb7,0xc3,0x3f,0x36,0xcf,0xa5,0x9f,0xac,0x62,0xd0,0xa1,0x98,0x9a,0xac,0x4d,0x3d,0x40,0x2d,0x1d,0x1d,0x2c,0x2f,0x27,0x22,0x34,0xc8,0xbe,0x3f,0x27 +,0x21,0x22,0x5c,0xa3,0x9b,0x97,0x90,0x90,0x98,0xa1,0xae,0xc1,0x3a,0x25,0x28,0x31,0x2c,0x1f,0x17,0x1b,0x2d,0x2f,0x1e,0x18,0x19,0x2a,0xa9,0x96,0x94,0x97,0x98,0x9a +,0x99,0x9d,0xa9,0x53,0x1f,0x16,0x15,0x21,0x5c,0xb3,0xc4,0x31,0x2f,0xdc,0xb8,0xdb,0xd8,0xc5,0xf4,0xef,0xc5,0xb7,0xb3,0xf5,0x27,0x1c,0x19,0x1d,0x33,0x4d,0x64,0xae +,0x9a,0x93,0x98,0xa3,0xb1,0xc3,0x4a,0x3c,0x62,0xba,0xb8,0x55,0x34,0x41,0xd8,0x48,0x27,0x18,0x13,0x1a,0x27,0x3a,0x4e,0xd1,0xb1,0xaa,0xa8,0x9e,0x99,0x9b,0xa5,0xd8 +,0x4f,0xaa,0x98,0x9c,0xb0,0x38,0x28,0x29,0x1b,0x12,0x14,0x18,0x1a,0x22,0x38,0xc3,0xaa,0xa5,0xa6,0xa2,0xa5,0xa8,0xa6,0xad,0xbf,0xb5,0x9f,0x9f,0xda,0x24,0x1a,0x19 +,0x22,0x31,0x3e,0xe6,0xbf,0xbe,0xbd,0xb1,0xa8,0xa5,0xc2,0x2a,0x1e,0x1d,0x2a,0x75,0xce,0x45,0x3e,0x46,0xd8,0xaf,0xa7,0xa5,0xba,0x33,0x2f,0xc9,0x9e,0x96,0x9d,0xbf +,0x46,0x42,0x2e,0x27,0x2c,0x2f,0x28,0x27,0x2c,0x2e,0x31,0x55,0xe0,0x34,0x2e,0x3e,0x65,0xb7,0xa2,0x93,0x8f,0x99,0xaa,0xb5,0xbb,0xc3,0x6c,0x29,0x1e,0x25,0x2d,0x28 +,0x28,0x2d,0x2a,0x24,0x1f,0x23,0x39,0xbd,0xa5,0x9d,0x9d,0xa3,0xb3,0xb0,0xa6,0xa9,0xb1,0xd5,0x2c,0x1c,0x1c,0x2f,0xb8,0xa8,0xb2,0x5f,0x42,0x5c,0xc8,0xd1,0x65,0x4a +,0x3b,0x49,0x4e,0x3c,0x3e,0xd0,0x4f,0x29,0x29,0x3f,0xbc,0xa9,0xa7,0xac,0xb4,0xcb,0xc2,0xb3,0xb7,0xc1,0xdd,0x37,0x2f,0x78,0xab,0xae,0x5a,0x3e,0x3f,0x31,0x26,0x24 +,0x23,0x1f,0x26,0x3e,0xc9,0xbe,0xb8,0xa7,0xa8,0xae,0x9e,0x9c,0xac,0xca,0xbd,0xb3,0xd0,0x3f,0x3f,0x40,0x2f,0x28,0x20,0x1d,0x22,0x25,0x28,0x43,0xbf,0xab,0xa3,0xa1 +,0xab,0xc0,0xc2,0xda,0xca,0xab,0x9f,0xab,0x45,0x33,0x30,0x2a,0x30,0x3c,0x38,0x35,0x47,0xb5,0xa6,0xaa,0xaf,0xaf,0xf7,0x28,0x29,0x2f,0x2a,0x2b,0x51,0xbf,0xe6,0x3f +,0xcf,0xaa,0xaa,0xaf,0xb4,0xea,0x38,0x3c,0xba,0xac,0xbc,0xd0,0xf5,0x2f,0x2a,0x4f,0xe3,0x4f,0x53,0x63,0x43,0x28,0x26,0x3b,0x4a,0x37,0x34,0x65,0xbb,0xbe,0xab,0x9f +,0xa8,0xbc,0xac,0x9e,0xa4,0xb4,0x5a,0x24,0x1b,0x29,0xcc,0xbc,0x35,0x1c,0x1b,0x26,0x2f,0xbf,0x9d,0xa3,0xcb,0x74,0xa7,0xa3,0xac,0xa8,0xb3,0x49,0x37,0xe4,0xc2,0x41 +,0x2b,0x25,0x23,0x23,0x2a,0xc5,0xb4,0x52,0x4a,0x61,0x40,0x37,0xcc,0xab,0xb0,0xba,0xab,0xb7,0x31,0x36,0xc5,0xb3,0xac,0xa6,0xa0,0xb7,0x2a,0x25,0x3e,0xf1,0x4b,0x6e +,0xeb,0x2e,0x25,0x30,0xe9,0xf3,0x4f,0xcd,0xee,0x34,0x29,0x2d,0x3a,0x47,0xc4,0xa0,0x9d,0xae,0xb6,0xac,0xc9,0x4c,0xac,0x9e,0xa6,0xba,0xdc,0x39,0x1e,0x1c,0x29,0x34 +,0x2c,0x20,0x1d,0x22,0x28,0x50,0xab,0xb5,0x43,0xdf,0xa3,0x9f,0xa0,0x9d,0xa6,0xbe,0xc1,0xa7,0x9c,0xa7,0x4a,0x2b,0x24,0x1d,0x1c,0x2f,0x68,0x45,0x55,0xbd,0x39,0x1d +,0x1f,0x3d,0xc3,0xb2,0xac,0xbb,0x47,0x34,0xe1,0xa7,0xa5,0xaf,0xb1,0xc0,0x4d,0x5c,0xae,0xa9,0xb1,0xb4,0xb9,0x37,0x1c,0x1f,0x2e,0x3b,0x43,0x3e,0x39,0x2c,0x25,0x42 +,0xb8,0x55,0x2f,0x35,0x42,0x4c,0xba,0x9f,0x9f,0xad,0xa9,0x9f,0xac,0xb9,0xac,0xaa,0xb8,0x46,0x2f,0x35,0x32,0x2d,0x5f,0xc4,0x28,0x17,0x17,0x1f,0x31,0xe0,0xa4,0xa6 +,0xbb,0xba,0xaf,0xae,0xbc,0xb5,0xab,0xb0,0x5d,0x3e,0xc5,0xd7,0x4b,0xb7,0xbb,0x38,0x26,0x2e,0x4a,0x3b,0x3b,0xe0,0xcf,0x3c,0x44,0xc3,0x5d,0x2b,0x24,0x3e,0xdc,0x37 +,0x3f,0xbc,0xad,0xb0,0xac,0xab,0x7e,0x3b,0xbc,0x9e,0xa5,0xd8,0x51,0x68,0x6f,0xbf,0xa8,0xab,0x2c,0x16,0x1b,0x2c,0x33,0x45,0xc9,0x73,0x3c,0x4d,0xba,0xce,0x3d,0x54 +,0xae,0xac,0xbd,0xa6,0x9c,0x9e,0xae,0xd1,0xef,0x2e,0x28,0x45,0x41,0x27,0x21,0x2b,0x35,0x3a,0xd7,0xb3,0x47,0x1f,0x29,0xc7,0xaf,0xb8,0xbc,0xaf,0xb1,0xbf,0xb0,0xb3 +,0x39,0x27,0x3e,0x74,0x4c,0xcb,0xb3,0xb0,0xcb,0xde,0xbb,0xd0,0x32,0x27,0x39,0x46,0x3f,0xcc,0xad,0xb2,0xcd,0xba,0xca,0x2b,0x21,0x32,0x5b,0x47,0x59,0xae,0xa0,0xaf +,0xc1,0xb7,0x6d,0x3c,0xed,0xad,0xb7,0x4f,0xbe,0xb3,0x6c,0x31,0x31,0x33,0x24,0x1e,0x29,0x38,0x2f,0x35,0xed,0xac,0xa6,0xad,0xaf,0xcc,0x3d,0x6d,0xa6,0xab,0x55,0xda +,0xae,0xb5,0x58,0x48,0x3d,0x28,0x1d,0x1d,0x27,0x37,0xe0,0xad,0xa1,0xac,0xc2,0xb3,0xc1,0x47,0x60,0xbb,0xdb,0x2d,0x34,0xb6,0xa1,0xab,0xda,0x36,0x2a,0x28,0x6a,0xab +,0xbe,0xfe,0xb9,0xaf,0xea,0x50,0x6f,0x3b,0x23,0x23,0x4b,0xd7,0x79,0xe9,0xb7,0xae,0xb5,0xbb,0x4a,0x27,0x22,0x33,0xdf,0xd7,0x48,0x77,0xb3,0xb3,0xad,0xa6,0xae,0x4c +,0x2c,0x28,0x2e,0x5f,0xaf,0xa6,0xb3,0x38,0x28,0x38,0x31,0x26,0x35,0xdd,0xfc,0xc9,0xa8,0x9f,0xa6,0xab,0xb5,0x5a,0x3a,0x2f,0x39,0x43,0x38,0xcc,0xa2,0xb0,0x34,0x34 +,0x3c,0x3d,0x3b,0x33,0x3e,0x5e,0xc5,0xac,0xa2,0xab,0xba,0xc5,0x3e,0x28,0x27,0x31,0x37,0x46,0xb8,0xac,0xb7,0x41,0x36,0x7b,0xba,0x4b,0x29,0x1f,0x22,0xbe,0x9a,0x99 +,0xac,0x4b,0x35,0x57,0xfa,0x39,0x33,0x33,0x3a,0xaf,0x9a,0x9e,0xbe,0x48,0x29,0x22,0x2f,0x52,0x51,0x45,0xfa,0xa7,0x99,0xac,0x3b,0x35,0x2c,0x25,0x2c,0x30,0x2d,0x59 +,0xa9,0xa5,0xac,0xaf,0xac,0xbd,0x3d,0x2c,0x30,0x43,0xeb,0xb3,0xaa,0xb9,0x54,0x47,0x33,0x2b,0x2e,0x26,0x22,0x28,0x5e,0xa2,0x9a,0xa6,0xc0,0xc7,0x47,0x33,0x25,0x21 +,0x33,0xe3,0xc6,0xb3,0xa1,0xa3,0xa4,0xab,0x3d,0x23,0x2b,0x50,0xe9,0xbd,0xaf,0xad,0xb8,0xe9,0x5b,0x36,0x21,0x18,0x1c,0x35,0xb7,0x9c,0x9d,0xc8,0x59,0xa3,0xa0,0xcf +,0x2d,0x1c,0x1e,0x3c,0xaa,0xa0,0xac,0x57,0xd8,0xad,0xd0,0x2d,0x1d,0x19,0x21,0xc9,0x9e,0x9d,0xae,0x5d,0x5b,0xf1,0x4d,0x31,0x1f,0x21,0x2e,0xca,0xaa,0xa3,0xa1,0x9f +,0xa9,0x53,0x24,0x18,0x23,0x78,0xb1,0xa9,0xac,0xbc,0xb0,0xa7,0xb8,0x36,0x1b,0x16,0x20,0xdc,0xa0,0x99,0xa6,0x4e,0xc9,0xad,0x52,0x26,0x1f,0x24,0x2f,0xb8,0xa0,0xa6 +,0xb2,0xab,0xaa,0xdd,0x28,0x1c,0x1b,0x1f,0x2e,0xad,0x9d,0x9f,0xa6,0xaa,0xcf,0x28,0x23,0x20,0x26,0x32,0xed,0xb0,0xac,0xa2,0x9c,0xa2,0x3c,0x1b,0x14,0x1d,0xdd,0xa5 +,0xa1,0xab,0xb5,0xa7,0x9a,0xa0,0x33,0x14,0x0f,0x1a,0x3b,0xb1,0xa6,0xac,0xb8,0xac,0xa2,0xb7,0x29,0x1a,0x1f,0x3e,0xb8,0x9d,0x9b,0xad,0xbc,0xb2,0xd0,0x2b,0x1c,0x1a +,0x22,0x2f,0xd5,0xab,0xa4,0xa2,0x9d,0x9f,0x46,0x1e,0x19,0x1d,0x27,0x3d,0xbc,0xb4,0xaf,0xa4,0x9d,0xae,0x28,0x14,0x17,0x36,0xad,0x9e,0xa1,0xb3,0xba,0xa7,0x9e,0xca +,0x1d,0x16,0x1d,0x2f,0xea,0xac,0xa4,0xa8,0xa5,0xa3,0xb6,0x2d,0x18,0x1a,0x2e,0x3f,0xce,0xa8,0xa1,0xa6,0xa6,0xa9,0x46,0x1f,0x1e,0x29,0x33,0x3d,0xc4,0xa9,0xa0,0x9e +,0xa0,0xcf,0x20,0x19,0x26,0xf4,0x49,0x37,0x37,0xdf,0xa2,0x97,0x9f,0x36,0x15,0x13,0x25,0xce,0xac,0xad,0xba,0xb8,0xa4,0x9b,0xa7,0x2a,0x14,0x19,0x3c,0xbb,0xaf,0xa9 +,0xa8,0xa7,0xa7,0xaf,0x3b,0x1e,0x1b,0x23,0x2c,0x38,0xb9,0xa1,0x9b,0x9c,0x9c,0xac,0x26,0x14,0x1a,0x29,0x2e,0x3e,0xf5,0xae,0x9d,0x96,0x9c,0x6d,0x1c,0x1b,0x38,0xe6 +,0xf4,0x7d,0xd0,0xb9,0xab,0xa8,0xcd,0x1f,0x14,0x1d,0x3a,0xda,0xb9,0xaf,0xa3,0x9d,0x9c,0xa2,0x4f,0x19,0x13,0x1f,0x37,0xe7,0xb4,0xa5,0x9c,0x9d,0x9f,0xb4,0x29,0x1b +,0x20,0x2c,0x2b,0x37,0xc1,0x9f,0x9a,0x9d,0xa8,0x47,0x1d,0x19,0x24,0x2d,0x33,0x56,0xae,0x9c,0x95,0x95,0xaf,0x23,0x18,0x24,0x3e,0x38,0x2a,0x2f,0xb7,0xa2,0x9d,0xa6 +,0x3a,0x1b,0x1b,0x2c,0x53,0xbd,0xbf,0xb8,0xab,0xa3,0xa0,0xb2,0x26,0x14,0x19,0x2a,0x3c,0x52,0xb0,0x9a,0x94,0x99,0xa4,0xce,0x2a,0x22,0x26,0x22,0x1f,0x32,0xb4,0x9d +,0x99,0x9d,0xb5,0x2b,0x1a,0x20,0x3b,0x30,0x25,0x32,0xab,0x9a,0x95,0x9a,0xbe,0x28,0x22,0x2f,0x32,0x30,0x35,0xca,0xaa,0xac,0xb6,0xd1,0x37,0x25,0x2a,0x2c,0x34,0xcc +,0xb1,0xac,0xbd,0x3a,0x47,0xb2,0xac,0xba,0x2f,0x1b,0x2c,0xab,0x99,0x9e,0x2f,0x19,0x2a,0xaf,0x9f,0xae,0x2a,0x27,0xb6,0x9c,0x9d,0x41,0x15,0x1a,0x3d,0xb0,0xac,0x3e +,0x1e,0x42,0x9d,0x95,0x9d,0x2f,0x1c,0x35,0xb7,0xac,0xce,0x21,0x28,0xac,0x9f,0xb3,0x25,0x13,0x21,0xbc,0xaa,0xbc,0x32,0x3b,0xa0,0x93,0x9f,0x36,0x17,0x1f,0xb4,0xa6 +,0xd8,0x23,0x1e,0xbc,0x94,0x9a,0x3c,0x16,0x18,0xc6,0x9c,0xae,0x2e,0x1e,0x44,0x98,0x94,0xb6,0x1f,0x16,0x2e,0xa4,0xb0,0x27,0x19,0x28,0x9e,0x8d,0x9a,0x2e,0x17,0x21 +,0xaf,0xa5,0x3d,0x1f,0x26,0xb4,0x92,0x98,0x37,0x17,0x1b,0xbc,0x9a,0xc3,0x1c,0x18,0x36,0x97,0x8f,0xb8,0x1d,0x19,0x3a,0x9f,0xac,0x28,0x1e,0x32,0x9e,0x8e,0x9d,0x2f +,0x1b,0x22,0xb3,0xb2,0x1f,0x14,0x1d,0xb7,0x91,0x98,0x4a,0x24,0x2b,0xb4,0x9d,0xe5,0x20,0x24,0x4c,0x9f,0x9a,0xc9,0x2d,0x2f,0x4f,0xa8,0xcc,0x1c,0x1b,0x2e,0xa6,0x93 +,0x9e,0x4d,0x27,0x25,0xe0,0xad,0x32,0x1e,0x26,0x68,0x9b,0x97,0xb3,0x37,0x25,0x2c,0xab,0xb2,0x2d,0x29,0x2b,0xbb,0x98,0xa5,0x3f,0x25,0x21,0xbe,0xa3,0x32,0x1c,0x1e +,0x43,0x94,0x8e,0xa2,0x3b,0x1a,0x23,0xaf,0xd4,0x1c,0x1a,0x25,0xa1,0x8d,0xa0,0x2e,0x1e,0x2c,0x9d,0x98,0x39,0x1b,0x1e,0xe0,0x90,0x95,0x41,0x19,0x11,0x34,0x9c,0xcb +,0x1c,0x1b,0x55,0x99,0x9a,0xcb,0x3c,0xc7,0xa5,0xab,0x2e,0x1e,0x25,0xb2,0xa1,0x39,0x20,0x2e,0xaf,0x98,0x9f,0x2a,0x17,0x1e,0xce,0x98,0xa8,0x21,0x1d,0xf0,0x95,0x91 +,0xeb,0x15,0x17,0x59,0x98,0x9e,0x1f,0x11,0x29,0x9b,0x8e,0xaf,0x19,0x18,0x47,0x9a,0x98,0x2f,0x0e,0x19,0xac,0x8c,0x90,0x31,0x13,0x19,0xff,0x9a,0xab,0x1d,0x1e,0x6e +,0x9b,0x91,0xd4,0x17,0x1a,0x25,0xad,0x97,0xc0,0x27,0x39,0xc2,0x9b,0xa0,0x21,0x1c,0x2d,0xd8,0xa0,0xd2,0x1a,0x2d,0xab,0x96,0x92,0x46,0x15,0x1d,0x2e,0xb1,0xa8,0x22 +,0x1c,0xdd,0x9b,0x8e,0xa1,0x18,0x17,0x30,0xbb,0x9e,0xeb,0x1e,0x3f,0xac,0x9d,0xa4,0x1e,0x14,0x2e,0xbd,0x9f,0xaa,0x1f,0x23,0xae,0x98,0x8f,0xab,0x19,0x1a,0x29,0x44 +,0xb7,0x2e,0x1c,0x6a,0xa2,0x98,0x9f,0x21,0x17,0x2d,0x5c,0xa9,0xab,0x2e,0x3d,0xa9,0x9c,0x94,0xba,0x15,0x17,0x21,0xea,0xa5,0x3f,0x1e,0x35,0xb4,0x97,0x94,0x46,0x1f +,0x25,0x2b,0xaf,0xa9,0x31,0x35,0xcc,0xa1,0x93,0xc0,0x14,0x15,0x1f,0xb5,0x97,0xbc,0x27,0x32,0xbf,0x96,0x95,0x2e,0x15,0x17,0x2a,0x9d,0x9f,0x2d,0x23,0x3a,0x9f,0x8e +,0xaa,0x1a,0x17,0x1f,0xaf,0x99,0x43,0x1d,0x2c,0xac,0x8e,0x96,0x1d,0x0d,0x13,0x48,0x91,0x98,0x2e,0x1f,0x2f,0x9f,0x8e,0xae,0x17,0x15,0x23,0xa6,0x9a,0x39,0x1b,0x2b +,0xaa,0x8d,0x98,0x1c,0x0e,0x19,0xc2,0x90,0x9e,0x24,0x1f,0x42,0x97,0x8e,0xfc,0x0f,0x0e,0x1f,0x9f,0x94,0xf0,0x23,0x33,0xac,0x93,0xa1,0x1c,0x12,0x1f,0xab,0x8f,0xa8 +,0x1b,0x19,0x3e,0x93,0x8b,0xbc,0x10,0x0b,0x19,0x9f,0x91,0xb6,0x24,0x26,0xbc,0x93,0x9f,0x1c,0x11,0x1b,0xac,0x8e,0x9c,0x2b,0x1b,0x31,0x96,0x8e,0xf3,0x0e,0x0c,0x1e +,0x98,0x90,0xed,0x18,0x1a,0xb8,0x8d,0x94,0x2d,0x0f,0x10,0xbe,0x8d,0x99,0x2b,0x19,0x2a,0x99,0x90,0x3b,0x0d,0x0b,0x2a,0x8e,0x8a,0xb7,0x14,0x10,0xd6,0x8b,0x8f,0x30 +,0x0d,0x0e,0xd0,0x8e,0x9a,0x2b,0x17,0x28,0x98,0x8f,0xe1,0x11,0x0c,0x28,0x8f,0x8d,0xbf,0x19,0x1a,0xab,0x8e,0x9f,0x18,0x0a,0x11,0x9e,0x88,0x96,0x29,0x0f,0x1c,0x9d +,0x90,0xb4,0x17,0x0e,0x2e,0x94,0x95,0x4c,0x18,0x1d,0xa4,0x8d,0x9d,0x1b,0x0a,0x13,0x9c,0x89,0x94,0x2b,0x10,0x1f,0x9f,0x96,0xd1,0x15,0x0e,0x30,0x94,0x91,0xb8,0x1b +,0x1c,0xaa,0x91,0xa2,0x20,0x0e,0x1b,0x9e,0x8f,0xa3,0x1d,0x11,0x3e,0x92,0x8f,0x66,0x0d,0x09,0x32,0x8e,0x8c,0xad,0x18,0x1a,0xaf,0x97,0xac,0x19,0x0c,0x25,0x93,0x8b +,0xa3,0x17,0x0e,0x38,0x90,0x8f,0x48,0x0c,0x0c,0xcb,0x8d,0x8e,0x7d,0x10,0x19,0xa5,0x8f,0xa2,0x18,0x0a,0x20,0x93,0x8c,0xa3,0x18,0x10,0x54,0x94,0x9b,0x23,0x0a,0x14 +,0x9b,0x88,0x90,0x21,0x0b,0x1c,0x97,0x8c,0xa5,0x11,0x09,0x2c,0x92,0x8e,0xbf,0x13,0x16,0xaf,0x8f,0xa3,0x15,0x08,0x1c,0x90,0x85,0x94,0x1e,0x0d,0x22,0x9a,0x93,0x50 +,0x0c,0x0c,0xb9,0x8a,0x8c,0x5c,0x0e,0x10,0xb5,0x91,0xa2,0x1c,0x0d,0x28,0x92,0x8b,0xa7,0x17,0x10,0x4c,0x92,0x98,0x21,0x08,0x0f,0x9f,0x86,0x8d,0x3c,0x0d,0x14,0xa9 +,0x93,0xaf,0x15,0x0e,0x46,0x8d,0x8b,0xbd,0x0f,0x0f,0xbf,0x8e,0x97,0x1f,0x08,0x10,0x9e,0x87,0x8f,0x27,0x0b,0x1c,0x9b,0x8f,0xbd,0x0e,0x0a,0x3f,0x8b,0x88,0xa1,0x14 +,0x0e,0x42,0x98,0x9f,0x1b,0x0b,0x1f,0x91,0x88,0x9b,0x15,0x09,0x25,0x94,0x8e,0xc5,0x0d,0x0d,0xb7,0x8a,0x8c,0x57,0x0c,0x16,0xa4,0x8e,0xa4,0x0f,0x07,0x28,0x8d,0x86 +,0x9a,0x12,0x09,0x2c,0x94,0x92,0x30,0x09,0x0f,0x9d,0x88,0x8d,0x2d,0x09,0x16,0xa0,0x8e,0x9d,0x15,0x09,0x2b,0x91,0x8b,0xa3,0x12,0x0f,0xc8,0x95,0x9c,0x20,0x09,0x19 +,0x97,0x88,0x8e,0x27,0x0a,0x1a,0xa1,0x94,0xb8,0x0e,0x0e,0xac,0x8c,0x8e,0xe5,0x0c,0x10,0xb2,0x91,0x97,0x25,0x0a,0x20,0x94,0x8a,0x99,0x19,0x0c,0x2e,0x9b,0x98,0x4c +,0x0c,0x0e,0xaa,0x8b,0x8c,0xcc,0x0c,0x12,0xb0,0x96,0x9f,0x1c,0x0d,0x44,0x8f,0x8c,0xa3,0x10,0x0a,0x38,0x96,0x94,0x5c,0x0c,0x15,0x9d,0x8b,0x91,0x2d,0x0a,0x19,0xa4 +,0x98,0xaf,0x11,0x0c,0xba,0x8a,0x89,0xa3,0x0e,0x0b,0x3d,0x9a,0x9a,0x2c,0x0b,0x1d,0x94,0x89,0x91,0x1e,0x07,0x18,0x9f,0x93,0xa8,0x13,0x0e,0xaf,0x8c,0x8c,0xb9,0x0b +,0x0d,0xbb,0x95,0x9c,0x1d,0x09,0x25,0x8e,0x87,0x93,0x18,0x07,0x1f,0x9e,0x96,0xbf,0x0e,0x14,0x9b,0x8a,0x8d,0x3d,0x08,0x0f,0xac,0x94,0xa0,0x17,0x09,0x3f,0x8c,0x87 +,0x98,0x11,0x07,0x29,0x9a,0x96,0x40,0x0a,0x14,0x97,0x88,0x8b,0x3f,0x09,0x15,0xaa,0x98,0xab,0x12,0x0a,0xc7,0x8b,0x8a,0xa9,0x0b,0x09,0x4f,0x95,0x95,0x3e,0x0c,0x1f +,0x96,0x8a,0x8d,0x2c,0x09,0x19,0xb2,0x9d,0xce,0x0e,0x0f,0xa3,0x8b,0x8b,0xb1,0x0c,0x0f,0xcd,0x9a,0x9b,0x24,0x0b,0x27,0x94,0x88,0x8f,0x1c,0x09,0x1d,0xb2,0x9b,0xbb +,0x10,0x16,0xac,0x8f,0x8b,0xb5,0x0e,0x17,0xbe,0x9a,0x9f,0x16,0x0b,0x37,0x91,0x88,0x94,0x13,0x09,0x1f,0xaa,0x94,0xba,0x10,0x1a,0xa9,0x8e,0x8b,0x49,0x0c,0x18,0xca +,0x9b,0xa6,0x12,0x0f,0xba,0x8e,0x88,0x9d,0x0e,0x0d,0x2e,0x9f,0x95,0x28,0x09,0x1a,0x9f,0x89,0x8a,0x2c,0x0e,0x22,0xbe,0x9b,0xbe,0x0e,0x16,0xab,0x8e,0x89,0xd6,0x0a +,0x17,0xb8,0x97,0x9a,0x15,0x09,0x28,0x99,0x88,0x8e,0x1a,0x0e,0x29,0xb2,0x99,0x3e,0x0c,0x1f,0x9d,0x8e,0x8d,0x34,0x0e,0x29,0xae,0x9d,0xb6,0x0c,0x0c,0xc9,0x90,0x87 +,0x99,0x0f,0x12,0x45,0xa4,0x98,0x27,0x0b,0x25,0xa1,0x8f,0x8f,0x28,0x15,0xdf,0xac,0xa4,0x39,0x09,0x12,0xa8,0x8f,0x8a,0xad,0x0e,0x1b,0xb3,0x9a,0x99,0x1a,0x0b,0x32 +,0xa0,0x8f,0x94,0x1c,0x14,0x5a,0xb5,0xa7,0x2f,0x0b,0x1f,0x9d,0x8f,0x8c,0xff,0x0f,0x2d,0xa2,0x99,0xae,0x0c,0x08,0x36,0x96,0x8a,0x93,0x1a,0x16,0x5e,0xad,0xa2,0x28 +,0x0b,0x25,0x9b,0x8f,0x91,0x2a,0x0f,0x54,0x9b,0x9a,0x5c,0x09,0x0a,0xc4,0x8e,0x8a,0x9f,0x11,0x17,0xaf,0x9d,0xa2,0x1c,0x0a,0x24,0x9b,0x8f,0x94,0x2c,0x15,0xc8,0x9d +,0xa7,0x23,0x08,0x11,0x9a,0x8a,0x8f,0xcc,0x0e,0x21,0x9c,0x98,0xb3,0x10,0x08,0x26,0x97,0x8e,0x95,0x29,0x1c,0xab,0x9d,0xb9,0x18,0x08,0x1c,0x97,0x8e,0x95,0x3e,0x12 +,0x37,0x9a,0x9b,0x5a,0x0d,0x0a,0x5f,0x8f,0x8e,0x9f,0x1d,0x1c,0xae,0xa1,0xbb,0x1e,0x0d,0x24,0x9c,0x96,0x9e,0x35,0x1b,0xb0,0x94,0xa4,0x24,0x09,0x0d,0xad,0x8e,0x91 +,0xa8,0x1d,0x20,0xa8,0x9e,0xbd,0x18,0x0a,0x25,0x98,0x95,0x9e,0x3e,0x22,0xa8,0x97,0xb5,0x1f,0x0a,0x0f,0xa0,0x8f,0x99,0xda,0x16,0x2b,0x94,0x98,0x71,0x13,0x09,0x2b +,0x95,0x96,0x9f,0x38,0x1f,0xab,0x9b,0xe6,0x1f,0x0d,0x1a,0x96,0x92,0xad,0x30,0x18,0xd5,0x8e,0x9c,0x2d,0x0f,0x09,0x42,0x90,0x9c,0xae,0x2e,0x24,0x9b,0x94,0x76,0x1c +,0x0c,0x1a,0x97,0x9a,0xd3,0x38,0x23,0xac,0x8e,0xab,0x20,0x0f,0x0d,0xaa,0x8d,0x9d,0xc3,0x21,0x1e,0x9c,0x98,0x3f,0x1d,0x0d,0x1e,0x98,0x9b,0xb8,0x61,0x2b,0xa7,0x91 +,0xda,0x1b,0x11,0x14,0xa0,0x90,0xae,0x42,0x1e,0x29,0x96,0x9a,0x35,0x1a,0x0d,0x2c,0x91,0x9a,0xc1,0x3d,0x2a,0xa6,0x97,0x38,0x1b,0x15,0x19,0x9d,0x97,0xf8,0x36,0x27 +,0xca,0x8f,0x9d,0x26,0x16,0x0f,0x6f,0x8e,0xa3,0x3f,0x2b,0x22,0xa6,0x9a,0x36,0x21,0x1a,0x26,0x97,0x9b,0x3c,0x37,0x28,0xb9,0x91,0xb6,0x1d,0x19,0x19,0xa8,0x8f,0xb4 +,0x35,0x2b,0x35,0x97,0x99,0x2f,0x1e,0x14,0x20,0x9e,0xb5,0x27,0x2c,0x26,0xb2,0x97,0x4f,0x1f,0x21,0x29,0x99,0x90,0xbe,0x41,0x38,0xc4,0x92,0x9c,0x2f,0x1e,0x15,0x30 +,0x99,0xa9,0x3f,0x3d,0x34,0xa8,0x9e,0x2f,0x1d,0x19,0x1d,0xa9,0xa2,0x33,0x2f,0x2b,0xeb,0x99,0xb1,0x23,0x1b,0x18,0xc7,0x93,0xa7,0xf0,0x43,0x3b,0x9e,0x9b,0x43,0x2a +,0x21,0x2f,0x9c,0xa1,0x52,0x6b,0x47,0xab,0x96,0xb9,0x25,0x1e,0x1b,0xbb,0x9b,0x68,0x2d,0x2a,0x2e,0xa1,0xa7,0x2c,0x29,0x1e,0x2f,0x9e,0xae,0x41,0x56,0x30,0xb9,0xa3 +,0x2d,0x1f,0x1f,0x1f,0xab,0x9d,0x6e,0x53,0x3f,0xda,0x9a,0xab,0x33,0x36,0x25,0xdb,0x9a,0xb4,0x4d,0x51,0x2d,0xb0,0xa3,0x3d,0x47,0x3a,0x33,0x9e,0xa0,0x4a,0x71,0x2f +,0x44,0xa1,0x6f,0x27,0x2c,0x1d,0x68,0x9f,0xdd,0x46,0x3a,0x27,0xb5,0xac,0x36,0x41,0x2b,0x29,0xa9,0xb9,0x33,0x51,0x2d,0xd7,0x9d,0xe3,0x34,0x41,0x29,0xb3,0x9d,0xe1 +,0xe8,0x47,0x2d,0xa9,0xab,0x39,0x4d,0x2a,0x33,0x9f,0xb3,0x47,0xcf,0x38,0xb7,0x9f,0x5e,0x40,0x49,0x2b,0xae,0xa2,0x3b,0x3b,0x2f,0x2f,0xa3,0xac,0x3b,0x64,0x2c,0x3c +,0xa2,0xcf,0x42,0xcc,0x2b,0x55,0xb3,0x2c,0x35,0x40,0x29,0xaf,0xae,0x2c,0x52,0x3a,0x32,0xa3,0xbb,0x34,0xea,0x28,0x36,0xac,0x33,0x31,0xc7,0x37,0xb1,0xa2,0x3a,0x75 +,0xd3,0x38,0xa2,0xa9,0x37,0xb6,0x7b,0x47,0xa3,0x7a,0x30,0xcc,0x35,0xbb,0x9c,0x53,0x4a,0xca,0x2b,0xb7,0xa8,0x3f,0xbf,0x4a,0x27,0xb4,0x72,0x25,0x66,0x32,0x3f,0xa6 +,0x43,0x2d,0x7a,0x2f,0xc9,0xa6,0x39,0x47,0x59,0x26,0xc6,0xc8,0x25,0x3c,0x37,0x3a,0xa7,0xd8,0x2e,0xbd,0x4b,0xc6,0x9f,0xd8,0x4e,0xbe,0x41,0xb5,0xac,0x2d,0x44,0xdb +,0x3e,0xa7,0xb3,0x2d,0xde,0x62,0xdc,0x9f,0xb3,0xf4,0xb0,0x38,0x3d,0xb8,0x2f,0x3c,0xb4,0xda,0xb2,0xbb,0x27,0x67,0xe2,0x32,0xb1,0xf5,0x2b,0xe5,0x4a,0x41,0xbb,0x30 +,0x2d,0xd4,0x33,0x7b,0xbd,0x27,0x3a,0xc2,0x50,0xb1,0xbf,0x2d,0xe4,0x42,0x2f,0xb9,0x3c,0x2b,0xd6,0xcf,0xb7,0xac,0x3f,0x3d,0xec,0x31,0xb9,0xa7,0x61,0xb9,0xb7,0x4f +,0xb7,0xcd,0x49,0xb0,0xd0,0x53,0xb1,0x3f,0x38,0xb5,0xb7,0xac,0xa8,0xd6,0xd5,0xce,0x32,0xbf,0xc9,0x29,0xec,0xc0,0xe8,0xbd,0x3f,0x2d,0x3d,0x2f,0x51,0xb4,0x31,0x2c +,0x69,0x49,0xcd,0xe7,0x2d,0x36,0x3e,0x4a,0xad,0xec,0x24,0x3c,0x3f,0x48,0xb3,0xc5,0x65,0x50,0x31,0x68,0xce,0x2f,0x45,0xb7,0xc6,0xbe,0xc6,0x55,0xba,0xbe,0xb8,0xa3 +,0xdb,0x33,0xc7,0xbe,0xbf,0xb3,0xcd,0xf3,0xe1,0xe3,0xb4,0xd3,0x2b,0x40,0xb9,0xbd,0xad,0xaf,0xeb,0xee,0x4e,0xcc,0xc2,0x2b,0x26,0x4e,0xdc,0xbf,0xb6,0x45,0x32,0x36 +,0x4d,0xb7,0xce,0x34,0x44,0x4d,0x35,0xd9,0xc9,0x4c,0x4e,0x41,0x4f,0x36,0x1f,0x2c,0xc1,0xcb,0xba,0xb3,0x49,0x3e,0x50,0xf3,0xbc,0x65,0x39,0xbf,0xbd,0xc4,0xab,0xc4 +,0x40,0xe6,0xcf,0xb4,0xc2,0x2f,0x61,0xc1,0x4f,0xbb,0xac,0x5d,0x48,0xd0,0xbd,0xad,0x45,0x2f,0xd8,0x4a,0xbc,0x9f,0xb8,0x3e,0x3b,0x36,0x5b,0xd8,0x3d,0xda,0x45,0x29 +,0xd3,0xf6,0x2d,0x4d,0xc7,0xb7,0xb9,0x32,0x3c,0xcf,0x34,0xcd,0xa3,0x59,0x36,0x5f,0x55,0xbe,0x40,0x2a,0x4b,0x34,0x41,0xa3,0xba,0x38,0xd2,0xe8,0xc5,0xb5,0x42,0x7e +,0xfa,0x30,0xac,0xa9,0x2c,0x33,0x5f,0xd6,0xad,0x7e,0x34,0x3c,0x1f,0x42,0x9d,0xaf,0xd8,0xc5,0x3b,0xdf,0xc1,0x3f,0xb7,0xcb,0x40,0xa4,0xbc,0x28,0x4d,0x44,0x53,0xb3 +,0x40,0x3b,0x43,0x28,0xb4,0xa1,0x37,0x43,0xcd,0x58,0xac,0xbd,0x3d,0xcd,0x2d,0x3e,0x9d,0xbb,0x3c,0xf1,0x2a,0x45,0xbe,0x30,0x49,0x3b,0x2e,0xa3,0xa7,0x35,0x5a,0x35 +,0x30,0xa7,0xae,0xb6,0xc1,0x1e,0x3d,0xa8,0x48,0xe9,0xcd,0x2f,0xe5,0x5a,0x2e,0xce,0x30,0x38,0x9e,0xbe,0x3f,0xc6,0x2b,0x67,0xa7,0x66,0xce,0x45,0x24,0xa7,0xa8,0x2b +,0x56,0x2c,0x2b,0xa8,0xbc,0xd6,0xca,0x1b,0x47,0x9b,0x73,0xbe,0xbd,0x2a,0xa7,0xa8,0x34,0xbe,0x24,0x1f,0x9c,0xaf,0x44,0xbb,0x1c,0x2b,0xa6,0x4e,0xb1,0xcf,0x1b,0xab +,0xa4,0x29,0xaf,0x5e,0x28,0x9d,0xbb,0x43,0xae,0x1c,0x33,0x9b,0x38,0x51,0xc5,0x18,0xc9,0xa4,0x2a,0xb9,0x2b,0x1a,0x9a,0xa9,0x46,0xa2,0x1f,0x22,0x9a,0xd7,0xba,0xaa +,0x16,0xc7,0x9d,0x22,0xcc,0x35,0x14,0xa1,0xa3,0x40,0xa3,0x1a,0x19,0x96,0xc6,0xbc,0x9d,0x18,0x3b,0x9b,0x2f,0xae,0xce,0x12,0xa2,0xa8,0x1f,0xa3,0x22,0x18,0x94,0xaf +,0x60,0xa2,0x15,0x2f,0x92,0x36,0xb0,0xb9,0x0e,0xad,0x9a,0x39,0x9e,0x24,0x0d,0x9d,0xb7,0x3b,0x9b,0x15,0x1f,0x92,0x6d,0xad,0xb1,0x0c,0xce,0x97,0x32,0x9b,0x43,0x0d +,0x9e,0xa0,0x66,0x98,0x19,0x15,0x9b,0x2e,0xd6,0xa3,0x0d,0x43,0x94,0x2b,0xa4,0x5e,0x0d,0x9d,0x9c,0x47,0x99,0x1d,0x12,0x92,0xb1,0xbe,0xa2,0x0b,0x22,0x96,0x37,0xa3 +,0xc3,0x09,0xb6,0x99,0x5f,0x95,0x24,0x0e,0x98,0xac,0xb7,0x9a,0x0d,0x18,0x97,0xef,0xa2,0xac,0x0a,0x44,0x9d,0x4b,0x95,0x37,0x0e,0x9d,0xa5,0xc5,0x9a,0x14,0x17,0x96 +,0xc9,0xa8,0xaa,0x0a,0x34,0x9a,0x4b,0x9c,0x33,0x0b,0xa2,0x9c,0xbd,0x97,0x16,0x0f,0x9b,0xae,0xa4,0xa2,0x0c,0x23,0x99,0xbc,0x96,0xeb,0x0a,0xc0,0xa0,0xbb,0x98,0x16 +,0x0c,0xa6,0xb3,0xa2,0x9a,0x0e,0x1d,0x9c,0xc5,0x98,0xb6,0x0d,0xd3,0x9f,0xba,0x98,0x1e,0x0d,0xaa,0xab,0xa6,0x9d,0x0e,0x18,0x9e,0xb7,0x9a,0xb4,0x0d,0x40,0x99,0xa2 +,0x96,0x1f,0x0a,0xcb,0xaa,0x9e,0x9d,0x0f,0x15,0xa7,0xac,0x99,0xa9,0x0e,0x2e,0x9e,0xaa,0x97,0x27,0x0c,0xec,0xa5,0x9d,0x95,0x18,0x0f,0xc6,0xc6,0xa0,0xab,0x0e,0x25 +,0x9e,0xa9,0x97,0x54,0x10,0xea,0xac,0xb2,0x9e,0x1b,0x13,0xa7,0xa3,0x9a,0xa1,0x12,0x20,0xa8,0xbf,0x9d,0x38,0x0a,0x2d,0xa9,0xa2,0x92,0x2e,0x13,0xca,0xbd,0xac,0xa5 +,0x18,0x25,0x9d,0xa8,0x9c,0xbd,0x0f,0x2a,0xab,0xbc,0xa1,0x29,0x0f,0xd4,0xab,0xa5,0x99,0x28,0x22,0xab,0xe4,0xb1,0xbb,0x14,0x2d,0xa4,0xbe,0x9e,0x74,0x16,0xd9,0xb6 +,0xd3,0xa4,0x22,0x18,0xab,0xac,0xa0,0x9f,0x1b,0x2a,0xad,0xe2,0xa3,0xe2,0x15,0x3c,0xb9,0xca,0x9f,0x40,0x21,0xb0,0xe6,0xfe,0xaf,0x1a,0x1d,0xad,0xb0,0x9c,0xa4,0x1c +,0x3a,0xb2,0x51,0xa3,0x4c,0x1a,0xcc,0xcb,0xc7,0x9f,0x2a,0x25,0xaf,0x49,0xbd,0xb9,0x1a,0x2a,0xb0,0xd1,0x9f,0xaf,0x22,0xc1,0xb5,0x70,0xaa,0x2e,0x1e,0xcc,0xed,0xaf +,0xa3,0x2a,0x3a,0xbb,0x30,0xae,0xb8,0x22,0xca,0xba,0x66,0xa5,0x33,0x1f,0xad,0xb8,0xb6,0xa4,0x27,0x28,0x5d,0x2c,0xd0,0x54,0x20,0x72,0x5a,0x32,0xa2,0x9c,0x9e,0xa5 +,0xf2,0x2c,0x3d,0x33,0x1f,0x25,0xba,0x93,0x91,0xb2,0x1f,0x16,0x16,0x24,0x23,0x24,0x2c,0x34,0x8f,0x85,0x8c,0x93,0x39,0x04,0x04,0x19,0x2c,0xac,0x94,0x8b,0x87,0x8a +,0x33,0x01,0x03,0x98,0x80,0xcf,0x15,0x1d,0x4a,0x97,0x87,0x3b,0x03,0x01,0x18,0x8f,0x8d,0x91,0xb5,0x30,0xb9,0x9c,0xc8,0x2d,0x9d,0x87,0x8e,0xa5,0x2f,0x09,0x06,0x06 +,0xb8,0x94,0x14,0x01,0x08,0x98,0x83,0x85,0xcf,0x17,0x45,0x94,0x8b,0x97,0xb1,0x97,0x91,0x1d,0x0e,0x29,0x58,0x1c,0x19,0x23,0x23,0x16,0x35,0xc0,0xc1,0x8e,0x93,0x18 +,0x0f,0x1e,0x2f,0x8e,0x83,0x98,0x14,0x18,0xb9,0x8c,0x98,0xcb,0x2c,0x06,0x02,0x0e,0xb5,0x9c,0x88,0x87,0x99,0x48,0x1a,0x08,0x01,0xb6,0x80,0x83,0xd2,0x18,0x39,0xe8 +,0xa9,0x38,0x06,0x01,0x00,0x41,0x80,0x82,0x8f,0xa3,0x92,0xcb,0x0e,0x0c,0x3a,0x8e,0x83,0x85,0xae,0x11,0x0f,0x17,0x13,0xdd,0x19,0x03,0x00,0x0e,0x86,0x80,0x83,0x9d +,0x53,0x31,0x3e,0x2f,0x20,0xab,0x92,0x8f,0xd8,0x1e,0x1b,0x25,0x9c,0x8f,0x1d,0x02,0x0a,0x2e,0xdf,0x9b,0x8c,0xb7,0x27,0x41,0xc5,0x65,0xac,0x8f,0xa7,0x33,0xa5,0x8c +,0x8b,0xac,0x57,0x27,0x0a,0x01,0x03,0x1d,0xa2,0x97,0x8f,0x9d,0x2f,0x16,0x15,0x24,0xa5,0x91,0x95,0x94,0x98,0x9c,0xa4,0xc5,0x2c,0x0d,0x05,0x05,0x1c,0x91,0x8f,0x9e +,0xab,0xae,0x30,0x18,0x20,0x99,0x85,0x84,0x9c,0x1e,0x28,0x20,0x0f,0x20,0xb0,0x1b,0x08,0x20,0x91,0x93,0xbb,0xab,0xcc,0x1e,0x10,0x11,0x14,0xa8,0x83,0x81,0x90,0x0e +,0x08,0x1b,0x9d,0x91,0xa9,0x13,0x0a,0x4b,0x9f,0x9d,0x5c,0x36,0x4c,0x1c,0x0f,0x0e,0x1b,0xae,0x8c,0x88,0x8d,0xa7,0x2d,0xd4,0x91,0x9a,0x16,0x05,0x03,0x11,0x9a,0x83 +,0x83,0x8f,0x36,0x13,0x1e,0x17,0x0c,0x19,0x9b,0x89,0x91,0x9d,0xbb,0x1a,0x22,0x2b,0x0b,0x01,0x07,0xc3,0x88,0x82,0x87,0x8e,0xb2,0x1d,0x1a,0x21,0x41,0xae,0x97,0xab +,0x37,0x47,0xb3,0xd6,0x1f,0x0f,0x0a,0x07,0x10,0xbb,0x8f,0x85,0x8c,0xaf,0x2b,0x2c,0x24,0x29,0x9c,0x8f,0x9e,0x26,0x13,0x1d,0xac,0x8c,0x92,0x42,0x0e,0x0b,0x21,0xb6 +,0xbd,0xc5,0xaa,0xab,0xed,0xcd,0x3e,0x27,0xaf,0x9f,0xae,0x32,0x47,0xb1,0x97,0x93,0xaf,0x1b,0x06,0x01,0x0a,0xaf,0x8b,0x8d,0x99,0xbf,0x38,0xc5,0x79,0x3e,0xe3,0xa3 +,0x96,0xa0,0xc9,0x27,0x2b,0xbf,0x49,0x11,0x06,0x08,0x23,0x95,0x89,0x8f,0xa3,0xc3,0xb2,0xe4,0x2b,0xb6,0x99,0x96,0x9f,0x49,0x2a,0x23,0x17,0x12,0x1b,0x1e,0x19,0x34 +,0xb0,0x9b,0x8f,0x94,0xb2,0x2b,0x25,0x23,0x4c,0x9b,0x8e,0x92,0xe1,0x10,0x10,0x36,0xa4,0xa7,0x30,0x13,0x16,0x33,0xc3,0xdb,0x55,0xac,0x9c,0xa3,0xed,0x26,0x38,0x9f +,0x9d,0xa8,0xb0,0xb0,0xaf,0xbe,0xcf,0x32,0x16,0x08,0x08,0x15,0xb0,0x8e,0x92,0xaa,0xb9,0xac,0xaf,0x4b,0x26,0x38,0x9d,0x8f,0x98,0xac,0x29,0x1d,0x2e,0x2e,0x13,0x07 +,0x07,0x27,0x8d,0x84,0x89,0xa5,0x3c,0x27,0x22,0x2f,0xf5,0xad,0x9b,0x96,0x9f,0xbe,0x29,0x15,0x0f,0x11,0x12,0x17,0x2f,0xad,0x96,0x8f,0x9d,0xb9,0x31,0x1f,0x29,0xe8 +,0x9e,0x94,0x9f,0xdc,0x46,0xec,0xac,0xa0,0xb8,0x23,0x18,0x1b,0x26,0x25,0x1c,0x31,0xa2,0x9c,0xbf,0x1e,0x1b,0xc1,0x95,0x96,0xa7,0xb3,0xa4,0x9e,0xa9,0xb3,0x50,0x1b +,0x0c,0x08,0x10,0xd3,0x9c,0x9f,0xb6,0xc4,0xac,0xa9,0x52,0x23,0x29,0xbc,0x96,0x93,0xa3,0xdc,0x3b,0x32,0x1e,0x0f,0x0c,0x15,0x3f,0x9c,0x8e,0x8f,0x9a,0xac,0x42,0x2d +,0x2c,0x2d,0xcf,0x9d,0x92,0x95,0xba,0x1b,0x0f,0x10,0x18,0x1e,0x20,0x33,0xbb,0xa5,0x9a,0x9a,0xaa,0x4d,0x26,0x1d,0x2f,0xa6,0x9a,0x9b,0xa5,0xc8,0xb4,0xa7,0xbd,0x2b +,0x15,0x15,0x2c,0x50,0x2a,0x1f,0x2d,0xad,0x9a,0xac,0x23,0x1b,0x3b,0xa7,0x9f,0xa0,0x9a,0x98,0x9f,0xb4,0x3a,0x24,0x1e,0x14,0x0f,0x18,0x2e,0xb1,0x9c,0x98,0x95,0x9a +,0xbe,0x1d,0x13,0x22,0xa6,0x98,0xa2,0xd7,0x3e,0xcb,0xb9,0x22,0x0f,0x0d,0x11,0x35,0x9a,0x8e,0x8d,0x94,0xaa,0xd9,0x51,0x2b,0x1e,0x27,0xbd,0x9a,0x9d,0x69,0x20,0x1c +,0x1f,0x25,0x1b,0x1c,0x2e,0xc4,0x9e,0x9a,0xa3,0xa5,0xac,0x32,0x23,0x26,0x54,0xa0,0x9c,0xab,0xc2,0xbf,0xba,0xb2,0xdf,0x36,0x34,0x22,0x1c,0x1d,0x21,0xc7,0xa2,0xbb +,0x2f,0x25,0x3f,0x9e,0x98,0xa9,0xbd,0xc1,0xad,0xa3,0xaf,0x5a,0x34,0x26,0x1b,0x17,0x1d,0x46,0xaf,0xa8,0xa1,0xa6,0xb7,0xce,0x2c,0x24,0xd1,0xac,0xae,0xc2,0x35,0x4d +,0xbc,0x31,0x18,0x17,0x1c,0x2c,0xc3,0xa9,0x96,0x8d,0x93,0xab,0x2a,0x1d,0x22,0x2e,0xbe,0x9a,0x9a,0xad,0x58,0x24,0x29,0x3b,0x1c,0x0e,0x11,0x29,0x9d,0x8f,0x9a,0xac +,0xb3,0xe3,0x3b,0x26,0x25,0xe1,0xa3,0x9d,0x9f,0xad,0xa2,0x9f,0xfe,0x2b,0x1b,0x10,0x11,0x1c,0x23,0x52,0xae,0xb3,0xaf,0xc6,0x5b,0xbe,0xb6,0xcf,0xde,0xae,0x9d,0x99 +,0xa3,0xbc,0x4f,0x2e,0x22,0x10,0x0c,0x19,0x42,0xa2,0x93,0x98,0xa6,0x9d,0x9e,0xb8,0x3c,0x20,0x1c,0x25,0x40,0xad,0x9a,0xa4,0x39,0x19,0x10,0x19,0x22,0x2e,0xc7,0x9f +,0x94,0x90,0x9f,0xb5,0xa3,0xad,0x40,0x25,0x1b,0x23,0xce,0xb9,0xe0,0x46,0x25,0x21,0x23,0x2a,0x6b,0xb9,0xc4,0x76,0x65,0xaf,0x9e,0xb2,0x4b,0xc6,0xa8,0x9d,0xa9,0x27 +,0x24,0xcb,0xa8,0xa3,0xba,0x24,0x1d,0x31,0x47,0x3f,0x2a,0x20,0x1f,0x22,0x36,0xae,0x99,0x92,0x97,0xaa,0xc4,0xcf,0xea,0xcc,0x67,0x32,0x2c,0x1e,0x15,0x1e,0xc8,0xa6 +,0xa3,0xbe,0x32,0xe8,0xa6,0x9e,0xaa,0x4d,0x30,0x49,0x4d,0x55,0x4c,0x3e,0x51,0x2e,0x19,0x19,0x2c,0x3f,0xb6,0x9f,0x95,0x91,0xa6,0x29,0x21,0x3f,0xb3,0xac,0x7e,0x3f +,0xbb,0xa4,0xa3,0xd2,0x29,0x21,0x16,0x0f,0x16,0x37,0xa0,0x93,0x9c,0xbb,0xce,0x3f,0x2a,0x3a,0xbf,0xab,0xa8,0xcc,0xd0,0x9e,0x93,0x97,0xba,0x1b,0x10,0x14,0x1e,0x2a +,0x28,0x2c,0xef,0xaf,0xae,0xb7,0x55,0x4f,0xb2,0xac,0xb0,0xb5,0xb7,0xb0,0xa4,0x9e,0x9e,0xee,0x13,0x0a,0x0a,0x1a,0xbd,0xa5,0xa4,0xa0,0x9f,0x9b,0x98,0xad,0x37,0x31 +,0x29,0x21,0x1e,0x22,0xdb,0x9c,0xa0,0x3e,0x1c,0x13,0x17,0x32,0xa6,0x98,0x9b,0xae,0xd6,0xb1,0x98,0x98,0xc9,0x1f,0x1c,0x38,0xb5,0xd7,0x26,0x2d,0xd3,0xc7,0x54,0x22 +,0x19,0x28,0xc4,0xab,0xae,0xeb,0x45,0x5e,0xae,0x99,0x8f,0x9f,0x36,0x23,0x2b,0xbe,0xaa,0xc4,0x34,0x36,0x3e,0x3c,0x2c,0x1d,0x1f,0x3d,0xde,0x3e,0x27,0x2d,0xae,0x92 +,0x8e,0x9b,0xc7,0x30,0x2f,0xdb,0xb9,0x3e,0x1d,0x1b,0x22,0x48,0xa6,0xa9,0x4c,0x37,0x4f,0xad,0x9e,0xb9,0x24,0x29,0xba,0x9a,0x9a,0x53,0x1a,0x1e,0x4b,0xd5,0x2c,0x19 +,0x18,0x2a,0xb0,0x97,0x90,0x97,0xb8,0x28,0x28,0x4f,0xf1,0x49,0xf1,0xa8,0x98,0x99,0xc4,0x21,0x1c,0x33,0x4c,0x1d,0x0d,0x11,0x47,0x98,0x91,0xa3,0xf8,0x3d,0x47,0xd2 +,0xb0,0xcd,0x3a,0x68,0xa8,0x94,0x8f,0xa0,0x2b,0x19,0x1e,0x32,0x33,0x17,0x0e,0x1e,0xaf,0x9a,0xa0,0x66,0x29,0x4d,0x9d,0x9a,0xb5,0x31,0x2f,0xbd,0x99,0x96,0xaf,0x26 +,0x14,0x13,0x1d,0x2d,0x2f,0x36,0xc7,0x9d,0x92,0x96,0xaa,0x3c,0x3a,0xd1,0xcb,0x1f,0x12,0x1f,0xae,0x99,0xa9,0x26,0x15,0x1d,0xca,0xa0,0xaf,0x2d,0x26,0xdd,0x9d,0x8f +,0x92,0xb4,0x21,0x21,0xb7,0x9d,0xaf,0x1d,0x10,0x22,0xa9,0x9f,0x42,0x17,0x17,0x3e,0xa6,0xae,0x37,0x2d,0x42,0xb0,0x9f,0x9f,0x9f,0xa7,0xb6,0xb5,0xad,0x40,0x1c,0x1d +,0x3a,0xac,0xa4,0xed,0x1c,0x1b,0x49,0xb4,0x45,0x1b,0x19,0x50,0x9c,0x95,0xa0,0xc9,0x7b,0xa9,0x99,0xa6,0x2f,0x13,0x10,0x22,0xb1,0xa2,0xba,0x33,0x2e,0xb8,0x9c,0x9f +,0x46,0x1c,0x1e,0xcc,0x9c,0x9f,0xc4,0x2e,0x33,0xc0,0xbc,0x26,0x14,0x19,0x2e,0xc1,0xaa,0xab,0xb4,0xab,0xa1,0xa6,0xc4,0x2c,0x26,0x3b,0xcb,0xa8,0x9e,0xa4,0xcd,0x5c +,0xc5,0x3a,0x19,0x0e,0x14,0x42,0xa3,0xab,0x3b,0x31,0xcb,0x9e,0x9a,0xaf,0x2b,0x25,0x3f,0xae,0x9b,0x99,0xa5,0x44,0x2c,0x47,0xb9,0x45,0x1b,0x13,0x18,0x35,0xac,0xa8 +,0xcc,0xe2,0xae,0xa4,0xb5,0x31,0x2d,0xce,0xa8,0xa6,0xb2,0x4c,0x2b,0x31,0xe2,0xce,0x3d,0x23,0x22,0x3f,0xb9,0xaa,0xa0,0xa2,0xad,0xad,0xb3,0x2c,0x17,0x1b,0x38,0xab +,0xa6,0xe9,0x24,0x1d,0x38,0xa2,0x9d,0x5c,0x1e,0x26,0xfe,0xaa,0xa2,0xa9,0xbf,0xd5,0xc5,0xbf,0xc0,0xd3,0x4a,0x31,0x2d,0x38,0xfa,0xcb,0x50,0x51,0xe5,0x4a,0x27,0x1c +,0x27,0xbc,0xa6,0xab,0xb6,0xb6,0xaf,0xa9,0xa1,0xaa,0xd8,0x47,0x3d,0x2e,0x2b,0x46,0xbb,0x51,0x2e,0x3b,0x48,0x2b,0x20,0x2b,0x50,0xb0,0xa1,0xa1,0xaf,0xb2,0xa9,0xab +,0xc5,0x2a,0x1e,0x21,0x2c,0x54,0xb7,0xbc,0x43,0x36,0xe3,0xb6,0xb8,0xbb,0xc0,0xe0,0x3a,0x3e,0xc3,0xb2,0xb6,0xc4,0xdc,0x3e,0x29,0x23,0x27,0x3a,0xc6,0xaf,0xb0,0xd6 +,0x71,0xba,0xaf,0xde,0x39,0x61,0xb6,0xb1,0xb4,0xb3,0xba,0x64,0x36,0x37,0x3b,0x2e,0x2a,0x27,0x27,0x43,0xb1,0xae,0x4f,0x39,0xb5,0xa5,0xb9,0x4b,0xde,0xc7,0xdf,0xba +,0xa6,0xa8,0xcc,0x39,0x37,0x2b,0x29,0x41,0x46,0x33,0x3a,0x71,0x51,0x38,0x52,0xb0,0xaa,0xb9,0xd1,0x5c,0x54,0xf5,0xdb,0xc9,0xed,0x4c,0x51,0xf5,0xd3,0x47,0x47,0x46 +,0x3b,0xce,0xa7,0xa3,0xbb,0x4b,0xfa,0xf4,0x36,0x38,0x49,0x46,0x3c,0x49,0xba,0xbe,0x44,0x4e,0xba,0xc6,0x3c,0x37,0x34,0x32,0xe7,0xab,0xa9,0xbf,0xe6,0xae,0xa7,0xb9 +,0xbd,0xc7,0x30,0x22,0x2b,0x68,0x5e,0x32,0x37,0x39,0x2a,0x27,0x30,0x48,0xe0,0xab,0x9e,0xa4,0xb9,0xbf,0xad,0xb3,0x60,0xd6,0xb8,0x6b,0x3a,0x43,0x3b,0x29,0x26,0xeb +,0xad,0x76,0x2e,0x26,0x22,0x3d,0xa2,0x96,0x9c,0xc1,0x27,0x24,0x2f,0x4e,0xaa,0xa1,0xb2,0x3e,0x3b,0xbb,0xc0,0xc8,0xbb,0xca,0x45,0x41,0xd9,0x62,0x36,0x32,0x3b,0x3d +,0x32,0x36,0x41,0x2b,0x24,0x48,0xc3,0x4f,0x4e,0xbf,0xab,0xac,0xaa,0x9f,0xb3,0x3f,0x67,0xad,0xa1,0x9e,0x9e,0xa7,0x3d,0x1d,0x1e,0x2e,0x34,0x29,0x2d,0x2b,0x1f,0x24 +,0x30,0x3d,0x3f,0x47,0xc4,0xaf,0xb3,0xb9,0xc8,0xb9,0xa4,0x99,0x93,0x9d,0xcd,0x39,0x30,0x2a,0x37,0xc4,0xd7,0x30,0x2a,0x2b,0x26,0x21,0x2c,0x5e,0xfb,0x4a,0x3c,0x44 +,0x7d,0xe8,0xac,0x9f,0xaf,0x5e,0xe0,0xb4,0xbf,0xc1,0xaf,0xb3,0xb9,0xb5,0xae,0xad,0xcd,0x38,0x35,0x31,0x28,0x25,0x29,0x38,0x4c,0xc3,0xc3,0x28,0x1a,0x1e,0x30,0xcd +,0xa8,0xa3,0xb4,0xcb,0xba,0xa4,0x9c,0x9f,0xad,0xc3,0x53,0x43,0xc7,0xae,0xb8,0xe6,0x4d,0x3a,0x20,0x19,0x1c,0x1d,0x20,0x32,0x64,0xd8,0x56,0x43,0xbb,0xab,0xb2,0xaf +,0xac,0xb4,0xc9,0xb3,0xa4,0xa6,0xa8,0xa9,0xce,0x2d,0x28,0x2f,0x3c,0x49,0x3e,0x32,0x41,0xeb,0xdd,0xb7,0xbf,0x2e,0x22,0x22,0x34,0xc5,0xac,0xa7,0xb2,0xba,0xbe,0xc8 +,0x6a,0x3f,0x64,0xc1,0xbd,0xc0,0xb6,0xaf,0xda,0x4d,0xcc,0x50,0x2c,0x2a,0x36,0x34,0x28,0x3a,0xc3,0xc2,0xd3,0xd7,0x55,0x2d,0x26,0x39,0xb9,0xb0,0xbd,0xc2,0xb0,0xa7 +,0xa8,0xaf,0x77,0x2f,0x3b,0xbd,0xab,0xb4,0x47,0x2d,0x37,0xd6,0xc1,0xc5,0x3a,0x1c,0x1a,0x2d,0xc5,0xae,0xa8,0xac,0xc5,0xd0,0xb1,0xb9,0x49,0x3b,0x3f,0xdd,0xe8,0xbc +,0xa6,0xab,0xc0,0x42,0x34,0x2e,0x33,0xe1,0xc7,0x44,0x37,0x4c,0x68,0xe1,0xd9,0xd6,0x41,0x24,0x23,0x38,0xc3,0xbb,0xc2,0xc1,0xb8,0xb3,0xba,0xb9,0x69,0x3b,0x61,0xbe +,0xce,0x5d,0xdd,0xc3,0xbe,0xcc,0xe0,0x3a,0x29,0x24,0x2c,0xf1,0xc0,0xbe,0xb8,0xb0,0xba,0xbb,0xaf,0xd8,0x33,0x33,0x3e,0x46,0x6f,0xb5,0xa5,0xac,0x4f,0x3b,0x34,0x36 +,0x60,0xbc,0xca,0x2e,0x3b,0xad,0xa6,0xbb,0x4a,0x32,0x29,0x2b,0x4d,0xb7,0x6f,0x2f,0x3c,0xc6,0xac,0xad,0xbe,0x42,0x28,0x28,0x61,0xaf,0xc2,0xd5,0xb4,0xad,0xb9,0xd8 +,0xfb,0x45,0x2d,0x26,0x26,0x2e,0xf4,0xac,0xa6,0xaf,0x62,0x62,0xd4,0x43,0x49,0xc6,0xbf,0x41,0x3c,0xbf,0xa7,0xa6,0xb7,0x55,0x32,0x2c,0x31,0xd4,0xd3,0x57,0xc1,0xb1 +,0xc8,0x37,0x3f,0x42,0x2f,0x27,0x3a,0xc8,0xca,0xc1,0xb3,0xa6,0xac,0xb2,0xc7,0x2e,0x1f,0x2a,0x75,0x64,0x3f,0x3e,0x6e,0xe6,0x65,0xb7,0xab,0xcf,0x32,0x2d,0x35,0xd4 +,0xa6,0x9a,0x9d,0xc6,0x2b,0x2f,0x3c,0x2d,0x2d,0x3d,0x36,0x32,0xbf,0xa3,0xa8,0xc9,0xcf,0x67,0x40,0x57,0xcd,0xdc,0x3a,0x46,0xa6,0x9d,0xdc,0x2f,0x3d,0x3e,0x36,0x34 +,0x34,0x38,0x52,0xbf,0xa8,0xa8,0xb8,0xb8,0xc4,0x34,0x2a,0x3a,0x41,0x38,0x59,0xae,0xac,0x52,0x2b,0x3a,0x68,0x5f,0x36,0x26,0x1e,0x30,0xa2,0x95,0x9f,0x55,0x3c,0x68 +,0xc9,0xcb,0x78,0x4a,0x3c,0xf1,0x9f,0x9a,0xad,0x4c,0x2c,0x1e,0x1e,0x2f,0x4c,0x39,0x36,0xbf,0x9d,0xa0,0xf7,0x4c,0x5c,0x36,0x35,0x49,0x3f,0x3d,0xb6,0xa0,0xa8,0xe5 +,0xe1,0xba,0x48,0x2c,0x29,0x36,0x45,0xd4,0xa9,0xa6,0xc0,0x3d,0x42,0x3f,0x37,0x32,0x27,0x20,0x2b,0xaf,0x97,0x9e,0x56,0x3c,0xd8,0x44,0x2b,0x22,0x2a,0x5b,0xbc,0xaf +,0xa7,0xa4,0xa7,0xa5,0xbb,0x2d,0x27,0x3d,0xfd,0xee,0xc1,0xb0,0xb7,0x3d,0x32,0x49,0x32,0x1e,0x1a,0x2a,0xc5,0xa2,0x99,0xa3,0x56,0xcf,0x9e,0xa6,0x46,0x25,0x21,0x2d +,0x59,0xaf,0xab,0xd7,0x36,0x6f,0xc2,0x3d,0x25,0x1c,0x1e,0x3a,0xa8,0x96,0x9c,0xb9,0xdf,0xbd,0x71,0x33,0x26,0x1f,0x27,0x38,0xbe,0xb2,0xb1,0xae,0xa4,0xae,0x3a,0x1e +,0x1f,0xe6,0xab,0xa7,0xaa,0xcd,0x61,0xac,0xa7,0xc6,0x28,0x18,0x18,0x2b,0xbe,0x9e,0x9d,0xc8,0x36,0xbd,0xac,0x49,0x26,0x2b,0x48,0xeb,0xad,0xa8,0xb6,0xb3,0xaa,0xb4 +,0x32,0x1c,0x1a,0x20,0x27,0x36,0xaf,0xa7,0xac,0xaa,0xa1,0xb8,0x2b,0x24,0x2a,0x33,0x3d,0xc2,0xaf,0xb0,0xa8,0x9f,0xad,0x29,0x14,0x16,0x2d,0xb7,0xa7,0xa6,0xb3,0xcf +,0xb0,0x9c,0xa5,0x30,0x1a,0x1a,0x28,0x78,0xaf,0xad,0xbc,0xc1,0xb1,0xae,0x55,0x20,0x1f,0x3a,0x6b,0xc6,0xa1,0xa2,0xbd,0xb3,0xa4,0xb9,0x27,0x19,0x1e,0x33,0x3d,0x60 +,0xbc,0xb0,0xa8,0x9d,0xa3,0x37,0x1a,0x1a,0x29,0x30,0x4b,0xc7,0xca,0xb7,0xa0,0x98,0xa3,0x2a,0x14,0x1a,0x3e,0xac,0xa1,0xa9,0xce,0x5d,0xb6,0xa9,0x52,0x1f,0x1e,0x2b +,0x47,0xc1,0xaa,0xa2,0xa5,0xaa,0xae,0xcd,0x27,0x1b,0x28,0x56,0x4b,0x41,0xbd,0xae,0xb2,0xa4,0xa6,0x46,0x24,0x21,0x2f,0x38,0x3e,0xc8,0xab,0xa4,0xa3,0xa0,0xb3,0x29 +,0x1d,0x36,0x60,0x2b,0x24,0x2b,0x5c,0xa6,0x9c,0xaa,0x44,0x1c,0x1b,0x33,0xbd,0xac,0xac,0xb0,0xbe,0xb7,0xa7,0xaa,0x2e,0x19,0x1f,0x35,0x5e,0xbf,0xad,0xa5,0xa9,0xb2 +,0xb8,0x3f,0x25,0x27,0x31,0x33,0x3d,0xc6,0xa4,0x9e,0xa4,0xa1,0xae,0x29,0x19,0x1e,0x26,0x2a,0x2b,0x37,0xb7,0x9e,0x96,0x9a,0xbd,0x20,0x20,0x3f,0xbe,0xbe,0x6c,0x5e +,0x44,0xcc,0xa9,0xb8,0x27,0x19,0x1c,0x26,0x5f,0xaf,0xa4,0x9d,0xa5,0xaf,0xaf,0xeb,0x23,0x1d,0x25,0x37,0xf0,0xc7,0xa8,0x9d,0xa1,0xa6,0xc7,0x26,0x1e,0x27,0x2a,0x2c +,0x33,0xbf,0x9e,0x9f,0xa1,0xa5,0xbd,0x2f,0x24,0x27,0x29,0x2b,0x2e,0xd3,0xac,0x9e,0x9a,0xa5,0x44,0x21,0x23,0x32,0x46,0x2e,0x49,0xb3,0xae,0xa9,0xac,0x68,0x2d,0x27 +,0x22,0x2d,0x56,0xb9,0xa9,0xac,0xb3,0xad,0xbc,0x2d,0x1c,0x1a,0x21,0x34,0xfe,0xaa,0x9a,0x9b,0x9f,0xa1,0xac,0x5a,0x2d,0x25,0x1e,0x1d,0x26,0xb8,0x9e,0x9f,0xa5,0xba +,0x3d,0x2a,0x2f,0x34,0x2a,0x1f,0x2a,0xd1,0xa4,0x93,0x93,0xa5,0x3a,0x22,0x24,0x3b,0x37,0x2d,0x42,0xc4,0xcd,0xbd,0xae,0x5c,0x47,0xd5,0x3f,0x28,0x4b,0xda,0xae,0xc4 +,0x27,0x2a,0xbb,0xb4,0xe7,0xba,0x31,0x4c,0xa8,0xab,0x27,0x1d,0x3f,0x9c,0x92,0xd1,0x42,0xb2,0xd5,0x29,0x1f,0x2b,0x36,0xb9,0xa2,0xad,0x3c,0x23,0xac,0xa5,0x32,0x21 +,0x4b,0xc4,0x26,0x38,0xba,0xaa,0x96,0x9d,0x2a,0x1e,0xe5,0xa4,0xa3,0x2b,0x14,0x2d,0xc8,0xbe,0xd3,0xb2,0x38,0x40,0xb7,0x68,0x56,0x35,0x5c,0xae,0xba,0x1b,0x27,0xbb +,0x9c,0xa0,0xfd,0x5f,0x2f,0xab,0xb0,0x23,0x1f,0x2f,0xa8,0x9e,0xbe,0x44,0x3b,0xfb,0x57,0xd6,0x4b,0x2d,0x49,0x9f,0xa6,0x2e,0x36,0xb3,0x98,0x2c,0x12,0x24,0xbc,0xbd +,0x3f,0xe8,0x40,0xac,0x9d,0xa2,0x3a,0x24,0x25,0xf4,0xe0,0x2c,0xb5,0xaa,0xaa,0xb4,0x3f,0x1d,0x26,0x99,0xaa,0x14,0x19,0x6c,0x97,0x9d,0x39,0x25,0xba,0xa6,0x3b,0x37 +,0x24,0x2b,0xa3,0x9a,0xc1,0x6c,0x30,0x36,0xb0,0x2d,0x20,0x36,0xbe,0xbe,0x48,0xce,0xb7,0x9c,0x91,0xa9,0x17,0x11,0x41,0x9a,0xaa,0x2d,0x46,0x20,0x24,0xf1,0xa4,0xa5 +,0x37,0xbb,0x3d,0x1b,0x1e,0xba,0x8c,0x94,0x34,0x21,0x2d,0x4a,0xc7,0x5f,0x1e,0x1b,0xa7,0x98,0xc9,0x5d,0xac,0xac,0xb6,0x20,0x19,0x46,0x32,0x39,0xb0,0xc7,0x2b,0xad +,0x93,0xa8,0x17,0x12,0x3c,0x9c,0xad,0x1f,0x2a,0xb2,0x95,0xa1,0xcb,0x2b,0x1d,0xb9,0xb9,0x28,0x2c,0xb7,0x9b,0xae,0x35,0x3e,0xb7,0xac,0x3d,0x30,0x17,0x1d,0xa5,0x9a +,0xb5,0x30,0x42,0xa8,0x9f,0x32,0x26,0x63,0x3f,0x2e,0xbe,0x32,0x30,0xad,0xaa,0xaf,0xb4,0xcb,0x24,0x2a,0x25,0x59,0xa1,0xa6,0x3f,0x1e,0x28,0xad,0x92,0xaa,0x2a,0x10 +,0x19,0xa3,0x92,0x99,0x34,0x2d,0xac,0xb1,0x24,0x1e,0x38,0xa6,0xad,0x2c,0x2e,0x38,0xce,0xb7,0xaa,0x2d,0x33,0x9c,0xad,0x57,0x44,0xdb,0x44,0x48,0x34,0x36,0x4f,0x29 +,0x36,0xaa,0x56,0x33,0x94,0x96,0x2e,0x13,0x2b,0xa6,0xa3,0x3a,0x23,0x39,0xb0,0x9e,0xb6,0x38,0x17,0x2c,0xa7,0x5e,0x1c,0xe0,0x8f,0xa3,0x3b,0xb6,0x67,0xd2,0x56,0x2f +,0x46,0x14,0x2a,0x98,0x99,0xdf,0x32,0xa5,0xa0,0x1e,0x1c,0xdd,0x36,0x15,0x21,0x96,0x9e,0xa5,0x96,0xad,0x15,0x12,0x2d,0xab,0xa5,0x2d,0x42,0x42,0x3c,0xa3,0x92,0xd9 +,0x11,0x61,0x9d,0x2f,0x14,0x2e,0x94,0x9d,0x2e,0xfb,0x47,0x3f,0x34,0x26,0xe7,0x27,0x22,0x9b,0x96,0x49,0x49,0x9a,0xa6,0x37,0x20,0x1e,0x29,0x2e,0xaf,0x9a,0xd2,0x31 +,0xa3,0xa0,0x3e,0x1d,0xc0,0x9f,0x23,0x0e,0x62,0xa6,0xb6,0x99,0x96,0x54,0x0b,0x28,0xae,0x45,0x1f,0x33,0x94,0xa0,0x2b,0xcf,0x9d,0x4d,0x1c,0x2d,0xaf,0x2f,0x3a,0x9a +,0xb2,0x1e,0x66,0x96,0xc6,0x1d,0x2d,0x37,0x25,0x1d,0xc8,0x8f,0xc5,0x1b,0x9c,0x8e,0x2f,0x14,0x2c,0xac,0x3e,0x1d,0xae,0xbf,0x79,0x9c,0x9b,0x52,0x13,0x2d,0xa2,0xbe +,0x1a,0x25,0x96,0x9e,0xea,0xb5,0xb5,0x1e,0x1b,0xb2,0xac,0x21,0x1d,0xa6,0xa9,0x50,0xab,0x8f,0xaa,0x0c,0x0e,0xd4,0xab,0x3a,0xb1,0x95,0x78,0x1d,0x9e,0x97,0x1b,0x16 +,0xc7,0xba,0x2c,0x1d,0xb3,0xa6,0xc4,0xc1,0xa5,0xcf,0x14,0xdc,0xa0,0x3f,0x16,0xbd,0x8f,0xb6,0x2e,0xb0,0xb6,0x12,0x1b,0xaf,0x9e,0x1f,0x14,0xa4,0x95,0xaa,0xad,0x9f +,0x3a,0x0f,0x1e,0x9f,0xcb,0x26,0xbd,0x9c,0x3c,0x27,0x97,0x93,0x22,0x0f,0x23,0xac,0xae,0x58,0x9e,0xb6,0x20,0x37,0x96,0xb9,0x0c,0x28,0x9d,0x51,0x18,0xac,0x93,0xc2 +,0x24,0xb7,0x9f,0x1d,0x1b,0xbb,0xa2,0x2f,0x25,0x97,0xa2,0x21,0x65,0x9b,0x64,0x14,0x27,0xb5,0x61,0x35,0xd5,0xab,0x3b,0x31,0x96,0x9a,0x19,0x0c,0x4a,0x97,0xb7,0x36 +,0xac,0x6a,0x20,0xc4,0x91,0xa2,0x0e,0x1b,0xab,0xaa,0x51,0xa3,0x9d,0x39,0x2b,0xae,0x9a,0x19,0x0d,0x2f,0x9c,0x50,0x35,0x98,0xe4,0x1e,0x51,0x9b,0xd5,0x1d,0x35,0xaa +,0xca,0x38,0xb4,0x9a,0x46,0x1a,0xa2,0x9d,0x18,0x10,0xb6,0x9d,0xce,0xd8,0xa3,0x38,0x25,0xc8,0xa1,0x43,0x11,0x2d,0xa0,0x9f,0x35,0xcd,0xdc,0x2e,0x3a,0x9f,0xa0,0x15 +,0x13,0x35,0x9e,0xbf,0xa8,0x98,0xd2,0x1c,0x26,0x9e,0xad,0x20,0x1f,0xb5,0xb9,0x3e,0xa5,0x95,0x2e,0x0e,0xc3,0xa0,0x29,0x25,0xa2,0xa4,0x37,0xbf,0xa5,0xba,0x2d,0x2c +,0xaa,0x48,0x11,0x2f,0x9c,0xa2,0xe2,0xab,0x60,0x17,0x29,0x9e,0x9e,0x2f,0x1d,0x2e,0xa4,0xb9,0xaf,0xa5,0x2b,0x18,0x2d,0x99,0xaa,0x22,0x1e,0xcf,0xaf,0xae,0x9f,0xa6 +,0x1d,0x0e,0xb7,0x9c,0xc1,0x24,0x2e,0xd4,0xc1,0x9e,0x9f,0xd7,0x16,0x16,0xa2,0xaa,0x1c,0x38,0x9d,0x9f,0xc2,0xad,0x3f,0x1d,0x29,0xa4,0x9c,0x2d,0x1d,0xfa,0x98,0xc9 +,0xca,0xa8,0x22,0x0e,0x2b,0x96,0xcf,0x3c,0xf0,0xc0,0xb2,0xa7,0xab,0x31,0x15,0x1a,0x9c,0x97,0xf4,0x1c,0x37,0xbe,0xb3,0x96,0xb5,0x20,0x16,0x21,0x9c,0x9d,0x3a,0x1e +,0x3a,0xc4,0x67,0xa8,0xad,0x27,0x16,0x24,0xb8,0xc7,0x3a,0xa6,0x95,0x5b,0x36,0xd7,0x4d,0x28,0x4a,0x9d,0x39,0x25,0x4f,0xa8,0xa4,0xbf,0xb7,0xbd,0x20,0x18,0xaa,0xad +,0x48,0xbe,0xa1,0xe3,0x2a,0x9f,0xca,0x2b,0x19,0x25,0x9f,0xa1,0x56,0x1f,0x2f,0x46,0xad,0x95,0xa9,0x1e,0x1f,0x3b,0xbe,0xa1,0xa8,0xbb,0xfd,0x26,0x2c,0xcd,0xa7,0x54 +,0x1c,0x28,0x24,0x49,0xb4,0xa3,0xab,0xdd,0xba,0xbf,0x34,0x20,0x57,0xac,0xb6,0x4a,0xbb,0x59,0x28,0xbf,0x4f,0x42,0x26,0x2f,0x9c,0xbd,0x35,0x51,0xb1,0xc6,0xb5,0x9b +,0x60,0x12,0x18,0xad,0x9e,0x9b,0xbc,0x38,0x2c,0x26,0xa6,0xa5,0x50,0x1f,0x33,0xb8,0x2e,0xbe,0xa7,0xbc,0xaf,0x54,0x27,0x3e,0xaf,0xd5,0x2b,0x20,0xd5,0xa9,0xa3,0xb1 +,0x31,0xc0,0x29,0x2e,0x33,0x2c,0xa9,0xa0,0xd7,0x2d,0xcc,0xbb,0xad,0xbd,0x20,0x10,0x26,0x98,0x99,0xcf,0x25,0x39,0xbf,0x4f,0xad,0xd5,0x26,0x1c,0x2c,0x9c,0xb3,0xb2 +,0xaf,0xc5,0x3d,0x41,0xc5,0x4b,0x5b,0x4d,0xc0,0x39,0xb3,0xa5,0xaa,0x69,0x2d,0xcf,0x30,0xed,0xb8,0x3d,0x21,0x29,0xd6,0xb2,0xb7,0xda,0xb3,0xbd,0x29,0x1c,0x70,0x9f +,0x9e,0x9c,0x2f,0x1e,0xc7,0xaf,0xa5,0x1f,0x16,0x26,0xbd,0x98,0xc5,0x3b,0xeb,0xbc,0xe9,0x46,0x2c,0xcf,0xae,0x2c,0x32,0x30,0xb3,0xa0,0xa1,0x2e,0x13,0xcd,0xa9,0xad +,0x34,0x1b,0x2a,0xb8,0xa0,0x9f,0xbf,0x2d,0xb5,0xca,0x6f,0x57,0xb5,0xaf,0x23,0x37,0x46,0x46,0xc9,0xa5,0xa4,0x1e,0x12,0x43,0x9f,0xa0,0xb3,0x5e,0x42,0xc6,0xab,0xab +,0x2f,0x1b,0x1f,0x2d,0xbd,0xb8,0xa3,0xc7,0xcf,0xc9,0x37,0xaf,0xaa,0xa9,0x29,0x14,0x1a,0xab,0x9c,0xb1,0x2d,0x1b,0xc6,0xa1,0xa4,0x34,0x49,0x67,0x32,0xbd,0x4f,0x37 +,0xc5,0x9f,0xa8,0x20,0x13,0x45,0x9a,0x9f,0x27,0x1b,0xd9,0xa0,0x9f,0xb8,0x1c,0x1e,0xdb,0xa8,0xa7,0x32,0x4a,0xe2,0xb4,0xae,0xa5,0xa2,0x31,0x1f,0x1d,0x2b,0x5f,0xa0 +,0xaf,0x4a,0x1b,0x1f,0x9d,0x9e,0xa6,0x54,0x3d,0x34,0xdd,0xac,0x4d,0x31,0x4c,0xb8,0xd7,0x3d,0x39,0x6a,0x4b,0xdc,0x35,0x21,0xb6,0x99,0x9e,0xe9,0x1d,0x1e,0xb9,0x99 +,0xab,0x1a,0x13,0x36,0x99,0x9e,0x5b,0x43,0x2b,0x22,0x34,0xb6,0xcc,0x49,0x66,0xae,0xc6,0x76,0xa3,0xa6,0xb7,0x27,0x2c,0xe7,0xae,0xac,0x26,0x1e,0xcd,0xa2,0xc8,0x3d +,0x38,0xde,0xad,0xbc,0x29,0x3b,0x9e,0xad,0x29,0x17,0x1b,0xbc,0x99,0x99,0xb9,0x17,0x15,0xc4,0x8e,0x9b,0x4d,0x39,0x30,0x3b,0x48,0xc3,0x37,0x2a,0x21,0xba,0xaa,0x3e +,0x3e,0x34,0xc4,0xb9,0xa5,0xaa,0xcd,0x27,0x24,0xcd,0xc4,0xb0,0xb8,0x28,0x18,0x36,0x9d,0x9e,0x3e,0x24,0xd1,0xc5,0x3b,0x3c,0xc7,0xa1,0x9d,0xa6,0x3e,0x1f,0x2d,0xb3 +,0xa0,0x30,0x19,0x27,0xcb,0x9f,0xa7,0xd1,0x25,0x36,0x7c,0xb5,0xba,0x20,0x27,0xad,0x95,0xae,0xa7,0xb7,0x28,0x1b,0x1c,0xb8,0xbd,0x61,0x4a,0x55,0x34,0xc4,0x9e,0xa3 +,0x33,0x1f,0xaa,0xae,0x25,0x15,0x23,0xa3,0x92,0x9b,0x5e,0x20,0x1e,0xd1,0xb1,0x30,0x33,0x2e,0x4f,0xaf,0xca,0xf3,0xcf,0xd5,0x6d,0xa0,0xbb,0x1b,0x1f,0xac,0x97,0xa9 +,0xc0,0x36,0x33,0x29,0x29,0xbf,0xb8,0x57,0x46,0xb1,0xc3,0x68,0xaf,0xc2,0x43,0x3b,0xcf,0xe5,0x1f,0x14,0x3e,0x95,0x8f,0xa8,0x18,0x1b,0x2b,0xb7,0x91,0xae,0x23,0x31 +,0xb5,0xaf,0x42,0x29,0x33,0xd2,0x54,0xaa,0x3a,0x0f,0x1e,0xa3,0x8d,0x99,0xb9,0x2d,0x3a,0x27,0x25,0x49,0x2f,0x68,0x2f,0xcf,0xaf,0xab,0xae,0x3e,0x24,0x63,0xa9,0x4c +,0x38,0x24,0xc6,0x8e,0x92,0x45,0x28,0x3b,0x3f,0xbc,0xc5,0x1c,0x17,0x2b,0x9f,0x9a,0x42,0x1c,0x28,0x9a,0x9d,0xa3,0x49,0x14,0x18,0xa3,0x8e,0x9f,0x2c,0x11,0x31,0x48 +,0xb4,0xad,0xdd,0xbf,0x46,0x4c,0x55,0xfd,0x3d,0xb3,0xb4,0xe7,0xfb,0x33,0x21,0x1f,0xbe,0x9a,0xab,0x1f,0x21,0xd6,0x58,0xb1,0xc3,0x3b,0xad,0xc0,0xa8,0xab,0x17,0x0e +,0x40,0x98,0x9b,0xbe,0x24,0x33,0xc6,0x97,0x99,0x36,0x1a,0x18,0xb6,0xa4,0x4a,0x29,0xae,0xa1,0x50,0xce,0x70,0x27,0x2e,0xba,0xce,0x4a,0xdf,0xb6,0x42,0x2f,0xb5,0xa2 +,0xb1,0x2c,0x2a,0xc2,0x4f,0x2e,0xb6,0xa7,0xa9,0x47,0x29,0x21,0x1b,0x48,0x9d,0xa5,0xd6,0x42,0x1f,0x4b,0xac,0xac,0xbc,0xdf,0x2d,0x2b,0xa1,0xc0,0x2c,0x2e,0xa2,0x9e +,0x2c,0x21,0x1d,0x1d,0x39,0xbd,0xaa,0x9a,0xbd,0xa7,0x99,0x2e,0x22,0xb6,0xb1,0x36,0x2d,0x3b,0x33,0x3b,0x9c,0x9a,0xc0,0x1e,0x1c,0x21,0x45,0xbb,0xbd,0xa8,0xaa,0xb7 +,0xad,0x9d,0x4a,0x65,0x2c,0x19,0x1c,0x32,0xa6,0x47,0x2e,0xba,0x97,0x94,0x50,0x17,0x2b,0x48,0x2e,0x32,0xbd,0xac,0xe3,0xc0,0xc2,0x20,0x2e,0xa1,0xb7,0x42,0x21,0x21 +,0xbc,0xa2,0xab,0x9e,0x9a,0x28,0x19,0x2d,0x37,0x23,0x39,0xa9,0x9e,0xb1,0xba,0xc1,0x1f,0xca,0xac,0xb5,0xb0,0x32,0x5e,0xbf,0x2c,0x3d,0x9b,0xb2,0x1c,0x20,0x2d,0x2c +,0x51,0xa7,0x9f,0xab,0x49,0x6b,0x35,0x3b,0xb0,0x61,0x47,0x4e,0x1f,0x3b,0x9b,0xb4,0xdf,0xd7,0x4c,0x26,0x2a,0xd8,0xd3,0x3d,0x35,0xab,0x9c,0x6d,0x1f,0xb8,0xae,0xc0 +,0x33,0x44,0xd6,0x36,0xab,0xba,0x1f,0x35,0x9e,0xbb,0x27,0x26,0x2a,0x4f,0xaa,0xaf,0xab,0xa9,0xfd,0x46,0x59,0x5e,0xbc,0xad,0x54,0x33,0x27,0xd5,0xb9,0x23,0x29,0x4e +,0xc5,0xa6,0xc5,0x41,0xb0,0x66,0xe6,0xa1,0xa5,0x22,0x1c,0x46,0xbc,0xaf,0xba,0xa9,0xdc,0x1d,0x29,0x2a,0x4c,0xb1,0xef,0xbe,0xb7,0xdf,0x6f,0x9e,0xb5,0x3e,0x40,0x28 +,0x1f,0x24,0xca,0xb7,0xb2,0xb8,0xb8,0xcb,0x48,0xdb,0xba,0x3b,0x3c,0xd0,0xb1,0xad,0xef,0xb9,0x3e,0x16,0x26,0xa2,0xa9,0x26,0x21,0x41,0xbc,0x8f,0x96,0xa8,0xc9,0x1c +,0x18,0x1e,0xc9,0xb2,0xbc,0x4f,0x42,0x2b,0x49,0x9b,0xc3,0x23,0x2c,0xcb,0xa6,0xcc,0x4a,0xa8,0xac,0xc8,0xbe,0x43,0x15,0x18,0xce,0xa7,0xa7,0xad,0xae,0x6a,0x2e,0xd4 +,0x4f,0x2c,0x52,0x3d,0x33,0x5b,0xad,0xac,0xad,0xa6,0xc6,0x46,0x20,0x1c,0x3c,0xac,0x9d,0xe3,0x36,0x31,0x40,0xa8,0xac,0xbd,0x21,0x21,0x36,0xae,0xa2,0xd7,0x45,0x58 +,0xc9,0x6e,0xac,0xcc,0x1c,0x1d,0x54,0xad,0x9d,0xb3,0x38,0xcd,0xad,0xad,0x31,0x29,0x25,0x30,0xcb,0xbc,0xcf,0xd5,0xa9,0xb4,0x3f,0xcc,0x39,0x28,0x44,0x6e,0xd4,0x4c +,0xb2,0xb9,0xbf,0xc0,0xd3,0x44,0x1b,0x28,0xac,0x96,0xae,0x1d,0x1b,0x2d,0xab,0x98,0x9e,0x3d,0x1d,0x26,0xbe,0xa2,0x9c,0x6b,0x1a,0x2e,0xb7,0xb7,0xd7,0x53,0x1f,0x25 +,0xaf,0xa5,0xb9,0x22,0x37,0xa7,0x9d,0x9d,0x3b,0x1d,0x1b,0x29,0xaf,0x9c,0xa6,0x3d,0x3f,0x2d,0x30,0x45,0x2f,0xbd,0xa8,0xc1,0x31,0x39,0x41,0x59,0xa6,0x97,0xaf,0x1a +,0x1b,0x3e,0xa2,0x98,0xa4,0x18,0x14,0x33,0xa9,0x97,0xb2,0x36,0x1c,0x35,0xb6,0xb9,0x67,0x27,0x4f,0xab,0x9b,0xaa,0x31,0x1f,0x19,0x3a,0xa5,0xa0,0xb8,0x28,0x30,0xbb +,0x9c,0xb1,0x26,0x47,0x5d,0x23,0x27,0xb0,0xb4,0xcd,0xb0,0xac,0x67,0x33,0x42,0x3e,0xd9,0xd9,0x43,0x2b,0xb6,0x9e,0xa7,0xbe,0x1c,0x1b,0x47,0x9a,0x9d,0xc7,0x17,0x0d +,0x4c,0x96,0x8e,0xa0,0x1e,0x11,0x20,0xa0,0x9a,0xb4,0x33,0x1a,0x1b,0xa6,0x8f,0xa9,0x32,0x38,0x26,0x1d,0x29,0x45,0xb9,0x9c,0x97,0x9a,0xba,0x1f,0x12,0x26,0xab,0xd3 +,0x78,0xa7,0xa3,0x46,0x3f,0x39,0x1c,0x2e,0xa7,0x97,0x50,0x11,0x12,0x64,0x8f,0x92,0x96,0xc1,0x0d,0x0d,0xae,0x8e,0xa5,0x23,0x15,0x1b,0xa9,0x8c,0x97,0x2e,0x1a,0x1b +,0x29,0xb7,0xab,0x35,0xde,0xa0,0xae,0xa8,0xc3,0x1e,0x23,0xc2,0xb7,0x2d,0x23,0x3d,0xaa,0xa4,0x9f,0xac,0x3f,0x27,0x1f,0xc6,0x34,0x12,0x2c,0x8f,0x87,0x9d,0x30,0x12 +,0x09,0x1b,0x9d,0x8f,0xa1,0x1c,0x15,0xbd,0x8f,0x98,0x38,0x1f,0x1c,0x3f,0x94,0x9b,0x1d,0x0c,0x1b,0xa7,0x8f,0x8d,0xb1,0x0f,0x12,0x3e,0xa9,0xab,0x2f,0x2d,0xa6,0xaf +,0xc3,0xb0,0x5b,0x31,0x3a,0xb6,0x24,0x16,0x2e,0xad,0x94,0x9b,0xaf,0x29,0x1d,0x41,0xd6,0xa3,0xd4,0x11,0x21,0x92,0x8e,0xae,0x2e,0x20,0x20,0x52,0x9e,0x55,0x0e,0x0f +,0xae,0x87,0x8c,0xd1,0x1a,0x13,0x1b,0xa5,0x8b,0x9c,0x0d,0x09,0x2c,0xaa,0x8d,0x8d,0xb4,0x1f,0x1c,0x25,0x1a,0x25,0x39,0xdb,0x93,0x99,0xaa,0xc8,0x28,0x35,0xce,0xb8 +,0x1e,0x11,0x5a,0x92,0x9b,0xc1,0x51,0x3f,0xb5,0x3c,0x27,0x31,0x19,0x15,0xa0,0x84,0x92,0x1f,0x1a,0x1f,0x4c,0xa8,0xa9,0x2a,0x09,0x15,0x97,0x88,0x8c,0x55,0x12,0x19 +,0x26,0xa8,0x9d,0x3c,0x0f,0x19,0xa3,0x99,0x8e,0x95,0x28,0x16,0x36,0x4f,0x16,0x14,0x3a,0x97,0x8f,0x9b,0xb9,0x50,0xb0,0x5f,0x27,0x18,0x0a,0x19,0x96,0x88,0x98,0xcf +,0x25,0x19,0x6b,0xc2,0x38,0x41,0x1c,0x23,0x94,0x8a,0x98,0x29,0x1e,0x28,0x27,0xf6,0xdd,0x10,0x07,0xba,0x84,0x85,0x97,0x1d,0x12,0x1d,0x2e,0xa8,0xd3,0x17,0x14,0xaf +,0x93,0x95,0x98,0xba,0x37,0x1d,0x38,0x1e,0x09,0x1c,0x98,0x8e,0x92,0x9d,0x3e,0x23,0x34,0x33,0x29,0x20,0x13,0xf0,0x8d,0x91,0xaf,0xc2,0x35,0x1e,0x1e,0x21,0x35,0x3c +,0x1e,0xba,0x86,0x83,0xa2,0x0b,0x0d,0x1e,0x3e,0xa5,0x4c,0x0f,0x14,0x94,0x87,0x8b,0xb1,0x19,0x21,0x1f,0x26,0x26,0x14,0x1f,0x9d,0x8d,0x93,0x9d,0xa4,0xfc,0x16,0x12 +,0x48,0x24,0x0e,0x36,0x98,0x97,0x94,0x9e,0x5d,0x29,0x1e,0x28,0x26,0x1b,0x1d,0x9c,0x86,0x88,0xa6,0x1b,0x11,0x0f,0x2c,0xd1,0x1e,0x18,0x28,0x9a,0x87,0x86,0x9e,0x22 +,0x21,0x15,0x1c,0x23,0x16,0x16,0xad,0x8b,0x8d,0x9f,0x49,0x35,0x2c,0x26,0x1d,0x20,0x1d,0x39,0xa5,0x95,0x93,0x9d,0xab,0x1f,0x15,0x30,0x69,0x11,0x0f,0xa3,0x8a,0x8d +,0x9e,0x79,0x20,0x1b,0xb5,0xa9,0x11,0x0b,0x1f,0x8f,0x85,0x95,0x23,0x1c,0x1f,0x19,0x3a,0x22,0x18,0x4c,0x9a,0x8c,0x85,0x92,0x24,0x16,0x1c,0x25,0x19,0x18,0x1a,0x22 +,0xa9,0x8d,0x8f,0xa2,0xc5,0x1a,0x24,0xac,0x44,0x15,0x19,0xa0,0x89,0x8d,0xde,0x24,0x30,0x21,0x29,0x2b,0x15,0x0d,0x2d,0x8a,0x88,0x9c,0x45,0x25,0x2c,0xb4,0xab,0x12 +,0x07,0x17,0x98,0x85,0x88,0xa8,0x27,0x1f,0x1f,0x24,0x18,0x11,0x17,0xb5,0x92,0x8d,0x90,0xa1,0x4e,0x1f,0x2e,0x25,0x15,0x1b,0x26,0xa9,0x88,0x86,0xb7,0x19,0x1f,0x3c +,0xac,0x1f,0x08,0x0e,0x54,0x8f,0x8e,0x9d,0x5e,0xac,0x9f,0xbf,0x24,0x0d,0x0e,0x1c,0x99,0x85,0x98,0x1d,0x30,0xae,0xe2,0x3b,0x1b,0x14,0x16,0x50,0x94,0x89,0x94,0x36 +,0x25,0x2c,0x46,0x23,0x12,0x10,0x50,0x8e,0x8b,0x93,0xaa,0x66,0x2a,0x3d,0x69,0x11,0x09,0x17,0xb3,0x90,0x91,0xa9,0x20,0x31,0xa2,0xa9,0x3f,0x18,0x16,0x3a,0x8f,0x8a +,0xae,0x1d,0x2a,0x9e,0x9e,0x19,0x05,0x0d,0x45,0x9d,0x97,0x97,0xc2,0x57,0xa1,0xaa,0xaa,0xe6,0x19,0x0e,0x29,0x92,0x8d,0xa0,0x1f,0x1e,0x35,0x5b,0x1e,0x09,0x12,0x56 +,0x91,0x8a,0x96,0xbe,0xc6,0x99,0x9d,0xcd,0x12,0x05,0x0d,0xbd,0x8c,0x8c,0x3f,0x1f,0x7a,0x9b,0x94,0x15,0x00,0x29,0x84,0x98,0x17,0x00,0x1d,0x82,0x84,0x87,0x2c,0x00 +,0x0e,0x88,0x88,0x50,0x8e,0x85,0xac,0x0c,0x0f,0xaf,0x0c,0x00,0x16,0xab,0xa0,0x8a,0x3c,0x02,0xa4,0x80,0x86,0x1a,0x00,0x27,0x84,0x99,0xa6,0x21,0x05,0x3e,0x85,0x9f +,0x0f,0x14,0x04,0x1d,0x94,0xae,0xa5,0xa8,0x9d,0x8e,0x5b,0x7b,0x39,0x05,0x01,0x9f,0x80,0x83,0x94,0x03,0x0e,0x87,0x87,0x28,0x04,0x03,0xa3,0x87,0x13,0x00,0x1c,0x8d +,0x88,0x95,0x92,0x95,0x0e,0x05,0xb3,0x8f,0x8e,0x89,0xcd,0x0d,0xa5,0x8e,0x16,0x02,0x00,0x3c,0x80,0x9b,0x26,0x0d,0x17,0x8a,0x80,0xa3,0x04,0x2b,0x91,0xa7,0x17,0x1f +,0x95,0x3a,0x10,0xcd,0xda,0xba,0x21,0x00,0x0a,0x87,0x85,0xb4,0x30,0xcb,0x8a,0x81,0xa7,0x07,0x00,0x07,0x95,0x84,0xa2,0x15,0x2c,0xb5,0x8e,0x91,0x24,0x1e,0x1e,0xa1 +,0xbe,0x08,0x0b,0xbb,0xfc,0xbe,0x87,0x81,0xb3,0x04,0x02,0xa8,0x81,0x94,0xc4,0x23,0x32,0x8a,0x93,0x09,0x00,0x0f,0x92,0x8e,0x30,0x2d,0xb2,0x34,0x9e,0x84,0x9f,0x2f +,0x3c,0x1f,0x18,0xc0,0x99,0xbe,0x15,0x0f,0x93,0x81,0xbc,0x05,0x00,0x3d,0x81,0x8f,0x09,0x0e,0x8c,0x81,0x96,0x1d,0x10,0x15,0x30,0xb6,0xab,0xbe,0x99,0xb8,0x10,0x2e +,0x93,0xa8,0x0f,0x17,0xb5,0x8d,0xc4,0x0c,0x0c,0x1f,0x97,0x80,0x86,0x0f,0x00,0x14,0x89,0x88,0xa6,0x57,0x97,0x9f,0x30,0x18,0x06,0x08,0x1a,0xac,0xa9,0x9c,0x9b,0xca +,0x1f,0xa8,0x85,0x86,0x1d,0x03,0x0f,0xcf,0x95,0xd8,0x10,0x18,0x97,0x8d,0x9a,0x3a,0x09,0x11,0xa3,0x8d,0x46,0x15,0x98,0x84,0x98,0x2f,0xc2,0x1d,0x09,0x0f,0xcd,0x8e +,0x8e,0x33,0x0e,0x13,0xb0,0x8d,0x30,0x04,0x1d,0x87,0x8f,0x14,0x06,0x18,0x97,0x8c,0x96,0xa9,0x1c,0x0d,0x1e,0xbf,0x9b,0x95,0x8a,0x8b,0xbf,0x1a,0x2b,0x25,0x0b,0x0e +,0x2f,0x97,0x96,0x25,0x05,0x17,0x8c,0x82,0x8f,0x1d,0x19,0xaf,0x9a,0x58,0x15,0x17,0xa7,0xa0,0x29,0x31,0x5a,0x2a,0x18,0x3e,0xaf,0xb1,0x4a,0x3d,0x9e,0x9b,0x9a,0x9b +,0x1a,0x02,0x15,0x8f,0x86,0x9f,0x19,0x11,0x2c,0xa6,0xad,0x23,0x25,0x9d,0x97,0x29,0x0e,0x15,0xb6,0x98,0xa9,0x97,0x8b,0xb5,0x0c,0x0c,0x3a,0x8f,0x8f,0xdf,0x27,0x5b +,0xb6,0x30,0x0f,0x0b,0x2a,0x8e,0x8b,0x47,0x0c,0x11,0xb8,0x92,0xa0,0xd7,0xbb,0xa5,0xa4,0x74,0x3f,0xeb,0xc7,0x5f,0x34,0x32,0xeb,0xb7,0x19,0x0c,0xb1,0x89,0x93,0x2d +,0x1b,0x3c,0xab,0xa8,0x2f,0x0e,0x0e,0x44,0x9b,0x9c,0x9f,0xa7,0xb1,0x46,0x1f,0x25,0xb3,0xa3,0xa9,0xab,0x3b,0x1e,0x21,0x1d,0x26,0x9f,0x8e,0x94,0x30,0x0d,0x18,0xa8 +,0x91,0x9e,0xc1,0xca,0xcc,0x22,0x0d,0x11,0x43,0x98,0x93,0xad,0x4e,0x3a,0x29,0x29,0x48,0xaa,0x97,0x9c,0x2a,0x1a,0xe9,0x9c,0xa3,0x2f,0x1a,0x21,0x4b,0xb4,0x5a,0x17 +,0x1f,0x9d,0x9d,0x3e,0x2d,0xc3,0x97,0x9d,0x35,0x2c,0x3c,0x40,0xc2,0xb1,0xaa,0x9d,0xb1,0x17,0x10,0x29,0xbb,0xa7,0xa9,0xa6,0xad,0x4a,0x28,0x16,0x18,0x6a,0x9b,0x9d +,0xbd,0x2a,0x22,0xb8,0x9d,0xa4,0xb4,0xd7,0xf1,0x3f,0x25,0x17,0x17,0x25,0xf9,0x9e,0x96,0x9a,0xec,0x17,0x1b,0xc9,0x9d,0x9b,0xaf,0x3c,0x57,0xbd,0x3c,0x28,0x35,0xc6 +,0xa8,0xe8,0x22,0x30,0xbd,0xa7,0xa6,0x3e,0x24,0x38,0xc8,0x71,0x3b,0x57,0xdc,0x3f,0x36,0xbb,0x9f,0x99,0x9d,0x3e,0x1b,0x21,0x39,0x2e,0x23,0x3d,0x9a,0x8e,0xa6,0x1c +,0x0e,0x14,0x59,0x9f,0x9e,0xb3,0x35,0x2c,0x44,0xb2,0x9d,0x97,0x9c,0xce,0x29,0x1d,0x19,0x21,0x35,0xcd,0xaa,0xad,0xd7,0x3e,0x2e,0x31,0xc5,0xb9,0x57,0xc1,0xa8,0xa1 +,0xa7,0x5d,0x28,0x26,0x2c,0x2f,0x45,0xbf,0xb8,0xe8,0xd6,0xab,0xb4,0xd9,0x56,0x39,0x48,0xcc,0x46,0x1e,0x19,0x33,0x9d,0x8f,0x96,0xb7,0x30,0x29,0x3e,0x36,0x22,0x24 +,0x5c,0xa8,0xac,0x65,0x38,0x3a,0x30,0x23,0x31,0xae,0x9c,0xa0,0x4c,0x28,0x5d,0xa9,0xab,0xb9,0xc7,0x52,0x46,0x2a,0x1b,0x26,0xb7,0x9c,0xa2,0xc8,0x2d,0x21,0x2c,0x32 +,0x3b,0xd8,0xac,0x9e,0x99,0xa1,0x6e,0x2f,0x2c,0x32,0x49,0x42,0x3e,0x39,0x31,0xd8,0xa7,0xaa,0xc8,0x47,0x32,0x34,0x3a,0x33,0x2c,0x28,0x2b,0xd7,0xa1,0x93,0x91,0xa4 +,0x37,0x1f,0x29,0x45,0xc5,0xb4,0xcd,0x4e,0x4f,0x32,0x1e,0x1f,0x2d,0x44,0xad,0xa7,0xc6,0xbd,0xa3,0xa0,0xaf,0xd4,0xdd,0xaf,0xba,0x1f,0x11,0x1b,0x3a,0xb1,0xa6,0xa9 +,0xa9,0xb0,0x3c,0x1f,0x1d,0x2f,0xbe,0xb2,0xb6,0xad,0xa0,0x9c,0xaf,0x24,0x1e,0x2c,0x67,0xcd,0x3a,0x23,0x2a,0x62,0xd1,0xaf,0xae,0xb9,0xc8,0x37,0x30,0x3c,0x3d,0xf0 +,0xb8,0xad,0x9b,0x9e,0x4f,0x33,0x30,0x27,0x34,0xe5,0xbc,0xa9,0xac,0xcf,0x4d,0x2f,0x20,0x23,0x29,0x2f,0xd5,0xaa,0xac,0xab,0x9f,0x9a,0x9e,0xae,0xcf,0x2f,0x29,0x1e +,0x14,0x16,0x2a,0xb6,0x9a,0x98,0xbe,0x27,0x20,0x28,0x36,0x52,0x40,0xc3,0xa3,0xa3,0xa9,0xc3,0x47,0xfe,0xc7,0xc9,0xca,0x42,0x37,0x3a,0x35,0xf9,0xaa,0xad,0x58,0x25 +,0x1b,0x24,0x6a,0xb4,0xb3,0xb5,0xab,0x9c,0x9e,0xae,0xc0,0x4f,0x38,0x21,0x1a,0x29,0xbf,0xa8,0xa3,0x7a,0x1f,0x1f,0x2a,0x44,0xae,0xbb,0x33,0x37,0xbb,0x9e,0x97,0x9c +,0xa9,0xb3,0x54,0x2c,0x1e,0x19,0x1c,0x29,0x47,0xb6,0xad,0xb1,0x66,0x24,0x28,0xcb,0xa4,0xa3,0xb6,0x68,0xc7,0xa6,0xa7,0xbd,0x3a,0x23,0x29,0x2e,0x31,0xd4,0xb1,0xb7 +,0xcb,0x3f,0x38,0xf8,0xde,0xef,0x2f,0x19,0x19,0x3a,0xa8,0x93,0x8e,0x99,0xb8,0x4d,0x3c,0x43,0x3a,0x27,0x27,0x2a,0x2f,0x55,0xba,0xae,0xc0,0x2c,0x2b,0x3e,0x4d,0xf8 +,0x34,0x3a,0xac,0x9a,0x9a,0xa1,0xce,0x38,0xca,0xd1,0x33,0x27,0x21,0x2a,0xcd,0xb5,0xb9,0xcb,0x33,0x27,0x29,0x2e,0xbf,0xa0,0x9c,0xa0,0xb7,0x4a,0x43,0xcf,0xbe,0xb7 +,0x49,0x29,0x1f,0x20,0x3a,0xac,0x9d,0xa4,0x5e,0x1f,0x22,0x2c,0x47,0x56,0x2a,0x2f,0xaa,0x99,0x9b,0xa4,0xbb,0xc3,0xb0,0xe4,0x2e,0x25,0x1d,0x28,0xde,0xbf,0x6d,0x2e +,0x1b,0x22,0xba,0x9c,0x9c,0xbd,0x47,0xcc,0xa9,0x9d,0x9c,0xae,0x45,0x20,0x16,0x1d,0x2e,0x3e,0xb5,0xa9,0xb8,0xc6,0x3b,0x27,0x42,0xc8,0xca,0xe7,0x24,0x23,0xb9,0x98 +,0x94,0x9c,0x5b,0x35,0xde,0xfb,0x4f,0x27,0x17,0x1e,0xbe,0xac,0xad,0xca,0x31,0x49,0xbc,0xce,0x33,0x22,0x27,0xc2,0x9e,0x96,0x9a,0xb7,0x31,0x2c,0xd6,0xa4,0xb4,0x25 +,0x1a,0x1f,0x3d,0xb6,0x6a,0x21,0x2a,0x4c,0xf2,0x5b,0x34,0x50,0x9a,0x8f,0x99,0xae,0xfe,0x71,0xd1,0x40,0x28,0x1c,0x18,0x1b,0x3a,0xaa,0x9f,0xb7,0x2b,0x30,0xb0,0x9f +,0xbc,0x23,0x1f,0xc9,0x98,0x98,0xaf,0x34,0x33,0xc9,0xaa,0xb9,0x2a,0x18,0x1a,0x3a,0xa6,0x9e,0xc1,0x25,0x1d,0x2c,0xaf,0xa3,0x5c,0x28,0x6b,0x9e,0x98,0x9d,0xc0,0x3f +,0xe0,0xc6,0x31,0x1a,0x1b,0x2e,0xaa,0xa8,0x3a,0x1f,0x25,0x7b,0xaa,0xa7,0xe9,0x2b,0x24,0x46,0x9c,0x8e,0x96,0xcf,0x2d,0x45,0xb0,0xb9,0x1f,0x0b,0x0e,0x3e,0x9b,0xa0 +,0x3a,0x20,0x3d,0x9d,0x98,0xb3,0x24,0x24,0xee,0xa8,0xa3,0xab,0x6f,0x2c,0x2f,0xb9,0x9f,0xbd,0x1d,0x16,0x40,0xa2,0xa5,0x2e,0x18,0x2a,0xab,0xa0,0x45,0x1b,0x20,0xae +,0x93,0x99,0xc7,0x4e,0xae,0xa5,0xac,0x5a,0x1e,0x14,0x1b,0x38,0xad,0xac,0x29,0x14,0x29,0x98,0x8b,0x99,0x1a,0x0e,0x35,0x93,0x8f,0xab,0x25,0x2b,0xb2,0xa2,0xc0,0x1d +,0x13,0x1e,0xcd,0xaf,0xd7,0x2c,0x2b,0x6e,0xab,0x9b,0xa0,0x5c,0x25,0x3d,0xa7,0xa2,0xd0,0x22,0x22,0xcb,0x9e,0xa9,0x21,0x11,0x22,0xa8,0x9c,0xc5,0x26,0x38,0xa5,0x9e +,0xbc,0x26,0x19,0x25,0xc5,0xa0,0xa2,0xce,0x30,0x3e,0xac,0x9b,0x9d,0xc4,0x23,0x1c,0x29,0x43,0x37,0x20,0x1e,0x31,0xd4,0x4e,0x2c,0x54,0x99,0x8c,0x8e,0xa3,0x33,0x1d +,0x27,0x65,0xbc,0xb6,0xce,0x36,0x25,0x25,0x45,0xb6,0xbe,0x37,0x2b,0x38,0x4e,0x47,0x41,0xd7,0xab,0xa6,0xb6,0xd0,0xbb,0xb0,0xad,0xb3,0x4b,0x28,0x24,0x38,0xbc,0xb7 +,0xcd,0x37,0x23,0x1e,0x21,0x4e,0xa1,0x98,0x9e,0xd8,0x28,0x1f,0x2a,0x67,0xae,0xa4,0xa6,0xb8,0x4f,0x45,0x5f,0xcf,0xe2,0x32,0x29,0x2c,0x41,0xcb,0x63,0x46,0x46,0xe3 +,0xc1,0xba,0xa6,0x9d,0x9d,0xb2,0x2f,0x1e,0x1b,0x25,0xe9,0xab,0xa8,0xc5,0x2f,0x20,0x24,0x6b,0xa5,0xa4,0xc6,0x3e,0x3e,0x4a,0x43,0x39,0x51,0xb6,0xa2,0x9d,0xa3,0xb9 +,0x3d,0x2c,0x27,0x24,0x29,0x32,0x44,0xd3,0xbd,0xda,0x2f,0x22,0x28,0xd7,0x9c,0x8f,0x90,0xa0,0x39,0x1d,0x1e,0x2a,0x3b,0xcd,0xae,0xa8,0xb1,0x3e,0x24,0x20,0x2b,0x48 +,0xcc,0xca,0x4a,0x3e,0x4e,0x4f,0xc9,0xa7,0x9f,0xa5,0xb4,0xbc,0xb6,0x62,0x26,0x1b,0x1f,0x3c,0xbd,0xb5,0xb0,0xae,0xc0,0x3b,0x28,0x28,0x5d,0xaf,0xb4,0xf4,0x39,0x33 +,0x3d,0xc7,0xa9,0x9e,0x9f,0xbb,0x39,0x31,0x45,0xe1,0x5c,0x39,0x2d,0x29,0x22,0x20,0x3c,0xaa,0x9f,0xa8,0xbb,0xdb,0xc6,0xb5,0xc7,0x55,0x4d,0x4a,0x4b,0x5d,0xb7,0xaf +,0xc4,0x48,0x2d,0x29,0x30,0x39,0x42,0xd8,0xcb,0x5c,0x4b,0x56,0xba,0x9f,0x9b,0xa2,0xcd,0x2f,0x25,0x25,0x36,0x60,0xc2,0xc7,0x38,0x23,0x1f,0x2a,0x3e,0xe6,0xb4,0xaa +,0xa3,0xaa,0xd2,0x3c,0x2d,0x2a,0x3b,0xb0,0xa3,0xa1,0x9b,0x9d,0xb5,0x32,0x1d,0x1d,0x39,0xaa,0xa0,0xaf,0xda,0x32,0x27,0x28,0x43,0xaf,0xa8,0xad,0x65,0x33,0x28,0x25 +,0x2f,0x44,0x4d,0x42,0x3e,0x2e,0x29,0x3c,0xc8,0xba,0xc9,0x77,0xdf,0xbf,0xbf,0xcf,0xd5,0xbe,0xaf,0xab,0xaa,0xa7,0xa4,0xac,0xbf,0x3a,0x28,0x2a,0x30,0x4c,0x56,0x6c +,0xce,0xbd,0xcc,0x42,0x4d,0x3f,0x2e,0x25,0x26,0x3f,0xbd,0xab,0xb7,0x5d,0x3e,0x36,0x37,0x50,0xb4,0xab,0xac,0xbd,0x3b,0x2c,0x2f,0x4d,0xb8,0xae,0xb3,0xaf,0xa6,0xaa +,0xbe,0xad,0xab,0xd9,0x2b,0x1c,0x1f,0x38,0xbd,0xbf,0x4a,0x39,0x2e,0x2e,0x2b,0x2e,0x58,0xb5,0xae,0xda,0x43,0x51,0xce,0xbb,0xcd,0xbe,0xae,0xb2,0xcb,0xee,0xbc,0xba +,0xe3,0x37,0x2b,0x34,0xe6,0xbb,0xd4,0x3d,0x43,0xc6,0xb4,0xbe,0xc3,0xb4,0xbe,0x43,0x26,0x1e,0x2d,0xb8,0xa9,0xba,0xc9,0xc5,0xd2,0x3f,0x2d,0x35,0x4e,0x68,0x3a,0x2a +,0x30,0xb6,0xa2,0xaf,0xed,0x51,0xea,0xbf,0xbb,0xb9,0xa9,0xa8,0xc1,0x26,0x1a,0x27,0xb3,0xa2,0xad,0xac,0xbc,0x58,0x3a,0x2f,0x31,0x52,0xb7,0xd6,0x2d,0x25,0x33,0xf8 +,0x4b,0x3e,0xd2,0xb6,0xb5,0xe7,0x37,0x35,0x4a,0x5c,0x37,0x3b,0xba,0x9e,0x9b,0xa6,0xbf,0x4e,0x53,0xe7,0xcf,0xc5,0xc5,0xd6,0x31,0x1c,0x1c,0x31,0x50,0x3b,0x3f,0xd2 +,0xb6,0xae,0x79,0x2f,0x39,0xec,0x5e,0x33,0x3f,0xad,0x99,0x9a,0xab,0xea,0x38,0x3b,0xee,0xca,0xc4,0xb5,0xbf,0x2c,0x1d,0x21,0x46,0xaf,0xad,0xb5,0xcf,0x5a,0x41,0x37 +,0x33,0x45,0xb8,0xb5,0x6c,0x3e,0x58,0xc2,0xca,0xd5,0xc3,0xae,0xa4,0xad,0x3c,0x21,0x23,0x2c,0x2c,0x36,0xc4,0xae,0xb6,0x44,0x2c,0x2d,0x4f,0xb1,0xa9,0xa9,0xae,0xd4 +,0x2a,0x1e,0x27,0xba,0x9c,0x9c,0xb0,0x3a,0x3b,0xce,0xe2,0x4c,0x5e,0xc6,0xed,0x2a,0x1e,0x28,0x74,0xbe,0xcf,0xd8,0xc1,0xb9,0xe1,0x37,0x3b,0xe7,0xb7,0xb8,0x59,0x4d +,0xb7,0xa3,0xa5,0xb2,0xc1,0xbd,0xbc,0x5b,0x2c,0x26,0x2f,0x37,0x30,0x32,0x3f,0x56,0x4f,0x3c,0x35,0x7e,0xad,0xa7,0xaf,0xd3,0x4b,0x4c,0x39,0x2d,0x4d,0xb4,0xa7,0xab +,0xdc,0x56,0xc6,0xbf,0xc7,0xe9,0x47,0x42,0x38,0x27,0x22,0x29,0x42,0xb6,0xad,0xbb,0xba,0xae,0xb6,0x54,0x30,0x37,0x58,0x3e,0x32,0x67,0xb1,0xad,0xb9,0xf5,0xc3,0xad +,0xb2,0xdb,0x3f,0x3d,0x38,0x33,0x30,0x2b,0x2c,0x36,0x54,0xcf,0xbb,0xab,0xa9,0xc0,0x3d,0x31,0x38,0x4c,0xcf,0xb4,0xa4,0xa0,0xad,0x78,0x3e,0xf5,0xac,0xa4,0xb1,0x57 +,0x2d,0x22,0x1e,0x1c,0x21,0x3e,0xc9,0xbc,0xd9,0x4f,0xb8,0xac,0xca,0xe4,0xd7,0xf7,0x4f,0x33,0x34,0xcd,0xab,0xaa,0xb5,0x65,0x69,0xb2,0xaa,0xb1,0x4c,0x26,0x1f,0x1e +,0x1b,0x20,0x48,0xae,0xa8,0xb0,0xb5,0xa9,0xaa,0xe7,0x3d,0x4f,0xc9,0xb7,0xbc,0x6f,0x3d,0x47,0x59,0x44,0x4e,0xaf,0x9e,0xa3,0xc8,0x2d,0x1c,0x18,0x19,0x22,0x7a,0xa8 +,0xa2,0xba,0x37,0x43,0xb5,0xa2,0x9c,0x9e,0xae,0x47,0x29,0x25,0x2a,0x4a,0xb0,0xb1,0xcc,0xd7,0xc3,0xb8,0xc2,0x43,0x2f,0x2b,0x2a,0x27,0x21,0x29,0x4e,0xc5,0xcc,0xbc +,0xa8,0x9f,0xa3,0xaf,0xbd,0x6d,0x46,0x4d,0x3e,0x2d,0x2e,0x4c,0x5b,0x54,0xba,0xa1,0x9c,0xac,0x37,0x22,0x1f,0x26,0x2d,0x38,0x5d,0xc6,0xc8,0xfd,0xbd,0xa4,0x9e,0xa4 +,0xc7,0x35,0x28,0x28,0x2b,0x2c,0x3f,0xb7,0xb2,0x5c,0x49,0xb6,0x9e,0x9b,0xa4,0xc6,0x2c,0x1e,0x20,0x25,0x28,0x37,0x46,0x43,0x56,0xb8,0xa2,0x9c,0xa2,0xad,0xbf,0x60 +,0x7b,0x4e,0x2f,0x27,0x2e,0x42,0x5e,0xc2,0xa6,0x9c,0xa8,0x3c,0x1f,0x1b,0x21,0x2f,0x2f,0x34,0x3c,0x30,0x2d,0x60,0xa1,0x91,0x8f,0x98,0xc8,0x21,0x1f,0x2e,0x32,0x38 +,0xd5,0xcb,0x36,0x24,0x41,0xa2,0x96,0x9a,0xb2,0x2d,0x1a,0x1a,0x1f,0x23,0x35,0xb7,0xa9,0xb7,0xc8,0xaa,0x9c,0x9d,0xa9,0xbd,0x6d,0x42,0x2e,0x1c,0x17,0x1d,0x2b,0x40 +,0xbf,0xa8,0x9b,0x9a,0xaa,0x54,0x2e,0x2f,0x5b,0x4b,0x2c,0x2d,0x32,0x36,0x44,0xbb,0x9a,0x90,0x96,0xad,0x2c,0x1e,0x25,0x29,0x1e,0x1d,0x2e,0x41,0x42,0xcc,0xa1,0x97 +,0x96,0x9f,0x66,0x26,0x24,0x31,0x2f,0x21,0x27,0x3f,0x58,0x49,0xbd,0x9a,0x8f,0x96,0xbd,0x25,0x1e,0x24,0x27,0x1e,0x1e,0x2f,0x43,0xdd,0xb7,0xa6,0x9c,0x9b,0xa9,0x55 +,0x42,0xcc,0xc6,0x2c,0x1c,0x29,0x3e,0x4b,0xde,0xae,0x9c,0x99,0xa5,0x3c,0x20,0x23,0x3a,0xe4,0x3a,0x26,0x26,0x28,0x3c,0xae,0x96,0x8e,0x93,0xaa,0x2b,0x1f,0x2a,0x3b +,0x2e,0x23,0x25,0x25,0x24,0x30,0xb7,0x98,0x8e,0x96,0xf8,0x1c,0x1a,0x25,0x38,0x39,0x3e,0xef,0x71,0x67,0xcd,0xa8,0x97,0x93,0x9f,0x4a,0x2a,0x25,0x1d,0x17,0x19,0x2a +,0x49,0xc8,0xb2,0xaa,0x9e,0x9a,0xa5,0x52,0x3c,0xbb,0xac,0xcd,0x28,0x1c,0x1a,0x1e,0x36,0xb6,0x9c,0x94,0x9b,0xcc,0x23,0x22,0x34,0xf9,0xc6,0xd6,0x57,0x32,0x27,0x30 +,0xb9,0x97,0x8e,0x98,0x4b,0x21,0x25,0x2b,0x25,0x1d,0x1f,0x2b,0x3f,0xb7,0xa2,0x9c,0x97,0x99,0xaf,0x3a,0x2d,0x2b,0x26,0x1e,0x1d,0x21,0x26,0x2f,0xe2,0xa0,0x90,0x8c +,0x96,0xd9,0x25,0x28,0x33,0x2c,0x21,0x1e,0x25,0x30,0x6e,0xbb,0xa9,0x9c,0x9d,0xaa,0xb7,0xb6,0xc9,0x33,0x1f,0x1d,0x1f,0x24,0x2f,0x6d,0xab,0x99,0x97,0xab,0x31,0x2b +,0x4e,0xbe,0xbd,0x4b,0x2a,0x1e,0x1e,0x34,0xb2,0x9a,0x90,0x95,0xb9,0x26,0x23,0x2d,0x3c,0x3f,0x33,0x28,0x25,0x2d,0x44,0xab,0x92,0x8c,0x98,0xd9,0x29,0x1e,0x1b,0x1c +,0x1e,0x20,0x27,0x3e,0xdf,0xbe,0xa1,0x94,0x93,0x9f,0xb6,0xf2,0x41,0x31,0x1e,0x15,0x14,0x1e,0x30,0xe5,0xa4,0x96,0x94,0xa6,0x44,0x47,0xbe,0xac,0xb9,0x32,0x1e,0x1a +,0x1e,0x26,0x55,0xa1,0x96,0x97,0xac,0x3e,0x29,0x2b,0x3e,0x48,0x3d,0x36,0x2b,0x28,0x44,0xa5,0x94,0x90,0x9a,0xbd,0x2c,0x24,0x3d,0x3f,0x20,0x18,0x1a,0x24,0x34,0xc7 +,0x9e,0x91,0x91,0x9d,0xbd,0x2f,0x2a,0x2d,0x29,0x25,0x26,0x2a,0x2a,0x33,0xae,0x96,0x8f,0x96,0xac,0x3f,0x31,0x2e,0x20,0x15,0x11,0x17,0x21,0x37,0xb8,0x9d,0x96,0x98 +,0x9f,0xa8,0xab,0xa8,0xae,0x3e,0x21,0x1d,0x1b,0x1a,0x28,0xb8,0x9d,0x99,0xa2,0x4a,0x29,0x28,0x76,0x49,0x2c,0xcd,0xaf,0x36,0x2e,0x4e,0xce,0xa9,0xc3,0x4d,0x68,0xdf +,0x2a,0x5e,0xa9,0xab,0x9a,0x96,0xea,0x12,0x1b,0x43,0xa5,0xcf,0x1f,0x4d,0xb4,0x5e,0x31,0x48,0x31,0x26,0xaf,0xb6,0x2b,0x21,0xb9,0x92,0x9c,0xae,0xc5,0xcb,0x1c,0x1c +,0xa9,0xc0,0x25,0x42,0xc6,0x4a,0xac,0x9d,0xa9,0x31,0x16,0x2c,0x64,0x2c,0x2d,0x9e,0x9b,0x33,0xd6,0xc5,0xce,0x29,0x2d,0xdb,0xbf,0xcb,0x44,0xc7,0x4e,0x9f,0x9c,0xa3 +,0x18,0x19,0x9f,0xf6,0x23,0x24,0xe6,0xaa,0xab,0xa7,0xbe,0x2a,0x17,0x2e,0x9a,0xaa,0x30,0x4d,0xa4,0xdb,0xc5,0xa6,0xaf,0x2c,0x1c,0x2e,0x30,0xcf,0x3e,0xb3,0xb9,0x4d +,0xaa,0x9f,0x3e,0x16,0x2f,0x61,0x4d,0x35,0xad,0x9d,0xbf,0xb7,0xa9,0xe2,0x11,0x20,0x9a,0x53,0x1e,0x2b,0xa4,0x9e,0x6f,0xc4,0xb0,0xbc,0x1a,0x27,0xd2,0x2a,0x35,0x9f +,0xa7,0xa9,0xa0,0x3c,0x24,0x1a,0x29,0xb0,0xb6,0x2f,0x3a,0xa3,0xa7,0x4e,0x9d,0x90,0x40,0x0e,0x18,0xca,0x9f,0xbc,0xc5,0xb7,0x1f,0x2c,0xaf,0x9d,0x23,0x1e,0xb3,0x3c +,0x29,0x3c,0x93,0x97,0xd0,0xbd,0xcd,0x1c,0x16,0x27,0xdd,0x3d,0x47,0x94,0x9b,0x76,0xfb,0xad,0xcc,0x1e,0x1b,0xc6,0xe9,0x1c,0x37,0x9d,0xb5,0x37,0x9c,0x99,0x25,0x0a +,0x19,0xaf,0x9b,0xb8,0x68,0xae,0xa9,0x9e,0xa1,0xcb,0x11,0x1a,0xaf,0x2f,0x2e,0xad,0x9c,0xaa,0x3f,0xaf,0xa9,0x33,0x15,0x2e,0xaf,0x3c,0x32,0xa8,0xab,0x5f,0x4b,0x4a +,0xa9,0x3c,0x25,0xe2,0xb6,0x63,0xa4,0xa2,0x33,0x32,0x30,0x3d,0x27,0x2b,0x2c,0xfe,0xa5,0xab,0x9b,0x9f,0x1e,0x0d,0x26,0xa2,0x8f,0xa6,0x1d,0x24,0x3c,0x9c,0x90,0x9f +,0x14,0x09,0x41,0xa3,0xc9,0x2d,0x63,0x9f,0x9c,0xbe,0x45,0x31,0x1c,0x2e,0xbd,0x34,0x1a,0xa5,0x8d,0xa8,0x3f,0x3c,0x3e,0x38,0x30,0x53,0xb1,0x23,0x24,0x97,0x95,0x39 +,0x35,0x9f,0x53,0x0e,0x1b,0xb2,0x9d,0xc1,0x1c,0x3d,0xa2,0x97,0xa0,0xc5,0x21,0x17,0xd3,0xc6,0x2c,0xe2,0x9f,0x95,0xad,0x2e,0xdc,0x28,0x14,0x1b,0xda,0x5a,0x2a,0xa3 +,0x92,0xa6,0x36,0x52,0x9d,0xac,0x0f,0x16,0x4d,0x23,0x23,0x96,0x8c,0xae,0xbc,0xab,0x29,0x11,0x21,0x3d,0xa5,0x4c,0x27,0xa7,0xb6,0xa5,0x99,0xaa,0x10,0x0c,0xaf,0xa2 +,0x24,0x4f,0xa6,0xa2,0xa8,0xd2,0xaf,0x33,0x15,0x24,0xa9,0xbc,0x26,0xc0,0x95,0x9b,0xb4,0xb4,0xb6,0x2d,0x0e,0x13,0x27,0x3d,0x99,0x95,0xb9,0x2f,0x55,0x9c,0xbb,0x0f +,0x1c,0xb4,0xa0,0x3a,0x21,0x9e,0xa0,0xb2,0xaa,0xcd,0x0d,0x12,0x9b,0xa8,0x27,0x21,0xa6,0x8e,0x99,0x25,0x25,0x2e,0x14,0x24,0xa5,0xe0,0x1d,0xa5,0x99,0x4e,0xc5,0xa2 +,0xef,0x1f,0x1c,0x4b,0xe7,0x46,0xa0,0x93,0x9f,0x28,0x37,0x9c,0xeb,0x0f,0x1f,0xcb,0xbd,0x38,0xc0,0xa8,0xc9,0x9e,0xbe,0xc7,0x20,0x13,0x55,0xbb,0x5d,0x68,0xa0,0x95 +,0xa2,0x18,0x1b,0x2d,0x29,0x9c,0x9f,0x1f,0x13,0xae,0x8f,0xa4,0xc4,0x55,0x3f,0x23,0x15,0x34,0xa8,0x60,0xd0,0x9b,0xb4,0x1a,0x4e,0x92,0x3b,0x0d,0x26,0xc1,0xa4,0xaa +,0xc5,0x65,0x6a,0xa9,0xb8,0xb8,0x16,0x17,0xb6,0xd4,0x2f,0xb5,0x92,0xb2,0x45,0x5b,0x5c,0x21,0x26,0xc6,0xb2,0x7d,0x20,0x9e,0x92,0xa1,0xd1,0x2a,0x2f,0x21,0x20,0xb7 +,0xb8,0x30,0x76,0xa7,0xa2,0xc9,0xba,0xaa,0x1c,0x0e,0x20,0xb2,0x92,0xa5,0x34,0x21,0x2c,0xab,0x9b,0xa9,0x0a,0x0b,0x99,0x93,0xc5,0xaf,0x9d,0xe1,0x2f,0x6b,0xea,0x1d +,0x19,0xfe,0xa7,0xbd,0x1d,0xac,0x95,0x3c,0x2c,0x3d,0x36,0x23,0xb9,0xb5,0x2f,0xbe,0xa0,0x9d,0xaa,0xe2,0x3b,0x3e,0x1c,0x1d,0xb7,0x9a,0x9f,0x3a,0x59,0x3a,0x4e,0xa9 +,0xb3,0xec,0x0d,0x15,0x9b,0x95,0xb4,0x2b,0xd4,0x56,0xca,0xaf,0xba,0x1c,0x0e,0x35,0x9a,0x9a,0xd5,0x9c,0xb4,0x1c,0x27,0xbc,0xb2,0x35,0xb8,0xd6,0x26,0x34,0xae,0x98 +,0xad,0x17,0x1c,0xb9,0x30,0x20,0xbf,0xa5,0xc9,0xf9,0x9c,0xce,0x2a,0x4d,0x38,0x3c,0x1a,0x3d,0x9b,0x9b,0xdc,0x2c,0xd2,0x3c,0xa7,0x99,0xca,0x0f,0x12,0xc7,0x94,0x95 +,0xc1,0xc4,0x21,0x1a,0x2c,0xa4,0xa6,0x1f,0x27,0x54,0xa1,0xa9,0xac,0x9e,0x41,0x0e,0x25,0x95,0xbf,0x25,0x44,0xae,0x45,0xc8,0x9f,0x43,0x24,0x1e,0xed,0xd0,0x1a,0x3d +,0x93,0x99,0x4c,0x43,0x3e,0x1b,0xc8,0x91,0xb8,0x13,0x17,0x7b,0x97,0x9c,0x3d,0x59,0x27,0x26,0xfc,0xa5,0x5f,0x14,0x35,0x9e,0x96,0xaf,0x3e,0x3b,0x2d,0x1c,0xbf,0x96 +,0x40,0x1c,0x2d,0xa5,0xaa,0xa3,0x9b,0x3a,0x15,0x19,0xaa,0x9e,0x25,0x37,0x9c,0x9e,0x46,0x64,0xef,0x1d,0x2e,0xb2,0xae,0x24,0x23,0xab,0x91,0xb9,0x16,0xf8,0xc7,0x34 +,0x4c,0xa2,0x30,0x19,0xaf,0x99,0xa8,0x41,0xcc,0x3a,0x20,0x1c,0xae,0x98,0x33,0x1a,0x46,0x9d,0xcf,0xa9,0x9e,0x1c,0x0f,0x1e,0x9e,0x96,0x38,0x1c,0x31,0xae,0xae,0x9e +,0x9d,0x23,0x10,0x2b,0x9a,0x9e,0xac,0xad,0x9a,0xea,0x1a,0xbc,0x47,0x20,0x26,0xaa,0xe4,0x1a,0x4b,0x9b,0x9c,0x53,0x52,0x47,0x22,0x17,0x9f,0x8f,0x56,0x2b,0x49,0xaf +,0x27,0xc0,0x9e,0x2a,0x13,0x1f,0x9c,0x95,0x42,0x19,0x4c,0xa6,0x9f,0x9c,0xd8,0x0f,0x0f,0xbf,0x95,0xbf,0x2f,0x39,0xbe,0x60,0x29,0xac,0xea,0x2f,0x21,0xc7,0xb7,0x2b +,0xd5,0x9c,0x9d,0x4d,0x44,0x34,0x2e,0x21,0xa9,0x9c,0x44,0x29,0xeb,0x9e,0x3e,0x33,0x57,0x3f,0x33,0xd4,0x9b,0xa5,0x28,0x25,0xb4,0xad,0x53,0xb0,0xb7,0x19,0x16,0xa3 +,0x91,0xb8,0x2c,0x1f,0xb0,0xbd,0xde,0x9b,0x30,0x16,0x1d,0xae,0xa9,0x2c,0xcd,0xa7,0xae,0x36,0x24,0x39,0xb2,0xbb,0x64,0x33,0x29,0xab,0x9a,0xa4,0x1e,0x1e,0xe1,0x3f +,0x39,0x31,0xb4,0xa7,0x3e,0x27,0xc4,0xac,0xb9,0x5e,0x2a,0x1c,0x26,0x9b,0x8f,0xad,0x37,0x37,0xbe,0xe1,0x31,0xae,0x54,0x2d,0x27,0xaf,0xa3,0x35,0x3a,0x49,0xbc,0xdc +,0xa8,0xb3,0x2e,0x1f,0x5b,0xc2,0x3a,0xb4,0xa2,0xa4,0x24,0x2a,0x3c,0x2e,0x64,0xdc,0x3f,0x39,0x4f,0xb5,0xa2,0xb6,0xd5,0xb9,0x49,0x20,0x34,0xab,0x9e,0xad,0x5d,0x1a +,0x1e,0xcb,0xa0,0xce,0x11,0x1a,0x33,0x93,0x96,0x31,0x3c,0xb8,0xb0,0xc6,0x3a,0x2b,0x5c,0x42,0x65,0xc8,0xf8,0xb7,0xa9,0xb5,0x2c,0xf5,0x9c,0xab,0x35,0x1d,0x2d,0x38 +,0xcf,0xb5,0xc5,0xbd,0xcd,0xc0,0x2c,0x24,0x55,0x9c,0xc8,0x28,0xd0,0xb0,0xad,0x4d,0xc5,0x3d,0x15,0x23,0xa3,0x9c,0xb1,0x39,0x38,0x6b,0xb7,0xad,0xbe,0x1c,0x18,0x3f +,0xb1,0xab,0xb1,0xd9,0xc3,0xb1,0x29,0xb5,0xb7,0x68,0xb8,0x1f,0x13,0x22,0xb6,0xa3,0xa1,0x2d,0x27,0xc4,0x99,0x9d,0xca,0xee,0x2d,0x2f,0xbb,0xb9,0x2e,0xe1,0xad,0x4a +,0x1e,0x21,0xdd,0x9d,0xdc,0x1f,0xb4,0x9c,0x9f,0xc8,0x2e,0x23,0x28,0xc6,0x9e,0x45,0x44,0xa9,0xc3,0x3a,0x20,0xb8,0xa4,0x5e,0x1d,0x1f,0x2f,0xc4,0xa0,0xe5,0x30,0x27 +,0xb0,0x96,0x9a,0xc6,0x38,0x31,0x2c,0xcb,0xd8,0x3d,0x25,0x2d,0x7d,0xd4,0xb4,0xbb,0x2d,0x45,0xcb,0x20,0xb6,0x99,0xae,0xb3,0x45,0x23,0x1f,0x33,0xac,0xae,0x2e,0x2e +,0xab,0x9d,0xa9,0xb3,0xbe,0x3c,0x1d,0x31,0xa5,0xd4,0x3d,0xd6,0xe4,0x39,0x3c,0xcc,0xa3,0x47,0x1e,0xbd,0xaa,0x9c,0xcc,0x15,0x1c,0xd4,0xbf,0xa8,0xaf,0x49,0xf4,0x5e +,0x31,0x20,0xb3,0x9a,0xaa,0x27,0x19,0x29,0x9c,0x92,0xb0,0x2c,0x1c,0x1e,0xac,0x96,0x3d,0x2f,0x3a,0x46,0x22,0x1f,0xe2,0xca,0x2e,0x2b,0xa8,0xaa,0xa2,0xb9,0xaf,0xb8 +,0x2d,0xb2,0x9c,0xcf,0x1e,0x31,0x35,0x58,0x3f,0x3b,0x52,0x40,0xbc,0x9f,0xab,0x3c,0x69,0xe4,0x4c,0x33,0x2d,0xbd,0x9e,0xa9,0xc2,0x30,0x27,0x2a,0x38,0xc9,0x34,0x4e +,0xbf,0xa5,0xa6,0xd3,0x28,0x2e,0xdf,0x3b,0xa9,0xb8,0x39,0x39,0xa9,0xb9,0x2e,0xb6,0xa1,0xbc,0x13,0x17,0x2c,0xc1,0xaf,0xb4,0xc6,0x34,0x51,0xa6,0xa5,0x25,0x3c,0xab +,0xb2,0x2b,0x16,0x2e,0x9d,0xa0,0xbe,0x49,0x44,0xac,0xae,0x3d,0x24,0x2d,0x2c,0xa3,0xa3,0x4f,0x3a,0xbd,0xbd,0x33,0xd7,0x36,0x4b,0x5a,0xae,0xbf,0xc0,0xa0,0xa6,0x47 +,0x11,0x1e,0xcd,0xad,0xbb,0xd9,0xda,0x2d,0x2b,0x7a,0xb4,0xdd,0x6c,0xb3,0xcc,0x2e,0x21,0xe8,0x94,0x99,0x51,0x33,0xbf,0x4e,0x4d,0x45,0x1e,0x1e,0x27,0xab,0xad,0x26 +,0x1f,0x2f,0xc6,0xaa,0xa1,0x46,0x49,0xc6,0xa3,0xa4,0xd0,0xad,0xb4,0xbb,0x1f,0x15,0x1a,0x49,0xac,0xce,0xb2,0xaf,0x9e,0x9b,0xbc,0x2c,0x31,0x40,0xd7,0xea,0x1d,0x2e +,0x9b,0xa9,0x2b,0x2f,0x43,0x59,0xc1,0x37,0x1f,0x48,0xa6,0x93,0xe1,0x10,0x1c,0x9b,0x8f,0x9c,0xb8,0x18,0x1d,0x2d,0xb9,0xab,0xbf,0x46,0xc6,0x4e,0x1f,0x39,0x2d,0xb7 +,0xab,0x28,0x23,0x73,0xa8,0xa7,0x47,0x36,0xeb,0xc6,0xb4,0xca,0x25,0x2b,0xcd,0xc6,0xb6,0xa0,0x9d,0xdc,0x51,0x22,0x2b,0xb4,0xaa,0xa1,0x29,0x0f,0x18,0xa7,0x96,0x9f +,0x37,0x2a,0xdf,0xa9,0x9a,0xcc,0x20,0x1c,0x38,0x9f,0xbc,0x23,0x27,0xa9,0x98,0x31,0x1d,0x2a,0xd8,0xa1,0xba,0x25,0x34,0xa9,0x9e,0xc0,0x1a,0x21,0xa9,0x9d,0xa6,0xb8 +,0x25,0x1c,0x2d,0x31,0x65,0xad,0xca,0xca,0x20,0x15,0xca,0x9a,0x9e,0xae,0x40,0x2e,0x9e,0x9e,0xbb,0x21,0x1b,0x33,0xb2,0x9a,0x3b,0x15,0x1b,0xa3,0x9b,0xc3,0xdc,0x37 +,0x3f,0xcb,0xbc,0xb1,0xb4,0xb0,0x95,0xbf,0x15,0x19,0xde,0xb1,0x33,0x29,0x2c,0x39,0xa7,0x97,0xb1,0x3a,0x27,0x2f,0x2f,0x56,0xbd,0xba,0xbe,0xb2,0xcf,0x3e,0xac,0xb8 +,0xc6,0x1e,0x12,0x29,0x99,0x94,0x2c,0x14,0x28,0x94,0x8e,0xc4,0x1f,0x17,0x1b,0x30,0x33,0xb6,0xa5,0xa8,0x97,0xad,0x16,0x2c,0x9d,0xa8,0xfc,0x1e,0x1e,0xa6,0x9c,0xfb +,0x69,0x2e,0x60,0xaa,0xcf,0x2e,0x15,0x28,0x9f,0x9e,0xa9,0x9d,0x6d,0x27,0xbc,0x2c,0x24,0x4b,0xbd,0xa5,0x2c,0x15,0x32,0x97,0x9c,0x38,0x1f,0x21,0xce,0xa1,0xa7,0xe5 +,0x28,0xd8,0x9b,0x3d,0x45,0xe1,0x7a,0xc4,0x2d,0x1f,0x2c,0xa8,0xfd,0x34,0x5e,0x3e,0x42,0x9e,0xaa,0x21,0x18,0x31,0x95,0x92,0xb6,0x3e,0x49,0x36,0xd5,0x31,0x6a,0xdf +,0x37,0xab,0x3e,0x11,0x31,0x97,0xa9,0xbb,0x4c,0x2c,0xb7,0xa6,0x62,0xdd,0x4e,0xb0,0xa0,0x24,0x20,0x29,0x69,0xad,0x3e,0x25,0xbd,0xeb,0x2c,0xb0,0xb9,0xb7,0x9e,0xa5 +,0xba,0x26,0x11,0x2c,0x9d,0xa8,0x1f,0x19,0x3d,0x9e,0x9e,0xa6,0xb1,0x21,0x28,0xb7,0x4a,0x3c,0x34,0x55,0xb3,0xd4,0xd3,0xdd,0xad,0x5c,0x1f,0x4a,0xce,0x47,0xa8,0xb5 +,0x2f,0x38,0xa8,0x9c,0xc5,0x35,0x42,0x47,0x1f,0x26,0x36,0xaf,0x9e,0xad,0xb1,0x2f,0x11,0x2b,0x94,0xa4,0x2b,0x28,0x2e,0xa6,0x95,0xad,0xb0,0x34,0x2b,0x32,0x19,0x21 +,0x28,0xf2,0x99,0x9b,0x37,0xbc,0xbe,0x29,0x3d,0xb1,0xac,0xb7,0x3e,0x2a,0x40,0x2d,0xc3,0xa1,0xbf,0x19,0x17,0xc9,0x9f,0xae,0xb3,0x9e,0xf7,0x29,0x53,0x2b,0x2c,0xbf +,0xad,0xc2,0x3f,0x58,0x78,0xa4,0x9f,0x43,0x34,0x29,0x26,0xdc,0xbd,0x2f,0x1d,0x59,0x9f,0x9d,0xb0,0xcc,0x4e,0x2c,0x4c,0xfe,0xbf,0xd0,0x27,0x23,0xad,0xa8,0xe1,0xaf +,0x34,0x19,0x27,0xac,0x9d,0xa3,0x44,0xe5,0xa9,0xab,0x5a,0x15,0x19,0x29,0xd8,0xa3,0xb5,0x2f,0xc5,0x97,0xa0,0x42,0xdf,0x35,0x28,0x46,0xce,0x37,0x22,0x5f,0xb3,0x9d +,0xac,0x46,0x30,0x33,0x40,0xb7,0x9f,0x34,0x1d,0x30,0xad,0xa1,0xa9,0xca,0x2b,0x27,0xd3,0xbf,0x3f,0x45,0x26,0x35,0x99,0x99,0x68,0x1f,0x1d,0x21,0x64,0x9c,0xa4,0x3f +,0x2e,0xa8,0x9b,0xac,0x4d,0x1e,0x25,0x25,0x2d,0xb6,0xbd,0x3c,0x6f,0x9e,0xac,0x44,0x36,0x41,0xde,0x46,0xec,0x47,0xbe,0xbc,0x4b,0xc5,0xb9,0x35,0x29,0xba,0xaa,0xd6 +,0x4b,0x2e,0x1c,0x7c,0x99,0x9a,0xce,0x20,0x26,0x4b,0xb4,0xe6,0x34,0x47,0x5c,0xa9,0x9a,0xbb,0x1e,0x1d,0xd1,0xb3,0xcd,0x40,0x29,0x2a,0xbc,0x90,0x92,0xb1,0x11,0x0d +,0x36,0xb0,0xad,0xca,0xbb,0x47,0x4d,0xc3,0x49,0x45,0xb5,0x9e,0xad,0x3d,0x1c,0x17,0x28,0x9b,0x91,0x9b,0x3d,0x0e,0x17,0xba,0x96,0xa1,0x38,0x1d,0x1b,0xd9,0x97,0x9c +,0xc6,0x3b,0x4c,0xcd,0x48,0x1c,0x19,0x3c,0xa7,0x8e,0x8f,0x42,0x0b,0x11,0xbb,0xa1,0x9f,0xb1,0x2d,0x15,0x35,0x95,0x91,0x9f,0x3c,0x1f,0x20,0x1b,0x1e,0xc9,0xa7,0x9a +,0xa2,0xbc,0x23,0x12,0x54,0x9f,0xa1,0x79,0x2f,0x33,0xd1,0xaa,0xba,0xbf,0x35,0x2f,0xae,0x9c,0x43,0x0f,0x12,0x2e,0xa1,0x8d,0x91,0x2e,0x0d,0x2c,0x9c,0xad,0x2e,0x18 +,0x2a,0xcb,0xa3,0x91,0x9a,0x2d,0x13,0x31,0xa6,0x2e,0x14,0x2e,0xa3,0x98,0x95,0x98,0x2c,0x0d,0x19,0xb6,0x9d,0x2c,0x1a,0xbe,0xa1,0xac,0xbe,0xc3,0x3b,0x3c,0xa4,0xa5 +,0x13,0x0a,0x29,0x99,0x88,0x8a,0xb9,0x0f,0x08,0x1d,0x9b,0x96,0xc9,0x19,0x26,0xf0,0xb6,0x9b,0xa2,0x40,0x28,0xab,0x9c,0x1e,0x08,0x12,0x9e,0x88,0x8f,0x9f,0x2b,0x08 +,0x0f,0xb2,0x9a,0x33,0x23,0xa2,0x9f,0x7a,0xb0,0x9d,0x3f,0x1f,0x34,0xe0,0x1f,0x11,0xed,0x8e,0x8a,0xab,0x1d,0x13,0x11,0xbd,0x90,0x9e,0x1b,0x0e,0x3e,0x9c,0x90,0x95 +,0x48,0x22,0x2b,0xc5,0xa6,0x21,0x0b,0x16,0x9b,0x88,0x94,0xbd,0x16,0x09,0x30,0x8f,0x96,0x1d,0x0e,0x2c,0xa1,0x96,0x9b,0x9f,0x4a,0x17,0x21,0xb6,0x26,0x0a,0x2a,0x8c +,0x89,0xab,0xf2,0x52,0x16,0x1c,0x37,0xbe,0x38,0x1f,0xa0,0x8f,0x9d,0x3e,0x20,0x2c,0x33,0xa9,0x98,0x18,0x02,0x1d,0x8f,0x86,0x89,0xa3,0x11,0x0a,0x38,0x9e,0xb6,0x1d +,0x15,0x52,0x99,0x97,0xa2,0xce,0x1f,0x1e,0xd8,0x9e,0x1f,0x0c,0x2b,0x99,0x88,0x94,0xbe,0x3c,0x16,0x0d,0x1b,0xa3,0xc1,0x1f,0xa0,0x8b,0xaa,0x23,0xbc,0xad,0x25,0x1f +,0xdf,0x17,0x0c,0xab,0x86,0x85,0x9e,0x1b,0x0e,0x0c,0x1d,0xa4,0x9c,0x1c,0x0f,0xa4,0x8a,0x8e,0x97,0x2f,0x0e,0x22,0xa2,0xb6,0x0c,0x0a,0x7b,0x93,0x85,0x8f,0xc3,0x21 +,0x0c,0x0c,0x3b,0x9a,0x2d,0x2f,0x9f,0x8f,0x98,0xba,0x5a,0x28,0x16,0x13,0xcf,0x6f,0x15,0x34,0x8d,0x83,0x9c,0x1f,0x2b,0x0f,0x0c,0x26,0xca,0x30,0x4f,0x8c,0x84,0x93 +,0x2f,0x14,0x0e,0x18,0x36,0xbd,0x17,0x0d,0x59,0x8a,0x82,0x92,0xad,0x21,0x07,0x0e,0xa6,0xb9,0x17,0x4c,0x97,0x8f,0x9c,0xbc,0x50,0x27,0x14,0x0e,0x3d,0x4a,0x25,0xac +,0x90,0x89,0x94,0xb6,0x1c,0x06,0x08,0x30,0x9f,0xaa,0xc1,0x95,0x83,0x92,0x11,0x0c,0x1f,0x1c,0x1c,0x3f,0x1c,0x11,0x9a,0x82,0x81,0x9d,0x27,0x18,0x06,0x07,0x29,0xbf +,0x3e,0xb7,0x9c,0x8a,0x97,0xad,0xd9,0x1a,0x0d,0x28,0x9c,0x1b,0x0e,0xae,0x8a,0x8a,0x93,0xb3,0x15,0x03,0x09,0x2e,0xaa,0xa9,0xb9,0x92,0x84,0x96,0x23,0x1f,0x1e,0x11 +,0x15,0x2a,0x21,0x20,0x9f,0x87,0x80,0x93,0x1a,0x0e,0x0c,0x0b,0x18,0x2b,0x40,0xa9,0x8d,0x82,0x94,0xbc,0xbb,0x24,0x0a,0x0b,0x28,0x1c,0x15,0x72,0x8b,0x86,0x8d,0xaa +,0x25,0x0a,0x09,0xbe,0x99,0x32,0x1a,0x94,0x85,0xa4,0x1f,0x1c,0x19,0x1e,0x29,0x20,0x15,0x2c,0x91,0x84,0x84,0x9c,0x33,0x1b,0x0b,0x09,0x15,0x26,0x2b,0xd7,0x8f,0x84 +,0x90,0xc9,0x1f,0x1c,0x19,0x1a,0x2a,0x46,0x20,0x43,0x89,0x82,0x8f,0x2f,0x13,0x08,0x09,0x29,0xc9,0x2e,0x20,0x97,0x87,0x96,0xad,0xea,0x1f,0x1b,0x29,0x3d,0x1f,0x1a +,0x9e,0x84,0x88,0x42,0x19,0x1f,0x11,0x0b,0x17,0x20,0x2b,0x9d,0x8a,0x85,0x8f,0x5c,0x20,0x49,0x20,0x0f,0x12,0x18,0x1c,0xbf,0x88,0x84,0x89,0x53,0x0b,0x09,0x12,0x20 +,0x1d,0x1c,0x3c,0x8a,0x82,0x8d,0x3e,0x1f,0xe0,0x4f,0x1b,0x0f,0x0f,0x1a,0xab,0x89,0x88,0xa8,0x3c,0x32,0x22,0x13,0x10,0x1d,0x2e,0xaf,0x8f,0x86,0x94,0x31,0x3e,0xb1 +,0x2a,0x12,0x0f,0x0c,0x1f,0x96,0x88,0x8b,0x9a,0x32,0x1c,0x1b,0x1d,0x1a,0x16,0x27,0x6b,0x8e,0x82,0x90,0x30,0x17,0x2e,0xb4,0x2d,0x0a,0x0b,0x4d,0x9d,0x8a,0x87,0x9e +,0x2f,0x25,0x23,0x16,0x0d,0x0e,0x2d,0x9b,0x8c,0x8e,0x4a,0x3b,0x94,0x90,0x11,0x00,0x1d,0xac,0x99,0x8e,0xab,0x2a,0x93,0x88,0x41,0x23,0x38,0x02,0x02,0x00,0x42,0x80 +,0x81,0x87,0x41,0x0d,0x45,0x8f,0x19,0x00,0x3a,0x84,0x8c,0x68,0x02,0x57,0x80,0x85,0x2a,0x02,0x07,0x13,0x16,0x12,0x8d,0x84,0xbd,0x44,0x23,0x9e,0x84,0x35,0x02,0x0e +,0x94,0x8d,0x9b,0x27,0xa0,0x8a,0x3c,0x0e,0x06,0x00,0x2d,0x82,0x8c,0x87,0x9e,0x0c,0x2e,0x88,0x97,0xb3,0x22,0x04,0x06,0x05,0xb1,0x81,0x8f,0x92,0x84,0x9b,0x2d,0x1b +,0x03,0x01,0xab,0x8e,0xa4,0x1f,0x0f,0x93,0x85,0x8b,0x38,0x06,0x03,0xd6,0x86,0x99,0xa2,0x3d,0xb9,0x8e,0x18,0x0e,0xc2,0x30,0x33,0x13,0x0d,0x93,0x8a,0x16,0x68,0x84 +,0x88,0xdf,0x06,0x00,0x4a,0x80,0x86,0xa1,0x24,0xa2,0x8b,0xb7,0x0a,0x0d,0x0a,0x14,0x28,0x0c,0x9c,0x83,0x9b,0x93,0x88,0x94,0x3b,0x12,0x05,0x0a,0xae,0x97,0x5a,0x06 +,0x31,0x81,0x82,0xa5,0x0c,0x02,0x0d,0xa7,0x9e,0x9f,0x97,0x9c,0xa1,0x36,0x0b,0x29,0x2c,0x0e,0xaf,0x95,0xac,0x9e,0xb8,0x3c,0x8a,0x86,0x27,0x06,0x03,0x03,0x4e,0x8f +,0x8f,0xb5,0x2c,0x90,0x83,0x8c,0x1a,0x05,0x04,0x26,0xc6,0x13,0x31,0x8b,0x81,0x88,0xbf,0x10,0x16,0x19,0x20,0x26,0xb3,0x9a,0x3a,0x04,0x15,0x87,0x80,0x9c,0x06,0x04 +,0x17,0xb2,0x9c,0xc1,0xa6,0x88,0x82,0xb7,0x03,0x08,0x16,0x32,0x9f,0x44,0x1d,0xa9,0x93,0xca,0xa2,0x88,0xda,0x07,0x01,0x11,0x91,0x86,0x9f,0x27,0xa5,0x8e,0x8c,0xcf +,0x0c,0x12,0x44,0x1f,0x06,0x08,0x31,0x8d,0x85,0x83,0x8f,0x23,0x06,0x09,0x2b,0x96,0x8c,0xab,0x32,0x23,0x1c,0xa0,0x97,0x1b,0x0c,0x2e,0xa3,0xac,0xba,0x28,0x31,0x94 +,0x83,0x99,0x05,0x02,0x1b,0xa1,0x9a,0xb6,0x34,0x99,0x88,0x99,0x9a,0xa5,0x0f,0x03,0x06,0x0e,0x9a,0x88,0x94,0xc9,0x5d,0xa8,0x9d,0x58,0x06,0x0e,0xa8,0x9c,0x21,0x10 +,0xb6,0x89,0x82,0x89,0x1f,0x06,0x18,0x3b,0x1f,0x17,0x2c,0xd1,0xad,0x66,0xaf,0x8b,0x9f,0x10,0x0b,0x35,0x98,0x8e,0x95,0x9a,0x9b,0xa4,0xac,0x14,0x04,0x13,0x9d,0x94 +,0xad,0x12,0x0f,0x62,0x96,0x8e,0x9e,0x1d,0x0a,0x0d,0x0e,0x13,0xa2,0x8b,0x89,0x8d,0xa7,0xa8,0xc4,0x23,0x0d,0x13,0xc7,0x37,0x0e,0x0f,0xa2,0x88,0x83,0x89,0x1f,0x0b +,0x28,0xaf,0xa8,0xbb,0x52,0x35,0x3b,0x1e,0x21,0xa0,0xa0,0xbd,0x1a,0x0a,0x0f,0x3d,0x9f,0x9a,0x8c,0x85,0x8d,0x19,0x01,0x0b,0x9d,0x86,0x94,0x1c,0x1a,0xac,0xb0,0xaf +,0xc4,0x3c,0x25,0x20,0x0f,0x0a,0x37,0x9d,0x93,0x96,0x99,0xa0,0x36,0x1a,0x17,0x24,0xb4,0xb8,0x1d,0x1a,0xa4,0x8a,0x85,0x8f,0x1d,0x10,0x32,0xb7,0x37,0x18,0x26,0xb7 +,0xab,0x2a,0x16,0x2a,0x46,0xae,0x99,0x9f,0xac,0xdc,0x44,0x3d,0xad,0x9b,0xb2,0x19,0x0b,0x12,0x3e,0xa0,0xb5,0x2a,0xc4,0x91,0x8e,0x98,0x32,0x15,0x26,0xc1,0x32,0x20 +,0xb6,0x94,0x91,0xdc,0x1b,0x29,0x61,0xd3,0x2b,0x1d,0x2d,0x2a,0x13,0x11,0x5c,0x8d,0x88,0x9d,0x1c,0x1f,0xb5,0x9f,0xaa,0x42,0xda,0x9e,0x9f,0x3d,0x1e,0x48,0xac,0xbe +,0x23,0x17,0x1f,0x4f,0xa6,0xcc,0x3e,0xb6,0x6c,0x17,0x15,0x6d,0x8f,0x89,0x9c,0x28,0x25,0xd6,0xad,0xaa,0xbd,0xd0,0x2f,0x10,0x09,0x0d,0x64,0x8d,0x88,0x93,0xbe,0x2a +,0x1e,0x2a,0x5b,0xb5,0xac,0x5b,0x20,0x16,0x1d,0xad,0x94,0x9b,0xb1,0x4d,0x42,0x5c,0x33,0x2c,0xbb,0x9f,0xad,0x1f,0x0e,0x30,0x97,0x9c,0xcf,0x2a,0x27,0xad,0x9d,0xae +,0xa6,0x9e,0xdd,0x15,0x0a,0x0f,0xcb,0x99,0xa1,0x47,0x2e,0xd0,0xc9,0x2f,0x38,0xad,0x9b,0xa6,0x22,0x14,0x61,0x95,0x99,0xb1,0x70,0xad,0x9f,0x43,0x0f,0x0a,0x16,0x3e +,0xb5,0xb0,0xa6,0x9b,0xaa,0x59,0xc7,0xa7,0x9d,0xb5,0x22,0x2b,0xbc,0xc3,0x33,0x16,0x15,0xb3,0x91,0x9e,0x3a,0x1f,0x28,0xb8,0xae,0xde,0x65,0xc1,0xc1,0x36,0x1d,0x24 +,0xd3,0xa7,0x9e,0xa8,0xac,0xa0,0xac,0x3a,0x2a,0x2a,0x2f,0x1d,0x0d,0x16,0xa7,0x91,0x9f,0x24,0x1a,0xad,0x8d,0x8e,0xa8,0x23,0x1e,0x3e,0x3b,0x27,0x3f,0xad,0x9e,0xaa +,0x29,0x1c,0x25,0x24,0x29,0xd9,0xa4,0x9a,0xae,0x19,0x14,0xb5,0x8e,0x91,0xbf,0x23,0x3d,0xa9,0xbd,0x2a,0x22,0xf4,0xad,0x3e,0x28,0x2d,0x3a,0xca,0xbe,0x46,0xc5,0xa7 +,0xc2,0xfa,0xd1,0x46,0x43,0x25,0x15,0x2e,0x9b,0x90,0x99,0xcc,0x3d,0xaf,0xab,0x3e,0x1b,0x15,0x29,0x58,0x25,0x19,0x1f,0xdc,0x99,0x8f,0x93,0x96,0xa4,0x32,0x24,0x39 +,0xbf,0xae,0x52,0x1d,0x18,0x26,0xcb,0x5c,0x29,0x2e,0xbd,0xa1,0x9f,0xcd,0x31,0xb4,0xa4,0xc5,0x37,0x34,0xca,0xa0,0xb4,0x26,0x29,0x4b,0xbe,0xb1,0x3e,0x2b,0x37,0x29 +,0x1b,0x1f,0xce,0xa0,0xa2,0xbc,0xb1,0x9e,0xa0,0xd2,0x21,0x23,0xba,0xa7,0xea,0x30,0x29,0xe0,0xa1,0xb2,0x4d,0x48,0x3e,0x2d,0x20,0x1f,0x2d,0xee,0xf0,0x4f,0xbb,0x9a +,0x90,0xa2,0x44,0x4c,0xbe,0xb0,0xb9,0x30,0x33,0xbe,0x2d,0x15,0x15,0x1f,0xcc,0xa9,0xd3,0x53,0xac,0xa0,0xa4,0xa8,0xc3,0x3e,0xd5,0xe4,0x26,0x1b,0x20,0xe0,0xb6,0xb5 +,0xa8,0xa5,0xa4,0xb8,0x2c,0x20,0x2c,0x37,0x29,0x22,0x2c,0xae,0x99,0x9c,0xab,0xc9,0xbd,0xad,0xb4,0xce,0x50,0x49,0x3c,0x2a,0x24,0x61,0xb4,0xdc,0x3a,0x1f,0x1d,0x3d +,0xc1,0xdb,0xae,0xa4,0xa9,0xba,0xcc,0xbd,0xae,0xae,0xdf,0x3a,0x36,0x3f,0x37,0x2e,0x30,0x29,0x2a,0x25,0x18,0x20,0xb4,0x9d,0x9d,0x9e,0xa6,0x9a,0x96,0xab,0xca,0xd5 +,0x46,0x22,0x16,0x0f,0x21,0xaf,0x9e,0x9f,0xbd,0x33,0x2f,0x3d,0xd1,0xb6,0xdb,0x4a,0x33,0x26,0x46,0x9e,0x97,0xa0,0x48,0x1f,0x31,0xad,0xaa,0xd3,0x3b,0x3d,0xe6,0x36 +,0x24,0x25,0x28,0x34,0x47,0x30,0x3f,0xac,0xa0,0x98,0x9a,0xae,0xb6,0x65,0x24,0x26,0x34,0x47,0xb7,0xbc,0x32,0x3f,0x5b,0x45,0x59,0x58,0x4a,0x33,0x22,0x1d,0x43,0xa0 +,0x91,0x91,0x9f,0xcc,0x37,0x3a,0x3c,0x3a,0x35,0x34,0x1e,0x1b,0x41,0xa0,0x99,0xab,0x2b,0x1d,0x2c,0xef,0xba,0xb3,0xb0,0xae,0x7d,0x2a,0x40,0xb3,0xa5,0xa6,0xc7,0x30 +,0x33,0x7b,0xb7,0xae,0x4f,0x2d,0x2b,0x1d,0x14,0x16,0x23,0xac,0x97,0x9c,0xa0,0x9f,0x9d,0xa0,0xa9,0xa5,0xad,0x2c,0x15,0x11,0x1a,0xfc,0xa4,0xb4,0x48,0x20,0x1e,0x4d +,0xad,0xad,0xbd,0xda,0x3d,0xd0,0xb1,0xa2,0x97,0x9b,0xc9,0x1f,0x17,0x1c,0x38,0xb6,0xa4,0xad,0x35,0x1d,0x1d,0x2b,0xc3,0xb0,0xd7,0x3e,0x43,0xc7,0xa7,0xa3,0xa3,0xa3 +,0xb0,0x43,0x1f,0x1d,0x26,0xe8,0xa9,0x9e,0xab,0x43,0x2b,0x26,0xde,0xa6,0xcf,0x18,0x0e,0x13,0x4b,0x91,0x8d,0x96,0xa5,0xc0,0xba,0xb0,0xc6,0x40,0x32,0x2c,0x1f,0x19 +,0x1b,0x3e,0xae,0xa4,0xbf,0x29,0x23,0x30,0xbc,0x9b,0x90,0x99,0xb5,0x34,0x2f,0x4a,0xe0,0x49,0x2b,0x25,0x2e,0xb9,0xb5,0xe0,0x45,0x46,0xb6,0xbd,0x28,0x16,0x1e,0xc5 +,0x9a,0x98,0xb1,0x6e,0xd6,0xad,0x9c,0x9c,0xde,0x17,0x0f,0x18,0x47,0xab,0xac,0xe6,0x38,0x51,0xd9,0x38,0x29,0x2d,0xca,0x9f,0xa6,0xea,0xdd,0xad,0x9f,0x9e,0xb1,0x2f +,0x1f,0x1f,0x2a,0xc6,0xb5,0x7b,0x2a,0x28,0x59,0xbc,0xda,0x25,0x21,0xe5,0x9a,0x98,0xaa,0xd6,0xe7,0xa3,0x97,0xb5,0x16,0x0d,0x1b,0xcc,0xa6,0xb9,0x34,0x2b,0x5b,0xa0 +,0x98,0xa7,0x29,0x15,0x1a,0x35,0xb3,0xa6,0xaa,0xc4,0xb3,0xa0,0xa5,0x7d,0x2a,0x27,0x4a,0xb5,0x44,0x21,0x23,0xcc,0x9e,0xac,0x28,0x14,0x1e,0xbe,0x9f,0xa1,0xb3,0x53 +,0x47,0xa1,0x95,0xa0,0x2f,0x14,0x16,0x3f,0xa2,0xab,0x2e,0x1c,0x28,0xa9,0x9c,0xd8,0x1c,0x1d,0x6e,0xa8,0xae,0xdf,0xe3,0xa9,0x98,0x97,0xa7,0x30,0x18,0x18,0x32,0xbc +,0xd3,0x2c,0x1a,0x22,0xaf,0x9d,0xa7,0x5b,0x4c,0xae,0xa4,0xcf,0x25,0x24,0x4e,0xa8,0xaa,0x52,0x2d,0x32,0x4a,0xbc,0xa3,0x9f,0xaa,0x77,0x2e,0x21,0x19,0x1a,0x29,0xca +,0x9f,0x9d,0xb3,0x31,0x36,0xa7,0x96,0x9a,0xba,0x31,0x29,0x2b,0x33,0x2e,0x23,0x1f,0x2a,0x5d,0xb5,0xa6,0xa7,0xb0,0xce,0x44,0x37,0x43,0xba,0xa6,0xa9,0xc7,0x32,0x27 +,0x2a,0x4e,0xa5,0x99,0x9b,0xce,0x1c,0x13,0x18,0x2a,0x4f,0x6e,0x4b,0x5d,0xbb,0xa8,0x9e,0x9e,0xa7,0xdc,0x27,0x23,0x4a,0xa4,0xa1,0xd2,0x29,0x23,0x2e,0x3d,0xdd,0xad +,0xa5,0xae,0x38,0x1c,0x18,0x1f,0x53,0xa7,0x9c,0x9e,0xb2,0x38,0x2a,0xce,0x9d,0x9b,0xb3,0x2c,0x20,0x28,0x33,0x2e,0x26,0x25,0x35,0xb1,0x9e,0x9a,0x9e,0xaf,0x4f,0x28 +,0x21,0x2a,0x4a,0xbc,0xaf,0xbd,0x41,0x2b,0x26,0x30,0xaf,0x99,0x96,0xa3,0x3e,0x1c,0x18,0x1f,0x31,0xdc,0xb5,0xae,0xa9,0xac,0xbe,0xe9,0x59,0xea,0xd4,0xeb,0x43,0x34 +,0x47,0x63,0x37,0x2e,0x3b,0xe3,0xc8,0xbb,0xac,0xab,0xd3,0x2a,0x1f,0x2f,0xbb,0xab,0xa5,0xa1,0xa3,0xbb,0x2d,0x20,0x2a,0xd8,0xb2,0xd9,0x2e,0x24,0x22,0x28,0x4f,0xa7 +,0x9c,0xa6,0xd2,0x5b,0xbd,0xb3,0xcc,0x46,0x44,0x6f,0x76,0x33,0x29,0x44,0xbb,0xb8,0x64,0x3a,0x4e,0xc0,0xe0,0x36,0x33,0x49,0x7e,0x42,0x4e,0xb8,0xaa,0xbf,0x2c,0x26 +,0x48,0xaa,0x9d,0x9c,0xa0,0xbc,0x28,0x19,0x15,0x24,0xae,0x9e,0xaa,0x64,0x3a,0x47,0xcb,0xc4,0xb7,0xa9,0xab,0xc1,0x3b,0x2d,0x2d,0x33,0x51,0x6b,0x54,0x48,0x4d,0xda +,0xc7,0xc5,0x50,0x3a,0x37,0x2f,0x3d,0xb2,0x9f,0xa4,0xc3,0x3a,0x41,0xd2,0xd3,0x43,0x4e,0xe1,0x57,0x31,0x23,0x2d,0x6a,0xb8,0xb9,0xba,0xb4,0xb3,0xbc,0x3c,0x2c,0x31 +,0xee,0xb3,0xb6,0xb3,0xaa,0xaf,0x5a,0x2b,0x37,0xb0,0x9f,0x9f,0xb1,0x4e,0x23,0x17,0x13,0x19,0x35,0xb3,0xa6,0xb5,0x5b,0x57,0xcb,0xaf,0xaf,0xc5,0x4f,0x3a,0x2c,0x1e +,0x28,0xc1,0xa4,0xa2,0xb4,0x6e,0x46,0x67,0xc1,0xb7,0xa6,0x9f,0xa4,0xb9,0x44,0x3c,0x41,0xde,0x72,0x3e,0x3f,0x46,0x47,0x37,0x2c,0x26,0x29,0x29,0x1f,0x2b,0xcb,0xb7 +,0xc8,0xd8,0xbd,0xad,0xa8,0xad,0xc7,0xe0,0x4f,0x4e,0x6f,0x69,0xb5,0xa0,0xa2,0xba,0x38,0x26,0x28,0x3c,0x4e,0x44,0xce,0xc9,0x3c,0x30,0x3f,0xc2,0xbe,0xc9,0xe1,0xd8 +,0xba,0xb2,0xad,0xba,0x51,0x30,0x28,0x1e,0x1e,0x3d,0xaa,0x9e,0xa4,0xba,0x45,0x3f,0x45,0x42,0x5e,0xbb,0xb3,0xdb,0x3c,0x3c,0xf2,0xbb,0xb0,0xba,0xe6,0x5f,0xf1,0x55 +,0x32,0x2e,0x42,0x77,0x44,0x3d,0x5a,0xcb,0xc4,0xd4,0x6d,0x6f,0xbd,0xb8,0x6c,0x44,0xe8,0xfc,0x3d,0x3a,0x5f,0xca,0xc6,0xc8,0xf2,0x58,0x4a,0xe6,0xc0,0x5b,0x4b,0x58 +,0x3f,0x4b,0xb5,0xa1,0xa0,0xa4,0xbc,0x2b,0x21,0x29,0x44,0xd1,0xd9,0x41,0x2d,0x27,0x25,0x27,0x32,0xb6,0x9e,0xa1,0xc0,0x5a,0x4b,0x35,0x3c,0xd6,0xb6,0xb6,0xc6,0xe6 +,0xd9,0xba,0xac,0xaf,0xba,0xb2,0xae,0xcf,0x2b,0x22,0x28,0x33,0x69,0xb3,0xa8,0xab,0xc1,0x39,0x21,0x20,0x37,0xcf,0xbb,0xb8,0xc5,0x4a,0x2e,0x26,0x2b,0x4c,0xae,0xa0 +,0xa6,0xce,0x3e,0x5e,0xee,0x71,0xe0,0x5e,0xf1,0xd1,0xee,0x5e,0xcb,0xb1,0xc7,0x2f,0x29,0x3c,0x71,0x3c,0x2f,0x35,0x3c,0x55,0x66,0xc5,0xa9,0xa1,0xa1,0xae,0x63,0x4b +,0xd8,0xc0,0xc3,0xce,0xed,0x57,0x31,0x24,0x26,0x37,0xc2,0xae,0xba,0xea,0x5c,0x37,0x29,0x2d,0x40,0xbe,0xab,0xac,0xb1,0xba,0xb4,0xb0,0xc0,0x7e,0xce,0xba,0x72,0x2e +,0x25,0x24,0x2c,0x3b,0x3d,0x44,0xd2,0xbc,0xe5,0x3b,0x3f,0xd3,0xb4,0xb0,0xbb,0xc6,0xc6,0xc4,0xcf,0xce,0xb9,0xab,0xa6,0xba,0x3b,0x2f,0x37,0x3d,0x34,0x30,0x39,0x40 +,0x38,0x2e,0x2e,0x41,0xbe,0xad,0xa9,0xaf,0xc4,0x47,0x2c,0x29,0x30,0xda,0xac,0xb1,0xe3,0xef,0xda,0x6a,0x60,0xc2,0xad,0xa8,0xb9,0x3c,0x2d,0x2d,0x3b,0xcc,0xb7,0xaa +,0xab,0xd2,0x3a,0x2e,0x32,0xea,0xc6,0x45,0x3b,0x3b,0x34,0x46,0xce,0xb6,0xa7,0xa5,0xab,0xbc,0x60,0x51,0x53,0x3e,0x34,0x35,0x31,0x30,0x37,0x35,0x3a,0x54,0xd8,0xe1 +,0x3d,0x38,0x57,0xc1,0xbd,0xd1,0xda,0xbf,0xbb,0xba,0xb4,0xae,0xaa,0xae,0xb9,0xb4,0xad,0xb1,0x43,0x1f,0x1b,0x1e,0x2c,0x4b,0x4b,0x45,0x75,0xec,0x4c,0x3f,0xdf,0xb4 +,0xb4,0xbf,0xc2,0xca,0x57,0x3d,0x54,0xaf,0xa7,0xaa,0xba,0x49,0x2e,0x30,0x57,0x4e,0x33,0x2f,0x35,0x3d,0x48,0x6e,0xcb,0xbe,0xb0,0xae,0xb2,0xb6,0xb9,0xbf,0x69,0x4a +,0x4f,0x42,0x3b,0x47,0xde,0xbc,0xb3,0xbc,0xcd,0x52,0x3d,0x33,0x29,0x32,0x48,0x4e,0x58,0x3a,0x2e,0x2d,0x35,0xd6,0xad,0xa3,0xa1,0xb0,0x3e,0x2c,0x35,0xdf,0xb3,0xac +,0xad,0xbb,0x6b,0x45,0x41,0xde,0xb5,0xaa,0xba,0x2b,0x1d,0x1f,0x27,0x2e,0x3c,0xbf,0xa7,0xa2,0xa8,0xb6,0xce,0x56,0x4c,0x55,0x4f,0x55,0x4d,0x4e,0x57,0x5c,0xde,0xc9 +,0xd1,0xcf,0xb4,0xae,0xb8,0x40,0x26,0x25,0x2c,0x43,0xc4,0xbc,0xd4,0x38,0x37,0xcf,0xad,0xa7,0xaa,0xbd,0x53,0x3b,0x37,0x36,0x37,0x4e,0xcb,0xd1,0x7a,0xdd,0xc1,0xb7 +,0xb2,0xb5,0x4c,0x27,0x22,0x2c,0x44,0xce,0xbc,0xcf,0x45,0x39,0x3e,0xcc,0xa5,0x9d,0xa7,0xce,0x3c,0x2e,0x29,0x34,0xe5,0xba,0xad,0xaf,0xd5,0x47,0x67,0xc5,0xe3,0x3b +,0x34,0x33,0x29,0x24,0x27,0x37,0xce,0xb0,0xa1,0x9c,0xa0,0xae,0x74,0x2e,0x2e,0xea,0xb5,0xb6,0xc7,0x42,0x37,0x32,0x2f,0x44,0xc1,0xad,0xae,0xe3,0x33,0x2b,0x2a,0x30 +,0x44,0xf2,0xca,0xc1,0xbe,0xb8,0xb3,0xad,0xa8,0xae,0xcd,0x3e,0x36,0x2f,0x26,0x26,0x2b,0x3b,0xe7,0xcb,0xbe,0xb1,0xab,0xb1,0x5c,0x39,0x4a,0x6b,0xe6,0xc4,0xcd,0x53 +,0x43,0x3d,0xce,0xac,0xaa,0xb3,0x45,0x27,0x28,0x3f,0xcc,0xdb,0x39,0x2d,0x42,0xc0,0xaf,0xa9,0xa7,0xae,0x42,0x22,0x1f,0x2d,0xcc,0xac,0xaa,0xb5,0xcb,0xda,0xd8,0xc9 +,0xae,0x9f,0xa1,0x42,0x1b,0x18,0x24,0x40,0x6a,0xdc,0x6e,0x3a,0x2e,0x3a,0xc1,0xa6,0x9d,0xa3,0xbf,0x44,0x33,0x34,0x46,0x50,0x41,0x3a,0x3e,0x45,0x66,0xb9,0xaa,0xb4 +,0x3d,0x2e,0x38,0x3d,0x56,0xe5,0x4e,0x45,0xff,0xbe,0xac,0xa7,0xaa,0xaf,0xcb,0x45,0x3c,0x4d,0xbd,0xb3,0x5d,0x29,0x24,0x2c,0x3d,0xd6,0xb5,0xb0,0x60,0x22,0x1d,0x27 +,0xf2,0xa3,0x9e,0xac,0xbf,0xcf,0xd0,0xcb,0xb8,0xa7,0xa3,0xaf,0x37,0x1c,0x1a,0x27,0x3e,0x46,0x40,0x56,0xda,0xc9,0xb5,0xab,0xab,0xb2,0xd7,0x63,0xc5,0xb3,0xb3,0x3e +,0x1b,0x18,0x25,0x6d,0xaf,0xa5,0xa4,0xaa,0xd9,0x2e,0x2c,0x3a,0xd4,0xba,0xea,0x2f,0x25,0x29,0x48,0xae,0xa1,0xa5,0xb5,0x46,0x38,0x67,0xb5,0xae,0xcb,0x2f,0x26,0x30 +,0xe9,0xaf,0xa9,0xaf,0xcf,0x3b,0x28,0x26,0x3a,0xb2,0xa7,0xb6,0x3c,0x29,0x2c,0x4f,0xa7,0x9d,0xa2,0xb8,0x2f,0x1e,0x1f,0x37,0xaf,0xaf,0x4c,0x35,0x3f,0xe4,0xb4,0xa7 +,0xa2,0xa3,0xb0,0x43,0x29,0x28,0x3a,0x41,0x2a,0x1f,0x23,0x35,0xc8,0xa7,0xa5,0xae,0xb5,0xcb,0x6e,0xcb,0xac,0xaa,0x52,0x1f,0x1b,0x1e,0x2f,0xad,0x9e,0xa2,0xac,0xcb +,0x33,0x26,0x3c,0xab,0xa6,0xcb,0x2c,0x1d,0x21,0xd8,0xa6,0xa7,0xae,0xc6,0x31,0x1e,0x25,0xc0,0xa4,0xa8,0xcd,0x3c,0x38,0x58,0xb8,0xab,0xa6,0xa7,0xbe,0x2e,0x22,0x2b +,0x3e,0x4b,0x36,0x21,0x20,0x37,0xaa,0x9b,0x9e,0xa0,0xad,0x4f,0x42,0xc7,0xab,0xa7,0xcc,0x25,0x19,0x1a,0x2c,0xbf,0xb5,0xb4,0xaf,0xc9,0x38,0x2b,0x39,0xbd,0xb9,0x3b +,0x20,0x1c,0x2a,0xaf,0x9d,0x9b,0x9e,0xb6,0x45,0x3f,0xc5,0xa3,0xa1,0xb9,0x29,0x17,0x1a,0x3a,0xb8,0xb2,0xb5,0xd2,0x2f,0x1f,0x21,0x3d,0xae,0xa2,0xab,0x54,0x35,0xd5 +,0xa2,0x9d,0x9f,0xa6,0xcb,0x28,0x1e,0x28,0x4c,0x4f,0x31,0x20,0x1f,0x27,0x6c,0xa2,0xb1,0xb6,0xa6,0xb6,0x32,0x4f,0xbc,0xa9,0xab,0x34,0x27,0x42,0x67,0x5f,0x9e,0xa3 +,0xb4,0xbb,0x4e,0x15,0x0d,0x28,0xa7,0x9a,0x4f,0x38,0xa7,0xa2,0xc3,0x32,0x37,0x28,0x23,0x3f,0x40,0x26,0x2e,0x9c,0x8e,0x9c,0xae,0xb2,0x62,0x18,0x1c,0xc2,0x38,0x36 +,0x2f,0x37,0xb9,0xa3,0x9c,0xa7,0x30,0x1e,0xcc,0xbe,0x2e,0x2d,0xa9,0xad,0x72,0x3c,0x32,0x44,0x26,0x5d,0xa6,0xa4,0x2c,0x33,0x51,0xa9,0x9a,0xbf,0xbd,0x16,0x20,0xa2 +,0xb2,0x23,0x1e,0xbd,0xa3,0xb1,0xe3,0x2b,0x32,0x37,0xc3,0x98,0xb7,0x2c,0x4d,0x9e,0xbe,0x46,0xab,0xbd,0x19,0x19,0xb2,0xa6,0x6a,0x20,0x6a,0xb8,0xd0,0xd7,0xab,0x38 +,0x18,0x31,0xaa,0xb2,0x22,0xb0,0x97,0xa5,0x69,0x3e,0x27,0x16,0xb7,0x98,0x48,0x1d,0x26,0xa2,0x9f,0x55,0x6c,0xdd,0x2e,0x17,0x37,0xa4,0xe3,0x64,0xa3,0xa6,0xaf,0x71 +,0x36,0x28,0x1e,0xca,0xa0,0xbf,0x27,0x1e,0xbf,0x9a,0xa8,0xb5,0xae,0x20,0x0f,0x32,0x99,0x9b,0xd7,0xbf,0x23,0x20,0x47,0xbb,0x9f,0x2c,0x38,0xbb,0x3f,0x1b,0x34,0x8d +,0x90,0x41,0x2d,0x26,0x14,0x1c,0xae,0x97,0x47,0x24,0xbc,0xad,0xbd,0xa9,0x9e,0xf4,0x19,0x1c,0xd4,0xe9,0x2d,0xc9,0x9e,0x40,0x22,0xb5,0xb4,0x17,0x18,0xa7,0x8f,0xae +,0x1e,0x42,0xad,0x93,0x9b,0xde,0x23,0x0c,0x1f,0xa2,0xae,0x3d,0xe4,0xa1,0x5c,0x2e,0xb3,0xa6,0x66,0x1f,0x3d,0xbf,0x3b,0x2f,0xb0,0xa1,0xad,0x25,0x28,0x74,0x26,0xad +,0x8e,0xac,0x19,0x20,0xe4,0x9a,0xb4,0x1a,0x18,0x15,0x45,0x91,0x8b,0xa3,0x1a,0x1d,0x4e,0xdb,0x21,0x41,0xa9,0xaf,0x36,0x6b,0x9f,0xab,0x9e,0xab,0x31,0x0b,0x0e,0xcc +,0x9f,0x9e,0xab,0x9c,0x9e,0x25,0x17,0xcb,0xc7,0x34,0x2f,0x2a,0x1b,0x25,0x8f,0x90,0xd9,0x30,0xd4,0xbf,0x2c,0x1f,0x3b,0xb5,0xd2,0xbd,0x9f,0x41,0x17,0xdf,0x90,0xa4 +,0x1a,0x1a,0x27,0xcd,0xac,0x9b,0x9c,0xac,0x2e,0x13,0x33,0xe3,0xc8,0xbf,0x27,0x19,0x36,0x9a,0x94,0xab,0xde,0xba,0x45,0x26,0x21,0x3a,0xbe,0xa5,0xa1,0xbf,0x25,0x1a +,0xad,0x90,0x37,0x0e,0x1d,0xec,0xb1,0xa1,0x8f,0xaa,0x17,0x1e,0xa6,0xa6,0x26,0x1c,0x2a,0xa9,0x4f,0xce,0xb6,0x75,0xb6,0xa9,0xab,0x1a,0x1c,0x42,0x46,0xc8,0x99,0x95 +,0xcd,0x27,0x2a,0xfe,0xcc,0x4b,0x2b,0x26,0x1c,0x2c,0x99,0x8d,0x9c,0x2f,0x41,0xdd,0x28,0x1e,0x2c,0xad,0x9d,0xba,0x2a,0x28,0x3f,0xaa,0x90,0xa8,0x0e,0x11,0x44,0x98 +,0xa0,0xa5,0xac,0x29,0x1d,0x2e,0xc5,0x19,0xcb,0xa2,0x4a,0x29,0x29,0x99,0x93,0xbd,0x1f,0xfc,0xb6,0x23,0x1f,0xdc,0x53,0xbf,0x97,0xab,0x28,0x28,0xfe,0xb7,0xcf,0x2b +,0x1f,0x23,0xe8,0x9b,0x96,0xb2,0x2f,0x32,0xc8,0x26,0x1a,0xc4,0x9d,0x9f,0x37,0x3f,0x48,0xb3,0xa9,0xd6,0xbb,0x16,0x14,0x35,0x9f,0x9c,0xc6,0xab,0xb1,0x34,0x18,0xca +,0x9c,0xc7,0x2f,0x1a,0x23,0xad,0x8f,0x95,0x46,0x17,0x25,0xcc,0xd7,0x4c,0x2e,0x3d,0x5a,0xa6,0x9b,0x37,0x19,0xb4,0x96,0x49,0x17,0x1e,0x3e,0xae,0xb8,0xba,0xcc,0xaa +,0xc6,0x2b,0x63,0x1b,0x3a,0xaf,0xa9,0xc6,0x67,0xab,0xcb,0xab,0x69,0x4d,0x34,0x1e,0x1f,0x6a,0xad,0x9a,0x94,0x4e,0x1b,0x1a,0x54,0x97,0xa8,0x1c,0x17,0x1f,0xb1,0x94 +,0x91,0xae,0x1b,0x18,0x40,0xbe,0xfb,0x38,0xbd,0xa2,0x4f,0xbb,0xc7,0xac,0xb6,0x50,0x2c,0x0f,0x2a,0xa2,0xa2,0x39,0x51,0xaa,0x3c,0x46,0xcc,0xdc,0x2c,0x25,0xcb,0xad +,0xbd,0x32,0xa1,0x9a,0x5b,0x22,0x2c,0xbb,0xeb,0x2c,0x19,0x3a,0x9a,0x94,0xa9,0x24,0x18,0x27,0xa9,0xa0,0xd8,0x1e,0x28,0x6a,0xa2,0x97,0xab,0x41,0x1d,0x28,0x53,0x24 +,0xa7,0x9e,0x64,0x20,0x37,0x93,0x9c,0x6e,0x1c,0x29,0x2b,0x39,0xa4,0x9c,0x40,0x1f,0xab,0xbe,0x3e,0x2c,0x3d,0xbf,0x78,0xc7,0x3c,0x2e,0xb5,0x9a,0x9d,0x29,0x15,0x2f +,0xae,0xc8,0x2d,0x23,0x47,0xac,0x9f,0x92,0x3c,0x17,0x1c,0xc0,0x9f,0xce,0xd1,0x23,0x47,0xfb,0xa7,0x98,0xb1,0x22,0x11,0x24,0x52,0x99,0x98,0xbd,0x1d,0x21,0x9f,0x99 +,0xa7,0x20,0x1c,0x24,0x32,0xa9,0x9f,0xa8,0x2d,0x49,0xba,0x2a,0x19,0xb7,0x98,0x3f,0x1c,0x29,0xad,0xb0,0x9c,0x9b,0x30,0x1a,0x1c,0xa3,0xa2,0x4c,0x5e,0x3b,0x3d,0x3a +,0xaa,0xa5,0x41,0x2f,0x27,0x23,0x33,0xa1,0x9d,0xc3,0x1f,0x35,0xa0,0xa3,0xc6,0x16,0x1a,0x35,0xae,0x97,0x9b,0x42,0x13,0x35,0x9b,0xa4,0x26,0x29,0x2d,0x2d,0xc6,0xa8 +,0x97,0xc8,0x34,0x65,0x39,0x23,0x28,0x9e,0xb8,0x28,0xeb,0xbc,0xbc,0x4f,0xaa,0xaf,0x2a,0x21,0x43,0xb0,0x72,0xa5,0x9b,0xbe,0x11,0x1f,0x99,0x97,0x5b,0x11,0x1c,0x20 +,0xa7,0x91,0xa6,0x1d,0x1b,0xa0,0x99,0xae,0x18,0x16,0x23,0xb4,0x9c,0x97,0xa8,0x13,0x2d,0xb3,0xb7,0xce,0x3f,0x3f,0x1d,0x2f,0xa7,0x97,0x99,0x41,0x24,0x28,0x29,0x2a +,0xd8,0x9f,0xbd,0x31,0xdc,0xb5,0x28,0xbe,0x9d,0xb3,0x2d,0x18,0x38,0xbf,0x9f,0xa0,0xb4,0x1f,0x13,0xc4,0x9a,0xad,0x21,0x3c,0x26,0x39,0xa1,0x94,0xac,0x15,0x77,0xa5 +,0xa4,0x38,0x1d,0x28,0x29,0x3f,0xa8,0x94,0xa8,0x27,0x1b,0x24,0x3b,0xa0,0x9a,0xdc,0x19,0x1f,0xa8,0x96,0x9e,0x46,0x1d,0x1f,0x41,0x2a,0xbc,0xa7,0xd8,0x4c,0xdd,0x2d +,0x22,0xab,0xa3,0xbe,0x2d,0x3b,0x61,0xad,0xa4,0xa2,0xbf,0x16,0x24,0xc9,0x9f,0xbf,0x26,0x33,0x27,0x64,0x9d,0x95,0x71,0x19,0x2b,0xd2,0xb6,0xb4,0xe3,0x23,0x1d,0x38 +,0x96,0x8d,0xb5,0x26,0x1d,0x18,0x3c,0x9e,0x98,0xd7,0x1e,0x39,0xb5,0xae,0x4d,0x2c,0x39,0xcc,0x38,0x2b,0x5e,0xa0,0x9c,0xad,0x27,0x14,0xd8,0xa4,0xa2,0x34,0x14,0x29 +,0xa8,0x98,0xa9,0xce,0x2a,0x23,0x34,0xb9,0xa8,0xc8,0xd1,0x34,0x19,0xee,0x95,0x99,0x35,0x17,0x32,0xbe,0xa6,0x65,0x45,0x27,0x22,0xb0,0x9a,0x9e,0x41,0x36,0x20,0x1f +,0x38,0xab,0xb4,0xad,0xae,0xc3,0x43,0x34,0xa4,0xcc,0x6a,0x35,0x25,0x36,0xac,0x9f,0xb2,0x26,0x0f,0x26,0x9f,0x9d,0xb4,0x44,0x1e,0x2a,0xaa,0x9a,0xa3,0xd6,0x32,0x28 +,0x25,0x37,0xac,0xb5,0xb4,0x25,0x1b,0xb5,0x9d,0xa2,0x3b,0x18,0x29,0xa9,0xa8,0xc7,0x38,0x2e,0xc8,0xa2,0xa7,0xd6,0xbd,0xbf,0x21,0x15,0x20,0xab,0x9f,0xae,0x39,0x38 +,0x6b,0xaf,0xa7,0x34,0x2a,0x50,0xb8,0x49,0xb8,0x9f,0xb5,0x27,0x19,0x43,0xba,0xbe,0xac,0x46,0x26,0x36,0xbe,0x9b,0x9f,0xc5,0x2d,0x1d,0x22,0xb5,0xa2,0xe8,0x26,0x18 +,0x34,0x95,0x91,0xaf,0x30,0x1c,0x3f,0xad,0xf7,0x37,0x31,0x28,0x3f,0xba,0xc1,0xae,0xb1,0xbc,0x27,0x25,0x45,0xbd,0xa2,0x9e,0x36,0x22,0x4a,0xb0,0xa6,0x3a,0x29,0x2a +,0xba,0xd8,0xc4,0x9f,0xb0,0x24,0x17,0x2b,0xac,0x98,0xa9,0x27,0x14,0x38,0x9f,0x98,0xb6,0x2b,0xde,0xb2,0xd7,0x79,0x5a,0x29,0x33,0x23,0x3c,0xab,0xa8,0xac,0x3d,0x24 +,0x41,0xae,0xad,0xbf,0x3b,0x32,0x29,0xd1,0xa2,0xa4,0xb8,0x33,0x14,0x14,0xa4,0x9b,0xce,0x67,0x35,0x38,0xaf,0xad,0xd0,0x3e,0x34,0xc5,0xc6,0x3c,0xb9,0xa1,0xae,0x2f +,0x28,0x56,0x42,0x2f,0xc0,0xc6,0x28,0x26,0xbc,0xa6,0xbe,0x5b,0x5f,0xaf,0xad,0xa6,0xc2,0x31,0x25,0x17,0x26,0x99,0x90,0xbb,0x20,0x14,0x25,0x9f,0x8d,0xa8,0x1b,0x1e +,0x34,0xbb,0xa5,0xb7,0x34,0x36,0x1e,0x35,0xa9,0xac,0xc8,0xbe,0x3b,0x3c,0xa3,0xad,0x46,0x23,0x4c,0xc7,0xe2,0x2e,0x49,0xbe,0xde,0x3f,0x1e,0xbf,0xac,0xc3,0xac,0xbf +,0x39,0x57,0xc7,0xd2,0xd8,0x52,0x52,0x57,0x46,0xa8,0xa6,0x29,0x18,0x1e,0xca,0xb5,0xa8,0xb1,0xed,0xed,0xb5,0xa4,0xdd,0x39,0x2a,0x40,0x60,0xbc,0xaf,0x3b,0x36,0x4d +,0x5c,0x38,0xb0,0xb8,0xe1,0x7d,0x1f,0x22,0x5d,0x96,0x9b,0xb5,0x56,0x33,0x29,0x27,0xca,0x59,0x5d,0x3f,0x53,0x6e,0x58,0xa7,0xa1,0x2e,0x25,0xb2,0xb8,0x32,0x1f,0x1f +,0xbd,0x99,0x9d,0xa2,0x3a,0x30,0x42,0x36,0x3a,0xc8,0x5c,0x2f,0xea,0x67,0xb0,0xdc,0xe3,0x32,0x5f,0xb6,0x2f,0x28,0xcb,0x95,0xa1,0xc7,0x22,0x1d,0x39,0xbf,0x9e,0xb8 +,0x2a,0x25,0x49,0xb6,0xaf,0x9f,0xc5,0x2d,0x30,0xbf,0xb0,0x2e,0x29,0x24,0xbd,0x9a,0xa1,0x3e,0x22,0x1e,0x26,0xa5,0xab,0xc2,0x47,0x51,0xa7,0xbd,0xda,0x37,0x2c,0x35 +,0xbf,0xbe,0x1e,0x18,0x3c,0x8e,0x98,0xa8,0xbd,0x23,0x2a,0x31,0xcd,0x33,0xd4,0x3b,0xd7,0xaa,0xb6,0xaa,0x28,0x19,0x2d,0xa9,0xb6,0x3a,0x1e,0x2d,0x97,0x8e,0x9b,0xdc +,0x2d,0x24,0x3f,0xa2,0xad,0x28,0x15,0x1d,0xbe,0xbd,0xaf,0xb9,0xbb,0x36,0xc7,0xb3,0x2c,0x33,0xd6,0x99,0xa9,0x3f,0x1f,0x2d,0x2f,0x4e,0xb5,0x38,0xba,0xd9,0xdf,0x5f +,0x2c,0x36,0xd9,0xac,0xa1,0xa8,0x4d,0x21,0x19,0x3c,0x9a,0x9e,0x6e,0x21,0x27,0x2a,0xcf,0x9a,0x9b,0xc3,0x1c,0x4b,0xbc,0x42,0x32,0x2c,0x42,0xc4,0xab,0xac,0xbd,0x46 +,0xaf,0xa8,0x3b,0x29,0x2f,0xc9,0xb3,0x2f,0x30,0xc2,0xa2,0xbb,0x74,0x75,0x25,0x3a,0xba,0xae,0x68,0x53,0x4c,0x4c,0x2e,0xe1,0x9c,0xa8,0x28,0x1f,0x42,0x2d,0xda,0xa9 +,0xaa,0xd3,0x24,0x43,0xbb,0x2f,0x34,0x44,0x62,0xaf,0x9e,0xb7,0x27,0x21,0x2c,0xaa,0xab,0xb9,0x3d,0xb7,0xc9,0x2b,0xbd,0x9c,0x9b,0x32,0x1e,0x1a,0x1b,0x28,0xb7,0x9e +,0xac,0x3a,0xb2,0x9c,0x75,0x43,0x4e,0x45,0x38,0xc6,0x9f,0xc6,0x30,0xda,0xbe,0xd0,0x34,0x36,0x2c,0x1b,0x1b,0x38,0x9d,0x90,0x96,0xbf,0x46,0x2b,0xcf,0x9d,0x3b,0x13 +,0x16,0x3e,0xee,0x35,0xb4,0x98,0x97,0x2a,0x18,0x2b,0x30,0xf9,0xbd,0xa5,0xa2,0xeb,0xc8,0x9f,0x29,0x1e,0x3c,0x3b,0xda,0x6f,0x51,0x36,0xc4,0xb5,0x9d,0x99,0x4e,0x27 +,0x2a,0x27,0x1b,0x43,0x9a,0x9a,0xe1,0x37,0xdf,0x25,0x4f,0xa9,0xd0,0x36,0x3c,0x9c,0x9d,0x36,0x27,0xb8,0xab,0x2d,0x24,0x49,0x2e,0x1d,0xeb,0xa6,0x9c,0xaf,0xb5,0xd7 +,0x1b,0x28,0x30,0xc0,0xa9,0xc2,0x2b,0xdf,0xbe,0xd7,0xa2,0xb5,0x22,0x1c,0x3d,0x48,0x4a,0xde,0xa0,0x97,0x7d,0x1e,0x3f,0x3a,0x60,0xcb,0xf9,0xa7,0x66,0xbd,0xa3,0x2a +,0x1d,0xa7,0xa8,0x2e,0x26,0x2c,0x39,0xcb,0xad,0xb5,0xac,0x38,0x6a,0xc1,0x33,0x38,0xbd,0x9c,0x9f,0x39,0x1e,0x45,0x35,0xd9,0xb4,0x2e,0x22,0x39,0xab,0xa2,0xcc,0x27 +,0x46,0xa1,0xba,0x2c,0xd1,0xbf,0x5f,0x53,0xab,0x9e,0x5b,0x21,0x19,0x16,0x29,0xb1,0xa4,0xa6,0xcf,0x44,0xa8,0x9b,0xb6,0x3e,0x47,0x21,0x26,0xe4,0x35,0x38,0xb0,0x9a +,0xa4,0x26,0x18,0x2f,0x36,0xb8,0x9f,0xab,0xa7,0xca,0xb3,0xae,0x23,0x12,0x30,0xb3,0x35,0x29,0x3d,0xcd,0x99,0x98,0xac,0xad,0x38,0x24,0x1b,0x2e,0xb3,0xac,0xb3,0xa4 +,0x3e,0x19,0x39,0x30,0x2b,0x33,0xb7,0xb7,0xb6,0xae,0xad,0xaa,0xbe,0xb7,0xc4,0x21,0x0f,0x41,0xa6,0xb6,0xd8,0xaa,0x9f,0xcd,0xc9,0x2d,0x14,0x18,0xb4,0x99,0xad,0x4a +,0x35,0x3a,0x9e,0x9c,0xcb,0x26,0x13,0x1e,0xb3,0xa3,0xb8,0xa9,0xbc,0x50,0x4f,0x44,0x4e,0x22,0x20,0x26,0xc9,0x9a,0x94,0xae,0x3f,0xbc,0x2d,0x2b,0xea,0x2b,0x19,0x2d +,0xad,0x96,0xa2,0x49,0xbd,0xbf,0x44,0x1c,0x1c,0x43,0xb6,0x9e,0xa3,0x39,0x2c,0xaf,0xa3,0x3d,0x39,0x32,0x1f,0x3e,0xa5,0xad,0x2e,0x46,0xc3,0xae,0xb0,0x5e,0x32,0x20 +,0x25,0x53,0x99,0x9c,0xd1,0x30,0x21,0x3c,0xb5,0xa5,0xcc,0x26,0x25,0x2e,0xcd,0x95,0x93,0x3d,0x32,0xf0,0x27,0x1d,0x32,0xd0,0xc4,0xab,0xc2,0x3b,0x26,0xde,0x9f,0xcc +,0x40,0x2e,0xd9,0xa5,0xbc,0x48,0x2d,0x2d,0xe5,0x9e,0xab,0x2c,0x1b,0x19,0x4f,0x9d,0x95,0xc9,0x23,0x23,0x29,0xaf,0x96,0x9b,0x26,0x1e,0x2d,0xd9,0x9f,0xac,0x2c,0x20 +,0xb7,0xa0,0xa9,0x2b,0x1b,0x1d,0x42,0x9c,0x9f,0xb5,0x26,0x28,0xae,0xa2,0xb8,0x3d,0x38,0x2a,0x2f,0x3f,0x4b,0xb7,0xb2,0xaa,0xab,0x5b,0x1a,0x12,0xb6,0x8d,0x9e,0x25 +,0x1f,0x20,0x3d,0xa2,0x99,0xa0,0x36,0x27,0x28,0x3b,0xd7,0x3d,0x2f,0x5a,0x9e,0x99,0xa7,0x1e,0x14,0x2b,0xc3,0x9f,0xaa,0x37,0x18,0x37,0x9e,0x98,0x9a,0x37,0x1b,0x16 +,0x28,0x4a,0xc8,0x96,0x96,0xb8,0x3a,0x22,0x1a,0x39,0x9d,0x99,0x4a,0x11,0x13,0x3c,0x9a,0x8e,0x97,0x34,0x11,0x1b,0xb0,0xa0,0x30,0x22,0xba,0x9c,0x98,0x9f,0x40,0x0e +,0x0f,0xd5,0x8e,0x99,0x19,0x0d,0x18,0xa8,0x90,0x8a,0x96,0x17,0x0b,0x1b,0xba,0xbe,0x4a,0xbd,0xa8,0x98,0x96,0x3a,0x0f,0x13,0x38,0xa8,0xbc,0x33,0x43,0xae,0x9d,0x9c +,0xa5,0x35,0x15,0x1e,0xb8,0xae,0x22,0x17,0xae,0x8d,0x94,0xb8,0x1f,0x0c,0x0e,0xc9,0x88,0x98,0x0e,0x0f,0x66,0x91,0x8f,0x95,0xbc,0x0c,0x0d,0x48,0xa4,0xdb,0x2c,0xd5 +,0x9f,0x9c,0xa5,0x3e,0x16,0x13,0x4d,0x93,0x9d,0x1e,0x19,0x50,0xa3,0x99,0x9a,0xa9,0x1b,0x14,0x2b,0x4f,0x32,0x25,0x9b,0x86,0x98,0x1e,0x0e,0x0c,0x23,0x98,0x88,0xb4 +,0x0a,0x15,0xbf,0x98,0x98,0x9a,0x3f,0x0e,0x15,0xaa,0x91,0x40,0x10,0x2d,0x8f,0x90,0xb5,0x35,0x1f,0x1c,0x49,0x92,0xa3,0x0c,0x0a,0x3d,0x8f,0x8e,0xa1,0x9f,0x29,0x0f +,0x26,0xb7,0x75,0x17,0x4e,0x8e,0x9c,0x4b,0xbd,0x38,0x20,0xdf,0xa0,0x24,0x08,0x1b,0x99,0x8a,0x96,0xba,0x3a,0x1a,0x20,0xa0,0x9a,0x18,0x08,0x31,0x89,0x8e,0xbf,0x33 +,0x16,0x1d,0x58,0x98,0x9e,0x0e,0x09,0x3d,0x8c,0x8c,0x9d,0x9c,0x2c,0x0e,0x2a,0xb5,0x1f,0x0a,0x33,0x8a,0x8c,0xb6,0x64,0x48,0x23,0x1c,0x49,0xb8,0x17,0x10,0xc6,0x8b +,0x8f,0x9b,0x9e,0x2b,0x0f,0x39,0xb3,0x0e,0x07,0x33,0x86,0x88,0xa7,0x2a,0x14,0x27,0xc5,0x98,0x9c,0x0c,0x07,0xbc,0x89,0x95,0xa2,0x9f,0x1a,0x0d,0x25,0xa4,0xf3,0x0d +,0x19,0x8f,0x87,0x9b,0xd9,0x7c,0x25,0x0f,0x42,0x99,0x15,0x05,0x3c,0x89,0x88,0x8f,0x9d,0x30,0x0d,0x0d,0x2a,0x29,0x15,0x2d,0x8b,0x8a,0xa6,0xb0,0xba,0x37,0x10,0xb9 +,0xa0,0x09,0x04,0xb0,0x83,0x8f,0xaa,0xb5,0x31,0x1a,0x1f,0xe1,0x74,0x11,0x28,0x8b,0x8b,0x48,0x4e,0xac,0x19,0x0b,0x2d,0x99,0x33,0x0f,0x2c,0x8f,0x85,0x8d,0xc5,0x2a +,0x13,0x09,0x25,0xf3,0x0f,0x1d,0x88,0x86,0x9a,0xce,0x5f,0xda,0x16,0x18,0x2a,0x10,0x0b,0x59,0x87,0x86,0x9a,0xaa,0xa7,0x17,0x08,0x4c,0xbb,0x0c,0x17,0x91,0x8b,0xa0 +,0xb3,0xcd,0x1e,0x0f,0xf8,0xa3,0x26,0x13,0x4c,0x8a,0x88,0xa0,0xad,0xba,0x0b,0x04,0x22,0xda,0x1b,0x2a,0x9b,0x8d,0x8c,0x96,0xdf,0xd6,0x23,0x19,0x1e,0x16,0x07,0x1f +,0x85,0x84,0x9c,0xb9,0xa5,0x21,0x10,0x14,0x19,0x12,0x1d,0x9d,0x8d,0x8e,0x9f,0x9f,0xcd,0x0f,0x1a,0x9e,0x40,0x05,0x16,0x8c,0x88,0x9b,0xaf,0x45,0x0f,0x11,0xb7,0x3f +,0x17,0x24,0x98,0x86,0x8d,0x45,0x2b,0xb8,0x14,0x10,0x23,0x19,0x0f,0x3f,0x8c,0x8b,0x92,0x97,0xad,0x28,0x1f,0x14,0x1a,0x1b,0x0f,0x40,0x89,0x8d,0xbe,0xa5,0xb8,0x28 +,0xe1,0x39,0x0d,0x08,0x29,0x8c,0x85,0x93,0xc2,0xcc,0x25,0x0e,0x1b,0x56,0x1f,0x0f,0xa8,0x88,0x92,0xb6,0xc4,0x3b,0x17,0x2d,0xd2,0x18,0x11,0xbc,0x8c,0x8b,0xa1,0xbb +,0xa5,0xdb,0x12,0x07,0x12,0x18,0x2a,0x9e,0x90,0x97,0x9f,0x94,0xaf,0xe8,0xcd,0x16,0x11,0x18,0x16,0xa5,0x84,0x8e,0x49,0x3f,0x3f,0x28,0x1e,0x0f,0x0b,0x16,0x9f,0x8e +,0x94,0x9b,0x9b,0x99,0xac,0x20,0x0e,0x19,0x14,0x25,0x92,0x93,0xce,0xaf,0xa2,0x2e,0x13,0x13,0x3a,0x2c,0x2e,0xac,0x93,0x8f,0xa9,0xd1,0xb0,0x9e,0x2c,0x10,0x0f,0x16 +,0x2c,0xa0,0x8f,0xa2,0xaf,0xa5,0xb5,0x3d,0x1d,0x0d,0x12,0x3c,0xbc,0x9f,0x8e,0x9d,0xb4,0x9b,0xad,0x40,0x1e,0x12,0x0c,0x28,0x9b,0x99,0xb4,0xb2,0x9e,0xa6,0x3d,0x0d +,0x17,0x45,0x3c,0x2e,0xa9,0x9d,0x9d,0x95,0xac,0x4c,0x26,0x2b,0x2a,0x1e,0x28,0xae,0x92,0x98,0xba,0x27,0x2c,0x2d,0x10,0x0e,0x1d,0xb1,0x99,0x98,0x9e,0xa8,0x94,0x8c +,0x9a,0x2a,0x0b,0x0b,0x17,0x25,0x36,0x9c,0x8e,0x9d,0x39,0x13,0x31,0xd3,0x42,0x22,0x1c,0x2f,0x0e,0x0b,0x8d,0x81,0x8e,0x8f,0x8a,0x20,0x08,0x9c,0x9d,0x95,0x8f,0xa0 +,0x43,0x0f,0x06,0x00,0x00,0x18,0x9d,0x1f,0x0d,0x8d,0x80,0x81,0x89,0x99,0x8a,0x8d,0x2b,0x05,0x10,0x9e,0x19,0x00,0x03,0x2d,0x95,0x97,0x8c,0x2b,0x1a,0xd5,0xad,0x1c +,0x1c,0x8b,0x80,0x90,0x10,0x01,0x0c,0xb4,0x91,0x1d,0x0c,0x8b,0x82,0xb9,0x0f,0x32,0x8c,0x9e,0x15,0x01,0x09,0x9d,0xaa,0x09,0x0e,0x8a,0x80,0xa2,0xed,0xac,0x9b,0xb7 +,0x24,0x1e,0x14,0x97,0x85,0x91,0x1f,0x0e,0x0f,0x02,0x0a,0x14,0x19,0x99,0x8e,0x95,0xa9,0x9f,0x86,0x87,0x8e,0xa0,0x72,0x19,0x0c,0x06,0x05,0x5c,0x8d,0x32,0x0f,0x1b +,0xba,0xbf,0xcb,0xc3,0xda,0x98,0x8a,0x8a,0x98,0x9b,0xae,0x0d,0x06,0x06,0x08,0xc8,0x8d,0x8c,0xaa,0xaa,0x92,0x98,0x2c,0x0c,0x38,0xad,0x12,0x04,0x00,0x3c,0x80,0x85 +,0xae,0x97,0x82,0x97,0x0f,0x04,0x1f,0x8e,0x95,0x34,0x0f,0x14,0xb9,0x21,0x07,0x14,0xab,0xb5,0xa9,0xad,0xab,0x89,0x84,0x92,0x31,0x17,0x3d,0xb2,0x1d,0x0b,0x08,0x20 +,0x9f,0x99,0xda,0x95,0x8a,0xc8,0x1c,0x09,0x13,0xba,0xae,0xab,0x8f,0x8e,0xa0,0x2b,0x09,0x1a,0x9b,0x3b,0x1a,0xd5,0xab,0xa6,0x9e,0xbb,0x78,0x98,0x9e,0x44,0x18,0x0d +,0x14,0x17,0x17,0x68,0xce,0x9c,0x83,0x87,0xb2,0x15,0x19,0xb0,0x9a,0xb5,0xa9,0x96,0xa6,0x0d,0x01,0x01,0x48,0x91,0x22,0x1e,0xb4,0x8d,0x86,0x93,0xdc,0xa0,0x8e,0x91 +,0x22,0x02,0x08,0x21,0x2f,0xe4,0xa4,0x74,0x9c,0x94,0x2f,0x12,0x3e,0xa0,0xbc,0x3c,0x7a,0x91,0x87,0x94,0x1c,0x0e,0x24,0x42,0x15,0x1f,0x9a,0x94,0xac,0x1c,0x0f,0x1e +,0xaa,0x9d,0xa1,0x31,0x11,0x0d,0x06,0x0f,0x8f,0x85,0x8a,0x91,0xc4,0x27,0x26,0x5c,0xdf,0x9b,0x8d,0x91,0xa6,0x1c,0x14,0x13,0x19,0x23,0x0e,0x08,0x2f,0x96,0x9a,0xa7 +,0x96,0x8d,0x8d,0x9e,0x1e,0x1e,0x2e,0x2d,0x0c,0x07,0x21,0x9d,0x89,0x8c,0x9e,0xb2,0xb3,0x22,0x0d,0x15,0x58,0x8f,0x8a,0xbf,0x0f,0x13,0x25,0xf6,0x73,0x38,0xba,0x91 +,0x99,0x1c,0x1f,0xaf,0x9c,0xba,0x1d,0x18,0x17,0x1d,0x0e,0x0d,0xee,0x8e,0x86,0x8b,0x8f,0x95,0x9c,0xaf,0x1f,0x17,0x5d,0x9c,0xa0,0xd8,0x23,0x10,0x08,0x0a,0x13,0x39 +,0xad,0xa7,0x5d,0x20,0x48,0x9b,0x89,0x8b,0x93,0x97,0xb1,0x22,0x0f,0x12,0x1e,0xe4,0xf3,0x1e,0x2a,0x9b,0x91,0xa8,0x35,0x29,0x58,0xa0,0xa3,0x2e,0x44,0xbb,0x22,0x0d +,0x0c,0x1d,0xa0,0x8d,0x94,0xb9,0x34,0x3e,0xd8,0xcf,0xb2,0xa3,0x9b,0xcd,0x0b,0x03,0x0f,0xac,0x90,0x91,0x92,0x8e,0x92,0x6d,0x18,0x22,0xa6,0x94,0xb7,0x15,0x0e,0x13 +,0x27,0x1f,0x1a,0x3f,0xaf,0xbf,0xd0,0xb3,0xa1,0x9b,0x9c,0xb4,0xc5,0xa4,0xa0,0xae,0xc7,0x48,0x20,0x1a,0x18,0x17,0x4a,0x91,0x95,0x3e,0x15,0x11,0x20,0xb7,0xa2,0x9d +,0x98,0xa8,0x39,0x18,0x15,0x36,0x9f,0x99,0xa8,0xb2,0xad,0xbb,0x42,0x31,0xbc,0x9c,0xa4,0x2b,0x0e,0x0e,0x1b,0x1f,0x1e,0x26,0xc9,0x91,0x87,0x92,0xb5,0xb4,0x9f,0xa0 +,0xee,0x29,0x2c,0x31,0x19,0x09,0x08,0x18,0xbb,0xb3,0xbc,0xa5,0x98,0x8e,0x98,0x39,0x66,0x96,0x94,0xa8,0x2b,0x17,0x1e,0x1f,0x19,0x20,0x43,0xb6,0xac,0xb4,0xb2,0xaa +,0xaf,0x3f,0x1c,0x1e,0xb2,0x9a,0xa4,0xeb,0x26,0x25,0x43,0x49,0xc4,0x9b,0x90,0x9c,0x2e,0x10,0x11,0x37,0x9e,0x96,0x9e,0x37,0x17,0x0d,0x0c,0x1f,0xa9,0x9a,0x9c,0xac +,0xba,0x9f,0x99,0x9f,0xa3,0xa6,0xae,0xf2,0x1a,0x0c,0x11,0x29,0x3f,0x28,0x18,0x1c,0xac,0x91,0x93,0x9e,0xae,0xad,0xb1,0xbc,0xab,0x9f,0x9d,0x4e,0x0c,0x07,0x11,0x31 +,0xaa,0x9d,0x9e,0x9b,0x9e,0x2d,0x18,0x2b,0xa9,0x9b,0xbe,0x1b,0x17,0x24,0x47,0xc4,0xa8,0x94,0x8e,0x97,0xc5,0x23,0x22,0x3a,0x49,0x2c,0x23,0x2e,0x30,0x1f,0x1a,0x1f +,0x39,0xd2,0xbe,0xa7,0x95,0x8c,0x8e,0xa0,0x7b,0x39,0x72,0xb9,0x42,0x26,0x22,0x18,0x0f,0x10,0x1f,0x4e,0xa6,0x9d,0xb0,0xb5,0xac,0xae,0xa7,0x9f,0x9e,0x97,0x9b,0xc6 +,0x22,0x17,0x14,0x16,0x15,0x1b,0x66,0x9b,0x98,0xa9,0xbf,0xd3,0xb5,0xb0,0xfd,0x32,0x3d,0x59,0x2a,0x17,0x16,0x45,0x97,0x8e,0x96,0xa0,0xb9,0x40,0x2a,0x23,0x48,0xac +,0xb3,0x27,0x0f,0x0d,0x1a,0x2f,0x36,0xdb,0x9b,0x8f,0x92,0x9a,0x9e,0x9b,0x99,0xab,0x21,0x17,0x1c,0x1d,0x1b,0x18,0x17,0x25,0xce,0xb8,0xaa,0x9d,0x9e,0xac,0x4a,0x37 +,0xb4,0x9a,0x9b,0xa0,0xa0,0xbb,0x20,0x14,0x0f,0x12,0x2f,0xad,0xac,0x53,0x30,0x31,0xc8,0xaf,0xb6,0xad,0xae,0xda,0x2e,0x1f,0x28,0xb5,0x9d,0x9b,0x9e,0xa6,0xb2,0x60 +,0x2c,0x27,0x42,0xb7,0xf9,0x33,0x2a,0x24,0x26,0x1e,0x17,0x1d,0x51,0xa6,0x98,0x95,0x94,0x8c,0x8b,0x99,0x42,0x21,0x1e,0x22,0x18,0x0c,0x0b,0x12,0x1e,0x4f,0x9d,0x94 +,0x96,0xa3,0xcc,0x3f,0xc3,0xa6,0xa8,0xaa,0xad,0xb1,0x43,0x1c,0x13,0x19,0x31,0x66,0xe8,0x4e,0xd1,0xa3,0x9e,0xad,0xcc,0xe2,0x4f,0x3b,0x33,0x26,0x23,0x2d,0xcd,0xa1 +,0x95,0x94,0x9c,0xaf,0x37,0x32,0x35,0x26,0x1f,0x1f,0x2f,0xb7,0xaa,0x36,0x16,0x15,0x29,0xbd,0xa6,0xa2,0x9e,0x96,0x95,0x98,0x9a,0x9f,0xaf,0x3d,0x1a,0x0d,0x0e,0x12 +,0x13,0x1a,0x2d,0xb7,0x9b,0x9b,0xb2,0xbd,0xa4,0x9d,0xa5,0xb8,0xa9,0x9a,0x9b,0xd5,0x1d,0x17,0x16,0x1b,0x21,0x27,0x46,0xaf,0xa9,0xb0,0xb1,0xae,0xaa,0xc7,0x3c,0x2f +,0x28,0x20,0x1f,0x2c,0xae,0x8e,0x89,0x95,0xd2,0x2f,0x31,0x2d,0x25,0x28,0x2d,0x2a,0x27,0x27,0x30,0x5f,0x49,0x38,0x37,0x3e,0xb0,0x9e,0x98,0x94,0x91,0x99,0xa2,0xdb +,0x1d,0x1c,0x1f,0x19,0x0f,0x0d,0x17,0x54,0xa0,0x9e,0x9e,0x9f,0xa3,0xa8,0xde,0x4a,0xb5,0x9b,0x99,0xa7,0x51,0x22,0x18,0x16,0x1d,0x2a,0x49,0x46,0x2d,0x2d,0xb6,0x95 +,0x8f,0x9b,0x38,0x22,0x28,0x27,0x23,0x1f,0x27,0xbb,0x9b,0x96,0x95,0x9d,0xb8,0xc6,0x37,0x21,0x22,0x22,0x1f,0x25,0x2e,0x2f,0x38,0x23,0x1f,0x46,0xa4,0x9a,0x9e,0x9c +,0x96,0x8f,0x91,0x9d,0xce,0x29,0x1f,0x18,0x12,0x0c,0x0b,0x12,0x37,0xa4,0x99,0x9c,0xb1,0xb8,0xa8,0xa5,0xa1,0xab,0xcf,0xd2,0xa4,0x9a,0xa0,0x2d,0x12,0x17,0x23,0x34 +,0x27,0x1b,0x1c,0xfd,0x9f,0x9b,0x99,0xa3,0xb3,0x60,0x2e,0x20,0x1e,0x2c,0xdf,0xa5,0x9b,0x99,0xa0,0xc6,0x32,0x34,0xcf,0x48,0x20,0x1d,0x25,0x3c,0x6a,0x30,0x1b,0x24 +,0xc2,0xab,0xb7,0x60,0xcb,0x9a,0x8c,0x8c,0x96,0xb0,0x3f,0x2a,0x1e,0x15,0x0c,0x09,0x0c,0x1e,0xac,0x93,0x94,0xac,0xbc,0xa7,0x98,0x9b,0xc8,0x2e,0x4b,0xab,0xa7,0xae +,0x41,0x20,0x1e,0x2a,0x36,0x2a,0x25,0x2d,0x46,0xc7,0xac,0xa6,0xa7,0xae,0xc1,0x62,0x2d,0x18,0x18,0xbe,0x8f,0x8b,0x96,0xf4,0x24,0x3d,0xad,0xb3,0x22,0x11,0x12,0x25 +,0x47,0x44,0x3c,0x39,0xdc,0xb2,0xa8,0xba,0x47,0x4f,0xaa,0x95,0x8d,0x8d,0x9e,0x31,0x20,0x2c,0x29,0x14,0x08,0x08,0x17,0xda,0xa6,0xa7,0xa7,0xa0,0x98,0x95,0x9f,0x63 +,0x38,0xb6,0xa5,0xb0,0x5c,0x2c,0x21,0x25,0x36,0x49,0x28,0x18,0x1d,0xbb,0x9c,0x9f,0xbb,0x4a,0xb5,0x9b,0x9e,0x2a,0x0e,0x0f,0x39,0x9a,0x93,0x9f,0xbe,0xc0,0xac,0xa1 +,0xa2,0x52,0x15,0x0f,0x18,0x2f,0xcb,0x6d,0x2d,0x2f,0xb4,0x9c,0x9f,0x3d,0x27,0xb7,0x97,0x96,0x9f,0xae,0xb3,0xb1,0xda,0x26,0x10,0x0d,0x16,0x2f,0x35,0x23,0x2b,0xc0 +,0x99,0x8f,0x91,0xa3,0x39,0x2d,0xc0,0x9c,0xa6,0x3b,0x24,0x29,0x44,0xc1,0x46,0x19,0x12,0x28,0xb3,0xaa,0xca,0x37,0xdc,0x9d,0x94,0x9d,0x3b,0x15,0x12,0x26,0xb1,0xa1 +,0xaa,0xbd,0xb4,0xa6,0x9d,0xa7,0xc9,0x33,0x27,0x1f,0x1a,0x15,0x18,0x25,0x41,0xda,0x37,0x35,0xb5,0x92,0x8c,0x8d,0x9f,0x6e,0x2a,0xd7,0xb8,0xae,0xe7,0x36,0x22,0x1e +,0x28,0xa2,0xa9,0x35,0xd0,0x37,0x94,0x2d,0x13,0x0c,0x00,0x0b,0x30,0xce,0x94,0x82,0x80,0xd2,0x41,0x13,0x1e,0x89,0x84,0x80,0xa7,0x8b,0x80,0x3a,0x05,0xa8,0x97,0x18 +,0x03,0x01,0x00,0x04,0x0c,0x14,0x0c,0xb8,0x80,0x8b,0xb6,0x0f,0x0d,0x16,0x1c,0x04,0x0a,0x1e,0x99,0x85,0x83,0x94,0xa0,0x8f,0x87,0x80,0x8b,0x89,0x80,0x82,0x88,0x87 +,0x98,0x16,0x07,0x0a,0x07,0x00,0x00,0x00,0x00,0x00,0x03,0x0c,0xae,0x87,0x87,0x81,0x88,0x9f,0x94,0x9d,0xc0,0x91,0x9a,0x95,0x85,0x88,0x8a,0x8c,0xb6,0x8e,0x81,0x96 +,0xa5,0x3e,0x2e,0x5a,0xbc,0x41,0x8f,0x94,0xa4,0x9e,0x2c,0x09,0x00,0x01,0x00,0x00,0x02,0x08,0x0e,0x1b,0x43,0xa4,0xaf,0x99,0x95,0x8e,0x85,0x88,0x87,0x85,0x85,0x83 +,0x81,0x80,0x81,0x84,0x8a,0xa0,0x1f,0x09,0x01,0x06,0x07,0x0b,0x2c,0x70,0x55,0xbe,0xac,0x10,0x05,0x0a,0x04,0x04,0x05,0x01,0x01,0x02,0x0b,0x1a,0x1f,0xa3,0x96,0x8d +,0x84,0x81,0x85,0x86,0x82,0x81,0x80,0x80,0x81,0x82,0x86,0x89,0x9c,0x1e,0x1a,0x0c,0x0c,0x10,0x08,0x03,0x04,0x03,0x01,0x07,0x0f,0x1d,0x0d,0x07,0x09,0x0a,0x04,0x03 +,0x0e,0x3d,0x9e,0x8f,0x8c,0x8e,0x8d,0x8a,0x82,0x84,0x84,0x82,0x80,0x82,0x82,0x85,0x8a,0x8c,0x8a,0x91,0xa7,0x67,0x2e,0x35,0x0e,0x05,0x00,0x00,0x02,0x03,0x02,0x05 +,0x0b,0x06,0x01,0x01,0x05,0x15,0xa9,0xa6,0xeb,0x93,0x8a,0xb6,0x2b,0xaa,0x8a,0x81,0x82,0x85,0x87,0x86,0x86,0x8b,0x89,0x84,0x86,0x93,0x8d,0x88,0x7d,0x1f,0x24,0x2f +,0x3c,0x33,0x19,0x06,0x05,0x06,0x02,0x00,0x00,0x01,0x06,0x0a,0x0a,0x0d,0x1f,0x2b,0x47,0xa1,0xae,0x39,0xa1,0x8a,0x87,0x8a,0x89,0x86,0x86,0x88,0x86,0x82,0x80,0x82 +,0x89,0x8c,0x93,0xa9,0x40,0x2d,0x49,0xa9,0xa1,0x2d,0x0d,0x0d,0x0c,0x06,0x02,0x00,0x00,0x00,0x01,0x01,0x03,0x06,0x08,0x1b,0xb9,0x9d,0x92,0x93,0x90,0x8b,0x89,0x8b +,0x8c,0x89,0x89,0x88,0x8a,0x87,0x84,0x85,0x85,0x84,0x83,0x84,0x8b,0x9c,0xb9,0x4d,0x25,0x13,0x0e,0x08,0x04,0x01,0x02,0x03,0x02,0x02,0x04,0x05,0x04,0x02,0x05,0x0b +,0x15,0x53,0x9e,0x94,0x8d,0x88,0x8b,0x8c,0x8c,0x8d,0x8a,0x8a,0x8c,0x8a,0x87,0x87,0x85,0x84,0x87,0x87,0x89,0x88,0x8f,0xaa,0x2f,0x17,0x14,0x10,0x0b,0x07,0x07,0x0a +,0x09,0x04,0x01,0x01,0x03,0x03,0x03,0x04,0x09,0x1b,0x2c,0x38,0xa8,0x94,0x8d,0x8a,0x87,0x87,0x8a,0x8c,0x8e,0x95,0x92,0x90,0x98,0x95,0x8d,0x88,0x86,0x8c,0x8e,0x8b +,0x8e,0x9a,0xbe,0x32,0x1e,0x22,0x1e,0x16,0x11,0x09,0x0c,0x0b,0x0a,0x0a,0x06,0x06,0x07,0x08,0x09,0x0f,0x1d,0x1f,0x1d,0x26,0x3b,0x56,0xe9,0xae,0x96,0x8b,0x88,0x88 +,0x8b,0x8f,0x8c,0x89,0x90,0x93,0x89,0x86,0x86,0x88,0x8f,0xaf,0x2f,0x1e,0x16,0x25,0xbd,0xa1,0x2f,0x11,0x0f,0x16,0x18,0x13,0x12,0x12,0x18,0x0e,0x09,0x04,0x03,0x0a +,0x16,0x1a,0x21,0x22,0x2b,0x26,0x27,0x28,0xcc,0x98,0x94,0x95,0x90,0x8a,0x8b,0x89,0x85,0x85,0x83,0x83,0x86,0x8d,0x9a,0x9d,0xad,0xbc,0xcb,0x44,0x32,0x73,0x28,0x0f +,0x0e,0x16,0x2e,0x37,0x2f,0x26,0x24,0x1a,0x0e,0x07,0x04,0x05,0x05,0x03,0x07,0x09,0x0d,0x19,0x1a,0x1d,0x49,0xb6,0xab,0xa1,0x91,0x87,0x87,0x87,0x85,0x81,0x81,0x81 +,0x82,0x86,0x86,0x87,0x8b,0x98,0x5d,0x1f,0x16,0x15,0x14,0x0d,0x12,0x24,0x2f,0x26,0x1f,0x1a,0x13,0x0c,0x06,0x07,0x0b,0x0c,0x08,0x05,0x09,0x10,0x15,0x1b,0x2a,0x39 +,0x42,0x2a,0x2a,0xcd,0x9e,0x91,0x8c,0x8d,0x8c,0x87,0x86,0x88,0x8f,0x8f,0x85,0x83,0x85,0x88,0x87,0x85,0x88,0x95,0xc3,0x5b,0x2c,0x2d,0x22,0x11,0x0c,0x06,0x05,0x05 +,0x04,0x06,0x08,0x05,0x04,0x06,0x03,0x02,0x05,0x0b,0x15,0x23,0xc6,0xad,0xaa,0x9d,0x8e,0x8b,0x91,0x90,0x8f,0x8c,0x89,0x8c,0x8c,0x8b,0x88,0x85,0x87,0x8a,0x86,0x84 +,0x87,0x8c,0x93,0x96,0x91,0x99,0xaf,0x32,0x1e,0x0f,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x04,0x05,0x08,0x0a,0x09,0x0b,0x16,0x1a,0x1a,0x29,0x53,0xa5,0x9a,0x99,0x91 +,0x87,0x83,0x83,0x83,0x83,0x86,0x8c,0x97,0x9e,0x9b,0x8b,0x85,0x86,0x86,0x84,0x86,0x8c,0x8f,0x9a,0xa8,0xb9,0x39,0x12,0x0b,0x08,0x03,0x01,0x01,0x02,0x05,0x06,0x05 +,0x03,0x02,0x07,0x0b,0x09,0x0e,0x18,0x1e,0x29,0x22,0x24,0x52,0xa0,0x94,0x91,0x8c,0x89,0x88,0x88,0x8b,0x88,0x83,0x81,0x82,0x83,0x83,0x81,0x82,0x85,0x8c,0x93,0x98 +,0x9d,0xaa,0x2e,0x11,0x10,0x16,0x0a,0x07,0x09,0x0d,0x0a,0x03,0x02,0x01,0x00,0x00,0x00,0x01,0x03,0x07,0x08,0x0b,0x15,0xd2,0x92,0x92,0x93,0x8c,0x8b,0x91,0x8b,0x86 +,0x83,0x82,0x83,0x84,0x81,0x80,0x80,0x81,0x84,0x85,0x89,0x8d,0x8f,0x97,0x9f,0xae,0x23,0x0d,0x07,0x07,0x09,0x0b,0x08,0x06,0x05,0x03,0x02,0x01,0x01,0x02,0x02,0x00 +,0x01,0x02,0x06,0x0f,0x1e,0x2c,0xc2,0xa7,0x97,0x94,0x91,0x88,0x85,0x85,0x83,0x82,0x81,0x80,0x80,0x81,0x81,0x81,0x81,0x82,0x87,0x89,0x8c,0xa3,0x79,0x39,0x1f,0x1a +,0x16,0x0a,0x07,0x05,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x01,0x06,0x0f,0x1c,0x17,0x0f,0x0e,0x11,0x1f,0x2f,0x2b,0xdf,0xac,0x9c,0x97,0x8c,0x86,0x84,0x83,0x83,0x82 +,0x82,0x82,0x83,0x86,0x87,0x87,0x8d,0x92,0x8b,0x85,0x86,0x89,0x91,0xac,0x3b,0x22,0x12,0x06,0x03,0x02,0x02,0x02,0x02,0x04,0x09,0x0d,0x0a,0x06,0x05,0x05,0x04,0x05 +,0x05,0x06,0x07,0x0a,0x15,0x3d,0x94,0x85,0x83,0x86,0x8b,0x8b,0x8a,0x89,0x8a,0x8a,0x8a,0x8f,0x8a,0x83,0x81,0x80,0x80,0x80,0x81,0x85,0x8c,0x9c,0xa4,0xae,0xde,0x1c +,0x07,0x03,0x01,0x07,0x0b,0x07,0x03,0x01,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x0a,0x13,0x14,0x25,0x2f,0x3d,0xdc,0xac,0x9b,0x98,0x8d,0x87,0x87,0x8b,0x87,0x82,0x81 +,0x80,0x80,0x80,0x81,0x83,0x82,0x82,0x84,0x88,0x93,0xad,0x3d,0x27,0x1c,0x1c,0x1c,0x1d,0x10,0x07,0x04,0x03,0x04,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x0b,0x18 +,0x14,0x11,0x19,0x34,0xbb,0xa5,0x99,0x94,0x8f,0x8c,0x87,0x83,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x81,0x83,0x88,0x8e,0x8d,0x8a,0x8c,0x8a,0x8e,0x57,0x0c,0x04,0x02 +,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x05,0x0f,0x17,0x0e,0x09,0x0a,0x11,0x22,0x56,0x3a,0x2e,0x40,0xaa,0x8e,0x84,0x82,0x82,0x82,0x85,0x88,0x87,0x86,0x87,0x87 +,0x8a,0x8c,0x91,0x9c,0x97,0x8b,0x86,0x8a,0x93,0xa0,0xb0,0x59,0xc1,0xb7,0x1f,0x0f,0x09,0x05,0x04,0x05,0x0a,0x0a,0x07,0x06,0x05,0x0b,0x11,0x17,0x0e,0x0a,0x08,0x05 +,0x06,0x0b,0x1c,0x3b,0xbb,0xb0,0xaa,0x9b,0x8f,0x8b,0x92,0xa2,0xbd,0xbc,0xa1,0x8f,0x85,0x84,0x83,0x83,0x85,0x87,0x86,0x82,0x85,0x8b,0x94,0x9f,0xa8,0xb2,0xa9,0x97 +,0x92,0x97,0xc7,0x10,0x06,0x04,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x07,0x0c,0x0a,0x07,0x09,0x0f,0x25,0xd0,0x62,0xc9,0xa1,0x9c,0x8f,0x87,0x84,0x81,0x80,0x81 +,0x83,0x84,0x83,0x81,0x82,0x86,0x8c,0x97,0x99,0x90,0x8b,0x8a,0x92,0x9e,0x62,0x39,0x2f,0x2b,0x2f,0x0f,0x08,0x04,0x01,0x01,0x02,0x06,0x07,0x03,0x01,0x00,0x01,0x06 +,0x0c,0x0a,0x08,0x09,0x06,0x0a,0x1f,0xa1,0x8c,0x86,0x86,0x89,0x88,0x83,0x81,0x80,0x81,0x81,0x88,0x8f,0x8e,0x8b,0x86,0x81,0x81,0x83,0x89,0x8a,0x8b,0x8f,0xb5,0x1e +,0x0e,0x03,0x03,0x03,0x06,0x0c,0x09,0x05,0x05,0x04,0x03,0x05,0x04,0x01,0x00,0x02,0x01,0x05,0x0f,0x23,0xce,0xb7,0xb4,0xa5,0x8d,0x87,0x84,0x82,0x86,0x85,0x85,0x8a +,0x8a,0x83,0x81,0x83,0x87,0x91,0x95,0x8c,0x95,0xaf,0x63,0x77,0x20,0x26,0x5d,0x36,0xa0,0xa9,0x3c,0x12,0x03,0x0c,0x05,0x00,0x00,0x00,0x00,0x03,0x1c,0x91,0x86,0x80 +,0x9a,0xa3,0x2e,0x16,0x85,0x83,0x80,0x9a,0x8c,0x80,0x8b,0x1c,0xc5,0x90,0x0f,0x01,0x01,0x01,0x06,0x0f,0x1d,0x13,0x9d,0x80,0x8b,0xa5,0x04,0x05,0x0c,0x09,0x00,0x0a +,0x2d,0xa3,0x8a,0x87,0x98,0xb2,0x8a,0x87,0x80,0xa7,0x4e,0x82,0x80,0x86,0x86,0x86,0x3d,0x08,0x15,0x0f,0x03,0x00,0x00,0x00,0x00,0x05,0x06,0x1a,0x96,0x87,0x82,0x80 +,0x8c,0x8d,0x85,0x8c,0x8c,0x6b,0x0f,0x19,0xaf,0x89,0x8b,0x1f,0x37,0x89,0x8e,0x3e,0x1f,0x1b,0x16,0x48,0x31,0x96,0x9c,0x33,0x9d,0x9f,0x13,0x00,0x00,0x00,0x00,0x01 +,0x0b,0x2d,0xa3,0x8f,0x84,0x81,0x80,0x80,0x85,0x87,0x9d,0x9e,0x87,0x81,0x83,0x82,0x82,0x88,0x84,0x8a,0xa6,0x1b,0x03,0x02,0x00,0x01,0x00,0x0d,0xaa,0x3b,0x12,0x23 +,0x23,0x08,0x02,0x04,0x01,0x02,0x00,0x05,0x0d,0x31,0x91,0xac,0x9a,0x9f,0x98,0x80,0x81,0x81,0x82,0x80,0x82,0x81,0x80,0x80,0x82,0x83,0x84,0x8a,0x1c,0x03,0x01,0x08 +,0x1a,0x04,0x00,0x00,0x00,0x05,0x1b,0x18,0x0c,0x0e,0x0e,0x07,0x01,0x04,0x08,0x0f,0x09,0x17,0xa9,0x97,0x8c,0x88,0x89,0x83,0x83,0x83,0x81,0x81,0x80,0x80,0x80,0x80 +,0x81,0x83,0x85,0xb2,0x13,0x0d,0x07,0x01,0x00,0x03,0x03,0x01,0x02,0x03,0x00,0x01,0x01,0x14,0x20,0x03,0x06,0x0a,0x15,0xdf,0xa3,0x9e,0x12,0x12,0x98,0x88,0x8b,0x89 +,0x85,0x81,0x85,0x86,0x83,0x81,0x80,0x80,0x81,0x86,0x88,0x88,0x8b,0xa1,0x29,0x0c,0x09,0x0b,0x00,0x05,0x06,0x01,0x00,0x01,0x01,0x01,0x01,0x06,0x08,0x0c,0x21,0x3c +,0xba,0x3c,0xe1,0x8f,0x83,0x8a,0x99,0x9b,0x9e,0x8a,0x84,0x84,0x86,0x84,0x81,0x83,0x86,0x89,0x89,0x92,0x35,0x0e,0xfd,0x95,0xa9,0x2e,0x5b,0x1f,0x08,0x0a,0x08,0x00 +,0x00,0x06,0x04,0x00,0x04,0x26,0xde,0x1a,0x22,0x75,0x1a,0x1b,0xad,0x97,0xa6,0xb5,0x9c,0x8e,0x83,0x87,0x87,0x86,0x85,0x82,0x80,0x83,0x85,0x8f,0xa0,0x97,0x4f,0x0a +,0x05,0x07,0x09,0x0a,0x10,0x0d,0x05,0x0c,0x1a,0x0f,0x0a,0x0e,0x07,0x02,0x00,0x0b,0x37,0xaa,0x9f,0x8d,0x89,0xa1,0x9e,0x8c,0x98,0xa4,0x8b,0x84,0x84,0x8c,0x84,0x80 +,0x80,0x89,0x97,0x9c,0xcc,0xa0,0xa9,0x23,0x08,0x04,0x13,0x14,0x04,0x02,0x0a,0x07,0x00,0x02,0x0d,0x09,0x04,0x0e,0x10,0x0c,0x18,0xdc,0xc3,0x4f,0xa6,0x8a,0x86,0x89 +,0x8b,0x87,0x8c,0x94,0x8c,0x86,0x8a,0x95,0x8c,0x82,0x83,0x8b,0x8a,0x87,0x8d,0x22,0x18,0x1b,0x04,0x07,0x18,0x0f,0x04,0x07,0x24,0x1f,0x05,0x03,0x05,0x06,0x09,0x15 +,0x28,0x0f,0x0d,0x2e,0x9d,0xaf,0x1a,0x34,0xbc,0x2e,0xad,0x8c,0x82,0x83,0x89,0x85,0x90,0x9a,0x86,0x82,0xa8,0x38,0xa6,0x8d,0x8a,0xaf,0x9a,0xa1,0x3a,0x20,0x2f,0x2a +,0x0d,0x22,0x3d,0x34,0x17,0x11,0x24,0x13,0x09,0x07,0x0a,0x0f,0x0a,0x0b,0x23,0x0b,0x07,0x2e,0xa6,0x40,0x1e,0x29,0x2e,0x1d,0xbb,0x87,0x89,0x96,0x8d,0x84,0x85,0x81 +,0x80,0x81,0x90,0x9a,0x8b,0x85,0x88,0x91,0xa1,0x1a,0x0f,0x19,0xb7,0x16,0x00,0x07,0x0e,0x14,0x0d,0x18,0x1b,0x06,0x01,0x09,0x0f,0x06,0x0b,0x1c,0x19,0x08,0x09,0xc7 +,0x97,0xad,0x43,0x41,0x42,0x9e,0x87,0x85,0x85,0x86,0x86,0x81,0x83,0x85,0x84,0x89,0x9d,0x8e,0x82,0x80,0x8b,0xb2,0x6c,0x1b,0x0b,0x12,0x1d,0x06,0x00,0x02,0x0f,0x14 +,0x05,0x0d,0x0f,0x04,0x03,0x15,0x1e,0x07,0x06,0x16,0x21,0x0f,0x37,0x91,0xaa,0x41,0xbb,0x93,0x8f,0x8b,0x81,0x88,0x9d,0x9f,0x88,0x80,0x8e,0x90,0x83,0x82,0x86,0x86 +,0x81,0x84,0x9b,0xc7,0xcd,0x0f,0x07,0x0c,0x0e,0x04,0x00,0x03,0x0e,0x0e,0x03,0x05,0x01,0x01,0x07,0x1e,0x11,0x02,0x06,0x1b,0xa7,0xcc,0xa8,0x9d,0x55,0xad,0x89,0x81 +,0x89,0x8a,0x84,0x85,0x86,0x85,0x81,0x81,0x9a,0xb9,0x8d,0x8c,0x9a,0x96,0x8b,0x9f,0x3b,0xae,0xac,0x2c,0x11,0x14,0x0d,0x02,0x02,0x0e,0x19,0x06,0x01,0x05,0x03,0x05 +,0x17,0x25,0x09,0x00,0x07,0x56,0x98,0xad,0x9b,0x9d,0xac,0x8f,0x86,0x82,0x90,0x9a,0x88,0x85,0x8c,0x89,0x81,0x87,0xa8,0xc3,0x93,0x94,0x9b,0xa6,0xc3,0x1c,0x1e,0x98 +,0x92,0xe5,0x13,0x1d,0x3f,0x17,0x1b,0xac,0x3e,0x0a,0x03,0x09,0x06,0x04,0x0a,0x0c,0x05,0x02,0x14,0xd0,0x43,0x16,0x18,0x17,0x12,0x39,0x92,0x8d,0xc1,0xa6,0x8c,0x84 +,0x86,0x84,0x84,0x8c,0x90,0x89,0x82,0x8d,0x99,0xa0,0xa4,0x3a,0xc5,0x8d,0x91,0x36,0x15,0x5e,0x96,0x9e,0xe7,0x2f,0x1d,0x1d,0x17,0x17,0x0c,0x03,0x02,0x03,0x05,0x02 +,0x04,0x0f,0x11,0x05,0x07,0x08,0x11,0xc4,0x9e,0xdd,0x29,0xa6,0x94,0x8b,0x8c,0x8c,0x88,0x88,0x89,0x83,0x80,0x81,0x83,0x89,0x84,0x88,0x89,0x85,0x95,0x30,0x29,0xa3 +,0x96,0xb3,0x0f,0x09,0x0b,0x0b,0x0e,0x09,0x01,0x00,0x01,0x02,0x05,0x07,0x08,0x05,0x02,0x05,0x0c,0x09,0x0e,0x5e,0xe0,0x2a,0x3a,0x94,0x82,0x80,0x83,0x8f,0x92,0x84 +,0x80,0x81,0x82,0x83,0x82,0x81,0x80,0x80,0x81,0x84,0x95,0xc3,0x1e,0x16,0x1f,0x0b,0x00,0x00,0x00,0x03,0x08,0x09,0x02,0x00,0x02,0x08,0x09,0x07,0x04,0x05,0x0a,0x0f +,0xf3,0xb9,0x33,0x55,0xa6,0x9d,0x9c,0x8e,0x88,0x8f,0xbb,0xba,0x91,0x85,0x81,0x81,0x83,0x8d,0x88,0x80,0x80,0x85,0x8e,0x92,0x9a,0x8d,0x96,0xb2,0xbe,0x25,0x12,0x0a +,0x0c,0x0b,0x0c,0x04,0x00,0x00,0x05,0x1d,0x27,0x13,0x07,0x04,0x07,0x0d,0x11,0x08,0x0a,0x0f,0x0e,0x24,0x4c,0xf6,0xb2,0x9f,0x91,0x94,0x8c,0x86,0x84,0x87,0x8f,0x8e +,0x84,0x80,0x80,0x86,0x8a,0x83,0x87,0x84,0x83,0x8b,0x92,0x9b,0x9e,0xa2,0x33,0x1a,0x0f,0x08,0x04,0x04,0x05,0x03,0x02,0x00,0x00,0x00,0x00,0x08,0x0a,0x02,0x03,0x0d +,0x36,0xbf,0x21,0x17,0x27,0xcd,0x95,0x91,0x9d,0x8a,0x85,0x86,0x84,0x82,0x81,0x80,0x80,0x82,0x84,0x80,0x80,0x80,0x83,0x8a,0x89,0x8e,0x97,0xb6,0x16,0x06,0x04,0x03 +,0x01,0x02,0x07,0x09,0x03,0x03,0x00,0x04,0x0c,0x0a,0x03,0x00,0x00,0x01,0x06,0x0a,0x07,0x08,0x19,0x9f,0x8b,0x8b,0x92,0x8e,0x86,0x83,0x81,0x81,0x80,0x80,0x80,0x82 +,0x82,0x80,0x81,0x80,0x88,0x98,0x8d,0x8c,0x9a,0xab,0x21,0x11,0x0e,0x0f,0x10,0x09,0x04,0x01,0x00,0x01,0x02,0x02,0x02,0x03,0x03,0x02,0x04,0x06,0x0f,0x13,0x08,0x13 +,0xcd,0x99,0x96,0x9e,0xb0,0x94,0x85,0x82,0x81,0x83,0x82,0x85,0x85,0x8a,0x8a,0x84,0x86,0x8b,0x99,0x93,0x86,0x84,0x88,0x95,0xb6,0xb7,0x9a,0x9f,0xc9,0x18,0x09,0x0b +,0x0d,0x0f,0x08,0x06,0x04,0x02,0x03,0x03,0x03,0x01,0x04,0x0a,0x05,0x06,0x18,0x38,0xe2,0x22,0x10,0x15,0x43,0x9f,0x92,0x9b,0x98,0x87,0x83,0x82,0x84,0x84,0x85,0x8b +,0x8d,0x86,0x84,0x86,0x88,0x89,0x8a,0x87,0x83,0x86,0x88,0x9f,0xbc,0x43,0x3d,0x2c,0x08,0x04,0x08,0x09,0x09,0x07,0x03,0x01,0x01,0x03,0x02,0x01,0x04,0x06,0x02,0x01 +,0x02,0x17,0xa0,0x9a,0x9e,0xc7,0xd5,0x92,0x83,0x88,0x88,0x87,0x87,0x84,0x82,0x83,0x87,0x8c,0x95,0x89,0x84,0x87,0x8e,0x9a,0x93,0x94,0x95,0x93,0xb0,0x36,0xbc,0xa6 +,0x3a,0x13,0x0c,0x04,0x05,0x09,0x0e,0x11,0x08,0x08,0x07,0x05,0x02,0x01,0x01,0x05,0x0e,0x0e,0x0a,0x07,0x10,0xdb,0x9b,0x9c,0x9e,0x9b,0x8c,0x83,0x85,0x8a,0x91,0x8f +,0x8a,0x84,0x83,0x85,0x88,0x88,0x84,0x87,0x86,0x87,0x93,0xb6,0xd3,0xa9,0xa8,0xb0,0x54,0x2a,0x1e,0x13,0x17,0x0d,0x01,0x03,0x07,0x0a,0x07,0x03,0x05,0x0c,0x18,0x10 +,0x0e,0x0b,0x0c,0x16,0x1e,0x3c,0x3b,0x40,0x96,0x89,0x8b,0x94,0xa2,0xa5,0xac,0x8e,0x8d,0x9d,0xaa,0xa3,0x89,0x86,0x81,0x84,0x80,0x8e,0xa1,0x95,0x65,0x13,0x02,0x0a +,0x1a,0x0c,0x00,0x01,0x04,0x18,0xa1,0x80,0xad,0x18,0x8b,0x80,0x85,0x16,0x00,0x0e,0x22,0x8f,0x96,0x05,0x0b,0x0e,0x0d,0x99,0x92,0x28,0x0e,0x00,0x35,0x81,0x85,0x24 +,0x08,0x13,0x49,0xa5,0x2e,0x13,0x0f,0x8e,0x90,0x95,0x82,0x80,0x87,0x82,0xa7,0x08,0x0a,0x0c,0x0b,0x16,0x1d,0xfc,0xbb,0x0c,0x96,0x87,0x80,0x8f,0x17,0x27,0x2b,0xb8 +,0x85,0x8b,0x0c,0x0f,0x8f,0x82,0x2d,0x24,0x34,0xb6,0x9e,0xe9,0x0e,0x03,0x03,0x0a,0x29,0x03,0x01,0x01,0x04,0x06,0x2a,0xbc,0x2f,0xac,0x86,0x80,0x82,0x80,0x83,0x8c +,0x8d,0x87,0x90,0xa1,0x0f,0x19,0x2f,0x15,0x16,0x19,0x13,0xc4,0xaa,0x96,0x9f,0x3d,0x8d,0xc3,0xbe,0xae,0x1c,0x0d,0x18,0xba,0xb5,0x3e,0xaf,0xc3,0x99,0x8c,0x8f,0x99 +,0x1e,0x12,0x0e,0x18,0x0a,0x00,0x06,0x11,0x0b,0x27,0x29,0x29,0xc9,0xad,0x9a,0x91,0x9a,0x59,0xb0,0x1c,0x1f,0x39,0xc9,0xc3,0xbc,0x8d,0x88,0x9d,0x93,0x87,0x83,0x99 +,0x8f,0x8d,0xae,0x9f,0xaf,0xac,0x2b,0x27,0x15,0x14,0x31,0x31,0x36,0xb9,0xd9,0xcd,0x96,0x9d,0xa6,0x1c,0x0f,0x0f,0x03,0x03,0x00,0x01,0x02,0x08,0x0e,0x0e,0x08,0x16 +,0x35,0x0f,0x0f,0x30,0x98,0x9e,0x8f,0x81,0x82,0x83,0x81,0x80,0x81,0x80,0x84,0x86,0x83,0x81,0x85,0x85,0x89,0x98,0x9d,0xdd,0x0a,0x07,0x06,0x00,0x02,0x12,0x2f,0x06 +,0x01,0x01,0x06,0x09,0x06,0x05,0x04,0x07,0x17,0x20,0x1c,0x33,0x1e,0x2b,0x26,0x0f,0x1b,0xa6,0x90,0x8b,0x92,0x9f,0x8b,0x89,0x93,0x8e,0x8f,0x88,0x86,0x85,0x83,0x86 +,0x83,0x81,0x80,0x86,0x84,0x8e,0x1c,0x39,0xc0,0x69,0xea,0x26,0x1d,0x0c,0x08,0x06,0x0d,0x08,0x00,0x01,0x02,0x05,0x02,0x04,0x07,0x07,0x06,0x11,0x0f,0x0c,0x16,0x1c +,0xc9,0x9f,0x95,0x8f,0x8d,0x90,0x91,0x8c,0x8f,0x9b,0xa7,0x96,0x8e,0x8c,0x8e,0x88,0x84,0x94,0x98,0x8b,0x88,0x84,0x8b,0x88,0x87,0x8e,0x8a,0x8c,0x3c,0x2f,0x91,0x2f +,0x0d,0x0a,0x18,0x1f,0x1c,0x0e,0x08,0x09,0x07,0x0b,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x0c,0x0c,0x12,0xb9,0x9f,0x8f,0x8b,0x91,0x92,0x8a,0x85,0x82,0x80,0x84 +,0x85,0x82,0x80,0x80,0x80,0x80,0x81,0x87,0x87,0x88,0x88,0x88,0x9e,0x39,0x5a,0x6a,0x2e,0x1c,0x07,0x02,0x02,0x02,0x01,0x03,0x06,0x05,0x04,0x04,0x06,0x03,0x05,0x04 +,0x05,0x02,0x02,0x00,0x06,0x18,0x30,0xec,0xa8,0xbc,0xad,0x88,0x83,0x84,0x85,0x80,0x80,0x80,0x81,0x80,0x81,0x81,0x89,0x9b,0x99,0x90,0x96,0x93,0x87,0xb5,0x15,0x1b +,0x25,0x1f,0x18,0x15,0x1a,0x29,0x16,0x0c,0x0b,0x0d,0x0b,0x08,0x03,0x00,0x07,0x17,0x1e,0x18,0x1e,0x13,0x0f,0x17,0x1b,0x27,0x2e,0xc1,0xf5,0x3a,0xb7,0x9c,0x8f,0x8b +,0x9c,0x2c,0xe9,0xa2,0x90,0x87,0x84,0x8a,0x8a,0x8b,0x88,0x8b,0x9e,0x24,0x1f,0xc7,0xc6,0x9d,0xa0,0xa5,0xa0,0x8d,0x8c,0xa4,0x36,0xce,0x42,0x2a,0x3e,0x29,0x2c,0x11 +,0x0c,0x0e,0x18,0x0e,0x05,0x05,0x09,0x0c,0x13,0x21,0xcc,0xa4,0xb2,0x24,0x0e,0x1b,0x29,0x48,0xa9,0x9b,0x47,0x1a,0x9a,0x89,0x87,0x98,0x37,0x32,0x57,0xa5,0x95,0x94 +,0xa7,0xa8,0xcc,0xc8,0xc0,0xbe,0x56,0x25,0x4b,0xaf,0xbd,0x2e,0xaf,0x9d,0xa0,0x8f,0x88,0x9b,0x4b,0xb4,0xa0,0xa7,0xa4,0xc8,0x29,0x17,0x22,0xdb,0x56,0xdb,0x12,0x1d +,0x6e,0x4e,0x3e,0xcd,0xa7,0xac,0xbf,0x1c,0x10,0x0f,0x15,0x22,0x11,0x06,0x04,0x11,0x36,0x1f,0x15,0x0b,0x07,0x0c,0x37,0xb7,0x66,0x1f,0xcf,0xa2,0xa5,0x88,0x86,0x8a +,0xa2,0x9e,0x88,0x87,0x88,0x90,0x94,0x88,0x83,0x81,0x86,0x90,0xa7,0x9c,0x9b,0xbf,0x3c,0x2c,0x6a,0xe2,0xa3,0x91,0x93,0x3d,0x15,0x1f,0x33,0x12,0x05,0x06,0x05,0x04 +,0x02,0x02,0x05,0x0b,0x0e,0x09,0x05,0x04,0x03,0x05,0x13,0x32,0x17,0x10,0x0e,0x33,0x92,0x8b,0x8d,0xaa,0x74,0xbd,0x8d,0x81,0x81,0x80,0x83,0x83,0x82,0x82,0x82,0x82 +,0x81,0x83,0x83,0x86,0x91,0xb4,0xf9,0x9b,0x9f,0x30,0x1c,0x11,0x0f,0x18,0x27,0x1e,0x07,0x03,0x02,0x03,0x03,0x07,0x0e,0x0e,0x0b,0x05,0x01,0x02,0x01,0x08,0x0e,0x02 +,0x00,0x00,0x05,0x11,0x57,0xbc,0xb9,0xaa,0x95,0x81,0x80,0x80,0x85,0x8f,0x8d,0x82,0x80,0x80,0x82,0x8b,0x87,0x80,0x82,0x85,0x86,0x86,0x84,0x85,0x83,0x87,0xab,0x19 +,0x27,0xba,0x18,0x04,0x02,0x03,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x0a,0x1c,0x15,0x09,0x0d,0x1e,0x39,0xa1,0x9a,0xb8,0x3a,0xa6,0x88,0x83,0x81,0x88 +,0x9c,0x26,0x9d,0x81,0x80,0x86,0x9e,0x95,0x87,0x83,0x80,0x89,0xa5,0x9c,0x8b,0x8b,0xae,0x1b,0x16,0xbf,0x94,0xaa,0x6a,0xf5,0x2a,0x1e,0x2c,0xc3,0x27,0x15,0x37,0xb9 +,0x3f,0x0f,0x0d,0x06,0x01,0x05,0x0a,0x07,0x02,0x0a,0x25,0x3f,0x0e,0x07,0x14,0x1f,0xa1,0x87,0x93,0x16,0x04,0x20,0x8f,0x8f,0x9e,0x1d,0x09,0x0c,0x30,0x98,0x97,0xbc +,0x36,0x90,0x84,0x86,0x8a,0x8d,0x9b,0x92,0x85,0x8d,0x31,0x3e,0x8a,0x83,0x8a,0x97,0x8b,0x8b,0x94,0x9b,0x8f,0x8f,0x2d,0x3b,0x88,0x88,0xdb,0x11,0x0c,0x0a,0x0f,0x13 +,0x08,0x03,0x01,0x0c,0x24,0x0c,0x01,0x00,0x02,0x06,0x0b,0x24,0x0b,0x00,0x01,0x05,0x17,0x2a,0x4c,0x1c,0x13,0xaf,0x88,0x83,0x88,0x89,0x82,0x80,0x80,0x82,0x85,0x88 +,0x86,0x85,0x84,0x8b,0x9e,0x85,0x80,0x81,0x83,0x98,0xa1,0xab,0x3d,0x13,0x14,0x0f,0x04,0x0a,0x1d,0x0f,0x01,0x02,0x04,0x02,0x02,0x0b,0x0b,0x06,0x12,0x97,0x87,0x98 +,0x0d,0x00,0x05,0x0a,0x11,0x15,0x08,0x00,0x14,0x90,0x84,0x87,0x90,0x28,0x1f,0x97,0x8a,0x97,0x35,0xb9,0x8b,0x82,0x81,0x8c,0x8c,0x8c,0xa3,0xb1,0xaf,0xb7,0x42,0x42 +,0x5b,0xa1,0x92,0xad,0xdf,0x22,0x1d,0xaa,0x93,0xc6,0xaf,0x86,0x80,0x97,0x0e,0x21,0x9e,0xb2,0xc1,0x5f,0x0f,0x07,0x15,0x96,0x9a,0x0e,0x04,0x02,0x04,0x0b,0x34,0x1d +,0x06,0x06,0x0f,0xa8,0xc6,0x17,0x0b,0x01,0x03,0x2e,0x96,0x3f,0x1e,0xb5,0x8e,0x85,0x87,0x91,0x98,0x9f,0xca,0xb4,0x8d,0x8f,0x9a,0x8c,0x85,0x8c,0xbf,0x24,0x19,0x17 +,0xa4,0x8c,0x8b,0x97,0x95,0x83,0x80,0x8b,0x1b,0x26,0x3f,0x21,0x37,0x1d,0x0c,0x15,0xac,0x87,0x94,0x0f,0x0c,0x04,0x06,0x0e,0x14,0x13,0x09,0x05,0x29,0x8a,0x9a,0x25 +,0x0d,0x02,0x06,0x14,0x18,0x09,0x0d,0x41,0xaa,0xae,0x1b,0x07,0x05,0x08,0x0f,0x18,0x31,0x37,0xa5,0x83,0x81,0x84,0x87,0x88,0x8f,0x97,0x8e,0x94,0x9a,0x91,0x85,0x80 +,0x80,0x88,0x9e,0xae,0x97,0x8d,0x88,0x86,0x97,0x9c,0x86,0x80,0x92,0x20,0x08,0x00,0x01,0x01,0x02,0x02,0x02,0x02,0x05,0x0d,0x09,0x02,0x02,0x00,0x08,0x1a,0x11,0x03 +,0x08,0xa3,0x9c,0x23,0x1e,0x1a,0x36,0xa3,0xc1,0x6b,0x94,0x8a,0x83,0x80,0x80,0x83,0x88,0x8f,0x96,0x8a,0x85,0x89,0x96,0x8e,0x83,0x81,0x84,0xa7,0x0f,0x0e,0x14,0x17 +,0x1c,0x1b,0x22,0xbf,0x94,0x98,0x4f,0x1e,0x0d,0x0c,0x18,0x1d,0x1e,0x11,0x12,0x3e,0xd3,0x3e,0x11,0x02,0x03,0x07,0x07,0x0b,0x0e,0x14,0xb7,0x8c,0x94,0x4b,0x28,0x1a +,0x2c,0x9c,0xa8,0x1f,0x34,0x9d,0x8d,0x86,0x91,0x4c,0x25,0x26,0x14,0x14,0x47,0x3a,0x3a,0x96,0x86,0x81,0x84,0x7e,0x0d,0x2b,0xa5,0xc9,0x2a,0x17,0x46,0x89,0x83,0x86 +,0x92,0x93,0x94,0xb4,0x4e,0x21,0xd1,0x96,0x8d,0x8b,0x8d,0x9b,0x28,0x1c,0x17,0x1f,0x1c,0x0f,0x08,0x0f,0xb4,0xae,0x23,0x0e,0x0d,0x0a,0x07,0x05,0x01,0x05,0x11,0x37 +,0x40,0x29,0x1d,0x0f,0x10,0x22,0x2f,0x1c,0x1e,0x23,0xb9,0x8e,0x87,0x88,0x8a,0xa0,0x9d,0x8b,0x99,0x98,0x8f,0x8c,0x89,0x81,0x87,0x9e,0x1b,0x21,0x21,0x1a,0x16,0x17 +,0x2e,0x96,0x8d,0x9a,0x8c,0x96,0xb5,0x1c,0x1d,0x2c,0x1b,0xbd,0xd2,0x2d,0x2c,0x1e,0x9a,0x99,0x92,0xab,0xd9,0x9d,0x8a,0x88,0x8e,0x80,0x94,0x0b,0x08,0x00,0x0d,0x25 +,0x02,0x07,0x07,0x0d,0x07,0x0c,0x01,0x2d,0x97,0xa8,0x88,0x52,0x5e,0xac,0x8e,0x80,0x8a,0x0b,0x0c,0x8c,0x9c,0x9f,0x1c,0xb5,0x9b,0xab,0x90,0x90,0x80,0x90,0x8b,0x8e +,0x8c,0x96,0x0c,0x00,0x1c,0x85,0x8b,0x37,0x0f,0x0d,0x0a,0x00,0x05,0x19,0x0e,0x02,0x04,0x07,0x14,0x93,0x0e,0x17,0x85,0x80,0x98,0xad,0x94,0x23,0x00,0x0b,0x26,0xad +,0x1e,0x1a,0x9c,0x0a,0x09,0x18,0xb6,0x86,0x80,0x80,0x81,0x80,0x84,0x8b,0x89,0x9a,0xa8,0x1d,0x6c,0xaf,0x0c,0x0e,0x00,0xd0,0x81,0x85,0x9e,0x45,0x2f,0x0c,0x21,0x1e +,0x3e,0x0f,0x05,0x0e,0x13,0x1e,0x03,0x01,0x00,0x06,0x1e,0x11,0x0d,0x2c,0x88,0x9c,0x9b,0x85,0x83,0x80,0x83,0x82,0x87,0x80,0x89,0xaf,0x60,0x8e,0x84,0xe7,0x0f,0x0c +,0x0e,0x22,0xc6,0x2b,0x0b,0x17,0xac,0xb5,0x4b,0x1f,0x4e,0xb9,0x3e,0x25,0x90,0x82,0x8c,0x94,0x23,0x15,0x42,0xc5,0x07,0x00,0x14,0xab,0x1a,0x0b,0x36,0x8a,0x82,0xa9 +,0x5b,0x93,0xab,0x06,0x0c,0x09,0x08,0x12,0x02,0x00,0x01,0x05,0x03,0x02,0xd6,0x97,0x8f,0x89,0x8f,0x87,0x8d,0x83,0x80,0x83,0x89,0x8c,0x88,0x88,0x86,0x97,0x9b,0x85 +,0x84,0x94,0x39,0x28,0xad,0xe4,0xdd,0x9a,0x86,0x89,0xa8,0x99,0x90,0x18,0x04,0x06,0x01,0x02,0x01,0x02,0x02,0x0a,0x07,0x04,0x0e,0x12,0x1a,0x0e,0x1d,0xae,0x96,0x18 +,0x02,0x9e,0x80,0x8c,0xba,0x1f,0x29,0x25,0x07,0x13,0x9c,0x87,0x90,0x27,0x2f,0x90,0x93,0x1b,0xba,0x83,0x81,0x8f,0x96,0x8c,0x8b,0x8a,0x95,0x9a,0x40,0x23,0x1d,0x14 +,0x1d,0x20,0xa7,0x8c,0x8a,0x8c,0x99,0xcf,0x9d,0x8f,0x1e,0x10,0x8f,0x99,0x16,0x0b,0x08,0x08,0x04,0x00,0x04,0x02,0x08,0x16,0xa6,0x89,0x8e,0x9c,0xb2,0xaa,0x40,0x2f +,0x36,0xbe,0x69,0x67,0x18,0x07,0xb6,0xad,0x16,0x0b,0x0c,0x1a,0x21,0x0a,0x12,0xa9,0x86,0x8d,0x2c,0xa0,0x8f,0xfd,0x10,0x25,0xad,0x9d,0x95,0xa2,0xa2,0x8a,0x8a,0x8d +,0x8c,0x8e,0x8b,0x8b,0x94,0x8b,0x81,0x83,0x84,0x84,0x8c,0xa5,0x9b,0x6e,0x1c,0x17,0x10,0x0d,0x09,0x04,0x02,0x0e,0x0f,0x07,0x04,0x07,0x09,0x09,0x03,0x07,0x1b,0x17 +,0x06,0x03,0x01,0x08,0x15,0x16,0x0c,0x0c,0x1a,0x27,0xa4,0x97,0x8d,0x83,0x81,0x88,0x88,0x8e,0x94,0x84,0x81,0x80,0x82,0x82,0x83,0x8a,0x8b,0xa2,0xa0,0x82,0x8c,0xa9 +,0x9d,0xbf,0x3a,0x43,0xaf,0xb0,0xc2,0x47,0x0d,0x13,0x0e,0x0a,0x0c,0x07,0x03,0x09,0x11,0x19,0x12,0x08,0x03,0x08,0x0e,0x10,0x0e,0x0f,0x1d,0x0a,0x06,0x0a,0x0e,0x20 +,0x2a,0x2a,0xb0,0xac,0x69,0x2f,0x22,0xcd,0x90,0x87,0x8c,0x8c,0x86,0x88,0x8c,0x87,0x82,0x80,0x81,0x84,0x84,0x84,0x84,0x8b,0xb8,0x2f,0xcb,0x3b,0x0e,0x0b,0x0f,0x07 +,0x07,0x0e,0x06,0x0a,0x17,0x11,0x0c,0x08,0x05,0x0d,0x9e,0x8e,0xad,0x2e,0x1f,0x32,0xf5,0xd0,0x3a,0xa5,0x96,0xa6,0x9b,0x9b,0xaf,0xa6,0x9e,0x90,0x88,0x92,0xa5,0x41 +,0xc0,0xaf,0x9d,0x9a,0x4c,0x1e,0x13,0x0d,0x0a,0x08,0x07,0x09,0x0f,0x1d,0x1f,0x0f,0x0f,0x1d,0x1e,0x0e,0x0d,0xad,0x92,0x8c,0x86,0x84,0x8b,0x93,0x97,0x8b,0x87,0x96 +,0x5b,0x1a,0x2d,0xcb,0xaf,0x9c,0xa0,0x99,0x94,0xa3,0x95,0x92,0x92,0x93,0x9f,0xbb,0x90,0x8d,0xce,0x1c,0x17,0x14,0x15,0x1a,0x12,0x0f,0x19,0xca,0x54,0x1b,0x07,0x08 +,0x15,0x14,0x0f,0x0b,0x11,0x18,0x10,0x12,0x20,0x3d,0xb2,0x3c,0x16,0x11,0x23,0x2a,0x3f,0xaf,0xa0,0x95,0x99,0x9f,0x9b,0x94,0x98,0x90,0x94,0x8e,0x86,0x88,0x87,0x84 +,0x88,0x97,0xa5,0xb0,0x3f,0x2d,0x19,0x0f,0x14,0x0f,0x1c,0x2d,0x1b,0x1c,0x24,0xd8,0x9b,0xab,0x3d,0xab,0x93,0x94,0x93,0x9c,0x38,0x35,0x26,0x16,0x26,0xb0,0xa8,0xbf +,0xb3,0xbd,0x3d,0xb4,0xde,0x17,0x0f,0x11,0x0f,0x0e,0x0a,0x0f,0x27,0xb3,0xd8,0x15,0x0e,0x16,0xad,0xb8,0x10,0x0d,0x19,0x42,0x2f,0x17,0x16,0x27,0xd1,0x69,0xc1,0xa0 +,0xa2,0x96,0x8d,0x8b,0x87,0x88,0x91,0x98,0x9e,0xab,0x9b,0xad,0xab,0xad,0xb4,0x9f,0x9f,0x9b,0x9f,0x9c,0x9f,0xaa,0xa4,0x95,0x8c,0x90,0x8d,0x89,0x8d,0x96,0xa2,0xcf +,0x1c,0x14,0x16,0x14,0x19,0x1d,0x1b,0x0f,0x07,0x0a,0x19,0x18,0x0f,0x08,0x01,0x02,0x06,0x13,0x1f,0x27,0x2f,0x39,0x2f,0x23,0x23,0x1f,0x27,0xb4,0xa9,0x30,0x1b,0x21 +,0x2e,0x23,0x3a,0xc2,0xa9,0x96,0x9a,0x8e,0x85,0x82,0x82,0x84,0x8c,0x95,0x9b,0x9f,0x98,0x9b,0x96,0x94,0x97,0x9d,0xad,0xa4,0x99,0x9f,0xa5,0xb8,0xcd,0xad,0x9f,0x9d +,0xa0,0x9d,0x55,0x27,0x26,0x3d,0x6f,0x26,0x0c,0x06,0x0c,0x19,0x16,0x0f,0x0b,0x06,0x06,0x08,0x0c,0x12,0x13,0x0e,0x17,0x3f,0x5c,0x3c,0x25,0x1c,0x31,0xc8,0xb2,0x3f +,0xbe,0xba,0x9a,0x93,0x9e,0xc5,0x34,0x2c,0x21,0x3c,0xb2,0x97,0x8d,0x88,0x89,0x89,0x88,0x8c,0xa0,0xee,0x2b,0xcc,0x3c,0x2e,0x2d,0x1f,0x62,0xad,0x94,0x89,0x89,0x8a +,0x96,0xa2,0x9b,0x98,0x90,0x9b,0xb2,0xad,0xb5,0x24,0x1f,0x17,0x15,0x20,0x30,0x32,0x2e,0x16,0x0a,0x04,0x06,0x0b,0x06,0x00,0x03,0x08,0x0a,0x10,0x28,0xa3,0x2b,0x3c +,0xbf,0x38,0xb5,0xb2,0x9e,0x8e,0x8e,0x95,0x9b,0x8f,0x8e,0x97,0xac,0x2d,0x2d,0xbb,0xae,0xb6,0x9a,0x9c,0xa8,0x9b,0x9a,0x9c,0x9a,0xae,0xbb,0xcc,0x1d,0x0c,0x13,0x2e +,0xac,0x9d,0xb7,0x33,0x3a,0xa9,0x97,0x95,0x94,0x9a,0x97,0x8e,0x8e,0x9d,0x2a,0x19,0x1e,0x3e,0x59,0x92,0x8f,0xba,0xc9,0x3a,0xab,0xdb,0x12,0x0c,0x07,0x0a,0x06,0x02 +,0x07,0x11,0x1b,0x24,0x1f,0x39,0xc1,0x1a,0x14,0x25,0xa2,0xe0,0x5a,0xa4,0x9e,0xa6,0xa9,0xb0,0x3b,0x36,0xdc,0xc4,0xb3,0x99,0x8b,0x87,0x92,0x95,0x9e,0x2e,0x13,0x15 +,0x20,0x2d,0xc1,0xb9,0xaa,0x99,0x92,0x89,0x8a,0x92,0x93,0x9d,0x7d,0xab,0x95,0x91,0x92,0x96,0xb6,0x11,0x0c,0x08,0x05,0x04,0x08,0x18,0x2c,0x21,0x3a,0x4a,0xab,0x92 +,0x9c,0x4a,0x14,0x20,0x37,0x61,0xca,0xa5,0xb3,0x49,0x33,0x2e,0x4c,0x32,0x1f,0x11,0x0d,0x10,0x3c,0x93,0x8e,0x99,0x9b,0xba,0xab,0x9f,0xb8,0xa5,0x9c,0x96,0x9a,0xa9 +,0xd2,0x24,0x1b,0x1b,0x0e,0x0a,0x0a,0x0d,0x0f,0x2d,0xa9,0x95,0x98,0xb1,0x9d,0x99,0x95,0xa6,0xbe,0xdd,0xf0,0xac,0xca,0x3f,0x9f,0x97,0xbb,0x31,0x17,0x1e,0xe2,0xa1 +,0xa4,0x98,0x94,0x9e,0xb3,0x71,0xc6,0xcb,0x1f,0x10,0x15,0x2e,0x9b,0x90,0x96,0x9b,0x9a,0xa2,0x9c,0x97,0x91,0x9e,0xab,0xc7,0x3c,0x23,0x1a,0x1c,0x0f,0x12,0x0b,0x05 +,0x06,0x0b,0x17,0x30,0xb4,0x56,0x2b,0x1d,0x1a,0x23,0x1a,0x10,0x0d,0x11,0x23,0x43,0x4a,0x34,0xb8,0x99,0x8f,0x99,0xb4,0xa0,0x93,0x89,0x87,0x8b,0x92,0x92,0x93,0x91 +,0x8d,0x9b,0xb2,0x31,0x1e,0x21,0x38,0xca,0xe6,0x2d,0x1f,0x31,0x46,0x2b,0x25,0x2d,0xa2,0x97,0x9a,0x93,0x97,0x9f,0xae,0xd9,0x32,0x2f,0x42,0x3c,0x6f,0xb7,0xb4,0x64 +,0x23,0x22,0x37,0x49,0x3b,0x16,0x0f,0x1c,0x2f,0x2f,0x1f,0x16,0x13,0x1c,0x17,0x0a,0x05,0x03,0x05,0x08,0x0c,0x14,0x26,0xac,0x9c,0x92,0x8b,0x8a,0x8d,0x8c,0x8a,0x87 +,0x88,0x89,0x8d,0x96,0x95,0x93,0x97,0xa3,0xc1,0x2f,0xac,0x97,0x99,0x9b,0xa1,0xa1,0xb5,0x21,0x13,0x11,0x1b,0x4f,0x3e,0x24,0x2e,0x39,0xc3,0xa7,0xb4,0x4b,0x20,0x1f +,0x30,0x46,0x2e,0x1f,0x1e,0x1b,0x27,0xc0,0x1f,0x0d,0x0f,0x10,0x1a,0x26,0x2b,0x21,0x30,0xb0,0x9a,0x99,0xa7,0xb2,0xca,0xba,0xab,0xac,0xa8,0xa1,0xa5,0xad,0xac,0xa6 +,0xe6,0x1f,0x22,0x21,0x1a,0x1d,0x1f,0x3d,0x41,0x35,0x66,0xca,0xa9,0xa1,0xa1,0x9c,0x90,0x8b,0x8b,0x9b,0x40,0x21,0x36,0xaf,0xac,0xc1,0x19,0x10,0x1e,0x29,0xb9,0x93 +,0x91,0xa3,0xb3,0xb9,0xa3,0xbb,0x1a,0x13,0x16,0x29,0x3e,0xd0,0x3c,0x40,0xc6,0xb8,0xbb,0xc0,0xac,0xb7,0xa8,0x6e,0x40,0x2c,0x1d,0x24,0x2f,0xa7,0x9e,0x99,0x9f,0x7d +,0x1e,0x1a,0x22,0x2e,0xd5,0x54,0xc4,0xa8,0xab,0xa3,0x9e,0xa3,0xac,0x55,0x37,0x28,0x1e,0x1c,0x10,0x0f,0x13,0x18,0x1e,0x1c,0x2d,0xd7,0x65,0x57,0xd1,0x2f,0x24,0x3b +,0xba,0x98,0x8c,0x94,0x9e,0xa2,0xac,0x9b,0x8f,0x93,0x9c,0xa4,0xed,0x26,0x1f,0x1c,0x12,0x1a,0x46,0xae,0xa1,0xa7,0xaf,0x78,0xc6,0x9e,0x93,0x8f,0x92,0x9a,0xc3,0x51 +,0x30,0x30,0x45,0xae,0x9a,0x94,0x96,0xa9,0x2d,0x11,0x0c,0x0c,0x16,0x1e,0x1b,0x1c,0x2e,0x2c,0x1a,0x19,0x27,0x46,0xaf,0xaf,0x2f,0x28,0x1b,0x13,0x19,0x2d,0xb9,0xa8 +,0xa6,0x3f,0x2b,0x25,0x1d,0x1d,0x20,0x2d,0x26,0x45,0xab,0xa1,0x9b,0x9d,0xa3,0x98,0x8d,0x8a,0x8f,0x9b,0xa1,0xe3,0x27,0x23,0x3c,0xbb,0x4d,0x3d,0x74,0xaf,0x9d,0x97 +,0xa3,0x9c,0x90,0x8e,0x93,0xa5,0x9c,0x99,0xbc,0x37,0x54,0x4c,0xf5,0xc8,0xcb,0x49,0x2d,0x20,0x14,0x0b,0x06,0x08,0x0e,0x0d,0x0e,0x10,0x1a,0x17,0x18,0x22,0x2a,0x2a +,0x18,0x13,0x19,0x20,0x35,0x3a,0x49,0xcf,0x9e,0x8c,0x8a,0x87,0x8b,0x8b,0x8a,0x8c,0x96,0x9d,0x9b,0x9b,0xab,0x5d,0x33,0x3d,0xaf,0x9c,0x9a,0x9d,0x9c,0xa9,0x30,0x11 +,0x1a,0x2b,0xef,0xbe,0x2c,0x21,0x12,0x0d,0x0d,0x11,0x16,0x17,0x17,0x11,0x0f,0x0f,0x0c,0x15,0x24,0x51,0xaf,0x9f,0x95,0x8f,0x8e,0x8e,0x8f,0x8e,0x92,0x91,0x8f,0x8e +,0x8e,0x9f,0xa5,0xa8,0xab,0xab,0x9e,0xa9,0x3e,0x20,0x17,0x20,0x2c,0x4a,0xc5,0xbe,0x54,0xcd,0xc0,0x2d,0x2f,0x48,0xc5,0x4b,0x1f,0x0c,0x0d,0x12,0x13,0x11,0x0c,0x15 +,0x1d,0x21,0x2f,0xab,0x9f,0xea,0x2c,0x32,0x3b,0x34,0x25,0x37,0xd5,0xbd,0xba,0xac,0xa8,0xab,0xac,0xcb,0xeb,0x35,0x3a,0x3e,0x50,0xa4,0xa4,0xa8,0x9e,0x9d,0x93,0x8e +,0x8e,0x8f,0x91,0x95,0xa0,0xac,0xa5,0xa3,0xb7,0x45,0x45,0xb9,0xaf,0xbd,0x72,0xe5,0x5f,0x38,0x1a,0x12,0x1d,0x22,0xe1,0xac,0xcc,0x63,0xbe,0xc9,0x3e,0x4e,0x4a,0xb6 +,0xc0,0x1d,0x17,0x1a,0x14,0x15,0x15,0x15,0x18,0x28,0x27,0x1b,0x16,0x14,0x17,0x14,0x17,0x1a,0x2d,0x3d,0x35,0x3f,0xda,0xb4,0xb5,0xb9,0x99,0x95,0x96,0x9a,0xb2,0xa3 +,0x99,0x8f,0x93,0x92,0x8e,0x8f,0x8c,0x93,0xa6,0xbd,0xeb,0xea,0x49,0x3c,0x3b,0x35,0x37,0x2c,0x2a,0x55,0xba,0xa8,0x9c,0x8f,0x8f,0x9b,0x9e,0xb6,0xc9,0x53,0xc6,0x59 +,0x26,0x23,0x1d,0x1c,0x1e,0x15,0x0e,0x0c,0x0c,0x10,0x0f,0x16,0x1b,0x1f,0x26,0x25,0x2e,0x56,0xe3,0x44,0xe8,0xc6,0x50,0x2e,0x20,0x63,0xb2,0x9f,0xa1,0x9d,0x92,0x98 +,0x97,0xa4,0xa1,0x97,0x94,0x9c,0xac,0x38,0x1e,0x1d,0x15,0x13,0x26,0x68,0xd4,0xef,0x62,0xca,0xdb,0xd3,0xb3,0xb0,0xb0,0xad,0xb4,0xc2,0xb5,0xa1,0xa6,0xb2,0xa3,0x9b +,0x9f,0xb1,0x49,0x4b,0xbc,0xa2,0x99,0x9e,0xa7,0xb3,0xb0,0xa8,0xbc,0xee,0x52,0x56,0x4a,0x1a,0x0e,0x0d,0x11,0x15,0x28,0x37,0x32,0x29,0x2a,0x2a,0x27,0x3d,0x3e,0xb0 +,0xd0,0xbd,0x99,0x9d,0xbe,0x3b,0xda,0xaa,0xb6,0x5c,0x2d,0x29,0x2d,0x2f,0x20,0x1f,0x20,0x3b,0x69,0xd7,0xb6,0xc2,0xbc,0xc9,0xef,0x68,0xa6,0xb3,0x35,0x27,0x28,0x29 +,0x58,0x7d,0xbc,0xa9,0xad,0xa5,0xaa,0xa5,0xbd,0xf2,0xc2,0xc5,0xcf,0x40,0x38,0x2f,0x5d,0xda,0xb6,0xa2,0xa0,0x9f,0xaf,0xa9,0xab,0xa7,0xa9,0x9e,0x8e,0x8e,0x90,0x8f +,0x91,0x93,0x9c,0xab,0x72,0x32,0x30,0x1f,0x10,0x0c,0x10,0x16,0x14,0x0f,0x15,0x22,0x29,0x1f,0x22,0x28,0x2e,0x3e,0x3f,0x23,0x1a,0x17,0x16,0x15,0x15,0x1d,0x34,0x3d +,0x1f,0x17,0x1e,0x3b,0xd7,0xcf,0xa9,0x8f,0x8d,0x8d,0x92,0x91,0x92,0x91,0x93,0x94,0x95,0xa8,0x65,0x1e,0x1d,0x26,0x3d,0xbb,0xad,0xb9,0xa4,0x9e,0xa2,0xad,0xe3,0xd7 +,0xce,0x2d,0x1b,0x1a,0x2f,0xbe,0xd2,0x5f,0xb8,0xa3,0xa5,0xad,0xaa,0x9f,0xa5,0xb1,0xce,0x55,0x36,0x33,0x3a,0x4e,0x46,0x34,0x54,0x57,0x2e,0x1d,0x18,0x19,0x18,0x12 +,0x1b,0x2b,0x4b,0x4d,0x3f,0xc0,0x9d,0x95,0x96,0x9f,0x5d,0x4f,0x3a,0x1e,0x17,0x1b,0x21,0x21,0x24,0x39,0xbc,0xb0,0xcf,0x6a,0xc7,0xae,0xb3,0xd7,0x35,0x28,0xcc,0xb2 +,0xaf,0xa2,0x9a,0x94,0x90,0xa1,0xb5,0xbb,0xbf,0xc7,0xfc,0xef,0x37,0x3e,0x4e,0xb6,0x9e,0x97,0xa4,0xa6,0xa7,0xb7,0xcd,0x60,0x28,0x12,0x16,0x17,0x18,0x1a,0x24,0x3a +,0xe3,0xb7,0xbc,0xc8,0x55,0xe4,0x77,0x29,0x2b,0x3c,0x2b,0x2e,0x41,0xb9,0x99,0x9b,0xa6,0xb5,0xc0,0xb8,0xbd,0xec,0x2b,0x2e,0x4c,0x3b,0x3b,0xb7,0x9d,0x9f,0xaf,0xcc +,0xe3,0x53,0x27,0x1d,0x16,0x11,0x0e,0x11,0x1b,0x2d,0xcb,0xaf,0xae,0xbb,0x6c,0x44,0xe0,0x4c,0x3f,0xbe,0xab,0xb4,0xac,0xaf,0xa3,0x9f,0x9e,0x9c,0xad,0xcb,0x51,0x4c +,0xbb,0xac,0xc8,0xdb,0x56,0xc3,0xa3,0x92,0x89,0x88,0x8e,0x92,0xa9,0xb6,0xb9,0x26,0x18,0x19,0x1c,0x11,0x0d,0x0e,0x2c,0x46,0x3d,0x2b,0x2b,0x29,0x15,0x0f,0x0e,0x1a +,0x30,0x4f,0xba,0x99,0x8e,0x92,0x9b,0xaf,0xa6,0x98,0x9c,0x9f,0x34,0x1e,0x1f,0x1d,0x2a,0xc7,0xa7,0xae,0xac,0xab,0xc0,0x3d,0x3d,0x2c,0x16,0x11,0x12,0x0f,0x14,0x1e +,0x36,0xb5,0xbd,0xb8,0xb4,0xb8,0xb8,0x42,0x1f,0x16,0x16,0x21,0x5e,0xb9,0xa6,0x9b,0x96,0x98,0x98,0xa4,0xb7,0xb1,0xb9,0xc0,0x6a,0x4b,0xb9,0x9b,0x8f,0x8a,0x88,0x89 +,0x8b,0x90,0x9b,0x98,0x9f,0x3d,0x15,0x10,0x15,0x28,0x3a,0x30,0x34,0x2d,0x26,0x1c,0x19,0x19,0x1e,0x1d,0x11,0x0d,0x0c,0x0c,0x10,0x1d,0xc4,0x9c,0x9f,0xcf,0x2b,0x21 +,0x2d,0x40,0x3f,0x29,0x1f,0x25,0x33,0xc4,0x9d,0x92,0x91,0x8d,0x92,0x99,0x9b,0xaf,0x53,0x2d,0x21,0x1e,0x1c,0x1f,0x2d,0xb4,0x9e,0x9c,0x9e,0xb4,0x4c,0x36,0x2e,0x28 +,0x20,0x23,0x2a,0x32,0x41,0xb6,0xa8,0x98,0x92,0x98,0x9a,0x97,0x93,0xa0,0xcc,0x59,0xae,0x99,0x8f,0x8d,0x8f,0x96,0x9d,0xd3,0x3b,0x3d,0x2e,0x20,0x0e,0x08,0x06,0x0b +,0x10,0x17,0x2a,0xc2,0x9f,0xa2,0x3c,0x22,0x2b,0x3a,0x4c,0x2a,0x1d,0x1c,0x1f,0x32,0x4c,0xba,0xbe,0xd6,0x68,0x38,0x5c,0x4d,0x1d,0x0f,0x0d,0x13,0x29,0xd7,0xaf,0xa5 +,0x9a,0x94,0x8f,0x98,0x9f,0xa9,0xa9,0xbf,0x38,0x2f,0x2d,0x49,0xcb,0xac,0x9e,0x97,0x9e,0xaa,0xac,0xa7,0xaf,0x49,0x25,0x19,0x1f,0x3b,0xbb,0xb1,0xa4,0x98,0x99,0x9f +,0xa8,0x9b,0x93,0x99,0xb3,0xd4,0xcc,0x5b,0x36,0x38,0xb5,0x9e,0x9b,0xa7,0x2f,0x1e,0x25,0x2f,0x29,0x18,0x17,0x14,0x0d,0x11,0x25,0xb9,0x9d,0x9c,0xa3,0xbd,0x3d,0x25 +,0x13,0x0f,0x0e,0x12,0x14,0x15,0x1b,0x1e,0x35,0xac,0x98,0x94,0x93,0xa6,0x37,0x26,0x1d,0x1c,0x1c,0x29,0x43,0xe9,0xaf,0x9e,0x9f,0xb7,0xcf,0xaf,0xa6,0xad,0xd3,0x27 +,0x13,0x1a,0xd2,0x9f,0x97,0x98,0x92,0x96,0x94,0x8b,0x8b,0x90,0x98,0xa4,0xc6,0x40,0x35,0xe1,0xc4,0xb1,0x9d,0x9e,0xbe,0x41,0x23,0x1f,0x1f,0x1b,0x11,0x0b,0x0f,0x19 +,0x1f,0x2e,0xac,0x9c,0x9e,0xa3,0xa7,0xba,0x2d,0x24,0x1e,0x14,0x12,0x16,0x1f,0x2c,0x6a,0xb2,0xa9,0xaa,0xa0,0x9e,0xae,0xd5,0x2e,0x15,0x12,0x1b,0x2b,0x48,0x48,0xcc +,0xc7,0xd6,0xd4,0xb4,0xae,0xcc,0x25,0x14,0x0e,0x0e,0x17,0x1f,0xc6,0x9e,0x97,0x9b,0x9e,0x98,0x97,0x95,0x98,0xa7,0xda,0x30,0x31,0x58,0xb7,0xa5,0x97,0x91,0x92,0x92 +,0x9a,0xa0,0xa6,0xaf,0xbc,0x2f,0x1c,0x19,0x19,0x24,0x2a,0x38,0x2d,0x2e,0x4b,0xc0,0xb7,0x2e,0x1c,0x1d,0x57,0xad,0xa7,0x3b,0x28,0xba,0x94,0x8e,0x8e,0x9e,0x35,0xcb +,0x9f,0x95,0x97,0x9d,0xa7,0x98,0xce,0xbe,0x5a,0x0e,0xa1,0x80,0x9f,0x00,0x8e,0x80,0x21,0x8e,0x2a,0x17,0x07,0x06,0x07,0x0c,0x14,0x00,0x04,0x00,0x00,0x00,0x00,0x02 +,0x00,0x00,0x02,0x02,0x08,0x07,0x05,0x06,0x14,0x1b,0x3c,0x98,0x9d,0x99,0x97,0x92,0x8d,0x80,0x80,0x8a,0x82,0x80,0x80,0x80,0x82,0x80,0x80,0x81,0x80,0x80,0x80,0x80 +,0x80,0x80,0x81,0x85,0x84,0x84,0x87,0x8a,0x9f,0xb7,0x9f,0x9d,0x46,0x1b,0x16,0x24,0x13,0x0a,0x0f,0x05,0x04,0x04,0x04,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x04,0x03,0x07,0x03,0x07,0x0d,0x16,0x18,0x25,0x39,0x9d,0x90,0x8c,0x87,0x8a,0x84,0x84,0x84,0x82,0x80,0x83 +,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x82,0x84,0x80,0x82,0x81,0x84,0x83,0x83,0x87 +,0x82,0x8d,0x93,0xa1,0x5a,0xaf,0x26,0x16,0x0b,0x03,0x07,0x0c,0x04,0x03,0x01,0x03,0x06,0x02,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x01 +,0x00,0x02,0x00,0x04,0x00,0x05,0x03,0x01,0x01,0x03,0x07,0x04,0x06,0x02,0x0a,0x02,0x0e,0x08,0x10,0x1b,0x05,0x0d,0x0f,0x0f,0x25,0x26,0x2c,0xd2,0xbc,0x99,0x9e,0x91 +,0x93,0x8e,0x8b,0x91,0x8c,0x85,0x8b,0x88,0x81,0x82,0x81,0x88,0x86,0x83,0x80,0x83,0x85,0x8c,0x86,0x80,0x82,0x81,0x83,0x82,0x83,0x80,0x82,0x80,0x83,0x81,0x83,0x82 +,0x81,0x86,0x83,0x84,0x81,0x84,0x88,0x8c,0x8c,0x86,0x83,0x85,0x8a,0x89,0x8a,0x8a,0x85,0x8e,0x8e,0x8e,0x8f,0x90,0x8e,0x9c,0x99,0x9d,0x95,0x95,0x9b,0x94,0x99,0x8e +,0x93,0x87,0x90,0x9a,0xa3,0x9c,0x99,0xa9,0xbb,0xb6,0xc6,0x5d,0x55,0x20,0x23,0x13,0x0b,0x0d,0x0b,0x08,0x09,0x08,0x07,0x07,0x06,0x03,0x05,0x01,0x06,0x05,0x01,0x02 +,0x00,0x01,0x00,0x03,0x00,0x02,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x03,0x01,0x02,0x00,0x01,0x02,0x02,0x06,0x00,0x06,0x02,0x01,0x00,0x02,0x00 +,0x03,0x05,0x04,0x09,0x03,0x0f,0x09,0x0c,0x09,0x11,0x1d,0x1c,0x4f,0x28,0xa2,0xa0,0x96,0x89,0x89,0x83,0x88,0x89,0x83,0x80,0x81,0x80,0x81,0x80,0x80,0x81,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x80,0x84,0x83,0x80,0x80,0x83,0x83,0x81,0x83,0x80,0x82,0x80,0x88,0x87,0x84,0x85 +,0x93,0x8b,0x92,0x9c,0x8d,0x9d,0xa3,0x37,0x1e,0x21,0x1c,0x1f,0x0b,0x0a,0x0a,0x05,0x07,0x06,0x0c,0x00,0x03,0x02,0x04,0x01,0x01,0x02,0x00,0x01,0x00,0x03,0x02,0x05 +,0x01,0x05,0x03,0x02,0x02,0x00,0x02,0x03,0x02,0x00,0x06,0x06,0x01,0x0a,0x01,0x09,0x08,0x05,0x05,0x0a,0x0f,0x0b,0x15,0x0f,0x18,0x11,0x1e,0x16,0x0f,0x19,0x1a,0x20 +,0x21,0x29,0x2b,0xb0,0xa9,0xa8,0x51,0xac,0xa9,0xab,0x8f,0xa8,0x90,0x96,0x8b,0x88,0x8e,0x8b,0x8c,0x8b,0x8d,0x8f,0x8a,0x86,0x91,0x88,0x84,0x8b,0x84,0x8f,0x92,0x89 +,0x95,0x88,0x8f,0x8e,0x8e,0x91,0x8f,0x90,0x9f,0xa9,0xc6,0xca,0x9e,0xbe,0xa7,0xad,0xba,0xa2,0xa8,0xac,0xc1,0x37,0x55,0xae,0xb5,0xbb,0x37,0x19,0x50,0x24,0x43,0x1b +,0x19,0x1c,0x13,0x17,0x17,0x2a,0x0f,0x1d,0x25,0x34,0x2d,0x16,0x2f,0x19,0x3e,0xbd,0x3f,0x47,0x24,0xc7,0xbd,0xb1,0xcd,0xc7,0x5e,0x98,0xa1,0x98,0x99,0xa1,0x8f,0x96 +,0x8e,0x96,0x94,0x9e,0x98,0x93,0x8e,0x8e,0x8f,0x8c,0x97,0x88,0x92,0x8e,0x90,0x9d,0x8f,0xa7,0x8c,0x9b,0xa3,0x9c,0xa4,0x9b,0xba,0xfc,0x1f,0x36,0x27,0xa5,0xdd,0x2d +,0x2e,0x19,0x43,0x1a,0x2d,0x19,0x22,0x25,0xba,0xd7,0x1e,0x31,0x13,0xd7,0x2e,0x59,0x2c,0x18,0x28,0x35,0xf9,0xcd,0xb7,0x20,0x3f,0x2f,0x6e,0xc9,0x24,0xc8,0x25,0xb7 +,0xab,0x4d,0x3b,0x3a,0x46,0x49,0x50,0x17,0x33,0x19,0xb3,0x4c,0x23,0x2c,0x19,0xa9,0xca,0xa2,0x3b,0x40,0x24,0xd9,0xa3,0xbf,0xa4,0x2e,0xc5,0xb4,0xa8,0xc9,0x3b,0x1f +,0x48,0xa8,0xd9,0xac,0x1f,0xc3,0x5d,0xc9,0xc9,0x1b,0x29,0x1d,0xa3,0xae,0xa6,0x20,0x26,0xbf,0x3f,0xb4,0x1e,0xcc,0x28,0xde,0xa9,0xbf,0x48,0x32,0xac,0xaf,0x93,0x5b +,0xc9,0x32,0xc5,0x98,0xae,0x97,0x4b,0x43,0x4c,0xa8,0xc1,0x5f,0x1f,0xe5,0xad,0xcd,0x9b,0x23,0x2e,0x2a,0xb8,0xad,0x2b,0x20,0x13,0x2f,0x2b,0xb0,0x3d,0x20,0x3d,0x29 +,0xc2,0x2e,0x33,0x1c,0x56,0xb6,0x97,0x92,0xb0,0xb9,0xce,0x9b,0x9c,0xa1,0xeb,0x75,0xcb,0x92,0x9d,0xb3,0xd4,0x23,0x9f,0xa7,0xa2,0x44,0x1d,0x2f,0xb5,0xa2,0x41,0x3c +,0x1b,0x3a,0xcc,0xbc,0x2f,0x17,0x2b,0x25,0xab,0xba,0x35,0x1d,0x1a,0x3a,0xbe,0x6b,0x1d,0x1d,0x20,0xb2,0xa3,0xb3,0x24,0x2e,0x5a,0xbf,0x9c,0x2d,0x3d,0x37,0xbd,0x93 +,0x9d,0xad,0xdc,0x4a,0xa9,0x9b,0xb2,0x48,0x2a,0xed,0x9e,0xa0,0x9e,0x4b,0x1f,0xc9,0x4e,0xb7,0x41,0x1a,0x2f,0x3e,0xaf,0xb4,0x16,0x1a,0x1f,0x34,0xa7,0x28,0x33,0x26 +,0x30,0x9a,0xa6,0xb5,0xaf,0xc7,0xac,0x96,0x9e,0xb9,0xe2,0x4a,0x9b,0x9e,0xa5,0xb0,0x37,0x47,0xad,0xa0,0x39,0x27,0x1f,0x29,0xb2,0xaf,0x48,0x19,0x13,0x2a,0xda,0x26 +,0x1e,0x17,0x22,0xd8,0xae,0xbb,0x19,0x4f,0x38,0xa8,0xa7,0x2f,0x33,0x28,0xc7,0x99,0x9a,0x4b,0xec,0x2b,0xb7,0x9a,0xb2,0xc7,0x2c,0x42,0x9c,0xa3,0xdc,0x31,0x1d,0x35 +,0xaa,0xaf,0x43,0x1d,0x2e,0xa5,0x96,0x99,0xdb,0x46,0x35,0xac,0xa6,0x32,0x1e,0x17,0x41,0xbb,0x9c,0xcc,0x2b,0x28,0x3f,0x9d,0xaf,0x2b,0x1f,0x3b,0xb2,0x97,0xaa,0x26 +,0x2b,0x2f,0xa5,0xa3,0x25,0x1f,0x1c,0x3a,0x97,0x9a,0x39,0x38,0x1c,0xa9,0x9f,0xdc,0x3a,0x16,0x3d,0xaa,0x9c,0xad,0x38,0x1f,0xdf,0xd4,0xb2,0x38,0x10,0x2b,0x34,0x9d +,0x9f,0x22,0x1f,0x25,0x52,0xa0,0xbb,0x1d,0x30,0x20,0x9a,0x9e,0xce,0x4f,0x1e,0xb2,0xa5,0xa6,0x2a,0x1c,0x28,0x9f,0x90,0x9f,0xbd,0x26,0x4d,0xa8,0x99,0xb9,0x20,0x2b +,0x2b,0x95,0x9f,0xaf,0x34,0x1e,0xb7,0x9f,0xa9,0x2a,0x2b,0x49,0xa1,0x93,0x98,0x31,0x2c,0x3b,0xc6,0x9b,0x2c,0x16,0x1e,0x20,0x97,0x99,0x37,0x27,0x1a,0x21,0xb4,0x25 +,0x19,0x11,0x0f,0xb6,0xd8,0xaf,0x1b,0x17,0x2f,0xbe,0xa9,0x33,0x1a,0x1d,0xb5,0x97,0x95,0xc7,0x39,0x34,0xad,0x97,0xa7,0x2a,0x21,0x25,0x9b,0x96,0xac,0x3d,0x25,0x7c +,0x9a,0x9c,0xe7,0x2f,0x45,0xa1,0x8e,0x93,0x5f,0xb1,0x30,0x9e,0x8e,0x3e,0x2e,0x19,0x2a,0x97,0x95,0xab,0x3e,0x1c,0x29,0xa9,0x21,0x25,0x0f,0x20,0xbd,0x9e,0x9f,0x17 +,0x1a,0x20,0x65,0xab,0x2b,0x0d,0x19,0x1b,0xae,0x9a,0x1e,0x2f,0x1d,0x2f,0x9a,0x3f,0x35,0x1b,0x32,0xa2,0x8e,0xcf,0x49,0x2c,0x56,0x93,0xad,0xd3,0x15,0x27,0xb4,0x8e +,0x96,0xa7,0x35,0x25,0xaa,0x9a,0xae,0x1e,0x25,0x68,0x99,0x8f,0xa4,0xcd,0x3c,0xbc,0xaa,0xe2,0x19,0x15,0x23,0x48,0x91,0xbc,0x26,0x21,0x30,0xa0,0x9e,0x27,0x16,0x16 +,0x23,0x95,0x9d,0xab,0x55,0x29,0xba,0xad,0x41,0x14,0x15,0x1b,0x9d,0x9b,0x72,0x3d,0x24,0xac,0x9d,0x9b,0x1b,0x17,0x10,0x3b,0x96,0xa9,0xbc,0x1a,0x2e,0xbb,0xa0,0x2c +,0x17,0x1e,0x29,0x97,0x98,0xac,0x2c,0xb3,0xad,0x93,0x9b,0x16,0x2a,0x14,0x97,0x8f,0xad,0x33,0x37,0x4f,0x95,0x93,0x1d,0x21,0x0d,0x49,0x9d,0xa7,0xb5,0x30,0x3c,0xa5 +,0x9f,0x27,0x0e,0x0d,0x22,0xa3,0x91,0xb8,0x14,0x29,0x27,0x92,0xa1,0x1e,0x1e,0x1a,0xab,0x8e,0x93,0x37,0xa4,0x6c,0x99,0x96,0x23,0x1f,0x14,0x5f,0x94,0x93,0x30,0x2b +,0x2f,0xd8,0x8d,0xb6,0x1a,0x0d,0x1e,0xb8,0x8d,0xb7,0x26,0x20,0x1f,0x98,0x68,0x1f,0x0d,0x19,0x26,0xa1,0x9f,0x1d,0x25,0x43,0x9f,0x95,0xcb,0x13,0x13,0xeb,0x9d,0x86 +,0xc5,0x26,0xbf,0x3e,0x90,0x9b,0x21,0x0f,0x1d,0x2e,0x90,0xd0,0x25,0x24,0x2e,0x9a,0xa4,0x28,0x0d,0x15,0x46,0x99,0x96,0xbd,0x1e,0x43,0x95,0x8f,0x97,0x1c,0x0f,0x2c +,0x34,0x8f,0xaf,0x1f,0x35,0xc2,0xa7,0x9e,0x2a,0x10,0x1e,0x6a,0x8e,0xa1,0x26,0x20,0xbe,0x93,0x93,0xae,0x0e,0x0d,0x1e,0xbe,0x99,0xbb,0x25,0x27,0xa0,0x9c,0x8e,0x1e +,0x18,0x24,0x3f,0x98,0xb8,0x22,0x18,0xa4,0x9a,0x8f,0x38,0x13,0x0e,0x4b,0x9a,0x9e,0xbc,0x13,0xbe,0x9e,0x96,0x9b,0x22,0x14,0x1a,0xc8,0xae,0xa2,0x1b,0x30,0xa5,0x99 +,0x8f,0x24,0x16,0x14,0x9e,0xa0,0x9c,0x28,0x16,0xe4,0x9a,0x96,0xad,0x1a,0x0d,0x36,0x66,0x9e,0xc7,0x14,0x22,0xd4,0xad,0xb0,0x1a,0x11,0x1b,0xb8,0x9c,0xab,0x1f,0x1f +,0xbb,0x90,0x96,0xaa,0x1b,0x10,0xc4,0xa5,0xa4,0x9f,0x1b,0x56,0x97,0x9c,0x93,0x4d,0x1e,0xc7,0xa4,0xaa,0x9e,0x1a,0x36,0xaf,0x9c,0xaa,0x26,0x10,0x13,0x3b,0xae,0xbd +,0x34,0x18,0x28,0x95,0x9f,0x9b,0x2c,0x14,0x46,0x9f,0xac,0x9c,0x1c,0x2b,0xa3,0xa7,0xaa,0x1e,0x15,0x16,0x48,0xcd,0x48,0x29,0x1e,0x35,0x97,0x97,0xac,0x5f,0x11,0xb9 +,0x99,0xa6,0x99,0x1d,0xef,0x9e,0x9f,0xc1,0x26,0x0e,0x3b,0xb2,0xae,0xa1,0x1d,0x3f,0x5d,0x93,0xa2,0x5d,0x23,0x17,0xb0,0x9c,0x9b,0xa5,0x3d,0x29,0x98,0x9f,0x3f,0x2b +,0x08,0x2c,0xe7,0xb7,0x4b,0x1d,0x26,0xb8,0x9c,0x54,0xc3,0x10,0x25,0xd5,0xa6,0xc1,0x37,0x25,0x22,0x9b,0xb8,0xe5,0x1e,0x16,0xbe,0xa5,0x9f,0xa9,0xb1,0x35,0x97,0x99 +,0xc8,0xbc,0x16,0xce,0xb1,0x9a,0xbc,0x54,0x1e,0xbd,0x95,0xba,0xae,0x1b,0x20,0x32,0xa3,0x48,0x36,0x23,0x17,0xad,0x3c,0xdf,0x2c,0x19,0x27,0xa9,0xb0,0x3e,0xbe,0x17 +,0xae,0xa8,0xa6,0x43,0x1e,0x25,0xac,0x9b,0xc7,0x9d,0x1e,0x60,0xa0,0xb5,0xca,0x36,0x2a,0x43,0xa7,0x50,0xb3,0x2e,0x28,0xa1,0xa6,0xa6,0x31,0x2f,0x15,0xa1,0x9e,0xba +,0xbe,0x20,0xc6,0xaa,0x9f,0x55,0xaf,0x1c,0xb2,0xa7,0x47,0xaa,0x2f,0x4b,0xb9,0xa1,0xd1,0x3d,0x29,0x22,0xa2,0x38,0xca,0x2f,0x1e,0x34,0xb8,0x73,0x28,0x2e,0x13,0xc5 +,0x2e,0xba,0x46,0x25,0x46,0xca,0xac,0x34,0xb5,0x25,0xca,0xaa,0xb8,0xda,0x44,0x2f,0x2b,0x9b,0x2b,0xb0,0x2d,0x2a,0xa1,0xcb,0xb1,0xb0,0xde,0x3d,0x9f,0xd0,0xab,0xae +,0x5e,0xc5,0xa0,0xa4,0xec,0xcc,0x26,0x3e,0xba,0x29,0xce,0x2e,0x2d,0xbc,0xb3,0x3a,0xcc,0x48,0x38,0x9b,0xdc,0x9f,0x66,0x32,0xb6,0xbb,0xc7,0x4e,0xdd,0x26,0xb5,0x5a +,0x36,0x37,0x1f,0x2e,0x2f,0xb4,0x28,0xbb,0x21,0x49,0xa7,0x31,0x36,0x30,0x26,0x3b,0x9f,0x24,0xa5,0x27,0x2f,0xa7,0x4a,0xbe,0xdf,0x6f,0xb8,0xa5,0xcb,0x2e,0x79,0x36 +,0xb0,0xb9,0xbd,0x4c,0xc5,0x54,0xc3,0x9e,0x26,0x9d,0x2f,0xde,0xaf,0x47,0x2f,0xd7,0x2a,0xcf,0xa5,0x22,0xb4,0x38,0x3a,0xaf,0x61,0x3a,0x3d,0x79,0x2c,0xaf,0x53,0x36 +,0xaf,0x2b,0xbc,0x4b,0x3a,0x24,0x9e,0x2d,0xb9,0xa3,0x4a,0x9b,0xb7,0xb9,0xbc,0xaf,0x32,0xa4,0x40,0xc8,0xa2,0x43,0xab,0xc9,0x4f,0xe3,0xb3,0x55,0xdb,0xaf,0x2a,0xb4 +,0x30,0x4a,0xc3,0x3f,0x2f,0xda,0x2f,0x1a,0xce,0x19,0x31,0x44,0x2e,0xc4,0x31,0x22,0x38,0x4c,0x25,0xc1,0x2d,0x21,0xb6,0xf8,0x7b,0xdb,0xc9,0x35,0x9f,0x72,0xad,0xa7 +,0x26,0xa8,0xbd,0xde,0xc8,0xaf,0x2a,0x9e,0xca,0x36,0xb6,0x28,0xd4,0xbe,0xa5,0xac,0xa2,0x40,0xb6,0xa4,0x2f,0xc8,0xbb,0x37,0xb8,0x9b,0x6a,0xbc,0x42,0x50,0x9b,0x3f +,0xd4,0xbb,0x25,0x3d,0xa4,0xe3,0xdd,0xdc,0x27,0xce,0x36,0x2e,0x30,0x20,0x21,0x33,0x55,0x2f,0xbc,0x30,0x2f,0xbc,0x2b,0x37,0x3e,0x29,0x39,0xa2,0x40,0xb8,0x29,0x2b +,0xaf,0x4c,0x69,0xbd,0x51,0x2b,0xa8,0xbc,0xaf,0xf5,0xd1,0xb9,0xd4,0x3d,0x67,0x57,0x29,0xba,0x9a,0x76,0xac,0xcc,0x76,0xba,0xcd,0xb4,0xaf,0x26,0x2b,0xa5,0x43,0xbc +,0x38,0x3f,0x46,0xea,0xdd,0xaf,0x42,0x36,0xbe,0xae,0xd7,0xb6,0xd1,0x5c,0xcb,0xb9,0x3b,0xbc,0x2b,0x3f,0x9f,0x62,0xae,0x48,0x4f,0x47,0xb1,0xc8,0xa1,0x2d,0x2b,0xcf +,0x3c,0x3b,0x3e,0x2e,0x3a,0x5a,0x5f,0x38,0x2d,0x1d,0x43,0xbc,0xd0,0xf9,0x46,0x48,0x3c,0xaa,0xce,0xa7,0x1c,0x3d,0xbb,0xc3,0xdc,0xb7,0x6d,0x2e,0x5b,0x6a,0xa5,0x3e +,0x2f,0xb2,0xca,0x4d,0xe8,0xd4,0x41,0xd8,0xb9,0xb9,0x6f,0x1e,0xdd,0x4b,0xb5,0xab,0xa6,0x3a,0x3c,0x7e,0x4e,0xb7,0x2c,0xd1,0xc9,0xaf,0xce,0xbb,0xe0,0x35,0xac,0xb2 +,0xa1,0x32,0x29,0x44,0xc0,0xc5,0xaf,0xb5,0x25,0xc6,0xfb,0xa8,0x77,0x2e,0x34,0x4e,0x5f,0xc2,0xa8,0x3f,0x3c,0x30,0xd0,0xc4,0x2d,0x3d,0x68,0xb5,0x3c,0xb9,0x4c,0x28 +,0x47,0xc8,0xa3,0x46,0x42,0x22,0xc6,0x2d,0xb9,0xb2,0x2b,0x63,0xf8,0xb1,0x3b,0x3d,0x24,0xa8,0x68,0xc2,0xa6,0x26,0x25,0x3d,0xb7,0xbe,0x4e,0x2a,0x44,0xda,0x2e,0xa0 +,0xe7,0x40,0xcf,0xab,0xa8,0xa8,0xb0,0x30,0xa8,0x2a,0xa6,0xab,0x4c,0x3e,0xb4,0x51,0xed,0xc9,0x1a,0xb0,0x3d,0xf6,0x9e,0x35,0x22,0x43,0x4e,0xcc,0xa1,0x24,0xbd,0xc2 +,0x22,0xaa,0x34,0x1f,0x34,0xa8,0x42,0xa7,0x38,0x27,0xbc,0x32,0xa7,0xa2,0x2c,0x28,0xaa,0x3a,0xad,0xa5,0x1c,0xb6,0x3a,0x3f,0x9e,0xe0,0x21,0x44,0x59,0x6b,0x96,0x2c +,0xc5,0xf5,0x2d,0xb4,0xa5,0x29,0x37,0xa2,0x2e,0x9a,0xdd,0x1f,0xd5,0x2d,0x67,0x9c,0x2c,0x1b,0xaf,0x28,0xae,0xa6,0x1a,0xd5,0x36,0x47,0xa6,0xbc,0x16,0x49,0xb2,0x68 +,0x99,0x34,0x22,0x2e,0x34,0xc1,0x98,0x1d,0x1c,0xa0,0x29,0x96,0x9f,0x25,0x48,0x2a,0x44,0x91,0xb4,0x1e,0x9e,0x28,0xab,0xa2,0x24,0x2f,0x59,0x56,0xa1,0x9f,0x16,0x3d +,0xcb,0x51,0x92,0xb6,0x1a,0xfb,0xde,0x74,0x8f,0x26,0x1c,0x9e,0x24,0x97,0xa8,0x12,0x21,0x53,0x1c,0x92,0xb7,0x0d,0xcc,0x24,0xb1,0x97,0x32,0x1c,0xc9,0x1b,0xa4,0x8e +,0x14,0x27,0xbe,0x1f,0x9a,0xa5,0x1d,0xd7,0x6b,0x28,0x89,0x28,0x11,0xb7,0x1e,0xa5,0x92,0x23,0x1b,0xaa,0x1f,0x8d,0x98,0x16,0xbf,0xd8,0xd4,0x8d,0xb7,0x14,0xbc,0x29 +,0xa8,0x8c,0x12,0x1d,0x3c,0x23,0x9a,0x94,0x18,0x2b,0x48,0x2f,0x88,0xd5,0x17,0x38,0x25,0x3d,0x8f,0x2c,0x15,0xea,0x1e,0x9d,0x9a,0x18,0x4e,0x37,0x2f,0x91,0xa2,0x10 +,0x51,0x20,0xcf,0x8e,0x1f,0x1c,0x1e,0x1d,0xbc,0x94,0x16,0x29,0x41,0x56,0x8c,0xae,0x1e,0x44,0x34,0xb0,0x89,0xec,0x1e,0xb4,0x1b,0x98,0x8d,0x1f,0x38,0x4f,0x29,0x92 +,0x9b,0x15,0x6f,0x13,0xcd,0x8c,0x2d,0x35,0x43,0x15,0x42,0x90,0x1c,0x35,0x48,0x28,0x8c,0x9f,0x13,0x20,0x25,0x1c,0x8c,0x60,0x15,0x69,0x12,0x9f,0x8b,0x29,0x2a,0xbd +,0x1e,0x96,0x97,0x13,0x51,0x1d,0xca,0x8b,0xb8,0x1f,0x36,0x1d,0x4c,0x8e,0x21,0x2c,0x28,0x2c,0x97,0x97,0x31,0xd2,0xd5,0x1d,0x8d,0xa8,0x1d,0xbf,0x1e,0xbe,0x93,0x45 +,0x2e,0xcd,0x1b,0xa6,0xa5,0x11,0x3e,0x20,0x3b,0x95,0xa1,0x1d,0xe2,0x1b,0x28,0x94,0x1a,0x2c,0x3e,0x19,0x6d,0x9a,0x22,0x36,0xd3,0x19,0x9a,0xba,0x1f,0xa8,0x30,0x39 +,0x8e,0xaf,0x30,0x93,0x23,0xab,0x90,0x30,0x5a,0x4b,0x2a,0xac,0x96,0x25,0x9c,0x20,0x12,0x9a,0x37,0x1f,0xbf,0x23,0x39,0x90,0x3f,0xb2,0xbd,0x1e,0x99,0xa2,0x1b,0x2d +,0x35,0x18,0x9f,0xa6,0x24,0x9a,0x1c,0x53,0x9e,0x23,0x28,0xaa,0x1f,0xb9,0x96,0x21,0xa9,0x2a,0x26,0xaa,0xba,0x1f,0x4f,0x1a,0x1f,0x9c,0x38,0x55,0xe4,0x27,0xaf,0xa1 +,0xa2,0x6f,0xc4,0x26,0xae,0xb8,0x23,0xcc,0x39,0xe3,0xbe,0xa6,0xbc,0x99,0x2f,0xb1,0x75,0x2e,0xae,0x13,0x1a,0xd9,0x93,0x90,0xbe,0x1f,0x1c,0x23,0x18,0x21,0x1d,0x49 +,0x4e,0xac,0x8b,0x92,0x9a,0x9d,0xa0,0x11,0x1b,0x0f,0x04,0x21,0x86,0x84,0x93,0x9e,0x0f,0x10,0x43,0x97,0x9f,0x27,0xb5,0x1c,0x0d,0xa9,0x88,0x8e,0x9f,0xcb,0x15,0x08 +,0x1a,0x91,0x9b,0x93,0xb7,0x18,0x0e,0x0c,0x1c,0x1c,0xae,0xa8,0x1e,0x01,0x09,0xbf,0x88,0x80,0x8e,0xc7,0x12,0x36,0x35,0xa1,0x8e,0xe9,0x2c,0x9d,0x8c,0x50,0x11,0x23 +,0xd3,0x08,0x0a,0x30,0x0e,0x0f,0x9b,0x85,0x95,0x3e,0x0d,0x0e,0x9b,0x80,0x83,0x20,0x3f,0xbe,0x2f,0xbf,0xac,0xa9,0x17,0x2f,0x2f,0x2c,0x24,0x22,0x16,0x26,0x9a,0xc9 +,0x0b,0x1b,0x8e,0x89,0x98,0x6f,0x22,0x06,0x1c,0x89,0x84,0x90,0xf8,0x23,0x18,0x1e,0x33,0x1f,0xa0,0x2c,0x1f,0x75,0x9e,0x8c,0x96,0x90,0x35,0x0c,0x05,0x0c,0x09,0x2b +,0x89,0x8b,0xe8,0x0a,0x0b,0x10,0x21,0x93,0x82,0x38,0x08,0xbc,0x9c,0x8c,0x8b,0x8b,0xbe,0x2d,0xca,0x1e,0x22,0x29,0xa2,0x2b,0x12,0x1c,0x28,0x12,0xaf,0x93,0x9c,0xbf +,0x0f,0x04,0x1f,0x87,0x80,0x8d,0xa5,0xa6,0x3c,0x12,0x1e,0x9f,0xa6,0xac,0xc7,0xdb,0x20,0x25,0x1e,0xcc,0xcf,0x1d,0x0c,0x05,0x13,0xac,0x8c,0x9a,0xc1,0x3e,0x14,0x20 +,0xca,0x9b,0x8e,0x9e,0xa7,0xc8,0xfa,0x18,0x40,0x91,0x9f,0x14,0x18,0x3f,0x97,0x98,0x96,0xa7,0x1d,0x0e,0x09,0x11,0x3e,0x93,0x9c,0x93,0x8d,0x9e,0x1a,0x18,0x9e,0x90 +,0x4a,0x3b,0x18,0x0f,0xc8,0x91,0x92,0x9d,0xb4,0x22,0x0b,0x14,0x26,0x1f,0x11,0x36,0x8f,0x8f,0x35,0x27,0xb6,0xbf,0xad,0x0f,0x0d,0x1b,0xa5,0x86,0x84,0x8e,0xa0,0x13 +,0x14,0x20,0xd0,0x4a,0xe2,0x28,0x28,0x9e,0xc5,0x49,0xbd,0xa9,0x1c,0x0c,0x0f,0x44,0xaf,0x90,0x99,0x95,0x54,0x0b,0x0f,0x28,0x90,0x96,0xc0,0xa8,0x23,0x1a,0xb1,0x8a +,0x8c,0x4d,0x2c,0x27,0x2e,0x9d,0x90,0xaa,0xac,0x19,0x0e,0x0a,0x18,0xa2,0x9a,0x3a,0x1e,0x1d,0x0d,0x07,0x39,0x85,0x82,0x8d,0x2f,0x16,0x28,0xe6,0x97,0x8c,0x9e,0x36 +,0x0e,0x33,0xad,0xd6,0x31,0x27,0x1e,0x14,0x10,0x0e,0x20,0x9b,0x8b,0x9a,0x1b,0x14,0x25,0x94,0x84,0x83,0x8e,0x1d,0x0e,0x2a,0xc3,0xa0,0x9c,0xca,0xaa,0x11,0x11,0x0b +,0x2e,0x99,0x3f,0x2c,0x15,0x10,0x17,0xbb,0x8d,0x8e,0xac,0x2f,0x0b,0x13,0xb1,0x8b,0x8a,0x96,0xb0,0x1a,0x14,0x38,0xbf,0xa7,0xad,0x9f,0xc3,0xcc,0xac,0xa1,0x94,0x9b +,0x1c,0x05,0x0b,0x1a,0xa3,0x9e,0xa1,0xd0,0x1b,0x0c,0x12,0xbf,0x98,0x8f,0x99,0x4e,0x2e,0x36,0xa2,0x9a,0x90,0x9b,0x24,0x23,0x2e,0x22,0x34,0xcc,0x26,0x1a,0x1a,0x32 +,0x13,0x24,0xbe,0x52,0xba,0x38,0x2a,0x3c,0x9b,0x84,0x8a,0x96,0xeb,0x2c,0x43,0x36,0x39,0xae,0xbe,0x47,0x26,0x1a,0x5d,0x3e,0xa6,0x28,0x16,0x0f,0x14,0x34,0xa9,0x8d +,0x8d,0x9b,0x36,0x0c,0x0e,0xcf,0x93,0x8d,0x91,0xb5,0x2d,0x3d,0xb8,0xcc,0x26,0x4c,0x44,0xc0,0x5c,0xaf,0xc9,0x9d,0xae,0x1b,0x13,0x10,0x23,0xb9,0x98,0x9f,0x52,0x17 +,0x0e,0x12,0xba,0x93,0x95,0x9c,0x35,0x34,0x2f,0xb2,0x97,0x9e,0x9c,0x37,0x3b,0x26,0x25,0xb4,0xab,0x44,0x28,0x12,0x12,0x1b,0x35,0xb3,0xae,0xa5,0x4c,0x1f,0x26,0x9e +,0x8e,0x97,0xae,0xbb,0xcb,0xa9,0x71,0xc2,0x6c,0xbb,0xc0,0x33,0x4a,0xb2,0xb6,0xad,0x2a,0x14,0x16,0x15,0x40,0xae,0x99,0x9e,0xab,0x30,0x12,0x13,0x2f,0x9f,0x8a,0x96 +,0xa8,0x58,0x2f,0x2b,0x1d,0x2e,0x41,0x2c,0xbf,0xbb,0xa5,0x9f,0xda,0x5d,0x1b,0x1d,0x1a,0x32,0xb5,0x9f,0xb1,0xef,0x2b,0x2f,0x33,0xbc,0x9d,0xa6,0xa2,0x39,0x43,0xcc +,0xa2,0x9c,0xaf,0xb8,0x34,0x2e,0xcf,0xca,0xc8,0x2d,0x1c,0x20,0x2a,0x2e,0x1f,0x1f,0x42,0xaf,0x99,0xc5,0x27,0xdf,0xb5,0x97,0x99,0xa8,0xae,0xb5,0xa7,0x33,0x2f,0x27 +,0x27,0xce,0x3f,0xd1,0xd0,0xba,0xaf,0x27,0x1b,0x21,0x23,0xba,0xbe,0xb7,0xa2,0x54,0x5f,0x1b,0x1e,0xae,0xa9,0x9e,0xba,0xaf,0x64,0x47,0x2c,0x1f,0x29,0x5a,0xbc,0xb2 +,0x9c,0xc2,0xec,0x30,0xc4,0x5e,0x49,0x20,0x1c,0xbf,0xc2,0x9f,0xb5,0x30,0x2a,0x2c,0xc9,0xa7,0x9e,0xa0,0xad,0xaf,0xb0,0xb7,0xa6,0xac,0x6a,0x2c,0x1a,0x34,0x2e,0xb8 +,0x41,0x1a,0x2b,0x1c,0x22,0x1c,0x35,0xab,0xac,0xac,0xc7,0x3d,0xad,0xa0,0x9c,0xa5,0xdf,0xb3,0xb0,0xbb,0x28,0x1e,0x4b,0x48,0xa0,0xb9,0x2b,0x2f,0x3b,0xa8,0x4e,0x39 +,0x2f,0x29,0x43,0xd8,0xbb,0xa2,0xcd,0x3a,0x1a,0x21,0xb4,0xa8,0x9b,0xa9,0xca,0xbe,0x2c,0x24,0x2a,0xbf,0xa9,0xe4,0xb9,0x48,0xae,0xa5,0xb3,0x47,0x2c,0x24,0x21,0x1f +,0xc9,0xba,0xcf,0xba,0x28,0x52,0x2f,0x36,0xcb,0x3e,0xa5,0xa3,0x9a,0xb5,0x40,0xa4,0x9e,0xb3,0x38,0x1c,0x23,0xbe,0xc3,0xaa,0x20,0x40,0x27,0x19,0x1e,0x1f,0xcd,0xb8 +,0xc4,0x3d,0x73,0xa3,0x9d,0x9c,0x9a,0xbe,0xfb,0x32,0x2c,0x2a,0x36,0xbf,0xc4,0xbe,0x4e,0xec,0xa3,0xb3,0xc7,0x18,0x15,0x23,0x2a,0xa0,0xaa,0xae,0xa2,0xaf,0x74,0x28 +,0x26,0x4a,0xba,0xa5,0xa5,0xac,0xab,0x4b,0xdf,0x6e,0x34,0xc7,0x1d,0x30,0x30,0xae,0x94,0xa7,0xb9,0x2c,0x23,0x1e,0x1d,0x1f,0x33,0x38,0x45,0x19,0x2c,0xb3,0x9f,0x8f +,0xae,0xc9,0x60,0x47,0xa7,0xa9,0x98,0x97,0xce,0x2b,0x21,0xcf,0xab,0xcf,0x21,0x0e,0x18,0x1a,0x1f,0xd0,0x41,0xab,0xa7,0xc6,0xc2,0x2e,0x44,0xaa,0xa9,0x9d,0xbc,0xa2 +,0xb6,0xca,0xc3,0x2d,0x5a,0x31,0x33,0x2c,0x27,0xaf,0x99,0xab,0xab,0x3e,0x34,0x23,0x28,0x3a,0x3d,0xb5,0x53,0x30,0x2c,0x54,0x96,0x93,0x9e,0xb6,0x21,0x2e,0xcc,0x4e +,0xd3,0xf4,0x64,0xc6,0x2d,0xbc,0xa6,0xa1,0x7b,0x1e,0x24,0x1e,0xdd,0x2c,0x26,0xae,0xb2,0xae,0x1e,0x16,0x1f,0x40,0xcc,0xb6,0xb8,0xa5,0x9e,0xa5,0x9e,0xa9,0x9c,0x32 +,0x28,0x18,0x1e,0x73,0xce,0xad,0x56,0x59,0x2c,0x22,0x1a,0x2b,0xb9,0xac,0xfb,0x2f,0x26,0xbc,0x8e,0x90,0x93,0x73,0x2c,0x26,0x25,0xb5,0xac,0xa9,0xd1,0x40,0x3a,0xfc +,0xb4,0x4e,0x2e,0x28,0x1c,0x2d,0x2e,0x2d,0xad,0xa0,0x9b,0x9e,0x2a,0x1f,0x24,0xbf,0x9f,0xb2,0xb2,0x35,0xad,0xb6,0x72,0xb3,0x3a,0x4e,0x27,0x1e,0x39,0xbb,0xa4,0x95 +,0xa5,0x9e,0xce,0x25,0x18,0x17,0xab,0x57,0x3e,0x10,0x0f,0x35,0xa8,0x97,0xa3,0x45,0x39,0x40,0xb7,0xa3,0xb2,0xa4,0xca,0xc5,0xbc,0xb2,0xc0,0x20,0x1f,0x1d,0x25,0x2b +,0x1c,0x1d,0x40,0xab,0x97,0xa3,0x3c,0x34,0x38,0xa1,0xb0,0xa9,0xbe,0x62,0xa1,0xa2,0x9e,0xb0,0x43,0x59,0x2d,0x37,0x37,0x1b,0x4b,0xb5,0xa9,0xab,0x41,0x1e,0x18,0x28 +,0xb2,0xae,0xdf,0x1b,0x1c,0xaa,0x92,0x8c,0xa1,0x27,0x26,0x4c,0xa8,0xc9,0x2b,0x20,0x30,0xc3,0x9f,0xa3,0xaa,0x69,0x2e,0x2f,0x4f,0x78,0x1e,0x24,0x2c,0xaf,0xad,0xc9 +,0x1b,0x17,0x33,0xb5,0xbf,0x27,0x33,0xac,0x90,0x8d,0x97,0xae,0x5a,0x49,0x4a,0x39,0x21,0x1c,0x2d,0x65,0xae,0xa7,0x3d,0x15,0x17,0x28,0xb8,0xd2,0x1e,0x14,0x1f,0x9c +,0x8c,0x90,0xa3,0x3a,0xc8,0xa1,0x9e,0xbc,0x23,0x1e,0xda,0xa5,0x99,0xac,0x24,0x2e,0x19,0x42,0x3d,0x28,0x22,0x1d,0xad,0xa7,0x9a,0xa9,0x2d,0x3e,0xbf,0xaa,0xd0,0x1c +,0x28,0xb8,0x9b,0x9a,0x3e,0x27,0x2a,0x4c,0xb4,0x3b,0x1c,0x24,0xbe,0x9c,0x97,0x9c,0xdb,0x1b,0x24,0x49,0xb1,0x42,0x10,0x0f,0x1e,0xa1,0x97,0xad,0x37,0x2a,0x9e,0x8f +,0x93,0x5e,0x2b,0x2b,0xe3,0x9d,0x9f,0xab,0x36,0x2f,0x21,0x40,0x21,0x19,0x1c,0x22,0xc5,0xad,0xad,0x28,0x30,0xbc,0x9e,0xae,0x2b,0x25,0x39,0xa4,0x96,0x9d,0xd2,0xcf +,0xb6,0x9e,0xaa,0x23,0x1c,0x19,0x43,0xa7,0xa2,0xda,0x21,0x24,0x57,0xaa,0xc8,0x2d,0x0f,0x1c,0xe4,0x95,0x94,0xb8,0xe1,0x34,0xa1,0x9a,0xc4,0x1f,0x14,0x1f,0x76,0xa9 +,0xaa,0xc4,0xad,0xa7,0xb1,0xc4,0x2a,0x1b,0x2c,0x36,0xb0,0xb7,0xcf,0x2e,0x22,0xee,0x5c,0x3c,0x1d,0x24,0xd1,0x94,0x95,0xa6,0xbc,0xba,0x9a,0x99,0xb5,0x1c,0x13,0x31 +,0x45,0xac,0xac,0x2a,0x1f,0x1f,0x30,0xc9,0x30,0x1c,0x16,0x19,0xab,0x9e,0x9a,0x4a,0xbd,0xb0,0x99,0x9f,0xe9,0x3e,0x2d,0xac,0xa6,0xa5,0x37,0xc0,0x5c,0xb1,0xb1,0x46 +,0x26,0x17,0x24,0x38,0xc5,0xb2,0xba,0xc5,0x5d,0xc8,0x3c,0x24,0x2b,0xe3,0xa5,0x99,0xb4,0x29,0x24,0x4e,0x9c,0x9c,0xd0,0x1d,0x17,0x2f,0xad,0x9c,0xab,0x3b,0x4b,0x34 +,0xbb,0xc1,0xdf,0x21,0x17,0x27,0xbf,0xb7,0xa7,0xbb,0x43,0xa9,0xab,0xa3,0x2b,0x2b,0xc5,0xb4,0xad,0xbc,0xfa,0x47,0xb6,0xb5,0xaf,0x29,0x22,0x24,0x1b,0x30,0x38,0xb6 +,0x5a,0x3e,0xbd,0x5f,0x49,0x28,0x2f,0xcf,0xad,0x96,0xb4,0xcd,0xc4,0xab,0xa2,0xb7,0x35,0x1b,0x29,0x43,0xb6,0x7c,0x57,0x24,0x32,0x41,0xb3,0xb4,0x4a,0x36,0x2f,0xb5 +,0xb1,0x9e,0xa6,0xb9,0xbf,0xa6,0xa6,0x2c,0x25,0x21,0x2b,0xb9,0xb0,0xae,0xda,0x3d,0x49,0xbc,0xec,0x42,0x47,0x42,0x59,0x34,0x33,0x39,0x3c,0x43,0xca,0xd4,0x3d,0x31 +,0x2e,0xaf,0xb0,0x9c,0xa6,0x4f,0x39,0xd0,0xa3,0xb4,0xde,0x2d,0xc7,0x40,0xba,0xb6,0x77,0x2a,0x23,0x3c,0x26,0x36,0x31,0x7e,0x36,0x43,0xd2,0x5b,0xd3,0x41,0xa6,0x9f +,0xa5,0xf1,0x3f,0x3f,0xe5,0xc9,0xcc,0xcb,0x2c,0xca,0xca,0xaf,0xbf,0x31,0x33,0x2a,0x36,0xbf,0xb4,0x5c,0x46,0xdb,0xaf,0xcc,0xe8,0xab,0x5a,0x4c,0x57,0xc9,0xcb,0x3c +,0xcc,0xbc,0xbc,0x35,0x3e,0x2f,0x3a,0xca,0xb1,0xa8,0x3b,0x59,0x37,0xc9,0x6f,0x45,0x70,0x28,0x2f,0x23,0xbf,0xb5,0xc9,0xae,0xc7,0xd1,0x4f,0x4b,0xbc,0xbd,0x5e,0xa7 +,0xb2,0xe8,0x67,0xf2,0xbf,0x3a,0xde,0xbc,0xc7,0x2b,0x3a,0x31,0x2d,0x3a,0x5d,0xa6,0x3c,0x2f,0x23,0x25,0x48,0xad,0x98,0x9e,0xb3,0x2f,0x37,0x34,0x73,0xac,0xaf,0xad +,0x35,0xde,0xb6,0xc7,0x48,0x34,0x31,0x3b,0x37,0x47,0xb4,0x2a,0x3a,0x43,0xfb,0x5d,0x36,0xf0,0x38,0x2e,0x36,0xb4,0xe2,0xc1,0xae,0xa5,0xa2,0xad,0x9c,0xb8,0x4e,0x3e +,0xb5,0xb3,0xb7,0xb6,0xe5,0x50,0x1a,0x23,0x29,0x2e,0x33,0x32,0x44,0x34,0x35,0x3c,0xf8,0x3d,0xc8,0xaf,0xa9,0xaf,0x3a,0x5c,0x66,0xb4,0x9c,0x97,0x98,0xba,0x2c,0x2a +,0x24,0x24,0xc6,0xc6,0x75,0x3b,0x2c,0x2d,0x1d,0x2b,0x34,0xde,0x49,0x45,0xd8,0xd4,0xb1,0xad,0x99,0xb4,0x63,0x53,0xb6,0xac,0xd9,0xb2,0xdb,0xbd,0x43,0xb7,0xb3,0xcf +,0x3e,0x26,0x33,0x21,0x2b,0x4d,0xdc,0xdc,0xb3,0xbf,0x2a,0x18,0x1e,0xf9,0xcf,0xaa,0xa5,0xb5,0xdb,0xca,0xa3,0x9c,0xa4,0xc1,0xc9,0x36,0x2e,0x50,0x57,0xf9,0x47,0xdd +,0x58,0x32,0x1d,0x1d,0x26,0x23,0xca,0xc6,0xaf,0xc9,0x33,0xd1,0xb6,0xb0,0x67,0xbc,0xb7,0xb4,0xb8,0x9e,0xaa,0xbc,0xb5,0x69,0x71,0x2b,0x43,0x39,0x2d,0x29,0x4e,0xcd +,0x5f,0x6c,0xce,0xb5,0x34,0x48,0x59,0x3b,0xda,0xce,0xb4,0xb2,0xb2,0xbf,0xcc,0x31,0x2b,0x59,0xdb,0xad,0xd9,0xdf,0xb8,0x37,0x37,0xcf,0xc4,0x33,0x2c,0x2c,0x3d,0x2a +,0x3a,0xab,0xb7,0xab,0x5d,0xce,0x38,0x2c,0x58,0xc5,0xd3,0x7d,0xb0,0xbc,0xa8,0xb6,0xb2,0x44,0x26,0x47,0xdc,0xb1,0xca,0xd5,0x33,0x62,0xbf,0xae,0xae,0x30,0x24,0x20 +,0x55,0xca,0xc7,0xe8,0xba,0x5b,0xe4,0xab,0xc7,0x79,0x23,0x29,0xf7,0xd8,0xb6,0xa5,0xa7,0x5f,0x46,0x3c,0x40,0x3c,0x3e,0xcf,0x36,0x4a,0x4b,0xb1,0xae,0xb6,0xbd,0x4f +,0x27,0x25,0x49,0x3a,0xbf,0x45,0xb8,0xbc,0x45,0xb5,0xbe,0xcf,0x3d,0x6b,0x6e,0xbe,0x3e,0xb9,0xad,0xd1,0xb4,0x32,0x3e,0x2b,0x2e,0x4a,0xc8,0xbd,0xe5,0xc0,0xbb,0xaf +,0xbc,0xaf,0xde,0x2d,0x28,0x28,0x3c,0x6e,0xac,0xb8,0xbb,0x39,0x32,0xda,0x51,0xbc,0xdf,0xbe,0x46,0x59,0xaa,0xa2,0xcb,0x3a,0x2e,0x23,0x2d,0x29,0xc3,0xca,0x2a,0xc0 +,0xc3,0xb7,0xad,0xc7,0xfd,0x28,0x2a,0xeb,0xb5,0x6d,0xdb,0xda,0xb7,0xaf,0xb6,0xb6,0x65,0x3f,0x39,0x2e,0x51,0xbb,0xbc,0xae,0xbd,0xf3,0x45,0xc5,0x40,0x38,0x4d,0x72 +,0xdc,0x48,0xaf,0xae,0xab,0xc7,0x58,0x50,0x2c,0x2e,0x42,0xfe,0x3b,0xbe,0xb5,0xcd,0x4a,0x3b,0x58,0x2e,0x2b,0x3d,0xbf,0x3e,0x5f,0xb4,0xaf,0xb3,0xd0,0xf9,0x35,0x25 +,0x36,0xdb,0x58,0xe6,0x3d,0x57,0xd7,0xd7,0xae,0xb2,0xdd,0x75,0x2f,0xd9,0xbf,0xa8,0x9e,0xae,0xcb,0x37,0x33,0x5e,0x3c,0x27,0x3c,0x29,0x43,0xb4,0xb1,0xb3,0x44,0x4a +,0xcc,0x38,0xd9,0xce,0x58,0x46,0x4d,0xa7,0x99,0xb3,0x36,0x40,0x34,0x3c,0x50,0x3b,0x31,0x34,0xda,0xa2,0xab,0xbc,0x5e,0x66,0x30,0x3c,0x3f,0x41,0x36,0x4e,0xad,0xc4 +,0xad,0x50,0x37,0x4c,0x46,0x3e,0x2f,0x27,0x3c,0xa3,0x9a,0xa5,0xd6,0x40,0xde,0x67,0xdf,0x39,0x2b,0x34,0x48,0xa2,0x9d,0xb5,0x40,0x2c,0x1c,0x28,0x38,0x3f,0x3d,0x2f +,0xbc,0x9f,0x9c,0xbd,0x3b,0x37,0x43,0x3f,0x3b,0x3b,0x2c,0xad,0xa9,0xa8,0xb7,0xd5,0xc5,0x2e,0x29,0x28,0x3e,0x48,0xbc,0xb7,0xad,0xc7,0xcc,0xb7,0x54,0x56,0x40,0x2b +,0x23,0x3e,0xae,0x9b,0x9f,0x3f,0x47,0x6e,0x72,0x3d,0x1e,0x28,0x32,0xbc,0xa4,0x9e,0xb2,0xa9,0xb4,0xbc,0x6e,0x28,0x43,0x2b,0x44,0xbc,0xa8,0xac,0x75,0x2f,0x31,0x34 +,0x24,0x25,0x1e,0x5a,0xae,0x9e,0xa6,0x2e,0xc2,0xad,0xaa,0x48,0x23,0x26,0x30,0xbd,0xb2,0xab,0x4b,0x36,0xe3,0xae,0xd0,0x29,0x24,0x1a,0x3e,0xa9,0x93,0x9b,0xbd,0x39 +,0x4c,0xaf,0x4c,0x2e,0x1d,0x26,0x2b,0xb8,0xaa,0xb3,0xaf,0xb7,0xab,0x39,0x28,0x20,0x3b,0xba,0xb9,0x9f,0xba,0xc5,0xb5,0xac,0x6d,0x2e,0x1b,0x1d,0x32,0x66,0x9f,0xac +,0xbb,0x34,0xbb,0xae,0x3f,0x26,0x21,0x54,0xd6,0x9d,0xa6,0xc3,0x70,0xc0,0xa0,0xf4,0x27,0x14,0x21,0x33,0x64,0xa6,0xa3,0xae,0xcd,0xad,0xb4,0xc8,0x26,0x24,0x22,0x35 +,0xc3,0xba,0xa6,0xaf,0xa8,0xaf,0x31,0x15,0x1a,0x29,0xd9,0xa7,0xb1,0xab,0xdd,0xaa,0x9a,0xaf,0x28,0x17,0x1f,0x39,0xcc,0xb5,0xac,0x5d,0xd3,0xa8,0xa2,0xbc,0x19,0x18 +,0x22,0xc6,0xae,0x9d,0x9f,0xde,0xb0,0xab,0xa8,0x31,0x1c,0x17,0x2c,0x52,0xd1,0xa8,0xac,0x9e,0x9d,0xa5,0x35,0x19,0x1c,0x23,0x30,0x2e,0xce,0xc0,0xb8,0xa0,0x9a,0xa4 +,0x23,0x18,0x19,0x57,0xb8,0xa9,0xa8,0xd8,0xb3,0xac,0x9d,0x36,0x18,0x18,0x2d,0x4c,0xd6,0xa4,0xb5,0xa5,0xb1,0xa0,0xb1,0x23,0x18,0x18,0x50,0x57,0xbe,0xbd,0xb3,0xc4 +,0xad,0xa1,0x52,0x32,0x1c,0x2a,0x3f,0x55,0xb3,0xa8,0x9c,0x9d,0x9c,0xb6,0x2e,0x19,0x3a,0xe9,0x29,0x2e,0x29,0x4f,0xbb,0x9a,0xaa,0x32,0x18,0x16,0x44,0xc4,0xb3,0xab +,0xaa,0xbd,0xa7,0x9e,0xa3,0x32,0x11,0x1e,0x5b,0xb2,0xb6,0xca,0xb9,0xae,0xad,0xb0,0x42,0x1c,0x1d,0x27,0x4d,0xd9,0xbb,0xa2,0xac,0xa3,0xa7,0xab,0x2e,0x1b,0x23,0x21 +,0x2e,0x29,0x3d,0xb7,0x9b,0x97,0x9a,0xc1,0x1a,0x1e,0x50,0xac,0xd8,0x4d,0x3f,0x75,0xbf,0xa5,0xab,0x1f,0x17,0x18,0x34,0xd2,0xb2,0xac,0xac,0xa7,0xab,0xa3,0xcc,0x22 +,0x19,0x28,0xd1,0xcd,0xb3,0xb3,0xa3,0xa4,0x9e,0xad,0x2d,0x17,0x1b,0x2d,0x2c,0x3e,0xf8,0xa2,0xad,0xa1,0xa5,0xaf,0x40,0x29,0x3e,0x20,0x37,0x2f,0xed,0xa9,0xa2,0x9b +,0xb0,0x33,0x1e,0x2f,0x46,0x60,0x26,0x38,0xb1,0xb9,0x9e,0xab,0xdd,0x1e,0x1e,0x2b,0x43,0xc9,0xf2,0xb1,0xad,0xa2,0xa9,0xbc,0x22,0x17,0x1c,0x21,0xc5,0x59,0xb1,0xa6 +,0xa1,0x9d,0xa3,0xa6,0x46,0x26,0x1d,0x2a,0x24,0x30,0xaf,0x9e,0xaa,0xb8,0xaf,0x2c,0x27,0x2e,0xf7,0x4c,0x20,0x3c,0xca,0xa1,0x96,0x92,0xa5,0x45,0x27,0x28,0xd0,0x36 +,0x41,0x40,0x7a,0xf6,0xc6,0xb0,0xc8,0x3f,0x23,0x32,0x2c,0xc3,0xa6,0xae,0x5d,0x25,0xe7,0xaa,0x9d,0xce,0x28,0x19,0x2c,0xd3,0xa2,0xb8,0x2e,0x1e,0x4f,0x9b,0x8e,0x9f +,0x26,0x22,0x23,0x99,0x9e,0x98,0x0e,0x3c,0x1f,0x00,0x0a,0x05,0xb8,0x2a,0x33,0x4d,0x1b,0x96,0x98,0x90,0x8c,0x8d,0xac,0x9c,0x8a,0xa0,0xa8,0x8b,0x22,0x24,0x8d,0x0a +,0x8c,0x83,0x9e,0x94,0x8a,0xdd,0x23,0x0f,0x03,0x0a,0x01,0x07,0x04,0x0c,0x03,0x08,0x07,0x14,0x04,0x09,0x10,0x08,0x19,0x27,0xbb,0x5e,0x99,0x99,0x92,0x99,0x8e,0x8c +,0x8f,0x89,0x8c,0x89,0x86,0x87,0x81,0x82,0x80,0x84,0x80,0x90,0x87,0x89,0x0e,0xd7,0x86,0x84,0x0c,0x6e,0x1d,0x08,0x19,0x06,0x03,0x04,0x00,0x08,0xb0,0x0f,0x0b,0x00 +,0x06,0x0f,0x00,0x03,0x00,0x19,0x0b,0x20,0xa9,0x2a,0x0c,0x29,0x91,0x8b,0x80,0x86,0x8d,0xf5,0x89,0x81,0x81,0x83,0x80,0x93,0x8a,0x86,0x85,0x87,0xac,0x94,0xaf,0x94 +,0xb5,0x8e,0x92,0xa9,0x0e,0x0a,0x0d,0x0f,0x0a,0x00,0x05,0x07,0x04,0x09,0x0b,0x00,0x06,0x03,0x06,0x0b,0x0a,0x0e,0x21,0x3c,0xaa,0xa2,0x69,0x2a,0x9b,0x97,0x9e,0x9e +,0xac,0x8e,0x8b,0xa1,0x94,0x8a,0x8b,0x82,0x8f,0x99,0x80,0x8d,0x8b,0x85,0x80,0x8a,0x89,0x89,0xb2,0x87,0x1f,0x0c,0x17,0x2e,0x0f,0x00,0x17,0x1a,0x06,0x03,0x02,0x00 +,0x06,0x09,0x0e,0x2b,0x13,0x05,0x00,0x00,0x08,0xb2,0x55,0x22,0x1f,0x0e,0x8a,0xed,0xc9,0x89,0x8c,0x80,0x8b,0x95,0x8f,0x87,0x82,0x87,0x84,0x86,0x8e,0x8b,0x87,0x88 +,0x89,0x23,0x1e,0x2c,0xad,0xa3,0x24,0x0f,0x0e,0x98,0x24,0x1b,0x1a,0x0b,0x24,0x07,0x01,0x1a,0x18,0x0e,0x05,0x03,0x01,0xcf,0x1f,0x1d,0x31,0x07,0x09,0x07,0x5e,0x25 +,0x80,0x89,0xb9,0xa8,0xa0,0xe7,0x1a,0x89,0x88,0x8a,0x17,0x37,0x80,0x88,0x8e,0xc1,0x1b,0x90,0x80,0x82,0x8c,0x8f,0x9c,0x99,0x16,0x92,0x96,0x15,0x28,0x1a,0x09,0x00 +,0x02,0x17,0x19,0x0d,0x1c,0x00,0x0a,0x06,0x35,0x92,0x08,0x07,0x0c,0x0b,0x2e,0xad,0x93,0x24,0x17,0x1d,0xae,0x88,0x89,0x92,0x84,0x89,0x26,0x3c,0x8f,0x80,0x89,0x83 +,0x9f,0x86,0xf4,0xad,0x81,0x81,0xa2,0x0a,0x19,0xa5,0x80,0x13,0x0b,0x5d,0x91,0x10,0x9a,0x91,0x0c,0x07,0x06,0xc3,0x07,0x19,0x21,0x00,0x0f,0x02,0x0c,0x0a,0x57,0xbc +,0x00,0x09,0x05,0xaf,0x2a,0xa9,0x4b,0x0f,0xac,0x08,0x8b,0x81,0x92,0x9f,0x60,0x8d,0x9a,0x8b,0x85,0x80,0x80,0xcd,0x17,0x8c,0x89,0x8d,0xa3,0x91,0x8a,0x9e,0x9f,0x0c +,0x10,0x90,0x82,0x0e,0x0b,0x08,0x21,0x1b,0x09,0x29,0x00,0x30,0x16,0x14,0x1a,0x11,0x01,0x09,0x3d,0x05,0x08,0x18,0xa8,0x37,0x0b,0x0c,0x93,0xa9,0xcd,0x15,0x05,0x3c +,0x8c,0x80,0x82,0x88,0x0f,0xb3,0xc4,0x85,0x82,0x56,0x8a,0x27,0x89,0x87,0x87,0xa0,0x1c,0x86,0x27,0x90,0x96,0x0d,0x98,0xaa,0x86,0x88,0x56,0x0b,0x0c,0x99,0x10,0x07 +,0x00,0xaf,0xbf,0x05,0x06,0x0d,0x0a,0x05,0x08,0x09,0x27,0x0d,0x06,0x05,0xd7,0x9f,0x9a,0x19,0x1a,0x1c,0x9d,0x88,0xa7,0x84,0xa7,0x91,0x8b,0x92,0x88,0x91,0x89,0x88 +,0x98,0xa7,0xd6,0x88,0x88,0x8c,0x9c,0x8f,0xa8,0x19,0x10,0x0e,0xa5,0xa2,0x25,0x17,0xc7,0x0c,0xaf,0xad,0x53,0x09,0x1f,0x1e,0x0e,0x1a,0x08,0xa1,0x0b,0x3e,0x9b,0x14 +,0x04,0x0a,0x18,0x1c,0xdf,0x19,0x05,0xb7,0x9e,0xb1,0x18,0x0e,0x88,0x3a,0x3f,0x94,0xa1,0xac,0xa1,0x87,0x83,0x8c,0x9d,0x9c,0x6a,0x97,0x8c,0x88,0x9f,0x82,0x85,0x9f +,0x8a,0x98,0x17,0x0f,0x9a,0xb0,0x8b,0x26,0x0e,0x0a,0x0e,0x68,0xcf,0x09,0x03,0x0b,0x1b,0x1f,0x0b,0x0d,0x00,0x1c,0x19,0x2e,0x27,0x0c,0x06,0x33,0x2d,0x34,0x96,0x13 +,0x9c,0x8a,0x96,0x98,0xa8,0xab,0xa3,0x8e,0x89,0x8c,0x84,0x8f,0xae,0x83,0x8e,0xa5,0xba,0x98,0x9c,0x21,0xa5,0x9e,0xaa,0x3e,0xc5,0xba,0xa7,0x2d,0x05,0x0b,0x26,0x52 +,0xca,0x93,0xc3,0x15,0x11,0x64,0x27,0x0e,0x1d,0x14,0x9e,0x13,0x15,0x09,0x17,0x29,0x14,0x1e,0x0d,0x15,0x0a,0x27,0xa5,0x9f,0x0f,0x3b,0xba,0x98,0x98,0x97,0x22,0xb9 +,0x8c,0x97,0x80,0x8a,0x8f,0xa2,0x89,0x8d,0x8f,0x87,0xcf,0xa4,0x8b,0x90,0x9c,0x41,0xb5,0xb7,0x96,0xba,0x0b,0x20,0x00,0x0f,0x9b,0x48,0x0d,0x04,0x28,0x13,0x24,0x10 +,0x00,0x07,0x28,0xd5,0x2f,0x25,0x0e,0x0f,0x20,0x1a,0xb6,0xba,0x11,0x9c,0xf8,0xa5,0xa2,0x33,0x9d,0xa8,0x85,0x8e,0xd2,0x9b,0x9d,0x8a,0x83,0x86,0x86,0xa0,0xa8,0x8d +,0x91,0x9a,0xa6,0x1e,0x10,0x91,0x8f,0x93,0x0c,0x19,0xe2,0x1a,0xc2,0x0a,0x16,0x0d,0x21,0x97,0x76,0x08,0x13,0x0c,0x21,0x94,0x13,0x07,0x0a,0x0d,0x2b,0x8f,0xf5,0x15 +,0x0f,0xc8,0x98,0x2e,0xa7,0x0f,0xe5,0x92,0x91,0x87,0x93,0xaa,0x2e,0x98,0x8b,0x89,0x40,0x15,0x2b,0x85,0x83,0x91,0x19,0x0f,0xd0,0xa3,0x8a,0x12,0x26,0x0d,0x36,0x83 +,0x9a,0x1d,0x05,0x12,0x9e,0x8f,0x10,0x07,0x02,0x17,0x96,0x92,0x1e,0x0d,0x19,0xac,0xab,0xaf,0x2c,0x04,0x30,0xa5,0x8d,0x9e,0x16,0x0b,0x1a,0xaa,0x9d,0x26,0x17,0x08 +,0x3c,0x88,0x87,0x8f,0x10,0x4a,0x8d,0x8d,0x85,0xc7,0x2f,0xa9,0x8c,0x80,0x8d,0xae,0x16,0x9a,0x8e,0x86,0x29,0x13,0x17,0x2c,0x85,0xa1,0x0b,0x03,0x0c,0x19,0xbd,0x0e +,0x08,0x03,0x0f,0x0d,0x4f,0xa1,0x00,0x0c,0xa4,0x2d,0x9c,0x3d,0x0a,0x45,0x97,0x86,0x8f,0x8d,0x1d,0x7c,0x8d,0x92,0x89,0x25,0x1e,0x9a,0x8e,0x85,0x8b,0x28,0x15,0x94 +,0xb0,0x99,0x6e,0x1d,0x1f,0x27,0x8b,0x48,0x1e,0x04,0x0f,0x2f,0xbc,0x41,0x1d,0x09,0x28,0x8c,0xae,0x96,0x33,0x0a,0x18,0x97,0x8e,0x29,0x16,0xd9,0xa3,0x8d,0x8c,0x1f +,0x07,0x11,0x2c,0x9e,0xba,0x16,0x0a,0xc7,0x88,0xad,0x4f,0x0b,0x09,0x2f,0xd0,0x8b,0x1a,0x17,0x1a,0x9a,0x82,0x96,0x2c,0x1e,0x9c,0x94,0x8b,0x8f,0xc5,0x1f,0x8a,0x85 +,0x85,0x9f,0x3f,0x0b,0x5b,0x8d,0xaf,0x27,0x0a,0x0e,0x3a,0x95,0x53,0x09,0x02,0x0c,0x33,0x39,0x15,0x0e,0x0d,0xdf,0xa6,0x8e,0x3c,0x08,0x0e,0xa4,0x9a,0x8e,0x22,0x19 +,0x9e,0x86,0x84,0x9e,0xe4,0x08,0xd4,0x9b,0x97,0x2e,0x26,0x1c,0x9b,0x80,0x8d,0xaa,0x1f,0x1e,0xa4,0x8c,0xa0,0x10,0x11,0xb9,0x8a,0x98,0xae,0x0f,0x05,0x3c,0x2f,0xa7 +,0x25,0x0b,0x18,0x93,0x96,0x90,0x26,0x0c,0x12,0x22,0xb5,0xda,0x1b,0x0d,0x9d,0x97,0x8f,0xa1,0x0f,0x0b,0xbc,0xab,0x99,0x3a,0x0f,0xce,0x8a,0x8d,0x89,0xc1,0x04,0x28 +,0x38,0x9d,0x39,0x16,0x1b,0xcb,0x8d,0x91,0xa9,0x17,0x0e,0xbc,0x94,0x9f,0x20,0x16,0xbe,0x8d,0x8b,0x94,0x30,0x0b,0x43,0xb0,0xa6,0xbd,0x0f,0x17,0xa7,0x8f,0x8f,0x31 +,0x0b,0x1b,0x3a,0xe2,0x40,0x0c,0x18,0xac,0x94,0x8f,0xad,0x0d,0x13,0x35,0xcf,0xac,0x17,0x0d,0x1a,0x9c,0x8f,0x8c,0xb1,0x12,0x24,0xa8,0x9e,0xda,0x24,0x31,0x92,0x88 +,0x88,0x95,0x1c,0x43,0xa1,0xa2,0xa4,0x1d,0x15,0xea,0x94,0x8e,0x9b,0x1d,0x0f,0x38,0xc3,0xca,0x2e,0x10,0x20,0xaf,0x9b,0x9a,0xe0,0x1b,0x28,0xc4,0x74,0x32,0x13,0x0e +,0xcf,0x95,0x94,0x9e,0x18,0x13,0x43,0xbe,0xd1,0x1f,0x0c,0x1e,0x99,0x97,0x93,0xb5,0x18,0xd5,0xc8,0x45,0x26,0x0f,0x10,0xaf,0x97,0x99,0xa2,0x18,0x25,0xab,0xb4,0xbc +,0x28,0x0f,0x3e,0x98,0x8e,0x8f,0x2f,0x18,0x4e,0xc0,0xff,0x24,0x12,0x1b,0x9d,0x99,0x9d,0xb8,0x1b,0x37,0xa8,0xb7,0x34,0x19,0x0c,0xc0,0x8f,0x8f,0x9c,0x23,0x1a,0xc4 +,0xb1,0x2f,0x1b,0x0e,0x28,0x98,0x8f,0x99,0xbe,0x21,0x41,0x9b,0xb9,0x1c,0x0f,0x0f,0xaa,0x8f,0x9c,0xba,0x24,0x26,0xaa,0xa0,0x32,0x15,0x10,0x26,0x9c,0x92,0x9a,0x62 +,0x29,0xb8,0x9c,0x7e,0x1a,0x11,0x1e,0x9d,0x8f,0x98,0xaf,0x23,0x2a,0x9e,0xa9,0x2b,0x18,0x13,0xc1,0x8f,0x91,0xa7,0x31,0x31,0xac,0xa0,0x25,0x15,0x12,0x1e,0xa7,0x96 +,0xa5,0xc4,0x38,0xf7,0x9b,0xd1,0x1a,0x10,0x16,0x48,0x98,0x9d,0xb5,0x5e,0x46,0xaa,0xab,0x42,0x17,0x11,0x1e,0xa1,0x93,0xa7,0xe5,0x32,0xb2,0x9c,0xe8,0x14,0x0e,0x18 +,0xab,0x92,0xa0,0xdb,0x39,0xd4,0x9d,0x9f,0x1e,0x0a,0x13,0x3b,0x9c,0x9a,0x48,0x58,0x68,0x9f,0x9f,0x3d,0x12,0x16,0x2c,0xa5,0x98,0x62,0x3f,0x3a,0xa0,0x96,0x9f,0x18 +,0x10,0x1e,0xb8,0x99,0xa6,0xc7,0x3b,0xaa,0x9d,0x95,0x31,0x13,0x1c,0x39,0x99,0x9e,0xf5,0x31,0xbf,0x9c,0x9c,0xcf,0x11,0x0f,0x1f,0xf5,0x9d,0xa5,0x38,0xe1,0xa7,0xa5 +,0xa1,0x29,0x10,0x1c,0x4c,0xac,0xa9,0x31,0x30,0xaf,0xaa,0x9d,0x5d,0x14,0x11,0x28,0xae,0x9f,0xa9,0x2d,0xec,0xa1,0x9c,0xa1,0x26,0x10,0x1d,0xdb,0xab,0xac,0x3b,0x2f +,0xac,0x9e,0x9d,0x62,0x16,0x1b,0x35,0xae,0x9d,0x67,0x27,0xb3,0xa4,0x9b,0xac,0x1b,0x10,0x24,0xce,0x9f,0xa9,0x1f,0x4a,0xb6,0xaa,0x9f,0x36,0x11,0x1c,0x37,0xb9,0xa3 +,0x30,0x30,0xb8,0xa2,0x9a,0xa9,0x20,0x1d,0x6d,0xb6,0xa6,0xc6,0x28,0x34,0x9f,0x9e,0xa6,0x3f,0x17,0x28,0x4e,0xab,0xac,0x2d,0x2b,0xb1,0xaa,0xa4,0xd3,0x18,0x1d,0x42 +,0xae,0xa5,0xcb,0x2b,0xb6,0x9f,0x9e,0x9f,0x2d,0x1b,0x2d,0xd3,0xb0,0xb3,0x2a,0x2d,0xb0,0xae,0xab,0x35,0x14,0x1a,0x2d,0x77,0xc2,0x31,0x27,0xb6,0x9f,0x9e,0xa8,0x27 +,0x1a,0x3d,0xbe,0xa6,0xb1,0x2c,0xeb,0xa6,0xa1,0x9f,0x3a,0x1b,0x30,0xcc,0xaa,0xa4,0x2f,0x31,0xaa,0xb0,0x9f,0xc6,0x1a,0x1c,0x32,0x65,0xae,0x4b,0x23,0xd3,0xad,0xa1 +,0xa9,0x29,0x1a,0x2f,0x51,0xb2,0xaf,0x2c,0x57,0xa7,0xa3,0xa3,0xf3,0x1e,0x27,0x68,0xb2,0xa2,0x2d,0x23,0x4b,0xdb,0xb8,0xc5,0x1f,0x1e,0x61,0xbb,0xa3,0xb9,0x2c,0xdd +,0xab,0xaa,0x9e,0x42,0x1c,0x3f,0x4f,0xbe,0xaa,0x2e,0x2f,0xb0,0xa8,0xa4,0xaf,0x25,0x29,0xca,0xc9,0xab,0xd7,0x22,0x34,0xb7,0xda,0xb9,0x41,0x1c,0x44,0x6d,0xe8,0xb7 +,0x26,0x2b,0xbb,0xb7,0xac,0xb3,0x27,0x38,0xbf,0xd2,0xab,0x63,0x26,0xc8,0xb3,0xde,0xa7,0x2f,0x25,0xd6,0xe5,0xb4,0xae,0x2c,0x39,0xaa,0xf8,0xa9,0xc1,0x23,0xbf,0xc4 +,0xd7,0xad,0x4b,0x22,0xc0,0xc0,0xce,0xa3,0x38,0x2d,0xca,0x3c,0xdb,0xae,0x27,0xce,0xa9,0x54,0xb5,0xc9,0x26,0xd7,0xc1,0x3e,0xaf,0x2a,0x1d,0xd6,0x30,0x68,0xaf,0x2c +,0x31,0xce,0x41,0xfd,0xb7,0x26,0xca,0xb3,0xe1,0xad,0xc4,0x2b,0x5c,0xbf,0x57,0xac,0x42,0x45,0xac,0x7a,0xbc,0xaa,0x2f,0x44,0xb3,0xd3,0xab,0xb9,0x2d,0xe4,0xc2,0x57 +,0xaf,0xbf,0x2b,0xb7,0x7b,0x3e,0xad,0x2c,0x2f,0xbb,0x4e,0xc3,0xac,0x24,0x36,0xf7,0x2d,0xb8,0x3c,0x29,0xc6,0x57,0x35,0xb4,0x3e,0x27,0xaf,0xee,0xd7,0xb0,0x2b,0x2b +,0xc6,0x2e,0xdc,0xba,0x26,0xc7,0xaf,0xf0,0xac,0xc5,0x40,0xa6,0xb4,0xba,0xa1,0x3e,0x2f,0xb2,0x4a,0xd1,0xaf,0x44,0xdf,0xb3,0x2d,0xc4,0xcd,0x30,0xaa,0xb3,0x79,0xc2 +,0x48,0x29,0xba,0x3f,0x4f,0xb2,0x2e,0xd1,0xae,0x2f,0x4e,0xd2,0x26,0x5a,0xd3,0x2b,0xe0,0x48,0x28,0xbf,0xd6,0x30,0xcf,0x40,0x34,0xba,0x36,0x3c,0xd0,0x29,0x4c,0xab +,0x45,0xbf,0xba,0x28,0xce,0x49,0x3c,0xa7,0xd3,0xc6,0xa5,0xbd,0x41,0xb3,0x64,0xca,0xa7,0xe3,0xb0,0xc1,0x2e,0xb9,0xa1,0x49,0xa6,0xb4,0x2d,0xbb,0x47,0x5a,0xb3,0x3a +,0x49,0xa6,0x49,0x63,0xb7,0x24,0x29,0x53,0x2f,0x60,0x4e,0x22,0x52,0x5b,0x2f,0xbb,0x36,0x26,0xcf,0x61,0xce,0xb6,0x24,0x2e,0xb9,0x33,0xae,0xac,0x30,0x4f,0xf7,0x3e +,0xbc,0x3d,0x27,0xa8,0xb8,0x5f,0xac,0x3b,0x37,0xbe,0xbe,0xac,0xb9,0x28,0xee,0xae,0xd5,0xa5,0xb0,0x3b,0xd4,0xba,0xca,0xac,0x2d,0x38,0xb0,0x4f,0xb5,0xa4,0x3c,0x3b +,0xc4,0xf9,0xb7,0x33,0x2c,0xc3,0x6d,0x6d,0xa7,0x54,0x20,0x37,0x3b,0x4d,0xc3,0x23,0x31,0x45,0x29,0xcd,0xb6,0x39,0xce,0xc7,0x5a,0xbb,0x2a,0x32,0xb1,0xdd,0xb5,0xa7 +,0x33,0x35,0x3d,0x44,0xbf,0xc9,0x34,0xc3,0xc6,0x3e,0xa0,0xb3,0x38,0xcd,0x4f,0xd6,0xaf,0x39,0xda,0xb8,0x35,0xbe,0xa9,0x36,0x42,0xc5,0xdd,0xab,0x43,0x2e,0xe9,0x2e +,0xeb,0x9b,0xc0,0x3a,0x4e,0x2d,0xc9,0xb4,0x5a,0xc8,0x3e,0x26,0xad,0xbd,0x2d,0xd6,0xca,0x5b,0xb0,0x3e,0x2b,0x5c,0x27,0xb6,0x9e,0x49,0x37,0xd5,0x36,0xb5,0xb5,0x2f +,0x46,0x2b,0x37,0xa1,0xaf,0x38,0x47,0x29,0x37,0xb1,0x46,0x3f,0x47,0x29,0xad,0xa8,0x2d,0x65,0x69,0xf8,0xa0,0xb0,0x40,0x34,0x1e,0x44,0x9b,0xb4,0x4a,0xd2,0x29,0x46 +,0xad,0x5b,0xbb,0x58,0x2e,0xa2,0xa9,0x32,0xb7,0x73,0x3f,0xa0,0xc6,0x3b,0x3d,0x23,0xc0,0xa8,0x3a,0x3c,0x4c,0x2b,0xc0,0xae,0x39,0x41,0x25,0x2b,0xa3,0xae,0x6f,0xb7 +,0x31,0x37,0xad,0xd9,0x7c,0x61,0x2f,0xa9,0xa7,0x2e,0xf5,0x2b,0x25,0xa4,0xad,0xdd,0xf3,0x1e,0x38,0xa1,0xe5,0xbc,0xae,0x2e,0xe4,0xbc,0x37,0xde,0x2e,0x27,0xa9,0xb5 +,0x37,0xc4,0x33,0x2a,0xa3,0xc9,0x3f,0x71,0x25,0xb9,0x9e,0x36,0xde,0x53,0x1e,0xa9,0xa9,0x4b,0x4f,0x1e,0x28,0xa5,0xd9,0xcf,0xac,0x2b,0x5a,0xa7,0x3f,0x4c,0x66,0x25 +,0xa2,0x9a,0xce,0xb2,0x36,0x25,0xa1,0xa8,0x4d,0xb9,0x23,0x3e,0x9f,0x37,0x46,0xbe,0x1e,0xc7,0xa3,0x2b,0x4a,0x2b,0x1f,0xa3,0xb6,0x2b,0xb3,0x2b,0x34,0x9d,0x5a,0x2f +,0x3a,0x1c,0xbc,0x99,0x4b,0x5f,0x3d,0x1a,0xad,0x9c,0x3e,0xbf,0x37,0x2d,0x99,0xb5,0x38,0xad,0x25,0x54,0x95,0x5e,0x36,0x2f,0x15,0xbb,0xa0,0x3d,0xb8,0x2d,0x1a,0x9f +,0xa5,0x37,0xb4,0x28,0x32,0x99,0xc7,0x3e,0xd5,0x1c,0xce,0x99,0x31,0x39,0x33,0x1b,0xa4,0x9f,0x26,0xd9,0x29,0x20,0x93,0xa3,0x38,0xf4,0x17,0x35,0x94,0xda,0xc0,0x67 +,0x17,0xa7,0x97,0x34,0x43,0x23,0x1c,0x99,0xa2,0x3a,0xdd,0x1b,0x28,0x8f,0xa9,0x40,0xc6,0x17,0xe5,0x96,0x47,0xc7,0x4a,0x17,0x9e,0xa0,0x29,0xcb,0x1d,0x1d,0x97,0xb8 +,0x2a,0xeb,0x16,0xc5,0x8e,0xe0,0x39,0x2e,0x15,0xa0,0x96,0x36,0xdf,0x1c,0x19,0x98,0xa2,0x2f,0xe4,0x16,0x2c,0x91,0xba,0x49,0x59,0x16,0xac,0x8e,0xe1,0xbc,0x25,0x15 +,0x9a,0x9d,0x47,0xb9,0x14,0x22,0x93,0xba,0x45,0x3d,0x15,0xba,0x94,0xe1,0xc4,0x2e,0x19,0x9d,0x9a,0x33,0x55,0x1c,0x23,0x94,0xa6,0x38,0x2f,0x0f,0x5c,0x90,0xc0,0x4f +,0x25,0x12,0x9f,0x94,0x4e,0x4d,0x19,0x1e,0x95,0x9d,0x43,0x2e,0x13,0x51,0x91,0xaa,0xd7,0x2c,0x16,0xad,0x97,0x62,0x4e,0x22,0x1f,0x9d,0x9e,0x4c,0x4e,0x1c,0x35,0x8e +,0xa7,0x35,0x27,0x16,0xb4,0x97,0x4b,0x31,0x1b,0x1a,0x97,0x99,0x5f,0x34,0x16,0x32,0x90,0xa0,0x61,0x2c,0x17,0xbf,0x96,0xc4,0x37,0x1e,0x17,0xa4,0x9d,0x3f,0x39,0x17 +,0x28,0x8f,0x9c,0xc5,0x40,0x12,0xd8,0x96,0xe1,0x5b,0x2a,0x1a,0x99,0x96,0xef,0x6e,0x1a,0x2b,0x99,0xb7,0x3d,0x3b,0x14,0xb3,0x93,0xb5,0xc2,0x20,0x1a,0xa0,0x9d,0x41 +,0x43,0x16,0x1a,0x97,0x9e,0xb6,0x48,0x0f,0x30,0x9e,0x4d,0x3e,0x26,0x19,0x99,0x9a,0x4d,0xb5,0x1d,0x27,0x95,0xb1,0xe5,0x35,0x11,0xcd,0x96,0xb1,0xaf,0x32,0x1b,0xa2 +,0xaa,0x34,0xc3,0x1f,0x2b,0x94,0xaa,0xae,0xb1,0x1c,0x61,0x9c,0x3e,0x3f,0x2e,0x11,0xa7,0x9a,0x45,0xb5,0x21,0x1f,0x9c,0xbc,0x35,0xca,0x14,0x2b,0x97,0x52,0xb4,0xb8 +,0x1c,0xaf,0xa6,0x24,0x4e,0x1c,0x1a,0x98,0xa4,0xc8,0xb1,0x1b,0x2e,0x9c,0x35,0x60,0xbd,0x1a,0xc1,0x9c,0x4a,0x9f,0xbd,0x23,0x9d,0xc9,0x2a,0xaa,0x1b,0x22,0x97,0x44 +,0xcd,0xa4,0x1d,0xb1,0x9a,0x26,0xbb,0x30,0x13,0x9e,0xac,0x62,0x9d,0x28,0x24,0xa3,0x2f,0x3c,0xad,0x14,0x43,0xa5,0x2a,0xab,0xcc,0x1c,0xa2,0xa1,0x47,0x9f,0x24,0x18 +,0xa6,0x3c,0x57,0xab,0x1a,0xc3,0xad,0x2a,0x9b,0x9d,0xd9,0x9d,0x3e,0x2a,0xa7,0x2b,0x1d,0x4f,0xb2,0x96,0x97,0x2a,0x18,0x1c,0x18,0x31,0x1e,0x31,0x9f,0xcc,0xc7,0xa9 +,0x99,0x36,0x4e,0x4b,0x37,0x2b,0x88,0xae,0x04,0x80,0x9a,0x03,0x18,0x17,0x2c,0xc3,0x93,0x27,0x04,0x02,0x00,0x05,0x00,0x02,0x0e,0x20,0x0d,0x00,0x00,0x06,0x0d,0x05 +,0x05,0x01,0x0e,0x02,0x12,0x8f,0x81,0x94,0x36,0x95,0x8f,0x82,0x80,0x83,0x87,0x80,0x80,0x80,0x81,0x81,0x80,0x81,0x82,0x81,0x83,0x84,0x80,0x81,0x80,0x87,0x38,0x13 +,0x8e,0x80,0x82,0x81,0x84,0x8c,0xd1,0x15,0x2c,0xcc,0x0c,0x0c,0x09,0x01,0x00,0x00,0x00,0x0b,0x22,0x04,0x00,0x00,0x00,0x01,0x00,0x02,0x02,0x00,0x00,0x02,0x05,0x03 +,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x13,0x07,0x00,0x00,0x04,0x06,0x09,0xa9,0x88,0x85,0x96,0xdd,0x8d,0x80,0x81,0x80,0x84,0x86,0x85,0x82,0x80,0x80,0x80,0x81,0x81 +,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x85,0x81,0x80,0x80,0x80,0x8b,0xa1,0x86,0x80,0x80,0x80,0x82,0x84,0x91,0xa3,0xaf,0xc4 +,0x1a,0x1a,0x1e,0x0b,0x01,0x00,0x00,0x04,0x12,0x0d,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00 +,0x00,0x00,0x00,0x00,0x01,0x09,0x0a,0x03,0x01,0x00,0x08,0x1b,0x16,0x09,0x04,0x03,0x05,0x15,0xac,0x9f,0x2e,0x2d,0xde,0x5d,0x67,0xf8,0x9b,0x84,0x81,0x81,0x87,0x8c +,0x8c,0x88,0x82,0x80,0x85,0x95,0x8b,0x80,0x80,0x80,0x82,0x8f,0x89,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x84,0x82,0x80,0x80,0x89,0xaa,0xb0,0x8a,0x80,0x80 +,0x80,0x86,0x93,0x9c,0x8a,0x82,0x83,0x8b,0x8f,0x86,0x85,0x84,0x8f,0x9c,0x99,0x8f,0x8f,0x9c,0x9f,0x94,0x87,0x88,0x8b,0xa1,0x29,0x16,0x39,0x8d,0x86,0x89,0x9b,0xbf +,0x98,0x8a,0x8c,0x93,0xbc,0x16,0x0c,0x14,0x2f,0x3d,0x27,0x1f,0x1e,0x0e,0x02,0x01,0x00,0x09,0x1b,0x16,0x08,0x01,0x01,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x01,0x02 +,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x05,0x03,0x00,0x00,0x00,0x02,0x05,0x03,0x01,0x07 +,0x0d,0x10,0x09,0x05,0x0b,0x1a,0x38,0x2a,0x22,0xce,0x9d,0x8d,0x84,0x88,0x92,0xa2,0x8b,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x80,0x80,0x81,0x83,0x82,0x81,0x81,0x82,0x84,0x88,0x8b,0x8e,0x8e,0x8a,0x88,0x8a,0x8c +,0x8a,0x9b,0x3a,0x16,0x1d,0x63,0x38,0x0f,0x02,0x02,0x02,0x0d,0x12,0x0e,0x07,0x01,0x01,0x00,0x02,0x02,0x01,0x02,0x05,0x05,0x02,0x00,0x00,0x01,0x03,0x04,0x01,0x00 +,0x00,0x02,0x06,0x06,0x03,0x00,0x00,0x01,0x03,0x04,0x04,0x06,0x09,0x13,0x14,0x11,0x0d,0x0b,0x08,0x06,0x08,0x0d,0x19,0x3c,0xa6,0xa4,0xdc,0x11,0x0c,0x18,0xb1,0x8e +,0x8a,0x8a,0x92,0x9d,0xae,0xac,0xa1,0x9c,0x96,0x96,0x8f,0x8d,0x8c,0x8c,0x8c,0x89,0x8a,0x8b,0x8c,0x89,0x87,0x84,0x83,0x84,0x87,0x8f,0x8e,0x8c,0x89,0x8d,0x9e,0xd8 +,0xae,0x92,0x8b,0x88,0x8c,0x90,0xa1,0xc3,0xce,0xb7,0xa2,0x9a,0x93,0x9b,0xad,0x39,0x30,0x49,0xac,0xa9,0x3f,0x28,0x1d,0x20,0x36,0x4d,0x44,0x24,0x19,0x16,0x17,0x15 +,0x15,0x21,0xe0,0xa8,0xae,0xaf,0x56,0x34,0x28,0x19,0x13,0x16,0x1f,0xce,0x98,0x90,0x98,0xc4,0x1f,0x1b,0xde,0x9a,0x8d,0x88,0x8a,0x8f,0x9c,0xa3,0xac,0xa9,0xa4,0x9c +,0x93,0x97,0x96,0x92,0x8e,0x8e,0x8e,0x96,0x9b,0x99,0x99,0x8f,0x8c,0x8b,0x8d,0x92,0x97,0x9f,0xa9,0xc9,0x2f,0x1e,0x21,0x2e,0x67,0xbf,0xdd,0x5b,0x3e,0x2b,0x1d,0x19 +,0x19,0x2e,0xc5,0xb8,0xef,0x27,0x1e,0x25,0x45,0xca,0xc4,0x3b,0x1f,0x1c,0x22,0x3c,0x4f,0x58,0x2d,0x21,0x1d,0x1a,0x1c,0x1c,0x31,0xb1,0xa1,0xa0,0xaa,0xd6,0x34,0x23 +,0x17,0x14,0x14,0x20,0x42,0xab,0xa1,0xbc,0x2a,0x17,0x1d,0x2d,0xc2,0xa8,0xa3,0xa8,0xba,0x5f,0x27,0x1c,0x17,0x1d,0x27,0x2b,0x28,0x24,0x32,0xc6,0xa9,0xc1,0x32,0x26 +,0x26,0x45,0xbb,0xa9,0xa3,0xa6,0xae,0xc1,0x52,0x39,0x25,0x1b,0x1a,0x1b,0x2d,0x66,0xcd,0x7c,0x50,0x46,0x2e,0x29,0x23,0x37,0xcb,0xa7,0xa8,0xbe,0x58,0xe5,0xbb,0xbe +,0xb7,0x59,0x3d,0x2f,0x39,0x4e,0x5b,0xc8,0x7b,0x48,0x2f,0x21,0x1b,0x1b,0x24,0xca,0x9c,0x9a,0x9b,0xa2,0xae,0x69,0x2a,0x1b,0x13,0x18,0x24,0xd1,0x9f,0x9e,0xad,0x3d +,0x2a,0x34,0xe9,0xbd,0xb2,0xad,0xa8,0xab,0xbc,0x48,0x28,0x20,0x1f,0x24,0x23,0x23,0x26,0x55,0xab,0xa4,0xab,0xee,0x3f,0x42,0x55,0x45,0xd8,0xb2,0xa4,0x9d,0xa6,0xb5 +,0x48,0x29,0x25,0x24,0x2a,0x2e,0x34,0x46,0xcb,0xd4,0xde,0x4d,0x3a,0x34,0x3d,0xcd,0xb2,0xb8,0xe8,0xce,0xb5,0xa6,0xa9,0xb8,0xda,0x5b,0x5d,0x45,0x3a,0x3b,0x48,0x5e +,0xe2,0x57,0x39,0x26,0x22,0x38,0xc2,0xa5,0xa0,0x9f,0xa0,0xaa,0xc3,0x2f,0x1f,0x21,0x30,0x3b,0x69,0xc6,0xba,0xbb,0xcd,0xca,0xc0,0xb4,0xae,0xa9,0xa0,0xa6,0xb0,0xd3 +,0x40,0x37,0x2e,0x29,0x2a,0x28,0x2a,0x60,0xb1,0xa4,0xad,0xdb,0x2c,0x3e,0xd8,0xbc,0xad,0xb4,0xa7,0xa3,0xa2,0xa7,0xab,0x4b,0x2a,0x22,0x21,0x32,0x47,0x78,0xc2,0xd3 +,0x3a,0x2d,0x2e,0x46,0x7d,0x41,0xe0,0xc0,0xce,0xb9,0xab,0xa3,0xa5,0xb9,0xe6,0x67,0x3d,0x4c,0x36,0x3b,0xc6,0xc0,0xc5,0x3d,0x2e,0x24,0x21,0x2e,0x42,0xbb,0xaa,0xaa +,0xa6,0x9c,0xa6,0xc1,0x2b,0x1b,0x1d,0x25,0x3c,0x6a,0xcb,0xc9,0xbd,0xcd,0xc2,0xcc,0xd3,0xba,0xb8,0xc1,0xc2,0xc3,0xb8,0xb7,0x62,0x2b,0x21,0x1c,0x1f,0x29,0x5d,0xb6 +,0xb3,0xb8,0x6a,0xcc,0xc7,0xed,0x56,0x3f,0x45,0xaf,0xb1,0xaf,0xaa,0xc6,0xb8,0xc8,0x4f,0x3c,0x28,0x27,0x35,0xe7,0x7a,0x3a,0x2b,0x2d,0x33,0xf3,0xae,0xb3,0xd0,0x30 +,0x2d,0xe0,0xa4,0x9d,0xa0,0xb2,0x3e,0x3c,0x54,0xe7,0xea,0x4a,0x33,0x2d,0x28,0x22,0x2c,0x4c,0xbb,0xc2,0xc8,0x52,0xc4,0xab,0xac,0xa6,0xce,0x39,0x2b,0x29,0x3a,0xd2 +,0xfb,0x3e,0x49,0x58,0xcd,0x5b,0x67,0xbb,0xa8,0xa3,0xaa,0xb2,0xde,0x5a,0x65,0x7b,0x3d,0x25,0x1d,0x1b,0x2a,0xd7,0xa2,0xaa,0x52,0x31,0x2e,0x47,0xcf,0xbe,0xcf,0xae +,0xaf,0xa8,0xb0,0xc4,0xb0,0xb8,0xbe,0x3d,0x27,0x2a,0x45,0xc5,0xb7,0x4e,0x2a,0x27,0x22,0x2d,0x3e,0x3a,0x38,0xc9,0xa7,0xa2,0x9b,0xa9,0xb2,0xb2,0xc4,0xc8,0x51,0x2e +,0x27,0x42,0xca,0xac,0xb7,0x30,0x1c,0x20,0x38,0xe4,0xba,0x71,0x60,0xbf,0xab,0x9f,0xa6,0xbe,0x38,0x1e,0x1f,0x2c,0x32,0x4b,0xc1,0xab,0xa7,0xbd,0x6a,0x3c,0xd6,0xa9 +,0xa9,0xe7,0x2c,0x49,0xb6,0xa7,0xb3,0x3a,0x2c,0x2b,0x29,0x35,0x48,0x39,0x3c,0x51,0xce,0xb3,0xb7,0x43,0x2b,0x41,0xb0,0x9e,0xa1,0x68,0x37,0xbe,0xa1,0x9e,0xbd,0x29 +,0x22,0x31,0xb7,0xcf,0x2d,0x1e,0x1e,0x2a,0xdb,0xc8,0x5c,0x51,0x3e,0x7a,0xb0,0xaf,0xba,0xb1,0xac,0xa7,0xad,0x76,0x3d,0x41,0xd0,0xb3,0x67,0x24,0x19,0x24,0xbe,0xac +,0xfb,0x2a,0x2e,0xbc,0x9f,0x9c,0xb2,0x2b,0x2c,0x6e,0xae,0xab,0xda,0x27,0x22,0x38,0xae,0xb0,0x3d,0x20,0x1f,0xb5,0x99,0x9e,0xc5,0x2e,0x4f,0xa6,0x9f,0xc6,0x22,0x1e +,0x27,0x5c,0xf9,0x44,0x5b,0xe1,0xed,0x42,0x41,0x2e,0x20,0x32,0xbd,0x9e,0x9c,0xb4,0xcd,0xaf,0x9d,0x9c,0xfb,0x1c,0x23,0x5a,0xa9,0xb5,0x25,0x1c,0x2c,0xbd,0xae,0x49 +,0x1c,0x13,0x1f,0xae,0x97,0x9b,0xb9,0x3a,0xc9,0x9e,0x9a,0xb1,0x25,0x1a,0x2e,0xa5,0xa1,0xbf,0x28,0x29,0x4e,0xb9,0xcc,0x23,0x1d,0x35,0xb1,0xa3,0xaf,0x4e,0x68,0xb9 +,0xb1,0xc0,0x2e,0x1f,0x1f,0x3f,0xaf,0xaa,0xca,0x74,0x4f,0xcb,0xa8,0xbd,0x2f,0x24,0xdb,0x9c,0x98,0xae,0x23,0x1f,0xbe,0xa4,0xad,0x28,0x18,0x1b,0xcc,0xb1,0xba,0x3f +,0x1e,0x32,0x4b,0xb8,0x9f,0xb3,0x3f,0x3d,0xb2,0x9a,0x9f,0xd6,0x36,0xc4,0x60,0xa6,0x3c,0x19,0x1f,0x40,0xbd,0xde,0x24,0x20,0x3c,0xc7,0xa2,0xc5,0xaa,0x61,0xba,0xaa +,0xaf,0xca,0x7e,0xa4,0xcf,0xbd,0xe3,0x26,0x1b,0x28,0xbe,0xa4,0xc8,0x1c,0x1a,0x35,0xa3,0x9a,0x9e,0x33,0x1d,0x2e,0xae,0x9d,0xc8,0x37,0x27,0x39,0xd0,0xbe,0xc5,0x3c +,0x37,0x3f,0xbe,0x6f,0xe2,0xd7,0xae,0xa6,0xb5,0xc4,0x28,0x18,0x29,0xaa,0x9f,0xcc,0x29,0x25,0x36,0xb2,0xa7,0xb6,0x25,0x2d,0x41,0x4f,0xbf,0xaf,0xaa,0xa9,0xb5,0xc3 +,0xbf,0x37,0x30,0xdc,0xb1,0xbc,0x67,0x29,0x2b,0xfb,0xa8,0xaf,0x2f,0x16,0x15,0x61,0xaf,0xa5,0xad,0x54,0x46,0x2c,0xbd,0xa9,0xb3,0xb7,0xba,0xc1,0x5c,0x39,0x46,0xbd +,0xba,0xb9,0x49,0x2e,0x1d,0x27,0xbc,0x9f,0xa3,0x48,0x35,0x2a,0x36,0xaf,0xac,0x3a,0x27,0x33,0xc3,0xaf,0xb6,0xad,0xbd,0x59,0x2f,0x2e,0x55,0xb9,0xaf,0xae,0xce,0x57 +,0x54,0x4b,0x33,0x45,0xaf,0xaa,0x3b,0x1d,0x23,0x40,0xb2,0xb9,0xbe,0x2e,0x2f,0x47,0xc5,0xb7,0xae,0xa6,0xbd,0x44,0x4a,0xb3,0xb6,0xdb,0x43,0xcd,0x4c,0x2c,0x2b,0x2d +,0xbd,0xb7,0x4a,0x29,0x23,0x3d,0xaf,0x9b,0xa4,0x63,0x2c,0x30,0xdc,0xac,0xa4,0xad,0x66,0x2c,0x35,0x4e,0xd5,0x75,0x70,0xec,0x3c,0x42,0x5d,0xcf,0xd7,0xb7,0xa7,0xca +,0x29,0x1d,0x2f,0xc9,0xa8,0xa9,0x61,0x1e,0x23,0xb7,0xa5,0x9f,0xbf,0x50,0x2c,0x22,0xe7,0xaa,0xaa,0xbe,0x4d,0x31,0x1f,0x29,0xee,0xc0,0xae,0xb0,0xbc,0x35,0x28,0xe3 +,0xa8,0xa7,0x4d,0x27,0x2d,0x37,0xc6,0xab,0xaa,0xe2,0x30,0x47,0xbd,0xae,0xb1,0xdd,0x32,0x34,0xc9,0xb1,0xb4,0x3e,0x24,0x2a,0x28,0x30,0xed,0xad,0xa1,0xaf,0xb4,0xb5 +,0x46,0x4b,0xc9,0xb3,0xca,0x3e,0x33,0x36,0x41,0x3d,0x43,0x34,0x28,0x34,0x44,0x43,0x40,0xd6,0xb9,0xd8,0xc0,0xac,0xac,0xbd,0xba,0xaa,0xb6,0x56,0x49,0x39,0xba,0xa3 +,0xa0,0xa8,0x2f,0x1a,0x23,0x31,0x6b,0xd4,0x45,0x3e,0x2e,0x2c,0x45,0xda,0xe7,0x50,0x4c,0xbf,0xbc,0xcc,0xdc,0xb3,0xae,0xb1,0xab,0xdc,0x38,0x45,0x74,0x5e,0x3d,0xe2 +,0xdf,0xf8,0xca,0xdc,0x3b,0x23,0x29,0x3c,0x56,0x69,0x3b,0x4e,0xd3,0xbd,0xa8,0xaf,0x53,0x3c,0xc7,0xa9,0xa5,0xae,0xca,0x4e,0x63,0xd7,0xb6,0xc8,0x33,0x28,0x2a,0x3d +,0x3f,0x34,0x4c,0xcf,0x5e,0xd0,0x5b,0x2c,0x28,0x39,0xb9,0xaa,0xa6,0xa9,0xc7,0xd3,0xcd,0xb2,0xbb,0x47,0x4f,0x5c,0x52,0x58,0xcc,0xbb,0xc0,0xe7,0x49,0x2f,0x24,0x26 +,0x39,0x4e,0xfd,0x41,0x3b,0xf4,0x62,0xbe,0xaf,0xbc,0x3d,0x36,0xbf,0xab,0xaf,0xb6,0xb3,0xcb,0xdf,0xc7,0xdc,0x46,0x67,0xcf,0xbb,0x61,0x2e,0x32,0x42,0xef,0xdf,0xce +,0x4d,0x22,0x22,0x33,0xca,0xa9,0xad,0xb1,0xc3,0xcc,0xc3,0xb9,0xd4,0xeb,0xd0,0xc6,0xde,0x3d,0x5d,0xc5,0xdc,0x43,0x43,0x2c,0x27,0x3f,0xb6,0xcd,0x39,0x3b,0x4b,0xd1 +,0xc9,0xad,0xaf,0x40,0x2d,0x34,0xbe,0xbd,0x7c,0xd2,0xc6,0xb1,0xc6,0x72,0x38,0x30,0x5a,0xb7,0xa3,0xb3,0x39,0x33,0x73,0xb5,0xb5,0xc5,0x3b,0x20,0x1e,0x33,0xd3,0xaf +,0xab,0xb7,0x3f,0x3d,0xe5,0xde,0x58,0x4b,0xe5,0x5f,0x53,0xd1,0x9f,0x9e,0xaa,0xe8,0x2c,0x28,0x2e,0xbf,0xaa,0x57,0x28,0x23,0x2d,0x6d,0xd3,0xbd,0x55,0x2a,0x2b,0x3a +,0xbd,0xa9,0xae,0xb9,0xbf,0xbf,0xc6,0xb4,0xd5,0x45,0x4c,0x4a,0x3f,0x3f,0xc9,0xae,0xb2,0x4d,0x2f,0x2b,0x34,0x37,0x43,0xcf,0xc2,0xbc,0xb6,0xab,0xb4,0xdd,0xeb,0x44 +,0x42,0x3e,0x46,0x5f,0xeb,0xb9,0xb0,0xd1,0x3a,0x3b,0x33,0x4a,0xc2,0xb5,0xb7,0x3c,0x3d,0xbd,0xad,0xcb,0x3b,0x33,0x2e,0x3b,0x43,0xd2,0xd5,0x4f,0x3e,0x6f,0xc4,0xc0 +,0xcf,0xda,0xcd,0x3e,0x59,0xd0,0xbc,0xb8,0xb8,0xbf,0xbc,0xda,0x43,0x3d,0x39,0x31,0x27,0x32,0xf9,0xb7,0xac,0xb6,0x49,0x39,0x4f,0xc9,0xdf,0xca,0x5f,0x3d,0x60,0xb7 +,0xa9,0xa9,0xbe,0x5f,0x3d,0x3a,0xd9,0xbe,0xc8,0x48,0x38,0x42,0x46,0x3c,0x64,0x55,0x44,0x2e,0x33,0x5b,0xd1,0xb6,0xae,0xb4,0xb6,0xc9,0xd7,0x4e,0x46,0x3f,0x40,0x48 +,0x41,0x46,0x3e,0x68,0xc9,0xb0,0xbf,0x6d,0x38,0x2f,0x35,0xd2,0xa9,0x9f,0xa2,0xcd,0x2f,0x37,0x48,0x40,0x31,0x38,0x36,0x3b,0xbd,0xaa,0xa3,0xac,0xcc,0x4b,0x2e,0x2f +,0xfd,0xce,0xd9,0x73,0xe2,0xc5,0x59,0x49,0xc9,0x5e,0x3a,0x35,0x38,0x3a,0xd1,0xaf,0xa9,0xb5,0xc4,0xcc,0x4b,0x38,0x2e,0x34,0x39,0xeb,0xbe,0xc4,0xb3,0xcd,0x52,0xce +,0xcc,0xda,0x2e,0x1f,0x21,0x61,0xa8,0x9e,0xae,0x3d,0x37,0x40,0x66,0xcd,0xd6,0xea,0x4f,0xd5,0xa8,0xa0,0xaa,0xc2,0x3f,0x26,0x21,0x2a,0x44,0xd1,0xc3,0xc5,0xad,0xc1 +,0x58,0xd9,0x69,0x3f,0x37,0x32,0x3b,0x60,0xb7,0xa8,0xbe,0x56,0xbf,0xb6,0xd8,0x3c,0x2a,0x2e,0x3e,0xaf,0xac,0xb7,0x5f,0x30,0x4f,0x57,0x49,0x3a,0x27,0x22,0x38,0xb4 +,0x9a,0x9e,0xbc,0xdd,0x49,0x4f,0x37,0x27,0x2d,0x44,0x69,0xda,0xb0,0xaf,0xaa,0xab,0xd2,0x2d,0x2c,0x42,0xd4,0xb3,0xb4,0xb0,0xd6,0x41,0x63,0x5f,0x36,0x24,0x1e,0x2d +,0xcf,0xa6,0x9f,0xb0,0x3b,0xee,0xa7,0xac,0xcd,0x2e,0x22,0x2e,0xda,0xb4,0xb0,0x6c,0x4f,0xc2,0xbb,0x60,0x29,0x22,0x26,0x3b,0xbd,0xa3,0xa5,0xb8,0xbe,0x69,0x2f,0x2a +,0x2d,0x27,0x4c,0xf8,0xbf,0xad,0xa8,0xa2,0xa4,0xb2,0x36,0x1c,0x20,0x6f,0xbe,0xb8,0xed,0x39,0x5a,0xaa,0xa3,0xba,0x2a,0x1a,0x1f,0x6b,0xa9,0x9c,0xa2,0x49,0x2f,0xcb +,0xbd,0xee,0x2c,0x25,0x31,0x71,0xac,0xaf,0xce,0xb7,0xa7,0xad,0x3b,0x20,0x1d,0x28,0x4b,0x66,0xb9,0xb4,0xaf,0xb0,0xab,0xce,0x2e,0x22,0x25,0x2f,0x4f,0xb9,0xc9,0xb1 +,0xa1,0x9c,0xb1,0x25,0x16,0x1a,0x41,0xaa,0xa2,0xa8,0xcc,0x48,0xa9,0x9d,0xab,0x36,0x17,0x16,0x28,0xce,0xb5,0xac,0xb8,0xc5,0xb7,0xb7,0x75,0x32,0x2e,0x40,0x43,0xcb +,0xa5,0xad,0xbf,0xb3,0xae,0xe5,0x23,0x19,0x21,0x38,0x52,0xc5,0xb9,0xae,0xa4,0x9c,0xa6,0x2f,0x1b,0x1b,0x2d,0x3a,0x37,0x60,0xd5,0xa8,0x9f,0x9b,0xa5,0x26,0x13,0x19 +,0xce,0x9f,0x9e,0xb8,0x40,0x52,0xab,0xa6,0x3d,0x1f,0x1b,0x28,0x46,0xc1,0xac,0xab,0xa9,0xa5,0xa8,0xce,0x27,0x1c,0x2c,0x5e,0x5c,0xf2,0xca,0xbf,0xb1,0xa1,0xad,0x46 +,0x21,0x1e,0x38,0x4f,0x68,0xc7,0xb5,0xaa,0xa4,0xa5,0xd5,0x25,0x1a,0x2e,0xd9,0x4b,0x33,0x2b,0xe4,0x9c,0x97,0xab,0x38,0x18,0x17,0x2e,0xb4,0xa3,0xa9,0xc5,0x5d,0xc1 +,0xa9,0xaa,0x30,0x1c,0x25,0x58,0xb2,0xbe,0xbf,0xb6,0xa5,0xac,0xd5,0x2b,0x1b,0x20,0x2e,0xe9,0xc7,0xbb,0xac,0xa1,0xa3,0xa0,0xbd,0x22,0x1d,0x24,0x39,0x41,0x33,0x33 +,0xbc,0x99,0x96,0xa3,0x2d,0x16,0x20,0xbc,0xa7,0xe4,0x2e,0x27,0xf8,0xa1,0x9a,0xaf,0x1e,0x16,0x1c,0x59,0xa8,0xaf,0xbb,0xbc,0xaf,0xa0,0xaa,0x39,0x1d,0x1c,0x2b,0x4d +,0xcf,0xc9,0xb2,0xa6,0xa1,0xa1,0xf8,0x21,0x1b,0x34,0x6f,0x4f,0x4d,0x49,0xa8,0xa1,0xa0,0xb1,0x34,0x1c,0x1d,0x2e,0x49,0xfc,0x39,0xe5,0xaa,0x96,0x93,0xaa,0x23,0x16 +,0x22,0x3f,0xcf,0x3c,0x2e,0x4b,0xb6,0x9f,0x9e,0xcd,0x28,0x1f,0x23,0xde,0xbb,0xbb,0xba,0xc0,0xa8,0x9f,0xba,0x22,0x15,0x1c,0x31,0xe6,0xd2,0xb9,0xa1,0x9c,0x9c,0xa0 +,0x6d,0x29,0x26,0x1f,0x2c,0x26,0x47,0xb0,0xa7,0x9d,0x9e,0xc5,0x23,0x1e,0x28,0xcd,0x43,0x26,0x28,0xd5,0x9b,0x91,0x98,0xd8,0x26,0x1c,0x2a,0x4c,0x4d,0x46,0x3a,0xf9 +,0xb8,0xa3,0xad,0xfa,0x2b,0x24,0x2f,0xea,0xb0,0xca,0x62,0x30,0xef,0xa7,0xab,0xad,0x2d,0x20,0x35,0xb4,0xa4,0xb3,0x4a,0x1a,0x26,0xee,0xa8,0xbb,0x37,0x32,0x54,0xcc +,0xa5,0xba,0x15,0xae,0x83,0x8e,0x00,0xab,0x80,0xcf,0x90,0x5b,0x21,0x0f,0x0b,0x0f,0x10,0x21,0x00,0x07,0x02,0x00,0x03,0x00,0x04,0x00,0x00,0x03,0x05,0x05,0x04,0x03 +,0x0d,0x0f,0x14,0x27,0xbd,0xa4,0x8f,0x87,0x8c,0x8b,0x81,0x80,0x87,0x83,0x80,0x80,0x80,0x81,0x80,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x82,0x82,0x87,0x89,0x85,0x8d +,0x8e,0x97,0x9a,0xa2,0xad,0xb7,0x2e,0x29,0x1b,0x1e,0x0b,0x09,0x03,0x02,0x04,0x02,0x03,0x00,0x01,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00 +,0x01,0x01,0x02,0x00,0x01,0x02,0x04,0x06,0x06,0x13,0x1b,0x2f,0x2d,0x62,0x9f,0x98,0x8c,0x89,0x86,0x85,0x84,0x84,0x82,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x81,0x81,0x84,0x86,0x8a,0x8b,0x8d,0x98,0x9e,0xbe,0xce,0x2a +,0x1b,0x10,0x07,0x05,0x07,0x04,0x02,0x01,0x01,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x07,0x07,0x05,0x06,0x07,0x0d,0x0e,0x0e,0x14,0x19,0x1f,0x24,0x30,0x5a,0xbe,0x9f,0xa6,0x99,0x8f,0x8e,0x8a,0x8a,0x88,0x87,0x86 +,0x85,0x83,0x83,0x82,0x84,0x82,0x81,0x81,0x82,0x83,0x82,0x81,0x81,0x81,0x82,0x83,0x81,0x82,0x80,0x82,0x82,0x82,0x83,0x82,0x83,0x83,0x84,0x85,0x86,0x83,0x84,0x87 +,0x8b,0x8d,0x8a,0x8a,0x8c,0x8f,0x91,0x8e,0x8c,0x8c,0x8e,0x97,0x94,0x98,0x92,0x8e,0x92,0x95,0x9a,0x93,0x93,0x91,0x98,0x98,0x99,0x9d,0x9a,0xa1,0xa2,0x9d,0x99,0x9e +,0x9a,0xab,0xb5,0xc0,0xe3,0xb9,0x34,0x2c,0x1b,0x18,0x12,0x13,0x0e,0x08,0x06,0x04,0x03,0x03,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x05,0x07,0x0a +,0x0b,0x0d,0x11,0x18,0x20,0x2f,0x40,0xb6,0xa4,0x9c,0x8f,0x8a,0x87,0x83,0x82,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x82,0x84,0x85,0x86,0x86,0x87,0x8b,0x8f,0x94,0x9a,0x9c,0xaa +,0xe0,0x46,0x2a,0x1e,0x18,0x10,0x0d,0x0c,0x0b,0x0a,0x06,0x03,0x02,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01 +,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x03,0x02,0x04,0x05,0x06,0x09,0x06,0x07,0x07,0x08,0x0c,0x0f,0x11,0x16,0x19,0x1b,0x1e,0x1f,0x20,0x24,0x38,0x64,0xbd,0xbd,0xbb +,0xab,0x9f,0x9c,0x97,0x99,0x9c,0x99,0x98,0x90,0x8d,0x8e,0x8d,0x8d,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0x8d,0x8a,0x8b,0x8c,0x8c,0x8d,0x8c,0x8d,0x91,0x95,0x98,0x94,0x90 +,0x91,0x96,0x9a,0x9e,0x9f,0x9c,0x9d,0xaa,0xbc,0xcc,0xc7,0xb1,0xb6,0xdc,0x64,0x4b,0x4d,0x46,0x28,0x1e,0x1f,0x26,0x32,0x2f,0x24,0x1f,0x20,0x22,0x27,0x24,0x19,0x18 +,0x1a,0x21,0x2f,0x2b,0x25,0x24,0x26,0x2d,0x2c,0x29,0x2e,0x2d,0x42,0xc0,0xbe,0xde,0xe1,0xb8,0xa4,0xa0,0xa4,0xad,0xaa,0x9f,0x97,0x91,0x93,0x93,0x95,0x96,0x92,0x91 +,0x96,0x96,0x93,0x8e,0x8e,0x91,0x96,0x94,0x90,0x8f,0x90,0x96,0x9b,0x9e,0x9b,0x9a,0x9b,0xa6,0xb6,0xb3,0xaf,0xae,0xd0,0x35,0x2e,0x33,0x48,0x4f,0x4e,0x30,0x28,0x2f +,0x33,0x2b,0x24,0x1c,0x20,0x38,0xce,0xf0,0x33,0x27,0x29,0x3b,0x56,0x77,0x32,0x28,0x2f,0x6b,0xc0,0xd5,0x3c,0x31,0x3b,0x7c,0x5f,0x32,0x26,0x27,0x3c,0xc1,0xbc,0x40 +,0x2e,0x2b,0x48,0xc7,0x45,0x2d,0x22,0x2e,0xc5,0xae,0xc8,0x2e,0x25,0x31,0xe9,0xdf,0x39,0x25,0x28,0x4d,0xb5,0xc0,0x39,0x28,0x30,0xda,0xbd,0x4d,0x21,0x1e,0x39,0xac +,0xa3,0xbf,0x2d,0x27,0x36,0xd6,0xc0,0x32,0x20,0x2a,0xcb,0xa5,0xb5,0x30,0x24,0x2e,0xc2,0xb0,0x46,0x20,0x20,0x46,0xa7,0xa6,0x5f,0x24,0x21,0x53,0xaf,0xba,0x29,0x1e +,0x2d,0xb2,0xa0,0xb1,0x36,0x27,0x39,0xc3,0xbb,0x30,0x1e,0x28,0xc1,0x9e,0xa4,0x3b,0x20,0x28,0x5b,0xaf,0xe9,0x27,0x20,0x30,0xab,0xa2,0xb8,0x2c,0x25,0x34,0xb9,0xb6 +,0x38,0x22,0x27,0xbe,0xa0,0xa4,0x56,0x27,0x2c,0x53,0xb5,0xd6,0x29,0x20,0x3a,0xa7,0x9f,0xb0,0x2e,0x21,0x32,0xbd,0xaf,0x4c,0x23,0x2f,0xba,0xa2,0xa6,0x40,0x24,0x2b +,0xc9,0xaa,0xc3,0x26,0x1d,0x3e,0xa2,0x9a,0xaf,0x2a,0x1f,0x39,0xaf,0xae,0x4c,0x1f,0x2c,0xb3,0x9b,0xa0,0x3b,0x1d,0x27,0xc1,0xa4,0xb9,0x25,0x1f,0x4c,0x9e,0x9a,0xbe +,0x21,0x1f,0x52,0xa4,0xa3,0x3a,0x1d,0x2c,0xaf,0x99,0xa7,0x2d,0x1e,0x2a,0xb9,0xa4,0xe6,0x20,0x22,0xbc,0x99,0x9d,0x4e,0x1c,0x22,0xc5,0xa2,0xab,0x2d,0x1d,0x34,0xa7 +,0x9a,0xac,0x24,0x1c,0x3d,0xaa,0xa1,0x45,0x1d,0x25,0xb6,0x98,0x9f,0x4e,0x1e,0x25,0xc4,0xa5,0xb7,0x24,0x1b,0x38,0x9e,0x97,0xae,0x25,0x1d,0x37,0xaa,0xa7,0x58,0x22 +,0x28,0xaf,0x9c,0xa2,0x3e,0x1f,0x28,0xc3,0xa3,0xbb,0x24,0x1b,0x4c,0x9d,0x98,0xb0,0x20,0x1d,0x34,0xab,0xa6,0x43,0x1e,0x25,0xad,0x97,0x9a,0x4a,0x1a,0x1f,0xcf,0xa2 +,0xb3,0x24,0x1c,0x69,0x9d,0x96,0xb8,0x1e,0x1a,0x32,0xa4,0x9e,0x4f,0x18,0x22,0xac,0x91,0x98,0x3c,0x18,0x1c,0xcf,0xa2,0xb6,0x1f,0x1c,0x78,0x98,0x94,0xbb,0x1a,0x17 +,0x39,0xa4,0x9e,0x36,0x1a,0x2d,0xa3,0x91,0x9c,0x2a,0x15,0x1f,0xbf,0x9d,0xc0,0x1b,0x20,0xcb,0x97,0x95,0xc9,0x1b,0x19,0x3b,0xa5,0xa5,0x2a,0x1a,0x38,0x9c,0x8f,0x9c +,0x27,0x16,0x24,0xc5,0xa0,0xda,0x1c,0x1e,0xcc,0x9b,0x97,0xbe,0x1a,0x1f,0x43,0xa2,0xa5,0x2e,0x1f,0x49,0xa0,0x95,0xa2,0x21,0x19,0x1f,0xcb,0xa1,0x5c,0x1e,0x25,0xbe +,0x97,0x93,0xce,0x1c,0x1a,0x39,0xa3,0xa7,0x2e,0x22,0x4d,0xab,0x96,0xa6,0x26,0x1c,0x20,0xbe,0xa1,0x40,0x1c,0x24,0xc9,0x94,0x93,0xe3,0x1f,0x1e,0x3f,0xa3,0xae,0x2a +,0x20,0x30,0xab,0x94,0xa8,0x28,0x1a,0x24,0xb1,0xa0,0x39,0x1f,0x2d,0xb8,0x93,0x9b,0x3c,0x1f,0x1f,0xe8,0x9e,0xba,0x20,0x1f,0x2f,0x9e,0x92,0xaf,0x2a,0x1c,0x28,0xad +,0xb0,0x24,0x23,0x33,0xa4,0x90,0x9e,0x31,0x1f,0x26,0xc7,0x9f,0x3f,0x1c,0x20,0x3d,0x99,0x93,0xc3,0x25,0x26,0x39,0xa3,0xb4,0x1d,0x23,0x2f,0xaa,0x92,0xa8,0x2c,0x2b +,0x2c,0xb2,0xa6,0x24,0x1b,0x29,0xc3,0x93,0x95,0x3c,0x26,0x25,0x3b,0xa1,0x57,0x1d,0x25,0x44,0xa2,0x94,0xad,0x2d,0x39,0x38,0xad,0xb4,0x1c,0x1c,0x2f,0xb6,0x94,0x9b +,0x33,0x2c,0x2f,0xd8,0xa3,0x2e,0x17,0x26,0x47,0xa0,0x94,0xb7,0x41,0x3e,0x49,0xab,0xcf,0x1d,0x1f,0x3c,0xaf,0x99,0xad,0x2b,0x2a,0x3b,0xad,0xac,0x28,0x18,0x26,0xc3 +,0x99,0x93,0xb5,0x37,0x2d,0x4e,0xaf,0x3f,0x18,0x1c,0x4e,0xa4,0x96,0xad,0x2f,0x2e,0xec,0xa9,0xbb,0x20,0x17,0x2b,0xb0,0x94,0x98,0xcd,0x2f,0x31,0xbd,0xae,0x31,0x18 +,0x1d,0x39,0xaa,0x9c,0xac,0x72,0xe5,0xb6,0xae,0x7b,0x1b,0x1c,0x3f,0xac,0x9b,0xac,0x38,0x31,0x51,0xb6,0xad,0x2a,0x1a,0x2a,0x42,0xa7,0x9c,0xb9,0xd5,0xe0,0xd4,0xac +,0x3c,0x16,0x21,0x3a,0xac,0x9c,0xba,0xd7,0xe1,0x66,0xae,0xb3,0x1e,0x1d,0x22,0x5e,0x9c,0xa1,0xba,0xdf,0xe3,0xd2,0xae,0x39,0x22,0x2a,0x2e,0xbd,0xa6,0xb8,0x6a,0xc1 +,0xbf,0xa8,0xb9,0x1a,0x1b,0x2a,0xce,0xa2,0xa8,0xce,0xba,0xbb,0xbd,0xab,0x2c,0x19,0x22,0x3d,0xb8,0xa4,0xc5,0xf7,0xad,0xae,0xb0,0x47,0x1c,0x1c,0x33,0xc7,0xaa,0xa8 +,0x65,0xb3,0xab,0xae,0xb4,0x25,0x19,0x1d,0x3b,0xdf,0xab,0xd6,0xc0,0xa2,0xa6,0xb2,0x77,0x1d,0x23,0x2e,0x4a,0xb5,0xbe,0xd4,0xbe,0xa1,0xac,0xb6,0x20,0x15,0x25,0xc3 +,0xb4,0xa5,0x34,0x66,0xaf,0xae,0xb0,0x3f,0x1c,0x1d,0xd9,0xec,0xb3,0xbc,0xad,0xa9,0xa1,0xc6,0x6b,0x22,0x18,0x2a,0x2e,0xb3,0xb0,0x66,0xcb,0xa6,0xac,0xbd,0xaf,0x29 +,0x36,0x4d,0x35,0xc4,0xb8,0xd1,0xcc,0xaf,0xd0,0x7c,0x24,0x28,0x42,0xde,0xec,0x4e,0xbe,0xb5,0xa1,0xa8,0xb6,0x45,0x1e,0x2b,0xd2,0x43,0xd3,0xc2,0xd7,0xa9,0xdc,0xb7 +,0xcf,0x2f,0x25,0x3f,0xc0,0x2c,0xaf,0x4f,0xb0,0x99,0xbd,0xb6,0x38,0x26,0x3a,0x4b,0x3c,0x3f,0xcf,0xe8,0xac,0xb3,0x4d,0xd3,0x2b,0x26,0xc3,0x39,0x34,0xb2,0x48,0xa8 +,0x9e,0xab,0xbe,0x4e,0x3f,0x3e,0xb5,0x29,0x3a,0x50,0x3f,0xa7,0xb2,0x3a,0x6b,0x27,0x21,0xb6,0x2a,0x30,0x65,0x5f,0xaf,0xa7,0xde,0x36,0x46,0x27,0x47,0xbc,0x43,0xc3 +,0xb4,0xb1,0x9b,0xa0,0xc3,0xb7,0x34,0x3b,0xbf,0x3d,0x3e,0x57,0x56,0xbe,0xb1,0x2c,0x3a,0x2f,0x1f,0x42,0x3a,0x22,0x4c,0x5f,0xbc,0xa6,0xbe,0x4a,0x5e,0x47,0x49,0xa6 +,0x35,0xe8,0xaa,0xbb,0xa2,0xa1,0x48,0xc3,0x62,0x39,0xae,0x3e,0x30,0x5e,0xaf,0xce,0xa7,0x59,0x33,0xc1,0x22,0x3b,0xd7,0x20,0x35,0xc7,0x39,0xa5,0xb6,0x3b,0xc9,0x4a +,0x37,0x6e,0x42,0x26,0xae,0xaa,0xbd,0xa2,0x3e,0x46,0xaa,0x2f,0xd5,0xba,0x21,0x44,0x6d,0x49,0xb5,0x3e,0x28,0x54,0x66,0x45,0xbc,0x36,0x2b,0xaf,0xda,0xbe,0xa0,0x4b +,0xb2,0xbf,0x33,0xb7,0x5c,0x28,0xdc,0xaf,0xcd,0xa4,0xbb,0x37,0xad,0x46,0x2f,0xa5,0x2a,0x2c,0xb6,0x31,0xb7,0xc9,0x32,0xf0,0xbf,0x32,0x4e,0x3d,0x1b,0x3f,0xc8,0x3b +,0xa9,0xc2,0x2e,0xa5,0x37,0xee,0xad,0x31,0x67,0xb1,0xb3,0xb2,0xa9,0x36,0x3b,0xd0,0x2e,0xc2,0xb8,0x1e,0xb5,0xc5,0x55,0xa3,0x3b,0x59,0xb3,0xce,0xba,0xba,0x2a,0x2f +,0xc5,0xc8,0xd8,0xa4,0x34,0x4d,0xad,0x22,0xb0,0x3f,0x22,0xad,0xc7,0xcc,0xad,0x37,0x43,0xb6,0xd9,0x67,0xc7,0x27,0x22,0xb5,0x25,0x5f,0xb7,0x1f,0xb6,0xe0,0x35,0xb3 +,0x36,0x28,0xbc,0xbf,0xbf,0xaa,0x61,0x37,0xaf,0x4d,0x38,0xa7,0x24,0xba,0xa1,0x4a,0xa0,0xca,0x2f,0xab,0x60,0x51,0xa8,0x4f,0x3f,0xbb,0x62,0x33,0xa6,0x3b,0x66,0xa5 +,0x2f,0xbf,0xd8,0x1c,0xe1,0xc9,0x34,0xa7,0x6e,0x39,0xc0,0x38,0x36,0xb2,0x30,0x2d,0xab,0x3a,0x4b,0xaf,0x21,0x3d,0xca,0x29,0xaa,0x7d,0x27,0xb7,0x49,0x3a,0xbc,0x3f +,0x2f,0xc7,0x59,0x72,0xaa,0x33,0x48,0xa5,0x3f,0xa8,0xa0,0x32,0xb1,0xc4,0x45,0xa9,0xd5,0x44,0xa8,0xce,0x3a,0xb4,0x3e,0x32,0xac,0xb9,0xbb,0xaa,0x1e,0x60,0xbb,0x2b +,0xb7,0x4a,0x34,0xca,0xbe,0x3c,0xbf,0x37,0x28,0xbb,0x47,0x2e,0xb4,0x2b,0x28,0xab,0x30,0xbf,0xd6,0x28,0xaa,0xb8,0x38,0xbe,0x47,0x27,0xea,0xd8,0x4f,0xb9,0x3c,0x32 +,0xa7,0x33,0x33,0xa8,0x2c,0xb8,0xa4,0x46,0xb2,0x46,0x39,0xa8,0xb3,0x52,0xaf,0xc9,0x2c,0xab,0xb6,0xd4,0xa8,0x39,0xcd,0xa8,0x26,0xca,0xb9,0x27,0xb2,0xbc,0xd0,0xb4 +,0x55,0x46,0xc3,0x46,0x2b,0xb5,0x31,0x21,0xb6,0x2e,0x4f,0x6b,0x20,0xd3,0x5f,0x30,0xac,0xcd,0x26,0x3d,0x41,0x32,0xbe,0xed,0x4b,0xa6,0x33,0x4b,0xaf,0x20,0x3b,0xb7 +,0x4d,0xaa,0xd9,0x30,0xbf,0x52,0xe6,0xaa,0xdb,0x29,0xb8,0xbc,0xbf,0x9e,0xd0,0xbe,0xae,0x2e,0xa5,0xb9,0x1f,0xda,0x72,0xbc,0xad,0xc8,0xd5,0xb7,0xdc,0xe5,0xa8,0x2f +,0x25,0xbb,0x54,0xae,0xa7,0x2e,0xef,0x33,0x29,0xab,0x33,0x2b,0x4e,0x33,0x3a,0x3f,0x5b,0x38,0xd1,0x39,0xe0,0xb2,0x1e,0x31,0xc1,0x3f,0xa7,0xbd,0x47,0xcc,0x24,0x48 +,0xc8,0x39,0x33,0xdf,0x5b,0x4b,0xae,0xc7,0xc7,0xc1,0x3e,0xa7,0xae,0x2c,0xaf,0xd9,0xe6,0xac,0xec,0xbf,0xe6,0x3d,0xb4,0xac,0x7d,0x37,0x6b,0x31,0x54,0xa1,0xe8,0xaf +,0x3d,0x34,0xa9,0x3c,0x7a,0xb8,0x3e,0x39,0xdd,0xd5,0xda,0x43,0x39,0xbe,0xae,0x2f,0x34,0x48,0x1d,0xc2,0xb6,0xc2,0xab,0x2b,0xe9,0xb6,0x3c,0xe6,0x42,0x2c,0x37,0xbb +,0xb1,0xe1,0x6f,0x28,0xcf,0xbc,0x2a,0xb0,0x29,0x28,0xad,0xbf,0xac,0x73,0x2a,0xb9,0xb2,0xbd,0xbe,0x3e,0x28,0x32,0xa4,0xae,0xae,0x3d,0x25,0xb7,0x3b,0x45,0xaf,0x22 +,0x53,0xb9,0xc5,0xa2,0x32,0x4b,0xc5,0xae,0xb0,0xc8,0x3f,0x1e,0xee,0xae,0xb9,0xb7,0x28,0x3e,0xaf,0x36,0xac,0x3e,0x1f,0xd8,0xee,0xa1,0xaa,0x34,0x4b,0xde,0xc5,0xe3 +,0xcb,0x2f,0x28,0xab,0xb8,0xaf,0x58,0x18,0xdc,0x4d,0xc0,0xa0,0x2a,0x2b,0x33,0xd1,0xa5,0xaf,0x47,0x48,0xb3,0xe0,0xc9,0xd3,0x1d,0x39,0xc3,0xd9,0xaa,0x2d,0x24,0xdb +,0x3b,0xb2,0xac,0x29,0x39,0x4f,0xab,0xa3,0xc2,0x34,0x43,0xae,0x66,0xa9,0x4f,0x1c,0x3d,0x3d,0xae,0xa8,0x28,0x3e,0xe8,0xf4,0xa9,0x61,0x2a,0x2b,0xb9,0xa4,0x9f,0xb2 +,0x24,0x47,0x55,0xc6,0x9e,0x32,0x2a,0x3d,0x4f,0xa6,0xdf,0x2e,0x3f,0x42,0xbd,0xa9,0xca,0x29,0x2d,0xc2,0xb4,0x9f,0x4c,0x23,0xcf,0x3f,0xab,0xb0,0x24,0x28,0x2b,0xbc +,0xa5,0x6f,0x2a,0x28,0x49,0xae,0xa5,0xc0,0x27,0x48,0xc9,0xad,0xa3,0x24,0x33,0x5f,0xef,0x9c,0xbe,0x24,0x1c,0x26,0xae,0xa5,0xbd,0x28,0x2d,0x4e,0xb1,0x9d,0x64,0x29 +,0x56,0xc6,0x9e,0xae,0x21,0x43,0x34,0xad,0x9c,0x5c,0x29,0x1f,0x48,0xb7,0xa5,0x4f,0x1f,0x45,0x59,0x9f,0x9b,0x2e,0x2a,0x32,0x5f,0x9b,0xca,0x31,0x28,0x39,0xa1,0xa5 +,0xee,0x17,0x26,0x4d,0xa1,0x9c,0x27,0x25,0x36,0x49,0x9a,0xa3,0x2c,0x29,0x2c,0xc1,0xa2,0xbf,0x2a,0x2c,0x55,0xac,0xa4,0x7b,0x18,0x29,0x3b,0xa1,0x9f,0x23,0x2b,0x2c +,0xae,0x95,0xad,0x21,0x25,0x4c,0xa7,0x9e,0xd7,0x1c,0x23,0xeb,0xaf,0x9c,0x23,0x19,0x34,0xe9,0x98,0xae,0x2c,0x1f,0x3b,0xa1,0x92,0xaa,0x1e,0x1d,0x3e,0xa2,0x9a,0x5f +,0x16,0x2e,0x50,0x9d,0xa0,0x1c,0x1d,0x34,0xae,0x97,0xae,0x26,0x1f,0xee,0xa4,0x9a,0xc2,0x17,0x31,0xcf,0xa2,0x9d,0x27,0x18,0x26,0xd0,0x95,0xa3,0x19,0x1b,0x3d,0xa3 +,0x96,0xb1,0x1b,0x27,0xbd,0x9e,0x95,0x23,0x13,0x28,0xbd,0x9b,0x9e,0x1d,0x15,0x2f,0xd2,0x95,0xc5,0x1c,0x27,0xef,0xa9,0x95,0xc7,0x19,0x3d,0xbf,0x98,0x97,0x1e,0x17 +,0x3c,0x52,0x9d,0xb7,0x16,0x22,0xe3,0xa6,0x97,0x3d,0x13,0x39,0xb6,0x9e,0x94,0x28,0x1d,0xc4,0xd7,0x97,0xa4,0x16,0x1f,0x5f,0xd3,0x9c,0x4e,0x0f,0x31,0xbe,0x9c,0x8f +,0x2c,0x17,0x65,0x3d,0xa6,0x9b,0x17,0x27,0xbb,0xc4,0x95,0xbd,0x11,0x3d,0xb6,0x48,0x9b,0x27,0x13,0xb9,0xc3,0x9f,0x96,0x1b,0x25,0xa9,0x40,0x9f,0xbf,0x0f,0x39,0xaf +,0xb3,0x95,0x45,0x14,0xd3,0x43,0xda,0xa4,0x17,0x1c,0xaa,0xb4,0x99,0x9f,0x19,0x40,0xaf,0xf1,0x98,0x49,0x15,0x41,0x66,0xad,0x9a,0x2e,0x1d,0xb8,0x2c,0xd1,0xb1,0x14 +,0x39,0xaf,0xc4,0x93,0xa8,0x1e,0xb7,0xc7,0x36,0xa2,0x29,0x1b,0xc4,0x53,0xb1,0x9c,0x20,0x38,0xa8,0x2b,0xa4,0xea,0x16,0x50,0xba,0xcc,0x96,0xc9,0x24,0xa5,0x3a,0x54 +,0xa6,0x17,0x1a,0xbb,0x6d,0x9b,0xa1,0x1c,0xc8,0xc9,0x31,0xa0,0x59,0x1b,0xcf,0xfb,0xbd,0x97,0x48,0x42,0xaa,0x31,0xbe,0xb0,0x13,0x26,0x47,0x3b,0x9c,0xb4,0x2f,0xae +,0xdb,0x42,0xa2,0x26,0x28,0xb9,0x3d,0xa4,0x9b,0x29,0xc3,0xad,0x2b,0xae,0x41,0x1b,0xda,0x47,0x42,0x9f,0x33,0x36,0xa5,0x6b,0xba,0xa5,0x26,0x33,0xcb,0x29,0xbe,0xe3 +,0x2a,0xbe,0xb7,0x30,0xcf,0xaa,0xaa,0xad,0xc9,0x36,0x37,0xd4,0x2d,0x29,0x5f,0xa1,0x94,0xa0,0x1f,0x19,0x1c,0x21,0x2d,0x39,0x6e,0x35,0xcf,0x9a,0x8d,0x98,0xa4,0xa0 +,0xa5,0x20,0x03,0x05,0x0e,0x43,0x8f,0x88,0x86,0x9c,0x18,0x11,0x2c,0xad,0xf1,0x11,0x2a,0xb4,0x33,0x0f,0x2e,0x8c,0x83,0x89,0xa5,0x3c,0x17,0x1d,0x15,0x4e,0xa0,0x94 +,0x20,0x0b,0x12,0x0f,0x0a,0x0b,0x36,0x3d,0x9f,0x8e,0x88,0x92,0x8e,0x92,0x93,0x99,0x38,0x23,0x18,0xb7,0xa6,0x27,0x15,0xa8,0x88,0xa7,0x17,0x0e,0x06,0x02,0x00,0x0d +,0x8d,0x80,0x82,0x84,0x8b,0xa7,0x0d,0x00,0x04,0x2c,0x8e,0x86,0x86,0x8f,0xcd,0x19,0x0f,0x10,0xd6,0xba,0x3f,0x20,0xaf,0x91,0x2c,0x1d,0x4c,0x5d,0xdc,0x4b,0x1c,0x12 +,0x0d,0x60,0x87,0x80,0x98,0x26,0x32,0x2f,0x17,0x03,0x04,0x3c,0x8b,0x86,0x83,0x86,0x92,0x98,0xb2,0x23,0x1b,0x0d,0x06,0x03,0x13,0xb2,0x3a,0x1e,0xb4,0x94,0xca,0x23 +,0x3e,0x54,0xb7,0x54,0x8f,0x81,0x82,0x8d,0x5b,0x4d,0x25,0x0b,0x00,0x10,0xbb,0x9e,0x9e,0xa5,0x1d,0x0c,0x0b,0x08,0x33,0x99,0x8c,0x8c,0x8e,0x96,0xc0,0x0e,0x0d,0x99 +,0x87,0x92,0x4c,0x33,0x18,0x1a,0x37,0xa3,0x8d,0x99,0x48,0x28,0xbc,0x2e,0x0f,0x10,0x24,0x15,0x1a,0x3a,0xca,0xd6,0x7a,0xac,0xa1,0x9b,0xd6,0x24,0x27,0xb2,0x9c,0xd3 +,0x16,0xab,0x8b,0x8a,0x8d,0x9e,0x37,0x1c,0x18,0x18,0x50,0x3c,0x20,0x28,0xcc,0x21,0x0e,0x09,0x1c,0x9c,0xb0,0xdf,0x9d,0x96,0xa3,0x94,0x89,0x89,0x9c,0xbe,0x35,0x21 +,0x16,0x06,0x02,0x1d,0x8a,0x80,0x8c,0x1e,0x08,0x0a,0x0c,0x0a,0x18,0xb2,0x90,0x83,0x86,0x8f,0x33,0x0a,0x0f,0x21,0x2d,0x1e,0x51,0x93,0x95,0x99,0x9b,0x98,0xaa,0x21 +,0x1b,0x28,0x19,0x0f,0x21,0xa8,0x8e,0x8c,0xa9,0x25,0x25,0x20,0x1c,0x28,0x37,0x41,0x9f,0xa6,0xbe,0x9e,0xa2,0x1e,0x0e,0x1f,0x4b,0x2a,0xbc,0x8f,0x8a,0x90,0x7a,0xb5 +,0x9b,0xb0,0x3e,0x1f,0x0d,0x06,0x05,0x0b,0x26,0x97,0x89,0x8c,0x95,0x35,0x18,0x16,0x24,0x9d,0x8b,0x87,0x90,0xbb,0x30,0x18,0x0e,0x16,0xdc,0x9f,0xb2,0x33,0x1f,0x16 +,0x11,0x32,0xb7,0xb7,0xb8,0xa2,0x90,0x91,0xeb,0x1c,0x4a,0xa4,0xcc,0xbe,0xa4,0xa9,0xa7,0xbc,0x25,0x17,0x2c,0x40,0x3d,0x5c,0x75,0x5b,0x31,0x1f,0x3a,0xae,0x47,0x1f +,0x24,0x3f,0x3f,0x77,0xa9,0x92,0x8d,0x8f,0xa0,0x25,0x0e,0x07,0x0f,0x49,0x9c,0x9a,0x8f,0x8f,0xa4,0x59,0x1e,0x1e,0x57,0x9b,0x98,0x68,0x15,0x0e,0x0c,0x0d,0x1d,0xbb +,0xa7,0xa6,0xc4,0x49,0xd7,0xd5,0xa4,0x8e,0x8b,0x8c,0x91,0x9f,0x2f,0x10,0x10,0x17,0x2d,0xb1,0x9b,0x96,0xaa,0x12,0x06,0x0a,0x10,0x1a,0x2e,0xc6,0x9c,0x8b,0x8d,0xbf +,0x2f,0xb6,0xa4,0xaf,0xcf,0xbc,0xab,0xa8,0xbe,0xe3,0xab,0xaf,0x2f,0x20,0x1c,0x18,0x18,0x1e,0x6c,0x9d,0x96,0x9c,0x2d,0x0e,0x0f,0x25,0xad,0x93,0x93,0x97,0x9d,0x6b +,0x1a,0x10,0x14,0x20,0xb7,0x9c,0x94,0x95,0x9e,0xce,0x3f,0xac,0x99,0x9f,0xd6,0x23,0x1c,0x19,0x0e,0x0a,0x13,0x2c,0xcd,0x9e,0x99,0xa9,0xdc,0x3d,0x2e,0xb9,0x9a,0x93 +,0x8f,0x92,0xb3,0x1f,0x15,0x14,0x1f,0xdc,0x9f,0x98,0x9c,0x34,0x11,0x0f,0x1f,0x69,0xd1,0x46,0x4c,0xb7,0xa2,0xbb,0x2d,0xd3,0x9e,0xa9,0x56,0x29,0x26,0xcd,0xa3,0x9c +,0x9d,0x9d,0xa5,0x38,0x14,0x15,0x24,0x41,0xb5,0xbe,0xc1,0x9f,0xa9,0x20,0x0e,0x0c,0x1e,0xa5,0x99,0x9b,0x99,0x9f,0x4c,0x1f,0x16,0x1e,0x45,0xb6,0xa3,0x9b,0x91,0x96 +,0xe4,0x21,0x54,0xa5,0x9b,0xa7,0x2b,0x17,0x10,0x0d,0x10,0x1e,0x44,0xa5,0x9a,0xa6,0x48,0x2b,0x2f,0xae,0x98,0x93,0x97,0xa2,0xc5,0x2f,0x23,0x2c,0x3c,0x2c,0x2d,0xb8 +,0x9c,0x9d,0xdd,0x1b,0x1a,0x32,0x44,0x28,0x1a,0x1a,0x3e,0xa8,0xa2,0xa2,0xa5,0xa2,0xab,0x6d,0x2a,0x24,0x4c,0xa8,0xa2,0xaa,0x9e,0x9e,0x49,0x1b,0x13,0x15,0x3b,0xac +,0xbc,0xa1,0x9b,0xb2,0x24,0x0e,0x13,0x43,0xa3,0xa2,0xa7,0xa7,0xb3,0x36,0x1d,0x18,0x28,0xb5,0x9f,0xa2,0xa5,0x9f,0xab,0xbf,0xb4,0xaa,0x9e,0xa1,0x71,0x1c,0x16,0x15 +,0x16,0x19,0x19,0x27,0x3f,0xc9,0xb8,0xbc,0xb9,0xa4,0x9d,0xa2,0x9c,0x9a,0x9d,0xac,0x2d,0x23,0x36,0x31,0x2d,0x3e,0xc9,0xaa,0xb9,0x2e,0x1f,0x29,0x39,0x33,0x2d,0x23 +,0x33,0x4f,0xc2,0xad,0xaa,0x9c,0x97,0x9f,0x49,0x1f,0x1e,0x5d,0x9f,0x9f,0xa4,0xb0,0x6e,0x26,0x17,0x16,0x29,0xb7,0xa4,0x9f,0x9c,0x9d,0xb1,0x24,0x0f,0x13,0x21,0x4c +,0xc1,0xc9,0xae,0xa5,0xc3,0x27,0x1a,0x25,0xca,0xae,0xb3,0xa9,0x9a,0x94,0x99,0xa4,0xad,0xae,0xb6,0x38,0x17,0x0d,0x0e,0x11,0x1a,0x3d,0xaf,0xae,0xb8,0x4a,0x2d,0xb2 +,0x9f,0x9f,0x9f,0xa0,0x9c,0x98,0xa5,0x38,0x2f,0x2d,0x30,0x2e,0x28,0x38,0xc7,0xb8,0xc9,0x4c,0x43,0xcc,0x36,0x1d,0x15,0x14,0x1f,0xed,0xab,0x9f,0x96,0x95,0x9e,0xcc +,0x37,0x34,0x45,0xcb,0xd7,0xcb,0xb2,0xac,0x5a,0x1f,0x1d,0x24,0x62,0xac,0xb7,0xbe,0xaf,0xb0,0x5b,0x2c,0x22,0x3c,0xaa,0xab,0x77,0x31,0x2c,0x23,0x26,0x2e,0xbb,0x9e +,0x9f,0xae,0xd8,0xb2,0xa2,0xa3,0xab,0xad,0xb5,0xb5,0x5f,0x1d,0x1d,0x24,0x25,0x1a,0x14,0x16,0x26,0x5b,0x6d,0xc3,0xaf,0xa0,0x98,0x97,0x9b,0x9c,0xaf,0x40,0x2f,0x33 +,0xc4,0xaf,0xdb,0x53,0xd5,0xbf,0xc8,0x2b,0x1a,0x1c,0x2b,0x36,0x4c,0x2a,0x20,0x2f,0xb2,0x9a,0x97,0x9c,0xad,0x3e,0x20,0x2d,0xbf,0x9b,0x96,0xa3,0x4e,0x26,0x22,0x1f +,0x1f,0x21,0x31,0xc7,0xaa,0xa7,0x9c,0x9b,0xa7,0x5e,0x1a,0x15,0x1f,0x40,0xc7,0xd1,0x37,0x35,0x37,0x3a,0x65,0x66,0xc6,0xb3,0xc4,0x7a,0xa4,0x98,0x96,0x95,0x9b,0xa4 +,0xca,0x1a,0x0d,0x0e,0x19,0x2b,0x2d,0x26,0x2d,0x4f,0xc5,0xb7,0xc5,0xb5,0xab,0xbc,0xdd,0xac,0x9d,0x93,0x99,0xc0,0x45,0x38,0x2c,0x2a,0x3f,0x46,0xea,0x4f,0x2e,0x6b +,0xb5,0xaf,0x43,0x19,0x0d,0x13,0x2d,0xad,0x9a,0xa2,0x9e,0x9b,0xa3,0xbc,0x43,0x3b,0xd6,0xba,0xdb,0x3a,0x35,0x34,0x34,0x4e,0xb9,0xad,0xd7,0x2c,0x26,0x4b,0xb0,0xa7 +,0xbb,0x4a,0x34,0x30,0xcc,0xbd,0x37,0x29,0x26,0x1f,0x23,0x2b,0x6f,0x9a,0x92,0x9e,0xb5,0xee,0xc9,0xa4,0x9e,0x9e,0xae,0x2e,0x1e,0x23,0x3d,0xc6,0x34,0x18,0x10,0x16 +,0x26,0x37,0x54,0xc9,0x9f,0x99,0x9b,0xa0,0xb6,0xbb,0xa8,0xa4,0xad,0xcd,0x3a,0x3c,0xe8,0xb6,0xa0,0xab,0x2c,0x17,0x13,0x1d,0x40,0x48,0x25,0x23,0x32,0xce,0xa5,0xa6 +,0xaf,0xa3,0xa4,0xbf,0x36,0x2b,0xc4,0x97,0x94,0xa8,0x2d,0x1a,0x1a,0x27,0x50,0x40,0x2b,0x29,0xbf,0x9e,0x94,0x98,0xb9,0x30,0x1f,0x23,0x2c,0x34,0x25,0x1e,0x2d,0xb9 +,0xa1,0xb5,0x28,0x23,0xcd,0xa3,0xa3,0xba,0xc3,0xa5,0x98,0x93,0x95,0xad,0x2d,0x1b,0x17,0x1c,0x1e,0x19,0x1e,0x44,0xca,0xc4,0x5f,0x30,0x28,0xc5,0xa6,0xb1,0x3f,0x34 +,0xa8,0x90,0x8d,0x9a,0xcd,0x39,0x4e,0xf8,0x59,0x2f,0x1f,0x29,0x60,0xb8,0xaa,0x43,0x17,0x14,0x1d,0x33,0xce,0x49,0x29,0xde,0x9b,0x8e,0x92,0xb5,0x29,0x2f,0xa7,0x9d +,0xcb,0x1d,0x1b,0x2d,0xb6,0xa8,0xb9,0x40,0x2b,0x2e,0x4d,0xc6,0xf7,0x4e,0xba,0xa8,0xad,0xeb,0x2d,0x22,0x28,0x69,0x59,0x1e,0x13,0x1c,0xac,0x8e,0x90,0xbc,0x2e,0xcc +,0x9c,0x91,0x9b,0x37,0x1c,0x34,0xb6,0xa6,0xad,0x27,0x11,0x13,0x24,0x48,0x2f,0x18,0x17,0x3b,0x9b,0x94,0xaa,0x39,0x41,0x9f,0x8e,0x97,0x42,0x28,0xc8,0x9f,0x9c,0xb6 +,0x3c,0x3c,0x4a,0x3f,0x2c,0x1b,0x0e,0x11,0x27,0xe5,0xb6,0xbe,0x5f,0xd7,0xa0,0x98,0xa9,0x2a,0x23,0xbb,0x94,0x91,0xb5,0x1e,0x1f,0xba,0x9c,0xaa,0x1d,0x0e,0x16,0xde +,0x98,0x96,0xad,0x2b,0x2b,0xad,0x9c,0xb8,0x1d,0x0f,0x18,0x56,0xa1,0xad,0x3e,0x2c,0x3c,0xb0,0xa9,0x42,0x20,0x4a,0x9e,0x98,0x9f,0xb9,0xc6,0xa5,0x9b,0xa7,0x2d,0x11 +,0x0f,0x1d,0x6e,0xc6,0x3f,0x32,0x2c,0x54,0xb7,0xbf,0x1f,0x1a,0x3f,0xa1,0x8f,0x94,0xbb,0x49,0xa4,0x94,0x94,0xd2,0x19,0x14,0x3e,0xb5,0x9d,0x5f,0x10,0x17,0x20,0xd1 +,0xb3,0x36,0x1d,0x1e,0x47,0xa9,0x95,0x9f,0xaf,0xa9,0xb3,0x99,0xc0,0x27,0x1b,0x54,0xaa,0xb1,0x29,0x1e,0x3f,0xd0,0xa3,0xb5,0x4c,0x2a,0x3f,0xd7,0x9f,0xb9,0x30,0x50 +,0xde,0xbb,0xbb,0x22,0x10,0x1e,0xd3,0x9d,0xa7,0xbe,0x2e,0x3d,0x9d,0x93,0x98,0x52,0x1e,0x2a,0xad,0x9c,0xa6,0x34,0x27,0x1d,0x2a,0x45,0x26,0x1f,0x1e,0x35,0x3f,0x6f +,0x3c,0xcc,0x9f,0x99,0x9a,0xa6,0x36,0x1c,0x35,0x9f,0x91,0x9e,0x3e,0x22,0x72,0xbf,0xa8,0xc8,0x1f,0x1d,0x19,0x1f,0x2b,0x41,0xb2,0xa1,0xad,0xbd,0x3e,0x32,0x32,0xb5 +,0x9e,0x9f,0xb0,0x2c,0x2c,0x59,0x9d,0x98,0x75,0x13,0x11,0x26,0xbf,0x9b,0xa7,0xbf,0x3b,0x25,0x58,0x6a,0xd7,0xee,0xc8,0x3a,0x26,0x22,0x38,0xaf,0xa4,0x9f,0xc3,0x28 +,0x19,0x2e,0xad,0x97,0x9c,0xb3,0xcf,0x35,0xb9,0xa6,0x9f,0xb4,0x24,0x1a,0x1a,0x35,0xc5,0xaf,0xb7,0x3b,0x21,0x1b,0x21,0x4e,0xaf,0xa2,0xa6,0xae,0xc1,0xcd,0xa9,0xa6 +,0x9c,0x9d,0x5c,0x19,0x1b,0xe4,0xab,0xae,0x42,0x1f,0x1d,0x1f,0x2f,0xc4,0xd0,0xe3,0x5f,0x36,0x4f,0xac,0xab,0xa8,0xac,0xb6,0xc9,0x2a,0x27,0x3d,0xae,0xa0,0xb3,0x24 +,0x1a,0x34,0xaa,0x9c,0x9f,0xc7,0x27,0x1f,0x2f,0xd5,0xa5,0xac,0x4a,0x23,0x23,0x30,0x5a,0xc5,0xda,0xc4,0xc5,0xd6,0x37,0x76,0xac,0x9d,0x9d,0xb1,0x38,0x21,0x32,0xc0 +,0xa8,0xa4,0xcc,0x25,0x18,0x2b,0xad,0xa8,0xc8,0x2e,0x1f,0x1c,0x1f,0x49,0xa2,0xa3,0xae,0xc5,0x3d,0x2a,0x50,0xac,0x9f,0x9e,0xac,0x47,0x2b,0x41,0xaf,0xa5,0xe6,0x1e +,0x1d,0x25,0x39,0xbd,0xb6,0xdb,0x2d,0x23,0xe0,0xa5,0xa7,0xae,0x32,0x2d,0xd0,0xad,0xa7,0xb5,0x4c,0x2b,0x33,0x37,0x37,0xce,0xa3,0x9c,0xa7,0xad,0xd2,0x32,0x28,0x4b +,0xb0,0x72,0x2e,0x1f,0x1e,0x24,0x2e,0x52,0x48,0x35,0x57,0xb3,0xce,0xf1,0xc0,0xb9,0xb4,0xb1,0xac,0xac,0xae,0xa8,0xa7,0xbc,0x3c,0x2c,0x3f,0xad,0xa8,0xb2,0x34,0x19 +,0x16,0x23,0xde,0xd5,0x3a,0x32,0x34,0x2f,0x5b,0xac,0xa6,0xb9,0xf1,0xb4,0xa6,0xbe,0x41,0xc2,0xa8,0xab,0xaf,0xb5,0x48,0x2f,0x2c,0x2c,0x2b,0x2d,0x44,0x7c,0xf3,0x63 +,0x48,0x32,0x2a,0x37,0xc9,0xba,0x71,0x39,0xd9,0xba,0xb4,0xa6,0xab,0xc5,0xe1,0xad,0xa2,0xac,0xd1,0x44,0x4a,0x70,0xfe,0xc4,0x4a,0x1f,0x1b,0x2a,0x38,0x2b,0x30,0x4a +,0xc1,0xbc,0xb3,0xba,0x37,0x29,0x3a,0xab,0x9e,0xa6,0xb4,0xb1,0xb9,0xb7,0xac,0xae,0xdf,0x2e,0x2e,0x34,0x2f,0x41,0x4f,0x5c,0x4a,0x38,0x2f,0x20,0x27,0x49,0xbf,0xbc +,0x76,0xbf,0xb3,0xcf,0xb7,0xa4,0xc3,0x37,0x47,0xbc,0xb3,0xc1,0xb8,0xbb,0x5e,0x46,0x5e,0x3e,0x31,0x2d,0x5b,0xba,0xd2,0x3d,0x49,0xe6,0x47,0xcc,0xb9,0xef,0x2e,0x28 +,0x3c,0xb6,0xaf,0xa9,0xa7,0xb7,0xc8,0xcf,0xba,0xce,0x3a,0x54,0xd4,0x34,0x2a,0x67,0x57,0x2f,0x44,0x3d,0x2a,0x26,0x3a,0xb3,0xbc,0x71,0xbc,0xad,0xc1,0xc1,0xab,0xb8 +,0x3f,0x2f,0xc6,0xad,0xd6,0x47,0xe2,0xcc,0xd6,0x4b,0x43,0x30,0x21,0x2a,0xb5,0xa2,0xf4,0x36,0x56,0xc1,0xbc,0xb1,0xa8,0x5a,0x21,0x2b,0xca,0xb9,0xae,0xaf,0xce,0x39 +,0x39,0xf4,0xe7,0x3f,0x38,0xe5,0x56,0x36,0xbe,0xa5,0xaa,0xba,0x3d,0x38,0x37,0x3c,0xb8,0xba,0x3b,0x2a,0x35,0xf0,0xc3,0x6c,0x61,0x3a,0x24,0x2a,0xb4,0xa3,0xad,0xb3 +,0xc0,0xc0,0xd7,0xcc,0xb9,0x42,0x26,0x32,0x4e,0x4c,0xee,0xbe,0xb7,0x43,0x2d,0x4b,0xcf,0x72,0x38,0x60,0xce,0xc9,0xad,0xa2,0xa1,0xbf,0xdb,0xcb,0x41,0x33,0x3c,0x3d +,0x32,0x32,0x6f,0xba,0x4a,0x2f,0x3a,0x37,0x3b,0xc6,0xa6,0xaf,0x62,0xbc,0xab,0xae,0xcb,0x53,0x50,0x37,0x28,0x3a,0xc4,0x52,0x36,0x3c,0xc2,0xd8,0x4a,0xea,0x4d,0x36 +,0x33,0xb8,0xb7,0xe9,0xbe,0xae,0xb5,0x54,0x47,0xd2,0xfd,0x38,0x38,0x46,0x3d,0x5e,0xb2,0xab,0xc5,0x37,0xfb,0xe2,0xff,0xdd,0xbc,0x51,0x2b,0x3e,0xb5,0xa3,0xb0,0xf7 +,0x3f,0x2e,0x2b,0xfe,0xae,0xc7,0x3f,0x5d,0xbc,0xed,0x50,0xd6,0x47,0x29,0x2b,0xdb,0xb6,0xb5,0xad,0xaf,0xc8,0x4a,0xd8,0xc6,0x32,0x26,0x2c,0x39,0x3d,0x4e,0x4f,0x61 +,0x49,0x5b,0xad,0xa9,0xbb,0xe5,0xe0,0xf6,0xc0,0xa7,0x9d,0xa9,0x3d,0x26,0x2c,0x28,0x2c,0x43,0x4c,0x39,0x3c,0xbe,0xae,0xb5,0xba,0xbf,0x40,0x35,0x41,0xc7,0xca,0x53 +,0xe9,0xae,0xbb,0x42,0xce,0xd1,0x43,0x34,0x3f,0xe2,0xca,0xbb,0xaf,0xb3,0x65,0x51,0x57,0x33,0x26,0x29,0x34,0x3f,0xc6,0xaa,0xad,0x63,0x34,0x4c,0xc0,0xbd,0xc2,0x5f +,0x2c,0x23,0x3e,0xa6,0xa4,0xbd,0x48,0x3c,0x62,0xc9,0xbd,0xcd,0x3f,0x3c,0xc6,0xa8,0xa9,0xbd,0x59,0x2a,0x1e,0x28,0x4f,0xc4,0xc9,0xe5,0xbb,0xab,0xaf,0xbb,0xcd,0x36 +,0x29,0x32,0x49,0x5b,0xc8,0xb0,0xbb,0x68,0x50,0xb5,0xb5,0x48,0x2e,0x27,0x2d,0x5a,0xaa,0xa6,0xc2,0x33,0x2f,0x3a,0x3f,0x52,0x49,0x3f,0x35,0xdf,0xa7,0x9e,0xac,0xbd +,0xbd,0x38,0x2d,0x35,0x4a,0x4a,0x44,0x32,0x30,0xe3,0xae,0xa1,0xaa,0x41,0x28,0x2e,0xf1,0xb8,0xb0,0xb8,0xcc,0xdd,0xdd,0xb9,0x7a,0x2b,0x1d,0x22,0x44,0xab,0x9d,0xa4 +,0xc4,0x3f,0xce,0xb5,0xbe,0x3f,0x26,0x1e,0x2a,0xcf,0xac,0xae,0x4b,0x4e,0xcd,0xe9,0x43,0x38,0x36,0x3f,0xbe,0xab,0xa7,0xb3,0xcf,0xee,0x32,0x20,0x2b,0x3e,0x3f,0xf1 +,0xbb,0xb7,0xaf,0xa8,0xa4,0xad,0x4e,0x27,0x1f,0x2e,0x65,0xbe,0xc5,0x4c,0x36,0xbf,0xa4,0xad,0x56,0x27,0x1e,0x28,0xbb,0x9f,0x9b,0xa8,0x4b,0x43,0x5b,0x49,0x2f,0x2a +,0x2c,0x32,0xdd,0xae,0xa9,0xb4,0xc0,0xd6,0x40,0x2f,0x34,0x37,0x36,0x3b,0xca,0xae,0xac,0xac,0xaf,0xda,0x29,0x23,0x30,0x65,0xcc,0xc6,0xc2,0xdb,0xc0,0xaa,0xaa,0x3f +,0x1c,0x18,0x21,0xbd,0x9f,0x9d,0xa8,0x52,0x4b,0xab,0xa1,0xbc,0x2c,0x1c,0x1c,0x2e,0xc5,0xaf,0xb4,0xc2,0xcb,0xba,0xca,0x3d,0x2f,0x39,0x69,0x65,0xb1,0xa7,0xb0,0xc5 +,0xe4,0x3f,0x31,0x28,0x29,0x43,0x64,0xe6,0xc3,0xb1,0xac,0xa6,0xad,0x3d,0x25,0x23,0x37,0xd9,0xe9,0x42,0x32,0x36,0xb0,0x9d,0xa1,0xe7,0x1e,0x1b,0x3b,0xa7,0x9f,0xad +,0x52,0x30,0x57,0xaf,0xbc,0x37,0x24,0x26,0x37,0xe7,0xaf,0xa8,0xa9,0xa6,0xb0,0xbf,0x63,0x28,0x26,0x35,0x45,0x3d,0x4f,0x61,0xc8,0xad,0xae,0xeb,0x2d,0x31,0x4d,0xc1 +,0xdf,0x6c,0xbf,0xb1,0xab,0xb0,0xc8,0x2a,0x1c,0x29,0xc0,0xb1,0xdd,0x2b,0x24,0xd0,0x9e,0x9e,0xb6,0x2a,0x1a,0x22,0xcc,0xa8,0xa9,0xc3,0x4a,0x67,0xb9,0xa7,0xc4,0x2d +,0x23,0x44,0xc3,0xc6,0xcd,0xcd,0xb5,0xbb,0xcc,0x43,0x2d,0x25,0x2f,0x4a,0x64,0xbf,0xaf,0xa8,0xa7,0xac,0xb8,0x3b,0x27,0x29,0x35,0x41,0x3e,0x31,0x3d,0xa3,0x99,0xa0 +,0x4b,0x1c,0x1a,0x62,0xa8,0xae,0x6b,0x2a,0x37,0xcc,0xa5,0xa4,0xe4,0x1d,0x18,0x25,0xc2,0xa5,0xae,0xb2,0xae,0xac,0xac,0xc0,0x2b,0x1f,0x29,0x3b,0xdd,0xf7,0x55,0xaf +,0xa8,0xa9,0xae,0x39,0x25,0x2f,0x51,0xc3,0xd4,0x3a,0xd6,0xaf,0xae,0xb2,0x49,0x26,0x25,0x37,0xcd,0xbb,0x4d,0x3c,0xb8,0x9c,0x96,0xa2,0x2f,0x18,0x1b,0x35,0xb3,0xe2 +,0x2b,0x30,0xdd,0xaa,0x9e,0xb2,0x37,0x2e,0x29,0x4b,0xb6,0xc9,0xeb,0xc0,0xc1,0xb1,0xb0,0x37,0x1e,0x1f,0x35,0xba,0xb9,0x50,0xbf,0xa9,0xa4,0xa1,0xbb,0x3a,0x2e,0x2f +,0x39,0x3c,0x33,0x52,0xae,0xac,0xa6,0xc1,0x2f,0x24,0x2b,0xbe,0xad,0x5e,0x22,0x2e,0xb8,0x9a,0x98,0xba,0x25,0x1c,0x25,0xca,0xa6,0x6c,0x38,0x3b,0x49,0xaf,0xaf,0xbd +,0x44,0x32,0x2c,0xda,0xb2,0xd5,0x74,0x2b,0x2b,0x45,0xc5,0xa6,0xb2,0xc9,0x43,0xaf,0xaf,0xa5,0x70,0x1f,0x16,0x22,0xb7,0x97,0x8f,0xec,0xaf,0x49,0x9f,0xc8,0xaa,0x10 +,0x1a,0x21,0x00,0x11,0x06,0xbb,0x38,0x56,0xa8,0x18,0x9f,0x9c,0x94,0x8c,0x88,0xaf,0xc0,0x89,0x9b,0xad,0x8a,0x2c,0x15,0xac,0x08,0x8e,0x82,0xa5,0x9a,0x94,0xad,0xc9 +,0x18,0x00,0x04,0x04,0x08,0x07,0x08,0x00,0x04,0x0b,0x22,0x0c,0x03,0x08,0x0b,0x4b,0xaa,0xa5,0x1b,0x71,0x92,0x8b,0x8e,0x8e,0x8f,0x9a,0x8a,0x87,0x84,0x84,0x85,0x84 +,0x80,0x81,0x81,0x84,0x8a,0x83,0x81,0xa1,0x9b,0x8d,0x8f,0x20,0x3f,0x42,0x04,0x0a,0x02,0x0a,0x0b,0x00,0x02,0x06,0x0a,0x0f,0x05,0x00,0x03,0x00,0x04,0x0d,0x0d,0x08 +,0x0c,0x18,0x95,0x9f,0x2c,0xb9,0xa8,0x87,0x84,0x82,0x8c,0x86,0x86,0x81,0x82,0x80,0x8b,0x90,0x83,0x85,0x81,0x8d,0x99,0x3a,0x96,0xa2,0x97,0x9a,0x49,0x0b,0x1e,0x21 +,0x0b,0x13,0x03,0x07,0x09,0x10,0x04,0x07,0x03,0x02,0x03,0x07,0x0a,0x05,0x0f,0x10,0xaf,0x9d,0x40,0x44,0xbd,0x8f,0x87,0x8e,0x98,0x9d,0xb6,0x8c,0x8b,0x9f,0x93,0x8c +,0x83,0x84,0x8e,0x85,0x90,0x8b,0x84,0x80,0x83,0x83,0xaa,0x26,0x8a,0x9f,0x23,0x09,0x07,0x0d,0x13,0x0d,0x0a,0x02,0x01,0x0a,0x0b,0x03,0x07,0x05,0x0c,0x28,0x1d,0x02 +,0x03,0x00,0x15,0xa1,0xc6,0xf5,0x0e,0xa2,0x9b,0x8e,0x8c,0x8e,0x86,0x89,0x87,0x88,0x82,0x89,0x89,0x85,0x82,0x8d,0xa4,0x8e,0x91,0x89,0x94,0xcc,0x1f,0x1e,0x23,0xa1 +,0xb9,0x0c,0x1e,0x0f,0x3e,0x1a,0x0b,0x0e,0x04,0x02,0x0f,0x18,0x09,0x0a,0x09,0x00,0x1f,0x15,0x0d,0x1e,0x2b,0x19,0x0d,0x2e,0x15,0x8b,0x87,0x8e,0x9a,0x99,0x9e,0xc0 +,0x81,0x8e,0xb2,0x1e,0xa4,0x80,0x88,0x8a,0x4e,0x32,0x86,0x82,0x80,0x8f,0xae,0x98,0x89,0x9a,0xd5,0xb7,0x17,0x13,0x3a,0x0b,0x03,0x03,0x04,0x13,0x1e,0x17,0x00,0x03 +,0x01,0x45,0x8e,0x13,0x00,0x08,0x2a,0xcb,0x90,0xad,0x04,0x09,0x23,0x8c,0x8e,0xa2,0xb5,0x93,0x82,0x87,0x94,0xb7,0x83,0x90,0x84,0x85,0x89,0xc5,0x2e,0x83,0x83,0x8e +,0x17,0x0d,0x11,0x8b,0x8f,0x31,0x34,0xbf,0x2d,0x95,0x83,0x2b,0x09,0x00,0x23,0x25,0x10,0x23,0x00,0x0b,0x08,0x14,0x14,0x08,0x15,0x00,0x33,0x1b,0x0f,0x29,0x2d,0x38 +,0x6c,0x90,0x10,0x46,0x95,0x8e,0x89,0xa3,0x93,0x9b,0x8d,0x82,0x80,0x81,0xfd,0x0c,0x8e,0x85,0x85,0x92,0xa6,0x8c,0xa2,0x85,0x4e,0x10,0x2a,0xa5,0x0f,0x2e,0x3f,0x1d +,0x36,0x01,0xcd,0x1a,0x27,0x0f,0x00,0x03,0x1c,0x1b,0x06,0x0e,0x06,0x09,0x4b,0xa6,0x1d,0x06,0x06,0xd7,0xa8,0x8e,0x26,0x0a,0x2c,0x99,0x80,0x84,0x8e,0x11,0x23,0x88 +,0x88,0x80,0xd0,0x97,0x8d,0x89,0x80,0x96,0x2e,0x15,0x87,0x9d,0x8c,0x8e,0x18,0x64,0xbd,0x87,0x90,0x4c,0x09,0x05,0x9e,0xbe,0x1c,0x03,0x0f,0x1c,0x0c,0x0e,0x08,0x05 +,0x00,0x17,0x13,0x13,0x09,0x08,0x05,0x6f,0x8e,0x6b,0x11,0x07,0x16,0x8d,0x80,0xcf,0x8a,0x9e,0x93,0x80,0x8e,0x84,0xb8,0x9a,0x83,0x8f,0x8a,0xae,0x9d,0x92,0x8f,0x89 +,0x97,0xa6,0x14,0x17,0x37,0x8d,0xa0,0x1c,0x12,0x9f,0x18,0x38,0x5f,0x10,0x09,0x15,0xa9,0x11,0x18,0x0a,0xb2,0x1a,0x28,0x1f,0x01,0x0d,0x0b,0x3a,0x5c,0x15,0x0b,0x09 +,0x28,0x9e,0xbb,0x13,0x07,0xad,0x98,0x99,0x8d,0x93,0x9d,0xa8,0x8c,0x87,0x8b,0xda,0x93,0x8e,0x8e,0x87,0x8e,0xab,0x88,0x81,0x97,0x8b,0xa6,0x1c,0x1c,0x9c,0x97,0x92 +,0x13,0x11,0x0c,0x10,0x9c,0x14,0x01,0x02,0x09,0x5a,0x2a,0x0d,0x09,0x04,0x1a,0x1e,0x33,0x0c,0x05,0x08,0xca,0xa3,0x1e,0xc2,0x17,0xc5,0x89,0x8c,0xb2,0xa9,0x5f,0xae +,0x85,0x86,0x90,0x89,0x83,0xa1,0x85,0x9c,0xce,0xa1,0x96,0x98,0xad,0x9c,0x1f,0xbf,0x51,0xae,0xb8,0x12,0x26,0x0e,0x12,0xa2,0xa0,0x1f,0x23,0xa5,0x13,0x19,0x4f,0x1c +,0x0c,0x20,0x0f,0xa8,0x14,0x10,0x0f,0x11,0xb4,0x14,0x26,0x0d,0x07,0x1a,0x8d,0xaf,0x9d,0x0e,0x17,0xa1,0x89,0xa0,0xa5,0x3b,0x38,0x81,0x99,0x8a,0x93,0x8f,0x92,0x8e +,0x8c,0xab,0x97,0xb2,0x8f,0x80,0x8e,0xa3,0x15,0x7d,0x9e,0x95,0xb3,0x01,0x0b,0x15,0x17,0x98,0x26,0x0d,0x02,0x38,0x19,0x0f,0x17,0x00,0x05,0x4e,0x95,0x1f,0x0f,0x02 +,0x1f,0xa1,0xca,0x21,0x23,0x0a,0xac,0x89,0x8e,0x94,0x15,0x4d,0x9a,0x87,0x88,0x40,0x31,0x9e,0x83,0x80,0x8a,0x95,0x39,0xaf,0x88,0x89,0x9b,0x2c,0x13,0x20,0x8d,0x8c +,0xa1,0x0a,0x0f,0xc8,0xab,0xb5,0x03,0x0b,0x11,0x2a,0x94,0xa5,0x0b,0x11,0x0e,0x0e,0x8e,0x1c,0x00,0x0d,0x20,0xb2,0x9c,0xc2,0x06,0x0e,0xa5,0x8f,0x38,0x5a,0x0a,0x43 +,0x86,0x8e,0x8d,0x3a,0xbd,0x9d,0x8d,0x94,0xa4,0x12,0xc3,0xab,0x84,0x80,0xe5,0x19,0x1a,0xa4,0x8f,0x90,0x0c,0x2d,0x26,0xad,0x83,0xbb,0x1e,0x15,0x16,0x98,0x8e,0x09 +,0x07,0x0a,0x1b,0x8f,0x9a,0x11,0x07,0x0b,0xb4,0x8e,0x66,0x20,0x03,0x7b,0x8b,0x98,0x36,0x1e,0x06,0x0c,0x9b,0xd8,0x0d,0x1d,0x13,0x49,0x8b,0x9a,0x9f,0x0e,0xc7,0x89 +,0x8d,0x8d,0xb1,0xc8,0x8b,0x85,0x80,0x8f,0x1f,0x1e,0x95,0x8b,0x8b,0x18,0x0f,0x28,0xc0,0x81,0xa5,0x08,0x02,0x0c,0x1c,0x9d,0x19,0x07,0x05,0x0e,0x46,0x42,0x47,0x05 +,0x02,0x36,0xa8,0x6d,0x24,0x0a,0x3f,0x8f,0x84,0x8f,0xc6,0x20,0x1f,0x88,0x87,0x91,0x1e,0x1d,0x9b,0x8d,0x86,0x8d,0x11,0x1d,0x90,0x98,0x97,0x1b,0x19,0x20,0xbc,0x86 +,0xa6,0x17,0x0d,0x15,0x9f,0x9c,0x36,0x14,0x04,0xbb,0x8a,0x47,0x9c,0x30,0x0e,0x2b,0xa0,0xa5,0x29,0x0c,0x21,0x89,0x99,0x94,0x1d,0x06,0x19,0xbb,0xa5,0x1c,0x1c,0x0c +,0x30,0x8b,0x59,0x3a,0x0b,0x05,0xaf,0xb9,0x96,0x1a,0x12,0xc1,0x92,0x86,0x93,0x4a,0x17,0xa0,0x92,0x87,0x8c,0xb8,0xee,0x8c,0x84,0x8f,0xad,0x9b,0x1b,0xae,0x8b,0x22 +,0x27,0x1a,0x1b,0x35,0x9a,0xce,0x0d,0x02,0x0e,0xc4,0x36,0x0f,0x15,0x08,0x26,0xce,0x9b,0xbb,0x08,0x10,0x2c,0x9c,0x99,0x3d,0x15,0xa5,0x87,0x84,0x99,0xcf,0x0e,0x17 +,0x94,0x8a,0x2d,0x21,0x26,0xc8,0x83,0x92,0x9f,0x21,0x16,0x9a,0x8d,0xab,0x2a,0x1c,0x1d,0x87,0x95,0xe7,0x4b,0x03,0x1a,0xb5,0xb2,0x21,0x05,0x0f,0x99,0x98,0x92,0x3a +,0x08,0x0a,0xc3,0xa4,0xe1,0x21,0x05,0x2f,0x91,0x8c,0x9e,0x22,0x0b,0x34,0x91,0x98,0x50,0x10,0x17,0x99,0x87,0x93,0xbd,0x0a,0x14,0x9e,0xa2,0x31,0x23,0x10,0x1d,0x86 +,0x8f,0x9f,0x7b,0x08,0xab,0x8d,0xb0,0xcd,0x19,0x1d,0x8e,0x89,0x9a,0x5a,0x06,0x2a,0x93,0xaf,0xaa,0x21,0x06,0x5a,0x86,0x91,0xba,0x0f,0x0e,0x2a,0xc9,0x5d,0x1d,0x0d +,0x1b,0x92,0x91,0xb1,0x1f,0x09,0x1e,0x9f,0xc9,0x16,0x0e,0x1b,0xa9,0x95,0x8d,0x98,0x15,0x10,0xb5,0x8e,0x98,0x2f,0x19,0xad,0x88,0x87,0x8d,0xe4,0x1b,0xb5,0x99,0x96 +,0xad,0x19,0x1d,0xa3,0x8b,0x92,0x24,0x0f,0x1d,0xa0,0xa7,0x3e,0x13,0x05,0x1e,0x8b,0x98,0x2e,0x3f,0x1b,0xc3,0xb4,0x2a,0x14,0x0e,0x26,0x9b,0x8e,0x9a,0x26,0x09,0x11 +,0xa7,0xa1,0x27,0x1d,0x11,0x3c,0x95,0x97,0x9c,0x35,0x1f,0xb0,0xaf,0xbc,0x26,0x15,0x17,0xa1,0x8e,0xa9,0x4d,0x17,0xcd,0x98,0xde,0x1e,0x0d,0x15,0xa5,0x8b,0x8d,0xde +,0x19,0x21,0xa5,0x9c,0x4e,0x16,0x10,0x29,0x91,0x95,0xab,0x41,0x17,0xee,0x98,0xa7,0x1c,0x08,0x14,0x94,0x91,0x9a,0x9f,0x20,0x20,0xad,0xbb,0x29,0x10,0x12,0xb8,0x8b +,0x9b,0xbb,0x1f,0x18,0x90,0x99,0x35,0x1c,0x0f,0x22,0x93,0x90,0xab,0x2c,0x18,0xcf,0x90,0xb1,0x1f,0x0f,0x0e,0xba,0x91,0x92,0xaa,0x25,0x24,0xa9,0xa3,0xfd,0x1a,0x0e +,0x23,0x9f,0x8f,0x98,0xd3,0x20,0x2d,0xa8,0xac,0xbc,0x15,0x0d,0xbc,0x92,0x91,0x9f,0x2f,0x1f,0xa8,0xa3,0x31,0x2d,0x14,0x22,0xa3,0x9f,0x93,0xb1,0x25,0x47,0xa2,0x3b +,0x18,0x12,0x28,0x9a,0xa1,0xae,0xb8,0x20,0xc8,0x92,0x3e,0x1f,0x1d,0x1a,0x3a,0x95,0xac,0xe6,0xb0,0x34,0xa6,0xab,0x42,0x1a,0x0f,0x27,0xa1,0x9e,0xb3,0xa0,0x49,0x9e +,0x9a,0x26,0x10,0x0e,0x2c,0x28,0x99,0x9e,0x6b,0x33,0x2f,0x99,0x98,0x3a,0x15,0x1d,0x2e,0x9b,0xbf,0x2b,0xbf,0xd7,0x9c,0x97,0xb5,0x1c,0x18,0x16,0x31,0x9b,0xa1,0xad +,0x4d,0xa8,0xab,0x57,0x29,0x28,0x24,0x2e,0x9e,0xa1,0x5a,0x2d,0xb3,0x9c,0x98,0x50,0x1e,0x12,0x0e,0xb5,0x96,0x42,0xd3,0x49,0xc9,0x92,0x9e,0x3b,0x14,0x19,0xfb,0xa3 +,0xc3,0xb8,0xa8,0xa7,0xa8,0xe9,0x1d,0x1d,0x1d,0x20,0x9b,0xa9,0x52,0xb7,0x36,0x47,0x96,0xa2,0x1f,0x23,0x1f,0xc5,0x9b,0x49,0x2c,0x26,0x4d,0x95,0x9e,0x2c,0x1a,0x13 +,0x2c,0x9f,0xa4,0xba,0x7b,0xc5,0xb8,0xcd,0x5b,0x24,0x36,0xbf,0xb3,0xb5,0x1d,0x32,0x9f,0xab,0xaa,0x9e,0x26,0x0d,0x22,0xbe,0xa3,0xaf,0x2a,0x2f,0xac,0x9b,0x93,0xb2 +,0x2b,0x1d,0x1b,0xab,0x8f,0xa2,0x27,0x35,0x35,0xad,0xa9,0x27,0x18,0x1b,0x4e,0xb4,0xc0,0xd2,0x26,0x20,0xab,0x96,0xd5,0x20,0x17,0x2d,0x99,0x9e,0x42,0x1e,0x48,0x9c +,0x94,0xa7,0x42,0x1f,0x22,0xb8,0xa2,0xb2,0xd8,0x3e,0xba,0x9f,0xd6,0x1f,0x1a,0x1c,0x28,0xa8,0x4f,0x48,0xdd,0xb2,0xad,0xaf,0xc7,0x1d,0x1f,0x3b,0x9f,0x9e,0x3f,0x46 +,0xc3,0x38,0x9f,0xa4,0x28,0x27,0x23,0x1f,0xc8,0xa1,0xa3,0xab,0x40,0x4a,0x57,0x35,0x4f,0x2a,0x36,0xbe,0xba,0x76,0xbd,0xc2,0xc6,0xa5,0xc6,0x3e,0x1f,0x6e,0x3c,0x52 +,0xca,0x3e,0xae,0xbc,0x99,0x9b,0x34,0x1e,0x1f,0xc2,0xaf,0xab,0x45,0x2c,0xbb,0x3a,0xbb,0x2a,0x1e,0x2d,0x33,0xba,0x38,0xe0,0xab,0xb1,0xab,0xab,0xc3,0x3d,0x25,0x5b +,0xae,0xb3,0xae,0x2b,0x37,0x54,0xba,0x9d,0xb6,0x26,0x1f,0x27,0x55,0x9d,0x9a,0xd3,0x2e,0x1a,0x30,0x9f,0xae,0x33,0x32,0x38,0x28,0xba,0x57,0xad,0xb6,0xce,0xae,0x3f +,0x19,0x27,0xb2,0xac,0xb0,0x2d,0x60,0xaf,0xfd,0x28,0xae,0x43,0x2a,0xcf,0x5b,0xae,0x5f,0x3d,0xb3,0x64,0xb3,0xaa,0x38,0x39,0x46,0x37,0x2c,0xb9,0xb4,0xb7,0x9d,0x58 +,0x2d,0xaf,0x74,0x2b,0xa9,0xba,0x53,0xde,0x1e,0xab,0x9d,0x3f,0xe0,0xe6,0x25,0x57,0xb9,0xbe,0x51,0x26,0x2e,0xe1,0xc8,0x2c,0xda,0x3d,0x69,0xbd,0x15,0x23,0xa9,0xb1 +,0xad,0xb5,0x28,0x46,0xdf,0x2f,0xae,0x6d,0x2f,0xb5,0xe1,0xb1,0xb2,0x3d,0xa0,0xb5,0x26,0xdc,0x9d,0xd0,0xcb,0x45,0x2f,0xca,0x4f,0xa8,0xaf,0x9b,0x2f,0x1b,0x5f,0x54 +,0x9e,0xd6,0x24,0xaa,0xb5,0x35,0x3d,0x46,0x2e,0x4c,0x39,0x47,0xaf,0x27,0x4e,0x52,0x27,0x7a,0xd8,0x2b,0xb3,0xaf,0x2a,0x5d,0x2c,0x27,0xae,0xdf,0xf4,0x45,0x1d,0xbd +,0xa1,0x35,0x6c,0xa9,0x3e,0xbe,0xb0,0xc7,0x9d,0xaf,0x38,0xac,0x63,0x37,0x9d,0xc8,0x1c,0x9f,0x9d,0x3c,0x40,0x2e,0xb1,0xa5,0x43,0xcc,0xbe,0x1f,0xc4,0xbc,0x2b,0xad +,0x37,0x1b,0x5d,0x3b,0x6e,0xa4,0x2b,0x27,0xb1,0x25,0x28,0xbf,0x1a,0xbf,0xb0,0x2d,0x9e,0xb2,0x1c,0x34,0x5e,0x24,0xbb,0xcb,0xfe,0xa8,0xba,0xcf,0xca,0x28,0x35,0xa8 +,0x71,0xa3,0xab,0xdf,0xac,0x5e,0x47,0xd4,0x3e,0xbd,0x97,0xce,0x2c,0xb2,0x3d,0xb2,0x9f,0x2d,0x67,0xbc,0x66,0xf8,0x56,0x1e,0x3e,0xbf,0x2d,0x9e,0xb6,0x2e,0xef,0x2c +,0x3f,0xae,0x37,0x48,0x4f,0x25,0x51,0x7c,0x57,0xbd,0x33,0x18,0xaa,0xbd,0x2d,0xb7,0x2a,0x2e,0x5d,0xbf,0xa7,0xaf,0x26,0x36,0xa6,0xb6,0x31,0x29,0x39,0xa3,0xb3,0x29 +,0x3a,0xba,0xe5,0xa4,0xb2,0x25,0x6b,0x2e,0x41,0xb4,0x9d,0xa0,0xd1,0xc3,0xbf,0xde,0x2a,0xc3,0xb0,0xeb,0xcf,0xc9,0xaf,0xb8,0xb7,0x60,0x5d,0x3f,0x3c,0x2d,0x3c,0xa1 +,0xab,0xb1,0xd8,0x1c,0x26,0xa7,0xae,0x5b,0x27,0x1a,0x2b,0xd2,0x37,0xbc,0x38,0x31,0xa2,0x72,0x26,0x25,0x2f,0x2d,0xb2,0xa8,0xa5,0xbd,0x23,0x2a,0xc9,0x3f,0x23,0x39 +,0x5e,0xa6,0xa5,0x2f,0x3d,0xa8,0x4c,0xab,0xad,0xd1,0xc7,0x2e,0x63,0x9f,0xa7,0xe0,0x37,0x2d,0xa2,0xb2,0xba,0x4c,0x28,0xdd,0x40,0x5f,0xad,0xa1,0x32,0x4a,0xa3,0x33 +,0x3c,0x34,0x35,0xc1,0xb7,0xaf,0xaf,0x4b,0x23,0xf3,0x3c,0xf5,0xb9,0x32,0x29,0x23,0x39,0xa5,0xa9,0x32,0x4c,0xd5,0x2d,0x4f,0x4b,0x38,0xbe,0xb6,0xa4,0xa5,0x2b,0x1d +,0x2c,0x45,0xa3,0xa2,0x29,0x25,0xad,0xd1,0xd2,0xef,0x28,0xc8,0xad,0x5e,0xba,0xdd,0x1f,0x27,0x6b,0x9d,0x9c,0x4d,0x2d,0x2f,0x23,0xb7,0xa4,0xc8,0x4b,0x2e,0x46,0xa4 +,0x4c,0xea,0x9f,0xc5,0xb2,0x60,0x2d,0x26,0x46,0xa6,0x9e,0x57,0x2f,0xcb,0x38,0xed,0xbc,0x2b,0x22,0x36,0xb6,0xa7,0xaf,0x2c,0x24,0xca,0xb6,0xac,0x3b,0x2a,0xb4,0x38 +,0xc8,0xa5,0x58,0xd2,0x32,0x2c,0xb7,0xbe,0x40,0x2d,0x29,0xc4,0xb9,0xb6,0x6b,0xad,0xb3,0x32,0xbd,0x2d,0x68,0x40,0x32,0xa5,0x9d,0xd0,0x28,0x24,0x1a,0xae,0xb7,0x4d +,0x76,0x1e,0xa9,0x95,0x2f,0x29,0x44,0xb8,0x9e,0xae,0x5a,0x2c,0x2b,0x2c,0xa1,0x64,0x4c,0x69,0x29,0xbe,0xd6,0xbb,0x25,0x2b,0x64,0x9f,0x96,0x32,0x25,0x2e,0x3f,0xa3 +,0x9d,0xba,0x3d,0x23,0x26,0x9f,0xa1,0x2b,0x45,0x2f,0xeb,0xa6,0x4d,0xc8,0x26,0x17,0x9a,0x96,0xd0,0x65,0x21,0x28,0xaa,0x9b,0x31,0x32,0x22,0x4f,0x9e,0xc4,0x31,0x20 +,0x27,0xbf,0x9e,0x2d,0x2f,0xe5,0x49,0xa7,0xad,0x20,0xc9,0x48,0x3d,0x9c,0x9e,0x24,0x1e,0x1b,0x2b,0x90,0xaa,0xcf,0x35,0x16,0xcf,0x97,0x52,0x32,0x32,0x41,0x95,0x9a +,0x23,0x24,0x25,0xb4,0x99,0xb1,0xc6,0x24,0x1a,0x5f,0xa5,0x3c,0xd1,0x42,0x29,0xa3,0xad,0x3d,0x2e,0x28,0xcf,0x9b,0x9c,0x40,0x26,0x1e,0xc6,0x96,0xa5,0x33,0x13,0x1d +,0xad,0x97,0xba,0x1e,0x3e,0x22,0xae,0x9b,0x4c,0x2c,0x1d,0xac,0x98,0xb7,0x2b,0x1e,0x1f,0xa3,0x91,0x55,0x1f,0x2b,0x26,0xa3,0xa9,0x31,0x3c,0x1f,0xb1,0x93,0xb5,0x22 +,0x28,0x27,0xa8,0x8e,0xc1,0x1f,0x24,0x21,0x9d,0x9c,0x2a,0x1b,0x1b,0xc3,0xa3,0xad,0x2c,0x2b,0x1b,0xfd,0x8f,0xa2,0x46,0x2e,0x2a,0xa8,0x96,0x36,0x1a,0x26,0x3a,0x96 +,0x99,0x1d,0x1e,0x17,0x32,0x8e,0x9d,0x26,0x4f,0x1f,0xcb,0x8c,0xbb,0x1e,0x1a,0xd8,0x90,0x97,0x24,0x28,0x1f,0x1b,0x95,0x9c,0x27,0x15,0x21,0x9d,0x8e,0xcf,0x1c,0x1d +,0x22,0x9c,0x8c,0xc9,0x17,0x1a,0x1f,0x96,0x95,0x35,0x28,0x0f,0x26,0x8d,0xb2,0x23,0x1b,0x1c,0x9e,0x96,0x36,0x4c,0x28,0x1a,0x8f,0x8e,0xfa,0x20,0x18,0x2e,0x90,0xad +,0x2d,0x24,0x14,0xa7,0x8d,0x36,0x1f,0x20,0x16,0x92,0x8a,0xbf,0x3b,0x19,0x21,0x8e,0x9d,0x29,0x26,0x25,0xdf,0x94,0x3b,0x1d,0x1e,0x13,0x91,0x8e,0x30,0x23,0x1b,0x3e +,0x96,0xb4,0x20,0x24,0x1c,0x99,0x8a,0xbe,0x1f,0x0f,0x1b,0x95,0x96,0x26,0x1d,0x14,0x2d,0x8c,0xa7,0x23,0x31,0x1e,0x9f,0x8f,0x4e,0x2f,0x1f,0x18,0x9d,0x94,0xb3,0xba +,0x25,0x23,0xaa,0x49,0x3e,0xc1,0x16,0x4c,0x8c,0xa2,0x2a,0x37,0x21,0x9c,0x91,0x2a,0x2d,0x16,0x11,0x9b,0x8d,0xb9,0x2b,0x15,0x18,0x9d,0xce,0x17,0xc9,0x23,0xde,0x8e +,0xbc,0x4c,0x3e,0x19,0x9d,0x90,0x2e,0x2f,0x19,0x1d,0x92,0x9e,0x2f,0xad,0x22,0x2d,0x9f,0x57,0x3d,0x3b,0x1d,0xa8,0x96,0x32,0xaa,0xc9,0x47,0x9a,0x5a,0x22,0xf3,0x19 +,0x2b,0x99,0xc6,0xad,0xb3,0x0f,0x2c,0xa6,0x20,0xb6,0xf6,0x27,0xa5,0x37,0x21,0x9c,0xb7,0xb5,0x9a,0x22,0x34,0x33,0x15,0xb7,0xad,0x1b,0x9a,0xad,0x19,0x9e,0xc4,0x2e +,0xa7,0x1f,0x1f,0x98,0xd7,0xab,0x99,0x29,0xbe,0xc6,0x1a,0xa8,0xb6,0x18,0xa9,0xb0,0x1d,0xac,0xae,0x39,0x9c,0x52,0xb1,0xa4,0x1a,0x2c,0x2b,0x2c,0x9e,0xb2,0x2b,0xce +,0x36,0x3e,0x9b,0xb0,0xc8,0xbc,0x10,0xbc,0xb9,0x0e,0x2b,0xb1,0x92,0x8d,0xaa,0x14,0x1a,0x0c,0x3e,0xb1,0x21,0xaa,0x51,0xaa,0x97,0xae,0x3c,0x8a,0xa4,0x0d,0x09,0x00 +,0x06,0x3d,0x86,0x81,0x81,0x8c,0x8f,0x1c,0x0d,0xb9,0x3a,0x4d,0x9a,0x21,0x0c,0xde,0xa6,0x3a,0x29,0x5e,0x12,0x0c,0x0d,0xab,0x9b,0xa3,0x37,0x2a,0x8c,0x89,0x93,0x17 +,0x22,0xef,0xb2,0x08,0x0f,0xa1,0x86,0x82,0x8f,0x29,0x09,0x1b,0x0c,0x2c,0x2f,0xb5,0x37,0xa9,0x90,0x39,0x14,0xaf,0x9f,0x15,0x22,0x2e,0x11,0x13,0x95,0x86,0x87,0x97 +,0xaf,0x2d,0x20,0x34,0x23,0x11,0x1a,0x99,0x91,0x92,0x9f,0x26,0x2b,0xbb,0x3b,0x0b,0x12,0xa8,0x99,0x3e,0x0f,0x0b,0x08,0x28,0x8c,0x83,0x9a,0xa4,0xae,0x3f,0x33,0x93 +,0x93,0x44,0x90,0x8f,0x23,0x03,0x09,0x10,0x14,0x2b,0xbe,0xad,0xbc,0xad,0x8e,0x86,0xa9,0x0a,0x16,0xa7,0xb3,0x3f,0x28,0xac,0x98,0xab,0x40,0x1e,0x4c,0xa0,0x96,0x1c +,0x0a,0x22,0x23,0x94,0x88,0x8d,0x2f,0x0f,0x1c,0x0e,0x0b,0x19,0x9c,0xb0,0x3e,0x4d,0x2e,0x9e,0x8c,0x93,0xc4,0xca,0xb7,0x1f,0x0e,0x18,0xaf,0x9a,0x8e,0x88,0x9a,0x61 +,0x3c,0x13,0x0f,0xb5,0xa0,0xb4,0x27,0x2e,0x91,0x9b,0x1f,0x07,0x00,0x04,0x23,0x8e,0x89,0x91,0x9c,0x93,0x8f,0x99,0x19,0x0b,0xd0,0x8f,0x96,0x27,0x0a,0x14,0xa0,0x8a +,0x93,0x19,0x0a,0x0e,0x16,0xf2,0xaa,0x30,0x16,0x32,0x87,0x86,0xa8,0x2e,0x1b,0xf7,0x3e,0x49,0x4e,0xaf,0x8e,0x91,0x8c,0xa1,0x18,0x02,0x15,0x92,0xa9,0x0e,0x06,0x0e +,0x34,0x8b,0x84,0x8e,0x2a,0x11,0x16,0x1c,0x36,0xaf,0xa1,0x97,0x8f,0x5e,0x1b,0x0f,0x0f,0x36,0x21,0x28,0x66,0xa1,0x8d,0x92,0xa8,0xa8,0x8c,0x98,0x16,0x08,0x10,0x39 +,0xa8,0x2d,0x08,0x0a,0xe0,0x8e,0x87,0x86,0xa1,0x47,0xb2,0xcc,0x21,0x18,0xdb,0x8c,0x86,0x8b,0x1a,0x01,0x08,0x1e,0xb2,0xe8,0x1d,0x0c,0x13,0x2d,0x97,0x8b,0x9a,0xb8 +,0x39,0x2f,0x29,0x28,0x2f,0xad,0x8b,0x89,0x91,0xc9,0x1c,0x47,0x20,0x1f,0x1e,0x0c,0x0e,0x62,0x91,0x96,0x9f,0x44,0x22,0x22,0x3e,0x30,0x23,0x2b,0x26,0xad,0x91,0x99 +,0x92,0x8e,0x94,0x9d,0x19,0x05,0x07,0x1b,0xa4,0x93,0x8c,0x94,0x99,0x9e,0x25,0x0b,0x0f,0x2e,0x2b,0x4a,0x21,0x24,0x9a,0x99,0x1a,0x04,0x0a,0x1d,0xb0,0x8d,0x90,0xa5 +,0xa0,0x8e,0x89,0x9a,0xac,0xab,0x30,0x2e,0x2a,0x0c,0x0b,0x68,0x8b,0x97,0xbc,0x1e,0x07,0x0c,0x24,0xa7,0x9a,0xa5,0x27,0x21,0xc1,0xbd,0xbf,0xb4,0x9d,0xa1,0x99,0x5f +,0x14,0xc0,0x9d,0x92,0x9e,0x32,0x14,0x23,0xb0,0x9a,0xa8,0x13,0x0b,0x12,0xbe,0x95,0x8e,0xa1,0x19,0x15,0x15,0x1b,0x55,0xae,0x9a,0x96,0x99,0x3e,0x0d,0x0d,0x2b,0x8d +,0x89,0x8e,0x9c,0xbc,0x3f,0x19,0x46,0xac,0xa5,0xbe,0x23,0x0b,0x0c,0x23,0x3a,0x25,0x1f,0x1f,0x26,0xb0,0x98,0x8f,0x9d,0x95,0x8f,0xa7,0x1f,0x33,0x45,0xb9,0x95,0x3a +,0x14,0x1b,0x30,0xcd,0xa5,0xbe,0x15,0x17,0x67,0xae,0xaf,0xa5,0xaf,0xcf,0xa7,0x26,0x1f,0x25,0x3f,0xa4,0x94,0x92,0xc7,0x23,0x2a,0xcc,0xfe,0x33,0x2a,0x28,0x2b,0xbc +,0xaa,0x58,0x30,0x26,0xbf,0x9f,0xa4,0x53,0x1b,0x29,0x2d,0xac,0xaa,0xf0,0xa3,0xa0,0xaf,0xc8,0x13,0x0a,0x1c,0xbd,0x98,0x91,0x9f,0xa4,0x97,0xd6,0x3c,0x39,0x33,0xae +,0xb0,0x17,0x1a,0x3b,0x4c,0xf5,0x1a,0x17,0x1c,0x1e,0x63,0xa2,0x9c,0x8f,0x89,0x9e,0x43,0x51,0xcd,0xab,0xb1,0x33,0x18,0x0e,0x21,0xa4,0x9a,0x97,0x37,0x0d,0x0e,0x16 +,0x28,0xc1,0x97,0x9c,0xaa,0xbf,0x1b,0x28,0xb2,0x8d,0x8c,0x95,0xac,0x1f,0x1e,0x43,0xa9,0xc5,0x3c,0x1b,0x0c,0x1f,0xb9,0xe5,0xc7,0x65,0x2c,0xbf,0xa1,0xc0,0x9f,0xc3 +,0x35,0xbe,0xac,0xb8,0x4a,0x27,0x2b,0xd4,0x56,0x36,0x15,0x18,0xc8,0xa1,0xa2,0x9c,0x9b,0x9c,0xbe,0x5f,0x31,0xb7,0xa9,0xc0,0x2d,0x1c,0x1b,0x17,0x1f,0x19,0x5c,0x29 +,0x2e,0x37,0x5f,0x93,0x89,0x8a,0x9b,0xb0,0xd4,0xe9,0x2a,0x2b,0x26,0x46,0xdc,0x53,0xd9,0xe9,0xc2,0x19,0x14,0x17,0x1c,0xc3,0xb0,0x9e,0xa0,0xa9,0xb8,0x20,0x2b,0xaf +,0x96,0xa3,0xb0,0xb9,0xd1,0xbc,0xbe,0xa8,0x2b,0x24,0x1d,0x1b,0x27,0x29,0x3e,0xdf,0xba,0xbc,0xd8,0xd8,0xac,0x9b,0xaa,0x36,0x1d,0x1d,0xc7,0xa5,0x9a,0xab,0x52,0x32 +,0x16,0x11,0x36,0xab,0xae,0xa0,0xa2,0x9d,0x98,0xa7,0x74,0x4b,0x4e,0xfa,0x25,0x14,0x1a,0x27,0x29,0x34,0x5d,0xc7,0xcd,0x3b,0x35,0xd0,0xa8,0x95,0x8f,0xb5,0xb0,0xb4 +,0xb5,0xb2,0x25,0x21,0x2a,0x49,0x29,0x2f,0xb6,0xa3,0xd0,0x20,0x1d,0x23,0x3b,0x33,0x2b,0x40,0x38,0x3e,0x45,0xb3,0x94,0x90,0x9a,0xa2,0xa3,0xbf,0xc6,0xcb,0x22,0x2f +,0x28,0x25,0xba,0x2a,0x23,0x3a,0x40,0x34,0x56,0xd4,0xc5,0xa6,0xae,0x9f,0xaa,0xe1,0xbc,0x6a,0x2d,0x35,0x3f,0x1e,0x1a,0x1e,0x25,0xad,0x99,0xa0,0xa6,0xaa,0xaf,0xb2 +,0xbd,0x2c,0x48,0xb2,0xaa,0x3d,0x1e,0x25,0x1e,0x2f,0x23,0x1f,0x28,0x3d,0xed,0xbf,0xb9,0x99,0x8c,0x95,0x93,0xb7,0x1b,0x1f,0x36,0x45,0xba,0xaf,0xc5,0xbd,0xd0,0xc3 +,0x3d,0x1c,0x18,0x17,0x1e,0x48,0xc8,0x3c,0x48,0xa0,0x9d,0xaf,0x66,0x2d,0xc0,0xa0,0xab,0xaa,0xa1,0xab,0x39,0xab,0xdf,0x24,0x1f,0x10,0x19,0x1e,0x2f,0xae,0x9c,0xb3 +,0xa3,0x95,0xaa,0xb3,0x20,0x18,0x26,0xfc,0xae,0xa7,0xa7,0x3b,0x3b,0x2d,0x3b,0x60,0xc0,0x32,0x2e,0xbb,0xac,0x9c,0x96,0x93,0x9c,0xb1,0x1b,0x19,0x0f,0x0f,0x2d,0xd1 +,0xcc,0x2a,0x23,0x63,0xa4,0xa5,0xa9,0x23,0x29,0xab,0x9a,0x9d,0xa4,0xb7,0x3c,0xc7,0x46,0x2f,0x37,0x67,0x40,0xd1,0xc2,0x40,0x48,0x2e,0x35,0xad,0xd2,0x18,0x17,0x15 +,0x2b,0xa8,0xae,0xaa,0x9f,0x94,0x91,0x98,0xad,0x6a,0x79,0x33,0x2a,0x27,0x2c,0x30,0x39,0x32,0x29,0xc6,0xc3,0x3d,0x2b,0x2e,0xd2,0x9f,0x9f,0xc7,0xb9,0xa4,0xa9,0x52 +,0x1e,0x16,0x27,0xd1,0x69,0x2a,0x44,0xa6,0x9e,0x9f,0xac,0xc7,0x32,0xbe,0xb4,0xce,0x6d,0x33,0x3b,0x48,0xb0,0xc3,0x4f,0x1c,0x0c,0x0f,0x1b,0xb4,0x9e,0xa8,0xae,0x9e +,0x9f,0xa1,0x9b,0xae,0xb0,0xc3,0x30,0x18,0x1e,0xbc,0x9c,0x98,0xa4,0x36,0x19,0x1a,0x1a,0x1d,0x29,0xd8,0x52,0x20,0x2c,0xaf,0x9d,0x9d,0xaa,0xd1,0xc9,0xa9,0xa9,0xd3 +,0xad,0x98,0xa0,0xc2,0x2b,0x1c,0x19,0x18,0x25,0x2b,0x3e,0x43,0xbd,0xa5,0x99,0x94,0xa0,0x2e,0x19,0x28,0x3c,0xbb,0x41,0x27,0x31,0xce,0xa7,0xa6,0x41,0x2b,0x39,0xc5 +,0xb0,0xce,0xd4,0xab,0x97,0x93,0xad,0x2b,0x1c,0x19,0x34,0x34,0x1c,0x16,0x2f,0xbb,0xac,0xa5,0xb3,0x2a,0x1a,0x45,0xaa,0x99,0xaa,0x2a,0x3d,0xb9,0x92,0x95,0xac,0x22 +,0x1b,0xca,0xc4,0xe9,0x22,0x2d,0x3c,0xc8,0xb2,0xb4,0x3f,0x15,0x14,0x18,0x3e,0xb9,0xbd,0xa8,0x9a,0x8f,0x8f,0x9f,0x3d,0x3f,0xac,0xcb,0x26,0x13,0x14,0x36,0xda,0xb4 +,0xad,0xae,0xbd,0x1d,0x1e,0x58,0xc9,0xb3,0xb5,0xae,0xab,0xb0,0xd6,0x29,0x37,0x32,0x32,0x4c,0x21,0x1e,0x34,0x9b,0x92,0x97,0xba,0x25,0xc9,0xa0,0x9f,0x3f,0x21,0x28 +,0x4d,0x9d,0xa1,0xc9,0x1e,0x0f,0x12,0x27,0x6e,0x3d,0x36,0x3f,0xae,0x96,0x95,0x9c,0x66,0x3d,0xec,0x44,0x2e,0x18,0xcb,0x98,0x93,0xa7,0x2d,0x2a,0x35,0x68,0x2c,0x1c +,0x10,0x17,0x43,0xbd,0xa8,0x9f,0x5e,0x33,0xbf,0x98,0x9d,0xdc,0x30,0x2c,0xac,0x93,0x92,0x62,0x18,0x15,0x2e,0xb7,0x3c,0x17,0x23,0xba,0xa2,0x9d,0xa7,0xa2,0xc5,0x39 +,0x33,0x30,0x1c,0x11,0x2a,0xb3,0x9e,0xa2,0xb6,0x38,0x3b,0xc4,0xab,0xaf,0x2b,0x2f,0xb7,0x97,0x99,0xb7,0x2b,0x40,0xa4,0xb1,0x29,0x13,0x0d,0x1a,0xbe,0xa1,0xb6,0x3b +,0x23,0x49,0x9e,0x9d,0xbd,0x1c,0x1f,0xb1,0x9b,0xa2,0xa8,0xc1,0xbd,0xb6,0xa4,0xa1,0x2d,0x17,0x1e,0x4d,0xb9,0xaf,0x48,0x3d,0x2a,0x2d,0x36,0x26,0x1e,0x29,0xe8,0xc9 +,0x9b,0x93,0x96,0xa0,0x5a,0xa8,0xad,0x23,0x1e,0x29,0xc4,0x4e,0x2a,0x22,0x3b,0x95,0x93,0xb5,0x13,0x16,0x2c,0xb6,0x94,0xae,0x39,0x28,0x34,0x38,0xa8,0xab,0x27,0x17 +,0x1a,0x4f,0xa9,0x9c,0xaa,0xae,0xbf,0x9c,0xaa,0xb6,0x2e,0x2e,0xc5,0x36,0x4a,0xce,0xae,0xce,0x4c,0x25,0x1f,0x1c,0x2b,0x2b,0xc2,0xbe,0xd4,0xaf,0xb1,0x98,0x9f,0xaf +,0x25,0x1c,0x33,0xa7,0x98,0xb1,0xbf,0xf2,0x2f,0xbf,0xa5,0x35,0x18,0x16,0x1c,0x39,0xca,0x29,0x3b,0xb7,0xaf,0x9f,0x9f,0xb1,0x1f,0x4a,0xac,0xa4,0xaa,0x4f,0x52,0x39 +,0xaa,0xb4,0x36,0x14,0x1a,0xe0,0xb8,0xa6,0xbb,0x39,0xce,0xba,0xbe,0xac,0x49,0x2d,0x20,0x2b,0x28,0xd6,0x9d,0xa5,0xb1,0x4a,0x27,0x43,0x3e,0x3f,0xa7,0x9e,0xb7,0x2a +,0x2f,0xbd,0x97,0x9d,0xc6,0x1e,0x14,0x28,0xbe,0x3a,0x36,0x53,0x38,0x2a,0x4e,0xb2,0xb7,0x5d,0x2f,0xc2,0xbc,0xaa,0xa4,0xa6,0xbc,0xae,0xa1,0xab,0x65,0x32,0x2f,0x35 +,0x2f,0x2e,0x2e,0x29,0x38,0x3f,0x5b,0x28,0x34,0x2e,0x30,0xaf,0x9e,0xa3,0xab,0xa8,0xc1,0xca,0x75,0xbe,0x4b,0x29,0x30,0x75,0x50,0x2c,0xd5,0xc1,0xce,0xa9,0xa7,0x3e +,0x2e,0x47,0xbc,0x55,0x2c,0xd4,0xcf,0xd0,0xdc,0x3f,0x31,0x2e,0xcb,0x5a,0x3e,0xaa,0xb0,0xbf,0x30,0x4f,0x9e,0xaa,0x54,0x3d,0x3e,0xc1,0xaf,0x46,0x2c,0x2a,0x6b,0xef +,0xb2,0xb7,0x1e,0x19,0x2c,0x2f,0xac,0x9c,0xb0,0x5e,0x36,0xc8,0xb9,0xae,0xb1,0xad,0x5b,0xdf,0x5e,0xda,0xc5,0xaf,0xad,0x2e,0x26,0x1d,0x20,0x29,0x42,0x3e,0xb7,0xcd +,0xd3,0x43,0xbd,0x9b,0xa6,0xa3,0xb8,0x4e,0x40,0x4e,0x4a,0xcc,0x58,0x4b,0x37,0x29,0x1f,0x21,0xbf,0xae,0xc6,0xae,0xda,0x3d,0xb1,0xa4,0xc3,0x23,0x29,0x49,0xbc,0xb6 +,0xbb,0x3a,0x2a,0x2a,0x45,0x9f,0xa6,0xb5,0x2f,0x1a,0x30,0xa7,0x95,0x99,0xd2,0x1c,0x1c,0x2c,0xd7,0xa9,0xa6,0xb6,0x61,0x2e,0x47,0xaf,0x4d,0xf3,0x7e,0x33,0x23,0x27 +,0xb7,0xb6,0xba,0xb7,0x4f,0x3d,0x48,0x5b,0x5d,0xc4,0xbc,0xc8,0x2a,0x2a,0xca,0xad,0x3d,0x3c,0xb0,0x50,0x2c,0x33,0xaa,0x9f,0x9d,0xa2,0xa7,0xcc,0x2b,0x27,0x41,0xea +,0x2d,0x2f,0xdc,0x42,0x27,0x2c,0x2e,0x3c,0x30,0xf1,0xba,0xb2,0xd2,0xea,0xbc,0xbc,0xa1,0x9a,0xa0,0x3c,0x6c,0x2d,0x29,0x58,0xc0,0xce,0x37,0x55,0xe5,0x3b,0x25,0x36 +,0xde,0x72,0x2c,0x2a,0x44,0xb9,0x63,0xad,0xac,0xbe,0xc7,0xc0,0xbd,0xb9,0xaf,0xc9,0xbf,0x4a,0x3c,0x75,0xa0,0xbf,0x25,0x29,0x47,0x2d,0x33,0xb0,0xa8,0xcc,0x37,0xc0 +,0x59,0x20,0x18,0x2d,0xf6,0x51,0xa4,0xae,0xd5,0xe1,0xca,0xb7,0xcd,0xad,0xb3,0xb6,0xb6,0xa9,0xbf,0x3b,0xda,0xb6,0xba,0x2c,0x1c,0x21,0x1f,0x23,0x32,0xe5,0xc3,0x39 +,0x2a,0xc9,0x9e,0xb3,0x39,0x6e,0xbb,0xc2,0xa9,0xa3,0xa6,0x78,0xc8,0xd3,0x43,0xdb,0x3a,0x37,0xd2,0xe8,0x47,0xc0,0x4f,0x38,0xc4,0xc2,0x28,0x29,0x32,0x48,0xbb,0xe9 +,0xad,0xa1,0xbc,0xd9,0xdc,0x2c,0x27,0xb3,0xbe,0x50,0x3f,0x47,0xba,0xea,0x37,0xac,0xa7,0x50,0xbf,0xdd,0x32,0x2e,0x39,0x55,0xb9,0x50,0x46,0x3d,0x2d,0x28,0x2a,0x56 +,0xe0,0x3e,0x5e,0xac,0xac,0xa5,0xa7,0xb8,0x31,0x45,0xb3,0x9f,0xa4,0x39,0x4d,0x37,0x36,0x3f,0xb9,0xe3,0x1f,0x23,0x3a,0xbf,0x39,0xc8,0xbc,0xdd,0xbd,0x68,0xb7,0xd0 +,0x36,0x5c,0xab,0x67,0x3c,0xb2,0xad,0xa7,0xc8,0x3a,0x3b,0x58,0x5a,0xae,0xc4,0x24,0x2b,0x29,0x36,0xe4,0xa8,0xaf,0x2b,0x19,0x2b,0x5e,0xb1,0xa9,0xda,0x5d,0x41,0xd3 +,0xae,0xa5,0x6d,0x2d,0x3c,0x38,0xba,0x9e,0x9d,0xcb,0x24,0x3b,0xcc,0xc5,0x32,0x2e,0x2d,0x25,0x3c,0xac,0xa9,0xbc,0x50,0x50,0xd9,0x2d,0x5a,0xbe,0xb8,0xbc,0x75,0xcf +,0xb3,0xab,0xea,0xc1,0x74,0x25,0x3b,0xc0,0xc2,0x42,0xad,0xbb,0x30,0x42,0x36,0xe2,0x39,0x39,0xd6,0x33,0x2b,0x73,0x5d,0xda,0xaa,0xae,0xcc,0x22,0x2e,0xad,0xc4,0x3b +,0xe3,0xa9,0xa2,0xb8,0x3d,0xbf,0xe5,0x25,0x2f,0x39,0x39,0x2f,0xbd,0x9f,0xae,0xdb,0x30,0x51,0x45,0x3f,0x38,0xfd,0x79,0x3a,0x56,0x7c,0x9d,0x9e,0xb4,0x37,0x31,0x51 +,0xaa,0xb1,0x6b,0xbe,0x48,0x3d,0x24,0x52,0xb8,0x37,0x1c,0x20,0xbd,0x4e,0xcb,0xa8,0xa7,0xba,0xcd,0xa8,0xbf,0x2a,0x27,0x40,0xcc,0x47,0x2f,0x37,0xb9,0xad,0x4e,0xf4 +,0xbf,0xce,0x3c,0x38,0x44,0xc3,0xa4,0xac,0xbd,0x56,0x5c,0x29,0x24,0x34,0xe4,0xd3,0x54,0xe8,0x68,0xb4,0xea,0xa3,0xaf,0x3f,0x5e,0x3c,0x59,0x39,0xbe,0xbc,0xa9,0xcf +,0x35,0xf8,0x42,0x76,0xb9,0x34,0x1f,0x2f,0xcf,0xb9,0xb6,0xbb,0xc5,0xb9,0x26,0x2c,0x32,0x6b,0xc9,0xc8,0xac,0x9e,0xa6,0x26,0x2f,0x6d,0xad,0x6d,0x2f,0x1e,0x16,0xd9 +,0x9e,0xa2,0xc6,0x4a,0x37,0x54,0xb6,0xd8,0x2f,0x2e,0xb6,0xa4,0xa9,0xa6,0xa9,0x6d,0x2f,0x1e,0x2a,0x3e,0x6a,0x2d,0x4e,0x9d,0xa6,0xc9,0x5c,0xd5,0x2d,0x3e,0x26,0x2b +,0x3d,0xaf,0x9d,0xbe,0x41,0xc5,0xc1,0xe2,0xbe,0x3f,0x29,0x26,0x4c,0xc4,0xa3,0xaa,0xc6,0x40,0x33,0x34,0x3d,0x30,0x3f,0x32,0x39,0xa2,0x9f,0xa3,0xba,0xd7,0x2b,0x24 +,0x25,0x3e,0x3b,0x35,0x2b,0x4d,0x9c,0x96,0x9c,0xca,0x36,0x28,0x6c,0xca,0xcd,0xb2,0xbf,0xc7,0xb8,0x5a,0x2a,0x2b,0x28,0x21,0x1f,0x34,0xb0,0xa2,0xae,0xad,0xb1,0xbe +,0xa9,0xb3,0x2c,0x25,0x27,0x62,0xa6,0xbd,0xd7,0x3e,0x5e,0xab,0xe3,0x2b,0x22,0x1a,0x3b,0xb5,0xab,0x9f,0xad,0xbb,0xba,0x3d,0x28,0x21,0x1f,0x3f,0xd9,0xb1,0xbc,0xbf +,0xae,0xa3,0xa4,0x5f,0x26,0x24,0x3e,0x63,0xc6,0xc5,0x42,0xc5,0x9d,0xa4,0xae,0x46,0x1c,0x15,0x1f,0xb5,0x98,0x99,0xc1,0x2b,0x31,0xcd,0xdc,0x3e,0x2d,0x2f,0x43,0xd4 +,0xb2,0xa7,0xa8,0xa7,0xbc,0x34,0x37,0x29,0x24,0x30,0x2f,0x3c,0xb9,0xaa,0xa3,0xb1,0x42,0x33,0x30,0x24,0x2f,0x3f,0x73,0xaa,0xb5,0xa0,0xa4,0xae,0x30,0x1e,0x1d,0x1f +,0xc1,0xa9,0x99,0xb0,0x36,0x40,0xa0,0x9f,0x6f,0x37,0x18,0x1d,0x29,0xdd,0xaa,0xa7,0xa9,0xbc,0xb5,0x45,0x27,0x25,0x34,0xc3,0xc8,0xab,0xb5,0xb8,0xaa,0xad,0xc1,0x2d +,0x1d,0x1e,0x32,0x3e,0xb0,0xba,0xbf,0xa2,0xa1,0xa9,0x58,0x1d,0x1d,0x26,0x2c,0x36,0x38,0x3f,0xb4,0x9c,0x97,0xa4,0x27,0x1b,0x19,0xce,0x9f,0x9b,0xaf,0x2c,0x3f,0xbe +,0x9f,0xde,0x2e,0x19,0x1b,0x2b,0xd6,0x9d,0xa0,0xa6,0xb4,0xaf,0xff,0x3e,0x2b,0x29,0x47,0x29,0x3a,0xc5,0xad,0xa0,0xac,0xc4,0x3b,0x2a,0x20,0x3b,0xce,0x41,0xbc,0xb2 +,0xc0,0xb2,0x9f,0xae,0x27,0x21,0x2c,0xf2,0x47,0x2f,0x25,0x34,0x9d,0x99,0xa2,0x4f,0x17,0x13,0x2a,0xa8,0xa5,0xb0,0xae,0xb7,0xb8,0xaf,0xab,0x37,0x21,0x28,0x32,0xde +,0xb4,0xca,0xba,0xa5,0xab,0x5e,0x2d,0x1e,0x1a,0x4a,0xc9,0xc7,0xaf,0xaf,0xa8,0x9d,0x97,0xa6,0x21,0x17,0x19,0x27,0x48,0x50,0x2f,0x46,0x9c,0x95,0x9f,0x3e,0x1c,0x1d +,0xbd,0xb3,0x41,0x3f,0x2d,0x40,0x9f,0x9a,0xb1,0x1e,0x15,0x20,0x30,0xb8,0xa4,0xa1,0xad,0xaf,0xac,0xb0,0x3c,0x20,0x1f,0x2c,0xd6,0x47,0x49,0xb7,0x9c,0x9d,0xa2,0xb9 +,0x25,0x1b,0x28,0x3f,0x2d,0x52,0xbc,0xb1,0x9f,0x9c,0xb0,0x30,0x23,0x2c,0x2f,0x2f,0x68,0x42,0xdf,0xa2,0x91,0x92,0xbf,0x1d,0x14,0x1f,0x44,0xbf,0x2f,0x1e,0x3d,0xb6 +,0x9a,0x9b,0xed,0x26,0x26,0x2d,0x37,0xbc,0xad,0xb3,0xad,0xb6,0xba,0xc7,0x22,0x18,0x1d,0x2e,0xeb,0xbd,0xad,0x9d,0x9a,0x9a,0xa6,0x2f,0x1f,0x23,0x46,0xcf,0x26,0x23 +,0xcf,0xa1,0x9c,0x9e,0xbb,0x1c,0x19,0x2f,0xdc,0xbf,0x32,0x21,0x54,0x9b,0x8e,0x95,0xd5,0x18,0x19,0x2c,0xcb,0xb6,0x30,0x2c,0xbe,0xa8,0xac,0xb9,0x22,0x2c,0xb9,0xbe +,0x3b,0x5d,0x4c,0xc6,0xb4,0x36,0x3d,0x38,0x34,0xbd,0x97,0xa8,0xcd,0xae,0xb3,0x23,0x1f,0x39,0xf9,0xf5,0x24,0x2d,0xc6,0xb0,0xdb,0x3a,0xac,0x20,0x2c,0x85,0x83,0x0d +,0x0d,0x80,0x9f,0x9e,0xa4,0x0e,0x17,0x07,0x16,0x09,0x17,0x04,0x00,0x05,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01,0x01,0x03,0x04,0x08,0x09,0x0d,0x1c,0xc6,0xb6,0x92 +,0x87,0x8b,0x8d,0x85,0x80,0x84,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x86,0x83,0x8a,0x8e,0x88,0x8f,0x9d,0xae,0xab,0xce +,0x1e,0x13,0x11,0x0a,0x05,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x01 +,0x05,0x03,0x0c,0x14,0x1d,0x29,0x24,0xac,0x93,0x8a,0x88,0x87,0x85,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x84,0x84,0x87,0x8c,0x8f,0x9d,0x9b,0xb4,0x3c,0x1e,0x18,0x0e,0x06,0x04,0x03,0x03,0x01 +,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x02 +,0x02,0x04,0x05,0x07,0x06,0x0b,0x0b,0x0a,0x15,0x1b,0x17,0x1f,0x46,0xbf,0xb9,0xa6,0x9a,0x95,0x8e,0x8b,0x8a,0x88,0x86,0x84,0x84,0x84,0x81,0x81,0x80,0x82,0x84,0x80 +,0x80,0x80,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x81,0x82,0x80,0x81,0x80,0x81,0x81,0x81,0x82,0x85,0x83,0x81,0x85,0x86,0x86,0x85,0x85,0x88,0x86,0x8a +,0x8b,0x8b,0x8c,0x8b,0x90,0x8d,0x8b,0x8d,0x8d,0x8e,0x8c,0x92,0x8f,0x8e,0x8e,0x91,0x97,0x91,0x93,0x8d,0x90,0x96,0x9c,0x9d,0x9f,0x9d,0x9d,0xb0,0xae,0xed,0xbd,0x3f +,0x33,0x2a,0x19,0x0f,0x0c,0x0b,0x07,0x07,0x05,0x06,0x05,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x02,0x03,0x05,0x07,0x08,0x0c,0x0e,0x0f,0x11,0x1c,0x3f +,0xb8,0x9a,0x91,0x8b,0x89,0x87,0x82,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x82,0x83,0x85,0x87,0x87,0x87,0x8d,0x9a,0x9d,0x9f,0xa4,0xc1,0x3f,0x2a,0x1c,0x0f,0x0d +,0x0b,0x07,0x05,0x05,0x04,0x02,0x01,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01 +,0x01,0x02,0x03,0x02,0x02,0x04,0x07,0x07,0x06,0x08,0x0c,0x0d,0x0c,0x0e,0x11,0x12,0x17,0x20,0x2c,0x27,0x36,0xbe,0xb3,0xb5,0xbc,0xa5,0x9f,0x9d,0x98,0x93,0x91,0x96 +,0x90,0x8b,0x8b,0x8c,0x8b,0x8b,0x8c,0x8b,0x87,0x86,0x88,0x89,0x87,0x87,0x89,0x88,0x87,0x8b,0x8f,0x8d,0x8a,0x89,0x8c,0x8e,0x8e,0x93,0x94,0x92,0x93,0x9d,0x9c,0x98 +,0x9b,0xa8,0xa4,0xa0,0xa9,0xbf,0x4f,0xf8,0x40,0x2e,0x3d,0x55,0x2e,0x26,0x39,0x45,0x22,0x1d,0x21,0x23,0x1e,0x1d,0x26,0x2a,0x21,0x1b,0x1b,0x21,0x20,0x23,0x34,0x23 +,0x1c,0x2b,0x51,0xce,0x3f,0x4a,0x74,0xd9,0xc0,0xa9,0xa0,0xb8,0xac,0x9b,0x98,0x9a,0x97,0x8f,0x94,0x9c,0x94,0x8c,0x93,0x94,0x8d,0x8c,0x8d,0x8e,0x8a,0x8b,0x91,0x94 +,0x8e,0x8e,0x8e,0x8e,0x8d,0x8f,0x98,0x98,0x97,0x9b,0xa8,0xaa,0xa6,0xcd,0xd3,0xb0,0xb6,0xec,0x34,0x41,0x2d,0x29,0x2f,0x35,0x2b,0x1c,0x20,0x3f,0xea,0x2d,0x2d,0x2d +,0x29,0x2b,0x41,0xf9,0x2c,0x2a,0x31,0x57,0x49,0x3c,0xe9,0x45,0x26,0x24,0x4b,0xef,0x33,0x38,0x60,0x39,0x2a,0x5e,0xb9,0x34,0x1d,0x2e,0x5a,0x2c,0x38,0xe3,0x5f,0x2c +,0x2b,0x69,0x3c,0x31,0x36,0x4a,0x32,0x21,0x3a,0xbf,0x5b,0x35,0x38,0x25,0x23,0x3c,0xc7,0xe1,0x27,0x29,0x2f,0x78,0xed,0x44,0x4f,0x27,0x24,0x31,0xc7,0xdb,0x2f,0x2d +,0x39,0x39,0x3a,0xbf,0xc8,0x33,0x1f,0x30,0xc8,0x6e,0x6e,0x4e,0x44,0x31,0x40,0xba,0x4d,0x2e,0x30,0x60,0x3e,0x2c,0x54,0xba,0xc7,0x38,0x50,0x3a,0x31,0x4e,0xb2,0xbb +,0x29,0x35,0xcb,0xad,0xeb,0x5b,0xe7,0x2c,0x2e,0x5b,0xb9,0x5b,0x3e,0xdf,0xde,0x42,0xe4,0xbc,0x76,0x37,0x2d,0xc5,0xb3,0xcc,0xcb,0xe4,0x48,0x3d,0xaf,0xad,0x38,0x2d +,0x37,0xee,0xd2,0xfa,0xe2,0xcf,0x4c,0x3b,0xc7,0xc3,0x66,0x3c,0x50,0xfc,0x3e,0xbd,0xaf,0xad,0x40,0x2d,0x54,0x34,0x4b,0xc3,0xc7,0x33,0x35,0xcf,0xae,0xc5,0xf1,0xbc +,0x68,0x3a,0x38,0xb7,0xc5,0x5d,0xd8,0xd8,0x43,0x3a,0xb5,0xbf,0x38,0x23,0x38,0xaf,0xac,0xba,0x3f,0x2f,0x2e,0xf9,0xab,0xb8,0x36,0x2d,0x62,0xf5,0x65,0xab,0xaf,0xe0 +,0x2f,0x36,0xef,0xd4,0xb6,0xbc,0x46,0x24,0x2e,0xc5,0xaa,0xc8,0x3d,0x35,0x39,0x56,0xd3,0xad,0xbf,0xc3,0x4a,0x4b,0x4d,0x42,0xbd,0xd4,0x3a,0x2a,0x49,0xbf,0xb3,0x6a +,0x2e,0x39,0x3a,0xb9,0xa7,0xdd,0x25,0x29,0xbc,0xab,0xb6,0xb7,0xdd,0x34,0x2e,0x5d,0xb6,0xe6,0x58,0xcb,0x4d,0x2f,0x3e,0xb9,0xa9,0xca,0x2c,0x26,0x4c,0xad,0xaa,0xbd +,0x2c,0x2e,0xd9,0xac,0xc2,0x65,0xdf,0x3e,0x39,0x2f,0xd8,0xb5,0xb9,0x6f,0x33,0x3b,0xfb,0xaa,0xac,0x39,0x20,0x2f,0xae,0x9f,0xbc,0x32,0x2b,0x3e,0xca,0xb3,0xbf,0x3a +,0x37,0x36,0x5b,0xcd,0xca,0xbc,0xb5,0x57,0x30,0x34,0xcb,0xa7,0xb3,0x6a,0x29,0x3a,0xad,0xa4,0x66,0x2b,0x3a,0x48,0xc6,0x6d,0xce,0x48,0x3c,0x3a,0x40,0xc3,0xdb,0xad +,0xb1,0x36,0x24,0x3c,0xb5,0xaa,0xb3,0x38,0x21,0x43,0xa7,0xad,0x6f,0x27,0x2c,0xdc,0xb7,0xb3,0xc1,0x43,0x45,0x3f,0x37,0x3b,0xdc,0xb4,0xea,0x2b,0x28,0x51,0xa0,0x9c +,0x55,0x27,0x3c,0xc0,0xb1,0xd5,0x32,0x2d,0x45,0xc7,0xd5,0x73,0x34,0x79,0xd9,0x31,0x75,0xbc,0xad,0xb3,0x5c,0x35,0x35,0xcf,0xa2,0xa7,0x32,0x1a,0x22,0xbb,0xa6,0xba +,0x3f,0x2f,0x55,0xaf,0xb1,0xc3,0x41,0x3b,0x36,0x42,0x6e,0xb7,0xa9,0xbd,0x2c,0x26,0x5e,0xab,0xa0,0x64,0x1f,0x1d,0xc4,0xa1,0xb5,0x56,0x27,0x3d,0xb7,0xc1,0xc6,0xb8 +,0xd6,0x44,0x40,0x50,0x49,0xb4,0xa8,0xcd,0x27,0x1e,0x3d,0xa0,0x9b,0x3b,0x18,0x22,0xae,0xa7,0xa9,0x48,0x27,0x51,0xc1,0xb0,0xe0,0x3f,0x70,0xd2,0x3c,0xb9,0xa9,0xae +,0x5c,0x23,0x24,0x41,0xa8,0xa4,0xda,0x24,0x1d,0x51,0xa8,0xad,0xaf,0x3f,0x38,0x4b,0xd6,0xc9,0xd8,0xb3,0xce,0x33,0x39,0x4a,0x54,0xa5,0xad,0x2b,0x19,0x2d,0x9c,0x9c +,0xc2,0x23,0x1c,0x49,0xa7,0xab,0x3d,0x1f,0x3c,0xa7,0xa8,0xc0,0xb6,0xdf,0x2b,0x29,0x7e,0xb4,0xcb,0x37,0x28,0x30,0x34,0xa8,0x9f,0xb4,0x47,0x1e,0x3d,0x9e,0x9f,0xba +,0x60,0xfa,0x62,0x2f,0x33,0x4e,0x54,0xcc,0xea,0x22,0x2e,0xb2,0x9f,0xb6,0x28,0x18,0x4e,0x94,0x98,0xa8,0x23,0x16,0x2f,0x9f,0xa8,0xd5,0x2f,0x2f,0x37,0x43,0xaf,0xb4 +,0xba,0x2a,0x26,0xc8,0xa9,0xcd,0x3f,0x7a,0x44,0x42,0xaf,0xac,0x41,0x2f,0x48,0xd8,0xb6,0xb7,0x3a,0x3e,0x4a,0xb4,0xb8,0x51,0x2e,0x3e,0xb9,0x3c,0x2d,0x25,0xaf,0x9a +,0xab,0x36,0x1d,0x25,0xa9,0x97,0xa9,0x43,0x1a,0x1d,0xa5,0x9c,0xaf,0xcc,0x2f,0x1c,0x24,0x66,0x63,0xdd,0x4f,0xa4,0xa8,0xb3,0xac,0x4f,0x2c,0x2b,0x4c,0xb2,0xad,0x29 +,0x2e,0x3d,0x5c,0xa3,0xa9,0x28,0x1f,0xe5,0xaa,0xc3,0x25,0x23,0xb3,0x95,0xa7,0x2d,0x27,0x5c,0xae,0xac,0xc8,0x2e,0x20,0x36,0xa7,0xaa,0x47,0x36,0x43,0x2c,0xc7,0xae +,0x4f,0x38,0x2c,0xc1,0xa4,0xa7,0xc6,0xe1,0x35,0x6a,0xa9,0xb2,0x61,0x28,0x2b,0x5a,0x60,0xb4,0xb1,0x29,0x2a,0x37,0xcf,0xbf,0x38,0x3b,0x9b,0x95,0xcb,0x1e,0x1e,0x25 +,0xbc,0x9c,0xa0,0x34,0x1a,0x46,0xb6,0xad,0xea,0x2e,0x28,0x46,0xbc,0xb3,0x5c,0x25,0x59,0x9b,0x9f,0xb6,0x32,0x1d,0x27,0x3a,0xbd,0xbd,0x38,0x31,0x49,0xaf,0x9a,0xa7 +,0x3d,0x21,0x2a,0xe0,0xc6,0x53,0x23,0x2f,0x9e,0x92,0x3b,0x1b,0x38,0xaf,0x9b,0x9f,0x32,0x14,0x23,0xab,0x96,0xbe,0x20,0x23,0x2b,0x44,0xaa,0xcf,0x2b,0x22,0x52,0x92 +,0x9d,0xb1,0x27,0x1e,0x45,0x9b,0x95,0xb9,0x2c,0x14,0x18,0x45,0xaf,0x3d,0x2a,0x46,0xaf,0x9f,0xa2,0x55,0x21,0x49,0xa3,0xa5,0x2d,0x1e,0x2a,0xc5,0xab,0xa1,0xb5,0x20 +,0x37,0xaa,0xaa,0x38,0x12,0x1b,0xa4,0x9e,0xa0,0x53,0x1e,0x2e,0x9d,0x8f,0xb7,0x17,0x0e,0x3f,0x99,0x9f,0xc5,0xc8,0xbd,0x24,0x2b,0xaf,0xb2,0x6e,0x2d,0x1e,0x33,0xb3 +,0xa8,0xb3,0x46,0x48,0xab,0xb3,0x23,0x2b,0x78,0xa9,0xaa,0x4b,0x3c,0x38,0x40,0x73,0x3a,0x1f,0x35,0xa1,0x9f,0xad,0xbf,0x1f,0x46,0x7c,0xbe,0x9e,0xc0,0x26,0x17,0xce +,0x9f,0xae,0x2d,0xda,0xd0,0x29,0x49,0xbe,0xdc,0x24,0xe9,0xa8,0xa3,0xae,0xce,0x74,0x2e,0x1c,0x33,0xc3,0x65,0xdb,0x37,0xd9,0xa8,0x96,0x95,0xd2,0x1d,0x1a,0x1c,0x6e +,0xbf,0x5b,0xcd,0x48,0x4e,0x42,0xa6,0xb0,0xb6,0xbc,0x1e,0x1f,0xbe,0x98,0xa6,0x41,0x3b,0xa1,0xaa,0x1a,0x17,0x1e,0x4e,0x41,0x24,0x5d,0xab,0xb2,0xac,0x9e,0x40,0x33 +,0x9f,0x9f,0x4d,0x22,0x1a,0x6d,0xaf,0xcd,0xaf,0x4d,0x28,0x21,0x4b,0xa5,0xbf,0x55,0xaf,0xa9,0xb9,0xb9,0xc4,0x1f,0x29,0xc9,0xb5,0xb8,0x48,0x70,0xc9,0x3d,0x3d,0x9d +,0xb9,0x1e,0x1f,0x39,0xb8,0x64,0xa1,0x9c,0x44,0x1d,0x22,0x34,0x7b,0xb8,0xc0,0xb8,0xc4,0x3e,0x3b,0x9b,0x9f,0x46,0xee,0x24,0x18,0x1e,0xd7,0x9e,0xdd,0x2b,0xc1,0xa8 +,0xee,0x2e,0xb8,0xa9,0xaf,0x31,0x46,0xbb,0x46,0xb2,0xaf,0x21,0x20,0xa0,0xc9,0x20,0x2e,0x55,0xa2,0xa6,0xd9,0xcb,0x5c,0x30,0x4c,0xcd,0xce,0x37,0x38,0xb8,0xd4,0xdd +,0xaf,0xa9,0x2c,0x1f,0x50,0xb6,0x9b,0xaf,0x3d,0x42,0x2a,0x25,0xd4,0xaa,0x1e,0x13,0x39,0x9e,0x9c,0x9f,0x98,0xab,0x2b,0x27,0x34,0x45,0x3f,0x39,0x37,0xdc,0x33,0x2b +,0xaa,0xb6,0x4c,0xdb,0x32,0x1c,0x4c,0x9f,0x97,0xa0,0xbb,0xbf,0x3a,0x2f,0x30,0x45,0x28,0x27,0x39,0xce,0xb2,0x45,0xb5,0xa0,0x33,0x2c,0xa1,0xa5,0x32,0x20,0x42,0xa2 +,0x9a,0xc2,0x2e,0x36,0x2a,0x1b,0x20,0xb3,0xaa,0xb1,0xae,0xa8,0xc2,0x3f,0xd5,0x53,0x22,0x22,0x36,0x50,0xbb,0xce,0xac,0xa9,0xaf,0xb2,0xde,0x1d,0x18,0xaa,0x9a,0xa7 +,0xbb,0xcc,0x33,0x1d,0x3d,0x6d,0x23,0x24,0x68,0xb9,0xba,0xac,0xa4,0x9d,0xa7,0x2b,0x24,0x23,0x24,0xc5,0xa5,0xa0,0xe3,0x2c,0x2a,0xcf,0xa4,0xae,0x31,0x1a,0x25,0x2d +,0xb2,0x99,0xab,0x35,0xd8,0xb0,0x76,0x3d,0x57,0x3d,0x27,0xd4,0xaf,0xa8,0x5d,0x30,0xae,0x9f,0x78,0x1a,0x1d,0x26,0xbf,0x9a,0x9f,0x42,0x29,0xcf,0xb0,0x4f,0xcc,0x6e +,0x2a,0x4d,0xbb,0x48,0x3c,0xaa,0xac,0xb1,0x2c,0x18,0x21,0x2f,0xb3,0x9a,0x96,0xbd,0x1d,0x1b,0x5e,0x9e,0x98,0xae,0x1d,0x1f,0x48,0xd0,0xaa,0x9b,0x2f,0x13,0x38,0xa5 +,0xaf,0x29,0xfa,0xae,0xc2,0xbe,0x39,0x2c,0x2e,0xba,0x9d,0x9e,0x5c,0x1a,0x20,0x2e,0xbb,0x9e,0xa9,0xca,0x33,0x61,0x31,0x2b,0xdc,0x42,0xcd,0xac,0xbd,0x25,0x34,0xb2 +,0xb4,0xaf,0xc6,0x26,0x20,0xcc,0x9f,0x9c,0xad,0x44,0x14,0x1c,0xa8,0x9b,0x9f,0x34,0x24,0x2d,0xbc,0xc8,0x37,0x2c,0x1c,0xbd,0x99,0x9d,0x4c,0x23,0xc9,0xca,0x5d,0x47 +,0x32,0x5f,0xc9,0xaf,0xa4,0xa1,0x26,0x11,0x47,0xad,0xe8,0x29,0xc1,0xa8,0xde,0xc8,0xc7,0xcf,0x68,0x50,0x4e,0xcc,0x32,0x26,0x41,0x9e,0x97,0xb0,0x20,0x0f,0x2d,0xa2 +,0x96,0xa9,0x25,0x15,0x10,0xac,0x8b,0x8f,0xc8,0x17,0x19,0x49,0xa2,0xc2,0x40,0x40,0x2a,0x37,0xb2,0x9b,0xbc,0x32,0xbb,0x4d,0x1e,0x14,0x28,0x9d,0x8f,0x95,0xb4,0x39 +,0x1c,0x19,0x46,0xb4,0x7e,0x53,0xaf,0xa2,0xcf,0x37,0x2f,0x20,0x6d,0xa7,0xa6,0x2c,0x0f,0x26,0x9d,0x8d,0xa3,0x2f,0x1c,0x17,0x60,0x97,0x94,0x2c,0x10,0x19,0xb1,0x8c +,0x8f,0xbf,0x14,0x1a,0x32,0x71,0xb7,0x2f,0x2e,0xee,0xa4,0x9c,0xc9,0x38,0x2e,0x36,0xad,0x4d,0x1c,0x28,0xad,0x91,0x9b,0xc9,0x4e,0x24,0x1d,0x25,0xc5,0x43,0x19,0x47 +,0x90,0x8f,0xde,0x22,0x1f,0x21,0x4d,0xa6,0xa4,0x2f,0x2b,0xd5,0x97,0x92,0x42,0x15,0x0e,0x32,0x98,0x9a,0xbe,0x14,0x15,0x60,0x9b,0x8f,0x9b,0x4c,0x1a,0x1d,0xdd,0xc2 +,0x34,0x28,0xd7,0x98,0xaa,0x36,0x45,0x36,0x4c,0xcd,0xc4,0x1f,0x13,0x4b,0x98,0x97,0xab,0xc3,0x3b,0x35,0x36,0x4f,0xca,0x25,0x27,0xb9,0x91,0x9b,0x25,0x23,0x1f,0x47 +,0xa6,0xa9,0x3b,0x0e,0x1a,0x99,0x8a,0x99,0x27,0x1c,0x24,0x33,0x9c,0x95,0x3a,0x0d,0x10,0xb0,0x98,0x95,0x97,0x38,0x1e,0x32,0x39,0x1d,0x1c,0x3e,0xaa,0x9f,0xa2,0xa2 +,0xd3,0x3b,0x2c,0x4d,0x5d,0x14,0x1b,0xaf,0x8e,0x98,0x4f,0xfe,0x4d,0xde,0x39,0x27,0x39,0x1c,0x1d,0x9a,0x8a,0xa4,0x1b,0x26,0x6b,0x43,0xb3,0xb5,0x19,0x0c,0x30,0x8a +,0x88,0x9f,0x24,0x11,0x1c,0x75,0xa0,0xab,0x1d,0x0d,0x25,0xa0,0x98,0x8b,0x99,0x2c,0x1a,0x38,0xdf,0x14,0x13,0x4b,0x8f,0x91,0xae,0xe3,0x32,0xdd,0x41,0x27,0x1e,0x0f +,0x21,0x8f,0x8d,0xa0,0xb9,0x66,0x34,0x26,0x39,0x65,0x27,0x16,0x32,0x91,0x8d,0xac,0x23,0x2c,0x34,0x2c,0xba,0xc2,0x0f,0x09,0xa7,0x84,0x88,0x9a,0x1b,0x16,0x1d,0x28 +,0xab,0x37,0x10,0x17,0x9b,0x8f,0x99,0x98,0xaa,0x2e,0x1c,0x4a,0x2d,0x0c,0x11,0x9d,0x90,0x95,0x9b,0x4b,0x30,0x24,0x24,0x31,0x1e,0x0f,0xad,0x89,0x93,0xaf,0x68,0x6f +,0x24,0x19,0x28,0xd7,0x2a,0x17,0xbb,0x8a,0x85,0x9d,0x0e,0x14,0x1b,0x25,0x9d,0x38,0x09,0x17,0x8f,0x84,0x8e,0xb1,0x2e,0x29,0x18,0x1e,0x2e,0x1c,0x17,0x78,0x92,0x8e +,0x99,0xa1,0xb1,0x10,0x0e,0xc3,0x3a,0x0d,0x2b,0x97,0x93,0x8f,0x9c,0xda,0x24,0x19,0x1f,0x2d,0x15,0x0e,0xaa,0x86,0x87,0xa0,0x29,0x2e,0x19,0x1d,0xb1,0x28,0x15,0x20 +,0xa7,0x8a,0x85,0x9e,0x1b,0x1b,0x0d,0x19,0xbf,0x22,0x0b,0x35,0x88,0x84,0x92,0xbc,0xdc,0x22,0x1b,0x1c,0x1d,0x17,0x1f,0x3e,0x9a,0x90,0x9e,0x9c,0x34,0x12,0x2e,0x9c +,0x2e,0x0c,0x2f,0x8b,0x88,0x99,0x53,0x1b,0x15,0x35,0xcc,0x12,0x0a,0x15,0x97,0x84,0x8b,0xba,0x32,0x34,0x14,0x33,0xbe,0x1c,0x19,0xcc,0x94,0x89,0x8c,0xe9,0x13,0x16 +,0x1c,0x25,0x34,0x1e,0x12,0x62,0x88,0x88,0x9b,0xd6,0x1f,0x1d,0x59,0x28,0x0f,0x14,0xeb,0x90,0x89,0x9d,0x46,0xa9,0x31,0x1b,0x2c,0x29,0x13,0x11,0x9f,0x87,0x93,0xc9 +,0x30,0x21,0x2d,0xa7,0x2b,0x09,0x0a,0x47,0x86,0x82,0x96,0x2f,0x2b,0x2c,0x1c,0x1d,0x18,0x11,0x24,0xa3,0x8f,0x8c,0x8f,0xcb,0x18,0x2c,0x33,0x1d,0x1e,0x17,0x1d,0x92 +,0x82,0x97,0x27,0x46,0x51,0xcf,0x2c,0x0c,0x0c,0x25,0xa7,0x96,0x90,0xb6,0xd0,0x99,0xb1,0x22,0x18,0x13,0x10,0x4e,0x89,0x88,0xab,0x31,0x3e,0x28,0x4d,0x4e,0x13,0x0c +,0x14,0xcb,0x8a,0x8c,0xb2,0x3c,0xc5,0xa7,0x3f,0x1c,0x17,0x21,0xb1,0x8e,0x8f,0xa9,0xc5,0x2d,0x1f,0x2b,0x16,0x0c,0x1d,0x33,0xb9,0x8e,0x8b,0xaa,0xcd,0xa4,0xaa,0xd9 +,0x1d,0x0b,0x0e,0xae,0x8f,0x9f,0x45,0x29,0xb3,0x93,0xd1,0x10,0x11,0x27,0x4d,0xa8,0x8f,0x98,0xac,0xd6,0x4c,0xdc,0xd2,0x20,0x0c,0x12,0x40,0x90,0x89,0xa9,0x2b,0x5e +,0xc0,0xcc,0x18,0x0c,0x1a,0xcc,0x9c,0x96,0xa7,0xb7,0x9c,0xa9,0xd0,0x2b,0x0f,0x0e,0x2f,0x9e,0x9d,0x93,0x8b,0xa8,0x0f,0x07,0x33,0x14,0x06,0x98,0x83,0x9a,0x10,0x09 +,0xd8,0x8d,0x88,0x82,0x9e,0x02,0x15,0xae,0x0a,0xa7,0x81,0xe4,0x6b,0x91,0x16,0x00,0x05,0x30,0x8b,0xc0,0x20,0x8b,0x96,0x27,0x88,0xb4,0x52,0x9b,0x19,0x0b,0x23,0x8b +,0xbb,0x09,0x00,0x97,0x84,0x4d,0xba,0x8f,0xab,0xa2,0x9e,0x19,0x15,0x20,0x95,0x89,0x2e,0x01,0x14,0x0a,0x29,0x85,0x8b,0x91,0x9d,0xac,0x24,0x1f,0x40,0xa2,0x0f,0x00 +,0xc9,0x84,0x2d,0x0f,0xc0,0x98,0x87,0x91,0xa9,0x2c,0xce,0xbd,0x0c,0x06,0x13,0x97,0x2e,0xd8,0x83,0x8f,0x19,0x05,0x26,0x9d,0x92,0x8b,0x92,0x11,0x0a,0xa5,0x9c,0x2a +,0xcd,0x4e,0x16,0xc9,0x57,0x12,0x0a,0xe9,0x86,0x8b,0x1b,0x0f,0x97,0xd6,0x2a,0x9d,0xa2,0xb9,0x1d,0x16,0xa6,0x9a,0xad,0x12,0x04,0x05,0xb9,0x89,0xc2,0x94,0x88,0x8b +,0xab,0x20,0x1b,0x0e,0x29,0x91,0xac,0x03,0x00,0x19,0x97,0x87,0x82,0x87,0x94,0xd6,0x1b,0x0b,0x14,0x96,0xa0,0x0e,0x18,0x97,0x3e,0x08,0x0d,0xa1,0x87,0x90,0x9f,0xf7 +,0x69,0xa7,0x93,0xad,0x15,0x16,0x19,0x16,0x32,0xd3,0x2c,0x19,0x39,0x8d,0x8f,0x9b,0x9d,0xac,0x20,0x0e,0xe9,0xae,0x1e,0x1b,0x9b,0x86,0x9d,0x26,0x0b,0x0e,0xca,0x9e +,0x4a,0x1a,0x57,0x96,0xac,0x29,0xad,0xa7,0xb1,0xaa,0x97,0xa8,0x12,0x10,0x12,0x19,0x9f,0x88,0x8f,0x20,0x22,0x45,0x2b,0xe2,0x28,0x38,0x33,0x94,0x8b,0x1a,0x00,0x0a +,0x98,0x8e,0x93,0x8c,0x95,0x49,0x3d,0xf5,0x43,0x46,0xcb,0x21,0x09,0x10,0x2d,0x26,0x1d,0x9b,0x83,0x8b,0xac,0xc1,0xad,0xbf,0xc9,0xb4,0x26,0x0d,0x18,0xac,0x98,0xa4 +,0x6d,0x19,0x10,0x38,0xa0,0xb4,0x9d,0x8e,0xa2,0x16,0x0c,0x26,0x1d,0x2b,0x9e,0x9f,0xbb,0x18,0x09,0x0c,0xa7,0x84,0x88,0x9d,0x27,0x25,0xd7,0x1d,0x41,0x91,0x91,0x99 +,0xab,0x25,0x0a,0x09,0x41,0xa0,0x3a,0x2b,0x70,0x9c,0x4b,0x9d,0x8d,0x99,0xa7,0x11,0x17,0x32,0xde,0x23,0x0a,0x0e,0x2e,0x93,0x8c,0xa3,0x9b,0x90,0x94,0xad,0x1d,0x1a +,0x1c,0x3c,0xa3,0xdf,0x1d,0x11,0x08,0x1f,0xa2,0x8f,0x98,0xb4,0xc2,0x3d,0x9d,0xac,0x34,0x1f,0x1e,0xa7,0xa7,0x2a,0x1c,0x21,0x32,0xb3,0x91,0x8e,0xb2,0x58,0xc2,0x58 +,0x25,0x12,0x32,0x35,0xb6,0x93,0xa1,0x2c,0x0d,0x1f,0xad,0x98,0x98,0xbd,0x1f,0x14,0x20,0xca,0x4f,0xcb,0xa0,0xa4,0x97,0xbb,0x25,0x19,0x16,0xa3,0x9c,0xcd,0x3f,0x65 +,0xa8,0xa8,0x95,0xac,0x47,0x44,0x16,0x1c,0x31,0x3c,0x2b,0x0e,0x0f,0xc8,0x9e,0x99,0x9a,0x93,0x9b,0xdb,0x4e,0x23,0x27,0xcc,0x98,0x9b,0x1f,0x0e,0x0f,0x16,0xc1,0x96 +,0x8e,0x91,0xa8,0xb7,0x2a,0x25,0x5b,0x3c,0x1e,0x18,0x2c,0x1e,0x17,0x38,0xa9,0x91,0x8e,0x9c,0xa6,0xc5,0x3a,0xda,0x3c,0x2b,0x27,0x30,0x25,0xd5,0x97,0xb3,0x2b,0x1d +,0x26,0x46,0xbb,0x9f,0x9e,0xc2,0xc4,0xed,0x40,0x22,0x22,0xb7,0xa3,0xa9,0x34,0x25,0x18,0x22,0x9f,0xa0,0xbe,0xc1,0x38,0x3a,0x3c,0xc2,0x9b,0xa2,0x9d,0xa8,0x42,0x1e +,0x1d,0x1f,0x16,0x25,0xdc,0xbb,0x9f,0xa4,0x9f,0x98,0xb1,0x37,0x14,0x14,0x4f,0xab,0xba,0x16,0x14,0x31,0xaa,0x8e,0x8e,0x98,0xb2,0x55,0x3d,0x1a,0x1f,0x5d,0x39,0xb8 +,0xbb,0x3c,0x25,0x17,0x25,0xb5,0x97,0xa1,0xae,0x9c,0xb1,0xa7,0xad,0x24,0x1d,0x15,0x21,0x3e,0x6b,0xb7,0x69,0x38,0x74,0xa9,0x9d,0x9f,0xa4,0xdb,0x2c,0x2a,0x13,0x1f +,0x2b,0xa7,0x8a,0x93,0xbd,0x17,0x0d,0x19,0x3d,0xb0,0xa6,0xb0,0xab,0xba,0xb2,0xc1,0xeb,0xee,0x2c,0xa8,0x3c,0x17,0x20,0x23,0xc1,0xac,0xaa,0xa4,0xa2,0xaa,0x6e,0x5b +,0xb6,0x31,0x3b,0x2e,0x2b,0xa6,0xbf,0x65,0x17,0x11,0x1c,0x28,0xa1,0x92,0x8d,0x8c,0x98,0xc5,0x27,0x1d,0x30,0x2a,0x32,0x13,0x13,0x27,0x20,0xa7,0x94,0x8f,0x91,0xab +,0x4e,0x33,0x29,0x26,0x24,0x61,0xc4,0xae,0x6e,0x2a,0x50,0x2c,0x2d,0x3e,0x34,0xaf,0xa0,0xa5,0xa6,0xbf,0xc3,0x34,0x25,0x1d,0x2a,0xb2,0xb5,0xbb,0x42,0x4c,0xac,0xa6 +,0x9d,0xab,0x3f,0x37,0x18,0x13,0x21,0x3d,0x9f,0x94,0x95,0xaf,0x2d,0x26,0x1a,0x2a,0x2c,0x34,0xa4,0xa1,0xa2,0xa6,0xad,0xa7,0xdb,0x38,0x1f,0x19,0x2c,0x1e,0x27,0x1f +,0x32,0x9d,0x9d,0x98,0xa4,0xbc,0xac,0x7d,0x45,0x2e,0x2b,0xaa,0xb5,0xc8,0x29,0x1f,0x1e,0x17,0x2d,0xda,0x9a,0x93,0x9f,0x9e,0xab,0xaf,0xad,0x1c,0x19,0x19,0x17,0x23 +,0x2b,0xb7,0xa5,0x96,0x93,0x9d,0x9d,0xb0,0x3a,0x1e,0x11,0x1d,0x2a,0x38,0xc9,0xb9,0x99,0xaf,0x2e,0x25,0x19,0x4a,0xae,0xa4,0xa1,0xad,0x9f,0xac,0xfa,0x35,0x24,0x42 +,0x2a,0x25,0x24,0x17,0x42,0xae,0x9b,0x9b,0xb3,0xa8,0x3c,0x2e,0x3e,0x56,0x9f,0xab,0xb2,0xbf,0x3e,0xb5,0x3c,0x1d,0x12,0x10,0x26,0x37,0xa4,0x99,0x97,0x8b,0x94,0xb4 +,0x26,0x1c,0x35,0x24,0x1e,0x17,0x16,0x43,0xbb,0x9b,0x93,0x9e,0x9e,0x5f,0x1f,0x1c,0x1f,0x43,0x48,0xb8,0xac,0xbd,0xd8,0x1c,0x1f,0x45,0xb2,0x9d,0xbe,0xbb,0xab,0xa9 +,0x99,0xb7,0x57,0x2f,0x14,0x14,0x15,0x31,0xb9,0xbe,0xa7,0xa5,0x97,0x99,0xa5,0xb5,0x25,0x2e,0x22,0x18,0x28,0x3b,0x9e,0x97,0xa5,0xca,0x21,0x29,0x2d,0x2a,0x40,0x33 +,0xaa,0xa3,0xa7,0xa1,0xbd,0xb9,0x68,0x2f,0x1e,0x17,0x26,0x30,0x37,0xb1,0xa7,0x9a,0x9e,0xb7,0x58,0x2d,0xcf,0x4b,0x2c,0x30,0x47,0xa6,0xa8,0x51,0x35,0x1a,0x1e,0x2e +,0x44,0xad,0xa1,0x92,0x9a,0xab,0xac,0xcf,0xc3,0x2f,0x16,0x11,0x0e,0x1a,0x2b,0xc1,0x94,0x8f,0x90,0xaa,0xc2,0xae,0x3f,0x33,0x1f,0x1e,0x31,0x40,0xbb,0x56,0xea,0xb7 +,0x3a,0x33,0x2a,0x37,0xc8,0xcc,0x9e,0x9a,0x9a,0xa7,0x28,0x1b,0x19,0x3a,0xb1,0x38,0x21,0x21,0xe7,0x9b,0x97,0x97,0xae,0x37,0x27,0x1c,0x2c,0x35,0xb7,0xa5,0xbd,0xbe +,0xfd,0x4c,0x5b,0x27,0x2d,0x33,0x35,0x48,0x38,0xa2,0x96,0x8e,0x97,0x38,0x1e,0x1a,0x1e,0x22,0x19,0x1d,0x25,0xbc,0x98,0x9e,0x9b,0xaa,0xaa,0xae,0x59,0x39,0x1c,0x1f +,0x35,0xcc,0xa2,0xbf,0x33,0x20,0x17,0xcb,0x9f,0xa4,0xdb,0x47,0xa5,0x9c,0x9b,0xaf,0x2b,0x1c,0x17,0x1c,0x23,0x27,0xc5,0xaa,0x9c,0x96,0x99,0x9c,0x5f,0x2d,0x2b,0x20 +,0x1f,0x17,0x19,0x3e,0x9b,0x91,0x9e,0xe5,0x32,0x4f,0xb5,0x75,0x2b,0x27,0x31,0xa8,0xa5,0xa8,0xb1,0x46,0x3d,0x2d,0x28,0x21,0x20,0x3b,0xd2,0xa5,0x9b,0xa4,0xb1,0x29 +,0x3c,0xb8,0xa9,0xc9,0x1b,0x21,0x45,0xac,0xa0,0xcb,0x23,0x1d,0x21,0x38,0x47,0xc0,0xb0,0xa0,0x91,0x9c,0xaa,0xea,0x2e,0x2a,0x1d,0x1c,0x14,0x14,0x2d,0xb4,0x94,0x90 +,0x97,0xa8,0xb2,0xa9,0xbe,0x2c,0x14,0x13,0x2d,0xa9,0xb6,0x75,0x2c,0x2d,0xda,0xab,0xa1,0x40,0x2b,0x45,0xa2,0x95,0x97,0xb1,0x20,0x18,0x1c,0x3b,0xb6,0x28,0x19,0x3b +,0x9f,0x94,0x9a,0xaf,0x46,0x45,0xfb,0x38,0x1d,0x1a,0x2f,0x9f,0x9d,0xac,0x36,0x30,0xe9,0xcd,0xaf,0x57,0x1e,0x1b,0x4c,0xa7,0x97,0x9c,0xbe,0x2a,0x2f,0xbd,0xc4,0x2b +,0x0e,0x1a,0xbc,0x9e,0xa2,0xc1,0xba,0xbc,0xaa,0xa6,0xde,0x21,0x1c,0x3d,0xc2,0xb0,0xd8,0x35,0x27,0x23,0x4b,0xa0,0xa4,0x2e,0x29,0xaf,0x97,0x95,0xa8,0x2e,0x1e,0x2b +,0x3c,0x2b,0x1c,0x1c,0x53,0xa9,0x9e,0xaa,0xad,0xa1,0xa8,0xb9,0x47,0x1f,0x14,0x1a,0x49,0xac,0xab,0xc1,0x2b,0x4e,0x9c,0x8f,0x9d,0x24,0x10,0x1e,0xae,0x9d,0xbe,0x2a +,0x29,0x35,0xac,0xae,0x31,0x19,0x29,0xa7,0x9b,0x9f,0xaf,0xf6,0xea,0xc7,0xb5,0xbd,0x2c,0x1e,0x1f,0x65,0x3c,0x3b,0x44,0x3f,0xc8,0xac,0xa4,0xd1,0x28,0x2e,0xae,0x9d +,0xa5,0x7b,0xd3,0xb7,0xc1,0x5a,0x2f,0x1c,0x1b,0x2b,0x64,0xea,0x62,0xc9,0xb0,0xa8,0x9f,0x9e,0xa8,0x5e,0x24,0x24,0x2c,0x2e,0x28,0x2f,0x33,0x32,0x34,0x47,0xb6,0x9d +,0x94,0x96,0xa9,0x2e,0x1a,0x21,0x3d,0xbf,0xb1,0xc3,0x4c,0x39,0x35,0xc9,0xa8,0xaf,0xb4,0x5d,0x5d,0x3c,0x2f,0x31,0x29,0x25,0x2e,0x4b,0xd4,0xcb,0xa0,0xa9,0xad,0xa8 +,0xd3,0x6d,0x47,0xae,0xfe,0xd0,0x21,0x1b,0x25,0x2a,0x35,0xaa,0x98,0x99,0xa5,0x20,0x2e,0x1e,0x32,0x50,0xd2,0xa8,0xb3,0xaf,0x59,0xae,0xc3,0xc2,0xc4,0x5a,0x36,0x4c +,0xca,0x3c,0x36,0x24,0x4d,0xbc,0xa3,0xa6,0xa2,0xad,0x4a,0xcf,0x24,0x1c,0x1c,0x39,0xdd,0xad,0xaf,0x48,0x2b,0x2c,0xae,0x9f,0x98,0xa7,0xd9,0x33,0x2b,0x2e,0x1f,0x1f +,0x2e,0xdc,0xa8,0xa1,0x9e,0xb0,0xb7,0xc9,0x60,0xf7,0x37,0x65,0x38,0x2c,0x1c,0x1d,0x26,0x33,0xc8,0xa1,0x90,0x8f,0x9b,0xdf,0x1a,0x1a,0x26,0x35,0x63,0xc6,0xb5,0xc5 +,0x5d,0x39,0x41,0x42,0xbf,0xa8,0xad,0xbc,0xfe,0x32,0x2a,0x27,0x4b,0xad,0xb2,0xb8,0xcc,0xc9,0xde,0x37,0x2c,0x2f,0x4a,0xbe,0xbb,0xb2,0xbd,0xc7,0x43,0x2f,0xe5,0xb3 +,0xa7,0xb3,0x37,0x1f,0x1e,0x2b,0x50,0xb8,0xaa,0xad,0xbe,0x74,0x6a,0xba,0xb5,0xab,0xb4,0xdb,0x31,0x1e,0x1b,0x25,0x61,0xbe,0xb4,0xb6,0xad,0xb4,0xaf,0xbc,0x3e,0x34 +,0x4b,0xcb,0xbf,0xcb,0x50,0x3d,0x2a,0x2e,0x41,0xba,0xb0,0xae,0xb6,0xda,0x4a,0x32,0x2f,0x39,0xc3,0xaf,0xad,0xba,0x42,0x2e,0x2e,0x3e,0xea,0xbb,0xb2,0xb8,0x45,0x22 +,0x27,0x2c,0x4e,0xc2,0xaa,0xa0,0xaf,0xdb,0x2f,0x24,0x1f,0x3a,0xb5,0xa0,0x9e,0x9f,0xa6,0xb9,0x3c,0x24,0x34,0xbf,0xa6,0xae,0xcf,0x52,0x2c,0x1f,0x22,0x38,0xaf,0xa6 +,0xab,0xb5,0x39,0x23,0x25,0x2e,0x30,0x2f,0x3a,0x4c,0x4c,0x36,0x36,0xd7,0xaa,0xa5,0xa4,0xa8,0xaf,0xbd,0x3d,0x2f,0x3e,0xbe,0xb0,0xb8,0xc0,0xd2,0x4f,0x44,0x41,0x3d +,0xcd,0xb8,0xc1,0x6e,0x43,0x41,0x3c,0x36,0x3b,0xf9,0x5f,0x33,0x28,0x29,0x32,0x56,0xb8,0xb4,0xaf,0xb6,0xb9,0xbb,0xc1,0xb2,0xb3,0xa8,0xaa,0xe9,0x39,0x2f,0x37,0x3c +,0x3b,0x51,0xbc,0xa9,0xb6,0xce,0xca,0xf3,0x37,0x2a,0x25,0x28,0x3d,0x73,0xdc,0x41,0x32,0x33,0x47,0xf9,0xc3,0xac,0xa7,0xa8,0xb8,0x4b,0x45,0x51,0x48,0x38,0xeb,0xb5 +,0xb3,0xb1,0xa9,0xa6,0xba,0x5f,0x36,0x2a,0x28,0x2b,0x37,0x6a,0x4e,0x47,0x4d,0x45,0x3b,0x46,0xdd,0xc2,0xd1,0x2d,0x26,0x48,0xb7,0xaf,0xb1,0xad,0xa2,0xa4,0xbe,0x48 +,0x4c,0xeb,0xb7,0xc2,0x31,0x27,0x2e,0x42,0x4b,0x66,0xc0,0xb9,0xbb,0xbf,0x7a,0x57,0x69,0x4a,0x2a,0x27,0x2f,0x41,0xbd,0xb6,0xb1,0xb4,0xba,0xaf,0xbd,0x4f,0x5e,0xb3 +,0xc0,0x39,0x2f,0x2e,0x37,0x3d,0x3b,0xcd,0xad,0xae,0xb7,0xe6,0x4f,0x61,0x7a,0x38,0x2d,0x40,0x61,0xca,0xc1,0xd2,0xcb,0xc1,0xba,0xb9,0xc5,0xde,0x6f,0x36,0x21,0x25 +,0x30,0x3b,0x47,0xcc,0xb2,0xb2,0xb5,0xc7,0x3c,0x31,0x3b,0x5f,0xdf,0xc2,0xb4,0xb3,0xad,0xb7,0xba,0xc4,0xcd,0xb5,0xb7,0xd6,0xef,0x5a,0x28,0x20,0x28,0x39,0xde,0xbf +,0xbf,0xea,0x5e,0x6f,0xcf,0x61,0x3e,0xeb,0x63,0x39,0x35,0x33,0x3d,0xca,0xab,0x9d,0x9a,0x9c,0xa9,0x5a,0x2e,0x2e,0x3c,0x2d,0x2b,0x3f,0x42,0x35,0x2b,0x2c,0x2e,0x49 +,0xaf,0xa5,0xa4,0xb1,0x4d,0x27,0x1d,0x24,0x3d,0xb9,0xa5,0xa4,0xad,0xb5,0xc4,0x6c,0x4a,0xfc,0xbf,0xb7,0x62,0x30,0x2c,0x2d,0x42,0x5f,0xd0,0xb5,0xae,0xbf,0x40,0x33 +,0x3a,0xce,0xc9,0x4d,0x56,0xcd,0xbf,0xc9,0xd0,0xbd,0xb3,0xae,0xb1,0xda,0x4b,0x3d,0x2e,0x28,0x2d,0x3b,0x3d,0x5a,0xd1,0xbe,0xb6,0xb7,0xc0,0xdf,0x59,0x49,0xe6,0x5a +,0x30,0x2f,0x39,0x6e,0xbe,0xaf,0xa7,0xa6,0xaf,0xc6,0xdc,0x62,0x4f,0x3e,0x2b,0x24,0x29,0x2c,0x3d,0x5a,0xcd,0xad,0xa7,0xae,0xde,0x38,0x30,0x34,0x30,0x38,0xcd,0xbc +,0xc3,0xc0,0xb7,0xaa,0xa5,0xa6,0xae,0xbe,0xd2,0x3b,0x28,0x22,0x21,0x26,0x2c,0x38,0x4b,0xcd,0xb7,0xbb,0xc6,0xcc,0xc7,0xdd,0x5c,0x60,0xcd,0xae,0xae,0xbd,0xde,0xf0 +,0xc4,0xae,0xa9,0xad,0xba,0x4b,0x2b,0x24,0x22,0x25,0x2b,0x35,0x69,0xd5,0xcf,0xb2,0xac,0xb4,0xb7,0xbd,0x6d,0x37,0x24,0x23,0x35,0xca,0xae,0xb7,0xd1,0xc6,0xaf,0xa5 +,0xa5,0xb0,0x5e,0x2e,0x1e,0x19,0x23,0x40,0xc9,0xcf,0xce,0xb0,0xab,0xc1,0x56,0xca,0xbb,0xc6,0x69,0x36,0x29,0x26,0x35,0xc4,0xb8,0xaf,0xa6,0xa1,0xa4,0xab,0xb1,0x77 +,0x28,0x1b,0x1b,0x27,0x3d,0x4e,0x3a,0x32,0x68,0xac,0xa3,0xa3,0xa6,0xab,0xbb,0x4c,0x2f,0x2c,0x2f,0x46,0xe5,0xb9,0xac,0xae,0xbb,0xca,0xcf,0xd8,0x5c,0x3a,0x26,0x1c +,0x1c,0x26,0x35,0x42,0xcc,0xaa,0x9f,0x9f,0xa4,0xae,0xc4,0xd0,0xea,0x3f,0x2e,0x30,0x3c,0x35,0x3b,0xbb,0xa1,0xa2,0xbd,0x4f,0x50,0x4c,0x34,0x27,0x24,0x25,0x29,0x33 +,0xec,0xae,0xa1,0x9f,0xa6,0xbe,0x54,0x49,0x41,0x32,0x32,0x49,0xfc,0x48,0x2f,0x3d,0xb5,0x9e,0x98,0x9b,0xa9,0x5a,0x28,0x21,0x23,0x27,0x2e,0x2d,0x26,0x2e,0x55,0xb4 +,0xa3,0x9e,0x9e,0xa4,0xad,0xc8,0x46,0x2d,0x24,0x2b,0x3e,0x47,0x57,0xbd,0xa9,0xa5,0xb4,0xd6,0x41,0x29,0x20,0x1f,0x25,0x2e,0x3a,0x39,0x4f,0xb3,0x9b,0x93,0x98,0xad +,0x4d,0x3b,0x2f,0x29,0x27,0x2e,0x37,0x2e,0x2d,0xf2,0xa8,0x9e,0xa0,0xab,0xbd,0x4b,0x2c,0x25,0x21,0x28,0x50,0xca,0x52,0x40,0xcb,0xab,0x9f,0x9e,0xa2,0xac,0xea,0x2d +,0x22,0x1d,0x1f,0x26,0x2c,0x5e,0xaf,0xa0,0x9d,0xa0,0xaa,0xb1,0xbf,0x4d,0x28,0x1a,0x1a,0x1f,0x2b,0x3e,0xbd,0xa1,0x9a,0x9a,0xa2,0xbb,0xdb,0x6d,0x3a,0x23,0x1c,0x1f +,0x27,0x2b,0x5f,0xa4,0x9b,0x9c,0xa1,0xbd,0x4e,0x42,0x3a,0x32,0x24,0x20,0x26,0x26,0x26,0x59,0x9c,0x8f,0x90,0x9f,0xec,0x30,0x2c,0x2b,0x25,0x20,0x21,0x24,0x26,0x38 +,0xb1,0x9f,0x9c,0x9c,0xa5,0xb0,0xbf,0x4e,0x2a,0x1f,0x2b,0x3d,0x34,0x2f,0x72,0xa5,0x9c,0x9c,0xa8,0xfe,0x3a,0x3a,0x3d,0x2d,0x22,0x1f,0x1f,0x24,0xd9,0x9c,0x94,0x95 +,0x9c,0xb6,0x44,0x3f,0x3d,0x2b,0x1e,0x1e,0x1e,0x1e,0x28,0xd3,0x9e,0x93,0x93,0xa8,0x3b,0x2e,0x30,0x35,0x30,0x33,0x36,0x2b,0x29,0x3c,0xb1,0x9a,0x93,0x99,0xb3,0x3b +,0x27,0x1d,0x1b,0x1f,0x30,0x3f,0x3a,0x49,0xbe,0xa7,0x9d,0x9c,0xa5,0xb8,0xb8,0xc0,0x3c,0x22,0x1c,0x1b,0x21,0x37,0xdc,0xaf,0xa3,0x9f,0xa7,0xbd,0xc7,0xc4,0xed,0x3f +,0x33,0x2e,0x27,0x24,0x33,0xbe,0x9e,0x95,0x9c,0xd6,0x2f,0x3b,0x42,0x2e,0x1e,0x1c,0x1d,0x24,0xdc,0xa5,0x9b,0x94,0x95,0xa6,0x64,0x3a,0x30,0x25,0x1f,0x21,0x22,0x1f +,0x22,0x34,0xb6,0x98,0x8e,0x91,0xaa,0x3d,0x3c,0x41,0x2f,0x27,0x26,0x25,0x27,0x2f,0x3c,0xcb,0xa5,0x9d,0xa2,0xaa,0xab,0xb9,0x40,0x26,0x1e,0x1d,0x1f,0x2e,0x6f,0xb3 +,0x9e,0x98,0xa1,0xc8,0xd9,0xb8,0xbc,0x4c,0x2a,0x1d,0x19,0x1d,0x31,0xbb,0x9f,0x94,0x96,0xad,0x3f,0x3d,0x42,0x4c,0x45,0x32,0x1f,0x18,0x20,0x3d,0xad,0x95,0x8f,0x99 +,0xbd,0x3f,0x36,0x2a,0x21,0x1f,0x1f,0x21,0x2c,0x33,0x37,0xaf,0x96,0x90,0x97,0xa1,0xb6,0x40,0x2a,0x22,0x1c,0x18,0x1b,0x25,0x32,0xba,0x9b,0x99,0xa8,0xb6,0xa8,0xab +,0xb8,0xdd,0x2b,0x1b,0x18,0x24,0x32,0x4d,0xac,0x9d,0x9f,0xad,0xbd,0xd7,0x4f,0x4d,0x36,0x23,0x1e,0x23,0x2d,0x5d,0xa1,0x93,0x94,0xa0,0xbb,0xee,0x4f,0x65,0x44,0x24 +,0x15,0x15,0x1b,0x1f,0x46,0x9e,0x91,0x94,0x9d,0xa8,0xdf,0x40,0x4d,0x2f,0x1f,0x1e,0x29,0x2a,0x2b,0xbe,0x9d,0x9b,0x9d,0x9e,0xab,0xdd,0x39,0x27,0x19,0x13,0x1a,0x25 +,0x2f,0xce,0xa2,0x9c,0x9e,0xa3,0xa5,0xa6,0xa4,0xae,0x37,0x1b,0x16,0x1a,0x1f,0x3a,0xab,0x9c,0xa5,0xb5,0xb9,0xbe,0xce,0xb5,0xeb,0x20,0x2d,0x4e,0x2d,0x22,0x69,0xc9 +,0xa8,0xc4,0x44,0x59,0xb8,0x4f,0xcc,0xac,0x6c,0xa9,0x9f,0xc0,0x15,0x21,0x4f,0xa8,0x5d,0xa8,0xb2,0xa5,0x2e,0x3c,0xda,0x6b,0x5d,0x29,0xa1,0x00,0x03,0x00,0x1e,0x8f +,0x2c,0x99,0x2a,0x20,0x95,0x95,0x9c,0xb0,0x98,0x9a,0x8c,0x8f,0xcb,0x8d,0x93,0x11,0x98,0x16,0x11,0x88,0x8b,0x8b,0xa3,0xa4,0x2d,0x2e,0x04,0x03,0x03,0x04,0x03,0x08 +,0x07,0x06,0x0c,0x14,0x18,0x00,0x12,0x0f,0x1f,0x17,0x1f,0xb5,0xa3,0x89,0x8d,0x91,0x97,0xaf,0x9d,0x88,0x89,0x8a,0x83,0x81,0x81,0x86,0x83,0x80,0x81,0x84,0x99,0x80 +,0x9f,0x26,0x8c,0x80,0x25,0x0e,0x98,0x08,0x06,0x0a,0x04,0x09,0x04,0x00,0xcd,0x31,0x05,0x06,0x00,0x0a,0x02,0x02,0x02,0x02,0x11,0x12,0x9b,0x74,0x0c,0x0e,0xb7,0x88 +,0x86,0x80,0x89,0xac,0x87,0x80,0x83,0x84,0x83,0x8b,0x99,0x84,0x89,0x80,0x8d,0x9e,0x9f,0x8d,0xad,0x9a,0x86,0x19,0x0a,0x08,0x17,0x19,0x0a,0x07,0x05,0x00,0x02,0x03 +,0x0b,0x06,0x00,0x0b,0x06,0x03,0x05,0x12,0x15,0x15,0xb3,0xb8,0x57,0x16,0xad,0x95,0xa1,0x8f,0x89,0x8e,0xc5,0xa2,0x90,0x8c,0x9b,0x8a,0x86,0xaf,0x80,0x8d,0x96,0x87 +,0x89,0x80,0x8b,0x85,0x1d,0x99,0x8e,0x1d,0x1e,0x1f,0xc2,0x00,0x0e,0xa4,0x0b,0x06,0x00,0x05,0x03,0x0a,0x18,0x26,0xd3,0x0c,0x04,0x02,0x07,0x05,0x5a,0x1e,0xb9,0x22 +,0x91,0x8e,0x0e,0x8b,0x8e,0x80,0x84,0x97,0x8f,0x85,0x85,0x84,0x80,0x82,0x8f,0xae,0x87,0x8f,0x9a,0x33,0x31,0xb4,0xa0,0x95,0x52,0x25,0x00,0x0b,0x1b,0x35,0xcd,0x17 +,0x10,0x07,0x00,0xd0,0x9c,0x0d,0x04,0x00,0x01,0x13,0xa1,0x18,0x9a,0x12,0x0d,0x05,0x44,0xa4,0x40,0x80,0x1f,0x38,0x86,0x82,0xbd,0x94,0x86,0x91,0x9a,0x04,0x94,0x80 +,0x93,0x96,0x1d,0x8a,0x81,0x80,0x86,0x88,0xa5,0x3d,0xa3,0x5d,0xa6,0xc3,0xfe,0x27,0x3e,0x01,0x03,0x06,0x0b,0x0c,0x17,0x07,0x01,0x0c,0x13,0x89,0x39,0x00,0x04,0x06 +,0x05,0x2f,0x98,0x1e,0x17,0x5b,0x33,0x8d,0x8b,0x89,0x8b,0x8a,0x42,0x0c,0xb2,0x80,0x82,0x80,0x88,0x97,0x8e,0xba,0x8c,0x8e,0x88,0x0f,0x12,0x37,0x88,0x8c,0x0e,0x2e +,0x96,0x39,0x00,0x86,0xb9,0x06,0x07,0xbd,0xb9,0x0c,0xa1,0x07,0x07,0x0c,0x00,0x0a,0x16,0xa3,0x03,0x03,0x17,0x1a,0x9d,0xdc,0x8f,0x06,0x21,0x0e,0x14,0x80,0x87,0x80 +,0xbf,0x9f,0xa3,0x89,0x90,0x8c,0x80,0x8d,0x13,0x43,0x84,0x85,0x8d,0x33,0x86,0x8e,0xba,0x13,0x15,0x44,0x82,0x90,0x18,0x79,0x05,0x9a,0x0e,0x0a,0x04,0x08,0x37,0x05 +,0x1d,0x19,0x0c,0x01,0xa4,0x1e,0x03,0x04,0x2c,0x4b,0x06,0x09,0x8f,0x81,0xc5,0x25,0x01,0x2c,0x6f,0x87,0x84,0x8d,0x50,0x17,0x8a,0x8e,0x80,0x96,0x94,0x99,0x29,0x87 +,0x8a,0x8e,0xaf,0x89,0x92,0xaf,0x8b,0xca,0x54,0x3b,0xb3,0x85,0x8e,0x15,0x09,0xa6,0x99,0x1e,0x07,0x0f,0x56,0x00,0x05,0x2c,0x1c,0x00,0x08,0x07,0x0e,0x2c,0x23,0x05 +,0x06,0xb4,0xa4,0xe1,0x0d,0x30,0xb1,0x80,0xaa,0x9a,0x8b,0x1a,0x93,0x8e,0x8a,0x94,0x8f,0x80,0x8f,0x8f,0xac,0xa7,0x85,0x9c,0xc3,0xa3,0x81,0x1b,0x18,0x29,0xba,0x9c +,0xab,0x2c,0x1d,0x06,0x10,0x8c,0xa8,0x1f,0x06,0x94,0x1a,0x0f,0x11,0x14,0x0a,0x07,0x9c,0x31,0x12,0x07,0x15,0x19,0x0d,0x2b,0x1e,0x0c,0x29,0xc0,0x22,0x0c,0x9b,0x82 +,0xa8,0xb9,0x27,0x9a,0x9a,0xbd,0x8b,0x82,0x8f,0x94,0x9e,0x87,0x8e,0x9d,0x85,0x90,0x82,0x9d,0x90,0x8d,0xbd,0x22,0x8b,0xb8,0xc8,0xbe,0x20,0x5d,0x01,0x0f,0xcb,0x26 +,0x01,0x13,0x11,0x0d,0x09,0x0f,0x16,0x13,0x06,0x0a,0x26,0x51,0x15,0x26,0x97,0x01,0x4e,0x92,0x2e,0xd4,0xa6,0x8f,0x93,0x98,0x91,0x8e,0x94,0x90,0x87,0x80,0x5f,0x7c +,0x8b,0xa0,0x96,0x8d,0x8d,0x2c,0x1f,0xd7,0x8f,0x99,0x0f,0x16,0xaf,0xa3,0x26,0x2c,0x1a,0x0f,0x3b,0xb7,0x90,0x18,0x03,0x14,0xa7,0x23,0x3d,0x39,0x0f,0x0e,0x0b,0xb1 +,0x10,0x1f,0x0d,0x25,0x22,0x29,0x3b,0x38,0x07,0x1b,0xad,0x3a,0xa1,0x26,0xbe,0x9a,0x8e,0x41,0x80,0xbb,0xd3,0x8a,0x88,0x89,0x29,0x91,0x92,0x88,0x86,0x98,0x93,0xaf +,0xb6,0x91,0x8e,0x27,0x1b,0x94,0x34,0x27,0xd5,0x0d,0x0c,0x18,0xc8,0x31,0x15,0x07,0x05,0x27,0x0e,0x21,0xaf,0x13,0x02,0x11,0x45,0xac,0x28,0x0b,0x15,0x9d,0xbd,0x99 +,0x8f,0x15,0x1d,0x1d,0x8f,0x97,0x94,0x87,0x9f,0xa2,0xa4,0x88,0x81,0x8e,0xa3,0x8e,0x9a,0x9d,0x8f,0x8e,0x92,0x98,0x22,0xcf,0x2b,0x3b,0xa8,0x1a,0xa9,0x0f,0x26,0x69 +,0xba,0x34,0x28,0x1f,0x0b,0x10,0x22,0x9c,0x0f,0x1f,0x1d,0x07,0x31,0x2c,0x1e,0x0f,0x0c,0x0f,0xc6,0xe6,0x3f,0x1c,0xa9,0xb9,0xbc,0x88,0x1b,0xac,0xb4,0x91,0x9d,0x98 +,0xa0,0x9e,0x8f,0xac,0x98,0x9d,0x91,0x9a,0xa4,0xbc,0x95,0xb5,0x96,0x9e,0x9f,0xa3,0x21,0xc7,0x61,0x36,0x3c,0x27,0x16,0xa7,0x20,0x14,0x3e,0x1b,0x1b,0x17,0x0d,0x1b +,0xaa,0xa2,0xd2,0x0e,0x2f,0x0f,0xee,0x8f,0x0f,0x0c,0x19,0x28,0x3f,0xa2,0x1e,0x0b,0xbc,0xba,0x4d,0x99,0x2c,0xac,0xc6,0xac,0x8b,0x90,0x90,0x8d,0x8f,0x8f,0xa0,0x89 +,0x86,0x97,0xa6,0xa8,0x94,0xa8,0x99,0xa6,0xa2,0x16,0x22,0xe7,0x0a,0x14,0x23,0x0e,0x13,0x11,0x07,0x15,0x47,0x0d,0x02,0x12,0x1d,0x07,0xcf,0xb1,0x16,0x29,0x1a,0xa6 +,0xe7,0x93,0xb7,0xb2,0x92,0xa6,0x8f,0x91,0x8f,0xae,0xd9,0x94,0x98,0x9e,0x91,0x50,0x35,0x93,0xa3,0xbf,0x95,0xa6,0xa5,0x1b,0x2c,0xdb,0x48,0xc0,0x39,0x4d,0x35,0x1e +,0xd9,0x25,0x1a,0xa0,0x0e,0x1c,0xf4,0x3f,0xb7,0x6c,0x26,0x23,0x21,0xaf,0x90,0x17,0x14,0x31,0x2f,0x9c,0xb1,0x2a,0x1d,0x2e,0x22,0x21,0x3e,0x20,0x18,0x1b,0x1b,0xdd +,0x2c,0x5e,0x9f,0x2e,0xb1,0x30,0x9f,0x98,0xa5,0xbd,0x97,0x9f,0x98,0x89,0x8b,0xab,0x98,0x96,0xb7,0xb4,0x97,0x96,0x25,0x99,0x27,0x60,0x43,0x33,0x2e,0x0f,0x10,0x0f +,0x15,0xee,0xb4,0x11,0x03,0x1f,0x1a,0x43,0x1b,0x09,0x30,0x1d,0xab,0x9e,0x9f,0xb1,0x9e,0xbc,0x9c,0xad,0xd3,0x9e,0x9b,0xef,0x2a,0xd5,0x90,0xa5,0x5a,0xb8,0x35,0x8f +,0x99,0xa7,0xd0,0x45,0xac,0xb2,0x9d,0xb7,0x64,0x3e,0xaf,0x32,0x0c,0xb6,0xd9,0x9d,0x32,0x14,0x29,0x5a,0x56,0xa5,0x1f,0x0d,0x2d,0x3f,0xab,0x29,0x33,0x1c,0x33,0x15 +,0xe8,0xb1,0x26,0x2c,0x24,0x35,0xa8,0x9d,0x9f,0x9f,0xb7,0x2f,0x3a,0xa7,0xbd,0x96,0x0f,0x19,0x34,0xb9,0x9f,0x55,0xae,0x28,0xa9,0xa4,0xa3,0x98,0xad,0x2d,0xbc,0xb7 +,0x4c,0xb5,0xa3,0xbe,0x4d,0x1f,0x2d,0xcb,0x9d,0xa2,0x15,0x34,0xb4,0x9c,0xd6,0x30,0x21,0x21,0x34,0xcb,0xb5,0x27,0x3a,0x26,0xde,0x18,0x2d,0xaa,0xe0,0x2e,0x0f,0x1d +,0xb8,0xab,0x41,0x28,0x1b,0x5a,0x9f,0xaa,0xa5,0x6e,0x27,0x4d,0xac,0xa1,0xca,0x9b,0xaa,0xbd,0xaf,0x9b,0x9f,0xb8,0xa7,0x49,0xef,0xe0,0x9d,0x9f,0xaf,0x55,0x2e,0x26 +,0x45,0xac,0xaf,0x2f,0x28,0x5d,0xa3,0xaa,0xb7,0xb3,0x27,0x24,0x27,0xae,0xb5,0x58,0x2e,0x27,0x1f,0x22,0xb3,0xb6,0x2f,0x1e,0x2b,0xbf,0x9b,0xb3,0x19,0x1e,0x48,0xb0 +,0xae,0x57,0x5b,0x33,0x31,0x2c,0x24,0xd9,0xab,0xbd,0x43,0x1d,0x1b,0xa0,0x92,0x9d,0x48,0x16,0x1c,0xac,0x96,0xd7,0x2e,0x28,0x2f,0x2c,0x2e,0xaf,0xaf,0x41,0x29,0xb6 +,0xa3,0xaa,0xbc,0x4d,0xde,0x4d,0xb2,0xa0,0xd4,0x2d,0x2a,0xce,0xbb,0xc7,0x38,0x23,0x34,0xa9,0x9f,0xbc,0x7d,0x2d,0x2b,0x31,0x33,0x2c,0xe7,0xa7,0xa3,0xbc,0x1e,0x18 +,0x2a,0xa3,0xa3,0x34,0x2a,0x28,0xbf,0x98,0xac,0x2b,0x1e,0x1f,0x2c,0xa0,0xa9,0x47,0x2a,0x32,0xa3,0xbf,0xa0,0x9f,0xe0,0x20,0x29,0xb4,0xac,0xbf,0x35,0xdf,0xbc,0xba +,0xa3,0xb1,0x1b,0x2d,0xa1,0xa2,0x43,0x1b,0x23,0xb7,0x98,0x9b,0x40,0x1d,0x4a,0xa9,0xbe,0x2f,0x21,0x24,0xaf,0xa5,0xae,0xd8,0x2a,0x39,0x4e,0xa9,0x37,0x25,0x30,0xee +,0x9f,0xa8,0xb6,0x40,0x2b,0x1b,0x3d,0x9d,0xa2,0x52,0x43,0xc5,0x62,0x4a,0xbf,0x5f,0x27,0x3f,0xac,0xb5,0x36,0x26,0x4c,0x98,0x8f,0xab,0x21,0x1d,0x2d,0xa0,0xa5,0x2c +,0x13,0x1d,0xbd,0xb9,0xfa,0x21,0x16,0x1b,0xc4,0xa6,0xcf,0x22,0x31,0x9e,0x90,0xa6,0x54,0x60,0x29,0x2b,0xd3,0xb3,0x35,0x27,0xde,0x9f,0x9b,0x96,0xa4,0x28,0x1c,0xd0 +,0xa5,0xb4,0x30,0x20,0xb5,0x98,0x9d,0x2d,0x21,0x2e,0xaf,0x97,0xb5,0x1d,0x1a,0x50,0x93,0x9d,0x22,0x0f,0x19,0xa2,0x9a,0xa5,0x1e,0x0d,0x11,0xb0,0x8f,0xac,0x2a,0x28 +,0x4b,0x5b,0xa7,0xbe,0x2e,0x49,0x60,0xdb,0x46,0x4a,0x3e,0x2d,0x48,0x9f,0x9e,0xb4,0x25,0x2c,0x9c,0x95,0xaa,0x2a,0x2c,0x3f,0xa9,0x9a,0xd2,0x27,0x28,0xe4,0xa2,0xb9 +,0x1b,0x10,0x28,0x9c,0x9c,0xdc,0x2b,0x1f,0x57,0x93,0x9a,0x1e,0x0f,0x18,0xb7,0x9a,0xaf,0x21,0x2b,0xcd,0xe6,0xb1,0xbb,0x32,0x27,0x3b,0x68,0xb3,0xa7,0xac,0x25,0x1f +,0xad,0x9b,0xa0,0x3e,0x39,0xc6,0xab,0xa7,0x3d,0x3b,0x48,0x48,0xab,0x35,0x15,0x25,0xae,0xa3,0xa8,0xc1,0x27,0x74,0xa2,0xa3,0x33,0x18,0x22,0x5e,0x9d,0xac,0x2d,0x18 +,0x35,0xae,0x7a,0xc9,0x28,0x1c,0x33,0xb3,0xa2,0x9a,0xb3,0xb3,0xd0,0x27,0x36,0x4c,0xc8,0x24,0x2d,0xab,0xa2,0xa5,0xa3,0xa5,0x3e,0x31,0x3f,0x30,0x4a,0x31,0x3b,0xbd +,0xae,0xe2,0x51,0xb4,0x5a,0x4d,0x1f,0x1e,0x36,0xa9,0x98,0x3e,0x1a,0x33,0x9d,0x9c,0x39,0x18,0x15,0x23,0x3a,0x36,0xc6,0xad,0xba,0x9e,0x9b,0x43,0x30,0xb9,0xa7,0xbb +,0xc3,0xc7,0xa7,0xa8,0x39,0x45,0x69,0x34,0x2f,0x67,0xc6,0x2c,0x2b,0x9f,0x93,0x9f,0xb3,0x5a,0x15,0x33,0x62,0x3e,0xdf,0x64,0xb3,0x2b,0x2a,0x2f,0xa1,0xbb,0x19,0x17 +,0x2e,0xa6,0xa7,0xa9,0xcc,0x40,0x2d,0xaf,0xb3,0x44,0x29,0x1e,0x46,0xa9,0xae,0xb9,0x9e,0xb8,0x3d,0x3a,0xfe,0x32,0x34,0xca,0xff,0x2f,0x43,0xaa,0x9d,0xac,0x41,0x4c +,0x37,0xaf,0x31,0x49,0xaf,0xd0,0xac,0xba,0x2f,0x1c,0xc2,0x4d,0x27,0x2e,0x54,0xa5,0xb5,0x2e,0x2e,0xa9,0xa9,0xd2,0x29,0x1d,0x23,0xf6,0x9d,0xa3,0x3b,0x2d,0xdb,0x29 +,0x36,0xb9,0xab,0x9e,0xbd,0x45,0x33,0x39,0xce,0xab,0xb2,0x20,0x15,0x2f,0x9e,0x97,0xa2,0xa3,0xb5,0x37,0x43,0xbd,0xaf,0x2f,0x1f,0x2c,0xc8,0x52,0x4a,0xae,0x49,0x1c +,0x2c,0xb7,0x39,0x2e,0x51,0xb3,0xad,0x9f,0xa3,0x6a,0x28,0x28,0x56,0x24,0x20,0x1f,0x31,0xa3,0x9d,0x9e,0xd0,0x21,0x2f,0xa4,0xa0,0x46,0x36,0xb9,0x9c,0x98,0x76,0x36 +,0xd1,0x65,0x26,0x1b,0x2e,0x28,0x32,0x9b,0x8e,0xae,0x32,0x37,0x1f,0x20,0x3c,0xa6,0xa6,0x2c,0x1a,0x6a,0xa9,0xa5,0xb9,0x3d,0x1d,0x18,0xeb,0xaa,0xa5,0xb1,0xa9,0xb8 +,0x3e,0x2f,0x1d,0x27,0x4e,0xee,0x55,0xf1,0xb5,0xa2,0x96,0x98,0x4c,0x30,0x32,0x32,0x3b,0x56,0xb7,0x62,0xdc,0xd1,0xa3,0xb7,0x29,0x1e,0x26,0x4d,0x4a,0xba,0xb6,0xdb +,0x53,0x9f,0xa0,0x34,0x1e,0x1d,0x1d,0x2e,0xae,0x9e,0xa1,0x2f,0x37,0xa2,0xa3,0x4e,0x15,0x18,0x24,0x4e,0x9e,0x9d,0xc2,0x6c,0xa8,0xae,0x43,0x33,0x30,0xd9,0xa8,0xb1 +,0x4b,0x54,0xc4,0xb8,0xab,0x3f,0x22,0x1d,0x27,0xed,0xa9,0x9a,0xce,0x34,0x3b,0xd1,0xa8,0xae,0x29,0x1f,0x4f,0xd8,0xcb,0xbc,0xc6,0x1b,0x24,0x9d,0xa2,0x2a,0x1c,0x31 +,0xd6,0xaf,0xa1,0x9f,0xc6,0x27,0x34,0xae,0xbe,0x48,0x35,0x4c,0x44,0xca,0xa3,0xaf,0x54,0xe7,0xcf,0x2d,0xd6,0x3e,0x2f,0xbd,0xb5,0x48,0x31,0xb4,0xaa,0xd9,0x37,0x3c +,0x28,0x30,0xa8,0x9e,0xb1,0x4c,0x2b,0x1e,0x38,0xb1,0xa1,0xc3,0x1a,0x24,0xf6,0xc6,0xb7,0xbb,0x4a,0x2d,0xbf,0x9a,0xb5,0x29,0x39,0xbc,0xb6,0xb1,0xc2,0x2d,0x36,0x4d +,0xb5,0xa1,0xa8,0x1f,0x15,0x46,0xbf,0xdf,0x60,0xad,0xbf,0x3d,0x2f,0x3c,0xb4,0xbe,0xa7,0xa4,0x3a,0x19,0x19,0x3e,0x9a,0x99,0xae,0x2e,0x16,0x2b,0xb4,0xac,0xa9,0x4c +,0x1e,0x1f,0xaf,0x98,0x9d,0xbe,0x29,0x4d,0xc2,0x78,0x39,0x28,0x47,0xc8,0xa3,0x97,0xc0,0x15,0x1b,0xeb,0xb8,0xb7,0x41,0x5c,0x2d,0x20,0xc4,0xa2,0x9d,0xb6,0x3e,0x23 +,0x15,0x1f,0xae,0x99,0x9b,0xb0,0x2d,0x25,0x2a,0xba,0xa8,0xb8,0x31,0x20,0xcb,0xa2,0x9d,0xbb,0x3d,0x2d,0x26,0xad,0x9b,0xc0,0x1d,0x1c,0x2a,0xb8,0x96,0x93,0xb6,0x0f +,0x15,0xdb,0xcc,0x4a,0x35,0xdf,0x4c,0x48,0x9d,0x98,0x4d,0x1a,0x2f,0xcf,0x34,0x2f,0xae,0x9c,0xa8,0x6c,0xd2,0x4a,0x28,0x35,0x50,0x75,0x21,0x25,0x9e,0x99,0xb4,0x3e +,0x4a,0x4e,0xc1,0xa2,0xb5,0x1d,0x0f,0x39,0x9b,0x90,0x93,0xb8,0x1c,0x09,0x16,0xa8,0x9b,0xbd,0x2a,0x58,0x38,0x3b,0xa7,0xa6,0xcb,0x21,0x47,0xa9,0x3e,0x1f,0x2f,0xa7 +,0x9b,0xaa,0xb9,0xc6,0x1c,0x1b,0x43,0xc2,0x30,0xbb,0x92,0xa1,0x2b,0x26,0xaf,0x5e,0x3d,0xc5,0xd6,0x1f,0x19,0xa2,0x8e,0x98,0x36,0x1b,0x1d,0x18,0xf0,0x93,0x9f,0x21 +,0x13,0x41,0xaa,0x9c,0x9c,0x56,0x1e,0x18,0x7a,0x9e,0xda,0x22,0x26,0xa6,0x9a,0xad,0xbc,0x2c,0x15,0x21,0xa5,0x9f,0x3a,0x3c,0xb6,0x70,0x32,0xdb,0x99,0xa4,0x3d,0x2e +,0x46,0x2a,0x17,0xb7,0x8f,0x96,0x28,0x28,0xb0,0x39,0x3a,0x34,0x29,0x1e,0x2e,0x98,0x99,0xba,0x30,0x24,0x2a,0x2b,0xaa,0x95,0x37,0x0b,0x1b,0x99,0x90,0x98,0x9d,0x27 +,0x0c,0x17,0xac,0x9d,0x2b,0x20,0x46,0xa4,0xa0,0xb8,0xaa,0x49,0x2d,0x2a,0xb6,0xc5,0x27,0xa9,0x99,0xa0,0x33,0x3e,0xb6,0x4e,0x26,0x1a,0x25,0x44,0xb7,0x99,0x9a,0x4c +,0x1e,0x45,0xa6,0x3d,0x47,0xdd,0x19,0x0e,0xc9,0x88,0x8c,0xaf,0x17,0x0b,0x0f,0x23,0x9f,0x8e,0x5d,0x12,0x2c,0x93,0x8f,0x9d,0xeb,0x16,0x15,0x36,0xa2,0x3d,0x1a,0xb8 +,0x9a,0x96,0xa5,0xb4,0xb3,0x25,0x11,0x1b,0xc5,0xc0,0xac,0x9c,0xa9,0x3c,0x2d,0xc6,0xb6,0x29,0x1f,0x2d,0x25,0x3a,0xad,0x96,0x91,0xaf,0x1a,0x1d,0x3a,0x25,0x47,0xca +,0x1f,0x1b,0xab,0x89,0x8e,0xbb,0x19,0x0e,0x20,0xc3,0xa1,0x49,0x19,0x51,0x8f,0x8b,0xaf,0x2e,0x4c,0x1b,0x10,0x59,0x9e,0xc6,0x6b,0xb0,0xb5,0xb6,0xc5,0xc9,0xc0,0x1f +,0x12,0x27,0xcb,0xc8,0xb2,0xa5,0x99,0xa2,0x32,0x25,0x19,0x18,0x6c,0xb3,0xdc,0xb5,0xa8,0x93,0x9b,0x1d,0x10,0x21,0xc6,0xbc,0xc2,0x24,0x17,0xbf,0x8a,0x85,0xa7,0x1c +,0x1b,0x0f,0x17,0x4d,0xad,0x9f,0xb8,0x2f,0xa6,0x95,0xb8,0x47,0x39,0x1c,0x1d,0x67,0xc9,0x5e,0xbc,0xa4,0xa0,0xa7,0x58,0x21,0x14,0x14,0x2e,0xb9,0xa9,0x3e,0xcd,0x8e +,0x94,0x3f,0x2d,0x32,0x32,0x37,0x24,0x15,0x21,0xab,0x92,0x88,0x9a,0x1f,0x16,0x1e,0x4c,0xcd,0x45,0xcc,0x40,0x37,0x98,0x93,0xa0,0xb8,0x28,0x10,0x17,0x29,0x5f,0xba +,0x6d,0xaf,0x96,0x9f,0x68,0x30,0x18,0x18,0x74,0x9b,0x57,0x13,0x3b,0x90,0xa3,0x49,0x2c,0x1c,0xd7,0xaf,0x2d,0x1d,0x4d,0xa8,0x92,0x8e,0xa6,0x38,0x1e,0x1c,0x3c,0xc1 +,0x35,0x23,0x24,0xdb,0x9b,0x91,0x9f,0x27,0x16,0x2c,0x49,0xbc,0xa2,0x4b,0x20,0xad,0x8d,0x9c,0x31,0x15,0x0f,0x17,0x41,0xad,0xd8,0x27,0xde,0x96,0x95,0x9e,0x30,0x1a +,0x44,0xe1,0x28,0x27,0x28,0xba,0x90,0x93,0x62,0x2d,0x1e,0x1c,0xc3,0xc0,0x2a,0x2c,0x3b,0xba,0x94,0x93,0xbb,0x1e,0x2d,0xbf,0x3d,0x2c,0x35,0x22,0x33,0x99,0x8e,0x8d +,0xab,0x0c,0x0c,0x47,0x6b,0x3a,0x2d,0x19,0x4d,0x8e,0x8e,0xa7,0x23,0x20,0xb2,0xbf,0x25,0x17,0x25,0xaa,0x95,0x9b,0xb7,0x35,0x24,0x3e,0x3a,0x29,0x2b,0x2b,0x20,0xe7 +,0x92,0x92,0xb3,0x2b,0x2f,0xae,0xa4,0x35,0x13,0x1d,0xab,0x98,0x96,0xa1,0x24,0x10,0x2c,0xa2,0xb6,0x35,0x1f,0x18,0xcb,0x97,0x9b,0xa1,0x2b,0x18,0xaf,0xa4,0x1f,0x1b +,0x5a,0xb9,0x97,0x8f,0xa8,0x1b,0x15,0x27,0x5b,0x2c,0x18,0x18,0xc8,0x8f,0x99,0xc2,0x2a,0x19,0x10,0x99,0x9c,0xc6,0x16,0x1c,0x88,0x80,0x11,0x10,0x80,0x5b,0xbb,0xbc +,0x00,0x0e,0x13,0x06,0x1c,0x42,0x01,0x00,0x02,0x00,0x07,0x01,0x03,0x0a,0x00,0x02,0x0c,0x06,0x02,0x09,0x00,0x1f,0xa9,0x22,0x0f,0x1a,0x8c,0x89,0x89,0xb4,0x84,0x80 +,0x84,0x82,0x84,0x80,0x80,0x80,0x82,0x80,0x82,0x83,0x89,0x87,0x81,0x80,0x81,0x80,0x89,0x97,0x83,0x80,0x88,0x8c,0xa9,0x3e,0x45,0x1b,0x02,0x46,0x8e,0x2b,0x16,0x01 +,0x05,0x0b,0x09,0x09,0x04,0x03,0x00,0x00,0x00,0x01,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x06,0x04,0x00,0x00,0x00,0x00,0x01,0x06,0x0a,0x0a,0x01,0x00,0x10,0xca +,0x93,0x9a,0x96,0x93,0x9b,0x39,0x99,0x80,0x82,0x80,0x85,0x85,0x80,0x80,0x82,0x82,0x80,0x80,0x80,0x81,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x82,0x84,0x82,0x81,0x88,0x94,0x99,0x88,0x91,0x15,0x03,0x35,0x96,0x2a,0x0a,0x02,0x13,0x1c,0x0a,0x02,0x01,0x01,0x00,0x00,0x00 +,0x02,0x01,0x00,0x00,0x00,0x01,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x06,0x0a,0x04,0x01,0x01,0x00,0x00,0x00,0x0a,0x28,0x0e +,0x03,0x03,0x08,0x0f,0x12,0x33,0x9e,0x9f,0x37,0x16,0x1c,0xab,0x85,0x82,0x84,0x8c,0xa3,0x95,0x86,0x80,0x80,0x83,0x86,0x84,0x83,0x87,0x83,0x80,0x80,0x80,0x83,0x85 +,0x81,0x80,0x81,0x80,0x80,0x80,0x85,0x93,0x89,0x80,0x80,0x80,0x82,0x85,0x83,0x81,0x82,0x86,0x83,0x82,0x88,0x90,0xa9,0x96,0x88,0x86,0x83,0x87,0x8c,0x89,0x89,0x8b +,0x8c,0x89,0x8b,0x99,0xcf,0x35,0x91,0x8c,0x9c,0xaf,0xa3,0x8d,0x85,0x8c,0x99,0x9b,0xa3,0x99,0xb4,0x2a,0xcb,0x9b,0xad,0x3e,0x2f,0x2a,0x25,0x1d,0x24,0x1c,0x0f,0x06 +,0x07,0x06,0x07,0x0d,0x09,0x04,0x01,0x00,0x01,0x05,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00 +,0x04,0x03,0x01,0x00,0x00,0x00,0x01,0x03,0x03,0x01,0x00,0x00,0x00,0x00,0x01,0x0d,0x1b,0x10,0x04,0x03,0x0a,0x18,0x39,0x36,0x28,0x1d,0x15,0x0c,0x24,0x8d,0x84,0x86 +,0x8c,0x8a,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x81,0x81,0x80,0x80,0x80,0x82,0x84,0x83,0x81,0x81,0x82,0x86,0x8a,0x8a,0x8c,0x93,0x9c,0xc1,0xc0,0xb5,0xd2,0xd3,0x40,0xf0,0x2d,0x15,0x0d,0x0d,0x0f,0x0b,0x05 +,0x02,0x01,0x01,0x00,0x00,0x01,0x04,0x05,0x01,0x00,0x01,0x03,0x05,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x02,0x01,0x01,0x04,0x06,0x09,0x08,0x06,0x02,0x01 +,0x01,0x02,0x0c,0x1a,0x1c,0x0c,0x04,0x05,0x10,0x3a,0xb3,0xb8,0x4f,0x20,0x0e,0x0f,0x2a,0xa0,0x90,0x96,0xd4,0x27,0x32,0xc9,0x97,0x8a,0x85,0x89,0x97,0xb3,0xa5,0x8d +,0x85,0x83,0x85,0x8c,0x96,0x97,0x8d,0x88,0x88,0x8c,0x8f,0x99,0xa3,0x99,0x8b,0x84,0x83,0x88,0x92,0x9b,0x9c,0x97,0x96,0x94,0x96,0xac,0x2c,0x1c,0xd2,0x94,0x8d,0x93 +,0xa6,0xeb,0x36,0x2d,0x25,0x31,0x4b,0x2c,0x17,0x0f,0x0e,0x11,0x1f,0x38,0x66,0x5f,0x4e,0x3e,0x2a,0x25,0x25,0x20,0x19,0x11,0x11,0x1a,0x23,0x23,0x1e,0x1f,0x3b,0xac +,0xa2,0xa9,0xaa,0xb2,0xdc,0x48,0x49,0xab,0x99,0x97,0x9b,0xa1,0xa0,0xa0,0x9e,0x93,0x8d,0x8d,0x91,0x9a,0x9f,0x95,0x8b,0x88,0x8a,0x8f,0x9b,0x9c,0x93,0x8e,0x8f,0x94 +,0x99,0x9e,0xb2,0xbc,0xa7,0x96,0x8e,0x98,0xcc,0x23,0x2a,0x5a,0xb6,0xac,0xe5,0x1e,0x0f,0x0b,0x11,0x30,0xa4,0x9c,0xa9,0x40,0x23,0x24,0x36,0xd1,0xc4,0x41,0x1d,0x0f +,0x0a,0x0f,0x34,0x9e,0x98,0xa4,0x66,0x38,0x4a,0xbf,0xad,0xab,0xbc,0x28,0x13,0x14,0x22,0x4a,0xce,0x51,0x3d,0x3a,0x33,0x39,0xb5,0x9f,0xa0,0xc9,0x1e,0x17,0x1d,0x35 +,0xd9,0xda,0x4a,0x2e,0x2b,0x33,0x5f,0xb2,0xab,0xb1,0x55,0x25,0x1d,0x28,0x4e,0xbe,0xb8,0xe2,0x56,0x47,0x2e,0x27,0x35,0xdd,0x63,0x3b,0x39,0x5b,0xaf,0xa4,0xac,0xcc +,0x49,0x3d,0x3c,0x3a,0x34,0x26,0x21,0x21,0x25,0x3d,0xb9,0xa5,0x9e,0xa4,0xba,0xd3,0xc3,0xae,0xa9,0xc7,0x37,0x23,0x18,0x18,0x20,0x41,0xb5,0xb0,0xbe,0xbf,0xae,0xa4 +,0xa2,0xab,0xc9,0x2f,0x1d,0x19,0x1f,0x2f,0x4a,0xef,0xea,0xc7,0xbd,0xbb,0xae,0xa8,0xad,0xcc,0x27,0x17,0x19,0x2c,0xcd,0xaf,0xc1,0x2f,0x27,0x2c,0x4c,0xb4,0xa8,0xa6 +,0xad,0x3f,0x23,0x25,0x3f,0xbf,0xbf,0x54,0x31,0x2d,0x27,0x2c,0x5e,0xb9,0xb2,0xd8,0x2f,0x2b,0x3a,0xca,0xae,0xab,0xbe,0x6c,0x5f,0x68,0x56,0x38,0x2b,0x25,0x25,0x20 +,0x22,0x3a,0xb1,0x9e,0x9d,0xa7,0xb5,0xcb,0x6e,0x59,0x63,0x5d,0x2b,0x1c,0x1c,0x28,0xda,0xa9,0x9f,0xa3,0xab,0xb6,0xcb,0xd3,0xce,0xe2,0x49,0x2e,0x23,0x23,0x2a,0x2c +,0x3e,0xc9,0xae,0xa4,0x9f,0x9d,0xa0,0xa3,0xaf,0x4c,0x26,0x1e,0x24,0x2f,0x2f,0x2a,0x30,0xe7,0xa9,0xa1,0xa4,0xa7,0xaa,0xb3,0x4c,0x2c,0x2f,0x55,0xc6,0xc4,0xbc,0xcf +,0x41,0x36,0x2e,0x42,0xca,0xc8,0x49,0x3a,0x44,0xc6,0xaa,0xa7,0xae,0xef,0x43,0x44,0x53,0x40,0x32,0x36,0x3e,0x48,0x3e,0x47,0xd5,0xbd,0xb6,0xb3,0xc1,0xdd,0xe4,0xc7 +,0xae,0xb1,0x54,0x24,0x1b,0x1f,0x2c,0x41,0xbc,0xa3,0x9d,0x9e,0xa3,0xb0,0xbd,0xca,0x4f,0x38,0x21,0x17,0x16,0x1d,0x2f,0xad,0x9e,0x9e,0xa4,0xbc,0xd7,0xbe,0xaf,0xb4 +,0x51,0x29,0x26,0x31,0x3e,0x3a,0x35,0x39,0x4c,0xed,0x5d,0xe2,0xb0,0xa1,0xa0,0xb9,0x3c,0x36,0x36,0x37,0x3b,0x3b,0x41,0x57,0x59,0xdd,0xb5,0xa9,0xa8,0xb2,0xe2,0x3d +,0x30,0x2b,0x2c,0x46,0xb9,0xa5,0xaa,0xd7,0x2c,0x26,0x3e,0x4c,0x3f,0x3c,0x59,0xd2,0xbc,0xa9,0x9e,0x9d,0xae,0x41,0x2a,0x29,0x28,0x21,0x1e,0x28,0x4e,0xce,0xc2,0xb4 +,0xac,0xa6,0xaa,0xc5,0xcf,0xc9,0xc5,0xbf,0x46,0x2b,0x23,0x21,0x23,0x26,0x2c,0x42,0xb3,0xa5,0xa3,0xa4,0xa8,0xaa,0xb5,0x4a,0x37,0x2e,0x27,0x21,0x1f,0x28,0xcd,0xa2 +,0xa2,0xab,0xc6,0xc1,0xb0,0xd1,0x2f,0x28,0x2f,0x3a,0x54,0xeb,0xcc,0xbf,0xe5,0x3b,0x2f,0x38,0xdc,0xbc,0xbd,0xb7,0xb5,0xbb,0xcc,0x5d,0x49,0xf2,0x5a,0x2c,0x1e,0x20 +,0x3d,0xb6,0xb8,0xcd,0xc1,0xb6,0xba,0x56,0x3d,0x5d,0xb9,0xb3,0xb1,0xb4,0xcd,0x49,0x2b,0x2d,0x52,0x4a,0x25,0x1d,0x25,0xcd,0x9b,0x98,0xa4,0xb5,0xda,0xce,0xbe,0x42 +,0x24,0x1c,0x21,0x2d,0x44,0xc2,0xa8,0xa0,0xa4,0xa9,0xda,0x3a,0x36,0x39,0xed,0xba,0xd3,0x31,0x26,0x28,0x3d,0xbe,0xbf,0x50,0x4d,0xbf,0xa2,0xa2,0xb6,0x4d,0x3c,0xbe +,0xb1,0x3a,0x19,0x16,0x24,0xc4,0xa3,0xac,0xbe,0xc4,0xbe,0xab,0xa7,0xb8,0x2e,0x21,0x26,0x4e,0xa8,0xa7,0xdc,0x2f,0x42,0xb9,0xc5,0x31,0x1f,0x29,0xb1,0xa6,0xb8,0xec +,0xbe,0xae,0xab,0xb7,0x36,0x22,0x1e,0x21,0x35,0xba,0xaf,0xbd,0xcb,0xb7,0xa9,0xac,0x40,0x23,0x2e,0xb4,0xa3,0xbd,0x2c,0x1f,0x2d,0xb3,0xa7,0x5e,0x1f,0x22,0xdd,0xa1 +,0x9a,0xa6,0xbe,0xc2,0xaf,0xa8,0xb7,0x2c,0x12,0x10,0x1f,0xcd,0xa9,0xab,0xfc,0xed,0xa1,0x9c,0xaa,0x3d,0x22,0x26,0xda,0xbb,0x4a,0x30,0x47,0xbb,0xad,0xc8,0x2d,0x2b +,0x41,0xd7,0xc6,0xd0,0x49,0x4c,0xaf,0x9c,0xa0,0xfa,0x1b,0x12,0x21,0xa8,0x9b,0xc3,0x22,0x1f,0xb2,0x92,0x9a,0x40,0x1e,0x28,0xe6,0xba,0xdc,0x3d,0x32,0x3f,0xb6,0xa5 +,0xad,0x47,0x1f,0x20,0x5f,0xa9,0xa8,0xc1,0x3f,0xf5,0xa6,0xa7,0xda,0x33,0x2b,0x3a,0x45,0x2a,0x1e,0x2f,0xbc,0xa4,0xa4,0xb1,0x5d,0x30,0x3c,0xb6,0xa5,0xa7,0xc4,0x27 +,0x1f,0x25,0x47,0xb9,0xbd,0xca,0xb3,0xb8,0x60,0x2d,0xe0,0xbe,0xac,0xb6,0xbe,0xdb,0x21,0x27,0x1e,0x2f,0xd9,0xae,0xa1,0xaa,0xac,0xc2,0xb3,0xb8,0x3a,0x60,0x34,0xc4 +,0x31,0x56,0x3d,0x25,0x3f,0x2c,0x4f,0xb8,0x9c,0xa7,0xa1,0x5d,0x2e,0x1e,0x29,0x49,0xdb,0xa9,0x4e,0xc1,0x26,0x35,0x4e,0xea,0xa9,0xb5,0xd5,0x59,0xd8,0x40,0x4f,0x4e +,0xb6,0xb3,0xd1,0x48,0x3d,0xbe,0xbc,0xc2,0x30,0x27,0x3f,0x3e,0xc2,0xac,0xaf,0xb4,0x4c,0x2c,0x2c,0x65,0xab,0xad,0xc2,0x53,0x37,0x2c,0x26,0x2b,0xdc,0xaa,0x9f,0xa1 +,0xb1,0xff,0x2c,0x29,0x2f,0x44,0x38,0x50,0x58,0x4e,0x4e,0x37,0x3d,0x41,0x46,0xaf,0x98,0x92,0x9a,0xd2,0x1f,0x15,0x1c,0x26,0xcc,0xbb,0xad,0xb2,0xcf,0x42,0x2a,0x3b +,0xf5,0x9e,0x9f,0xae,0xf3,0x1f,0x1b,0x25,0x63,0x9e,0xa3,0xb7,0x56,0x44,0xd1,0x75,0x3d,0x2d,0x35,0xbf,0xae,0xb1,0xb5,0xdf,0x48,0x28,0x28,0x37,0xba,0xaa,0xb9,0x5f +,0x3a,0x3c,0x33,0x36,0xb7,0x99,0x9a,0xdc,0x23,0x1f,0x1d,0x2a,0xd5,0xa5,0x9f,0xb3,0x3b,0x26,0x35,0xdf,0xc1,0xaf,0xa7,0xa7,0xb6,0x38,0x1d,0x1f,0x32,0x4d,0xb8,0xc4 +,0x54,0xce,0x3e,0x2a,0x34,0xd7,0xb0,0xa5,0x9d,0x9d,0xaf,0x2e,0x1b,0x17,0x23,0xc2,0x9e,0x9c,0xa8,0xd4,0x2d,0x2b,0x2e,0xfc,0xab,0x9f,0xab,0x3b,0x1f,0x15,0x1d,0x3e +,0xb5,0xa4,0xa4,0xb4,0xfb,0x3e,0x3a,0xce,0xbc,0xae,0xc8,0x3d,0x3b,0x5a,0x7a,0x37,0x44,0xe3,0xb7,0xef,0x39,0x48,0xca,0xbe,0x65,0x37,0x4a,0xce,0xc2,0xb5,0xb7,0xbb +,0x61,0x33,0x27,0x24,0x3c,0xb5,0xac,0xaf,0xbb,0xbe,0xd9,0x45,0x54,0xc4,0xac,0xa8,0xb3,0xc4,0x59,0x2f,0x25,0x1e,0x24,0x38,0xc6,0xb6,0xc0,0x5b,0x3d,0x54,0xef,0xcf +,0x5d,0x48,0x4b,0x3b,0x2b,0x2c,0x52,0xb6,0xa0,0x9d,0xa1,0xae,0xf9,0x49,0x70,0xb1,0xad,0xb7,0xbc,0xda,0x3a,0x27,0x2b,0x3d,0xed,0xcd,0xc3,0xe8,0x3d,0x3c,0x2d,0x33 +,0x2f,0x2c,0x2d,0x37,0x4c,0xdc,0xbb,0xb9,0xb4,0xb7,0xb9,0xb9,0xbb,0xba,0xba,0xda,0x47,0x53,0xb6,0xad,0xb7,0x53,0x3e,0x30,0x30,0x36,0x3e,0xb8,0xb2,0x59,0x2f,0x32 +,0x2f,0x36,0x42,0xd8,0xb8,0xb5,0x77,0xed,0xc9,0xca,0xc6,0xea,0x4a,0x3a,0xc6,0xb3,0xa6,0xa2,0xa2,0xb2,0x3b,0x2c,0x28,0x2d,0x3c,0xd8,0x3d,0x2f,0x31,0x36,0x46,0xbb +,0xa8,0xaf,0xbb,0xdc,0x48,0x34,0x38,0x5c,0x6f,0x49,0x48,0x4e,0x5a,0x52,0x70,0xb1,0xad,0xb7,0xc8,0xef,0x6e,0xbe,0xbd,0x4a,0x3c,0x45,0x37,0x3c,0xda,0xb8,0xb7,0xd1 +,0x4a,0x44,0x37,0x33,0x5d,0x4a,0x4d,0xc7,0xbc,0xcf,0xbb,0xc0,0x3e,0x37,0x56,0xbf,0xb8,0xc1,0xef,0x62,0x34,0x2e,0x33,0x37,0xf3,0xa9,0xa1,0xb6,0x44,0x2f,0x25,0x2c +,0x4d,0xbc,0xaf,0xb9,0xcc,0xd1,0xe3,0xcf,0xad,0xa6,0xa4,0xad,0xdb,0x28,0x21,0x27,0x2a,0x45,0xb2,0xa8,0xaf,0xde,0x3c,0x39,0x37,0x48,0xc9,0xcb,0xec,0xd3,0x56,0x31 +,0x2d,0x31,0x3c,0xc8,0xa9,0xa5,0xac,0xbd,0xd9,0x4a,0x3b,0x40,0x3d,0x3d,0x48,0x45,0x49,0x4d,0xd2,0xc3,0x42,0x37,0x5c,0xbb,0xf3,0x3b,0x3b,0x38,0x4e,0x4b,0x5f,0xbc +,0xaa,0xa3,0xa3,0xb9,0x4e,0x57,0x6b,0xe8,0xbd,0xae,0xbc,0x48,0x28,0x25,0x2f,0xdf,0xad,0xac,0xc1,0x4c,0x2d,0x20,0x22,0x30,0xe7,0xb9,0xb3,0xb6,0xc0,0xd6,0xbf,0xae +,0xae,0xae,0xb3,0x5d,0x32,0x2b,0x2a,0x37,0x71,0xee,0x4a,0x53,0xdb,0xc5,0xd5,0xe7,0xd2,0x5d,0x47,0x3f,0x3d,0x42,0x55,0xe0,0xce,0xbf,0xb0,0xa8,0xac,0xbc,0xc4,0xc2 +,0xca,0x4f,0x33,0x2f,0x2d,0x29,0x2a,0x2e,0x3c,0xce,0xad,0xa9,0xb3,0xc9,0x59,0x3b,0x32,0x34,0x61,0xbe,0xc2,0x68,0x42,0x4c,0xd7,0xb9,0xb0,0xab,0xa6,0xb3,0x43,0x31 +,0x2d,0x31,0x4a,0xd5,0xbd,0xb8,0xeb,0x3b,0x38,0x3e,0xd5,0xbf,0xef,0x3c,0x33,0x34,0x4a,0xc5,0xb6,0xae,0xa8,0xa9,0xb5,0xd3,0xcc,0xbe,0xdc,0x41,0x32,0x27,0x1f,0x20 +,0x2a,0x53,0xb6,0xad,0xb4,0x47,0x2c,0x3e,0xcd,0xb9,0xba,0xee,0x4b,0x3c,0x37,0x3f,0xc9,0xa6,0x9f,0xa0,0xa4,0xa9,0xb3,0x4d,0x2b,0x27,0x26,0x2e,0x36,0x2d,0x2d,0x54 +,0xc2,0xc2,0xd3,0xdf,0xc0,0xbf,0x69,0x5a,0xe7,0x47,0x30,0x34,0x7d,0xb1,0xa7,0xa8,0xae,0xc5,0xc3,0xb4,0xcd,0x3e,0x2e,0x27,0x2e,0x45,0x57,0x4e,0x42,0x50,0xcf,0xc6 +,0xb7,0xac,0xb6,0x66,0x5b,0xdd,0x46,0x2d,0x2a,0x3b,0xb8,0xa3,0x9d,0xa4,0xc4,0x4b,0x35,0x2c,0x3f,0x55,0x37,0x2f,0x2c,0x27,0x24,0x2d,0xd2,0xaa,0xa1,0x9c,0xa3,0x4d +,0x24,0x27,0x3e,0xc8,0xb2,0xbb,0x53,0x3d,0x5c,0xbb,0xae,0xa6,0xa0,0xb4,0x2d,0x1f,0x1e,0x24,0x2b,0x2f,0x4f,0xb9,0xae,0xaf,0xbb,0xaf,0xa1,0xa4,0xbf,0x40,0x2f,0x2a +,0x2b,0x35,0x44,0x5a,0xc7,0xc7,0xca,0xb1,0xa3,0xa1,0xb4,0x3e,0x30,0x31,0x32,0x32,0x2b,0x25,0x2c,0x5b,0xb8,0xae,0xac,0xad,0xbe,0x7e,0x56,0x4b,0x40,0x35,0x31,0x3a +,0x68,0xb4,0xaa,0xa9,0xa7,0xa3,0xa7,0xef,0x25,0x1c,0x1f,0x2c,0x35,0x3b,0x3a,0x39,0x3c,0x56,0xad,0x9a,0x97,0x9f,0xc1,0x35,0x29,0x27,0x2a,0x2d,0x36,0xcb,0xa7,0xa8 +,0xb8,0xbe,0xb0,0xae,0xbf,0x4a,0x31,0x24,0x1b,0x19,0x1e,0x33,0xae,0x9d,0x9d,0x9f,0xa1,0xa8,0xcc,0x3b,0x47,0xe0,0x54,0x2f,0x1d,0x1a,0x29,0xc3,0xa7,0x9f,0x9d,0xa1 +,0xbd,0x42,0x36,0x34,0x3b,0x34,0x26,0x1c,0x1f,0x40,0xb5,0xa4,0x99,0x96,0x9d,0xba,0x32,0x25,0x2a,0x2e,0x29,0x1f,0x20,0x41,0xba,0xb0,0xa4,0x9a,0x99,0xa7,0x4a,0x28 +,0x23,0x26,0x2a,0x28,0x24,0x33,0xfd,0xb5,0xa6,0xa1,0x9f,0xa6,0xbb,0x43,0x3a,0x4f,0x35,0x1e,0x1a,0x28,0xbd,0xa4,0xa4,0xa6,0xa6,0xab,0xbd,0x42,0x2a,0x2d,0x3a,0x3b +,0x30,0x2a,0x37,0xcd,0xaf,0x9f,0x95,0x93,0x9f,0x3b,0x1d,0x1f,0x2f,0x31,0x20,0x19,0x1d,0x2d,0xef,0xac,0x9e,0x97,0x98,0xa2,0xbb,0x3b,0x2a,0x28,0x27,0x27,0x29,0x2f +,0x4d,0xcf,0xb8,0xa5,0x9d,0xa1,0xba,0x36,0x26,0x27,0x26,0x1f,0x25,0x4d,0xac,0xa3,0xa6,0xa9,0xa7,0xa7,0xad,0xc4,0x46,0x41,0x3a,0x1f,0x14,0x17,0x33,0xb2,0xa4,0x9e +,0x9d,0xa8,0x5e,0x2f,0x31,0x4f,0xc8,0x65,0x2a,0x1e,0x27,0x7d,0xb2,0xa9,0x9d,0x98,0x9c,0xaf,0x2f,0x1f,0x25,0x2f,0x2c,0x1f,0x1e,0x33,0xbf,0xa5,0x9c,0x9b,0x9d,0xab +,0xd9,0x43,0x42,0x45,0x28,0x15,0x11,0x1d,0x4a,0xb0,0xa4,0x9c,0x95,0x96,0x9f,0xcd,0x2a,0x25,0x2c,0x26,0x1c,0x1d,0x2a,0x4e,0xb6,0xa4,0x9f,0xa3,0xae,0xcd,0x6d,0xd4 +,0x68,0x2e,0x1a,0x15,0x27,0xb9,0xa2,0x9d,0x9d,0x9d,0xa1,0xbe,0x2f,0x28,0x35,0x41,0x2c,0x1d,0x1c,0x26,0x3f,0xaf,0x9c,0x98,0x98,0x9e,0xb7,0x37,0x2f,0x3c,0x2d,0x1c +,0x19,0x26,0x3f,0xc6,0xa6,0x9a,0x96,0x98,0xa3,0xdd,0x2e,0x28,0x21,0x19,0x14,0x1a,0x2e,0xe1,0xac,0xa3,0x9f,0x9c,0x9b,0xa0,0xb5,0x64,0x32,0x1e,0x13,0x12,0x1d,0x43 +,0xaa,0x9d,0x9c,0x9c,0x9e,0xad,0x58,0x43,0xc8,0xf4,0x23,0x14,0x12,0x1c,0x67,0xa4,0x9f,0xa1,0xa2,0xab,0xcb,0x4e,0xd4,0xbd,0x3c,0x1c,0x19,0x24,0x31,0xc2,0x9e,0x98 +,0x95,0x97,0xa1,0xd6,0x2f,0x2e,0x2a,0x1b,0x11,0x11,0x19,0x39,0xa8,0x9e,0x9a,0x96,0x98,0x9e,0xaa,0xae,0xbf,0x2e,0x18,0x13,0x14,0x1e,0x4d,0xb5,0xae,0xa0,0x9b,0xa2 +,0xb6,0x73,0x6f,0x34,0x1d,0x18,0x19,0x20,0xc6,0x9f,0x9f,0x9f,0x9f,0xa0,0xaa,0xb5,0xac,0xb5,0x2e,0x16,0x0e,0x12,0x23,0xd5,0xab,0x9f,0x9b,0x9d,0xaa,0xd4,0x70,0xcb +,0x41,0x20,0x17,0x18,0x25,0x5f,0xb1,0xa8,0x9e,0x9a,0x9c,0xa4,0xaa,0xb2,0x49,0x22,0x1a,0x17,0x18,0x21,0xc7,0xbd,0xbd,0x9e,0x99,0xa4,0xa1,0xaa,0xac,0xbc,0x1b,0x17 +,0x1d,0x29,0x28,0xad,0xae,0xd0,0x9a,0x94,0xc0,0x15,0x48,0xa7,0xdf,0x28,0x26,0x55,0xc8,0xb1,0x53,0xc2,0x2f,0x1c,0x91,0x80,0x57,0x00,0x83,0x86,0xc4,0x8d,0x19,0x20 +,0x0c,0x10,0x0c,0x14,0x0d,0x00,0x09,0x00,0x02,0x00,0x01,0x02,0x00,0x00,0x04,0x02,0x04,0x03,0x07,0x0c,0x0d,0x1f,0x23,0xd6,0x95,0x88,0x89,0x8f,0x8a,0x80,0x82,0x87 +,0x82,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x83,0x89,0x84,0x88,0x8a,0x8c,0x91,0x9c,0x9c,0xad,0xa9,0x34,0x0e,0x14,0x0a,0x0f,0x08,0x03 +,0x03,0x02,0x02,0x01,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x00,0x04,0x04,0x09,0x0f,0x16,0x20,0x1d +,0xd0,0x9e,0x97,0x8a,0x8a,0x89,0x82,0x82,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x81,0x80,0x80,0x81,0x82,0x81,0x84,0x87,0x84,0x8d,0x8c,0x98,0x9a,0xa4,0xcc,0x33,0x15,0x13,0x0c,0x06,0x04,0x05,0x02,0x04,0x00,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x02,0x02,0x02,0x04,0x05,0x06,0x06,0x09,0x0a +,0x0b,0x0f,0x14,0x17,0x1d,0x27,0x3a,0xc4,0xb6,0x9c,0x91,0x8d,0x8f,0x8d,0x8a,0x87,0x84,0x84,0x83,0x83,0x83,0x82,0x81,0x81,0x81,0x81,0x80,0x81,0x81,0x80,0x80,0x80 +,0x81,0x81,0x81,0x81,0x80,0x80,0x81,0x81,0x82,0x81,0x81,0x82,0x82,0x82,0x82,0x84,0x83,0x84,0x85,0x84,0x84,0x86,0x88,0x8a,0x88,0x87,0x8a,0x8c,0x8c,0x8d,0x8c,0x8a +,0x8f,0x8d,0x8d,0x88,0x8c,0x90,0x93,0x94,0x8b,0x90,0x8f,0x92,0x91,0x91,0x95,0x98,0x96,0x98,0x9b,0x9e,0xd8,0xbc,0xbc,0xac,0xb6,0x31,0x1c,0x18,0x16,0x0e,0x0e,0x08 +,0x06,0x05,0x04,0x03,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x01,0x01,0x03,0x06,0x08,0x09,0x0a,0x0e,0x13,0x15,0x1d,0x32,0xc8,0xa5,0x9c,0x95,0x8c,0x86,0x82 +,0x82,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x83,0x83,0x84,0x86,0x88,0x89,0x8b,0x93,0x9b,0x9f,0xa9,0xaf,0x65,0x32,0x21,0x18,0x12,0x0f,0x0c,0x06,0x04,0x05,0x04,0x03,0x02 +,0x01,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x01,0x03,0x04,0x03,0x03,0x04,0x06 +,0x07,0x07,0x09,0x0b,0x0d,0x10,0x15,0x17,0x13,0x15,0x21,0x2a,0x2d,0x4a,0xc5,0xbc,0xb0,0xa5,0xa1,0xa0,0xa0,0x9d,0x95,0x95,0x92,0x8c,0x8c,0x8c,0x8e,0x8c,0x89,0x8a +,0x8b,0x8a,0x8c,0x8d,0x8a,0x87,0x88,0x8c,0x8b,0x89,0x8b,0x8d,0x8d,0x8c,0x8d,0x8e,0x8f,0x8e,0x92,0x93,0x91,0x98,0xad,0xa0,0x96,0x9e,0xaf,0xb5,0xac,0xb6,0xc9,0xba +,0xbf,0x3e,0x2d,0x39,0x57,0x29,0x27,0x43,0x3f,0x23,0x1d,0x23,0x25,0x1f,0x1e,0x1f,0x1a,0x19,0x23,0x2f,0x23,0x1e,0x26,0x30,0x29,0x23,0x2a,0x2e,0x23,0x2b,0xc5,0xe6 +,0x4f,0xef,0xae,0xb0,0x58,0xa9,0x99,0x9d,0xa1,0x9e,0x93,0x92,0x99,0x95,0x91,0x95,0x98,0x8e,0x8e,0x95,0x90,0x8c,0x8d,0x92,0x92,0x8e,0x8f,0x95,0x91,0x90,0x99,0x9c +,0x96,0x93,0xa2,0xeb,0xaf,0xa4,0xcd,0x4b,0xcb,0xcb,0x2d,0x29,0x53,0x31,0x22,0x29,0x32,0x2b,0x1d,0x22,0x2d,0x28,0x21,0x2f,0x5a,0x2a,0x24,0x2d,0x34,0x22,0x27,0xdb +,0x48,0x21,0x26,0x4a,0x44,0x2d,0x30,0x4e,0x2f,0x23,0x34,0xc8,0x55,0x2c,0x3e,0xdf,0x2f,0x1f,0x3f,0xc9,0x2e,0x26,0x3b,0x4a,0x31,0x46,0xcb,0x45,0x2e,0x32,0x7a,0x42 +,0x2a,0x3c,0x78,0x30,0x23,0x45,0xbb,0x36,0x31,0x45,0x32,0x27,0x3e,0xb8,0xcf,0x2e,0x2c,0xe6,0x76,0x3d,0x36,0x47,0x35,0x2b,0xe0,0xb7,0x4c,0x2c,0x52,0xbf,0x66,0x3f +,0xee,0x49,0x2f,0x43,0xc9,0xd6,0x3b,0x4f,0xbd,0x59,0x2c,0x2e,0xdd,0xed,0x36,0xc7,0xbf,0x3a,0x29,0x5e,0xb5,0x63,0x47,0x59,0x61,0x2f,0x49,0xb8,0xbb,0x31,0x28,0xca +,0xc6,0x3b,0x35,0x5d,0x36,0x32,0xc5,0xd0,0x32,0x32,0xdf,0xbe,0x45,0x2d,0x3b,0x3f,0x33,0x45,0xaf,0xbc,0x2b,0x34,0xc4,0x52,0x3a,0x43,0x5b,0x39,0x31,0xeb,0xb8,0xc0 +,0x3c,0x45,0xf4,0x42,0x36,0x49,0xe2,0x3f,0x44,0xdd,0xbe,0x3e,0x39,0xc3,0x67,0x43,0x3d,0xdd,0x5f,0x43,0xbe,0xb8,0x6f,0x38,0x48,0xc8,0x7c,0x36,0xce,0xce,0x3a,0x47 +,0xb8,0xb7,0x33,0x51,0xb6,0xc9,0x50,0x43,0x46,0x43,0x38,0x69,0xad,0xb1,0x59,0x38,0x38,0x38,0xd3,0xaf,0xc3,0x3a,0x3f,0xfe,0xb7,0xbf,0xcf,0xcb,0x3d,0x3e,0x34,0x4e +,0x63,0x4c,0xdd,0xbc,0xeb,0x37,0x44,0xd6,0xbd,0xdf,0xbe,0xef,0x4b,0x46,0xcf,0xbe,0x38,0x3e,0x49,0x7d,0x63,0x39,0x3e,0x58,0x63,0xbd,0xb2,0xd1,0x30,0x38,0xcc,0x59 +,0x52,0xc1,0x4a,0x2f,0x4f,0xcc,0xae,0xcd,0x50,0xe5,0x39,0x3b,0x45,0xbf,0xd5,0x43,0xcb,0xc5,0xd7,0x58,0x39,0x4c,0xc3,0xeb,0x60,0x43,0xf9,0xbb,0xd0,0x4d,0x33,0xf1 +,0xc7,0x7e,0x41,0x2c,0x55,0xae,0xb2,0xbf,0xc6,0x48,0x3c,0x44,0xc6,0xc6,0xe4,0xc3,0x4e,0x37,0x56,0xba,0xb8,0x4f,0x35,0x7e,0xcd,0xfa,0x3d,0x42,0x47,0x53,0xb3,0xb3 +,0xc9,0x48,0x3d,0x4d,0x59,0x4d,0xda,0xe2,0xc4,0xd0,0xc7,0xbd,0x44,0xc2,0xd0,0x52,0x5e,0x44,0x3d,0xe3,0xbd,0xd3,0x5e,0x35,0x39,0x6c,0xbd,0xe6,0x53,0x64,0x3f,0xbb +,0xad,0xdc,0x55,0x49,0x4c,0x46,0x48,0xdf,0xeb,0xbb,0x4b,0x31,0xc9,0xad,0xb7,0x42,0x27,0x43,0xae,0xc5,0xdb,0x3b,0x3a,0xce,0xac,0xae,0x48,0xdf,0xe7,0x2f,0x28,0x36 +,0xdd,0xc0,0xc3,0x4a,0xd8,0xc7,0xb8,0xb3,0x45,0x2d,0xcb,0xa6,0x6b,0x5e,0xce,0x47,0x3d,0x36,0x5f,0x63,0x49,0x69,0xfa,0x5c,0x73,0xb9,0xa7,0xab,0x68,0x34,0x2f,0x35 +,0xbf,0xc0,0x4d,0x35,0x2e,0x4b,0xa7,0xa0,0x51,0x3d,0x2d,0x5e,0xb5,0x52,0x3c,0x2e,0x38,0xe8,0xad,0xbc,0xd7,0xfe,0xbf,0x75,0x39,0xc9,0x47,0xc7,0xbb,0x36,0x3b,0xc2 +,0xb1,0xf8,0x33,0x2b,0xeb,0xa9,0xd7,0xf7,0xb4,0xc0,0x34,0x2a,0x32,0xc3,0xad,0xbd,0x50,0x22,0x42,0xa5,0xa2,0xbd,0x26,0x4c,0xae,0xb0,0xc1,0x2f,0x23,0x2e,0xee,0xdd +,0xb1,0xc4,0xd1,0x73,0x39,0xc6,0xb3,0xaf,0x40,0x3c,0x2d,0x35,0xc2,0xaf,0xb2,0x3a,0x39,0x27,0x2c,0xbd,0xaf,0xd9,0xd4,0x60,0x4c,0xac,0xac,0x4d,0x2f,0x3e,0xb2,0xaf +,0x67,0x79,0xc6,0xe2,0x2e,0xd6,0xbf,0x3d,0x29,0x35,0x46,0x35,0xb3,0xac,0xbc,0x30,0x40,0xb7,0xa7,0xb2,0xd7,0xc7,0x3c,0x4d,0x27,0x21,0xba,0x9b,0xac,0x2a,0x1d,0x32 +,0xa5,0x9d,0xc3,0x29,0x2e,0xc5,0xab,0xae,0x38,0x22,0x3a,0x3e,0xb5,0xb8,0x31,0x2e,0xb9,0xbc,0x3e,0xac,0xac,0x42,0x21,0x35,0xba,0xb3,0xda,0xd5,0xd5,0x29,0x42,0xc6 +,0xb8,0xc6,0x3c,0xb4,0xb7,0x3b,0x3e,0xcd,0x4b,0x3e,0x6d,0x59,0xc2,0xba,0xae,0x51,0x29,0x27,0x4c,0xab,0xb6,0x64,0x2a,0x38,0xae,0x9c,0x9c,0x3e,0x1a,0x22,0xbd,0xa6 +,0xbc,0xd9,0x2d,0x3f,0xd6,0xca,0xce,0x51,0x4c,0x72,0xbe,0x22,0x2d,0xb3,0x9c,0xb2,0x5d,0xaf,0xdc,0x38,0x1e,0x38,0x3c,0x47,0xd0,0xdb,0xdc,0x3e,0xbf,0xa3,0xcd,0x20 +,0xc2,0xa9,0x3d,0x1f,0x22,0xb7,0x99,0x9c,0xa9,0x2a,0x1d,0x4c,0xb6,0x4a,0x28,0x36,0x5c,0xb1,0xbb,0x7a,0x3e,0x37,0x48,0xaf,0xad,0x2e,0x31,0x5a,0xa6,0xa9,0xba,0xcb +,0x35,0x29,0x2b,0xbb,0xdc,0x3f,0x38,0xbf,0xa8,0xc4,0xc2,0xb7,0x42,0x2f,0xb2,0xa5,0x43,0x1a,0x1a,0xd6,0x9a,0x9c,0xbd,0x24,0x19,0x22,0xa3,0xa6,0x34,0x28,0xaa,0x9d +,0xbf,0x33,0x26,0x28,0x4b,0xae,0xd7,0x23,0x1e,0xaf,0x96,0x9b,0xb2,0x57,0x38,0x2e,0x1c,0x65,0x2c,0x3d,0xbf,0xa4,0x9e,0x35,0x4c,0x29,0x22,0x31,0x99,0xb3,0x30,0x1f +,0x27,0x9e,0x8e,0x9d,0x48,0x36,0x1d,0xb0,0x9a,0xb9,0x1c,0x12,0x59,0x9a,0xa8,0x28,0x36,0xb8,0xc9,0xad,0x57,0x36,0x2b,0x72,0x99,0xa5,0x47,0x20,0x39,0x3d,0xcf,0x40 +,0x1b,0x2d,0xbc,0x99,0xba,0x32,0x1f,0x3a,0xbd,0xaa,0x9e,0xcd,0x2d,0x1e,0x3d,0x9c,0x9a,0x41,0x29,0x1f,0x3c,0xca,0x9c,0xb9,0x1d,0x34,0xae,0x97,0x5b,0x12,0x14,0xbc +,0x94,0x9c,0xbe,0x2c,0x21,0xbe,0xa0,0xc8,0x2f,0x29,0xc1,0xc0,0x34,0x2f,0xe1,0x9e,0xa1,0xae,0x3c,0x1d,0x28,0xac,0x9f,0x5d,0x29,0xca,0xbb,0x34,0x7e,0xab,0xb3,0x23 +,0x1c,0xcd,0xd1,0xc3,0x55,0x28,0xf3,0xce,0xaa,0xa9,0x2a,0x16,0x22,0xa6,0x9a,0x9a,0xc7,0x1b,0x27,0xdb,0xa1,0xad,0x33,0x1f,0xb9,0xa3,0x68,0x36,0xb8,0x9c,0xca,0x24 +,0x21,0x1c,0x1f,0xaa,0xa6,0xbe,0x3b,0xb1,0x9a,0xb8,0x37,0x2d,0x3f,0xb9,0x3f,0xa3,0xac,0x2b,0x3d,0x43,0xbe,0xc7,0xb7,0x39,0x1a,0x13,0x32,0x9e,0x8e,0x97,0x7a,0x2b +,0x2e,0xa7,0xab,0x2d,0x11,0x14,0xaf,0xa7,0x44,0x37,0xb0,0x9a,0xe2,0x2d,0x28,0x2b,0x67,0xf1,0xb9,0xac,0x9f,0xb2,0xa9,0x47,0x1a,0x26,0x70,0xde,0x4a,0x4e,0x31,0xb2 +,0xbf,0xad,0x9e,0xb7,0x2e,0x22,0x34,0x31,0x2e,0xa5,0x9a,0xb4,0x3c,0x5f,0xd9,0x36,0x3e,0x27,0x31,0x48,0x9a,0x96,0x33,0x1a,0x3e,0x9c,0xac,0x29,0x22,0x2e,0x28,0x5d +,0xbb,0x9c,0x9c,0xad,0xb8,0x17,0x17,0x29,0xad,0x9c,0x70,0x36,0x45,0xb2,0xa8,0x43,0xbc,0x33,0x19,0x38,0x42,0x40,0xdb,0xa8,0x96,0xaf,0x24,0x2f,0x47,0xba,0x3e,0x3b +,0xbd,0xcb,0xb3,0xb1,0x76,0x20,0xdb,0xa0,0x34,0x2e,0x1d,0x2d,0xa6,0xb7,0xbb,0xba,0xba,0x78,0xca,0x5a,0x4e,0xe3,0xa4,0xbe,0x40,0x28,0x45,0xb0,0x3a,0xb1,0x2a,0x28 +,0x30,0xd8,0x9b,0xca,0x26,0x51,0xb3,0xa2,0x48,0x3a,0xd2,0x2b,0x4f,0xc1,0x9f,0xca,0x2d,0x1f,0x1f,0x2b,0x69,0xba,0xa2,0xbe,0x43,0x9e,0xb7,0xaf,0x26,0xbe,0x6a,0x21 +,0xba,0x29,0x3f,0xd6,0xa0,0x9d,0x36,0x19,0x22,0x33,0xa7,0xa5,0xb8,0xbb,0x45,0x9f,0xad,0x31,0x19,0x28,0xa7,0x3e,0x2c,0x3d,0x38,0x9c,0x9f,0xac,0xa9,0x36,0x2f,0x1b +,0xd9,0xbe,0x3f,0xb5,0xac,0x67,0x23,0x3c,0x2e,0x24,0x29,0xac,0xac,0xb5,0x3a,0xb9,0x9f,0xc0,0xac,0xfc,0x2f,0x17,0x31,0xa8,0xbc,0xd8,0xaf,0xb6,0xc4,0xb7,0xcf,0x21 +,0x15,0x60,0xb2,0xa8,0xb4,0x4b,0x3d,0xb0,0xa4,0xbc,0x3e,0x1d,0x1d,0x6b,0xa6,0xb4,0xa8,0x6d,0xe3,0x5e,0x31,0x48,0x2a,0x34,0x29,0xf9,0x9c,0xa2,0xc2,0xbb,0xac,0x3b +,0x21,0x61,0x2b,0x1e,0x4f,0xbc,0x9b,0xbb,0x46,0xa7,0xab,0xc1,0x1c,0x1b,0x39,0x42,0xa0,0x9f,0x44,0x34,0x4d,0xb1,0x4c,0xf1,0xba,0x24,0x3d,0x4b,0xee,0xb3,0xc9,0xd4 +,0x44,0xbc,0xbb,0x6f,0x3f,0x1f,0x30,0xa1,0xac,0xc1,0x44,0x42,0xed,0xe4,0xbb,0x31,0x3e,0x65,0x33,0x63,0xa0,0xa7,0x41,0xbf,0xa6,0x25,0x1f,0x59,0x40,0xb3,0xba,0xbc +,0x37,0x1d,0x56,0xa6,0xa5,0xca,0x2c,0xd8,0xc7,0x44,0xb9,0xd9,0x35,0x2a,0xb8,0xb5,0x4a,0xd0,0x1d,0x2c,0xa4,0xa4,0xc9,0x30,0xd9,0x26,0x33,0x9b,0xa2,0xd1,0x2f,0x2f +,0x39,0xd4,0xa9,0x57,0x37,0xaf,0xb8,0xcf,0x26,0x27,0xdb,0x60,0xb5,0x5f,0xd6,0x31,0x2d,0x94,0xa4,0x38,0x2a,0x2c,0x34,0x3a,0xa4,0xba,0x33,0x33,0xdf,0xb0,0xa7,0x3c +,0x18,0x3c,0x97,0x9d,0x37,0x38,0x1d,0x1e,0xbf,0x99,0x92,0xcd,0x21,0x20,0x20,0xd6,0xbe,0xb4,0xcc,0x2d,0xad,0xa2,0x50,0x2e,0x2e,0x3d,0x41,0xcf,0xaf,0x28,0xcd,0xaa +,0xac,0xa7,0x3c,0x43,0x1d,0x2b,0xce,0x41,0x9f,0xa4,0xbc,0xb6,0x2b,0x24,0x29,0xa6,0x9d,0x2e,0x1d,0x16,0x2e,0xb0,0x95,0x8e,0xaa,0x1c,0x10,0x32,0xa9,0xca,0xb3,0xaf +,0xe8,0x5d,0xb6,0xa7,0x28,0x1c,0x41,0xaf,0xad,0x26,0x1f,0x40,0xca,0xac,0xa2,0x9a,0x61,0x1b,0x23,0x2f,0x3f,0xe0,0xad,0x9f,0x9f,0xaa,0x4a,0x14,0x1d,0xbb,0xae,0xb4 +,0x23,0x27,0xb7,0xa3,0x8f,0x9a,0x3b,0x0c,0x0c,0xb2,0x9e,0x9d,0x5d,0x2b,0x58,0x39,0xa1,0xa8,0x2f,0x1f,0x19,0x9d,0xa2,0x22,0x2f,0x39,0xa0,0xaa,0x95,0x9a,0x16,0x12 +,0x19,0xc0,0xac,0x6f,0xa3,0xb4,0xb4,0xbc,0x35,0x38,0x1f,0xc2,0xa0,0xd1,0x2a,0x1b,0xe6,0xab,0xa1,0x96,0xb7,0x1e,0x17,0x2b,0xbb,0xd0,0x36,0x45,0x9e,0x98,0xb1,0x3b +,0x18,0x10,0xe5,0x90,0x9b,0x23,0x15,0x2c,0x64,0xa0,0x8e,0xb3,0x19,0x12,0x2c,0x95,0x9f,0x4f,0x1d,0x37,0xb6,0xbc,0x95,0xad,0x34,0x36,0x3c,0xe5,0x15,0x16,0xfc,0xa1 +,0x8f,0x9f,0xac,0x39,0x16,0x2b,0x55,0xaf,0x2d,0x21,0xa7,0xbd,0xaa,0xa2,0x3b,0x3c,0x55,0xa8,0x23,0x0e,0x1a,0x2c,0x90,0x8b,0x8f,0xbf,0x0d,0x16,0x60,0x93,0xa1,0x13 +,0x17,0xcd,0xa3,0x9c,0xa4,0x3e,0x1e,0x25,0xb8,0xa9,0x69,0x15,0x18,0xaa,0x97,0x8f,0x9f,0x37,0x22,0x1d,0x6d,0x3f,0x1b,0x29,0xb1,0x97,0x98,0xb5,0x35,0x2f,0x6b,0x36 +,0x25,0x2b,0x1a,0x3f,0x96,0x90,0x92,0x50,0x1e,0x16,0x3c,0x95,0x31,0x0e,0x0e,0xb2,0x89,0x8d,0x9d,0x17,0x15,0x6b,0xae,0x9c,0x2c,0x0c,0x1b,0xb4,0x8e,0x8d,0x9d,0x1e +,0x09,0x1c,0x7c,0x9f,0xa8,0x1e,0x34,0xb0,0x93,0x96,0x42,0xc4,0x21,0x1c,0x4d,0x21,0x0e,0x17,0x92,0x86,0x8e,0xae,0x1d,0x1b,0x20,0x1d,0x31,0x2e,0x27,0xac,0x97,0x8d +,0xa3,0x39,0x37,0x20,0x55,0xba,0x1c,0x0c,0x1c,0x9f,0x8d,0x89,0x9e,0x0f,0x13,0x35,0xb9,0xa5,0x29,0x17,0x40,0x9d,0x9b,0xa3,0xa7,0x3e,0x0f,0x14,0xc8,0xa1,0x37,0x1f +,0xb9,0x91,0x87,0xaf,0x18,0x1e,0x19,0x1f,0x5c,0x46,0x24,0xaf,0x91,0x97,0xa4,0xcf,0xdf,0x61,0x1a,0x12,0x0f,0x1a,0xb2,0x9c,0x8b,0x8b,0xa7,0x4a,0x1c,0x0f,0x24,0xab +,0x2a,0x0d,0x4c,0x99,0x90,0x8f,0x49,0x1e,0x19,0x30,0xb5,0x3b,0x20,0x27,0x9f,0x8a,0x90,0xbb,0x34,0x18,0x0f,0x19,0x4a,0x35,0x32,0xb4,0xba,0x92,0x8e,0xad,0xc3,0x31 +,0x1a,0x19,0x17,0x16,0x28,0x91,0x83,0x90,0x2f,0x1c,0x34,0x32,0x24,0x1f,0x0f,0x1b,0xc0,0x9f,0x89,0x8e,0xae,0x37,0x19,0x1c,0x54,0xb5,0x19,0x14,0xa9,0x8c,0x8e,0xaa +,0x1f,0x10,0x20,0xa0,0xb6,0x1d,0x2f,0xdb,0x95,0x8f,0xd9,0x29,0x4c,0x20,0x0f,0x28,0x2d,0x28,0xbc,0x98,0x8e,0x8e,0xab,0x2a,0x4b,0x44,0x1d,0x13,0x1e,0x1b,0x34,0x98 +,0x8c,0x98,0x40,0x31,0x2a,0xc3,0x73,0x13,0x0c,0x2c,0x91,0x85,0x8a,0xbc,0x23,0x17,0x18,0x2a,0xed,0x1e,0x10,0x3c,0x90,0x8c,0xa7,0xe2,0x3f,0x1a,0x36,0xbb,0x1d,0x1f +,0x58,0x9d,0x8d,0x94,0x43,0x2b,0xf0,0x28,0x16,0x11,0x15,0xe9,0x9a,0x9d,0x9d,0x9d,0x9f,0x3d,0x39,0xff,0x19,0x19,0x1d,0x1e,0xa3,0x83,0x8b,0x2c,0x1a,0x2e,0xc0,0xdd +,0x14,0x0a,0x13,0xb5,0x8e,0x8e,0xaa,0x4f,0xa2,0xaf,0x2c,0x1b,0x15,0x16,0x6d,0x8d,0x8c,0xb7,0x2c,0x4d,0x24,0x18,0x37,0x5f,0x21,0x28,0xb9,0x97,0x91,0xa7,0x3a,0x3f +,0xb2,0xc4,0x1a,0x0d,0x19,0xbd,0x93,0x8b,0xa4,0x44,0x34,0x3c,0x9c,0x3b,0x09,0x0c,0x26,0xab,0x8e,0x8f,0xd9,0x2e,0xb2,0xce,0xd3,0x29,0x0f,0x17,0xca,0x88,0x8e,0xf1 +,0x26,0xd1,0x9e,0x38,0x0d,0x0f,0x24,0x36,0xa4,0x99,0x9e,0xbd,0xb0,0xc8,0x52,0x4c,0x2c,0x34,0x32,0xae,0x9a,0x9a,0xad,0x2d,0x27,0x2d,0x3b,0x17,0x0a,0x17,0xaa,0x8c +,0x91,0xad,0x2b,0xa4,0x94,0x9f,0x7c,0x0e,0x07,0x26,0xa2,0xad,0x5a,0xe2,0xa0,0xa1,0x9e,0xcc,0x23,0x07,0x18,0x45,0xcc,0x86,0x8a,0xb8,0xae,0x8d,0x8f,0x1b,0x0d,0x20 +,0x9c,0x1e,0x08,0x0f,0x00,0xbb,0x81,0x94,0x0b,0x09,0x3c,0x9d,0x8d,0x85,0x9c,0xa5,0x24,0x47,0x8f,0x99,0x8f,0x15,0x15,0x31,0xbf,0x1e,0x0b,0x0a,0x1f,0x94,0x38,0x07 +,0x04,0x0e,0x8d,0x80,0x85,0xa6,0x1f,0x8e,0x81,0x88,0xb5,0x0f,0x0a,0x01,0x06,0x03,0x0c,0x99,0x94,0x9c,0xb7,0x9f,0xb1,0x10,0x26,0x8b,0x85,0xaf,0x0a,0x0a,0x1e,0x8b +,0x80,0x99,0x0a,0x04,0x26,0x9c,0xaa,0xd6,0x17,0x0d,0x38,0x24,0x0e,0x0a,0xa4,0xa9,0x6b,0x95,0x99,0x9b,0xba,0x8f,0x84,0x85,0x9d,0x0a,0x05,0x0a,0x9e,0x8d,0x21,0x07 +,0x09,0x27,0x2c,0x41,0x22,0x1d,0xc8,0x5b,0xa8,0x9f,0x94,0x86,0x84,0x81,0x8c,0x62,0x0d,0x04,0x0d,0x20,0x36,0x07,0x02,0x14,0x2a,0x8b,0x82,0x9d,0x0a,0x18,0x88,0x88 +,0xae,0x42,0xb0,0x9f,0x9c,0xa9,0x1a,0x10,0xa6,0xd3,0x2b,0x19,0x20,0x22,0x13,0x9a,0x8c,0xaf,0x08,0x04,0x15,0xb2,0x87,0x82,0x9c,0x1d,0xaa,0x85,0x85,0xa0,0x18,0x09 +,0x16,0x1b,0x0c,0x03,0x0d,0x9d,0x8e,0x94,0x49,0x10,0x0f,0xda,0x8c,0x86,0x8d,0x2a,0x0a,0x38,0x8a,0x80,0x8f,0x17,0x07,0x09,0x27,0x37,0x20,0x1e,0x22,0x65,0x3d,0x1c +,0x0b,0x25,0x87,0x82,0x89,0x56,0x23,0x43,0xaf,0x8f,0x88,0x9c,0x09,0x01,0x04,0x1b,0x8f,0x8b,0x4e,0x16,0x36,0x97,0x25,0x0b,0x1d,0x9f,0x93,0x44,0x18,0x0e,0x95,0x80 +,0x80,0x8b,0x1a,0x07,0x12,0x3a,0xd6,0x27,0x14,0x0b,0x07,0x10,0x49,0x92,0x99,0xfd,0x28,0xa9,0x87,0x89,0x96,0x97,0x8d,0x8d,0xaf,0x0b,0x03,0x14,0xa6,0xa4,0x1f,0x06 +,0x0a,0x2e,0xa9,0x9e,0xb7,0x20,0x0b,0x21,0x9e,0x9b,0x90,0x8b,0x93,0xc3,0xc3,0x94,0xa7,0x23,0x1d,0x1d,0x23,0x12,0x0e,0x17,0x9e,0x87,0x91,0x24,0x08,0x12,0xa0,0x8c +,0x8e,0xa6,0x65,0x26,0x24,0xb6,0x91,0x8a,0xac,0x18,0x0f,0x1c,0x26,0x1d,0x2e,0xc7,0x3e,0x37,0x1a,0x0b,0x0f,0x99,0x81,0x88,0xa6,0x19,0xf9,0x90,0x8b,0x93,0xb2,0x17 +,0x08,0x08,0x0d,0x12,0xcb,0x97,0xc2,0x18,0x1e,0xaa,0xac,0xa1,0x96,0x95,0xcf,0x17,0x1b,0xca,0x8e,0x86,0x8b,0x5b,0x0c,0x14,0xb2,0x9f,0x54,0x16,0x11,0x11,0x18,0x1a +,0x1a,0xc3,0x9b,0x93,0x9d,0xab,0xa6,0xa2,0x9b,0x9b,0x9f,0xb0,0x2a,0x0e,0x14,0xb4,0x97,0xcf,0x18,0x12,0x1d,0xe2,0x75,0x2e,0x3c,0x71,0x4f,0xa8,0xa1,0x9e,0x90,0x8e +,0x9c,0x3a,0x2b,0x5d,0x30,0x24,0x23,0x28,0x18,0x0c,0x0d,0x1e,0xab,0x97,0x9c,0xd3,0x3c,0x9c,0x8b,0x93,0xa6,0xae,0xc2,0x2f,0x1f,0x1c,0x38,0xa4,0xa3,0x57,0x1c,0x1b +,0x2d,0x3f,0x4c,0x30,0x1b,0x15,0x1e,0x2a,0xc2,0x8d,0x87,0x8d,0xa4,0x36,0xd4,0x9b,0x93,0x9c,0x49,0x16,0x0e,0x0d,0x0b,0x14,0xcf,0xa9,0x46,0x18,0x19,0xca,0x98,0x8d +,0x8f,0x9b,0xb1,0x29,0x22,0xc5,0x99,0x92,0x93,0xef,0x15,0x1b,0x2b,0x2c,0x25,0x23,0x1c,0x17,0x13,0x17,0xc1,0x8e,0x89,0x8e,0xad,0xd1,0xb0,0xb2,0xad,0xaa,0xac,0x57 +,0x19,0x0f,0x1b,0xb9,0x9f,0xce,0x18,0x10,0x1c,0x27,0x2e,0xc9,0x9d,0x9b,0xaf,0x35,0x2a,0xb5,0x90,0x8a,0x97,0xba,0xcf,0xe9,0xd2,0x4b,0x1e,0x15,0x11,0x0c,0x0e,0x1b +,0x2f,0xb0,0x9b,0x9a,0x98,0x95,0x95,0x9b,0xad,0xc3,0xcc,0x4e,0x28,0x1c,0x2f,0xaf,0xab,0x51,0x1e,0x18,0x24,0x6f,0x36,0x23,0x24,0x35,0xc5,0xab,0xaf,0xb1,0x9d,0x97 +,0x9c,0xb1,0xcc,0xb8,0xbc,0xfe,0xc7,0xe4,0x26,0x14,0x0e,0x18,0xc8,0xac,0x30,0x1d,0x34,0xa3,0x92,0x9a,0xbc,0xb9,0xaf,0xcf,0x38,0x4b,0xa6,0x9b,0x9e,0xb0,0x31,0x29 +,0x28,0x18,0x14,0x1a,0x1b,0x1f,0x1c,0x17,0xb9,0x8a,0x87,0x8c,0x9d,0xbc,0xac,0xa9,0xf9,0x46,0x4f,0x32,0x1f,0x16,0x16,0x21,0x62,0xb2,0x40,0x1f,0x29,0x59,0xb7,0x9e +,0x9d,0xa6,0xbf,0x2d,0x27,0xce,0xa5,0x9c,0x9c,0xb8,0xda,0xb1,0xaf,0x4e,0x23,0x1a,0x17,0x14,0x0f,0x17,0x2a,0xaf,0x98,0x91,0x97,0x9d,0xa1,0xaf,0xab,0xaf,0xbf,0xce +,0x29,0x20,0x55,0xad,0xaf,0x49,0x1f,0x18,0x1a,0x1b,0x1e,0x33,0xb7,0xaa,0xb7,0xc4,0xaa,0x99,0x92,0x94,0xb5,0x39,0xda,0xd3,0x70,0x44,0x2c,0x27,0x1c,0x0f,0x13,0x21 +,0x47,0xae,0xb7,0xb3,0x9d,0x95,0x98,0xa6,0xc4,0xc7,0xf8,0x27,0x1f,0x2a,0x50,0xa2,0x9b,0xa7,0xc8,0x37,0x25,0x20,0x1e,0x1c,0x1d,0x1c,0x20,0x2d,0xb8,0x95,0x8e,0x91 +,0x9b,0xaa,0xc5,0xb8,0xad,0xb4,0xbe,0x35,0x1c,0x1a,0x1b,0x1d,0x29,0x2e,0x1e,0x1f,0x2f,0xc6,0xa3,0x98,0x99,0x9e,0xab,0x4d,0xf2,0xbb,0xaa,0xa9,0xba,0x5c,0xcf,0xb4 +,0xc8,0x30,0x1c,0x18,0x13,0x12,0x17,0x22,0xb2,0x95,0x91,0x95,0x9a,0x9b,0x9f,0xab,0x79,0x30,0x2c,0x29,0x25,0x29,0xbe,0xa0,0xa4,0x42,0x1f,0x1c,0x24,0x29,0x23,0x2d +,0x37,0x4c,0xbf,0xab,0xa1,0x9d,0x9e,0xa6,0xbe,0xd8,0xb6,0xab,0xa9,0xb9,0x30,0x1a,0x12,0x11,0x15,0x1c,0x29,0x43,0xb8,0xa2,0x99,0x94,0x91,0x95,0x9e,0xb8,0x2d,0x1f +,0x1d,0x22,0x49,0xb6,0xa9,0xae,0x71,0x29,0x27,0x2d,0x3a,0x3d,0x23,0x1d,0x1e,0x33,0xa5,0x8f,0x8f,0x9c,0xc8,0x3a,0xfd,0xaf,0xa9,0xb8,0x66,0x2b,0x1f,0x1d,0x28,0xdd +,0xc9,0x2d,0x18,0x19,0x2f,0xac,0x9e,0xa2,0xa9,0xad,0xbb,0x49,0x45,0xb5,0xa2,0xa5,0xad,0xaf,0xb0,0xba,0xfa,0x27,0x1c,0x15,0x12,0x12,0x12,0x1b,0x5e,0x9c,0x90,0x8e +,0x96,0x9c,0xa4,0xa9,0xa6,0xb5,0x2c,0x1b,0x19,0x1d,0x4a,0xb1,0xb8,0x4d,0x28,0x1e,0x1f,0x33,0xc0,0xa7,0xb5,0x3c,0x3d,0xb3,0x9d,0x9f,0xab,0xbb,0x58,0x3f,0x5a,0xb9 +,0xa7,0xa7,0xcf,0x23,0x19,0x14,0x1b,0x26,0x2d,0x35,0x4c,0xbc,0xa4,0x99,0x9a,0x9a,0x9e,0xab,0xc8,0x2e,0x1f,0x2e,0xbc,0xab,0xab,0x6d,0x2a,0x21,0x1f,0x23,0x2f,0x2f +,0x24,0x21,0x23,0x59,0x9b,0x8e,0x8e,0x9c,0xc5,0x53,0xc7,0xad,0xb5,0x41,0x29,0x23,0x1f,0x20,0x25,0x2a,0x49,0x45,0x2d,0x2d,0x3a,0xb8,0x9b,0x96,0x9f,0xb1,0x43,0x2c +,0x3e,0xd1,0xc3,0xb1,0xa9,0xa2,0xa9,0x6b,0x38,0x35,0x2f,0x23,0x19,0x12,0x10,0x17,0x2c,0xa3,0x91,0x8e,0x95,0xa8,0xb3,0xa3,0x9c,0x9f,0x68,0x1d,0x18,0x24,0x55,0xb8 +,0x4f,0x20,0x1c,0x1c,0x24,0x3d,0x5e,0xc8,0xa5,0xa5,0xaf,0xa4,0xa0,0xa2,0x9f,0xa9,0x75,0x37,0x2e,0x3c,0x79,0x5d,0x3d,0x2b,0x22,0x1a,0x1a,0x28,0x3e,0x40,0xc7,0xa0 +,0x99,0x99,0x9f,0xbe,0xc9,0xad,0xae,0x48,0x1d,0x18,0x32,0xa3,0x9e,0xab,0x3e,0x24,0x27,0x32,0x42,0x2c,0x19,0x18,0x25,0xd7,0x9f,0x96,0x9c,0xa1,0x9d,0x9d,0x9f,0xae +,0x60,0x4a,0x67,0x32,0x20,0x1b,0x18,0x18,0x1c,0x2a,0x32,0x40,0xce,0xac,0x9e,0x97,0x99,0x9f,0xa4,0xad,0xc9,0x46,0x1f,0x1d,0xd3,0x9d,0x9f,0xdf,0x1c,0x14,0x29,0xbd +,0xc3,0x21,0x11,0x14,0x40,0x9b,0x93,0x99,0xa8,0xaf,0xad,0xa1,0x9f,0xb5,0x2f,0x22,0x28,0x55,0xae,0xcb,0x2b,0x21,0x23,0x2d,0x2f,0x1d,0x1c,0x34,0xaa,0xa1,0xaa,0xb2 +,0xa7,0x9a,0x97,0x9e,0x65,0x30,0xdc,0xad,0xbb,0x3b,0x1d,0x17,0x1e,0x2a,0x2d,0x20,0x15,0x1b,0xaf,0x91,0x8f,0x9d,0xc6,0xb7,0x98,0x93,0xa6,0x21,0x13,0x1b,0xf9,0xa9 +,0xcc,0x28,0x21,0x2e,0x6e,0xa6,0xb8,0x1f,0x15,0x1e,0x55,0xa3,0xa0,0xbc,0xbd,0xa4,0x98,0x97,0xb3,0x2d,0x3e,0xad,0xa9,0x49,0x1d,0x1b,0x2a,0x42,0x38,0x1d,0x17,0x24 +,0xd6,0xa8,0xaa,0xc7,0xcf,0x9e,0x91,0x91,0x9e,0x39,0x1f,0x37,0xa7,0x9f,0x72,0x18,0x12,0x1f,0x75,0xeb,0x1d,0x0d,0x12,0x40,0x98,0x92,0xa8,0xf3,0xa5,0x93,0x8f,0x98 +,0xf4,0x23,0x25,0x32,0x43,0x2f,0x1d,0x1e,0x33,0xde,0xc3,0xd3,0x40,0x33,0x3f,0xbd,0xbe,0x3d,0x34,0x4f,0xc3,0xbb,0x54,0xeb,0x9d,0x8f,0x8f,0x9e,0x2f,0x14,0x14,0x26 +,0xea,0x61,0x2d,0x1d,0x1c,0x20,0xcd,0xa7,0x9f,0xae,0xaa,0x9c,0xa1,0xa2,0x2e,0x2d,0xb1,0xaa,0xab,0x5f,0x29,0x22,0x1f,0x25,0x3a,0x40,0x29,0xdc,0x57,0xb7,0xb5,0xc6 +,0xda,0xd0,0xb7,0xbf,0x9b,0x9b,0x97,0xb9,0x29,0x17,0x14,0x23,0x3d,0x58,0x5c,0x6a,0x22,0x30,0x3c,0xbc,0xa3,0xa4,0xc6,0xc2,0xdc,0xc5,0xb4,0x68,0xb2,0xc7,0xaa,0xc1 +,0xc8,0xc7,0xbe,0xbe,0x2d,0x22,0x1b,0x1d,0x2c,0x6a,0xcd,0xad,0x77,0x48,0x2a,0xca,0x98,0x93,0x95,0xba,0x4f,0x2d,0x2b,0x2d,0x3f,0x46,0xbe,0xd2,0x3f,0x36,0x2d,0x2b +,0x29,0x3e,0xd8,0xb1,0xb7,0xaa,0xb7,0xbe,0xe3,0x45,0x47,0xec,0xa9,0x9c,0x98,0xa8,0x31,0x16,0x11,0x1c,0x2f,0x55,0xb8,0xa9,0xb0,0xce,0x3a,0x39,0xdd,0xa8,0xa3,0xaa +,0xef,0x2c,0x4a,0x30,0xed,0xc1,0xab,0xa9,0x36,0x2e,0x2c,0x30,0x29,0x1d,0x20,0x50,0xbb,0xa7,0xae,0xad,0xa6,0xb8,0xcb,0x47,0xaf,0xb3,0xac,0xba,0x39,0x2d,0x1f,0x25 +,0x29,0xd5,0xb4,0xca,0x44,0x3e,0x4e,0xce,0xd9,0x4d,0x7d,0xc5,0xb2,0xd6,0xb1,0xa6,0xa5,0xae,0x41,0x2d,0x33,0x3c,0x2e,0x2c,0x35,0x38,0x2c,0x1f,0x2e,0xbf,0xaa,0xa7 +,0xad,0xbc,0xcb,0xca,0xc8,0xb7,0xb2,0xaf,0xb8,0x50,0x34,0xdd,0xb4,0xc1,0x39,0x28,0x26,0x27,0x3e,0x5a,0xe5,0xf5,0x4a,0x33,0x3e,0xb5,0x9e,0x9c,0xa2,0xcd,0x27,0x1f +,0x24,0xdb,0xae,0x9f,0xa4,0xc1,0x22,0x15,0x1a,0x2c,0xc3,0xaf,0xa8,0xaa,0xa7,0xbd,0x3f,0x2d,0x48,0xaf,0xbe,0xde,0xc5,0xbc,0xd2,0x4d,0x27,0x20,0x25,0x2c,0x47,0x3b +,0x46,0xc2,0xbc,0x77,0x50,0xb7,0xa5,0xa0,0xb7,0xf7,0xc7,0xb3,0xac,0xad,0xaf,0xb1,0xc6,0x2d,0x20,0x24,0x31,0x5f,0xc8,0x3c,0x31,0x2f,0x41,0xec,0x4b,0x6b,0xdc,0xc7 +,0x4f,0x36,0x47,0xaf,0xaa,0xc3,0x34,0x2f,0x2e,0x2e,0x3b,0x4c,0xae,0xa9,0xad,0xc5,0xbb,0xac,0xaf,0xbd,0x54,0x4c,0xd4,0xbe,0xb4,0xaf,0xbf,0xfb,0x3d,0x29,0x1c,0x2a +,0x4a,0x4c,0x4a,0x39,0x3b,0x39,0x4f,0x40,0x41,0x73,0xe2,0xe4,0xcc,0xb4,0xa0,0x9e,0xab,0x5e,0x2c,0x32,0x6a,0xb8,0xbb,0xb6,0xb2,0x46,0x26,0x1f,0x35,0xba,0xb9,0xbc +,0xdb,0xc1,0xc8,0xd1,0xbc,0xb9,0xb2,0xbe,0x55,0x2f,0x3a,0xe1,0x6f,0x37,0x2e,0x26,0x26,0x35,0x42,0x61,0xbb,0xa8,0xb5,0xe7,0xd8,0xb8,0xa8,0xa9,0xb4,0x3d,0x2e,0x38 +,0x4e,0xec,0xcd,0xb3,0xbd,0xe2,0x2c,0x24,0x2c,0x30,0x32,0x3c,0x4d,0xbe,0xa6,0xb0,0xcc,0xb9,0xac,0xcb,0x3e,0xf6,0xb7,0xaf,0xbd,0x41,0x29,0x24,0x2b,0x3d,0x4f,0xef +,0xb9,0xc6,0x4b,0x4f,0xd6,0xb5,0xaa,0xa9,0xc4,0x5e,0xe3,0xc6,0xb7,0xbb,0xbe,0xce,0x44,0x37,0x3a,0x33,0x2c,0x31,0x2d,0x20,0x24,0x73,0xae,0xaf,0xb3,0xb7,0xd0,0x3a +,0x30,0x3c,0xb9,0xa4,0xa4,0xc7,0x3e,0x47,0x6e,0x58,0x59,0xb4,0xac,0xaf,0xc6,0xd3,0x57,0x31,0x2d,0x2b,0x2e,0xfe,0xa6,0xa3,0xb5,0x6f,0x34,0x2b,0x2e,0x42,0x5f,0x78 +,0x67,0x36,0x21,0x1d,0x2e,0xb5,0xa1,0x9e,0xa6,0xc8,0x4a,0x46,0xde,0xbb,0xa6,0x9f,0xbf,0x2c,0x25,0x2e,0x3d,0x35,0x3f,0x7d,0xc8,0xcc,0x3a,0x2f,0x31,0x69,0xc0,0xcf +,0xc9,0xa9,0x9f,0xa5,0xb2,0xcc,0xd2,0xbd,0xbb,0xcf,0x49,0x3d,0x3e,0x24,0x1d,0x22,0x3f,0xd0,0xcd,0xd2,0x53,0xdb,0xdb,0x65,0xef,0xc0,0xba,0xc2,0x5d,0x61,0xb5,0xac +,0xae,0xc1,0x51,0x3f,0xf8,0xcc,0x3e,0x2d,0x2c,0x2d,0x29,0x24,0x2a,0x49,0xbc,0xad,0xad,0xb3,0xac,0xac,0xb9,0xd3,0xef,0xbb,0xb8,0x4d,0x38,0x49,0x6b,0xfa,0x4d,0x3b +,0x75,0xb5,0xae,0xbc,0x67,0x48,0x3a,0x3d,0x3a,0x41,0x6f,0xd9,0xdc,0x3d,0x35,0x6a,0xbe,0xf1,0x37,0x39,0x4a,0x5d,0x48,0x46,0xc8,0xb0,0xb1,0xba,0xb7,0xac,0xa4,0xa3 +,0xaf,0xfd,0x2d,0x1f,0x23,0x29,0x42,0xce,0xdd,0xe6,0x3d,0x2a,0x30,0xd7,0xb5,0xaf,0xb6,0xb5,0xc0,0x44,0x43,0xd3,0xb9,0xb1,0xae,0xb3,0xb9,0xbb,0x5f,0x2f,0x29,0x24 +,0x22,0x24,0x23,0x2c,0x3e,0xcf,0xbc,0x69,0x6c,0xbb,0xa9,0xa3,0xa8,0xac,0xae,0xd1,0x3e,0x44,0xd5,0xb9,0xc2,0xcf,0xca,0xbf,0xae,0xb9,0x35,0x25,0x24,0x27,0x2d,0x34 +,0x4e,0xcc,0xdc,0x59,0x56,0xdd,0xae,0xa1,0x9f,0xa4,0xb9,0x39,0x1f,0x19,0x1e,0x52,0xab,0xa9,0xb5,0x5a,0x37,0x5c,0xdb,0x5f,0x6c,0xcc,0xbe,0xcf,0x61,0x49,0x38,0x2e +,0x3d,0xd0,0xb7,0xac,0xa8,0xb9,0x46,0x3b,0x3b,0x45,0xf5,0xd6,0xc8,0xcb,0xd6,0xc8,0x52,0xec,0xae,0xb4,0x4e,0x2d,0x28,0x28,0x28,0x2e,0x3c,0x3a,0x39,0x6b,0xb3,0xa3 +,0x9c,0x9d,0xad,0x72,0x38,0x2b,0x2f,0x65,0xbf,0xbc,0xdd,0x4a,0x52,0xbc,0xa7,0xa7,0xbf,0x47,0x3d,0x32,0x27,0x23,0x26,0x2b,0x32,0x45,0xc4,0xae,0xa6,0xa4,0xa9,0xb9 +,0xcb,0xcf,0x4d,0x3b,0x41,0x47,0x3e,0x32,0x34,0xd7,0xaa,0x9f,0xac,0x45,0x24,0x1f,0x2a,0x52,0xc1,0xde,0x2f,0x23,0x2e,0xcb,0xa4,0x9a,0x9b,0xa2,0xb8,0x40,0x2d,0x2c +,0x3c,0x6a,0x59,0x36,0x29,0x2c,0x40,0xb4,0x9e,0x9e,0xb4,0x41,0x27,0x22,0x25,0x34,0x52,0x3b,0x36,0xef,0xaf,0xa1,0x9a,0x9b,0xa9,0xc5,0xde,0x3f,0x2b,0x29,0x2b,0x2b +,0x29,0x2d,0xea,0xa7,0x9e,0xa1,0xbc,0x3e,0x38,0x3d,0x4c,0x5c,0x3f,0x27,0x1d,0x1e,0x35,0xa9,0x97,0x92,0x9b,0xbd,0x40,0x37,0x2e,0x2d,0x3b,0x41,0x2e,0x20,0x21,0x37 +,0xb4,0x9f,0x9f,0xa9,0xbf,0xe7,0x4b,0x38,0x35,0x30,0x2a,0x28,0x2f,0x6e,0xa8,0x9d,0x9e,0xa9,0xbc,0xc3,0xd9,0x38,0x2b,0x28,0x28,0x24,0x25,0x34,0xba,0x9f,0x9a,0x9d +,0xae,0xf1,0x3b,0x35,0x3e,0x35,0x26,0x20,0x27,0x3c,0xaf,0x98,0x93,0x9d,0xcf,0x2e,0x35,0x41,0x36,0x2e,0x26,0x1e,0x1b,0x1c,0x2f,0xab,0x96,0x91,0x96,0xa7,0xd0,0x5e +,0x40,0x40,0x51,0x4f,0x32,0x1e,0x1a,0x28,0xaf,0x9d,0xa0,0xb8,0x5b,0x4b,0x3a,0x32,0x38,0x3e,0x3e,0x35,0x36,0x52,0xaf,0x9c,0x9a,0xa2,0xc5,0x47,0x39,0x2e,0x27,0x23 +,0x20,0x1e,0x22,0x31,0xbe,0x9d,0x97,0x9d,0xb0,0xc6,0xbc,0xbf,0xcc,0x4a,0x28,0x1f,0x20,0x2b,0xef,0xa2,0x94,0x95,0xab,0x2e,0x21,0x27,0x2e,0x48,0x67,0x3b,0x23,0x1b +,0x20,0xe3,0x9a,0x8f,0x93,0xa5,0xd6,0x41,0x2d,0x26,0x29,0x2d,0x36,0x32,0x25,0x22,0x3b,0xad,0x9f,0xa0,0xab,0xac,0xb3,0xda,0x67,0x3b,0x29,0x20,0x22,0x37,0xb1,0x99 +,0x98,0xad,0x35,0x2d,0x4c,0x64,0x46,0x2c,0x20,0x1f,0x21,0x29,0x41,0xa8,0x95,0x94,0x9d,0xad,0xc3,0x5b,0x40,0x36,0x25,0x1d,0x1a,0x1e,0x31,0xae,0x96,0x94,0x9f,0xd9 +,0x3b,0x5b,0xc7,0xbe,0x4c,0x28,0x22,0x1d,0x1d,0x2c,0xae,0x96,0x93,0x9b,0xaf,0x4a,0x30,0x34,0x45,0x34,0x2a,0x24,0x1d,0x1e,0x35,0xa5,0x9a,0x9f,0xad,0xb4,0xb5,0xc4 +,0xf3,0x39,0x2a,0x27,0x24,0x25,0x31,0xc0,0xa0,0x9e,0xa7,0xb6,0xc8,0xd4,0xde,0x48,0x21,0x1b,0x1d,0x23,0x46,0xa8,0x96,0x96,0xa6,0xd7,0x44,0x53,0xc1,0xbf,0x39,0x23 +,0x1d,0x19,0x19,0x27,0xa9,0x91,0x8f,0x98,0xaf,0x3f,0x39,0xcc,0xc9,0x32,0x25,0x1c,0x17,0x19,0x37,0xa2,0x98,0x99,0xa2,0xac,0xb9,0xca,0x71,0x35,0x2e,0x31,0x26,0x1b +,0x1f,0x40,0xb2,0xa2,0xa7,0xbb,0xb9,0xad,0xa8,0xbf,0x30,0x29,0x23,0x1f,0x2c,0xb5,0x9d,0x9d,0xa7,0xbe,0x57,0x45,0x6d,0x6c,0x29,0x1f,0x1f,0x1b,0x1a,0x2a,0xad,0x98 +,0x96,0x9d,0xaf,0xcc,0xba,0xa9,0xc1,0x2d,0x1f,0x16,0x14,0x1f,0xb5,0x96,0x92,0x99,0xb1,0x4e,0x68,0xc7,0xfc,0x2f,0x2a,0x22,0x18,0x13,0x1c,0xcf,0x9a,0x91,0x95,0xa0 +,0xaa,0xa5,0xa8,0xe1,0x35,0x2b,0x1d,0x16,0x1a,0x2f,0xc7,0xb7,0xb9,0xc8,0xc7,0xc2,0xab,0xb5,0x2f,0x3b,0xc1,0x44,0x2d,0xf0,0xb9,0xa7,0xd4,0x26,0x28,0x4c,0x3b,0x51 +,0x9f,0xa8,0xa4,0x9e,0xbf,0x16,0x1c,0xb6,0x9f,0xaf,0x22,0x25,0xca,0xbf,0x31,0x37,0xc2,0x47,0x76,0xae,0x42,0x27,0x72,0x9a,0xa1,0xba,0xb1,0xcf,0x27,0x14,0x37,0xae +,0x47,0x42,0x66,0x7d,0xb5,0x9e,0xa3,0xcc,0x1c,0x1e,0xbc,0x4f,0x20,0xd4,0x9d,0xe3,0x44,0xb8,0x79,0x30,0x3e,0x3e,0xce,0xac,0x39,0x25,0xe8,0x9b,0x9e,0xa0,0x43,0x12 +,0x45,0xa9,0x2a,0x26,0x31,0x4f,0xa1,0x9d,0xc5,0x23,0x2a,0x3d,0xad,0xa1,0x67,0x30,0x55,0xcf,0xbb,0xa5,0xad,0xf0,0x1d,0x1b,0x36,0xac,0xb7,0x3f,0x70,0xeb,0xb3,0xa4 +,0xb1,0x25,0x25,0x20,0x5a,0xdb,0x3f,0xa6,0xa2,0xa8,0xbd,0xb9,0x1d,0x1b,0xa8,0xb0,0x25,0x2f,0x67,0xc9,0xa8,0xac,0xc3,0xc7,0x32,0x1b,0x46,0xbc,0x37,0x57,0xad,0xad +,0x9a,0xa7,0x1e,0x1a,0x27,0xb6,0xbd,0xdd,0x2e,0x2d,0xae,0xa8,0x9f,0x96,0xb5,0x15,0x18,0x27,0xa2,0x9c,0xb0,0x44,0x1c,0x35,0xc4,0x9e,0xc4,0x1f,0x3e,0x2e,0x26,0x3a +,0xad,0x98,0x95,0xaa,0x3e,0x1e,0x1a,0x21,0x60,0xb5,0x32,0xc2,0x9f,0xdd,0xac,0x9d,0x4f,0x3d,0x21,0x2d,0x79,0x2a,0x22,0x6b,0xa2,0xbe,0xa9,0x9b,0x34,0x0d,0x1a,0xda +,0x98,0xa2,0x36,0x2d,0xec,0x94,0x9b,0xa1,0x26,0x10,0x21,0x26,0x46,0x9f,0x9d,0xcb,0xe2,0xc6,0xba,0xaf,0x2d,0x25,0x71,0xd6,0x31,0x2c,0xbd,0xae,0xa3,0xd7,0x2a,0x49 +,0x30,0xd5,0xb0,0xbe,0xbe,0xc6,0xca,0x52,0x2e,0x38,0x3d,0x31,0x41,0x2b,0xc9,0x99,0x9e,0xc7,0x2e,0x1b,0x1b,0xb5,0x97,0x9c,0x1f,0x22,0xb8,0xa5,0x9b,0xc7,0x32,0x13 +,0x28,0xaa,0xed,0x34,0x25,0xaa,0x94,0xa8,0xdb,0x34,0x1f,0x28,0x3e,0xcd,0x2b,0x38,0x9a,0x9e,0xcf,0xd1,0x34,0x35,0x39,0x4b,0xb3,0x41,0x23,0x43,0x96,0xa3,0x5b,0xc4 +,0xfc,0x1b,0x18,0xcc,0xa6,0xad,0x22,0x2a,0xee,0x9d,0x96,0x9f,0x5f,0x0e,0x25,0xcf,0x3c,0xb0,0xa2,0xa6,0xd2,0xea,0xbf,0x5d,0x1e,0x13,0x32,0xbc,0x35,0x3a,0x9d,0x9c +,0xaf,0xbf,0xb5,0xe3,0x1c,0x30,0x3c,0x21,0x1e,0xbe,0x8e,0x99,0xbc,0xab,0x5f,0x13,0x1a,0x3c,0xad,0xcf,0x28,0xc7,0x68,0xb0,0x90,0x9c,0x1e,0x09,0x2d,0xa1,0xca,0xc9 +,0xde,0xb0,0xc4,0xb3,0xa4,0xac,0x20,0x13,0x37,0xaf,0x38,0x34,0x9e,0x9c,0xab,0xa9,0xad,0x38,0x17,0x1b,0x2f,0x26,0x47,0x9d,0x94,0xb9,0x29,0xb2,0xac,0x1a,0x1d,0xa8 +,0xb2,0x2f,0x1e,0xac,0xa6,0xad,0x9f,0xab,0x26,0x0b,0x3e,0xa5,0xb9,0x30,0x3b,0x9a,0xa8,0xe9,0xae,0xb7,0x14,0x0f,0xe4,0xa1,0x39,0x47,0x9e,0xd8,0xdf,0xa9,0xad,0x37 +,0x19,0x3b,0xb5,0x38,0x3c,0x92,0x93,0x2b,0x1c,0xab,0x9e,0x1f,0x1d,0x39,0xcd,0x26,0x2a,0x9c,0x9e,0xb7,0xcf,0xbc,0x38,0x11,0x38,0x9f,0x52,0x3c,0xb2,0x99,0xc5,0x22 +,0x6b,0xe5,0x1d,0x2d,0x9e,0xaf,0x1f,0x2f,0x99,0xa2,0x45,0xbb,0xa2,0x27,0x0e,0x24,0xaa,0xcc,0x34,0x9a,0x9d,0x24,0x1e,0x9b,0x9d,0x17,0x18,0x47,0xb1,0xcd,0xb9,0x9d +,0xe1,0x27,0x63,0x9e,0x3e,0x0f,0xce,0xa5,0x26,0x2f,0x9a,0x9c,0x45,0x33,0xbd,0xd2,0x18,0x1f,0x9d,0xa0,0x1b,0x49,0x97,0x9c,0xb9,0xd2,0xbf,0x1c,0x12,0x38,0x9a,0xd6 +,0x3e,0xad,0xab,0x46,0x3b,0x9a,0xd2,0x11,0x14,0xbf,0x9d,0x5d,0x48,0xa2,0x3c,0x1d,0xad,0x97,0x23,0x0b,0xc1,0x99,0xe1,0xf3,0x98,0x9c,0x2c,0x22,0xcb,0x5d,0x15,0x28 +,0x9a,0xad,0x18,0x29,0x97,0xa3,0x2d,0x47,0x44,0x24,0x26,0xa6,0xa3,0x2c,0xce,0x9c,0xa5,0x46,0x3a,0xad,0x4e,0x10,0x25,0x9e,0x9d,0xfb,0xc8,0xab,0x35,0x28,0xc9,0x9a +,0x25,0x10,0xe3,0xa3,0xce,0x40,0xa8,0xaa,0x3e,0x26,0xc3,0xbd,0x16,0x1e,0x9d,0x9d,0x2b,0xa9,0x94,0x2f,0x17,0x41,0xa4,0x48,0x2f,0xb9,0xd2,0x25,0x4f,0x99,0x9d,0x1c +,0x14,0xaa,0xcf,0x18,0x31,0x9e,0xb7,0x37,0x9f,0xa1,0x25,0x24,0x48,0xb5,0x2a,0x1f,0xa9,0xa3,0xbe,0xeb,0xab,0x6a,0x3f,0xc4,0xa5,0x2c,0x0e,0x41,0x99,0x9a,0x4d,0xaf +,0xc6,0x1f,0x20,0x5d,0xa6,0x38,0x27,0x60,0xa3,0xb9,0xcc,0x9b,0xa8,0x11,0x16,0x9e,0xab,0x27,0x43,0xaf,0xdd,0x5d,0xa6,0xc1,0x2e,0x24,0x2d,0xb9,0x1f,0x25,0x98,0x95 +,0x6d,0x2e,0xbb,0x21,0x28,0x99,0x9d,0x19,0x13,0xd3,0x9f,0xa2,0x3f,0xb5,0x57,0x23,0x2d,0x4e,0xaf,0x24,0x42,0xa2,0xa4,0xbf,0x66,0xbf,0x4b,0x23,0x2c,0xb6,0x71,0xd8 +,0x4a,0xf7,0xb6,0xab,0x9e,0xd3,0x29,0x1e,0x30,0xa4,0x3e,0x35,0xa2,0xa6,0xc6,0x6d,0xc2,0x1e,0x25,0xc7,0xbb,0x38,0x2d,0xb6,0xa0,0xa4,0x1d,0x44,0xa9,0x71,0x31,0x4d +,0x5d,0x1e,0xa6,0x9b,0xc9,0x4a,0xcf,0xc9,0x25,0x25,0x42,0xae,0xe0,0x33,0x4a,0xbb,0xd2,0xb6,0x98,0x23,0x13,0x25,0xcb,0x9e,0xbe,0x3e,0x24,0x55,0xa3,0xa4,0xa7,0x2e +,0x1e,0x25,0x61,0x9f,0x9b,0xac,0xb7,0xc0,0x26,0xe9,0x54,0x4d,0x37,0x29,0x52,0x26,0xae,0xac,0xae,0xbc,0x47,0xfe,0x2f,0x1f,0x4c,0x99,0xd5,0x4b,0xe2,0xb0,0x2f,0x3f +,0x9d,0x2d,0x1d,0x23,0xb4,0x9d,0xb0,0x2b,0x1f,0xb8,0x9b,0x9e,0xc6,0x18,0x13,0x4e,0xaf,0xb4,0xae,0xee,0x40,0x47,0x3c,0x4c,0x38,0xbb,0x6b,0x3d,0x51,0x2d,0xbc,0xa2 +,0xa6,0xcb,0x45,0x33,0x3b,0x39,0x59,0xc8,0xdb,0xca,0xed,0xa7,0x4d,0x2e,0x52,0x2d,0xb8,0xae,0xaf,0xae,0x34,0x2b,0x4e,0xa4,0xa9,0x76,0x3c,0x1b,0x1a,0xa6,0x99,0xb7 +,0xde,0x2a,0x6a,0xb5,0xdd,0xb1,0x38,0x23,0x25,0xc3,0xb3,0x2d,0xb9,0xaa,0xba,0xde,0x2c,0x22,0xdb,0xab,0x4d,0x2d,0x33,0x9f,0x9b,0xae,0x21,0x1e,0x52,0x39,0xbd,0x4e +,0x36,0xbe,0xc7,0x41,0x58,0xad,0xab,0xda,0x2e,0x1a,0x1d,0x9f,0x8e,0xaa,0x2b,0x2f,0xc6,0xb0,0x5a,0x70,0x3e,0x2b,0x39,0xaf,0xa4,0x34,0x3e,0xd9,0x56,0xbd,0xad,0xca +,0x2e,0x2b,0x3d,0x5d,0xd3,0xa1,0xac,0xaf,0x25,0x1d,0xcc,0x58,0xcc,0x57,0x35,0x34,0xbc,0xb8,0xb1,0xc7,0xfe,0xb1,0xc0,0x36,0x1f,0xb5,0x9e,0xb3,0xcf,0x23,0x1e,0xf3 +,0xb3,0xd6,0x1a,0x18,0x65,0x98,0x98,0x33,0x2e,0xdf,0xaf,0xad,0xce,0x27,0x34,0x39,0x3b,0xb0,0xd5,0xaa,0xb0,0xdc,0x27,0x35,0x9b,0x9d,0x3d,0x1b,0x27,0x4f,0xa9,0xbd +,0xcc,0xe8,0x46,0xbc,0x32,0x25,0x3c,0xa4,0xb8,0x29,0xd5,0xa8,0xae,0xee,0x44,0x4b,0x20,0x27,0xaa,0xa2,0xb1,0x2e,0x28,0xe3,0xa9,0xa5,0xc5,0x19,0x15,0x2c,0xa5,0x99 +,0xc7,0x35,0x3b,0xa7,0xbd,0x4a,0xc3,0xd2,0xe1,0x2a,0x1f,0x20,0xb8,0xa9,0xa8,0x2f,0x22,0xbc,0x9e,0x9f,0x35,0x4e,0x5b,0x32,0xb0,0xb9,0x31,0xe5,0xc8,0xce,0x28,0x25 +,0xcf,0xa7,0xd7,0x22,0xbd,0x9a,0x9f,0x76,0x2e,0x19,0x2f,0xa6,0xa6,0xda,0x21,0xe1,0xa6,0xbd,0x25,0x75,0xa5,0x6f,0x25,0x25,0x38,0xbd,0xa7,0x3c,0x3a,0x2e,0x58,0x97 +,0xa3,0xbd,0x33,0x27,0x37,0xc7,0xa8,0xbe,0x26,0x1a,0x3d,0xab,0xa3,0xc1,0x27,0x29,0x57,0x77,0xb8,0xa8,0xb8,0xc2,0xb9,0x32,0x1b,0x2d,0xb1,0xa6,0x2e,0x28,0xb5,0x9b +,0xa8,0x47,0xbf,0x7e,0x33,0x36,0xb4,0x58,0x35,0x4e,0xb7,0x64,0x34,0xb0,0xb7,0x3c,0x1a,0xce,0x9d,0x9f,0xb4,0x1a,0x15,0x39,0xa1,0x9c,0xbd,0x28,0x38,0xb9,0xd0,0x20 +,0x60,0x9d,0xa6,0x33,0x20,0x22,0xb0,0x9a,0xaf,0xbe,0x2a,0x20,0x53,0x9a,0xbb,0x2c,0x4d,0x46,0x29,0x25,0xc8,0x5a,0x1a,0x25,0x9a,0x99,0xaf,0x38,0x2f,0xb6,0xbb,0xa6 +,0x97,0x36,0x15,0x2e,0xa9,0xd6,0x3a,0x4e,0x3b,0x2d,0x3a,0x94,0x97,0x3e,0x1d,0x36,0xbc,0xd4,0x3a,0x3d,0xae,0xb8,0xac,0xb7,0x23,0x19,0x5d,0xa2,0x65,0x28,0x3e,0xae +,0x9d,0xa8,0x5c,0x28,0x20,0x26,0x9f,0x96,0x2a,0x20,0x47,0xaa,0x7e,0xba,0xa6,0x56,0x17,0x1c,0xbc,0xe8,0xe4,0x3d,0xbf,0xab,0xc9,0xb4,0xa0,0x1e,0x19,0xab,0x9d,0x40 +,0x16,0x1f,0xb4,0xaa,0xa9,0xa1,0x4a,0x49,0xb1,0xda,0x2e,0x31,0x24,0xaf,0x9f,0xbe,0xb8,0xcb,0x24,0x36,0xae,0xa8,0x25,0x21,0xe0,0x8f,0x9a,0xa2,0x45,0x18,0x3b,0x21 +,0x8c,0x37,0xa2,0x0c,0x00,0x08,0x03,0x9c,0x1e,0x31,0x21,0x3c,0x88,0x9e,0x99,0x95,0x99,0x98,0x93,0x87,0xb2,0xae,0x8f,0x37,0x94,0x26,0x00,0x8b,0x85,0x8e,0x96,0xaf +,0x0f,0x22,0x1d,0x06,0x05,0x00,0x05,0x09,0x0b,0x02,0x03,0x00,0x0a,0x00,0x14,0x22,0x06,0x0d,0xc3,0x8d,0x8c,0x8d,0xa0,0x3a,0x9e,0x89,0x89,0x8b,0x98,0x8e,0x82,0x81 +,0x85,0x84,0x86,0x80,0x83,0x80,0x96,0x83,0x93,0x19,0x8d,0x80,0x9c,0x01,0x98,0x2b,0x14,0x23,0x04,0x00,0x02,0x00,0x10,0xa8,0x07,0x08,0x00,0x0a,0x1a,0x00,0x02,0x00 +,0x11,0x0e,0xad,0xea,0x0e,0x04,0xa9,0x82,0x84,0x80,0x85,0x98,0x9d,0x80,0x84,0x80,0x83,0x80,0x95,0x82,0x87,0x82,0x87,0x95,0x9b,0x22,0xae,0xc9,0x87,0x9f,0x20,0x08 +,0x15,0x0d,0x0f,0x43,0x06,0x01,0x00,0x04,0x0d,0x09,0x01,0x07,0x08,0x03,0x02,0x10,0x11,0x09,0xcd,0x1d,0x32,0xbf,0x8e,0x8d,0xb4,0xef,0x9e,0x88,0x97,0x90,0xaf,0xad +,0x92,0x86,0x82,0x8f,0x8c,0x80,0x9b,0x90,0x87,0x80,0x86,0x82,0x96,0xc8,0x85,0x26,0xe7,0x13,0x18,0x08,0x00,0xab,0x13,0x00,0x02,0x02,0x03,0x0e,0x18,0x18,0x1a,0x0b +,0x05,0x00,0x12,0x0c,0xb0,0x3b,0x3e,0x1c,0x0d,0x8a,0x13,0xca,0x89,0x86,0x80,0x8f,0x8a,0x8a,0x8a,0x85,0x86,0x82,0x82,0x8a,0x8e,0x95,0x89,0x99,0xb8,0xb6,0x1e,0xc4 +,0x0e,0x2a,0xc3,0xe8,0x2b,0x03,0x0d,0x25,0x8d,0xae,0x00,0x03,0x0b,0x18,0x12,0x02,0x02,0x04,0xa4,0x2f,0xbf,0x11,0x01,0x0a,0x0c,0xa4,0x22,0x80,0x8e,0x26,0x94,0x87 +,0x39,0x38,0x81,0x8f,0x9e,0x0a,0x9c,0x80,0x8b,0x8b,0xd3,0xfc,0x89,0x80,0x87,0x85,0x8e,0x96,0x59,0x08,0x9f,0xa5,0xac,0x1b,0x0a,0x05,0x00,0x07,0x2b,0x11,0x03,0x0a +,0x00,0x16,0x07,0xba,0xa7,0x03,0x07,0x0d,0x08,0x2c,0x8e,0xb4,0x0e,0x0e,0x36,0x8e,0x86,0x8b,0xa4,0x92,0x8d,0xaa,0x96,0x87,0x80,0x8d,0x9a,0x8f,0x84,0x9d,0x8b,0x89 +,0x81,0x21,0x07,0xa4,0x84,0x84,0x0a,0x0b,0x9e,0x8c,0x0e,0x9c,0xbc,0x08,0x15,0x2b,0x15,0x04,0x9f,0x22,0x01,0x0e,0x00,0x0d,0x1a,0xa5,0x23,0x00,0x14,0x0c,0x98,0x1a +,0x2e,0x14,0x18,0x91,0x0a,0x96,0x86,0x88,0x8c,0xad,0xaf,0x96,0x84,0x88,0x80,0x88,0x0d,0x30,0x86,0x87,0x8f,0x30,0x8d,0x86,0x8f,0xb4,0x04,0x13,0x89,0x80,0x13,0x0b +,0x02,0x46,0x55,0x0f,0x18,0x00,0x16,0x00,0x13,0x21,0x1a,0x05,0x10,0x1c,0x00,0x0d,0xc7,0xa7,0x0e,0x02,0x12,0x86,0x8e,0xad,0x08,0x0a,0x3d,0x92,0x80,0x8b,0xad,0x07 +,0xa2,0x87,0x80,0x87,0x96,0x8f,0x36,0x85,0x83,0x89,0xa0,0x99,0x92,0x0e,0x89,0x8f,0x27,0xb4,0x12,0x8d,0x8b,0x9b,0x14,0x12,0xb6,0x13,0x0f,0x02,0xad,0x12,0x00,0x11 +,0x17,0x08,0x0d,0x0c,0x0e,0x11,0x08,0x08,0x04,0xe5,0x58,0x54,0x11,0x3b,0x21,0x88,0x87,0xa3,0x80,0x2a,0x95,0x8a,0x8d,0x88,0x8c,0x86,0x8c,0x98,0x8f,0x98,0x85,0x8f +,0x2e,0x35,0x87,0x8b,0x2e,0x0f,0x14,0x9d,0x9a,0x24,0x16,0x1e,0x05,0xa2,0x97,0xac,0x08,0xb2,0xb7,0x12,0x1d,0x08,0x14,0x06,0xaf,0x22,0x0c,0x0c,0x0d,0x1d,0x14,0x1b +,0x19,0x0d,0xa8,0x9e,0x1f,0x09,0x15,0x87,0xaa,0x9e,0xa5,0x9b,0x9b,0x9b,0x8e,0x8b,0x8b,0x93,0x91,0x74,0x8a,0x8a,0x89,0x9a,0x81,0x8b,0xa2,0x8d,0x99,0x34,0xbd,0x94 +,0xdd,0xa8,0x16,0x1b,0x0a,0x0b,0x1b,0x14,0x03,0x07,0x17,0x28,0x0c,0x0d,0x0c,0x0f,0x0d,0x04,0x19,0x2b,0x2d,0x10,0xac,0x09,0x26,0x99,0x18,0x8e,0x8a,0x9b,0xad,0x99 +,0xa7,0x95,0x8c,0x86,0x88,0x80,0x8c,0x3c,0x95,0xca,0x8d,0x88,0x8d,0x2a,0x4f,0xae,0x2e,0x9c,0x51,0x27,0x10,0x1f,0x3e,0x0d,0x24,0x51,0xbb,0x39,0x2e,0x1c,0x07,0x15 +,0xca,0x19,0x1f,0x5b,0x1a,0x28,0x01,0x1d,0x13,0xa3,0x1c,0x0b,0x1b,0x0e,0x0f,0x22,0xa8,0xc7,0x99,0x0b,0x1d,0x9d,0x93,0x9d,0x8a,0x3c,0xa0,0x9d,0x9a,0x80,0x87,0x8a +,0xa1,0x9a,0xa2,0x94,0x86,0x98,0x8b,0x89,0x96,0x96,0xac,0xac,0x51,0x39,0x19,0x50,0xa2,0x09,0x0d,0xe6,0x1a,0x1e,0x1f,0x1f,0x03,0x07,0x05,0x0b,0xb3,0xd2,0x1a,0x0d +,0x15,0x0a,0x32,0x5f,0x11,0xae,0xa8,0xba,0x8d,0x21,0x2a,0xad,0xa5,0x92,0x96,0x81,0x9a,0x24,0x4c,0x96,0x83,0x85,0x83,0x88,0xd7,0x9a,0x88,0x9d,0x4f,0x9c,0x51,0x2c +,0xdb,0xc7,0x8e,0x12,0x3f,0x43,0x2a,0x15,0x07,0x37,0x38,0xde,0x49,0x1f,0x0b,0x15,0x0b,0x38,0x9c,0x04,0x0b,0x1c,0x1a,0x17,0x27,0x41,0x17,0x31,0x96,0xa5,0x13,0x1a +,0x4c,0x88,0x9f,0x92,0x8f,0x91,0x41,0x24,0x8e,0x8e,0x89,0xbe,0xaf,0x26,0x94,0x8a,0x8e,0xbb,0xf4,0xb5,0x97,0xaf,0x0d,0xb9,0x18,0x9b,0x8a,0x9f,0x30,0x0c,0x0a,0xa7 +,0x9d,0x05,0x11,0x1c,0x1a,0x17,0x30,0xeb,0x24,0x27,0x2e,0x2f,0x2d,0x09,0x17,0x8c,0x98,0x2b,0x16,0x20,0x0f,0x1d,0xa1,0x2f,0x2b,0x2f,0x10,0x96,0xa2,0x90,0x8b,0xab +,0x8c,0x9d,0x9c,0x89,0x4a,0x90,0x8d,0x87,0x80,0xa0,0xba,0xc7,0x9d,0x9b,0x8d,0x12,0x24,0x1d,0x2a,0x9f,0x23,0x16,0x2d,0x0e,0x07,0x19,0x09,0x0a,0x0a,0xf1,0x57,0x25 +,0x43,0x0f,0x0a,0x14,0x0d,0xaa,0xdd,0x29,0xa7,0x93,0x8a,0x9f,0x8e,0xca,0xba,0x94,0x88,0x98,0x0a,0x5d,0x8c,0x8b,0x89,0x90,0xcc,0x3f,0xa6,0x2b,0xeb,0x2a,0xbe,0x37 +,0x31,0xa8,0x1a,0xcd,0x45,0x29,0x17,0x28,0x1e,0x14,0x0d,0x9d,0x8c,0xb5,0xa1,0x5f,0x1d,0x15,0x2c,0xaa,0xb1,0x2d,0xa7,0x96,0xa7,0x4c,0x2f,0xb6,0x3b,0x0e,0x26,0x1e +,0x0d,0x0f,0x94,0x89,0x41,0x1a,0x04,0x0d,0x10,0x19,0x99,0x59,0x3c,0x29,0x9e,0x89,0x99,0xb3,0x98,0x9c,0xa9,0x90,0x9c,0x1a,0xe9,0x87,0x82,0x87,0x9e,0x92,0x14,0xc9 +,0x2f,0x30,0xa9,0x1a,0x1a,0x2f,0x9d,0x2c,0x0f,0x0d,0x14,0x11,0x0b,0x1b,0x19,0x0c,0x42,0x9d,0x8a,0x1c,0x0f,0x19,0x11,0x1f,0x9c,0xa8,0xe5,0xa1,0x88,0x8d,0x97,0x9c +,0x1b,0x21,0x1a,0xab,0x1d,0x59,0x23,0x99,0x80,0x8f,0x9c,0xaf,0x2e,0x0f,0xa9,0x98,0xdf,0x1e,0x40,0x90,0xd2,0x9a,0x27,0x22,0xbf,0x08,0x27,0x25,0x19,0x47,0x9e,0x9c +,0x8d,0xb1,0x17,0x08,0x05,0x0f,0xac,0xa1,0x5e,0x58,0x9c,0x85,0xbb,0x0d,0x10,0x3b,0x1f,0x37,0x32,0x18,0x3e,0x8a,0x84,0x83,0xd5,0x11,0x16,0x02,0x17,0xf2,0x9b,0x36 +,0x20,0x90,0x8e,0x96,0xa5,0x27,0x33,0x24,0xac,0xc9,0x1b,0x3b,0x94,0x87,0x88,0x99,0x19,0x11,0x0a,0x12,0xbb,0x8f,0x45,0x3d,0x8d,0x95,0xda,0x2c,0x2c,0x10,0x08,0x0d +,0x1d,0x37,0x2f,0x9a,0x85,0x86,0x49,0x09,0x08,0x05,0x10,0x2b,0xbc,0x28,0x4b,0x92,0x84,0x8e,0xaf,0xd4,0x1d,0x0f,0x1b,0xab,0xaf,0xb9,0x93,0x83,0x85,0x8d,0xb0,0x1b +,0x11,0x36,0x92,0x9d,0x18,0x22,0x8d,0x8f,0xaf,0x28,0x10,0x12,0x1f,0x18,0x15,0x34,0xce,0x95,0x83,0x8b,0xd5,0x1a,0x0e,0x08,0x0c,0x1d,0x2d,0x30,0x55,0x96,0x87,0x91 +,0x27,0x10,0x19,0x16,0x1f,0x43,0x1c,0x1b,0x9c,0x82,0x88,0xae,0x19,0x0d,0x0a,0x18,0x37,0x3f,0x26,0xe9,0x8d,0x8d,0x98,0xb5,0x31,0x18,0x1b,0xd5,0xc5,0x24,0x2f,0x90 +,0x84,0x98,0x38,0x1c,0x0d,0x0c,0x27,0x2b,0x1c,0xbc,0xa3,0x8a,0x8a,0x9f,0x2d,0x20,0x23,0x0d,0x10,0x1a,0x1c,0x29,0x9b,0x86,0x84,0x96,0x0f,0x05,0x12,0x1d,0x1d,0x32 +,0x24,0xaf,0x84,0x84,0x98,0x38,0x45,0x3d,0x28,0x1c,0x15,0x15,0x33,0x8d,0x87,0x9b,0xd1,0x3d,0x23,0x13,0x0f,0x28,0xd3,0x34,0xbb,0x88,0x8c,0xb7,0x37,0x2e,0x25,0x1b +,0x20,0x0f,0x0e,0x6b,0x8d,0x85,0x90,0xe0,0x18,0x1a,0x2c,0x1e,0x14,0x23,0x2a,0x9f,0x86,0x8b,0x9a,0x4b,0x1e,0x1c,0x38,0x15,0x0d,0x1f,0xc9,0x92,0x84,0x8c,0x49,0x14 +,0x2d,0x1e,0x1c,0x16,0x2a,0x3d,0x94,0x8a,0x88,0x80,0xca,0x40,0x1a,0x10,0x0b,0x56,0x0b,0x4a,0x1d,0x00,0x0c,0x00,0xc3,0x0f,0x15,0x0f,0x06,0x9d,0x90,0x87,0x85,0x85 +,0xa2,0x9a,0x89,0x98,0xcf,0xaf,0x0c,0x21,0x9b,0x21,0x80,0x85,0x8a,0x93,0x99,0x1c,0x0b,0x0a,0x06,0x0e,0x08,0x12,0x0f,0x21,0x08,0x0a,0x04,0x06,0x00,0x05,0x06,0x02 +,0xb5,0x98,0x8f,0xa4,0x96,0x99,0x2e,0x2d,0xa0,0x99,0x97,0x83,0x82,0x82,0x84,0x8b,0x88,0x85,0x87,0x90,0x8d,0x98,0x89,0x83,0xa7,0xa4,0x84,0x8d,0x05,0x28,0x0c,0x00 +,0x11,0x08,0x0b,0x0c,0x01,0x13,0x9d,0x0e,0x05,0x00,0x02,0x08,0x00,0x06,0x09,0x2b,0xb8,0xac,0x67,0x19,0x08,0x19,0x9f,0x89,0x80,0x82,0x81,0xa2,0x8c,0x86,0x80,0x84 +,0x85,0xb8,0x9d,0x8c,0x89,0x80,0x8b,0x8c,0xdb,0x8e,0xa4,0xb7,0x17,0x09,0x0c,0x18,0x21,0x30,0x11,0x04,0x0a,0x06,0x04,0x05,0x08,0x00,0x05,0x0c,0x15,0x14,0x1d,0x3e +,0x13,0xc7,0x38,0x2a,0x4e,0x4d,0x97,0x85,0x82,0x8c,0x8b,0xa2,0x8d,0x8c,0x32,0x1f,0x4f,0x8d,0x93,0x8c,0x80,0x8e,0x8a,0x88,0x80,0x8e,0x8c,0xc1,0x36,0x81,0x66,0xac +,0x1f,0xc4,0x1e,0x00,0x17,0x06,0x02,0x00,0x03,0x00,0x0d,0xab,0xdf,0xad,0x12,0x0b,0x00,0x00,0x07,0x72,0x1e,0xe8,0x9e,0x1f,0x85,0xa8,0x9c,0x89,0x8a,0x81,0xac,0xae +,0x8a,0x84,0x83,0x82,0x82,0x81,0x8b,0x2f,0x52,0xad,0x9f,0xa4,0xb1,0xbf,0x4e,0x65,0x67,0xa4,0xc0,0x0a,0x04,0x09,0x0e,0x0e,0x27,0x04,0x09,0x9e,0x1f,0x1d,0x01,0x03 +,0x00,0x36,0x23,0xe7,0x36,0x06,0x09,0x0e,0x85,0xce,0x8a,0xb5,0x0d,0x9c,0x84,0x90,0xa8,0x82,0x86,0x8b,0x20,0x2f,0x80,0x8f,0x8b,0x92,0x36,0x89,0x81,0x80,0x87,0x83 +,0xad,0x10,0x0b,0x4b,0xcf,0x24,0xb1,0x9d,0x1a,0x00,0x05,0x1e,0x10,0x00,0x0a,0x00,0x0c,0x08,0x68,0x98,0x0c,0x05,0x1b,0x16,0x05,0x0e,0x23,0x15,0x0c,0xcf,0x8a,0x84 +,0x8b,0x86,0x84,0xb7,0x0e,0x20,0x89,0x80,0x86,0x91,0x98,0x80,0x99,0x93,0x8a,0x8e,0x36,0x06,0x2f,0x98,0x80,0xd0,0xac,0x8e,0x8a,0x14,0x0e,0xad,0x09,0x07,0x14,0xc2 +,0x02,0x35,0xed,0x00,0x11,0x00,0x05,0x04,0x1a,0xd6,0x00,0x18,0x22,0x9a,0xdd,0x98,0xe1,0x0e,0xc8,0x00,0x8d,0x85,0x86,0x9f,0xa1,0x89,0x8e,0x80,0x86,0x80,0x8d,0x1a +,0x22,0x8a,0x86,0x87,0x96,0x96,0x8c,0x90,0x3c,0x07,0x09,0x9f,0x80,0x20,0x1e,0x0e,0x2f,0x9b,0x15,0x2b,0x00,0x13,0x04,0x10,0x2c,0x0d,0x07,0x0b,0x99,0x17,0x07,0x0f +,0x1a,0x0a,0x08,0x1c,0x8f,0xb1,0xae,0x0c,0x12,0xa3,0x8f,0x83,0x8b,0x94,0x0e,0xbb,0xa1,0x85,0x80,0x98,0x8d,0xbd,0x8c,0x87,0x91,0x90,0xa8,0x8e,0x13,0x95,0x88,0xc0 +,0x95,0x0f,0xbc,0xa6,0xc8,0x0a,0x0c,0xb3,0x25,0x28,0x04,0x5e,0x1d,0x00,0x09,0x13,0x0b,0x0b,0x07,0x08,0x1b,0x1c,0x13,0x02,0x4d,0x2e,0x22,0x13,0x5c,0x2d,0x96,0x83 +,0x98,0x82,0x2d,0xa2,0x87,0x8d,0x85,0x99,0x8b,0x85,0xa5,0xa3,0x4e,0x89,0x89,0x91,0x4e,0x97,0x9c,0x28,0x30,0x1a,0x9e,0xb0,0x24,0x1c,0xb8,0x0b,0xbf,0x2d,0x59,0x08 +,0x14,0xbf,0x14,0x22,0x05,0x5a,0x02,0x20,0xa2,0x0c,0x08,0x07,0x25,0x1a,0x20,0x29,0x08,0xbf,0x97,0x4c,0x17,0x20,0x8b,0xa6,0xa7,0x9d,0x96,0x8f,0xa6,0x8d,0x8b,0x8f +,0x9f,0x8e,0x9a,0x96,0x8f,0x93,0x9c,0x83,0x81,0x8f,0x8f,0xc5,0x2b,0x43,0x93,0x2a,0x9a,0x29,0x22,0x0d,0x03,0x1f,0x1b,0x07,0x03,0x0e,0x0d,0x0b,0x17,0x0d,0x02,0x13 +,0x0e,0x4c,0x1c,0x12,0x04,0xa9,0x19,0x0d,0x8e,0x51,0x94,0x94,0x8f,0x9f,0x94,0x93,0x96,0x91,0x87,0x88,0x80,0x8b,0x53,0x8d,0x8e,0x8d,0x8e,0x9c,0x21,0x23,0xae,0xae +,0xa9,0xce,0x1a,0x13,0x1a,0x69,0x21,0x19,0x11,0x1b,0x29,0x9c,0x90,0x0d,0x0f,0xb1,0x3f,0x1a,0x22,0x07,0x2f,0x0f,0x1e,0x0d,0x26,0x27,0x0a,0xb8,0x22,0x17,0x17,0xce +,0x20,0x9e,0x1c,0xca,0x96,0x9e,0x9e,0x8e,0xad,0xa9,0x99,0x3b,0x84,0x87,0x8a,0x99,0x78,0xa8,0x8d,0x80,0x92,0xa5,0xa1,0xb3,0xa9,0x9e,0x95,0x2f,0xbc,0x2e,0x19,0x42 +,0x0d,0x0d,0x2d,0x16,0x0f,0x14,0xff,0x03,0x0f,0x2b,0x0c,0x30,0x1f,0x0d,0x08,0x2e,0x38,0x39,0x1d,0x0c,0x9a,0x8e,0xcc,0x8c,0x34,0x1e,0xac,0x3c,0x92,0x97,0x8b,0x8d +,0xc3,0x9f,0x8d,0x85,0x93,0x99,0x86,0xa0,0x98,0x8d,0xba,0x9d,0x8d,0xad,0x0e,0x3e,0x2f,0xb1,0x11,0x18,0x3e,0x15,0x1e,0x1e,0xa9,0x1a,0x1e,0x1b,0x1d,0x0e,0x29,0x1f +,0x1f,0xbb,0x07,0x19,0xc6,0x1b,0x12,0x29,0x35,0x2e,0x31,0xc6,0x49,0x50,0x8e,0xba,0x8e,0x45,0x37,0x91,0x90,0x94,0xc1,0x9a,0xa8,0x83,0xad,0xea,0x54,0x95,0x8e,0xa1 +,0x2e,0x22,0x47,0xcf,0x96,0x2f,0x8d,0x22,0x30,0xa1,0xbe,0x56,0x26,0x20,0x2a,0x9e,0x11,0x1e,0x12,0x14,0x2b,0x34,0x1a,0x10,0xc8,0xa8,0x2b,0xee,0x39,0x13,0x9e,0x2b +,0x0e,0x18,0x28,0x28,0x2b,0x24,0x13,0x2a,0x93,0x2c,0x2c,0xaa,0xb0,0x93,0x38,0xa4,0x9d,0xac,0x87,0x8e,0x8b,0x98,0x95,0x87,0x98,0xa9,0xed,0x93,0x99,0x9e,0x3b,0x9d +,0xdd,0x36,0x9d,0x1c,0x0a,0x14,0x1b,0x0e,0x14,0x0d,0x11,0x20,0x1e,0x07,0x0e,0x51,0x11,0x0f,0xc4,0x0f,0x79,0xcb,0x2f,0x9f,0x9a,0x92,0xb5,0x93,0x2a,0x9f,0x8f,0x9d +,0x92,0xa5,0x8e,0x97,0x3b,0x9a,0x96,0x6f,0xa4,0x97,0x24,0x29,0x3b,0xbe,0xaa,0x28,0xb5,0x1f,0x18,0x14,0x30,0x38,0x29,0x20,0xc5,0x5b,0xb2,0xa7,0x14,0x9d,0xb8,0x27 +,0x3b,0x3b,0x4f,0x29,0xc5,0x9a,0xb4,0x24,0x54,0x2c,0x1b,0xe2,0x23,0x2e,0x51,0x24,0x1f,0x43,0x9e,0x2c,0x19,0x0a,0x19,0x28,0x23,0x99,0x1e,0xd4,0xa6,0xa4,0x9d,0xa9 +,0xbe,0xae,0x9b,0xb9,0xa0,0x8f,0x99,0xab,0x89,0x8f,0x96,0x96,0x8d,0x26,0x4e,0xaa,0x2f,0xaa,0x35,0x23,0x1a,0x2a,0x3a,0x11,0x0c,0x1e,0x20,0x09,0x0f,0x23,0x1b,0x4e +,0x0e,0x35,0x1f,0x21,0x25,0x31,0xad,0x97,0xa8,0x61,0x9f,0x92,0x95,0x93,0x9c,0x10,0x2a,0x34,0xa1,0x39,0xa6,0xa0,0xab,0x99,0xd0,0xa1,0x99,0x9f,0xd3,0xc7,0x58,0x39 +,0xa8,0xce,0x9d,0x26,0xc8,0xa7,0x1e,0x2d,0x14,0x42,0xbf,0x26,0x34,0xaa,0x1c,0x4f,0x2e,0x45,0x46,0x2c,0x1c,0x1b,0x18,0x1d,0x9d,0xc3,0xaf,0x3d,0x28,0x1a,0xf7,0xc0 +,0xbc,0xaa,0xbc,0xcd,0xb1,0x36,0x9a,0x94,0x24,0xeb,0x14,0x1f,0x2c,0xc4,0xa4,0xaf,0x92,0xb2,0x37,0xab,0xba,0x9d,0xae,0x31,0x2d,0x5c,0x9a,0xa4,0x56,0xab,0x99,0xc4 +,0xb8,0x2b,0x1c,0x48,0xaf,0xcb,0xbd,0x6e,0x32,0x3d,0x1d,0xbe,0xce,0x26,0x14,0x0d,0x21,0x3c,0x9c,0xb7,0x47,0x27,0x1d,0x30,0x2d,0x39,0x21,0x67,0xc8,0x3e,0x2c,0xb0 +,0x98,0x9b,0xae,0xc7,0x4c,0x3a,0xac,0x99,0x92,0x93,0x90,0x9a,0xa8,0xa8,0xa4,0xa3,0xc5,0x29,0x39,0xd6,0xae,0xc2,0x45,0x4a,0xd1,0xa5,0xd9,0x19,0x12,0x20,0xcc,0xa8 +,0xc6,0x2a,0x29,0x3b,0x68,0xac,0xb7,0x1f,0x15,0x15,0x1d,0xee,0xa6,0xad,0x37,0x2c,0x52,0x67,0x37,0x23,0x2a,0xc3,0xac,0xc8,0x4e,0xfd,0xbe,0xa6,0xb2,0x32,0x1d,0x1f +,0x26,0x4b,0xa8,0xa9,0xac,0xc1,0xf6,0xb4,0xab,0x3a,0x20,0x1e,0x38,0xa7,0xaf,0x40,0x31,0xde,0x9e,0x99,0xf7,0x19,0x17,0x2f,0xac,0xa6,0x6b,0x2a,0x2f,0xbd,0x9d,0x9d +,0xbb,0x1f,0x18,0x1f,0xd9,0xa9,0xac,0xd2,0x2e,0x43,0xb3,0xbc,0x32,0x24,0x25,0xbe,0xa9,0xf5,0x52,0xbe,0xa1,0x9e,0xc7,0x1e,0x1a,0x2b,0xdf,0xb2,0xc4,0x41,0x36,0xb6 +,0x98,0x9a,0xbf,0x1e,0x16,0x22,0xad,0x9e,0xb5,0x2d,0x26,0xcd,0x9a,0x99,0xe3,0x1f,0x21,0x47,0xb9,0xcf,0x3a,0x33,0xbf,0xa3,0xa4,0xb8,0x2f,0x1e,0x24,0x50,0xc3,0xe1 +,0x4e,0x2e,0x2a,0xcb,0xa4,0xa7,0xdb,0xb7,0xbd,0xaf,0x34,0x2c,0x30,0xbd,0xae,0xa9,0x4c,0x20,0x2d,0xbc,0xa7,0x9a,0x9f,0x93,0x80,0x4f,0x15,0x17,0x9e,0x1f,0xb5,0x22 +,0x1a,0x2f,0x00,0x06,0x00,0x9d,0xb0,0x20,0x23,0x0f,0x8d,0x97,0x9e,0x9b,0xaf,0x95,0x9a,0x86,0x8d,0x9c,0x85,0x46,0x16,0xac,0x1a,0x8f,0x80,0xa5,0xa0,0x9f,0x1f,0x18 +,0x30,0x1b,0x14,0x09,0x02,0x03,0x07,0x04,0x04,0x0a,0x0f,0x0c,0x0e,0x15,0x09,0x1b,0xa3,0x97,0xbc,0x5f,0xa4,0x9e,0x89,0x88,0x8b,0x9b,0x8d,0x8a,0x8e,0x80,0x83,0x80 +,0x85,0x83,0x87,0x82,0x8f,0x8a,0x86,0x18,0xd6,0x8a,0x88,0x02,0x2d,0xc6,0x0b,0xa5,0x0c,0x06,0x06,0x00,0x04,0xa5,0x11,0x07,0x03,0x00,0xce,0x05,0x04,0x00,0x0c,0x17 +,0x1a,0xb0,0x46,0x15,0x15,0x8d,0x8d,0x81,0x84,0x84,0x8a,0x81,0x82,0x85,0x85,0x85,0x8d,0x8b,0x85,0x87,0x80,0x95,0x9e,0xba,0x8f,0xda,0x9a,0xae,0x25,0x0e,0x0f,0x28 +,0x07,0x10,0x0b,0x04,0x01,0x06,0x07,0x13,0x09,0x03,0x01,0x04,0x07,0x09,0x0f,0x0a,0xae,0xb9,0x20,0xd8,0x48,0x9d,0x87,0x87,0x92,0x94,0x97,0x9d,0x94,0x92,0x8b,0x82 +,0x86,0x94,0x90,0x80,0x8c,0x8d,0x94,0x85,0x88,0x8c,0x88,0xb1,0x87,0x33,0x0f,0x1c,0x1e,0x0e,0x00,0x16,0x32,0x0f,0x06,0x00,0x00,0x03,0x12,0x0c,0x1f,0x0e,0x0a,0x01 +,0x06,0x08,0x33,0xa4,0x2c,0x8e,0x22,0x8a,0x9f,0xc5,0x89,0x8c,0x80,0x8f,0x93,0x8b,0x81,0x84,0x87,0x83,0x8b,0x91,0x9b,0x8b,0x94,0x8e,0xb1,0x29,0x2a,0x2f,0xbc,0xaa +,0x92,0xd1,0x5d,0x0a,0x02,0x0b,0x1e,0x35,0x04,0x04,0xdb,0x28,0x24,0x07,0x02,0x00,0x4d,0x5b,0x18,0xbd,0x0a,0x0b,0x07,0xa1,0x2a,0x8e,0x87,0x2b,0x98,0x84,0xa0,0x1b +,0x89,0x8d,0x90,0xe5,0x1c,0x80,0x8b,0xa8,0x93,0x9a,0x8b,0x81,0x80,0x8f,0xaa,0xbf,0x96,0x2e,0x64,0xbe,0x36,0x1a,0x15,0x0e,0x00,0x03,0x16,0x17,0x00,0x0b,0x00,0x08 +,0x0a,0x1c,0x8a,0x19,0x00,0x15,0x1a,0x19,0xa2,0x8d,0x2e,0x2d,0x57,0x97,0x8a,0x8d,0x8f,0x8c,0x8e,0x1b,0xae,0x8e,0x80,0x88,0x8a,0xb0,0x8a,0x9e,0xa4,0x80,0x82,0x94 +,0x04,0x26,0x9c,0x80,0x1c,0x08,0x19,0x92,0x0e,0x1f,0x85,0x0b,0x0d,0x0a,0xc6,0x06,0x14,0xa3,0x00,0x0f,0x05,0x03,0x16,0x11,0xcd,0x00,0x0c,0x05,0x1e,0xad,0xd4,0xa2 +,0x11,0x91,0x04,0xa5,0x81,0x82,0x9a,0x21,0xa3,0x9c,0x81,0x86,0x82,0x80,0xb4,0x15,0x81,0x85,0x90,0x61,0xad,0x88,0x8e,0x9a,0x0e,0x08,0xa6,0x80,0x1f,0x08,0x0d,0x19 +,0x4c,0x03,0x19,0x03,0x13,0x10,0x0a,0x1c,0x17,0x0c,0x05,0xba,0x16,0x0a,0x0c,0x1f,0x1e,0x06,0x0e,0x8d,0x91,0xb3,0x0f,0x04,0x1e,0x8f,0x80,0x87,0x8c,0x0e,0x11,0xa8 +,0x88,0x80,0x92,0x8d,0xb3,0x94,0x86,0x92,0x8c,0x9a,0x8b,0x1f,0x9e,0x82,0x26,0xb3,0x18,0xa2,0x83,0x9c,0x16,0x0a,0xb1,0x1e,0x17,0x0a,0x2c,0x1d,0x00,0x04,0x0f,0x11 +,0x0c,0x0f,0x05,0x14,0x12,0x0e,0x03,0x22,0x2c,0x4b,0x13,0xcd,0xaf,0x5b,0x87,0x29,0x8a,0x9e,0x9b,0x89,0x9e,0x8e,0x88,0x8b,0x87,0xa7,0x97,0xa6,0x8b,0x85,0x9a,0x39 +,0xb9,0x82,0x4e,0x33,0x1b,0x7a,0xb1,0x4b,0x19,0xcc,0x0d,0x39,0x97,0xac,0x0a,0x0a,0xbd,0x0b,0x18,0x07,0x1f,0x04,0x26,0xa8,0x07,0x0d,0x0a,0x19,0x13,0x29,0x23,0x11 +,0xd3,0xbd,0x2f,0x0e,0x0c,0x8a,0x99,0x2d,0x9b,0x4d,0x9d,0x9a,0x8c,0x8b,0x8c,0x8f,0x89,0x98,0x90,0x9c,0x98,0x8d,0x83,0x82,0x9d,0x91,0xa9,0xa2,0x46,0x8d,0x1f,0xa7 +,0x3d,0x10,0x0f,0x04,0x29,0x27,0x0b,0x00,0x0a,0x13,0x11,0x0c,0x19,0x09,0x0a,0x07,0x11,0x2e,0x29,0x0b,0xd9,0x41,0x12,0x92,0x3e,0xae,0x8d,0x97,0x9f,0x8f,0x99,0xaf +,0x98,0x89,0x88,0x83,0x83,0xbf,0x8f,0x94,0xa6,0x92,0x8e,0x9f,0x16,0x25,0x4d,0xa2,0xa8,0xd9,0x6b,0x25,0xaa,0x24,0x2a,0x2d,0x1e,0x28,0xa7,0x93,0x11,0x11,0x2a,0x45 +,0x16,0x37,0x0f,0xd9,0x18,0x18,0x0f,0x0e,0x1e,0x07,0x38,0x1f,0x25,0x1e,0x9d,0x19,0x4c,0x1b,0xdf,0x91,0xa1,0xb3,0x8f,0xb2,0xc3,0x8d,0x23,0x8d,0x88,0x85,0xa4,0xac +,0x91,0x9b,0x82,0x8b,0x9e,0x96,0x9c,0xb2,0x9e,0x8e,0xb4,0xa3,0x4d,0x13,0xa8,0x16,0x0a,0x2d,0x12,0x10,0x06,0x35,0x08,0x0d,0x1a,0x03,0x14,0x29,0x3b,0x08,0x34,0x1a +,0x1c,0x27,0x08,0x1d,0x9d,0x4d,0x91,0xa4,0x1f,0x2f,0x26,0x94,0x8f,0x85,0x88,0xa6,0xb3,0x9e,0x8c,0x89,0x8e,0x86,0x94,0x9a,0x8f,0x9c,0xaa,0x9b,0x99,0x1a,0xaf,0xdb +,0xa9,0x12,0x18,0xb0,0x19,0xe2,0x15,0xa4,0x30,0x17,0x1c,0x17,0x0e,0x17,0x20,0x0e,0xba,0x0d,0x0d,0x2a,0x0c,0x10,0x3d,0xb4,0x30,0x47,0x47,0xde,0x23,0x98,0xd3,0x9a +,0xa2,0x21,0x91,0x8c,0x87,0xa2,0x9a,0xae,0x8c,0x9b,0xa7,0x3c,0xb1,0x8b,0x96,0xb3,0xd7,0xcf,0x3f,0x95,0xc9,0x8f,0x2f,0x0e,0xa7,0xac,0x2f,0x22,0x2a,0xeb,0x97,0x1a +,0x1b,0x28,0x16,0x1e,0x2b,0x18,0x0f,0xdc,0xb8,0x1f,0x1d,0x22,0x0a,0xbf,0xcc,0x2c,0x2f,0x55,0x3c,0x12,0x1f,0x14,0x1a,0xa0,0x20,0x20,0xb0,0xd5,0x97,0xe6,0x91,0x8d +,0x9e,0x8a,0x9c,0xa2,0xa0,0x9d,0x89,0x92,0x9f,0xc2,0x91,0x9f,0x8f,0xaa,0xa4,0x98,0x26,0xa4,0x4b,0x0d,0x1c,0x1a,0x0f,0x36,0x11,0x12,0x19,0x1b,0x08,0x07,0x28,0x18 +,0x05,0x34,0x0b,0x19,0x50,0x26,0x92,0xad,0x96,0xae,0x8d,0x93,0xc9,0x9a,0x94,0x93,0xa4,0xb1,0x9d,0x3a,0xbe,0x96,0xfa,0x9f,0x8c,0xeb,0x3b,0x3a,0xcf,0xa2,0x18,0xcf +,0x30,0x26,0x2f,0x4e,0xac,0x4b,0x33,0xa5,0x34,0x4d,0xae,0x0c,0x38,0xe6,0x1a,0x2c,0xd0,0xaf,0x3a,0x3e,0x9c,0xab,0x3f,0x60,0x2f,0x22,0xbb,0x1f,0x21,0x1b,0x1e,0x26 +,0x1e,0xbf,0x0f,0x36,0x29,0x1c,0x25,0x15,0xa5,0x30,0x56,0x42,0x2f,0xa4,0x9a,0xa0,0x92,0x8a,0xa4,0x96,0x8f,0x9e,0xaa,0x8d,0x8b,0x8e,0x9f,0x8d,0xb5,0xaa,0x90,0xab +,0x9d,0x2b,0x1c,0x0a,0x0d,0x1d,0x10,0x0f,0x15,0x16,0x0c,0x0e,0x31,0x16,0x1f,0x0f,0x3e,0x45,0x20,0x2e,0x2a,0xfc,0xa2,0xbc,0x2b,0xa6,0xa3,0xac,0xb3,0x97,0x45,0xab +,0xbb,0xa1,0x3b,0xb2,0xac,0x42,0x92,0xa5,0xa3,0x98,0x96,0x9d,0x99,0xa0,0x47,0xb2,0x43,0x9d,0x3e,0x1c,0x2c,0x18,0xab,0x24,0xb8,0xcf,0x27,0x24,0x2a,0x15,0x2f,0xde +,0xc8,0xce,0x19,0x1f,0x25,0x2a,0x17,0xae,0xda,0x41,0x7c,0x23,0x14,0x64,0x3d,0xda,0xa7,0x57,0xb9,0xa1,0x52,0xba,0x99,0x29,0x9c,0x53,0x4b,0x5e,0xc3,0xbc,0x1d,0x3f +,0x21,0x3a,0xa0,0x9e,0x98,0x95,0xb5,0xab,0xab,0xa8,0xab,0xae,0xa8,0xbc,0x33,0x62,0x29,0x33,0xae,0xb7,0xbf,0x2a,0x3b,0x2e,0x2f,0x28,0x58,0x23,0x1c,0x21,0x1a,0xdc +,0x30,0xb3,0x33,0x2d,0x2d,0x16,0x36,0x37,0xb9,0x58,0xd0,0x3a,0x26,0x1d,0x7d,0x9a,0x9f,0x9f,0xba,0xbe,0x23,0xb1,0x97,0x9c,0x99,0x97,0x9e,0xad,0x9f,0x9f,0x99,0x96 +,0x9a,0xae,0xee,0x40,0x2f,0x30,0x35,0x24,0x23,0x25,0x30,0x50,0x65,0x40,0x3a,0x41,0x31,0x4e,0xd9,0xbf,0x34,0x25,0x1c,0x1a,0x1e,0x32,0xbb,0xbc,0xb6,0xcf,0x34,0x29 +,0x3e,0xbd,0xa7,0xaf,0x3f,0x28,0x20,0x2e,0xe0,0xae,0xaa,0xbf,0x2c,0x25,0x28,0x49,0xaf,0xab,0xac,0x4d,0x43,0x3b,0x50,0x5f,0xb6,0xa9,0xb7,0x6e,0x34,0x30,0x34,0x64 +,0x4f,0x36,0x2f,0x3f,0xce,0xb7,0xaa,0xaa,0xbc,0xec,0x7e,0xda,0xc3,0xb2,0xcd,0x2d,0x20,0x1c,0x1f,0x2f,0x6b,0xbb,0xbe,0xc7,0x4b,0x39,0xcf,0xb0,0xb1,0xd2,0x37,0x2c +,0x2e,0x5c,0xbd,0xab,0xa5,0xb6,0x42,0x3d,0xf5,0xb6,0xa3,0xb2,0x3c,0x26,0x1e,0x23,0x3c,0xbb,0xb0,0xad,0xc0,0x2d,0x2b,0x52,0xad,0xa0,0xa3,0xca,0x3b,0x44,0xc7,0xb9 +,0xb2,0xb5,0xbd,0x3f,0x27,0x29,0x2d,0x5c,0x54,0x2e,0x36,0xd4,0xb7,0xb2,0xaf,0xb2,0xb4,0xca,0x3e,0x3a,0x59,0xb9,0xb5,0xae,0xbf,0xcb,0xd0,0xb0,0xb8,0xac,0xc1,0x41 +,0x20,0x15,0x1a,0x1c,0xbd,0xee,0xc3,0xbe,0x66,0x46,0x5b,0x30,0x34,0x64,0x13,0xae,0x80,0xa1,0x00,0x8a,0x80,0xc8,0x8a,0xe8,0xc3,0x18,0x0e,0x12,0x09,0x11,0x00,0x03 +,0x00,0x01,0x02,0x00,0x03,0x00,0x01,0x02,0x05,0x0b,0x0a,0x0c,0x0e,0x44,0x62,0xbe,0x9a,0x98,0xab,0xcd,0xa4,0x94,0x80,0x81,0x90,0x87,0x80,0x81,0x80,0x81,0x80,0x81 +,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x86,0x84,0x83,0x87,0x8b,0x8e,0xb6,0x38,0xab,0xb8,0x3c,0x41,0x49,0x1b,0x0c,0x0a,0x08,0x03,0x01,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x00,0x00,0x04,0x05,0x01,0x04,0x03,0x03,0x00,0x05,0x0b,0x09,0x1b,0x24,0x2a,0x97,0x9f,0x8a,0x86,0x83,0x84 +,0x87,0x85,0x88,0x81,0x82,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x81,0x81,0x86,0x82,0x89 +,0x84,0x87,0x87,0x83,0x8d,0x89,0x8f,0x90,0x8f,0x9e,0x9e,0x2c,0x17,0x17,0x07,0x07,0x08,0x04,0x03,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x03 +,0x01,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x02,0x04,0x02,0x0a,0x0c,0x17,0x0b,0x12,0x28,0x16,0x30,0x1d,0x18,0x17,0x17,0x16 +,0x10,0x29,0x3c,0x2f,0x4e,0xa8,0x9a,0x96,0x98,0x8a,0x81,0x87,0x82,0x81,0x80,0x81,0x81,0x80,0x81,0x80,0x83,0x87,0x85,0x83,0x80,0x82,0x81,0x80,0x81,0x80,0x80,0x80 +,0x80,0x80,0x81,0x80,0x82,0x80,0x82,0x80,0x84,0x83,0x89,0x8e,0x8d,0x9e,0x91,0xb0,0xbd,0x32,0xcc,0xaa,0x4c,0x1d,0x10,0x12,0x12,0x0c,0x09,0x12,0x0c,0x0d,0x0d,0x1f +,0x24,0xc8,0xa9,0xa7,0x92,0x94,0x8a,0x85,0x88,0x8a,0x88,0x8a,0x89,0x87,0x89,0x8e,0x91,0x9c,0x9b,0x93,0x94,0x9c,0x97,0xa9,0x95,0xa4,0xa9,0x99,0x9b,0xa0,0x23,0x2c +,0x09,0x0e,0x08,0x06,0x03,0x00,0x01,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03 +,0x01,0x01,0x00,0x03,0x01,0x03,0x06,0x07,0x06,0x04,0x0a,0x09,0x0e,0x0c,0x13,0x13,0x0c,0x1e,0x1e,0xa6,0x9d,0x98,0x88,0x89,0x81,0x84,0x82,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x80,0x87,0x85,0x83,0x83,0x85,0x87,0x84,0x88,0x82,0x84 +,0x81,0x84,0x84,0x82,0x84,0x83,0x81,0x81,0x83,0x82,0x84,0x83,0x87,0x88,0x89,0x96,0x94,0x3d,0x2d,0x1c,0x0b,0x0a,0x05,0x09,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x05,0x05,0x03,0x05,0x00,0x09,0x07,0x09,0x06,0x0a,0x0f,0x0b,0x0e,0x08,0x0e,0x10,0x21 +,0x3a,0x3b,0xaa,0xa3,0x91,0x8f,0x84,0x82,0x86,0x86,0x82,0x84,0x84,0x86,0x88,0x83,0x8c,0x88,0x9a,0x8e,0x8c,0x92,0x8d,0x8e,0x8d,0x8f,0x93,0x8e,0x88,0x8b,0x8a,0x8a +,0x95,0x89,0x8f,0x90,0x8e,0xd2,0x99,0x2d,0xca,0xad,0xcd,0xb2,0xad,0x34,0x43,0x73,0x33,0x9e,0x36,0x78,0x22,0x20,0x1d,0x15,0x1c,0x10,0x15,0x0e,0x0f,0x0a,0x0e,0x15 +,0x12,0x1f,0x10,0x1c,0x12,0x24,0xc7,0xcd,0x44,0x2c,0xe6,0x27,0x59,0x25,0x36,0xd0,0x3a,0xb2,0x28,0xac,0x9e,0xa3,0xab,0xb0,0xa6,0xaa,0x9f,0xa1,0x8f,0xc5,0xa1,0x3c +,0xd9,0x4d,0x2b,0xe1,0x2c,0xc0,0x21,0x39,0x45,0xa3,0xa5,0x97,0x91,0x8c,0x89,0x89,0x81,0x82,0x80,0x82,0x84,0x80,0x83,0x80,0x81,0x81,0x81,0x84,0x85,0x89,0x8c,0x93 +,0x90,0xa3,0x95,0xd9,0x30,0x43,0x15,0x12,0x08,0x06,0x05,0x05,0x02,0x02,0x01,0x00,0x02,0x00,0x03,0x02,0x03,0x03,0x04,0x07,0x07,0x0d,0x11,0x16,0x0d,0x14,0x13,0x1f +,0x27,0x1f,0xbe,0x1b,0x2b,0x5d,0xd5,0xac,0xac,0xa1,0xa8,0x9d,0x9e,0x8b,0x8a,0x86,0x8c,0x8b,0x84,0x88,0x83,0x88,0x85,0x89,0x89,0x97,0x93,0x91,0x90,0x8c,0x96,0x9d +,0xb9,0x9e,0x96,0x91,0xa5,0x4a,0x39,0x2f,0xb9,0x26,0x2e,0x25,0x14,0x0f,0x07,0x0f,0x0b,0x19,0x0f,0x19,0x0c,0x10,0x1d,0x16,0x56,0x18,0x27,0x11,0x16,0x19,0x16,0x15 +,0x13,0x16,0x09,0x0e,0x07,0x10,0x0f,0x0f,0x1e,0x0e,0x1d,0x1c,0x24,0x3a,0xbb,0x37,0xce,0x2d,0xd7,0xaf,0x2f,0xa6,0x2d,0xb6,0x45,0x33,0xa7,0xb3,0xa1,0x9d,0x97,0x9d +,0x8f,0x8c,0x88,0x87,0x8b,0x8a,0x97,0x8f,0x9e,0xa0,0xcd,0x2d,0x2b,0x16,0x10,0x0b,0x0f,0x0d,0x12,0x14,0x16,0x17,0x25,0x40,0xa6,0x99,0xa9,0x94,0x96,0x8b,0x87,0x8b +,0x89,0x89,0x89,0x89,0x88,0x87,0x84,0x84,0x84,0x87,0x88,0x87,0x89,0x8a,0x8b,0x99,0xaa,0x33,0x20,0x12,0x0d,0x0a,0x06,0x04,0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x02 +,0x01,0x04,0x03,0x08,0x0a,0x09,0x09,0x0a,0x0b,0x0f,0x13,0x12,0x1a,0x17,0x19,0x18,0x20,0xb7,0xa7,0x9e,0x97,0x99,0x94,0x8e,0x8a,0x87,0x88,0x8a,0x89,0x8d,0x88,0x86 +,0x8d,0x88,0x8d,0x8d,0x8e,0x8d,0x87,0x8b,0x89,0x87,0x8b,0x8a,0x8a,0x8a,0x88,0x8d,0x90,0x98,0xa8,0xa1,0xa6,0x5f,0x3f,0x23,0x18,0x16,0x16,0x16,0x11,0x0e,0x15,0x19 +,0x11,0x16,0x1e,0x23,0x16,0x16,0x12,0x18,0x11,0x0f,0x11,0x0c,0x0d,0x07,0x0b,0x0c,0x0c,0x0e,0x0f,0x0c,0x14,0x14,0x1d,0x3f,0x20,0x29,0x27,0x24,0x60,0x28,0x2c,0x27 +,0x18,0x1e,0x1e,0x3b,0xcf,0xbb,0xc1,0xa7,0xa9,0x9c,0x92,0x8c,0x8a,0x8e,0x8b,0x8e,0x8c,0x8e,0x91,0x91,0xa3,0xa7,0x4d,0xc5,0xd3,0xc4,0x2a,0x26,0x28,0x22,0x25,0x22 +,0xb3,0x23,0x37,0x3d,0x2d,0xb5,0xbe,0xa1,0x9c,0xa2,0x99,0x9a,0x8f,0x8a,0x89,0x89,0x84,0x85,0x82,0x83,0x83,0x82,0x85,0x84,0x88,0x8c,0x8f,0x95,0xbd,0xc1,0x12,0x0f +,0x09,0x05,0x08,0x01,0x06,0x03,0x01,0x03,0x02,0x04,0x05,0x04,0x03,0x04,0x03,0x05,0x03,0x04,0x07,0x03,0x08,0x04,0x08,0x0c,0x0f,0x16,0x1e,0x2d,0x41,0xa6,0x9b,0x8f +,0x8f,0x8c,0x8e,0x8e,0x8d,0x91,0x89,0x91,0x8d,0x8d,0x97,0x90,0x92,0x8a,0x8b,0x89,0x85,0x87,0x86,0x85,0x84,0x82,0x82,0x86,0x85,0x8d,0x8a,0x8c,0x97,0x92,0x9d,0xbb +,0x48,0x27,0x2f,0x47,0x24,0x38,0x2c,0x25,0x35,0x1d,0xc5,0x2b,0x1d,0x2a,0x19,0x20,0x1d,0x1b,0x1a,0x0f,0x0d,0x0c,0x07,0x0b,0x0d,0x0c,0x10,0x0f,0x10,0x0e,0x0f,0x1d +,0x1f,0x1f,0x17,0x18,0x1c,0x20,0x17,0x1f,0x16,0x1a,0x18,0x0f,0x1d,0x16,0x5e,0x23,0x48,0xae,0x3b,0xa5,0x9a,0x94,0x8d,0x94,0x94,0x8e,0x94,0x8f,0x8d,0x9a,0x90,0xaa +,0xac,0xb2,0x59,0x99,0xe5,0xb8,0xaf,0x3b,0xf7,0xd8,0x39,0xbc,0x2d,0x27,0x44,0x18,0xd9,0x65,0x47,0xab,0x47,0xa8,0xab,0x98,0x8b,0x89,0x8a,0x85,0x85,0x84,0x81,0x82 +,0x80,0x81,0x81,0x86,0x85,0x8a,0x89,0x8f,0x9a,0xae,0x25,0x1c,0x0e,0x0d,0x0c,0x06,0x04,0x03,0x04,0x02,0x04,0x04,0x04,0x03,0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x02 +,0x03,0x07,0x06,0x0a,0x0c,0x0c,0x1d,0x1f,0x49,0xad,0xa8,0x9b,0xa5,0x9c,0x9c,0x96,0x9c,0x92,0x9c,0xa6,0x9b,0xa2,0x8d,0x93,0x8c,0x8f,0x8d,0x8b,0x87,0x86,0x84,0x85 +,0x89,0x83,0x89,0x86,0x87,0x88,0x8b,0x96,0x99,0xa6,0xa0,0xaa,0x9c,0xb0,0xaf,0xa9,0x5a,0x9c,0xc2,0x9a,0x3c,0x35,0x3a,0x2a,0x24,0x1f,0x1e,0x0f,0x0f,0x06,0x0c,0x0a +,0x0c,0x10,0x0f,0x12,0x11,0x12,0x18,0x25,0x17,0x1b,0x10,0x13,0x1c,0x0c,0x1c,0x0a,0x10,0x0c,0x0b,0x0b,0x0c,0x17,0x18,0x28,0x1b,0x42,0x27,0xb4,0x9e,0xa3,0x9a,0xbc +,0x9e,0x9c,0x9b,0x93,0x9c,0x99,0xa1,0x9f,0xb8,0x9c,0x9d,0x92,0x9b,0x9c,0x94,0x98,0x96,0x9c,0x8c,0xa8,0x9f,0xc5,0xc5,0xbb,0x53,0xb7,0x3c,0x2d,0x1c,0x20,0x1d,0x5a +,0xc0,0xae,0x95,0x9e,0x8a,0x8f,0x89,0x85,0x87,0x84,0x8a,0x88,0x8c,0x89,0x95,0x8f,0xb0,0xaa,0xd7,0x1f,0x3b,0x16,0x1f,0x1a,0x13,0x16,0x0e,0x13,0x16,0x13,0x0f,0x17 +,0x0b,0x0f,0x12,0x0c,0x18,0x0d,0x1a,0x0c,0x0f,0x0d,0x15,0x10,0x17,0x1c,0x22,0x2d,0x21,0xbb,0x34,0xaa,0x5f,0xbb,0xc6,0xb4,0xc2,0xee,0xbd,0x45,0x62,0x2b,0x5e,0xd8 +,0x28,0xaf,0xdc,0xa6,0x3d,0xa9,0xae,0xab,0x9c,0xb4,0x9c,0xb7,0x9d,0xbc,0xa0,0xac,0x9a,0xb1,0xa9,0xab,0xbc,0x9f,0xb3,0x9e,0xa6,0xa4,0xa0,0xa2,0x99,0xa5,0x9a,0xa5 +,0x9b,0xa1,0xa2,0xa2,0xaf,0x9e,0x47,0xa9,0x2a,0xce,0x39,0x3f,0x3a,0x2e,0x2c,0x3d,0x2d,0x27,0x4c,0x2e,0x63,0x2a,0x26,0x29,0x1a,0x2f,0x18,0x1a,0x1f,0x12,0x27,0x17 +,0x1e,0x20,0x24,0x1f,0x3b,0x1c,0x2e,0x28,0x27,0x2a,0x1d,0x26,0x2c,0x1e,0x2f,0x2e,0x1f,0x41,0x24,0x38,0x27,0x38,0x4e,0x34,0x3a,0xc2,0x3b,0xaf,0xbe,0xa9,0xb3,0xad +,0x9f,0xb1,0xa0,0x9a,0xa0,0x9b,0x9d,0x99,0x98,0x9c,0x91,0x98,0x92,0x97,0x91,0x95,0x8e,0x99,0x8e,0x98,0x95,0x8f,0xa1,0x93,0xa7,0xa4,0xa0,0xb8,0xad,0xb5,0x3d,0xb9 +,0x3a,0x2d,0xcd,0x23,0x2f,0x2a,0x1d,0x3c,0x1a,0x27,0x1b,0x18,0x20,0x1f,0x16,0x1e,0x1a,0x19,0x1f,0x13,0x37,0x18,0x20,0x1c,0x16,0x22,0x1d,0x20,0x2f,0x32,0x23,0x5c +,0x23,0x3e,0x22,0x1e,0x30,0x1d,0x66,0x24,0x4b,0x41,0x30,0x3a,0x2c,0x37,0x31,0xc9,0x2f,0xbb,0x3f,0xf5,0xe0,0x45,0xb1,0xee,0xaa,0xb1,0xa0,0xa4,0xa4,0x9e,0x9f,0x9d +,0x9c,0x96,0xa2,0x91,0x9b,0x97,0x93,0x9d,0x91,0x9e,0x91,0x9b,0x92,0x9c,0x99,0x9a,0xac,0x9c,0xb7,0x9e,0x44,0xa2,0xcc,0x39,0xd2,0x28,0x4c,0x1e,0x3e,0x1f,0x29,0x1b +,0x23,0x1c,0x12,0x21,0x12,0x1f,0x11,0x1f,0x14,0x19,0x1a,0x19,0x1b,0x16,0x29,0x19,0x1f,0x1a,0x25,0x1c,0x1c,0x26,0x1e,0x2a,0x22,0x2e,0x1f,0x37,0x38,0x25,0x57,0x2c +,0xcc,0x22,0xbd,0x44,0xd5,0xdc,0xd7,0xa6,0xd4,0x9f,0xb4,0x99,0xb0,0x99,0x9e,0xa8,0x96,0x9e,0x96,0xa1,0x93,0x96,0x99,0x94,0x96,0x8f,0x9a,0x8f,0x96,0x93,0x9d,0x98 +,0x97,0xa2,0x96,0xab,0x9d,0xa8,0xa1,0xaf,0xbb,0xb8,0xbb,0xb8,0x4a,0xc1,0x3e,0x54,0x3d,0x32,0x3b,0x28,0x33,0x20,0x2d,0x1e,0x2c,0x1d,0x24,0x25,0x1d,0x2a,0x19,0x2f +,0x1b,0x28,0x1e,0x21,0x1f,0x23,0x22,0x20,0x3b,0x1c,0x28,0x28,0x1f,0x29,0x22,0x2c,0x28,0x2b,0x2b,0x36,0x27,0x30,0x2d,0x25,0x47,0x23,0xd4,0x2c,0x3b,0x75,0x35,0x3e +,0x48,0xf7,0x4e,0xc4,0x68,0xa8,0x7d,0xb5,0xaa,0x63,0x9d,0xbf,0x9d,0xa7,0xa8,0x9f,0x9f,0xa4,0x9d,0x9c,0xa0,0x93,0xb7,0x91,0xaf,0xa0,0x9b,0xb8,0x9c,0xb3,0xa2,0xa4 +,0xb6,0xaa,0xaf,0xdd,0xb8,0xc5,0x35,0xae,0x2c,0xd0,0x43,0x28,0xc8,0x20,0x48,0x26,0x2c,0x2a,0x2b,0x23,0x29,0x21,0x2a,0x28,0x20,0x39,0x1f,0x28,0x2a,0x20,0x2f,0x1c +,0x2e,0x1f,0x2a,0x29,0x23,0x33,0x25,0x55,0x1f,0x6a,0x1f,0xcf,0x29,0x3c,0x50,0x3d,0xd2,0x38,0xb4,0x37,0xb7,0xe7,0xaf,0xdf,0xb2,0xb7,0xba,0xa3,0xc6,0x9e,0xae,0xa4 +,0xa0,0xb4,0x9f,0xae,0x9c,0xaf,0x9f,0xa9,0xa1,0xaa,0xa3,0xa2,0xb1,0x9c,0xc9,0x9c,0xbb,0xaa,0xaa,0xb0,0xab,0xb3,0xa9,0xc1,0xb5,0xdd,0xb4,0xd5,0xc8,0xbc,0x3d,0xaf +,0x49,0xc9,0x3e,0x65,0x5d,0x38,0xcb,0x2b,0xf5,0x33,0x53,0x2d,0x3e,0x28,0x2e,0x2f,0x29,0x42,0x24,0x4e,0x29,0x31,0x2b,0x26,0x2b,0x25,0x29,0x24,0x28,0x2a,0x31,0x29 +,0x2f,0x2d,0x2d,0x38,0x20,0x3a,0x31,0x2d,0x3f,0x37,0x46,0x49,0x3e,0x6c,0x42,0x3e,0xc1,0x57,0xbb,0xba,0x6e,0xac,0xf2,0xaa,0xbd,0xbd,0xa2,0xaf,0xa5,0xae,0xa3,0xb3 +,0xa4,0xc0,0xa2,0xbd,0xad,0xa8,0xb1,0xac,0xb4,0xab,0xad,0xac,0xb9,0xae,0x54,0xb3,0x57,0xca,0x4b,0xef,0x62,0x44,0x43,0xdc,0x34,0xd9,0x36,0x4b,0x33,0x32,0x3c,0x31 +,0x2d,0x29,0x46,0x25,0xec,0x21,0x4d,0x24,0x2e,0x2c,0x29,0x2e,0x34,0x2f,0x2a,0x37,0x25,0x39,0x2f,0x29,0x49,0x24,0x4b,0x36,0x2f,0x3f,0x36,0xdf,0x37,0x57,0x32,0xb2 +,0x33,0xbd,0x41,0xc4,0xe6,0xd4,0xb7,0xdf,0xae,0xc5,0xaf,0xb4,0xb4,0xb1,0xb2,0xac,0xbc,0xaa,0xc4,0xa8,0xad,0xab,0xa1,0xc1,0x9b,0xbc,0xa6,0xc0,0xa2,0xbf,0xaa,0xac +,0xc0,0xab,0xbe,0xae,0xc8,0xae,0xb5,0xbe,0xb4,0xc9,0xb6,0x5f,0xbe,0x5d,0xe1,0xd1,0x36,0xb0,0x2e,0xbf,0x32,0xc9,0x39,0x46,0x3e,0x34,0x4b,0x2c,0x5f,0x26,0x47,0x2e +,0x3a,0x3b,0x27,0x41,0x2a,0x40,0x2c,0x34,0x29,0x32,0x39,0x2b,0x51,0x25,0xd4,0x28,0xe9,0x2e,0x37,0x3f,0x2d,0x74,0x34,0x75,0x3b,0xcc,0x72,0x71,0xd5,0x41,0xc8,0x5f +,0xbd,0x6c,0xba,0xc3,0xb8,0xac,0xe0,0xa1,0xe4,0xa5,0x5d,0xab,0xbe,0xb6,0xaf,0xbf,0xae,0xea,0xa1,0x49,0xac,0xd4,0xa8,0xbb,0xc1,0xae,0x4e,0xbd,0x58,0xc3,0x3d,0x70 +,0xc8,0x4a,0xcd,0x3d,0xc2,0x34,0xbf,0x41,0x39,0x5e,0x2f,0xd5,0x28,0x5c,0x31,0x43,0x33,0x5a,0x35,0x41,0x38,0x37,0xd3,0x24,0x5d,0x2f,0x38,0x3e,0x33,0x53,0x2b,0x75 +,0x3b,0x78,0x35,0x4a,0x3e,0x2e,0xc4,0x2d,0xce,0x2d,0xba,0x3f,0x4c,0xda,0x48,0xc0,0x3b,0xb2,0x3c,0xc7,0xe2,0xbb,0xbe,0xd0,0xab,0x65,0xaa,0x44,0xab,0x6d,0xbb,0xae +,0xbf,0xa9,0xf8,0xa2,0x4a,0xa7,0x4c,0xaa,0xd0,0xc4,0xa9,0x5a,0xa6,0xe1,0xa9,0xcc,0xbf,0xc6,0xbf,0xcc,0xee,0xbe,0x5e,0xb3,0x4b,0xd9,0x54,0x3e,0xb5,0x2e,0xbb,0x3f +,0x5b,0xf7,0x45,0xd1,0x36,0x48,0x2f,0x5d,0x2b,0xf9,0x2e,0x3c,0x5b,0x2c,0xdc,0x2c,0x54,0x33,0x3f,0x37,0x3f,0x3a,0x2f,0xcf,0x2a,0xc3,0x2a,0x5a,0x42,0x2f,0xc7,0x30 +,0xc9,0x42,0xc3,0x3c,0x7c,0x52,0xd5,0xea,0x3b,0xb7,0x34,0xbb,0xec,0xc7,0xbb,0x6b,0xaa,0x64,0xb6,0x5c,0xbc,0xef,0xc2,0xb8,0xcb,0xaf,0x5e,0xaa,0xcc,0xae,0x4b,0xb8 +,0xbd,0xc8,0xbf,0x47,0xab,0x64,0xb7,0x5c,0xcd,0xbc,0x4c,0xb6,0x3e,0xc2,0x48,0xbf,0x4a,0xf9,0x4a,0x45,0xdf,0x38,0xc8,0x2a,0xbf,0x3b,0x4f,0x6c,0x40,0x62,0x43,0x42 +,0x4a,0x3c,0x2f,0x65,0x43,0x3a,0x64,0x2f,0xbb,0x34,0x4a,0x4c,0x3d,0x50,0x39,0x6c,0x3c,0xbd,0x30,0xb8,0x39,0xea,0xd0,0x3f,0xc8,0x44,0xe2,0x4a,0xd3,0x61,0xd9,0xbf +,0x5b,0xb7,0x40,0xb3,0x44,0xcf,0xd0,0x69,0xbb,0x4c,0xbc,0x4e,0xab,0x53,0xad,0x5a,0xbb,0xd3,0xcb,0xb7,0x3f,0xb3,0x4c,0xb3,0x70,0xc2,0x59,0xca,0xb3,0x53,0xaa,0x30 +,0xbe,0x50,0xd1,0xb8,0x2f,0xb1,0xf0,0xc4,0x57,0xdf,0x3b,0xcd,0xd8,0x55,0x64,0x2d,0xb5,0x41,0x4a,0x76,0x3c,0x4d,0x47,0x59,0x32,0x55,0x2f,0xbb,0x4a,0x4a,0xd3,0x2f +,0xc3,0x37,0x7e,0x35,0x51,0x4c,0xf3,0x3b,0x4a,0xcc,0x31,0xb6,0x3d,0xec,0x3d,0xbc,0xca,0x3a,0xc5,0xe2,0xbf,0x3d,0xb6,0x48,0xce,0xed,0xd0,0xb8,0x43,0xb2,0x4e,0xbe +,0x79,0xca,0xde,0x4b,0xbd,0xe2,0xcd,0x3c,0xb7,0xd9,0x78,0xb9,0xd2,0xcc,0x46,0xbc,0xdd,0x4a,0xf7,0xb8,0x68,0x3e,0xbf,0x46,0xcd,0x3f,0xba,0x41,0x44,0xc4,0xe4,0xdf +,0x43,0xce,0x78,0xbd,0x49,0xc8,0x39,0x46,0xc0,0xe5,0x5f,0x3b,0xd2,0x5b,0x5b,0xbd,0x40,0xcf,0x47,0xb9,0x49,0x41,0xdb,0x36,0xb4,0x42,0xd9,0x3f,0xdc,0xc0,0xd9,0x48 +,0xd0,0x74,0x3c,0xca,0x34,0xf7,0xde,0x70,0xc2,0x33,0xc5,0x67,0xde,0x75,0xe6,0x47,0xbd,0xe3,0x67,0xba,0x2d,0xb0,0x2f,0xc7,0xcd,0x47,0xc0,0x7b,0xd0,0xbe,0x59,0xdb +,0xda,0x41,0xb3,0xdc,0x4c,0xb2,0x50,0xb1,0x3d,0x76,0xbf,0x42,0xb9,0x4c,0xba,0x42,0xb2,0x49,0xbe,0x35,0xe5,0xd9,0x30,0xbb,0x3e,0xb6,0x3a,0xd8,0x51,0x45,0xb8,0x38 +,0xe0,0x3a,0xcb,0x42,0xdc,0xd8,0xaf,0xba,0xb6,0xb1,0x1f,0x26,0x0e,0x9f,0x96,0xa7,0xb7,0xbf,0x3c,0x1f,0x1b,0x0e,0x2e,0x34,0xba,0x3b,0xd6,0xa6,0x1f,0x38,0xd8,0xb9 +,0xbf,0x2f,0xa3,0x97,0x8f,0x99,0x5d,0x55,0xb2,0x3e,0x1f,0x2b,0x9a,0x89,0x9c,0x9f,0x3b,0x15,0x3f,0xbf,0x16,0x05,0x0b,0x14,0x37,0xdf,0xab,0x17,0x3d,0x93,0x94,0x9b +,0x43,0x9d,0x96,0x8a,0x97,0x5c,0x1f,0xea,0x91,0x96,0xbd,0x21,0x12,0x06,0x1b,0xa1,0x34,0x0f,0x17,0x2d,0x3f,0x63,0x11,0x0d,0x39,0x92,0x8a,0x95,0x9c,0xaa,0x93,0x98 +,0x9f,0x2d,0x18,0x25,0x75,0x91,0x99,0x32,0x19,0x23,0x18,0x12,0x23,0x2e,0x47,0x15,0x3a,0x9c,0xaf,0x37,0x27,0xbd,0x26,0x9c,0xaf,0xd1,0x97,0x8f,0xa0,0xba,0xb6,0x53 +,0x74,0x1f,0xd1,0x9e,0x96,0x9e,0xaf,0x12,0x16,0xc7,0x40,0x11,0x0b,0x0c,0x30,0xba,0xad,0x27,0x12,0xb2,0x8c,0x95,0x6a,0xaa,0xa9,0x92,0x85,0x98,0x1a,0x1e,0x5e,0x8e +,0x9b,0xfc,0x1d,0x0a,0x0c,0x3f,0xae,0x23,0x15,0x18,0x1d,0xac,0x29,0x0e,0x1a,0x5f,0x89,0x8f,0x97,0xa4,0xa5,0xab,0x8d,0x9b,0x1e,0x0f,0x23,0x98,0x8d,0x99,0x28,0x25 +,0x16,0x1e,0x1c,0x16,0x49,0x25,0x1b,0x6c,0xbc,0xca,0xc8,0x70,0x22,0x59,0xc8,0x2e,0xba,0x98,0x95,0x93,0xa9,0xd6,0x26,0x1b,0x57,0xa1,0x91,0x8f,0xa0,0x21,0x1c,0x33 +,0x4a,0x2c,0x0d,0x09,0x17,0x26,0xc7,0xa3,0x2f,0x1f,0xa6,0x9e,0x96,0xa1,0xbf,0x9f,0x8c,0x8d,0x31,0x22,0x2a,0xab,0x91,0x9d,0x5f,0x12,0x0c,0x12,0x4c,0xb3,0x44,0x1d +,0x10,0x3f,0x5f,0x29,0x17,0x2f,0xa3,0x8e,0x95,0xaa,0xb3,0x9f,0x94,0x99,0xc9,0x16,0x1d,0x28,0x9b,0x94,0xb9,0x25,0x2a,0x22,0x27,0x1c,0x1a,0x29,0x36,0xaf,0x3f,0x2a +,0xa4,0xf1,0x51,0xbf,0x5a,0x32,0x2b,0xb4,0x94,0x94,0xa8,0xd8,0x1f,0x3e,0x29,0xb7,0xaf,0x97,0x8e,0xc9,0x4f,0x2b,0x1d,0x38,0x1d,0x1c,0x15,0x10,0x1c,0x3a,0xa6,0x61 +,0x49,0xb9,0x9d,0xa1,0xb2,0xb7,0x97,0x94,0x99,0xbc,0x2e,0x33,0xac,0x9c,0xa3,0x61,0x12,0x19,0x1a,0x31,0xa5,0x34,0x1a,0x16,0x24,0x2a,0x1e,0x1c,0xac,0xa6,0x91,0x97 +,0xbc,0x98,0xb1,0x8c,0xa0,0x4c,0x22,0x0f,0x33,0xa7,0x9a,0x9e,0x26,0x26,0x45,0x1d,0x17,0x19,0x5e,0xcb,0xca,0x62,0x51,0x4f,0x3c,0xef,0xb7,0x2b,0x1d,0x43,0x9c,0x92 +,0x8c,0x9e,0x36,0x1e,0x26,0x45,0x44,0xae,0x94,0x94,0xb0,0x3d,0x1d,0x1c,0x1a,0x2c,0x33,0x1a,0x0c,0x1c,0x39,0xbf,0xaf,0xc1,0xb1,0xb2,0xa5,0xa4,0xa5,0x9a,0x98,0x9e +,0xad,0x78,0x3e,0xb5,0xa9,0xc1,0x60,0x23,0x16,0x17,0x2c,0xcd,0x4d,0x1e,0x23,0x1b,0x29,0x1e,0x3e,0xa4,0x9d,0x9e,0x9b,0xa5,0x9e,0x9c,0x93,0x98,0x2a,0x25,0x12,0x57 +,0x6f,0xad,0xa9,0xc4,0x31,0x38,0x16,0x16,0x19,0x4b,0xab,0x45,0xb7,0x4f,0xd6,0xc5,0xb0,0xea,0x27,0x1d,0xd4,0x9d,0x8f,0x97,0x9f,0x3e,0x28,0x2d,0x3c,0x3b,0xa4,0x9a +,0x9a,0x9e,0x40,0x17,0x15,0x2a,0x28,0x20,0x17,0x12,0x1b,0x39,0x9e,0xaa,0xaa,0xa9,0x41,0xa4,0xac,0x97,0xa7,0xa0,0x9d,0xbf,0x3b,0xcc,0x43,0xc5,0xbc,0x64,0x6e,0x15 +,0x1f,0x27,0xef,0x2e,0x23,0x1f,0x12,0x18,0x2a,0xc8,0x99,0xac,0x9c,0x9d,0xb1,0x97,0x9d,0x96,0xa4,0x28,0x3e,0x21,0x1e,0xbc,0xd3,0xa5,0xae,0xb8,0x21,0x1a,0x20,0x1a +,0xb6,0x59,0x47,0x55,0x33,0xc4,0x40,0xbf,0x55,0x19,0x2e,0xb6,0x9b,0x99,0x9b,0x9a,0xee,0x2c,0x3d,0x45,0x38,0x9e,0x97,0x99,0xa2,0x29,0x1e,0x26,0x26,0x19,0x23,0x15 +,0x0e,0x29,0x2f,0xab,0xa3,0xb7,0xae,0xcf,0xa7,0xab,0xa6,0x9a,0x9f,0x97,0xc0,0x46,0xae,0x29,0xa4,0xbd,0x3f,0xe1,0x15,0x2a,0x3b,0x34,0x2f,0x27,0x1e,0x12,0x19,0x4a +,0xd6,0xad,0x99,0xb0,0x9d,0x9f,0x9c,0xa1,0x9e,0xa1,0x2b,0xd0,0x17,0x2b,0xc9,0x3f,0x9b,0xab,0x37,0x2e,0x1b,0x1e,0x32,0x3f,0xb9,0x2c,0x3c,0x35,0x6d,0x59,0x3d,0x3c +,0x20,0x69,0xa9,0xa8,0xa1,0x9c,0xa7,0x9d,0x55,0x3e,0x2d,0xfa,0xa6,0xa8,0x96,0xdf,0x3b,0x28,0x2a,0x23,0x23,0x1d,0x0d,0x17,0x20,0x4b,0xc7,0xaf,0xb3,0xa9,0xaf,0xa1 +,0xab,0xd9,0x9a,0x9e,0x95,0xa9,0x46,0xbc,0x2e,0xb3,0xb7,0x2c,0x4f,0x19,0x42,0x2a,0x1e,0xbe,0x17,0x17,0x27,0x16,0xf4,0x44,0x3b,0x99,0xac,0x93,0x99,0x9b,0x9f,0xa0 +,0xa6,0xbc,0x32,0x26,0x2e,0x46,0xb3,0xe4,0xa9,0x31,0x36,0x1f,0x2a,0x33,0x2e,0x37,0x39,0x4f,0x4c,0x2b,0xbc,0x2f,0x1e,0xb7,0xdd,0xa4,0xb0,0x94,0xbc,0x9b,0xa2,0xc6 +,0x60,0x2d,0xb3,0xae,0xb1,0xb6,0xb7,0x34,0x3d,0x25,0x40,0x1c,0x16,0x15,0x18,0x24,0x45,0xe7,0xc7,0xb9,0x9f,0xa8,0xaa,0xaf,0xb3,0x97,0xa0,0x99,0xaa,0xe8,0xcf,0xed +,0x4a,0xb0,0x2e,0x1c,0x4a,0x2b,0x36,0x21,0x37,0x1d,0x12,0x2d,0x28,0x26,0x36,0xad,0xa7,0x9f,0x98,0xa1,0xa0,0x98,0xad,0x9b,0x3f,0x3c,0x2d,0x1e,0xbc,0x32,0xb6,0x57 +,0x2b,0x36,0x39,0x30,0x4b,0x2b,0x68,0x59,0x35,0x3e,0x37,0xde,0x2a,0x37,0xbe,0xc6,0xbe,0xae,0x9f,0x9d,0xa5,0xa5,0xb1,0x4c,0x68,0xb9,0xab,0xd6,0xc4,0xbf,0x2b,0x3f +,0x32,0x3a,0x19,0x13,0x21,0x15,0x26,0x30,0x26,0xa1,0xc8,0xb2,0xa3,0xae,0x9d,0xc5,0x95,0x91,0xaa,0xa4,0xb5,0xb7,0xd9,0x5c,0xc1,0x24,0x28,0x2b,0x2e,0x2a,0x1e,0x2f +,0x1a,0x1e,0x3e,0x20,0x34,0x3d,0xb2,0xa5,0xab,0x9e,0x9a,0x9d,0x9a,0xa4,0xad,0xb7,0x26,0x41,0x25,0xcb,0x6b,0x3c,0x46,0x2d,0x5e,0x2f,0x34,0xc9,0x30,0x42,0xc5,0x2b +,0x3c,0x33,0x38,0x6d,0x22,0xbf,0x3a,0xcd,0x9f,0xcb,0x9a,0xac,0x9d,0xbe,0xce,0xb1,0xc6,0xa4,0x50,0xc4,0xca,0x31,0xb7,0x26,0x38,0x1d,0x1f,0x1d,0x15,0x27,0x2c,0x3c +,0x3f,0xbb,0xb5,0xb2,0xdf,0x9b,0xad,0x97,0x9e,0x9f,0x9c,0xf5,0xae,0xbe,0xb8,0x61,0x25,0x3b,0x2c,0x1f,0x2e,0x1f,0x1e,0x28,0x29,0x28,0x20,0x2c,0xbc,0xe4,0xc4,0x9e +,0xa8,0x9e,0x9d,0xa4,0x9c,0xad,0xc0,0xee,0x3d,0x3e,0xbc,0x4e,0x3e,0x6d,0x40,0x35,0x42,0x2e,0x3d,0x31,0x6c,0x31,0x20,0xaf,0x1f,0x40,0x4d,0x3f,0xcf,0x26,0xac,0xa8 +,0xb4,0xaa,0x9e,0xa3,0xad,0xc1,0xaf,0xb8,0xae,0xc3,0x52,0xa6,0x41,0x55,0x44,0x2d,0x1e,0x1e,0x1a,0x1b,0x1f,0x23,0x38,0x2f,0xc3,0x6d,0xaf,0xb8,0xb1,0x9c,0xa8,0x98 +,0xa9,0x9d,0xa1,0xc3,0xa9,0xe5,0xcd,0x3c,0x29,0x4c,0x29,0x1e,0x2b,0x1e,0x37,0x1a,0x2e,0x31,0x1e,0xbc,0x58,0xa8,0xa8,0xaf,0x9a,0x9e,0xac,0xa7,0xae,0xed,0xc7,0xfd +,0x3c,0xcb,0x6c,0x6b,0xc2,0x3b,0x45,0x46,0x3b,0x34,0xdf,0x2d,0x25,0x42,0x25,0x3c,0x2b,0x44,0x3d,0x48,0x36,0xbf,0xa3,0xb5,0xa6,0xa1,0x9d,0xae,0xcc,0xb2,0xa7,0xd3 +,0xad,0xc8,0x75,0xc7,0x31,0xfa,0x25,0x1e,0x29,0x1b,0x1d,0x2d,0x1e,0x27,0xdd,0x36,0xbe,0xd9,0xae,0xa3,0xa5,0xa1,0xa0,0x9d,0xa4,0xa0,0xa1,0xaf,0xc0,0xd1,0x3c,0x31 +,0x35,0x27,0x28,0x1e,0x1f,0x1d,0x1c,0x25,0x1d,0x3d,0x36,0x47,0xa9,0xa7,0xc8,0x9b,0x9b,0xa5,0xac,0xae,0xa8,0xc2,0xb6,0x5b,0xbc,0xcc,0x3a,0xdd,0x52,0x46,0x4e,0x37 +,0x62,0x4e,0x1e,0x35,0x2d,0x23,0x2f,0x2a,0x46,0x24,0xd3,0x5c,0xda,0xab,0xaf,0xa6,0xa2,0xb2,0xa7,0xa4,0xaf,0xac,0xb7,0x9f,0x3a,0xe3,0xc3,0x35,0x3a,0x2a,0x29,0x1f +,0x1d,0x20,0x21,0x29,0x32,0x3b,0x40,0x79,0xc3,0xb5,0xae,0xa8,0x9d,0xa2,0x9c,0xa4,0xa9,0xa6,0xad,0xbf,0xb7,0x31,0x46,0xed,0x1c,0x37,0x21,0x1e,0x24,0x1e,0x22,0x1f +,0x29,0x46,0x3d,0xee,0xa5,0xa7,0xa4,0xa7,0x9e,0x9e,0xca,0xaa,0xaf,0xc1,0xb5,0x32,0xb5,0x5b,0x41,0x4c,0x3d,0xdc,0x2c,0x37,0x2f,0x2d,0x40,0x2e,0x2d,0x3c,0x3f,0x38 +,0x2c,0x37,0x4b,0xb1,0xc7,0xb6,0xa7,0xa8,0xad,0xad,0xa3,0xb0,0xad,0xa4,0xb7,0xb2,0xca,0x3f,0xc1,0x2c,0x32,0x2c,0x1f,0x1d,0x1c,0x2a,0x21,0x1f,0x33,0x3d,0x47,0xc3 +,0xcb,0xa7,0xa5,0xa9,0x97,0xab,0x9e,0x9a,0xac,0xa6,0xaf,0xba,0xba,0x3f,0x37,0x2d,0x2f,0x29,0x1a,0x22,0x1a,0x2f,0x1c,0x29,0x42,0x52,0xb4,0xd7,0xb4,0xac,0xa6,0xaf +,0xa1,0xb8,0xa6,0xab,0xba,0xb3,0xc0,0xcf,0xed,0x54,0x44,0x47,0x31,0x35,0x38,0x2c,0x2a,0x35,0x22,0x2c,0x2c,0x3f,0x3c,0x37,0x59,0x76,0xaa,0x68,0xa8,0xaa,0xae,0xad +,0xa7,0xb4,0xa8,0xa8,0xc8,0xa8,0x47,0xb4,0xdb,0x39,0x3f,0x30,0x1f,0x29,0x25,0x1e,0x24,0x1e,0x3b,0x29,0x31,0xbd,0x45,0xac,0xae,0xad,0x9d,0x9f,0xa3,0x9f,0xae,0xa9 +,0xa3,0x57,0xc3,0x3c,0x4d,0x38,0x29,0x30,0x24,0x24,0x25,0x22,0x26,0x21,0x3e,0x45,0xcb,0xbc,0xae,0xb0,0xb4,0xad,0xab,0xa1,0xb8,0xa9,0xb3,0xbf,0x4f,0xc6,0x76,0x5c +,0x56,0x42,0x4d,0x5d,0x42,0x39,0x33,0x28,0x4a,0x2c,0x2d,0x41,0x2f,0x54,0x3f,0xdb,0xb2,0x6d,0xc2,0xb0,0xae,0xc3,0xb6,0xad,0xb0,0xb2,0xb9,0xb5,0xcf,0xce,0xee,0xd1 +,0x4f,0x3d,0x2c,0x2d,0x2b,0x20,0x2d,0x25,0x47,0x24,0x37,0x4f,0xdf,0xdd,0xba,0xa6,0xb7,0x9c,0xad,0xa2,0xaa,0xae,0xa6,0xb5,0xcf,0x54,0xd5,0x3f,0x34,0x2d,0x2e,0x2c +,0x20,0x34,0x1f,0x33,0x39,0x37,0xdc,0x56,0xc3,0xd0,0xbd,0xb5,0xa6,0xc2,0xa3,0xb7,0xbe,0xb0,0xcc,0xc3,0x56,0xc4,0xe9,0x42,0x44,0x5b,0x4e,0x43,0x2c,0x34,0x3e,0x2c +,0x48,0x34,0x3d,0x46,0x3d,0xc5,0x55,0xb5,0xbf,0xc1,0xbf,0xad,0xb2,0xbe,0xb9,0xb2,0xa5,0x43,0xb6,0xc9,0xd4,0xd6,0x3f,0xce,0x2c,0x37,0x2a,0x2b,0x3b,0x2a,0x2e,0x3e +,0x3b,0x48,0xcc,0x4b,0xad,0xbb,0xb8,0xac,0xb0,0xa7,0xb3,0xac,0xc0,0xae,0xd8,0x70,0x43,0x3a,0x41,0x2c,0x4b,0x2b,0x32,0x2c,0x2c,0x3e,0x3c,0x48,0x69,0xce,0xdd,0xc1 +,0x5d,0xb0,0xad,0xcd,0xa9,0xc0,0xb8,0xbe,0xbb,0xbe,0x5e,0x62,0x5d,0xe2,0x39,0x59,0x3a,0xde,0x48,0x33,0x3c,0x35,0x3c,0x36,0x3b,0x38,0xfe,0x39,0xca,0xc8,0xd1,0xb7 +,0xdc,0xab,0xcd,0xbc,0xbc,0xaf,0xb3,0xb5,0xbb,0x5d,0xbb,0x44,0xcd,0x4e,0x37,0x42,0x2e,0x2e,0x39,0x2e,0x2e,0x3e,0x3b,0x4b,0x4a,0x3e,0xca,0xbd,0xb4,0xae,0xab,0xaa +,0xb8,0xaf,0xb4,0xb8,0xc7,0xc8,0x46,0x4f,0x4e,0x44,0x45,0x31,0x41,0x29,0x31,0x3a,0x4b,0x39,0x41,0xe9,0x42,0xd0,0x4d,0xba,0xd8,0xae,0xb4,0xca,0xb4,0xc7,0xbb,0xdb +,0xb3,0xc8,0xce,0x4f,0x56,0xfa,0x33,0xf9,0x4b,0x39,0x3d,0x3f,0x43,0x42,0x3f,0x36,0x3d,0x39,0x5a,0x4d,0xd7,0xbd,0xc8,0xba,0xbc,0xb4,0xba,0xbd,0xba,0xb0,0xc0,0x7c +,0xc8,0x49,0x57,0x71,0x59,0x3d,0x3a,0x2c,0x2d,0x3b,0x2b,0x5a,0x32,0x58,0x69,0x44,0xc5,0xc7,0xb2,0xb8,0xaf,0xb1,0xac,0xbc,0xad,0xc5,0xcf,0xc0,0x43,0xdc,0x37,0x48 +,0x3e,0x3c,0x39,0x36,0x36,0x31,0x4e,0x3f,0xe8,0x42,0x6a,0xda,0xfc,0xca,0xbf,0xb7,0xbf,0xb4,0xd6,0xb0,0xdd,0xcf,0xbc,0x4b,0xba,0x61,0x5e,0x6c,0x52,0x50,0x4c,0x4e +,0x3c,0x50,0x2e,0x4f,0x3f,0x40,0xef,0x38,0xcf,0x3f,0xe4,0xde,0xd6,0xbe,0xb6,0xd1,0xb8,0xaf,0xda,0xb6,0xce,0xb2,0xd9,0xd6,0x71,0x51,0x53,0x35,0x7b,0x30,0x42,0x2e +,0x3f,0x3e,0x38,0x4f,0x3e,0xd3,0x54,0xbd,0xd6,0xb5,0xbb,0xb0,0xaf,0xc9,0xb0,0x6a,0xdc,0xcd,0xe2,0xe3,0x53,0x4c,0x47,0x56,0x36,0x3d,0x38,0x3d,0x41,0x3b,0x68,0x3e +,0x74,0x5c,0xc9,0xed,0xc8,0xc9,0xbe,0xb2,0xde,0xb8,0xea,0xc0,0xd2,0xee,0xc7,0xf6,0xeb,0x45,0xdc,0x3f,0xe2,0x3d,0x4f,0x53,0x3a,0x67,0x2e,0x5e,0x3d,0x53,0x59,0xf4 +,0x59,0xde,0xcd,0xce,0xb4,0xd2,0xbf,0xb8,0xbb,0xd3,0xbe,0xd2,0xc8,0xbd,0x47,0x6d,0x41,0x3c,0x46,0x33,0x48,0x3b,0x37,0x4c,0x41,0x43,0xea,0x48,0xcf,0xcd,0x7d,0xbf +,0xc1,0xaf,0xb0,0xc6,0xb3,0xbc,0xdf,0xc4,0xc9,0xe5,0x5e,0x49,0x52,0x3a,0x3a,0x3e,0x2d,0x76,0x3c,0x44,0x4b,0x49,0xf5,0x7c,0xcf,0xcf,0xd6,0xe9,0xc0,0xcd,0xbd,0xf0 +,0xc7,0xdb,0xc1,0xc7,0xdb,0xc3,0x72,0xbf,0x51,0xcb,0x4d,0x3b,0x4e,0x38,0x5c,0x3b,0x49,0x3f,0x60,0x70,0x4d,0xda,0x3d,0xea,0x61,0xe7,0xba,0xc2,0xcf,0xbe,0xba,0xe3 +,0xbf,0xc6,0xc1,0xc1,0x5f,0xbc,0x49,0x4a,0x51,0x3b,0x3d,0x37,0x38,0x42,0x3a,0x3b,0xcd,0x43,0xcf,0x5e,0xdc,0xc3,0xd3,0xb9,0xb9,0xc4,0xc2,0xba,0xcf,0xc0,0xe5,0xe1 +,0x61,0x56,0xdb,0x48,0x3f,0x46,0x3c,0x3e,0x57,0x43,0x45,0x4c,0x4b,0xd0,0x5f,0xdc,0xea,0xe8,0xcf,0xc5,0xbb,0xd0,0xc8,0xcf,0xc4,0xdc,0xe2,0xc7,0xdf,0xcf,0xc1,0x6c +,0x5a,0x46,0x4a,0x51,0x31,0xed,0x58,0x31,0x59,0x44,0x63,0x54,0x51,0xda,0x4e,0xdf,0xc5,0xc2,0xd0,0xc6,0xc4,0xbb,0xc3,0xc1,0xcc,0xd7,0xbd,0xc8,0xe1,0x47,0x77,0x3a +,0x3c,0x3b,0x3c,0x48,0x2f,0x65,0x3d,0x49,0x5a,0x6d,0xd3,0x7a,0xbf,0xc4,0xb8,0xcf,0xb6,0xd8,0xbf,0xbc,0x68,0xc6,0x53,0xd0,0x5e,0x5f,0x3e,0x4f,0x47,0x3b,0x4b,0x3e +,0x4a,0x43,0x5f,0x75,0xe6,0xdc,0x5e,0xcf,0xe8,0xc5,0xcc,0xc6,0xc7,0xdd,0xcd,0x60,0xc0,0xde,0xce,0xd2,0xcb,0x5d,0xd0,0x53,0x4e,0x6c,0x35,0xf2,0x39,0x61,0x45,0x3e +,0xf8,0xf2,0xfe,0x4a,0xda,0x54,0xbc,0x4e,0xbf,0xc5,0x5a,0xb8,0x57,0xb9,0xeb,0xc8,0xd0,0xc8,0xc8,0xde,0xcc,0x41,0x54,0x30,0x43,0x39,0x3a,0x51,0x3a,0xd2,0x50,0x6c +,0x48,0x5e,0xe4,0xc2,0xbe,0xc1,0xbc,0xcf,0xbb,0xe1,0xc9,0x5b,0xc6,0xf0,0x5d,0xcd,0x4c,0xdf,0x3f,0x4c,0x44,0x47,0x54,0x46,0xed,0x45,0xfa,0x64,0xd8,0x46,0x5f,0xd5 +,0xdc,0xbb,0xe4,0xc0,0xcb,0xcc,0x52,0xcb,0xd9,0xe0,0xf5,0x5b,0xbb,0x4f,0xdf,0x48,0x59,0xf2,0x5b,0xf3,0x36,0xf2,0x3f,0x4c,0x54,0x66,0x3f,0x4f,0xd5,0xcf,0xc7,0x51 +,0xb7,0xd4,0xbb,0x5d,0x4e,0xca,0xd5,0xb9,0xcb,0xd4,0xd2,0x79,0x3d,0x51,0x47,0x5a,0x54,0x31,0xf6,0x37,0x4e,0x5c,0x5e,0xc5,0x48,0xcc,0x6b,0xca,0x6d,0xb6,0xbc,0xc6 +,0xbd,0x49,0xca,0x49,0xfa,0x4e,0xcf,0x64,0x66,0x66,0x51,0xd9,0x33,0x63,0x46,0xd6,0x43,0xc9,0xb7,0x4b,0xd9,0x43,0xd0,0x47,0xcf,0xc7,0xd2,0xb8,0xe2,0xce,0x3e,0xdb +,0xd1,0x49,0x4d,0xcb,0xd2,0x40,0x4f,0x3d,0xd2,0x48,0x64,0x5e,0x5b,0xd2,0x43,0xd2,0x4b,0xfd,0x6d,0xd8,0x7c,0x73,0xca,0xd7,0xbe,0xdb,0xb8,0x6e,0xc9,0x6f,0x6f,0x6c +,0x42,0xbc,0x57,0x6b,0x45,0x6d,0x59,0x56,0xeb,0x43,0x3f,0x4a,0xf4,0x44,0xef,0xdd,0xbc,0xc0,0xe8,0xbe,0x46,0xbd,0x61,0x38,0xd6,0x79,0xba,0x5f,0xb2,0xce,0x38,0x44 +,0x46,0x69,0x43,0x4a,0xcf,0xb2,0x3e,0xcb,0x35,0x46,0xdd,0x3d,0xc1,0xdd,0xae,0xc1,0x4e,0x44,0x3c,0x4d,0xc7,0xc0,0xc7,0xcc,0xe9,0xea,0x3e,0x3d,0xeb,0xce,0xc1,0xe6 +,0xbf,0x3a,0x3c,0x3f,0x4c,0xbd,0x65,0x54,0x4a,0xbe,0xe7,0x62,0x50,0xcd,0xbb,0x3d,0xc9,0xcf,0xf4,0x64,0x5e,0xc1,0x5c,0xc1,0xe4,0x7d,0x63,0x57,0x44,0x53,0x45,0xc3 +,0x44,0x4b,0xc9,0x2b,0xba,0x4c,0xb4,0xee,0x46,0xa8,0x6a,0xbb,0x3a,0xe8,0x41,0x49,0xc9,0x45,0xbf,0xba,0xce,0x67,0xd6,0x2f,0x5c,0x49,0xba,0x5a,0x3d,0xaf,0x41,0xf1 +,0x6d,0x44,0xc7,0x45,0xe2,0xc7,0x3f,0xde,0xbb,0x47,0xc0,0xb7,0xda,0x4b,0x2a,0xce,0x5e,0xb9,0xf8,0x4f,0xbd,0x58,0x54,0x33,0xd3,0xc3,0xb6,0x5d,0x4c,0xd7,0x54,0x51 +,0x3b,0xc5,0x47,0xb8,0x4a,0xef,0x71,0x33,0xb9,0x3d,0xb9,0xbd,0xe6,0xcf,0x6c,0xce,0x58,0x37,0xce,0xc3,0x40,0xce,0x4c,0x62,0xe0,0x32,0xd1,0x6f,0xec,0x45,0xde,0xd3 +,0xe1,0x37,0xe9,0xd4,0x38,0xac,0x38,0xc3,0xad,0x3d,0x47,0xd1,0xad,0xd7,0x3f,0xb4,0xbe,0x53,0x3f,0x5e,0x67,0x4a,0x38,0x4f,0x3c,0xc4,0x26,0xbc,0xc1,0x22,0xed,0x39 +,0xb7,0xeb,0x2a,0x99,0x99,0x57,0xdf,0x22,0xaa,0xcd,0x9d,0x2a,0x42,0x1e,0x03,0x0a,0x05,0xaf,0x2c,0x45,0x34,0x34,0x87,0x93,0x9c,0xa3,0x9d,0xa9,0xa7,0x86,0xa0,0xf4 +,0x8c,0x3b,0xd6,0x9e,0x1d,0x8a,0x86,0x8a,0x8d,0x8f,0x40,0x18,0x0f,0x02,0x06,0x00,0x02,0x00,0x07,0x02,0x06,0x01,0x06,0x05,0x0b,0x12,0x16,0xd3,0xa2,0x8e,0x95,0x8a +,0x8f,0x8e,0x9a,0x8d,0x95,0xa8,0x9b,0x9b,0x8e,0x8b,0x86,0x83,0x83,0x80,0x85,0x80,0x8c,0x87,0x8c,0x18,0x97,0x80,0x8b,0x05,0x2a,0x0d,0x04,0x08,0x00,0x05,0x02,0x00 +,0x05,0xbf,0x0e,0x0c,0x00,0x0e,0x2d,0x00,0x04,0x00,0x2e,0x2f,0xa1,0x98,0x1f,0x08,0x14,0x9f,0x8d,0x8a,0x8e,0x8a,0x25,0x93,0x84,0x80,0x81,0x80,0x87,0x82,0x94,0x99 +,0x87,0x97,0x98,0xa7,0x8a,0xae,0xa6,0xb2,0x21,0x0d,0x0e,0x0a,0x15,0x18,0x07,0x05,0x28,0x0e,0x1b,0x2a,0x06,0x0a,0x00,0x04,0x0f,0x28,0x0b,0x07,0x1e,0x29,0x27,0x19 +,0x18,0x3e,0x0c,0x51,0x9d,0x3e,0xa0,0x83,0x85,0x92,0x8b,0x85,0x86,0x3b,0x9a,0x80,0x93,0x8e,0x86,0x80,0x8a,0x8d,0x8e,0x4e,0x87,0x0d,0x0b,0xa4,0x12,0x24,0x1e,0xb1 +,0xb7,0x04,0x09,0x05,0x00,0x06,0x26,0xbb,0x6c,0x22,0x13,0x00,0x04,0x0b,0x13,0x0c,0x0b,0xad,0x14,0x39,0x84,0x86,0x80,0x81,0x80,0x97,0x13,0x94,0x89,0x8a,0x87,0x85 +,0x86,0x8c,0x9c,0x75,0xb5,0xa2,0x1a,0x04,0x23,0x22,0x21,0x83,0x88,0x8f,0x8d,0x3c,0x1e,0x02,0x16,0x95,0x01,0x15,0xbb,0xac,0x9a,0x05,0x08,0x01,0xa0,0x1d,0x12,0xa0 +,0x00,0x0c,0x8a,0x80,0x98,0x87,0xa2,0x06,0x16,0x8e,0x1d,0x09,0x80,0x54,0x54,0x16,0x03,0x84,0x38,0x0a,0x07,0x00,0x1d,0xb3,0x93,0x86,0xc7,0x27,0x17,0x10,0x14,0x15 +,0xac,0x2b,0x8c,0x9f,0x18,0xa3,0xa5,0x50,0x25,0x15,0x06,0x07,0x00,0x18,0x3e,0x94,0x8b,0xa3,0x84,0x9d,0x8a,0x8c,0x56,0x80,0x88,0x80,0x80,0x80,0x82,0x80,0x85,0x9f +,0x37,0x8d,0x80,0xd1,0xcf,0x18,0x81,0x9d,0x9b,0x8f,0x9f,0x1c,0x03,0x10,0x8d,0x85,0x09,0x34,0x16,0x93,0x07,0x0f,0x9a,0x00,0x04,0x00,0x08,0x03,0x06,0xaf,0x02,0x07 +,0x0a,0x08,0x0a,0x0f,0x0d,0x00,0x0d,0x18,0x8f,0x2f,0x95,0xe4,0x01,0x0e,0x00,0xa5,0x92,0x2d,0xa6,0x08,0x8a,0x80,0x86,0x80,0x83,0x80,0x17,0x3f,0x80,0x85,0x81,0x8b +,0x90,0x80,0x88,0xa0,0x13,0x1a,0x8e,0x92,0x03,0x0c,0x02,0xaf,0xa3,0x09,0x92,0x04,0x0d,0x05,0x02,0x36,0x08,0x03,0x11,0x0f,0x08,0x03,0x07,0x2d,0x0e,0x0a,0x0d,0xa6 +,0x8b,0x90,0x84,0x83,0x87,0x80,0x80,0x80,0x84,0x4c,0x87,0x80,0x82,0x80,0x98,0x83,0xa0,0xa1,0x8a,0x4e,0x22,0x0d,0x0e,0x04,0x07,0x9e,0x2e,0x03,0x0b,0x10,0x09,0x05 +,0x00,0x05,0x17,0x03,0x03,0x00,0x13,0x05,0x00,0x01,0x06,0x01,0x06,0x00,0x0c,0x0c,0x1b,0x8a,0x02,0x8d,0x9b,0xbb,0x14,0x0f,0x8d,0x8c,0x8b,0x8e,0x80,0x88,0x88,0x8e +,0x86,0x83,0x82,0x83,0x88,0x8c,0x8e,0x89,0x80,0x84,0x80,0x87,0x8b,0x8c,0x0b,0x1f,0x91,0x9f,0x82,0x99,0x3e,0xb9,0x04,0x4f,0x5a,0x2c,0x0e,0x03,0x0d,0x03,0x07,0x95 +,0x1a,0x01,0x98,0x0d,0x00,0x02,0x00,0x26,0x0a,0x2f,0x2d,0x08,0xbd,0x18,0x12,0x05,0x0c,0x90,0x07,0x08,0x14,0x0a,0x83,0x8f,0xaa,0x80,0xa0,0xd0,0xd2,0x24,0x80,0xa7 +,0x88,0x80,0x82,0x80,0xb2,0x9d,0xa8,0x38,0x2c,0x1e,0x0b,0x95,0x0d,0x8a,0xa6,0x15,0x85,0xa8,0x0b,0x00,0x0c,0x99,0x1d,0x2c,0x92,0x0f,0xbf,0x05,0x0f,0x0f,0x04,0x06 +,0x08,0x00,0x08,0x06,0x33,0x81,0x9c,0x82,0x9a,0x8f,0xad,0x4d,0x81,0x81,0x80,0x80,0x81,0x81,0x82,0x86,0x80,0x83,0x81,0x94,0x09,0xa2,0x4d,0x8e,0x80,0x3c,0x9d,0x5a +,0x09,0x05,0x00,0x0c,0x1b,0x00,0x48,0x0e,0x00,0x00,0x01,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x04,0x8c,0x0a,0x0f,0x1f,0x00,0x0c,0x00,0x1e,0xbe,0xad,0x9a,0x9f,0x97 +,0x8f,0x1c,0x8d,0x9e,0x96,0x8c,0x15,0x8f,0x8f,0x88,0x80,0x83,0x81,0x80,0x81,0x87,0x87,0x8c,0x80,0x88,0x81,0x81,0x9a,0x88,0xb9,0xb3,0x8c,0x13,0x0e,0x0a,0x07,0x16 +,0x07,0x83,0x28,0x2f,0x9a,0x01,0x09,0x00,0x05,0x10,0x14,0x1e,0x26,0x0c,0x0b,0x1b,0x25,0x0d,0x2c,0x14,0x00,0x05,0x0c,0x20,0x85,0x86,0xa7,0x8f,0xf6,0x31,0x1c,0x0f +,0x9c,0x9e,0x93,0x92,0xa3,0xb8,0x1e,0x9c,0x50,0x0b,0xd0,0x14,0x0c,0x09,0x0b,0x82,0x8b,0xb9,0x92,0xa8,0x05,0x02,0x09,0xa3,0x31,0x77,0x92,0x1e,0x84,0x50,0xaf,0x86 +,0xb4,0x2f,0x2a,0x0a,0x1c,0x1c,0x9c,0x80,0x1b,0x91,0x1d,0x11,0x19,0x06,0x2e,0x96,0x9b,0x97,0x9c,0xa6,0x84,0x9a,0x89,0xa3,0x96,0x87,0xa8,0x98,0x9d,0x87,0x80,0x86 +,0x85,0x80,0x92,0x93,0x9d,0x87,0x84,0x9f,0x84,0x8a,0x82,0x24,0x0c,0x0f,0x03,0x02,0x02,0x00,0x01,0x00,0x05,0xac,0x08,0x02,0x03,0x08,0x03,0x00,0x05,0x10,0x06,0x18 +,0x12,0x08,0x10,0x0e,0x0c,0x0f,0x1d,0x09,0x09,0x15,0x2c,0x4c,0x82,0x85,0x8b,0x80,0x91,0x9b,0x8e,0x91,0x82,0x83,0x80,0x83,0x85,0x8c,0x86,0x8b,0x96,0x8e,0xba,0x09 +,0x0d,0x17,0x11,0x84,0x8e,0x2c,0x8d,0xaa,0x0a,0x16,0xa8,0x8a,0x48,0x83,0x9d,0x95,0x8c,0xca,0x5b,0x47,0xcc,0x05,0x13,0x04,0x13,0x0d,0x8e,0x8a,0x16,0xc6,0xb5,0x18 +,0x1e,0x0f,0x27,0x4b,0xa4,0x9e,0x2b,0x1e,0x19,0x11,0x06,0x12,0x01,0x03,0x00,0x06,0x00,0xa9,0x99,0x20,0x9e,0x54,0x18,0x0b,0x07,0xfd,0xc5,0xcd,0x96,0xa2,0xa7,0x3e +,0x98,0x2e,0x27,0xed,0x1f,0x0e,0x3e,0xcf,0x8c,0x80,0x89,0x88,0x8a,0x93,0x34,0x16,0xa2,0x9d,0x27,0xa2,0xa4,0xba,0xbc,0x3a,0x16,0x1d,0x1a,0x0a,0x0c,0x35,0x0d,0xa0 +,0x80,0xa2,0x8b,0x87,0x96,0x9a,0x1c,0x99,0x85,0x87,0x80,0x83,0x82,0x88,0x8b,0x88,0x8a,0x8f,0x95,0x1d,0xb0,0x1e,0xb7,0x80,0xbd,0x27,0x6a,0x02,0x03,0x00,0x05,0x0e +,0x05,0x0e,0x0c,0x0a,0x05,0x09,0x09,0x05,0x05,0x03,0x00,0x03,0x00,0x18,0x8a,0x1b,0x14,0x23,0x0c,0x0c,0x00,0x19,0x8f,0xaf,0x8f,0x8e,0x92,0x89,0x9f,0x88,0xa1,0xa5 +,0x98,0x16,0xad,0x2b,0xa5,0x80,0x94,0x97,0x86,0xc7,0x91,0x3a,0xa0,0x80,0x8e,0x81,0x82,0x80,0x84,0x89,0x8b,0x8d,0x97,0x97,0x18,0x2a,0x1f,0xc2,0x80,0x37,0x24,0xa4 +,0x1a,0x12,0x08,0x0b,0xa3,0x12,0xa2,0xb2,0xa8,0x62,0x08,0x25,0x0d,0x09,0x0f,0x02,0x05,0x02,0x0d,0x8a,0x1c,0x20,0xa1,0x11,0x09,0x05,0x0f,0x9b,0x2a,0xac,0x92,0xad +,0x2c,0x0a,0x1f,0x36,0x0c,0x09,0x03,0x05,0x03,0x1d,0x83,0x56,0xc1,0xa2,0x25,0x1e,0x0d,0xb8,0x86,0x94,0x8e,0x86,0x88,0x8f,0xa5,0x9b,0x94,0xea,0x2a,0x09,0x0d,0x12 +,0xab,0x80,0x9f,0xac,0x96,0x61,0x23,0x15,0xb4,0x8e,0x3a,0xa4,0x98,0x97,0x5b,0x37,0xa1,0xa3,0x2f,0x1c,0x3b,0xb2,0x99,0x88,0x80,0x85,0x80,0x81,0x80,0x8a,0x92,0x83 +,0x82,0x89,0x87,0x88,0x8e,0xaf,0x0b,0x09,0x0e,0x00,0x03,0x00,0x03,0x00,0x0f,0xcd,0x05,0x09,0x07,0x04,0x02,0x00,0x09,0x0c,0x07,0x0e,0x13,0x11,0x05,0x05,0x0d,0x1c +,0x0c,0x06,0x09,0x0d,0x0f,0x8e,0x80,0x95,0x87,0x8c,0x95,0x6b,0x37,0x87,0x88,0x90,0x8d,0x8c,0x8a,0x96,0x9e,0x8d,0x8d,0x93,0xba,0x9e,0x8f,0x97,0x80,0x82,0x85,0x85 +,0x8a,0x8b,0xcd,0x21,0x8e,0x93,0x98,0x93,0x97,0x96,0x63,0x17,0xd5,0x4e,0x1d,0x0b,0x10,0x19,0x04,0x88,0x8c,0xda,0x68,0x13,0x10,0x02,0x02,0x4b,0x22,0x1d,0x1e,0x27 +,0x20,0x09,0x0c,0x1c,0x21,0x0d,0x03,0x05,0x0b,0x05,0x86,0xa2,0x18,0x63,0x0a,0x0a,0x00,0x06,0x5a,0x2f,0x6e,0xb6,0xd5,0x9f,0x2e,0xe5,0x98,0xb7,0x35,0x10,0x3d,0xeb +,0x2b,0x80,0x89,0x91,0x97,0xe1,0xaf,0x13,0x2a,0x85,0x92,0x8b,0x8d,0x8b,0x8b,0xb3,0xca,0x9f,0x56,0x1a,0x07,0x0a,0x0e,0x10,0x82,0xa8,0xac,0x9a,0x29,0xb5,0x0d,0x22 +,0x87,0x90,0x87,0x84,0x82,0x83,0x90,0x8d,0x83,0x8d,0xa9,0x3b,0xa2,0xa9,0x9c,0x80,0x93,0x99,0xa8,0x1a,0x0c,0x00,0x0a,0x29,0x0d,0x1f,0x26,0x11,0x07,0x02,0x04,0x08 +,0x03,0x04,0x00,0x07,0x08,0x23,0x87,0x1b,0xeb,0xe0,0x1e,0x28,0x09,0xc2,0x86,0x8f,0x8a,0x95,0xa8,0x4b,0x10,0x15,0xec,0x19,0x0f,0x08,0x10,0x0c,0x58,0x85,0x2b,0x9d +,0xa5,0xbd,0x37,0x0d,0x96,0x83,0x8f,0x8c,0x8f,0x9b,0x4d,0x1c,0xad,0x95,0xbb,0x73,0x23,0x28,0x0f,0x94,0x87,0x26,0x9c,0xb9,0xf6,0x1c,0x0d,0x8e,0x8f,0x9d,0x8b,0x91 +,0x9c,0xc2,0xbf,0x91,0x8d,0x92,0xa3,0x15,0x1a,0x0d,0x8d,0x93,0x28,0x91,0x4c,0x35,0x0f,0x06,0xb7,0x3a,0x2d,0x41,0x1c,0x27,0x0a,0x09,0x2c,0x3b,0x16,0x07,0x04,0x07 +,0x06,0x88,0x96,0xbc,0x8b,0xa4,0xb8,0x08,0x09,0x9b,0x38,0x37,0xac,0x38,0x2e,0x09,0x0f,0x26,0x10,0x0d,0x04,0x08,0x08,0x16,0x81,0x9a,0x95,0x87,0xa3,0xac,0x09,0x1c +,0x88,0x92,0x87,0x87,0x88,0x8c,0x36,0xae,0x9e,0xd8,0xc8,0x15,0x2d,0x1b,0xaf,0x80,0x9f,0x8a,0x87,0x98,0xa5,0x17,0x9d,0x80,0x87,0x80,0x85,0x85,0x8e,0x3f,0xb3,0xc1 +,0xf5,0xe1,0x0e,0x2f,0x0d,0x6a,0x8d,0x0e,0xda,0x11,0x0a,0x0e,0x00,0x23,0xa4,0x2d,0xbe,0x38,0x57,0x13,0x02,0x1b,0x1f,0x40,0xc3,0xb9,0x9f,0x23,0x88,0x88,0x29,0x99 +,0xe0,0x2a,0x0c,0x01,0x28,0x11,0x03,0x06,0x03,0x03,0x01,0x00,0x03,0x04,0x09,0x04,0x01,0x09,0x08,0x8b,0xad,0x25,0x87,0x9d,0x90,0xaa,0x56,0x88,0x8a,0x88,0x84,0x89 +,0x82,0x91,0x96,0x8a,0x92,0x9a,0x2d,0xae,0x9c,0x9b,0x80,0x89,0x87,0x80,0x86,0x82,0x9c,0x9f,0x80,0x87,0x85,0x87,0x89,0x8b,0xf0,0x47,0xbf,0x0d,0x0b,0x01,0x07,0x00 +,0x0c,0x9b,0x08,0x0d,0x13,0x06,0x04,0x00,0x07,0x1d,0x0b,0x1c,0xc3,0x8f,0x88,0x94,0x8b,0x85,0x8c,0x8d,0xb9,0xb7,0xbb,0x8b,0x81,0xb0,0x96,0x2e,0x0b,0x01,0x00,0x02 +,0x03,0x04,0x0a,0x10,0x2b,0x1a,0x02,0x08,0x0a,0x0b,0x03,0x02,0x0f,0x10,0x8d,0x84,0xa9,0x8c,0xaa,0xa8,0x4d,0x0d,0x97,0x8a,0x8a,0x86,0x86,0x83,0x99,0x33,0xa1,0xc3 +,0xd7,0x2f,0x4a,0xa9,0xa5,0x80,0x84,0x8c,0x84,0x89,0x8b,0xac,0x18,0x88,0x8b,0x8a,0x8c,0x99,0x8c,0x3d,0x0b,0x0c,0x08,0x09,0x03,0x01,0x09,0x05,0x9c,0x22,0x11,0x27 +,0x0e,0x29,0x1e,0x1b,0x8b,0x84,0x83,0x81,0x82,0x80,0x8c,0x93,0x8b,0x8f,0x9f,0x17,0x0a,0x09,0x05,0xba,0x0a,0x03,0x0b,0x05,0x09,0x01,0x02,0x0c,0x0b,0x0d,0x0d,0x14 +,0x68,0x13,0x0d,0x2a,0x1c,0x14,0x04,0x08,0x08,0x11,0x88,0x97,0x99,0x8c,0x8f,0x91,0x19,0x0e,0xa9,0xa3,0x9e,0x9c,0x8c,0x83,0x8e,0x9c,0x99,0x95,0x95,0x79,0x64,0xbb +,0x90,0x80,0x85,0x85,0x84,0x89,0x8e,0x1a,0x0f,0xb3,0xb3,0x9d,0x2e,0x48,0x97,0x1f,0x08,0x08,0x08,0x0c,0x00,0x05,0x05,0x19,0x85,0x88,0x8c,0x89,0x86,0x80,0x8d,0xa4 +,0x84,0x82,0x80,0x81,0x86,0x89,0xa9,0x17,0x0d,0x02,0x02,0x00,0x01,0x00,0x04,0x21,0x0d,0x06,0x0a,0x14,0x0f,0x05,0x06,0x1d,0x73,0x99,0xac,0x5e,0xb3,0x41,0x1e,0x15 +,0x0e,0x16,0x18,0x1a,0x10,0x20,0x8f,0xa3,0xbb,0xff,0xb1,0x97,0xbb,0x2c,0x9f,0x8b,0x84,0x8c,0x93,0x8a,0x93,0x9d,0x8f,0x92,0x8f,0x92,0x93,0xbe,0x28,0x8d,0x8e,0xa3 +,0xba,0xb7,0xa5,0x7b,0x1a,0x19,0x0e,0x21,0xdd,0x0f,0x0a,0x0c,0x18,0x53,0x32,0x9e,0x91,0xa5,0x9f,0x99,0x86,0x82,0x82,0x80,0x80,0x83,0x81,0x8d,0xae,0x51,0x30,0x35 +,0x0b,0x04,0x05,0x02,0x04,0x05,0x03,0x02,0x02,0x01,0x01,0x00,0x0b,0x19,0x20,0x43,0x1c,0x1e,0x33,0x19,0x1d,0x1c,0xdf,0x95,0xb7,0xc7,0x9c,0x9b,0x99,0x9f,0xce,0x47 +,0x1d,0x22,0x34,0x49,0x97,0x86,0x8a,0x9f,0xac,0x9d,0x98,0x9b,0x8f,0x8a,0x87,0x88,0x86,0x93,0xa3,0x9b,0x93,0xa0,0x23,0x2a,0x2f,0x1c,0x21,0x26,0x15,0x24,0x13,0x0c +,0x08,0x02,0x11,0x7b,0xa3,0x93,0x9a,0x92,0x88,0x88,0x84,0x83,0x81,0x81,0x81,0x84,0x85,0x89,0x95,0xa4,0x47,0x0b,0x06,0x08,0x03,0x03,0x02,0x06,0x05,0x01,0x01,0x02 +,0x03,0x0a,0x10,0x12,0x12,0x1b,0x20,0x15,0x16,0x29,0x27,0x38,0x2b,0x2f,0xd9,0x35,0xa4,0xac,0xc4,0x5a,0x1a,0x1e,0x51,0xb8,0x96,0x8b,0x8d,0x95,0x9e,0x9d,0xab,0xa2 +,0x91,0x89,0x86,0x8a,0x88,0x89,0x97,0x99,0xa8,0xaf,0xad,0xdb,0x3c,0xbe,0xa5,0x55,0x34,0x21,0x18,0x0e,0x0d,0x11,0x18,0x1b,0x41,0x9b,0x59,0x43,0xb3,0x9c,0x92,0x8d +,0x86,0x82,0x82,0x81,0x82,0x84,0x83,0x86,0x8d,0x65,0x28,0x27,0x17,0x14,0x0e,0x09,0x06,0x01,0x02,0x01,0x02,0x05,0x08,0x0d,0x0f,0x10,0x0d,0x0a,0x0d,0x14,0x10,0x15 +,0x11,0x1a,0x33,0x45,0x5a,0x2a,0x31,0xbb,0x2c,0x30,0xaa,0x9a,0x99,0x91,0x8d,0x93,0xaf,0xaf,0xa3,0xb5,0x9b,0x8d,0x8b,0x8d,0x8b,0x8e,0x94,0x94,0xa2,0xc3,0xa6,0xa3 +,0x9f,0x9e,0x9d,0xa1,0xa4,0xb5,0x1e,0x0b,0x0d,0x1c,0x1f,0x19,0x2a,0x44,0x1a,0x14,0x13,0x23,0x4f,0xad,0x93,0x8e,0x89,0x83,0x84,0x83,0x85,0x87,0x86,0x8b,0x90,0x97 +,0xa5,0x9c,0xeb,0x1e,0x0f,0x07,0x03,0x02,0x03,0x06,0x07,0x08,0x0d,0x09,0x08,0x08,0x0b,0x09,0x0e,0x16,0x18,0x18,0x19,0x1f,0x25,0x1c,0x26,0x2a,0x1c,0x37,0xda,0xa6 +,0x94,0x8d,0x90,0x9b,0xa5,0xa4,0xa2,0x9a,0x9c,0x8f,0x8d,0x8b,0x8c,0xa6,0xa2,0x95,0x9b,0xa7,0x9f,0x9a,0x95,0x95,0x90,0x99,0xba,0xb1,0x4c,0x1c,0x15,0x23,0x34,0x34 +,0xd1,0x33,0x1b,0x11,0x0e,0x0b,0x16,0x46,0xa6,0x9c,0x8c,0x8b,0x8e,0x89,0x86,0x84,0x84,0x85,0x84,0x86,0x86,0x88,0x98,0xc8,0x26,0x16,0x07,0x02,0x03,0x04,0x03,0x07 +,0x04,0x03,0x03,0x04,0x04,0x05,0x0c,0x14,0x1a,0x21,0x2d,0x26,0x20,0x24,0x37,0x20,0x2d,0x32,0x2e,0xb1,0x9d,0x9c,0xb7,0xde,0xbb,0x36,0x21,0x3d,0xa6,0x9e,0x9a,0x8f +,0x90,0x9c,0xa0,0x98,0x92,0x8f,0x8e,0x8a,0x8d,0x8d,0x88,0x89,0x92,0x98,0x9e,0x9f,0xbe,0x2c,0x2b,0x33,0x66,0x30,0x18,0x0c,0x0b,0x0a,0x06,0x0b,0x0f,0x22,0x4a,0xbc +,0xae,0xa5,0x96,0x8e,0x89,0x87,0x83,0x82,0x83,0x83,0x81,0x83,0x8a,0x93,0xad,0x22,0x0f,0x0e,0x0e,0x08,0x08,0x09,0x03,0x01,0x02,0x02,0x02,0x04,0x09,0x0b,0x0a,0x10 +,0x11,0x14,0x12,0x10,0x1b,0x15,0x1d,0x2c,0xe0,0x9a,0x9a,0x9c,0x99,0xa7,0xcb,0xed,0xa3,0x90,0x8f,0x8e,0x8c,0x8f,0x9a,0xa6,0xa1,0xa2,0x9f,0x94,0x98,0x9d,0x95,0x96 +,0x98,0x9d,0x9d,0xa4,0xde,0xd4,0xa7,0xa1,0x9c,0x99,0xaa,0xce,0x38,0x27,0x22,0x2a,0x5a,0xb8,0xb8,0x5c,0x36,0x2f,0x2a,0x2f,0x28,0x2b,0x35,0x29,0x28,0x2e,0x36,0x33 +,0x28,0x1f,0x1c,0x18,0x1a,0x19,0x1f,0x28,0x39,0x49,0x27,0x1f,0x20,0x21,0x2c,0x3e,0x3a,0x46,0x3c,0x48,0x39,0x23,0x2b,0x33,0x2d,0x24,0x24,0x3f,0x3e,0xec,0xb9,0xb7 +,0xba,0xbc,0x3e,0x51,0xcc,0xc4,0xa3,0xa8,0xad,0x55,0x3c,0x43,0x40,0x40,0xbd,0xae,0xae,0xa6,0xa2,0x9f,0x9e,0x9c,0x99,0x9d,0x9e,0x9e,0x9a,0x9a,0x98,0x8e,0x8f,0x94 +,0x9b,0x9e,0xa5,0xab,0xb4,0xae,0xb9,0xd3,0x5e,0x2f,0x28,0x1f,0x1e,0x24,0x1c,0x19,0x19,0x15,0x17,0x1b,0x1d,0x1a,0x19,0x14,0x19,0x1a,0x19,0x1c,0x27,0x34,0x31,0x3a +,0x32,0x32,0x30,0x3d,0x45,0x3d,0x49,0x36,0x2f,0x45,0x31,0x35,0x34,0x29,0x2b,0x27,0x29,0x2f,0x33,0x4f,0x6b,0x59,0xcf,0x3c,0x5e,0xfa,0xc0,0xaa,0xb5,0xbb,0x48,0xbf +,0xb1,0xd1,0xab,0x9f,0x9c,0x9a,0x9a,0x94,0x95,0x8f,0x8a,0x8c,0x8c,0x88,0x89,0x8b,0x8c,0x8e,0x8c,0x8f,0x95,0x9f,0x9a,0xa8,0xb7,0xb0,0xe9,0x4c,0x38,0x30,0x2b,0x22 +,0x1b,0x14,0x10,0x0e,0x11,0x0d,0x13,0x12,0x06,0x07,0x1c,0x8c,0xe1,0x00,0xaf,0x87,0x1e,0xad,0x0c,0x19,0x1c,0x13,0x0e,0x23,0x38,0x00,0x08,0x00,0x02,0x00,0x00,0x02 +,0x02,0x05,0x04,0x00,0x00,0x02,0x04,0x10,0xae,0x9e,0xbf,0xc1,0x99,0x8f,0x95,0x92,0x83,0x80,0x80,0x85,0x8a,0x81,0x80,0x80,0x82,0x82,0x81,0x81,0x82,0x80,0x80,0x80 +,0x82,0x81,0x80,0x80,0x80,0x80,0x82,0x81,0x89,0xa2,0x9e,0x8e,0x8f,0xbe,0x39,0x19,0x05,0x02,0x02,0x0f,0x12,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x02,0x0a,0x0e,0x08,0x0f,0x1a,0x31,0x1e,0x08,0x17,0x98,0x89,0x88,0x8d,0xa9,0xc3,0xac,0x89,0x80,0x80 +,0x80,0x82,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x82,0x80,0x80,0x81,0x83,0x82,0x80,0x80,0x80,0x80,0x84,0x8c,0x96 +,0x91,0x8b,0x98,0xb1,0x35,0x30,0x19,0x07,0x04,0x0a,0x12,0x0e,0x06,0x02,0x00,0x00,0x00,0x02,0x0c,0x06,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x00,0x01,0x03,0x02,0x00,0x01,0x03,0x09,0x0c,0x03,0x01,0x00,0x07,0xca,0x89,0x94,0x25,0x1a,0x22,0xb4,0x73,0xbb,0x8e,0x83,0x83 +,0x88,0x92,0xa1,0x98,0x90,0x89,0x80,0x83,0x8c,0x90,0x87,0x80,0x80,0x80,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x82,0x81,0x80,0x80,0x80,0x81,0x82,0x81,0x81,0x84,0x83 +,0x80,0x80,0x80,0x84,0x98,0xae,0x40,0xab,0x8a,0x89,0x9e,0x15,0x04,0x05,0x0d,0x10,0x17,0x10,0x0a,0x02,0x03,0x06,0x0d,0x0d,0x13,0xb0,0x90,0x8c,0xb6,0xc3,0x9b,0x8d +,0x86,0x89,0x89,0x8a,0x86,0x85,0x83,0x8b,0xdd,0x2d,0xa2,0x86,0x80,0x87,0x99,0xa5,0x9d,0x98,0x93,0x8d,0x8a,0x8d,0x8f,0xb5,0x1e,0x09,0x04,0x0a,0x0f,0x0c,0x00,0x00 +,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x07 +,0x06,0x02,0x00,0x00,0x00,0x00,0x08,0x2e,0x1d,0x09,0x07,0x0d,0x1f,0x38,0xc0,0x8d,0x81,0x81,0x85,0x87,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81 +,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x87,0x83,0x81,0x82,0x82,0x87,0x89,0x86,0x83,0x81,0x80,0x80,0x81,0x85,0x82,0x80 +,0x81,0x82,0x81,0x80,0x80,0x82,0x8a,0x8e,0x96,0x97,0x9f,0x64,0x2b,0x2a,0x0f,0x14,0x1c,0x07,0x03,0x00,0x01,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x00,0x01,0x00,0x09,0x26,0x14,0x08,0x06,0x0e,0x50,0x30,0x3d,0x9c,0x91,0x88,0x8d,0x89 +,0x81,0x81,0x82,0x82,0x84,0x87,0x88,0x87,0x84,0x82,0x86,0x9b,0xb6,0x39,0x3e,0xa4,0x97,0x8d,0x95,0x45,0x9a,0x83,0x84,0x87,0x8a,0x86,0x81,0x8e,0xba,0xba,0x9d,0x8d +,0x9a,0xa4,0x93,0x8c,0x97,0xb4,0x30,0x19,0x19,0x13,0x19,0x3a,0x2c,0x1f,0x16,0x0a,0x07,0x03,0x03,0x0b,0x0f,0x0c,0x19,0x4a,0x2c,0x0f,0x0e,0x1f,0xb8,0x3e,0x29,0xde +,0xaf,0x9e,0xb6,0x66,0x97,0x93,0x6c,0x23,0x14,0x1b,0x2c,0x18,0x1c,0x22,0x3a,0xb3,0xdd,0xb8,0x3d,0x2c,0x26,0x27,0x23,0x2c,0x97,0x8b,0x91,0xc8,0x36,0xc8,0xae,0x32 +,0xd8,0xb6,0xa8,0xa2,0xc6,0x90,0x86,0x83,0x82,0x83,0x84,0x83,0x83,0x83,0x81,0x80,0x80,0x80,0x81,0x82,0x87,0x8b,0x93,0x98,0xa5,0x97,0x85,0x83,0x8c,0xc4,0x18,0x1c +,0x0f,0x05,0x09,0x09,0x0d,0x05,0x01,0x02,0x03,0x04,0x02,0x02,0x02,0x01,0x00,0x00,0x00,0x02,0x04,0x06,0x0a,0x0d,0x0c,0x07,0x07,0x0d,0x0f,0xae,0x8d,0x90,0x9c,0x4d +,0x37,0xbe,0x3e,0x39,0xa6,0x8e,0x86,0x8c,0x8c,0x86,0x84,0x86,0x87,0x88,0x83,0x86,0x91,0x8c,0x8f,0x8f,0x8d,0x8f,0x88,0x98,0x35,0x1c,0x14,0x1b,0x1b,0x98,0x85,0x8c +,0x99,0xa9,0xbb,0x3f,0x18,0x20,0xa3,0x97,0xa5,0x1d,0x1c,0x27,0x16,0x0b,0x0d,0x17,0x37,0x22,0x0f,0x0b,0x0a,0x0c,0x0c,0x16,0x1d,0x0f,0x08,0x04,0x05,0x02,0x05,0x21 +,0xd0,0x3f,0x1d,0x11,0x19,0x0f,0x07,0x18,0xc0,0x93,0x97,0xa9,0x8f,0x8a,0x94,0xaa,0xa9,0x92,0x8f,0x9a,0xb0,0x29,0x26,0x14,0x0f,0x25,0x62,0xc1,0x6f,0x3e,0xab,0xc4 +,0xa2,0x84,0x85,0x84,0x90,0xae,0xa7,0x27,0x18,0x1e,0x27,0xcf,0x25,0x0d,0x12,0x19,0x1a,0x18,0x1d,0xce,0x9e,0x91,0x8f,0x90,0x8b,0x8d,0x8f,0x8a,0x84,0x83,0x84,0x8c +,0x8d,0x95,0x9a,0x87,0x84,0x84,0x89,0x8c,0x8a,0x9e,0x32,0x36,0xd1,0xa0,0x20,0x08,0x09,0x08,0x06,0x02,0x01,0x01,0x01,0x00,0x01,0x00,0x02,0x00,0x01,0x02,0x06,0x08 +,0x0a,0x0b,0x08,0x0d,0x0a,0x39,0x9b,0x9a,0x9e,0xa9,0xa0,0x3b,0x19,0x29,0xa7,0x93,0x8e,0x97,0x8e,0x8b,0x88,0x86,0x87,0x84,0x82,0x84,0x84,0x8b,0x8b,0x8c,0x95,0x95 +,0x97,0x90,0x91,0x91,0xb2,0xc7,0x32,0xb8,0x89,0x88,0x8b,0x90,0x8e,0x8d,0xba,0x24,0xeb,0xc5,0x9d,0xd5,0x26,0x54,0x29,0x1e,0x0e,0x0f,0x1c,0x14,0x19,0x1a,0x22,0x3c +,0x1a,0x14,0x16,0x17,0x13,0x09,0x06,0x03,0x02,0x03,0x07,0x19,0x18,0x11,0x11,0x1f,0x27,0x16,0x1b,0x2e,0x9e,0x92,0xab,0xbb,0x9d,0x9b,0xa8,0xbd,0xb9,0xa4,0xb9,0x2c +,0x31,0x3c,0x34,0x1f,0x2b,0xb4,0xa9,0xaf,0xb4,0xad,0xac,0xa3,0xc9,0x8f,0x84,0x87,0x8a,0x98,0x97,0xa8,0x23,0x12,0x11,0x21,0x3c,0x15,0x16,0x25,0x2b,0x22,0x21,0xad +,0xa3,0x9d,0xa8,0x99,0x8f,0x8d,0x90,0x91,0x85,0x85,0x86,0x8e,0x91,0x94,0x8d,0x9b,0x8e,0x82,0x84,0x85,0x89,0x88,0x8c,0xbc,0x2f,0x3d,0x50,0x44,0x0b,0x05,0x06,0x04 +,0x01,0x01,0x01,0x02,0x02,0x02,0x01,0x03,0x03,0x04,0x09,0x0d,0x0e,0x0c,0x08,0x09,0x0f,0x0c,0x0c,0x0b,0xb7,0x99,0xb1,0x70,0x2e,0xa5,0xd0,0x43,0xad,0x9e,0x88,0x8c +,0x92,0x89,0x8a,0x88,0x8c,0x90,0x87,0x88,0x8a,0x92,0x9b,0x9a,0xa0,0x98,0x93,0x8d,0x91,0x97,0xa6,0xa9,0x9d,0x98,0xac,0x9d,0x86,0x87,0x8f,0xae,0xac,0x9a,0xdb,0x22 +,0x24,0x2a,0xae,0x20,0x22,0x25,0x2b,0x23,0x14,0x26,0x2d,0x39,0x1f,0x16,0x15,0x1a,0x11,0x17,0x11,0x0d,0x0a,0x05,0x02,0x02,0x04,0x03,0x05,0x07,0x2e,0x47,0x1b,0x14 +,0x2d,0xa8,0xde,0x36,0x38,0xa2,0x8e,0x9a,0xa5,0x9d,0x9c,0xaa,0x3c,0xe4,0xbe,0xca,0x3c,0x3f,0xbf,0xb1,0xcc,0xa8,0x97,0x98,0x9f,0xa2,0x9d,0xa5,0x9d,0xac,0xc4,0xea +,0xe3,0xa4,0xc9,0x4b,0x3e,0x49,0x2d,0x1c,0x35,0xbf,0x93,0x97,0xac,0x9d,0x99,0x97,0x97,0x8f,0x89,0x88,0x8c,0x8f,0x8b,0x88,0x89,0x8d,0x86,0x85,0x84,0x88,0x89,0x86 +,0x8d,0x93,0xa4,0xc0,0x2f,0xa3,0xb3,0x47,0x0e,0x04,0x08,0x01,0x04,0x02,0x05,0x06,0x03,0x01,0x03,0x04,0x06,0x04,0x05,0x07,0x07,0x07,0x06,0x08,0x09,0x09,0x0b,0x10 +,0x1e,0x28,0x23,0x48,0x2a,0x2c,0x3b,0xbd,0x9e,0xad,0x92,0x8d,0x8f,0x8e,0x96,0x8d,0x8c,0x8d,0x8e,0x8e,0x85,0x85,0x8b,0x88,0x86,0x87,0x8a,0x8b,0x85,0x85,0x88,0x8d +,0x8f,0x8c,0x8f,0x98,0x9f,0x9e,0xa2,0x40,0x2b,0x3b,0x1f,0x20,0x18,0x16,0x18,0x2e,0xa5,0xa6,0xa6,0x4c,0x37,0x34,0x24,0x24,0x2c,0x49,0x27,0x18,0x0e,0x0a,0x0d,0x0a +,0x0c,0x0c,0x0d,0x0e,0x0d,0x0f,0x15,0x15,0x15,0x10,0x13,0x15,0x0f,0x11,0x11,0x0e,0x0d,0x0d,0x0f,0x10,0x1a,0xba,0xa4,0xa1,0xaa,0x9d,0x95,0x92,0x8b,0x8b,0x8c,0x8c +,0x97,0x9e,0x9d,0x9c,0x97,0x9f,0xa2,0xa8,0xae,0xaf,0xcd,0xc5,0xb8,0xae,0xba,0xf9,0xbe,0xab,0xad,0xb4,0xac,0xb4,0xa1,0xad,0x9f,0xb8,0x9d,0x99,0xc2,0xba,0xcd,0x99 +,0x9c,0x9e,0xaf,0x9e,0x8d,0x8c,0x91,0x8e,0x8e,0x8b,0x88,0x88,0x8a,0x94,0x9a,0xaa,0x3d,0x2e,0x1f,0x0e,0x0d,0x06,0x09,0x09,0x07,0x08,0x05,0x07,0x06,0x0b,0x12,0x11 +,0x1b,0x2a,0x1e,0x28,0x1c,0x36,0x2b,0x1e,0x1f,0x1e,0xaf,0xf6,0x3c,0xe1,0xa8,0x9c,0xa8,0x9d,0x9c,0xa6,0xac,0x32,0x2b,0xea,0x4b,0x4b,0x27,0x1a,0x2b,0x28,0x2a,0x2b +,0x3f,0xbb,0x67,0xa5,0x9d,0x8d,0x90,0xa2,0x91,0x89,0x86,0x88,0x92,0x9c,0xb7,0xab,0xb6,0xde,0xb1,0xc0,0xee,0x2c,0x22,0x51,0xd9,0x5a,0xbf,0x32,0xbf,0xab,0xac,0xb4 +,0xb1,0xbf,0x39,0x39,0x2c,0x27,0x3e,0x32,0x35,0x1d,0xbc,0x97,0xb5,0xc9,0x2c,0xbe,0x40,0x36,0x2a,0x25,0x38,0x19,0x12,0x17,0x16,0x24,0x17,0x14,0x22,0x38,0xa8,0x4a +,0x30,0x3a,0x2a,0x3d,0x42,0x33,0x3c,0x17,0x13,0x0d,0x12,0x16,0x11,0x0f,0x0f,0x59,0xc4,0xb6,0x4f,0xb8,0x9c,0xa8,0xb8,0xa8,0x9a,0x8e,0x99,0xa1,0x93,0x8e,0x8c,0x8d +,0x87,0x87,0x87,0x85,0x84,0x84,0x87,0x89,0x8c,0x91,0x8e,0x9d,0xc3,0x38,0x1c,0x17,0x16,0x18,0x13,0x27,0x26,0x22,0x2a,0xba,0xae,0x46,0x4a,0x3a,0x41,0xb4,0xd3,0x31 +,0x2a,0x1b,0x1c,0x20,0x21,0x1c,0x1c,0x1d,0x1b,0x1a,0x2d,0x3d,0x26,0x1a,0x1d,0x17,0x12,0x16,0x14,0x14,0x11,0x0f,0x19,0x34,0x50,0xbf,0xaa,0x97,0x8f,0x8a,0x8b,0x90 +,0x8b,0x8b,0x8e,0x89,0x88,0x8a,0x9d,0x2a,0x1c,0x18,0x18,0x0f,0x08,0x05,0x07,0x07,0x05,0x03,0x03,0x02,0x03,0x04,0x05,0x07,0x06,0x06,0x16,0x1e,0x2d,0xf6,0xaf,0x9c +,0x9c,0x8c,0x87,0x88,0x87,0x86,0x87,0x85,0x86,0x87,0x89,0x8d,0x8e,0x8c,0x89,0x8b,0x92,0x90,0x94,0x8f,0x8d,0x98,0x9b,0x9f,0xa0,0xa6,0xad,0xbf,0x42,0x29,0x32,0x35 +,0x3c,0x6c,0x37,0x35,0x37,0x37,0xba,0xad,0xb0,0xcb,0x6a,0x54,0x3a,0x35,0x25,0x18,0x09,0x07,0x08,0x08,0x0b,0x0b,0x09,0x0c,0x0d,0x12,0x13,0x10,0x15,0x19,0x1d,0x21 +,0x35,0xd9,0x3d,0x24,0x26,0x4f,0xb9,0xb4,0xc2,0xbb,0x9b,0x95,0x92,0x8f,0x91,0x8f,0x91,0x99,0x9b,0x9c,0x9c,0xa2,0xd7,0x38,0x29,0x2b,0x45,0xf7,0x3c,0x1f,0x26,0xc4 +,0xa6,0xea,0x41,0xc0,0xa6,0x9f,0x9a,0x9a,0x9b,0x98,0x9c,0x97,0x90,0x8d,0x8a,0x86,0x84,0x84,0x83,0x81,0x83,0x84,0x86,0x87,0x88,0x89,0x8b,0x91,0x9c,0xb8,0xd5,0x3e +,0x1e,0x15,0x0f,0x08,0x07,0x09,0x0b,0x08,0x04,0x02,0x02,0x03,0x02,0x02,0x02,0x03,0x01,0x01,0x03,0x05,0x06,0x06,0x09,0x0c,0x0e,0x19,0x1c,0x19,0x1c,0x23,0x2a,0x2f +,0x32,0x29,0x24,0x26,0x20,0x27,0xdc,0x9e,0x92,0x93,0x93,0x8e,0x88,0x84,0x86,0x87,0x86,0x84,0x84,0x84,0x86,0x87,0x8a,0x90,0x92,0x91,0x92,0x95,0x98,0x9a,0x9f,0xa0 +,0x95,0x9c,0xb9,0x41,0x30,0x66,0x3a,0x22,0x1c,0x1e,0x19,0x0e,0x12,0x19,0x1a,0x1c,0x21,0x26,0x34,0xa8,0xa5,0xb6,0xb0,0xaa,0xac,0xa7,0xb8,0x47,0x28,0x14,0x0f,0x0e +,0x0f,0x0b,0x09,0x08,0x08,0x08,0x0a,0x0d,0x0c,0x0b,0x0d,0x14,0x1b,0x20,0x24,0x2c,0x23,0x1e,0x33,0xc5,0xa9,0x9e,0x9d,0xa1,0xa2,0x97,0x8f,0x92,0x9a,0x9b,0x98,0x9a +,0x9e,0xad,0xa7,0xb6,0x52,0xb9,0x9e,0x97,0x94,0x8d,0x8c,0x8a,0x86,0x82,0x82,0x82,0x83,0x81,0x81,0x81,0x82,0x85,0x87,0x8a,0x89,0x8a,0x8e,0x94,0xa5,0x73,0x1f,0x16 +,0x16,0x0e,0x06,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x05,0x08,0x09,0x17,0x22,0x22,0x28,0x43,0xaf,0xa6,0x9d,0xa5,0xa0,0xab,0xb0,0xa3 +,0x9b,0x98,0x9a,0x97,0x96,0x97,0x8d,0x8d,0x93,0x94,0x95,0x91,0x92,0x8f,0x8f,0x94,0x9d,0xa9,0x9c,0x94,0x97,0x8f,0x8f,0x8f,0x8e,0x8c,0x88,0x8b,0x8c,0x91,0x92,0x8d +,0x95,0x9f,0xa5,0x5f,0x2e,0x1f,0x1c,0x1a,0x14,0x12,0x0f,0x11,0x19,0x22,0x1b,0x19,0x19,0x18,0x19,0x18,0x1c,0x1b,0x14,0x0f,0x11,0x13,0x12,0x12,0x14,0x14,0x1a,0x1d +,0x27,0x25,0x19,0x1a,0x1b,0x1f,0x1f,0x1b,0x1c,0x16,0x0d,0x0d,0x0e,0x14,0x11,0x0e,0x12,0x19,0x29,0x3e,0x47,0x43,0x58,0xc9,0xc4,0xad,0x9c,0x99,0x97,0x9d,0x96,0x8c +,0x89,0x86,0x86,0x84,0x82,0x82,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x83,0x85,0x8a,0x91,0x95,0x94,0x99,0xa2,0x5a,0x27,0x1a,0x12,0x16,0x0f,0x0a,0x07,0x06,0x05,0x03 +,0x03,0x03,0x02,0x01,0x01,0x01,0x02,0x03,0x05,0x06,0x09,0x0b,0x13,0x1c,0x19,0x18,0x16,0x18,0x1e,0x22,0x21,0x1d,0x16,0x1b,0x28,0x4e,0x67,0xcf,0xae,0xa5,0x94,0x8b +,0x8a,0x8c,0x8c,0x8a,0x89,0x89,0x8a,0x8d,0x92,0x92,0x8e,0x8d,0x8d,0x8f,0x8f,0x8f,0x8f,0x8e,0x8d,0x94,0x99,0x9d,0x9d,0x9f,0xab,0xcd,0x3b,0x3a,0x47,0x3d,0x2c,0x2b +,0x27,0x2a,0x47,0xb6,0xc3,0xed,0x7d,0xe5,0xc3,0xc8,0x4e,0x33,0x26,0x26,0x31,0x2b,0x28,0x25,0x1f,0x1b,0x18,0x1f,0x1d,0x15,0x15,0x13,0x11,0x0e,0x0d,0x0d,0x0a,0x08 +,0x0a,0x0b,0x0e,0x10,0x10,0x17,0x1c,0x36,0xb9,0xde,0xd7,0xc2,0xb2,0xc2,0xc9,0xb4,0xb6,0xcc,0x3d,0xc0,0xad,0xa5,0xa2,0xa5,0x9f,0x9b,0x8e,0x89,0x88,0x87,0x86,0x84 +,0x83,0x82,0x83,0x84,0x86,0x87,0x85,0x85,0x84,0x85,0x87,0x88,0x8a,0x88,0x88,0x90,0x9f,0xbc,0x4b,0x29,0x16,0x0e,0x08,0x03,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0x01 +,0x02,0x04,0x03,0x04,0x05,0x07,0x07,0x09,0x0a,0x0f,0x11,0x0e,0x19,0x29,0x4f,0xc3,0xbc,0xa7,0x9d,0x94,0x8c,0x8c,0x8c,0x8e,0x8f,0x8d,0x8d,0x8e,0x91,0x9a,0xa6,0xa6 +,0x9a,0x9b,0x9a,0x99,0x98,0x99,0x8f,0x8d,0x91,0x96,0x9c,0x99,0x96,0x8f,0x92,0x97,0x9d,0xa5,0x9f,0x9f,0xa5,0xa7,0xa5,0xa5,0xa9,0x9a,0x9b,0xad,0x4b,0x31,0x2c,0x28 +,0x1f,0x17,0x11,0x0e,0x12,0x12,0x14,0x13,0x12,0x10,0x13,0x1b,0x26,0x1f,0x1c,0x1c,0x1c,0x1e,0x1b,0x1a,0x12,0x0f,0x12,0x15,0x16,0x11,0x15,0x15,0x16,0x1c,0x20,0x1e +,0x1c,0x1c,0x1e,0x21,0x21,0x24,0x1e,0x1d,0x2e,0x54,0xc2,0xba,0xa8,0x9d,0x9e,0x92,0x8c,0x8c,0x8d,0x8b,0x87,0x86,0x86,0x85,0x85,0x87,0x87,0x86,0x85,0x85,0x83,0x85 +,0x85,0x84,0x84,0x85,0x8a,0x8b,0x8e,0x91,0x91,0x99,0xa3,0x6e,0x19,0x13,0x11,0x0e,0x0b,0x06,0x05,0x04,0x05,0x06,0x04,0x03,0x02,0x02,0x02,0x02,0x03,0x02,0x02,0x01 +,0x02,0x04,0x06,0x08,0x0b,0x0c,0x0f,0x1b,0x33,0x56,0x4f,0xb2,0x9e,0x97,0x92,0x92,0x8e,0x91,0x99,0x97,0x91,0x8d,0x8b,0x8d,0x8c,0x8a,0x89,0x86,0x8a,0x8c,0x8e,0x8f +,0x8e,0x8f,0x91,0x94,0x9d,0xaa,0xaa,0xa6,0xa6,0xad,0xbc,0xad,0xac,0x9a,0x95,0x96,0x9a,0x9f,0xa0,0xa9,0xad,0xc8,0x58,0x2a,0x21,0x23,0x2c,0x29,0x27,0x1f,0x1b,0x1d +,0x1f,0x2e,0x20,0x1c,0x1f,0x1c,0x1d,0x19,0x12,0x0e,0x0a,0x07,0x08,0x09,0x0c,0x0f,0x0d,0x0f,0x16,0x27,0x28,0x1b,0x1f,0x1e,0x26,0x2d,0x2b,0x2d,0x1f,0x22,0x36,0x33 +,0x32,0x36,0x29,0x3f,0xd8,0xa7,0xa2,0xac,0xaa,0xa5,0x9c,0x9c,0x94,0x94,0x9a,0x96,0x8d,0x88,0x85,0x84,0x83,0x82,0x81,0x80,0x81,0x81,0x81,0x81,0x82,0x83,0x84,0x86 +,0x8c,0x93,0x98,0x9e,0xb8,0x2c,0x18,0x11,0x0e,0x0e,0x0b,0x06,0x03,0x02,0x02,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x04,0x05,0x07,0x0c,0x18,0x19,0x1b,0x21 +,0x3b,0x51,0xb1,0xae,0xac,0xad,0xc6,0xcb,0xb7,0xa0,0xa5,0x9e,0x9f,0x9e,0x97,0x8f,0x8f,0x93,0x96,0x9a,0x96,0x93,0x92,0x95,0x97,0x98,0x9c,0x96,0x90,0x8f,0x92,0x94 +,0x93,0x8e,0x88,0x89,0x8d,0x8f,0x8d,0x8e,0x91,0x93,0x99,0xab,0x49,0x3f,0x32,0x38,0x2f,0x23,0x21,0x1d,0x20,0x1d,0x21,0x1c,0x17,0x17,0x14,0x14,0x18,0x1e,0x12,0x0f +,0x0c,0x0f,0x11,0x1a,0x1e,0x1b,0x33,0x11,0x2a,0x89,0x8c,0x02,0x19,0x80,0x35,0xb0,0x22,0x0d,0x0c,0x04,0x0b,0x06,0x17,0x00,0x02,0x03,0x00,0x04,0x00,0x08,0x04,0x01 +,0x07,0x08,0x0a,0x0a,0x0d,0x2d,0x2b,0x4f,0x9c,0x8d,0x85,0x83,0x82,0x84,0x83,0x80,0x80,0x83,0x82,0x80,0x80,0x80,0x81,0x81,0x82,0x83,0x83,0x82,0x82,0x84,0x82,0x84 +,0x85,0x88,0x89,0x89,0x8d,0x8b,0x8f,0x93,0xa4,0x9c,0xa8,0x62,0x21,0x1b,0x1b,0x0b,0x10,0x09,0x06,0x07,0x06,0x05,0x03,0x03,0x01,0x02,0x00,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x02,0x03,0x09,0x08,0x0b,0x14,0x29,0x2c,0x3f,0xa0,0x9d,0x93,0x8d,0x8b,0x87,0x82,0x83,0x82,0x82,0x82,0x81,0x81 +,0x81,0x81,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x83,0x83,0x83,0x86,0x87 +,0x8f,0x95,0xa9,0xb8,0x24,0x13,0x0e,0x07,0x05,0x04,0x02,0x02,0x02,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x02,0x02,0x04,0x03,0x04,0x04,0x06,0x0b,0x0c,0x14,0x2c,0x3f,0xaf,0x9c,0x8f,0x86,0x86,0x83,0x83,0x82,0x81,0x81 +,0x81,0x81,0x80,0x80,0x80,0x81,0x80,0x81,0x80,0x82,0x82,0x81,0x82,0x83,0x86,0x85,0x86,0x87,0x86,0x87,0x88,0x88,0x87,0x88,0x8b,0x89,0x88,0x89,0x87,0x89,0x8a,0x8b +,0x8a,0x8e,0x8d,0x8d,0x8e,0x8f,0x94,0x94,0x98,0x9d,0x9a,0x9b,0xa3,0xa3,0xad,0xa7,0xaf,0x9f,0xa4,0xa8,0xa0,0xa7,0xa3,0xa2,0x9a,0x9d,0x95,0x96,0x94,0x8e,0x91,0x8f +,0x8e,0x8b,0x8b,0x8b,0x8c,0x8b,0x8b,0x8c,0x8d,0x8e,0x8e,0x94,0x9a,0xa2,0xa4,0xbd,0x48,0x2e,0x1f,0x15,0x0e,0x0c,0x0a,0x07,0x05,0x03,0x02,0x02,0x01,0x01,0x00,0x01 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 +,0x01,0x02,0x02,0x03,0x05,0x07,0x0a,0x10,0x1d,0x29,0x71,0xa2,0x90,0x8a,0x85,0x83,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x85,0x87,0x88,0x8a,0x8c,0x8e,0x93,0x99,0x9f,0xaa +,0xcc,0x44,0x2d,0x22,0x1d,0x14,0x10,0x0d,0x0a,0x0a,0x08,0x07,0x06,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x05,0x05,0x04,0x04,0x04,0x04,0x03,0x04,0x04,0x04,0x04,0x03 +,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x06,0x07,0x09,0x09,0x0b,0x0b,0x0e,0x11,0x14,0x18,0x1a,0x1c,0x23,0x23,0x26,0x2b,0x2e,0x3d,0x4c +,0x4d,0x52,0x6d,0x70,0x6b,0x5c,0xd7,0xea,0xe1,0xc6,0xcd,0xcf,0xcd,0xe9,0xd3,0xbc,0xb0,0xac,0xa4,0xa2,0x9e,0x9a,0x99,0x97,0x94,0x92,0x91,0x8f,0x8e,0x8e,0x8e,0x8e +,0x8e,0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8f,0x90,0x90,0x8f,0x92,0x94,0x98,0x97,0x99,0x9d,0x9e,0x9f,0xa0,0xa3,0xa8,0xa2,0xa6,0xa7,0xaa,0xae,0xad,0xb7,0xc3,0xcf,0xcc +,0xf7,0x56,0x41,0x2f,0x30,0x29,0x20,0x20,0x1f,0x1d,0x1d,0x1c,0x1c,0x19,0x17,0x1b,0x19,0x1b,0x1c,0x1e,0x22,0x27,0x2c,0x37,0x44,0xd8,0xb8,0xa9,0xa2,0xa0,0x9b,0x98 +,0x93,0x93,0x92,0x8f,0x8f,0x8f,0x8e,0x8e,0x8e,0x90,0x92,0x93,0x92,0x93,0x95,0x97,0x98,0x9c,0xa0,0x9f,0xa7,0xae,0xba,0xbf,0xb5,0xbc,0xc0,0xcc,0xd1,0xbd,0xce,0xd9 +,0xc4,0xb8,0xba,0xc6,0xd5,0xc7,0xcb,0xc2,0xc7,0xc2,0xd8,0x43,0x3d,0x3b,0x3a,0x31,0x2c,0x27,0x26,0x20,0x1e,0x1d,0x1e,0x1d,0x1d,0x1d,0x1d,0x20,0x20,0x25,0x29,0x2d +,0x35,0x31,0x3a,0x4f,0x4d,0x7c,0x5c,0x64,0xd6,0x5e,0xe1,0xdb,0xde,0x55,0x3d,0x39,0x36,0x35,0x35,0x36,0x2d,0x2c,0x2b,0x2c,0x2c,0x2a,0x2b,0x2f,0x35,0x3d,0x47,0x4e +,0xd9,0xbe,0xb6,0xaf,0xaa,0xa7,0xa7,0xa6,0xa3,0xa4,0xaa,0xa5,0xa6,0xa5,0xa8,0xaf,0xb1,0xc1,0xd4,0xf1,0x4e,0x41,0x35,0x2d,0x2a,0x2a,0x25,0x22,0x1f,0x20,0x23,0x23 +,0x29,0x2a,0x2e,0x37,0x4c,0x4e,0xcc,0xbb,0xb8,0xaf,0xad,0xaa,0xad,0xad,0xab,0xab,0xaa,0xac,0xae,0xaf,0xb6,0xbf,0xc4,0x54,0x51,0x44,0x3f,0x46,0x34,0x37,0x31,0x2e +,0x2e,0x38,0x35,0x37,0x38,0x43,0x59,0x5d,0xc3,0xb7,0xb3,0xb9,0xb6,0xaf,0xae,0xae,0xb0,0xaa,0xa9,0xb3,0xbb,0xb9,0xb8,0xbe,0xc9,0x5f,0x4c,0x3c,0x35,0x2e,0x2f,0x34 +,0x30,0x2b,0x29,0x2d,0x30,0x30,0x2e,0x31,0x3a,0x43,0x53,0xec,0xcc,0xd4,0xc9,0xca,0xcc,0xc1,0xda,0xbe,0xbf,0xc8,0xcf,0xc7,0xd2,0x76,0xdc,0x6b,0xf7,0x43,0x3c,0x48 +,0x4b,0x3d,0x3c,0x3e,0x3a,0x3c,0x3e,0x41,0x3c,0x45,0x43,0x4b,0xcf,0xc8,0xbf,0xc1,0xc3,0xbd,0xc0,0xbc,0xb6,0xb8,0xb5,0xb8,0xbf,0xbe,0xd6,0xcd,0xcb,0xd7,0xd7,0x46 +,0x3d,0x41,0x4c,0x41,0x3f,0x45,0x4e,0x48,0x3e,0x3f,0x4d,0x6c,0x4a,0xf3,0xce,0xc7,0xbe,0xcd,0xbe,0xbf,0xbd,0xbf,0xdb,0xc9,0xca,0xcc,0xd9,0xd1,0xd5,0xde,0x5c,0x52 +,0x4f,0x5c,0x4e,0x40,0x49,0x3e,0x42,0x3c,0x45,0x47,0xfe,0x60,0x46,0x52,0x4e,0xec,0xcc,0xbf,0xc1,0xbc,0xc3,0xcd,0xc9,0xc5,0xbd,0xc8,0xdb,0xe7,0x4b,0x4d,0x3e,0x5e +,0x76,0x47,0x40,0x3a,0x3a,0x31,0x35,0x37,0x3e,0x48,0x62,0x57,0x6d,0xe6,0xde,0xc3,0xc2,0xb7,0xb6,0xb7,0xaf,0xb0,0xb9,0xbd,0xba,0xbd,0xb7,0xcc,0xea,0x56,0x43,0x40 +,0x3c,0x3e,0x3b,0x40,0x30,0x36,0x3a,0x32,0x34,0x34,0x34,0x3b,0x41,0x5c,0xcf,0xd5,0xbf,0xbd,0xbd,0xb9,0xbc,0xad,0xaa,0xaa,0xab,0xae,0xaf,0xbc,0xbd,0xbf,0xed,0x60 +,0x4b,0x37,0x36,0x35,0x34,0x34,0x30,0x39,0x32,0x2c,0x2d,0x2f,0x30,0x3a,0x3e,0x4d,0xce,0x62,0xd2,0xc5,0xb8,0xad,0xb0,0xae,0xab,0xab,0xaf,0xae,0xac,0xaa,0xaf,0xbc +,0xca,0x4e,0x45,0x39,0x39,0x3a,0x36,0x33,0x2e,0x2b,0x31,0x32,0x31,0x30,0x2b,0x36,0x30,0x49,0x5d,0xde,0xbd,0xc7,0xb7,0xb4,0xb3,0xae,0xac,0xab,0xa8,0xa9,0xaf,0xb0 +,0xb4,0xb4,0xc6,0xec,0x58,0x3a,0x34,0x2c,0x2c,0x2b,0x2b,0x2d,0x2d,0x2a,0x2a,0x28,0x27,0x2e,0x35,0x45,0x5d,0xdc,0xcc,0xd0,0xb8,0xb3,0xac,0xa9,0xa9,0xab,0xa8,0xa9 +,0xac,0xa9,0xad,0xac,0xbc,0xd7,0x4c,0x3e,0x35,0x35,0x31,0x2d,0x2e,0x2a,0x2a,0x2b,0x2c,0x2c,0x2b,0x2f,0x36,0x43,0x54,0xcf,0xc3,0xb4,0xaf,0xb1,0xab,0xad,0xa7,0xaa +,0xa7,0xa3,0xa7,0xaa,0xaf,0xb8,0xbc,0xca,0xe2,0x4e,0x36,0x2e,0x28,0x28,0x2a,0x2b,0x2c,0x29,0x27,0x25,0x28,0x28,0x2d,0x3d,0x50,0xcc,0xd4,0xbc,0xb6,0xb1,0xaa,0xa5 +,0xa6,0xa8,0xac,0xad,0xa6,0xa8,0xaa,0xb1,0xbc,0xc7,0x4c,0x41,0x3a,0x2d,0x2c,0x29,0x28,0x2b,0x26,0x29,0x2b,0x26,0x2e,0x2b,0x35,0x37,0x45,0xd6,0xcc,0xb5,0xb8,0xaf +,0xad,0xa7,0xa8,0xa8,0xa9,0xa5,0xa4,0xab,0xac,0xaf,0xae,0xbb,0xda,0x73,0x40,0x39,0x2a,0x27,0x2a,0x2c,0x2b,0x2a,0x28,0x2a,0x2a,0x26,0x2f,0x2f,0x40,0x52,0xeb,0xbd +,0xba,0xb1,0xaf,0xab,0xa8,0xa5,0xa7,0xa8,0xa8,0xaa,0xa9,0xb1,0xb6,0xbf,0xe3,0x69,0x54,0x3a,0x2c,0x2b,0x2b,0x2f,0x29,0x2b,0x2a,0x29,0x2a,0x2a,0x2d,0x2f,0x37,0x42 +,0x51,0xcb,0xb5,0xbb,0xb6,0xae,0xb1,0xac,0xa8,0xa8,0xa5,0xa8,0xa5,0xa9,0xb2,0xb0,0xba,0xc4,0xc4,0x58,0x41,0x2f,0x2a,0x2d,0x2b,0x2c,0x2d,0x2d,0x29,0x2c,0x27,0x2b +,0x2e,0x33,0x60,0x63,0xc9,0xbe,0xb8,0xaf,0xb4,0xac,0xac,0xad,0xac,0xa9,0xa8,0xa8,0xac,0xb1,0xc1,0x64,0x76,0x44,0x3b,0x31,0x34,0x32,0x2f,0x2b,0x2c,0x32,0x2e,0x2e +,0x2d,0x2e,0x30,0x35,0x46,0x69,0xbc,0xbc,0xbb,0xb5,0xb5,0xb3,0xb7,0xad,0xb3,0xaf,0xb4,0xae,0xb2,0xaf,0xbf,0xbc,0xc4,0xc9,0x4f,0x3b,0x3e,0x3a,0x4e,0x2d,0x34,0x30 +,0x2f,0x2c,0x26,0x29,0x35,0x25,0x34,0x3d,0xc0,0x5f,0x52,0xd1,0xca,0xb8,0xbb,0xae,0xb7,0xaa,0xae,0xa7,0xb0,0xae,0xb6,0xba,0xbf,0x6e,0xbf,0x44,0x3c,0x2c,0x2c,0x3d +,0x39,0x48,0x29,0x4e,0x2e,0x35,0x38,0x26,0x30,0x2e,0x3f,0x4f,0xe0,0xbf,0xcf,0x5a,0xb8,0xbf,0xb7,0xb5,0xb4,0xa9,0xa9,0xb5,0xb5,0xbe,0xbc,0xbf,0xcc,0xdd,0x68,0x74 +,0x6f,0x45,0x60,0x38,0x56,0x48,0x2e,0x35,0x27,0x33,0x28,0x39,0x39,0x35,0xe1,0x54,0x51,0x58,0x4e,0xbd,0xd9,0xbe,0xb3,0xc0,0xaa,0xba,0xbc,0xb6,0xb5,0xb6,0xc1,0xbe +,0xc2,0xc7,0xd1,0xdc,0xd1,0x4d,0x5e,0xfd,0x3b,0x4c,0x32,0x30,0x2c,0x2a,0x39,0x38,0x45,0x43,0x48,0x4a,0x48,0x5f,0xc6,0x4b,0xbc,0xb7,0xc1,0xbb,0xc1,0xaf,0xbe,0xbe +,0xba,0xca,0xb2,0xc3,0x6e,0xc1,0x65,0xc5,0x59,0x4f,0x4c,0x33,0x4e,0x40,0x33,0x3b,0x2f,0x43,0x3c,0x46,0x65,0x37,0x52,0x40,0xee,0xf0,0xed,0xcb,0xde,0xbe,0xbc,0xbd +,0xb7,0xfb,0xbd,0xc8,0xb9,0xc3,0xf2,0xc3,0xca,0xc5,0xca,0xe8,0xdc,0x5b,0x3d,0xce,0x2f,0x4b,0x2f,0x43,0x3f,0x36,0xd9,0x3f,0x46,0x3c,0x4c,0x67,0x60,0xce,0xbd,0x69 +,0xbe,0xdd,0xbd,0xd3,0xc4,0xbe,0xd4,0xbe,0xcc,0xcb,0xba,0xea,0x5e,0xdd,0x7c,0xbd,0x55,0xfe,0x4d,0x3c,0x4a,0x46,0x4b,0x3f,0x3c,0x5d,0x41,0x53,0x5d,0x42,0x5e,0x4a +,0xe0,0xc7,0x5b,0xbe,0xcb,0xc0,0xfc,0x60,0xbf,0x6f,0xba,0xce,0xc6,0xd3,0x5f,0xdb,0xdd,0xde,0xd6,0x44,0xd1,0x46,0x4b,0x67,0x35,0x6e,0x55,0xed,0x4f,0x4c,0x78,0x57 +,0x53,0xdf,0x48,0xe5,0x4f,0xdd,0xba,0x51,0xbb,0x66,0xc8,0xbe,0x4d,0xc1,0x4f,0xd7,0xce,0x5b,0xcc,0x76,0xfb,0xd6,0x4f,0xd9,0x49,0x48,0x4a,0x41,0xcd,0x3f,0x64,0x51 +,0x43,0xe5,0x49,0xcf,0xc6,0x55,0xbd,0x5b,0xc1,0xbe,0x52,0xba,0x58,0xd2,0xd2,0x5c,0xc4,0x4a,0xf7,0xe3,0x42,0xc5,0x4f,0x7b,0xf0,0x35,0xeb,0x3a,0xe6,0x50,0x49,0xbf +,0x49,0xc3,0x46,0x7a,0xd9,0x5f,0xd6,0xd7,0xdb,0xc3,0x54,0xca,0x65,0x49,0xba,0x40,0xba,0x5b,0x6c,0x76,0x44,0xc3,0x5f,0x6a,0xcb,0x4b,0xd7,0x4f,0x48,0xbe,0x49,0xd4 +,0x44,0x5e,0xc6,0x3f,0xe3,0x55,0x55,0xdc,0x42,0xc0,0xdd,0x5b,0xbc,0xeb,0xbd,0x6b,0xd4,0xc7,0x5d,0xc7,0x5d,0x6a,0x6a,0x4d,0x74,0x5c,0x4d,0xec,0x3c,0x5f,0x7a,0x4f +,0xf7,0x3e,0xcb,0x7e,0x6c,0xd4,0x49,0xc5,0x6e,0x5f,0xd8,0x5a,0xc2,0xde,0xcd,0xbe,0x65,0xce,0x52,0x69,0xdd,0x4b,0xcb,0x4d,0x57,0x69,0x6b,0xcf,0x50,0x4c,0xd8,0x5d +,0xd3,0x43,0x61,0xcc,0x49,0xd5,0x4f,0xcb,0x65,0x4b,0x6a,0x68,0xf8,0x7c,0x71,0xbe,0xda,0xcc,0xc3,0x47,0xc3,0x62,0xcb,0x51,0x43,0xc6,0x49,0xfc,0x67,0x57,0xdd,0x4e +,0x65,0xf8,0x46,0xe3,0x4b,0x70,0x76,0x4a,0xbb,0x58,0xcb,0xd7,0x56,0xb7,0x3d,0xd1,0xce,0x67,0xbf,0x48,0xcb,0x78,0x4f,0xe1,0x3c,0x5d,0x6f,0x48,0xe5,0x39,0xde,0xf1 +,0xcf,0xbe,0x43,0xc9,0x5d,0x4f,0xd8,0x4b,0xce,0x5e,0xd9,0xb7,0x7e,0xbe,0xee,0xfc,0x7b,0x5f,0xcb,0xd7,0xf1,0xd2,0x4f,0xc9,0x49,0x3e,0xef,0x3d,0xd2,0x34,0x5e,0x58 +,0x41,0xe2,0x45,0xde,0xd2,0xdd,0xdb,0x4d,0x67,0xeb,0x5c,0xd1,0xf8,0xc4,0xb8,0xcc,0xc2,0xd0,0xdc,0xcb,0x5c,0xc1,0x79,0xd8,0xcb,0x44,0xce,0x53,0x4e,0x51,0x37,0x6c +,0x3d,0x4a,0x56,0x3f,0xc6,0x43,0x51,0xe4,0x5e,0xe5,0x4d,0x65,0xf6,0x5e,0xbf,0x53,0xbe,0xba,0xf8,0xb4,0x50,0xb8,0xcc,0xef,0xb9,0x4f,0xcc,0xeb,0x4f,0xce,0x3c,0x59 +,0x52,0x3c,0xe5,0x33,0x48,0x53,0x43,0x48,0x4d,0xec,0x76,0x4e,0xc9,0x53,0x5c,0xdd,0x5a,0xbc,0x61,0xb4,0xdc,0xc8,0xb5,0xfc,0xbb,0xcc,0xd1,0xce,0x5f,0xc4,0x44,0x4a +,0xd4,0x41,0xdf,0x37,0x41,0x44,0x3c,0x4d,0x35,0x46,0xce,0x5a,0xd1,0x4f,0xef,0xbe,0x51,0xc6,0x52,0xcc,0xc1,0x79,0xb5,0xe9,0xbf,0xbc,0x57,0xb8,0x54,0xca,0xc8,0x48 +,0xbe,0x4a,0xec,0x4a,0x3d,0xcf,0x38,0xf2,0x40,0x34,0xcf,0x34,0xf1,0x54,0x49,0xc4,0x3f,0xcb,0x6d,0x52,0xd4,0x55,0xbb,0xcb,0xf3,0xb7,0xd9,0xb7,0xc5,0xfa,0xba,0x67 +,0xc5,0x76,0x66,0xd1,0x39,0x70,0x7c,0x41,0xe9,0x35,0x53,0x3e,0x3e,0xfb,0x39,0xcc,0x42,0x4f,0xcf,0x3e,0xcc,0xee,0x4f,0xbf,0x4e,0xbd,0xd9,0xd9,0xae,0x6b,0xba,0xbd +,0xeb,0xb5,0xde,0xbe,0xc6,0x45,0xc7,0x3f,0xde,0x3f,0x3c,0x5c,0x34,0x54,0x39,0x38,0x4d,0x2f,0xe4,0x5f,0x46,0xca,0x37,0xcc,0xfa,0xc9,0xbc,0x6a,0xb2,0xcc,0xca,0xb2 +,0xcd,0xba,0xcd,0xc5,0xbd,0x5d,0xc3,0x54,0x53,0xde,0x38,0x5d,0x4d,0x39,0x66,0x35,0x6c,0x3a,0x3f,0xd3,0x37,0xc5,0x58,0x52,0xca,0x40,0xc5,0xdf,0xe6,0xc6,0x52,0xb9 +,0xd2,0xd8,0xb5,0x5a,0xb9,0xd6,0xe4,0xba,0x5c,0xbd,0x47,0xcd,0x79,0x47,0xd3,0x37,0x51,0x51,0x3c,0x4f,0x37,0x4a,0x4f,0x3a,0xbc,0x4d,0x6d,0xe4,0x3e,0xbf,0x49,0xc6 +,0xcb,0x57,0xb5,0xdf,0xc2,0xcf,0xe2,0xc4,0x53,0xc5,0xd5,0x48,0xbf,0x4c,0xd4,0xdf,0x49,0xc8,0x40,0x4c,0x49,0x46,0xe7,0x3f,0x68,0xfa,0x3d,0xcc,0x44,0xcd,0x5d,0x4f +,0xca,0x45,0xcc,0xde,0x6e,0xc2,0xcc,0xc9,0xc3,0x48,0xc8,0x5f,0xb8,0x5e,0x3f,0xb2,0x43,0xbe,0xef,0x4f,0xbd,0x3d,0x6f,0x4a,0x37,0xf5,0x38,0x5c,0x5f,0x3e,0xcc,0x3b +,0x5b,0x55,0x5d,0xbf,0x3c,0xbd,0xc9,0xd2,0xbc,0xde,0xc2,0xd8,0xe3,0xbd,0xec,0xca,0xed,0xf4,0xcf,0x4b,0xd5,0xd9,0xdc,0xbc,0x4e,0x3a,0xce,0x39,0xa1,0x2f,0x38,0xb8 +,0x3e,0xc6,0x2e,0x5c,0x34,0xbb,0x44,0x41,0xde,0xca,0x61,0x3e,0xcf,0x40,0xbc,0x5e,0xce,0x79,0xbb,0xdf,0x3c,0xb7,0x3b,0xbb,0x3f,0x55,0xbe,0x38,0x6b,0x43,0x40,0xd3 +,0xe8,0x3c,0xd0,0xb3,0x2f,0x33,0xeb,0x41,0xda,0xaa,0x45,0x33,0xb8,0x2d,0xab,0x38,0x58,0xc8,0xde,0xca,0x42,0xb9,0x30,0x69,0xa4,0x33,0xad,0xea,0xb3,0xaf,0x2b,0x9d +,0x27,0xa9,0x24,0x4f,0xb5,0x3b,0xc4,0x38,0xbc,0xca,0x2e,0x54,0x6f,0x40,0xd6,0x38,0xba,0x40,0xd4,0x47,0xb7,0xc9,0xb6,0xfd,0xd8,0xf2,0x4c,0x34,0x6e,0xae,0x2d,0xb8 +,0xa5,0xdd,0xd4,0xc4,0xcb,0x3b,0x2f,0xd6,0xd1,0x5b,0x39,0x44,0xc8,0x6c,0x39,0xbe,0xe4,0x41,0x3b,0x42,0xcc,0xe7,0x66,0x5a,0xbd,0xb9,0x36,0xd3,0x4e,0xbc,0x3f,0xc2 +,0x52,0x41,0xb8,0x30,0xc6,0xe0,0x7b,0xba,0x42,0xfb,0xac,0x62,0x51,0x48,0xee,0x3c,0xb6,0x33,0xb8,0xbd,0x2c,0x45,0xde,0x3c,0xb9,0x2f,0x46,0xb1,0x2d,0xc2,0x3d,0xd2 +,0x41,0x44,0x75,0xb0,0x4b,0xc2,0xcf,0xed,0xeb,0xe7,0x46,0xa0,0x37,0xac,0x1a,0xd3,0x8d,0x29,0x98,0x24,0xad,0x2b,0x1f,0xb6,0x46,0x37,0x37,0x2c,0xf1,0x48,0x3f,0xdf +,0xc1,0xdd,0x36,0x69,0x3e,0xa7,0xe8,0x59,0xb1,0xb7,0xcf,0x6d,0x4d,0xa3,0x51,0x4e,0x48,0xd3,0xc9,0x3a,0xd5,0x77,0xcb,0x2c,0x57,0xa9,0xc4,0xe1,0x42,0xf9,0x51,0x34 +,0x3e,0x42,0xc1,0x2d,0x35,0x4f,0x4e,0xce,0x5c,0x6f,0xb8,0x6d,0xc4,0xad,0xbe,0xb7,0xc4,0xb8,0xbd,0xfb,0xd3,0x4e,0xc6,0xcf,0x3d,0x4d,0x3e,0x45,0x5a,0x38,0x4e,0x45 +,0x59,0x5a,0x3b,0x44,0x3b,0xd5,0x39,0xc7,0xe1,0x72,0xc8,0x40,0xb0,0xcf,0xcc,0xb7,0xb6,0xb6,0xc4,0xc7,0xbf,0xc9,0x50,0xba,0xfa,0xe6,0xbf,0x3c,0x64,0x3f,0x42,0x4c +,0x2f,0x3e,0x3d,0x3a,0xe9,0x35,0x35,0x4f,0x2e,0xf0,0xe4,0x44,0xbe,0x5e,0xc0,0xb5,0x5f,0xbd,0xca,0xad,0xb7,0xc3,0xa5,0xc7,0xb8,0xba,0xdd,0xb2,0x56,0xde,0xbd,0x33 +,0x26,0x1c,0x4e,0xba,0x3a,0x1f,0x57,0xc9,0x15,0x11,0x29,0xbc,0x96,0xa6,0x19,0x24,0x33,0x95,0x88,0x95,0x14,0x2a,0x85,0x87,0x98,0xa3,0x33,0x4f,0xa0,0x1e,0x05,0x1f +,0x9d,0x0c,0x0c,0x0a,0x0f,0x9e,0x9a,0x0e,0x14,0x9c,0x8f,0x8c,0x90,0xad,0x13,0xa4,0x8d,0x8c,0x8e,0xa5,0xda,0xb4,0xbf,0x13,0x16,0xd0,0x7e,0x0f,0x0c,0x0f,0x34,0xa3 +,0xbd,0x1d,0x1b,0x3f,0x98,0x8f,0xaa,0x2e,0x2d,0xb4,0x98,0xa1,0xaf,0xc2,0x34,0xb9,0x9b,0xb1,0x1f,0x9f,0xa2,0x1e,0x0e,0x14,0xb0,0x9c,0xd3,0x0c,0x0c,0x5e,0xb8,0x96 +,0x9e,0x09,0x18,0x8b,0x89,0xb6,0xb0,0xa7,0x9f,0x9d,0x48,0x13,0x25,0x93,0xc7,0x16,0x0a,0x0d,0x9d,0x8d,0x21,0x08,0x52,0x8f,0x8b,0xa2,0x1e,0x18,0x3a,0x99,0x98,0xa7 +,0x39,0xb7,0xab,0x42,0x17,0x20,0x9d,0x92,0x30,0x0d,0x17,0xae,0x94,0x99,0xd3,0x12,0x5d,0x8f,0x92,0x44,0x1f,0x11,0x1d,0x4e,0x28,0x29,0x2a,0x52,0x2d,0xae,0x55,0x26 +,0x96,0x8d,0xc8,0x1c,0x51,0x96,0x8b,0x98,0x18,0x14,0xc2,0xa0,0x95,0x7b,0x0d,0x12,0xbd,0xa2,0x3d,0x27,0x55,0xbf,0x21,0x1a,0x0e,0x34,0x99,0xaf,0x7a,0x0d,0x1e,0x8d +,0x88,0xa7,0x16,0xc2,0x89,0x88,0x9d,0x1b,0x1d,0x3c,0x40,0xb6,0x29,0x1e,0x3d,0x4f,0x1a,0x07,0x0f,0x55,0x9d,0x51,0x0c,0x1b,0x9a,0x8b,0x8a,0x9a,0x2d,0xaa,0x8a,0x8a +,0x9f,0x2d,0x3f,0x61,0x48,0x1a,0x14,0x38,0x2f,0x18,0x1a,0x18,0x1a,0xc9,0x9b,0x20,0x12,0x24,0xae,0x89,0x96,0x38,0x3c,0x9c,0x8e,0x90,0x9a,0xbd,0x3b,0xa0,0xa1,0x36 +,0x47,0xb3,0x4e,0x11,0x09,0x08,0x19,0x4a,0x3f,0x1b,0x07,0x12,0xa1,0x8e,0x9d,0x3c,0xaa,0x89,0x85,0x8f,0xa5,0xb1,0xa1,0x9f,0xa8,0x71,0x38,0xbd,0x65,0x10,0x06,0x08 +,0x18,0x5b,0x1b,0x05,0x0b,0x1d,0xa1,0x8d,0xab,0xc2,0xa8,0x8a,0x86,0x8c,0x95,0x9b,0x9e,0xb0,0x49,0x46,0xa6,0xb7,0x2a,0x16,0x0d,0x11,0x30,0x1e,0x19,0x0b,0x08,0x20 +,0xbf,0xb8,0x3f,0x3c,0xa8,0x91,0x88,0x8c,0x94,0x8e,0x9b,0x9d,0x9e,0x9b,0x99,0xa3,0x28,0x08,0x0a,0x0d,0x1a,0x3a,0x0e,0x06,0x09,0x2c,0xae,0xfc,0xb6,0xc4,0x9d,0x8c +,0x8d,0x8c,0x95,0x9b,0x90,0x9f,0xf1,0xae,0x8f,0xaa,0x1c,0x0c,0x0a,0x0d,0x19,0x2c,0x07,0x09,0x1c,0xaf,0x9d,0xbb,0xaa,0xa7,0xa9,0x8c,0x8e,0x93,0x99,0x9b,0xa5,0x19 +,0x37,0x9c,0xa4,0xdf,0x11,0x0d,0x13,0x0f,0xa0,0x1f,0x0d,0x27,0x28,0xbf,0xef,0xad,0xa1,0x3f,0x99,0x8f,0xa5,0x97,0x99,0x9d,0xdc,0xdb,0x9d,0xaa,0xaf,0x24,0x08,0x0b +,0x07,0xac,0x5a,0x12,0xe3,0x1b,0x26,0xbe,0x99,0x97,0x48,0x94,0x8f,0xb5,0x93,0x99,0x9f,0xb2,0x4c,0xbe,0x29,0xae,0xb0,0x0d,0x0f,0x05,0x38,0x25,0x0e,0xa9,0x1c,0x21 +,0xa6,0x9b,0x98,0xaf,0x90,0x92,0x3a,0x8f,0x9a,0xbd,0xa0,0x4b,0x1c,0x18,0xba,0xa4,0x15,0x1b,0x0b,0x22,0xe5,0x16,0x92,0x35,0x20,0xb1,0x34,0xae,0xe0,0x9a,0x97,0x2a +,0x9b,0xa2,0xc2,0x97,0xb1,0x50,0x2f,0xbf,0xb0,0x1c,0x3c,0x08,0x18,0xbd,0x0e,0x99,0xb9,0x27,0xa6,0x21,0xd1,0xa6,0xa5,0x91,0x3f,0xa5,0x9e,0xcd,0x92,0x9a,0xc8,0x39 +,0x26,0x4a,0x1a,0x32,0x15,0x0d,0xae,0x09,0x42,0xa8,0x12,0xa9,0xb8,0x67,0x9e,0xa2,0x8b,0xad,0xa8,0x8c,0x37,0x9d,0x93,0x7e,0x2c,0x1a,0x27,0x19,0x1f,0x47,0x08,0xb6 +,0x21,0x17,0x92,0x23,0xd1,0xad,0x2b,0x47,0x3b,0x9b,0x9b,0xd4,0x92,0x62,0xc5,0x8d,0xa9,0xe0,0xaf,0x3e,0x3a,0x23,0xd7,0x0b,0x18,0xa9,0x09,0xaa,0xcc,0x1d,0xa2,0x46 +,0x35,0x2f,0xb3,0x92,0x3b,0xa6,0xa4,0x2e,0x98,0x8f,0xad,0xab,0xde,0x3b,0x26,0x25,0x2e,0x0c,0xa5,0x17,0x12,0x9d,0x15,0x3b,0xa0,0x43,0xd8,0xcb,0x91,0xa3,0xc2,0x8f +,0x68,0xbb,0x95,0xa9,0x3c,0xd8,0x20,0x18,0x18,0x52,0x0f,0x19,0x99,0x0e,0xb2,0x9c,0x20,0xa0,0xa9,0x3e,0x2a,0x57,0x9b,0x3c,0x9c,0x98,0x2b,0xa1,0x98,0xae,0xba,0xac +,0x3c,0x23,0x2d,0x34,0x0a,0x58,0xbf,0x0b,0x9e,0x36,0x19,0x9e,0x66,0x22,0x2c,0xa4,0xa7,0x37,0x94,0xaa,0x2f,0x92,0x98,0xac,0x9d,0xa6,0x40,0x2d,0x36,0x25,0x0c,0xa1 +,0x25,0x09,0x9b,0x1a,0x1a,0xa3,0x49,0x24,0x60,0x9d,0xa5,0xb8,0x8f,0xae,0xec,0x96,0xb6,0xcd,0xb0,0x49,0x2b,0x2b,0x30,0x1e,0x0f,0x96,0x1a,0x18,0x8d,0x1e,0x39,0x96 +,0x2c,0x1c,0xd5,0xb7,0xd2,0xc0,0x94,0x3a,0xdd,0x92,0xae,0xc3,0x9f,0xc5,0x2f,0x29,0x30,0x19,0x0f,0x97,0x13,0x1a,0x92,0x13,0x49,0x96,0x1e,0x2b,0xb7,0xad,0xe7,0xcf +,0x96,0x2e,0xa9,0x8c,0xac,0xa4,0x9b,0xcf,0x4e,0x2b,0x38,0x14,0x13,0x9b,0x09,0x1d,0x9d,0x0b,0xcf,0xa4,0x1e,0x34,0xad,0x9b,0xb5,0x9f,0x91,0x3c,0x9e,0x99,0x4e,0xb5 +,0xb7,0x43,0x3e,0x2f,0x3d,0x12,0x2b,0x96,0x0c,0xae,0x9d,0x11,0xae,0xbe,0x17,0x25,0xb8,0xba,0x52,0xac,0xa0,0x37,0x9d,0x98,0xbf,0xa8,0xa3,0xfd,0x3d,0x2e,0x3a,0x0f +,0x3f,0x9f,0x0a,0xa3,0xae,0x14,0x9d,0xbc,0x1c,0xe6,0xb6,0xda,0x46,0xaf,0xae,0x39,0x97,0x9b,0xbf,0x9f,0xa8,0xd5,0x49,0x2d,0x2e,0x0b,0x3e,0x52,0x05,0x9f,0x32,0x13 +,0x99,0xd3,0x23,0xac,0x9a,0xa4,0xa8,0x94,0xb1,0xbc,0x95,0xb7,0x62,0xad,0xc3,0x2e,0x3e,0x21,0x1e,0x0e,0xb4,0x34,0x0c,0x93,0x2b,0x1a,0x99,0x28,0x1a,0xae,0xac,0xbf +,0xbf,0x9d,0xd1,0xaf,0x92,0xaa,0xbb,0x9d,0xb2,0x3f,0x48,0x28,0x29,0x10,0xa5,0x22,0x0f,0x93,0x20,0x29,0x99,0x1f,0x21,0xaf,0xcc,0x43,0xd7,0xa8,0x4b,0xa8,0x97,0xae +,0xae,0x9a,0xb6,0xef,0x5f,0x27,0x1e,0x10,0xad,0x11,0x13,0x95,0x19,0x35,0x99,0x21,0x49,0x9b,0xa3,0xa3,0xab,0x9d,0xec,0xab,0xa1,0x48,0xb7,0xad,0x35,0x3c,0x25,0x1f +,0x16,0x1b,0xa0,0x0e,0xd7,0x97,0x18,0xb6,0xa6,0x1a,0x71,0x9e,0x6f,0xb4,0xaf,0xb4,0xc2,0x9f,0xa2,0xb1,0xab,0xa5,0x5b,0x56,0x26,0x38,0x16,0x21,0xa1,0x0a,0xae,0x9e +,0x12,0xab,0xbe,0x14,0xcb,0xaa,0x35,0xea,0xa8,0xb9,0xc1,0x95,0xa2,0xa8,0x98,0xa2,0xb9,0xc9,0x2b,0x31,0x0d,0x2a,0xfa,0x05,0xa1,0xc6,0x0e,0xa8,0xc7,0x1c,0xa7,0x9b +,0xca,0xaf,0x9d,0xb0,0xbe,0x99,0xb1,0xbd,0xa3,0xc0,0x35,0x44,0x28,0x2d,0x0e,0xb5,0x68,0x09,0x8e,0x38,0x13,0x9c,0x35,0x1e,0xa4,0xaf,0x43,0xc8,0xa1,0xbe,0xb2,0x98 +,0xa9,0xa8,0xa3,0xb3,0x50,0x36,0x2a,0x2e,0x0c,0xb6,0x35,0x0b,0x91,0x2b,0x15,0x9c,0x2d,0x1d,0xa3,0xc8,0x35,0xbb,0xa0,0xb2,0xac,0x92,0xa2,0xa3,0x97,0xaf,0xcb,0x4f +,0x26,0x20,0x0b,0xcd,0x1a,0x0a,0x93,0x16,0x18,0x98,0x28,0x3f,0x99,0xb8,0xad,0xad,0xa2,0xa5,0xb8,0x9a,0xaf,0xaf,0xa9,0x72,0x4d,0x2b,0x28,0x25,0x0d,0xa0,0x1a,0x10 +,0x8f,0x12,0x23,0x99,0x21,0x3e,0x9a,0x7e,0xbd,0xab,0xa3,0xac,0xa3,0x9c,0xa8,0xa9,0xaa,0xbc,0x49,0x26,0x2b,0x24,0x0c,0xa1,0x17,0x11,0x95,0x16,0x1f,0x9c,0x1f,0x2d +,0x9e,0xeb,0xcc,0xad,0x99,0xb2,0xa2,0x93,0xa8,0xaa,0x97,0xbf,0x48,0x3d,0x27,0x16,0x0f,0xa8,0x0a,0x1b,0x9a,0x0d,0x2f,0x99,0x1c,0xc9,0x94,0xbe,0xae,0x9d,0xa0,0xbc +,0x9d,0xa4,0xb8,0xab,0xb3,0x38,0x49,0x22,0x30,0x16,0x1a,0x9c,0x08,0xf5,0x9c,0x0b,0xa8,0xa6,0x1a,0xb0,0xa1,0x6e,0xb0,0xa0,0xaa,0xaa,0x9d,0xaa,0xa7,0xa7,0xb8,0xd1 +,0x5d,0x1d,0x3a,0x11,0x1a,0x9c,0x05,0xc9,0x9c,0x09,0xa5,0xa9,0x10,0xaf,0xa2,0x39,0xad,0xa2,0xa3,0xa7,0x99,0x9a,0x9f,0x9d,0xa3,0xb9,0x60,0x26,0x2d,0x0b,0x2f,0x59 +,0x03,0x9f,0x3f,0x0c,0x9b,0x62,0x18,0x9e,0xa7,0xf7,0xa9,0x9e,0xaf,0xa9,0x9b,0xab,0xa0,0xab,0xb9,0xc0,0x33,0x20,0x3f,0x0b,0xaa,0x51,0x08,0x8f,0x2e,0x12,0x95,0x4f +,0x18,0x9a,0xde,0x47,0xb6,0xab,0xb1,0xe1,0xa0,0xac,0xde,0xa9,0xb7,0x36,0xd6,0x27,0x2b,0x14,0x9d,0x29,0x12,0x8d,0x1d,0x1b,0x96,0x20,0x1f,0x9f,0x48,0x6a,0xb8,0xa4 +,0xba,0xae,0x9a,0xab,0xaf,0xa6,0xcb,0x61,0x29,0x33,0x10,0x1c,0x9e,0x0a,0xcc,0xa2,0x11,0xb7,0xa4,0x21,0xac,0xae,0xb9,0xb0,0xc0,0xa0,0xc0,0xaa,0xaa,0xa6,0x48,0xa3 +,0x5b,0x38,0x2d,0x28,0x0f,0x6a,0xaa,0x09,0x95,0x5b,0x13,0x9a,0xb9,0x1c,0x98,0xca,0x5e,0xa9,0xf2,0xaf,0xfb,0xa3,0xe4,0xab,0xbc,0xbf,0xbe,0x37,0x28,0x2c,0x13,0xa0 +,0x44,0x0f,0x8f,0x1e,0x22,0x97,0x31,0x2f,0xa3,0xc3,0x4e,0xbc,0xa8,0x40,0xb1,0x9f,0x69,0xa2,0xb7,0x4f,0xe1,0x1f,0x28,0x19,0x17,0xa5,0x10,0x25,0x96,0x19,0xc4,0x96 +,0x29,0xad,0x9b,0xad,0xb4,0xbb,0xa4,0x54,0xab,0xa3,0xdd,0xcc,0xc2,0x5e,0x3b,0x20,0x37,0x0e,0x2a,0x9f,0x09,0xa6,0x9f,0x0e,0x9d,0x9f,0x1b,0x9f,0xa7,0xd0,0xbe,0xa6 +,0xa7,0x49,0x9e,0xb6,0xe2,0xa9,0xbb,0x4d,0x3c,0x20,0x28,0x12,0xb4,0x4e,0x0c,0x96,0x4c,0x14,0x92,0x4e,0x1c,0x99,0xba,0xc1,0xa9,0xa8,0xbd,0xb7,0x9e,0xaf,0xb9,0xa7 +,0x5e,0x36,0x2b,0x22,0x16,0x15,0xa6,0x0f,0x1f,0x94,0x17,0x3f,0x92,0x22,0xbe,0x95,0xd0,0xac,0xa2,0xb2,0xc2,0xa3,0xbc,0xaf,0xbb,0xb9,0x67,0x33,0x2c,0x1f,0x14,0x26 +,0xb6,0x0c,0xc3,0x9e,0x12,0xa7,0x9c,0x19,0x9e,0x9d,0x47,0x9c,0xb6,0xb9,0xa8,0xca,0xaa,0xae,0x76,0xa8,0x44,0x2b,0x2e,0x1f,0x0f,0xb1,0x34,0x0c,0x98,0x3f,0x15,0x99 +,0x5b,0x1e,0x9b,0xb3,0xba,0xa5,0xaa,0xb0,0xa9,0xa4,0xa5,0xb7,0xad,0xbe,0x2a,0x3a,0x1c,0x19,0x10,0xab,0x17,0x15,0x8e,0x1d,0x2c,0x8e,0x26,0x47,0x8f,0x46,0xa4,0xa0 +,0xf5,0xaf,0xaa,0xc3,0xb4,0xc5,0xcf,0x49,0x36,0x22,0x1f,0x11,0x19,0x9e,0x0c,0xdf,0x90,0x11,0xac,0x93,0x1c,0xa5,0x94,0x5a,0xa3,0xa5,0xfc,0xb7,0xb0,0xdd,0xb7,0x75 +,0xaf,0x32,0x38,0x25,0x20,0x10,0xd2,0xb5,0x0a,0x97,0xbd,0x12,0x9c,0xb0,0x19,0x9a,0xa3,0x50,0x9c,0xab,0xc7,0xa6,0xab,0xb6,0xad,0xbc,0xca,0x2e,0x2f,0x1a,0x1f,0x0e +,0xbd,0x2f,0x0e,0x90,0x51,0x1c,0x92,0xd9,0x27,0x92,0xab,0xbc,0xa2,0xae,0xd6,0xbd,0xb3,0xb6,0x3d,0xb3,0x5f,0x23,0x27,0x29,0x10,0x15,0x95,0x0b,0x59,0x8c,0x11,0xac +,0x91,0x1d,0xa6,0x91,0x4f,0xa7,0xa3,0xcf,0x48,0xaf,0xd5,0x54,0xcf,0xbd,0x2a,0x32,0x23,0x1f,0x15,0x2d,0xa3,0x0b,0xa1,0x9c,0x0f,0x9b,0xa2,0x19,0x9b,0x9c,0x4e,0xa1 +,0x9d,0xc3,0xba,0xa1,0xb6,0xcf,0xb2,0xc8,0x26,0x2a,0x1f,0x1b,0x0d,0xac,0x22,0x0e,0x8d,0x2a,0x21,0x91,0x3a,0x2e,0x92,0xb3,0xb7,0x9e,0xab,0xd1,0xb1,0xb7,0xb3,0xd5 +,0xc8,0xbc,0x27,0x23,0x25,0x1b,0x0d,0x9b,0x1a,0x15,0x89,0x1d,0x2a,0x8c,0x28,0x55,0x8e,0xd4,0xcb,0x9f,0xb5,0x30,0xb9,0xad,0x39,0xce,0xa9,0x27,0x2e,0x2d,0x1f,0x13 +,0x29,0xa3,0x0b,0xa7,0x97,0x0f,0x9d,0x9c,0x1e,0x9b,0x9d,0xbd,0xa9,0xa1,0xa7,0x3f,0xa7,0xac,0x42,0xbd,0xb7,0x21,0x2e,0x1d,0x1c,0x0d,0x39,0xd2,0x0a,0x92,0xb2,0x17 +,0x91,0xad,0x26,0x95,0xa1,0xd4,0xa3,0x9e,0x73,0xdb,0xa4,0xdb,0xe6,0xb3,0xcf,0x2a,0x2b,0x24,0x1a,0x0c,0xa5,0x24,0x0e,0x8c,0x33,0x1b,0x8e,0xd3,0x33,0x92,0xa8,0xc4 +,0xb3,0x9f,0x43,0x3e,0xa7,0xca,0x32,0xab,0x66,0x1f,0x2f,0x29,0x14,0x13,0x98,0x10,0x2a,0x8c,0x18,0xea,0x8f,0x27,0xb3,0x92,0x6b,0xa9,0xa8,0xac,0x6c,0xcf,0xb1,0x6d +,0x3a,0xb6,0x2c,0x25,0x25,0x20,0x0f,0x17,0x98,0x0d,0xce,0x8b,0x12,0xa9,0x8f,0x1e,0xa1,0x98,0xcd,0xad,0xa5,0xac,0x48,0xb3,0xb2,0x5e,0x6b,0xb7,0x27,0x28,0x20,0x1e +,0x0b,0x3f,0xae,0x09,0x95,0xa0,0x11,0x93,0xa3,0x22,0x94,0x9f,0xb5,0xb9,0xa2,0xb5,0x2d,0xa4,0xb4,0x2c,0xad,0xbb,0x1e,0x3e,0x22,0x1e,0x0d,0xab,0x44,0x0c,0x8c,0x43 +,0x16,0x8f,0x68,0x2f,0x95,0xa8,0xb8,0xb1,0x9c,0x55,0x5c,0xa1,0x4e,0x3e,0xab,0x38,0x29,0x2b,0x1e,0x1c,0x0c,0x9e,0x27,0x11,0x8b,0x3b,0x1c,0x8d,0xdc,0x3c,0x94,0xa5 +,0xd3,0xad,0x9e,0x39,0xbc,0xad,0xe0,0x3f,0xbc,0x39,0x26,0x1d,0x26,0x10,0x11,0x97,0x0d,0x39,0x8d,0x18,0xb6,0x91,0x2b,0xa5,0x97,0xaf,0xb0,0xaf,0xa2,0x3e,0xba,0xa5 +,0x56,0x48,0xa7,0x2d,0x28,0x26,0x20,0x0f,0x1e,0xa2,0x0c,0xc6,0x98,0x14,0xb4,0x9b,0x29,0xa7,0x9b,0xbb,0xae,0xa6,0xaa,0xb8,0xb7,0xac,0xb8,0x43,0xae,0x4c,0x25,0x25 +,0x2f,0x0b,0x3e,0xa9,0x09,0x9b,0x9d,0x11,0x9e,0x9b,0x1d,0x9e,0x99,0x5c,0xbe,0x9e,0xbc,0x3b,0xa3,0xaf,0x33,0xbf,0xaf,0x1f,0x30,0x28,0x1b,0x0d,0xb1,0x4f,0x0c,0x90 +,0xb8,0x19,0x95,0xa0,0x27,0x9a,0x9b,0x52,0xad,0xa3,0x7e,0xba,0xb0,0xb8,0xc5,0x56,0xbd,0x36,0x22,0x21,0x1c,0x0c,0xad,0x29,0x0e,0x90,0x3d,0x18,0x92,0xb5,0x2a,0x95 +,0x9c,0x66,0xa7,0x9a,0x4d,0xb3,0xa1,0xc5,0x58,0xc6,0x73,0x2a,0x25,0x25,0x16,0x0f,0x9e,0x19,0x1a,0x8e,0x21,0x2b,0x91,0x3c,0x4c,0x97,0xaf,0xbc,0xac,0xa8,0x4d,0xb3 +,0xad,0xbf,0x4f,0xbf,0x4c,0x2e,0x2e,0x1f,0x16,0x18,0x9e,0x14,0x28,0x90,0x1b,0x60,0x92,0x39,0xd3,0x96,0xb2,0xee,0xa3,0xc7,0xe4,0xa6,0xd4,0xaa,0x4d,0xea,0xdb,0x2b +,0x21,0x21,0x0f,0x1a,0xa0,0x0c,0x46,0x92,0x16,0xb3,0x91,0x25,0xa4,0x95,0xb9,0xaa,0xae,0xa9,0xc2,0xb2,0xa8,0xc9,0x30,0xae,0x2c,0x26,0x26,0x1e,0x0f,0x1f,0x9f,0x0a +,0xc7,0x93,0x11,0xa6,0x93,0x1f,0xa2,0x97,0xc9,0xaf,0xa1,0xb8,0xb8,0xa0,0xc7,0xbd,0x6c,0xdb,0x39,0x32,0x1d,0x22,0x0f,0x27,0xaa,0x09,0xa6,0x9c,0x13,0x9c,0x9b,0x1f +,0x9c,0x9a,0x6d,0xaa,0xae,0xc0,0xaa,0xb3,0xae,0xb7,0x3b,0xaf,0x2e,0x2a,0x1e,0x1c,0x0f,0x28,0xc1,0x0b,0xa9,0x9e,0x18,0x9e,0x9b,0x29,0x9a,0x98,0xb5,0xaa,0xa3,0xae +,0xab,0xb3,0xb5,0xb6,0x2d,0xb9,0x2e,0x20,0x1c,0x1e,0x0d,0x24,0xbc,0x0a,0xa4,0x9d,0x18,0x9b,0x9b,0x27,0x99,0x96,0x67,0xa2,0xa0,0xc1,0xa2,0xb7,0xb6,0xb5,0x34,0xb8 +,0x2b,0x26,0x1e,0x1e,0x0e,0x34,0xcd,0x0a,0x9b,0xa8,0x15,0x95,0xa8,0x22,0x91,0xa2,0xc5,0xa1,0xac,0xab,0xab,0xac,0xae,0xbe,0x4e,0xd2,0x27,0x25,0x1b,0x1c,0x0d,0x3c +,0x59,0x0c,0x98,0xb3,0x1a,0x94,0xab,0x30,0x92,0x9d,0xb3,0xa2,0xa4,0xb0,0xae,0xb0,0xbd,0xcc,0x47,0x58,0x32,0x22,0x18,0x25,0x09,0x45,0xed,0x08,0x97,0xb8,0x19,0x94 +,0xa7,0x32,0x92,0x9e,0xac,0x9d,0xac,0xa3,0xa4,0xc3,0xa9,0xcc,0x2f,0xce,0x2b,0x1d,0x1b,0x1e,0x09,0xc9,0x3e,0x09,0x93,0xbb,0x17,0x93,0xa7,0x26,0x96,0x9f,0xbc,0xa7 +,0xa7,0xa5,0xad,0xb7,0xa1,0x4d,0x34,0xad,0x2b,0x1e,0x1e,0x23,0x09,0xba,0x48,0x0a,0x95,0xc1,0x18,0x9a,0xa4,0x25,0x96,0x9a,0xc9,0x9c,0xa3,0xb8,0x9f,0xc0,0xb8,0xbe +,0x2f,0xcc,0x38,0x1b,0x1a,0x1d,0x0b,0xba,0x26,0x0d,0x93,0x64,0x1a,0x90,0xa7,0x2a,0x90,0x9c,0xbd,0x9e,0x9d,0xb0,0xaf,0xa6,0xb0,0x2f,0x6c,0xc3,0x22,0x1f,0x1e,0x17 +,0x0b,0xa9,0x1b,0x0c,0x8d,0x2f,0x1b,0x8c,0xb8,0x33,0x8f,0xa1,0xb8,0x9a,0xa1,0xab,0xa9,0xb9,0xa8,0x36,0x3a,0xb5,0x27,0x1a,0x21,0x18,0x0c,0xa9,0x1c,0x0f,0x8f,0x2e +,0x1f,0x8f,0xfd,0x38,0x91,0xac,0xc7,0x9c,0xa6,0xca,0xa8,0xb0,0xb1,0x4e,0xd5,0xc4,0x22,0x21,0x23,0x14,0x0f,0x9f,0x18,0x13,0x8c,0x26,0x29,0x8e,0x4a,0x47,0x8f,0xaf +,0x5a,0x98,0xaf,0xbb,0x9f,0x47,0xb1,0x38,0x52,0xb3,0x1f,0x1b,0x25,0x17,0x14,0xa9,0x13,0x1f,0x8e,0x1d,0x32,0x8e,0x2a,0xea,0x8e,0xa6,0xc9,0x9b,0x9d,0xcb,0xa3,0xa7 +,0xed,0x4c,0xd3,0x33,0x1b,0x1c,0x21,0x0c,0x1c,0xab,0x0c,0x2d,0x8f,0x15,0x49,0x90,0x28,0xc9,0x8e,0xb9,0xd9,0x9d,0x9d,0xe8,0xa6,0xaa,0xed,0xc9,0xa5,0xb1,0x1b,0x37 +,0x19,0x12,0x1d,0x96,0x06,0xeb,0xa2,0x00,0x1e,0x1a,0x48,0x32,0xa3,0xbd,0x28,0x86,0x8f,0x97,0x8d,0x8c,0x9f,0x9f,0x86,0xe1,0x19,0x8f,0x2d,0x0d,0x99,0x0b,0x1b,0x81 +,0x90,0x51,0x8b,0xaf,0x10,0x64,0x19,0x08,0x06,0x0b,0x06,0x0d,0x08,0x0b,0x07,0x0d,0x0e,0x05,0x10,0x06,0x09,0x0a,0xc9,0xfa,0x0f,0x8c,0x95,0x2c,0x86,0x8b,0xa2,0x86 +,0x86,0x87,0x82,0x82,0x83,0x84,0x81,0x84,0x82,0x86,0x88,0x90,0x26,0x3b,0xbb,0x1d,0x13,0x1d,0x04,0x17,0x29,0x00,0x13,0x0f,0x00,0x12,0xf9,0x0b,0x0b,0x07,0x03,0x13 +,0x02,0x07,0x05,0x11,0x21,0x12,0x1a,0x0f,0x0f,0x15,0x95,0xa9,0x90,0x80,0x8a,0x98,0x81,0x82,0x86,0x83,0x81,0x87,0x85,0x83,0x8d,0x85,0x94,0x8d,0x3c,0x9e,0xb9,0x33 +,0x74,0x13,0x0a,0x06,0x29,0x0a,0x08,0x2c,0x04,0x06,0x19,0x06,0x0b,0x18,0x12,0x08,0x0d,0x12,0x19,0x1b,0x0d,0x49,0x3b,0xaa,0xb3,0x13,0xbf,0xa7,0x30,0x26,0x8b,0x20 +,0xc9,0x82,0xbe,0x90,0x86,0x8c,0x87,0x85,0x83,0x88,0x88,0x89,0x85,0x85,0x89,0x88,0x4f,0x96,0x33,0x15,0x21,0x0f,0x0a,0x03,0x0d,0x01,0x16,0x0a,0x01,0x08,0x0e,0x0c +,0x0e,0xdd,0x0e,0x17,0x09,0x07,0x0b,0x2f,0xaf,0x25,0x55,0x2f,0xb5,0x31,0xbb,0xac,0xbd,0x80,0x95,0xb8,0x81,0x86,0x8f,0x84,0x82,0x8b,0x84,0x84,0x8b,0x8f,0x88,0xad +,0xa4,0xb0,0xa3,0x36,0x18,0x2c,0x14,0x17,0x09,0x06,0x04,0x20,0x0e,0x03,0x15,0x0e,0x0a,0x1e,0x09,0x06,0x07,0xd5,0x1d,0x1f,0xac,0x1b,0x16,0x0d,0x8f,0x2a,0x95,0x8f +,0x2f,0xac,0x93,0xf8,0x0e,0x86,0xa6,0x9b,0x92,0x2e,0x84,0x8a,0x91,0x8c,0x8c,0x85,0x84,0x80,0x8e,0x8d,0x8a,0xa0,0xb5,0xb9,0xce,0x52,0x11,0x05,0x08,0x00,0x06,0x15 +,0x04,0x07,0x16,0x00,0x10,0x1a,0x0c,0x9b,0x2d,0x0b,0x28,0x54,0x19,0x24,0xab,0x3e,0x39,0x4c,0xbb,0xab,0xac,0xc7,0x9f,0xd0,0x99,0xaf,0x7d,0x80,0x9a,0x8f,0x84,0x86 +,0x8f,0x92,0x82,0x87,0x97,0x35,0xbd,0xcc,0x8a,0xad,0x0f,0x30,0xa1,0x22,0x0f,0x22,0x08,0x07,0x16,0x1c,0x0e,0x40,0x18,0x02,0x2f,0x04,0x0e,0x1a,0x21,0xac,0x07,0x0e +,0x06,0x25,0x35,0xb2,0xd1,0x11,0xb6,0x0b,0xde,0x8d,0x76,0x92,0x61,0xa8,0x85,0x88,0x8d,0x83,0x80,0x98,0xa3,0x84,0x86,0x9c,0x8f,0x90,0x8c,0xa3,0x9c,0x1d,0x23,0xb2 +,0x97,0x19,0x0c,0x0b,0x0f,0xb8,0x01,0x21,0x14,0x0f,0x0d,0x36,0x13,0x11,0x17,0x0a,0x3c,0x1e,0x18,0x19,0x27,0x16,0x0e,0x24,0x92,0x48,0x20,0x07,0x0f,0x1d,0xbd,0x87 +,0x9d,0x84,0xa1,0x2c,0x8b,0x8a,0x80,0x92,0x8b,0x8f,0x95,0x81,0x8b,0x9b,0xca,0x88,0xbc,0xa0,0x98,0x2b,0x2a,0x16,0x26,0x44,0x9f,0x09,0x14,0x92,0x0e,0x1a,0x1e,0x1b +,0x28,0x09,0x29,0x1c,0x0b,0x0f,0x11,0x0c,0x1c,0x0f,0x0c,0x0b,0x19,0x1c,0x1f,0x26,0x09,0xdb,0xb4,0x9e,0x8b,0x85,0xa3,0x8e,0x86,0x8e,0x88,0x85,0x8b,0x99,0x8d,0x8f +,0x9d,0x8d,0x98,0xa7,0xaa,0xb8,0x93,0x1d,0x14,0x07,0x1b,0xa5,0x16,0x2f,0x8f,0x0b,0x3d,0xa3,0xae,0x31,0x2d,0x9c,0x16,0xeb,0x14,0x3d,0x0b,0x13,0xb5,0x1b,0x1e,0x0d +,0x07,0x0c,0x0d,0x0a,0x30,0x1c,0x22,0x9c,0x18,0x2b,0x8c,0xa8,0x9c,0x95,0x9b,0x96,0x9f,0x8e,0x8e,0x90,0x9c,0x8f,0x9b,0x9c,0x9b,0x92,0xba,0x9a,0x9f,0x98,0x93,0x2f +,0x8b,0x5a,0x9a,0xa8,0xad,0x53,0xbd,0x27,0x0d,0x30,0x3a,0x0f,0x08,0x12,0x1c,0x15,0x0a,0x0e,0x0e,0x10,0x07,0x06,0x13,0x52,0x02,0xab,0xac,0x0b,0x8c,0xad,0x49,0x8d +,0x8d,0x92,0x98,0x92,0x96,0x98,0x8f,0x9c,0x86,0x82,0x2c,0x9e,0xfa,0xc8,0x9e,0x35,0xa4,0x0f,0xa6,0x8e,0xb4,0x9b,0xbd,0x15,0x39,0x94,0x9a,0x28,0x2d,0xae,0x17,0xbd +,0x9e,0x0c,0x0d,0x26,0x18,0x0f,0x1e,0x07,0x09,0x11,0x13,0x0d,0xc0,0x1c,0x12,0xb7,0x2a,0xa4,0x1c,0xac,0x18,0xbe,0xca,0xca,0x9b,0xaa,0x48,0x9f,0xb5,0xbf,0x8c,0x23 +,0x99,0x5a,0x86,0x99,0x37,0x84,0x9a,0x88,0x89,0x98,0x89,0x97,0x94,0x9e,0xa8,0x96,0x2b,0x26,0x1f,0x3e,0x0d,0x07,0x33,0x0e,0x0c,0x09,0x0b,0x07,0x10,0x0e,0x18,0x1a +,0x1a,0x2c,0x12,0x9e,0x1e,0xc1,0x9d,0x16,0xda,0x9a,0x2e,0x9c,0x7c,0x29,0xb8,0x21,0x93,0x1e,0x98,0xaa,0xaf,0x92,0x26,0x85,0x88,0x8e,0x83,0x95,0x8e,0x88,0x98,0x94 +,0xa7,0x8e,0x3e,0xbe,0xa7,0x25,0x16,0x18,0x23,0x15,0x0e,0x0d,0x0f,0x0e,0xb6,0x0c,0x32,0x15,0x0e,0x76,0x13,0x9a,0x1e,0x0e,0x95,0x1f,0x1c,0xb7,0x27,0x2e,0x2b,0x33 +,0x38,0x10,0x9d,0x33,0x56,0xad,0x10,0x8f,0xa6,0xae,0x8e,0x98,0x97,0x8b,0xa4,0x8b,0xa8,0x8c,0x84,0xa6,0x93,0xac,0xb9,0xad,0x94,0x21,0x42,0x21,0x12,0x4a,0x42,0x0e +,0x15,0x1e,0x0c,0xa5,0x21,0x1a,0x36,0x1c,0x34,0x4f,0x3b,0x9f,0x3e,0x99,0xa4,0x1b,0x4b,0x0d,0xaf,0x24,0x29,0x14,0x12,0x24,0x12,0x0f,0x1d,0x28,0x39,0x3b,0x2d,0xa7 +,0x9f,0x8c,0xa8,0x9c,0x89,0x8a,0x91,0x8a,0x8c,0x8c,0x9f,0x8e,0x91,0x49,0xcb,0x9e,0x40,0xc6,0x1f,0x16,0xd5,0x15,0xd7,0x28,0x0a,0x1b,0x25,0x1e,0x47,0x1b,0x11,0x30 +,0x30,0x0f,0x18,0xa3,0x1e,0x0b,0xb5,0x0b,0x26,0x58,0xca,0xaf,0x43,0xa1,0x1b,0x96,0xa7,0x99,0x97,0xb0,0x8c,0xa4,0x97,0x8d,0xa2,0x90,0xaa,0x9c,0x9b,0x8c,0xa8,0x18 +,0x2b,0x4e,0x9b,0x1c,0x4c,0x15,0x11,0x1b,0x14,0x3d,0x1d,0x0f,0x25,0x19,0x4a,0xa5,0x16,0xac,0xb1,0x4e,0xc2,0x95,0x95,0x3d,0xcd,0x9d,0xa2,0xd5,0x9f,0x25,0x20,0xaf +,0x3a,0x3f,0x2a,0x1b,0x12,0x1d,0x36,0x11,0x1f,0x19,0x12,0x22,0x1b,0xa2,0x4b,0xa7,0xb6,0x59,0x9d,0x9b,0x9a,0xa4,0x8c,0x99,0x8f,0x8d,0xa2,0xa2,0x8f,0x97,0x95,0xc2 +,0x9e,0x3b,0xc6,0x4c,0x10,0x46,0x26,0x20,0x16,0x16,0x18,0x17,0x12,0x2e,0xcd,0x34,0x1c,0xfc,0x24,0x55,0x0f,0x5c,0x9e,0xe7,0xd8,0x2a,0xa5,0xa5,0xc2,0x2d,0xb7,0xa9 +,0xe8,0x28,0xa9,0x25,0xdd,0xed,0xa7,0x2f,0x2e,0xa3,0xae,0x91,0x9a,0xa3,0xac,0x9b,0xa3,0x99,0xa8,0x50,0xbb,0x24,0xa9,0x50,0x3f,0x23,0x0f,0x6f,0x23,0x49,0x22,0x1e +,0x2b,0x65,0x19,0x32,0xcf,0xe7,0xbd,0x27,0x3e,0xb3,0xa2,0x4d,0xb2,0xda,0x33,0x9f,0xab,0x29,0x99,0xbd,0x45,0xb0,0xd1,0x32,0xcc,0x1e,0x4b,0xa6,0x1b,0xce,0x1c,0x52 +,0xfa,0xd5,0xbf,0x26,0xb4,0xd8,0x58,0xa2,0xc5,0xc8,0xaa,0xc5,0xa7,0x9f,0xa9,0xd3,0xc6,0x74,0xb2,0xb9,0xcc,0xa4,0xb6,0xca,0x4e,0x41,0xcf,0x3f,0x57,0x28,0x2f,0x39 +,0x24,0x30,0x43,0x26,0x25,0x1e,0x31,0x31,0xe8,0xa7,0x23,0xbf,0xf6,0x2c,0x24,0x33,0x98,0xad,0x35,0x65,0x29,0xd4,0x9d,0xa6,0x9f,0xac,0x2d,0xcc,0xaf,0xa7,0x9f,0xad +,0xc6,0x55,0xb7,0xb2,0xac,0xb9,0xba,0xcc,0x49,0xb1,0xc7,0xbe,0xb1,0xca,0xdc,0x2e,0xab,0xad,0x54,0xdf,0x3e,0x24,0x2f,0xb1,0xb2,0x50,0x3f,0x27,0x1f,0x24,0x2e,0xbf +,0x39,0x6b,0x2c,0x20,0x22,0xdd,0xbd,0xc8,0xac,0x2f,0x27,0x4c,0x53,0x3c,0x62,0x3c,0x33,0x26,0x41,0xa6,0xa4,0xc7,0x2e,0x1f,0xd0,0xac,0xc2,0xc1,0xa0,0xb5,0x3f,0x44 +,0x2d,0xb9,0xc7,0xb9,0xae,0x77,0x2b,0x5f,0x38,0xbb,0xd7,0x31,0x3a,0x34,0xae,0xbc,0x51,0x56,0xbe,0x25,0x24,0xa4,0x9d,0x42,0x76,0x29,0x2a,0xcd,0x3e,0xa0,0xcf,0x24 +,0xb7,0x29,0x48,0xaf,0x30,0x25,0x3f,0xbd,0x30,0xc2,0xce,0xa6,0x3d,0x28,0xbf,0xeb,0xb7,0xab,0xcb,0xcf,0xa9,0xc8,0xab,0xc5,0x3b,0x4c,0x41,0x3f,0xbb,0x5c,0x46,0x46 +,0x44,0x33,0x49,0x6d,0x34,0xb9,0xde,0xb4,0xcc,0x38,0x2f,0x56,0xc5,0x9c,0xa8,0x32,0x39,0x2b,0xc9,0x36,0xd8,0xb6,0x44,0x36,0x47,0x35,0xde,0xb9,0x2b,0xbe,0xab,0xa2 +,0xbd,0x25,0x6b,0x69,0x55,0xb8,0x9c,0xb2,0x29,0x3c,0x4c,0xbf,0x66,0xbe,0x65,0x47,0x47,0x4d,0xb8,0x3c,0x4a,0x36,0x37,0xed,0x38,0xb1,0xbb,0x42,0xed,0xb7,0xae,0x36 +,0x36,0xb7,0xa8,0xbc,0xc9,0x2b,0x3d,0xbb,0x3d,0x4f,0x2e,0x1f,0x55,0x9f,0xae,0x74,0x1c,0x1f,0xa2,0xb2,0x48,0xb7,0xd5,0x4a,0x53,0xb5,0xbb,0xc9,0xc5,0xb3,0xe7,0x7d +,0xb2,0x3f,0xb4,0x3b,0x2e,0x27,0x6b,0x9e,0xae,0xdd,0x6e,0xd5,0x2a,0xd4,0xb6,0xaf,0xc5,0xbf,0xb3,0xd5,0xcb,0x22,0x2c,0xb4,0xd4,0xad,0xed,0x25,0x42,0xce,0x3d,0x3c +,0x76,0x50,0xad,0xbe,0x34,0x20,0xec,0xae,0x6d,0xab,0xda,0xbb,0xd5,0x2c,0xcb,0x41,0x5f,0xae,0x64,0xde,0xbf,0x34,0x39,0x3f,0x60,0xb4,0x7b,0x49,0x3e,0x3e,0xcd,0xaa +,0xa4,0x4c,0x25,0x38,0xb5,0xad,0x57,0x43,0xba,0x60,0x3b,0x74,0x5d,0xe0,0xd9,0x35,0x62,0x48,0xf7,0xbb,0x37,0xb3,0x50,0x46,0xc8,0x30,0x4f,0x36,0x44,0xa8,0xcf,0x34 +,0x42,0x2f,0xbc,0xab,0xbe,0x2b,0x36,0xc8,0xc8,0xac,0xc9,0x4d,0xc1,0xb1,0x4c,0xa7,0xb9,0xc2,0xba,0xd2,0xe8,0x48,0xc0,0x51,0xc6,0x3b,0x3d,0x7e,0x5b,0xbd,0x5f,0x28 +,0x2d,0x33,0xe6,0xdd,0xbe,0xd5,0x38,0x3f,0x37,0xcc,0xae,0xaf,0x45,0x44,0xcf,0x42,0xc9,0x44,0xdc,0xc6,0x3d,0x2e,0xfb,0xbb,0xc2,0xcb,0x26,0xe0,0xb8,0xb6,0x3a,0x4b +,0x30,0x59,0xbe,0xb8,0xab,0x39,0xcc,0xb8,0x5b,0x51,0x3f,0x68,0x9d,0xbf,0x35,0x37,0x73,0x61,0xb7,0x4a,0x49,0xcb,0x27,0x38,0xbb,0xae,0xc5,0xba,0x38,0x49,0xd8,0xe4 +,0xbd,0xac,0x69,0x31,0x2a,0x33,0xb4,0x55,0x4f,0x58,0xcf,0x5c,0x5a,0x5e,0x2d,0xb7,0xea,0x2d,0xaf,0xb5,0xc8,0xbe,0x56,0xaf,0xb0,0x53,0xda,0x46,0xc5,0xbb,0x3e,0x2d +,0xfb,0x5a,0xc9,0xd8,0x37,0x34,0x35,0xb8,0xc0,0xba,0x3c,0x31,0x33,0xc9,0xa3,0xb6,0x3f,0x4c,0x40,0xee,0xb9,0x5e,0xb5,0xe7,0x3d,0x3c,0xcd,0x3f,0x69,0xaf,0x33,0x35 +,0x39,0x34,0x3f,0xc0,0x6b,0xf5,0xe2,0xb4,0xad,0x5b,0x4a,0x5f,0xaa,0xbf,0xbe,0x68,0xdd,0x44,0x5c,0xb6,0x4c,0x36,0x33,0xd1,0xc7,0xe8,0x49,0x3b,0x3e,0xcc,0x6b,0xb2 +,0xd2,0xc6,0xcd,0x36,0x58,0xcb,0xaf,0xc3,0x49,0xee,0x3a,0x4c,0xaf,0x4a,0x36,0x3c,0xbd,0xd8,0x56,0x33,0x51,0xae,0xfb,0x3c,0x36,0x5a,0xe8,0xaa,0xef,0x43,0xb0,0xcd +,0xcc,0x4e,0x38,0x68,0xbd,0x4c,0xbf,0xc4,0x2c,0xba,0x61,0x44,0xc9,0x41,0x3c,0x2c,0xca,0xc3,0xc5,0xec,0x4b,0xa7,0xc6,0x36,0x3d,0xc8,0xad,0xb6,0xcb,0xdf,0x5c,0x2e +,0xe1,0x57,0x3f,0xc0,0x3a,0x28,0x29,0xbc,0xb5,0x46,0x4e,0xcf,0x4b,0x41,0x49,0xee,0xb3,0xba,0xa9,0x47,0x5d,0xbf,0x58,0xb7,0x42,0xe6,0xb4,0x3d,0x25,0xb7,0xbd,0xfb +,0x69,0x44,0xf5,0x3a,0xcd,0x3f,0x47,0x45,0xe0,0xab,0xa7,0xbc,0x39,0x35,0xe6,0xb6,0xc1,0xb6,0x65,0x2f,0x41,0x33,0xd1,0xcd,0xe3,0x40,0x2c,0x73,0x26,0xe9,0xaf,0xcd +,0x60,0x4e,0x49,0xcc,0xaf,0xd9,0xb9,0x49,0x3d,0xb4,0xac,0xc9,0x3a,0x3a,0x47,0x76,0xc3,0x56,0x2f,0x76,0x56,0x4b,0xbe,0x3c,0xc0,0xc0,0x3a,0xd8,0x76,0x6e,0x7e,0xbb +,0xc8,0xc3,0xc9,0x4a,0x3f,0x43,0xbd,0x33,0x2c,0xc0,0xbc,0xbc,0x2f,0x2d,0xbe,0xb8,0xb2,0x29,0x2c,0xb1,0xa5,0xf7,0x24,0x43,0xbc,0xa9,0xba,0xd5,0xd3,0x49,0x48,0x52 +,0xb7,0x5a,0x34,0xf4,0xe9,0xb0,0xb3,0x49,0x2b,0x27,0x3f,0xd5,0xb7,0xab,0x3f,0x71,0xae,0x5f,0x3d,0xcd,0x50,0x7e,0xc4,0x5b,0xb8,0xf9,0x3a,0xda,0x6b,0x2a,0x32,0xbe +,0xb9,0x49,0x37,0x3d,0xd5,0x3e,0x63,0xb2,0xcc,0xc8,0x42,0x3b,0xbb,0xb0,0xca,0xff,0xbd,0x64,0x2c,0x40,0xb0,0xb1,0xc5,0x39,0x25,0x4e,0x5b,0xbd,0xa8,0xc1,0x2d,0x33 +,0xdc,0xbd,0xa9,0xe2,0x32,0x73,0x46,0xbc,0xab,0x79,0x3f,0x30,0x3a,0x5f,0x45,0xdc,0xba,0xc5,0x38,0x30,0x3b,0x38,0xb5,0xea,0x5c,0xaf,0xc7,0x36,0xc2,0xab,0xc5,0x53 +,0x3b,0xd2,0xb6,0xbe,0x70,0x39,0xcc,0x4a,0x35,0xe5,0x4e,0xea,0x4b,0x58,0x2f,0x45,0xc2,0xc1,0xba,0xc4,0x54,0x78,0x57,0xd9,0xc5,0xc2,0xa9,0x6c,0x2a,0x43,0xb9,0xb5 +,0xb5,0x29,0x28,0x3c,0x58,0xae,0xbe,0x6f,0x27,0x24,0x4d,0x6f,0xad,0xb0,0xbc,0xce,0x3c,0x49,0xc2,0xca,0x42,0x37,0xda,0xb6,0x55,0xe7,0xb7,0x4a,0x27,0x33,0xc2,0xbe +,0xbb,0xab,0x37,0x35,0xbc,0xbe,0xbf,0xe6,0x4e,0xad,0xd8,0x4e,0x38,0xe8,0xa5,0xbd,0x4b,0x2c,0x4b,0x74,0xc2,0x36,0x58,0xc4,0x2e,0x40,0xdb,0xbe,0x58,0x2e,0xe6,0xbb +,0x38,0x4f,0xbd,0xb8,0xb6,0xdd,0xed,0xd2,0xc4,0x3f,0x47,0xb0,0x48,0x37,0x49,0x52,0xe7,0x53,0x4d,0x39,0xc3,0xd1,0x3c,0xa6,0xb0,0x2b,0x33,0x3e,0xa0,0xa7,0x3d,0x57 +,0x3e,0xbf,0xae,0xbc,0xfb,0xd9,0x31,0x54,0xe5,0x73,0xb2,0x33,0x35,0xf7,0x48,0xb8,0x44,0x4b,0x38,0x39,0xbb,0x28,0xae,0xb6,0xc9,0xdb,0x2f,0x3a,0x6a,0xa6,0x53,0xad +,0xa7,0x33,0x30,0x2e,0xda,0xb5,0x37,0x4f,0xad,0xef,0x32,0xbf,0xee,0x3c,0x43,0x34,0xab,0xad,0x50,0x41,0x40,0xbd,0xc1,0x3e,0x7b,0xaf,0xb8,0x3a,0x36,0x66,0xc4,0x4c +,0x33,0xaf,0xcf,0x4d,0x59,0xde,0x39,0x3b,0xab,0x4d,0x56,0xba,0xc9,0x49,0x48,0x6c,0x4a,0x40,0x62,0x73,0x37,0xad,0xbc,0x48,0x3e,0x40,0xb2,0xde,0xb1,0x4b,0x48,0x5f +,0x3c,0x64,0xb9,0xb5,0x38,0x57,0x3a,0x5a,0xcb,0x42,0xca,0xba,0x6b,0x40,0x61,0xc1,0xbd,0xcc,0xcf,0xc2,0x3b,0x3d,0xe3,0x4a,0xd6,0xc4,0x52,0x4a,0x5b,0x56,0x4f,0xc8 +,0x4d,0x2e,0xbd,0x5a,0xb9,0xaa,0x3d,0x37,0x39,0x57,0x39,0xbb,0xb4,0xf1,0x69,0x3f,0xbd,0xde,0xcc,0xcf,0x55,0xd3,0xcb,0x4f,0x3c,0xc0,0xc3,0x3c,0x41,0xd6,0xba,0xcd +,0xcf,0x34,0x39,0x68,0x44,0xe3,0xc3,0xad,0xba,0x37,0x2f,0x4b,0xce,0xaf,0xc0,0xd8,0x38,0x3c,0x30,0xbc,0xac,0xd6,0x4b,0x2b,0x49,0x4f,0xa9,0x5a,0x5a,0xcc,0x4c,0xef +,0xe5,0xc5,0x2b,0xee,0xe7,0xc7,0xaa,0x68,0xe9,0x41,0x3a,0x7a,0x4b,0x4e,0x3a,0xd1,0xa9,0xc5,0x44,0x32,0x41,0xea,0xb5,0xaa,0xba,0x4d,0x2f,0x2f,0x46,0xa7,0xbe,0x41 +,0x60,0xd4,0x4d,0x2c,0x58,0xbf,0xbc,0x40,0xdf,0xe9,0x3b,0xc0,0xb3,0x57,0x4f,0xbe,0x34,0xe9,0xaf,0x45,0x46,0xbe,0xdb,0x57,0xca,0x36,0x49,0xbc,0xbf,0x42,0x32,0xce +,0xc5,0xe9,0xd3,0xbf,0x29,0x47,0xb4,0xd4,0xb7,0xd7,0x5a,0x41,0xd7,0xbe,0x52,0xe3,0xc2,0x58,0x49,0x4d,0xdd,0x37,0x2d,0x51,0xb6,0x6a,0xeb,0xaf,0x3c,0x51,0x3b,0x36 +,0xcd,0xa9,0xa2,0xe5,0xbf,0x2f,0x2c,0xc9,0xb6,0xad,0x66,0x45,0x35,0xb0,0xca,0x58,0x43,0x2e,0x53,0x64,0xbd,0xc9,0x3c,0x2d,0x3f,0xbc,0x63,0x2b,0xc9,0xbd,0xa8,0x69 +,0x2e,0x3f,0xd6,0xb4,0xc8,0xbb,0xc8,0xe1,0x47,0x42,0xca,0xdc,0x41,0xe1,0x32,0x3d,0xaf,0xc0,0x2b,0x51,0xca,0x3f,0xcf,0xc0,0xb2,0xc1,0x36,0x61,0xe0,0xdb,0xc9,0xda +,0xe4,0x59,0xfb,0x2b,0xd4,0xa8,0x2d,0x2b,0x3f,0xd5,0xba,0x49,0xc9,0xe7,0x2c,0x37,0xb0,0xb7,0xb8,0x67,0x43,0xcf,0x46,0xd5,0x4a,0x69,0xc6,0xba,0x3a,0x2e,0xc4,0xbb +,0xb4,0x42,0x37,0x34,0x62,0xb5,0xaf,0xd0,0x69,0xd9,0x5d,0xda,0x2e,0xae,0xd1,0x3f,0xb5,0xc2,0x4e,0x37,0xaf,0xcd,0x3f,0x4d,0x2f,0x3a,0xb7,0xb2,0xb0,0x3b,0x29,0x39 +,0xb9,0xc1,0x3f,0xaa,0x6f,0x29,0x5e,0x5d,0x39,0xbf,0x6d,0x4d,0x54,0x3b,0xae,0xc8,0xc1,0xe3,0x2b,0x60,0xcd,0x4a,0xae,0xbc,0x46,0x38,0xef,0xad,0x45,0xc4,0xd1,0x3e +,0xbf,0xb2,0x54,0x50,0xcc,0xd3,0x3d,0x69,0xae,0x3d,0x3a,0xcb,0x2c,0x3a,0xcb,0x4c,0xbb,0xc6,0x40,0x3c,0x44,0x34,0xe5,0xb7,0xbb,0xcd,0x45,0x4b,0xcc,0xc2,0x63,0x38 +,0x25,0xc9,0xb1,0xc7,0x6b,0x33,0xcf,0xdb,0x43,0x39,0xdc,0xaa,0xb9,0xcd,0xec,0x41,0xd3,0x4a,0xcf,0xb9,0xb6,0xbc,0x63,0x2d,0x38,0xcb,0x3a,0xab,0xc5,0xe9,0xa7,0xad +,0xa1,0x9a,0x2e,0x2c,0x34,0x0e,0x0f,0x19,0x2b,0xb8,0xae,0x27,0x28,0xab,0xc3,0x2d,0xa2,0xd9,0x18,0xb2,0x98,0x8a,0x99,0x1b,0x99,0x8e,0x98,0x9f,0x9d,0xbf,0x1b,0x1a +,0x10,0x20,0xac,0x9a,0xbe,0xbf,0x16,0x0f,0xeb,0x1d,0x1b,0x33,0x39,0x2a,0x9f,0x94,0x1d,0x29,0xac,0xbc,0xbf,0x3d,0x2d,0x98,0xbd,0x05,0x0e,0x96,0x92,0xa5,0x9d,0xbe +,0x25,0x4d,0xac,0x2d,0x9c,0xa4,0x2b,0xbe,0x54,0xdd,0x8f,0x8e,0x36,0x23,0x17,0x28,0xd4,0x32,0x19,0x15,0x2c,0x96,0x86,0x96,0xae,0x9b,0xa7,0x19,0x19,0x27,0xb6,0x3b +,0x16,0x0b,0x16,0x15,0x16,0xc7,0x29,0x2d,0xb3,0x95,0xac,0xda,0x26,0x17,0x40,0x93,0x8d,0x8d,0x93,0xad,0x2e,0xbb,0x36,0x1a,0x95,0x9a,0x41,0x2f,0xb0,0x29,0xbb,0xab +,0x32,0x6e,0x24,0x2f,0x9c,0x5c,0x07,0x11,0xd0,0xaf,0xb9,0xbc,0xb2,0xaa,0xc4,0xb8,0x3a,0x4b,0xa4,0x9b,0xc8,0x2d,0xba,0x98,0x92,0x32,0x1b,0x1c,0x24,0x62,0x17,0x08 +,0x07,0x0b,0x47,0x98,0xac,0x67,0x94,0x8f,0xaa,0x2b,0xbe,0x8a,0x88,0x9e,0x2d,0xb0,0x97,0x93,0x9c,0xa8,0x20,0x7a,0x8f,0xaf,0x24,0x0e,0x07,0x16,0xdf,0x26,0x1b,0x1e +,0x2c,0xed,0x1e,0x0e,0x1e,0xbd,0xfe,0x32,0xc8,0x98,0x8c,0x98,0xd4,0x4b,0xbb,0x9c,0x98,0x94,0x5d,0x0a,0x11,0xc4,0xa6,0xae,0x4a,0x34,0xb2,0x21,0x15,0x0e,0x21,0x95 +,0xa2,0x1d,0x0d,0xd1,0x8b,0x8c,0xad,0x3d,0x5e,0xbc,0x95,0x9e,0x69,0x29,0x26,0x90,0x8a,0x98,0x94,0x8e,0x8f,0xd3,0x0e,0x1a,0xb3,0x5a,0x10,0x0a,0x07,0x1b,0x9a,0xae +,0x22,0x5e,0x8f,0x86,0x86,0x8a,0x8d,0xb4,0x3d,0xa2,0x9d,0x9e,0xa0,0x58,0x1b,0x0b,0x00,0x05,0x0d,0x0d,0x08,0x01,0x02,0x09,0x08,0x02,0x05,0x01,0x0c,0x1f,0x0b,0x0d +,0x1a,0x2a,0xc5,0x2f,0x92,0x86,0x92,0x89,0x88,0x8d,0xa7,0x9d,0x83,0x83,0x9f,0x3e,0x92,0x85,0x81,0x8d,0xa2,0xa4,0xa0,0xa2,0xb7,0x19,0x1e,0xb8,0xb8,0x8e,0x8a,0x88 +,0x84,0x87,0x88,0x95,0xc3,0x8e,0x84,0x90,0x3d,0x18,0xbf,0x9d,0xc2,0x37,0x1f,0x22,0x2f,0x32,0x15,0x07,0x01,0x04,0x03,0x02,0x28,0x0e,0x15,0xbb,0x09,0x07,0x0f,0xc2 +,0x8c,0x1b,0x0d,0x23,0x35,0xad,0xab,0x31,0x2b,0x2d,0x55,0xa9,0x1b,0x20,0x19,0x0f,0x14,0x0e,0x28,0x33,0x11,0xac,0x31,0x07,0x9f,0x8a,0x89,0x8f,0x22,0x90,0x8b,0x92 +,0x89,0x29,0x23,0x41,0x3e,0xaf,0x1a,0x22,0xa2,0xbe,0xba,0xa4,0x8b,0x87,0x92,0x90,0x9e,0x1f,0x8d,0x82,0x94,0x87,0x8e,0x8a,0x81,0x84,0x80,0x84,0x8c,0x80,0x87,0x8e +,0x92,0xe7,0xa7,0x1c,0x09,0x1e,0x23,0x1e,0x0f,0x01,0x01,0x00,0x01,0x02,0x00,0x03,0x06,0x00,0x12,0x0f,0x08,0x10,0x0a,0xcf,0x0f,0x04,0x36,0x19,0x09,0x0a,0x0a,0xf9 +,0x22,0xcb,0x98,0x17,0x27,0xc6,0xa7,0xa1,0x4e,0xc5,0x61,0x13,0x87,0x8d,0xe8,0x85,0x8b,0x8c,0x88,0x8c,0x82,0x9b,0xaf,0x84,0x8d,0x88,0x80,0x87,0x88,0xa5,0x9e,0x8d +,0xa2,0x96,0x9f,0x21,0x2e,0x55,0x37,0x3f,0x11,0x93,0x9b,0x1d,0x89,0xa2,0x2b,0x27,0x28,0x51,0x0f,0x2a,0x8f,0x1b,0x0a,0x17,0x19,0x1a,0x0d,0x21,0x0e,0x07,0x16,0x1c +,0x1e,0x0e,0x0a,0x0e,0x07,0x06,0x9e,0x1a,0x0b,0xab,0x1d,0x1a,0x30,0x9a,0x8b,0x4c,0xb7,0x95,0xde,0xc4,0xa1,0xb9,0x31,0x1d,0x67,0x21,0x0f,0x26,0x18,0x10,0x13,0x0b +,0x0e,0x0f,0x0e,0x8b,0x28,0xd3,0x80,0x84,0x80,0x83,0x80,0x85,0x8a,0x85,0x80,0x97,0x8c,0x80,0x84,0x86,0x88,0x83,0x89,0x89,0x84,0x93,0x5d,0x35,0x1a,0x0d,0x01,0x09 +,0x4f,0x07,0x0b,0x4f,0x0d,0x0e,0x14,0x0c,0x09,0x01,0x0d,0x0e,0x03,0x08,0x07,0x07,0x05,0x0e,0x12,0x01,0x07,0x09,0x05,0x02,0x07,0x09,0x0f,0x09,0xc0,0x8c,0x14,0x93 +,0x82,0xab,0x93,0x85,0x88,0x9d,0xaa,0x84,0x8e,0xa0,0x85,0x86,0x90,0x8d,0x83,0x89,0x9a,0x9c,0x9f,0xa2,0x95,0x8a,0x9a,0x4d,0x11,0xa9,0x8e,0x2c,0x86,0x85,0xa6,0x8e +,0x84,0x85,0x8c,0x8b,0x87,0xa7,0xb7,0x96,0x35,0x1b,0x0f,0x08,0x05,0x07,0x1e,0x13,0x08,0x0e,0x0b,0x07,0x0a,0x05,0x3f,0x20,0x04,0xbc,0x46,0x0e,0x3e,0xb1,0x1c,0x0e +,0x25,0x77,0x0c,0x16,0x41,0x0d,0x12,0xb2,0x70,0x1c,0xfe,0xbc,0x1d,0x19,0x17,0x0f,0x0d,0x04,0x05,0x45,0x12,0x13,0x8e,0xc5,0xda,0x8c,0x8e,0x8e,0x92,0x8d,0x8a,0x96 +,0x89,0x82,0x87,0x85,0x84,0x88,0x8d,0x88,0x86,0x8a,0x89,0x89,0x8a,0x85,0x8d,0x8f,0x81,0x97,0x8f,0x80,0x94,0x99,0x90,0x2c,0x16,0x0c,0x1f,0x1c,0x11,0x1c,0x0a,0x09 +,0x0d,0x0d,0x07,0x03,0x03,0x02,0x01,0x02,0x03,0x01,0x03,0x00,0x09,0x11,0x02,0x22,0x1d,0x03,0x18,0xca,0xc2,0x40,0xb7,0x91,0x9f,0x90,0x8b,0x9f,0x98,0xa1,0xbc,0xb5 +,0xc2,0xae,0xb9,0xcb,0x99,0xa4,0xb0,0x93,0xcd,0x87,0x8d,0x3d,0x83,0x85,0x96,0x88,0x87,0x8f,0x8e,0x8e,0x89,0x9c,0x91,0x86,0x94,0x8d,0x88,0x96,0x98,0x8e,0x95,0x9f +,0x44,0x68,0x1e,0x0a,0x04,0x04,0x1f,0x07,0x0e,0xb5,0x1b,0x23,0xa6,0xcd,0x3a,0x5f,0x4f,0x1f,0x0f,0x5e,0x24,0x11,0x25,0x0f,0x0c,0x0b,0x15,0x0f,0x0b,0x09,0x0b,0x0a +,0x0d,0x0c,0x0d,0xac,0x0f,0xd1,0x88,0x4a,0x64,0x95,0x78,0x21,0x39,0xc7,0x1c,0x16,0xa6,0xdd,0x19,0xaa,0x93,0xba,0xa4,0x9a,0xb1,0xbe,0xa1,0x99,0xbd,0x9e,0x96,0x97 +,0x82,0x91,0x84,0x80,0x87,0x84,0x81,0x82,0x83,0x82,0x81,0x84,0x89,0x83,0x93,0xa4,0x96,0x2e,0x0f,0x1b,0x0c,0x06,0x05,0x06,0x09,0x05,0x06,0x00,0x08,0x0f,0x01,0x0b +,0x11,0x02,0x09,0x0d,0x07,0x06,0x0e,0x1c,0x0a,0x0f,0x2c,0x15,0x10,0x1f,0x0f,0x10,0xcf,0xe3,0x2a,0x27,0x1c,0x1c,0x28,0xe7,0x18,0x9f,0x99,0x27,0x87,0x89,0x8f,0x87 +,0x86,0x88,0x85,0x86,0x88,0x92,0x96,0x89,0x9d,0x94,0x8c,0x9c,0xa1,0x9c,0x9a,0x97,0x8e,0x9b,0xb4,0xac,0x9a,0x2d,0x9c,0x8d,0x33,0x8f,0x9b,0x49,0x9b,0xae,0x2e,0x3d +,0x30,0x40,0x37,0x22,0xae,0x2f,0x1c,0xd6,0x18,0x0c,0x14,0x0c,0x07,0x08,0x0a,0x07,0x05,0x08,0x00,0x1f,0x1e,0x10,0x9f,0x33,0x1a,0x4a,0x23,0x1f,0x2b,0x27,0xcd,0x26 +,0x1c,0xa7,0x2a,0x2f,0xae,0x18,0x28,0x20,0x1b,0x1f,0x21,0x20,0x1b,0x1f,0x2c,0x0f,0xac,0x9a,0x1c,0x8c,0x89,0x99,0x86,0x83,0x87,0x84,0x82,0x80,0x81,0x81,0x80,0x82 +,0x83,0x81,0x85,0x84,0x85,0x8c,0x94,0xce,0xbf,0xb3,0x23,0x1f,0x06,0x16,0x1f,0x05,0x2f,0x1f,0x05,0x18,0x1b,0x0b,0x0c,0x07,0x09,0x03,0x03,0x0d,0x05,0x04,0x08,0x03 +,0x07,0x0c,0x0b,0x0f,0x0d,0x0e,0x0b,0x04,0x0d,0x05,0x18,0xa9,0x0e,0x43,0xa2,0x2d,0x97,0x8d,0x8e,0x8e,0x95,0x89,0x8c,0x92,0x86,0x8f,0x8c,0x85,0x92,0x8d,0x8e,0x9d +,0x9f,0xac,0xa8,0xa5,0xde,0x9e,0x4e,0xa6,0x8a,0x9b,0x87,0x86,0x9e,0x8c,0x88,0x8c,0x86,0x8d,0x8d,0x9d,0xad,0x94,0xa1,0xc8,0x59,0x2e,0x26,0x2b,0x22,0x2a,0x17,0x0e +,0x17,0x0e,0x18,0x09,0x0e,0x18,0x06,0x19,0x1f,0x0a,0x19,0x1c,0x15,0x29,0x34,0xb3,0x2e,0x49,0xb8,0x1a,0x16,0x24,0x11,0x14,0x2b,0x1a,0x10,0x12,0x17,0x17,0x0e,0x1e +,0x0a,0x0e,0xa8,0x17,0x4d,0x9d,0x2a,0xa9,0x93,0xa6,0xa4,0x9b,0x8e,0x9b,0x9e,0x85,0x8a,0x8b,0x83,0x88,0x87,0x82,0x83,0x81,0x83,0x85,0x84,0x89,0x83,0x8e,0x8b,0x88 +,0xaf,0x90,0x94,0xbf,0x98,0xaa,0x39,0x3a,0x1c,0x2f,0x1b,0x0d,0x1d,0x0d,0x09,0x0d,0x04,0x03,0x04,0x03,0x03,0x04,0x03,0x01,0x01,0x03,0x01,0x0e,0x0d,0x08,0x3d,0x12 +,0x0c,0x51,0x1a,0x1c,0x4f,0x3e,0xbe,0x1f,0x52,0x9f,0xb6,0xa1,0x9a,0xaf,0xa7,0x9c,0x9e,0x97,0x9e,0x9b,0xba,0x99,0xb0,0xab,0x8e,0xcf,0x93,0x8f,0xa5,0x91,0x8d,0x8f +,0x8b,0x8b,0x89,0x88,0x89,0x87,0x8b,0x8a,0x8c,0x95,0x94,0x97,0xad,0xca,0xf4,0x55,0x27,0x3c,0x14,0x0e,0x2e,0x0b,0x0f,0x1e,0x0d,0x13,0x1c,0x16,0x49,0x44,0x2a,0x35 +,0x27,0xc6,0x48,0x49,0x45,0x24,0x1f,0x1d,0x1d,0x1b,0x21,0x1c,0x0f,0x0c,0x0c,0x10,0x20,0x1b,0x20,0xa3,0x30,0x46,0x9f,0xb4,0xb1,0x62,0xa1,0xa6,0xa5,0xa3,0xb6,0xaf +,0x9c,0x96,0xa6,0xa5,0xdd,0xcc,0xbd,0x4f,0x27,0x2c,0x1c,0x16,0xc6,0x2e,0xcd,0x97,0xe5,0xb1,0x98,0x9c,0x8d,0x91,0x93,0x95,0x95,0x8e,0x92,0x94,0x9b,0xae,0xe0,0x9e +,0xae,0xc5,0x6b,0x2e,0x18,0x2f,0x29,0x1f,0xac,0x1c,0x37,0x9d,0x2d,0x26,0xe7,0x1d,0x26,0x3a,0xb7,0xbb,0xa9,0x9e,0xaf,0x9b,0x93,0xac,0x3d,0xaf,0x2c,0x26,0x1f,0x0f +,0x0c,0x0f,0x02,0x0e,0x22,0x0a,0x3c,0x1f,0x11,0xee,0x31,0x30,0xbb,0x34,0x49,0x58,0x45,0xab,0xce,0x24,0x2a,0x27,0xb9,0xbc,0x2c,0x4a,0x1e,0x41,0xa8,0xc2,0x21,0x9c +,0x95,0xb6,0x89,0x8e,0xa0,0x8d,0x91,0xa9,0x94,0x93,0x96,0x93,0x8c,0x8d,0x8b,0x87,0x8a,0x98,0x95,0x97,0x9d,0x9e,0xbb,0x21,0x1a,0x10,0x19,0xd1,0x0c,0x20,0xde,0x0f +,0xce,0xb4,0x1e,0x3e,0x1d,0x2c,0x36,0x26,0x39,0x17,0x15,0x1b,0x0d,0x12,0x21,0x14,0x14,0x12,0x11,0x24,0x0e,0x0b,0x4a,0x16,0x26,0xa7,0x22,0xdd,0xa8,0x26,0x49,0xab +,0xad,0x5d,0xa7,0x9d,0x9b,0x9c,0xa6,0xa5,0xcd,0x9b,0xad,0xb8,0x31,0x19,0x23,0x0f,0x36,0x95,0x3f,0xa7,0x8d,0x3e,0x95,0x86,0x98,0x8f,0x93,0x92,0x8f,0x8f,0x91,0xa7 +,0xa1,0xae,0xbf,0xad,0xb2,0xad,0xaa,0xc9,0xbe,0x9b,0x35,0x93,0x91,0xb7,0x86,0x95,0x9f,0x88,0xa6,0x69,0xa9,0x24,0x20,0x0f,0x13,0x11,0x0a,0x0e,0x0a,0x02,0x03,0x04 +,0x01,0x03,0x01,0x00,0x00,0x00,0x08,0x02,0x08,0x13,0x06,0x1e,0xd2,0x4c,0x9a,0x96,0x9b,0x8f,0x8d,0x8b,0x89,0x88,0x89,0x95,0x96,0x92,0x93,0x93,0x93,0x90,0x93,0x8d +,0x80,0x8d,0x89,0x80,0x85,0x82,0x81,0x86,0x82,0x85,0x8a,0x87,0x8c,0x89,0x95,0x9e,0x95,0xa1,0xb4,0x2d,0x12,0x19,0x0b,0x08,0x08,0x04,0x11,0x04,0x06,0x1a,0x0a,0x0e +,0x1a,0x08,0x0e,0x24,0x23,0x32,0x1f,0x24,0x1e,0x1f,0x6b,0x22,0x19,0x12,0x08,0x10,0x0b,0x07,0x08,0x05,0x1d,0x14,0x3f,0x9e,0x1d,0xad,0x9d,0x3d,0xa4,0x9d,0xa6,0xa3 +,0xa4,0xa9,0x96,0x8f,0x9b,0x9f,0xb5,0xa8,0xbd,0x33,0x1a,0x21,0x0e,0x0c,0x27,0x0a,0x22,0x38,0x09,0xc8,0x96,0xb3,0x8f,0x90,0x88,0x83,0x81,0x80,0x80,0x80,0x80,0x80 +,0x81,0x81,0x81,0x87,0x96,0x91,0x25,0xa9,0xa3,0x10,0x42,0x18,0x0a,0x1b,0x0a,0x03,0x09,0x05,0x07,0x05,0x06,0x05,0x04,0x04,0x03,0x05,0x04,0x03,0x05,0x05,0x04,0x09 +,0x00,0x0f,0x15,0x06,0xb3,0x1f,0x14,0xaf,0x19,0x2f,0xa4,0xa3,0xb3,0x9d,0x93,0x94,0x84,0x88,0x8c,0x89,0x8b,0x8e,0x86,0x8f,0x8d,0x97,0xc5,0x8a,0x9d,0x8e,0x84,0xa0 +,0x8c,0x8a,0x95,0x8a,0x93,0x95,0x9c,0xad,0x9c,0xaa,0xc2,0x3d,0x15,0x18,0x18,0x0e,0x18,0x08,0x0f,0x09,0x13,0xbf,0x11,0xb7,0x50,0x24,0x99,0xdf,0x37,0xb9,0x2c,0xc8 +,0xb7,0xb3,0xad,0x4a,0x3a,0x48,0xb3,0xab,0x2e,0x1d,0x15,0x18,0x19,0x08,0x38,0x15,0x0c,0x6d,0x17,0xbf,0x99,0x27,0x3e,0xb4,0x9c,0x96,0x70,0xa5,0xb0,0x4a,0x27,0x0e +,0x0d,0x0b,0x09,0x0e,0x08,0x0b,0x0f,0x0f,0x93,0x9d,0x89,0x81,0x88,0x81,0x81,0x81,0x80,0x80,0x82,0x80,0x82,0x80,0x85,0x86,0x8a,0x98,0x9c,0xb4,0x1f,0x0f,0x06,0x07 +,0x02,0x05,0x07,0x00,0x08,0x04,0x00,0x09,0x07,0x06,0x0c,0x09,0x14,0x12,0x14,0x21,0x2a,0x1e,0x1d,0x17,0x0e,0x0f,0x12,0x0d,0x07,0x11,0x06,0x20,0x31,0x38,0x92,0xbc +,0xa7,0x8b,0x97,0x8d,0x86,0x90,0x8e,0x8f,0x89,0x87,0x84,0x8b,0x8a,0x87,0x8b,0x8a,0x8d,0x9f,0x98,0xaf,0xd2,0x8e,0x42,0x9f,0x9a,0x21,0x95,0xa5,0x48,0x93,0xa2,0x9e +,0x94,0x98,0x94,0x98,0xa2,0xb2,0xc5,0xbd,0x29,0x17,0x18,0x06,0x0c,0x06,0x0d,0x1b,0x07,0x2a,0x21,0x1c,0xd3,0x17,0x1b,0x9f,0x49,0x46,0x6c,0x22,0x2e,0x19,0x0e,0x13 +,0x18,0x13,0x0e,0x11,0x10,0x0f,0x16,0x0a,0x27,0x1c,0x20,0xb4,0x18,0x3c,0x1f,0x0b,0x2d,0x2f,0x23,0x5e,0x47,0xb7,0xb5,0x96,0x92,0x92,0x86,0x88,0x89,0x83,0x87,0x88 +,0x83,0x87,0x81,0x83,0x82,0x80,0x85,0x83,0x83,0x86,0x82,0x87,0x8e,0x8f,0xbc,0x45,0x45,0x1a,0x0f,0x06,0x02,0x03,0x02,0x02,0x01,0x01,0x00,0x03,0x07,0x03,0x12,0x08 +,0x03,0x15,0x0c,0x16,0x23,0x0f,0x1e,0x1e,0x21,0xba,0x29,0xe2,0xbf,0x2d,0xa4,0xa1,0x41,0xcb,0x29,0x3b,0x20,0x59,0x9d,0x26,0x99,0x9d,0xb0,0x87,0x95,0x8f,0x84,0x8b +,0x82,0x85,0x87,0x84,0x85,0x89,0x8b,0x92,0x9a,0x9b,0xb2,0x27,0x1e,0x2e,0x12,0x3a,0x28,0x13,0x9f,0x36,0x2b,0xa6,0x28,0xa4,0xa3,0x2a,0xa0,0xa5,0xba,0xb0,0x26,0x33 +,0x45,0x1a,0x26,0x1e,0x24,0x1f,0x0b,0x0f,0x0d,0x1d,0x12,0x0e,0xaf,0x19,0x0b,0x18,0x0c,0x28,0xe2,0x26,0xc7,0xb7,0xd4,0xa2,0xa0,0xa1,0x9f,0x4c,0xbb,0x33,0x1e,0x0f +,0x0a,0x07,0x04,0x13,0x09,0x0b,0x3b,0x0d,0x25,0x9b,0xcf,0x8f,0x8c,0x8a,0x82,0x83,0x81,0x81,0x80,0x82,0x81,0x82,0x82,0x82,0x84,0x88,0x8b,0x8e,0xae,0x9c,0x40,0x1f +,0xac,0x13,0x11,0x1a,0x04,0x05,0x06,0x03,0x09,0x0a,0x08,0x0a,0x09,0x0f,0x0f,0x0c,0x0e,0x07,0x0a,0x09,0x0b,0x0c,0x06,0x0b,0x0a,0x0c,0x2e,0x18,0x1f,0xa4,0x25,0xab +,0x92,0xad,0x8d,0x90,0x99,0x8a,0x8f,0x8e,0x8d,0x9d,0x95,0x9f,0xad,0x9f,0xa5,0x9c,0xae,0x91,0x92,0x8f,0x88,0xa8,0x90,0x8b,0xa5,0x94,0x94,0x9a,0x98,0x9b,0x9d,0x92 +,0x98,0xb7,0xab,0xaf,0x9e,0x51,0x2a,0x28,0x1c,0x1a,0x0a,0x1e,0x20,0x12,0x2c,0x0e,0x19,0xc8,0x10,0x26,0x50,0x2f,0xad,0xaf,0xda,0xb8,0xc3,0x2c,0x6b,0x2e,0x19,0x0f +,0x0d,0x09,0x08,0x0b,0x05,0x1a,0x0f,0x10,0x74,0x14,0x2f,0xb1,0x1c,0x5d,0x73,0x31,0xa1,0xed,0x37,0xee,0x28,0x2b,0x3f,0x1e,0x37,0x30,0x46,0xb4,0xc7,0xa7,0xa8,0x89 +,0x8b,0x88,0x80,0x85,0x83,0x82,0x84,0x81,0x80,0x83,0x81,0x82,0x83,0x82,0x8a,0x8e,0x91,0x55,0x2c,0x12,0x08,0x05,0x01,0x01,0x00,0x03,0x02,0x02,0x06,0x01,0x06,0x0f +,0x07,0x0f,0x0f,0x0a,0x1e,0x1c,0x20,0x30,0x1a,0x15,0x1e,0x1a,0x1d,0x25,0x1e,0x1c,0x1f,0x34,0x1d,0xbe,0x38,0x58,0x92,0x52,0x9a,0x8d,0xa8,0x92,0x92,0x92,0x88,0x89 +,0x88,0x89,0x88,0x85,0x86,0x8a,0x8e,0x93,0x91,0xa3,0xa6,0xa8,0x38,0xb1,0x19,0x3e,0x94,0x2c,0xbe,0xa7,0x29,0x98,0x9a,0xaa,0x94,0xa7,0x98,0xa0,0xc8,0xa9,0x33,0x18 +,0x21,0x12,0x16,0x19,0x0e,0x15,0x09,0x12,0x1d,0x1c,0xc5,0x1b,0x21,0xe5,0x16,0x2d,0x2a,0x15,0x29,0x2d,0x23,0x3c,0x2a,0x20,0x24,0x22,0x2e,0x2e,0x1d,0x10,0x18,0x0f +,0x0e,0x20,0x11,0x0e,0x15,0x08,0x19,0x2c,0x10,0x3c,0xec,0x6e,0x8e,0x8e,0x8b,0x83,0x83,0x82,0x83,0x82,0x82,0x82,0x85,0x85,0x83,0x86,0x8a,0x84,0x8b,0x8b,0x81,0x93 +,0x8f,0x8f,0x43,0xb4,0x58,0x1a,0x1b,0x0d,0x0c,0x0e,0x09,0x08,0x05,0x03,0x05,0x04,0x04,0x07,0x03,0x03,0x02,0x0a,0x08,0x11,0x19,0x08,0x1b,0x1c,0x17,0x32,0x3f,0x5f +,0x9f,0xa1,0x94,0x8a,0x96,0xaa,0x98,0xa2,0xa8,0xaa,0xc0,0xa6,0x51,0x1c,0x21,0x9f,0x4e,0xbd,0x90,0xaa,0x8f,0x89,0x9b,0x8a,0x8b,0x8e,0x87,0x89,0x89,0x8a,0x8f,0x97 +,0x97,0xb8,0xa7,0xc2,0x3a,0x2a,0x26,0x2e,0x21,0xc0,0x1b,0x28,0xba,0x25,0xab,0x30,0x1a,0xf5,0x2b,0xc9,0xa9,0xc8,0xac,0xb7,0xb1,0xa9,0xcb,0x32,0x40,0x26,0x1a,0x0e +,0x0c,0x0d,0x09,0x12,0x06,0x0a,0x15,0x09,0x15,0x18,0x12,0x44,0x26,0xbd,0xa2,0x2e,0xa1,0x56,0xbc,0xc9,0x10,0x13,0x10,0x0b,0x12,0x07,0x0c,0x0e,0x18,0xb1,0x31,0x8e +,0x95,0x93,0x80,0x80,0x28,0x56,0x80,0x86,0x80,0x84,0x81,0x86,0x8f,0x85,0x44,0x9a,0x0d,0x05,0x12,0x00,0x05,0x00,0x02,0x01,0x00,0x01,0x01,0x01,0x03,0x02,0x07,0x0d +,0x08,0x16,0x24,0xc0,0x8f,0x8d,0x8f,0xa7,0x8a,0x80,0x89,0x8c,0x84,0x80,0x80,0x83,0x82,0x84,0x86,0x80,0x82,0x80,0x81,0x80,0x84,0x82,0x83,0x85,0x84,0x87,0x88,0x89 +,0x85,0x8f,0x9d,0xa1,0x38,0x25,0x17,0x0c,0x0c,0x08,0x06,0x03,0x08,0x06,0x00,0x02,0x02,0x02,0x02,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x00,0x00,0x01,0x01,0x00,0x01 +,0x01,0x01,0x03,0x03,0x01,0x06,0x0a,0x15,0x0f,0x29,0x2d,0x15,0xad,0xc3,0x96,0x88,0x8d,0x85,0x82,0x82,0x80,0x82,0x81,0x80,0x82,0x80,0x82,0x81,0x84,0x87,0x85,0x83 +,0x80,0x80,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x83,0x83,0x84,0x85,0x83,0x84,0x83,0x8e,0x8a,0x8c,0x96,0x90,0xa5,0x9c,0xab,0xc0,0xc3,0x16,0x0e +,0x0a,0x05,0x09,0x07,0x05,0x03,0x01,0x04,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x04,0x04,0x08,0x09,0x0c,0x0b +,0x0a,0x0b,0x06,0x06,0x08,0x0c,0x0a,0x08,0x08,0x0a,0x0b,0x0f,0x0e,0x12,0x15,0x27,0xc2,0x5b,0xa7,0x99,0x96,0x8f,0x8c,0x8c,0x8a,0x8a,0x88,0x89,0x8a,0x8b,0x8f,0x93 +,0x92,0x91,0x95,0xa5,0x9d,0x8d,0x8d,0x88,0x87,0x87,0x84,0x83,0x81,0x82,0x81,0x81,0x81,0x82,0x81,0x81,0x83,0x87,0x89,0x89,0x87,0x89,0x8f,0x90,0x91,0x96,0x98,0x94 +,0x94,0x8e,0x8d,0x8b,0x8a,0x8c,0x8a,0x86,0x84,0x86,0x86,0x82,0x82,0x82,0x83,0x83,0x87,0x99,0xaa,0x97,0xac,0x14,0x08,0x02,0x03,0x02,0x03,0x05,0x09,0x06,0x09,0x1c +,0x44,0xc1,0xc7,0x9d,0x8f,0x8b,0x8f,0x92,0xa6,0xc5,0x62,0x2b,0x23,0x14,0x09,0x07,0x08,0x05,0x04,0x05,0x04,0x04,0x06,0x04,0x04,0x02,0x02,0x03,0x03,0x05,0x05,0x09 +,0x04,0x07,0x09,0x02,0x03,0x03,0x02,0x01,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x04,0x03,0x02,0x03,0x06,0x09,0x08,0x0c,0x0e,0x0a,0x0c,0x0c,0x0d +,0x0b,0x0c,0x0b,0x0b,0x11,0x14,0x19,0x19,0x29,0x48,0xac,0x99,0x91,0x8e,0x88,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81 +,0x81,0x82,0x81,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x81,0x84,0x88,0x8d,0x94,0x9b,0x37,0x17,0x0d +,0x03,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x03,0x03,0x03,0x04,0x08,0x0d +,0x0d,0x0b,0x09,0x06,0x08,0x0a,0x10,0x0e,0x0a,0x08,0x0b,0x0f,0x10,0x17,0x19,0x1e,0x27,0x35,0x40,0x2f,0x2e,0x4f,0xa6,0x9b,0x94,0x8c,0x8f,0x8d,0x89,0x8c,0x8e,0x8d +,0x8d,0x91,0x94,0x97,0xa2,0xb0,0x9a,0x97,0x96,0x93,0x96,0x96,0x96,0x8d,0x8c,0x8f,0x92,0x92,0x8b,0x8b,0x9b,0x9b,0xa4,0x53,0xe3,0xad,0xa8,0x76,0x29,0x2e,0xb6,0xa4 +,0x48,0x21,0xd3,0xb8,0x38,0x2c,0x71,0x2f,0x14,0x18,0x3b,0xaf,0xb6,0x57,0xab,0x96,0xac,0x45,0x9f,0x8c,0x8c,0x8e,0x8b,0x8d,0x93,0x88,0x84,0x82,0x81,0x82,0x84,0x84 +,0x82,0x83,0x89,0x8a,0x8d,0x93,0x9d,0x78,0x1c,0x09,0x04,0x03,0x04,0x03,0x01,0x01,0x01,0x03,0x06,0x0a,0x0a,0x10,0x1d,0x2a,0x3e,0x73,0x6c,0x47,0xa7,0x97,0x97,0x8d +,0x8c,0x8e,0x8b,0x8d,0x91,0x91,0x92,0x92,0x9b,0x9f,0xb6,0x3d,0xa5,0xa7,0xad,0x97,0x9d,0x9d,0x93,0x8d,0x8c,0x93,0x8f,0x8d,0x8d,0x8a,0x8d,0x9c,0xad,0xac,0xa6,0xac +,0xee,0x4e,0x2f,0x36,0x2b,0x29,0x3a,0x27,0x29,0xf7,0xd8,0x33,0x2d,0x33,0xc7,0xa4,0xaa,0xae,0x9b,0x93,0x9c,0x59,0x62,0x4d,0x1f,0x1b,0x1e,0x13,0x06,0x02,0x09,0x13 +,0x0b,0x07,0x0e,0x23,0x28,0x1c,0x2f,0x44,0x30,0x2b,0x2f,0xc0,0x6e,0x24,0x23,0x25,0x18,0x0d,0x0b,0x0f,0x17,0x0e,0x0a,0x08,0x0c,0x16,0x18,0x41,0xa2,0x9f,0x92,0x8b +,0x88,0x85,0x83,0x81,0x80,0x80,0x80,0x81,0x81,0x82,0x83,0x85,0x89,0x99,0x3d,0x1e,0x0d,0x09,0x07,0x04,0x02,0x04,0x06,0x05,0x05,0x04,0x06,0x09,0x0b,0x0d,0x10,0x11 +,0x12,0x15,0x19,0x18,0x16,0x1a,0x2a,0x2c,0x1e,0x17,0x11,0x1a,0x22,0x1e,0x2b,0x2f,0x23,0x35,0xcb,0xad,0xad,0xa0,0x99,0x8e,0x87,0x89,0x8c,0x8f,0x91,0x94,0x97,0x93 +,0x9d,0x53,0x50,0x58,0x41,0xb6,0xb0,0xba,0xa0,0x9b,0x9b,0x96,0x9b,0xa2,0x9c,0x92,0x97,0x9d,0xa0,0x9e,0xaa,0x4f,0x4a,0xbb,0xdf,0x33,0x49,0x5a,0x26,0x0e,0x11,0x2c +,0x1f,0x15,0x15,0x14,0x17,0x12,0x10,0x1b,0x24,0x16,0x18,0xd8,0xac,0x6d,0x2b,0x33,0x38,0x2c,0x1e,0x16,0x12,0x0f,0x0c,0x0c,0x16,0x12,0x0f,0x16,0x27,0x48,0x39,0x34 +,0x37,0x42,0xb6,0xa8,0x98,0x93,0x92,0x8b,0x89,0x88,0x85,0x83,0x83,0x81,0x81,0x82,0x84,0x83,0x82,0x83,0x85,0x87,0x8e,0x93,0x9b,0xaa,0x4d,0x22,0x15,0x0f,0x18,0x13 +,0x0a,0x07,0x05,0x05,0x06,0x06,0x05,0x03,0x03,0x03,0x04,0x08,0x0a,0x0a,0x0f,0x1c,0x27,0x2e,0x2f,0x37,0x48,0xee,0xdd,0xbd,0xb4,0xb6,0xb7,0xb9,0xd7,0x4a,0xd5,0xb9 +,0xab,0xb6,0xde,0x61,0xc9,0xa9,0xa7,0x9f,0xa3,0xaa,0x9b,0x8d,0x8e,0x99,0x96,0x8d,0x8b,0x8c,0x8c,0x8c,0x8d,0x9a,0xa2,0x9c,0xa6,0x43,0x2e,0x58,0x3f,0x1c,0x1f,0x3e +,0xb5,0xac,0xcc,0xbe,0xa4,0xa4,0xb9,0xb6,0xc5,0x3c,0x2d,0x4c,0x6a,0x33,0x21,0x1b,0x1f,0x1c,0x12,0x0c,0x0d,0x0f,0x0c,0x0c,0x0d,0x0a,0x0b,0x13,0x18,0x20,0x2e,0x2a +,0x34,0x52,0x3f,0x39,0x5a,0xbb,0xcf,0x3b,0x26,0x17,0x0f,0x15,0x1d,0x1f,0x22,0x2d,0x4f,0x9c,0x8c,0x89,0x86,0x83,0x82,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x81,0x82 +,0x85,0x8c,0x91,0x9d,0x3e,0x17,0x0c,0x06,0x04,0x02,0x01,0x01,0x01,0x01,0x02,0x04,0x05,0x09,0x0c,0x18,0x2a,0x2a,0x29,0x36,0xb1,0xae,0xcd,0xda,0x2d,0x1b,0x1a,0x1d +,0x1f,0x16,0x12,0x14,0x1b,0x2e,0x2c,0x36,0xb7,0xb7,0xa4,0x95,0x91,0x98,0x9e,0x92,0x8c,0x8d,0x8d,0x8c,0x8a,0x8a,0x8e,0x8f,0x93,0x9c,0xa9,0xaf,0xaa,0xdc,0x1f,0x20 +,0x3e,0x4e,0xd8,0xbe,0xac,0xa0,0x9c,0x97,0x94,0x95,0x99,0x98,0x91,0x93,0x98,0xae,0x45,0x44,0x2d,0x1e,0x16,0x12,0x0f,0x0f,0x11,0x10,0x0d,0x0c,0x0e,0x16,0x1b,0x1f +,0x18,0x12,0x1c,0x27,0x2a,0x3c,0x58,0x46,0xd2,0xe0,0x35,0x28,0x23,0x1e,0x1b,0x15,0x0d,0x08,0x07,0x0b,0x0f,0x0f,0x16,0x24,0x4c,0x9c,0x8f,0x8b,0x86,0x83,0x82,0x81 +,0x80,0x81,0x81,0x80,0x80,0x81,0x82,0x83,0x84,0x87,0x8d,0x9b,0xce,0x24,0x16,0x0d,0x09,0x06,0x03,0x04,0x06,0x05,0x05,0x07,0x09,0x10,0x14,0x15,0x19,0x19,0x19,0x1b +,0x21,0x1a,0x0f,0x14,0x1b,0x16,0x10,0x10,0x16,0x1f,0x20,0x29,0x3f,0x38,0x46,0xb2,0x9c,0x9c,0xb3,0xa7,0x96,0x93,0x97,0x96,0x90,0x8f,0x8f,0x92,0x94,0x96,0x9a,0xa0 +,0x9e,0xa3,0xc6,0x35,0x3f,0xc9,0xd5,0xd0,0xbb,0xac,0x9c,0x92,0x92,0x97,0x95,0x94,0x92,0x8f,0x95,0x9b,0xae,0xc0,0xb7,0xb9,0xd4,0x3a,0x23,0x21,0x2a,0x22,0x1e,0x18 +,0x17,0x15,0x11,0x13,0x12,0x0f,0x14,0x19,0x1b,0x1b,0x1d,0x26,0x30,0xc0,0xca,0x3a,0x2a,0x23,0x23,0x29,0x24,0x17,0x0e,0x0c,0x0c,0x0b,0x0a,0x0a,0x0a,0x0e,0x18,0x1b +,0x20,0x2e,0xc3,0x9b,0x8d,0x88,0x85,0x84,0x83,0x81,0x81,0x80,0x81,0x80,0x81,0x80,0x80,0x82,0x86,0x89,0x8f,0x9d,0xd7,0x26,0x11,0x09,0x06,0x05,0x05,0x04,0x03,0x05 +,0x0a,0x0a,0x09,0x0a,0x0e,0x0f,0x10,0x17,0x1d,0x18,0x15,0x19,0x22,0x20,0x19,0x1c,0x26,0x33,0x2c,0x23,0x28,0x2b,0x29,0x29,0x46,0x3f,0x2a,0x5f,0xb3,0xac,0xa3,0x9f +,0x97,0x8f,0x8e,0x8e,0x8f,0x8f,0x92,0x91,0x94,0x93,0x9b,0xa3,0x9f,0xa5,0xa5,0xbb,0xb3,0xad,0xa0,0xae,0xaf,0xb8,0xd6,0xbb,0xbf,0xc8,0x6c,0x5a,0x3f,0xc6,0xd9,0xd7 +,0xde,0x61,0x56,0xce,0xb8,0xdb,0x43,0x2a,0x23,0x25,0x2b,0x24,0x20,0x1a,0x17,0x19,0x18,0x1d,0x1e,0x23,0x25,0x25,0x29,0x30,0x3d,0x44,0x31,0x26,0x2a,0x33,0x48,0x49 +,0xcb,0xe3,0x5d,0xbd,0xbe,0xb3,0xbb,0xc5,0xb5,0xc4,0xca,0xc6,0xe7,0x66,0xd3,0xd6,0xf9,0xd2,0xcd,0xba,0xa1,0x9d,0xa1,0xaa,0xb5,0xa7,0x9f,0x9e,0x9f,0x9f,0x9f,0xa0 +,0x9d,0x9f,0x9d,0xa2,0x9d,0x9f,0xa9,0xa7,0xaf,0xae,0xbf,0xba,0xbe,0x4b,0x30,0x22,0x22,0x20,0x1d,0x1d,0x1c,0x1c,0x1d,0x1c,0x1c,0x1b,0x1b,0x1e,0x1b,0x1a,0x1c,0x1c +,0x1d,0x21,0x21,0x22,0x29,0x2e,0x38,0x3d,0x56,0xcd,0xbd,0xb7,0xa8,0xa7,0xaa,0xa2,0xa0,0x9d,0x9b,0x9c,0x9c,0x96,0x9a,0x9b,0x97,0x9c,0x9a,0x9a,0x9d,0x9c,0x9c,0x9c +,0x9e,0xa0,0xa3,0xa8,0xa6,0xa4,0xaa,0xb2,0xae,0xb5,0xba,0xb5,0xdc,0x7e,0xcf,0x4c,0x2e,0x3e,0x2e,0x25,0x1f,0x19,0x1d,0x1f,0x1c,0x1c,0x1f,0x1f,0x1e,0x1c,0x1c,0x1e +,0x1f,0x1c,0x1f,0x26,0x1e,0x1f,0x27,0x23,0x1f,0x1d,0x1d,0x1f,0x22,0x1b,0x1d,0x20,0x1d,0x1d,0x1b,0x1d,0x1f,0x29,0x26,0x2c,0x31,0x3a,0xc3,0xb8,0xad,0xa6,0x9e,0x9b +,0x98,0x95,0x94,0x92,0x90,0x8f,0x8f,0x8d,0x8e,0x8f,0x8e,0x8f,0x91,0x91,0x90,0x94,0x94,0x98,0x9b,0x9f,0xa6,0xab,0xbc,0xc3,0xcd,0x3b,0x2b,0x2a,0x22,0x1c,0x17,0x15 +,0x14,0x13,0x10,0x0f,0x10,0x0f,0x0f,0x10,0x10,0x11,0x14,0x13,0x16,0x19,0x1a,0x1f,0x20,0x28,0x35,0x4c,0x51,0xc5,0xb4,0xb9,0xaf,0xa8,0xa6,0xa9,0xa2,0xa4,0x9e,0x9f +,0xa1,0x9e,0xa0,0x9f,0x9f,0x9f,0xa1,0x9f,0x9e,0x9b,0x9d,0xa0,0x9f,0x9e,0x9e,0xa0,0xa5,0xa1,0xaa,0xaf,0xb0,0xc0,0xc8,0xfa,0xc9,0x6b,0x48,0x4a,0x37,0x34,0x39,0x2f +,0x2d,0x2c,0x2d,0x3b,0x30,0x2f,0x3f,0x3b,0x41,0x45,0x3d,0x4b,0x4d,0x3a,0x38,0x36,0x2e,0x2d,0x2b,0x2e,0x2c,0x2f,0x2a,0x2b,0x33,0x29,0x26,0x2b,0x2c,0x2d,0x2c,0x2f +,0x38,0x32,0x49,0x49,0x66,0xcd,0xda,0xc3,0xbd,0xbd,0xba,0xb5,0xaf,0xac,0xa9,0xac,0xac,0xa5,0xab,0xab,0xa6,0xa6,0xa6,0xa5,0xa9,0xa6,0xa6,0xac,0xae,0xaf,0xb3,0xbb +,0xbc,0xd3,0x62,0x6e,0x4f,0x3a,0x36,0x35,0x2d,0x27,0x29,0x25,0x1e,0x1d,0x1d,0x1c,0x1c,0x1e,0x1e,0x1e,0x1e,0x1f,0x23,0x20,0x23,0x2b,0x2b,0x2e,0x33,0x48,0xe5,0x6e +,0xc8,0xb3,0xb7,0xad,0xab,0xa7,0xa9,0xad,0xa4,0xa9,0xa9,0xa2,0xa6,0xa6,0xa0,0xa5,0xa5,0xa7,0xab,0xa6,0xad,0xb2,0xac,0xa9,0xac,0xae,0xac,0xab,0xae,0xb5,0xaf,0xbc +,0xcc,0xd4,0xe1,0x64,0x4f,0x47,0x35,0x3a,0x37,0x33,0x2f,0x2d,0x2d,0x2d,0x29,0x26,0x2f,0x2b,0x2a,0x34,0x37,0x3e,0x39,0x4c,0x5e,0x65,0x42,0x46,0x6d,0x44,0xf0,0x49 +,0x54,0x71,0x44,0x3d,0x4f,0x40,0x48,0x58,0x3f,0x50,0x4a,0x4f,0xf4,0xd9,0xd0,0xc7,0xb8,0xb8,0xb4,0xb1,0xb6,0xab,0xb0,0xb1,0xa9,0xad,0xac,0xaa,0xb3,0xb5,0xb1,0xb5 +,0xb1,0xbb,0xbf,0xb3,0xb7,0xb6,0xbc,0xbf,0xb3,0xbf,0xbc,0xbb,0xcd,0xc6,0x78,0x4f,0xe5,0x48,0x3f,0x3f,0x35,0x31,0x28,0x28,0x29,0x25,0x21,0x23,0x21,0x1f,0x27,0x23 +,0x29,0x29,0x2c,0x30,0x38,0x38,0x38,0x4b,0x37,0x50,0x58,0xfb,0x75,0xc2,0xcb,0xcf,0xcb,0x6e,0xc1,0xe1,0xc2,0xc9,0xc3,0xbb,0xc8,0xbc,0xb4,0xb5,0xaf,0xac,0xad,0xad +,0xad,0xae,0xb2,0xb0,0xb2,0xb2,0xb4,0xb3,0xb6,0xbd,0xbf,0xcb,0xfc,0xeb,0x50,0x3f,0x49,0x4b,0x4b,0x50,0x46,0x46,0x57,0x5f,0x40,0x54,0x6c,0x4d,0x46,0x68,0x4f,0x5d +,0x6a,0x79,0x6b,0x45,0xf5,0x3f,0x64,0x4b,0x41,0x4e,0x49,0x48,0x49,0x63,0x45,0x50,0x75,0x52,0xd9,0x4e,0x48,0xd7,0x48,0x48,0xdf,0x46,0x65,0x6e,0x47,0xfc,0x4a,0x5f +,0x42,0x52,0x6b,0x57,0x75,0xef,0xe8,0xd6,0xdc,0xcb,0xc9,0xc5,0xbf,0xd4,0xc1,0xcc,0xc1,0xcf,0xc4,0xeb,0xce,0xc4,0xec,0xdc,0xd9,0x56,0x5f,0xd1,0x40,0xdb,0xfe,0x70 +,0xec,0x6b,0xc3,0xe9,0xd6,0xc7,0x69,0x6e,0x71,0x5c,0xf1,0xe6,0x73,0x43,0xef,0xf4,0x71,0x53,0x4e,0x55,0x41,0x4c,0x4a,0xdf,0x45,0xe3,0xd0,0xde,0xca,0xcd,0xbd,0xbc +,0xcd,0x7a,0xbf,0x5d,0x6f,0xcf,0x65,0x5e,0xd0,0x4d,0x62,0x59,0x5a,0x5e,0x3a,0x5f,0x3d,0x51,0x55,0x4c,0x4d,0x54,0x6d,0xf8,0xd4,0xdb,0xe7,0xe9,0xd9,0x49,0xde,0xef +,0x4a,0x67,0x6c,0x47,0xde,0xd1,0x4c,0xdc,0x57,0x6b,0xce,0xd3,0xde,0xdf,0xc0,0xcd,0xcc,0xc9,0xbc,0xc1,0xcc,0xcd,0xd1,0xcc,0xcb,0xc0,0x48,0x7b,0x6a,0x4e,0x6a,0x62 +,0x4a,0x45,0x5a,0xe7,0xed,0x4b,0xf8,0xd1,0xd9,0x5e,0xcf,0xc7,0xcd,0x62,0x63,0x7a,0x58,0x64,0x72,0x69,0x4f,0x4c,0x4b,0x48,0x50,0x48,0x3d,0x57,0x4a,0x74,0xcd,0xec +,0xcf,0xc8,0xde,0xcb,0xc3,0xc7,0xbd,0xcf,0x60,0x60,0xed,0x5a,0x4d,0x49,0x44,0x53,0x47,0x43,0x3d,0x45,0x49,0x3c,0x5f,0x4c,0xe6,0xde,0xdd,0xbf,0xe7,0xbb,0xc3,0xba +,0xb5,0xc9,0xda,0xd5,0xf6,0xf9,0x72,0x48,0x4b,0x54,0x4b,0x43,0x4e,0x44,0x5a,0x3e,0x62,0xf9,0x54,0xd5,0x75,0xc0,0xc5,0xc7,0xb9,0xb5,0xba,0xc0,0xcc,0xeb,0xd7,0x67 +,0x6d,0x4e,0x4b,0x49,0x3d,0x4d,0x3d,0x3f,0x54,0x47,0x65,0xed,0x55,0xcb,0xd2,0xc4,0xcb,0xcf,0xb8,0xb9,0xbd,0xc5,0xcc,0xd4,0xca,0x54,0x65,0x3e,0x4c,0x63,0x31,0x40 +,0x3e,0x3a,0x3f,0x43,0x4c,0x59,0x4f,0xd8,0xce,0xe6,0xf2,0xc5,0xbc,0xd7,0xbf,0xc7,0xcd,0xd0,0xc9,0x7a,0xcc,0x78,0x42,0xd6,0x40,0x3e,0x5d,0x36,0x38,0xe9,0x3e,0x4e +,0x68,0xcb,0xcf,0x74,0xc6,0xb9,0xbc,0xbd,0xbc,0xc1,0xcf,0xd9,0xbe,0xea,0xe1,0xd8,0x7b,0x4f,0x59,0x4b,0x48,0x36,0x3f,0x3e,0x3c,0x71,0x41,0xec,0xfa,0x6d,0xcb,0xca +,0xbd,0xbf,0xc9,0xcb,0xed,0xc6,0xd7,0x4b,0xcf,0x5e,0x55,0x5b,0x56,0x4a,0x46,0x46,0x3e,0x44,0x37,0x42,0x55,0x57,0x51,0x61,0x52,0xd5,0xbd,0xc2,0xca,0xd3,0xc0,0xc5 +,0xf2,0xd8,0xc6,0x59,0xd9,0xdd,0x5f,0x4b,0x4e,0x4e,0x4d,0x43,0x4b,0x4f,0x48,0xef,0x4f,0xf2,0xfc,0xca,0xbd,0xe0,0xca,0xb8,0xd7,0xcd,0xc7,0xdc,0xd2,0xec,0xdf,0xdf +,0x4f,0x4e,0x79,0x5e,0x53,0x54,0x53,0x5e,0x6b,0xe9,0x59,0x53,0xd1,0xed,0xd1,0x6e,0xca,0xd2,0xe4,0x65,0xdb,0xcd,0x53,0xca,0xd5,0x58,0xe8,0xe9,0x54,0x6b,0x46,0xdc +,0x4c,0x5d,0xe1,0x4d,0xcf,0x4d,0x66,0xe0,0x73,0xe5,0xea,0x5e,0x64,0xd9,0x5a,0xe2,0xd6,0xcd,0xef,0xeb,0xdd,0xe0,0x68,0x55,0x54,0x4c,0x58,0x58,0xde,0x44,0xf0,0xe4 +,0x5e,0x78,0xcf,0xfb,0x5c,0xd8,0x4a,0x46,0xe3,0x4b,0xca,0xdb,0x57,0xc5,0xcc,0xef,0x4c,0xb9,0xe5,0x6d,0xd1,0xd7,0x46,0xdf,0xd7,0x59,0xda,0x4c,0x66,0xeb,0x74,0xe8 +,0x61,0x45,0x46,0x58,0xf9,0x5c,0x56,0xf1,0xd8,0x60,0xc5,0x65,0xc7,0xd6,0x73,0xc0,0x59,0xca,0xe3,0x45,0xc9,0xd7,0x4c,0xdb,0xc1,0x62,0x3d,0xd2,0xd1,0x4f,0x43,0x73 +,0xcd,0x4d,0x4b,0xc5,0xef,0x67,0xc4,0x53,0x68,0xda,0xd2,0xcf,0xc8,0x4e,0x4c,0x6d,0x5c,0xcd,0x63,0x6a,0x59,0xec,0xeb,0x4a,0xf2,0xde,0x4f,0xed,0x49,0xd9,0xce,0x42 +,0xf5,0xc9,0xce,0x7a,0xf1,0x5b,0xcb,0x57,0xcc,0xd7,0x7b,0x5d,0x3f,0xde,0x48,0xe0,0x53,0x4d,0xce,0x7d,0x5b,0xf6,0xde,0x52,0x68,0xc5,0xee,0x47,0xd1,0xca,0xda,0x59 +,0xd8,0xbe,0xd5,0x68,0x5a,0xf1,0xd4,0x7c,0x47,0x4c,0x44,0xeb,0x4d,0x59,0x52,0x6a,0xc5,0x49,0xdd,0xbf,0x4a,0xd6,0xbc,0x28,0x2c,0x39,0xbc,0x99,0xa4,0x5a,0xb6,0xb6 +,0x1b,0x31,0xb2,0x2a,0x9d,0x35,0x1f,0x93,0xce,0x16,0x28,0x94,0xa2,0x17,0xb6,0x9d,0x11,0x00,0x2e,0x84,0xda,0xa6,0x93,0xa1,0xa3,0x63,0x11,0x17,0x8c,0x8d,0x6d,0x0f +,0x16,0xb1,0x0b,0x1a,0x82,0x90,0x2a,0x1e,0x2c,0x4a,0x93,0xb3,0x3a,0xe4,0x29,0x16,0x06,0x15,0x8d,0x9d,0x17,0x99,0x8f,0x1e,0x0d,0x8f,0x81,0x8e,0x19,0x07,0x22,0x1f +,0xa9,0x90,0x95,0x90,0x4b,0x0c,0x07,0x4a,0x8f,0x99,0x5e,0x1a,0x20,0x17,0x05,0x21,0x86,0x8a,0xab,0x39,0x13,0x07,0x1a,0x8d,0x80,0x9a,0x1c,0x9c,0x2b,0x1d,0xa4,0x72 +,0x96,0x8e,0xed,0x09,0x16,0x99,0xa2,0x0f,0x14,0x9d,0x21,0x04,0x11,0xa6,0x8c,0x87,0xb7,0x0f,0x32,0x93,0xeb,0x2e,0x9d,0x96,0x2f,0x07,0xa9,0x88,0xbd,0xb1,0x94,0xa5 +,0x4e,0x16,0x1c,0xf5,0xc8,0x41,0x4a,0x20,0x14,0x16,0x07,0x32,0x97,0x92,0x9a,0xb3,0x9b,0x98,0x1e,0x0e,0xd7,0x8d,0x9f,0x21,0xad,0x9d,0x28,0x1c,0xa9,0x94,0x97,0xb5 +,0xc4,0x4d,0x1f,0x1b,0x0d,0x07,0xc1,0x2a,0x10,0x24,0xab,0xa3,0x2f,0x9c,0x88,0x9a,0x10,0x26,0xae,0x99,0x94,0x9b,0xa7,0x99,0x9f,0x19,0x0b,0xb6,0x8b,0x2e,0x10,0x30 +,0xc4,0x0e,0x05,0x23,0x31,0x38,0x4b,0x25,0xbf,0x99,0x8e,0x99,0xa7,0xa9,0xc2,0x22,0x34,0x9e,0x97,0x90,0x94,0x9a,0x3f,0x0f,0x12,0xb3,0x99,0xb7,0x1e,0x1b,0x0d,0x01 +,0x06,0x14,0x97,0x8c,0x93,0x95,0x9e,0xb0,0xca,0x2c,0xae,0x8a,0x9f,0x1c,0x1a,0xad,0x9d,0xce,0x93,0x8e,0x2a,0x11,0x25,0xbd,0xa0,0xdf,0x1d,0x09,0x07,0x0c,0x04,0x25 +,0x8b,0x87,0xaa,0x44,0x9a,0xa0,0x36,0xc4,0x90,0x8f,0xbf,0x1f,0x52,0xa6,0x99,0x97,0xab,0x4d,0xdf,0x2f,0x17,0x26,0x1d,0x1c,0x0b,0x0c,0x16,0x14,0x47,0xa2,0x8c,0x8b +,0x9f,0xc3,0xc1,0x32,0x1e,0x1f,0x97,0x8f,0x99,0x8f,0x98,0x9a,0x9f,0x1e,0x15,0x67,0x9d,0xb9,0x10,0x0d,0x0a,0x04,0x04,0x0e,0xa0,0x8e,0x8d,0x96,0xb6,0xa2,0x9f,0xad +,0xa2,0x9e,0xa4,0x28,0x13,0xaa,0x8c,0x97,0x99,0x98,0x24,0x0f,0x20,0xa3,0x97,0x2b,0x0b,0x04,0x02,0x07,0x14,0x91,0x86,0x87,0x9a,0x19,0x25,0xbf,0x9d,0x8e,0x9d,0xa0 +,0xc3,0x11,0xdb,0x90,0x8a,0x89,0xaf,0x1a,0x0e,0x0b,0x1e,0xb8,0xae,0x28,0x09,0x09,0x06,0x10,0xa8,0x90,0x84,0x8c,0xdf,0x1b,0x1a,0xce,0xcf,0xce,0x98,0x94,0xab,0xa6 +,0x9d,0x99,0x8c,0x9e,0x1e,0x1b,0x2d,0x54,0x15,0x0b,0x0e,0x0a,0x06,0x07,0xc3,0x8d,0x8c,0x89,0x95,0x60,0x2a,0x29,0xb2,0xbe,0xaa,0x96,0xae,0x98,0x93,0x9a,0x9d,0xaa +,0x44,0x18,0x1d,0xc9,0xcd,0x1b,0x0a,0x02,0x0b,0x09,0x1f,0x94,0x8e,0x8a,0xd6,0x1b,0x25,0xb4,0x8e,0x8c,0x96,0x9c,0x3b,0x22,0xb5,0x92,0x88,0x91,0xba,0x1b,0x0b,0x0c +,0x25,0xb1,0xd9,0x16,0x06,0x07,0x02,0x28,0x8c,0x88,0x85,0x90,0x2e,0x0b,0x13,0x9d,0x93,0x9f,0x91,0xa5,0xb8,0xaf,0x9d,0x8c,0x93,0xaa,0x24,0x09,0x10,0x29,0x3a,0x3b +,0x0f,0x0d,0x04,0x04,0x42,0x94,0x85,0x89,0x99,0x2c,0x0e,0x29,0xa7,0x96,0x89,0x92,0xaa,0xbc,0x2b,0xcc,0xb3,0x98,0x9c,0xdb,0x2a,0x1e,0x23,0x1b,0x0f,0x08,0x0c,0x08 +,0x19,0xbb,0x90,0x8c,0xa0,0xc3,0x29,0x2e,0xa3,0x95,0x94,0x8f,0x9e,0xa2,0xaa,0xad,0x97,0x9e,0x3a,0x1f,0x17,0x11,0x11,0x20,0x42,0x13,0x10,0x0e,0x0a,0xb0,0x9b,0x8b +,0x92,0xb8,0xbd,0x15,0x2f,0x99,0x96,0x8c,0x9c,0xbe,0xaa,0xca,0x9c,0xa1,0xa0,0xb2,0x19,0x15,0x13,0x1b,0x37,0x1e,0x0f,0x0b,0x02,0x12,0xa7,0x8b,0x84,0x8a,0x9b,0x25 +,0x11,0x2b,0xaa,0x8f,0x8a,0x98,0xbe,0x4c,0x2a,0x32,0xb3,0xa9,0xa5,0x41,0x22,0x1b,0x1c,0x2f,0x1c,0x18,0x18,0x0b,0x28,0x65,0x9b,0x92,0xb9,0xab,0x1f,0x2a,0xa3,0xa2 +,0x8b,0x8e,0x98,0xa2,0x45,0x52,0x3c,0xcc,0xa9,0x32,0x3a,0x23,0x1c,0x24,0x1e,0x17,0x1a,0x10,0x14,0x54,0xac,0x8f,0xa0,0xa5,0x66,0x25,0x39,0xe7,0xba,0x99,0x9d,0x99 +,0x9e,0x9c,0x9b,0xa1,0xad,0x50,0x1e,0x2c,0x29,0x28,0x39,0x1e,0x10,0x0b,0x08,0x0e,0xbb,0x9b,0x89,0x9d,0xa4,0x3b,0x1e,0x53,0xad,0x99,0x8c,0xa4,0xab,0x4e,0x43,0xba +,0xcc,0x9d,0xdf,0x51,0xca,0x3a,0x73,0x49,0x29,0x14,0x0a,0x09,0x0b,0x5a,0x9d,0x8e,0x9e,0xae,0x34,0x1b,0x48,0xa1,0x94,0x8d,0x9d,0xad,0xbe,0xb8,0xac,0xaf,0xb0,0xf2 +,0x20,0x20,0x1f,0x39,0xb9,0x39,0x2b,0x14,0x14,0x09,0x20,0xcb,0x95,0x99,0xa2,0x3d,0x1d,0x28,0x4d,0xa3,0x95,0x8e,0x9b,0x9c,0xa9,0xad,0xb3,0xb9,0xc6,0x4b,0xda,0xcf +,0x34,0x31,0x19,0x0f,0x08,0x0c,0x09,0x21,0xad,0x8e,0x8d,0x9f,0xa9,0x19,0x2d,0xf8,0xa4,0x93,0x95,0x9a,0xa5,0xcb,0xa4,0xbd,0xaa,0xdf,0x3d,0xd9,0x41,0x6c,0x2b,0x20 +,0x1a,0x0d,0x0f,0x0d,0x0e,0xde,0xc9,0x8f,0xa1,0xa1,0xb4,0x2a,0xa5,0x9d,0x95,0x93,0xa0,0xa2,0xbd,0x53,0xad,0x32,0xda,0x27,0x29,0xc8,0x55,0xb6,0x32,0x1f,0x1a,0x0b +,0x17,0x0e,0x39,0x9b,0x90,0x92,0xca,0x3e,0x11,0x1c,0xb1,0x9f,0x8f,0x91,0xa4,0x9d,0x7d,0xa2,0xb5,0xcd,0xc0,0x26,0x39,0x3e,0x37,0x64,0x1f,0x20,0x13,0x0f,0x17,0x0d +,0xaa,0x9b,0x8f,0x9c,0xe0,0x2d,0x16,0x39,0xa5,0x9d,0x90,0xa6,0xbe,0xc9,0x75,0x9d,0xa4,0x98,0x9d,0x53,0x54,0x2d,0x2d,0x2f,0x15,0x1c,0x0b,0x0e,0x08,0x15,0xa2,0x95 +,0x8f,0x9e,0xdd,0x1f,0x24,0xbf,0x98,0x8f,0x8d,0xa5,0xb4,0x39,0xd9,0xd4,0xb1,0xa7,0xc5,0x4b,0xf1,0x3f,0x36,0x39,0x22,0x1b,0x0e,0x10,0x09,0x25,0xad,0x96,0x9d,0xae +,0x5a,0x1f,0x40,0xa8,0x93,0x8f,0x91,0xad,0xf4,0xc8,0xa9,0xa9,0x9f,0xbc,0x48,0x22,0x24,0x20,0x2a,0x30,0x1e,0x18,0x1a,0x0f,0x17,0xba,0x9a,0x93,0xaf,0xad,0x1d,0x1c +,0x48,0xad,0x99,0x94,0x9a,0xa7,0xbc,0x9c,0xa4,0xac,0xa9,0x5a,0xe1,0x2f,0x5a,0x3a,0x23,0x1a,0x0e,0x09,0x0f,0x0b,0x25,0xae,0x91,0x90,0xa0,0xa3,0x29,0x5d,0xaa,0x9f +,0x9a,0x9b,0xae,0xbe,0xc7,0x9f,0xba,0xac,0xaf,0xee,0xc1,0x3f,0x57,0x25,0x20,0x17,0x0c,0x0f,0x0e,0x0e,0x33,0xbb,0x95,0x9d,0xa1,0xab,0x44,0xa1,0xa0,0x9b,0x95,0x9d +,0xa3,0xbd,0xba,0xb3,0x35,0xc3,0x38,0x36,0x6c,0x40,0x3b,0x22,0x22,0x1f,0x0e,0x17,0x12,0x1e,0xaf,0x9a,0x8f,0xaa,0xbb,0x24,0x20,0xbc,0xb1,0x9b,0x93,0x9d,0x9f,0xd3 +,0xae,0xb6,0xad,0xa4,0x47,0x6b,0x4c,0x23,0x20,0x18,0x1c,0x13,0x11,0x1a,0x10,0x76,0x9f,0x90,0x9b,0xa8,0x6b,0x24,0x39,0xaf,0xa8,0x9a,0xa0,0xab,0xc7,0xcb,0xa6,0xa9 +,0x99,0x9f,0xb2,0xcf,0x41,0x21,0x1b,0x17,0x13,0x0d,0x0e,0x09,0x1b,0xaf,0x93,0x97,0x9b,0xa8,0x2f,0x38,0xb3,0x9d,0x93,0x90,0x9e,0xab,0xcc,0xb1,0xcd,0xb6,0xb4,0xec +,0x58,0x3a,0x22,0x1b,0x19,0x17,0x11,0x16,0x0f,0x1f,0xb7,0x96,0x9b,0xad,0xdd,0x22,0x44,0xb6,0x9e,0x94,0x91,0x9b,0xae,0xb2,0xa3,0xab,0xa7,0xb3,0x4b,0x3c,0x20,0x1a +,0x14,0x18,0x16,0x0e,0x1c,0x13,0x30,0xa2,0x94,0x97,0xa3,0xc9,0x21,0x42,0xb5,0xa9,0x98,0x99,0xa4,0xa9,0xae,0xa6,0xa9,0xa7,0xb1,0xf4,0xc7,0x3a,0x20,0x1c,0x18,0x12 +,0x0d,0x0f,0x0c,0x1e,0xad,0x9b,0xa2,0x9c,0xbb,0x49,0xb5,0xaa,0x9a,0x94,0x97,0xa1,0xa9,0xb0,0xb5,0xbb,0xac,0xc0,0x5a,0x41,0x35,0x20,0x1a,0x1c,0x10,0x11,0x10,0x10 +,0x2e,0xab,0x9f,0xb2,0xae,0x3b,0x3f,0xaf,0x9e,0x97,0x91,0x92,0x9c,0x9e,0x9f,0xa5,0xb7,0xb3,0x3d,0x2c,0x26,0x1a,0x17,0x11,0x14,0x0e,0x10,0x12,0x1b,0xba,0x9e,0x9f +,0x9d,0xa1,0xbb,0xab,0xae,0xa4,0xaa,0x9c,0x9e,0xa3,0xa1,0xa7,0xab,0xb6,0xca,0x63,0x4d,0x4e,0x2c,0x19,0x18,0x12,0x10,0x0f,0x11,0x29,0xbe,0xa7,0xaf,0xa7,0xaf,0xad +,0xa0,0xa6,0x9e,0x9e,0x9b,0x9e,0x9b,0x9d,0xa9,0xdc,0x51,0x39,0x51,0x56,0x6c,0x2c,0x1e,0x17,0x0e,0x13,0x0f,0x1d,0x37,0xcc,0x3e,0x3e,0x42,0x5b,0xa4,0x9e,0x9e,0x9e +,0x9e,0x99,0x9a,0x93,0x95,0xa4,0xb6,0xc8,0xed,0x31,0x5f,0x2e,0x22,0x1b,0x0f,0x0d,0x12,0x10,0x28,0xbd,0xe0,0xca,0x50,0xd4,0xb6,0x9e,0x9a,0x9f,0xa6,0xa9,0x9c,0x9b +,0x96,0x9b,0xa8,0xb0,0x4e,0x2f,0x33,0x44,0x2f,0x26,0x19,0x0f,0x0d,0x0c,0x16,0x2f,0xf6,0x3b,0x4c,0xc7,0xd5,0x9c,0x96,0x98,0x9d,0x9e,0xa4,0x9e,0x9b,0x97,0xa7,0xbb +,0xed,0x3a,0xe7,0x38,0x4e,0x2e,0x25,0x1a,0x12,0x15,0x0e,0x1e,0x4c,0x4a,0x2a,0x2b,0x3d,0x39,0xa2,0x9a,0x9e,0x9f,0x9f,0xa2,0x95,0x90,0x95,0x9f,0xa3,0xc1,0xcb,0xdd +,0x3f,0x42,0x22,0x1c,0x11,0x14,0x0d,0x0f,0x1f,0x42,0x2c,0x1f,0x31,0x2c,0xb9,0x9d,0x9d,0x9e,0xa0,0xa9,0x9e,0x94,0x8e,0x93,0x9f,0x9f,0xc5,0xba,0xbf,0xed,0x38,0x23 +,0x1b,0x0e,0x0f,0x0a,0x0f,0x1f,0x20,0x1d,0x2e,0x32,0xf5,0xa3,0x9a,0x97,0x9c,0x96,0x9d,0x98,0x93,0x93,0x9d,0xa7,0xbc,0xcc,0xc3,0x51,0x3d,0x2a,0x1f,0x13,0x12,0x10 +,0x0d,0x1a,0x2a,0x1f,0x1f,0x34,0x33,0xbb,0x9f,0x9a,0x99,0x9b,0x9a,0x9a,0x91,0x91,0x94,0xa0,0xa6,0xcf,0xbf,0xca,0x31,0x23,0x1c,0x19,0x10,0x12,0x0e,0x12,0x23,0x2c +,0x1d,0x2d,0x57,0xcc,0xa2,0x9d,0x9c,0xa1,0xa0,0x9e,0x97,0x90,0x8f,0x9b,0xa3,0xa8,0xc5,0xb2,0xb8,0x47,0x24,0x1c,0x12,0x0e,0x0d,0x0c,0x18,0x1f,0x1c,0x19,0x2b,0x3b +,0xa9,0x9a,0x9b,0x98,0x9f,0x9a,0x9c,0x92,0x8d,0x94,0xa0,0xa4,0xc0,0xbe,0xbf,0x53,0x33,0x1e,0x1a,0x10,0x10,0x0d,0x15,0x1e,0x1d,0x13,0x1b,0x2b,0x38,0x9f,0x99,0x99 +,0x9d,0x9a,0x97,0x90,0x8c,0x8d,0x96,0x9f,0xa8,0xc7,0xe7,0x44,0x25,0x1b,0x1a,0x11,0x12,0x0f,0x0d,0x19,0x1d,0x1a,0x17,0x35,0x44,0xae,0x9a,0x99,0x9a,0xa1,0x9d,0x9a +,0x8f,0x8e,0x90,0x9b,0x9e,0xb1,0xbc,0xc7,0x45,0x29,0x1e,0x16,0x0f,0x12,0x0b,0x12,0x1a,0x1b,0x13,0x1d,0x36,0xe2,0x9b,0x98,0x97,0x9c,0x9b,0x9d,0x94,0x8e,0x8f,0x9d +,0x9e,0xa9,0xc2,0xae,0x45,0x32,0x20,0x1f,0x12,0x15,0x14,0x0f,0x19,0x1b,0x17,0x14,0x23,0x26,0xc7,0x9e,0x99,0x9a,0x9b,0x9b,0x99,0x8f,0x8f,0x8f,0x9c,0x9b,0xa6,0xb3 +,0xbc,0x38,0x21,0x1a,0x19,0x10,0x16,0x0f,0x11,0x1c,0x1c,0x15,0x1a,0x2b,0x35,0xa9,0x9e,0x9b,0x9f,0x9c,0x9c,0x99,0x8e,0x8e,0x97,0x9e,0x9e,0xa9,0xab,0xbb,0x2f,0x21 +,0x1d,0x17,0x12,0x15,0x0d,0x14,0x19,0x17,0x12,0x1c,0x32,0x65,0x9d,0x99,0x97,0x9b,0x98,0x97,0x93,0x8f,0x92,0x9e,0xaa,0xad,0xb0,0xb4,0xe0,0x3b,0x1e,0x1a,0x14,0x15 +,0x14,0x0f,0x1e,0x1d,0x16,0x12,0x21,0x2a,0xb3,0x9b,0x9f,0x9b,0x9a,0x97,0x96,0x8f,0x8f,0x94,0x9f,0xa0,0xb0,0xaf,0xba,0x37,0x23,0x1c,0x1a,0x10,0x15,0x11,0x10,0x1d +,0x1f,0x18,0x18,0x2e,0x3b,0xaa,0x9e,0x9c,0x9c,0x9d,0x96,0x94,0x90,0x91,0x97,0xa2,0xa7,0xad,0xb8,0xbd,0x44,0x23,0x1c,0x16,0x10,0x14,0x0e,0x14,0x1f,0x19,0x16,0x1c +,0x36,0x6d,0x9e,0x9d,0x9b,0x9b,0x9b,0x97,0x90,0x8d,0x94,0x9d,0xac,0xaf,0xcd,0xbc,0x5d,0x32,0x21,0x1c,0x17,0x16,0x19,0x0e,0x18,0x1e,0x1c,0x18,0x22,0x2f,0xe7,0xa0 +,0x9b,0x9e,0x9c,0x9a,0x98,0x8f,0x8f,0x91,0xa0,0xb0,0xbf,0xbf,0xdd,0x75,0x32,0x1f,0x1c,0x1b,0x13,0x1a,0x10,0x15,0x26,0x1f,0x1c,0x26,0x45,0x63,0x9f,0x9f,0xa0,0xa4 +,0x9b,0x9a,0x93,0x8f,0x92,0xa1,0xb4,0xae,0xb2,0xb9,0xd4,0x30,0x23,0x1e,0x1a,0x16,0x1b,0x0e,0x13,0x1e,0x1d,0x1c,0x23,0x46,0x78,0x9f,0x9e,0x9e,0xa7,0x9c,0x9b,0x90 +,0x92,0x94,0xa0,0xae,0xb2,0xb1,0xb8,0x5c,0x30,0x27,0x25,0x20,0x22,0x19,0x11,0x0c,0x1c,0x1d,0x1b,0x1c,0x4c,0x3f,0xad,0x9e,0xa0,0xa1,0x9e,0x98,0x95,0x8e,0x92,0x9b +,0xaf,0xaf,0xba,0xb4,0x62,0x35,0x23,0x21,0x26,0x1e,0x1e,0x17,0x0e,0x18,0x1f,0x1d,0x1c,0x49,0x4f,0xc4,0xa4,0xa5,0xa8,0x9e,0x9a,0x94,0x90,0x96,0x98,0xa7,0xa7,0xa8 +,0xa5,0xd0,0x35,0x1f,0x23,0x22,0x20,0x1b,0x19,0x0b,0x0e,0x1e,0x1c,0x1c,0x31,0xc0,0x6e,0x9e,0x9f,0xa4,0xa3,0x98,0x9b,0x93,0x90,0x94,0xa7,0xab,0xa9,0xb4,0xbc,0x4c +,0x26,0x20,0x2e,0x20,0x18,0x1a,0x10,0x0b,0x1a,0x20,0x1d,0x26,0xc5,0x50,0xaf,0x9e,0x9e,0x9f,0x9b,0x98,0x92,0x91,0x96,0x9e,0xaa,0xad,0xae,0xbe,0x34,0x2e,0x22,0x26 +,0x23,0x25,0x19,0x15,0x0c,0x18,0x25,0x23,0x21,0x3d,0xde,0xfd,0x9f,0x9f,0xa1,0x9f,0x98,0x9f,0x93,0x91,0x9a,0xab,0xa7,0xab,0xc0,0x55,0x36,0x26,0x24,0x26,0x1e,0x1b +,0x18,0x10,0x0e,0x24,0x28,0x26,0x2d,0xbf,0xed,0xa4,0x9e,0xa4,0xa7,0x9c,0x9d,0x97,0x91,0x99,0xa6,0xb5,0xab,0xbd,0xb8,0x3f,0x3a,0x28,0x2b,0x1f,0x1e,0x17,0x16,0x0d +,0x18,0x2d,0x28,0x24,0x35,0xc1,0xc2,0x9c,0xa3,0xa7,0xa6,0x9b,0x9f,0x90,0x92,0x9d,0xab,0xac,0xbe,0xb6,0xba,0x48,0x2d,0x28,0x24,0x1c,0x1b,0x19,0x15,0x11,0x21,0x20 +,0x1f,0x1f,0xde,0xdc,0xa8,0xa1,0xa8,0xac,0x9b,0x9b,0x93,0x8e,0x98,0xa2,0xae,0xaf,0xbe,0xac,0x6c,0x37,0x28,0x24,0x1c,0x20,0x19,0x18,0x0f,0x19,0x21,0x1f,0x1d,0x3d +,0xc1,0xbf,0xa2,0xa9,0xae,0xa2,0x96,0x9b,0x8f,0x92,0x9e,0xb1,0xa3,0xb3,0xac,0xb6,0x47,0x25,0x25,0x22,0x1d,0x1b,0x1c,0x11,0x10,0x21,0x1b,0x1b,0x2b,0xb8,0x4f,0xa5 +,0xa5,0xab,0xa7,0x94,0x9a,0x93,0x8f,0x9e,0xae,0xa5,0xa7,0xb6,0xa9,0x4e,0x29,0x22,0x24,0x1b,0x1f,0x1c,0x14,0x0d,0x1b,0x1e,0x1c,0x25,0xd5,0xcc,0xb5,0x9e,0xa9,0xa8 +,0x97,0x94,0x9c,0x8f,0x96,0xad,0xb6,0x9f,0xb7,0xb8,0xca,0x29,0x1f,0x2a,0x24,0x1f,0x1e,0x19,0x0e,0x13,0x20,0x1f,0x22,0x33,0xc8,0xd3,0xa1,0xa5,0xa7,0x9f,0x94,0x9a +,0x97,0x92,0x9e,0xb2,0xa4,0xaa,0xb4,0xbb,0x3a,0x21,0x22,0x2b,0x23,0x1c,0x1b,0x11,0x0e,0x1e,0x1f,0x23,0x28,0xd0,0x5d,0xab,0x9f,0xa5,0xa3,0x98,0x9a,0x9b,0x90,0x99 +,0xa7,0xa4,0xa3,0xbb,0xb5,0xcc,0x28,0x1f,0x2a,0x22,0x1c,0x1a,0x15,0x0e,0x1a,0x1f,0x1f,0x24,0x3d,0xcf,0xb7,0xa1,0x9f,0x9e,0x9c,0x9b,0x9d,0x93,0x94,0x9f,0xa5,0xa3 +,0xb4,0xbd,0xc2,0x2e,0x21,0x29,0x21,0x1b,0x1b,0x16,0x0e,0x1a,0x20,0x1b,0x21,0x38,0x4c,0xbd,0x9f,0xa0,0x9f,0x99,0x9a,0x9d,0x91,0x91,0x9f,0xa4,0xa2,0xb0,0xb7,0xcf +,0x2e,0x23,0x2a,0x21,0x1b,0x1a,0x17,0x0e,0x15,0x23,0x1e,0x1e,0x2b,0x3f,0x7b,0x9f,0x9e,0xa0,0x9d,0x98,0x9e,0x98,0x8f,0x99,0xa1,0x9e,0xa9,0xbe,0xc3,0x34,0x20,0x24 +,0x27,0x1a,0x18,0x18,0x0e,0x15,0x22,0x1d,0x1c,0x2e,0x43,0xea,0x9e,0x9d,0xa7,0x9c,0x98,0x9e,0x97,0x8f,0x9b,0xa2,0x9b,0xa9,0xb8,0xae,0x3f,0x1d,0x29,0x26,0x1c,0x18 +,0x1a,0x0d,0x13,0x1e,0x19,0x19,0x2c,0x4e,0x4c,0x9f,0x9d,0xa5,0x9f,0x95,0x9a,0x94,0x8f,0x95,0xa0,0x9c,0xa3,0xc5,0xc0,0x3f,0x1e,0x1f,0x21,0x1a,0x1a,0x1a,0x10,0x14 +,0x22,0x1a,0x19,0x2b,0x4d,0xe9,0xa0,0x9b,0xa2,0x9d,0x96,0x9b,0x99,0x8e,0x91,0x9e,0x9e,0xa8,0xcc,0x65,0x4b,0x20,0x22,0x25,0x1d,0x16,0x1a,0x11,0x10,0x1f,0x1b,0x17 +,0x25,0xee,0x46,0xa6,0x9b,0x9e,0x9e,0x93,0x9a,0x98,0x8f,0x95,0x9e,0x9d,0xa5,0xde,0x74,0x2e,0x1e,0x28,0x28,0x1a,0x1a,0x17,0x0d,0x14,0x20,0x19,0x1c,0x2b,0x3c,0x5b +,0xa2,0x9f,0x9f,0x9a,0x94,0x9a,0x95,0x90,0x96,0x9c,0x9d,0xa5,0xc7,0xeb,0x2c,0x1e,0x23,0x28,0x1b,0x18,0x16,0x0e,0x11,0x1e,0x19,0x1d,0x35,0x42,0x7b,0xa2,0xa6,0xa1 +,0x97,0x95,0x97,0x92,0x8e,0x96,0x9c,0x96,0xa1,0xb8,0xc8,0x2c,0x20,0x1e,0x2b,0x1a,0x1a,0x11,0x0b,0x10,0x20,0x1d,0x38,0x4a,0xf3,0x23,0x9a,0x8e,0x8f,0x8d,0xa0,0x92 +,0x09,0x0a,0x03,0x1b,0x95,0x1a,0xc5,0x0a,0x18,0x96,0xaa,0xb1,0x4c,0xa8,0xd0,0x8e,0x8d,0x7d,0x95,0x94,0x41,0x8f,0x30,0xc7,0x85,0x94,0x8d,0x8f,0xa0,0x2e,0x45,0x19 +,0x20,0x0f,0x0b,0x03,0x0b,0x0a,0x02,0x07,0x07,0x06,0x00,0x0c,0x02,0x06,0x0e,0x1d,0x2f,0x9e,0x98,0x93,0x89,0x87,0x87,0x89,0x85,0x84,0x84,0x82,0x87,0x84,0x85,0x82 +,0x83,0x82,0x86,0x8c,0x85,0x18,0x26,0x93,0x88,0x19,0x05,0x19,0x01,0x12,0x07,0x02,0x07,0x05,0x00,0x75,0xb7,0x09,0x08,0x00,0x4c,0x1b,0x08,0x05,0x0c,0x26,0x17,0xcc +,0x1e,0x0e,0x08,0xaf,0x90,0x8d,0x8f,0x8c,0xda,0xa9,0x80,0x88,0x84,0x80,0x84,0x8b,0x80,0x88,0x80,0x85,0x82,0x96,0x92,0x94,0x98,0x9b,0x2b,0x2c,0x06,0x0d,0x07,0x09 +,0x01,0x02,0x00,0x03,0x08,0x05,0x08,0x0d,0x12,0x08,0x16,0x19,0x12,0x14,0x2b,0x93,0x8c,0x90,0xb1,0x90,0x86,0x87,0x97,0x8e,0x8c,0x34,0xa1,0x98,0xad,0x6b,0x97,0x29 +,0x25,0x83,0x9a,0xb8,0x84,0x85,0x86,0x8d,0x86,0x9a,0x8b,0x97,0x26,0xc7,0x1b,0x9c,0x00,0x07,0xb7,0x07,0x04,0x05,0x03,0x03,0x0d,0x05,0x13,0x17,0x02,0x02,0x09,0x06 +,0x25,0x88,0x2a,0xab,0x9b,0x8c,0x85,0x32,0x89,0x85,0x85,0x80,0x8e,0x8d,0x85,0x83,0x8b,0x82,0x92,0x99,0xde,0x30,0x31,0x2b,0x18,0x06,0xa9,0x0e,0x13,0xbc,0x5d,0x2b +,0xb0,0x3c,0x1f,0xc8,0xbe,0x89,0x24,0x06,0x8f,0x96,0xa3,0xde,0x0b,0x03,0x1d,0x9d,0x1f,0xb4,0x04,0x00,0x00,0x06,0x1c,0x15,0x1e,0x14,0x26,0x0a,0x2a,0x12,0x16,0xbe +,0x2c,0xc3,0x01,0x9f,0x80,0x5a,0xb2,0x3a,0xcf,0x89,0x80,0x8d,0x8e,0x9d,0x93,0x58,0xc0,0x8b,0x37,0x94,0x4c,0x29,0xa6,0x2b,0x11,0x8b,0x9c,0x9b,0xa8,0x3c,0x95,0x34 +,0x80,0x8b,0x15,0xa1,0x92,0x29,0xd7,0x9c,0x2c,0x1e,0x1f,0x1c,0x15,0xce,0xbd,0xb6,0x8b,0x0b,0x5d,0x92,0x8a,0x80,0x8a,0x27,0xc6,0x8c,0xa9,0x9a,0x9a,0x86,0x05,0x0c +,0xa6,0x87,0x36,0x04,0x13,0x19,0x28,0x00,0x15,0x04,0x07,0x00,0x0e,0x17,0x00,0x8f,0x0b,0x0a,0x2b,0x03,0x15,0x45,0x86,0x34,0x09,0x0f,0x24,0x5f,0xcf,0x89,0x0d,0x1c +,0x0a,0x0a,0x93,0x9a,0xa9,0x0a,0x19,0xa8,0xa0,0x92,0x85,0x80,0x81,0x97,0x8a,0x80,0x84,0x81,0x83,0x80,0x81,0x80,0x8a,0x8e,0x8d,0x80,0x88,0x1b,0x48,0x1f,0x0c,0x03 +,0x05,0x01,0x00,0x04,0x00,0x00,0x06,0x07,0x00,0x19,0x07,0x00,0x09,0x05,0x0b,0x0a,0x05,0x22,0xe6,0x1b,0x1d,0x01,0x25,0xc4,0xac,0x8c,0x8c,0x12,0x06,0x29,0x26,0x89 +,0xa7,0x49,0x1e,0x9e,0x81,0x92,0x80,0x89,0x8a,0x83,0x8b,0x80,0x85,0x83,0x8b,0x94,0x80,0x87,0xa6,0x7e,0x9b,0xc5,0x34,0x16,0x10,0xb3,0x06,0x04,0x13,0x1d,0x02,0x06 +,0x0f,0x06,0x19,0xa9,0x0a,0x0d,0x88,0xa1,0xa4,0x9a,0x9c,0xd4,0x89,0x99,0x8b,0x98,0x4b,0x9d,0x2a,0x8c,0x9b,0x2c,0x98,0xec,0x2d,0x1d,0x14,0x9c,0x10,0xb5,0x17,0xde +,0x87,0x0d,0x05,0x99,0x99,0x34,0x1c,0x35,0x1d,0x08,0xcb,0x3d,0x08,0x09,0x1f,0x05,0x23,0x08,0x01,0x0b,0x0d,0x94,0xa5,0x39,0xb6,0x42,0x88,0x86,0x86,0x80,0x85,0x80 +,0x81,0x84,0x8d,0x80,0x84,0x8c,0x95,0x9f,0x91,0x22,0xbc,0x1b,0x27,0x5c,0x13,0x06,0x0b,0x0d,0x0b,0x0d,0x0e,0x21,0x00,0xb1,0x0d,0x04,0x38,0x16,0x14,0xa3,0x3e,0x12 +,0x29,0x09,0x26,0x29,0x2b,0x07,0x04,0x26,0x16,0x05,0x12,0x20,0x0d,0x11,0x32,0x3b,0xad,0x2f,0x1a,0x2b,0x95,0x92,0x9e,0x80,0x8a,0x8c,0x81,0x91,0x8b,0x84,0x87,0x84 +,0x84,0x84,0x80,0x9e,0x8c,0x94,0x23,0x8d,0x8b,0xb1,0x1b,0x28,0x1d,0x2d,0x3c,0x1f,0x06,0xa9,0x17,0x17,0x8b,0x0e,0x15,0x99,0xc8,0x94,0xa1,0x0e,0x3e,0x3a,0x2a,0x43 +,0x2c,0x56,0x0c,0x01,0x35,0x0f,0x09,0x09,0x0e,0x0e,0x03,0x04,0x06,0x05,0xb6,0x09,0x1e,0x8a,0x0b,0x1c,0x9b,0xbb,0x1d,0x8e,0x22,0x2a,0xae,0x94,0x96,0xa9,0x89,0xa8 +,0x86,0x80,0x85,0x86,0x80,0x85,0x82,0x81,0x82,0x8f,0x8b,0x82,0x96,0x85,0x8d,0xab,0x9b,0x8b,0x0e,0x25,0x37,0x06,0x0e,0x02,0x0a,0x06,0x04,0x03,0x00,0x06,0x09,0x07 +,0x00,0x0a,0x0e,0x0c,0x10,0x14,0x01,0x0a,0xc5,0x10,0xab,0x8c,0xcd,0xaa,0x8c,0xe0,0x8b,0x80,0x8e,0x8c,0x86,0x8c,0x8d,0x8c,0x8c,0x98,0x8e,0x9c,0x51,0xa5,0x96,0xc7 +,0x1d,0x96,0x26,0x2f,0xae,0x87,0x1d,0xa2,0x87,0x21,0xbd,0x98,0xdf,0x21,0x99,0x17,0x16,0xc2,0x2a,0x0d,0x20,0xae,0x19,0x21,0xaf,0x22,0x14,0xc9,0x24,0xbe,0x1c,0x07 +,0x16,0xde,0x88,0x0a,0x9f,0x89,0x51,0x87,0x87,0xb3,0x93,0x86,0xa1,0x97,0x39,0xd5,0x17,0xc1,0xea,0x08,0x11,0x10,0x19,0x1b,0x37,0x10,0x0b,0x05,0x13,0x07,0x08,0x21 +,0x00,0x0a,0x1a,0x00,0x16,0xaf,0x22,0x94,0x98,0x92,0x9d,0x8d,0x80,0x85,0x86,0x81,0x83,0x82,0x82,0x8b,0x88,0x80,0x89,0x8f,0x89,0xa3,0x92,0x49,0x8f,0x3b,0x1c,0x95 +,0x0c,0x35,0x9f,0x02,0x1e,0x48,0x08,0x07,0x0f,0x12,0x0a,0x0f,0x12,0x0d,0x07,0x17,0x0e,0x07,0x10,0x0b,0x07,0x03,0x06,0x00,0x0e,0x34,0x00,0x0f,0xad,0x1c,0xb5,0x8f +,0x27,0x8a,0x87,0xa5,0x86,0x8f,0x8c,0x8b,0x87,0x80,0x95,0x8b,0x87,0x8a,0x85,0x8c,0x91,0x8e,0x9e,0xa8,0xb6,0x3f,0x8b,0x18,0x1e,0x8c,0x0e,0x9c,0x97,0x18,0x90,0xa6 +,0x20,0xab,0xbe,0x23,0x2a,0xb3,0x5e,0x11,0x1b,0x16,0x19,0x31,0x2e,0x0f,0x28,0x1d,0x18,0x10,0x2b,0xa0,0x02,0xb2,0x9c,0x06,0x9c,0xc4,0x0a,0x38,0x25,0x0f,0x1a,0x5c +,0x13,0x1a,0x2d,0x1b,0x0f,0x0e,0x23,0x11,0x14,0x2a,0x05,0x0a,0x16,0x0a,0x0b,0x29,0xae,0x18,0x8a,0x84,0x94,0x81,0x82,0x84,0x82,0x80,0x84,0x83,0x80,0x84,0x83,0x84 +,0x87,0x91,0x96,0x94,0x39,0x40,0x24,0x0d,0x0d,0x04,0x07,0x03,0x04,0x02,0x00,0x0f,0x07,0x00,0x1f,0x0c,0x0d,0xa8,0x11,0x14,0x2e,0x32,0x1c,0xcd,0x64,0x15,0x14,0x41 +,0x18,0x12,0xb6,0x1d,0x32,0xbe,0x28,0x5b,0x1c,0x9b,0x99,0x2f,0x88,0xa1,0xae,0x85,0xa3,0xb4,0x80,0xa0,0x96,0x8a,0x95,0x8d,0x8e,0x94,0x90,0x9a,0xc2,0x9d,0x9d,0x9e +,0x1f,0x1f,0x1b,0x2a,0x0e,0x0d,0x9f,0x0e,0x3a,0x8c,0x17,0x9f,0x90,0x2b,0x95,0x8f,0x2f,0xcf,0xd4,0x28,0xac,0x1c,0x2e,0x2c,0x1d,0x39,0x27,0xd5,0x1c,0x27,0x24,0x10 +,0xc1,0x0e,0x1b,0x3f,0x06,0xa9,0x2c,0x15,0x97,0x37,0x1f,0x98,0x7d,0x27,0xaf,0x2b,0x2b,0x32,0x29,0x0b,0x08,0x0c,0x08,0x0d,0x15,0x0e,0x14,0x1b,0x29,0xb5,0x94,0x86 +,0x91,0x85,0x80,0x87,0x81,0x82,0x84,0x81,0x81,0x83,0x82,0x86,0x89,0x89,0x87,0x8e,0x2f,0xb9,0x2d,0x0c,0x23,0x0a,0x04,0x03,0x03,0x00,0x04,0x0f,0x00,0x11,0x19,0x01 +,0x1a,0x19,0x08,0x2b,0x28,0x0d,0x29,0x23,0x15,0x1d,0xd6,0xbb,0x17,0x53,0xba,0x25,0x9e,0xc9,0x2d,0x2a,0x4a,0x15,0x4a,0x8d,0x0d,0x9f,0x8b,0x3b,0x8e,0x8d,0xa1,0x87 +,0x88,0x8d,0x8b,0x88,0x8e,0x9c,0x8a,0x8f,0xa7,0x9b,0xbf,0x2d,0x9f,0x2c,0x2a,0x1c,0x1c,0x10,0xa5,0xae,0x0f,0x8d,0x22,0x2d,0x8e,0xdd,0xd9,0xad,0x32,0x38,0x3e,0xad +,0x3a,0x73,0x99,0xe2,0x4b,0x9f,0x23,0x2f,0xa3,0x1e,0x14,0x1f,0x05,0x05,0xac,0x06,0x20,0x9d,0x03,0x20,0x9f,0x0c,0x36,0xdc,0x12,0x1c,0x3a,0x18,0x07,0x1b,0x0e,0x06 +,0x1d,0x0f,0x0b,0x26,0x1a,0x1c,0xbb,0xb1,0x34,0x85,0x8c,0x8d,0x80,0x85,0x81,0x80,0x84,0x83,0x80,0x82,0x81,0x84,0x81,0x8b,0x8d,0x8b,0x3d,0xc1,0x49,0x0a,0x17,0x0b +,0x00,0x03,0x02,0x01,0x08,0x01,0x0a,0x23,0x01,0x17,0x34,0x08,0x1a,0x22,0x1a,0x25,0x23,0x13,0x13,0x41,0x28,0x11,0x57,0x30,0x2a,0xc8,0xe4,0x2e,0x4e,0x1d,0x28,0x8d +,0x18,0x95,0x8b,0x1f,0x88,0x8e,0xbb,0x87,0x89,0x95,0x88,0x87,0x93,0x8f,0x8b,0x99,0x9d,0x9b,0x57,0x27,0x57,0x0f,0x12,0x1f,0x0d,0xa2,0x13,0x1e,0x90,0x0d,0x9c,0x8e +,0xc3,0x88,0x87,0xab,0x9a,0xa1,0x42,0x33,0x9d,0xc2,0x59,0xb3,0x16,0x11,0x12,0x0c,0x0a,0x2a,0x0d,0x9a,0x2c,0x14,0x98,0x0d,0x3f,0x9a,0x37,0xa5,0x95,0x32,0x2f,0x29 +,0x1b,0x1e,0xac,0xcf,0x36,0xf9,0x1f,0x13,0x1c,0x18,0x18,0x72,0x1c,0x94,0x1d,0x20,0x92,0x13,0x99,0x8c,0xd5,0x9a,0x9f,0x23,0x4d,0xbf,0x67,0xa1,0x8e,0xa3,0xa1,0xa5 +,0x28,0x22,0xad,0x30,0x40,0xaa,0x1a,0xa1,0x12,0x34,0x98,0x1d,0x8c,0x90,0x43,0x91,0xbb,0x2d,0xac,0xa0,0x9e,0x9b,0x8b,0xbe,0x9d,0x9e,0x3b,0xbd,0x9e,0x2a,0x2c,0x1c +,0x0d,0x30,0x04,0x5a,0xb5,0x0e,0x93,0xfd,0x10,0xaa,0x19,0x1d,0xb6,0xaa,0xaa,0xab,0xab,0x19,0x1f,0x27,0x10,0x29,0xd5,0x0e,0x1e,0x07,0x14,0x0b,0x0b,0x96,0x12,0xab +,0x89,0x29,0xa9,0x91,0xc8,0x95,0x8a,0x89,0x8a,0x84,0x8f,0x9f,0x98,0xa9,0x30,0x99,0xae,0x29,0x28,0x10,0xc3,0x08,0x5e,0x9a,0x1b,0x89,0x98,0x1e,0x8b,0x99,0xbb,0x91 +,0x8a,0x91,0x91,0x8e,0x1f,0xd8,0x66,0x13,0x1e,0x2e,0x15,0x15,0x04,0x16,0x10,0x06,0xa4,0x17,0x25,0x87,0x27,0x31,0x8e,0x18,0x20,0xb7,0xae,0x5a,0x9c,0x2f,0x0f,0x16 +,0x0b,0x07,0x16,0x17,0x0d,0x10,0x08,0x30,0x06,0x24,0x9d,0x16,0x8e,0x89,0x4c,0x8b,0x92,0x3e,0x8f,0x8d,0x96,0x8f,0x88,0xa0,0x9c,0xa0,0x5d,0xa4,0x8d,0x9d,0x92,0xa4 +,0x8c,0x8a,0x48,0x86,0x91,0x91,0x80,0x74,0x1c,0x9d,0x1f,0x0d,0x05,0x03,0x0a,0x19,0x09,0x00,0x01,0x04,0x02,0x02,0x04,0x07,0x11,0x03,0x29,0x0c,0x13,0x9c,0x13,0x9a +,0x88,0x1f,0x96,0x8f,0x1a,0xb7,0x92,0xa1,0x8f,0x85,0x8e,0x93,0x8f,0x9b,0xa7,0x89,0x94,0x8c,0x95,0x8c,0x8b,0x28,0x87,0x94,0xba,0x83,0xb0,0x48,0x86,0x27,0x0d,0xa6 +,0x93,0xbe,0x98,0x8b,0x8a,0x8b,0x99,0xa1,0x88,0x8d,0x14,0xa8,0xae,0xbc,0x0a,0x09,0xaf,0x06,0x08,0x47,0x0a,0x0f,0x11,0x00,0x0d,0x12,0x0a,0x14,0xcd,0x16,0x15,0x1a +,0x12,0x09,0x1c,0x0f,0x0f,0x24,0x0a,0x31,0x06,0x1b,0xbf,0x0a,0x9e,0x8c,0x2f,0x8f,0x93,0x5d,0x95,0x98,0x9e,0x8e,0x87,0x95,0x9f,0xa3,0xbc,0x25,0xba,0x12,0xed,0xc8 +,0x1b,0x23,0x08,0x89,0x9a,0x22,0x87,0x83,0x84,0x82,0x87,0x83,0x80,0x86,0x87,0x82,0x80,0x8e,0x2a,0xdb,0x2d,0x12,0x0c,0x00,0x0a,0x04,0x04,0x06,0x01,0x17,0x05,0x00 +,0xa4,0x13,0x0e,0xa5,0x0c,0x13,0x33,0x18,0x30,0xa6,0x4b,0x1d,0x1a,0x12,0x08,0x0a,0x13,0x0b,0x1f,0x08,0x25,0x1f,0x06,0x98,0x15,0x37,0x83,0xd2,0x9d,0x8c,0x51,0xa1 +,0x9f,0xbd,0xaa,0x89,0x97,0x1d,0xb8,0xa4,0xa8,0xa1,0xaa,0x94,0x80,0x8e,0x87,0x89,0x8d,0x80,0x9b,0x8b,0x80,0x8e,0x8c,0x92,0xf4,0xaf,0x4a,0x10,0x0f,0xad,0x18,0x03 +,0x12,0x08,0x05,0x0d,0x0b,0x0b,0x16,0x04,0x1d,0x0e,0x05,0xa8,0x06,0x17,0x93,0x0f,0x1e,0xcc,0x09,0x0e,0x2b,0x1f,0x27,0xa0,0x52,0x1e,0xbd,0x29,0x23,0xb0,0x9c,0x56 +,0x9a,0x1f,0xc9,0xac,0x0b,0x94,0x22,0x28,0x84,0x2d,0x11,0x99,0xad,0xa2,0x99,0x8e,0x85,0x80,0x85,0x90,0x80,0x81,0x89,0x8a,0x80,0x86,0x85,0x2d,0xf1,0xaf,0x07,0xff +,0x08,0x0b,0xab,0x0b,0x05,0x1c,0x05,0x07,0x19,0x15,0x20,0x55,0x25,0x15,0x1b,0x11,0x12,0x1c,0x47,0x17,0x19,0x0d,0x0e,0x16,0x03,0xb3,0x33,0x0f,0x8e,0x29,0x15,0x9b +,0x1a,0x25,0x9d,0xa7,0x99,0x97,0xab,0x51,0xad,0x56,0x1b,0x21,0x99,0x2d,0x15,0x0b,0x17,0x99,0x0e,0xa5,0x86,0x89,0x80,0x8e,0x97,0x80,0x83,0x8e,0x85,0x80,0x81,0x87 +,0x9a,0xa6,0xa4,0x38,0x0c,0x12,0x4f,0x09,0x04,0x07,0x00,0x0e,0x05,0x12,0x9d,0x0e,0xaf,0x9d,0x0c,0xd4,0x25,0x17,0xaf,0xb1,0xae,0x6d,0x4a,0x26,0x0d,0x21,0x1f,0x15 +,0xa9,0x1b,0x11,0x18,0x09,0x2e,0x0b,0x42,0x89,0x2a,0x95,0x95,0x27,0x98,0xc3,0x1c,0x97,0x8e,0xaf,0x1c,0x42,0x9f,0xb4,0x32,0xae,0x8c,0x80,0x91,0xa5,0x87,0x8b,0x85 +,0x9b,0x98,0x80,0x8f,0x9b,0x87,0x37,0xe3,0xc7,0x0c,0x2c,0x5f,0x19,0x0a,0x0e,0x0c,0x04,0x0b,0x1e,0x0e,0x23,0x1f,0x07,0x0a,0x03,0x14,0x0a,0x15,0x8e,0x10,0x2d,0x9f +,0x09,0x1e,0xc5,0x19,0xa3,0x92,0xb2,0xbf,0x9f,0xc7,0x27,0xad,0x9e,0xa9,0x96,0x9e,0x22,0xba,0x0d,0x25,0x31,0x26,0x85,0x16,0x10,0x8b,0x29,0x2e,0x9c,0xa5,0x81,0x85 +,0x8e,0x86,0x80,0x83,0x8c,0x88,0x80,0x83,0x88,0xa5,0x32,0x35,0x07,0x16,0x08,0x0e,0xaa,0x00,0x08,0x21,0x03,0x0b,0x1f,0x08,0x2d,0xbf,0x18,0x1d,0x28,0x1d,0x14,0x4a +,0xd7,0x2a,0xbc,0x1f,0x07,0x0f,0x02,0x21,0x11,0x11,0x8c,0x12,0x24,0x95,0x0e,0x43,0x97,0xd7,0x8e,0x91,0x97,0xa0,0x99,0x47,0x1f,0x9e,0x98,0x3d,0x25,0x1f,0x28,0x24 +,0x06,0xa0,0xa4,0x8b,0x83,0xb4,0x85,0x80,0x97,0x8a,0x80,0x84,0x80,0x88,0x93,0x90,0x8f,0x19,0x10,0x42,0x17,0x0c,0x0f,0x04,0x03,0x04,0x00,0x20,0x05,0x1b,0x99,0x03 +,0x25,0xbb,0x05,0x6b,0xb3,0x18,0xa1,0xa3,0x1f,0x1c,0x40,0x13,0x19,0x5b,0x37,0x24,0xd7,0x0d,0x0e,0x0f,0x0e,0x9e,0x13,0x8f,0x90,0x17,0x89,0xaa,0x0a,0x90,0x8f,0xbd +,0xa7,0xbd,0xb9,0x9c,0xa0,0x13,0x9a,0x80,0x91,0x98,0x82,0x8a,0x89,0xa0,0x96,0x82,0x91,0x81,0x92,0xcb,0x82,0x3f,0x0a,0x9d,0x1f,0x15,0x32,0x17,0x05,0x0d,0x11,0x05 +,0x12,0x36,0x0f,0x1a,0x1a,0x02,0x0c,0x04,0x1d,0x12,0x13,0x8f,0x0f,0x1d,0x95,0x0c,0x1c,0x95,0x30,0xb6,0x95,0xb5,0x34,0xa7,0x2f,0x1d,0x95,0x95,0x3a,0x9e,0xa7,0x16 +,0x10,0x08,0xa3,0x36,0x4a,0xa0,0x0c,0x95,0x96,0x07,0xa2,0x82,0x8b,0x8a,0x86,0x82,0x82,0x82,0x8c,0x87,0x80,0x84,0x99,0x8d,0xa5,0x1d,0x0b,0x0f,0x17,0x06,0xbb,0x0b +,0x01,0x29,0x0b,0x04,0x2d,0x12,0x17,0xb7,0x3e,0x1a,0x19,0x40,0x1a,0x25,0xa6,0x2a,0x1f,0x4f,0x09,0x0b,0x06,0x1a,0x15,0x0f,0x8e,0x12,0x14,0x94,0x0f,0x16,0x90,0xb6 +,0xa4,0x93,0x9f,0xa0,0x9c,0x36,0x30,0x9a,0x90,0x1d,0x16,0xe4,0x20,0x08,0x0a,0x92,0xb6,0x8b,0x86,0xa5,0x80,0x85,0xb2,0x87,0x80,0x84,0x80,0x88,0x8a,0x8e,0x95,0x38 +,0x1f,0xd3,0x49,0x0a,0x0c,0x05,0x02,0x00,0x05,0x1a,0x01,0xca,0x3d,0x00,0xbb,0x2f,0x03,0xaa,0xbc,0x1a,0xa2,0xbb,0x1b,0x2f,0x34,0x15,0x24,0xb1,0x64,0x25,0x53,0x14 +,0x13,0x0a,0x4e,0xf3,0x1f,0x87,0x3f,0x25,0x89,0x1a,0x0c,0x8d,0x9d,0x57,0xd7,0xef,0x4e,0xbc,0x24,0x21,0x8e,0x83,0x98,0x94,0x84,0x8a,0x8e,0x9a,0x84,0x83,0x88,0x80 +,0x92,0x9d,0x83,0x1c,0x19,0x93,0x1a,0x19,0x32,0x0b,0x04,0x0c,0x08,0x09,0x14,0x21,0x0c,0x16,0x0b,0x04,0x07,0x0c,0xcd,0x0c,0xcf,0x9c,0x05,0x50,0xad,0x09,0xb9,0x9a +,0x32,0xcb,0xbb,0x27,0x2c,0xbf,0x4d,0xa7,0x96,0xaa,0x1a,0x3e,0x2a,0x1d,0x10,0x1f,0x8a,0x19,0x37,0xaf,0x0c,0x97,0x9f,0x0f,0x8a,0x81,0x9b,0x92,0x8c,0x87,0x83,0x84 +,0x84,0x80,0x81,0x84,0x9f,0x98,0xa5,0xe6,0x1f,0xfb,0xce,0x04,0x2b,0x0c,0x00,0x1f,0x12,0x0a,0x5c,0x16,0x0e,0x17,0x14,0x1c,0x11,0x2c,0xce,0x1d,0x31,0x1e,0x0c,0x1a +,0x0c,0x0d,0x0c,0xbc,0xc0,0x06,0x9b,0x3c,0x0a,0x99,0xb0,0x2a,0x90,0x98,0x4b,0x3d,0x9d,0x9b,0x38,0xa7,0x91,0x9f,0x3f,0x20,0x08,0x2b,0x33,0x0c,0x12,0x8f,0x8d,0x1e +,0x8b,0x87,0x8c,0x83,0x84,0x89,0x80,0x81,0x8a,0x89,0x8b,0x90,0x93,0x9a,0x9d,0x2a,0x19,0x1c,0x01,0x05,0x07,0x04,0x01,0x23,0x12,0x02,0xca,0x0f,0x05,0x94,0xc8,0x17 +,0x97,0x6c,0x28,0x1c,0x1f,0xa7,0x27,0x3e,0xaa,0x18,0x20,0x1f,0x08,0x23,0x1e,0x0e,0x17,0xba,0xda,0x07,0x8f,0x88,0x16,0x93,0x9c,0xfb,0x85,0xa4,0x39,0x9a,0x93,0x06 +,0x0a,0x80,0xaf,0x00,0x3d,0x89,0x85,0x82,0x92,0x92,0x8e,0x0b,0x10,0x0f,0x1a,0x1b,0x00,0x1a,0x2f,0x00,0x00,0x03,0x02,0x1f,0x0f,0x0c,0x04,0x00,0xec,0xcb,0x9b,0x89 +,0x11,0x38,0xcf,0x97,0x86,0x18,0x8f,0x82,0x82,0x80,0x82,0x80,0x84,0x87,0x84,0x80,0x81,0x83,0x8b,0x81,0x81,0x80,0x8e,0x23,0x9a,0x80,0x88,0xac,0xbf,0x13,0x0e,0x16 +,0x8a,0xaa,0x1c,0xb7,0x04,0x06,0x0c,0x07,0x00,0x08,0x49,0x0b,0x01,0x12,0x0d,0x00,0x01,0x07,0x05,0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00,0x15,0x07,0x07,0x20,0x02 +,0x0a,0xdf,0x17,0x15,0x8e,0x95,0x2b,0xf4,0x91,0xa3,0x13,0x98,0x82,0x81,0x80,0x81,0x81,0x98,0xa3,0x80,0x84,0x82,0x80,0xa4,0x86,0x80,0x86,0x84,0x80,0x80,0x80,0x81 +,0x83,0x81,0x80,0x80,0x81,0x80,0x80,0x80,0x89,0x93,0x85,0x82,0xad,0x20,0x3c,0x8d,0x82,0x80,0x8e,0x98,0x81,0x97,0x8f,0x88,0x2d,0x26,0x2d,0x1c,0x0f,0x03,0x04,0x07 +,0x0b,0x0b,0x02,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x01,0x00,0x02,0x09,0x00,0x00,0x03,0x01,0x17,0x0e,0x02,0x05,0x02,0x04,0x01,0x03,0x01,0x02,0x02,0x07,0x0e,0x04 +,0x03,0x02,0x11,0x1d,0x0c,0x06,0x05,0x00,0x04,0xb8,0x58,0x9c,0x8c,0x21,0x26,0x9c,0x9d,0xa9,0x3f,0x8c,0x80,0x82,0x86,0x96,0x87,0x84,0x85,0x8e,0x91,0xa8,0xb3,0x9f +,0x95,0x8a,0x8f,0xc1,0xa9,0x82,0x82,0x83,0x80,0x82,0x85,0x84,0x82,0x81,0x80,0x87,0x86,0x80,0x85,0x97,0x9b,0x86,0x80,0x80,0x80,0x85,0x8c,0x8a,0x99,0x92,0x88,0x8d +,0xae,0xb1,0x8c,0x94,0x87,0x83,0x8f,0x8f,0x98,0xa6,0xbe,0x1a,0x12,0x27,0x36,0x2f,0x10,0x09,0x09,0x07,0x0c,0x13,0x09,0x03,0x20,0xb3,0x9f,0x97,0x9d,0x76,0x97,0x99 +,0xb4,0x89,0x85,0x98,0x27,0x41,0x9b,0x9f,0x19,0x1c,0xb2,0xab,0x16,0x01,0x02,0x06,0x06,0x05,0x09,0x03,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x17,0x0e,0x01,0x10,0x0f +,0x03,0x00,0x00,0x03,0x04,0x00,0x00,0x02,0x0a,0x04,0x00,0x01,0x05,0x06,0x04,0x02,0x00,0x00,0x00,0x01,0x04,0x08,0x01,0x01,0x0c,0x06,0x05,0x1b,0x1d,0x23,0x23,0x31 +,0xa3,0xab,0x5a,0x2f,0xa6,0x8a,0x97,0x55,0x9a,0x8b,0x85,0x81,0x84,0x8a,0x86,0x81,0x80,0x80,0x80,0x83,0x85,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x84,0x84,0x83,0x83,0x84,0x9c,0x96,0x82,0xa2,0x23,0x34,0x35,0x0e,0x06,0x07,0x0c,0x07,0x02,0x01,0x04,0x0a +,0x02,0x00,0x02,0x09,0x0f,0x0d,0x07,0x04,0x00,0x00,0x01,0x03,0x05,0x00,0x03,0x11,0x0d,0x00,0x09,0x19,0x0f,0x08,0x03,0x06,0x0e,0x06,0x05,0x1f,0xb0,0x21,0x03,0x05 +,0x0d,0x0f,0x0b,0x07,0x0c,0x19,0x24,0x21,0x2d,0x52,0x0b,0x0c,0x9d,0xc5,0x49,0xad,0xa6,0x99,0xa4,0xbd,0x9d,0x8c,0x89,0x87,0x86,0x85,0x9e,0x1e,0x2b,0xad,0x96,0x94 +,0xaa,0x36,0x1e,0x29,0x27,0x2f,0xb0,0x32,0x91,0x83,0x92,0x9e,0x9d,0xa1,0xa6,0x2b,0x2b,0xc4,0x5c,0x46,0xad,0x8b,0x8c,0xc6,0x25,0xaf,0x9f,0xba,0x2f,0x23,0x18,0x1b +,0x24,0x39,0x9a,0xa2,0x1e,0x93,0x85,0x8e,0x8c,0x86,0x80,0x81,0x80,0x81,0x81,0x82,0x84,0x83,0x81,0x81,0x90,0x3e,0x4d,0xf7,0x30,0x1c,0x16,0x11,0x0b,0x06,0x02,0x02 +,0x00,0x00,0x10,0x0e,0x04,0x09,0x09,0x0b,0x0b,0x04,0x09,0x10,0x20,0xb4,0x96,0x8a,0x96,0x2c,0x2b,0x3c,0xbf,0x9c,0x9c,0x9c,0xaf,0xa8,0x9e,0x99,0x98,0x9b,0x86,0x81 +,0x86,0x8d,0x95,0x8c,0x88,0x8f,0x8c,0x86,0x8b,0x90,0x95,0x8f,0x8e,0x9b,0xa7,0x99,0x94,0x92,0x99,0xa9,0x30,0x1c,0x1e,0x1c,0x1f,0x12,0x1f,0x96,0x9c,0xb0,0xb3,0xa2 +,0x8e,0x99,0xbb,0xac,0x47,0x1b,0x22,0xed,0xa1,0x9c,0xb6,0x24,0x19,0x1b,0x1a,0x11,0x14,0x1d,0x1f,0x1a,0x1c,0x0f,0x0a,0x2c,0x32,0x1d,0x19,0x0c,0x0d,0x0e,0x0f,0x17 +,0x1a,0x21,0x19,0x27,0xba,0xd9,0x3d,0x13,0x0d,0x11,0x12,0x1b,0x35,0xc3,0xc7,0xad,0xa1,0xba,0xb6,0x87,0x80,0x81,0x80,0x81,0x80,0x87,0x89,0x84,0x85,0x88,0x8d,0x98 +,0x94,0x8f,0xaf,0x3d,0x35,0x1c,0x14,0x0b,0x05,0x02,0x00,0x01,0x02,0x02,0x00,0x0a,0x0a,0x0d,0x12,0x06,0x0e,0x0b,0x09,0x35,0x9f,0x99,0xa3,0x7d,0xa5,0x9a,0x9f,0xa9 +,0xa4,0xa9,0xb1,0xed,0x33,0x67,0x50,0x42,0xae,0x9f,0x31,0xae,0xac,0x53,0x9b,0x99,0x91,0x99,0xcf,0xb3,0x98,0x9a,0xa9,0xc2,0xa0,0x8e,0x8d,0x90,0x91,0x9c,0xb0,0x2f +,0x24,0x26,0x1d,0x13,0x15,0x2f,0x1b,0xfd,0xab,0xa2,0x90,0x95,0x8e,0x9d,0x19,0x14,0x24,0xd1,0xa2,0xbf,0xb8,0xbc,0xae,0x45,0x1f,0x25,0x2f,0x1d,0x19,0x1d,0x17,0x0d +,0x09,0x0d,0x07,0x15,0x18,0x0e,0x14,0x1b,0x39,0x22,0x0d,0x0e,0x1b,0x69,0xb7,0x3d,0xd3,0x2a,0x28,0x36,0xbf,0xa0,0x99,0x96,0x9c,0x95,0x97,0xac,0x9c,0x89,0x85,0x81 +,0x80,0x80,0x82,0x83,0x81,0x81,0x87,0x8b,0x91,0x9c,0x9c,0xcd,0x47,0x49,0x2e,0x1d,0x16,0x15,0x0b,0x03,0x02,0x03,0x02,0x02,0x00,0x02,0x00,0x08,0x10,0x0a,0x0f,0x0e +,0x1f,0xae,0x5a,0xb6,0xc6,0x63,0xa1,0xbb,0xa2,0x9c,0xa1,0x9f,0xa8,0x9e,0x9e,0xb2,0xad,0xa7,0xa7,0xad,0x2d,0x27,0x14,0x2c,0x9b,0x9c,0x97,0xa2,0x9b,0x8d,0x97,0xa2 +,0x9e,0x99,0x91,0x9e,0x98,0x8a,0x8e,0x9d,0xa6,0x9a,0x98,0xac,0x2e,0x2b,0x2e,0x20,0x15,0x1c,0x1b,0x2d,0x9c,0x9c,0x95,0xa5,0x50,0xc2,0x36,0xcf,0xb7,0xca,0xae,0x4e +,0x3b,0x37,0x2f,0x23,0x1b,0x29,0x34,0x3e,0x25,0x0e,0x0b,0x0c,0x0a,0x08,0x04,0x06,0x0a,0x0c,0x11,0x0d,0x13,0x23,0x1e,0x26,0x3c,0x3f,0x2c,0x13,0x17,0x3b,0xc6,0xaf +,0xab,0x96,0x8a,0x88,0x89,0x89,0x88,0x85,0x84,0x82,0x82,0x86,0x83,0x83,0x83,0x83,0x87,0x88,0x90,0xa1,0x98,0xbe,0xd9,0x2a,0x14,0x1d,0x14,0x0e,0x08,0x03,0x07,0x08 +,0x06,0x06,0x04,0x04,0x03,0x05,0x07,0x03,0x06,0x0e,0x14,0x20,0x2a,0x3b,0x74,0x3c,0xa4,0x9c,0xa0,0x98,0xac,0xaa,0x9d,0xa4,0x9f,0xad,0xa1,0x99,0x9a,0x95,0xa9,0x36 +,0x2b,0x30,0x67,0x4e,0x31,0xbe,0xb1,0xa2,0x9d,0xaa,0x9d,0x9d,0x9a,0x93,0x92,0x8f,0x91,0x9d,0x99,0x9b,0x9d,0x9b,0xaf,0xb9,0xb0,0xaa,0xba,0x2d,0x2e,0x2b,0x48,0xb3 +,0x39,0x18,0x14,0x21,0x2b,0x2a,0x24,0x33,0x41,0x46,0x41,0x2c,0x2e,0x4a,0x54,0x3b,0xe5,0x45,0x2a,0x1a,0x15,0x1d,0x1f,0x19,0x0f,0x0b,0x0c,0x0f,0x11,0x0d,0x0c,0x0c +,0x0f,0x19,0x16,0x14,0x12,0x16,0x2a,0xd5,0xb0,0x9f,0x95,0x8b,0x86,0x86,0x85,0x84,0x82,0x82,0x81,0x81,0x81,0x82,0x83,0x83,0x82,0x87,0x91,0x9c,0xb3,0xba,0x24,0x0f +,0x13,0x0f,0x0c,0x0d,0x0c,0x0c,0x09,0x05,0x07,0x0a,0x0a,0x0a,0x09,0x0a,0x0e,0x12,0x0e,0x0e,0x0f,0x10,0x17,0x22,0x28,0x1f,0x1d,0x26,0x3f,0x40,0xd3,0xb1,0xbe,0xb8 +,0x9d,0xa1,0xa6,0x9e,0xa0,0x96,0x96,0x9d,0x9e,0x9f,0xa0,0xa4,0xa5,0x9b,0x9d,0xa2,0x9e,0x99,0x9a,0xa8,0xa6,0xac,0xab,0xa2,0xa0,0xa4,0xad,0xb9,0xab,0xa1,0xa8,0xb8 +,0xcd,0xb2,0xc9,0x6f,0x45,0xeb,0xce,0xb5,0xa3,0xaa,0xc1,0x41,0x62,0xed,0xb1,0xa9,0xb8,0x57,0x37,0x34,0x4a,0x3c,0x2c,0x24,0x2a,0x29,0x1e,0x1f,0x16,0x17,0x19,0x17 +,0x14,0x10,0x10,0x0f,0x0f,0x15,0x13,0x0f,0x11,0x15,0x16,0x19,0x23,0x1c,0x12,0x16,0x20,0x36,0xaf,0xa7,0x99,0x8c,0x88,0x88,0x87,0x86,0x83,0x82,0x82,0x82,0x84,0x84 +,0x84,0x84,0x88,0x89,0x8e,0x96,0x97,0xa5,0xc4,0x37,0x19,0x0f,0x0f,0x10,0x0d,0x09,0x08,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0d,0x0f,0x0f,0x0d,0x0f,0x1a,0x1a,0x21 +,0x3a,0x31,0x3f,0x4d,0xaf,0xa8,0xa3,0xb2,0xfa,0xb8,0xb8,0xb2,0xae,0x9f,0x9b,0x9c,0x9f,0x9b,0x9c,0x9d,0x9e,0xa0,0x9d,0x9c,0xa5,0xa5,0xa7,0xae,0xac,0x9f,0x9f,0xad +,0xa0,0xae,0x9f,0xab,0xa0,0x98,0xa2,0x9f,0xad,0xa3,0xa7,0xaf,0x4d,0x41,0x25,0x1d,0x19,0x1a,0x19,0x18,0x23,0x1b,0x2e,0x20,0x25,0x2c,0x43,0xc0,0xc8,0xc6,0x3c,0x3e +,0x2f,0xeb,0x4f,0xc9,0xb7,0xba,0xec,0x32,0x32,0x2f,0xbf,0x5c,0x35,0x40,0x4f,0x3e,0x32,0x42,0xb9,0xa0,0xae,0xc0,0xbe,0xc3,0x5f,0x42,0x3a,0x36,0x2f,0x1f,0x1d,0x1d +,0x1c,0x25,0x31,0x29,0x27,0x32,0x4b,0xee,0xcb,0xba,0xa5,0xb1,0xb2,0xbf,0xeb,0xc5,0xbf,0xcd,0xd5,0xc2,0x3d,0x2d,0x33,0x6e,0xc4,0xb4,0xbd,0xb9,0xab,0xa3,0xa5,0x99 +,0x96,0x9f,0xaa,0xc1,0x69,0x26,0x37,0xdb,0x49,0xbb,0xc4,0xea,0xac,0x9e,0x9b,0x9a,0x9a,0x99,0x97,0x93,0x99,0x99,0x93,0x9c,0xa7,0xbe,0x5c,0x3b,0x25,0x1c,0x14,0x0e +,0x0a,0x0b,0x0c,0x0c,0x10,0x0d,0x0d,0x12,0x12,0x1a,0x23,0x2d,0x4f,0x41,0x3e,0x38,0x43,0xcd,0xd9,0xcd,0xcd,0x4f,0x2c,0x7e,0xc5,0xbe,0xa4,0xa9,0xab,0xa2,0x9a,0x97 +,0x8f,0x8b,0x8f,0x94,0x8e,0x97,0x95,0x91,0x99,0x9b,0xa2,0xbc,0x4a,0xb8,0xb6,0xaf,0xad,0xa2,0xaf,0xc8,0xb0,0xb2,0xac,0xac,0xea,0x3b,0x4e,0x39,0x34,0x2e,0x2c,0x25 +,0x1f,0x2d,0x23,0x1b,0x24,0x1f,0x1c,0x18,0x18,0x14,0x14,0x15,0x19,0x1e,0x1c,0x16,0x0f,0x18,0x18,0x18,0x18,0x1a,0x1b,0x1c,0x1d,0x17,0x24,0x40,0xdb,0xcd,0xac,0x9d +,0x9d,0x96,0x91,0x8d,0x8b,0x8e,0x91,0x8e,0x8d,0x8b,0x8a,0x8e,0x96,0x9a,0x96,0x99,0xaa,0xac,0xa0,0x9b,0x9d,0xad,0xdf,0xd4,0xd9,0x3a,0x2e,0x23,0x19,0x0f,0x0e,0x0c +,0x0a,0x0a,0x07,0x06,0x07,0x06,0x03,0x06,0x07,0x09,0x0b,0x0e,0x0e,0x0d,0x13,0x16,0x1f,0x40,0xd9,0xd3,0xb4,0xa6,0x9f,0x9d,0x99,0x97,0x9a,0x99,0x9e,0xc0,0xb2,0xa8 +,0x9a,0x95,0x8f,0x8d,0x8e,0x8b,0x8b,0x87,0x85,0x89,0x8a,0x87,0x8b,0x8b,0x8b,0x8d,0x8f,0x99,0xa3,0xba,0x3a,0x3b,0x3d,0x37,0x4f,0x42,0x34,0x36,0x38,0x37,0x56,0xc5 +,0x3e,0x28,0x24,0x1a,0x1b,0x1b,0x19,0x19,0x13,0x0f,0x0e,0x0b,0x0e,0x12,0x14,0x1a,0x19,0x18,0x1e,0x1f,0x1a,0x31,0xc9,0x5e,0x40,0x36,0x2b,0x2c,0x36,0x34,0x36,0x2a +,0x21,0x1a,0x19,0x25,0x23,0x28,0x49,0x7a,0xc4,0xb3,0xb1,0xa2,0x92,0x94,0x9b,0x99,0x95,0x96,0x93,0x9c,0x9e,0x9a,0xa5,0xae,0xae,0x9e,0x9a,0x95,0x96,0x97,0x95,0xa8 +,0xaf,0xa8,0xa7,0xa3,0x59,0x26,0x25,0x1e,0x1a,0x19,0x0f,0x10,0x14,0x0f,0x10,0x13,0x15,0x19,0x2b,0x3a,0x39,0x3e,0x62,0xa5,0x96,0x91,0x8b,0x89,0x8a,0x8a,0x89,0x8b +,0x8e,0x8d,0x8c,0x8a,0x8d,0x8f,0x97,0xad,0xaa,0xad,0xcb,0x43,0x2d,0x23,0x1a,0x19,0x15,0x17,0x13,0x0d,0x0d,0x0d,0x0e,0x0c,0x09,0x08,0x08,0x05,0x03,0x03,0x03,0x08 +,0x0b,0x0e,0x13,0x0f,0x10,0x1b,0x22,0x58,0xab,0xac,0xaa,0xb2,0xa1,0x9f,0x9f,0x9c,0x9c,0x99,0xa1,0xaa,0xbb,0xb5,0xa3,0x9e,0x9a,0x97,0x95,0x93,0x8f,0x8e,0x89,0x85 +,0x87,0x87,0x88,0x87,0x87,0x8a,0x8a,0x8a,0x96,0x97,0x9b,0xd0,0xbd,0xcb,0x6b,0xd0,0x57,0x38,0x3e,0x3f,0x31,0x39,0xec,0x3a,0x29,0x27,0x25,0x24,0x1f,0x1e,0x1b,0x17 +,0x17,0x15,0x0d,0x11,0x1e,0x1b,0x1e,0x1e,0x1f,0x24,0x25,0x24,0x44,0xee,0x3c,0x2e,0x26,0x21,0x19,0x16,0x18,0x1e,0x1a,0x18,0x18,0x0f,0x18,0x1f,0x1a,0x2d,0x3e,0x2a +,0x3b,0xbd,0xba,0xa2,0x9e,0xa7,0xaa,0xa4,0xa4,0xae,0xaf,0xb9,0xae,0xc5,0xde,0x5e,0x36,0xbf,0xa6,0xa9,0xa4,0xa5,0xaa,0xa0,0xa7,0xaa,0x9b,0xa0,0xd3,0x36,0x31,0x2a +,0x22,0x1f,0x23,0x27,0x1e,0x1d,0x18,0x19,0x21,0x37,0xd2,0xa9,0x9b,0x9a,0x8f,0x8b,0x8a,0x87,0x86,0x85,0x85,0x86,0x87,0x84,0x87,0x87,0x87,0x8c,0x8e,0x96,0xa3,0xa6 +,0xa4,0xb0,0x32,0x26,0x1e,0x15,0x11,0x0f,0x0f,0x0d,0x0a,0x08,0x07,0x07,0x05,0x05,0x05,0x06,0x05,0x03,0x02,0x05,0x07,0x08,0x0c,0x0c,0x0f,0x11,0x18,0x20,0x2e,0xca +,0xc8,0xbf,0xc7,0xbd,0xa8,0xa7,0xaa,0xa1,0x9f,0x9e,0xa5,0xb1,0xab,0xa3,0x98,0x96,0x96,0x91,0x8e,0x8d,0x8b,0x87,0x86,0x87,0x89,0x8a,0x8b,0x8b,0x8b,0x8d,0x90,0x95 +,0x9b,0x9e,0xaf,0xbf,0xb7,0xab,0xb3,0xda,0x48,0x3d,0x6b,0x57,0xcd,0xc6,0x7a,0x41,0x23,0x29,0x2f,0x1f,0x1e,0x1c,0x16,0x14,0x0f,0x0d,0x0f,0x13,0x16,0x17,0x1a,0x15 +,0x18,0x1b,0x1e,0x33,0x2d,0x22,0x1f,0x1f,0x1e,0x1d,0x1c,0x23,0x26,0x1b,0x1d,0x1b,0x17,0x1e,0x28,0x25,0x3c,0xfa,0x3e,0xbf,0xad,0xa6,0x9a,0x9e,0xa6,0xac,0xa5,0xa0 +,0xa2,0x9f,0xa5,0xaa,0xaf,0xb8,0xb1,0xa5,0x9f,0x99,0x9a,0x98,0x96,0x9c,0x9b,0x99,0x9b,0x9e,0xb6,0x5f,0x3e,0x2b,0x2a,0x20,0x1d,0x13,0x0e,0x0e,0x0f,0x14,0x17,0x1a +,0x29,0x3d,0xc6,0xa8,0x9d,0x8e,0x8d,0x8e,0x8b,0x8a,0x89,0x87,0x88,0x89,0x86,0x8a,0x8d,0x8d,0x8d,0x8f,0x8f,0x93,0x9c,0x9f,0xab,0xbd,0xb8,0xc2,0x2f,0x1c,0x13,0x0f +,0x0c,0x0a,0x09,0x07,0x07,0x06,0x03,0x03,0x03,0x04,0x06,0x07,0x07,0x08,0x0a,0x0c,0x10,0x1a,0x1b,0x17,0x1b,0x22,0x29,0x3a,0x44,0x49,0xd5,0xbf,0x6c,0x44,0xb0,0x9e +,0x9d,0x9a,0x97,0x99,0x98,0x94,0x91,0x8d,0x8c,0x8e,0x90,0x8f,0x8e,0x91,0x90,0x8e,0x8f,0x8f,0x91,0x99,0x9b,0x97,0x95,0x92,0x92,0x95,0x99,0x98,0x97,0x98,0x92,0x99 +,0xa6,0xb1,0xca,0x3e,0x39,0x2d,0x23,0x1e,0x19,0x16,0x0f,0x0e,0x14,0x17,0x15,0x1a,0x1a,0x17,0x1d,0x1f,0x2b,0x49,0x27,0x1e,0x1d,0x16,0x16,0x18,0x18,0x17,0x13,0x12 +,0x0e,0x0b,0x0e,0x12,0x15,0x16,0x19,0x1b,0x20,0x2a,0x31,0xc4,0xb3,0xc1,0x62,0xe1,0xd7,0xbf,0xbc,0xb9,0xb5,0xb5,0xb4,0x48,0x4a,0xb4,0xa8,0xa9,0xa4,0x9e,0x9b,0x98 +,0x92,0x8f,0x8c,0x8c,0x93,0x99,0x99,0x9f,0x9f,0xa2,0xaf,0xc4,0x2c,0x24,0x19,0x14,0x19,0x1a,0x1c,0x21,0x20,0x22,0x2f,0x5a,0xc2,0xa9,0x9e,0x9b,0x99,0x95,0x93,0x90 +,0x8d,0x8d,0x8c,0x8c,0x8c,0x8c,0x8f,0x8c,0x8d,0x8f,0x8d,0x91,0x96,0x97,0x99,0x9b,0x9b,0xab,0x4d,0x2f,0x1e,0x16,0x12,0x0e,0x0c,0x08,0x07,0x07,0x03,0x03,0x03,0x04 +,0x06,0x06,0x07,0x07,0x09,0x0c,0x0d,0x15,0x19,0x19,0x1b,0x1f,0x21,0x28,0x2c,0x2a,0x3a,0x47,0x3b,0x2f,0x39,0xbe,0xa3,0xa0,0x9c,0x98,0x97,0x98,0x93,0x8e,0x8b,0x8d +,0x8e,0x8e,0x8e,0x8e,0x8e,0x8d,0x8d,0x8d,0x8e,0x90,0x98,0x99,0x95,0x93,0x95,0x95,0x94,0x9b,0x97,0x9a,0x9c,0x94,0x9c,0xa3,0xaa,0xb7,0xcc,0xcc,0x47,0x3a,0x34,0x1e +,0x1c,0x13,0x13,0x1a,0x1a,0x18,0x1b,0x1d,0x1b,0x1e,0x21,0x24,0x32,0x30,0x23,0x1e,0x1c,0x1d,0x1d,0x1b,0x1d,0x19,0x12,0x0f,0x0d,0x0e,0x11,0x15,0x1a,0x1f,0x1e,0x1f +,0x27,0x28,0x38,0xaf,0xb2,0xca,0xde,0xc5,0xb8,0xbe,0xb3,0xbb,0xbd,0xde,0xb7,0xd0,0x68,0xa7,0x9f,0xa6,0x9d,0x98,0x9b,0x97,0x94,0x8f,0x8d,0x8d,0x96,0x97,0x94,0x9b +,0x9f,0xa7,0xb8,0x51,0x28,0x1c,0x13,0x12,0x18,0x18,0x19,0x1d,0x1f,0x1f,0x2b,0x38,0xbd,0xa1,0x9f,0x9d,0x98,0x90,0x8e,0x8d,0x8a,0x8b,0x8b,0x8b,0x8b,0x8e,0x8e,0x8c +,0x8b,0x8c,0x8e,0x8e,0x91,0x96,0x9e,0x9d,0x9b,0xa7,0x4d,0x25,0x18,0x11,0x0e,0x0b,0x09,0x08,0x06,0x04,0x03,0x02,0x03,0x04,0x07,0x06,0x05,0x09,0x0c,0x0a,0x0e,0x18 +,0x19,0x16,0x1a,0x1b,0x1f,0x2d,0x25,0x2c,0x2d,0x2d,0x29,0x28,0x42,0xb6,0xac,0xa2,0x9b,0x99,0x9a,0x99,0x92,0x8c,0x8c,0x8f,0x8e,0x8e,0x8e,0x92,0x8f,0x8e,0x8f,0x93 +,0x94,0x99,0x9b,0x98,0x97,0x8f,0x92,0x92,0x93,0x93,0x92,0x92,0x95,0x94,0x9a,0xa1,0xa6,0xac,0xba,0x58,0x3f,0x2c,0x2f,0x1e,0x19,0x0f,0x0d,0x4e,0x8d,0x1d,0x00,0x90 +,0x9a,0x1a,0xbd,0x12,0x25,0x0c,0x0d,0x0b,0x12,0x0c,0x00,0x0a,0x00,0x02,0x02,0x01,0x03,0x00,0x02,0x03,0x03,0x08,0x07,0x0a,0x0d,0x16,0x2e,0xad,0xa1,0x93,0x89,0x8c +,0x8d,0x8a,0x80,0x85,0x8a,0x84,0x81,0x80,0x82,0x82,0x81,0x82,0x81,0x82,0x80,0x82,0x82,0x80,0x84,0x83,0x89,0x88,0x89,0x8a,0x8d,0x96,0xa3,0xcd,0xb1,0x2b,0x1c,0x14 +,0x17,0x0f,0x0c,0x0a,0x04,0x08,0x05,0x04,0x04,0x05,0x03,0x02,0x02,0x01,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x04,0x03,0x07,0x05,0x0b,0x0d +,0x0e,0x1c,0x29,0x3c,0x3e,0xac,0x9d,0x95,0x8f,0x8f,0x8e,0x8a,0x85,0x86,0x85,0x84,0x82,0x82,0x82,0x81,0x81,0x81,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x81,0x81,0x80 +,0x81,0x81,0x82,0x82,0x83,0x83,0x84,0x87,0x86,0x87,0x88,0x8a,0x87,0x89,0x8e,0x8d,0x96,0x95,0x99,0x9e,0xad,0xd8,0x3c,0x27,0x13,0x0f,0x09,0x0a,0x0b,0x05,0x06,0x01 +,0x04,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x01,0x06,0x07,0x04,0x04,0x06,0x07,0x0b,0x0b,0x09,0x0a +,0x0e,0x14,0x10,0x18,0x13,0x16,0x2e,0x1e,0x1d,0x1f,0x1e,0xa7,0x94,0x93,0x96,0x96,0x8a,0x88,0x89,0x89,0x8a,0x86,0x84,0x87,0x86,0x89,0x87,0x84,0x88,0x87,0x8a,0x88 +,0x86,0x89,0x8a,0x87,0x8a,0x8a,0x8e,0x8f,0x92,0x9a,0x85,0x84,0x84,0x85,0x89,0x83,0x83,0x83,0x87,0x8f,0x8a,0x85,0x8b,0x8c,0x99,0x96,0x8c,0x8f,0x95,0x9e,0x9d,0x8f +,0x95,0x97,0xa8,0xaa,0x9d,0xcc,0x49,0x1b,0xa0,0x8b,0x8c,0x8b,0x98,0x8d,0x88,0x88,0x8b,0x9c,0x9d,0x8c,0x8e,0x8d,0x97,0x9d,0x90,0x95,0x96,0xa1,0xae,0x9a,0x9b,0xb6 +,0x2c,0x18,0x0e,0x0d,0x0a,0x01,0x12,0x1f,0x26,0x1b,0x08,0x0c,0x0e,0x0b,0x06,0x02,0x01,0x04,0x04,0x03,0x01,0x01,0x01,0x02,0x01,0x01,0x00,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x04,0x03,0x09,0x05,0x01,0x03,0x03,0x04,0x02,0x00,0x02,0x06,0x08,0x0c,0x05,0x07,0x0b,0x0c,0x0f,0x09,0x0b,0x12,0x11,0x1b,0x11,0x0e,0x15,0x1d +,0x18,0x9e,0x82,0x86,0x81,0x86,0x83,0x82,0x83,0x81,0x84,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x81,0x83,0x83,0x80 +,0x80,0x80,0x81,0x81,0x80,0x81,0x81,0x84,0x87,0x80,0x81,0x80,0x82,0x85,0x89,0x89,0x89,0x92,0x98,0x9d,0xa2,0xa6,0x55,0x26,0x12,0x0d,0x0a,0x04,0xec,0x7e,0x50,0x18 +,0x04,0x0b,0x05,0x07,0x04,0x01,0x08,0x0b,0x13,0x0c,0x03,0x03,0x01,0x03,0x02,0x01,0x02,0x01,0x02,0x01,0x00,0x00,0x00,0x01,0x00,0x11,0x17,0x16,0x0e,0x00,0x07,0x04 +,0x08,0x08,0x03,0x0f,0x24,0x4f,0xd8,0x11,0x13,0x19,0x1d,0x20,0x0f,0x1e,0x1a,0x31,0x36,0x21,0x1b,0x1b,0x16,0x17,0x8a,0x88,0x86,0x90,0xac,0x95,0x9c,0x90,0x92,0x9f +,0x89,0x84,0x84,0x81,0x8c,0x93,0x9b,0x96,0x8f,0x98,0x8f,0x98,0x8f,0x96,0x9f,0xd4,0x4f,0x3f,0x31,0x85,0x86,0x85,0x94,0x63,0xa5,0xb4,0x9b,0x99,0x5d,0x93,0x8c,0x88 +,0x8a,0xd6,0x23,0x20,0x32,0x4a,0x2d,0x2e,0x1c,0x2d,0x1d,0x17,0x0c,0x0b,0x0a,0x0a,0x90,0x97,0x91,0x3f,0x0f,0x1c,0x15,0x3a,0x37,0x15,0xb6,0x9d,0x95,0x92,0x21,0x18 +,0x16,0x25,0xd7,0x49,0x65,0x2d,0x4c,0x31,0x2d,0x1d,0x25,0x15,0x2e,0x84,0x85,0x84,0x9e,0xbb,0xa6,0xa0,0x8b,0x90,0x9a,0x89,0x86,0x84,0x84,0x97,0xae,0x46,0x9f,0x93 +,0x90,0x8f,0xac,0xa1,0xc9,0xd4,0x2d,0x2a,0x0c,0x53,0x89,0x8a,0x8b,0x1c,0x16,0x13,0x20,0xa8,0x30,0x3f,0xa3,0xa4,0x8e,0xa7,0x25,0x0f,0x0a,0x1f,0x24,0xbf,0x65,0x17 +,0x19,0x10,0x15,0x18,0x15,0x06,0xb6,0x92,0x8a,0x96,0x11,0x15,0x0d,0xd5,0x9e,0xbf,0xab,0xad,0x96,0x8d,0xa2,0x5c,0x0f,0x17,0x30,0x66,0x9f,0x3d,0x27,0x19,0x18,0x1e +,0x1c,0x17,0x09,0x9c,0x97,0x88,0x9e,0x19,0x1a,0x10,0xa6,0x9b,0x9f,0x9b,0xa6,0x90,0x8a,0x9f,0xce,0x10,0x20,0x74,0xa6,0x98,0x40,0x2d,0x1b,0x1b,0x1b,0x1f,0x0e,0x11 +,0x96,0x96,0x88,0xdf,0x1d,0x13,0x12,0xa0,0xa5,0x9c,0xa1,0xa9,0x8f,0x8c,0x9a,0x5e,0x11,0x21,0x40,0xa5,0x9b,0x3a,0x26,0x16,0x1e,0x18,0x21,0x0a,0x1d,0x96,0x92,0x8a +,0x27,0x18,0x0c,0x1d,0xa0,0x9e,0x98,0xac,0xa9,0x90,0x97,0x9b,0x21,0x13,0x20,0x2d,0x9e,0xaf,0x37,0x1b,0x10,0x1d,0x16,0x23,0x07,0x22,0x9b,0x96,0x8c,0x23,0x19,0x0b +,0x27,0x9d,0x9c,0x98,0xaa,0xac,0x8f,0x9c,0x9e,0x1e,0x19,0x31,0x3b,0x97,0xac,0x3a,0x1e,0x18,0x1b,0x1d,0x20,0x0b,0xcc,0x99,0x8f,0x90,0x23,0x1e,0x0b,0xfb,0x99,0x95 +,0x98,0xad,0xa7,0x97,0x9b,0xab,0x1d,0x19,0x2a,0x49,0x96,0xb1,0x42,0x16,0x19,0x12,0x22,0x1d,0x12,0x9a,0x9f,0x89,0xb3,0x2a,0x18,0x0e,0xac,0x9e,0x93,0x9d,0xac,0xa3 +,0x9b,0xa6,0xb9,0x19,0x28,0x22,0xba,0x9d,0x47,0x3a,0x0f,0x17,0x12,0x2c,0x16,0x2d,0x99,0x98,0x8d,0x30,0x2b,0x0c,0x1b,0xad,0x9f,0x92,0x9d,0x9f,0xa2,0x9f,0xa7,0x29 +,0x1e,0x2f,0x29,0x9e,0xaa,0xc8,0x23,0x1b,0x1a,0x17,0x2c,0x12,0x9e,0x9b,0x8e,0x9a,0x1f,0x28,0x0c,0x62,0xa5,0x99,0x95,0x9f,0xa3,0x9f,0xa2,0xad,0x1f,0x23,0x2c,0x3a +,0x9e,0xca,0x5d,0x19,0x1e,0x17,0x26,0x18,0x2a,0x96,0x9c,0x8d,0x28,0x2c,0x10,0x1a,0xa9,0xa7,0x92,0x9f,0xa4,0x9e,0x9f,0x9f,0x44,0x17,0x27,0x1d,0xa2,0xba,0xbe,0x2b +,0x15,0x1a,0x13,0x25,0x0f,0xa5,0xa0,0x92,0xaa,0x19,0x1c,0x0c,0xd1,0xa6,0x98,0x9b,0xa9,0xb9,0x9e,0x9b,0xab,0x2b,0x1b,0x24,0x40,0xa0,0xc3,0xf3,0x19,0x1f,0x0f,0x26 +,0x16,0x31,0x96,0x9d,0x8d,0x1f,0x27,0x0e,0x1c,0xa6,0x9c,0x8f,0x9d,0xa1,0xa0,0x9e,0x9a,0xcc,0x2e,0x2f,0x2c,0x9f,0xa7,0xb4,0x2c,0x1a,0x1e,0x17,0x2e,0x16,0xa6,0x9b +,0x96,0x9e,0x17,0x1d,0x0c,0x55,0xa3,0x96,0x99,0xac,0xa9,0xa6,0x9f,0xa1,0x41,0x31,0x2e,0x34,0xa6,0xe5,0xef,0x19,0x1f,0x15,0x1e,0x18,0x23,0x98,0xa3,0x8f,0x1f,0x1b +,0x0e,0x18,0xad,0xa9,0x94,0xaa,0xa5,0xab,0x9e,0x9f,0xaf,0x33,0x2c,0x22,0xb9,0xb9,0xb8,0x2e,0x1d,0x1d,0x16,0x1f,0x15,0x9d,0x9e,0x8e,0xb0,0x1c,0x1c,0x0c,0xb2,0xab +,0x97,0x9b,0xa3,0xa5,0xa1,0x9f,0xa7,0x64,0x3c,0x2f,0x3f,0xab,0xba,0xcd,0x1b,0x22,0x11,0x21,0x16,0xc0,0x93,0x98,0x92,0x1a,0x22,0x0d,0x24,0xa7,0x9c,0x94,0xa7,0xa6 +,0xaf,0xa1,0xa4,0xce,0x3d,0x3a,0x39,0xb1,0xcf,0xbf,0x1f,0x25,0x17,0x1b,0x1b,0x1d,0x94,0xa2,0x8f,0x29,0x1d,0x14,0x17,0xae,0xaa,0x97,0xa5,0xa7,0xad,0x9f,0xa1,0xa9 +,0x30,0x3e,0x29,0xbb,0xcc,0xdd,0x28,0x1b,0x1e,0x13,0x28,0x13,0x9f,0x9d,0x93,0xa3,0x1a,0x1c,0x0c,0x58,0xa4,0x97,0x9a,0xa4,0xad,0xa1,0x9d,0xa4,0x55,0x2f,0x33,0xd9 +,0xb5,0x73,0x44,0x15,0x27,0x16,0x30,0x1b,0xb5,0x97,0x98,0x95,0x1a,0x1e,0x0b,0x2e,0xaf,0x99,0x97,0x9f,0xaf,0xb0,0x9e,0x9d,0xbb,0x2e,0x34,0x47,0xac,0x72,0x48,0x14 +,0x1d,0x16,0x31,0x1d,0xab,0x9d,0x9b,0x9b,0x1b,0x27,0x0b,0x2f,0xbe,0x98,0x99,0xa2,0xb9,0xb4,0x9c,0xa0,0xbc,0x33,0x34,0x2e,0xc6,0x54,0x53,0x17,0x18,0x0f,0x2d,0x1f +,0xa2,0x9d,0xa1,0xa4,0x16,0x2f,0x0e,0x4b,0xc4,0x9e,0x9b,0x9f,0xa7,0xb8,0xa5,0xa9,0xae,0xdf,0xc0,0xcc,0xbd,0x3e,0x3d,0x14,0x1d,0x11,0x2d,0x1d,0x9c,0x98,0x9f,0xa4 +,0x17,0x2b,0x0f,0xc5,0xd2,0x97,0x9e,0x9b,0xb2,0xb3,0xa9,0xad,0xa8,0xb7,0xc3,0xc5,0xc7,0x3c,0x34,0x14,0x14,0x10,0x22,0x31,0x8d,0x96,0x93,0x1e,0x17,0x10,0x19,0xa7 +,0xa5,0x92,0xa6,0x9f,0xad,0xac,0xc6,0xee,0x48,0xaa,0xad,0xa2,0xbf,0x31,0x17,0x0f,0x0e,0x14,0x1b,0x90,0x8e,0x8c,0x68,0x0f,0x0f,0x0a,0xb0,0xa0,0x90,0x99,0x9d,0xae +,0xbe,0xb9,0x2c,0x3b,0xc8,0xa2,0x9c,0xaa,0x39,0x0f,0x0e,0x0d,0x1a,0x14,0x92,0x91,0x8d,0xac,0x17,0x18,0x0a,0x3a,0xba,0x8d,0x95,0x92,0xb1,0xa9,0xba,0x40,0x2f,0x3a +,0xb2,0xab,0xa1,0xcf,0x20,0x0b,0x0d,0x0c,0x29,0x8f,0x8c,0x8e,0x32,0x1d,0x0e,0x18,0x4a,0x35,0x9e,0x9d,0x90,0x9b,0x9e,0x65,0x2b,0x5b,0xaf,0x9b,0xb6,0xce,0x1f,0x18 +,0x0f,0x15,0x12,0x31,0x93,0x8e,0x8a,0x2a,0x22,0x0a,0x1e,0xbe,0xaa,0x96,0xab,0x9f,0xab,0x9c,0xbd,0x6a,0x2b,0xed,0x4c,0xa5,0xd3,0x27,0x0d,0x0a,0x0e,0x1e,0x8d,0x8f +,0x8b,0x2c,0x1b,0x16,0x16,0xb0,0xe0,0xa8,0xa5,0x9e,0x9f,0xa1,0xc9,0xc3,0x38,0xaa,0xc1,0xc6,0x61,0x22,0x18,0x0d,0x14,0x10,0x98,0x8e,0x89,0xaf,0x19,0x13,0x0d,0xad +,0xac,0x98,0xa3,0xa0,0xae,0xa3,0xac,0x5d,0x65,0xc4,0xa6,0xb6,0xb3,0x22,0x0f,0x0a,0x18,0x15,0x97,0x90,0x94,0xb0,0x18,0x37,0x12,0xbb,0xd0,0xac,0xa0,0x9b,0x9a,0xa5 +,0xb5,0x57,0x5e,0xc8,0xad,0xc7,0xf7,0x1e,0x16,0x0d,0x13,0x13,0x9c,0x96,0x91,0xc8,0x1b,0x1b,0x12,0xa8,0xaf,0x9e,0xac,0x9f,0xa7,0xa0,0xae,0xbf,0x2f,0xc0,0xac,0xb0 +,0xb8,0x21,0x0d,0x0b,0x14,0x1a,0x92,0x9a,0x8f,0x2f,0x24,0x1d,0x13,0xac,0xca,0x9a,0x9e,0x99,0xa4,0xad,0xba,0xd5,0xc2,0xa6,0xb7,0xc6,0x3d,0x18,0x10,0x14,0x12,0x32 +,0x91,0x95,0x8f,0x1e,0x20,0x0e,0x1b,0xa7,0xb7,0x92,0xa9,0x99,0xa7,0xa7,0xb6,0x6f,0xd9,0xab,0xbf,0xb6,0x2f,0x14,0x0d,0x11,0x14,0xaf,0x8f,0x90,0x98,0x15,0x2e,0x0b +,0x37,0xbd,0xb4,0x9c,0x9f,0x9b,0xba,0xae,0x42,0x65,0xb0,0x9d,0xae,0xd7,0x1e,0x0f,0x0d,0x17,0x15,0x91,0x9a,0x8d,0xdf,0x1b,0x2c,0x0e,0x9e,0x6a,0xa6,0xb5,0xa5,0xa7 +,0xa3,0xbb,0xcd,0x2e,0xc4,0xa6,0xbc,0xdf,0x1b,0x0c,0x13,0x14,0xd1,0x8c,0x9a,0x92,0x0f,0x3b,0x17,0x48,0x98,0xae,0xa3,0xc4,0xa3,0xb8,0xbb,0x47,0x3e,0x58,0xa1,0xa9 +,0xbf,0x1d,0x0d,0x0c,0x1b,0x2b,0x8c,0x92,0x8f,0x1f,0x13,0x1c,0x1c,0x98,0xad,0x94,0xec,0x9a,0xae,0xa8,0xf4,0x32,0x34,0xbd,0xa4,0xaf,0x2c,0x13,0x0b,0x0c,0x1c,0xc2 +,0x88,0x90,0x90,0x16,0x1d,0x0f,0x39,0xa1,0xa6,0x9e,0xae,0x97,0xb1,0x9f,0x3c,0x37,0x34,0xaa,0xa5,0x5e,0x1f,0x0b,0x08,0x11,0x1c,0x8b,0x8f,0x8e,0x2a,0x14,0x1f,0x1e +,0x92,0xae,0x9f,0x37,0xa2,0xa6,0x97,0xad,0xc8,0x51,0xbe,0x9d,0xc0,0x26,0x0e,0x06,0x0e,0x12,0xb4,0x88,0x99,0x91,0x0d,0x23,0x0f,0x4e,0x98,0xa3,0x95,0xb4,0x9e,0xbe +,0xac,0x3d,0xbd,0xbe,0x92,0x9f,0xb3,0x1e,0x09,0x08,0x0c,0x18,0x8f,0x8d,0x8c,0x3b,0x0e,0x17,0x0e,0x9a,0x66,0x97,0xc0,0x9d,0x9e,0x9e,0xa4,0x2e,0x40,0xbd,0x9a,0x9f +,0xcb,0x1a,0x0d,0x0a,0x12,0x27,0x8d,0x96,0x93,0x19,0x1c,0x12,0x27,0xa6,0xbe,0xa0,0xbe,0x99,0xb2,0x9d,0x55,0xc9,0x68,0x9b,0x9b,0xb7,0x28,0x0f,0x0b,0x16,0x17,0x98 +,0x8c,0x94,0xab,0x0a,0x20,0x0b,0xa8,0xaf,0xa6,0xad,0xb4,0xa2,0xa7,0xae,0x3c,0x58,0xea,0x8f,0xa4,0xa0,0x17,0x0d,0x09,0x11,0x23,0x8e,0x8c,0x8b,0x44,0x11,0x1a,0x0c +,0xa4,0x48,0x98,0xbb,0x9d,0x9e,0xb1,0xb8,0x25,0x2e,0xb1,0x99,0x99,0xcc,0x1c,0x0b,0x0a,0x15,0x31,0x8b,0x90,0x8e,0x1c,0x1e,0x15,0x29,0xb0,0xb8,0xad,0xca,0x99,0xac +,0x99,0x29,0x40,0x1f,0xa1,0x98,0xa4,0x3d,0x12,0x09,0x0e,0x1c,0xba,0x89,0x9a,0x90,0x0e,0x25,0x11,0x28,0x9c,0xb2,0x97,0xaa,0x99,0xb1,0xc9,0x28,0x32,0x2d,0x95,0x9b +,0xa8,0x27,0x0d,0x09,0x0f,0x1c,0x98,0x8c,0x8d,0x9e,0x10,0x22,0x0a,0x4d,0xd0,0x9f,0x99,0x9b,0x90,0xb2,0xb9,0x24,0x28,0x46,0x99,0x9d,0xaa,0x1e,0x0f,0x07,0x12,0x1c +,0x9b,0x8c,0x92,0xa5,0x14,0x25,0x0d,0xdb,0xcc,0xa9,0xa3,0x9a,0x96,0xa5,0xb0,0x2c,0x3d,0xcc,0x96,0xa7,0xe2,0x1a,0x0b,0x0d,0x1a,0x25,0x8f,0x9d,0x92,0x2e,0x16,0x2b +,0x0f,0x9e,0x3a,0x9d,0xad,0x9c,0xa0,0xb6,0xdb,0x3f,0xdc,0x9d,0x93,0xaf,0xd3,0x11,0x0e,0x0c,0x1c,0x30,0x8f,0x98,0x93,0x1a,0x1b,0x12,0x19,0xa6,0x61,0x91,0xbf,0x8f +,0xbc,0xaf,0x32,0x2f,0xd1,0x9d,0x96,0xa5,0x36,0x16,0x0d,0x13,0x1c,0x5d,0x8d,0x9e,0x91,0x13,0x29,0x0e,0x21,0xdb,0xc8,0x9b,0xa8,0x93,0xb9,0xa5,0x26,0xbb,0x45,0x97 +,0xa5,0xbd,0x29,0x12,0x10,0x1a,0x1d,0xa3,0x8f,0x97,0x99,0x0d,0x2e,0x0a,0xd0,0x6b,0xa5,0x9e,0xb6,0x98,0x4e,0xad,0x2b,0xb7,0xb2,0x95,0xa3,0xce,0x17,0x0e,0x0c,0x1c +,0x23,0x91,0x8f,0x8e,0xb9,0x12,0x1e,0x0b,0xb6,0x2d,0x95,0xae,0x97,0xa5,0x62,0xda,0x1f,0xb3,0xaa,0x8f,0xa0,0x48,0x16,0x0c,0x0c,0x1b,0x21,0x8e,0x93,0x8d,0x3d,0x19 +,0x1f,0x11,0xad,0x49,0x9c,0xb4,0x9a,0xa6,0xb0,0x3e,0x2d,0x3d,0xa0,0x97,0xa5,0x30,0x13,0x0b,0x14,0x1e,0xd9,0x8c,0x9d,0x90,0x11,0x37,0x14,0x2d,0xa2,0xc7,0x99,0x5e +,0x98,0x58,0xb2,0x35,0xef,0xb8,0x96,0xa2,0xd6,0x19,0x0f,0x0d,0x18,0x2a,0xab,0x8d,0x95,0xa0,0x13,0x27,0x0e,0xd9,0xb2,0x9b,0x9f,0xab,0x9a,0x7e,0xbc,0x28,0x34,0xb1 +,0x9a,0x9d,0xbb,0x18,0x0e,0x07,0x1c,0x1e,0x8e,0x8e,0x8f,0x79,0x12,0x26,0x0f,0xaa,0xe5,0xa0,0xb8,0x9c,0x9c,0xa1,0xb9,0x2b,0x47,0xb0,0x9a,0xa7,0x2f,0x16,0x0b,0x0f +,0x1e,0x28,0x8f,0x9f,0x8e,0x24,0x28,0x1f,0x16,0xac,0x3b,0x98,0xc7,0x99,0xa5,0xb5,0xc8,0xe4,0xad,0x99,0x9f,0xb4,0x1b,0x0f,0x0c,0x14,0x22,0x76,0x91,0x9f,0x97,0x16 +,0x2c,0x14,0x36,0xaa,0xc6,0x9c,0xd6,0x99,0xad,0xaa,0xde,0xeb,0xab,0x9a,0x9c,0xa8,0x1a,0x13,0x09,0x17,0x18,0xcf,0x8f,0xa5,0x96,0x12,0x36,0x11,0x3a,0xb8,0xbf,0x9c +,0xcd,0x98,0xb2,0xaa,0x4f,0xb9,0xa8,0x9a,0x9d,0x7b,0x1b,0x17,0x0f,0x29,0x17,0xaa,0xa1,0xa2,0xa5,0x12,0xbe,0x0d,0xbb,0x3f,0xb8,0xa8,0xc9,0x98,0xb1,0xa7,0xb4,0xb8 +,0x9f,0x9b,0xb0,0x5c,0x10,0x1b,0x0f,0x38,0x1d,0xac,0x9f,0xa5,0xbb,0x15,0x49,0x11,0xab,0x6f,0xa6,0xb6,0x7b,0x9d,0xb9,0x9d,0xae,0xb2,0x9d,0xaf,0xa7,0x2a,0x1f,0x1a +,0x11,0x38,0x12,0xa1,0xaf,0x98,0xc9,0x1b,0x3b,0x0e,0xab,0x55,0xb0,0xbe,0xca,0xa2,0xb2,0xa5,0xb3,0xad,0x9c,0x9e,0xaf,0x3a,0x19,0x18,0x1a,0x37,0x1b,0xe5,0xb6,0xa1 +,0xb4,0x2a,0xd1,0x18,0xbd,0x42,0xbb,0xb5,0xb4,0xa2,0x5e,0xa8,0xb6,0xab,0x9c,0xa7,0xb4,0x1f,0x1e,0x1e,0x1d,0x4d,0x17,0x76,0xbb,0x9f,0xba,0x2d,0xe8,0x1a,0xbf,0xd3 +,0xc5,0x65,0xc4,0xa5,0xad,0xa1,0xa7,0xae,0xaa,0xaf,0xc2,0x29,0x27,0x25,0x1f,0x37,0x17,0x3d,0x5d,0xa2,0xc0,0x2c,0xbb,0x1a,0xcb,0xf6,0xcc,0xb7,0xd4,0x9e,0xaf,0x98 +,0x9d,0xad,0xa7,0x41,0x6d,0x26,0x2f,0x37,0x23,0x2c,0x11,0x28,0xec,0xaf,0xb8,0x2f,0xd8,0x2a,0xc2,0xc5,0xe5,0xfa,0x4d,0xa7,0xa0,0x99,0x99,0x9f,0xb0,0x73,0x53,0x2d +,0x2d,0x34,0x25,0x2a,0x1c,0x1b,0x28,0xcd,0xdb,0x4b,0xbe,0x49,0xc1,0xc1,0xe9,0x5e,0xe5,0xb0,0xaa,0x9d,0x95,0x99,0xa9,0xb3,0x40,0x3c,0x3b,0x3c,0x26,0x1f,0x1e,0x16 +,0x26,0x32,0x3f,0x33,0xfd,0x5c,0x4f,0xb2,0xc5,0xca,0xb8,0xbc,0x9d,0x9a,0x99,0x9c,0xac,0xa2,0x4a,0xb8,0x4c,0x58,0x2e,0x1b,0x1e,0x15,0x1a,0x20,0x34,0x2c,0x46,0x65 +,0xf9,0x7b,0xc1,0xce,0xba,0xac,0x9f,0x96,0x93,0xa4,0xaf,0xb2,0x48,0xb3,0xb9,0xae,0x50,0x2f,0x1d,0x17,0x17,0x18,0x23,0x28,0x2e,0xea,0x65,0x40,0x6e,0xea,0xb6,0xb5 +,0x9e,0xa1,0x97,0x9c,0xa1,0xa8,0xcc,0xaa,0xbe,0xaa,0xd1,0x3f,0x2e,0x1f,0x1f,0x17,0x1c,0x28,0x19,0x1e,0x2f,0x1d,0x3b,0xf2,0x3f,0xd9,0x7b,0x30,0x2a,0x8f,0x83,0x8a +,0x9b,0x22,0x13,0x9a,0x83,0x8e,0xa6,0xc7,0xb5,0xdf,0x2c,0x0c,0x0d,0x10,0x21,0x2a,0x10,0x09,0x10,0x2b,0xbd,0x96,0xc4,0x47,0x0c,0x0d,0xb2,0x85,0x80,0x84,0x8c,0x96 +,0x98,0xb7,0xe6,0x0c,0x17,0x2b,0xbb,0x1d,0x0b,0x0b,0x13,0xc9,0x23,0x19,0x1a,0x28,0x3c,0xa4,0x9f,0x97,0x8e,0x90,0x9e,0x4c,0x36,0x3b,0x36,0x4a,0x29,0xa9,0x93,0x1c +,0x0b,0x16,0xac,0x92,0xde,0x12,0x0d,0x50,0x90,0x91,0x9a,0xb6,0xaa,0xbf,0x1e,0x1b,0x2b,0xd1,0xdf,0x3e,0x5b,0xf1,0x39,0x1b,0x1a,0xa2,0x8a,0x91,0x54,0x15,0x0e,0x32 +,0xa1,0x9b,0xaf,0x38,0xa7,0xb5,0x2f,0x1e,0x2b,0xbc,0xa5,0x9e,0x53,0x4a,0xb9,0xa3,0x9d,0x9f,0xbd,0x16,0x09,0x0c,0x17,0xa6,0x91,0xac,0xd9,0xd7,0xc9,0x39,0x2c,0x17 +,0x1e,0x9c,0x92,0x9b,0xbe,0x48,0xb2,0xa3,0x9d,0xaf,0x22,0x22,0x27,0xbd,0x96,0x93,0x9c,0x63,0x17,0x0d,0x1c,0x2c,0x29,0x17,0x20,0x4b,0x47,0x1c,0x0e,0x1e,0x9f,0x87 +,0x98,0xc7,0xfe,0xa2,0x8e,0x8d,0x97,0x99,0x92,0x9d,0x27,0x1d,0x30,0x1b,0x16,0x15,0x1c,0x1f,0x17,0x08,0x08,0x40,0x98,0xa8,0x36,0x1f,0x2d,0x9a,0x8b,0x88,0x96,0x94 +,0x98,0xb8,0xaf,0x3c,0x2b,0xdb,0xba,0xab,0x38,0x3e,0x4d,0x23,0x35,0x2c,0x30,0x17,0x0a,0x08,0x14,0x9e,0x9e,0x2c,0x30,0xcc,0x9a,0xaa,0x53,0x62,0xb3,0x8a,0x8c,0x9a +,0xcc,0xed,0x9d,0x92,0x93,0xb0,0x21,0x16,0x14,0x1c,0x41,0x59,0x54,0x1f,0x0f,0x0e,0x0d,0x1a,0x11,0x12,0xb6,0x94,0x87,0xa8,0x46,0xaa,0x95,0x86,0x9d,0x3f,0x2f,0xbf +,0x8d,0x95,0x99,0xa5,0xbc,0xa6,0x1f,0x18,0x15,0x15,0x1a,0x14,0x1b,0x15,0x08,0x06,0x03,0x2b,0x8e,0x8b,0x95,0x6f,0x9b,0x92,0x88,0x89,0x9c,0x92,0x93,0x94,0x9e,0x3d +,0x49,0x19,0x20,0x2e,0x17,0x19,0x0d,0x13,0x1b,0x29,0x46,0x0e,0x0c,0x06,0x0c,0x98,0x89,0x85,0x92,0x96,0x8f,0xbf,0xb0,0x35,0x29,0x93,0x90,0x8d,0xa7,0x35,0xdf,0x42 +,0xae,0x2f,0x18,0x14,0x12,0x2b,0x54,0x44,0x26,0x0e,0x0e,0x06,0x0e,0x46,0xbe,0x95,0x98,0x8a,0x87,0x9e,0x9f,0x37,0x98,0x87,0x91,0x98,0x22,0x28,0x2a,0x5f,0xaa,0x4c +,0x5e,0x2e,0x17,0x18,0x0f,0x0e,0x0e,0x10,0x2b,0x11,0x2d,0x4b,0xc6,0x8e,0x96,0x8d,0x9b,0xc2,0xa5,0xca,0x98,0x8f,0x9b,0x8f,0xa4,0xa6,0xc8,0x28,0x46,0x1b,0x2a,0x25 +,0x19,0x1c,0x0a,0x0c,0x0f,0x23,0x3a,0x0d,0x27,0x2b,0xa1,0x8c,0x8e,0x85,0x92,0x91,0x9a,0x2f,0xaf,0xc6,0xb2,0x9f,0x7b,0xae,0x32,0x2f,0x2f,0x1c,0x38,0x2a,0x29,0x23 +,0x10,0x1c,0x1d,0xaf,0x4d,0x2c,0xa0,0x3d,0xbb,0x20,0x1c,0xcf,0xbe,0x8f,0x9c,0xc0,0x9f,0xb7,0x95,0x97,0xa5,0xa3,0x5f,0xa9,0xba,0xe6,0xa7,0xdd,0x3e,0x15,0x0b,0x0c +,0x0f,0x10,0x08,0x23,0xb1,0x9a,0x9f,0x2a,0xd5,0xab,0x94,0x8d,0xb3,0xa1,0x9c,0x9c,0x98,0xac,0xa5,0xa3,0xa3,0xab,0x28,0x25,0x28,0x1d,0x23,0x0f,0x15,0x15,0x1a,0x0d +,0x1a,0xa9,0x9f,0xa5,0x1a,0x1e,0x44,0xa9,0x93,0x9f,0x99,0x89,0x8f,0x8f,0xbd,0x34,0xb4,0xa4,0x97,0xb9,0x3b,0x25,0x1e,0x19,0x0f,0x0d,0x0c,0x12,0x09,0x17,0xac,0x97 +,0x8b,0xa7,0xaf,0xb9,0x58,0xc8,0x1a,0x36,0x9b,0x91,0x8d,0x9d,0xc3,0xb1,0xba,0xad,0x55,0x2a,0x5e,0x4d,0xb9,0x31,0x22,0x25,0x29,0x0f,0x17,0x3f,0x3d,0xbf,0x1e,0x25 +,0xe6,0x41,0x58,0x1b,0x27,0x92,0x8e,0x89,0x98,0xbc,0x9e,0xa1,0x95,0x9e,0xaa,0xa5,0xf4,0x2a,0x13,0x09,0x0a,0x0d,0x06,0x1a,0xa2,0x9f,0x97,0x2f,0x33,0xaa,0xb7,0x9e +,0x29,0x2f,0x9e,0x9e,0x91,0x9e,0xae,0x9a,0x9f,0xa4,0x3d,0x26,0x2d,0x26,0x2a,0x1f,0x16,0x21,0x23,0x12,0xbd,0xae,0xa8,0xc8,0x1e,0xdf,0xce,0xa2,0xa2,0x3d,0xb4,0xa0 +,0xb1,0xac,0x2d,0x37,0xa6,0x9b,0x96,0xbd,0x3e,0x30,0x1d,0x1e,0x1b,0x11,0x1f,0x14,0x24,0x95,0x92,0x8b,0x9b,0xb8,0xb8,0x35,0x3b,0x24,0x19,0xde,0xa7,0xac,0xb3,0x27 +,0x2c,0x4a,0xd4,0xc8,0x32,0x5c,0xba,0xda,0x47,0x35,0xce,0xad,0x2e,0xaa,0x9f,0xa1,0xa0,0x28,0x2b,0x23,0x21,0x2e,0x1d,0x2d,0xa1,0x9f,0x9a,0xb4,0x2d,0x4e,0x7e,0xb1 +,0xb4,0xd7,0xa8,0xaa,0x59,0x27,0x0f,0x1c,0x10,0x13,0xac,0xa9,0x93,0x99,0xb9,0xa4,0xba,0xbb,0x52,0x21,0xbc,0xa3,0xa4,0x9c,0xc4,0xbb,0xbb,0x3a,0x20,0x12,0x14,0x1c +,0x2a,0x31,0x29,0x2c,0xef,0x23,0xb1,0x95,0x9b,0x92,0xb0,0xb8,0xae,0xdd,0xb0,0x38,0x5a,0x9c,0xab,0xaa,0x5e,0x23,0x4a,0x42,0x5f,0x32,0x1f,0x22,0x22,0x1d,0x1e,0x15 +,0x20,0x1c,0x19,0x9a,0x98,0x8c,0x8d,0x9a,0x91,0xa7,0xb3,0xde,0x21,0xbd,0xb4,0xc6,0xb2,0x34,0x64,0x55,0x30,0x29,0x1b,0x1a,0x1b,0x16,0x1c,0x18,0x22,0xbc,0x2f,0x9a +,0x8d,0x93,0x94,0x51,0xdd,0xb2,0x3f,0xcc,0x2e,0x54,0x99,0xa2,0x9e,0xab,0xe8,0xab,0xd5,0x47,0x3b,0x2b,0xdd,0x2c,0x1f,0x1a,0x0c,0x14,0x0b,0x0b,0x43,0xc3,0x98,0x9c +,0xa8,0x91,0x98,0x9a,0xa2,0xbb,0x97,0x95,0x9a,0x99,0xa9,0x9c,0xa2,0x7e,0x21,0x0f,0x13,0x12,0x0e,0x0e,0x0b,0x0f,0x1a,0x0f,0x3c,0xa5,0x9c,0x91,0xa1,0x9a,0x99,0xa0 +,0x9f,0xb7,0xa5,0x8f,0x99,0x99,0xa8,0xbf,0xb0,0x49,0x3a,0x23,0x1f,0x27,0x1c,0x17,0x15,0x0c,0x17,0x0e,0x0d,0x4d,0x5c,0x9f,0x9f,0xa8,0x92,0x9a,0x99,0x9e,0xcc,0x98 +,0x99,0x9c,0x99,0xae,0xa1,0xa8,0xbd,0x38,0x18,0x18,0x17,0x12,0x14,0x0f,0x12,0x29,0x1c,0xc2,0x9a,0xa2,0x9e,0x4f,0x5a,0xae,0x69,0xb2,0x5f,0x43,0x9c,0xa6,0x9e,0x9d +,0xaa,0x99,0x9f,0xb2,0xda,0x2f,0xd8,0xe2,0x2d,0x2e,0x15,0x18,0x14,0x0a,0x24,0x24,0x35,0xd0,0x28,0xb4,0xb6,0xcb,0xb4,0x3d,0xa1,0x91,0x97,0x8f,0x99,0x98,0x91,0x9d +,0xad,0x30,0x1f,0x26,0x1c,0x19,0x16,0x0e,0x19,0x0e,0x1a,0xb5,0xcc,0x9f,0xba,0xc6,0xa8,0xcf,0xcc,0x45,0x32,0xa1,0x9f,0xa1,0x9e,0xbd,0xa6,0xa0,0xab,0xb3,0x43,0xe9 +,0xb9,0x38,0x4a,0x1a,0x1c,0x1e,0x11,0x4d,0x3e,0x41,0xd0,0x33,0xad,0xaa,0xca,0xef,0x1d,0x35,0xad,0xb5,0xa4,0xb6,0xaf,0x9b,0x9e,0xa3,0xcb,0x2e,0xc9,0x3f,0x43,0x2f +,0x18,0x2d,0x1c,0x28,0xa2,0xae,0x9c,0xad,0x49,0xb1,0x34,0x2e,0x24,0x16,0x3d,0xf6,0x55,0xb8,0x2e,0xc6,0xaa,0xae,0xa5,0xc3,0xa8,0x99,0x9d,0x9d,0xbe,0x28,0x2d,0x14 +,0x2f,0xbe,0x36,0x58,0x1e,0x22,0x43,0x2d,0x38,0x29,0x29,0xa8,0xaf,0xa3,0xa8,0xbb,0x9c,0x9b,0x9d,0xab,0xf5,0xdf,0x76,0x2e,0x2d,0x18,0x1e,0x1f,0x18,0xd2,0xd3,0xbe +,0xac,0xcf,0xaa,0xab,0xb5,0xb5,0x3c,0xc9,0xab,0xb7,0xb1,0xde,0x2c,0x4e,0x42,0x38,0x2c,0x21,0x45,0xc4,0xb2,0xba,0x27,0x2d,0x26,0x22,0xa8,0xb2,0xab,0xae,0xb4,0xa2 +,0xa5,0xaf,0xc0,0x35,0x3d,0xb5,0xbf,0xa9,0xf5,0x2c,0x36,0x2c,0x34,0x31,0x2a,0x35,0x2c,0x31,0x32,0x1f,0x38,0x2c,0x3c,0x9f,0x9b,0x99,0x9d,0xb3,0xaa,0xa8,0xb4,0xaa +,0x49,0xdf,0xbb,0x68,0x4c,0x25,0x1b,0x31,0x31,0x2f,0x2a,0x21,0x45,0xbc,0xaf,0xad,0x40,0x46,0x36,0x28,0xaf,0xb7,0xb8,0xd1,0x30,0x57,0xbc,0xae,0xab,0x4d,0x78,0xa4 +,0x9d,0x99,0xa0,0xc8,0xcc,0xe7,0x3f,0x46,0x29,0x27,0x29,0x1f,0x1e,0x16,0x17,0x19,0x16,0x35,0xb4,0xa9,0x9f,0xa7,0xa6,0x9d,0x9c,0x94,0x98,0x9a,0x96,0x9a,0xa3,0xbf +,0x27,0x20,0x1d,0x1d,0x21,0x21,0x23,0x29,0x23,0x1f,0x1a,0x16,0x20,0x1d,0xfb,0xa6,0xa3,0x9f,0xb8,0xbf,0xa2,0x9c,0x96,0x9c,0xa8,0x9c,0x9d,0x9b,0xa5,0x59,0x2d,0x36 +,0x2b,0x2f,0x26,0x1f,0x1f,0x1a,0x1d,0x1a,0x18,0x1d,0x23,0x28,0xad,0xa3,0xa1,0xac,0xc7,0xb5,0xa2,0x9d,0x97,0x9f,0xa4,0x9e,0xa9,0xa4,0xc7,0x46,0x31,0x2b,0x37,0xf3 +,0x3b,0x3f,0x2e,0x29,0x27,0x20,0x1e,0x2b,0x26,0x2c,0x3f,0x26,0x2c,0x22,0x2c,0xc7,0xab,0xa3,0x8f,0x95,0x95,0x91,0x95,0x92,0xa0,0xaf,0xc1,0xfa,0xc0,0x2e,0x22,0x16 +,0x18,0x1d,0x15,0x19,0x13,0x1a,0x18,0x21,0x34,0xe3,0xe1,0xbd,0xa7,0xa3,0x98,0x96,0x8f,0x96,0x99,0xa5,0xa3,0xa0,0xaa,0xbb,0x2e,0x4a,0x43,0x38,0x22,0x1e,0x20,0x26 +,0x2b,0x24,0x25,0x1f,0x1e,0x17,0x29,0x36,0xda,0xbe,0xd4,0xaa,0xa6,0x9f,0x99,0x9f,0xa2,0xa1,0xa5,0x9a,0x9e,0xa4,0x63,0x3b,0x28,0x2a,0x22,0x1f,0x27,0x2e,0x34,0x22 +,0x2e,0x1e,0x1e,0x19,0x21,0x43,0x6b,0xcf,0xc3,0xd8,0xad,0xa3,0xa2,0xa0,0xaa,0x9e,0x9d,0x9a,0x9e,0xa0,0xaf,0xc7,0x5b,0x4c,0x45,0x3d,0x2f,0x25,0x26,0x1f,0x1b,0x13 +,0x10,0x13,0x1a,0x29,0x34,0xe0,0xc6,0xad,0x9f,0x9e,0x97,0x97,0x97,0x96,0x95,0x9c,0x9e,0xad,0xc5,0x3e,0x2a,0x23,0x21,0x24,0x24,0x29,0x20,0x26,0x1e,0x20,0x21,0x20 +,0x21,0x30,0xae,0xb2,0xae,0xc9,0x57,0xaf,0xae,0xa2,0x9e,0xa7,0xa6,0xa8,0xad,0x9f,0xac,0xbb,0xbb,0x69,0xc9,0x68,0x39,0x2d,0x27,0x23,0x25,0x1e,0x20,0x1c,0x1d,0x1b +,0x2b,0xeb,0xc7,0xb5,0x6f,0xbb,0xaa,0x9f,0x99,0x9e,0xa5,0xa0,0xad,0xa2,0xae,0xa6,0xac,0xc1,0xf4,0x2f,0x35,0x29,0x2d,0x2d,0x2a,0x26,0x22,0x1a,0x1d,0x1c,0x22,0x53 +,0x33,0x3f,0x46,0xe3,0xa2,0xa3,0x9d,0x9d,0xa6,0x9a,0x97,0x9a,0x97,0xa4,0xb9,0xbe,0x33,0x2b,0x1d,0x18,0x21,0x1f,0x2a,0x28,0x1c,0x1c,0x1e,0x21,0x21,0xc2,0xca,0xab +,0xae,0xb5,0xa5,0xac,0xa3,0xa6,0xa5,0xa2,0x9c,0x9e,0x9e,0xca,0x75,0x41,0x37,0x30,0x36,0x35,0x33,0x42,0x56,0x37,0x28,0x20,0x1d,0x1d,0x15,0x3c,0x2d,0x44,0x5d,0x34 +,0xb7,0xa2,0x9c,0x94,0x9b,0x9d,0x97,0x9d,0x9a,0xaa,0xb6,0xdd,0x3b,0x2d,0x2c,0x1f,0x2f,0x25,0x2b,0x22,0x1c,0x1b,0x1f,0x18,0x20,0xe2,0x31,0xaf,0x3c,0xba,0x9c,0x9d +,0x98,0x9d,0xb1,0x98,0x99,0x9e,0xa0,0xcd,0xe3,0xe7,0x32,0x35,0x25,0x2c,0x37,0x2c,0x28,0x1e,0x18,0x1c,0x1a,0x16,0x5a,0x27,0xc2,0xd2,0xc9,0x9b,0x9c,0x99,0x97,0xa8 +,0x9b,0x99,0xa5,0x9e,0xc8,0xe0,0x59,0x25,0x28,0x22,0x29,0x3a,0x2b,0x2f,0x28,0x1e,0x26,0x1d,0x1b,0xc9,0x30,0xcf,0x5d,0x41,0xa1,0xa6,0x9e,0x9c,0xb1,0x9d,0x9a,0xa8 +,0x9e,0x61,0xdf,0xbd,0x3e,0xc4,0x36,0x41,0xca,0x47,0x39,0x23,0x11,0x17,0x10,0x14,0x4f,0x23,0x5d,0x3d,0x3f,0x9f,0xa6,0x98,0x95,0xa2,0x96,0x98,0xa3,0x99,0xd1,0xbf +,0xdc,0x31,0x4e,0x29,0x34,0x32,0x2a,0x25,0x1d,0x15,0x1d,0x13,0x1d,0xdc,0x34,0xb7,0xe0,0xb9,0x99,0xa7,0x9b,0x9e,0xb9,0x97,0xa2,0xa4,0xab,0x4f,0xb9,0x5f,0x50,0x46 +,0x2b,0x5e,0x44,0x2f,0x2a,0x1b,0x19,0x1d,0x10,0x28,0x5c,0x56,0xa9,0x49,0xa8,0x9d,0xab,0x9a,0xae,0xae,0x9a,0xab,0xa0,0xb8,0xdb,0xb4,0x33,0x41,0x2b,0x29,0x6b,0x46 +,0x3a,0x2d,0x1a,0x1f,0x1e,0x17,0xe3,0x3c,0xcd,0xb3,0x43,0x9d,0x9f,0xaf,0xa4,0x41,0xaf,0x9f,0xb3,0xa4,0x4e,0xce,0xaf,0x4f,0xc5,0x32,0x3f,0xb8,0x58,0xcf,0x2b,0x1b +,0x1d,0x11,0x0f,0x34,0x37,0xb5,0xb5,0x57,0x9d,0x9e,0x9f,0x9c,0xe3,0xa4,0x9e,0xac,0xa5,0x3f,0x6d,0xce,0x35,0x4a,0x23,0x37,0xcc,0x3b,0x4d,0x22,0x19,0x20,0x17,0x15 +,0xc2,0xcf,0xa6,0xa4,0xbf,0x96,0x9c,0x9f,0x9f,0x34,0xae,0xad,0x68,0xc2,0x27,0x4a,0xe4,0x40,0xdd,0x2a,0xd9,0xbc,0x45,0x50,0x24,0x1f,0x24,0x18,0x14,0x6c,0xc6,0xa3 +,0xa2,0xaf,0x98,0x9f,0xa3,0xa7,0x3c,0xb2,0xab,0x79,0xc8,0x2f,0x5a,0xd3,0x32,0x43,0x25,0xec,0xb4,0x47,0x44,0x20,0x1c,0x26,0x1b,0x18,0xb9,0xbb,0xa4,0xa4,0xb3,0x97 +,0xa1,0xac,0xad,0x2e,0xb0,0xa8,0xd9,0xc2,0x2a,0x51,0xdf,0x40,0xcd,0x2e,0xb9,0xaf,0x60,0x3f,0x1d,0x1a,0x1d,0x19,0x14,0xc8,0xbd,0xa7,0xa6,0xb9,0x97,0x9a,0x9f,0xa4 +,0x3c,0xb4,0xa6,0xcb,0xbf,0x2d,0x45,0xcf,0x3a,0x3e,0x25,0x40,0xbb,0x3c,0x32,0x1f,0x1a,0x22,0x1c,0x12,0xc6,0xaf,0x9f,0x9d,0xb3,0x95,0x97,0x9d,0xa2,0x30,0xdd,0xaf +,0x52,0xbe,0x2a,0x49,0xbd,0x3e,0x5b,0x25,0x48,0xba,0x46,0x4d,0x21,0x1e,0x1d,0x19,0x0d,0x2c,0xa8,0xa2,0x96,0xaf,0x9c,0x95,0xa2,0x9d,0x3f,0x5e,0xa4,0xeb,0xad,0x37 +,0x3d,0xbe,0x2f,0x3d,0x25,0x3a,0xb5,0x42,0x4c,0x22,0x1c,0x1e,0x1a,0x0e,0x22,0xa9,0xa1,0x95,0xad,0xa1,0x96,0xa2,0x9e,0x5b,0x3d,0xa1,0xbd,0xb2,0x52,0x32,0xbb,0x4c +,0x48,0x39,0x36,0xb9,0x3f,0x38,0x22,0x19,0x1b,0x1a,0x0e,0x19,0xae,0xa5,0x96,0xa9,0xa7,0x92,0x9d,0x9a,0xbf,0x30,0x9e,0xb0,0xaf,0xcd,0x2c,0xc3,0x41,0x34,0x34,0x29 +,0xc7,0x4d,0x34,0x25,0x19,0x19,0x1c,0x11,0x17,0xab,0x9f,0x94,0xa6,0xad,0x96,0x9f,0x9c,0xc6,0x2b,0xa1,0xa8,0xb3,0xd7,0x2a,0xd7,0xc7,0x47,0x53,0x2c,0xd0,0xdd,0x30 +,0x25,0x17,0x18,0x1d,0x14,0x12,0xb6,0x9f,0x98,0xa5,0xcf,0x99,0x9c,0x9c,0xae,0x2a,0xa3,0x9f,0xaf,0xb4,0x2f,0xc5,0xb6,0x4c,0x4f,0x29,0xe2,0xd5,0x34,0x26,0x18,0x18 +,0x1a,0x10,0x0d,0xd2,0xa5,0x9a,0xa0,0xf3,0x98,0x9c,0x9d,0xae,0x27,0xa2,0x9c,0xa8,0xa9,0x44,0xc1,0xb3,0x49,0x54,0x33,0xcb,0xc6,0x2e,0x1f,0x15,0x14,0x17,0x0d,0x0f +,0xbe,0xa7,0x98,0xa7,0xd5,0x97,0x9d,0x9c,0xaf,0x35,0x9b,0x9a,0xa8,0xaf,0x33,0xda,0xb8,0x48,0x5b,0x37,0xcd,0xea,0x27,0x1f,0x16,0x15,0x19,0x0d,0x16,0xb0,0xa6,0x98 +,0xb6,0xc1,0x97,0xa0,0x9d,0xd8,0x2c,0x9c,0xa4,0xaa,0xad,0x40,0xaa,0xae,0xd5,0x49,0x2e,0xc1,0x47,0x27,0x1d,0x14,0x17,0x1a,0x0e,0x1d,0xb0,0xa6,0x99,0xbe,0xac,0x98 +,0xa9,0xa4,0x3d,0x34,0x9a,0xa6,0xaa,0xb5,0x3b,0xa6,0xae,0xc5,0x4a,0x2e,0xba,0x4a,0x29,0x20,0x15,0x17,0x19,0x0d,0x25,0xaf,0xa3,0x9c,0x6d,0xa3,0x9a,0xaa,0xa3,0x38 +,0x6b,0x9a,0xab,0xaa,0xbe,0xec,0xa2,0xb5,0xd6,0x3a,0x36,0xbb,0x36,0x1f,0x1c,0x16,0x19,0x1b,0x0e,0x31,0xac,0xa4,0x9f,0x5e,0x9c,0x99,0xa9,0xa8,0x31,0xb9,0x98,0xae +,0xb4,0x41,0x64,0xa7,0xcd,0x5c,0x34,0x43,0xb7,0x31,0x20,0x1e,0x1a,0x1d,0x16,0x0f,0x5d,0xa6,0x9c,0xa5,0xf3,0x9b,0x9e,0xa8,0xb6,0x2a,0xba,0xa1,0xbc,0xc1,0x52,0xb2 +,0xa6,0xc9,0x3d,0x2e,0x58,0xba,0x37,0x21,0x1d,0x18,0x21,0x16,0x19,0xb3,0xae,0x9d,0xb2,0xb7,0x96,0xa4,0xa5,0xeb,0x2c,0xa9,0xac,0xc9,0xdd,0x50,0xa9,0xad,0xc8,0x3d +,0x2f,0xec,0x4f,0x31,0x28,0x1d,0x19,0x1c,0x10,0x28,0xa8,0xab,0x9e,0xce,0xa6,0x97,0xaa,0xa9,0x43,0x42,0x9e,0xab,0xca,0xce,0xf5,0xa8,0xbc,0x40,0x32,0x2f,0xc7,0x44 +,0x28,0x26,0x1a,0x1b,0x1b,0x10,0x6b,0xa4,0xa6,0x9f,0x4d,0x9e,0x99,0xad,0xb1,0x2c,0xcd,0x9c,0xaa,0xe5,0x3a,0x4c,0xba,0xd1,0x5a,0x3a,0x56,0xb9,0x3e,0x2b,0x26,0x1b +,0x1e,0x19,0x12,0xd9,0xaa,0x9e,0x9e,0x5a,0x9e,0x9d,0xaf,0xb1,0x2e,0xc2,0x9f,0xb3,0xbb,0x49,0xe2,0xb0,0x7b,0x46,0x2e,0x3b,0xb3,0x3b,0x27,0x20,0x16,0x22,0x1c,0x17 +,0xb7,0xac,0xa6,0xa8,0xe4,0x99,0x9d,0xab,0xbb,0x30,0xb6,0xa0,0xae,0xcb,0x41,0xca,0xb5,0x60,0x3d,0x2b,0xee,0xb6,0x34,0x25,0x20,0x1a,0x22,0x17,0x1c,0xab,0xaf,0xa1 +,0xaf,0xb8,0x99,0xa3,0xaf,0xc9,0x40,0xa9,0xab,0xb7,0x68,0x42,0xb8,0xa7,0xb9,0x31,0x2c,0x53,0xde,0x2f,0x1f,0x1e,0x1b,0x23,0x19,0x17,0xa9,0xa8,0xa4,0xae,0xdb,0x98 +,0x9b,0xac,0xc0,0x33,0xa8,0xa7,0xfc,0x67,0x3a,0xaf,0xae,0x70,0x4b,0x2e,0xdf,0xd9,0x2b,0x26,0x27,0x1c,0x21,0x17,0x17,0xad,0xad,0xa5,0xac,0xf6,0x9c,0x9e,0xaa,0xba +,0x2c,0xa9,0x9e,0xbb,0x66,0xca,0xba,0xa6,0x45,0x58,0x30,0xdd,0xc8,0x2c,0x1f,0x3c,0x4f,0x24,0x11,0x0f,0x9c,0xaf,0x96,0x2f,0xac,0x18,0x0a,0x13,0x12,0xab,0x23,0x97 +,0x3e,0x2d,0x8e,0x90,0x8f,0x92,0x9a,0xad,0x92,0x8a,0x34,0xb7,0x90,0x0f,0xbc,0x16,0x03,0x87,0x89,0x94,0x97,0xab,0xc1,0xae,0x19,0x0e,0x07,0x09,0x0b,0x0a,0x08,0x07 +,0x0d,0x0d,0x17,0x06,0x1b,0x1b,0x0e,0x1c,0x2f,0x33,0x27,0x39,0x26,0x31,0x93,0x8b,0x8b,0x8e,0x8d,0x84,0x86,0x83,0x8a,0x8c,0x83,0x81,0x83,0x82,0x8b,0x84,0x8d,0x4e +,0xa5,0x94,0x99,0x0e,0x19,0x15,0x08,0x0b,0x03,0x01,0x03,0x04,0x15,0x27,0x08,0x0b,0x02,0x1a,0x13,0x00,0x05,0x0c,0x35,0x19,0x40,0x2c,0x67,0x23,0xc8,0x92,0x99,0x86 +,0x8a,0x97,0x93,0x86,0x8c,0x8e,0x96,0x8d,0x89,0x83,0x88,0x87,0x89,0x89,0x8c,0x99,0x9b,0x42,0x8f,0x9e,0x36,0x1b,0x19,0x1d,0x1c,0x0f,0x07,0x06,0x0c,0x09,0x05,0x0b +,0x04,0x04,0x03,0x02,0x04,0x1a,0x1d,0x1b,0xb7,0x30,0x8f,0x97,0x9e,0x8f,0xa3,0x95,0x8d,0x95,0xa3,0x95,0x95,0x90,0x94,0x8d,0x8a,0x90,0x8a,0x8e,0x9c,0x90,0x8f,0x87 +,0x3d,0xa8,0x8b,0x93,0x89,0x2c,0xde,0x9f,0xaf,0x10,0x04,0x13,0x12,0x16,0x04,0x0b,0x05,0x0e,0x1b,0x03,0x10,0x08,0x0d,0x03,0x05,0x08,0x27,0x12,0x17,0x15,0x0c,0x8b +,0x9b,0x94,0x91,0x8b,0x80,0x89,0x8f,0x8d,0x8a,0x86,0x81,0x8b,0x8e,0x93,0x8c,0x89,0xa4,0xab,0x3d,0xa7,0x33,0x37,0x19,0x18,0x1f,0x10,0x0e,0x06,0xaa,0x4b,0x3e,0x2b +,0x03,0x20,0x33,0x0e,0x0a,0x06,0x09,0x0b,0x23,0x23,0x50,0x25,0x17,0x04,0x18,0xa9,0xe1,0x8e,0xc8,0xb4,0xa3,0xae,0x1e,0x16,0x95,0x81,0x8b,0xa5,0x8e,0x84,0x87,0x9c +,0x45,0xaf,0x8e,0x80,0x81,0x90,0x8b,0x89,0x98,0xae,0x28,0x5d,0x17,0x19,0x16,0x06,0x06,0x04,0x07,0x03,0x06,0x05,0x1f,0x16,0x13,0x3c,0x33,0x19,0x04,0x0c,0x10,0x10 +,0x90,0x92,0xbe,0x92,0xb8,0x9b,0xaf,0xcf,0x9d,0x9a,0xa9,0xae,0x9a,0x8d,0x87,0x36,0x9e,0x9b,0x9d,0x85,0x87,0x87,0x8a,0x23,0x3a,0x35,0xc4,0x8f,0x1f,0xa4,0x8a,0x8c +,0x2e,0x98,0xc3,0x1f,0x0c,0x0e,0x23,0x04,0x2f,0x0e,0x03,0x0e,0x01,0x06,0x02,0x0a,0x9c,0x15,0x20,0x0e,0x19,0xa9,0x48,0x13,0x1f,0xa7,0x9a,0x85,0x88,0x85,0x91,0x9b +,0x24,0x4f,0x96,0x95,0x80,0x8a,0xba,0xa9,0x91,0xbf,0xb4,0x25,0x39,0x80,0x8a,0x8f,0x1a,0x2b,0x88,0x9e,0x08,0x11,0x1f,0x8e,0x9f,0x44,0xb0,0x0e,0x19,0x03,0x07,0x0b +,0x15,0x0a,0x0f,0x39,0x15,0x06,0x08,0x0b,0x08,0x0c,0x8b,0x95,0xab,0x9d,0x0f,0x9e,0x20,0x31,0x8d,0x8e,0x80,0x99,0x8e,0x89,0x82,0x90,0x1e,0x9e,0x1e,0x8c,0x8d,0x91 +,0x8e,0x94,0xa2,0x08,0xb5,0x18,0x19,0x83,0x94,0x8d,0xa1,0x46,0x4b,0x0c,0x13,0x0f,0x3f,0x49,0xa6,0x18,0x0d,0x1e,0x0f,0x05,0x07,0x08,0x09,0x25,0x11,0x1a,0x0d,0x0f +,0x0c,0x1e,0x06,0x3c,0x86,0x85,0x8b,0xbc,0x8e,0x9e,0xa6,0xb3,0x98,0x85,0x81,0x84,0x87,0x8e,0x8e,0x2c,0x5c,0xd3,0x4d,0xac,0x9d,0x96,0xb8,0x0f,0x0d,0x0e,0x21,0x08 +,0x2d,0x88,0x2c,0x99,0x1f,0xc6,0x13,0x0d,0x10,0x19,0xae,0xa7,0x8f,0x14,0x3a,0x38,0x09,0x0a,0x0b,0x1a,0x26,0x32,0x1a,0x1c,0x2a,0x15,0x13,0x09,0x16,0x86,0x8b,0x93 +,0x9c,0xee,0x8d,0xa3,0x30,0x9f,0x93,0x8c,0x80,0x89,0x8a,0x8e,0xa6,0x54,0x97,0x98,0x9c,0x98,0x9e,0x9c,0x25,0x31,0x0d,0x13,0x07,0x0f,0x96,0xd6,0xab,0x11,0x04,0x15 +,0x04,0x0a,0x0c,0x2c,0xaf,0xa6,0x51,0x13,0x37,0x0c,0x0a,0x0c,0xb9,0x3b,0x3a,0x8f,0x45,0xc3,0xce,0x1b,0x3c,0x41,0x9c,0x83,0x87,0x89,0x4b,0x8f,0x97,0x28,0x9c,0xa8 +,0x88,0x84,0x87,0xd3,0xbe,0xa6,0x21,0x2d,0x26,0x5c,0x2f,0x4b,0xcd,0x13,0x12,0x0f,0x0e,0x20,0x0d,0x9b,0x9d,0x3d,0xa1,0x08,0xcb,0x22,0x09,0x14,0x0c,0x8e,0xa1,0xa1 +,0x43,0x1c,0x1a,0x13,0x09,0x1c,0xae,0x3d,0xa7,0x1c,0x59,0x2b,0x17,0x29,0x9e,0x0d,0x88,0x85,0x93,0x91,0xc4,0x88,0xba,0x49,0xc2,0x8e,0x81,0x83,0x8b,0x98,0xa9,0x2c +,0x46,0x27,0x2e,0x95,0xbb,0x2c,0x29,0x08,0x09,0x0e,0x0f,0x12,0x01,0x88,0xea,0x36,0x31,0x00,0x1c,0x15,0x0a,0x1b,0xa4,0x9f,0x8e,0xed,0x1e,0xb6,0x6c,0x2c,0xcd,0x21 +,0x9f,0x9e,0xa2,0x98,0xed,0x9d,0x18,0x2f,0x2b,0xea,0x80,0x89,0x8c,0xa8,0x32,0x9c,0xa0,0x20,0x3e,0x89,0x86,0x94,0x9d,0x2c,0x49,0x0b,0x18,0x17,0x1b,0xbd,0x28,0xb2 +,0x1d,0x0f,0x10,0x0c,0x08,0x16,0x14,0x8c,0x99,0x14,0x14,0x11,0x15,0x0d,0x14,0x2d,0x9f,0x89,0x84,0xbf,0x1d,0xde,0x0f,0xa4,0x1e,0xb2,0x88,0x8b,0x94,0xb6,0xdd,0x3c +,0x9d,0x2e,0x28,0x0e,0x81,0x89,0x8c,0x3c,0x15,0x29,0xe7,0x4a,0x27,0x87,0x90,0x8c,0xa8,0x3f,0x19,0x11,0x0d,0x1f,0x4a,0x47,0xc7,0x1c,0x15,0x1f,0x17,0x06,0x0f,0x14 +,0x12,0x8b,0x85,0xc1,0x0e,0x0e,0x20,0x26,0x11,0x2a,0xa5,0x8e,0x87,0x25,0x17,0x3d,0x0f,0x34,0x20,0xd1,0x84,0x93,0x8a,0xc3,0x2c,0xad,0x3d,0x9f,0xb7,0x24,0x8b,0x81 +,0x8f,0xa4,0x0e,0x4c,0x97,0x16,0x33,0xb6,0x93,0x81,0x40,0x07,0x17,0x0c,0x0a,0x15,0x0f,0x2e,0xf6,0x1e,0x02,0x09,0x53,0x10,0x07,0x25,0x00,0xae,0x80,0x9d,0x9c,0x14 +,0x48,0x9c,0x9d,0x35,0x93,0x83,0x82,0x87,0x12,0x31,0xb1,0x2a,0x9e,0xc6,0x95,0x8d,0x96,0x34,0x17,0x1c,0x34,0x10,0x0d,0x19,0x0d,0x80,0x99,0x2f,0x10,0x04,0xb8,0xbd +,0x0c,0x61,0x9a,0x8d,0x81,0x10,0x0e,0x2c,0x29,0x2c,0x18,0xbe,0x86,0xaa,0x42,0x1e,0x14,0x22,0x10,0x11,0x3b,0x09,0x98,0x83,0xaa,0xe0,0x03,0x1f,0x26,0x45,0x16,0xa8 +,0x88,0x87,0xa5,0x0b,0x2c,0xe8,0xb3,0x2e,0x96,0x8a,0x90,0x95,0xa6,0x2b,0x47,0xb9,0x2f,0x58,0x7e,0xbd,0x83,0x8b,0xc7,0x16,0x0f,0xcd,0x2c,0x0f,0x20,0x9f,0xa4,0xaf +,0x0b,0x13,0x0b,0x26,0x2f,0x11,0x22,0x26,0x9e,0xbd,0x17,0x18,0x2d,0x3d,0xcf,0x24,0x23,0xaa,0x80,0x94,0x98,0x11,0x14,0x9f,0xad,0xb6,0xc6,0x8e,0x8a,0x92,0x29,0x18 +,0x4a,0x9c,0xc7,0x5c,0xb0,0x9e,0xa8,0xf6,0x12,0x41,0x10,0x21,0x13,0x14,0x13,0x4e,0x81,0xad,0x39,0x0c,0x28,0x42,0x30,0x1f,0x9c,0x9b,0x8f,0xd6,0x10,0x1c,0x39,0xa4 +,0x2a,0x4a,0xb6,0xa6,0xb8,0xaa,0x2e,0x2b,0x2a,0x55,0x1b,0x37,0x0a,0xa0,0x80,0xaf,0x9c,0x0a,0x15,0xce,0x19,0x1b,0x9c,0x89,0x89,0xab,0x16,0x22,0xe6,0x57,0xc2,0x4d +,0xa2,0x95,0x9e,0xc3,0x16,0x23,0x14,0x44,0x26,0x24,0x10,0xa8,0x80,0xbc,0xb7,0x0c,0x13,0x37,0x29,0xdb,0x9e,0x9a,0x94,0x95,0x0c,0x19,0x25,0x4d,0xc7,0x3d,0x35,0x9f +,0xa1,0x2c,0x1a,0x1f,0x1b,0x1e,0x1f,0x2f,0x2b,0x5c,0x80,0x9a,0xb3,0x17,0x1b,0xab,0xb8,0x3c,0xa0,0x8e,0x86,0x8c,0x1a,0x1d,0x29,0xb1,0x9f,0xab,0xe9,0xb3,0xb7,0x68 +,0x19,0x29,0x19,0x1f,0x1c,0x25,0x1a,0x32,0x80,0x9b,0xbe,0x11,0x0a,0x30,0xae,0x2f,0xb7,0xa5,0x98,0x88,0x2e,0x14,0x18,0x35,0xa0,0x6b,0x1c,0xac,0x9d,0xc9,0x17,0x19 +,0x22,0x27,0xcc,0x2c,0x1b,0x0f,0x8b,0x8d,0x9e,0x28,0x06,0x27,0xaf,0xc9,0x74,0x9c,0x97,0x8c,0xe6,0x22,0x1e,0xc2,0xb8,0xbb,0x3e,0xcf,0xab,0xb2,0xdb,0x19,0x2d,0x29 +,0xbc,0x19,0x2b,0x0c,0x94,0x85,0xc3,0xbf,0x08,0x26,0xa2,0xf4,0x1e,0xac,0xa0,0x8b,0x96,0x1a,0x22,0x35,0xcc,0x28,0x2f,0xba,0x95,0x9f,0x1f,0x17,0x27,0x4b,0xd1,0x23 +,0x26,0x0a,0x2a,0x81,0x95,0xa4,0x0c,0x0f,0xaf,0xbb,0xf1,0xb6,0xa8,0x8c,0x8a,0x1a,0x1c,0x24,0xa9,0x76,0x1e,0xf4,0xa8,0xa4,0xac,0x22,0x1a,0x2b,0xbc,0x2e,0x20,0x1c +,0x12,0x86,0x8c,0x98,0x20,0x0a,0xc0,0xab,0x4a,0x24,0xa1,0x8d,0x8a,0x4d,0x1b,0x20,0x26,0x63,0x2d,0x54,0x9b,0x97,0xa6,0x1c,0x15,0x1a,0x2f,0xb6,0x1b,0x1b,0x0f,0x98 +,0x84,0x99,0xf0,0x09,0x13,0xa8,0xcf,0x5d,0x94,0x9f,0x8a,0xa9,0x14,0x25,0x2f,0xce,0x3f,0xd2,0x99,0x96,0x55,0x1b,0x17,0x25,0x4f,0xb7,0x1a,0x18,0x0b,0xa6,0x80,0x8f +,0xaf,0x06,0x16,0xb4,0xf3,0x3b,0xcd,0xa9,0x8c,0x96,0x16,0x1a,0x23,0x3d,0xba,0xbc,0xaf,0x9a,0xa7,0x4e,0x14,0x1f,0x29,0xc9,0xda,0x24,0x1f,0x2c,0x83,0x8f,0xae,0x19 +,0x0e,0xbd,0xa2,0x48,0xeb,0xaf,0x8e,0x8b,0x17,0x0f,0x17,0xb1,0xb9,0xb3,0xb6,0xa3,0xdb,0x23,0x11,0x1b,0xbe,0x2e,0x4b,0x1d,0x26,0x1c,0x87,0x8f,0xad,0x24,0x12,0xdd +,0x37,0x39,0x45,0x98,0x95,0x8e,0x1b,0x15,0x2c,0xb8,0x9b,0xad,0x27,0x58,0xb4,0xdb,0x2b,0x1b,0x2f,0x2c,0xd5,0x2d,0x34,0x13,0x90,0x8a,0x9f,0x47,0x0f,0x35,0xce,0x32 +,0x28,0xab,0x9b,0x8b,0x5a,0x1b,0x2f,0x4f,0xad,0xb5,0x2c,0x41,0xb1,0xd6,0x2f,0x1f,0x38,0x3d,0x3b,0x2c,0x28,0x0f,0x8d,0x8c,0xae,0x37,0x0d,0x3c,0xad,0x4d,0x26,0xab +,0x9a,0x89,0xbd,0x1b,0x32,0x43,0xad,0xb0,0x38,0x3d,0xa8,0xaa,0x2c,0x1a,0x2c,0xaf,0x29,0x1c,0x18,0x1c,0x84,0x8c,0xbf,0x15,0x0d,0x47,0xb1,0x1e,0x3c,0xb1,0x94,0x8b +,0x33,0x1c,0x3b,0xd5,0xbc,0x2c,0x1f,0xa2,0xa9,0xba,0x22,0x2b,0x41,0x4c,0x18,0x1e,0x16,0x9c,0x82,0xaa,0x4d,0x0c,0x29,0xd3,0xb9,0x46,0x2c,0xa7,0x88,0x8e,0x28,0x17 +,0x17,0xb5,0xad,0x38,0xc4,0xaf,0x7c,0x2f,0x17,0x24,0xbc,0x1d,0x1f,0x15,0xd8,0x81,0x90,0xe8,0x0e,0x1a,0x50,0xdb,0x4a,0xd5,0x9d,0x8c,0x8c,0x1e,0x1c,0x20,0x56,0xb3 +,0x2f,0x4f,0xab,0x9e,0x2e,0x1c,0x28,0x29,0x18,0x21,0x23,0x24,0x83,0x8d,0xc3,0x1c,0x0d,0x26,0x39,0xba,0xcd,0x9d,0x8a,0x8e,0x27,0x13,0x36,0xd0,0x3b,0x25,0xb9,0xa4 +,0xa4,0x33,0x12,0x2f,0xc5,0x28,0x1a,0x13,0x20,0x85,0x88,0xba,0x1e,0x09,0x24,0xb3,0x5b,0x59,0x97,0x87,0x8f,0x1a,0x0f,0x33,0xbe,0xea,0x1b,0x2d,0xa1,0xa6,0x4b,0x1d +,0x1f,0x3a,0x1a,0x22,0x18,0x39,0x82,0x8d,0xab,0x13,0x0b,0x5a,0xaa,0x3d,0x43,0x96,0x88,0x8b,0x22,0x16,0x25,0xc0,0xad,0x1f,0x4e,0xa9,0xa9,0x59,0x27,0x1b,0x25,0x1b +,0x16,0x13,0x99,0x85,0x98,0x3e,0x0d,0x2d,0x33,0x2f,0x32,0xa2,0x88,0x88,0xa9,0x0f,0x1a,0x37,0xbb,0xa6,0x71,0x2a,0x45,0x38,0x2c,0x26,0xd5,0x1f,0x17,0x13,0x21,0x84 +,0x8f,0x9e,0x1b,0x0b,0xda,0xbe,0xe5,0xab,0x95,0x94,0x98,0x39,0x29,0x53,0xa6,0xc4,0x34,0x43,0xe2,0x70,0x24,0x1f,0x23,0xe0,0x1e,0x2d,0x0d,0xa9,0x87,0xb3,0xe8,0x0d +,0x1e,0xe8,0xaf,0xc4,0xa7,0x98,0x94,0xae,0x1f,0x4d,0xa5,0xa7,0x2c,0x29,0xd0,0xc8,0x3f,0x2b,0x18,0x2f,0x28,0x3f,0x17,0x4a,0x85,0x94,0xb8,0x0d,0x18,0x7b,0xcf,0xba +,0xa3,0x8e,0x8d,0xa1,0x1a,0x3e,0xb4,0xdb,0xc1,0xca,0xb8,0x3d,0x16,0x15,0x13,0xda,0xbc,0x2c,0x0f,0x16,0x86,0x92,0x42,0x0e,0x18,0xa5,0x30,0x2b,0x5d,0x8c,0x8a,0x9a +,0x23,0x24,0x9e,0xb6,0xac,0x55,0x2d,0xe1,0x1e,0x1e,0x1f,0xf4,0xd0,0x2b,0x16,0x11,0x88,0x8e,0xa6,0x26,0x0a,0xcf,0x35,0x41,0xa6,0x8f,0x8d,0x96,0x2d,0x10,0xf4,0xab +,0xa6,0xb0,0xfa,0x4d,0x13,0x13,0x1d,0x2c,0xcd,0x43,0x2a,0x0e,0x99,0x8c,0xa4,0x1a,0x0d,0x3f,0x49,0xb2,0xb5,0x8f,0x8b,0x9a,0x21,0x1b,0x46,0x9f,0x9e,0xab,0xb7,0xc5 +,0x25,0x17,0x21,0x18,0x3c,0x36,0x26,0x27,0x89,0x8b,0xdf,0x14,0x09,0x4d,0xb6,0xac,0xcd,0x9c,0x91,0x95,0x27,0x17,0xfd,0xbe,0xaf,0xc6,0xbb,0xab,0x25,0x19,0x12,0x12 +,0x31,0x1e,0x3c,0x45,0x8a,0x8a,0xe1,0x14,0x07,0x29,0x9f,0x9d,0xbb,0x99,0x91,0x9a,0x39,0x19,0xbe,0x9f,0xa3,0x9f,0xcd,0xc4,0x36,0x10,0x1c,0x14,0x36,0xc0,0x5a,0x1f +,0x54,0x8b,0xa6,0x3a,0x0e,0x11,0x66,0xab,0xa9,0x9c,0x96,0x9b,0xca,0x15,0x18,0xaf,0x90,0x97,0xab,0x2f,0x26,0x11,0x1c,0x1e,0x4a,0xbf,0x25,0x19,0x4d,0x84,0x96,0x4f +,0x0e,0x14,0x68,0xe9,0xb3,0x9b,0x8d,0x8d,0xaa,0x0f,0x0e,0xc5,0x9c,0x9d,0x9a,0x4f,0xb4,0x1a,0x0f,0x0d,0x1d,0xea,0x69,0x2d,0x3f,0x83,0xa3,0x37,0x0c,0x0f,0xbe,0xc7 +,0xaf,0xad,0x8f,0x8d,0xa3,0x18,0x20,0x47,0xab,0xa8,0xaa,0x68,0x9e,0xcb,0x17,0x0b,0x0b,0x36,0xcd,0x3f,0x2d,0x85,0x90,0xc9,0x0e,0x06,0x3e,0xb9,0xaf,0xae,0x8f,0x8a +,0x9a,0x27,0x1d,0x1d,0xcc,0x9e,0x95,0xba,0xd8,0x2c,0x17,0x1d,0x13,0x37,0x18,0x26,0x1d,0x90,0x84,0xaf,0x23,0x09,0x25,0xdf,0xb6,0xbf,0xa0,0x8a,0x8e,0x68,0x10,0x22 +,0xb7,0xac,0x9b,0x9b,0xef,0x41,0x13,0x0e,0x12,0x3a,0xdf,0x2c,0x16,0x18,0x81,0x9b,0x55,0x1b,0x14,0x67,0x2d,0x4d,0xc9,0x8b,0x8b,0x90,0x23,0x1b,0x4e,0xd7,0xad,0xab +,0xbc,0xb3,0xee,0x36,0x11,0x13,0x3b,0x20,0x1f,0x19,0x88,0x8f,0xad,0x2d,0x08,0x2b,0xd6,0xec,0xac,0xa4,0x97,0x8c,0xad,0x1c,0x21,0x4a,0xac,0xae,0x4b,0xb6,0xf0,0x2e +,0x28,0x15,0x20,0x27,0x21,0x12,0x66,0x82,0x9d,0xb1,0x0f,0x0c,0xc8,0xa1,0xa6,0x54,0x9d,0x99,0x8d,0x27,0x27,0x50,0xaa,0xa9,0x3c,0x50,0xf9,0xb9,0x1d,0x23,0x26,0x35 +,0x1b,0x21,0x0d,0x9d,0x81,0x9b,0x4c,0x0a,0x17,0x58,0xa9,0xb9,0xb1,0x99,0x8e,0x9c,0x1b,0x18,0x3a,0xad,0xaf,0xc5,0x28,0xd5,0xb6,0x2a,0x1c,0x1a,0x3b,0x23,0x1c,0x0e +,0x8c,0x86,0x99,0x3b,0x07,0x20,0xa5,0x9f,0x31,0xae,0x96,0x8c,0x97,0x1d,0x1a,0x55,0x3f,0xb6,0x49,0x67,0xa5,0xb6,0x1b,0x1c,0x20,0x58,0x2d,0x1b,0x0a,0xb1,0x82,0x98 +,0xae,0x0b,0x16,0xe6,0xb1,0x33,0xe2,0x98,0x8f,0x8f,0x38,0x1b,0x29,0x39,0xc1,0xf6,0xae,0xc1,0xa1,0x20,0x25,0x36,0x2e,0x28,0x15,0x14,0x1c,0x81,0x8f,0x96,0x19,0x0c +,0x21,0xdf,0xc0,0x2b,0x97,0x8b,0x88,0x62,0x0d,0x15,0xc4,0xc0,0xe5,0x48,0xcd,0xa4,0xab,0x2e,0x17,0x1d,0x1c,0x13,0x24,0x13,0x8e,0x85,0x98,0x4f,0x09,0x26,0x3e,0x40 +,0x2d,0xa0,0x8c,0x86,0x99,0x10,0x13,0x2d,0x2e,0xc1,0x3e,0xad,0x95,0x9d,0x30,0x10,0x1b,0x1c,0x1c,0x23,0x39,0x1b,0x8a,0x86,0xa8,0x1c,0x06,0x1a,0x76,0x65,0xcb,0x95 +,0x8b,0x8a,0xd6,0x0d,0x1c,0xb4,0x57,0xdd,0x5d,0x9e,0x9b,0xb7,0x26,0x1d,0x16,0x18,0x19,0x1b,0x58,0x1f,0x87,0x88,0x4e,0x17,0x07,0x23,0xb7,0x4a,0xa3,0x95,0x91,0x8f +,0x7e,0x14,0x28,0x3b,0x36,0xad,0xb1,0xaa,0xa9,0x5d,0x2c,0x1d,0x1c,0x22,0x2f,0x1b,0x47,0x1c,0x96,0x86,0xaf,0x39,0x09,0x2d,0x48,0xc1,0xd5,0x9e,0x90,0x8f,0xa9,0x14 +,0x21,0x3c,0xa8,0xa9,0x61,0x49,0xaa,0x4a,0x2d,0x1a,0x3d,0x2d,0x2e,0x1a,0x2b,0x21,0x4a,0x83,0xa2,0x62,0x16,0x10,0xbc,0xa7,0x49,0xad,0xa4,0x93,0x98,0x37,0x2b,0xf7 +,0x42,0x30,0x43,0x2a,0xa6,0xa0,0x4c,0x32,0x20,0x3b,0x3c,0x23,0x1c,0x1c,0x0f,0x9a,0x82,0xa4,0xaa,0x0e,0x10,0x5b,0x4a,0xcd,0xb7,0x8f,0x88,0x99,0x18,0x17,0x3d,0x4f +,0xd0,0x2c,0x32,0x97,0x97,0xda,0x19,0x1f,0x23,0x19,0x1f,0x23,0xc4,0x16,0x99,0x88,0xaf,0x52,0x19,0x27,0xaf,0x2e,0x1d,0x9c,0x95,0x8a,0x95,0x23,0x1c,0x1d,0x2a,0xbf +,0xbb,0xad,0x97,0xb7,0x24,0x17,0x20,0x2a,0x39,0xb7,0x19,0x19,0x0c,0x91,0x82,0xac,0x2d,0x0d,0x25,0xa6,0x5c,0x4f,0x96,0x91,0x96,0x3b,0x1a,0x26,0xcd,0xc7,0xc8,0x3e +,0xc0,0x9f,0xdf,0x1f,0x1f,0x30,0x3f,0x50,0x2e,0x18,0x36,0x1a,0xa8,0x88,0xa7,0xb0,0x20,0x2f,0x2a,0x21,0x3d,0x94,0x8e,0x9c,0xc9,0x18,0x2b,0xae,0xba,0x4c,0x36,0xe7 +,0x9f,0xba,0x23,0x2e,0x27,0x4b,0x34,0x34,0x2b,0xd5,0x15,0x1f,0x87,0x93,0xa4,0x15,0x16,0xc2,0xb2,0x2a,0xd7,0x96,0x8f,0x9d,0x1e,0x2f,0x3a,0x2e,0x4c,0x2b,0xad,0x9d +,0xab,0x29,0x18,0x29,0x41,0xba,0x4e,0x27,0x16,0x0f,0x3f,0x86,0x8c,0x9b,0x1b,0x0f,0x28,0x59,0xc5,0x1e,0x1e,0x1c,0x18,0xf7,0xab,0x1b,0x15,0xbe,0x8b,0x87,0x82,0x87 +,0x8e,0x96,0xa2,0xa8,0xac,0xbb,0x13,0x15,0x11,0x05,0x19,0x14,0x01,0x02,0x09,0x52,0x98,0x8e,0x8f,0x8e,0x85,0x84,0x8e,0x9e,0x8c,0x9f,0xb3,0x36,0x1c,0x38,0xb4,0x2e +,0x05,0x01,0x03,0x14,0x5b,0x4e,0x1a,0x2d,0xa8,0x89,0x89,0x9d,0x8d,0xbb,0xdb,0x29,0x14,0xad,0x98,0xbf,0x1a,0x15,0xb8,0x93,0x1b,0x08,0x0f,0x99,0x88,0x9c,0xa8,0x8e +,0x89,0x95,0xa7,0x23,0x48,0xe7,0x1a,0x01,0x19,0x8c,0x92,0xb3,0x08,0x0f,0x2f,0x0b,0x02,0x0f,0x91,0x83,0xa4,0x3a,0xaf,0x9b,0x93,0x9f,0xac,0xae,0x8d,0x8d,0x9c,0x9e +,0xb6,0x6e,0x16,0x09,0x0d,0x1e,0x09,0x0c,0x31,0x29,0x26,0x11,0x30,0xb6,0x26,0xae,0x8d,0x87,0x85,0x96,0xa7,0x5d,0x6c,0x29,0x1e,0xb8,0xa6,0x9e,0x35,0x0c,0x0b,0xc7 +,0xa8,0x15,0x0b,0xa6,0x87,0x8a,0x8a,0x8f,0x96,0xad,0x18,0x1b,0xcc,0xc2,0x36,0x11,0x23,0x30,0x7d,0x12,0x00,0x00,0x0f,0x8c,0x88,0x8d,0x98,0x8f,0x8d,0x96,0xa3,0xa8 +,0xad,0xb6,0xcd,0x18,0x0f,0xad,0x9e,0x0f,0x05,0x09,0xbb,0x53,0x10,0x14,0xad,0x84,0x91,0xbb,0x9a,0x88,0x8d,0x9b,0xb9,0xa7,0x8f,0x8e,0xcc,0x0d,0x0f,0x27,0x33,0x20 +,0x1a,0x16,0x03,0x08,0x2d,0xae,0x98,0x61,0x3c,0xb0,0xa3,0xaa,0x8d,0x84,0x8d,0xa9,0xd2,0x95,0x9b,0xe8,0x2f,0xb7,0x45,0x31,0x1a,0x08,0x0b,0x12,0x24,0x13,0x0d,0x25 +,0x31,0x22,0xa0,0x9b,0x95,0x94,0x9b,0x98,0xd6,0xdd,0x2d,0xba,0x9a,0x91,0x9d,0x2a,0x0f,0x04,0x0e,0x9e,0x90,0x36,0x74,0x94,0x8a,0x8c,0x94,0xc9,0x2d,0xbe,0x2f,0x21 +,0x93,0x93,0xc5,0x25,0x0e,0x23,0xc2,0x1e,0x09,0x1f,0x8b,0x81,0x8f,0x98,0x8e,0x8c,0x9e,0x9e,0xac,0xb6,0x66,0x1b,0x14,0x0a,0x05,0x03,0x02,0x00,0x03,0x00,0x08,0x0a +,0x0a,0x0b,0x07,0x15,0x11,0x22,0xaf,0x9b,0x8e,0xa4,0x1d,0x23,0xe7,0x9f,0xab,0x2c,0xbc,0xa4,0x8b,0x88,0x8b,0x9c,0x28,0x53,0xa0,0x86,0x86,0x88,0x80,0x82,0x8c,0xa9 +,0xa3,0x91,0xa3,0x4b,0x99,0x8a,0x81,0x90,0x34,0x1e,0x41,0xda,0x23,0x31,0x39,0x9b,0xa0,0x34,0x3a,0xaa,0x9c,0xdd,0x21,0x2c,0x18,0x9f,0x84,0x98,0x1e,0x04,0x08,0x0c +,0x08,0x17,0x2e,0xcb,0x15,0x06,0x08,0x19,0x45,0x0f,0x29,0xab,0x8f,0x97,0x24,0x21,0x3e,0x27,0x1c,0x1a,0x25,0x15,0x08,0x1f,0x27,0x1f,0x0d,0x06,0x05,0x06,0x1e,0x95 +,0x84,0x80,0x87,0x8c,0x97,0x99,0x98,0x9e,0x88,0x85,0xa2,0x2b,0x0c,0x27,0xca,0x1c,0x13,0x0d,0x21,0x28,0x94,0x8c,0x97,0x96,0x99,0x94,0x9f,0x9f,0x9d,0x97,0x8c,0x99 +,0xbe,0x41,0x3b,0x17,0x08,0x0d,0xf2,0xa7,0x1b,0x05,0x05,0x13,0x15,0x1b,0xb4,0x9c,0x9f,0x8e,0xa2,0xbe,0xaa,0xa9,0xa8,0xd9,0x9b,0x8e,0x87,0x86,0x8b,0x8f,0x8f,0x98 +,0x9d,0x96,0x8e,0x88,0x8d,0x9a,0x99,0x90,0xb0,0x19,0x0f,0x18,0x16,0xba,0x9c,0x2d,0x0e,0x01,0x02,0x00,0x02,0x05,0x08,0x0f,0x07,0x00,0x02,0x04,0x0c,0x0e,0x10,0x29 +,0x29,0x31,0x19,0x16,0x15,0x0e,0x14,0x1e,0x1d,0x22,0x99,0x97,0xa0,0xe8,0x69,0xd3,0x5b,0x9d,0x88,0x80,0x80,0x80,0x85,0x8a,0x8f,0x8f,0x95,0x8e,0x8a,0x8f,0xa8,0x4e +,0x22,0x17,0x1b,0x2e,0x1e,0x1f,0x8d,0x8b,0x8e,0x90,0x8b,0x86,0x99,0x98,0x8d,0x88,0x87,0x95,0xa4,0xb9,0x20,0x16,0x07,0x0a,0x17,0x15,0x16,0x0e,0x12,0x0b,0x08,0x10 +,0x1d,0x19,0xa8,0x8f,0x9d,0xc9,0x19,0x20,0x13,0x17,0x1f,0x1f,0xae,0x52,0x18,0x1f,0x15,0x14,0x0e,0x0b,0x0f,0x0f,0x14,0x18,0x2f,0x4d,0xe3,0x5d,0x5c,0x2c,0x9a,0x8c +,0x96,0x8f,0x9c,0x9a,0x24,0x11,0x34,0xa1,0x8a,0x98,0xca,0xc8,0x2f,0x47,0xbb,0x9b,0x91,0xb6,0x3d,0xa7,0x9e,0x9b,0x47,0x2f,0xce,0x1a,0xab,0xab,0x3e,0x36,0x11,0x1c +,0x0d,0x0c,0x2a,0x35,0x9f,0xa2,0x9f,0x8a,0x89,0x85,0x88,0x8c,0x85,0x94,0x9f,0x8e,0x90,0x96,0x4d,0x41,0xad,0x9c,0x81,0x8e,0xab,0xa8,0xa7,0x8b,0x9c,0x94,0x86,0x89 +,0x85,0x96,0xeb,0xaa,0x26,0x12,0x0b,0x09,0x0c,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x03,0x02,0x11,0x0e,0x11,0x16,0x10,0x22,0x10,0x1b,0x22,0x2e,0xa3,0x40,0x42,0xb8 +,0x24,0x29,0x2d,0x9d,0x8a,0x95,0x9a,0x9e,0xbe,0xb1,0xa5,0x8a,0x87,0x8a,0x80,0x86,0x88,0x91,0xa3,0x9c,0xad,0x9e,0x8f,0x8d,0x86,0x94,0x9f,0x9e,0xe0,0xdf,0x49,0xb4 +,0xa5,0xa0,0x98,0x9a,0xb6,0xd4,0x1e,0x4c,0xcf,0xa8,0x87,0xa3,0xe2,0x24,0x0d,0x0d,0x04,0x0a,0x24,0x27,0x4a,0x1f,0x1c,0x26,0x12,0x1e,0x33,0xb7,0x99,0xbe,0x3e,0x3c +,0x1f,0x13,0x07,0x0b,0x0a,0x0c,0x2a,0x1d,0x11,0x0c,0x08,0x08,0x04,0x07,0x1d,0x47,0x8f,0x8a,0x92,0x89,0x8f,0x97,0xa0,0x98,0x8f,0xb3,0x2a,0x36,0x25,0x1b,0x15,0x0f +,0x1d,0x1f,0x93,0x93,0xa9,0x93,0x99,0x91,0xa6,0xab,0x8c,0x8b,0x8a,0x8f,0x9e,0x93,0xa7,0x2d,0x1a,0x12,0x25,0x1b,0x0e,0x15,0x15,0x10,0x0d,0x0c,0x17,0x1a,0x94,0x87 +,0x95,0x8e,0x9a,0x8f,0x91,0xb6,0x97,0x8c,0x89,0x85,0x8c,0x8a,0x89,0x97,0x8e,0x98,0x99,0x92,0xb4,0xab,0xa6,0xab,0xb8,0x3a,0x37,0x20,0x13,0xa9,0x2e,0x18,0x20,0x09 +,0x0a,0x01,0x01,0x09,0x07,0x05,0x07,0x01,0x05,0x05,0x05,0x07,0x09,0x18,0x11,0x11,0x25,0x1d,0x24,0x21,0x18,0x28,0x19,0x9f,0x94,0x2e,0xbb,0xe3,0xa9,0xa0,0x3c,0x97 +,0x8c,0x8b,0x84,0x84,0x82,0x80,0x87,0x85,0x88,0x87,0x8b,0xa7,0x98,0xaf,0xde,0x30,0x1b,0x2b,0x34,0x19,0x9e,0x9d,0xc5,0x9e,0x5e,0x91,0x90,0x98,0x89,0x8f,0x8c,0x8a +,0x99,0x96,0xaa,0x29,0x23,0x15,0x0e,0x0d,0x0a,0x0b,0x09,0x09,0x0e,0x0e,0x16,0x14,0x0e,0xa6,0xa2,0xaa,0xa2,0x26,0x37,0x1c,0x1a,0x36,0x1f,0x22,0x23,0x14,0x1c,0x1c +,0x0e,0x18,0x0f,0x0d,0x0f,0x0d,0x1a,0x19,0x1a,0x41,0x33,0x48,0x31,0x1e,0x8f,0x95,0x9f,0x95,0xaa,0x99,0xc8,0x21,0x9c,0xa0,0x9f,0x95,0xac,0x9a,0x9b,0xaa,0x93,0x97 +,0x9e,0xa0,0xad,0x96,0x96,0x9f,0xba,0x3e,0x31,0x33,0x13,0x68,0x4e,0x18,0x3e,0x1f,0x2f,0x1b,0x0c,0x29,0x74,0xc4,0x91,0x93,0x8b,0x8a,0x8d,0x86,0x88,0x8c,0x89,0x90 +,0x8c,0x92,0xb1,0x9b,0xad,0x59,0xa5,0x39,0x3d,0x9a,0xc3,0x97,0x93,0x96,0x8f,0x2d,0x33,0xab,0x25,0x2f,0x20,0x16,0x15,0x08,0x07,0x06,0x01,0x02,0x02,0x02,0x04,0x02 +,0x07,0x06,0x03,0x05,0x09,0x08,0x4c,0x64,0x1f,0xa9,0x38,0xab,0x39,0x1a,0xd6,0x2f,0x79,0x9a,0x9d,0x90,0x95,0x94,0x8c,0x96,0x97,0x8f,0x8a,0x85,0x87,0x8f,0x8f,0x8f +,0x9c,0x9f,0xa9,0xab,0x89,0x92,0x98,0x98,0xa7,0x9a,0xc3,0x6d,0x9e,0xa7,0xa8,0x9a,0xa7,0x96,0x94,0x9b,0x9d,0xa2,0xa6,0xa8,0xae,0x9c,0x9f,0x39,0x1b,0x0e,0x08,0x0d +,0x0d,0x0a,0x26,0x1c,0x1b,0x18,0x0b,0x10,0x10,0x1a,0x3e,0x2a,0xb1,0xa7,0x4f,0xbb,0x3c,0x3c,0x49,0x21,0x0f,0x11,0x15,0x14,0x0d,0x0b,0x0b,0x08,0x06,0x0b,0x0b,0x1c +,0x9c,0xb9,0xaa,0x9f,0xa3,0x99,0xc4,0xad,0x8d,0xa2,0x99,0x97,0xd7,0xa2,0xbf,0xa9,0x99,0xaf,0xaf,0xb6,0xab,0x95,0x9e,0x98,0x98,0xb8,0xaf,0xa1,0xbe,0xb8,0x96,0xb0 +,0x4c,0x3e,0x24,0x1c,0x11,0x1a,0x2f,0x1f,0xeb,0xbe,0x43,0xb6,0xb3,0xa2,0x9b,0x9d,0x96,0x8e,0x8e,0x8b,0x91,0x8f,0x8a,0x91,0x9a,0x9e,0xab,0x9e,0x88,0x8b,0x95,0x8e +,0x97,0xab,0xd3,0x63,0x9c,0xa0,0xad,0xb8,0x2d,0x26,0x16,0x0f,0x0f,0x0e,0x0b,0x08,0x05,0x06,0x05,0x06,0x06,0x03,0x02,0x02,0x04,0x01,0x07,0x11,0x13,0x15,0x17,0x18 +,0x1f,0x1f,0x35,0xc2,0x75,0x98,0x9f,0xac,0x9a,0xad,0xa4,0x9d,0x95,0x92,0x97,0x98,0x96,0x97,0x92,0x90,0x8f,0x93,0x94,0x96,0x95,0x85,0x88,0x8f,0x8e,0x93,0x9c,0xa9 +,0xb4,0x8d,0x9f,0x98,0xa7,0xbe,0xca,0x10,0x1e,0x19,0xd9,0x14,0x21,0xb2,0x1a,0xa5,0x9f,0xb6,0x9c,0xb7,0x1f,0xa6,0x93,0x2c,0xfc,0x8d,0x44,0xa0,0xa4,0x09,0x2f,0xad +,0x6d,0x2c,0xb8,0x2e,0x1d,0xbe,0x11,0x03,0x0a,0x07,0x05,0x05,0x06,0x0f,0x0c,0x10,0x0d,0x13,0x12,0x02,0x0d,0x12,0x15,0xb9,0xa4,0x9a,0x93,0x8c,0x87,0x97,0xa5,0x97 +,0x98,0x8d,0x87,0x86,0x88,0x87,0x87,0x88,0x93,0x96,0x8f,0xa3,0x9e,0x9e,0xc8,0xe5,0x3c,0xd1,0x33,0x25,0x21,0x15,0x27,0x1c,0x1e,0x27,0x15,0x16,0x23,0x11,0x11,0x19 +,0x09,0x08,0x09,0x0c,0x18,0x1f,0x6e,0xc2,0xb3,0xb5,0xa2,0x9f,0xa2,0x91,0x8b,0x8a,0x84,0x88,0x86,0x8f,0x94,0x88,0x93,0x9a,0xa1,0xa0,0x99,0x9e,0xc9,0x9f,0x32,0x36 +,0x43,0x25,0x16,0x10,0x1b,0x1a,0x1e,0x0f,0x0d,0x0b,0x09,0x07,0x0b,0x09,0x06,0x07,0x05,0x0c,0x0d,0x12,0x32,0xa3,0xb0,0x9d,0x9c,0x42,0xbd,0xaa,0x9a,0xbf,0xa5,0xa4 +,0xc4,0xb4,0xa5,0xaf,0xb2,0xa3,0xa5,0x96,0x99,0x91,0x8a,0x88,0x88,0x89,0x8e,0x8e,0x97,0xbc,0xb8,0x9e,0xa0,0xa5,0x97,0xb1,0x19,0x10,0x18,0x0d,0x10,0x19,0x14,0x2c +,0x17,0x1b,0x0c,0x0b,0x08,0x0a,0x17,0x26,0x40,0x1c,0xb2,0xb0,0x95,0x93,0xad,0x9e,0xb7,0x91,0x88,0x96,0x99,0x8a,0x9b,0x9c,0x8d,0x9b,0x97,0xb7,0xa2,0x9c,0xad,0x1f +,0xb6,0xdc,0x54,0xbd,0x36,0x6a,0x1b,0x1e,0x11,0x0f,0x0d,0x11,0x0b,0x0d,0x10,0x16,0xb5,0xd0,0x2b,0xa2,0xb5,0x2d,0x38,0x32,0x32,0xc6,0x2a,0x24,0x41,0x0f,0x0d,0x08 +,0x07,0x0b,0x0d,0x09,0x07,0x14,0x21,0x1c,0x1d,0x4b,0xa2,0xdf,0xa7,0xa7,0x9b,0x82,0x89,0x87,0x86,0x8e,0x88,0x8f,0x91,0x8f,0xa0,0x9d,0x9a,0x96,0xa2,0xa4,0x26,0x48 +,0x2c,0x26,0x3b,0x0f,0xf8,0xe0,0xc3,0xab,0x9c,0xa3,0xa7,0x9f,0x48,0xaf,0x9f,0x5f,0x97,0x96,0xa1,0xae,0xb8,0xa1,0xbf,0x44,0x40,0xae,0x1d,0xc2,0x2f,0x3a,0xae,0x3b +,0x27,0x0f,0x0f,0x0e,0x0b,0x09,0x0d,0x0d,0x12,0x1b,0x45,0x96,0x86,0x92,0x8a,0x84,0x86,0x8b,0x90,0x86,0xa7,0x9c,0x91,0x17,0x17,0x08,0x03,0x06,0x00,0x04,0x01,0x06 +,0x01,0x0c,0x14,0x11,0x0f,0x0e,0x2d,0x1c,0x27,0xbb,0x97,0x98,0x8f,0x88,0x8c,0x8e,0x97,0x8d,0x95,0xa8,0x96,0x88,0x85,0x89,0x8b,0x8a,0x8f,0x9e,0x9b,0x6a,0x9f,0x9b +,0x94,0xa7,0xa6,0xa0,0xab,0xd5,0x0f,0xd1,0x29,0x3a,0xde,0x94,0x40,0x4d,0xae,0x18,0x29,0x1f,0x27,0x18,0x1a,0x23,0x4b,0x26,0x20,0x10,0x1d,0x15,0x1f,0x17,0x04,0x18 +,0x16,0x19,0x23,0x1a,0x25,0xa8,0x94,0x91,0x83,0x86,0x88,0x81,0x81,0x82,0x85,0x81,0x8a,0x8c,0xa6,0xbb,0x3b,0x10,0x0c,0x06,0x0a,0x0a,0x06,0x06,0x03,0x03,0x01,0x05 +,0x06,0x00,0x0d,0x12,0x0a,0x4f,0xbb,0x11,0x2a,0x1b,0x23,0x2b,0x34,0x20,0xad,0x94,0xa6,0x9a,0x91,0x8d,0xb7,0x8f,0xa0,0xa4,0x93,0x96,0x8b,0x93,0x8e,0x8d,0xa5,0x89 +,0x8b,0xa4,0x8f,0x8f,0x92,0x8a,0x87,0x8e,0x8e,0x8f,0x91,0xad,0xa5,0x69,0x4f,0x2b,0x3d,0xab,0x79,0x2b,0x14,0x13,0x09,0x08,0x02,0x07,0x04,0x01,0x12,0x0d,0x16,0x3f +,0x46,0xce,0xa4,0x90,0x9a,0x8e,0x84,0x82,0x88,0x88,0x80,0x86,0x89,0x90,0xb8,0xa8,0x59,0x0c,0x0a,0x0b,0x06,0x08,0x06,0x06,0x04,0x0f,0x0c,0x0a,0x16,0x11,0x21,0xd1 +,0xbd,0xc3,0xb6,0x2f,0xba,0x29,0xf2,0x27,0x13,0x52,0x2f,0x1e,0x63,0xb9,0x29,0x1f,0x12,0x0e,0x0d,0x13,0x0a,0x18,0xc3,0xb3,0xa9,0x91,0xa2,0xb3,0x8c,0x97,0x90,0x8c +,0x8b,0x8b,0x87,0x84,0x86,0x8c,0x8d,0x97,0x92,0x8d,0xc1,0x9d,0x9d,0xaf,0x1f,0x3a,0x35,0x09,0x14,0x1c,0x0f,0x10,0x16,0x14,0x11,0x19,0xc2,0xa7,0x9f,0x94,0xa4,0x8f +,0x84,0x8a,0x85,0x84,0x82,0x84,0x83,0x90,0x9d,0x3c,0x22,0x10,0x03,0x05,0x01,0x09,0x04,0x03,0x0c,0x07,0x01,0x08,0x08,0x0e,0x18,0x1e,0x22,0xec,0xde,0xaa,0xa7,0x56 +,0xaf,0xab,0xa9,0x4b,0xc7,0xba,0xc4,0xa2,0xa4,0xa7,0xb2,0xa3,0x9f,0x43,0xac,0x44,0xce,0x95,0xa4,0x8f,0x9a,0xcb,0xa6,0xc0,0x9a,0xa2,0xa8,0x3b,0x9e,0x92,0xad,0xa2 +,0xad,0xae,0x26,0x1f,0x10,0x15,0x13,0x14,0x45,0x2c,0x33,0x9b,0x33,0x27,0x44,0x15,0x2b,0x25,0xcf,0x34,0x31,0x98,0xa7,0x92,0x91,0x9d,0x88,0x87,0x8c,0x84,0x85,0x85 +,0x85,0x85,0x8c,0x97,0x8f,0xa9,0x2a,0x3c,0x13,0x0a,0x0e,0x04,0x08,0x0b,0x0b,0x05,0x03,0x08,0x09,0x05,0x0d,0x1d,0x09,0x0f,0x21,0x1f,0x15,0x19,0x15,0x0e,0x0f,0x09 +,0x25,0x39,0x3e,0xad,0x92,0xad,0xa1,0x93,0x99,0x8f,0x9a,0x8f,0xa2,0x8a,0x8a,0x8d,0x8c,0x8f,0x90,0x99,0x9e,0x9e,0xa5,0xac,0x90,0x31,0x9d,0x93,0xbf,0x9c,0x32,0xbc +,0x99,0x24,0x27,0xa7,0xc8,0xc5,0x57,0xae,0x23,0x1a,0x24,0x10,0x16,0x17,0x0a,0x1b,0x21,0x0d,0x42,0x1b,0x22,0x2a,0xb6,0xa0,0xa7,0x89,0x8a,0x86,0x80,0x86,0x84,0x87 +,0x8f,0x8b,0xa5,0xa6,0xbf,0x1b,0x5b,0x19,0x0f,0x15,0x06,0x0c,0x0d,0x07,0x05,0x06,0x07,0x0d,0x09,0x10,0x14,0x17,0x38,0x12,0x1e,0x1f,0x1b,0x2c,0x54,0x4c,0x3c,0xab +,0x9a,0x24,0x33,0x9f,0x77,0x33,0xaf,0x6e,0xa4,0x9a,0xaa,0x99,0x9f,0x9b,0x2d,0xa7,0xac,0xa8,0x97,0xb8,0x8e,0x89,0x8e,0x8a,0x94,0x95,0x92,0x9c,0x92,0x9b,0xb2,0x9e +,0xa5,0xb0,0x9c,0x1a,0x2d,0x1b,0x0c,0x0d,0x05,0x07,0x06,0x08,0x0e,0x0a,0x29,0xbf,0x14,0x95,0x94,0x96,0x87,0x85,0x82,0x82,0x81,0x80,0x87,0x8b,0x89,0x9b,0xa5,0x2e +,0x12,0x17,0x0c,0x06,0x05,0x06,0x05,0x00,0x01,0x01,0x00,0x0a,0x06,0x0c,0x1c,0x19,0x2f,0x51,0xbd,0xeb,0x6e,0xa3,0x9d,0xcd,0x9a,0x8e,0x91,0x8c,0x8e,0x96,0x99,0xa6 +,0xa1,0x56,0xba,0xa7,0x31,0xdd,0xbe,0x65,0xb5,0x1d,0x2e,0x9d,0x2f,0xd0,0xa3,0x96,0x96,0x8f,0x91,0x98,0xd3,0x98,0x92,0xb3,0xab,0x74,0xab,0x93,0xe6,0x1f,0x3d,0x1e +,0x1f,0x0e,0x0e,0x07,0x04,0x0d,0x0d,0x0a,0x32,0x4f,0x3e,0x98,0xa9,0x98,0x8b,0x88,0x85,0x85,0x81,0x83,0x82,0x81,0x85,0x8e,0x95,0xad,0x1b,0x18,0x07,0x0b,0x07,0x06 +,0x08,0x01,0x03,0x03,0x01,0x08,0x07,0x06,0x1a,0x17,0x1c,0x32,0xb3,0x2d,0x20,0x66,0x3e,0x1c,0x64,0xb8,0xd0,0xa4,0xb3,0xc3,0xa7,0xeb,0x27,0xc5,0x27,0x47,0x26,0x58 +,0xae,0xec,0x9b,0x9d,0x98,0x90,0x92,0x93,0x95,0x90,0x8c,0x93,0x8b,0x87,0x8c,0x8a,0x91,0xa4,0x97,0xb8,0x42,0xaf,0xc0,0x57,0x28,0x2b,0x40,0x16,0x0b,0x11,0x08,0x0c +,0x16,0x0e,0x1a,0x1a,0x2e,0xad,0xae,0xa2,0xa6,0x98,0x8c,0x8f,0x8b,0x80,0x85,0x85,0x83,0x88,0x8e,0x8f,0x98,0xad,0x26,0x12,0x0f,0x04,0x08,0x0c,0x06,0x08,0x08,0x03 +,0x0b,0x0d,0x0c,0x0f,0x17,0x1f,0x18,0x70,0xcd,0x29,0x44,0x30,0x1b,0x1e,0x1f,0x23,0xbe,0xb4,0xad,0xa2,0x2f,0x2c,0x38,0x1e,0x30,0x2a,0xbd,0x98,0x9e,0x9c,0x8e,0x98 +,0x96,0x93,0x91,0x96,0xa2,0x93,0x91,0x90,0x98,0x94,0x92,0x95,0xa9,0xbc,0xac,0xb4,0xbb,0x4c,0x27,0x2d,0x20,0x1e,0x7a,0x18,0x17,0x23,0x12,0x15,0x18,0x14,0x2b,0x45 +,0xd6,0xad,0xc1,0xa6,0x9c,0x9d,0x96,0x8c,0x87,0x85,0x85,0x84,0x84,0x86,0x8e,0x9f,0xa6,0xe5,0x18,0x0f,0x15,0x0a,0x0b,0x15,0x09,0x04,0x08,0x08,0x0a,0x0d,0x09,0x0f +,0x1c,0x19,0x1d,0x1f,0x1f,0x1b,0x1b,0x2a,0x1d,0x13,0x21,0x35,0x62,0x4a,0x3d,0xb8,0x6c,0x4b,0xa9,0x3e,0x4d,0x9e,0xaa,0x9a,0x90,0x90,0x8f,0x91,0x92,0x9d,0xa0,0x9b +,0x96,0x9a,0x9b,0x96,0x91,0x8b,0x97,0xb8,0xe2,0xbe,0xbf,0xd5,0x44,0x3a,0x68,0x24,0x3e,0x4a,0x1a,0x2b,0x2f,0x15,0x1c,0x1e,0x1a,0x28,0x28,0x2e,0xc1,0xad,0xd0,0xaf +,0x9e,0x99,0x8e,0x88,0x83,0x86,0x84,0x85,0x88,0x8b,0x98,0xa0,0xae,0x29,0x1e,0x21,0x0d,0x0a,0x0d,0x05,0x0c,0xad,0x1e,0x00,0xae,0x94,0x11,0xab,0x1b,0x19,0x0c,0x0b +,0x0c,0x0f,0x14,0x00,0x09,0x01,0x03,0x05,0x00,0x07,0x01,0x04,0x0b,0x0b,0x11,0x0e,0x20,0xb8,0x47,0xa8,0x96,0x9c,0x90,0x88,0x8d,0x99,0x90,0x80,0x83,0x8e,0x89,0x80 +,0x80,0x81,0x82,0x80,0x82,0x82,0x82,0x81,0x81,0x82,0x81,0x86,0x85,0x8d,0x96,0x91,0x91,0x91,0x91,0x91,0xa7,0x9e,0xac,0xa9,0xc4,0x35,0x1e,0x11,0x13,0x08,0x08,0x05 +,0x08,0x05,0x02,0x01,0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00,0x03,0x03,0x04,0x03,0x02,0x05,0x09,0x08,0x05,0x0b,0x06,0x0b,0x09,0x08,0x0d,0x13,0x2a,0x1b,0x28,0xb2 +,0xae,0x9c,0x8f,0x8a,0x85,0x87,0x8d,0x8e,0x8b,0x87,0x85,0x85,0x84,0x82,0x82,0x83,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82 +,0x83,0x82,0x84,0x89,0x8e,0x8c,0x8d,0x93,0x96,0x9f,0xa2,0xc2,0xaf,0x9e,0x9b,0xaa,0x4e,0x39,0x2b,0x1e,0x1b,0x19,0x0d,0x10,0x07,0x04,0x04,0x03,0x03,0x05,0x05,0x02 +,0x04,0x02,0x04,0x04,0x04,0x02,0x02,0x01,0x02,0x03,0x03,0x02,0x04,0x04,0x01,0x02,0x02,0x03,0x04,0x03,0x04,0x04,0x06,0x06,0x09,0x0d,0x0b,0x0a,0x0e,0x15,0x1a,0x1d +,0x15,0x0e,0x0c,0x08,0x08,0x0b,0x0d,0x15,0x16,0x1e,0x26,0x41,0xc9,0xb1,0x8e,0x8a,0x8b,0x87,0x84,0x83,0x82,0x82,0x82,0x82,0x81,0x85,0x85,0x83,0x82,0x82,0x84,0x84 +,0x84,0x82,0x82,0x81,0x82,0x81,0x81,0x84,0x83,0x82,0x81,0x83,0x84,0x86,0x85,0x84,0x88,0x8b,0x8d,0x90,0x95,0xac,0xab,0xa0,0x9f,0xa1,0x3f,0x21,0x1c,0x1c,0x18,0x1a +,0x14,0x18,0x15,0x11,0x1b,0x2d,0xc7,0xb2,0xa8,0xa8,0x95,0x8c,0x86,0x87,0x88,0x86,0x8b,0x89,0x8c,0x91,0x98,0x98,0xaa,0xb3,0xac,0xb1,0xa1,0xa9,0xa9,0xaf,0xc0,0xbe +,0xb4,0x65,0x31,0x1d,0x13,0x0f,0x0c,0x07,0x05,0x04,0x02,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x0a,0x0d,0x0a,0x0c,0x0f,0x11,0x16,0x18,0x19,0x1a,0x20,0x1d,0x21,0x78,0xae,0x9d,0x99,0x90,0x8a,0x8a,0x87,0x82 +,0x81,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x81,0x82,0x82,0x82,0x83,0x88,0x8a,0x89,0x8b,0x8c +,0x8a,0x8e,0x8b,0x85,0x87,0x86,0x85,0x87,0x87,0x85,0x82,0x82,0x83,0x84,0x85,0x86,0x86,0x89,0x8b,0x8f,0x97,0xa9,0x3b,0x26,0x19,0x0f,0x0b,0x07,0x03,0x03,0x02,0x01 +,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x04,0x05,0x03,0x07,0x0b,0x0b,0x12,0x19,0x19 +,0x1c,0x17,0x1d,0x36,0xe4,0xac,0xa1,0x9e,0x95,0x8f,0x8c,0x87,0x85,0x87,0x89,0x8a,0x89,0x88,0x8a,0x8e,0x8d,0x8f,0x99,0x99,0x95,0x99,0x8f,0x8e,0x92,0x8f,0x8e,0x8d +,0x88,0x88,0x8a,0x8d,0x8f,0x91,0x95,0x98,0x9b,0xa1,0xa9,0xd4,0x24,0x20,0x27,0x25,0x1e,0x2d,0x27,0x22,0x4e,0x56,0xb4,0xa8,0xc8,0xdc,0xdf,0xcb,0xdb,0x31,0x33,0x32 +,0x23,0x1a,0x16,0x13,0x18,0x1d,0x1a,0x18,0x18,0x17,0x1a,0x2b,0x2a,0x2b,0x31,0x1e,0x2d,0x4b,0x2b,0x45,0xc9,0xb5,0xad,0xb7,0xa3,0x9b,0x9a,0x97,0x99,0x9c,0x99,0x99 +,0x9a,0x95,0x9d,0xb7,0x39,0x22,0x23,0x25,0x1b,0x1e,0x2d,0x23,0x25,0x4f,0xcd,0xa2,0x96,0x8f,0x8a,0x88,0x84,0x82,0x81,0x81,0x81,0x82,0x82,0x82,0x82,0x82,0x82,0x85 +,0x8a,0x91,0x97,0x97,0xa6,0xe1,0xb7,0x4c,0x24,0x27,0x21,0x1a,0x15,0x0e,0x0c,0x0a,0x08,0x08,0x06,0x05,0x04,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06,0x06,0x0a,0x0e +,0x0b,0x0a,0x0f,0x15,0x16,0x24,0x3c,0x3a,0x44,0x42,0xc5,0xa2,0x9d,0x9b,0x96,0x96,0x95,0x90,0x8d,0x89,0x89,0x8d,0x8e,0x8d,0x8d,0x8d,0x8f,0x8f,0x93,0xa1,0xa7,0x9b +,0x9d,0x9c,0x96,0x9a,0x9b,0x99,0x99,0x94,0x91,0x9b,0xa9,0xaa,0xa8,0xad,0xc2,0x47,0x33,0x24,0x17,0x0f,0x0f,0x11,0x12,0x0f,0x0f,0x0c,0x0b,0x12,0x1a,0x1b,0x1b,0x19 +,0x19,0x1e,0x20,0x25,0x2a,0x23,0x1f,0x1c,0x15,0x18,0x1e,0x23,0x25,0x29,0x22,0x22,0x22,0x28,0x44,0x38,0x2d,0x22,0x22,0x2b,0x3d,0x3b,0x44,0x7a,0x7a,0x50,0xff,0xad +,0xa1,0x9a,0x99,0x96,0x93,0x8f,0x8e,0x8a,0x88,0x8b,0x8e,0x96,0x9b,0xa4,0xb0,0x58,0x27,0x1e,0x12,0x0c,0x0d,0x0e,0x10,0x13,0x1a,0x1f,0x23,0x32,0xb9,0x9d,0x99,0x9b +,0x96,0x8e,0x8b,0x8a,0x8a,0x89,0x89,0x8a,0x8d,0x8c,0x8b,0x8a,0x8a,0x8b,0x8e,0x94,0x95,0x9a,0x96,0x9b,0xaf,0xe5,0x3a,0x21,0x19,0x14,0x0d,0x0a,0x08,0x05,0x04,0x05 +,0x05,0x06,0x06,0x05,0x05,0x05,0x07,0x09,0x0c,0x0c,0x0d,0x0b,0x0a,0x0b,0x0e,0x13,0x17,0x17,0x1a,0x1e,0x2c,0x60,0xaf,0xa5,0x9d,0x97,0x95,0x90,0x8e,0x8a,0x88,0x8b +,0x8d,0x8d,0x8d,0x8e,0x8d,0x8e,0x8f,0x92,0x98,0x9b,0x98,0x95,0x96,0x93,0x8f,0x8f,0x8f,0x90,0x8d,0x8b,0x90,0x97,0x9a,0x9c,0x9e,0xa6,0xb6,0xd9,0x3d,0x1d,0x1b,0x1e +,0x1a,0x1b,0x1a,0x16,0x17,0x16,0x16,0x1b,0x1c,0x18,0x15,0x16,0x18,0x1a,0x18,0x16,0x12,0x0e,0x0d,0x0f,0x16,0x19,0x1b,0x1a,0x1a,0x1a,0x1c,0x2e,0x31,0x29,0x2c,0x2b +,0x2a,0x28,0x2a,0x28,0x21,0x19,0x18,0x1e,0x2c,0x4c,0x64,0xbe,0xaf,0xae,0xa5,0x9a,0x91,0x8e,0x8d,0x8c,0x8c,0x8c,0x8d,0x8e,0x94,0x9a,0xa8,0xbc,0xb8,0xbe,0xdd,0x3c +,0x2a,0x22,0x22,0x1f,0x27,0x2d,0x29,0x2f,0x37,0x3c,0xc6,0xb8,0xb0,0xa6,0xa3,0x9f,0x9d,0x91,0x8b,0x89,0x88,0x88,0x87,0x86,0x86,0x84,0x84,0x86,0x88,0x8c,0x91,0x95 +,0x9e,0xc3,0x2f,0x1d,0x10,0x09,0x09,0x08,0x08,0x07,0x06,0x05,0x05,0x05,0x08,0x0b,0x0a,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0c,0x0f,0x15,0x1b,0x1e +,0x28,0x2f,0x45,0xb7,0x9b,0x97,0x98,0x9a,0x9d,0x99,0x95,0x96,0x95,0x92,0x94,0x99,0x99,0x94,0x93,0x8f,0x8e,0x8e,0x8c,0x8b,0x89,0x86,0x85,0x88,0x8c,0x8e,0x8e,0x93 +,0x9a,0x9a,0x9d,0xa6,0xd8,0x2d,0x2b,0x3f,0x3d,0x30,0x3b,0x36,0x35,0x37,0x42,0xcd,0x3e,0x27,0x27,0x1f,0x21,0x2b,0x1f,0x1d,0x16,0x0f,0x0e,0x0d,0x0d,0x0f,0x13,0x15 +,0x16,0x13,0x14,0x19,0x23,0x2c,0x1f,0x1e,0x23,0x26,0x28,0x22,0x1f,0x1d,0x1b,0x16,0x16,0x1c,0x2c,0x46,0x3b,0x4c,0x52,0xb5,0xad,0xa8,0x96,0x94,0x98,0x99,0x9c,0x97 +,0x96,0x9a,0x98,0x9b,0xa2,0xad,0xae,0xb3,0xac,0xad,0xcc,0x6d,0x3e,0x3a,0x4b,0xf5,0xbc,0x59,0x2e,0x2f,0x2f,0x43,0x38,0x38,0xee,0xbc,0x55,0xce,0x9f,0x95,0x8e,0x8d +,0x8b,0x88,0x87,0x85,0x83,0x83,0x84,0x86,0x86,0x89,0x8e,0x8e,0x96,0xa4,0xc3,0x24,0x1b,0x1a,0x11,0x0e,0x0a,0x0a,0x09,0x07,0x07,0x08,0x09,0x08,0x07,0x05,0x07,0x08 +,0x06,0x08,0x08,0x06,0x06,0x08,0x0b,0x0d,0x0e,0x12,0x18,0x20,0x2a,0x2d,0xad,0xa6,0xac,0x9e,0xa1,0x9b,0x96,0x9a,0x9c,0x9b,0x9a,0x9e,0x98,0x91,0x95,0x91,0x90,0x93 +,0x91,0x8d,0x89,0x8a,0x8b,0x8b,0x8d,0x8d,0x8e,0x8e,0x91,0x95,0x99,0xa6,0xa0,0xa0,0xa2,0xa3,0xa9,0xb9,0xb8,0xb0,0xab,0xa6,0xae,0xc9,0x4a,0x39,0x3a,0x2c,0x27,0x22 +,0x1a,0x10,0x0d,0x11,0x14,0x14,0x14,0x16,0x12,0x14,0x16,0x1d,0x28,0x22,0x1f,0x19,0x1a,0x1d,0x1c,0x1a,0x17,0x16,0x17,0x0e,0x0f,0x18,0x19,0x1b,0x1d,0x24,0x25,0x29 +,0x6a,0xa6,0xad,0xa9,0xa9,0xa7,0xaa,0xa1,0x99,0xa3,0x9a,0x99,0xa0,0xa4,0xa1,0x99,0x99,0x9d,0x99,0x9b,0x9e,0x9c,0x97,0x97,0xa0,0xad,0xc0,0x3a,0x2c,0x2f,0x29,0x24 +,0x1e,0x18,0x18,0x19,0x1e,0x3c,0xbb,0xa6,0x9f,0x96,0x8d,0x88,0x88,0x85,0x86,0x88,0x88,0x88,0x89,0x8b,0x8e,0x96,0xa3,0xc3,0x39,0x23,0x22,0x1b,0x1c,0x16,0x14,0x14 +,0x13,0x16,0x1c,0x13,0x0f,0x18,0x11,0x17,0x14,0x14,0x13,0x11,0x0e,0x0f,0x15,0x14,0x1d,0x1b,0x26,0x27,0x27,0x3f,0x43,0xeb,0xbb,0xc3,0xd6,0xc3,0xcb,0xb9,0xbf,0xc1 +,0xc5,0x54,0x4f,0x42,0x54,0xc1,0xdd,0xdb,0xdd,0xd0,0xb2,0xb3,0xad,0xaa,0xaa,0xab,0xac,0xa7,0xab,0xb5,0xb7,0xab,0xb3,0xbe,0xc4,0xb8,0xb8,0xc0,0xb2,0xb5,0xb4,0xad +,0xa8,0xa9,0xa5,0xa9,0xaa,0xb2,0xb5,0xae,0xac,0xaf,0xbb,0xb6,0xb9,0xbf,0xcf,0xeb,0xc6,0xce,0x7a,0xc8,0xf5,0xec,0x58,0x58,0x5d,0x4f,0x40,0x3d,0x38,0x31,0x3c,0x2e +,0x29,0x26,0x1e,0x25,0x21,0x23,0x28,0x1f,0x25,0x25,0x29,0x29,0x2b,0x2c,0x2e,0x2e,0x30,0x34,0x30,0x2e,0x2e,0x2e,0x2c,0x2d,0x2b,0x30,0x32,0x2f,0x2e,0x2f,0x31,0x2e +,0x34,0x3b,0x4e,0xfe,0x4e,0x44,0xfe,0xcb,0xc2,0xc0,0xbd,0xb7,0xb0,0xaa,0xaf,0xac,0xa4,0xa2,0xa0,0x9b,0x9a,0x99,0x94,0x92,0x92,0x92,0x92,0x91,0x90,0x92,0x92,0x90 +,0x92,0x96,0x98,0x98,0x99,0x9b,0x9d,0xa3,0xa5,0xa2,0xaf,0xc3,0xc8,0x56,0x43,0x2f,0x26,0x2d,0x2b,0x20,0x1c,0x19,0x1b,0x1a,0x15,0x16,0x19,0x1a,0x1b,0x1a,0x19,0x1d +,0x1e,0x1d,0x1e,0x1e,0x1f,0x21,0x26,0x20,0x20,0x21,0x1e,0x1f,0x1e,0x22,0x29,0x2c,0x28,0x27,0x28,0x29,0x27,0x29,0x2f,0x33,0x3e,0x3d,0x3c,0x3f,0x4a,0xfa,0xf9,0xd7 +,0xc5,0xb7,0xae,0xae,0xa7,0xa1,0x9f,0xa0,0xa0,0x9e,0x9a,0x9a,0x99,0x97,0x96,0x94,0x97,0x99,0x98,0x98,0x97,0x98,0x98,0x98,0x99,0x99,0x9a,0x9c,0x9e,0xa2,0xa3,0xa4 +,0xac,0xb2,0xb9,0xca,0x4c,0x38,0x2f,0x27,0x22,0x20,0x1e,0x1c,0x1b,0x1a,0x1a,0x1a,0x18,0x19,0x19,0x19,0x1a,0x1b,0x1b,0x1b,0x1d,0x1c,0x1c,0x1d,0x1d,0x1e,0x1e,0x1d +,0x20,0x23,0x23,0x29,0x26,0x27,0x2c,0x2d,0x2f,0x2f,0x2f,0x36,0x3c,0x3f,0x4e,0x44,0x65,0xcc,0xd2,0xb6,0xaf,0xaa,0xa6,0xa5,0x9f,0x9f,0x9e,0x9d,0x9d,0x9b,0x99,0x98 +,0x97,0x98,0x99,0x97,0x96,0x98,0x99,0x9a,0x99,0x9a,0x9a,0x9a,0x9d,0x9d,0x9f,0xa1,0xa4,0xa8,0xab,0xab,0xb3,0xbf,0xc5,0x62,0x42,0x3a,0x34,0x39,0x34,0x2e,0x2c,0x26 +,0x29,0x2a,0x24,0x23,0x24,0x21,0x1f,0x1f,0x22,0x25,0x25,0x23,0x24,0x26,0x24,0x2a,0x27,0x2b,0x2c,0x2c,0x2e,0x2b,0x2b,0x2a,0x31,0x31,0x2f,0x33,0x36,0x2f,0x37,0x37 +,0x3a,0x3d,0x39,0x3b,0x35,0x5b,0xd9,0x4d,0x6c,0x5e,0x5a,0xdb,0x5e,0x62,0xd8,0xc3,0xbe,0xc3,0xc6,0xb8,0xb4,0xb7,0xb4,0xaa,0xa7,0xa3,0xa7,0xa6,0xa1,0xa9,0xa3,0xa9 +,0xae,0xaa,0xab,0xa8,0xab,0xb1,0xae,0xb5,0xb4,0xbc,0xc5,0xbc,0xdb,0xc6,0xe2,0x5e,0x59,0x54,0x55,0x3d,0x3d,0x42,0x46,0x3c,0x41,0x3c,0x30,0x2e,0x2f,0x2c,0x2c,0x2e +,0x32,0x3c,0x2f,0x2c,0x2e,0x2d,0x31,0x2a,0x2b,0x39,0x2e,0x30,0x2c,0x30,0x3a,0x35,0x40,0x46,0x47,0x4c,0x4c,0x4a,0x54,0x7b,0x46,0x41,0x44,0x41,0x7a,0x50,0xfa,0xd2 +,0xe8,0xeb,0xdf,0x77,0xc7,0xc6,0xbf,0xb1,0xb4,0xb7,0xb8,0xb7,0xaf,0xab,0xb2,0xab,0xa5,0xa8,0xae,0xa8,0xa6,0xae,0xaa,0xaf,0xb2,0xad,0xac,0xaa,0xaf,0xb9,0xba,0xbd +,0x6d,0x4c,0xd2,0xd9,0x38,0x57,0x56,0x3b,0x3d,0x39,0xdc,0x4b,0x62,0xcf,0x47,0xc6,0xc9,0x40,0xd3,0x49,0x4a,0xf1,0x38,0x4f,0x5d,0x4c,0xd9,0x3a,0x39,0x59,0x31,0x3e +,0x38,0x3b,0x6c,0x3f,0x3d,0x5a,0x52,0x39,0x58,0xc7,0x45,0x52,0xc8,0x48,0xc4,0xcd,0x44,0xe9,0x42,0x77,0x6b,0x3a,0xae,0xf5,0x58,0xc2,0x33,0xdf,0x3c,0x5d,0x4f,0x55 +,0xb0,0x58,0x66,0xaf,0xe8,0x59,0xb0,0xc7,0xb1,0xaf,0xb9,0xc3,0xbd,0xb3,0xcf,0xcc,0xb9,0xb9,0x6c,0xc9,0xc4,0xe6,0xfa,0xfd,0x5a,0x33,0xf5,0x3a,0x4d,0xe1,0x38,0xbf +,0x37,0x31,0x4a,0x33,0x3f,0x39,0x4f,0xf9,0x3e,0xf7,0x2f,0x40,0xc5,0x4a,0x3e,0xcf,0x4b,0x47,0xcf,0x31,0x45,0x37,0x50,0x35,0x24,0x62,0x3e,0x47,0x4f,0x40,0xc6,0x35 +,0x62,0xfc,0x38,0xca,0xfb,0xbb,0xbe,0x43,0xb2,0x40,0xcc,0xb8,0x36,0xac,0x5e,0xdb,0xbe,0x4b,0xc4,0x4b,0xd6,0xb6,0x3c,0xb7,0xda,0xca,0xbb,0xbc,0xa9,0x49,0xd1,0xb6 +,0x78,0x7c,0xc3,0xc6,0xc7,0xcc,0xb6,0x52,0xb8,0xd5,0xdb,0xb2,0x42,0xb1,0x62,0xea,0xcd,0x3e,0xd5,0x38,0xc4,0x3f,0x47,0xb6,0x3a,0xbb,0xdb,0x59,0xbc,0x3b,0xbd,0x47 +,0x40,0xb0,0x4f,0xba,0x52,0xd4,0xba,0x41,0xca,0xc6,0x50,0xfd,0xc9,0x42,0xd3,0x52,0x3a,0xc3,0x34,0x3c,0xc9,0x2d,0xce,0x40,0x51,0xd6,0x27,0xcf,0x38,0x3b,0xe2,0x3e +,0x70,0x49,0x44,0xd9,0x62,0x58,0x46,0x46,0xb6,0x44,0x49,0xdf,0x36,0x5d,0x37,0x42,0x32,0xdf,0xb6,0x36,0xbe,0x58,0xc5,0xba,0x62,0xb3,0x5d,0xd5,0xb7,0x66,0xc5,0x56 +,0xbf,0xbd,0x78,0x55,0xd3,0xbb,0xe6,0xc1,0x50,0x49,0xbf,0x59,0x32,0xb7,0xbb,0x6b,0xba,0x7e,0xca,0xc8,0x34,0x50,0xb6,0xee,0x5b,0x3c,0xca,0xbd,0x2e,0x5a,0x57,0xbe +,0x3f,0x5c,0x55,0x43,0xb9,0x3d,0x3b,0x47,0x53,0x3b,0x35,0x46,0xc0,0x3c,0x4e,0x3e,0x4d,0x6c,0x36,0xc4,0x49,0x44,0xc8,0x4d,0x5d,0xf9,0x3d,0x45,0xf5,0xe5,0x3b,0xc3 +,0x50,0xe1,0x5f,0x36,0xc0,0x31,0xa6,0x2f,0x55,0xac,0x3c,0xbb,0x39,0xaf,0x44,0xfa,0xa8,0x3b,0xb8,0xba,0xbd,0xb0,0x4c,0xb0,0x46,0xbf,0xb7,0xc4,0x67,0xc3,0xc8,0xbf +,0xd5,0x47,0xb1,0xc9,0xc0,0x44,0xc9,0xbe,0xbc,0x41,0xb0,0xbf,0xc0,0xb7,0xd2,0xaa,0x3d,0xae,0xd8,0x4f,0xd3,0x39,0x3f,0xb3,0x4b,0x2c,0xc2,0x41,0x44,0x44,0x2d,0xba +,0xee,0x30,0xb4,0x28,0xc0,0x3e,0x28,0xb7,0x33,0x4b,0x62,0x4a,0xc8,0x2b,0xdf,0x3e,0x3f,0x31,0xd2,0xcf,0x36,0xcf,0x2c,0xb1,0x39,0x39,0x36,0x4a,0x48,0xdd,0x36,0xca +,0x60,0x49,0xce,0x3c,0x68,0x65,0xce,0xba,0xd8,0xaf,0xb9,0x3b,0xb1,0x40,0xba,0xca,0x51,0xb9,0xc1,0x40,0xc2,0x2e,0xc8,0x3e,0xe8,0xbb,0x2f,0xa5,0x43,0xbe,0xbe,0x46 +,0xba,0x73,0x47,0xc8,0xab,0x3a,0xce,0xa6,0x33,0xbe,0x58,0x43,0xba,0x34,0x53,0xcb,0x36,0xc4,0x3a,0x2f,0x43,0x3d,0x46,0x4b,0x5a,0x45,0xbd,0x2b,0x6d,0xd3,0x4a,0x4a +,0xbd,0x4a,0xe8,0x54,0x45,0xaa,0x3a,0xc7,0x31,0x43,0xc3,0x2e,0x32,0xb3,0x2a,0xac,0x41,0x21,0x9f,0x3f,0x44,0xbe,0xce,0x4c,0xac,0x5d,0xcf,0xb1,0xd8,0xbe,0xba,0x54 +,0xc6,0xbe,0x41,0xae,0xd1,0xdc,0xbb,0xf6,0xb8,0x46,0xd7,0xae,0x78,0xb8,0x51,0xbd,0xbf,0x3c,0xcb,0xdf,0xcf,0xcb,0xbf,0x52,0x48,0xb4,0xc3,0x36,0x5b,0xb5,0xd3,0x4a +,0xaf,0x53,0xcf,0xc4,0x36,0xe1,0x2b,0xe3,0x55,0x47,0x33,0xdc,0xc0,0x30,0x41,0x30,0xd0,0x30,0xe0,0xdc,0x2f,0xb8,0x74,0x47,0xf9,0x36,0xb8,0x3f,0x54,0xdd,0xfe,0xd9 +,0x29,0xc1,0x40,0x63,0xd4,0x37,0xbc,0xc8,0x32,0xd6,0xbf,0xca,0x5c,0x38,0xb7,0xbd,0x38,0xb2,0xb9,0x5b,0xae,0x4f,0xd9,0xaf,0x31,0xb1,0x44,0xea,0xac,0x2b,0xc9,0x50 +,0xcc,0xd4,0x4b,0xb9,0x4f,0x6f,0xd6,0xc0,0xb5,0x48,0xb9,0x33,0xbf,0xbf,0x41,0xc7,0xd7,0xc2,0xed,0x25,0xc7,0x62,0x2c,0xaf,0x38,0xc6,0x3f,0xce,0x46,0x50,0xdf,0x46 +,0x38,0xb0,0xd4,0x3c,0x46,0xbb,0xce,0x34,0xbc,0x49,0xd9,0x3f,0xeb,0x52,0xe3,0x47,0xbe,0x25,0xcc,0x47,0xd5,0xad,0x2b,0xcf,0x39,0x5b,0xa7,0x2f,0x3d,0xb3,0x36,0xdb +,0x43,0xab,0x3c,0xc6,0xf1,0xaf,0xba,0x35,0xbd,0xc0,0x54,0xd3,0xac,0x30,0xab,0x29,0x31,0xab,0x31,0xbf,0x3f,0xef,0xb8,0x42,0xc0,0x3d,0x50,0xf0,0x4a,0xb1,0xc2,0xce +,0xd2,0x50,0xb6,0xaf,0x4e,0x45,0xa9,0xe7,0x4d,0x47,0x25,0x38,0xa4,0xa3,0xaf,0x13,0x0f,0xc2,0x9e,0x9f,0xad,0xa7,0xb8,0xa5,0x0d,0x10,0x0d,0x1f,0x93,0x8e,0x98,0x13 +,0x05,0x0d,0x8e,0x83,0xa4,0x10,0x2e,0xa2,0x89,0x96,0x9e,0xaf,0x19,0x1b,0x36,0x3f,0x5b,0x2e,0x12,0x36,0x25,0x15,0x03,0x1d,0x8a,0x86,0x89,0x42,0x31,0x24,0x1f,0x89 +,0x8f,0xae,0x2f,0x0f,0x3e,0x9f,0x97,0xc3,0x1e,0x28,0x1f,0x19,0x37,0x9f,0x90,0x39,0x2e,0x34,0x18,0x15,0x09,0xac,0x89,0x86,0xa7,0x0c,0x25,0xb9,0x9a,0x94,0x30,0x1b +,0x15,0x2f,0x94,0x92,0x9b,0x26,0x08,0x1c,0x96,0xaa,0xc7,0xa0,0x9b,0xb1,0x22,0x1a,0x0f,0x09,0x79,0x8e,0x8c,0x33,0x07,0x0a,0x26,0x82,0x8f,0x1f,0x22,0xbf,0x8f,0x95 +,0x97,0x97,0x17,0x29,0x38,0x3b,0xb6,0x13,0x24,0x3b,0xc2,0x1f,0x05,0x09,0xb5,0x8b,0x89,0x95,0x37,0x16,0x29,0x9f,0x8a,0x98,0x56,0x16,0x27,0x93,0x97,0x3e,0x1c,0xad +,0x2d,0x1c,0x19,0xca,0xac,0x9d,0xbb,0xd0,0x25,0x0a,0x0b,0x1e,0x8d,0x88,0x8f,0x2d,0x1c,0x2a,0x56,0x9d,0xa1,0x2a,0x1c,0x21,0xad,0x92,0x9c,0xbf,0x17,0x2c,0xb0,0x4e +,0xcc,0xbf,0x8c,0xa2,0xd4,0x19,0x0a,0x12,0x0e,0x95,0x91,0xa7,0x18,0x05,0x23,0x9d,0x89,0xa6,0x26,0xd2,0xaf,0x90,0x99,0x9f,0xaf,0x29,0x5c,0x4d,0x4e,0x1e,0x10,0xdc +,0xa3,0xbd,0x0a,0x06,0x1f,0xab,0x8c,0x8f,0xa4,0x3b,0x18,0x4a,0x90,0x9a,0x9c,0x11,0x11,0xa0,0x99,0xa7,0x2c,0xc7,0xbc,0x2c,0x1c,0x28,0x3c,0xb5,0x9e,0xa2,0xdf,0x11 +,0x07,0x15,0xa7,0x8d,0x91,0xa1,0x45,0x28,0xb4,0xcb,0xb7,0xba,0x2d,0x1e,0x1f,0x9f,0x98,0x4a,0xc8,0x2a,0xba,0xbc,0x15,0x9e,0x9f,0x8e,0xa7,0x23,0x26,0x06,0x18,0x1e +,0x9d,0x8e,0x21,0x1a,0x0d,0xc6,0x9c,0xab,0x99,0x35,0xad,0x6d,0x9e,0x8f,0xaf,0x9b,0xcc,0x41,0x5d,0x1a,0x19,0x24,0x9e,0xaa,0x34,0x0d,0x09,0x2d,0xb6,0x99,0x95,0xc5 +,0xf1,0x28,0xca,0x95,0xac,0xe0,0x17,0x66,0xa0,0xbc,0x3a,0xab,0xaf,0xa7,0x24,0x1a,0x1f,0x33,0x9f,0x9c,0x92,0x1b,0x11,0x0c,0x14,0x97,0x95,0x9d,0x9f,0xe8,0xa5,0x1e +,0x3a,0xcb,0x3c,0xc6,0x1c,0xb3,0xb9,0x57,0xec,0x9e,0xa8,0x37,0x29,0x29,0xb1,0x93,0x94,0xa7,0x1f,0x1a,0x0a,0x11,0xb8,0xba,0xa6,0x28,0x25,0x20,0x7a,0xab,0xb1,0x9c +,0xae,0x4e,0xb8,0xba,0x9c,0xa3,0x9d,0x99,0x2b,0x2a,0x14,0x12,0xad,0x99,0xb1,0x1e,0x0e,0x14,0x23,0xae,0x9c,0xa5,0xc9,0xbd,0xcb,0xca,0xa6,0x39,0x2c,0xb2,0xb1,0xb7 +,0x3e,0xb0,0xa4,0xc5,0xa5,0x26,0x1b,0x19,0x36,0x90,0x99,0xa5,0x17,0x0b,0x1d,0x24,0xa2,0xa0,0xa6,0x9e,0xb5,0xa2,0x1e,0x23,0x4b,0x25,0xaa,0x35,0x3d,0x3c,0x2a,0x9c +,0x97,0xb1,0x34,0x22,0x4f,0xbd,0x9a,0x8e,0xb7,0x1d,0x1d,0x14,0x1a,0x40,0x5b,0x41,0x48,0xb7,0xca,0xe2,0x26,0x9a,0xa5,0xb3,0xd7,0x38,0xaa,0xb0,0x96,0x9e,0xbc,0x2b +,0x12,0x16,0x2d,0xaf,0xa8,0xba,0x2a,0x16,0x17,0x28,0x9e,0x64,0x9d,0xa2,0xdb,0xa7,0xd6,0x3e,0x27,0xa8,0xaa,0x3b,0xe1,0xfa,0xaa,0xaf,0xa7,0x4f,0x21,0x1a,0x1f,0xc9 +,0x9f,0x9b,0x49,0x24,0x0e,0x2b,0x2e,0xba,0x98,0xa9,0x98,0xa8,0xcf,0x33,0x1e,0x33,0x2f,0xcf,0xba,0x1b,0x41,0xf9,0x9b,0x96,0x2a,0xba,0x23,0xba,0x9d,0xc5,0x96,0xb9 +,0x2f,0x14,0x15,0x2e,0x22,0x2d,0x3b,0xb6,0xb3,0x3c,0xc3,0x61,0x9f,0xab,0xae,0xac,0x34,0xca,0xa8,0x9a,0xa1,0xe2,0x2b,0x18,0x1d,0x35,0xb2,0x5e,0x3a,0xdf,0x19,0x23 +,0x2b,0xb8,0xb6,0xdd,0x9a,0xc8,0xa8,0x4b,0x26,0xa0,0x46,0xa4,0x62,0x38,0xab,0x41,0xa6,0xab,0x39,0x27,0x18,0x2a,0xcb,0xaf,0xa2,0x20,0x31,0x2e,0x2d,0x54,0x45,0x9a +,0xa0,0xa9,0x9c,0x4b,0x3e,0x1f,0x30,0x47,0x2e,0x50,0x13,0xe9,0xb0,0xa4,0x97,0xbd,0xbe,0x6f,0x3a,0x9d,0xb7,0xab,0xcc,0x29,0x35,0x1e,0x1f,0x13,0x26,0x44,0xbc,0xb7 +,0xb3,0x73,0xaa,0x9f,0xa5,0xbb,0x3f,0xd4,0x77,0xa9,0x9e,0x9f,0x38,0x23,0x34,0x1c,0x40,0x33,0x43,0x59,0x2f,0x38,0x29,0x3b,0x2c,0xcc,0xbb,0x96,0xbf,0x3c,0xa1,0xd4 +,0xc0,0xa0,0x52,0x55,0xd9,0xcf,0xab,0x47,0xcb,0x30,0x1d,0x2b,0x32,0xcc,0xb2,0x29,0x4f,0xc9,0x25,0x4f,0x43,0xb0,0x9e,0xc4,0x98,0x6e,0x74,0x4d,0x2d,0xdf,0x26,0x2c +,0x2a,0x1e,0xc8,0xa3,0xa4,0x9f,0xf3,0xab,0xc5,0xb8,0xb1,0xb4,0xa7,0x2e,0x43,0x37,0x14,0x26,0x10,0x36,0xc2,0x1b,0x9c,0x3b,0xa3,0x9e,0x53,0x9b,0x2f,0xcd,0xbf,0x3d +,0x94,0xb0,0xee,0xb0,0x1a,0x3d,0x3d,0x2b,0xb2,0x36,0xbd,0x3e,0x25,0x38,0x20,0xd0,0x39,0xae,0x9f,0x2d,0xaf,0xcf,0xc7,0x9f,0x3f,0xa9,0xbf,0xe9,0xab,0x2d,0xa3,0x33 +,0x27,0x3c,0x2d,0x3a,0x31,0xd6,0x48,0x41,0xc4,0x2f,0x4b,0x6c,0xd6,0xa1,0xb2,0xa0,0x7d,0xcd,0x38,0x59,0xe8,0x22,0x2d,0x27,0x29,0xb5,0xca,0xbd,0x9b,0xb1,0xad,0xc6 +,0xbe,0xb1,0x4a,0xaf,0xc0,0x36,0x3b,0x15,0x1f,0x20,0x1e,0x3a,0x4b,0xab,0x4a,0xaa,0x9b,0xcb,0xa5,0xed,0xc7,0xa9,0x78,0xaf,0xad,0x33,0xae,0x54,0x2a,0x4f,0x25,0xb1 +,0x3e,0x4c,0x31,0x33,0x3a,0x1c,0xc2,0x56,0x3d,0xa6,0x3e,0xbd,0xb5,0xee,0x9f,0xbf,0xa2,0xb1,0x3b,0x9d,0x26,0x49,0xeb,0x21,0xad,0x1a,0x31,0xe7,0x2a,0xd4,0x3d,0xd6 +,0x2d,0xe7,0xaf,0x24,0x97,0xb3,0xb0,0xa4,0x2c,0xaf,0x42,0x37,0x48,0x37,0x38,0x3e,0x67,0xb5,0x2f,0x9d,0xae,0xdd,0xa4,0x36,0xaf,0xc5,0xd9,0xb7,0x2a,0x28,0x1c,0x1c +,0x29,0x23,0x3c,0x7a,0xa8,0x4c,0x9c,0xad,0xb9,0x9f,0xe7,0xab,0xb0,0xbc,0x4a,0xc4,0x3f,0xae,0x21,0x43,0xbb,0x21,0x5f,0xcc,0x38,0x26,0x2e,0x34,0x41,0x35,0x5a,0x48 +,0xaf,0x49,0xb2,0xae,0xaf,0x9f,0xd1,0x9e,0xb2,0xb7,0xd2,0x37,0x3e,0x33,0x48,0x2f,0x2b,0x22,0xbf,0x28,0x54,0xd1,0x24,0xb8,0x43,0xbe,0xb5,0xab,0xbc,0x68,0xa5,0x5b +,0x52,0x78,0x30,0x4f,0x26,0x5d,0xf3,0x52,0xc3,0xac,0xac,0xad,0xb1,0xaf,0xcc,0xc8,0xb9,0x33,0xb0,0x24,0x1f,0x21,0x27,0x26,0x1c,0xe6,0x40,0x52,0xa5,0xae,0xb7,0xa8 +,0xaa,0xaf,0xad,0xa1,0xcb,0xc7,0xc5,0x64,0xbd,0x7a,0x3c,0x47,0x28,0x43,0xce,0x1d,0x40,0x20,0x28,0x45,0x22,0xb5,0x37,0x39,0xa8,0xbc,0x9e,0xca,0xa0,0xa0,0xbd,0x9d +,0xd4,0xb9,0xe8,0x5a,0x48,0x28,0x2d,0x31,0x1f,0x2d,0x2e,0x6c,0x54,0xe7,0x57,0x68,0xb0,0x39,0xa9,0xd2,0xbd,0xa8,0x37,0xbb,0x5f,0x1f,0x43,0x2b,0x45,0xff,0xcb,0xa0 +,0xde,0xad,0xa7,0xca,0xad,0xb2,0xbd,0xbc,0x5e,0xde,0x2e,0x24,0x1e,0x1a,0x1f,0x36,0x3a,0x36,0xcb,0xb0,0xbb,0xb6,0xa1,0xb2,0xa8,0x7a,0xab,0xa1,0xf0,0xbf,0xf8,0xbb +,0xbf,0xf7,0x21,0xb7,0x2d,0x28,0x74,0x2f,0x4e,0x1d,0x2f,0x2e,0x4b,0x43,0x4b,0xbc,0xbf,0xad,0xa0,0xb9,0xa0,0xaa,0xd0,0xa3,0x65,0xbf,0x3b,0x49,0x46,0x26,0x36,0x2b +,0x32,0x34,0x2d,0xc8,0x39,0xef,0xb9,0x74,0xb4,0xc5,0xb6,0xb1,0xd7,0xda,0x32,0xfd,0x5c,0x25,0x44,0x28,0xcd,0xbe,0x62,0xa9,0xaf,0xce,0xaa,0xaa,0xb0,0xb1,0x40,0xad +,0x36,0x2c,0x3c,0x24,0x28,0x21,0x4c,0x3b,0x2f,0x4e,0x54,0xdc,0xb9,0xad,0xae,0xbf,0xc4,0xac,0xc1,0xb0,0xb4,0xca,0xba,0xbc,0xed,0xc2,0xd7,0x28,0x5c,0x34,0x2f,0x30 +,0x26,0x2f,0x2f,0x2c,0x42,0x3e,0xc8,0xca,0xb5,0xa1,0xcd,0xa0,0xab,0xbe,0xa8,0xcc,0xb8,0xcb,0x28,0x3d,0x2e,0x2f,0x3a,0x29,0x54,0x4b,0x36,0xbb,0xc7,0xd1,0xc3,0xb1 +,0xbe,0xc2,0xba,0xdf,0xe3,0x26,0xe0,0x34,0x27,0x39,0x3b,0x67,0xce,0xbb,0xb9,0xb4,0xd2,0xb1,0xa8,0xa8,0xaf,0xb7,0x63,0x46,0x4a,0x31,0x3c,0x2f,0x29,0x3c,0x31,0x2c +,0x64,0xe1,0xc3,0x5b,0xf8,0xa9,0x3c,0x4b,0xa8,0xce,0xab,0xb7,0xca,0xaf,0x53,0xbe,0xbc,0x66,0xca,0x2e,0x42,0x37,0x26,0x4b,0x1f,0x3f,0x30,0x38,0x3b,0x42,0xa7,0xbb +,0xad,0xac,0xb0,0xb0,0xd6,0xd9,0xaa,0xd4,0x54,0x7b,0x28,0x26,0x42,0x48,0xbd,0x47,0x4d,0xcc,0xdb,0xd1,0xb2,0xcc,0xc1,0xb3,0x4d,0x54,0xc6,0x48,0x3a,0xc7,0x26,0x4b +,0x2b,0x35,0x4e,0xee,0xb6,0xb2,0xb1,0xd6,0xb9,0xb1,0xba,0xc5,0xb4,0x5c,0xb6,0x31,0x3a,0x76,0x23,0x35,0x3d,0x38,0x43,0x4a,0x5c,0x46,0x3d,0xbf,0xc7,0xda,0xdc,0xdf +,0xac,0xc4,0xaa,0xb0,0xd5,0xb8,0xc7,0xee,0xd1,0xd3,0x34,0x35,0x27,0x58,0x2a,0x3a,0xfa,0x22,0xc9,0x5a,0xc4,0xb9,0xc6,0xa3,0xbd,0xb0,0x64,0xbe,0xca,0x3d,0xb4,0x35 +,0xe5,0x31,0x27,0x6a,0x5d,0x40,0x48,0xc0,0x63,0x55,0xba,0xbe,0xbc,0xc6,0xbc,0xc5,0x53,0xda,0x40,0x3e,0x36,0x44,0x3e,0x3d,0x55,0x3c,0xbd,0xcc,0x46,0xaf,0xb9,0xce +,0xae,0xbc,0xd9,0xcb,0xc6,0x42,0x3c,0x5d,0x3a,0x32,0x42,0x4e,0x5e,0x5b,0x3d,0x59,0xd9,0xec,0xc2,0x65,0x63,0xb6,0xe2,0xcf,0xb6,0xcc,0xb0,0xbc,0xf4,0xc6,0xdb,0x75 +,0x34,0x42,0x3c,0x2d,0x36,0x38,0x3d,0x42,0x64,0xc0,0xbc,0xb9,0xc2,0xaa,0xb1,0xc0,0xb2,0x6d,0xe7,0x4c,0xd9,0x3f,0x2a,0x39,0x33,0x3b,0xd3,0x4a,0x5e,0x55,0xef,0xe8 +,0xcc,0xb4,0xf6,0xb9,0xcd,0xce,0xc6,0x44,0x59,0x43,0x5d,0xdd,0x3d,0x42,0xd9,0x43,0x62,0xca,0xd2,0xbc,0xec,0xb1,0xc3,0x63,0xb8,0x6b,0x4f,0x4f,0xe8,0x50,0x39,0x43 +,0x3f,0x4c,0x4e,0x41,0x52,0xe5,0x5a,0xcc,0xf6,0xd7,0xd4,0x56,0xb7,0xe3,0xcb,0xbc,0xbc,0xc2,0xc6,0xc8,0xef,0x59,0x39,0x44,0x32,0x34,0x3d,0x3c,0x3e,0x42,0x53,0x56 +,0xce,0xcc,0xb6,0xb2,0xc0,0xad,0xb5,0xc9,0xbb,0x47,0x4a,0x46,0x3a,0x49,0x3d,0x3a,0x3d,0x4a,0xf4,0xde,0x4c,0xce,0xcb,0xcb,0xba,0xc8,0xcf,0xd2,0xe2,0x55,0x49,0x4d +,0x46,0x72,0x4c,0x47,0xfd,0x45,0x7d,0x79,0xdb,0xc0,0xbe,0xbd,0xc0,0xcd,0xd7,0xd6,0xc5,0xed,0x46,0x74,0x45,0x57,0x49,0x3b,0x64,0x3c,0x50,0x49,0x48,0xd9,0x4c,0xdf +,0x75,0xe7,0xbd,0xcb,0xc9,0xbc,0xb6,0xbb,0xca,0xbf,0xcb,0x67,0x46,0x5a,0x38,0x33,0x3a,0x36,0x3b,0x4f,0x50,0xfe,0x4f,0x62,0xb6,0xbf,0xb6,0xbf,0xb9,0xba,0xda,0x7e +,0x4a,0x4b,0x40,0x3c,0x5f,0x4f,0x5b,0xdc,0x4e,0xd1,0xd6,0x4b,0xd3,0xcf,0xcd,0xcd,0xd7,0xcb,0xf4,0x42,0x4d,0x5e,0x3e,0x45,0x62,0xf6,0x4f,0x5e,0xda,0xef,0x65,0xcf +,0xc9,0xc0,0xbf,0xca,0xc4,0xe0,0xdb,0x74,0x54,0x71,0x43,0x72,0x67,0x40,0x49,0x4a,0x4a,0x4b,0x51,0x4c,0x56,0xd5,0xd1,0x79,0xd2,0xc4,0xc7,0xcf,0xc0,0xba,0xcf,0xc8 +,0xc3,0xcf,0xd8,0x3c,0x3e,0x3f,0x36,0x41,0x3a,0x47,0x6f,0x50,0xe3,0xcf,0xca,0xc5,0xd2,0xbd,0xb6,0xcc,0xd4,0x5c,0xe7,0x54,0x4a,0x4f,0x3a,0x57,0x4d,0xf2,0xd3,0x76 +,0xe1,0x62,0xdd,0xc0,0xdf,0xcd,0xdc,0xd5,0xd9,0x6d,0x75,0x3a,0x43,0x5f,0x5d,0x68,0x68,0x57,0x4e,0x73,0xc9,0xe4,0xfb,0xd8,0xd4,0xcd,0xc5,0xd1,0xd2,0x66,0x6b,0xe3 +,0x4f,0x76,0x4a,0x4e,0x58,0x4f,0xdc,0x4c,0x3f,0x3f,0x4d,0x6c,0x5f,0xd0,0xd5,0xd0,0xc1,0xbf,0xbd,0xbf,0xdd,0xc9,0xde,0xc9,0xda,0x47,0x52,0x3c,0x42,0x3a,0x3d,0x4b +,0x40,0x5d,0xd4,0xc2,0xc5,0xde,0xd6,0xdb,0xc4,0xbd,0xc4,0xd9,0xe3,0xe1,0x5c,0x4c,0x3f,0x3c,0x43,0x7c,0xfc,0xd6,0xdd,0xf1,0x78,0xfc,0xcb,0xda,0xdd,0xcc,0xe7,0xdc +,0xd2,0x6c,0x59,0x49,0x44,0x48,0x54,0xea,0xde,0x79,0xce,0xd2,0x73,0xd8,0x4e,0x64,0xcf,0xe0,0xc3,0xde,0xcd,0xdd,0x4e,0xf7,0x4a,0x5d,0x4f,0x48,0x72,0x78,0x71,0x64 +,0x47,0x54,0x4d,0x57,0xd5,0xcd,0xbf,0xd2,0xc2,0xc2,0xcc,0xd3,0xec,0x60,0x6e,0xcb,0xf5,0x46,0x3d,0x3d,0x3d,0x40,0x48,0x4d,0xe8,0xe2,0xc9,0xc0,0xc7,0xc5,0xd6,0xd0 +,0xcd,0xce,0xcd,0xde,0x6f,0x55,0x49,0x4a,0x4c,0x46,0x4b,0x4f,0xd3,0xd3,0xe2,0xd3,0x5a,0xe8,0x5d,0xef,0xd1,0x6b,0xdb,0xde,0xe4,0xdd,0x64,0x66,0x64,0x56,0xdc,0xed +,0xec,0x73,0x58,0xd9,0xfb,0x75,0x53,0x50,0xda,0xd5,0xc3,0xcb,0x6a,0x5e,0x48,0x5a,0x69,0x58,0xee,0x4d,0x65,0xf8,0x5b,0xed,0x54,0xf6,0xe8,0xde,0xc9,0xcb,0xd5,0xce +,0xc3,0xcd,0xe7,0x57,0x58,0x4f,0x78,0xe1,0x62,0x50,0x3e,0x3c,0x51,0x57,0x68,0x6c,0x5a,0xc6,0xc9,0xcb,0xc6,0xc9,0xcc,0xee,0xe8,0xcf,0x7a,0x5b,0x54,0x5e,0xfb,0x54 +,0x44,0x43,0x5b,0xd2,0xce,0xd2,0xdc,0x54,0x50,0xe8,0xdc,0xdf,0xe8,0x55,0x70,0xdc,0xd3,0x70,0x4e,0x5f,0xf2,0xe4,0xec,0xe6,0xdc,0x61,0x7e,0xe5,0x67,0x68,0x46,0x6d +,0xca,0xc4,0xcb,0x5b,0x6f,0x5e,0x4e,0x63,0x5a,0xff,0x57,0x4d,0xe6,0xf3,0x6e,0x54,0x5c,0xce,0xcb,0xcf,0xce,0xd5,0xcb,0xcf,0xe0,0x63,0x51,0x51,0x4e,0x70,0xe5,0x6c +,0x4a,0x47,0x50,0x7b,0x6c,0xea,0x64,0xe7,0xcc,0xcd,0xc3,0xe0,0xea,0x7c,0xfa,0xd4,0xd5,0xe6,0x5c,0x57,0xed,0x68,0x4b,0x47,0x47,0xf0,0xf6,0xe5,0xc9,0xe6,0x75,0x6c +,0xe5,0xe0,0x64,0x67,0x6a,0xda,0xc8,0xee,0x5d,0x5f,0x56,0x73,0x68,0xef,0xd0,0x66,0x5d,0x72,0xe4,0xdb,0x52,0x4d,0xe2,0xc8,0xcf,0xd5,0xd7,0xef,0xf8,0x5c,0x54,0x53 +,0x4a,0x56,0xfd,0xd2,0xdc,0x59,0x5e,0x5d,0xe3,0xd3,0xd9,0xc4,0xda,0xde,0xd3,0x64,0x5a,0x4f,0x4b,0x4a,0x58,0xeb,0xec,0x63,0xd1,0x75,0x58,0x5b,0x5a,0x7c,0xf2,0xc6 +,0xc6,0xca,0xcf,0x71,0x5f,0x53,0xf6,0xd9,0x67,0xf3,0x59,0x6e,0x55,0x4d,0x61,0x51,0x60,0xee,0xe0,0xde,0xda,0xd9,0xd9,0xf7,0xea,0x71,0x4f,0x5d,0xdc,0xc2,0xd1,0x5a +,0x5a,0x4e,0x63,0x76,0x5f,0x79,0x64,0xee,0x69,0xf7,0xff,0x58,0xe4,0xef,0xe7,0xd2,0xca,0xd4,0xd7,0xdd,0x64,0x49,0x45,0x50,0x5f,0xd6,0xdd,0xd9,0xe5,0x5e,0x66,0xd4 +,0xd7,0xd4,0xfe,0xdb,0xca,0x53,0x57,0x4f,0x59,0x59,0x48,0x51,0xef,0xce,0xc7,0xd2,0xe8,0x60,0x56,0x53,0x50,0xdf,0xd6,0xd6,0xd7,0xda,0xea,0x74,0x78,0xe4,0xd5,0x65 +,0x4f,0x6a,0x64,0x6f,0x6d,0x58,0x55,0x4d,0x59,0x66,0xd8,0xc1,0xd9,0x6e,0x75,0x5a,0x6d,0x79,0xc4,0xc2,0xd0,0xdd,0x49,0x4b,0x5d,0xe4,0xe3,0x79,0x6e,0xe7,0x5f,0x48 +,0x53,0x5c,0x67,0xe4,0xd3,0xe0,0xcd,0x6e,0x5e,0x74,0x67,0x63,0x6c,0xd7,0xd7,0xd5,0xed,0xfd,0x62,0xef,0x68,0xef,0xca,0xcb,0xd6,0xfc,0x52,0x6b,0x46,0x40,0x56,0x6c +,0xd8,0x4e,0x52,0x7e,0xd6,0xdb,0xe8,0xe0,0xfe,0x64,0x68,0xde,0xd7,0xce,0xcd,0xdb,0x66,0x43,0x64,0x6b,0x69,0xbb,0xcd,0xca,0xeb,0x4b,0x57,0x39,0x66,0xd3,0x78,0x5c +,0xea,0xcc,0xf3,0x61,0x51,0x48,0x49,0xda,0x70,0xd9,0xc7,0xc8,0xc8,0xd4,0x69,0x5d,0x4c,0xd1,0x55,0x49,0xdd,0xec,0xc9,0xe9,0xbd,0x5e,0x3e,0x4e,0x45,0xf2,0x7b,0x5b +,0xb4,0xe4,0x44,0x57,0x46,0x5a,0x3f,0xe6,0xbf,0xbc,0xbd,0xcd,0x60,0x3e,0x3c,0xd9,0xc9,0xc0,0x63,0x5a,0xe3,0x4a,0x3e,0x3c,0xbf,0xcb,0xd2,0xc1,0x71,0x48,0x4d,0x4c +,0xd9,0xcd,0xd2,0xde,0x62,0xce,0x4b,0xed,0x4a,0xe1,0xdd,0x45,0xce,0xce,0xd2,0x61,0xce,0x52,0x49,0xc3,0x5f,0x57,0xe4,0x4e,0xde,0x49,0xc7,0xcd,0x45,0xd6,0x3b,0x5c +,0xdf,0xd9,0xcc,0x4b,0xc2,0xbb,0x5c,0x64,0x49,0x6c,0x65,0x5a,0x79,0x49,0xb3,0xd7,0x6e,0xd7,0x49,0x58,0x44,0xc6,0xcd,0x42,0x53,0xd7,0x55,0x7c,0xe5,0x5c,0xe4,0x51 +,0xbf,0xe9,0x46,0xba,0xce,0x5e,0xc5,0xcc,0x5c,0x34,0x30,0xe6,0xdb,0xbd,0x64,0x4f,0xc7,0xc9,0x46,0x3f,0xc1,0xce,0xc3,0x7e,0x5e,0xfe,0xeb,0x48,0x52,0x55,0xd8,0xd8 +,0xe4,0xcb,0x3f,0x59,0xd9,0x4a,0xc4,0xcf,0x56,0xcd,0x39,0xbf,0x50,0x59,0xc5,0xde,0xce,0xef,0x60,0x55,0x45,0x4e,0xc8,0x74,0x6d,0x3f,0xcb,0xf4,0x48,0x50,0xc4,0x3e +,0xca,0xd9,0x48,0xc0,0xad,0x31,0xcc,0xbe,0x9e,0xa3,0x4c,0xdb,0x20,0xb1,0x2b,0x9d,0x18,0x3a,0x1c,0x01,0x11,0x09,0xa8,0xd9,0xea,0x64,0x2a,0x8d,0x8f,0x9d,0xa2,0x97 +,0xae,0x9f,0x87,0xbe,0xb5,0x8b,0x38,0xd0,0xa0,0x15,0x8d,0x88,0x93,0x98,0x8a,0x4a,0x1c,0x1c,0x08,0x0d,0x00,0x04,0x04,0x07,0x02,0x07,0x03,0x0e,0x08,0x11,0x47,0x17 +,0x30,0xaf,0x9a,0x95,0x9f,0x9a,0x92,0xa1,0x8d,0x9d,0x92,0x9b,0x9d,0x8d,0x86,0x83,0x85,0x83,0x83,0x84,0x80,0x8c,0x85,0x8b,0x15,0xa8,0x86,0x88,0x0a,0x16,0x0f,0x0a +,0x17,0x03,0x05,0x04,0x00,0x08,0xa3,0x0a,0x08,0x00,0x08,0xaf,0x04,0x04,0x08,0x33,0xb6,0xaa,0xbc,0x26,0x0c,0x1e,0x43,0x9f,0x81,0x8b,0x9d,0x43,0x8f,0x85,0x80,0x83 +,0x80,0x8c,0x88,0x8f,0x90,0x88,0x99,0x9d,0x9d,0x8f,0xdf,0x9e,0x37,0x29,0x10,0x0b,0x23,0x18,0x0e,0x05,0x0c,0x34,0x11,0x0c,0x18,0x09,0x07,0x04,0x07,0x0f,0x0f,0x0f +,0x06,0x16,0x33,0x48,0x20,0x22,0x4c,0x23,0xb4,0xae,0xa9,0x97,0x88,0x91,0x97,0x91,0x89,0x87,0xaf,0x97,0x80,0x93,0x8f,0x89,0x80,0x8d,0x96,0x9a,0xd3,0x8e,0x0c,0x24 +,0x34,0xc3,0x95,0x16,0x3c,0x1b,0x0c,0x0c,0x06,0x00,0x0a,0x23,0x26,0x39,0x20,0x0c,0x00,0x03,0x0c,0x2d,0x0f,0x1a,0xba,0x0f,0xc2,0x8b,0x87,0x82,0x84,0x83,0x93,0xab +,0x9a,0x88,0x8a,0x84,0x85,0x8f,0x8d,0x9b,0x9c,0x36,0xa7,0x1f,0x29,0xb4,0x1f,0x2f,0x84,0x8c,0xba,0x8b,0x1d,0x2e,0x0e,0x14,0xa0,0x0b,0x1b,0x61,0xd1,0xbf,0x11,0x08 +,0x08,0xa5,0x0e,0x20,0xb6,0x03,0x14,0xb2,0x86,0x9b,0x92,0xb4,0x09,0x0f,0x9f,0x1b,0x15,0x87,0x26,0x46,0x0f,0x0a,0x85,0x18,0x09,0x0c,0x00,0x36,0xbf,0x90,0x93,0x0d +,0x40,0x16,0x07,0x18,0x1e,0xcb,0x24,0x93,0x72,0x0f,0xbf,0xaf,0x31,0x2e,0xf0,0x0a,0x09,0x06,0x3b,0x8e,0xa2,0xfc,0x9b,0x96,0x9b,0x85,0x9e,0xb1,0x84,0x86,0x80,0x82 +,0x80,0x83,0x82,0x89,0x4e,0xc7,0x91,0x89,0xa3,0x34,0x1b,0x80,0xab,0xbb,0x8a,0x9c,0x4e,0x00,0x1c,0x90,0x83,0x33,0x0f,0x2e,0x9c,0x03,0x0f,0x3c,0x00,0x06,0x00,0x0b +,0x00,0x0c,0x98,0x01,0x0b,0x06,0x02,0x19,0x09,0x17,0x03,0x0b,0x25,0x70,0x4b,0x90,0x32,0x10,0x24,0x00,0x9e,0xc4,0x9f,0xa7,0x27,0x85,0x88,0x83,0x83,0x82,0x80,0x35 +,0x1d,0x80,0x86,0x80,0x8d,0x89,0x83,0x8e,0x8d,0x15,0x13,0x8a,0x8f,0x0e,0x0a,0x0c,0x87,0xf1,0x1a,0x3c,0x00,0x14,0x00,0x0b,0x1a,0x08,0x0e,0x07,0x15,0x0d,0x04,0x0d +,0x16,0x14,0x09,0x0c,0x87,0x8f,0x90,0x84,0x93,0x80,0x80,0x80,0x80,0x88,0x9e,0x81,0x82,0x80,0x80,0x92,0x88,0x2c,0x9a,0x8a,0xbf,0x22,0x02,0x17,0x02,0x15,0x8f,0x08 +,0x0b,0x0c,0x09,0x08,0x02,0x02,0x05,0x03,0x0a,0x06,0x00,0x14,0x09,0x00,0x04,0x05,0x04,0x02,0x06,0x06,0x12,0x8d,0xe5,0x0a,0x8e,0x9f,0xa3,0x19,0x32,0x91,0xa9,0x82 +,0x8c,0x82,0x8d,0x91,0x86,0x86,0x84,0x82,0x85,0x87,0x89,0x89,0x82,0x80,0x81,0x80,0x8b,0x8a,0x9c,0x15,0xa9,0x2c,0x9b,0x8b,0xb7,0x36,0x2e,0x07,0x37,0xb2,0xad,0x0c +,0x03,0x23,0x03,0x9d,0x3e,0x1e,0x1c,0x10,0x19,0x05,0x01,0x0f,0x10,0x0b,0xb4,0x1a,0x12,0x18,0x18,0x1c,0x08,0x12,0xed,0x03,0x1c,0x12,0xa3,0x87,0x1f,0x91,0xa1,0xaa +,0x21,0x10,0xa3,0x9a,0x60,0x86,0x98,0x80,0x8c,0xa5,0x8b,0xba,0x47,0x1c,0x2b,0x37,0x1d,0x3e,0x87,0x0e,0xc1,0x94,0x1f,0x0c,0x00,0xdc,0x96,0x16,0x9b,0x1f,0x21,0x48 +,0x01,0x19,0x0e,0x0d,0x06,0x03,0x06,0x01,0x1e,0x92,0x66,0x8f,0x90,0xb7,0x95,0xd2,0x8f,0x80,0x82,0x80,0x80,0x80,0x83,0x83,0x84,0x81,0x85,0x81,0xb5,0x26,0xac,0xa7 +,0x80,0x9e,0x9e,0xae,0x13,0x1c,0x00,0x0a,0x1e,0x08,0x15,0x1e,0x0d,0x03,0x00,0x04,0x05,0x00,0x02,0x00,0x02,0x00,0x04,0x39,0x13,0x07,0x14,0x0d,0x0e,0x04,0x0b,0xa0 +,0x19,0x97,0xc4,0xaf,0x8e,0x2f,0xa4,0x8f,0x2c,0x98,0xad,0x1c,0x8d,0x92,0x80,0x86,0x86,0x80,0x8a,0x81,0x8b,0x8f,0x80,0x89,0x87,0x80,0x88,0x89,0x9b,0xb4,0xae,0xa5 +,0x1b,0x0d,0x13,0x2b,0x10,0xa6,0x88,0x0d,0xd1,0x1b,0x04,0x0b,0x08,0x21,0x0a,0x11,0x1e,0x0d,0x22,0x08,0x0c,0x33,0x14,0x2d,0x0e,0x01,0x16,0x08,0x95,0x85,0xb6,0x8c +,0xdc,0x27,0x23,0x0f,0x9d,0xa0,0x9f,0x97,0x64,0x90,0xf8,0x1b,0xb7,0x25,0x12,0xbf,0x0d,0x20,0x09,0x3f,0x83,0x37,0x9c,0xd3,0x23,0x13,0x07,0x22,0xa0,0x2c,0x8e,0xdb +,0xb5,0x95,0x19,0x8d,0x91,0xbd,0x38,0x12,0x3f,0x11,0x3c,0x80,0xae,0x2e,0x97,0x16,0x17,0x06,0x12,0x9f,0xbd,0x95,0x79,0xb2,0x9d,0x8e,0x8c,0x9d,0xbe,0x8e,0x9a,0xa0 +,0x9b,0x93,0x80,0x87,0x80,0x88,0x88,0x95,0xa1,0x8f,0x84,0x8b,0x8f,0x8f,0x8d,0x8b,0x14,0x26,0x14,0x05,0x05,0x02,0x00,0x03,0x00,0x38,0x15,0x00,0x0a,0x00,0x05,0x00 +,0x00,0x08,0x09,0x09,0x17,0x0d,0x0d,0x08,0x16,0x0e,0x10,0x14,0x0e,0x16,0x1c,0x2b,0x83,0x88,0x93,0x84,0x88,0x94,0xa8,0x8c,0x83,0x86,0x85,0x80,0x89,0x83,0x95,0x8c +,0x8c,0x9d,0x94,0xba,0x0c,0x37,0x19,0x91,0x80,0x2f,0x9c,0x9e,0x7b,0x0f,0x0f,0x87,0x95,0x35,0x83,0x53,0x99,0xb0,0x41,0xa7,0xdd,0x1e,0x07,0x11,0x13,0x0b,0xa0,0x84 +,0x49,0x35,0xdd,0xdc,0x16,0x0d,0xa8,0xae,0x23,0x96,0x24,0x1f,0x18,0x12,0x14,0x07,0x08,0x05,0x02,0x06,0x02,0x18,0x91,0x1b,0x9f,0x4b,0x21,0x1e,0x00,0xcf,0x9f,0x1d +,0x9b,0xaa,0xaf,0x35,0x29,0x98,0x3a,0x26,0xea,0x12,0x1d,0x29,0xa0,0x80,0x90,0x8a,0x8f,0x99,0x98,0x10,0xaf,0x8e,0xb6,0x98,0xc3,0x9b,0xbc,0x4f,0x44,0x1d,0x1f,0x1b +,0x0d,0x26,0x2f,0x1e,0x80,0x8a,0x95,0x8f,0x92,0x98,0x7a,0xa1,0x84,0x9b,0x84,0x83,0x88,0x84,0x8d,0x8c,0x92,0x95,0x8c,0xb2,0x20,0xaa,0xc5,0x84,0xb5,0xcc,0xd3,0x0c +,0x01,0x00,0x02,0x0d,0x09,0x09,0x0e,0x0e,0x0a,0x04,0x0a,0x0b,0x05,0x04,0x02,0x00,0x04,0x04,0x8f,0x1e,0x0f,0x2c,0x09,0x0d,0x04,0x0b,0x9d,0xa7,0x97,0x8b,0x8e,0x98 +,0x9b,0x91,0x89,0xa8,0xa7,0x4e,0x2f,0x9c,0x38,0x80,0x90,0xa4,0x8c,0x9f,0x29,0xbf,0xbe,0x86,0x8e,0x8d,0x83,0x86,0x84,0x92,0x8a,0x8d,0x9e,0x9d,0xcc,0x29,0xa2,0x21 +,0x80,0x92,0x22,0xa7,0x35,0x19,0x0b,0x10,0xc8,0xae,0x39,0x9e,0xa5,0xa9,0x1c,0x18,0x3e,0x10,0x0e,0x0d,0x03,0x0d,0x06,0x97,0xd4,0x0d,0xd7,0x14,0x0c,0x03,0x09,0x39 +,0x4e,0x3e,0xab,0xbc,0x47,0x14,0x12,0x2b,0x0d,0x09,0x07,0x06,0x06,0x07,0x8b,0xa0,0x1d,0xb1,0xb6,0x22,0x0f,0x2a,0x89,0x8c,0x8f,0x86,0x8d,0x8d,0x9e,0x9a,0x91,0xa6 +,0xe9,0x1f,0x17,0x35,0x41,0x83,0x89,0x9e,0x8e,0xb9,0xbc,0x19,0x20,0x91,0xab,0xdb,0x98,0xa6,0xdf,0x2d,0x24,0xa5,0x2f,0x1d,0x27,0x38,0xae,0x93,0x80,0x85,0x85,0x81 +,0x84,0x86,0x8f,0x8c,0x82,0x88,0x88,0x87,0x8f,0xa6,0x3a,0x17,0x16,0x07,0x02,0x01,0x01,0x01,0x04,0xb3,0x0e,0x07,0x0f,0x06,0x04,0x00,0x06,0x0f,0x0a,0x0a,0x16,0x10 +,0x07,0x05,0x08,0x12,0x09,0x07,0x06,0x0d,0x09,0x2f,0x80,0x95,0x94,0x8d,0xa0,0xa3,0x25,0x98,0x8a,0x94,0x8d,0x90,0x8e,0x96,0xaa,0x95,0x8e,0x9f,0xb2,0xbb,0x9e,0x9a +,0x87,0x80,0x87,0x85,0x85,0x8a,0x98,0x2b,0x8f,0x8e,0x9f,0x98,0x95,0x90,0xc9,0xdc,0xbd,0xa3,0x1f,0x24,0x13,0x24,0x0e,0xa2,0x86,0x43,0xa2,0x2e,0x19,0x0c,0x00,0x18 +,0x22,0x15,0x4d,0x1d,0x24,0x0f,0x0d,0x18,0x1e,0x0f,0x08,0x03,0x0c,0x03,0xb5,0x8f,0x16,0x56,0x14,0x13,0x06,0x02,0x2f,0x56,0x29,0xc6,0xbc,0xbd,0x2d,0x2f,0x9a,0xa4 +,0x3c,0x1f,0x28,0xc8,0x26,0x88,0x85,0x9b,0x8b,0x9e,0xa7,0x45,0x23,0x89,0x89,0x8f,0x8b,0x94,0x96,0xa7,0xb7,0xa0,0xb7,0x1d,0x0f,0x0a,0x13,0x0a,0x91,0x98,0x24,0xa1 +,0x21,0x2b,0x11,0x12,0x92,0x99,0x9a,0x8a,0x8b,0x83,0x87,0x8b,0x85,0x88,0x8f,0xb6,0xa7,0x95,0x98,0x80,0x87,0x94,0x99,0x2b,0x15,0x04,0x02,0x25,0x16,0x12,0x1c,0x1a +,0x0e,0x05,0x02,0x0a,0x07,0x02,0x02,0x04,0x09,0x0c,0x8c,0x33,0x16,0xd0,0x19,0x1b,0x0c,0x26,0x8a,0x95,0x92,0x8f,0xa7,0xba,0x24,0x23,0x34,0x21,0x1a,0x0b,0x10,0x1b +,0x23,0x85,0xaa,0xa6,0x9e,0x44,0xa9,0x12,0xc6,0x87,0x8b,0x8d,0x90,0x8f,0x9c,0x34,0x49,0x94,0xa6,0x33,0x1f,0xce,0x1f,0xd1,0x83,0xad,0xa4,0xba,0x2c,0x1d,0x09,0xb6 +,0x8e,0xaf,0x9a,0x99,0xa2,0x47,0x26,0xb5,0x94,0x9f,0xa4,0x3b,0x4e,0x17,0x9c,0x85,0x28,0x9c,0xa7,0xe2,0x1f,0x0a,0x61,0xbb,0x35,0xfc,0x26,0x37,0x13,0x0d,0x1f,0xb6 +,0x3b,0x0e,0x08,0x14,0x06,0xac,0x8e,0xca,0x8b,0xa8,0x9b,0x1f,0x09,0xb2,0xb4,0x2d,0x48,0x40,0xc5,0x0f,0x0c,0x38,0x1a,0x12,0x0c,0x06,0x09,0x06,0x8c,0x97,0x2e,0x8c +,0xb1,0xae,0x17,0x0d,0x9b,0x9f,0x96,0x8e,0x99,0x8d,0xc1,0x33,0xaa,0xd0,0xc7,0x1c,0x1e,0x3b,0x25,0x81,0x97,0xa0,0x88,0x9c,0x9e,0x19,0xce,0x82,0x88,0x87,0x82,0x83 +,0x85,0xaf,0xa5,0x93,0xb4,0xaa,0x29,0x3c,0x2e,0xdf,0x86,0x2d,0x36,0xca,0x0b,0x13,0x05,0x10,0xb6,0x2a,0xd7,0x45,0x21,0x1b,0x07,0x0c,0x1b,0x1b,0x2a,0x1c,0x9c,0xd1 +,0x96,0x86,0x3a,0x96,0xaf,0x15,0x13,0x05,0x27,0x48,0x05,0x09,0x0c,0x0b,0x03,0x00,0x03,0x08,0x08,0x08,0x04,0x0a,0x07,0xab,0x8f,0x1c,0x9a,0xa2,0x9f,0xa4,0x3a,0x8e +,0x8c,0x8f,0x87,0x8b,0x8a,0x8f,0xa6,0x8d,0x95,0x98,0xad,0x31,0xae,0xad,0x81,0x89,0x8f,0x81,0x88,0x87,0x8e,0xa3,0x84,0x89,0x87,0x86,0x8c,0x89,0x9f,0x42,0xa3,0xc2 +,0x27,0x0a,0x05,0x0b,0x06,0xc2,0x0b,0x09,0x1e,0x0d,0x06,0x00,0x03,0x1b,0x18,0x09,0x16,0xb0,0x8a,0x96,0x9a,0x8c,0x8a,0x88,0x9e,0xbf,0x2a,0xa4,0x80,0xae,0xd1,0xcf +,0x16,0x0b,0x00,0x04,0x08,0x04,0x07,0x0e,0x18,0x26,0x0c,0x0a,0x0e,0x0e,0x0d,0x03,0x0f,0x14,0x9b,0x84,0xa6,0x8a,0x91,0xa7,0xad,0x17,0xaf,0x8c,0x8f,0x89,0x8c,0x85 +,0x8c,0xda,0xae,0xa8,0x9f,0xbb,0x36,0x9e,0xa1,0x87,0x80,0x8b,0x85,0x8a,0x8c,0x96,0x1a,0x9c,0x8e,0x97,0x8d,0xa3,0x94,0x3a,0x09,0x16,0x0a,0x06,0x06,0x00,0x0e,0x07 +,0x3b,0x55,0x0d,0xc1,0x28,0x15,0x12,0x16,0x8f,0x86,0x86,0x84,0x84,0x80,0x86,0x9f,0x96,0x8c,0x8f,0xb8,0x12,0x1d,0x06,0x3f,0x1d,0x00,0x09,0x05,0x05,0x00,0x01,0x0b +,0x0c,0x09,0x13,0x0d,0x20,0x20,0x0f,0x20,0x29,0x2b,0x15,0x0b,0x12,0x0f,0x97,0x96,0xab,0x8f,0x97,0x8d,0x5f,0x13,0xcc,0xac,0xb7,0xa5,0x96,0x88,0x8f,0x9c,0x91,0x99 +,0x96,0xab,0x67,0xca,0xa4,0x82,0x83,0x87,0x83,0x86,0x89,0xcd,0x11,0xad,0xae,0xa5,0xaf,0x2a,0x9f,0xaa,0x18,0x0d,0x05,0x08,0x08,0x03,0x04,0x06,0x9d,0x8d,0x8e,0x8c +,0x8f,0x88,0x8a,0x97,0x8a,0x84,0x84,0x81,0x84,0x83,0x90,0x5d,0x1a,0x0b,0x04,0x01,0x00,0x01,0x00,0x15,0x14,0x06,0x07,0x09,0x0d,0x05,0x01,0x09,0x1a,0x4f,0xbb,0xc6 +,0xb9,0x4c,0x25,0x22,0x14,0x1d,0x21,0x20,0x23,0x27,0x8d,0x8f,0xad,0xa7,0xaa,0x9f,0xac,0x2d,0xaa,0x95,0x88,0x8a,0x93,0x8d,0x8c,0x97,0x98,0x94,0x95,0x8e,0x97,0x99 +,0xcc,0x99,0x90,0x9a,0x9c,0xa1,0xbb,0x76,0x23,0x3e,0x5f,0x21,0x29,0x17,0x1c,0x18,0x0d,0x0f,0x1c,0x33,0x96,0xaf,0x47,0x70,0x90,0x80,0x85,0x83,0x83,0x82,0x82,0x87 +,0x91,0x9c,0xb9,0xb5,0x1f,0x09,0x07,0x06,0x04,0x05,0x06,0x04,0x03,0x01,0x02,0x00,0x06,0x16,0x1a,0x21,0x1d,0x20,0x2e,0x1a,0x1c,0x24,0x28,0xbe,0xd5,0x3c,0xc4,0xab +,0x9e,0xad,0x4f,0xe8,0x24,0x16,0x25,0x2d,0x9f,0x8d,0x8c,0x8f,0x9a,0xa5,0x99,0x99,0x95,0x88,0x8b,0x8b,0x89,0x89,0x8d,0x9a,0xaf,0xa1,0xaf,0x4e,0x1e,0x14,0x2b,0xc6 +,0x3c,0x25,0x18,0x0c,0x13,0x0a,0x0b,0x10,0x24,0xa6,0x9b,0xa4,0xa8,0x96,0x8b,0x87,0x89,0x86,0x83,0x84,0x86,0x83,0x86,0x8e,0x9b,0x4f,0x10,0x10,0x0a,0x06,0x05,0x05 +,0x09,0x04,0x02,0x03,0x04,0x04,0x0a,0x0f,0x15,0x16,0x1d,0x1b,0x18,0x23,0x28,0x1e,0x1a,0x1d,0x3c,0x2a,0x4a,0xa7,0xd7,0xc3,0x28,0x1c,0x29,0x39,0xa6,0x98,0x93,0x8e +,0x9a,0xa2,0xa1,0xba,0xa2,0x8f,0x89,0x8b,0x8c,0x8b,0x8d,0x8c,0x8f,0xa2,0xde,0xa8,0x94,0x9f,0xd3,0xaf,0x9e,0x9f,0xd5,0x1b,0x0e,0x12,0x22,0x2d,0x19,0x2a,0x3c,0x2d +,0x4f,0x2d,0x68,0xb3,0x95,0x8b,0x8a,0x86,0x83,0x84,0x84,0x86,0x86,0x8d,0xb4,0xac,0xb4,0x2e,0x3a,0x24,0x14,0x0b,0x04,0x04,0x01,0x03,0x04,0x08,0x0a,0x0b,0x0e,0x0c +,0x09,0x0c,0x0f,0x0e,0x0e,0x0f,0x1a,0x1f,0x4b,0x41,0x28,0x43,0x3a,0x2f,0x3b,0xae,0x99,0x9e,0x94,0x8e,0x9c,0xa7,0xa7,0xad,0xa8,0x9f,0x94,0x8f,0x8e,0x8d,0x95,0x96 +,0x91,0x97,0xa9,0x53,0xa5,0x9b,0x93,0x93,0xa5,0xa7,0xa8,0xb8,0x1f,0x14,0x1c,0x3a,0x3d,0x45,0x1d,0x12,0x15,0x15,0x16,0x16,0x30,0xb4,0xa7,0x92,0x8d,0x8a,0x88,0x87 +,0x84,0x8b,0x8d,0x8e,0x91,0x93,0x94,0xa5,0x43,0x16,0x0d,0x08,0x03,0x06,0x08,0x07,0x08,0x0a,0x08,0x06,0x08,0x0b,0x0a,0x0c,0x10,0x17,0x15,0x1c,0x26,0x1b,0x1b,0x29 +,0x2c,0x23,0x23,0xc2,0x9c,0x98,0x8f,0x9c,0x9f,0x9e,0xa9,0xa4,0x9f,0x90,0x8e,0x97,0x8d,0x8c,0x94,0x9e,0xa0,0x9b,0x9e,0x9d,0xa2,0xaf,0x9a,0x8e,0x98,0xbe,0x29,0x3b +,0x3d,0x2e,0x2d,0x25,0xfc,0xa4,0x53,0x19,0x0f,0x0f,0x12,0x14,0x1d,0x2d,0xb7,0x9f,0x9d,0x9a,0x94,0x8c,0x8b,0x8b,0x86,0x84,0x86,0x84,0x85,0x8b,0x99,0xb1,0x2f,0x0f +,0x0d,0x0c,0x0a,0x0b,0x0a,0x08,0x06,0x03,0x04,0x06,0x07,0x0d,0x0e,0x10,0x1c,0x2c,0x1c,0x1a,0x1e,0x21,0x25,0x24,0x21,0x2e,0xe6,0x9f,0xa0,0x51,0x4e,0x6f,0x47,0x24 +,0x2e,0xaa,0x99,0x9b,0x9b,0x9a,0x97,0x96,0x96,0x9c,0x9d,0x8d,0x8a,0x8e,0x91,0x8b,0x8a,0x8d,0x98,0x9f,0xb9,0xbf,0xa8,0xc4,0x5f,0xd9,0xba,0x2d,0x14,0x0f,0x0c,0x0a +,0x0b,0x0f,0x18,0x18,0x25,0x49,0xcd,0xab,0x9a,0x96,0x8f,0x86,0x84,0x83,0x83,0x81,0x82,0x85,0x8d,0x97,0xaa,0x30,0x25,0x1b,0x0f,0x10,0x0c,0x05,0x04,0x02,0x04,0x04 +,0x04,0x06,0x0a,0x0d,0x12,0x17,0x18,0x16,0x19,0x15,0x19,0x27,0x2e,0xae,0x9c,0x9b,0x9b,0xa8,0xaf,0xb1,0xb7,0xa6,0x98,0x99,0x94,0x94,0x9e,0xa7,0xab,0xac,0xb7,0xaa +,0xa4,0xa3,0x9d,0x99,0x9d,0x9e,0x9d,0x9d,0xb3,0xe1,0xaf,0xa8,0xa8,0x9c,0xa2,0xb9,0xbf,0x49,0x35,0x28,0x4b,0xd9,0xc9,0xc6,0xce,0x55,0x34,0x46,0x3c,0x31,0x38,0x2c +,0x2a,0x2a,0x2b,0x3f,0x4c,0x2f,0x29,0x27,0x21,0x25,0x22,0x28,0x44,0x70,0x44,0x38,0x29,0x2c,0x35,0x3d,0x3a,0x32,0x39,0x30,0x3e,0x2c,0x29,0x3a,0x38,0x31,0x2f,0x33 +,0x35,0x5b,0xc5,0xb7,0xc6,0xd5,0x64,0x46,0x4e,0x6c,0xc0,0xb3,0xbb,0xfd,0x38,0x3c,0x4f,0x46,0xcc,0xbe,0xb2,0xaf,0xa7,0xa1,0x9c,0x98,0x93,0x92,0x94,0x96,0x95,0x92 +,0x92,0x8f,0x8f,0x94,0x9b,0x9f,0xa3,0xb2,0xcb,0xbe,0xd9,0x4f,0x3a,0x2b,0x22,0x1b,0x19,0x1b,0x18,0x17,0x16,0x15,0x15,0x17,0x1d,0x1e,0x1b,0x1a,0x1e,0x21,0x1d,0x22 +,0x2d,0x3d,0x46,0x41,0x5a,0x5b,0x49,0x3e,0xe4,0x56,0x5e,0x52,0x39,0x4f,0x41,0xdd,0x6b,0x32,0x38,0x3f,0x3c,0x7c,0xdf,0xbf,0xba,0xca,0xae,0xbc,0xb8,0xaf,0xc8,0xb5 +,0xb7,0x7e,0x2e,0x3c,0x6c,0x3f,0xd0,0xd7,0xc8,0xbb,0xae,0xaa,0xa3,0x9c,0x98,0x96,0x97,0x8f,0x92,0x8f,0x8d,0x8f,0x8f,0x90,0x8e,0x96,0x99,0x9a,0xa4,0x9f,0xa2,0xb0 +,0xbf,0xc8,0x3c,0x32,0x39,0x2e,0x1e,0x1e,0x34,0x30,0x23,0x0b,0x0b,0x0f,0x0c,0x1d,0xb8,0x15,0x00,0xae,0x97,0x0f,0x23,0x03,0x09,0x20,0xbc,0x12,0x0b,0x11,0x00,0x1b +,0x06,0x00,0x01,0x01,0x22,0x0d,0x07,0x10,0x04,0x01,0x07,0x0e,0x13,0x0c,0x0f,0x20,0x42,0x97,0x92,0xcb,0x8e,0x81,0x80,0x80,0x83,0x81,0x80,0x80,0x80,0x80,0x84,0x84 +,0x81,0x82,0x81,0x80,0x86,0x85,0x80,0x81,0x83,0x83,0x80,0x86,0x8f,0x8d,0x85,0x84,0x8e,0x9d,0xb8,0xa8,0xae,0x0d,0x03,0x05,0x09,0x08,0x05,0x06,0x02,0x00,0x01,0x08 +,0x0b,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x06,0x0b,0x04,0x05,0x09,0x20,0x46,0x12,0x03,0x0f,0x94,0x89,0x8a,0x8e,0x8f,0x8f +,0x8c,0x8e,0x97,0x98,0x86,0x83,0x85,0x81,0x81,0x82,0x82,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x84,0x83,0x83,0x88,0x8b,0x85,0x82,0x85,0x86 +,0x83,0x82,0x89,0x8f,0x8e,0x8b,0x86,0x8c,0x9e,0xae,0x9e,0xba,0x0f,0x0f,0x17,0x0f,0x0e,0x0a,0x04,0x02,0x02,0x04,0x08,0x09,0x03,0x00,0x00,0x01,0x01,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x03,0x02,0x02,0x06,0x05,0x01,0x01,0x06,0x0f,0x0e,0x0e,0x0a,0x04,0x06,0x0b,0x0c,0x0b,0x0e,0x16,0x12,0x12,0x1a,0x1a +,0x22,0xa7,0x8d,0x90,0x93,0x90,0x8b,0x88,0x82,0x87,0x8a,0x88,0x89,0x8b,0x8c,0x87,0x86,0x86,0x82,0x80,0x81,0x82,0x84,0x81,0x80,0x81,0x83,0x82,0x80,0x80,0x80,0x81 +,0x82,0x82,0x83,0x82,0x82,0x83,0x83,0x82,0x86,0x8e,0x8f,0x92,0x92,0x8e,0x99,0x4b,0x1b,0x13,0x15,0x11,0x0f,0x0d,0x09,0x07,0x05,0x06,0x07,0x08,0x0c,0x15,0x2c,0x9b +,0x98,0xac,0x99,0x8c,0x91,0x9a,0x96,0x88,0x81,0x82,0x83,0x8a,0x8f,0x90,0x9b,0xbd,0xbb,0xc1,0xb5,0xaa,0xaa,0xb3,0xcf,0xac,0x90,0x93,0x9d,0xa2,0xaa,0xad,0xac,0xb5 +,0x1b,0x0a,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x01,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x03,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00 +,0x01,0x01,0x02,0x03,0x06,0x05,0x02,0x01,0x01,0x02,0x04,0x16,0x1d,0x0e,0x0c,0x0f,0x18,0x28,0x2d,0x37,0x98,0x88,0x84,0x85,0x84,0x80,0x81,0x82,0x81,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x83,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x85,0x84,0x84,0x86,0x8a,0x89,0x84,0x83 +,0x83,0x83,0x82,0x83,0x82,0x83,0x84,0x84,0x86,0x84,0x83,0x83,0x87,0x92,0xa9,0xb2,0x73,0xce,0x1c,0x16,0x24,0x0c,0x0a,0x06,0x01,0x02,0x01,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x01,0x02,0x01,0x02,0x00,0x03,0x04,0x0e,0x67,0x37,0x22,0x1b,0x0b,0x0d,0x0c,0x08,0x18 +,0x2a,0xc7,0xa5,0x9a,0x8a,0x84,0x86,0x85,0x87,0x88,0x83,0x81,0x81,0x82,0x85,0x8c,0x94,0xbe,0x7a,0x6b,0x5e,0xba,0xa1,0xb4,0x9d,0x88,0x89,0x87,0x8d,0x8f,0x90,0x9c +,0xa4,0x99,0x8c,0x88,0x94,0xa6,0x9d,0x94,0x94,0xa3,0xc1,0x48,0xc3,0xc4,0x3c,0x3f,0x4e,0x2c,0x25,0x18,0x15,0x0d,0x08,0x0c,0x13,0x14,0x18,0x32,0x20,0x15,0x15,0x1a +,0x18,0x0f,0x10,0x2a,0xa7,0x96,0x99,0xae,0xa3,0x9d,0xd2,0x50,0x3f,0xcb,0xa5,0xb5,0xc7,0x37,0x17,0x1b,0x16,0x13,0x18,0x0d,0x0e,0x13,0x16,0x1f,0x9a,0x8b,0x98,0xb0 +,0xbd,0x96,0x8f,0x9f,0xa5,0x97,0x98,0x9b,0xec,0xe1,0x9a,0x96,0x8d,0x89,0x86,0x83,0x84,0x83,0x84,0x83,0x85,0x84,0x84,0x82,0x82,0x83,0x89,0x8f,0x9a,0xa5,0x88,0x83 +,0x89,0x9a,0x76,0xe1,0x31,0x0c,0x09,0x0d,0x0f,0x0b,0x02,0x03,0x04,0x04,0x03,0x04,0x04,0x03,0x00,0x01,0x00,0x03,0x02,0x02,0x02,0x07,0x0b,0x0a,0x0a,0x0f,0x10,0x1e +,0xa1,0x98,0x97,0x9e,0x9c,0x94,0x9c,0xc4,0xb7,0x9f,0x95,0x9f,0xbc,0xa3,0x9d,0x9c,0x96,0x8f,0x86,0x84,0x8d,0x8f,0x8d,0x8b,0x87,0x87,0x85,0x86,0x92,0xac,0x29,0x24 +,0x20,0xce,0x91,0x91,0x9c,0xa5,0xaf,0xa7,0x62,0x21,0x33,0x3f,0x40,0x1f,0x24,0xc0,0x5a,0x1e,0x17,0x16,0x3d,0x44,0x1a,0x12,0x14,0x16,0x15,0x11,0x1a,0x1e,0x0f,0x0b +,0x07,0x06,0x05,0x1e,0xaf,0xca,0x39,0x17,0x15,0x12,0x0a,0x10,0x21,0x54,0x64,0x1e,0xb9,0x94,0x97,0xa3,0xaf,0x9c,0x97,0xa4,0xae,0xb4,0xaa,0xb6,0x4a,0x3f,0x42,0xc8 +,0x41,0x26,0x28,0x20,0x13,0xb5,0x95,0x8f,0x92,0xa5,0x99,0xb2,0x2d,0x36,0x7e,0xa1,0x9e,0x2c,0x2d,0x33,0x2d,0x21,0x16,0x27,0xeb,0xb2,0xab,0xa4,0x90,0x88,0x89,0x89 +,0x89,0x89,0x8a,0x8f,0x92,0x8e,0x8e,0x87,0x83,0x84,0x84,0x89,0x88,0x8e,0xaa,0xae,0xb6,0x9d,0xab,0x16,0x12,0x0f,0x0c,0x06,0x02,0x04,0x04,0x02,0x01,0x01,0x03,0x03 +,0x02,0x04,0x03,0x05,0x03,0x06,0x06,0x08,0x08,0x14,0xae,0xa4,0xa3,0xae,0x9e,0x9f,0x3e,0xd7,0x9b,0x8f,0x8a,0x93,0x96,0x8f,0x94,0x98,0x99,0x98,0x92,0x93,0x8f,0x90 +,0x95,0x8d,0x8f,0x8e,0x91,0x97,0x91,0x8c,0x95,0x9f,0xa1,0xa5,0x8a,0x8a,0x8e,0x8d,0x9b,0x96,0xaa,0x42,0xb4,0xf9,0xb4,0x3b,0x14,0x15,0x13,0x18,0x14,0x12,0x23,0x28 +,0x20,0x23,0x1f,0x56,0xce,0x26,0x25,0x1e,0x1e,0x0f,0x0a,0x07,0x05,0x04,0x06,0x11,0x18,0x17,0x13,0x19,0x20,0x17,0x12,0x19,0x31,0xad,0x49,0x1f,0x2f,0x43,0x48,0x3c +,0x6a,0xa7,0xa8,0xc0,0x50,0x47,0xe7,0xb6,0xbb,0xa9,0x9e,0xa8,0xb6,0xb1,0xba,0xaa,0x2e,0x55,0x92,0x95,0x96,0xa8,0xa4,0x9e,0xd7,0x26,0x1d,0x27,0xb8,0x7e,0x3d,0xb8 +,0xaf,0xac,0x62,0xbb,0x9b,0x9e,0xab,0xad,0x9b,0x91,0x8f,0x8f,0x89,0x8a,0x8c,0x9b,0xa9,0xa0,0x9d,0x9a,0x94,0x84,0x82,0x83,0x89,0x89,0x85,0x94,0xc3,0x4c,0x4a,0xbc +,0x1b,0x0a,0x08,0x06,0x04,0x00,0x01,0x01,0x03,0x03,0x02,0x03,0x04,0x03,0x04,0x08,0x0b,0x09,0x05,0x03,0x07,0x08,0x0c,0x0a,0x1a,0x9b,0xac,0xfd,0x7c,0x9f,0x96,0xa3 +,0x9f,0x93,0x89,0x86,0x8d,0x8a,0x8a,0x8d,0x94,0xa7,0x97,0x8f,0x8f,0x92,0x9a,0x91,0x9a,0x9e,0x96,0x8e,0x8a,0x8e,0x90,0x94,0x91,0x91,0x8f,0x92,0x89,0x86,0x8c,0x99 +,0xaa,0x9d,0xaa,0x2f,0x1e,0x1a,0x1e,0x19,0x0e,0x15,0x1c,0x22,0x17,0x1a,0x2c,0xf9,0xc2,0x32,0x21,0x29,0x1c,0x17,0x17,0x15,0x12,0x0b,0x08,0x04,0x06,0x06,0x09,0x0a +,0x23,0xb6,0x3f,0x26,0x1f,0xc6,0x7d,0x21,0x19,0x2a,0xae,0xb2,0x4f,0xc5,0xaa,0xab,0x4e,0x39,0xaf,0x9f,0x9d,0xa2,0x9d,0x98,0x99,0x9e,0x99,0x90,0x95,0xa7,0xb7,0x4f +,0x3f,0x43,0x2c,0x23,0x2d,0xce,0x36,0x26,0x1e,0x25,0x27,0x1a,0x1f,0x40,0xa1,0x93,0x9c,0xa1,0x99,0x9b,0x9a,0x99,0x8e,0x8a,0x8c,0x91,0x9a,0x93,0x91,0x98,0x96,0x8c +,0x8a,0x8a,0x8d,0x8a,0x89,0x8a,0x8f,0x9c,0xaf,0x9f,0x9c,0x5d,0x1e,0x0b,0x0b,0x05,0x03,0x04,0x03,0x06,0x04,0x02,0x04,0x06,0x0a,0x0a,0x08,0x0a,0x07,0x08,0x06,0x06 +,0x07,0x07,0x07,0x08,0x0e,0x18,0x19,0x26,0x4e,0x33,0xd5,0xae,0x97,0x93,0x8f,0x88,0x8c,0x8c,0x91,0x8f,0x8e,0x97,0x99,0xa8,0x9d,0x90,0x98,0x93,0x8f,0x91,0x92,0x96 +,0x8e,0x88,0x88,0x89,0x8b,0x88,0x8a,0x8e,0x96,0x96,0x99,0xa2,0x4c,0x2f,0x2a,0x23,0x1c,0x12,0x10,0x12,0x2a,0x2e,0x3e,0x39,0x2e,0x2c,0x25,0x2f,0x38,0x68,0xcb,0x37 +,0x21,0x14,0x0f,0x0f,0x0e,0x0f,0x0f,0x0f,0x0e,0x0b,0x0e,0x12,0x1b,0x1b,0x18,0x1b,0x19,0x19,0x16,0x15,0x0e,0x10,0x0e,0x0c,0x0b,0x1d,0x55,0x49,0xcc,0xd4,0x9f,0x9c +,0x94,0x8b,0x89,0x88,0x8b,0x92,0x93,0x93,0x8d,0x91,0x9c,0xa0,0xb3,0x4d,0x2f,0x29,0x33,0x32,0x27,0x21,0x21,0x28,0x2b,0x40,0xf8,0x44,0x6e,0xb3,0xa3,0x9e,0xa6,0x8f +,0x98,0xa5,0xa7,0xa1,0x92,0x97,0x97,0xa0,0x94,0x8d,0x92,0x96,0x92,0x8f,0x8a,0x8a,0x88,0x8b,0x90,0x96,0xaa,0xc1,0x49,0x3c,0x18,0x12,0x09,0x0d,0x0b,0x08,0x07,0x06 +,0x08,0x05,0x0c,0x0e,0x1d,0x21,0x25,0x1f,0x1e,0x27,0x36,0x26,0x1b,0x19,0x18,0x2b,0x21,0x28,0x44,0xab,0xaf,0xb0,0x97,0x9b,0x99,0x9f,0xa6,0xa1,0xa4,0x9f,0xae,0xc9 +,0x2c,0x25,0x2c,0x24,0x1e,0x2a,0x27,0x28,0x2f,0xb2,0x9f,0xc2,0xae,0xa4,0x97,0x8f,0x93,0x9a,0xa0,0xb4,0xa7,0xc1,0xb4,0xad,0xaf,0xcf,0x2a,0x2e,0x3d,0xb8,0xde,0x34 +,0x26,0x76,0xd7,0xbe,0xb5,0xa8,0xae,0xe4,0xb5,0xba,0xa1,0x9f,0xa0,0xa9,0xac,0x8f,0x8f,0x98,0xa0,0xad,0xa7,0xbf,0xd8,0x37,0x3d,0xc5,0x1b,0x18,0x1f,0x25,0x2b,0x16 +,0x20,0x25,0x27,0x46,0x25,0x22,0x1f,0x1d,0x25,0x27,0x2a,0x25,0x1c,0x14,0x0d,0x15,0x18,0x1d,0x16,0x1e,0x4d,0x3c,0xe2,0x4a,0xc3,0x48,0x24,0x1f,0x21,0x3b,0x30,0x20 +,0x23,0x25,0xf2,0x66,0xcd,0xa5,0xa7,0x98,0x91,0x8c,0x89,0x8e,0x94,0x9a,0x96,0x99,0xad,0xb4,0x3f,0x30,0x23,0x27,0x29,0x47,0xaf,0xb4,0xaa,0xa2,0x8f,0x8d,0x8e,0x8e +,0x91,0x8d,0x8b,0x90,0x94,0x96,0x9d,0xb1,0xa8,0xa1,0xae,0xb4,0x42,0x30,0x2e,0x5a,0xcb,0x2e,0x20,0x1e,0x18,0x15,0x15,0x0f,0x0e,0x0a,0x08,0x0e,0x16,0x1b,0x1b,0x25 +,0x30,0x5b,0xaf,0xad,0xb7,0xab,0xbb,0xb8,0xa0,0x9e,0xa8,0x2e,0x24,0x25,0x1e,0x1d,0x19,0x1b,0x1d,0x1a,0x22,0x2a,0x2c,0x33,0x52,0xbd,0xac,0xa8,0xa5,0xa9,0x96,0x8b +,0x8d,0x8b,0x89,0x89,0x90,0x94,0x8f,0x96,0xa4,0xbb,0x4d,0x29,0x16,0x0f,0x0e,0x09,0x04,0x03,0x06,0x08,0x07,0x07,0x0a,0x0c,0x0f,0x16,0x17,0x17,0x19,0x1e,0x28,0x2e +,0x36,0x75,0xcc,0xba,0xab,0x9a,0x90,0x92,0x8f,0x8e,0x8c,0x86,0x84,0x85,0x87,0x87,0x88,0x89,0x89,0x8b,0x94,0xab,0xb6,0xb1,0xaf,0xa6,0xac,0xae,0xaf,0xae,0x9e,0x9f +,0xa9,0xba,0xbf,0xba,0xb8,0xb1,0xdc,0x2e,0x1e,0x17,0x19,0x19,0x14,0x11,0x12,0x14,0x14,0x1b,0x28,0x21,0x1a,0x19,0x19,0x19,0x1b,0x19,0x16,0x10,0x0c,0x0c,0x0f,0x0f +,0x0e,0x0f,0x11,0x17,0x1c,0x27,0x32,0xe9,0xbf,0xd9,0xa8,0x97,0x9a,0x9b,0x9b,0x9a,0x99,0x98,0x92,0x90,0x92,0x97,0x9a,0x8e,0x8c,0x98,0xa7,0xaa,0xac,0xd0,0x39,0x2d +,0x27,0x20,0x1a,0x21,0x30,0x34,0x31,0x32,0x4d,0xb3,0x9a,0x8e,0x8a,0x88,0x88,0x87,0x86,0x86,0x85,0x85,0x84,0x88,0x8a,0x87,0x88,0x8a,0x8d,0x94,0x9c,0xa7,0xac,0xcc +,0x23,0x12,0x0c,0x0b,0x08,0x04,0x02,0x02,0x01,0x00,0x01,0x01,0x03,0x04,0x04,0x06,0x07,0x0c,0x12,0x10,0x11,0x15,0x1d,0x22,0x23,0x2a,0x30,0x26,0x1c,0x1e,0x2d,0x4c +,0xc4,0xbb,0xb0,0xa5,0x9b,0x92,0x95,0x9a,0x9b,0x98,0x93,0x94,0x96,0x95,0x93,0x9f,0xaa,0x9b,0x94,0x91,0x8f,0x8f,0x8e,0x89,0x84,0x85,0x88,0x87,0x86,0x87,0x8b,0x8e +,0x92,0x97,0xab,0x39,0x35,0x43,0x26,0x1a,0x13,0x13,0x11,0x14,0x17,0x10,0x0e,0x0d,0x10,0x16,0x16,0x15,0x14,0x0f,0x0f,0x13,0x16,0x1b,0x21,0x24,0x1f,0x23,0x47,0xbd +,0x5c,0x2c,0x2d,0x35,0x36,0x30,0x28,0x2e,0x1e,0x13,0x13,0x16,0x18,0x18,0x1b,0x1d,0x1d,0x2d,0xc5,0xec,0x2f,0x3b,0xbf,0xb4,0xaa,0xa8,0xa6,0xa5,0xa8,0x9c,0x95,0x8f +,0x8f,0x8f,0x8e,0x8c,0x89,0x84,0x85,0x87,0x89,0x8a,0x8a,0x8a,0x89,0x8b,0x8d,0x92,0x92,0x91,0x96,0x98,0x95,0x94,0x9c,0x9e,0x94,0x99,0xaa,0x58,0x34,0x26,0x1d,0x14 +,0x0d,0x0b,0x06,0x03,0x04,0x04,0x04,0x03,0x02,0x03,0x03,0x07,0x08,0x05,0x05,0x06,0x07,0x09,0x0c,0x0c,0x0c,0x0a,0x0b,0x15,0x1b,0x24,0x62,0xaf,0x9e,0x9d,0x8f,0x8a +,0x8b,0x8a,0x8c,0x89,0x88,0x89,0x89,0x8b,0x8e,0x97,0x9a,0x97,0x98,0x9a,0x9e,0x9e,0x97,0x90,0x8d,0x91,0x92,0x91,0x92,0x91,0x90,0x90,0x93,0x9a,0x9f,0xa1,0xa7,0xa6 +,0xa9,0xaf,0xb9,0xcc,0x67,0xba,0xe5,0x2e,0x27,0x22,0x1d,0x1a,0x18,0x15,0x0e,0x08,0x09,0x0b,0x0c,0x0b,0x0c,0x0c,0x0d,0x0f,0x18,0x19,0x13,0x16,0x19,0x1b,0x1f,0x1f +,0x1e,0x1d,0x15,0x19,0x1f,0x30,0x2e,0x2a,0x34,0x2d,0x31,0xc3,0xcd,0x5a,0x4f,0x51,0x50,0x4c,0x3e,0x29,0x1f,0x16,0x1e,0x4c,0xbc,0xaa,0xa2,0x99,0x95,0x8f,0x87,0x86 +,0x85,0x85,0x84,0x83,0x82,0x82,0x83,0x83,0x85,0x88,0x88,0x89,0x88,0x89,0x8c,0x8f,0x91,0x8f,0x98,0xba,0x36,0x1d,0x14,0x0d,0x0a,0x09,0x05,0x02,0x02,0x03,0x03,0x02 +,0x02,0x03,0x03,0x05,0x0a,0x0c,0x0b,0x0b,0x0c,0x0f,0x15,0x16,0x11,0x0f,0x14,0x1c,0x22,0x2b,0x2f,0x45,0x5f,0xd1,0xa8,0xa0,0xab,0xac,0xa4,0x9c,0x9b,0x9d,0x9e,0xa5 +,0xa0,0x9b,0x9b,0x98,0x99,0x98,0x93,0x8d,0x88,0x8a,0x8b,0x8b,0x8a,0x89,0x8a,0x8b,0x8d,0x91,0x91,0x8e,0x8e,0x8f,0x94,0x98,0x9f,0xa5,0x9e,0xac,0xca,0x45,0x33,0x27 +,0x1e,0x1c,0x16,0x0e,0x0a,0x0a,0x0d,0x10,0x11,0x13,0x17,0x18,0x24,0x2f,0x26,0x1f,0x20,0x25,0x24,0x2d,0x2b,0x27,0x1c,0x12,0x17,0x18,0x1b,0x1b,0x18,0x18,0x1b,0x2e +,0x3b,0x25,0x20,0x1f,0x1e,0x23,0x23,0x21,0x1e,0x16,0x14,0x19,0x22,0x2f,0x32,0x59,0xb8,0xa3,0x90,0x8b,0x8b,0x8c,0x8b,0x88,0x86,0x85,0x84,0x84,0x86,0x88,0x88,0x87 +,0x88,0x88,0x89,0x89,0x89,0x87,0x86,0x8b,0x8f,0x95,0x9c,0xa7,0xbf,0x3f,0x2b,0x1a,0x0f,0x0e,0x0d,0x0b,0x09,0x08,0x08,0x06,0x0a,0x0c,0x0a,0x09,0x08,0x08,0x09,0x0a +,0x09,0x08,0x07,0x04,0x06,0x09,0x0a,0x0d,0x0f,0x12,0x16,0x1f,0x2e,0x2f,0x2e,0x34,0x4c,0xab,0x9f,0x9f,0x9d,0x9f,0x9e,0x98,0x93,0x91,0x8f,0x8d,0x8d,0x8c,0x88,0x87 +,0x89,0x8d,0x8e,0x8e,0x8f,0x92,0x97,0x9e,0xa2,0x9f,0x9d,0x9a,0x9a,0x9b,0x9e,0xa1,0x9b,0x96,0x9a,0x9f,0xa3,0xa0,0xa6,0xb4,0xe0,0x2d,0x1f,0x1e,0x1f,0x1e,0x1f,0x22 +,0x1e,0x1e,0x2b,0x2f,0x23,0x1c,0x1b,0x19,0x17,0x16,0x15,0x0f,0x0d,0x0e,0x0f,0x0f,0x0e,0x0e,0x0f,0x14,0x1c,0x27,0x23,0x1e,0x1f,0x27,0x2c,0x2c,0x2a,0x28,0x1d,0x20 +,0x2b,0x2d,0x38,0x40,0x56,0x5f,0xb5,0x9f,0xa4,0xaa,0xa5,0xa1,0x9b,0x96,0x95,0x90,0x94,0x98,0x92,0x8d,0x8a,0x89,0x88,0x87,0x86,0x84,0x83,0x83,0x84,0x85,0x85,0x87 +,0x87,0x89,0x8d,0x95,0xa4,0xac,0xaf,0xcc,0x3b,0x21,0x18,0x12,0x12,0x15,0x0e,0x09,0x08,0x07,0x06,0x05,0x05,0x04,0x03,0x01,0x02,0x03,0x04,0x04,0x05,0x08,0x0a,0x0e +,0x15,0x14,0x17,0x19,0x1d,0x25,0x3a,0xe9,0xd0,0xee,0x53,0xc8,0xa7,0x9f,0x9f,0x9d,0x99,0x94,0x8e,0x8b,0x8c,0x8e,0x8f,0x8e,0x90,0x90,0x93,0x96,0x9e,0xa4,0x9f,0x9c +,0x98,0x98,0x99,0x97,0x96,0x91,0x8e,0x8f,0x8e,0x8f,0x8f,0x8f,0x91,0x94,0x9b,0xb5,0xe4,0xd7,0xd1,0x5a,0x3e,0x39,0x2d,0x2f,0x4e,0x34,0x21,0x1a,0x15,0x14,0x13,0x14 +,0x10,0x0c,0x0c,0x0c,0x0c,0x0c,0x0b,0x0c,0x0c,0x10,0x1c,0x1e,0x1d,0x1e,0x1f,0x1f,0x20,0x22,0x1c,0x15,0x18,0x21,0x2a,0x2c,0x28,0x2b,0x2f,0x40,0xce,0x54,0x3f,0x44 +,0x53,0xdd,0xe4,0xcc,0xc8,0x3f,0x48,0xae,0xa0,0x9d,0x9a,0x94,0x8d,0x89,0x85,0x83,0x84,0x83,0x83,0x83,0x83,0x83,0x83,0x85,0x88,0x8b,0x8b,0x8b,0x8c,0x90,0x97,0x9c +,0xa4,0xaa,0xd0,0x2c,0x1c,0x16,0x11,0x0d,0x0b,0x08,0x05,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04,0x06,0x0a,0x0b,0x0b,0x0b,0x0b,0x0f,0x14,0x17,0x1b,0x1c,0x17,0x1a +,0x23,0x32,0x4c,0xfe,0xc5,0xaf,0x9e,0x95,0x96,0x96,0x97,0x98,0x93,0x91,0x91,0x93,0x98,0x9f,0xa4,0x9c,0x9b,0x9b,0x9a,0x99,0x93,0x92,0x8e,0x8d,0x8e,0x8f,0x8e,0x8e +,0x8d,0x8e,0x8f,0x93,0x98,0xa0,0xa0,0xad,0xa6,0xab,0xd6,0xbb,0x1f,0xb0,0x86,0x8c,0x02,0x1b,0x82,0x1e,0x3d,0x1e,0x0b,0x0b,0x06,0x08,0x04,0x0e,0x00,0x03,0x03,0x00 +,0x06,0x02,0x05,0x03,0x02,0x08,0x06,0x0b,0x0f,0x09,0x08,0x10,0x18,0x1d,0x6f,0xee,0x9e,0x97,0xa5,0x94,0x83,0x80,0x89,0x8b,0x84,0x80,0x81,0x85,0x84,0x87,0x8a,0x87 +,0x85,0x82,0x85,0x81,0x84,0x83,0x85,0x89,0x84,0x8b,0x8d,0x8f,0x95,0x9e,0x9c,0x9f,0xbb,0x40,0x34,0x26,0x0e,0x13,0x0a,0x09,0x0a,0x06,0x06,0x05,0x05,0x03,0x04,0x03 +,0x02,0x01,0x02,0x01,0x01,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x07,0x05,0x06,0x05,0x08,0x0c,0x0a,0x0d,0x0f,0x19,0x16,0x1b,0x25,0x28,0x2f,0x47,0x4a,0xac,0x97,0x91 +,0x92,0x8f,0x8a,0x8a,0x87,0x85,0x84,0x84,0x84,0x82,0x83,0x82,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x82,0x81 +,0x84,0x83,0x85,0x88,0x8b,0x8c,0x8c,0x93,0x9a,0xa6,0xa3,0xfb,0x26,0x13,0x18,0x0e,0x0b,0x07,0x03,0x07,0x03,0x03,0x01,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00 +,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x04,0x03,0x02,0x04,0x04,0x04,0x05,0x05,0x09,0x0b,0x0a,0x0a,0x10,0x14,0x0d,0x10,0x1c,0x26,0x2b,0x2b +,0x6d,0xce,0xbc,0xae,0xa6,0x94,0x8f,0x8b,0x86,0x84,0x84,0x83,0x83,0x82,0x83,0x82,0x81,0x80,0x81,0x82,0x81,0x81,0x81,0x81,0x82,0x82,0x81,0x82,0x82,0x83,0x82,0x82 +,0x84,0x85,0x85,0x83,0x83,0x85,0x87,0x83,0x86,0x88,0x87,0x87,0x87,0x8c,0x8d,0x8f,0x90,0x95,0x9f,0xac,0xa6,0xaf,0xb5,0x32,0x2a,0x2a,0x1d,0x1b,0x13,0x1a,0x16,0x1b +,0x18,0x14,0x1a,0x1f,0x28,0x29,0x3c,0xb4,0x9f,0xa4,0x9d,0x9b,0x95,0x92,0x96,0x91,0x94,0x91,0x9a,0x9e,0x9f,0xa3,0xaa,0x5a,0xf5,0x2e,0x20,0x13,0x0f,0x0d,0x0a,0x08 +,0x05,0x03,0x03,0x03,0x03,0x02,0x01,0x01,0x01,0x02,0x01,0x02,0x02,0x02,0x01,0x01,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x01,0x01,0x01,0x01 +,0x01,0x01,0x02,0x03,0x04,0x04,0x04,0x07,0x09,0x09,0x0b,0x0f,0x18,0x1e,0x25,0x3a,0xbd,0xa9,0x9f,0x9c,0x93,0x8d,0x8a,0x87,0x85,0x84,0x84,0x83,0x82,0x82,0x82,0x81 +,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x83,0x83,0x84,0x86,0x88 +,0x8a,0x8e,0x90,0x90,0x93,0x9a,0xa7,0xab,0xb3,0x5c,0x4b,0x2b,0x25,0x1f,0x15,0x0e,0x0d,0x0d,0x08,0x07,0x07,0x06,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x02,0x02,0x02 +,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x09,0x0a,0x0b,0x0c,0x0f,0x0f,0x0f,0x11,0x15,0x19,0x16,0x19,0x1c,0x1a,0x1b,0x1a,0x1c,0x1a,0x1b,0x19,0x17 +,0x19,0x17,0x1a,0x1a,0x1d,0x20,0x25,0x2a,0x2a,0x33,0x48,0xf4,0xba,0xaa,0xa0,0x9e,0x9b,0x98,0x97,0x92,0x90,0x8e,0x8e,0x8d,0x8c,0x8d,0x8c,0x8c,0x8c,0x8c,0x8d,0x8d +,0x8e,0x8f,0x92,0x94,0x94,0x96,0x95,0x95,0x95,0x98,0x9d,0x9f,0xa1,0xa4,0xa2,0x9f,0x9f,0xa1,0xa8,0xac,0xb0,0xb5,0xbd,0xbf,0xb6,0xbb,0xc9,0xc6,0xcb,0x58,0x42,0x3e +,0x37,0x32,0x30,0x31,0x2f,0x2f,0x2c,0x27,0x25,0x24,0x25,0x27,0x28,0x2b,0x2e,0x2e,0x29,0x29,0x2c,0x2d,0x35,0x35,0x36,0x3d,0x3e,0x3d,0x47,0xd6,0xc3,0xbe,0xb4,0xaa +,0xa3,0xa9,0xa7,0xa0,0x9f,0x9e,0x9e,0x9f,0x9b,0x9b,0x9d,0x9d,0x9d,0x9d,0x9f,0x9e,0x9e,0x9d,0x9e,0x9f,0xa0,0xa4,0xa6,0xa9,0xa8,0xaa,0xad,0xbb,0xb8,0xaf,0xaf,0xad +,0xad,0xae,0xae,0xaf,0xad,0xad,0xab,0xaa,0xae,0xad,0xa9,0xa9,0xac,0xad,0xad,0xaf,0xb5,0xbb,0xc7,0xd3,0xe1,0x4b,0x37,0x2e,0x29,0x27,0x24,0x22,0x1f,0x1d,0x1c,0x1c +,0x1d,0x1d,0x1d,0x1f,0x23,0x25,0x26,0x27,0x2a,0x2c,0x2f,0x33,0x39,0x42,0x48,0x55,0x5b,0x56,0x61,0x52,0x55,0xd1,0xc7,0xc6,0xce,0xdd,0xeb,0x5f,0x52,0x42,0x3f,0x46 +,0x47,0x46,0x41,0x39,0x37,0x38,0x41,0x45,0x4e,0xfc,0xf1,0xd6,0xce,0xd0,0xec,0xcf,0xb7,0xb5,0xb7,0xb2,0xaf,0xac,0xaf,0xb4,0xb2,0xaf,0xb0,0xb7,0xb9,0xb8,0xbe,0xc6 +,0xd4,0xda,0xda,0x6e,0x59,0x51,0x57,0x5b,0x4d,0x46,0x45,0x55,0x50,0x46,0x48,0x48,0x4f,0x43,0x44,0x48,0x43,0x4f,0x6b,0x5c,0x4c,0x42,0x47,0x43,0x3e,0x3b,0x36,0x37 +,0x33,0x2f,0x2e,0x2c,0x2a,0x2b,0x26,0x27,0x27,0x25,0x27,0x29,0x2d,0x31,0x33,0x31,0x35,0x3e,0x43,0x45,0x4b,0x6a,0xcf,0xcf,0xcc,0xbf,0xbc,0xb3,0xac,0xad,0xae,0xae +,0xab,0xac,0xad,0xad,0xab,0xab,0xad,0xae,0xaf,0xb0,0xb9,0xbe,0xc2,0xbd,0xbc,0xc3,0xc2,0xca,0xe1,0x60,0x44,0x43,0x4a,0x49,0x46,0x44,0x44,0x48,0x45,0x43,0x50,0x61 +,0x6b,0x5d,0x59,0x62,0x69,0x5a,0x4f,0x62,0xdd,0xe0,0xdd,0x66,0x71,0x57,0x4e,0x5a,0x61,0xcd,0xd2,0xe3,0x50,0x61,0x59,0x45,0x4b,0x4b,0x5b,0x5f,0x4f,0x4a,0x4d,0x44 +,0x4d,0x57,0x6d,0x56,0x4a,0x57,0x5c,0xf9,0xe6,0xd7,0xc7,0xc7,0xdb,0xe7,0xd1,0xc8,0xd5,0xe8,0xc8,0xc7,0xd0,0xd1,0xd0,0xca,0xd2,0xcc,0xde,0xdd,0xcc,0xc8,0xc7,0xc8 +,0xc2,0xc0,0xbd,0xbc,0xba,0xba,0xbc,0xc4,0xbe,0xc3,0xce,0xcd,0xcb,0xd0,0xe3,0xe6,0x60,0x59,0x45,0x42,0x4a,0x4d,0x4a,0x41,0x3d,0x42,0x3e,0x3e,0x40,0x42,0x3f,0x44 +,0x66,0x50,0x5f,0xe5,0xc6,0xc8,0xde,0xc6,0xcd,0xcf,0xd9,0xe5,0xe0,0xe6,0xbe,0xd5,0x55,0x49,0x4a,0xde,0x46,0x5c,0x47,0x53,0x7a,0x49,0x5a,0x45,0xe9,0x71,0xd0,0xcf +,0x69,0xcf,0xcd,0xc5,0xd3,0xc6,0xb6,0xbd,0xbb,0xc0,0xbd,0xc2,0xd6,0xcd,0x4b,0x56,0x48,0x54,0x5b,0x40,0x3c,0x34,0x39,0x33,0x2b,0x2e,0x36,0x3e,0x3a,0x3b,0x47,0x3e +,0x48,0x3f,0x3b,0x4b,0xda,0xe7,0xda,0xd8,0xc3,0xbb,0xbd,0xba,0xb8,0xb6,0xbc,0xca,0xc2,0xc4,0x79,0xd4,0xcf,0x51,0x47,0x40,0x5d,0x52,0x36,0x3d,0x39,0x3c,0x3a,0x3d +,0x54,0x50,0x68,0x54,0x39,0x40,0x41,0xf9,0xff,0xe4,0xbb,0xc1,0xb9,0xce,0xbb,0xb2,0xb5,0xb2,0xb4,0xb8,0xc0,0xc4,0xbf,0xc0,0xcb,0xc6,0xcf,0xde,0x53,0x58,0x4d,0x45 +,0x4f,0x51,0x52,0x50,0x4e,0x4f,0x4e,0x44,0x53,0x4f,0x59,0x64,0x57,0xfb,0xc9,0xca,0xc9,0xd9,0xc0,0xc9,0xd1,0xcb,0xdf,0xc0,0xdb,0xcc,0x56,0x4b,0xd2,0xfd,0x5e,0x4d +,0x63,0x4d,0x38,0x41,0x53,0x65,0x5b,0xca,0x4b,0x39,0x46,0x3b,0x48,0x45,0xd4,0x78,0x64,0xc0,0xd3,0xbd,0xd7,0xba,0xca,0xdb,0xbd,0x53,0xbd,0xd6,0xd8,0xc2,0xdd,0xe0 +,0x4d,0x51,0x51,0x3d,0x57,0x4c,0x59,0x41,0x3a,0x49,0x3f,0x3b,0x3f,0x4d,0x3a,0x3d,0x40,0x4c,0x40,0x72,0xd3,0x4b,0x50,0xeb,0x6a,0x3e,0x4a,0xc2,0x7e,0x56,0xd6,0xdc +,0xca,0xde,0xcc,0xdc,0xe9,0xc8,0x58,0x5b,0xdd,0xd2,0xe7,0xcf,0xd1,0x4b,0x49,0x53,0x50,0x48,0x4f,0x4b,0x58,0x5d,0x58,0x5d,0x57,0xe7,0x79,0x4e,0x7c,0x56,0xcf,0x65 +,0x5b,0xc5,0xfb,0xc4,0xde,0x5d,0xc1,0xf3,0xc5,0xca,0xcb,0xba,0x5d,0xbe,0xca,0xc9,0xd9,0xf7,0xca,0x44,0x67,0x56,0x47,0x59,0x46,0xd3,0x69,0x43,0xef,0x36,0x43,0x3f +,0x46,0x4e,0x4c,0xd6,0x4d,0x66,0x6d,0xcd,0xe0,0xf9,0xc0,0xce,0xf4,0xcb,0xcc,0xc1,0xc9,0xe5,0xcd,0x58,0xfc,0x49,0x3f,0x6d,0x54,0x5d,0x49,0x4f,0xfd,0x55,0xf9,0x51 +,0x3f,0x50,0x4e,0x4b,0x7a,0xf6,0xd1,0xce,0xd0,0xe2,0xe0,0xc6,0xd9,0xc5,0xc8,0xbe,0xbf,0xc7,0xc6,0xcd,0xbc,0xd3,0xdc,0xc6,0x66,0x5b,0x4d,0x74,0xfc,0x47,0xf3,0x53 +,0x5c,0x4b,0x3b,0x3a,0x42,0x49,0x3c,0x54,0xeb,0x6e,0xef,0x62,0x61,0xef,0x57,0xe9,0x4d,0xd5,0xba,0xc4,0xbc,0xc4,0xc0,0xdc,0x59,0xdf,0x4f,0x6c,0x7b,0x4e,0x67,0x43 +,0x69,0x59,0x76,0x63,0x3a,0x4a,0x3f,0x3a,0x44,0x64,0x6b,0x60,0x69,0x61,0xf0,0x7a,0xf4,0xcb,0xcb,0xc9,0xd2,0xc8,0xb8,0xcd,0xcf,0xcd,0xc6,0xc9,0xc5,0x47,0xe4,0xcc +,0x66,0xc3,0xf4,0xde,0xf5,0x42,0x3c,0x3e,0x38,0xc4,0x2c,0x3f,0xc6,0xbe,0x40,0x3a,0xc6,0xd9,0xd6,0x5a,0xb2,0x7b,0xb9,0xb8,0xb7,0x54,0xc0,0xbe,0xcf,0xcd,0x43,0xbf +,0x45,0x48,0x49,0x3d,0xd2,0x56,0x4a,0x44,0x56,0xe8,0x38,0x3e,0x35,0x67,0x6f,0xee,0x7b,0xd0,0xc9,0x54,0xd4,0xc8,0xdb,0xce,0xba,0xca,0xbc,0xd8,0xbe,0xed,0xcc,0xca +,0xf4,0xd4,0x49,0xce,0xf5,0xdf,0x56,0xc9,0x46,0x51,0xd3,0x3b,0x3d,0x35,0x3d,0x4c,0x4d,0x5f,0x4e,0xf2,0x61,0xe7,0xd5,0x5b,0xbb,0xcf,0xbd,0xc5,0xbd,0xb8,0xec,0xc9 +,0xdb,0xd7,0xd1,0x56,0xcf,0x6c,0x4d,0x61,0x4b,0xe9,0x4b,0x56,0x55,0x49,0x7b,0x48,0x40,0x44,0x40,0x56,0x44,0x5a,0xcd,0xd9,0xec,0x56,0xcb,0xc5,0x4f,0xc5,0xc2,0xea +,0xc7,0xde,0xbc,0xde,0x5e,0xc5,0x42,0x55,0x4d,0x55,0xc9,0x49,0x58,0x4b,0x47,0x4c,0x47,0x47,0x41,0x4a,0x6c,0x48,0x79,0xe9,0xc8,0xca,0x76,0xbe,0xe1,0xbc,0xd2,0xd8 +,0xbb,0xcb,0xbb,0xc9,0xc9,0xcb,0x67,0x6f,0x60,0x67,0x4d,0x53,0x49,0x4f,0x4b,0x57,0x47,0x6b,0x49,0x49,0x61,0x37,0x77,0x3d,0xde,0x69,0x51,0xbf,0xd8,0xe4,0x63,0xe3 +,0xce,0xd1,0xc7,0xba,0xcd,0xc4,0xce,0xcc,0xc7,0x5e,0xd2,0x47,0x51,0x5f,0x5b,0xc9,0x3e,0x4f,0x69,0x40,0x52,0x3b,0x5e,0xee,0x3b,0xd9,0x4c,0xee,0xe0,0x4f,0xcb,0x6c +,0xc3,0xd9,0x59,0xcf,0xca,0xc7,0xc2,0xc9,0xbe,0xc6,0xce,0x58,0xf8,0xdd,0x4b,0xdf,0x56,0x5f,0x4b,0x43,0x4a,0x4b,0x45,0xf6,0x4c,0x7e,0x62,0x44,0xcd,0x46,0xde,0x75 +,0xd6,0xcb,0xdf,0xc8,0x5f,0xda,0xda,0xef,0xc9,0xcc,0xd4,0xc1,0x5b,0xc6,0x5c,0xcd,0xf2,0x3e,0xd3,0x3b,0xdb,0x4d,0x4f,0x7b,0x58,0x4c,0x63,0x4e,0xdf,0x4e,0x54,0xc6 +,0x48,0xc0,0x4b,0xe8,0xca,0x6d,0xc3,0x59,0xcf,0xcc,0xf8,0xbe,0x65,0xcc,0xcd,0x5c,0xb9,0x4d,0xe7,0x7b,0x43,0xd1,0x46,0xdc,0x4c,0x49,0xd3,0x4a,0xe9,0x66,0x3c,0xf5 +,0x3e,0xd8,0xee,0x57,0xc1,0x45,0xbf,0x5a,0xdf,0xd2,0x5c,0xd4,0xfc,0xec,0xc9,0x7e,0xd7,0xde,0x50,0xbe,0x3c,0xc7,0x64,0x52,0xcd,0x46,0xbc,0x52,0x79,0xdb,0x4f,0xcc +,0x4e,0x4e,0xcb,0x57,0xf3,0x5a,0x66,0xd4,0x3d,0xde,0x4d,0x5f,0xd5,0x42,0xcb,0x5b,0xe9,0xc6,0x76,0xc7,0xe1,0xc8,0xcb,0x55,0xd4,0x53,0x6d,0xce,0x5b,0xd1,0x5c,0x4a +,0xdc,0x45,0x71,0x58,0x4e,0xe5,0x45,0xc9,0x5d,0x6f,0x7e,0x3f,0xce,0x4b,0x5d,0xe2,0x5c,0xc0,0x75,0xce,0xbd,0x6c,0xbf,0x57,0xda,0xcd,0x4d,0xc5,0x52,0xc7,0xc1,0x72 +,0xf1,0x45,0x59,0xde,0x4e,0xe9,0x54,0xf0,0xd6,0x44,0xd3,0x4c,0xfc,0xe4,0x4d,0xd8,0x51,0xdf,0xf7,0x58,0xc6,0x6c,0xcc,0xce,0x4d,0xc1,0xf1,0xd9,0x5d,0x67,0xc9,0x4a +,0xc9,0xe4,0xf0,0xdb,0x4b,0xf2,0x50,0x4e,0xe5,0x4b,0xe1,0xf1,0x54,0xbf,0x4c,0x6b,0x6e,0x5f,0xc7,0x3f,0xde,0x7a,0x64,0xe1,0x4f,0xd4,0x5a,0x59,0xd0,0x4b,0xe6,0x69 +,0x68,0xc1,0x48,0xc3,0xd1,0xdd,0xcd,0x47,0xc8,0x5f,0x52,0xcf,0x55,0xcc,0x68,0x5e,0xca,0x4d,0xcb,0x5b,0x4f,0x7e,0x46,0xd9,0x5d,0x66,0xdf,0x48,0xd9,0x4a,0x6c,0xd0 +,0x45,0xc5,0x57,0xdb,0xd7,0x59,0xc7,0x73,0xd5,0xc9,0x6c,0xcb,0x6f,0x62,0xd6,0x3d,0xc6,0x6e,0x7a,0xd1,0x49,0xcb,0x4d,0xdd,0x51,0x4b,0xd5,0x47,0xf6,0xed,0x4d,0xdf +,0x5c,0x68,0xd7,0x4c,0xc6,0x45,0xd6,0xca,0x4f,0xb5,0x4f,0xcf,0xcf,0xd8,0xc7,0x4c,0x7d,0x69,0x4b,0xd8,0x4d,0xea,0xd3,0x4a,0xc4,0x43,0xcc,0x5f,0x4e,0xca,0x40,0xcf +,0x61,0x63,0xd2,0x51,0xc9,0x6e,0x4c,0xca,0x4e,0xca,0xee,0x5a,0xd9,0x61,0xc4,0xe5,0xfb,0xcf,0x43,0xf9,0xd1,0x6a,0xbe,0x49,0xce,0xe6,0x70,0xcf,0x3e,0xc9,0x63,0x59 +,0xef,0x47,0xdc,0x4e,0x4a,0xd3,0x4e,0xcc,0x4d,0x48,0xdf,0x48,0xd8,0x55,0xcc,0xcb,0x71,0xc4,0xe7,0xd0,0xcb,0x68,0xd8,0x68,0xdd,0xcb,0x58,0xc5,0x52,0xf0,0xe2,0x40 +,0xcd,0x3f,0x75,0x6e,0x42,0xd0,0x46,0x5d,0x4e,0x3e,0xd3,0x46,0xd9,0x6a,0x44,0xbd,0x4c,0xc8,0xde,0xdb,0xbc,0x58,0xc4,0xd5,0xef,0xc2,0x70,0xca,0xd1,0x4c,0xbf,0x48 +,0xcf,0x6d,0x45,0xc9,0x3d,0x70,0x4b,0x41,0x6b,0x38,0x5a,0x77,0x3e,0xc5,0x3e,0xde,0xdb,0x4a,0xbd,0x49,0xbb,0xe4,0xe0,0xb9,0x51,0xbc,0xcb,0x66,0xc0,0x56,0xc5,0xe3 +,0x57,0xbc,0x45,0xcc,0xf5,0x44,0xc9,0x3f,0xea,0x4d,0x3d,0xd7,0x3b,0xee,0x4c,0x46,0xd6,0x40,0xd2,0x4e,0x56,0xc6,0x3f,0xc0,0xca,0xde,0xb9,0x58,0xbc,0xd4,0xce,0xbb +,0x52,0xbb,0xfd,0x69,0xc6,0x4a,0xcc,0x68,0x54,0xec,0x41,0x76,0x42,0x42,0xf1,0x39,0x62,0x4f,0x3f,0xe5,0x3c,0xd0,0x4b,0x5f,0xc0,0x4f,0xb9,0xe4,0xda,0xcd,0x60,0xc1 +,0xee,0xf0,0xc1,0x69,0xbd,0xe1,0xf5,0xc3,0x42,0xc2,0x4e,0x6e,0xde,0x4a,0xca,0x3f,0x5c,0x5d,0x3e,0xef,0x3f,0x51,0x5d,0x36,0xd6,0x45,0x5e,0xd7,0x40,0xb9,0x62,0xd7 +,0xc8,0x5f,0xb8,0x75,0xbf,0xbb,0xdd,0xba,0xe5,0xc6,0xc9,0x5b,0xd6,0x42,0x65,0xff,0x40,0xd8,0x3e,0x4b,0x5c,0x3d,0xf3,0x3a,0x4c,0x4e,0x47,0xcf,0x3f,0xd8,0xc8,0x58 +,0xc3,0xd7,0xc2,0xc7,0xdb,0xbc,0x7e,0xbf,0xca,0x67,0xbf,0x6e,0xd9,0xdc,0x5c,0xdc,0x4b,0xd6,0x5a,0x42,0xd8,0x3f,0xee,0x5e,0x41,0x6e,0x3f,0x5b,0x47,0x41,0xcd,0x49 +,0xce,0xea,0x49,0xbe,0x5b,0xc6,0xee,0xd5,0xbb,0xec,0xbe,0xd6,0xcd,0xc4,0x79,0xd4,0x79,0x5c,0xd4,0x3e,0x4d,0x48,0x4e,0xe5,0x3e,0xd1,0x5b,0x62,0x63,0x44,0xe6,0x5c +,0x4a,0xec,0x50,0xee,0xd8,0x51,0xc9,0x51,0xc6,0xd5,0xf2,0xbc,0x61,0xc1,0xd6,0xec,0xc6,0x67,0xda,0x59,0x71,0xdc,0x3b,0xd1,0x57,0x40,0xd6,0x56,0xd7,0x53,0x6b,0x6c +,0x45,0xeb,0x50,0x4e,0xd9,0x4e,0x79,0x74,0x62,0xd1,0x4e,0xc5,0x61,0xfe,0xc0,0x6d,0xc8,0xcf,0x75,0xbf,0x57,0xda,0xe7,0x55,0xc6,0x3f,0xd3,0x4c,0x6f,0xea,0x40,0xc9 +,0x4a,0x44,0xf9,0x4a,0xcd,0x4d,0x5b,0xda,0x44,0xc5,0x60,0xd1,0xcd,0x78,0xcb,0x6d,0xdc,0xd7,0xdd,0xd0,0x70,0xf5,0xd3,0x5b,0x5c,0x57,0x6e,0xdb,0x46,0xd8,0x64,0x61 +,0x6a,0x47,0xd0,0x59,0xda,0xe7,0x49,0xcb,0x65,0x64,0x4e,0x53,0xbf,0x64,0xe2,0x72,0x71,0xd2,0x69,0xc6,0xd2,0x54,0xd6,0x4e,0xc1,0xc5,0xb2,0xfa,0x2b,0xd0,0x41,0x4a +,0xdf,0xbe,0xc4,0x3c,0x3b,0x78,0x48,0x47,0xcf,0x64,0xf0,0x78,0x76,0xde,0x5e,0xd4,0xd3,0xce,0x5f,0xf0,0xc5,0x4d,0xd8,0x58,0xe6,0xe7,0x42,0x5a,0x77,0x6c,0x54,0x4f +,0x67,0xdb,0x55,0x5d,0x5a,0xda,0x66,0x6e,0xc6,0xcb,0xcf,0x67,0xcc,0xf1,0xfe,0x78,0x6b,0xee,0x68,0x6a,0x56,0xd3,0x6d,0xd3,0x4e,0x47,0x55,0x4c,0xd6,0x4d,0xfa,0xf1 +,0xe0,0xd0,0x70,0xd4,0xeb,0xeb,0xe3,0xe5,0x69,0x7b,0xbe,0xd2,0x4c,0xdb,0xce,0xd0,0xe6,0x5e,0x4c,0x5a,0xee,0x4f,0xe0,0xe0,0x56,0x4d,0xe7,0x44,0x66,0x7e,0x43,0xf4 +,0x51,0xd7,0x44,0xc7,0xc8,0xde,0xd6,0x5e,0xbe,0xe5,0xc3,0xc2,0x6b,0xe9,0xe7,0x5d,0xbe,0x5d,0xfb,0x59,0x4c,0xfc,0x67,0x64,0x43,0xc9,0x55,0x56,0xf0,0x55,0x73,0x7e +,0x62,0xe9,0xec,0xe0,0x5d,0x5d,0x58,0x6d,0x59,0xcb,0xef,0xda,0xc9,0x47,0xef,0xc5,0xbd,0x6f,0xc6,0x3e,0x4d,0xbc,0x71,0xdf,0x4e,0xe7,0x4d,0x3e,0xb9,0xea,0x68,0x4c +,0xde,0x5d,0x3f,0xf2,0xcb,0x65,0x3f,0xe9,0x4b,0x63,0xd7,0xdd,0x4a,0xda,0x3d,0xc3,0xc9,0x45,0xed,0xcb,0xdd,0xcf,0xc3,0xd8,0xda,0x70,0xd0,0x4d,0xbc,0xd1,0x4e,0xe3 +,0x46,0xdb,0x46,0xce,0xac,0xb4,0xa6,0x2f,0x2e,0x33,0x3e,0xfb,0x14,0x15,0x3b,0x99,0x90,0x2c,0x0c,0x17,0xfb,0x98,0x91,0x98,0xa3,0xbf,0x2e,0x1b,0x26,0x9d,0x8f,0xd0 +,0x22,0xb3,0x9c,0xd8,0x34,0x6f,0xad,0x96,0x22,0x0e,0x74,0x26,0x0a,0x0d,0x21,0x92,0x8c,0xa9,0x24,0x18,0xbe,0x93,0x89,0x93,0xdb,0xe8,0xbb,0x2a,0x13,0x26,0x9a,0x98 +,0xa1,0x2a,0x0f,0xd1,0xa6,0x1b,0x06,0x04,0xcf,0x87,0x98,0x19,0x18,0x9f,0x9b,0x53,0xd6,0x8f,0x8c,0x94,0xf5,0x29,0x39,0x41,0xd5,0x1b,0x17,0x1f,0x9e,0x9a,0x3a,0x0d +,0x0b,0x29,0x9f,0x9d,0x99,0xa4,0x33,0x35,0x1b,0x2c,0xa7,0x8f,0xa4,0x2f,0x37,0xa7,0x9b,0xb3,0x32,0xda,0x9d,0x24,0x13,0x2e,0x5d,0x17,0x0c,0x1f,0x9f,0x8d,0x9a,0x29 +,0x1a,0x1f,0xa6,0x8c,0x91,0xb2,0x2d,0x5d,0x6f,0x18,0x2e,0xa3,0x97,0xab,0x28,0x25,0x3e,0x9d,0x3a,0x09,0x07,0x18,0x8f,0x8c,0x35,0x1c,0x3d,0x9c,0xa1,0x30,0x9c,0x8b +,0x91,0xb5,0x2e,0x2b,0x30,0xf1,0x1b,0x17,0x1e,0xab,0x99,0xa1,0x19,0x07,0x1b,0xb3,0x98,0x99,0xa9,0x59,0x24,0x1e,0x40,0xb1,0x8b,0x9d,0xe2,0x36,0x31,0x98,0xac,0xc8 +,0x4b,0xc7,0xb9,0x17,0x1a,0xfe,0x25,0x16,0x0f,0x39,0x90,0x9f,0xf4,0x23,0x1d,0xaf,0x9a,0x8e,0xa2,0x29,0xf9,0x66,0x40,0x31,0xae,0x97,0xb8,0x2f,0x27,0x35,0xa7,0x67 +,0x1a,0x06,0x0b,0xa8,0x8f,0x9c,0x29,0x2c,0xad,0xbb,0x50,0xa1,0x8e,0x8e,0xcc,0x37,0x23,0x2c,0x66,0x29,0x2b,0x1e,0xc0,0x97,0xae,0x1f,0x0a,0x17,0x4a,0xba,0x92,0x9e +,0xb9,0x2f,0x19,0x41,0xb6,0x92,0x90,0xbe,0x29,0x20,0x9d,0x95,0xc1,0x30,0x37,0x5b,0x1e,0x1a,0x46,0x53,0x25,0x13,0x1e,0xa5,0x99,0xab,0x5f,0x22,0x28,0x9f,0x99,0x9c +,0x47,0x40,0xba,0xd0,0xc1,0xad,0x9f,0xbe,0x41,0x45,0x32,0xb9,0xae,0x19,0x09,0x06,0x1e,0x96,0x8f,0xa6,0x36,0x47,0x5e,0x37,0xad,0x90,0x90,0x9d,0x34,0x20,0x2a,0x3b +,0x3a,0x29,0x2f,0xd3,0xa1,0xa5,0x57,0x1a,0x12,0x24,0xcf,0xa0,0x9a,0xab,0x3e,0x1b,0x1e,0xb9,0x95,0x96,0xa8,0x2b,0x24,0xeb,0xab,0xa0,0x38,0x2b,0x20,0x1f,0x24,0x33 +,0xae,0x4a,0x1f,0x1d,0x57,0x99,0x92,0xa2,0x4c,0x29,0xc3,0x9b,0x9d,0xaf,0x3a,0x46,0x43,0x2f,0x2d,0xc9,0x3b,0x2b,0x26,0x24,0xba,0xbc,0x39,0x11,0x0c,0x1f,0x9d,0x88 +,0x8a,0xa2,0xc4,0x4b,0xcc,0xa5,0x9c,0x96,0xaa,0x28,0x15,0x0f,0x14,0x1d,0x1c,0x2f,0x2e,0xc2,0x9a,0xab,0xbf,0x2c,0x2f,0xa9,0xa4,0x90,0x95,0xb0,0x47,0x1e,0xb8,0xae +,0xa5,0xbf,0x18,0x1e,0x18,0x1f,0x35,0x5a,0x3d,0x1a,0x25,0xb8,0xb1,0x9b,0x9b,0xaa,0xe2,0x27,0x97,0x8d,0x98,0xbf,0x24,0x2e,0x21,0x34,0x3d,0x23,0x23,0x17,0x13,0xd3 +,0xbf,0x3d,0xac,0xa3,0x9a,0xba,0x9d,0x9c,0x25,0x15,0x16,0xa9,0x96,0x95,0x95,0x41,0x1f,0x17,0x1f,0xab,0xca,0x5c,0x13,0x24,0x58,0x12,0xbd,0x9f,0x9b,0xa7,0xba,0x8f +,0xa1,0xb3,0xd4,0x28,0x33,0x1e,0xaa,0xad,0x2d,0x1e,0x11,0x20,0x29,0x76,0x1d,0xd0,0x9a,0x27,0x9b,0x93,0x91,0xa1,0x25,0x9f,0x29,0x4e,0x9a,0xa8,0xac,0x0c,0x20,0x57 +,0x49,0xaa,0x1e,0x20,0x0e,0x11,0x11,0xe4,0x8f,0xd9,0x95,0x98,0x96,0x9f,0xc2,0x8d,0xb5,0xb1,0xa2,0xda,0xa0,0x11,0x0f,0x0f,0x0e,0xe6,0x4d,0xbe,0x1f,0x11,0x0e,0xd4 +,0x98,0x9f,0x8b,0x92,0x98,0x7e,0x28,0x95,0x6c,0xcd,0xa0,0x39,0xa1,0x29,0xa9,0xcb,0x0f,0x16,0x0c,0x18,0x1b,0x13,0x15,0xa1,0xa7,0x7d,0x8e,0x8e,0x92,0xa6,0xa1,0x8f +,0xc7,0xac,0x9e,0x2b,0x2c,0x18,0xc1,0xef,0x22,0x3f,0x0f,0x0a,0x0e,0x1b,0x18,0x97,0x9d,0x25,0xa2,0xac,0x92,0x9b,0xa7,0x89,0xb3,0x5c,0x98,0x58,0x9d,0x4b,0xad,0xac +,0x18,0x2b,0x0c,0x09,0x05,0x08,0x0c,0xb4,0x8a,0xbe,0x9b,0x96,0x9e,0x9a,0xaf,0x8a,0x98,0x27,0xa2,0xec,0xef,0xc3,0x4e,0xa5,0x1c,0x22,0x2b,0x22,0x1f,0x0e,0x0c,0x0c +,0xa9,0x47,0xd7,0x8d,0x9a,0x99,0xc7,0x9f,0x8f,0x3f,0xa5,0x9d,0xc3,0x9f,0x3b,0xae,0x2d,0x12,0x1f,0x17,0x27,0x22,0x17,0x0c,0x2f,0xa2,0x32,0x91,0x8f,0x9f,0xa8,0x17 +,0xa8,0xa7,0x27,0x8e,0xa1,0xa4,0xad,0x30,0x99,0x2c,0x3a,0x60,0x1d,0x21,0x0e,0x0e,0x06,0x27,0x42,0x1f,0x8e,0x98,0x94,0x9b,0x3c,0x8e,0xb8,0xdc,0x8f,0xa9,0xab,0x43 +,0x4e,0x9f,0x2f,0x2e,0x49,0x17,0x12,0x0f,0x18,0x12,0xa9,0x4c,0x18,0xa3,0xd0,0x9e,0xa8,0xbb,0x8d,0xb6,0xcd,0x91,0xa8,0x9d,0xab,0xc3,0xa4,0x2c,0x3b,0x37,0x11,0x11 +,0x0d,0x13,0x0e,0x9c,0xa9,0x18,0x96,0xa2,0x97,0xa5,0x27,0x94,0x2a,0x18,0x99,0xa9,0x98,0xa4,0xa2,0xa0,0x2d,0xba,0xb6,0x1f,0x1b,0x0d,0x16,0x06,0x4b,0x9c,0x0f,0xa4 +,0xad,0xa1,0x9e,0x2e,0x93,0x9d,0x1f,0x91,0x9c,0xa3,0xa8,0xc6,0x9f,0x35,0x32,0xb5,0x1f,0x16,0x0c,0x0f,0x0c,0x19,0x8a,0x3d,0x56,0xa4,0x60,0xab,0x27,0xb0,0x92,0x34 +,0xa0,0x98,0xa0,0x9c,0xb0,0x96,0xa8,0x2f,0x48,0x2b,0x14,0x0d,0x0b,0x11,0x0a,0x97,0x9c,0x28,0x95,0xab,0x9c,0xbb,0x2e,0x99,0x3c,0x1b,0xc7,0xbc,0x9f,0xab,0x9c,0x97 +,0xb0,0xe1,0xb8,0x39,0x26,0x0e,0x17,0x0d,0x10,0x8d,0x27,0x46,0x9d,0xba,0xa7,0x1d,0xb2,0x93,0x1b,0xcb,0x9b,0xa7,0xa0,0x48,0x97,0x9f,0x26,0xb5,0xce,0x1f,0x13,0x0e +,0x15,0x08,0x98,0x8d,0x2d,0x9c,0xaf,0xa9,0x1f,0x17,0x9a,0x5d,0x1e,0xa1,0xac,0x9d,0xa7,0x9c,0x8f,0xb3,0x57,0x6d,0x2f,0x18,0x0a,0x0e,0x0e,0x12,0x8c,0xb9,0xc7,0x91 +,0xae,0xa1,0x1e,0x28,0x97,0x1e,0x1b,0xab,0xb8,0x9b,0xb6,0x95,0x92,0x68,0xdb,0xab,0xe4,0x1b,0x0d,0x1f,0x0c,0x12,0x8e,0x32,0xac,0x9f,0xf0,0xcb,0x15,0x47,0x9d,0x1e +,0xc9,0x9a,0xa4,0x9e,0xb5,0x93,0x9e,0x47,0xb7,0xb0,0x2c,0x16,0x0d,0x1c,0x09,0x37,0x8a,0x3b,0xa0,0xad,0x57,0x32,0x0d,0x4b,0xa4,0x1b,0xaa,0x98,0x9b,0x9a,0x9e,0x8c +,0x9f,0x37,0xdb,0x47,0x1a,0x0b,0x0c,0x1d,0x08,0xaf,0x8d,0x35,0x94,0xa0,0xab,0x3d,0x14,0xbb,0x3e,0x14,0xaf,0xa7,0xa5,0x9e,0x9b,0x8d,0xb7,0xe7,0x9f,0x60,0x20,0x15 +,0x17,0x1c,0x06,0x9c,0x9a,0x1c,0x98,0x45,0xbd,0x20,0x13,0x9f,0x3c,0x28,0x99,0x9f,0x9a,0xa6,0x9a,0x95,0xd4,0xc2,0xc3,0x3e,0x1e,0x11,0x1a,0x1a,0x0d,0x8e,0xa3,0x2b +,0x9e,0x2e,0xf1,0x18,0x17,0xa8,0x3e,0x3b,0x96,0x9e,0x95,0xa0,0x95,0x95,0x45,0x47,0x5c,0x27,0x14,0x0c,0x19,0x14,0x0e,0x8a,0xaa,0xce,0x99,0xb4,0xa7,0x1a,0x22,0xa8 +,0x2a,0x23,0xa8,0xb1,0x9e,0xac,0x9b,0x98,0xb4,0xaf,0xad,0x38,0x28,0x0f,0x18,0x0f,0x0e,0x8c,0x36,0x4a,0x9f,0x68,0xaf,0x1a,0x30,0x9f,0x28,0xd0,0x9f,0xab,0x9b,0xb8 +,0x96,0x9e,0xdd,0xca,0xd8,0x2f,0x1c,0x0e,0x23,0x10,0x1e,0x89,0x37,0xcd,0xa9,0xbe,0xdc,0x12,0x2f,0xab,0x1f,0xcd,0x9f,0x9e,0x98,0x9f,0x8f,0xa2,0x6d,0x57,0x40,0x18 +,0x0f,0x0d,0x1b,0x0c,0x4e,0x87,0x35,0xa1,0x96,0xa2,0x41,0x15,0x4c,0xd3,0x13,0x40,0xa3,0xb6,0x9f,0x9f,0x8f,0x9b,0xbe,0xa6,0xbd,0x1d,0x13,0x0f,0x1d,0x09,0xc2,0x8c +,0x1c,0xaa,0x9f,0xb8,0x47,0x15,0xb7,0xb6,0x18,0xac,0xa5,0xad,0xa3,0xa5,0x93,0xa7,0x5e,0xae,0xf5,0x1e,0x18,0x19,0x26,0x0d,0x9a,0x8f,0x15,0xa1,0xad,0xd2,0x27,0x0e +,0xa8,0x4e,0x1c,0x9e,0x9e,0x9c,0xa6,0x9e,0x97,0xb5,0x37,0xc0,0x34,0x17,0x13,0x19,0x26,0x0d,0x8d,0x94,0x25,0x93,0xa8,0xac,0x1a,0x0f,0xbf,0x25,0x16,0xac,0xa8,0xa1 +,0xac,0x9c,0x8f,0xa8,0xbe,0xa9,0x61,0x1d,0x11,0x1c,0x1c,0x0c,0x8b,0xab,0x22,0x9a,0xbb,0xae,0x17,0x1c,0xa7,0x2f,0x21,0x9f,0xae,0xa9,0xc2,0x9e,0x97,0xbf,0xbc,0xac +,0x68,0x1e,0x17,0x2b,0x1c,0x12,0x88,0xe2,0x26,0x9b,0x57,0x7c,0x0c,0x1c,0xac,0x22,0x39,0x9a,0xa0,0xa3,0xa9,0x96,0x97,0x77,0xd2,0xae,0x25,0x16,0x10,0x2b,0x17,0x21 +,0x83,0x54,0xbe,0x97,0xc4,0x43,0x0a,0x22,0x5f,0x14,0x2e,0xa8,0xb5,0xad,0xa0,0x8f,0x93,0xb9,0xa7,0xa4,0x22,0x19,0x11,0x2e,0x0f,0x30,0x88,0x1e,0xaf,0x9d,0xc0,0x2f +,0x0e,0x4f,0xdb,0x17,0xc5,0xaa,0xbb,0xaa,0xa0,0x8f,0xa2,0xca,0xaa,0xa6,0x22,0x1c,0x18,0x29,0x0e,0xb7,0x8d,0x13,0xa6,0xad,0x47,0x1f,0x0f,0xb7,0xe5,0x20,0x9c,0x9f +,0xa7,0x9f,0x9b,0x92,0xbc,0xe3,0xc7,0x53,0x15,0x16,0x1a,0x25,0x0f,0x95,0x8f,0x19,0x97,0xb1,0x3f,0x19,0x12,0xbe,0x31,0x20,0x9e,0xac,0xa8,0x99,0x93,0x92,0xb1,0xb9 +,0xba,0x34,0x17,0x14,0x18,0x19,0x0d,0x8f,0xa1,0x1e,0x92,0xae,0xdd,0x1d,0x1d,0xb5,0x2a,0x29,0x9d,0xba,0xa9,0x9a,0x97,0x99,0xbc,0xb8,0xab,0x2f,0x1c,0x15,0x1e,0x16 +,0x0e,0x8c,0x5f,0x1f,0x96,0xcc,0x40,0x16,0x24,0xa4,0x28,0xd5,0x96,0xaf,0x9d,0x9b,0x95,0x9c,0x37,0x48,0xe8,0x1a,0x17,0x14,0x2a,0x12,0x1c,0x86,0x3c,0x3f,0x92,0xc5 +,0x3a,0x12,0x2c,0xaa,0x1a,0xc9,0x9a,0xab,0x99,0x9a,0x90,0x9e,0x2c,0x4b,0x4f,0x17,0x16,0x12,0x2a,0x0d,0x2b,0x87,0x25,0xbd,0x93,0xbb,0x3a,0x12,0x38,0xb1,0x17,0xb2 +,0x9d,0xa9,0x9d,0x9f,0x90,0xa5,0x32,0xc3,0x6f,0x1b,0x1a,0x17,0x31,0x0b,0xd3,0x8a,0x1a,0xac,0x9a,0xd4,0x28,0x14,0xc0,0xb1,0x1c,0xa1,0x9e,0xaa,0xa0,0xa0,0x93,0xc1 +,0x2b,0x5e,0x30,0x19,0x1a,0x1a,0x30,0x0d,0x9c,0x8d,0x1b,0x9b,0x9d,0xcb,0x1f,0x16,0xbd,0x3d,0x1b,0xa1,0xa6,0xa9,0x9e,0x9b,0x93,0xc3,0x3d,0xc5,0x2f,0x19,0x17,0x1a +,0x29,0x0c,0x92,0x94,0x1c,0x90,0xa1,0xc1,0x18,0x18,0xbb,0x24,0x1f,0xa5,0xad,0xb3,0xa4,0x98,0x95,0xb7,0xdf,0xaf,0x36,0x1a,0x18,0x1c,0x1f,0x0c,0x8c,0x9f,0x1a,0x8f +,0xb2,0xdf,0x17,0x25,0xa6,0x22,0x2e,0x9c,0xad,0xad,0xa1,0x96,0x9c,0x50,0x4e,0xd5,0x24,0x18,0x17,0x22,0x1b,0x12,0x87,0x59,0x22,0x8e,0xc9,0x40,0x11,0x2f,0xb8,0x1b +,0xcf,0x99,0xaa,0x9e,0x9d,0x90,0x9f,0x46,0xe0,0x3d,0x1d,0x16,0x13,0x28,0x10,0x1f,0x84,0x25,0xc8,0x8f,0xfa,0x27,0x10,0x43,0x53,0x18,0xb9,0x9d,0xac,0x9c,0x9a,0x8f +,0xa0,0xd3,0xc2,0x3b,0x1a,0x16,0x12,0x25,0x0b,0x60,0x87,0x19,0xa6,0x94,0xdb,0x25,0x19,0xb6,0x47,0x1b,0xa6,0x9c,0xb0,0xa0,0x99,0x92,0xba,0x41,0xc9,0x24,0x17,0x18 +,0x16,0x27,0x08,0x98,0x8c,0x14,0x93,0x9a,0x6b,0x1d,0x1c,0xad,0x29,0x28,0x9a,0xa2,0xa8,0x9f,0x96,0x99,0x4c,0x43,0x4f,0x1e,0x15,0x15,0x16,0x1c,0x0b,0x8c,0x93,0x19 +,0x8d,0xa0,0x37,0x1b,0x23,0xb0,0x20,0x2e,0x98,0xad,0xa7,0x9b,0x93,0x9c,0xc8,0xc7,0x59,0x1d,0x15,0x15,0x15,0x15,0x0d,0x89,0xa5,0x1b,0x8d,0xa9,0x37,0x1d,0x37,0xb4 +,0x1c,0x47,0x95,0xbd,0xa8,0x9b,0x94,0xa2,0x43,0xc5,0x5e,0x1b,0x1c,0x19,0x1b,0x12,0x16,0x84,0x39,0x2a,0x8c,0xcb,0x2f,0x18,0x4b,0xd5,0x1a,0xad,0x97,0xca,0xa0,0x99 +,0x95,0xb0,0x38,0xcb,0x42,0x17,0x1c,0x17,0x1b,0x11,0x34,0x83,0x1e,0xbe,0x8c,0x45,0x27,0x1b,0x66,0x3a,0x1a,0xa6,0x9e,0xcd,0x9b,0x97,0x97,0xb4,0x73,0x6f,0x37,0x14 +,0x19,0x14,0x1b,0x0d,0xb9,0x87,0x16,0x9e,0x8e,0x4e,0x2a,0x20,0xbb,0x34,0x1c,0x9c,0xa5,0xc5,0x9c,0x9a,0x98,0xcd,0xcf,0xc2,0x2b,0x18,0x1b,0x14,0x1c,0x0a,0x97,0x8d +,0x0e,0x92,0x9a,0x32,0x24,0x20,0xad,0x27,0x27,0x92,0xb5,0xb6,0x9c,0x96,0x9a,0x48,0xb9,0xc1,0x1f,0x17,0x1b,0x16,0x18,0x0e,0x8a,0x9d,0x12,0x8b,0xa0,0x28,0x1f,0x2c +,0xd0,0x1c,0x3b,0x96,0xe1,0xa9,0x97,0x95,0xa4,0xc5,0xb8,0x4f,0x1b,0x15,0x16,0x16,0x14,0x11,0x86,0xc5,0x23,0x87,0xaa,0x2d,0x21,0x49,0xd8,0x1a,0xc1,0x96,0x7c,0xa5 +,0x99,0x99,0xab,0xc4,0xba,0x3f,0x13,0x1b,0x15,0x13,0x11,0x15,0x84,0x2b,0x2a,0x85,0xf3,0x2a,0x2b,0x4b,0xcb,0x19,0xa3,0x92,0x3f,0x9e,0x95,0x9a,0xb8,0xc1,0xb9,0x28 +,0x12,0x20,0x12,0x13,0x0f,0x2c,0x85,0x19,0xbb,0x86,0x36,0x28,0x2d,0x41,0x3d,0x1d,0x9f,0x9b,0x4a,0x99,0x98,0x9d,0xb9,0xba,0xbf,0x1f,0x17,0x1f,0x0f,0x1b,0x0c,0xda +,0x87,0x11,0x97,0x8a,0x2e,0x35,0x2e,0xcb,0x2f,0x1e,0x99,0xa7,0x47,0x99,0x9e,0xa3,0xb8,0xbf,0x45,0x1f,0x1a,0x20,0x0f,0x1d,0x0c,0xab,0x8a,0x0f,0x92,0x8c,0x2c,0x35 +,0x3c,0xc6,0x36,0x2b,0x97,0xa9,0x44,0x9a,0x9a,0xad,0xcf,0xbd,0x33,0x1f,0x1b,0x1e,0x12,0x1a,0x0d,0x96,0x93,0x0f,0x8a,0x94,0x20,0x34,0x3d,0xce,0x2a,0x36,0x94,0xd5 +,0xd1,0x96,0x9d,0xad,0xba,0xbc,0x33,0x1d,0x1d,0x1c,0x11,0x1a,0x0e,0x8d,0x9e,0x17,0x85,0x9d,0x21,0x41,0x45,0x4f,0x1f,0x49,0x97,0x32,0xc6,0x97,0x9e,0xb3,0xb6,0xbe +,0x33,0x1c,0x1f,0x1c,0x12,0x14,0x15,0x89,0x61,0x28,0x83,0xae,0x22,0x5a,0xc8,0x3b,0x21,0xaa,0x9c,0x29,0xaa,0x99,0xa4,0xdd,0xb6,0xcc,0x26,0x1c,0x21,0x18,0x16,0x11 +,0x1f,0x87,0x21,0xca,0x84,0x3b,0x23,0xcd,0x66,0x3b,0x23,0x9f,0x9a,0x25,0x9e,0x96,0xac,0xbd,0xb8,0x52,0x24,0x18,0x27,0x15,0x16,0x0f,0xdb,0x89,0x16,0x97,0x89,0x2a +,0x38,0x61,0x58,0x2a,0x27,0x9b,0xbd,0x2b,0x98,0x9e,0xaa,0xae,0xbd,0xe9,0x29,0x1c,0x27,0x11,0x1b,0x0d,0xac,0x8d,0x0f,0x8d,0x8d,0x22,0xd3,0x7e,0xcb,0x2c,0x26,0x96 +,0x35,0x2b,0x96,0xa9,0xb4,0xb5,0xaf,0x48,0x1f,0x27,0x21,0x13,0x1b,0x0c,0x93,0x9a,0x14,0x87,0x9b,0x25,0xc1,0x69,0x64,0x26,0x47,0x96,0x2d,0x56,0x94,0xa9,0xb8,0xad +,0xbb,0x2e,0x1f,0x23,0x1a,0x15,0x16,0x0e,0x8b,0xad,0x1c,0x83,0xa9,0x25,0xe0,0x4c,0x42,0x1d,0xc5,0x98,0x1f,0xb2,0x8f,0xb2,0xb5,0xa2,0xb3,0x2e,0x1f,0x2a,0x19,0x11 +,0x18,0x13,0x8d,0xd6,0x2a,0x84,0xcc,0x21,0xb8,0x5d,0x2b,0x2a,0xb2,0xa2,0x26,0xa8,0x95,0xbf,0xba,0x9e,0xcc,0x29,0x2b,0x2c,0x1a,0x16,0x15,0x18,0x8b,0x2b,0x46,0x85 +,0x2f,0x2a,0xb1,0x45,0x2e,0x33,0xa2,0xa8,0x21,0x9a,0x97,0x59,0xaf,0xa1,0x39,0x26,0x2f,0x27,0x15,0x18,0x18,0x1b,0x8c,0x25,0xbf,0x87,0x2b,0x2d,0xae,0x4d,0x2b,0x52 +,0xa5,0xb6,0x2b,0x99,0x99,0x5f,0xaa,0xa0,0x30,0x2f,0x2c,0x27,0x15,0x19,0x13,0x1b,0x8b,0x19,0xb3,0x87,0x20,0x3e,0xa2,0x63,0x29,0xe8,0x9f,0x6c,0x29,0x9a,0x9f,0x7b +,0xaa,0xa4,0x2f,0x48,0x3a,0x26,0x17,0x1d,0x11,0x23,0x8d,0x13,0xa4,0x8a,0x1e,0xed,0xa6,0x3d,0x35,0xe8,0xa4,0x58,0x2b,0x94,0xa4,0x5e,0xa4,0xaf,0x31,0x46,0x2c,0x25 +,0x14,0x1f,0x0f,0x30,0x91,0x12,0x97,0x8f,0x23,0xb8,0xa1,0x4e,0x2e,0xad,0xa7,0x2c,0x67,0x97,0xab,0xeb,0xa6,0xa6,0x21,0x3b,0x56,0x19,0x12,0x25,0x0c,0xdb,0x96,0x0f +,0x90,0x91,0x24,0xaa,0xa5,0x35,0x37,0xb2,0xab,0x2b,0xf1,0x97,0xad,0xc3,0xa6,0xb1,0x29,0x56,0x44,0x1d,0x18,0x22,0x0c,0xaf,0x9f,0x0f,0x8d,0x9a,0x1e,0xa8,0xae,0x2c +,0x3e,0xa9,0xab,0x25,0xb3,0x9b,0xed,0xb4,0xa2,0xcb,0x30,0xca,0x31,0x1c,0x1c,0x1e,0x0e,0xa5,0xa7,0x19,0x8c,0x9c,0x21,0xa8,0xa5,0x24,0x57,0xa2,0x51,0x25,0xaa,0x9e +,0x5d,0xbb,0x9e,0xfc,0x30,0x55,0x29,0x1d,0x18,0x1b,0x11,0x9b,0xed,0x22,0x88,0xb9,0x2d,0x9d,0xbb,0x24,0xb8,0xa7,0x3b,0x41,0xa0,0xa5,0xca,0xba,0xa1,0x4d,0x2e,0xd4 +,0x25,0x19,0x1d,0x17,0x12,0x94,0x26,0x26,0x88,0x3b,0x2d,0x9a,0xb7,0x28,0xae,0xa0,0x55,0x43,0x9d,0xab,0x36,0xac,0xa4,0x28,0x4b,0xcd,0x1f,0x19,0x28,0x16,0x19,0x95 +,0x1b,0x40,0x8b,0x2d,0x36,0x95,0x41,0x3c,0x9f,0xb1,0x46,0x5f,0x9b,0xb9,0x32,0xa3,0xaf,0x25,0x32,0x53,0x1c,0x17,0x2e,0x15,0x29,0x97,0x18,0xa4,0x8d,0x1e,0xb0,0x9d +,0x3a,0xed,0x8e,0xab,0x2e,0xbb,0x95,0x4b,0xa2,0xad,0x36,0x3b,0x02,0x0b,0x00,0x1a,0x1a,0x06,0xac,0x2f,0x2e,0x89,0x8b,0x9e,0x8c,0x93,0xab,0x88,0x8d,0x51,0x8e,0x9e +,0xce,0x96,0x0d,0x9f,0x89,0x9b,0x9a,0xa8,0x1f,0x11,0x15,0x02,0x1e,0x0a,0x00,0x1b,0x0f,0x02,0x1a,0x0c,0x08,0x16,0x1f,0x20,0x0e,0x36,0x36,0xde,0xa6,0x99,0xbd,0xa5 +,0x9b,0x9a,0x9b,0x9e,0xa1,0xa7,0x82,0x8d,0x8e,0x80,0x89,0x88,0x81,0x83,0x88,0x86,0x86,0x5a,0xa0,0x8f,0x94,0x1f,0x16,0x4a,0x07,0x1b,0x0d,0x03,0x04,0x04,0x00,0x12 +,0x18,0x00,0x09,0x06,0x09,0x05,0x0b,0x03,0x0f,0x26,0x28,0xcf,0x3a,0x25,0x2d,0x95,0x90,0x87,0x8d,0x86,0x8e,0x8d,0x87,0x89,0x8e,0x86,0x8b,0xa2,0x80,0x8e,0x8f,0x88 +,0x8e,0xe8,0x9a,0x99,0xaf,0xaa,0xbe,0x1f,0x11,0x1c,0x14,0x12,0x0c,0x07,0x03,0x07,0x05,0x09,0x06,0x13,0x04,0x04,0xe3,0x0a,0x0e,0x28,0x1d,0x3f,0x9c,0x9c,0xd0,0x94 +,0x95,0x9c,0x97,0x8d,0x9b,0xae,0x9b,0xa1,0x9d,0x9a,0x8f,0xab,0x93,0x82,0xa6,0x8a,0x86,0x8d,0x82,0x86,0x92,0x92,0x87,0xaa,0x57,0x2c,0x1e,0x22,0x08,0x0b,0x0f,0x0c +,0x08,0x04,0x05,0x02,0x08,0x05,0x1c,0x0b,0x09,0x15,0x05,0x0a,0xd2,0xb9,0x0f,0x90,0xc2,0xa8,0x94,0x4d,0x8c,0x8b,0x83,0x8d,0x90,0x88,0x8b,0x86,0x90,0x88,0x94,0x95 +,0x8c,0x9d,0x8e,0x87,0x24,0xa1,0x99,0x16,0x99,0xa8,0x25,0x33,0xb5,0x13,0x19,0x31,0x12,0x18,0x16,0x07,0x0a,0x11,0x0a,0x03,0x05,0x03,0x0f,0x0f,0x34,0x2a,0x0c,0x3b +,0x09,0x3b,0x8f,0x95,0x8e,0x90,0x9b,0x91,0x8d,0xc8,0x93,0x8e,0x91,0xa5,0x2a,0x89,0x8d,0xcc,0xa5,0x9c,0x97,0x8a,0x80,0x99,0xbe,0x87,0xac,0xbf,0x8b,0x5c,0x5f,0xb7 +,0x1f,0x12,0x08,0x06,0x0b,0x13,0x08,0x0d,0x06,0x04,0x08,0x07,0x44,0x23,0x03,0x10,0x3a,0x0e,0x20,0x9f,0x12,0xc4,0x9b,0xd4,0x8a,0x8a,0xa0,0x8d,0x89,0xa4,0x8f,0x9c +,0x83,0x8a,0x99,0x8e,0x91,0x9b,0xce,0x8b,0x8f,0x98,0xdb,0x27,0xb0,0x85,0x55,0x23,0xa2,0x9c,0x9b,0xe3,0xd5,0xd9,0x23,0x0c,0xb4,0x0f,0x0b,0x2d,0x01,0x0b,0x0a,0x02 +,0x0f,0x0a,0x21,0x02,0x0e,0x17,0x06,0xd1,0xc2,0xc8,0x16,0xaf,0x39,0xae,0x8a,0x90,0x8e,0xb9,0x94,0x8d,0x8e,0x8c,0x85,0x81,0xa3,0x49,0x89,0x8b,0x9e,0x97,0xa7,0x94 +,0x96,0xab,0x12,0x1d,0x5b,0x8b,0xa2,0x0e,0x1d,0x20,0x76,0x10,0x69,0x0c,0x1b,0x12,0x0c,0x1c,0x1b,0x0f,0x06,0x20,0x19,0x12,0x0e,0x20,0x0c,0x0f,0x0e,0xb0,0x51,0xd4 +,0x3d,0x0d,0xe2,0xa6,0x85,0x8a,0x86,0x9e,0xb7,0x92,0x92,0x80,0x9a,0x92,0x97,0x9c,0x88,0x8f,0x94,0x50,0x8e,0x3e,0x32,0x8d,0xd9,0xb8,0x3a,0xbe,0xf9,0xa7,0xce,0x0d +,0x3e,0x26,0x18,0x0a,0x18,0x2e,0x04,0x0b,0x28,0x16,0x0c,0x16,0x08,0x12,0x15,0x15,0x0b,0x18,0x36,0x3d,0xba,0x21,0x37,0xa9,0x8d,0xc1,0x8f,0x91,0xa5,0x96,0x99,0x8a +,0x8e,0x8e,0x8a,0x9f,0x8d,0x96,0x9e,0x94,0xa1,0x9f,0xba,0x8f,0xbb,0x33,0x17,0x45,0xaf,0xa9,0x21,0xdb,0x19,0x0e,0xc4,0x3d,0x29,0x15,0x4e,0x12,0x2a,0x0d,0x2e,0x1e +,0x0c,0xb1,0x1b,0x17,0x0f,0x17,0x22,0x1d,0x34,0x1e,0x2f,0x37,0x27,0x1f,0x32,0x91,0xa4,0xc9,0x9f,0x4e,0x9d,0x97,0x9d,0x96,0x8e,0x95,0x96,0x9a,0x9c,0x92,0x95,0x92 +,0x8d,0x8c,0x9c,0x95,0x97,0xa9,0x21,0xb3,0xac,0x9d,0x1d,0x12,0x19,0x07,0x1d,0x6d,0x0e,0x09,0x13,0x17,0x1f,0x0c,0x11,0x09,0x18,0x0f,0x1e,0x26,0x1d,0x13,0x22,0xcc +,0x0f,0xa0,0xcc,0x66,0xa7,0xa2,0x98,0x95,0x95,0xa1,0x98,0x8d,0x8f,0x86,0x86,0xaf,0x97,0xb1,0xac,0x8d,0x8f,0x9f,0x2e,0xc6,0xbd,0xb7,0x36,0x2c,0x44,0x1e,0xfb,0x56 +,0x1d,0x14,0x26,0x56,0x2e,0xa3,0x22,0x12,0x20,0x36,0x18,0x6a,0x17,0x1d,0x1a,0x1a,0x1e,0x17,0xf4,0x0c,0x2e,0x2e,0x29,0x17,0x5b,0x1c,0xbc,0x30,0x2c,0x9f,0x5d,0xaf +,0x91,0x9a,0x49,0x8b,0x58,0x8f,0x94,0x97,0x8f,0xa0,0x9a,0x9f,0x86,0x96,0x9f,0x96,0x9b,0xa1,0x9f,0x9e,0x34,0x5c,0x6a,0x1a,0xd0,0x38,0x0e,0x1e,0x15,0x2b,0x0c,0x1b +,0x0e,0x0f,0x3d,0x0a,0x1e,0x22,0x1f,0x0c,0x24,0xde,0x21,0x37,0x23,0x1d,0xa6,0x59,0x9f,0xaa,0x1e,0xa2,0xd9,0xa1,0x9e,0x90,0x98,0xbf,0x9b,0x9d,0x90,0x8b,0x99,0x93 +,0x90,0xa1,0x8a,0x9a,0x5c,0x9d,0x97,0x1e,0xaa,0x6c,0x2e,0x23,0x10,0xb0,0x17,0x27,0x19,0x2d,0x1d,0x1a,0x15,0x1e,0x1b,0x19,0x27,0x0c,0xb5,0x13,0x11,0xc4,0x1c,0x1b +,0x3c,0x73,0x2d,0xd2,0x67,0xaa,0x2f,0x9c,0xb4,0xae,0x99,0x2e,0x9c,0xa5,0x8c,0x9f,0x99,0xae,0x9a,0x95,0xaa,0xac,0xab,0x8e,0xa5,0xc4,0xb1,0x6a,0x26,0x96,0xf7,0xab +,0xb5,0x16,0x62,0xb6,0x41,0x1c,0x1c,0x1e,0xaa,0x1d,0x10,0x2b,0x12,0x1a,0x24,0x1d,0x27,0x38,0xa9,0xce,0x3b,0x43,0x13,0xb4,0xd4,0x1e,0x20,0x57,0xcc,0x1f,0x29,0x36 +,0x21,0xb0,0xcc,0x3a,0x9a,0xd4,0x9c,0xab,0xab,0x8e,0x9f,0x91,0x9a,0x94,0x90,0xdb,0x8d,0x9a,0x9f,0xb4,0x9a,0x9c,0xb9,0x4d,0x30,0xb9,0x1a,0xcf,0xba,0x0f,0x13,0x38 +,0x15,0x25,0x18,0x10,0x1b,0x1b,0x11,0x14,0x67,0x27,0x0e,0x3e,0x2a,0x2a,0xaa,0xcb,0xaa,0x64,0xb4,0xe6,0x97,0x97,0x9b,0x98,0xae,0x9b,0xb6,0xc5,0x9b,0xc0,0xa9,0x95 +,0x4e,0xce,0x9a,0x9f,0x2e,0x31,0x4c,0xab,0x25,0x28,0x4f,0x36,0x42,0x26,0x64,0x3b,0x27,0x2d,0x2e,0x3d,0xa4,0x1f,0x60,0xa1,0x3a,0x46,0x5c,0xc0,0xb6,0xe9,0xa5,0xb2 +,0x24,0x63,0xf4,0x29,0xda,0xf4,0x51,0x3b,0x1d,0x29,0x1b,0xbf,0x2b,0x2d,0x30,0x1a,0x2d,0x15,0xc8,0xea,0xa6,0x9d,0x21,0x47,0xa3,0xa5,0xb2,0x9b,0x9c,0x98,0x92,0xa7 +,0xab,0x8e,0x95,0x97,0xaa,0x9d,0xd1,0xae,0x95,0x21,0x3b,0x2d,0x2c,0x1a,0x15,0x28,0x19,0x0e,0x29,0x2b,0x21,0x13,0x20,0x1b,0x2b,0x3b,0x4d,0xc1,0x23,0x3b,0x3b,0x4f +,0x9b,0x9e,0xcb,0xcb,0xb9,0xa6,0xc6,0xa0,0x37,0xa9,0xb9,0x9e,0x33,0x2d,0xa9,0xb2,0x9d,0xb7,0xcf,0x7a,0xa1,0xb0,0xa8,0x99,0xd5,0x38,0x3c,0x30,0x44,0x2e,0xa2,0x2e +,0xb6,0x24,0x2f,0xbf,0x27,0xe1,0xc0,0x2f,0x39,0xb6,0x3f,0x34,0x1c,0x3c,0xc5,0x5a,0x1c,0xcd,0x31,0x2f,0xce,0xfa,0x23,0x61,0xb0,0xba,0xa8,0x36,0x2f,0x67,0xaa,0xa8 +,0xa3,0x18,0xc8,0xb6,0x5b,0xb6,0xab,0xad,0x29,0xba,0xfb,0xb6,0xa4,0x65,0xb7,0xc2,0x42,0xcc,0xc9,0xbd,0xbd,0xdd,0xef,0x9f,0x34,0xb8,0xd1,0x40,0x4f,0x3d,0xa0,0x33 +,0x34,0x38,0x2c,0x34,0xc3,0x33,0x24,0x5a,0x2c,0x4e,0x32,0x25,0x34,0x2d,0xbd,0x68,0x54,0xbd,0x68,0x51,0x73,0x5f,0x5c,0x30,0x6e,0xb3,0xb8,0xae,0xe7,0xbb,0xb7,0x46 +,0xd5,0xa5,0x9d,0x9d,0xb0,0xe9,0xb0,0xbd,0xce,0xa2,0xa3,0xde,0xe6,0xcc,0x4d,0xcd,0xcd,0xcd,0xb8,0x59,0x3e,0xd9,0x2b,0x35,0xb7,0x34,0x27,0xfc,0x65,0x3e,0x5a,0x34 +,0xb5,0x38,0x2b,0xe0,0x34,0xf7,0x35,0xc5,0xce,0xb4,0x66,0x23,0x6c,0x40,0xd7,0xcd,0x25,0x2f,0xa5,0xe7,0x3f,0x4e,0x2d,0x34,0x2e,0x58,0xc6,0x48,0xd5,0x3f,0x4a,0xc6 +,0xb2,0xac,0x51,0xaf,0x4d,0x24,0x4e,0xae,0xad,0xce,0x3f,0x30,0x4f,0xc9,0xaa,0xb1,0x2e,0x2b,0x33,0xbd,0xa7,0x6d,0x2e,0x2b,0xd9,0xa8,0xb3,0xca,0x5e,0x2b,0x3f,0xbd +,0x77,0xef,0x48,0xba,0x4a,0x30,0x64,0x36,0xd8,0x3f,0x42,0x3b,0x24,0x44,0xc9,0x4f,0xf7,0xac,0xdc,0x3c,0x63,0x3e,0xb5,0xbf,0xb5,0xbb,0x2f,0x4d,0x50,0xa1,0xae,0xe3 +,0x68,0x2d,0xce,0xc9,0xc5,0xe9,0x5e,0x52,0xc8,0xc1,0x4d,0xae,0xbb,0x69,0xfb,0x34,0xb0,0xbf,0x3d,0x45,0x29,0xcf,0xb0,0xdf,0x3d,0xd9,0x32,0x31,0xba,0xba,0xc4,0x48 +,0x2c,0x33,0xd3,0xe6,0xba,0xda,0xcd,0xda,0xb6,0xb2,0x57,0x45,0x3b,0x56,0xd9,0xab,0xcc,0x2f,0x44,0xb8,0xb9,0xd4,0xbf,0x47,0x23,0x46,0x70,0xd8,0xab,0xc2,0xc8,0x3f +,0x42,0xca,0x48,0xb5,0xcd,0x4f,0xcc,0x2a,0x3f,0xce,0xbf,0x33,0x32,0xc4,0xe9,0x34,0x2a,0xaf,0xc6,0x1f,0x28,0x4e,0xcc,0xbd,0xe1,0xc5,0xba,0x54,0x55,0xc5,0xae,0xb2 +,0x66,0x43,0xcc,0xbf,0xd6,0xc2,0xbd,0x58,0x76,0xcc,0x2c,0xca,0x7b,0xed,0xbf,0x3f,0xb5,0x40,0xb2,0xa4,0xb3,0x50,0x2d,0x37,0x3a,0xb6,0xbc,0xba,0x46,0x45,0x4f,0x2d +,0x5c,0xb4,0xdf,0x2c,0xbb,0xc8,0x44,0x45,0x39,0x45,0xe3,0xc4,0x33,0xc9,0xba,0x30,0xd7,0xc9,0xac,0xfb,0xe2,0xb4,0x3c,0x5e,0x36,0xcb,0xb6,0xb7,0x36,0x45,0x75,0x3c +,0x2a,0x4d,0xaf,0xe4,0x5b,0x36,0xeb,0xba,0xb9,0x3a,0xed,0x44,0x3b,0xbb,0xc2,0x34,0xc0,0xbe,0x69,0x50,0x5c,0xc9,0x2d,0x32,0xa7,0xc9,0x30,0xbc,0x26,0x2d,0xf2,0xa3 +,0xae,0x3a,0xd3,0xb3,0x3e,0xd2,0x67,0x3b,0xb8,0xb6,0xab,0x47,0x47,0x36,0xd5,0xdd,0xbf,0xa8,0x3d,0x2a,0x2c,0xca,0xb1,0xfa,0x3d,0x40,0xd1,0xcf,0xbe,0xe4,0xbc,0xc2 +,0xcc,0xd8,0xc2,0xdb,0x2f,0xb0,0x4c,0x50,0xae,0x44,0x34,0xe7,0x3a,0x38,0x3f,0x49,0xb1,0x26,0x24,0xd9,0xad,0xb1,0x55,0x49,0x53,0xc6,0x56,0x3d,0x55,0x3c,0x62,0xf2 +,0xdb,0xb0,0xaf,0xe5,0x41,0xc1,0x2e,0x2e,0xae,0xbd,0x46,0xb9,0x45,0xbc,0xae,0xc7,0xc2,0xbe,0xb5,0x20,0x39,0xad,0xbb,0xbc,0x3f,0xd8,0x3d,0x2f,0xbe,0x5a,0x6f,0x5c +,0x2d,0x2b,0xbd,0x3f,0x4b,0x47,0x3e,0xbc,0x3c,0xaf,0xb9,0x56,0xcd,0xbc,0x2f,0xbb,0xb6,0x39,0xbb,0x3d,0xb8,0xae,0xb0,0xb8,0x29,0x29,0xda,0xe6,0x6c,0xc9,0xd6,0x38 +,0x3c,0xb2,0xb9,0xca,0xdc,0x33,0x40,0xbf,0x58,0x3f,0x31,0xb1,0xaf,0x4f,0xce,0x6c,0x35,0xaf,0xd6,0x3d,0xb0,0x2b,0x3c,0x6f,0xe8,0x44,0xb6,0x5c,0x3e,0xbe,0xdb,0x6e +,0x2d,0x34,0x5b,0xa4,0xfa,0xef,0xd4,0x21,0x3b,0xb5,0xc9,0xa7,0x3d,0x2b,0x56,0x47,0xc1,0x74,0xc0,0xd1,0xb8,0xae,0xc8,0x3e,0xaf,0x2a,0x3b,0xa7,0xb7,0x5f,0x28,0xc6 +,0x5e,0x5d,0xca,0x30,0x31,0xc3,0xae,0xbc,0x39,0x2e,0x3c,0xbb,0x62,0xd4,0x4a,0xdb,0xa7,0xe2,0xcd,0x62,0x5e,0x34,0x4b,0xaf,0xaf,0xd3,0x36,0x63,0x46,0x37,0xe2,0xcd +,0xb6,0xbd,0x29,0x28,0xde,0xd7,0xcf,0xb9,0x3a,0xbf,0xd8,0x33,0xaf,0x45,0xe6,0xaf,0xb0,0xf4,0x29,0xd7,0xbd,0xe5,0x71,0x44,0x39,0x71,0x3c,0xb4,0xc4,0x2e,0xe6,0x56 +,0xd3,0xb8,0x68,0x2f,0xe6,0xaa,0xab,0x49,0x2c,0x59,0x6c,0x5a,0x41,0xdf,0xc7,0x36,0xe7,0x49,0x4f,0xba,0xf7,0x64,0x3b,0xc7,0xb9,0x31,0xf4,0x4c,0x4d,0xa7,0xac,0xcf +,0x38,0x3e,0x50,0xd7,0xcd,0x54,0x46,0xbf,0xaa,0x5b,0x2b,0x37,0x33,0xbb,0xb7,0x63,0xac,0x3b,0x3c,0x43,0x3c,0xd7,0x58,0xe8,0xb2,0xa8,0xd1,0x51,0xce,0x31,0x30,0xbc +,0xb5,0xaa,0x51,0x2d,0xe6,0xbb,0x3a,0x37,0x37,0xd2,0xe3,0xba,0xbc,0x30,0x2c,0x2b,0xc3,0xbc,0x9f,0xbb,0xf2,0x2f,0x34,0xc5,0xbe,0xc6,0x2e,0x2b,0x38,0xaf,0xaa,0xa7 +,0x35,0x31,0x4e,0x2d,0xc0,0xaa,0xd3,0x4a,0x42,0x5e,0xd0,0xba,0xaf,0xba,0x39,0x3b,0xc4,0x79,0x2b,0x3d,0xb6,0xf7,0x3e,0x40,0xab,0x5f,0x5e,0x6d,0x35,0x46,0xca,0xb8 +,0x37,0xc4,0xe4,0x37,0xf9,0xb3,0xbf,0xbb,0xe7,0x3f,0x78,0x2f,0x31,0xaa,0xac,0x3a,0x3f,0x47,0xcd,0xbd,0x4d,0xc6,0xbe,0x2f,0x35,0x39,0xc5,0xb8,0xc2,0x46,0xb2,0xcb +,0x31,0xbe,0xc3,0xb6,0x39,0x2a,0x2d,0xaf,0xa4,0x53,0x37,0x6d,0x4f,0x35,0xcd,0xb7,0xbd,0x39,0x2f,0x5d,0x4f,0xc8,0x4c,0xc2,0xb3,0xec,0x45,0xb9,0xab,0x41,0x30,0x32 +,0x44,0xe8,0xae,0x7c,0x7c,0x72,0x69,0xd9,0xe2,0x3b,0x3a,0x43,0xd2,0xbf,0x67,0xc7,0xd7,0x69,0x3a,0xb8,0xbf,0xbb,0xc2,0x41,0x45,0x5a,0x43,0x72,0xe5,0xd5,0xab,0x3f +,0x2e,0xde,0xce,0x62,0x47,0x57,0xec,0xae,0x38,0x2a,0xbc,0xda,0xcc,0xcb,0xb9,0xc4,0xdb,0x5b,0x40,0x38,0x4a,0x59,0x46,0xbb,0xb9,0xc6,0x4e,0x32,0xbf,0xc6,0x3c,0x39 +,0x5d,0x54,0x41,0xac,0xb0,0xad,0x3d,0x2f,0xc8,0xca,0xca,0xc0,0xe7,0x3e,0x31,0x3e,0xc1,0xa8,0x44,0x3e,0xb5,0x30,0x7c,0x48,0x4f,0xba,0xbe,0x2c,0x3e,0x57,0xda,0xaf +,0x67,0x4a,0x4d,0xe9,0xea,0x62,0x33,0x4d,0xbe,0xcc,0x30,0xd9,0xc1,0x59,0xad,0xe6,0x3a,0x46,0xee,0xb8,0xbc,0x61,0x30,0x57,0xc5,0xae,0xb8,0xd0,0x56,0x3c,0xd7,0xd1 +,0xb0,0x35,0x29,0x67,0xba,0xb9,0x60,0x3d,0x4b,0xb4,0x3f,0x38,0x3e,0x37,0xb9,0x4d,0xbf,0xb4,0x4a,0x5d,0x3e,0xcb,0xaa,0x5b,0x35,0xfc,0x2f,0xcf,0xf8,0x35,0xc9,0xc4 +,0xae,0x43,0x51,0x45,0xdb,0xc9,0x33,0xca,0xaf,0xaf,0x36,0x38,0xb8,0x50,0x3a,0xaf,0xa6,0x53,0x3f,0xc2,0x37,0x3f,0x41,0xeb,0xbe,0xca,0x4d,0x49,0x3c,0x3d,0xb4,0xc9 +,0xc3,0xcf,0x23,0x2e,0xae,0xb3,0xc3,0x4b,0xc7,0xd9,0x51,0x4d,0x35,0xbd,0xf2,0x3c,0xbf,0x38,0xe8,0xbc,0xd2,0xf4,0x48,0xbc,0xcc,0x36,0x45,0xb9,0x55,0x4e,0x51,0x4a +,0xb1,0xab,0xe1,0x74,0x39,0x3c,0xf8,0xaf,0xc1,0x2f,0x2d,0x3a,0xaf,0xa9,0xd0,0x39,0x30,0x2c,0xbd,0xb7,0x5d,0xd1,0xcd,0x53,0x41,0xd6,0x4d,0x57,0xb2,0xbb,0x39,0x2c +,0xe3,0xc8,0xbb,0xc3,0xc8,0x34,0x2d,0xb4,0xbe,0xba,0xb2,0x4a,0x33,0x36,0x42,0xae,0xbd,0x5f,0x33,0x36,0xbf,0xd1,0xcd,0x9e,0xea,0x24,0x2f,0xc1,0xc7,0x2f,0xf8,0x41 +,0xb7,0xcc,0xc9,0xdc,0xbe,0x3c,0x2d,0xf1,0xc1,0xd3,0x47,0xd6,0x58,0x5a,0x47,0xcf,0x5e,0xe2,0xb6,0xbd,0x57,0xc8,0x33,0x60,0x5b,0xcb,0xaf,0xee,0x3f,0x35,0xc8,0xb3 +,0xb6,0x29,0x2e,0x3e,0xb8,0xb1,0xc0,0x3a,0x43,0x6b,0x3a,0x9f,0xdc,0x36,0xfd,0x4b,0x63,0xef,0xbd,0x39,0xe7,0xda,0x5b,0xc1,0xdd,0xf8,0xcf,0xdf,0x57,0x38,0x2d,0x46 +,0xce,0xbc,0x4b,0xbf,0xda,0xbf,0x43,0x4a,0xa3,0xc9,0x2c,0x34,0xce,0x2e,0xbe,0xaf,0xc3,0xbe,0x35,0x4a,0xb5,0x4f,0x46,0x34,0x3d,0xdb,0xcd,0xb6,0xc7,0xc0,0x4d,0x47 +,0xc0,0xbd,0x38,0x39,0x54,0xc0,0x3a,0xd8,0xb2,0x6d,0x4c,0xcb,0x40,0x35,0xc2,0x74,0xb1,0xc8,0x3d,0x2b,0x3a,0xc3,0xaa,0xb6,0xfe,0x76,0x3e,0x47,0x3b,0xc6,0x71,0xca +,0xb4,0x2a,0x4e,0xbc,0xc0,0xba,0xdc,0x3a,0x33,0xbf,0x3d,0x3f,0x51,0xd8,0xb9,0x49,0x5b,0xbe,0xba,0xc8,0xc2,0xb6,0x49,0x64,0x40,0x42,0xbc,0x4b,0xb9,0x5d,0x4c,0xdc +,0x68,0x4b,0x2b,0x2a,0x40,0x2f,0x33,0xdb,0xdb,0x4c,0x48,0x56,0xd8,0xaf,0xbc,0xa9,0x42,0xb2,0xa8,0xd9,0xab,0xa8,0xaa,0xc2,0xb4,0xbf,0xb5,0xc2,0x3d,0x2a,0x25,0x28 +,0x3a,0x36,0x30,0x2e,0x1a,0x1d,0x2d,0x31,0x3f,0xe7,0x26,0x48,0xae,0xa8,0xaa,0x9b,0x9c,0xa3,0xa0,0xa8,0x9c,0xad,0xab,0xb1,0xaf,0xce,0x54,0x4f,0x3b,0x1f,0x21,0x24 +,0x1f,0x1d,0x17,0x1f,0x22,0x25,0x19,0x21,0x38,0xe8,0xa8,0xa1,0xae,0xa6,0x9f,0xa6,0x96,0x92,0x99,0x9f,0xaf,0xaa,0xb1,0xa6,0xa9,0x62,0x34,0x22,0x28,0x17,0x20,0x26 +,0x1f,0x17,0x12,0x25,0x1f,0x1f,0x28,0x4f,0x64,0xcb,0xa7,0xa3,0x9d,0xa0,0xaa,0x9c,0x91,0x94,0x95,0x94,0xa8,0x5b,0x5f,0xb5,0xbb,0x3e,0x27,0x18,0x1b,0x1d,0x1b,0x1f +,0x1a,0x12,0x1b,0x1b,0x20,0x35,0x29,0x33,0xbd,0x9c,0xad,0x9a,0x90,0x93,0x97,0xa6,0xa2,0x9a,0x91,0xab,0xa6,0xbc,0xcd,0xba,0x30,0x22,0x19,0x26,0x20,0x1d,0x14,0x16 +,0x16,0x16,0x1a,0x1f,0x27,0x32,0xc9,0xa7,0xad,0xab,0x96,0x99,0x9b,0x9e,0x98,0x9c,0x9c,0x92,0x9e,0xa6,0xc4,0x36,0xc5,0x4f,0x2c,0x1b,0x17,0x1b,0x1f,0x1f,0x0d,0x18 +,0x27,0x1b,0x1f,0x2f,0x3c,0x3c,0xa6,0x9c,0xa2,0x9e,0xa0,0x9d,0x97,0x92,0x94,0x9a,0x9e,0xa6,0xa8,0xc9,0x36,0x3b,0x2d,0x20,0x29,0x1b,0x15,0x1a,0x1a,0x12,0x17,0x16 +,0x0f,0x23,0x44,0xa0,0x8e,0x8f,0x92,0x91,0xaf,0x2c,0x4f,0x9e,0x9a,0x17,0x05,0x1e,0x93,0x8f,0x8f,0x2b,0x1d,0xaa,0x9d,0x48,0x25,0x2f,0x0e,0x38,0x59,0x33,0x6d,0x95 +,0x1e,0x1e,0x29,0x22,0x9d,0xa1,0x96,0x19,0xa4,0x90,0x8f,0x88,0x8d,0x2d,0xad,0x98,0x22,0xdd,0x2b,0x0e,0x03,0x11,0x15,0xdc,0xa7,0x11,0x06,0x08,0x0a,0x1c,0xa3,0x9b +,0x97,0xa9,0x3d,0x2a,0x8f,0x81,0x8e,0x94,0x95,0x8e,0x93,0xb0,0xa5,0x1d,0x13,0xad,0x8c,0x8e,0xc9,0x1d,0x12,0x09,0x05,0x0f,0x36,0xcc,0x12,0x01,0x1a,0xaf,0x9d,0x83 +,0x93,0x2a,0xa2,0x86,0x95,0xad,0xc9,0x25,0x24,0x2f,0x49,0x9c,0x8d,0x28,0x14,0x19,0x13,0x19,0x5c,0xc7,0x10,0x0d,0x23,0xaa,0xa7,0x3f,0xd2,0xa5,0x51,0xb9,0x8e,0x8d +,0xb4,0x2d,0xac,0x96,0x85,0x8a,0x91,0x45,0x10,0x2e,0xb5,0xb5,0x43,0xa1,0x26,0x09,0x06,0x0c,0xf3,0x29,0x15,0x1b,0x16,0x1c,0x36,0xa1,0x53,0x15,0x9f,0x84,0x84,0x8f +,0x93,0x9d,0x67,0x27,0x1b,0xb7,0xa0,0x1c,0x0f,0x16,0x14,0xba,0x9b,0xad,0x11,0x0e,0xa4,0xb0,0xca,0x48,0x1a,0xed,0xab,0xb3,0x87,0x83,0x96,0xa7,0xa6,0xcb,0x36,0xa0 +,0x95,0x1c,0x0c,0x3a,0xc4,0x2d,0x25,0x28,0x3f,0x19,0x0a,0x10,0x20,0x0a,0x07,0x1d,0x26,0xc0,0x88,0x8a,0x47,0xbf,0xb6,0x92,0x88,0x8a,0x92,0x9d,0xb1,0x24,0x44,0x98 +,0x93,0x4d,0x25,0xba,0x1e,0x13,0x4d,0x14,0x03,0x09,0x3c,0x99,0xab,0x1a,0xa4,0xbe,0x12,0xa9,0x8f,0x94,0x8f,0x8c,0x98,0x9c,0x8d,0x84,0x93,0x20,0xc8,0xb6,0x34,0xb6 +,0x16,0x0a,0x0d,0x07,0x0a,0xb5,0xa4,0x30,0xa6,0x1b,0x1d,0x8b,0x8e,0x8e,0x8d,0xb6,0x67,0x90,0x96,0xad,0xbf,0x3e,0x14,0x0a,0x0f,0x07,0x02,0x01,0x02,0x00,0x09,0x13 +,0x0c,0x03,0x02,0x00,0x1a,0xca,0x13,0x97,0x99,0x26,0x96,0x8c,0x8c,0x83,0x81,0x84,0x8a,0x87,0x86,0x88,0x86,0x97,0xb1,0x8c,0x84,0x8a,0x8d,0xa9,0x2e,0x24,0x1b,0x1f +,0x1c,0xa1,0x41,0x9e,0x8b,0xbe,0x89,0x80,0x8f,0x95,0x88,0x87,0x89,0x8a,0x95,0x1b,0x1b,0xb4,0xce,0xb4,0xa6,0x0e,0x03,0x04,0x02,0x06,0x08,0x07,0x00,0x08,0x05,0x0b +,0xce,0x31,0x22,0x9f,0x36,0x1a,0xb4,0xa5,0x21,0x1d,0xb7,0x3a,0xae,0x90,0x4e,0x12,0x1c,0x0f,0x16,0xcc,0x29,0x13,0x0c,0x0b,0x06,0x1c,0xbc,0x4d,0x8b,0xa8,0x32,0x8a +,0x89,0x8f,0x92,0x9f,0x9d,0x93,0x87,0x8e,0xdf,0xca,0x26,0x10,0x29,0x39,0x3a,0x97,0xc4,0x2a,0x3d,0xa6,0x9c,0x90,0x85,0x99,0x8a,0x80,0x8f,0x88,0x84,0x9a,0x88,0x80 +,0x83,0x82,0x84,0x87,0x99,0xba,0xaa,0xd2,0xbf,0xd3,0x09,0x04,0x07,0x04,0x09,0x09,0x02,0x00,0x02,0x00,0x03,0x0a,0x01,0x00,0x17,0x0f,0x0f,0x33,0x0e,0x0e,0x10,0x18 +,0x1a,0x1d,0xce,0x12,0x10,0x25,0x14,0x1f,0xbc,0x2f,0x1a,0x29,0x58,0x24,0xa6,0xa0,0x12,0x99,0x8a,0x92,0x83,0x82,0x8c,0x82,0x86,0xa5,0x90,0x87,0x88,0x8d,0x87,0x90 +,0x99,0x8b,0x8c,0xa0,0x91,0xa7,0x33,0x9e,0xcd,0x1b,0x0f,0xd3,0x32,0xbf,0x85,0x9c,0xaf,0x8a,0x30,0x13,0x99,0xab,0x7d,0x6a,0x21,0x15,0x2b,0xc1,0x1c,0x1b,0x1f,0x0b +,0x08,0x0e,0x09,0x05,0x07,0x06,0x07,0x17,0x25,0x09,0x36,0x3c,0x0e,0xa2,0xab,0x2b,0x8f,0x99,0x36,0xb0,0xe4,0xaa,0xa1,0x96,0xb5,0x2c,0xe5,0x2e,0x15,0x10,0x07,0x05 +,0x1a,0x0e,0x1a,0x1e,0xbc,0x10,0x0c,0x9a,0xb0,0x90,0x80,0x8b,0x88,0x80,0x87,0x83,0x81,0x84,0x86,0x85,0x87,0x8b,0x8c,0x8c,0x98,0x8d,0x88,0x98,0x8a,0x8d,0xb6,0x1f +,0x25,0xd3,0x0f,0xda,0xbb,0x06,0x2b,0x30,0x0c,0xb0,0xae,0x0f,0x12,0x0b,0x0b,0x0a,0x06,0x04,0x01,0x06,0x03,0x02,0x06,0x05,0x00,0x03,0x01,0x03,0x05,0x0d,0x15,0x06 +,0xac,0xa8,0x43,0x83,0x92,0x9d,0x85,0x87,0x8a,0x85,0x97,0x3b,0x99,0x8d,0x91,0x8f,0x89,0x8c,0x93,0x95,0xa8,0xa3,0x9b,0xae,0xaf,0x22,0xa2,0x9e,0x3d,0x85,0x95,0xb0 +,0x81,0x8f,0x90,0x81,0x8d,0x89,0x83,0x8c,0x8d,0x8b,0x97,0xb6,0x39,0x19,0x0c,0x0e,0x0a,0x02,0x04,0x04,0x03,0x09,0x0f,0x25,0x0f,0x18,0xaa,0x0b,0x1b,0xae,0x08,0x16 +,0x4e,0x0f,0x36,0xbc,0x1d,0x26,0x25,0x19,0x10,0x1a,0x27,0x17,0x20,0x1e,0x0b,0x18,0x1f,0x1b,0x10,0x0e,0x42,0x12,0x1b,0x46,0x0a,0x2a,0x9c,0x29,0x94,0x88,0x98,0x89 +,0x8e,0x97,0x88,0x8a,0x8c,0x86,0x8b,0x93,0x95,0x8b,0x8b,0x8f,0x86,0x88,0x8c,0x8a,0x8d,0x84,0x8b,0x88,0x80,0x91,0x86,0x81,0x97,0x8b,0x8e,0x2e,0xb0,0x2d,0x09,0x0e +,0x0d,0x09,0x0b,0x0e,0x09,0x04,0x0c,0x0b,0x05,0x06,0x02,0x00,0x00,0x01,0x08,0x00,0x0b,0x13,0x00,0x1e,0x29,0x09,0xb6,0xa2,0x2a,0x98,0xa2,0xbe,0x9d,0xa1,0x9a,0xa7 +,0xa0,0xa4,0xaa,0xbe,0x6c,0x30,0x55,0x29,0x39,0xae,0x9f,0x85,0x99,0x89,0x82,0xa7,0x86,0x86,0x9b,0x84,0x8b,0x9b,0x89,0x8c,0x98,0x94,0x94,0x8f,0x97,0x95,0x91,0x94 +,0x93,0xab,0x4d,0x9d,0xaf,0x3c,0x18,0x0a,0x26,0x06,0x14,0x2f,0x08,0xd2,0x33,0x08,0xab,0xa3,0x40,0x9a,0xb7,0x20,0x2b,0x25,0x10,0x0d,0x08,0x04,0x06,0x08,0x0d,0x0d +,0x14,0x08,0x07,0x07,0x0a,0xb1,0x1a,0xbc,0xa3,0x0e,0x9e,0x9c,0x1f,0x8f,0x91,0x3f,0xa8,0xcc,0x27,0x1e,0x1c,0x1d,0x26,0x7c,0xac,0xb9,0x9d,0xa5,0xd6,0x91,0x9b,0xa2 +,0xae,0x9b,0x89,0xab,0x89,0x81,0x8e,0x81,0x83,0x88,0x80,0x80,0x83,0x81,0x85,0x87,0x88,0x89,0x8f,0xb2,0x2f,0x14,0x0e,0x10,0x0d,0x05,0x04,0x02,0x04,0x04,0x07,0x18 +,0x04,0x11,0x1b,0x01,0x22,0x19,0x00,0x0a,0x06,0x04,0x1e,0x11,0x07,0x0f,0x19,0x11,0x15,0x33,0x1a,0x1b,0x1c,0x1a,0x18,0x1e,0x18,0x13,0x1b,0xd8,0x9b,0x5a,0x93,0x91 +,0xdb,0x88,0x88,0x98,0x82,0x86,0x88,0x82,0x86,0x89,0x89,0x8e,0x9b,0xa3,0x9c,0xac,0xbd,0x9f,0xa6,0xb0,0x97,0xa8,0x9f,0xad,0x9a,0x88,0x4f,0x8b,0x8b,0xca,0x8a,0xa2 +,0x1f,0x93,0xba,0x21,0xa8,0x1d,0x19,0xe7,0x4d,0x2e,0x19,0x1e,0x17,0x0f,0x1a,0x13,0x11,0x0a,0x05,0x06,0x02,0x05,0x09,0x03,0x1f,0x27,0x0d,0x9b,0x66,0x13,0x98,0x4e +,0x3e,0x99,0x31,0x27,0x2c,0x1c,0x23,0x26,0x2d,0x2f,0x1f,0x26,0x13,0x19,0x1a,0x13,0x1d,0x0e,0xc0,0xb3,0x22,0x8a,0x9a,0x9f,0x82,0x8e,0x8a,0x81,0x89,0x85,0x81,0x83 +,0x81,0x81,0x81,0x83,0x82,0x82,0x83,0x85,0x87,0x94,0xa2,0xb9,0x31,0x1d,0x17,0x51,0x09,0x0f,0x33,0x07,0x2f,0xbd,0x0b,0x17,0x1e,0x10,0x1a,0x14,0x0e,0x0c,0x0a,0x05 +,0x03,0x05,0x02,0x01,0x04,0x05,0x05,0x0b,0x09,0x08,0x05,0x0d,0x16,0x0c,0xb6,0x6c,0x1b,0x9c,0xfe,0x2f,0x8b,0x92,0x93,0x86,0x8d,0x93,0x8b,0x8c,0x95,0x8d,0x92,0x9e +,0x93,0x8e,0x98,0x94,0xbc,0xce,0x45,0x5b,0x8f,0x2f,0x9c,0x8c,0x5d,0x8c,0x85,0x91,0x83,0x87,0x8e,0x83,0x87,0x88,0x8d,0x96,0xa7,0x2e,0xfa,0x2a,0x1d,0x1b,0x0b,0x0c +,0x0f,0x13,0x0e,0x0a,0x15,0x0a,0x0d,0xd7,0x0d,0x24,0xa6,0x0d,0x1f,0x34,0x0c,0x1d,0x1e,0x16,0x2f,0x20,0x3d,0x34,0x28,0x18,0x0d,0x20,0x1d,0x0d,0x13,0x12,0x06,0x05 +,0x17,0x0d,0x11,0x9b,0x17,0x1b,0x94,0xe9,0xa6,0x8f,0xc1,0xa9,0x97,0xad,0x98,0x89,0x8f,0x9c,0x8f,0x96,0x9e,0x8b,0x90,0x9c,0x8e,0x8c,0x8c,0x8b,0x82,0x87,0x8a,0x80 +,0x85,0x85,0x80,0x89,0x8c,0x85,0x98,0x9b,0x91,0x7d,0x2b,0x43,0x1d,0x0e,0x19,0x14,0x05,0x07,0x08,0x01,0x04,0x04,0x01,0x02,0x06,0x00,0x05,0x0d,0x00,0x0a,0x11,0x03 +,0x1b,0x25,0x0e,0x27,0x4a,0x1c,0x25,0x72,0x22,0x1d,0xe0,0x1f,0x14,0x5f,0x1f,0x18,0x41,0x39,0x17,0xa4,0xb7,0x40,0x83,0x97,0xa0,0x82,0x8f,0x8f,0x80,0x89,0x89,0x85 +,0x8d,0x98,0x8b,0x8b,0x9a,0x8d,0x9b,0x7e,0x8f,0x92,0xa7,0x99,0x97,0x26,0x97,0x97,0x32,0x89,0xbe,0x21,0x8b,0xb4,0xbf,0x8e,0x32,0x2b,0xb5,0x1a,0x15,0x29,0x0f,0x0f +,0x18,0x20,0x15,0x17,0x15,0x07,0x0f,0x0c,0x05,0x1d,0x0e,0x07,0xc1,0x17,0x1a,0x98,0x18,0x3a,0x97,0x2c,0x98,0x9c,0x40,0xac,0x9d,0xbb,0xa7,0xad,0x2f,0xcd,0x29,0x1a +,0x1d,0x3b,0x0d,0x1b,0xab,0x0c,0xac,0x8d,0x2b,0x8d,0x8a,0xa6,0x8b,0x8c,0x9f,0x97,0x9a,0xbd,0xad,0xa4,0x48,0xb9,0xc3,0x27,0xb6,0xdd,0x30,0x7a,0x1c,0x16,0xba,0x19 +,0x19,0x9f,0x13,0x2d,0x94,0x2d,0x9c,0x91,0xc2,0xa7,0xac,0xa2,0xa3,0xad,0x34,0x28,0x36,0x15,0x26,0x20,0x07,0x0c,0x12,0x07,0x2e,0x1f,0x0f,0x90,0x31,0xa6,0x85,0xa9 +,0x8e,0x88,0x93,0x8b,0x8a,0x8f,0x91,0x9a,0xa0,0x9b,0x9c,0xce,0x2d,0x29,0x20,0x2e,0x22,0x0b,0x2a,0x17,0x0f,0x9c,0x33,0xe2,0x99,0x17,0x4a,0x97,0x78,0xb8,0xaa,0x1f +,0xdf,0xa3,0x49,0xed,0x2d,0x1c,0x1a,0x1b,0x0d,0x0f,0x09,0x00,0x0d,0x01,0x09,0x14,0x03,0x2d,0x2f,0x1d,0x9a,0xa5,0xa6,0x8e,0x97,0x9b,0x8a,0x8c,0x9e,0x98,0x9b,0xad +,0x99,0x9f,0x34,0xa7,0x37,0xa9,0x8f,0x2d,0x8d,0x97,0xbb,0x83,0x90,0x98,0x84,0xa2,0x98,0x87,0x8d,0x8d,0x8b,0x93,0x9b,0x8d,0x97,0xaf,0xac,0x37,0x22,0x25,0x09,0x1e +,0x0e,0x08,0x2b,0x09,0x14,0xbc,0x13,0x2f,0x4a,0x1b,0xc5,0xdb,0x41,0xad,0xe3,0x32,0xdb,0x30,0x24,0x19,0x18,0x0f,0x1c,0x0f,0x0e,0x38,0x08,0x2b,0xbb,0x16,0xae,0x2f +,0x2b,0x94,0xac,0x9f,0x9e,0x2b,0xbe,0x9d,0x9a,0x9d,0xc6,0xb2,0x3a,0x24,0x3c,0x17,0x18,0x07,0x0f,0x0b,0x04,0x1d,0x05,0x0a,0x16,0x04,0x0e,0x1f,0x17,0x4c,0x3a,0x20 +,0x96,0x8f,0x9f,0x91,0x95,0x93,0x98,0x93,0x9e,0x9e,0x4b,0xb5,0x8c,0xc2,0x88,0x8c,0x9b,0x83,0x87,0x86,0x80,0x8a,0x87,0x84,0x8e,0x87,0x89,0x94,0x98,0xa4,0xcf,0x49 +,0xca,0x1f,0x19,0x20,0x16,0xae,0x1f,0x1c,0xa4,0x13,0x30,0xa8,0x1c,0xaa,0x29,0x0d,0x37,0x17,0x12,0x1e,0x16,0x0b,0x12,0x14,0x0d,0x0f,0x0d,0x06,0x0c,0x09,0x08,0x17 +,0x09,0x1e,0x22,0x19,0x9e,0x2f,0x2f,0x96,0xb9,0x94,0x8c,0x9e,0x95,0x93,0xaa,0x96,0x9f,0xcb,0x70,0x35,0x2b,0x18,0x1f,0x0e,0x53,0x28,0xc3,0x8f,0xd7,0x99,0x96,0xb4 +,0x8e,0x8f,0xb1,0x9a,0x58,0x2b,0xa3,0x99,0x9d,0x91,0x9a,0x9f,0x94,0x8d,0x93,0x8e,0x92,0x8f,0x86,0x94,0x85,0x87,0x8d,0x85,0x8a,0x8c,0x83,0x98,0x96,0x8f,0xcc,0x9b +,0xae,0x17,0x19,0x0e,0x07,0x09,0x03,0x02,0x01,0x00,0x00,0x02,0x01,0x02,0x08,0x01,0x0a,0x1a,0x0b,0x1d,0x26,0x11,0x74,0xd0,0x20,0x4a,0x3f,0x21,0x2c,0x25,0x2c,0x33 +,0x25,0x19,0x2d,0x40,0x4d,0x9e,0x27,0x92,0x8e,0xa5,0x87,0x8e,0x9b,0x85,0x90,0x9a,0x87,0x9f,0x92,0x91,0x9e,0x8c,0x8b,0x99,0x9e,0xa4,0xdb,0x5d,0xc9,0x26,0x2d,0x25 +,0x12,0xa9,0x3e,0x2e,0x9d,0x2f,0x3c,0x98,0xae,0xa0,0x96,0x38,0x49,0x9f,0xef,0x36,0xcc,0x18,0x14,0x21,0x15,0x13,0x19,0x09,0x22,0x1b,0x19,0x93,0x19,0x2c,0x99,0x1c +,0xbb,0x98,0x20,0xc8,0xbd,0x26,0xc7,0xbc,0x66,0xae,0xc8,0x3a,0x2f,0x2a,0x18,0x16,0x17,0x07,0x2c,0x0d,0x0a,0x1d,0x03,0x28,0xa1,0x1b,0x9c,0x95,0xaa,0x86,0x89,0x88 +,0x82,0x84,0x85,0x82,0x82,0x85,0x87,0x84,0x8b,0x8b,0x98,0xc4,0x8b,0xb0,0x9c,0x8d,0x1e,0xac,0xda,0x0e,0x46,0x1e,0x0b,0x0c,0x05,0x08,0x0a,0x09,0x06,0x09,0x09,0x09 +,0x0f,0x10,0x06,0x0b,0x06,0x05,0x1e,0x05,0x14,0x1d,0x03,0x4f,0x23,0x10,0xa0,0x3a,0xaf,0x92,0xaa,0x98,0x93,0x93,0x97,0x96,0x92,0x9e,0xae,0xa5,0xd0,0xa5,0xde,0x60 +,0x90,0x2d,0x8e,0x8a,0xbf,0x87,0x99,0xab,0x86,0x92,0x91,0x8d,0x9f,0x98,0x97,0x90,0x99,0x8f,0x9a,0x9f,0x93,0xa0,0x3f,0xc8,0x23,0x19,0xb8,0x0c,0x2b,0x2e,0x08,0x3e +,0x1d,0x0f,0xf4,0x19,0x18,0x3d,0x1f,0x29,0x1f,0x18,0x1c,0x24,0x19,0x14,0x12,0x0c,0x06,0x0b,0x07,0x0b,0x19,0x05,0x1d,0x30,0x19,0x9b,0x5a,0x23,0x9b,0x6c,0xc7,0x94 +,0xad,0xcc,0x55,0x3d,0x2b,0x38,0x34,0x28,0x2b,0x3e,0x24,0xc6,0x48,0x2e,0x90,0xb0,0x8b,0x81,0x8d,0x82,0x86,0x89,0x80,0x81,0x82,0x80,0x81,0x83,0x82,0x81,0x85,0x87 +,0x8c,0x9b,0x9d,0xdf,0x0e,0x0b,0x03,0x01,0x09,0x02,0x04,0x09,0x00,0x0a,0x0b,0x08,0x15,0x0c,0x0a,0x17,0x14,0x13,0x1b,0x1a,0x10,0x14,0x18,0x16,0x27,0x1b,0x0f,0x1b +,0x11,0x0d,0xb2,0x1d,0x28,0x97,0x1d,0x9c,0x94,0x3d,0x90,0x98,0xad,0x8c,0x8d,0x91,0x8c,0x8d,0x8e,0x88,0x86,0x98,0x93,0x92,0xab,0xa7,0xa5,0x2c,0xa9,0x2b,0x13,0x97 +,0x38,0xba,0x90,0xdd,0x98,0x8c,0x9d,0x90,0x92,0xa4,0x94,0x94,0xa5,0xa4,0xc0,0x1d,0x20,0x25,0x0f,0x0c,0x11,0x06,0x12,0x17,0x09,0xdf,0x13,0x0c,0xc2,0x14,0x1f,0xc1 +,0x17,0x21,0x23,0x14,0x2e,0x2d,0x39,0x51,0x47,0xc3,0xba,0xbc,0x27,0x15,0x23,0x13,0x18,0xe6,0x08,0x18,0x1f,0x06,0xe6,0x27,0x10,0xa7,0x22,0x2a,0x91,0x9d,0x94,0x88 +,0x89,0x87,0x87,0x89,0x85,0x86,0x87,0x89,0x86,0x89,0x8b,0x82,0x8c,0x8a,0x80,0x90,0x88,0x8b,0xaf,0x8d,0x9c,0x3d,0xbd,0x17,0x0b,0x11,0x0a,0x0b,0x0c,0x04,0x07,0x05 +,0x07,0x08,0x05,0x05,0x01,0x0e,0x09,0x08,0x22,0x07,0x0c,0x1c,0x0a,0x2e,0x4b,0x12,0x48,0x2d,0xbb,0x99,0xaa,0x9d,0x9c,0xa4,0xb4,0xaa,0xaa,0xd4,0x2f,0x33,0x1a,0xab +,0xad,0x3d,0x88,0xa8,0x98,0x84,0x99,0x8c,0x87,0x93,0x8a,0x89,0x8d,0x8b,0x95,0x9a,0x93,0x96,0x98,0x9d,0xa1,0xae,0x47,0xae,0x3f,0xa3,0xa6,0x16,0x98,0xbe,0x21,0x90 +,0x27,0x25,0xa4,0x21,0xcb,0xe6,0x27,0xc1,0x4c,0x2a,0x38,0x2c,0x1a,0x19,0x19,0x0f,0x0b,0x0e,0x05,0x0a,0x0e,0x00,0x1b,0x11,0x0d,0xb5,0x15,0x2b,0x9f,0x2c,0xdc,0xa9 +,0xd2,0xa3,0xba,0xcf,0x52,0x17,0x1d,0x1e,0x14,0x10,0x0c,0x11,0x09,0x17,0xcd,0x1d,0x91,0x97,0xa0,0x82,0x89,0x87,0x80,0x85,0x82,0x81,0x82,0x80,0x81,0x81,0x82,0x83 +,0x84,0x87,0x91,0x9f,0x3b,0x2d,0x0f,0x10,0x0e,0x00,0x0a,0x04,0x04,0x0d,0x03,0x08,0x12,0x07,0x16,0x1d,0x0e,0x1b,0x17,0x15,0x1e,0x11,0x12,0x0f,0x08,0x09,0x0a,0x0d +,0x02,0x12,0x0f,0x0a,0x9c,0x28,0x25,0x8f,0x47,0x9a,0x86,0x9f,0x8d,0x8c,0x9b,0x8f,0x8d,0x8d,0x8d,0x95,0x97,0x94,0x91,0x9c,0xa6,0xb0,0x25,0x96,0xc7,0x46,0x8d,0x2f +,0xb1,0x90,0xd1,0x8f,0x8d,0xb1,0x89,0x8a,0x91,0x88,0x8b,0x91,0x8d,0x97,0xb4,0xad,0xcc,0x1a,0x14,0x0e,0x07,0x1d,0x07,0x0e,0x3a,0x09,0x3e,0xbd,0x13,0xcf,0x2b,0x1c +,0xab,0xb0,0x4f,0x32,0x1d,0x16,0x24,0x20,0x1a,0x18,0x15,0x0a,0x12,0x0c,0x0e,0x2b,0x05,0x21,0x2a,0x09,0xb5,0x2d,0x0b,0xdc,0x1f,0x1e,0xa8,0x60,0x6e,0xb7,0xaf,0x96 +,0x8d,0x97,0x93,0x8e,0x8f,0x8e,0x88,0x97,0x8b,0x86,0x9a,0x82,0x84,0x89,0x80,0x88,0x88,0x80,0x86,0x86,0x87,0x95,0x94,0x92,0xb8,0x37,0x1b,0x0b,0x09,0x07,0x03,0x01 +,0x04,0x00,0x06,0x05,0x03,0x12,0x04,0x0a,0x1f,0x06,0x19,0x23,0x0a,0x14,0x15,0x14,0x1f,0x29,0x1c,0x3a,0x2b,0x37,0xbd,0xb7,0x2c,0x22,0x2c,0x19,0xab,0x1c,0x5f,0x9e +,0x22,0x9d,0x9b,0xac,0x8c,0x92,0x9d,0x8a,0x8f,0x8d,0x88,0x93,0x8f,0x8c,0x96,0x91,0xa4,0xae,0x58,0xb9,0x2c,0xca,0xae,0x21,0x8b,0x9b,0x9b,0x85,0xa8,0x98,0x89,0x9f +,0x90,0x94,0xa7,0x9e,0x4e,0x3a,0x42,0x24,0x26,0x1d,0x1f,0x0f,0x0c,0x15,0x09,0x1e,0x0c,0x11,0x49,0x0d,0x1e,0x28,0x08,0x28,0x24,0x0d,0x64,0x1e,0x1f,0x3b,0x21,0x41 +,0xc3,0x1f,0x2b,0x20,0x12,0x10,0x17,0x0a,0x07,0x1b,0x02,0x1e,0x2d,0x0e,0x97,0x34,0xcc,0x89,0x9d,0x8a,0x88,0x8c,0x85,0x82,0x86,0x84,0x83,0x85,0x88,0x85,0x88,0x8a +,0x88,0x9c,0x83,0x8e,0x8e,0x8c,0xc8,0x87,0x81,0x11,0x05,0x84,0x2b,0x15,0x23,0x03,0x0b,0x02,0x09,0x05,0x07,0x03,0x00,0x04,0x00,0x01,0x00,0x00,0x01,0x00,0x02,0x02 +,0x01,0x08,0x04,0x12,0x2e,0x15,0x2e,0xb4,0xa9,0x92,0x8b,0x8e,0x94,0x8a,0x80,0x86,0x89,0x84,0x81,0x80,0x83,0x81,0x84,0x81,0x81,0x82,0x80,0x81,0x81,0x81,0x83,0x84 +,0x82,0x86,0x8a,0x87,0x8b,0x8a,0x8c,0x99,0xaf,0x31,0x2d,0x17,0x0d,0x08,0x0d,0x04,0x04,0x0d,0x00,0x07,0x07,0x00,0x04,0x06,0x00,0x01,0x01,0x00,0x01,0x00,0x01,0x01 +,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x04,0x08,0x01,0x11,0x09,0x0b,0x5a,0x1a,0x4b,0xb1,0x2d,0xa7,0x90,0x93,0x8f,0x89,0x87,0x83,0x82,0x83,0x83,0x82,0x83,0x82,0x83 +,0x83,0x80,0x86,0x83,0x81,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x83,0x85,0x85,0x86,0x85,0x87,0x87,0x8c,0x86,0x8b,0x89,0x81,0x9d,0x89 +,0x8b,0x9f,0x8e,0xac,0x17,0x1c,0x0d,0x08,0x0b,0x02,0x02,0x01,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x03,0x01,0x02,0x04 +,0x01,0x04,0x04,0x03,0x05,0x04,0x04,0x03,0x04,0x04,0x05,0x06,0x03,0x0f,0x09,0x14,0x2c,0x0b,0x4c,0xa8,0x2d,0x9d,0x98,0x95,0x89,0x91,0x92,0x88,0x8f,0x8f,0x8b,0x8c +,0x8b,0x8b,0x8e,0x9e,0x8e,0x9f,0x8f,0x8c,0x99,0x85,0x89,0x86,0x83,0x87,0x83,0x80,0x83,0x80,0x82,0x82,0x82,0x82,0x82,0x83,0x82,0x84,0x85,0x83,0x85,0x89,0x8a,0x8b +,0x84,0x88,0x86,0x84,0x91,0x8f,0x97,0x9f,0x8b,0xdc,0x13,0x43,0x1a,0x11,0x0e,0x10,0x1e,0x0d,0x0a,0x35,0x3a,0x1a,0x21,0x29,0x4f,0xb7,0xbd,0x3d,0xaf,0xc7,0xd5,0x8e +,0x92,0x91,0x89,0x8f,0x86,0x83,0x87,0x84,0x84,0x88,0x84,0x89,0x8b,0x8f,0xa9,0xa5,0x41,0x23,0x13,0x1b,0x0c,0x0b,0x1c,0x0a,0x08,0x0a,0x03,0x06,0x07,0x01,0x02,0x00 +,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x04,0x02,0x01,0x03,0x02,0x03,0x05,0x03 +,0x08,0x07,0x08,0x09,0x0b,0x0b,0x0a,0x19,0x0c,0x21,0xa9,0x3a,0xb2,0xaa,0xad,0x90,0x96,0x96,0x84,0x89,0x8b,0x85,0x84,0x80,0x82,0x82,0x80,0x80,0x80,0x81,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x85,0x85,0x8d,0xa8,0xad,0x52,0x4c,0x1c,0x15,0x1b,0x0f,0x1f,0x18,0x0b +,0x1f,0x0f,0x09,0x18,0x0b,0x07,0x06,0x04,0x08,0x07,0x07,0x09,0x05,0x0a,0x0d,0x0b,0x0c,0x07,0x0a,0x08,0x0a,0x0d,0x04,0x0a,0x09,0x04,0x0f,0x09,0x05,0x0d,0x07,0x0d +,0x0f,0x07,0x09,0x0a,0x0b,0x09,0x09,0x09,0x06,0x07,0x08,0x07,0x0b,0x06,0x0c,0x0f,0x0c,0x37,0x16,0x0f,0x33,0x1b,0x24,0x3f,0x19,0x1b,0x23,0x1c,0x20,0x25,0x26,0x24 +,0x2f,0xc1,0xdc,0xd3,0x2b,0x27,0xb9,0x3e,0xb6,0x47,0x2d,0x92,0xa6,0xac,0x91,0x9c,0x98,0x9b,0x93,0x85,0x8c,0xbf,0xa1,0x92,0x9d,0xbb,0xc5,0xaf,0x48,0x1d,0x19,0xce +,0xae,0x21,0xad,0x93,0x92,0x8e,0xad,0x8b,0x80,0x86,0x81,0x81,0x83,0x81,0x81,0x80,0x80,0x81,0x81,0x81,0x81,0x80,0x86,0x8a,0x90,0x9e,0xb0,0x17,0x17,0x0a,0x02,0x08 +,0x03,0x03,0x04,0x01,0x05,0x07,0x05,0x0a,0x06,0x09,0x0c,0x0b,0x10,0x0c,0x0a,0x0c,0x09,0x10,0x0e,0x10,0x1f,0x14,0xc4,0xa7,0xbe,0x92,0x9c,0x90,0x88,0x8d,0x87,0x89 +,0x8b,0x87,0x87,0x85,0x87,0x88,0x86,0x86,0x83,0x87,0x8b,0x87,0x8d,0x8c,0x8d,0x9c,0x97,0xa6,0xa6,0x98,0xa7,0xaa,0xa7,0xa5,0x94,0x94,0x9c,0xa5,0xa2,0x9f,0xab,0xa2 +,0xad,0x3a,0x5b,0x5d,0x57,0x34,0x1a,0x2e,0x3a,0x1d,0x21,0x1e,0x1d,0x19,0x10,0x24,0x20,0x0c,0x10,0x2e,0xbc,0x26,0x15,0x29,0xbf,0x35,0x26,0x4c,0xd1,0x1c,0x0e,0x19 +,0x19,0x0d,0x06,0x0c,0x11,0x06,0x04,0x06,0x0b,0x14,0x0e,0x11,0x17,0x15,0x1a,0x2f,0xae,0x9e,0x98,0x90,0x89,0x86,0x84,0x82,0x81,0x80,0x80,0x81,0x82,0x81,0x82,0x84 +,0x84,0x8b,0x9c,0xa7,0xbd,0x3e,0x1e,0x11,0x0b,0x0b,0x0d,0x09,0x07,0x06,0x06,0x09,0x0a,0x09,0x08,0x06,0x08,0x09,0x09,0x0c,0x0c,0x09,0x0e,0x15,0x18,0x18,0x18,0x2b +,0x3b,0x5a,0xce,0xbf,0xc0,0xb6,0xa0,0x99,0x95,0x93,0x96,0x8f,0x89,0x8d,0x91,0x95,0x97,0x93,0x98,0xa0,0x9d,0xbe,0x7e,0xad,0xa8,0xa3,0xab,0xb0,0x9f,0x97,0x9e,0xa1 +,0x9c,0x9f,0xa7,0x9e,0x95,0xa0,0x45,0x65,0xa9,0xad,0x3d,0x4b,0xb5,0x5d,0x3e,0x4c,0xcb,0xc8,0x20,0x22,0xa9,0xb5,0x22,0x16,0x21,0x2c,0x19,0x1f,0x57,0x5f,0x2a,0x24 +,0x5b,0xd5,0x20,0x1f,0x27,0x24,0x1a,0x0c,0x09,0x0c,0x0b,0x0c,0x0d,0x0c,0x0c,0x0b,0x11,0x1d,0x1d,0x1a,0x1a,0x1f,0x23,0x2e,0x68,0x63,0xbc,0xa3,0x9b,0x8f,0x8a,0x88 +,0x84,0x82,0x81,0x81,0x81,0x81,0x81,0x80,0x81,0x81,0x85,0x88,0x8a,0x8f,0x99,0xaa,0x4d,0x28,0x1f,0x16,0x0f,0x0a,0x06,0x06,0x07,0x07,0x04,0x03,0x03,0x05,0x06,0x07 +,0x09,0x0a,0x0a,0x12,0x17,0x17,0x1a,0x18,0x23,0x35,0x44,0x49,0x2f,0x40,0xbb,0xb5,0xaa,0xa5,0xa2,0x9f,0x94,0x8d,0x95,0x9b,0x97,0x96,0x93,0x99,0x99,0x99,0xa8,0xa8 +,0x98,0x97,0xa4,0xa8,0x98,0x8d,0x96,0xa6,0x9d,0x95,0x9d,0xc0,0x9f,0xa1,0x41,0x2e,0xd2,0xa8,0x58,0x22,0x53,0x9f,0xa4,0x55,0x55,0xb1,0xbd,0x37,0x4a,0xb4,0x70,0x28 +,0x28,0x45,0x45,0x32,0x2b,0xe3,0xb2,0x29,0x1d,0x27,0x2d,0x29,0x1f,0x18,0x15,0x0f,0x0e,0x13,0x16,0x14,0x10,0x10,0x14,0x10,0x0e,0x10,0x16,0x16,0x13,0x0f,0x0a,0x0c +,0x11,0x16,0x1a,0x26,0x33,0xbd,0x99,0x8f,0x88,0x86,0x85,0x82,0x81,0x81,0x81,0x82,0x81,0x80,0x81,0x82,0x82,0x85,0x87,0x89,0x92,0x9d,0xd7,0x22,0x19,0x0f,0x0a,0x05 +,0x03,0x03,0x04,0x04,0x03,0x05,0x06,0x08,0x0c,0x0d,0x0c,0x0d,0x0e,0x12,0x1b,0x16,0x10,0x13,0x18,0x1b,0x20,0x29,0x43,0x3a,0xd7,0x9e,0x9c,0xa8,0xa9,0x95,0x92,0x9e +,0x9b,0x98,0x9f,0xaa,0xae,0x98,0x99,0xae,0xa8,0x94,0x8e,0x9a,0xaa,0x96,0x90,0x9f,0xa4,0x9a,0x9d,0xbf,0xca,0xaf,0xa5,0xaa,0xd3,0xb7,0x9c,0xa2,0xb8,0xb4,0xae,0xa8 +,0xd5,0x3e,0xcb,0x35,0x22,0x2c,0x31,0x43,0x28,0x1e,0x2d,0x59,0xcd,0x70,0xe6,0x3b,0x31,0x39,0x33,0x5c,0x3b,0x1c,0x1e,0x1c,0x17,0x1a,0x1a,0x19,0x1f,0x20,0x16,0x0f +,0x0f,0x11,0x12,0x12,0x11,0x0c,0x08,0x0a,0x0c,0x0e,0x12,0x17,0x1a,0x45,0xa9,0xad,0x9a,0x8e,0x89,0x85,0x84,0x83,0x83,0x82,0x81,0x81,0x81,0x81,0x82,0x82,0x82,0x83 +,0x89,0x8e,0x93,0x9f,0xd9,0x24,0x12,0x0d,0x0a,0x07,0x08,0x05,0x04,0x05,0x08,0x09,0x06,0x06,0x09,0x0a,0x08,0x0a,0x0a,0x09,0x0a,0x0d,0x13,0x12,0x12,0x1d,0x63,0xbf +,0x3a,0xd0,0x9e,0x9e,0xa9,0x9b,0x96,0x9e,0xa7,0x9d,0x93,0x96,0xa0,0xa1,0x8f,0x8d,0x9c,0x9f,0x9b,0x9c,0x9f,0xa5,0xa0,0xae,0x61,0xc1,0xa6,0xa2,0xad,0xbb,0xa3,0x93 +,0x99,0xa3,0xa5,0xa3,0xa5,0xa5,0xa2,0xa5,0xdc,0x30,0x31,0x55,0x4e,0x3e,0x4f,0x3f,0xc4,0xd7,0x34,0x3f,0x66,0xc6,0xb9,0x40,0x2e,0x20,0x1e,0x2c,0x38,0x3a,0x29,0x1c +,0x1e,0x3c,0x56,0x29,0x1d,0x21,0x19,0x11,0x0f,0x0e,0x0c,0x09,0x0a,0x0c,0x0c,0x0a,0x0a,0x0b,0x15,0x1a,0x14,0x18,0x1f,0x2c,0x6d,0xaa,0x98,0x92,0x8d,0x88,0x85,0x82 +,0x83,0x82,0x81,0x80,0x80,0x81,0x81,0x81,0x82,0x85,0x87,0x8c,0x9f,0x6a,0x44,0x29,0x13,0x0b,0x0b,0x0a,0x09,0x09,0x0a,0x09,0x07,0x07,0x0a,0x0c,0x09,0x05,0x09,0x0c +,0x09,0x0a,0x0f,0x12,0x12,0x1b,0x2c,0x2f,0x29,0x26,0x45,0xaf,0xb7,0xc8,0xb6,0xaa,0xa8,0xa4,0x9f,0x9e,0x9d,0x9a,0x94,0x90,0x94,0x99,0x9a,0x98,0x98,0x9d,0xa4,0xaa +,0xa9,0xab,0xa8,0xaf,0xaf,0xac,0xad,0x9f,0x9e,0xa2,0xae,0xa4,0xa6,0xac,0xab,0xc9,0xcd,0xcc,0xde,0x57,0xde,0x4d,0x4a,0x76,0x4e,0x39,0x3c,0x39,0x2f,0x2e,0x28,0x28 +,0x23,0x23,0x26,0x27,0x27,0x29,0x2f,0x32,0x35,0x37,0x3f,0x37,0x33,0x34,0x32,0x2c,0x27,0x2b,0x23,0x23,0x25,0x29,0x27,0x2a,0x2d,0x2e,0x38,0x3e,0x52,0x63,0xcb,0xda +,0xc2,0xe9,0xc2,0xbb,0xb8,0xad,0xac,0xa8,0xa8,0xa3,0xa3,0xa5,0xa5,0xa0,0xa2,0xa1,0xa7,0xa7,0xae,0xac,0xa8,0xaa,0xa7,0xa2,0xa2,0xa3,0x9e,0xa5,0xa6,0xa5,0xae,0xb3 +,0xbd,0x69,0x52,0x3a,0x2f,0x27,0x27,0x22,0x23,0x23,0x20,0x1f,0x1c,0x1b,0x1b,0x1c,0x1c,0x1c,0x19,0x1c,0x1f,0x1c,0x23,0x2a,0x25,0x37,0x2e,0x3d,0xdf,0x4f,0xca,0xbd +,0xb5,0xae,0xaa,0xa5,0xa9,0xa6,0xa3,0xa4,0x9b,0xa0,0x9d,0x98,0x9c,0x99,0x9c,0x9f,0x99,0x9d,0x9d,0x9c,0xa5,0xa2,0xa1,0xa6,0xaa,0xaf,0xb1,0xad,0xb3,0xb5,0xba,0xc0 +,0xcf,0x79,0x4d,0x4f,0xe1,0x3d,0x39,0x40,0x30,0x26,0x24,0x21,0x26,0x21,0x1e,0x27,0x23,0x20,0x1e,0x19,0x1e,0x1f,0x18,0x1d,0x21,0x1c,0x1e,0x1e,0x20,0x22,0x1d,0x1e +,0x1f,0x25,0x21,0x1d,0x23,0x24,0x1f,0x21,0x20,0x25,0x2c,0x2c,0x36,0x3b,0x49,0xf0,0xca,0xab,0xad,0xac,0xa0,0x9e,0x99,0x94,0x96,0x92,0x8f,0x8f,0x8d,0x8f,0x8e,0x8f +,0x90,0x8f,0x92,0x92,0x94,0x96,0x9b,0x9e,0xa0,0xa8,0xae,0xb7,0xe5,0x5a,0x47,0x2c,0x30,0x2b,0x1f,0x22,0x1c,0x1a,0x19,0x16,0x16,0x13,0x13,0x12,0x10,0x12,0x13,0x11 +,0x14,0x16,0x16,0x1a,0x1d,0x1d,0x21,0x28,0x2c,0x3c,0xfd,0xc3,0xbd,0xaf,0xac,0xa9,0xa4,0xa0,0x9e,0x9f,0x9e,0x9d,0x9c,0x9d,0x9e,0x9f,0x9d,0xa0,0xa3,0x9e,0xa0,0xa5 +,0xa3,0xac,0xaa,0xa1,0xaa,0xa5,0xa3,0xab,0xab,0xae,0xb4,0xb4,0xbe,0xbd,0xc0,0xd2,0xda,0x68,0x42,0x3c,0x3a,0x2e,0x34,0x36,0x2c,0x2c,0x2e,0x27,0x2d,0x2f,0x2b,0x3a +,0x37,0x36,0x40,0x38,0x36,0x3a,0x30,0x31,0x37,0x37,0x39,0x3f,0x32,0x38,0x35,0x2d,0x36,0x31,0x2e,0x32,0x2f,0x2d,0x3b,0x3b,0x3f,0x5a,0x4b,0x52,0xcf,0xdd,0xcf,0xbb +,0xbd,0xbb,0xb1,0xb0,0xab,0xa7,0xa9,0xa4,0xa6,0xa5,0xa3,0xa5,0xa5,0xa9,0xaa,0xaa,0xab,0xab,0xae,0xaf,0xb6,0xc3,0xc5,0x69,0x4a,0x46,0x35,0x2e,0x2d,0x28,0x28,0x24 +,0x21,0x20,0x1f,0x21,0x1f,0x1f,0x20,0x1e,0x1f,0x21,0x23,0x28,0x29,0x2c,0x2e,0x2e,0x36,0x39,0x3b,0x4a,0x48,0x55,0xd4,0xd9,0xc7,0xb6,0xb6,0xb4,0xac,0xac,0xaa,0xa7 +,0xa8,0xa8,0xa5,0xa4,0xa4,0xa0,0xa2,0xa6,0xa5,0xa7,0xab,0xab,0xac,0xad,0xb1,0xb3,0xba,0xbf,0xbf,0xcd,0xdd,0xd6,0xfa,0x4f,0x5e,0x46,0x3a,0x3c,0x3a,0x37,0x3b,0x3e +,0x3d,0x3c,0x3d,0x34,0x36,0x38,0x2f,0x33,0x33,0x34,0x33,0x38,0x38,0x35,0x3b,0x3e,0x3b,0x3f,0x47,0x40,0x47,0x44,0x44,0x4e,0x5e,0xea,0xdd,0xd2,0xcc,0xef,0xd6,0xce +,0x5d,0xde,0xe1,0x76,0xe2,0xd6,0xcd,0xc9,0xbc,0xbc,0xbe,0xb4,0xb7,0xb6,0xaf,0xb5,0xb1,0xb0,0xae,0xad,0xae,0xab,0xac,0xaf,0xac,0xaf,0xb4,0xb2,0xbb,0xc2,0xbf,0xd0 +,0xe7,0xd9,0x71,0x56,0x48,0x47,0x3f,0x37,0x35,0x2f,0x2d,0x2d,0x2d,0x2d,0x2d,0x2c,0x2b,0x2a,0x2c,0x29,0x29,0x2c,0x28,0x28,0x2d,0x2a,0x2d,0x33,0x2f,0x37,0x37,0x3a +,0x49,0x48,0x5b,0x6b,0xed,0xc8,0xc3,0xba,0xb6,0xb8,0xb3,0xb8,0xb6,0xb4,0xb9,0xaf,0xb6,0xb9,0xb2,0xbb,0xb8,0xb4,0xb9,0xba,0xba,0xb8,0xbc,0xbc,0xbd,0xd0,0xbe,0xc1 +,0xce,0xbb,0xc7,0xd7,0xc5,0xf5,0x5e,0x7c,0x4c,0x59,0x4b,0x45,0x48,0x43,0x4a,0x46,0x45,0x44,0x44,0x4a,0x46,0x49,0x45,0x41,0x56,0x4d,0x58,0xd0,0x6f,0xdc,0xc8,0x5b +,0xed,0xfa,0x4d,0x77,0x4e,0x48,0x5f,0x46,0x4e,0x5e,0x44,0x50,0x54,0x48,0x53,0x4b,0x41,0x4f,0x4f,0x4b,0xea,0xd3,0xee,0xcd,0xc6,0xe9,0xd5,0xd6,0x68,0xcf,0xed,0x58 +,0xd1,0x66,0xf6,0xca,0xf0,0xcb,0xc9,0xd5,0xc2,0xde,0xe1,0xcb,0xeb,0xd5,0xcf,0xdb,0xcc,0xcf,0xd6,0xe0,0xee,0xf7,0x67,0xde,0x55,0x51,0x7c,0x48,0x56,0x58,0x48,0x5e +,0x57,0x55,0x5d,0x4e,0x63,0x5d,0x59,0xec,0x67,0xdf,0xcd,0xe4,0xcf,0xd8,0x7e,0xd6,0xdc,0xdb,0xe8,0xdc,0xdd,0x66,0xe9,0x66,0x61,0x77,0x58,0x66,0x59,0x51,0x68,0x59 +,0x61,0xe8,0x65,0xdc,0xda,0x63,0xf4,0x56,0x4d,0x5c,0x5d,0x50,0x53,0x5d,0x4b,0x52,0x5c,0x55,0x6b,0x61,0x67,0x5a,0x55,0x58,0x5a,0x70,0x5e,0xf4,0xde,0xd6,0xcf,0xd2 +,0xd7,0xdc,0xee,0xd8,0xca,0xdd,0xce,0xca,0xdd,0xcd,0xd0,0xd3,0xc6,0xcf,0xd0,0xd4,0xe6,0x76,0xfb,0x76,0x59,0x6f,0x64,0x7a,0xda,0x6c,0x67,0x69,0x4c,0x61,0xfd,0x4b +,0x6e,0x66,0x4b,0xe4,0x5b,0x5c,0xd0,0x70,0xf0,0xdc,0x60,0x6b,0xe9,0x5f,0x5a,0xf7,0x71,0xec,0xd8,0x5c,0x61,0x67,0x4b,0xf1,0x61,0x4a,0xe4,0x4d,0x49,0xe4,0x4e,0x7a +,0xcd,0x54,0xe9,0xd9,0x57,0xdc,0xe1,0x57,0xfd,0xdf,0x61,0xee,0xde,0x5b,0x67,0x5e,0x4c,0xf3,0x70,0x5a,0xd5,0x59,0x66,0xcf,0x61,0xdc,0xd5,0x5b,0xd5,0xdb,0x5d,0xde +,0xeb,0x5e,0xf2,0xdb,0xed,0xd4,0xcd,0x6a,0x73,0x68,0x53,0xdd,0xef,0x65,0xd6,0xfd,0xf2,0xd2,0xf7,0xd3,0xd2,0x6c,0xda,0xfb,0x5f,0xe7,0x7d,0x5d,0x76,0xd9,0xd9,0xd8 +,0xd8,0xf7,0x75,0x72,0x59,0xfc,0x75,0x56,0xe6,0x69,0x53,0xd5,0xdc,0xde,0xce,0xfa,0xe5,0xec,0x65,0x6a,0x57,0x57,0x5f,0x6a,0x7d,0x78,0x7a,0x7e,0x53,0x50,0x59,0x57 +,0x5c,0x5e,0x6c,0x5a,0x5e,0xd8,0xf7,0xe5,0xcd,0xdb,0xdd,0xde,0xef,0x6d,0x79,0x6d,0x69,0xf6,0xda,0xe2,0xda,0xdd,0x5d,0xed,0xde,0xfc,0xe1,0xe8,0x7a,0xfd,0x7c,0xe6 +,0xeb,0xd7,0xd9,0xe5,0xfc,0x7c,0xec,0x6c,0xf0,0xfa,0x6c,0xe9,0xde,0xf8,0xe8,0xfc,0x58,0x73,0x74,0x5b,0xf8,0x69,0x56,0x5e,0x59,0x5b,0xfc,0x62,0x5f,0x63,0x51,0x65 +,0x5e,0x64,0xf8,0x68,0xfd,0xe4,0xee,0xdf,0xe8,0x5b,0x58,0x63,0x5e,0x65,0xea,0x67,0x6b,0x72,0x64,0xec,0xe8,0x5e,0xeb,0x5d,0x4c,0x5c,0x4c,0x61,0x6e,0x6e,0xdf,0xd9 +,0xd3,0xcc,0xcb,0xdf,0xe6,0xcf,0xdb,0xdb,0xd0,0xea,0xea,0xdc,0xf0,0xe7,0xdb,0x71,0xef,0x5d,0x4d,0x50,0x4c,0x5a,0x59,0x5b,0x77,0xdb,0xce,0xd1,0xce,0xcf,0xd5,0xcd +,0xce,0xdd,0xd7,0xd9,0x7b,0xe6,0xec,0xfc,0xd8,0xdb,0xf8,0x63,0x65,0x53,0x4e,0x5b,0x45,0x48,0x5d,0x52,0x5e,0xe9,0xf5,0x77,0xe8,0xd8,0xd8,0xcd,0xcd,0xdd,0xdc,0xdc +,0xdd,0xce,0xd6,0xda,0xd9,0xed,0xfc,0x4f,0x62,0x60,0x48,0x4e,0x4d,0x4b,0x61,0x5d,0x5a,0x5d,0x66,0xe8,0xe9,0xd4,0xd9,0xe9,0xd6,0xdc,0xe2,0xcd,0xd8,0xce,0xd5,0x71 +,0xfe,0x62,0xe5,0x64,0x52,0x5d,0x58,0x5c,0x65,0x54,0x51,0x5b,0x5b,0x5e,0x67,0x6e,0x68,0x6e,0xf4,0x7d,0xd9,0xcf,0xda,0xca,0xd2,0xe2,0xd3,0xdd,0xe2,0xe2,0xe9,0xe4 +,0xdd,0xdf,0xe5,0xe4,0x6c,0x5c,0x5a,0x5a,0x55,0x53,0x59,0x4d,0x4c,0x5a,0xe8,0xe6,0xd6,0xcc,0xd9,0xdc,0xe2,0xfc,0xe4,0xed,0xe7,0xdf,0xd3,0xcc,0xd0,0xce,0xdb,0xf5 +,0xfb,0x7d,0x52,0x50,0x4f,0x42,0x44,0x4f,0x4d,0x57,0xe8,0x7b,0x63,0xe5,0x5a,0x5c,0xdd,0x5f,0x6d,0xcf,0xcc,0xcb,0xc8,0xc9,0xcf,0xd4,0xcb,0x6b,0x56,0x4e,0x39,0x30 +,0x32,0x2b,0x3d,0x7b,0x3e,0xb9,0xb5,0xc6,0xb0,0xb2,0xc9,0xbc,0xbc,0xc3,0xdc,0xc8,0xcb,0x62,0xc8,0xc6,0xd6,0xcf,0xdb,0x49,0x35,0x28,0x2b,0x1f,0x1b,0x31,0xbb,0x25 +,0xd0,0x9a,0x33,0xb0,0x9e,0x4f,0xbb,0xaf,0xb1,0xcf,0x53,0xab,0x5e,0x50,0xa1,0xae,0xd0,0xa0,0xc4,0x2d,0xb6,0x37,0x25,0xec,0x3b,0x2a,0x1f,0x18,0x1d,0x0f,0xcf,0xb0 +,0x20,0x87,0x96,0x16,0xb0,0xc1,0x12,0x3c,0x88,0x86,0x1f,0x0a,0x0f,0x1a,0x8e,0x85,0x8c,0x8f,0x98,0x1d,0x08,0x2e,0x97,0xb1,0x24,0x05,0x01,0x0d,0x0b,0x09,0xa8,0x90 +,0x87,0x8c,0x07,0xa5,0x80,0x88,0x87,0xa1,0x1c,0x2c,0x25,0x2c,0xd1,0xaa,0xaa,0x0d,0x08,0x12,0x1a,0x8e,0x8b,0x2d,0x2d,0x1c,0x17,0x09,0x04,0xa7,0x80,0x2f,0x5f,0x30 +,0x09,0x91,0x83,0x94,0xb8,0x9c,0xa5,0x14,0x0b,0xa5,0x9e,0x2c,0xb9,0x17,0x20,0x9d,0x38,0x29,0xa5,0x91,0xbc,0x18,0x1f,0x1e,0x38,0x8b,0x1a,0x0e,0x9c,0x1a,0x3e,0x99 +,0xa8,0xf6,0x1c,0x22,0xa3,0xa5,0x98,0x96,0xd5,0x93,0xd7,0x21,0x95,0x8c,0xad,0x37,0x25,0x13,0x0b,0x08,0x0a,0x09,0x91,0x17,0x12,0x93,0x31,0x8b,0x84,0x91,0x28,0x1a +,0x93,0x97,0x5f,0x92,0xb7,0x16,0xb3,0x1d,0x16,0xae,0x8a,0x95,0x18,0x0f,0x13,0x16,0x0e,0x0f,0x1f,0x86,0x33,0x00,0x1c,0xcb,0x89,0x81,0x8f,0x9c,0x9e,0xa2,0xb5,0x2d +,0x94,0x96,0x2a,0x2c,0x09,0x07,0xa9,0x52,0x29,0x9a,0x60,0x14,0x0c,0x1b,0x30,0x2f,0x87,0x32,0x0c,0xa4,0x2b,0x9a,0x85,0x9f,0x1b,0x29,0xaa,0x30,0x2b,0x8d,0x8d,0xca +,0x9e,0x27,0x0b,0xe9,0xa5,0xb3,0x9c,0x38,0x11,0x08,0x07,0x11,0x27,0x88,0x2b,0x1e,0x91,0x15,0xbe,0x88,0x94,0x9f,0xd7,0x97,0xab,0x14,0xb8,0x41,0xad,0x8d,0x51,0x1c +,0xa5,0x8e,0xcc,0x25,0x19,0x18,0x10,0x0c,0x07,0x11,0x95,0x0e,0x13,0xa7,0xbf,0x87,0x85,0xac,0xa7,0x95,0x8f,0xa7,0x3c,0x8d,0x99,0x33,0xe4,0x0f,0x0c,0x43,0x4f,0x2a +,0x1b,0x12,0x1d,0x1b,0x1e,0x13,0xba,0x8d,0x0c,0x20,0x97,0xae,0x88,0x87,0xb7,0x28,0xad,0x9b,0x48,0x57,0x8d,0x8f,0x21,0x1e,0x0d,0x0d,0x9e,0x9e,0xe8,0x3a,0x0f,0x06 +,0x06,0x14,0x3f,0x8d,0x87,0x1d,0xa8,0xa4,0x1f,0x8d,0x86,0x9b,0xd1,0x27,0x38,0x15,0x18,0x9d,0xb1,0x9c,0x95,0x14,0x13,0xa3,0x91,0xa3,0xae,0x23,0x10,0x0e,0x0f,0x0b +,0xee,0x94,0x06,0x2d,0xb6,0x23,0x8c,0x87,0x92,0xa4,0xb6,0xa0,0x31,0x23,0x8f,0x9a,0xa2,0x8f,0x0f,0x08,0xbe,0xab,0xa8,0x45,0x21,0x14,0x0a,0x0f,0x05,0xb9,0x96,0x12 +,0x9d,0x5e,0x57,0x8b,0x9f,0xae,0xa7,0x91,0x90,0xa7,0x9e,0x91,0x9f,0xb9,0xae,0x0e,0x13,0xad,0x3c,0x14,0x15,0x0b,0x07,0x0f,0x25,0x1f,0x9c,0x8b,0x12,0x9e,0x8e,0xcd +,0x86,0x8d,0x9e,0xaf,0x2b,0xa8,0x1d,0x1e,0x94,0x38,0x3e,0xa6,0x15,0x29,0x9a,0x9e,0x58,0x24,0x0f,0x0d,0x15,0x22,0x14,0xaf,0x9b,0x08,0xbb,0x94,0x5c,0x8b,0x86,0x9d +,0x57,0x29,0xc4,0x2a,0xdc,0x8a,0xa5,0x63,0xaa,0x0b,0x09,0x9e,0x92,0x9d,0xb9,0x2e,0x18,0x0b,0x1a,0x08,0x1d,0x8d,0x0d,0x1d,0xaf,0x19,0x9d,0x8d,0x94,0x9b,0x9c,0x8d +,0xd2,0xdc,0x89,0x92,0xaf,0x9e,0x1f,0x12,0xd3,0xad,0x2b,0x18,0x0b,0x0a,0x0a,0x0b,0x10,0x23,0x86,0x28,0x2d,0x8a,0x2e,0x9b,0x88,0x93,0x97,0xae,0x99,0x2a,0x14,0x94 +,0x99,0x6b,0xab,0x61,0x1a,0x36,0xbb,0x1e,0x25,0x1f,0x13,0x13,0x15,0x14,0x09,0x9d,0x2a,0x28,0x83,0x98,0x94,0x84,0x99,0xb4,0x6b,0xbf,0xbd,0x1d,0x9e,0xb5,0x14,0x3b +,0x1a,0x15,0x9f,0x98,0x9d,0x42,0x27,0x1e,0x16,0x21,0x22,0x12,0x96,0x43,0x0b,0x95,0xca,0x39,0x90,0x9b,0xc7,0x48,0x9a,0x9d,0x3c,0x97,0x8d,0x2e,0x24,0xc3,0x19,0xae +,0x97,0xcc,0x28,0x16,0x11,0x16,0x15,0x4b,0x14,0xb2,0x9d,0x01,0xaf,0x98,0xd9,0x8d,0x8f,0x9a,0x38,0x28,0xa9,0x24,0xa0,0x84,0x9d,0x69,0xaa,0x2f,0x35,0xb9,0xd3,0x2a +,0x1a,0x11,0x0b,0x06,0x12,0x11,0x1a,0x8e,0x1c,0xb0,0x85,0xa9,0x8e,0x8b,0x98,0x9d,0x4a,0xa3,0x4e,0x20,0x96,0x3a,0x0d,0x2f,0x2a,0x2d,0xb4,0xa5,0xa9,0x31,0x49,0x1f +,0x0d,0x1b,0x1f,0x0f,0x99,0x38,0x17,0x8b,0xaf,0xad,0x8c,0x99,0xa4,0xb8,0xaf,0xae,0x1b,0xb7,0xa8,0x19,0x4e,0xb0,0xcc,0x62,0x2c,0x6a,0x21,0x30,0xba,0x1e,0x30,0xb8 +,0x0d,0x5c,0x73,0x0a,0x97,0x97,0x3c,0x9e,0xae,0x2a,0x2f,0xbd,0x93,0xae,0x93,0x8e,0x32,0xe1,0x9c,0x57,0xaf,0xb6,0xdb,0x26,0x17,0x20,0x09,0x0c,0x2c,0x0a,0x12,0x9c +,0x13,0xa1,0x87,0x99,0x94,0x97,0xa4,0xda,0xe3,0x93,0xad,0xcd,0x9c,0x2b,0x1b,0xb6,0xa3,0x5d,0xa7,0xad,0x30,0x18,0x19,0x0e,0x11,0x24,0x20,0x07,0x49,0x24,0x0d,0x8a +,0x93,0x91,0x87,0x90,0x96,0xb2,0xa2,0x98,0x27,0xad,0x49,0x11,0x22,0x2e,0x1f,0x25,0xca,0xb8,0xf1,0x41,0x4d,0x2e,0x30,0x47,0x16,0x0e,0x9c,0x1d,0x3b,0x8c,0xca,0xad +,0xb7,0x6b,0xc1,0x3b,0x94,0x9a,0x37,0x98,0xbc,0x34,0xb3,0xb3,0xc5,0xcc,0xb3,0xd8,0x1b,0x1f,0x28,0x1c,0x16,0x2a,0x0f,0x19,0x99,0x1b,0xbf,0x92,0xdc,0xac,0xa3,0xa5 +,0xa1,0x4d,0x98,0x56,0x1f,0x99,0xaf,0xad,0x97,0x99,0xaf,0xdd,0xca,0x2c,0x13,0x2f,0x1b,0x0a,0x0c,0x11,0x03,0x23,0x91,0x21,0x92,0x85,0xa9,0x95,0x90,0x96,0x9a,0xc3 +,0x93,0x2c,0x16,0xa5,0x23,0x1c,0xba,0xc9,0x27,0x48,0xb0,0x2f,0x31,0xad,0x27,0x0e,0x19,0x1c,0x08,0xad,0x95,0x12,0x92,0x90,0x38,0x96,0x9a,0x93,0xa4,0xc3,0x99,0x17 +,0x25,0x9d,0x1f,0x3f,0x9d,0x37,0x2b,0x3d,0x2e,0x3a,0xc0,0xb4,0x2b,0x19,0x2c,0x23,0x0c,0x99,0xbc,0x0f,0x90,0xbd,0x1c,0xaa,0xbc,0xa3,0x61,0xb4,0x8f,0x2f,0x9c,0x8e +,0xe2,0x9c,0x9a,0xd7,0xd2,0x27,0x5f,0x37,0x16,0x1c,0x0d,0x0a,0x16,0x13,0x0f,0x95,0xc9,0x37,0x88,0x9d,0xaa,0x92,0x99,0xa1,0x66,0xae,0x9c,0x1a,0xb3,0x9b,0x36,0xbc +,0xa1,0xd0,0x29,0x3d,0xb7,0x1e,0x14,0x26,0x12,0x0c,0x1f,0x16,0x0e,0x98,0x48,0x6e,0x85,0x96,0x96,0x8b,0x98,0x9f,0x53,0xae,0xad,0x0f,0xf4,0xb6,0x0d,0x2a,0xc5,0x1f +,0x39,0xa7,0xa8,0x2e,0x40,0xaf,0x1e,0x1c,0xb3,0x14,0x1c,0x97,0x18,0x33,0x93,0x35,0xbb,0xa4,0xd6,0xae,0xe3,0x98,0x9f,0x2f,0x8f,0xa6,0x21,0x9f,0xbb,0x2b,0xc0,0x3b +,0x2b,0x1c,0x28,0x39,0x15,0x20,0x51,0x0f,0x2a,0x9e,0x17,0xaa,0x94,0xda,0xa4,0xab,0xc5,0xab,0x3d,0x9a,0xa2,0x73,0x8e,0xaa,0xb6,0x9b,0xc1,0xcd,0x37,0x1b,0x28,0x10 +,0x17,0x19,0x0a,0x19,0x1d,0x0d,0xac,0x99,0x39,0x8c,0x8c,0x9c,0x96,0x9c,0x9c,0xb5,0xfe,0x9b,0x2a,0x20,0xae,0x25,0x24,0x5c,0xda,0x40,0x29,0xd4,0x50,0x23,0xdf,0x29 +,0x16,0x46,0x17,0x13,0x9a,0x31,0x37,0x8e,0xa4,0xb7,0x9c,0x9d,0xaa,0x55,0xab,0xa4,0x20,0x6f,0xa3,0x29,0x37,0xac,0x2d,0x27,0x3e,0xc6,0x60,0x59,0xb0,0x2b,0x27,0x31 +,0x0f,0x33,0xaf,0x1a,0xac,0xaf,0x24,0xd5,0xb5,0xbb,0xbd,0xb0,0x94,0xa6,0xc1,0x92,0x9f,0xaf,0x9a,0xb6,0x2e,0xf9,0x2e,0x24,0x1f,0x1b,0x1b,0x10,0x18,0x11,0x16,0x9d +,0x55,0xd8,0x8f,0xad,0xac,0x9a,0xa7,0xa5,0xbe,0x9e,0xae,0x2c,0xa4,0xa9,0xc2,0xa8,0xad,0x3a,0x36,0x3e,0x24,0x1f,0x23,0x1d,0x13,0x18,0x14,0x0d,0xa8,0xb6,0x30,0x8d +,0x95,0x9f,0x94,0x9b,0x9c,0xaf,0xa4,0xab,0x21,0xda,0x46,0x23,0x35,0x2c,0x2e,0x27,0x3f,0x4f,0x36,0xb7,0x35,0x2a,0x45,0x23,0x14,0xa1,0xb7,0x1b,0x96,0xad,0x2e,0xac +,0xb2,0xba,0xcd,0xa6,0x9e,0x31,0xac,0x9c,0x6d,0xb0,0xab,0x5b,0x36,0x46,0x42,0x27,0x2e,0x32,0x1c,0x21,0x1c,0x11,0xaa,0x5c,0x1d,0x92,0xb0,0x4a,0x9f,0xb9,0xab,0x65 +,0xac,0x9f,0x29,0xa2,0x99,0xde,0x9a,0xa2,0x4e,0xcd,0x71,0x32,0x2d,0x23,0x20,0x10,0x12,0x0e,0x0a,0xa4,0x1d,0x2e,0x8a,0xb9,0xa7,0x94,0x9e,0x97,0xa9,0x95,0x97,0x26 +,0x9b,0xab,0x1c,0xa8,0x3d,0x1b,0x29,0x2c,0x2c,0x1e,0x28,0x21,0x1c,0x26,0x10,0x22,0x96,0x1d,0xa0,0x8d,0x34,0x9c,0x9f,0xac,0xa1,0xae,0x96,0xae,0x23,0x97,0xc8,0x23 +,0xa1,0x4c,0x23,0x3b,0x24,0x2b,0x14,0x28,0x2d,0x15,0x38,0x10,0xa7,0xad,0x28,0x8a,0x9d,0x2e,0x96,0xab,0x21,0xbe,0xab,0x4d,0x3e,0xa6,0xa3,0x34,0xaa,0x96,0x4a,0x6d +,0x9c,0x49,0x23,0x34,0x2c,0x12,0x17,0x18,0x0a,0xb7,0x29,0x2b,0x9a,0xc2,0xa8,0x9f,0xa1,0xa9,0xa9,0x9a,0x9e,0xed,0x9d,0xa5,0xd7,0xa8,0xab,0xc3,0x46,0x62,0x38,0x1d +,0x20,0x26,0x0c,0x19,0x0c,0x23,0xbb,0x11,0x97,0xa3,0xd7,0x9a,0x9e,0xa4,0x9e,0x9b,0x95,0xa9,0xa0,0x92,0xd0,0xaa,0x9f,0x5a,0x23,0x26,0x1d,0x19,0x13,0x17,0x13,0x0f +,0x1a,0x12,0xbb,0x47,0x67,0x8a,0xa5,0x9e,0x94,0xa0,0xaa,0xc5,0xa1,0xa9,0x2f,0xac,0xae,0x34,0xac,0xb0,0x2e,0x67,0x42,0x2e,0x2b,0x1b,0x22,0x14,0x20,0x0c,0x28,0xa2 +,0x13,0x95,0x8f,0x49,0x94,0x9a,0xaf,0xaf,0xba,0x9b,0x4a,0x49,0x9d,0x35,0x58,0xa9,0x58,0x3c,0xcb,0x43,0x31,0x27,0x29,0x1c,0x1c,0x1c,0x0e,0xa3,0x1f,0x1d,0x90,0x4e +,0x4c,0x9c,0xaf,0xc2,0xac,0xa5,0x99,0x6b,0x9c,0x98,0xea,0xa1,0xa3,0xd9,0x3e,0x3b,0x28,0x1e,0x15,0x19,0x16,0x19,0x0c,0x72,0xaa,0x0e,0x93,0x97,0x3a,0x97,0x9b,0xb0 +,0xac,0xa4,0x9d,0xbb,0xb2,0x95,0x54,0xbd,0xa4,0x32,0x3a,0x3d,0x26,0x26,0x1a,0x18,0x14,0x17,0x0e,0x23,0xa1,0x17,0xa4,0x8f,0xd0,0x9e,0x93,0x9f,0xa7,0xa5,0x96,0xad +,0x33,0x96,0xcd,0x21,0xaa,0x53,0x1c,0x56,0x3b,0x23,0x1e,0x27,0x1c,0x1b,0x1a,0x1b,0x9a,0x2a,0x31,0x8e,0xc4,0xdf,0x9e,0xaa,0xc5,0xbe,0xa2,0xa9,0x40,0x9e,0x9b,0x36 +,0xa8,0xa4,0x2b,0x4d,0x50,0x2e,0x1e,0x1b,0x1f,0x16,0x19,0x11,0xae,0xb9,0x19,0x92,0xa1,0x3d,0x9c,0xa5,0xb6,0xd2,0xb2,0x9c,0x38,0xc7,0x8f,0xae,0x68,0x96,0xb3,0x32 +,0xb6,0x5a,0x25,0x19,0x22,0x0e,0x0f,0x0e,0x14,0xa9,0x11,0x58,0x8e,0x38,0xab,0x93,0x9e,0xa4,0xa0,0x94,0xa8,0x78,0x92,0xa7,0x7a,0xa7,0xb0,0x2c,0x27,0x42,0x2e,0x13 +,0x1c,0x1e,0x0e,0x14,0x0f,0xa8,0x3d,0x19,0x8c,0xa6,0x35,0x96,0x9a,0xab,0xa6,0x9b,0x99,0x38,0xa7,0x92,0x37,0xbc,0x9d,0x45,0x20,0x37,0x2c,0x19,0x1a,0x1b,0x10,0x19 +,0x10,0x1c,0x97,0x1b,0xad,0x89,0x4e,0xaf,0x92,0xa1,0xc3,0xae,0x9e,0xae,0x1f,0x9b,0xa0,0x22,0x9d,0x9f,0x2c,0x35,0xca,0x33,0x18,0x1e,0x23,0x13,0x13,0x0e,0xc6,0x3e +,0x15,0x90,0xa1,0x33,0x9a,0x98,0xae,0xb7,0x98,0x9a,0xcd,0xac,0x96,0x64,0x48,0x9d,0x55,0x27,0x51,0x3c,0x24,0x1a,0x21,0x1a,0x14,0x1b,0x0e,0xac,0x39,0x1c,0x8f,0xad +,0x5e,0x97,0x9f,0xad,0xad,0x9d,0x98,0xd9,0xa3,0x95,0x60,0xb0,0xa5,0x3a,0x36,0x2e,0x23,0x1a,0x15,0x1e,0x10,0x14,0x1f,0x10,0x9e,0x56,0x35,0x8b,0xa6,0xad,0x93,0x9d +,0xb0,0xaa,0xa2,0xa5,0x34,0xb0,0xa4,0x2d,0xf5,0xad,0x46,0x27,0x45,0x37,0x1e,0x23,0x27,0x14,0x1c,0x1d,0x10,0x9e,0x3d,0x30,0x8c,0xaa,0xb9,0x98,0x9e,0xab,0xb1,0xa2 +,0x9f,0x33,0xb5,0xa5,0x2c,0xda,0xbb,0x3f,0x27,0x37,0x3c,0x29,0x25,0x2e,0x1d,0x1c,0x23,0x10,0xa6,0x4f,0x1f,0x90,0xb2,0x3b,0x9b,0xab,0xb3,0xab,0xa3,0x9a,0xbf,0xaf +,0x9a,0x47,0xbb,0xa6,0x34,0x2e,0x45,0x28,0x21,0x23,0x1f,0x18,0x18,0x1e,0x0e,0xaa,0xca,0x1f,0x8f,0x9d,0x49,0x99,0x9f,0xba,0xae,0xa7,0x9b,0xc6,0xc1,0x9b,0x6b,0x44 +,0xa1,0x3d,0x2b,0x4e,0x31,0x26,0x27,0x1f,0x1c,0x13,0x25,0x0e,0x2c,0x9c,0x19,0x9c,0x8f,0x4b,0x9d,0x98,0xaf,0xa8,0xbe,0x97,0xba,0x2c,0x9b,0xbf,0x24,0xae,0xd9,0x25 +,0x3b,0x45,0x3e,0x2a,0x27,0x2e,0x18,0x25,0x17,0x1b,0x9b,0x1d,0xd3,0x90,0x54,0xc4,0x9c,0xab,0xbb,0xb5,0x9a,0xa2,0x3d,0x9c,0x9e,0x2f,0xb2,0xae,0x2a,0x47,0x3a,0x3b +,0x2a,0x1e,0x2c,0x19,0x19,0x21,0x0e,0xad,0xbe,0x1d,0x93,0xa1,0x45,0x9f,0xa2,0xb3,0xb4,0xa8,0x9b,0xc7,0xb6,0x9d,0xb7,0x62,0xab,0xce,0x46,0x3a,0x3c,0x2e,0x1d,0x21 +,0x1c,0x14,0x22,0x0e,0x21,0x9a,0x1c,0xa8,0x91,0xcb,0xaa,0x9b,0xaa,0xab,0xb6,0x9c,0xa6,0x38,0xa5,0xa8,0x2f,0xc2,0xbf,0x3b,0x42,0x2c,0x76,0x29,0x1e,0x3d,0x1b,0x16 +,0x2e,0x0e,0xc0,0xad,0x1b,0x94,0xa0,0x5a,0x9b,0xaa,0xaa,0xa7,0xbb,0x9a,0xe6,0x7a,0x9e,0xc7,0x3f,0xb6,0xd6,0x37,0x2d,0x5e,0x3f,0x1f,0x3b,0x2e,0x14,0x27,0x1d,0x13 +,0xa5,0x39,0x37,0x9a,0xb4,0xbc,0xa4,0xac,0xa9,0xba,0xa8,0x9c,0x53,0xa9,0x9b,0xd9,0xd3,0xab,0x40,0x2d,0x49,0x45,0x28,0x28,0x2f,0x1e,0x12,0x29,0x14,0x19,0x9c,0x28 +,0x62,0x94,0xb6,0xb4,0x9c,0xa9,0xa8,0xbe,0xa2,0xa4,0x3e,0xa6,0xa0,0x3e,0xce,0xb0,0x42,0x31,0x44,0xde,0x23,0x2a,0x2e,0x1a,0x14,0x2a,0x11,0x24,0xa2,0x21,0xaf,0x96 +,0xbc,0xa4,0x9b,0xa8,0xa7,0xc9,0xa0,0xaa,0x38,0xa8,0xa9,0x2c,0xbb,0xb7,0x30,0x4a,0xf2,0x5f,0x2a,0x31,0x31,0x18,0x18,0x2f,0x0c,0x2e,0x9d,0x16,0xa8,0x92,0xfb,0xa5 +,0x9a,0xa6,0xae,0xc6,0x98,0xac,0x31,0x9e,0xab,0x29,0xbc,0xb9,0x3c,0x3b,0xe5,0x52,0x26,0x2e,0x24,0x1a,0x17,0x21,0x0f,0x3f,0xaf,0x1e,0x9c,0x98,0xe0,0x9e,0x9c,0xaf +,0xac,0xaf,0x9c,0xb5,0xda,0xa2,0xbe,0x63,0xb2,0xd9,0x67,0x4c,0x39,0x39,0x28,0x1e,0x22,0x16,0x17,0x20,0x0d,0xdd,0xa7,0x1f,0x97,0x95,0xbb,0x9d,0xa0,0xad,0xac,0xb6 +,0xa0,0xbb,0x41,0xac,0xac,0x45,0xc1,0xae,0x6f,0x4a,0x3b,0x52,0x29,0x1e,0x2c,0x14,0x16,0x20,0x0c,0xbc,0xb2,0x21,0x93,0x9b,0xba,0x9f,0xa6,0xa0,0xb6,0xae,0x9a,0xf8 +,0x4b,0xa3,0xb9,0x3f,0xaf,0xbd,0x43,0x34,0x4b,0x34,0x20,0x2a,0x24,0x10,0x1e,0x19,0x0f,0xa4,0x4e,0x43,0x95,0xa1,0xa9,0xa5,0xa0,0x9f,0xbb,0xa7,0x9c,0x3d,0xdc,0x9e +,0xd3,0x48,0xb1,0x6c,0x2e,0x31,0x2e,0x2c,0x23,0x23,0x21,0x11,0x24,0x15,0x24,0x9e,0x2d,0xa5,0x95,0xaf,0xa6,0xa0,0xa1,0xae,0xbd,0x9c,0xb8,0x4a,0xa9,0xac,0xec,0xcc +,0xbf,0x4c,0x2a,0x33,0x3b,0x20,0x1f,0x27,0x16,0x18,0x1f,0x16,0xab,0xc6,0x3e,0x97,0xa3,0xab,0xa6,0xa5,0xa3,0xca,0xa9,0xa5,0xc4,0xb8,0xab,0xa7,0x50,0xf1,0xbe,0x34 +,0x28,0x40,0x30,0x20,0x1f,0x1c,0x17,0x1c,0x12,0x4d,0xaa,0x20,0xa0,0x9a,0xb3,0xa8,0xa2,0x9f,0xab,0xb6,0xa2,0xa7,0xb3,0xaa,0x9f,0xcd,0x4b,0xbe,0x3a,0x2b,0x30,0x36 +,0x26,0x1c,0x18,0x15,0x1d,0x0f,0x25,0x9e,0x1f,0xb3,0x96,0xb5,0xa4,0xa3,0x96,0xa5,0xc7,0x99,0xa7,0xbe,0xa1,0xa5,0xc1,0x4f,0x7a,0x34,0x23,0x2b,0x2e,0x23,0x1f,0x1a +,0x13,0x21,0x10,0x1e,0x9b,0x23,0xb3,0x94,0xb0,0x9f,0xa5,0x96,0xa1,0xc8,0x9b,0xa3,0xc7,0xa9,0xa3,0xc2,0x49,0xe2,0x44,0x24,0x28,0x33,0x25,0x1b,0x18,0x13,0x1f,0x0d +,0x23,0x9f,0x22,0xa4,0x9a,0xac,0x9f,0xa5,0x97,0xa2,0xb0,0x97,0xa1,0xaf,0xab,0xa2,0xbc,0x39,0xc8,0x33,0x20,0x26,0x25,0x22,0x18,0x13,0x1c,0x1e,0x0d,0x45,0xab,0x20 +,0xa0,0x9d,0xa4,0xa5,0x9e,0x92,0xac,0xab,0x97,0xa2,0xb3,0xae,0xa1,0xcd,0x35,0xd8,0x2a,0x1f,0x25,0x2b,0x1d,0x15,0x17,0x1e,0x1a,0x12,0xaf,0xc9,0x2d,0x9e,0x9f,0xa1 +,0xad,0x9d,0x96,0xb6,0xa8,0x98,0xa9,0xae,0xa0,0xaa,0xe9,0x3f,0x3b,0x2c,0x1f,0x25,0x2d,0x1d,0x14,0x17,0x22,0x11,0x25,0xa9,0x2c,0xb9,0xa0,0xab,0xaa,0xa9,0x98,0xa0 +,0xa4,0x9d,0xa3,0xa6,0xb7,0xa1,0xaf,0x45,0xd8,0x30,0x2e,0x23,0x23,0x2e,0x19,0x12,0x22,0x15,0x10,0xba,0x37,0x3d,0xa5,0xae,0xa2,0xcb,0x9d,0x9b,0xab,0x98,0x9d,0xa0 +,0x9f,0xa3,0xa4,0xb9,0xca,0x68,0x2d,0x2c,0x22,0x21,0x20,0x18,0x16,0x1e,0x10,0x29,0xbd,0x27,0xad,0xab,0xab,0xae,0xad,0x98,0xa9,0xa3,0x99,0x9f,0xa0,0xa1,0x9b,0xb4 +,0xbf,0xc2,0x2d,0x32,0x2a,0x20,0x20,0x16,0x15,0x1a,0x0f,0x1d,0xcb,0x28,0xc5,0xaf,0xac,0xa5,0xd1,0x97,0x9f,0xb7,0x9a,0x9b,0xa4,0x9f,0x9c,0x8e,0xbb,0xbd,0x2c,0x54 +,0xbf,0xba,0xc0,0x12,0x2c,0x00,0x02,0x00,0x13,0xce,0x0f,0xf8,0x18,0x57,0x92,0x8f,0x8d,0x8f,0x8e,0x8c,0x86,0x82,0x91,0x86,0x8c,0x7b,0x8a,0x17,0x17,0x90,0xa8,0x31 +,0x3e,0x23,0x05,0x04,0x05,0x0f,0x04,0x09,0x06,0x14,0x0b,0x0d,0x18,0x0f,0x0f,0x0d,0x4e,0x16,0x1e,0x32,0x98,0xea,0x96,0x93,0x9f,0x9e,0xb1,0x8e,0xa6,0x9c,0x9a,0xa3 +,0x95,0x8b,0x8f,0x88,0x82,0x82,0x80,0x82,0x87,0x80,0x9e,0x99,0x83,0x80,0xaa,0x0d,0xac,0x09,0x15,0x15,0x02,0x05,0x01,0x00,0x1b,0x1a,0x00,0x04,0x00,0x1b,0x0b,0x00 +,0x06,0x11,0x3e,0x31,0x8f,0x92,0x4a,0x3a,0x86,0x84,0x80,0x82,0x83,0x94,0x8d,0x85,0x89,0x86,0x86,0x8f,0xab,0x99,0xab,0x9b,0xbe,0x9f,0x48,0xac,0xc8,0xac,0x96,0xba +,0x20,0x19,0x26,0x19,0x17,0x15,0x0f,0x0d,0x0e,0x0a,0x18,0x14,0x0b,0x0d,0x07,0x04,0x04,0x07,0x03,0x08,0x1a,0x15,0xab,0x33,0x9a,0x87,0x8b,0x87,0x88,0x8a,0x88,0x8b +,0x8b,0x8a,0x8a,0x86,0x8e,0x94,0x83,0x8a,0xab,0x8f,0x85,0x86,0xaf,0x8e,0x1d,0xcd,0x2c,0x00,0x17,0x11,0x13,0x00,0x09,0x1c,0x0f,0x09,0x0a,0x0a,0x05,0x25,0x4d,0xaa +,0xa3,0x2b,0x08,0x06,0x0e,0x1c,0xaf,0x15,0xc0,0x22,0x36,0x42,0x12,0x9e,0x97,0x85,0x8e,0x9c,0x8a,0x86,0x82,0x86,0x83,0x84,0x88,0x8e,0x8d,0x97,0x8b,0x8e,0xbf,0xa6 +,0x2f,0xdf,0x1f,0x19,0x1f,0x1b,0x0e,0x09,0x0f,0x0f,0x52,0x21,0x00,0x1c,0x36,0xb8,0x3d,0x10,0x02,0x2d,0x90,0x16,0xab,0x0d,0x0b,0x00,0x0f,0x34,0x20,0x9d,0x01,0x0e +,0x3d,0x16,0x00,0x0e,0x9e,0x14,0x0e,0x05,0x96,0x8c,0x10,0xb8,0xbc,0x9d,0x86,0x80,0x84,0x84,0x85,0x89,0x8d,0x8b,0x88,0x8a,0x8b,0x90,0x35,0x0e,0x29,0x36,0x9e,0x2f +,0xad,0x21,0x11,0xe7,0x14,0x87,0xa9,0x09,0xe7,0x27,0x1e,0xbc,0x99,0xc3,0x2f,0x40,0xa9,0x96,0x91,0x90,0x91,0x88,0x3b,0x24,0xa6,0x82,0x84,0xbe,0x1a,0xa7,0x9d,0x0b +,0x3a,0xa7,0xaa,0x02,0x06,0x0b,0x94,0xca,0x00,0x23,0xc4,0x34,0x05,0x9d,0x36,0x0b,0x0b,0x38,0xfd,0x0e,0x9f,0x0b,0x0d,0x14,0x00,0x10,0x1a,0x90,0x08,0x01,0x10,0x0c +,0x24,0x21,0x92,0x09,0x11,0x05,0x19,0x80,0x90,0x8c,0xb6,0x96,0x9b,0x8e,0x80,0x83,0x80,0x84,0x8e,0x82,0x80,0x82,0x80,0x82,0x80,0x82,0x80,0x97,0x50,0x95,0x80,0x95 +,0x04,0x08,0x02,0x0d,0x02,0x01,0x02,0x00,0x08,0x02,0x08,0x07,0x06,0x00,0x0f,0x0c,0x05,0x04,0x06,0x09,0x04,0x02,0x17,0x1d,0x0b,0x13,0x04,0x06,0x19,0x93,0x8e,0x92 +,0x1c,0x0b,0xac,0x9b,0x80,0x92,0x8e,0x90,0xa8,0x80,0x84,0x80,0x8a,0x87,0x84,0x89,0x80,0x94,0x8d,0x8e,0x98,0x86,0x8f,0xab,0x0b,0x25,0x29,0x15,0x0c,0x12,0x27,0x04 +,0x07,0x14,0x1f,0x06,0x0e,0x09,0x18,0x22,0x14,0x0c,0x29,0x96,0xc7,0xa7,0x39,0xa5,0x2f,0x8a,0xaa,0x99,0x90,0x1b,0xa3,0x38,0x50,0xbf,0x9c,0x95,0x22,0x1a,0xb5,0x9c +,0x8d,0xb5,0xa4,0x9a,0x8f,0x2c,0x19,0x14,0x2d,0xa6,0xb6,0x30,0x16,0x07,0x08,0xd8,0x1f,0x0d,0x04,0x20,0x06,0x09,0x06,0x17,0x25,0x11,0x90,0x92,0x98,0x8f,0x85,0x82 +,0x80,0x81,0x82,0x82,0x80,0x82,0x88,0x96,0x81,0x87,0x59,0xac,0x1a,0x2b,0x13,0x14,0x14,0x17,0x16,0x09,0x05,0x04,0x08,0x09,0x0b,0x0f,0xda,0x16,0x26,0x14,0x13,0x0e +,0xc1,0x33,0x5d,0x9c,0x26,0x19,0x0c,0x59,0xa9,0x2b,0x03,0x0b,0x1c,0x13,0x08,0x14,0x0a,0x0f,0x0c,0x19,0xab,0xa0,0x2c,0x32,0x8f,0xb5,0x86,0x8c,0x8e,0x84,0x84,0x87 +,0x88,0x8a,0x91,0x87,0x86,0x84,0x88,0x80,0xa7,0xad,0x9a,0x64,0x9f,0xac,0xc4,0x0a,0x10,0x11,0x1a,0xc6,0x1b,0x0d,0x1c,0x50,0x22,0x19,0x3e,0xc9,0x2d,0x30,0x90,0xa4 +,0x15,0x20,0xb3,0x3a,0x9c,0x2a,0x11,0x1b,0x09,0x12,0x07,0x27,0x06,0x03,0x05,0x08,0x08,0x0a,0x06,0x10,0x21,0x0b,0x13,0x1a,0x20,0x78,0xa3,0x1d,0x9b,0x17,0xf5,0x8c +,0x89,0x84,0x90,0x8a,0x86,0x80,0x81,0x81,0x81,0x80,0x81,0x82,0x80,0x85,0x8a,0x89,0x91,0x91,0x9c,0x14,0x1e,0x23,0x1e,0x0a,0x0d,0x0c,0x00,0x0f,0x03,0x06,0x0b,0x09 +,0x01,0x05,0x06,0x0b,0x0d,0x01,0x06,0x1d,0x18,0x15,0x2c,0x07,0x12,0x0f,0x2d,0xf9,0x28,0xa2,0xd2,0xa0,0x9f,0x8d,0x84,0x89,0x86,0x84,0x8b,0x83,0x86,0x88,0x8a,0x85 +,0x97,0x9c,0x9c,0x97,0xa9,0x27,0x95,0x2a,0xb5,0xdd,0xae,0xd8,0x1e,0x27,0x29,0x1f,0x21,0xbd,0x0e,0x3b,0x44,0x16,0xab,0x2f,0x24,0x38,0xaa,0xa8,0xa1,0x3b,0x5a,0x3e +,0xaa,0xd7,0x1f,0xa4,0x17,0x4b,0x2f,0xa7,0x2d,0x2a,0x1d,0xaf,0x91,0xda,0x1b,0x23,0x8f,0x93,0xa5,0xd3,0x9f,0x20,0xa6,0x31,0xb2,0xab,0x14,0x4c,0xc9,0x30,0x14,0x0d +,0x0e,0x38,0x0d,0x07,0x09,0x03,0x04,0x05,0x0a,0x0b,0x1d,0x3c,0xb0,0x92,0x8a,0x93,0x88,0x80,0x83,0x81,0x81,0x80,0x81,0x82,0x83,0x89,0x81,0x86,0xb4,0x9c,0xa9,0x9b +,0x4b,0x0f,0x1e,0x0b,0x0c,0x11,0x0a,0x0c,0x03,0x08,0x0d,0x0b,0x06,0x12,0x14,0x14,0x1a,0x13,0xec,0x11,0x26,0x5b,0x0d,0x12,0x29,0x0d,0x0c,0x0d,0x0c,0x11,0x0e,0x0b +,0x03,0x1e,0x38,0x0d,0xbe,0xc8,0x2f,0x9d,0x9e,0x8b,0x8d,0x8d,0x8e,0x86,0x82,0x86,0x84,0x87,0x84,0x82,0x86,0x88,0x8e,0x90,0x84,0x97,0xac,0x99,0xa2,0x1d,0x16,0x1b +,0x71,0x1a,0x0e,0x17,0x16,0x1a,0x0e,0x1a,0x24,0x20,0x27,0x21,0x35,0x9b,0x14,0x1d,0x9f,0x32,0xbe,0xb9,0xaf,0xa3,0x53,0x3d,0x4e,0x1f,0x27,0x29,0x17,0x17,0x0c,0x08 +,0x0a,0x10,0x14,0x0b,0x14,0x08,0x0d,0x1e,0x0d,0x21,0x12,0x1e,0x1f,0x14,0x3b,0x18,0x20,0x5e,0xb6,0xa0,0x8f,0x94,0x8b,0x82,0x82,0x85,0x82,0x81,0x81,0x81,0x80,0x81 +,0x85,0x82,0x88,0x89,0x8e,0x97,0xb1,0x33,0x48,0x3b,0x0d,0x0d,0x0f,0x0c,0x08,0x0f,0x0a,0x0a,0x04,0x01,0x0d,0x0a,0x08,0x09,0x0d,0x0f,0x1f,0x0e,0x1c,0x19,0x17,0x12 +,0x2d,0x1d,0x0f,0x13,0x1b,0x1d,0x19,0xe6,0x26,0xb4,0xbb,0x9f,0x8a,0x8e,0x94,0x8c,0x86,0x8f,0x8c,0x8b,0x8d,0x92,0xb8,0x91,0x9c,0x91,0xad,0xaf,0x91,0x9e,0xf5,0xba +,0xb5,0x5e,0xbb,0x3b,0xb4,0x1e,0x20,0x2e,0xba,0x4b,0xce,0x67,0x69,0x9b,0x94,0xab,0xb1,0xa5,0xa6,0x9e,0xb9,0xa7,0x39,0x1f,0x15,0x5e,0x19,0x1d,0x29,0x15,0x27,0x1a +,0x25,0x12,0x2b,0x3e,0x1b,0x29,0x2b,0x20,0x1d,0x25,0x3c,0x3d,0x48,0x58,0x2c,0x3a,0xa4,0x4f,0x39,0x33,0x1c,0x1a,0x13,0x11,0x0c,0x0c,0x0a,0x0d,0x0e,0x17,0x1e,0x1f +,0xa1,0x8e,0x89,0x88,0x86,0x81,0x82,0x81,0x81,0x81,0x82,0x81,0x84,0x84,0x85,0x8c,0x8f,0x9c,0x92,0xa8,0x36,0x2b,0x1c,0x13,0x0c,0x0e,0x0b,0x04,0x04,0x07,0x07,0x07 +,0x08,0x09,0x0a,0x0c,0x15,0x19,0x11,0x12,0x1a,0x1c,0x1c,0x19,0x1a,0x19,0x1c,0x1f,0x28,0x3c,0x3f,0x33,0xa9,0x95,0xa3,0xbd,0x9d,0x97,0x99,0x95,0x95,0x94,0x9e,0x9f +,0x98,0x93,0x95,0x9a,0x97,0x8f,0x8f,0x98,0x9f,0x99,0x9d,0xa5,0xa8,0xaa,0xaf,0x45,0x41,0x4e,0x67,0x55,0x36,0x3f,0xb8,0xb2,0xbe,0xdc,0x46,0x79,0x76,0xcb,0xd9,0x36 +,0x1e,0x1c,0x25,0x34,0x31,0x2a,0x1f,0x22,0x35,0x32,0x2f,0x2b,0x35,0x2f,0x29,0x29,0x26,0x1d,0x19,0x1b,0x1c,0x1b,0x18,0x18,0x1e,0x26,0x20,0x22,0x1e,0x1a,0x18,0x15 +,0x17,0x12,0x0b,0x0a,0x0e,0x0f,0x13,0x1a,0x34,0xaa,0x90,0x8b,0x88,0x85,0x83,0x82,0x81,0x80,0x80,0x81,0x82,0x81,0x83,0x85,0x87,0x88,0x8f,0x96,0x9b,0xad,0x33,0x18 +,0x0f,0x10,0x0c,0x08,0x06,0x04,0x04,0x04,0x06,0x08,0x07,0x07,0x0f,0x18,0x15,0x16,0x18,0x1f,0x1f,0x1c,0x28,0x2c,0x1a,0x16,0x21,0x2f,0x28,0x20,0x26,0xc1,0xad,0xb3 +,0xae,0xb7,0x9d,0x9d,0x9c,0x94,0x97,0x9f,0x9e,0x98,0x91,0x92,0x94,0x92,0x8d,0x8a,0x8f,0x91,0x94,0x9a,0x9b,0x9c,0xb8,0x54,0x37,0x1f,0x1d,0x1d,0x28,0x48,0x5d,0x3d +,0x2c,0x29,0x2a,0x3f,0xaf,0x9a,0x94,0x9e,0xa1,0xad,0x4b,0x2e,0x54,0xc6,0xaa,0xa5,0x3d,0x24,0x1a,0x12,0x19,0x1f,0x36,0xa8,0xba,0xdf,0x36,0x1f,0x1d,0x1f,0x33,0xb5 +,0xcf,0x2d,0x54,0x26,0x0e,0x12,0x22,0x28,0xcb,0xb8,0x3b,0x3d,0x24,0x23,0x4d,0xc9,0x9d,0x99,0xa6,0xaf,0xc4,0x44,0xc9,0xac,0xa4,0x9e,0xbe,0x2d,0x2c,0x1f,0x1f,0xfe +,0xc8,0x9e,0x9c,0xab,0xbe,0x37,0x3e,0xae,0xa2,0x9a,0x96,0x9f,0xb4,0x2d,0x2c,0x41,0x48,0xb9,0xa1,0xdb,0x51,0x20,0x15,0x21,0x3e,0xae,0xa3,0xa9,0xaa,0xab,0xf2,0xb0 +,0x9e,0x97,0x94,0x9b,0xaf,0xb5,0x2a,0x24,0x38,0x3f,0xb3,0xc9,0x42,0x28,0x1f,0x1a,0x26,0x43,0xc2,0xa8,0xcd,0x46,0x33,0x1a,0x19,0x26,0x2d,0xc3,0xb2,0x2c,0x18,0x0f +,0x0d,0x11,0x15,0x2c,0xb3,0xd7,0x27,0x2d,0x2b,0x2b,0xc3,0xa5,0x93,0x93,0x97,0x9c,0xa9,0x5c,0xb5,0x9c,0xa0,0x94,0x96,0xac,0xbc,0xe9,0x39,0x71,0xaf,0xa0,0x9a,0xaa +,0xac,0xa2,0xaf,0xbf,0xa6,0xa1,0xa0,0x9b,0xab,0xc5,0x3c,0x2b,0x2e,0x33,0xeb,0xb4,0xc3,0x3a,0x2f,0x25,0x26,0x4c,0xbf,0xa3,0x9a,0xa9,0xc4,0x58,0x2c,0x3e,0x3d,0x49 +,0xb0,0x62,0x1e,0x12,0x0d,0x0a,0x0d,0x14,0x1f,0x27,0x22,0x1a,0x18,0x12,0x19,0x2c,0x66,0xab,0x9f,0xaa,0xc3,0x47,0x20,0x33,0xe6,0xb8,0xac,0xb4,0x48,0x29,0x1f,0x23 +,0x4c,0xac,0x9b,0x92,0x91,0x97,0x96,0x97,0x92,0x8d,0x8d,0x8b,0x88,0x8d,0x95,0x97,0x92,0x93,0x9a,0x96,0x9c,0xbc,0x19,0x15,0x11,0x09,0x07,0x0d,0x15,0x0c,0x07,0x05 +,0x07,0x09,0x09,0x09,0x14,0x20,0x17,0x14,0x0f,0x0a,0x0d,0x16,0x2a,0xbc,0xb7,0xa9,0xa7,0xb1,0xbb,0x9c,0x95,0x8d,0x8b,0x8b,0x8d,0x92,0x95,0x98,0x93,0x8e,0x8b,0x8a +,0x90,0x9a,0x9b,0xb5,0xbf,0xd8,0xaa,0xa4,0xb7,0x67,0x52,0xcd,0x3e,0xbf,0x9e,0x8c,0x8f,0x97,0x8b,0x8a,0x97,0xa7,0x8f,0x87,0x8e,0xb1,0xab,0x9a,0x22,0x06,0x0c,0x1b +,0x1b,0x0f,0x0b,0x0f,0x0e,0x06,0x06,0x11,0x1c,0x26,0x26,0x1c,0x16,0x0e,0x08,0x0c,0x12,0x19,0x21,0x22,0x1c,0x17,0x14,0x15,0x27,0x2e,0xb8,0xb1,0xc4,0xc3,0xc9,0x27 +,0x35,0xeb,0xa9,0x97,0xa1,0xad,0xb2,0xad,0x33,0xda,0xaa,0x9b,0x9c,0xab,0xa3,0x9d,0x40,0xb9,0x91,0x8a,0x88,0x89,0x85,0x85,0x87,0x95,0x8a,0x82,0x86,0x8a,0x8a,0x87 +,0x93,0x1f,0x15,0x66,0x3b,0x1a,0x12,0x14,0x15,0x08,0x05,0x0a,0x0e,0x0f,0x13,0x18,0x14,0x0e,0x08,0x0b,0x0e,0x0c,0x11,0x24,0x1b,0x13,0x10,0x0e,0x13,0x1d,0x3b,0xc9 +,0xad,0xc6,0x48,0x3f,0x21,0x24,0x4c,0xb5,0x9b,0xc2,0x3c,0xf5,0x1e,0x1b,0x25,0x3d,0xfd,0xfc,0x3e,0xb2,0x37,0x26,0xb0,0x8e,0x8d,0x8d,0x84,0x82,0x85,0x8f,0x8a,0x85 +,0x81,0x89,0x88,0x84,0x8a,0xa8,0x24,0x4c,0xb7,0x2e,0x1c,0x3f,0x2c,0x18,0x13,0x0c,0x13,0x23,0x1e,0x2c,0x32,0x18,0x0f,0x0b,0x0c,0x0c,0x0c,0x21,0x1e,0x1a,0x10,0x0e +,0x11,0x19,0x1a,0x2f,0xb8,0xbd,0xce,0x43,0x3c,0x21,0x2f,0x4c,0xa5,0xb6,0xd3,0xfa,0x34,0x1a,0x1a,0x24,0x37,0x3c,0x2f,0xb6,0x46,0x23,0x28,0x99,0x8f,0x8e,0x8a,0x87 +,0x83,0x8a,0x8e,0x8c,0x83,0x87,0x8b,0x86,0x89,0x97,0x38,0x2c,0x5b,0x27,0x12,0x1d,0x27,0x18,0x0f,0x0e,0x0b,0x0f,0x10,0x1f,0x57,0x26,0x18,0x11,0x14,0x0e,0x11,0x19 +,0x2b,0x2e,0x1b,0x16,0x15,0x10,0x18,0x23,0x3e,0xb7,0xbf,0xcd,0xcc,0x31,0x20,0xed,0xbf,0xaf,0xae,0xd9,0x4a,0x25,0x16,0x1c,0x2d,0x2d,0x2d,0xd1,0x4b,0x20,0x22,0xea +,0x96,0x98,0x93,0x84,0x82,0x85,0x8a,0x8b,0x81,0x85,0x88,0x85,0x82,0x8a,0xab,0x6a,0x5c,0x47,0x19,0x1b,0x32,0x23,0x0f,0x0d,0x0c,0x0f,0x16,0x21,0xcb,0xbf,0x3f,0x27 +,0x1d,0x11,0x15,0x1e,0x2f,0x49,0x2e,0x1f,0x19,0x11,0x11,0x1a,0x28,0x3e,0xcc,0x5e,0x3f,0x2a,0x1c,0x27,0x5d,0xc3,0xac,0xae,0xd1,0x3b,0x1d,0x18,0x21,0x26,0x28,0x48 +,0xd2,0x25,0x18,0x2e,0xab,0x9e,0x9e,0x8b,0x82,0x85,0x8a,0x8b,0x84,0x84,0x8a,0x89,0x82,0x82,0x90,0xc5,0xb9,0xbd,0x27,0x19,0x1f,0x30,0x18,0x0c,0x0b,0x08,0x0c,0x0e +,0x15,0x1f,0x1e,0x15,0x13,0x0c,0x0a,0x0e,0x16,0x21,0x26,0x26,0x1e,0x20,0x17,0x15,0x2b,0xca,0xae,0xa2,0xad,0xbb,0x49,0x29,0x42,0xae,0xa4,0x9d,0x9d,0xa9,0x48,0x20 +,0x29,0x2b,0x2a,0x37,0xad,0xcf,0x1e,0x1f,0x46,0xa4,0xa6,0x97,0x87,0x82,0x88,0x8a,0x85,0x84,0x89,0x8a,0x85,0x82,0x88,0xa0,0xba,0xbb,0x2f,0x17,0x14,0x1f,0x1d,0x0d +,0x0b,0x08,0x0a,0x0c,0x0f,0x1f,0x2b,0x28,0x1a,0x1a,0x11,0x0f,0x16,0x1e,0x2f,0x2b,0x23,0x1c,0x1a,0x16,0x18,0x23,0x3a,0xc0,0xb2,0xcd,0x33,0x25,0x27,0x4c,0xce,0xb7 +,0xa5,0xa6,0x47,0x2c,0x27,0x2e,0x27,0x2b,0xb2,0xad,0x2e,0x1a,0x36,0xbf,0xb7,0xbe,0x91,0x83,0x86,0x8c,0x89,0x82,0x85,0x8b,0x8b,0x83,0x82,0x8c,0x9d,0x9c,0xa9,0x28 +,0x1a,0x1e,0x32,0x1f,0x0e,0x0b,0x0b,0x0b,0x11,0x1b,0x2a,0x33,0x26,0x1e,0x15,0x0f,0x0f,0x17,0x1f,0x2a,0x26,0x1a,0x14,0x10,0x0f,0x1a,0x1d,0x2a,0xac,0xb8,0x5a,0x2e +,0x26,0xbf,0xae,0xab,0x9c,0x97,0x9f,0x58,0x3f,0x36,0x31,0x22,0x59,0xaa,0x36,0x15,0x16,0x31,0x38,0x24,0xbc,0x8c,0x86,0x8e,0x90,0x84,0x88,0x8b,0x8a,0x85,0x82,0x86 +,0x93,0x9a,0x9c,0xdd,0x1f,0x21,0x3e,0x23,0x15,0x0d,0x0c,0x0a,0x0c,0x0f,0x1b,0x29,0x23,0x1b,0x18,0x12,0x0c,0x16,0x1b,0x27,0x2c,0x24,0x20,0x19,0x11,0x17,0x21,0x3f +,0xb9,0xa4,0xac,0x48,0x30,0x32,0x55,0xd2,0xad,0xa7,0xa6,0x3a,0x2c,0x26,0x1a,0x19,0x23,0xb3,0xb1,0x1d,0x17,0x2f,0x50,0x2c,0x4b,0x90,0x85,0x86,0x8c,0x88,0x84,0x85 +,0x8c,0x88,0x82,0x82,0x8a,0x9c,0x9e,0xa6,0x27,0x14,0x1f,0x2c,0x1e,0x0b,0x0c,0x0c,0x0b,0x0c,0x11,0x1e,0x27,0x24,0x19,0x17,0x0d,0x0e,0x17,0x1e,0x28,0x2a,0x1e,0x1b +,0x14,0x12,0x1c,0x23,0x49,0xad,0xa4,0xbd,0x33,0x2f,0x38,0x49,0xd8,0xae,0x9e,0xaf,0x2f,0x2c,0x2c,0x1b,0x1c,0x30,0xb3,0xcb,0x19,0x1f,0x3d,0x39,0x2c,0xa4,0x8a,0x85 +,0x8c,0x8c,0x82,0x84,0x86,0x8a,0x84,0x80,0x84,0x8b,0x95,0x9a,0xad,0x29,0x1a,0x26,0x23,0x14,0x0d,0x0b,0x0c,0x0c,0x0f,0x19,0x26,0x2a,0x24,0x19,0x12,0x10,0x12,0x1c +,0x23,0x23,0x2f,0x1f,0x1b,0x13,0x18,0x24,0x22,0x4c,0xa9,0xbe,0x38,0x26,0x21,0x78,0x3c,0xd8,0x9d,0x9f,0xc6,0x3a,0x2e,0x37,0x20,0x27,0xbd,0xcd,0x20,0x16,0x1c,0x30 +,0x2a,0x2c,0x95,0x87,0x8b,0x90,0x8b,0x84,0x85,0x8a,0x86,0x83,0x83,0x88,0x93,0x95,0x96,0xb7,0x2e,0x45,0xdb,0x1f,0x10,0x0a,0x09,0x0b,0x0f,0x15,0x1c,0x22,0x1a,0x1a +,0x0f,0x0f,0x14,0x23,0x2b,0x21,0x1a,0x14,0x14,0x10,0x1a,0x25,0x37,0x3d,0x45,0x3e,0x1d,0x20,0x2e,0xb6,0xa8,0xac,0xaa,0xb0,0x4b,0x1d,0x3e,0xab,0xba,0x5b,0xba,0xbd +,0x2b,0x0c,0x11,0x37,0xc1,0x3e,0xc3,0x8e,0x8f,0x98,0xa2,0x8a,0x84,0x84,0x84,0x83,0x81,0x85,0x91,0x9e,0x90,0x90,0x96,0xc5,0x36,0x1f,0x0d,0x0c,0x0c,0x0f,0x14,0x1e +,0x1f,0x10,0x13,0x0f,0x0e,0x0e,0x14,0x1d,0x30,0x1d,0x17,0x16,0x0b,0x19,0x1e,0x2f,0xb7,0x4d,0x54,0xb6,0x22,0x26,0x6a,0xbb,0x9e,0xbc,0xaf,0xa1,0x2f,0x1c,0x1f,0x6c +,0xa2,0x33,0x3e,0xba,0x2a,0x16,0x0d,0x1e,0xca,0x2f,0x38,0x9a,0x8f,0x97,0xa6,0x94,0x82,0x82,0x84,0x83,0x81,0x83,0x88,0x94,0x96,0x8b,0x90,0x9a,0xdf,0x2c,0x1a,0x09 +,0x08,0x0e,0x10,0x19,0x15,0x12,0x12,0x0f,0x0e,0x15,0x1b,0x21,0x2f,0x23,0x1f,0x19,0x19,0x0e,0x1c,0x1f,0x41,0x2b,0x2c,0x5e,0x24,0x1e,0x26,0x5b,0xab,0xad,0x1f,0xa0 +,0x57,0x1c,0x8e,0x80,0x2f,0x1e,0x80,0xa7,0x1b,0x09,0x0b,0x13,0x08,0x24,0x19,0x2e,0x04,0x0a,0x1b,0x00,0x1f,0x18,0x04,0x01,0x00,0x06,0x12,0x08,0x09,0x1a,0x0d,0x1f +,0x0a,0x0a,0x1d,0x6f,0x97,0x89,0x88,0x88,0x80,0x81,0x86,0x87,0x81,0x81,0x80,0x85,0x85,0x83,0x82,0x86,0x8c,0x83,0x80,0x82,0x8e,0x8b,0x84,0x8b,0x88,0x85,0x91,0x9b +,0x8a,0x98,0x15,0x15,0x37,0xa6,0x0a,0x0e,0x8a,0x91,0xc5,0x2f,0x10,0x08,0x04,0x00,0x02,0x00,0x08,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x01 +,0x01,0x04,0x06,0x03,0x01,0x03,0x02,0x0e,0x2b,0x56,0x8c,0x89,0x99,0x95,0x98,0x8d,0x84,0x83,0x88,0x85,0x81,0x83,0x80,0x81,0x80,0x82,0x80,0x82,0x84,0x85,0x81,0x81 +,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x81,0x82,0x80,0x87,0x89,0x80,0x80,0x80,0x82,0x84,0x80,0x88,0x8d,0x88,0x8d,0x8b,0x83,0x98,0x48,0x5e,0x97,0x92,0x1b,0x17,0xd1 +,0x12,0x05,0x0d,0x03,0x00,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x05,0x02,0x02,0x03,0x00,0x00,0x01,0x00,0x03,0x05,0x00,0x02,0x05,0x04,0x04,0x00 +,0x02,0x04,0x01,0x06,0x03,0x01,0x0f,0x3c,0x0c,0x0f,0x2a,0x3d,0x22,0x17,0x5f,0x64,0x15,0xae,0x8d,0x9f,0x8c,0x8c,0x96,0x9e,0xbc,0x9c,0x8c,0x94,0x8c,0x8a,0x9f,0xaa +,0x9c,0x3b,0xad,0x8e,0x81,0x88,0x98,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x84,0x88,0x8e,0x85,0x81,0x86,0x87,0x85,0x95,0x95,0x98,0x7b,0xb2,0x37,0x14,0x1e,0x14 +,0x11,0x5d,0x2e,0x21,0x2d,0x8d,0x9c,0x9f,0x87,0x86,0x87,0x83,0x85,0x8a,0x84,0x82,0x82,0x89,0x9a,0x8a,0x86,0x8c,0x87,0x86,0x84,0x86,0x89,0x93,0x9a,0x9a,0x90,0x9b +,0x95,0x8f,0x92,0xb1,0xb1,0xc1,0x8f,0xa7,0x38,0x9d,0x36,0x17,0x34,0x38,0x0d,0x1b,0x0b,0x0c,0x08,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x02,0x07,0x07,0x08,0x04,0x05,0x09,0x05,0x00,0x00,0x01,0x01,0x01,0x02,0x06,0x13,0x19,0x31,0x4b +,0x1d,0x15,0x16,0x07,0x08,0x1e,0xac,0x3c,0x37,0x8e,0x9b,0x88,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x81,0x80 +,0x82,0x82,0x85,0x82,0x84,0x8e,0x92,0x8c,0x8d,0x97,0x86,0x9e,0x9d,0x87,0x88,0xae,0x95,0x8a,0x87,0x84,0x89,0x88,0x84,0x8e,0x94,0x8b,0x9e,0x2c,0x13,0x15,0x0f,0x14 +,0x15,0x35,0x2f,0x25,0x21,0x32,0x12,0x0d,0x09,0x0b,0x07,0x18,0x16,0x00,0x0b,0x2e,0x16,0x0c,0x2b,0x1e,0x2f,0x24,0x13,0x0e,0x19,0x07,0x07,0x06,0x03,0x01,0x01,0x00 +,0x00,0x01,0x05,0x09,0x0f,0x09,0x0a,0x0d,0x04,0x01,0x04,0x05,0x04,0x1d,0x09,0x04,0x13,0x2f,0x0b,0x35,0xe7,0x2b,0x31,0x24,0x23,0xb8,0xaf,0x24,0xb5,0xb3,0x2b,0x20 +,0x2c,0x0e,0x15,0x16,0x2b,0xdd,0xaa,0x34,0x94,0x8c,0xab,0x3e,0xad,0x47,0xa8,0x88,0xaf,0x9d,0x8c,0x8f,0x98,0x82,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x81,0x81,0x88,0xa3,0xac,0xad,0xa9,0x9b,0xa9,0x29,0x2e,0x1d,0x0e,0x06,0x05,0x00,0x08,0x07,0x00,0x01,0x08,0x04,0x04,0x0f,0x0e,0x14,0x1b,0x13,0x1a,0xbe,0x16,0x0e +,0x1d,0x1d,0x14,0x24,0x17,0x0b,0x0f,0x0f,0x16,0xc5,0x3f,0x3c,0x9a,0x97,0xa3,0xac,0xab,0x3f,0x8c,0x8f,0xa0,0x8c,0x83,0x8d,0x8c,0x83,0x85,0x82,0x84,0x89,0x88,0x80 +,0x87,0x8b,0x86,0x86,0x8f,0x8c,0x91,0xa1,0x78,0x34,0x28,0xb8,0xde,0xfd,0xa3,0x9e,0xa0,0xba,0x2c,0x1a,0x9f,0x33,0x0f,0x1e,0xb8,0x0f,0x0e,0x28,0xce,0xa5,0xb5,0x32 +,0xb1,0x93,0x35,0x22,0xc7,0xd7,0x1e,0x1f,0x0e,0x0b,0x07,0x04,0x08,0x1e,0x13,0x0f,0x1a,0x1f,0x20,0x22,0x13,0x09,0x1c,0x0b,0x02,0x0d,0x33,0x13,0x23,0x9f,0x8f,0x89 +,0x88,0x8a,0x86,0x80,0x83,0x83,0x83,0x82,0x83,0x81,0x84,0x84,0x8a,0xa0,0xce,0xa6,0xb2,0x2c,0x1e,0x16,0x12,0x14,0x09,0x03,0x0e,0x0a,0x01,0x08,0x0e,0x05,0x05,0x0d +,0x0e,0x1d,0x21,0x0f,0x15,0xbb,0x58,0x23,0x4e,0x33,0x38,0xbf,0x2b,0x23,0x33,0x13,0x0d,0x1e,0x24,0x1f,0x67,0xc8,0xac,0x8f,0x92,0xbf,0x99,0x92,0xc0,0xa5,0x95,0xa6 +,0xb1,0x93,0x98,0x8c,0x84,0x8c,0x8f,0x86,0x86,0x8d,0x8f,0x9b,0xb2,0xa5,0x6e,0x20,0x39,0x1a,0x0d,0x17,0x1e,0x19,0x29,0x2b,0x2c,0xae,0xaf,0x17,0x18,0x3d,0x15,0x0f +,0x26,0x27,0x0f,0x1d,0x2b,0x41,0xad,0xab,0x4d,0xdc,0xbf,0x24,0x2a,0x2d,0x23,0x2c,0x3c,0x18,0x18,0x14,0x0d,0x10,0x14,0x10,0x13,0x15,0x0f,0x1c,0xcc,0x35,0x14,0x2c +,0x2d,0x16,0x1e,0x33,0x20,0x3d,0xac,0xae,0x91,0x87,0x89,0x87,0x80,0x81,0x81,0x80,0x81,0x81,0x81,0x82,0x85,0x87,0x93,0xaf,0xb2,0xde,0x2b,0x3c,0x21,0x16,0x21,0x1e +,0x0c,0x07,0x0d,0x09,0x02,0x04,0x04,0x03,0x07,0x09,0x0d,0x25,0x32,0x1d,0x30,0xae,0xbd,0x43,0x36,0x24,0x26,0x3b,0x2a,0x1c,0x1a,0x19,0x19,0x25,0x36,0x36,0xe9,0xbe +,0xa9,0xa5,0xa6,0xc3,0xb6,0x97,0xa7,0xab,0x9d,0x9e,0xab,0x96,0x8f,0x90,0x8b,0x8a,0x90,0x8e,0x88,0x8e,0x8e,0x95,0xa0,0x9c,0x99,0xc6,0x29,0x25,0x1d,0x17,0x18,0x1a +,0x20,0x2c,0x2f,0xcf,0xc8,0xcb,0x25,0x2d,0xe4,0x25,0x1b,0x1b,0x11,0x11,0x1e,0x1e,0x2d,0xc3,0xf8,0x50,0x9e,0x9c,0xac,0xb3,0x5a,0x2a,0x28,0x1b,0x0d,0x0b,0x0a,0x09 +,0x0c,0x0f,0x10,0x1b,0x29,0x2f,0x34,0x28,0x1e,0x11,0x18,0x1c,0x14,0x1a,0x1d,0x27,0xc4,0x98,0x8f,0x87,0x83,0x82,0x81,0x80,0x80,0x82,0x81,0x82,0x82,0x83,0x86,0x90 +,0x9c,0xa6,0xc4,0x45,0x28,0x1c,0x17,0x17,0x17,0x0e,0x0a,0x0b,0x08,0x0a,0x0a,0x07,0x06,0x06,0x06,0x0a,0x0f,0x0e,0x13,0x20,0x24,0x3d,0xc1,0xe2,0x62,0xc2,0x6c,0x5f +,0xdc,0x26,0x12,0x18,0x1b,0x1c,0x23,0x2d,0x3e,0xa8,0x9a,0x9a,0x9a,0x9c,0x9b,0x9b,0x95,0xa2,0xba,0xbe,0xac,0xad,0x9c,0x91,0x8f,0x8c,0x8b,0x87,0x86,0x89,0x8e,0x8e +,0x92,0xa5,0xb2,0xba,0x26,0x1d,0x20,0x20,0x29,0x2f,0x2c,0x3f,0xa8,0xa7,0xb9,0x3b,0x2e,0x28,0x1f,0x20,0x20,0x16,0x11,0x16,0x1a,0x1f,0x21,0x29,0x45,0xba,0xbd,0x68 +,0x3d,0x3d,0xfc,0x40,0x32,0x2d,0x1b,0x0f,0x0e,0x10,0x17,0x19,0x15,0x13,0x1e,0x2b,0x22,0x20,0x1e,0x26,0x1f,0x20,0x2a,0x22,0x20,0x44,0xad,0x9e,0x8f,0x8b,0x87,0x83 +,0x80,0x81,0x80,0x80,0x80,0x81,0x82,0x83,0x87,0x95,0xae,0x64,0x31,0x20,0x16,0x11,0x11,0x18,0x16,0x10,0x0c,0x0c,0x09,0x06,0x07,0x06,0x02,0x03,0x07,0x09,0x0b,0x0f +,0x17,0x1f,0x53,0xbc,0xbe,0xbf,0xc5,0xcc,0xcc,0x48,0x3c,0x2d,0x1f,0x22,0x2d,0x3e,0x43,0x46,0xe0,0xa5,0x9c,0x9f,0xa7,0xa3,0x9d,0xa5,0x9e,0x9a,0xa9,0xad,0x9f,0x9c +,0x98,0x93,0x97,0x95,0x8d,0x8b,0x8d,0x8b,0x8b,0x8f,0x92,0x98,0x9d,0xa7,0x4e,0x2f,0x2c,0x1f,0x1d,0x1b,0x1d,0x2a,0xe2,0xd9,0x3e,0x34,0x47,0x36,0x48,0x40,0x24,0x1b +,0x16,0x14,0x19,0x20,0x1f,0x2e,0x52,0xbe,0xbe,0xb3,0xb8,0xb9,0xbe,0x3b,0x2a,0x1d,0x0f,0x0c,0x0d,0x0e,0x0f,0x11,0x0f,0x11,0x1c,0x1c,0x18,0x1b,0x1b,0x15,0x1e,0x1e +,0x1a,0x22,0x3a,0xb1,0x93,0x8e,0x8b,0x85,0x83,0x81,0x80,0x80,0x81,0x81,0x81,0x82,0x83,0x84,0x8d,0x99,0xa1,0xc0,0x36,0x1f,0x14,0x0f,0x0e,0x0c,0x0b,0x0a,0x07,0x0a +,0x0e,0x0a,0x09,0x0a,0x08,0x09,0x0e,0x10,0x12,0x18,0x19,0x22,0x5c,0x39,0x36,0xc6,0x73,0x48,0xc6,0xe3,0x3c,0x2e,0x27,0x24,0x2a,0x27,0x28,0x2e,0x3d,0xc4,0xa9,0xab +,0xa5,0x97,0x9a,0x9b,0x96,0x9c,0xa6,0x9c,0x99,0x98,0x92,0x91,0x94,0x8f,0x94,0x92,0x8e,0x90,0x93,0x95,0x9c,0xa3,0xa5,0xc8,0xc5,0x2d,0x2f,0x43,0x1e,0x1c,0x1c,0x1d +,0x19,0x1d,0x29,0x21,0x2b,0x2b,0x2a,0x2a,0x36,0x63,0x66,0xb0,0x4c,0xb3,0xaa,0xc7,0xb1,0xae,0x2d,0x26,0x23,0x13,0x18,0x11,0x13,0x15,0x17,0x11,0x16,0x14,0x0f,0x1d +,0x20,0x3f,0xaf,0xab,0xaf,0x9e,0x9c,0x94,0x8f,0x93,0x94,0x96,0x9a,0xaa,0xa3,0xa4,0x9e,0xaa,0xb1,0xa2,0xad,0xca,0xa9,0xa4,0xa1,0xa5,0x62,0x6a,0x2c,0x1e,0x19,0x1c +,0x18,0x19,0x26,0x18,0x16,0x33,0xf8,0xc4,0xa3,0xa3,0xaa,0xa5,0xa6,0xac,0x9e,0xa6,0xbe,0xcd,0x4e,0x48,0x39,0x37,0x3e,0x35,0x28,0x1e,0x1a,0x1d,0x1b,0x1d,0x27,0x1f +,0x1d,0x31,0x56,0xf2,0x9f,0x9a,0x9e,0x9d,0x9e,0xa7,0xad,0xab,0xbe,0xac,0xcb,0x4e,0xec,0x7a,0xae,0xb5,0xad,0xa0,0x9e,0x9d,0x9c,0x9c,0x92,0x94,0x9f,0xab,0xe3,0x34 +,0x40,0x4c,0x26,0x23,0x17,0x0f,0x15,0x17,0x1a,0x26,0x24,0x26,0x2b,0x22,0x24,0x2e,0x32,0x24,0x19,0x11,0x10,0x13,0x14,0x17,0x18,0x1a,0x17,0x12,0x19,0x1d,0x2b,0xcc +,0xa8,0xa4,0xa1,0x9c,0x96,0x8a,0x87,0x8a,0x8a,0x8b,0x88,0x86,0x8a,0x8d,0x8e,0x93,0x9f,0xcc,0x4c,0xc9,0xd4,0x55,0x55,0xdd,0xe1,0xdd,0xbd,0xa2,0xa7,0xbc,0xa9,0xab +,0xb3,0xbc,0xbe,0xae,0xa9,0xa4,0xa5,0xb6,0xaf,0xb2,0xc8,0x31,0x27,0x20,0x1a,0x18,0x10,0x13,0x12,0x0d,0x0b,0x0a,0x09,0x09,0x0a,0x0b,0x0d,0x0b,0x0f,0x16,0x17,0x24 +,0x41,0xcd,0xa3,0x98,0x97,0x91,0x8e,0x8d,0x89,0x89,0x8e,0x94,0x9b,0x96,0x91,0x99,0x9f,0xa7,0xa9,0x9f,0xaa,0x4b,0x6b,0xc5,0xaf,0xc8,0x2d,0x39,0xe2,0xc3,0xbb,0xb8 +,0xbe,0xbc,0x4d,0x31,0x27,0x1f,0x1f,0x13,0x0b,0x09,0x07,0x05,0x04,0x04,0x05,0x07,0x08,0x0a,0x0e,0x0f,0x12,0x19,0x27,0x2c,0x1d,0x2b,0xf6,0xbd,0xa7,0x9f,0x9c,0x90 +,0x8e,0x94,0x97,0x97,0x8f,0x8b,0x89,0x89,0x8a,0x8c,0x8b,0x8a,0x89,0x87,0x89,0x8b,0x8b,0x8d,0x93,0x99,0x9c,0xa2,0xbf,0xe6,0xf1,0x37,0x52,0x6b,0x52,0xcc,0xbb,0xb4 +,0xae,0xac,0xaa,0x9b,0x99,0xa4,0xbd,0x3a,0x30,0x2c,0x1c,0x16,0x15,0x11,0x0e,0x0b,0x06,0x06,0x07,0x09,0x08,0x0a,0x10,0x17,0x1f,0x2b,0x3a,0xbf,0xad,0xb7,0xb7,0xb4 +,0xba,0xb1,0xac,0xc3,0x46,0x2d,0x21,0x1f,0x24,0x21,0x20,0x2c,0x2f,0x2f,0x2b,0x2b,0x30,0xb1,0xaf,0x5b,0xb9,0xa2,0x9b,0x9a,0x9c,0x99,0x91,0x92,0x91,0x91,0x8f,0x8b +,0x8a,0x8b,0x8d,0x94,0x9f,0xa5,0xad,0xad,0xa8,0x4f,0x26,0x20,0x1c,0x13,0x0c,0x0a,0x0a,0x09,0x0b,0x0f,0x0f,0x15,0x1f,0x31,0xb4,0x9f,0x9d,0x98,0x8f,0x88,0x85,0x83 +,0x83,0x86,0x88,0x89,0x8a,0x8d,0x8d,0x8f,0x92,0x93,0x9d,0xbe,0x3a,0x32,0x33,0x21,0x1c,0x1c,0x17,0x16,0x13,0x0f,0x18,0x19,0x0f,0x0e,0x0d,0x0c,0x0c,0x0b,0x09,0x07 +,0x06,0x05,0x03,0x03,0x04,0x05,0x07,0x08,0x09,0x0b,0x0e,0x11,0x21,0x37,0x44,0xbf,0xad,0xa4,0x9e,0x9a,0x94,0x8f,0x8e,0x8e,0x94,0x99,0x95,0x92,0x8f,0x8f,0x93,0x8f +,0x8f,0x90,0x8e,0x8a,0x88,0x88,0x8b,0x8e,0x8f,0x93,0x93,0x97,0xa0,0x9c,0x9e,0xaa,0xb8,0xb5,0xab,0xa3,0xa1,0x9e,0x9d,0xa0,0x9f,0xa5,0x9f,0x9c,0xb1,0x38,0x2d,0x25 +,0x1f,0x1c,0x16,0x17,0x18,0x12,0x0c,0x09,0x0a,0x0d,0x0b,0x0e,0x14,0x17,0x1d,0x24,0x2b,0xbd,0xa5,0xa7,0xa8,0xb1,0xae,0xb3,0xd6,0x4f,0x36,0x22,0x1d,0x14,0x0d,0x11 +,0x17,0x1a,0x1d,0x1e,0x1e,0x1f,0x21,0x2f,0x43,0xd8,0xb8,0xd3,0xbc,0xab,0xb3,0xac,0x9e,0x99,0x97,0x98,0xa1,0x9e,0x96,0x96,0x9a,0xa2,0xa8,0xa9,0xbc,0x64,0x6b,0xc8 +,0x4e,0x23,0x18,0x12,0x0e,0x0f,0x0e,0x0d,0x13,0x19,0x18,0x1a,0x1b,0x28,0xb7,0x9f,0x98,0x8f,0x8c,0x88,0x86,0x85,0x83,0x83,0x84,0x84,0x86,0x86,0x85,0x87,0x89,0x8b +,0x8f,0x96,0xa9,0x49,0x55,0x2e,0x25,0x2e,0x24,0x1e,0x1e,0x19,0x1b,0x26,0x1e,0x14,0x0e,0x0c,0x0b,0x08,0x08,0x07,0x05,0x04,0x04,0x02,0x03,0x03,0x04,0x06,0x08,0x0a +,0x0a,0x0b,0x0e,0x18,0x23,0x34,0x5c,0xd3,0xad,0xa4,0x9c,0x92,0x8f,0x8f,0x8e,0x90,0x94,0x96,0x95,0x90,0x91,0x96,0x95,0x95,0x94,0x90,0x8e,0x8b,0x8c,0x8e,0x90,0x92 +,0x96,0x92,0x98,0x9d,0x97,0x98,0xa2,0xad,0xb3,0xa5,0x9b,0x9e,0x9e,0x9f,0xa0,0x9a,0x9c,0x9a,0x9c,0xbd,0x39,0x27,0x1c,0x17,0x13,0x0e,0x0d,0x0d,0x0b,0x08,0x06,0x08 +,0x0c,0x0b,0x0d,0x15,0x17,0x1d,0x27,0x34,0xb6,0xaf,0xd5,0xc6,0xf5,0xdb,0xc2,0xdf,0x5b,0x34,0x20,0x1a,0x11,0x0f,0x15,0x16,0x15,0x1a,0x1e,0x21,0x2f,0x2e,0x68,0xb7 +,0x4a,0xc4,0xab,0xa7,0x9d,0x9b,0x99,0x95,0x96,0x97,0x9a,0x9b,0x92,0x8f,0x8f,0x8f,0x94,0x9a,0x99,0x9d,0x9c,0x9c,0xbd,0x43,0x2e,0x22,0x1c,0x19,0x10,0x0e,0x0b,0x08 +,0x0b,0x0f,0x19,0x1f,0x24,0x4f,0xab,0x9f,0x94,0x8d,0x89,0x86,0x86,0x87,0x87,0x89,0x8a,0x89,0x8b,0x8c,0x8d,0x94,0x95,0x93,0x96,0x97,0xa3,0xbc,0xe0,0x2b,0x2b,0x56 +,0x5a,0x35,0x20,0x16,0x15,0x14,0x11,0x13,0x0e,0x0b,0x08,0x05,0x05,0x06,0x04,0x04,0x04,0x04,0x05,0x06,0x07,0x0c,0x12,0x12,0x13,0x13,0x16,0x19,0x19,0x26,0x4b,0xd0 +,0xba,0xd3,0xbe,0x9c,0x92,0x8d,0x8b,0x8c,0x8b,0x8a,0x8a,0x87,0x86,0x89,0x8c,0x90,0x92,0x8f,0x93,0x96,0x98,0x9a,0x9a,0x9e,0xb3,0xb2,0xa6,0xa6,0x9b,0x97,0x97,0x95 +,0x97,0x97,0x8f,0x8e,0x8e,0x94,0x9b,0x9d,0x9f,0xa9,0xae,0x57,0x28,0x1e,0x15,0x0e,0x0e,0x0e,0x0f,0x0f,0x0e,0x0f,0x0e,0x0e,0x0f,0x15,0x18,0x1b,0x1d,0x1e,0x27,0x25 +,0x24,0x28,0x29,0x33,0x31,0x1e,0x1a,0x1d,0x1f,0x26,0x20,0x1d,0x1d,0x1c,0x1f,0x27,0x37,0x40,0x29,0x1f,0x23,0x25,0x21,0x1e,0x1d,0x21,0x31,0x39,0x37,0x4b,0xc2,0xa8 +,0x9a,0x94,0x8e,0x8b,0x8a,0x89,0x88,0x86,0x86,0x8b,0x90,0x97,0xa0,0xa8,0xaf,0xc0,0x3b,0x1d,0x19,0x11,0x0b,0x0b,0x0c,0x0d,0x0c,0x10,0x18,0x1f,0x38,0xc1,0x9e,0x95 +,0x91,0x8c,0x88,0x87,0x86,0x86,0x84,0x84,0x86,0x88,0x8c,0x91,0x8f,0x8e,0x8f,0x8f,0x94,0x9a,0x9f,0xac,0xc4,0xc9,0x2c,0x17,0x15,0x12,0x0f,0x0e,0x0a,0x08,0x08,0x08 +,0x08,0x05,0x05,0x07,0x07,0x09,0x0a,0x08,0x08,0x08,0x07,0x0b,0x13,0x12,0x11,0x10,0x13,0x17,0x18,0x15,0x19,0x18,0x18,0x20,0x20,0x2e,0xbc,0xa8,0x9d,0x97,0x91,0x8c +,0x8a,0x89,0x87,0x86,0x86,0x87,0x8a,0x8c,0x8e,0x90,0x8f,0x90,0x94,0x94,0x98,0xa1,0xa5,0xa1,0xa0,0x9f,0xa9,0xac,0xa0,0x9c,0x97,0x94,0x92,0x94,0x9a,0x9a,0x99,0x9b +,0x9e,0xa4,0xb3,0xba,0x47,0x24,0x1b,0x13,0x12,0x15,0x14,0x17,0x19,0x15,0x15,0x15,0x16,0x1b,0x18,0x0f,0x10,0x14,0x19,0x1d,0x1b,0x1b,0x1c,0x1c,0x1c,0x18,0x18,0x23 +,0x26,0x25,0x2d,0x2c,0x26,0x29,0x1f,0x2c,0xe2,0x3a,0x33,0x35,0x2f,0x34,0x32,0x27,0x27,0x24,0x20,0x27,0x2a,0xff,0xa6,0xa3,0x9c,0x96,0x91,0x8c,0x8a,0x89,0x86,0x87 +,0x89,0x8b,0x90,0x96,0x9c,0xa9,0xc3,0x47,0x2b,0x20,0x19,0x0e,0x0d,0x0e,0x0f,0x10,0x0e,0x10,0x1a,0x27,0xec,0xa8,0x9b,0x94,0x91,0x8d,0x88,0x86,0x86,0x86,0x86,0x85 +,0x87,0x89,0x8c,0x8e,0x8e,0x8f,0x92,0x92,0x97,0x9d,0xa3,0xb8,0xbe,0xbd,0x2c,0x19,0x16,0x12,0x10,0x0f,0x0c,0x0a,0x09,0x08,0x08,0x06,0x06,0x09,0x09,0x08,0x08,0x08 +,0x08,0x09,0x09,0x0d,0x10,0x0f,0x0f,0x0f,0x12,0x16,0x16,0x17,0x1b,0x1a,0x1d,0x22,0x29,0xd1,0xa7,0x9d,0x95,0x91,0x8d,0x8a,0x89,0x87,0x85,0x86,0x87,0x88,0x8b,0x8e +,0x91,0x95,0x96,0x9b,0x9b,0x9d,0xaa,0xb6,0xb3,0xaf,0xab,0xaa,0xb0,0xa1,0x9a,0x97,0x94,0x8f,0x8d,0x8f,0x90,0x8f,0x91,0x94,0x96,0xa2,0xab,0xb9,0x33,0x22,0x11,0x0b +,0x3a,0x96,0x15,0x00,0x98,0xa0,0x11,0x30,0x0d,0x0f,0x05,0x09,0x04,0x0c,0x0b,0x00,0x07,0x00,0x03,0x01,0x03,0x06,0x01,0x03,0x05,0x04,0x07,0x04,0x06,0x0f,0x0f,0x15 +,0x46,0xa3,0xa1,0x8e,0x92,0x9a,0x8e,0x80,0x87,0x91,0x83,0x81,0x80,0x81,0x81,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x86,0x87,0x87,0x8e,0x95,0x9a,0xa7 +,0xc9,0x2d,0x1d,0x11,0x0d,0x0d,0x08,0x09,0x07,0x04,0x06,0x0a,0x08,0x06,0x0a,0x06,0x03,0x07,0x04,0x04,0x05,0x02,0x01,0x02,0x03,0x02,0x02,0x01,0x01,0x01,0x03,0x04 +,0x02,0x04,0x02,0x05,0x06,0x08,0x0c,0x15,0x2c,0x42,0xa2,0x97,0x90,0x8b,0x8b,0x87,0x85,0x82,0x83,0x83,0x83,0x82,0x82,0x82,0x81,0x82,0x82,0x82,0x81,0x82,0x81,0x80 +,0x82,0x81,0x81,0x81,0x82,0x83,0x81,0x82,0x80,0x82,0x82,0x82,0x83,0x81,0x83,0x83,0x83,0x83,0x85,0x89,0x89,0x8e,0x92,0xa4,0xd2,0x3f,0x26,0x19,0x0f,0x0d,0x08,0x05 +,0x05,0x04,0x02,0x02,0x01,0x03,0x02,0x03,0x02,0x03,0x03,0x02,0x05,0x03,0x04,0x05,0x03,0x03,0x04,0x02,0x02,0x02,0x02,0x01,0x02,0x03,0x02,0x03,0x04,0x03,0x03,0x04 +,0x05,0x05,0x06,0x0a,0x0e,0x16,0x1a,0x19,0x1e,0x1e,0x29,0xc7,0xb2,0xb3,0xaa,0xb2,0xa3,0xa3,0xa2,0xa0,0xa9,0xa1,0xa2,0x9b,0x9e,0x97,0x95,0x93,0x97,0x92,0x91,0x8f +,0x8f,0x96,0x8a,0x86,0x84,0x88,0x86,0x86,0x84,0x83,0x84,0x83,0x82,0x82,0x83,0x83,0x85,0x84,0x86,0x88,0x88,0x87,0x88,0x89,0x89,0x8a,0x8b,0x8e,0x91,0x91,0x96,0x99 +,0x98,0x96,0x8e,0x91,0x8f,0x91,0x93,0x92,0x8e,0x8b,0x8d,0x8b,0x8e,0x8e,0x8f,0x93,0x94,0x97,0x99,0xa1,0x9c,0x9d,0x98,0x97,0x9a,0x99,0x98,0x9b,0xa5,0xaa,0xaf,0xa6 +,0xa6,0xa0,0x9c,0xa1,0xa7,0xab,0xbc,0xb8,0xc1,0x3b,0x2a,0x19,0x12,0x0d,0x0b,0x07,0x04,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x06,0x0b,0x0f,0x19 +,0x24,0x31,0xd5,0xaf,0x9b,0x8f,0x8b,0x86,0x85,0x84,0x83,0x82,0x82,0x81,0x81,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x85,0x87,0x88,0x89,0x8a,0x8d,0x8f,0x96,0x9d,0xa6,0xb8,0x4e,0x3d,0x55,0x44,0x3a,0x2c,0x22 +,0x1e,0x1a,0x1c,0x1c,0x16,0x13,0x0e,0x0a,0x09,0x07,0x05,0x04,0x03,0x02,0x02,0x01,0x02,0x02,0x02,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 +,0x05,0x08,0x0a,0x0c,0x0d,0x0c,0x0d,0x0f,0x10,0x0f,0x0f,0x0e,0x0e,0x0e,0x11,0x18,0x1a,0x1f,0x1f,0x1f,0x22,0x24,0x27,0x2e,0xcf,0xaf,0x9c,0x97,0x98,0x96,0x93,0x8e +,0x8a,0x89,0x89,0x89,0x8b,0x8c,0x8c,0x8c,0x8d,0x8e,0x93,0x95,0x97,0x95,0x93,0x97,0x9a,0x9e,0xa4,0xa8,0xad,0xb6,0xab,0xa4,0x9d,0x97,0x9b,0x9d,0x9c,0x9f,0x9b,0x95 +,0x97,0x99,0x9e,0xaa,0xab,0xb8,0xde,0x5d,0x32,0x26,0x24,0x24,0x29,0x25,0x24,0x1e,0x18,0x15,0x16,0x14,0x13,0x1a,0x1f,0x2d,0x38,0x36,0x3c,0x39,0x4d,0xb1,0xac,0xac +,0xa9,0xb3,0xb5,0xb4,0xc0,0xc8,0xe5,0x4a,0x43,0x3b,0xea,0xb9,0xbb,0xb5,0xbe,0xcf,0xbb,0xb6,0xba,0xaa,0x9e,0x98,0x91,0x91,0x90,0x8e,0x8e,0x8b,0x89,0x89,0x88,0x8a +,0x8d,0x8d,0x8f,0x93,0x94,0x9a,0x9f,0xa5,0xa9,0xa5,0xac,0xb9,0xe1,0x37,0x27,0x24,0x1e,0x1d,0x2b,0x30,0x36,0x39,0x30,0x36,0x35,0x3e,0xcc,0xc0,0xc2,0xcd,0x4e,0x4e +,0x41,0x2f,0x2c,0x22,0x1a,0x19,0x18,0x1a,0x1b,0x1b,0x1b,0x19,0x15,0x13,0x12,0x10,0x17,0x1e,0x28,0x42,0x46,0x4f,0xff,0xcf,0xac,0xa0,0x9f,0x9e,0xa5,0xab,0xaa,0xb5 +,0xc2,0xc5,0x3e,0x2f,0x2f,0x2e,0x3f,0x3f,0x40,0x3b,0x2d,0x25,0x27,0x23,0x21,0x39,0x57,0xb5,0xad,0xb1,0xa8,0xa9,0xa0,0x98,0x97,0x97,0x98,0x9f,0xa3,0xaa,0xbb,0xcc +,0x3e,0x2b,0x26,0x20,0x24,0x29,0x26,0x24,0x1e,0x19,0x18,0x15,0x11,0x19,0x1f,0x2a,0x3e,0x35,0x3f,0x51,0x7b,0xaf,0xa4,0xa7,0xa2,0xab,0xb9,0xb8,0xdf,0x4e,0x3a,0x26 +,0x1f,0x1d,0x1d,0x24,0x21,0x20,0x1f,0x1b,0x19,0x1a,0x16,0x17,0x24,0x2b,0x58,0xc2,0xcc,0xb4,0xaf,0xa7,0x9b,0x9b,0x9a,0x9b,0xa2,0xa2,0xa4,0xac,0xae,0xc3,0x43,0x3b +,0x38,0x41,0x50,0x44,0x42,0x33,0x28,0x25,0x23,0x1e,0x2b,0x3f,0xca,0xa8,0xab,0xaa,0xa5,0xa3,0x9a,0x96,0x98,0x96,0x9c,0xa1,0xa0,0xaa,0xb2,0xba,0x58,0x3b,0x37,0x32 +,0x3d,0x39,0x37,0x2e,0x23,0x1d,0x1c,0x18,0x18,0x1f,0x29,0x5a,0xcd,0x5c,0xca,0xc0,0xb2,0xa0,0xa1,0xa0,0xa3,0xb4,0xb8,0xc0,0x52,0x48,0x33,0x26,0x23,0x1f,0x25,0x29 +,0x27,0x27,0x1f,0x1b,0x1a,0x18,0x14,0x1a,0x24,0x34,0xc7,0xeb,0xd6,0xba,0xb7,0xa4,0x9b,0x9b,0x9a,0x9e,0xa6,0xa7,0xb2,0xb5,0xba,0x55,0x3c,0x35,0x30,0x43,0x3c,0x40 +,0x44,0x30,0x2a,0x2b,0x21,0x1f,0x38,0x69,0xb1,0xa8,0xae,0xaa,0xa9,0xa5,0x9a,0x99,0x9a,0x9b,0xa1,0xa5,0xa9,0xb9,0xc0,0x4f,0x30,0x30,0x28,0x29,0x2d,0x28,0x2a,0x26 +,0x1f,0x1e,0x1c,0x16,0x1c,0x2c,0x3b,0xb8,0xba,0xcc,0xc3,0xc1,0xab,0x9e,0xa1,0xa1,0xa8,0xba,0xb8,0xcf,0x48,0x40,0x2b,0x23,0x22,0x1e,0x26,0x25,0x23,0x23,0x1e,0x1c +,0x1b,0x18,0x15,0x1e,0x2b,0xf8,0xac,0xb3,0xaf,0xac,0xa8,0x9b,0x98,0x99,0x98,0x9f,0xa5,0xa7,0xb2,0xb9,0xc8,0x3b,0x33,0x2e,0x31,0x3f,0x38,0x39,0x31,0x29,0x24,0x23 +,0x1e,0x1f,0x36,0xe2,0xa9,0xa5,0xa6,0x9f,0xa1,0x9b,0x94,0x94,0x95,0x98,0x9f,0xa0,0xaa,0xb7,0xc0,0x42,0x2b,0x2c,0x26,0x29,0x2b,0x27,0x27,0x22,0x1e,0x1c,0x1a,0x15 +,0x1d,0x2c,0x4b,0xb7,0xb4,0xb1,0xaf,0xae,0x9d,0x9b,0x9d,0x9c,0xa5,0xad,0xae,0xcb,0x4d,0x36,0x24,0x20,0x1f,0x1e,0x25,0x23,0x20,0x21,0x1e,0x1b,0x1a,0x18,0x17,0x22 +,0x30,0xc3,0xae,0xaf,0xaa,0xa8,0x9f,0x98,0x99,0x98,0x99,0xa0,0xa2,0xa6,0xb0,0xbc,0xea,0x38,0x33,0x2d,0x33,0x35,0x2f,0x34,0x2b,0x23,0x20,0x1e,0x19,0x1d,0x2d,0xf6 +,0xab,0xab,0xaa,0xa5,0xa6,0x9c,0x96,0x96,0x95,0x9b,0xa2,0xa2,0xab,0xbc,0xcb,0x3f,0x30,0x30,0x2a,0x30,0x2c,0x2a,0x29,0x20,0x1d,0x1d,0x19,0x15,0x1e,0x2e,0x5f,0xb8 +,0xbd,0xb6,0xaf,0xab,0x9c,0x99,0x9b,0x9b,0xa4,0xab,0xaa,0xbe,0x7b,0x48,0x2b,0x2c,0x2b,0x27,0x2e,0x2b,0x28,0x24,0x1f,0x1b,0x1a,0x15,0x15,0x26,0x36,0xd5,0xb7,0xbd +,0xb5,0xab,0xa1,0x97,0x97,0x98,0x9a,0xa1,0xa2,0xa6,0xbb,0xca,0x59,0x34,0x3a,0x2d,0x30,0x38,0x2f,0x2c,0x29,0x24,0x1e,0x1c,0x18,0x1d,0x30,0x49,0xb3,0xac,0xb0,0xac +,0xa7,0x9e,0x97,0x98,0x98,0x9c,0xa3,0xa3,0xab,0xbd,0xd4,0x33,0x2a,0x2c,0x2a,0x3d,0x36,0x2f,0x2e,0x2a,0x22,0x1e,0x1b,0x16,0x1f,0x2d,0x63,0xb0,0xbb,0xc4,0xb9,0xaf +,0x9d,0x98,0x9a,0x9c,0xa6,0xaa,0xa9,0xb8,0xc7,0x48,0x2a,0x29,0x29,0x2b,0x36,0x2c,0x2c,0x2d,0x28,0x20,0x1e,0x17,0x17,0x27,0x39,0xb4,0xab,0xbb,0xb0,0xad,0xa2,0x98 +,0x99,0x99,0x9c,0xa4,0xa2,0xab,0xba,0xce,0x3b,0x2e,0x33,0x2f,0x36,0x37,0x2e,0x2e,0x2e,0x29,0x1f,0x1f,0x17,0x1d,0x38,0xd6,0xaa,0xb1,0xb4,0xaa,0xa4,0x9c,0x98,0x99 +,0x99,0x9f,0xa8,0xa4,0xab,0xbb,0xf1,0x32,0x2c,0x35,0x34,0x41,0x34,0x29,0x2a,0x25,0x22,0x1d,0x19,0x14,0x1e,0x34,0xc2,0xa8,0xb0,0xb5,0xaf,0xa9,0x9b,0x95,0x99,0x9d +,0xa3,0xa6,0xa2,0xb0,0x6d,0x3c,0x2d,0x2d,0x31,0x2f,0x38,0x2f,0x2f,0x2e,0x28,0x22,0x1b,0x15,0x13,0x1f,0x3d,0xbb,0xaa,0xb6,0xb8,0xac,0x9e,0x95,0x95,0x9c,0x9d,0xa5 +,0xa2,0xa1,0xaf,0xcf,0x37,0x2a,0x35,0x38,0x36,0x3a,0x29,0x2c,0x2d,0x2e,0x27,0x1e,0x16,0x1c,0x29,0xb9,0xa9,0xac,0xb9,0xbf,0x9f,0x9e,0x98,0x95,0xa2,0xa0,0xa2,0x9f +,0x9c,0x61,0x5f,0x29,0x2c,0x3f,0x47,0x2e,0x27,0x1f,0x2c,0x2b,0x1d,0x1e,0x16,0x16,0x13,0x2f,0xc5,0xaf,0xa4,0x5c,0xba,0xa3,0x9c,0x93,0x9b,0x9b,0x9d,0x9f,0x9d,0xa2 +,0xc8,0x42,0x2d,0x2b,0x3d,0x2f,0x2e,0x27,0x25,0x26,0x29,0x21,0x16,0x19,0x16,0x1b,0x33,0xdc,0xb2,0xc2,0xe8,0xad,0xa3,0x9b,0x93,0x97,0x9e,0xa1,0x9d,0xa1,0xa5,0x79 +,0x44,0x3d,0x2c,0x3f,0x2a,0x30,0x27,0x2c,0x35,0x2c,0x24,0x18,0x16,0x14,0x22,0x64,0xcd,0xc1,0xc5,0x78,0xa2,0x9d,0x9b,0x93,0x9e,0x9a,0x9e,0xa3,0x9e,0xca,0xf9,0x39 +,0x37,0x49,0x45,0x2c,0x2e,0x37,0x2e,0x58,0x26,0x20,0x1a,0x17,0x15,0x22,0x39,0x37,0xc1,0x50,0xb4,0xab,0xa5,0x9b,0x98,0x98,0x9d,0x9f,0x9f,0xa5,0xc3,0x7d,0x58,0x36 +,0x3a,0x2f,0x23,0x2e,0x2f,0x31,0x34,0x20,0x1d,0x1b,0x1a,0x18,0x26,0xc6,0xc7,0xc0,0xb7,0xb6,0xa9,0x9e,0x9c,0x98,0xa1,0x9d,0xa2,0xa9,0x9f,0xdd,0xd1,0x52,0x36,0x35 +,0x33,0x3b,0x39,0x3e,0x3c,0x34,0x2b,0x1b,0x1a,0x1b,0x1b,0x3c,0x41,0xc9,0xb6,0xcc,0xad,0xa7,0xa3,0x98,0x9d,0xa4,0x9e,0xa3,0xa1,0xb1,0xea,0x3d,0xcb,0x34,0x33,0x2f +,0x29,0x5b,0x34,0x46,0x2e,0x20,0x1b,0x1b,0x18,0x1d,0x4c,0x49,0xc8,0xca,0xc6,0xa8,0xa4,0x9e,0x9c,0x9f,0xa0,0x9b,0xaa,0xab,0xb2,0x3f,0xf7,0x4a,0x3b,0x32,0x27,0x36 +,0x46,0x2e,0x3b,0x28,0x1f,0x1c,0x1e,0x1a,0x1f,0x63,0x3c,0xc6,0xca,0xcb,0x9e,0x9e,0x9c,0x99,0xa6,0x9a,0x9d,0xaa,0xa2,0xbf,0x6b,0xcd,0x38,0x30,0x29,0x2c,0x30,0x36 +,0x35,0x2b,0x2c,0x1a,0x23,0x1f,0x19,0x39,0x4d,0xce,0xc0,0x39,0xaf,0x9f,0x9c,0x99,0xa3,0xa0,0x9b,0x9c,0xab,0xae,0xbe,0x66,0x59,0x34,0x2b,0x2e,0x2c,0x7c,0x31,0x28 +,0x36,0x22,0x22,0x1d,0x15,0x1f,0x3d,0x61,0xc4,0x40,0xbf,0xa0,0x9d,0xa1,0xa4,0x9d,0x9b,0x97,0xa8,0xb4,0xab,0x4e,0xd7,0x33,0x27,0x3c,0x2a,0x3c,0x3e,0x25,0x34,0x2b +,0x1f,0x1f,0x18,0x1a,0x28,0xc8,0x3f,0x47,0xc1,0xb8,0x99,0xad,0xa6,0x97,0x9d,0x97,0xa1,0xb6,0xa0,0xbb,0xd9,0xc6,0x29,0x3a,0x3d,0x2d,0x2f,0x2d,0x2a,0x2e,0x28,0x18 +,0x1e,0x1e,0x18,0x55,0x41,0x46,0xb5,0x3d,0xa9,0xa0,0xab,0x9b,0x9a,0x99,0x96,0xa6,0xa6,0x9f,0xb7,0x67,0x67,0x38,0x33,0x32,0x21,0x2f,0x2b,0x26,0x2e,0x1c,0x1c,0x23 +,0x17,0x1e,0xfb,0x3d,0x3e,0x53,0xc6,0xa4,0xa8,0xa8,0x9b,0x99,0x9b,0x9a,0xa3,0x9f,0x9f,0xee,0xc4,0xd0,0x35,0x44,0x2a,0x2b,0x3c,0x2a,0x2a,0x23,0x20,0x1e,0x1b,0x17 +,0x25,0xd5,0x2a,0x3b,0xcb,0xbf,0xa3,0xb3,0xa9,0x8f,0x9d,0x9c,0x9b,0xaa,0x99,0xb4,0x6d,0xbe,0xe9,0x46,0x35,0x2f,0x3a,0x39,0x23,0x24,0x27,0x1c,0x1c,0x1d,0x16,0x36 +,0x49,0x20,0xe6,0xc6,0xc9,0xad,0xbc,0x9c,0x98,0xa2,0x9b,0x9a,0x9d,0x9e,0xab,0xbc,0xae,0x65,0x32,0xc1,0x2d,0x39,0x32,0x1f,0x40,0x1b,0x1c,0x21,0x1a,0x18,0x30,0x37 +,0x23,0x3e,0xcd,0xe4,0xba,0xaa,0xa3,0x98,0xa7,0x9c,0x95,0xa9,0x97,0xa8,0xba,0xa3,0x3f,0xd5,0x5b,0x2f,0x2c,0x31,0x2c,0x27,0x1d,0x1e,0x22,0x1f,0x17,0x25,0xd5,0x1d +,0x2e,0xce,0x60,0xbf,0xae,0x9f,0x9f,0xa0,0x9a,0x97,0xa1,0xa2,0x97,0xb8,0xb3,0xaa,0x50,0xcf,0x48,0x2d,0x3e,0x1e,0x27,0x24,0x17,0x26,0x1c,0x1e,0x1e,0x2f,0x2f,0x1a +,0xfb,0xba,0x34,0xa4,0xa3,0xad,0x9d,0x9d,0x99,0x9e,0x9f,0x9a,0xaa,0xac,0xa8,0xc6,0x54,0xca,0x46,0x2a,0x3b,0x27,0x21,0x22,0x1f,0x20,0x1d,0x1f,0x1d,0x2a,0x28,0x1b +,0xbd,0x59,0x33,0x9c,0xb6,0xb4,0x96,0xa1,0x99,0x9b,0xa0,0x96,0xae,0x9e,0xa4,0x43,0xb6,0xe9,0x2a,0x38,0x2f,0x21,0x24,0x26,0x1f,0x23,0x23,0x1d,0x18,0x25,0x3c,0x18 +,0x44,0xb5,0x1f,0x9f,0xa7,0x3f,0x91,0xa3,0xa9,0x8e,0xa1,0x9d,0x97,0xa9,0x9f,0xb9,0xbf,0xd4,0x32,0x3d,0x29,0x20,0x2e,0x28,0x20,0x27,0x1e,0x19,0x28,0x18,0x23,0xd4 +,0x14,0xb6,0xfc,0x1e,0x97,0xc6,0x5e,0x93,0xaa,0x9e,0x91,0xa5,0x9b,0x98,0xa6,0xa6,0xae,0xf4,0xc2,0x42,0x2f,0x44,0x28,0x2b,0x24,0x1e,0x27,0x19,0x23,0x2b,0x19,0x27 +,0x36,0x1e,0x2b,0xe8,0x39,0x5d,0xa5,0xb3,0xaf,0x94,0xa9,0x9e,0x92,0xaa,0x9b,0x9c,0xb4,0xa3,0xb5,0xd9,0xc0,0xe1,0x3c,0x28,0x33,0x1f,0x1f,0x2d,0x1b,0x2b,0x26,0x1e +,0x29,0x20,0x22,0x37,0x24,0x3b,0xb7,0x31,0xac,0xa3,0xbe,0x9c,0x9b,0xb2,0x98,0x9d,0xb7,0x97,0xa8,0xaa,0xa4,0xda,0xce,0x6f,0x4c,0x27,0x2b,0x34,0x1e,0x2a,0x2e,0x19 +,0x38,0x23,0x1d,0x39,0x25,0x35,0x3d,0x40,0x39,0xc6,0xd1,0xe3,0xa1,0xc8,0xae,0x9d,0xb0,0x9d,0x9d,0xa7,0x9e,0xa6,0xb4,0xb2,0xd2,0xd8,0x39,0xda,0x31,0x25,0x4f,0x1c +,0x2d,0x30,0x21,0x4c,0x2b,0x25,0xe8,0x25,0x45,0x47,0x2a,0xbe,0x28,0xbc,0x49,0x3b,0x9e,0xf8,0xa7,0xa2,0xb8,0xa2,0xaa,0xaa,0xa6,0xaa,0xb6,0xba,0xbd,0x4d,0x61,0x56 +,0x34,0x4f,0x3e,0x30,0x48,0x37,0x34,0x3b,0x37,0x36,0x2c,0x3a,0x27,0x3f,0x2f,0x32,0xbf,0x24,0xb3,0x3a,0x36,0xa9,0x38,0xac,0xb1,0xbb,0xa1,0xae,0xaa,0xa6,0xab,0xac +,0xb8,0xab,0xc8,0xce,0xb4,0x44,0xd1,0x54,0x37,0x3e,0x34,0x2e,0x33,0x2e,0x32,0x2a,0x3a,0x26,0x2b,0x3a,0x1e,0xec,0x22,0x42,0xc4,0x26,0xab,0xea,0x4b,0xa1,0xbb,0xa6 +,0x9d,0xa8,0x9c,0xa6,0x9d,0xa8,0xb5,0xa9,0x52,0xbd,0x5d,0x37,0x59,0x3a,0x37,0x2e,0x2e,0x2d,0x29,0x2b,0x26,0x26,0x32,0x1e,0x36,0x26,0x24,0x6f,0x1f,0xc8,0xd6,0x35 +,0xa4,0xbc,0xae,0x9e,0xa8,0x9a,0xa2,0x9d,0xa0,0xac,0x9c,0xb8,0xa7,0xb7,0x3c,0xb4,0x33,0x2f,0x4a,0x24,0x29,0x29,0x27,0x25,0x25,0x28,0x1f,0x2f,0x29,0x2d,0x48,0x22 +,0xc1,0x44,0x39,0xa9,0x3d,0xb6,0xa7,0xca,0xa2,0xa6,0xa3,0x9b,0x9e,0x9c,0xa7,0x9e,0xa8,0xc1,0xc1,0x58,0x2e,0x3b,0x30,0x21,0x28,0x2a,0x21,0x2e,0x2f,0x25,0x38,0x32 +,0x2f,0x3b,0x36,0x33,0x35,0x30,0xd0,0x30,0x4d,0xac,0x35,0xad,0x9e,0x6d,0x9e,0x9b,0xb2,0x9d,0x9d,0xaf,0xa9,0xaa,0xd5,0xe8,0x66,0x4d,0x2b,0x43,0x3c,0x1f,0x3f,0x37 +,0x1f,0x4f,0x32,0x2b,0x51,0x2f,0x3e,0x4b,0x3b,0x5a,0x29,0x53,0xc3,0x21,0xc4,0xc3,0x2a,0xab,0xa6,0xe0,0x9f,0x9e,0xb7,0x9d,0x9f,0xa9,0xa7,0xbb,0xb2,0x75,0x3a,0xca +,0x2b,0x29,0x4d,0x23,0x30,0x3c,0x32,0x3c,0x4e,0x67,0x39,0x3c,0x43,0x38,0x20,0x31,0x28,0x33,0x2d,0x2f,0xc3,0x3a,0xbf,0xa4,0xb7,0xa9,0x9c,0xa6,0x9e,0xa1,0xa3,0xaa +,0xba,0xad,0xd3,0x3d,0xcb,0x48,0x2e,0x43,0x43,0x29,0x39,0x4f,0x36,0x3d,0x39,0x42,0x27,0x2d,0x30,0x23,0x1e,0x2a,0x44,0x20,0x3c,0xae,0x4c,0xcb,0x9c,0xad,0xa8,0x9a +,0xa2,0x9c,0x9f,0x9f,0xa2,0xbe,0xcc,0xaf,0x3a,0x2d,0xdf,0x2c,0x32,0x4b,0x3a,0x39,0x3e,0x3e,0x3a,0x38,0x2a,0x28,0x2c,0x1f,0x25,0x1d,0x2b,0x40,0x1e,0xbe,0xb4,0xf4 +,0xa4,0xa0,0xa1,0x9e,0x9c,0x9a,0x9d,0xa1,0xa3,0xa6,0x5d,0x60,0xbd,0x37,0x2e,0x37,0x2d,0x39,0x2c,0x35,0x3f,0x26,0x48,0x3a,0x23,0x26,0x27,0x25,0x24,0x16,0x38,0xc6 +,0x22,0xc1,0x9e,0xc5,0xa4,0x99,0xa1,0x99,0x9f,0x99,0x98,0xb2,0xb9,0xa8,0x59,0x56,0x4f,0x38,0x34,0x38,0x2c,0xc7,0x44,0x22,0xbe,0x3b,0x23,0x2d,0x25,0x22,0x32,0x1f +,0x23,0x22,0x40,0x5c,0x3b,0xbd,0xa2,0x9e,0xa2,0xa8,0x9a,0x99,0xab,0xa2,0xa1,0xb5,0xa8,0xb3,0x38,0x48,0xca,0xbf,0xa8,0xa0,0x34,0x2f,0x1d,0x2c,0x1e,0x20,0x3a,0x36 +,0x18,0x0e,0x22,0x42,0xdc,0x35,0x32,0x15,0x16,0x0e,0xa7,0x91,0xac,0x89,0x85,0x8b,0x9d,0xac,0x44,0x2a,0x24,0x2e,0x89,0x87,0xaa,0x30,0x26,0x1f,0x24,0xb6,0x22,0x07 +,0x07,0x30,0xaf,0xfe,0x3e,0x48,0x21,0x06,0x01,0x3c,0x9e,0xb6,0x8c,0x8d,0x8e,0x9a,0xaf,0xa2,0x94,0xa8,0x96,0x97,0x1c,0x30,0x9d,0x91,0x21,0x0e,0xef,0x8b,0x98,0x19 +,0x18,0x1c,0x1a,0x1a,0x2a,0x5a,0x0f,0x06,0x0f,0x19,0x35,0x8a,0x9b,0x09,0x04,0x2b,0x83,0x80,0x87,0x90,0x8d,0x99,0x4b,0xac,0xb2,0x29,0x0d,0x21,0x93,0x9b,0xb0,0x2a +,0x1e,0x0d,0x08,0x20,0x37,0x12,0x0b,0x28,0xfa,0x9b,0x93,0xaa,0x12,0x06,0x27,0xa9,0x94,0x89,0x8b,0x8e,0x4c,0x17,0xa1,0x89,0x94,0x37,0x1f,0x23,0x2b,0xc5,0x95,0x97 +,0x22,0x18,0xb6,0x48,0x1b,0x1d,0x1d,0x21,0x0e,0x2e,0x94,0xb9,0x15,0x0d,0x1f,0x5e,0x8f,0x9b,0x23,0x1c,0xcd,0x8a,0x8b,0xad,0x9e,0x8c,0xaa,0x19,0x0f,0xd0,0x8e,0x33 +,0x18,0xae,0xbc,0x24,0x23,0xde,0xac,0xbd,0x3b,0x19,0x0b,0x1a,0x9b,0x99,0x38,0x1b,0x33,0xba,0xa4,0x4a,0x1a,0x48,0xc1,0x9f,0x8b,0x9d,0x2f,0x74,0xbd,0xba,0xbd,0x3f +,0x24,0x0c,0x0a,0xdc,0x88,0x86,0x94,0xb0,0x54,0x2f,0x22,0x4f,0xc7,0x3d,0x2b,0x3a,0x4e,0x24,0x1f,0x16,0x1e,0x19,0x0e,0x2d,0x9a,0x92,0x94,0xab,0xbc,0x9d,0x98,0xbe +,0x29,0x1b,0x2b,0xa0,0x9d,0x8f,0x8f,0xa5,0x0e,0x0c,0xbf,0x88,0x8b,0x32,0x0a,0x0d,0x2b,0xb3,0xb5,0x1d,0x0f,0x0d,0x48,0xb4,0xe7,0xb4,0xb7,0x21,0x1e,0x4a,0x9a,0x8f +,0xb3,0x2b,0xaa,0x90,0x9c,0x58,0x19,0x26,0xa1,0x8d,0x8f,0x92,0x97,0xa5,0x1b,0x08,0x0b,0x22,0xc1,0x29,0x1b,0x1d,0x1c,0x0e,0xec,0xaa,0x20,0x1e,0x19,0x28,0xa9,0x98 +,0x90,0x8c,0x99,0xda,0xc5,0xa5,0xa6,0xb0,0xea,0xa2,0x94,0x8f,0x9a,0x3d,0x20,0x2f,0x33,0x21,0x1a,0x15,0x19,0x0e,0x0d,0x1e,0xbe,0x25,0xd3,0x33,0x18,0x33,0xbc,0x93 +,0x91,0x9c,0xae,0xa0,0xb2,0xc8,0xae,0x91,0x99,0x4a,0x19,0x27,0x98,0x8f,0xa2,0x5f,0x5d,0xbd,0xa9,0x33,0x1a,0x14,0x16,0x0f,0x18,0x22,0x38,0x0f,0x0a,0x1a,0xbe,0x8b +,0x8d,0xaf,0x2a,0x67,0xae,0x8b,0x84,0x8d,0xa4,0x5b,0x37,0xb9,0xb1,0xdc,0xed,0x20,0x1b,0x2d,0xa1,0xa5,0xf1,0x1d,0x11,0x13,0x10,0x0f,0x1b,0x22,0x34,0x3c,0xa1,0x93 +,0xad,0xbf,0x2f,0x2f,0xb8,0x92,0x8e,0x8d,0x96,0xb7,0x36,0xdf,0xad,0xc1,0x28,0x0f,0x1d,0x5e,0xaa,0xa0,0xa2,0xf4,0x1c,0x0f,0x17,0x3c,0xcc,0x26,0x25,0x51,0xce,0x26 +,0x22,0xce,0x43,0xa8,0x99,0x9a,0xa6,0xb4,0x3e,0xb3,0xa1,0x9f,0xa1,0xa1,0xb0,0x70,0x2d,0x1c,0x49,0x3d,0x2f,0x27,0x2f,0x2c,0x3f,0x2f,0xc3,0xa8,0x48,0x0f,0x09,0x1c +,0xae,0xa5,0xb1,0x8f,0x9d,0xb5,0xad,0xae,0xb8,0xbf,0x29,0x3c,0x9b,0x97,0xa3,0x42,0x1e,0x1c,0x3e,0x25,0x26,0x29,0x23,0x33,0xaa,0x95,0x8c,0x9c,0x24,0x1f,0x1f,0x2b +,0x24,0x3b,0xbf,0x2f,0x10,0x39,0x9c,0xac,0xaa,0xfc,0x3d,0x36,0x38,0x4e,0x95,0x90,0xa5,0xdd,0x5d,0x5c,0x58,0x2e,0x1f,0x25,0x2f,0xad,0x9c,0x98,0xaa,0x35,0x26,0xba +,0xaa,0x50,0x1a,0x15,0x1e,0x2a,0x1f,0x33,0x96,0xc7,0x1d,0x23,0xba,0x99,0xa2,0x35,0x5c,0x9f,0xad,0x5c,0xb5,0xa8,0xaa,0xb9,0x30,0x3a,0x30,0x4f,0xe0,0xb6,0xa8,0x9a +,0x9f,0xac,0xbc,0x2c,0x23,0x15,0x1a,0x1d,0x1c,0x0e,0x2c,0xad,0x3c,0x62,0x4f,0xfd,0x30,0x17,0x17,0x9e,0x8a,0x8b,0x93,0x96,0x9c,0xaf,0x34,0x2e,0xc7,0xc9,0xd3,0xaf +,0xad,0xaa,0xac,0x1f,0x1e,0x1a,0x15,0x13,0x15,0x2c,0x42,0x23,0x14,0xb7,0xa9,0x28,0x34,0x39,0xb4,0xa3,0xac,0x9c,0x8b,0x96,0xbb,0xce,0xa8,0x93,0x9c,0x5a,0x36,0xcf +,0x4d,0xe4,0xb9,0xab,0xae,0x28,0x1e,0x3a,0x31,0x22,0x10,0x0b,0x14,0x18,0x17,0x18,0xb1,0xaf,0x4d,0xa8,0x9e,0x9a,0xa9,0x67,0xa5,0x8c,0x8d,0x8f,0x94,0x9c,0xbf,0x29 +,0x24,0x3d,0xc8,0x2b,0x2f,0x47,0xbb,0xb7,0x2c,0x27,0x2a,0x15,0x0b,0x0c,0x12,0x35,0x30,0x1c,0x2a,0x96,0x9d,0xba,0xa6,0xaa,0x94,0x9d,0x9f,0x90,0x8c,0x9e,0xaf,0xbb +,0xc9,0xfd,0x1a,0x1a,0x1e,0x1d,0x25,0xbe,0xb5,0xa0,0xc5,0x1f,0x39,0x2c,0x1a,0x1b,0x1e,0x29,0x3a,0x24,0x1d,0x27,0xa0,0xbe,0x46,0xb4,0xaa,0x97,0x9f,0x9c,0x8f,0x91 +,0x9e,0xa3,0xae,0xae,0x4d,0x1e,0x20,0x29,0x23,0x21,0x25,0x25,0x2c,0x2c,0x3d,0xad,0xc9,0x27,0x23,0x21,0x2c,0x77,0x50,0xd9,0xc1,0xa3,0xbc,0xdb,0xae,0xb6,0xae,0xfe +,0xc1,0x9e,0x9a,0x9f,0xa1,0xb9,0xc5,0x2c,0x1a,0x1d,0x27,0x30,0x4e,0xb6,0xa5,0x9e,0xaf,0xca,0x38,0x22,0x1e,0x34,0x37,0x61,0x54,0x31,0x31,0x24,0xc0,0x40,0x2c,0x3b +,0x30,0xac,0xa7,0xa1,0x9a,0xa2,0xae,0xb9,0xd1,0xb1,0xbe,0x37,0xda,0xc7,0xb1,0xbf,0xc8,0xb9,0xb9,0xed,0x36,0x44,0x33,0x25,0x1b,0x1c,0x28,0x3a,0x31,0x36,0x23,0xdb +,0x56,0x2b,0xc3,0xca,0xa5,0xc1,0xed,0xab,0xa6,0xa5,0xaa,0xb6,0xb3,0x58,0x35,0xc4,0xae,0xa6,0xa4,0xaa,0x9f,0x9c,0xb5,0x4c,0x34,0x25,0x1b,0x17,0x1a,0x1c,0x1e,0x19 +,0x1c,0x18,0x27,0x3e,0x20,0x46,0x4b,0xaf,0x9c,0x9b,0x8f,0x8f,0x97,0x9c,0xa8,0xa4,0xad,0xe1,0xb4,0xd8,0xc2,0xbd,0xbe,0xb0,0xc9,0x2f,0x1e,0x1d,0x1d,0x1d,0x1e,0x26 +,0x23,0x29,0x2d,0x24,0x20,0x19,0x28,0x33,0x45,0xa4,0xa2,0x97,0x9b,0xa6,0x96,0x9b,0x9b,0xa1,0xaf,0xa5,0xb0,0xb3,0xb7,0xb0,0xc1,0x3b,0x34,0x2f,0x32,0x2a,0x20,0x22 +,0x22,0x1e,0x1f,0x28,0x27,0x24,0x2a,0x29,0x2a,0x2a,0x4a,0x3b,0x48,0xac,0xac,0x97,0x92,0x97,0x95,0x9a,0x9a,0x9f,0xb2,0xa2,0xbd,0x70,0x5c,0x2e,0x48,0x29,0x20,0x1a +,0x17,0x17,0x1b,0x26,0x32,0xde,0xba,0xad,0xc3,0xb8,0x68,0xd3,0x7d,0x3c,0x3b,0xc9,0xb4,0xc4,0xb2,0xcb,0xae,0xd2,0xc7,0xbc,0xb6,0xaf,0xbb,0xb7,0xa5,0xa9,0xae,0xdb +,0x32,0x32,0x20,0x2a,0x26,0x2d,0x2f,0x30,0x3d,0x51,0xcb,0xb9,0xc5,0xc9,0xc4,0xc5,0xbc,0x4f,0xb9,0x59,0x57,0xcd,0x43,0xbe,0x4d,0x32,0x36,0x2d,0x42,0x62,0x79,0xbc +,0xb7,0xbc,0xb9,0xb3,0xb9,0xbd,0x46,0x3c,0x37,0xf0,0xb2,0xb5,0xad,0xb4,0xbc,0xc0,0xcb,0xc2,0x54,0x3a,0x3a,0x39,0x44,0x42,0x3d,0x2d,0x2d,0x1f,0x25,0x24,0x2c,0x2f +,0x38,0xc0,0xb0,0x9e,0xa1,0x9e,0xa7,0xad,0xaf,0xab,0xb2,0xb2,0xac,0xbe,0xd8,0x5d,0x48,0x3e,0x37,0x22,0x27,0x27,0x2e,0x40,0x4f,0x5e,0x4f,0x3c,0x59,0xc1,0x37,0xc9 +,0x3e,0x6a,0xc2,0x38,0xb7,0xce,0xbc,0xee,0x55,0xb9,0xc2,0xd3,0xbf,0x65,0xb2,0xab,0xb9,0xa9,0xbd,0xbd,0xd9,0x4b,0x32,0x37,0x27,0x28,0x25,0x22,0x2e,0x35,0x44,0x44 +,0xd4,0xf4,0xca,0xbb,0xaf,0xa4,0x9e,0xa5,0xa2,0xab,0xaa,0xb4,0x4f,0x39,0x2d,0x2f,0x2b,0x32,0x2e,0x36,0x2d,0x31,0x36,0x2d,0x2d,0x29,0x2d,0x36,0xee,0xd1,0xb9,0xb4 +,0xbd,0xba,0xaf,0xa8,0xa8,0xae,0xab,0xa2,0xa6,0xa7,0xa8,0xb5,0xb6,0xcb,0x39,0x2e,0x28,0x1f,0x1f,0x1f,0x28,0x27,0x26,0x2e,0x2d,0x43,0x44,0x48,0xf8,0xcb,0xc0,0xb4 +,0xba,0xb9,0xab,0xbc,0xb6,0xaf,0xbf,0xbb,0xc1,0xba,0xa8,0xac,0xad,0xbb,0xb2,0xb5,0xc8,0x49,0x35,0x36,0x2e,0x21,0x20,0x23,0x21,0x2e,0x1f,0x2a,0x3e,0x3d,0x3f,0x62 +,0xc6,0xab,0xa4,0xa6,0x9f,0xa5,0xa1,0xa2,0xa4,0xaa,0xb9,0xd4,0x51,0x4a,0x4c,0x2f,0x2e,0x2e,0x2c,0x23,0x26,0x29,0x27,0x2f,0x34,0x58,0xcc,0xbb,0xc0,0xb0,0xb3,0xbe +,0xb7,0xbe,0xbd,0xb6,0xb7,0xb4,0xb8,0xbd,0xcc,0xc5,0xdc,0x59,0x58,0x3a,0x44,0x49,0x49,0x44,0x40,0x2f,0x31,0x38,0x30,0x30,0x38,0x37,0x37,0x5f,0xdb,0xb8,0xb4,0xbb +,0xb8,0xad,0xad,0xb2,0xb8,0xb4,0xc5,0xcc,0xb8,0x44,0xbf,0xda,0x5f,0xed,0x3e,0x40,0x42,0x34,0x34,0x3c,0x31,0x3f,0x2d,0x46,0x3f,0x3b,0x2d,0x3d,0x3d,0x67,0xb9,0xaf +,0xae,0xa2,0xa4,0xb0,0x9e,0xbd,0xa8,0x58,0xc0,0x4c,0x56,0xd3,0x3b,0x2b,0x26,0x29,0x1c,0x3a,0x1f,0x4b,0x34,0xd5,0xbd,0xca,0xa3,0xb9,0xae,0xe9,0xa7,0xb4,0x7c,0xc3 +,0x4c,0xc7,0xcb,0xd0,0xdf,0x4f,0x3d,0xe8,0x43,0x48,0x5c,0x4f,0xce,0x57,0xf6,0x47,0x4c,0x52,0x4e,0xe3,0x40,0x34,0x4d,0x59,0xdd,0xdf,0xca,0xb4,0xc1,0xcc,0xc2,0xbf +,0xbe,0x77,0xcb,0xc1,0xb5,0xb3,0x75,0xba,0x57,0x5a,0x38,0x2f,0x2d,0x2c,0x2f,0x2a,0x4b,0x58,0x41,0x3d,0x57,0x4f,0x6a,0xc9,0xb6,0xcb,0xb5,0xb6,0xb1,0xb5,0xb1,0xac +,0xc5,0xbc,0xbe,0xca,0x3e,0xc7,0x5f,0x63,0xef,0x40,0x37,0x3b,0x29,0x26,0x2b,0x25,0x45,0x2f,0x52,0xeb,0xbe,0xbb,0xc0,0xae,0xb7,0xb1,0xaf,0xb9,0xb5,0xb9,0xc3,0xba +,0xbf,0xdc,0x39,0x43,0x36,0x37,0x37,0x38,0x45,0x6d,0xc9,0x78,0xcb,0x5e,0xdd,0x50,0x4e,0x44,0x4d,0x44,0x57,0x69,0x3f,0xdb,0x4f,0xc3,0x55,0xca,0xbc,0xb8,0xba,0xb2 +,0xae,0xba,0xb9,0xda,0xcb,0xde,0xff,0x36,0x33,0x2f,0x2f,0x30,0x5d,0x4c,0x4b,0x61,0x5f,0xe4,0x52,0xbb,0xf7,0xc4,0xb2,0xcb,0xb6,0xac,0xbd,0xc6,0x6c,0xce,0xdd,0x47 +,0x44,0x3b,0x55,0x66,0x50,0x3a,0x3d,0x3c,0x36,0x37,0x3e,0x4e,0x5f,0x63,0xc8,0xcc,0xb1,0xaf,0xc5,0xb6,0xcc,0xbb,0xc4,0xcf,0xbe,0xb8,0xd0,0x53,0xc6,0x5c,0x57,0x3c +,0x3f,0x41,0x2e,0x2e,0x46,0x45,0x3f,0x4b,0x4e,0x5f,0xcb,0xce,0x5b,0xda,0xe3,0xe0,0xd4,0xca,0xb6,0xba,0xe7,0xc8,0xcb,0xd0,0xda,0xd8,0xd9,0xdb,0xcd,0xb7,0xc4,0xcd +,0xbf,0x46,0x3e,0x39,0x3b,0x38,0x3c,0x37,0x36,0x40,0x43,0x58,0x5f,0x5b,0x46,0x6d,0xbb,0xc0,0xba,0xb5,0xb7,0xaa,0xb6,0xb4,0xbc,0xde,0xcd,0x3f,0x3f,0x77,0x3f,0x3f +,0x41,0x41,0x3a,0x36,0x3c,0x38,0x42,0x3e,0xf6,0xd1,0xcb,0xce,0xba,0xbf,0xc4,0xd5,0xde,0xc8,0xc8,0xc0,0xcc,0xb9,0xc6,0xc4,0xd5,0xd7,0xce,0x46,0x3e,0x3f,0x3a,0x49 +,0x3f,0x3c,0x39,0x42,0x51,0x4c,0x4e,0x58,0xd7,0xd3,0x6f,0xe3,0xc2,0xc1,0xb8,0xec,0xbe,0xbb,0xd6,0xdf,0xdd,0xc0,0x4a,0x4f,0xca,0xba,0xd0,0xce,0x55,0x4c,0x3f,0x39 +,0x4c,0x2c,0x3f,0x3f,0x3b,0x44,0x74,0xf6,0x59,0x43,0x4a,0xdf,0xc9,0xc3,0xcd,0xb3,0xb4,0xad,0xad,0xaf,0xc0,0xc7,0xdc,0xc9,0xfd,0x5d,0x54,0x3e,0x39,0x38,0x3c,0x2f +,0x2e,0x2b,0x3d,0x3d,0x40,0x5d,0xe1,0xbf,0xbb,0xd4,0xc2,0xba,0xc5,0xbf,0xc7,0xc1,0xc5,0xc9,0xcb,0xde,0xca,0xc4,0xcc,0x6c,0x5d,0xd6,0x4c,0x5c,0xef,0x44,0x5d,0xf9 +,0x4f,0x45,0x3f,0x3d,0x3c,0x4a,0x42,0x3e,0x3e,0x4f,0xce,0xc6,0xea,0xbc,0xb8,0xc8,0xba,0xb9,0xbb,0xc1,0xdd,0xce,0xc8,0xe4,0xca,0x42,0x45,0x4b,0x4b,0x48,0x3d,0x58 +,0x62,0xd8,0x4f,0x5c,0xe4,0x60,0x3d,0x36,0x49,0x59,0x58,0x75,0xcd,0xbe,0xaf,0xc6,0xe1,0xc6,0xb3,0xc4,0x59,0xbf,0x74,0x6b,0x4d,0x3d,0x5e,0x41,0x33,0x37,0x3d,0x59 +,0x60,0xdf,0xbf,0xd2,0xc7,0xba,0xc7,0xff,0xdf,0xcf,0xe4,0xd6,0xf0,0xce,0x73,0xe6,0x56,0x3b,0xdb,0x56,0x5f,0x75,0xe3,0xfd,0x68,0x4a,0x4f,0xca,0x71,0x41,0x4f,0xd6 +,0x5e,0x7d,0x5e,0x6e,0x5a,0x5c,0xf9,0xcb,0xc5,0xca,0xc9,0x59,0xca,0xc6,0x74,0xc8,0xd8,0xcf,0xc0,0xe7,0xd2,0x49,0x3f,0x45,0x45,0x49,0x42,0x59,0x48,0x5f,0xea,0x5a +,0xef,0xef,0xdd,0x66,0xd6,0xd1,0xc6,0xc4,0xdd,0xc3,0x77,0xca,0x70,0xf9,0xe8,0x67,0xe2,0x54,0x64,0xfa,0xe0,0x49,0xf2,0x4f,0x44,0x42,0x47,0xc1,0xd1,0x47,0x67,0xd7 +,0xd8,0xc5,0x6b,0xde,0xe4,0x47,0xd6,0xbf,0xc5,0xd8,0xf9,0x66,0xca,0x5a,0x46,0x5e,0x7c,0x46,0x37,0x76,0xcf,0x4e,0x56,0x59,0x5c,0xce,0xf0,0xc4,0xcf,0xe7,0xcb,0xcc +,0x59,0x54,0x58,0x4d,0x4a,0x49,0x56,0xd8,0xca,0xe5,0xce,0xeb,0xe9,0xc6,0xce,0xdc,0xd0,0x7c,0xe9,0x4c,0x44,0x4b,0x3f,0x4c,0x3d,0x44,0xeb,0xd4,0x7d,0x5c,0xfb,0xcd +,0xd3,0xdc,0xc1,0xef,0xcf,0xc6,0xc4,0xd9,0x5b,0x60,0x4f,0x63,0x69,0x49,0x6b,0xcb,0xe6,0xce,0x60,0x3b,0x44,0x59,0xd2,0xcb,0x69,0xd0,0xdf,0xc0,0xfb,0x4a,0x57,0x4d +,0xfe,0x7e,0xdb,0xc4,0xbe,0xca,0xef,0x49,0x5b,0xe9,0xdd,0x5c,0xd1,0xe8,0x5d,0xcf,0x6d,0x5d,0x3a,0x46,0x64,0x56,0xea,0xfa,0xc6,0x6c,0x46,0xc7,0xce,0xe9,0x63,0x46 +,0xcc,0xcf,0x5e,0x6a,0xda,0xf3,0xe8,0xca,0xd4,0x7b,0xec,0xc9,0xda,0x77,0x78,0x59,0x68,0xf6,0x57,0x57,0x41,0x57,0x4a,0xd9,0x50,0x38,0xfc,0xe7,0xcc,0xf8,0xcf,0xdb +,0xcb,0xcb,0xec,0xbf,0xcf,0xe4,0xf9,0xfa,0xd9,0x5e,0x59,0xec,0x4c,0x4b,0xec,0x55,0x4e,0x51,0xfc,0xd4,0xd9,0x64,0xd4,0xfa,0x60,0xd8,0x59,0x41,0x3d,0xfb,0x6f,0x47 +,0xda,0xd2,0xc5,0xcc,0x79,0xcd,0x4e,0xd0,0xce,0xc8,0xe0,0x6b,0xcc,0xc2,0xdf,0x35,0x3b,0x3a,0xdb,0xca,0x5d,0x50,0xdc,0xc9,0xde,0xe6,0x59,0x42,0x4c,0x66,0xec,0xc7 +,0xdd,0xcc,0x61,0x49,0xcb,0xc6,0x47,0x47,0xbf,0xc0,0xec,0xd8,0xde,0xe8,0x54,0x40,0x5c,0x63,0xef,0xd5,0x64,0x57,0x59,0x4b,0xdf,0xcf,0x4d,0x53,0xd1,0xbe,0xc0,0x63 +,0x51,0x68,0x65,0x56,0x5f,0xde,0xd8,0xd2,0xde,0x5c,0xff,0xfe,0x50,0x6c,0xf3,0xd1,0xce,0xdc,0xc1,0xc5,0x5e,0x4b,0x41,0x42,0x5e,0xda,0xe8,0x67,0x68,0x5e,0xe1,0x5f +,0x48,0x48,0x58,0xdc,0xd5,0xcb,0xce,0xda,0x59,0x57,0x6f,0x6d,0xef,0xec,0x6a,0x69,0xe4,0xeb,0xdf,0x59,0x4a,0x5c,0x57,0x6b,0xd8,0x79,0xee,0x6b,0x58,0xe3,0x79,0x65 +,0xe6,0xdb,0xef,0x5f,0x68,0x59,0x5c,0x63,0x5e,0x75,0xea,0x7e,0xee,0xe7,0x5f,0x63,0x73,0xec,0xf4,0xcb,0xca,0xe3,0x6c,0x63,0xd1,0xd6,0x5c,0x4f,0x61,0xdf,0xd1,0xea +,0x6f,0x6f,0x69,0x56,0x53,0x63,0x70,0x7b,0xfa,0x5e,0x6b,0xd4,0x7d,0x5b,0x5e,0xfb,0xd4,0xe2,0xdc,0xea,0x5b,0xe1,0xd6,0xdc,0xda,0xe3,0xf8,0xcb,0xe0,0x5b,0xdf,0xdd +,0x56,0x57,0x73,0xf7,0xce,0x5e,0x4f,0x67,0x5d,0x50,0x51,0x50,0xdb,0xdc,0xf7,0xe6,0xf2,0xfe,0x5c,0x47,0x45,0x78,0xe7,0xcd,0xc5,0xc1,0xc1,0xd1,0x6e,0xd3,0xda,0xe3 +,0x7b,0x61,0xf7,0x69,0xfa,0x70,0x4f,0x44,0x46,0x47,0x6a,0x60,0xf8,0xd7,0xdf,0xea,0xed,0xfa,0xdd,0xf5,0x53,0xdb,0xeb,0xfb,0xec,0x64,0xe9,0xd2,0xef,0xf6,0x77,0xdd +,0xe7,0x5f,0xf5,0xff,0x6c,0x5f,0x5d,0x79,0x79,0x5f,0x52,0x54,0xd8,0x53,0x42,0x4b,0xee,0xcf,0xca,0xcc,0xd0,0xd5,0x72,0xfc,0xd6,0xce,0xdc,0x7d,0x69,0xd4,0xde,0xdb +,0x7d,0x4a,0x5f,0x53,0x4c,0x71,0x56,0x59,0x6e,0x60,0xe0,0xf0,0x50,0x4b,0x50,0x73,0x79,0xf9,0xc5,0xc8,0xd0,0xdd,0xd0,0xbf,0xc5,0xdd,0x7b,0xf1,0xed,0x5a,0x6d,0xbe +,0xc8,0xe7,0x53,0x4b,0x5e,0x59,0x4e,0x48,0x4a,0x42,0x46,0x4e,0x5a,0xf7,0x56,0x4d,0xe4,0xd2,0xd4,0xd3,0xe0,0xcb,0xc7,0xd5,0xcb,0xd4,0xe6,0x4f,0x46,0x62,0xd9,0xd2 +,0xdc,0xe3,0xe7,0xd2,0xd6,0xd2,0xd7,0x69,0x44,0x46,0x47,0x3f,0x55,0x4f,0x48,0x4b,0x44,0x4d,0xdd,0xdb,0x6e,0xe3,0xd5,0xcd,0xc7,0xcc,0xce,0xce,0xcd,0xd1,0x6f,0xef +,0xe6,0x65,0x4d,0x55,0xcc,0xca,0xcf,0xdb,0xf2,0x52,0x4f,0x5d,0x60,0x67,0x4a,0x44,0x40,0x46,0x57,0x56,0x59,0x65,0x4f,0x59,0xe4,0xd2,0xc9,0xca,0xbf,0xc1,0xc7,0xd7 +,0xd7,0xdb,0x6a,0x70,0x5c,0xd7,0xd7,0xd9,0xf0,0x56,0xdb,0x65,0x53,0x55,0x41,0x4f,0x49,0x3e,0x4c,0x78,0xf3,0x4a,0x47,0x4b,0x5d,0x61,0xc5,0x65,0xa6,0x9e,0x1a,0x41 +,0xa4,0xc9,0x2a,0x39,0xa4,0x5e,0x3b,0xc9,0xad,0x41,0x49,0x54,0xc3,0x44,0x3d,0xb9,0xd6,0x62,0xa3,0x2b,0x3e,0xae,0x7d,0x37,0x1f,0xa0,0xce,0x47,0x1b,0x9c,0x0f,0x01 +,0x1b,0x10,0xa7,0x2c,0xb1,0x2f,0x36,0x8d,0x92,0x9c,0x8e,0x8f,0x30,0x91,0x8e,0xc1,0xc2,0x9b,0x63,0x95,0x1e,0x07,0x8a,0x8c,0x9a,0xaa,0xa0,0x16,0x21,0x1f,0x0d,0x08 +,0x08,0x07,0x05,0x0f,0x07,0x0c,0x0a,0x11,0x09,0x1f,0x1d,0x0b,0x20,0xb7,0x9e,0xb2,0xaa,0xa2,0x9f,0x95,0x90,0x90,0x91,0x92,0x8a,0x88,0x87,0x85,0x86,0x85,0x82,0x84 +,0x83,0x8d,0x85,0x96,0xd0,0x94,0x98,0xa8,0x11,0x23,0x17,0x14,0x13,0x04,0x04,0x04,0x03,0x08,0x0e,0x05,0x08,0x02,0x0a,0x0b,0x01,0x07,0x06,0x1c,0x28,0xe7,0xa7,0x3a +,0x3c,0xa4,0x9b,0x8e,0x8a,0x94,0x89,0x89,0x84,0x86,0x88,0x81,0x82,0x97,0x88,0x85,0x88,0x88,0x9b,0x9e,0xca,0x4f,0x25,0xcf,0x21,0x20,0x12,0x0a,0x53,0x20,0x13,0x11 +,0x0b,0x13,0x0e,0x0d,0x18,0x0b,0x09,0x0c,0x0b,0x0f,0x0e,0x10,0x19,0x69,0x32,0xa3,0xa0,0xc2,0x9d,0x99,0x98,0x9b,0xbb,0x48,0xa0,0x54,0xbf,0x2a,0x9d,0x83,0x9e,0x8b +,0x80,0x87,0x83,0x84,0x80,0x85,0x85,0x9f,0x92,0x8f,0x24,0x1a,0x10,0x49,0x0f,0x04,0x13,0x0d,0x0c,0x0f,0x08,0x01,0x0b,0x10,0x0a,0x0e,0x04,0x07,0x03,0x04,0x06,0x11 +,0x17,0xc5,0xab,0xb3,0x85,0x9c,0x8e,0x8c,0x8c,0x80,0x8f,0x95,0x90,0x88,0x88,0x86,0x88,0x8d,0x8e,0x97,0x8d,0x8e,0x8d,0xa7,0x2d,0xd7,0xb4,0x14,0x0f,0x22,0x1c,0x1a +,0x0d,0x0a,0x0c,0x10,0x1c,0x09,0x0c,0x27,0x2f,0x13,0x09,0x08,0x03,0x45,0x0f,0x26,0x2a,0x13,0x15,0x18,0x9f,0xe7,0x86,0xd5,0x3a,0x94,0x8a,0xb4,0xf5,0x84,0xa2,0xa1 +,0x22,0x93,0x82,0x95,0xca,0x37,0xb6,0x8e,0x80,0x86,0x8a,0x88,0x8c,0x96,0xac,0x3d,0x5f,0x27,0x21,0x2d,0x16,0x06,0x0a,0x21,0x0b,0x10,0x0c,0x00,0x0b,0x09,0x2e,0x34 +,0x09,0x0b,0x27,0x1b,0x14,0x18,0x10,0x16,0x24,0x10,0x17,0x98,0x81,0x8e,0x85,0x85,0x94,0x96,0x9a,0x85,0x8c,0x88,0x9c,0x8f,0x94,0x8b,0x80,0x8a,0xc6,0x26,0x2a,0x93 +,0x8d,0x16,0x29,0xb7,0xa4,0x1f,0xb1,0x3d,0x0c,0x0a,0x18,0x18,0x00,0x0a,0x12,0x0f,0x18,0x10,0x2f,0x29,0xad,0x0f,0x00,0x1e,0x13,0x34,0x23,0x96,0x99,0x2f,0x3d,0x4f +,0x8c,0x9b,0xae,0xa3,0x94,0x9b,0x97,0x8a,0x92,0x80,0x93,0x0c,0xd0,0x85,0xac,0x16,0x21,0x9b,0x80,0x93,0x9d,0x99,0x9f,0x95,0x4d,0x08,0x21,0x0f,0x3f,0xae,0x33,0xcf +,0x13,0x14,0x0b,0x12,0x06,0x11,0x08,0x1a,0x23,0x0b,0x14,0x27,0x23,0x0e,0x05,0x1e,0x4d,0x05,0x0a,0x00,0x9b,0x85,0x8f,0x82,0x82,0x86,0x2a,0x0a,0x36,0x81,0x8a,0x97 +,0x89,0x97,0x80,0x8c,0x97,0x8e,0x9f,0xa2,0x0c,0x91,0x8e,0x48,0xc1,0xa9,0xae,0xb9,0x48,0x07,0x19,0x16,0x02,0x03,0x03,0x99,0x91,0x06,0x51,0xab,0x26,0x1e,0x00,0x06 +,0x18,0x29,0x1d,0x30,0x9e,0x95,0xad,0x0b,0x1f,0x22,0x92,0xbb,0xc6,0x86,0x9d,0x8e,0x9a,0x90,0x8a,0xa2,0x9b,0x95,0x38,0x1c,0x0d,0x9e,0x80,0x87,0x8e,0x86,0x94,0x62 +,0x06,0x06,0xa0,0x91,0xa5,0xbf,0x8f,0xb7,0x95,0x2f,0x1b,0x05,0x14,0x0c,0x15,0x3d,0x0f,0xbb,0x08,0x3d,0x5b,0x0e,0x06,0x02,0x0b,0x0a,0x09,0x06,0xc8,0x81,0x8f,0xa7 +,0x1f,0xc3,0x50,0x04,0xd2,0x95,0x8d,0x89,0x86,0x84,0x83,0x94,0x1d,0xca,0x95,0x8f,0xa0,0x8e,0x8c,0x82,0x97,0xd8,0x9d,0x98,0x2e,0x1e,0x1e,0x04,0x10,0x07,0x96,0x83 +,0xd4,0x46,0x5e,0x09,0x07,0x00,0x0c,0x31,0xce,0x47,0x30,0xcc,0x19,0x16,0x06,0x0e,0x0a,0x29,0x16,0x22,0x8d,0xac,0xb1,0xad,0xb9,0x98,0x97,0x3a,0x2f,0xc0,0xbf,0xb0 +,0x81,0x80,0x83,0x8e,0xa9,0x8f,0xa5,0x25,0x0f,0xe4,0x87,0x87,0x8c,0x9f,0xb0,0x1f,0x0e,0x0e,0x13,0x1f,0x1c,0xa2,0x2a,0xa5,0xb5,0x0d,0x09,0x17,0x1e,0x17,0x1c,0x01 +,0x07,0x00,0xae,0x84,0x8e,0x15,0x1d,0x1e,0x0a,0x05,0x08,0x9e,0x88,0x87,0x24,0x9a,0x9b,0xaa,0x1d,0x2e,0x28,0x8b,0x8b,0xa6,0x80,0x8a,0x9b,0x37,0x95,0xa7,0x9b,0x96 +,0x5f,0x59,0x3c,0x33,0x94,0x80,0x8a,0x38,0x2c,0x1a,0x12,0x26,0x00,0x29,0x90,0x9e,0x4e,0x13,0x25,0x09,0x0a,0x09,0x0a,0x18,0x4c,0x3a,0x2d,0xbe,0x15,0x08,0x13,0x0d +,0xb4,0xad,0x13,0x2f,0x0a,0x0f,0xa4,0x85,0x82,0x9d,0x93,0xae,0x2b,0x5c,0xd0,0x8c,0x80,0x83,0x83,0xa2,0xa0,0x8c,0x1e,0x1a,0xad,0x96,0xa6,0x91,0xa8,0xcd,0x0f,0x38 +,0x17,0x09,0x29,0x11,0x3c,0x07,0x08,0x0b,0x0d,0xac,0x80,0x4f,0x13,0x38,0x01,0x0b,0x0f,0x0f,0x96,0x8b,0xa1,0x6e,0x4e,0xab,0x13,0x17,0xbe,0x27,0x8a,0x9d,0x93,0x8f +,0x9c,0xe3,0x2b,0x9b,0x42,0x90,0x40,0x2f,0x1b,0x29,0xbb,0x9c,0x85,0x89,0xbd,0xc3,0xa9,0x1b,0x25,0x09,0x9f,0x80,0x94,0xaf,0x2e,0x23,0xac,0xc2,0x06,0x0d,0x2a,0x52 +,0xb0,0x9c,0x21,0x0d,0x2b,0x2d,0x16,0xf5,0x21,0x09,0x1c,0x0c,0x07,0x15,0xcb,0x8a,0x86,0x1a,0x0e,0x28,0x1c,0x0b,0x22,0x98,0x88,0x80,0x90,0x95,0xc8,0xad,0xa2,0xef +,0x8e,0x98,0x88,0x83,0x92,0x9c,0x9e,0xc9,0x22,0x99,0x4e,0xa2,0x0d,0x08,0xa5,0x0e,0x04,0x1a,0xa2,0x84,0xaa,0x00,0x06,0x0c,0x0b,0x01,0x0d,0x86,0x8b,0xe2,0x36,0x0b +,0x28,0x0f,0x14,0xab,0x92,0x93,0x95,0x8d,0x97,0x8f,0x39,0x38,0x99,0xd0,0x94,0xa9,0x1e,0xaf,0x16,0x17,0xad,0x92,0x85,0x81,0x31,0xb5,0x17,0x11,0x26,0x0b,0x8f,0x86 +,0x8c,0x4c,0x1c,0x15,0x67,0x17,0x24,0x26,0x36,0x8b,0xb8,0x2f,0x38,0x3d,0x4b,0x0f,0x10,0x9a,0x5d,0x10,0x1e,0x1e,0x0c,0x21,0x12,0x9e,0x80,0xaf,0x15,0x1c,0x15,0x0e +,0x17,0x0f,0x94,0x89,0x92,0x9c,0x13,0xce,0x5a,0x12,0x28,0xa2,0x8c,0x82,0x9a,0x6c,0x8a,0x95,0x50,0x3a,0x94,0x8f,0x4a,0x1e,0x49,0x1d,0xb3,0x2d,0x14,0x8c,0x86,0x57 +,0x06,0x0b,0x0d,0x0b,0x05,0x12,0x8c,0x96,0x9f,0x1a,0x0b,0x17,0x08,0x42,0x30,0x27,0x95,0x8f,0x97,0x9a,0x2c,0x27,0xb5,0xb9,0x29,0xba,0x98,0x19,0x18,0x28,0x25,0x1f +,0xbc,0x86,0x82,0x93,0x20,0x23,0x24,0x24,0x1a,0xa0,0x80,0x88,0x95,0x2a,0xd3,0x10,0x1e,0x1d,0x22,0xb5,0xa4,0x8f,0x2d,0x18,0x1e,0x1f,0x0f,0x1f,0xed,0xa6,0x1e,0x0c +,0x0b,0x25,0x33,0x25,0x3b,0x9b,0x80,0x93,0x0e,0x0a,0x2b,0xc3,0x2d,0xa4,0x82,0x84,0x99,0x17,0x24,0x1c,0x12,0x46,0xc6,0x98,0x9b,0xa6,0x28,0x1e,0x39,0x32,0xa4,0xc5 +,0xad,0xa6,0x24,0x3e,0x0d,0x12,0x2b,0xb4,0xd4,0xdb,0x85,0x8f,0x2e,0x08,0x0f,0x4f,0xc5,0x2e,0x8f,0x82,0x92,0xbc,0x0f,0x1b,0x34,0xec,0x29,0x2d,0xac,0x9d,0xd5,0x15 +,0x29,0x1d,0xc9,0x3f,0x2e,0x23,0x20,0x2c,0x31,0x2b,0x1b,0xca,0x32,0x23,0xa1,0x83,0x9d,0xc9,0x28,0x2b,0xad,0xc6,0xa8,0x90,0x86,0x8c,0xa8,0x1a,0x18,0x36,0x52,0x2b +,0xba,0xde,0x9e,0xbc,0x1f,0x29,0x27,0x61,0x33,0x36,0xaf,0xa2,0xe1,0x2a,0x0d,0x1e,0x2f,0x19,0x14,0xa8,0x82,0x8b,0xbe,0x0a,0x10,0xf3,0x2b,0x25,0x95,0x8a,0x8e,0xc0 +,0x0d,0x10,0x31,0x2d,0x22,0x2c,0x9f,0x90,0x49,0x1c,0x20,0x3f,0xcd,0xbf,0xe6,0x52,0x9b,0x3d,0x1f,0x0f,0x0b,0x35,0x43,0x20,0xa7,0x84,0x86,0xa8,0x0d,0x09,0x2e,0xbf +,0x26,0x97,0x8d,0x8c,0x99,0x11,0x0b,0xa6,0x9f,0x1d,0x55,0xaf,0x9b,0xa4,0x21,0x32,0xa6,0x45,0x2b,0x2f,0x2f,0x9f,0xce,0x1c,0x12,0x13,0x4d,0x25,0x18,0x28,0x89,0x86 +,0xa3,0x1c,0x0d,0x1e,0x3d,0x1b,0xcd,0x93,0x8a,0x89,0x28,0x0f,0x1c,0xd6,0xe4,0x6b,0x38,0x9f,0x98,0x38,0x30,0xf2,0xa2,0xc8,0x1c,0x2c,0x9d,0x91,0x34,0x13,0x11,0x23 +,0x41,0x2c,0x2a,0x9e,0x84,0x8d,0x27,0x0c,0x19,0xaf,0xc1,0x1f,0xa8,0x89,0x89,0xb7,0x0f,0x1b,0xad,0x3c,0x46,0x4b,0xb1,0xa3,0x4f,0x21,0xd8,0xa8,0x3f,0x3d,0x2a,0xae +,0xad,0x2e,0x18,0x17,0x26,0x34,0x4f,0x1c,0x1d,0x8b,0x86,0xc8,0x12,0x12,0x1f,0xa6,0xb4,0x31,0x98,0x8a,0x97,0x40,0x20,0x34,0xb7,0x25,0x3d,0x6d,0xd7,0x9f,0x9e,0xaf +,0x73,0x25,0x2d,0xd8,0xbe,0xa4,0xae,0x1b,0x0d,0x16,0x38,0x33,0x17,0x1f,0x3f,0x87,0x8e,0x29,0x18,0x0b,0x27,0x3d,0x3a,0x9e,0x8a,0x8a,0x9d,0x25,0x14,0x19,0x70,0xa4 +,0xa9,0xad,0xa6,0x95,0x52,0xc2,0xa7,0xbd,0x24,0x40,0xa3,0xa5,0xc5,0x0e,0x1a,0x15,0xd2,0x2f,0x13,0x25,0x8d,0x88,0x1d,0x1a,0x17,0x33,0x57,0x2e,0xb3,0x92,0x8c,0x9a +,0x3c,0x1e,0x26,0x3d,0x22,0x2d,0x9d,0x99,0x97,0xbe,0x20,0x31,0x3e,0x3d,0x6a,0x3b,0x54,0xb6,0x2a,0x17,0x12,0x32,0xbb,0x15,0x13,0x99,0x83,0x8e,0x26,0x0a,0x1a,0xae +,0xb7,0xb0,0x94,0x8b,0x8d,0x4b,0x0f,0x18,0xbf,0xa0,0x3b,0x41,0x9e,0x96,0xac,0x1d,0x12,0x1c,0x59,0xcf,0x3e,0xa9,0xdc,0x22,0x0c,0x0b,0x30,0x37,0x1a,0x2d,0x86,0x85 +,0xad,0x0e,0x08,0x35,0x9c,0xac,0xa6,0x8d,0x8a,0x8e,0x2a,0x0d,0x1a,0xac,0x9c,0xcc,0xad,0x98,0x98,0x2d,0x0e,0x0f,0x22,0xaa,0xa6,0xab,0xbb,0x50,0x12,0x04,0x13,0x37 +,0x51,0x4f,0x89,0x85,0xa9,0x14,0x06,0x24,0xac,0xac,0xb2,0x96,0x87,0x8d,0x34,0x14,0x15,0x1f,0xbf,0xa3,0x9b,0x96,0xb2,0x32,0x14,0x0d,0x2f,0xbb,0xb3,0xa7,0xbd,0x24 +,0x10,0x0e,0x18,0x2c,0x2b,0xa6,0x83,0x8e,0x4d,0x1b,0x0c,0x46,0xea,0x34,0x90,0x87,0x85,0xa4,0x0f,0x0f,0x24,0x3d,0xbf,0xb2,0x95,0x93,0x24,0x1b,0x19,0x2e,0x67,0x2e +,0x6d,0xc4,0x47,0x19,0x14,0x48,0x40,0x0f,0x33,0x86,0x89,0xa9,0x1f,0x08,0x2a,0xb4,0x37,0x94,0x8b,0x87,0x94,0x1a,0x11,0x11,0xc9,0x96,0x7e,0x4f,0x9c,0xa7,0x38,0x19 +,0x0e,0x31,0x3e,0x51,0xbd,0x23,0x23,0x17,0x16,0x30,0x1d,0x9f,0x83,0x9a,0x4f,0x10,0x10,0xe7,0x4e,0xa8,0x8e,0x89,0x88,0x9e,0x1a,0x28,0x21,0x3c,0xaf,0x35,0x99,0x9e +,0x56,0x2b,0x23,0x44,0x20,0x1e,0x4e,0xcf,0x2c,0x18,0x10,0x1d,0x2f,0xe6,0x8c,0x8f,0xa1,0x1f,0x05,0x19,0xcd,0xb2,0x9a,0x8e,0x8d,0x8c,0x3b,0x17,0x27,0x3e,0x9f,0xa6 +,0x2e,0xcd,0xc1,0x4f,0xed,0x28,0x3e,0x31,0xb6,0xcd,0x1f,0x09,0x16,0x31,0x2e,0x35,0x8d,0x84,0x9d,0x2f,0x05,0x14,0xb7,0xb7,0x9f,0x8b,0x92,0x94,0x4e,0x17,0x17,0x71 +,0x9e,0xb4,0xab,0x9e,0xb8,0x1a,0x0e,0x2e,0xa4,0x44,0x42,0xab,0x65,0x08,0x0b,0x16,0xd2,0x22,0x93,0x83,0x99,0x42,0x03,0x0d,0xd6,0xaf,0xa2,0x8f,0x8c,0x8a,0x3a,0x0d +,0x1b,0x2d,0xb8,0x99,0x92,0x91,0x7a,0x19,0x1f,0x26,0xcb,0x9d,0x32,0x3b,0x22,0x10,0x2a,0x1a,0x23,0x32,0x8c,0x85,0xa1,0x17,0x06,0x18,0xaa,0xcf,0xb7,0x8e,0x8c,0x95 +,0x1f,0x0c,0x1d,0x23,0xaa,0x98,0xb4,0xab,0x4e,0x28,0x1f,0x1d,0xbe,0x9d,0xba,0xb1,0x1a,0x09,0x15,0x3d,0x34,0x97,0x84,0x8c,0xa6,0x11,0x03,0x13,0xb2,0x96,0x86,0x92 +,0x90,0xa7,0x13,0x0f,0x1d,0xbd,0x9d,0x9c,0xa0,0xb8,0x21,0x1f,0x1e,0x25,0x44,0xad,0xb5,0x33,0x19,0x13,0x11,0x1a,0x1f,0x8c,0x83,0x9f,0x34,0x09,0x0d,0xaf,0xc7,0xb8 +,0x8f,0x8c,0x89,0xc9,0x0d,0x0d,0xda,0xa3,0xa6,0xa9,0xa2,0xa6,0x29,0x1f,0x1a,0x30,0xad,0xa4,0xab,0x1f,0x10,0x19,0x1e,0x18,0x3b,0x83,0x86,0xae,0x0c,0x05,0x25,0x3a +,0x47,0x8d,0x89,0x8c,0xa7,0x09,0x0f,0x37,0xad,0x9c,0xbf,0xa5,0x98,0x4b,0x17,0x0f,0x2e,0xab,0x9b,0xb4,0x20,0x13,0x18,0x1f,0x1e,0x20,0x8f,0x81,0x94,0x2a,0x06,0x0e +,0xa9,0x3c,0x39,0x8f,0x8b,0x84,0x3d,0x06,0x16,0x4b,0xab,0x99,0x59,0xa3,0x94,0x2d,0x22,0x1a,0x17,0x3a,0xa5,0xbd,0x33,0x25,0x1c,0x1d,0x1b,0x2a,0x85,0x86,0xa0,0x1e +,0x07,0x15,0xdf,0x22,0xa8,0x89,0x8d,0x91,0x1c,0x0e,0x25,0x24,0x4c,0x9c,0x96,0x97,0xb1,0x18,0x15,0x1a,0x2c,0xa7,0xa8,0xb9,0x19,0x12,0x1c,0x4b,0x16,0xa6,0x80,0x89 +,0xaf,0x08,0x07,0x2b,0xb7,0x67,0x8d,0x8a,0x8a,0xee,0x0b,0x15,0x35,0x6c,0xd6,0xa3,0x99,0x9d,0x2e,0x1c,0x1e,0x24,0x5a,0x58,0xaf,0x74,0x0e,0x1a,0x2f,0x5e,0x23,0x91 +,0x83,0xa7,0x1e,0x07,0x25,0xad,0x29,0xd7,0x93,0x87,0x8a,0x2f,0x08,0x18,0x25,0x2c,0x9f,0x9b,0x8f,0xad,0x24,0x24,0x18,0x24,0x65,0xbc,0xac,0xe7,0x13,0x15,0x29,0x6a +,0x28,0x8a,0x84,0xbc,0x1c,0x04,0x1e,0xa5,0xcc,0x95,0x90,0x94,0x8d,0x2c,0x0b,0x10,0x2e,0xd8,0xa8,0xa9,0xa1,0x97,0x1c,0x12,0x2b,0xe7,0xbf,0x4b,0x35,0x19,0x0f,0x24 +,0x46,0xd3,0x6d,0x88,0x8b,0x41,0x23,0x08,0x1d,0x9f,0xdc,0x9f,0x8c,0x8e,0x8f,0x24,0x11,0x15,0x24,0xb6,0xa9,0xa3,0xa2,0xb9,0x36,0x27,0x2f,0x28,0x27,0xac,0x44,0x2a +,0x18,0x1b,0x1e,0x20,0x3b,0x89,0x84,0xe2,0x1d,0x09,0x23,0xa6,0x29,0xb7,0x8d,0x8c,0x8c,0xb7,0x0f,0x15,0x1e,0xde,0xad,0x9f,0x98,0xfd,0x23,0x1c,0x23,0xbc,0x3d,0x4c +,0x48,0xbb,0x30,0x0f,0x15,0x2c,0x1a,0x34,0x81,0x8a,0xa6,0x19,0x06,0x20,0xc4,0x27,0x94,0x8a,0x8b,0x8f,0x15,0x1a,0x22,0x26,0x38,0xf0,0x9b,0x91,0xf3,0x24,0x1c,0x28 +,0xba,0x3e,0xb4,0x30,0x2f,0x25,0x18,0x13,0x21,0x25,0x9f,0x80,0x9b,0x24,0x18,0x0d,0xc4,0x31,0x2b,0x8e,0x8e,0x8b,0xa9,0x28,0x1f,0x20,0x1a,0x3c,0xa5,0x9f,0x9b,0xb9 +,0xd1,0x1f,0x1d,0x21,0x34,0xb6,0xb9,0x57,0x21,0x17,0x17,0x20,0x14,0xa7,0x80,0x8c,0xaf,0x15,0x0c,0x2d,0x3b,0x2c,0x99,0x8b,0x8b,0x92,0x22,0x1e,0x2c,0x17,0x3b,0xbb +,0xa8,0xa1,0xaa,0xc0,0x47,0x20,0x2b,0x26,0x20,0x33,0xad,0x2f,0x12,0x11,0x16,0x38,0x28,0x87,0x86,0xa0,0x30,0x0a,0x26,0x46,0x14,0x9f,0x87,0x89,0x8b,0x37,0x24,0x1d +,0x17,0x2f,0x34,0xab,0x93,0x9c,0xaa,0x33,0x16,0x16,0x2f,0xb0,0x3f,0xb2,0x28,0x0c,0x17,0x11,0x5c,0x24,0xa2,0x80,0x92,0x22,0x15,0x13,0x34,0x2a,0x1e,0x8e,0x86,0x84 +,0xa6,0x1d,0x1d,0x19,0x17,0x27,0xbd,0x9e,0x93,0x9a,0xb4,0x1b,0x17,0x24,0x30,0xf8,0x49,0x3a,0x18,0x0f,0x22,0x40,0x5d,0x2d,0x8a,0x82,0xc8,0x1a,0x09,0x1d,0xa2,0x2a +,0x9c,0x8b,0x85,0x8d,0x1b,0x15,0x24,0x1d,0x1f,0x49,0x9f,0x92,0xac,0xd9,0xec,0x39,0x13,0x1b,0x26,0xd4,0xd5,0x21,0x1d,0x1b,0x23,0x2d,0x1d,0xb4,0x80,0x8c,0x36,0x09 +,0x0d,0xac,0x5f,0x1f,0x8c,0x87,0x8b,0x9c,0x1f,0x1e,0x1d,0x1e,0x29,0x64,0x9e,0x8f,0x9e,0xb3,0x3e,0x1b,0x1a,0x16,0x2b,0xcc,0x3e,0x61,0x19,0x29,0x5d,0x1d,0x11,0x9b +,0x82,0x95,0x26,0x0b,0x1d,0xb0,0x25,0x3f,0x8b,0x85,0x8a,0x32,0x11,0x22,0x1f,0x1c,0x4a,0xa2,0x90,0x97,0xa8,0x25,0x1d,0x2f,0x18,0x1c,0x3e,0xaa,0xa6,0x3e,0x0e,0x19 +,0x1d,0x16,0x25,0x8b,0x80,0x9b,0x14,0x04,0x1d,0xa0,0x40,0xa5,0x8a,0x85,0x96,0x15,0x12,0x21,0x26,0x36,0x9c,0x9b,0x95,0xab,0x3e,0x1a,0x1c,0x23,0x1f,0x3b,0xae,0x9a +,0xfe,0x11,0x07,0x28,0x29,0x37,0x37,0x8f,0x81,0xb3,0x0d,0x0a,0x79,0xa2,0x30,0x9f,0x85,0x89,0x99,0x0c,0x13,0x2f,0x3f,0xa9,0xa5,0x94,0xa7,0x27,0x13,0x31,0x3d,0x28 +,0x3e,0xb8,0x9f,0x59,0x16,0x15,0x24,0x2f,0x27,0x1f,0x2a,0x93,0x84,0xa9,0x18,0x1a,0x2f,0xba,0x3f,0xb0,0x8c,0x8b,0x9d,0x23,0x21,0xc5,0x49,0x2b,0x4a,0xb5,0xbb,0xd4 +,0x46,0xb9,0xaf,0x24,0x1f,0x21,0x2d,0xcd,0x4e,0x36,0x1c,0x1e,0x2b,0x2f,0x20,0xac,0x86,0x95,0x4c,0x23,0x1b,0xd6,0x2a,0x1c,0x94,0x88,0x8c,0xa6,0x2b,0xbf,0x1b,0x0d +,0x1d,0xc3,0x90,0x96,0xba,0xb9,0x41,0x21,0x12,0x14,0xb3,0xa9,0xb6,0x3f,0x3a,0x33,0x15,0x17,0x1d,0x26,0x96,0x83,0x92,0x2c,0x0f,0x0f,0x47,0x75,0x9d,0x88,0x86,0x8e +,0x24,0x10,0x0f,0x18,0x3e,0xb2,0x9f,0x9d,0xa9,0xaf,0x3d,0x18,0x11,0x19,0x4a,0x9c,0xa9,0xc5,0x22,0x1a,0x14,0x36,0xa1,0x32,0x1a,0x9f,0x8b,0x3a,0x5f,0x1f,0x19,0x27 +,0x5e,0x8f,0x80,0x89,0x88,0x9c,0x21,0x2f,0x11,0x0e,0x0b,0x16,0x9e,0xb0,0x15,0x0f,0x1a,0x1c,0x1a,0x92,0x84,0x8d,0xa4,0xdc,0x4b,0x3a,0xaf,0x8d,0x93,0xb9,0x38,0x9c +,0x5e,0x04,0x05,0x0b,0x18,0x0d,0x0e,0xa1,0x88,0x9a,0x1a,0x1f,0x4f,0x43,0x31,0xb8,0x8c,0x85,0x85,0x9e,0x3a,0x10,0x17,0x0e,0x08,0x14,0x95,0x83,0x40,0x0d,0x0e,0xeb +,0x9e,0x9c,0x91,0x8c,0x87,0x8c,0x29,0x0d,0x07,0x4b,0x8e,0x20,0x1d,0xce,0x96,0xa8,0x14,0x14,0x17,0x1b,0x62,0x90,0x89,0x9b,0xb5,0x3f,0x1c,0x0f,0x0f,0xbc,0xa3,0xa8 +,0x8f,0x8c,0x99,0x22,0x05,0x05,0x0a,0x0d,0xbb,0x86,0x87,0xab,0x18,0x11,0x21,0xb0,0x98,0x9d,0xa0,0x93,0x8d,0x99,0x4a,0x37,0x2a,0x1c,0x12,0x1a,0xb0,0xdf,0x16,0x28 +,0x2d,0x16,0x17,0xaa,0x90,0xaf,0x3e,0x99,0x8b,0xa1,0x2d,0x36,0xa7,0x93,0x86,0x83,0x92,0x1d,0x09,0x05,0x05,0x04,0x0d,0x9c,0xae,0x14,0x1d,0xaf,0x97,0x9f,0xc4,0xeb +,0xa5,0x9a,0xae,0xa4,0xa2,0x9f,0x91,0xbe,0x14,0x0c,0x1e,0x24,0x0e,0x0e,0x24,0x9a,0xab,0x5e,0xca,0x93,0x8a,0xa3,0x4b,0x1a,0x2b,0xa5,0xa1,0x9e,0x99,0x8f,0x94,0x1e +,0x05,0x07,0x0c,0x22,0x79,0x9f,0xa6,0x33,0x43,0xb8,0x99,0x8d,0x94,0xb2,0x35,0x32,0x9d,0xa1,0x1e,0x1c,0x9d,0x95,0xc5,0x28,0xa1,0x2e,0x0e,0x0e,0x15,0xa4,0x2b,0x21 +,0x74,0xaf,0xc4,0x72,0x72,0x2a,0x12,0x1c,0x8b,0x82,0x83,0x85,0x99,0x4c,0x34,0x38,0xb8,0xac,0x99,0x97,0xaa,0x23,0x1a,0xae,0x99,0xbe,0x26,0x94,0x82,0x90,0x16,0x05 +,0x0d,0x1d,0x11,0x20,0xd8,0x2d,0x0c,0x00,0x01,0x00,0x02,0x06,0x08,0x0d,0x2b,0x7d,0x50,0x14,0x09,0x0b,0x0d,0x22,0x96,0x8d,0x93,0x6b,0x24,0x1b,0x0a,0x0b,0xb4,0x89 +,0x93,0x94,0x9d,0x95,0x8e,0x94,0x87,0x81,0x80,0x80,0x84,0x8f,0xa2,0xa2,0x95,0x98,0x9d,0x8a,0x94,0x5e,0x22,0x21,0x44,0xad,0xa6,0xab,0xbc,0xc6,0x2a,0x2b,0x95,0x96 +,0xbb,0x91,0x91,0x27,0x2b,0x19,0x2c,0x2c,0x11,0x26,0xb7,0xed,0x0f,0x02,0x04,0x09,0x06,0x09,0x0f,0xba,0x9c,0x37,0x15,0x12,0x0e,0x0e,0x11,0x25,0xbe,0xb9,0x50,0x0e +,0x0b,0x15,0x0b,0x0f,0x8c,0x8b,0xa1,0x2e,0x0c,0x1d,0x22,0x5e,0x8e,0x89,0x88,0x8e,0xbb,0x97,0xa0,0xc4,0x9e,0x95,0x8c,0x93,0xa9,0xd8,0x1b,0x0a,0x14,0x30,0x9b,0xa8 +,0x22,0x16,0xbf,0x8c,0x8b,0x8e,0x82,0x86,0x9e,0xab,0x27,0x9c,0xb8,0x27,0xc8,0xc0,0x3d,0x0c,0x02,0x06,0x07,0x05,0x14,0x28,0xb5,0x42,0x17,0x2c,0x30,0xfb,0xa7,0xa3 +,0x88,0x83,0x86,0x9a,0x46,0x8f,0x90,0xb0,0x8b,0x80,0x85,0x84,0x9b,0xa4,0x97,0xec,0x94,0x84,0x83,0x82,0xb1,0x0c,0x09,0x01,0x04,0x0b,0x15,0x1a,0x07,0x06,0x04,0x00 +,0x01,0x00,0x06,0x08,0x06,0x04,0x09,0x0c,0x07,0x02,0x25,0x9b,0x1d,0x0d,0x0a,0x38,0x9c,0xb0,0x99,0x97,0x9c,0xab,0x1d,0x2a,0x55,0xba,0x8c,0x8e,0x8e,0x8a,0x90,0x87 +,0x85,0x8c,0x8f,0x8d,0x86,0x86,0x93,0xc2,0x9d,0x95,0xc0,0xbb,0x86,0x88,0xa0,0xc2,0x3f,0x99,0x9b,0xa7,0x8c,0x86,0x84,0x87,0x8a,0x8b,0xb3,0x32,0x65,0xa2,0x89,0x96 +,0xfb,0x39,0x0d,0x03,0x01,0x03,0x0e,0x0f,0x03,0x02,0x0c,0x38,0x17,0x3c,0x87,0x9e,0x2f,0x0c,0x0a,0x43,0x1a,0x17,0xb1,0x9f,0xa0,0x13,0x05,0x04,0x05,0x0f,0x2e,0x93 +,0x8c,0x9f,0x56,0x36,0x28,0x26,0x46,0x9f,0x97,0xcd,0x0f,0x13,0x54,0x3d,0x12,0x9c,0x8a,0x2a,0x1e,0x0b,0x12,0xc0,0x29,0x94,0x83,0x83,0x82,0x8d,0x94,0xa3,0x2c,0xd4 +,0x99,0x8b,0x8e,0xa7,0xa1,0xaf,0x24,0x0d,0x09,0x0e,0x0f,0x0b,0x0e,0x21,0x31,0x0e,0x0e,0x8e,0x90,0xb9,0x36,0x2a,0x9a,0x9d,0x91,0x80,0x80,0x80,0x81,0x8a,0x8c,0x9a +,0xe8,0x9b,0x8b,0x86,0x8b,0x8f,0x95,0xbe,0x2e,0x1a,0x2f,0x9f,0xab,0x15,0x09,0x06,0x0b,0x00,0x0a,0x99,0x1b,0x05,0x02,0x00,0x01,0x00,0x00,0x0c,0x24,0xcb,0x1c,0x0e +,0x1e,0x09,0x03,0x0c,0x27,0xae,0xce,0x9d,0x98,0x40,0x2c,0x0f,0x14,0x1d,0x0f,0x0e,0x12,0xcc,0x9e,0x9a,0x86,0x80,0x87,0x89,0x8d,0x8d,0x86,0x9e,0x8e,0x81,0x83,0x82 +,0x92,0x96,0xbe,0x18,0x13,0x1e,0xb1,0x96,0x8f,0x89,0x8c,0xa0,0xb5,0x57,0x9c,0xa1,0xcc,0xba,0xb0,0xc4,0x22,0x0f,0x90,0x85,0xed,0x1f,0x07,0x07,0x08,0x00,0x13,0xca +,0xc2,0xc4,0x1f,0x2d,0x0e,0x07,0x17,0x13,0x2d,0x30,0x29,0xa8,0x57,0x19,0x0f,0x11,0x28,0x14,0x0a,0x0b,0x0f,0x18,0x31,0x16,0x9a,0x8a,0x39,0x36,0x1d,0xbf,0xc1,0x25 +,0x94,0x86,0x8a,0x8a,0x92,0x95,0xa4,0x1f,0x3e,0x5f,0xbe,0xb0,0x24,0xb1,0x9d,0x4f,0x2e,0x56,0x98,0x8a,0x8f,0x96,0x95,0xab,0x99,0x3d,0x9d,0x80,0x99,0xb1,0x1b,0x0e +,0x0f,0x01,0x05,0x22,0xcf,0x9f,0xa6,0x39,0x2f,0x13,0x17,0x6b,0xa6,0x8a,0x82,0x85,0x85,0x8f,0x90,0x8d,0x99,0x8d,0x8e,0x91,0x99,0xbf,0x99,0xaa,0x9d,0x80,0x8a,0xa9 +,0xab,0x61,0xb9,0x37,0x14,0xe0,0x30,0x19,0x11,0x08,0x08,0x01,0x00,0x01,0x02,0x02,0x06,0x09,0x10,0x08,0x02,0x08,0x0a,0x0c,0x0f,0x22,0x1d,0x10,0x14,0x15,0x0a,0xa4 +,0x87,0x99,0x9c,0x7c,0xbc,0xcc,0x16,0xca,0x89,0x8a,0x89,0x90,0x8c,0x8b,0xaf,0xa7,0x8d,0x85,0x85,0x84,0x85,0x84,0x8f,0xb6,0xa4,0xa8,0xc7,0xad,0x99,0x3d,0x14,0x21 +,0x1a,0x2b,0x8b,0x8a,0x9c,0x96,0xa9,0xa0,0x9d,0x4c,0x91,0x8b,0x8e,0x8d,0x9d,0x92,0x34,0x07,0x07,0x09,0x09,0x09,0x15,0x15,0x0e,0x0c,0x09,0x08,0x0f,0x1d,0x32,0xad +,0x2e,0x1e,0x13,0x0b,0x08,0x36,0x96,0x35,0x19,0x0f,0x09,0x05,0x03,0x0f,0xaa,0xa1,0x93,0x94,0x95,0xa9,0x1f,0x2e,0xc8,0xef,0xb8,0x98,0x93,0x9c,0xd8,0x24,0x1c,0x2d +,0x27,0xbd,0xab,0x58,0xae,0xcb,0x4e,0x39,0x9e,0x81,0x84,0x8b,0x8b,0x92,0x99,0x4a,0x4f,0x8a,0x8b,0x8d,0x8f,0x9d,0xaa,0x13,0x06,0x0a,0x0a,0x0e,0x28,0xb0,0x9f,0x3a +,0x19,0x3b,0x40,0x56,0xb0,0x96,0x8d,0x99,0x98,0x8b,0x89,0x93,0x89,0x80,0x87,0x8d,0x9b,0x9a,0xa7,0x1c,0xae,0x8c,0x9a,0xb6,0xbc,0xa4,0x38,0x09,0x0e,0x0f,0x0a,0x09 +,0x0c,0x28,0x14,0x05,0x03,0x02,0x01,0x00,0x01,0x02,0x04,0x02,0x05,0x0a,0x08,0x06,0x4a,0x8c,0x40,0x2a,0x37,0xd9,0x3d,0x14,0xb8,0x8e,0x8f,0x9a,0x9e,0xa4,0x23,0x0d +,0x23,0xae,0xb4,0x9b,0x86,0x81,0x83,0x86,0x85,0x87,0x8a,0x98,0x91,0x89,0x88,0x94,0x9e,0x9a,0x3d,0x19,0xf8,0x8f,0xad,0xaf,0xa9,0xa0,0xa7,0x3a,0x90,0x88,0x8a,0x89 +,0x8d,0x8b,0xa7,0x1c,0x1d,0x20,0x25,0x29,0xb1,0xa6,0x29,0x10,0x0b,0x04,0x07,0x0b,0x10,0x1a,0x18,0x0f,0x0f,0x0f,0x13,0x0e,0x1d,0x9c,0x31,0x25,0x2a,0x15,0x17,0x0e +,0x11,0x32,0x1f,0x1b,0x39,0xf6,0x24,0x0f,0x10,0x18,0x1b,0x37,0xa1,0x94,0x93,0xb6,0xb4,0xaf,0xe4,0xc3,0xbc,0xa0,0xaa,0xbf,0x2d,0x1b,0x2b,0x35,0x1e,0xae,0x8f,0xa9 +,0xa2,0x9c,0x9a,0x94,0x93,0x89,0x89,0x8d,0x8c,0x8a,0x8a,0x9a,0xce,0x3e,0x1e,0x0c,0x07,0x0b,0x16,0x14,0x16,0x24,0x17,0x14,0x18,0x51,0x95,0x91,0x8c,0x8c,0x93,0x8c +,0x97,0xa3,0x88,0x81,0x8a,0x8d,0x8b,0x8e,0xa7,0x29,0xbd,0x92,0x9d,0xad,0x9c,0x91,0x9c,0x2a,0x1d,0x11,0x09,0x0a,0x0d,0x16,0x15,0x09,0x04,0x02,0x00,0x01,0x02,0x07 +,0x04,0x05,0x08,0x04,0x06,0x0a,0x07,0x16,0x9d,0x9d,0xbc,0x37,0x27,0x16,0x0e,0x26,0x9e,0x96,0x97,0x94,0x94,0xaa,0x1f,0x3f,0xa6,0xa9,0x99,0x8c,0x8d,0x8c,0x8d,0x89 +,0x86,0x8d,0x8d,0x8b,0x8c,0x8b,0x92,0x97,0x9f,0xae,0x9f,0xc9,0x2a,0xa2,0x8c,0xaa,0xda,0xab,0xaf,0xa0,0xc2,0x9e,0x8e,0x91,0x92,0x95,0x91,0x97,0xac,0xad,0xc7,0x31 +,0x29,0x1f,0x24,0x1e,0x1a,0x18,0x11,0x06,0x11,0x0b,0x0c,0x0e,0x05,0x0e,0x03,0x0b,0x08,0x04,0x0c,0x0d,0x9f,0x9d,0x25,0xac,0xac,0x14,0x21,0x8d,0x95,0xa8,0x82,0x8e +,0x8b,0x8a,0x18,0x96,0x89,0x97,0x92,0x8c,0xa9,0xd3,0x44,0x15,0x09,0x08,0x0c,0x06,0x0d,0x09,0x12,0x0b,0x0c,0x0f,0x26,0x3d,0x14,0xb3,0x9d,0xbf,0xbb,0x95,0x8b,0x88 +,0x8d,0x8a,0x8c,0x94,0x93,0x91,0x8e,0x92,0x90,0x9c,0x92,0x90,0x90,0x8d,0x93,0x9a,0x9b,0x98,0xa4,0x4c,0x22,0x2c,0x34,0x3d,0x1f,0x18,0x13,0x0c,0x13,0x0a,0x06,0x0b +,0x13,0x26,0x11,0x0d,0x0d,0x01,0x00,0x04,0x0d,0x13,0x28,0xa5,0xa8,0xc8,0x1e,0x4e,0xb4,0xa8,0x98,0x8b,0x84,0x81,0x84,0x82,0x86,0x88,0x89,0x8b,0x89,0x91,0x87,0x8c +,0xa1,0xc9,0x99,0x20,0x1e,0xa2,0xce,0x1a,0x0a,0x0b,0x09,0x05,0x06,0x09,0x0c,0x09,0x06,0x0e,0x0a,0x07,0x06,0x0b,0x13,0x14,0x2a,0xab,0x91,0x95,0xa3,0x94,0xb4,0xba +,0xa4,0xa4,0xaf,0x40,0x33,0x2b,0x10,0x1e,0x31,0x31,0xa3,0xa7,0x8d,0x96,0x8f,0x83,0x88,0x87,0x8e,0x93,0x88,0x87,0x8f,0x8e,0x96,0x9d,0xd0,0xd0,0xb4,0x16,0x0d,0x0c +,0x13,0x18,0x1a,0x15,0x1e,0x15,0x18,0x0e,0x11,0x0c,0x0c,0x16,0x12,0xce,0x2a,0xab,0xa9,0x8e,0x83,0x8d,0x8a,0x88,0x84,0x88,0x9a,0x8d,0x88,0x8a,0x86,0x85,0x8b,0x97 +,0xb5,0x3f,0x2f,0x27,0x0f,0x23,0x1a,0x19,0x28,0x18,0x21,0x12,0x14,0x0b,0x0b,0x0a,0x0a,0x0b,0x1a,0x11,0x1c,0x45,0xae,0xa6,0xcd,0x6b,0x34,0x35,0x1d,0x19,0x16,0x1a +,0x10,0x1d,0x0d,0x0b,0x0b,0x0a,0x0a,0x02,0x08,0x07,0x1e,0x47,0x26,0x1d,0x48,0x9a,0xa8,0x9c,0x9d,0x97,0x86,0x8e,0x92,0x89,0x8f,0x8b,0x90,0x8d,0x8b,0x9e,0x96,0x8e +,0x97,0x2d,0xca,0x1a,0x1c,0x2d,0x4a,0x9a,0x17,0xec,0xa7,0xb3,0x9b,0xa2,0x90,0x8d,0x8e,0x93,0x8e,0x89,0x9d,0x96,0x97,0x97,0x8e,0x9b,0xb1,0x23,0x45,0x1e,0x1f,0x0c +,0xa3,0xae,0x19,0xb1,0x0e,0x14,0x0b,0x08,0x0b,0x0f,0x0b,0x1f,0x24,0x25,0xc1,0xaa,0x8f,0x88,0x8d,0x8b,0x83,0x87,0x8c,0x9d,0x8f,0xd1,0x29,0x44,0x08,0x07,0x03,0x00 +,0x02,0x00,0x02,0x00,0x0b,0x0a,0x0a,0x1e,0x26,0x0d,0x0e,0x22,0x2d,0xb2,0xa4,0x8b,0x8c,0x8e,0x8f,0x9a,0x90,0x9b,0x8d,0x84,0x9d,0x95,0x84,0x86,0x8e,0x89,0x8a,0x8f +,0x9f,0x9c,0xbd,0xd0,0xb3,0xab,0xb9,0x5e,0x8d,0x8f,0x8e,0x9f,0x96,0x3f,0xc5,0xad,0xa6,0xab,0xa0,0x9a,0x34,0xc1,0x23,0x1a,0x0a,0x06,0x0b,0x12,0x0d,0x0c,0x0f,0x11 +,0x08,0x02,0x08,0x05,0x0e,0x0b,0x21,0x9e,0x4e,0x9d,0x9d,0x86,0x86,0x89,0x80,0x82,0x80,0x84,0x82,0x82,0x81,0x90,0x9e,0xa6,0x3d,0x21,0x0e,0x06,0x05,0x07,0x05,0x02 +,0x07,0x03,0x04,0x05,0x05,0x07,0x03,0x09,0x0a,0x0d,0x0e,0x14,0x0a,0x17,0x3b,0x19,0x24,0xbe,0x33,0x37,0xa1,0x9d,0x8f,0x8f,0x89,0x97,0x93,0x8c,0x91,0x8c,0x8e,0x8a +,0x89,0x8b,0x87,0x8e,0x86,0x8b,0x90,0x8c,0x93,0x8b,0x8e,0x8a,0x94,0x95,0x9f,0x9c,0x8e,0xa1,0xc1,0xa8,0x24,0x16,0x1a,0x16,0x16,0x0f,0x12,0x07,0x0b,0x07,0x0c,0x0a +,0x03,0x10,0x0a,0x0f,0x37,0xa2,0x9e,0xa7,0x98,0x89,0x87,0x88,0x87,0x8d,0x84,0x86,0x92,0x97,0x8a,0x58,0x1b,0x45,0x14,0x0f,0x0e,0x07,0x0b,0x07,0x10,0x1b,0x10,0x15 +,0x19,0x2b,0x13,0x2b,0x33,0x27,0x27,0xbc,0x1f,0x25,0x16,0x21,0x1b,0x0b,0x15,0x18,0x18,0x0b,0x13,0x1f,0xaf,0x16,0x23,0xce,0x1a,0x12,0x44,0xb9,0xda,0x4c,0x95,0x91 +,0xb2,0x8b,0x8b,0x96,0x96,0x89,0x89,0x89,0x86,0x89,0x8b,0x88,0x9b,0x91,0x8d,0xb7,0x9f,0xb6,0x3e,0x4b,0x3d,0xbe,0x22,0x13,0x35,0x4e,0x10,0x0b,0x0c,0x0e,0x1a,0xc8 +,0x8e,0x9a,0x94,0x89,0x86,0x81,0x8e,0x8b,0x83,0x82,0x86,0x86,0x93,0xab,0x26,0x0e,0x0c,0x02,0x06,0x02,0x02,0x02,0x00,0x0b,0x09,0x00,0x10,0x0c,0x09,0x0c,0x0f,0x0f +,0x1c,0x6d,0x5c,0xa0,0x4c,0xa6,0x9b,0xa5,0x44,0x39,0xab,0x9c,0x8a,0x93,0x91,0x8f,0x9b,0xcf,0x56,0x2d,0x4e,0xa9,0x2d,0x1d,0x9a,0x8f,0x16,0x9a,0x97,0xc1,0xbc,0x9b +,0xa2,0xb7,0x99,0x91,0x97,0x99,0x8c,0xb3,0x9e,0xa0,0x28,0x16,0x13,0x1e,0xac,0x1f,0x52,0x25,0x0a,0x12,0x08,0x0d,0x0b,0x0a,0x0f,0x2d,0x8f,0x99,0x9e,0x85,0x87,0x87 +,0x84,0x86,0x82,0x83,0x82,0x82,0x83,0x86,0x88,0x8d,0xa7,0x3e,0x0b,0x09,0x02,0x03,0x04,0x01,0x07,0x07,0x03,0x02,0x02,0x02,0x04,0x01,0x0a,0x0a,0x1a,0x18,0x28,0xe8 +,0x1a,0x1f,0x1e,0xe4,0x67,0xcd,0xa5,0x8e,0xa6,0x92,0x87,0x9b,0x8f,0x93,0x92,0xb3,0xb0,0xaa,0x97,0xa0,0x9c,0x8d,0x9b,0x97,0xaa,0xa6,0x9e,0xa6,0x55,0x8d,0x89,0x91 +,0x86,0x8c,0x93,0x99,0xa4,0xad,0x1b,0x27,0x9b,0x26,0x1f,0xd3,0x1b,0x0f,0x14,0x0e,0x0c,0x06,0x06,0x0c,0x0f,0x16,0x0f,0xae,0xac,0x75,0xbe,0x92,0x88,0x90,0x8b,0x87 +,0x83,0x86,0x83,0x81,0x89,0x8f,0x90,0xc7,0x20,0x17,0x0e,0x12,0x0b,0x0f,0x13,0x0a,0x0c,0x08,0x08,0x03,0x0c,0x0f,0x0e,0x1b,0x18,0x27,0x11,0x1d,0x15,0x0a,0x1d,0x19 +,0x0a,0x1b,0x36,0x15,0xd6,0x91,0x3f,0x26,0x9b,0x9e,0x1e,0x41,0xc8,0xac,0xa3,0x93,0x88,0x94,0x96,0xb4,0x8c,0x8e,0xad,0x8e,0x93,0x89,0x87,0x91,0x8d,0x9c,0x99,0xac +,0xc0,0xbe,0xce,0x31,0xa9,0xb4,0x1c,0xa6,0x26,0x2f,0x1c,0x14,0x0f,0x08,0x12,0x18,0x0d,0x23,0xad,0x9f,0x93,0xaf,0x95,0x8e,0x8e,0x8d,0x85,0x82,0x83,0x85,0x81,0x8a +,0xa7,0xb3,0x37,0x23,0x0e,0x04,0x05,0x0e,0x08,0x06,0x13,0x0a,0x01,0x06,0x04,0x05,0x07,0x0c,0x17,0x10,0x23,0xb4,0x1c,0x19,0x2c,0x1d,0x55,0xb6,0xce,0xa7,0x9b,0x9a +,0x9e,0x92,0x90,0x9a,0x3e,0xae,0xa4,0x65,0xd1,0xb9,0x8d,0x9c,0xa5,0x8f,0x98,0xaa,0xc9,0xb5,0xba,0x9f,0x94,0x95,0x90,0x99,0x89,0x99,0xaa,0xa0,0xbb,0xb0,0xef,0xab +,0xa5,0xcf,0x22,0x4d,0x34,0x18,0x0b,0x0c,0x05,0x07,0x0c,0x0e,0x0c,0x22,0x9e,0xcd,0x93,0x8d,0x90,0x8a,0x88,0x86,0x85,0x82,0x83,0x85,0x85,0x88,0x96,0xbb,0xb4,0x1e +,0x13,0x08,0x0a,0x0b,0x02,0x07,0x0b,0x08,0x02,0x05,0x06,0x05,0x02,0x09,0x0f,0x0f,0x11,0x31,0x2d,0x11,0x2a,0x5d,0x1a,0x2d,0xb1,0xb0,0xa8,0x9a,0x90,0x9a,0xa9,0x9a +,0x94,0xaf,0xaf,0xbf,0xad,0x99,0xa4,0x91,0x8f,0x94,0x9f,0xc6,0xa4,0x9d,0xa5,0x9a,0x9e,0x9b,0x8f,0x95,0x93,0x95,0xac,0xc3,0xa3,0x9e,0xca,0xe7,0xad,0x37,0x3e,0xce +,0x23,0x0f,0x11,0x16,0x0c,0x0a,0x0b,0x0e,0x11,0x35,0xab,0xa9,0xa5,0x9c,0x97,0x91,0x8b,0x88,0x84,0x84,0x83,0x84,0x84,0x90,0xa1,0xa3,0xb5,0x1c,0x0d,0x19,0x0d,0x09 +,0x0f,0x0d,0x0a,0x07,0x0b,0x09,0x06,0x09,0x0b,0x15,0x1e,0x19,0x24,0x21,0x2b,0x25,0x1d,0x25,0x1c,0x1d,0x34,0xc7,0xc7,0xaf,0xab,0xb8,0x35,0xbb,0xae,0x32,0x3f,0xac +,0xac,0xb5,0x97,0x93,0x9c,0x9a,0x9a,0x9d,0x99,0x95,0x9a,0xa5,0x95,0x8f,0x8d,0x8a,0x8e,0x9d,0xa4,0x9d,0xa9,0x58,0x35,0x5f,0x71,0xe4,0x41,0x1f,0x15,0x12,0x11,0x0a +,0x08,0x0b,0x0c,0x14,0x20,0xbe,0xab,0xb7,0x9f,0x9c,0x8c,0x88,0x87,0x84,0x83,0x82,0x85,0x82,0x85,0x8d,0x9c,0xa1,0xd9,0x16,0x0b,0x0c,0x0d,0x09,0x09,0x07,0x05,0x05 +,0x04,0x04,0x04,0x05,0x07,0x0c,0x1b,0x1b,0x19,0x14,0x14,0x1f,0x19,0x1f,0x37,0x46,0xac,0xab,0xa2,0x95,0x93,0x99,0xb4,0xaf,0x9f,0xaa,0xaf,0xb1,0xa5,0x9f,0x9b,0x95 +,0x9f,0xac,0xaf,0x9f,0xab,0xd3,0xab,0x9a,0x92,0x8e,0x8f,0xac,0x9d,0xa0,0xa6,0xa0,0xbb,0xb1,0xc9,0xac,0xa5,0xb7,0xce,0x52,0x22,0x15,0x14,0x14,0x0c,0x0e,0x17,0x18 +,0x28,0xb2,0xa7,0xa7,0x9f,0x9d,0x9a,0x91,0x87,0x86,0x85,0x84,0x85,0x8b,0x92,0x9e,0xb8,0x2d,0x18,0x1a,0x10,0x0d,0x0a,0x04,0x03,0x09,0xa7,0xc9,0x00,0x27,0x8e,0x1b +,0x53,0x1b,0x1c,0x18,0x11,0x15,0x0e,0x18,0x00,0x06,0x02,0x01,0x04,0x00,0x05,0x01,0x02,0x0a,0x0d,0x0c,0x0e,0x18,0x2e,0x28,0x26,0xaa,0xa7,0xa4,0x92,0x98,0x97,0x95 +,0x82,0x80,0x90,0x88,0x80,0x80,0x80,0x81,0x80,0x81,0x82,0x81,0x80,0x80,0x81,0x80,0x81,0x82,0x88,0x8a,0x89,0x8a,0x8b,0x95,0x9b,0x97,0x98,0xb1,0xb7,0xb8,0x42,0x19 +,0x0f,0x0c,0x06,0x07,0x03,0x02,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x01,0x02,0x02,0x05,0x03,0x02,0x02,0x05,0x08,0x05,0x0a +,0x11,0x1e,0x1c,0x1f,0xbe,0xa7,0x93,0x8f,0x88,0x82,0x85,0x87,0x89,0x86,0x84,0x82,0x82,0x81,0x81,0x82,0x83,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x81,0x82,0x82,0x84,0x84,0x85,0x89,0x8d,0x88,0x87,0x8a,0x86,0x8d,0x8f,0x8d,0x95,0x8d,0x8c,0x8d,0x96,0xbd,0xc5,0x26,0x16,0x18,0x0b,0x0b,0x05,0x02,0x03 +,0x00,0x01,0x00,0x01,0x00,0x01,0x01,0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x02,0x01,0x03,0x03,0x07,0x0b,0x0c +,0x0e,0x10,0x1d,0x24,0x2b,0x3b,0x27,0x27,0x1c,0x1b,0x27,0x20,0x38,0x37,0x3e,0xd5,0xa7,0x98,0x93,0x88,0x86,0x87,0x85,0x84,0x83,0x81,0x82,0x81,0x80,0x81,0x82,0x83 +,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x81,0x83,0x84,0x86,0x89,0x8e,0x97,0x9f,0xa4,0xac,0x43,0x48,0x3f,0x36,0x2f,0x1e +,0x10,0x10,0x1b,0x15,0x16,0x10,0x11,0x16,0x16,0x24,0x2e,0x5c,0xbd,0xa3,0x9b,0x9a,0x93,0x8b,0x87,0x89,0x87,0x89,0x86,0x89,0x8f,0x99,0x9f,0x9f,0xac,0x9f,0x98,0x91 +,0x9e,0xa7,0xae,0xb0,0xa8,0xa9,0xa0,0xaf,0x3d,0x2d,0x1b,0x10,0x0f,0x08,0x05,0x04,0x01,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00 +,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x02,0x04,0x07,0x09,0x07,0x06,0x0a,0x09,0x0b,0x0d,0x0f,0x16,0x0f,0x0f,0x16,0x20,0x42,0xbf,0x9f +,0x90,0x90,0x89,0x86,0x83,0x80,0x81,0x81,0x81,0x81,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81 +,0x82,0x83,0x84,0x84,0x85,0x87,0x89,0x88,0x85,0x83,0x84,0x85,0x86,0x87,0x85,0x84,0x81,0x84,0x84,0x83,0x85,0x84,0x87,0x86,0x86,0x8e,0x94,0x9f,0xc4,0xd9,0x27,0x17 +,0x0c,0x05,0x05,0x02,0x01,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x05,0x04,0x05,0x05,0x06 +,0x09,0x0a,0x0f,0x0e,0x0f,0x11,0x0b,0x0c,0x14,0x1f,0x2f,0x5b,0xb5,0xa8,0x9b,0x93,0x8b,0x87,0x87,0x87,0x89,0x87,0x87,0x89,0x88,0x8a,0x8a,0x8e,0x95,0x8d,0x8f,0x8d +,0x8b,0x91,0x8e,0x8f,0x91,0x8b,0x89,0x8a,0x8e,0x90,0x8f,0x94,0x97,0x9b,0xa7,0xae,0xd4,0x33,0x2c,0x2f,0x31,0x2a,0x26,0x2f,0x21,0x1e,0x2b,0x37,0xac,0x45,0x27,0x43 +,0x31,0x4a,0x2d,0x24,0x29,0x1d,0x17,0x11,0x12,0x1d,0x1e,0x1f,0x28,0x1f,0x21,0x23,0x38,0xc0,0x3e,0x37,0x35,0x2e,0x29,0x21,0x20,0x2b,0x22,0x22,0x25,0x32,0xb2,0xbd +,0xa9,0xa3,0xad,0x9f,0x9c,0x9a,0x92,0x9a,0xa3,0xbf,0x36,0x3d,0x2b,0x3c,0xfb,0x3d,0x3e,0x2c,0x33,0x4c,0xb4,0x9e,0x9d,0x92,0x8d,0x8b,0x85,0x84,0x84,0x83,0x84,0x82 +,0x81,0x82,0x80,0x81,0x81,0x84,0x87,0x86,0x89,0x8a,0x8e,0x98,0x9a,0xc5,0x37,0x42,0x29,0x18,0x0b,0x08,0x07,0x03,0x03,0x02,0x02,0x01,0x00,0x01,0x01,0x01,0x02,0x02 +,0x03,0x05,0x04,0x0d,0x13,0x14,0x1f,0x1b,0x2f,0x35,0x3f,0xcd,0x37,0x44,0x37,0x3d,0xb1,0xae,0xa6,0xa2,0xae,0xa6,0xa8,0x99,0x8d,0x8f,0x91,0x97,0x93,0x8f,0x96,0x8f +,0x8f,0x91,0x8e,0x9a,0x93,0x8e,0x97,0x8f,0x91,0x95,0x91,0x99,0x8f,0x8f,0x9e,0xa6,0xdb,0xeb,0x79,0x34,0x32,0x1e,0x1d,0x19,0x0c,0x0d,0x0e,0x12,0x12,0x0b,0x0f,0x0f +,0x0c,0x16,0x19,0x20,0x1a,0x16,0x29,0x1b,0x20,0x28,0x1b,0x1d,0x19,0x19,0x17,0x14,0x21,0x1e,0x1c,0x21,0x1b,0x2e,0x2e,0x3e,0xba,0x53,0x55,0x51,0x48,0xb7,0x5c,0x3b +,0xd5,0x2c,0x2b,0x22,0x2f,0xb9,0xbb,0x9f,0x9d,0x9e,0x93,0x92,0x8b,0x89,0x8b,0x89,0x8f,0x97,0x99,0xa5,0xae,0x3f,0x22,0x1e,0x10,0x0f,0x0f,0x0d,0x0f,0x10,0x0f,0x15 +,0x19,0x2a,0xcb,0xc4,0xad,0xb2,0xa4,0x92,0x8f,0x8c,0x8a,0x8b,0x88,0x8b,0x8a,0x87,0x86,0x84,0x85,0x86,0x87,0x8b,0x8c,0x8c,0x8e,0x97,0xb2,0x49,0x2c,0x16,0x0e,0x0a +,0x07,0x05,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x04,0x06,0x07,0x0d,0x0e,0x0d,0x0f,0x11,0x19,0x1f,0x28,0x2c,0x2d,0x2c,0x24,0x2c,0x49,0xd8,0xae,0x9e,0x97,0x97 +,0x9a,0x92,0x8c,0x8b,0x8c,0x8e,0x8f,0x8d,0x8e,0x8d,0x8d,0x90,0x8f,0x94,0x94,0x90,0x8f,0x8d,0x8d,0x8d,0x8e,0x8d,0x8c,0x8a,0x88,0x8b,0x8f,0x96,0x9f,0xa7,0xab,0xbc +,0x45,0x27,0x1b,0x19,0x19,0x18,0x17,0x13,0x12,0x14,0x15,0x19,0x22,0x28,0x1c,0x15,0x14,0x14,0x17,0x12,0x10,0x12,0x0f,0x0d,0x0d,0x10,0x14,0x15,0x18,0x17,0x16,0x1b +,0x2c,0x38,0x2a,0x29,0x2d,0x2f,0x2d,0x2d,0x29,0x2b,0x21,0x1a,0x1e,0x33,0xc8,0xbe,0xb4,0xa9,0xa2,0xa4,0x9f,0x94,0x8f,0x8f,0x90,0x8e,0x8d,0x8e,0x91,0x96,0x9b,0xa9 +,0xb9,0xb8,0xc5,0xcf,0x5b,0x35,0x2b,0x25,0x2e,0x4a,0x48,0x3a,0x3c,0x43,0x46,0x63,0xc1,0xba,0xac,0xa2,0xa3,0x9f,0x98,0x92,0x8e,0x8b,0x8b,0x8a,0x87,0x85,0x84,0x84 +,0x87,0x89,0x8e,0x90,0x91,0x99,0xab,0x5c,0x2a,0x17,0x0d,0x0b,0x08,0x07,0x07,0x06,0x05,0x04,0x04,0x05,0x08,0x07,0x04,0x05,0x07,0x08,0x0b,0x0b,0x09,0x0a,0x0a,0x0a +,0x0c,0x10,0x1a,0x1c,0x26,0x33,0x3c,0xc0,0xa4,0x9b,0x95,0x93,0x94,0x96,0x97,0x94,0x93,0x93,0x91,0x92,0x95,0x97,0x93,0x90,0x90,0x8e,0x8f,0x8d,0x8b,0x89,0x87,0x86 +,0x88,0x8c,0x8d,0x8d,0x8e,0x8d,0x91,0x96,0x9f,0xc1,0x3b,0x2b,0x32,0x37,0x3d,0x38,0x2c,0x2b,0x27,0x22,0x34,0x2b,0x24,0x26,0x1f,0x1f,0x1c,0x1b,0x16,0x0f,0x0f,0x0e +,0x0d,0x0f,0x11,0x17,0x13,0x11,0x16,0x18,0x1a,0x1f,0x2d,0x29,0x1f,0x1c,0x1a,0x1e,0x23,0x20,0x24,0x2a,0x1f,0x1a,0x1c,0x23,0x33,0x2e,0x3f,0xc3,0xb7,0xad,0xa5,0x96 +,0x95,0x9c,0x99,0x98,0x97,0x97,0x95,0x97,0x9a,0x9d,0xab,0xab,0xab,0xa8,0xae,0xbc,0xc8,0x66,0x58,0x4b,0xdb,0xb0,0xe8,0x34,0x2f,0x2b,0x2f,0x33,0x34,0x43,0x3e,0x3d +,0xd8,0xa8,0x9a,0x90,0x8e,0x8e,0x8c,0x8a,0x88,0x86,0x84,0x84,0x85,0x86,0x89,0x8e,0x8e,0x94,0xa2,0xb8,0x2e,0x1c,0x19,0x13,0x0e,0x0c,0x08,0x08,0x08,0x07,0x08,0x09 +,0x0a,0x07,0x06,0x06,0x05,0x06,0x05,0x07,0x07,0x06,0x06,0x09,0x0c,0x0e,0x12,0x19,0x1d,0x28,0x44,0xb8,0xa6,0xa9,0xa6,0xa0,0x9b,0x9b,0x9c,0x9d,0x9d,0xa6,0xa6,0x9e +,0x99,0x94,0x93,0x93,0x92,0x91,0x8d,0x89,0x89,0x88,0x88,0x89,0x89,0x89,0x89,0x8a,0x8f,0x93,0x9d,0xa1,0x9f,0xa0,0xa3,0xa5,0xad,0xb0,0xab,0xae,0xab,0xb5,0xbd,0x49 +,0x3d,0x3e,0x31,0x2a,0x22,0x1a,0x11,0x0e,0x0f,0x12,0x13,0x14,0x12,0x14,0x16,0x15,0x1e,0x2a,0x20,0x1c,0x18,0x15,0x16,0x14,0x14,0x15,0x11,0x0f,0x0d,0x0c,0x0e,0x12 +,0x16,0x18,0x1f,0x22,0x2f,0x4b,0xb7,0xa7,0xb3,0xb7,0xb0,0xa9,0x9e,0x9b,0x9e,0x9f,0xa0,0xa9,0xaf,0xa8,0x9d,0x96,0x98,0x9a,0x98,0x98,0x9c,0x9a,0x97,0x9c,0xa4,0xb3 +,0xd8,0x5a,0x3a,0x2c,0x23,0x1c,0x1e,0x1a,0x19,0x24,0x3c,0xc8,0xaf,0xa5,0x99,0x90,0x8a,0x87,0x85,0x84,0x86,0x86,0x86,0x86,0x88,0x8a,0x8d,0x94,0x9d,0xbb,0x3d,0x2a +,0x1c,0x1c,0x12,0x10,0x0e,0x0f,0x0f,0x0d,0x0c,0x0b,0x0c,0x09,0x0d,0x0d,0x0f,0x0c,0x0b,0x0b,0x0d,0x0c,0x0e,0x15,0x17,0x1f,0x1f,0x26,0x31,0x55,0xc8,0xae,0xae,0xad +,0xad,0xa9,0xaf,0xb3,0xab,0xb9,0xc3,0xc4,0xbe,0xc7,0xc6,0xbe,0xae,0xba,0xb8,0xa9,0xa9,0x9e,0x9f,0x9e,0xa1,0xa7,0xaa,0xa8,0xa5,0xa9,0xa7,0xaa,0xb0,0xb9,0xbd,0xc5 +,0xbd,0xb8,0xb6,0xb2,0xae,0xb7,0xaf,0xaa,0xa9,0xab,0xb9,0xb5,0xb1,0xb3,0xb4,0xc5,0xcc,0xc4,0xce,0xc9,0xf1,0xcc,0xbe,0xbe,0xc5,0xcc,0xc1,0xbd,0xb4,0xbe,0xbd,0xbc +,0xd9,0x3f,0x30,0x34,0x2a,0x29,0x26,0x22,0x27,0x1f,0x23,0x21,0x21,0x25,0x20,0x24,0x24,0x24,0x2b,0x2f,0x2a,0x29,0x2a,0x2d,0x2f,0x2c,0x2d,0x2f,0x2a,0x26,0x29,0x2c +,0x32,0x37,0x34,0x35,0x33,0x31,0x2e,0x34,0x3f,0x35,0x35,0x46,0x5d,0x5d,0x44,0x54,0x51,0x54,0xf0,0x75,0xba,0xb8,0xb7,0xad,0xa6,0xa1,0x9e,0x99,0x99,0x98,0x95,0x96 +,0x94,0x95,0x92,0x90,0x90,0x91,0x92,0x94,0x98,0x9a,0x9d,0x9b,0x9e,0xa0,0x9e,0x9f,0xa4,0xae,0xb3,0xc7,0xdc,0x4e,0x41,0x4b,0x39,0x29,0x27,0x28,0x1e,0x1e,0x1f,0x1d +,0x1f,0x1b,0x1b,0x1d,0x1c,0x1b,0x1b,0x1c,0x1c,0x1d,0x1a,0x1f,0x21,0x1d,0x1d,0x1f,0x1e,0x1f,0x20,0x22,0x2c,0x29,0x27,0x2d,0x2f,0x2e,0x2f,0x2e,0x38,0x38,0x3b,0x42 +,0x49,0x6e,0x46,0x3b,0x3f,0x40,0x50,0xee,0xce,0xce,0xcb,0xc9,0xdb,0xcb,0xb5,0xaf,0xaa,0xa2,0xa2,0x9f,0x9e,0x9f,0xa0,0x9d,0x9d,0x9c,0x97,0x98,0x97,0x98,0x9b,0x9c +,0x9e,0x9d,0x9c,0x9c,0x9a,0x9b,0x9d,0xa1,0xaa,0xb2,0xbd,0xc8,0xbd,0xcb,0x68,0x42,0x31,0x29,0x28,0x23,0x24,0x28,0x23,0x27,0x21,0x1e,0x1e,0x19,0x1c,0x1c,0x1c,0x20 +,0x22,0x22,0x1f,0x1d,0x1c,0x1d,0x1d,0x22,0x27,0x2a,0x2d,0x29,0x28,0x21,0x1e,0x24,0x2a,0x2a,0x2d,0x34,0x34,0x2f,0x34,0x3a,0x44,0xdd,0xbe,0xb3,0xaf,0xaf,0xb3,0xb4 +,0xa9,0xab,0xa5,0x9f,0xa0,0x9f,0x9e,0x9c,0x9f,0x9e,0x9b,0x9b,0x9a,0x99,0x9a,0x9c,0x9c,0x9d,0x9e,0xa2,0xa0,0x9e,0xa1,0xa7,0xab,0xaa,0xb0,0xb8,0xaf,0xb1,0xbb,0xc4 +,0xcd,0xcd,0x64,0x49,0x78,0x45,0x3f,0x41,0x35,0x44,0x30,0x2f,0x3d,0x36,0x34,0x2e,0x31,0x2b,0x2d,0x37,0x2b,0x2c,0x2f,0x36,0x2c,0x22,0x37,0x2c,0x26,0x31,0x2e,0x39 +,0x2b,0x32,0x37,0x2a,0x2d,0x2a,0x47,0x34,0x2d,0x4e,0x2b,0x37,0x34,0x2c,0x40,0x39,0x44,0x2d,0x34,0x46,0x2b,0x47,0x44,0x31,0x60,0x3a,0x3f,0xcf,0x41,0xd7,0xba,0xbb +,0xc5,0xbe,0xad,0xcb,0xac,0xa9,0xbd,0xa9,0xad,0xa8,0xaf,0xad,0x9e,0xaf,0xa9,0xa3,0xab,0xac,0xb4,0xaa,0xbe,0xb5,0xba,0xc1,0xb6,0x3f,0xc8,0xdd,0x38,0x5b,0x3f,0x3d +,0x42,0x40,0x59,0xdd,0x4d,0x34,0x3c,0x37,0x32,0x2f,0xee,0x4b,0x49,0x58,0x35,0x46,0x34,0x50,0x3d,0x42,0x68,0x33,0x36,0x34,0x2a,0x33,0x30,0x30,0x39,0x2e,0x31,0x32 +,0x28,0x35,0x3c,0x2b,0x4e,0x3c,0x3e,0xd3,0x40,0xee,0x33,0xd1,0xc8,0x39,0xa9,0x41,0xb2,0xaa,0xe3,0xa7,0x6c,0xac,0xae,0xec,0xa5,0xbd,0xad,0xaf,0xc8,0xa4,0x4f,0xb5 +,0xaf,0xaf,0xb0,0xc6,0xac,0xbc,0xa8,0x72,0xaa,0xab,0xfc,0xab,0xb1,0xaf,0xc6,0xaf,0xa5,0x4e,0xae,0xb7,0xc6,0xb3,0xc8,0xac,0xe7,0xac,0x65,0x64,0xb2,0x39,0xcf,0x3a +,0x4e,0x3d,0x2e,0xe1,0x2a,0x3d,0x57,0x45,0x2c,0x39,0x65,0x29,0x34,0x34,0x22,0x2f,0x45,0x29,0x39,0x36,0x35,0x3b,0x2f,0x2a,0x33,0x36,0x39,0x2f,0x5e,0x3b,0x2a,0x64 +,0x2d,0x38,0x2c,0x38,0x3e,0x3f,0x31,0x5b,0xba,0x38,0xc1,0xca,0x62,0xcc,0xab,0xfd,0xc0,0xaf,0xc0,0xbe,0xbc,0xac,0xee,0xa1,0xa4,0x60,0xa8,0xaf,0xb2,0xce,0xb6,0xa6 +,0xcf,0xab,0xa7,0x5c,0xb3,0xb7,0x59,0xc7,0xac,0xd5,0xde,0xae,0x76,0xb2,0x67,0xc9,0xd2,0x59,0xad,0x2f,0xfc,0xac,0x26,0xc9,0x35,0xd5,0x34,0x46,0x41,0x25,0xac,0x1d +,0x3f,0x5e,0x2b,0xf2,0x34,0x29,0xae,0x1d,0x33,0x3e,0x20,0x56,0x28,0x5c,0x30,0x36,0x58,0x2f,0x2c,0x49,0x2c,0xda,0xda,0x67,0x44,0xcc,0xcf,0x5b,0x42,0xde,0xa5,0x2d +,0xb2,0xbd,0xc4,0xcf,0xb4,0xaf,0x4a,0xa7,0xb9,0x5f,0xbd,0xb4,0xb9,0xc9,0xa8,0xc1,0xb8,0xa9,0x5c,0x9f,0xca,0x4a,0x9f,0xc9,0xd5,0xa3,0x54,0xa7,0xc4,0xc2,0xa6,0x2c +,0xa7,0xaa,0x2f,0xa6,0xc3,0xd4,0xb8,0x3e,0xae,0x37,0xd3,0xd6,0xc5,0x43,0x28,0xb6,0x2d,0x45,0x33,0x49,0x69,0x2e,0x48,0x35,0x45,0x1f,0x3a,0xdd,0x26,0x42,0x32,0x2a +,0x43,0x1b,0xce,0x2c,0x2c,0x68,0x23,0x40,0x32,0x47,0x3d,0x41,0x3a,0x41,0x2f,0x3e,0x42,0x55,0x33,0xa6,0x39,0xf7,0xba,0x29,0xa6,0x3d,0xae,0xb5,0xd3,0xad,0x3e,0xa3 +,0xb3,0x46,0xae,0xcd,0xb6,0x5c,0xb3,0xbc,0x4f,0xa2,0xc2,0xd6,0xa3,0xcd,0xb0,0xb8,0xb2,0xb6,0x6b,0xa6,0x3b,0xae,0xc5,0xc3,0xac,0x4e,0xbe,0x2d,0xaf,0x57,0x43,0xa7 +,0x4a,0x78,0xbd,0x38,0x3b,0x2e,0x68,0x54,0x2b,0xcf,0x2b,0x36,0x30,0x46,0x2a,0x28,0xb9,0x3b,0x1f,0x73,0x2e,0x23,0xd2,0x2b,0xc8,0x3b,0x40,0xbe,0x22,0xdc,0x37,0x39 +,0x72,0x45,0x47,0x45,0xb4,0x34,0x3f,0xfc,0x78,0x47,0xcd,0x4a,0xbc,0xca,0x3d,0xc4,0xb0,0x66,0x52,0xcb,0xaf,0xb2,0x5d,0xbd,0xb8,0xbd,0xc2,0xb3,0xd6,0xa4,0xd6,0xb1 +,0xae,0x51,0xaa,0xc9,0xc6,0xa3,0xfc,0xc8,0xac,0x37,0xa7,0xf7,0x3c,0xac,0x53,0xb1,0x63,0x3b,0xb5,0xc1,0x4e,0xcc,0xe8,0x4b,0x51,0x41,0x3a,0xce,0x3f,0xcb,0xc6,0x48 +,0x3e,0x39,0x5c,0x28,0xac,0x1e,0xab,0x3d,0x31,0x5d,0x24,0xb8,0x20,0xbf,0x27,0x4e,0xef,0x2a,0x54,0x73,0x21,0xae,0x4c,0x38,0xe3,0x69,0xeb,0x28,0xd0,0x3e,0xdf,0x48 +,0x67,0xbe,0xbe,0x2c,0xae,0x4e,0x48,0xb0,0x3c,0xa7,0xc4,0xc9,0xda,0xbb,0xc4,0x65,0xc5,0xae,0xaf,0x57,0xa9,0x5f,0xb3,0x36,0xb9,0xb9,0x45,0xa4,0x3b,0xae,0x43,0xb1 +,0x4d,0x41,0xad,0x36,0xac,0xd9,0xd0,0xf6,0x48,0xb2,0x48,0xd5,0x35,0xb4,0x51,0x46,0x3e,0x3e,0xbb,0x31,0x49,0x64,0xcc,0x2a,0xc8,0x77,0x3c,0x30,0xc9,0x3e,0x39,0xe2 +,0x52,0xd3,0x2b,0xc5,0x33,0x2f,0xce,0x39,0xca,0x38,0xd8,0xbf,0x34,0xb0,0x31,0x3e,0xbd,0x5c,0x45,0xd8,0xc8,0xe8,0xfb,0xc4,0x5e,0x59,0xae,0x6e,0xe5,0xb6,0xee,0xe1 +,0x7d,0x37,0xad,0x2a,0xc2,0xa5,0x2d,0xa8,0x55,0xb5,0x31,0xd4,0xa8,0x40,0xac,0x5c,0xbd,0xd4,0x56,0x5c,0x5d,0x47,0xad,0x49,0x3b,0xa8,0x2e,0x41,0xb3,0x55,0xd1,0xcf +,0xcb,0xb8,0x2e,0xc1,0x54,0x2b,0xa9,0x22,0xb3,0x42,0x40,0xb0,0x23,0xb9,0x32,0xdb,0xbc,0x71,0x32,0xbc,0x40,0x4f,0x27,0xbc,0xcd,0x2b,0xcf,0x69,0xb3,0x1e,0xba,0x49 +,0x37,0x3b,0xbe,0xca,0x56,0x48,0x5f,0xbd,0x30,0x3f,0xbe,0xbc,0x45,0xc2,0xbf,0xbc,0x2f,0xbc,0xc4,0x63,0x6f,0xdf,0xc0,0xdb,0x5d,0x3e,0xbb,0xbb,0x36,0xba,0xce,0x5d +,0xe1,0xe6,0xb7,0x3a,0xa1,0x37,0xc2,0xaf,0x31,0xd2,0xb3,0xca,0x6f,0xcc,0x3f,0xbf,0x67,0x5f,0xb9,0xf1,0x4f,0xb6,0x5c,0xd8,0xd8,0x2e,0xe2,0x3f,0xd3,0xc0,0x30,0x67 +,0x3c,0xcf,0x3d,0xf0,0x40,0xb4,0xbd,0x24,0xaf,0x2f,0x42,0xbe,0x28,0xa8,0x28,0x4d,0xa5,0x1b,0xad,0x78,0xca,0xc7,0x2f,0xaa,0xec,0x45,0x3d,0x45,0x40,0xfa,0xe6,0x3f +,0xc4,0x3b,0x55,0xce,0x2a,0xae,0x33,0xbd,0xb3,0x3e,0xb4,0x58,0xab,0x1f,0xac,0x58,0xe7,0x3c,0x7b,0xc5,0x65,0xf2,0x44,0xa6,0x2e,0xc8,0x36,0xa2,0x33,0x47,0xd0,0xb0 +,0x43,0x2f,0xa6,0xe8,0x29,0xb7,0xb6,0x2e,0xb9,0x4f,0xae,0x2f,0x51,0xba,0xb5,0xb9,0x24,0xdb,0xb3,0xcb,0x1a,0x1d,0x92,0x96,0xc1,0x15,0x13,0xb9,0x9c,0xc2,0x97,0xae +,0x12,0x06,0x16,0x99,0x90,0x93,0xab,0xce,0x1f,0x9c,0x26,0x2a,0x9e,0xa1,0xbb,0x1c,0x2d,0x0f,0x0b,0x24,0x94,0x9d,0x17,0x11,0xf0,0x8d,0x8b,0x3e,0x0e,0x49,0xa0,0xce +,0xa4,0x8c,0x8e,0x2d,0x1d,0x1b,0xab,0xae,0xa7,0xa0,0xbd,0xaa,0x0d,0x01,0x10,0xbd,0x3e,0xb8,0xa0,0xd2,0x25,0x4c,0x99,0x8f,0x96,0xaa,0xf4,0x3b,0xac,0x99,0x2e,0xbf +,0x9c,0x1c,0x0e,0x29,0xb1,0xa7,0x2d,0x29,0x5b,0xdc,0x4f,0x11,0xab,0xb6,0x8d,0x2f,0x0f,0x3e,0x41,0x9a,0xa9,0x8f,0x2f,0x0a,0x0c,0xe9,0x8f,0x99,0x99,0xba,0x4f,0xbd +,0x30,0x1d,0xa5,0x90,0x3e,0xab,0x32,0x11,0x0d,0x10,0xaa,0x96,0xbc,0x2e,0x0f,0xbd,0x8a,0xa0,0x28,0x19,0xb6,0x39,0xc2,0x9c,0x8e,0xa7,0x2c,0x1c,0x34,0xcd,0xbf,0x97 +,0xa8,0x75,0x31,0x0a,0x09,0x1a,0x4c,0xb0,0xa3,0xa0,0x2a,0x5c,0x4a,0x8f,0x96,0x9c,0x9c,0x40,0x23,0xb5,0x5f,0x3b,0x98,0x2f,0x13,0x17,0x26,0xc2,0xc7,0xde,0xd7,0x4f +,0xb3,0x2d,0xf2,0x2f,0x9b,0x97,0x1b,0x1e,0x26,0xbc,0x93,0x9c,0xba,0x21,0x0e,0x10,0xc9,0x90,0x8f,0x96,0x27,0xbd,0x23,0x1c,0xa5,0xae,0xa0,0xa2,0xb3,0x19,0x0a,0x0e +,0x1e,0x9b,0x97,0x38,0x21,0x15,0xb3,0x91,0x5e,0x35,0x48,0x32,0xc2,0x95,0x9f,0x9b,0x40,0xa1,0x5a,0x1d,0xab,0xaf,0x94,0x2c,0xab,0x20,0x04,0x14,0x1e,0x4e,0x95,0xaf +,0xfd,0x14,0x2e,0x9a,0x98,0x8e,0x9c,0x9b,0x1a,0x29,0x2a,0x2d,0xa6,0x9c,0xd1,0x32,0x1b,0x16,0x2c,0xa9,0xb2,0x41,0xa9,0xba,0x32,0x1f,0xb5,0xb6,0xd6,0xcd,0x2f,0x19 +,0xa8,0x96,0x9c,0x38,0x1e,0x1b,0x11,0xa8,0x9a,0x8e,0xac,0xdb,0x42,0x19,0x31,0xa9,0xa4,0x9c,0xa2,0x38,0x1d,0x08,0x14,0xae,0xa9,0xa8,0xaa,0x18,0x27,0x2d,0xae,0x9b +,0x2e,0x43,0x23,0x9b,0xa3,0xac,0xa8,0xb2,0x98,0x26,0x2f,0x48,0xa9,0xad,0xc7,0xcc,0x0e,0x0f,0x11,0x1a,0xa6,0xa5,0xbe,0x2d,0x2b,0xa0,0xaf,0x93,0x8c,0x9a,0xb8,0x26 +,0x23,0x1b,0xbb,0x9f,0xab,0xc7,0x2f,0x15,0x0d,0x5d,0xa3,0xa6,0xa6,0x3c,0xac,0x27,0x21,0x45,0x40,0x97,0x35,0x4c,0x30,0xb7,0x9d,0x5d,0xbe,0x1a,0x1c,0x3b,0xbf,0x92 +,0x91,0xa4,0xd8,0x14,0x3f,0x23,0xbe,0x9b,0x9f,0x97,0x1e,0x12,0x0a,0x1b,0xba,0xa4,0x9c,0xdf,0x1f,0x22,0x2b,0x9a,0xa1,0x3e,0x5d,0xc6,0xa4,0xc6,0xed,0xba,0x9b,0x9f +,0x4e,0x2d,0x37,0xb9,0xbb,0x3c,0x51,0x17,0x0f,0x12,0x55,0x9e,0xbc,0x2b,0x2f,0x3c,0xb2,0x98,0x98,0x90,0xa8,0xc6,0x26,0x18,0x2a,0xb4,0x9f,0x98,0xa9,0x15,0x13,0x16 +,0x3f,0x9f,0xa4,0xab,0xc8,0xde,0x25,0x1c,0x43,0xc9,0xae,0xdc,0x46,0xc8,0xce,0xa9,0x34,0xba,0x6e,0x22,0x30,0xcf,0x9b,0x97,0xd9,0x2b,0x44,0x28,0x48,0xa5,0xa0,0xa6 +,0xbb,0x1e,0x19,0x18,0x24,0xbe,0x98,0xbe,0x3f,0x1d,0x19,0xc3,0x50,0x99,0xcd,0xab,0xb6,0x36,0x7a,0x43,0x97,0x9b,0xa0,0xbc,0xdb,0x2e,0x2d,0x38,0x38,0x27,0x27,0x1c +,0x1d,0xef,0x31,0xb7,0x2d,0x2d,0xa9,0xb6,0x9a,0x9b,0x9a,0xa5,0x3c,0x24,0x1e,0x32,0xbf,0x94,0xa5,0xb0,0x19,0x11,0x20,0x3e,0x9b,0xac,0xa0,0xc0,0xe5,0x1a,0x17,0x39 +,0x69,0xa7,0xb6,0xbf,0xde,0x38,0x48,0x48,0xb2,0xe8,0x2e,0x6c,0x54,0x9f,0xa5,0x59,0xb4,0x36,0xec,0x47,0xbd,0x9a,0x5b,0x68,0x1f,0x27,0x28,0x1e,0xac,0xb5,0xae,0x3d +,0x18,0x26,0x4c,0xbc,0xa2,0xa5,0xbc,0xb6,0x29,0x32,0xaf,0x9c,0x9a,0xa8,0xbf,0x39,0x26,0x22,0x75,0x52,0x3f,0x3d,0x26,0x2a,0x26,0x2a,0x3f,0x2c,0xa4,0xb6,0x9e,0x9c +,0xa0,0x96,0x5e,0x2e,0x1e,0x2a,0x3d,0xc0,0x9f,0xa4,0x3c,0x19,0x17,0x28,0xd0,0xaf,0x9d,0xa7,0xcc,0xe9,0x19,0x25,0x3b,0xae,0xa7,0x4c,0xb8,0x44,0x2e,0x44,0xbb,0xaf +,0xc1,0x2b,0xbc,0xcf,0xba,0xb8,0xd3,0xb4,0x33,0xbc,0xda,0xb3,0xad,0xc9,0x61,0x25,0x23,0x2f,0x2a,0xf3,0xb5,0x31,0x34,0x1e,0x2f,0xc0,0xc0,0x9f,0xac,0xac,0x6b,0x46 +,0xc8,0xba,0x98,0x9d,0xa0,0xcc,0x32,0x34,0x1d,0x32,0x36,0x2d,0x2f,0x23,0x28,0x25,0x26,0x2f,0x47,0xb3,0x9e,0xa1,0x99,0x9f,0xaa,0xb0,0x2e,0x5a,0x23,0x3c,0xa2,0xc6 +,0xbc,0x2c,0x29,0x2c,0x2a,0xa9,0xb8,0xb6,0xb9,0x49,0x42,0x1b,0x32,0xd0,0xd8,0xb7,0xc6,0xd3,0x32,0x35,0xbb,0xc9,0xaf,0xb0,0x4e,0xb5,0x37,0xb9,0x5b,0x3b,0xcd,0xc1 +,0xb2,0xbf,0xae,0xdb,0x55,0x4f,0x3d,0x25,0x43,0x38,0x56,0x49,0x2d,0x2d,0x1e,0x4c,0xc6,0xb5,0xa4,0xb9,0xb9,0x46,0x5a,0xbb,0xac,0x9b,0x9d,0xa3,0xbe,0x2e,0x2c,0x2a +,0x24,0xf3,0x2f,0x32,0x29,0x1e,0x2d,0x1f,0x6b,0xc0,0xc0,0x9f,0xa7,0xa2,0xa5,0xab,0xab,0x2e,0x3c,0x58,0x35,0xb3,0xdd,0x65,0x2b,0x29,0x3d,0x2f,0xbe,0xb7,0xb0,0xbf +,0x39,0x3c,0x2e,0x35,0xc4,0xc8,0xad,0x7d,0x3c,0x54,0x3a,0xae,0xb8,0xbc,0xb8,0x3f,0x69,0x4a,0xea,0xcf,0x4e,0xbb,0xbc,0xc2,0xc8,0xd3,0xf2,0x72,0xea,0x58,0x30,0x3a +,0x44,0x37,0x3b,0x22,0x2e,0x2b,0x3c,0xbd,0xbd,0xa5,0xbf,0xf1,0xbf,0xc2,0xa8,0xa4,0x9e,0x9d,0xb4,0xc6,0x2d,0x29,0x2c,0x2f,0x47,0x2a,0x2a,0x2a,0x1d,0x2e,0x2c,0x3f +,0xbe,0xbd,0xa3,0xac,0xa8,0xa6,0xaf,0xaf,0x4a,0x3d,0xd6,0x5d,0xb8,0x5d,0x60,0x3d,0x2b,0x51,0xce,0xc7,0xbe,0x69,0xe1,0x39,0x2c,0x44,0x3a,0xbd,0x5e,0xda,0x43,0x2f +,0x3d,0x50,0xaf,0xb4,0xb1,0xbe,0x41,0x50,0xca,0xcb,0xc0,0x4c,0xb8,0xb7,0xd5,0xbb,0xe2,0xbf,0xba,0xd4,0x48,0x36,0x3a,0x36,0x2f,0x3b,0x21,0x29,0x31,0x37,0xbe,0x54 +,0xad,0xba,0xee,0xb4,0xbe,0xa4,0x9f,0xa0,0xa5,0xc1,0x6d,0x38,0x2c,0x4a,0x2f,0x33,0x33,0x26,0x27,0x1e,0x33,0x3d,0x4e,0xba,0xc4,0xac,0xae,0xb7,0xa3,0xae,0xb8,0xd5 +,0x4b,0xca,0x48,0xd7,0xe5,0x41,0x56,0x38,0xcd,0xda,0x53,0xd3,0x3e,0xe0,0x3b,0x33,0x52,0x3d,0xc7,0x53,0x45,0x4d,0x32,0xdc,0xbf,0xaf,0xb4,0xce,0xd3,0x3f,0x4a,0xbc +,0xe3,0xc0,0xd1,0xcb,0xbb,0x44,0xc0,0xdf,0xbd,0xaf,0xce,0xdc,0x48,0x2d,0x36,0x2a,0x2e,0x28,0x25,0x48,0x37,0xbb,0xd5,0xc4,0xbd,0x70,0xad,0xad,0xa4,0x9e,0xa7,0xa9 +,0xba,0xdf,0x4b,0x2e,0x3b,0x32,0x31,0x28,0x21,0x2b,0x24,0x2d,0x4e,0x4e,0xbb,0xbe,0xbd,0xae,0xaf,0xa8,0xb8,0xbe,0xb8,0xcd,0xbd,0x4d,0x69,0x68,0x3f,0x53,0x3e,0xd2 +,0x75,0x40,0xd3,0x4e,0x40,0x44,0x34,0x4e,0x50,0x64,0x59,0x44,0x5b,0x49,0xf3,0xb3,0xb8,0xc1,0xc4,0x68,0xcf,0x4d,0x78,0x6a,0xda,0xb8,0xd5,0xc1,0xdb,0xc2,0xbe,0xc2 +,0xb7,0xd9,0x68,0x40,0x35,0x30,0x2b,0x2d,0x2a,0x2c,0x35,0x3e,0x50,0x4d,0xd8,0xc4,0xb8,0xa8,0xa9,0x9f,0x9f,0xa7,0xab,0xc0,0xdb,0x40,0x39,0x3b,0x2d,0x2d,0x2e,0x23 +,0x28,0x2b,0x37,0x3d,0x54,0xc4,0xcb,0xb9,0xb8,0xaf,0xaf,0xb5,0xbc,0xb7,0xca,0xe4,0xe4,0x45,0x6d,0x4b,0xc6,0x70,0xea,0xc4,0x42,0xce,0x4a,0x3c,0x5f,0x3c,0x4f,0x4c +,0x41,0x43,0x3d,0x5a,0x55,0xce,0xcd,0xcb,0xc0,0xd3,0x6f,0xd9,0xd6,0x5c,0xd0,0xcc,0xc3,0xe0,0xcc,0xd3,0xc9,0xbe,0xc0,0xb8,0xc9,0xd1,0x6f,0x3f,0x30,0x30,0x2a,0x2e +,0x2e,0x2b,0x38,0x3a,0x4d,0x79,0xc9,0xb3,0xb1,0xa9,0xa7,0xa9,0xaa,0xad,0xb2,0xbf,0xed,0x53,0x46,0x39,0x2e,0x2b,0x2e,0x2a,0x27,0x2c,0x3e,0x3a,0x4a,0xf4,0xc8,0xbb +,0xbd,0xb8,0xbb,0xb6,0xbb,0xc3,0xbf,0xbf,0xc5,0xc2,0xc5,0xc1,0x41,0x4f,0x4a,0x4a,0x6a,0x46,0x4c,0x3f,0x4e,0x3f,0x3e,0x48,0x57,0x57,0xe6,0xd9,0xda,0xdf,0xcc,0xd4 +,0x5b,0xd2,0xdf,0x7a,0xe4,0xdc,0xec,0x7d,0xd8,0xcc,0xcb,0xbb,0xb2,0xb7,0xba,0xce,0xf7,0x42,0x3a,0x3f,0x35,0x36,0x2f,0x2e,0x2f,0x2f,0x30,0x43,0x73,0xca,0xbc,0xaf +,0xaa,0xa7,0xad,0xaf,0xab,0xb4,0xbe,0x7e,0xdf,0x49,0x3b,0x30,0x30,0x2d,0x37,0x2a,0x3a,0xe6,0x2e,0x3e,0x51,0x56,0xbc,0xc2,0xc8,0xbd,0xb8,0xcf,0xc4,0xd5,0xc8,0xae +,0xe6,0xb3,0xe9,0xc2,0x4a,0x46,0x3d,0xed,0x54,0x38,0x6f,0x35,0xe7,0x34,0x4d,0x3d,0xda,0x3b,0xe4,0xd3,0x56,0xb3,0x3b,0xc7,0xc0,0xbf,0x7e,0x4a,0x6e,0xc5,0xbf,0xbc +,0xd0,0xcd,0xbd,0xcd,0xae,0xbc,0xc1,0x46,0x30,0x3a,0x75,0x35,0x2f,0x2a,0x2d,0x34,0x31,0x48,0x37,0xbb,0xcd,0xbc,0xb0,0xab,0xaa,0xb6,0xaf,0xb1,0xb4,0xca,0xcd,0x60 +,0x53,0x41,0x3d,0x32,0x39,0x38,0x34,0x3c,0x46,0x67,0x3c,0x3f,0xfd,0xc5,0xc4,0xb5,0xbe,0xc2,0xd1,0xc1,0xc0,0xcf,0xce,0xd8,0xc9,0xd0,0xc8,0x44,0x4d,0x5b,0xef,0x42 +,0x46,0x4b,0x36,0xd6,0x42,0x6a,0xcd,0x3f,0xe4,0x4a,0xc4,0xc1,0xee,0x6b,0x4a,0xe1,0xe9,0x62,0x6b,0xcc,0xd0,0xcc,0xe6,0xc2,0xcf,0xbd,0xc3,0xc6,0xb9,0x5c,0x5a,0x3e +,0x41,0x3c,0x3a,0x35,0x31,0x35,0x39,0x40,0x73,0xbf,0xbf,0xc1,0xce,0xb2,0xb5,0xb7,0xb4,0xbc,0xb3,0xcc,0xda,0xef,0x53,0x56,0x3b,0x33,0x37,0x40,0x3c,0x47,0x46,0x3d +,0x54,0x49,0x4c,0xd4,0xcb,0xd7,0xc2,0xc4,0xcb,0xc4,0xd2,0xc2,0xc3,0xc7,0xc7,0xea,0xe3,0x53,0x40,0x6f,0xd2,0x5d,0x40,0x46,0x4e,0x40,0x48,0x64,0xd7,0xda,0xdc,0x7b +,0xc8,0xe9,0x79,0xea,0x6e,0x5c,0x50,0xde,0x5e,0xd8,0x61,0xd9,0x6a,0xd8,0xcb,0xd4,0xbc,0xc5,0xc7,0xcd,0x59,0x3e,0x49,0x4b,0x48,0x3e,0x3b,0x3b,0x33,0x3d,0x59,0xc7 +,0xc8,0xc2,0xbc,0xc4,0xb6,0xc2,0xbc,0xb6,0xc5,0xcf,0xda,0x59,0x46,0x4c,0x50,0x51,0x3a,0x3a,0x3c,0x48,0x52,0x50,0xdd,0x4a,0x56,0x5f,0xd8,0xc1,0xc1,0xc9,0xcd,0xd0 +,0x5c,0xc9,0xc4,0xc7,0xca,0xc9,0xde,0x59,0x4c,0x4c,0x50,0x71,0x59,0x4e,0x47,0x4a,0xfd,0x59,0xd6,0xcf,0x55,0x50,0x6e,0xef,0xd6,0xf5,0xd7,0x4d,0x52,0x57,0x60,0xe1 +,0x74,0xc9,0xeb,0xc9,0xc9,0xc4,0xc6,0xc2,0xc8,0xd1,0xf5,0x4c,0x45,0x40,0x42,0x3a,0x44,0x37,0x3a,0x42,0x45,0xdb,0xd2,0xda,0xcc,0xcd,0xbf,0xbb,0xbd,0xbd,0xbd,0xb8 +,0xc0,0xcf,0xe6,0x5b,0x58,0x64,0x6f,0x4c,0x3b,0x3c,0x38,0x31,0x3e,0x38,0x37,0x3f,0x3d,0x59,0xd2,0xd1,0xcb,0xc7,0xba,0xb1,0xb0,0xae,0xaf,0xb2,0xaf,0xb6,0xc1,0xde +,0x48,0x55,0x3b,0x32,0x29,0x2d,0x39,0x2f,0x2e,0x2f,0x42,0x54,0x40,0x69,0xbc,0xad,0xb2,0xba,0xad,0xb2,0xb4,0xbd,0xbd,0xbd,0xcb,0xcd,0xd0,0x55,0x3f,0x47,0x37,0x2f +,0x2b,0x30,0x37,0x30,0x3f,0x4b,0x65,0xdc,0xdd,0xc2,0xb8,0xab,0xa9,0xad,0xaf,0xbe,0xbe,0xbd,0xca,0x69,0x48,0x4e,0x3a,0x29,0x27,0x29,0x2c,0x33,0x3d,0xf4,0xc8,0xbe +,0xc5,0xbe,0xb4,0xb1,0xb8,0xaf,0xad,0xbf,0xc8,0xee,0x55,0x3a,0x3b,0x43,0x39,0x2e,0x2e,0x3d,0x38,0x40,0x4f,0xd6,0xbc,0xbe,0xb6,0xb7,0xb8,0xba,0xbb,0xb6,0xbf,0xf0 +,0xd6,0xc9,0x4a,0x38,0x3c,0x39,0x2e,0x29,0x2f,0x3b,0x3c,0x47,0x74,0xcc,0xb7,0xb8,0xb0,0xab,0xa9,0xad,0xb3,0xb8,0xbd,0xdc,0x5f,0x5b,0x36,0x32,0x2d,0x2a,0x25,0x23 +,0x2d,0x39,0x3f,0xe3,0xc7,0xb3,0xaf,0xb2,0xaa,0xaa,0xa9,0xac,0xac,0xb1,0x6d,0x55,0x48,0x3b,0x2f,0x35,0x39,0x2e,0x28,0x27,0x2f,0x2e,0x3e,0x5e,0xba,0xaf,0xb4,0xb4 +,0xb2,0xaf,0xad,0xb4,0xb4,0xbe,0xc9,0xbe,0x64,0x3b,0x3c,0x3f,0x36,0x2a,0x26,0x31,0x32,0x3a,0x50,0xf2,0xc0,0xbb,0xbb,0xb1,0xac,0xac,0xb8,0xb8,0xbc,0x59,0xf0,0xf1 +,0x4f,0x39,0x3b,0x3f,0x31,0x2d,0x2d,0x37,0x48,0x6d,0xea,0xc7,0xb2,0xb1,0xb7,0xb4,0xb7,0xbc,0xc9,0xcd,0x60,0x53,0xc8,0x4c,0x39,0x3d,0x4b,0x44,0x2f,0x30,0x38,0x46 +,0x4a,0x77,0xc9,0xba,0xbe,0xc3,0xb4,0xb5,0xb9,0xc4,0xb9,0xc0,0x6f,0x7d,0x4f,0x4c,0x3a,0x3e,0x45,0x3b,0x30,0x29,0x37,0x40,0x4a,0xd7,0xcc,0xb9,0xb2,0xb3,0xaf,0xb6 +,0xb3,0xb7,0xbf,0xe7,0xe4,0xcb,0x5c,0x3b,0x37,0x46,0x36,0x2c,0x29,0x34,0x44,0x41,0x61,0xcf,0xbf,0xbc,0xc4,0xb7,0xb3,0xb6,0xba,0xba,0xba,0xcf,0xbe,0xc9,0x5a,0x48 +,0x52,0x59,0x38,0x2d,0x2a,0x32,0x3a,0x3c,0x3e,0x59,0xc4,0xc9,0xc3,0xbb,0xba,0xbb,0xbc,0xb5,0xc1,0xbc,0xb9,0xca,0x5c,0x4f,0xf4,0x3e,0x32,0x2b,0x33,0x3a,0x38,0x3f +,0x51,0xc4,0xcc,0xc7,0xbd,0xba,0xbc,0xc2,0xbb,0xc1,0xd9,0xc5,0xc3,0x69,0x45,0x4e,0x58,0x3b,0x30,0x2f,0x39,0x40,0x48,0x63,0xda,0xc4,0xc3,0xc2,0xba,0xba,0xc2,0xc4 +,0xbb,0xca,0xcf,0xc6,0xda,0x55,0x45,0x68,0x48,0x33,0x2b,0x2f,0x3f,0x3d,0x41,0x4a,0xcc,0xbb,0xc1,0xbc,0xb2,0xb5,0xbc,0xbe,0xbc,0xce,0xd7,0xd6,0xe2,0x61,0x40,0x4c +,0x36,0x2e,0x2f,0x34,0x3f,0x4a,0xef,0xdf,0xc3,0xc0,0xc6,0xbd,0xbc,0xb7,0xba,0xc2,0xbc,0xd8,0xd2,0xdf,0x56,0x4a,0x4a,0x66,0x39,0x35,0x36,0x35,0x3b,0x3f,0x4f,0x69 +,0xd0,0xbd,0xbc,0xc7,0xce,0xc4,0xc0,0xba,0xbc,0xc4,0xb9,0xbf,0x7e,0x46,0x51,0x45,0x36,0x31,0x36,0x48,0x3f,0x40,0x43,0x63,0xc7,0xcf,0xd9,0xcd,0xbd,0xbf,0xc9,0xbd +,0xc9,0xcc,0xca,0xd7,0xdf,0x4a,0x69,0x5b,0x42,0x3f,0x3f,0x4a,0x4b,0x5c,0x48,0x5e,0xce,0xd3,0xce,0xe6,0xc7,0xce,0xe0,0xc5,0xe0,0xdd,0xbf,0xbc,0xcb,0x4a,0x4d,0x5b +,0x40,0x36,0x33,0x41,0x4b,0x56,0x47,0x50,0xc6,0xcf,0xce,0xce,0xb5,0xb7,0xbc,0xbe,0xc5,0xc9,0xee,0xca,0xfe,0x4f,0x45,0x61,0x4b,0x36,0x2e,0x2e,0x39,0x3e,0x4a,0x6d +,0xd3,0xd8,0xc2,0xc8,0xc2,0xbc,0xbe,0xb3,0xb8,0xc1,0xc3,0xbc,0xc6,0x67,0x4a,0x4c,0x5f,0x3e,0x2d,0x2c,0x30,0x3b,0x3f,0x38,0x56,0xc5,0xca,0xc9,0xc2,0xb8,0xba,0xbc +,0xb4,0xb0,0xba,0xbf,0xbe,0xde,0x51,0x3f,0x46,0x3f,0x32,0x2d,0x2e,0x2f,0x39,0x47,0x41,0xe5,0xc5,0xbd,0xc0,0xc9,0xb5,0xb1,0xb7,0xb6,0xba,0xbb,0xb7,0xcd,0x72,0x40 +,0x3e,0x47,0x34,0x2b,0x2c,0x35,0x36,0x3c,0x3c,0x4c,0xcc,0xc0,0xbb,0xbb,0xb4,0xb2,0xb5,0xb5,0xc3,0xc5,0xcb,0xbe,0xd4,0x42,0x3b,0x3b,0x5e,0x3a,0x2e,0x2d,0x3d,0x4a +,0x3d,0x3f,0xda,0xbf,0xbd,0xbc,0xb9,0xb6,0xbf,0xbb,0xbf,0xbf,0xc8,0xd3,0xf1,0xda,0x3c,0x32,0x50,0x3d,0x2e,0x2e,0x3b,0x3a,0x4f,0x65,0x46,0xc6,0xb5,0xb6,0xb5,0xb6 +,0xb1,0xb7,0xba,0xbc,0x6f,0x55,0xe7,0xd4,0x41,0x2e,0x3e,0x4a,0x34,0x2a,0x2c,0x3a,0x47,0xe2,0xeb,0xca,0xb3,0xbd,0xb3,0xb6,0xaf,0xaf,0xbe,0xae,0xc0,0x41,0x43,0x4b +,0x36,0x21,0x29,0x5a,0x3f,0x2b,0x25,0x3e,0xd0,0xda,0xd3,0xb6,0xa4,0xa7,0xb7,0xad,0xab,0xb6,0xba,0xed,0xcb,0x32,0x32,0x39,0x2a,0x1d,0x30,0x7d,0x31,0x2d,0x2d,0xc7 +,0xc2,0xba,0xb1,0xa3,0x9c,0xa4,0xb9,0xab,0xac,0xb1,0xdf,0x51,0x38,0x1e,0x25,0x1c,0x16,0x2a,0x64,0x34,0x31,0x2d,0xbb,0xa5,0xaa,0xa3,0x9f,0x94,0xa2,0xb3,0xa5,0xae +,0xc7,0x2f,0x35,0x2d,0x15,0x1a,0x1b,0x0e,0x36,0x60,0x3d,0xaf,0xdf,0x94,0x9c,0xa7,0x94,0xa1,0x95,0xae,0xbe,0xa4,0x3b,0xea,0x22,0x1a,0x1b,0x06,0x16,0x0d,0x0f,0x9a +,0x31,0x9f,0xa0,0x99,0x89,0xe2,0x8e,0x97,0xa6,0x9c,0x29,0x9d,0x3c,0x23,0x3f,0x16,0x29,0x05,0x0f,0x1c,0x07,0x93,0xaf,0x9f,0x8e,0xa9,0x85,0x59,0x9d,0x97,0x37,0x9c +,0x1e,0xa4,0xc7,0x22,0xb5,0x17,0x32,0x09,0x0d,0x2a,0x04,0x9c,0xac,0xc1,0x8e,0xae,0x86,0x57,0xb2,0x93,0x38,0x9b,0x2c,0xa7,0xa4,0x1b,0xbb,0x23,0x2c,0x12,0x06,0x37 +,0x03,0xd0,0x96,0x38,0x89,0xc1,0x88,0x9e,0x33,0x97,0x33,0x9a,0x1f,0xc4,0x98,0x22,0xaf,0x20,0x47,0x16,0x05,0x46,0x0a,0x1b,0x8d,0xd5,0x8f,0x9f,0x8e,0x8c,0x18,0x91 +,0xaf,0xb6,0x5f,0xe4,0x96,0x2f,0x7d,0xba,0x33,0x2b,0x07,0x0f,0x12,0x0c,0x89,0xc8,0xa4,0xc1,0x9c,0x86,0x3f,0x3c,0xa7,0x24,0x07,0x0d,0x1c,0x9e,0x3c,0xad,0xe0,0x1a +,0xd0,0xc9,0xab,0x12,0xac,0x93,0xae,0x86,0x9a,0x8c,0x8b,0x2a,0xa1,0x9c,0x1d,0xab,0x86,0x8b,0x93,0x88,0x9e,0x2e,0x0d,0x00,0x06,0x00,0x01,0x0d,0x0a,0x08,0x0e,0x16 +,0xd2,0x00,0x0e,0x5a,0x0e,0x1e,0x11,0x92,0x9b,0x9e,0x88,0xa1,0xae,0x3c,0x36,0xc2,0x0c,0x9b,0x82,0x8b,0x80,0x82,0x80,0x83,0x8f,0x80,0x8d,0x89,0x8b,0x14,0x8f,0x8a +,0x81,0x17,0x13,0x11,0x00,0x08,0x01,0x01,0x0c,0x09,0x09,0x9f,0x27,0x29,0x00,0x0c,0x9a,0x02,0x05,0x03,0xb4,0xb9,0x38,0x8d,0x4b,0x12,0x01,0x16,0x9f,0x47,0x97,0x80 +,0x9a,0x88,0x81,0x80,0x83,0x8b,0x84,0x84,0x91,0x8f,0x86,0x89,0x9e,0xaf,0x8a,0x23,0x14,0x0c,0x0e,0x15,0x00,0x39,0x97,0x6a,0xbe,0x1e,0xa3,0x08,0x0a,0xba,0x06,0x04 +,0x0b,0x0f,0x16,0x08,0x17,0x0c,0x0b,0x0a,0x05,0x1a,0x07,0x16,0x82,0x8c,0x92,0x80,0x88,0x89,0x2b,0x8e,0x83,0xaa,0x87,0x88,0x8c,0x80,0x9b,0x8e,0x8b,0x8d,0xbb,0x1e +,0x9b,0x08,0xa0,0x84,0xc6,0x99,0x89,0x93,0x06,0x0a,0xdf,0x08,0x03,0x0a,0x00,0x15,0x17,0x14,0xcc,0x09,0x03,0x01,0x00,0x08,0x02,0x9b,0x86,0x9d,0x89,0x82,0x8b,0xbf +,0x99,0x88,0x86,0x93,0x92,0x87,0x8a,0x91,0x86,0x84,0xae,0xb6,0x0c,0x11,0x0f,0x17,0x89,0x8f,0xae,0x8c,0x95,0x8d,0x26,0x1a,0x8f,0x09,0x2b,0xd7,0xc7,0xa3,0x0c,0x0e +,0x18,0x10,0x10,0x02,0x03,0x00,0x28,0x8d,0x98,0x9e,0x9e,0x26,0x0b,0xa5,0xb9,0x8b,0xbf,0x14,0xc8,0x8d,0x46,0x07,0x94,0x3e,0x02,0x03,0x00,0x98,0x17,0x04,0xa4,0x05 +,0xbd,0x84,0x8d,0x72,0x07,0x0f,0x1b,0x0a,0x4a,0xbc,0x8c,0x3a,0x1d,0xd3,0x09,0x12,0x0c,0x19,0x16,0x1a,0x11,0xa6,0x40,0x9c,0x80,0xae,0x0d,0x16,0x9f,0x9a,0x8e,0x80 +,0x86,0x82,0x8a,0x86,0x80,0x8c,0x86,0x89,0x8e,0x11,0x1d,0x88,0x80,0x8d,0x8a,0x97,0x88,0x59,0x12,0x97,0x97,0xae,0x12,0x43,0x8f,0x86,0x1a,0x0a,0x0b,0x47,0x06,0x00 +,0x1e,0x00,0x07,0x17,0x25,0x13,0x20,0x51,0x00,0x02,0x08,0x05,0x1c,0xc7,0xa7,0x07,0x07,0x0b,0xdc,0x1d,0x1b,0x1a,0x00,0x12,0x00,0x9d,0x80,0x88,0x8a,0xa2,0x92,0xa7 +,0x92,0x82,0x80,0x80,0x88,0x9d,0x83,0x84,0x8b,0x8e,0x9b,0x8b,0x2e,0x26,0x13,0x02,0x9c,0x80,0x39,0x18,0x2a,0x34,0x23,0x01,0x1e,0x02,0x17,0x1e,0x06,0x2a,0x0b,0x04 +,0x01,0x0a,0x04,0x00,0x01,0x16,0x09,0x0f,0x86,0x80,0x84,0x80,0x8f,0x21,0x9d,0x84,0x80,0x81,0x80,0x8a,0x86,0x84,0x83,0x80,0x66,0xac,0x18,0x1f,0x8f,0x19,0xab,0x86 +,0xa4,0x1b,0xac,0x28,0x03,0x00,0x08,0x13,0x0c,0x1e,0x05,0x03,0x0a,0x04,0x01,0x00,0x08,0x0b,0x00,0x03,0x00,0x0a,0x98,0x0f,0x13,0xa5,0x70,0x12,0x00,0xc5,0x93,0xb1 +,0x90,0x9f,0x9c,0x8f,0x8c,0x9d,0x8c,0xb4,0x9f,0x9d,0x94,0x88,0x8e,0x80,0x80,0x82,0x80,0x87,0x84,0x8c,0x8c,0x84,0x92,0x81,0x8c,0xb7,0x1e,0xac,0x98,0x1e,0x12,0x2f +,0x04,0x0c,0x1d,0x3e,0x86,0xc3,0xc8,0xa5,0x1d,0x07,0x04,0x04,0x28,0x15,0x14,0x19,0x09,0x0d,0x05,0x0c,0x06,0x04,0x0b,0x19,0x0e,0x03,0x0a,0x80,0x93,0x15,0x88,0xbc +,0xc7,0x0c,0x0e,0x96,0xaa,0x9c,0x8b,0x98,0x9e,0x28,0x94,0x94,0x95,0x85,0x4b,0x9a,0x9c,0x13,0x8c,0x80,0xa4,0x81,0xaf,0x21,0x0b,0x02,0x90,0x4e,0x12,0x21,0x2f,0xbe +,0x12,0x1b,0x12,0x0d,0x0f,0x01,0x06,0x0b,0x05,0x2c,0x8b,0x0e,0x25,0xa5,0x0d,0x10,0x13,0x8f,0x95,0x9c,0x82,0x88,0x82,0x84,0x83,0x80,0x84,0x89,0x86,0x90,0x87,0x88 +,0x83,0x80,0x8e,0x85,0x8b,0x8d,0x47,0x08,0xef,0x70,0x12,0x57,0x23,0x1f,0x12,0x03,0x0d,0x0b,0x00,0x03,0x00,0x05,0x00,0x0f,0xf7,0x09,0x09,0x0b,0x06,0x02,0x00,0x07 +,0x26,0x15,0x70,0x3c,0xc6,0x1d,0x3d,0x40,0x1d,0x4b,0x53,0x15,0xc7,0xc5,0xb0,0x80,0x9b,0x87,0x80,0x85,0x8d,0x36,0x8c,0x80,0x82,0x80,0x82,0x83,0x89,0x94,0x89,0x85 +,0xd6,0xa0,0x2b,0x1e,0xd6,0x16,0x82,0x91,0xc2,0x8e,0x14,0x29,0x03,0x0c,0xa4,0x03,0x2f,0xa9,0x1e,0x0c,0x05,0x0b,0x0b,0x0c,0x0a,0x04,0x0b,0x0f,0x0e,0x86,0x96,0x2f +,0xa2,0xb5,0xe9,0x0f,0x19,0x98,0x4c,0xb6,0x88,0x9d,0xb9,0x2e,0x46,0x44,0x27,0x29,0x16,0x17,0x49,0x0b,0x89,0x89,0xa8,0xae,0x1d,0xca,0x0a,0x11,0xb2,0xab,0x48,0xab +,0x28,0x51,0x18,0x38,0xbd,0x0e,0xae,0x1e,0x0a,0xa0,0x1b,0x8f,0x82,0xb2,0x8c,0xa9,0x29,0x15,0x00,0x9b,0xb1,0x11,0x96,0x24,0x34,0x30,0x61,0x31,0x1f,0x26,0x9b,0x36 +,0xe7,0x4b,0x96,0x80,0x8b,0x83,0x84,0x95,0x9e,0x90,0x95,0x80,0x8a,0x84,0x81,0x88,0x8d,0x9d,0xb5,0xac,0xa2,0x1a,0x05,0x08,0x00,0x16,0x8b,0x05,0x0c,0x18,0x05,0x00 +,0x00,0x05,0x03,0x04,0x17,0x0e,0x03,0x0a,0x03,0x0e,0x0c,0x02,0x06,0x04,0x05,0x07,0x2a,0x80,0xe4,0xa9,0x88,0xce,0x29,0x2b,0x9a,0x84,0x97,0x87,0x80,0x89,0x88,0x8e +,0x80,0x95,0x96,0xb0,0xe8,0xb2,0xf9,0x95,0x80,0x9d,0x9f,0x88,0x23,0xa8,0x0d,0x26,0x8c,0xda,0xaa,0x9d,0x8a,0x9c,0x12,0x8f,0x2f,0x14,0x59,0x0d,0x0c,0x1d,0x18,0x8a +,0x96,0x1f,0x89,0x3d,0x18,0x0b,0x0f,0x94,0x35,0xa6,0x86,0xba,0x1b,0x2e,0x9f,0x14,0x0c,0x1b,0x08,0x03,0x06,0x07,0x8e,0xca,0x07,0x9f,0x11,0x0b,0x03,0x0b,0x9c,0x4b +,0x4e,0xa1,0xb9,0xb3,0x1c,0x1d,0xc6,0x0e,0x13,0x0e,0x0f,0x2f,0x0b,0x89,0x8b,0x31,0x82,0x8f,0xab,0xda,0x27,0x84,0x91,0x9c,0x84,0x92,0x9d,0xc6,0xe4,0x19,0x24,0x16 +,0x17,0x06,0x0d,0x0e,0x8c,0x86,0x54,0x82,0xb4,0x38,0xbf,0x1c,0x9b,0x87,0x94,0x80,0x8e,0x8b,0x95,0x94,0x83,0x98,0x94,0x97,0xca,0xb9,0x9f,0x86,0x83,0x9e,0x8b,0x8b +,0x1a,0x0f,0x0d,0x1b,0xc8,0x00,0x3e,0x0f,0x05,0x0a,0x01,0x0b,0x09,0x00,0x03,0x01,0x07,0x01,0x0f,0x88,0x08,0x1a,0x26,0x0c,0x07,0x00,0x10,0x35,0x0d,0x3d,0xc5,0x2e +,0xb4,0x27,0xb4,0xba,0x15,0xb0,0x1f,0x3e,0xc5,0x59,0x80,0x9b,0x8d,0x89,0x94,0xb5,0x18,0x44,0x86,0x9e,0x8c,0x82,0x8a,0x8a,0xa1,0x8d,0x8c,0x97,0x9c,0x94,0x56,0xaa +,0x9b,0x80,0x8e,0x93,0x80,0x9c,0x21,0x0c,0x0e,0x8e,0x4d,0x58,0x8a,0x26,0xa7,0x1a,0x23,0x4c,0x12,0x0d,0x0c,0x09,0x09,0x07,0x89,0x91,0x0c,0xaa,0x19,0x05,0x05,0x00 +,0x40,0x24,0x0f,0x95,0x28,0xd9,0x28,0x1b,0x2c,0x13,0x09,0x0f,0x05,0x0b,0x0a,0x9d,0x85,0x0f,0xaf,0xcb,0x12,0x0d,0x06,0xba,0x97,0x42,0x88,0x8d,0x8b,0x92,0x9f,0x96 +,0xc6,0x3e,0xb4,0x1a,0x4b,0xcf,0x97,0x80,0xec,0x8f,0x8d,0x4e,0x1e,0x0a,0x31,0x9a,0x27,0x93,0x8b,0xad,0xb6,0x39,0x33,0x1f,0x0f,0x1b,0x12,0x12,0x19,0xaa,0x80,0x90 +,0x8b,0x81,0x8a,0x95,0xac,0x96,0x80,0x88,0x84,0x80,0x85,0x87,0x8e,0x9f,0xbf,0x1c,0x0e,0x07,0x00,0x04,0x03,0x97,0x15,0x05,0x25,0x03,0x01,0x01,0x00,0x12,0x04,0x07 +,0x2d,0x0d,0x0a,0x09,0x05,0x06,0x02,0x03,0x05,0x03,0x07,0x07,0x89,0x8f,0x2b,0x89,0x96,0xb8,0x3d,0x19,0x89,0x93,0x9d,0x81,0x8d,0x8c,0xa3,0xa9,0x9a,0xc4,0xab,0xc1 +,0x3d,0xa8,0xd5,0x82,0x82,0x8e,0x80,0x88,0x94,0x9d,0x31,0x86,0x90,0xa7,0x83,0x94,0x95,0xaf,0xab,0xab,0x1a,0x21,0x20,0x0d,0x2f,0x0f,0x89,0x8a,0x19,0x92,0xc5,0x1b +,0x13,0x00,0x28,0x1b,0x08,0xb7,0x2e,0x43,0x15,0x14,0x19,0x06,0x07,0x0d,0x06,0x10,0x00,0x9e,0x8a,0x0a,0x9d,0x3c,0x16,0x0b,0x00,0x32,0x1e,0x0b,0x9b,0xab,0xb3,0x48 +,0x3a,0xa9,0x19,0x2c,0x3d,0x19,0x29,0x0f,0x8c,0x82,0xbe,0x86,0x8b,0x9d,0xc3,0x0e,0x90,0x9a,0x3a,0x87,0x91,0x92,0x9b,0xa6,0x8f,0xb0,0x21,0x3c,0x15,0x1f,0x0a,0x96 +,0x81,0x42,0x8c,0x8b,0xa2,0x3b,0x0b,0x96,0x9a,0x12,0x93,0x9d,0x98,0x95,0x99,0x88,0xac,0x28,0xaf,0x24,0x29,0x1b,0x8c,0x80,0xa0,0x84,0x89,0xab,0x2e,0x08,0xc3,0x1e +,0x04,0xbe,0x24,0x37,0x24,0x0d,0x1d,0x09,0x03,0x06,0x00,0x08,0x00,0xa2,0x88,0x1f,0x9b,0xb8,0x37,0x19,0x05,0x9f,0xb5,0x2d,0x8d,0x8e,0x8f,0xbe,0x3b,0x9a,0x1e,0x0b +,0x0d,0x0b,0x15,0x05,0x8d,0x8e,0x1e,0x9a,0xa4,0xb2,0x15,0x10,0x93,0xab,0xc2,0x8c,0x90,0x90,0xaa,0xa4,0x9b,0x39,0x20,0x21,0x27,0x3f,0x16,0x8a,0x8c,0xb2,0x92,0xac +,0xa2,0x10,0x0e,0xa0,0xb1,0xcb,0xa6,0x97,0x8f,0xb7,0xac,0x93,0x9f,0xc5,0xdb,0x9d,0x3f,0x16,0x87,0x8d,0xbd,0x9f,0xa0,0x94,0x0f,0x14,0xa2,0x18,0x12,0x13,0x42,0x2c +,0x11,0x25,0x41,0x23,0x0e,0x0c,0x10,0x05,0x04,0x9b,0xa6,0xb5,0x9b,0x90,0x89,0x1a,0x1f,0xb8,0x11,0x14,0x0e,0x4b,0x25,0x18,0x36,0x26,0x1b,0x06,0x08,0x0d,0x01,0x0a +,0x98,0x9b,0x99,0x9a,0x8a,0x89,0x27,0xc0,0xa7,0x48,0x55,0x4f,0x8b,0x92,0x8f,0x8e,0x97,0x9d,0x19,0x1b,0x43,0x0f,0x39,0x8b,0x92,0x89,0x95,0x89,0x8b,0x2a,0x9e,0x8f +,0x93,0x95,0x96,0x80,0x8b,0x8c,0x92,0x91,0xac,0x13,0x25,0x35,0x0d,0x2b,0x94,0xbf,0xa0,0x23,0xbd,0x2c,0x07,0x1c,0x1b,0x1b,0x1c,0x15,0x44,0x16,0x20,0x1c,0x22,0x2a +,0x11,0x30,0xa5,0xbc,0x95,0x8a,0x98,0x8e,0xb7,0x9b,0xaa,0x15,0x1c,0x27,0x16,0x04,0x02,0x05,0x04,0x02,0x01,0x09,0x07,0x03,0x07,0x09,0x02,0x14,0xd2,0x78,0xa8,0xad +,0x8a,0x90,0x9f,0x8b,0x8e,0x91,0xa3,0x93,0x8d,0x98,0x8d,0x89,0x85,0x91,0xa6,0xb3,0xac,0x49,0x93,0x87,0x8b,0x84,0x86,0x81,0x84,0x88,0x87,0x87,0x8b,0x96,0x96,0x95 +,0x9d,0x9e,0x9f,0x9a,0x26,0x0b,0x09,0x08,0x02,0x08,0x0c,0x0d,0x0d,0x0e,0x21,0x0a,0x03,0x09,0x0e,0x0e,0x07,0x14,0x2e,0xa8,0x8f,0x87,0x85,0x8e,0x8f,0x91,0x9c,0x53 +,0x98,0x8b,0x90,0x9f,0xbb,0x44,0x0d,0x09,0x09,0x05,0x04,0x04,0x0d,0x0a,0x0c,0x15,0x12,0x16,0x08,0x0c,0x0b,0x0e,0x0f,0x27,0xac,0x9f,0x9e,0xa0,0x97,0xb1,0xae,0xa4 +,0x9b,0x98,0x9d,0x95,0x97,0xac,0xc1,0xb7,0x9e,0xc7,0x6d,0xb4,0x9c,0xa6,0x98,0x85,0x89,0x8b,0x8c,0x87,0x8d,0x94,0x8d,0x8d,0x8d,0x94,0x9a,0xae,0x2b,0x1f,0x16,0x1a +,0x0d,0x0a,0x0c,0x0f,0x0f,0x03,0x0b,0x0f,0x11,0x0c,0x15,0x44,0xa6,0x91,0x8a,0x83,0x83,0x84,0x83,0x89,0x8c,0x8e,0x88,0x8c,0xa4,0xcd,0x1c,0x0f,0x03,0x01,0x03,0x02 +,0x06,0x03,0x04,0x0d,0x0a,0x0c,0x0b,0x11,0x0f,0x0d,0x1c,0x1c,0x3f,0x7d,0xc1,0x4b,0x2e,0x2a,0x18,0x1b,0x28,0x37,0xd6,0x9a,0x8f,0xaa,0xae,0xa9,0xa9,0xb0,0xa2,0x90 +,0x92,0x92,0x8b,0x8a,0x8c,0x8d,0x93,0x8e,0x96,0x97,0x92,0x91,0x8e,0x8d,0x94,0xa2,0xb0,0xc3,0x54,0x2e,0x3a,0x45,0x2a,0x24,0x33,0x1e,0x18,0x12,0x1c,0x1e,0x15,0x1b +,0x26,0x6e,0x9d,0x93,0x97,0x8e,0x8a,0x88,0x88,0x8a,0x88,0x87,0x88,0x88,0x97,0xb3,0x31,0x19,0x12,0x08,0x07,0x08,0x06,0x05,0x06,0x07,0x05,0x06,0x0b,0x0d,0x09,0x0e +,0x18,0x1e,0x20,0x2d,0x27,0x14,0x13,0x15,0x19,0x18,0x24,0xec,0xc3,0xac,0xa3,0xa1,0xb1,0x67,0xce,0xb6,0xbf,0xa9,0x9b,0x96,0x8e,0x8c,0x8e,0x92,0x9a,0x99,0xa1,0x9f +,0x94,0x8f,0x90,0x8d,0x8e,0x9d,0xae,0xb8,0xac,0x54,0xdb,0x46,0x43,0xd4,0xd1,0x4a,0x1e,0x1a,0x1f,0x16,0x0e,0x0e,0x18,0x7b,0xa9,0x95,0x9c,0x99,0x8e,0x89,0x8a,0x8c +,0x88,0x86,0x86,0x87,0x89,0x92,0x9b,0x37,0x1e,0x0f,0x06,0x05,0x05,0x06,0x09,0x0c,0x07,0x06,0x0a,0x0f,0x09,0x0b,0x15,0x17,0x1b,0x4a,0xde,0x23,0x23,0x26,0x22,0x19 +,0x1f,0x37,0x5b,0x41,0xa1,0x9b,0xad,0xc7,0xc0,0xb1,0x4c,0xc2,0xa0,0x96,0x97,0x8f,0x91,0x94,0x9a,0x9e,0x9d,0x9e,0x9d,0x9a,0x91,0x96,0x98,0xa0,0xa8,0xa2,0xa9,0x7d +,0x53,0xe9,0xb3,0xbf,0xd0,0x4b,0x2a,0x20,0x21,0x1d,0x0f,0x13,0x22,0xcc,0xab,0x99,0x9e,0x9a,0x91,0x8d,0x8c,0x8b,0x87,0x82,0x87,0x89,0x87,0x8f,0x9d,0x46,0x26,0x11 +,0x0a,0x0a,0x0c,0x0b,0x08,0x08,0x06,0x04,0x04,0x05,0x08,0x0c,0x0e,0x15,0x21,0x2b,0x26,0x1b,0x1d,0x20,0x16,0x23,0x42,0xd8,0xb5,0xaf,0xa7,0xc4,0x4b,0x6d,0x25,0x2b +,0xcf,0xaf,0xa2,0x98,0x95,0x98,0x9e,0x9e,0xad,0xb4,0x98,0x91,0x91,0x8f,0x8b,0x8e,0x96,0x9d,0xad,0xb7,0xa4,0xb2,0xc5,0xb8,0xaa,0xcd,0x1e,0x15,0x12,0x10,0x11,0x16 +,0x11,0x12,0x25,0x5c,0x30,0x3f,0xb8,0xa1,0x9e,0x96,0x8b,0x86,0x84,0x84,0x84,0x85,0x88,0x8b,0x90,0x9e,0xae,0x3f,0x28,0x1a,0x13,0x0b,0x05,0x07,0x08,0x03,0x04,0x05 +,0x09,0x0d,0x12,0x16,0x11,0x11,0x18,0x1c,0x19,0x1d,0x31,0x3f,0x5f,0xa3,0xbc,0xcf,0x6f,0xbd,0xc1,0xc5,0xa6,0xaa,0xa8,0xa0,0x98,0xa7,0xc2,0xaa,0xae,0xb3,0xa4,0x9a +,0x93,0x93,0x8f,0x8f,0x96,0x99,0xa4,0xa8,0x98,0x91,0x94,0x98,0x94,0x9f,0xd0,0x3d,0x1d,0x12,0x15,0x1f,0x1f,0x15,0x1b,0x1d,0x14,0x13,0x13,0x1d,0x2e,0xbd,0x95,0x8c +,0x86,0x83,0x84,0x84,0x87,0x8c,0x91,0x8d,0x8c,0x8f,0x94,0x9b,0x3f,0x1a,0x0e,0x08,0x05,0x03,0x07,0x05,0x03,0x0a,0x0e,0x0c,0x0b,0x0b,0x0e,0x0a,0x0e,0x19,0x1b,0x26 +,0xc6,0xb3,0x4d,0x39,0xc5,0xf0,0x3f,0xd3,0xb4,0xa2,0xa0,0x9e,0xa4,0xaa,0xb2,0xad,0xc1,0xb4,0xb9,0xae,0x9f,0x96,0x97,0xa4,0x97,0x94,0x9c,0xac,0x9e,0x97,0x96,0x95 +,0x92,0x9e,0xb9,0xa7,0xb1,0x37,0x38,0x47,0x64,0x34,0x22,0x1a,0x0f,0x10,0x0e,0x0d,0x13,0x23,0x40,0xac,0x9a,0x95,0x94,0x8e,0x89,0x8b,0x87,0x85,0x84,0x84,0x86,0x88 +,0x95,0xb5,0x37,0x19,0x0d,0x09,0x0c,0x0a,0x07,0x08,0x09,0x06,0x03,0x05,0x06,0x07,0x0a,0x10,0x18,0x28,0x34,0x30,0x2e,0x20,0x20,0x24,0x2f,0x4c,0xb2,0xa3,0x99,0x9f +,0xaf,0xae,0xae,0xdd,0x47,0xbb,0xa1,0xb5,0xab,0x94,0x95,0x9a,0x9f,0x9b,0xa6,0xa5,0x9e,0x97,0x97,0x8d,0x88,0x90,0x9c,0xa8,0x9e,0xa9,0xc5,0x43,0x53,0x4c,0x56,0x37 +,0x1e,0x17,0x17,0x16,0x0d,0x0c,0x0f,0x1f,0x39,0xab,0x9d,0x98,0x97,0x90,0x8c,0x88,0x86,0x86,0x84,0x85,0x84,0x8b,0x93,0x9a,0xbe,0x24,0x17,0x0e,0x0b,0x06,0x08,0x09 +,0x05,0x06,0x06,0x05,0x04,0x06,0x0d,0x12,0x12,0x1d,0x20,0x1d,0x18,0x1c,0x23,0x23,0x3d,0xb7,0xae,0xa6,0xab,0xb2,0xae,0xbb,0xba,0xa9,0x9f,0x9a,0x99,0x94,0x94,0x96 +,0x9c,0xa2,0xa4,0xa9,0x9f,0x96,0x94,0x91,0x8e,0x95,0x99,0xb2,0xd9,0xbc,0xdc,0xaf,0xa9,0xa9,0xa8,0xc8,0x67,0x44,0x29,0x29,0x24,0x2f,0x2f,0x30,0xc9,0xe8,0x4b,0x50 +,0x37,0x30,0x1f,0x27,0x36,0x30,0xf3,0xb1,0xb1,0x55,0x3d,0x4c,0x34,0x2f,0x2c,0x2f,0x3e,0x31,0x36,0x3d,0x2b,0x24,0x29,0x21,0x1e,0x18,0x1c,0x22,0x28,0x2e,0x3d,0x3d +,0x2c,0x30,0x34,0x44,0x47,0xd1,0xb2,0xac,0xaf,0xc3,0xc4,0xb3,0xbf,0xb6,0xb0,0xae,0xba,0xbf,0xa7,0xa8,0xa7,0x9e,0x9b,0x9d,0xa2,0x9f,0x99,0x9d,0x9c,0x9a,0x9d,0x9f +,0xaf,0xaf,0xb2,0xd1,0xe1,0x5f,0x68,0x34,0x27,0x2b,0x24,0x21,0x25,0x21,0x21,0x21,0x1e,0x20,0x20,0x23,0x22,0x25,0x2b,0x23,0x2a,0x2f,0x2f,0x3d,0x4b,0x62,0x3c,0x30 +,0x62,0x5f,0x54,0x5e,0x76,0x65,0x43,0x3b,0x39,0x36,0x2c,0x27,0x23,0x25,0x1d,0x1e,0x27,0x28,0x2c,0x34,0x3f,0x31,0x2f,0xec,0xc4,0xb3,0xa7,0x9e,0x9e,0xa6,0xa9,0xa7 +,0xa0,0x9e,0x9e,0x9b,0x9a,0x9d,0x9b,0x96,0x96,0x96,0x90,0x8f,0x95,0x94,0x90,0x91,0x92,0x96,0x98,0x9a,0xa6,0xaf,0xb0,0xad,0xd2,0x39,0x3b,0x2d,0x28,0x20,0x22,0x1f +,0x1f,0x20,0x24,0x20,0x1c,0x1d,0x20,0x22,0x1b,0x1b,0x21,0x1e,0x10,0x0e,0x1a,0x21,0x10,0x22,0x22,0x1d,0x46,0x92,0xaf,0x00,0xaf,0x8f,0x6e,0x8b,0x1c,0x0b,0x0a,0x43 +,0x2c,0x16,0x1c,0x00,0x11,0x03,0x02,0x05,0x00,0x03,0x00,0x02,0x01,0x03,0x00,0x09,0xb3,0x8b,0xeb,0x3d,0x91,0x84,0x88,0x8d,0x82,0x88,0x81,0x80,0x80,0x83,0x83,0x80 +,0x81,0x85,0x85,0x85,0x88,0x82,0x80,0x81,0x89,0x8b,0x85,0x81,0x81,0x80,0x81,0x83,0x8a,0x9c,0x93,0x8f,0x9a,0x9f,0xc8,0xc8,0x19,0x03,0x02,0x09,0x0b,0x03,0x01,0x02 +,0x04,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x01,0x00,0x03,0x0c,0x0c,0x0b,0x12,0x37,0x4a,0x35,0xbf,0xa8,0x9a +,0xa0,0x97,0x8a,0x8f,0xa5,0xa1,0x87,0x80,0x80,0x82,0x81,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x80,0x80,0x83,0x84,0x81,0x81,0x84,0x8e +,0x8c,0x83,0x81,0x80,0x80,0x80,0x82,0x8c,0x8e,0x87,0x8a,0x91,0x9e,0xa9,0x48,0x0d,0x03,0x04,0x0d,0x0d,0x03,0x02,0x02,0x03,0x01,0x00,0x00,0x02,0x02,0x00,0x00,0x00 +,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x08,0x06,0x06,0x05,0x07,0x07,0x06,0x05,0x05,0x07,0x08,0x05,0x03,0x00,0x00,0x02,0x29,0x8e,0xa4 +,0x24,0x1c,0x38,0xaf,0xc8,0xcf,0x9b,0x8b,0x88,0x8a,0x8e,0x9d,0xa8,0x9e,0x8c,0x88,0x89,0x89,0x86,0x82,0x82,0x82,0x83,0x82,0x81,0x80,0x80,0x80,0x80,0x82,0x83,0x81 +,0x80,0x81,0x81,0x81,0x81,0x85,0x8b,0x8f,0x8b,0x85,0x84,0x85,0x89,0x8c,0x9a,0xaa,0x9c,0x94,0x9a,0xb6,0xd5,0xc4,0x4a,0x39,0x58,0x24,0x12,0x0e,0x12,0x13,0x1d,0x29 +,0x20,0x29,0xc1,0x9b,0x8e,0x8e,0x97,0x92,0x90,0x92,0x90,0x8d,0x8b,0x8c,0x94,0x9b,0xc4,0x1f,0x1f,0xc7,0x8d,0x87,0x8e,0xa5,0xad,0xa3,0x93,0x8d,0x8c,0x8b,0x87,0x88 +,0x8e,0x9b,0x54,0x28,0x1f,0x1c,0x0e,0x06,0x02,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x04,0x0a,0x0a,0x05,0x04,0x05,0x09,0x0f,0x0c,0x07,0x07,0x06,0x06,0x06,0x0c,0x14,0x1c,0x57,0x9f,0x92,0x8c,0x8a,0x87,0x85,0x85 +,0x83,0x82,0x81,0x81,0x81,0x81,0x84,0x88,0x89,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x86,0x88,0x85,0x85,0x87,0x8c,0x91 +,0x8b,0x86,0x87,0x89,0x8e,0x8e,0x84,0x80,0x80,0x80,0x81,0x83,0x82,0x81,0x81,0x81,0x84,0x87,0x8b,0x8d,0x9b,0xb0,0xae,0xa5,0xbb,0x16,0x06,0x02,0x02,0x03,0x06,0x04 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x05,0x04,0x05,0x04,0x08,0x09,0x06,0x0a,0x0a,0x0e,0x0d,0x05,0x05,0x02,0x03 +,0x06,0x13,0xba,0xbc,0xcf,0x4b,0x35,0xb1,0x9f,0x92,0x88,0x87,0x85,0x88,0x8a,0x8d,0x8b,0x83,0x86,0x85,0x88,0x8f,0x95,0x94,0x8a,0x8b,0x91,0x96,0x98,0x8a,0x89,0x87 +,0x8a,0x90,0x8f,0x8f,0x8f,0x99,0xa5,0xbd,0x27,0x1d,0x1c,0x14,0x19,0x27,0xd4,0x2b,0x16,0x0f,0x12,0x27,0xb8,0x8f,0x99,0xb1,0x3c,0x30,0x3e,0x24,0x3c,0x74,0x7d,0x23 +,0x0d,0x0a,0x0f,0x0f,0x1a,0x28,0x43,0x7b,0x2e,0x3c,0x44,0x54,0x26,0x21,0x22,0x1d,0x17,0x1b,0x11,0x0b,0x08,0x07,0x06,0x15,0x99,0x8f,0x8a,0x8f,0x90,0x9b,0x9e,0x92 +,0x8e,0x88,0x8c,0x96,0x94,0x9a,0xb2,0xc8,0xc5,0xb7,0x31,0x1b,0x18,0x1b,0x29,0xd4,0xa4,0x98,0x97,0x8e,0x89,0x86,0x83,0x82,0x82,0x82,0x80,0x80,0x81,0x81,0x82,0x82 +,0x89,0x99,0x92,0x8b,0x8b,0x8f,0x9f,0xa7,0x2f,0x1a,0x1b,0x1a,0x1e,0x0c,0x04,0x03,0x02,0x02,0x02,0x03,0x04,0x01,0x01,0x00,0x00,0x00,0x02,0x01,0x0c,0x2f,0x28,0x2d +,0x2d,0xa8,0xaf,0x28,0xbf,0xa8,0x9e,0x9a,0xb5,0xb1,0xe7,0x1f,0x1a,0x1d,0xe4,0x9d,0x9a,0x91,0x94,0x9c,0x97,0x9d,0x8e,0x89,0x89,0x8d,0x93,0x91,0x92,0x9b,0x8c,0x85 +,0x89,0x8f,0xc4,0xb8,0xa4,0xb4,0xad,0xac,0xa3,0xa1,0xc3,0xad,0xa0,0x9f,0xae,0xc5,0xb4,0xb3,0x44,0x21,0x19,0x11,0x0e,0x07,0x05,0x07,0x0e,0x13,0x0d,0x0a,0x0d,0x0b +,0x0f,0xba,0xa9,0xc8,0x1f,0x15,0x1b,0x18,0x15,0x1e,0x29,0x56,0x23,0x0f,0x10,0x0e,0x18,0x22,0x2d,0xc2,0xaf,0xaf,0xa4,0xa6,0xa8,0xb5,0x3c,0x35,0x52,0xc5,0x7a,0x1d +,0x1d,0x10,0x0e,0xd6,0xa2,0x98,0x95,0x8f,0x87,0x8e,0x95,0x91,0x8c,0x86,0x8f,0x9e,0xa6,0xb6,0x3f,0x20,0x22,0x21,0x16,0x0e,0x09,0x07,0x0b,0x0e,0x17,0x18,0x1d,0x39 +,0xc4,0xa0,0x8f,0x94,0x8b,0x81,0x81,0x80,0x82,0x84,0x83,0x85,0x8d,0x91,0x8f,0x88,0x8d,0x93,0x95,0xa2,0xbe,0x3c,0x34,0x2d,0x1e,0x12,0x0a,0x04,0x03,0x02,0x01,0x01 +,0x00,0x01,0x01,0x01,0x01,0x00,0x01,0x0a,0x12,0x23,0x2b,0x29,0xdd,0xe7,0x52,0xc3,0xbb,0x9f,0x9e,0xa9,0xad,0x38,0x38,0x39,0x31,0x3e,0x49,0xc3,0xa4,0x9f,0x98,0x8c +,0x89,0x8c,0x8f,0x8d,0x8c,0x8f,0x93,0x95,0x9b,0x8e,0x88,0x87,0x89,0x90,0x92,0x92,0x9d,0x9d,0x97,0x8d,0x86,0x8e,0x99,0x9c,0xa6,0xa3,0xab,0xbf,0xb3,0x60,0x3e,0x1f +,0x10,0x11,0x11,0x0f,0x0d,0x07,0x0a,0x0b,0x0e,0x1c,0x0d,0x22,0xd0,0xcf,0xac,0x28,0x1e,0x1e,0x14,0x15,0x0b,0x0c,0x1a,0x19,0x1e,0x1a,0x11,0x12,0x16,0x20,0xf4,0xda +,0xbe,0xb7,0xb0,0xae,0xbb,0xb2,0xaf,0xe3,0x30,0x27,0x16,0x1a,0x1d,0x19,0xeb,0xa6,0x9d,0x9b,0xa9,0x95,0x8c,0x8b,0x8a,0x8e,0x8d,0x86,0x89,0x8d,0x9b,0xac,0xc6,0x26 +,0x27,0x1f,0x1b,0x21,0x1a,0x17,0x18,0x14,0x1e,0x3c,0x36,0x33,0x3c,0x4a,0xa4,0x9f,0x8f,0x83,0x83,0x81,0x84,0x88,0x87,0x86,0x85,0x88,0x8b,0x8a,0x8a,0x8b,0x8b,0x95 +,0xa4,0xcc,0x36,0x2d,0x1d,0x18,0x10,0x0b,0x08,0x04,0x02,0x01,0x01,0x01,0x01,0x01,0x00,0x02,0x01,0x07,0x13,0x21,0x24,0x15,0x17,0x1c,0x27,0x41,0x39,0x70,0xaf,0xb7 +,0xdf,0x3c,0x45,0x5e,0x69,0xbf,0xc8,0xbc,0xad,0xa0,0x96,0x8f,0x93,0x8f,0x8d,0x8d,0x8e,0x91,0x96,0x94,0x93,0x9a,0x8a,0x85,0x84,0x85,0x8c,0x90,0x94,0x94,0x8f,0x8c +,0x8d,0x8f,0x92,0x96,0xa5,0xbf,0xc8,0xcf,0xc5,0x65,0x31,0x28,0x1f,0x24,0x26,0x1a,0x19,0x16,0x13,0x11,0x0e,0x11,0x0f,0x0f,0x0c,0x1d,0x42,0x4a,0x42,0x1c,0x19,0x10 +,0x0a,0x0d,0x0e,0x15,0x1f,0x1e,0x1e,0x1a,0x14,0x18,0x2b,0x37,0x2c,0x39,0x53,0xdb,0xbe,0xca,0xc2,0xbf,0xef,0x2e,0x25,0x21,0x2b,0x2a,0x4a,0x46,0xb5,0x9c,0x9d,0x8f +,0x97,0x9d,0xa2,0x9d,0x91,0x94,0x92,0x8f,0x92,0x99,0xad,0x3f,0x3a,0x42,0xdc,0x54,0x3b,0x2b,0x1f,0x1f,0x27,0x36,0x33,0x29,0x34,0x3b,0x43,0xaa,0xaa,0x9a,0x96,0x8f +,0x85,0x83,0x81,0x83,0x85,0x86,0x87,0x85,0x85,0x86,0x85,0x8c,0x92,0x9f,0xd0,0x32,0x1b,0x17,0x11,0x0a,0x07,0x05,0x04,0x03,0x03,0x02,0x02,0x02,0x02,0x02,0x03,0x02 +,0x04,0x03,0x05,0x0e,0x13,0x2a,0x1f,0x13,0x16,0x1b,0x4a,0xb4,0xb5,0xa8,0xaa,0x9d,0x99,0x9a,0x99,0xaa,0xa4,0xa1,0xa1,0x9e,0xa9,0xa9,0xa7,0xa1,0xa2,0xa4,0x9f,0x98 +,0x9b,0x99,0x94,0x90,0x8d,0x8d,0x85,0x83,0x83,0x86,0x8d,0x91,0x96,0x97,0x95,0x9b,0xa3,0xf7,0xf1,0xaf,0xc0,0x46,0x30,0x47,0xc2,0xbb,0xb9,0xac,0xc7,0x31,0x1f,0x19 +,0x1a,0x13,0x12,0x0c,0x0a,0x0d,0x0a,0x08,0x07,0x11,0x26,0x2a,0x2a,0x1b,0x13,0x14,0x1c,0x37,0x2a,0x1d,0x1d,0x25,0x25,0x1e,0x1c,0x18,0x17,0x1a,0x1c,0x23,0x2d,0x2f +,0x2a,0x31,0x53,0xbc,0xaa,0xa9,0x9f,0xad,0xa9,0xbc,0xbf,0x4a,0xae,0x9b,0x93,0x92,0xaa,0x72,0x32,0xdf,0xa4,0x9f,0x9d,0x9f,0xa0,0x9b,0x9e,0x98,0xa5,0xad,0xb7,0xae +,0xaa,0xd1,0xcd,0x2e,0x2d,0x28,0x26,0x2a,0x34,0x48,0xcd,0xae,0x99,0x8e,0x91,0x87,0x82,0x83,0x80,0x85,0x85,0x88,0x8d,0x92,0x95,0x97,0xad,0x52,0x22,0x1d,0x0e,0x08 +,0x06,0x08,0x0a,0x0a,0x09,0x05,0x06,0x07,0x0b,0x0d,0x0d,0x0e,0x0c,0x09,0x0d,0x11,0x16,0x17,0x1b,0x3a,0xb0,0xa4,0xad,0xb4,0xd3,0xbc,0x9c,0x8f,0x8d,0x94,0x9a,0x9f +,0xa0,0xaa,0xc1,0x38,0x2b,0x25,0x19,0x21,0x25,0x2b,0x29,0x35,0xc8,0xb0,0xa0,0xa8,0xb7,0xd3,0xa6,0x92,0x93,0x91,0x90,0x94,0xa1,0x41,0x39,0x2d,0x25,0x35,0x3c,0x41 +,0xd3,0xba,0xaa,0xc7,0x50,0xb2,0xb1,0xa1,0x9d,0xa5,0xa7,0xd1,0x39,0xe9,0xaf,0xa9,0xb7,0xbc,0x3d,0x2b,0x5f,0xad,0xa6,0x7b,0x52,0xc2,0xab,0xaa,0xd8,0x2c,0x16,0x13 +,0x15,0x26,0x34,0x24,0x29,0x21,0x2c,0x3c,0xda,0xc8,0x2f,0x2f,0x33,0x55,0x45,0x2b,0x28,0x1f,0x18,0x1c,0x1e,0x10,0x0f,0x10,0x1b,0x1a,0x26,0xc6,0xbc,0xad,0xc2,0xfb +,0x24,0x1e,0x2d,0xbb,0xa0,0x9d,0x9f,0x9a,0x9d,0x9a,0x95,0x94,0x8f,0x90,0x8d,0x8d,0x94,0x99,0x9c,0xaa,0xa4,0xb0,0xad,0xed,0x21,0x2f,0x3d,0xbf,0xae,0x9c,0x9a,0x95 +,0x92,0x92,0x93,0xa0,0xaa,0xa4,0x9c,0x96,0x99,0x9d,0xa5,0x43,0x34,0x4b,0x60,0x3c,0x2b,0x1f,0x1d,0x21,0x2c,0x1f,0x1c,0x1b,0x15,0x11,0x0c,0x0e,0x0e,0x0e,0x0c,0x10 +,0x23,0x25,0x4a,0x6d,0xbe,0xa5,0xad,0x97,0x95,0x95,0x8c,0x8f,0x91,0x97,0x98,0x9b,0xb9,0x20,0x11,0x0e,0x0e,0x0c,0x07,0x07,0x08,0x0b,0x08,0x07,0x05,0x04,0x07,0x08 +,0x0c,0x0c,0x0e,0x0f,0x1d,0x2c,0x31,0xd4,0xcd,0xab,0x9d,0x8e,0x88,0x89,0x88,0x86,0x87,0x87,0x89,0x89,0x8c,0x90,0x8f,0x92,0x91,0x92,0x95,0x95,0x98,0x91,0x8f,0x96 +,0x96,0x98,0x95,0x94,0x9b,0x93,0x97,0x99,0xa7,0xaf,0xae,0x54,0x59,0x3e,0x4b,0xbe,0xb1,0xc2,0x35,0x23,0x26,0x1d,0x1f,0x1b,0x16,0x10,0x07,0x07,0x09,0x0b,0x0d,0x0d +,0x0d,0x0d,0x0f,0x1d,0x22,0x1c,0x18,0x1f,0x25,0x3e,0x7d,0x3a,0x36,0x17,0x17,0x22,0x2b,0xc7,0x69,0x4e,0xbc,0xba,0xa3,0x9f,0xab,0xb7,0xce,0xd1,0xc9,0xaf,0xaf,0xba +,0x3c,0x23,0x2b,0x2e,0x3d,0xae,0xb3,0xac,0xa7,0x99,0x8e,0x96,0x95,0x96,0x90,0x96,0x9d,0x9c,0x9b,0x99,0x9c,0x99,0x93,0x94,0x91,0x8b,0x89,0x88,0x88,0x85,0x87,0x89 +,0x89,0x89,0x89,0x8b,0x90,0x99,0xa8,0xba,0xc1,0xbc,0x46,0x1f,0x1a,0x13,0x15,0x13,0x12,0x0d,0x06,0x05,0x04,0x04,0x05,0x05,0x04,0x03,0x02,0x02,0x03,0x05,0x04,0x04 +,0x05,0x07,0x0d,0x18,0x1e,0x1b,0x18,0x18,0x1b,0x2a,0x5f,0xc1,0xbc,0x4a,0x4a,0xba,0x9c,0x93,0x95,0x96,0x9a,0x9a,0x8f,0x89,0x87,0x88,0x8a,0x8b,0x8c,0x88,0x89,0x8a +,0x92,0x9e,0x9d,0x9b,0x96,0x97,0x9c,0xa2,0xa5,0xa2,0x9b,0x9e,0xa2,0xa1,0xa3,0xac,0xab,0xad,0xa6,0xae,0x35,0x1e,0x15,0x17,0x19,0x22,0x2f,0x2c,0x2c,0x3d,0x47,0x60 +,0x58,0x42,0x2f,0x2d,0x2b,0x20,0x1e,0x14,0x12,0x11,0x0e,0x0b,0x0b,0x0c,0x0f,0x11,0x18,0x17,0x10,0x19,0x25,0x2e,0x34,0x27,0x21,0x24,0x1e,0x27,0x4d,0xcd,0xc3,0xdb +,0xe4,0xc7,0xb0,0x9d,0x9d,0xac,0xc7,0xb6,0xa6,0xa5,0xa4,0xb8,0xe0,0x39,0x3b,0xad,0x99,0x8f,0x8f,0x8f,0x8d,0x87,0x82,0x81,0x82,0x83,0x83,0x83,0x83,0x82,0x83,0x85 +,0x8c,0x95,0x96,0x93,0x92,0x9d,0xcf,0x23,0x14,0x12,0x15,0x0e,0x07,0x04,0x02,0x01,0x02,0x02,0x02,0x01,0x00,0x01,0x01,0x03,0x07,0x0a,0x0b,0x0c,0x10,0x1f,0x2f,0x42 +,0x62,0xd2,0x4d,0x47,0xbd,0xab,0xa4,0xc7,0x41,0x55,0xed,0xc2,0xb1,0xa8,0xa2,0xa5,0x9e,0x99,0x96,0x90,0x8f,0x8e,0x8f,0x91,0x91,0x8f,0x8e,0x8f,0x90,0x91,0x95,0x93 +,0x90,0x8f,0x8d,0x8b,0x8c,0x96,0x99,0x96,0x93,0x95,0x9c,0xb0,0x67,0x2c,0x1e,0x1c,0x19,0x11,0x0f,0x0f,0x13,0x19,0x1f,0x28,0x1e,0x1d,0x23,0x35,0x4f,0xc9,0x49,0x2e +,0x1f,0x18,0x1e,0x26,0x20,0x18,0x11,0x0e,0x10,0x17,0x27,0x1f,0x17,0x13,0x11,0x12,0x14,0x16,0x17,0x12,0x0e,0x0f,0x18,0x20,0x1c,0x19,0x18,0x1e,0x3a,0xac,0xa3,0xaa +,0xaf,0xbc,0xc3,0xae,0xa0,0x98,0x98,0x9e,0x9d,0x97,0x8f,0x8b,0x89,0x88,0x87,0x85,0x82,0x82,0x82,0x83,0x83,0x85,0x85,0x85,0x85,0x88,0x8e,0x96,0x9b,0x9d,0xa1,0xa2 +,0xa9,0xe7,0x2d,0x25,0x19,0x0e,0x0b,0x0b,0x09,0x07,0x05,0x03,0x02,0x01,0x01,0x02,0x04,0x04,0x04,0x05,0x07,0x0a,0x0f,0x13,0x14,0x15,0x1d,0x24,0x2b,0x30,0x28,0x25 +,0x1f,0x38,0xaf,0xa0,0x9d,0xa6,0xa5,0x9e,0x95,0x8c,0x8b,0x8b,0x8e,0x8f,0x8f,0x8f,0x8f,0x90,0x94,0x95,0x94,0x95,0x99,0x9b,0x9c,0x9f,0x9d,0x97,0x93,0x94,0x95,0x99 +,0xa2,0xa7,0xab,0xb2,0xb3,0xab,0xa1,0xad,0xda,0x3a,0x33,0x3d,0x5c,0xb5,0xc5,0x33,0x27,0x24,0x2b,0x2a,0x29,0x27,0x1c,0x19,0x1b,0x1c,0x1c,0x19,0x17,0x1a,0x1e,0x33 +,0x30,0x21,0x1c,0x16,0x14,0x17,0x19,0x1d,0x1a,0x14,0x16,0x18,0x1c,0x21,0x1f,0x21,0x20,0x2f,0x47,0x31,0x3a,0x3a,0x44,0x46,0x40,0x52,0x4b,0x2d,0x22,0x2d,0x58,0xc1 +,0xad,0x9f,0x98,0x90,0x8b,0x89,0x8b,0x8b,0x88,0x85,0x83,0x82,0x83,0x84,0x87,0x8a,0x88,0x87,0x87,0x8a,0x8d,0x8f,0x92,0x8e,0x8f,0x9a,0xa9,0x4e,0x25,0x18,0x10,0x0c +,0x07,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x04,0x07,0x08,0x0a,0x0d,0x0f,0x12,0x14,0x17,0x1c,0x1b,0x19,0x1e,0x28,0x30,0x41,0xe0,0xba,0xaa,0x9b,0x93,0x96 +,0x99,0x99,0x96,0x93,0x91,0x92,0x94,0x9a,0x9f,0x9c,0x99,0x9a,0x9b,0x9b,0x9b,0x9a,0x8f,0x8c,0x8e,0x93,0x95,0x95,0x93,0x92,0x95,0x96,0x9f,0xac,0xa8,0xa7,0xa7,0xa9 +,0xaa,0xae,0xbc,0xb1,0xb6,0x3b,0x25,0x20,0x20,0x1e,0x1c,0x1a,0x16,0x11,0x15,0x18,0x1b,0x1a,0x17,0x1a,0x1f,0x32,0xea,0x42,0x2f,0x27,0x20,0x1e,0x1d,0x1b,0x15,0x10 +,0x13,0x16,0x18,0x19,0x18,0x17,0x18,0x1f,0x2d,0x29,0x29,0x29,0x2c,0x32,0x33,0x2e,0x1f,0x1b,0x1f,0x2a,0x30,0x39,0x54,0xc5,0xb2,0x9b,0x93,0x92,0x8f,0x8e,0x8b,0x89 +,0x87,0x86,0x86,0x87,0x86,0x84,0x84,0x84,0x84,0x84,0x85,0x85,0x84,0x85,0x88,0x8b,0x8d,0x90,0x95,0xa0,0xbc,0x2b,0x12,0x0d,0x0b,0x0a,0x08,0x06,0x05,0x04,0x05,0x07 +,0x05,0x03,0x03,0x03,0x05,0x06,0x06,0x08,0x07,0x06,0x07,0x09,0x0d,0x10,0x15,0x19,0x1d,0x2f,0xc1,0xb7,0xae,0xac,0xa7,0xa5,0xa3,0xa0,0xa1,0xa6,0xb1,0xab,0x9d,0x99 +,0x95,0x94,0x94,0x91,0x8e,0x8b,0x8c,0x8e,0x8f,0x8e,0x8d,0x8c,0x8f,0x93,0x9b,0xa4,0xa0,0x9e,0x9d,0x9c,0x9e,0x9e,0xa1,0x99,0x94,0x9b,0xa2,0xac,0xb1,0xcb,0x45,0x32 +,0x28,0x1d,0x17,0x18,0x1c,0x1b,0x18,0x18,0x18,0x1c,0x2a,0x3f,0x37,0x2f,0x35,0x32,0x2b,0x26,0x1f,0x17,0x0f,0x0e,0x13,0x14,0x15,0x14,0x15,0x17,0x17,0x1e,0x21,0x1b +,0x1a,0x1b,0x20,0x27,0x26,0x20,0x19,0x18,0x1c,0x1e,0x20,0x22,0x25,0x2e,0xfc,0xab,0xa5,0xaa,0xa9,0xa6,0xa1,0x9c,0x99,0x97,0x95,0x8f,0x8a,0x89,0x87,0x85,0x85,0x84 +,0x83,0x82,0x82,0x84,0x84,0x84,0x84,0x85,0x88,0x8b,0x96,0xa0,0xa7,0xbd,0x57,0x2e,0x1e,0x18,0x10,0x14,0x13,0x0b,0x07,0x05,0x05,0x05,0x04,0x04,0x03,0x02,0x02,0x03 +,0x04,0x04,0x05,0x06,0x08,0x0b,0x15,0x1a,0x1d,0x21,0x2a,0x37,0x44,0xfb,0xc5,0xcc,0x3e,0x44,0xba,0xaa,0xa3,0x9f,0x9e,0x9c,0x98,0x90,0x8f,0x93,0x94,0x8f,0x8e,0x8e +,0x8e,0x8f,0x91,0x99,0x9b,0x98,0x97,0x95,0x97,0x99,0x96,0x92,0x8d,0x8e,0x94,0x95,0x96,0x97,0x99,0x9b,0x9e,0xaa,0xca,0x4b,0x4a,0x42,0x3d,0x2e,0x29,0x26,0x2b,0x3f +,0x3d,0x32,0x28,0x2e,0x2f,0x2b,0x2a,0x20,0x17,0x14,0x10,0x16,0x1c,0x22,0x1a,0x11,0x1b,0x0e,0x25,0x8d,0x8f,0x01,0x16,0x85,0x1f,0x61,0x22,0x0e,0x13,0x09,0x0c,0x08 +,0x1a,0x01,0x06,0x08,0x00,0x08,0x01,0x0a,0x05,0x02,0x06,0x09,0x0b,0x08,0x0b,0x14,0x1f,0x1e,0xea,0x95,0x9e,0x8f,0x87,0x8b,0x8a,0x82,0x80,0x86,0x85,0x80,0x80,0x80 +,0x82,0x81,0x83,0x83,0x83,0x83,0x82,0x83,0x81,0x82,0x82,0x87,0x89,0x87,0x8a,0x8d,0x8d,0x97,0xa1,0x9e,0x4a,0x24,0x1f,0x16,0x12,0x0c,0x09,0x06,0x04,0x07,0x05,0x04 +,0x02,0x03,0x03,0x02,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x02,0x01,0x01,0x01,0x01,0x03,0x03,0x04,0x04,0x05,0x08,0x07,0x0e,0x1a,0x1e,0x1f,0x1d,0x3e,0xb0,0x9e +,0x97,0x8d,0x8b,0x89,0x85,0x85,0x83,0x83,0x82,0x83,0x82,0x81,0x81,0x81,0x81,0x81,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x81,0x80,0x81,0x81,0x80,0x81,0x81,0x83,0x82 +,0x82,0x83,0x84,0x84,0x84,0x88,0x89,0x8e,0x93,0x98,0xa6,0xac,0x3c,0x29,0x1a,0x19,0x0f,0x0a,0x08,0x07,0x05,0x02,0x02,0x01,0x03,0x00,0x01,0x00,0x01,0x00,0x00,0x00 +,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x01,0x02,0x02,0x01,0x02,0x03,0x04,0x05,0x08,0x08,0x0b,0x0e,0x12,0x17,0x1b,0x2d,0x2b,0x6c,0xd7,0xb6,0x98,0x97 +,0x92,0x8f,0x8e,0x8a,0x8c,0x8b,0x8b,0x8b,0x8a,0x89,0x88,0x89,0x89,0x89,0x8c,0x8d,0x8b,0x8d,0x89,0x8d,0x8b,0x8b,0x8c,0x8a,0x8d,0x8d,0x8d,0x8d,0x8c,0x8e,0x91,0x8b +,0x8c,0x8d,0x8d,0x8c,0x8a,0x8e,0x8e,0x92,0x8f,0x8e,0x8e,0x93,0x91,0x91,0x97,0x92,0x97,0x94,0x97,0x99,0x95,0x98,0x91,0x8e,0x91,0x90,0x94,0x8e,0x8f,0x90,0x8e,0x8f +,0x8c,0x8e,0x8d,0x8d,0x8b,0x8b,0x8c,0x8a,0x8c,0x8d,0x8f,0x91,0x8f,0x8e,0x8f,0x8f,0x94,0x98,0x99,0xa2,0xaa,0xb9,0xbd,0x3e,0x35,0x25,0x1c,0x17,0x0f,0x0e,0x0b,0x08 +,0x06,0x05,0x04,0x03,0x03,0x03,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x01,0x01,0x01,0x01,0x02,0x02,0x03,0x05,0x06,0x08,0x09,0x0c,0x0f,0x15,0x1d,0x29,0x3d,0xe0,0xad,0x9b,0x90,0x8d,0x89,0x87,0x86,0x84,0x83,0x82,0x82,0x81,0x81,0x81 +,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x81,0x81,0x82,0x82,0x82,0x82,0x83,0x83,0x83,0x84,0x84,0x86,0x86,0x87 +,0x89,0x89,0x8a,0x8b,0x8d,0x8e,0x93,0x99,0x9c,0x9d,0xa1,0xaa,0xb0,0xbd,0x6f,0x4a,0x34,0x2a,0x1e,0x18,0x17,0x14,0x0f,0x0d,0x0d,0x0d,0x0a,0x09,0x08,0x07,0x06,0x05 +,0x07,0x06,0x05,0x05,0x04,0x05,0x05,0x05,0x06,0x04,0x04,0x04,0x04,0x05,0x04,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x07,0x07,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0c,0x0d +,0x0e,0x0f,0x11,0x13,0x14,0x17,0x18,0x1c,0x1f,0x1f,0x29,0x28,0x29,0x28,0x29,0x3c,0x49,0xee,0xda,0xce,0xc3,0xbf,0xbb,0xae,0xab,0xa7,0xa1,0x9f,0x9b,0x9b,0x99,0x97 +,0x96,0x93,0x92,0x8f,0x8f,0x8e,0x8c,0x8c,0x8c,0x8d,0x8b,0x8b,0x8a,0x8b,0x8c,0x8d,0x8d,0x8c,0x8e,0x8f,0x91,0x92,0x95,0x97,0x98,0x9d,0xa0,0xa4,0xab,0xad,0xbc,0x4b +,0x39,0x36,0x2f,0x29,0x25,0x26,0x20,0x1c,0x1a,0x1b,0x1c,0x1b,0x1c,0x1c,0x19,0x1a,0x18,0x1a,0x1d,0x1c,0x21,0x22,0x23,0x25,0x28,0x2f,0x32,0x31,0x3c,0x65,0x56,0xd7 +,0xc1,0xb9,0xaf,0xae,0xa4,0xa6,0xa7,0x9f,0x9d,0x9b,0x9c,0x99,0x98,0x98,0x96,0x97,0x96,0x93,0x95,0x92,0x94,0x97,0x94,0x94,0x93,0x94,0x96,0x93,0x97,0x97,0x9a,0xa0 +,0xa3,0xaf,0xaa,0xae,0xba,0xc2,0x54,0x4b,0x38,0x33,0x2f,0x2b,0x2b,0x28,0x27,0x25,0x20,0x25,0x28,0x29,0x2d,0x2c,0x2b,0x26,0x24,0x2c,0x2d,0x2e,0x36,0x39,0x39,0x2f +,0x2f,0x37,0x35,0x37,0x3b,0x3a,0x3c,0x2f,0x31,0x3b,0x36,0x35,0x2e,0x37,0x3a,0x30,0x36,0x37,0x39,0x3b,0x37,0x3e,0x4e,0x4b,0x65,0x4e,0x5e,0xfd,0x5f,0xc7,0xca,0xbe +,0xb0,0xb8,0xb5,0xb7,0xba,0xb7,0xca,0xc3,0xbc,0xbe,0xbd,0xc2,0xc9,0xd1,0x51,0x50,0x58,0x68,0x55,0x3f,0x4f,0x46,0x3a,0x3e,0x3e,0x3d,0x35,0x30,0x32,0x30,0x33,0x31 +,0x2f,0x30,0x32,0x3b,0x3c,0x3b,0x3a,0x3f,0x40,0x3d,0x3e,0x56,0xe1,0x65,0xcf,0xdf,0x4f,0x71,0xe4,0xc9,0xd7,0x54,0xd1,0x7e,0xef,0xe7,0x69,0xec,0x4a,0x44,0x47,0x47 +,0x4a,0x40,0x44,0x48,0x3a,0x54,0x59,0x51,0x4f,0x4d,0x5d,0x56,0x4c,0x78,0xf8,0xe4,0xcd,0xd0,0xc1,0xe0,0xf9,0xee,0xed,0xd8,0xdc,0xde,0xd9,0x66,0xd9,0xd4,0x51,0x49 +,0x45,0x44,0x3f,0x3f,0x45,0x3d,0x39,0x3e,0x42,0x4c,0x44,0x3c,0x42,0x45,0x46,0x3e,0x41,0x7a,0x5a,0x70,0xff,0x55,0x53,0x5e,0x6c,0x5c,0x4a,0x5c,0xd2,0xde,0xcf,0xf5 +,0xe2,0x56,0x4d,0x53,0x5f,0x7c,0xf8,0xda,0xdf,0xe0,0xe2,0xca,0x66,0x4e,0x55,0xfe,0xed,0x52,0x4f,0x62,0x7e,0x73,0xfa,0xfc,0xda,0xe8,0xdd,0xe3,0x58,0x72,0xcb,0xc0 +,0xcc,0xdf,0xd5,0x6b,0x53,0x51,0x4d,0x6a,0x5c,0x7c,0x61,0x49,0x4f,0x4b,0x5d,0x54,0x47,0x57,0x6f,0x58,0x4d,0x59,0x68,0x6c,0xed,0xe1,0x6a,0x66,0x6b,0x5e,0x55,0x55 +,0xe8,0xdb,0xda,0xd8,0xda,0xdd,0x58,0x47,0x56,0xe5,0xeb,0xff,0x75,0x5a,0x51,0x51,0xf8,0x70,0x5d,0x55,0x4d,0x55,0x4d,0x53,0x52,0x52,0x5e,0xed,0x78,0x6a,0xe8,0x6c +,0xee,0xe8,0xcd,0xc4,0xd5,0xd2,0xd9,0xd4,0xee,0x52,0x5f,0x73,0x64,0x67,0x6c,0x65,0x59,0x54,0x68,0x66,0xec,0xef,0x5e,0x5e,0x65,0x67,0x56,0x58,0xe2,0xdb,0xd9,0xdc +,0xfa,0x63,0x4e,0x4c,0x59,0x73,0xdc,0xdd,0x6e,0x73,0x78,0x5f,0x5c,0x5e,0xf6,0xe7,0x6c,0x60,0x50,0x69,0x7d,0x72,0xf9,0x5c,0x5f,0x58,0x5e,0xee,0x67,0x66,0x6d,0xf6 +,0xd3,0xe7,0x64,0x6e,0xe9,0xe5,0xe6,0xda,0xd0,0xce,0xcc,0xec,0x66,0x7e,0x5e,0x66,0x6a,0x68,0x5b,0x50,0x52,0x65,0x68,0x7e,0x6d,0x68,0xea,0x6e,0x6e,0xee,0xf7,0x7a +,0xfd,0xe1,0xdc,0xec,0xce,0xd3,0xea,0xf3,0x70,0xdd,0xd6,0xd9,0xd1,0xed,0x76,0xe8,0xf2,0xef,0x6b,0xfb,0xe0,0x68,0x53,0x57,0x63,0xfe,0x5b,0x69,0x75,0x59,0x4f,0x4c +,0x54,0x58,0x57,0x5e,0x5e,0x6d,0xd9,0xe5,0x79,0x67,0x73,0xe4,0xdc,0xda,0xf6,0xf8,0xdd,0xdb,0xd5,0xeb,0x6c,0x6f,0x6b,0x6b,0x4d,0x4a,0x52,0x56,0x57,0x5f,0x61,0x6e +,0x68,0x58,0x5d,0x62,0x6f,0x65,0xf5,0xd2,0xd1,0xd3,0xdd,0x75,0x6c,0x79,0xdb,0xcf,0xd4,0xd0,0xd8,0xd7,0xd1,0xe8,0xe0,0xe4,0xf1,0xd9,0xde,0xee,0x59,0x5b,0xdc,0xea +,0xdf,0xde,0xf1,0x69,0x4d,0x4f,0x5a,0x5a,0x5e,0x65,0xfe,0xde,0x75,0xef,0xe8,0xf7,0xd9,0xd4,0xd7,0x6c,0x64,0xe0,0xdb,0xdf,0xe8,0x6e,0x55,0x51,0x5c,0x64,0x53,0x56 +,0x67,0x75,0x7e,0x66,0xe8,0xf6,0x6b,0xf8,0xfc,0xf6,0x5a,0x60,0xdf,0xe3,0xe1,0xf1,0x5b,0x51,0x4d,0x6c,0xdd,0xec,0xe0,0xed,0xfc,0xee,0x72,0xe7,0xf1,0x74,0xe2,0xea +,0x6f,0x5e,0x65,0xdb,0xd7,0xd2,0xd0,0x7e,0x62,0x62,0xe7,0xe6,0x5e,0x5e,0x67,0x79,0xf5,0x7d,0xe1,0xef,0x5d,0x65,0xfa,0xf8,0x6d,0x61,0xf2,0xeb,0x6f,0x6d,0x58,0x55 +,0x5e,0x70,0x7c,0x6b,0x62,0x63,0xff,0xdd,0xdc,0xe1,0x68,0x5f,0xf8,0xe3,0xec,0x6d,0x66,0x73,0xed,0xe2,0xd7,0x7b,0x59,0x5d,0x79,0xea,0xf4,0x6e,0xe3,0xe2,0xf1,0xf0 +,0xed,0xe2,0xf5,0xe4,0xdf,0xea,0x5d,0x58,0x5e,0xe4,0xd0,0xd9,0x6c,0x5a,0x65,0x5a,0x6b,0xed,0xde,0xdb,0xdd,0xde,0xee,0xde,0xda,0xde,0xd7,0xcc,0xd0,0x6d,0x6b,0xf6 +,0xd8,0xe0,0xfb,0x66,0x53,0x4f,0x4c,0x5e,0x6d,0x67,0x66,0xf6,0xe0,0xdf,0xdc,0xd3,0xd9,0xda,0xe4,0x77,0xf5,0xe7,0xe3,0xdf,0xe4,0xf2,0x67,0x4b,0x4c,0x6a,0xdd,0xf9 +,0x6b,0x5f,0xec,0x64,0xf4,0xd9,0xd9,0xda,0xef,0x74,0x69,0x69,0x72,0xf9,0xdd,0xd8,0xe4,0x59,0x4e,0x5a,0x6d,0xed,0x6d,0xcb,0x7c,0xee,0x6c,0xd0,0xdc,0x79,0x5a,0xf1 +,0x5a,0xcc,0x53,0xd3,0x4b,0x44,0xc9,0x49,0xbd,0x43,0xdb,0xda,0xd7,0x71,0xc6,0x51,0xc6,0xd4,0xc5,0xc8,0xdf,0xc9,0xf8,0xc6,0x59,0xd4,0x3f,0x62,0x3f,0xdf,0x3a,0x64 +,0x4a,0x3b,0x62,0x3e,0x68,0x40,0xbb,0xbf,0x52,0xc0,0xcd,0xbf,0xd6,0xc7,0xdd,0xfe,0xbe,0x46,0xcf,0xe6,0xcd,0xbd,0xd6,0x5d,0x47,0x58,0x68,0x59,0x65,0xd3,0xdd,0xd6 +,0x5e,0x5a,0x55,0x48,0xdd,0x54,0x46,0x50,0xe4,0x63,0x4c,0xd6,0xc6,0x46,0xda,0xf7,0x59,0xbf,0x50,0xcc,0x59,0xc9,0xcf,0xd1,0xc2,0xf5,0xbf,0x67,0x70,0x6a,0x67,0x7e +,0x4f,0x5a,0xd9,0x54,0xd4,0x4f,0x55,0xd2,0x57,0xcb,0x42,0x4d,0x54,0x7a,0xca,0xf7,0xcc,0xe5,0x47,0xed,0x46,0x4f,0xdd,0x6b,0x76,0xce,0xbd,0xd9,0x5e,0xdf,0xc4,0x78 +,0xbd,0x58,0xc2,0xf8,0x50,0xcb,0x3e,0xef,0x38,0x76,0xe4,0x46,0x56,0x4d,0x48,0x47,0x46,0xdb,0xd7,0x5c,0xcf,0x52,0xd7,0x58,0xe7,0xbd,0xf5,0xcb,0x71,0xc7,0x7d,0x5b +,0xd5,0x56,0xc2,0xe0,0x6b,0xd4,0x68,0xca,0xce,0xcf,0xcd,0x57,0xfc,0x3c,0x69,0xe1,0x46,0x40,0x41,0xeb,0x63,0x52,0x51,0x45,0x4e,0xed,0x48,0xdc,0x4a,0xc5,0xc2,0xd5 +,0xbf,0xef,0xbf,0xfb,0x65,0xce,0xcc,0xbe,0xc3,0x57,0xc3,0x4c,0x78,0x52,0x61,0xcd,0x3d,0xf7,0x3a,0x71,0xdf,0x58,0x74,0x5e,0x51,0xda,0xfd,0x73,0xde,0x4c,0x63,0x4f +,0xc4,0xc4,0x7d,0xc2,0xdd,0x5a,0x6f,0x46,0xcc,0x53,0xee,0xd7,0x58,0xbf,0x55,0xdf,0x49,0xe1,0xda,0x41,0xcb,0x5d,0xf2,0xdc,0x5c,0x56,0x4e,0x5b,0xe8,0x45,0xe0,0xe2 +,0x4c,0xcf,0x48,0xc4,0xc9,0xc8,0xd5,0x4d,0xce,0x44,0x5b,0xcd,0x42,0x5f,0xda,0xeb,0xc4,0x3b,0xd5,0x48,0xf0,0xc9,0x5b,0xbb,0x45,0xcf,0xd9,0xe6,0xc5,0xf9,0x4c,0xe9 +,0x4c,0xd9,0x45,0x39,0xdb,0x5f,0xca,0xfd,0xe5,0xec,0x4c,0xcf,0xe8,0x50,0xdc,0x47,0xbc,0xfd,0xdc,0xcc,0x47,0xcc,0x3a,0x61,0x61,0xe0,0xc0,0x5a,0xdd,0xfc,0x4b,0xce +,0x49,0xce,0xcc,0x57,0xc0,0x39,0xcc,0xcd,0x5b,0xbb,0xf9,0xd7,0x65,0x58,0xda,0x49,0x7a,0x4f,0x4a,0xc7,0x45,0xda,0xde,0x43,0xea,0x3f,0xc4,0x57,0x4d,0xce,0x58,0xbe +,0x4f,0xf3,0xc8,0x53,0xcb,0xef,0x64,0xca,0x4d,0xc4,0xdf,0xed,0xc8,0x52,0xcf,0x65,0xfa,0xd5,0x42,0xfd,0x64,0xe8,0xc7,0x48,0xcd,0x3b,0x3f,0x4f,0x3c,0xe4,0x4a,0x65 +,0xd5,0x5e,0x75,0x4d,0x52,0xca,0x64,0xdc,0xdc,0xe5,0xcf,0x75,0xbb,0xe3,0x72,0xbf,0x60,0xc1,0xea,0x5b,0xe5,0x4d,0x73,0x4d,0x67,0x61,0x49,0xce,0x4a,0x45,0x6c,0x3d +,0xcf,0xf2,0x5e,0xd8,0x64,0xd8,0xed,0xde,0xdd,0x3f,0xcd,0xd7,0x66,0xc3,0x5a,0xba,0xe4,0xcc,0xec,0x6d,0xcf,0x4f,0xde,0xe2,0x52,0x7c,0xe8,0x4e,0xcb,0x46,0xe7,0x43 +,0x5e,0x5d,0x50,0xc4,0x42,0xd6,0xfc,0xfb,0xdc,0x6d,0xd2,0xee,0x55,0xd7,0x67,0x6f,0xe9,0x55,0xc9,0x48,0xe7,0xf1,0x4c,0xce,0x44,0xe3,0xfe,0x4e,0xe2,0x59,0xcd,0xee +,0x55,0xc7,0x48,0xcf,0xe0,0x5b,0xd1,0x4a,0xb7,0xf9,0x78,0xc8,0x58,0xea,0x43,0x7d,0xdd,0x47,0xf9,0x58,0x6f,0xca,0x47,0xd2,0x55,0x64,0xdf,0x4d,0xbd,0x44,0x6f,0xbe +,0x44,0xca,0x5b,0x6d,0xd4,0x4a,0xca,0x47,0xda,0xe1,0x5a,0xcf,0x7c,0x5c,0xd0,0x52,0xdc,0x6a,0x56,0xc6,0x3b,0xba,0x5d,0xed,0xd7,0x51,0xd1,0x40,0xd3,0x4f,0x54,0xca +,0x48,0xdc,0xd2,0x44,0xdf,0x4a,0xd5,0x76,0x3f,0xd1,0x4a,0xcc,0xd1,0x50,0xb7,0x6f,0xe7,0xdc,0x47,0xd9,0x4c,0x73,0xcd,0x4c,0xba,0xdf,0x5f,0xd3,0x3d,0xbc,0x3f,0xdc +,0x61,0x51,0xb9,0x42,0xdf,0x53,0x62,0xfd,0x45,0xc9,0x61,0x41,0xca,0x3f,0xcf,0x66,0x69,0xce,0x52,0xc8,0x53,0xcd,0xcc,0x64,0xd5,0xed,0xdf,0xbc,0x6d,0xc5,0x54,0x67 +,0xde,0x35,0xc9,0x56,0x5c,0x6a,0x4a,0xe0,0x49,0x4f,0x4d,0x44,0xc5,0x55,0x47,0xcc,0x4a,0xce,0xf3,0xd0,0xc1,0x5d,0xbd,0xd6,0xdb,0xc2,0x64,0xd8,0x61,0xf3,0xcf,0x5a +,0xd1,0x3a,0x5b,0xce,0x3f,0xcb,0x52,0xd3,0xfa,0x42,0xd0,0x49,0xcd,0x67,0x4c,0xbc,0x3e,0x6b,0xdc,0x3f,0xbe,0x4e,0xcb,0xd9,0xee,0xc6,0xfd,0xd7,0xcf,0x4d,0xbe,0x52 +,0xcd,0xc5,0xd3,0x98,0x29,0xb5,0xb2,0x2f,0xc3,0x33,0xe8,0x2e,0x42,0xbe,0x2f,0x2f,0x69,0x39,0x4e,0x3c,0xbf,0xdb,0x6c,0xad,0x46,0x5f,0xbb,0xd4,0xcf,0xf4,0x4e,0x57 +,0xdf,0xc1,0x2c,0xdc,0xcf,0x31,0xee,0x3f,0x45,0x3f,0x67,0xdd,0x37,0x64,0x4f,0x3f,0xda,0x3d,0xef,0x4d,0x52,0x55,0x3a,0xcd,0x4f,0x41,0xd2,0x47,0xc9,0xc4,0x51,0xc4 +,0x58,0x46,0xdd,0xd7,0x4e,0xc5,0xcf,0x4a,0xc5,0xce,0x39,0xcf,0xcf,0xc7,0xdc,0xce,0xb3,0x69,0xff,0xba,0xfd,0xdb,0xb3,0xe0,0xbc,0x4c,0xb6,0x79,0xb6,0xb9,0x38,0xa9 +,0x6b,0xbd,0xc5,0x3e,0xb6,0x76,0x4f,0xb7,0x50,0xb9,0x52,0x3a,0xbc,0x32,0xcf,0x4c,0x51,0xcc,0x42,0xbe,0x3d,0xd8,0xbc,0x37,0xcc,0xba,0x3a,0xb5,0xcf,0x4d,0xae,0x38 +,0xe1,0xbe,0x4b,0xc4,0x53,0x36,0xcd,0x79,0x3e,0xd0,0x38,0x53,0xed,0x2f,0xcc,0x50,0x36,0xc8,0x34,0xbd,0x4d,0x3a,0xac,0x2b,0xbd,0x63,0x38,0xb7,0x3f,0xc0,0x55,0xde +,0xbb,0x38,0xb7,0x44,0xdf,0xb0,0x38,0xba,0x47,0x77,0xdb,0x30,0xd0,0xf6,0x2d,0x64,0x2f,0x3f,0x3b,0x2c,0xc5,0x27,0xbc,0x3d,0x73,0xac,0x3d,0xab,0xd5,0xb1,0xa9,0xbb +,0xab,0xb6,0xb7,0xb2,0xcd,0xd6,0x45,0x3d,0x4f,0x24,0x2d,0x26,0x27,0x30,0x1c,0x3e,0x35,0x32,0xdb,0x3d,0xac,0xb1,0xbe,0x9d,0xad,0x98,0x9d,0xa9,0x9d,0xae,0xa3,0x4d +,0x68,0x41,0x28,0x2c,0x1c,0x1f,0x1b,0x18,0x1d,0x1f,0x22,0x2b,0x2b,0xd4,0xb5,0xa7,0x9b,0x9f,0x93,0x96,0x98,0x99,0x9e,0x9d,0xae,0xc1,0xdf,0x28,0x2a,0x2c,0x13,0x17 +,0x12,0x19,0x18,0x15,0x1f,0x1d,0xcb,0xdf,0xc0,0x9e,0x9a,0x90,0x9a,0x97,0x94,0x98,0x98,0xad,0xa9,0xae,0x42,0x29,0x21,0x1e,0x18,0x0e,0x16,0x17,0x14,0x1a,0x1b,0x33 +,0x58,0xb9,0xae,0xa2,0x91,0x94,0x94,0x94,0x93,0x96,0x9d,0xa8,0xae,0xdb,0x2e,0x23,0x1d,0x17,0x0f,0x13,0x16,0x1a,0x15,0x1a,0x2e,0x4a,0xdc,0xaf,0x9f,0x95,0x92,0x91 +,0x92,0x96,0x90,0x9f,0xa2,0xaf,0xcc,0x3d,0x1f,0x1f,0x17,0x0f,0x13,0x17,0x16,0x18,0x19,0x2a,0x3e,0xd1,0xac,0xa8,0x94,0x91,0x94,0x91,0x95,0x92,0x9e,0xa2,0xac,0x51 +,0x3a,0x1e,0x1e,0x16,0x0e,0x16,0x14,0x1c,0x18,0x1a,0x37,0x3e,0xc0,0xa9,0x9f,0x95,0x92,0x96,0x92,0x99,0x96,0x9f,0xad,0xaf,0x4c,0x37,0x1d,0x1f,0x17,0x0f,0x16,0x19 +,0x1c,0x18,0x1b,0x32,0x59,0xc0,0xab,0xa1,0x93,0x97,0x96,0x95,0x96,0x96,0xa0,0xa9,0xae,0x59,0x30,0x1f,0x1c,0x16,0x0e,0x18,0x17,0x18,0x18,0x1d,0x38,0x3f,0xc6,0xaa +,0x9f,0x94,0x96,0x93,0x95,0x97,0x95,0x9e,0xa9,0xbd,0x52,0x30,0x1d,0x18,0x16,0x0f,0x17,0x17,0x1b,0x1b,0x1d,0x45,0xd5,0xca,0xa0,0x9e,0x92,0x93,0x97,0x96,0x98,0x95 +,0xa3,0xab,0xbe,0x3a,0x29,0x1d,0x16,0x17,0x0e,0x17,0x1b,0x1c,0x1d,0x1e,0x4e,0xc7,0xb4,0x9f,0x9c,0x92,0x92,0x98,0x95,0x96,0x98,0xa6,0xb5,0xcf,0x36,0x23,0x1a,0x14 +,0x15,0x0f,0x15,0x1a,0x23,0x1d,0x21,0x4e,0xb4,0xae,0xa6,0x9a,0x93,0x90,0x98,0x99,0x98,0x98,0xa5,0xaf,0xbe,0x61,0x21,0x1b,0x18,0x16,0x12,0x16,0x1a,0x1d,0x23,0x24 +,0x40,0xbd,0xad,0xa2,0x99,0x95,0x96,0x98,0x9a,0x9e,0x9d,0xa9,0xc0,0xfc,0x3d,0x29,0x1b,0x17,0x18,0x0e,0x14,0x1b,0x1d,0x27,0x29,0x53,0xbb,0xac,0x9e,0x9c,0x95,0x90 +,0x99,0x97,0x99,0x9b,0xa4,0xb9,0xae,0xae,0x23,0x0d,0x18,0x28,0x08,0x0d,0x1a,0x1d,0xac,0xa2,0xcf,0x3c,0x3b,0xa2,0x89,0x8f,0xb0,0xa3,0x8e,0xa8,0xbf,0x97,0xa2,0x37 +,0xe3,0x50,0x18,0x0c,0x14,0x4f,0x25,0x17,0x14,0x16,0x20,0x22,0xa4,0xa0,0x2f,0x4a,0x97,0x8b,0xb0,0x2a,0x99,0x81,0x82,0x8c,0xaf,0x2a,0x35,0x1e,0x09,0x01,0x0a,0x09 +,0x11,0x18,0x04,0x0b,0x8e,0x84,0xab,0xbc,0x99,0x88,0x82,0x8b,0x42,0xb5,0x91,0x8e,0xaf,0x19,0x1d,0xb2,0x9b,0x0f,0x00,0x09,0x1e,0x11,0x14,0x0f,0x1d,0x94,0x8f,0x9d +,0x2e,0xb6,0x91,0x88,0x8c,0xb9,0x3c,0x9f,0x97,0xa6,0x45,0xad,0xac,0x3a,0x25,0x11,0x12,0x16,0x3b,0x2f,0x1d,0x1c,0x19,0x26,0xa3,0xa4,0x33,0xad,0xa8,0x9e,0x93,0xa1 +,0x3e,0x9c,0x86,0x85,0x90,0xc3,0x26,0x2c,0x1b,0x07,0x03,0x07,0x10,0x19,0x19,0x0e,0x17,0x8d,0x85,0xa2,0x49,0xac,0x8b,0x82,0x8f,0x30,0x40,0x95,0x9c,0xdd,0x35,0x26 +,0xba,0xa6,0x10,0x04,0x03,0x13,0x3b,0x1b,0x0f,0x1b,0x95,0x8b,0x98,0x55,0xaf,0x8f,0x88,0x8e,0xb3,0x2e,0x54,0x9a,0xb6,0x1f,0x53,0x9f,0xda,0x12,0x09,0x1a,0x34,0x3b +,0x21,0x1c,0x1d,0x16,0x26,0x9d,0x9e,0x57,0x9d,0x9a,0xac,0xa3,0x97,0xa0,0x9f,0x93,0x8d,0x8e,0xa5,0x22,0x25,0x1d,0x08,0x05,0x09,0x0f,0x10,0x1c,0x23,0x1c,0xb0,0x88 +,0x8d,0xbd,0xcb,0x91,0x82,0x8c,0xc4,0xd6,0x9e,0xa5,0x3a,0x2f,0xc3,0x3f,0x3e,0x17,0x07,0x03,0x0b,0x3b,0x33,0x13,0x1c,0x9d,0x8f,0x92,0xb3,0x9a,0x8d,0x8d,0x92,0xa9 +,0xd4,0x63,0xa0,0xb2,0x20,0x2c,0x9f,0x72,0x12,0x09,0x1b,0x33,0x1f,0x2b,0x2c,0x22,0x14,0x21,0xa6,0xa4,0x49,0xa2,0x98,0xa9,0xb6,0x9b,0x8e,0x96,0xa2,0x96,0x8e,0x9a +,0xef,0x31,0x1c,0x0b,0x08,0x07,0x08,0x0f,0x1e,0x21,0x1c,0x35,0x8f,0x8c,0xa1,0xb4,0x95,0x86,0x8c,0x9d,0xa0,0xa8,0xda,0x43,0xc5,0xa5,0x54,0x35,0x20,0x0a,0x04,0x06 +,0x1c,0x33,0x15,0x1c,0xcc,0x9d,0x8f,0x97,0x91,0x92,0x92,0x8f,0x9e,0x5e,0x4c,0x9d,0xb3,0x1a,0x22,0xa8,0xca,0x16,0x0b,0x1b,0x34,0x1e,0x27,0x2e,0x1d,0x19,0x2b,0xa7 +,0xa5,0xc8,0x9b,0x9e,0xc2,0xad,0x99,0x8e,0x94,0x9e,0xa1,0xa7,0xa1,0x9d,0xae,0x1c,0x09,0x0a,0x0a,0x05,0x08,0x1e,0xb9,0x61,0x35,0xa1,0x8f,0x98,0xa0,0x9c,0x8c,0x8c +,0x96,0x9f,0xbc,0x3f,0x33,0xf7,0xa9,0xb5,0x2e,0x18,0x0b,0x09,0x09,0x0f,0x1f,0x28,0x2e,0x63,0xab,0x95,0x8d,0x8f,0x91,0x98,0x9a,0x9f,0x67,0x46,0xb9,0xc2,0x21,0x24 +,0xb1,0xb3,0x26,0x14,0x1a,0x41,0x26,0x1a,0x26,0x2d,0x2d,0x30,0x4f,0xae,0xad,0xac,0x9f,0xbf,0xaf,0x97,0x90,0x95,0xad,0xc8,0xc0,0xa5,0x9c,0xa8,0x33,0x14,0x0c,0x0c +,0x06,0x06,0x1e,0xb9,0xbe,0x3d,0xc6,0x95,0x95,0xa4,0x9d,0x98,0x8f,0x93,0xa3,0xb4,0x32,0x7b,0xbf,0xb0,0xac,0xd0,0x38,0x12,0x07,0x0a,0x0e,0x11,0x2c,0x38,0x4c,0xce +,0xaa,0x8c,0x8c,0x97,0x9d,0x9f,0xa0,0x6e,0x2f,0xbc,0xc7,0x3e,0x29,0xca,0xa1,0xbb,0x47,0x2b,0x20,0x24,0x16,0x0e,0x42,0xeb,0x6d,0x4a,0x2f,0x9d,0xb4,0x2d,0x2d,0x5d +,0x95,0x9c,0xa6,0x9d,0xa9,0xa2,0xac,0x96,0x93,0xaf,0x2e,0x11,0x0c,0x07,0x04,0x09,0xaa,0x98,0xd3,0xc7,0xa4,0x8d,0xa4,0x26,0xbd,0x99,0x9a,0xbf,0x3c,0xa3,0xa7,0xac +,0xa5,0x98,0x9e,0x29,0x19,0x0e,0x0a,0x07,0x08,0x0a,0xa5,0x9b,0xeb,0x91,0x8c,0x84,0x98,0x28,0xb6,0xbe,0x3a,0x21,0x29,0x9f,0xe4,0x32,0xbc,0x9e,0x9d,0x36,0x62,0x3d +,0x1d,0x10,0x0a,0x0c,0x9e,0xa0,0x2e,0x9f,0xa5,0x99,0x25,0x11,0xc4,0xa9,0xaa,0xa8,0x9f,0x94,0xb3,0xa7,0x94,0x92,0x9e,0x20,0x25,0x0e,0x06,0x05,0x09,0x0f,0x97,0x90 +,0x71,0x95,0x99,0x92,0x3c,0x1a,0xb5,0xa7,0xea,0xe5,0xa5,0x97,0xa4,0xa5,0x96,0x9f,0x43,0x17,0x1f,0x0e,0x08,0x08,0x10,0x0c,0xaf,0x8c,0xa7,0x86,0x8d,0x8a,0xaa,0x11 +,0x3d,0x33,0x24,0x24,0x41,0xa4,0x61,0xdd,0x9c,0x9c,0xa3,0x3e,0xad,0x2e,0x12,0x0e,0x19,0x0e,0x41,0x90,0x3b,0x9d,0x5a,0xad,0x34,0x0d,0xcc,0x9f,0x9f,0xb1,0xa4,0x92 +,0x9d,0xa0,0x93,0x99,0xb0,0x1a,0x20,0x0e,0x08,0x08,0x18,0x14,0x29,0x8a,0xb5,0x95,0xa7,0x9f,0xaf,0x0e,0x6c,0xaa,0xad,0xbf,0x9c,0x8a,0x97,0xa6,0x9e,0xb2,0x34,0x0e +,0x19,0x12,0x09,0x0a,0x13,0x15,0x1e,0x86,0x8d,0x8c,0x8d,0x96,0xa3,0x0b,0x18,0x3f,0x28,0x24,0xdd,0x99,0xa4,0xb3,0x95,0x95,0x9f,0x4a,0xc3,0x3a,0x0f,0x0d,0x18,0x18 +,0x0e,0x97,0xa2,0xfa,0xb7,0x5b,0xad,0x10,0x2c,0x9e,0xa8,0xbf,0xa4,0x8c,0x92,0x9d,0x95,0x9a,0xcd,0x19,0x1b,0x1a,0x09,0x0c,0x15,0x1c,0x0b,0x9a,0x8c,0xac,0x9b,0xb2 +,0x9a,0x16,0x1c,0xa2,0xa7,0xa9,0x9e,0x8a,0x94,0xba,0xa8,0xb7,0x26,0x12,0x16,0x1f,0x0a,0x0b,0x16,0x27,0x15,0x98,0x81,0x97,0x91,0xa6,0xa1,0x16,0x0a,0x3c,0x37,0x29 +,0x3a,0x97,0x90,0x9f,0x95,0x90,0xa6,0xd9,0x2e,0x71,0x16,0x0c,0x17,0x1c,0x09,0x22,0x8e,0x4a,0xc1,0x44,0xaa,0x30,0x12,0xae,0xaa,0xb1,0xab,0x8d,0x89,0x98,0x99,0x97 +,0xc3,0x2d,0x17,0x2a,0x12,0x0a,0x10,0x17,0x0c,0x1b,0x87,0xab,0xaf,0xb2,0xa6,0xc5,0x11,0xab,0x9b,0xa6,0x9f,0x8d,0x8d,0xa6,0xb2,0xa4,0x26,0x15,0x11,0x1d,0x0f,0x09 +,0x18,0x2e,0x1c,0x33,0x81,0x94,0xa6,0x9e,0xa8,0x4e,0x07,0x1f,0xd5,0x1f,0x3b,0x93,0x8a,0x96,0x9b,0x8d,0xa8,0x2e,0x27,0x3b,0x1c,0x0b,0x12,0x1d,0x0e,0x0c,0x8b,0x9e +,0x3e,0xaa,0xac,0xa9,0x0c,0x2b,0x9b,0xcf,0xb6,0x8e,0x88,0x98,0xa8,0x93,0xae,0x1f,0x19,0x27,0x18,0x09,0x0e,0x1b,0x18,0x0d,0x8b,0x94,0x38,0xa1,0xa9,0x9d,0x13,0x3d +,0x90,0xb1,0xb1,0x90,0x8d,0xa4,0xcb,0xa4,0x2f,0x11,0x11,0x1e,0x15,0x0d,0x1e,0x3d,0x3c,0x1c,0x88,0x8d,0xdf,0x99,0xb2,0xdd,0x08,0x12,0xcd,0x1b,0x3b,0x90,0x8a,0x92 +,0x99,0x8d,0xa4,0x2b,0x32,0x36,0x1c,0x0c,0x14,0x18,0x0e,0x0b,0x8e,0x97,0x2c,0x9f,0xa6,0xb1,0x0d,0x29,0x9d,0x4e,0xae,0x8c,0x8a,0x96,0xa2,0x8f,0xaf,0x19,0x1c,0x1f +,0x13,0x05,0x0f,0x1c,0x10,0x10,0x8a,0x93,0x35,0x9c,0x99,0xa4,0x15,0xd6,0x91,0xb6,0xae,0x8c,0x8e,0xa3,0x3e,0xa6,0x27,0x0a,0x11,0x1e,0x16,0x0b,0x26,0xbe,0x23,0x2a +,0x82,0x9a,0xc7,0x9d,0xb6,0x30,0x07,0x23,0xca,0x22,0xac,0x8b,0x8d,0x96,0x9f,0x8f,0xda,0x1e,0x28,0x2f,0x12,0x0b,0x18,0x17,0x0d,0x1f,0x84,0x44,0xc3,0x97,0xb3,0x48 +,0x15,0xb0,0xa6,0x3f,0x99,0x8b,0x97,0x9d,0xa0,0x95,0x2a,0x1a,0x21,0x1c,0x09,0x0a,0x13,0x17,0x0c,0xd6,0x83,0x28,0x9e,0x90,0x9c,0xdd,0x1f,0x9a,0xa1,0x53,0x9a,0x8d +,0x9b,0xc8,0xc0,0xb3,0x0f,0x10,0x18,0x1d,0x0b,0x0f,0x3a,0x3d,0x18,0x94,0x82,0x4f,0x9b,0x99,0xb7,0x10,0x0e,0x4e,0x3f,0x27,0x97,0x8b,0x93,0xa1,0x97,0x9a,0x1b,0x34 +,0x2f,0x15,0x0b,0x0e,0x1f,0x1c,0x0c,0x8c,0x8f,0x22,0x9b,0xa8,0xbc,0x10,0x23,0xa0,0x4f,0xaf,0x8d,0x8c,0x92,0xa2,0x90,0x65,0x1a,0x27,0x16,0x0e,0x08,0x10,0x1a,0x0e +,0x15,0x86,0xa9,0x39,0x8f,0x96,0xb7,0x21,0x9e,0x93,0xc5,0x9f,0x8d,0x9c,0xae,0x4e,0xb9,0x16,0x0e,0x20,0x17,0x0b,0x13,0x1d,0x32,0x17,0xa9,0x80,0xea,0x9b,0x96,0xba +,0x1a,0x0f,0xb9,0xb7,0x24,0x9a,0x8e,0x9e,0x9f,0x9e,0x9d,0x23,0x2d,0x4f,0x1b,0x0a,0x13,0x1b,0x1b,0x0d,0x97,0x8a,0x2d,0x9f,0xa4,0xb3,0x18,0x20,0x9f,0xe8,0x3f,0x8c +,0x96,0x99,0x9c,0x97,0xa4,0x1c,0x37,0x1f,0x0e,0x08,0x0f,0x11,0x12,0x0e,0x88,0x94,0x30,0x8e,0x9b,0xab,0x21,0xb2,0x94,0xdf,0xa1,0x8a,0xb3,0xaf,0xb6,0xb6,0x1b,0x0e +,0x25,0x19,0x0d,0x0f,0x1b,0x26,0x1f,0xb3,0x80,0xa6,0xa7,0x90,0xd6,0x1d,0x15,0x60,0xb6,0x1c,0x9a,0x8d,0xba,0xa6,0x9f,0x97,0x29,0x2b,0x4f,0x21,0x0d,0x0f,0x1b,0x1d +,0x11,0x99,0x88,0x28,0x9b,0x9f,0x47,0x1f,0x1d,0xa3,0xb1,0x29,0x8d,0x8f,0xac,0x9a,0x95,0xa7,0x18,0x31,0x2f,0x0f,0x09,0x0d,0x1c,0x0f,0x10,0x89,0x95,0x2a,0x8f,0x99 +,0x3b,0x29,0xbe,0x91,0x59,0xad,0x8a,0xb0,0xc7,0xb1,0xa9,0x1e,0x14,0x1f,0x21,0x12,0x0e,0x27,0x2b,0x15,0xa5,0x80,0xb1,0xab,0x8d,0xb4,0x17,0x13,0xca,0xbd,0x17,0x98 +,0x94,0x58,0x9e,0xa5,0x9b,0x23,0x25,0xec,0x1c,0x0b,0x15,0x25,0x2a,0x13,0x8e,0x8b,0x1f,0x96,0xa4,0x2a,0x0e,0x2b,0xaa,0x30,0x4c,0x8b,0x9b,0xa6,0x98,0xa0,0xa0,0x25 +,0x3a,0x22,0x16,0x0c,0x0c,0x17,0x14,0x15,0x87,0x98,0x48,0x8e,0xae,0x43,0x1f,0x38,0x9b,0xb0,0xaa,0x8b,0xb4,0xb5,0xee,0xf2,0x3a,0x18,0x2b,0x1f,0x15,0x0f,0x14,0x42 +,0x1a,0xbc,0x81,0xae,0xa1,0x90,0xc7,0x21,0x14,0x29,0xb7,0x20,0xa4,0x92,0xb3,0x9f,0xad,0xa9,0xcc,0x5e,0x29,0x2b,0x19,0x0e,0x19,0x31,0x12,0x9b,0x84,0x32,0x9e,0x9e +,0x29,0x18,0x17,0x2d,0xcd,0x2b,0x8f,0x93,0xb2,0x93,0xa0,0xa8,0x4f,0x48,0x27,0x1a,0x0e,0x0f,0x12,0x15,0x11,0x88,0x91,0x22,0x89,0xa2,0x26,0x1f,0x38,0xad,0x45,0xaf +,0x8b,0xb8,0xbe,0xa1,0xc1,0x2f,0x20,0x35,0x26,0x15,0x0f,0x17,0x1f,0x19,0x3f,0x80,0xa6,0xb4,0x8c,0x42,0x1a,0x1b,0x2d,0x47,0x2a,0xa5,0x8e,0xcb,0x9f,0xa1,0xb6,0x3d +,0x3a,0x4a,0x22,0x18,0x19,0x16,0x1e,0x16,0x98,0x83,0x2d,0x94,0x9a,0x1c,0x19,0x16,0x31,0x29,0x2b,0x8e,0x98,0xac,0x93,0x9f,0xa8,0x3d,0x59,0x36,0x17,0x11,0x0e,0x0f +,0x19,0x12,0x8a,0x8c,0x37,0x8b,0x9e,0x28,0x21,0x25,0xc1,0x35,0xcd,0x8d,0xb5,0xa8,0xa2,0xca,0xe5,0x29,0x35,0x21,0x15,0x13,0x13,0x1b,0x1f,0x2f,0x81,0xa0,0xa8,0x8a +,0x3a,0x23,0x1c,0x1c,0x3d,0x23,0xaa,0x90,0xe4,0x99,0x9f,0xad,0x7e,0x56,0x39,0x1f,0x16,0x19,0x13,0x1c,0x1b,0xab,0x83,0x59,0x96,0x96,0x21,0x1c,0x18,0x21,0x32,0x2a +,0x92,0x97,0xaf,0x90,0x9d,0xaa,0x66,0xb4,0x26,0x18,0x13,0x0e,0x0d,0x19,0x11,0x90,0x8a,0x31,0x8a,0x9b,0x23,0x2a,0x2d,0x36,0x36,0x62,0x8f,0xac,0xb2,0x95,0xaf,0xd6 +,0x67,0x7a,0x21,0x17,0x13,0x13,0x11,0x1c,0x1c,0x88,0x94,0x58,0x87,0xac,0x1c,0x25,0x25,0x27,0x27,0xd2,0x91,0xbe,0xa8,0x97,0xa9,0x4a,0xb3,0xc3,0x21,0x1e,0x14,0x11 +,0x1a,0x16,0x24,0x82,0xb8,0xaf,0x87,0x47,0x15,0x1f,0x20,0x23,0x25,0xa8,0x90,0xbe,0x98,0x96,0xa1,0xcf,0xa8,0x51,0x1d,0x12,0x0e,0x0d,0x15,0x0d,0xc6,0x82,0x32,0x93 +,0x89,0x3d,0x1f,0x2e,0x26,0x2b,0x29,0x9d,0x9c,0xba,0x99,0x9b,0xa6,0xdb,0xa6,0x2d,0x1d,0x13,0x0e,0x0e,0x1c,0x0c,0x9b,0x87,0x24,0x8c,0x8e,0x2d,0x25,0x25,0x22,0x2a +,0x25,0x99,0xab,0xaf,0x96,0xa5,0xa5,0xad,0xb2,0x2b,0x29,0x11,0x11,0x14,0x1a,0x11,0x8b,0x8f,0x32,0x8b,0x9f,0x25,0x1b,0x24,0x1f,0x2f,0x40,0x98,0xa8,0xa1,0x98,0x9c +,0xac,0xaa,0xc0,0x1e,0x1b,0x0f,0x0e,0x12,0x13,0x1c,0x83,0xa9,0xac,0x89,0xac,0x33,0x21,0x2e,0x2a,0x24,0xb6,0x9c,0xf0,0x9b,0x9f,0xa1,0xb7,0xad,0x4c,0x1f,0x18,0x11 +,0x0f,0x19,0x0e,0xb6,0x83,0x32,0x93,0x8d,0x54,0x27,0x25,0x26,0x21,0x27,0xa3,0xa9,0xc0,0x98,0xa6,0xa2,0xb7,0xae,0x37,0x1e,0x19,0x12,0x0f,0x1f,0x10,0x90,0x89,0x2c +,0x8a,0x9b,0x2a,0x22,0x1f,0x24,0x29,0x2d,0x9a,0xb4,0xae,0x99,0xa3,0xa7,0xae,0xb1,0x25,0x1f,0x15,0x0e,0x10,0x1b,0x14,0x87,0x9a,0x40,0x87,0xa8,0x2b,0x2a,0x28,0x28 +,0x26,0x43,0x9a,0x6d,0x9f,0xa2,0x9d,0xab,0xbc,0xb5,0x23,0x1b,0x15,0x0f,0x17,0x14,0x21,0x81,0x53,0xad,0x86,0xdf,0x27,0x2d,0x23,0x2c,0x24,0xbf,0x9c,0x67,0xa1,0xa2 +,0xa3,0xb6,0xad,0x59,0x32,0x1a,0x13,0x13,0x1a,0x12,0x55,0x83,0x2e,0xa7,0x88,0x47,0x26,0x44,0x2b,0x2f,0x29,0xb9,0xa0,0x4a,0x9f,0x9e,0xab,0xab,0xab,0x36,0x33,0x17 +,0x11,0x12,0x1b,0x0f,0xba,0x85,0x21,0x97,0x8b,0x38,0x28,0x2f,0x26,0x25,0x24,0xa7,0xa3,0xc2,0x95,0x9a,0xa2,0xae,0xa2,0x3c,0x22,0x18,0x14,0x0e,0x1b,0x0c,0x9c,0x8a +,0x1b,0x8d,0x95,0x29,0x29,0x3e,0x28,0x2a,0x32,0xa1,0xb7,0xd6,0x9a,0x9a,0xa5,0xa8,0x9e,0x3b,0x27,0x15,0x14,0x12,0x1a,0x0a,0x90,0x91,0x18,0x8b,0x94,0x28,0x3b,0xbd +,0x23,0x2e,0x31,0xa6,0xbb,0xbf,0x9a,0x99,0xa1,0xa5,0xbd,0x30,0x21,0x0e,0x12,0x18,0x19,0x0d,0x8c,0x95,0x1e,0x8a,0x97,0x1d,0x31,0x64,0x21,0x2c,0x3f,0x9c,0xd8,0xbe +,0x91,0x9d,0xac,0x9c,0xb3,0x33,0x25,0x16,0x1a,0x0d,0x16,0x12,0x90,0x9e,0x1d,0x8b,0x98,0x1d,0x35,0xb2,0x27,0x28,0x28,0x99,0xc9,0xc5,0x93,0x96,0xa6,0x9c,0xab,0x2f +,0x27,0x10,0x17,0x10,0x14,0x12,0x8e,0xa2,0x21,0x89,0x99,0x1c,0xa8,0xa9,0x18,0x2c,0x46,0xa2,0x5e,0xb9,0x96,0x9e,0xb5,0x9f,0xb9,0x29,0x1e,0x1b,0x1b,0x11,0x17,0x15 +,0x8d,0xb6,0x1c,0x88,0x9f,0x1d,0xad,0x5b,0x22,0x3c,0x3d,0xa1,0x66,0xae,0x93,0xa0,0xaf,0x96,0xc6,0x26,0x20,0x1c,0x1a,0x0d,0x12,0x16,0x8e,0xea,0x19,0x86,0xa3,0x1e +,0x9f,0x4f,0x1d,0x66,0xcd,0xa4,0xcd,0xa7,0x93,0x9d,0xa6,0xa0,0xc1,0x24,0x1f,0x23,0x13,0x0e,0x13,0x16,0x90,0x32,0x1c,0x87,0xad,0x27,0x9e,0xc7,0x28,0x5b,0xaf,0xa4 +,0x37,0xaa,0x94,0xa6,0xaf,0xa5,0xc0,0x35,0x1e,0x1f,0x15,0x14,0x19,0x0f,0x90,0x37,0x23,0x88,0xb4,0x2a,0x9c,0x4b,0x20,0xca,0xe8,0xaf,0x4d,0x9f,0x97,0x9e,0xa4,0xa2 +,0x5f,0x2c,0x29,0x1d,0x0f,0x14,0x17,0x12,0x95,0x25,0x32,0x8b,0xbc,0x36,0x9a,0x40,0x29,0xab,0xc5,0xad,0xe4,0x98,0x98,0xa3,0xaa,0xab,0x4c,0x23,0x1f,0x1c,0x0e,0x19 +,0x13,0x12,0x8f,0x1d,0x46,0x8a,0xdc,0x46,0x9a,0x57,0x59,0xae,0xce,0xa8,0x4f,0x9d,0x9f,0xaf,0xb2,0xa6,0x2f,0x2d,0x27,0x1b,0x14,0x1c,0x10,0x1b,0x8f,0x14,0xe2,0x8c +,0x45,0x43,0x97,0x2f,0x4d,0xad,0xcd,0xa9,0xc7,0x9c,0x9f,0xa6,0xaf,0xae,0x27,0x33,0x2c,0x19,0x13,0x25,0x0b,0x36,0x95,0x0a,0x9b,0x90,0x21,0xa9,0x99,0x20,0xa3,0xa8 +,0xbc,0xa6,0xcc,0x96,0xa8,0xcd,0xa1,0xd6,0x1a,0x58,0x1d,0x12,0x1a,0x22,0x0b,0xb0,0xa6,0x0f,0x91,0x96,0x27,0x9d,0x98,0x29,0xa2,0xa8,0xb1,0xb6,0xad,0xa2,0xb0,0x4e +,0xaa,0x60,0x20,0x42,0x20,0x17,0x1b,0x1f,0x0a,0x99,0x48,0x11,0x8d,0xa3,0x1f,0x95,0xa7,0x28,0x9d,0xaf,0xad,0xbf,0xa9,0x9c,0xbb,0x6d,0x9c,0x26,0x2b,0x3e,0x1d,0x15 +,0x1d,0x13,0x13,0x93,0x14,0x2a,0x8c,0x3e,0x2d,0x8e,0x5d,0xe5,0x98,0xb5,0xab,0xbb,0xa3,0xa0,0xc9,0xe8,0xa4,0x22,0x2b,0x28,0x18,0x13,0x26,0x0b,0x3e,0x94,0x0d,0x9c +,0x8d,0x24,0xab,0x92,0x2b,0xa4,0xa3,0xb3,0xac,0xdd,0xa6,0xa4,0x41,0xbb,0xae,0x1d,0x32,0x27,0x1b,0x13,0x24,0x0b,0xaf,0xa5,0x0e,0x90,0x96,0x23,0x9d,0x9d,0x29,0xa0 +,0xad,0xa7,0xb0,0xbc,0x9b,0xaa,0x38,0xa4,0xbd,0x1e,0x44,0x1e,0x19,0x1d,0x15,0x0f,0x99,0x27,0x18,0x8c,0xb4,0x21,0x95,0xab,0x48,0x9e,0xaf,0x9f,0xdd,0xaf,0x9c,0xc2 +,0x57,0x9f,0x2f,0x27,0x31,0x1b,0x14,0x1b,0x10,0x1b,0x92,0x13,0xe6,0x8a,0x2e,0xce,0x8f,0x33,0xac,0x9b,0xc3,0xa4,0x71,0xb1,0xa6,0x53,0xd8,0xa4,0x29,0x37,0x2e,0x1c +,0x13,0x23,0x0d,0x40,0x9a,0x0f,0x9c,0x93,0x21,0xae,0x98,0x29,0xa2,0xa8,0xb9,0xa5,0xbe,0xaa,0xa1,0xdb,0xaf,0xa6,0x29,0x31,0x2d,0x17,0x18,0x1b,0x0c,0x9f,0x38,0x11 +,0x91,0xa7,0x1b,0x96,0xa0,0x2a,0x97,0xa5,0xa8,0xb4,0xab,0xa2,0xc9,0xce,0xa4,0x3c,0x33,0x29,0x20,0x17,0x18,0x14,0x15,0x94,0x1d,0x20,0x8a,0x4a,0x24,0x91,0xeb,0x4e +,0x93,0xb7,0xa4,0xa8,0xb4,0xa7,0xcf,0x9e,0xab,0x3c,0x22,0xbe,0x1e,0x24,0x1b,0x0e,0x1d,0x06,0x04,0x09,0x96,0x23,0x1b,0x93,0x0e,0x99,0x8c,0x9e,0x8b,0x92,0x98,0x94 +,0x8b,0x8f,0xc3,0x8f,0xae,0x29,0x9f,0x00,0x27,0x96,0x93,0x94,0x2f,0xa7,0xc8,0x0b,0x0f,0x16,0x03,0x0e,0x07,0x11,0x08,0x0e,0x0d,0x10,0x0e,0x0e,0x1f,0x0e,0x10,0x12 +,0x17,0x18,0x1f,0x15,0x8d,0xab,0xbe,0x82,0x96,0x9b,0x83,0x8f,0x8a,0x80,0x87,0x82,0x82,0x82,0x80,0x84,0x89,0x81,0xad,0xc3,0x9a,0x98,0x0a,0x0a,0x0c,0x05,0x4d,0x01 +,0x08,0x16,0x00,0x06,0x36,0x08,0x0b,0x05,0x00,0x22,0x04,0x03,0x09,0x0b,0x1b,0x2a,0x21,0x2a,0x13,0x14,0xb4,0xa2,0xa1,0x88,0x88,0xa6,0x83,0x81,0x89,0x85,0x80,0x89 +,0x87,0x82,0x87,0x82,0x89,0x8a,0x9a,0x9d,0x9d,0xa2,0xbc,0x3a,0x10,0x06,0x0f,0x03,0x06,0x1b,0x05,0x03,0x19,0x06,0x0b,0x1e,0x07,0x06,0x12,0x15,0x12,0x1f,0x12,0x29 +,0xaa,0xfd,0x9a,0x23,0xc8,0xaa,0xbe,0x51,0xb8,0x25,0x29,0x8d,0xba,0x90,0x86,0x8b,0x87,0x85,0x87,0x89,0x89,0x86,0x83,0x83,0x88,0x87,0x94,0x8b,0x99,0x10,0x1c,0x18 +,0x0a,0x01,0x06,0x01,0x0d,0x0a,0x00,0x0f,0x08,0x0b,0x1b,0xce,0x11,0x1b,0x0c,0x0b,0x17,0x51,0xaa,0x39,0xa0,0x4a,0xa2,0xcb,0xc5,0x9d,0xaa,0x81,0x92,0x26,0x88,0x8b +,0x89,0x84,0x85,0x8a,0x86,0x8d,0x8b,0x8b,0x8d,0x93,0x9b,0xa2,0x69,0xcf,0x1f,0xa2,0x0f,0x18,0x0e,0x0d,0x0b,0x0c,0x0d,0x01,0x0d,0x06,0x11,0x23,0x0c,0x0a,0x04,0x0d +,0x31,0x2f,0xac,0x18,0x12,0x16,0xa6,0xad,0x8e,0x87,0x3c,0x9e,0x9a,0xa6,0x0e,0x98,0x9b,0xb8,0x9a,0x1c,0x82,0x87,0x9e,0x8d,0x8d,0x89,0x84,0x81,0x86,0x8d,0x90,0x8c +,0xab,0xad,0x96,0x25,0x11,0x1a,0x05,0x00,0x00,0x05,0x03,0x06,0x17,0x00,0x0c,0x14,0x0a,0xaa,0x2a,0x0b,0x14,0xb7,0x2a,0x1f,0x94,0x40,0x7a,0x30,0x9a,0xa4,0xb6,0x8f +,0xa3,0xa6,0x1d,0xc6,0x1a,0x83,0x8c,0x41,0x84,0x85,0x8b,0x93,0x87,0x83,0x8d,0xbc,0xa0,0xb0,0x85,0x95,0x1b,0x3e,0x88,0x30,0x0f,0xa5,0x13,0x0c,0x00,0x16,0x07,0x13 +,0x29,0x00,0x15,0x0d,0x08,0x0a,0x19,0xba,0x05,0x1e,0x1a,0x1a,0xe4,0x9f,0x98,0x17,0xa1,0x1f,0xd7,0x8d,0x9e,0xc5,0x32,0xbd,0x27,0x8e,0x8d,0x8e,0x80,0x97,0x29,0x8b +,0x87,0x89,0x96,0x8a,0x85,0x97,0x8e,0x33,0xdb,0xa8,0x89,0x33,0x11,0x1e,0x0e,0xe2,0x03,0x0e,0x00,0x0b,0x12,0x06,0x18,0x11,0x0b,0x05,0x24,0x1b,0x0e,0x28,0xb1,0x3c +,0x1c,0x16,0x8d,0xa2,0xa8,0xe2,0x0e,0x5b,0xa7,0x92,0x97,0x8c,0x44,0x0c,0xbb,0x97,0x8b,0x8d,0x96,0x9f,0x9f,0x85,0x8a,0x88,0x8d,0x88,0xa9,0x9d,0x83,0x97,0x99,0xa7 +,0x95,0xd2,0x74,0x2f,0x12,0x30,0x11,0x0b,0x00,0x0e,0x1c,0x00,0x07,0x0f,0x0c,0x03,0x12,0x0b,0x19,0x2a,0x1a,0x0e,0x64,0xa5,0xa7,0x9e,0x4c,0x29,0xf4,0x82,0xb2,0x91 +,0xa8,0x9f,0x8f,0xa5,0x8f,0x94,0xa5,0x9b,0x9c,0x92,0x9c,0xb5,0x8b,0x92,0xa1,0x99,0x86,0xaa,0xac,0x4b,0x99,0xa2,0xc4,0x30,0xcf,0x0e,0x1a,0xa7,0x19,0x10,0x08,0x1a +,0x05,0x21,0x09,0x0c,0x0f,0x05,0xc5,0x1b,0x1b,0x27,0x17,0x24,0x50,0xe8,0x34,0xad,0xa2,0x9c,0x1b,0x1c,0x8d,0x97,0xe4,0xa0,0xbf,0x54,0xa7,0x9a,0x96,0xa3,0xd3,0xa1 +,0x9b,0x91,0x90,0x93,0x97,0x92,0x80,0x9c,0x8f,0x90,0x8e,0xa7,0xa2,0xa6,0xa1,0x76,0x18,0x1e,0x07,0x15,0x19,0x0d,0x08,0x0c,0x08,0x13,0x07,0x08,0x0e,0x24,0x08,0x0d +,0x26,0x16,0x1b,0x18,0xc6,0x15,0x93,0xa0,0xa9,0x93,0xa5,0x95,0x92,0x8f,0xa9,0x92,0x8b,0x92,0x88,0x80,0xbe,0xa3,0xa4,0xb6,0x93,0x93,0xac,0x1f,0xba,0xb7,0xaa,0x6a +,0x20,0x25,0x1e,0x29,0x3f,0x2d,0x1c,0x1e,0xb2,0x4d,0xaf,0x21,0x1a,0xaf,0xcb,0x0c,0x36,0x1a,0x20,0x22,0x1a,0x1f,0x0e,0x2c,0x11,0x2b,0x25,0xba,0x15,0x2f,0x13,0x2a +,0x24,0x71,0xb0,0xbd,0xb4,0xa4,0x9c,0xad,0x8c,0x2f,0x8c,0x8e,0x89,0x8e,0x9c,0x97,0x9b,0x89,0x8b,0x9b,0x94,0x9d,0xa8,0xa5,0x9e,0x4e,0x23,0x2f,0x10,0x51,0x29,0x09 +,0x1e,0x13,0x16,0x12,0x6d,0x18,0x0b,0x2c,0x0c,0x17,0x1c,0x2d,0x0f,0x24,0x1e,0x28,0x46,0x0f,0x19,0xa5,0x38,0xad,0xa5,0x2b,0xa0,0x2d,0x9c,0x9e,0x9b,0x8e,0x9f,0x9e +,0x98,0x90,0x8b,0x96,0x92,0x91,0xba,0x8d,0x94,0xba,0x9f,0xa0,0x1b,0x55,0x2c,0x3c,0x4c,0x17,0xbb,0x1b,0x36,0x15,0x30,0xad,0x24,0x2a,0x1f,0x19,0x1b,0x1f,0x17,0xae +,0x19,0x0b,0xeb,0x24,0x15,0x29,0x49,0x17,0x25,0xb1,0xb9,0x19,0xbe,0xbd,0xb5,0x95,0x36,0x92,0x98,0x92,0xa5,0xa6,0xa6,0x96,0x98,0xae,0xc5,0xaf,0x90,0x9f,0xb7,0xd6 +,0x36,0x26,0x8f,0x4f,0xce,0x32,0x14,0xab,0xb1,0xc5,0x4f,0x35,0x21,0xa7,0x1f,0x32,0x29,0x15,0x2a,0x27,0xe6,0x1e,0x4d,0x46,0x2e,0x2d,0xbc,0x12,0x37,0x49,0x19,0x1e +,0x28,0xe4,0x19,0x1c,0x29,0x44,0xcc,0x3a,0x29,0xad,0xc0,0x95,0xa7,0xb6,0x8f,0x95,0x9d,0x9c,0x9d,0x92,0xa5,0x90,0x91,0x6d,0xc7,0x9f,0x9b,0x9e,0xb4,0x35,0xa7,0x2b +,0xd6,0x6e,0x16,0x23,0x1c,0x1a,0x4b,0x13,0x0e,0x1f,0x27,0x0d,0x0a,0xdc,0x25,0x12,0x5b,0x18,0x2b,0xab,0xaa,0xa1,0xb7,0x9a,0x3f,0x98,0x8f,0x98,0x9c,0xa7,0x95,0xa9 +,0x51,0x9a,0x9b,0xcd,0x99,0x29,0x43,0x8f,0xeb,0x20,0xe9,0xeb,0xa7,0x2e,0x3a,0x3a,0x15,0x3c,0x5a,0xb8,0x3d,0x1c,0xb3,0x37,0x3b,0x9c,0x3c,0xe0,0xa2,0x4e,0x33,0xae +,0x4d,0xbd,0x33,0xaa,0xb6,0x21,0x2b,0x27,0x2f,0xd1,0x36,0xd3,0xbb,0x1a,0x2c,0x1d,0xa7,0x26,0x23,0x38,0x19,0xd5,0x1c,0xaa,0x3d,0x4a,0xb8,0x1c,0xb2,0xdf,0xd8,0xbf +,0x98,0xa9,0xa3,0x95,0xac,0xb5,0x9c,0x92,0x98,0x9e,0x91,0xbc,0x5f,0x9c,0xcc,0xb7,0xbd,0xcc,0x19,0x19,0x36,0x18,0x10,0x29,0x26,0x1d,0x12,0x41,0x14,0x15,0x0f,0x27 +,0xa2,0x28,0x42,0x1f,0x42,0xaf,0x9f,0x9e,0xa1,0xa2,0xb6,0x2c,0xa3,0xc8,0xb2,0xb3,0x9f,0x3b,0x27,0xc9,0x45,0x96,0xb6,0x3b,0xae,0xa7,0xb1,0x6a,0xb4,0xce,0xb2,0xac +,0xaa,0x55,0x21,0xb0,0x2d,0x9d,0xdf,0xaf,0xbc,0x1a,0x3b,0x5d,0xef,0xaf,0xc8,0x30,0x3a,0x1e,0x2f,0x3c,0x36,0x1d,0xb6,0xf6,0x1f,0xbd,0x47,0x2a,0xae,0xb3,0xaf,0xe0 +,0xdd,0x2f,0x29,0x46,0xbf,0xad,0x27,0x57,0x25,0x35,0xbe,0xd2,0xaa,0x5f,0xb7,0x37,0x2f,0x9e,0xbc,0xb1,0xa1,0xa5,0xaa,0x94,0xab,0x2f,0xb4,0xc0,0xa7,0xa9,0xba,0x5b +,0x3a,0xbe,0xb0,0xc3,0x48,0x1e,0x2d,0xdd,0x3f,0x34,0x44,0x20,0x34,0x2f,0x5d,0x4f,0x22,0x37,0x2d,0xfe,0x38,0x39,0x21,0x2c,0x26,0xdc,0xbd,0x2e,0x3c,0x6c,0x6d,0x2d +,0xb2,0xda,0xb8,0xa9,0xa5,0x9e,0x7d,0xab,0x9e,0x97,0x9f,0xa1,0x9e,0xc1,0x9d,0xae,0x56,0xae,0xae,0xba,0xd1,0x6c,0x2a,0x42,0xca,0xe4,0xbf,0x2e,0x31,0x20,0x1f,0xcb +,0xb5,0x3e,0x34,0x60,0xbe,0xbc,0x27,0x2a,0x44,0x37,0xbc,0x33,0x19,0x33,0x36,0x28,0x30,0xa4,0xcd,0x38,0x47,0x1c,0x2a,0x2e,0xab,0xb7,0x34,0x43,0x2a,0x7c,0xaa,0xa0 +,0xb6,0xd3,0xd1,0x1f,0x50,0xa0,0xb1,0xd5,0xbf,0xea,0x52,0xd9,0xc0,0xad,0xae,0xd3,0x24,0x2c,0x47,0xba,0xb2,0x38,0x24,0xac,0xa4,0x2d,0xbe,0xdc,0x38,0x3c,0x2b,0x45 +,0x48,0xb2,0xbc,0x37,0x44,0x32,0xab,0x4b,0x36,0xdf,0x2a,0x4a,0xfb,0xcf,0x3c,0x62,0xaf,0x4d,0x3f,0x4f,0xbe,0xa7,0xb6,0xc9,0x58,0x24,0x31,0xaa,0xa1,0xac,0x61,0x40 +,0xd3,0xb9,0x41,0xd5,0xcf,0x6b,0x55,0x69,0x46,0x31,0x9d,0xa3,0x3f,0x2e,0xd0,0xac,0xbb,0xb9,0x3e,0x24,0x2f,0xe4,0xbe,0xd5,0xda,0xc2,0x56,0x37,0x21,0x54,0xaa,0x42 +,0x5e,0x35,0x68,0xbf,0x53,0xbe,0x36,0xed,0xb5,0xbf,0xbf,0xbe,0xbd,0xef,0x3e,0xc9,0xae,0xbf,0xb0,0xb6,0xc8,0x57,0xf7,0x3d,0x25,0xf0,0x5f,0xc1,0xbe,0x40,0xca,0xc4 +,0xbf,0xde,0xb1,0x35,0x3a,0xcb,0x2f,0x47,0xce,0x47,0x27,0x57,0x45,0xf4,0xfe,0x33,0x46,0x3d,0xe9,0x2b,0x38,0x37,0xbc,0xc8,0x48,0xab,0x7d,0xfb,0xf1,0xc0,0x3e,0x4a +,0xaf,0xb2,0x3d,0x42,0xc0,0xa7,0xa6,0x3c,0x28,0xdd,0xae,0xa7,0x43,0x2e,0x4f,0x6b,0xa2,0xde,0xd6,0x3e,0xc7,0x9f,0xc8,0xd0,0x2e,0x3d,0xd6,0x4b,0x67,0x3c,0x3d,0x2c +,0xc6,0x49,0x2b,0xc6,0xb8,0x2d,0x26,0x36,0x29,0x44,0xb3,0xa5,0xc8,0xe0,0xba,0xbc,0x3e,0x6b,0xc5,0xa8,0xaf,0x2a,0x2c,0xc7,0xa6,0xcf,0xca,0x7b,0x3e,0xc7,0xc0,0x56 +,0xc7,0x4a,0x38,0xcc,0xd3,0xae,0xc7,0x31,0xbe,0xaa,0x49,0x3a,0x4e,0x5e,0x34,0x2c,0x49,0x47,0x3e,0x55,0xe0,0x2f,0x48,0x4d,0x37,0x32,0x56,0x36,0x29,0xae,0x44,0x4c +,0xbc,0xc2,0xa9,0xbc,0x35,0x2f,0xdd,0xa9,0xb8,0xaa,0xbb,0x34,0xe6,0xbb,0xad,0xa6,0xbb,0x39,0x2e,0x2a,0xc8,0xbe,0xb9,0xc0,0x41,0x40,0x35,0xbf,0xb1,0xcb,0xbe,0x4b +,0xcc,0x3c,0x31,0xf4,0x49,0x44,0x6a,0xc9,0x5c,0x2e,0x5c,0x4a,0x1d,0x4b,0xca,0xc1,0x5e,0x4e,0x2c,0xd8,0xb7,0xb0,0xb3,0xb2,0xaa,0x34,0xd1,0xd8,0xbb,0x51,0xce,0xae +,0xb9,0x46,0x3d,0xcf,0xad,0x35,0x2b,0x3a,0xcc,0xed,0x29,0xcf,0x5a,0xbc,0x69,0xb6,0xbc,0xc9,0x43,0xb3,0xd7,0x53,0x3e,0x39,0xb3,0xba,0xbc,0x2d,0x31,0x3d,0xbf,0x1e +,0x2e,0x3c,0x50,0xc3,0x34,0x2b,0xbb,0xb4,0x50,0xa6,0xf8,0xb7,0xc2,0xd6,0xb7,0xc3,0x55,0xb1,0xc1,0xc0,0xac,0xc3,0x3c,0x22,0x42,0xb0,0xce,0xd1,0x38,0x1f,0x3f,0xbf +,0xc7,0x54,0xa8,0xbe,0x4e,0x3a,0xb9,0xad,0x28,0x4d,0xcc,0xbc,0xde,0x40,0xcf,0x2d,0x40,0xaf,0x2d,0x3a,0x67,0x23,0x2e,0xb4,0x6e,0x42,0xaf,0xb3,0xc1,0x29,0x51,0x9f +,0xa5,0xaf,0x3c,0xe3,0x26,0xb9,0x9d,0xcf,0xb2,0x5b,0x2c,0xae,0xab,0x2e,0x2b,0x23,0x57,0xcd,0x45,0x3f,0xaa,0x4d,0x2b,0xe0,0xbe,0xcb,0x39,0xaf,0x5f,0x37,0x48,0xde +,0xb0,0xfe,0x2c,0x46,0x6e,0xad,0xb0,0x39,0x2b,0x30,0x40,0xed,0xb2,0xb9,0xcb,0x4f,0xcb,0x48,0xc7,0xca,0xd2,0xac,0xbd,0xb4,0x29,0x26,0xbc,0xa4,0xb6,0x3d,0xaf,0xf7 +,0x36,0x36,0x55,0x3b,0x2e,0xb8,0xe3,0xe7,0x31,0x3b,0x36,0x70,0xac,0xcf,0xc6,0x34,0x78,0xbf,0x51,0xc6,0x3e,0x4e,0xab,0xbb,0x3a,0xbf,0xb5,0x22,0x6a,0x3c,0xcf,0xc3 +,0x21,0x4f,0xb1,0xab,0x4b,0xd9,0x2a,0xbe,0xd2,0x2a,0xa7,0xab,0xd1,0x2f,0x2e,0xd2,0x9d,0x9c,0x38,0x1e,0x2f,0x33,0xae,0xa8,0xbc,0x45,0x1c,0x44,0xa8,0xb6,0xbc,0xbd +,0x38,0x1f,0x29,0xa0,0xad,0x2f,0xec,0x4a,0xc3,0x44,0x2b,0xca,0xb7,0xaf,0x59,0x19,0x30,0xa6,0xa9,0x41,0x71,0x4b,0x27,0xae,0xac,0xad,0xe3,0x40,0x2d,0x69,0xa0,0x74 +,0x62,0x2b,0xbe,0xab,0x39,0xbe,0x4a,0xce,0xc5,0x65,0x2e,0x73,0x5e,0x3d,0x41,0xbe,0xa8,0x2b,0xbb,0xc0,0x3e,0xc8,0x2d,0x3b,0x41,0x41,0xad,0xc2,0xc2,0xc2,0x3a,0x29 +,0xb0,0xb4,0xbe,0x4e,0x37,0x53,0x1c,0xd2,0xb5,0xc0,0xbc,0xb2,0x6e,0x38,0xbe,0xbc,0x4b,0x2f,0x6d,0x56,0xc5,0xac,0xba,0x46,0x22,0xc3,0xb1,0x5b,0xb5,0x3a,0x2e,0x38 +,0x41,0x45,0xb5,0xaa,0xbf,0x52,0x5b,0x38,0x3a,0xbb,0xbb,0x34,0x7c,0x59,0x45,0x65,0xcb,0xac,0x51,0x41,0x5b,0xb4,0xe6,0x2d,0x2e,0xad,0x52,0x3c,0xb2,0xc7,0x3b,0x5f +,0xae,0xd3,0x4a,0xda,0x48,0x59,0xc8,0x2e,0xc8,0xaf,0x37,0x44,0xc0,0xee,0x9c,0x4d,0x20,0x2d,0xd0,0xa7,0x2e,0x42,0xfd,0xb2,0xbe,0x2d,0xa0,0x7c,0x26,0xa8,0x4c,0xb2 +,0x4f,0x2c,0x2d,0x59,0xa4,0xa4,0xb6,0x30,0xeb,0x2c,0x28,0x48,0xbb,0xdb,0x3a,0xb0,0x3c,0x28,0xda,0xcb,0x5c,0x46,0xfb,0xad,0x30,0x3f,0xc2,0x32,0xaf,0xbe,0xcc,0x4a +,0xd6,0xbb,0xd6,0xb8,0xc4,0x33,0x1f,0x34,0x9f,0xb9,0x4a,0x4e,0xc7,0xa3,0xb9,0x3f,0x24,0xd7,0xbe,0xb3,0xc2,0xd2,0x2e,0x2d,0xd1,0x5d,0xae,0xdd,0xbf,0x6c,0x2d,0x70 +,0x33,0xc0,0x47,0x39,0xb6,0x37,0xab,0x57,0x3f,0xdd,0xd7,0xcc,0x27,0xbe,0x31,0x3c,0xab,0x6c,0xdf,0xce,0xd3,0x3f,0x43,0xd7,0xbb,0x42,0xba,0x45,0x32,0x45,0xbf,0x9d +,0xbc,0xf8,0x3a,0xb4,0x37,0xbc,0xa9,0x6c,0xd9,0x1e,0xba,0xa5,0x40,0xbe,0x2f,0x26,0xaf,0xb7,0x34,0x6e,0x2a,0x2a,0x5a,0x43,0xbc,0x57,0xc9,0x4a,0x37,0x3a,0xab,0xbb +,0xd5,0xc6,0x33,0x4b,0x45,0xc1,0xc5,0xa6,0x3e,0x2f,0xba,0x71,0xbe,0x25,0x49,0xbc,0xae,0xb6,0xd9,0xb5,0x38,0xbe,0x3c,0xb8,0xb4,0xba,0x3d,0x33,0xb8,0xd6,0xbb,0x3c +,0x60,0x5a,0x3e,0x4f,0xe8,0x45,0xef,0xcb,0x43,0x3c,0x30,0x39,0xbb,0x3c,0xbe,0xae,0x44,0x34,0xc2,0xaf,0x2d,0x4f,0x6b,0xac,0xc7,0x3b,0x2c,0x44,0x7b,0xaf,0xae,0x2d +,0xcd,0x2a,0x4a,0xb4,0xba,0xed,0x2d,0xbc,0x9f,0xdf,0x6e,0xc9,0x79,0xd4,0x33,0xa4,0x5b,0x41,0xa7,0x23,0x4a,0xc7,0x33,0xcc,0xb8,0xd9,0x43,0x4e,0x33,0xbe,0x61,0x27 +,0x4b,0xdf,0xa9,0xb4,0x53,0xd2,0x3c,0x55,0x39,0x4d,0x5b,0xcd,0x3f,0x30,0xbd,0x68,0xca,0xc0,0x3f,0x3f,0xc5,0x30,0xe5,0x4a,0xcf,0x3d,0xdb,0xa5,0xc1,0xb5,0x4a,0x4a +,0x3b,0xca,0xb3,0xaf,0xda,0xd6,0x36,0x67,0x4c,0xb8,0xa7,0x67,0x49,0x2d,0xdf,0xbf,0x59,0x22,0x4b,0xac,0xb4,0xbb,0xc2,0x29,0x2a,0x6c,0xa8,0xb6,0x2b,0x47,0x34,0xe0 +,0x4e,0x37,0x37,0x56,0xc9,0xc1,0xe7,0x2f,0x34,0xb9,0xb4,0x2f,0x69,0xd5,0xe1,0x5b,0xad,0xea,0xc5,0xa0,0xda,0x37,0x33,0x46,0x3b,0x9f,0xc2,0x3f,0x52,0x3f,0xac,0xbb +,0xe5,0xbe,0xcb,0x2f,0x63,0x46,0x33,0x3f,0xb6,0xab,0xc1,0x29,0x4d,0xb5,0x51,0x48,0x27,0x52,0x2f,0xb6,0xb2,0x4a,0x58,0x1f,0xcb,0xb8,0xb8,0xd9,0x3f,0xc5,0x36,0x32 +,0x4b,0xcd,0xb8,0xba,0xdc,0xca,0xad,0x64,0x2e,0x33,0xaf,0xd4,0x3a,0xb5,0xa6,0xc3,0x2c,0xd7,0x3f,0x65,0xb3,0xaf,0xb3,0x3d,0x21,0x38,0xc4,0x3c,0xbf,0xb8,0xbe,0xd6 +,0x26,0xd9,0x39,0x5a,0x47,0x2a,0xa8,0x41,0xdb,0xb0,0x48,0xb4,0x3b,0x28,0xc0,0xb8,0xa1,0xdf,0x34,0x2d,0x44,0xb7,0x51,0xcb,0xd5,0xcf,0xc9,0x37,0x44,0x30,0x34,0xaa +,0x6d,0x65,0x3f,0x26,0xb2,0x9c,0xbd,0x3f,0x38,0x2b,0x33,0xa8,0xa5,0xa4,0xb3,0x35,0x73,0xad,0xa8,0xc0,0xaf,0xbe,0x4e,0xe0,0x3d,0x37,0x33,0x30,0x2d,0x3e,0xb2,0x34 +,0x2c,0x21,0x2c,0x3b,0x27,0x26,0x3d,0xc6,0x49,0x34,0x44,0xb5,0x2a,0xd6,0xa6,0xbe,0xb0,0xc0,0xbd,0xa6,0x9c,0x9f,0xab,0xa3,0xad,0xa8,0xae,0xa9,0xa9,0x2f,0x48,0x25 +,0x4d,0xc9,0x30,0x2e,0x21,0x22,0x25,0x29,0x27,0x32,0x32,0x29,0x28,0x54,0x1f,0x58,0xb8,0xc6,0xa3,0x3a,0xba,0xa7,0xab,0xa6,0xa9,0xc0,0xae,0xad,0xab,0xa2,0x9f,0xae +,0x44,0xec,0x26,0x2a,0xe0,0x3e,0x2b,0x21,0x26,0x26,0x20,0x2d,0x2e,0x33,0x2d,0x33,0x3d,0xde,0x4e,0x49,0xa3,0x31,0xbf,0x94,0x9e,0x91,0x9f,0x50,0xa5,0x9b,0x9c,0xb2 +,0x4e,0x7b,0x2c,0xcf,0x45,0x3c,0x30,0x29,0x22,0x17,0x22,0x15,0x1b,0x23,0x1d,0x1c,0x31,0x24,0xbf,0xbd,0x2b,0xa0,0xa6,0xb2,0x9f,0x8f,0x9e,0x98,0x93,0xa3,0x94,0x9b +,0xbe,0xab,0xa2,0x46,0x37,0x31,0x1c,0x1e,0x1b,0x22,0x28,0x1d,0x1c,0x10,0x21,0x15,0x1f,0x6f,0x15,0xaa,0xc7,0x4f,0xa4,0xa0,0xa1,0x9c,0x8f,0x9c,0x92,0x93,0xb8,0x98 +,0x93,0xcf,0xaa,0x5d,0x27,0x22,0x32,0x3d,0x29,0x2e,0x11,0x0d,0x1b,0x19,0x1d,0x1b,0x1e,0x6c,0x15,0x3a,0x9a,0x41,0xa4,0xa6,0x9e,0x95,0xad,0x8e,0x9c,0x9b,0x96,0x9c +,0x8f,0xbf,0xad,0xa0,0x3e,0x2c,0x1c,0x1a,0x20,0x1c,0x0f,0x1b,0x1b,0x0b,0x25,0x16,0x1c,0x1d,0x1a,0xbb,0x2a,0xab,0x9c,0xa0,0x94,0x97,0x94,0x8d,0x8e,0x98,0x9d,0x9e +,0x99,0xb9,0x28,0xbe,0x2e,0xd7,0xa7,0x40,0xd3,0x17,0x05,0x07,0x1f,0x96,0xa5,0x24,0x03,0x01,0x0a,0x13,0x8c,0x88,0xaa,0x9c,0x92,0x98,0x95,0x88,0x87,0x8f,0x8b,0x87 +,0x8f,0xab,0x1a,0x01,0x10,0x1b,0x96,0x8d,0xaf,0x1c,0x00,0x0c,0x26,0x8f,0x35,0x01,0x0b,0x0a,0x07,0x92,0x8f,0xa4,0xaa,0x3d,0x94,0x95,0x87,0x89,0x8a,0x9e,0x18,0x3d +,0x92,0x98,0x94,0x2a,0x02,0x14,0x23,0x1d,0x05,0x01,0x03,0xc1,0xcc,0x09,0x95,0xa4,0x13,0x91,0x81,0x84,0x80,0x88,0x9c,0x17,0x0f,0x9e,0x83,0x85,0xa8,0x06,0x0c,0x10 +,0x2a,0x92,0xd2,0x27,0x1d,0x0a,0x0e,0x0f,0x08,0xcc,0x10,0x03,0x1a,0x25,0x23,0x3f,0x1a,0x1a,0x9f,0x88,0x80,0x82,0x85,0xa6,0x92,0x83,0x89,0x8d,0x5a,0x0c,0x0d,0x0b +,0x2b,0xc8,0x1c,0x07,0x07,0x04,0x11,0xa8,0xb5,0x8a,0x2f,0x03,0x53,0x8d,0x8c,0x80,0x89,0xb5,0x9c,0x93,0x9a,0xb1,0x30,0x1c,0x21,0x43,0x0a,0x11,0xa6,0x10,0x11,0x3f +,0xbc,0x96,0xbf,0x06,0x0e,0x00,0x1a,0x83,0x9e,0x9b,0x2d,0x04,0x19,0x8f,0x83,0x82,0x88,0x90,0x9c,0x94,0x99,0x93,0x86,0xa1,0x0c,0x12,0x3a,0x38,0x26,0x05,0x04,0x07 +,0x0b,0x92,0xa6,0x42,0xa8,0x15,0x92,0x87,0x3c,0x98,0xa0,0x16,0xa9,0x8e,0x94,0x96,0xad,0x1c,0x09,0x23,0xa1,0x9c,0x95,0x18,0x01,0x0a,0x0f,0xba,0xa0,0xe9,0xa8,0x04 +,0x0e,0x8a,0x1f,0xf5,0x94,0x25,0x94,0x91,0x98,0x89,0x8b,0x92,0x95,0x86,0x8a,0x9c,0xba,0x08,0x00,0x11,0x2d,0xb9,0x1e,0x04,0x09,0x04,0x1f,0x88,0xab,0x8d,0x8f,0x0e +,0x8e,0x8c,0xba,0x81,0x85,0xc5,0x32,0x9c,0x93,0x8f,0xac,0x26,0x18,0xbf,0x9e,0x95,0x8e,0x33,0x1a,0x2f,0x22,0x0d,0x09,0x0b,0x0e,0x00,0x26,0x1b,0x02,0x34,0x0c,0x00 +,0x1c,0x5f,0x29,0x95,0x1c,0x00,0x08,0x13,0x2b,0xba,0xaa,0x13,0x03,0x0c,0x09,0x1c,0x3e,0x19,0x1b,0x0f,0x90,0x9d,0x9c,0x80,0x8a,0x8c,0x81,0x80,0x82,0x80,0x8a,0xa0 +,0x8a,0x85,0x85,0x85,0x94,0x0b,0x0c,0x4a,0xa0,0x8b,0x90,0x38,0x1a,0x27,0x44,0x2c,0x8d,0x89,0x0a,0xba,0x9d,0x6d,0x82,0x90,0x12,0x39,0x9d,0x2a,0x97,0x85,0x3a,0x12 +,0x1e,0x08,0x06,0x11,0x0c,0x00,0x03,0x00,0x06,0x0d,0x06,0x03,0x00,0x27,0x1b,0xdf,0x80,0x1a,0x0e,0xb1,0x44,0x8d,0x80,0x87,0x8d,0xa3,0x2e,0x15,0xab,0x91,0x22,0x2f +,0x27,0x02,0x0e,0xd8,0x3f,0x54,0x1b,0x15,0x24,0x8d,0x9c,0x00,0x2f,0x2e,0x09,0x8c,0x88,0xaf,0x95,0x87,0x8b,0x88,0x80,0x84,0x88,0x82,0x8b,0x8c,0x82,0x84,0x8c,0x90 +,0xd5,0xc6,0x8d,0x87,0x94,0x9a,0x89,0x14,0xab,0x80,0x92,0x8e,0x83,0xab,0x6c,0x9a,0x2d,0x1e,0x1c,0x0e,0x00,0x06,0x07,0x00,0x00,0x00,0x00,0x01,0x09,0x04,0x01,0x00 +,0x02,0x00,0x0f,0x17,0x06,0x97,0x17,0x00,0x1b,0x1b,0x21,0x93,0x91,0x2d,0xb1,0x95,0x9b,0x91,0x85,0x8f,0x90,0x85,0x89,0x9a,0x8d,0xb5,0x19,0x30,0x9c,0xb9,0xb1,0x84 +,0x1a,0x9e,0x80,0x8c,0x86,0x80,0x91,0x8e,0x80,0x84,0x84,0x83,0x89,0x52,0xb6,0x98,0x9c,0x8f,0x9c,0x18,0x0d,0x0d,0x13,0x18,0x26,0x28,0x06,0x23,0x15,0x01,0xa7,0x1d +,0x01,0xce,0x2a,0x0c,0x4b,0x29,0x0b,0x12,0xaa,0xa3,0x33,0x64,0x0f,0x00,0x0d,0x2e,0x13,0x2f,0x53,0x0d,0x03,0x08,0x0a,0x0a,0x94,0x10,0x04,0x9e,0x18,0x25,0x84,0x98 +,0xdb,0x89,0x95,0xb7,0x95,0x9c,0x31,0x1a,0x1d,0x1b,0x16,0x33,0xbf,0x33,0x9d,0x8e,0x9c,0x93,0x88,0x9d,0x8f,0x81,0x97,0x85,0x80,0x8f,0x8d,0x80,0x88,0x81,0x80,0x81 +,0x84,0x87,0x88,0xa0,0x8f,0x86,0x9e,0x3a,0x4c,0x0b,0x04,0x06,0x04,0x00,0x03,0x04,0x00,0x03,0x04,0x00,0x0d,0x13,0x00,0x19,0x1b,0x00,0x09,0x19,0x0a,0x0d,0x1e,0x1c +,0x10,0x13,0x16,0x07,0x0f,0x48,0x1a,0x18,0x37,0x0f,0x17,0xd0,0x9a,0xea,0x8b,0x90,0x1f,0x83,0x82,0x94,0x86,0x87,0xa6,0x8a,0x81,0x84,0x84,0x84,0x89,0x8d,0x87,0x93 +,0xb0,0xc0,0xa9,0xad,0xa1,0x9e,0xcb,0x2a,0x51,0xa6,0xa7,0x87,0x88,0xc2,0x98,0x98,0x18,0x9a,0x88,0x69,0x9d,0xa5,0x11,0x14,0x1e,0x23,0x19,0x1b,0x11,0x07,0x09,0x07 +,0x08,0x0b,0x16,0x09,0x0a,0x08,0x08,0x02,0x08,0x1f,0x03,0x26,0x8f,0x15,0x1b,0x97,0x1d,0xac,0x8e,0xed,0xdc,0x75,0x3f,0x23,0x1e,0x5f,0x29,0x0e,0x0e,0x1b,0x20,0x38 +,0x25,0x1c,0x0d,0x0d,0x13,0x23,0x85,0xab,0x9d,0x80,0x8c,0x8c,0x80,0x86,0x89,0x80,0x82,0x81,0x81,0x81,0x84,0x85,0x81,0x81,0x85,0x83,0x83,0x93,0x9a,0x98,0xac,0xa7 +,0xc9,0x1a,0x04,0x19,0x13,0x00,0x33,0x1e,0x02,0x17,0x0d,0x00,0x09,0x0c,0x04,0x09,0x0b,0x09,0x07,0x03,0x04,0x00,0x01,0x0a,0x08,0x09,0x1d,0x0a,0x02,0x0e,0x2a,0x09 +,0x21,0xae,0x07,0xb1,0x8f,0x1e,0x9a,0x87,0xb3,0x92,0x85,0x8a,0x88,0x87,0x89,0x8d,0x95,0x8b,0x93,0x9a,0x8d,0x8a,0x92,0x8c,0x8c,0x9d,0xa3,0x9f,0xab,0x40,0x85,0xa8 +,0x5c,0x80,0x95,0xbd,0x83,0x82,0x8c,0x85,0x89,0x9c,0x9b,0x9a,0x99,0x78,0x1b,0x39,0x07,0x0f,0x46,0x15,0x13,0x15,0x0e,0x0c,0x0f,0x0e,0x00,0x10,0x14,0x01,0x3e,0xad +,0x09,0x18,0x3a,0x09,0x1e,0xab,0x52,0x2a,0x49,0x3e,0x28,0x66,0xbf,0x15,0x0d,0x17,0x17,0x0c,0x0f,0x19,0x10,0x0a,0x1c,0x14,0x0c,0x9d,0x15,0x1c,0x8f,0x22,0x29,0x8b +,0xad,0x9b,0x82,0x88,0x85,0x87,0x86,0x88,0x8a,0x84,0x84,0x8c,0x86,0x82,0x88,0x87,0x83,0x82,0x84,0x82,0x88,0x94,0x82,0xa2,0xb0,0x84,0x2c,0x23,0x8b,0xbc,0x17,0x33 +,0x15,0x14,0x29,0x1f,0x12,0x03,0x03,0x02,0x01,0x02,0x04,0x01,0x01,0x02,0x03,0x01,0x03,0x06,0x00,0x1d,0x0e,0x05,0x9e,0x20,0x0b,0xa5,0x42,0x1b,0xac,0xb2,0x2f,0x3d +,0xb6,0x9b,0xa7,0xa9,0x96,0xac,0x9f,0x85,0x8e,0x94,0x8f,0x9f,0xbc,0x95,0xa8,0xb8,0x81,0x50,0xc5,0x80,0x93,0xa1,0x84,0x8f,0x8c,0x80,0x87,0x8a,0x88,0x89,0x89,0x93 +,0x92,0x89,0xbe,0x22,0x30,0x18,0x23,0x4f,0x13,0x0c,0x23,0x08,0x12,0x8b,0x0f,0x1f,0x90,0x09,0x12,0x9b,0x0d,0x0e,0x1f,0x07,0x0f,0x11,0x14,0x16,0x0a,0x14,0x25,0x10 +,0x22,0x33,0x0f,0x1a,0x2b,0x0c,0x17,0x17,0x00,0x27,0x13,0x02,0xae,0x2e,0x0b,0x9b,0xf2,0x14,0x91,0x97,0xa7,0x9c,0x9f,0xa1,0xa4,0x28,0x62,0x48,0x29,0xa5,0xa3,0xa5 +,0x8c,0x8b,0x8f,0x84,0x8c,0x85,0x80,0x89,0x81,0x80,0x86,0x83,0x80,0x83,0x81,0x81,0x8f,0x9e,0x99,0x98,0xa1,0x4b,0x1f,0x0f,0x0b,0x0f,0x0f,0x0c,0x09,0x06,0x02,0x02 +,0x00,0x03,0x07,0x00,0x04,0x0b,0x00,0x09,0x1e,0x01,0x09,0x25,0x18,0x14,0x30,0x49,0x15,0x0e,0x28,0x19,0x09,0x1c,0x1b,0x0a,0x0e,0x1c,0x12,0xbb,0x13,0x9f,0x8c,0x19 +,0x85,0x80,0x9a,0x8c,0x80,0x94,0x8a,0x83,0x89,0x89,0x96,0x8a,0x8e,0xba,0x8e,0x96,0xe4,0x8c,0x88,0x9a,0x95,0xb9,0xbe,0xb9,0x2b,0x80,0x9b,0x2e,0x84,0xa4,0x16,0x8c +,0x95,0x2a,0x9b,0x9d,0xa5,0xde,0x9f,0x98,0x2c,0x1d,0xb5,0x1a,0x0e,0x23,0x0d,0x02,0x04,0x00,0x07,0x00,0x07,0x39,0x01,0x0c,0x8e,0x17,0x15,0x86,0x35,0x21,0x9b,0x5a +,0x3a,0x35,0x25,0x23,0x07,0x0c,0x21,0x0e,0x0f,0x1d,0x09,0x0a,0x16,0x2f,0x29,0x0d,0x90,0x2c,0x0b,0x8b,0x93,0x23,0x88,0x90,0xc3,0x87,0x84,0x84,0x85,0x83,0x81,0x82 +,0x81,0x80,0x82,0x84,0x81,0x80,0x86,0x85,0x86,0x91,0x1a,0x8b,0x99,0x09,0x8b,0x91,0x0b,0xb3,0xab,0x10,0x39,0x42,0x1b,0x0d,0x09,0x11,0x05,0x00,0x08,0x04,0x00,0x04 +,0x03,0x00,0x02,0x04,0x02,0x00,0x2b,0x11,0x05,0xa4,0xd2,0x0d,0xb3,0xb5,0x1e,0xce,0x45,0xb5,0x1b,0x36,0x9c,0x2a,0x25,0x90,0xac,0x71,0x88,0x95,0x99,0x99,0x8e,0x3c +,0xad,0x80,0x37,0x9f,0x80,0x9a,0xa3,0x82,0x8f,0x8f,0x89,0x89,0x88,0x8f,0x85,0x85,0xb7,0x98,0x84,0xa4,0x8f,0x92,0x5f,0x1d,0x2c,0x2a,0x0b,0x8f,0xb9,0x0c,0x9a,0x3a +,0x09,0xcd,0xd2,0x16,0x4d,0x2d,0xc3,0x1c,0x15,0x22,0x08,0x07,0x1d,0x11,0x0a,0x15,0x10,0x05,0x0f,0x1c,0x04,0x41,0x60,0x03,0xa3,0x8c,0x1e,0xac,0x90,0xce,0x36,0xab +,0x9c,0x2d,0x38,0x5e,0x16,0x13,0xaf,0x3a,0x1b,0xfa,0xdd,0x2b,0x2b,0xa7,0x0e,0x98,0x8b,0x17,0x92,0x83,0xca,0xa3,0x8b,0xa0,0xa9,0xa0,0x92,0xab,0xad,0x93,0x96,0x29 +,0x9f,0xa3,0x24,0xba,0xa5,0x29,0x12,0x1f,0x08,0x98,0x8e,0x19,0x8f,0x8a,0xb3,0x8e,0x83,0x91,0x9e,0x90,0x93,0x47,0x22,0xf4,0x20,0x07,0x1d,0x1f,0x0a,0x19,0xb8,0x0f +,0x22,0x45,0x0e,0x8a,0x9f,0x21,0x80,0x91,0x1c,0x8c,0x94,0x36,0xaf,0xd2,0xdd,0x27,0x13,0xda,0x22,0x06,0xce,0x22,0x08,0x11,0x0f,0x06,0x18,0x06,0x05,0xda,0x02,0x0e +,0x93,0x15,0x0c,0x9e,0x37,0x36,0x99,0xa0,0xac,0x28,0x3e,0x90,0x57,0x4e,0x95,0x1d,0x19,0x5f,0x1a,0x13,0xbd,0x08,0x9a,0x8a,0x2a,0x82,0x81,0x9d,0x8b,0x80,0x8b,0x81 +,0x84,0x85,0x8a,0xa9,0x96,0x8d,0x24,0x9e,0x9a,0x20,0xae,0xab,0x13,0x1c,0x0f,0x08,0x89,0x12,0x07,0x8f,0x2c,0x00,0xaf,0xdc,0x13,0x28,0x24,0x1f,0x1e,0x32,0xfc,0x1f +,0x10,0xa1,0x1c,0x0d,0x27,0x1c,0x01,0x0d,0x05,0xcb,0x99,0x00,0xce,0x8e,0x12,0xbd,0x87,0x3b,0x3c,0x6c,0xa1,0xcb,0x1e,0x2f,0x39,0x0a,0xe1,0xa7,0x1f,0xc3,0xac,0x1c +,0x22,0x2a,0x22,0x82,0x1f,0x2b,0x80,0x9d,0x1f,0x88,0x95,0x3f,0xab,0x99,0x8c,0xa0,0xad,0x8c,0x98,0x9e,0x83,0x90,0xa5,0x8a,0x8a,0x9f,0x8e,0xc6,0x89,0x89,0x30,0x8a +,0x80,0x4c,0x99,0x8b,0x1e,0xc8,0xc8,0x12,0x07,0x06,0x05,0x07,0x00,0x03,0x01,0x01,0x00,0x02,0x00,0x02,0x00,0x02,0x2d,0x08,0x09,0x8f,0x37,0x0d,0x94,0xa3,0xaa,0x9c +,0x9b,0xa9,0xd8,0x58,0x94,0x9d,0xac,0x89,0x8f,0x8f,0x81,0x89,0x8e,0x87,0x8f,0x80,0x83,0x8a,0x80,0x80,0x8d,0x87,0x80,0x85,0x85,0x83,0x84,0x8b,0x96,0x92,0x8f,0x23 +,0x23,0x7c,0x0f,0x0b,0x1a,0x03,0x05,0x00,0x07,0xe0,0x06,0x03,0xaf,0x20,0x07,0xa7,0x32,0x0c,0x15,0x18,0x14,0x10,0x0b,0x16,0x07,0x01,0x0c,0x0b,0x05,0x08,0x0b,0x07 +,0x0d,0x01,0xb0,0x6c,0x04,0x9f,0x89,0x1b,0x33,0x93,0x53,0xc4,0x9c,0x90,0x9c,0xaf,0x97,0x8e,0x4e,0x9f,0x92,0xaf,0x1f,0x3c,0x1d,0x10,0x04,0x08,0x9c,0x0d,0x09,0x8e +,0x92,0x1a,0x8a,0x85,0x85,0x80,0x83,0x82,0x83,0x81,0x81,0x80,0x83,0x80,0x83,0x88,0x86,0x80,0x8f,0x8d,0x4d,0x94,0x83,0x0f,0x1c,0x8e,0x16,0x03,0x2b,0x09,0x02,0x01 +,0x01,0x01,0x01,0x01,0x03,0x00,0x00,0x04,0x05,0x02,0x06,0x05,0x00,0x05,0x00,0x31,0x22,0x00,0x1b,0x9d,0x05,0x17,0x9b,0x15,0x37,0x9d,0x95,0x8b,0x9e,0x94,0x81,0x95 +,0x8d,0x81,0x85,0x91,0x88,0x92,0x98,0x8d,0x9e,0x80,0x94,0xbe,0x80,0x84,0xae,0x87,0x84,0xa5,0x91,0x95,0x9c,0xbb,0x10,0x39,0x4e,0x0a,0x23,0x30,0x1a,0x12,0x3e,0x1a +,0x32,0x1a,0x0e,0x8d,0x1e,0x14,0x86,0x99,0x0b,0x9a,0xa3,0x1d,0xb7,0xbc,0xc4,0x57,0x29,0x9d,0x9d,0x0e,0x45,0xab,0x20,0x1f,0x27,0x04,0x0e,0x07,0x0d,0x8b,0x0f,0x0e +,0x85,0xa3,0x0e,0x90,0x9e,0x2b,0x31,0x27,0x42,0x1c,0x06,0x0d,0x16,0x04,0x15,0x0d,0x08,0x0a,0x1e,0x17,0x52,0x27,0xb8,0x80,0x9b,0x8a,0x80,0x85,0x8a,0x80,0x80,0x81 +,0x80,0x82,0x81,0x83,0x86,0x80,0x86,0xb7,0x93,0x98,0x27,0x2b,0x14,0x00,0x05,0x00,0x06,0x1d,0x02,0x00,0x1f,0x0f,0x00,0x18,0x0a,0x05,0x11,0x06,0x0d,0x15,0x02,0x0c +,0x0e,0x00,0x16,0x1a,0x0c,0x18,0x13,0x0e,0xd6,0x07,0x12,0x85,0x29,0x4f,0x80,0x8e,0x2b,0x8b,0x8a,0x8f,0x88,0x8c,0x84,0x86,0x8f,0x85,0x80,0x94,0x8b,0x85,0x8f,0x8e +,0x9d,0x45,0x98,0x0e,0x0d,0x85,0x24,0x0f,0x83,0x8f,0x33,0x8c,0x8c,0x94,0x8e,0xa6,0x8f,0x8e,0x30,0xa3,0x9e,0x0b,0x1a,0xae,0x23,0x15,0x16,0x0d,0x15,0x08,0x04,0xa2 +,0x13,0x00,0xa6,0xbc,0x07,0x15,0x1c,0x0b,0x12,0x0b,0x0d,0x16,0x0a,0x0e,0x2d,0x23,0x24,0xad,0x28,0x1d,0x29,0x22,0x24,0x10,0x00,0x28,0xaf,0x00,0x29,0x95,0x0d,0x17 +,0x7d,0xca,0x99,0xab,0xad,0x8b,0x9a,0x98,0x80,0x88,0x86,0x82,0x84,0x82,0x81,0x81,0x83,0x80,0x89,0x85,0x80,0x84,0x84,0x80,0x88,0x8f,0x86,0x9a,0xaa,0x24,0x06,0x0d +,0x07,0x02,0x08,0x02,0x00,0x05,0x03,0x04,0x07,0x02,0x00,0x04,0x02,0x00,0x18,0x0f,0x00,0x11,0x2d,0x0c,0x1b,0x3b,0x1e,0x2a,0x22,0xbb,0x9b,0x1f,0x2b,0x96,0xb3,0xa7 +,0xa8,0xa5,0x9a,0xc8,0xb2,0x9e,0x9b,0x1c,0x95,0x80,0x9d,0x8b,0x80,0x8a,0x97,0x86,0x86,0x8b,0x9d,0x9f,0x89,0xe6,0x1c,0x90,0xa0,0x2c,0xad,0xa5,0xad,0x6f,0x58,0x3b +,0xca,0x0d,0x12,0x87,0x29,0x0d,0x93,0xa2,0x16,0x51,0xc3,0x28,0x2c,0x1a,0xbf,0xcc,0x18,0x2a,0x29,0x0f,0x3c,0xd8,0x14,0x19,0x17,0x06,0x0b,0x07,0x02,0x9f,0x2a,0x02 +,0x98,0x88,0x22,0xca,0x93,0x4b,0x51,0x27,0x32,0xbd,0x0f,0x0c,0x1c,0x0a,0x0d,0x19,0x08,0x0e,0x11,0x0d,0x0f,0x1c,0x04,0xc8,0x87,0x28,0x88,0x80,0x87,0x88,0x80,0x82 +,0x80,0x80,0x81,0x80,0x81,0x81,0x81,0x80,0x84,0x84,0x8e,0x8a,0x9e,0x1d,0x0a,0x07,0x00,0x02,0x1b,0x07,0x00,0x0d,0x0a,0x07,0x15,0x06,0x0b,0x0c,0x01,0x0c,0x1a,0x09 +,0x09,0x0d,0x06,0x07,0x0a,0x1a,0x10,0x0c,0x08,0x13,0x15,0x05,0x98,0xae,0x0d,0x8d,0x85,0xa0,0x94,0x97,0x96,0x8a,0xa2,0x8f,0x83,0x96,0x8f,0x82,0x8a,0x89,0x8b,0x8d +,0x87,0x98,0xcb,0xa4,0xbd,0x06,0xa9,0x8d,0x15,0x97,0x84,0xa5,0xa1,0x96,0x92,0x86,0x9e,0xb9,0x8b,0xa6,0x34,0x99,0xc6,0x22,0x24,0x25,0x33,0x11,0x0d,0x15,0x12,0x00 +,0x28,0x89,0x0b,0x1b,0x8c,0xbd,0x1d,0x46,0x29,0x2c,0x15,0x08,0x42,0x22,0x09,0x1b,0x19,0x0a,0x1f,0x28,0x27,0x1a,0x0b,0x0b,0x18,0x02,0x0f,0x96,0x0c,0x0e,0xa3,0x23 +,0x14,0x28,0x16,0xd7,0x3b,0x27,0x9a,0xaa,0x21,0x92,0x8b,0x96,0x89,0x8a,0x85,0x86,0x8d,0x8a,0x80,0x8c,0x88,0x80,0x83,0x82,0x80,0x83,0x85,0x83,0x85,0x87,0x92,0x38 +,0x28,0x13,0x02,0x0b,0x07,0x02,0x03,0x01,0x02,0x03,0x02,0x00,0x04,0x00,0x05,0x1d,0x05,0x03,0x29,0x0c,0x09,0x16,0x0c,0x2d,0x19,0x0e,0xb9,0x5c,0x1c,0xa2,0xa8,0x2d +,0x9e,0xb8,0x9b,0x95,0x2d,0x1b,0xb9,0x18,0x9e,0x81,0x5f,0x8c,0x80,0x8d,0x8b,0x80,0x8a,0x84,0x87,0x95,0x83,0x8b,0xa1,0x90,0x9a,0xa8,0xa3,0xbc,0x9f,0xa8,0x0b,0x18 +,0x9c,0x0f,0x9c,0x8c,0x17,0x94,0x89,0x1a,0x9d,0x9a,0x10,0xc3,0x1f,0x0e,0xc5,0x2d,0x14,0xad,0x30,0x1b,0x25,0x1b,0x28,0x1a,0x07,0x0e,0x0b,0x00,0xc1,0x22,0x00,0xa8 +,0xb2,0x07,0xd7,0x3c,0x1a,0xae,0x1e,0x16,0xbf,0x24,0x1e,0xa9,0x1f,0x0f,0x17,0x17,0x19,0x0d,0x02,0x0f,0x03,0x0c,0x90,0x1d,0x28,0x82,0x98,0xbe,0x84,0x8c,0x87,0x81 +,0x8b,0x87,0x81,0x85,0x80,0x81,0x81,0x81,0x80,0x81,0x83,0x8a,0x92,0x8f,0x1f,0x8e,0x90,0x0b,0x22,0x74,0x07,0x06,0x09,0x02,0x09,0x03,0x01,0x0d,0x0a,0x00,0x0a,0x0a +,0x07,0x0b,0x09,0x0a,0x09,0x00,0x07,0x06,0x08,0xcc,0x10,0x10,0x8e,0xab,0x30,0x91,0x50,0x56,0x97,0x6c,0xb2,0x8e,0x29,0xcc,0x94,0xac,0xad,0x9b,0x8c,0x8c,0xac,0xa9 +,0x8f,0x3f,0x8b,0x88,0x9a,0x85,0x80,0x95,0x92,0x8b,0xc0,0x92,0x99,0xfc,0x9b,0xa1,0x4b,0x93,0x99,0xa9,0x98,0xb7,0xdc,0xa3,0x13,0x1f,0x19,0x0f,0x9c,0x2d,0x17,0x8b +,0xa1,0x16,0x9a,0x67,0xc9,0xa7,0x1c,0x1d,0xb6,0x0d,0x18,0x37,0x11,0x13,0x0d,0x0c,0x0c,0x03,0x04,0x09,0x04,0xbe,0x4d,0x0d,0xb4,0x98,0x1c,0x1e,0x2b,0x17,0x22,0x15 +,0x15,0x1e,0x0d,0x0d,0x1a,0x0f,0x14,0x1c,0x26,0xaf,0x15,0x13,0x95,0x84,0x1e,0x1c,0x80,0x83,0x80,0x83,0x88,0x82,0x89,0x80,0x8a,0x81,0xab,0x19,0xcb,0x03,0x19,0x08 +,0x00,0x04,0x00,0x02,0x00,0x01,0x00,0x02,0x09,0x04,0x00,0x15,0x19,0x0b,0x3c,0x56,0x3b,0x2d,0x9a,0x80,0x87,0x92,0x88,0x80,0x80,0x80,0x80,0x81,0x82,0x86,0x87,0x80 +,0x86,0x80,0x85,0x87,0x81,0x80,0x88,0x8a,0x87,0x89,0x83,0x98,0x9c,0x8b,0xab,0x34,0xca,0x20,0x17,0x15,0x0f,0x08,0x05,0x00,0x03,0x00,0x06,0x0a,0x00,0x01,0x03,0x02 +,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01,0x02,0x02,0x03,0x07,0x06,0x0a,0x00,0x09,0x08,0x0e,0x93,0x18,0x2f,0x8c,0x8c,0xa1,0x8b,0x89,0x85,0x80,0x87,0x82 +,0x81,0x84,0x82,0x80,0x82,0x80,0x82,0x80,0x82,0x83,0x82,0x81,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x86,0x8b,0x80,0x84,0x85,0x81,0x81,0x84,0x86 +,0x81,0x84,0x87,0x9b,0x9a,0xb2,0x88,0x8a,0x21,0xf0,0x98,0x16,0x07,0x09,0x03,0x06,0x00,0x01,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x02,0x00,0x00,0x06,0x07,0x00,0x02,0x00,0x04,0x03,0x00,0x01,0x04,0x01,0x01,0x07,0x0c,0x09,0x06,0x0b,0x2f,0x0e,0x03,0x0e,0x15,0x8f,0xaa,0xc6,0x87,0x83,0x8d,0x8f +,0x8a,0x8a,0x88,0x93,0x92,0x82,0x85,0x8e,0x8b,0x84,0x85,0x86,0x8b,0x89,0x85,0x94,0x8f,0x8a,0x81,0x81,0x85,0x80,0x80,0x81,0x81,0x80,0x81,0x81,0x82,0x85,0x83,0x84 +,0x8b,0x84,0x87,0x82,0x84,0x8e,0x8c,0x83,0x97,0xbc,0xb4,0x90,0x80,0x9d,0x8f,0x80,0x85,0x91,0x88,0x8a,0x88,0x87,0x8f,0x8d,0x84,0x8a,0x90,0x9a,0x69,0x9b,0x9d,0x11 +,0x0b,0x05,0x01,0x02,0x00,0x2c,0x29,0x04,0x18,0x8c,0xba,0x47,0x51,0x9b,0x8b,0xa7,0x3f,0x95,0x9e,0x1d,0x37,0x47,0x74,0x1a,0x0c,0x0b,0x21,0x08,0x03,0x00,0x1a,0x1d +,0x01,0x08,0x1f,0x0e,0x00,0x03,0x01,0x08,0x00,0x01,0x00,0x04,0x01,0x00,0x01,0x02,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x07,0x01,0x00,0x03,0x09,0x02,0x02,0x00 +,0x03,0x05,0x01,0x00,0x07,0x08,0x01,0x04,0x05,0x0f,0x0b,0x07,0x09,0x0f,0x0c,0x0d,0x07,0xbe,0x8a,0xd9,0x9f,0x85,0x84,0x8d,0x8a,0x87,0x80,0x81,0x82,0x81,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x82,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82 +,0x80,0x82,0x84,0x93,0x8d,0x80,0x97,0x2c,0xb2,0xbb,0x06,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x06,0x09 +,0x00,0x00,0x07,0x06,0x04,0x04,0x00,0x05,0x06,0x03,0x02,0x08,0x07,0x05,0x02,0x08,0x1c,0x12,0x05,0x0d,0x0f,0x15,0x15,0x0c,0x9a,0x9a,0x2b,0xa6,0x8c,0x9d,0xba,0x2c +,0x27,0x93,0x9b,0x35,0xce,0x97,0x8e,0x90,0xb3,0x99,0x8b,0x97,0xa8,0x96,0xa4,0xad,0xf8,0xae,0x81,0x8a,0x9a,0x8a,0x85,0x89,0x86,0xa2,0xac,0x8d,0x92,0xd1,0xcd,0xad +,0xab,0x47,0x10,0x58,0x99,0x5c,0x1e,0x25,0xd5,0x9a,0x16,0x24,0x88,0x9d,0x37,0x97,0x93,0xa9,0x29,0x07,0x18,0xb0,0x1e,0x0c,0x21,0xb2,0xa5,0x1e,0x1f,0x8f,0x87,0x8d +,0x8c,0x8c,0x8d,0x8b,0x8e,0x84,0x80,0x83,0x84,0x80,0x81,0x81,0x8a,0x9b,0x97,0x97,0x2d,0x12,0x13,0x06,0x04,0x02,0x01,0x04,0x06,0x02,0x02,0x03,0x09,0x0a,0x03,0x20 +,0xac,0x3e,0xc1,0x95,0x9f,0xa1,0xb8,0x41,0x94,0x91,0xb2,0xa6,0x8f,0x90,0x8f,0xa7,0xa5,0x8e,0x8f,0x95,0x9b,0x3f,0xb2,0xad,0x63,0x8b,0x8b,0x95,0x8d,0x84,0x86,0x88 +,0xa0,0xa2,0x8a,0x8f,0xa6,0xa7,0xb0,0xa9,0x9d,0x3c,0xcb,0xa5,0xba,0xb5,0xc0,0x1c,0xe3,0x1f,0x1c,0x9b,0xae,0x3b,0x5b,0xdd,0xa7,0xa4,0x16,0x1e,0xae,0xc8,0x28,0x1d +,0x1c,0x32,0x18,0x08,0x18,0x1c,0x0b,0x06,0x07,0x08,0x0b,0x01,0x07,0xd9,0x48,0x1a,0x57,0xb8,0xa8,0xf1,0x0c,0x20,0x7e,0x15,0x12,0x1b,0x13,0x0f,0x0a,0x08,0x18,0x1b +,0x14,0x14,0x0b,0x0a,0x1b,0x16,0xbe,0x88,0x8c,0x88,0x82,0x82,0x81,0x80,0x81,0x80,0x80,0x80,0x81,0x82,0x83,0x82,0x87,0x9e,0xaf,0x48,0x21,0x15,0x06,0x02,0x03,0x00 +,0x03,0x0c,0x08,0x06,0x0a,0x08,0x10,0x13,0x05,0x0a,0x14,0x0f,0x15,0x18,0x10,0x1b,0x1f,0x26,0x39,0x24,0x26,0x46,0x1b,0x11,0x1e,0x10,0x0e,0xbc,0xd1,0xcb,0x9e,0xaf +,0x9d,0x8f,0x98,0x94,0x88,0x8e,0x8f,0x8e,0x96,0x8e,0x8d,0xb8,0xa9,0x9c,0x9c,0x97,0xbf,0x30,0xb1,0xb5,0x3b,0x94,0x93,0xa7,0x95,0x92,0x99,0x99,0xbb,0xb1,0x9a,0xef +,0xb9,0x9a,0xdb,0x46,0xa2,0xa4,0xbf,0x26,0x1a,0x30,0x2e,0x0f,0x09,0x07,0x06,0x05,0x07,0x10,0x16,0x0f,0x09,0x12,0xea,0x2c,0x1a,0x30,0x79,0x43,0x24,0x1f,0x29,0x27 +,0x1a,0x20,0x26,0x15,0x16,0x15,0x17,0x1c,0x1a,0x0f,0x0d,0x1d,0x37,0x62,0xba,0xae,0x9c,0x8c,0x8b,0x88,0x83,0x83,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x82,0x85 +,0x8e,0x9d,0xc5,0x29,0x16,0x09,0x09,0x08,0x06,0x0a,0x06,0x02,0x04,0x07,0x06,0x07,0x07,0x07,0x0a,0x0a,0x0c,0x10,0x0f,0x0f,0x17,0x23,0x2d,0x2c,0x27,0x18,0x15,0x16 +,0x1c,0x16,0x0f,0x21,0x2c,0x3a,0xf0,0x3b,0xf4,0x9f,0x94,0x8c,0x8e,0x8f,0x8e,0x8e,0x8f,0x90,0x96,0x9c,0x9a,0x92,0x91,0x9e,0xab,0xa3,0x9a,0x9f,0xae,0x9d,0x9c,0xb1 +,0xac,0xa4,0xa5,0xba,0x58,0xa2,0x96,0xad,0xc5,0xa4,0x92,0x92,0xa8,0xab,0x9e,0xa2,0xba,0x4d,0x32,0x1e,0x17,0x17,0x19,0x18,0x0f,0x0f,0x17,0x19,0x0e,0x0c,0x10,0x1b +,0x1e,0x1b,0x17,0x0f,0x14,0x17,0x1c,0x2b,0x38,0x2e,0x28,0x33,0x33,0x1c,0x1a,0x26,0x23,0x1f,0x1a,0x11,0x0d,0x0f,0x17,0x1e,0x31,0xc5,0xb2,0x97,0x8a,0x88,0x86,0x84 +,0x81,0x81,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x87,0x8d,0x8e,0x93,0xae,0x1e,0x0f,0x0f,0x0c,0x07,0x04,0x02,0x01,0x01,0x01,0x03,0x03,0x04,0x05,0x0c,0x14,0x12 +,0x15,0x15,0x1e,0x37,0x35,0x47,0x2f,0x24,0x28,0x2c,0x3d,0x4d,0x3b,0x35,0xbc,0xaf,0xb4,0xba,0xb8,0xb4,0xaf,0xa7,0x9d,0xa6,0x48,0xb4,0x9d,0x9f,0xaf,0x9b,0x90,0x90 +,0x8f,0x8d,0x8d,0x91,0x95,0x8e,0x8d,0x8f,0x9d,0xb6,0xa1,0xab,0xba,0xb7,0xac,0xbd,0xae,0xa4,0xa8,0xad,0xaf,0xcf,0x4b,0xb1,0xb0,0x35,0x29,0x2d,0x22,0x1d,0x1f,0x2e +,0x1e,0x27,0x34,0x27,0x1a,0x10,0x10,0x18,0x1c,0x1a,0x13,0x0d,0x0f,0x13,0x1a,0x1d,0x1f,0x1f,0x31,0x39,0x29,0x23,0x1e,0x1d,0x28,0x29,0x17,0x0d,0x0c,0x11,0x17,0x13 +,0x18,0x1e,0x2e,0xa8,0x9d,0x8f,0x88,0x87,0x84,0x82,0x81,0x82,0x81,0x80,0x80,0x81,0x81,0x82,0x82,0x82,0x86,0x8d,0x96,0xa8,0x33,0x14,0x0d,0x06,0x02,0x03,0x02,0x02 +,0x03,0x01,0x03,0x08,0x07,0x06,0x0b,0x0d,0x0e,0x15,0x18,0x1b,0x15,0x1f,0x2d,0x28,0x26,0x37,0x4e,0xbc,0xac,0xc3,0xa8,0xaa,0xdb,0xa5,0x9c,0xb8,0xca,0xc4,0xbc,0xac +,0xb5,0xbc,0x9e,0x9e,0x9a,0x96,0x97,0x92,0x98,0x9d,0x96,0x93,0x9f,0xab,0xac,0xb0,0xa1,0xa8,0xa6,0x9b,0x9f,0x9d,0x98,0x9e,0xa8,0xa5,0xaa,0xa1,0xa6,0xc7,0x39,0x3b +,0x5a,0xc8,0xe8,0x3f,0x3c,0x2a,0x30,0x51,0x3a,0x2d,0x28,0x1f,0x28,0x22,0x16,0x0f,0x15,0x17,0x16,0x13,0x11,0x19,0x1b,0x22,0x2e,0x2a,0x1f,0x18,0x17,0x22,0x20,0x15 +,0x0d,0x0c,0x0c,0x0c,0x0b,0x0e,0x11,0x12,0x1c,0x2b,0x2e,0x31,0xbe,0xa3,0x94,0x89,0x87,0x87,0x84,0x82,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x84,0x86,0x89,0x8d +,0x96,0xaf,0x1f,0x10,0x09,0x08,0x06,0x04,0x03,0x03,0x06,0x07,0x06,0x05,0x09,0x0b,0x0a,0x0c,0x11,0x0e,0x09,0x0d,0x15,0x1b,0x19,0x1b,0x44,0xd7,0xe9,0xc5,0xb5,0xb7 +,0xae,0xab,0xac,0xa7,0xb0,0xad,0xa7,0xa1,0x9d,0x9d,0x9d,0x96,0x95,0x93,0x9a,0x9e,0x9a,0x9e,0x9c,0x9b,0x9b,0x9f,0x9e,0xa6,0xa6,0xad,0xa8,0xaa,0xa2,0xa3,0xa6,0xa0 +,0xaa,0xa1,0xb7,0xac,0xc4,0x5c,0xf1,0xf9,0x2d,0x24,0x2d,0x26,0x33,0x3d,0x53,0x3b,0x2b,0x2b,0x32,0x21,0x1f,0x1f,0x17,0x1f,0x1c,0x19,0x1e,0x1f,0x26,0x26,0x28,0x2e +,0x37,0x2b,0x29,0x3c,0x32,0x34,0x35,0x38,0xc3,0xbb,0x3e,0xc5,0xbf,0xc3,0xab,0xc1,0xba,0xa6,0xb1,0xab,0xa7,0xaa,0xaa,0xa9,0xae,0xa7,0x9c,0xaf,0xa4,0xa6,0xa1,0x9b +,0xa0,0x9f,0x97,0x9a,0xa2,0x9c,0xa3,0xab,0xb6,0xc7,0xbd,0xdb,0x39,0x4b,0x45,0x2e,0x2c,0x29,0x1e,0x26,0x25,0x18,0x1b,0x19,0x18,0x19,0x16,0x1f,0x20,0x1a,0x1f,0x27 +,0x22,0x24,0x28,0x23,0x3a,0x2e,0x2e,0x4f,0xf3,0xc2,0xbf,0xb7,0xa8,0xa4,0xab,0xa6,0xa3,0x9e,0x9b,0x9b,0x96,0x94,0x94,0x95,0x92,0x95,0x9a,0x98,0x9e,0x9f,0x9b,0xa3 +,0xa5,0xa0,0x9f,0xa8,0xb1,0xa7,0xae,0xbd,0xbc,0xbf,0x58,0x73,0x3b,0x36,0xe2,0x45,0x36,0x32,0x42,0x37,0x1f,0x1c,0x1e,0x1b,0x1a,0x1e,0x1a,0x1f,0x1d,0x12,0x18,0x1d +,0x18,0x16,0x1d,0x1d,0x1a,0x1a,0x1d,0x1f,0x1e,0x1b,0x1b,0x1f,0x23,0x1b,0x1a,0x24,0x1c,0x18,0x1e,0x21,0x22,0x2e,0x2b,0x29,0x45,0x58,0x5d,0xb3,0xab,0xac,0x9f,0xa3 +,0x98,0x93,0x94,0x91,0x8f,0x8c,0x8c,0x8d,0x8d,0x8c,0x8d,0x8f,0x8e,0x8c,0x8d,0x8f,0x94,0x97,0x97,0xa0,0xa8,0xa8,0xb8,0xde,0x4d,0x34,0x2d,0x29,0x1d,0x1c,0x1b,0x17 +,0x15,0x0f,0x0f,0x10,0x0e,0x0c,0x0f,0x11,0x12,0x11,0x0f,0x18,0x1a,0x17,0x1b,0x1f,0x1f,0x1f,0x28,0x36,0x4c,0xef,0xcd,0xb2,0xb1,0xab,0xa3,0xad,0xa3,0x9e,0xa5,0xa3 +,0x9a,0x99,0x9a,0x9e,0x9d,0x98,0x9b,0x9f,0x9c,0x99,0x9e,0xa7,0xa2,0x9d,0xa7,0xa5,0xa4,0xa6,0xaa,0xab,0xb4,0xc7,0xc7,0xc9,0xce,0x5b,0xcc,0xcf,0x3f,0x3d,0x43,0x3e +,0x34,0x31,0x3c,0x49,0x33,0x2d,0x32,0x36,0x35,0x2a,0x36,0x3f,0x39,0x34,0x31,0x30,0x25,0x2d,0x2a,0x2a,0x35,0x2d,0x2c,0x35,0x33,0x32,0x3a,0x2e,0x30,0x41,0x2f,0x2a +,0x4b,0x5f,0x3d,0x3f,0x67,0x66,0xe7,0xdf,0xed,0xc3,0xc7,0xcc,0xbb,0xae,0xa9,0xae,0xab,0xa0,0xa5,0xa2,0xa4,0xa2,0x9e,0xa1,0xa3,0xa2,0xa3,0xa6,0xab,0xb3,0xac,0xba +,0xd2,0x6c,0x3f,0x3c,0x30,0x28,0x2a,0x2e,0x26,0x1f,0x22,0x21,0x20,0x1e,0x1f,0x1e,0x21,0x1d,0x1e,0x27,0x1f,0x24,0x24,0x28,0x2f,0x2d,0x2b,0x2f,0x2e,0x3b,0x45,0x3a +,0x5b,0xd1,0xe4,0xcd,0xb0,0xae,0xa8,0xa9,0xa7,0x9e,0xa5,0xa7,0x9f,0x9f,0x9e,0x9f,0xa0,0xa1,0x9d,0xa1,0xac,0xa4,0xa8,0xaf,0xad,0xb1,0xbc,0xb3,0xbd,0xdc,0xcc,0xc5 +,0xdf,0xd3,0xd1,0xfe,0xe3,0x55,0x3f,0x4f,0x3d,0x30,0x3c,0x39,0x42,0x3b,0x28,0x2e,0x31,0x26,0x33,0x2f,0x2c,0x3b,0x39,0x2f,0x3c,0x3e,0x38,0x45,0x46,0xe8,0x4f,0x4d +,0x5e,0xcd,0xd4,0x7b,0xec,0x6a,0x79,0x7a,0x42,0x5d,0x61,0x4d,0xd8,0x7e,0x4b,0xdb,0xcc,0xd7,0xb6,0xbf,0xb5,0xb7,0xae,0xae,0xad,0xac,0xb4,0xac,0xa7,0xac,0xaf,0xa8 +,0xaa,0xae,0xb4,0xaf,0xb7,0xbd,0xbc,0xbe,0xc5,0xc8,0xc4,0xd6,0x5c,0x5d,0xcc,0x4e,0x61,0x70,0x55,0x38,0x2c,0x38,0x2f,0x25,0x2c,0x34,0x2a,0x27,0x25,0x25,0x24,0x22 +,0x24,0x25,0x22,0x28,0x2d,0x2a,0x2b,0x2d,0x3b,0x3b,0x3f,0x4d,0xdf,0xf9,0x56,0xb9,0xc3,0xca,0xb8,0xb6,0xb6,0xb6,0xb3,0xb5,0xb7,0xc7,0xb9,0xb6,0xc4,0xbe,0xab,0xb9 +,0xc7,0xb0,0xaf,0xaf,0xb6,0xac,0xaf,0xb8,0xb8,0xb6,0xb6,0xbf,0xba,0xc3,0xbe,0xc9,0x54,0xce,0x47,0x31,0x56,0x48,0x2e,0x41,0x49,0x31,0x35,0x3c,0x4b,0x4a,0x4c,0x5b +,0x59,0x52,0x61,0x5f,0xf7,0xd6,0xf8,0xca,0xbe,0x6c,0x73,0xc3,0x43,0x3f,0xe3,0x47,0x44,0x5f,0x44,0x3f,0x43,0x4e,0x4a,0x3f,0x56,0x4b,0x42,0x62,0x5a,0x4a,0xe1,0xdb +,0x49,0xc4,0xbd,0x6c,0xd1,0xbf,0xf4,0x6a,0xdc,0xe7,0xc4,0xd8,0xe0,0xda,0xca,0xe7,0xc9,0xc8,0xc0,0xd1,0xeb,0xbf,0xcf,0x7a,0xbb,0xc5,0xdc,0xbb,0xd0,0xcf,0x4d,0xed +,0x76,0x66,0x4a,0x4e,0xe9,0x4f,0x37,0x52,0xd5,0x4a,0x4f,0xfe,0xd6,0x3d,0x4e,0x6f,0x5e,0x4d,0xcd,0xce,0x72,0xd9,0xbf,0xda,0xd7,0xc8,0xdb,0xce,0x55,0xcf,0xca,0x7a +,0x53,0xd9,0xd3,0xe6,0x49,0xda,0xcc,0x48,0x46,0x69,0x5e,0x3f,0x4e,0xdf,0x6d,0x4a,0x60,0xef,0xcc,0x48,0x64,0xd2,0x51,0x54,0xe0,0x59,0x46,0xd7,0xe6,0x5e,0x65,0xeb +,0xd4,0x5e,0x3a,0x65,0x6e,0x4a,0xd5,0x71,0x53,0xdc,0x50,0xe4,0xce,0x50,0xce,0xc1,0xcb,0xd4,0xc4,0xd7,0xbd,0xbf,0xdd,0xbe,0xc7,0xce,0xba,0xcb,0x4c,0xc0,0xe5,0x61 +,0xde,0x46,0x4f,0x4e,0x3d,0x49,0x6c,0x3e,0x49,0xce,0x3e,0x4d,0xdf,0x59,0xcd,0x4e,0x5e,0xc9,0xd0,0x71,0xd9,0xc9,0xe2,0x6c,0x5d,0xd9,0x62,0x4a,0x70,0x56,0x52,0x59 +,0x4b,0x4e,0x6d,0x73,0x52,0x3e,0xed,0xd2,0x57,0x51,0xf3,0xcd,0x75,0xe2,0x67,0xc7,0xf4,0x7c,0xd8,0xd4,0xe7,0x49,0xd6,0x59,0x68,0x54,0x77,0xdf,0x79,0xe9,0x45,0xe4 +,0xe4,0xfc,0x6d,0x57,0xcd,0xfd,0xce,0xee,0x59,0xcf,0xd5,0xf9,0x5c,0xdb,0xcf,0x5c,0x5b,0xcd,0x62,0x55,0xf9,0xc5,0x60,0x4b,0xcf,0xdc,0xce,0xda,0x6f,0x71,0xce,0xd1 +,0x6f,0xe6,0xe1,0x6d,0xc5,0x54,0x4f,0xcc,0x52,0x4a,0xf8,0xd1,0x47,0x59,0xdf,0xdb,0x6e,0x3f,0xcf,0xc9,0x6f,0xd7,0xcd,0xde,0xe1,0xdf,0x4b,0xcc,0x63,0x4d,0xc6,0x76 +,0x4c,0xe5,0xdb,0x3b,0xed,0xd8,0x43,0x6f,0x77,0xea,0x48,0x45,0xca,0xe9,0x4e,0xc8,0xc6,0x59,0xf7,0xc9,0x5d,0xe7,0xed,0x61,0xcd,0xdf,0x6c,0xd4,0x6a,0x50,0xc7,0x63 +,0x78,0xda,0xc8,0x5c,0x4c,0xcc,0xcc,0xf2,0x6c,0xc1,0xf5,0xe1,0xe8,0xca,0x58,0x4c,0xe0,0x6e,0xfa,0x53,0x53,0xda,0xdb,0x4a,0x68,0xcf,0xe0,0x63,0xcd,0x48,0x5e,0xe6 +,0xec,0xdf,0x73,0xc4,0xf3,0xee,0xe5,0xd4,0x3e,0x44,0xe5,0x4c,0x5b,0x4d,0x46,0x52,0x61,0x4f,0x54,0xda,0xc8,0x69,0x43,0xcf,0xd0,0x4e,0xe5,0xee,0xc9,0xc6,0xf5,0x78 +,0xc8,0xee,0x4d,0xdf,0x58,0x56,0x64,0x4b,0x49,0x4f,0x53,0x59,0x50,0xda,0xca,0x72,0x52,0xd9,0xcb,0xd6,0x49,0xc4,0xba,0x4e,0xce,0xd9,0xd6,0xd9,0xea,0x5f,0x57,0x78 +,0xdc,0x5e,0x56,0xec,0x4d,0x52,0x53,0xd9,0x69,0x55,0x59,0xc7,0xcf,0x4b,0x60,0xcc,0xbc,0x4e,0xde,0xcb,0xd6,0x5e,0x4d,0xcd,0x75,0x4a,0x53,0xe1,0xf9,0x60,0x48,0x53 +,0xe6,0xcb,0x6c,0x3b,0xe6,0xce,0x4e,0x49,0x78,0xbf,0xdc,0x43,0xc4,0xc0,0x54,0xdf,0xea,0xec,0xdd,0x4a,0xf1,0xf3,0x56,0x54,0x4e,0x71,0x6c,0xd5,0x59,0x3c,0xec,0xc5 +,0x52,0x3e,0x71,0x5d,0xf3,0x55,0xef,0xcd,0x78,0xe5,0x4e,0xb6,0xfb,0x5a,0x5e,0x6e,0xcd,0x4a,0xdb,0x58,0xd9,0x6d,0x45,0x72,0xd0,0x54,0x48,0x5b,0xcc,0x4d,0x41,0xd0 +,0x7d,0x5e,0xcf,0x78,0xdf,0xc9,0xd8,0xcc,0xde,0xc5,0xd3,0xe3,0x53,0xd5,0xbe,0x4d,0x5a,0xc5,0xde,0x3f,0x48,0xc9,0x79,0x37,0x4a,0xd9,0x4d,0x52,0xfa,0x58,0xde,0x5f +,0xd2,0xd1,0xcf,0xe8,0xbe,0xc5,0x4c,0xb4,0xc3,0x4c,0x7e,0xc8,0xc1,0x3c,0x4d,0xb6,0x47,0x34,0x4d,0x75,0x40,0x4c,0x49,0x6b,0xd4,0x48,0x4f,0xdb,0xd7,0xe7,0xbf,0xed +,0xd8,0xbe,0xbf,0x5e,0xf8,0xb5,0xc3,0x47,0x73,0xc8,0xf8,0x41,0x48,0xcf,0x47,0x37,0x60,0xd3,0x45,0x42,0x46,0xd3,0x49,0xfd,0xd2,0xcd,0xcd,0x7c,0xbe,0xdb,0xb9,0xe6 +,0xcd,0xe9,0xc9,0xc7,0x3e,0x5c,0x69,0xcf,0xd2,0x44,0x49,0xd3,0x3f,0x3c,0x4e,0xcc,0x51,0x50,0x42,0xdc,0xca,0x47,0x62,0xbf,0xc1,0xd7,0xce,0x58,0xcd,0xcb,0xc3,0xc6 +,0xb4,0x4f,0xbe,0xae,0xab,0xe9,0xca,0x28,0x04,0x0b,0x34,0x8c,0x86,0x2d,0x06,0x19,0xc9,0x97,0x8f,0x9d,0xac,0x92,0xa5,0x2b,0x14,0x03,0x28,0x91,0x8b,0x8f,0x12,0x01 +,0x10,0x8c,0x88,0x88,0x95,0x1f,0x22,0x0f,0x5e,0x9e,0x0f,0x0b,0xbc,0xaa,0x9d,0x37,0x0b,0x12,0xa5,0x9d,0xa0,0x45,0x13,0x9a,0x8d,0x8f,0x95,0x1f,0x05,0x45,0x85,0x94 +,0x2a,0x0f,0x0e,0xc9,0xa6,0x8f,0x98,0x24,0x4d,0x23,0x1f,0x17,0x10,0x06,0x0b,0x8d,0x87,0x9e,0x0c,0x03,0xe6,0x8d,0x8a,0x91,0x93,0xaf,0x97,0x8b,0x46,0x2c,0x1f,0x14 +,0x49,0x76,0xd9,0xcc,0x07,0x0d,0xa1,0xa6,0x38,0x46,0x0f,0x0c,0xa1,0xcb,0xaf,0x1d,0x14,0x88,0x86,0x2e,0x2f,0x24,0xe3,0x87,0x94,0x9b,0xae,0x30,0x3f,0xa8,0x40,0xbc +,0x1f,0x0c,0xbf,0x99,0x33,0x0e,0x08,0x06,0x1f,0xcd,0x9e,0x37,0xc9,0x8f,0x8c,0x8c,0xde,0x12,0x0d,0x26,0x89,0x80,0x9f,0x15,0x0f,0x5f,0x92,0xcc,0x37,0xa3,0x72,0xa7 +,0x9b,0x20,0x12,0x0d,0x05,0x13,0x1a,0x27,0x22,0x09,0xa1,0x80,0x8b,0x92,0xdf,0x36,0x96,0x8e,0x8e,0xdc,0x0c,0x2a,0x94,0x9b,0x26,0x15,0x17,0x1d,0x9f,0x90,0xa5,0x1c +,0x11,0x0a,0x0e,0x0e,0x14,0x20,0x0e,0x96,0x80,0x8c,0xab,0x0d,0x20,0x89,0x84,0x8c,0xd7,0x2e,0xa7,0xc5,0x2c,0x40,0x33,0x14,0x10,0xcd,0x9f,0xbc,0x0d,0x07,0x0e,0x1a +,0x10,0x2f,0xe4,0x9a,0x82,0x84,0x8c,0x14,0x0b,0x2e,0x92,0x86,0x8b,0x17,0x06,0x1e,0xa0,0xa0,0xca,0xa7,0xa9,0xff,0x1e,0x3b,0x1a,0x0f,0x0d,0x16,0x2b,0x14,0x1b,0x17 +,0x9e,0x82,0x82,0x8b,0x3f,0x0d,0x31,0x96,0x8b,0x8c,0x1e,0x0e,0x19,0xad,0xa8,0x1b,0x18,0x7d,0x9e,0x9d,0x27,0x18,0x1b,0x17,0x0c,0x07,0x26,0x2a,0xd4,0x95,0x88,0x80 +,0x98,0x0e,0x0b,0xbd,0x86,0x85,0x9d,0x41,0x27,0xf3,0xa5,0xcb,0x18,0x1d,0x3e,0xd2,0xb9,0x19,0x03,0x01,0x09,0x12,0xa5,0x93,0x8b,0x8c,0x99,0x98,0x9e,0xd1,0x1e,0x32 +,0x94,0x81,0x90,0x1e,0x0d,0x1a,0x9a,0x8b,0xa7,0x35,0x22,0x1d,0x21,0x12,0x11,0x04,0x05,0x07,0x1c,0x97,0x98,0x99,0x91,0x8c,0x8d,0x99,0xb0,0x9c,0xb0,0x8e,0x8e,0xa8 +,0x3c,0x0a,0x21,0x99,0x8f,0xb3,0x0c,0x0a,0x22,0x1b,0x1e,0x0e,0x0b,0x10,0x15,0xbb,0x9d,0x8c,0x92,0x9c,0xa5,0xad,0xa6,0x24,0x1c,0x9f,0x88,0x88,0x8b,0xa6,0xbd,0xbe +,0xa8,0xb9,0x14,0x07,0x0e,0x2d,0x1d,0x0c,0x02,0x04,0x08,0xd6,0x8a,0x85,0x86,0x8d,0xb4,0x1b,0x2b,0xbf,0xa0,0xbc,0x8f,0x8d,0x97,0xa2,0x1f,0xb6,0x8d,0x93,0xa8,0x12 +,0x0a,0x1a,0x10,0x17,0x0a,0x03,0x02,0x08,0x9d,0x88,0x85,0x8c,0xa8,0x37,0x1e,0xe6,0x92,0x8f,0x86,0x89,0x9d,0xa5,0x34,0x36,0xbb,0x9b,0x97,0x1c,0x03,0x02,0x0a,0x1e +,0x42,0x1e,0x13,0x07,0x1c,0x9c,0x8c,0x89,0x96,0xa4,0x28,0x24,0x38,0xcc,0xa2,0x8b,0x8a,0x8e,0x90,0x9e,0xa7,0xac,0xc0,0x59,0x14,0x04,0x09,0x0c,0x26,0x1c,0x06,0x05 +,0x08,0x9a,0x85,0x84,0x84,0x95,0x4c,0x10,0x17,0x39,0xfd,0x99,0x8e,0x8f,0x8f,0xb1,0xbe,0xba,0xaf,0xa4,0xee,0x27,0x0e,0x10,0x1a,0x21,0x16,0x0a,0x00,0x0d,0x9b,0x87 +,0x87,0xa4,0x3c,0x1e,0x1b,0x56,0x98,0x8a,0x87,0x89,0x9b,0xaa,0xdc,0x2c,0xa0,0xb1,0xb0,0x2d,0x09,0x06,0x0a,0x21,0xbe,0x21,0x14,0x06,0x15,0x9d,0x8c,0x85,0x9b,0x64 +,0x19,0x11,0x25,0xbd,0x9c,0x85,0x88,0x8a,0x98,0xbb,0x9d,0xa5,0xae,0xc5,0x1a,0x08,0x04,0x0c,0x1f,0x25,0x12,0x0a,0x06,0x23,0x96,0x86,0x86,0x8c,0xa3,0x1e,0x17,0x1d +,0xb8,0x9f,0x87,0x8a,0x8f,0xb0,0x19,0x35,0xcd,0xc5,0xae,0x2f,0x29,0x1a,0x1d,0x35,0x13,0x0b,0x0b,0x03,0x22,0x9a,0x8e,0x89,0xab,0xac,0x2d,0x1d,0x36,0xa8,0x90,0x85 +,0x8a,0x8f,0xb6,0x3a,0x27,0xda,0xcd,0x2f,0x1a,0x10,0x18,0x1d,0x56,0x2a,0x17,0x16,0x0e,0x11,0xa3,0xa7,0x8d,0x9f,0xaa,0xdc,0x13,0x17,0x31,0x9b,0x86,0x87,0x8b,0x8d +,0xaa,0xb4,0x52,0xc9,0x28,0x16,0x0f,0x13,0x23,0x39,0x1a,0x10,0x09,0x0e,0x09,0x39,0x91,0x8a,0x85,0x91,0x99,0x15,0x0e,0x1f,0xb9,0x8c,0x85,0x96,0x97,0x41,0x3b,0x48 +,0x39,0xe4,0x42,0x2c,0x2d,0x29,0x35,0x1c,0x0d,0x0d,0x09,0x13,0x0b,0xc3,0x96,0x8b,0x8a,0x8f,0xba,0x20,0x26,0xae,0x96,0x8a,0x8d,0xaf,0xa8,0x27,0xcb,0x23,0x20,0x30 +,0x32,0xc2,0xb6,0xe3,0xd9,0x1d,0x0f,0x0f,0x15,0x15,0x0f,0x51,0x9c,0x8d,0x92,0xbd,0x1b,0x11,0x28,0xa7,0x95,0x85,0x88,0x8e,0x95,0xc7,0x41,0x1f,0x1d,0x2e,0x34,0xb0 +,0x5c,0x1e,0x21,0x0c,0x0f,0x16,0x1e,0x2b,0x17,0xb9,0x9c,0x92,0x98,0x47,0x2c,0x1a,0x36,0xab,0xa1,0x8b,0x88,0x95,0x96,0xb7,0xbd,0xbf,0xd6,0xb3,0x7e,0x3a,0x1b,0x12 +,0x10,0x0e,0x0e,0x11,0x17,0x20,0x0e,0x4b,0x98,0x8d,0x87,0x92,0xa3,0x1a,0x1d,0x32,0xbf,0x8f,0x8a,0xa6,0xb0,0x32,0x2d,0xeb,0xb8,0xa2,0xc4,0xad,0xca,0x2f,0x2c,0x1c +,0x0e,0x0d,0x0c,0x17,0x0b,0x17,0xb8,0x98,0x88,0x93,0x9a,0x32,0x24,0xae,0x9a,0x8f,0x8a,0xa1,0xc7,0x30,0x2d,0x52,0x3b,0xd4,0x29,0xdf,0xcc,0xbd,0xc4,0x4a,0x25,0x15 +,0x11,0x13,0x0c,0x09,0x2a,0xaf,0x92,0x97,0x9e,0x3a,0x22,0xb4,0x9f,0x8a,0x88,0x88,0x9d,0xb0,0x5a,0x2e,0x39,0x29,0x2f,0x2d,0x32,0x31,0x29,0x1c,0x1c,0x13,0x1b,0x17 +,0x1b,0x20,0x20,0x9f,0x94,0x91,0x97,0xc0,0x2c,0x1d,0x38,0x99,0x97,0x8b,0x97,0xae,0xa2,0xc9,0xab,0xb5,0xb0,0x44,0x27,0x2f,0x2a,0x14,0x18,0x12,0x0b,0x0f,0x0f,0x2f +,0x17,0xaf,0x8f,0x89,0x87,0x96,0xaa,0x17,0x1d,0x3b,0xb1,0x9e,0x98,0xcf,0xb0,0x61,0xad,0x9c,0xaa,0x9e,0x4a,0xb8,0xcb,0x24,0x20,0x18,0x0c,0x0e,0x0d,0x19,0x14,0x10 +,0xbc,0x98,0x87,0x93,0x96,0xb9,0x23,0xca,0xaf,0x96,0x93,0x9a,0xb5,0xde,0x4b,0x4f,0x38,0x47,0x34,0x57,0xec,0xd5,0xcf,0x23,0x27,0x15,0x19,0x17,0x14,0x0f,0x1b,0xa7 +,0x97,0x94,0x9d,0x9f,0x28,0x2f,0xb6,0x8f,0x8e,0x8a,0x92,0xbf,0xb7,0x27,0x2e,0x2e,0x2a,0x25,0x20,0x20,0x39,0x20,0x40,0x2a,0x2d,0x33,0x21,0x31,0x16,0xd5,0xa6,0x98 +,0x95,0xb1,0x2a,0x12,0x1e,0xae,0x97,0x90,0x8c,0xa7,0xa7,0xbc,0xbc,0xa4,0xc3,0x45,0x24,0x20,0x25,0x2a,0x23,0x27,0x1b,0x27,0x1c,0x28,0x1b,0x1d,0xa2,0x99,0x8e,0xa6 +,0xc6,0x1f,0x18,0x3a,0xa8,0x9b,0x95,0x9c,0xc4,0xaf,0xa7,0x9e,0xac,0xa9,0xed,0xf0,0x52,0x39,0x27,0x17,0x17,0x0e,0x0e,0x0f,0x15,0x0d,0x40,0x9d,0x8d,0x8d,0x94,0x9d +,0x2b,0xb3,0xb6,0x9d,0x9a,0x9b,0xcf,0xbd,0x64,0xc4,0x3d,0xe2,0xcf,0x33,0xb4,0xcd,0xbd,0x22,0x2b,0x0f,0x12,0x0f,0x14,0x0c,0x19,0xb3,0x9b,0x8e,0x9d,0x9e,0x32,0xe0 +,0xaf,0x96,0x94,0x8f,0xa5,0xbf,0xaf,0xd6,0xf1,0x2d,0x32,0x26,0x43,0x4c,0xca,0x2d,0x4e,0x20,0x1c,0x1c,0x1b,0x16,0x15,0xcb,0xaa,0x98,0xaf,0xd9,0x1f,0x23,0xda,0x9c +,0x94,0x8f,0x93,0x9c,0x93,0x9f,0xac,0x40,0x3e,0x2d,0x33,0x36,0x42,0x1e,0x1e,0x13,0x0e,0x14,0x18,0x1a,0x15,0xa5,0x9d,0x92,0x9e,0xae,0x64,0x2b,0xd2,0xa9,0xa5,0x9b +,0x99,0xb0,0x99,0xa7,0x9f,0xbc,0xc9,0x57,0xfa,0x48,0xcf,0x2a,0x1c,0x13,0x0c,0x0e,0x13,0x13,0x0f,0xb3,0xa4,0x93,0x9b,0x97,0xb3,0xb7,0xae,0xa6,0x9e,0x9d,0xa3,0x6f +,0xa7,0xb8,0xba,0x42,0x7b,0x37,0xb1,0xb0,0xac,0x4d,0x2d,0x16,0x14,0x12,0x17,0x0d,0x17,0xb7,0xb5,0xa8,0xd4,0xbd,0x30,0xab,0xa1,0x93,0x97,0x93,0x9e,0x9e,0x97,0xa0 +,0xba,0x33,0x3a,0x2d,0x31,0x3a,0x3e,0x34,0x29,0x1c,0x17,0x18,0x11,0x0f,0x3e,0xa6,0xa5,0x67,0xca,0x27,0x34,0xab,0x96,0x96,0x96,0x99,0x9f,0x96,0x95,0x97,0xa8,0xb3 +,0x3e,0x3b,0x2a,0x20,0x1b,0x17,0x13,0x0c,0x0d,0x0c,0x0c,0xe0,0x9b,0x99,0xaa,0xad,0xd2,0xbd,0x9d,0x95,0x98,0x9a,0x9b,0xaa,0xa1,0xa2,0xac,0xc1,0xab,0xb4,0x56,0x3c +,0x27,0x1f,0x1c,0x1d,0x16,0x15,0x0d,0x0a,0x2e,0xab,0xac,0x39,0x59,0x30,0xcd,0x9e,0x99,0x9a,0x96,0x94,0x9c,0x9b,0xb6,0xb6,0x5c,0x62,0xdc,0xe1,0x4b,0x32,0x28,0x29 +,0x28,0x1e,0x26,0x14,0x13,0x2f,0xbf,0x29,0x1d,0x24,0x1e,0x39,0xab,0xa0,0xa4,0x91,0x95,0x8d,0x8f,0x93,0x9d,0xae,0xaa,0xae,0xa8,0xbe,0x34,0x1b,0x13,0x0f,0x15,0x11 +,0x0f,0x14,0x2d,0x3e,0x1d,0x1d,0x29,0x35,0xb8,0xa6,0xa7,0xb3,0x9a,0x96,0x8f,0x8e,0x90,0x9e,0xaa,0xa3,0xb0,0xa8,0xaf,0xc9,0x36,0x19,0x0e,0x0d,0x0b,0x09,0x0d,0x2d +,0x28,0x18,0x1a,0x38,0x54,0xa3,0x97,0x96,0x95,0x91,0x91,0x8f,0x8c,0x9a,0xa2,0xc6,0x67,0x50,0xc3,0x4b,0xe6,0x54,0x27,0x1d,0x11,0x11,0x0a,0x0f,0x36,0x2c,0x13,0x16 +,0x1d,0x22,0xb5,0x9b,0x97,0x99,0x90,0x8f,0x8c,0x8a,0x8f,0x93,0xa6,0xa6,0xcb,0xbe,0x4f,0x28,0x1d,0x15,0x14,0x0f,0x0d,0x09,0x12,0x1f,0x20,0x12,0x21,0x2e,0x46,0x9f +,0x9f,0x9d,0x98,0x8f,0x8e,0x8b,0x8c,0x8f,0x98,0x9e,0xa3,0xa4,0xa7,0xb1,0x35,0x19,0x0f,0x0c,0x0b,0x0a,0x09,0x15,0x17,0x0f,0x12,0x24,0x39,0xa9,0x93,0x95,0x99,0x8f +,0x8b,0x8d,0x8b,0x8e,0x94,0xa6,0xb6,0xc5,0xaf,0xab,0xbd,0x2d,0x19,0x12,0x0a,0x0d,0x0c,0x0e,0x1a,0x1a,0x0f,0x10,0x1e,0x35,0xa4,0x94,0x96,0x99,0x90,0x8d,0x8b,0x8a +,0x8d,0x92,0x9f,0xb6,0xcf,0xc8,0xbb,0x4e,0x27,0x17,0x11,0x0c,0x0a,0x08,0x11,0x1d,0x1c,0x14,0x1b,0x29,0x3c,0xa4,0x9c,0xa2,0x9e,0x95,0x8f,0x89,0x8a,0x8d,0x94,0x9d +,0xa6,0xa6,0xac,0xb5,0xd2,0x26,0x18,0x0e,0x0e,0x09,0x07,0x0f,0x15,0x13,0x14,0x26,0x2f,0xcb,0x9e,0x9e,0xa5,0x97,0x8f,0x8d,0x88,0x8b,0x90,0x9d,0xa5,0xab,0xa5,0xad +,0xda,0x3a,0x1c,0x15,0x0e,0x0e,0x0a,0x0c,0x10,0x0f,0x0d,0x13,0x29,0x3d,0xa2,0x9a,0x9a,0x99,0x90,0x8e,0x89,0x87,0x8c,0x93,0x9b,0xa8,0xb4,0xae,0x4e,0x2a,0x1d,0x16 +,0x0e,0x0e,0x0c,0x0a,0x0f,0x16,0x14,0x0f,0x1c,0x33,0xd7,0x9d,0x9a,0x9f,0x9c,0x94,0x8f,0x89,0x88,0x8d,0x97,0x9a,0x9d,0xa2,0xa5,0xde,0x2d,0x1a,0x11,0x0b,0x0d,0x09 +,0x07,0x0e,0x17,0x13,0x12,0x29,0x37,0xac,0x96,0x95,0x9d,0x96,0x92,0x90,0x8b,0x8b,0x93,0x9d,0xa1,0xa6,0xa0,0xaa,0xe4,0x27,0x16,0x14,0x0e,0x0e,0x0d,0x0a,0x11,0x16 +,0x12,0x13,0x27,0x36,0xbe,0x9d,0x99,0x9e,0x94,0x90,0x8e,0x87,0x8a,0x92,0x9c,0x9d,0xa6,0xa9,0xaf,0x38,0x1d,0x15,0x0f,0x0c,0x0f,0x0d,0x0a,0x13,0x1c,0x16,0x17,0x33 +,0x3b,0xae,0x9a,0x9c,0x9e,0x95,0x93,0x8c,0x89,0x8b,0x94,0x9e,0xa2,0xa0,0xa0,0xaf,0x3d,0x1e,0x12,0x0f,0x0f,0x0e,0x0d,0x07,0x14,0x1b,0x19,0x17,0x2d,0x36,0xad,0x97 +,0x97,0x9a,0x93,0x91,0x90,0x8b,0x8d,0x97,0xa3,0xa3,0xa4,0xa3,0xb4,0x37,0x1d,0x1a,0x18,0x15,0x10,0x0d,0x08,0x13,0x1c,0x1a,0x16,0x2a,0x30,0xcc,0x98,0x98,0x9a,0x94 +,0x8f,0x8f,0x8b,0x8d,0x99,0xa8,0xa2,0xa8,0xaa,0xb2,0x32,0x1b,0x18,0x1a,0x16,0x11,0x10,0x09,0x12,0x1f,0x1d,0x18,0x2b,0x36,0x59,0xa2,0x9c,0x9e,0x98,0x8f,0x8f,0x8c +,0x8e,0x99,0xa0,0x9d,0x9f,0x9f,0xb1,0x3b,0x1d,0x1b,0x19,0x19,0x12,0x10,0x08,0x0f,0x1b,0x1a,0x15,0x27,0x5e,0xf6,0x9f,0x9e,0x9f,0x97,0x8d,0x92,0x8b,0x8c,0x9a,0xaf +,0x9d,0xa5,0xa3,0xad,0x34,0x1d,0x21,0x1e,0x17,0x16,0x16,0x0b,0x0c,0x1c,0x17,0x13,0x1d,0x4b,0x41,0xa3,0x9d,0xa2,0x9a,0x8d,0x8f,0x8c,0x8a,0x98,0xa9,0xa0,0xa5,0xa7 +,0xab,0x3b,0x1f,0x25,0x1f,0x1a,0x16,0x16,0x0e,0x0c,0x1d,0x1b,0x16,0x17,0x3d,0x35,0xad,0x9e,0xa2,0xa7,0x92,0x92,0x91,0x89,0x8f,0x9f,0x9f,0x9a,0xaa,0xa8,0xc6,0x26 +,0x1e,0x27,0x1a,0x12,0x16,0x0f,0x0a,0x17,0x20,0x19,0x19,0x34,0x34,0xc3,0x9d,0xa1,0xa6,0x97,0x95,0x94,0x8c,0x8e,0x9b,0x9c,0x9b,0xa5,0xa5,0xd4,0x2b,0x21,0x25,0x1c +,0x19,0x12,0x12,0x0a,0x12,0x21,0x21,0x19,0x28,0x37,0x43,0x9f,0x9e,0xa4,0x9b,0x92,0x99,0x8e,0x8e,0x98,0xa1,0x99,0xa6,0xad,0xbc,0x35,0x1f,0x28,0x20,0x19,0x17,0x18 +,0x0d,0x0f,0x25,0x1f,0x18,0x1b,0x35,0x43,0xa2,0x9e,0xa2,0xa1,0x95,0x97,0x92,0x8e,0x93,0x9e,0x9b,0x9d,0xa6,0xad,0x44,0x23,0x25,0x26,0x1c,0x19,0x16,0x0e,0x0c,0x1b +,0x1e,0x1a,0x19,0x35,0x59,0xac,0xa0,0xa9,0xad,0x9b,0x96,0x94,0x8e,0x8f,0x9a,0x9e,0x9a,0x9e,0xa1,0xb8,0x35,0x24,0x22,0x1c,0x18,0x14,0x12,0x0b,0x14,0x1e,0x18,0x14 +,0x28,0x3f,0xba,0x9f,0xa3,0xae,0x9f,0x9a,0x99,0x8e,0x8d,0x96,0xa0,0x9c,0xa1,0xa0,0xae,0x43,0x21,0x24,0x1d,0x1b,0x18,0x18,0x0d,0x0f,0x1c,0x19,0x14,0x1f,0x4c,0xef +,0xa0,0x9e,0xa8,0xa7,0x98,0x9a,0x8f,0x8b,0x90,0xa4,0xa2,0xa7,0xab,0xab,0x5f,0x29,0x27,0x26,0x1b,0x1a,0x16,0x0f,0x0b,0x19,0x1a,0x1a,0x1d,0x39,0xec,0xa8,0x9b,0xa3 +,0xa5,0x9d,0x98,0x94,0x8d,0x90,0x9e,0xaa,0x9f,0xa5,0xa9,0xbd,0x2d,0x26,0x29,0x1e,0x19,0x16,0x11,0x0a,0x11,0x1d,0x1d,0x1c,0x2b,0x4b,0xb4,0x9d,0x9f,0xb0,0xa2,0x97 +,0x98,0x8e,0x8e,0x9a,0xa4,0x9a,0xa0,0xa3,0xb3,0x32,0x21,0x2e,0x22,0x1e,0x19,0x11,0x0c,0x0d,0x1a,0x1e,0x1d,0x1e,0x41,0xc7,0xa3,0xa2,0xab,0xaf,0x99,0x96,0x90,0x8d +,0x93,0x9f,0x9d,0x9d,0xaa,0xb6,0x3b,0x21,0x24,0x29,0x22,0x1e,0x17,0x0f,0x0c,0x17,0x1d,0x1c,0x1a,0x30,0xcf,0xac,0x9f,0xa3,0xae,0x9e,0x97,0x96,0x8f,0x91,0x9c,0xa0 +,0x9b,0xa5,0xaf,0x5c,0x28,0x22,0x27,0x25,0x24,0x1a,0x16,0x0d,0x10,0x1d,0x1c,0x15,0x27,0xcf,0xbb,0x9f,0x9e,0xb0,0xa2,0x97,0x9c,0x8f,0x8e,0x98,0x9d,0x97,0xa5,0xac +,0xcf,0x27,0x22,0x2a,0x1e,0x1e,0x1b,0x14,0x0e,0x0f,0x1c,0x1d,0x19,0x1c,0x4e,0xb9,0xa0,0x9c,0xa6,0xa6,0x99,0x99,0x94,0x8f,0x94,0x9d,0x9b,0xa2,0xad,0xc9,0x2c,0x20 +,0x28,0x22,0x1e,0x1c,0x16,0x10,0x0e,0x1b,0x1f,0x1c,0x1b,0x32,0xd9,0xa7,0x9b,0xa1,0xa9,0x9a,0x97,0x95,0x8e,0x92,0x9d,0x9e,0xa5,0xaf,0xb7,0x3d,0x23,0x27,0x29,0x25 +,0x20,0x17,0x10,0x0d,0x15,0x21,0x20,0x1c,0x2d,0x45,0xba,0x9d,0x9e,0xac,0x9b,0x98,0x97,0x8f,0x90,0x9d,0x9f,0xa1,0xb2,0xb2,0x64,0x28,0x23,0x29,0x24,0x21,0x1a,0x11 +,0x0b,0x12,0x1e,0x1e,0x1f,0x32,0x59,0xbb,0xa1,0xa2,0xae,0x9c,0x96,0x98,0x8f,0x8f,0x9e,0x9f,0x9c,0xab,0xb0,0xcb,0x2a,0x27,0x31,0x24,0x1f,0x18,0x0f,0x0a,0x11,0x1d +,0x1e,0x1c,0x2c,0xf1,0xb0,0x9f,0x9f,0xac,0x9f,0x94,0x95,0x8f,0x8e,0x9c,0xa6,0x9c,0xa7,0xad,0xc3,0x25,0x20,0x2f,0x24,0x1f,0x19,0x10,0x0a,0x11,0x1b,0x1c,0x1b,0x26 +,0x40,0xba,0x9d,0xa0,0xad,0x9f,0x96,0x97,0x8d,0x8e,0x9a,0x9f,0x9d,0xa9,0xab,0xbf,0x23,0x1e,0x2a,0x20,0x20,0x18,0x10,0x0c,0x11,0x1d,0x1f,0x1c,0x27,0x56,0xc4,0x9c +,0x9a,0xa7,0xa1,0x94,0x98,0x8f,0x8d,0x9a,0xa4,0x9e,0xa8,0xb1,0xb9,0x2e,0x1e,0x25,0x23,0x1d,0x18,0x11,0x0c,0x10,0x1d,0x1c,0x1b,0x28,0x3e,0xce,0x9e,0x99,0x9f,0x9c +,0x95,0x98,0x92,0x8f,0x98,0x9f,0x9e,0xa6,0xb4,0xc4,0x2e,0x21,0x28,0x24,0x1c,0x18,0x15,0x0c,0x0f,0x1d,0x1c,0x1b,0x2e,0x3b,0x6d,0xa3,0x9d,0xa1,0x9c,0x96,0x98,0x91 +,0x8f,0x98,0x9f,0x9f,0xae,0xb9,0xb8,0x35,0x1e,0x25,0x21,0x1c,0x1a,0x17,0x0f,0x0f,0x1a,0x1e,0x1e,0x2a,0x36,0x3d,0xae,0xa0,0xa4,0x9e,0x97,0x99,0x95,0x8f,0x98,0x9e +,0x9e,0xa8,0xb4,0xb6,0x3e,0x1f,0x22,0x1f,0x1d,0x1b,0x1a,0x0f,0x0f,0x1a,0x1e,0x1e,0x2a,0x30,0x52,0xab,0x99,0x9c,0x9a,0x95,0x96,0x92,0x8c,0x94,0x9c,0xa6,0xa4,0xb5 +,0xa4,0xcf,0x1f,0x17,0x1d,0x33,0x24,0x51,0x0a,0x22,0x03,0x00,0x00,0x0b,0xaf,0x17,0xba,0x17,0xb2,0x89,0x8e,0x8f,0x89,0x8a,0x8d,0x87,0x83,0x95,0x8f,0x88,0x2c,0x9a +,0x20,0x0c,0x9b,0xb6,0x27,0x1a,0x13,0x06,0x08,0x04,0x0b,0x08,0x04,0x07,0x1a,0x22,0x13,0x15,0x0f,0x22,0x1a,0xbc,0x2d,0x24,0x26,0x76,0xb5,0x9f,0x97,0xba,0x34,0xb5 +,0x99,0x99,0xa7,0xa7,0xaa,0x9d,0x89,0x8a,0x83,0x86,0x83,0x82,0x80,0x87,0x80,0x94,0xae,0x85,0x80,0x8f,0x17,0xd0,0x07,0x10,0x11,0x02,0x01,0x01,0x00,0x0b,0x1e,0x00 +,0x05,0x00,0x0d,0x0c,0x00,0x02,0x04,0x3d,0xab,0x8d,0x8c,0x99,0x60,0x86,0x80,0x81,0x80,0x85,0x8d,0x8f,0x83,0x89,0x8a,0x8a,0x9a,0xbe,0x93,0xd8,0x9a,0x9d,0xb0,0x48 +,0xca,0x9f,0xa5,0x8e,0x9a,0x36,0x22,0x35,0x22,0x32,0x2d,0x0d,0x07,0x06,0x07,0x0a,0x0a,0x0a,0x04,0x01,0x04,0x02,0x02,0x01,0x07,0x0f,0x0c,0xb3,0x40,0x9f,0x85,0x87 +,0x85,0x82,0x89,0x8b,0x83,0x8c,0x89,0x86,0x88,0x83,0xa6,0x8f,0x84,0x3e,0x97,0x86,0x84,0xb0,0x95,0x21,0x18,0xaa,0x00,0x07,0x4d,0x2f,0x00,0x05,0x9b,0x1b,0x06,0x08 +,0x11,0x0a,0x0f,0xaa,0x3b,0x39,0x1c,0x0a,0x01,0x08,0x05,0xc1,0x27,0x14,0x23,0x30,0xe3,0x0f,0x9b,0xcc,0x8a,0x80,0xa5,0x89,0x82,0x80,0x84,0x81,0x82,0x84,0xaa,0x8d +,0x84,0xa0,0x92,0xa1,0x2b,0x1c,0xbd,0x14,0x2a,0x15,0x0a,0x0c,0x00,0x0a,0x0e,0x13,0x09,0x08,0x2d,0x9a,0x87,0x9f,0x13,0x0a,0x39,0x8e,0x56,0x8e,0x20,0x03,0x03,0x17 +,0x2b,0x04,0xa4,0x0f,0x08,0x15,0x0b,0x09,0x00,0x28,0x0b,0x0a,0x00,0x5e,0x83,0x11,0x8d,0x9c,0x2b,0x8a,0x80,0x84,0x81,0x86,0x80,0x97,0x95,0x81,0x8e,0xa6,0xc3,0xc7 +,0x02,0x12,0x1e,0xdf,0x0a,0x22,0x39,0x09,0x0d,0x1d,0x80,0x93,0x3b,0x8a,0x98,0x92,0x85,0x83,0x97,0xb0,0x8e,0x9e,0x9c,0x89,0x89,0xad,0x84,0xcc,0x0e,0x64,0x92,0x84 +,0x4a,0x0b,0x12,0x3e,0x0a,0x24,0x98,0xa4,0x08,0x47,0x1c,0xa9,0x83,0x0c,0x19,0x9e,0x8f,0x0f,0x28,0x2a,0x10,0x07,0x25,0x36,0x00,0xaf,0x13,0x00,0x0b,0x00,0x09,0x02 +,0x18,0x0a,0x02,0x15,0x03,0x99,0x9d,0x93,0x28,0x9c,0x29,0x0a,0x89,0x87,0x88,0x21,0xb5,0xa8,0x8d,0x87,0x8c,0x80,0x88,0x37,0x8d,0x80,0x85,0x82,0x8d,0x80,0x82,0x80 +,0xa7,0x9f,0x80,0x84,0x80,0x94,0x9b,0x1e,0x2e,0x0c,0x08,0x07,0x02,0x09,0x00,0x0f,0x04,0x02,0x00,0x04,0x05,0x01,0x00,0x02,0x00,0x02,0x00,0x1e,0x31,0x02,0xad,0x06 +,0x05,0xa8,0x83,0x87,0x80,0x9a,0x16,0xb8,0x3e,0x80,0x9a,0x8c,0x89,0x14,0x8a,0x80,0x88,0x8b,0x86,0x91,0xef,0x83,0x9e,0xae,0x87,0x27,0x82,0x84,0xb6,0xcf,0x8a,0xc2 +,0x58,0xb5,0x1b,0x98,0x11,0x0f,0x1b,0x2e,0x0e,0x0b,0x02,0x12,0x12,0x0e,0x09,0x03,0x1c,0x0e,0x15,0x07,0xaa,0x19,0xc9,0x85,0x97,0x94,0x8d,0x9d,0xae,0x86,0x88,0x91 +,0x99,0x8e,0xa3,0xd0,0xa0,0x8c,0xde,0xcf,0x21,0xf0,0xce,0x09,0x00,0x03,0x1a,0x0d,0x04,0x2d,0x06,0x08,0xa0,0x0d,0xa5,0x13,0x0f,0x1d,0x3d,0x0f,0x06,0x1b,0x24,0x8a +,0x9b,0x9a,0x9e,0x8d,0x84,0x8b,0x82,0x81,0x88,0x83,0x82,0x88,0x45,0x88,0x80,0x18,0x87,0x8b,0x2a,0x8a,0x94,0x1a,0x8e,0x99,0x14,0x1b,0x0f,0x14,0x0e,0x1a,0x19,0x36 +,0x0a,0x0e,0x08,0x0a,0x05,0x05,0x11,0x08,0x15,0x06,0x21,0x02,0x05,0x8a,0x16,0x05,0xb7,0x0f,0x1a,0x27,0x2f,0x14,0x3a,0x38,0x36,0x8e,0x8b,0xa3,0x2b,0x89,0x6e,0x9e +,0x85,0xaa,0x8f,0x90,0x9b,0xa3,0xa1,0x86,0xa8,0x98,0x80,0x8b,0x80,0x83,0xb0,0x89,0x88,0x92,0x8a,0x8a,0xda,0x21,0xa4,0xa1,0xaf,0x2f,0x60,0x11,0x13,0x33,0x0f,0x16 +,0x06,0x09,0x0b,0x1b,0xca,0x01,0x1b,0x8f,0x04,0x33,0x8d,0x16,0x2a,0x18,0x27,0x2f,0xd3,0x05,0x11,0x2f,0x0d,0x08,0x17,0x0c,0x0c,0x1b,0x10,0x20,0x13,0x08,0x0a,0x24 +,0x06,0xa3,0x08,0x11,0x93,0x1d,0x8d,0x8b,0xa2,0x8b,0x80,0x82,0x80,0x81,0x80,0x81,0x80,0x80,0x82,0x83,0x85,0x8a,0x88,0x81,0x51,0x63,0x41,0x18,0x0a,0x05,0x20,0x00 +,0x0d,0x0f,0x00,0x0d,0x19,0x00,0x09,0x0d,0x05,0x0b,0x03,0x03,0x2e,0x25,0x2f,0x30,0x0b,0x0f,0x0e,0x2f,0xbb,0x1c,0xab,0x2c,0x14,0x1a,0x1d,0x87,0x2d,0x9b,0x80,0x5d +,0x8a,0x87,0x96,0x85,0x84,0xa0,0x8f,0x8c,0x8e,0x86,0xc8,0x8d,0xa4,0x93,0x9f,0xa3,0x90,0x28,0x2d,0xac,0x22,0x0d,0x20,0x07,0xbd,0x0f,0x0a,0x8c,0x0c,0x1c,0x90,0x2f +,0x99,0x96,0xb7,0x8f,0xaf,0x58,0x8c,0x99,0x9b,0x16,0x2b,0x6a,0xb4,0x19,0x22,0xce,0x5b,0xa7,0x20,0x28,0x08,0x99,0x24,0x4c,0x93,0x0c,0x1e,0x8e,0x1f,0x4e,0xa2,0x0b +,0xa1,0x9f,0x2a,0x36,0x1c,0x18,0x22,0x0b,0x0d,0x0a,0x04,0x07,0x01,0x0a,0x09,0x05,0x1e,0x0c,0x2b,0x9a,0x4b,0x84,0x88,0x8b,0x80,0x82,0x80,0x80,0x81,0x81,0x82,0x80 +,0x80,0x87,0x81,0x97,0x8d,0x8d,0x27,0x9e,0x44,0x0f,0xdc,0x14,0x05,0x04,0x00,0x16,0x0a,0x00,0x2b,0x0a,0x0b,0xad,0x06,0x20,0x2b,0x07,0x2e,0x19,0x08,0x1c,0x0a,0x0a +,0x11,0x07,0x0b,0x0f,0x0a,0x09,0x18,0xba,0x15,0x11,0x42,0x11,0x93,0xa0,0x44,0x82,0x90,0xab,0x82,0x87,0x8b,0x83,0x8d,0x85,0x82,0x8e,0x84,0x8b,0x8e,0x8a,0x99,0x92 +,0x92,0x4d,0x24,0x2b,0x25,0xad,0x0a,0x13,0x14,0x1f,0x1c,0x0e,0x8a,0x11,0x0f,0x8b,0x28,0x1e,0x90,0x16,0x4e,0x99,0x14,0x37,0xce,0x3f,0xcc,0x23,0xb9,0xa3,0x0c,0x2d +,0x27,0x16,0x18,0x05,0x06,0x03,0x0d,0x0a,0x0a,0xa5,0x0a,0x10,0x8f,0x0a,0x46,0xba,0x1a,0x9a,0x2c,0x18,0x20,0x13,0x24,0x1a,0x12,0xaa,0x35,0xb0,0x8b,0x8c,0x88,0x89 +,0x87,0x81,0x84,0x80,0x84,0x86,0x80,0x84,0x82,0x85,0x8b,0x84,0x86,0x97,0x90,0xb6,0x39,0x3b,0x11,0x0a,0x08,0x06,0x04,0x01,0x01,0x06,0x01,0x03,0x01,0x03,0x02,0x0d +,0x15,0x00,0xd5,0x2a,0x02,0x92,0x20,0x0c,0xa4,0x25,0x39,0xa4,0xba,0xbc,0x9e,0x94,0xb8,0x9c,0x93,0xb0,0x99,0x8c,0xe2,0x95,0x9a,0x1e,0xaf,0x1b,0x8a,0x25,0x9c,0x84 +,0x2a,0x84,0x8d,0x5c,0x86,0x8b,0x5f,0x87,0x92,0x94,0xd6,0xaa,0xaf,0x48,0x5f,0x18,0x21,0x4f,0x1d,0x28,0x4e,0x10,0x1f,0x15,0xc4,0x18,0x19,0xaa,0x0e,0x24,0x8d,0x0c +,0x3b,0x90,0x1f,0x96,0x9e,0x99,0x3d,0x9f,0xa9,0x2f,0xa4,0x2f,0x15,0x2f,0x11,0x0d,0x1c,0x0c,0x10,0x0c,0x3f,0x10,0x11,0x9d,0x0a,0x1e,0x9b,0x0a,0x29,0x29,0x04,0x1b +,0x1a,0x15,0x14,0x2e,0x2f,0x29,0xaa,0x93,0x96,0x8c,0x87,0x8c,0x83,0x88,0x89,0x8a,0x81,0x8c,0x87,0x80,0x8f,0x86,0x82,0x94,0x86,0x85,0x4e,0x9b,0x99,0x1a,0x27,0x26 +,0x08,0x0a,0x0a,0x05,0x05,0x0a,0x02,0x05,0x08,0x07,0x00,0x0b,0x13,0x02,0xbf,0x13,0x06,0xa9,0x11,0x0b,0xa1,0x1e,0x1b,0xd9,0xce,0xb3,0xb3,0x98,0xa1,0x9d,0x9a,0xbd +,0x9a,0x8f,0x3a,0x2d,0xa2,0xca,0x21,0x8c,0x31,0xd2,0x80,0xbd,0x92,0x81,0xca,0x8b,0x82,0xa2,0x93,0x8f,0x49,0xae,0x8d,0xbf,0x3c,0xa9,0xb9,0x1f,0x9e,0x67,0x1e,0x1a +,0x16,0x0b,0x48,0x3d,0x0a,0x96,0x11,0x0c,0x95,0x21,0x2b,0x90,0xc5,0xab,0x9c,0xb0,0x38,0xad,0xaf,0x2d,0x51,0x33,0x0e,0x17,0x24,0x0c,0x0d,0x11,0x01,0x19,0x1f,0x07 +,0x9a,0x22,0x0b,0x9a,0x1b,0x0d,0x56,0x0d,0x0d,0x24,0x14,0x11,0x1f,0x1e,0x15,0x4a,0x98,0x9c,0x8b,0x89,0x8c,0x84,0x86,0x8d,0x81,0x89,0x8f,0x80,0x87,0x85,0x80,0x8e +,0x88,0x80,0x98,0x95,0x8c,0x3f,0x58,0x3c,0x11,0x09,0x06,0x01,0x04,0x05,0x04,0x00,0x06,0x01,0x06,0x1a,0x00,0x1e,0x32,0x00,0xa8,0x53,0x0a,0xab,0x3e,0x2b,0x9c,0x47 +,0x35,0xaf,0xcd,0x2b,0xb4,0xab,0x2c,0x5c,0xaf,0x33,0xd4,0x3d,0x0e,0x90,0x54,0xef,0x81,0xd1,0x8e,0x83,0x97,0x84,0x83,0x96,0x85,0x8f,0x98,0x8e,0xaf,0xb3,0xc5,0x1e +,0x23,0x2b,0x1f,0x1d,0x19,0x15,0x08,0xd3,0x19,0x21,0x82,0x40,0x96,0x88,0x1e,0x9e,0x96,0x2a,0x93,0x99,0xb6,0x9d,0x2e,0x1d,0x19,0x16,0x17,0x22,0x40,0x1f,0x16,0x17 +,0x02,0x25,0x14,0x0b,0x87,0x24,0x46,0x8b,0x0f,0x2a,0x9c,0x1c,0x9b,0x95,0xb3,0x9b,0x50,0x2f,0xc7,0x38,0xd2,0xa2,0xa6,0x2b,0x1f,0x1e,0x08,0xb7,0x0f,0x26,0x88,0x10 +,0xa5,0x95,0x0a,0x9e,0x97,0x6b,0x89,0x94,0x9b,0xa7,0xa4,0xb2,0xa1,0x9c,0x9a,0x90,0xa3,0x1d,0x18,0x09,0x0c,0xad,0x08,0x9d,0xa2,0x06,0xaf,0x29,0x0d,0x8f,0x9f,0xa4 +,0x88,0x9e,0x98,0xa0,0xa4,0xa8,0x94,0x8e,0xa4,0xb1,0x3c,0x0a,0x1e,0x07,0x2a,0xbd,0x09,0x90,0x1b,0x11,0x97,0x19,0x5b,0x86,0x9f,0x8d,0x8f,0xae,0xbf,0x38,0xb2,0x49 +,0xa8,0xa7,0x1e,0x1e,0x0d,0x00,0x09,0x00,0x38,0x17,0x0e,0x95,0x09,0x1c,0xa5,0x0e,0x99,0x88,0xb0,0x8a,0x95,0xac,0x98,0xdd,0xaa,0x9d,0x9e,0x9b,0xbd,0x3e,0x11,0x17 +,0x11,0x2f,0x96,0x1d,0x8d,0x9e,0x2e,0x8a,0x66,0xb7,0x85,0x93,0x8c,0x8e,0xbf,0xc1,0x36,0x47,0x4a,0xaf,0x9c,0x3d,0x5d,0x33,0x08,0x10,0x09,0xb0,0xb2,0x2a,0x80,0x53 +,0xc5,0x8a,0x1c,0x9c,0x87,0xcf,0x8d,0x9c,0x1b,0x35,0x0f,0x0c,0x21,0x14,0x2e,0x26,0x1d,0x0b,0x06,0x09,0x09,0xa9,0x12,0xb5,0x96,0x0d,0x9f,0x5c,0x0c,0x9e,0xbc,0xae +,0x97,0x3b,0x3e,0x28,0x26,0x22,0xab,0x94,0xa6,0x9e,0x8f,0xb1,0x93,0xac,0x99,0x82,0xa5,0x80,0x8a,0x22,0x8d,0x2d,0x0e,0xa5,0x08,0x1a,0x41,0x02,0x02,0x07,0x04,0x06 +,0x08,0x0f,0x1e,0x1a,0x0d,0x04,0x0e,0x06,0x5b,0x29,0x21,0x84,0x17,0x36,0x8f,0x10,0x9c,0x87,0x9b,0x84,0x8b,0x96,0x8b,0x93,0x98,0x89,0x87,0x87,0x8a,0x8b,0x9b,0xcb +,0xb4,0x1d,0x8d,0x36,0xb9,0x84,0x0c,0xb6,0x9d,0x0b,0x99,0x94,0xa0,0x85,0x93,0x8f,0x8a,0x85,0x88,0x8e,0x83,0x87,0x8f,0xa2,0x0d,0x13,0x0a,0x03,0x11,0x00,0x1e,0x0e +,0x00,0x16,0x0b,0x00,0x2b,0x0c,0x17,0x9c,0x0c,0x24,0x27,0x0f,0x22,0x27,0xbf,0x47,0x25,0x1c,0x03,0x0b,0x00,0x0f,0xd1,0x07,0x93,0xac,0x0b,0x8b,0x50,0x44,0x80,0x8e +,0x8a,0x83,0x8f,0x91,0x92,0x9f,0x9b,0x96,0x98,0xb3,0xbc,0x1e,0x08,0x14,0x02,0x28,0xae,0x21,0x81,0xa6,0x9f,0x80,0x8e,0x87,0x80,0x81,0x80,0x83,0x89,0x86,0x8a,0xa0 +,0x1f,0xa5,0x9e,0x11,0x0c,0x06,0x00,0x04,0x00,0x0d,0x0f,0x04,0xb9,0x0a,0x06,0xcd,0x07,0x16,0x9e,0x17,0x45,0xf6,0x10,0x15,0x0a,0x12,0x17,0x1e,0x40,0x14,0x1f,0x19 +,0x03,0x12,0x07,0x2f,0x5e,0x0f,0x86,0x27,0x18,0x8d,0x1d,0xc5,0x8e,0xb9,0x95,0x98,0xe9,0x4f,0x33,0x5e,0xa5,0x8b,0x87,0x8e,0x88,0x83,0x88,0x8b,0x8d,0x84,0x81,0x8c +,0x80,0x89,0x93,0x85,0x24,0x7b,0x87,0x40,0x1c,0x24,0x12,0x09,0x08,0x0e,0x0c,0x21,0x2a,0x0c,0x17,0x12,0x01,0x0e,0x06,0x21,0x5f,0x09,0x9c,0x10,0x05,0xae,0x0b,0x13 +,0x98,0x21,0xdb,0xaf,0x18,0x28,0x3d,0x30,0xbb,0x98,0x98,0xc1,0x3f,0xcc,0x0f,0x24,0x0f,0x1e,0x91,0x08,0x9f,0xaa,0x01,0x99,0x4d,0x5f,0x80,0x8e,0x8d,0x82,0x83,0x85 +,0x86,0x80,0x81,0x81,0x82,0x85,0x88,0x8f,0x12,0x29,0x1c,0x17,0x36,0x00,0x33,0x14,0x00,0x39,0x0f,0x0a,0x9b,0x1a,0x1e,0xaf,0x0e,0x18,0x1c,0x21,0x36,0x3a,0x41,0x18 +,0x0d,0x0c,0x01,0x0a,0x04,0x0f,0xa6,0x04,0x5f,0xc1,0x02,0x9d,0xca,0x2a,0x84,0x9a,0xcf,0x97,0xc7,0x65,0x40,0xaf,0xb7,0x37,0x60,0x24,0x11,0x10,0x0a,0x1d,0x3a,0xcc +,0x88,0xb5,0x84,0x84,0x9f,0x82,0x82,0x85,0x80,0x81,0x84,0x82,0x9d,0xae,0x9b,0x9a,0x5e,0x1d,0x1b,0x0c,0x04,0x05,0x02,0x06,0x08,0x07,0x3b,0x06,0x18,0xb1,0x00,0xaa +,0xa0,0x1a,0x8b,0x9b,0x29,0xbc,0x3e,0x29,0x3f,0x9e,0xad,0xab,0xbe,0x2c,0x27,0x18,0x0f,0x1a,0x2c,0x18,0x95,0x0f,0x1d,0x92,0x03,0xb8,0x97,0x16,0x9a,0xb0,0x17,0x24 +,0x20,0x4d,0xa4,0x8a,0x92,0x8c,0x82,0x8a,0x8d,0x86,0x85,0x86,0x88,0x9e,0x80,0xa1,0x2f,0x8c,0x0d,0xd1,0x97,0x08,0xdb,0x25,0x03,0x0e,0x06,0x0d,0x13,0x1a,0xce,0x1d +,0x1c,0x29,0x09,0x19,0x19,0x0c,0x31,0x0e,0xce,0x10,0x07,0x9e,0x03,0x1c,0x8a,0x0e,0x9f,0x95,0x0e,0xa9,0x41,0x3a,0x9a,0x94,0x92,0x9c,0x9c,0xa3,0x2a,0xc8,0x46,0x1b +,0xde,0x0f,0xc8,0x19,0x05,0x99,0x19,0xbc,0x84,0xb2,0x86,0x80,0x8e,0x85,0x81,0x80,0x82,0x82,0x80,0x84,0x8a,0xa0,0x24,0xad,0x1a,0x0b,0x0e,0x03,0x13,0x05,0x03,0x22 +,0x00,0x10,0x9f,0x05,0xda,0x5d,0x07,0x3d,0x22,0x1d,0xd7,0xa4,0xc8,0x29,0x28,0x12,0x0e,0x1d,0x0e,0x16,0x20,0x09,0x9b,0x0b,0x10,0x8e,0x08,0x9b,0x88,0x20,0x8c,0x8e +,0x26,0xa6,0xa3,0xa3,0xb9,0x98,0xaf,0x1b,0x34,0x13,0x15,0x9f,0x23,0xbf,0x98,0x99,0x80,0x25,0x88,0x80,0x97,0x83,0x83,0x8a,0x80,0x8d,0x6f,0x8d,0xaf,0x2c,0x1e,0xc0 +,0x18,0x06,0x0c,0x05,0x01,0x0d,0x01,0x0c,0x09,0x0d,0x31,0x00,0xb4,0x1c,0x05,0x87,0x42,0x1c,0x8c,0x22,0x1b,0xf6,0xc7,0x39,0xb4,0x9d,0x22,0x3e,0xc9,0x0b,0x1f,0x3d +,0x11,0x4d,0x18,0x93,0x1b,0x0f,0x87,0x0e,0xed,0x87,0x23,0x9a,0x97,0x1d,0xd5,0x96,0x91,0xa9,0x87,0x81,0x8e,0x88,0x86,0x8e,0x80,0x8c,0x90,0x87,0x88,0x89,0x0f,0x91 +,0x97,0x05,0x98,0x5b,0x0c,0xda,0x0c,0x09,0x0b,0x0e,0x19,0x0d,0xeb,0x2c,0x07,0x4b,0x10,0x01,0x23,0x0b,0x0c,0x0f,0x3e,0x0f,0x05,0xa8,0x07,0x17,0x8b,0x19,0xb8,0x93 +,0x2a,0xef,0xd9,0xa4,0x9e,0x9b,0x8c,0x99,0xbd,0x9c,0x26,0x18,0x21,0x1d,0x0e,0x2c,0xab,0x00,0xb5,0xad,0x0a,0x8b,0x90,0x97,0x80,0x86,0x8b,0x83,0x80,0x85,0x85,0x80 +,0x81,0x86,0x8c,0x9c,0xaa,0x27,0x0d,0x0b,0x05,0x2d,0x0a,0x01,0x29,0x00,0x06,0x6a,0x0a,0x15,0xb0,0x14,0x13,0x1e,0x3e,0x1a,0xdf,0x9e,0x29,0x53,0x31,0x0f,0x12,0x0d +,0x0f,0x0e,0x15,0x98,0x03,0x47,0xa6,0x00,0x99,0x9b,0x2d,0x98,0x9a,0xa7,0x29,0xad,0xa0,0x15,0x90,0x8f,0x1b,0xb7,0x26,0x0f,0x40,0x14,0x25,0x32,0x87,0x93,0x24,0x80 +,0x88,0x8c,0x81,0x82,0x82,0x80,0x85,0x95,0x9d,0x8a,0x2e,0x1a,0x8e,0x1a,0x0c,0x26,0x03,0x05,0x08,0x05,0x05,0x0a,0xbc,0x04,0x1e,0xab,0x00,0x4c,0x9f,0x18,0xb3,0xc0 +,0x36,0x0e,0x19,0x36,0x0b,0x51,0xba,0x1b,0xd4,0xad,0x0e,0x17,0x24,0x28,0x0f,0x9a,0x92,0x06,0x87,0xad,0x0c,0x8a,0xa4,0xcc,0x91,0xa3,0x1a,0x16,0xaa,0x3f,0x20,0x8e +,0x87,0x8e,0x8d,0x8a,0x8a,0x86,0x87,0x8a,0x8b,0x80,0x9d,0xbc,0x80,0x3e,0xc7,0x8a,0x30,0x34,0x7a,0x1b,0x04,0x09,0x13,0x04,0x12,0x22,0x0b,0x0e,0x14,0x0d,0x05,0x0b +,0x14,0x06,0x0d,0xa7,0x06,0x15,0x98,0x0a,0x6f,0x95,0x34,0x31,0xae,0xdf,0x0f,0xaa,0x9b,0x38,0x9b,0xa4,0x37,0x30,0x31,0x2d,0x38,0x52,0x5d,0x0a,0x42,0x9f,0x00,0xaf +,0x92,0x2c,0x91,0x94,0x93,0x92,0x88,0x8b,0x8d,0x80,0x82,0x85,0x81,0x81,0x86,0x8e,0x8b,0x93,0xc3,0xa8,0x1f,0x03,0x16,0x17,0x00,0x18,0x14,0x07,0x21,0x18,0x0d,0x0a +,0x2d,0x1f,0x08,0xa2,0x51,0x12,0xc3,0x22,0x10,0x13,0x2e,0x19,0x0c,0x31,0x22,0x00,0x4a,0x24,0x07,0x94,0xbb,0x63,0x93,0x9b,0xaa,0x2a,0x9a,0x9d,0x2d,0x89,0x9e,0x2d +,0x9b,0x4c,0x0f,0x0f,0x4f,0x3a,0x27,0xcf,0xaa,0x1e,0x8e,0x8f,0x23,0x80,0x80,0x84,0x83,0x81,0x80,0x8c,0x84,0x89,0x9b,0x81,0x9a,0x20,0xaa,0x14,0x0b,0x02,0x0c,0x0c +,0x07,0x0d,0x07,0x00,0x08,0x19,0x02,0x2f,0xbb,0x1f,0xbc,0x19,0x2e,0x15,0x2c,0xba,0x18,0xa8,0xac,0x1c,0x26,0x2d,0x39,0x13,0x1f,0xa3,0x23,0x29,0x19,0x1c,0x10,0xae +,0x4e,0xb7,0x95,0x53,0x9c,0xb7,0x97,0xab,0x94,0x1a,0x00,0x45,0x8f,0x85,0x80,0x28,0x0f,0x8b,0x84,0x91,0x90,0x0c,0x01,0x1a,0x03,0x04,0x06,0x05,0x24,0x0b,0x02,0x07 +,0x00,0x08,0x0a,0x2c,0xa3,0x19,0x05,0x1a,0xc1,0x9c,0x8f,0x84,0x9e,0x30,0x83,0x80,0x89,0x8a,0x80,0x81,0x80,0x82,0x8b,0xa8,0x93,0x81,0x80,0x89,0x8b,0x80,0x82,0x82 +,0x84,0x81,0x8c,0x97,0x88,0x8b,0x89,0x87,0xba,0x17,0x26,0x29,0x19,0x0e,0x06,0x02,0x00,0x04,0x09,0x01,0x00,0x04,0x08,0x05,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01 +,0x00,0x02,0x03,0x07,0x0e,0x05,0x00,0x04,0x3c,0x99,0x1f,0x0b,0x1d,0xa6,0x21,0x21,0x2b,0x21,0x2c,0x93,0x83,0x3f,0xaf,0x84,0x81,0x80,0x82,0x82,0x88,0x8b,0x81,0x80 +,0x80,0x80,0x80,0x81,0x85,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x82,0x8a,0x85,0x80,0x80,0x89,0x3c,0x9d,0x8b,0xba,0x86,0x80,0x92,0x97,0x95,0x83,0x8a,0xae,0x8a,0x9f +,0x14,0x24,0x3e,0xfa,0x1b,0x0c,0x13,0x13,0x07,0x04,0x00,0x04,0x12,0x1b,0x09,0x00,0x00,0x05,0x0b,0x05,0x00,0x04,0x02,0x00,0x02,0x03,0x08,0x07,0x06,0x0f,0x04,0x03 +,0x09,0x00,0x01,0x01,0x02,0x02,0x03,0x01,0x08,0x04,0x13,0x11,0x02,0x01,0x0a,0x16,0x11,0x1f,0x00,0x0f,0x2b,0x10,0x1d,0x1a,0x9e,0x98,0x0a,0xb3,0x86,0x92,0x8b,0x9c +,0x9a,0xa8,0x37,0x1e,0x13,0x22,0x97,0x97,0xac,0xbc,0x95,0x8a,0x80,0x85,0x80,0x89,0x97,0x80,0x81,0x80,0x80,0x80,0x80,0x81,0x83,0x80,0x80,0x81,0x80,0x83,0x85,0x83 +,0x88,0x89,0x86,0x81,0x80,0x9d,0x17,0xb9,0x92,0x87,0x9b,0xa3,0x82,0x2f,0x8f,0x80,0x97,0x8b,0x80,0x85,0x86,0x8d,0x85,0x85,0xa6,0x87,0x84,0x27,0x1d,0x2b,0x0e,0x1e +,0xb9,0x92,0x38,0x02,0x10,0x1f,0x08,0x05,0x00,0x04,0x02,0x01,0x0c,0x04,0x00,0x29,0x1f,0x04,0x05,0x03,0x13,0x06,0x01,0x1a,0x09,0x00,0x03,0x00,0x03,0x02,0x09,0x06 +,0x01,0x00,0x0c,0x0a,0x05,0x00,0x0b,0x28,0x00,0x0d,0x0b,0x00,0x09,0x1f,0x07,0x03,0x06,0x1f,0x1e,0x02,0x0c,0x0d,0x00,0x01,0x05,0x02,0x0a,0x08,0x01,0x02,0x01,0x0b +,0x0f,0x01,0x03,0x00,0x29,0x14,0x0a,0x96,0xb4,0x4f,0x8d,0x9c,0x1f,0x19,0x2e,0x8f,0xbb,0x17,0x99,0x9f,0x47,0x8a,0x81,0x81,0x81,0x83,0x83,0x80,0x80,0x80,0x81,0x83 +,0x83,0x80,0x81,0x87,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x84,0x85,0x8b,0xa7,0x8a,0x82,0x81,0x81,0x82,0x82,0x81,0x81,0x80,0x81,0x84,0x85,0x84,0x80 +,0x8e,0x8d,0x80,0x82,0x81,0x8a,0x97,0x99,0x41,0xa8,0x8d,0x18,0x03,0x0a,0x01,0x00,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x02 +,0x07,0x02,0x02,0x01,0x02,0x03,0x03,0x0a,0x04,0x00,0x03,0x03,0x02,0x07,0x0c,0x0f,0x10,0x0b,0x35,0x25,0x0b,0x05,0x0b,0x0c,0x06,0x98,0xab,0x4f,0x82,0x82,0x86,0x89 +,0x8e,0x86,0x84,0x89,0x81,0x8b,0x28,0x9e,0x92,0x9c,0x93,0x91,0x8e,0x8f,0x96,0x88,0x87,0x8e,0x93,0x8e,0x9b,0x1f,0x90,0x2e,0x0f,0x92,0x91,0xb4,0xad,0xc5,0x9e,0x8a +,0x8f,0x8b,0x95,0x18,0x53,0xa8,0x3e,0xaf,0x35,0x47,0xac,0x13,0x17,0x41,0x19,0x13,0x14,0x0f,0x06,0x2b,0x1d,0x0b,0x97,0x8d,0x1b,0x0d,0x0d,0x14,0x25,0x1b,0xa9,0x9b +,0x1b,0x9d,0x8c,0x96,0x88,0x8a,0x88,0x80,0x87,0x85,0x82,0x88,0x87,0x86,0x8e,0xb8,0x89,0xa6,0xe4,0x83,0x87,0x9c,0x9e,0xa6,0x9e,0xa6,0x1d,0x42,0x0e,0x01,0x0a,0x05 +,0x03,0x0d,0x09,0x18,0xe6,0x14,0x18,0x1b,0x11,0x10,0x24,0x0e,0x13,0xa9,0x10,0x36,0x87,0x9c,0xa2,0x9e,0xaf,0x8e,0x9d,0xae,0x8b,0xae,0x4a,0x8f,0xb5,0x2c,0xbf,0x21 +,0xc5,0xa5,0x29,0xae,0x9b,0xa9,0x8f,0x8d,0x2c,0x95,0x8e,0x2c,0x8d,0x85,0x92,0x9a,0xce,0xc7,0x8e,0x38,0xb8,0x8b,0x20,0x3a,0x97,0x3a,0x3d,0xa6,0xb4,0x8f,0xa8,0x16 +,0x14,0x0c,0x03,0x08,0x03,0x04,0x2d,0x07,0x0c,0x94,0xa5,0x34,0xde,0x1f,0xab,0xa9,0x0e,0xbf,0xb0,0x10,0x2e,0x31,0x0f,0x1d,0x0d,0x13,0xc9,0x14,0x0b,0x17,0x09,0x0b +,0x15,0x02,0x15,0x19,0x00,0x0f,0x40,0x0f,0x71,0xa8,0x9f,0x80,0x8a,0x88,0x81,0x86,0x86,0x80,0x84,0x83,0x85,0x8c,0x82,0x83,0x8d,0x8f,0x93,0xba,0x9f,0x23,0x20,0x90 +,0x12,0x0b,0x98,0x3d,0x0b,0x16,0x06,0x09,0x0a,0x00,0x0c,0x0e,0x04,0x13,0x18,0x08,0x15,0x0b,0x0a,0x27,0x12,0x0d,0x10,0x05,0x0e,0x19,0x07,0xa7,0xb1,0x09,0x9a,0x8a +,0xbf,0x9b,0x95,0x93,0x89,0xab,0x94,0x89,0xda,0x3e,0x9d,0xae,0x6b,0xab,0xa3,0x8b,0x8a,0x92,0x93,0x9d,0xf8,0x98,0x5e,0xa5,0x89,0x1a,0x2e,0x8e,0xa4,0xab,0x95,0xbf +,0x8e,0x96,0xd0,0x92,0x99,0xa6,0x97,0xa0,0xbd,0x34,0x0a,0x17,0x15,0x07,0x07,0x0b,0x01,0x07,0x0e,0x0f,0x9b,0x2c,0x12,0x99,0xba,0x1f,0xb1,0x25,0xd1,0xaa,0x1f,0xc4 +,0xc1,0x1e,0x4f,0xac,0x3d,0x30,0x10,0x0c,0x23,0x1c,0x0e,0x14,0x0e,0x04,0x08,0x01,0x3f,0x9a,0x15,0x91,0x80,0x87,0x85,0x81,0x82,0x80,0x82,0x81,0x80,0x84,0x86,0x81 +,0x83,0x85,0x88,0x99,0x97,0x99,0xb8,0x1e,0x1a,0x0d,0x0d,0x05,0x0a,0xab,0x0d,0x00,0x1d,0x13,0x03,0x09,0x05,0x0e,0x11,0x04,0x1b,0x2c,0x0e,0x18,0x1f,0x21,0x23,0x0e +,0x0c,0x14,0x13,0x0b,0x0f,0x0f,0x0d,0x1a,0x0d,0xa3,0x8c,0x27,0x9c,0x84,0x95,0x8d,0x93,0xb0,0x8b,0xad,0x31,0x8f,0x95,0x9f,0x92,0x8b,0x86,0x89,0x9c,0x8f,0x8a,0xa9 +,0xb4,0xa4,0x1d,0x24,0x0f,0x17,0x89,0xad,0x33,0x8b,0x8d,0x9c,0x97,0xac,0x99,0x8e,0x7c,0xa4,0x94,0x78,0x27,0x25,0x1d,0x27,0x0e,0x04,0x16,0x17,0x0b,0x0f,0x13,0x0e +,0x0f,0x03,0x3c,0x90,0x0f,0x1e,0x9d,0x3f,0x2b,0x31,0x1f,0xb5,0x3c,0x17,0x54,0x62,0x1c,0x21,0x27,0x2f,0xb9,0x10,0x0a,0x18,0x0d,0x0c,0x11,0x11,0x21,0x2a,0x3b,0x85 +,0x82,0x88,0x80,0x80,0x80,0x80,0x81,0x85,0x80,0x88,0x8c,0x81,0x8b,0x8f,0x90,0xa2,0x94,0xad,0x14,0x21,0x17,0x0f,0x0d,0x08,0x02,0x03,0x01,0x00,0x14,0x0b,0x00,0x15 +,0x14,0x0f,0x29,0x09,0x16,0x4b,0x0b,0x1b,0x37,0x12,0x19,0x18,0x1b,0xaf,0x2a,0x1c,0xdf,0xde,0xc8,0xb7,0x31,0x26,0xb8,0x1d,0xe0,0x86,0xa1,0xb6,0x8b,0x92,0x93,0x93 +,0xcd,0x8f,0x89,0x9b,0x8c,0x85,0x8b,0x89,0x8c,0x8e,0x87,0xa9,0x2d,0xa8,0x4c,0x50,0x3e,0x16,0x1d,0x3b,0x0e,0x2f,0x8f,0x49,0xc7,0x92,0x9b,0x95,0xac,0x1a,0x53,0x32 +,0x0c,0x1a,0x25,0x14,0x1d,0x1b,0x24,0x48,0x0e,0x12,0x31,0x21,0x22,0x14,0x08,0x0a,0x0f,0x02,0x1a,0x9e,0x1b,0x29,0xa6,0xbc,0xa5,0x40,0x14,0xbf,0x4b,0x12,0x26,0x1e +,0x16,0x1c,0x14,0x22,0x49,0x23,0x2f,0x96,0x8d,0x8a,0x87,0x8e,0x86,0x82,0x8b,0x83,0x80,0x84,0x82,0x80,0x83,0x81,0x8f,0xa6,0x8c,0x9e,0x27,0x39,0x29,0x1e,0x1b,0x0e +,0x0e,0x14,0x06,0x03,0x09,0x05,0x06,0x03,0x01,0x03,0x07,0x00,0x0f,0x35,0x0f,0x27,0xb6,0x3f,0xbf,0x1b,0x13,0xb6,0x4b,0x22,0xbe,0xc3,0xb8,0x99,0xb8,0xa9,0x95,0xbe +,0xaf,0x9a,0xa6,0xa5,0xe0,0x23,0x55,0xf5,0x1a,0x9c,0x8c,0x9e,0x8a,0x86,0x8a,0x86,0x8d,0x95,0x87,0x8d,0x9c,0x99,0xaf,0xa1,0x98,0x45,0xce,0xa4,0x32,0xba,0xad,0x35 +,0xd5,0x24,0x18,0x2b,0x25,0x13,0x68,0xca,0x28,0xba,0xbb,0x56,0xbf,0x1d,0x13,0x3b,0x1f,0x17,0x20,0x1c,0x4e,0x52,0x10,0x1e,0x1f,0x12,0x25,0x1a,0x17,0x24,0x0f,0x0a +,0x11,0x12,0x0a,0x22,0x37,0x1c,0x3d,0x32,0x22,0x2a,0x13,0x10,0x29,0x1e,0x2a,0x42,0xbf,0x8a,0x86,0x8a,0x83,0x81,0x81,0x80,0x81,0x82,0x82,0x84,0x88,0x8b,0x8d,0xa3 +,0x90,0x8b,0x9c,0x96,0xa1,0x50,0x76,0x19,0x0f,0x16,0x0d,0x0b,0x0a,0x0a,0x14,0x13,0x08,0x0b,0x0b,0x06,0x08,0x09,0x08,0x0f,0x0e,0x0a,0x0e,0x0f,0x08,0x40,0xaa,0x57 +,0x9b,0x9a,0x97,0xa4,0x48,0xeb,0xa1,0xb0,0x98,0x9f,0xa2,0x8f,0x99,0xab,0x98,0x91,0x9d,0xa3,0x35,0xb1,0x9e,0xbd,0x3e,0x63,0x3c,0x48,0xae,0xa4,0x9e,0xa3,0x99,0xa5 +,0xab,0xeb,0x65,0x31,0x27,0xaf,0xa5,0xa7,0xb3,0xa9,0xba,0xaa,0xbe,0x4a,0xce,0x36,0x39,0x2e,0x16,0x12,0x15,0x1c,0x12,0x1a,0xc4,0xd0,0xbb,0xb7,0xa6,0x98,0xaa,0x38 +,0xca,0x49,0x4d,0xb4,0x44,0x3d,0x44,0x27,0x1e,0x14,0x14,0x1f,0x1c,0x1a,0x25,0x1c,0x13,0x1a,0x26,0x2f,0x4b,0xb5,0xad,0xac,0xbb,0xa6,0xa9,0xa6,0xa9,0xb4,0xad,0xb0 +,0xa0,0x96,0x99,0x98,0x95,0x9b,0xa2,0xb0,0xa7,0x9f,0x9f,0xa8,0xc3,0x27,0x29,0x23,0x21,0x1f,0x17,0xcb,0xac,0x47,0xd4,0xb7,0x9d,0x9a,0xae,0xab,0x9b,0x92,0x94,0x9a +,0x99,0x9d,0xa9,0x2b,0x19,0x1b,0x17,0x0f,0x0c,0x0c,0x07,0x05,0x07,0x0b,0x0e,0x0d,0x0b,0x18,0xcc,0x49,0xc5,0x9c,0x94,0x92,0x98,0x9a,0x96,0x8e,0x8f,0x91,0x98,0x98 +,0x9b,0xaa,0x9d,0x99,0x9e,0x96,0x96,0xa1,0x9c,0xb9,0xb5,0x95,0xa5,0x48,0xd0,0x2c,0x72,0xaa,0x45,0xb9,0xc6,0xde,0xf0,0x36,0x3e,0xa8,0xa5,0xab,0xab,0xef,0x35,0x36 +,0x51,0x2e,0x2c,0x1c,0x1a,0x1c,0x13,0x0f,0x0d,0x0e,0x12,0x10,0x0d,0x0f,0x16,0x14,0x15,0x19,0x1c,0x2b,0x29,0x1d,0x5f,0xec,0x24,0x32,0x23,0x28,0x39,0x29,0x20,0x43 +,0x44,0x3d,0x59,0x2e,0xb2,0x9f,0x9e,0x9b,0x95,0x93,0x90,0x90,0x8c,0x87,0x86,0x8b,0x8e,0x8a,0x88,0x86,0x8b,0x8d,0x8c,0x93,0x9e,0x9d,0xa7,0x98,0x92,0xa4,0x9f,0xa4 +,0x3c,0x26,0x1c,0x1a,0x23,0x10,0x07,0x04,0x04,0x05,0x04,0x04,0x03,0x03,0x02,0x02,0x01,0x03,0x04,0x07,0x08,0x0e,0x18,0x0f,0x16,0x42,0xbb,0x99,0x93,0xa5,0x9e,0x8f +,0x93,0x98,0x8e,0x93,0x91,0x95,0xbf,0xbd,0xaa,0xa0,0x92,0x92,0x8b,0x85,0x8b,0x8c,0x85,0x83,0x82,0x83,0x88,0x86,0x84,0x89,0x8d,0x8f,0x8f,0x93,0x9f,0x37,0x35,0xe3 +,0x2b,0x2b,0x36,0x2e,0x2f,0x21,0x19,0x21,0x32,0x37,0x1f,0x17,0x22,0x1e,0x0f,0x0f,0x17,0x12,0x14,0x10,0x0a,0x0e,0x10,0x0f,0x12,0x1b,0x19,0x1d,0x1e,0x1b,0x21,0x3f +,0xc3,0xcb,0x3c,0x2b,0x3b,0x37,0x6a,0x2e,0x24,0x26,0x25,0x18,0x12,0x1d,0x2e,0xdd,0xbb,0xbd,0xad,0xa7,0xa1,0x93,0x8c,0x8f,0x93,0x97,0x9c,0x97,0x9c,0x98,0x95,0x9b +,0xa2,0xad,0xa5,0x9c,0x99,0x96,0x93,0x8f,0x98,0xc4,0xe8,0xab,0xa4,0xac,0x2a,0x1a,0x1b,0x15,0x10,0x0b,0x0a,0x0b,0x09,0x08,0x0c,0x0c,0x0e,0x1b,0x20,0x2e,0xdd,0xc0 +,0xc8,0xa6,0x90,0x89,0x87,0x85,0x87,0x88,0x87,0x87,0x87,0x8a,0x88,0x89,0x8c,0x92,0x9d,0xaa,0xa2,0xa1,0xaf,0xb5,0x37,0x41,0x2f,0x1a,0x1a,0x1e,0x1b,0x0f,0x0b,0x09 +,0x06,0x05,0x07,0x04,0x04,0x02,0x04,0x03,0x02,0x04,0x06,0x0a,0x0c,0x0c,0x0c,0x15,0x17,0x23,0x5f,0x58,0x51,0xdb,0xbb,0xb5,0xa4,0x9d,0x9b,0x97,0x96,0xa3,0x57,0xc7 +,0xa1,0x97,0x99,0x99,0x8f,0x8d,0x8d,0x8d,0x88,0x86,0x87,0x8a,0x8d,0x8b,0x8a,0x8d,0x8b,0x8c,0x91,0x95,0xa8,0xbe,0xba,0xc5,0xbe,0xb1,0xad,0xad,0xd3,0x4d,0x76,0xc7 +,0xb5,0xb9,0x5f,0x26,0x28,0x2a,0x1c,0x1a,0x18,0x13,0x17,0x0f,0x0c,0x12,0x15,0x25,0x27,0x1c,0x26,0x22,0x2d,0x2d,0x27,0x3e,0x4c,0x29,0x24,0x26,0x1a,0x1c,0x20,0x1c +,0x18,0x1a,0x16,0x0d,0x10,0x19,0x20,0x1d,0x15,0x29,0x3f,0x4f,0xbf,0xa8,0x99,0x9f,0xaf,0xb9,0xa7,0xc3,0xad,0xa6,0xa8,0xa3,0xac,0xe6,0x52,0xa1,0x98,0x96,0x9c,0x9c +,0x9c,0x9f,0xac,0xa8,0x98,0x97,0xaf,0x2c,0x1d,0x1b,0x1e,0x20,0x1f,0x1c,0x1e,0x1e,0x0d,0x0d,0x22,0x2e,0xcf,0xab,0x97,0x8f,0x8f,0x8e,0x8b,0x85,0x83,0x85,0x87,0x86 +,0x86,0x87,0x87,0x89,0x89,0x87,0x8d,0x9a,0xa5,0xa3,0xad,0xc1,0xe8,0x2b,0x1e,0x1c,0x1a,0x0d,0x0f,0x13,0x0c,0x0a,0x07,0x04,0x06,0x06,0x04,0x04,0x03,0x03,0x02,0x02 +,0x05,0x07,0x0b,0x0b,0x0d,0x16,0x19,0x1d,0x22,0xbb,0xa4,0xd9,0xd8,0xcf,0xb0,0x9b,0x9d,0xa3,0x9b,0xa2,0xab,0xa4,0xaa,0xa3,0x95,0x93,0x99,0x95,0x8d,0x8e,0x8f,0x89 +,0x84,0x87,0x88,0x8b,0x8b,0x8b,0x8b,0x8d,0x8e,0x8d,0x93,0xa2,0xc9,0xcb,0xac,0xa1,0xb7,0x78,0xba,0xe5,0x34,0x35,0x4a,0x56,0x35,0x30,0x2a,0x1c,0x1e,0x1d,0x1c,0x18 +,0x18,0x12,0x0d,0x0d,0x0c,0x15,0x1b,0x19,0x14,0x19,0x19,0x1e,0x28,0x2f,0xdf,0x40,0x21,0x1d,0x1d,0x1a,0x1f,0x1e,0x23,0x1d,0x15,0x10,0x1b,0x2a,0x28,0x36,0x39,0xed +,0xce,0xbc,0xaf,0xa0,0x9c,0x99,0x9f,0xad,0xa2,0xae,0xa6,0x9a,0x9e,0xa8,0xb9,0xc2,0xb3,0xc6,0xb8,0x9c,0x93,0x92,0x97,0x97,0x98,0x95,0x96,0xa1,0xac,0xb3,0xcd,0x3f +,0x28,0x18,0x16,0x14,0x0d,0x0d,0x0e,0x12,0x14,0x19,0x1f,0x34,0xde,0xaa,0x9c,0x8f,0x8a,0x8c,0x8a,0x8a,0x89,0x86,0x85,0x87,0x88,0x8a,0x8d,0x8d,0x8a,0x8c,0x91,0x91 +,0x95,0x9d,0xaa,0xaa,0xac,0xaf,0x37,0x19,0x17,0x10,0x0c,0x09,0x06,0x05,0x05,0x03,0x01,0x01,0x03,0x04,0x03,0x03,0x05,0x05,0x09,0x0b,0x0e,0x17,0x1f,0x1d,0x18,0x20 +,0x2d,0x3e,0xdb,0xb8,0x5d,0x5c,0x44,0x4d,0xac,0x9e,0x9c,0x9a,0x96,0x97,0x97,0x97,0x8c,0x89,0x89,0x8b,0x8d,0x8c,0x8b,0x8d,0x8e,0x8b,0x8a,0x8d,0x95,0x9c,0x98,0x8e +,0x8f,0x91,0x92,0x92,0x97,0x9c,0x9d,0x95,0x8c,0x93,0xa4,0xc2,0xca,0xd7,0x40,0x29,0x29,0x1d,0x1c,0x17,0x0b,0x0e,0x18,0x1a,0x12,0x15,0x1a,0x1d,0x1b,0x18,0x24,0x3a +,0x2d,0x1f,0x1a,0x1b,0x1a,0x1b,0x1a,0x17,0x15,0x0f,0x0e,0x0d,0x0e,0x13,0x12,0x17,0x1d,0x1c,0x1f,0x2f,0x78,0xae,0xb1,0xc7,0x7d,0xc2,0xb2,0xbf,0xaf,0xac,0xb4,0xcc +,0xcd,0x46,0x3f,0xd4,0xb9,0xa8,0xa1,0x9b,0x9d,0x99,0x92,0x8d,0x8a,0x8b,0x90,0x90,0x95,0x9c,0xa1,0xa5,0xa0,0xbc,0x35,0x22,0x19,0x16,0x12,0x17,0x18,0x1c,0x21,0x18 +,0x1e,0x5c,0xb1,0xa4,0x9c,0x9b,0x95,0x8f,0x91,0x8f,0x8c,0x89,0x8b,0x8c,0x8a,0x8c,0x8f,0x8e,0x8c,0x8a,0x8c,0x90,0x96,0x92,0x92,0x9e,0xa7,0xac,0xcc,0x2f,0x1f,0x12 +,0x0d,0x0b,0x08,0x05,0x04,0x05,0x02,0x01,0x01,0x02,0x03,0x04,0x03,0x05,0x08,0x08,0x0a,0x10,0x17,0x1e,0x1d,0x1a,0x1b,0x22,0x35,0x2b,0x2b,0xbf,0xcb,0x31,0x30,0x78 +,0xa0,0x9a,0x9c,0x99,0x95,0x92,0x9b,0x95,0x88,0x88,0x8c,0x8f,0x8f,0x8d,0x8f,0x94,0x93,0x8d,0x89,0x90,0x9a,0x9d,0x99,0x90,0x92,0x95,0x90,0x92,0x9b,0x9e,0x9d,0x91 +,0x92,0x9a,0xac,0xc3,0xcb,0x39,0x37,0x33,0x38,0x2c,0x18,0x0f,0x0d,0x11,0x20,0x19,0x14,0x19,0x1b,0x22,0x1c,0x19,0x45,0x47,0x1d,0x1a,0x1c,0x31,0x25,0x18,0x13,0x15 +,0x18,0x14,0x0b,0x0a,0x10,0x18,0x1a,0x18,0x20,0x1e,0x1f,0x1e,0x2c,0xaf,0xb9,0x6e,0xcc,0xeb,0xc5,0xc9,0x7d,0xb9,0xb9,0xb7,0xcc,0x3b,0x45,0xac,0xa9,0xab,0x9e,0x9f +,0x9c,0x95,0x94,0x8f,0x8c,0x91,0x92,0x94,0x9c,0x99,0xa7,0xb6,0xab,0x47,0x27,0x1f,0x1a,0x19,0x1a,0x17,0x17,0x21,0x2c,0x29,0x25,0x33,0xa9,0x99,0x9e,0x9e,0x97,0x8e +,0x8c,0x8e,0x8e,0x8b,0x8a,0x8b,0x8e,0x8f,0x8a,0x8a,0x8f,0x8f,0x8d,0x91,0x93,0x9d,0x9e,0x8e,0x9a,0xad,0xcf,0x19,0x1a,0x1c,0x0d,0x0f,0x0c,0x07,0x06,0x03,0x02,0x02 +,0x02,0x05,0x04,0x03,0x03,0x02,0x06,0x0b,0x0f,0x0e,0x0b,0x0f,0x2c,0x48,0x37,0x22,0x20,0x33,0x3f,0x40,0xc3,0xb5,0xad,0x9d,0xa2,0xac,0xa6,0x98,0x97,0x95,0x97,0x8e +,0x8e,0x99,0x98,0x9b,0x8f,0x8c,0x98,0xa0,0x88,0x86,0x88,0x98,0xda,0x9b,0x8f,0x8c,0x8b,0x8f,0x8b,0x89,0x97,0xa5,0x9e,0x8f,0x93,0x9b,0xcb,0x40,0x6e,0x24,0x16,0x1a +,0x17,0x17,0x17,0x04,0x0d,0x91,0x85,0x24,0x00,0x50,0x97,0x3b,0x9e,0x2f,0x5d,0x16,0x10,0x04,0x0d,0x11,0x00,0x11,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x02,0x04,0x02 +,0x04,0x3d,0xc1,0x1f,0x18,0x11,0xaf,0x8e,0x8a,0x87,0x84,0x87,0x80,0x88,0x9b,0x83,0x80,0x80,0x80,0x86,0x83,0x84,0x85,0x85,0x82,0x83,0x84,0x81,0x89,0x82,0x80,0x83 +,0x8d,0xbf,0x39,0x93,0x9d,0xa9,0x8c,0x9f,0x50,0x0e,0x05,0x08,0x18,0x14,0x05,0x07,0x03,0x04,0x00,0x02,0x01,0x02,0x00,0x00,0x00,0x00,0x18,0x09,0x00,0x02,0x00,0x02 +,0x01,0x02,0x09,0x11,0x13,0x07,0x01,0x00,0x0a,0x22,0x24,0x2a,0x1c,0x30,0x16,0x15,0xc3,0x9d,0xa8,0xab,0xaa,0x9c,0x81,0x80,0x82,0x8a,0x9f,0x93,0x82,0x82,0x81,0x80 +,0x81,0x80,0x87,0x8b,0x82,0x80,0x80,0x80,0x82,0x80,0x82,0x81,0x84,0x83,0x83,0x85,0x84,0x8f,0x83,0x80,0x82,0x88,0xb6,0x34,0x8c,0x89,0x91,0x82,0x86,0x8f,0xfc,0x09 +,0x09,0x2a,0x34,0x1e,0x0e,0x05,0x09,0x00,0x02,0x01,0x04,0x01,0x01,0x00,0x04,0x9d,0x1b,0x00,0x01,0x00,0x03,0x05,0x03,0x0b,0x1c,0x19,0x06,0x00,0x00,0x02,0x0f,0x0d +,0x0a,0x04,0x06,0x06,0x01,0x02,0x05,0x08,0x02,0x04,0x00,0xa3,0x88,0x12,0x06,0x00,0x03,0x2e,0x18,0x1d,0x97,0x8d,0x8f,0x16,0x03,0x10,0x9c,0x90,0x8f,0x9b,0x9b,0x8c +,0x99,0xb0,0x99,0x8c,0x8e,0x93,0xab,0x8a,0x80,0x81,0x85,0xb8,0xc2,0x87,0x80,0x84,0x80,0x80,0x80,0x82,0xa3,0xad,0x84,0x81,0x80,0x83,0x85,0x83,0x86,0x8e,0x98,0x89 +,0x8d,0x90,0xb6,0xa0,0x80,0x80,0x89,0x53,0x10,0xa4,0x82,0x8d,0x87,0x80,0x82,0x80,0xac,0x1b,0x96,0x84,0x85,0x85,0x8e,0x86,0x8a,0x9d,0xcd,0xa1,0x92,0x96,0xc1,0x21 +,0x87,0x80,0x8a,0x22,0x03,0x0e,0x8f,0xab,0xc9,0x96,0x92,0x88,0x0f,0x00,0x02,0x07,0x0e,0x0e,0x04,0x06,0x09,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x07,0x97,0x0f,0x00 +,0x02,0x00,0x03,0x02,0x01,0x04,0x07,0x16,0x0a,0x00,0x01,0x00,0x03,0x03,0x04,0x00,0x07,0x01,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x94,0x9f,0x04,0x03,0x00,0x06,0x1e +,0x0a,0x20,0xac,0x97,0x87,0x14,0x04,0x1f,0x9f,0x8a,0x87,0x8d,0x83,0x82,0x86,0x8a,0x8e,0x85,0x81,0x84,0x88,0x81,0x80,0x80,0x83,0x9e,0x8b,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x8d,0x89,0x80,0x81,0x80,0x80,0x80,0x80,0x81,0x81,0x89,0x89,0x83,0x84,0x8e,0x88,0x80,0x81,0x86,0x2c,0x1a,0x8e,0x86,0x95,0x87,0x82,0x82,0x82,0x1d,0x0b +,0x20,0x3e,0xa2,0x66,0x1b,0x42,0x20,0x09,0x05,0x00,0x06,0x03,0x04,0x00,0xb4,0x8d,0x05,0x02,0x00,0x00,0x07,0x03,0x02,0x0b,0x13,0x23,0x06,0x00,0x01,0x00,0x05,0x07 +,0x05,0x05,0x0c,0x02,0x02,0x00,0x03,0x02,0x04,0x00,0x0d,0x85,0xb5,0x08,0x04,0x00,0x10,0x20,0x0a,0x3a,0x9f,0x8e,0x90,0x08,0x06,0x11,0x1e,0xd6,0xd6,0xf3,0x9a,0xa9 +,0x2a,0x19,0x1d,0x51,0xee,0x29,0x19,0x89,0x80,0x91,0x2f,0x09,0x2e,0x8b,0x99,0x9f,0x83,0x85,0x80,0x8e,0x17,0xbc,0x9e,0x94,0x8b,0x96,0x8c,0x87,0x9e,0xaf,0x4a,0xb6 +,0xa4,0xc4,0x1b,0xeb,0x80,0x86,0x9f,0x12,0x08,0xbb,0x98,0x2a,0xa0,0x8a,0x87,0x84,0x1c,0x08,0x1f,0x23,0xd4,0xc9,0x38,0x9b,0xb8,0x1b,0x1a,0x11,0x2a,0x1d,0x11,0x07 +,0xac,0x80,0x9b,0x29,0x07,0x0a,0xa5,0xd4,0x19,0x97,0x8c,0x82,0x8c,0x0e,0x13,0x36,0x4e,0xa3,0xb1,0x9f,0x8a,0xad,0x69,0x3f,0x4f,0xa6,0x79,0x1e,0x27,0x85,0x80,0x8e +,0xce,0x11,0x30,0x8c,0xb5,0xbf,0x86,0x85,0x80,0x90,0x17,0x2e,0xb4,0xac,0x9b,0xb1,0x9b,0x90,0xd8,0x31,0x26,0x2c,0x25,0x14,0x08,0x10,0x82,0x88,0x4f,0x10,0x02,0x15 +,0x32,0x0b,0x1c,0x97,0x8a,0x86,0x21,0x05,0x11,0x19,0x23,0x47,0x2f,0xa9,0xa2,0x21,0x1e,0x18,0x1e,0x18,0x0f,0x06,0x23,0x80,0x8c,0xd8,0x0f,0x08,0x32,0x33,0x0d,0xc3 +,0x8a,0x85,0x87,0x1c,0x0b,0x2a,0x20,0x2d,0xf1,0x44,0x96,0x9b,0x34,0x3a,0x1f,0x23,0x16,0x0f,0x09,0xca,0x80,0x8d,0x6b,0x0d,0x0b,0x36,0x20,0x0c,0xa6,0x88,0x85,0x8d +,0x13,0x0d,0x2f,0x20,0x2a,0x38,0x56,0x95,0xa1,0x32,0x2d,0x17,0x1d,0x0e,0x0c,0x0b,0xaf,0x80,0x8e,0x39,0x0e,0x0b,0x29,0x1f,0x0d,0x96,0x85,0x86,0x8d,0x14,0x0f,0x3d +,0x1f,0x36,0x68,0xbe,0x90,0x9f,0x3e,0x3b,0x17,0x1d,0x0f,0x0e,0x0f,0xaf,0x80,0x8e,0x6c,0x17,0x0b,0x2e,0x25,0x10,0x8f,0x85,0x85,0x8b,0x1a,0x11,0xc9,0x27,0x2c,0x44 +,0xc0,0x8f,0x9c,0x34,0x3a,0x1e,0x1b,0x0f,0x10,0x0d,0xae,0x80,0x93,0xb9,0x14,0x09,0x2b,0x1c,0x11,0x91,0x86,0x87,0x8f,0x1a,0x14,0x44,0x21,0x1f,0x2d,0xae,0x8e,0x9e +,0x28,0x31,0x1d,0x16,0x0f,0x0e,0x15,0xb4,0x80,0x8c,0x52,0x16,0x0b,0x1e,0x2d,0x11,0x97,0x86,0x8b,0x8f,0x1d,0x17,0x3d,0x1d,0x29,0x2c,0xb7,0x93,0xa7,0x2d,0x2c,0x13 +,0x18,0x12,0x0b,0x25,0x1f,0x86,0x86,0x37,0x16,0x0c,0x1a,0xcc,0x14,0xc0,0x86,0x8c,0x8d,0x39,0x15,0x42,0x2e,0x29,0x34,0xc8,0x95,0x9b,0xde,0x2e,0x1a,0x1d,0x21,0x10 +,0x29,0x1c,0x8f,0x80,0xbd,0x1d,0x0f,0x1c,0xb3,0x18,0x1e,0x8b,0x89,0x8b,0xa9,0x18,0x39,0xd7,0x1c,0x2a,0xe7,0x9c,0x97,0xdd,0x32,0x29,0x1a,0x27,0x16,0x18,0x20,0x41 +,0x81,0x94,0x21,0x1f,0x17,0x2f,0x22,0x0e,0xa2,0x88,0x8c,0x97,0x21,0x1d,0x4c,0x1e,0x20,0x5e,0xa9,0x97,0xf0,0x2a,0x30,0x1d,0x21,0x26,0x12,0x23,0x13,0x9e,0x82,0xc6 +,0x3a,0x28,0x1a,0x35,0x11,0x13,0x8d,0x8a,0x8e,0xad,0x1b,0x3a,0x3d,0x1d,0x32,0xae,0x9b,0x9f,0x41,0x2c,0x42,0x23,0x2d,0x1a,0x15,0x21,0x1d,0x87,0x89,0x7d,0x5d,0x20 +,0x1d,0x26,0x0b,0xae,0x86,0x8f,0x93,0x4a,0x2c,0xae,0x21,0x16,0xa6,0xaa,0x9e,0xcb,0x33,0xb7,0x39,0x1f,0x1e,0x12,0x22,0x18,0xce,0x80,0x95,0x48,0x25,0x10,0x27,0x19 +,0x18,0x8d,0x8b,0x8e,0x9e,0x28,0xd5,0x35,0x11,0x3d,0xb5,0xbf,0xab,0x39,0xcc,0xbf,0x1c,0x19,0x16,0x0f,0x20,0x18,0x8f,0x82,0xb9,0x23,0x14,0x18,0x2a,0x0f,0xe7,0x88 +,0x8e,0x92,0xb3,0x2b,0x45,0x1d,0x1a,0xca,0xdd,0xa9,0xba,0x57,0xa8,0x2e,0x11,0x1e,0x0e,0x1a,0x28,0xad,0x80,0x95,0x25,0x1f,0x1c,0x33,0x1d,0x18,0x8e,0x88,0x91,0x9b +,0x3a,0xc0,0x60,0x15,0x29,0xb4,0xa4,0xa7,0xc9,0xb5,0x4d,0x16,0x1c,0x14,0x1a,0x28,0x4d,0x83,0x8e,0x2c,0x31,0x25,0x2b,0x20,0x10,0x9c,0x86,0x90,0x9a,0x44,0x70,0xec +,0x13,0x19,0xd9,0xa5,0xa8,0x51,0x6c,0x5d,0x1c,0x11,0x0d,0x1c,0x2a,0xbd,0x85,0x98,0x3f,0x33,0x1a,0x24,0x17,0x1c,0x99,0x8c,0x8f,0x95,0x55,0x5b,0x2c,0x13,0x1e,0x72 +,0x9f,0xa1,0xcf,0xd8,0x54,0x1d,0x0f,0x0e,0x24,0x33,0x91,0x8a,0xad,0xb4,0x33,0x1d,0x19,0x15,0xc6,0x8f,0x91,0x8e,0x9c,0xbc,0xea,0x20,0x18,0x36,0xb0,0xa2,0xa9,0xc1 +,0xc0,0x2a,0x13,0x0c,0x19,0x1f,0x96,0x88,0xad,0xab,0xe2,0x1f,0x1b,0x0c,0x2a,0x8d,0x93,0x91,0x98,0xad,0xb2,0x28,0x13,0x20,0xcf,0xab,0xa4,0xac,0xc3,0x2b,0x15,0x0a +,0x19,0x15,0x95,0x87,0x6b,0xa9,0xc5,0x1f,0x17,0x0b,0x24,0x90,0x93,0x90,0x9a,0xa4,0xab,0x2a,0x10,0x1d,0xcf,0xaa,0xb2,0xac,0xb4,0x34,0x0c,0x09,0x11,0x3b,0x88,0x96 +,0xb0,0xae,0x5a,0x26,0x0f,0x0f,0xac,0x99,0x93,0x8f,0x99,0x9d,0xbc,0x19,0x1c,0x2c,0xef,0xa4,0xbd,0xbc,0xbb,0x19,0x0f,0x1a,0x0e,0x91,0x8d,0x56,0x9f,0x3b,0x17,0x24 +,0x18,0xd8,0x9a,0xa6,0x8d,0x95,0xa5,0xa8,0x1f,0x1d,0xee,0x2a,0x4f,0xa8,0xa9,0xb7,0x10,0x09,0x26,0x19,0x99,0x8f,0x37,0x9b,0xb6,0x14,0x14,0x14,0xcf,0x93,0xa7,0x91 +,0x91,0x9e,0xad,0x18,0x20,0xc4,0x3d,0xc6,0xc1,0xd9,0xa3,0x11,0x07,0x18,0x1b,0x8b,0x8f,0xf7,0x9b,0x42,0x1a,0x0e,0x08,0xda,0x92,0x96,0x87,0x97,0xa6,0xb8,0x13,0x1c +,0x3b,0xdc,0xa4,0xa3,0xac,0xc3,0x09,0x0f,0x14,0x2c,0x88,0xa3,0x9d,0x90,0x29,0x16,0x0d,0x12,0xb3,0xe2,0x92,0x89,0x90,0x98,0x29,0x17,0x26,0x29,0x27,0x9e,0x99,0x9f +,0x23,0x09,0x1b,0x14,0x9e,0x97,0x1e,0x92,0x9f,0x33,0x1d,0x0e,0x37,0xc3,0x5d,0x97,0x94,0x90,0x96,0x27,0x20,0x22,0x19,0x44,0xb9,0x9f,0x54,0x13,0x22,0x10,0xca,0x8d +,0x3b,0xa5,0x97,0x2b,0x20,0x10,0x27,0xa2,0xc7,0x9b,0x9a,0xa2,0xb0,0x25,0x2e,0xae,0x32,0x2b,0xb5,0x7d,0xf4,0x0e,0x17,0x25,0xa7,0x90,0x2a,0xa6,0x95,0x34,0x1d,0x15 +,0x27,0x9c,0xcf,0x98,0x94,0x99,0xa3,0x1e,0x1f,0x37,0x2e,0x3c,0xa4,0xaf,0x3d,0x0d,0x12,0x1d,0xb5,0x92,0xc3,0xa1,0x9f,0x27,0x1b,0x20,0x44,0xbb,0xcf,0x9a,0x91,0x95 +,0x9e,0x37,0x23,0x34,0x1b,0x4d,0xa9,0xcf,0x51,0x11,0x1c,0x17,0xaf,0x91,0x3b,0x9c,0x9d,0x2a,0x18,0x12,0x3c,0xaf,0xc6,0x93,0x98,0x9a,0xaf,0x2f,0xbd,0x3b,0x1e,0xe7 +,0x4d,0x43,0x28,0x11,0x24,0x14,0x93,0x90,0x2f,0x9d,0xa8,0x38,0x18,0x13,0x39,0xb2,0xc3,0x9b,0x93,0x96,0xae,0x37,0x35,0x2d,0x1d,0xbc,0xaf,0x48,0x1c,0x10,0x25,0x1a +,0x8f,0x9c,0x43,0x90,0xb0,0x1e,0x19,0x1b,0x55,0xbe,0xd8,0x93,0x92,0x9b,0xb4,0x36,0xcc,0x38,0x29,0xc7,0x3e,0x4b,0x14,0x18,0x18,0x19,0x8a,0xaf,0xc7,0x91,0x4c,0x23 +,0x16,0x25,0xa9,0xb4,0xa3,0x94,0x93,0xa7,0x2f,0x4a,0xc0,0x35,0x2c,0xd2,0xdc,0x2b,0x0c,0x1e,0x16,0xcf,0x8d,0x26,0xab,0x91,0xb2,0x1c,0x11,0x1d,0xbe,0xce,0xa3,0x91 +,0x8e,0xa2,0x4d,0x3f,0x3f,0x1e,0x26,0xab,0xda,0x2a,0x0b,0x27,0x13,0xad,0x94,0x1f,0x94,0x95,0x30,0x1f,0x1f,0x35,0xbc,0x2f,0x9b,0x98,0x99,0xaa,0xaf,0xa3,0x6f,0x1f +,0x27,0x3a,0x2d,0x19,0x18,0x65,0x12,0x8e,0xa1,0x21,0x95,0xb9,0x3d,0x1f,0x1c,0x6c,0x55,0xb6,0x92,0x97,0x9f,0x30,0xc5,0xab,0xcd,0x31,0x4f,0xb3,0x28,0x0a,0x17,0x18 +,0x2a,0x87,0xb7,0xbe,0x98,0x54,0x23,0x13,0x1a,0xba,0xc7,0xa4,0x90,0x92,0xa1,0x77,0x3e,0xdf,0x2a,0x1d,0xae,0xb2,0x37,0x0d,0x1e,0x13,0x3e,0x8d,0x1f,0xa3,0x8e,0xf0 +,0x2b,0x13,0x2c,0xb0,0x24,0xa2,0x93,0x91,0x9d,0x56,0xb3,0xb3,0x22,0x20,0x47,0x29,0x1a,0x15,0x2f,0x13,0x9b,0x8f,0x21,0xa6,0xe0,0x55,0x2a,0x1b,0xa8,0xb1,0xc1,0x9d +,0x9e,0x9d,0xc4,0xb2,0xa1,0xa9,0x2d,0x2c,0xc8,0x21,0x0f,0x0b,0x16,0x1c,0x8d,0x9a,0x3f,0x94,0xac,0x2f,0x12,0x16,0xb9,0xb2,0xae,0x97,0x95,0x95,0xc4,0x43,0xf9,0xd0 +,0x3a,0xba,0x7e,0x2f,0x10,0x0d,0x14,0x0f,0x8d,0xb9,0xbe,0x8e,0xb1,0x62,0x1e,0x26,0xb9,0x27,0x56,0x96,0x97,0x96,0xc3,0x9c,0xa6,0x34,0x1f,0x3d,0x3d,0x47,0x0d,0x17 +,0x19,0x17,0x8d,0x27,0xbf,0x9b,0xb4,0xe4,0x23,0x36,0xad,0x53,0xb8,0xab,0xaa,0x9d,0xad,0x99,0xa5,0xbb,0x36,0xb2,0x1f,0x1d,0x0e,0x1d,0x1a,0x22,0x8c,0x28,0xac,0xa3 +,0x5b,0x35,0x27,0x40,0xb9,0x49,0xb7,0x9c,0xa6,0xa2,0xd3,0x9d,0xa1,0xc5,0x2d,0xe1,0x33,0x25,0x0e,0x1c,0x11,0x2b,0x8b,0x16,0xa2,0x9e,0xbc,0x3d,0x18,0xba,0xce,0xdb +,0xaf,0xaa,0xa4,0xa5,0xb7,0x90,0xa3,0xd3,0x28,0x52,0x4e,0x15,0x0e,0x1b,0x1b,0xce,0x9c,0x12,0x9e,0x9e,0xc2,0x24,0x29,0xa3,0xb7,0x50,0x32,0x9c,0xa3,0xab,0xae,0x9e +,0x97,0xcc,0x39,0xcc,0x2d,0x1f,0x0d,0x18,0x19,0xc4,0x9a,0x10,0xac,0xa2,0x38,0xe4,0x32,0x9f,0xa7,0xbb,0x4b,0xe5,0xa5,0x60,0xab,0x9d,0x9b,0xaf,0x2d,0xe6,0x3d,0x1e +,0x19,0x1b,0x1c,0xc9,0xb4,0x16,0xf1,0x9b,0x2e,0x29,0x50,0x9f,0xa2,0xac,0xce,0xc4,0xa1,0x63,0xdc,0xa8,0x9c,0xac,0x42,0xbe,0xc8,0x2d,0x1e,0x16,0x21,0x51,0x6f,0x19 +,0x2a,0xab,0x30,0x2b,0x31,0xab,0x9f,0xc9,0xbc,0xb1,0xa2,0x9c,0xba,0xa4,0xa8,0xb8,0xc7,0x2e,0xad,0xbb,0x36,0x26,0x19,0x37,0x25,0x11,0x1d,0x32,0x46,0x2c,0x34,0xaf +,0xa5,0xaf,0xcf,0xc9,0xa5,0x9a,0x9c,0x9d,0x9a,0x9f,0xdb,0x36,0x3c,0xce,0x4b,0x29,0x26,0x2e,0x3c,0x17,0x0f,0x1b,0x1e,0x38,0xef,0x40,0xa7,0xa1,0xa6,0xeb,0xbe,0x95 +,0x99,0x96,0xa5,0xa8,0x9d,0xce,0xe2,0x34,0x2e,0x39,0x1c,0x1f,0x1f,0x22,0x24,0x1d,0x1b,0x1f,0x36,0xd6,0x54,0xac,0xa6,0xb1,0xa2,0xa3,0x94,0x9a,0x9c,0x9d,0xbd,0xdb +,0xb2,0xba,0xbc,0x35,0x1e,0x1e,0x14,0x1e,0x16,0x1b,0x2f,0x3c,0x4a,0x2e,0x42,0xdb,0x67,0xff,0xaf,0x99,0x90,0x92,0x9a,0xa1,0xa7,0xb7,0xaf,0xca,0x50,0xb8,0x3b,0x24 +,0x19,0x14,0x1e,0x11,0x14,0x27,0x2d,0xb0,0x5b,0x44,0xcd,0x3a,0xb7,0xa7,0x99,0x92,0x99,0x93,0xa0,0xaf,0xad,0xc5,0xaf,0xbb,0x3e,0x28,0x19,0x1a,0x1e,0x17,0x15,0x1e +,0x31,0x20,0x29,0x5b,0xd8,0xaf,0xad,0xac,0x9d,0x98,0x97,0x9f,0xa9,0x98,0xa5,0xa2,0xaf,0xbb,0xb0,0x26,0x1f,0x14,0x17,0x1e,0x16,0x20,0x2c,0x1f,0x30,0x26,0x2b,0x42 +,0xae,0x9d,0xab,0x94,0x98,0x9e,0x9e,0xac,0xa0,0xa7,0xa3,0xaa,0xb1,0xbf,0x1d,0x19,0x18,0x1b,0x1f,0x16,0x25,0x2a,0x20,0x2d,0x22,0x4d,0xb6,0xb3,0xa9,0xaa,0x91,0x98 +,0x9e,0x9b,0xab,0xa1,0xa5,0xbc,0xae,0xd3,0x3c,0x26,0x17,0x1f,0x1e,0x1d,0x1d,0x1b,0x23,0x22,0x2d,0x4a,0xce,0xa8,0xb9,0xad,0x9b,0x9b,0x9a,0x9a,0x9f,0xa9,0xa5,0xa4 +,0xb7,0xe7,0x2e,0x1e,0x23,0x1a,0x24,0x20,0x1c,0x2a,0x1e,0x27,0x22,0x2f,0xb9,0xcb,0xae,0xa9,0xa6,0x9a,0x9c,0x9b,0x9c,0xa3,0xa2,0xad,0xae,0xc8,0x36,0x2d,0x1b,0x1b +,0x1f,0x20,0x19,0x20,0x30,0x25,0x2c,0x36,0x31,0xcf,0xc0,0xc4,0x9e,0x9d,0x93,0x99,0xa1,0x9b,0xa8,0xa2,0xac,0x52,0xd6,0x2d,0x1f,0x1b,0x1c,0x2b,0x13,0x1b,0x20,0x1d +,0x3c,0x3a,0xb8,0xc0,0xca,0xb7,0xd7,0x9b,0x94,0x98,0x95,0x9d,0x9f,0xa8,0xb3,0xd2,0x36,0x44,0x1d,0x16,0x2a,0x20,0x17,0x1d,0x1f,0x1e,0x25,0x2d,0xcd,0xb2,0xa9,0xad +,0xa7,0x9c,0x9d,0x9e,0x9e,0x95,0x9d,0xa4,0xb3,0x4c,0x5d,0x27,0x1a,0x18,0x1f,0x3f,0x16,0x1d,0x2b,0x1a,0x34,0x2b,0xe3,0xc7,0xed,0xac,0xa9,0x92,0x92,0x9e,0x9c,0x9f +,0xab,0xab,0xac,0xac,0x4f,0x27,0x1c,0x12,0x27,0x29,0x16,0x25,0x23,0x1a,0x2e,0x4c,0xbc,0x5e,0xd6,0xcb,0xad,0x93,0x99,0x97,0x9b,0x9c,0xa7,0xaa,0xa9,0x3a,0x32,0x23 +,0x20,0x1e,0x2c,0x27,0x16,0x1c,0x1e,0x24,0x4d,0xbb,0x41,0x43,0x5e,0xb4,0x9e,0x95,0x9a,0xb7,0x9d,0x99,0x9a,0x9a,0xbb,0x39,0x2b,0x1c,0x1b,0x1c,0x72,0x21,0x17,0x1d +,0x21,0x2f,0x47,0xe0,0x31,0x5e,0xe9,0xb1,0x9d,0x8f,0xa3,0xa9,0xa1,0x9c,0x97,0x9c,0xb6,0x42,0x2f,0x1f,0x14,0x1c,0x2e,0x18,0x15,0x1b,0x2d,0x33,0xc7,0x43,0x47,0x63 +,0xb4,0xad,0x96,0x94,0xa3,0xa0,0x9c,0x99,0x9d,0xa4,0x3e,0x39,0x38,0x27,0x16,0x20,0x28,0x14,0x12,0x1e,0x21,0x3b,0xb8,0x38,0x48,0xb7,0xae,0xa9,0x96,0x98,0xa2,0xa1 +,0xa4,0x9f,0x93,0x9a,0xdb,0x2a,0x21,0x1b,0x1a,0x2e,0x27,0x15,0x14,0x1c,0x1c,0x34,0x50,0x3e,0x41,0xb4,0xab,0x9a,0x8e,0x9d,0xa7,0xa9,0xa4,0x9a,0x97,0xab,0xec,0x42 +,0x38,0x18,0x12,0x20,0x1b,0x15,0x1b,0x29,0x25,0xd9,0x75,0x24,0x39,0xb8,0xa4,0x93,0x91,0xa1,0xa4,0x9b,0xa0,0xa4,0x9b,0xae,0x4d,0x46,0x1e,0x19,0x2c,0x29,0x0f,0x0d +,0x1e,0x28,0x3d,0xbd,0x32,0x2f,0xe2,0xbf,0xa7,0x95,0x94,0xa8,0x9d,0x9a,0xa2,0x99,0x9e,0xc5,0x3a,0x2f,0x1f,0x1c,0x2b,0x20,0x12,0x19,0x1f,0x20,0x38,0x46,0x52,0x3c +,0x4e,0xbc,0x9b,0x92,0x9c,0xb4,0xa5,0x9d,0x9b,0x9a,0xa6,0xdf,0x3e,0x41,0x1d,0x26,0x2b,0x19,0x0f,0x19,0x1f,0x39,0xc8,0x44,0x27,0x40,0xaa,0x97,0x8f,0x9f,0xa7,0xa2 +,0x9c,0xa3,0xab,0x34,0x32,0x36,0x60,0xa8,0xa8,0xdc,0x14,0x0b,0x09,0x1e,0x9c,0xa1,0x58,0xbc,0xa9,0xda,0x18,0xbc,0x8e,0x96,0x99,0x2b,0x0f,0x22,0x98,0x96,0x95,0xb3 +,0x1f,0x2e,0xa4,0xae,0x21,0x3c,0x18,0x1b,0xbe,0xb0,0x17,0x0c,0x0d,0x13,0x9e,0x9b,0xbc,0xaf,0xb0,0x9f,0x8a,0x81,0x83,0x8e,0xfc,0x1a,0x17,0x47,0xa1,0x18,0x09,0x08 +,0x09,0x12,0x10,0x11,0x45,0xa7,0x23,0x24,0xae,0x8e,0x8d,0x8c,0x8b,0x95,0x97,0x8b,0x9a,0x4d,0xb2,0x31,0x19,0x31,0x41,0x0f,0x07,0x05,0x09,0xcb,0x91,0xca,0x14,0x13 +,0x24,0x7b,0x85,0x82,0x92,0x98,0xcd,0x2f,0xa9,0x99,0x62,0x2d,0x22,0x1b,0xaa,0x95,0x2b,0x0c,0x14,0x2b,0x1a,0x1e,0x1d,0x1a,0x35,0xab,0xbb,0xab,0x92,0x52,0x2f,0xa8 +,0x9d,0x8f,0x8a,0x8f,0x9d,0x47,0x27,0x0b,0x0e,0xab,0x45,0x0c,0x07,0x0b,0x10,0xb7,0xa1,0xc7,0x9c,0x97,0x3b,0xa3,0x8a,0x8b,0x90,0xa5,0x4e,0xc5,0x95,0xba,0x11,0x11 +,0x2f,0x23,0x5c,0x21,0x06,0x08,0x1a,0x2e,0xa1,0x8d,0x99,0xad,0x65,0xc7,0xb5,0x8c,0x8c,0xad,0x66,0xb1,0x29,0x3d,0xca,0x26,0x37,0x2d,0x08,0x09,0xad,0x9b,0x93,0xa9 +,0x45,0x2a,0x32,0x4c,0xc0,0x48,0x3d,0x2d,0x23,0x8c,0x8d,0xc2,0x1f,0x2c,0xc9,0x8f,0x94,0x4b,0x18,0x0b,0x0e,0x18,0x8d,0x89,0x9f,0x11,0x0c,0x13,0xab,0x99,0xf0,0x2b +,0x3f,0xa2,0x9c,0x95,0xaf,0xde,0x2e,0xcd,0x25,0x56,0x35,0x55,0x23,0x1d,0x0f,0x30,0x8b,0xa3,0xa5,0x31,0x4f,0xdb,0xac,0xc2,0x75,0x1d,0x2e,0xa2,0x8f,0x8b,0xbf,0x0e +,0x16,0x1e,0x47,0xae,0x2d,0x17,0x13,0x09,0x1b,0x85,0x82,0x85,0x36,0x1d,0xe0,0x3f,0x26,0x15,0x0d,0xa1,0x8b,0xa5,0x1d,0x09,0x0c,0xac,0x8e,0x92,0x96,0xa2,0x4e,0x0a +,0x04,0x09,0x8c,0x82,0x87,0x3e,0x0f,0x33,0x1c,0x17,0x1c,0x1b,0xa5,0x87,0x9b,0x5d,0x2a,0xad,0x8e,0x91,0xd2,0x1b,0x10,0x4d,0x1c,0x0c,0x02,0xb6,0x80,0x87,0x3a,0x00 +,0x0f,0xdf,0xc2,0x43,0x40,0xb1,0x83,0x88,0x9f,0x2a,0x3f,0x99,0x97,0x27,0x1a,0x1c,0x2d,0x11,0x03,0x03,0x1c,0x80,0x89,0x90,0x1e,0x28,0x9f,0x21,0x0d,0x1c,0x9d,0x83 +,0x84,0xe1,0x0e,0x0a,0x2c,0x98,0x9b,0xa0,0xbb,0x5e,0x37,0x0a,0x04,0x04,0x8f,0x80,0x8d,0x2b,0x01,0x13,0x27,0x1b,0x39,0x9d,0x89,0x80,0x9c,0x13,0x0c,0x30,0x8d,0x98 +,0x3b,0xef,0x3e,0x4d,0x08,0x03,0x06,0xd0,0x80,0x91,0x32,0x05,0x14,0x97,0xa5,0x2e,0xbc,0xa1,0x82,0x8b,0x2e,0x1d,0x19,0xa4,0x96,0xc2,0x3b,0x0e,0x0c,0x0c,0x00,0x07 +,0x14,0x85,0x81,0x8d,0xca,0x18,0x9d,0x98,0x1d,0x24,0xb8,0x8f,0x80,0x42,0x0c,0x08,0x18,0xa9,0x28,0x22,0x68,0x2b,0xbb,0x0d,0x05,0x0b,0xa9,0x80,0x87,0x9e,0x09,0x0e +,0xaa,0x5c,0x14,0xc2,0x9e,0x85,0x90,0x16,0x0e,0x0c,0xaa,0x99,0xb2,0xaf,0x20,0x10,0x0d,0x04,0x1c,0xb7,0x85,0x80,0xa8,0x0d,0x01,0x2a,0x99,0x22,0x1e,0xaa,0x8c,0x80 +,0xf6,0x13,0x15,0x3d,0x97,0x33,0x25,0x46,0x1f,0x2e,0x0d,0x0a,0x18,0x2c,0x80,0x8a,0xa9,0x0f,0x0c,0x95,0xa2,0x2e,0xab,0x54,0x95,0x9f,0x05,0x0b,0x13,0xa3,0x96,0xc9 +,0x98,0x95,0x45,0x1c,0x05,0x16,0xf6,0x8b,0x80,0xa1,0x14,0x02,0x0f,0xb8,0x11,0x16,0x9d,0xa3,0x86,0x46,0x07,0x13,0x2b,0x8e,0x93,0x9f,0x90,0xa6,0x29,0x12,0x08,0x1a +,0x25,0x84,0x83,0x3f,0x0e,0x00,0x16,0x74,0x14,0xd0,0x9b,0x9b,0x85,0x23,0x2b,0xa2,0x94,0x8c,0x32,0x31,0xb8,0x25,0x17,0x07,0x05,0x11,0x31,0x80,0x93,0x1e,0x0d,0x0b +,0x95,0x9f,0x2f,0x97,0x9c,0x8d,0x8e,0x0f,0x21,0x1f,0xae,0xab,0x1e,0xc5,0x48,0x1c,0x24,0x0b,0x15,0x1b,0xa3,0x80,0xb5,0x14,0x03,0x0d,0x96,0xb1,0xa4,0x88,0x8e,0x85 +,0x32,0x07,0x29,0x24,0x9a,0xbf,0x59,0x93,0x4e,0x17,0x0d,0x00,0x0f,0x1a,0x8a,0x81,0x2f,0x15,0x01,0x21,0x95,0x43,0x9c,0x8f,0x8e,0x82,0x27,0x27,0xab,0xb4,0x96,0x1d +,0x25,0xc3,0x0e,0x12,0x0a,0x05,0x12,0x0e,0x81,0x8d,0x3a,0x28,0x0b,0x8c,0x8d,0xce,0x8e,0x9d,0x95,0x9a,0x05,0x1e,0x2c,0xad,0x9d,0x17,0xf6,0x38,0x14,0x1c,0x09,0x19 +,0x4c,0xa0,0x80,0x95,0x2b,0x0b,0x06,0x9b,0xb4,0x20,0x98,0xab,0x8b,0xc2,0x04,0x1e,0x23,0x9a,0xb6,0x2a,0x9f,0xb7,0x52,0x36,0x0d,0x2d,0x2d,0x96,0x80,0xcd,0x1e,0x05 +,0x0b,0x9e,0x1d,0x26,0x9a,0xae,0x8a,0x21,0x0d,0xae,0xb1,0x91,0x2c,0x30,0x9f,0xcb,0x38,0x24,0x0c,0x1f,0x10,0x93,0x80,0xca,0x3f,0x05,0x33,0x8e,0x23,0xe9,0xb1,0xba +,0x8e,0x0d,0x0a,0x27,0xca,0x93,0x27,0xb7,0x98,0xaf,0x47,0x1c,0x1b,0xc2,0x1a,0x8e,0x81,0xdb,0x24,0x01,0x20,0x9d,0x1b,0xd8,0xcb,0xc4,0x9a,0x0e,0x12,0xac,0x95,0x86 +,0xad,0xa7,0x9d,0x3c,0x29,0x15,0x18,0x5f,0x16,0xa4,0x80,0x40,0x12,0x01,0x0a,0xb3,0x2c,0xba,0x9a,0x92,0x84,0xaf,0x21,0x9d,0x8f,0x8a,0xbc,0x4b,0xcf,0x21,0x0f,0x0e +,0x0c,0x14,0x0a,0x29,0x80,0x9b,0x2d,0x08,0x12,0x92,0xb4,0xbd,0x95,0x8f,0x88,0x45,0x0a,0x2c,0xa6,0x8f,0x58,0x25,0xc5,0x4d,0x23,0x1b,0x1c,0x39,0x1d,0x14,0x86,0x8d +,0x2c,0x0f,0x09,0x9e,0xa3,0x32,0xaa,0xa3,0x93,0xbd,0x0b,0x31,0x9a,0x8d,0x9d,0x21,0xb1,0x74,0x28,0x23,0x1d,0x2a,0x29,0x10,0x94,0x86,0x39,0x1a,0x06,0x32,0x9b,0x31 +,0x9d,0x9d,0x99,0x9e,0x12,0x24,0x94,0x8f,0x96,0x1b,0x14,0x1c,0x10,0x16,0x1f,0x5b,0xb1,0x29,0xa6,0x80,0x93,0x4c,0x0f,0x15,0x98,0xc0,0xd2,0xa9,0x66,0x55,0x0e,0x08 +,0xcf,0x9f,0x9a,0x2b,0x24,0xc1,0x65,0xcb,0xc8,0xa3,0xa4,0x4d,0x2f,0x86,0x8d,0x2b,0x0c,0x08,0xb1,0x77,0x21,0x37,0x4b,0xa9,0x27,0x0c,0xc7,0x97,0x8f,0xa2,0x2a,0xb4 +,0x9d,0xa0,0xa4,0xb9,0x28,0x1d,0x09,0x93,0x8f,0x13,0x0d,0x07,0xb6,0xae,0x2b,0xac,0xa5,0x9e,0xa3,0x2c,0x99,0x89,0x92,0x69,0x15,0x29,0x54,0x32,0x27,0x35,0x2b,0x1f +,0x12,0x8c,0x8d,0x23,0x0f,0x0b,0x9c,0xcd,0x1c,0x48,0xc1,0x9a,0xb7,0x1b,0x9a,0x8d,0x8f,0xb9,0x25,0xb2,0xa6,0x55,0x3c,0x2b,0x24,0x16,0x18,0x88,0xad,0x14,0x09,0x0d +,0xab,0x18,0x18,0x97,0x99,0x8f,0xcf,0x3d,0x8a,0x8f,0x97,0x3d,0xd9,0x9b,0xa7,0x2f,0x36,0x13,0x10,0x04,0x5b,0x8c,0x18,0x16,0x09,0xfb,0xa2,0x1d,0xa4,0x8d,0x8a,0x8c +,0x2d,0x9f,0x8f,0xa0,0xde,0x13,0x1a,0x3c,0x20,0x2b,0x12,0x0d,0x16,0x39,0x82,0xa4,0x1e,0x1d,0x41,0x8f,0xd4,0x3a,0x91,0x9a,0xa0,0x14,0x16,0x9b,0x9d,0xc9,0x1a,0x1c +,0xe3,0x2a,0x25,0x20,0x14,0x1e,0xa9,0x81,0x91,0x2d,0x0f,0x1e,0x96,0x52,0x2b,0xa3,0x9a,0x9b,0x16,0x15,0xa7,0x97,0xac,0x1e,0x29,0xb6,0x22,0x1d,0x20,0x14,0x1b,0xa3 +,0x81,0xa9,0x20,0x10,0x18,0x9f,0x3a,0xaf,0x91,0x93,0x98,0x1b,0x1f,0x9a,0x9b,0x9d,0x28,0x2c,0x1f,0x0b,0x0b,0x0c,0x15,0x2b,0x87,0x86,0xac,0x21,0x17,0x70,0xb1,0xbd +,0x8c,0x8c,0x95,0x42,0x0a,0x18,0x22,0xcc,0xa2,0xaa,0xb2,0x18,0x0d,0x0f,0x12,0x38,0x8d,0x80,0x93,0xc3,0x13,0x18,0x3e,0x1b,0xa9,0x91,0x94,0xb2,0x0c,0x16,0x1f,0x1a +,0x3c,0xad,0x8f,0x9c,0x22,0x12,0x12,0x23,0x89,0x80,0x95,0xdc,0x1d,0x1c,0x16,0x05,0x27,0x9c,0x9c,0xa2,0x15,0x19,0x1d,0x24,0xe4,0xb9,0x8e,0x8f,0xa2,0x21,0x0d,0x13 +,0x97,0x80,0x99,0x43,0x17,0x1e,0x27,0x0c,0x1f,0x9b,0x93,0x9b,0x17,0x2f,0x6b,0x2d,0xc8,0x41,0xa4,0xc8,0x1d,0x15,0x19,0xad,0x80,0xa6,0x1d,0x27,0x3c,0xa4,0x12,0x22 +,0x9b,0x8f,0x99,0x1e,0x1c,0xc8,0x2a,0x39,0x37,0xb4,0x4d,0x20,0x14,0x17,0x20,0x8f,0x83,0xa9,0xb6,0x1d,0x3c,0x3e,0x22,0x9f,0x98,0x9d,0x2d,0x18,0x2c,0x1a,0x1f,0x32 +,0xae,0xae,0x2f,0x0e,0x16,0xd6,0x88,0x83,0xba,0xb1,0xbc,0x69,0x13,0x0b,0xd0,0x94,0x94,0x3c,0x0d,0x1d,0x1d,0x2d,0x4f,0x9e,0xa5,0xfa,0x13,0x10,0x2b,0x8f,0x80,0xa4 +,0x58,0x24,0xc0,0x1c,0x09,0x3d,0x8c,0x98,0x2c,0x15,0x45,0x4e,0x29,0xc9,0xa4,0x8e,0x1f,0x06,0x09,0x37,0x81,0x8a,0x35,0x3e,0x2b,0x1e,0x0b,0x0e,0x90,0x90,0x9e,0xb2 +,0xac,0xbc,0x10,0x34,0x99,0x94,0xae,0x0d,0x08,0x16,0x34,0x82,0xaf,0x1f,0xbd,0x28,0xd6,0x07,0x37,0x89,0x92,0x9d,0x39,0x5e,0x2f,0x18,0x4d,0xa7,0xa8,0x2e,0x05,0x16 +,0x14,0x97,0x84,0x2c,0x96,0xc8,0x3c,0x26,0x0c,0x9e,0x8d,0xbf,0xad,0x33,0x2f,0xd9,0x1e,0xb4,0xcd,0xc3,0x1a,0x07,0x0b,0x38,0x80,0x99,0xf1,0xa6,0x41,0xb9,0x12,0x27 +,0x91,0x9c,0xcb,0x5a,0x1f,0x39,0x17,0x2f,0x98,0xac,0x31,0x05,0x18,0x61,0x85,0x8f,0x1d,0xa3,0x4c,0x33,0x13,0x17,0x90,0x8d,0x5b,0x2b,0x0e,0x2e,0xaa,0x31,0xa0,0xac +,0x9f,0x16,0x0a,0x1c,0x8a,0x87,0x15,0xd7,0xa8,0x5f,0x13,0x09,0x9f,0x89,0xc5,0x34,0x2a,0xc9,0xaf,0x1f,0xbe,0xa5,0xd4,0x0f,0x0d,0x1c,0x8d,0x85,0x1e,0x4e,0xc7,0x54 +,0x1d,0x0f,0x98,0x89,0x41,0x2f,0x29,0x2f,0x9e,0x23,0xab,0xba,0x3b,0x0d,0x09,0x12,0x92,0x84,0x1d,0xbd,0xc4,0x65,0x16,0x12,0x90,0x81,0x9a,0xcd,0x27,0x1e,0x30,0x1a +,0xa6,0x9a,0x3f,0x06,0x08,0x15,0x8f,0x8a,0x13,0xaa,0xa1,0x36,0x22,0x1b,0x8e,0x88,0xbf,0xb5,0xb0,0x4e,0x38,0x24,0xbb,0xd2,0x13,0x04,0x0c,0x18,0x89,0x86,0x1a,0xb9 +,0xf1,0x1f,0x1d,0x14,0x8e,0x84,0xa0,0xa2,0x21,0x30,0x2f,0x1f,0xa4,0x9f,0x1f,0x04,0x09,0x10,0x88,0x91,0x22,0x90,0xb1,0x1f,0x14,0x18,0x8c,0x8c,0xb2,0x98,0x27,0x34 +,0x38,0x29,0xa2,0xb9,0x18,0x0b,0x0f,0x22,0x82,0xab,0x17,0xa0,0x38,0x33,0x18,0x25,0x89,0x99,0x3c,0x9f,0x36,0xbf,0x4b,0x46,0x9d,0xac,0x17,0x0e,0x0e,0x45,0x81,0x3b +,0x1e,0x9c,0x1d,0x13,0x0d,0x36,0x87,0xa0,0xa6,0x9a,0x29,0x4b,0x38,0xb4,0x96,0xb9,0x0e,0x0c,0x12,0xa4,0x81,0x1e,0x33,0xa0,0x18,0x18,0x0f,0xb6,0x8b,0xbb,0xac,0x95 +,0x22,0xc6,0xc1,0xa5,0xa0,0x33,0x14,0x10,0x0d,0xae,0x85,0x10,0x32,0x99,0x2a,0x1b,0x0d,0xb0,0x87,0xb1,0x9c,0x95,0x33,0x3b,0x74,0x9f,0xa7,0x2c,0x0f,0x0e,0x0a,0xaf +,0x85,0x23,0x4b,0xac,0x14,0x19,0x1a,0xaa,0x89,0xa9,0x9f,0x9b,0x24,0xa8,0xc0,0xa8,0xaa,0x23,0x12,0x0f,0x0f,0xa1,0x86,0x11,0x43,0xa9,0x20,0x22,0x18,0xb0,0x8f,0xc3 +,0xa5,0x94,0x1f,0xd9,0xbe,0xa8,0x9b,0xc5,0x13,0x0b,0x09,0x51,0x81,0x2b,0x3a,0x94,0x15,0x15,0x18,0xb8,0x87,0xa4,0xdc,0xa5,0x18,0x33,0xa5,0xac,0x98,0xaf,0x1e,0x0e +,0x0b,0x18,0x87,0x9f,0x1c,0x97,0x67,0x15,0x14,0x1a,0x97,0x95,0x32,0x8f,0xaa,0x27,0xa8,0x38,0xb0,0x9b,0x33,0x1d,0x16,0x0a,0x96,0x8b,0x17,0xe5,0xba,0x13,0x1c,0x13 +,0xaf,0x8d,0x5e,0x9c,0x99,0x1b,0xb0,0xa9,0xab,0x90,0x3d,0x18,0x15,0x0b,0x1e,0x85,0xa6,0x1a,0xa1,0x1f,0x1b,0x13,0x1c,0x96,0x9f,0xb4,0x92,0xaa,0x2b,0xa9,0xb7,0xa7 +,0xae,0x49,0x27,0x17,0x07,0x28,0x8a,0x31,0xa8,0x93,0x24,0x1b,0x0c,0x1f,0x95,0xab,0x9b,0x8b,0xb9,0x34,0xad,0x6e,0xd8,0x31,0x30,0x21,0x1f,0x10,0x9d,0x8f,0x0e,0xfa +,0x9b,0x29,0x26,0x17,0x4e,0x99,0x3a,0x9a,0x94,0x47,0xad,0xb5,0xc2,0xa7,0x52,0x25,0x19,0x10,0x0e,0x92,0x99,0x2b,0x8f,0xab,0x12,0x18,0x14,0xb3,0x9d,0x79,0x94,0x9e +,0x4e,0xaf,0x36,0xb8,0xa4,0x3e,0x2f,0x1a,0x16,0x1a,0x94,0xaf,0x2d,0x97,0xac,0x25,0x1e,0x13,0x4d,0xab,0xc1,0x92,0x96,0xab,0xbf,0x2a,0xc1,0xb1,0x2b,0x28,0x23,0x14 +,0x19,0x97,0x45,0x3f,0x97,0x50,0x40,0x23,0x1e,0x9d,0xcb,0xf8,0x94,0xa7,0xa8,0xa6,0x66,0xa4,0x34,0x31,0x26,0x10,0x0e,0x1c,0x93,0xbe,0x2c,0xa2,0xaa,0xd9,0x26,0x1e +,0xb0,0xc1,0xa8,0x98,0xa9,0xa0,0xa9,0x43,0xa8,0x4f,0x43,0x1b,0x0f,0x14,0x25,0x9b,0x2e,0x2e,0xa2,0xa7,0x49,0x24,0x39,0x9d,0xa3,0xd2,0xb2,0xa9,0xa8,0xb8,0x65,0xb6 +,0xac,0xdb,0x13,0x1a,0x18,0x25,0xa1,0x24,0x3f,0xa0,0xb5,0xbd,0x29,0x46,0xa8,0x31,0xe5,0x9a,0x9e,0xa9,0xb9,0xc4,0x9c,0xbd,0x27,0x18,0x1c,0x13,0x1e,0xa9,0x4d,0xb7 +,0xac,0x4d,0xc6,0x2c,0x3b,0xad,0xec,0xa1,0x9f,0xbb,0xb5,0xb6,0xae,0xa5,0xeb,0xfa,0x20,0x1d,0x15,0x1d,0xb2,0x2e,0x33,0xb7,0xb4,0xa9,0x36,0x2e,0xae,0x4f,0xa4,0xaa +,0xd0,0xa3,0xa0,0xa8,0xb6,0x4f,0xb9,0x29,0x18,0x19,0x1b,0xbf,0x30,0x2e,0xb7,0xce,0xc5,0x4c,0x3f,0xa5,0xec,0xd5,0xa9,0xb9,0x9a,0xbe,0x3e,0xaa,0xad,0xfa,0x23,0x2a +,0xcc,0x23,0x27,0x3c,0x26,0xe4,0xd1,0xc6,0x62,0x37,0x6c,0xcd,0x59,0xa7,0xa9,0xc5,0xf9,0xdb,0xa5,0xad,0x57,0x48,0xb8,0xc2,0x3f,0x32,0x39,0x2d,0x4a,0x7b,0x3e,0xd5 +,0xcc,0x30,0x21,0x2c,0xb9,0xb4,0x52,0xb9,0xac,0xaf,0x3a,0x43,0xaf,0xaf,0xbc,0xe2,0xcf,0x7a,0x54,0xb8,0xb8,0xda,0xe8,0x29,0x23,0x33,0x5e,0xc1,0x3c,0x2b,0x6a,0x78 +,0x65,0xdd,0xb8,0xb2,0x54,0x63,0x59,0x50,0x5d,0xea,0xb6,0xa9,0xa9,0xb5,0x5b,0xd3,0x6b,0x4d,0x51,0xfe,0xc3,0x2c,0x1c,0x2e,0x70,0xbb,0xc1,0x3d,0x4e,0x2a,0x37,0x5c +,0x58,0xb1,0xa6,0xb3,0xcd,0xbd,0xaf,0xaa,0xb6,0xb7,0xbf,0x3b,0x25,0x3c,0x6a,0x43,0x43,0x4a,0x41,0x32,0x31,0x39,0x46,0x46,0x6b,0x6a,0xce,0xb1,0xab,0xb4,0xc3,0xba +,0xb8,0xb8,0xec,0x43,0x41,0x45,0x62,0xce,0xeb,0x40,0x45,0x34,0x4d,0xbf,0x57,0x44,0x39,0x50,0xc3,0xd2,0x43,0xde,0xbe,0xc8,0xd5,0x47,0xc0,0xbc,0xcb,0x6b,0x3b,0x49 +,0xb9,0xbf,0x65,0x6e,0x45,0x5a,0x51,0x53,0x49,0xd6,0xca,0x68,0x4c,0x3d,0x6d,0x60,0x4d,0x4e,0x51,0xc3,0xae,0xbc,0xba,0xdd,0x3e,0x4b,0x3e,0x57,0xc3,0xe5,0xc5,0xb8 +,0x4d,0x48,0x3d,0x3f,0xd0,0xce,0x6e,0xcc,0x33,0x31,0xe8,0xea,0xba,0xc4,0xc9,0xbf,0xd2,0x3e,0x5e,0xd2,0xbe,0xaf,0x3b,0x2c,0x4c,0xc1,0xb2,0xd5,0x49,0xc0,0x53,0x2c +,0x2a,0x39,0xc1,0xc1,0xc9,0x70,0xdd,0xcf,0xd7,0xcb,0xd2,0xc4,0xbd,0xd9,0x5f,0x50,0x70,0xce,0xcf,0xd9,0x3c,0x31,0x3a,0x57,0x3f,0x58,0xbd,0xc7,0x40,0x37,0xd0,0xb2 +,0xad,0xb4,0xce,0x64,0x37,0x36,0xe2,0xb6,0xb4,0xc1,0x41,0x31,0x32,0x37,0x48,0x59,0xb6,0xbe,0x4c,0x39,0x32,0xd9,0xb6,0xaf,0xb6,0xbe,0xe7,0x42,0x4b,0x58,0x5c,0xce +,0xbf,0xc8,0x3d,0x27,0x3f,0x6e,0xb7,0xb4,0x45,0x58,0x78,0x47,0x4c,0x4a,0xb8,0xad,0x7e,0x34,0x3a,0xbf,0xbe,0xb8,0xdc,0x5e,0x4e,0x3f,0xdf,0x5a,0x43,0xdf,0xc7,0xcc +,0x4a,0x3b,0x76,0x6e,0xc7,0xd6,0x61,0x4d,0x41,0xcf,0xbf,0xe4,0xc0,0xc7,0xc4,0x4b,0x33,0x4a,0x54,0xaf,0xb8,0x58,0x39,0x32,0x59,0xd4,0x45,0xbf,0xbb,0xc9,0xcd,0x37 +,0x6c,0x56,0x4d,0xbf,0xc1,0x5c,0x5a,0x57,0x5e,0x4f,0x74,0xc0,0xc2,0xc6,0x43,0x3e,0x4c,0x4b,0xef,0xd4,0xcc,0xbc,0x5d,0x5a,0x57,0x57,0xcb,0x51,0x51,0xed,0x4e,0x5a +,0x6e,0xfb,0xc6,0xcf,0xdc,0x4a,0x56,0xea,0xe8,0xcc,0xc8,0xc8,0x71,0x48,0x40,0x42,0xd7,0xc1,0xe6,0x68,0x3d,0x39,0x40,0xd0,0xbc,0xb7,0xbf,0xdf,0xd3,0x47,0x3e,0x53 +,0xba,0xb4,0xeb,0x42,0x45,0x35,0x37,0x4b,0xbf,0xaf,0xc3,0x4a,0x49,0x3b,0x3d,0x51,0xcc,0xb8,0xdb,0xc5,0xca,0xbf,0xcc,0x7d,0x4f,0x57,0x5d,0x7b,0x3d,0x38,0xd5,0x5d +,0xee,0x79,0xc8,0xbd,0xd9,0x4c,0xff,0x5f,0x3a,0x51,0x7d,0xd4,0xcf,0xc5,0xd3,0xf2,0x44,0xdf,0xbd,0x61,0xc2,0xee,0x3e,0x41,0x73,0xec,0xc3,0xcd,0xd1,0xd7,0x40,0x38 +,0x4a,0x63,0xd2,0xcc,0x7a,0x69,0x41,0xc3,0xaf,0xd6,0x47,0xe8,0x7b,0xde,0x4a,0xfe,0xdf,0xc1,0x57,0x3c,0x3c,0xbd,0x5e,0xd0,0xbe,0x9f,0xa8,0x4c,0x2e,0x2f,0xb2,0x53 +,0x98,0x29,0xaf,0x0c,0x01,0x0e,0x0d,0xa6,0x1c,0xe7,0x23,0x26,0x8f,0x94,0x96,0x8d,0x92,0xba,0x93,0x8c,0xb4,0x9f,0x8d,0x1b,0x98,0xf4,0x0a,0x8b,0x8b,0x9c,0x9b,0x9b +,0x1c,0x2a,0x0f,0x0f,0x0c,0x07,0x08,0x09,0x0b,0x08,0x0d,0x08,0x16,0x06,0x19,0x14,0x09,0x1c,0x68,0xb0,0xaa,0xa3,0xaa,0xa5,0x9d,0x8d,0x95,0x8e,0x8d,0x8f,0x88,0x87 +,0x8b,0x88,0x83,0x84,0x83,0x84,0x8e,0x88,0x94,0xba,0x9c,0x93,0x9d,0x0c,0x26,0x14,0x14,0x1c,0x06,0x0a,0x05,0x00,0x09,0x18,0x0b,0x0a,0x02,0x08,0x0a,0x00,0x07,0x1c +,0x26,0x0e,0x08,0x0f,0x2a,0x92,0x8f,0xb9,0x3f,0x9d,0x86,0x82,0x81,0x8b,0x9d,0x9b,0x83,0x80,0x85,0x87,0x3b,0xa0,0x8b,0x8d,0x90,0x98,0x9f,0xae,0x9c,0x33,0x14,0x0b +,0x27,0x1d,0x1f,0x08,0x06,0x0a,0x07,0x0b,0x09,0x0e,0x00,0x10,0x0a,0x13,0x0c,0x07,0x0d,0x09,0x9c,0xb0,0x93,0xae,0x27,0xb9,0xb7,0x8f,0x8b,0x8e,0x39,0xb4,0x9a,0x86 +,0x8b,0x8c,0x8d,0xa1,0x87,0x88,0x86,0x8a,0x86,0x89,0x94,0x89,0x8e,0x93,0xa1,0x21,0x1e,0x2e,0x2a,0x0d,0x04,0x0c,0x0e,0x0f,0x07,0x08,0x03,0x06,0x15,0x1b,0x17,0x09 +,0x06,0x03,0x0c,0x0f,0x2f,0x1a,0xda,0x37,0x22,0xa1,0x19,0xb9,0x8c,0x87,0x80,0x8f,0x91,0x88,0x84,0x84,0x83,0x85,0x90,0x8c,0x8c,0x8f,0x94,0xae,0x2b,0xb9,0x3d,0x28 +,0x0f,0x08,0x17,0xb9,0x3a,0x1a,0x1f,0x12,0x17,0xc8,0x10,0x11,0x1b,0x0e,0x18,0x09,0x08,0x03,0x20,0x0d,0x1b,0x0e,0x09,0x09,0x0d,0xac,0x2f,0x8a,0x98,0x9b,0x8d,0x8d +,0xaa,0x9e,0x85,0x8e,0x94,0xbc,0x8c,0x80,0x95,0x92,0xa6,0xa3,0x88,0x8b,0x8e,0x9c,0xb8,0xbf,0x5f,0xaf,0x98,0xa4,0x2c,0x1e,0xb6,0x0e,0x09,0x08,0x0f,0x1b,0x1a,0x0f +,0x03,0x0e,0x07,0x18,0x15,0x04,0x0a,0x14,0x08,0x0b,0x25,0x37,0xc1,0x9b,0x4c,0x99,0x8b,0x89,0x8c,0x8c,0x96,0xa0,0x94,0x8e,0x80,0x94,0x8f,0xa0,0x9d,0x39,0xbc,0x9d +,0xaa,0x3f,0xbc,0x96,0x86,0x88,0x6f,0xb4,0x9c,0x93,0x1f,0x99,0x9e,0x36,0x17,0x26,0x1e,0x08,0x22,0x0a,0x00,0x05,0x00,0x02,0x08,0xa3,0xb9,0x0a,0x14,0x0e,0xaa,0xa7 +,0xb5,0x23,0x35,0xa1,0xb2,0x8a,0x93,0xae,0x3e,0xe7,0x58,0xa3,0xa8,0xc2,0x8d,0x86,0x9a,0x94,0x80,0x8e,0x8c,0x8b,0x8d,0x90,0x96,0xa8,0x3a,0x9a,0x92,0x8a,0x13,0x18 +,0x12,0x06,0x04,0x06,0x0a,0x00,0x59,0x1c,0x56,0xa4,0x1b,0x0d,0x0e,0x2c,0x0e,0x13,0x48,0xa1,0x20,0x0f,0xaf,0xc3,0x3c,0x1e,0x06,0x07,0x16,0x2f,0xac,0x85,0x87,0x90 +,0x85,0x9c,0x86,0x85,0xab,0x89,0x96,0x88,0x85,0x8c,0x9b,0x8c,0x91,0x21,0x9e,0x14,0x0c,0x17,0x07,0xad,0x88,0x8f,0x7e,0xd3,0xb0,0x15,0x1a,0x0a,0x25,0x0e,0x0c,0xc9 +,0x1a,0x08,0x0c,0x0c,0x0a,0x0a,0x00,0x03,0x02,0x0d,0xac,0x8b,0x9d,0x8f,0x27,0x8f,0x8a,0xa7,0x91,0x9e,0x84,0x83,0x89,0x8f,0x8a,0x8d,0x8f,0x3b,0x1b,0x11,0xa5,0x24 +,0x65,0x83,0x87,0x8c,0x2f,0x28,0xb3,0xae,0x1f,0x2b,0x9b,0x9d,0x2e,0x28,0x62,0xa7,0x08,0x20,0x0f,0x02,0x06,0x01,0x0a,0xee,0x8d,0xae,0x37,0x10,0x0f,0x1e,0x0c,0x19 +,0xbb,0x4b,0x8c,0xa2,0x2a,0x19,0xbf,0xb1,0x18,0x13,0x0d,0x47,0x1b,0x93,0x80,0x87,0x8e,0xa3,0x99,0x8e,0x90,0xae,0x89,0x86,0x80,0x86,0xba,0x90,0x8e,0x21,0x1a,0x1e +,0x0a,0x0c,0x06,0x1f,0x8c,0x3b,0x3b,0x1a,0x00,0x16,0x16,0x06,0x0d,0xb1,0xc8,0xa0,0x13,0x06,0x35,0x1a,0x0b,0x07,0x08,0x07,0x05,0x2f,0x80,0x8a,0x9b,0x95,0x23,0x96 +,0x9c,0x15,0x97,0x80,0x82,0x80,0x9b,0x26,0x8c,0x94,0xad,0xa5,0x21,0x0b,0x0a,0x0f,0x85,0x86,0x55,0x21,0x0a,0x2f,0xba,0x01,0x1e,0x86,0x8b,0x98,0x1a,0x24,0x2f,0x1a +,0x16,0x0d,0x0d,0x0a,0x09,0x06,0x92,0x8d,0x07,0x1e,0x08,0x1c,0xaa,0x08,0x0b,0x8a,0x8a,0x93,0xd4,0x0d,0x9c,0x95,0xbf,0x36,0x38,0x18,0x2f,0x2e,0x85,0x80,0x9a,0x8e +,0x1f,0x9a,0x96,0x0d,0x8f,0x80,0x83,0x80,0xf5,0x0e,0x9b,0x97,0x2e,0x25,0x0f,0x07,0x15,0x00,0x9a,0x8b,0x0b,0x10,0x03,0x1e,0x0d,0x08,0x0d,0x98,0x9b,0x90,0x0e,0x04 +,0xa5,0x36,0x39,0x1d,0x08,0x18,0x1d,0x00,0x87,0x8e,0x9c,0x46,0x07,0x97,0x94,0x3d,0x9a,0x80,0x84,0x84,0xa9,0xae,0x8c,0x85,0x9a,0x9b,0x9e,0x14,0x11,0x0c,0x9c,0x81 +,0x9d,0x20,0x07,0x05,0x9f,0x0f,0x17,0x8e,0x9a,0x86,0x21,0x08,0x44,0x18,0x0c,0x1b,0x1a,0x11,0x1d,0x00,0xb2,0x81,0x19,0x0d,0x09,0x38,0x26,0x0c,0x29,0x8d,0x85,0x83 +,0x0e,0x1c,0xa0,0x9c,0x91,0xa1,0xa3,0xca,0x3a,0x0b,0x8f,0x80,0x9d,0x1a,0x4d,0x9f,0x97,0x11,0x13,0x8d,0x80,0x8b,0x1a,0x15,0x15,0xa0,0x96,0x43,0x28,0x0b,0x09,0x0b +,0x1d,0x86,0x9f,0x0f,0x09,0x0b,0xc8,0x0b,0x05,0x97,0x80,0x88,0xcb,0x00,0x19,0x9d,0xaa,0x16,0x1a,0xa6,0x10,0x06,0x0b,0x88,0x88,0xde,0x08,0x25,0xab,0x27,0x17,0xac +,0x80,0x82,0x8f,0x29,0xbc,0x8c,0x96,0x94,0x94,0xab,0x41,0x17,0x2a,0x8f,0x82,0x23,0x1b,0x0c,0x15,0x9a,0x03,0x0c,0x96,0x8e,0x9c,0x08,0x01,0x1a,0x5b,0x1c,0x09,0x10 +,0xf6,0x07,0x02,0xb7,0x86,0x8c,0x18,0x0f,0x17,0x9c,0x18,0x23,0x84,0x83,0x82,0xc4,0x10,0x90,0x88,0x98,0xf2,0x27,0x9b,0x27,0x09,0x4c,0x80,0x92,0x46,0x0e,0x11,0xc8 +,0x0f,0x0b,0x1b,0x88,0x84,0xa3,0x04,0x0c,0xa7,0x9b,0x1f,0x1f,0xbc,0x0c,0x19,0x0d,0xb7,0x80,0x9f,0x22,0x0b,0x69,0x99,0x10,0x16,0x8d,0x82,0x91,0x13,0x05,0xaf,0xbc +,0x40,0x15,0xbc,0x2b,0x00,0x05,0x0f,0x80,0x9e,0x16,0x10,0x08,0x8e,0x22,0x0d,0x98,0x82,0x84,0x8f,0x0e,0x28,0x86,0x8f,0xc7,0x25,0x8c,0x9d,0x1b,0x0a,0x92,0x80,0x92 +,0x2c,0x08,0x18,0x26,0x0e,0x11,0x97,0x8a,0xbd,0x0d,0x03,0x40,0x30,0x1e,0x1c,0x29,0x31,0x02,0x09,0x0b,0x87,0x87,0xd6,0x26,0x34,0xc6,0x42,0x0f,0x98,0x84,0x80,0x93 +,0x04,0x2e,0xa4,0x9b,0x28,0xac,0xad,0x3d,0x10,0x06,0xae,0x80,0x8c,0x22,0x10,0x1c,0x50,0x1a,0x10,0x8e,0x87,0x8e,0x1f,0x0c,0x3b,0xdc,0xad,0x2d,0x1f,0x2f,0x17,0x05 +,0x0c,0xa0,0x80,0xe9,0x10,0x09,0x3b,0xd1,0x0e,0xb4,0x8f,0x85,0x8b,0x1a,0x0e,0xaa,0xc5,0xb5,0x44,0xa3,0xb4,0x0d,0x04,0x0d,0x8d,0x87,0xb6,0x1c,0x11,0x1f,0x9f,0x12 +,0x4c,0x8a,0x8b,0x87,0x2a,0x11,0xdc,0x9c,0xa4,0x3f,0xa4,0xb3,0x0e,0x0b,0x11,0x86,0x87,0xc0,0x14,0x0b,0xc1,0xaa,0x1b,0x47,0x94,0x8a,0x96,0x0f,0x14,0x3c,0xb2,0xd1 +,0x2b,0x27,0x47,0x15,0x09,0x08,0x8b,0x86,0xc9,0x1c,0x0b,0xe5,0x34,0x10,0x3a,0x90,0x85,0x90,0x20,0x0b,0x29,0x9a,0xa9,0x92,0x9d,0xce,0x16,0x18,0x1b,0x91,0x82,0x9e +,0xfc,0x18,0x39,0x5c,0x25,0x23,0x92,0x87,0x8c,0xaf,0x0a,0x20,0xbc,0x1d,0xc9,0xc6,0xaf,0x10,0x08,0x09,0xab,0x80,0x9f,0x36,0x0b,0x1a,0xbf,0x1e,0x14,0x97,0x85,0x8e +,0x23,0x06,0x1d,0x9e,0xc4,0xc6,0x25,0x43,0x26,0x04,0x08,0x3f,0x80,0x90,0x1c,0x0c,0x2d,0x9e,0x38,0x1a,0x96,0x88,0x8e,0x46,0x13,0x25,0xb8,0xb0,0x41,0xd3,0xc7,0x15 +,0x0a,0x12,0x2b,0x80,0x8f,0x40,0x1b,0x1f,0x50,0x22,0x1f,0xa5,0x88,0x8b,0xad,0x10,0x17,0x2f,0xae,0xb9,0xbb,0xcf,0x1c,0x09,0x08,0x12,0x8b,0x83,0x9f,0x24,0x14,0x1b +,0x27,0x1b,0xc3,0x88,0x85,0x8f,0x0f,0x0a,0x1e,0xa7,0x9c,0xe5,0x4d,0xc7,0x13,0x0a,0x0e,0xa3,0x80,0x93,0x1f,0x0e,0x1a,0xaf,0x26,0x17,0x8a,0x88,0x8f,0x39,0x07,0x1e +,0x3e,0xaf,0xaa,0xab,0xa3,0x20,0x0a,0x06,0x4a,0x81,0x88,0xa8,0x16,0x0e,0x1e,0x21,0x1a,0x95,0x85,0x86,0xa8,0x08,0x0d,0x2d,0xad,0x97,0x9e,0xbe,0x21,0x06,0x0c,0x1d +,0x8c,0x80,0xa2,0x19,0x0b,0x11,0x4e,0x37,0xa1,0x8b,0x91,0xb1,0x1c,0x12,0x19,0xa9,0xb0,0x9d,0xa8,0x35,0x0d,0x09,0x17,0xb6,0x80,0x89,0x4f,0x0a,0x08,0x3a,0x2c,0x3a +,0x8c,0x8e,0x91,0x22,0x09,0x29,0xae,0xaf,0xae,0x29,0xc3,0x21,0x07,0x14,0x31,0x85,0x82,0xb9,0x0a,0x09,0x1b,0xba,0x36,0xa5,0x87,0x8c,0x4c,0x09,0x19,0xd4,0xa7,0xad +,0xbe,0xa9,0xbb,0x0d,0x0e,0x20,0x8f,0x80,0xb5,0x20,0x18,0x1f,0x46,0x0e,0xbf,0x84,0x8b,0xed,0x0d,0x10,0x35,0xc4,0xab,0xac,0xb1,0xa7,0x12,0x07,0x0d,0xa6,0x80,0x8d +,0x70,0x15,0x09,0x22,0x21,0x35,0x8c,0x8c,0x8f,0x18,0x08,0x28,0x70,0xad,0x9b,0xaa,0xb9,0x10,0x0a,0x1d,0x68,0x81,0x8a,0x27,0x0f,0x0a,0x28,0xdb,0x26,0x93,0x89,0x8d +,0x2e,0x00,0x1f,0xaa,0x9e,0x98,0xaf,0xbf,0x13,0x04,0x23,0xaf,0x88,0x84,0x1e,0x17,0x0f,0x1c,0x3f,0x16,0x9a,0x89,0x8a,0xc6,0x06,0x15,0x65,0xa8,0x99,0xd8,0xb5,0x2d +,0x07,0x13,0x18,0x8e,0x80,0xee,0x16,0x0a,0x17,0xb4,0x1f,0xa0,0x8c,0x8a,0xaf,0x0c,0x19,0xb4,0xa1,0x9c,0xf3,0xbb,0x4f,0x06,0x17,0x19,0x96,0x80,0xb9,0x1d,0x0f,0x0f +,0x3d,0x1e,0xbf,0x8a,0x8d,0xb3,0x0e,0x18,0xbd,0xad,0xa8,0xaf,0xad,0x28,0x0b,0x0d,0x0f,0x9a,0x80,0x9d,0x40,0x15,0x0c,0x3d,0x0c,0x49,0x88,0x8a,0x91,0x19,0x12,0x24 +,0x3d,0xa6,0xa0,0xa8,0xb7,0x0b,0x0c,0x0f,0xa5,0x80,0x9e,0x2b,0x0c,0x0f,0x61,0x14,0xaa,0x8b,0x8c,0x95,0x13,0x14,0x26,0xbd,0xa3,0xb4,0xa6,0xb7,0x0e,0x0d,0x0f,0x9d +,0x80,0xad,0xbc,0x10,0x0b,0x27,0x0d,0xa1,0x82,0x88,0xae,0x0e,0x12,0x30,0xcc,0xb0,0xa6,0x9d,0x42,0x08,0x0c,0x13,0x90,0x82,0xad,0x35,0x0d,0x1d,0x1d,0x09,0xa0,0x83 +,0x86,0xbb,0x16,0x24,0x18,0x2e,0x9d,0x9a,0x9a,0x19,0x08,0x18,0x38,0x82,0x8e,0x41,0x4d,0x0d,0x2b,0x1b,0x19,0x91,0x89,0x96,0x38,0x1a,0x2d,0xcd,0x39,0xac,0xce,0xcd +,0x13,0x0b,0x15,0xd5,0x80,0x9a,0x32,0x18,0x11,0x35,0x11,0x21,0x8a,0x85,0xa1,0x15,0x14,0x57,0xd0,0x5f,0x41,0x9c,0xa1,0x0d,0x0b,0x11,0x92,0x80,0xcf,0x2f,0x1b,0x2b +,0x55,0x0d,0xbf,0x86,0x8b,0xb2,0x10,0x23,0xa8,0x6a,0x2a,0x37,0xa8,0x45,0x0c,0x0b,0x25,0x82,0x8b,0x1c,0x19,0x11,0x4f,0x23,0x2e,0x8a,0x8b,0x9c,0x1b,0x0d,0xbd,0xa1 +,0x42,0x2b,0xf3,0xa7,0x11,0x09,0x13,0x9c,0x80,0xd7,0x15,0x0e,0x17,0xb7,0x22,0xaf,0x85,0x87,0xbc,0x08,0x0d,0xa6,0x9c,0x9c,0xd4,0xbd,0x26,0x0b,0x0b,0x1a,0x83,0x86 +,0x30,0x10,0x07,0x41,0xb9,0x20,0x8e,0x88,0x95,0x27,0x03,0x31,0x96,0xac,0x4e,0xb9,0xb7,0x0e,0x03,0x0c,0x94,0x80,0xa3,0x17,0x0b,0x0c,0x38,0x1a,0x9c,0x80,0x8f,0xaa +,0x0d,0x0c,0x32,0xcb,0x90,0x9d,0xa2,0x22,0x07,0x0d,0x19,0x82,0x8c,0x23,0x27,0x0f,0xf0,0x27,0x19,0x8c,0x83,0x92,0x13,0x07,0xc2,0xa9,0x3f,0xae,0x9b,0xa8,0x08,0x07 +,0x11,0x95,0x80,0x49,0x1a,0x17,0x20,0x2f,0x13,0x9e,0x80,0x91,0x2f,0x06,0x19,0x9c,0xc6,0xa0,0xa5,0xa6,0x18,0x09,0x0f,0xcd,0x80,0x9b,0x1a,0x13,0x17,0xb1,0x17,0x28 +,0x84,0x86,0x97,0x0f,0x07,0xbf,0xcc,0xb9,0xc2,0xa3,0xb2,0x0c,0x0a,0x1d,0x85,0x87,0x1f,0x14,0x14,0x33,0x25,0x1a,0x8c,0x88,0x9b,0x39,0x0b,0xa5,0xac,0x1c,0x68,0xbd +,0xa0,0x14,0x0c,0x18,0x90,0x83,0x3e,0x24,0x11,0x1d,0xd0,0x18,0x99,0x81,0x96,0x3a,0x07,0x1d,0x9b,0xc2,0xa6,0x69,0xb4,0x0e,0x09,0x22,0xaa,0x80,0xa5,0x0f,0x0e,0x12 +,0xb5,0x22,0x4a,0x80,0x8c,0x28,0x0f,0x0e,0x9b,0xb2,0xc1,0xb1,0x47,0x34,0x07,0x0b,0xd1,0x81,0x88,0x16,0x07,0x0c,0x2b,0x2d,0xce,0x85,0x83,0xa1,0x0f,0x04,0x4b,0x9e +,0x9f,0xa3,0xc6,0x33,0x06,0x08,0x20,0x88,0x81,0x2d,0x0d,0x08,0x1a,0xd6,0x1d,0x8e,0x81,0x92,0x28,0x05,0x1f,0xa9,0xbb,0x9a,0xa2,0xca,0x0c,0x02,0x14,0x91,0x80,0xa6 +,0x1d,0x11,0x0d,0x1b,0x0f,0x95,0x80,0x86,0xb7,0x03,0x14,0xda,0xa4,0x99,0xab,0x9f,0x0e,0x06,0x13,0xa9,0x80,0xa8,0x18,0x13,0x16,0x2c,0x0c,0xd8,0x81,0x8b,0xa0,0x0c +,0x15,0xad,0x1c,0xb5,0x9a,0x93,0x26,0x01,0x0a,0xb7,0x80,0x94,0x15,0x1e,0x23,0x30,0x0b,0x3a,0x82,0x8a,0xb1,0x0e,0x1c,0x9f,0x4f,0xd4,0xda,0xa3,0x2f,0x08,0x0c,0x2b +,0x80,0x98,0x18,0x1c,0x1f,0xb4,0x10,0x19,0x88,0x89,0x93,0x19,0x0d,0xaa,0x58,0xa7,0x38,0xdf,0x26,0x07,0x1c,0xb7,0x80,0x95,0x0c,0x11,0x15,0xb8,0x1c,0x37,0x85,0x8b +,0xb7,0x0f,0x10,0x98,0xaf,0x58,0xa1,0x4b,0x1b,0x09,0x17,0xd7,0x81,0x8c,0x1a,0x1d,0x0e,0x22,0x28,0x56,0x85,0x8a,0xbb,0x12,0x10,0xab,0xbc,0xa7,0xa6,0xdb,0x29,0x03 +,0x0d,0x5c,0x85,0x85,0x1d,0x11,0x0e,0x21,0x2c,0x39,0x8a,0x85,0xae,0x11,0x0b,0xb5,0x97,0xc7,0x9f,0xe5,0x1f,0x06,0x0d,0x44,0x89,0x81,0x29,0x10,0x09,0x15,0x46,0x2f +,0x8d,0x83,0x97,0x23,0x0b,0x1e,0xa8,0x9c,0x9d,0xc1,0x44,0x0d,0x06,0x12,0x9a,0x80,0xb5,0x11,0x13,0x13,0x23,0x0f,0x9b,0x82,0x8b,0x5b,0x0a,0x2a,0x9c,0xbe,0xb8,0xcb +,0xbb,0x1b,0x06,0x1e,0xa8,0x80,0x9b,0x17,0x1c,0x0e,0x36,0x10,0x2b,0x84,0x8b,0xa0,0x1d,0x14,0xd9,0x2d,0xa6,0x96,0xac,0x22,0x06,0x11,0x2a,0x8b,0x84,0x2b,0x1d,0x17 +,0x1f,0x1c,0x11,0x98,0x80,0x8e,0x1f,0x0e,0x20,0xd6,0xcc,0x9a,0xb2,0xb3,0x13,0x08,0x1c,0xaf,0x80,0x9e,0x1f,0x20,0x14,0x2c,0x11,0x39,0x86,0x88,0x9e,0x13,0x18,0x7a +,0x37,0xa9,0xb1,0xce,0xe0,0x0a,0x13,0x24,0x8f,0x84,0x16,0x26,0x27,0x1f,0x1e,0x0a,0x95,0x86,0x8d,0xb8,0x10,0xdb,0xe1,0x1f,0xca,0x9e,0xae,0x29,0x0a,0x19,0x35,0x86 +,0x89,0x1c,0x27,0x13,0x22,0x13,0x1f,0x89,0x8b,0xa1,0x40,0x21,0xc2,0x21,0x2e,0xa8,0xa8,0xc0,0x0e,0x0f,0x2f,0x46,0x87,0x96,0x1e,0xb9,0x12,0x1e,0x1e,0x29,0x8b,0x96 +,0x95,0x40,0x5d,0xb2,0x12,0x2b,0x3b,0x92,0xb1,0x14,0x1c,0x1c,0x17,0x8c,0x8d,0x38,0xf6,0x0e,0x2b,0x17,0x24,0x89,0x8b,0x99,0x54,0x34,0x3c,0x19,0x29,0xa2,0x9b,0x41 +,0x1e,0x23,0x17,0x18,0x89,0x8e,0x25,0x39,0x12,0x4f,0x1b,0x1e,0x8b,0x96,0x8f,0x4b,0x38,0xc7,0x0f,0x47,0xa6,0xaf,0x28,0x2b,0x22,0x1f,0x15,0x8d,0x8f,0x19,0xfe,0x18 +,0xbd,0x1b,0x11,0x92,0x8b,0x8c,0xca,0x25,0x56,0x16,0xf2,0xb3,0x9f,0x9f,0x23,0x16,0x17,0x14,0x8e,0x8a,0x38,0xd4,0x14,0x33,0x1c,0x15,0x95,0x8e,0x94,0xdb,0x30,0xec +,0x1b,0x4f,0x51,0xa5,0xab,0x2d,0x25,0x11,0x0a,0xa1,0x82,0x2a,0x39,0x2f,0xdc,0x35,0x08,0xb9,0x8f,0x8f,0x98,0x36,0x71,0x1d,0x18,0xcb,0x9e,0xa9,0x9f,0x1c,0x0b,0x0b +,0x35,0x81,0xb2,0xc7,0xbc,0xd8,0x28,0x08,0x2e,0x8e,0x8e,0x99,0xc3,0xaf,0x29,0x16,0x5d,0xb2,0x9e,0x35,0x1d,0x17,0x1c,0x1d,0x8a,0x9f,0x26,0xa3,0x38,0xdd,0x07,0x24 +,0x8f,0x9f,0x9d,0x9f,0xa3,0x6d,0x0d,0x1f,0x9c,0x9e,0x5e,0x24,0x1b,0x0c,0x0c,0x96,0x81,0xc2,0xbe,0x2d,0x1f,0x12,0x0f,0x95,0x93,0x94,0x9b,0xc5,0xb5,0x11,0x1d,0xa3 +,0xa2,0xae,0x29,0x1f,0x12,0x0a,0xbc,0x80,0x9e,0xd1,0x31,0x28,0x27,0x09,0x3a,0x8f,0x8f,0x9b,0x46,0xd9,0x2d,0x19,0x37,0xc4,0xab,0x4c,0x2b,0x10,0x0f,0x25,0x85,0x8d +,0x6a,0xb5,0x21,0x1e,0x05,0x26,0x8c,0x8c,0x95,0xbb,0xda,0x1f,0x0f,0xe8,0xa6,0xa0,0x4c,0x21,0x19,0x0f,0x19,0x8f,0x82,0xae,0x4d,0x1e,0x19,0x13,0x17,0x8e,0x8c,0xa4 +,0x9d,0x45,0x49,0x11,0x24,0xae,0xb4,0x36,0x22,0x24,0x15,0x1a,0xad,0x80,0xb3,0x32,0x20,0x26,0x2f,0x0f,0x9d,0x94,0x9a,0x94,0x4d,0x2f,0x1e,0x23,0xbb,0xc5,0x40,0x49 +,0x41,0x15,0x0e,0x43,0x80,0x9e,0x14,0xdf,0xda,0x24,0x09,0xba,0x89,0x9e,0x9f,0xcf,0x36,0x1f,0x1f,0xaf,0xaf,0xc3,0x3a,0x1a,0x0d,0x16,0x3c,0x83,0x9a,0x17,0x25,0x1a +,0x1b,0x0e,0xa3,0x81,0xb9,0x0e,0x4a,0x8f,0x9b,0x1f,0x9c,0x89,0x9e,0x0f,0x03,0x15,0x9b,0x8b,0x83,0x4c,0x3e,0x88,0xc4,0x0c,0x00,0x1d,0x84,0x86,0x8d,0xa0,0xcb,0x0b +,0x02,0xa6,0x91,0x1a,0x08,0x03,0x18,0x91,0x87,0x81,0xaf,0x0a,0x18,0x29,0x39,0x14,0xc6,0x8c,0xa2,0x98,0xd1,0xd0,0x10,0x0a,0x67,0xab,0xad,0x2a,0x16,0x0f,0x1d,0x9b +,0x80,0x2f,0x14,0xaf,0x26,0x42,0x09,0xba,0x84,0x85,0x88,0x9c,0xbb,0x0d,0x4a,0x8b,0x8f,0x29,0x08,0x05,0x10,0x13,0x8d,0x89,0x07,0x15,0x1b,0x13,0x07,0x08,0x8a,0x8a +,0xcb,0x9a,0x90,0x97,0x3a,0x3f,0xa6,0x9f,0x9a,0x21,0x09,0x10,0x26,0x81,0x94,0x0b,0xb7,0xa9,0x22,0x00,0x11,0x85,0x93,0x8d,0x9d,0x1c,0x27,0x12,0xb1,0x9f,0xba,0x0e +,0x01,0x00,0x10,0x8a,0x80,0x34,0x12,0x8f,0x8d,0x97,0x0b,0xbf,0x8c,0x96,0x82,0x85,0x8a,0x13,0x04,0x0e,0x0b,0x29,0x2a,0x07,0x04,0x00,0xa7,0x80,0x44,0x31,0x0c,0x05 +,0x09,0x1e,0x82,0x89,0x8c,0x88,0x97,0xa7,0x0c,0x2e,0x93,0xab,0xa9,0x32,0x19,0x0d,0x1d,0x80,0xdd,0x0b,0x99,0x6b,0x2e,0x0a,0x4d,0x90,0xca,0xa6,0x99,0x8e,0x62,0x0c +,0x3c,0xad,0xa7,0x89,0x40,0x09,0x00,0x3b,0x80,0xad,0x8f,0xbe,0x0a,0x0b,0x08,0xa9,0xbd,0xbf,0x89,0x86,0x9e,0x1a,0x34,0x99,0x26,0xb3,0xa2,0x14,0x09,0x04,0x85,0x8d +,0x1f,0xa8,0x11,0x0f,0x00,0x26,0x8b,0x27,0xad,0x8a,0x86,0xa6,0x1b,0x31,0x20,0x14,0x9f,0x9e,0x1e,0x06,0x70,0x85,0x1c,0x91,0x88,0x3e,0x0e,0x0f,0x87,0x89,0x8f,0x86 +,0x83,0x86,0xbf,0xbb,0x90,0x18,0x13,0x29,0x10,0x04,0x04,0x9c,0x11,0x00,0x1f,0x0a,0x06,0x00,0x07,0x15,0x00,0x1d,0x8b,0xc7,0x0d,0x04,0x0b,0x0a,0x0c,0xb1,0xc8,0x38 +,0x0e,0x92,0x88,0x1c,0x85,0x8a,0xa8,0x26,0x40,0x81,0x88,0x9b,0x87,0x89,0xa4,0x90,0x86,0x8e,0x29,0x48,0x9d,0x9e,0xb6,0x95,0x80,0x11,0x2b,0x80,0x88,0x8c,0x45,0x8d +,0x8c,0x31,0x92,0x86,0x8e,0x90,0x92,0x96,0x17,0x12,0x26,0x0b,0x08,0x0d,0x8a,0x4f,0x00,0x26,0x16,0x0c,0x06,0x06,0x1f,0x02,0x1b,0x92,0x5b,0x29,0x29,0x92,0xae,0x0a +,0x0d,0x0d,0x0e,0x16,0x8d,0x83,0x05,0x0b,0x20,0x06,0x07,0x08,0x90,0xa2,0x19,0x93,0x9c,0x4b,0x47,0x8b,0x93,0x1a,0x1c,0x3d,0xfe,0x40,0xa4,0x80,0xa5,0x06,0x9d,0xbf +,0x23,0x29,0x98,0x80,0x9d,0x9c,0x8b,0xa0,0x1a,0xc1,0x86,0x8c,0xa9,0xa4,0x28,0x0d,0x06,0x9d,0x80,0x0e,0x1d,0x28,0x06,0x0d,0x13,0x8d,0xd4,0x07,0x31,0x4f,0x14,0x16 +,0x2c,0xd9,0x1a,0x19,0x44,0x1b,0x0f,0x1f,0x80,0x8f,0xaf,0x81,0x90,0x33,0x1e,0x93,0x80,0x84,0x83,0x80,0x8e,0xce,0xa8,0x8c,0x87,0x94,0x8b,0xb4,0x0b,0x05,0xa5,0x84 +,0x07,0x0d,0x18,0x00,0x02,0x00,0x12,0x1a,0x00,0x0e,0x19,0x00,0x01,0x05,0x14,0x14,0x0d,0x15,0x07,0x03,0x01,0x90,0x93,0x0d,0x8c,0xa0,0x09,0x01,0x0b,0x8f,0x9a,0xa3 +,0x80,0x8c,0x2f,0xf6,0x96,0x8d,0x9b,0x8b,0x87,0xb4,0x25,0xab,0x80,0x94,0x9a,0x80,0x4b,0x09,0x0f,0x9a,0x81,0x89,0x83,0x80,0x89,0xc9,0xce,0x9a,0x99,0x93,0x81,0x8b +,0x3e,0x0d,0x1a,0x8f,0x0e,0x3a,0x97,0x0c,0x04,0x01,0x1e,0xaf,0x24,0xa8,0xc3,0x0e,0x06,0x0d,0xdc,0x3b,0x39,0x9b,0x22,0x07,0x02,0x38,0x86,0x0f,0xb6,0x90,0x0d,0x03 +,0x08,0x4e,0x2e,0x15,0x9e,0x93,0x2c,0x0b,0x19,0x2d,0x13,0x22,0xa5,0x5b,0x0f,0x06,0x9c,0x81,0x57,0x93,0x89,0x18,0x09,0x2a,0x92,0x94,0xaf,0x89,0x8b,0x3d,0x1c,0xa3 +,0xa5,0x28,0xb5,0x86,0x97,0x2d,0x2a,0x94,0x83,0x18,0xa3,0x8c,0x1d,0x09,0x16,0x3e,0x25,0x14,0xdb,0x96,0x24,0x1e,0x38,0x23,0x23,0x3b,0x91,0xcf,0x12,0x25,0x9b,0x80 +,0xb2,0x9b,0x80,0x96,0x45,0xab,0x8c,0x89,0x98,0x86,0x80,0x87,0x8b,0x8c,0x91,0xa8,0xa1,0x8b,0x8f,0x2b,0x0e,0x0e,0x91,0x0d,0x05,0x1d,0x0a,0x02,0x00,0x06,0x05,0x01 +,0x0b,0x23,0x0a,0x04,0x09,0x08,0x03,0x0f,0x27,0x16,0x03,0x02,0x05,0x99,0x6b,0x19,0x8d,0x9e,0x37,0x16,0xc5,0xbb,0x48,0x9d,0x86,0x84,0x91,0x98,0x92,0xb1,0xb0,0x96 +,0x8d,0x9f,0x28,0x28,0x8c,0x85,0xa5,0x84,0x89,0x39,0x33,0x9e,0x8f,0x91,0x90,0x81,0x84,0x99,0x9e,0x8e,0xa9,0xa3,0x8e,0x8b,0xa3,0x19,0x10,0x22,0x9b,0x14,0x38,0xa7 +,0x17,0x0d,0x0a,0x0d,0x0a,0x07,0x26,0x30,0x1a,0x10,0x2e,0x5f,0x2e,0x9b,0xc6,0x24,0x05,0x05,0x0b,0x97,0xa6,0x42,0xa6,0x10,0x0b,0x03,0x12,0x11,0x0c,0x6d,0xa6,0xbf +,0x3b,0xcd,0x9e,0x3f,0xb9,0xc8,0xed,0x13,0x15,0x1d,0x9f,0x8a,0x3a,0x94,0x97,0xbf,0x3c,0x5f,0x9d,0x98,0x8f,0x89,0x95,0x9e,0x9e,0x8e,0x91,0x98,0x8b,0xa3,0x31,0x16 +,0x0d,0x21,0x8f,0x4a,0xab,0xa8,0x21,0x22,0x0d,0x2b,0x1d,0x1b,0xbb,0x58,0x2e,0x4d,0xbe,0x5d,0x4c,0xa6,0x5d,0x20,0x1a,0x2f,0xa3,0x87,0x86,0x8c,0x88,0x8a,0x8a,0x93 +,0x8b,0x8b,0x93,0x8d,0x88,0x8c,0x93,0x8f,0x94,0x9e,0xab,0xb4,0x40,0x0d,0x0a,0x07,0x0a,0x1c,0x09,0x0d,0x0d,0x04,0x02,0x01,0x03,0x03,0x04,0x09,0x06,0x08,0x0b,0x17 +,0x26,0x1d,0x2a,0x19,0x08,0x0a,0x0a,0x3f,0x8e,0xab,0x94,0x97,0xc6,0x3e,0x3c,0x92,0x98,0x9a,0x8a,0x8f,0x8f,0x8a,0x85,0x88,0x8e,0x8d,0x90,0xac,0xbf,0x4b,0xab,0x8f +,0xae,0x97,0x96,0x9f,0x9b,0x99,0x8a,0x91,0x92,0x89,0x8f,0x97,0x95,0x88,0x8c,0x93,0x90,0xa9,0x1d,0x09,0x08,0x0e,0x34,0x1b,0x19,0x1b,0x1a,0x1d,0x0c,0x1d,0x28,0x13 +,0x17,0x17,0x17,0x35,0xd0,0xb7,0x3c,0x1d,0x19,0x0a,0x0c,0x0d,0x0b,0x27,0x21,0x16,0x1c,0x15,0x23,0x16,0x1f,0x2c,0x15,0x18,0x1e,0x31,0x2d,0xbb,0xb5,0x45,0x6e,0x48 +,0x2d,0x28,0x2d,0x1d,0xa5,0xa5,0xb2,0x91,0x99,0x8d,0x9f,0x9f,0x92,0xad,0x9f,0x91,0x97,0x9b,0x8d,0x8b,0x92,0x95,0x99,0xb1,0x46,0x1e,0x1c,0xaf,0xce,0x22,0x26,0x2c +,0x3c,0x24,0x35,0xcf,0x28,0x25,0xd1,0xa5,0xb2,0x9d,0x8e,0x99,0x9e,0xa9,0x9d,0x9e,0xaf,0xaf,0x9d,0x94,0x9e,0x99,0x8f,0x8a,0x8c,0x8d,0x8c,0x8f,0x92,0x8d,0x8d,0x92 +,0x93,0x95,0xa3,0x39,0x1f,0x1b,0x0b,0x06,0x04,0x02,0x04,0x03,0x02,0x04,0x04,0x05,0x06,0x06,0x07,0x0c,0x0d,0x09,0x0f,0x19,0x19,0x1a,0x16,0x1a,0x22,0x1e,0x18,0x1a +,0x29,0x2e,0xb8,0xae,0xab,0x97,0x93,0x8e,0x9a,0x99,0x8e,0x8d,0x91,0x8f,0x88,0x8b,0x92,0x92,0x93,0x9a,0x9c,0x9b,0x9f,0x9e,0xb6,0xbf,0xc4,0xaa,0x8e,0x8f,0x94,0x9e +,0xa1,0x94,0x94,0x97,0x8e,0x8d,0x91,0x9b,0x93,0x98,0x6f,0xc1,0x3b,0x1e,0x1e,0x1a,0x14,0x0b,0x0a,0x12,0x16,0x12,0x0f,0x16,0x10,0x14,0x27,0x37,0x4d,0x3b,0x3f,0x6f +,0x2f,0x2e,0x4a,0x23,0x1e,0x19,0x1a,0x10,0x08,0x0f,0x0f,0x15,0x14,0x18,0x1b,0x11,0x1b,0xd3,0xb9,0x48,0x2e,0x6e,0xb6,0x44,0xdf,0xae,0xa7,0x3a,0x40,0xd3,0x41,0x41 +,0xa4,0x9b,0x96,0x93,0x96,0x99,0x9d,0x90,0x91,0x8a,0x8e,0x90,0x91,0xa4,0xb4,0xae,0xa8,0x50,0x28,0x41,0x38,0x16,0x11,0x28,0x69,0x55,0x3b,0x6a,0x31,0x21,0xd3,0xa2 +,0x99,0x9b,0xa0,0x9c,0xa9,0xa9,0x93,0x8d,0x8f,0x96,0x94,0x96,0x9a,0x8f,0x8a,0x8b,0x8b,0x8e,0x9d,0xa4,0x9c,0x99,0x97,0x9e,0xa1,0xac,0x25,0x1a,0x1d,0x1b,0x0e,0x0b +,0x0c,0x0b,0x04,0x03,0x05,0x06,0x05,0x04,0x06,0x04,0x05,0x07,0x0b,0x11,0x1c,0x16,0x14,0x16,0x16,0x22,0x23,0x20,0x37,0xcb,0x3a,0x2c,0x4d,0xbc,0xa2,0xa7,0x9c,0x91 +,0x9d,0x99,0x92,0x8d,0x89,0x89,0x88,0x8f,0x93,0x92,0x93,0x95,0x99,0x9b,0xad,0xc7,0xbc,0xb0,0xb5,0xbd,0xa7,0x9f,0x98,0x99,0x98,0x96,0x8a,0x8b,0x8c,0x8d,0x8f,0x8f +,0x9a,0xad,0xc9,0x53,0x35,0x2a,0x13,0x20,0x14,0x11,0x12,0x1e,0x1d,0x23,0x17,0x1b,0x24,0x09,0x0c,0x0a,0x17,0x0e,0x09,0x19,0x0d,0x1a,0x3d,0x21,0xbe,0xb8,0x27,0x54 +,0x8e,0xac,0xc0,0x8e,0xa4,0x9c,0x92,0x10,0x6b,0x8b,0xab,0xa3,0xa4,0x54,0x3e,0x3d,0x0f,0x0e,0x0b,0x0e,0x0e,0x16,0x1b,0x16,0x35,0x33,0x29,0x2a,0xb3,0x38,0x27,0x34 +,0x57,0xb6,0x9a,0x8b,0x90,0x8e,0x8d,0x8e,0x9e,0xa2,0xac,0x99,0x90,0x95,0x98,0x91,0x87,0x8a,0x8e,0x93,0x91,0xac,0x9f,0x91,0xac,0xbf,0xa8,0xa2,0x4b,0x21,0x1d,0x15 +,0x0c,0x0d,0x0e,0x0b,0x0b,0x06,0x19,0x0f,0x0b,0x11,0x07,0x04,0x0a,0x0f,0x13,0x1b,0x48,0xa1,0x58,0x3d,0xb6,0xaf,0x9d,0x98,0x8d,0x87,0x85,0x87,0x85,0x86,0x87,0x84 +,0x87,0x87,0x8f,0x8d,0x8d,0x8f,0xac,0xa6,0xd9,0x29,0x1e,0x14,0x12,0x0d,0x0e,0x0a,0x0e,0x0a,0x0c,0x0e,0x0c,0x0c,0x12,0x0d,0x0a,0x08,0x0c,0x13,0x14,0x26,0x1e,0xd9 +,0xde,0x53,0xc8,0x20,0x3e,0xbc,0xb9,0x4e,0xde,0x37,0x2d,0xe3,0x48,0xbe,0xab,0xa0,0x9e,0x97,0x93,0x8e,0x89,0x89,0x86,0x8b,0x8c,0x8e,0x8f,0x92,0x9e,0xaa,0x35,0x44 +,0x37,0x27,0x1c,0x0f,0x18,0x11,0x13,0x1f,0x11,0x1f,0x1f,0x3d,0x21,0x1c,0x19,0x13,0x21,0xb4,0xad,0xc6,0x9b,0xa0,0x8e,0x8d,0x91,0x8e,0x8e,0x86,0x89,0x92,0x8e,0x8b +,0x8c,0x91,0x8a,0x94,0xa5,0x9d,0xaa,0x33,0x2f,0x10,0x1e,0x16,0x1d,0x6d,0x16,0x1b,0x1b,0x44,0x0f,0x0f,0x0f,0x13,0x14,0x16,0x19,0x37,0x65,0x1c,0x1a,0x1c,0x15,0x11 +,0x18,0x15,0x1a,0x1f,0x2b,0x12,0x17,0x19,0x13,0x08,0x08,0x13,0x0f,0x0e,0x0a,0x24,0xa8,0x28,0x1a,0x38,0x9e,0x94,0x9e,0xa1,0x99,0x89,0x85,0x88,0x89,0x91,0x89,0x8e +,0x9b,0x96,0xa8,0x9e,0xaa,0x9b,0xc8,0xb1,0x3d,0x3f,0x35,0x1d,0x3e,0x19,0xd3,0x4c,0x9e,0x98,0x90,0x8f,0x98,0x94,0xa0,0x9b,0x98,0xae,0xa0,0xa4,0x9a,0x9a,0x98,0x95 +,0xba,0xb2,0x2a,0xae,0x1e,0x3d,0x2c,0x1e,0xc9,0x21,0x2b,0x17,0x17,0x0c,0x09,0x08,0x16,0x1f,0x1c,0x25,0x34,0x8f,0x86,0x89,0x89,0x8b,0x8b,0x94,0x9c,0x8b,0xa9,0x2f +,0xae,0x0f,0x09,0x05,0x02,0x06,0x00,0x02,0x00,0x07,0x01,0x07,0x1a,0x13,0x0c,0x0c,0x1e,0x16,0x1e,0xdc,0xa6,0x95,0x9b,0x94,0x8b,0x90,0x94,0x8c,0x8a,0xa8,0xb0,0x89 +,0x88,0x8b,0x87,0x88,0x92,0xa0,0x93,0xa4,0xa5,0xa2,0x90,0x93,0xa7,0x8f,0x8e,0x96,0xd4,0x9a,0x2a,0xcd,0x44,0xd0,0xa1,0x2b,0x4b,0x1a,0x4f,0x22,0x16,0x17,0x11,0x09 +,0x10,0x19,0x1e,0x18,0x1b,0x1a,0x0f,0x15,0x08,0x11,0x1a,0x3f,0xc4,0x3b,0xa7,0x9a,0x89,0x8e,0x88,0x84,0x8b,0x82,0x84,0x83,0x84,0x81,0x8c,0x8e,0x9b,0x34,0x3c,0x0c +,0x08,0x0a,0x0b,0x0c,0x06,0x08,0x03,0x05,0x04,0x07,0x0a,0x05,0x06,0x0f,0x0f,0x0c,0x17,0x0a,0x12,0x14,0x15,0x10,0x0c,0x16,0x41,0xa0,0xa9,0x98,0x99,0x8e,0xb7,0x98 +,0x8c,0x9a,0x93,0x98,0x8a,0x8c,0x8b,0x89,0x88,0x86,0x8c,0x8d,0x8e,0x98,0x8e,0x8a,0x84,0x8b,0x91,0x94,0x99,0xd6,0xac,0xc5,0xbb,0x1f,0x16,0x38,0x24,0x20,0x20,0x4a +,0x0e,0x0e,0x06,0x0c,0x09,0x0b,0x19,0x0c,0x19,0x21,0x2b,0x3b,0xca,0x9d,0x8f,0x8f,0x8a,0x86,0x8a,0x89,0x81,0x84,0x88,0x8f,0xa9,0xcd,0x1f,0x11,0x0f,0x19,0x08,0x0e +,0x16,0x0b,0x0b,0x0b,0x0e,0x12,0x13,0x0c,0x1f,0x2a,0x22,0x36,0xb0,0x27,0x2c,0x13,0x0f,0x13,0x10,0x2c,0x29,0x1f,0x35,0x4d,0x2a,0x3e,0x26,0x28,0x17,0x2c,0x33,0x3b +,0x6a,0xbb,0xa5,0x97,0x9b,0xcd,0x90,0x9c,0x99,0x8e,0x92,0x8c,0x87,0x84,0x86,0x8c,0x8b,0x91,0x92,0x8e,0xc5,0x95,0x9f,0x4f,0xdf,0xa9,0xb1,0x13,0x1d,0x1a,0x18,0x0f +,0x0d,0x0e,0x11,0x1d,0x3e,0xb5,0xb8,0xb0,0xbd,0xa1,0x8a,0x8c,0x8b,0x88,0x88,0x85,0x83,0x90,0x97,0xa6,0x3f,0x1b,0x0a,0x0c,0x08,0x0a,0x06,0x07,0x08,0x07,0x02,0x05 +,0x05,0x0b,0x0d,0x0c,0x12,0x2e,0x21,0x1f,0xbe,0x26,0xbc,0xd4,0x6a,0x2d,0x32,0xb4,0xac,0x94,0x97,0x98,0x9c,0x9c,0xa4,0xb1,0xb7,0x3a,0xa9,0x9e,0xb4,0x99,0x91,0xb5 +,0x9a,0xb0,0xad,0xae,0xb7,0x5d,0xb6,0x8d,0xa2,0x9f,0xa1,0xa0,0x55,0x43,0xb9,0x3b,0x4b,0x50,0x3a,0xbf,0x20,0xb1,0xad,0x17,0x28,0x15,0x1c,0x16,0x1a,0x27,0x20,0xba +,0x9f,0x96,0x98,0x9f,0x8e,0x86,0x8e,0x89,0x83,0x84,0x85,0x84,0x86,0x85,0x92,0x9e,0xbd,0x1f,0x19,0x07,0x0e,0x08,0x07,0x0a,0x06,0x05,0x05,0x04,0x05,0x07,0x03,0x0c +,0x09,0x08,0x19,0x27,0x19,0x11,0x1c,0x17,0x1f,0x1c,0x2c,0x2f,0xad,0xaf,0x9f,0x93,0xb5,0x9b,0xa6,0x9c,0xc2,0xb1,0xb0,0x99,0x98,0x8f,0x8c,0x97,0x8d,0x90,0x96,0x9d +,0x9a,0x97,0x89,0x93,0x8d,0x88,0x94,0x93,0x9d,0xa4,0xb4,0x2f,0x34,0x51,0x1d,0x21,0x5b,0x2d,0x1a,0x11,0x0c,0x0c,0x0f,0x10,0x07,0x09,0x16,0x15,0xc6,0xd3,0x35,0xae +,0x99,0x92,0x97,0x8e,0x8b,0x87,0x82,0x82,0x85,0x8a,0x92,0x93,0xbf,0x46,0x44,0x12,0x0f,0x0d,0x0f,0x0f,0x09,0x0f,0x0a,0x07,0x06,0x08,0x09,0x12,0x12,0x13,0x28,0x15 +,0x24,0x2c,0x11,0x17,0x15,0x11,0x24,0x29,0x21,0x42,0xa8,0x64,0x3a,0xa4,0xa5,0x25,0x2e,0x2c,0xad,0x96,0x9e,0x90,0x8f,0x8e,0x9f,0x93,0x91,0x9b,0x95,0x92,0x8f,0x91 +,0x8d,0x89,0x90,0x99,0x97,0xb6,0xd2,0xab,0xc9,0xce,0xb1,0xb1,0xb8,0x1a,0x19,0x19,0x17,0x10,0x0a,0x0e,0x0d,0x0b,0x0f,0x14,0x69,0x9b,0x2d,0xb2,0x94,0x9c,0x90,0x87 +,0x82,0x85,0x86,0x82,0x82,0x89,0x91,0x99,0xf3,0x2d,0x13,0x0e,0x0c,0x08,0x08,0x09,0x08,0x02,0x05,0x05,0x03,0x05,0x06,0x15,0x16,0x14,0x2e,0x1e,0x24,0x31,0xcf,0x61 +,0x44,0x30,0xbe,0x9e,0x9d,0x99,0x8c,0x90,0x94,0x9e,0xa5,0xbf,0x4c,0x90,0x9d,0xa0,0xa5,0x9e,0xad,0xf8,0xaa,0x9e,0xa6,0x2b,0x36,0xa5,0xa1,0x95,0x9b,0x99,0xac,0xc2 +,0xb0,0xd2,0xcb,0x36,0xcd,0xaa,0xd3,0x3f,0xc3,0x78,0x37,0x1c,0x25,0x0f,0x0d,0x11,0x1b,0x13,0x13,0x4b,0xaf,0xa5,0xa9,0x9e,0x94,0x8f,0x8c,0x86,0x82,0x82,0x82,0x82 +,0x86,0x8b,0x93,0x90,0xcb,0x1f,0x10,0x14,0x0e,0x08,0x0a,0x0d,0x07,0x02,0x04,0x05,0x06,0x06,0x0c,0x11,0x17,0x10,0x2c,0x1c,0x17,0x26,0x26,0x1b,0x16,0x2e,0xb6,0xb4 +,0xba,0xa9,0x9a,0xb4,0x5e,0xa4,0xd2,0xa6,0x7b,0xc8,0xa4,0x95,0x93,0xa5,0x99,0x97,0x99,0x9d,0xac,0xa3,0x8f,0x91,0x8f,0x8c,0x89,0x92,0x9b,0x95,0x97,0xa8,0xc1,0xab +,0x9f,0xa8,0xc2,0xbf,0xba,0x4b,0x1d,0x0e,0x0e,0x11,0x0c,0x0f,0x13,0x0e,0x17,0x1e,0x24,0x4c,0xcb,0xb2,0x9d,0x96,0x8c,0x85,0x87,0x85,0x84,0x85,0x89,0x91,0x9a,0x9e +,0xc7,0x1f,0x1b,0x15,0x0e,0x0d,0x0d,0x0a,0x09,0x05,0x04,0x06,0x06,0x08,0x0e,0x18,0x1c,0x2b,0x22,0x1b,0x1c,0x1b,0x2d,0x27,0x2c,0x3e,0x4f,0xc2,0xaf,0x9c,0xac,0xed +,0xce,0xbc,0xda,0x37,0x40,0x9e,0x97,0xa0,0xa2,0x9b,0x96,0xb2,0xab,0x97,0xa2,0x9a,0x91,0x96,0x97,0x96,0x8f,0x92,0x9e,0xab,0xaf,0xb4,0x56,0xb4,0xbd,0xd2,0xb6,0xba +,0xdb,0x30,0x1f,0x1b,0x1d,0x14,0x0e,0x0c,0x12,0x19,0x24,0xea,0x3c,0x2f,0xd4,0x9c,0x9d,0x9e,0x8b,0x84,0x84,0x85,0x83,0x83,0x86,0x8a,0x99,0xaf,0xf9,0x39,0x1a,0x0e +,0x12,0x0e,0x0a,0x04,0x03,0x04,0x05,0x02,0x03,0x0b,0x0f,0x0c,0x10,0x3b,0x2c,0x1b,0x15,0x1d,0x42,0xfa,0x2e,0x26,0xa6,0x98,0x9e,0xa3,0xa7,0xad,0x5d,0x38,0x3f,0x4c +,0xdc,0xaf,0xab,0xa3,0x9b,0x9e,0x9c,0xa0,0xaa,0xcb,0x9d,0x90,0x95,0x92,0x8d,0x88,0x91,0x9f,0xa9,0xae,0xb9,0xb9,0x3a,0x22,0xa6,0xa3,0xb9,0x3c,0x33,0x37,0x23,0x15 +,0x0b,0x1e,0x25,0x21,0x21,0x3b,0xa9,0xb0,0xda,0x4c,0xb2,0x9c,0x91,0x8f,0x8e,0x87,0x83,0x86,0x8a,0x88,0x8d,0x99,0xb0,0x29,0x4c,0x2c,0x1c,0x0d,0x0b,0x08,0x0b,0xca +,0x21,0x00,0x1d,0x98,0x07,0x14,0x0f,0x17,0x0d,0x06,0x0d,0x0c,0x15,0x00,0x05,0x01,0x02,0x0a,0x02,0x08,0x05,0x07,0x0e,0x0b,0x0a,0x0a,0x18,0x1c,0x1c,0x53,0xa9,0xa3 +,0xae,0x97,0x9c,0x9d,0x96,0x83,0x80,0x89,0x83,0x81,0x80,0x80,0x81,0x81,0x85,0x84,0x80,0x81,0x83,0x83,0x80,0x82,0x85,0x8e,0x8e,0x8d,0x8f,0x8d,0x8e,0x94,0x9a,0x92 +,0xa3,0xac,0x9f,0x3f,0x18,0x06,0x08,0x09,0x02,0x03,0x05,0x05,0x01,0x01,0x00,0x01,0x02,0x01,0x01,0x00,0x01,0x02,0x05,0x06,0x09,0x0a,0x04,0x01,0x01,0x03,0x04,0x02 +,0x01,0x05,0x08,0x04,0x04,0x08,0x13,0x29,0x21,0x27,0xac,0x8f,0x8b,0x87,0x84,0x82,0x86,0x8c,0x90,0x8a,0x85,0x85,0x86,0x85,0x82,0x82,0x81,0x84,0x81,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x84,0x88,0x88,0x88,0x93,0x8f,0x94,0x8d,0x8f,0x97,0x94,0x95,0x8c,0x8f,0x96,0x97,0x89,0x8b,0xa4,0xa5,0xa6,0x2e,0x16,0x0e +,0x09,0x0a,0x03,0x00,0x02,0x02,0x02,0x01,0x02,0x01,0x03,0x04,0x02,0x03,0x07,0x07,0x05,0x01,0x03,0x03,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x02,0x02 +,0x03,0x05,0x09,0x0c,0x0e,0x12,0x10,0x1c,0x2d,0x24,0x1c,0x0f,0x0b,0x0e,0x0c,0x07,0x0c,0x15,0x1f,0x16,0x20,0xb4,0xa4,0x95,0x8b,0x85,0x85,0x83,0x81,0x83,0x81,0x82 +,0x82,0x83,0x85,0x85,0x85,0x87,0x86,0x83,0x81,0x83,0x85,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x86,0x8d,0x89,0x8a,0x98,0xba,0xab,0x9d,0x34 +,0x21,0x24,0xe2,0xae,0x2c,0x20,0x1d,0x2c,0x3d,0x2a,0x26,0x18,0x11,0x12,0x12,0x1e,0x44,0x2a,0x1d,0x31,0x96,0xa2,0xa8,0x98,0x95,0x86,0x8d,0x8b,0x8c,0x8a,0x8b,0xac +,0xa1,0x3f,0x4d,0x3f,0x1b,0x95,0x94,0xa1,0x35,0x29,0x8b,0xae,0x21,0x0b,0x0f,0xcc,0x14,0x0e,0x08,0x15,0x0c,0x00,0x01,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x01,0x01 +,0x07,0x00,0x01,0x00,0x04,0x0a,0x01,0x01,0x01,0x0a,0x04,0x00,0x01,0x00,0x01,0x00,0x01,0x1f,0x0b,0x04,0x00,0x10,0x16,0x00,0x04,0x04,0xad,0x45,0x0c,0x0a,0x26,0x94 +,0x1b,0x14,0x3d,0xc2,0x2d,0x11,0x8f,0x80,0x83,0x85,0x8a,0x80,0x81,0x8d,0x87,0x80,0x80,0x80,0x83,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x89,0x89,0x80,0x80,0x80,0x82 +,0x83,0x80,0x86,0xa2,0x86,0x80,0x80,0x8d,0x98,0x85,0x81,0x8d,0x94,0x83,0x83,0x96,0x1a,0xa5,0x80,0x81,0x88,0x87,0x87,0x80,0x9a,0xe9,0x86,0x80,0x81,0x9d,0x9d,0x8b +,0x91,0x26,0x19,0xb3,0x1c,0x01,0x00,0x00,0xb6,0x17,0x00,0x02,0x02,0x08,0x00,0x02,0x00,0x07,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0xcf,0x12 +,0x00,0x02,0x0f,0x15,0x00,0x05,0x10,0x99,0x1b,0x07,0x0c,0x16,0x1d,0x0a,0x1f,0xb2,0x4f,0x0a,0x0a,0xa7,0x80,0x86,0x8e,0x8e,0x85,0x81,0xca,0x96,0x82,0x80,0x85,0x96 +,0x91,0x8b,0x8b,0xa0,0x90,0x8a,0x9b,0x19,0x0f,0xa7,0x80,0x8a,0x99,0xd8,0x8d,0x89,0x10,0x4d,0x90,0x80,0xa0,0x33,0x26,0xa7,0x9c,0x27,0xab,0xad,0x35,0x05,0x04,0x19 +,0x80,0x96,0x1e,0x0e,0xcb,0xa8,0x02,0x0c,0x3d,0x88,0x1d,0x0b,0x0a,0x22,0x2e,0x14,0x26,0x2b,0x12,0x01,0x02,0x16,0x80,0xa6,0x19,0x0c,0xbd,0xa0,0x02,0x0f,0xc3,0x84 +,0xe2,0x1d,0x21,0x9c,0x93,0xd3,0xa9,0xaf,0x6a,0x08,0x09,0x27,0x80,0x91,0x27,0x0d,0x3f,0x97,0x0a,0x10,0x3d,0x86,0xa6,0x2b,0x21,0x9e,0x88,0x98,0x91,0x8d,0x86,0xa8 +,0xc4,0x90,0x81,0x80,0x84,0x8c,0x8b,0x80,0x89,0x9a,0x8e,0x80,0x82,0x91,0xb0,0x9e,0x86,0xa8,0x37,0x2a,0x58,0x0b,0x01,0x00,0x17,0x8e,0x07,0x02,0x01,0x0f,0x05,0x00 +,0x01,0x0a,0x2d,0x05,0x03,0x00,0x1c,0x16,0x0d,0x0f,0x25,0x13,0x00,0x02,0x0e,0x82,0x9d,0x21,0x0c,0x46,0x97,0x13,0x1d,0xa9,0x80,0x8d,0xc4,0x46,0x8b,0x81,0x89,0x94 +,0x8f,0x87,0xed,0x27,0xc7,0x84,0x81,0x8e,0xd3,0xe6,0x83,0x9f,0x38,0xae,0x88,0x83,0xa2,0xb9,0x9c,0x86,0x98,0xbd,0x35,0xad,0x19,0x03,0x04,0x11,0x86,0x32,0x09,0x04 +,0x24,0x57,0x04,0x08,0x19,0x8e,0xbc,0x15,0x0d,0xd9,0x97,0x2b,0x12,0x12,0x24,0x03,0x04,0x00,0xa5,0x94,0x0e,0x08,0x0d,0x9b,0x10,0x09,0x0e,0x92,0x89,0xbd,0x18,0x2c +,0x89,0x9a,0xc6,0x1d,0x9c,0x1f,0x09,0x04,0x1d,0x80,0x92,0xb7,0x1c,0x8f,0x92,0x2d,0x5b,0x8f,0x80,0x85,0x9a,0x36,0x8c,0x87,0x99,0x24,0x31,0xbf,0x07,0x04,0x00,0xac +,0x8e,0x1a,0x0a,0x0c,0xa8,0x19,0x0e,0x23,0x8b,0x84,0x99,0xc2,0x9d,0x82,0x85,0x8d,0x9a,0x85,0x8f,0x2d,0x26,0x9a,0x80,0x83,0x8a,0xc7,0x91,0x8a,0xae,0x6e,0xb8,0x86 +,0x93,0x1e,0x0a,0x12,0x2b,0x0e,0x06,0x03,0x05,0x00,0x01,0x00,0x05,0xc6,0x0e,0x03,0x01,0x0b,0x0e,0x04,0x05,0x12,0xab,0x23,0x16,0x10,0x20,0x37,0x2b,0x1b,0x1a,0x28 +,0x0e,0x13,0x0d,0x95,0x80,0x8d,0xab,0x48,0x87,0x8f,0x9f,0xa6,0x88,0x80,0x85,0x91,0xa5,0x87,0x88,0x8d,0x9a,0x8f,0x94,0xc1,0x2a,0x38,0x82,0x83,0x89,0xc9,0xba,0x8d +,0xb0,0x24,0x2a,0x8b,0x8b,0xb1,0x12,0x11,0x56,0x4d,0x19,0x0f,0x21,0x0e,0x06,0x02,0x0a,0x87,0x8f,0x1f,0x06,0x14,0x48,0x0d,0x07,0x0d,0xa4,0xbc,0x10,0x04,0x11,0x4c +,0x1e,0x0f,0x16,0x25,0x0a,0x06,0x07,0x40,0x84,0x9c,0x27,0x0b,0x3b,0xcd,0x16,0x0d,0x2c,0x8c,0x9a,0xb5,0x2c,0xaa,0x97,0xa1,0x9f,0x97,0x91,0xbd,0x3c,0x2a,0x8e,0x80 +,0x87,0x99,0x25,0x96,0xa3,0x24,0x17,0xa7,0x88,0x92,0xdf,0x13,0x2b,0xae,0xb1,0x52,0x2a,0x2c,0x14,0x0c,0x09,0x9c,0x81,0x8e,0x33,0x15,0x9a,0x94,0xa1,0xb2,0x87,0x80 +,0x82,0x8b,0x98,0x85,0x80,0x85,0x8d,0x92,0x8d,0xac,0x11,0x0f,0x8f,0x85,0x1c,0x03,0x03,0x15,0x09,0x02,0x01,0x0e,0x2d,0x0a,0x03,0x03,0x15,0x0f,0x04,0x05,0x09,0x0a +,0x00,0x02,0x00,0xa3,0xa1,0x09,0x04,0x0c,0xdb,0x19,0x10,0x1e,0x8e,0x86,0x8f,0x9c,0x96,0x87,0x8f,0x9c,0x98,0x8e,0x9c,0x23,0x1b,0xf5,0x82,0x87,0x99,0x53,0x99,0x86 +,0x91,0x9c,0x94,0x80,0x82,0x82,0x8a,0x8f,0x86,0x88,0x8c,0x9a,0x95,0xd0,0x12,0x0a,0x12,0x85,0x90,0x2f,0x0b,0x1d,0xc8,0x1d,0x11,0x1e,0x8e,0x95,0xce,0x0f,0x24,0xae +,0x4a,0x1b,0x0e,0x1d,0x08,0x02,0x01,0x0b,0x8b,0xac,0x10,0x05,0x15,0x47,0x1c,0x0c,0x18,0x92,0xa6,0xb3,0x12,0x25,0xb2,0x28,0x1a,0x0f,0x2a,0x0c,0x08,0x04,0x24,0x80 +,0x96,0x3f,0x15,0x9a,0x89,0x9c,0x20,0x9e,0x81,0x85,0x8c,0xca,0x92,0x8d,0x9a,0x3d,0xf8,0x99,0x23,0x0f,0x08,0x52,0x80,0xa0,0x1b,0x10,0x9f,0x96,0x19,0x07,0xd1,0x86 +,0x90,0x3e,0x0f,0xac,0x9c,0xad,0xd0,0x99,0x8a,0xb3,0x22,0x32,0x88,0x80,0x82,0x88,0x8e,0x82,0x85,0x9a,0xc8,0x87,0x82,0x89,0x50,0x12,0x2b,0x20,0x11,0x0a,0x0d,0x0c +,0x00,0x02,0x00,0x14,0x98,0x0d,0x04,0x01,0x0c,0x0d,0x02,0x02,0x0c,0x1f,0x13,0x06,0x04,0x0f,0x1c,0x18,0x12,0x1d,0x29,0x10,0x12,0x13,0x90,0x80,0x99,0x48,0x37,0x8b +,0x8e,0x3f,0x1e,0x92,0x86,0x89,0x9f,0xad,0x8f,0x8b,0x8c,0x95,0x88,0x8a,0x9d,0x43,0xeb,0x85,0x80,0x89,0xad,0xab,0x87,0x92,0x1b,0x1f,0x8e,0x84,0x8e,0x2d,0x41,0x9f +,0x93,0xba,0x2d,0xb3,0x5b,0x0e,0x06,0x06,0x92,0x89,0x1b,0x09,0x08,0x3a,0x13,0x01,0x0a,0x61,0x9e,0x40,0x0c,0x13,0x36,0x33,0x10,0x0f,0x27,0x18,0x04,0x03,0x02,0x9d +,0x96,0x0b,0x0a,0x0a,0xf2,0x1c,0x05,0x17,0xa4,0x8c,0x94,0x7b,0xb0,0x9f,0x9c,0x58,0xb2,0x91,0xa1,0x23,0x0f,0x1d,0x85,0x88,0xa7,0x44,0xae,0x87,0x9e,0x1f,0xa6,0x88 +,0x80,0x8c,0xb7,0xb7,0x9d,0xa0,0x28,0xd9,0x9b,0x47,0x09,0x03,0x0f,0x85,0x92,0x44,0x24,0xaa,0x88,0x53,0x1d,0x94,0x80,0x81,0x8c,0xba,0x93,0x8c,0x9d,0xcb,0x9a,0x8d +,0x2e,0x06,0x04,0x18,0x87,0xab,0x15,0x10,0x1d,0x64,0x08,0x06,0x24,0x9c,0x9d,0x14,0x0e,0x1a,0x36,0x17,0x0f,0x2c,0x29,0x0c,0x03,0x04,0x14,0x86,0x9f,0x26,0x13,0x34 +,0x9d,0x18,0x0e,0xba,0x8a,0x89,0x56,0x18,0xed,0xae,0x4c,0x27,0xb0,0xa5,0x1a,0x05,0x06,0xed,0x80,0x96,0x36,0x1f,0x9f,0x90,0x15,0x12,0x97,0x86,0x89,0x3c,0x2c,0xab +,0xa7,0x32,0x41,0x99,0x9d,0x1d,0x0a,0x0c,0x9a,0x80,0x9f,0xad,0x49,0x8d,0x96,0x0e,0x20,0x95,0x84,0x8e,0xd5,0xe6,0xa9,0xa2,0x2e,0x4f,0x9f,0xa8,0x17,0x09,0x09,0x93 +,0x85,0x7a,0x2b,0x1e,0x97,0x3c,0x03,0x12,0xa9,0x8d,0xb5,0x17,0x1f,0x3a,0x36,0x0f,0x1e,0xb4,0x3b,0x0c,0x03,0x0a,0x8b,0x8c,0x26,0x1d,0x1c,0x9b,0x17,0x04,0x21,0x9f +,0x91,0x38,0x17,0x1e,0x3e,0x2b,0x19,0x38,0xb2,0x2d,0x0a,0x04,0x13,0x85,0x90,0x3e,0x20,0x2f,0x99,0x1a,0x0d,0xc9,0x8b,0x88,0x9e,0x55,0xe6,0x96,0xa0,0xb6,0x96,0x90 +,0x9c,0x1b,0x10,0xa9,0x80,0x8c,0xa4,0xcc,0x9c,0x8a,0x2c,0x1f,0x91,0x85,0x85,0xa7,0xcd,0xa8,0x93,0xad,0x49,0xa0,0x99,0x2d,0x08,0x06,0x2d,0x82,0xdc,0x16,0x13,0x1f +,0x74,0x05,0x09,0x3a,0x9b,0x9e,0x13,0x0f,0x20,0x5e,0x17,0x11,0x30,0x65,0x13,0x04,0x03,0x2d,0x85,0x32,0x13,0x12,0x37,0xc8,0x07,0x0b,0xca,0x8d,0x97,0x20,0x1e,0xb6 +,0xa6,0x1e,0x24,0xa5,0x9b,0x24,0x0b,0x0d,0x9c,0x80,0xa7,0xd9,0xc6,0x96,0x95,0x15,0x32,0x8c,0x82,0x8a,0xa1,0xa2,0x93,0x90,0xc6,0x9d,0x8d,0x90,0xdd,0x11,0x13,0x99 +,0x80,0x9b,0xae,0xd6,0x99,0xa6,0x0b,0x1b,0x9b,0x86,0x94,0x2b,0x2a,0x4d,0xb9,0x1b,0x27,0xd4,0xdc,0x0e,0x04,0x02,0x4e,0x82,0x29,0x18,0x18,0xd8,0x2c,0x00,0x0f,0xa4 +,0x8c,0xa9,0x16,0x1c,0x46,0x28,0x13,0x25,0xbe,0xbf,0x0c,0x03,0x06,0xaa,0x82,0x2d,0x1f,0x2f,0xa7,0x20,0x03,0x1b,0x93,0x89,0xb1,0x33,0x27,0xbf,0xf1,0x1e,0xb5,0xa9 +,0xbd,0x10,0x06,0x0e,0x90,0x80,0xb8,0xd7,0xbf,0x97,0x6d,0x0c,0xc9,0x88,0x84,0x93,0xa9,0xc1,0x9a,0xa4,0x4b,0xa0,0x9a,0xa0,0x13,0x0a,0x17,0x8b,0x82,0x39,0x49,0x56 +,0x9e,0x2a,0x09,0x55,0x8e,0x8c,0xaa,0x3e,0x2c,0x6e,0x30,0x1b,0x3e,0xc2,0x39,0x09,0x07,0x0a,0x8f,0x88,0x15,0x28,0x1f,0xad,0x19,0x06,0x32,0x97,0x94,0xad,0x27,0x20 +,0xde,0x23,0x22,0x38,0xc5,0x55,0x07,0x08,0x0c,0x8a,0x8a,0x18,0x34,0x2a,0x99,0x16,0x08,0xca,0x8d,0x8d,0xae,0xdd,0x51,0xaf,0x2b,0x26,0xa0,0x9b,0xbb,0x0e,0x0d,0x1f +,0x82,0x8e,0x39,0xa5,0xae,0x8c,0x1a,0x15,0x99,0x88,0x8b,0xa5,0xa9,0xae,0xb0,0x2e,0x43,0x9a,0x9b,0x3b,0x0c,0x0d,0x1a,0x83,0x96,0x33,0xac,0xce,0x9b,0x0e,0x0d,0xa7 +,0x8e,0x92,0xae,0x39,0xdf,0x2e,0x1b,0x2c,0xb2,0x9f,0x1e,0x08,0x0a,0x18,0x82,0xa4,0x21,0xde,0xd2,0xae,0x09,0x0c,0xa4,0x8f,0x9f,0xc4,0x28,0x61,0x21,0x13,0x3a,0xbb +,0xa7,0x1b,0x07,0x09,0x1c,0x82,0xad,0x2c,0xbc,0xb0,0xb5,0x06,0x0f,0x9d,0x8e,0x9c,0xaf,0xd7,0xb9,0x29,0x18,0xc8,0xa5,0xa1,0x21,0x0c,0x0e,0x42,0x80,0xab,0xcb,0xa7 +,0xa1,0xa0,0x07,0x1b,0x8f,0x8a,0x97,0xad,0xae,0xb4,0x27,0x16,0xb9,0x9d,0xaa,0x15,0x0a,0x0c,0x45,0x80,0x5e,0x7e,0xbe,0xb7,0x3e,0x03,0x1a,0x95,0x8e,0xa2,0xbf,0xca +,0x39,0x17,0x15,0xcd,0xa3,0xb4,0x0d,0x0b,0x0b,0x3d,0x80,0x39,0xca,0xbc,0xbd,0x2c,0x05,0x1e,0x93,0x92,0xa2,0xb1,0x49,0x30,0x19,0x1d,0xb6,0xa7,0xc4,0x0e,0x0a,0x0c +,0xbd,0x80,0x54,0xb1,0xb8,0xaf,0x29,0x07,0x4c,0x8e,0x8f,0x99,0x9f,0xc1,0x3b,0x22,0x2d,0xa6,0xa3,0xaf,0x15,0x0e,0x10,0xa6,0x80,0x3b,0xab,0xaf,0xa8,0x2f,0x07,0xca +,0x8d,0x92,0x9c,0x9a,0xcc,0x2e,0x25,0x24,0xa0,0xb6,0xc4,0x14,0x0c,0x0e,0xa6,0x82,0x2a,0xae,0xc9,0xa7,0x21,0x04,0x65,0x93,0x95,0x9f,0x9a,0xbb,0x2b,0x22,0x1f,0xaa +,0xdf,0x71,0x10,0x0d,0x0d,0x9f,0x84,0x1f,0xae,0x5a,0xad,0x17,0x03,0x49,0x95,0x98,0xa1,0x9c,0xce,0x28,0x1a,0x1a,0xb6,0x5d,0x47,0x0e,0x0f,0x0c,0x96,0x88,0x1f,0xa7 +,0xea,0xa5,0x11,0x07,0xb8,0x8f,0x96,0x97,0x99,0xbb,0x2d,0x19,0x31,0xa6,0xaa,0xbf,0x11,0x12,0x0c,0x8e,0x8a,0x27,0x99,0xaf,0x9f,0x0f,0x08,0xa5,0x8f,0x9a,0x94,0x96 +,0xc2,0x29,0x1b,0x35,0xab,0xc5,0x46,0x13,0x0d,0x0b,0x8b,0x8d,0x1e,0xa2,0xae,0xad,0x0a,0x09,0x9d,0x91,0x9f,0x9a,0x97,0x3d,0x1c,0x19,0x36,0xab,0x52,0x3c,0x0e,0x0b +,0x09,0x89,0x90,0x1b,0x9f,0xaa,0xbb,0x06,0x0b,0x9a,0x94,0xa1,0x99,0x94,0x43,0x1b,0x1e,0x3a,0xb1,0x52,0x38,0x10,0x0c,0x0e,0x84,0x99,0x22,0x9b,0xa5,0xb3,0x06,0x18 +,0x92,0x94,0x99,0x94,0x95,0x5d,0x1e,0x2a,0x4f,0xaf,0xc1,0x39,0x0f,0x0b,0x15,0x82,0x9f,0x29,0x96,0xa0,0xc4,0x06,0x1f,0x96,0x99,0x9b,0x8f,0x94,0xf8,0x2b,0x1e,0x37 +,0xe0,0xdc,0x2e,0x0f,0x0c,0x18,0x82,0xbe,0x2c,0x93,0xaf,0x3b,0x04,0x24,0x9a,0xa6,0x9a,0x8f,0x98,0x25,0x22,0x1c,0x28,0x59,0x50,0x28,0x0d,0x0a,0x13,0x82,0x59,0x37 +,0x94,0xac,0x27,0x04,0x25,0xa7,0xad,0x9b,0x8c,0x9a,0x20,0x29,0x26,0x1f,0x43,0xc7,0x2f,0x0e,0x0a,0x1b,0x81,0xde,0x48,0x8e,0x9f,0x2d,0x05,0x3c,0x9f,0xa5,0x92,0x8c +,0x97,0x27,0x3e,0x31,0x1d,0xce,0xad,0x33,0x0c,0x0b,0x27,0x82,0xc9,0x3e,0x89,0x9c,0x23,0x06,0x3a,0xa1,0xb1,0x93,0x8e,0x96,0x2a,0x3d,0x1e,0x1e,0xd1,0xb2,0x27,0x09 +,0x0f,0x19,0x86,0xc9,0x4b,0x8a,0xa4,0x1a,0x07,0x2a,0xaa,0x58,0x98,0x90,0x9e,0x37,0x2a,0x23,0x1d,0xd6,0xe0,0x1e,0x0a,0x12,0x10,0x8a,0xaa,0x72,0x8b,0x9f,0x24,0x08 +,0x33,0xc1,0x48,0x9a,0x8f,0x9a,0x5f,0x38,0x38,0x1f,0xa7,0x4f,0x21,0x0b,0x13,0x0f,0x96,0x8f,0x5c,0x88,0x99,0x32,0x0e,0x2e,0xcc,0x35,0x9f,0x8b,0x9d,0xc4,0xda,0xbc +,0x2e,0xbc,0xb5,0x1f,0x0c,0x10,0x0d,0xab,0x89,0xc7,0x8a,0x93,0x51,0x14,0x21,0x3b,0x2f,0xa8,0x8d,0xa3,0x4f,0xb4,0xac,0x34,0xde,0xa9,0x21,0x09,0x0b,0x0e,0x24,0x87 +,0xd1,0x8e,0x8d,0xd3,0x1e,0x17,0x3b,0x28,0x75,0x98,0x9f,0x6a,0xaa,0xb0,0x55,0x63,0xa9,0x20,0x09,0x0b,0x13,0x10,0x8b,0xa5,0x95,0x89,0xbe,0x2d,0x18,0xea,0x25,0x39 +,0xab,0x94,0x3f,0xba,0xac,0xab,0xb0,0xb4,0x2c,0x11,0x0b,0x12,0x0c,0x99,0x8e,0xb8,0x86,0xa6,0xb8,0x1b,0x59,0x41,0x25,0xb1,0x96,0x3f,0xcf,0xa0,0xa5,0xb3,0xbe,0xc5 +,0x13,0x0d,0x12,0x0d,0x48,0x8c,0x49,0x8b,0xa2,0xa7,0x25,0x3b,0xa3,0x20,0xb1,0xa3,0xc7,0x20,0xa5,0x9f,0xc3,0xbb,0xa9,0x1b,0x10,0x11,0x0f,0x11,0x98,0xac,0xa3,0x9c +,0xb8,0xaf,0x1e,0x9d,0x4a,0xc1,0xb3,0xb4,0x23,0x36,0x9b,0xb0,0xba,0xdf,0x57,0x14,0x15,0x16,0x14,0xbd,0x9f,0xbe,0xb4,0x68,0xa4,0x38,0xac,0xa5,0x5f,0xaf,0x46,0x66 +,0x29,0xa1,0x9c,0xb4,0xe1,0x42,0x2d,0x1e,0x16,0x28,0x3b,0xaf,0xad,0x27,0xdf,0xc7,0xb6,0x57,0xb9,0xa5,0xc6,0x4b,0x31,0xb7,0x9c,0xa4,0x9f,0xb4,0xba,0x49,0x26,0x4e +,0xed,0xac,0x5b,0xe5,0x3f,0x2f,0x46,0x2d,0x46,0x4b,0x3d,0x28,0x27,0x35,0x49,0xad,0xa1,0xa4,0xaa,0xb4,0x3e,0x3f,0xb8,0xb7,0xa9,0xb3,0xa8,0xb8,0x5a,0xd8,0xee,0xc2 +,0x2e,0x3a,0x1f,0x1c,0x20,0x1c,0x56,0xc1,0xc4,0x68,0x3e,0x3b,0x2c,0x74,0xb6,0xaf,0xab,0x9f,0xa3,0xff,0xa9,0xa0,0xa9,0xbc,0xda,0x58,0x22,0x23,0x26,0x5f,0xbd,0x2d +,0x2a,0x28,0x25,0x1f,0x22,0x47,0xb8,0xc3,0xdd,0xb4,0xaf,0xad,0xa9,0xa2,0xa4,0xa9,0xb3,0x4a,0xe5,0xb9,0xa9,0xaa,0xad,0xba,0x22,0x13,0x0f,0x2b,0x9c,0x92,0xa9,0x29 +,0x14,0x07,0x12,0xb0,0x90,0x93,0xac,0x5a,0x48,0x22,0x1f,0x9f,0x8b,0x8f,0x9e,0x34,0x1d,0x43,0x56,0xb4,0xbd,0x19,0x0c,0x0d,0x3d,0x9c,0x99,0x31,0x2c,0x27,0x2b,0x27 +,0x1f,0x9d,0x8e,0x8c,0x3b,0x1c,0x1f,0x39,0x99,0x94,0x9e,0xd8,0x14,0x23,0xa8,0xa9,0xa5,0x4b,0x22,0x23,0x33,0x2c,0x6c,0xa4,0x9d,0xaa,0x2c,0x13,0x0f,0x1e,0x9d,0x8f +,0xa0,0x38,0x24,0x24,0xd1,0x99,0xac,0x2d,0xca,0xad,0xb7,0xbe,0xb8,0xc3,0x24,0x24,0x4c,0x4e,0xad,0x96,0x95,0xa9,0x22,0x0e,0x0e,0x2a,0xaa,0x9e,0xa6,0xb0,0x2e,0x1c +,0x1a,0x2c,0xa6,0x9b,0x9f,0xfc,0x2d,0xd6,0xf2,0xfc,0xbb,0x36,0x19,0x0d,0x28,0x95,0x8f,0xa3,0xb9,0xbd,0x3d,0x2f,0x28,0xc7,0x95,0x92,0xa6,0x27,0x15,0x19,0x39,0x9a +,0x9a,0x2e,0x0c,0x0b,0x25,0xa6,0x9d,0xb5,0x25,0x23,0x2c,0x2f,0x71,0x9d,0x8e,0x97,0xa0,0x4c,0x1b,0x12,0xba,0x87,0x89,0x9b,0x1c,0x0d,0x19,0x49,0xbd,0xb8,0xe5,0x68 +,0x45,0x2c,0x3c,0x2e,0x22,0x2c,0x2c,0x32,0x25,0x4c,0x9e,0x92,0x91,0x46,0x11,0x11,0x2c,0xb5,0xa1,0x95,0x8f,0xb8,0x27,0x25,0x5c,0x9a,0x9c,0xac,0x43,0x32,0x33,0x28 +,0x3d,0x55,0x32,0x1a,0x13,0x2a,0x6f,0xd1,0x4a,0xb7,0xa6,0xac,0x2a,0x23,0xc5,0xa2,0x9d,0xa0,0x3f,0x1f,0x2c,0xb6,0x93,0xa0,0x27,0x15,0x2e,0xa5,0x9c,0xb6,0x21,0x1a +,0x2c,0x30,0x45,0xb3,0x9f,0x9a,0xa7,0xa5,0x28,0x0f,0x17,0xab,0x89,0x8d,0xb6,0x12,0x0f,0x2f,0xae,0xb0,0x3b,0x2b,0x28,0x43,0xba,0xab,0x30,0x2d,0x3b,0x42,0x3f,0x39 +,0xaa,0x98,0x8c,0x99,0x27,0x10,0x13,0x2f,0x9e,0x93,0x95,0xb5,0x26,0x1c,0x27,0xa6,0x99,0xb5,0x3a,0x2c,0x24,0x24,0x35,0xcb,0x78,0x39,0x19,0x13,0x1a,0x3b,0x99,0x97 +,0x98,0xa4,0x2c,0x1b,0x1c,0xaf,0x94,0x91,0x9e,0x3b,0x1e,0x26,0xba,0x9a,0xaf,0x2e,0x33,0x2b,0xd1,0xdd,0xe2,0x35,0x27,0x2a,0x22,0x2e,0xcd,0xa5,0x97,0x9d,0xc5,0x1a +,0x0c,0x1c,0xab,0x90,0x95,0xfa,0x1f,0x1e,0x25,0xd5,0xae,0xac,0xc9,0xc2,0xac,0xa4,0xc9,0x27,0x42,0xb6,0xaf,0x5a,0x2c,0xd5,0x9c,0x96,0xb9,0x1d,0x18,0x16,0x2a,0xa4 +,0x9a,0xa4,0x40,0x1f,0x27,0x31,0xc9,0x63,0xe3,0xcd,0x38,0x2e,0x26,0x53,0xc1,0x59,0x44,0x23,0x1b,0x31,0xb7,0x8d,0x8b,0x90,0xa7,0x2b,0x3a,0x30,0x5d,0xa9,0x9e,0xad +,0x2e,0x22,0x36,0x45,0xf2,0x3a,0x21,0x20,0x23,0x3a,0x44,0x70,0x5c,0x21,0x23,0x20,0x3f,0xab,0xa8,0x95,0x9e,0xdf,0x1d,0x1b,0xbe,0x93,0x8b,0x92,0xb9,0x23,0x1a,0x20 +,0xea,0xb1,0xac,0xb7,0xe4,0xbe,0x40,0x2c,0x2b,0x30,0x5f,0x36,0x2b,0x1f,0xf2,0x9b,0x99,0x9f,0x1f,0x12,0x10,0x22,0xaf,0xa5,0xaa,0xb7,0xda,0x60,0xd5,0xba,0xa9,0xad +,0xaf,0xdc,0x3e,0xdd,0x64,0xac,0xa7,0xb8,0x3b,0x13,0x1e,0x7c,0x97,0x99,0xaa,0xc6,0x28,0x1f,0x1d,0x39,0xa9,0xa3,0xb2,0x44,0x1f,0x27,0x26,0x31,0x51,0xda,0x79,0x36 +,0x2f,0x40,0x62,0x4f,0x29,0x2a,0x54,0xc2,0x9d,0x9a,0x8f,0x95,0xb8,0x3f,0x29,0xc6,0xa2,0x9c,0x9f,0xed,0x36,0x1f,0x20,0x2e,0x2e,0x4c,0x4e,0x2b,0x24,0x23,0x2c,0x2f +,0x35,0xc3,0x30,0x23,0x24,0xd7,0xa3,0x9f,0xa7,0x2f,0x2b,0x49,0xbb,0x9e,0x9b,0x9a,0x99,0xa9,0xb1,0xdb,0xba,0xa4,0xb7,0xce,0x3a,0x2b,0x29,0x26,0xe3,0x3c,0x24,0x15 +,0x0b,0x19,0x3f,0x9e,0x9e,0xac,0xc4,0x2c,0x1c,0x18,0x2c,0xa4,0x9b,0xa4,0xac,0xbd,0xab,0x5e,0xba,0xa0,0xa5,0xa7,0xfb,0xdd,0xb3,0xb6,0xaf,0x38,0x2e,0x39,0x29,0x5e +,0xc1,0xa6,0xb2,0x2d,0x1f,0x1a,0x3c,0xc2,0xc9,0xba,0x2f,0x21,0x19,0x19,0x1e,0x40,0xac,0xa7,0xb9,0xbc,0xc4,0xc4,0xae,0xb1,0x9c,0xad,0xb5,0xbf,0xa5,0x92,0x9a,0xa7 +,0x4d,0x30,0x2f,0x23,0x2d,0x3b,0xd4,0xae,0x5e,0x3a,0x29,0x23,0x1d,0x1c,0x1f,0x25,0x24,0x2e,0x35,0xce,0xc6,0x2d,0x22,0x20,0xb7,0x9c,0x90,0x8f,0x97,0x96,0xa5,0xc8 +,0xc3,0xaf,0xa3,0xa6,0xaa,0xbd,0x48,0x38,0x2b,0x30,0x3f,0x2c,0x28,0x1b,0x1e,0x25,0x1d,0x1e,0x15,0x16,0x1c,0x2b,0x74,0xb4,0xa1,0xad,0xb1,0xaf,0xaf,0x99,0x94,0x95 +,0x97,0xa0,0xa4,0xb5,0x5f,0xad,0xac,0xaa,0xbc,0x34,0x3f,0x29,0x2d,0x2e,0x28,0x26,0x14,0x18,0x19,0x23,0x4c,0x3d,0x3c,0x24,0x21,0x26,0x24,0x4c,0xab,0x9e,0x95,0x9f +,0x9f,0x9f,0xa7,0x9c,0xa5,0x9e,0xa6,0xaf,0x9e,0xad,0xa9,0xb8,0x29,0x20,0x15,0x23,0x43,0x45,0xcd,0x3e,0x32,0x1b,0x11,0x17,0x18,0x2a,0x38,0x3a,0x59,0x2b,0x49,0xc7 +,0xad,0x9d,0xa4,0x9d,0xa6,0xae,0x9c,0xa0,0x9e,0xa6,0xac,0x9f,0xb7,0xb0,0xb5,0xaf,0xac,0x49,0x41,0x26,0x25,0x26,0x23,0x2e,0x1d,0x18,0x16,0x11,0x1b,0x23,0x30,0x38 +,0x29,0xbf,0xdb,0xb9,0xa2,0xae,0x9e,0xab,0xaa,0x9d,0x9a,0x91,0x98,0x95,0x9a,0xd4,0xd1,0x5b,0x5d,0xb8,0xbf,0xb3,0x39,0x24,0x20,0x17,0x1b,0x12,0x14,0x18,0x17,0x28 +,0x25,0x29,0x26,0x1b,0x34,0x2e,0xd9,0x99,0x97,0x8e,0x93,0x92,0x93,0xa3,0xa3,0xa1,0x94,0x9a,0xb0,0xb0,0xe2,0xd4,0xe0,0x29,0x2d,0x1f,0x18,0x17,0x12,0x1e,0x18,0x19 +,0x19,0x15,0x24,0x25,0x2c,0x3b,0xab,0x9e,0xad,0xa2,0x9e,0x9a,0x93,0x99,0x9b,0x9b,0xa5,0xaa,0xab,0xa6,0xae,0xbb,0xbc,0x5f,0xd9,0xec,0x45,0x2e,0x1a,0x1a,0x18,0x13 +,0x19,0x1b,0x29,0x28,0x25,0x2c,0x22,0x24,0x34,0xcb,0xb5,0xa2,0x99,0x96,0x97,0x99,0x9b,0x98,0xa1,0xbb,0xa2,0xa5,0xae,0xae,0xbf,0xd2,0x2e,0x27,0x1f,0x1e,0x2c,0x24 +,0x2d,0x24,0x1c,0x26,0x1d,0x1d,0x21,0x31,0xdc,0x24,0x2e,0xc1,0xcb,0xa6,0xa8,0x9f,0x9d,0xa3,0x9d,0xac,0x9e,0xa1,0xae,0xa4,0xf3,0xb8,0xac,0xb4,0xb3,0xbc,0xac,0x5a +,0x23,0x1f,0x20,0x25,0x1e,0x18,0x1a,0x18,0x1d,0x1b,0x20,0x2b,0x28,0xfa,0x59,0xcb,0xa0,0x9b,0x9a,0x9f,0x9b,0x9b,0xa5,0xa3,0xa8,0x99,0x9a,0xad,0xb8,0xd3,0xc7,0x7d +,0x3a,0x32,0x35,0x30,0x29,0x1d,0x1d,0x1b,0x1a,0x17,0x15,0x28,0x2b,0x2f,0x27,0x34,0x52,0x47,0xc1,0xae,0x9e,0x95,0x96,0x9b,0x98,0x99,0x9b,0xa0,0xa2,0xaa,0xad,0xb4 +,0x5c,0xd7,0xb8,0x4c,0x3a,0x20,0x1b,0x1d,0x16,0x18,0x17,0x1c,0x1c,0x17,0x1b,0x1f,0x2c,0x57,0x4c,0xaf,0x9f,0x9f,0x9d,0x9d,0x93,0x93,0x93,0x97,0xaa,0x9f,0xa4,0xbb +,0xb9,0xca,0xbc,0x47,0x35,0x36,0x36,0x47,0x25,0x1d,0x1c,0x15,0x15,0x13,0x1a,0x28,0x35,0x44,0x28,0x2e,0x49,0x50,0xb2,0xa2,0x9a,0x96,0x98,0x97,0x98,0x96,0x9b,0xa5 +,0x9e,0xb6,0xbf,0xc9,0xd9,0xd2,0x3e,0x3a,0x27,0x20,0x1a,0x1c,0x1e,0x1e,0x1e,0x1b,0x1a,0x1e,0x24,0x34,0x3e,0x7c,0xb1,0xc0,0xaf,0xa6,0x9f,0x9c,0x9c,0x9c,0x9b,0x9b +,0xa1,0xb1,0xa8,0xab,0x64,0x4e,0x2e,0x37,0x4f,0x49,0x5a,0x45,0x3d,0x26,0x26,0x20,0x1d,0x1f,0x1e,0x1d,0x22,0x33,0x2a,0x2f,0x3c,0xec,0xc0,0xb2,0xae,0xaf,0x9b,0x98 +,0x9d,0x9d,0xa7,0xa8,0xa7,0xad,0xb7,0xc3,0xb0,0xfa,0x4e,0x4e,0x4b,0x55,0x3f,0x2d,0x37,0x2c,0x1d,0x1d,0x18,0x1e,0x25,0x27,0x22,0x25,0xf0,0x3b,0x44,0xc0,0xbe,0xab +,0xae,0xac,0xa2,0x9b,0x96,0x9d,0x9d,0x9c,0xa8,0xae,0xbd,0xd1,0xb6,0xb6,0x5f,0x3e,0x39,0x32,0x28,0x20,0x1a,0x1b,0x19,0x14,0x15,0x1d,0x28,0x24,0x30,0x2c,0x3e,0xb4 +,0xb2,0x9f,0x9b,0x93,0x92,0x97,0x96,0x9d,0x9c,0x9d,0xb4,0xb1,0xc3,0x4c,0x3f,0x2c,0x41,0x2e,0x32,0x2a,0x1e,0x2c,0x1b,0x1d,0x1b,0x19,0x21,0x1f,0x2d,0x28,0x2d,0xba +,0x52,0xc6,0xac,0xa6,0x9d,0x9d,0x98,0x98,0x97,0x97,0x9e,0xa0,0xa8,0xbe,0xaf,0xdf,0x69,0xcc,0x3f,0x2f,0x25,0x1f,0x1b,0x1b,0x19,0x19,0x1a,0x1b,0x1f,0x23,0x2d,0x33 +,0x3d,0xcf,0xf2,0xc4,0xa5,0x9d,0x9c,0x9b,0x93,0x95,0x9a,0x9d,0xa5,0x9f,0xaf,0xc4,0x6f,0x6f,0x3b,0x34,0x29,0x26,0x39,0x29,0x26,0x23,0x2d,0x2b,0x23,0x1d,0x1c,0x2d +,0x2e,0x2d,0x23,0x38,0xb4,0x3a,0xb7,0xae,0x9c,0x9c,0xa0,0x9f,0x9c,0x94,0xa2,0x9e,0xac,0xac,0xba,0xe6,0x3f,0x4e,0x5f,0x2f,0x2c,0x24,0x31,0x28,0x24,0x20,0x2a,0x29 +,0x20,0x1c,0x1f,0x2f,0x2f,0x5e,0x3a,0x46,0xc1,0xb5,0xac,0xa7,0xa2,0xa0,0xa1,0x9d,0xa6,0xa8,0x9f,0xb0,0xa8,0xac,0xb4,0xf8,0x42,0x3d,0x33,0x52,0x4c,0x31,0x28,0x23 +,0x1f,0x1d,0x18,0x1c,0x28,0x2a,0x1e,0x21,0x37,0x4f,0x63,0xd6,0xa8,0xa4,0x9e,0xa1,0xa1,0x96,0x97,0x98,0x9d,0xa8,0xa5,0xb4,0xdb,0x3a,0x49,0x6d,0x2d,0x27,0x1e,0x27 +,0x24,0x1b,0x1d,0x1f,0x1e,0x15,0x1a,0x24,0x29,0x3f,0xde,0x6e,0xd7,0xac,0xaa,0xa2,0x9d,0x98,0x96,0x97,0x9b,0x9d,0x97,0xa3,0xae,0xc2,0xd6,0x73,0x34,0x2e,0x30,0x31 +,0x2a,0x26,0x1f,0x1c,0x18,0x19,0x18,0x17,0x20,0x39,0x29,0x2d,0xfd,0xe7,0xb5,0xb0,0xa6,0x9e,0x97,0x9b,0x9c,0x96,0x99,0x98,0x9b,0xa7,0xb0,0xb0,0x62,0x36,0x28,0x31 +,0x3a,0x23,0x20,0x20,0x2d,0x20,0x16,0x1b,0x24,0x21,0x1c,0x22,0x2f,0x4d,0xd1,0x3f,0xc8,0xa9,0xaa,0xaa,0xa2,0x9a,0x97,0x94,0x9c,0x9c,0x9a,0xa3,0xbd,0xef,0xd3,0xca +,0x47,0x2c,0x2b,0x32,0x2b,0x20,0x28,0x25,0x23,0x1f,0x19,0x1b,0x23,0x33,0x34,0x2c,0x41,0x3b,0xdd,0xba,0xaf,0x9d,0x9a,0x9b,0xa1,0x9c,0x9b,0x9e,0x9d,0xa3,0xa8,0xa9 +,0xc9,0x4e,0x51,0x48,0x4a,0x46,0x2b,0x27,0x27,0x20,0x1d,0x1b,0x1b,0x1c,0x23,0x20,0x1f,0x2d,0x3b,0x36,0x4e,0xce,0xb5,0xa5,0xa5,0x9e,0x99,0x91,0x95,0x9b,0x98,0x9d +,0xa3,0xaf,0xd8,0xbf,0xbe,0xee,0x2c,0x27,0x2b,0x1e,0x1d,0x1b,0x1a,0x1e,0x1b,0x18,0x1f,0x24,0x28,0x2d,0x3b,0x4b,0xcb,0xbe,0xbf,0xa6,0x9d,0x98,0x9a,0x9b,0x9c,0x99 +,0x9a,0xa0,0xa3,0xab,0xae,0xed,0x40,0x35,0x2d,0x3b,0x2f,0x28,0x29,0x21,0x1a,0x19,0x1a,0x1b,0x20,0x22,0x1f,0x2d,0x4d,0x4d,0xdc,0xba,0xb2,0xa6,0xa5,0x9e,0x9c,0x98 +,0x91,0x97,0x9a,0xa2,0xa9,0xb2,0xd2,0xdd,0x52,0x51,0x31,0x27,0x26,0x20,0x26,0x1f,0x1d,0x21,0x1f,0x1d,0x1f,0x23,0x27,0x4b,0x4e,0x3b,0x6d,0xb1,0xb2,0xb9,0xa7,0x9f +,0x9d,0x9d,0x9d,0x9a,0x9a,0x9c,0xa6,0xae,0xb4,0xda,0x3d,0x37,0x30,0x36,0x3e,0x27,0x26,0x28,0x26,0x1e,0x18,0x1b,0x21,0x28,0x23,0x2b,0xe0,0x45,0x48,0xd6,0xbf,0xab +,0xa9,0xa4,0xa1,0x9c,0x98,0x99,0x9c,0x9f,0xa5,0xab,0xc6,0x4c,0xd2,0xe8,0x49,0x34,0x32,0x30,0x26,0x26,0x23,0x29,0x26,0x1f,0x1b,0x1f,0x23,0x24,0x41,0x3c,0x41,0x66 +,0xc6,0xc0,0xb4,0xa8,0xa4,0x9e,0x9b,0x9b,0x99,0x9b,0x9f,0xa0,0xa6,0xb1,0xc9,0x4d,0x48,0x38,0x3d,0x3b,0x2a,0x24,0x1e,0x1f,0x1e,0x1c,0x1b,0x1e,0x29,0x23,0x21,0x35 +,0x35,0x55,0xcd,0xbd,0xa7,0xa5,0xa2,0x9f,0x9b,0x97,0x98,0x9b,0x9f,0xa2,0xa1,0xad,0xc1,0xd5,0xd3,0x44,0x2a,0x24,0x29,0x2d,0x23,0x1e,0x21,0x24,0x1e,0x17,0x1b,0x22 +,0x23,0x31,0x32,0x43,0xba,0xb4,0xb2,0xac,0xa0,0x9d,0x9c,0x9c,0x9a,0x95,0x98,0xa4,0xa9,0xa6,0xad,0xce,0x3a,0x3d,0x2f,0x2d,0x27,0x22,0x27,0x20,0x20,0x1c,0x1d,0x1f +,0x1f,0x28,0x24,0x2a,0x44,0x3a,0x46,0xc3,0xac,0xa4,0xa7,0xa6,0xa3,0x9f,0x9b,0x9b,0x9a,0x9d,0xa1,0xa4,0xb8,0xd4,0xe7,0x59,0x42,0x2e,0x2c,0x2c,0x28,0x25,0x21,0x28 +,0x26,0x1e,0x1b,0x1d,0x23,0x2c,0x37,0x3f,0x48,0xce,0xbc,0xca,0xb2,0xa4,0x9e,0x9e,0x9e,0x9d,0x9c,0x9e,0xa8,0xa8,0xa7,0xac,0xca,0x51,0x54,0x3b,0x46,0x30,0x27,0x2b +,0x2b,0x26,0x1f,0x21,0x24,0x22,0x21,0x20,0x27,0x2f,0x32,0x35,0xe7,0xb6,0xae,0xaf,0xab,0xa4,0xa4,0x9c,0x9d,0x9e,0x9b,0x9d,0x9f,0xad,0xb3,0xb9,0xcd,0x5e,0x3b,0x3a +,0x2e,0x25,0x24,0x22,0x22,0x22,0x1d,0x1d,0x1f,0x1f,0x29,0x2a,0x30,0x3c,0x53,0xcd,0xcf,0xb3,0xa3,0x9f,0x9f,0x9e,0x9c,0x9e,0xa3,0x9f,0xa1,0xa0,0xa7,0xba,0xc2,0xe8 +,0x47,0x3a,0x2e,0x2a,0x29,0x28,0x24,0x21,0x24,0x25,0x1e,0x1d,0x1f,0x29,0x27,0x2b,0x3e,0xd5,0xb9,0xb5,0xae,0xa7,0xa3,0xa3,0x9e,0x9d,0x9d,0x9e,0x9f,0xa3,0xae,0xaf +,0xbb,0xcf,0x7c,0x41,0x38,0x2a,0x25,0x21,0x28,0x27,0x24,0x22,0x25,0x28,0x25,0x2e,0x2e,0x34,0x32,0x40,0x6d,0xe4,0xb4,0xac,0xa7,0xa6,0xa9,0xa7,0xa6,0xa8,0xa7,0xa0 +,0xa3,0xaa,0xaf,0xb4,0xc5,0x5e,0x5c,0x3c,0x38,0x2f,0x2d,0x2e,0x27,0x29,0x2c,0x29,0x26,0x22,0x28,0x2a,0x26,0x32,0x3d,0x69,0xdd,0xca,0xb1,0xb0,0xaa,0xa3,0xa5,0xa6 +,0xa7,0xa6,0xaa,0xac,0xa6,0xa8,0xaf,0xbd,0xcc,0xd0,0x42,0x2d,0x33,0x35,0x2f,0x2c,0x2c,0x2e,0x28,0x28,0x2c,0x26,0x27,0x2b,0x33,0x39,0x4a,0xbf,0xba,0xbe,0xb8,0xb5 +,0xae,0xb0,0xb5,0xa8,0xa4,0xa2,0xa9,0xab,0xad,0xb8,0xb8,0xbe,0xeb,0x63,0x4d,0x43,0x38,0x2f,0x37,0x30,0x2b,0x28,0x2c,0x2d,0x26,0x27,0x2e,0x3e,0x45,0x36,0x46,0xce +,0xc8,0xbf,0xba,0xb8,0xb3,0xaf,0xb1,0xb4,0xac,0xa5,0xaa,0xaf,0xac,0xae,0xc2,0x69,0x62,0xc9,0xd5,0x46,0x3c,0x40,0x3c,0x2e,0x2d,0x2e,0x2a,0x2c,0x28,0x2e,0x34,0x3a +,0x60,0x55,0x72,0x7a,0xef,0x63,0x6a,0xc2,0xb6,0xb3,0xb2,0xb6,0xb4,0xb3,0xb7,0xae,0xb0,0xb6,0xb9,0xc4,0xc4,0x64,0x5b,0xdf,0x5c,0x4b,0x3f,0x41,0x39,0x2f,0x31,0x34 +,0x39,0x34,0x34,0x4b,0x5c,0x5b,0x63,0x51,0x41,0x49,0x49,0x51,0x6a,0xc3,0xb3,0xb9,0xb9,0xb7,0xb8,0xbf,0xe1,0xbf,0xb6,0xbd,0xbf,0xc9,0xbc,0xcf,0x54,0x5e,0x4e,0x43 +,0x38,0x34,0x41,0x41,0x49,0x67,0x5b,0x5f,0x53,0x48,0x45,0x44,0x4a,0x45,0x49,0x59,0x4b,0x69,0x67,0x55,0xd0,0xc6,0xe4,0xd8,0xcd,0xc2,0xc9,0xc6,0xb8,0xb8,0xbd,0xc5 +,0xce,0xe6,0x47,0x44,0x50,0x74,0xce,0x58,0xd3,0xde,0x6f,0xec,0x57,0x41,0x6f,0xce,0x40,0x4f,0x5a,0xd4,0xdc,0x48,0x4b,0x46,0x39,0x34,0x4f,0x65,0x6e,0xe4,0x50,0xd9 +,0xce,0xdc,0xcf,0xd5,0xc7,0xcf,0xcb,0xc3,0xc3,0xb4,0xae,0xb0,0xbd,0xcb,0x64,0x5a,0x42,0xef,0xdf,0x67,0xe6,0x38,0x7e,0x48,0x3b,0x45,0x3f,0x4d,0x49,0x3d,0x3f,0x53 +,0xef,0xc9,0xda,0xd3,0x51,0x47,0x41,0x49,0xcf,0xbf,0xc9,0xc9,0xbf,0xb7,0xb1,0xbb,0xbb,0xbe,0xbc,0xca,0xdf,0xd5,0xbe,0xbb,0xc6,0x57,0x47,0x3f,0x38,0x37,0x3a,0xee +,0x42,0x37,0x34,0x3a,0x4b,0x3b,0x3c,0x4e,0x56,0x44,0x42,0x4b,0xce,0xbd,0xb4,0xb9,0xbe,0xb9,0xc0,0xbc,0xc5,0xc2,0xb6,0xbd,0xd6,0xc6,0xbe,0xc4,0xcb,0x76,0xe4,0x5d +,0x47,0x39,0x43,0x4b,0x4a,0x47,0x3d,0x40,0x3c,0x3d,0x3b,0x37,0x38,0x3f,0x3f,0x51,0x5a,0xd8,0xd6,0xcc,0xb8,0xb6,0xbf,0xc4,0xbc,0xb5,0xb3,0xc4,0xbf,0xc8,0xcf,0xe2 +,0xdf,0xcf,0x4f,0x56,0x4e,0x51,0x63,0x4f,0x3f,0x49,0x4c,0x57,0x52,0x32,0x40,0x3b,0x3c,0x3d,0x55,0x5f,0x5d,0xd8,0x68,0xc1,0xdf,0x79,0xd7,0xbf,0xc3,0xc5,0xd8,0xd5 +,0xbb,0xc1,0xc2,0x7b,0xcd,0xcc,0x54,0x6b,0xf1,0xd7,0xdb,0x6a,0x5f,0x64,0x6a,0x40,0x38,0x4b,0x5c,0x66,0x51,0x3f,0x5d,0xc7,0xe1,0x56,0x67,0x50,0x6b,0x40,0x5a,0xc7 +,0xc7,0xdf,0x49,0xdd,0xc3,0xd2,0x4f,0xdc,0xcb,0xc6,0xed,0x73,0xcf,0xc1,0xbf,0xdc,0xee,0xd6,0x48,0x44,0x4a,0x76,0xcb,0xeb,0xf3,0x4c,0xd3,0x66,0x49,0x49,0x48,0x48 +,0x52,0x46,0x3b,0x49,0xf4,0x5e,0x3f,0x42,0x73,0x59,0x4f,0xca,0xc3,0xbc,0xc2,0xbd,0xbe,0xb9,0xbe,0xca,0x6c,0xf6,0xcc,0x6c,0xd5,0xc7,0xc8,0xd4,0xdd,0x73,0xd7,0x5f +,0x47,0x43,0x48,0x36,0x43,0x4e,0x46,0x2c,0x42,0x6b,0x41,0x35,0x6d,0x4d,0xca,0x40,0x4d,0xad,0xa6,0x99,0xbf,0xac,0x28,0xb9,0x51,0xa9,0x25,0x49,0x3e,0x03,0x16,0x09 +,0xa3,0xec,0x38,0xbb,0x27,0x8b,0x91,0x97,0xbe,0x9f,0xbe,0xd1,0x8c,0xaf,0x3b,0x9e,0xbe,0x3d,0x9b,0x1b,0x93,0x83,0x8d,0x8c,0x8b,0x9a,0xaf,0x2e,0x0d,0x0e,0x01,0x03 +,0x03,0x0a,0x03,0x05,0x05,0x0c,0x05,0x07,0x1c,0x0e,0x19,0x25,0x2f,0xd1,0xc3,0x5c,0x95,0x9c,0x9c,0x91,0x9f,0x8f,0x8c,0x8a,0x81,0x86,0x83,0x83,0x82,0x84,0x80,0x86 +,0x85,0x85,0x21,0xbd,0x8a,0x87,0x0a,0x11,0x1b,0x06,0x11,0x05,0x02,0x03,0x04,0x01,0x20,0x0b,0x0a,0x01,0x04,0xa9,0x14,0x0b,0x09,0x24,0xa2,0x9d,0x9d,0xab,0x11,0x19 +,0xab,0x9b,0x83,0x8e,0x97,0xaf,0x8e,0x8a,0x86,0x83,0x80,0x8f,0x9c,0x94,0x9c,0x87,0xd4,0x26,0x1b,0xd8,0xd4,0x2f,0x62,0xdf,0x2f,0xdd,0x3b,0xc4,0x9a,0x40,0x1c,0x3c +,0x1f,0x0d,0x17,0x09,0x07,0x04,0x05,0x07,0x08,0x0a,0x06,0x16,0x16,0x1d,0x1d,0x16,0x3e,0xaf,0xb2,0x3c,0xcf,0x92,0x8f,0xa1,0x8b,0x87,0x84,0x84,0x87,0x88,0x80,0x8c +,0x92,0x8b,0x81,0x91,0x93,0x8e,0x29,0x8d,0x2a,0x26,0xa1,0xc6,0xdc,0x05,0x0f,0x25,0x06,0x06,0x02,0x01,0x01,0x06,0x04,0x1f,0x17,0x05,0x04,0x10,0x2f,0xa1,0xa9,0x9c +,0x87,0xa7,0x87,0x9d,0xa8,0x88,0x87,0x82,0x8f,0x9d,0x8c,0x8d,0x8d,0x91,0x83,0x94,0xfd,0xac,0x4f,0x53,0x24,0x44,0x44,0x20,0x17,0x9c,0x98,0x5e,0xa4,0x8d,0xab,0x30 +,0xdc,0xcf,0x3f,0x0b,0x0c,0x2d,0x1b,0x21,0x0f,0x06,0x06,0x9d,0xab,0xcd,0x9c,0x22,0x18,0x03,0x91,0xa2,0x9d,0xa2,0x02,0x15,0xdc,0x17,0x00,0xa9,0x94,0x14,0x10,0x1b +,0x80,0x96,0x12,0x27,0x0c,0x2b,0x8b,0x92,0x1f,0x22,0x15,0x24,0x10,0x2a,0xab,0xad,0x23,0x2c,0x2b,0x0a,0x10,0x25,0x32,0x0f,0xda,0x0f,0x14,0x08,0x1e,0x8e,0xd3,0x1d +,0x59,0x8e,0x8f,0x88,0x87,0x8a,0x87,0x8d,0x86,0x80,0x82,0x84,0x87,0x83,0xb4,0x9f,0x8e,0x80,0x8b,0x41,0x2f,0x8f,0xfa,0x20,0xa3,0xbf,0x25,0x03,0x1b,0x26,0x89,0x13 +,0x05,0x30,0x9d,0x14,0x46,0x8e,0x13,0x0b,0x0a,0x44,0x05,0x1d,0x35,0x00,0x07,0x02,0x0b,0x19,0x1d,0xa3,0x00,0x09,0x09,0x1d,0x1b,0x1b,0xb5,0x06,0x20,0x00,0x43,0x8b +,0x8f,0x9a,0x2f,0xb7,0x8a,0x8b,0x88,0x80,0x80,0x8c,0xab,0x81,0x85,0x8a,0x8d,0x87,0x88,0x8c,0x8d,0x25,0x1e,0x94,0x80,0x58,0x16,0x18,0x10,0x14,0x0e,0x16,0x00,0x0c +,0x08,0x02,0x0a,0x05,0x04,0x00,0x15,0x16,0x02,0x18,0x8c,0x40,0x20,0x9d,0x80,0x8a,0x8b,0x89,0xa7,0x8b,0x83,0x80,0x80,0x81,0x9f,0x8b,0x85,0x84,0x80,0x9d,0x8e,0x2d +,0xa8,0x89,0x49,0x51,0x0c,0x27,0x06,0x0d,0x1f,0x00,0x1f,0x01,0x19,0x60,0x0f,0x07,0x00,0x11,0x06,0x00,0x00,0x0d,0x0b,0x01,0x03,0x13,0x0d,0x05,0x0b,0x04,0x33,0x29 +,0x0b,0x05,0x36,0xad,0x43,0x21,0x2b,0x29,0x40,0x96,0x3f,0x8e,0x8a,0x86,0x88,0x81,0x80,0x84,0x80,0x80,0x80,0x8a,0x8d,0x80,0x84,0x89,0x84,0x85,0x87,0x9e,0xe6,0x23 +,0xb2,0x94,0xac,0x1b,0x2f,0x09,0x19,0xae,0xae,0x0f,0x02,0x22,0x0a,0x0f,0x00,0x1f,0x1a,0x08,0x91,0x1c,0x0b,0x12,0x0d,0x19,0x0e,0x1f,0x19,0x11,0xae,0xd4,0x1a,0x12 +,0x9a,0xb3,0x1f,0x39,0x31,0xac,0x1a,0x37,0xee,0xaa,0x28,0xaf,0x34,0x45,0xb7,0x4a,0xaf,0x8e,0x80,0x8d,0x8c,0x87,0x98,0x9b,0x85,0x9c,0x95,0x34,0xb3,0x20,0x08,0xad +,0x9f,0x1b,0x0d,0x1c,0xb9,0x0e,0x11,0x2c,0x15,0x15,0x04,0x10,0x0f,0x0e,0x05,0x08,0x0c,0x05,0x10,0x08,0x0c,0x8b,0x99,0x95,0x81,0x90,0x86,0x87,0x84,0x80,0x82,0x80 +,0x8a,0x87,0x80,0x85,0x81,0x81,0x85,0x90,0xa9,0x98,0x8c,0xaf,0xb7,0x25,0x16,0x15,0x09,0x0e,0x05,0x08,0x03,0x03,0x07,0x03,0x02,0x04,0x11,0x03,0x08,0x05,0x0b,0x00 +,0x04,0x04,0x0d,0x0b,0x03,0x1c,0x22,0x18,0x0c,0xb8,0x09,0x3a,0x1f,0x23,0xa6,0xa6,0xb6,0xa1,0xa6,0x95,0x87,0x47,0x8b,0x92,0x88,0x8e,0x85,0x86,0x8d,0x80,0x83,0x80 +,0x82,0x84,0x87,0x8b,0x86,0x8c,0xa5,0x8c,0x97,0x91,0xa4,0x16,0xb2,0x1f,0x1e,0x1b,0x1b,0x09,0x0e,0x17,0x04,0x0a,0x0e,0x08,0x03,0x07,0x01,0x05,0x08,0x2b,0x0f,0xbe +,0x93,0xae,0xb7,0x27,0x9d,0x1e,0xd4,0x9d,0xae,0xa4,0xae,0xa8,0xe0,0xa9,0x8e,0xd1,0x38,0x60,0x2c,0xad,0x38,0x3e,0x5a,0xbf,0x1b,0xa4,0x29,0x40,0x18,0x0f,0x46,0x1d +,0x90,0x13,0x98,0x8e,0x1b,0xcc,0x3c,0x2d,0x2e,0x22,0xa8,0xae,0x1d,0x8f,0x8c,0x91,0x9f,0xad,0xbb,0x31,0xb6,0x2c,0x2e,0x1f,0x22,0x18,0x17,0x0e,0x0b,0x14,0x1d,0x17 +,0x0e,0x24,0x97,0x8c,0x96,0x81,0x8b,0x8b,0x82,0x81,0x88,0x8f,0x86,0x85,0x87,0x88,0x82,0x8a,0x89,0x86,0x87,0x9d,0x99,0x9d,0x3d,0x94,0x28,0x13,0x14,0x04,0x08,0x07 +,0x04,0x05,0x00,0x02,0x01,0x08,0x02,0x05,0x1f,0x07,0x05,0x07,0x0b,0x05,0x06,0x18,0x0b,0x05,0xb2,0x1e,0x15,0xa8,0x33,0xa8,0x3d,0x62,0x9e,0x22,0x91,0x91,0x97,0x8c +,0x9c,0x83,0x8f,0x92,0x8e,0x8a,0x9f,0x85,0x8d,0xa5,0x80,0x8e,0x8a,0x8c,0xae,0x9f,0x5b,0xaf,0x92,0x3b,0xa0,0x9c,0x8e,0x75,0x40,0x82,0xbf,0x22,0x98,0x1e,0x20,0xbc +,0x29,0x3c,0x2a,0x31,0x08,0x28,0x23,0x0d,0x16,0x18,0x8d,0x1c,0x3b,0x86,0x65,0x9e,0xa9,0x21,0x28,0x32,0x2c,0x13,0x0d,0x44,0x21,0x0e,0x2b,0x0f,0x12,0x0a,0x0c,0x11 +,0x0b,0x10,0x1a,0x16,0x19,0x28,0x0a,0x16,0x1c,0x0c,0x0d,0x12,0x9d,0x2e,0x16,0x83,0x95,0x57,0x95,0x9d,0xa6,0xd8,0x92,0x8c,0xa4,0x88,0x8c,0x91,0x89,0x9d,0x8e,0xae +,0xcf,0xa6,0x11,0x3b,0x50,0x1e,0x37,0x1f,0x27,0x17,0x25,0xc7,0x52,0x14,0xa6,0x84,0x45,0x8b,0x81,0x8c,0x8a,0x8d,0x86,0xab,0x96,0x81,0x93,0x8d,0x83,0x8a,0x89,0x8d +,0x88,0x90,0xb7,0x92,0xa5,0x28,0xd8,0x1f,0x0e,0x12,0x04,0x05,0x05,0x03,0x02,0x01,0x02,0x2d,0x0a,0x0a,0xe1,0x13,0x0e,0x0e,0x1b,0x08,0x07,0x0f,0x17,0x04,0x33,0x20 +,0x0c,0xdd,0x16,0x23,0x1e,0x39,0x58,0x1c,0x99,0xc6,0xef,0x94,0x9b,0xa9,0x4b,0xa1,0x38,0xb9,0x2f,0x8d,0x8e,0x31,0x84,0x8c,0xae,0x8c,0x8c,0x8c,0x99,0x96,0x85,0x94 +,0x83,0x85,0x88,0x87,0x8c,0x89,0x98,0x9b,0x8c,0xd9,0xae,0xa9,0x18,0x24,0x28,0x1d,0x15,0x1d,0x09,0x13,0x08,0x28,0x8f,0x0d,0x9e,0x91,0x2e,0x2e,0x27,0x3d,0x0c,0x0f +,0x31,0x09,0x0a,0xc4,0x17,0x19,0x3a,0x1c,0x15,0x19,0x4c,0x19,0x1c,0x2e,0x1f,0x15,0x1b,0x1b,0x08,0x15,0x0e,0x0a,0x08,0x09,0x93,0x12,0x41,0x87,0xfe,0x9d,0x99,0x96 +,0x9c,0x9f,0x8d,0x94,0xa8,0x87,0x93,0x8c,0x8e,0x95,0x93,0xb5,0x9f,0xc2,0xdd,0xa3,0xb1,0x4a,0x4b,0x2d,0x2f,0x1f,0x4d,0x1f,0x19,0x0e,0x9f,0xaf,0x15,0x85,0xa0,0x4b +,0x9a,0x9a,0x9c,0xaf,0x8c,0x87,0x97,0x85,0x82,0x89,0x82,0x81,0x83,0x87,0x86,0x88,0x99,0x98,0x95,0x30,0x2d,0x1a,0x0c,0x04,0x05,0x04,0x02,0x00,0x0d,0x12,0x00,0x23 +,0x16,0x04,0x0c,0x08,0x07,0x02,0x08,0x0d,0x00,0x0c,0x0e,0x03,0x1b,0x17,0x0f,0x17,0x16,0x2d,0x20,0x29,0x9e,0xb8,0xb1,0x9e,0xa9,0xbb,0xa9,0xaa,0xb8,0xf9,0x99,0x88 +,0x39,0x8a,0x81,0x95,0x88,0x8b,0x8b,0x94,0x8e,0x82,0x8f,0x8b,0x82,0x92,0x88,0x86,0x8b,0x91,0x98,0x94,0x7c,0x52,0xa6,0xd4,0xef,0x33,0x3d,0x1e,0x1e,0x21,0x22,0x14 +,0x1f,0x8c,0x15,0xc7,0x90,0x1f,0x2c,0x23,0x18,0x0b,0x0a,0x2d,0x0f,0x0c,0xbb,0x11,0x19,0x29,0x25,0x20,0x19,0x26,0x15,0x0e,0x1e,0x16,0x0d,0x0f,0x0f,0x0b,0x08,0x0b +,0x0a,0x07,0x0f,0x92,0x1b,0x37,0x88,0xae,0x9a,0x90,0x98,0xa9,0xbb,0x91,0x9d,0xc3,0x87,0x9d,0x9f,0x96,0xa2,0xa9,0xb0,0x9c,0xa3,0xb4,0xa9,0xa9,0xc5,0xb0,0xae,0x54 +,0x20,0x24,0x1b,0x13,0x0e,0x8e,0xc2,0x27,0x83,0xa4,0xab,0x91,0x9a,0xb8,0xe6,0x9e,0xa0,0x3e,0x8a,0x88,0x8e,0x86,0x8e,0x91,0x90,0x95,0x94,0x99,0x8f,0x8d,0x98,0xa0 +,0xdd,0x1b,0x18,0x10,0x05,0x08,0x02,0x4b,0x1a,0x08,0x9e,0x15,0x07,0x19,0x0e,0x08,0x0b,0x1e,0x26,0x0f,0xaa,0x3e,0x10,0x35,0x2d,0x1b,0x40,0x9e,0xa4,0xb4,0x9d,0x9f +,0x2d,0x3e,0x31,0x21,0x14,0x1d,0x11,0x13,0x0f,0x9c,0x9a,0x11,0x8f,0x9d,0x21,0xb1,0x9d,0xb1,0xaa,0x91,0x8c,0xc3,0x96,0x8f,0xb0,0x9a,0x9d,0xb5,0x9c,0x9d,0x9e,0x9b +,0xa9,0xa5,0x2e,0x49,0x2c,0x17,0x10,0x2e,0x17,0x2c,0x24,0x9b,0x97,0x1b,0x85,0x9b,0xbc,0x8d,0x8f,0x9a,0x95,0x8f,0x99,0x2f,0x9e,0xa5,0x14,0xc9,0x3d,0x1c,0x29,0x2c +,0x1d,0x10,0x0f,0x17,0x0b,0x0e,0x15,0x12,0x12,0x27,0x16,0x14,0x0b,0x3a,0xaa,0x0c,0x8d,0x90,0xae,0x91,0x90,0xb5,0x30,0x46,0x2b,0x12,0x21,0x4f,0x11,0x51,0x66,0x1a +,0x2c,0x19,0x14,0x16,0x15,0x2c,0x28,0xfe,0xac,0xb2,0xb1,0x9f,0x46,0x3b,0x37,0x93,0x8d,0xa4,0x80,0x89,0x90,0x86,0x8f,0xa5,0xac,0x9f,0x9c,0xca,0x99,0x95,0x9b,0x9f +,0x9f,0xa4,0x37,0xbe,0xad,0xbd,0xa0,0x99,0x96,0x9f,0xa7,0xf0,0x24,0x3c,0x12,0x0f,0x13,0xa4,0x5f,0x2e,0x94,0x1e,0x0f,0x34,0x12,0x09,0x1b,0x28,0x20,0x16,0xbb,0x30 +,0x17,0xec,0x19,0x1c,0x40,0x26,0xb2,0xa7,0x89,0x8a,0x9b,0xa4,0xc1,0xcf,0x3f,0x17,0x0b,0x0f,0x1d,0xb7,0x05,0x08,0x1c,0x06,0x02,0x05,0x06,0x07,0x0a,0x19,0x1c,0x11 +,0x42,0x2c,0xf8,0xa4,0xb8,0xa0,0x9c,0x90,0x8d,0x96,0x8e,0x98,0x8f,0x90,0x98,0x9a,0x95,0x90,0x9c,0xaa,0x8c,0x8b,0xdf,0x85,0x86,0xa1,0x8b,0x87,0x8e,0x8b,0x86,0x85 +,0x91,0x97,0x8a,0x9d,0x9e,0x8d,0xb3,0xb0,0xa6,0x39,0x1b,0x10,0x0b,0x09,0x0c,0x06,0x04,0x01,0x07,0x09,0x02,0x00,0x12,0x09,0x0b,0x37,0x0b,0x1f,0x8d,0x8b,0x8c,0x8a +,0x84,0x84,0x8b,0x8a,0x9b,0x9b,0x83,0x99,0x37,0x5f,0x10,0x0c,0x02,0x02,0x03,0x03,0x05,0x06,0x06,0x0b,0x11,0x0f,0x09,0x2c,0xa5,0x0d,0x9e,0x96,0xe2,0x95,0x8d,0x96 +,0xa9,0xa5,0x99,0xaf,0xad,0x8f,0x9a,0x8e,0x88,0x90,0x94,0x99,0xa7,0x9d,0xaa,0xaa,0x9b,0x98,0x8e,0x92,0x90,0x90,0x99,0x4b,0x95,0x89,0x31,0x90,0x8a,0x76,0x9e,0x9d +,0x2f,0x1d,0x19,0x23,0x10,0x07,0x16,0x19,0x1f,0x33,0x0f,0x13,0x13,0x16,0x11,0x06,0x13,0xd7,0x9d,0x90,0x8d,0x93,0x8f,0x83,0x97,0x97,0x82,0x9b,0x8a,0x84,0x40,0x3f +,0x3b,0x09,0x04,0x03,0x03,0x04,0x01,0x0c,0x10,0x0b,0x14,0x0d,0x0d,0x0d,0x0a,0x0f,0x0f,0x1c,0x4a,0x2c,0x48,0x26,0x1d,0x19,0x22,0x1e,0x30,0x86,0xab,0x99,0x82,0xb1 +,0x47,0xa1,0x4d,0x4e,0x5c,0x9a,0x8f,0x9c,0x89,0x86,0x8e,0x8b,0x86,0x93,0x8e,0x8c,0x8c,0x90,0x94,0x8e,0x99,0xb0,0xac,0x4e,0x1f,0x2b,0x33,0x09,0x35,0x95,0x0f,0x48 +,0x15,0x02,0x15,0x0e,0x0a,0x0f,0x11,0xa3,0x96,0xa8,0x8e,0x92,0x8b,0x80,0x86,0x88,0x86,0x86,0x86,0x90,0x9d,0xac,0x2d,0x17,0x0c,0x05,0x07,0x01,0x05,0x05,0x05,0x19 +,0x04,0x06,0x1a,0x04,0x08,0x1a,0x0e,0x1d,0x2a,0x40,0x51,0x1f,0xcf,0xc5,0x28,0xbe,0xa7,0xb4,0xa8,0x9e,0x9d,0xa5,0x4e,0x6d,0xc6,0x2d,0xaf,0x9d,0x98,0x97,0x8f,0x9e +,0xa0,0xa7,0x98,0x8f,0xae,0x89,0x89,0x94,0x8c,0x89,0x8e,0x98,0xba,0xa4,0xb6,0xe6,0xbd,0x24,0x32,0xa5,0xb5,0x17,0x0f,0x0d,0x1a,0x18,0x0b,0x0e,0x1d,0x4c,0x99,0x9c +,0xae,0x98,0x89,0x84,0x8c,0x8e,0x88,0x87,0x8f,0x8f,0x95,0x9a,0xab,0x28,0x2d,0x14,0x09,0x0b,0x08,0x04,0x08,0x05,0x03,0x03,0x07,0x0a,0x0b,0x16,0x1e,0x25,0x2e,0x35 +,0x2a,0x1f,0x1f,0x28,0x1f,0x2b,0xce,0xaf,0xac,0x9d,0x9c,0xab,0xae,0xd5,0x3a,0x32,0xe2,0xaf,0x9c,0x97,0x97,0x90,0x8f,0x99,0x9a,0x99,0x9f,0x98,0x98,0x97,0x91,0x8d +,0x8d,0x9c,0xbf,0xac,0x9f,0x63,0x40,0x53,0x37,0xbb,0xc4,0x17,0x0c,0x0d,0x14,0x13,0x0d,0x0c,0x13,0x30,0xac,0xab,0xc7,0xa5,0x8f,0x8a,0x8d,0x89,0x84,0x82,0x84,0x82 +,0x85,0x8d,0x9c,0xc2,0x1c,0x0c,0x1d,0x0f,0x05,0x10,0x0d,0x06,0x03,0x03,0x04,0x02,0x04,0x0b,0x0f,0x12,0x29,0x3a,0x22,0x1a,0x25,0x19,0x11,0x29,0x3a,0x3c,0xb0,0xa7 +,0xb7,0xb4,0xbd,0xee,0x3b,0x37,0xb1,0xae,0x9e,0x97,0x9f,0x9d,0x98,0x9e,0xad,0xa2,0x94,0x91,0x91,0x8f,0x91,0x8f,0x91,0x9f,0xb7,0xa2,0x91,0x97,0xab,0xa7,0xaa,0xd3 +,0x2e,0x19,0x0c,0x0e,0x1e,0x20,0x10,0x0f,0x1e,0x25,0x27,0x24,0x4e,0xc9,0xa4,0x8d,0x89,0x87,0x83,0x82,0x85,0x86,0x88,0x8b,0x95,0x9e,0xa7,0xdd,0x29,0x1c,0x0d,0x08 +,0x03,0x03,0x04,0x02,0x04,0x06,0x0a,0x0f,0x18,0x14,0x15,0x17,0x1a,0x17,0x1b,0x27,0x2b,0x4e,0xb0,0xcd,0xc5,0x42,0x2d,0x59,0x4a,0xba,0xab,0xac,0x9f,0x95,0x98,0xa9 +,0xa9,0xa0,0xb2,0xb1,0xa8,0x99,0x8e,0x8b,0x8e,0x99,0x90,0x8e,0x9c,0xa5,0x9a,0x93,0x8d,0x8f,0xa1,0xcc,0xbd,0xc4,0x1d,0x0e,0x11,0x1d,0x25,0x23,0x12,0x0f,0x12,0x11 +,0x0f,0x10,0x25,0xd1,0xaa,0x8f,0x89,0x8c,0x89,0x87,0x87,0x88,0x88,0x88,0x89,0x8a,0x8c,0xa1,0x39,0x1b,0x0e,0x08,0x03,0x04,0x04,0x06,0x08,0x08,0x08,0x08,0x08,0x0d +,0x0a,0x0c,0x19,0x21,0x2d,0x4c,0x49,0x3f,0x3a,0x2c,0x44,0x2f,0x32,0xb0,0x9e,0xa1,0x9a,0x9a,0xa5,0xb2,0xb5,0xc8,0xd2,0xaa,0xa0,0xa7,0x9d,0x8e,0x94,0xa9,0xaa,0xa0 +,0x9d,0x9a,0x9b,0xa0,0x9a,0x8c,0x8f,0xaa,0x53,0x50,0xcf,0x67,0x40,0x26,0x29,0xbf,0x5d,0x18,0x10,0x0f,0x0d,0x0d,0x11,0x1a,0x26,0xc7,0xa2,0x9f,0x9a,0x8e,0x8e,0x8b +,0x85,0x83,0x83,0x83,0x83,0x87,0x91,0x9e,0xc5,0x1d,0x14,0x0e,0x0c,0x0a,0x0b,0x09,0x06,0x05,0x06,0x06,0x06,0x0a,0x0d,0x0f,0x1b,0x25,0x1b,0x1b,0x1a,0x1d,0x1d,0x1f +,0x2d,0x4d,0xc1,0xa0,0x9c,0xa7,0xb3,0xab,0xa4,0xcc,0x69,0xac,0x9a,0x9e,0x9a,0x99,0x9a,0x96,0x9c,0xa7,0xaf,0x9b,0x8e,0x8f,0x93,0x90,0x8f,0x8f,0x9b,0xac,0x4c,0xb8 +,0x9f,0xc7,0x3c,0x6f,0xbf,0x30,0x1c,0x15,0x12,0x0c,0x0c,0x0f,0x12,0x18,0x29,0x6c,0xc5,0xb6,0xa3,0x96,0x95,0x8a,0x85,0x85,0x83,0x82,0x83,0x86,0x90,0x97,0xa6,0x30 +,0x22,0x19,0x10,0x0d,0x0d,0x08,0x05,0x03,0x04,0x04,0x04,0x07,0x0b,0x0e,0x18,0x1f,0x19,0x15,0x15,0x19,0x1b,0x2a,0x37,0x49,0xab,0x9d,0xa4,0xb3,0xa8,0xaf,0x51,0xda +,0xaa,0x9d,0x97,0x97,0x9a,0x9a,0xa0,0xb5,0xc3,0xb8,0xaa,0x9e,0x97,0x91,0x98,0x9d,0x92,0xa1,0xef,0xc4,0xad,0x9d,0x9d,0x99,0x94,0x9c,0xa9,0xbf,0x37,0x2d,0x2a,0x46 +,0xcd,0xba,0xab,0xc0,0xd9,0x3c,0x23,0x2e,0x21,0x1c,0x2e,0x33,0xbf,0x6c,0x2c,0x37,0x21,0x1d,0x1c,0x19,0x2a,0x29,0x28,0x32,0x2d,0x2c,0x27,0x21,0x2f,0x39,0x25,0x27 +,0x34,0xbc,0xb9,0x5c,0xc9,0xbf,0x51,0x3f,0x33,0x3c,0x67,0x37,0x4c,0xb8,0xbc,0xcc,0x35,0x30,0x32,0x6a,0xaf,0x27,0x38,0xbc,0xc8,0xb5,0x34,0xbd,0xbf,0x2a,0x2d,0x54 +,0x67,0x4f,0xa4,0xc2,0xc5,0x41,0x2c,0xbd,0xda,0xb5,0x9f,0x9b,0x98,0x98,0x9e,0x98,0x9e,0x9d,0x94,0x98,0x91,0x8f,0x95,0x97,0x9a,0xa1,0xad,0xab,0xad,0xbe,0xd4,0x4a +,0x38,0x29,0x23,0x22,0x1a,0x1b,0x1e,0x17,0x19,0x19,0x15,0x16,0x16,0x17,0x17,0x1a,0x1e,0x1a,0x1d,0x22,0x23,0x28,0x39,0x5f,0x5c,0xc4,0xb7,0xc1,0xd6,0xcc,0xce,0xce +,0xc3,0xc2,0xfe,0x3d,0x3c,0x2e,0x23,0x28,0x33,0x30,0x3b,0x6a,0x53,0x42,0x4c,0xd6,0xde,0xd4,0xb0,0xb0,0xb6,0xab,0xb0,0x4e,0x41,0x51,0x49,0xc4,0xbc,0xb1,0xa6,0xaa +,0xa9,0x9e,0x9b,0x95,0x92,0x93,0x8f,0x8e,0x90,0x8f,0x8f,0x8d,0x90,0x93,0x95,0x8f,0x89,0xda,0x25,0x1b,0xa5,0xa5,0x10,0x0e,0x10,0x3f,0x86,0x89,0x00,0x4c,0xa4,0x0c +,0xf8,0x0f,0x1a,0x5e,0x20,0x0b,0x00,0x03,0x00,0x08,0x07,0x03,0x0b,0x01,0x02,0x00,0x00,0x09,0x19,0x03,0x0b,0x0d,0x16,0xc2,0x0f,0x0a,0x27,0x9a,0x90,0xa5,0x35,0x8a +,0x80,0x83,0x88,0x86,0x80,0x80,0x80,0x87,0x86,0x89,0x42,0x99,0x80,0x80,0x80,0x87,0x8b,0x86,0x8b,0x92,0x81,0x80,0x80,0x83,0x9b,0x4a,0x3e,0x1a,0x1d,0x98,0x85,0x9f +,0x0b,0x03,0x05,0x06,0x06,0x0a,0x07,0x08,0x03,0x00,0x01,0x17,0x0b,0x00,0x02,0x04,0x05,0x00,0x01,0x01,0x03,0x01,0x01,0x00,0x03,0x07,0x05,0x00,0x01,0x00,0x01,0x00 +,0xce,0x80,0xd0,0x0d,0x01,0x0e,0x3a,0x23,0x89,0x80,0x81,0x87,0x19,0x2c,0x86,0x84,0x87,0x83,0x80,0x80,0x8b,0x8d,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x85,0x85 +,0x86,0x84,0x82,0x80,0x81,0x80,0x85,0x84,0x82,0x82,0x82,0x81,0x82,0x80,0x84,0x88,0x8a,0xab,0x45,0xb3,0xae,0x12,0x04,0x13,0x80,0xa7,0x01,0x04,0x00,0x0a,0x01,0x09 +,0x1f,0xc7,0x23,0x00,0x00,0x02,0x05,0x05,0x06,0x09,0x05,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x1b,0x98,0x00,0x01,0x00,0x04,0x0e,0x01,0x0d,0x1a,0x1d,0x07,0x00,0x02 +,0x11,0x5d,0x2c,0x13,0x12,0x0f,0x0a,0x05,0x05,0x06,0x2d,0x80,0x8b,0x12,0x05,0x1c,0x8c,0xa6,0x9b,0x84,0x81,0x82,0x19,0x03,0x9f,0x80,0x80,0x80,0x80,0x80,0x87,0x98 +,0xa7,0x86,0x81,0x80,0x81,0x80,0x8d,0xf9,0x8b,0x8a,0x86,0x80,0x81,0x80,0x95,0x0f,0xa5,0x82,0x80,0x81,0x82,0x8f,0xf5,0x11,0x0a,0x1b,0x94,0x80,0x86,0x4a,0x00,0x03 +,0x0e,0x04,0x1b,0x9b,0x86,0x8e,0x06,0x00,0x0a,0xae,0x8e,0xa8,0x8f,0x8c,0xbd,0x19,0x12,0xb6,0x80,0x83,0x86,0x27,0x2f,0x80,0xba,0x43,0x98,0x86,0x80,0x98,0x14,0x1a +,0x97,0x86,0x90,0xa5,0x95,0x98,0x15,0x05,0x0e,0x86,0x88,0x07,0x00,0x00,0x04,0x02,0x03,0x0a,0x23,0x23,0x00,0x01,0x00,0x07,0x29,0x10,0x05,0x03,0x00,0x00,0x00,0x01 +,0x8f,0xab,0x00,0x02,0x00,0x04,0x00,0x03,0x06,0x2d,0x20,0x00,0x01,0x00,0x0c,0x2e,0x16,0x13,0x14,0x01,0x01,0x00,0x32,0x80,0xa6,0x0d,0x00,0x0c,0xcf,0xb8,0x9e,0x9b +,0x85,0x89,0xae,0xa1,0x88,0x80,0x80,0x80,0x83,0x87,0x8d,0x8b,0x84,0x80,0x81,0x80,0x8b,0x97,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x9e,0x96,0x80,0x81,0x80,0x84,0x8d +,0xc4,0x28,0x18,0x8c,0x80,0x81,0x85,0x29,0x8e,0x85,0x8a,0x83,0x85,0x80,0x80,0x82,0x8a,0x84,0x80,0x81,0x87,0x8f,0x94,0xa6,0xb3,0xa4,0x81,0x8c,0x25,0x06,0x02,0x1a +,0x0a,0x06,0x02,0x04,0x05,0x00,0x01,0x00,0x0d,0x0e,0x03,0x00,0x00,0x00,0x01,0x00,0x0e,0x18,0x00,0x01,0x00,0x01,0x00,0x02,0x02,0x0f,0x1f,0x05,0x01,0x00,0x0d,0x33 +,0x1c,0x07,0x0c,0x07,0x07,0x00,0x1d,0x8f,0x27,0x1b,0x09,0x9c,0x8d,0x99,0x9c,0x96,0x82,0x85,0x90,0x92,0x81,0x80,0x81,0x9d,0x48,0x25,0x4f,0xaf,0x8c,0x80,0x8a,0x9c +,0x12,0xb9,0x88,0x8b,0x85,0x86,0x82,0x89,0xb9,0x2f,0x96,0x85,0x85,0xa3,0x23,0x0e,0x08,0x0f,0xb5,0x80,0x94,0x3e,0x07,0x0c,0xc8,0x2f,0x49,0x42,0x94,0x8c,0xe3,0x14 +,0x5b,0x8d,0x8c,0x16,0x0a,0x06,0x02,0x09,0x18,0x8a,0xa2,0x0f,0x01,0x03,0x23,0x47,0xaf,0x3f,0x98,0x98,0x0e,0x02,0x12,0x8e,0x87,0xb5,0x1a,0x0c,0x06,0x08,0x18,0x83 +,0x82,0x8a,0x1b,0x08,0xa4,0xb9,0xac,0xcb,0x90,0x85,0xa3,0x0f,0x14,0xdb,0x94,0xc3,0x0f,0x0a,0x05,0x10,0x23,0x87,0x80,0x82,0x8e,0xca,0x85,0x81,0x80,0x81,0x80,0x80 +,0x80,0x87,0x8a,0x81,0x80,0x81,0x88,0xae,0x15,0x1d,0x1d,0x8e,0x82,0xa0,0x17,0x00,0x04,0x04,0x05,0x08,0x0f,0xbf,0x1f,0x06,0x00,0x03,0x0d,0x0c,0x03,0x03,0x00,0x01 +,0x00,0x03,0x49,0x1e,0x17,0x04,0x0a,0x33,0x1c,0x2b,0x1c,0x96,0x8e,0xa7,0x1f,0x5d,0x8a,0x8a,0xa8,0x1f,0x1d,0x1a,0x2f,0xd1,0x87,0x80,0x83,0x9c,0x1b,0x99,0x8c,0x8a +,0x86,0x82,0x80,0x88,0xc9,0x1c,0x99,0x88,0x89,0xa2,0x32,0x13,0x0b,0x0c,0x20,0x82,0x85,0x89,0x18,0x0a,0x4b,0x24,0x4f,0x27,0x98,0x8c,0x3f,0x09,0x02,0x11,0x3c,0x28 +,0x10,0x0c,0x05,0x07,0x04,0x15,0x92,0xaf,0x24,0x01,0x0c,0x26,0x36,0xba,0xba,0x97,0xa3,0x1a,0x07,0x11,0xb8,0x9d,0x2f,0x14,0x0c,0x06,0x08,0x0b,0x9d,0x82,0x8e,0xb5 +,0x09,0x28,0xc5,0xa3,0x9d,0x96,0x88,0x8e,0xce,0x16,0x37,0x91,0x89,0x8d,0x97,0xaa,0x2f,0x1f,0x19,0x9b,0x8a,0x96,0xb6,0x07,0x19,0x15,0x17,0x0d,0x0d,0x2a,0x3f,0x19 +,0x0a,0x15,0xdd,0x9a,0x9a,0x92,0x92,0x94,0x97,0x9b,0x84,0x80,0x80,0x84,0x96,0x85,0x89,0x89,0x91,0x8f,0x85,0x85,0x98,0x2c,0x32,0x9d,0xa0,0x34,0x19,0x07,0x00,0x01 +,0x00,0x15,0xb4,0x21,0x0b,0x00,0x03,0x01,0x04,0x03,0x0b,0x1c,0x17,0x05,0x01,0x06,0x22,0xce,0x30,0x17,0x0e,0x04,0x07,0x08,0x9e,0x84,0x8f,0xbd,0x08,0xdb,0xbf,0xa2 +,0xa2,0x91,0x82,0x83,0x8c,0xa0,0x8c,0x82,0x82,0x85,0x8d,0x92,0xca,0x47,0x2c,0x8c,0x80,0x82,0x8e,0x1c,0xa5,0xab,0x9b,0xab,0x91,0x81,0x86,0x9a,0x29,0xc1,0x8e,0x91 +,0xa7,0x2a,0x16,0x06,0x04,0x03,0x3d,0x8a,0xa0,0x1e,0x00,0x0d,0x0d,0x1a,0x1f,0x45,0x9b,0xae,0x14,0x03,0x0a,0x2a,0x26,0x13,0x0c,0x0e,0x05,0x04,0x03,0x22,0x8b,0x9e +,0x4d,0x04,0x1e,0x2f,0x2c,0x17,0x2a,0x97,0x97,0xc0,0x11,0x1d,0xa0,0x97,0xd4,0x1d,0x2c,0x17,0x0f,0x0d,0x59,0x80,0x85,0x8a,0x22,0x9d,0x8e,0x8f,0x91,0x8e,0x82,0x83 +,0x92,0x1f,0x1a,0xb2,0x9f,0x39,0x1a,0x0f,0x05,0x03,0x03,0x0e,0x8c,0x91,0x8e,0x17,0x29,0xa9,0xaf,0x8f,0x8d,0x80,0x82,0x85,0x97,0x9d,0x89,0x82,0x83,0x84,0x87,0x98 +,0xdb,0xda,0xb2,0x81,0x85,0x89,0x26,0x13,0x1c,0x09,0x0b,0x06,0x13,0x1b,0x0a,0x00,0x00,0x08,0x12,0x09,0x06,0x04,0x05,0x00,0x03,0x01,0xaf,0xa8,0x1d,0x09,0x04,0x23 +,0x13,0x17,0x0f,0x5f,0x9a,0x3a,0x12,0x12,0xa5,0x8d,0x9d,0xb5,0xce,0xbe,0x22,0x3c,0xc7,0x83,0x81,0x82,0x95,0xb6,0x86,0x94,0x8e,0x92,0x89,0x83,0x8c,0xac,0xc3,0x94 +,0x85,0x8a,0x8f,0x9d,0xb8,0x19,0x1e,0x23,0x8a,0x83,0x87,0x9f,0x11,0x63,0x1c,0x28,0x1e,0xc4,0x98,0xa1,0x26,0x0e,0x19,0xbb,0xc2,0x45,0x1c,0x0c,0x01,0x04,0x00,0x25 +,0x90,0xa6,0x1e,0x00,0x0a,0x05,0x0d,0x13,0x34,0x99,0x9c,0x27,0x0d,0x1b,0x9c,0x94,0xa4,0x2b,0x15,0x04,0x07,0x06,0xc3,0x86,0x8f,0xb7,0x04,0x18,0x18,0x45,0xb5,0x9b +,0x88,0x8b,0xa3,0x2a,0xb0,0x88,0x86,0x8a,0x91,0xa3,0x26,0x2c,0x2c,0x99,0x82,0x8d,0xbe,0x06,0x1b,0x17,0x16,0x1a,0x26,0x9a,0x9b,0x44,0x1b,0x1e,0x9f,0x94,0x93,0x98 +,0xa6,0x2e,0x2a,0x3f,0x8f,0x80,0x82,0x82,0x9f,0x8a,0x8b,0x8a,0x85,0x87,0x80,0x83,0x8d,0x38,0x27,0x9d,0xaf,0x2f,0x0d,0x04,0x00,0x01,0x00,0x09,0x59,0x26,0x0f,0x00 +,0x04,0x04,0x08,0x0d,0x18,0xb0,0x3a,0x0b,0x02,0x07,0x1c,0x2e,0x21,0x0d,0x08,0x00,0x05,0x03,0xbe,0x87,0x8a,0x99,0x19,0x9e,0xa3,0x97,0x99,0x91,0x82,0x86,0x8c,0xbf +,0x9b,0x88,0x87,0x88,0x98,0xa3,0x20,0x29,0x40,0x8b,0x80,0x81,0x8b,0xd1,0x94,0x97,0x95,0x99,0x96,0x86,0x8c,0xb1,0x16,0x3a,0x94,0x9a,0xa8,0x1c,0x16,0x06,0x0d,0x18 +,0x8d,0x84,0x8d,0x4b,0x10,0x69,0x1a,0x1b,0x1d,0x38,0xab,0x1b,0x07,0x03,0x0e,0x1f,0x15,0x0f,0x07,0x03,0x01,0x06,0x13,0x90,0x97,0xb0,0x14,0x11,0x38,0x1a,0x29,0x21 +,0x4c,0xa7,0x25,0x13,0x0e,0xe6,0xa5,0xb0,0xee,0x2a,0x1e,0x12,0x23,0xbc,0x84,0x8a,0x8c,0x3e,0xab,0x96,0xa7,0x97,0x9f,0x8c,0x88,0x9b,0xc7,0x3c,0x94,0x92,0x9e,0xc0 +,0x1e,0x0e,0x06,0x09,0x2f,0x89,0x93,0xa8,0x0d,0x31,0x2e,0x1e,0x2d,0x50,0x8a,0x89,0x95,0xa0,0x8e,0x83,0x82,0x82,0x85,0x84,0x8f,0x9d,0x94,0x87,0x81,0x88,0x9d,0x12 +,0x2e,0x0f,0x07,0x06,0x03,0x13,0x0d,0x06,0x00,0x04,0x0e,0x0f,0x15,0x13,0x0b,0x05,0x01,0x05,0xad,0x95,0xac,0x0e,0x0a,0x20,0x10,0x18,0x1c,0xae,0x8a,0x9f,0x2f,0x1d +,0xa3,0x88,0x8f,0x96,0xbe,0x1c,0x11,0x0e,0x4d,0x8a,0x8d,0x9a,0x22,0x65,0xac,0x49,0xbe,0xac,0x8b,0x85,0x8f,0xb3,0x2a,0x99,0x8a,0x89,0x90,0xc7,0x16,0x08,0x04,0x4d +,0x99,0x9d,0x25,0x0e,0x39,0x19,0x1f,0x1d,0xae,0x89,0x8d,0xbc,0x28,0xd8,0x93,0x8f,0x93,0xa5,0x31,0x19,0x0a,0x17,0x8f,0x8e,0x91,0x2a,0xad,0x9e,0x3f,0x3e,0x1b,0x9e +,0x8c,0x94,0x32,0x17,0x1a,0x3c,0x41,0xca,0x27,0x13,0x0a,0x04,0x1e,0x93,0x92,0xc9,0x10,0x4a,0x5b,0x2d,0x1a,0x19,0x9a,0x9c,0x5d,0x11,0x17,0x4f,0x42,0x25,0x35,0x2b +,0x2c,0x10,0x0e,0x9f,0x9d,0xaf,0x18,0x17,0xad,0x31,0x24,0x15,0x65,0x8c,0x8f,0x9d,0xc9,0x98,0x8e,0x8f,0x91,0x9b,0xb4,0x55,0x19,0xdc,0x8f,0x98,0xad,0x14,0xfe,0xc7 +,0xd0,0xb6,0x4c,0x95,0x8b,0x87,0x8b,0x8e,0x89,0x8e,0x95,0x98,0xab,0xba,0x33,0x1d,0xc3,0xba,0xb2,0x23,0x23,0xaa,0x3c,0x7e,0x2a,0x56,0x99,0x9c,0x9b,0xb3,0x4a,0xc9 +,0x19,0x1a,0x14,0x08,0x09,0x07,0x0b,0x1f,0x14,0x16,0x0c,0x1c,0xbb,0x46,0x45,0x17,0x18,0xd0,0x9f,0x9b,0xa8,0x74,0x31,0x15,0x15,0x15,0x0d,0x16,0x13,0x1a,0x52,0x27 +,0x1c,0x14,0xbd,0x96,0x8f,0x94,0xae,0xac,0x90,0x89,0x88,0x84,0x85,0x8d,0xa8,0xb7,0xb8,0x4d,0xdf,0x23,0x22,0x1b,0x0d,0x05,0x07,0x0b,0x09,0x0e,0x0e,0x0b,0x07,0x0b +,0x12,0x2b,0xce,0xba,0x23,0x1f,0x24,0x21,0x2a,0xb2,0xbd,0xa4,0xc3,0x28,0x20,0xaf,0x91,0x8e,0x8b,0x8d,0x91,0x90,0x86,0x88,0x83,0x83,0x85,0x8b,0x8f,0x96,0x9f,0xb3 +,0xa8,0x2f,0xcc,0x4b,0x1f,0x10,0x25,0xb6,0x99,0x8f,0x9e,0xf5,0x40,0x9b,0x93,0x8c,0x90,0x9d,0x2d,0x2a,0x1a,0x15,0x16,0x1c,0x0b,0x0b,0x09,0x08,0x04,0x0b,0x11,0x18 +,0x21,0x13,0x0d,0x0e,0x2b,0x2c,0x2d,0x48,0x5d,0x2b,0x31,0x34,0xbc,0xae,0x9d,0xb4,0xa0,0xa1,0x3e,0x22,0xad,0x90,0x90,0x9d,0xe1,0x29,0x37,0x9f,0x96,0x8d,0x93,0xad +,0xda,0x9f,0x97,0xa0,0xc5,0xad,0x35,0x3f,0x1c,0x0f,0x0e,0x20,0x38,0xe1,0xac,0xc8,0x3e,0xaf,0x97,0x91,0x8b,0x88,0x85,0x88,0x87,0x8a,0x8b,0x8c,0x8b,0x99,0x90,0x98 +,0xaf,0xd1,0x97,0x90,0x93,0x9b,0xc6,0x4e,0xa3,0x95,0xb1,0x3b,0x2d,0x25,0x13,0x11,0x09,0x08,0x03,0x02,0x00,0x03,0x03,0x01,0x00,0x04,0x03,0x06,0x08,0x07,0x07,0x0e +,0x1d,0x1c,0x25,0x4b,0xb0,0x4a,0x3b,0x2c,0xe0,0xcb,0xb9,0x34,0xb2,0xaf,0xf0,0xc0,0x98,0x92,0x99,0x94,0x97,0x8f,0x8a,0x86,0x89,0x8f,0x8d,0x8c,0x91,0x8e,0x91,0x97 +,0x98,0x94,0x97,0x8f,0x98,0xad,0xca,0x99,0x91,0x98,0x99,0xa1,0x4c,0xf0,0xa6,0xa9,0xaa,0xa8,0xbf,0x3b,0x60,0x30,0x1f,0x1b,0x1e,0x0d,0x0f,0x14,0x0c,0x08,0x11,0x10 +,0x0b,0x0d,0x0d,0x0b,0x1a,0x37,0x3e,0x30,0xb1,0xa4,0xdc,0xb9,0x2f,0x2f,0x2e,0x30,0x17,0x18,0x16,0x09,0x07,0x1a,0x26,0x24,0x28,0x27,0x26,0xaa,0x8d,0x92,0x97,0x92 +,0x93,0x9d,0xa1,0xdf,0x64,0x43,0x4f,0x21,0x38,0xe6,0x2d,0x26,0xb3,0x9b,0x92,0x8b,0x8c,0x8d,0x89,0x83,0x86,0x83,0x82,0x81,0x85,0x89,0x8e,0x8c,0x8a,0x8c,0x9c,0xa0 +,0x9f,0x42,0x2f,0xb4,0xe8,0x1f,0x17,0x0f,0x0d,0x15,0x17,0x0c,0x09,0x0a,0x0b,0x07,0x08,0x05,0x05,0x05,0x05,0x03,0x06,0x07,0x05,0x03,0x08,0x0b,0x0b,0x0e,0x12,0x12 +,0x1e,0xbe,0x4a,0xb1,0x9d,0x98,0x9c,0x98,0x91,0x8d,0x93,0x9b,0xce,0xb6,0x97,0x9a,0x9f,0x99,0x96,0xae,0xae,0xa0,0x96,0x8d,0x88,0x8c,0x8a,0x87,0x83,0x88,0x89,0x89 +,0x8a,0x8d,0x91,0xa2,0xb9,0xac,0x4a,0x26,0x29,0x3a,0x1f,0x1e,0x24,0x27,0xd8,0x9e,0xb9,0x3f,0x4e,0xbd,0x3a,0x32,0x2d,0x1f,0x13,0x09,0x04,0x06,0x0c,0x0b,0x07,0x06 +,0x0a,0x0a,0x12,0x1c,0x1f,0x2a,0xc1,0xe9,0x5d,0x4e,0xbd,0x57,0x2d,0x25,0x1e,0x20,0x1c,0x10,0x0b,0x17,0x1f,0x19,0x15,0x1d,0x1f,0x2f,0x3d,0x57,0xb7,0x9c,0xa1,0xd0 +,0xab,0x94,0x8f,0x8d,0x8b,0x8e,0x8d,0x8e,0x8c,0x8e,0x8a,0x89,0x8e,0x8f,0x8b,0x88,0x89,0x88,0x8c,0x8c,0x87,0x85,0x87,0x87,0x87,0x88,0x8a,0x89,0x93,0xab,0x3d,0x1a +,0x0a,0x06,0x09,0x06,0x03,0x01,0x02,0x03,0x04,0x03,0x04,0x0a,0x0d,0x0a,0x11,0x18,0x19,0x11,0x0f,0x10,0x15,0x11,0x0b,0x05,0x06,0x0a,0x0c,0x0b,0x0e,0x23,0x23,0x3b +,0xcd,0x9c,0x92,0x8e,0x8f,0x8f,0x88,0x86,0x88,0x8d,0x8e,0x8c,0x8c,0x9a,0xb6,0xc8,0xae,0xa7,0xaa,0xaf,0x9c,0x9a,0x99,0x9d,0x97,0x8c,0x8a,0x8d,0x8f,0x89,0x88,0x87 +,0x8c,0x91,0x96,0x94,0x9b,0xbd,0x27,0x1d,0x26,0x1a,0x10,0x10,0x18,0x12,0x0a,0x0c,0x15,0x22,0x2b,0x1d,0x24,0x34,0xc0,0xb9,0x32,0x28,0x24,0x1e,0x12,0x0e,0x0d,0x0f +,0x0d,0x07,0x07,0x0c,0x15,0x13,0x15,0x1e,0x47,0xa3,0xa6,0xbd,0xa9,0x9c,0x9c,0xad,0xae,0xaf,0xe8,0x1b,0x0c,0x0d,0x0f,0x17,0x15,0x10,0x1b,0xee,0xa9,0x9c,0x96,0x8c +,0x8b,0x89,0x88,0x84,0x81,0x82,0x82,0x85,0x84,0x85,0x88,0x8c,0x8d,0x8f,0x8f,0x8d,0x8e,0x98,0x99,0x97,0x9e,0x9d,0x9e,0xa0,0xae,0x3f,0x1d,0x24,0x2f,0x24,0x17,0x0e +,0x0b,0x07,0x06,0x05,0x04,0x03,0x03,0x03,0x02,0x02,0x04,0x05,0x05,0x05,0x07,0x0e,0x17,0x19,0x1e,0x4c,0xaa,0x9a,0x95,0x9c,0xad,0xc5,0xcd,0x6a,0xce,0x62,0x3d,0x33 +,0x1e,0x26,0xba,0xa2,0x9d,0x9c,0x94,0x8c,0x87,0x86,0x86,0x85,0x84,0x85,0x88,0x8a,0x8d,0x95,0xa9,0xa3,0x9c,0xad,0xc4,0xc5,0xc4,0xc4,0xa0,0x9f,0xa9,0xa2,0xa9,0xa1 +,0xa0,0x9e,0x9d,0xa3,0xac,0xcf,0x4f,0x47,0x29,0x1e,0x1c,0x13,0x16,0x0f,0x0b,0x0b,0x0b,0x0a,0x0b,0x0d,0x0c,0x0b,0x0b,0x11,0x22,0x39,0x2f,0x46,0xbd,0xe6,0xad,0xa8 +,0xae,0xd7,0x5b,0x2a,0x18,0x18,0x12,0x12,0x11,0x0e,0x0d,0x14,0x14,0x11,0x16,0x2b,0xaf,0x98,0x98,0xa4,0x97,0x8e,0x8d,0x8b,0x8a,0x88,0x8b,0x96,0x9c,0x92,0x8b,0x8e +,0x90,0x8d,0x8f,0x8e,0x88,0x89,0x89,0x86,0x86,0x86,0x85,0x87,0x89,0x89,0x8c,0x8f,0x96,0x9e,0xbc,0x2b,0x1e,0x10,0x0f,0x11,0x07,0x02,0x03,0x03,0x02,0x02,0x03,0x03 +,0x03,0x02,0x02,0x08,0x0e,0x0d,0x0f,0x17,0x1f,0x28,0x55,0x43,0x32,0x36,0x28,0x1e,0x1f,0x20,0x17,0x12,0x12,0x12,0x15,0x1f,0x29,0x4e,0xa6,0x9a,0x8e,0x88,0x86,0x88 +,0x86,0x82,0x82,0x84,0x86,0x89,0x8e,0x92,0x98,0x9d,0x9a,0xa0,0x5d,0x55,0xbb,0xad,0xad,0xa1,0x9d,0x9c,0x98,0x99,0x94,0x8b,0x8b,0x98,0x9a,0x92,0x96,0x9e,0x9f,0xac +,0xad,0xdc,0x30,0x28,0x19,0x0e,0x07,0x06,0x08,0x08,0x05,0x04,0x05,0x08,0x0b,0x0f,0x12,0x1c,0x27,0x25,0xc8,0x9a,0x9b,0x9f,0xa9,0xae,0xbd,0x3e,0x20,0x12,0x14,0x16 +,0x11,0x0b,0x0b,0x0e,0x0d,0x0e,0x18,0x20,0x24,0x2b,0x4b,0xae,0x9c,0x99,0x99,0x9c,0x93,0x8c,0x8b,0x8a,0x8a,0x88,0x88,0x89,0x87,0x84,0x85,0x87,0x8b,0x8c,0x8b,0x8d +,0x94,0x90,0x90,0x91,0x8f,0x91,0x90,0x8e,0x91,0x9a,0x94,0x8c,0x8e,0x9f,0xbb,0x28,0x26,0x1d,0x0e,0x07,0x05,0x02,0x00,0x00,0x01,0x02,0x02,0x01,0x01,0x03,0x07,0x0b +,0x0a,0x0e,0x1b,0x26,0x25,0x38,0x4e,0xbc,0x67,0x4a,0x48,0x4c,0xd4,0x6d,0x3b,0x46,0xb6,0xa8,0xbd,0x2b,0x2a,0x3e,0x56,0xf3,0xa7,0xa7,0x9e,0xa3,0xaa,0x9a,0x8c,0x89 +,0x88,0x88,0x88,0x86,0x85,0x83,0x86,0x86,0x89,0x8c,0x99,0x9f,0xa0,0xa8,0x58,0x1f,0x24,0x24,0x18,0x18,0x1e,0x36,0x1f,0x3c,0x8b,0x85,0x0f,0x13,0x80,0x97,0x98,0x9c +,0x22,0x1c,0x08,0x0b,0x05,0x11,0x03,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x02,0x03,0x04,0x09,0x0c,0x12,0x1e,0x2e,0x9f,0x94,0x8a,0x84,0x85,0x87,0x82,0x80 +,0x84,0x87,0x83,0x80,0x80,0x84,0x87,0x8a,0x8d,0x8c,0x89,0x86,0x88,0x87,0x85,0x83,0x87,0x89,0x83,0x82,0x85,0x87,0x88,0x8d,0x8d,0x94,0xad,0x46,0x21,0x19,0x0e,0x07 +,0x05,0x03,0x04,0x02,0x01,0x02,0x01,0x01,0x01,0x01,0x01,0x04,0x03,0x02,0x03,0x06,0x08,0x07,0x09,0x08,0x0a,0x0b,0x0b,0x09,0x0b,0x0e,0x09,0x07,0x06,0x0c,0x0f,0x0c +,0x10,0x10,0x1a,0x15,0x31,0xbb,0x9d,0x8d,0x8d,0x84,0x84,0x82,0x83,0x82,0x81,0x81,0x80,0x81,0x82,0x82,0x81,0x84,0x83,0x83,0x88,0x86,0x8c,0x8f,0x87,0x86,0x8a,0x86 +,0x83,0x81,0x82,0x87,0x81,0x81,0x81,0x81,0x81,0x80,0x81,0x82,0x81,0x87,0x88,0x8b,0x8e,0x8b,0xa3,0xa7,0xb3,0x15,0x10,0x08,0x23,0x19,0x05,0x0f,0x09,0x0e,0x05,0x06 +,0x0f,0x08,0x07,0x08,0x05,0x04,0x01,0x05,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x06,0x04,0x05,0x0d,0x03,0x06,0x0b,0x0c,0x0a +,0x0a,0x19,0x17,0x09,0x0e,0x16,0x13,0x0d,0x12,0x17,0x1c,0x0a,0x16,0x9e,0x30,0x99,0x90,0x8e,0x8f,0x8c,0x82,0x85,0x85,0x82,0x83,0x85,0x84,0x82,0x81,0x84,0x81,0x82 +,0x83,0x86,0x89,0x87,0x86,0x8c,0x83,0x81,0x8a,0x82,0x81,0x81,0x83,0x83,0x80,0x83,0x83,0x81,0x83,0x82,0x83,0x82,0x87,0x8b,0x84,0x8b,0x8e,0x8d,0x8c,0x96,0xaa,0x37 +,0x96,0x95,0x47,0x8e,0x8f,0x92,0xa3,0x9e,0x99,0x40,0xad,0x9f,0x5b,0xea,0x2b,0x33,0x18,0x12,0x2f,0x0d,0x11,0x0b,0x09,0x08,0x05,0x04,0x11,0x13,0x0a,0x39,0x24,0x24 +,0x1d,0x39,0x56,0x17,0xcc,0x37,0x16,0x1d,0x19,0x1f,0x12,0x13,0x0f,0x06,0x08,0x05,0x02,0x03,0x01,0x02,0x09,0x02,0x04,0x08,0x06,0x07,0x04,0x08,0x04,0x01,0x07,0x03 +,0x03,0x04,0x03,0x03,0x00,0x03,0x01,0x02,0x01,0x02,0x01,0x01,0x00,0x04,0x0b,0x03,0x0d,0x10,0x12,0x11,0x15,0x39,0x19,0x34,0xaf,0x2d,0xde,0xbc,0xa3,0xb1,0xb4,0x97 +,0x9b,0x94,0x90,0x92,0x8c,0x8a,0x8c,0x83,0x84,0x84,0x80,0x81,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x81,0x81,0x81,0x81,0x84,0x83,0x85 +,0x86,0x80,0x86,0x82,0x80,0x82,0x81,0x83,0x81,0x85,0x87,0x81,0x8a,0x89,0x8a,0x8f,0x95,0x9d,0x98,0x42,0x2c,0x28,0x15,0x0f,0x0e,0x05,0x12,0x14,0x08,0x1a,0x10,0x11 +,0x09,0x09,0x0d,0x03,0x07,0x07,0x03,0x04,0x02,0x02,0x00,0x01,0x02,0x00,0x02,0x01,0x00,0x00,0x01,0x00,0x07,0x03,0x08,0x0d,0x0a,0x0c,0x07,0x16,0x15,0x12,0x37,0x1d +,0x1a,0x1c,0x1e,0x23,0x1b,0xcc,0x25,0x1f,0x26,0x19,0x12,0x1d,0x18,0x2b,0xaa,0x28,0x9f,0xa4,0xa7,0xa4,0x98,0x8e,0x9e,0x98,0x92,0xa2,0x99,0x98,0x93,0x9d,0x9c,0x94 +,0xae,0xa0,0xa8,0xcd,0xe3,0xce,0x2e,0x96,0xab,0xa2,0x89,0x8d,0x8a,0x8f,0x8a,0x8d,0x94,0x85,0x8b,0x8d,0x8b,0x93,0x92,0xa3,0x91,0x9f,0xb3,0xa6,0x42,0x1c,0x13,0x0b +,0x1a,0x4e,0x1a,0xb5,0xbe,0x5f,0x53,0xf1,0xa2,0xdf,0xa2,0x9c,0x57,0xa7,0xa9,0xb7,0xc8,0xaf,0xad,0x25,0x28,0x1a,0x10,0x0f,0x14,0x0e,0x27,0x23,0x15,0x56,0x37,0xb3 +,0xde,0xa1,0x9a,0xac,0x94,0x99,0xa8,0x92,0x96,0x9a,0x9c,0x97,0xa0,0xb5,0xaf,0xc6,0x3b,0x2b,0x2f,0x1b,0x9c,0x47,0xae,0x97,0xa3,0x94,0xa4,0x8f,0x96,0x9a,0x8a,0x99 +,0x9c,0x96,0xa1,0xa6,0x61,0xa6,0x35,0x35,0x27,0x1b,0x0f,0x0d,0x0d,0x0d,0x24,0x0f,0x3a,0xeb,0x39,0xbd,0xb4,0x9e,0xb2,0xa4,0x95,0xba,0x9d,0x99,0xa4,0x9e,0x9e,0x99 +,0xe7,0xbe,0xc6,0x2d,0x18,0x22,0x11,0x2b,0xd9,0x17,0xa5,0xbc,0xb1,0xd1,0x7c,0xb7,0x25,0xb3,0xb4,0x1f,0xb5,0xba,0x4e,0x2b,0x3d,0x57,0x15,0x2b,0x20,0x13,0x0f,0x19 +,0x0b,0x2b,0x30,0x1d,0xa9,0x43,0xab,0xc2,0xb3,0xab,0x41,0x9a,0x99,0xd4,0x9c,0xb3,0xae,0x54,0xab,0xb2,0x26,0xc1,0x33,0x1a,0x1c,0x19,0x10,0xc6,0x1b,0x3e,0xac,0x3a +,0xaf,0xe8,0xa1,0xb9,0xc5,0x97,0xdd,0xbb,0x9a,0xb0,0xad,0xd2,0x9c,0x68,0x4a,0xa8,0x36,0x22,0x36,0x1d,0x1c,0xae,0x20,0xb7,0xa8,0xad,0xa3,0xcf,0xa0,0x3e,0xcd,0x9c +,0x34,0xcc,0xae,0x55,0x4e,0x4d,0xa5,0x2d,0x42,0xee,0x1d,0x12,0x1a,0x12,0x16,0xb1,0x1c,0xc5,0xb3,0x4d,0xc6,0x45,0xa6,0x38,0xc2,0xa4,0x25,0xc7,0xb7,0x47,0x3e,0xe7 +,0xa6,0x20,0x3c,0x2e,0x18,0x17,0x22,0x16,0x1a,0xa7,0x1d,0xbd,0xab,0xb6,0xac,0xbc,0x9b,0xc8,0x9f,0x94,0xd5,0x9c,0x9a,0x9e,0xa2,0xa7,0x96,0xfc,0xa2,0xad,0x2d,0x2a +,0x4a,0x19,0x2c,0xab,0x1d,0xad,0xc2,0xc8,0xce,0x6b,0xa6,0x28,0xae,0xa2,0x2c,0xb3,0x68,0x6b,0x43,0xd1,0xaf,0x25,0xb3,0x38,0x1a,0x1a,0x1d,0x0f,0x1e,0xcc,0x18,0xae +,0xb5,0x78,0xfc,0xb5,0xa2,0x34,0xa4,0xa5,0x3d,0xa5,0xad,0xbf,0xb9,0xae,0xb6,0x27,0xbd,0x29,0x19,0x15,0x18,0x0c,0x1e,0xdd,0x13,0xaa,0xb3,0x65,0x56,0xb9,0xa6,0x3d +,0x9d,0x9b,0x68,0x9a,0xa7,0xb1,0xae,0xa3,0x9f,0x2f,0xad,0x34,0x21,0x1e,0x23,0x13,0x2b,0xae,0x19,0xa9,0xad,0xc1,0xb1,0xac,0x9b,0xd2,0x9d,0x9e,0x52,0x9d,0xb3,0xa8 +,0xe4,0xc3,0xaa,0x24,0xb7,0x22,0x1d,0x19,0x19,0x10,0x27,0xdd,0x18,0xa2,0xb2,0xba,0xb6,0xac,0xa0,0x50,0x9c,0xa0,0x38,0xa0,0xc8,0xbb,0x6f,0xb9,0xb8,0x22,0x7e,0x22 +,0x1a,0x16,0x1d,0x0c,0x35,0x50,0x17,0xa4,0xbd,0xaf,0xa9,0xa2,0x9a,0x40,0x9b,0x9f,0x46,0x98,0xa7,0xa2,0xbe,0xa5,0xa7,0x39,0xb2,0x2f,0x21,0x1b,0x1c,0x0e,0x2d,0x4e +,0x1c,0x9d,0xc6,0x5f,0xbe,0xd5,0xbd,0x3c,0x9d,0xaa,0x39,0xa1,0xb1,0xaf,0xbe,0xac,0xbf,0x31,0xbf,0x1f,0x16,0x19,0x1d,0x0e,0xc7,0x27,0x1c,0x9f,0x37,0xbf,0xca,0x9f +,0xaf,0x4f,0x93,0xa7,0xb7,0x9a,0xb6,0xac,0xbc,0x9d,0xd2,0x2e,0xae,0x2a,0x18,0x19,0x16,0x0a,0x57,0x1a,0x1d,0xa4,0x3f,0xc4,0x4d,0xa0,0xa8,0xc3,0x95,0xb1,0xb9,0x98 +,0xa7,0xa3,0xae,0x94,0xab,0x43,0xad,0x24,0x19,0x1b,0x17,0x0f,0xb6,0x21,0x22,0xa7,0xc8,0xaa,0xbc,0xa0,0xcc,0xbd,0x95,0xbd,0xbe,0x9a,0xa1,0x9f,0xb9,0x9d,0x55,0x3e +,0xda,0x1d,0x16,0x1a,0x16,0x0a,0xc3,0x19,0x2c,0xa5,0x30,0xbc,0x55,0x9f,0xe2,0xce,0x92,0xbf,0xa5,0x9c,0xad,0xa4,0xb8,0x9e,0x3c,0xd6,0xda,0x1c,0x13,0x1a,0x12,0x0f +,0xab,0x14,0x2b,0xa9,0x36,0xc5,0x5d,0x9a,0xf8,0xaf,0x91,0x57,0xa4,0x9b,0xa5,0x9e,0xa6,0x97,0xcf,0xe2,0xb9,0x21,0x18,0x24,0x0f,0x0f,0xaf,0x12,0x2b,0xbb,0x2e,0xc2 +,0x49,0x9c,0x45,0xe7,0x96,0x41,0xaf,0x97,0xa4,0xa4,0xb4,0xa1,0x51,0xd7,0xb7,0x22,0x17,0x24,0x13,0x10,0xbb,0x15,0x38,0xac,0x57,0xcd,0x6a,0x9e,0x48,0xac,0x94,0xbc +,0xa1,0x9a,0xa9,0xa6,0xab,0x9f,0x36,0xc7,0xc2,0x1b,0x1a,0x1e,0x0e,0x12,0xb5,0x13,0x37,0xac,0x45,0xc8,0xd3,0x9c,0x49,0xbb,0x94,0x4c,0x9e,0x97,0xad,0x9f,0xab,0x9f +,0x4b,0xae,0xca,0x1f,0x1e,0x20,0x0f,0x16,0xab,0x11,0x4f,0x9f,0x3f,0x73,0x5c,0xab,0x33,0xb5,0x97,0x3f,0xa9,0x9d,0xb5,0xac,0xae,0xa2,0x55,0xbc,0xf9,0x1f,0x1a,0x25 +,0x0e,0x22,0xab,0x11,0xb6,0xb4,0x43,0xba,0xc2,0xa2,0x2c,0xad,0x9e,0x2c,0xa2,0xa1,0xc2,0xba,0xac,0xa1,0x3f,0xb7,0x44,0x1d,0x1f,0x2a,0x0c,0x1d,0xa6,0x14,0xac,0xa8 +,0x53,0xad,0xaf,0x9d,0x39,0xae,0x96,0x2d,0xa2,0xa0,0xb5,0xae,0xcd,0xa3,0x2c,0xb4,0x6c,0x17,0x1a,0x1f,0x0e,0x2d,0xb2,0x18,0xac,0xb1,0xe1,0xb5,0xb7,0x9d,0x3e,0xa4 +,0x99,0x2f,0xa1,0xac,0xdb,0xb0,0xb5,0xb7,0x2f,0xf2,0x39,0x1c,0x19,0x26,0x0c,0x33,0xa7,0x0f,0xa1,0xa7,0xdf,0xb3,0xac,0x99,0x3c,0xa4,0x99,0x2a,0x9e,0xa2,0x59,0x6c +,0xd9,0xa6,0x2a,0x6f,0x3e,0x1a,0x1f,0x1d,0x0a,0x53,0xf4,0x1e,0x9d,0xac,0xb2,0xaf,0x9f,0xa7,0x37,0x9a,0x9f,0x26,0x9f,0xb3,0xdf,0xbe,0xb6,0xb1,0x27,0xbf,0x2f,0x14 +,0x1d,0x21,0x0f,0xd8,0xcb,0x1c,0x99,0xad,0xaf,0xa4,0xae,0xa7,0x30,0xa8,0xa3,0x2d,0x9c,0xba,0xbc,0xb6,0xf3,0xb1,0x23,0xb6,0x37,0x17,0x1d,0x1a,0x11,0xab,0x38,0x2c +,0x9b,0x4a,0xb9,0xe9,0xaa,0xae,0xee,0x9a,0xb8,0x40,0x9d,0xd1,0xba,0xbf,0xab,0xd1,0x2f,0xb0,0x25,0x1a,0x28,0x1d,0x0f,0xae,0x27,0x1f,0x9a,0xde,0xb7,0xac,0xa7,0xb1 +,0x3a,0x99,0xab,0x38,0x9a,0xb4,0xba,0xb9,0xac,0x5c,0x36,0xb2,0x27,0x12,0x27,0x12,0x13,0xa8,0x18,0xbd,0x9e,0x56,0xae,0xc9,0xa1,0x67,0xdc,0x97,0x4c,0xae,0x9f,0xc0 +,0xad,0xb2,0xa6,0x2d,0x75,0xe6,0x17,0x16,0x27,0x0c,0x38,0xac,0x19,0x9e,0xaf,0xc9,0xc2,0xc2,0x9e,0x2f,0xa8,0x9a,0x38,0xa0,0xab,0xad,0xce,0xad,0xae,0x28,0x79,0x35 +,0x1a,0x19,0x21,0x0e,0xb2,0x2d,0x28,0x98,0x69,0xab,0xb4,0xab,0xc0,0x3e,0x97,0xb8,0xce,0x9b,0xc2,0xc0,0xc9,0xa7,0x3c,0x70,0xc7,0x1f,0x12,0x24,0x11,0x16,0x9c,0x19 +,0xab,0x9e,0x7d,0xc0,0xbf,0x99,0x30,0xb6,0x94,0x2c,0xb7,0xa5,0xc4,0xb9,0xbd,0x9f,0x28,0x53,0x4e,0x12,0x16,0x1d,0x12,0xbb,0x5e,0x28,0x99,0xc6,0xac,0xca,0xa5,0xae +,0x31,0x96,0xbd,0x44,0xa4,0xc8,0xbd,0x5a,0xab,0xc5,0x3c,0xda,0x28,0x14,0x1e,0x17,0x18,0xa5,0x23,0xb1,0x9b,0x5c,0xab,0xb1,0x9e,0xf4,0x47,0x95,0x36,0xbf,0xa8,0xe6 +,0xaf,0xe9,0xa3,0x3a,0x37,0xce,0x1c,0x10,0x29,0x0f,0xd2,0xcf,0x1b,0x96,0xc4,0xa4,0xaf,0xb1,0xa2,0x24,0xa1,0xa7,0x25,0x9d,0xc8,0xba,0xc4,0xdc,0xb3,0x35,0x5c,0x44 +,0x17,0x1b,0x1b,0x16,0xa2,0x1f,0xa8,0x9b,0x58,0x9f,0x74,0xaa,0x35,0x3e,0x9b,0x4d,0xb3,0xa8,0x6d,0xbe,0xce,0xa8,0x5f,0xd1,0xc9,0x1f,0x14,0x23,0x10,0x56,0xb8,0x1d +,0x98,0xb0,0xb3,0xb1,0xc3,0xad,0x2b,0xa8,0xa7,0x2b,0xa8,0xaf,0xc4,0xe4,0xa5,0xb0,0x4d,0xde,0x4e,0x17,0x1a,0x1c,0x14,0xa3,0x22,0xad,0x9e,0x4e,0xa8,0xc2,0xb8,0x38 +,0x7d,0x9c,0x3d,0xe4,0x9e,0xfb,0xb9,0xb6,0xad,0x72,0xc3,0xc1,0x1f,0x10,0x2d,0x11,0x32,0xc3,0x1a,0x94,0xbe,0xaf,0xad,0xbf,0xab,0x27,0xa9,0xa8,0x37,0x9d,0xbb,0xc1 +,0xb6,0xb6,0xae,0x39,0x74,0x4b,0x15,0x1c,0x1b,0x15,0xab,0x1b,0xaf,0x9b,0x5a,0xa5,0xbe,0xa8,0x37,0xcf,0x9a,0x2c,0xb8,0xa0,0xbc,0xcd,0xc5,0xa7,0x30,0xbc,0xb7,0x1b +,0x17,0x23,0x10,0xde,0x36,0x21,0x99,0xb6,0xa9,0xae,0xaa,0xbd,0x27,0xa0,0xae,0x4a,0xa2,0xb3,0xbc,0x3c,0xb1,0xe5,0x3f,0xdd,0x49,0x15,0x1a,0x18,0x23,0xd3,0x1b,0x9c +,0xa3,0xae,0xaf,0xb7,0xa7,0x3b,0xaf,0xa1,0x47,0xba,0xa2,0xbc,0x2f,0xb8,0xbc,0x50,0x47,0x50,0x20,0x12,0x19,0x17,0xb0,0x21,0xdb,0x99,0x48,0xa1,0xa8,0xaa,0xbf,0xd8 +,0x9c,0xcf,0x5f,0xaf,0xbb,0xcf,0xc0,0xaf,0x3f,0x43,0xe6,0x2b,0x12,0x25,0x0f,0x33,0xbf,0x17,0x99,0xad,0xa9,0xa0,0xbb,0x9c,0x24,0xab,0xa1,0x2a,0xa4,0xb1,0xb7,0x49 +,0xc2,0xc9,0x36,0xcf,0x5f,0x15,0x27,0x14,0x18,0xa1,0x16,0xaa,0x9c,0xc4,0x9e,0xd3,0xa4,0x47,0x39,0x96,0x32,0xa9,0xaf,0x42,0xb5,0x34,0xa8,0x36,0x64,0xb1,0x1c,0x1e +,0x22,0x0b,0xad,0x61,0x26,0x99,0xbe,0xaa,0xb9,0xaa,0xa7,0x29,0xa4,0xb6,0x2a,0xb0,0x4d,0xb4,0x49,0xab,0xc6,0x41,0xb6,0x36,0x19,0x2b,0x15,0x2d,0xa7,0x18,0x9f,0xaf +,0xaf,0xa8,0xb0,0xa6,0x2d,0xca,0xac,0x29,0xb9,0xb8,0xb9,0xcd,0xd0,0xc5,0x39,0xca,0xdd,0x24,0x22,0x2b,0x0f,0x9f,0x1f,0x3e,0x93,0x38,0xa1,0xcf,0xa6,0xb2,0x20,0x9d +,0x3e,0x36,0xa6,0x37,0xbb,0x5f,0xc1,0xc7,0x50,0xae,0x3c,0x19,0x34,0x11,0xa9,0x53,0x1b,0x8e,0x37,0xaf,0xa6,0x44,0xa6,0x29,0xa6,0xc5,0x1e,0x9b,0x26,0xba,0xc0,0x46 +,0xa7,0x2c,0xae,0xcc,0x16,0x4e,0x14,0x1e,0x97,0x12,0x9a,0x9f,0x35,0x9a,0x45,0x9d,0x3b,0x3d,0x9b,0x1d,0xac,0x63,0x37,0xac,0x33,0xa9,0x29,0x57,0xaf,0x17,0x27,0x1d +,0x1d,0x97,0x17,0xaf,0x95,0x26,0x9d,0xc6,0xa5,0xc9,0x4d,0x97,0x22,0x55,0x99,0x22,0xd7,0xbc,0x54,0x2e,0x44,0xb4,0x21,0x1d,0x40,0x0e,0xc4,0xaf,0x16,0x94,0xae,0xca +,0xab,0xa2,0xa1,0x39,0xac,0xa8,0x23,0xa5,0xbd,0x2f,0xbf,0xca,0xcf,0x28,0xe9,0xc8,0x18,0x28,0x1b,0x1e,0x9e,0x11,0xa4,0x9c,0x2d,0x9b,0xb8,0x9f,0xc4,0xdc,0x97,0x27 +,0x4d,0x9f,0x32,0x46,0xb0,0xde,0x24,0xc0,0xd9,0x23,0x1a,0x3c,0x11,0x36,0xa3,0x14,0x9c,0xa5,0xd8,0xa2,0xab,0x9e,0x38,0xb7,0x9c,0x1b,0xb0,0xae,0x25,0xa2,0xcf,0x59 +,0x38,0xc2,0xce,0x1e,0x2e,0x2e,0x10,0x3b,0xa6,0x14,0xa3,0x9c,0x4b,0xa7,0xa6,0xa4,0x2c,0xb2,0xa4,0x1e,0x61,0xa4,0x2d,0x40,0xa6,0xbe,0x2f,0xd5,0xac,0x29,0x36,0x5a +,0x29,0x13,0xb2,0xbd,0x11,0x99,0xae,0x3b,0xa9,0xa5,0xaf,0x26,0xa2,0xbc,0x21,0xb8,0xb2,0x2a,0x2b,0xa3,0x6b,0x37,0x9f,0xa6,0x2e,0xad,0xc7,0x1c,0x1e,0x24,0xba,0x18 +,0xed,0x9b,0x20,0xae,0xa7,0xd0,0xd2,0xd6,0xa7,0x21,0x39,0xaf,0x28,0xb8,0xab,0xae,0xb4,0xbb,0x9b,0x4c,0xc7,0xab,0x32,0x23,0x26,0x21,0x1e,0xc2,0x1e,0x2f,0xb0,0x39 +,0xef,0xcc,0xad,0xc4,0xd2,0xa4,0x43,0x43,0xa6,0xde,0xe5,0xb1,0xa7,0xb1,0x7c,0xa5,0xbc,0x3e,0xaf,0x3a,0x33,0x29,0x1f,0x16,0x1a,0xbe,0x1a,0xdf,0xa3,0x28,0xb1,0xa2 +,0xae,0x71,0xa9,0xa0,0x46,0xcd,0xa4,0x3f,0xdd,0xaf,0x7b,0x54,0xbf,0xa2,0x31,0x44,0xab,0x23,0x3e,0x4c,0x31,0x32,0x1e,0x1d,0x1f,0xd7,0x24,0xe0,0x9c,0xc0,0x9f,0x9e +,0xae,0xb1,0xc2,0xa6,0x43,0x2b,0xb1,0x33,0x3a,0x47,0x4a,0x79,0xf0,0xa7,0xfc,0x40,0xb5,0x2d,0x35,0x53,0x46,0x43,0x35,0xc0,0x3e,0x40,0xb0,0x31,0x53,0xc9,0xba,0xd1 +,0xdf,0xa3,0x3c,0xd8,0xb2,0x37,0x38,0x47,0x5d,0x34,0x37,0xb3,0x3e,0x65,0xac,0xca,0xc2,0xb5,0xaa,0x5c,0x4a,0xae,0x33,0x34,0xc4,0x2d,0xba,0xdd,0x3b,0xbf,0x32,0x45 +,0xdf,0x34,0xfa,0x3a,0x28,0xc9,0x36,0x3d,0xd0,0xc1,0xb0,0xce,0xa5,0xbe,0xfa,0xab,0xde,0xb8,0xcb,0x51,0x48,0x33,0xe0,0x52,0x44,0xe6,0x5e,0xc7,0xca,0x62,0x34,0x37 +,0x3f,0x37,0x3c,0xc8,0x74,0xe5,0xac,0x48,0xaa,0xc1,0xfc,0xb4,0x47,0xd3,0xd0,0x5e,0x47,0x2f,0x53,0x29,0x3e,0xaf,0x1e,0xae,0xbb,0x2e,0xb1,0xc4,0xba,0xdb,0xb2,0xad +,0x3a,0x71,0x5f,0x2e,0xd7,0xc5,0xd3,0xcd,0xbb,0xb0,0x49,0x6c,0xc5,0x34,0x66,0x62,0x3c,0x39,0x38,0x46,0x4d,0xdd,0xb9,0xbb,0xf7,0xbe,0xfd,0x3b,0xee,0xd8,0x5c,0x63 +,0xe7,0x67,0x4b,0x44,0x3f,0x50,0xc5,0xd0,0xd0,0xb8,0xee,0x60,0x5a,0xfe,0xc3,0xde,0xfa,0x67,0x48,0x3f,0xd1,0x43,0x44,0xc6,0xbf,0x5c,0x62,0xbe,0x43,0x57,0xfb,0x4b +,0x46,0xc8,0xc3,0x79,0x4b,0x6f,0xd2,0x5b,0xc4,0xcb,0xbc,0xd1,0xf9,0x66,0x39,0x4c,0x4d,0x31,0x5b,0x5e,0xe2,0xde,0x47,0xb0,0xc6,0xbb,0xb0,0xdc,0xbf,0x43,0x36,0x43 +,0x38,0x75,0x3b,0xf1,0xbc,0x3c,0x5d,0xb1,0x64,0xdd,0xb6,0x58,0x3f,0x4b,0xc2,0x3b,0x4a,0xb6,0x68,0xdb,0xbb,0xf8,0xbe,0xeb,0xce,0x56,0x48,0xc8,0x4e,0xce,0x3d,0x59 +,0xe8,0x37,0x4a,0x4c,0x4a,0xca,0xc3,0xb9,0xdf,0x60,0xbe,0x58,0x55,0xd4,0xc8,0x66,0x58,0x5d,0x3d,0x4a,0x7a,0x49,0xc0,0xc8,0x42,0xdd,0xfe,0x4f,0x7c,0xdb,0xc8,0xd8 +,0x72,0x5a,0x31,0x4a,0xc6,0x76,0xd5,0xc9,0xec,0x76,0xe6,0xc0,0xf5,0xdc,0x3f,0x22,0x1c,0x34,0x99,0x8f,0x97,0xa7,0xb1,0x1f,0x0d,0x13,0x9e,0x8e,0xac,0x21,0x09,0x01 +,0x0d,0x92,0x89,0x28,0x35,0x8d,0x8b,0x4a,0xbb,0x98,0x91,0x96,0x2d,0x17,0x4e,0xdd,0x16,0xcc,0x16,0x18,0xa4,0xce,0x0d,0x0d,0x2d,0x9d,0x9c,0xa2,0xa2,0x26,0xdb,0xd8 +,0x9b,0x8e,0x99,0xc4,0xbf,0x44,0x15,0xd1,0x94,0x35,0x05,0x0a,0x29,0xb7,0xce,0xab,0x8c,0x9a,0x16,0x0c,0x44,0x9e,0xa6,0x9d,0xc2,0xef,0x35,0x21,0x1e,0x11,0x38,0x8b +,0x86,0x8f,0xaf,0x3a,0x22,0x0e,0x1b,0xcd,0x95,0xa7,0x16,0x13,0x0b,0x07,0xcf,0x8c,0xae,0x19,0xa6,0x8b,0x9c,0xa6,0xa3,0x8f,0x98,0x29,0x27,0xbf,0xec,0x2b,0x40,0x23 +,0x0f,0x2c,0xb2,0x1f,0x10,0x2d,0xa4,0x9a,0xb1,0x36,0xa3,0xc5,0x2c,0xa3,0x91,0xa4,0x3d,0xc5,0x4a,0x28,0xcb,0x9b,0xc7,0x0a,0x04,0x1c,0xb9,0xb0,0x9b,0x94,0x9c,0x29 +,0x0f,0x1e,0xa8,0x95,0xa0,0xa6,0xdf,0x1d,0x3f,0xd4,0x1b,0x34,0x90,0x89,0x93,0xb4,0x2f,0x1f,0x1c,0x1e,0x33,0xa7,0xae,0x1b,0x1f,0x18,0x0b,0xd0,0x8e,0xa7,0x20,0x39 +,0x96,0x98,0xa1,0xa9,0x9d,0xae,0x3f,0x2c,0x36,0xb9,0x43,0x3c,0x1c,0x14,0x26,0x49,0x26,0x26,0x39,0xb4,0xa9,0x35,0x41,0xb7,0xc5,0xae,0x9f,0x97,0x98,0xc7,0x71,0xc6 +,0x48,0xa8,0x99,0xac,0x12,0x06,0x18,0x50,0xb3,0x98,0x93,0x9f,0x56,0x14,0x11,0x37,0x9b,0x9a,0xdd,0x1a,0x13,0x17,0x2f,0x25,0x19,0x91,0x87,0x90,0x9f,0xae,0xcc,0x2f +,0x3f,0x69,0x7b,0x40,0xc0,0x39,0x13,0x18,0x5e,0x96,0x9e,0x39,0x23,0x4f,0x99,0x98,0xac,0xcc,0x45,0x21,0x1d,0x31,0x31,0x2f,0xac,0x1d,0x0d,0x20,0xd8,0xa9,0xb3,0xaf +,0xaf,0xb8,0xb8,0xb7,0xab,0x9f,0x9c,0x9b,0xa8,0xab,0xdc,0x2a,0x37,0x40,0xc5,0xa5,0xe3,0x0e,0x07,0x09,0x18,0xc5,0xdc,0x9c,0x9b,0x49,0x2e,0x20,0xcd,0x98,0x8a,0x8f +,0x3f,0x28,0xcc,0xb9,0x2f,0x40,0xa1,0x98,0x95,0xa2,0x3a,0x28,0x2b,0x3a,0x1f,0x1a,0x19,0x1b,0x20,0x16,0x0d,0x28,0xb3,0xb6,0xb6,0x3e,0xab,0x90,0x86,0x8a,0x9c,0xb0 +,0xbd,0xe0,0x65,0xa9,0x9f,0xb4,0x2a,0x0f,0x0b,0x12,0x33,0xcd,0x3f,0x58,0x29,0x16,0x1f,0x2f,0x37,0x9d,0x9e,0xb3,0xa9,0xaf,0xec,0xda,0x9b,0x98,0x94,0x99,0x2d,0x12 +,0x11,0x27,0xad,0x98,0x96,0xa6,0x7b,0x1f,0x12,0x19,0xd9,0x9b,0xac,0x1c,0x11,0x11,0x17,0xf4,0x36,0x43,0x9a,0x93,0x99,0xac,0xa0,0xaa,0xac,0xad,0x33,0x2e,0xfe,0xac +,0xc0,0x38,0x3a,0x3f,0xcd,0x2f,0x21,0x33,0xae,0x94,0x9f,0x31,0x1b,0x13,0x12,0x3b,0xd2,0xae,0x9f,0xf8,0x1d,0x0f,0x2c,0xad,0x9f,0x97,0x9f,0xb6,0x55,0xa9,0x9f,0x9b +,0x92,0x99,0xab,0x47,0x2a,0x1e,0x1e,0x2d,0x29,0x29,0x1f,0x0c,0x07,0x11,0x17,0x39,0x94,0x8f,0x97,0xa7,0xa3,0xca,0xd0,0x98,0x8e,0x9a,0xc6,0x4e,0x34,0x43,0xb2,0xb1 +,0xea,0x5e,0xbd,0xd0,0x51,0x5e,0x29,0x22,0x16,0x0a,0x0b,0x1a,0x31,0x50,0xa7,0xa4,0x3e,0xbb,0xa3,0xf8,0xad,0x91,0x89,0x8c,0x99,0xae,0x43,0x2d,0xdb,0xa8,0xa4,0xbc +,0x3e,0x18,0x0b,0x0d,0x13,0x1f,0x2e,0x1f,0x0f,0x1b,0x2a,0x34,0x99,0x91,0x92,0x99,0x9e,0x9c,0xba,0xa1,0x9c,0xa1,0x9d,0xbb,0xdd,0x22,0x1a,0x25,0x32,0xad,0xaa,0xb5 +,0xdd,0x2c,0x18,0x12,0x1f,0x26,0x1a,0x23,0x23,0x17,0x3e,0x9d,0x9c,0xa6,0xa2,0x98,0x9a,0x92,0x8f,0x97,0x9c,0xde,0x23,0x17,0x1c,0x33,0xcb,0xb4,0x3e,0x2b,0x1f,0x1d +,0x19,0x14,0x33,0xb3,0xd0,0xcf,0x6c,0x22,0x2b,0xb5,0x9d,0x96,0x96,0x9a,0xd7,0x29,0x2b,0x3f,0xa9,0xa2,0xab,0x4c,0x29,0x3e,0x63,0xa9,0x9e,0xa1,0xac,0x3c,0x21,0x17 +,0x1c,0x27,0x1a,0x1f,0x38,0x1f,0x1b,0x26,0x3c,0xb5,0x9c,0x91,0x96,0x9d,0x9a,0xa8,0xb7,0xaa,0xa5,0xad,0x52,0x34,0x28,0x35,0x5a,0xdc,0x60,0x2a,0x22,0x24,0x32,0x4b +,0x3b,0x2b,0x2e,0x18,0x11,0x1f,0x49,0xa4,0x9e,0x99,0x9f,0xb2,0xac,0xb4,0xad,0xa3,0x99,0x93,0xa4,0xcf,0x3b,0x32,0x66,0xe3,0xb9,0xbb,0x2b,0x16,0x0f,0x0f,0x0f,0x14 +,0x30,0x29,0x1b,0x2f,0xbc,0xa0,0x99,0x8e,0x8b,0x94,0x9b,0xa1,0xa9,0xa7,0xae,0xaf,0x56,0x35,0x27,0x1f,0x24,0x25,0x37,0x51,0x43,0x2b,0x2a,0x2f,0x1f,0x1a,0x36,0x3b +,0x1f,0x2d,0x3f,0xbc,0xa8,0x9e,0x93,0x9a,0xaa,0xb3,0xa7,0x9a,0x9d,0x98,0x9e,0xd5,0x2a,0x1b,0x1c,0x1f,0x3c,0xe1,0x39,0x25,0x17,0x19,0x17,0x12,0x2a,0xbf,0xba,0xbd +,0xbb,0xa1,0xa4,0xa1,0x95,0x93,0x96,0xa3,0xad,0xdd,0x28,0x38,0x46,0x32,0x2a,0x24,0x29,0x2c,0x53,0xab,0xa5,0xaf,0x46,0x31,0x2a,0x1a,0x1f,0x3d,0x32,0x2c,0x2e,0x5f +,0xe9,0x65,0xaa,0x9f,0x9b,0x9f,0xa0,0x9c,0xad,0xab,0xaa,0xbe,0x4b,0x28,0x33,0x2d,0x29,0x3c,0x52,0xfc,0x2f,0x27,0x24,0x1b,0x25,0xc2,0xbe,0xbd,0x5c,0x3c,0x3b,0x28 +,0xea,0xa6,0x9a,0x9c,0xae,0xa5,0xb0,0xc9,0xc5,0xb4,0xa9,0xc2,0xc2,0xc8,0x67,0x7b,0x5d,0xbf,0x3d,0x28,0x28,0x18,0x15,0x1b,0x1c,0x1f,0x1f,0x26,0x36,0x3c,0xab,0x9b +,0x91,0x8c,0x8f,0x91,0x9e,0xaa,0xa6,0xbd,0xae,0x4a,0x28,0x26,0x1d,0x26,0x24,0x2b,0x2b,0x20,0x25,0x1c,0x1c,0x34,0x3c,0x4a,0x55,0x49,0xd6,0x4a,0xc3,0xa6,0x9d,0x93 +,0x98,0x9a,0x9f,0xb6,0xac,0xb3,0xa8,0xa9,0xca,0xcf,0x25,0x1e,0x1a,0x18,0x1f,0x1b,0x1e,0x1a,0x15,0x20,0x2b,0x36,0xda,0xba,0xa5,0xa0,0x9f,0x96,0x93,0x90,0x95,0x9c +,0x9b,0xac,0xc6,0x3f,0x2f,0x2b,0x1d,0x1b,0x18,0x18,0x1d,0x21,0x2d,0x3e,0xcc,0xcb,0x3d,0x7a,0x6d,0xee,0xbf,0xe6,0xc0,0xcd,0x65,0xb8,0xac,0xa0,0xa4,0xaa,0xa0,0xb3 +,0xb8,0xb4,0xbe,0xb3,0xd7,0x41,0x2a,0x26,0x27,0x1f,0x23,0x2c,0x2b,0x32,0x2a,0x24,0x37,0x49,0xbd,0xb0,0xa9,0xa1,0xb7,0xaf,0xad,0xbd,0xad,0xae,0xaf,0xbb,0xd8,0x78 +,0x3d,0x58,0x57,0x33,0x39,0x48,0x50,0x78,0x65,0xc8,0xc3,0xd7,0x54,0x2d,0x32,0x36,0x28,0x2a,0x26,0x32,0x32,0x1f,0x2c,0x4c,0xb3,0xa4,0x9e,0x95,0x97,0x9c,0x9d,0xa6 +,0xa4,0xaa,0xd2,0x5d,0x33,0x2c,0x24,0x21,0x29,0x22,0x26,0x25,0x1d,0x23,0x2d,0x35,0x3f,0x4d,0xdc,0xda,0x7c,0xc2,0xb2,0xa6,0x9e,0x9e,0x9f,0xa1,0xa6,0xb0,0xb6,0xab +,0xae,0xb4,0xce,0x4c,0x44,0x2c,0x28,0x25,0x22,0x25,0x1d,0x1b,0x1d,0x22,0x27,0x29,0x32,0x38,0xd9,0xb4,0xae,0x9d,0x93,0x90,0x93,0x96,0x98,0xa1,0xb2,0xaf,0xcb,0x3a +,0x29,0x1d,0x17,0x16,0x1a,0x1c,0x24,0x34,0x44,0x4c,0xec,0xfc,0xbb,0xb0,0xb5,0xba,0xd9,0xc1,0xd8,0xf1,0xb9,0xb6,0xad,0xb0,0xd8,0xcd,0xc3,0xbd,0xbe,0xb8,0xb9,0x40 +,0x33,0x2c,0x2d,0x3a,0x37,0x53,0xeb,0x43,0x46,0x45,0x41,0x4f,0xe1,0xb8,0xc5,0x5f,0xc1,0xd6,0xc6,0xc1,0xe5,0xd5,0x48,0x54,0x41,0x3f,0x74,0x56,0x59,0x42,0x3e,0x4f +,0xe2,0xbe,0xb2,0xa2,0x9f,0xa9,0xae,0xad,0xbc,0xe5,0xd9,0x3e,0x2a,0x21,0x1e,0x19,0x1b,0x1f,0x23,0x30,0x45,0xc5,0xb4,0xaa,0xa4,0x9f,0x9c,0x9e,0xa6,0xaf,0xba,0xc3 +,0xb7,0xc4,0xc9,0xd7,0x40,0x35,0x2e,0x2f,0x38,0x4a,0x3a,0x3f,0x2e,0x2a,0x26,0x2a,0x38,0x42,0xe7,0x60,0xca,0x69,0xc7,0xaf,0xb2,0xac,0xac,0xaf,0xb1,0xaf,0xb3,0xb3 +,0xae,0xaf,0xee,0x4a,0x3b,0x2b,0x2d,0x2d,0x2c,0x2a,0x29,0x2b,0x29,0x36,0xe4,0xdd,0xad,0xac,0xac,0xa7,0xb2,0xab,0xaa,0xaf,0xbc,0x76,0x3d,0x2f,0x24,0x27,0x29,0x2b +,0x2f,0x38,0xee,0xd6,0xb6,0xa9,0xaa,0xa8,0xac,0xba,0xc8,0x69,0x5f,0xde,0x5e,0xe1,0x4c,0x42,0x47,0x36,0x41,0x48,0x66,0x50,0x3c,0x40,0x39,0x37,0x5e,0x64,0xc2,0xce +,0x5f,0xc9,0xee,0xcb,0xcd,0xb9,0xb5,0xd7,0xc9,0xbd,0xbf,0xb4,0xb7,0xbb,0xca,0x50,0x4a,0x3c,0x32,0x2e,0x2f,0x2e,0x2b,0x29,0x2f,0x32,0x35,0xd2,0xb2,0xaf,0xa5,0xa1 +,0xaa,0xa9,0xa6,0xae,0xb5,0xbe,0xfb,0x37,0x2e,0x28,0x1f,0x2b,0x2b,0x27,0x27,0x3a,0x5e,0xc2,0xb5,0xae,0xac,0xac,0xb9,0xbc,0xb1,0xbd,0xb9,0xd4,0xd7,0x48,0xdc,0x62 +,0xd9,0x5e,0x62,0xcc,0x3d,0x2b,0x2e,0x3e,0x37,0xfd,0x4b,0xc0,0x5f,0x48,0x6a,0xea,0xbc,0xc0,0xaf,0x4c,0x60,0x79,0xd5,0xaf,0xaf,0xaf,0xb7,0xbf,0x5c,0x4e,0x3b,0x41 +,0x33,0x3c,0x38,0x2a,0x2b,0x2c,0x33,0x36,0x44,0xdb,0xaf,0xb9,0xab,0xa7,0xa7,0xaa,0xaf,0xa6,0xec,0xeb,0x3e,0x30,0x2e,0x29,0x44,0x38,0x32,0x33,0x37,0x47,0xec,0xc1 +,0xcb,0xc1,0xd0,0xd3,0xb6,0xca,0xbe,0xbd,0xd8,0xcb,0xed,0xef,0xcf,0xf2,0x4d,0x5d,0x65,0x40,0x42,0x3b,0x3d,0x73,0x6f,0xea,0x53,0x58,0xf7,0xda,0x53,0xca,0xbe,0x4b +,0x76,0xe3,0x5b,0xbe,0xb1,0xaf,0xb2,0xb6,0xb5,0xee,0x5a,0x37,0x3e,0x37,0x29,0x2e,0x2f,0x2f,0x30,0x36,0x63,0xd4,0xce,0xb6,0xb7,0xb3,0xae,0xa9,0xa8,0xad,0xaf,0xbc +,0x5d,0x4f,0x39,0x32,0x32,0x2f,0x2f,0x31,0x38,0x40,0x5e,0xda,0xc9,0xc2,0xdb,0xde,0xbd,0xc2,0xca,0xc2,0xc5,0xd5,0xd8,0xe9,0x64,0xcd,0xd5,0x56,0x43,0x4d,0x4a,0x3d +,0x3f,0x4c,0xd9,0xe7,0xc5,0x73,0x56,0xeb,0x70,0xd6,0xe1,0xc5,0xda,0x57,0x73,0x75,0xc8,0xc2,0xce,0xd2,0xc5,0xc5,0xfb,0x5f,0x5b,0x3f,0x34,0x35,0x33,0x33,0x31,0x3d +,0xee,0xd6,0xd7,0xb5,0xaf,0xb6,0xb2,0xb8,0xaf,0xbb,0xc1,0xd2,0x5b,0x57,0x3b,0x3e,0x34,0x2f,0x33,0x30,0x2f,0x35,0x46,0xd7,0xc9,0xbf,0xbe,0xc4,0xbc,0xb5,0xb6,0xba +,0xc4,0xbf,0xbd,0xcc,0x66,0x46,0x4e,0x4d,0x4c,0x40,0x4c,0x3c,0x39,0x37,0x50,0x58,0x56,0xd4,0xef,0xd7,0xf8,0xde,0xd0,0xc7,0xf4,0xca,0xe6,0xcd,0xbf,0xc8,0xbb,0xbf +,0xbe,0xcf,0xd1,0xd9,0x5f,0x4f,0x3d,0x34,0x32,0x31,0x36,0x37,0x39,0x4f,0x57,0xe6,0xc3,0xb7,0xb5,0xc1,0xb7,0xb1,0xb1,0xbd,0xc8,0xc6,0x5a,0x4b,0x64,0x43,0x4d,0x3e +,0x30,0x3b,0x37,0x44,0x52,0xe3,0xed,0xd9,0xbe,0xcb,0xc1,0xc2,0xc5,0xcf,0xf7,0xc9,0xca,0x57,0x4c,0x5f,0x50,0x4f,0x58,0x52,0x4e,0x58,0x5f,0xfa,0xdb,0xd5,0xbf,0xce +,0xd2,0xfb,0x63,0xc9,0x73,0x6a,0x53,0x46,0x4e,0x40,0xd1,0xce,0xca,0xbc,0x6a,0xd8,0xdb,0x68,0x4d,0x3d,0x3f,0x3f,0x3f,0x4a,0x3c,0x46,0xe4,0xd2,0xc2,0xb9,0xb6,0xb7 +,0xbc,0xc3,0xb6,0xc2,0xc8,0xcf,0x63,0x3a,0x3f,0x44,0x30,0x3b,0x31,0x31,0x2f,0x38,0x52,0x75,0xd4,0xcf,0xbe,0xc8,0xc1,0xb3,0xb4,0xb0,0xb4,0xc9,0xcc,0xc8,0xf7,0x52 +,0x57,0x72,0x47,0x39,0x3c,0x42,0x38,0x3b,0x43,0x4f,0x52,0x50,0x57,0x46,0xdb,0xd7,0xbc,0xbb,0xd3,0xc8,0xcd,0xef,0xcb,0xbf,0xb8,0xbe,0xc4,0xc6,0xda,0xd1,0x6f,0x4b +,0x3c,0x38,0x31,0x39,0x38,0x33,0x3d,0x4e,0x48,0x5b,0xea,0xbe,0xbe,0xbf,0xb7,0xbf,0xbb,0xbf,0xb9,0xcc,0xd9,0xcd,0xdb,0xf9,0x4d,0x32,0x37,0x36,0x3c,0x4b,0x50,0xda +,0x4f,0xfb,0xf7,0xd7,0xbf,0xc2,0xca,0xce,0xe0,0x73,0x55,0xc9,0xc9,0xf3,0xfc,0x54,0x5f,0x48,0xf2,0x79,0xe5,0x7c,0xf5,0xdd,0x59,0x4f,0x53,0xfb,0xda,0xd5,0xfb,0xe1 +,0x48,0x60,0x64,0x64,0xc9,0xc6,0xd5,0xf6,0xdd,0xcf,0xd4,0xc4,0x65,0x47,0x52,0x36,0x45,0x42,0x4f,0x48,0x58,0xe6,0x4f,0xcd,0xbf,0xba,0xbe,0xc5,0xc2,0xcb,0x7e,0x70 +,0x56,0x52,0x53,0x61,0x67,0x3e,0x46,0x46,0x3f,0x4c,0x4d,0x64,0x58,0x4f,0xd7,0xcc,0xbe,0xb3,0xbf,0xc4,0xca,0xdb,0x5a,0x5f,0xbd,0xdf,0x5f,0x4f,0x3c,0x47,0x4f,0x51 +,0x67,0x4a,0x52,0x51,0x4b,0x5d,0x54,0xf1,0xca,0xdd,0xda,0xcc,0xd2,0xe9,0x60,0xbc,0xc5,0xd9,0xd6,0xc6,0xe1,0xf4,0xca,0xcc,0xd5,0x47,0x44,0x3a,0x3b,0x3a,0x3c,0x4b +,0x50,0x46,0x46,0xf9,0x7c,0xca,0xbe,0xb8,0xb4,0xb9,0xc0,0xcb,0xc9,0xec,0xd5,0x6f,0x5d,0x4e,0x3f,0x48,0x42,0x45,0x4d,0x4b,0x47,0x44,0x41,0x49,0xd9,0xc8,0xce,0xc4 +,0xc0,0xc1,0xef,0xcc,0xc6,0xd4,0xd5,0xd8,0x59,0x4d,0x5c,0xe2,0xcf,0x56,0xe1,0x73,0x46,0x41,0x4b,0x4c,0x46,0x6a,0x68,0x4d,0x6e,0xd8,0x67,0xdb,0xc8,0xc3,0xdd,0xdd +,0xdb,0xbe,0xba,0xe7,0xc6,0xc6,0x64,0x3e,0x54,0x50,0x43,0x3f,0x51,0x48,0x3e,0x58,0x4b,0x7d,0xdb,0xcc,0xbb,0x73,0xca,0xc0,0x5e,0xcd,0xd3,0xba,0x56,0x45,0xda,0x4d +,0x5b,0x53,0xea,0xdf,0x49,0x49,0x47,0x6d,0x56,0xea,0xcb,0xd5,0xcc,0xd0,0xc7,0xd6,0xcb,0xdf,0x5a,0xdf,0x74,0x46,0x40,0x46,0xf3,0x4c,0xd9,0xf3,0x66,0xf8,0x48,0x4e +,0xde,0xce,0x66,0xc6,0xcf,0xe7,0xdb,0xd0,0xcd,0xcb,0xca,0x54,0x6f,0xd9,0xf4,0xf9,0xfb,0x74,0x43,0x49,0x4e,0x4c,0x3f,0x4b,0x3c,0x40,0x51,0x57,0xdb,0xc6,0xc8,0xd9 +,0xb3,0xc5,0xc1,0xbf,0xcd,0xc3,0xd3,0xbe,0xe0,0x51,0x4c,0x3b,0x46,0x3d,0x48,0x43,0x40,0x42,0x39,0x43,0x5e,0xcd,0xc5,0xc0,0xbd,0xc6,0xcd,0xca,0xc9,0xc6,0xd0,0xea +,0xdc,0x57,0x47,0x56,0x4f,0x67,0x5b,0xfd,0x4a,0x4f,0x6f,0x3e,0x4a,0xe4,0x6a,0x5e,0x5d,0x61,0xcf,0xc8,0xd1,0xc7,0xb9,0xc4,0xfd,0xd3,0xe1,0x62,0xc6,0xd2,0x4a,0x54 +,0x66,0x52,0x6d,0x3b,0x4a,0x3d,0x42,0x3c,0x4f,0xd3,0x58,0xc2,0xe0,0xb8,0xba,0xbd,0xcf,0xc6,0xd8,0xe2,0xde,0xf6,0xd4,0x48,0x4e,0x4d,0x4c,0x57,0x48,0x3b,0x40,0x40 +,0x4d,0x4f,0xcb,0xbd,0xc5,0xde,0xd2,0xc0,0xcc,0xb8,0xbb,0x57,0x54,0x47,0x3f,0x4b,0xeb,0xda,0x5a,0xdc,0x60,0x56,0xce,0x4f,0x46,0xeb,0x66,0x7c,0x6d,0xde,0x47,0xea +,0xbe,0xd7,0xde,0xba,0xc6,0x3d,0x51,0xe6,0x5e,0xea,0xc2,0x52,0x3f,0x51,0x5b,0x4f,0xca,0xd1,0x47,0x62,0x4d,0x44,0x75,0xcd,0xce,0xcc,0xbd,0xcb,0xeb,0xc3,0xce,0x4e +,0xf5,0xf3,0x5a,0x51,0x44,0x50,0x3c,0xef,0xd7,0x43,0x41,0x4f,0xd4,0xe5,0xd0,0xcc,0xd5,0xc7,0x61,0x6b,0xd7,0xc2,0xb9,0xcc,0xe2,0x49,0x4d,0x73,0x67,0x60,0xcc,0xd9 +,0x4b,0x49,0x45,0xf8,0xd3,0x46,0x3a,0x4d,0x7d,0x45,0x3f,0x52,0xc2,0xbf,0xe5,0xcb,0xbc,0xcf,0xd9,0xc9,0xc7,0xbb,0xc9,0xdc,0xcf,0x48,0xdd,0xbe,0x3c,0x5b,0xec,0x2f +,0x32,0x5c,0x35,0x34,0x5e,0x5d,0x46,0xe8,0xbf,0xd0,0xbc,0xbb,0xd1,0xc5,0xce,0xca,0xc2,0xde,0xc3,0x5f,0xc9,0xca,0x49,0x56,0x45,0x3f,0x60,0x6a,0x43,0x45,0x4c,0x39 +,0x3a,0x59,0x7e,0xc2,0xbf,0xcc,0xe7,0xd6,0xc7,0xc4,0xca,0xc7,0xc3,0x49,0x6f,0xde,0x7b,0xc8,0xda,0xde,0x36,0x50,0x4e,0x3c,0xec,0x44,0x5b,0xe4,0x71,0xf7,0x49,0xda +,0xd6,0x5d,0xc2,0xbe,0xe4,0xfb,0xcf,0x68,0xd3,0xf5,0xc9,0xdc,0x6a,0x5b,0x5a,0xf4,0x42,0x50,0xf2,0xe3,0x54,0xd2,0xeb,0xfe,0xea,0x56,0x46,0x56,0x61,0x4a,0xeb,0x69 +,0x59,0xec,0xdb,0xcc,0xda,0xdd,0xbb,0xde,0xd1,0xd3,0x5b,0xe7,0xf4,0x55,0x53,0xbe,0x58,0x66,0xca,0x4e,0x4a,0xff,0xdd,0x42,0x4c,0x53,0x4a,0x6d,0x5a,0xcc,0xe6,0x59 +,0xc4,0x56,0x6e,0xd6,0xd0,0xcf,0xd6,0xda,0xdf,0xda,0xf2,0xfd,0x6c,0xd9,0x7a,0xd4,0xef,0xdd,0x68,0x4c,0x67,0x4c,0x62,0x59,0x51,0x4d,0x4a,0x4c,0x5e,0x62,0x5d,0x60 +,0xd4,0xc8,0xc4,0xd8,0xbf,0xba,0x62,0xd3,0xe5,0xf4,0x47,0x6a,0x6c,0x6f,0xc9,0x76,0xd5,0xde,0x48,0x7a,0x6d,0x4c,0x6e,0x42,0x4e,0x49,0x52,0x47,0x68,0xd0,0xe7,0xfc +,0xd1,0xd3,0xc3,0xc7,0x78,0x5d,0xee,0xc8,0xef,0xd4,0xce,0xcd,0x6d,0xc5,0xe5,0x5c,0xe5,0x56,0x4f,0x48,0x56,0x56,0x48,0x4d,0xdf,0x4c,0x79,0xdf,0x54,0xbf,0xd0,0xde +,0xf9,0xd5,0xc4,0xf9,0xc8,0xe8,0xd9,0x5d,0xd5,0xd7,0xeb,0x53,0x4e,0x78,0x47,0xc2,0x44,0x7d,0xe1,0x34,0x4d,0x59,0x3f,0x51,0x45,0xca,0x6b,0xcc,0xcd,0xde,0xb4,0xbf +,0xde,0xd4,0xc2,0xf7,0xe3,0xcb,0x6e,0x63,0xda,0x52,0x61,0x51,0xa8,0xd7,0xc8,0x26,0xcc,0xcd,0xaa,0x34,0x27,0xdd,0x03,0x0e,0x07,0x4c,0x3e,0x1a,0xbf,0x17,0x99,0x92 +,0xa5,0x94,0x94,0xab,0x9d,0x8d,0x94,0x7b,0x94,0x9e,0x6a,0x8f,0x0c,0xb9,0x86,0x9a,0xa6,0x9b,0xd8,0x1a,0x1e,0x0d,0x0c,0x06,0x0a,0x07,0x0d,0x09,0x0c,0x09,0x11,0x0e +,0x0d,0x2d,0x13,0x17,0x36,0xaf,0x2f,0xaf,0xa8,0xa2,0x9f,0x96,0x91,0x99,0x91,0x9c,0x8c,0x88,0x8d,0x8e,0x87,0x85,0x86,0x81,0x86,0x87,0x87,0x9e,0xa5,0x93,0x8c,0x2a +,0x1f,0x37,0x0c,0x2e,0x0e,0x06,0x08,0x03,0x03,0x0d,0x08,0x04,0x05,0x00,0x19,0x05,0x01,0x07,0x0d,0x18,0x1d,0x53,0xb2,0x3b,0xaf,0x8c,0x90,0x82,0x8a,0x86,0x8a,0x85 +,0x83,0x89,0x88,0x84,0x89,0x90,0x8b,0x96,0x8d,0xa8,0xb7,0x27,0x2f,0x28,0xd5,0xc2,0x27,0x1c,0x18,0x1f,0x1b,0x1d,0x17,0x10,0x0e,0x11,0x11,0x22,0x0f,0x0d,0x0e,0x0b +,0x0f,0x0e,0x11,0x0b,0x1d,0x26,0x24,0x39,0x17,0x37,0x48,0x2e,0xd2,0xa7,0x70,0xbf,0xa2,0x8c,0x8b,0x8b,0x83,0x85,0x87,0x83,0x86,0x87,0x87,0x82,0x85,0x90,0x8c,0x9d +,0x9d,0xcd,0x20,0x1f,0x1a,0x0f,0x01,0x07,0x10,0x06,0x06,0x08,0x04,0x02,0x0d,0x18,0x36,0x14,0x1d,0x10,0x0e,0x2f,0xaf,0x9a,0x35,0x9d,0x4f,0x92,0x97,0xac,0x99,0x9a +,0x86,0x8c,0x9e,0x9a,0x8d,0x8f,0x93,0x8d,0xa5,0x9f,0x98,0x96,0x95,0x8f,0x98,0xca,0x9e,0xa3,0x9d,0xa2,0xab,0xb6,0xa9,0x22,0x27,0x25,0x1b,0x1f,0x07,0x04,0x0c,0x0d +,0x0c,0x0b,0x07,0x00,0x08,0x0f,0x0e,0x0d,0x0e,0x0c,0x0a,0xa3,0xae,0x8e,0x8a,0x95,0x89,0x87,0x89,0xa4,0x86,0x85,0x8f,0xb5,0xaf,0x80,0x8b,0x97,0x91,0x42,0x98,0x8b +,0x91,0x95,0x37,0xb8,0x48,0x0e,0x20,0x29,0x22,0x1f,0x2f,0x26,0x08,0x0e,0x2b,0x5a,0x0f,0x1d,0x0d,0x13,0x1a,0x0e,0xa4,0x25,0x06,0x0e,0x1e,0x0a,0x10,0x24,0x18,0x29 +,0x0f,0x18,0x32,0x29,0xdf,0xaf,0x93,0xa5,0x9e,0x91,0x80,0x88,0x86,0x85,0x84,0x86,0x92,0x85,0x86,0x8c,0x41,0xd5,0xab,0x8f,0xaa,0x13,0x1e,0xb3,0x1d,0x18,0x2b,0x0b +,0x0e,0x08,0x15,0x0a,0x06,0x2d,0x02,0x18,0x18,0x0e,0x29,0x1c,0x98,0x18,0x1d,0x48,0xd9,0xb9,0xad,0x9f,0x1b,0xab,0x1b,0x2c,0x8f,0x9b,0x95,0x6d,0x2e,0xb6,0x93,0x9b +,0x89,0x89,0xbc,0x2b,0x9f,0x88,0x8e,0x90,0x8f,0x88,0x8c,0x8d,0xc8,0x2d,0xa3,0x88,0xa6,0x20,0x2a,0x1e,0x40,0x0b,0x19,0x0c,0x11,0x0e,0x0b,0x13,0x07,0x0b,0x04,0x08 +,0x0a,0x09,0x0e,0x29,0x29,0x2e,0x39,0x8e,0x97,0xa6,0xcb,0x30,0x90,0x93,0x85,0x87,0x8d,0x9e,0xc7,0xa0,0x91,0x85,0x9e,0xa4,0xa8,0x38,0x91,0xa9,0x57,0x3a,0xa4,0x1c +,0x1f,0x9b,0x5c,0x9a,0xae,0x9e,0x93,0x92,0x9b,0x35,0x9e,0xd7,0x3a,0x1d,0x2c,0xf4,0x08,0x08,0x1a,0x15,0x05,0x0a,0x04,0x0e,0x0d,0x0c,0x0b,0x16,0x0d,0x0f,0x24,0x16 +,0x47,0xa4,0x87,0x9e,0x8b,0x8e,0x92,0x83,0x8e,0x8b,0x84,0x88,0x8c,0x9b,0x92,0x9a,0x9f,0x98,0xb7,0x43,0x34,0xa4,0x43,0x1c,0x0c,0x1d,0x18,0x12,0x0f,0x2d,0x0d,0x18 +,0xad,0x38,0x23,0x24,0x9b,0x2d,0xb2,0x20,0xaf,0xc4,0x1f,0x97,0x48,0x22,0x1e,0x1c,0x21,0x11,0x15,0x12,0x1b,0x2d,0x2f,0x0b,0x0d,0x41,0x1b,0x29,0x35,0x1d,0xad,0x97 +,0x95,0x8f,0x8f,0x96,0x8c,0x88,0x8c,0x8b,0x8a,0x8b,0x89,0x83,0x9c,0x9c,0x97,0x98,0x2f,0xea,0x34,0x1e,0x1d,0x13,0x14,0x03,0x09,0x0d,0x08,0x07,0x0c,0x1f,0x17,0x11 +,0x19,0x1f,0xbe,0x1b,0x34,0x6d,0x9f,0xbc,0x9a,0x9c,0x19,0x9e,0xad,0xb4,0x9d,0xa2,0x35,0xa0,0xa2,0x3a,0xa8,0xa5,0x3c,0xb2,0x90,0x39,0xa1,0xb4,0xa3,0x8f,0x96,0x96 +,0xbe,0x9c,0x9b,0x8c,0x90,0x97,0xa8,0xe4,0xa2,0xc1,0x2e,0x2d,0x37,0x1d,0x1f,0xcc,0x13,0x0d,0x1a,0x13,0x0d,0x11,0x06,0x13,0x11,0x0d,0x1e,0x28,0xbb,0x1b,0x39,0xb8 +,0xac,0xb7,0x9d,0x41,0x94,0xa1,0xbd,0x97,0xa9,0xac,0x9f,0xa9,0x2d,0x99,0x32,0xaa,0x97,0xa3,0xb8,0x4a,0x50,0x25,0x93,0x9b,0xbd,0x95,0x94,0x9d,0xa3,0x95,0x9b,0x9b +,0x97,0x77,0xa6,0xb2,0x10,0xa5,0xc2,0x3c,0x0c,0x1a,0x0e,0x0b,0x38,0x0b,0x17,0x13,0x0d,0x09,0x14,0x0a,0x0e,0x1c,0x0d,0x1d,0x9b,0xdd,0xbc,0xb3,0x2a,0x99,0xa2,0x92 +,0x8f,0x8d,0x86,0x97,0x8f,0x94,0x8f,0x89,0x9a,0x96,0x9c,0xa6,0x93,0x4c,0x21,0x35,0x57,0x12,0x15,0x15,0x24,0x18,0x11,0xb2,0x17,0xb4,0x2c,0xca,0xa8,0xb4,0xdb,0xa5 +,0x36,0x4a,0x95,0x22,0x9e,0x19,0x0e,0x3e,0x1a,0x17,0x1d,0x36,0x1b,0x14,0x23,0x1b,0x0b,0x1c,0x1a,0xae,0xb8,0x1e,0xaa,0x9b,0x8a,0x9f,0x96,0xab,0x8c,0x8c,0x8d,0x93 +,0x9b,0x89,0x8e,0x9e,0xd0,0xae,0x2a,0x9f,0x3e,0xc9,0x59,0x0e,0x2a,0x2d,0x19,0x0c,0x0c,0x15,0xbc,0x16,0x18,0x33,0x14,0x4f,0xaa,0xb8,0x2e,0x9c,0x9c,0x9f,0x9a,0x9f +,0x2e,0x9e,0xa6,0x1f,0x22,0x1d,0x26,0x1d,0x40,0x1b,0x0e,0x21,0x14,0x11,0x2c,0x0f,0xb1,0x44,0x41,0x8e,0xa7,0x94,0x8d,0x8d,0x8f,0x97,0x85,0x88,0x8e,0x93,0x8a,0x8c +,0x96,0xb2,0x4a,0x9f,0x1b,0x5f,0xbb,0x0d,0x17,0x13,0x08,0x10,0x0a,0x07,0x0f,0x18,0x07,0x0c,0x3d,0x2a,0x0f,0xb5,0x45,0x38,0x90,0xa8,0x99,0x97,0x8e,0x9d,0x8c,0x8e +,0xbf,0xa5,0xb7,0x9c,0xa9,0xb7,0xad,0x1b,0x42,0xae,0x1f,0x20,0x59,0x21,0x17,0x28,0x34,0x97,0x3e,0xc8,0x65,0x58,0xb1,0xa0,0x9d,0xa7,0x9b,0x93,0xa4,0x5a,0x9a,0x23 +,0xb1,0xd3,0x25,0xc1,0x48,0x2a,0x1d,0x0f,0x1c,0x27,0x12,0x12,0x1b,0x11,0x2d,0x44,0x1e,0x3d,0xcd,0xad,0x76,0x9f,0x2d,0xae,0x9d,0xb7,0x9b,0xbd,0xa7,0xbf,0xa9,0xb9 +,0x3a,0xaf,0x45,0x64,0xb3,0xa7,0x3b,0x4b,0xa6,0xc8,0x15,0x36,0xab,0x99,0x9b,0x91,0xe0,0x5f,0x8c,0x48,0x9a,0xaa,0xaa,0xb3,0x4c,0xcb,0x28,0x29,0x1f,0x1b,0x14,0x17 +,0x28,0x18,0x1a,0x0b,0x0f,0x21,0x0e,0x19,0x1c,0x19,0x59,0x33,0xdc,0x9c,0xa2,0x9f,0xb7,0x92,0xa6,0x99,0x93,0x8f,0x9e,0x9b,0x8e,0x9f,0x95,0xaa,0xa1,0xae,0xc3,0xb4 +,0xc1,0xa7,0x22,0x17,0x16,0x2b,0x17,0x09,0x16,0x0c,0x3e,0x1f,0x2b,0xe7,0x2c,0xe9,0xa0,0xa4,0xa4,0xa4,0xa1,0x9d,0x9e,0x97,0xac,0xae,0x19,0x6b,0x3f,0x28,0xcd,0x2b +,0x1d,0x1f,0x35,0x1d,0x24,0x27,0x14,0x24,0x25,0x53,0x9c,0x20,0xe7,0x5c,0xa0,0x9c,0x9c,0x93,0xbf,0x8e,0x92,0x9c,0x9f,0xc7,0xab,0x9c,0xd9,0x6f,0xbb,0x48,0x4c,0x35 +,0x1b,0x17,0x1b,0x21,0x18,0x17,0x21,0x1e,0x2b,0xaf,0x9c,0xbf,0xbe,0x27,0xbe,0x99,0x99,0x9c,0xa5,0x96,0xa6,0xa6,0x35,0x38,0xbc,0x2b,0x36,0x38,0x2b,0x1a,0x1e,0x20 +,0x1d,0x1d,0x13,0x10,0x1e,0x33,0x63,0xa9,0xbc,0xaf,0x9c,0xa4,0xa9,0x95,0x8c,0x8e,0x90,0x94,0xa2,0xa2,0x95,0xa2,0xc4,0x33,0x34,0x3f,0x2b,0x26,0x25,0x1c,0x1b,0x1b +,0x11,0x11,0x1a,0x24,0x1f,0x43,0xb7,0x6d,0xcb,0xab,0xab,0xae,0xa0,0x9c,0x9e,0x99,0x95,0x9f,0xcc,0xc1,0x5f,0x57,0xe8,0x2c,0x38,0x2f,0x24,0x1d,0x1c,0x17,0x14,0x0b +,0x11,0x21,0x23,0xc6,0x47,0x3d,0xcd,0xb9,0xaf,0xa4,0x98,0x97,0x97,0x99,0x97,0x9b,0x9d,0x9d,0xae,0xd9,0x23,0x38,0x3f,0x6b,0x63,0x23,0x17,0x17,0x18,0x0f,0x0e,0x1d +,0x36,0x1d,0x3c,0xfd,0xbc,0xa1,0xa5,0xa2,0xad,0x9f,0x9b,0x98,0x90,0x99,0x9d,0xac,0xab,0xc9,0x49,0x43,0x34,0xd5,0x22,0x20,0x1d,0x1a,0x10,0x19,0x16,0x16,0x22,0x1e +,0x4e,0x40,0xc9,0xb5,0xa5,0x9d,0xa1,0x96,0x9b,0x9f,0x9e,0x9c,0x93,0x9a,0x9e,0x3a,0x2a,0x45,0x39,0x57,0x34,0x2e,0x1c,0x1e,0x1d,0x1c,0x15,0x13,0x19,0x2a,0x37,0xc1 +,0x9c,0xa1,0xa9,0xc7,0xaa,0x9a,0x92,0x98,0x99,0x97,0x98,0xa5,0xa8,0x9e,0xd9,0xfa,0x28,0x32,0x4c,0x2e,0x1f,0x1c,0x1f,0x10,0x17,0x0e,0x16,0x28,0x24,0x2d,0x40,0xad +,0xe1,0x9e,0xa2,0xab,0x9e,0xa1,0x9e,0x9a,0x95,0x98,0x9a,0xa1,0xb9,0x2f,0x4d,0x4a,0x35,0x20,0x30,0x30,0x1f,0x1f,0x12,0x13,0x10,0x1b,0x23,0x4f,0xbd,0xd7,0xbf,0xd0 +,0x9f,0x9d,0x9f,0xa0,0x9b,0x97,0x96,0x9a,0xcf,0xa6,0xad,0x35,0xb4,0x3c,0x1d,0x22,0x40,0x2a,0x1c,0x1d,0x16,0x18,0x16,0x12,0x29,0x3f,0x3e,0xae,0xb4,0xa5,0x95,0x9b +,0xaa,0x9d,0x97,0x9c,0x97,0x8f,0x99,0x75,0x5f,0xb1,0xf2,0xba,0x33,0x1e,0x21,0x26,0x3c,0x1f,0x1a,0x1b,0x0f,0x0d,0x20,0x39,0x3f,0x5c,0xbf,0xbb,0xb4,0xab,0x9d,0x9f +,0x9d,0x97,0x9f,0x9f,0x9a,0x9d,0xb6,0xaf,0x55,0x3f,0x5b,0x3f,0x2c,0x1d,0x35,0x35,0x25,0x16,0x15,0x11,0x16,0x2a,0x24,0x57,0xc8,0xb9,0xb5,0xae,0xac,0xb9,0x96,0x9a +,0x9a,0x99,0x99,0x9f,0xa3,0x9f,0x39,0x6a,0x29,0x32,0xba,0x2b,0x25,0x2a,0x19,0x18,0x19,0x16,0x14,0x17,0x20,0x2c,0x40,0xc2,0xa0,0xc0,0xa4,0x98,0x9a,0x9a,0x98,0x99 +,0x97,0x93,0x9d,0x9f,0xab,0xb4,0x3d,0x4c,0x34,0x40,0x27,0x1d,0x21,0x19,0x1e,0x19,0x13,0x0d,0x16,0x2e,0x4d,0x3f,0x45,0xae,0x9c,0xa5,0xab,0xae,0x9e,0x90,0x93,0x9c +,0x9b,0xa0,0xa2,0xc3,0x30,0xbd,0x2d,0x3f,0x47,0x1c,0x1f,0x2a,0x1d,0x1c,0x15,0x0b,0x18,0x5d,0x38,0x40,0xa9,0xb8,0xba,0xa2,0xa1,0x9e,0x9c,0x9a,0x9c,0x93,0x96,0xc2 +,0xae,0xa6,0xef,0x37,0x2f,0x30,0x31,0x2e,0x1e,0x24,0x29,0x1b,0x11,0x0e,0x1d,0x33,0x2e,0x3d,0x44,0xb8,0xc0,0xaa,0xa5,0xbe,0x97,0x9b,0xa7,0x99,0x97,0x95,0x9b,0xba +,0xb9,0xc9,0x4e,0x49,0x25,0x25,0x5a,0x3c,0x2b,0x1f,0x15,0x12,0x13,0x2a,0x26,0x24,0x4a,0xd4,0xc7,0xac,0xa7,0xa6,0xa2,0xa0,0x99,0x9d,0x9e,0xa3,0xa2,0x9d,0xa2,0x39 +,0x25,0x3d,0x56,0xbc,0x31,0x20,0x1d,0x1e,0x18,0x23,0x1a,0x13,0x1f,0x1a,0x22,0xca,0xa5,0xc9,0xa7,0xa5,0xb9,0xa6,0x94,0x9a,0xa5,0x98,0x94,0x9a,0x9e,0xac,0x3f,0x3e +,0x2f,0xbb,0x4b,0x2b,0x1e,0x1b,0x21,0x2b,0x1d,0x0c,0x0f,0x19,0x41,0x52,0xb7,0xba,0xb8,0xb2,0xaf,0x9e,0xa5,0x98,0x95,0x9c,0x97,0x9c,0xb1,0xbf,0x59,0xac,0xbc,0x41 +,0x1e,0x1f,0x2b,0x1f,0x2c,0x24,0x18,0x14,0x16,0x10,0x15,0x27,0xc4,0xaa,0xa1,0x9d,0xae,0xae,0xa1,0x9c,0x93,0x98,0x93,0x9e,0xab,0x9a,0xa5,0xa3,0xcf,0x1c,0x23,0x3d +,0x26,0x25,0x20,0x1d,0x1e,0x16,0x0b,0x16,0x18,0x1e,0x45,0xba,0xa4,0xb1,0xb6,0xb0,0xa0,0x98,0x92,0x9d,0x97,0x92,0xa0,0xa1,0xa7,0xd0,0xbb,0xd3,0x2c,0x21,0x2b,0x2d +,0x2a,0x29,0x1f,0x12,0x10,0x18,0x15,0x1d,0x30,0xc3,0x5b,0xac,0xa6,0xa1,0x9f,0xae,0x94,0x8f,0x99,0x9d,0xa1,0x9f,0x94,0xac,0x4a,0xcb,0x3c,0x27,0x26,0x4a,0x2c,0x1e +,0x1d,0x1a,0x16,0x0e,0x0f,0x16,0x3f,0x5b,0x64,0x54,0xb6,0xa8,0xb1,0x9d,0xa3,0x9b,0x91,0x90,0x9e,0x9b,0xa4,0xb1,0xae,0x41,0x62,0x2f,0x2e,0x57,0x1f,0x2a,0x1c,0x12 +,0x1d,0x10,0x18,0x1d,0x1e,0x28,0x3f,0xc0,0xa0,0x9a,0xa8,0xab,0x9c,0x9a,0x99,0x92,0x98,0x9d,0x9f,0x9b,0xb4,0x41,0x41,0x28,0x28,0x20,0x23,0x1d,0x26,0x1c,0x16,0x17 +,0x0e,0x17,0x19,0x26,0xd9,0xe2,0xb9,0xad,0x9b,0x9a,0x9d,0x9b,0x9c,0x91,0x93,0x94,0xa3,0x9f,0xa4,0x4d,0xbc,0x50,0x37,0x26,0x24,0x21,0x1f,0x1c,0x1a,0x1d,0x15,0x16 +,0x1d,0x1f,0x26,0x51,0xaa,0x9a,0xb6,0xac,0xa0,0x9c,0x9b,0x9d,0x96,0x9d,0x9b,0xa5,0xad,0xc0,0xcd,0xbe,0x3a,0x1b,0x24,0xef,0x20,0x1f,0x24,0x17,0x14,0x17,0x1b,0x1e +,0x21,0x45,0x3e,0xc1,0x9d,0xa0,0xaf,0xa5,0x98,0x95,0x9c,0x9c,0x96,0x9d,0xa9,0xa5,0xc1,0xc1,0xd1,0x2c,0x2b,0x1e,0x26,0x26,0x23,0x1e,0x1c,0x17,0x14,0x1a,0x1c,0x25 +,0x47,0xae,0xba,0xaa,0x9e,0xa4,0x9c,0x9d,0x9b,0x9d,0xa3,0x9c,0x9b,0x9c,0xb5,0xb9,0x2f,0x25,0x28,0x2a,0x3a,0x2a,0x2f,0x1c,0x1f,0x14,0x0f,0x16,0x26,0x24,0x2a,0x76 +,0xb4,0x9a,0xa9,0xa4,0xa3,0x94,0x99,0xa0,0x98,0x93,0x96,0x9f,0xb0,0xc5,0xc0,0x3c,0x2a,0x21,0x24,0x24,0x3f,0x1f,0x1b,0x14,0x0e,0x17,0x20,0x1c,0x1d,0x54,0xc4,0xd7 +,0xae,0xa5,0x9e,0x97,0xab,0x99,0x99,0x93,0x91,0xa1,0xa1,0xaa,0xaf,0x4e,0x31,0x2f,0x38,0x1b,0x28,0x2b,0x1e,0x29,0x14,0x0d,0x12,0x28,0x20,0x2a,0x35,0xee,0xb0,0xa3 +,0x9b,0x98,0x99,0x9e,0x9b,0x9b,0x95,0x9a,0xa3,0xaf,0xad,0xa7,0x60,0x28,0x20,0x1d,0x20,0x29,0x2d,0x1c,0x1a,0x11,0x10,0x20,0x25,0x37,0x2e,0x39,0xee,0x9e,0xa2,0xb1 +,0x9b,0x98,0x98,0x96,0x93,0x9e,0x9d,0xa1,0xaf,0xa9,0xac,0x38,0x25,0x22,0x21,0x24,0x1f,0x1f,0x22,0x1b,0x0f,0x16,0x22,0x1d,0x1e,0x41,0xc1,0xad,0xbb,0xb2,0x98,0x8f +,0xa0,0xad,0x9a,0x8f,0x97,0x9f,0x9d,0xab,0xb5,0x2c,0x2f,0x33,0x3b,0x3a,0x20,0x1f,0x1b,0x17,0x15,0x1a,0x1e,0x1a,0x1b,0x32,0x38,0xe1,0xb0,0xab,0x99,0xa1,0xa5,0x9a +,0x97,0x95,0x9c,0x99,0x97,0xa6,0xc2,0xce,0xe6,0x3f,0x31,0x22,0x19,0x22,0x23,0x15,0x1d,0x19,0x1c,0x1d,0x1d,0x23,0x2f,0xee,0xe5,0xa1,0xa1,0x98,0x9e,0xa3,0x9c,0x98 +,0x96,0x98,0x9c,0x9f,0xac,0xd8,0xd3,0x2f,0x37,0x2b,0x29,0x2c,0x1e,0x14,0x1f,0x1b,0x1f,0x1c,0x17,0x1c,0x1a,0x36,0xb3,0xa1,0xaa,0xab,0xa9,0x9b,0x9b,0x9b,0x9b,0x97 +,0x96,0x9c,0xa6,0x62,0xc5,0xc6,0x3f,0x2c,0x2f,0x34,0x1a,0x16,0x1d,0x1f,0x24,0x1d,0x19,0x1f,0x1c,0x1e,0xd6,0xb2,0xb9,0xaa,0xa0,0x99,0x9c,0x9a,0x9f,0x9a,0x93,0x9a +,0x9e,0xad,0xaa,0xca,0x50,0x27,0x2d,0x3c,0x22,0x1d,0x19,0x19,0x1f,0x28,0x16,0x17,0x1c,0x1d,0x3e,0x48,0xaf,0xad,0xbf,0xa3,0x9e,0x9c,0x99,0x9a,0x9a,0x94,0x99,0x9b +,0xb6,0x63,0xc0,0xbb,0x4d,0x24,0x28,0x1d,0x21,0x25,0x1b,0x1c,0x20,0x1b,0x1d,0x1e,0x22,0x35,0x50,0x3b,0xaf,0xa0,0xa5,0xa2,0xa7,0x9b,0x9a,0x9a,0x9c,0x9b,0xa5,0xa1 +,0xa6,0xdc,0x3d,0x40,0x66,0x28,0x26,0x21,0x19,0x1f,0x25,0x23,0x1b,0x1f,0x1e,0x1b,0x2b,0x3a,0x65,0xba,0x9f,0xb4,0xae,0xa4,0xa0,0x9b,0x9f,0x98,0x96,0x9e,0xa6,0xaf +,0xb7,0x54,0x43,0xe0,0x3f,0x24,0x22,0x29,0x18,0x25,0x29,0x28,0x1d,0x19,0x1f,0x23,0x38,0x37,0x39,0xb5,0xad,0xab,0xa6,0xa2,0x99,0x9c,0x99,0x9d,0xa6,0xa1,0xa6,0xab +,0xa9,0xd1,0x34,0x42,0x2c,0x24,0x2d,0x1c,0x29,0x22,0x19,0x1e,0x1c,0x1f,0x2a,0x3c,0x53,0x56,0x33,0x61,0xca,0xae,0x9e,0x9f,0x99,0x98,0x9d,0xa7,0xaf,0x9c,0x9c,0xa2 +,0xbc,0x4c,0x54,0x49,0x29,0x1e,0x2f,0x3b,0x27,0x1a,0x1d,0x25,0x23,0x34,0x26,0x30,0x4a,0x2d,0x6c,0xd0,0xb2,0xb9,0x5a,0xa9,0x99,0x9e,0xa2,0xa9,0xa7,0xaa,0xb2,0xa2 +,0xa7,0xc3,0xdc,0x4d,0x37,0x41,0x31,0x2b,0x2e,0x1b,0x1e,0x34,0x29,0x2b,0x31,0x1e,0x22,0x36,0x36,0xba,0xad,0xbf,0xdb,0xc0,0xb9,0x9f,0x9c,0xa5,0xa2,0xa4,0x9f,0xa0 +,0xb9,0xba,0xaa,0xbf,0xca,0x2b,0x4f,0xce,0x26,0x2a,0x1f,0x25,0x33,0x36,0x2b,0x24,0x25,0x1e,0x23,0x23,0x58,0xb1,0xae,0xc5,0x4a,0xc0,0xbb,0xa6,0xa7,0xa4,0x9c,0xa8 +,0xaa,0xa6,0xac,0xa2,0xb7,0xcf,0x30,0x4c,0x67,0x57,0x3c,0x2d,0x23,0x1c,0x42,0x26,0x28,0x25,0x23,0x2e,0x4d,0x41,0x3d,0x49,0x3e,0xc3,0xac,0xb2,0xa9,0xa7,0xad,0x9c +,0xa5,0xad,0xa9,0xa3,0xc5,0x4b,0xdf,0xcd,0xc4,0x41,0x4e,0x2d,0x2d,0x28,0x28,0x28,0x24,0x2f,0x34,0x3e,0x39,0x36,0x3e,0x3d,0x40,0xb9,0xc2,0xc2,0xaa,0xa3,0xac,0xb5 +,0xbc,0xae,0xa9,0xa7,0xb1,0xc1,0xa1,0xaa,0x50,0x3b,0xcc,0x3a,0x29,0x38,0x43,0x3d,0x36,0x33,0x2d,0x31,0x28,0x2e,0x5b,0x38,0x3c,0x3f,0x48,0xb9,0xd1,0xc8,0xbe,0xac +,0xb6,0xbe,0xc0,0xb3,0xa3,0xc6,0x36,0xe9,0x9a,0xa0,0xaa,0x58,0x1f,0xa7,0x9b,0xd1,0x36,0xee,0x3b,0x1c,0x27,0x30,0x0b,0x01,0x09,0x3e,0x8e,0x44,0x3f,0x90,0xae,0x2a +,0xb4,0x92,0x8f,0x8f,0x91,0x9a,0x9f,0x8d,0x92,0xd9,0x0b,0x0b,0x2f,0xb7,0x1f,0x1e,0x6a,0x11,0x15,0x99,0x8d,0x1d,0xda,0xad,0x26,0x13,0x1e,0x94,0x8f,0xb2,0x0c,0x26 +,0xad,0x2f,0x4f,0xa7,0x2f,0x30,0xaa,0xb4,0x1f,0x0d,0x17,0x2c,0x5e,0x8e,0x81,0x8d,0x31,0x2a,0x26,0x21,0xa5,0x8f,0x8a,0x9f,0x14,0x1b,0x94,0x5f,0x08,0x0b,0x27,0x18 +,0x1a,0x38,0x41,0xbd,0x1d,0x14,0xc8,0x92,0x96,0x95,0x8d,0x9c,0x23,0xc1,0xa8,0xbd,0x49,0x2f,0x0f,0x19,0xb8,0xbe,0x20,0x08,0x0d,0x2e,0xb8,0x13,0x36,0x98,0x35,0x18 +,0xa1,0x8b,0x8e,0x96,0x9c,0x2c,0x14,0xaf,0x8d,0x89,0xb6,0x22,0x4b,0xa7,0xa1,0xb7,0xb3,0x21,0x2f,0xa7,0xd0,0x1d,0x08,0x19,0x1c,0x10,0x45,0x90,0x92,0x36,0x25,0x17 +,0x19,0xb4,0x9f,0x97,0xac,0x2d,0xad,0xac,0xbc,0x2c,0x35,0x3a,0x1e,0x3b,0xb5,0xb1,0x25,0x1f,0x18,0x1a,0xb4,0x90,0x87,0x8d,0xc1,0x21,0x9e,0x95,0xab,0xba,0x3b,0x3d +,0x47,0xbe,0xa0,0x46,0x0b,0x10,0x21,0x5f,0x52,0x2a,0x9d,0xb5,0x21,0x28,0x9a,0x8b,0x90,0xad,0x1c,0x1b,0x1f,0xa8,0x9f,0x36,0x23,0x27,0x27,0x22,0x2c,0x1e,0x28,0x2a +,0x48,0x2a,0x0e,0x22,0x65,0x3b,0x32,0xaa,0x8d,0x83,0x86,0x9a,0x31,0x5d,0x90,0x8d,0x92,0x97,0x5e,0xcc,0xb8,0x1c,0x1c,0x0e,0x0e,0x10,0x0c,0x1a,0x1d,0x1a,0xb9,0x1d +,0x10,0xa7,0x8d,0x88,0x84,0x94,0xa9,0x91,0x9d,0x95,0x96,0x98,0xa4,0xa7,0x9b,0xbe,0x1f,0x16,0x20,0x1c,0x2e,0x1c,0x5a,0x2e,0x15,0x1a,0x04,0x26,0x94,0x25,0x22,0x15 +,0x03,0x23,0x2d,0x1e,0x2b,0x1a,0x13,0x0e,0x1f,0x18,0x0a,0x0f,0x16,0x0f,0x0a,0x09,0x09,0x0f,0x08,0x05,0x0a,0xd5,0x88,0x94,0x8c,0x9f,0x55,0x8b,0x82,0x85,0x82,0x83 +,0x82,0x80,0x86,0x8c,0x8d,0x8a,0x94,0xa3,0xa2,0x9a,0xb5,0xc4,0x1d,0x0a,0x19,0xaa,0x99,0x9b,0x8a,0xe0,0x3c,0x8f,0xcd,0xab,0x8e,0x9f,0x8f,0x86,0x8f,0xbd,0x34,0x34 +,0x1e,0x14,0x1e,0x22,0x0e,0x15,0x09,0x01,0x07,0x11,0x14,0x0b,0x04,0x00,0x0e,0x0e,0x0b,0x3d,0x33,0x18,0xa4,0x9f,0xb3,0x9f,0x9f,0x9d,0x9d,0xa9,0xc3,0x3c,0x37,0x2d +,0x12,0x1c,0x5b,0xaf,0xaf,0xbd,0x16,0x0f,0x22,0x22,0xa7,0x29,0x24,0x8d,0x90,0xdb,0xa6,0xed,0x22,0xad,0xa7,0xa2,0x8f,0x8a,0x8b,0xa0,0x36,0x9d,0x91,0x87,0x83,0x88 +,0x8c,0x8d,0x9b,0x9a,0xa5,0x46,0x88,0x96,0x9e,0x82,0x8c,0xaa,0x8b,0x8e,0xa7,0x87,0x8a,0x9c,0x95,0xbf,0x1b,0x1b,0x2d,0xba,0x0c,0x01,0x04,0x02,0x01,0x02,0x02,0x02 +,0x01,0x00,0x08,0x04,0x03,0x18,0x11,0x01,0x17,0x25,0x0b,0x51,0xb5,0x17,0x22,0x3e,0x9b,0x98,0xa2,0x8f,0xa4,0x43,0xbc,0x32,0x20,0x9c,0x97,0xa3,0x41,0x36,0x8c,0x44 +,0x34,0x88,0x90,0xa5,0x87,0x84,0x94,0x8b,0x8b,0x8d,0x84,0x82,0x81,0x82,0x8c,0x8b,0x9f,0x26,0xa6,0x95,0xab,0xed,0x28,0x43,0x17,0x0c,0x62,0x0e,0x0e,0xba,0x16,0x11 +,0xad,0x4d,0x19,0xb9,0xb2,0x2e,0x55,0x2d,0x51,0x2d,0x0f,0x18,0x19,0x0f,0x16,0x14,0x0c,0x0f,0x08,0x0a,0x04,0x06,0x22,0x0b,0x05,0x2c,0x1d,0x18,0xa6,0x9e,0x93,0x89 +,0x8b,0x8c,0x8e,0xae,0xac,0xb1,0xdf,0x98,0xa2,0x24,0x2e,0x1e,0x08,0x0c,0x0a,0x0f,0x0e,0x13,0x9c,0xda,0xe6,0x8a,0x90,0x8f,0x80,0x80,0x80,0x80,0x83,0x85,0x86,0x89 +,0x83,0x81,0x8c,0x8c,0x8b,0x96,0x95,0x94,0x4d,0x2b,0x1a,0x18,0x0e,0x0a,0x27,0x0e,0x00,0x17,0x1d,0x09,0x1d,0x23,0x11,0x11,0x15,0x1d,0x16,0x0d,0x0c,0x0a,0x04,0x08 +,0x0b,0x04,0x01,0x05,0x04,0x03,0x04,0x04,0x09,0x03,0x2a,0xa6,0x1d,0x9c,0x87,0x9e,0xa7,0x8b,0x8f,0x8f,0x8d,0x8a,0x87,0x89,0x8b,0x8d,0x9e,0xaa,0x8e,0x8c,0x95,0x94 +,0x9b,0xc9,0xca,0x49,0xa5,0xdd,0xa1,0x86,0xad,0xab,0x87,0x93,0xbf,0x89,0x89,0x8d,0x85,0x89,0x88,0x8e,0xa6,0xac,0xc4,0x16,0x15,0x0f,0x06,0x07,0x0b,0x09,0x0b,0x0b +,0x0b,0x0d,0x08,0x5c,0x3c,0x0b,0x6d,0xc9,0x0b,0x1c,0xb7,0x1f,0x2b,0x16,0x11,0x1b,0x13,0x18,0x17,0x0f,0x18,0x24,0x18,0x1f,0x22,0x2b,0xbd,0x68,0x14,0x1e,0x0d,0x08 +,0x50,0x1d,0x19,0x9c,0xa5,0x1f,0xa1,0x96,0xb6,0x9d,0x92,0x94,0x8f,0x8b,0x8b,0x8b,0x96,0x97,0x89,0x88,0x86,0x84,0x88,0x85,0x85,0x93,0x86,0x8c,0x97,0x81,0x87,0x90 +,0x83,0x8b,0xa6,0x8c,0x9e,0x2f,0x2c,0x20,0x1a,0x1a,0x0a,0x07,0x0b,0x05,0x08,0x0f,0x0c,0x06,0x07,0x04,0x06,0x07,0x02,0x04,0x03,0x00,0x0a,0x08,0x01,0x10,0x15,0x05 +,0x16,0x30,0x3c,0xc0,0xc1,0xb4,0x9b,0xa2,0x90,0x8c,0xa6,0x9f,0xa6,0x62,0x6e,0x9e,0x9e,0x96,0x9b,0xba,0xa8,0x99,0xad,0x92,0x89,0xa8,0x9c,0x87,0x94,0x9f,0x8c,0x8e +,0x91,0x8c,0x86,0x86,0x8a,0x93,0x8a,0x8c,0xa2,0x91,0x8b,0xa2,0xad,0xa1,0xb0,0x28,0x20,0x1d,0x13,0x0a,0x03,0x1a,0x18,0x05,0x13,0x35,0x11,0x65,0xa6,0x36,0xbc,0xc7 +,0x36,0xb7,0x21,0x17,0xeb,0x11,0x0a,0x0b,0x0a,0x09,0x0b,0x0b,0x0e,0x0f,0x0c,0x0f,0x26,0x1b,0x09,0xc8,0xbc,0x16,0x9f,0x9d,0x18,0x47,0x3f,0x38,0xa5,0xbe,0xa4,0x97 +,0xbb,0x50,0x97,0xae,0x3f,0xa3,0xab,0xab,0x93,0x93,0x9b,0x9d,0x98,0x8e,0x86,0x8b,0x8c,0x80,0x84,0x8a,0x84,0x81,0x87,0x87,0x84,0x85,0x8a,0x8b,0x8e,0x8f,0xde,0x1f +,0x27,0x0d,0x0b,0x0d,0x07,0x06,0x08,0x0a,0x13,0x0c,0x09,0x0c,0x0d,0x07,0x04,0x10,0x0c,0x02,0x07,0x0e,0x06,0x0c,0x18,0x0b,0x0c,0x1a,0x28,0x55,0x1c,0x18,0xd2,0x28 +,0x29,0x5f,0xea,0x59,0xc2,0xa9,0xb4,0xa3,0x9e,0xa3,0xa1,0x93,0x99,0x9f,0x8c,0x92,0x9f,0x8b,0x93,0x9e,0x8c,0x99,0xab,0x97,0x98,0x8f,0x89,0x9c,0x8e,0x85,0x8c,0x8a +,0x8f,0x9a,0x8f,0x98,0x9b,0x9e,0xa4,0xb0,0x31,0x1a,0x12,0x10,0x13,0x1e,0x0d,0x12,0x39,0x31,0x1b,0x36,0x36,0x3c,0xbf,0xc5,0xb0,0xbc,0x24,0x1e,0x1f,0x0e,0x13,0x15 +,0x0f,0x0b,0x0b,0x0e,0x17,0x17,0x15,0x16,0x13,0x14,0x09,0x0f,0x40,0x15,0x14,0x37,0x2b,0xea,0x9f,0xa3,0xaa,0xa7,0x9d,0x94,0x98,0xae,0xa0,0xa7,0x49,0x4a,0x2e,0x2a +,0x1f,0x45,0xc3,0xcb,0xa9,0x9a,0x9a,0x93,0x89,0x8c,0x85,0x80,0x83,0x83,0x80,0x82,0x85,0x84,0x84,0x85,0x87,0x96,0x98,0x9a,0x2a,0x2e,0x20,0x0c,0x0c,0x0c,0x0b,0x09 +,0x0a,0x0a,0x09,0x0b,0x0a,0x0c,0x0a,0x0b,0x05,0x02,0x0a,0x09,0x05,0x0d,0x0b,0x06,0x0f,0x16,0x1d,0x1a,0x1c,0x21,0x33,0x1a,0x1d,0x74,0x20,0x1f,0x26,0x27,0x4d,0xa3 +,0xa3,0xab,0xa0,0x91,0x91,0x92,0x8d,0x93,0xa2,0x90,0x8b,0x9a,0x9a,0x8e,0x9c,0xa5,0x96,0x9b,0x92,0x92,0x97,0x8e,0x90,0x91,0x89,0x88,0x91,0x91,0x8c,0x90,0x92,0x92 +,0x96,0x9e,0xc1,0x3c,0x3b,0x2c,0x19,0x0c,0x15,0x22,0x12,0x1a,0x40,0x1e,0x18,0x2b,0x2c,0x48,0xbd,0x2c,0x2c,0xd7,0x1a,0x14,0x1b,0x15,0x0f,0x0e,0x14,0x16,0x18,0x1e +,0x15,0x14,0x15,0x17,0x11,0x0e,0x0d,0x12,0x1b,0x0f,0x16,0x26,0x29,0x34,0xbe,0xb2,0xa3,0x9d,0x9a,0x95,0x98,0xa9,0xa2,0xa2,0xb8,0xc6,0xd5,0xbe,0xc6,0xc6,0x9c,0x91 +,0x8f,0x8f,0x8d,0x89,0x89,0x86,0x83,0x81,0x86,0x85,0x81,0x85,0x85,0x85,0x86,0x89,0x93,0x9d,0x99,0xa7,0x33,0x23,0x15,0x10,0x0f,0x0d,0x0c,0x08,0x07,0x06,0x07,0x09 +,0x08,0x06,0x07,0x03,0x03,0x0a,0x09,0x03,0x0c,0x12,0x0f,0x19,0x19,0x21,0x37,0x25,0x21,0x42,0x29,0x20,0x3d,0x28,0x1d,0x1c,0x34,0xa8,0xb6,0xcc,0x9d,0x98,0xa3,0x99 +,0x91,0x8e,0x9d,0x96,0x88,0x97,0xa2,0x8f,0x91,0xa6,0x98,0x96,0x90,0x90,0x9b,0x8c,0x8f,0x97,0x8f,0x8a,0x8c,0x8d,0x91,0x92,0x8e,0x9c,0xa5,0xa5,0x6b,0x39,0xeb,0x2b +,0x1a,0x0e,0x1d,0x12,0x05,0x0f,0x16,0x0a,0x0b,0x1a,0x18,0x45,0x3f,0x35,0xab,0x35,0x40,0xb0,0xd1,0xa9,0x69,0x3a,0x2c,0x37,0x21,0x36,0x2a,0x0f,0x18,0x15,0x25,0x13 +,0x2d,0x26,0x18,0x29,0xc8,0x59,0xbb,0xa9,0xcd,0x99,0xa5,0xab,0x9b,0x9b,0xba,0xa8,0x95,0x96,0xad,0xd4,0xa7,0xb5,0x29,0x47,0x5e,0x24,0x18,0x18,0x1b,0x11,0x29,0x3b +,0x20,0x52,0x9f,0x9b,0x9d,0xa5,0x99,0x8b,0x9a,0xa2,0x97,0xa1,0x3e,0xbf,0xa5,0xad,0xed,0x20,0x29,0x2d,0x31,0x3f,0x2a,0x18,0x18,0x21,0x1c,0x16,0x4c,0x2f,0x14,0x30 +,0x3a,0xc0,0xa1,0x9e,0x9d,0x93,0x92,0x8e,0x8a,0x94,0x95,0x9c,0xb2,0xa2,0xbd,0x39,0x49,0x21,0x29,0xcb,0x3d,0x25,0x23,0x2f,0x33,0x42,0xaa,0xde,0x25,0xc7,0xc9,0x32 +,0xb0,0x3f,0x20,0x2a,0x1c,0x1f,0x2f,0x1d,0x1f,0x1c,0x19,0x24,0x19,0x14,0x1a,0x1e,0x11,0x21,0x20,0x16,0x13,0x0b,0x05,0x0d,0x39,0x13,0x1f,0xdc,0x60,0x9d,0x90,0x95 +,0x8a,0x8a,0x8e,0x84,0x84,0x88,0x89,0x89,0x8c,0x8e,0x8d,0x8a,0x8c,0x98,0x98,0x8e,0x99,0xa6,0xa8,0x4e,0x1b,0xad,0xb5,0x1f,0xea,0x3e,0x18,0x2e,0x42,0xca,0xa8,0x23 +,0x44,0x97,0x9e,0xb5,0xa1,0xc8,0x45,0x2c,0x2d,0x2b,0x1a,0x11,0x0d,0x0f,0x0f,0x14,0x0e,0x07,0x0f,0x19,0x18,0x22,0x44,0x1f,0x37,0xa9,0xcf,0xa7,0x3d,0x2b,0xac,0xa5 +,0xc0,0xae,0xbe,0x28,0x25,0x1f,0x5d,0x2f,0x0f,0x19,0x1b,0x0f,0x10,0x11,0x06,0x11,0x17,0x0b,0x29,0xac,0xab,0x93,0x8e,0x8d,0x82,0x85,0x88,0x84,0x85,0x87,0x86,0x8b +,0x8f,0x96,0xa4,0x9e,0xab,0xcb,0xbf,0x4d,0x3d,0xad,0x9b,0x78,0xb6,0x9d,0xa6,0x9d,0x99,0x9b,0xa5,0xaf,0x2d,0x48,0x1e,0x16,0x23,0x0f,0x07,0x07,0x09,0x05,0x04,0x04 +,0x03,0x03,0x03,0x06,0x04,0x03,0x03,0x04,0x00,0x0b,0x15,0x09,0x1d,0xc2,0xa7,0x8f,0x8e,0x8b,0x84,0x88,0x87,0x81,0x84,0x87,0x85,0x8b,0x89,0x8b,0x8e,0x8b,0x8d,0x93 +,0x8f,0x8c,0x93,0x97,0x9e,0x97,0x87,0x90,0xa5,0x8b,0x8d,0x9c,0x93,0x97,0x92,0x91,0xa4,0xa6,0x93,0xaa,0xb9,0xbc,0x1d,0x1a,0x14,0x13,0x13,0x0d,0x08,0x05,0x05,0x08 +,0x0a,0x03,0x09,0x19,0x0c,0x0f,0x29,0x15,0x14,0x2c,0x25,0x49,0xfd,0x1d,0x2d,0x26,0x17,0x75,0xc5,0x2f,0x2b,0x1c,0x28,0x5e,0x30,0x22,0x29,0x15,0x18,0x1c,0x12,0x2e +,0x19,0x0c,0x22,0x59,0x3c,0xb1,0xb7,0x79,0x99,0x96,0x8d,0x89,0xa5,0xa9,0x91,0x9d,0x9f,0x90,0x97,0xa5,0xab,0x95,0x8d,0x8c,0x8b,0x8e,0x8d,0x86,0x81,0x86,0x84,0x81 +,0x86,0x86,0x85,0x88,0x8c,0x9b,0xbe,0xa3,0x3d,0x11,0x0f,0x0a,0x08,0x07,0x05,0x03,0x04,0x02,0x01,0x02,0x02,0x03,0x00,0x02,0x06,0x02,0x02,0x09,0x09,0x08,0x11,0x27 +,0xc1,0xca,0x2d,0xda,0x9f,0xa3,0x9b,0x91,0x9f,0xaf,0xad,0xa3,0x98,0x9c,0xba,0xa5,0xa5,0x9e,0x9d,0xad,0x8e,0x91,0xa9,0x8d,0x89,0x92,0x8d,0x8f,0x92,0x8a,0x91,0x93 +,0x8a,0x93,0x9c,0x8e,0x8e,0x9d,0xb2,0xb7,0xaa,0xac,0x33,0x21,0x20,0x17,0x16,0x0d,0x1f,0x41,0x14,0x20,0xa5,0xa0,0xa7,0xa0,0xae,0x9b,0x99,0xa7,0x98,0x9b,0x41,0x28 +,0x3f,0x33,0x2d,0x1d,0x18,0x20,0x21,0x1b,0x1c,0x16,0x10,0x0d,0x0d,0x2a,0x16,0x08,0x14,0x1d,0x17,0x1e,0x22,0x34,0xfd,0x27,0x34,0xa5,0xad,0x3a,0x2d,0x25,0x24,0x28 +,0x21,0x1e,0x26,0x24,0x46,0x5c,0xb7,0x9a,0x99,0x89,0x84,0x87,0x82,0x81,0x81,0x81,0x80,0x81,0x82,0x83,0x86,0x87,0x8a,0x92,0xa6,0xb5,0x29,0x19,0x0e,0x08,0x07,0x06 +,0x04,0x03,0x02,0x01,0x00,0x01,0x09,0x06,0x04,0x0d,0x0f,0x0e,0x14,0x1d,0x27,0x2e,0x2b,0x2f,0x3e,0x41,0x4f,0x45,0x24,0x1f,0x33,0xfe,0xbd,0xce,0x4c,0xbd,0x9f,0xa1 +,0xa9,0x63,0x9c,0x8e,0xa1,0x98,0x8f,0x9a,0x9c,0x98,0x93,0x90,0x93,0x90,0x8f,0x92,0x94,0x8f,0x90,0x93,0x9e,0xab,0xa2,0xa3,0xc2,0xde,0xcf,0x25,0x39,0x2e,0x1e,0xa4 +,0xae,0x31,0x99,0x93,0xad,0xa7,0xad,0xac,0x9f,0xa8,0x63,0x3f,0x1d,0x18,0x1d,0x13,0x13,0x19,0x11,0x10,0x20,0x18,0x1c,0x16,0x0b,0x14,0x0d,0x09,0x1c,0x0f,0x06,0x13 +,0x18,0x12,0x19,0x15,0x21,0x2e,0x28,0xae,0xbe,0x46,0x34,0x3b,0x46,0x43,0x27,0x1f,0x2b,0x28,0x21,0x3b,0x5f,0x34,0xae,0xa0,0x8f,0x83,0x86,0x88,0x82,0x82,0x82,0x80 +,0x80,0x81,0x81,0x83,0x84,0x83,0x86,0x89,0x8e,0x96,0x9f,0xaa,0x21,0x16,0x10,0x09,0x0a,0x05,0x02,0x03,0x01,0x00,0x05,0x04,0x03,0x08,0x0a,0x08,0x0e,0x1b,0x19,0x2b +,0x1b,0x1c,0x3a,0x2e,0x38,0x2f,0x20,0x18,0x1e,0x27,0x58,0xcd,0xe0,0xd8,0x51,0xec,0xa2,0xab,0x45,0x99,0x98,0xac,0x9b,0x91,0x93,0x98,0xab,0x9c,0x8c,0x8d,0x91,0x8f +,0x93,0x93,0x8c,0x94,0x95,0x99,0xa8,0xaa,0xac,0xaa,0xc1,0x2e,0x21,0x28,0x36,0x16,0x25,0xa4,0x2f,0x4e,0x99,0x9e,0xa4,0xa1,0xaf,0xa1,0x9b,0xa9,0xac,0xbc,0x2f,0x25 +,0x1f,0x26,0x22,0x18,0x10,0x16,0x31,0x2e,0x1b,0x13,0x16,0x1b,0x12,0x0d,0x1d,0x1c,0x0d,0x19,0x28,0x1a,0x29,0x25,0x19,0x2f,0x78,0x4d,0xba,0x4b,0x2c,0x3c,0x1b,0x1e +,0x2e,0x1f,0x1b,0x1e,0x1c,0x2e,0x49,0x2d,0x44,0x9d,0x95,0x8e,0x84,0x89,0x88,0x82,0x81,0x82,0x81,0x81,0x81,0x81,0x84,0x88,0x86,0x89,0x92,0x9e,0xac,0xcd,0x22,0x10 +,0x0d,0x0e,0x08,0x07,0x07,0x03,0x02,0x02,0x01,0x04,0x08,0x04,0x05,0x0b,0x0c,0x15,0x1a,0x15,0x1e,0x23,0x1e,0x2a,0x40,0x2d,0x45,0x2a,0x20,0x56,0x43,0x60,0xa0,0xa8 +,0xb0,0x96,0x90,0x9c,0xae,0x9f,0xa3,0xa4,0x94,0x96,0xab,0xbb,0xa2,0x99,0x97,0x95,0x93,0x8d,0x90,0x90,0x8c,0x8e,0x94,0x99,0x9c,0x9c,0xa1,0xb3,0xad,0x53,0x39,0x37 +,0x48,0x4e,0x28,0x28,0x28,0x32,0xb8,0xac,0x23,0x2e,0xa7,0xb3,0xb0,0xae,0x61,0x5e,0x50,0x30,0x6f,0x53,0x2f,0x2a,0x22,0x2b,0x2c,0x1f,0x20,0x1d,0x19,0x17,0x19,0x17 +,0x12,0x0b,0x0b,0x0d,0x0b,0x0f,0x0f,0x0f,0x0f,0x26,0x39,0x35,0x2e,0x29,0x49,0xc5,0xbb,0xca,0x50,0x28,0x27,0x28,0x2c,0x57,0xb4,0xa5,0x9b,0x93,0x89,0x86,0x86,0x84 +,0x85,0x82,0x83,0x84,0x82,0x82,0x86,0x85,0x86,0x87,0x87,0x8e,0x96,0x92,0x98,0xac,0x3b,0x1d,0x13,0x0b,0x06,0x04,0x04,0x03,0x03,0x02,0x03,0x04,0x04,0x07,0x07,0x06 +,0x0b,0x0b,0x09,0x15,0x1c,0x16,0x1d,0x22,0x26,0x36,0x28,0x2e,0xa8,0x9f,0xb2,0xa7,0x9d,0x9c,0x9c,0x96,0x96,0x96,0x98,0x93,0x8e,0x94,0x94,0x9a,0xa3,0xa5,0xad,0xa7 +,0xb7,0xb5,0x9f,0xaa,0xaa,0x97,0x95,0x9f,0x9b,0x97,0x92,0x91,0x98,0x9f,0xa0,0xa6,0xb6,0xbf,0xb9,0xce,0x46,0x3c,0x4c,0xb6,0xbc,0x41,0x3a,0x32,0x1f,0x21,0x24,0x19 +,0x15,0x18,0x13,0x16,0x1b,0x1a,0x1e,0x24,0x2c,0xb1,0xb0,0x47,0xcd,0x36,0x42,0x3d,0x2f,0x20,0x17,0x14,0x0e,0x11,0x11,0x17,0x16,0x12,0x12,0x17,0x1a,0x15,0x0f,0x17 +,0x29,0x1c,0x1c,0x25,0x24,0x30,0x3b,0xd5,0x9e,0x93,0x91,0x93,0x8b,0x86,0x84,0x85,0x84,0x83,0x82,0x82,0x83,0x82,0x83,0x86,0x87,0x88,0x8e,0x93,0x9a,0xab,0xaf,0xb7 +,0x4a,0x24,0x19,0x11,0x10,0x0e,0x0b,0x0c,0x0a,0x08,0x04,0x07,0x0a,0x08,0x06,0x07,0x07,0x0a,0x0f,0x0d,0x10,0x0f,0x14,0x0f,0x11,0x17,0x16,0x0b,0x0d,0x2e,0x29,0x28 +,0xbc,0xa7,0xa4,0x95,0x8f,0x8a,0x88,0x8c,0x8e,0x8f,0x8e,0x90,0x97,0x9c,0xa3,0xae,0xd8,0xbb,0xa3,0xa5,0xaf,0xb4,0xad,0xae,0xad,0xb8,0xbb,0x9d,0x9b,0xa3,0x9d,0x9d +,0xa1,0x9d,0xa0,0xa1,0x96,0x98,0x9f,0x9c,0x99,0x97,0x9a,0xb1,0xb6,0xc4,0x43,0x33,0x37,0x39,0x1e,0x17,0x10,0x0e,0x12,0x14,0x0d,0x19,0x29,0x2e,0x2a,0x21,0x28,0x3c +,0x30,0x28,0xc4,0x46,0x1e,0x1e,0x17,0x1b,0x1b,0x11,0x11,0x14,0x1a,0x1e,0x20,0x10,0x13,0xa4,0x99,0x0a,0x01,0x99,0x19,0x19,0xa1,0x16,0x78,0x1f,0x9e,0xa6,0x8c,0x56 +,0x1e,0x84,0x2d,0x9c,0xdc,0x33,0xf9,0x10,0x1f,0x1d,0x13,0x0d,0x0b,0x1e,0x20,0x0f,0x11,0x14,0x25,0x22,0x29,0x4d,0x1e,0x9a,0x80,0x90,0x9d,0x87,0x80,0x80,0x82,0x82 +,0x82,0x86,0x83,0x83,0x81,0x87,0x83,0x89,0x8a,0x89,0x98,0x96,0x96,0x97,0xc8,0xa8,0xad,0x2c,0x2d,0xb6,0x37,0x36,0x4d,0x22,0x2e,0x16,0x0d,0x16,0x0f,0x06,0x09,0x06 +,0x06,0x08,0x02,0x01,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x03,0x01,0x03,0x05,0x0a,0x0b,0x0e,0x15,0x0c,0x24,0x47,0x3c,0xa5,0xb1,0xab,0x9f,0x97,0x8e,0x90 +,0x8f,0x8f,0x87,0x87,0x8a,0x89,0x88,0x85,0x85,0x87,0x85,0x86,0x8b,0x86,0x82,0x81,0x81,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x83,0x89,0x89,0x87 +,0x85,0x86,0x85,0x8b,0x8a,0x87,0x8d,0x8f,0x96,0x9c,0x99,0x90,0x9e,0xb0,0x2c,0x1e,0x1d,0x18,0x0d,0x09,0x0b,0x04,0x06,0x03,0x03,0x02,0x01,0x01,0x01,0x01,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x01,0x02,0x03,0x04,0x02,0x05,0x07,0x06,0x08,0x09,0x0e,0x0e,0x0b,0x13,0x1e,0x15,0x16,0x26,0x2d,0x3a,0x3c +,0x4f,0xa6,0xa2,0xa9,0x96,0x90,0x98,0x8f,0x89,0x88,0x83,0x85,0x88,0x86,0x84,0x84,0x84,0x86,0x87,0x86,0x87,0x86,0x87,0x87,0x86,0x85,0x84,0x83,0x86,0x88,0x88,0x8a +,0x8c,0x87,0x86,0x88,0x85,0x85,0x84,0x85,0x85,0x84,0x82,0x82,0x83,0x84,0x85,0x8f,0x9a,0x96,0x96,0x2f,0x0c,0x12,0x0d,0x08,0x05,0x08,0x0a,0x05,0x03,0x11,0x2d,0x15 +,0x1b,0x3a,0xb5,0x9f,0xa3,0xad,0xb2,0x9f,0x98,0x90,0x8e,0x8b,0x8b,0x8e,0x89,0x88,0x89,0x8b,0x8b,0x8d,0x8d,0x8d,0x95,0xa4,0xde,0x29,0x42,0xdb,0x1e,0x1f,0x1c,0x22 +,0x32,0x19,0x0d,0x10,0x10,0x0e,0x0c,0x07,0x04,0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00 +,0x01,0x03,0x04,0x03,0x02,0x03,0x04,0x03,0x04,0x05,0x05,0x06,0x08,0x09,0x0b,0x0a,0x0a,0x0c,0x0b,0x15,0x43,0x5e,0x2a,0x5b,0x9f,0x9a,0x93,0x8f,0x88,0x83,0x86,0x84 +,0x82,0x80,0x81,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x84,0x8a,0x8f +,0x9a,0xa5,0xb6,0x2e,0x1f,0x18,0x1a,0x18,0x0e,0x0b,0x0a,0x09,0x07,0x08,0x09,0x03,0x02,0x06,0x05,0x07,0x07,0x06,0x08,0x0e,0x15,0x14,0x0f,0x0e,0x14,0x15,0x10,0x0b +,0x08,0x08,0x07,0x05,0x06,0x07,0x05,0x02,0x04,0x05,0x06,0x08,0x06,0x08,0x0d,0x0b,0x0e,0x0f,0x09,0x0e,0x15,0x17,0x1a,0x19,0x18,0x26,0x30,0x1e,0x19,0x16,0x1c,0x24 +,0x1c,0x18,0x15,0x0c,0x0e,0x0f,0x0d,0x18,0x1e,0x17,0x2e,0xb4,0xbc,0xa5,0xa7,0xaa,0x97,0x8f,0x91,0x95,0x9d,0x91,0x8d,0x9a,0x9b,0x97,0xad,0xcc,0x9a,0x93,0xa2,0x2c +,0x23,0xcc,0x50,0x1a,0x2e,0xd6,0x29,0x1e,0x28,0xa7,0x97,0xa9,0x9e,0x87,0x87,0x90,0x8f,0x88,0x82,0x82,0x83,0x82,0x84,0x85,0x82,0x81,0x81,0x82,0x84,0x85,0x83,0x84 +,0x8d,0x92,0x91,0x9b,0xae,0x2b,0x1c,0x15,0x0b,0x08,0x0b,0x0a,0x07,0x06,0x05,0x09,0x0b,0x08,0x07,0x07,0x07,0x0c,0x0c,0x0a,0x08,0x06,0x07,0x0a,0x0c,0x0a,0x14,0x26 +,0x47,0xa1,0xa2,0x9f,0x8e,0x8a,0x89,0x87,0x86,0x86,0x86,0x88,0x87,0x86,0x89,0x8a,0x8d,0x8c,0x89,0x8d,0x92,0x90,0x8f,0x94,0x97,0x9c,0xb9,0xb3,0x9e,0xa2,0xa4,0xa2 +,0xa3,0x9d,0x8f,0x90,0x9a,0x9b,0x96,0x93,0x99,0x9e,0xa6,0x6e,0x41,0x5c,0x2b,0x1f,0x1f,0x24,0x2c,0x1f,0x1a,0x24,0x1d,0x0e,0x0e,0x25,0x25,0x0d,0x0e,0x2b,0xcc,0x32 +,0x1d,0x2a,0xa7,0xc7,0x35,0xac,0xaf,0x28,0x13,0x1a,0x1e,0x0b,0x05,0x0b,0x0e,0x07,0x04,0x05,0x0b,0x0f,0x0c,0x0b,0x0e,0x13,0x14,0x1f,0xb4,0xa3,0x9a,0x8e,0x89,0x86 +,0x83,0x82,0x81,0x80,0x80,0x81,0x81,0x81,0x82,0x84,0x85,0x8a,0x9a,0xaf,0xc9,0x29,0x10,0x0b,0x09,0x07,0x06,0x06,0x07,0x05,0x06,0x08,0x0b,0x0d,0x0a,0x0a,0x0f,0x10 +,0x16,0x1a,0x14,0x14,0x19,0x29,0x2b,0x1e,0x1c,0x28,0x33,0x3a,0x43,0x3a,0x2b,0x31,0x56,0xc3,0xbc,0xae,0xa5,0x9a,0x8e,0x91,0x96,0x90,0x8f,0x8f,0x8f,0x92,0x92,0x98 +,0xa0,0xa2,0x9f,0xa1,0xa9,0xc6,0xbb,0xa1,0xb7,0xbd,0xb7,0x6d,0x37,0x3e,0xc5,0x4f,0x19,0x1c,0xcc,0xd8,0x2f,0x40,0xb5,0xa8,0xa6,0xa6,0x99,0x9e,0xb5,0xaa,0x99,0x9e +,0x4f,0x1f,0x2f,0x41,0x18,0x13,0x2d,0x3a,0x18,0x1a,0x26,0x26,0x19,0x14,0x1a,0x1b,0x11,0x0d,0x0c,0x0f,0x11,0x0f,0x14,0x19,0x13,0x10,0x1c,0x32,0x3f,0x26,0x1c,0x20 +,0x26,0x29,0x2c,0x27,0x30,0xcc,0xaa,0x9a,0x93,0x8d,0x89,0x84,0x82,0x82,0x83,0x82,0x81,0x81,0x81,0x82,0x86,0x87,0x88,0x8d,0x96,0xa2,0xb4,0x44,0x22,0x19,0x0f,0x0a +,0x07,0x06,0x05,0x05,0x04,0x03,0x04,0x04,0x04,0x06,0x08,0x07,0x07,0x0a,0x12,0x16,0x16,0x19,0x1e,0x2a,0xe7,0xc0,0x4f,0xc8,0xa7,0x9d,0x98,0x99,0x9a,0x9b,0x93,0x8e +,0x96,0x9e,0x9c,0x9a,0x9f,0xa2,0xa6,0xba,0xd0,0xfa,0xaf,0xa7,0xcc,0x47,0xab,0x94,0x9a,0xaf,0x9e,0x90,0x97,0xa3,0x98,0x93,0xa0,0xb3,0xa0,0x96,0xa6,0x36,0x49,0xa4 +,0xb2,0x29,0x2a,0x54,0x34,0x1d,0x1e,0x2a,0x27,0x1a,0x1a,0x22,0x28,0x29,0x30,0xc7,0xbf,0x48,0x3e,0xe9,0xbb,0xca,0xd5,0x3c,0x27,0x1e,0x18,0x16,0x1a,0x1a,0x10,0x11 +,0x11,0x0c,0x0d,0x0e,0x0e,0x0e,0x0d,0x0a,0x09,0x0a,0x0d,0x15,0x1c,0x29,0x4c,0xaf,0x93,0x8a,0x87,0x84,0x83,0x82,0x81,0x80,0x81,0x82,0x81,0x81,0x82,0x84,0x86,0x88 +,0x8a,0x8e,0x9a,0xb4,0x2b,0x1c,0x15,0x10,0x0b,0x05,0x04,0x06,0x07,0x06,0x05,0x08,0x0d,0x10,0x10,0x14,0x17,0x15,0x15,0x19,0x1d,0x1d,0x19,0x14,0x19,0x1a,0x1d,0x2c +,0x40,0x2d,0x39,0xa5,0xa1,0xad,0xad,0x9f,0x9d,0x9e,0x9a,0x98,0x9f,0xab,0xa1,0x92,0x94,0xa4,0xa3,0x8f,0x8c,0x97,0x9d,0x98,0x93,0x9a,0xa3,0x9c,0x9e,0xcb,0xd8,0xb3 +,0xaf,0xf0,0x3f,0x7c,0xae,0xba,0x35,0x44,0xb9,0xb5,0xde,0x5b,0xbf,0xc2,0x38,0x4b,0xbb,0xb4,0xff,0x40,0x68,0xaf,0xa8,0xb6,0xb9,0xc1,0x3e,0x34,0x46,0x62,0x2e,0x1a +,0x18,0x18,0x16,0x10,0x11,0x14,0x1b,0x23,0x18,0x10,0x13,0x1a,0x1b,0x1b,0x1c,0x16,0x10,0x12,0x17,0x1e,0x1f,0x1e,0x24,0xfa,0xab,0xaa,0x9e,0x90,0x8b,0x8a,0x87,0x85 +,0x85,0x84,0x83,0x83,0x82,0x82,0x83,0x83,0x82,0x83,0x88,0x8c,0x8e,0x99,0xaa,0x60,0x1f,0x16,0x0e,0x0b,0x0a,0x08,0x05,0x06,0x0a,0x0a,0x08,0x07,0x09,0x09,0x08,0x09 +,0x08,0x07,0x08,0x0b,0x12,0x13,0x10,0x1e,0xc5,0xbc,0x4e,0xb8,0x9a,0x94,0x9b,0x99,0x93,0x98,0x9e,0x9c,0x94,0x97,0x9f,0xa1,0x95,0x96,0xa6,0xad,0xa5,0xa3,0xad,0xbb +,0xaf,0xbe,0x3e,0x4e,0xaf,0xa6,0xab,0xb1,0xa6,0x94,0x94,0x9b,0x9d,0x9e,0x9d,0x9c,0x9c,0xa0,0xd8,0x32,0x38,0x3d,0x36,0x29,0x24,0x30,0xf4,0x2c,0x1e,0x20,0x29,0x35 +,0x36,0x2b,0x29,0x21,0x21,0x30,0x73,0xc9,0x4a,0x2f,0x35,0xbe,0xbd,0x47,0x2f,0x26,0x1f,0x17,0x11,0x12,0x0d,0x08,0x09,0x0b,0x0b,0x09,0x08,0x0a,0x12,0x13,0x0e,0x15 +,0x1e,0x28,0x50,0xa5,0x95,0x90,0x8e,0x88,0x84,0x83,0x82,0x82,0x81,0x80,0x80,0x81,0x81,0x82,0x84,0x86,0x8a,0x8e,0xa3,0x48,0x2f,0x1e,0x0f,0x0a,0x0b,0x0b,0x09,0x0a +,0x0b,0x0b,0x09,0x09,0x0e,0x10,0x0c,0x09,0x0c,0x0e,0x0d,0x0c,0x12,0x16,0x12,0x19,0x2c,0x2b,0x20,0x25,0x3d,0xbb,0xbe,0x4e,0x5f,0xaf,0xb0,0xb1,0xa5,0x9d,0x9c,0x9c +,0x97,0x8f,0x93,0x9b,0x9a,0x96,0x95,0x99,0x9e,0xa6,0x9f,0xac,0xb0,0xa6,0xab,0xad,0xa7,0x9f,0x9e,0xa7,0xaf,0xb4,0xaf,0xbe,0xaf,0xb7,0x68,0xd2,0xd5,0xc8,0x5f,0xc3 +,0xbe,0xb3,0xc9,0xc3,0xcd,0x62,0x6a,0x45,0x3f,0x2f,0x2d,0x24,0x2d,0x28,0x27,0x28,0x2a,0x30,0x38,0x34,0x31,0x34,0x37,0x3c,0x2f,0x36,0x2b,0x28,0x26,0x29,0x2d,0x26 +,0x2b,0x2f,0x35,0x42,0x3c,0x3c,0x4f,0x3a,0x3a,0x36,0x37,0x3b,0x36,0x3f,0x38,0x49,0x4e,0xd9,0xd0,0xcc,0xbc,0xba,0xaf,0xb3,0xae,0xad,0xaf,0xb2,0xb0,0xae,0xab,0xaa +,0xac,0xaf,0xa6,0xa4,0xa9,0xa7,0xa1,0x9f,0xa0,0xa4,0xa5,0xa6,0xae,0xaa,0xa7,0xa9,0xac,0xac,0xb2,0xb5,0xb7,0xca,0xcc,0xea,0x44,0x35,0x2f,0x2b,0x25,0x21,0x1c,0x1e +,0x1b,0x1a,0x1c,0x18,0x1a,0x1c,0x1c,0x1b,0x1b,0x1e,0x1f,0x22,0x27,0x26,0x2c,0x2f,0x35,0x45,0x5a,0xca,0xd0,0xb8,0xaf,0xac,0xaa,0xa8,0xa3,0xa2,0xa0,0xa3,0xa2,0xa1 +,0x9f,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9b,0x9e,0x9c,0x9a,0x9e,0x9d,0x9d,0xa1,0xa5,0xa7,0xae,0xba,0xb8,0xbf,0xcc,0x52,0x31,0x33,0x3f,0x2d,0x28,0x2e,0x30,0x26,0x1e +,0x20,0x23,0x22,0x21,0x20,0x2a,0x29,0x1f,0x21,0x28,0x25,0x1d,0x1f,0x28,0x26,0x20,0x1f,0x1f,0x1d,0x1a,0x17,0x1a,0x1d,0x1e,0x19,0x1c,0x20,0x1e,0x1e,0x1e,0x22,0x29 +,0x2d,0x31,0x44,0x4f,0xf3,0xbd,0xb4,0xa7,0xa3,0x9f,0x9d,0x9a,0x98,0x96,0x94,0x93,0x90,0x90,0x8f,0x90,0x90,0x90,0x91,0x93,0x94,0x93,0x96,0x97,0x98,0x9c,0x9f,0xa6 +,0xab,0xb2,0xbf,0x6a,0x3a,0x2a,0x24,0x1f,0x1b,0x18,0x17,0x14,0x10,0x11,0x10,0x0f,0x0f,0x0f,0x0f,0x10,0x12,0x12,0x16,0x17,0x18,0x1b,0x1e,0x22,0x29,0x2e,0x3d,0x66 +,0xdb,0xbe,0xaf,0xac,0xa9,0xa4,0xa2,0x9f,0x9f,0x9e,0x9e,0x9d,0x9e,0x9f,0x9f,0x9f,0xa0,0xa2,0xa1,0xa0,0xa1,0xa4,0xa2,0xa5,0xa4,0xa5,0xa6,0xa6,0xa8,0xaa,0xad,0xae +,0xb5,0xb4,0xbc,0xbd,0xc2,0xde,0x50,0x6f,0x4d,0x3a,0x37,0x34,0x35,0x30,0x2f,0x2f,0x2d,0x2b,0x2b,0x2c,0x30,0x2f,0x36,0x3f,0x42,0x36,0x37,0x3c,0x3c,0x3b,0x3d,0x3d +,0x3f,0x3f,0x34,0x36,0x31,0x32,0x2f,0x34,0x2f,0x2e,0x2d,0x2c,0x33,0x2d,0x2f,0x3c,0x3c,0x44,0xdb,0xfe,0xc3,0xb3,0xb7,0xaf,0xaa,0xa6,0xa7,0xa1,0xa0,0xa4,0xa0,0xa2 +,0xa5,0xa3,0xa3,0xa6,0xa7,0xa8,0xad,0xb5,0xb7,0xc4,0xee,0x77,0x4b,0x3d,0x3c,0x33,0x2f,0x2e,0x2c,0x29,0x28,0x27,0x25,0x21,0x20,0x23,0x20,0x21,0x20,0x1f,0x1f,0x21 +,0x21,0x22,0x28,0x2b,0x29,0x2a,0x32,0x30,0x38,0x3f,0x51,0xcd,0xc5,0xc8,0xb2,0xad,0xab,0xab,0xaa,0x9f,0xa5,0xa9,0xa3,0xa3,0xa3,0xa5,0xa8,0xa8,0xa7,0xa5,0xaa,0xa8 +,0xa8,0xb0,0xae,0xaf,0xb9,0xc6,0xbe,0xba,0xd0,0xe5,0xd2,0xd0,0x73,0x5b,0x57,0x5c,0x53,0x3b,0x3e,0x40,0x3b,0x33,0x36,0x31,0x33,0x36,0x2c,0x2f,0x34,0x2f,0x2e,0x39 +,0x36,0x35,0x35,0x3b,0x3a,0x3a,0x3e,0x4a,0x48,0x4f,0xed,0x45,0xee,0xdd,0x65,0xf3,0x4e,0xdc,0xdb,0x6f,0xef,0x57,0xf7,0xdb,0x6a,0xe4,0xc1,0xcb,0xca,0xd7,0xc8,0xc2 +,0xc2,0xbd,0xb9,0xb1,0xb3,0xbb,0xaf,0xa9,0xb1,0xad,0xaa,0xa8,0xa6,0xb1,0xae,0xa8,0xb8,0xb4,0xbb,0xc4,0xbb,0xc0,0xdc,0x6d,0x66,0x42,0x3d,0x3a,0x32,0x33,0x3d,0x3a +,0x2a,0x25,0x2b,0x31,0x2a,0x24,0x2b,0x35,0x2b,0x26,0x31,0x2d,0x2b,0x2a,0x2d,0x34,0x3b,0x30,0x2c,0x4d,0x40,0x34,0x50,0x32,0x4d,0x4b,0x3c,0xb6,0x7a,0x6c,0xca,0xb8 +,0xc5,0xdb,0xc5,0xa8,0xa4,0xbc,0xaf,0xac,0xa7,0xab,0xb2,0xaa,0xac,0xa6,0xb5,0xbb,0xba,0xaf,0xe4,0x61,0xb3,0x3e,0xdc,0x45,0xd5,0x6c,0x44,0x6e,0x3b,0x47,0x40,0xdb +,0x4e,0x38,0xbf,0x66,0xf3,0xff,0x41,0xbf,0x4e,0xba,0xfa,0x48,0xcd,0x4f,0x47,0x3f,0x57,0x42,0x54,0xf0,0x49,0x34,0x37,0x6d,0x3a,0x3e,0x56,0x5d,0xec,0x56,0x48,0x49 +,0xd0,0xd1,0xde,0xba,0xd7,0xfd,0xd2,0x5b,0xe6,0x3a,0xca,0xe3,0x59,0x53,0x3a,0x4a,0x4f,0x78,0x37,0xd7,0xc8,0x4d,0x68,0x60,0xc4,0x69,0xbf,0xac,0xe2,0xf9,0xb9,0xc0 +,0xbb,0xce,0xc4,0xdb,0xc4,0xc2,0xda,0x3b,0xc8,0xbe,0x2d,0xd5,0x2e,0xe9,0x35,0x47,0x43,0x3e,0xb7,0x3b,0xeb,0x45,0x5a,0xc7,0xce,0xbe,0xcd,0xbf,0xc1,0x4c,0xbe,0xca +,0xf2,0xb4,0x66,0xf5,0xea,0x3d,0xd9,0x36,0xdb,0x44,0x62,0x41,0x54,0xbf,0x36,0xcf,0xbc,0xd8,0x4e,0x56,0xbb,0xdf,0x42,0xc5,0xcc,0x5e,0x5c,0x45,0x5b,0xb8,0x2f,0xd2 +,0x53,0x56,0x4c,0x3d,0xc1,0x2e,0x3c,0x42,0xc1,0x7d,0x43,0x5a,0xea,0xaf,0x4f,0x36,0xc8,0xaf,0xed,0x49,0xf9,0xad,0x54,0xe0,0xbb,0xed,0xd0,0x68,0xc7,0xd9,0xb6,0x3c +,0xd4,0xbf,0xcf,0x2f,0xaf,0x41,0xbc,0x42,0x4f,0xad,0x2a,0xa6,0x3f,0xd4,0x3b,0xbe,0x51,0x67,0xc8,0x3a,0xbd,0x50,0x54,0x54,0x3f,0xea,0xc0,0xda,0x31,0x68,0x3e,0xcb +,0xce,0x2a,0xae,0x36,0xb1,0x2e,0x78,0xc4,0x51,0xb4,0x34,0xbf,0x4d,0xf6,0xed,0xd5,0xca,0xd1,0x39,0xb3,0x2f,0x4b,0xe8,0x42,0xb3,0x25,0x6f,0xba,0x35,0x46,0x41,0x3f +,0xb9,0xcd,0x69,0xcb,0x40,0xac,0x38,0x3f,0xa6,0x2e,0xbb,0x6a,0x5e,0xca,0x5a,0xf1,0xf7,0x43,0xbf,0x35,0xed,0x63,0xc0,0x78,0x3b,0xc9,0x4b,0xae,0x27,0xaa,0x3a,0xbd +,0xc7,0x3c,0xcf,0xd5,0xb6,0x36,0xc0,0x74,0xe5,0xca,0xfb,0xfd,0xc6,0x4c,0xbe,0x3c,0x3e,0xac,0x3a,0x4a,0xb5,0xe0,0x41,0x47,0xae,0x38,0xdc,0xec,0x47,0xb5,0x66,0x3e +,0xf7,0xb9,0x38,0xca,0xc5,0xff,0xc0,0x2b,0xa7,0xed,0x21,0xa5,0x2e,0xbf,0x4c,0xdd,0xcd,0x30,0xbc,0x40,0xcc,0x71,0x35,0xbf,0xba,0x30,0xcd,0x6e,0xd0,0x39,0xad,0x42 +,0x4e,0xaf,0x54,0xd3,0x51,0xc5,0x6d,0x6a,0x42,0xfe,0x43,0xa9,0x3a,0x34,0xc6,0xc8,0x47,0x3d,0xc4,0x45,0xc1,0x5f,0x51,0xb5,0x46,0xbd,0xdc,0x79,0xb9,0x5f,0x74,0x39 +,0xad,0x4a,0x3f,0xf9,0x36,0xbb,0x38,0x4d,0x7e,0x58,0xcf,0x2b,0xbb,0x36,0xcf,0x3f,0xcf,0xab,0x2c,0xb9,0x4b,0xc9,0xbe,0x38,0xca,0xcc,0x3d,0xee,0x3a,0xe3,0xca,0x4c +,0xf7,0x3c,0xb3,0x36,0x3a,0xb2,0x2a,0xb3,0x4e,0xdd,0x4d,0x6f,0x5c,0xc5,0xbf,0x3b,0xa3,0x2e,0xcf,0xb6,0x39,0xb8,0xdb,0x39,0xaa,0x2d,0xe8,0x48,0xef,0xd8,0x2d,0xba +,0x3c,0x57,0xce,0x40,0x49,0xb8,0x4f,0xf9,0xb4,0xbe,0x53,0xac,0x34,0xa9,0x30,0xad,0xa7,0x28,0xa4,0x2d,0xad,0x3c,0x3f,0xbc,0x32,0x54,0x37,0xca,0x4e,0x22,0xba,0x36 +,0xbb,0x2c,0x56,0xaa,0x33,0x5a,0xd6,0xab,0xbc,0x5a,0xbc,0xb6,0x39,0xaf,0x5b,0xa7,0x23,0xa5,0x44,0x56,0x7a,0x22,0xb3,0x31,0xb4,0x28,0x5d,0x43,0xdf,0x26,0xae,0x3a +,0xbd,0x2c,0xe3,0xab,0x3c,0xba,0xe5,0x9d,0x21,0xa3,0x2b,0xab,0xb8,0x35,0xb4,0x33,0xac,0x31,0xbc,0x3d,0x28,0xab,0x39,0x40,0xb6,0x1e,0xb8,0x33,0xdf,0x2d,0xc3,0xbb +,0x2c,0xa6,0x28,0xba,0x4c,0xbf,0xad,0x5f,0x45,0xa7,0x48,0x57,0xac,0xb9,0x68,0xfc,0xd5,0x49,0x59,0x39,0xba,0x28,0xd2,0x36,0x3f,0x4b,0x4c,0xcf,0x2d,0xc2,0x62,0xcd +,0x59,0xb6,0xdb,0xdc,0xad,0x22,0x95,0x2b,0x78,0xa9,0x35,0x9c,0x1e,0xa3,0x2d,0x3d,0xcd,0x3a,0xb4,0x2b,0xbe,0x39,0x33,0x6e,0x3a,0xe2,0x4b,0x38,0xb3,0x48,0x4f,0x66 +,0x3f,0xaa,0xec,0x3f,0xa5,0xd2,0xbe,0xaa,0x38,0xaf,0x21,0x9c,0x59,0x22,0xba,0x28,0xa9,0x1f,0x3e,0x34,0xb8,0x3a,0x2f,0xb1,0xdb,0x3b,0x3a,0xd5,0xac,0x4b,0xeb,0xa5 +,0xeb,0x56,0x55,0x9e,0x3f,0xac,0x41,0x56,0xbe,0xe9,0xc4,0x2c,0xc7,0x32,0xdd,0x32,0x3b,0x3e,0x37,0xb9,0x31,0x48,0xed,0x42,0xb6,0x2d,0xb0,0xc0,0xb8,0xc1,0x69,0xcb +,0xcd,0xa9,0xcc,0xcc,0xcb,0x2f,0x2c,0x9d,0xa9,0xbb,0x2b,0xab,0x20,0x09,0x1a,0x9e,0x8e,0x18,0x0f,0x40,0xd1,0xa8,0x2d,0xac,0x93,0x85,0x9a,0x07,0x0f,0x3c,0x84,0x9e +,0xab,0x37,0x0e,0x1b,0x27,0xa5,0x1f,0xbf,0xa6,0x20,0x4a,0x27,0x59,0x34,0xb0,0x98,0x29,0xa7,0x8c,0x1f,0x02,0x42,0x86,0xa1,0x10,0x27,0xa6,0x8f,0xf1,0xee,0x19,0x27 +,0x88,0x98,0x12,0x18,0x45,0x0f,0x1a,0x44,0x9a,0x9d,0x1e,0x2d,0xa8,0xac,0x95,0x99,0xac,0x23,0x19,0xf5,0x4d,0x21,0x0a,0xa5,0x8a,0x3c,0x0d,0x10,0x9f,0x89,0x86,0x9f +,0x1b,0x1d,0x21,0x54,0x6b,0xaa,0x90,0x2c,0x0c,0x0c,0x18,0xae,0x92,0x9c,0xaf,0xa3,0xcc,0x0d,0x0d,0xbe,0x8b,0x8c,0xbc,0xbe,0x08,0x0d,0x9a,0x88,0x9a,0x26,0x4a,0xb0 +,0x14,0x18,0xa5,0xac,0x8e,0xae,0x20,0x0c,0x29,0xad,0x1b,0xac,0xa4,0x92,0x17,0x07,0xc7,0xa5,0x82,0xa4,0x6c,0x16,0x23,0x9b,0x43,0x9a,0x1e,0x42,0x33,0x1f,0x27,0x0c +,0x9a,0x97,0x9a,0x99,0x1c,0xc2,0x33,0xaf,0xb6,0xb4,0x9d,0x44,0x0d,0x09,0x2f,0x92,0xb0,0x18,0xc4,0xaa,0x8d,0x97,0x11,0x1f,0xc3,0x99,0xab,0x20,0xaf,0x21,0x23,0x31 +,0xab,0x58,0xb1,0xa9,0xaa,0x2e,0x21,0xbb,0x1e,0x3e,0xe3,0x97,0xaf,0x21,0x12,0x0d,0xb2,0x89,0x8d,0x41,0x09,0xac,0x9f,0x9c,0x3d,0x31,0x92,0xc5,0x29,0x11,0x2a,0xaa +,0xb2,0xf5,0x75,0x24,0x27,0x11,0x45,0x99,0x8d,0x8f,0x3a,0x0e,0x12,0x94,0x8f,0x91,0x32,0x10,0x19,0x15,0x35,0x26,0x44,0x95,0x8a,0xc2,0x17,0x10,0xbb,0x92,0x95,0xa4 +,0x2e,0x37,0x0f,0x0a,0x24,0x89,0x8d,0xd2,0x10,0x3d,0xcb,0xa0,0xad,0x40,0xbb,0x9e,0xcc,0x12,0x15,0x2b,0xd3,0xa1,0x9b,0x28,0xdb,0x16,0x93,0x9a,0x9d,0xc5,0x2f,0x52 +,0x15,0x24,0x28,0x93,0x2a,0x18,0x2c,0xc0,0xa2,0x3a,0x25,0xbc,0x97,0x98,0xc3,0x1b,0x2c,0x9a,0x9c,0xa4,0x31,0x2e,0x67,0x25,0x26,0x2a,0x47,0x66,0x41,0xac,0xc9,0xcd +,0x34,0x21,0xa8,0x39,0x99,0x9a,0xb0,0x15,0x0a,0xab,0xa5,0xae,0xe8,0x2d,0x92,0xb0,0x1a,0x1c,0x27,0x8b,0x95,0xb4,0x19,0x1f,0x1d,0x19,0x22,0xa0,0x95,0x9e,0x1c,0x15 +,0x9b,0xab,0x8d,0xad,0x33,0x49,0x39,0x14,0x22,0x2d,0xe1,0x97,0xc9,0x3e,0x0e,0x2a,0x99,0x94,0x92,0xc4,0x4c,0x1a,0x39,0x36,0x3f,0x92,0xb0,0x1c,0x0e,0x16,0x4c,0x9e +,0xac,0x99,0xab,0x9e,0x1b,0x18,0x24,0x3e,0x86,0xa6,0xc4,0x1e,0x0f,0x3c,0x4d,0x96,0xa5,0xb1,0xb8,0x16,0xe0,0x26,0x2d,0xa2,0x9c,0xa1,0x12,0x3f,0xad,0x15,0x42,0x1f +,0x98,0xa1,0x1d,0x29,0x33,0x8c,0x9b,0xbe,0xd5,0x4d,0xbf,0x6e,0xc7,0x29,0x18,0xbb,0x30,0x2e,0x1d,0x33,0xa0,0x54,0xab,0xc4,0x9b,0x9d,0x29,0x5a,0xad,0x3d,0xa7,0x3d +,0x12,0x1f,0x27,0xbb,0x6b,0x21,0xac,0x8a,0x9a,0x29,0x26,0x1f,0xa4,0xcf,0x4f,0xa6,0x3e,0x2d,0x18,0x28,0xb2,0x9f,0xa2,0x9a,0xfb,0x30,0x1f,0x31,0xdf,0x32,0xa5,0x96 +,0x2e,0x1e,0x0d,0x1a,0x97,0x56,0x8b,0x3d,0x25,0xb4,0x30,0xa2,0x3e,0xa1,0x96,0x30,0x25,0x1c,0x47,0x46,0xc6,0xae,0x2f,0x43,0x1b,0x22,0x49,0xa4,0x9f,0x97,0x36,0x27 +,0x39,0xae,0x97,0xb4,0xb9,0x18,0x21,0x21,0x20,0x28,0xc7,0x8f,0x9a,0x4e,0x21,0xd2,0x4a,0xac,0xef,0x9f,0xbe,0x1c,0x1d,0x0d,0xc8,0xa5,0x98,0xa1,0x2e,0x5d,0xad,0xc3 +,0xe3,0x35,0x97,0xac,0x46,0x18,0x19,0x5c,0x1d,0xbc,0xa5,0x6c,0xba,0xa5,0xaf,0xb8,0xbe,0x9d,0x31,0x34,0x2c,0x28,0xc5,0x2b,0x1a,0xb9,0x32,0xaa,0xb7,0x4c,0xc8,0x2e +,0xa0,0xb9,0xae,0x34,0x59,0xb3,0xb2,0xce,0x43,0xc9,0xc6,0x2b,0x1d,0x2f,0x1f,0x54,0xb6,0xbc,0xa7,0x3f,0xa0,0x1a,0x46,0x9d,0xc4,0x8d,0x31,0x24,0x26,0x2b,0xbe,0x45 +,0xe6,0xa9,0x9b,0x31,0x20,0x1d,0xa4,0xac,0xa2,0xb1,0x1f,0x4d,0x0c,0x1c,0x1f,0x9d,0xa9,0xaa,0xac,0x38,0x9b,0xaa,0x9b,0xa8,0xd1,0xfd,0x2a,0x1e,0x1b,0x19,0xb1,0x36 +,0xc7,0x41,0x24,0xc4,0xbb,0x9c,0xa7,0xdd,0x3f,0x48,0x35,0xe2,0x38,0x98,0xd2,0x23,0x2f,0x37,0xbf,0xd5,0xbc,0xa6,0x9d,0x42,0x28,0x27,0xda,0x25,0xa1,0xac,0x4a,0x3b +,0x1c,0x7e,0xb2,0x45,0xb7,0xcd,0xb0,0x44,0x1d,0xb8,0x3f,0xaf,0xf4,0x9f,0xad,0x36,0xc7,0x22,0x23,0xb6,0x65,0x3d,0xcc,0xd0,0xb1,0xc6,0xa9,0xa0,0x5e,0xbe,0xac,0x3e +,0x20,0x2a,0x1c,0x2c,0x3d,0x26,0xbb,0x33,0xb9,0xa5,0x3e,0x9c,0x99,0xc9,0xa8,0xfc,0x53,0xec,0x59,0x21,0x3b,0x3f,0x2d,0x29,0x20,0xbc,0xa5,0xab,0x9f,0xcd,0x30,0xbf +,0x1e,0x47,0xae,0x60,0x48,0x5c,0x1d,0x78,0xd4,0xa2,0xa3,0xca,0x9e,0x47,0x27,0x29,0xce,0xd0,0xb1,0x5f,0x5d,0x30,0x23,0x1d,0xbd,0xb2,0x38,0xa6,0x3a,0xc1,0xad,0x21 +,0x9a,0x9f,0xec,0xa9,0x29,0xec,0x22,0x46,0x72,0x45,0x35,0x3f,0x3c,0x29,0x47,0xaf,0x9c,0xbf,0xcb,0xd5,0xbd,0xad,0xae,0x3e,0xbb,0x24,0x33,0x1f,0x14,0xd8,0xb3,0xb5 +,0xae,0xbe,0xa8,0xad,0x2e,0xa4,0xb1,0x3e,0xdd,0x3d,0x20,0x2d,0x3f,0x4e,0xb0,0xb5,0xae,0xa5,0x7e,0x3f,0xda,0xd2,0x49,0xda,0x35,0x45,0x29,0x18,0xce,0x28,0xba,0xed +,0xc0,0x9a,0x55,0x9c,0xae,0xde,0xa3,0x49,0xb8,0x33,0x1a,0xc9,0x20,0xe0,0x27,0x2f,0x9a,0x1f,0xc8,0xe0,0x41,0xb0,0xd4,0xc5,0xa5,0x5d,0xba,0xc7,0xca,0xad,0x28,0xb8 +,0x37,0x23,0x26,0x4c,0xc2,0xbc,0x49,0xf4,0x9e,0x3d,0x2f,0xad,0xb6,0xb5,0x34,0x2b,0xc1,0x1f,0x33,0xbb,0x4c,0xab,0xb9,0xe9,0xca,0x49,0xa7,0xa8,0x55,0xb9,0x43,0x27 +,0x2c,0x19,0x2a,0x5a,0x4f,0xa5,0x45,0xbd,0x9e,0xad,0xa4,0xae,0xad,0xc3,0x23,0x29,0x28,0x26,0x52,0x27,0x3c,0x4a,0x3b,0x6f,0xa4,0xc0,0xb8,0xab,0x77,0xaa,0x35,0xb9 +,0xac,0x57,0xdc,0x3d,0x2d,0x4a,0x2f,0xd2,0xfd,0xc2,0xcb,0x4a,0x4b,0xf2,0xe1,0x4f,0xc4,0x48,0xcf,0x52,0x66,0x3e,0x4a,0xdd,0xb1,0x51,0xcf,0xb4,0x30,0xcd,0xec,0x64 +,0x9f,0x36,0xaa,0xdd,0x2c,0x68,0x1e,0xcc,0x20,0x31,0xb8,0x3d,0xae,0x6a,0xaf,0x9e,0xca,0xa6,0xbc,0x7e,0xf6,0x2b,0x2e,0x2f,0x22,0x3f,0x47,0x37,0xeb,0xbf,0xbf,0xa7 +,0xad,0xb9,0xa1,0x46,0xb7,0xc5,0x2f,0xcc,0x2b,0x2e,0x37,0x1d,0xce,0x3a,0xc2,0xa1,0x49,0xad,0xbe,0xd4,0xce,0x31,0xb4,0xc6,0x2d,0x4a,0x26,0xe6,0xb3,0x3f,0xaa,0xbe +,0xbc,0xb2,0x2f,0x6a,0xe2,0xd0,0xc0,0x49,0x3c,0x2f,0x2d,0x41,0x3b,0xe9,0x4b,0xc1,0xd7,0x41,0xae,0xc1,0xaa,0xb1,0xbb,0xb6,0x4a,0xe5,0xc0,0x1e,0x3c,0x4b,0x37,0x33 +,0x23,0x48,0x46,0xb2,0x5d,0xb8,0xa4,0xb5,0xa9,0xb8,0xaa,0xc5,0xd7,0xd2,0x20,0x28,0x23,0x3c,0x4d,0x43,0xbb,0xbd,0xaf,0xb5,0x4c,0xb7,0xaa,0xed,0x3a,0x48,0x2f,0x27 +,0x3f,0x47,0x4a,0xc6,0xad,0xb3,0xc3,0xce,0xac,0xe6,0xbc,0x5e,0x37,0xbd,0x2d,0x21,0x2d,0x30,0x39,0x5d,0xca,0xbc,0xfe,0xb2,0xb1,0xaa,0xa8,0xde,0xc4,0xf4,0xe2,0x3a +,0x2f,0xe6,0x39,0x67,0x35,0x3d,0xd6,0x3c,0x3d,0xb6,0xe0,0xca,0xc4,0x47,0xa9,0x4f,0xb6,0xb2,0x3f,0x47,0x38,0x31,0x3e,0x38,0x44,0xe7,0xc7,0x60,0xbd,0xbc,0x70,0xa8 +,0xb4,0xbd,0x62,0x5f,0x38,0x35,0x32,0x4c,0x5d,0x63,0x5f,0x3a,0xbb,0xbf,0xad,0xbd,0xbe,0xe5,0x75,0xdc,0x27,0x35,0x2d,0x39,0x69,0x4d,0x4e,0xbf,0xac,0xb2,0xaa,0xaa +,0xaf,0xca,0x46,0x3b,0xd7,0x2d,0x2d,0x31,0x2b,0x68,0x3a,0x3e,0xd4,0xd5,0xc7,0xb7,0xbd,0xb6,0x5d,0xd1,0xb2,0xcb,0xcc,0x4e,0x48,0x7c,0x44,0x35,0xdf,0x56,0xde,0xf2 +,0x6f,0xf4,0x62,0xd6,0x49,0xca,0xdf,0xc5,0x5b,0x3e,0x41,0x4e,0xcb,0xc8,0x48,0xcc,0xd2,0x3a,0xb0,0xb8,0xca,0xaf,0xb8,0xc0,0x6b,0x3c,0x2c,0x35,0x59,0x2d,0x3f,0x3d +,0xf0,0x46,0xf9,0xaf,0xa6,0xa8,0xcd,0xc7,0xc9,0xf2,0x42,0x32,0x31,0x3b,0x3d,0x4e,0x2f,0x4f,0xd2,0xb5,0xb1,0xaf,0xbf,0xbc,0xc1,0xcd,0xda,0xe7,0x58,0x3b,0x36,0x2e +,0x45,0xcf,0x4e,0xfb,0xb9,0x42,0xb3,0x3e,0xd8,0xd4,0x3b,0x76,0x4b,0x5e,0x4e,0x5f,0xb5,0xbb,0xba,0xce,0xc3,0x6f,0xc8,0xb0,0x2c,0xcb,0x43,0xcd,0x3d,0x39,0x3a,0x5f +,0x31,0x2f,0xc9,0x49,0xb9,0x41,0xd1,0xde,0xab,0xb4,0xaf,0xc7,0xd4,0xb2,0x3a,0xf8,0x3b,0x3d,0x36,0x58,0x3a,0x33,0x42,0x3d,0xde,0x5e,0xb8,0xb8,0xbb,0xbb,0xc4,0xcb +,0x66,0x5f,0x4c,0x44,0x4b,0x4c,0x5b,0xe4,0x6f,0xb6,0xbf,0xc8,0xb9,0x5f,0xc8,0x4c,0x4f,0x48,0x31,0x3f,0x3c,0x43,0xd3,0xc6,0x63,0xd8,0xc9,0xcd,0xc6,0x6b,0xc8,0xc9 +,0x4f,0x66,0x42,0x3b,0x49,0xde,0x4e,0xf3,0x65,0xc8,0xc7,0xcf,0xbb,0xba,0xc0,0xfc,0xdb,0x4c,0xdf,0x48,0x42,0x43,0x5e,0x3a,0x3f,0xce,0x5d,0xd8,0x43,0x5c,0xc4,0x65 +,0xd1,0xbc,0xc0,0xb9,0xd1,0xc0,0xdd,0x43,0x5b,0x43,0x4a,0x4c,0x40,0x5c,0x53,0xd6,0xf6,0xc4,0xc2,0x60,0xc9,0x77,0x72,0x4a,0x65,0x5d,0x3e,0x49,0xcd,0xdd,0x5a,0x66 +,0xbd,0xbd,0xd0,0xcc,0xce,0xc1,0x48,0x3a,0x3b,0x3c,0x47,0x41,0x5c,0xee,0xcf,0xc9,0xc4,0xb5,0xb7,0xbf,0xde,0xbe,0xfd,0x40,0x3d,0x39,0x37,0x3d,0xe0,0x4f,0x6e,0xcd +,0xe6,0xc7,0x6a,0xcd,0xce,0x5c,0xc9,0xde,0xc8,0x65,0x69,0xd9,0x78,0x61,0x66,0x55,0xce,0xc9,0x5c,0x55,0x44,0x4c,0x5f,0x5c,0xeb,0xcd,0x6d,0x5c,0xeb,0x5e,0xe2,0xd8 +,0x70,0xc7,0x5a,0x67,0x5e,0xdb,0xcf,0xe6,0xbe,0xbe,0xcd,0x56,0x50,0x4b,0x50,0x3b,0x41,0x49,0x4c,0x55,0x53,0xdd,0xbc,0xbb,0xbb,0xc3,0xcf,0xd8,0x58,0x63,0x4b,0x3b +,0x3f,0x3f,0x43,0x5f,0x59,0xcb,0xcf,0xc9,0xca,0xcb,0xc0,0xc7,0xc2,0xda,0x4d,0x4d,0x41,0x3d,0x4e,0x53,0xcf,0xdc,0xe9,0xdc,0xe3,0xe2,0xdc,0x61,0x69,0xe9,0x57,0x49 +,0x4c,0xfc,0x58,0xd1,0xe0,0xd5,0xc1,0xef,0xcf,0xf8,0x5d,0xd0,0x4f,0x74,0x50,0x58,0xd9,0x47,0xcd,0x53,0x4b,0xec,0x4e,0xd1,0x60,0x5f,0xe5,0xe1,0xc9,0xd2,0xcd,0xd7 +,0xc7,0x6c,0x43,0x68,0x4f,0x67,0x46,0x5b,0x59,0x4a,0x65,0xfc,0xcf,0xd6,0xbf,0xc8,0xc1,0xd6,0xdb,0xcd,0x77,0x42,0x3d,0x3c,0x51,0x4d,0x52,0xcc,0xd4,0xd1,0x63,0xe5 +,0xd4,0xcd,0xdf,0xcf,0x57,0x49,0x4c,0x63,0x66,0x58,0xca,0xc1,0xc4,0xdb,0xe5,0xcc,0xc5,0xe8,0xeb,0x54,0x4a,0x3e,0x3c,0x44,0x5a,0x64,0x52,0x71,0xd9,0xda,0xde,0xbe +,0xbf,0xce,0xdb,0xd7,0xdb,0x5e,0x58,0xd5,0xe8,0x74,0x6c,0x5a,0x62,0x57,0xe7,0xe9,0x5b,0x5b,0xee,0xed,0xee,0x5f,0xd0,0xcb,0x60,0x46,0x59,0xde,0x50,0x45,0x5e,0xd8 +,0x70,0xdf,0xe5,0xd4,0xeb,0xd0,0xd5,0xe4,0xd5,0x5d,0xe2,0x7d,0xe9,0x4e,0x46,0x64,0x6d,0x5e,0x62,0xe7,0xe5,0x67,0x4c,0xf0,0xd7,0x67,0x52,0x45,0x40,0x58,0x57,0x70 +,0x62,0xdc,0xbe,0xc5,0xcd,0xc4,0xca,0xc0,0xce,0x59,0x6b,0x43,0x46,0x3e,0x4f,0x5b,0x44,0x3f,0x3e,0x42,0xe6,0x6a,0xe0,0xdb,0x5b,0xdf,0x67,0xd7,0xf6,0xcf,0xd1,0xd1 +,0xc8,0xe1,0x66,0xe4,0xce,0xcd,0xde,0xe3,0x54,0x49,0x56,0x52,0x5f,0xfd,0x69,0x47,0x5c,0x77,0xca,0xe6,0x56,0xde,0xdb,0xc7,0xcc,0xc0,0xbb,0xbf,0xca,0xcd,0xca,0xce +,0x59,0x5a,0xdb,0xe2,0x54,0x45,0x58,0xdf,0xcb,0xc6,0xd9,0x62,0x57,0x4b,0x64,0x75,0x4e,0x4c,0x4c,0x52,0x7a,0x56,0xed,0xc8,0xc1,0xd4,0xce,0xc8,0xe0,0xcc,0xd7,0xdd +,0xd9,0xdb,0x4c,0x47,0xe5,0xdc,0xed,0x5b,0x57,0x79,0xd8,0x6e,0x6d,0xeb,0xee,0x54,0x3b,0xe5,0xcc,0x4e,0x52,0xcb,0xc1,0x77,0x4d,0xfa,0xd2,0xe4,0x42,0x5e,0x74,0x4a +,0x4c,0x4a,0x74,0x45,0x3f,0x3f,0x47,0x4e,0x56,0x55,0xf3,0xe7,0xd7,0xd3,0xca,0xd4,0xdb,0xbc,0xe0,0xfe,0xf3,0xe7,0x69,0x4d,0x69,0xd3,0xf0,0x4b,0x3f,0x51,0xcf,0x6b +,0x3f,0x4b,0xcd,0xce,0x67,0x51,0xd0,0xc9,0x58,0x60,0x4d,0xcf,0xc3,0xee,0xd3,0xd7,0xcb,0xe7,0x6a,0x62,0xe1,0xdc,0x53,0x4e,0x47,0x52,0xca,0xf9,0xe1,0xcb,0xdc,0xd9 +,0x55,0xd4,0xd2,0xe0,0xcc,0xf7,0x69,0x4c,0x49,0xd3,0xdb,0xcc,0xcb,0xd2,0xe6,0x57,0x5b,0xd2,0xc0,0xd2,0xf3,0xf8,0xe0,0x4d,0x40,0x62,0xd9,0x65,0x4d,0x59,0x69,0x4f +,0x49,0x4f,0xd2,0x61,0x63,0x5e,0x5a,0xbf,0xce,0x5a,0x63,0xd0,0xda,0x49,0x46,0xdf,0xd6,0xdd,0x77,0x5e,0xea,0xe5,0x63,0x5d,0x4d,0x51,0xf9,0x60,0x47,0x45,0x4e,0xcb +,0xb8,0xd6,0xe7,0xc9,0xc7,0xd6,0xc9,0xc5,0x5c,0x4f,0x5f,0xea,0xfb,0x39,0x3d,0xe4,0xf8,0x4e,0x42,0x4f,0xdc,0xe8,0xdf,0x5b,0x54,0xc7,0x7d,0x5a,0x53,0x44,0xce,0xd5 +,0xf9,0xd8,0xcf,0xb7,0xc4,0x55,0x4d,0xc3,0xbc,0x74,0x53,0x6e,0xd1,0xee,0x48,0xed,0xc2,0xcd,0x5e,0x46,0x6e,0xc8,0xc9,0x4f,0x4d,0xca,0xbf,0x57,0x43,0xfd,0xbc,0xcb +,0x52,0x43,0xef,0xdd,0x41,0x5e,0xea,0xd1,0x62,0x3f,0x60,0xc8,0xde,0x52,0x5d,0xc1,0x6f,0x3a,0x3f,0xfe,0x5b,0x47,0x50,0xde,0xbf,0x72,0x56,0xd7,0xc7,0xd1,0xfe,0x54 +,0xcc,0x73,0x46,0x5c,0x4b,0x6d,0x48,0x6c,0xc4,0xe5,0x6a,0x4e,0xc6,0xc4,0x55,0x57,0x67,0xcb,0x6b,0x46,0xf4,0xe6,0x7b,0x63,0xf5,0x7d,0x6e,0xd3,0xe3,0x6a,0x6b,0xe9 +,0x5f,0x4c,0x44,0x4e,0x64,0x79,0xe1,0x46,0x46,0xd7,0xc4,0xc0,0xda,0x78,0xbf,0xc3,0xc6,0xd4,0x4f,0xea,0xbb,0xd0,0x42,0x4a,0xeb,0xd1,0x50,0x4f,0x6f,0xcb,0xee,0x49 +,0x64,0x68,0xce,0xc8,0x40,0x46,0xd4,0xbd,0xe4,0x42,0x3e,0xcd,0xb9,0x4c,0x4c,0xcd,0xbd,0xd4,0x77,0xee,0xc0,0xc6,0x62,0x45,0xf1,0xd6,0x55,0x41,0x48,0xc9,0xdd,0xda +,0x45,0x58,0xc3,0x5e,0xf7,0x58,0x52,0x60,0x3e,0x3b,0x4e,0xe6,0x61,0x50,0x51,0x6d,0xed,0xd4,0x72,0x4c,0xdc,0xc7,0xc9,0x56,0x37,0x67,0xbe,0xc5,0x6c,0x49,0xce,0xc4 +,0x78,0xef,0xd8,0xc2,0xc2,0xed,0xcc,0xde,0xe6,0x79,0xcd,0xcb,0x69,0x77,0xd0,0xcb,0x6a,0x5b,0xdd,0xcc,0x4f,0x48,0x56,0x3e,0x3c,0x4c,0x58,0x3b,0x2c,0x3a,0x4c,0x47 +,0x30,0x33,0x54,0x51,0xe9,0x53,0x51,0xcf,0xbb,0xbb,0xbe,0xba,0xaf,0xb4,0xb0,0xb1,0xb8,0xad,0xae,0xb1,0xbd,0xbb,0xb9,0xcb,0xec,0x65,0x6c,0x58,0x36,0x2c,0x2f,0x30 +,0x29,0x2a,0x2f,0x30,0x30,0x31,0x2e,0x30,0x3e,0x4a,0x3e,0x3f,0x63,0x6b,0x5d,0xf7,0xc1,0xb5,0xad,0xaa,0xae,0xaa,0xa0,0x9f,0xa6,0xa8,0xa9,0xa6,0xab,0xbc,0xcf,0xcd +,0xcd,0x51,0x3f,0x33,0x32,0x2c,0x2d,0x2e,0x29,0x28,0x25,0x2b,0x2b,0x26,0x23,0x31,0x36,0x2f,0x2d,0x32,0xe2,0xc4,0xcc,0xbe,0xab,0xa9,0xa8,0xa5,0xa1,0x9e,0x9e,0x9f +,0x9f,0xa3,0xac,0xb5,0xbe,0xc4,0xf7,0x3f,0x3b,0x2e,0x36,0x2e,0x23,0x2a,0x2d,0x2c,0x25,0x22,0x27,0x30,0x2c,0x1e,0x21,0x2f,0x3c,0x43,0x43,0x4d,0xbc,0xa7,0xa8,0xab +,0xa4,0x9e,0x9b,0x99,0x9d,0xa2,0xa5,0xa3,0xa6,0xb8,0xcb,0xdc,0xdc,0x63,0x3b,0x2c,0x2d,0x2d,0x29,0x23,0x22,0x25,0x23,0x22,0x1f,0x22,0x2d,0x2a,0x29,0x2b,0x3a,0x63 +,0x47,0x73,0xbd,0xab,0xa6,0xa9,0xa5,0x9d,0x9a,0x9b,0x9b,0x9d,0xa4,0xa5,0xac,0xb4,0xcd,0x54,0x67,0x3c,0x33,0x2c,0x26,0x29,0x2b,0x27,0x26,0x23,0x22,0x25,0x28,0x27 +,0x26,0x28,0x29,0x3b,0x3a,0x3b,0xca,0xba,0xae,0xa8,0xa7,0x9f,0x9b,0x9b,0x9a,0x99,0x9c,0x9e,0xa5,0xad,0xaf,0xc7,0x55,0x44,0x34,0x2b,0x27,0x1e,0x1f,0x22,0x20,0x21 +,0x21,0x1e,0x22,0x27,0x20,0x23,0x21,0x33,0x6c,0x65,0x79,0xcd,0xaf,0x9f,0x9c,0x9e,0x9c,0x97,0x94,0x98,0x9e,0x9e,0x9d,0xa7,0xbc,0x43,0x33,0x34,0x35,0x2b,0x1f,0x1c +,0x1f,0x22,0x1e,0x1e,0x20,0x24,0x2a,0x25,0x1f,0x20,0x26,0x3c,0x56,0x40,0xbf,0xb6,0xab,0xa3,0xa2,0x9d,0x97,0x94,0x94,0x99,0x9f,0xa3,0xa6,0xa8,0xb9,0x5e,0x38,0x36 +,0x27,0x26,0x1a,0x26,0x25,0xc1,0x20,0x1e,0x1a,0x2a,0xbd,0xe4,0xa7,0x24,0xa3,0x05,0x02,0x03,0x0c,0xad,0x1b,0xc6,0x2a,0x3c,0x8b,0x88,0x8d,0x8b,0x8b,0x91,0x8b,0x84 +,0x9e,0x92,0x91,0x23,0x94,0x1e,0x0c,0x9b,0xae,0x33,0xc1,0x1d,0x0c,0x12,0x02,0x09,0x03,0x03,0x03,0x07,0x07,0x08,0x0c,0x0f,0x22,0x0c,0xe0,0x43,0x2f,0xb9,0x99,0x98 +,0x8e,0x8a,0x96,0xb6,0x9b,0x8c,0xa7,0x96,0x9b,0xa3,0x9c,0x9c,0x9d,0x90,0x8a,0x8f,0x88,0x87,0x9c,0x83,0xbb,0x2f,0x88,0x80,0x9d,0x0c,0x9b,0x13,0x13,0x2c,0x09,0x0b +,0x06,0x03,0x22,0x4f,0x08,0x07,0x00,0x0b,0x0c,0x01,0x03,0x01,0x0e,0x0d,0x3d,0x1e,0x12,0x0b,0xa8,0x8b,0x8c,0x83,0x8c,0x8f,0x96,0x86,0x86,0x88,0x82,0x83,0x90,0x81 +,0x8a,0x80,0x87,0x8b,0x95,0x9b,0x8d,0xa9,0x99,0x41,0x1f,0x05,0x11,0x0f,0x07,0x04,0x01,0x04,0x04,0x04,0x09,0x08,0x00,0x09,0x03,0x08,0x03,0x0b,0x12,0x0e,0xa8,0xa3 +,0x97,0x8b,0x8b,0x88,0x80,0x87,0x81,0x87,0x8e,0x88,0x91,0x8b,0x94,0x96,0x9b,0x3e,0x8e,0x96,0x1d,0xc0,0x8d,0x86,0xce,0x96,0x18,0x68,0xb1,0x07,0xd4,0x15,0x1f,0x04 +,0x06,0xa1,0x22,0x0f,0x0f,0x11,0x13,0xbb,0x65,0x24,0xa8,0x3b,0x0a,0x03,0x07,0x0b,0x21,0x1a,0xf5,0x14,0x18,0xbc,0x17,0xa7,0x8d,0x89,0x8f,0x3a,0x9a,0x86,0x81,0x8b +,0x89,0x88,0x8b,0x85,0x88,0x88,0x8a,0x84,0x98,0xad,0xbe,0xb0,0x36,0x52,0x25,0x13,0x0f,0x04,0x0f,0x1c,0xbe,0x1b,0x00,0x1a,0xa9,0x5f,0x22,0x07,0x02,0x0e,0xa3,0x13 +,0xc6,0x0f,0x02,0x04,0x05,0x1d,0x0f,0x89,0x1c,0x10,0x9b,0xee,0x0a,0x14,0x8c,0x3f,0x25,0x05,0xad,0x82,0x44,0xbd,0x1b,0xab,0x87,0x80,0x87,0x86,0x8e,0xa4,0xa9,0xdf +,0x90,0x8d,0x92,0xaf,0xb4,0x0c,0x1a,0x2d,0xa1,0x90,0x96,0x9b,0x43,0x8f,0xa6,0x80,0x8b,0x26,0xb2,0xa8,0xd9,0x24,0xbb,0x42,0x17,0x08,0x0a,0x23,0xc8,0xa0,0x5e,0xbb +,0x17,0x0a,0x1a,0x8c,0x83,0x9a,0x1d,0x1e,0x8c,0xb8,0x91,0x92,0x8d,0x20,0x17,0x26,0x8c,0x90,0x03,0x0f,0x36,0xba,0x00,0x1c,0x10,0x01,0x03,0x0d,0x0d,0x01,0xef,0x0d +,0x00,0x08,0x01,0x05,0x0f,0x9a,0x15,0x01,0x12,0x0b,0xaa,0x9e,0x84,0xbd,0x3a,0xb3,0x2f,0x80,0x87,0x8b,0x95,0xa1,0x4a,0xa8,0x83,0x88,0x80,0x89,0xc4,0x8b,0x80,0x84 +,0x80,0x83,0x80,0x84,0x80,0x8e,0x29,0x95,0x83,0x83,0x16,0x0d,0x09,0x21,0x0f,0x0c,0x05,0x01,0x1a,0x03,0x0a,0x05,0x05,0x00,0x07,0x07,0x03,0x01,0x04,0x03,0x04,0x00 +,0x12,0x2e,0x0c,0x0d,0x00,0x07,0x11,0x92,0x89,0x8a,0xaf,0x07,0x41,0x96,0x80,0x8e,0xa6,0x8b,0x91,0x81,0x85,0x80,0x87,0x8a,0x84,0x90,0x80,0x90,0x98,0x8b,0x53,0x93 +,0xb5,0xb3,0x16,0x19,0x33,0x0c,0x1b,0x0d,0xb6,0x08,0x05,0x1d,0x18,0x12,0x0e,0x09,0x12,0xd8,0x21,0x0d,0x1f,0x8c,0x96,0xc8,0x44,0x99,0x3e,0x86,0xaf,0xab,0x8d,0x17 +,0xb6,0x24,0x2b,0x9d,0xa7,0xa2,0x3d,0x20,0xdf,0x26,0x9a,0xb9,0xd7,0x67,0x9f,0x24,0x16,0x1a,0x35,0xbe,0x9d,0xaf,0x37,0x1e,0x09,0x9a,0x9c,0x1c,0x05,0xbd,0x16,0x07 +,0x06,0x1b,0x51,0x11,0x9e,0x8f,0x9f,0xa3,0x93,0x88,0x84,0x82,0x85,0x8d,0x80,0x85,0x88,0x92,0x8c,0x82,0xad,0xa3,0xb7,0xd6,0x57,0x3e,0xba,0xd8,0x70,0x20,0x14,0x0c +,0x0c,0x0d,0x17,0x0f,0x76,0x0c,0x0b,0x0d,0x0c,0x06,0x0d,0x1b,0x10,0x5b,0x0c,0x0e,0x09,0x1d,0xd4,0x2c,0x07,0x0b,0x27,0x39,0x1f,0x34,0x51,0xb5,0xb3,0xc0,0x8c,0x8d +,0xa0,0xa8,0x8d,0x4f,0x92,0x90,0xab,0x8b,0x8e,0x97,0x95,0x98,0xa0,0x9a,0x8e,0x8b,0x8e,0x81,0x99,0xb8,0x9d,0xac,0x98,0x93,0x8d,0x51,0x4f,0xdb,0xa5,0x88,0x93,0x9b +,0x3a,0x9f,0xbb,0x15,0x27,0x1f,0x1c,0x08,0xc3,0x2d,0x04,0x09,0x15,0x12,0x1b,0x15,0x0b,0x11,0x05,0x0a,0x06,0x40,0x0b,0x07,0x0a,0x12,0x19,0x18,0x1c,0x67,0xa3,0x1e +,0xb5,0xc6,0xd5,0x5f,0xaa,0x18,0x9f,0x16,0x0c,0xb0,0x9f,0x8c,0xad,0x9b,0x91,0x85,0x80,0x82,0x81,0x81,0x82,0x82,0x80,0x84,0x85,0x89,0x8d,0x8c,0x87,0x32,0x3d,0xb1 +,0xfb,0x1f,0x12,0x1c,0x03,0x17,0x07,0x01,0x09,0x04,0x01,0x01,0x05,0x05,0x05,0x03,0x01,0x13,0x19,0x14,0x20,0x08,0x0d,0x0f,0x1f,0x6b,0x36,0xa0,0xb0,0xb8,0xa6,0x92 +,0x86,0x89,0x87,0x84,0x8b,0x85,0x87,0x8a,0x89,0x86,0x90,0xa1,0x9e,0x97,0x94,0x1d,0x99,0xa9,0xb2,0xab,0xc6,0xb1,0x2e,0x2c,0x2a,0x1c,0x15,0x25,0x0b,0x1b,0x1d,0x07 +,0x28,0x22,0x1a,0x1f,0x34,0x9f,0x98,0xa2,0x9d,0x99,0x9e,0x96,0x49,0x94,0x3c,0x3f,0x5b,0xbd,0x61,0x2d,0x20,0x35,0x92,0x4f,0x1c,0x0f,0xa8,0xaa,0x2e,0x17,0x19,0x09 +,0x1a,0x17,0x11,0xc1,0x0e,0x25,0xad,0xd0,0xd7,0x23,0x22,0x9a,0xc1,0x1a,0x21,0x0e,0x0a,0x0f,0x13,0x11,0x20,0x3f,0xb0,0xbe,0x8f,0x9a,0x8f,0x81,0x89,0x86,0x84,0x84 +,0x84,0x85,0x90,0x8e,0x86,0x8a,0x9d,0x8e,0xaf,0x8f,0x99,0xae,0x93,0xc8,0xcd,0xc8,0x34,0x2e,0x0b,0x0f,0x1e,0x0c,0x05,0x07,0x0c,0x08,0x0f,0x05,0x13,0x09,0x0c,0x1b +,0x09,0x09,0x0e,0x09,0x09,0x0a,0x0b,0x11,0x19,0x0f,0x08,0x35,0x96,0xe0,0x9b,0x8e,0x99,0x85,0x88,0x84,0x8a,0x88,0x88,0x8c,0x86,0x8d,0x8c,0x8e,0x8c,0x8a,0x99,0x8c +,0x94,0xaa,0x95,0xa6,0xc6,0x9e,0xa0,0x14,0x12,0x1c,0x9d,0x24,0x1c,0x35,0x30,0xa1,0xbf,0x9f,0xaf,0xcd,0xa7,0xa9,0xbe,0x9f,0x10,0x13,0xc3,0x17,0x11,0x17,0x2c,0x32 +,0x13,0x15,0x23,0x15,0x16,0x1b,0x0d,0x1c,0x0c,0x05,0x0b,0x0d,0x1c,0x0c,0x1b,0x14,0x0e,0x3c,0x1d,0x42,0x2d,0x29,0xb2,0x5d,0xc8,0x1d,0x2d,0xd9,0xbd,0x3e,0xa5,0xa1 +,0xa4,0x88,0x84,0x87,0x86,0x81,0x83,0x82,0x82,0x80,0x87,0x83,0x86,0x8c,0x8d,0x94,0xab,0x2a,0xe6,0x3e,0x12,0x19,0x13,0x11,0x0b,0x19,0x10,0x0a,0x08,0x01,0x0d,0x09 +,0x09,0x09,0x0c,0x0f,0x17,0x0c,0x1c,0x19,0x19,0x0d,0x1b,0x1f,0x10,0x12,0x12,0x19,0x16,0xc2,0x1c,0xb9,0xac,0xab,0x8d,0x8f,0x8b,0x91,0x8a,0x88,0x8b,0x8b,0x8c,0x8d +,0xa2,0x8f,0x9a,0x8d,0x95,0xdb,0x8f,0x95,0xc2,0x9e,0xa6,0x44,0xa5,0x2b,0xb9,0x2b,0x19,0x0e,0x1d,0x1d,0x21,0x38,0x14,0xb9,0xa6,0xb8,0xae,0x9a,0xa7,0x97,0x9d,0xa9 +,0x9e,0x39,0x1a,0xbe,0x1b,0x1a,0xfe,0x14,0x1f,0x1a,0x1e,0x17,0x1d,0x2b,0x15,0x1f,0x1b,0x13,0x13,0x11,0x1c,0x1e,0x20,0x1d,0x28,0x32,0xa9,0xac,0xb6,0xa9,0x75,0xb3 +,0x3f,0x3f,0x23,0x1f,0x18,0x13,0x15,0x18,0x26,0x27,0xad,0x9b,0x90,0x8b,0x89,0x83,0x85,0x83,0x83,0x83,0x84,0x87,0x88,0x88,0x88,0x8e,0x94,0x9a,0x92,0x9a,0xaf,0xb5 +,0xbd,0x25,0x17,0x1d,0x15,0x0c,0x07,0x09,0x08,0x05,0x07,0x08,0x08,0x08,0x0c,0x11,0x0b,0x0e,0x0e,0x0e,0x13,0x0f,0x15,0x14,0x1b,0x1e,0x31,0xfb,0x62,0x6d,0xa1,0x8e +,0x90,0x95,0x8f,0x8d,0x8e,0x90,0x8f,0x8e,0x99,0x9f,0x9b,0x99,0x9b,0x9f,0xab,0x9f,0x98,0x9e,0xa6,0xaa,0xae,0xb7,0xed,0xba,0xbd,0x31,0x31,0x39,0x4a,0xc7,0xe3,0xc0 +,0xa3,0x9d,0x9c,0xa4,0xa8,0xaa,0xa4,0xa4,0xb0,0x32,0x19,0x1a,0x1e,0x24,0x1d,0x19,0x18,0x19,0x23,0x2b,0x28,0x27,0x24,0x23,0x20,0x21,0x24,0x1d,0x1b,0x29,0x2e,0x29 +,0x1e,0x24,0x3e,0xbc,0xca,0x2f,0x2d,0x1e,0x1b,0x15,0x11,0x0f,0x0a,0x08,0x0a,0x0c,0x0b,0x0f,0x1d,0x3a,0xa0,0x97,0x90,0x89,0x86,0x83,0x82,0x81,0x81,0x81,0x81,0x81 +,0x81,0x82,0x83,0x84,0x89,0x8e,0x93,0x9d,0xc6,0x1d,0x16,0x11,0x0c,0x07,0x06,0x04,0x03,0x03,0x04,0x06,0x04,0x04,0x07,0x11,0x14,0x0e,0x15,0x1d,0x24,0x2b,0x2f,0x3c +,0x2c,0x33,0xc1,0xbc,0xdf,0x48,0x41,0xbc,0xae,0x66,0x3e,0xd6,0xd6,0xc3,0xf6,0xc8,0xac,0xc2,0xbb,0xad,0xa7,0x9f,0x9e,0x98,0x8e,0x8b,0x8b,0x8c,0x8a,0x8a,0x8d,0x8d +,0x8e,0x95,0x9d,0xbc,0x5d,0xde,0xef,0xbb,0x54,0x2c,0x28,0x1d,0x15,0x1d,0x30,0x51,0xaf,0xe6,0x2e,0x24,0x15,0x19,0x1e,0x2d,0x61,0xe9,0x55,0x4f,0x3c,0x26,0x4e,0xc6 +,0x9e,0x92,0x97,0xa2,0xac,0x51,0x22,0x1e,0x19,0x2d,0x2f,0x20,0x14,0x0c,0x0b,0x0e,0x14,0x18,0x28,0x2a,0x33,0x30,0x2f,0x32,0xc2,0x9e,0x90,0x8c,0x8f,0x92,0x98,0x98 +,0x98,0x96,0x96,0x95,0xa9,0x34,0x1d,0x13,0x13,0x1b,0x1d,0x1f,0x32,0x2c,0x26,0x19,0x18,0x24,0xeb,0x9d,0x94,0x9c,0x9f,0xaf,0xb3,0xa7,0x9e,0x94,0x92,0x94,0x9e,0xc5 +,0x26,0x28,0x3f,0xb9,0xd0,0x38,0x2e,0x25,0x15,0x14,0x19,0x24,0x6f,0x2e,0x23,0x18,0x10,0x17,0x31,0xbf,0xa0,0x9d,0x9c,0x96,0x9c,0xaa,0x9b,0x91,0x8a,0x86,0x89,0x8f +,0x9a,0xa3,0xde,0xd6,0x35,0x6b,0xc5,0x1f,0x0e,0x07,0x04,0x06,0x0a,0x0d,0x0f,0x16,0x18,0x1c,0x1b,0x11,0x2b,0xaa,0x94,0x8e,0x92,0x97,0x92,0x9b,0xa8,0xa5,0xa7,0x9a +,0xa6,0x38,0x1c,0x14,0x11,0x16,0x19,0x1f,0x3c,0x4b,0x3b,0x3c,0x1e,0x2f,0xa7,0x9e,0x8e,0x92,0x99,0x98,0x98,0xa0,0x9d,0x94,0x8e,0x89,0x8e,0x9e,0xa5,0xb2,0x43,0xc5 +,0xb9,0xa9,0x9f,0xcf,0x2c,0x29,0x1b,0x1c,0x28,0x2e,0x38,0x4d,0x2d,0x20,0x1a,0x0e,0x1d,0xce,0xa5,0x96,0x98,0xa4,0xa6,0xb1,0x4e,0xb8,0xa2,0x9e,0xa7,0x41,0x1c,0x10 +,0x09,0x0c,0x0d,0x0d,0x11,0x10,0x0d,0x07,0x05,0x06,0x0f,0x1b,0x3f,0xae,0xa7,0x9a,0x96,0x8f,0x8c,0x88,0x84,0x81,0x81,0x84,0x8e,0x91,0x8e,0x9c,0x35,0x19,0xe4,0x4d +,0x09,0x01,0x03,0x07,0x04,0x01,0x04,0x0c,0x0d,0x09,0x0d,0x0d,0x11,0x1f,0xaf,0x95,0x9b,0xaf,0xaa,0xb5,0xcd,0xca,0xaf,0x97,0x91,0x9d,0xb3,0xb3,0xca,0xab,0x9b,0x8f +,0x8c,0x8b,0x8d,0x90,0x9a,0xae,0x9b,0x8f,0x87,0x89,0x96,0x9b,0x9b,0xa9,0x5b,0x2e,0xac,0x8d,0x91,0xc6,0x4d,0x9f,0x9d,0xaa,0xb9,0x8f,0x84,0x8f,0xb4,0xa4,0x9d,0x3c +,0x1a,0x22,0xba,0x23,0x08,0x08,0x12,0x0a,0x03,0x06,0x15,0x3e,0x18,0x0e,0x1a,0x1f,0x16,0x1b,0x1d,0x36,0xe3,0x2c,0x14,0x0a,0x05,0x0a,0x10,0x15,0x17,0x16,0x1e,0x22 +,0x15,0x0d,0x25,0xa8,0x8f,0x8a,0x90,0x93,0x8d,0x8f,0x8f,0x91,0x8d,0x87,0x88,0x8f,0xa6,0xe5,0x27,0x20,0x1d,0x2b,0x3b,0x1b,0x13,0x31,0xad,0x4a,0x50,0x90,0x81,0x83 +,0x93,0x8c,0x82,0x82,0x8e,0x96,0x83,0x80,0x8b,0xae,0xa9,0xa2,0x37,0x16,0x1b,0x34,0x24,0x12,0x0e,0x0d,0x07,0x06,0x0d,0x16,0x1d,0x13,0x0e,0x0d,0x08,0x04,0x03,0x09 +,0x11,0x1f,0x1d,0x10,0x13,0x1c,0x1e,0x49,0x53,0xa1,0x8f,0x9a,0xa4,0xbd,0x28,0x2f,0x36,0x3f,0xbf,0x29,0x1d,0x1f,0x18,0x0a,0x07,0x12,0x48,0x47,0x13,0x1d,0x98,0x8e +,0x9f,0x91,0x82,0x80,0x81,0x81,0x80,0x80,0x83,0x86,0x83,0x80,0x88,0xa3,0xb1,0xb2,0x19,0x05,0x06,0x0f,0x14,0x0e,0x08,0x0b,0x0b,0x08,0x09,0x0b,0x12,0x2a,0x32,0x24 +,0x14,0x0e,0x0f,0x1b,0x28,0x48,0xb9,0xbd,0xc9,0x42,0x20,0x1b,0x43,0xcb,0xb1,0xe2,0x35,0x38,0x2a,0x17,0x1a,0x21,0x44,0xba,0x3f,0x24,0x1a,0x16,0x0f,0x2c,0xbb,0xb2 +,0xe0,0xb3,0x8d,0x86,0x99,0x95,0x82,0x80,0x80,0x83,0x83,0x80,0x84,0x9b,0x96,0x88,0x8b,0xa2,0x2e,0x3a,0x19,0x06,0x04,0x0b,0x0d,0x0b,0x0f,0x19,0x1f,0x0f,0x0b,0x1e +,0xd9,0xab,0xa3,0xb2,0xbd,0x56,0x1e,0x16,0x14,0x16,0x21,0x1f,0x15,0x0d,0x08,0x08,0x0d,0x11,0x16,0x1c,0x3a,0x45,0x29,0x17,0x11,0x30,0xb2,0xa0,0xa1,0xb9,0xa7,0xa8 +,0x2f,0x2a,0xe9,0x9e,0x9d,0xc1,0xa3,0x94,0xa1,0x51,0x9a,0x85,0x84,0x88,0x86,0x81,0x82,0x96,0xa2,0x87,0x85,0x91,0xc4,0xc0,0xab,0x21,0x0b,0x0e,0x1a,0x29,0x4a,0x64 +,0x40,0x25,0x27,0x35,0xc6,0xc7,0xcd,0xaf,0xef,0x1e,0x10,0x0a,0x0a,0x11,0x16,0x1b,0x19,0x12,0x13,0x0f,0x0d,0x0f,0x1f,0xb9,0xa0,0x9f,0xb0,0xb2,0xab,0xa5,0x99,0x94 +,0x94,0x92,0x94,0xa5,0x26,0x0e,0x19,0x34,0x1e,0x0e,0x10,0x3d,0xc2,0x1c,0x23,0x9a,0x89,0x89,0x8a,0x84,0x84,0x8a,0x92,0x8a,0x83,0x8a,0x92,0x90,0x91,0xa5,0x1e,0x10 +,0x24,0x28,0x22,0x1f,0x16,0x13,0x0f,0x09,0x0b,0x0e,0x13,0x25,0x23,0x18,0x0d,0x0a,0x0b,0x0d,0x0e,0x0f,0x1e,0x3c,0x2c,0x1f,0x16,0x1e,0xb4,0x9f,0x95,0x91,0x95,0x90 +,0x96,0xab,0xac,0xa2,0x98,0x99,0xaa,0xca,0x26,0x0f,0x0d,0x1c,0x2a,0x17,0x16,0x54,0xa5,0x3e,0x16,0xa8,0x85,0x84,0x87,0x83,0x80,0x80,0x87,0x8b,0x83,0x83,0x86,0x8c +,0x8e,0x9c,0x24,0x0d,0x0b,0x0c,0x09,0x08,0x0c,0x0c,0x09,0x06,0x03,0x09,0x0f,0x16,0x1b,0x13,0x16,0x1c,0x16,0x12,0x15,0x24,0xb8,0xa6,0xae,0x5d,0x4b,0x64,0xd5,0xb1 +,0xb9,0xa7,0x9c,0xac,0x4f,0x1f,0x16,0x29,0x3f,0x35,0x37,0x2f,0x2b,0x17,0x09,0x0c,0x14,0x19,0x19,0x4d,0x9c,0xa9,0x4b,0x9f,0x86,0x81,0x84,0x82,0x80,0x80,0x81,0x89 +,0x86,0x81,0x87,0x95,0x9b,0xa2,0x2c,0x0d,0x06,0x07,0x06,0x07,0x0b,0x0d,0x0a,0x06,0x08,0x0d,0x18,0x23,0x27,0xd6,0xae,0xbd,0x5b,0x23,0x27,0x7c,0xbe,0xb0,0xbf,0x3b +,0x28,0x1a,0x11,0x13,0x19,0x26,0x49,0x41,0x2e,0x1c,0x18,0x1d,0x2b,0x28,0x27,0xbb,0xa7,0xf8,0x19,0x16,0xce,0xa7,0x45,0xb0,0x91,0x8b,0x95,0xa4,0x8c,0x83,0x86,0x87 +,0x82,0x80,0x84,0x8f,0x91,0x89,0x8d,0xad,0xe0,0xa7,0x43,0x0e,0x05,0x04,0x09,0x0b,0x0d,0x10,0x10,0x16,0x18,0x19,0x1d,0x2a,0xb4,0x9d,0x9e,0xbe,0x2a,0x24,0x1a,0x14 +,0x14,0x17,0x1f,0x23,0x17,0x0f,0x0b,0x0b,0x18,0x1f,0x2b,0x28,0x35,0xca,0x43,0x38,0x3c,0xb0,0x9a,0x92,0x8b,0x90,0xab,0xcd,0xab,0x99,0xc3,0x28,0xae,0x95,0xa3,0x25 +,0x2b,0x98,0x8c,0x94,0x8c,0x83,0x82,0x89,0x96,0x8e,0x8c,0x8f,0x97,0x8f,0x8e,0xc4,0x1e,0x18,0x19,0x1f,0x1a,0x26,0x40,0x27,0x19,0x12,0x0f,0x14,0x1a,0x1f,0x24,0x19 +,0x13,0x0f,0x0c,0x09,0x0a,0x12,0x1c,0x1e,0x12,0x0e,0x16,0x16,0x1a,0x23,0x3a,0xa5,0x9a,0x9e,0xa8,0xb3,0xa3,0x96,0x95,0x9a,0x96,0x96,0xae,0x1d,0x13,0x1f,0x1f,0x12 +,0x11,0x2a,0x39,0x19,0x14,0xd0,0x91,0x97,0x91,0x84,0x80,0x81,0x88,0x87,0x81,0x81,0x83,0x86,0x85,0x87,0x96,0x42,0x19,0x16,0x16,0x13,0x0e,0x0a,0x07,0x07,0x06,0x06 +,0x08,0x0d,0x16,0x18,0x13,0x0d,0x0e,0x0f,0x14,0x1f,0x29,0xbc,0xb2,0xbd,0xbe,0x58,0x61,0xaa,0xa0,0x9a,0x9a,0xa9,0xbb,0x41,0x22,0x26,0x2c,0x28,0x4e,0xbb,0x38,0x10 +,0x0b,0x13,0x24,0x13,0x0c,0x28,0xa6,0xb0,0x25,0x6d,0x8b,0x84,0x85,0x82,0x80,0x80,0x82,0x84,0x83,0x82,0x86,0x89,0x8b,0x95,0xed,0x15,0x0b,0x0a,0x0a,0x08,0x08,0x08 +,0x06,0x05,0x03,0x07,0x0e,0x1b,0x2a,0x2f,0x2c,0x29,0x25,0x33,0xbf,0xb5,0xa7,0x9f,0xaa,0xf6,0x21,0x1e,0x2f,0x34,0x2c,0x21,0x1f,0x20,0x12,0x0c,0x12,0x2c,0xcc,0x5a +,0x21,0x3f,0xca,0x22,0x1b,0x32,0x9d,0x9a,0x3f,0x2d,0xa3,0xac,0x34,0x75,0x8f,0x84,0x87,0x8e,0x8a,0x84,0x89,0x90,0x8b,0x83,0x83,0x8c,0xa0,0xa1,0xd8,0x15,0x10,0x17 +,0x21,0x18,0x0e,0x0c,0x0b,0x0b,0x0d,0x1a,0x29,0xbe,0xcc,0x35,0x2c,0x24,0x1a,0x1b,0x21,0x27,0x29,0x17,0x0e,0x0d,0x0a,0x0b,0x11,0x15,0x1c,0x23,0x1e,0x19,0x1d,0x18 +,0x27,0xba,0x9b,0x96,0xab,0xa5,0x91,0x9a,0x5f,0x4c,0x9d,0x8e,0xa0,0x2c,0x2c,0xc7,0x22,0x0f,0x2b,0x92,0x90,0x9a,0x94,0x89,0x88,0x90,0x8c,0x88,0x86,0x86,0x8a,0x8e +,0x8f,0xa5,0x56,0xcb,0xaf,0xaf,0x60,0x2d,0x1c,0x17,0x16,0x19,0x19,0x1d,0x1d,0x18,0x12,0x0b,0x07,0x0e,0x0f,0x0e,0x13,0x15,0x11,0x0d,0x0a,0x0c,0x1c,0x22,0x47,0x3a +,0x35,0x45,0xb0,0x9e,0xaf,0xba,0x8d,0x82,0x93,0x9b,0xa7,0xb0,0x98,0x83,0x20,0x00,0x9d,0x98,0x33,0x1f,0x07,0x0b,0x00,0x0a,0x34,0x24,0x02,0x11,0x83,0x28,0x08,0x09 +,0x1d,0xde,0x1d,0xaf,0x27,0x13,0x1f,0x0b,0x01,0x0d,0xa2,0xbd,0x09,0x03,0xb5,0x8d,0x47,0x1f,0x8f,0x80,0x84,0x93,0xb2,0x89,0x85,0x81,0x80,0x85,0x82,0x80,0x80,0x82 +,0x80,0x80,0x82,0x8e,0x8e,0x94,0xc0,0x8d,0x89,0xae,0x27,0x96,0x99,0x17,0x16,0x28,0xbf,0x6f,0x24,0x0d,0x02,0x0e,0xfe,0x0e,0x00,0x05,0x06,0x01,0x01,0x0a,0x04,0x03 +,0x14,0x0b,0x00,0x01,0x04,0x05,0x00,0x0a,0x16,0x07,0x00,0x06,0x07,0x07,0x12,0x18,0x0a,0x00,0x0d,0xac,0xb7,0x0f,0x2c,0x8f,0x8f,0x8b,0x8e,0x8e,0x8a,0x86,0x81,0x82 +,0x81,0x80,0x80,0x82,0x81,0x80,0x80,0x84,0x95,0x8a,0x80,0x84,0x8e,0x99,0x8f,0x84,0x80,0x88,0x92,0x84,0x80,0x82,0x81,0x81,0x85,0x89,0x81,0x82,0x8a,0x8e,0x80,0x84 +,0xa6,0x91,0x80,0x84,0x8b,0x86,0x82,0x86,0x9f,0x1c,0x0b,0x03,0x1b,0x57,0x08,0x00,0x03,0x05,0x01,0x01,0x04,0x02,0x00,0x00,0x00,0x00,0x00,0x03,0x05,0x01,0x01,0x03 +,0x02,0x01,0x03,0x06,0x09,0x07,0x03,0x02,0x00,0x03,0x08,0x03,0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x04,0x04,0x02,0x00,0x03,0x16,0x1b,0x07,0x18,0x98,0x96,0xab,0x8e +,0x82,0x83,0x87,0x85,0x95,0x6f,0x8f,0x80,0x83,0x8b,0x87,0x80,0x84,0x8a,0x8b,0x88,0x84,0x81,0x83,0x8e,0x89,0x80,0x81,0x86,0x83,0x80,0x80,0x83,0x87,0x82,0x80,0x80 +,0x81,0x83,0x81,0x80,0x80,0x8a,0x9a,0x8d,0x88,0x8f,0xa1,0x3e,0x19,0x16,0x14,0x0b,0x03,0x04,0x0b,0x0f,0x0a,0x0b,0x1f,0x2e,0x4e,0xad,0x9a,0x95,0x9a,0x9e,0xa3,0x98 +,0x86,0x81,0x8b,0x97,0x88,0x81,0x82,0x87,0x8c,0x8e,0x94,0x91,0x8e,0x9b,0x9b,0x89,0x89,0x9d,0x53,0x34,0x23,0x2a,0xce,0x2b,0x0f,0x09,0x05,0x01,0x00,0x0a,0x11,0x04 +,0x00,0x01,0x03,0x05,0x04,0x05,0x09,0x14,0x0d,0x01,0x00,0x00,0x04,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x05 +,0x05,0x01,0x01,0x06,0x11,0x15,0x0b,0x07,0x12,0xa8,0x9f,0x2b,0x26,0x2f,0x23,0x16,0x1f,0xe3,0xf2,0x45,0x4a,0x37,0xc5,0x93,0x8b,0x8e,0x87,0x80,0x80,0x80,0x80,0x80 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x85,0x86,0x83,0x87,0x93,0xaf,0xa9,0x9c,0xaa,0x2c,0x1c,0x2e,0x48,0x2d +,0x16,0x13,0x32,0xa3,0xa9,0x37,0x26,0x2f,0x4a,0xcb,0xcf,0x4e,0x29,0x28,0x2a,0x18,0x15,0x22,0x24,0x0c,0x04,0x09,0x0f,0x0e,0x0e,0x11,0x11,0x0f,0x09,0x03,0x00,0x07 +,0x1b,0x14,0x07,0x05,0x05,0x06,0x06,0x09,0x0a,0x06,0x05,0x02,0x02,0x03,0x0b,0x1b,0x1f,0x25,0x20,0x1c,0x11,0x0d,0x0e,0x19,0x28,0x1e,0x0d,0x08,0x11,0x25,0x1c,0x12 +,0x0e,0x11,0x17,0x17,0x1c,0x22,0x2b,0x31,0x2f,0x1e,0x1d,0x2c,0xba,0xb0,0xaa,0x96,0x8e,0x8d,0x8a,0x88,0x8a,0x8b,0x8f,0xa3,0x2f,0x44,0xa4,0xb5,0x2b,0x30,0xae,0x9f +,0xa9,0xcd,0x4f,0x5f,0xa1,0x94,0x8e,0x88,0x83,0x82,0x83,0x83,0x81,0x80,0x80,0x81,0x81,0x82,0x82,0x82,0x83,0x83,0x82,0x82,0x89,0x9c,0xda,0x33,0x24,0x1b,0x0e,0x08 +,0x06,0x03,0x02,0x01,0x01,0x01,0x03,0x02,0x01,0x02,0x05,0x07,0x0a,0x0d,0x0e,0x0c,0x09,0x07,0x0a,0x19,0x33,0x3e,0x3f,0xaf,0x98,0x93,0x91,0x8d,0x8d,0x93,0x99,0x9c +,0x9c,0x92,0x88,0x84,0x85,0x87,0x88,0x8b,0x8c,0x88,0x87,0x88,0x8b,0x8f,0x9b,0xa8,0x9f,0x99,0xa7,0xae,0xa9,0xa9,0xa9,0xac,0xa4,0x92,0x8b,0x8c,0x91,0xa2,0xa6,0x9d +,0x9e,0xa7,0xb8,0xc0,0xb0,0xbb,0x47,0x2d,0x25,0x1d,0x10,0x0c,0x0a,0x0a,0x0e,0x11,0x11,0x19,0x25,0x1f,0x0f,0x0d,0x17,0x24,0x2b,0x2e,0x2a,0x2d,0xb6,0xaf,0xbe,0xbb +,0xd9,0x44,0x26,0x1a,0x11,0x0a,0x0d,0x13,0x0e,0x0b,0x0b,0x0b,0x0b,0x0f,0x1d,0x4e,0xac,0x9f,0x93,0x8b,0x88,0x87,0x87,0x87,0x87,0x85,0x84,0x85,0x85,0x85,0x84,0x84 +,0x85,0x88,0x8e,0xa0,0xe3,0x29,0x1b,0x15,0x0f,0x0d,0x0c,0x0a,0x08,0x06,0x03,0x04,0x06,0x03,0x02,0x02,0x03,0x06,0x0c,0x0f,0x11,0x11,0x15,0x15,0x17,0x28,0x45,0xec +,0xbd,0xb6,0xbd,0xae,0x9e,0x96,0x95,0x96,0x92,0x90,0x93,0x8f,0x8a,0x87,0x88,0x8a,0x90,0x9e,0x99,0x95,0x99,0x9e,0xa1,0xa5,0xa8,0xb4,0xde,0x4a,0x46,0x34,0x1c,0x15 +,0x1b,0x26,0x75,0xa6,0xa2,0x9c,0x95,0x94,0x94,0x95,0x94,0x94,0x9f,0xaf,0xb9,0xc5,0xba,0xc8,0x41,0x28,0x1e,0x1a,0x14,0x0e,0x0f,0x14,0x13,0x0f,0x0d,0x0c,0x0e,0x14 +,0x14,0x14,0x1a,0x28,0x2b,0x4c,0xb8,0xc9,0xdb,0x3d,0x26,0x1e,0x1a,0x18,0x14,0x12,0x18,0x19,0x1c,0x1e,0x1e,0x21,0x2b,0x39,0x35,0x42,0xb3,0x98,0x8d,0x89,0x86,0x84 +,0x83,0x82,0x82,0x82,0x84,0x85,0x86,0x88,0x86,0x89,0x8e,0x92,0x99,0x9f,0xb0,0x49,0x2b,0x1b,0x16,0x14,0x0d,0x09,0x07,0x07,0x07,0x07,0x06,0x04,0x05,0x08,0x0a,0x0d +,0x10,0x15,0x13,0x11,0x11,0x12,0x14,0x15,0x20,0x2e,0xba,0xa2,0xad,0xa5,0x98,0x91,0x90,0x97,0x9c,0x9d,0x9b,0x93,0x8f,0x8c,0x8a,0x8a,0x8b,0x8c,0x8e,0x91,0x95,0x9b +,0xa1,0xad,0xc3,0x70,0x3f,0x2f,0x33,0x31,0x36,0x22,0x23,0x3b,0xcf,0xa2,0xa5,0xb8,0xaf,0xa2,0x9c,0x9c,0xa6,0x9e,0x9b,0x9e,0x9e,0x9e,0x9f,0xa7,0xe9,0x2e,0x2a,0x1c +,0x13,0x10,0x12,0x11,0x10,0x13,0x17,0x14,0x17,0x18,0x16,0x10,0x0d,0x15,0x1c,0x2e,0x30,0x1b,0x1c,0x2b,0x2d,0x2d,0x25,0x21,0x1c,0x12,0x13,0x15,0x16,0x1b,0x23,0x28 +,0x4f,0xc5,0xad,0x9a,0x91,0x8a,0x86,0x85,0x84,0x85,0x85,0x84,0x85,0x85,0x88,0x88,0x88,0x88,0x87,0x8b,0x90,0x91,0x9d,0xbb,0x47,0x27,0x1d,0x11,0x0e,0x0e,0x0c,0x0d +,0x0c,0x0a,0x0a,0x0b,0x08,0x05,0x04,0x05,0x06,0x07,0x08,0x0a,0x09,0x0b,0x0f,0x17,0x17,0x17,0x23,0x33,0xd0,0xc6,0x66,0xb2,0x9f,0x9b,0x95,0x95,0x94,0x93,0x93,0x8d +,0x8b,0x8b,0x8b,0x8e,0x90,0x8e,0x92,0x9a,0x9e,0x9f,0x9f,0xa5,0xae,0xb6,0x65,0x32,0x2e,0x2b,0x24,0x18,0x19,0x26,0x55,0xb2,0xba,0xaf,0x9c,0x96,0x97,0x98,0x99,0x9a +,0xa3,0xa8,0xac,0xc7,0x4f,0x41,0x39,0x4c,0x36,0x1d,0x19,0x15,0x12,0x12,0x11,0x11,0x0f,0x0d,0x0e,0x0f,0x14,0x17,0x1b,0x30,0x4a,0xc7,0xcb,0x3e,0x41,0x4a,0x3f,0x3c +,0x28,0x1b,0x13,0x13,0x1a,0x1d,0x1f,0x25,0x2a,0x3e,0xbe,0xbe,0xac,0x9e,0x95,0x8d,0x8a,0x88,0x86,0x86,0x84,0x83,0x83,0x83,0x87,0x89,0x8a,0x8b,0x8c,0x96,0x9f,0xa3 +,0xb7,0xdf,0x40,0x25,0x19,0x13,0x14,0x0f,0x0b,0x0a,0x0a,0x09,0x0a,0x09,0x06,0x06,0x07,0x08,0x0a,0x0c,0x0e,0x0c,0x0b,0x0f,0x12,0x14,0x12,0x15,0x25,0x5e,0xa6,0xa5 +,0xab,0x9a,0x8f,0x8e,0x8f,0x92,0x96,0x98,0x98,0x92,0x91,0x93,0x8f,0x8f,0x8f,0x8e,0x93,0x94,0x98,0x9e,0xa4,0xad,0xbb,0x4c,0x24,0x25,0x30,0x30,0x27,0x1c,0x27,0x72 +,0xac,0xa5,0xb8,0xb5,0xa5,0xa1,0x9c,0x9b,0x9c,0x9e,0x9f,0x9e,0x9f,0xa8,0xa5,0xa8,0xc9,0xe1,0x2b,0x1a,0x14,0x10,0x12,0x14,0x12,0x0e,0x0b,0x0c,0x14,0x17,0x17,0x12 +,0x13,0x1d,0x25,0x2d,0x27,0x21,0x2f,0x39,0x30,0x2f,0x1f,0x16,0x13,0x11,0x14,0x11,0x10,0x17,0x18,0x29,0xe1,0xb6,0x9e,0x96,0x8d,0x87,0x85,0x85,0x84,0x85,0x83,0x83 +,0x84,0x86,0x8b,0x8a,0x8a,0x8c,0x8f,0x9b,0x9f,0xa5,0xbc,0x53,0x29,0x19,0x15,0x11,0x0e,0x0d,0x0c,0x0e,0x0e,0x0e,0x13,0x0d,0x0c,0x0c,0x0c,0x0d,0x0c,0x0b,0x0a,0x09 +,0x0c,0x0f,0x0e,0x11,0x12,0x1b,0x2c,0xf8,0xab,0xaf,0xa2,0x97,0x91,0x8f,0x8d,0x8e,0x8f,0x8f,0x90,0x91,0x97,0x98,0x99,0x9f,0xa1,0xa8,0xa1,0x9e,0x9c,0x9b,0x9a,0xa5 +,0xac,0xb3,0xf7,0xcd,0x3c,0x43,0x24,0x1d,0x3e,0x2e,0x23,0x1d,0x1b,0x35,0x51,0xb6,0xd8,0xb3,0xa7,0x99,0x9b,0xa5,0x98,0x9b,0x9d,0xc9,0xe2,0x46,0x56,0x20,0x18,0x1a +,0x1f,0x1e,0x12,0x13,0x16,0x2f,0x22,0x1d,0x16,0x1c,0x4a,0x3d,0x4a,0xdd,0xba,0xae,0xa1,0xa2,0x9d,0x98,0x9e,0xcc,0x3a,0x6f,0x6f,0x59,0x4d,0x65,0xef,0x48,0x3f,0x3f +,0x42,0xb7,0xa9,0xde,0x5f,0xd1,0xc7,0x6e,0x2e,0x2a,0x25,0x1b,0x1c,0x20,0x1e,0x28,0x28,0x20,0x31,0xba,0xa4,0xa8,0xb3,0xa0,0x99,0x96,0x9e,0xa8,0x9f,0xa5,0xaf,0xec +,0x31,0x2b,0x2d,0x1d,0x1c,0x23,0x23,0x2c,0x2b,0x2a,0xb9,0xd1,0xed,0x63,0xed,0x9e,0x99,0x99,0x9a,0x97,0x9a,0x90,0x8f,0x90,0x8d,0x9a,0xa3,0xab,0xae,0xbf,0x31,0x23 +,0x1f,0x29,0x26,0x1d,0x19,0x1e,0x22,0x1f,0x15,0x17,0x1c,0x16,0x18,0x12,0x12,0x14,0x11,0x11,0x14,0x19,0x25,0x24,0x1b,0x20,0x39,0xd8,0xb0,0xb0,0xc7,0xa1,0x98,0x94 +,0x95,0x98,0x90,0x94,0x9d,0xaf,0xb0,0xb0,0x61,0x2d,0x1b,0x22,0x4a,0xbb,0xa8,0xaa,0x9c,0x8e,0x8f,0x96,0x9b,0x92,0x8d,0x8c,0x8f,0x97,0x90,0x8e,0x8f,0x97,0x9d,0x99 +,0x9b,0xaf,0x5d,0x47,0x37,0x30,0x1b,0x0f,0x12,0x10,0x0f,0x12,0x0f,0x18,0x1e,0x17,0x16,0x15,0x16,0x17,0x17,0x11,0x0e,0x0f,0x15,0x1e,0x1c,0x21,0x32,0x36,0x39,0x3b +,0xbe,0xb1,0xa0,0x9b,0x9a,0x97,0x9a,0xa2,0xaa,0xae,0xb8,0x73,0x20,0x18,0x17,0x18,0x19,0x1a,0x16,0x1c,0x37,0xdd,0xa9,0xa4,0x98,0x8e,0x92,0x95,0x90,0x8d,0x8b,0x8b +,0x8f,0x8f,0x8b,0x8a,0x8a,0x8a,0x8b,0x89,0x8a,0x8e,0x94,0x99,0x9a,0xa0,0xb2,0xfe,0x32,0x27,0x22,0x29,0x1f,0x1b,0x1b,0x10,0x0b,0x08,0x05,0x03,0x03,0x01,0x00,0x00 +,0x01,0x02,0x03,0x03,0x08,0x0f,0x0d,0x0f,0x22,0xbc,0xa7,0xab,0xa3,0x93,0x93,0x99,0x99,0x9c,0x98,0x98,0xaa,0xa9,0x9f,0x9e,0x97,0x98,0x9d,0x98,0x92,0x8e,0x8c,0x8c +,0x8c,0x89,0x89,0x8d,0x8e,0x8c,0x8b,0x8b,0x91,0x94,0x8e,0x8b,0x8b,0x8d,0x8e,0x8c,0x8c,0x93,0x9e,0xad,0xbe,0xce,0x49,0x27,0x23,0x1f,0x19,0x12,0x0d,0x0e,0x0d,0x0a +,0x08,0x06,0x05,0x07,0x07,0x04,0x03,0x04,0x08,0x0a,0x08,0x0a,0x10,0x16,0x13,0x12,0x1f,0x2f,0x2d,0x22,0x26,0xb3,0xa3,0xbc,0xa8,0x96,0x8f,0x8e,0x8e,0x88,0x85,0x86 +,0x85,0x83,0x83,0x85,0x85,0x84,0x82,0x84,0x8a,0x8a,0x8a,0x98,0x6f,0x40,0x4e,0x2e,0x0f,0x07,0x0a,0x0d,0x0d,0x0d,0x0d,0x15,0x17,0x10,0x11,0x11,0x14,0x18,0x15,0x13 +,0x18,0x16,0x14,0x17,0x14,0x16,0x1a,0x19,0x15,0x13,0x16,0x1b,0x24,0x1e,0x1d,0x2a,0x34,0xe0,0xc0,0xab,0x96,0x96,0x9b,0x9a,0x97,0x8f,0x8f,0x98,0x97,0x8f,0x8f,0x91 +,0x94,0x92,0x8e,0x94,0x9d,0xa0,0xa6,0xaa,0xaf,0xb6,0xb6,0xaf,0xac,0xaa,0xb7,0xec,0xcb,0xc3,0x3f,0x2b,0x1a,0x14,0x1a,0x19,0x16,0x13,0x13,0x1b,0x1a,0x12,0x1a,0x2c +,0x2b,0x1d,0x14,0x1c,0x23,0x14,0x0f,0x16,0x21,0x23,0x18,0x1d,0xbc,0xad,0xbd,0xa5,0x91,0x8a,0x8d,0x90,0x8a,0x84,0x83,0x84,0x85,0x85,0x84,0x87,0x8d,0x90,0x98,0xaa +,0x3e,0x1f,0x20,0x1b,0x0e,0x0c,0x0c,0x0e,0x0d,0x0a,0x09,0x0a,0x08,0x09,0x0a,0x09,0x0c,0x0f,0x17,0x1d,0x1d,0x2a,0x37,0x33,0x36,0x37,0x47,0xdb,0x47,0x23,0x2e,0xb2 +,0xad,0xaf,0xb9,0x9d,0x91,0x97,0x9a,0x95,0x8e,0x8c,0x8e,0x98,0x96,0x94,0x98,0x9a,0x9d,0x9c,0x99,0x9f,0xa9,0xad,0xb0,0xb1,0xb4,0xb9,0x5c,0x42,0xc8,0xa4,0x9a,0xa2 +,0xa1,0x9e,0xa9,0xba,0x4d,0xcf,0xbd,0x38,0x18,0x16,0x29,0x34,0x1f,0x14,0x1c,0x2f,0x1c,0x0e,0x0e,0x14,0x10,0x0b,0x08,0x09,0x0c,0x0a,0x0a,0x0f,0x18,0x24,0x26,0x2b +,0xb6,0x99,0x90,0x8d,0x8b,0x8d,0x8a,0x86,0x84,0x83,0x84,0x84,0x82,0x83,0x85,0x89,0x8b,0x8d,0x94,0xaa,0x34,0x24,0x18,0x0c,0x07,0x06,0x08,0x06,0x04,0x04,0x06,0x05 +,0x06,0x07,0x07,0x0b,0x0f,0x16,0x1c,0x19,0x1f,0x47,0x50,0xeb,0xe8,0xde,0xa8,0x9f,0xa9,0xad,0xa0,0x99,0x97,0x9a,0x97,0x8f,0x93,0x9a,0x9c,0x98,0x98,0x9e,0xa8,0xba +,0xaa,0xa3,0xac,0xae,0xac,0x9d,0x9a,0x9f,0xa3,0xa1,0xad,0xb0,0xa3,0xab,0xb9,0xb3,0xa6,0x97,0x99,0x9a,0x93,0x93,0x96,0xa0,0xa8,0xa8,0xaf,0x2c,0x18,0x1a,0x1c,0x14 +,0x0b,0x0a,0x0d,0x0d,0x09,0x08,0x08,0x0a,0x0a,0x0a,0x08,0x09,0x0a,0x0b,0x10,0x1a,0x28,0x53,0xc5,0xa4,0x91,0x8b,0x87,0x85,0x85,0x85,0x83,0x82,0x82,0x82,0x84,0x83 +,0x83,0x87,0x8d,0x93,0x9a,0xa8,0x60,0x1c,0x14,0x0f,0x09,0x08,0x06,0x07,0x06,0x03,0x04,0x06,0x07,0x09,0x0a,0x0c,0x0e,0x13,0x1e,0x2d,0x39,0x58,0xb0,0xa0,0xa8,0xba +,0xe5,0xc8,0xb7,0xcd,0x2d,0x26,0x38,0x2e,0x36,0x31,0x49,0xb3,0xcf,0x5b,0xca,0xae,0xa8,0xb2,0xae,0xa2,0x9a,0x96,0x98,0x93,0x8f,0x8b,0x8b,0x8b,0x8c,0x8d,0x8f,0x8e +,0x8e,0x98,0x9e,0x9e,0x9b,0x9c,0xab,0xaa,0xa5,0xbc,0x36,0x26,0x26,0x2a,0x1f,0x14,0x12,0x14,0x10,0x0c,0x0d,0x0f,0x15,0x16,0x0e,0x0d,0x11,0x14,0x17,0x14,0x11,0x1b +,0x1d,0x1c,0x22,0x24,0x2f,0xf9,0xc9,0xb0,0xad,0xa5,0x95,0x93,0x95,0x91,0x8c,0x88,0x88,0x88,0x86,0x85,0x89,0x8d,0x90,0x90,0x92,0x9c,0xca,0x37,0x2e,0x23,0x20,0x15 +,0x11,0x14,0x12,0x0e,0x0b,0x0a,0x09,0x0a,0x0b,0x09,0x08,0x08,0x0c,0x11,0x0e,0x14,0x1e,0x1f,0x1c,0x1e,0x26,0x2e,0x2d,0x23,0x28,0x4f,0xb2,0xa7,0xad,0xa1,0x92,0x8d +,0x8e,0x8f,0x8d,0x8c,0x8d,0x8e,0x92,0x91,0x94,0x97,0x91,0x95,0x9a,0x96,0x9a,0xa8,0xa2,0xb7,0xad,0xab,0xb8,0xc5,0xe9,0xd4,0xba,0xb0,0xaa,0x99,0x9b,0xa4,0xac,0xa9 +,0xa3,0x9c,0xb4,0xc4,0x41,0xef,0x3a,0x1f,0x1d,0x12,0x17,0x0e,0x0a,0x09,0x06,0x07,0x08,0x04,0x05,0x05,0x07,0x0a,0x0c,0x0e,0x16,0x1f,0x2a,0xd1,0x9f,0x90,0x8a,0x8b +,0x8d,0x84,0x83,0x82,0x82,0x83,0x80,0x83,0x82,0x87,0x8b,0x8e,0x99,0xaa,0x34,0x1b,0x18,0x0b,0x0c,0x08,0x06,0x08,0x04,0x06,0x05,0x06,0x05,0x06,0x07,0x07,0x0a,0x10 +,0x1c,0x1e,0x27,0xcc,0xac,0x9c,0xac,0x99,0x9c,0x94,0x97,0xab,0xa3,0xaa,0xa4,0xb5,0xaf,0xaf,0xa9,0xa9,0xde,0xb9,0xac,0xca,0xa5,0xd6,0xad,0xa3,0xae,0xa8,0xa5,0x99 +,0x97,0x94,0x96,0x9a,0x93,0x97,0x90,0x8f,0x96,0x8f,0x90,0x8f,0x93,0x90,0x97,0x95,0xa1,0xad,0xc6,0x49,0x48,0x2b,0x1a,0x17,0x17,0x0f,0x13,0x0d,0x10,0x0d,0x0b,0x08 +,0x09,0x0a,0x09,0x0d,0x09,0x08,0x0a,0x0d,0x12,0x1e,0x1c,0x3b,0xb0,0xa9,0x9c,0x9a,0x96,0x8f,0x8d,0x90,0x8b,0x8a,0x88,0x87,0x89,0x89,0x85,0x8a,0x8e,0x96,0x98,0x9c +,0xbf,0x27,0x1c,0x17,0x13,0x18,0x0a,0x0d,0x0c,0x0c,0x0b,0x0a,0x0e,0x0c,0x0f,0x14,0x11,0x12,0x14,0x18,0x23,0x16,0x33,0x2d,0x2f,0x2c,0x21,0x3e,0x32,0x5a,0x2d,0x26 +,0x3d,0xbb,0xed,0x6d,0xba,0x9d,0x99,0x98,0x97,0x98,0x94,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8d,0x8c,0x8c,0x8c,0x91,0x98,0x9d,0x9f,0x9f,0xaa,0xad,0x3f,0xbd,0xcb,0xd9 +,0xbc,0x3d,0xa0,0xb1,0xdd,0x3d,0x5e,0xcd,0xfb,0x47,0x34,0x4e,0x2d,0x27,0x39,0x34,0x29,0x2b,0x1b,0x1c,0x15,0x0e,0x0f,0x0a,0x0a,0x08,0x07,0x09,0x0a,0x08,0x0d,0x17 +,0x1b,0x32,0x30,0xb8,0xa1,0x8e,0x91,0x91,0x8b,0x88,0x83,0x85,0x84,0x84,0x84,0x85,0x88,0x88,0x87,0x90,0x98,0xa0,0xb6,0x41,0x23,0x12,0x0c,0x0b,0x0a,0x09,0x04,0x04 +,0x05,0x05,0x07,0x08,0x05,0x06,0x0f,0x0e,0x12,0x17,0x1d,0x35,0x19,0xda,0xd5,0xcc,0xa4,0xba,0xa3,0xa5,0x93,0x90,0x98,0x8c,0x8e,0x8d,0x8b,0x98,0x93,0xa2,0x99,0x93 +,0xa0,0xb5,0xb9,0x9f,0xa0,0x9f,0xa4,0x95,0xa6,0x2f,0x95,0x80,0x9b,0x02,0x8d,0x83,0xb3,0x8a,0xd5,0x3d,0x23,0x38,0x21,0x23,0x1d,0x00,0x12,0x05,0x02,0x05,0x01,0x05 +,0x01,0x01,0x03,0x03,0x04,0x04,0x02,0x05,0x07,0x08,0x10,0x1a,0x26,0x54,0xcb,0xa7,0x9f,0x82,0x83,0x92,0x88,0x82,0x80,0x82,0x84,0x82,0x83,0x82,0x82,0x81,0x80,0x83 +,0x80,0x83,0x84,0x87,0x8a,0x87,0x8f,0x97,0x9b,0xb9,0xbd,0xbe,0x34,0x1f,0x1e,0x19,0x0d,0x0b,0x0f,0x09,0x05,0x09,0x06,0x04,0x06,0x04,0x03,0x06,0x02,0x04,0x04,0x04 +,0x05,0x04,0x08,0x03,0x07,0x03,0x02,0x03,0x05,0x06,0x02,0x05,0x01,0x07,0x08,0x07,0x0d,0x12,0x15,0x1b,0x14,0x35,0x66,0x4f,0xab,0x99,0x8b,0x8b,0x85,0x85,0x83,0x82 +,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x82,0x81,0x83,0x83,0x87,0x88,0x85,0x87,0x8a,0x94,0x8f,0x94,0x9e,0x9a,0xa8 +,0xb6,0x48,0x4a,0x1c,0x33,0x28,0x16,0x1e,0x11,0x19,0x0c,0x0f,0x0a,0x0a,0x05,0x05,0x05,0x03,0x02,0x02,0x04,0x01,0x05,0x00,0x04,0x02,0x03,0x02,0x02,0x02,0x03,0x02 +,0x01,0x02,0x02,0x02,0x03,0x02,0x06,0x04,0x03,0x09,0x08,0x0d,0x0d,0x15,0x19,0x16,0x1f,0x11,0x1c,0x1e,0x1a,0x2c,0x1d,0x20,0x24,0x32,0x37,0x7b,0xbb,0xc4,0xb7,0xa2 +,0xaa,0xae,0xa8,0xa3,0x9c,0xae,0x99,0x96,0x93,0x8e,0x95,0x8b,0x8a,0x87,0x84,0x88,0x84,0x83,0x81,0x82,0x82,0x82,0x80,0x81,0x81,0x81,0x81,0x82,0x82,0x81,0x83,0x82 +,0x81,0x83,0x82,0x83,0x86,0x85,0x8d,0x89,0x8e,0x94,0x8d,0x99,0x9e,0x99,0xa1,0xa7,0xb9,0xa5,0x9b,0xaa,0xa3,0xaf,0xa0,0xaf,0xa6,0xa5,0xa4,0xb3,0x57,0xa7,0x2a,0xad +,0xd9,0x4a,0xa8,0xce,0xb8,0xb4,0xc6,0xa5,0xa8,0xae,0xa5,0xb1,0xa2,0x4c,0x3c,0x2c,0x38,0x30,0x1d,0x16,0x1a,0x13,0x0e,0x11,0x11,0x0d,0x0e,0x0d,0x09,0x0c,0x06,0x09 +,0x06,0x03,0x04,0x04,0x02,0x04,0x00,0x02,0x02,0x01,0x02,0x01,0x02,0x02,0x02,0x01,0x02,0x02,0x01,0x02,0x03,0x01,0x02,0x02,0x03,0x01,0x01,0x03,0x02,0x04,0x06,0x03 +,0x0c,0x04,0x0c,0x06,0x0e,0x16,0x0b,0x1f,0x10,0x1f,0x17,0x2a,0x3e,0x58,0xa2,0x96,0x91,0x89,0x8a,0x85,0x86,0x83,0x82,0x84,0x80,0x83,0x81,0x82,0x81,0x81,0x81,0x81 +,0x80,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x81,0x82,0x80,0x82,0x82,0x82,0x82,0x84,0x82,0x85,0x82,0x85,0x84,0x85,0x86,0x88,0x86,0x8c,0x8f +,0x8d,0xa8,0x92,0xae,0xa6,0x9e,0x23,0x32,0x45,0x1d,0x21,0x22,0x14,0x13,0x11,0x0c,0x0d,0x0a,0x07,0x0c,0x03,0x07,0x05,0x04,0x04,0x04,0x04,0x04,0x03,0x04,0x07,0x01 +,0x06,0x04,0x04,0x03,0x05,0x03,0x02,0x04,0x05,0x03,0x05,0x05,0x04,0x05,0x06,0x09,0x07,0x09,0x0e,0x0a,0x0f,0x10,0x11,0x10,0x12,0x2e,0x0e,0x2f,0x35,0x15,0xe1,0x2f +,0x3d,0xb7,0x39,0x9c,0xbe,0xa5,0x97,0xa2,0x95,0xa9,0x92,0xa6,0xa0,0x9d,0xa4,0x97,0x9e,0xa9,0x91,0xa7,0xa1,0x8e,0x9c,0x8d,0x99,0x8a,0x97,0x8d,0x8c,0x96,0x8e,0x93 +,0x90,0x91,0x95,0x9d,0x91,0x9e,0x9b,0x9f,0x9c,0x9d,0xac,0xa0,0x9d,0xc5,0xa5,0xa8,0xc2,0xf2,0x2a,0xba,0x23,0x32,0x70,0x1a,0x32,0x24,0x2b,0x1d,0x3b,0x2f,0x34,0x38 +,0x21,0xb9,0x25,0x3a,0x2e,0x26,0x23,0x1f,0x1f,0x21,0x17,0x43,0x28,0x2d,0x36,0x34,0xc0,0x3e,0x75,0xab,0xf3,0xae,0xaa,0x43,0xa5,0x3b,0x9c,0xce,0xa0,0x9c,0xa5,0x96 +,0xa4,0x91,0x8f,0x9b,0x8c,0x92,0x99,0x8b,0x95,0x9a,0x90,0x9c,0xa6,0x98,0xaa,0xa0,0x9b,0xab,0x9a,0xab,0x9f,0x9d,0xb8,0xa1,0xd4,0xa7,0xae,0xbf,0xcc,0x2f,0x3f,0x4e +,0x1c,0x4d,0x1f,0x26,0x36,0x1f,0x30,0x2d,0x31,0x2e,0x2d,0x3b,0x33,0x36,0x2d,0x1f,0x30,0x1c,0x38,0x20,0x24,0x24,0x2b,0x41,0x27,0x32,0x3e,0x3a,0x41,0x2c,0xc5,0x38 +,0x3e,0x72,0x2c,0x3a,0x4b,0x47,0xcf,0x4b,0x39,0x61,0x4c,0xb0,0x3b,0xae,0xc0,0x49,0xf7,0xb7,0x31,0x43,0x52,0x36,0x28,0x29,0x46,0x20,0x22,0x35,0x2b,0x1d,0x3a,0x2a +,0x41,0x47,0x39,0xec,0xb7,0x5f,0x60,0xcb,0xf4,0xb8,0xb0,0xab,0x79,0xc6,0xaf,0xaf,0xb4,0xa4,0xad,0xa7,0xb2,0xa4,0xa8,0x61,0xc6,0xc6,0x2a,0x35,0x32,0x24,0x3f,0x1b +,0x2e,0x20,0x20,0x1d,0x27,0x22,0x6a,0x22,0xc0,0x34,0x30,0x78,0x2b,0xb0,0xb5,0xaa,0xe3,0xa0,0xeb,0xaf,0xad,0x9f,0x5a,0xa0,0xa4,0xaf,0xb6,0xb2,0xe8,0x44,0x2c,0x24 +,0x31,0x22,0x1e,0x22,0x27,0x16,0x24,0x25,0x1f,0x28,0x5a,0x3d,0xde,0x31,0xb1,0x57,0xcd,0xf8,0xad,0xa7,0xbe,0xbd,0xa2,0xa8,0xaa,0x9a,0xdf,0x96,0xae,0xaa,0xa5,0xb3 +,0x58,0x33,0x4d,0x29,0x29,0x20,0x2d,0x1a,0x1e,0x26,0x1f,0x23,0x2a,0x2c,0x2c,0x3c,0x38,0xcb,0x44,0x4c,0xc7,0x9d,0xb6,0xb2,0xac,0xaf,0x9c,0xb6,0x99,0x9c,0xac,0xa9 +,0x9f,0xa3,0xba,0xc4,0xc8,0x3f,0x30,0x33,0x36,0x1d,0x21,0x26,0x19,0x26,0x24,0x24,0x1f,0x41,0x2b,0x2d,0xfe,0x2d,0x34,0xc7,0xc7,0xaf,0xc4,0xba,0xb0,0xae,0x9c,0xa3 +,0x9e,0x9c,0xa3,0x9e,0x9d,0xa6,0xab,0xbe,0x71,0x49,0x39,0x21,0x3a,0x20,0x20,0x23,0x21,0x1f,0x22,0x1c,0x29,0x2c,0x2e,0x27,0x24,0xbe,0x1f,0xb3,0x45,0x4f,0xaf,0x75 +,0x9e,0x9d,0xb9,0x94,0xa6,0x9f,0x9a,0xb0,0x9f,0xa7,0xb5,0x37,0xaf,0x33,0x39,0x2c,0x29,0x3b,0x20,0x1e,0x4c,0x1b,0x22,0x2f,0x28,0x2b,0x1d,0x2e,0x2a,0xc2,0x46,0x4c +,0xad,0x4e,0xa8,0xaa,0xa1,0x9a,0xb0,0x94,0x9e,0xa7,0x9c,0xa6,0xc3,0xaa,0xee,0xc1,0x30,0x3c,0x41,0x1d,0x28,0x3e,0x2b,0x1b,0x45,0x1e,0x38,0x32,0x1b,0x44,0x48,0x22 +,0xb2,0x50,0x31,0xaa,0xb4,0xad,0x9d,0xa2,0x9d,0x9c,0xa4,0xa1,0x9a,0xac,0xb8,0xaa,0xde,0x45,0x6c,0x37,0x29,0x2d,0x27,0x2c,0x20,0x35,0x26,0x1a,0x70,0x32,0x1c,0x38 +,0x2c,0x4c,0xfc,0xdb,0xc1,0xcd,0xaf,0xad,0xa7,0xa1,0xb0,0x97,0xa3,0xa7,0xaa,0xab,0xad,0xdb,0x58,0x3e,0xde,0x27,0x29,0x2a,0x2b,0x22,0x3a,0x1d,0x37,0x24,0x28,0x3f +,0x37,0x20,0x2f,0xc9,0x56,0x69,0xce,0xae,0xbd,0xa7,0xb6,0x9d,0xa4,0xa3,0xab,0x9f,0xb4,0xa3,0xb5,0x65,0xcb,0x2e,0x3e,0x2e,0x28,0x29,0x2f,0x25,0x25,0x2e,0x26,0x2e +,0x3d,0x22,0x32,0x28,0x3d,0x38,0xc8,0xc2,0x62,0xc5,0xb9,0xa7,0xb2,0xaa,0x96,0xa0,0xab,0x97,0xa8,0xba,0xa5,0xd1,0x5d,0xe3,0x2c,0x49,0x29,0x22,0x2c,0x29,0x20,0x2c +,0x24,0x2e,0x2c,0x2f,0x37,0x24,0x2f,0x45,0x4d,0x6b,0xdd,0xaf,0xb7,0xc5,0x98,0xa8,0xa0,0x9b,0xa2,0x9e,0xa2,0xa7,0xa6,0xab,0xf1,0xfa,0x3f,0x2f,0x3d,0x32,0x2a,0x2b +,0x29,0x25,0x2a,0x26,0x2a,0x33,0x26,0x32,0x2c,0x2c,0x30,0xbf,0xbb,0x57,0xbe,0xab,0xab,0xa5,0x9d,0x9f,0x97,0xa4,0x9d,0xab,0xad,0xa4,0xcb,0xe4,0xb9,0x27,0x2e,0x2e +,0x21,0x27,0x20,0x32,0x1d,0x2a,0x31,0x28,0x2c,0x29,0x26,0x3f,0x2b,0xe4,0xf1,0xd1,0xbd,0xd3,0xa6,0xa4,0xa5,0x9e,0x9b,0xa3,0x9e,0xa4,0xa6,0xab,0xbf,0xce,0x3e,0x4e +,0x38,0x2a,0x2a,0x2a,0x2b,0x22,0x2e,0x27,0x20,0x29,0x43,0x20,0x25,0x3a,0x2d,0x4e,0x79,0xcc,0xbd,0xb6,0xb7,0xa0,0xa3,0xa1,0x9b,0x9d,0x9f,0xa5,0xa5,0xa6,0xac,0xdb +,0xbf,0x3d,0x34,0x34,0x2d,0x27,0x22,0x2d,0x1f,0x2a,0x25,0x2d,0x2d,0x2b,0x33,0x29,0x2e,0x7b,0xd1,0xce,0xd6,0xcb,0xaa,0xba,0xa4,0x9e,0x9e,0x9f,0xa0,0x9f,0xa7,0xa6 +,0xa9,0xb4,0xd6,0x58,0x3d,0x2f,0x2e,0x2d,0x34,0x2b,0x1f,0x2e,0x22,0x26,0x2b,0x28,0x2a,0x24,0x27,0x35,0x31,0x3b,0xb9,0xc9,0xc2,0xaa,0xb3,0xa6,0x9e,0xa2,0x9a,0x9c +,0xa0,0xa1,0xaa,0xaf,0xae,0xce,0x40,0x37,0x33,0x20,0x2c,0x2e,0x1e,0x28,0x2d,0x1e,0x25,0x2f,0x1f,0x2f,0x23,0x2e,0x4c,0x30,0xc2,0xdf,0xc2,0xbb,0xa9,0xa4,0xa8,0x9c +,0x9f,0xa0,0x9a,0xa5,0xa7,0xa4,0xfa,0xba,0xf8,0x3f,0x3e,0x27,0x2c,0x30,0x23,0x29,0x2f,0x24,0x26,0x2f,0x29,0x27,0x29,0x23,0x3c,0x44,0x2f,0xb4,0xc5,0xb6,0xab,0xa4 +,0xb0,0xa4,0x9a,0xa3,0x9d,0xa0,0x9f,0xa5,0xaf,0xbc,0xae,0x3a,0x36,0x29,0x35,0x28,0x24,0x27,0x29,0x2f,0x29,0x29,0x25,0x24,0x24,0x33,0x22,0x3a,0x4c,0x3c,0xbd,0x3c +,0xd2,0xa8,0xa9,0xa8,0xa3,0x96,0x9d,0x98,0xa3,0x9e,0xa1,0xad,0xae,0xbb,0x71,0x47,0x38,0x2a,0x2f,0x21,0x27,0x1f,0x22,0x1f,0x20,0x2a,0x21,0x1e,0x3c,0x24,0x2b,0x4d +,0x43,0x56,0xaf,0xae,0xc1,0xb7,0xa4,0xa7,0xa2,0x9c,0xab,0x9c,0xae,0xa4,0xa9,0xae,0xba,0x47,0x54,0x2c,0x2f,0x34,0x28,0x28,0x30,0x21,0x2b,0x29,0x28,0x27,0x3b,0x2d +,0x30,0x3c,0x2c,0x49,0xc1,0x67,0xba,0xb1,0xc2,0xa7,0xa3,0x9c,0xa1,0x9e,0xa3,0xa4,0xac,0xaf,0xb5,0xc4,0x59,0xe4,0x3c,0x35,0x5a,0x26,0x2e,0x2b,0x2e,0x29,0x26,0x34 +,0x28,0x2e,0x2e,0x33,0x32,0x30,0x42,0x5c,0xc9,0x69,0xc5,0xb2,0xad,0xb6,0x9d,0x9d,0xa3,0xa4,0xa2,0xa5,0xb7,0xaa,0xd1,0xc8,0x75,0x38,0x47,0x48,0x30,0x40,0x39,0x2e +,0x33,0x2f,0x27,0x25,0x2e,0x27,0x32,0x25,0x28,0x30,0x3a,0x47,0xbb,0xcb,0xcb,0xac,0xba,0xa9,0xa1,0xa8,0xa5,0x9d,0xb3,0xa9,0xac,0xb7,0xb7,0xe6,0xe7,0xdf,0x2e,0x36 +,0x40,0x2c,0x3a,0x26,0x30,0x2f,0x29,0x2b,0x2a,0x2b,0x2b,0x2f,0x31,0x2c,0x36,0x45,0x5d,0xb6,0xb3,0xac,0xac,0xab,0xa0,0xa6,0x9b,0x9f,0xa6,0xa2,0xae,0xaa,0xb8,0xbd +,0xd8,0x3f,0x3f,0x4c,0x2b,0x31,0x2a,0x2d,0x21,0x2c,0x42,0x2a,0x33,0x28,0x3e,0x2d,0x30,0x3d,0x30,0x31,0x79,0x75,0xb0,0xaf,0xae,0xa4,0xa9,0x9f,0xa1,0x9e,0xaa,0xaa +,0xa8,0xbc,0xc0,0xb7,0x4f,0x5e,0x3d,0x39,0x38,0x2b,0x40,0x25,0x2f,0x2b,0x2b,0x32,0x2b,0x33,0x39,0x3c,0x5d,0x39,0x3c,0xef,0x37,0xc0,0xde,0xd8,0xbc,0xbb,0xb2,0xb3 +,0xa7,0xad,0xa5,0xa0,0xb2,0xa5,0xbb,0xc4,0xaf,0x3f,0x63,0x3e,0x33,0x38,0x2d,0x4f,0x35,0x30,0x3b,0x2d,0x3e,0x2e,0x38,0x45,0x32,0x4f,0x41,0x38,0x43,0x39,0xcb,0x3f +,0xce,0xbe,0xde,0xb8,0xc9,0xaa,0xaf,0xa8,0xa7,0xaf,0xaf,0xae,0xcd,0xb7,0x60,0x48,0xd5,0x31,0x4f,0x32,0x4c,0x3d,0x44,0x4b,0x2f,0x36,0x35,0x36,0x3b,0x32,0x3d,0x46 +,0x34,0x40,0x32,0x5c,0x40,0x3c,0xcf,0x5f,0xc2,0xb8,0xbc,0xad,0xaf,0xa6,0xa7,0xaa,0xa6,0xbe,0xb7,0xc1,0x64,0xd8,0x3b,0x41,0x40,0x33,0x5c,0x4c,0x48,0x3f,0x35,0x4e +,0x35,0x39,0x3a,0x2c,0x4c,0x2f,0x46,0x39,0x2b,0x7e,0x48,0xcf,0xbe,0xc2,0xba,0xd0,0xb5,0xab,0xb1,0xa4,0xac,0xaa,0xb5,0xc1,0xad,0x6e,0xc5,0xe7,0x4e,0xd9,0x45,0x4f +,0x65,0x3e,0xef,0x3f,0x4c,0x39,0x2c,0x3d,0x2b,0x3c,0x2c,0x2f,0x38,0x2d,0x3e,0x3f,0x4f,0xbc,0x5c,0xcc,0xc8,0xda,0xaf,0xb5,0xa6,0xb1,0xaf,0xac,0xb5,0xad,0xc3,0xb3 +,0xc2,0x55,0xce,0x47,0x50,0xf1,0x45,0xd9,0x43,0x38,0x49,0x2d,0x34,0x2c,0x37,0x34,0x28,0x34,0x2e,0x38,0x37,0x35,0xd2,0xf0,0xe8,0xc4,0x61,0xba,0xb9,0xb0,0xac,0xae +,0xa3,0xac,0xa4,0xab,0xb3,0xac,0xc9,0xbe,0xee,0x4e,0xe7,0x4a,0x48,0x4b,0x39,0x45,0x2f,0x2c,0x2d,0x29,0x2e,0x29,0x2d,0x2a,0x2a,0x3a,0x2d,0x4f,0x51,0x59,0xbc,0xce +,0xb9,0xb5,0xad,0xa7,0xa7,0x9f,0xa3,0xa8,0xa1,0xad,0xaa,0xb4,0xc6,0xc8,0x3c,0x46,0x34,0x38,0x38,0x30,0x3c,0x2a,0x32,0x2e,0x23,0x2e,0x28,0x2f,0x34,0x2a,0x38,0x2c +,0x37,0x77,0xe4,0xaf,0xca,0xac,0xad,0xb9,0xa5,0xab,0x9f,0xa3,0xa5,0xa5,0xae,0xb0,0xaf,0xd4,0xcf,0x3e,0x37,0x3d,0x29,0x53,0x2c,0x36,0x38,0x29,0x39,0x28,0x2e,0x2e +,0x28,0x3b,0x2c,0x38,0x37,0x34,0xed,0x73,0xbb,0xb8,0xaf,0xab,0xb0,0xac,0xa8,0xab,0xa0,0xa9,0xa8,0xad,0xbc,0xae,0xcc,0xcb,0x5c,0x37,0x3f,0x2c,0x37,0x33,0x30,0x3e +,0x2c,0x38,0x2e,0x2e,0x33,0x2a,0x31,0x36,0x30,0x3b,0x34,0x57,0x57,0xc8,0xae,0xb7,0xa8,0xac,0xac,0xab,0xb4,0xa8,0xaa,0xae,0xaa,0xc5,0xb8,0xd2,0xee,0xc9,0x3a,0x46 +,0x32,0x31,0x4c,0x36,0x3b,0x32,0x31,0x43,0x2e,0x3b,0x32,0x2f,0x49,0x2d,0x47,0x34,0x3d,0xdf,0x57,0xb4,0xb8,0xb3,0xb5,0xbd,0xab,0xb4,0xb3,0xa6,0xba,0xac,0xb9,0xbf +,0xb2,0xd0,0xbd,0x71,0x4c,0x51,0x32,0x47,0x35,0x2e,0x42,0x29,0x35,0x2e,0x35,0x3a,0x2d,0x4c,0x2c,0x31,0x3a,0x31,0xca,0xdf,0xbd,0xaf,0xc3,0xae,0xb0,0xa9,0xa6,0xae +,0xa3,0xaf,0xb6,0xae,0xc8,0xae,0xc6,0xcb,0x67,0x36,0x50,0x38,0x35,0x2f,0x2d,0x2e,0x26,0x29,0x31,0x27,0x45,0x2f,0x33,0x32,0x28,0x6c,0x47,0xc7,0xbf,0xcb,0xac,0xb8 +,0xa7,0xa1,0xa9,0x9d,0xa9,0xa6,0xac,0xb3,0xac,0xc7,0xc1,0x69,0x37,0x4f,0x33,0x37,0x3d,0x2a,0x30,0x21,0x29,0x27,0x26,0x33,0x28,0x30,0x2f,0x2f,0x43,0x3f,0xd7,0xb9 +,0xbe,0xad,0xb2,0xa9,0xa3,0xa6,0x9d,0xa8,0xa2,0xa9,0xac,0xa9,0xc9,0xba,0x57,0x45,0x48,0x35,0x3e,0x34,0x30,0x32,0x24,0x28,0x23,0x20,0x2b,0x21,0x2d,0x28,0x2c,0x3f +,0x37,0xbc,0xbe,0xb0,0xa8,0xae,0xa4,0xa3,0xa6,0xa1,0xa9,0xa5,0xa7,0xaa,0xa8,0xbd,0xb5,0xf5,0x41,0x49,0x2f,0x33,0x2c,0x2c,0x2d,0x23,0x2a,0x26,0x29,0x2c,0x2a,0x2e +,0x25,0x2d,0x38,0x3d,0xcb,0xc0,0xb8,0xab,0xae,0x9f,0xa4,0xa3,0xa0,0xaa,0xa0,0xae,0xaa,0xac,0xbc,0xb9,0x6b,0x64,0x59,0x3b,0x43,0x2e,0x29,0x2d,0x20,0x27,0x22,0x27 +,0x2b,0x25,0x2c,0x24,0x35,0x3c,0x46,0xc5,0xcf,0xb8,0xaf,0xab,0xa2,0xa3,0x9f,0x9f,0xa9,0xa0,0xab,0xac,0xae,0xca,0xca,0x4a,0x5f,0x42,0x3e,0x41,0x2f,0x2d,0x2b,0x23 +,0x26,0x22,0x27,0x27,0x20,0x29,0x25,0x39,0x4d,0x5f,0xbd,0xbb,0xad,0xad,0xa9,0xa4,0xa8,0xa3,0xa0,0xa9,0xa0,0xa8,0xab,0xad,0xbe,0xb7,0xde,0xe6,0x3f,0x38,0x39,0x2d +,0x2f,0x2b,0x1f,0x27,0x22,0x2b,0x26,0x20,0x27,0x1f,0x35,0x3a,0x68,0xb6,0xbc,0xac,0xa6,0xab,0xa0,0xa5,0x9f,0xa6,0xab,0xa2,0xb1,0xa9,0xb7,0xb9,0xb8,0xdf,0xe9,0x57 +,0x37,0x3b,0x2c,0x28,0x26,0x1f,0x29,0x23,0x2b,0x28,0x27,0x2a,0x2b,0x38,0x3c,0x5b,0xbe,0xc7,0xbb,0xb2,0xac,0xa5,0xa5,0x9e,0xa1,0xa0,0xa2,0xab,0xac,0xb7,0xbd,0xc1 +,0x6c,0xf2,0x41,0x36,0x39,0x2a,0x29,0x24,0x1f,0x27,0x25,0x25,0x26,0x25,0x2b,0x2b,0x3c,0x54,0xd3,0xba,0xc6,0xb0,0xac,0xaa,0xa5,0xab,0xa1,0xa2,0xa2,0xa3,0xaa,0xac +,0xba,0xc2,0xd4,0x59,0x4c,0x45,0x37,0x37,0x31,0x2c,0x2b,0x26,0x2c,0x2a,0x29,0x26,0x24,0x26,0x26,0x32,0x3d,0xe1,0xc6,0xb6,0xb5,0xae,0xaa,0xa7,0xa8,0xa7,0xa2,0xa6 +,0xa5,0xa9,0xa6,0xad,0xb4,0xba,0xc6,0xf1,0x42,0x45,0x31,0x2f,0x2a,0x26,0x2a,0x25,0x29,0x2d,0x2b,0x29,0x29,0x29,0x2d,0x34,0x58,0xdb,0xcc,0xad,0xb7,0xab,0xa7,0xa6 +,0x9e,0xaa,0xa6,0xa6,0xab,0xad,0xbb,0xb3,0xd8,0xec,0xc7,0x42,0x39,0x3f,0x31,0x2e,0x24,0x24,0x28,0x26,0x30,0x28,0x29,0x2b,0x2d,0x37,0x36,0x36,0x67,0xd4,0xd4,0xbc +,0xb4,0xaa,0xa9,0xa4,0xa3,0xa4,0xa2,0xa3,0xa5,0xab,0xb6,0xb5,0xbb,0xc8,0xe9,0xe3,0x43,0x3d,0x33,0x2d,0x29,0x25,0x27,0x21,0x26,0x1e,0x1f,0x28,0x26,0x2d,0x3b,0x42 +,0xc5,0xcb,0xb9,0xb8,0xaf,0xa4,0xa5,0xa3,0x9e,0xa1,0xa1,0x9e,0xa6,0xa4,0xb2,0xaf,0xcd,0xcd,0x5e,0x3b,0x3b,0x34,0x2d,0x2a,0x27,0x28,0x2d,0x22,0x24,0x1e,0x24,0x26 +,0x25,0x2a,0x35,0x38,0xce,0xbe,0xba,0xab,0xae,0xa2,0xa1,0xa4,0xa2,0xa2,0xa2,0xa6,0xac,0xa9,0xad,0xba,0xc6,0x6e,0x3f,0x3d,0x39,0x2c,0x2c,0x27,0x2b,0x2f,0x3a,0x3c +,0x33,0x2a,0x22,0x34,0x29,0x1c,0x13,0x15,0xbd,0x6d,0x17,0x2e,0x90,0x89,0x8f,0x9f,0x9b,0x8f,0x8d,0x94,0x9e,0x9b,0xaa,0x9f,0xd5,0x16,0x0c,0x14,0x17,0x2d,0xb1,0xbf +,0x17,0x0b,0x0f,0x14,0xb6,0xb7,0xca,0x7c,0x64,0x35,0xae,0xaa,0x2a,0x09,0x12,0xc6,0x96,0x8d,0xaf,0x97,0x8d,0x87,0x8c,0x97,0x2c,0x1b,0xae,0x95,0x9d,0x44,0xb8,0x38 +,0x0f,0x0b,0x19,0xca,0x1f,0x17,0x37,0xfd,0xb8,0xae,0x42,0x35,0xd5,0xb4,0x29,0x0e,0x09,0x13,0x41,0x27,0x2e,0x42,0x91,0x9a,0xb4,0x93,0x8b,0x8a,0x8f,0xa1,0x9f,0x8f +,0xa1,0xc8,0x41,0x3c,0x1f,0x15,0x04,0x02,0x0d,0x3d,0xad,0x55,0xd4,0xa0,0x93,0xa3,0xbf,0xb5,0x9c,0x97,0xa3,0xd2,0x22,0x13,0x1c,0x25,0x1b,0x0c,0x18,0x1d,0x1c,0xcc +,0x92,0x8c,0x9b,0x98,0x95,0x9b,0x90,0x93,0x9a,0xb8,0x1c,0xc7,0x44,0x1a,0x08,0x0c,0xca,0x9c,0xad,0x2c,0x1b,0x1a,0x29,0xb9,0x99,0xab,0xa5,0xd7,0x5c,0x35,0x25,0xb6 +,0x19,0x0b,0x17,0xe4,0x99,0x9a,0x9d,0x92,0x8f,0x9e,0xfc,0x2d,0x2c,0x3f,0xa2,0x9c,0xb3,0x6b,0xce,0x3b,0x16,0x0e,0x2b,0xa5,0xd9,0x64,0xa8,0xab,0x2a,0x25,0x3f,0x64 +,0x4e,0x24,0x0e,0x0d,0x58,0xa6,0x4d,0x25,0x1b,0xc7,0x89,0x8b,0x99,0x94,0x89,0x8f,0xa7,0xa0,0xb2,0xe9,0x2a,0x2f,0x3d,0x1a,0x0f,0x0b,0x07,0x05,0x0f,0x53,0xa7,0xaf +,0xb1,0xa6,0x9a,0x92,0x99,0xc4,0x39,0xb2,0xc3,0x9e,0x3e,0x19,0xa7,0xa8,0x33,0x1c,0x38,0x2f,0xcd,0x93,0x8d,0x8f,0x9e,0xbf,0xc6,0xbe,0x46,0x5e,0x36,0x1f,0x19,0x1f +,0x2a,0x19,0x0f,0x1a,0x53,0xb2,0x30,0x17,0x27,0x6d,0xb7,0xb2,0x9a,0xa4,0xa1,0x93,0x48,0x5d,0x9d,0xa0,0x64,0x30,0x30,0xb8,0x9f,0xaf,0xad,0xa1,0xaf,0x29,0x14,0x12 +,0x31,0xa5,0xba,0x3d,0x44,0x4d,0xd9,0x4d,0x1a,0x15,0x4b,0xa5,0xa4,0xb4,0xc0,0x44,0x2a,0x39,0xb1,0xd4,0xad,0x28,0x12,0x57,0xb6,0xbd,0xac,0xad,0x22,0x2f,0xa2,0x92 +,0x97,0xac,0x51,0xb9,0xb6,0x3d,0x45,0x32,0x54,0xa6,0xa5,0x29,0x13,0x13,0x17,0x15,0x1b,0xb4,0x9e,0xa7,0xae,0xbf,0x4f,0xc1,0x74,0xc3,0x97,0xbb,0xaa,0x96,0xb3,0x70 +,0xad,0xce,0x15,0x0c,0x0f,0x28,0xad,0xa3,0x9f,0x99,0xa6,0xbe,0xb2,0xbb,0xb2,0xa2,0xa9,0x46,0x30,0x3d,0x21,0x11,0x0f,0x14,0x22,0x2b,0x1d,0x20,0x33,0xa7,0xb6,0x96 +,0x8f,0xa7,0x8d,0x8e,0x9d,0xa5,0x9b,0x9e,0xbd,0x1f,0x17,0x26,0x4b,0x43,0xb9,0xae,0x1e,0x15,0x19,0x19,0x32,0xb0,0xbc,0xbc,0x56,0x42,0xc1,0x48,0x1e,0x14,0x21,0x5d +,0xbb,0xbf,0xb9,0x3f,0xaa,0x8e,0xa9,0xb8,0xa6,0xb0,0xfa,0xab,0x9f,0x9c,0xa6,0x29,0x1f,0x23,0x33,0x35,0xbe,0xbc,0x52,0xd7,0xbf,0xda,0xbf,0xb8,0xd1,0x51,0x1f,0x13 +,0x14,0x19,0x17,0x18,0x23,0x42,0xbe,0x9f,0xba,0x9f,0x90,0xaf,0x9b,0x94,0x9c,0xa1,0xa4,0xcb,0x71,0xde,0x2c,0x1c,0x0f,0x09,0x0d,0x59,0xa6,0x9d,0x9c,0x9b,0x9c,0xa1 +,0xa7,0xab,0xae,0xa9,0xb6,0xfd,0x31,0x23,0x1b,0x14,0x14,0x17,0x1a,0x18,0x62,0x2e,0x3a,0xa0,0x9b,0x99,0x9b,0x9a,0x93,0x96,0xb1,0xc5,0xca,0x2e,0x1b,0x16,0x14,0x21 +,0x47,0xa1,0x9b,0xb2,0x3d,0x3b,0x35,0xc3,0xa6,0xa0,0x9e,0xab,0x60,0x34,0x2d,0x1f,0x0d,0x18,0x46,0x29,0xaf,0xa1,0x9c,0x9b,0xa4,0xa9,0xa4,0x37,0x29,0xd5,0x64,0x58 +,0xc6,0xbb,0x48,0x1f,0x16,0x1c,0x2c,0xfe,0xae,0xa4,0xa4,0xb8,0x3f,0x45,0x3c,0x74,0x58,0x26,0x25,0x17,0x2a,0xbf,0x23,0x43,0x68,0xa9,0x98,0x9c,0x91,0x8e,0x94,0x98 +,0x97,0x9f,0xb4,0x3a,0x66,0x5d,0x29,0x27,0x1c,0x0e,0x08,0x08,0x10,0x24,0x2d,0xbc,0x9f,0xaa,0xaa,0xbd,0xd2,0xc3,0x2f,0xcb,0xac,0x4e,0xc0,0xe6,0xb9,0xba,0x3a,0x7d +,0xdf,0xbe,0xa0,0x9f,0x98,0x93,0x9b,0x9b,0xa4,0xbb,0xda,0x5b,0x2e,0x2d,0x1f,0x27,0x1b,0x15,0x18,0x1d,0x40,0x4f,0x3f,0x2e,0x32,0x24,0xce,0xc2,0xcb,0x9f,0x9d,0xa0 +,0xac,0xc8,0xba,0xd7,0x2d,0x33,0x37,0x51,0xfe,0xd1,0xae,0xa7,0xc2,0x74,0x31,0x28,0x31,0x54,0xc4,0xb7,0xbe,0xbc,0xc7,0x3c,0x28,0x2e,0x4c,0xc4,0xaa,0xa7,0x9e,0xac +,0xaf,0xb7,0xcf,0xdb,0x47,0x33,0x25,0x22,0x24,0x2e,0x22,0x24,0x2a,0x3e,0xb7,0xad,0xa1,0xa6,0xae,0xae,0x7d,0x3a,0xf2,0x38,0x4d,0x7b,0x3e,0x47,0x29,0x1e,0x1c,0x1a +,0x2e,0xc7,0xa3,0x95,0x99,0x97,0x9d,0xa8,0xb3,0xbc,0xba,0xbc,0xca,0xbc,0xd9,0xbf,0x4e,0x1f,0x19,0x16,0x16,0x1f,0x4d,0xd0,0xa1,0xa1,0x9d,0xa3,0xb3,0xba,0xf9,0x4f +,0x44,0x36,0x30,0x26,0x1b,0x19,0x19,0x1f,0x2b,0x46,0x73,0xb9,0xb7,0xab,0xa5,0xa3,0x9d,0x9b,0x9b,0xa5,0xa6,0xae,0xaf,0xbe,0xea,0x40,0x2e,0x3f,0x56,0xb9,0xaf,0xb8 +,0xd2,0x4a,0x21,0x29,0x24,0x28,0x2c,0x30,0x55,0x3f,0x3f,0x32,0x2c,0x26,0x3e,0x47,0xba,0xb9,0xae,0xa5,0xa7,0xa6,0xab,0xbc,0xcc,0x40,0x30,0x3a,0x57,0xd4,0x40,0x3f +,0x37,0x39,0x4f,0xc0,0xad,0xa6,0xaf,0xa9,0xb0,0xc2,0xb9,0xbb,0xbf,0xfd,0x36,0x3c,0x2b,0x1b,0x1f,0x1c,0x29,0x48,0xaf,0x9f,0xa7,0xa2,0xa0,0xab,0xa9,0xca,0xdc,0x4d +,0x25,0x2e,0x26,0x29,0x1e,0x19,0x18,0x18,0x1b,0x2c,0xdd,0xad,0x9c,0x9b,0x96,0x99,0x9e,0x9b,0x9c,0x9e,0xa3,0xac,0xb5,0x46,0x3f,0x2d,0x21,0x29,0x23,0x2c,0x2d,0x2f +,0x37,0x42,0xd3,0x70,0xc3,0xc5,0xc8,0xdb,0xcf,0xd0,0x5f,0x2c,0x2a,0x20,0x1f,0x2a,0x43,0xb5,0xb9,0xa2,0xac,0xad,0xad,0xba,0xb6,0xa8,0xa4,0xaa,0xaf,0xba,0x46,0x33 +,0x2d,0x24,0x29,0x36,0x52,0xde,0xbd,0xad,0xae,0xd4,0xed,0x4f,0x3f,0x2f,0x34,0x3a,0x43,0x49,0x3e,0x3d,0x2f,0x41,0xc0,0xb5,0xb0,0xa8,0xa8,0xaf,0xb6,0xbd,0xc6,0xd1 +,0x36,0x2f,0x27,0x26,0x22,0x20,0x26,0x24,0x31,0x42,0xbf,0xaf,0xa7,0x9c,0x9c,0x9d,0x9e,0xaa,0xaa,0xb1,0xce,0xdd,0xf1,0x40,0x29,0x1f,0x19,0x19,0x1a,0x21,0x2f,0xc4 +,0xb2,0xa4,0x9f,0xa2,0xa1,0xa6,0xab,0xb7,0xd9,0x47,0x3c,0x2d,0x28,0x1e,0x1e,0x1f,0x2b,0x32,0x3f,0xf1,0xb3,0xa7,0xa2,0xa3,0xa3,0xa2,0xad,0xb5,0xb5,0xcf,0x39,0x2e +,0x28,0x2a,0x26,0x3d,0x3f,0x45,0xd4,0xd4,0xcd,0xc9,0xb5,0xb4,0xbb,0xa9,0xad,0xba,0xbb,0xbf,0x3f,0x3e,0x33,0x31,0x34,0x28,0x41,0x33,0xcc,0x59,0x61,0xe5,0x36,0x4e +,0x3d,0x56,0x5e,0x55,0xbd,0xee,0xc2,0xe0,0x4a,0xcd,0xc9,0xae,0xa8,0xa8,0xa6,0xa0,0xab,0xab,0xb0,0xbe,0x48,0x2c,0x2c,0x20,0x1d,0x1d,0x1d,0x1e,0x24,0x34,0x3b,0xcf +,0xae,0xa5,0xa7,0xa5,0xa8,0xad,0xa8,0xa8,0xb4,0xc0,0xc7,0x35,0x3a,0x27,0x1f,0x1d,0x2f,0x3d,0x45,0xbc,0xbb,0xae,0xaf,0xa9,0xaa,0xac,0xb4,0xb7,0xd5,0xeb,0x4b,0x34 +,0x2a,0x21,0x25,0x1e,0x1f,0x2a,0x2d,0x48,0xba,0xa9,0xa6,0x9f,0x9e,0xa2,0x9d,0x9d,0xa6,0xb1,0xbb,0x35,0x2a,0x25,0x1b,0x1d,0x1d,0x27,0x24,0x2c,0x3a,0x3c,0xbf,0xba +,0xa7,0xa8,0xa3,0xa4,0xa8,0xa9,0xae,0xb8,0xed,0x3a,0x38,0x3b,0x58,0xc3,0x4b,0xd2,0xea,0x4f,0xfc,0xcc,0x47,0x3b,0x46,0x5b,0x54,0x36,0x3c,0x39,0x2e,0x49,0x40,0x46 +,0xd5,0x48,0xbd,0xb3,0xab,0xab,0xac,0xb6,0xc9,0xc7,0x50,0xdf,0x4f,0x3a,0x32,0x31,0x2f,0x30,0x4b,0x3b,0x4e,0xb3,0xb7,0xad,0xb2,0xb3,0xb0,0xb4,0xb5,0xeb,0xbd,0x44 +,0x2e,0x2e,0x21,0x28,0x2a,0x2a,0x49,0xd3,0xc2,0xb8,0xa6,0x9f,0x9c,0xa3,0xac,0xa6,0xc2,0xde,0x4b,0x36,0x24,0x1c,0x1f,0x18,0x1d,0x23,0x26,0x41,0x4a,0xb5,0xa8,0xa8 +,0xa5,0x9f,0x9e,0x99,0x9f,0xad,0xad,0xd9,0xde,0x37,0x35,0x29,0x24,0x2c,0x24,0x24,0x2f,0x3e,0x42,0x3f,0x6a,0xc5,0xa8,0xb5,0xd1,0xaf,0xb8,0xcb,0x39,0xe4,0x36,0x5e +,0x47,0xd8,0x57,0x72,0xb6,0x59,0xc3,0xd3,0xc4,0xb8,0xb9,0xe0,0x65,0x47,0x59,0x39,0xce,0x3a,0xd9,0x35,0x44,0x61,0x4a,0x4c,0xd0,0xb2,0xaa,0x99,0xc0,0xb5,0x35,0xc4 +,0x26,0x18,0x1b,0x06,0x08,0x1d,0x2e,0xa3,0x8b,0x80,0x9c,0x4c,0x2a,0x32,0x93,0x8b,0x83,0xae,0xa7,0x89,0x9a,0x07,0x1d,0xaf,0x29,0x0a,0x05,0x03,0x0a,0x22,0x30,0x28 +,0xe5,0x84,0x8b,0x93,0x29,0x1a,0x16,0x3e,0x15,0x0e,0x19,0xca,0x9d,0x96,0x93,0x9f,0x8f,0x94,0x83,0x93,0xa6,0x8a,0x86,0x94,0x8b,0x8c,0x9e,0x1f,0x14,0x12,0x03,0x00 +,0x00,0x00,0x02,0x06,0x05,0x17,0xa3,0x90,0x8a,0x86,0x90,0x93,0x99,0xb2,0x9f,0xa1,0x37,0xa7,0x90,0x91,0x91,0x9d,0x9f,0x8d,0x9a,0x59,0xa9,0xae,0x63,0xa7,0xa0,0x99 +,0x98,0x2f,0x6e,0x24,0x11,0x06,0x00,0x00,0x02,0x0a,0x08,0x12,0x2d,0xcd,0xa4,0x98,0x98,0x96,0x9f,0x98,0x9a,0xa3,0x8e,0x8b,0x8e,0x8b,0x89,0x88,0x8f,0x92,0x97,0xae +,0x33,0x1b,0x16,0x11,0x1b,0x1d,0x7a,0x3b,0x1c,0x4d,0x2c,0x10,0x08,0x06,0x06,0x0b,0x0d,0x0e,0x0f,0x16,0xd3,0xb4,0xbc,0xa1,0x9e,0x9e,0x8b,0x8d,0x90,0x8f,0x90,0x8a +,0x84,0x85,0x8d,0x8c,0x98,0x9a,0xdb,0x16,0x11,0x14,0x1f,0x1c,0x13,0x0f,0x12,0x0d,0x0e,0x15,0x1b,0x24,0x18,0x12,0x12,0x0e,0x0a,0x0f,0x2f,0xc2,0xb4,0xaf,0x9f,0xa0 +,0x9f,0x94,0x8f,0x8d,0x88,0x84,0x85,0x86,0x89,0x8c,0x93,0x95,0x98,0xac,0xc3,0x79,0x34,0x21,0x14,0x0d,0x0d,0x0e,0x09,0x08,0x0b,0x11,0x0d,0x0c,0x17,0x14,0x1c,0x47 +,0x4c,0x1c,0x1c,0x3e,0x34,0x2a,0xaf,0x95,0x8e,0x8c,0x8d,0x92,0x8f,0x8a,0x8d,0x8f,0x8c,0x86,0x8c,0x93,0x8c,0x90,0x9b,0x9d,0x77,0x2c,0x27,0x19,0x0e,0x07,0x08,0x06 +,0x05,0x04,0x05,0x0e,0x0d,0x15,0x19,0x14,0x18,0x19,0x30,0xc5,0xa6,0xa5,0x9f,0x91,0x8c,0x8f,0x95,0x8f,0x8e,0x8f,0x8b,0x87,0x8b,0x8d,0x8d,0x8a,0x8e,0x96,0xa1,0x44 +,0x58,0x35,0x18,0x0e,0x0c,0x0f,0x11,0x0e,0x0a,0x05,0x04,0x09,0x09,0x07,0x0b,0x0d,0x0f,0x21,0xc4,0xa7,0xa8,0x9c,0x95,0x9b,0xa5,0x9b,0x94,0x93,0x8c,0x8e,0x8d,0x87 +,0x87,0x89,0x89,0x8a,0x8e,0x92,0x99,0xa8,0x35,0x23,0x17,0x15,0x13,0x0e,0x0c,0x12,0x0f,0x0a,0x09,0x09,0x0d,0x0d,0x0c,0x0c,0x17,0x16,0x1b,0x3c,0xaa,0x9c,0x9c,0x9a +,0x9f,0x9a,0x9c,0x9a,0x9a,0x95,0x8c,0x88,0x85,0x85,0x87,0x88,0x8a,0x8e,0x92,0xa2,0xbf,0x50,0x2a,0x23,0x1a,0x12,0x12,0x0f,0x0b,0x0f,0x0c,0x06,0x08,0x0c,0x0b,0x0d +,0x0c,0x0f,0x1b,0x21,0x2c,0x2d,0xc2,0xad,0xa5,0x9c,0x97,0x97,0x95,0x91,0x91,0x8b,0x8c,0x92,0x8e,0x8b,0x8b,0x8a,0x8d,0x94,0x94,0x9d,0xb7,0x40,0x28,0x1f,0x23,0x20 +,0x16,0x0e,0x0d,0x0e,0x10,0x13,0x12,0x0d,0x0c,0x0f,0x0c,0x0a,0x0e,0x19,0x17,0x17,0x1a,0x1c,0x3d,0xaf,0x9e,0x96,0x91,0x8d,0x8b,0x8e,0x90,0x90,0x8f,0x8d,0x95,0x97 +,0x97,0x94,0x8e,0x95,0x9b,0xb7,0xcd,0x5d,0x2a,0x2d,0x22,0x29,0x20,0x19,0x1a,0x11,0x0f,0x0e,0x0c,0x0e,0x0e,0x0a,0x0a,0x09,0x0d,0x13,0x14,0x26,0x2d,0x3c,0xb1,0xad +,0xa5,0x9d,0xa2,0x9e,0x97,0x8d,0x8a,0x87,0x87,0x86,0x87,0x86,0x8b,0x8e,0x93,0x9c,0x9d,0xc0,0x32,0x20,0x1f,0x12,0x17,0x12,0x0f,0x0f,0x0b,0x0e,0x12,0x17,0x14,0x13 +,0x18,0x1b,0x1c,0x1d,0x14,0x1d,0x14,0x1b,0x1f,0x2b,0x42,0xb6,0xae,0xb1,0xa0,0x9a,0x92,0x90,0x8c,0x8b,0x88,0x8b,0x8e,0x90,0x8c,0x8c,0x8d,0x91,0x90,0x90,0x9e,0x3b +,0x16,0x0f,0x0d,0x0f,0x0d,0x0b,0x0c,0x13,0x1a,0x19,0x1e,0x23,0x20,0x22,0x1a,0x1b,0x1a,0x1c,0x1b,0x19,0x1f,0x45,0xc4,0xa6,0x9d,0xa3,0x9b,0x9c,0x9c,0x9c,0x9c,0x9f +,0x9f,0x98,0x95,0x9b,0x9d,0xaa,0xa2,0x98,0x93,0x94,0xa4,0x9a,0x99,0xae,0xb5,0xcc,0x2f,0x28,0x1d,0x1a,0x11,0x0e,0x15,0x0f,0x0d,0x10,0x16,0x1a,0x19,0x19,0x1f,0x27 +,0x1b,0x20,0x2b,0x2a,0xd0,0xb2,0xc0,0xb8,0xaf,0x9f,0x97,0x9d,0xaa,0x9b,0x9c,0x9e,0x9a,0x94,0x94,0x98,0x8e,0x8f,0x8d,0x90,0x8f,0x97,0x9f,0xa5,0x48,0x24,0x19,0x17 +,0x17,0x13,0x10,0x14,0x10,0x17,0x16,0x16,0x10,0x12,0x12,0x17,0x13,0x17,0x1d,0x18,0x2f,0x4b,0x3e,0x59,0xa5,0xa9,0xa3,0xaa,0x9f,0x9e,0x9a,0x96,0x97,0x8e,0x8f,0x92 +,0x97,0x9b,0xa0,0xa8,0xc4,0xba,0xd9,0xb1,0xac,0xa5,0x9b,0xa3,0xa5,0xda,0xc8,0x47,0x2b,0x23,0x17,0x17,0x16,0x13,0x0f,0x0f,0x14,0x12,0x0f,0x0e,0x0e,0x1a,0x18,0x1a +,0x1c,0x20,0x58,0xbd,0xa3,0xa5,0xa2,0x9c,0x9b,0x9c,0x95,0x91,0x93,0x95,0x92,0x91,0x8f,0x8f,0x95,0x9a,0x9b,0x9a,0x9d,0x9f,0xac,0xae,0xac,0xad,0xca,0x6c,0x4a,0x2d +,0x26,0x27,0x1c,0x13,0x0f,0x0e,0x0d,0x0a,0x0c,0x0d,0x0c,0x10,0x1a,0x1c,0x19,0x13,0x13,0x1d,0x36,0x55,0x7c,0xb8,0x9b,0x96,0x97,0x91,0x8d,0x8b,0x8a,0x8a,0x8a,0x89 +,0x8a,0x8d,0x8f,0x8f,0x8e,0x93,0x97,0x99,0xa6,0xc4,0x38,0x20,0x17,0x15,0x0e,0x15,0x14,0x0f,0x0c,0x08,0x0b,0x0b,0x09,0x0b,0x0e,0x0d,0x0d,0x11,0x15,0x13,0x1b,0x29 +,0xac,0xa1,0xa0,0x98,0x95,0x92,0x93,0x94,0x91,0x8d,0x8c,0x8b,0x8f,0x8f,0x89,0x87,0x87,0x86,0x8b,0x8d,0x8f,0x98,0xb0,0x53,0x21,0x15,0x12,0x0f,0x0c,0x0b,0x0d,0x09 +,0x08,0x07,0x0b,0x0b,0x0e,0x13,0x10,0x17,0x1c,0x1f,0x19,0x1a,0x28,0x32,0xd3,0xca,0xac,0x9f,0xa6,0x9d,0xa0,0x9c,0x97,0x91,0x90,0x90,0x90,0x91,0x8b,0x8b,0x8c,0x8c +,0x8b,0x8e,0x8d,0x90,0x9b,0xa9,0xbc,0xdc,0x1f,0x19,0x1a,0x13,0x11,0x10,0x0d,0x0d,0x0c,0x0f,0x0e,0x10,0x0d,0x0b,0x0d,0x0e,0x12,0x11,0x12,0x15,0x15,0x1c,0x2d,0x38 +,0xbd,0xa2,0x94,0x96,0x9d,0x9b,0x8f,0x91,0x93,0x92,0x8f,0x8d,0x8b,0x8e,0x8e,0x89,0x8d,0x8a,0x8f,0x93,0x93,0x97,0xa9,0xbf,0x4f,0x31,0x1f,0x17,0x15,0x13,0x0d,0x09 +,0x08,0x05,0x04,0x09,0x0b,0x07,0x08,0x0c,0x18,0x1e,0x20,0x1f,0x22,0x1e,0x2b,0xe1,0xbb,0xb8,0x9f,0x97,0x90,0x8e,0x8e,0x8e,0x8d,0x8a,0x8d,0x8a,0x8a,0x8c,0x8d,0x8a +,0x8c,0x8d,0x91,0x9d,0x9c,0xaf,0x54,0x1f,0x1b,0x19,0x19,0x16,0x0d,0x15,0x17,0x18,0x0f,0x0e,0x0d,0x0b,0x0d,0x0a,0x0a,0x0b,0x0d,0x11,0x1a,0x1d,0x1b,0x1d,0x38,0x40 +,0x5e,0xb8,0xa1,0x9a,0x98,0x91,0x8f,0x8f,0x8c,0x8a,0x8b,0x90,0x91,0x8d,0x8c,0x8b,0x8b,0x8a,0x8a,0x8c,0x8e,0x8f,0x97,0xcd,0x1e,0x1c,0x23,0x18,0x0c,0x08,0x09,0x0c +,0x0f,0x0d,0x0e,0x0d,0x0b,0x0f,0x0b,0x0b,0x0d,0x12,0x18,0x1b,0x19,0x1b,0x28,0xc9,0xad,0xc3,0xab,0x9a,0x8e,0x95,0x97,0x8e,0x88,0x88,0x89,0x89,0x8b,0x8b,0x8a,0x8c +,0x8e,0x8d,0x95,0x92,0x90,0x8f,0x9a,0xb3,0x55,0x3c,0x2f,0x17,0x0b,0x0d,0x0e,0x09,0x13,0x0a,0x09,0x0b,0x09,0x0d,0x0d,0x09,0x06,0x0c,0x0c,0x0a,0x10,0x14,0x1c,0x30 +,0x4f,0xb5,0xab,0x9b,0x96,0x93,0x8d,0x8e,0x8d,0x8d,0x8d,0x8c,0x8c,0x8b,0x8b,0x88,0x87,0x8a,0x8a,0x8a,0x87,0x89,0x8d,0x98,0xa2,0xa9,0x4a,0x23,0x1a,0x10,0x0c,0x07 +,0x05,0x03,0x02,0x05,0x04,0x04,0x05,0x05,0x05,0x06,0x0e,0x0d,0x16,0x1e,0x20,0x37,0x4a,0x8f,0x8a,0x8b,0x8b,0x8a,0x86,0x89,0x89,0x83,0x86,0x8a,0x8c,0x8a,0x88,0x90 +,0x94,0x91,0x89,0x94,0xa6,0xa5,0xae,0xa9,0xac,0x6c,0x38,0xca,0x2e,0x0e,0x06,0x09,0x06,0x03,0x01,0x06,0x0a,0x03,0x03,0x05,0x0a,0x0f,0x0a,0x16,0x34,0x51,0xc2,0x31 +,0xad,0xbc,0x2d,0xb9,0x8b,0x87,0x8b,0x98,0x99,0x8a,0x87,0x8c,0x86,0x83,0x81,0x82,0x8c,0x8c,0x95,0xa4,0x32,0x9d,0x9a,0xec,0x29,0x18,0x35,0xc9,0x2e,0xc0,0xe0,0xb0 +,0x2e,0x0e,0x0c,0x03,0x01,0x01,0x08,0x05,0x01,0x04,0x05,0x13,0x11,0x15,0xc6,0xca,0x97,0x1f,0x32,0x26,0x35,0x1f,0x2e,0x8a,0x93,0x8d,0x83,0x83,0x82,0x81,0x82,0x80 +,0x83,0x80,0x9d,0x94,0x43,0xe6,0x07,0x28,0x25,0x08,0x3d,0x05,0x9c,0x2e,0x13,0x0f,0x00,0x2e,0x15,0x00,0x02,0x09,0x0c,0x17,0x80,0x9c,0x3c,0x94,0x46,0x85,0x86,0x8d +,0x80,0x88,0x80,0x94,0x08,0x0c,0x15,0x0b,0x18,0x1f,0x00,0x0b,0x13,0x9d,0x11,0x05,0x4e,0x40,0x49,0x05,0x03,0x01,0x07,0x00,0x30,0x86,0x91,0x85,0x90,0x80,0x81,0x9f +,0x92,0x8a,0x85,0x8e,0x96,0x88,0x73,0xba,0x80,0x89,0x8a,0x9e,0x99,0x8e,0x04,0x00,0x05,0x05,0x08,0x07,0x00,0x0e,0x16,0x08,0x89,0x97,0x20,0xa8,0xdc,0x8b,0x2f,0x00 +,0x15,0x51,0xaf,0x28,0x0e,0x14,0x23,0x16,0x8f,0x8a,0xaa,0x9e,0x58,0x85,0x8f,0x9d,0x9f,0x23,0x83,0xbe,0x0c,0x06,0x05,0x00,0xbb,0x84,0x99,0x82,0xb5,0x82,0x9d,0x19 +,0xaf,0x9b,0x83,0x8c,0xca,0x35,0x0c,0x1a,0x83,0x89,0x9e,0xa1,0x42,0x92,0x33,0x06,0x0a,0x00,0x42,0x15,0x0f,0x0f,0x00,0x09,0x91,0x85,0x33,0x0e,0x05,0x0b,0x02,0x01 +,0x02,0x04,0x0c,0x18,0x3c,0xe0,0x27,0xb8,0x83,0x80,0x80,0x94,0x8b,0x80,0x84,0x86,0x81,0x81,0x80,0x82,0x88,0x54,0x0d,0x0f,0x94,0x9f,0x0c,0x0c,0x00,0x06,0x00,0x04 +,0x00,0x2e,0x91,0x1f,0x05,0x00,0x01,0x00,0x37,0xb7,0x13,0x09,0x2a,0xa6,0x9b,0x1c,0xc5,0x81,0x83,0x80,0x88,0x8b,0x96,0x8f,0x80,0x80,0x80,0x8c,0x8b,0x85,0x9f,0x8e +,0xb1,0xcd,0x99,0x0f,0x04,0x02,0x00,0x0b,0x87,0x98,0x0e,0x07,0x0d,0x16,0x0a,0x02,0x02,0x8f,0x8b,0x21,0x02,0x02,0x00,0x3c,0x81,0x8e,0xcd,0x05,0x1c,0x1f,0x5d,0xc2 +,0x92,0x81,0x87,0x86,0x7b,0x21,0x13,0x8e,0x80,0x81,0xc5,0x07,0x8c,0x13,0x09,0x08,0x03,0x95,0x83,0x8e,0x12,0x05,0x0c,0x91,0x80,0x84,0x91,0x0b,0x1e,0x42,0x14,0x13 +,0x0b,0x8d,0x82,0x9e,0x0a,0x00,0x03,0xa4,0x80,0x85,0x4f,0x00,0x1a,0x0f,0x05,0x24,0x1c,0x9b,0x47,0x0e,0x0a,0x00,0x00,0x09,0x88,0xa6,0x06,0x01,0x08,0xb7,0xdf,0x54 +,0x85,0x80,0x83,0x80,0x8c,0x91,0x23,0x94,0x80,0x82,0x80,0x3e,0x66,0x95,0x9f,0x9a,0x88,0x80,0x81,0x98,0x0d,0x07,0x00,0x06,0x94,0x1e,0x06,0x02,0x00,0x01,0x03,0x06 +,0x00,0x0c,0x12,0x0d,0x0a,0x00,0x02,0x00,0x59,0x80,0x85,0x84,0x94,0x8b,0x8b,0x87,0x8a,0x80,0x80,0x81,0x80,0x0d,0x18,0x87,0x82,0x80,0x81,0x81,0x82,0x8c,0x1b,0x09 +,0x0b,0xa0,0x84,0x17,0x00,0x01,0x00,0x02,0x00,0xca,0x96,0x10,0x06,0x00,0x01,0x00,0x00,0x08,0x9c,0x8b,0xa7,0x20,0x0b,0x05,0x0d,0x96,0x80,0x82,0x81,0x26,0x11,0x9f +,0x95,0x80,0x83,0x80,0x83,0x80,0xa2,0x0e,0x56,0x14,0x81,0x86,0x8e,0x99,0x1e,0x0f,0x18,0xbd,0x19,0xaa,0x8d,0x2b,0x05,0x00,0x02,0x05,0x0c,0x92,0x9e,0xa8,0x0b,0x00 +,0x01,0x22,0x4b,0x29,0x8c,0x8c,0x9b,0x23,0x00,0x05,0x13,0x8c,0x80,0x8d,0x8f,0x0b,0x0c,0x26,0xae,0xea,0x86,0x80,0x87,0x84,0x1c,0x0a,0x0d,0x16,0x84,0x80,0x86,0xa4 +,0x0e,0x1b,0x08,0x20,0xb8,0x91,0x95,0xa2,0x24,0x00,0x01,0x00,0x0b,0x85,0x85,0xc1,0x16,0x00,0x03,0x12,0xa6,0x9c,0x81,0x85,0x8b,0x97,0x22,0xa5,0x1f,0x93,0x80,0x88 +,0x92,0x12,0x06,0x02,0x1d,0x35,0x9b,0x8d,0x94,0x14,0x00,0x00,0x05,0x02,0x1d,0x88,0xa4,0xc2,0x06,0x02,0x10,0xa2,0x9a,0x82,0x89,0x96,0xd8,0x14,0x11,0x34,0x98,0x87 +,0x80,0x80,0x8a,0x18,0x1d,0xad,0x82,0x94,0x88,0x8b,0x99,0x5b,0x09,0x02,0x07,0x1a,0x8f,0x85,0x39,0x02,0x00,0x00,0x03,0x0f,0x3b,0x9a,0x2d,0x48,0x06,0x05,0x06,0x07 +,0x14,0x8b,0x80,0x99,0x1b,0x05,0x06,0x9d,0x88,0x97,0x81,0x88,0x94,0x8c,0xb6,0xd2,0x88,0x8b,0x81,0x81,0x83,0x9e,0x29,0x2b,0x8d,0x88,0x88,0x81,0x8c,0xac,0x0d,0x07 +,0x00,0x16,0x17,0x36,0xb6,0x24,0x04,0x00,0x01,0x08,0x1f,0x27,0xa8,0x2c,0x0f,0x02,0x00,0x00,0x09,0x19,0x86,0x81,0x8c,0xa4,0x07,0x23,0x9a,0x8d,0x86,0x82,0xaa,0x9d +,0x2d,0x0b,0x3f,0x3e,0x89,0x80,0x80,0x85,0xaf,0xbd,0xaf,0x8b,0x86,0x80,0x87,0x94,0xa1,0x1c,0x0e,0x11,0x09,0x1f,0x93,0xba,0x16,0x01,0x00,0x00,0x0d,0x07,0x2e,0x29 +,0x0e,0x14,0x05,0x07,0x04,0x0b,0x60,0x84,0x86,0xa4,0x1d,0x08,0x19,0x8a,0x88,0x84,0x84,0x8e,0x97,0x36,0x9e,0xa5,0xa5,0x84,0x80,0x80,0x86,0x24,0x0e,0x9c,0x8d,0x89 +,0x91,0x4a,0xb3,0x0a,0x00,0x07,0x05,0x0f,0x18,0x8a,0xd7,0x02,0x06,0x00,0x07,0x09,0x2d,0x8c,0x5d,0x14,0x0f,0x02,0x0a,0x1d,0x13,0x8d,0x80,0x87,0x93,0x16,0x1d,0xbe +,0x8d,0x85,0x82,0x88,0x83,0x91,0xa5,0x1a,0x15,0x9d,0x84,0x80,0x8a,0xac,0x06,0x06,0x14,0x60,0xb7,0xac,0x9e,0x3f,0x00,0x03,0x00,0x08,0x19,0xa4,0x87,0x18,0x08,0x02 +,0x00,0x1d,0x97,0x88,0x84,0x86,0xa9,0x1a,0x12,0x22,0x9d,0x97,0x86,0x80,0x86,0x9d,0x0e,0x1c,0x99,0x93,0x81,0x87,0x93,0x42,0x14,0x0b,0x07,0x0b,0x1e,0x86,0x82,0x3c +,0x07,0x02,0x04,0x12,0x0b,0xb2,0x9e,0x24,0x14,0x00,0x03,0x00,0x0f,0x94,0x80,0x81,0x8b,0xe4,0x06,0x19,0x25,0x99,0x80,0x86,0x81,0xaf,0x12,0x25,0x23,0x2c,0x88,0x80 +,0x85,0x89,0x0e,0x00,0x10,0xa9,0xe9,0x93,0x8d,0x2d,0x12,0x05,0x04,0x0a,0x0a,0xa8,0x86,0x8b,0x26,0x03,0x00,0x06,0x4e,0xac,0x8c,0x9d,0x0b,0x02,0x04,0x05,0x27,0x92 +,0x87,0x81,0xb7,0x10,0x03,0x0b,0x8f,0x8f,0x85,0x80,0x85,0x88,0xba,0xb9,0xa7,0x93,0x85,0x80,0x82,0x82,0xa7,0x06,0x16,0x29,0xcd,0xa0,0xbd,0x9a,0x13,0x02,0x00,0x00 +,0x04,0x1c,0x86,0xb0,0x0c,0x00,0x00,0x06,0x07,0x0c,0x27,0x1d,0x1b,0x0d,0x03,0x0a,0x18,0x9a,0x88,0x80,0x82,0x88,0x27,0x26,0x9b,0x8b,0x80,0x81,0x80,0x86,0x86,0x98 +,0xa9,0x8c,0x86,0x80,0x81,0x8b,0x26,0x02,0x08,0x09,0x07,0x1b,0x3e,0x1d,0x0d,0x00,0x01,0x00,0x03,0x1f,0xad,0x2b,0x04,0x01,0x00,0x04,0x15,0x99,0x8b,0x86,0x89,0x5f +,0x17,0x0d,0x14,0x8b,0x80,0x80,0x81,0x96,0x3c,0x2d,0x87,0x84,0x82,0x80,0x81,0x87,0xa1,0x14,0x0d,0x29,0x8b,0x80,0x87,0xa3,0x0d,0x00,0x0e,0x18,0x2b,0xa8,0x23,0x7b +,0x09,0x00,0x02,0x00,0x09,0x8c,0x94,0x0e,0x04,0x00,0x03,0x03,0x2a,0x9c,0xb1,0x97,0x75,0x0e,0x07,0x0a,0x90,0x80,0x80,0x80,0xa1,0x1d,0x92,0x8b,0x81,0x80,0x81,0x80 +,0x83,0x94,0x28,0x2f,0xaf,0x84,0x82,0x94,0x0e,0x00,0x02,0x01,0x08,0x0a,0x15,0x47,0x1e,0x02,0x00,0x01,0x03,0x8e,0x8f,0x36,0x0a,0x00,0x09,0x0c,0x5e,0xb6,0x90,0x86 +,0x95,0x39,0x13,0x27,0x8c,0x80,0x82,0x82,0xa4,0x29,0x97,0x91,0x8b,0x86,0x85,0x83,0x9a,0x1e,0x0d,0x1e,0x8c,0x80,0x86,0x9c,0x09,0x0c,0x0f,0x0c,0x1e,0x37,0xaf,0x22 +,0x06,0x00,0x03,0x00,0x23,0x8a,0xcc,0x10,0x00,0x02,0x06,0x0e,0x31,0xd3,0xa5,0xad,0x10,0x15,0x25,0x92,0x80,0x83,0x80,0xb8,0x2c,0x99,0x94,0x87,0x81,0x87,0x80,0x8b +,0x2d,0x2c,0xa6,0x81,0x80,0x82,0x92,0x06,0x0d,0x0f,0x0a,0x17,0x0a,0x14,0x25,0x06,0x01,0x00,0x00,0xb5,0xad,0x09,0x05,0x00,0x02,0x03,0x09,0x2e,0xa1,0x89,0x95,0x26 +,0x11,0x10,0x88,0x80,0x80,0x87,0x21,0x94,0x83,0x88,0x84,0x86,0x84,0x84,0x90,0xba,0x3c,0x9a,0x80,0x8d,0xbd,0x0c,0x06,0xb0,0xad,0x98,0x3b,0x16,0x27,0x0c,0x00,0x03 +,0x00,0x50,0x88,0x1f,0x0a,0x00,0x02,0x05,0x09,0x0d,0x20,0xa5,0x25,0x00,0x03,0x00,0x1c,0x80,0x84,0x81,0x1d,0x0f,0x98,0x92,0x82,0x81,0x80,0x80,0x8b,0xc0,0x33,0xae +,0x80,0x80,0x83,0x8d,0x09,0x23,0x25,0x0d,0x35,0x43,0x8f,0x90,0x0d,0x06,0x00,0x0f,0x8a,0xaa,0x1c,0x01,0x06,0x06,0x00,0x02,0x05,0xad,0x8c,0x18,0x00,0x02,0x05,0x83 +,0x8d,0x8a,0xa7,0x1a,0x90,0x9d,0x8b,0x8b,0x83,0x80,0x87,0x69,0x1c,0x1c,0x86,0x80,0x84,0x81,0xa7,0x95,0x9c,0x6e,0x2d,0x0f,0x0e,0x3b,0x05,0x00,0x00,0x05,0x8d,0xb9 +,0x8c,0x16,0x00,0x41,0x89,0x84,0x23,0x18,0x9a,0xae,0x09,0x0c,0x08,0x84,0x80,0x98,0x24,0x1d,0x9f,0x2c,0x0d,0x3f,0x83,0x80,0x9b,0x00,0x04,0x00,0x95,0x86,0xd1,0x29 +,0x00,0x1b,0x1e,0x90,0x82,0x86,0x80,0x86,0x0a,0x00,0x00,0x04,0x88,0x92,0xa3,0x10,0x0c,0xb9,0xaf,0xad,0x89,0x83,0x81,0x89,0x1c,0x0c,0x36,0x82,0x8c,0x8a,0x9c,0x17 +,0xc0,0xa9,0xa9,0x2c,0x2d,0xa7,0xe6,0x08,0x00,0x05,0x1b,0x24,0x0d,0x05,0x00,0x05,0x0f,0xdc,0x40,0x95,0x82,0x84,0x9a,0xb0,0x41,0x8f,0x80,0x88,0x92,0x04,0x0c,0x2c +,0x17,0x20,0x9a,0x84,0x8a,0x25,0x09,0x01,0x1a,0x80,0x82,0x80,0x21,0x06,0x15,0x0d,0x55,0x2c,0xc1,0x88,0x9e,0x0f,0x08,0x00,0x90,0x8a,0x96,0xb1,0x09,0x14,0x00,0x01 +,0x07,0x1b,0x8c,0x91,0x0e,0x0d,0x08,0x90,0x81,0x8a,0x9c,0x23,0x92,0xa7,0xba,0xaa,0x92,0x89,0x85,0xa9,0x1a,0x0d,0x9e,0x80,0x8e,0x93,0x19,0xbc,0x9c,0x3a,0x1b,0x16 +,0xfe,0xb0,0x18,0x05,0x01,0x07,0x85,0x83,0x88,0x12,0x07,0x9a,0x96,0xa8,0x10,0x3f,0x2d,0x0f,0x00,0x02,0x00,0xbe,0x89,0x93,0x28,0x03,0x27,0x17,0xc4,0x3d,0x94,0x81 +,0x80,0x89,0x5b,0x1c,0x87,0x80,0x81,0x83,0x2b,0x8d,0xa1,0xb5,0xce,0x28,0x8f,0x84,0x2f,0x05,0x00,0x09,0x99,0x2e,0xab,0x0b,0x0c,0x0b,0x11,0x2c,0x0d,0xa0,0x96,0x29 +,0x06,0x04,0x0b,0x90,0x6a,0x42,0x0d,0x0d,0xe2,0x1d,0x44,0x19,0x99,0x8c,0xa3,0x33,0x0f,0x11,0x83,0x83,0x82,0x98,0x20,0x87,0x8e,0x86,0x85,0x83,0x80,0x86,0x46,0x08 +,0x08,0x98,0x80,0x8e,0xcb,0x01,0x0d,0x0d,0x0f,0x12,0x0b,0xbf,0xc0,0x06,0x00,0x00,0x08,0x98,0x1f,0x20,0x06,0x12,0x1a,0x0c,0x14,0x07,0x93,0x81,0x8d,0x19,0x02,0x0c +,0x83,0x83,0x85,0x43,0x0c,0x9b,0x9b,0x85,0x86,0x82,0x80,0x84,0xa2,0x1d,0x17,0x87,0x80,0x8d,0x4d,0x00,0x2e,0x4f,0xbe,0x31,0xb9,0x88,0x8a,0x28,0x02,0x00,0x09,0x88 +,0x8f,0x3a,0x01,0x05,0x0a,0x02,0x06,0x00,0x11,0x43,0x0e,0x01,0x00,0x05,0x84,0x86,0x81,0x3c,0x1e,0x8c,0x8e,0x86,0xa9,0x89,0x83,0x82,0xb0,0x21,0x28,0x86,0x80,0x83 +,0x8c,0x23,0x92,0xaa,0xa4,0x31,0xb4,0x89,0x86,0xab,0x08,0x00,0x25,0x81,0x99,0x1f,0x00,0x0a,0x09,0x06,0x07,0x07,0x2d,0xc9,0x12,0x00,0x03,0x00,0xab,0x94,0x30,0x09 +,0x01,0x18,0x5d,0x91,0xc8,0x8e,0x82,0x81,0x8b,0x6a,0x21,0x8a,0x80,0x80,0x82,0xbc,0x96,0xd3,0xb7,0x9e,0x95,0x85,0x87,0x34,0x07,0x00,0x26,0x80,0x84,0x88,0x0b,0x12 +,0x15,0x0e,0x17,0x0f,0xad,0x96,0x3e,0x02,0x01,0x01,0xb3,0xaa,0xa8,0x13,0x00,0x06,0x00,0x05,0x07,0x9f,0x85,0x83,0x19,0x01,0x00,0xa8,0x80,0x83,0x88,0x31,0x8f,0x92 +,0x89,0x97,0x8a,0x81,0x81,0x8d,0x0e,0x01,0x19,0x82,0x8d,0x9f,0x08,0x23,0xa0,0xb4,0xa4,0xd7,0x8c,0x8b,0xac,0x05,0x02,0x00,0x91,0x87,0x97,0x19,0x05,0x12,0x10,0x38 +,0x1d,0x94,0x87,0x86,0x0d,0x02,0x00,0x1f,0x80,0x84,0xb9,0x00,0x1c,0x0e,0x1b,0x09,0x48,0x86,0x80,0x8f,0x0e,0x00,0x1a,0x80,0x88,0x85,0x1e,0x3a,0x27,0x0f,0x0b,0x0d +,0x8d,0x83,0x82,0x26,0x03,0x07,0x87,0x82,0x80,0x9e,0x24,0xa8,0x35,0x98,0xb1,0x8d,0x8a,0x8a,0x17,0x03,0x00,0x48,0x84,0x9c,0x1d,0x00,0x17,0x0f,0x13,0x06,0x0c,0xc7 +,0xa0,0x12,0x04,0x00,0x0a,0x8c,0x88,0x84,0x18,0x1c,0x1a,0x1c,0x2b,0xbe,0x85,0x83,0x8b,0x1b,0x02,0x0f,0x80,0x85,0x80,0x70,0x14,0x25,0x12,0xce,0x3d,0x86,0x83,0x81 +,0xcf,0x09,0x06,0x90,0x81,0x84,0x90,0x07,0x21,0x0c,0x0e,0x05,0x15,0x8c,0x88,0x62,0x05,0x00,0x04,0x90,0x91,0x9c,0x0d,0x19,0x2b,0x0f,0x0f,0x0a,0xa7,0x8a,0x8e,0x0a +,0x04,0x00,0x9f,0x86,0x8a,0x28,0x06,0x3e,0x30,0x9f,0x27,0xa4,0x8c,0x85,0xcd,0x09,0x01,0xaf,0x80,0x83,0x81,0x23,0x9d,0x99,0x92,0x97,0xa8,0x89,0x82,0x8c,0x0d,0x02 +,0x02,0x8d,0x87,0x87,0x33,0x0a,0x3b,0x0e,0x21,0x14,0xc8,0x9a,0x8c,0x20,0x08,0x00,0x16,0x8a,0x9b,0xca,0x01,0x0c,0x0f,0x17,0x08,0x06,0x2e,0x8d,0xc3,0x06,0x01,0x06 +,0x8c,0x89,0x88,0x1d,0x13,0x2f,0xad,0x87,0x9e,0x87,0x84,0x82,0x9a,0x0e,0x1b,0x88,0x82,0x80,0x93,0x0a,0xc7,0xa3,0x82,0x8f,0x9d,0x88,0x88,0xa7,0x0d,0x00,0x09,0x8e +,0x8e,0x9d,0x08,0x05,0x09,0x0f,0x1d,0x0f,0x22,0x94,0x9d,0x0e,0x05,0x00,0xbb,0x89,0x87,0x25,0x00,0x03,0x08,0x1d,0x09,0x1a,0xad,0x94,0x4a,0x13,0x0c,0x9f,0x80,0x80 +,0x88,0x0a,0x25,0xbb,0x8b,0x8c,0xa3,0x8d,0x86,0x85,0xa4,0x0d,0x15,0x87,0x83,0x80,0x3a,0x0f,0x3c,0xa1,0x80,0x8a,0x90,0x8d,0x8c,0x32,0x06,0x00,0x13,0x8c,0x8d,0x3f +,0x00,0x02,0x03,0x19,0x1d,0x0d,0x22,0xc1,0x22,0x05,0x00,0x00,0xb4,0x8a,0x86,0x17,0x02,0x0c,0x18,0x32,0x12,0x1c,0xa0,0x88,0x98,0x1a,0x05,0x9b,0x81,0x80,0x8a,0x3e +,0xa7,0x97,0x86,0x8d,0x9a,0x9f,0x89,0x84,0xab,0x20,0x97,0x83,0x80,0x83,0x21,0x13,0x19,0x90,0x83,0xa7,0x1c,0x0b,0x1a,0x0d,0x05,0x01,0x1d,0xa8,0x42,0x0d,0x00,0x03 +,0x00,0x15,0x11,0x0e,0x0f,0x09,0x0d,0x07,0x01,0x03,0xa7,0x86,0x8a,0x15,0x08,0x12,0xa7,0x81,0x83,0x80,0x83,0x86,0x9d,0x25,0x22,0x8c,0x80,0x80,0x86,0x9f,0x9b,0x9b +,0x84,0x87,0x8e,0x98,0x96,0x91,0x27,0x09,0x04,0x1d,0x51,0x9f,0x1b,0x05,0x05,0x0b,0x21,0x07,0x17,0x1b,0xb3,0xeb,0x0e,0x08,0x0c,0xbe,0xae,0xac,0x10,0x04,0x01,0x14 +,0x6d,0x49,0x2d,0x1d,0x65,0x2e,0x44,0xb7,0x8f,0x84,0x88,0x9f,0x4c,0x5b,0xaa,0x89,0x8d,0x9c,0x29,0x57,0x9c,0x9f,0xa4,0xab,0x8c,0x8f,0x8a,0x9e,0x29,0x19,0x2a,0x9d +,0xa6,0xb3,0xaf,0x9f,0x42,0x21,0x0d,0x29,0x8e,0x89,0x97,0x0a,0x0e,0x18,0x4a,0xb6,0x1f,0x1a,0x14,0x2a,0x2b,0x2e,0x0d,0x21,0xa3,0x9c,0xaf,0x29,0x3f,0x14,0x1f,0x15 +,0x0f,0x1e,0x34,0xcc,0x35,0x16,0x10,0xb9,0x92,0x88,0x8f,0x2e,0x1c,0x13,0xaa,0xa9,0xa7,0x68,0x15,0x25,0x20,0xbf,0x1b,0xda,0xa9,0x8c,0x8a,0xa6,0xa4,0x27,0x9b,0x92 +,0x87,0x86,0x8e,0x8d,0xa5,0xa9,0x3b,0xa3,0x8d,0x89,0x83,0xa1,0x14,0x04,0x10,0xa9,0x90,0x9d,0x0c,0x09,0x08,0x10,0x0c,0x0c,0x26,0x1c,0xa8,0x0f,0x04,0x01,0x04,0x1d +,0x2a,0x2d,0x0a,0x15,0x0f,0x0d,0x09,0x03,0x1d,0x98,0x80,0x8b,0xa2,0x1a,0x1e,0x86,0x82,0x81,0x8d,0x9c,0x8c,0x8e,0x87,0xe2,0x94,0x86,0x84,0x80,0x96,0x97,0x58,0x8f +,0x8f,0x8e,0x90,0xa1,0x89,0xae,0xc8,0x0c,0x03,0x12,0x18,0x9f,0x11,0x0b,0x02,0x05,0x12,0x09,0x11,0x08,0x08,0x16,0x0f,0x0b,0x04,0x06,0x09,0x13,0x99,0x4f,0xa5,0x0a +,0x0d,0x19,0x14,0x91,0xae,0x8a,0x95,0x8d,0x8a,0x38,0x9d,0x97,0x87,0x80,0x86,0x86,0x29,0xd3,0xa5,0x8e,0x83,0x89,0x8b,0x9e,0x9a,0xcf,0x16,0x2a,0xb5,0x90,0x87,0x87 +,0x8f,0x11,0x28,0x1f,0x98,0x8e,0xab,0xbb,0x09,0x04,0x03,0x02,0x09,0x11,0x0d,0x10,0x07,0x08,0x02,0x08,0x0a,0x17,0x1c,0x0d,0x15,0x17,0x4c,0xb0,0x21,0x10,0x22,0xa4 +,0x85,0x89,0x8d,0x1d,0x1a,0xa7,0x8d,0x85,0x8f,0x90,0x8f,0x8c,0x8f,0x9f,0xb2,0x9d,0x97,0x83,0x85,0x8c,0xe0,0x24,0x49,0x63,0x8d,0x8f,0x8d,0x9d,0xed,0x18,0x15,0x24 +,0xb8,0x97,0x9c,0x97,0x24,0x10,0x02,0x07,0x18,0x37,0xcc,0x0f,0x06,0x08,0x0e,0x10,0x1a,0x19,0x1a,0x38,0x9c,0xb2,0x27,0x0b,0x0c,0x25,0xac,0x9d,0x1b,0x17,0x16,0x37 +,0xa6,0xa9,0x3d,0x41,0xc5,0x91,0x8a,0x91,0x92,0xa4,0x95,0x90,0x91,0x94,0x97,0x9f,0x96,0xa1,0xb3,0x1d,0x17,0x5a,0xb1,0x8a,0x91,0x9d,0x28,0x2a,0x4b,0x4c,0x98,0x96 +,0x2d,0x0c,0x2e,0x19,0x09,0x05,0x18,0x98,0x8a,0x85,0xbc,0x0f,0x1f,0x5d,0x1a,0xa0,0x80,0x82,0x9b,0x17,0x04,0x0a,0x12,0x19,0x3f,0x07,0x01,0x00,0x04,0x05,0x17,0xb9 +,0xd5,0x2a,0x16,0x8b,0x8c,0x8e,0x83,0x85,0x80,0x82,0x85,0x26,0xae,0x9d,0x92,0x1b,0x00,0x42,0x9f,0x94,0x0e,0xbd,0xa5,0xba,0x8f,0xba,0x0a,0x17,0x04,0x45,0x83,0x82 +,0x92,0x07,0x04,0x00,0x16,0x3c,0x9e,0x2e,0x06,0x02,0x09,0x1e,0x89,0x98,0x6c,0xac,0x8e,0x83,0x8f,0x87,0x9a,0x25,0x0e,0x09,0x0a,0x1b,0x0d,0x08,0x15,0x19,0x2b,0x3c +,0xd7,0x95,0x82,0x8b,0x92,0x91,0x9e,0x8f,0x9c,0xad,0x1e,0xa9,0x81,0x96,0x18,0x04,0x71,0x86,0x80,0x87,0x9e,0xa8,0x2a,0x1d,0x1c,0x95,0x8c,0x38,0x2c,0x0a,0x02,0x02 +,0x01,0x03,0x01,0x1a,0xb4,0x9d,0xd0,0x18,0x1e,0xae,0x88,0x84,0x85,0x8a,0x98,0xf8,0x8f,0x97,0x33,0x3d,0x1e,0x17,0x09,0x18,0x2b,0x15,0x9a,0x8c,0x5d,0x0c,0x09,0x53 +,0x96,0x8b,0x8b,0x9e,0x97,0x90,0x8e,0x80,0x83,0x96,0x19,0x0f,0x1a,0x69,0x98,0x30,0x24,0x2e,0x1e,0x20,0x0e,0x0c,0x0c,0x49,0x94,0x92,0x8a,0x0e,0x00,0x00,0x13,0x94 +,0x9c,0x13,0x00,0x05,0x0d,0x12,0x12,0xad,0x9f,0x95,0x86,0x98,0xa1,0x93,0x8c,0x86,0x94,0x8d,0x8e,0x9a,0xd0,0xec,0x99,0x3f,0xd6,0x25,0x1b,0x21,0xc2,0x8b,0x8d,0x89 +,0x88,0x84,0x82,0x91,0x9b,0x93,0x9a,0xac,0x25,0x07,0x04,0x0a,0x2d,0x40,0x11,0x03,0x00,0x02,0x00,0x15,0xb8,0xb8,0x55,0x4e,0x69,0x2f,0xb7,0x90,0x87,0x85,0x81,0x97 +,0xbb,0x0d,0x05,0x16,0xd7,0x9d,0x2f,0x21,0x1c,0x2f,0x97,0x8b,0x89,0x84,0x86,0x82,0x8d,0x9d,0x2f,0x0c,0x1a,0x28,0x4f,0x1a,0x09,0x08,0x0f,0xc5,0xc2,0x12,0x0c,0x22 +,0x9a,0x92,0xb6,0x21,0x10,0x16,0x18,0x15,0x16,0x05,0x07,0x06,0x05,0x09,0x00,0x00,0x03,0x21,0x87,0x88,0x8c,0xbd,0x1e,0xc2,0x8f,0x80,0x81,0x81,0x84,0x88,0x8a,0x91 +,0x9c,0x94,0x98,0x90,0x9e,0xc9,0x26,0x1f,0x97,0x8e,0x8d,0xa4,0xbc,0x54,0x2f,0x13,0x0e,0x1f,0xaf,0x98,0x8c,0x9a,0x1e,0x43,0xce,0x8b,0x87,0x83,0x8a,0x93,0x92,0x93 +,0x93,0xa1,0x2f,0x0b,0x03,0x0e,0xae,0xa0,0xce,0x07,0x01,0x03,0x0c,0x1d,0x15,0x21,0x2d,0x11,0x0f,0x01,0x01,0x05,0x12,0xa0,0x35,0x27,0x0b,0x07,0x0f,0x0d,0x31,0x46 +,0xad,0xcc,0x1a,0x14,0x0e,0x1d,0xa9,0x8b,0x87,0x8e,0xb5,0x20,0x14,0x9a,0x83,0x80,0x86,0xaa,0x1b,0x37,0x87,0x86,0x84,0x81,0x81,0x80,0x85,0x87,0x90,0xb6,0x9e,0x9c +,0x97,0x3f,0x13,0x0e,0x09,0x0a,0x09,0x02,0x05,0x08,0x11,0xaf,0x1e,0x1b,0x07,0x08,0x0f,0x0c,0x13,0x12,0x4a,0x9f,0x90,0x99,0x25,0x2a,0x9e,0x8a,0x81,0x8d,0xaf,0x0d +,0x06,0x2a,0x8e,0x82,0x85,0x8d,0x93,0xaa,0x96,0xa2,0x3d,0xa1,0x95,0x88,0x9c,0xb8,0x10,0x05,0x12,0x23,0x39,0x24,0x0e,0x11,0x0a,0x02,0x05,0x0c,0xa9,0x2c,0x2c,0x0e +,0x05,0x09,0x0d,0xb6,0xa4,0xbb,0x22,0x09,0x08,0x0d,0x20,0x38,0x1a,0xc0,0x38,0x98,0x96,0xae,0xac,0xa8,0x84,0x82,0x81,0x83,0x9c,0x9f,0x9e,0xa1,0xb1,0x0c,0x18,0x20 +,0xba,0xa7,0x22,0x18,0x06,0x17,0x27,0xa3,0x8c,0x9b,0x8f,0x8f,0x8c,0x9f,0x22,0x9f,0x8b,0x81,0x82,0x87,0x96,0xcf,0x8f,0x8a,0x8d,0x95,0x13,0x12,0x0e,0x10,0xca,0x21 +,0xab,0xa3,0x94,0x9d,0x25,0x18,0x03,0x0d,0xad,0x92,0x99,0x0e,0x02,0x07,0x0c,0x2a,0x0b,0x12,0x15,0x16,0xa6,0x13,0x0b,0x05,0x06,0x0f,0x0c,0x0e,0x07,0x07,0x0a,0x0b +,0x14,0x0a,0x18,0x4a,0xdd,0xad,0x2b,0x9e,0xa7,0x9f,0x97,0x9a,0x8b,0x90,0x85,0x81,0x84,0x82,0x8a,0x87,0x81,0x82,0x80,0x8a,0x8d,0x26,0x19,0xac,0x98,0x8c,0xd9,0x18 +,0x06,0x02,0x0b,0x02,0x13,0x2c,0x9f,0x88,0x9b,0x9c,0x1a,0x2e,0x8d,0x88,0x83,0x89,0x97,0xb5,0xb4,0xaa,0x22,0x6d,0x55,0xaf,0x93,0x37,0x3f,0x17,0x4f,0x88,0x8d,0x92 +,0x1e,0x07,0x07,0x02,0x0c,0x05,0x0c,0x08,0x0a,0x1e,0x19,0x1e,0x04,0x06,0x16,0x1e,0xba,0x1f,0x0f,0x23,0x1b,0x36,0x0a,0x11,0x2c,0xcc,0x93,0x59,0x55,0x0f,0x0b,0x2f +,0xa9,0x8a,0x94,0x9d,0x93,0xb1,0x9a,0x58,0xb7,0x8e,0x8a,0x80,0x86,0x91,0x38,0xab,0x8f,0x8b,0x83,0x85,0x8c,0x9d,0xbe,0x98,0x91,0x8a,0x87,0x97,0x96,0x20,0x0b,0x03 +,0x07,0x24,0xaf,0x8f,0xa2,0x1e,0x0e,0x0e,0x14,0x0c,0x23,0xc6,0xae,0x92,0x32,0x37,0x0f,0x0b,0x19,0x1a,0x2f,0x13,0x12,0x16,0x1d,0xbc,0x23,0x25,0xc5,0xb8,0x8b,0x9a +,0x8f,0xc3,0x18,0xce,0xbf,0xb6,0x1a,0x16,0x12,0x09,0x10,0x08,0x0c,0x2b,0xaf,0x8d,0x9c,0x9d,0x20,0x23,0xa0,0x8e,0x84,0x92,0x4d,0x1c,0x12,0x17,0x11,0x1b,0x9b,0x8d +,0x82,0x90,0xac,0x0e,0x0d,0x59,0xa1,0x84,0x8b,0x95,0xa7,0x3e,0xf4,0x26,0x15,0x35,0xba,0xab,0x6f,0x26,0x0b,0x01,0x12,0x2c,0x57,0x27,0x19,0x16,0x24,0xbc,0xed,0xb8 +,0xa5,0x9e,0x83,0x88,0x8c,0xa0,0x65,0x93,0x8b,0x80,0x85,0x88,0x88,0x84,0x8f,0xcd,0x30,0xaf,0xad,0x8f,0x8e,0x8e,0xa1,0x15,0x28,0x2a,0x96,0xaa,0xb6,0xc3,0x0f,0x09 +,0x01,0x02,0x05,0x04,0x10,0x0d,0x08,0x03,0x01,0x03,0x05,0x0e,0x11,0x17,0x0b,0x02,0x04,0x05,0x0a,0x4d,0xd3,0x8c,0x94,0xab,0x1d,0x07,0x1b,0xd1,0x8d,0x8c,0x8c,0x9c +,0xcb,0xcc,0xa9,0xa6,0x8c,0x84,0x81,0x85,0x87,0x8e,0xaf,0x9d,0x98,0x8d,0x8e,0x95,0x90,0x97,0xa5,0xaa,0xb3,0x97,0xa7,0x8a,0x89,0x8a,0x98,0x20,0xab,0xa1,0x91,0x9d +,0x9e,0xad,0x57,0x28,0x14,0x0d,0x23,0x39,0x9a,0x9e,0xaf,0xc0,0x0c,0x0e,0x16,0xa9,0x4d,0x2c,0x2e,0x11,0x08,0x01,0x00,0x03,0x08,0x38,0x19,0x09,0x05,0x01,0x0b,0x0c +,0x18,0x1f,0x3b,0x35,0x21,0x16,0x19,0x2a,0xa9,0x9a,0x89,0x96,0x99,0x99,0xc8,0x9e,0x96,0x85,0x86,0x88,0x98,0xb9,0x43,0x48,0x79,0xa3,0xa6,0x99,0xa3,0xaf,0xa5,0xb1 +,0xa0,0xb3,0x8d,0x86,0x86,0x8a,0x93,0xad,0xa4,0xc1,0x3a,0x2f,0xda,0x65,0x1d,0x0d,0x05,0x10,0x0d,0x12,0x15,0x2e,0xa9,0xa6,0x9c,0xa3,0xa9,0x96,0x91,0x8e,0x89,0x88 +,0x8f,0xac,0xa9,0xa3,0x9e,0x92,0x91,0x99,0xa8,0x3c,0x27,0x33,0x2d,0x28,0xc8,0xa0,0x3c,0x0b,0x07,0x07,0x0c,0x0b,0x08,0x09,0x0a,0x06,0x05,0x04,0x03,0x03,0x06,0x16 +,0x17,0x25,0x1e,0x1d,0x49,0x46,0xd5,0xca,0xa8,0x99,0x98,0x9b,0x9e,0x4c,0x23,0x1c,0x2f,0xe9,0xbc,0xa9,0xa8,0x27,0x14,0x1f,0xbc,0x8e,0x8b,0x8a,0x95,0x94,0x91,0x9a +,0x9b,0x93,0x8a,0x87,0x88,0x9c,0xa7,0x9c,0x93,0x92,0x94,0x8e,0x8e,0x92,0xa4,0x4c,0x1f,0x29,0xc9,0xbd,0xc7,0x26,0x1c,0x0f,0x17,0x37,0x31,0x2b,0x2d,0x2f,0x22,0x26 +,0x1b,0x1a,0x16,0x11,0x13,0x10,0x0d,0x16,0x1a,0x1a,0x1c,0x1f,0x38,0xda,0x3f,0x1c,0x24,0xaf,0xa8,0xe0,0x55,0xdc,0xc9,0xb4,0xd0,0x26,0x2b,0x2f,0x1d,0x23,0x2d,0x2a +,0x3c,0x29,0x25,0x2e,0x25,0x36,0xbb,0xa9,0xb3,0xb7,0x3f,0x24,0xd4,0xbf,0xa9,0x9e,0xaa,0xa9,0xa8,0xa7,0xae,0xaa,0x96,0x8d,0x8e,0x8d,0x9d,0xa8,0x9c,0x98,0x9c,0x97 +,0x97,0xc7,0x2b,0x16,0x13,0x14,0x0f,0x15,0x19,0x15,0x0f,0x0a,0x0a,0x15,0x37,0x5d,0xac,0x98,0x93,0x8c,0x8b,0x89,0x86,0x87,0x87,0x85,0x85,0x86,0x86,0x88,0x8d,0x8f +,0x97,0xa5,0xc7,0x51,0xd7,0x2b,0x1c,0x1a,0x0f,0x0b,0x08,0x0a,0x0e,0x0c,0x0d,0x0f,0x0c,0x0c,0x10,0x0d,0x0e,0x0b,0x05,0x05,0x06,0x05,0x06,0x0b,0x0b,0x10,0x0d,0x11 +,0x1f,0x1d,0x3c,0xb6,0x9f,0x9e,0x9d,0xac,0xb7,0xb5,0xd1,0x46,0xf0,0xa2,0x9e,0x9a,0x96,0x9a,0x9d,0x8e,0x86,0x84,0x83,0x84,0x87,0x89,0x8d,0x91,0x9c,0xaa,0xaa,0xac +,0xbf,0x2e,0x32,0x34,0x2f,0x43,0x3e,0xab,0x99,0xa3,0xe0,0xc7,0x9e,0xa6,0xa0,0xab,0xa6,0x33,0x46,0x3a,0x64,0x32,0x0b,0x24,0x1e,0x47,0x1c,0x14,0x40,0x1f,0xb6,0xa6 +,0xdb,0x9f,0xa8,0xd9,0x4f,0xa1,0x19,0x0c,0xab,0x2e,0x29,0x4a,0x06,0x16,0xad,0x4b,0x45,0xbf,0x43,0x17,0x1c,0x0c,0x0e,0x0c,0x10,0x0f,0x15,0x14,0x13,0x19,0x0e,0x17 +,0x0e,0xaf,0xc8,0x7d,0xae,0xe7,0xe6,0xaf,0xa0,0xad,0x93,0x8c,0x90,0x9a,0x92,0x98,0x8f,0x85,0x88,0x89,0x88,0x8a,0x84,0x83,0x86,0x88,0x8b,0x8a,0x8b,0x96,0x8f,0xa9 +,0xe5,0x17,0x06,0x0a,0x0a,0x09,0x04,0x05,0x04,0x09,0x07,0x0f,0x0d,0x0b,0x12,0x0a,0x05,0x0c,0x0d,0x1e,0xba,0x9e,0xa0,0xa8,0x9d,0x9b,0x98,0x8d,0x8c,0x88,0x83,0x84 +,0x86,0x94,0x94,0x8f,0x8c,0x99,0x8f,0x9a,0x9b,0x9d,0xb1,0x39,0x65,0xa8,0x92,0x8f,0x45,0x2e,0x1c,0x1e,0x13,0x1b,0x0d,0x0e,0x0d,0x09,0x07,0x07,0x09,0x09,0x15,0x0d +,0x14,0x0f,0x16,0x0c,0x2b,0xb1,0xad,0x9a,0xda,0x9e,0xab,0xb6,0xd0,0x98,0xa0,0x9f,0x9c,0xa9,0x9b,0xb2,0x8e,0x98,0x93,0x8e,0x99,0x8b,0x8f,0x87,0x8f,0x9a,0x99,0x94 +,0x99,0x99,0xb2,0x19,0x18,0x1e,0x24,0x0e,0x13,0x17,0x1c,0x49,0x2f,0x1a,0x29,0x13,0x1d,0x17,0x1c,0x12,0x0a,0x0f,0x1d,0x29,0x11,0xc4,0xbc,0x9c,0x98,0x9b,0x8f,0x8c +,0x85,0x84,0x89,0x88,0x88,0x88,0x89,0x89,0x97,0x95,0x93,0x9a,0xa8,0xad,0xe0,0x46,0x3a,0x2d,0x4e,0x15,0x1e,0x19,0x2b,0x1e,0x20,0x26,0x0c,0x0c,0x0d,0x0a,0x09,0x1c +,0x0e,0x09,0x1b,0x14,0x16,0x23,0x1d,0x25,0x34,0x3e,0x24,0x2b,0x1a,0x12,0x0d,0x15,0x2f,0x14,0x0f,0x0c,0x1d,0x1f,0x1c,0x2e,0xa4,0x8f,0x9d,0x9d,0x99,0x9d,0x8e,0x8e +,0x9d,0x8f,0x9f,0x9c,0x98,0xba,0xe8,0x34,0xc4,0x9c,0xbb,0x47,0x1f,0x1b,0x40,0x21,0x4c,0xb0,0x2b,0xb9,0x2f,0x36,0x94,0x9b,0x9e,0x9c,0x90,0x93,0x9b,0x94,0x9e,0x89 +,0x91,0x95,0x93,0xc8,0x99,0x94,0x9c,0xc3,0xad,0xd1,0x8e,0xae,0x2a,0xa3,0x49,0xc3,0x46,0x20,0x10,0x15,0x1e,0x21,0x0f,0x18,0x32,0x26,0xa2,0x8f,0x97,0x96,0x93,0x8d +,0x8e,0xa5,0x9c,0xe0,0x1f,0xd9,0x0b,0x0a,0x0c,0x0c,0x0c,0x00,0x09,0x07,0x08,0x05,0x04,0x09,0x0b,0x0b,0x08,0x14,0x0c,0x34,0xb2,0x4f,0xaa,0x9d,0x96,0x9a,0x8c,0x96 +,0x8f,0x88,0x90,0xa5,0x90,0x8d,0x90,0x8d,0x89,0x9a,0x97,0x89,0x9e,0xa5,0xa6,0x89,0x94,0xad,0xb4,0xae,0x8a,0x1c,0x19,0x48,0x95,0x92,0x1e,0x21,0x2e,0x9b,0xb0,0x9c +,0xcc,0xc1,0xa3,0xa2,0x1d,0x0b,0x18,0x4c,0x33,0x0c,0x18,0x0d,0xcc,0x10,0x0a,0x0c,0x2b,0x94,0x2c,0x30,0x9e,0x8a,0x95,0x9a,0x89,0x87,0x89,0x8a,0x8f,0x86,0x86,0xb6 +,0xbb,0x9d,0xb4,0x3d,0x10,0x1d,0x0f,0x0f,0x08,0x03,0x0f,0x08,0x09,0x05,0x09,0x09,0x08,0x0b,0x08,0x05,0x10,0x1d,0x0d,0x0d,0x10,0x2b,0x42,0x43,0x28,0x38,0x39,0x56 +,0xb9,0x9f,0x98,0x1f,0x92,0x91,0x97,0x98,0xac,0x8b,0x89,0x8c,0x8d,0x8d,0x85,0x87,0x8e,0x8e,0x8b,0x8b,0x97,0x93,0x92,0x90,0xab,0x98,0x99,0x9d,0x77,0xb5,0xcb,0x9f +,0xa9,0x28,0x2d,0x22,0x2c,0x14,0x17,0x11,0x14,0x0a,0x0c,0x0b,0x17,0x15,0x1e,0xb6,0xbf,0x2a,0xb2,0x8e,0x8a,0x8b,0x8f,0x97,0x89,0x8e,0xee,0x93,0x94,0xbd,0x1b,0x19 +,0x25,0x12,0x0b,0x07,0x0a,0x1d,0x0f,0x0f,0x19,0x0a,0x14,0x1d,0x1b,0x21,0x24,0xa6,0x49,0xdc,0x1d,0x2a,0x29,0x23,0x40,0x18,0x30,0x37,0x1c,0x16,0x1c,0x21,0x1f,0x11 +,0x35,0x0e,0x45,0x3e,0x1d,0xa6,0x25,0xaf,0x97,0xa9,0x9d,0x8b,0x86,0x8b,0x8f,0x88,0x8a,0x85,0x91,0xa9,0x8d,0x89,0x8e,0x8f,0x8e,0x94,0xa5,0xa6,0xaa,0x99,0x99,0x2e +,0x3c,0x31,0x25,0x1f,0x37,0x17,0x08,0x09,0x19,0x52,0x25,0x19,0x32,0x9d,0xa0,0x8c,0xad,0x9f,0x88,0x8d,0x8a,0x9e,0x98,0x9e,0x27,0x6c,0x17,0x16,0x0c,0x05,0x17,0x0b +,0x08,0x08,0x0e,0x06,0x0a,0x0d,0x07,0x29,0x3c,0x29,0x64,0x1e,0xce,0xa6,0xc9,0x4d,0x9b,0x8c,0xb6,0x9d,0xba,0x9f,0x8f,0x2e,0x44,0xb5,0x8d,0xa5,0x2d,0x9f,0xd4,0x95 +,0xa0,0xa0,0x96,0xb8,0x2c,0xa7,0xa5,0xae,0x30,0xe4,0x8f,0xf0,0xb1,0xc7,0x6e,0x9d,0x2b,0x1c,0xa6,0x9f,0xd4,0x2f,0x3b,0x4d,0xa2,0x4d,0x4a,0xbb,0x15,0xae,0x17,0x21 +,0x40,0x0e,0xae,0x20,0x99,0x9b,0x99,0x8f,0xbf,0x84,0x8d,0x8a,0x87,0x8e,0x88,0x9d,0x88,0x9d,0x9b,0x8d,0xc7,0xb0,0x0f,0x14,0x1c,0x06,0x09,0x05,0x0c,0x12,0x07,0x0d +,0x04,0x08,0x07,0x07,0x33,0x1c,0x11,0x09,0x12,0x25,0x10,0xc5,0x13,0x43,0xb7,0x16,0xee,0x1b,0x91,0xa3,0x4f,0xc9,0xa0,0x8b,0xa2,0xa3,0xaa,0xb2,0x8f,0x89,0x8b,0x8e +,0x93,0x99,0x9d,0x92,0x8c,0x96,0x9f,0x8a,0x91,0x91,0xaf,0xae,0x90,0x98,0x7c,0x26,0xd8,0x33,0x36,0x0b,0x15,0x2c,0x1a,0x14,0x1c,0x2a,0x0f,0x12,0x0a,0x0c,0x1b,0x14 +,0x13,0x25,0x32,0x5b,0x29,0x9e,0x92,0x96,0x8c,0x8e,0x86,0x83,0x88,0x8e,0x9c,0x98,0x92,0xad,0x45,0x47,0x2f,0x27,0x28,0x1c,0x21,0x2c,0x51,0x31,0x17,0x2d,0x4b,0x1d +,0x2b,0x23,0x3d,0x40,0x16,0x1e,0x40,0x27,0x1f,0x1c,0x18,0x30,0x10,0x0b,0x23,0xcb,0x14,0x0c,0x23,0x39,0x17,0x1c,0x18,0x1e,0xaf,0x3c,0xb6,0xb4,0x9e,0xa4,0x99,0x8b +,0x8e,0x8e,0x96,0x95,0x91,0xa6,0xa5,0x9e,0x98,0x8c,0xb8,0xa7,0x9d,0xac,0xb5,0xb4,0xaa,0xd1,0xb6,0x30,0x1e,0x14,0x0f,0x18,0x1c,0x1f,0x0f,0x11,0x2e,0xdf,0x9c,0xca +,0x95,0x8b,0x9b,0x95,0x8a,0x8a,0x90,0x90,0x8f,0x8f,0xa4,0x9f,0xa5,0x43,0xe4,0x3c,0x19,0x16,0x33,0x1e,0x0f,0x0a,0x06,0x09,0x0c,0x13,0x0e,0x09,0x10,0x0c,0x15,0x18 +,0x1a,0x40,0x29,0x26,0x1d,0x2c,0x26,0x3d,0xa6,0x9e,0xa2,0xad,0xb3,0xbc,0x9e,0x8f,0x95,0x96,0x91,0x94,0x9d,0x5f,0x29,0x3d,0xa9,0x9f,0x46,0x1b,0x23,0x1b,0x30,0xc4 +,0x9f,0xa9,0xae,0xa7,0xb7,0xe4,0x28,0xba,0x8d,0x92,0x9a,0xd4,0x3c,0xca,0x1b,0x43,0xbe,0xab,0x1d,0x1a,0x24,0x0e,0x08,0x09,0x3a,0xa3,0xaf,0x31,0x5b,0x98,0x9e,0x8d +,0x84,0x84,0x80,0x84,0x83,0x8c,0x99,0xa6,0xa1,0x91,0xa1,0x6f,0x0f,0x07,0x07,0x0b,0x1f,0x0c,0x1c,0x17,0x11,0x0c,0x01,0x05,0x08,0x1b,0x0f,0x0e,0x0b,0x05,0x0e,0x1c +,0x2d,0x48,0xb2,0xa5,0xb7,0x31,0x21,0xcc,0x9f,0x97,0x92,0x57,0xba,0xc1,0xae,0x91,0x94,0x8c,0x91,0x8f,0x9e,0x14,0x1a,0x2e,0xa2,0x9e,0x64,0x37,0x1f,0x1e,0xad,0x8c +,0x8d,0x8d,0x95,0x8a,0x99,0x23,0x1f,0x39,0x9d,0xa9,0x2d,0x11,0x0f,0x0d,0x22,0xe5,0x36,0x4d,0xae,0xa1,0x2f,0x28,0x3a,0x9e,0x8d,0x8b,0x8a,0x8d,0x91,0x8d,0x81,0x82 +,0x80,0x87,0x86,0x8b,0x2f,0x10,0x0b,0x1f,0x13,0x07,0x04,0x03,0x02,0x06,0x15,0x0f,0x17,0x0f,0x12,0x12,0x07,0x03,0x05,0x0f,0x0b,0x0a,0x08,0x0f,0x0d,0x33,0x8f,0x98 +,0x94,0x9a,0x8e,0x90,0x9a,0xb4,0xb2,0x97,0xa7,0xe8,0x30,0x50,0x27,0x9f,0x91,0x92,0x97,0xca,0x99,0xaa,0xbd,0x3a,0xcd,0xa4,0xaf,0x4f,0x32,0x3a,0x2e,0x8d,0x8c,0x95 +,0xa4,0x9a,0x95,0xcc,0x6e,0x2a,0xc6,0x47,0x30,0x17,0x15,0x1c,0x14,0x9d,0x92,0x97,0xaf,0xab,0x95,0x9f,0x9d,0x9a,0x91,0x8c,0x8b,0x9c,0x92,0x9f,0x9e,0x85,0x89,0x8e +,0xb4,0x3a,0x22,0x0e,0x0d,0x09,0x06,0x06,0x07,0x04,0x01,0x00,0x04,0x15,0x19,0x0c,0x0b,0x0f,0x15,0x1a,0x13,0x18,0x1d,0x18,0x17,0x2d,0x1d,0x10,0xbf,0x8f,0x8e,0x98 +,0x9f,0x9a,0x94,0x94,0xb3,0xb5,0x9c,0x9c,0xa5,0xc6,0x3f,0x17,0xae,0x89,0x8a,0x98,0xa2,0x8f,0x95,0x99,0x94,0x97,0x93,0x92,0x97,0x96,0xb0,0x2f,0x9c,0x85,0x9c,0x31 +,0x56,0x9f,0xb5,0x18,0x14,0x19,0x1c,0x0c,0x0d,0x12,0x0d,0x10,0xcd,0x89,0x93,0xaa,0x8e,0x85,0x88,0x8a,0x89,0x86,0x86,0x8d,0x90,0x95,0xaf,0x2c,0xee,0xa3,0xdc,0x11 +,0x11,0x1e,0x09,0x04,0x19,0x19,0x00,0x06,0xe1,0x0d,0x19,0x0c,0x14,0xec,0x09,0x06,0x12,0xa1,0x06,0x05,0x03,0x00,0x08,0x00,0x03,0x00,0x01,0x00,0x11,0xaa,0x13,0x0a +,0x0d,0x26,0x1c,0x0e,0xc0,0x98,0x8f,0xa4,0x94,0x8a,0x81,0x81,0x8a,0x82,0x80,0x81,0x80,0x81,0x80,0x84,0x88,0x85,0x80,0x84,0x87,0x81,0x8e,0x96,0x92,0x83,0x85,0x8d +,0x99,0x90,0x85,0x9d,0xa7,0x3f,0xa3,0x29,0x21,0x1c,0x05,0x08,0x01,0x28,0x52,0x0b,0x05,0x05,0x06,0x06,0x04,0x03,0x03,0x0a,0x03,0x00,0x00,0x01,0x00,0x06,0x0f,0x03 +,0x03,0x01,0x13,0x0c,0x02,0x05,0x09,0x0e,0x05,0x08,0x0e,0x15,0x0f,0x0c,0x8d,0x97,0x9f,0xab,0xaf,0x8b,0xe2,0x96,0x8c,0x81,0x83,0x86,0x83,0x82,0x80,0x84,0x82,0x80 +,0x80,0x82,0x84,0x80,0x84,0x88,0x81,0x81,0x80,0x83,0x83,0x85,0x83,0x8d,0x98,0x81,0x83,0x87,0x87,0x89,0x83,0x8d,0x93,0x8f,0x82,0x83,0x93,0x8a,0x95,0xaf,0x1d,0x32 +,0x98,0x42,0x57,0x0f,0xb3,0x45,0x08,0x0b,0x02,0x1d,0x07,0x02,0x03,0x00,0x02,0x00,0x0a,0x09,0x00,0x02,0x00,0x11,0x0b,0x00,0x04,0x00,0x0c,0x05,0x06,0x03,0x03,0x04 +,0x00,0x18,0x09,0x0b,0x09,0x05,0x0e,0x05,0x01,0x06,0x08,0x11,0x0e,0x10,0x0d,0x0c,0x04,0x09,0x96,0xa4,0x9b,0x34,0xad,0x8d,0xe6,0x9f,0x60,0x8c,0x88,0x8d,0x87,0x92 +,0x86,0x94,0x8d,0x80,0x84,0x84,0x8c,0x86,0x84,0x8d,0x8b,0x8b,0x80,0x82,0x86,0x80,0x84,0x80,0x8c,0x8c,0x80,0x82,0x83,0x87,0x86,0x80,0x87,0x85,0x8b,0x81,0x88,0xa0 +,0x9b,0x41,0x99,0x1a,0x2f,0x8e,0x95,0x9b,0x14,0xaf,0x3e,0x19,0x5a,0x1e,0xb0,0x49,0x0f,0x2a,0x27,0xbc,0x10,0x26,0x86,0x93,0x99,0x1b,0x9c,0x90,0x2d,0xb5,0x28,0x8e +,0x8a,0xb5,0x98,0x8a,0x85,0x9f,0xa0,0x84,0x87,0x8b,0x9a,0x93,0x89,0x1e,0x68,0x2c,0xba,0xa4,0x07,0x1a,0x0d,0x0e,0x06,0x00,0x16,0x09,0x01,0x00,0x05,0x09,0x00,0x01 +,0x00,0x09,0x08,0x02,0x00,0x05,0x08,0x02,0x00,0x0e,0x14,0x02,0x03,0x00,0x0c,0x02,0x01,0x03,0x08,0x0c,0x02,0x02,0x02,0x04,0x02,0x00,0x19,0x0b,0x0c,0x05,0x07,0x60 +,0x07,0x03,0x0e,0xf3,0x99,0x25,0x3e,0x93,0x8f,0x8f,0x64,0x88,0x80,0x83,0x8a,0x8b,0x80,0x8a,0x89,0x86,0x88,0x80,0x8d,0x81,0x82,0x83,0x80,0x95,0x84,0x80,0x83,0x8b +,0x87,0x80,0x85,0x91,0x84,0x80,0x81,0x83,0x88,0x80,0x85,0x88,0xa7,0x89,0x80,0x84,0x8f,0x9d,0x80,0x9a,0x41,0x9c,0x8e,0x80,0x8d,0x8a,0x84,0x93,0xc4,0x28,0x8b,0x80 +,0x90,0xa2,0x97,0x80,0x9f,0x05,0x14,0x96,0xbe,0x12,0x0b,0x4f,0x08,0x00,0x00,0x06,0x26,0x00,0x01,0x00,0x13,0x08,0x00,0x00,0x02,0x04,0x00,0x01,0x06,0x04,0x00,0x02 +,0x00,0x26,0x09,0x00,0x05,0x0d,0x13,0x00,0x0a,0x0d,0x18,0x09,0x04,0xb9,0x2c,0x03,0x06,0x24,0x80,0x8c,0x25,0xa6,0x8f,0x80,0x18,0x31,0x82,0x82,0x87,0x97,0x82,0x84 +,0x25,0x12,0x28,0x85,0x82,0x9d,0x8f,0x95,0x85,0x13,0x0b,0x8c,0x91,0x98,0x94,0x88,0x81,0x4f,0x07,0x49,0x8f,0x80,0x9c,0x9b,0x88,0x97,0x50,0x03,0xc8,0x99,0x41,0xb7 +,0xab,0x92,0x1f,0x00,0x04,0x0f,0x8c,0x28,0x0b,0x1c,0x16,0x1f,0x04,0x09,0x1c,0x0d,0x18,0xb2,0xa7,0x6b,0x03,0x0c,0x0f,0x88,0x98,0x24,0xa2,0x51,0x94,0x0c,0x1c,0xa2 +,0xae,0xc2,0x46,0xa4,0x42,0x06,0x06,0x04,0x9b,0x84,0x16,0x29,0x16,0xc3,0x1b,0x05,0x54,0xbe,0x8f,0x92,0x8a,0x90,0x2b,0x1f,0x1a,0x8f,0x82,0x91,0x8f,0x9a,0x8d,0xa8 +,0x12,0x9e,0x8d,0x87,0x85,0x83,0x82,0x8b,0x4d,0x39,0x9b,0x80,0x82,0x85,0x86,0x86,0x83,0x1d,0x30,0xbd,0x93,0x94,0x8f,0x91,0xd6,0x10,0x01,0x04,0xbf,0xfe,0x04,0x09 +,0x05,0x0d,0x00,0x06,0x07,0x09,0x0e,0x05,0x0f,0x0e,0x00,0x03,0x00,0x4e,0x8e,0x0a,0x0d,0x10,0x62,0x0d,0x03,0x1d,0x9a,0x94,0x93,0x9d,0x91,0x56,0x0e,0x17,0xa0,0x80 +,0x91,0x87,0x94,0x8a,0x9a,0x10,0x9d,0x8b,0x80,0x88,0x84,0x87,0xbc,0x0e,0x0d,0x31,0x83,0x8d,0xa9,0xa3,0xcd,0x9a,0x01,0x09,0x29,0xbc,0x96,0x1f,0x9e,0x9a,0x11,0x14 +,0x01,0x9f,0x8b,0x49,0xa4,0xc3,0x97,0x1a,0x03,0x24,0x9f,0xa0,0xaf,0x14,0x44,0x05,0x04,0x00,0x15,0x8e,0x09,0x16,0x07,0x1a,0x11,0x00,0x0f,0xaf,0x8c,0xf1,0x15,0xb6 +,0x58,0x0e,0x1d,0x27,0x80,0x90,0xa5,0x9e,0xa7,0x8b,0x08,0x2d,0x8c,0x85,0x85,0x48,0xbf,0x22,0x0a,0x0f,0x0e,0x85,0x90,0x9f,0x9a,0x9c,0x9c,0x06,0x08,0x9f,0x88,0x87 +,0xaa,0x51,0x91,0x11,0x15,0x09,0x96,0x85,0xdd,0xa8,0x4a,0x8d,0x24,0x07,0x76,0x8b,0x84,0x8f,0x7c,0xae,0xb3,0xd7,0xb0,0x95,0x80,0x8d,0x8a,0x8e,0x89,0x9a,0x0c,0xa1 +,0x88,0x84,0x8d,0x1b,0xcc,0x16,0x05,0x05,0x06,0x8c,0x1e,0x04,0x07,0x0c,0x0c,0x00,0x05,0x0e,0x9d,0xbd,0x04,0x02,0x08,0x00,0x09,0x00,0x9b,0x9c,0x16,0x1b,0x0a,0x23 +,0x00,0x09,0xa9,0x8c,0x89,0xae,0x30,0x9e,0x29,0x40,0xc3,0x88,0x80,0x95,0x8d,0x8e,0x81,0x99,0x38,0x8d,0x80,0x80,0x8d,0x40,0xac,0x42,0xae,0xb8,0x99,0x80,0x95,0x8d +,0xb7,0xac,0x30,0x0a,0x38,0x96,0x8a,0x9d,0x12,0x17,0x10,0x0a,0x12,0x1f,0x81,0x96,0x9b,0x2b,0x3f,0xab,0x02,0x15,0xbc,0x8b,0x92,0x0e,0x06,0x0a,0x0b,0x0f,0x05,0xa1 +,0xc6,0x15,0x10,0x04,0x0e,0x00,0x06,0x19,0xba,0x99,0x16,0x0b,0x1a,0x17,0x31,0x13,0x88,0x8a,0xa3,0xac,0x18,0x92,0x1c,0x16,0x96,0x87,0x82,0x9a,0x0e,0x1c,0x1c,0xb5 +,0x28,0x9b,0x83,0xa7,0x9d,0x0d,0x24,0x1b,0x09,0x97,0x85,0x84,0x8d,0x2a,0x2e,0x19,0x34,0x1b,0x99,0x81,0x8e,0x8c,0x25,0xa9,0x26,0x05,0x1d,0x96,0x85,0x8d,0x15,0x18 +,0x1f,0xb7,0xa9,0x56,0x80,0x89,0x80,0x93,0xa4,0x97,0x1b,0x98,0x89,0x85,0x82,0xb0,0x2e,0x23,0x1e,0x23,0x17,0x90,0x3f,0x1a,0x08,0x00,0x07,0x00,0x03,0x0a,0x27,0x22 +,0x05,0x00,0x02,0x03,0x0e,0x04,0x9c,0xb4,0x3c,0x1d,0x03,0x18,0x03,0x0f,0xb9,0x8b,0x80,0x96,0x20,0x25,0x13,0xa7,0x2b,0x8b,0x80,0x8b,0x87,0x26,0x9a,0x4f,0x1d,0x94 +,0x87,0x80,0x84,0xb6,0xae,0x32,0x9f,0xa0,0x8e,0x80,0x8b,0x89,0x34,0x9e,0xae,0x26,0xa8,0x89,0x81,0x8d,0x0f,0x0d,0x0b,0x1e,0x20,0x1f,0x86,0x39,0xb2,0x0d,0x16,0xbd +,0x18,0xac,0x99,0x8b,0x94,0x08,0x07,0x06,0x0a,0x24,0x1a,0x86,0xaa,0x2c,0x0e,0x00,0x09,0x00,0x09,0x28,0xa6,0x8e,0x0e,0x02,0x06,0x03,0x13,0x08,0x89,0x88,0x89,0x9d +,0x11,0xba,0x14,0x26,0x96,0x8a,0x82,0x9c,0x2a,0x4b,0x1a,0xa2,0x27,0x8c,0x85,0x99,0x94,0x09,0x47,0x13,0x0e,0xb5,0xb6,0x89,0xb6,0x0e,0xb8,0x18,0xac,0x2a,0xb4,0x82 +,0xa2,0x9e,0x0f,0x2a,0xa9,0xad,0x8c,0x8a,0x86,0x89,0x1d,0xb4,0x49,0x9c,0x91,0x91,0x80,0x8e,0x87,0x1a,0x28,0xac,0x26,0x96,0x8a,0x84,0x83,0x2f,0x1a,0x10,0x0c,0x18 +,0x07,0x8c,0x98,0xdf,0x15,0x00,0x0c,0x00,0x0b,0x16,0x21,0x37,0x06,0x01,0x04,0x00,0x07,0x00,0xb9,0x9d,0x18,0x17,0x00,0x0d,0x05,0x0f,0xc2,0x9f,0x8a,0x32,0x0f,0x2b +,0x1e,0x9f,0xbb,0x8e,0x82,0x8d,0x8c,0x28,0xa2,0xbb,0x9f,0x84,0x87,0x81,0x90,0x2c,0xa4,0x36,0xad,0x9f,0xa1,0x80,0x8e,0x8d,0x15,0x0e,0x3f,0x35,0x89,0x88,0x83,0x8a +,0xa9,0xae,0x39,0x25,0x3d,0x47,0x88,0x92,0xae,0x1a,0x09,0x17,0x0b,0xce,0xa2,0xa7,0x97,0x0f,0x0e,0x10,0x05,0x19,0x08,0x9e,0x8f,0x25,0x1a,0x00,0x07,0x06,0x0c,0x21 +,0xee,0x5e,0x62,0x0e,0x13,0x03,0x0a,0x0e,0x1b,0x8b,0x5a,0xa8,0x0c,0x1c,0x1b,0x1b,0x99,0xac,0x8d,0xa6,0x2c,0x35,0x1e,0xcb,0xac,0xa4,0x83,0x8e,0x95,0x27,0x0e,0x5b +,0x27,0x95,0x95,0x8b,0x8a,0xd8,0x9e,0x31,0x6b,0xa4,0x3a,0x87,0x89,0x92,0xac,0x0f,0xbe,0xbc,0xaa,0x97,0x8e,0x88,0x99,0x33,0xf4,0x1d,0xa3,0xb8,0x8d,0x81,0x97,0x96 +,0x06,0x23,0x12,0xe6,0x97,0x8f,0x82,0xa5,0x2f,0x1d,0x0b,0x1d,0x14,0x18,0x82,0xb9,0xdc,0x0b,0x08,0x25,0x0f,0x26,0x21,0x2e,0x50,0x0d,0x14,0x06,0x0a,0x15,0x11,0x8a +,0xa7,0x38,0x0e,0x07,0x0d,0x12,0x1b,0x3d,0x94,0x92,0x9d,0xa3,0xbc,0x29,0xaa,0x1c,0x8a,0x8c,0x9c,0xa2,0x0d,0x9b,0xc5,0x9c,0x4f,0xaa,0x99,0x36,0x38,0x11,0x0f,0x46 +,0x22,0x9e,0x86,0x2d,0xfd,0x02,0x0f,0x21,0xf0,0x92,0x8e,0x81,0x91,0xa2,0x29,0x0e,0x64,0x1f,0xa8,0x80,0x91,0x97,0x18,0x1e,0x9f,0x98,0xa5,0x8e,0x8f,0x8f,0x4b,0x1c +,0x14,0x14,0x3d,0x15,0x82,0x96,0xa0,0x27,0x09,0xbb,0x1e,0x2d,0x2e,0xa2,0x9c,0x41,0x29,0x11,0x0f,0x19,0x0a,0x8f,0x8b,0x5d,0xa2,0x09,0x7e,0x26,0x0e,0x24,0x30,0xca +,0x1c,0x10,0x11,0x0d,0x1f,0x0d,0xfd,0x89,0x1e,0x42,0x06,0x0b,0x19,0x0e,0x36,0xc5,0x9d,0x9f,0xc4,0x21,0x18,0x2d,0x1e,0xc1,0x83,0xa6,0x9d,0x25,0x16,0x9f,0x3d,0x95 +,0x8e,0x8d,0x8f,0x7a,0x2c,0x0f,0x2b,0x52,0x21,0x81,0x96,0x97,0xb5,0x09,0x9e,0x28,0xbd,0x8e,0x8f,0x84,0x8d,0xb6,0x5a,0x24,0xb3,0x4b,0x8f,0x83,0x8c,0x82,0x28,0xa2 +,0xcf,0x1b,0xb7,0xae,0xa0,0xb5,0x17,0x0c,0x0d,0x0e,0x0d,0x21,0x93,0x2b,0xc1,0x04,0x0b,0x18,0x07,0x2e,0x28,0xa4,0x9e,0x2c,0x1d,0x16,0x2d,0x1e,0x21,0x89,0xb9,0x9e +,0x1e,0x0c,0x2e,0x0f,0x25,0x3a,0x63,0xa5,0x46,0x0f,0x0f,0x0e,0x21,0x16,0x97,0xa3,0x3e,0x3f,0x04,0xb7,0x21,0xa8,0x8b,0x8b,0x83,0x8b,0xa1,0x2d,0x60,0xc9,0xa8,0x90 +,0x82,0x8c,0x85,0xc2,0x9d,0x97,0x40,0x90,0xa2,0x8f,0x8e,0x3d,0x24,0x0f,0x1a,0x1b,0x33,0x85,0x96,0x8e,0x15,0x0f,0x1b,0x0c,0x24,0x3a,0x9c,0x8f,0xc7,0x18,0x17,0x1a +,0x55,0x1c,0x88,0x9d,0x94,0x3b,0x09,0x33,0x08,0x1f,0x21,0xc9,0x9a,0xba,0x18,0x15,0x0d,0x0e,0x0a,0xbf,0x99,0x28,0x27,0x03,0x18,0x0b,0x15,0xcf,0x9f,0x86,0x99,0x63 +,0x25,0x1a,0x27,0x17,0xae,0x89,0xa2,0x93,0x1c,0xaa,0xaf,0x41,0x9f,0x9c,0x92,0x95,0x29,0x21,0x18,0x19,0x28,0x19,0x84,0xce,0x8e,0x21,0x32,0xae,0x19,0x9e,0xa5,0x87 +,0x8b,0xa0,0xd3,0xc9,0xd2,0x9f,0xc9,0x81,0x8d,0x8d,0xa1,0x1e,0x9a,0x11,0x49,0xbc,0xc6,0x95,0x19,0x14,0x0b,0x0c,0x1d,0x0a,0x99,0xa4,0xb7,0x1f,0x09,0x1c,0x08,0x1c +,0x2b,0x9a,0x8a,0xa2,0xce,0x4a,0x1a,0x45,0x0b,0x9b,0x8e,0xb5,0x9a,0x07,0x48,0x0f,0x1a,0x3d,0x4c,0x8f,0xb3,0x23,0x19,0x0a,0x13,0x08,0x2b,0x96,0xd9,0xd2,0x0e,0x35 +,0x2c,0x2c,0xce,0xa2,0x8a,0x92,0xac,0x9d,0x20,0xac,0x23,0x97,0x82,0x9c,0x89,0x1f,0x9d,0xa7,0xaf,0x98,0xb0,0x8e,0x9f,0x1c,0x25,0x0f,0x1d,0x2c,0x42,0x81,0x9b,0x95 +,0x22,0x20,0xba,0x17,0xb8,0x37,0x93,0x93,0xb8,0xc0,0x1a,0x1f,0x39,0x43,0x84,0x9a,0x91,0x33,0x1d,0x62,0x0e,0x5b,0x19,0x9b,0x91,0x7a,0x26,0x0e,0x07,0x16,0x05,0x94 +,0xc2,0x2e,0x33,0x05,0x45,0x04,0x19,0x18,0xc8,0x8e,0x9c,0xb9,0x58,0x1f,0xbd,0x20,0x97,0x8b,0xa4,0x9a,0x10,0x9c,0x32,0xaf,0xa8,0xcc,0x89,0x9f,0x3d,0x1c,0x0b,0x1f +,0x0e,0x45,0x8d,0x53,0x9d,0x0e,0x42,0x25,0x1b,0xb4,0x2f,0x8f,0x93,0xcf,0xc1,0x16,0x29,0x5e,0x4c,0x80,0x94,0x8b,0x2d,0x2f,0xad,0x29,0xa5,0x2d,0x9a,0x9a,0xf5,0x1c +,0x0f,0x0a,0x14,0x09,0x96,0x9c,0x9f,0x75,0x0c,0x3d,0x0c,0x28,0x14,0x32,0x92,0x99,0x9b,0xbd,0x1e,0xb4,0x1e,0x97,0x8b,0x95,0x96,0x11,0x6f,0x1e,0x3a,0x2d,0x3c,0x94 +,0xa2,0x5f,0x32,0x0c,0x21,0x0c,0x1f,0x8e,0x28,0xa2,0x0a,0x1a,0x23,0x28,0xa7,0x2e,0x94,0x98,0xa0,0xd9,0x2d,0x4a,0x41,0x20,0x87,0x96,0x8e,0x4f,0x21,0x9e,0x27,0x97 +,0xee,0x8c,0x95,0xbb,0x38,0x0c,0x0d,0x0e,0x07,0x96,0xaa,0x95,0xa9,0x12,0x4b,0x15,0xcf,0x25,0xcf,0x9b,0xa5,0x3e,0x3f,0x28,0xac,0x15,0x8d,0x88,0x90,0x8c,0x25,0x9a +,0x44,0xd0,0xda,0xbc,0xa2,0xa3,0xad,0x27,0x1e,0x23,0x15,0x43,0x98,0xb1,0x98,0x10,0x16,0x1f,0x0f,0x3b,0x1e,0x9e,0x9c,0xbf,0x35,0x5f,0xbb,0x36,0x54,0x89,0x9f,0x98 +,0x1d,0x1b,0x35,0x13,0xc5,0x33,0x9f,0x9b,0xa7,0x20,0x1a,0x15,0x1f,0x0a,0xa9,0xcd,0xa1,0x2f,0x09,0xae,0x15,0x51,0x5f,0xa2,0x8c,0x98,0xc4,0xbe,0x32,0x3c,0x1e,0x93 +,0x8e,0x96,0x9e,0x15,0xa2,0x33,0xbb,0x9e,0xd4,0x98,0xa3,0x1f,0x24,0x12,0x16,0x0b,0x25,0x9f,0xad,0xa6,0x0b,0xa7,0x3b,0xe0,0xbe,0x2f,0x9b,0xad,0x4d,0x2d,0x25,0x1d +,0x2d,0xb9,0x88,0x9a,0x8b,0x1c,0xc3,0xce,0x21,0x96,0x17,0xa3,0xb7,0x28,0x26,0x15,0x16,0x14,0x13,0x9e,0x9b,0x96,0x22,0x17,0x3f,0x13,0xd2,0x21,0x34,0xa9,0x27,0xba +,0xae,0x51,0xaf,0x28,0x93,0x8f,0x87,0xb5,0x1b,0x3c,0x13,0x94,0x32,0xb1,0x9a,0x3b,0x2f,0x3d,0x20,0x44,0x18,0x2c,0x91,0xad,0xa4,0x0b,0x2f,0x12,0x5e,0xc3,0x29,0x8c +,0x6c,0xa0,0xa5,0xed,0xa5,0xc5,0x2e,0x8c,0x96,0x96,0x3b,0x26,0x61,0xb2,0xad,0x27,0x97,0xaf,0x36,0x47,0x17,0x25,0x12,0x06,0xa0,0x4e,0x9e,0x26,0x20,0xca,0xc6,0xa2 +,0x21,0x9a,0xd8,0x45,0x3f,0x1d,0x42,0xc3,0x14,0x8f,0x8e,0x91,0x98,0x15,0xb2,0x31,0xa3,0x1f,0xd0,0xac,0x16,0x3a,0x0c,0x1a,0x17,0x03,0xbf,0x9e,0xaf,0xae,0x11,0x27 +,0x39,0xab,0x48,0xac,0x9d,0xcf,0x98,0x5f,0xb2,0x95,0x13,0x91,0x87,0x91,0x8a,0x10,0x4a,0x1a,0x54,0x1f,0x2e,0x9f,0x2f,0x9e,0x25,0x28,0xbe,0x09,0x27,0x8f,0x34,0x92 +,0x1b,0x29,0xcb,0x2f,0xac,0xe7,0x96,0xc0,0xa3,0x6e,0x23,0x99,0x11,0x38,0x8b,0xae,0x94,0x0f,0x17,0x1b,0x21,0xef,0x35,0x9d,0x50,0x40,0x29,0x0e,0x2c,0x0d,0x0b,0x8e +,0x3f,0x8c,0x2f,0x1c,0xa3,0x61,0x8e,0xab,0x91,0x9d,0xa7,0xb9,0x1a,0xb1,0x1c,0x11,0x8a,0xab,0x98,0x29,0x0c,0x2f,0x1a,0x58,0x4c,0xc6,0xae,0xbc,0xcd,0x27,0x74,0x2a +,0x0a,0x8f,0xa7,0x98,0xbf,0x16,0xad,0x3f,0xaa,0xb8,0x9e,0xa9,0x69,0xd1,0x1f,0x43,0x2f,0x0e,0x8f,0x9b,0x93,0xaf,0x18,0xcc,0x21,0x4e,0xe4,0xc2,0x9c,0xbf,0xb3,0x1d +,0x2f,0x44,0x0a,0x93,0xab,0x97,0xa9,0x1e,0xd0,0x22,0xd8,0x38,0xe7,0xbe,0x2d,0x2a,0x16,0x1e,0x38,0x13,0x98,0x8f,0x93,0x90,0x3e,0xae,0x2d,0x4f,0xcd,0xdc,0xb0,0x4f +,0xc3,0x1e,0x2b,0x38,0x0a,0x73,0xb6,0xcb,0xa0,0x1d,0x43,0x24,0x31,0x24,0x3a,0x4e,0x39,0xae,0xc1,0x32,0xba,0x1d,0x9b,0x8a,0xa0,0x8e,0x34,0xab,0x2f,0x3d,0x2b,0x31 +,0xaa,0xc1,0x9e,0x46,0x27,0x42,0x10,0x2e,0x9b,0x44,0xae,0x1e,0x26,0x2e,0xcf,0x66,0xb1,0xa8,0xa6,0x9e,0x56,0x2c,0x4a,0x16,0x48,0x8d,0xbb,0x96,0x46,0xb0,0x1f,0x38 +,0x49,0x35,0xa2,0x35,0x98,0x50,0x18,0x24,0x0e,0x0d,0xa4,0x2e,0xa2,0x2c,0x2f,0xe3,0x3b,0x9c,0xa7,0x98,0xd0,0x99,0x9b,0x46,0x34,0x15,0x1c,0x97,0xae,0x9a,0x5c,0x32 +,0x74,0x65,0x54,0x24,0xb4,0x1e,0xa1,0xae,0x1e,0xdf,0x1f,0x0d,0xac,0xba,0xaf,0xda,0x19,0xc9,0x75,0xc7,0x1c,0xad,0xcb,0x9d,0x96,0x24,0x61,0x18,0x1b,0x98,0x97,0x9f +,0x9d,0xae,0xd3,0xdf,0x2a,0x1b,0xc0,0x51,0xb0,0xa1,0x29,0x2c,0x3c,0x0f,0xc9,0xa6,0xc4,0xa2,0x30,0xb9,0x44,0xbf,0xdf,0x9e,0xbb,0xba,0x96,0x26,0x2b,0x14,0x18,0x28 +,0xad,0x33,0x9c,0xdf,0x31,0xad,0x2c,0x9a,0xbd,0x9c,0xd2,0x94,0x42,0x29,0x46,0x12,0x1f,0x30,0x59,0xb5,0xb7,0x16,0xc9,0x2e,0x45,0xb0,0x46,0x9b,0x92,0xa0,0xb1,0x67 +,0x15,0x1a,0xba,0x2b,0xaa,0x9a,0xb5,0xd9,0x28,0x24,0x24,0x60,0x2c,0xaf,0x9d,0x9e,0x9c,0x50,0x1a,0x1c,0x1e,0xb8,0x96,0x46,0xc6,0x1c,0x50,0x9e,0xad,0xb4,0xb2,0x9b +,0x2c,0x1f,0x0f,0x1e,0x17,0x0b,0x2b,0x87,0x85,0x3c,0x19,0x38,0x9e,0x5e,0x17,0x2a,0x43,0x9b,0x8d,0xb1,0x19,0x13,0x19,0x29,0x94,0x97,0xc6,0x1e,0xa8,0x8c,0x99,0x9d +,0x45,0xaa,0x2a,0xbe,0xa9,0x1c,0x11,0x06,0x32,0x93,0x9b,0x1d,0x0d,0x14,0xc7,0x3a,0x15,0x0f,0x25,0x94,0x8a,0x88,0xa3,0xe8,0xf9,0x6d,0xa3,0x93,0xad,0x20,0x0d,0x23 +,0xa5,0x96,0x99,0x7e,0xb1,0x98,0xa0,0x15,0x11,0x13,0x1a,0x9f,0x8e,0xb8,0x23,0x78,0x9e,0xb4,0xaa,0xb3,0x25,0x0b,0x0e,0x6d,0x36,0x30,0x1d,0x16,0xcf,0x8d,0x8c,0x9f +,0x1a,0x9f,0x85,0x8b,0xa2,0x34,0xc0,0xa8,0x98,0x24,0x06,0x04,0x06,0x1c,0x98,0x8e,0x95,0xcb,0xac,0xbe,0x2a,0x45,0x1e,0x0c,0x10,0xe9,0xa4,0x2b,0x1b,0x1c,0x2e,0x95 +,0x93,0xda,0x0f,0x0d,0xae,0x8b,0x88,0x99,0x99,0x8f,0x8f,0x8f,0x3d,0x18,0x0b,0x1d,0xb5,0x9c,0x4f,0x16,0x14,0x1c,0x1f,0x19,0x29,0x1d,0x12,0x31,0x92,0x9f,0xd0,0xc5 +,0xa1,0x92,0x91,0xa5,0x1d,0x28,0x95,0x8f,0x8e,0x93,0x98,0xb6,0x4a,0x3f,0x2e,0x1a,0x08,0x04,0x12,0xad,0xae,0xaf,0xaa,0xb7,0x30,0x28,0x4b,0x29,0x1a,0x1c,0xb6,0x9b +,0xd5,0x1a,0x18,0xb2,0x99,0x93,0xa0,0xaf,0x62,0x9b,0x90,0x96,0x91,0xac,0x39,0x1e,0x2b,0x7d,0xbf,0x38,0x2e,0x2e,0x3b,0x16,0x0a,0x11,0x1d,0x22,0x1f,0x3b,0x48,0x5f +,0x98,0x8d,0x97,0xde,0x28,0x32,0xa0,0x9b,0x9c,0x92,0x8f,0x9e,0x37,0x21,0x1f,0x3b,0x30,0x3a,0xeb,0x5e,0x2f,0x17,0x0e,0x41,0x9c,0xad,0x1c,0x13,0x2d,0xab,0xae,0xbc +,0x9a,0xa2,0x43,0x2e,0x45,0x32,0x21,0x19,0x3d,0xa2,0x9d,0xa2,0x97,0x8f,0x95,0x93,0x9a,0xa5,0x2f,0x1b,0x27,0x1c,0x26,0x27,0x13,0x0e,0x2a,0xa1,0xc3,0x24,0x29,0x5d +,0x2f,0x37,0xe8,0xae,0xb1,0xb5,0xa6,0x9b,0xbf,0x1c,0x1a,0x71,0xac,0xa3,0x9f,0xb9,0xda,0x44,0xaf,0x9f,0xaf,0x3f,0xee,0xaf,0xa3,0x4d,0x2b,0x26,0xc0,0xa1,0xaf,0x2e +,0x1c,0x1f,0x1a,0x17,0x1b,0xcb,0xab,0x45,0xbf,0xad,0xae,0xc4,0x1f,0x3e,0xa3,0xa1,0xa6,0xa9,0xad,0x96,0x90,0x8e,0xb3,0xc2,0x47,0x21,0x2d,0x11,0x14,0x16,0x1c,0x2a +,0x43,0x2f,0x41,0x42,0xab,0x65,0x27,0x28,0x28,0xba,0x74,0xab,0xab,0x5b,0x20,0x14,0x28,0x9f,0x92,0x91,0x9a,0x9b,0x9c,0x9f,0x96,0xa4,0xb5,0xba,0x46,0x22,0x1d,0x1b +,0x1f,0x42,0xaa,0xc2,0x29,0x13,0x0c,0x14,0x17,0x34,0x42,0xa4,0xcc,0x6a,0xa2,0xa0,0x9f,0xc0,0xcb,0x9b,0x94,0xab,0x75,0xb4,0x96,0xbe,0x2e,0x2a,0x26,0x2e,0x40,0x35 +,0x47,0x20,0x1d,0x33,0xe1,0xa6,0xa6,0xad,0x47,0x25,0x2b,0x3b,0x4c,0xcf,0xe8,0xae,0xbe,0x49,0x25,0x17,0x1b,0xc8,0x99,0x9b,0x9d,0x94,0x99,0x95,0xac,0xc0,0xb3,0xab +,0xc4,0x2d,0x26,0x18,0x19,0x1c,0x2f,0x38,0xb2,0x54,0x3a,0xd9,0xb0,0xcc,0xb8,0xce,0xd5,0xae,0xa7,0xe4,0x2b,0x25,0x1e,0x5c,0xae,0x9c,0x69,0x46,0xdb,0xdd,0xb2,0x3b +,0x51,0xba,0xb1,0xa4,0xab,0xaa,0x3e,0x28,0x2e,0xda,0x9f,0xa5,0x3f,0x28,0x3b,0x2a,0x1c,0x17,0x15,0x28,0xc1,0xb9,0xed,0x37,0x26,0x37,0xbb,0xa4,0x99,0x9d,0x9c,0xb5 +,0xb2,0xa6,0xaf,0x9c,0x9e,0xa9,0xa7,0x3b,0x1c,0x0b,0x0b,0x1c,0xd8,0xb1,0x32,0x3b,0x3e,0xc0,0xa6,0xd8,0x2e,0x2e,0x2b,0x4e,0x44,0x4e,0x27,0x1b,0x1e,0x40,0xa9,0xa0 +,0x4f,0xba,0x98,0x90,0x8d,0x9a,0xa8,0xad,0x9a,0xab,0x5d,0x25,0x17,0x18,0x39,0xaf,0xaf,0x60,0x29,0x1e,0x1a,0x14,0x12,0x1f,0x2d,0xc6,0xbb,0xba,0xb3,0xdf,0xcb,0x99 +,0x8f,0x8f,0x9d,0x3f,0x3f,0xa1,0xa0,0xb8,0x39,0x2b,0x2a,0x4b,0x60,0x19,0x19,0x1c,0x4a,0xaf,0xae,0xc8,0xdf,0xb0,0x33,0x28,0x3b,0x3a,0x2e,0x53,0xdf,0xa8,0xab,0x25 +,0x1a,0x21,0xac,0xaa,0xa6,0xad,0xc4,0x92,0x95,0x96,0x9f,0xac,0x9d,0xab,0x4c,0x1a,0x17,0x14,0x13,0x24,0x20,0x28,0x48,0x32,0x3a,0x4f,0x5a,0xd1,0xe0,0xb8,0xa8,0x9e +,0xbc,0x29,0x24,0x27,0xaf,0xa3,0xa5,0xad,0xdf,0xf5,0xdb,0x3d,0xf0,0x5e,0x52,0xaf,0x75,0x48,0x3d,0x26,0x27,0xbe,0x99,0x98,0x9f,0xbe,0x28,0x32,0x28,0x36,0x21,0x14 +,0x25,0x24,0x46,0x3b,0x24,0x36,0xaf,0xa0,0xa1,0xa3,0xa3,0x9c,0x9a,0xad,0xbd,0xa3,0xae,0xa4,0xa7,0xbd,0x3f,0x1b,0x18,0x1e,0x3a,0xc6,0xf8,0x2e,0x2a,0x37,0x61,0x36 +,0x3c,0x2d,0x4e,0xb4,0x45,0x41,0x2d,0x23,0x35,0x4f,0x65,0xbd,0xad,0xa7,0xbb,0xa2,0x96,0x98,0x9a,0x9d,0xa8,0xab,0xdd,0x23,0x18,0x1c,0x3d,0x69,0xbd,0x3e,0x30,0x2e +,0x1f,0x1b,0x10,0x1a,0x2f,0xe1,0xb9,0x3d,0xc9,0xa7,0xb8,0xa3,0x9c,0x9d,0x92,0x99,0x92,0x9d,0x9f,0x9f,0xca,0x2f,0x29,0x24,0x1b,0x17,0x14,0x1a,0x2f,0xab,0xbd,0xaf +,0x36,0x2f,0x2f,0x28,0x26,0x28,0xd2,0xb4,0xa7,0xa3,0xb1,0xb2,0x3f,0x2a,0x2d,0x2a,0xe9,0xd9,0xa2,0x96,0x9b,0x98,0x98,0xa9,0xa4,0xbc,0x3c,0x1f,0x20,0x1e,0x19,0x35 +,0x1f,0x38,0x38,0x1e,0x29,0x19,0x26,0x2b,0xc8,0x98,0x9c,0x9b,0x99,0xb7,0x3b,0x1f,0x21,0xcc,0x42,0xb7,0xb2,0xa7,0xa2,0xa5,0x9f,0x5c,0x2b,0x21,0x1b,0x27,0x26,0x37 +,0xc5,0xae,0xa0,0x9f,0xa3,0xa6,0xbb,0x3a,0x20,0x21,0x27,0x1b,0x2f,0x35,0x67,0x57,0x2c,0x27,0x2a,0xcb,0xad,0xac,0x9e,0x9e,0x96,0x9a,0xa2,0xa8,0xcc,0x3c,0x45,0xdf +,0x23,0x27,0x1f,0xdd,0xb6,0xaf,0xb0,0x3c,0x2b,0x21,0x30,0x25,0x37,0xd0,0xd8,0xab,0xa4,0xa4,0xaf,0x2e,0x2d,0x2e,0x27,0x49,0x2d,0xbc,0xb6,0xbd,0xa1,0xae,0x97,0xa7 +,0xae,0xb4,0x47,0xed,0x2d,0x30,0x33,0x26,0xbd,0xbc,0xc6,0x2e,0x19,0x1c,0x1b,0x26,0x23,0x31,0xc3,0xbd,0xc7,0xf4,0xf4,0xa6,0xb7,0xa9,0xa9,0xa3,0x9f,0x9b,0x90,0x99 +,0x9c,0xc4,0x2b,0x1b,0x18,0x1a,0x18,0x16,0x17,0x1f,0x3b,0xae,0xab,0xa4,0xd5,0x45,0x46,0x4b,0xac,0xc6,0xa6,0xa2,0xa9,0xaf,0xb7,0xcd,0x55,0x2b,0x33,0x4a,0xcf,0xcb +,0x35,0xa9,0xa5,0xa1,0xad,0x3e,0x37,0x1d,0x1f,0x29,0x24,0xd8,0x4b,0xcb,0xac,0xcd,0xe5,0x29,0x30,0xe8,0x4d,0xd8,0xa7,0xa0,0x9c,0xa9,0x9f,0xaf,0x44,0x2c,0x1d,0x3e +,0x29,0x2c,0x24,0x34,0xcf,0xd5,0x30,0x25,0x26,0x1f,0x27,0x26,0x4a,0x48,0xab,0x98,0x92,0x8e,0x94,0x9a,0xc5,0x4b,0x73,0xbf,0xc1,0x4b,0x30,0x26,0x25,0x25,0x1f,0x17 +,0x1d,0x1c,0x2f,0x38,0x39,0xc7,0xbb,0xa3,0xa1,0xa6,0xad,0x5b,0xdb,0x5f,0xcf,0xb1,0xbc,0xab,0xa7,0xa6,0xaa,0xaf,0x3a,0x2d,0x37,0x4d,0x37,0x43,0x2b,0x34,0xbf,0xc9 +,0xf6,0x20,0x18,0x18,0x22,0x35,0x2f,0x2f,0x28,0x4f,0xab,0xa1,0x9e,0xa2,0xa6,0xb9,0xad,0xac,0xac,0xbc,0xa0,0x9e,0x98,0xa8,0x47,0x37,0x1d,0x28,0x2b,0x22,0x19,0x1c +,0x20,0x3a,0x39,0x2b,0x24,0x2c,0x5c,0x67,0xaf,0xa9,0xa3,0x9a,0x97,0x95,0x96,0xa8,0x6a,0x3f,0x35,0x28,0x1e,0x1b,0x1e,0x4b,0xa8,0xae,0xcb,0xe6,0x67,0xba,0xb7,0xbb +,0x62,0x3e,0x4a,0xbb,0xbb,0xb5,0xec,0x2b,0x2a,0x24,0xd0,0x56,0x39,0x35,0x35,0xaf,0xa8,0xa4,0xa5,0xba,0xca,0x50,0x31,0x28,0x25,0xdc,0xb6,0xb9,0xe2,0x20,0x1f,0x22 +,0x2d,0xd3,0x5c,0x4f,0xdd,0xa9,0x9b,0xa6,0xac,0xb5,0x6b,0xb6,0xae,0xab,0xbe,0x28,0x2f,0x5b,0xbc,0xcd,0x2b,0x26,0x20,0x2e,0x25,0x20,0x1e,0x29,0xb5,0xb1,0xa1,0xb2 +,0xa9,0xa9,0xa4,0xa1,0xa4,0xba,0x45,0x36,0x51,0xbe,0x2c,0x25,0x17,0x1f,0x39,0xcd,0xc3,0x35,0x5b,0xc4,0xa6,0xa2,0xb2,0xa6,0xab,0xac,0xce,0x2d,0x1c,0x2c,0x5e,0xa7 +,0x9e,0x55,0x51,0x23,0x38,0xbb,0xa7,0xc9,0x45,0x44,0x40,0xb8,0xdf,0x3d,0x3c,0xcb,0xbe,0xb3,0xd8,0x35,0x23,0x2d,0x36,0x7c,0xef,0x67,0xb6,0xb0,0xb1,0xe1,0x4f,0x36 +,0x49,0xaa,0xa3,0xaf,0xbb,0xbd,0xc5,0x48,0x3a,0x39,0x3a,0x20,0x28,0x30,0x29,0x2a,0x25,0x39,0xb9,0xa7,0xa6,0xad,0xc2,0xbb,0xad,0xa9,0xa5,0xa2,0xac,0xbb,0xcd,0x32 +,0x28,0x26,0x20,0x2a,0x21,0x44,0x49,0x38,0x33,0x3e,0xad,0xaf,0xa4,0xd6,0xdb,0xd4,0xb8,0xf9,0x59,0xf3,0xbb,0xc4,0xc5,0xa9,0xdb,0xbd,0x2b,0x45,0xb7,0xbc,0xad,0xaa +,0xb4,0xea,0x34,0x2a,0x25,0x2c,0xb7,0xdd,0xbf,0x63,0x1f,0x22,0x29,0xcf,0xb5,0xc8,0x50,0x2d,0xbf,0xd1,0xc3,0xbe,0xc4,0xb3,0xad,0xa6,0xbd,0xae,0xcc,0x42,0xed,0x50 +,0x3a,0x48,0x4b,0x2d,0x31,0x27,0x28,0x26,0x28,0xb6,0xaf,0xaa,0xd9,0xc1,0xb9,0xa2,0x9c,0xa4,0xaf,0x46,0xdd,0x2a,0x2e,0x29,0x3a,0x4d,0x2f,0x36,0x47,0x63,0x3f,0x44 +,0xdd,0xc9,0xae,0xa8,0xb9,0xb9,0xb5,0xbe,0x6f,0x37,0x3b,0x5f,0xc4,0xb8,0x4d,0x6d,0x26,0x29,0x50,0xbb,0xb3,0xb7,0xb6,0x59,0x60,0x45,0xfe,0xca,0xb2,0xca,0xc2,0xaf +,0x39,0x27,0x2e,0x45,0xe0,0xcf,0xf4,0x6d,0x4a,0x3a,0xb8,0xc9,0x5a,0xd0,0xb9,0xad,0xbc,0xc4,0x4d,0x5f,0x56,0xfb,0x4a,0x40,0x3e,0x27,0x24,0x25,0x54,0x3d,0x29,0x2f +,0xd2,0xa8,0xa3,0xaa,0xb8,0xad,0xb6,0xab,0xa7,0xae,0xcd,0x34,0x33,0x2b,0x29,0x36,0x41,0x38,0x2e,0x3b,0x4b,0x49,0x3e,0xd5,0xb2,0xb9,0xbb,0xdb,0x34,0xce,0xbf,0x4e +,0xbf,0x4c,0xb2,0xac,0xae,0xb3,0x41,0x47,0x34,0x3a,0xbc,0xaf,0xb8,0x54,0x3d,0xe6,0x56,0x62,0xb5,0x6a,0x4b,0x55,0x5e,0x6f,0x2d,0x3c,0x4e,0x7e,0x57,0x6d,0x40,0x3c +,0xce,0xaf,0xaf,0x2f,0xcf,0xc8,0xbd,0xa4,0xb2,0xac,0x4e,0x2d,0x2c,0x6a,0xbd,0x34,0x2c,0x27,0x23,0x23,0x2e,0x35,0xd2,0xbe,0xaa,0xa8,0xbb,0xaf,0xb6,0xa7,0xa7,0xaf +,0xb3,0xbb,0xee,0x40,0x3b,0x27,0x31,0xe7,0xcb,0x40,0x34,0x39,0x2a,0x2d,0xfa,0xa8,0xa7,0x6c,0x26,0x3a,0xe5,0xcb,0xb6,0xab,0xa6,0xb9,0xce,0xbd,0xbc,0x3c,0x28,0x2a +,0x3f,0xd7,0xbc,0xb5,0x53,0x34,0x2e,0x27,0x2e,0x47,0xd3,0x6f,0xcd,0x64,0xf7,0x3a,0x3c,0xb2,0xb4,0xb5,0xc0,0xad,0xb9,0x59,0x4d,0x5e,0xad,0xac,0xac,0xb0,0xc7,0x29 +,0x1c,0x33,0x58,0xb1,0xd7,0x31,0x2f,0x20,0x1f,0x2d,0x37,0x48,0xd5,0xe7,0xae,0xad,0xb2,0xb4,0xb1,0xa0,0x9e,0x9f,0xb2,0x56,0x44,0x2f,0x29,0x4b,0xbd,0xcd,0x66,0x27 +,0x2c,0x21,0x23,0x2d,0x37,0x3b,0x67,0xcb,0x5d,0xb8,0xc5,0xb3,0xd3,0xc4,0xac,0xa6,0x9c,0xa6,0xb2,0x49,0x36,0x59,0xb5,0xae,0xc9,0x39,0x24,0x29,0x2b,0x37,0x6c,0xc9 +,0x54,0xcd,0xc8,0x43,0x22,0x1f,0x2e,0x3b,0xaf,0xaf,0xcb,0xe7,0x5d,0xbf,0xad,0xa0,0xa6,0xc8,0xe2,0x4c,0xd5,0xbf,0xbc,0xbf,0xcf,0xf5,0x3a,0x23,0x21,0x29,0x1e,0x2d +,0x2e,0x41,0xea,0x3c,0xb6,0xb9,0xb6,0x69,0xbf,0xc0,0xad,0xa0,0xa7,0xae,0xde,0xba,0xd3,0xc5,0x46,0x32,0x3f,0x41,0x3e,0x64,0x3f,0x39,0xe6,0xcb,0xaf,0xcc,0x39,0x26 +,0x27,0x77,0xb1,0xaa,0xb9,0xbc,0xe5,0xf8,0xb7,0xbe,0x62,0x48,0x62,0xc4,0x6d,0x58,0xdb,0x49,0xd2,0x48,0x37,0x37,0x2e,0x5b,0x37,0x48,0xc1,0x63,0xe4,0xcc,0xaf,0xcd +,0x35,0x2a,0x3a,0x4e,0xea,0xc8,0xbd,0xaa,0xab,0xad,0xc2,0x5a,0x3a,0x4b,0xc1,0xc0,0xc2,0x2b,0x22,0x34,0x62,0xb9,0x69,0x34,0x20,0x27,0x5a,0xb4,0xaa,0xae,0xbf,0x4d +,0xae,0xaa,0xb9,0x45,0x2e,0x54,0x64,0xd0,0xbb,0xb4,0xad,0xbb,0x3b,0x3b,0x30,0x30,0x3b,0x4c,0x6f,0x3b,0x2f,0x36,0xc1,0xc8,0xce,0x2f,0x2b,0x49,0xd0,0xaa,0xb2,0xcd +,0xd8,0xd0,0xae,0x9d,0xab,0x33,0x26,0x2d,0xd2,0xd5,0xec,0xee,0x56,0xc0,0x50,0xcd,0xbd,0x30,0x1d,0x21,0x44,0xbc,0xcd,0xdc,0xb3,0xd0,0xb4,0xaf,0xcb,0x4d,0x75,0x52 +,0x4e,0xbd,0xbd,0xab,0xc8,0xe9,0x43,0x31,0x30,0x42,0xcf,0x4b,0x31,0x3d,0xb7,0xbd,0xb0,0xbe,0x46,0x34,0x22,0x2f,0xce,0xda,0xb7,0x42,0x5e,0xa8,0xaf,0xb1,0x4b,0x39 +,0x37,0x51,0xe9,0xe0,0xdb,0x65,0xc9,0xbc,0xab,0xc3,0x5b,0x2a,0x1f,0x32,0x4f,0xbf,0xb3,0xac,0xbf,0x51,0xcd,0xba,0x60,0x3c,0x44,0x49,0x3e,0x40,0xbf,0x9f,0xa5,0xbf +,0x3f,0x2d,0x2f,0x44,0xb5,0x71,0x61,0x64,0xfd,0xbe,0xf7,0xcd,0x3c,0x22,0x25,0x3e,0xde,0xc7,0xbf,0xbc,0xae,0xa5,0xab,0xbe,0x3c,0x23,0x34,0x45,0x58,0x47,0x2e,0x39 +,0x63,0xcd,0xb7,0xdb,0x54,0x35,0x35,0xfe,0xc3,0xa0,0xa8,0xb4,0xc6,0x52,0xc5,0xd4,0x39,0x36,0x36,0x34,0x43,0xcd,0xa6,0xa3,0xac,0xde,0x2e,0x23,0x2d,0x46,0x4e,0xbf +,0xe4,0xc3,0xbb,0xcc,0x6f,0xc8,0x4e,0x35,0x3d,0x3d,0x5d,0xbd,0xac,0xb3,0xaf,0xbc,0xbe,0xe9,0x2f,0x25,0x2f,0xee,0xca,0x68,0x4b,0xc9,0xbc,0xbe,0xbb,0xd8,0x2b,0x21 +,0x1c,0x2d,0xb0,0xa8,0xad,0xbe,0x38,0x3e,0xbb,0xda,0xbf,0x47,0x44,0xd3,0xaf,0xa0,0xb4,0xb9,0xbe,0x35,0x26,0x1f,0x24,0x5d,0x48,0xc8,0xb0,0xab,0xae,0x6b,0xd9,0x68 +,0x37,0x31,0x3d,0x3e,0xb4,0xb9,0xba,0xbe,0xc8,0xb2,0xd6,0x64,0x30,0x2d,0x2e,0xc3,0xad,0xc4,0x44,0x3b,0xb9,0xc7,0xc3,0x40,0x31,0x28,0x22,0xd2,0xad,0xa3,0xa6,0xb7 +,0xc3,0x4e,0xfd,0x2a,0x26,0x2f,0x41,0xc2,0xad,0xb4,0xb5,0xab,0xda,0x52,0x23,0x2b,0x33,0xc1,0xab,0xbd,0xba,0x3c,0x5c,0x5a,0x65,0x34,0x22,0x27,0x5e,0xc2,0xb2,0xa7 +,0xbd,0xa9,0xa3,0xaa,0xde,0x32,0x2d,0x21,0x31,0xc2,0xbb,0x50,0x38,0xd4,0xc7,0xd7,0x2e,0x22,0x23,0x2b,0xd3,0xa0,0x9d,0xa9,0xbb,0xcd,0xd8,0x4b,0x3c,0x27,0x3d,0x43 +,0x62,0xb7,0xb0,0x9d,0xa6,0xb7,0x38,0x28,0x1f,0x27,0xca,0xb9,0xac,0x47,0x57,0xb3,0xa7,0xce,0x2c,0x19,0x1d,0x4a,0xb5,0xa0,0x9f,0xa4,0x43,0x71,0xd7,0x4d,0x35,0x29 +,0x3d,0xd9,0xc1,0xbc,0xc1,0xbc,0xb2,0xb0,0x37,0x2d,0x1c,0x1e,0x26,0x3a,0xaf,0xb0,0xa9,0x69,0xb9,0xcf,0xeb,0x29,0x2d,0x3c,0x6d,0xaa,0xac,0xa3,0xa9,0xa6,0xca,0x36 +,0x21,0x17,0x21,0x58,0xa9,0xb0,0xbf,0xdb,0xb7,0xa1,0xac,0xcf,0x1f,0x19,0x1e,0x7c,0xb9,0xa0,0xac,0xc7,0xad,0xc9,0xf9,0x1f,0x27,0x3b,0xcf,0xb4,0xb1,0xb2,0xb6,0xd1 +,0xce,0xdb,0x3c,0x26,0x1d,0x2f,0x5a,0xb8,0xb1,0xae,0xa6,0xab,0xb4,0x3c,0x28,0x2b,0x25,0x38,0x47,0xb5,0xaf,0xb6,0xa9,0xaa,0xb6,0x2d,0x1e,0x23,0x5c,0xb6,0x9f,0xac +,0xbb,0xca,0x51,0xcf,0x33,0x2a,0x1d,0x2b,0x59,0xb9,0xa6,0xaf,0xa0,0xa4,0xa5,0xb2,0x2b,0x20,0x26,0x3d,0xe8,0xca,0xe6,0x48,0xf9,0xaa,0xac,0x4a,0x1e,0x1c,0x2f,0x5e +,0xbf,0xbd,0xa9,0xac,0xc6,0xda,0x73,0x45,0x29,0x38,0xbf,0xe9,0x52,0x35,0xe2,0xa9,0x9c,0xa6,0x27,0x1d,0x1e,0x39,0xbc,0xaa,0xb1,0xc1,0xc8,0xb0,0xaf,0x6c,0x33,0x1d +,0x25,0x4e,0xa9,0xb4,0xc0,0xaf,0xa9,0xac,0x38,0x2f,0x25,0x29,0x3d,0xd5,0xc1,0xcc,0xb8,0xbe,0xb1,0xab,0xb1,0x27,0x22,0x2d,0x2c,0x34,0x39,0xcd,0x6e,0xab,0xad,0x9c +,0xcc,0x18,0x2f,0x4b,0xa9,0xc3,0xad,0xaf,0xca,0xc5,0x53,0xda,0x22,0x18,0x1b,0x3d,0xb4,0xb4,0x5c,0xb0,0x9f,0xb9,0xcc,0x2b,0x2a,0x31,0xfa,0xab,0xb7,0xab,0xde,0xa9 +,0x9d,0xa2,0xcf,0x23,0x19,0x1e,0xeb,0xbd,0xb3,0x5a,0xb4,0x59,0x5d,0x3d,0x28,0x3c,0x26,0x44,0x54,0xc6,0xbf,0xcc,0x9f,0x9d,0x9f,0xac,0x34,0x1f,0x31,0xf3,0xba,0x43 +,0x46,0xa6,0xa5,0x9c,0xae,0x3a,0x1e,0x18,0x34,0x39,0x47,0x2d,0x3c,0xb5,0xbc,0x7a,0x3d,0x43,0x1c,0x2b,0x3f,0xa3,0xa5,0x63,0xb4,0xa3,0x9d,0xa5,0xde,0x3e,0xcd,0x75 +,0xb8,0x3c,0x4a,0xbe,0xcd,0x47,0x2e,0x2e,0x23,0x1f,0x39,0xbb,0xb5,0x42,0x4c,0xc7,0xac,0xaf,0xba,0xd0,0x2e,0x38,0x34,0xa9,0x9b,0x9e,0xb7,0xa5,0x9b,0xae,0xe9,0x16 +,0x21,0xc5,0x20,0x1a,0x10,0x1e,0xa3,0xa2,0xac,0xac,0xa0,0x9a,0xb9,0x3c,0x1b,0x58,0x28,0x0e,0xb9,0xbb,0x6f,0xc1,0x47,0x92,0x88,0x9f,0x9d,0x2f,0x9f,0x99,0xb8,0x12 +,0x12,0x1f,0x00,0x07,0x0c,0xae,0xac,0x3a,0xc7,0x37,0xab,0xa9,0xa1,0x93,0x83,0x8d,0x99,0x87,0x99,0x57,0xa6,0x11,0x2a,0xae,0x0c,0xac,0x86,0x87,0x94,0x8e,0x2f,0x3b +,0x40,0x07,0x09,0x02,0x03,0x02,0x00,0x04,0x10,0x0f,0x25,0x0d,0xb3,0x98,0x34,0x5e,0xc8,0x88,0xa8,0x11,0x3c,0x62,0xa9,0x17,0x15,0x8a,0x87,0x84,0x8e,0x87,0x80,0x87 +,0x88,0x89,0x88,0x82,0x22,0xa0,0x86,0x34,0x19,0xbf,0x80,0xbf,0x9d,0x1e,0x09,0xad,0x0e,0x07,0x09,0x09,0x27,0xb0,0x10,0x0b,0x03,0x01,0x08,0x09,0x09,0x0f,0x27,0x13 +,0x1a,0x1b,0x18,0x0b,0x29,0x95,0x94,0x81,0x8a,0x8b,0x8d,0x88,0x86,0x87,0x84,0x80,0x8d,0xce,0x95,0x87,0x80,0x8e,0xbc,0x20,0x96,0x99,0x8f,0x85,0x4f,0x1c,0xba,0xb8 +,0x15,0x0c,0x03,0x06,0x1f,0x11,0x05,0x09,0x01,0x03,0x09,0x1d,0xd2,0x15,0x0b,0x0e,0x17,0x0e,0x1c,0x12,0x2c,0xb1,0xbc,0x8c,0x94,0x9a,0xa9,0x8b,0x88,0x95,0x8a,0x8e +,0x98,0xaf,0x9f,0x80,0x90,0xa3,0x8d,0x81,0x89,0x96,0x8c,0xaa,0x84,0xa7,0xc5,0x55,0x08,0x08,0x00,0x12,0xa9,0x1f,0x06,0x04,0x05,0x0b,0xb7,0xc9,0xa1,0x55,0x31,0x0e +,0x02,0x07,0x0a,0x26,0x9d,0x98,0x41,0xb5,0x2e,0xbf,0x86,0x8a,0x8e,0x91,0x8c,0x8c,0x14,0x18,0x95,0x81,0x84,0xb5,0x1e,0xb4,0xa9,0x89,0x8d,0x8f,0x8d,0x96,0x8b,0x9b +,0x2b,0x08,0x14,0xb8,0x96,0x4e,0x32,0x4a,0x02,0x05,0xbe,0xca,0x2f,0x05,0x02,0x09,0xb4,0x4b,0x14,0xac,0x1a,0x15,0x16,0x9f,0x17,0xaf,0x80,0x92,0x8b,0x92,0x3f,0x0c +,0x93,0x97,0x13,0x11,0x09,0x88,0x3e,0x00,0x0a,0x00,0x1f,0x8d,0x8b,0x9c,0x9e,0x1f,0x04,0x02,0x0f,0x95,0xac,0x16,0x29,0x0f,0x07,0x0c,0x16,0xbf,0xc3,0x8c,0x4d,0x9f +,0x16,0x33,0x81,0x98,0x8f,0xa9,0x9f,0x28,0x95,0xa6,0xa3,0x80,0x88,0x87,0x8b,0x89,0x8e,0x9c,0x3a,0x3a,0x81,0x84,0x80,0x96,0x12,0x2a,0x8f,0x8f,0x9c,0x83,0x8a,0x97 +,0x1a,0x0c,0x05,0xaa,0x2a,0xd1,0xa2,0xc9,0x0d,0x04,0x2b,0x0e,0x15,0x0f,0xaf,0x16,0x1d,0x28,0x00,0x04,0x00,0x0e,0xd2,0x54,0x28,0x00,0x03,0x00,0x29,0x90,0x9a,0x4d +,0x03,0x1b,0x02,0x32,0x87,0x81,0x81,0x8a,0x8e,0xa9,0x92,0x9b,0x85,0x80,0x8d,0x9a,0x86,0x85,0x9e,0x11,0xc0,0x80,0x81,0x8d,0x13,0x0e,0x33,0x8f,0x07,0x1a,0x9e,0x60 +,0xa4,0x05,0x0e,0x01,0x0e,0x0e,0x16,0xa7,0xc5,0x15,0x06,0x18,0x04,0x03,0x3e,0x92,0x98,0x1b,0x2c,0x8c,0xe7,0x27,0x18,0x9c,0x87,0x87,0x87,0x93,0x8e,0x18,0x13,0x8b +,0x81,0x80,0x89,0x97,0x1b,0x19,0x90,0x8c,0x83,0x8b,0x88,0x15,0x16,0x20,0x00,0x0f,0x17,0x96,0x95,0x15,0x03,0x00,0x01,0x00,0x06,0x10,0xdc,0x0f,0x00,0x02,0x01,0x05 +,0x03,0x17,0x1f,0xa0,0x33,0x05,0x00,0x06,0x11,0x97,0x87,0x84,0x8e,0xa3,0x85,0xa3,0x8a,0x85,0x82,0x80,0x85,0x85,0x87,0x93,0x9a,0x4f,0x8d,0x81,0x82,0x87,0x9d,0x2e +,0x3f,0x95,0x9c,0x9c,0x99,0x8b,0x9d,0xa0,0x0b,0x0f,0x0d,0x90,0x80,0x86,0x26,0x06,0x33,0x09,0x0c,0x15,0x9c,0x26,0x1f,0x1d,0x0c,0x06,0x00,0x0d,0x33,0x9b,0x95,0x0e +,0x06,0x0b,0x0b,0x05,0x0f,0x8f,0x94,0xb9,0x1f,0x0e,0x0a,0x06,0x13,0xa6,0x87,0x88,0x9c,0x1c,0x19,0xf3,0x31,0x94,0x80,0x81,0x88,0x8d,0x97,0x36,0x1d,0x4d,0x9f,0x88 +,0x8c,0xc8,0x0c,0x05,0x1b,0x25,0x0c,0x2d,0xaf,0x19,0x06,0x09,0x0c,0x00,0x09,0x0b,0xbf,0x99,0xbb,0x0c,0x0a,0x0f,0x11,0x8c,0x86,0x86,0x8a,0x90,0xaf,0x36,0x1c,0x9f +,0x83,0x81,0x80,0x80,0x87,0xd6,0xa7,0xaa,0x8b,0x80,0x80,0x86,0xa1,0x98,0x2c,0x22,0xaf,0x96,0x86,0x81,0x8c,0x21,0x05,0x05,0x0a,0x0e,0xb5,0x99,0x12,0x07,0x13,0x08 +,0x00,0x06,0x05,0x12,0x0a,0x04,0x03,0x00,0x01,0x00,0x0c,0x10,0x0f,0x0d,0x09,0x0c,0x21,0x09,0x0f,0xd3,0x8d,0x8b,0x89,0x9d,0xbe,0x9b,0xb1,0x85,0x80,0x80,0x80,0x84 +,0x8e,0xa0,0x98,0x92,0x84,0x83,0x81,0x89,0x9f,0xb8,0x21,0x1e,0xa7,0x87,0x82,0x8c,0x1b,0x20,0x0c,0x02,0x04,0x3a,0xa1,0x8e,0x91,0x1f,0x0d,0x09,0x09,0x08,0x9e,0x92 +,0x9a,0x47,0x18,0x09,0x0d,0x03,0x1d,0xb1,0xbb,0xa5,0x1e,0x19,0x0d,0x12,0x27,0xa8,0x9a,0x9c,0xb8,0xc5,0x0e,0x0c,0x1a,0xd6,0x96,0x8c,0xd9,0x15,0x0f,0x02,0x1c,0x51 +,0x91,0xa6,0xa2,0x95,0x25,0x1b,0x0f,0x45,0x8d,0x88,0x83,0xa2,0x0a,0x0c,0x0c,0x09,0xa6,0x9b,0x90,0x84,0xbb,0x12,0x06,0x02,0x07,0xb2,0x89,0x86,0xd8,0x20,0x14,0x11 +,0x13,0x36,0x8a,0x85,0x80,0x8e,0x98,0x1a,0x1d,0xe1,0x93,0x87,0x82,0x83,0x9c,0xb5,0xb7,0x9a,0x8f,0x81,0x83,0x80,0x96,0xc5,0x9a,0x1f,0x2a,0x9f,0x90,0x8a,0x8e,0x0e +,0x0e,0x19,0x0c,0xad,0x9d,0x62,0x1c,0x0c,0x0c,0x01,0x02,0x08,0x09,0x97,0xbb,0x03,0x01,0x00,0x01,0x00,0x0d,0x27,0x3e,0x35,0x08,0x01,0x03,0x01,0x04,0xc1,0x84,0x83 +,0x9e,0xbb,0xd5,0xde,0xac,0x8e,0x80,0x83,0x83,0x88,0x88,0x98,0xed,0x64,0x89,0x80,0x86,0x8a,0xb2,0x10,0x18,0x24,0xa8,0x8b,0x8f,0xa4,0xe8,0xbc,0x09,0x06,0x56,0x9b +,0x9a,0x8c,0x18,0x1a,0x2c,0x21,0x92,0x89,0x84,0x89,0x91,0x2a,0x1f,0x25,0x10,0x2c,0x97,0x8a,0x8f,0x11,0x05,0x08,0x02,0x2f,0x88,0x8b,0xa4,0x2a,0x0f,0x06,0x01,0x01 +,0x08,0x2a,0x9e,0x27,0x0b,0x02,0x01,0x05,0x0b,0x9b,0x8a,0x99,0xa4,0x2d,0x09,0x05,0x0e,0xa9,0x8c,0x85,0x80,0x96,0x19,0x16,0x0f,0x20,0x8e,0x8b,0x90,0xd0,0xc7,0x4d +,0x1d,0xe8,0x4e,0xa2,0x90,0xd1,0x26,0x0d,0x24,0x21,0xab,0x87,0x8b,0x8c,0xdb,0x7a,0x4b,0x46,0xa3,0x8d,0x85,0x84,0xb1,0xa6,0xab,0xd9,0xa7,0x8a,0x85,0x82,0x84,0xac +,0xa3,0x25,0xa3,0x8f,0x8f,0x83,0x9b,0x16,0x0e,0x0e,0x0f,0x21,0x8d,0x8b,0x85,0xb4,0x0e,0x09,0x00,0x05,0x11,0x49,0x99,0x3a,0x03,0x07,0x03,0x03,0x00,0x08,0x08,0x29 +,0x15,0x06,0x04,0x00,0x03,0x14,0xb2,0x9b,0x99,0x14,0x16,0x14,0x1a,0x4b,0xa1,0x8b,0x83,0x8d,0x31,0xa6,0x2d,0x2f,0x85,0x88,0x81,0x96,0x21,0x2b,0x97,0xad,0x97,0x88 +,0x8d,0x85,0xa5,0x29,0xdd,0xb2,0xac,0x83,0x83,0x88,0x9a,0x0a,0x08,0x64,0x46,0x90,0x82,0x8a,0x84,0xa2,0x0f,0x11,0x19,0x17,0x93,0x8b,0xa3,0x21,0x03,0x06,0x10,0x12 +,0x9d,0x8b,0x8b,0x9f,0x0f,0x03,0x04,0x07,0x16,0x90,0x86,0x8f,0x1a,0x07,0x01,0x07,0x06,0x1c,0xbe,0x32,0x20,0x0b,0x06,0x03,0x0a,0x14,0x99,0x95,0xc8,0x1e,0x09,0x14 +,0xbd,0x94,0x87,0x86,0x87,0xaf,0x1e,0x10,0x10,0xa7,0x8d,0x83,0x80,0x97,0x1d,0x0e,0x0c,0xe9,0x9c,0x95,0x8b,0x9e,0x3e,0xdd,0x23,0xdb,0x8a,0x8b,0x85,0x8a,0x19,0x0c +,0x07,0x0e,0xa0,0x84,0x83,0x80,0x8e,0x2a,0xbd,0x11,0x2c,0x8b,0x85,0x80,0x81,0x9b,0x2b,0x2e,0x25,0x8b,0x82,0x8b,0x84,0xb2,0x18,0x1b,0x03,0x0e,0x94,0x8a,0x84,0xa8 +,0x04,0x01,0x03,0x01,0x1b,0xae,0x2d,0x37,0x0b,0x00,0x00,0x00,0x00,0x20,0xa4,0x26,0x0c,0x00,0x02,0x08,0x15,0xa2,0x8e,0x57,0x6d,0x1a,0x00,0x06,0x13,0x8f,0x80,0x80 +,0xa0,0x28,0x0e,0x13,0x91,0x8c,0x8c,0x80,0x8f,0x8b,0x8e,0x0e,0xc3,0x8c,0x86,0x80,0x8a,0x22,0x1c,0x0f,0x37,0x82,0x87,0x82,0x87,0xad,0x35,0x0e,0x02,0x34,0x83,0x82 +,0x82,0xa6,0x09,0x0a,0x10,0xb4,0x87,0x8c,0xd4,0x2d,0x0d,0x00,0x0d,0x09,0xb1,0x84,0xea,0x27,0x0d,0x00,0x04,0x0d,0x33,0x8a,0xa0,0x1b,0x18,0x01,0x00,0x06,0x0f,0x91 +,0x8d,0x1a,0x14,0x0d,0x0c,0xac,0x9f,0xae,0x92,0xa8,0x4d,0x1a,0x0c,0x0d,0x95,0x8a,0x96,0x9f,0x0e,0x1d,0xba,0xbc,0x9c,0x94,0xbb,0x8f,0x8d,0x1a,0x59,0xde,0xbc,0x83 +,0x8f,0xbf,0xb7,0x1a,0xae,0x80,0x88,0x86,0x96,0x1c,0x1b,0x0a,0x0b,0xbd,0x8c,0x9d,0x69,0x20,0x0a,0x20,0x9e,0x8b,0x81,0x8d,0xa8,0xa6,0x19,0x0f,0x98,0x85,0x80,0x80 +,0xba,0x17,0x11,0x06,0x9d,0x94,0x9e,0x8b,0xaa,0x24,0x09,0x00,0x06,0x99,0x89,0x99,0x24,0x00,0x00,0x03,0x0f,0xcc,0xa3,0x19,0xad,0x31,0x00,0x06,0x06,0x44,0x8a,0xc8 +,0x0f,0x17,0x05,0x18,0x8f,0xa5,0x92,0x94,0xa1,0xbc,0x16,0x12,0x9b,0x83,0x99,0x77,0x0e,0x0b,0xa9,0x8b,0x8d,0x85,0x9a,0xa9,0x9f,0x04,0x0c,0x39,0x96,0x83,0x9e,0x0d +,0x0f,0x27,0x9a,0x83,0x93,0xa8,0x7c,0x40,0x10,0x08,0x12,0x97,0x80,0x84,0x8d,0x66,0x0f,0x1b,0x89,0x8d,0x87,0x98,0x1e,0x23,0x04,0x0b,0xa5,0x81,0x83,0x98,0x08,0x01 +,0x01,0x0c,0xba,0x9c,0x90,0xa5,0xdc,0x07,0x01,0x0c,0xa7,0x83,0x95,0x15,0x08,0x04,0x09,0x9f,0xaf,0x95,0x8a,0x8a,0xaf,0x04,0x00,0x17,0x87,0x88,0xaf,0x0b,0x04,0x05 +,0x3f,0xab,0xa1,0xa6,0xef,0xa5,0x07,0x01,0x08,0xcf,0x8d,0x9e,0x1a,0x18,0x1d,0xaa,0x86,0x94,0x98,0x9a,0x8c,0x4e,0x0d,0x1a,0x94,0x80,0x8b,0x5b,0x2d,0x2f,0x9f,0x81 +,0x8f,0x8f,0xa1,0x9c,0xa4,0x08,0x0c,0x8f,0x80,0x80,0x8c,0x0e,0x07,0x0d,0x8f,0x88,0x8d,0x9f,0xa9,0x97,0x08,0x05,0x2a,0x86,0x80,0x87,0x18,0x05,0x00,0x0e,0xa5,0x49 +,0xa0,0xaa,0x93,0x0c,0x00,0x00,0x18,0x8f,0xab,0x10,0x05,0x02,0x0f,0x8f,0xa7,0x95,0x95,0x84,0x95,0x0a,0x04,0x15,0x93,0x8f,0xc0,0x14,0x09,0x0e,0xa3,0x1d,0x11,0x03 +,0x0f,0x0f,0x00,0x01,0x0a,0x9e,0x99,0x24,0x05,0x07,0x0a,0x97,0x8b,0x8e,0xba,0xb1,0x97,0x0c,0x1c,0x96,0x81,0x80,0x86,0xaa,0x24,0x22,0x8a,0x80,0x83,0x80,0x83,0x80 +,0x46,0x0a,0x15,0x89,0x80,0x83,0x96,0x28,0x08,0x29,0x9c,0xba,0x92,0xb1,0x89,0x1d,0x00,0x03,0x1c,0x92,0x90,0x26,0x0a,0x03,0x06,0x21,0x0c,0x14,0x0d,0x9e,0x4d,0x06 +,0x0b,0x45,0x89,0x8a,0xa0,0xa2,0x9a,0x9e,0x81,0x8f,0x8f,0x98,0x88,0xa9,0x02,0x01,0x06,0xa0,0xbe,0x08,0x00,0x01,0x01,0x22,0x18,0x1a,0x0d,0x2f,0xe7,0x02,0x02,0x0a +,0x8b,0x80,0x8a,0x40,0x1a,0x15,0x90,0x8f,0x99,0x9f,0x9a,0x85,0x37,0x10,0x12,0x94,0x85,0x8a,0x9b,0xa3,0x2e,0xa4,0xa1,0xaa,0x8a,0x88,0x80,0xac,0x0e,0x13,0x91,0x82 +,0x8a,0x6f,0x47,0xdf,0x8d,0x88,0xca,0x33,0x24,0x8a,0x36,0x08,0x02,0x10,0x9f,0xca,0x05,0x04,0x02,0x0e,0x9f,0x1e,0x43,0x1e,0x94,0x9e,0x49,0xe9,0x8e,0x80,0x82,0x8d +,0xc9,0x40,0x9d,0x86,0xa1,0x97,0xc3,0x97,0x24,0x00,0x01,0x06,0x5e,0xa9,0x0d,0x00,0x01,0x07,0xa5,0x1d,0x0c,0x02,0x16,0xd5,0x05,0x04,0x04,0x31,0x8f,0xaa,0x1a,0x14 +,0x0f,0x90,0x8f,0x9f,0x97,0x8d,0x86,0xae,0x2c,0xaf,0x82,0x80,0x85,0xc0,0x35,0x29,0x88,0x84,0x91,0x9c,0xbe,0x8b,0x26,0x0e,0x0e,0x91,0x83,0x8c,0x1a,0x07,0x0b,0xa5 +,0x89,0xb2,0x34,0x14,0x97,0x1e,0x06,0x03,0x16,0x8d,0x83,0x94,0x28,0x0c,0x24,0x86,0x8a,0x85,0x88,0x80,0x8c,0x5b,0x24,0x9a,0x80,0x87,0xb9,0x0a,0x03,0x09,0xab,0x1c +,0x09,0x02,0x15,0x2f,0x02,0x01,0x00,0x15,0xa8,0x43,0x0c,0x05,0x06,0xa1,0x9e,0xae,0x30,0xb1,0x8d,0x0f,0x06,0x04,0xa8,0x84,0x86,0xb6,0x13,0x03,0x4a,0x8b,0x94,0x9a +,0x4c,0x94,0x19,0x0a,0x0e,0x93,0x80,0x84,0x9c,0x14,0x0f,0x9a,0x80,0x8a,0x8d,0x9c,0x81,0x8e,0x1e,0x09,0x1b,0x8a,0x83,0x8d,0x20,0x04,0x03,0x2d,0x23,0x25,0x0c,0x5f +,0x42,0x03,0x04,0x0a,0x8e,0x81,0x88,0x91,0xca,0xb9,0x81,0x82,0x82,0x91,0x8f,0x82,0x9f,0x2c,0x0d,0x31,0xa2,0x1d,0x06,0x05,0x01,0x18,0x24,0x09,0x08,0x08,0xa8,0x12 +,0x01,0x01,0x04,0x6d,0xb0,0x1c,0x0b,0x01,0x0e,0x99,0xab,0xa5,0x1d,0x9a,0xb0,0x0b,0x0b,0x25,0x83,0x80,0x85,0x9e,0x1d,0x22,0x84,0x89,0x89,0x98,0x8e,0x81,0xc8,0x1c +,0x12,0x9f,0x84,0x8a,0x9e,0x29,0x04,0x1c,0xe9,0x2a,0xbd,0xae,0x82,0xac,0x07,0x01,0x0b,0x94,0x8b,0xae,0x21,0x07,0x16,0x8d,0x99,0x95,0x60,0x8d,0x87,0xb0,0xca,0xa5 +,0x82,0x81,0x85,0x98,0xce,0x2b,0x8b,0x94,0x2d,0x12,0x11,0xa3,0x0c,0x02,0x00,0x07,0x31,0x3e,0x0d,0x05,0x00,0x0c,0xbf,0x3d,0xbe,0x12,0x9e,0x1e,0x02,0x03,0x0f,0x8e +,0x88,0xa6,0x13,0x09,0x0a,0x8e,0xa3,0x99,0x60,0x9d,0x8a,0x1b,0x0e,0x0b,0x9a,0x85,0x87,0x94,0xae,0x14,0x9c,0x9b,0xbd,0x97,0x98,0x80,0x8e,0x2f,0x0a,0x5c,0x85,0x81 +,0x91,0xcb,0x0d,0x16,0x8d,0xcf,0xa9,0x0f,0x34,0xd7,0x03,0x03,0x03,0x2b,0xa3,0x3e,0x17,0x16,0x16,0x8a,0x87,0x87,0x88,0x8e,0x80,0x8f,0xa9,0xbd,0x8a,0x80,0x82,0x99 +,0x18,0x01,0x06,0x2e,0x14,0x55,0x0b,0x0e,0x09,0x00,0x01,0x03,0xac,0x92,0xeb,0x03,0x03,0x00,0x1d,0xbf,0x9c,0x98,0xcf,0x8e,0x0d,0x07,0x05,0xb1,0x81,0x82,0x85,0xa0 +,0x0c,0x18,0x93,0x9d,0x86,0x8f,0x83,0x8d,0x1a,0x10,0x15,0x8d,0x84,0x89,0x9d,0x1d,0x09,0xa9,0x9d,0x92,0x94,0xab,0x8b,0x0f,0x0f,0x0c,0xd4,0x8b,0xb5,0x1a,0x09,0x05 +,0x1e,0x8f,0xc6,0xa7,0x0f,0x9e,0x99,0x17,0x25,0x26,0x84,0x81,0x80,0x8a,0x59,0x25,0x85,0x82,0x80,0x8f,0x22,0x55,0x04,0x03,0x01,0x20,0x91,0xb1,0x09,0x00,0x00,0x04 +,0x4d,0xcd,0xa1,0x12,0x1d,0x16,0x00,0x04,0x04,0x96,0x86,0x97,0x1c,0x05,0x01,0x3c,0x8f,0x93,0x8e,0x9f,0x89,0x25,0x09,0x05,0x2e,0x82,0x82,0x86,0xf1,0x0b,0x23,0x85 +,0x84,0x84,0xa7,0x91,0x8f,0x4a,0x39,0x1e,0x8b,0x85,0x89,0xd5,0x0f,0x0d,0x9f,0x86,0x97,0x36,0x0e,0xa9,0x1d,0x09,0x04,0x09,0xb0,0x9f,0xbe,0x0b,0x06,0x0e,0x91,0x83 +,0x84,0x8e,0x97,0x90,0xb1,0xa0,0x8e,0x80,0x80,0x81,0xac,0x09,0x08,0x2b,0x90,0x9f,0x2b,0x06,0x0a,0x08,0x00,0x01,0x02,0x38,0x95,0x2d,0x00,0x02,0x00,0x23,0x91,0xa9 +,0xb2,0x13,0xc0,0x16,0x09,0x05,0x26,0x82,0x83,0x8c,0x1f,0x0d,0x35,0x86,0x8b,0x8b,0xcb,0x3b,0x9c,0x26,0x3f,0x1d,0xa0,0x87,0x8e,0xb3,0x3e,0x20,0x9f,0x8f,0xa5,0x9d +,0x47,0x8f,0x97,0xbc,0x21,0x15,0x8f,0x8c,0xa1,0x13,0x07,0x0d,0x9d,0x98,0xaa,0x1a,0x08,0x43,0x14,0x1e,0x1c,0xaa,0x84,0x88,0x94,0x76,0x9d,0x8a,0x80,0x82,0x81,0x9a +,0x9f,0x8f,0xe4,0x1e,0x07,0x1c,0xe1,0x28,0x09,0x01,0x00,0x03,0x24,0xbb,0xb2,0x09,0x0b,0x0c,0x05,0x08,0x07,0xca,0x95,0x9e,0x2a,0x0f,0x05,0x24,0x94,0x8d,0x90,0x25 +,0xbc,0x46,0x23,0x1e,0x52,0x8a,0x8d,0x8e,0xa7,0x2f,0x1e,0xac,0x98,0x8c,0x8f,0x98,0x88,0x9f,0xa4,0x2f,0x9e,0x87,0x8a,0x9f,0x1b,0x0f,0x21,0x8e,0x8a,0x8d,0x25,0x1e +,0x4d,0x49,0x1e,0x0a,0x1c,0x2e,0xd6,0x38,0x19,0x0c,0x22,0x91,0x8d,0x94,0x1a,0x1b,0x23,0x17,0x1a,0x15,0xb2,0x91,0x96,0x5b,0x15,0x07,0x24,0x95,0x8e,0x96,0x19,0x1e +,0x17,0x18,0x1b,0x4b,0x92,0x8c,0x8d,0xc0,0x10,0x05,0x32,0xa7,0x9c,0x4d,0x19,0x30,0x12,0x16,0x0e,0x1d,0x8f,0x87,0x87,0x9c,0x0b,0x01,0x10,0xad,0x8c,0x92,0xb6,0xc4 +,0xe7,0x42,0x27,0xdc,0x95,0x8f,0x95,0x2a,0x08,0x05,0xbb,0x85,0x83,0x8c,0x9b,0xa4,0xaa,0xae,0x15,0x13,0xe9,0x9a,0x97,0xb4,0x1b,0x1e,0x96,0x86,0x83,0xa6,0x0e,0x0d +,0x0b,0x15,0x11,0x0a,0x14,0xc3,0xa4,0x2f,0x0f,0x03,0x14,0x2f,0xc9,0x2b,0x09,0x08,0x09,0x20,0xb1,0xb8,0x98,0x9e,0xa4,0xbe,0x18,0x0b,0x2d,0x8f,0x8d,0x9f,0x2c,0x56 +,0x5d,0xba,0x25,0x06,0x14,0xb3,0xae,0x2c,0x10,0x0d,0x0b,0x36,0x9f,0x8f,0x9c,0xae,0xa3,0xb8,0xbb,0x26,0x1e,0x74,0x9d,0x9a,0x9e,0xee,0x33,0x96,0x85,0x82,0x80,0x8c +,0x95,0x99,0xa0,0x5f,0x22,0xac,0x8d,0x85,0x83,0x96,0xc7,0x49,0x95,0x85,0x86,0x9e,0x2e,0x1e,0x1d,0x1c,0x0b,0x14,0xb3,0x92,0xa4,0x0f,0x00,0x02,0x08,0x22,0x2a,0x88 +,0x95,0x00,0x0f,0x56,0x1f,0x9f,0x21,0x1b,0xb8,0x1d,0x08,0x04,0x05,0x00,0x11,0x05,0x01,0x08,0x06,0x0b,0x07,0x05,0x15,0x0a,0x01,0x08,0x07,0x08,0x06,0x04,0xdb,0x87 +,0x84,0x83,0x8b,0x3d,0x18,0x8a,0x80,0x86,0x84,0x80,0x80,0x80,0x81,0x85,0x8f,0x86,0x80,0x80,0x80,0x81,0x80,0x82,0x81,0x81,0x87,0x92,0x8c,0x87,0x81,0x87,0x86,0xb9 +,0x1e,0xa3,0x3c,0x3e,0x29,0x1d,0x0d,0x03,0x02,0x01,0x03,0x04,0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x0b,0x23,0x07,0x00,0x00,0x00,0x00,0x05,0x05,0x03,0x00,0x04,0x03 +,0x05,0x04,0x07,0x21,0xa9,0x9c,0x16,0x04,0x04,0x1c,0x91,0x8a,0xa3,0xaf,0xac,0x8f,0x95,0x8e,0x8e,0x93,0x80,0x81,0x80,0x82,0x83,0x81,0x82,0x81,0x82,0x81,0x80,0x80 +,0x80,0x80,0x80,0x80,0x84,0x84,0x80,0x80,0x80,0x80,0x80,0x83,0x85,0x82,0x82,0x86,0x88,0x8a,0x89,0x89,0x8f,0x9a,0x6a,0xa2,0x90,0x8f,0xa6,0x3b,0x1b,0x0f,0x10,0x0d +,0x0a,0x05,0x07,0x13,0x0e,0x05,0x01,0x00,0x00,0x02,0x0f,0x0e,0x03,0x01,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x03,0x00,0x01,0x00,0x01,0x05,0x03,0x05,0x02,0x00,0x01 +,0x09,0x30,0x1e,0x0c,0x07,0x05,0x0a,0x18,0x2c,0x0f,0x05,0x0c,0x40,0x9a,0x8f,0x9b,0xae,0x58,0xaf,0x9e,0xab,0x8f,0x85,0x83,0x83,0x8b,0xad,0x27,0xa4,0x84,0x80,0x80 +,0x80,0x83,0x82,0x82,0x81,0x86,0x8b,0x86,0x87,0x85,0x82,0x81,0x80,0x82,0x82,0x84,0x83,0x82,0x83,0x84,0x85,0x87,0x88,0x8e,0x93,0x90,0x92,0x8e,0xa2,0x1d,0x08,0x08 +,0x24,0x9e,0x8b,0x73,0x0d,0x0b,0x0b,0x19,0x1d,0x59,0xa5,0xa9,0xa7,0x9f,0xbc,0xd6,0x4a,0xa7,0x96,0x9b,0xac,0x1d,0xd9,0x91,0x89,0x8d,0x9a,0x98,0x9e,0x9c,0x91,0x92 +,0x9f,0x64,0xbe,0x94,0x8a,0x86,0x8b,0x9e,0xb0,0x2d,0x2a,0x5e,0x9c,0x8e,0x9e,0x4b,0x0c,0x01,0x01,0x00,0x03,0x0a,0x15,0x0c,0x02,0x02,0x01,0x01,0x00,0x01,0x01,0x00 +,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x04,0x06,0x02,0x03,0x03,0x01,0x02,0x02,0x03,0x01,0x02,0x04,0x04,0x01,0x01,0x00,0x06,0x18,0x25,0x16,0x09,0x06,0x03,0x07,0x17 +,0xcb,0xab,0x5c,0xa6,0x98,0x92,0x8f,0x8e,0x85,0x83,0x82,0x82,0x86,0x83,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x82,0x83,0x80,0x80,0x80,0x80,0x81,0x83 +,0x86,0x84,0x81,0x81,0x80,0x81,0x80,0x85,0x8e,0x9f,0xa3,0x88,0x82,0x81,0x81,0x84,0x85,0x87,0x87,0x83,0x85,0x85,0x8a,0x8e,0x87,0x85,0x85,0x8e,0x93,0x8f,0x97,0x9b +,0xaa,0xac,0xda,0x20,0x16,0x09,0x02,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x02,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x03,0x02,0x02,0x01,0x06 +,0x07,0x07,0x04,0x03,0x04,0x06,0x0d,0x10,0x10,0x0f,0x0d,0x18,0x29,0x1f,0x18,0x12,0x48,0x95,0x8c,0x87,0x8e,0x94,0x9a,0x9c,0x91,0x89,0x84,0x82,0x82,0x82,0x8a,0x9f +,0x53,0xa9,0x8e,0x8b,0x8a,0x91,0x8e,0x92,0x95,0x94,0x9b,0x9e,0x4c,0x3a,0xba,0xaf,0xa9,0xb4,0xa4,0x93,0x97,0x99,0x9e,0x94,0x8f,0x91,0x8d,0x91,0x9e,0xc8,0x2d,0x3b +,0x27,0x16,0x09,0x0b,0x1d,0x36,0xc1,0x2c,0x1e,0x12,0x0b,0x0b,0x0e,0x0e,0x10,0x13,0x1c,0x23,0x19,0x14,0x1c,0xa9,0x9c,0x96,0xb5,0x2e,0x1a,0x17,0x37,0xb6,0x99,0xa4 +,0xb1,0xb0,0x6f,0x59,0x23,0x1e,0xda,0xa2,0x93,0x9b,0xaf,0x3e,0x1e,0x21,0x2b,0x36,0xad,0xa6,0x8e,0x8d,0x97,0x5c,0x17,0xc9,0x9c,0x8a,0x8d,0x8f,0x8e,0x8d,0x87,0x87 +,0x87,0x88,0x88,0x88,0x86,0x88,0x8c,0x89,0x82,0x81,0x81,0x88,0x9a,0xa9,0xa7,0x9c,0x99,0x9b,0xa8,0x20,0x0f,0x06,0x02,0x01,0x01,0x04,0x09,0x0d,0x08,0x06,0x04,0x04 +,0x04,0x05,0x08,0x0b,0x0a,0x0e,0x0d,0x0b,0x0a,0x0b,0x35,0xaa,0x96,0xa6,0x28,0x1b,0x13,0x25,0x36,0x54,0xbb,0xb4,0xa7,0xac,0x59,0x2b,0x3e,0x9b,0x8b,0x85,0x88,0x8e +,0x94,0x91,0x8e,0x8e,0x90,0x91,0x90,0x8c,0x89,0x87,0x8c,0x8f,0x8d,0x91,0x91,0xa7,0xc4,0x52,0x4a,0xc1,0xbd,0xc3,0xd8,0x31,0x28,0x13,0x0a,0x05,0x07,0x23,0xa2,0x8d +,0x95,0x58,0x1a,0x14,0x1c,0x2b,0x41,0xa8,0xb1,0xb3,0x34,0x18,0x09,0x08,0x19,0x2c,0x5e,0x13,0x0a,0x07,0x09,0x0e,0x10,0x18,0x15,0x16,0x19,0x19,0x19,0x0d,0x1c,0xc3 +,0x99,0x8e,0x99,0x9b,0xaa,0xb9,0xad,0xce,0xb1,0x9e,0x9c,0x90,0x9c,0x9f,0x37,0x39,0x9d,0x94,0x8e,0xa0,0xc1,0x40,0x48,0xb9,0xbf,0xac,0xb3,0x41,0x4c,0x2c,0x25,0x11 +,0x26,0xa9,0x94,0x94,0xb9,0x3d,0x1c,0x20,0x3c,0xbf,0x99,0x90,0x8d,0x8a,0x90,0x99,0xba,0x99,0x89,0x82,0x81,0x83,0x84,0x8d,0x93,0x9b,0xa4,0x94,0x94,0x9a,0xaa,0x1f +,0x0d,0x04,0x08,0x0f,0x19,0x14,0x0a,0x06,0x03,0x02,0x03,0x03,0x09,0x09,0x08,0x09,0x08,0x0a,0x09,0x17,0x27,0xc4,0x5e,0x2f,0x29,0x20,0x20,0x23,0x29,0x38,0x3c,0x45 +,0xc3,0xb9,0x45,0x2b,0xb7,0x9d,0x8c,0x93,0x96,0x95,0x9c,0x8f,0x8c,0x88,0x83,0x86,0x83,0x87,0x8e,0x9c,0x9f,0x8a,0x85,0x82,0x87,0x8f,0x9b,0xa8,0xc9,0x38,0x32,0xbf +,0xb6,0xb7,0x42,0x1b,0x0c,0x0b,0x19,0x2a,0x4d,0x2d,0x53,0xac,0xad,0xc1,0x2d,0x3a,0xe5,0x33,0x3f,0x27,0x1d,0x12,0x18,0x2f,0x2e,0x2a,0x18,0x15,0x13,0x0e,0x0a,0x06 +,0x09,0x0c,0x0d,0x15,0x1a,0x1a,0x12,0x1a,0x29,0x7b,0xa8,0xb5,0xa4,0x9f,0xaa,0xaa,0xdc,0xaa,0xa6,0xb1,0xa7,0x48,0x5b,0x22,0x50,0x9a,0x8e,0x8f,0xa0,0xab,0xbb,0xd8 +,0x5a,0xba,0x9e,0x99,0x98,0x91,0xa1,0xcb,0x1c,0x25,0xbd,0xaa,0xa7,0xc3,0xb3,0xb6,0xb4,0xb9,0x44,0x41,0x29,0x3b,0xae,0xa8,0xa6,0xed,0xaa,0x93,0x89,0x86,0x88,0x87 +,0x89,0x8a,0x89,0x8b,0x8a,0x8d,0x93,0x8f,0x9d,0xae,0x24,0x1b,0x38,0x2a,0x26,0x18,0x12,0x0c,0x0c,0x0a,0x05,0x04,0x01,0x02,0x03,0x05,0x05,0x04,0x07,0x0f,0x18,0x20 +,0x1e,0x20,0x1c,0x24,0x20,0x16,0x1c,0x16,0x2c,0xc2,0x5b,0xef,0x1c,0x26,0xbc,0x9d,0x8f,0x9e,0x9d,0xb5,0xae,0x95,0x95,0x8d,0x8f,0x92,0x8e,0x91,0x8d,0x8e,0x93,0x8b +,0x8c,0x8c,0x95,0x9c,0x96,0x93,0x8d,0x93,0x9c,0xb1,0x62,0xa1,0x9c,0x9c,0xaf,0x25,0x2d,0x35,0x7d,0xc1,0xfb,0xc5,0xcc,0xce,0x4b,0x2e,0x3d,0x30,0x31,0x25,0x18,0x10 +,0x0b,0x0e,0x1a,0x28,0x2b,0x1f,0x14,0x13,0x19,0x23,0x23,0x18,0x0d,0x0a,0x17,0x30,0xcf,0x39,0x15,0x12,0x18,0x28,0x50,0x28,0x30,0x54,0xb3,0xa3,0x57,0x28,0x21,0x27 +,0x4b,0xe8,0x3b,0x2f,0x2d,0x41,0xbc,0xa2,0x9c,0x9d,0x95,0x99,0x95,0x93,0x96,0x96,0x95,0x94,0x8f,0x91,0x9b,0xa7,0x2d,0x1f,0x1f,0x27,0x2b,0x37,0x3d,0x56,0x49,0x1f +,0x16,0x16,0x2a,0xbe,0xa5,0xa2,0x96,0x8e,0x8c,0x88,0x86,0x86,0x86,0x88,0x86,0x86,0x8b,0x8c,0x8d,0x8e,0x8e,0x9d,0xb7,0xca,0x4b,0x2b,0x1b,0x11,0x0d,0x0d,0x0a,0x0a +,0x09,0x05,0x02,0x02,0x03,0x07,0x08,0x06,0x08,0x0a,0x0b,0x0f,0x15,0x19,0x1f,0x1f,0x1b,0x19,0x11,0x0e,0x20,0x35,0xbe,0xb1,0x2f,0x2c,0x39,0xe2,0xa8,0xa3,0xa0,0x9c +,0xa4,0xa8,0x9c,0x97,0x91,0x8c,0x8c,0x8d,0x8e,0x90,0x91,0x8f,0x96,0x95,0x92,0x99,0x9a,0xa9,0xbe,0x9d,0x99,0x9b,0x9b,0xab,0xaa,0xa3,0xac,0xba,0xaf,0xa9,0x9e,0x9f +,0xe4,0x32,0x32,0x38,0xc1,0x59,0x21,0x26,0x36,0x3e,0x39,0x19,0x0f,0x17,0x15,0x19,0x1b,0x15,0x18,0x1b,0x15,0x16,0x12,0x0f,0x19,0x18,0x11,0x0f,0x10,0x13,0x1b,0x1b +,0x15,0x1b,0x1f,0x26,0x2e,0x1d,0x22,0x42,0x4c,0xc2,0xa7,0xb6,0xc5,0xbe,0xf1,0xc0,0xb7,0xc7,0xa8,0x9f,0x99,0x91,0x96,0x98,0x9d,0x9f,0x9a,0x8f,0x8f,0x96,0x9e,0x66 +,0x3f,0xc9,0xae,0x9f,0xa9,0x5e,0x42,0xbf,0xb1,0xb6,0x50,0x31,0xc9,0x9c,0x9c,0xae,0x5f,0xb3,0xa6,0x99,0x8e,0x8a,0x95,0x9f,0xad,0xc0,0x92,0x8e,0x8c,0x8e,0xc9,0x17 +,0x26,0x34,0xb0,0xcc,0x1d,0x10,0x52,0xbf,0x48,0x1a,0x0b,0x13,0x18,0x25,0x1c,0x14,0x0d,0x0b,0x09,0x25,0x3e,0xc6,0x3a,0x18,0x14,0x1f,0xb7,0xb3,0xcf,0x18,0x14,0x6e +,0x8c,0x8f,0xc3,0x1b,0x0c,0x1a,0xc5,0xa6,0x3d,0x3d,0xbd,0x3a,0x2f,0x3c,0xa6,0x9f,0x95,0xab,0x1c,0x19,0x3c,0xad,0xbf,0xba,0xea,0xa5,0x99,0xa7,0x24,0x48,0x9f,0x8e +,0x85,0x89,0x96,0x32,0x1f,0x20,0xaf,0x90,0x90,0x9a,0xb4,0x1a,0x20,0xb3,0x9b,0x8f,0x97,0xd6,0x1f,0xbe,0xb9,0x2f,0x1e,0x1a,0x1d,0x31,0xb8,0x2f,0x2c,0xcb,0x3c,0xd5 +,0xa4,0xbc,0xaf,0xa6,0xba,0x1d,0x19,0x2d,0x2c,0x27,0x1a,0x13,0x22,0xa8,0xa5,0x3d,0x1b,0x18,0x1f,0xd6,0xc5,0xd8,0x3b,0x1e,0x0f,0x10,0x1e,0x28,0xaa,0xaa,0x33,0x15 +,0x14,0x26,0xb6,0x9f,0xa9,0xb7,0xa2,0x9c,0xbf,0x3f,0x4c,0xbf,0x97,0x8d,0x9d,0xcd,0x4e,0x33,0xfd,0xa2,0x99,0x93,0x8f,0x98,0x4b,0x3c,0x9f,0x8c,0x88,0x9a,0x2c,0x1f +,0xa7,0x8d,0x8b,0x8e,0xa2,0xad,0x9b,0x97,0x9b,0x9a,0x9b,0xaa,0xc6,0x2e,0x21,0x3d,0x7b,0x3d,0x2e,0x2c,0x24,0x27,0x1f,0x19,0x20,0x35,0x33,0x19,0x10,0x0e,0x12,0x14 +,0x12,0x0f,0x1b,0xe3,0xaf,0xbf,0x2e,0x1c,0x21,0xbb,0x9e,0x99,0xbc,0x1c,0x14,0x22,0xa9,0x8d,0x87,0x91,0xc4,0x2a,0x29,0xae,0x93,0x96,0xb7,0x1b,0x10,0x1b,0x2f,0x26 +,0x18,0x0f,0x0f,0x0d,0x0d,0x0d,0x0b,0x0b,0x0a,0x0f,0x1f,0x57,0x3b,0x1e,0x19,0x19,0x37,0x9d,0x9f,0xe9,0x2e,0x49,0xac,0x99,0x8e,0x90,0x8f,0x93,0x9a,0x9d,0x91,0x88 +,0x85,0x88,0xa2,0x7e,0xc6,0x9b,0x8e,0x8a,0x8b,0x9d,0xa6,0x9c,0x96,0x8f,0x8d,0x8d,0x8e,0x9d,0xbe,0x49,0x49,0x4c,0xe5,0xb5,0xbe,0x40,0x23,0x0f,0x0a,0x12,0x2e,0xce +,0x3d,0x17,0x0a,0x09,0x0c,0x10,0x17,0x17,0x0f,0x0c,0x0b,0x0f,0x18,0x2d,0x40,0x25,0x1a,0x0f,0x0f,0x1b,0x29,0x38,0xc8,0xad,0xb8,0xaf,0xb2,0xbd,0xd8,0xbe,0xb6,0xed +,0xbe,0x2d,0x2e,0xd1,0xaa,0xa1,0xa6,0xad,0x6f,0xd0,0xae,0xa0,0x92,0x92,0x9d,0xb4,0xba,0xa5,0x98,0x8e,0x93,0xa2,0x45,0x30,0xce,0x9c,0x99,0x9d,0x9a,0x9f,0xaf,0xd3 +,0xb3,0xa2,0x9a,0x8f,0x8e,0x8f,0x90,0x93,0x97,0x9b,0x9a,0x91,0x8d,0x8c,0x96,0x9e,0x9b,0x97,0x8f,0x8e,0x95,0x4c,0x21,0x12,0x17,0x24,0x26,0x17,0x09,0x05,0x02,0x06 +,0x07,0x07,0x04,0x03,0x05,0x07,0x0a,0x09,0x05,0x04,0x06,0x0a,0x0a,0x09,0x08,0x08,0x0e,0x1f,0xbe,0xaf,0xb2,0x5c,0x4e,0xac,0x9b,0x8d,0x8d,0x90,0x9e,0xa6,0x8e,0x87 +,0x84,0x88,0x90,0x9a,0x99,0x92,0x91,0x8f,0x95,0x9c,0x9a,0x98,0x94,0x96,0x9b,0xa4,0xba,0xa6,0x9e,0x9f,0xa8,0xb4,0xcc,0xa5,0x96,0x96,0xa2,0x3b,0x2a,0x32,0x9f,0x9d +,0xaa,0xad,0x2c,0x1a,0x1b,0x2b,0x3d,0x25,0x12,0x0a,0x0a,0x0e,0x1a,0x29,0x1f,0x0f,0x08,0x0c,0x12,0x19,0x19,0x0d,0x0c,0x19,0x3c,0x2d,0x27,0x27,0x18,0x25,0xaf,0xa4 +,0xbb,0x43,0x33,0x21,0x4f,0x9e,0x9b,0xc3,0x2a,0x25,0x34,0xae,0xa3,0xaa,0x22,0x18,0x20,0x39,0xba,0xc0,0x34,0x1a,0x25,0xc9,0x9c,0x8d,0x88,0x87,0x8c,0x8d,0x89,0x85 +,0x83,0x85,0x89,0x8e,0x89,0x82,0x81,0x82,0x89,0x92,0x92,0x8b,0x86,0x8d,0x39,0x18,0x1f,0x21,0x3c,0xae,0x14,0x01,0x00,0x02,0x05,0x0f,0x10,0x03,0x00,0x02,0x09,0x0e +,0x13,0x09,0x03,0x05,0x0f,0x27,0x1b,0x16,0x19,0x17,0x12,0x2f,0xa3,0x25,0x0f,0x34,0x45,0x19,0xcf,0x8a,0x9a,0x2f,0xce,0xa6,0xb1,0x98,0x88,0x9e,0x28,0xcb,0x98,0x8b +,0x84,0x84,0x99,0x2d,0x96,0x83,0x83,0x85,0x89,0x94,0xb3,0x92,0x82,0x84,0xa7,0x2a,0xa6,0xa3,0xa2,0x8a,0xa3,0x0f,0x2e,0xa9,0xb9,0x1e,0x1f,0x0f,0x05,0x1e,0xaf,0x37 +,0x0d,0x1a,0x1a,0x07,0x0e,0x9e,0xa1,0x11,0x0e,0x21,0x17,0x0e,0xbf,0x8e,0x34,0x11,0x29,0x0b,0x0b,0xa4,0x97,0x18,0x03,0x0b,0x1a,0x51,0xa7,0x12,0x00,0x07,0x34,0xae +,0x1d,0x1d,0x2a,0x0a,0x0e,0x97,0x82,0x8e,0x0d,0x0c,0x1e,0xab,0x85,0x81,0xb7,0x16,0xaf,0x8e,0x8a,0x84,0x85,0xae,0xb4,0x8b,0x86,0x87,0x82,0x81,0x8c,0x98,0x8b,0x80 +,0x87,0x8c,0x8d,0x96,0xbd,0x9b,0x80,0x90,0x3b,0xe7,0xad,0x1f,0xb7,0x91,0x1f,0x04,0x07,0x0f,0x11,0xce,0x2c,0x05,0x00,0x02,0x09,0x12,0x17,0x0c,0x02,0x00,0x04,0x2b +,0x38,0x08,0x03,0x06,0x03,0x0f,0xa6,0x9f,0x0c,0x14,0xdc,0x2c,0xa6,0x91,0xa5,0x1b,0xaa,0x8e,0x8f,0x86,0x82,0x8f,0x2e,0x9e,0x84,0x85,0x87,0x8e,0x99,0x20,0xdd,0x89 +,0x82,0x9b,0x47,0xac,0x42,0xc4,0x8b,0x84,0xd3,0x48,0xa9,0xb3,0x94,0x83,0x8c,0x17,0x1f,0x9e,0x98,0x92,0x91,0x77,0x0d,0x1c,0x92,0x8a,0xc2,0x13,0x0e,0x0a,0x0a,0xb6 +,0x8c,0x1b,0x02,0x04,0x07,0x0a,0x67,0xaa,0x08,0x00,0x0b,0x16,0x1f,0x9e,0xab,0x0d,0x04,0x17,0xd7,0x6d,0xb0,0xa5,0x1f,0x0e,0x49,0x90,0xa2,0x18,0x1d,0x1d,0x1a,0xb5 +,0x88,0xc2,0x0a,0x0e,0x32,0xbf,0x90,0x8a,0x1d,0x08,0x11,0xa1,0x93,0x8c,0x8b,0xac,0x2b,0x96,0x82,0x82,0x85,0x88,0x88,0x92,0x86,0x80,0x80,0x89,0x95,0x87,0x88,0x8b +,0x85,0x97,0x1b,0x1a,0x4f,0x2f,0x34,0x3e,0x0d,0x00,0x04,0x0e,0x0e,0x0a,0x06,0x02,0x00,0x00,0x0c,0x2d,0x0c,0x02,0x02,0x03,0x08,0x27,0x6b,0x15,0x14,0x22,0x2a,0x2a +,0xa6,0xb9,0x15,0x0f,0x2b,0xae,0x93,0x96,0x53,0x0b,0x11,0x9e,0x8b,0x8b,0x91,0x99,0xac,0xb0,0x96,0x87,0x8a,0x98,0x9d,0xa6,0x9f,0x8a,0x84,0x8f,0xb4,0x9d,0x91,0x89 +,0x82,0x84,0x92,0x6c,0xb9,0xa7,0x99,0x8e,0x98,0x30,0x1a,0xd9,0xb2,0x3a,0x1f,0x15,0x12,0x17,0xd7,0xa9,0x46,0x0f,0x0e,0x13,0x16,0xb2,0x9a,0xf6,0x0e,0x09,0x09,0x12 +,0xbc,0x9c,0x1e,0x0c,0x1b,0x3b,0x2c,0x1c,0x24,0x0e,0x08,0x16,0xb6,0xb1,0x33,0x15,0x0a,0x06,0x10,0xc3,0xbf,0x4b,0x2c,0x25,0x22,0x29,0xfa,0x2e,0x17,0x1f,0xb9,0xbb +,0xac,0x9f,0xd0,0x1a,0x3b,0x8e,0x88,0x85,0x87,0x8a,0x98,0x92,0x8b,0x86,0x83,0x84,0x86,0x8d,0x8b,0x85,0x85,0x8a,0x8d,0x8b,0x88,0x86,0x83,0x90,0x2b,0x13,0x23,0x4a +,0x3f,0xd3,0x20,0x07,0x04,0x0b,0x12,0x17,0x10,0x0e,0x05,0x05,0x0d,0x0f,0x0a,0x05,0x07,0x07,0x09,0x0b,0x0e,0x06,0x05,0x04,0x0d,0x1e,0x49,0xa8,0x2b,0x18,0x19,0x2c +,0x2d,0xb8,0x9c,0xa9,0x3d,0xaf,0x99,0x96,0x9d,0x93,0x90,0x8d,0x87,0x85,0x88,0x98,0xba,0x3d,0x9c,0x87,0x84,0x8e,0xb2,0xc9,0xd4,0x4e,0x90,0x88,0x8a,0x9d,0x9f,0x93 +,0x9d,0xab,0xb7,0x7e,0x74,0xb8,0x9c,0xa8,0x36,0x1f,0x15,0x3f,0xbc,0xa3,0x9e,0xa8,0xc3,0x1b,0x0c,0x10,0x28,0xce,0x1e,0x19,0x12,0x0b,0x0f,0x16,0x27,0x1a,0x1b,0x1e +,0x1d,0x26,0x1e,0x0c,0x03,0x0d,0x31,0x3e,0x2e,0x14,0x0b,0x06,0x12,0xb0,0xab,0xb5,0x3a,0x39,0x2d,0x24,0xcd,0xb1,0xb8,0xa9,0xa8,0xa6,0xb1,0xaa,0x30,0x27,0xb5,0x94 +,0x8a,0x8d,0x88,0x89,0x94,0xa3,0x9b,0x89,0x87,0x85,0x89,0x8f,0x8f,0x8d,0x82,0x82,0x83,0x84,0x86,0x87,0x8b,0x8f,0xd2,0x1c,0x30,0xaf,0xaf,0x4b,0x1d,0x06,0x01,0x09 +,0x12,0x14,0x0f,0x0d,0x05,0x00,0x02,0x03,0x05,0x07,0x08,0x09,0x05,0x08,0x09,0x08,0x0e,0x1f,0xbd,0xe1,0xbe,0xbd,0x17,0x09,0x0e,0xb4,0x99,0x99,0xa5,0xb2,0x35,0x1a +,0xb8,0x92,0x87,0x8c,0x9c,0x9e,0x9f,0xb3,0xb1,0xa4,0x94,0x8e,0x91,0x91,0x8d,0x9a,0x49,0x96,0x85,0x86,0x8c,0x89,0x8a,0x9f,0x31,0x3a,0xab,0x8b,0x87,0x9a,0x7c,0xcb +,0x36,0x1c,0x5c,0xbe,0xae,0x30,0x39,0xa1,0x36,0x05,0x09,0x24,0xab,0xb6,0xb8,0xa9,0x0d,0x03,0x08,0x22,0x2d,0x3b,0x28,0xc8,0x42,0x07,0x04,0x06,0x37,0x8a,0x8d,0x07 +,0x0a,0x8d,0x0b,0x17,0x9f,0xe4,0xa7,0x1d,0xad,0x0b,0x03,0x01,0x02,0x2a,0x09,0x0e,0x0c,0x01,0x04,0x00,0x11,0x2e,0x47,0x2f,0x3b,0x9b,0x0f,0x02,0x0d,0x8f,0x80,0x82 +,0x83,0x85,0x89,0x89,0x81,0x84,0x80,0x80,0x80,0x81,0x80,0x89,0x3f,0x91,0x80,0x80,0x80,0x82,0x81,0x8a,0x35,0x31,0x88,0x83,0x84,0x89,0x89,0x8b,0x11,0x09,0xc1,0x8c +,0x8e,0x3c,0x53,0x13,0x08,0x00,0x03,0x27,0x26,0x1d,0x07,0x10,0x06,0x00,0x01,0x00,0x10,0x0a,0x01,0x03,0x00,0x00,0x00,0x04,0x10,0x11,0x13,0x0e,0x07,0x00,0x00,0x00 +,0x09,0x37,0xa3,0x23,0x3e,0x21,0x03,0x04,0x2e,0x88,0x88,0x95,0x92,0x89,0x36,0x0f,0xb3,0x84,0x80,0x80,0x80,0x80,0x84,0x99,0xa3,0x86,0x80,0x81,0x80,0x81,0x80,0x89 +,0x98,0x86,0x80,0x80,0x80,0x81,0x80,0x8c,0x37,0xc8,0x84,0x80,0x80,0x80,0x81,0x81,0x9e,0x1a,0xcf,0x86,0x83,0x87,0x8f,0x93,0x24,0x03,0x03,0xaf,0x91,0x7a,0x1b,0x09 +,0x09,0x00,0x01,0x00,0x12,0x1e,0x07,0x03,0x04,0x00,0x00,0x00,0x0d,0x2c,0x0d,0x05,0x04,0x03,0x00,0x00,0x01,0x22,0x3b,0x0d,0x06,0x07,0x00,0x01,0x00,0x0c,0x5c,0x11 +,0x0c,0x09,0x07,0x01,0x00,0x0b,0xb8,0x8c,0x8f,0x9a,0x95,0x1a,0x07,0x19,0x89,0x80,0x83,0x80,0x83,0x81,0xae,0x24,0x89,0x80,0x80,0x80,0x83,0x81,0x95,0x2d,0xbd,0x85 +,0x80,0x81,0x80,0x81,0x82,0x9b,0x2d,0x90,0x82,0x80,0x82,0x86,0x8b,0xeb,0x1f,0x2d,0x8b,0x80,0x83,0x84,0x8c,0xa0,0x0e,0x03,0x22,0x99,0x8e,0x8f,0x91,0x99,0x1b,0x08 +,0x0a,0x97,0x80,0x86,0x8c,0x9a,0xa1,0x1a,0x03,0x1e,0x89,0x82,0x83,0x8c,0x9b,0x35,0x11,0x1c,0x5f,0x8a,0x87,0x89,0x8e,0xa8,0x1e,0x09,0x23,0x8d,0x84,0x86,0x84,0x8f +,0x32,0x08,0x09,0x3e,0x8d,0x93,0xb3,0xce,0x25,0x0b,0x00,0x01,0x0b,0x2c,0x2c,0x0e,0x02,0x01,0x00,0x01,0x00,0x09,0x19,0x0d,0x0a,0x00,0x00,0x00,0x00,0x01,0x07,0x0f +,0x0a,0x02,0x00,0x00,0x00,0x00,0x03,0x0f,0x0b,0x0c,0x03,0x00,0x00,0x00,0x01,0x0a,0x18,0x0f,0x05,0x01,0x00,0x00,0x00,0x07,0xa0,0xa9,0x36,0x1b,0x0d,0x0c,0x04,0x11 +,0x90,0x81,0x80,0x82,0x8b,0x95,0x9c,0x90,0x85,0x80,0x80,0x80,0x80,0x83,0x88,0x89,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x85,0x89,0x83,0x80,0x80,0x80,0x80,0x81,0x85 +,0x98,0x99,0x82,0x80,0x80,0x80,0x8b,0xa0,0xb6,0xb4,0xa5,0x8b,0x80,0x81,0x85,0x97,0x27,0x20,0x27,0xa1,0x8a,0x87,0x8a,0xa3,0x17,0x08,0x05,0x0d,0x1c,0x9d,0x9b,0x26 +,0x0e,0x02,0x02,0x00,0x02,0x11,0x20,0x15,0x0a,0x05,0x04,0x00,0x02,0x00,0x0f,0xa5,0x2c,0x0f,0x03,0x01,0x01,0x00,0x09,0x23,0xe3,0x23,0x07,0x02,0x02,0x03,0x06,0x08 +,0x24,0x1f,0x22,0x12,0x01,0x03,0x00,0x11,0xa8,0xa9,0xe1,0x29,0x1d,0x0e,0x06,0x0d,0x22,0x8f,0x8b,0xb9,0x45,0x24,0x22,0x11,0x11,0xa2,0x8f,0x8e,0xaa,0x12,0x10,0x0e +,0x0f,0x18,0xa1,0x82,0x86,0x8e,0x2a,0x08,0x14,0xd0,0x8b,0x83,0x86,0x8b,0x98,0xef,0x1d,0x1d,0xba,0x93,0x86,0x83,0x88,0x8f,0x7c,0x19,0x14,0xc4,0x86,0x83,0x89,0x98 +,0x4e,0x2d,0x3b,0x3e,0x50,0x89,0x80,0x85,0x8f,0x2f,0x33,0x40,0x28,0xa5,0x89,0x84,0x8a,0x34,0x0f,0x0c,0x0d,0x1c,0x58,0x8c,0x96,0xda,0x12,0x05,0x0c,0x0d,0x4a,0x8f +,0xa6,0x27,0x21,0x1f,0x18,0x0c,0x0e,0x47,0x87,0x88,0xa7,0x3c,0x1b,0x1b,0x14,0xdd,0x88,0x83,0x89,0xb9,0x16,0x19,0x21,0x3d,0xb5,0x8d,0x82,0x89,0x8c,0xbf,0x1c,0x33 +,0xaa,0x8a,0x82,0x86,0x8b,0xa0,0x1d,0x12,0x2c,0x98,0x89,0x82,0x8f,0xba,0x29,0x1c,0x16,0x15,0xc1,0x93,0x99,0xb2,0x2e,0x16,0x0e,0x11,0x15,0x23,0x8a,0x86,0x97,0x39 +,0x0a,0x0f,0x1b,0x2d,0xa2,0x97,0xa7,0x56,0x0f,0x0d,0x18,0x31,0x4b,0x5b,0x9e,0xbf,0x3b,0x0f,0x0a,0x0e,0x1a,0x99,0x88,0x94,0xfe,0x20,0x13,0x15,0x30,0xd5,0x97,0x84 +,0x95,0x39,0x1e,0x21,0x4c,0x2b,0x3e,0x9a,0x98,0x9f,0x18,0x09,0x0f,0x13,0x1f,0x25,0x95,0x8b,0x9f,0xb1,0x0f,0x12,0xed,0x9e,0x89,0x8c,0x9e,0xcc,0x2b,0x2c,0x25,0x4c +,0xb4,0x90,0x87,0x9d,0xb1,0x2b,0x1a,0x10,0x0d,0x31,0xa2,0xd4,0x21,0x0d,0x0f,0x25,0x2b,0x19,0x1c,0x8f,0x99,0xce,0x2f,0x1a,0x31,0x24,0x3d,0x98,0x96,0xa2,0x43,0x1f +,0x1e,0x1c,0x29,0x31,0x96,0x9c,0x6d,0x2e,0x15,0x15,0x0f,0x26,0x9d,0x99,0x44,0x1f,0x2e,0xc7,0x43,0x2f,0x21,0x9d,0x8a,0xae,0xc9,0x34,0x27,0x27,0x23,0xae,0x93,0xa2 +,0x4f,0x18,0x14,0x1b,0x1a,0x1e,0x2d,0xa0,0x9b,0x99,0x9e,0x22,0x16,0x24,0xb9,0x94,0x9b,0xb7,0xaf,0xd6,0x26,0x1e,0x23,0x7e,0x8e,0x8f,0xa7,0xea,0x1f,0x15,0x0e,0x17 +,0x3d,0xac,0xb1,0x7a,0x19,0x20,0x2c,0x22,0x14,0xbf,0x88,0x8b,0x90,0x4c,0x17,0x13,0x26,0xb2,0x98,0x94,0x9a,0xba,0x34,0x1e,0x1f,0x17,0x1e,0x9d,0xa0,0xa5,0x67,0x1d +,0x13,0x0b,0x22,0xa0,0x93,0x9e,0x39,0x49,0x2e,0x29,0x21,0x36,0x8c,0x89,0x9c,0xae,0x3b,0x28,0x21,0x27,0xaf,0x98,0xa2,0x43,0x22,0x1c,0x18,0x16,0x19,0xb4,0x9f,0xaa +,0xb1,0x2a,0x14,0x0d,0x4a,0x97,0x8d,0x95,0xdb,0x5b,0x30,0x16,0x17,0x1f,0x97,0x85,0x8f,0x9a,0xe5,0x1c,0x0b,0x0c,0x24,0x9d,0x91,0xaa,0x1f,0x0f,0x0c,0x11,0x1f,0xb8 +,0x8b,0x87,0x8d,0xa6,0x1f,0x0c,0x15,0xec,0x9b,0x92,0x94,0x9a,0xab,0x29,0x19,0x1b,0x1d,0xa2,0x98,0x9e,0xb2,0x1f,0x0c,0x0b,0x19,0xf2,0xa2,0x9e,0x5a,0x5f,0xb6,0x27 +,0x2e,0x2d,0xa2,0x8e,0x9a,0xae,0x31,0x23,0x31,0xbe,0x9e,0x93,0x92,0xcb,0x17,0x0e,0x0b,0x1f,0xc8,0x9e,0x93,0xb7,0x30,0x1a,0x0a,0x0a,0x2f,0x8e,0x88,0x8c,0xad,0x21 +,0x21,0x15,0x14,0x28,0x9c,0x84,0x87,0x98,0x2f,0x16,0x0e,0x17,0xce,0xa5,0x94,0x99,0x39,0x16,0x0a,0x0c,0x18,0x1e,0x9d,0x8b,0x8b,0x91,0xca,0x12,0x0f,0x3f,0xaa,0x9a +,0x9a,0xad,0xcf,0x25,0x1b,0x1f,0xdc,0x8f,0x8f,0xac,0x3c,0x24,0x13,0x0e,0x1e,0xae,0x9a,0xae,0x20,0x11,0x22,0x4f,0xb9,0x9e,0x8d,0x8e,0x95,0x45,0x10,0x0d,0x0f,0xa7 +,0x8a,0x89,0x91,0x43,0x16,0x12,0x0d,0x16,0x69,0x8f,0x8e,0xa1,0x3d,0x18,0x0e,0x08,0x12,0x9c,0x88,0x88,0x9c,0x27,0x13,0x0f,0x14,0x29,0x8d,0x88,0x8a,0x95,0x2f,0x13 +,0x0b,0x1c,0xa3,0x98,0x9a,0xab,0x26,0x1c,0x0f,0x0e,0x1d,0xa1,0x9a,0xb5,0xa4,0x4f,0x21,0x1a,0x24,0x98,0x8a,0x93,0x4c,0x18,0x14,0x1a,0x3e,0xa5,0x8d,0x8c,0x99,0xae +,0x1c,0x0e,0x0f,0x1e,0x99,0x8f,0x97,0xbe,0x18,0x0b,0x04,0x12,0x67,0x90,0x85,0x8e,0x9d,0x52,0x0f,0x0a,0x16,0x9f,0x87,0x89,0xa3,0x26,0x15,0x10,0x1a,0x2e,0x9b,0x89 +,0x92,0xa2,0x2a,0x09,0x08,0x0e,0xc6,0x91,0x8e,0x9a,0x5f,0x1a,0x0a,0x0e,0x69,0x8e,0x88,0x96,0xbb,0xd1,0x22,0x17,0x1b,0xaf,0x8d,0x90,0xaa,0x1f,0x16,0x0e,0x12,0x2f +,0x97,0x8b,0x93,0xde,0x19,0x14,0x0b,0x1a,0x96,0x8d,0x8d,0x9d,0x1f,0x19,0x0f,0x0f,0x59,0x8b,0x86,0x8c,0xa0,0x2d,0x0f,0x04,0x0b,0xae,0x89,0x87,0x9a,0x1e,0x0c,0x06 +,0x06,0x18,0x8d,0x82,0x8a,0x9c,0x23,0x0e,0x0b,0x14,0xa9,0x89,0x87,0x8e,0xbd,0x16,0x07,0x06,0x1f,0x8f,0x87,0x8b,0x97,0x42,0x0f,0x06,0x0a,0x63,0x93,0x95,0xba,0x3b +,0x1f,0x15,0x17,0x2d,0x91,0x8b,0x96,0xa6,0x2a,0x14,0x13,0x20,0x9f,0x8b,0x8b,0x96,0x3e,0x0b,0x06,0x09,0x36,0x8d,0x89,0x92,0xba,0x1d,0x07,0x07,0x1e,0x97,0x87,0x89 +,0xa3,0x47,0x11,0x05,0x0a,0x3d,0x89,0x85,0x86,0x90,0x27,0x09,0x04,0x10,0xa6,0x89,0x85,0x90,0xb1,0x0d,0x03,0x07,0x1f,0x9e,0x8b,0x83,0x89,0xac,0x09,0x01,0x09,0x38 +,0x92,0x8f,0x9f,0xd1,0x24,0x1f,0x3b,0x9e,0x8d,0x91,0x9f,0xb9,0x1f,0x0a,0x04,0x19,0x93,0x85,0x88,0xad,0x14,0x07,0x09,0x14,0xb7,0x9c,0x99,0x93,0x93,0xbf,0x0e,0x07 +,0x17,0x93,0x88,0x87,0x9d,0x47,0x16,0x0a,0x13,0xa3,0x99,0x96,0x8e,0x9f,0x1b,0x04,0x03,0x07,0xa1,0x83,0x81,0x8d,0xdd,0x0d,0x08,0x0d,0x2d,0xa7,0xa8,0x92,0x8b,0x91 +,0x29,0x0b,0x18,0xaf,0x9e,0xa1,0xc3,0x3e,0x0f,0x08,0x1b,0x96,0x8e,0x9e,0xab,0xa2,0xae,0x12,0x07,0x14,0xb3,0x8a,0x8a,0x9c,0x2b,0x0b,0x07,0x11,0x9c,0x8e,0x90,0x9a +,0x9e,0x6f,0x11,0x0c,0x25,0x9e,0x8d,0x99,0x3a,0x29,0x0c,0x08,0xb5,0x88,0x89,0x9a,0x5b,0x4b,0x1e,0x09,0x04,0x11,0xae,0x94,0x89,0x85,0x94,0x52,0x11,0x13,0x24,0x3f +,0xa9,0xac,0x9a,0xa3,0x1a,0x15,0x1c,0x34,0xa3,0x9e,0x9e,0xd3,0x17,0x06,0x0f,0x94,0x88,0x8d,0x9a,0xaa,0x22,0x0c,0x0b,0x2f,0x96,0x90,0x96,0xaf,0x2f,0x1a,0x10,0x25 +,0xad,0xbf,0x9f,0x9c,0xc2,0x24,0x1c,0x23,0xaf,0xa6,0x9a,0x9b,0xab,0x3e,0x15,0x17,0x2b,0x9b,0x94,0x8d,0x9f,0x5f,0x32,0x0e,0x0a,0x1a,0x69,0xaa,0xb5,0xb5,0x3e,0x1a +,0x12,0x1f,0x9d,0x9a,0x99,0x99,0x99,0xbb,0x18,0x1e,0x45,0xe6,0xa6,0xb3,0xe7,0x2b,0x27,0x25,0xc6,0x9d,0x9d,0xa5,0xda,0x33,0x21,0x12,0x09,0x16,0x99,0x83,0x8c,0x8f +,0xaf,0x1b,0x08,0x14,0xa2,0xa0,0xba,0xc9,0xab,0xc6,0x15,0x0f,0x3a,0xaa,0x98,0xa3,0xd8,0x13,0x0a,0x17,0x95,0x86,0x8d,0x99,0xbc,0x5a,0x10,0x08,0x0c,0x2e,0x8e,0x86 +,0x96,0xb8,0x2f,0x1a,0x0d,0x0f,0x53,0xab,0xa5,0xa8,0x99,0x92,0xde,0x1f,0x29,0xad,0x9d,0xae,0xc9,0x2a,0x14,0x14,0x33,0x96,0x95,0xb4,0xbb,0x4a,0x21,0x0e,0x15,0x18 +,0x3a,0x95,0x9a,0xaa,0x2c,0x1d,0x1f,0x38,0x9c,0x94,0x99,0xa1,0xe3,0x5b,0x20,0x11,0x1f,0xae,0x95,0xb3,0xcf,0xbf,0x27,0x1d,0x24,0x9f,0x93,0x99,0x99,0x9f,0x28,0x09 +,0x05,0x14,0xa8,0x8c,0x8b,0x92,0xa9,0x24,0x0e,0x0a,0x22,0x9e,0xa6,0xd7,0x41,0xa1,0xa8,0x29,0x36,0xbe,0x96,0x98,0xe7,0x47,0x29,0x0e,0x10,0x2e,0xa0,0x9f,0x9d,0x96 +,0x9f,0xc8,0x11,0x0d,0x1b,0xb1,0x96,0x9e,0xa7,0x3c,0x1a,0x15,0x1c,0x34,0x93,0x8b,0x8f,0x95,0x2c,0x0d,0x0b,0x18,0xb3,0x93,0xa9,0xdf,0x2d,0x1c,0x1c,0x22,0x9b,0x8f +,0x96,0x9d,0xad,0x3e,0x16,0x09,0x19,0x66,0x95,0x8e,0xa1,0xbb,0x17,0x0e,0x16,0x2c,0xa5,0x91,0x93,0x95,0xac,0x1b,0x0e,0x0c,0x36,0x91,0x8f,0x92,0xa5,0x58,0x19,0x09 +,0x11,0x6b,0x93,0x93,0xa4,0x4a,0x13,0x0d,0x13,0x38,0x92,0x8a,0x8d,0x97,0xde,0x18,0x0a,0x09,0x24,0xcb,0x8f,0x8b,0x8f,0x9b,0x1a,0x0a,0x0e,0xb3,0x8d,0x8e,0xa8,0x26 +,0x12,0x0c,0x0b,0x25,0x9c,0x87,0x88,0x98,0xaa,0x17,0x0f,0x0f,0x2b,0x9e,0x9f,0xa0,0xb3,0x23,0x14,0x0d,0x1e,0x96,0x8c,0x8a,0x9f,0xcd,0x28,0x0d,0x0d,0x1a,0xa7,0x8d +,0x92,0xa4,0xb6,0x2a,0x18,0x0c,0x19,0xa5,0x8f,0x8e,0xa4,0x2b,0x0e,0x08,0x13,0xa0,0x8a,0x87,0x91,0xd0,0x20,0x0e,0x0b,0x19,0xa9,0x8d,0x8d,0xae,0x59,0x1b,0x0f,0x14 +,0x17,0xa5,0x91,0x97,0x9f,0x31,0x19,0x14,0x14,0xeb,0x9f,0x97,0x94,0xa2,0xa8,0x3d,0x1e,0x1f,0x48,0x9e,0x9b,0xad,0x3f,0x1d,0x12,0x12,0x0f,0x3d,0x98,0x90,0x95,0xae +,0x6a,0xda,0xda,0x3b,0x34,0x44,0xc1,0x54,0x54,0x53,0x24,0x27,0x4c,0xa5,0x9b,0xa5,0xa7,0xd3,0x57,0x2c,0x18,0x1b,0x6a,0xaa,0xae,0xc9,0x58,0xe6,0xd4,0x38,0x35,0xc2 +,0xba,0xaf,0x34,0x63,0xb0,0x3b,0x41,0x44,0xbf,0x9e,0xa5,0xb4,0xd5,0x25,0x21,0x1e,0x41,0xd5,0x5e,0xb1,0xad,0x8f,0x9a,0x1f,0x10,0x0d,0x37,0x9c,0xa3,0xa6,0x4f,0x24 +,0x1d,0x13,0x47,0x9f,0x9c,0x97,0x9b,0x9b,0xbe,0x26,0x19,0x1f,0xb4,0xad,0xad,0xa7,0x2f,0x1a,0x0d,0x13,0xc9,0xb0,0x94,0x97,0x8f,0x99,0x23,0x0d,0x0a,0x2e,0xab,0xa0 +,0x9a,0xa9,0xac,0x34,0x14,0x1b,0x2b,0xa2,0x95,0x8e,0x96,0x21,0x0d,0x08,0x11,0xaf,0x9a,0x8f,0x92,0xa4,0x5a,0x16,0x1b,0x3f,0xcb,0x9d,0x9d,0xa4,0xa9,0x1b,0x0e,0x10 +,0x2f,0x97,0x8e,0x8d,0xa6,0x24,0x10,0x09,0x14,0x57,0xa3,0x93,0x91,0x98,0xba,0x1d,0x17,0x23,0xbf,0x9e,0x95,0xa5,0xc9,0x18,0x08,0x0d,0x1d,0x9a,0x8a,0x8b,0x90,0xc6 +,0x25,0x0f,0x0d,0x1d,0x63,0x96,0x97,0xa7,0x3d,0x19,0x16,0x19,0xe8,0x91,0x8e,0x8e,0x99,0x3e,0x18,0x0a,0x0f,0x34,0x93,0x8b,0x9e,0xba,0x22,0x12,0x17,0x1a,0xbc,0x96 +,0x97,0x9f,0x6f,0x37,0x18,0x0d,0x1a,0xc6,0x8e,0x8e,0x9f,0x35,0x14,0x1c,0x24,0xaa,0x92,0x9e,0xa0,0xbb,0x26,0x1e,0x11,0x1a,0xba,0x9b,0x8d,0x99,0xb6,0x22,0x0d,0x0f +,0x16,0xe6,0x9e,0x9b,0x98,0xbf,0xec,0x34,0x26,0xae,0x9e,0x97,0x9f,0x69,0x20,0x0f,0x15,0x1a,0x3b,0x9c,0x97,0x92,0xa4,0xd9,0x26,0x16,0x24,0x2e,0xb0,0x9a,0xb1,0x48 +,0x32,0x24,0x28,0x22,0x48,0xac,0x9e,0x9b,0xae,0xa7,0x44,0x1e,0x1e,0x32,0xae,0xa5,0xc5,0x34,0x2c,0x2f,0x3e,0x36,0xa8,0x9e,0xac,0xc8,0x2a,0x3f,0x71,0x41,0x2b,0x35 +,0xae,0xa8,0xa6,0xb7,0x4a,0x44,0x32,0x2f,0xef,0xb1,0xb6,0x45,0x39,0x2f,0x42,0x3d,0x3c,0xbf,0xfb,0xa9,0xaa,0xd0,0x60,0x2c,0x1e,0x26,0xae,0xa3,0xb0,0xe0,0x44,0x38 +,0x46,0x4e,0xa5,0x9b,0x9c,0xb6,0x29,0x25,0x19,0x1d,0x21,0x2f,0xbf,0xaf,0xa3,0x98,0x9a,0xa9,0x26,0x1b,0x1f,0x2b,0xa8,0xac,0xc7,0x2b,0x21,0x31,0x76,0xb0,0xa4,0xa3 +,0x9c,0xa6,0x3f,0x24,0x1b,0x29,0x34,0xb4,0x9f,0xa4,0xdc,0x1c,0x1b,0x30,0xdf,0xb4,0xaa,0xb9,0xa1,0xa9,0xc6,0x2a,0x1c,0x2e,0x6c,0xa7,0xc9,0xdc,0xc4,0xee,0x59,0x1f +,0x31,0xa4,0x9f,0xa1,0xc5,0x2f,0x1e,0x15,0x21,0xbb,0x8e,0x90,0xbd,0x1f,0x19,0x1f,0x3d,0xbf,0xb5,0xa8,0xaf,0xb3,0xd0,0x3c,0x26,0x28,0xdc,0x9e,0x9d,0xaf,0x2b,0x1a +,0x1d,0x20,0xfc,0xb2,0xad,0xbb,0xcf,0xac,0xb4,0x5a,0x2c,0x44,0xa8,0x9d,0xa0,0x52,0x1a,0x19,0x14,0x20,0xc5,0xa1,0x92,0x9a,0x9e,0x3a,0x19,0x19,0x1f,0xab,0x9a,0x9f +,0xb6,0x17,0x16,0x21,0xc2,0x93,0x9b,0xa7,0x31,0x4a,0xbc,0x2e,0x20,0x1e,0xb3,0x97,0xa0,0xb3,0x1e,0x18,0x1f,0x32,0xaf,0xb1,0xa7,0xba,0xb8,0xa4,0xdd,0x36,0x1f,0x26 +,0xc4,0xad,0xa6,0x7d,0x22,0x1f,0x32,0x9e,0x95,0x9b,0xa6,0x5d,0x3c,0x19,0x0f,0x17,0x45,0x92,0x99,0xba,0x2a,0x19,0x1f,0x32,0x9d,0x9b,0xad,0xdb,0x31,0xbd,0x5e,0x36 +,0x2d,0x3c,0x9e,0x9b,0xa2,0x54,0x19,0x16,0x21,0xac,0x98,0xa4,0x43,0x2a,0xe6,0x3f,0x1d,0x1f,0x3d,0x9c,0x9c,0xac,0x3e,0x1f,0x1f,0x1f,0xb9,0xa0,0x94,0xa3,0xd8,0xde +,0x46,0x3e,0x2d,0x48,0xb7,0xa1,0xaf,0x25,0x10,0x0f,0x2c,0x93,0x93,0x9d,0xdb,0x25,0x28,0x1e,0x3e,0x40,0xbc,0xac,0xc1,0xb1,0x70,0x31,0x22,0x2e,0xa8,0x97,0x99,0xaa +,0x2e,0x28,0x2c,0x4e,0xaf,0xb4,0xb0,0xca,0xbf,0x27,0x15,0x12,0x1e,0xb5,0x99,0x94,0xa3,0x4f,0x1f,0x13,0x1b,0x54,0xa0,0x9c,0xaa,0xb2,0x3a,0x24,0x2e,0xb2,0x9f,0x90 +,0x92,0xc6,0x1e,0x0f,0x18,0x39,0xbc,0xa4,0xb6,0x66,0x2f,0x2f,0x2f,0x25,0x2e,0xb7,0x9c,0x9b,0xaf,0x2a,0x17,0x12,0x32,0x99,0x8c,0x99,0x34,0x17,0x1c,0x3e,0xa7,0xac +,0xb8,0x9a,0x99,0xac,0x1e,0x0f,0x1f,0x47,0xa6,0xa8,0xaf,0x48,0x15,0x10,0x1e,0xbd,0xb0,0xb2,0x9f,0x9d,0xb3,0x38,0x1a,0x1e,0xbb,0x92,0x96,0xbb,0x1e,0x18,0x33,0xa5 +,0x9c,0xbb,0xdc,0xbf,0xaa,0xe7,0x1b,0x10,0x19,0xb8,0x9f,0xac,0x42,0x1a,0x1a,0x4f,0x9f,0x9e,0xaa,0xcc,0x52,0xaf,0xaf,0x6c,0x34,0xf6,0xab,0xa8,0xa4,0x42,0x0f,0x0f +,0x37,0x9c,0x9d,0xb7,0x51,0xba,0xa9,0x30,0x22,0x15,0x1c,0xad,0x9d,0xa9,0x29,0x1b,0x2e,0x9d,0x8d,0x99,0x45,0x16,0x14,0x2e,0x36,0xb7,0x9c,0x8f,0x97,0xaa,0x14,0x0d +,0xcc,0x8f,0x97,0xaf,0x2e,0x0c,0x1d,0x1b,0x14,0x34,0xa2,0x90,0x97,0x32,0x0d,0x19,0x6c,0x1b,0x9f,0x87,0x85,0x8d,0xa6,0x62,0x11,0x1e,0x2c,0xba,0x24,0x0a,0x0f,0x34 +,0x28,0x13,0x46,0xa4,0x99,0x8e,0x8d,0x9a,0xda,0x33,0xb9,0xe8,0x26,0x4e,0x93,0x68,0x0a,0x0c,0x1c,0xb7,0x94,0x92,0xb6,0x2f,0x34,0x35,0x2f,0x1a,0x2c,0x89,0x86,0x96 +,0x1b,0x09,0x04,0x13,0x9e,0x94,0x8d,0x8f,0x9c,0xee,0x17,0x0a,0x44,0x87,0x85,0x9c,0x2c,0x0b,0x04,0x1a,0xa7,0xa7,0xb2,0xb3,0xa3,0xae,0x17,0x0e,0x2e,0xad,0x32,0xad +,0x99,0xa3,0x9e,0x9e,0xa2,0xaf,0xa6,0xb9,0x46,0x16,0x0b,0x16,0x2a,0x29,0x41,0xa1,0xaa,0xa2,0xac,0x36,0xbd,0x9e,0x9d,0x94,0xb4,0x1c,0x1f,0x55,0x26,0x10,0x1f,0x49 +,0xae,0xa1,0xcf,0x2a,0x1e,0x34,0x98,0x8e,0xaa,0x39,0xa0,0x9f,0x1d,0x1b,0x20,0x17,0x2d,0xb8,0xaa,0xc1,0xac,0x9c,0xa3,0x1f,0x16,0xab,0x8c,0x95,0x7a,0x28,0x0e,0x10 +,0x2c,0xa6,0xa1,0x5f,0x25,0x25,0x3d,0x48,0xa4,0x98,0xbc,0x27,0x2a,0x39,0xb8,0x9f,0x99,0x93,0x99,0xb7,0x2d,0x10,0x0b,0x1d,0xb4,0xa0,0x39,0x1f,0x2a,0x2c,0x6a,0xae +,0x9a,0x92,0x9d,0xba,0x40,0x16,0x0f,0xc7,0x8f,0x9e,0x28,0x1a,0x2b,0xa9,0xad,0xb2,0x3d,0x1f,0x25,0xce,0xa3,0x4a,0xd8,0xa5,0xa5,0xb4,0xa9,0xdc,0x1e,0x19,0x1f,0x37 +,0x3d,0xbf,0x9b,0x9c,0x30,0x27,0x34,0x39,0x36,0xa2,0x90,0x99,0x49,0x1d,0x20,0x29,0x5e,0x79,0xcb,0x3c,0x2f,0xb9,0x54,0x19,0x17,0x48,0x95,0x8d,0x8f,0x9d,0xab,0xb6 +,0x3d,0x2d,0x18,0x0e,0x28,0xb0,0x77,0x1e,0x0f,0x19,0x2b,0xa8,0x92,0x8a,0x89,0xa4,0x2d,0x19,0x15,0x27,0x9e,0x90,0xc5,0x1a,0x15,0x14,0x2c,0xad,0x9b,0x99,0xa9,0x3b +,0x24,0x25,0x4e,0x96,0x8c,0x99,0xdd,0x2c,0x1e,0x15,0x12,0x1e,0x2c,0xd4,0xaa,0xa4,0xbe,0x26,0x3a,0xbc,0xb3,0xc2,0xb2,0xa7,0xa8,0x40,0x27,0x2a,0x35,0x7d,0xb7,0xa8 +,0xc3,0xac,0xb0,0xd5,0x2b,0x23,0x48,0xaf,0x9c,0x9f,0xaf,0xaf,0x5e,0x2f,0x1d,0x0e,0x14,0x2a,0xb5,0xd2,0x2c,0x26,0x28,0xc1,0xa2,0xa3,0x9c,0x97,0x97,0x9a,0xdb,0x22 +,0x29,0xbb,0xae,0xef,0x37,0x3d,0x3c,0x33,0x3b,0x2d,0x27,0x24,0x2e,0x28,0x26,0x6e,0xa5,0xa3,0xbd,0x4f,0x79,0xa3,0xa3,0xca,0xfd,0x55,0x4f,0x36,0x3e,0xd9,0xab,0x98 +,0x99,0xb4,0x25,0x13,0x1d,0xb6,0xa9,0xaf,0xc0,0xbb,0x3a,0x1b,0x15,0x12,0x24,0xa8,0xa4,0xd7,0x2b,0x24,0x36,0xaa,0x92,0x8d,0x8b,0x8d,0x9e,0x2c,0x0d,0x0d,0x1d,0x48 +,0xce,0x45,0x2f,0x2c,0x2f,0x23,0x29,0xcd,0x9f,0x99,0x9a,0xb5,0x4e,0x49,0xe8,0xd8,0x2f,0x2b,0x46,0xb1,0xae,0x45,0x2f,0x2a,0x2d,0xfa,0xea,0xc9,0xaa,0x9a,0x9e,0xd1 +,0x2a,0x1f,0x34,0xb8,0xbf,0xfe,0x41,0x25,0x1e,0x1f,0x30,0xa7,0x96,0x95,0xa1,0xc7,0x78,0xbb,0xa8,0xbc,0x45,0x3f,0x34,0x2e,0x1e,0x19,0x22,0x2c,0xd9,0x52,0x24,0x21 +,0x29,0xb8,0x9e,0x97,0x91,0x95,0x99,0xa7,0xc5,0x2e,0x1d,0x25,0x2b,0x29,0x1c,0x1c,0x2f,0xaa,0x9f,0xa8,0xaf,0xc8,0xb8,0xbb,0xc2,0xfd,0x51,0x66,0x5b,0x3f,0x47,0xd9 +,0xe6,0x29,0x18,0x21,0xbb,0x9e,0xa0,0xbf,0x47,0xcc,0xa3,0x9c,0xae,0x6f,0xd3,0xc7,0x5e,0x20,0x1f,0x37,0x3f,0x3a,0x2e,0x3a,0xb8,0xa2,0xa5,0xc1,0x27,0x24,0x50,0xa9 +,0x9f,0xa2,0xb4,0x27,0x1c,0x18,0x1e,0x30,0x41,0xb9,0xa8,0xaa,0xd2,0x45,0x66,0xbf,0xa6,0x97,0x91,0x99,0xbd,0x27,0x1a,0x1b,0x28,0x30,0x28,0x19,0x15,0x27,0xb5,0xa2 +,0x9f,0xa0,0x9f,0xa7,0xaa,0xbb,0x3f,0x44,0x53,0x42,0x2d,0x30,0x53,0xbc,0x48,0x2c,0x3d,0xf0,0xbe,0xce,0x58,0xdf,0x53,0xb5,0xa0,0xaf,0xbe,0xbc,0xbd,0x45,0x26,0x27 +,0x2e,0x29,0x20,0x20,0x48,0xa2,0x9b,0x9e,0xd1,0x22,0x26,0xb8,0xa1,0xa3,0x9b,0x9e,0xba,0x33,0x1d,0x1c,0x1e,0x1e,0x2c,0x65,0xc1,0xcf,0xca,0xae,0xaf,0xaa,0x9b,0x96 +,0x9d,0xbd,0x2f,0x1e,0x18,0x1c,0x3d,0xcf,0x64,0x2a,0x27,0x3e,0xda,0xb7,0xa6,0xaf,0xbe,0xb1,0xa9,0xaf,0xc6,0xc3,0x4f,0x34,0x2d,0xcc,0xca,0x46,0x4b,0x53,0xcf,0x4e +,0x38,0x33,0x3d,0x39,0xc9,0xbb,0x38,0x29,0x3d,0xaf,0xae,0xaf,0xb9,0x48,0x25,0x1a,0x19,0x2d,0xa3,0x91,0x8f,0xa2,0x30,0x22,0x3a,0xc8,0xae,0xa3,0xa2,0xee,0x26,0x1f +,0x1f,0x21,0x28,0x3e,0x6f,0x6e,0x3a,0x37,0x38,0x57,0xb3,0x98,0x8f,0x9b,0xaf,0xd6,0x4c,0x2c,0x1e,0x1f,0x27,0x30,0x5e,0xc8,0xb9,0xb6,0x3c,0x3a,0x4a,0xcf,0xb4,0xae +,0xb1,0xa8,0xab,0x42,0x37,0x41,0xca,0xbe,0x3b,0x1f,0x1a,0x1b,0x36,0xa8,0x9c,0x9f,0xb9,0xd1,0xcd,0x57,0x50,0x53,0xb8,0xae,0xa9,0xa8,0xb4,0x3e,0x1b,0x17,0x24,0xb0 +,0xab,0xbc,0xe0,0x3d,0x6b,0xac,0xa8,0xaa,0xa8,0xa4,0xb1,0x41,0x1c,0x11,0x17,0x2c,0xca,0xbd,0xc2,0xcb,0x5b,0x37,0x34,0x6e,0xa8,0x9c,0x97,0x9d,0xaa,0xee,0x2b,0x23 +,0x27,0x3f,0x43,0x24,0x1c,0x27,0xd6,0xac,0xa4,0xaf,0xc1,0xc0,0xde,0x6e,0x3f,0x51,0x4a,0xdc,0xbc,0xb6,0xaf,0xc1,0x61,0x2d,0x23,0x2c,0x30,0x4f,0xd4,0xaf,0xaa,0xbb +,0xd0,0x70,0xb4,0xbb,0x62,0x35,0x44,0xca,0xe1,0x31,0x2c,0x45,0xae,0xa7,0xd8,0x31,0x29,0x27,0x3d,0xa7,0x9d,0x9d,0xa1,0xa9,0xbb,0x37,0x1a,0x14,0x10,0x13,0x29,0xd3 +,0xaa,0xac,0xb5,0xac,0x9e,0x9d,0xab,0x58,0x3d,0xd6,0xbd,0xbc,0xcc,0x4b,0x42,0x3f,0x3e,0x37,0x21,0x1d,0x32,0x54,0xdb,0xbe,0xc8,0xa8,0x9e,0xa6,0xde,0x33,0x32,0x36 +,0x7d,0xb0,0xa5,0xb3,0x41,0x2f,0x3f,0x49,0x33,0x34,0x42,0x66,0xde,0xb3,0xba,0xb2,0xac,0xab,0xb0,0x57,0x29,0x1b,0x18,0x1d,0x40,0xca,0xb0,0xab,0xa7,0xae,0xcb,0x4f +,0x33,0x3e,0xbe,0xa0,0x9f,0xac,0xbb,0xc3,0x3f,0x21,0x12,0x14,0x21,0x5c,0xb2,0xbd,0xb7,0xaf,0xa7,0x9e,0x99,0x9f,0xbd,0x31,0x27,0x27,0x2b,0x2f,0x3b,0xca,0xb2,0xac +,0x57,0x1f,0x18,0x1e,0x39,0xaf,0x9e,0x9a,0xa4,0xb0,0xa9,0xa8,0xb6,0x38,0x26,0x21,0x2c,0x32,0x32,0x2f,0x48,0xad,0xa4,0xa7,0x56,0x2f,0x29,0x39,0x49,0xe5,0xbb,0xb8 +,0xa9,0xab,0xbf,0x2a,0x1c,0x19,0x27,0xd5,0xae,0xa9,0xb9,0xbd,0xbd,0xaa,0xa9,0xb6,0xbc,0xbe,0xcd,0x4b,0x49,0x37,0x2a,0x2d,0x38,0x59,0x70,0x30,0x1f,0x2d,0x50,0xb4 +,0xa8,0xa3,0x9e,0x9c,0x9c,0xb6,0x31,0x1d,0x1d,0x2a,0x43,0x57,0xcf,0xca,0xbf,0xc4,0x4d,0x30,0x26,0x3d,0xc2,0xdd,0xef,0xef,0xc1,0xab,0x9f,0xa0,0xb8,0x3b,0x1e,0x1f +,0x27,0x2e,0xda,0xb6,0xbf,0xb3,0xae,0xb3,0x6b,0x27,0x2a,0xd0,0xaa,0xad,0xd1,0x4c,0x6b,0xdd,0x5e,0x32,0x25,0x21,0x28,0x43,0xbc,0xa8,0xa7,0xa5,0x9b,0x97,0x95,0xad +,0x2d,0x21,0x1d,0x19,0x19,0x1f,0x2b,0xc8,0xac,0xad,0xe0,0x2a,0x1f,0x38,0xb6,0xa8,0xa2,0xa5,0xaf,0xb1,0xb1,0xad,0xce,0x2b,0x1c,0x21,0x47,0x73,0xd0,0xc9,0xb6,0xbc +,0xb9,0x4f,0x29,0x25,0x2d,0xf2,0xc6,0xb4,0xad,0xb4,0xbd,0xae,0xb4,0x38,0x1e,0x1e,0x2f,0x36,0x3d,0xbb,0xab,0xa8,0x9f,0x9e,0xa2,0xb7,0x32,0x2a,0x25,0x25,0x3e,0x47 +,0x5f,0xb1,0xab,0xac,0xd2,0x27,0x23,0x2e,0x4e,0xc3,0xba,0xad,0xaa,0xae,0xbf,0x66,0x38,0x2a,0x2a,0x29,0x2a,0x31,0xd7,0xb2,0xad,0xa4,0xac,0xd7,0x2f,0x30,0x35,0x4d +,0xc5,0xab,0xa7,0xae,0xac,0xaf,0xaf,0x3c,0x24,0x20,0x1a,0x1a,0x27,0x2d,0xba,0xa6,0x9f,0x9d,0xa6,0xaf,0x56,0x72,0x3c,0x4e,0x57,0x64,0xc1,0xba,0xaf,0xd5,0x37,0x26 +,0x20,0x34,0x49,0xdf,0xb5,0xaf,0xbd,0xc0,0xe8,0x61,0xc9,0x3b,0x25,0x15,0x1e,0xb4,0x9c,0xa7,0xd1,0xbf,0xaf,0x5b,0x2f,0xac,0x9d,0x97,0xac,0x1b,0x12,0x28,0x9f,0xa5 +,0xcc,0x2e,0x2e,0x1b,0x0f,0x23,0xaf,0x99,0xa3,0x46,0x20,0x2d,0x9d,0x8f,0x9f,0xad,0xb6,0xd2,0x2d,0x1c,0x4e,0xa8,0x9c,0xbc,0x16,0x0c,0x17,0xbd,0xa9,0xaf,0xa5,0xa5 +,0xc3,0x1f,0x2e,0x60,0xa4,0x9c,0x6f,0x27,0x1e,0x48,0x69,0xb2,0xab,0x9b,0xb6,0x21,0x21,0x23,0xbb,0x9b,0x96,0x3a,0x19,0x1a,0x6d,0xb2,0xa9,0xab,0xbd,0x4a,0x1d,0x1e +,0x22,0xaa,0x8f,0x94,0xca,0x2c,0x36,0x48,0xb7,0x9b,0x9a,0xaf,0x19,0x0e,0x10,0x27,0x9e,0xa0,0xce,0x20,0x1b,0x32,0xd2,0xa1,0x98,0x9f,0xb4,0x2f,0x1e,0x1f,0xa5,0x94 +,0x9d,0xcc,0x1b,0x1e,0x2b,0xed,0xa4,0xaa,0xc7,0x1c,0x17,0x28,0xa1,0x8f,0x9c,0x69,0x24,0x28,0x25,0x28,0xe7,0xa8,0xa3,0xf6,0x23,0x1e,0x25,0xb9,0xa0,0xa1,0xa9,0x47 +,0x32,0x1e,0x2a,0xc0,0xa2,0x9f,0x57,0x22,0x16,0x3f,0xa9,0xaa,0xcd,0x3b,0xb8,0xb7,0x3b,0x57,0xad,0x9d,0xa4,0x29,0x1b,0x23,0xb0,0xa8,0x43,0x2a,0x29,0x5e,0x35,0xdd +,0xac,0xae,0xcb,0x2f,0x28,0x2d,0xa6,0x95,0x9d,0xcb,0x30,0x4a,0xe2,0x34,0x4c,0x6a,0xf0,0x56,0x32,0x1d,0x20,0x4a,0xb2,0xb3,0xc3,0xa3,0xa7,0xcf,0x3e,0xc5,0xc5,0x55 +,0x33,0x38,0x65,0xbe,0xbd,0x33,0x2c,0xcf,0xaa,0xfd,0xb0,0xa5,0xad,0x38,0x1b,0x1f,0x32,0xad,0xc0,0x3d,0x32,0xce,0xa8,0x36,0x27,0xb7,0x9e,0xc8,0x3f,0x2f,0x33,0xa5 +,0x9e,0xba,0x2f,0x3c,0xab,0xb6,0x2f,0x24,0x28,0x2d,0x2d,0x5e,0x66,0xcd,0xa4,0xa4,0x55,0x2d,0xab,0x9f,0xba,0x4c,0x39,0xc2,0xb9,0x2d,0x1d,0x22,0xc3,0xa1,0xae,0x2d +,0x26,0xf6,0x42,0x37,0xf2,0xdf,0xb4,0xab,0x7e,0x2a,0x31,0xd8,0xbe,0xaa,0xcb,0xc2,0xb4,0x7a,0xc8,0xd6,0x66,0x3a,0x2c,0x22,0x33,0x9f,0x9c,0x69,0x2c,0x2e,0xbd,0xb5 +,0xc8,0xfe,0xc6,0xbd,0x2b,0x1f,0x1d,0x2f,0xc7,0xbf,0xb0,0xa4,0x9a,0xa7,0xc7,0xb6,0xb1,0xa5,0x42,0x1c,0x16,0x1d,0x47,0x3b,0x30,0x2e,0xbe,0x9f,0xac,0xc2,0xc7,0xa3 +,0x9e,0x31,0x15,0x1d,0xb5,0xa9,0xd0,0x4e,0xb8,0xa4,0xbb,0x51,0xc5,0xaa,0xb1,0x25,0x10,0x1a,0xb2,0xa4,0xcf,0x5a,0xae,0xa7,0xb0,0xc2,0x6c,0x3e,0x49,0x55,0x36,0x1f +,0x24,0x62,0xf4,0x59,0xda,0xab,0x9d,0x9e,0xbe,0x33,0x54,0xb9,0x39,0x17,0x17,0xea,0xa7,0xe4,0x29,0x5c,0xa3,0xb5,0xcb,0xc6,0xa9,0x9d,0xba,0x29,0x1e,0x3c,0x60,0x2c +,0x37,0xea,0xad,0xc4,0x41,0xba,0xca,0x4a,0xe2,0xbe,0x33,0x2a,0xdc,0x57,0x4e,0x40,0xd6,0xac,0xaa,0xaf,0x53,0x53,0xb4,0xb2,0x30,0x1d,0x40,0xcd,0x2b,0x24,0xc0,0x9b +,0xa2,0xbd,0x3a,0xbc,0xa2,0xc0,0x24,0x1e,0x3c,0x48,0x29,0x1f,0x3a,0xa2,0x9f,0xae,0xcd,0xd3,0xbc,0xc3,0x47,0x28,0x31,0x42,0x3a,0x31,0x33,0xad,0x9b,0x99,0xc7,0x29 +,0xd3,0xb6,0xc0,0x28,0x1d,0x69,0xb1,0xef,0x2b,0x40,0x9c,0x98,0xb3,0x20,0x25,0x42,0x3a,0x2b,0x23,0xfa,0xc6,0x32,0x2c,0x47,0x9d,0x94,0x99,0xb6,0x26,0x37,0x3f,0x5a +,0x62,0xde,0xb8,0x39,0x2b,0x26,0x4d,0x9e,0x9d,0x69,0x1b,0x26,0xbf,0xbe,0x40,0x34,0xcd,0x5b,0x31,0x31,0xd4,0x95,0x98,0xc6,0x23,0x26,0x77,0xdd,0x39,0xc9,0xa2,0xbf +,0x25,0x19,0x3d,0x98,0x94,0xad,0x28,0x1d,0x27,0x35,0xd8,0x57,0xcb,0xb4,0x34,0x1a,0x1f,0xa1,0x8f,0x93,0xae,0x26,0x23,0x33,0x52,0x3d,0x57,0xad,0xda,0x16,0x12,0xaf +,0x8c,0x94,0xb6,0x1d,0x27,0xb1,0xb5,0x35,0x28,0xba,0x57,0x1a,0x14,0x3f,0x8f,0x8d,0x9a,0x56,0x1f,0x27,0x2b,0x3d,0x5f,0xa7,0xa7,0x18,0x0e,0x1f,0x98,0x8a,0x91,0x57 +,0x1b,0x35,0x46,0x31,0x31,0x49,0xa8,0xcd,0x1a,0x15,0xd8,0x8f,0x8f,0xa2,0x2b,0x30,0x35,0x27,0x32,0xbd,0x9c,0x5a,0x11,0x0e,0x4a,0x8a,0x8a,0xae,0x19,0x1a,0x43,0xd0 +,0x49,0x57,0x9c,0x9f,0x27,0x0d,0x13,0x9c,0x8c,0x95,0x4f,0x22,0x2a,0x1c,0x1f,0x38,0x9a,0x93,0x2e,0x0f,0x18,0x98,0x89,0x98,0x2d,0x13,0x38,0xbe,0x46,0x2d,0x3e,0xa5 +,0x55,0x18,0x0f,0x3d,0x8d,0x8d,0x9e,0x2e,0x1f,0x2d,0x28,0x5a,0xa5,0x91,0xa3,0x14,0x06,0x15,0x8c,0x86,0x9d,0x1c,0x16,0xd5,0x69,0x2c,0x2c,0xab,0x9b,0x2b,0x0e,0x12 +,0xa0,0x8b,0x9d,0x4c,0x26,0x44,0x2e,0x2a,0xe5,0x9e,0x94,0x2e,0x0a,0x0d,0x9d,0x84,0x8b,0xb8,0x13,0x1c,0x37,0x37,0x5b,0x39,0xa6,0xae,0x17,0x0b,0x1b,0x91,0x89,0x90 +,0x38,0x1d,0x3f,0x24,0x21,0xd0,0x90,0x97,0x17,0x06,0x11,0x8d,0x82,0x94,0x2c,0x12,0x28,0x34,0x2d,0x3d,0xa6,0x9c,0x24,0x0b,0x0e,0xb4,0x8a,0x8d,0x9e,0x34,0x28,0x1b +,0x15,0x4d,0x9a,0x90,0xbd,0x0f,0x09,0x29,0x8a,0x86,0x9d,0x1b,0x14,0x31,0x3a,0x2f,0x69,0x9f,0xa5,0x1f,0x0a,0x18,0x90,0x87,0x94,0xd7,0x1e,0x28,0x1e,0x1d,0xad,0x8d +,0x95,0x1a,0x06,0x09,0xa2,0x85,0x8e,0x55,0x18,0x1e,0x2c,0x37,0xbe,0x9e,0x9d,0x36,0x14,0x12,0x3b,0x8e,0x8e,0xa2,0x28,0x20,0x35,0x4b,0xc1,0xa1,0x9a,0xe5,0x0d,0x07 +,0x23,0x8c,0x86,0x9d,0x19,0x10,0x2b,0x51,0xbf,0xab,0x9d,0xb1,0x1b,0x0c,0x14,0xa1,0x8b,0x93,0xb5,0x33,0x2b,0x29,0x2c,0xdf,0x9e,0x9d,0x24,0x0c,0x13,0xa6,0x8c,0x8e +,0xb4,0x17,0x17,0x39,0xc0,0xb5,0xb4,0xc0,0x26,0x10,0x15,0xb0,0x8b,0x8a,0x9d,0x27,0x1a,0x1e,0x2d,0xd1,0xb0,0xa8,0x5f,0x13,0x0f,0x40,0x8f,0x89,0x8f,0x3d,0x16,0x21 +,0x3a,0x39,0x68,0x61,0x2e,0x21,0x1b,0x3a,0x94,0x8b,0x97,0x5b,0x1c,0x1f,0x2c,0xf9,0xbe,0xc9,0x38,0x1f,0x14,0x1c,0x99,0x86,0x8b,0xae,0x1b,0x14,0x1d,0x44,0xaa,0xab +,0x65,0x1e,0x18,0x1d,0xb1,0x8e,0x8e,0xa7,0x23,0x19,0x28,0x4e,0xaf,0xb8,0x27,0x21,0x1f,0x20,0xb4,0x8c,0x8b,0xa1,0x27,0x18,0x23,0xc1,0xa0,0xb0,0x2a,0x17,0x15,0x1b +,0xee,0x96,0x8d,0x99,0x3b,0x20,0x35,0xbd,0xb8,0xba,0x50,0x1d,0x19,0x25,0x72,0xa1,0x98,0x96,0xb5,0x36,0x5c,0xec,0xbd,0xbd,0x27,0x17,0x13,0x1d,0x51,0xa0,0x94,0x99 +,0xb1,0x32,0x3d,0xb9,0xaa,0xb1,0x64,0x1d,0x14,0x16,0x49,0xaa,0x9b,0x90,0xa8,0x34,0x32,0xbc,0xc3,0xcb,0x4a,0x1c,0x10,0x18,0x2e,0xa2,0x95,0x98,0xb2,0x22,0x30,0xb0 +,0xa2,0xa4,0x45,0x19,0x13,0x1d,0xd9,0x9b,0x92,0x96,0xc5,0x1e,0x30,0xcc,0xb4,0xad,0x29,0x18,0x1d,0x26,0xcf,0xa5,0x9c,0xa3,0xb5,0x4e,0x37,0xe2,0xcd,0xbf,0x2d,0x1b +,0x1f,0x3c,0xae,0xa4,0xaf,0xaa,0xad,0xc3,0xb7,0x4e,0x33,0x3c,0x35,0x27,0x2d,0xb6,0xbf,0xd1,0xd2,0x4c,0xb7,0xa2,0x9f,0x57,0x1d,0x22,0x4a,0xbf,0xc8,0x30,0x2e,0x2b +,0xcc,0xa7,0xac,0xa2,0xa8,0x42,0x20,0x2a,0xbd,0xa2,0xa3,0x27,0x10,0x1e,0xe9,0x9a,0x9c,0xa4,0x75,0x2b,0x27,0x36,0xbe,0xa0,0x9e,0x2f,0x0e,0x0d,0x2b,0x91,0x8d,0xb5 +,0x23,0x1f,0x4d,0xaa,0x9a,0x99,0xa4,0x1b,0x08,0x0c,0xbd,0x89,0x8b,0xa0,0x14,0x0c,0x2f,0x9d,0x8e,0x8e,0x35,0x0d,0x08,0x11,0x9d,0x90,0x96,0xc1,0x19,0x16,0x45,0x94 +,0x8a,0x97,0x15,0x06,0x0f,0xbc,0x96,0x99,0xa7,0x36,0x18,0x25,0xa5,0x8e,0x8b,0xef,0x0d,0x0a,0x18,0x9c,0x9c,0xb8,0x2e,0x1d,0x2f,0xa3,0x92,0x91,0xb2,0x11,0x0d,0x29 +,0x9b,0x97,0xbb,0x35,0x17,0x14,0xd3,0x90,0x89,0xab,0x0f,0x0f,0x2c,0x9c,0x9c,0xac,0xbe,0x19,0x13,0x2d,0x99,0x89,0x9c,0x12,0x05,0x1b,0x9d,0x8f,0x94,0xd6,0x14,0x0d +,0x1e,0x9a,0x88,0x8b,0x33,0x06,0x0b,0xfe,0x91,0x8c,0x9b,0x20,0x0a,0x0f,0xac,0x88,0x87,0x5b,0x08,0x09,0x24,0x9a,0x8a,0x90,0x49,0x09,0x06,0x3c,0x89,0x84,0x9f,0x12 +,0x07,0x0f,0x4b,0x8e,0x8b,0xa7,0x1a,0x08,0x17,0x99,0x86,0x8e,0x1f,0x0c,0x0d,0x4d,0x98,0x8f,0x93,0x1f,0x07,0x0c,0xb1,0x8c,0x86,0xa9,0x0f,0x0a,0x1d,0x9b,0x8b,0x93 +,0x37,0x0b,0x0b,0x3c,0x8e,0x8a,0xa7,0x18,0x0c,0x1c,0xaa,0x8e,0x8a,0xdc,0x08,0x06,0x1b,0x87,0x86,0x94,0x10,0x0f,0x20,0xb0,0x9c,0xad,0x92,0x06,0x02,0x00,0x17,0x8d +,0x98,0x52,0x02,0x14,0x90,0x8b,0x89,0x86,0xb5,0x14,0xa2,0x97,0x92,0x80,0x99,0x0b,0x29,0x09,0xc0,0x80,0x8a,0x97,0x1c,0x0d,0x13,0x9e,0x9e,0x1a,0x01,0x03,0x03,0x0e +,0x15,0x4f,0x11,0x01,0x04,0x03,0x9d,0x9a,0x2d,0x15,0x15,0x25,0xa3,0x97,0x8e,0x8d,0xb9,0x1d,0x22,0x8c,0x80,0x85,0x96,0x9e,0x8e,0x89,0x83,0x82,0x80,0x8a,0xb2,0xbf +,0xad,0x8d,0x82,0x91,0x0e,0x07,0x44,0x28,0xd4,0x3b,0x03,0x03,0x02,0x00,0xbe,0xc0,0x09,0x06,0x00,0x0f,0x05,0x05,0x14,0x10,0x0d,0x08,0x23,0xd1,0x9c,0xb4,0xae,0xc7 +,0x9b,0x8d,0x88,0x84,0x85,0x86,0x9b,0x8e,0x83,0x83,0x86,0x8c,0x9d,0x8c,0xa5,0xaa,0x99,0x8d,0xab,0x26,0x2f,0x34,0x9d,0x3c,0x25,0x0a,0x10,0x09,0x08,0x0a,0x0e,0x0e +,0x07,0x07,0x04,0x1b,0x36,0x1f,0x0b,0x0f,0x0f,0x26,0x3e,0xc1,0xa6,0x34,0x39,0x41,0x8e,0x8c,0x8e,0xad,0x34,0xae,0xa4,0x96,0x8a,0x8e,0x95,0xae,0x94,0x88,0x8b,0x85 +,0x86,0x8e,0xa7,0x8e,0xa7,0x8d,0x98,0x24,0x11,0x08,0x21,0x14,0x21,0x18,0x0b,0x08,0x08,0x0a,0x0b,0xc9,0x24,0x10,0x06,0x07,0x0c,0x10,0xf2,0x25,0x27,0x0b,0x1e,0x3a +,0x91,0x89,0x58,0xab,0xa9,0x8c,0x8a,0x8e,0x8d,0x85,0x8b,0x95,0x89,0x87,0x85,0x8d,0x8f,0xc6,0xab,0x9f,0xb5,0xa0,0x9d,0xa3,0x1e,0x0b,0x0f,0xb0,0xb0,0x57,0x16,0x07 +,0x0f,0x0f,0x05,0x28,0x46,0x10,0x0b,0x05,0x06,0x10,0x2f,0x33,0x21,0x0d,0x0c,0x09,0x3f,0x94,0x8c,0x8f,0x1f,0x28,0xb3,0x89,0x96,0x8a,0x8a,0xbb,0x42,0x17,0x88,0x80 +,0x8e,0x8f,0xca,0xbf,0x8b,0x88,0x87,0x8a,0x91,0x9f,0x11,0x15,0xa1,0x9c,0x4d,0x0e,0x08,0x07,0x06,0x0e,0x19,0x0a,0x15,0x07,0x09,0x29,0x15,0xa6,0x25,0x02,0x13,0x1e +,0x15,0x24,0x2e,0x1a,0x22,0xae,0x9e,0x96,0x99,0xbc,0xa2,0x92,0x94,0x92,0x90,0x89,0x9b,0xb9,0x90,0x80,0x83,0x90,0xe9,0x34,0x98,0x2e,0xb8,0x98,0x8a,0xa5,0x05,0x0b +,0x95,0x83,0x9a,0xbb,0x13,0x07,0x0d,0x9f,0xbd,0x19,0x6f,0x03,0x05,0x06,0x0e,0xa4,0x1c,0x24,0x02,0x04,0x0f,0x2f,0x91,0xcb,0x30,0x0f,0x19,0x13,0xae,0x84,0x85,0x90 +,0x44,0x26,0x3c,0x8a,0x82,0x88,0x83,0x9f,0x1e,0x95,0x89,0x8a,0x8b,0x93,0x8d,0xb3,0xcb,0xaa,0xca,0x2f,0xb5,0xb0,0x25,0x26,0x0d,0x1c,0x0c,0xaf,0x4a,0x0c,0x0d,0x08 +,0x18,0x13,0x16,0x0f,0x35,0x25,0x05,0x06,0x29,0xce,0x9e,0x2c,0x2d,0x28,0x13,0x14,0x26,0x91,0xb6,0x9b,0xa1,0xa7,0x9c,0x9f,0x80,0x8c,0x8e,0x1e,0x2c,0x89,0x8d,0x82 +,0xa7,0xb1,0xd5,0xa2,0xdc,0x92,0x80,0x9d,0x29,0x0d,0x1e,0x8d,0x90,0x92,0x0b,0x10,0x1d,0x0b,0x1e,0x18,0x93,0x14,0x0c,0x08,0x06,0x0b,0x1e,0x0f,0x0e,0x0e,0x05,0x0d +,0x34,0xdf,0x50,0x8f,0x37,0x3f,0x12,0x90,0x90,0x90,0x96,0x1a,0x95,0x8f,0x88,0x92,0x96,0x85,0x8d,0x8d,0xac,0x2d,0x9d,0x9e,0x90,0x4c,0x9a,0xcb,0x15,0x0c,0x18,0x8e +,0x85,0xb8,0x1c,0x0b,0x09,0xb1,0x96,0xab,0x15,0xb5,0x0c,0x08,0x07,0xb8,0x8d,0xb2,0x2c,0x0a,0x07,0x38,0x33,0x23,0x2a,0x1d,0x11,0x03,0x30,0x41,0x97,0x97,0xad,0x1d +,0x22,0xa4,0x8b,0x8a,0x9e,0x43,0xc0,0x99,0xaf,0x8f,0x8c,0x89,0x88,0x8f,0x16,0xc4,0x82,0x8e,0x98,0xb1,0x45,0x2a,0x36,0x2e,0x9f,0x9c,0xaa,0x1b,0x04,0x0c,0xb2,0x26 +,0x09,0x0a,0x04,0x1f,0x0d,0x20,0x15,0x23,0xcf,0x1c,0x2d,0x0e,0x0c,0x27,0xa1,0x0f,0x3f,0xb2,0x1d,0xad,0x99,0x8d,0x8d,0x96,0xbf,0x2f,0x9f,0x8e,0x85,0x86,0x4a,0xb9 +,0x98,0x90,0x94,0x92,0x97,0xa1,0x96,0x1f,0x19,0x2e,0x93,0xbb,0x1b,0x13,0x1f,0x64,0x1f,0xd3,0x2b,0xc3,0x9c,0x1b,0x01,0x3d,0x9f,0x3c,0x30,0x11,0x3d,0x1d,0x0b,0x2f +,0x1c,0xde,0x1d,0x19,0x17,0x09,0x6d,0x9d,0x41,0x5f,0x11,0x0c,0xbf,0x9a,0x94,0x9b,0x99,0xae,0x8b,0x32,0xbd,0x85,0x86,0x99,0x10,0xa8,0x96,0x92,0x8c,0xab,0x89,0x8b +,0xa1,0x40,0x28,0x95,0x94,0x3c,0x09,0x12,0xa7,0x0c,0x27,0xa0,0x17,0x36,0x2d,0x13,0x06,0x22,0x25,0x0e,0x0b,0x10,0x0e,0x1d,0x69,0xb3,0x37,0x21,0x2b,0xc5,0x2f,0x2b +,0x8e,0x2c,0xe8,0x17,0x1d,0x8a,0x8a,0x8d,0xb4,0xa7,0x8d,0x8b,0xa0,0xeb,0x94,0x8b,0xa8,0x2d,0xae,0xa8,0x98,0x8f,0x2a,0x34,0x9d,0x8d,0x25,0x08,0x27,0x4e,0xa2,0x18 +,0x14,0x19,0x1e,0xaa,0xb3,0x2f,0x1b,0x21,0x0e,0x1d,0x1d,0x28,0xaf,0x12,0x09,0x0d,0xb0,0xd8,0xa4,0x24,0x58,0x2b,0xa3,0xa3,0x16,0x96,0xa9,0x8d,0xb0,0xae,0xb4,0x9c +,0x99,0x8f,0xa8,0x9b,0x98,0xaa,0x4f,0xa6,0x84,0x9c,0x36,0x03,0xac,0xb7,0x9d,0x97,0x0e,0xaf,0x9e,0xf7,0x1b,0x17,0xa0,0x8c,0x1e,0x06,0x09,0x0c,0x33,0xb5,0x34,0x1d +,0x2e,0x42,0x28,0x1e,0xa9,0x59,0x66,0x19,0x0c,0x28,0xbd,0xaa,0xc6,0xc9,0x3d,0x2f,0xa8,0x4f,0x0f,0x95,0xa1,0xbc,0x13,0x1f,0x8e,0x8d,0x8a,0xa6,0x9e,0x91,0x98,0x8c +,0x97,0x90,0x9d,0xa1,0x47,0x1e,0x90,0xd1,0x99,0x2a,0x28,0x9e,0x1f,0x1a,0x13,0x0c,0x55,0x29,0x06,0x0e,0x32,0x28,0x0f,0x1d,0x17,0x15,0x3a,0xe0,0x19,0xbd,0x5b,0x9d +,0x49,0xcb,0xa6,0x9b,0x85,0x46,0x97,0x9c,0x98,0x47,0x32,0xb7,0x9b,0x91,0x9e,0x35,0x15,0x99,0x9a,0x9e,0x3e,0x24,0xa0,0xb4,0x26,0xd8,0x18,0x59,0xc5,0x39,0x28,0x21 +,0xb0,0xd0,0x13,0x26,0xc9,0xb1,0x95,0x0e,0x25,0xa6,0xa2,0x4a,0x0e,0x1e,0xb6,0xa7,0x5f,0xae,0xc1,0xbb,0x64,0x16,0x2e,0x53,0xaf,0xca,0x16,0x13,0x19,0x32,0x4c,0xba +,0x47,0xa6,0x9b,0x35,0x1b,0x27,0x9e,0x89,0xd0,0x15,0xaf,0x9a,0x8c,0x8f,0xc3,0xaf,0x96,0x8c,0x94,0x53,0xa0,0x52,0x40,0xac,0x30,0x55,0xb1,0xcb,0x1a,0x17,0x29,0x2c +,0x0e,0x14,0x2d,0x79,0x19,0x16,0x0f,0x38,0x1c,0x7d,0x9a,0x0f,0x2d,0x62,0x9a,0x4a,0x46,0xaf,0xa7,0x47,0x9c,0xac,0x99,0xa0,0x1f,0xb1,0x9b,0x92,0xaf,0x38,0x1d,0x97 +,0x93,0x9f,0x2b,0x48,0x9c,0x8e,0xc5,0x13,0x1b,0x76,0x9c,0xad,0x17,0x59,0xb1,0xb2,0xc9,0x0f,0x2b,0x1f,0x3b,0xeb,0x23,0x47,0x9c,0x1d,0x1d,0x21,0x98,0x8f,0x25,0x0e +,0x12,0xb1,0x9d,0x45,0x1d,0x1c,0xa5,0x90,0x2b,0xb3,0xaa,0x99,0xa1,0x18,0x1f,0xad,0x2e,0xee,0x4c,0x9d,0xc5,0x2f,0xaf,0x41,0xc0,0x98,0x99,0x2c,0x0f,0x23,0x8f,0x9f +,0xb5,0x27,0xbf,0x9c,0xa4,0x22,0x56,0xaf,0xae,0x4b,0x22,0x26,0xe4,0x9b,0x21,0x1b,0xb2,0xa5,0xc1,0x15,0x1b,0xa7,0xb6,0x25,0x0d,0x1a,0xb2,0x8e,0x45,0x20,0x28,0x3b +,0xc4,0x29,0x23,0x39,0xad,0xb8,0x1a,0x39,0xa4,0xa9,0xa2,0x9e,0xa5,0x4b,0x44,0xae,0x6f,0xbf,0xa5,0x97,0x9f,0x14,0xdf,0x99,0x91,0x51,0x31,0x29,0x50,0xad,0x65,0xd3 +,0xbc,0xaa,0x2a,0x2a,0x40,0xaf,0x9f,0x27,0x15,0x1b,0x4e,0x70,0x1c,0xcb,0x95,0x94,0x2e,0x14,0x24,0xe3,0x9e,0xaa,0x26,0x60,0x15,0x9e,0x27,0x1d,0x93,0xb8,0xa2,0x2f +,0x34,0x27,0x32,0x61,0xb6,0x2b,0x3c,0x2e,0xc4,0x4f,0x47,0xa5,0xa8,0x2a,0x15,0x2b,0xe9,0x9e,0xc5,0x1f,0x3e,0xa8,0x36,0xad,0xc3,0xaa,0xaa,0xb2,0x1b,0x1a,0x63,0xc7 +,0x9f,0x33,0x45,0xaf,0xa9,0x24,0x2d,0x2d,0xa2,0xa4,0x25,0x20,0x24,0x98,0xa6,0x45,0x27,0xbd,0xa3,0x26,0x36,0x2c,0x9b,0xac,0x1d,0x2b,0x2f,0x9e,0x95,0xad,0x1c,0x17 +,0x3e,0xae,0x54,0x9c,0x2b,0x41,0x1c,0x27,0xb9,0x9c,0x92,0xcf,0x1f,0x1d,0xbf,0xbd,0x5f,0x16,0xd1,0x29,0x96,0xdd,0x1a,0xad,0x94,0x9f,0x4c,0x29,0x35,0xaf,0xf2,0x34 +,0x27,0xba,0xcf,0x65,0x2c,0x9c,0x99,0xbb,0x1c,0x1e,0xed,0x9e,0xbe,0x64,0x32,0x3f,0xa8,0x28,0x2d,0xe3,0xba,0xcc,0x32,0x44,0x5f,0x9b,0xa6,0x1d,0x1d,0xd3,0xa9,0xcc +,0x27,0x2d,0x93,0xcf,0x1c,0x1c,0x58,0xc4,0xbd,0xa4,0xc8,0x25,0x3a,0x3b,0xaa,0x9c,0xbb,0xb0,0x38,0x18,0x21,0xa0,0xcd,0xab,0xaf,0xac,0xfc,0xbd,0xad,0x25,0x30,0x27 +,0xbf,0x3f,0x32,0xab,0xbf,0xce,0xbc,0xb2,0xcd,0x31,0x1e,0x1e,0x2c,0xb9,0xaf,0x65,0xa9,0x4e,0xae,0x97,0x39,0x1c,0x3f,0xac,0x2a,0xe0,0xb2,0x3e,0xc9,0xc1,0xac,0xbe +,0xc3,0x5e,0x2d,0xcb,0x2d,0x3c,0x9b,0xaf,0xd6,0x41,0xa9,0xcb,0x2c,0x38,0x33,0xb4,0x28,0x1e,0xa0,0xac,0xb4,0x5f,0xb5,0xdc,0x1e,0xa5,0xaf,0xb4,0x27,0xae,0x9d,0x27 +,0x2f,0xc0,0x1f,0x4a,0xb4,0xbb,0x2a,0x1f,0x97,0x25,0x5b,0x42,0x32,0xb1,0x34,0x23,0x41,0xbc,0x50,0xad,0xa9,0xfa,0xab,0x4f,0x1f,0x2f,0x1c,0xa1,0xbd,0xc0,0xce,0x3b +,0x9c,0xa6,0xbd,0xa7,0x2c,0x21,0x2a,0x29,0x99,0xd1,0x4a,0xc3,0xe0,0xbb,0x36,0xb4,0xb7,0x21,0xee,0x31,0x2e,0x3b,0xa1,0x98,0xb7,0xeb,0x68,0x61,0x1b,0x21,0x36,0x46 +,0x42,0x2e,0xb7,0x99,0xa9,0xb8,0x36,0x32,0x28,0x29,0xa7,0xde,0x2b,0x45,0x38,0xd6,0xa4,0x94,0xbd,0x19,0x1f,0x3a,0x9d,0xa7,0x2e,0x34,0x3e,0xa4,0xaa,0x99,0xa5,0x14 +,0x32,0x33,0xac,0xc7,0x55,0xcd,0x3d,0xdf,0xc6,0xbd,0x37,0x2e,0x57,0xb7,0x3b,0xfb,0xb5,0x3e,0xcc,0xdd,0xbd,0x38,0x27,0xab,0xb3,0x26,0x1b,0x5c,0x44,0xaa,0xa7,0x4c +,0x59,0xdb,0x46,0x4b,0x39,0x34,0x3e,0x9f,0x9b,0x28,0x2e,0x2b,0xa2,0x97,0x3d,0x25,0x1c,0x2b,0xf4,0x4f,0xa1,0xb3,0x98,0xba,0xbe,0xcc,0x19,0xad,0x29,0x3a,0xca,0x9b +,0xab,0x2e,0xb2,0x52,0x2f,0x3a,0xa6,0x69,0x1e,0x2c,0xd2,0xbf,0xa9,0xff,0xbe,0xa7,0x26,0x29,0x39,0x1b,0x19,0xce,0x9a,0xc4,0x34,0xab,0xa2,0xc8,0x71,0x49,0x20,0x27 +,0x27,0xd6,0x98,0x9f,0xbd,0xbd,0x22,0xad,0x92,0xc2,0x34,0x0d,0x1d,0xa1,0xcc,0xb0,0xa9,0x2c,0x32,0xa7,0xba,0x2a,0x25,0x29,0xbd,0xae,0x44,0xa1,0xc9,0x47,0x26,0x27 +,0xa2,0xae,0x30,0x2b,0xbf,0x47,0x4e,0x37,0xa3,0xd3,0xce,0x97,0x1e,0x10,0x29,0x9f,0x9d,0x52,0xa4,0xce,0x2a,0xec,0x3a,0xb0,0x2e,0x1f,0xbe,0xa4,0x9a,0xaa,0x52,0x37 +,0x26,0xae,0xa9,0x27,0x1d,0x29,0xab,0x9a,0xab,0xf2,0x30,0x26,0xa9,0xac,0x27,0x2d,0x2e,0x22,0xab,0xbf,0xb2,0x8e,0x66,0x1a,0x14,0x35,0x25,0x2f,0xbd,0xc6,0xa5,0x4f +,0x96,0xbe,0x2b,0x29,0x55,0x93,0x1b,0x15,0x1f,0x9e,0x9a,0x7b,0xa1,0xad,0xb2,0xb6,0xbc,0x22,0x41,0x1e,0xcd,0x63,0xad,0x95,0x4a,0x3e,0x26,0xb4,0xbe,0x36,0x19,0x2b +,0xb1,0xf8,0xb9,0xb3,0x3a,0x3a,0xcf,0xa9,0x2f,0x17,0x2e,0xbc,0x96,0x2f,0x42,0x3f,0x55,0x9f,0xbc,0xdc,0x1a,0x28,0xc7,0xb9,0x66,0xa7,0xb4,0x37,0x20,0xeb,0xdb,0x2a +,0xcc,0xbf,0x9e,0xad,0xbb,0x56,0x30,0x3b,0xb9,0xa1,0xae,0x24,0x21,0x57,0x97,0xa7,0xdf,0xb5,0xc2,0xb3,0x25,0xb8,0x2d,0x1e,0x2b,0x34,0xa2,0xa7,0xe9,0x65,0x17,0x18 +,0xb6,0x6f,0xba,0x2b,0x57,0x39,0x53,0x9e,0xab,0xa6,0x2b,0x2c,0x32,0xbb,0xb3,0xba,0xa6,0x20,0x2b,0xa5,0xaa,0xcc,0xac,0xb8,0x2c,0x1e,0x18,0x44,0x95,0x93,0xb5,0x1e +,0x1b,0xc1,0xa2,0xba,0x4f,0x23,0x27,0xe1,0xaf,0x99,0xbe,0xd7,0x17,0x1c,0x99,0xa4,0xbd,0x1a,0x24,0x39,0xbe,0xa1,0xa3,0xbb,0x1e,0x27,0x9f,0xd8,0x27,0x38,0xd6,0x9a +,0xb8,0xb8,0x3f,0x27,0x6b,0x42,0x2d,0x4a,0x33,0xaf,0xab,0xb4,0xcd,0x22,0x79,0x49,0xbb,0xae,0x2c,0x31,0x44,0xa3,0x94,0xba,0xc4,0x29,0x27,0x3c,0xa6,0xbb,0x21,0x1d +,0x23,0xa7,0xa6,0xac,0x3d,0x28,0x19,0x3b,0xa4,0xa8,0x52,0x1b,0x23,0xaa,0x92,0xa1,0x21,0x20,0x27,0xb6,0x9e,0xde,0x2d,0x2f,0xb0,0xae,0x9b,0xa6,0xac,0x1d,0x4e,0xb7 +,0x29,0xe3,0xb8,0xa7,0x2b,0x36,0x2c,0xbe,0xae,0xc1,0x3b,0x48,0x46,0x39,0xd1,0x4d,0xa8,0x28,0x23,0x2b,0x36,0xa7,0xb6,0xb6,0x26,0x2f,0xd2,0xb1,0x97,0xc0,0x22,0x1d +,0x2a,0xa3,0x91,0xa7,0x27,0x24,0x24,0xce,0xa1,0x96,0x4a,0x0c,0x1d,0x3f,0x9c,0xaa,0x3e,0xbe,0x7c,0x29,0x6a,0xae,0x3e,0x44,0xf4,0x4a,0x2d,0xa5,0xae,0xb2,0x9d,0xd5 +,0x31,0x5b,0x5c,0xb8,0x43,0x38,0x47,0x1f,0xaf,0x9a,0xb7,0x30,0x2d,0x1d,0x21,0x9f,0x93,0x2c,0x1d,0x22,0x2c,0x99,0xa2,0x41,0x29,0x21,0x42,0x9f,0x94,0xc2,0x1d,0x41 +,0x45,0xd6,0xc3,0xb2,0xce,0x21,0x3d,0x5b,0xac,0xa5,0x6f,0x3a,0x29,0x2d,0xbd,0xdd,0x4f,0x46,0xbd,0xad,0x2a,0x5e,0xb0,0xe4,0xc8,0x5a,0x45,0x25,0x2f,0xb7,0xa9,0xa7 +,0x3f,0x6c,0xab,0xae,0xb7,0x25,0x21,0x3e,0xc6,0xa8,0xaf,0x4e,0x28,0xc9,0xad,0xac,0x2c,0x26,0x1c,0x1c,0xa9,0xa2,0xa1,0x4f,0x34,0x42,0xca,0xd9,0xa2,0xad,0x1e,0x26 +,0x4c,0xed,0xae,0xaa,0xe5,0x31,0x32,0xd7,0xab,0xa0,0x59,0x4b,0xec,0x46,0x2a,0xb4,0xac,0xc7,0xee,0x2e,0x2a,0x28,0xae,0xc9,0x41,0x2c,0x20,0xbd,0xa0,0x5d,0x33,0x42 +,0x36,0xde,0xad,0xae,0xb8,0x55,0x2b,0x3f,0xae,0xb9,0xca,0x4c,0x2d,0x4a,0xaf,0x96,0x9c,0x52,0x18,0x14,0x3d,0xb8,0xa9,0x4f,0x2b,0x55,0x6e,0xbc,0xb4,0xac,0xdb,0x49 +,0x30,0x2c,0x72,0xb9,0xa7,0xb5,0xcb,0x56,0x4a,0xa2,0xab,0x2d,0x37,0x1f,0x21,0xdc,0xb0,0x67,0x41,0xcd,0xad,0xac,0x5d,0x37,0x27,0x2a,0x1f,0xeb,0xa6,0xac,0xab,0x2d +,0x20,0x21,0xb3,0x96,0xaa,0x32,0x1b,0x21,0xb2,0x93,0x9c,0x3b,0x23,0x35,0xbc,0xa5,0xaf,0xc5,0xc7,0x32,0x3a,0x2b,0x41,0xaa,0xa4,0x50,0x1f,0x2a,0x4d,0x9b,0x9c,0x3f +,0x25,0x1c,0x5e,0xaf,0x65,0xd4,0x65,0xc0,0x38,0xdc,0xb4,0x3a,0x2c,0xdb,0xd7,0x3f,0x52,0x39,0xb4,0x2e,0xe3,0xac,0xb4,0x9c,0xad,0x25,0x1b,0x45,0x42,0xbd,0x3e,0xc0 +,0xaa,0x45,0xe1,0xe4,0xbd,0x38,0x44,0x27,0x2f,0x49,0x45,0xa6,0xa1,0xb7,0x39,0xc5,0xaf,0xa8,0xb1,0x20,0x1e,0x65,0xcc,0xb8,0xc0,0xaa,0x53,0x3d,0xba,0x59,0x47,0xd8 +,0x4e,0x2c,0x26,0x25,0xac,0xb3,0x37,0x38,0xca,0xa8,0xa0,0x4b,0x1b,0x25,0xc6,0xa5,0x9f,0xc5,0x3a,0x41,0x36,0xb2,0xb7,0x28,0x41,0xaa,0x4e,0x68,0x36,0xad,0xaa,0x34 +,0x2a,0x37,0xa3,0xa9,0xa3,0x39,0x15,0x29,0xb8,0xb2,0xce,0x2f,0x25,0x4e,0xcc,0xbb,0xab,0xf3,0xe4,0xdc,0xc4,0x3f,0x2d,0xb4,0xc5,0xa9,0x39,0x2f,0xb7,0xa9,0x9b,0x38 +,0x19,0x1c,0xd9,0xae,0x4a,0x3e,0x3d,0x66,0xb9,0xbb,0xa6,0xbd,0x4d,0x3d,0x31,0x3c,0x27,0x39,0xbf,0xa1,0xcf,0x4a,0xb4,0xab,0xad,0x22,0x32,0xec,0x34,0xbe,0xc2,0xcc +,0xe1,0x32,0xd2,0xcb,0xf6,0xa3,0xa0,0x3a,0x1f,0x27,0xb4,0xac,0x34,0x24,0x24,0xc1,0x9f,0xa7,0x2f,0x1a,0x28,0x4b,0xb8,0xb0,0xc1,0xc6,0xbf,0xad,0xbe,0xba,0x3e,0x36 +,0xbb,0x38,0x3b,0x54,0xc3,0xab,0xa0,0xd9,0x22,0x2b,0xcd,0xa2,0xa7,0xd2,0x1d,0x1e,0xba,0xb0,0xcf,0xef,0xdf,0x54,0x49,0xb7,0xab,0xa7,0x2a,0x1b,0xc5,0xbc,0x1f,0x24 +,0x74,0xb6,0xa7,0xaf,0xba,0x3f,0x2c,0x35,0x79,0xae,0xaa,0x34,0x2f,0xb1,0xb3,0x34,0x2f,0xfe,0xd8,0xcf,0x2c,0x1b,0x2d,0x9f,0x9f,0x2f,0x2f,0x2d,0xba,0x95,0x93,0xa6 +,0x23,0x25,0x2a,0xad,0xc2,0x5e,0x56,0x6e,0xce,0x39,0xb4,0xbf,0x46,0x2a,0xb9,0xac,0xc6,0x36,0x21,0xdb,0xb8,0xbd,0xb5,0x3d,0x28,0x2d,0x48,0xc4,0xaf,0xbc,0x1f,0x3d +,0xc4,0xb1,0xa6,0x2c,0x53,0x9b,0xb4,0x2a,0x26,0x28,0x29,0x2c,0x1f,0xbd,0x93,0x3e,0xa2,0x92,0x2e,0x2e,0x1f,0xe2,0xb9,0x30,0xa8,0x2b,0xcf,0x6f,0xbd,0x9e,0x2c,0xb6 +,0xbd,0x46,0x5d,0x4f,0xac,0xf1,0x2e,0xab,0xb0,0x4c,0x50,0x38,0x6b,0x40,0x37,0x48,0x3d,0x20,0x20,0xaa,0x98,0x69,0x21,0x31,0xa8,0x5e,0x15,0x26,0x3d,0x8c,0x9e,0x33 +,0xa8,0x3c,0xd4,0x38,0xa9,0xba,0x1f,0xb7,0xbb,0xc9,0x99,0xcd,0xc7,0x26,0xf8,0x4f,0x1b,0x0f,0x0c,0x54,0x9c,0x81,0xba,0xb6,0x1c,0x26,0x90,0xa6,0x8c,0x32,0x1f,0xa1 +,0x21,0x0f,0x0b,0x1d,0x2b,0x0c,0x8a,0x8b,0x25,0x18,0x1a,0x25,0xa4,0x8f,0xad,0x13,0x17,0x1b,0x8a,0x84,0x12,0x8f,0x20,0x0f,0x1a,0xba,0x80,0x1f,0x26,0xa1,0x1f,0x3a +,0x19,0xa9,0x98,0x1a,0x91,0x1e,0x22,0x0f,0x0d,0x28,0xac,0x85,0x12,0x8e,0x8d,0x2a,0x2d,0x19,0xc7,0x9d,0xbc,0xa1,0x07,0x17,0x92,0x8a,0x8b,0x0c,0x19,0x07,0x02,0x1f +,0x8f,0x94,0x20,0x0f,0x8c,0xa7,0xc9,0x85,0x93,0xbb,0x0f,0x9d,0x8c,0x2b,0x1c,0x28,0x35,0x2d,0x2c,0x91,0x4c,0x0d,0x33,0x49,0x2f,0x0d,0x23,0x37,0x1e,0x82,0x2a,0xa6 +,0x81,0xa5,0xae,0x0b,0x59,0x26,0x16,0x84,0x8d,0x39,0x15,0x08,0x2d,0x1b,0x99,0xa3,0x19,0x1c,0x0d,0xbb,0x16,0x8d,0x5f,0x19,0x87,0x45,0x92,0x2b,0x24,0x99,0x1d,0xa1 +,0x90,0xa7,0xb0,0x0f,0x2e,0xa0,0x9c,0x8c,0x0e,0x07,0x02,0x04,0x07,0x8e,0x83,0x48,0x8c,0x29,0x3e,0x52,0x98,0x80,0x27,0xb7,0x92,0x28,0xa6,0x12,0x3a,0x17,0x15,0x95 +,0x17,0x39,0x0e,0x0d,0x0d,0x8c,0x9e,0x26,0x85,0xcd,0x1d,0x1d,0x94,0x84,0x26,0x9c,0xc8,0x09,0xde,0x2b,0x80,0xb9,0x19,0x1f,0x0a,0x1e,0x1c,0x24,0x1d,0x85,0x29,0x1e +,0x98,0x66,0x34,0x0a,0xc6,0x94,0x14,0x8f,0x91,0xae,0x90,0x29,0x8e,0x16,0x30,0x1c,0x07,0x20,0x20,0xc1,0xa7,0x87,0x0c,0x12,0x5e,0x28,0x3e,0x17,0x8d,0x92,0x16,0x92 +,0xae,0x92,0x8e,0x9e,0x8d,0x15,0x4a,0x13,0x35,0x25,0x19,0x19,0x93,0x87,0x14,0x8f,0x8d,0x93,0x1d,0x13,0x8b,0xa4,0xa1,0x82,0x8c,0x82,0x94,0x8b,0xbb,0x0f,0x17,0x0a +,0x08,0x0a,0x1b,0x05,0xa5,0x08,0x07,0x15,0x05,0x0a,0x00,0x14,0x19,0x02,0x2a,0x25,0x1b,0x21,0x0d,0x3e,0x0e,0xaf,0x54,0xac,0x38,0x4f,0x25,0x8f,0x87,0x15,0x8a,0x8d +,0x85,0x96,0xab,0x8b,0x73,0x33,0x85,0x8e,0x87,0x8c,0x84,0x88,0xa1,0x8f,0x8b,0x8f,0x8f,0xad,0xcf,0x80,0x1e,0x93,0x93,0x44,0x1e,0x03,0x9c,0x99,0x29,0x9a,0xa7,0x2b +,0x0d,0x11,0xad,0x19,0xce,0x36,0x1d,0x13,0x1a,0x00,0xa7,0x30,0x04,0xad,0x2e,0xac,0x09,0x1a,0x3c,0x07,0x1f,0x53,0x1d,0x27,0x1c,0x9d,0x0b,0x0e,0x26,0x1e,0x23,0x15 +,0x0a,0x31,0x86,0x2a,0x89,0x89,0xad,0x0e,0x0d,0x9c,0x28,0x1f,0x93,0xa8,0xb0,0x2b,0xc5,0x1f,0x11,0x28,0x0e,0x0c,0x27,0xcd,0x36,0x80,0x3f,0xa5,0x8a,0x94,0x9e,0x11 +,0x9b,0x91,0xb0,0x85,0x85,0x87,0x8b,0x8c,0x82,0x8e,0x84,0x88,0x8c,0x9f,0x5c,0xb6,0x80,0x86,0x8a,0x81,0x8b,0xb8,0x04,0xba,0xa4,0x06,0x13,0x1c,0x15,0x0c,0x05,0x08 +,0x00,0x02,0x01,0x01,0x02,0x04,0x00,0x2a,0x10,0x06,0x24,0x12,0x0a,0x00,0x08,0xb7,0x24,0xa8,0x9d,0xba,0x2e,0x13,0xab,0x1b,0x66,0xba,0xaf,0x34,0x6e,0x0f,0x88,0x92 +,0x32,0x8b,0x9a,0x8f,0xc6,0x86,0x80,0x8c,0x89,0x82,0x86,0x87,0x8b,0x83,0xb0,0x5f,0xa9,0x9a,0x3d,0x1b,0x0d,0x92,0x8c,0x34,0x82,0x8f,0x45,0x00,0x14,0x88,0x9d,0x9f +,0x8b,0x9d,0x1d,0x1a,0x98,0x15,0x0c,0x10,0x11,0x0c,0x0f,0x06,0x9c,0xe6,0x08,0x35,0x11,0x29,0x07,0x3a,0xaf,0x0b,0x0a,0x26,0x99,0x24,0x14,0xcf,0x0d,0x25,0xaf,0xa6 +,0x44,0x09,0x00,0xa3,0xdc,0x22,0x8b,0x9c,0x39,0x00,0x1e,0x97,0x1a,0x19,0x26,0x27,0x0f,0xaa,0x82,0x58,0x48,0xcb,0xbb,0x40,0x16,0x2b,0x80,0x9a,0xa8,0x80,0x81,0x8c +,0x31,0x87,0x82,0x97,0x85,0x80,0x80,0x8d,0x94,0x85,0x90,0x87,0x83,0x88,0x9e,0x0d,0x1f,0x84,0x23,0x17,0x32,0x14,0x07,0x00,0x25,0x1e,0x02,0x04,0x03,0x06,0x02,0x15 +,0x12,0x01,0x00,0x02,0x06,0x0a,0x00,0x09,0xca,0x06,0x44,0x98,0x91,0x12,0x09,0xa4,0xad,0x36,0xa6,0xa1,0x9c,0x1b,0xa6,0x92,0xa8,0x9c,0x40,0xc9,0x0d,0x17,0x86,0x80 +,0x8c,0x89,0x8a,0x82,0xa8,0x91,0x80,0x88,0xa2,0xb2,0x88,0x85,0x9e,0x87,0xa9,0x17,0x0c,0xdc,0x84,0x9b,0x17,0x3f,0x31,0x1d,0x92,0x89,0x88,0x0e,0x33,0xaa,0x9e,0x5d +,0x12,0x33,0x1b,0x0a,0xda,0x56,0x1e,0x08,0x07,0x0b,0x01,0x09,0x28,0xab,0x1e,0x09,0x05,0x31,0x0f,0x1c,0x1e,0x2d,0x1d,0x0d,0xa2,0x8a,0xa4,0x1e,0x0e,0x25,0x29,0x37 +,0xc5,0x15,0x0b,0x01,0x16,0xb6,0x9c,0x2b,0x18,0x05,0x09,0x9f,0x8c,0x8d,0x9d,0xa3,0x8e,0x89,0x8c,0x8e,0x92,0x97,0x9c,0x90,0x89,0x83,0x8e,0x8b,0x86,0x8b,0x90,0x87 +,0x80,0x86,0x85,0x8a,0x87,0x85,0x8a,0x82,0x82,0x97,0xc7,0xab,0xa4,0x1d,0x0a,0x03,0x03,0x0f,0x29,0x12,0x02,0x01,0x00,0x01,0x04,0x19,0x1a,0x02,0x02,0x01,0x0e,0x3e +,0x15,0x0b,0x08,0x0e,0x0e,0x1e,0xb9,0x1d,0x14,0x27,0xd0,0xcb,0x24,0x14,0x2c,0x28,0x26,0xa2,0x9a,0x94,0x97,0xca,0x91,0x96,0x9b,0x87,0x8c,0x84,0x8d,0x8c,0x8f,0x8f +,0x8a,0x98,0x92,0xaf,0xc4,0x91,0x85,0x92,0xb5,0x2c,0x3f,0x97,0x94,0x8a,0x93,0x2b,0xd7,0x9a,0x86,0x92,0xb2,0x4b,0x17,0x33,0xd8,0xa6,0x1c,0x0a,0x08,0x1c,0xd2,0x54 +,0x5a,0x13,0x15,0x20,0x18,0x27,0x2c,0x17,0x19,0x29,0x1d,0x12,0x15,0x0c,0x0d,0x08,0x0e,0x09,0x08,0x40,0x98,0x96,0x15,0x1e,0xf8,0xce,0x3d,0x17,0xe4,0x18,0x10,0xa8 +,0x95,0x48,0x07,0x08,0x12,0x2b,0x5a,0xaf,0x25,0x0f,0x32,0x91,0x82,0x88,0x9d,0xaa,0x9a,0x8c,0x83,0x83,0x81,0x8c,0x8a,0x85,0x81,0x83,0x85,0x8a,0x8d,0x8a,0x8c,0x88 +,0xa0,0x8c,0x86,0x84,0x98,0x10,0xc0,0xa8,0xc8,0x11,0x04,0x12,0x09,0x1b,0x18,0x07,0x06,0x00,0x07,0x0a,0x02,0x00,0x02,0x00,0x0a,0x16,0x3b,0x11,0x00,0x0b,0x09,0x1b +,0xdb,0x30,0xa4,0x19,0xa6,0x8a,0x91,0x3d,0x09,0x1f,0x25,0x11,0x6d,0x95,0x11,0x24,0xa5,0x89,0x89,0xac,0x88,0x8d,0x8e,0x89,0x89,0x80,0x91,0x88,0x82,0x82,0x9b,0xe0 +,0x95,0x97,0x3a,0xbd,0x95,0x0f,0xa5,0x8f,0x8b,0x4a,0x3e,0x85,0xbe,0xa6,0xd8,0x8d,0x95,0x20,0x94,0x8a,0x8e,0x10,0x02,0x09,0x08,0x11,0x9f,0x14,0x03,0x14,0xb7,0xa1 +,0x0c,0x22,0x0e,0x09,0x0d,0x0f,0xa1,0x15,0x1f,0x2f,0x17,0x1b,0x09,0x1f,0x17,0x00,0x5c,0x9d,0x0d,0x10,0x59,0x8f,0x2a,0x4c,0x9a,0x0a,0x13,0x0e,0x64,0x20,0x08,0xa5 +,0x37,0xa7,0xa8,0x3b,0xd5,0x0b,0x4e,0x81,0xaa,0xa3,0x8f,0x8d,0x81,0x89,0x80,0x8b,0x9e,0x95,0x92,0x81,0x8c,0x80,0x86,0x8e,0x83,0x85,0x8a,0xb2,0xc7,0x84,0x9d,0x0c +,0xcf,0x26,0x21,0x05,0x45,0xa1,0x07,0x16,0x04,0x0b,0x07,0x0a,0x0e,0x00,0x05,0x11,0x0a,0x05,0x00,0x08,0x28,0x05,0x0a,0x09,0x0e,0x08,0x19,0x83,0x2c,0x24,0x97,0xaf +,0xab,0x64,0x88,0xa8,0x18,0xb2,0x9f,0xa1,0x14,0x0c,0x94,0xa8,0x2a,0x8f,0x90,0x9b,0x3c,0x85,0x81,0x8e,0x85,0x90,0x8f,0x97,0x89,0x82,0xac,0x94,0x8e,0x9d,0xb2,0x0c +,0x2b,0x96,0x25,0xc1,0x96,0xe3,0x15,0x37,0x81,0x9b,0x8b,0x9c,0x1b,0x39,0x4b,0x8e,0x47,0x14,0x11,0x22,0xc1,0xe6,0x07,0x2b,0x15,0x0e,0x36,0x0d,0x0e,0x00,0x25,0x21 +,0x38,0x96,0x1d,0x11,0x0b,0x17,0x17,0x0e,0x29,0x1b,0x12,0x75,0x1e,0x32,0xa8,0x0f,0xab,0x31,0x13,0x07,0x0c,0xac,0x25,0x9e,0xbe,0x1f,0x24,0xde,0x9d,0x31,0x3e,0x9b +,0x38,0xc4,0x9d,0x99,0x83,0x93,0x89,0x80,0x85,0x8b,0x95,0x83,0x8c,0x87,0x80,0x83,0x8d,0x92,0x81,0x82,0x8b,0x94,0x96,0xa4,0xa5,0x2a,0xa8,0x3e,0x04,0x2b,0x28,0x0b +,0x00,0x08,0x14,0x02,0x0d,0x1f,0x18,0x04,0x06,0x1b,0x08,0x03,0x03,0x04,0x07,0x04,0x0c,0x1a,0x01,0x0a,0xce,0xad,0x0e,0x09,0x9d,0x3a,0xa8,0x88,0x8c,0x99,0x34,0x90 +,0x9c,0x5b,0xbe,0x2f,0x2f,0x15,0x27,0x87,0x98,0xcc,0x93,0x96,0x8b,0xae,0x8d,0x8f,0x9e,0x84,0x84,0x80,0x8b,0x88,0x84,0x9a,0xa8,0x37,0x25,0x3e,0x1d,0x9c,0x9e,0x18 +,0x3f,0x9c,0x90,0xc9,0xc2,0xb1,0x18,0x29,0xea,0x94,0x95,0x28,0x45,0x3a,0x55,0x35,0x1b,0x13,0x05,0x19,0x24,0x0b,0x07,0x06,0x25,0x21,0x11,0x1c,0x17,0x1e,0x22,0xb7 +,0xab,0x2b,0x75,0xb0,0xd0,0xbd,0xde,0x2e,0x0a,0x10,0xa3,0xb8,0x4c,0x21,0x32,0xb9,0x30,0x2c,0x33,0x23,0xf6,0xac,0x9a,0xa2,0xa8,0x9a,0x9b,0x9c,0x7c,0xb9,0xba,0xa6 +,0xa7,0xcf,0xa0,0x9d,0x3b,0x1f,0x39,0x62,0xb0,0x43,0x1e,0x51,0xa2,0x99,0x92,0x8e,0x90,0x9b,0x8f,0x8f,0xe5,0x1b,0x1e,0xce,0xc6,0x98,0xad,0x17,0x44,0x9e,0xa5,0xfc +,0xc8,0x4c,0xb0,0xbd,0xbb,0x9b,0x9d,0xb6,0xac,0x9c,0x3e,0x15,0x17,0x1a,0x18,0x2a,0xdb,0x1e,0x0f,0x22,0xaa,0xac,0x20,0x0d,0x0c,0x14,0x1d,0x1e,0x2d,0x4f,0x1e,0x19 +,0x18,0x18,0x17,0x18,0x10,0x24,0xcf,0x2f,0x34,0x2c,0xbc,0x9d,0x97,0xa0,0x28,0x1e,0xa5,0xb4,0xbe,0xb1,0xa6,0x99,0x8f,0x8e,0x9b,0x9e,0x9f,0x9c,0x9b,0x96,0x8f,0x8b +,0x98,0x98,0x8f,0x96,0xa1,0x49,0x62,0x9d,0xa5,0xa0,0x9e,0xa9,0x49,0x48,0xa2,0xce,0x1e,0x07,0x10,0x23,0x1d,0x37,0x2f,0x28,0x27,0xc4,0xad,0xca,0x21,0x15,0x1a,0x38 +,0x59,0x3d,0x2f,0x2e,0x4a,0x17,0x12,0x0c,0x0d,0x21,0x1e,0x16,0x13,0x27,0x19,0x23,0x97,0x9b,0x3f,0x32,0xbf,0x48,0xde,0xc4,0xad,0x97,0x9b,0xab,0xbf,0xcc,0x14,0x0c +,0x1e,0x21,0x52,0xd5,0x1e,0x17,0xb2,0x8e,0x8f,0x9a,0xb7,0xb5,0xa8,0x8f,0x8a,0x88,0x86,0x8e,0x8e,0x96,0x98,0xa1,0x9d,0x9e,0xb7,0x3b,0xc0,0x99,0xa3,0x98,0x9c,0x9d +,0x9f,0xa3,0x6d,0x3d,0x93,0x8f,0x9b,0xa6,0x5d,0x2f,0xee,0x21,0x0c,0x09,0x09,0x09,0x07,0x07,0x04,0x05,0x07,0x07,0x05,0x01,0x00,0x02,0x08,0x07,0x04,0x0a,0x1b,0x24 +,0xe6,0xb8,0xd3,0x29,0x1e,0xb9,0x96,0x89,0x8a,0x8c,0x91,0x8f,0x88,0x84,0x88,0x8d,0x8e,0x8f,0x8d,0x88,0x83,0x84,0x85,0x85,0x88,0x88,0x8b,0x92,0x8e,0x95,0x9e,0xa2 +,0x96,0x8e,0x92,0x8b,0x8b,0x9d,0xbd,0x47,0xb9,0x3c,0x19,0x1e,0x1a,0x24,0x19,0x17,0x0e,0x0b,0x0e,0x08,0x0d,0x0d,0x08,0x0b,0x0f,0x10,0x2a,0x2e,0x1c,0x0e,0x0e,0x19 +,0x18,0x1b,0x27,0x26,0x13,0x15,0x1e,0x22,0x20,0x21,0x18,0x1f,0x28,0x22,0x25,0xe6,0xaf,0x3d,0x69,0x5a,0x45,0x3f,0xb0,0xaa,0x4e,0x3b,0xaa,0x9f,0xb6,0x36,0x33,0x69 +,0x31,0x4b,0x53,0xee,0xa6,0xa9,0xc4,0xa1,0x96,0x92,0x94,0x99,0x91,0x8a,0x84,0x84,0x82,0x82,0x83,0x84,0x84,0x82,0x83,0x8a,0x8f,0x91,0x8e,0x95,0xa9,0xb8,0x2e,0x1b +,0x15,0x0e,0x07,0x03,0x05,0x05,0x02,0x04,0x09,0x0b,0x07,0x04,0x04,0x07,0x0a,0x08,0x07,0x06,0x06,0x0d,0x0e,0x0e,0x11,0x17,0x1c,0x1d,0x24,0x29,0x3e,0xbd,0xa2,0xac +,0xa0,0x9d,0x95,0x94,0x9e,0x9c,0x9b,0x90,0x90,0x96,0x91,0x92,0x92,0x8b,0x8c,0x8c,0x91,0x93,0x8f,0x90,0x8c,0x8a,0x8c,0x95,0xab,0xc2,0xa3,0x97,0xa7,0x5b,0x2a,0x26 +,0x36,0x2a,0x4f,0x2d,0x21,0x19,0x1b,0x2a,0x44,0x3d,0x1e,0x21,0x36,0x31,0x27,0xd0,0x5a,0xc5,0xb9,0x2d,0x28,0x26,0xe2,0xca,0x27,0x1a,0x1e,0xad,0x5b,0x1b,0x13,0x18 +,0x30,0x2a,0x1e,0x1b,0x2c,0x59,0x2e,0x21,0xda,0xad,0x70,0xd5,0x26,0x2f,0x3f,0x22,0xf6,0x2b,0x19,0x1e,0x3b,0xc6,0x1f,0x1c,0x1e,0x37,0xbf,0xae,0x97,0x96,0x91,0x96 +,0x8c,0x84,0x83,0x82,0x84,0x85,0x86,0x85,0x84,0x86,0x8c,0x89,0x8e,0x94,0x9b,0xc6,0x33,0x1f,0x17,0x0d,0x09,0x08,0x07,0x08,0x07,0x09,0x07,0x07,0x08,0x06,0x0d,0x0e +,0x09,0x06,0x0b,0x11,0x13,0x13,0x12,0x16,0x23,0x2c,0x17,0x14,0x18,0xcb,0xa5,0xc2,0x35,0x2a,0xc3,0xb4,0xa1,0x97,0x95,0x9c,0x9b,0xa1,0x9d,0x8b,0x89,0x8e,0x9b,0x9c +,0x8f,0x8b,0x90,0x9a,0x9a,0x92,0x91,0x97,0x9a,0x9b,0x9d,0x9d,0x9a,0xa3,0xab,0x9b,0x9c,0x9f,0x9e,0xa7,0xb8,0x3c,0x56,0xba,0xc5,0x34,0x2e,0x68,0x40,0x2c,0x4c,0x40 +,0x22,0x20,0x1e,0x1e,0x13,0x10,0x1d,0x24,0x2d,0x24,0x1a,0x1c,0x1a,0x14,0x0e,0x1a,0x19,0x13,0x16,0x13,0x29,0x37,0x1b,0x15,0x16,0x1f,0x1f,0x1c,0x1a,0x14,0x18,0x1a +,0x2e,0xe7,0x25,0x25,0x2c,0x2f,0x25,0x20,0xd7,0xac,0xb2,0xc1,0xa7,0x9a,0x8d,0x8b,0x8b,0x8c,0x87,0x87,0x88,0x83,0x83,0x82,0x82,0x83,0x85,0x83,0x86,0x89,0x95,0x97 +,0x98,0xa6,0xb6,0x20,0x16,0x0f,0x0e,0x08,0x05,0x09,0x06,0x07,0x08,0x0a,0x0b,0x0b,0x0c,0x0b,0x0a,0x0b,0x0c,0x0d,0x14,0x15,0x1b,0x1f,0x18,0x1a,0x22,0x2a,0x2e,0x28 +,0x25,0x2c,0xca,0xaa,0xaf,0xa9,0x9f,0x9c,0x9d,0xa6,0xa6,0xac,0xa5,0x9b,0x95,0x96,0x9a,0x8d,0x91,0x90,0x96,0x96,0x94,0xa4,0xae,0x9f,0x98,0x99,0x9d,0x9b,0x99,0x9e +,0x97,0xaf,0xbe,0x33,0x38,0x53,0xb6,0xa2,0xb6,0xb3,0xbd,0xc3,0x48,0x4d,0x2a,0x2a,0x1c,0x14,0x17,0x3e,0xd3,0x22,0x1b,0x16,0x1f,0x23,0x27,0x2d,0x25,0x19,0x0f,0x14 +,0x1e,0x2d,0x29,0x1f,0x19,0x14,0x23,0x33,0x2c,0x29,0x2f,0x2a,0x24,0x33,0x4d,0x41,0x33,0x21,0x27,0x2a,0x1c,0x24,0x2f,0x54,0x2e,0x2d,0x2b,0x24,0x3d,0xee,0xaa,0xa4 +,0x91,0x8d,0x8b,0x87,0x88,0x88,0x85,0x83,0x82,0x83,0x85,0x88,0x8a,0x83,0x84,0x87,0x96,0xb0,0x4e,0x29,0x26,0x1b,0x13,0x0d,0x0b,0x0c,0x0c,0x0e,0x0d,0x09,0x05,0x03 +,0x0a,0x0d,0x0d,0x09,0x0c,0x11,0x18,0x16,0x13,0x16,0x15,0x13,0x15,0x14,0x1b,0x2c,0xd4,0xba,0xc0,0x9d,0xa2,0xac,0xb9,0x5b,0xb0,0xa8,0x9f,0x96,0x95,0x8f,0x96,0x94 +,0x94,0x93,0x8d,0x9b,0xac,0xac,0x9a,0x90,0x8f,0x95,0x97,0x99,0xa5,0xa2,0xa0,0x95,0x9a,0xb8,0x5b,0xca,0x9e,0x9c,0x9a,0x9f,0xba,0x45,0x49,0x44,0xef,0x39,0x49,0x75 +,0x3f,0x2c,0x27,0x29,0x2e,0x32,0x24,0x1f,0x14,0x1f,0x1d,0x1b,0x27,0x2a,0x25,0x1b,0x13,0x13,0x1d,0x1c,0x1f,0x26,0x23,0x25,0x23,0x1a,0x1c,0x2c,0x31,0x20,0x18,0x1d +,0x24,0x47,0x57,0x39,0x37,0x1e,0x12,0x12,0x1c,0x35,0x3e,0x23,0x2e,0xc6,0xaa,0xa3,0x9a,0x96,0x97,0x8f,0x8a,0x8a,0x8c,0x88,0x83,0x81,0x82,0x83,0x83,0x85,0x89,0x8a +,0x8c,0x90,0x9a,0x99,0xa6,0xb2,0x49,0x20,0x1b,0x0f,0x09,0x06,0x06,0x05,0x09,0x0b,0x0f,0x10,0x0d,0x0c,0x0b,0x0e,0x0e,0x13,0x0a,0x04,0x0b,0x16,0x2f,0x2b,0x1e,0x19 +,0x22,0x30,0x48,0x2f,0x29,0x2c,0x34,0xb2,0xa9,0x9d,0x9f,0xa0,0xa2,0x9f,0x91,0x96,0x9f,0xac,0x9d,0x8f,0x94,0x8f,0x95,0x98,0x97,0x99,0x9d,0x9b,0x9f,0x9f,0x98,0x9c +,0x95,0x9c,0x9e,0xab,0xac,0xb5,0xc7,0xbc,0xce,0xa9,0xa3,0xb5,0x2f,0x31,0xb8,0xbd,0xf4,0xd8,0x24,0x1c,0x1b,0x38,0xbf,0x2c,0x1b,0x15,0x19,0x21,0x25,0x1e,0x1f,0x1f +,0x2a,0x49,0xc5,0x2b,0x19,0x17,0x16,0x26,0x25,0x18,0x13,0x16,0x1e,0x3a,0x5e,0x38,0x20,0x19,0x21,0x1b,0x16,0x1c,0x2b,0xe6,0x3e,0x2d,0x2c,0x1f,0x2a,0xb6,0xcd,0x3f +,0x2e,0x4a,0x9d,0x91,0x86,0x83,0x86,0x87,0x86,0x82,0x82,0x84,0x88,0x88,0x86,0x84,0x83,0x8c,0x91,0x97,0x9a,0x99,0xab,0x23,0x0e,0x0e,0x0c,0x16,0x15,0x0b,0x0a,0x08 +,0x07,0x08,0x07,0x06,0x07,0x0b,0x10,0x11,0x0d,0x0a,0x0e,0x1c,0x1e,0x1c,0x14,0x14,0x1f,0x24,0x2d,0x36,0xcf,0xef,0x3c,0xa8,0xad,0x37,0x2a,0xc9,0x9f,0xa5,0xa1,0xa1 +,0xa6,0xa5,0xa0,0x90,0x90,0xa4,0xb7,0xa6,0x95,0x91,0x96,0x9b,0xa6,0x9a,0x98,0xa5,0x9b,0xac,0xb9,0x9e,0x9d,0x9d,0x9a,0xa0,0xb4,0xa8,0xa7,0xbb,0xde,0x65,0x59,0xe5 +,0x35,0xb9,0xa7,0xe9,0x52,0xb1,0xb5,0x2e,0x28,0x1f,0x2d,0x41,0x28,0x2d,0x30,0x5f,0x2d,0x1b,0x1a,0x0e,0x14,0x19,0x21,0x20,0x19,0x26,0x41,0x2c,0x25,0x1e,0x1c,0x1b +,0x1b,0x22,0x16,0x17,0x17,0x35,0x51,0x2d,0x39,0x20,0x1a,0x18,0x1e,0x2b,0x2b,0x2d,0xb2,0x9d,0xa6,0x92,0x9c,0x9d,0x8c,0x80,0x8f,0x1c,0x81,0x82,0x8a,0x81,0x8c,0x95 +,0xd9,0xbe,0x1e,0x44,0x16,0x03,0x17,0x04,0x03,0x03,0x03,0x07,0x02,0x02,0x05,0x07,0x06,0x0a,0x09,0x0b,0x0b,0x0a,0x10,0x1e,0x31,0xbc,0xbe,0xaa,0x93,0x81,0x83,0x8f +,0x88,0x82,0x83,0x85,0x81,0x81,0x82,0x83,0x85,0x85,0x86,0x85,0x87,0x86,0x89,0x8d,0x8e,0x92,0x8a,0x8e,0x8b,0x9c,0xa1,0x9a,0xc7,0x23,0x15,0x18,0x0f,0x11,0x0c,0x09 +,0x0f,0x0b,0x05,0x04,0x03,0x03,0x04,0x06,0x02,0x03,0x05,0x04,0x02,0x01,0x02,0x00,0x01,0x01,0x04,0x03,0x02,0x06,0x03,0x09,0x0b,0x0a,0x09,0x04,0x11,0x26,0x14,0x1a +,0x2f,0x19,0xb9,0xa7,0x91,0x8e,0x93,0x86,0x85,0x81,0x82,0x83,0x83,0x80,0x83,0x80,0x85,0x82,0x80,0x85,0x80,0x82,0x81,0x81,0x80,0x80,0x80,0x80,0x80,0x82,0x81,0x82 +,0x85,0x81,0x8b,0x85,0x83,0x8f,0x85,0x87,0x87,0x8d,0x8b,0x81,0x89,0x8d,0x8a,0xb0,0xa8,0x1b,0x17,0x26,0x01,0x0e,0x06,0x01,0x06,0x01,0x02,0x01,0x04,0x09,0x01,0x04 +,0x03,0x00,0x02,0x00,0x07,0x05,0x00,0x06,0x00,0x02,0x01,0x03,0x0a,0x01,0x17,0x09,0x04,0x1c,0x06,0x0b,0x03,0x02,0x1d,0x01,0x1d,0x12,0x00,0x15,0x07,0x22,0x19,0x47 +,0x9d,0x15,0xb5,0x21,0x1c,0xc1,0x13,0x91,0x2e,0x2a,0x8f,0x29,0x9c,0xa1,0x8c,0x8b,0x8f,0x80,0x87,0x80,0x83,0x86,0x87,0x98,0x83,0x82,0x90,0x82,0x91,0x8d,0x84,0x87 +,0x82,0x8d,0x83,0x86,0x85,0x80,0x8e,0x86,0x94,0x9f,0x81,0x9d,0x8f,0x8d,0xb1,0x94,0x95,0x8a,0x94,0x87,0x86,0x8b,0x80,0x8b,0x8f,0x8e,0x99,0x86,0x89,0xa4,0x89,0x8f +,0x8f,0x8e,0x8c,0x8a,0x8e,0x87,0xba,0x8e,0x92,0x16,0x1e,0x0a,0x0e,0x15,0x05,0x07,0x0f,0x03,0x08,0x0d,0x29,0x19,0x48,0x9f,0xc2,0x88,0x29,0x27,0xaf,0x16,0x23,0x40 +,0x0f,0x18,0x0d,0x0b,0x0e,0x0d,0x19,0x05,0x28,0x0b,0x16,0x15,0x00,0x0b,0x03,0x01,0x04,0x05,0x00,0x04,0x01,0x05,0x00,0x08,0x03,0x07,0x1a,0x02,0x13,0x05,0x01,0x08 +,0x00,0x01,0x05,0x03,0x00,0x03,0x02,0x03,0x00,0x0b,0x00,0x0e,0x10,0x06,0x13,0x00,0x09,0x0c,0x01,0x07,0x0c,0x05,0x13,0x0e,0x19,0x1b,0xaf,0x98,0xc2,0x82,0x93,0x84 +,0x82,0x8d,0x82,0x8d,0x89,0x81,0x8a,0x87,0x82,0x86,0x82,0x82,0x80,0x82,0x80,0x81,0x83,0x80,0x81,0x80,0x83,0x8e,0x84,0x83,0x8d,0x81,0x81,0x81,0x81,0x81,0x80,0x80 +,0x80,0x81,0x80,0x80,0x80,0x81,0x82,0x82,0x80,0x8b,0x85,0x82,0x8c,0x8d,0x91,0x8a,0x40,0x9a,0x1f,0x06,0x13,0x02,0x02,0x00,0x00,0x01,0x00,0x01,0x09,0x00,0x02,0x03 +,0x05,0x01,0x05,0x0b,0x00,0x02,0x05,0x00,0x02,0x00,0x08,0x04,0x00,0x17,0x00,0x03,0x0b,0x03,0x04,0x05,0x16,0x04,0x02,0x1f,0x02,0x06,0x05,0x16,0x0f,0x04,0x8a,0x13 +,0x0b,0x97,0x37,0x32,0x28,0x8b,0x50,0x13,0x87,0x17,0x1e,0xaf,0x94,0x62,0x20,0x80,0x53,0x12,0x8a,0xa0,0x33,0xb1,0x82,0xd6,0x19,0x85,0x26,0x1f,0x96,0x8b,0x2d,0xb0 +,0x80,0x9f,0x3a,0x85,0x8a,0x5b,0x9c,0x80,0xbd,0x37,0x84,0x59,0x29,0x98,0x88,0x1d,0xa8,0x83,0x35,0x3b,0xa1,0x45,0x0b,0xff,0x8a,0x07,0x14,0xa6,0x06,0x02,0x20,0xaf +,0x03,0x1c,0x9a,0x14,0x1c,0xae,0xab,0xbf,0x89,0x80,0x9a,0x8b,0x84,0x93,0x87,0x80,0x83,0x8b,0x81,0x82,0x8e,0x8c,0x88,0x98,0x1a,0x9b,0x97,0x0b,0x11,0x0a,0x00,0x03 +,0x1a,0x0b,0x00,0x0b,0x08,0x05,0x0c,0x14,0x10,0x07,0x5c,0xab,0x1a,0x45,0x1e,0x1d,0xc6,0x89,0xa0,0xa2,0x8d,0xa2,0xa4,0x98,0x98,0xb9,0x3d,0x8a,0x8d,0x99,0x91,0x3f +,0x3e,0xa0,0x88,0xa3,0x9b,0x91,0xad,0xa6,0x93,0x8f,0xa2,0xd8,0x88,0x8e,0x98,0x98,0x25,0x32,0x9d,0x8a,0xa0,0x90,0x98,0xe5,0xe7,0xab,0xa2,0x21,0x12,0xa4,0x59,0x2e +,0x21,0x09,0x08,0x1c,0x5b,0x0e,0x39,0x1d,0x09,0x0d,0x19,0xc1,0x1c,0x0c,0x9c,0xb1,0xc9,0x22,0x0e,0x1c,0x77,0xa7,0x1f,0x9c,0xc7,0x0a,0x15,0x37,0x30,0x0d,0x00,0x23 +,0x1d,0x0f,0x14,0x06,0x04,0x0c,0x11,0x0d,0x20,0x18,0x07,0x0a,0x1c,0x59,0x2c,0x1f,0x8c,0x88,0x89,0x88,0x96,0x8e,0x87,0x80,0x81,0x80,0x80,0x88,0x89,0x81,0x82,0x89 +,0x9d,0x8b,0x8d,0xa6,0xbc,0x0d,0x07,0x0b,0x13,0x08,0x0d,0x07,0x02,0x02,0x05,0x16,0x0d,0x01,0x13,0x17,0x12,0x18,0x09,0x08,0x0f,0xc2,0x32,0x9c,0x9e,0x1a,0x1b,0x3e +,0x9d,0xb4,0x10,0xb1,0xac,0xb2,0x9f,0x24,0x1e,0x26,0x92,0xac,0x93,0x8f,0x2b,0x36,0xa3,0x8a,0x8c,0xcc,0x8c,0x89,0x8e,0x89,0xa0,0xae,0xb8,0x8a,0x90,0x8b,0x86,0xa7 +,0x47,0xd1,0x9c,0x97,0x1d,0x4c,0xad,0x59,0xa8,0x1b,0x0f,0x14,0xaf,0x1d,0x3e,0xa1,0x1c,0x0a,0x0d,0x41,0xa5,0x19,0x1a,0xb4,0x4d,0xe6,0x13,0x13,0x17,0xa2,0x49,0xaa +,0x8d,0x25,0x0f,0x15,0x34,0xb5,0x0f,0x0b,0x32,0x1f,0x4a,0x16,0x0e,0x0c,0x21,0x14,0x15,0xd4,0x12,0x07,0x07,0x19,0xcb,0x25,0x24,0x98,0x95,0x8c,0x96,0x96,0x91,0x84 +,0x82,0x83,0x80,0x81,0x88,0x87,0x82,0x81,0x86,0x94,0x89,0x8d,0x8f,0x2f,0x16,0x0d,0x1b,0x0f,0x06,0x1c,0x0b,0x01,0x00,0x05,0x0d,0x07,0x01,0x12,0x11,0x14,0x08,0x07 +,0x0e,0x2b,0x1e,0x1c,0x98,0xa5,0x1a,0x12,0x43,0x9e,0xd0,0x1b,0xa9,0xb6,0xac,0x33,0x1f,0xc9,0x9d,0x77,0xd0,0x8c,0x8e,0xc2,0x1c,0xa8,0x89,0x93,0xa9,0x93,0x94,0x8e +,0xaa,0xae,0x9f,0x88,0x96,0xa1,0x82,0x85,0x95,0x22,0x4d,0x8a,0xac,0x21,0xa3,0xa6,0xa6,0x1d,0x16,0x58,0x8f,0x23,0x0f,0x9b,0x9c,0x13,0x03,0x0f,0x9b,0x46,0x18,0xb2 +,0xd6,0x3c,0x0c,0x0e,0x49,0x8f,0x1b,0x10,0x8c,0x8e,0x1b,0x08,0x10,0x9f,0x21,0x09,0x1d,0x1c,0x10,0x04,0x05,0x27,0x9c,0x0a,0x0a,0xaf,0xb6,0x08,0x00,0x0a,0xb1,0x1c +,0x14,0xb0,0x96,0x9e,0x12,0xb2,0x84,0x80,0x92,0x8a,0x80,0x80,0x86,0x8c,0x85,0x80,0x88,0x8a,0x86,0x80,0x8e,0x1b,0x58,0x87,0x8d,0x0f,0x09,0x4a,0x31,0x05,0x00,0x0c +,0x18,0x02,0x06,0x0c,0x3a,0x0a,0x00,0x05,0xa2,0xe8,0x03,0x0b,0xbb,0x99,0x0c,0x05,0x69,0xb1,0x13,0x1f,0x40,0x8e,0x13,0x02,0xaf,0x80,0x8f,0x35,0x35,0x8c,0x9b,0x0f +,0x1e,0x94,0x8e,0xc8,0xac,0x8c,0x86,0x1d,0x0d,0x8e,0x81,0x9d,0x44,0xb0,0x8c,0x95,0x30,0x9e,0x87,0x91,0xa6,0xb6,0x8d,0x98,0x0c,0x0e,0x8c,0x86,0xac,0x53,0xc6,0x97 +,0xc8,0x0c,0x22,0x46,0x25,0x16,0x18,0xaf,0x1d,0x00,0x12,0x8b,0xa2,0x25,0x19,0x2a,0xa8,0x17,0x18,0xb9,0xa0,0xb3,0x13,0x3f,0x3d,0x09,0x06,0xaf,0x99,0x4b,0x13,0x13 +,0xb5,0x1c,0x09,0x0c,0x0e,0x15,0x10,0x07,0x1c,0x0c,0x01,0x1c,0x90,0x94,0x9d,0xa2,0x8a,0x86,0x8e,0x88,0x83,0x81,0x81,0x80,0x82,0x81,0x8f,0x8f,0x81,0x82,0x85,0x8c +,0x8f,0x8f,0x25,0x12,0x0f,0x06,0x13,0x0a,0x03,0x03,0x00,0x00,0x10,0x37,0x1e,0x0d,0x0a,0x13,0x07,0x02,0x13,0x0e,0x22,0x50,0x1f,0x25,0x0e,0x09,0x9d,0x88,0xbf,0xac +,0x2d,0x9f,0x75,0x10,0x9b,0x95,0x93,0x93,0xf7,0xac,0x0f,0x08,0x92,0x83,0x8a,0x9f,0xac,0x8c,0x91,0x2d,0x93,0x94,0x8e,0x9c,0xba,0x8f,0x34,0x16,0x9f,0x82,0x89,0x99 +,0x3b,0x8e,0x9c,0x0f,0x3d,0x27,0xa8,0x9d,0x3a,0x26,0x0d,0x03,0xde,0x96,0x98,0xad,0x14,0xa8,0x1f,0x26,0xb1,0x1c,0xc2,0xe3,0x1f,0x15,0x07,0x10,0x92,0x4f,0x3e,0x4e +,0x1f,0xab,0x08,0x15,0x17,0x0a,0x1f,0x1a,0x0d,0x0f,0x00,0x0a,0x95,0x14,0x1a,0x0c,0x12,0x3d,0x03,0x1c,0x2e,0xd8,0x8e,0xa9,0x9c,0xbe,0xdc,0x88,0x82,0x84,0x82,0x8b +,0x80,0x81,0x86,0x80,0x8b,0x82,0x88,0x8f,0x93,0x16,0x12,0x87,0xaf,0xa8,0x22,0x0c,0x1c,0x00,0x09,0x00,0x0f,0x26,0x07,0x09,0x09,0x00,0x3f,0xb3,0x1f,0xba,0x07,0x33 +,0x10,0x0b,0x2b,0x1a,0x9c,0xab,0x24,0x13,0x06,0x58,0x8b,0xd3,0x9e,0xc7,0x8f,0x90,0x10,0x9c,0x2c,0xa3,0x8b,0x2f,0xac,0x19,0x15,0x86,0x8a,0x8e,0x8f,0xba,0x81,0xc3 +,0x27,0xb5,0xa6,0x89,0xa8,0x43,0x1c,0x0f,0x90,0x90,0x25,0x90,0x0d,0x94,0xa5,0x08,0x44,0x15,0x9e,0x9b,0x09,0x0a,0x00,0x0c,0x87,0x1f,0xa8,0x29,0xa0,0x8c,0x0e,0x3c +,0x10,0xb1,0x8c,0x10,0x14,0x06,0x04,0x83,0x9d,0x99,0xb6,0x1f,0x92,0x0e,0x1b,0x14,0x32,0x8b,0x49,0x3c,0x13,0x04,0x8a,0x9e,0x43,0xaf,0x12,0x85,0x31,0x1f,0xb0,0xb4 +,0x82,0x95,0xb4,0x2a,0x0d,0x8f,0x87,0xb6,0x9c,0x1a,0x89,0xa1,0x52,0x3c,0x0b,0x8e,0x9b,0x0f,0x10,0x00,0x23,0x85,0x1a,0xbf,0x0a,0xc9,0x33,0x08,0x1b,0x04,0xab,0xad +,0x1c,0x1e,0x04,0x21,0x80,0x54,0x92,0x1e,0x9f,0x8a,0x11,0xbf,0x22,0x8b,0x86,0x9c,0x54,0x08,0x28,0x80,0x9b,0x8e,0x29,0xa2,0x85,0x4e,0xae,0x0a,0xb6,0x86,0x55,0x2c +,0x0a,0x0d,0x80,0x9a,0x8c,0x35,0xb5,0x86,0xd8,0x9e,0x09,0xbc,0x8a,0xc5,0x3d,0x0b,0x07,0x80,0x2e,0xdf,0x18,0x0d,0x8e,0x0c,0x25,0x01,0x18,0x8d,0x4b,0x0e,0x07,0x00 +,0x8c,0x2a,0x26,0x16,0x0c,0x86,0x0f,0x26,0x0b,0x0e,0x8e,0xcc,0x1a,0x0e,0x00,0x87,0x9f,0x99,0x24,0x12,0x87,0x16,0xce,0x06,0x0c,0x88,0xd7,0x17,0x14,0x02,0x80,0x9e +,0xaf,0x65,0x1e,0x82,0xa4,0x90,0x1f,0xa8,0x81,0x8a,0x8a,0x38,0x0f,0x80,0x8e,0x89,0x9e,0x2c,0x81,0x8f,0x8e,0x1c,0x46,0x8c,0x99,0x1a,0x0a,0x00,0x8b,0x4c,0x1e,0x14 +,0x07,0x95,0x09,0x10,0x01,0x05,0x51,0x2e,0x0b,0x07,0x00,0x8c,0x94,0xbb,0x13,0x0d,0x86,0x66,0x95,0x0c,0x1d,0x84,0x8e,0xaa,0x11,0x07,0x84,0x8e,0x99,0x21,0x0f,0x8a +,0xbf,0x8f,0x0d,0x25,0x88,0x9b,0xae,0x0d,0x02,0x83,0x8d,0x98,0x47,0x11,0x83,0x91,0x8d,0x11,0x2c,0x88,0x8e,0x98,0x0d,0x08,0x80,0x8b,0x8d,0x37,0x06,0x8d,0xaa,0xa0 +,0x09,0x07,0xa2,0x9b,0x2d,0x0b,0x00,0xa7,0x97,0xa7,0x17,0x06,0x94,0x3e,0x98,0x13,0x0e,0x8e,0x8f,0xb9,0x13,0x01,0x8f,0x88,0x95,0x2e,0x09,0x8f,0xa3,0x8e,0x0a,0x03 +,0x9e,0x95,0xcd,0x13,0x00,0xa6,0x89,0xa1,0x2d,0x02,0xac,0xa9,0x92,0x0f,0x08,0xa7,0x8e,0x8b,0x3d,0x05,0x8f,0x84,0x8c,0x91,0x0c,0x8c,0x8d,0x88,0xbe,0x0f,0x9b,0x89 +,0x98,0x16,0x02,0x52,0x89,0xa2,0x33,0x00,0xca,0xb5,0xa3,0x13,0x00,0x1c,0xa7,0xbc,0x13,0x00,0x10,0x86,0x98,0xa5,0x05,0x53,0x9c,0x8f,0xa8,0x01,0x74,0x91,0x8c,0x5c +,0x05,0x1f,0x81,0x8f,0x8e,0x0a,0x21,0x8f,0x94,0xaa,0x04,0x3e,0x97,0x8e,0x2e,0x04,0x0b,0x87,0x8a,0x8d,0x10,0x16,0x8a,0x8f,0x8b,0x0b,0x1d,0x8f,0x80,0x93,0x0d,0x09 +,0x8b,0x85,0x86,0x26,0x0a,0x96,0x9f,0x8f,0x09,0x0a,0x39,0x9a,0xb8,0x0e,0x00,0x2f,0x89,0x9e,0x20,0x02,0xf1,0xb4,0x95,0x0e,0x06,0xcb,0x8e,0x9a,0x13,0x03,0xdf,0x81 +,0x8c,0xa2,0x05,0xae,0x90,0x8b,0x3c,0x09,0x3c,0x91,0x8d,0x1c,0x01,0x0b,0x87,0x8a,0xa1,0x06,0x11,0xa7,0x97,0xbf,0x06,0x29,0x98,0x8c,0xeb,0x0a,0x0f,0x89,0x85,0x86 +,0x26,0x15,0x8a,0x8e,0x8d,0x18,0x27,0x92,0x87,0xa1,0x0b,0x08,0x95,0x84,0xa1,0x1a,0x04,0xb3,0xae,0xb6,0x09,0x00,0x2e,0x9f,0xf6,0x0e,0x00,0x15,0x86,0x96,0x73,0x03 +,0x34,0x98,0xa5,0x49,0x07,0xc7,0x8f,0x93,0x26,0x0a,0x21,0x83,0x92,0xa0,0x10,0x1d,0x8f,0xba,0xae,0x08,0x28,0x91,0xa8,0x1c,0x0a,0x09,0x8b,0x89,0xb8,0x1d,0x0f,0x8a +,0x9a,0xa7,0x15,0x28,0x8a,0x8a,0x98,0x16,0x0b,0x99,0x82,0x95,0x9a,0x0c,0xa6,0x96,0xcb,0x26,0x0c,0xa7,0x97,0xbc,0x0f,0x08,0x0b,0x8d,0xa6,0x2b,0x0f,0x20,0x99,0x19 +,0x22,0x07,0x4d,0x90,0x98,0x25,0x0d,0x0e,0x8e,0x89,0xae,0xd1,0x17,0x8b,0x9d,0xf6,0x0c,0x1e,0x91,0x90,0xb1,0x0d,0x04,0x22,0x86,0xbb,0x36,0x07,0x38,0xa8,0x35,0x21 +,0x0b,0xbb,0x9c,0x9d,0x1e,0x11,0x18,0x89,0x93,0x96,0x3a,0x4f,0x8a,0xc2,0xaf,0x1a,0x9c,0x8d,0x93,0x4b,0x14,0x0c,0x8f,0x8b,0xc0,0x41,0x0e,0x93,0xd7,0x24,0x08,0x0c +,0xab,0x9f,0x36,0x11,0x03,0x30,0x87,0xa4,0xa3,0x0a,0xa2,0x8f,0xae,0x5c,0x16,0xa5,0x8f,0x92,0xbe,0x16,0x19,0x88,0xa4,0x9d,0x28,0x5d,0x8f,0x1e,0x26,0x08,0x3f,0x98 +,0xbe,0x1c,0x0f,0x09,0x94,0x9a,0x24,0x2b,0x13,0x8b,0xc0,0x29,0x0e,0x25,0x8f,0x8d,0x9d,0x1c,0x0e,0xad,0x89,0xaf,0x9c,0x11,0x94,0x9a,0x20,0x1d,0x0e,0x9f,0x9a,0xaf +,0x1a,0x0a,0x07,0x93,0xc5,0x6f,0x1c,0xdc,0x97,0x14,0x25,0x0d,0xa0,0x8f,0x98,0x79,0x1a,0x0f,0x8e,0x8d,0xa8,0xad,0x24,0x85,0xaf,0x23,0x0c,0x32,0x91,0x8c,0xa3,0x11 +,0x03,0x1c,0x8b,0xaa,0xc8,0x0d,0x9b,0x51,0x18,0x16,0x0b,0xb5,0x95,0x9f,0x27,0x0b,0x0e,0x8b,0x9d,0xa0,0x33,0x9f,0x96,0x73,0xef,0x19,0x9c,0x95,0x97,0xab,0x1e,0x12 +,0x95,0xa3,0x55,0x1e,0x1e,0x8e,0x28,0x15,0x0a,0x19,0x9e,0x90,0x44,0x0d,0x06,0x2b,0x8b,0x9f,0x42,0x1e,0x8e,0x9d,0x9f,0x21,0x1c,0x8c,0x8e,0x94,0x3e,0x0b,0x0e,0x8a +,0xa7,0xb0,0x36,0x29,0x97,0x1f,0x11,0x0e,0xcb,0xb5,0x9c,0x4f,0x0f,0x0f,0xb4,0xa3,0xcd,0xb6,0x3f,0x88,0x2f,0x15,0x10,0x33,0x8a,0x89,0xb0,0x1b,0x0f,0x30,0x83,0xb3 +,0x2e,0x39,0x93,0xb5,0x5a,0x10,0x0e,0x9f,0xae,0x93,0x2a,0x02,0x07,0x95,0xb5,0xa3,0x2a,0x20,0x93,0x2d,0x2b,0x2d,0x9a,0x99,0x8d,0x45,0x1a,0x27,0xda,0x94,0x9f,0xa9 +,0xa8,0x8f,0x1e,0x2d,0x11,0x2f,0x8a,0x9e,0x25,0x11,0x08,0x27,0x89,0x31,0x35,0x20,0xb2,0xa8,0x35,0x0e,0x1e,0x97,0xaf,0x8e,0x2b,0x09,0x17,0x96,0x9a,0x91,0x44,0xb2 +,0x8e,0x40,0xc0,0x35,0xb0,0xa7,0xa1,0x21,0x29,0x0e,0x18,0xa7,0xc7,0x45,0xc4,0xb9,0x1a,0xd0,0x1a,0xab,0x96,0x49,0x2a,0x21,0x17,0xa7,0x8d,0x2d,0xbf,0xf8,0x96,0x92 +,0x28,0x13,0xdd,0x98,0x93,0x96,0x18,0x09,0x0f,0xb8,0x9a,0xa3,0x17,0x1b,0xb1,0x5e,0xa4,0x2d,0x44,0x9b,0xbf,0x53,0x2c,0x0e,0x1a,0xbf,0xda,0x9c,0xb9,0x2f,0x3b,0xd9 +,0xaa,0x99,0x97,0xb8,0xaa,0x3b,0xe0,0xdc,0xd4,0x45,0x3b,0x47,0x55,0xaa,0x15,0x1c,0xdc,0xa5,0x94,0x9e,0x28,0x1c,0x20,0x6b,0x9b,0x36,0x1d,0x1d,0x24,0xc1,0xac,0x44 +,0xc6,0xb7,0x9f,0x95,0xd2,0x1d,0x22,0x42,0x9b,0x96,0xd6,0x1e,0x1a,0xaf,0x9c,0x97,0x3a,0x26,0xae,0xbb,0xc2,0x1c,0x1e,0x26,0x46,0xa7,0xa8,0x24,0x16,0x25,0xe5,0x99 +,0x9d,0xc0,0x3c,0x51,0x55,0xae,0xaf,0x24,0x50,0xda,0xb6,0xba,0x28,0x30,0x29,0xd0,0x93,0x90,0x4f,0x1f,0x27,0x3d,0xb6,0x42,0x30,0x30,0x36,0x3a,0xa6,0xb1,0x27,0x43 +,0xc6,0xa0,0xcd,0x19,0x1c,0x28,0xcc,0xb4,0xb3,0x64,0x2c,0x3f,0xa8,0x9f,0xb9,0xc6,0x3e,0xd5,0xa0,0x9f,0x53,0x31,0x24,0x2f,0xa9,0xf1,0x38,0x18,0x21,0xab,0x9a,0xa2 +,0x25,0x1f,0xb4,0xa9,0xeb,0x2e,0x1a,0x22,0xb4,0x9d,0xbc,0x2a,0x34,0xa2,0x9c,0xac,0x2e,0x2b,0xc8,0xa8,0xa9,0xcd,0x3d,0x2e,0x9f,0xa5,0x44,0x2e,0x41,0xcd,0x71,0xbf +,0x41,0x36,0x3e,0x2f,0x2d,0x35,0x22,0x3b,0xf0,0x29,0x47,0xb0,0x99,0xa7,0xee,0xbc,0xbe,0x98,0x9d,0x48,0x27,0x29,0x4a,0xba,0xa5,0xdc,0x24,0x26,0x3f,0x63,0x38,0x29 +,0x50,0xa8,0xb0,0xd4,0x38,0x2f,0x2c,0xbe,0xa9,0x4e,0x3b,0x1e,0x33,0x37,0x38,0xb5,0xa5,0x97,0x96,0xba,0x3f,0x42,0x39,0x9b,0xdf,0xa8,0xb5,0xcf,0x37,0x1f,0xba,0xb6 +,0xb5,0x29,0x20,0x1c,0x25,0x14,0xd3,0x3a,0xb0,0xab,0x36,0xbd,0x12,0xde,0xa0,0x93,0x98,0xbe,0x2e,0x2c,0xc4,0xb2,0x38,0xa1,0x94,0x36,0xe7,0x1a,0x16,0xb8,0x32,0x3e +,0x4d,0x69,0xc4,0x5c,0x36,0xb5,0xb2,0x33,0xbb,0x2a,0x25,0x26,0x40,0x99,0x8c,0xc8,0xac,0x95,0x14,0x0a,0xcf,0x9e,0x1e,0x11,0x0a,0xbd,0x9e,0x89,0x88,0x25,0x53,0x72 +,0x15,0x0f,0x10,0x0b,0x94,0x85,0x9d,0x1f,0x25,0x89,0x87,0x8d,0x26,0x2e,0x58,0xd9,0x26,0x07,0xcd,0x85,0xc9,0x02,0x0f,0x46,0x93,0x17,0x0f,0x8e,0x80,0x86,0x1f,0x09 +,0x11,0x16,0x0f,0x03,0x10,0x2c,0x15,0x80,0x8b,0xb3,0xa1,0x9e,0x8c,0xa2,0x5c,0x28,0x00,0x0f,0x8d,0xa3,0x92,0x8d,0x80,0x44,0x16,0xd4,0x1e,0x13,0x04,0x19,0xb0,0x00 +,0xad,0x94,0x2c,0xa8,0x36,0x98,0x0f,0x11,0x04,0xaf,0x8f,0x8f,0xab,0x0f,0x0a,0x86,0x95,0x57,0x9c,0x9f,0x85,0x1a,0x1c,0x47,0x84,0x3d,0x21,0x2d,0x06,0x00,0x58,0x6c +,0x8b,0x81,0x88,0xaf,0x0b,0x56,0x0d,0x08,0x0f,0xa4,0x16,0x00,0x0d,0x83,0x8e,0x8a,0xa6,0x8d,0xbe,0x29,0xa2,0x0e,0xed,0x8d,0x88,0xec,0x07,0x2c,0x83,0xc4,0x91,0x13 +,0x1c,0x06,0x1c,0xa0,0x33,0x91,0x99,0xe0,0x0b,0x00,0x0b,0x81,0x9c,0xb4,0x1f,0x86,0xdb,0xbf,0x91,0xa0,0x8d,0x8e,0xd8,0x09,0x00,0x1a,0x80,0x99,0x88,0xca,0x8c,0x17 +,0x27,0xab,0x1d,0x17,0x29,0x9e,0x22,0x00,0x1e,0x81,0xa7,0xab,0x03,0x58,0x29,0x2b,0x1e,0xce,0x8e,0x98,0xbc,0x1d,0x05,0xac,0x80,0xa9,0xaf,0x21,0x84,0x1b,0x1c,0xa0 +,0x97,0xa1,0x3d,0x1a,0x0b,0x02,0xbc,0x80,0x32,0xa9,0x20,0x8f,0x0b,0x0a,0x13,0x1a,0xab,0x55,0x3b,0x13,0x0b,0x4e,0x85,0x36,0x88,0x9f,0x90,0x2a,0xaa,0x8f,0xa0,0xc2 +,0x19,0x9b,0xad,0x05,0x0b,0x88,0x40,0x9c,0x24,0x90,0x36,0x50,0xad,0x33,0x24,0x0e,0x20,0x08,0x00,0x17,0x82,0x1f,0x9f,0xaf,0x88,0x6c,0x6a,0x98,0xe3,0xa8,0x4b,0x8d +,0xa4,0x0c,0x0b,0x85,0xcf,0x9b,0xd1,0x94,0x1e,0x0b,0x26,0x11,0xdc,0xab,0x8c,0x37,0x03,0x00,0x8c,0x1e,0x27,0xbd,0x8e,0xb1,0x15,0xa4,0x37,0xa6,0x9a,0x84,0xab,0x07 +,0x06,0x82,0xa7,0xa7,0xb4,0x99,0x9b,0x15,0x31,0x14,0xad,0xa4,0x8d,0x2a,0x07,0x03,0x85,0x9c,0x22,0xc1,0xad,0x22,0x00,0x0f,0x1f,0x99,0xa0,0x8c,0xcc,0x0f,0x02,0x8a +,0x8d,0xaa,0x89,0x93,0xa9,0x02,0x35,0xa0,0x8e,0x94,0x88,0x42,0x0c,0x00,0x9a,0x91,0x1e,0x9a,0x38,0xa9,0x00,0x13,0x2f,0x61,0x1f,0xc4,0x36,0x0f,0x00,0x9b,0x84,0xb9 +,0x92,0xc3,0x8f,0x0b,0x44,0x90,0x94,0x99,0x98,0xca,0x12,0x04,0x9a,0x82,0x2f,0xb9,0x15,0x36,0x00,0x18,0x93,0x9a,0xb0,0xce,0x54,0x14,0x00,0x12,0x84,0x3c,0xb6,0x12 +,0xc4,0x21,0x36,0x8b,0xa4,0x96,0x8b,0x8a,0x3d,0x01,0x1b,0x80,0x38,0x52,0x1f,0x9a,0xcb,0x14,0x99,0x1e,0x38,0xab,0xab,0x1d,0x03,0x0e,0x80,0x1f,0x0c,0x08,0x26,0xaf +,0x0f,0x99,0xcf,0x95,0x92,0x96,0xb8,0x13,0x1c,0x80,0xd8,0x1e,0x37,0xaf,0xa4,0x08,0x99,0x9f,0x9e,0x9f,0x96,0x2c,0x08,0x00,0x8c,0x97,0x39,0xa4,0x39,0x9e,0x02,0x1e +,0x1c,0x2f,0xa7,0x9d,0x30,0x0d,0x00,0x8f,0x8c,0x38,0x8c,0x97,0x86,0x0b,0x22,0xb7,0xab,0x97,0x8b,0x94,0x19,0x00,0xa1,0x8b,0x13,0xa3,0x36,0x98,0x08,0x19,0xac,0xb6 +,0xad,0x9a,0x45,0x08,0x00,0x18,0x87,0xee,0x8d,0xc0,0x9a,0x10,0x27,0x8c,0x92,0x93,0x8c,0x9d,0x0a,0x00,0x19,0x80,0x9e,0x8f,0xa9,0x9b,0x0e,0x05,0x33,0xc3,0x93,0x87 +,0x99,0x09,0x00,0x09,0x82,0x59,0xaa,0x34,0x21,0x10,0x05,0xa0,0x98,0x8e,0x89,0x8d,0x1f,0x06,0x0a,0x81,0xa4,0x9f,0x9f,0x9f,0xc6,0x09,0x98,0x8f,0xa6,0xb3,0x58,0x0b +,0x06,0x04,0x85,0x96,0xd6,0xb9,0x1e,0x21,0x03,0x32,0xce,0x2f,0xa0,0x99,0x1d,0x0e,0x05,0x88,0x89,0x9c,0x91,0x2d,0x2c,0x02,0x38,0x8c,0x9f,0xa3,0x96,0x36,0x1d,0x00 +,0x99,0x8b,0x2a,0x95,0x46,0x99,0x0d,0x1b,0xb3,0x12,0x1e,0xac,0x19,0x0d,0x00,0xe3,0x83,0x4c,0x8b,0x9e,0x8b,0x25,0x1f,0x9b,0x21,0x49,0x92,0x9d,0x3c,0x04,0x2b,0x80 +,0xc3,0x96,0x33,0xca,0x0c,0x07,0xc4,0x2b,0xbc,0x94,0xbc,0x0e,0x01,0x0d,0x81,0x1f,0xfc,0xae,0x9d,0x2a,0x07,0x9c,0xac,0x96,0x89,0x8d,0x2d,0x07,0x09,0x81,0x9f,0x9f +,0x93,0x9e,0x3c,0x00,0x3e,0x29,0xd9,0x9c,0x96,0x37,0x09,0x07,0x87,0xa0,0x20,0xac,0x28,0x1b,0x00,0x2a,0x6e,0xbd,0x9c,0x8e,0x9e,0x1a,0x0c,0x8a,0x8a,0x4e,0x98,0xb1 +,0xb9,0x06,0x33,0xa5,0xa2,0x97,0x92,0x37,0x0a,0x00,0xa6,0x85,0x31,0x9b,0x2a,0x26,0x01,0x0d,0x45,0x3c,0xab,0x99,0xb1,0x0f,0x08,0xa4,0x80,0xa1,0x8d,0xcd,0xca,0x0e +,0x0d,0xa8,0xd0,0x9f,0x93,0x9f,0x17,0x09,0x49,0x80,0x39,0xbe,0x4b,0x3c,0x19,0x06,0xb9,0x68,0xbb,0xa5,0x2e,0x0c,0x04,0x0f,0x80,0xc6,0x3a,0xb4,0xe1,0xad,0x0e,0x98 +,0x95,0x9c,0x94,0xa1,0x22,0x12,0x0f,0x81,0x9f,0x28,0xaf,0x24,0xa2,0x08,0x53,0xae,0x49,0xa7,0xa2,0x1d,0x0e,0x00,0x95,0x9a,0x0d,0xb3,0x1d,0x99,0x0d,0x4f,0x93,0xa2 +,0x8f,0x91,0xad,0x26,0x09,0x9b,0x87,0x13,0xa5,0x39,0x9a,0x10,0x14,0x9e,0x5f,0x98,0x9c,0xe8,0x1e,0x05,0x29,0x83,0x1c,0x3f,0x1d,0x3c,0x12,0x09,0xa0,0x34,0x9f,0x92 +,0x9d,0x2a,0x0a,0x13,0x80,0x9b,0x9c,0xa0,0xaf,0x36,0x0a,0x93,0x9f,0x9c,0x9d,0xa8,0x19,0x09,0x08,0x87,0x99,0x17,0x6a,0x30,0xbd,0x03,0x31,0x36,0x3c,0x47,0xbf,0x35 +,0x11,0x09,0x8f,0x83,0xd8,0x9a,0xaf,0x90,0x15,0xf4,0xa5,0x58,0xae,0xaf,0x2f,0x0f,0x04,0xcc,0x81,0x27,0xb4,0xd2,0x9e,0x13,0x1c,0x93,0xb6,0xd5,0x3a,0x1c,0x0c,0x03 +,0x19,0x80,0x35,0x2d,0xd6,0x92,0xa4,0x21,0x92,0xa7,0xaf,0xae,0xba,0x29,0x0f,0x0c,0x82,0xa1,0x3a,0xb6,0xd5,0xd3,0x0e,0xa3,0x4a,0x1f,0x3c,0xa9,0x2d,0x12,0x00,0x91 +,0x96,0x11,0xbc,0xc2,0x98,0x1a,0x9c,0x9a,0x3c,0xbd,0x95,0xa3,0x2d,0x07,0xa0,0x86,0x18,0xdd,0xcc,0x94,0x18,0x1c,0x43,0x0f,0x1f,0x9c,0x98,0x27,0x04,0x19,0x81,0xc8 +,0xa8,0xa6,0xa3,0x17,0x0b,0xaf,0x1d,0x29,0xa5,0x90,0xd7,0x0d,0x0e,0x84,0x99,0x4f,0x97,0x9b,0x35,0x07,0xb8,0xcb,0x32,0xac,0x9b,0x2b,0x0b,0x03,0x9b,0x89,0x2b,0x9c +,0x92,0xa1,0x0e,0x1d,0xc1,0x1b,0xe5,0x98,0xaa,0x17,0x08,0x31,0x82,0x9c,0xa2,0x99,0x46,0x15,0x0f,0x9e,0x19,0x13,0xc0,0x9a,0x45,0x0e,0x0c,0x8f,0x91,0x27,0x8f,0xab +,0xac,0x13,0xa0,0xa2,0x35,0x9d,0x93,0xb0,0x11,0x07,0x2e,0x88,0x0f,0xbf,0xa8,0xab,0x1e,0x17,0xbf,0x10,0x61,0x9b,0x9a,0x1d,0x0a,0x11,0x85,0xa1,0x20,0x99,0xae,0xaf +,0x18,0x9d,0x28,0x1c,0x9b,0x86,0x88,0x3e,0x08,0x2a,0x94,0x0d,0xa4,0x99,0xc1,0x0b,0x13,0xb9,0x1c,0xb4,0x95,0x8d,0x35,0x09,0x06,0x98,0x20,0x18,0x89,0x93,0x56,0x0c +,0xf2,0x33,0x30,0x92,0x86,0x93,0x1c,0x0a,0x9f,0x83,0x29,0x98,0x9a,0x29,0x0d,0x0f,0x27,0x09,0x26,0x8d,0x8b,0x3e,0x09,0x06,0x93,0xa9,0x33,0x8c,0xc2,0x1d,0x0d,0xaf +,0xaf,0x34,0x8f,0x8e,0xa4,0x25,0x0c,0x23,0x97,0x29,0x94,0x85,0x9a,0x1d,0x0b,0x2a,0x15,0xad,0x8f,0xaf,0x18,0x0b,0x09,0xb2,0x8f,0xcf,0x8b,0x95,0xcb,0x0f,0x16,0x1e +,0x22,0x91,0x8c,0xa7,0x15,0x0c,0x09,0x91,0x96,0xac,0x96,0x4a,0x2f,0x2e,0x9e,0xad,0xbe,0xb2,0xad,0x36,0x28,0x0a,0x0b,0x99,0xc3,0x96,0x90,0xbb,0x1c,0x16,0xc3,0xaf +,0xa3,0xc4,0x2d,0x2d,0xfb,0x19,0xad,0x95,0x4b,0x9a,0x98,0xb3,0x0e,0x0d,0xfd,0xac,0x9b,0xa5,0xe1,0x28,0x15,0x11,0xa8,0x9b,0x23,0x70,0xbb,0xaf,0x28,0xaf,0x9c,0xb0 +,0xa9,0x9b,0xa2,0x15,0x0f,0x0d,0x8f,0x8f,0xde,0xc7,0x2b,0x21,0x22,0xa7,0xbc,0x1f,0x1a,0xb1,0xab,0x9f,0xec,0x25,0x96,0xa9,0xfc,0x9f,0x33,0x12,0x0f,0xbd,0xa4,0x2f +,0xb8,0xaf,0xb9,0xce,0x3d,0x6e,0xa3,0x1e,0x30,0x9d,0x9e,0x38,0x1c,0xb5,0x64,0xa8,0xaa,0x2f,0x1e,0x26,0x2f,0xca,0x95,0xa9,0x31,0xab,0xdb,0x19,0x1c,0x23,0x23,0x61 +,0x9d,0x9b,0xb5,0x3f,0xfc,0xa7,0x89,0xb8,0x1d,0x30,0x17,0x29,0x6d,0xb2,0x26,0x3e,0xaf,0x5b,0x65,0xb7,0x7a,0x34,0xd7,0xc3,0x9f,0xc6,0xbd,0x44,0x5e,0xa9,0x5d,0x4b +,0x14,0x1c,0xac,0xaf,0xbc,0xda,0x2b,0xb7,0xd8,0xbe,0xae,0x49,0x2f,0x1f,0xae,0xa3,0xdf,0x3d,0xa5,0xa3,0xc4,0x2e,0x28,0x26,0x2e,0xba,0xc2,0xa9,0x3c,0x2e,0x2e,0xd9 +,0xb5,0x3f,0x3c,0x38,0x4d,0xb0,0xa7,0xa8,0xa5,0x4c,0xd2,0xbe,0xbf,0x33,0x1c,0x2f,0x3b,0x75,0xca,0x2b,0xbb,0xa7,0xbe,0xa9,0x66,0x2d,0x1b,0x2e,0xa6,0xa4,0xbc,0x35 +,0x5e,0xad,0xba,0x3c,0xd6,0x51,0x31,0x2e,0x40,0xdc,0xb6,0xa8,0xc5,0x3e,0x42,0x2d,0x4c,0xd3,0x4f,0xb0,0xc8,0xbe,0x3e,0x59,0xb2,0xb3,0xb1,0x45,0x23,0x24,0x4a,0xb5 +,0xaa,0xd1,0x48,0x3d,0x48,0x2a,0x33,0x60,0x4d,0xdf,0x76,0xb9,0xbc,0xb3,0xa1,0x9c,0xa9,0x32,0x28,0x33,0x2e,0x39,0xda,0x42,0x2f,0x25,0x2f,0xba,0x9f,0x9d,0xad,0x31 +,0x23,0x6b,0xa9,0xa5,0xd8,0xc1,0x3f,0x18,0x1a,0x2d,0xbf,0xac,0xa6,0xa8,0xb0,0x3e,0x4d,0xd1,0xb6,0xbf,0x35,0x2a,0x1f,0x27,0xd6,0xac,0xab,0xab,0xae,0xf2,0x31,0x5f +,0xc7,0xb6,0xc9,0x33,0x29,0x2c,0x2c,0xce,0xaa,0xcd,0xe1,0x5f,0x75,0x31,0x35,0xa7,0x9e,0xab,0x44,0x2b,0x38,0x36,0xea,0xa9,0xba,0x3d,0x2e,0x3e,0x47,0x41,0xc2,0xca +,0xbf,0xc1,0xcf,0x4b,0x2f,0x3e,0xc8,0xdb,0xce,0xa6,0xb4,0x6a,0x2f,0x51,0x56,0x3c,0x48,0x3f,0xbf,0x46,0x2d,0xe8,0xb1,0xab,0xa5,0xae,0xb9,0x2f,0x2d,0x39,0x37,0xce +,0xd1,0xb8,0x59,0x2e,0x36,0x43,0xbf,0xb4,0xbe,0xce,0x38,0x31,0x31,0x58,0xb4,0xaf,0xa9,0x3a,0x17,0x1d,0x76,0x9f,0x98,0x9a,0xaa,0x26,0x1d,0x26,0xc9,0xa8,0xc2,0xbf +,0x3e,0x20,0x2c,0x6c,0xb1,0xa9,0xb7,0xaf,0x2d,0x25,0x2c,0x4b,0xae,0xba,0x9d,0xa8,0x2b,0x1d,0x26,0x3c,0xbe,0xb2,0x9b,0xb1,0x33,0x3a,0x2e,0xb4,0xb2,0xab,0xa8,0x2b +,0x1d,0x28,0x2f,0xa8,0xb3,0xae,0x50,0x1e,0x2f,0x26,0xdb,0xc1,0x59,0xbb,0x78,0x44,0xaf,0xc4,0xb6,0xc2,0xb4,0xa7,0x56,0xd5,0x38,0x4f,0xb2,0xa6,0xa4,0x5c,0x1d,0x1a +,0x24,0xfa,0xbc,0xb6,0xb2,0x28,0x20,0x2e,0xe2,0xad,0xa7,0xad,0x6d,0x27,0x36,0xdf,0xa8,0x9f,0xa3,0x9c,0x51,0x27,0x21,0x27,0x3f,0x6b,0xcd,0xf4,0x33,0x37,0x3e,0x2c +,0x35,0x3d,0xa2,0xa0,0xde,0x2f,0x2b,0x52,0xbb,0xa3,0x9e,0xbc,0x33,0x38,0xde,0xba,0xca,0xad,0xab,0x59,0x39,0x40,0x43,0x2b,0x29,0x2a,0x20,0x2f,0xdb,0xb7,0xbb,0xe7 +,0xbc,0xaf,0xbd,0xc5,0x48,0x54,0x52,0xec,0xad,0xcd,0x49,0x6b,0xcc,0xd0,0x62,0xaf,0xa1,0xc9,0x4d,0x31,0x37,0x5c,0xbc,0xa3,0x5b,0x16,0x16,0x27,0x42,0xea,0xbf,0xac +,0xe8,0xd5,0xce,0xf6,0xd3,0xbf,0xb7,0xc9,0x5a,0xce,0xaf,0xb1,0xd2,0xd1,0xa9,0xb4,0xbf,0x44,0x26,0x24,0x30,0x61,0xbb,0x52,0x32,0x43,0x3b,0x32,0x7b,0xb0,0xce,0x63 +,0x65,0xc7,0xb6,0xa8,0xad,0xba,0x3d,0x29,0x3d,0xc7,0xae,0xc1,0xc9,0x2f,0x2b,0x40,0xe4,0xd7,0x3c,0x34,0x3d,0x4d,0x49,0x65,0xc4,0xaf,0xc2,0xa8,0xaf,0x5a,0x36,0x26 +,0x30,0x75,0xaf,0xb0,0xc6,0x3c,0x34,0x47,0xac,0xb7,0xd1,0x37,0x45,0xdb,0x4f,0xc5,0xdf,0xb9,0xc8,0x6a,0x4b,0x5f,0x53,0x7a,0x3f,0x3a,0x36,0xd5,0xaa,0xb5,0x6a,0x26 +,0x29,0x3b,0xde,0xab,0xa8,0xf4,0xd7,0xca,0xad,0xb5,0xb1,0xba,0x24,0x21,0x29,0xcc,0xb6,0x4d,0x2b,0x39,0x36,0xc8,0xb1,0xad,0xe7,0x26,0xec,0x4a,0xb7,0xb3,0xba,0xb3 +,0xc4,0x53,0x4e,0x4f,0x46,0x3f,0x39,0x5d,0x43,0xaa,0xc0,0x3c,0x32,0x2a,0x3f,0xca,0xaa,0xb2,0x42,0x2c,0x58,0xac,0x9e,0xac,0xb1,0x5e,0x22,0x26,0x3b,0xaf,0xaf,0xc5 +,0xd8,0x3d,0x40,0xed,0x5f,0x3a,0x29,0x3a,0xc6,0xed,0xce,0xda,0xe7,0xba,0xb3,0xb2,0xd9,0x58,0x3a,0x30,0x3a,0x31,0xde,0xa8,0xc9,0x34,0x2b,0x42,0xb3,0xb5,0xba,0xd5 +,0x69,0xdd,0xbc,0xb1,0xaf,0xef,0x49,0x2c,0x24,0x2e,0x4c,0xc2,0x44,0x38,0x37,0xb6,0xaa,0xb5,0x74,0x39,0x3b,0xdf,0xb6,0xae,0xb9,0x49,0xba,0xd7,0xba,0xb1,0xba,0x4e +,0x26,0x2b,0x2e,0x4c,0xb3,0xb6,0x58,0x3f,0x38,0xd6,0xfa,0x60,0x59,0x49,0xdd,0x3f,0x72,0xbc,0xbc,0xbd,0xbe,0xc8,0x45,0x3d,0x4f,0x2e,0x38,0x56,0xbe,0xac,0xd6,0x3a +,0x37,0x49,0xfb,0xbb,0xb8,0x69,0x48,0xc8,0xc2,0xaf,0xae,0xaf,0xc8,0x25,0x22,0x2d,0xe4,0xbb,0xde,0xe0,0xed,0x2f,0x39,0xc2,0xbb,0x5d,0x47,0xc6,0xde,0xc5,0xae,0xb1 +,0xaf,0xbe,0xe1,0x50,0x38,0x2d,0x29,0x2d,0x3e,0xc1,0xa9,0xac,0x36,0x38,0xe4,0xb4,0xc2,0x44,0x38,0x2d,0x3b,0xcd,0xaa,0xad,0xc0,0x3b,0x47,0x2e,0x38,0xdd,0xe4,0x57 +,0x2f,0x4e,0xba,0xaa,0xb2,0xcd,0x3b,0x6e,0x47,0xfe,0xdf,0xcb,0xb0,0xb6,0xb8,0x48,0xca,0xd9,0x3b,0x2e,0x2c,0x30,0x60,0xc2,0xa9,0xba,0x35,0x3d,0x5d,0xaf,0xbb,0x50 +,0x36,0x35,0x4d,0xc4,0xb5,0xb0,0xd8,0x7e,0x4e,0x4e,0xdc,0x2c,0x34,0x5d,0xbb,0xac,0xc5,0xc8,0x77,0x28,0x2e,0x59,0xb7,0xb1,0x47,0x40,0x3f,0xd3,0xb5,0xb6,0xb6,0x36 +,0x29,0x2b,0x22,0x57,0xaf,0x9f,0xa5,0x6d,0x56,0x54,0xc4,0xba,0x75,0x2e,0x2f,0x42,0xb8,0xc4,0xc4,0xcc,0xaf,0xaa,0x38,0x36,0x33,0x2c,0x30,0x59,0xb0,0xb4,0x40,0x3c +,0x3c,0x6d,0xbf,0xae,0xba,0x3c,0x4d,0xce,0xce,0xbc,0xb1,0xb3,0xd9,0x29,0x2c,0x1f,0x26,0x5f,0xb1,0xa7,0xc4,0x76,0xc8,0xb8,0xc1,0xbe,0x41,0x2c,0x2e,0xbf,0xc1,0x58 +,0x47,0x47,0xad,0xab,0xb1,0x38,0x1f,0x1f,0x68,0xae,0xa8,0xb0,0xc2,0xdd,0x35,0x5d,0xc3,0xbe,0x4d,0x3d,0x3c,0xd7,0x6f,0xbf,0xac,0xc2,0x44,0x3e,0x46,0x2b,0x30,0x4f +,0xb8,0xab,0xbe,0x48,0xf4,0xce,0xdf,0x64,0x29,0x2e,0x43,0xbb,0xcc,0x39,0xc4,0xa7,0x9e,0xbc,0x2e,0x24,0x21,0x2f,0xb9,0xad,0xb9,0xd6,0xce,0xf8,0x38,0xe2,0xcc,0x50 +,0x39,0x3c,0xbe,0xaf,0xbf,0xd0,0x69,0xcb,0xd0,0x3f,0x30,0x2f,0x4a,0xd5,0xba,0xb1,0xbe,0xb6,0xab,0xca,0x39,0x23,0x23,0x3a,0xbc,0xaf,0x47,0x34,0xbb,0xa0,0xa9,0xd4 +,0x3e,0x3e,0x2c,0x2f,0x6c,0xca,0x67,0x36,0xbb,0xb3,0xe6,0x44,0x32,0x32,0x3e,0xc4,0x9f,0xae,0x40,0x44,0xeb,0xb5,0xc0,0x4a,0x25,0x1d,0x26,0x58,0xa9,0xa1,0xac,0xaa +,0xed,0x48,0x41,0x37,0x61,0x6c,0xbb,0xce,0x34,0x2a,0x70,0xa7,0x9e,0xc5,0x38,0x2b,0x2b,0x36,0x51,0xb5,0xc6,0xb8,0xbe,0xd6,0xc5,0x44,0x2a,0x44,0x53,0xb8,0xc1,0x45 +,0x35,0x42,0xaa,0xa5,0xaf,0x47,0x27,0x26,0x56,0xc9,0xad,0x7c,0xdc,0xd4,0x47,0x4d,0x2a,0x35,0x38,0x5f,0xca,0xcc,0x5f,0xc6,0xb0,0xa5,0xaa,0xcc,0x2e,0x23,0x43,0xd2 +,0xb8,0x54,0x6d,0xc3,0xc5,0xe2,0xc7,0xd7,0x2f,0x3e,0xba,0xa7,0x59,0x2c,0x35,0xb3,0xad,0xba,0xca,0x25,0x21,0x2a,0xcd,0xb3,0xd2,0xda,0xbc,0xb9,0xaa,0xb4,0x44,0x23 +,0x20,0xda,0xb1,0xc7,0x38,0xea,0xb0,0xbe,0xb2,0xae,0x51,0x39,0x31,0x40,0x33,0x26,0x40,0xb9,0xbb,0xcb,0xc8,0x37,0x28,0x48,0xa0,0xa6,0xbd,0x5e,0x5b,0xcb,0xc5,0xaf +,0xbb,0x30,0x1c,0x28,0x45,0xbc,0xb1,0xb7,0xba,0x6a,0xa4,0x9f,0x64,0x20,0x19,0xcb,0x99,0x32,0x27,0x1f,0x34,0x8c,0x9e,0xb3,0x1c,0x0f,0xb2,0xa2,0xbb,0xaf,0x1c,0x29 +,0x9e,0xaf,0xae,0x2c,0x0e,0x35,0x92,0xa7,0xb3,0x1c,0x0c,0xba,0x8d,0x99,0xaf,0x0f,0x07,0xb6,0x91,0xa2,0xae,0x20,0x16,0x9d,0x98,0xad,0xd8,0x0f,0x12,0x96,0x9b,0xae +,0xfb,0x0e,0x1e,0x8c,0x8c,0x9d,0x24,0x04,0x13,0x98,0x9a,0xac,0x3d,0x09,0x24,0x8f,0x97,0xaa,0xf9,0x12,0x36,0x97,0x9d,0x46,0x37,0x0c,0x20,0x93,0x95,0xb0,0x4c,0x0d +,0x16,0x8e,0x93,0xa2,0x28,0x09,0x0a,0x90,0x8e,0x8f,0x9d,0x1b,0x07,0x98,0x91,0x8f,0xa3,0x19,0x06,0xde,0xa8,0x18,0x1c,0x00,0x2c,0x00,0x8c,0x8a,0xa1,0xb8,0x10,0x3f +,0xa7,0x84,0x82,0x82,0xdc,0x07,0x25,0x9d,0x90,0x80,0x4a,0x02,0x15,0x3a,0xa4,0x80,0x83,0xbf,0x00,0x03,0x00,0xba,0x8c,0x22,0x07,0x00,0x00,0x0a,0x86,0x87,0x3b,0x00 +,0x02,0x00,0x8c,0x80,0x81,0x25,0x00,0x04,0x1e,0x80,0x81,0x88,0x08,0x06,0x16,0x80,0x82,0x80,0x8e,0x1b,0x12,0x8f,0x80,0x83,0x83,0x0c,0x01,0x05,0x83,0x84,0x86,0x4e +,0x00,0x00,0x12,0xd5,0x89,0x2e,0x00,0x05,0x02,0x91,0x9d,0x6c,0x06,0x02,0x00,0x0c,0xa5,0x87,0xbf,0x09,0x02,0x03,0xab,0x89,0x80,0x9a,0xb6,0x0d,0xa0,0x84,0x80,0x84 +,0x85,0x2e,0x1b,0x8b,0x83,0x80,0x81,0x98,0x04,0x2e,0x89,0x81,0x80,0x9c,0x0c,0x00,0x1b,0x8e,0x8c,0xa5,0x04,0x00,0x01,0x2b,0xa1,0x8b,0x13,0x00,0x00,0x08,0x9b,0xa1 +,0x9f,0x05,0x01,0x03,0xa9,0x86,0x88,0x87,0xbb,0x13,0x26,0x81,0x84,0x80,0x8b,0x12,0x00,0x22,0x80,0x82,0x83,0x96,0x12,0x02,0x9b,0x80,0x83,0x80,0x3a,0x03,0x06,0x96 +,0x83,0x85,0x39,0x06,0x02,0x00,0x97,0x1b,0x96,0x94,0x00,0x02,0x05,0x4b,0x8c,0x84,0x95,0x07,0x00,0x00,0x17,0x9f,0x8e,0x80,0x1e,0x02,0x0d,0xc3,0x85,0x81,0x89,0x95 +,0x31,0x2b,0xae,0x98,0xa7,0x80,0x8b,0x4c,0x04,0x2c,0x84,0x8b,0x87,0x9d,0xb6,0x20,0xb3,0xad,0x15,0x31,0x80,0xaa,0x18,0x03,0x0e,0x9a,0xae,0x29,0x9b,0x7e,0x02,0x02 +,0x17,0x00,0xe6,0x80,0x0f,0x0d,0x00,0x0b,0x41,0x89,0xa2,0x03,0x15,0x0b,0x00,0x3a,0x05,0x18,0x80,0x9a,0x1d,0x00,0x06,0x9e,0x80,0x8f,0x8f,0x1d,0x09,0x9e,0x80,0x8b +,0xa4,0x80,0x94,0x8f,0x08,0xbc,0x99,0x9c,0x89,0x89,0x3d,0x07,0x08,0x08,0x24,0x2b,0x80,0x41,0x18,0x03,0x1b,0x80,0x97,0x8e,0xa5,0x37,0xd3,0xa7,0x2f,0x1f,0x00,0x97 +,0x80,0x88,0x9a,0x05,0x4d,0x2c,0xa5,0x89,0x83,0x83,0xac,0x07,0x06,0x2d,0x2c,0x83,0x83,0x8c,0x06,0x00,0x0f,0x95,0x83,0x19,0xb3,0x1e,0x0c,0x00,0x15,0x15,0xaa,0x83 +,0x29,0x0f,0x00,0x16,0x04,0x17,0x59,0x0e,0x17,0x0a,0x05,0x01,0x00,0x17,0x82,0x83,0xb8,0x06,0x00,0x0e,0xa7,0x92,0x80,0x84,0x8e,0x3a,0x04,0xe7,0x8e,0x80,0x82,0x80 +,0x89,0x0e,0xce,0x8b,0x80,0x80,0x81,0x80,0x8a,0x41,0x08,0x2e,0x8b,0x80,0x85,0xec,0x0b,0x00,0x06,0x07,0x21,0xe4,0x1d,0x10,0x03,0x00,0x01,0x05,0x5c,0x8c,0x16,0x01 +,0x00,0x05,0x0d,0x0e,0x0e,0x93,0x9b,0x13,0x01,0x01,0x00,0x1f,0x80,0x81,0x88,0x0b,0x00,0x08,0xc2,0x80,0x83,0x84,0x8f,0x0a,0xc0,0x9b,0x9a,0x80,0x82,0x81,0xf4,0xc7 +,0xdb,0xb2,0x89,0x88,0x80,0x84,0xa7,0x01,0x0d,0x19,0x99,0x82,0x9d,0xa9,0x04,0x01,0x15,0x28,0x0f,0x38,0x1e,0x2b,0x0c,0x04,0x01,0x05,0x85,0x82,0x8a,0x0e,0x06,0x07 +,0x94,0x86,0x88,0x83,0x9e,0x2b,0x0b,0x3d,0x9d,0x88,0x80,0x82,0x1a,0x04,0x04,0xb0,0x8a,0x9e,0x4f,0xb8,0x43,0x01,0x00,0x01,0x19,0x87,0x92,0xd2,0x0e,0x00,0x07,0x25 +,0xa8,0x22,0x96,0xa2,0x1b,0x02,0x01,0x0e,0x96,0x80,0x80,0x99,0x0b,0x12,0xa2,0x81,0x81,0x80,0x87,0x87,0xaf,0x36,0x30,0x8d,0x80,0x89,0x8b,0x17,0x08,0x0b,0x23,0x99 +,0x8e,0xa2,0x19,0x0e,0x00,0x03,0x0e,0xaf,0x89,0x80,0xbe,0x07,0x02,0x0b,0x1b,0x9c,0x9b,0x1f,0x3d,0x03,0x00,0x04,0x11,0x8b,0x88,0x18,0x06,0x01,0x03,0x1b,0x92,0x9c +,0x27,0x1f,0x0f,0x13,0x1d,0x2e,0xc3,0x83,0x8b,0x8d,0x57,0x0b,0x91,0x82,0x82,0x82,0x85,0x9a,0x25,0x31,0xa4,0x8e,0x80,0x83,0x8e,0xb7,0x07,0x20,0xa6,0x8e,0xa5,0x43 +,0xdf,0x23,0x0e,0x08,0x17,0x3c,0x86,0x85,0x2b,0x08,0x02,0x17,0x97,0x84,0x95,0x1a,0x2b,0x22,0x04,0x0a,0x1d,0xb6,0x88,0x36,0x0e,0x05,0x00,0x0c,0xaa,0x9b,0x1f,0x06 +,0x07,0x03,0x01,0x0e,0x11,0x89,0x89,0x17,0x07,0x05,0x0a,0x94,0x8e,0x8f,0x95,0xa3,0xa1,0xaf,0x9c,0x89,0x80,0x80,0x84,0x8d,0xab,0x9f,0x80,0x83,0x80,0x85,0x87,0x8f +,0xa2,0xc1,0x15,0x6c,0x8c,0x88,0x0d,0x04,0x01,0x00,0x30,0x1f,0x0c,0x0a,0x07,0x04,0x01,0x02,0x0b,0x1b,0x8f,0x7d,0x18,0x0b,0x01,0x63,0x23,0xfd,0x28,0x3e,0xc7,0x11 +,0x21,0x1c,0xb1,0x8b,0x84,0x8f,0x2d,0x06,0xb1,0x90,0x85,0x87,0x9c,0x8c,0x9e,0x2a,0x17,0x92,0x8e,0x87,0x8f,0x95,0x19,0x1a,0x93,0x8d,0x83,0xb0,0xcd,0xad,0x1c,0x06 +,0x28,0x1c,0x9d,0x83,0x1f,0x1b,0x01,0x06,0x3c,0x9b,0xad,0x16,0xbf,0x44,0x07,0x0b,0xb1,0xa1,0x80,0xa1,0xf2,0x13,0x10,0x94,0x91,0x87,0xa3,0x95,0xaa,0x2a,0x10,0x26 +,0x2c,0x90,0x88,0x30,0x0e,0x09,0x22,0x22,0xbe,0x0f,0x1c,0x2e,0x0e,0x02,0x05,0x0d,0x3c,0x84,0x26,0x19,0x03,0x07,0x46,0x7a,0x2a,0x1c,0x8d,0x9b,0x9e,0xa9,0x70,0x9a +,0x80,0x82,0x85,0x98,0xab,0x80,0x86,0x82,0x8e,0x83,0x84,0x90,0xab,0x1e,0x1a,0x9f,0x82,0x91,0x35,0x00,0x13,0x19,0xc3,0x19,0x1a,0xde,0x1c,0x07,0x06,0x0f,0x15,0x83 +,0xbf,0x2b,0x04,0x06,0x2d,0x0c,0x0d,0x0e,0x14,0x29,0x19,0x00,0x09,0x07,0x8b,0x9a,0x1a,0x15,0x00,0x3e,0xb8,0xa5,0xc3,0x91,0x89,0x8a,0xa4,0x1f,0xa9,0x87,0x82,0x81 +,0x94,0x17,0x8d,0x98,0x84,0x92,0x9c,0x8a,0x9e,0xb2,0x15,0xad,0xe1,0x83,0x8e,0xa6,0x08,0x0f,0x34,0x11,0x23,0x0e,0x9b,0x59,0x22,0x08,0x10,0x10,0x8b,0x88,0xad,0x2c +,0x02,0x20,0xbb,0x8a,0x6f,0x9c,0xa3,0xbb,0x0e,0x08,0x13,0x31,0x89,0x29,0x14,0x00,0x0e,0x17,0x24,0x1a,0x17,0x11,0x0c,0x09,0x05,0x0b,0x12,0x83,0xb3,0x23,0x06,0x10 +,0x48,0xb1,0x35,0x36,0x8e,0x96,0x81,0xa0,0xa7,0x8f,0x81,0x81,0x81,0x97,0x9a,0x87,0x85,0x80,0x8b,0x81,0x89,0x83,0x2d,0x14,0x0f,0x1b,0x8d,0x1f,0x0f,0x00,0x18,0x0c +,0x1f,0x06,0x0a,0x1d,0x10,0x0e,0x04,0x07,0x0b,0x88,0x1f,0xdc,0x06,0x13,0x0e,0x19,0x0d,0x0c,0xaa,0x30,0xa3,0x06,0x23,0x21,0x81,0x8c,0xa6,0x0c,0x1e,0x95,0xac,0x96 +,0xd9,0x90,0x92,0x89,0x24,0x2d,0x59,0x8c,0x85,0x8f,0x24,0x2e,0x8f,0xa1,0x84,0xde,0xa9,0x9c,0xa4,0x1c,0x1e,0x12,0x96,0x82,0x35,0xc9,0x1d,0x9e,0xd8,0xbc,0x0e,0xb2 +,0xa5,0x35,0x1d,0x0c,0x1b,0x94,0x80,0xc8,0xa0,0x00,0x3d,0xba,0x3d,0x21,0x21,0xa0,0xb7,0x3b,0x10,0x29,0xbd,0x85,0x51,0x1c,0x01,0xe9,0xdd,0xac,0xe5,0x0f,0xbf,0x1c +,0x0c,0x05,0x08,0x06,0x8c,0x21,0x11,0x04,0x17,0xbb,0xad,0x28,0x0f,0x97,0x23,0x53,0x18,0x20,0x91,0x80,0x84,0x80,0xab,0xaf,0x80,0x86,0x81,0x8b,0x84,0x87,0x82,0xa9 +,0xb5,0x96,0x81,0x88,0x5c,0x05,0x05,0x19,0x12,0xe8,0x06,0x0f,0x18,0x15,0x01,0x07,0x00,0x5a,0x92,0x10,0x08,0x06,0xc2,0xa8,0x9d,0x09,0x24,0x27,0x1c,0x0b,0x09,0x02 +,0x98,0x83,0x99,0xd1,0x00,0x33,0xaf,0xa1,0x19,0x2e,0x34,0xac,0x1e,0x10,0x5e,0x86,0x80,0x85,0xa6,0x06,0x8d,0x98,0x88,0x91,0x94,0x8d,0x85,0xb7,0x1f,0x13,0x40,0x80 +,0x96,0x3f,0x04,0xcc,0xe0,0x89,0x34,0xe5,0x96,0x9d,0x28,0x0c,0x03,0x14,0x80,0xa6,0x90,0x0a,0x34,0x6b,0x9e,0x22,0xba,0xab,0x1d,0x23,0x04,0x12,0xac,0x80,0x9d,0xac +,0x00,0x1b,0x1e,0x28,0x16,0x08,0x11,0x15,0x15,0x01,0x0f,0x0a,0x89,0xb2,0x1d,0x00,0x12,0x14,0xb0,0xa4,0x19,0xa3,0xb5,0x35,0x0a,0x10,0x0d,0x80,0x8c,0x86,0x9e,0x8f +,0x80,0x83,0x83,0x8b,0x80,0x85,0x84,0xb2,0xc4,0xa7,0x80,0x8a,0x83,0x18,0x12,0xaf,0x1a,0x14,0x07,0x17,0x0c,0x30,0x05,0x08,0x03,0xa4,0x66,0x1e,0x05,0x08,0x25,0x0f +,0x1a,0x06,0x45,0xca,0xc7,0x00,0x08,0x03,0x90,0x9d,0x26,0x09,0x12,0x97,0x9f,0x8b,0x17,0x9b,0x9d,0x8e,0x31,0x25,0x19,0x81,0x87,0x8b,0xe7,0x22,0x89,0x98,0x8e,0x14 +,0x99,0x71,0x97,0xd9,0x3b,0x26,0x82,0x8e,0xa4,0x23,0x0a,0x8e,0xb9,0xad,0x0c,0xb8,0xba,0x91,0x1b,0x0d,0x0c,0x8e,0x8d,0xc0,0x10,0x09,0x8a,0x9b,0x8b,0x22,0x7e,0xcf +,0x9d,0x11,0x18,0x0d,0x8e,0x8c,0x2c,0x0e,0x0c,0x95,0xb0,0x9b,0x04,0x1d,0x1f,0x3e,0x0e,0x1a,0x0b,0x8b,0x8b,0x36,0x12,0x0a,0x96,0xa6,0x9b,0x07,0xb2,0x57,0x8d,0xbb +,0x1a,0x0a,0x8d,0x8d,0xaf,0x23,0x04,0x9f,0xc4,0x91,0x1e,0x9c,0x31,0xa2,0x15,0x0c,0x09,0x93,0x8a,0xbe,0x10,0x05,0x8f,0x9f,0x88,0x26,0xb4,0xc3,0x9f,0x1e,0x48,0x2f +,0x87,0x82,0x95,0x1d,0x07,0x94,0x9c,0x83,0x1d,0xb3,0xca,0xa9,0x38,0xbf,0x11,0x8e,0x85,0xc3,0x24,0x00,0xd9,0xad,0x8b,0x11,0xac,0x5b,0xaa,0x1c,0x0b,0x03,0xa1,0x87 +,0x6f,0x2c,0x00,0x53,0x3d,0x91,0x26,0x57,0x1d,0xc2,0x10,0x06,0x0b,0xae,0x83,0xa8,0x20,0x00,0x4a,0x1e,0x8f,0x2f,0x23,0x5b,0xa7,0x28,0x1c,0x1d,0xa4,0x80,0x91,0xb6 +,0x04,0xa7,0xa6,0x80,0x9e,0x9c,0x8c,0x93,0x98,0x30,0x0f,0xe8,0x80,0x9e,0x97,0x01,0x1f,0xd7,0x8f,0x38,0xae,0x99,0xbd,0xb2,0x02,0x05,0x1d,0x80,0x94,0x92,0x00,0x20 +,0x3e,0xb2,0xa7,0x20,0xb4,0xa1,0xaa,0x07,0x15,0x18,0x80,0x89,0x9c,0x01,0x0f,0x18,0xaf,0x9d,0x06,0x32,0x31,0x66,0x09,0x07,0x00,0x8c,0x97,0x1d,0x06,0x04,0x20,0x97 +,0x9c,0x15,0x94,0x9e,0x89,0x33,0x09,0x0e,0x82,0x85,0x80,0x3d,0x0f,0x86,0x89,0x84,0x98,0x89,0x8b,0x80,0xa5,0x3d,0x29,0x8a,0x80,0x80,0x2b,0x04,0x27,0x11,0x9b,0x07 +,0x08,0x13,0xbb,0x08,0x02,0x00,0x11,0x8b,0x1f,0x08,0x00,0x17,0x28,0x9f,0x07,0x2d,0xaf,0x9b,0xb7,0x0b,0x00,0x2b,0x81,0x9a,0xa5,0x00,0xbc,0x92,0x87,0x49,0x35,0x9f +,0x88,0x88,0x2a,0x16,0x3d,0x80,0x84,0x82,0x0e,0x9b,0x92,0x89,0x91,0x1f,0xa0,0x87,0x87,0x23,0x09,0x17,0x80,0x88,0x8f,0x0d,0x9b,0x88,0x88,0x90,0xd4,0x86,0x92,0x8c +,0x3c,0x09,0x00,0x97,0x91,0x28,0x04,0x01,0x1a,0xaf,0x1f,0x00,0x09,0x0d,0xa0,0x12,0x07,0x00,0xba,0x94,0x98,0x12,0x05,0xc3,0xe3,0xa5,0x09,0x16,0x35,0x99,0x0e,0x08 +,0x04,0xa0,0x88,0xb8,0x0c,0x03,0x56,0xaa,0x8d,0x10,0x1b,0xac,0x88,0x9b,0x3c,0x0d,0xa0,0x80,0x89,0x9d,0x02,0x4d,0x8b,0x80,0x92,0x2d,0xa4,0x82,0x80,0x8d,0x1b,0x96 +,0x80,0x83,0x89,0x15,0x8f,0x94,0x9e,0x2e,0x1d,0x21,0x1d,0x1e,0x0c,0x06,0x02,0x9e,0xa8,0x24,0x01,0x08,0x3e,0x95,0x34,0x01,0x0a,0xda,0x8f,0x20,0x08,0x00,0xad,0x94 +,0x9e,0x0e,0x01,0x0f,0x3a,0xa3,0x0f,0x0b,0x11,0xb7,0x26,0x13,0x02,0xd0,0x8d,0x91,0x28,0x04,0xb8,0x92,0x89,0x34,0x19,0xaa,0x8a,0x98,0x3b,0x1d,0x8f,0x82,0x87,0x88 +,0xa4,0x8c,0x88,0x83,0x81,0x8b,0x9f,0x89,0x80,0x88,0x18,0x0f,0x8e,0x8b,0xa3,0x04,0x05,0x16,0x4d,0x6b,0x09,0x09,0x18,0x47,0xbd,0x11,0x05,0x2a,0xab,0x98,0x2c,0x09 +,0x1b,0x2d,0xaa,0x18,0x0f,0x18,0x29,0x3f,0x12,0x03,0x13,0x59,0xb3,0x3a,0x05,0x14,0x1c,0xb1,0xdd,0x13,0x1a,0xfc,0x99,0xa1,0x1b,0x12,0xb5,0x8f,0x86,0x45,0x11,0x32 +,0x8c,0x82,0x9d,0xa5,0x89,0x80,0x82,0x90,0x91,0x81,0x85,0x85,0x89,0x8b,0x95,0xcb,0xa0,0xa6,0x37,0x0e,0x0d,0x1c,0x1c,0x07,0x06,0x12,0x22,0x34,0x0f,0x15,0x1d,0x6e +,0x3d,0x15,0x18,0x1c,0x6d,0xac,0x1c,0x0b,0x17,0x1c,0xd4,0x34,0x1b,0x15,0x16,0x24,0x18,0x15,0x17,0x45,0xbe,0x22,0x0a,0x12,0x36,0xaf,0xcb,0x32,0xc8,0x44,0xfb,0xc7 +,0xaf,0xa5,0xc4,0xb7,0x9a,0x9a,0xa9,0xb6,0x8d,0x81,0x85,0x94,0x8c,0x80,0x82,0x8c,0x95,0x87,0x81,0x8b,0xbe,0x38,0xd9,0x1f,0x17,0x1e,0x1d,0x14,0x0e,0x0d,0x0d,0x15 +,0x24,0xb3,0xb7,0x28,0x15,0x19,0x41,0xba,0x6d,0x2c,0x2c,0x2c,0x29,0x1d,0x1f,0x1f,0x38,0x2c,0x1b,0x1b,0x1b,0x1b,0x20,0x22,0x18,0x1c,0x22,0x3a,0x26,0x21,0x17,0x23 +,0xa8,0x9f,0x43,0x15,0x26,0xb0,0xab,0x2c,0xe9,0x9a,0x8f,0x9f,0xa6,0x8b,0x83,0x87,0x8f,0x87,0x81,0x87,0x92,0x8b,0x84,0x88,0x99,0xbe,0xb9,0x2e,0x17,0x11,0x22,0x26 +,0x0d,0x07,0x0a,0x16,0x1e,0x19,0x1b,0x1b,0x1d,0x2b,0x18,0x1f,0x2e,0xc9,0x53,0x31,0x1d,0x12,0x16,0x27,0x31,0x23,0x2f,0x22,0x3f,0x20,0x2a,0x2b,0x49,0xc5,0x2c,0x1b +,0x16,0x2e,0x45,0xcb,0xb8,0x9e,0xbb,0x5c,0x35,0xb3,0x9e,0xab,0xb2,0x9c,0x8f,0xac,0xbb,0x95,0x84,0x88,0x91,0x8e,0x83,0x84,0x8d,0x8d,0x85,0x81,0x8d,0xbd,0x28,0xc2 +,0x2b,0x19,0x0e,0x11,0x0b,0x07,0x0c,0x10,0x15,0x16,0x19,0x1a,0x1d,0x15,0x1f,0x25,0x2d,0x2a,0x3b,0x3c,0x2e,0x20,0x17,0x1f,0x3c,0x5e,0x2d,0x29,0x1c,0x21,0x26,0x36 +,0x2e,0x23,0x1f,0x23,0x26,0x35,0x2c,0x20,0x4a,0xa1,0x9d,0x2b,0x1a,0x3b,0x9d,0xa8,0x37,0x4a,0xa7,0xa0,0xa4,0x96,0x88,0x84,0x94,0x97,0x86,0x80,0x85,0x8c,0x8d,0x87 +,0x89,0x91,0x9f,0x9c,0xbd,0x1b,0x1f,0x26,0x28,0x0d,0x07,0x08,0x10,0x18,0x14,0x11,0x14,0x18,0x2e,0xb1,0xee,0xcf,0x37,0xcc,0x5a,0x29,0x1c,0x1d,0x1d,0x1b,0x1e,0x1e +,0x1f,0x1a,0x2c,0x28,0x39,0x2b,0x28,0x1a,0x1b,0x5f,0xb7,0xf9,0x27,0x30,0xe1,0xc9,0x32,0xdb,0xdc,0xbf,0x2d,0x38,0x9b,0x94,0xad,0x55,0x94,0x87,0x89,0x9b,0x90,0x85 +,0x84,0x8d,0x8b,0x83,0x83,0x8a,0xa1,0xa3,0xa6,0x52,0x1a,0x19,0x13,0x0f,0x0c,0x0c,0x0f,0x15,0x15,0x14,0x15,0x11,0x1e,0x29,0x2a,0x24,0x20,0x32,0xf2,0x39,0x26,0x1f +,0x22,0x38,0x30,0x26,0x1f,0x1d,0x1f,0x2a,0x27,0x2a,0x39,0x25,0x27,0x4c,0x4d,0x47,0x48,0xd2,0x9f,0x9d,0x3d,0x22,0x36,0xc8,0x7c,0x2c,0xda,0x98,0x9d,0x4b,0xab,0x8c +,0x86,0x93,0x9b,0x88,0x81,0x86,0x8e,0x8e,0x87,0x88,0x93,0x9b,0x9a,0xbf,0x25,0x32,0x30,0x2c,0x18,0x0d,0x0f,0x0f,0x13,0x18,0x19,0x17,0x18,0x18,0x1b,0x23,0x2a,0x23 +,0x2a,0x20,0x19,0x1e,0x14,0x17,0x15,0x19,0x2b,0x45,0x2e,0x2a,0x17,0x1b,0x2a,0x1e,0x2c,0x2b,0x4d,0x2f,0x26,0x1f,0xb3,0x8f,0x9e,0x33,0x23,0x66,0xa6,0xcc,0x26,0xad +,0x9c,0xa8,0xdc,0x9b,0x8c,0x91,0x9b,0x8c,0x82,0x84,0x8d,0x8f,0x84,0x82,0x84,0x8d,0x8b,0x94,0xf8,0x23,0x18,0x23,0x1f,0x0e,0x0a,0x0d,0x0e,0x17,0x10,0x0f,0x13,0x1e +,0x2b,0x29,0x27,0x1a,0x29,0x41,0x42,0x32,0x1c,0x18,0x1b,0x1c,0x2f,0x3b,0x2c,0x2a,0x29,0x26,0x2e,0x3e,0x3c,0x32,0x2d,0x2b,0x32,0x27,0x24,0xa8,0xa0,0x4f,0x2e,0x51 +,0xb0,0x2d,0x10,0x22,0x9e,0xa0,0x39,0x48,0x93,0x8d,0x9e,0x96,0x85,0x81,0x84,0x8e,0x8d,0x84,0x83,0x8b,0x8e,0x8b,0x99,0xbb,0x29,0x23,0x37,0x23,0x14,0x0d,0x0a,0x07 +,0x09,0x11,0x16,0x15,0x1a,0x1e,0x34,0x2a,0x1f,0x20,0x26,0xd9,0xda,0x2c,0x19,0x10,0x17,0x2b,0x2f,0x54,0x2d,0x1b,0x16,0x22,0xfa,0xee,0xb0,0xbe,0x3f,0x24,0x18,0x3e +,0x99,0xba,0x1b,0x13,0x2a,0x3c,0x1c,0x22,0xaf,0x99,0xb7,0x2e,0xb2,0x90,0x8e,0x9e,0x93,0x83,0x82,0x86,0x86,0x83,0x82,0x86,0x8c,0x89,0x8b,0xa7,0x1a,0x14,0x1e,0x36 +,0x27,0x1a,0x14,0x0d,0x0e,0x11,0x1c,0x1a,0x18,0x1b,0x26,0x24,0x18,0x1a,0x26,0x33,0x5a,0x23,0x10,0x13,0x15,0x14,0x1e,0x41,0xea,0x34,0x1b,0x1c,0x2b,0x35,0x1c,0x1b +,0x37,0xbf,0x22,0x25,0xa1,0x9b,0xc9,0x44,0xaa,0xa5,0x1e,0x07,0x1e,0x9a,0x9d,0x3b,0x40,0x9b,0x8a,0x8e,0xaa,0x8d,0x82,0x83,0x8e,0x8b,0x82,0x83,0x89,0x92,0x89,0x8e +,0x9e,0x2f,0x1c,0x0e,0x0f,0x18,0x2a,0x1f,0x0b,0x0c,0x19,0x3f,0x2c,0x2b,0x12,0x19,0x12,0x35,0xc4,0x1d,0x16,0x12,0x14,0x1c,0x1e,0x14,0x15,0x10,0x30,0xa9,0x3f,0xcd +,0x55,0x1d,0x06,0x22,0x8e,0x98,0xa6,0x1d,0x26,0x92,0x98,0x1b,0x1b,0x19,0x8f,0xc9,0x0c,0xa4,0x83,0x19,0x00,0x80,0x8f,0xab,0x8b,0x8f,0x80,0x8c,0x18,0x18,0x92,0x44 +,0x1f,0x4f,0x0f,0x01,0x03,0x00,0x20,0xaa,0x0a,0x23,0x05,0x13,0x19,0x02,0x06,0x05,0x12,0xdd,0xaa,0xca,0x2e,0x66,0x0e,0x3d,0x80,0xa7,0x48,0x84,0x81,0x80,0x89,0x92 +,0x86,0x82,0x81,0x80,0x81,0x80,0x8a,0xb9,0x9c,0x81,0x83,0x98,0x89,0x8d,0x88,0x91,0x11,0x0f,0x49,0xac,0x8f,0x16,0x1e,0xed,0x0e,0x08,0x01,0xdd,0x07,0x0b,0x0b,0x00 +,0x09,0x04,0x04,0x00,0x00,0x04,0x09,0x01,0x03,0x00,0x03,0x00,0x10,0x0a,0x08,0xa8,0x0f,0x0e,0x03,0x02,0x06,0x07,0x27,0x9d,0x4c,0xbb,0x12,0x0a,0x02,0x23,0x80,0xe6 +,0x8b,0x9f,0x8b,0x80,0x8c,0x85,0x83,0x80,0x80,0x82,0x82,0x81,0x83,0x84,0x8d,0x80,0x82,0x81,0x80,0x85,0x80,0x83,0x86,0x85,0x85,0x80,0x80,0x81,0x80,0x8c,0x8f,0xa0 +,0x86,0x81,0x8d,0x83,0xa1,0x8c,0x8e,0x25,0xb6,0x5a,0x9a,0x9b,0x0c,0x18,0x08,0x0d,0x07,0x06,0x5f,0x10,0x47,0x0a,0x00,0x08,0x03,0x08,0x01,0x01,0x0a,0x04,0x05,0x03 +,0x00,0x02,0x00,0x07,0x00,0x05,0x0b,0x07,0x0c,0x00,0x04,0x0b,0x07,0x1b,0x08,0x07,0x0c,0x00,0x06,0x00,0xd2,0xb7,0x2c,0x29,0x02,0x1c,0x13,0x0c,0x26,0x18,0x96,0xa2 +,0x31,0x3f,0x13,0x9b,0x19,0x8f,0x9e,0xaf,0x84,0xa1,0x86,0x8b,0x8e,0x8c,0x9e,0x8b,0x88,0x8c,0x80,0x8f,0x88,0xa0,0x8b,0x80,0x85,0x80,0x87,0x80,0x87,0x8e,0x8a,0x8f +,0x85,0x80,0x8e,0x84,0xaa,0x8b,0xaa,0xa6,0x82,0x9f,0x81,0x8e,0x88,0x88,0x8d,0x82,0x85,0x89,0x80,0x8d,0x80,0x93,0x9b,0x9e,0xb7,0x80,0xbb,0x98,0x30,0xc3,0x9e,0x08 +,0x0a,0x05,0x16,0x8e,0x16,0x35,0x14,0x0d,0x19,0x00,0xbd,0x19,0x8f,0xa3,0x25,0x9e,0x1a,0xab,0xaf,0x61,0x89,0x1d,0xb5,0x5a,0x0d,0x21,0x0e,0x80,0xc0,0xb8,0xc1,0x1e +,0x8f,0x0c,0x13,0x0d,0x0a,0x3e,0x03,0x0c,0x0e,0x00,0x06,0x00,0x0b,0x01,0x04,0x06,0x02,0x0f,0x01,0x03,0x07,0x00,0x14,0x04,0x06,0x0b,0x00,0x05,0x00,0x2b,0x09,0x08 +,0x0e,0x00,0x0d,0x01,0x01,0x03,0x05,0x1c,0x03,0x04,0x0f,0x04,0x10,0x00,0x3d,0x11,0x08,0x16,0x03,0xa6,0x26,0x1e,0x38,0x0c,0x96,0xd3,0x9d,0x87,0x9b,0x8e,0xe6,0x82 +,0x82,0x86,0x80,0x82,0x80,0x89,0x8f,0x83,0x85,0x80,0x81,0x81,0x81,0x86,0x85,0xa2,0x81,0x80,0x81,0x80,0x83,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x84,0x80 +,0x8a,0x80,0x85,0x8c,0x88,0xa6,0x83,0xa9,0x18,0x2a,0x08,0x4f,0x09,0x09,0x2f,0x08,0x0f,0x00,0x13,0x0d,0x00,0x07,0x00,0x1a,0x07,0x00,0x02,0x00,0x10,0x08,0x01,0x09 +,0x00,0x04,0x00,0x1c,0x1a,0x04,0x12,0x0b,0xba,0x0d,0x04,0x16,0x08,0x52,0x09,0x0b,0x3c,0x06,0x11,0x00,0x3e,0x1e,0x04,0x0c,0x03,0xa2,0x1d,0x0c,0x1c,0x0e,0x8d,0xd0 +,0x32,0x9e,0x12,0x5f,0x07,0x8c,0x93,0x3b,0x94,0xcb,0x82,0xb6,0x20,0xaa,0x29,0x8a,0xe7,0x54,0x8c,0x6c,0x97,0x0c,0x89,0x8b,0xbf,0xae,0x15,0x86,0xab,0x2d,0xa8,0x20 +,0x8e,0x29,0x2a,0x9f,0x1a,0x9f,0x0b,0x89,0x91,0x42,0x94,0xe3,0x80,0x8f,0xab,0x9f,0x17,0x93,0x5d,0xab,0x88,0x25,0x99,0x04,0x97,0x92,0x45,0x89,0x35,0x83,0x92,0xa0 +,0x86,0x8d,0x80,0x82,0x83,0x81,0x99,0x86,0x5a,0x89,0x84,0xb5,0x9b,0x0c,0xcf,0x16,0x07,0x23,0x06,0x16,0x07,0x02,0x18,0x01,0x16,0x00,0x30,0xc3,0x00,0x0d,0x00,0x44 +,0x2a,0x0d,0x7b,0x0a,0xbe,0x28,0x1b,0x8e,0x10,0xb0,0x08,0xa6,0x8a,0x2e,0x88,0x9d,0x81,0x87,0x94,0x82,0x91,0x83,0x8a,0x9b,0x80,0xc1,0x90,0x20,0x94,0x83,0x25,0x99 +,0x19,0x93,0x9d,0x19,0x92,0x32,0x93,0xa6,0x1a,0x88,0x22,0xac,0x0b,0xc8,0x88,0x19,0x99,0x1e,0x8f,0x9e,0x10,0xa3,0x17,0xc2,0x2d,0x0c,0x95,0x0d,0x1f,0x08,0xb3,0x84 +,0x14,0xb9,0x0c,0xb1,0x32,0x02,0x2f,0x11,0x37,0x1d,0x04,0xc2,0x07,0x0e,0x03,0x1f,0x8e,0x07,0x48,0x0d,0xbe,0xad,0x0d,0xa1,0x25,0x3d,0x22,0x06,0xa4,0x14,0x1d,0x0b +,0x23,0x86,0x10,0x9f,0x2b,0x93,0x8e,0x26,0x8b,0x8b,0x83,0x81,0x88,0x80,0x85,0x84,0x98,0x94,0x80,0xa9,0x90,0x55,0x9d,0x9e,0x05,0x28,0x11,0x1c,0x18,0x01,0x1b,0x05 +,0x05,0x03,0x09,0x93,0x0a,0x17,0x0b,0x12,0x69,0x00,0x21,0x17,0x2c,0x4b,0x06,0xa6,0x1e,0x12,0x0d,0x06,0x8a,0x18,0x4e,0x46,0xcc,0x85,0x1c,0x8e,0x8c,0x8d,0x84,0x45 +,0x88,0x9c,0x5d,0xdb,0x17,0x80,0xb6,0xb7,0xb0,0x27,0x8b,0x0b,0x41,0xac,0xdb,0x8f,0x11,0x98,0x9a,0x49,0xd7,0x0c,0x84,0x9d,0x2e,0xa3,0x2e,0x85,0x1a,0x25,0xa0,0x23 +,0x9d,0x0d,0x65,0xb8,0x0d,0x26,0x03,0x99,0x9d,0x17,0x9e,0x15,0x95,0x17,0x09,0x3a,0x0d,0xbc,0x0c,0x16,0xad,0x07,0x0f,0x00,0x22,0x96,0x09,0x4e,0x0f,0xa7,0x5d,0x05 +,0x9f,0x32,0x95,0x2f,0x0f,0x99,0x10,0x2e,0x12,0x30,0x80,0x23,0x9c,0xb8,0x92,0x85,0x25,0x8a,0x8d,0x86,0x83,0x8d,0x80,0x86,0x84,0x8a,0x94,0x80,0x97,0x9c,0xa6,0xb5 +,0x8b,0x07,0x19,0x1a,0x11,0x23,0x00,0x17,0x0d,0x03,0x08,0x00,0xbd,0x1b,0x09,0x14,0x06,0xb1,0x06,0x0b,0x1f,0x0f,0xb6,0x09,0x40,0xaa,0x0f,0x1f,0x00,0x9b,0x99,0x0d +,0xc6,0x1f,0x85,0xa7,0x1e,0x8a,0x97,0x80,0x9b,0x9e,0x87,0x4b,0xa2,0x0f,0xaf,0x84,0x23,0x9d,0x28,0x95,0x95,0x0f,0x94,0xbf,0x90,0xa7,0x23,0x8b,0x37,0xb4,0x27,0x69 +,0x80,0xc4,0xa3,0xce,0x9d,0x84,0x18,0xa7,0x40,0xb3,0xa7,0x09,0xaa,0x21,0x1d,0x17,0x05,0x8a,0x2f,0x1d,0x51,0x2b,0x8a,0x08,0x15,0x23,0x1b,0xba,0x06,0xdf,0x3a,0x0a +,0x13,0x00,0x99,0xa8,0x10,0x34,0x0a,0x9a,0x11,0x0c,0x3a,0x17,0x98,0x11,0x1f,0xbf,0x0c,0x2a,0x07,0x9f,0x86,0x21,0xa1,0x29,0x89,0x8f,0x3e,0x84,0x88,0x80,0x87,0x8a +,0x80,0x86,0x81,0x8b,0x8b,0x80,0xac,0x9a,0x48,0xa2,0x95,0x05,0x1e,0x0d,0x13,0x0e,0x00,0x1e,0x09,0x03,0x03,0x00,0xbb,0x0b,0x09,0x10,0x15,0x9a,0x06,0x1e,0x50,0x3d +,0xac,0x0d,0xac,0x48,0x0e,0x11,0x01,0x95,0xbf,0x13,0x4e,0x19,0x8c,0x26,0x2b,0x8c,0x95,0x85,0x4e,0x9f,0x8c,0x57,0xa6,0x16,0x8c,0x87,0x2b,0x99,0xd5,0x88,0xa2,0x17 +,0x8a,0x9e,0x8d,0x41,0x26,0x8a,0x30,0xa5,0x1f,0xa3,0x82,0x1a,0xac,0xde,0x8f,0x8e,0x0a,0x9f,0x30,0x4d,0x29,0x07,0x9a,0x13,0x10,0x0b,0x0e,0x83,0x1f,0x4b,0xb2,0xb0 +,0x8c,0x07,0xc5,0xac,0x38,0xb9,0x04,0xaa,0x26,0x0b,0x0f,0x01,0x94,0x1c,0x0a,0x17,0x0a,0xb0,0x03,0x10,0xb7,0x1b,0xbd,0x05,0x36,0xcd,0x0d,0x49,0x1a,0x84,0x8d,0x28 +,0x91,0x9c,0x80,0x94,0x9a,0x80,0x89,0x80,0x90,0x8b,0x80,0x8b,0x82,0x93,0x87,0x84,0x26,0x9f,0x2b,0xa1,0x2b,0x00,0x2e,0x08,0x0a,0x05,0x03,0x27,0x04,0x07,0x03,0x0a +,0x9f,0x07,0x1a,0x1b,0x2a,0xa8,0x04,0xad,0xb9,0xdf,0xaf,0x0e,0x92,0x2b,0x16,0x13,0x0a,0x8e,0x16,0x10,0x38,0x36,0x8f,0x0f,0xa5,0x88,0x99,0x8c,0x20,0x8e,0x97,0x30 +,0xa2,0x40,0x82,0x98,0x29,0x9a,0xc2,0x8a,0x4a,0x39,0x8c,0x47,0x9c,0x1c,0xa6,0x8e,0x23,0xbc,0x1f,0x8d,0x8e,0x19,0xa5,0xae,0x8b,0x9f,0x21,0x8a,0xb3,0xb6,0x1b,0x18 +,0x9f,0x0d,0x16,0x0e,0x46,0x94,0x13,0xb2,0xb3,0xab,0xaa,0x0f,0x98,0xde,0x1d,0x1a,0x0b,0xab,0x0f,0x0c,0x0b,0x17,0x9d,0x08,0x0c,0x1d,0x1b,0x31,0x06,0x35,0xe5,0x14 +,0x21,0x0a,0xab,0x2f,0x0f,0x24,0x29,0x87,0xa4,0xaf,0x8a,0x94,0x88,0x9c,0x89,0x80,0x86,0x83,0x8b,0x83,0x82,0x8b,0x8c,0x8e,0x82,0x8f,0x39,0x9c,0xbb,0xab,0x15,0x0c +,0xc9,0x10,0x0d,0x06,0x08,0x0c,0x02,0x05,0x09,0x1c,0x16,0x00,0x0e,0x1c,0x2a,0x22,0x13,0x9a,0x4c,0x26,0x28,0x24,0x9e,0x1a,0x10,0x26,0xad,0xa9,0x0d,0x15,0x33,0xa5 +,0x94,0xac,0x8e,0x95,0xdb,0xab,0x99,0x85,0x94,0x1d,0x1e,0x47,0x8b,0x93,0x97,0x8c,0x8f,0xa6,0x1e,0xa7,0x9a,0xa7,0xba,0x1a,0xaa,0xa9,0x37,0x2e,0x25,0x96,0xb3,0xcc +,0xa4,0xae,0x1e,0x0d,0x19,0x97,0x8a,0x97,0x2b,0x11,0x18,0x09,0x0f,0x2d,0x96,0xad,0x0d,0x10,0xac,0x8a,0x96,0xba,0x44,0x4b,0x2f,0x24,0xe2,0x36,0x34,0x20,0x2c,0xa6 +,0xaa,0x1d,0x0e,0x3c,0x39,0x40,0x1f,0x59,0xc3,0x0e,0x26,0xeb,0x90,0x98,0x16,0x1c,0x2e,0x90,0x95,0xb3,0x92,0xba,0x24,0x0e,0x10,0x94,0xb9,0x2d,0xcf,0x2d,0x30,0x0c +,0x5f,0xa5,0x99,0x91,0x0a,0x4f,0xa7,0x2e,0x2b,0x18,0x93,0x9c,0x28,0xab,0x1d,0x3a,0x1f,0x28,0x8d,0xa1,0x8c,0x30,0xcf,0x8c,0xe3,0x91,0xa5,0x98,0x94,0x0f,0xb2,0x97 +,0x90,0x9d,0x1d,0xbf,0x1c,0xa1,0xcf,0x18,0x98,0x42,0xf1,0x2b,0x1d,0x9d,0x17,0xa3,0x95,0x1f,0x2a,0x04,0x15,0x10,0xcc,0xa8,0x15,0x8a,0xbe,0x19,0x1b,0x0d,0x46,0x14 +,0x1d,0xc5,0x0f,0x13,0x03,0x14,0x18,0xa2,0x89,0x1a,0x9d,0xcd,0x3f,0xa6,0xa1,0x86,0x39,0x1d,0xa2,0x3e,0x9e,0x43,0x97,0x77,0x9c,0x84,0x38,0x88,0x84,0x8f,0x93,0x9c +,0x89,0x6b,0x5b,0x8d,0x22,0x9e,0x26,0xbc,0x12,0x22,0x8c,0x0c,0x9d,0xc6,0x1e,0x2f,0x1f,0x99,0x13,0x05,0x38,0x15,0x9c,0x38,0x3f,0x0e,0x16,0x8d,0x09,0x94,0x91,0x2a +,0x12,0x03,0x28,0x0c,0xe7,0x89,0x0e,0x12,0x03,0x16,0x17,0x45,0x89,0x02,0x38,0xb4,0x4a,0xa5,0x2b,0x8f,0x1b,0x2b,0x89,0x64,0x9c,0x21,0x4f,0x1e,0xa1,0x80,0x96,0x84 +,0x86,0x91,0x96,0x8e,0x80,0x9c,0xa9,0x81,0x53,0x69,0x2d,0xab,0x18,0x28,0x8c,0x00,0x18,0x42,0x12,0x0e,0x0b,0x12,0x00,0x03,0x2e,0x0b,0x14,0x0a,0x06,0x00,0x0c,0x96 +,0x06,0xd4,0x9d,0x1d,0x21,0x31,0x8f,0x13,0x18,0x8e,0xf3,0x9b,0xa5,0xaf,0x0c,0x25,0x80,0xf6,0x88,0x82,0x99,0xb9,0xa9,0x86,0xba,0x97,0x80,0xab,0xbd,0xae,0x9f,0xb8 +,0x95,0x80,0x26,0x9b,0x87,0xaa,0xa8,0x95,0x84,0x2a,0xb7,0x82,0x4b,0xe8,0xba,0x38,0x09,0x1f,0x86,0x05,0x29,0xb7,0x05,0x09,0x27,0x94,0x0a,0x0d,0x6b,0x06,0x1e,0xe5 +,0x1d,0x06,0x0f,0x91,0x06,0xa8,0x87,0x24,0x1d,0x1e,0xb5,0x07,0x1a,0x8b,0x18,0x28,0x23,0x18,0x0a,0x21,0x85,0x08,0xbb,0x8b,0x14,0x19,0x2f,0xa6,0x07,0x17,0x86,0x29 +,0x9f,0xa5,0x19,0x0d,0xba,0x80,0x3d,0x8c,0x82,0x1b,0x2f,0x8e,0x82,0x9c,0x96,0x80,0x1b,0xa1,0x8b,0xad,0x1e,0x37,0x8a,0x05,0xae,0x85,0x13,0x16,0x1b,0x21,0x06,0x13 +,0x9a,0x04,0x0e,0x1e,0x0c,0x14,0xb8,0x86,0x04,0x23,0x86,0x58,0x90,0x87,0x8a,0x1f,0xae,0x80,0x8e,0x85,0x82,0xa5,0x1a,0x9f,0x80,0xba,0x8e,0x80,0x17,0x1e,0xa0,0x9c +,0x18,0x1d,0x9d,0x03,0x0c,0x1f,0x02,0x01,0x05,0x1b,0x00,0x12,0x91,0x08,0x04,0x0f,0x0f,0x04,0x16,0x8d,0x0a,0x0b,0x20,0x02,0x06,0x48,0x86,0x07,0x0f,0x95,0x09,0x2b +,0x85,0x9b,0x0a,0x12,0x8f,0x26,0x96,0x82,0x24,0x17,0xa0,0x81,0xb4,0x8b,0x80,0x32,0xb8,0x83,0x8b,0x94,0x8b,0x80,0x3f,0xa5,0x81,0xa0,0xad,0xa1,0x89,0x0f,0xa3,0x80 +,0xbf,0x27,0xb4,0x29,0x0e,0x3a,0x86,0x1b,0x12,0xb7,0x06,0x0a,0x58,0x81,0x19,0x20,0x94,0x0a,0x29,0x89,0xa7,0x0a,0x0a,0xa8,0x20,0xa7,0x89,0x0c,0x03,0x0d,0x90,0x12 +,0x43,0x92,0x05,0x03,0x15,0xb3,0x50,0x1e,0x2d,0x04,0x0b,0xa0,0x39,0x23,0x11,0x69,0x05,0x24,0x80,0xa5,0xba,0xa2,0x38,0x18,0xca,0x81,0x94,0xaa,0x9e,0x08,0x16,0x9c +,0x81,0x23,0xac,0x88,0x08,0x41,0x80,0x9a,0x0e,0x19,0xa7,0x0f,0x9f,0x81,0x0f,0x00,0x09,0xbb,0x14,0x8e,0x81,0x08,0x07,0xaf,0xa9,0x9f,0x89,0x8b,0x08,0x0d,0x8b,0x97 +,0x8c,0x91,0x8b,0x0c,0xe2,0x80,0x88,0x85,0x8b,0xaf,0x57,0x8e,0x80,0x8c,0x92,0x8d,0x11,0x22,0x99,0x80,0x3f,0x47,0x99,0x04,0x1b,0x8a,0xad,0x0d,0x06,0x08,0x00,0x1a +,0x8d,0x09,0x02,0x01,0x0a,0x00,0xd1,0x8a,0x04,0x01,0x03,0x01,0x0d,0xaf,0xc7,0x03,0x04,0x13,0x0b,0x2f,0xaa,0xa8,0x00,0x2d,0x81,0x9f,0x8a,0x8d,0x32,0x25,0x99,0x80 +,0x84,0x89,0x91,0x19,0x4a,0x8a,0x80,0x98,0x8a,0x8c,0x08,0xc0,0x82,0x89,0x99,0x55,0xbc,0x13,0xac,0x85,0xaa,0x2f,0x3d,0x1f,0x0c,0x86,0x84,0x1a,0x4d,0xb2,0x18,0xa6 +,0x84,0x88,0x17,0x24,0x34,0x14,0x9b,0x86,0x46,0x00,0x28,0x32,0x17,0x91,0xb7,0x04,0x01,0x0b,0xb0,0x3d,0x9e,0x0f,0x00,0x00,0x23,0xb5,0x10,0x99,0x12,0x02,0x0f,0xb4 +,0x98,0xb4,0x2a,0x28,0x11,0x9b,0x92,0xa8,0x1d,0xa1,0x17,0x1b,0x80,0x9d,0xb8,0xc6,0x0d,0x0e,0x9b,0x86,0x93,0x2b,0xa5,0x08,0x0c,0x8f,0x80,0x25,0x2b,0x90,0x0e,0x9a +,0x80,0x93,0x1f,0x2f,0xbd,0xc0,0x8f,0x82,0x20,0x02,0x25,0x8e,0x43,0x89,0x8e,0x08,0x0a,0x17,0x37,0x91,0xa7,0x17,0x06,0x0e,0x45,0x9e,0x99,0x92,0xe3,0x0d,0x87,0x86 +,0x87,0x80,0x8d,0x26,0x9b,0x86,0x83,0x84,0x80,0xac,0x0c,0x40,0x80,0xa1,0x2c,0x82,0x0c,0x03,0xae,0x9c,0x0a,0x05,0x07,0x02,0x01,0x2f,0x0f,0x00,0x01,0x0b,0x00,0x18 +,0x89,0x07,0x01,0x04,0x03,0x0d,0x9e,0x99,0x14,0x0f,0x0c,0x0d,0x99,0x80,0x96,0x09,0x8b,0x90,0x1e,0x83,0x88,0x32,0x1a,0x9f,0x9f,0x92,0x82,0x94,0x0e,0x1e,0x87,0xb1 +,0xb1,0x80,0xb4,0x07,0xa9,0x8e,0x8e,0x92,0x86,0xa0,0x24,0x97,0x89,0x8f,0x8c,0x84,0x0a,0xaf,0x80,0xa3,0x8c,0x9a,0x10,0x0a,0x40,0x87,0xb9,0x1e,0x10,0x00,0x08,0x89 +,0xa5,0x06,0x90,0x0d,0x00,0xa1,0x95,0x1a,0x0c,0x34,0x09,0x06,0x94,0x9c,0x06,0x26,0x97,0x01,0x56,0x80,0x10,0x10,0x2d,0x0d,0x05,0x45,0x90,0x1d,0x0f,0x0d,0x01,0x0d +,0x88,0xd6,0x14,0x8f,0x06,0x0e,0x8b,0x9e,0x25,0xbd,0xa6,0x2b,0x93,0x84,0x59,0x13,0x8e,0x9e,0x4b,0x80,0x8a,0x17,0xba,0xa0,0x2d,0xad,0x83,0x90,0x1d,0x21,0x1e,0x17 +,0x92,0x8e,0x10,0xa3,0x37,0x0a,0x9a,0xa8,0x19,0x18,0x29,0x13,0x28,0x96,0x50,0x0a,0x9c,0x8d,0x16,0x87,0x80,0xcd,0x97,0x8f,0x92,0x8d,0x82,0x82,0x92,0x9e,0xac,0xbf +,0x8e,0x86,0x25,0x8d,0xab,0x09,0x93,0xa9,0x0d,0x08,0x0b,0x05,0x12,0x38,0x0a,0x00,0x0c,0x1d,0x00,0xcb,0xb8,0x00,0x0e,0x0b,0x0f,0x0e,0x27,0x14,0x08,0x0b,0x08,0x07 +,0x92,0x92,0x08,0x8a,0x42,0x0c,0x92,0x8d,0xb5,0x3d,0x8e,0x4c,0x19,0x8e,0x99,0x0d,0x8a,0xa8,0x1a,0x80,0x8f,0x95,0x8e,0xa7,0xb5,0x92,0x80,0x8c,0x93,0x96,0x23,0xb5 +,0x80,0xa6,0x9e,0x84,0x12,0x99,0x80,0x8d,0xf8,0xd9,0xa2,0x17,0x3b,0xa0,0x0e,0x2e,0x99,0x01,0x9a,0x94,0x16,0x9f,0x29,0x11,0x0c,0x97,0x9c,0x1f,0x32,0x19,0x00,0xaf +,0xc6,0x0c,0x81,0x3c,0x19,0x1d,0x19,0xef,0x30,0x24,0x0c,0x08,0x0a,0x0a,0x21,0x9e,0x02,0x1e,0xae,0x07,0xae,0xaf,0x14,0x08,0xc0,0x9b,0x1c,0xaa,0x2a,0x05,0xa0,0x8f +,0x5e,0x80,0xa2,0x34,0x9d,0xae,0x97,0x8e,0x82,0xd1,0x27,0x9f,0x1b,0x4d,0x82,0x1c,0xb7,0x8e,0x1a,0x90,0xa3,0xaa,0x7e,0x29,0xb5,0x0d,0x1d,0x24,0x09,0x92,0x18,0x0b +,0x83,0x42,0x2b,0xad,0x1f,0x17,0x2c,0x84,0x9e,0xdf,0xa4,0x0e,0x9f,0x84,0xa1,0x80,0x88,0xb9,0x82,0x86,0x8a,0x9d,0x8e,0x9f,0x23,0x8c,0xa8,0x0b,0x96,0x1e,0x0e,0x8d +,0x0f,0x46,0x1f,0x05,0x09,0x0b,0x17,0x06,0x08,0x09,0x00,0x1d,0x25,0x00,0x98,0x0f,0x06,0x26,0x0a,0x0d,0x10,0xa9,0x35,0x09,0x1d,0x02,0x37,0x88,0x06,0x99,0x91,0x16 +,0x8c,0x87,0x97,0xbe,0x8f,0x8e,0x3a,0x8f,0x9e,0x2b,0x86,0x47,0x94,0x80,0xb5,0x8d,0x90,0xa8,0x99,0x8b,0x81,0xeb,0xae,0xb7,0x09,0x86,0x98,0x58,0x80,0xf3,0xa7,0x91 +,0xa5,0xc3,0xce,0x94,0x2e,0x1c,0xa9,0x04,0xc0,0x9a,0x06,0x8b,0x68,0x0e,0xe2,0xb8,0x96,0x13,0x08,0x99,0x35,0x2a,0x0f,0x06,0x9a,0x00,0x22,0xc7,0x05,0x14,0x00,0x08 +,0x00,0x04,0x0c,0x00,0x07,0x02,0x00,0x2e,0x05,0x0a,0x3b,0x00,0x2c,0x3e,0x11,0x21,0xbe,0x8f,0xcf,0x91,0x99,0x26,0x80,0x8a,0x96,0x80,0x82,0x80,0x81,0x82,0x87,0x86 +,0x80,0x8a,0x83,0x85,0x9f,0x81,0x87,0x95,0x80,0x8a,0x94,0x85,0x91,0xa8,0x9b,0x8c,0x44,0x1e,0xcf,0x00,0x51,0xa6,0x00,0xaa,0x16,0x05,0x18,0x0b,0x07,0x01,0x0a,0x08 +,0x00,0x04,0x00,0x01,0x12,0x00,0x0d,0x10,0x00,0x0b,0x05,0x05,0x00,0x0b,0x0d,0x00,0x0c,0x02,0x01,0xa4,0x05,0x26,0x93,0x0c,0xad,0xba,0x99,0xc2,0x90,0x87,0x4c,0x8b +,0x94,0xbb,0x80,0x9c,0x8e,0x80,0x8d,0x80,0x82,0x81,0x86,0x85,0x80,0x87,0x82,0x87,0x9f,0x80,0x8a,0x8d,0x80,0x87,0x83,0x81,0x82,0x86,0x85,0x80,0x8b,0x8c,0x86,0xcc +,0x83,0x8d,0x2c,0x80,0xb0,0xa4,0x8d,0xa2,0xac,0x2e,0x97,0x13,0x0b,0x20,0x00,0x15,0x33,0x00,0x2c,0x09,0x03,0x0e,0x02,0x04,0x00,0x0c,0x07,0x00,0x07,0x00,0x04,0x19 +,0x00,0x16,0x0c,0x00,0x0d,0x04,0x07,0x01,0x19,0x0f,0x01,0x0e,0x04,0x02,0xa7,0x02,0x19,0xbd,0x01,0x28,0x1e,0x1e,0x10,0x2f,0xb3,0x0d,0x26,0x28,0x05,0x8c,0x13,0x1e +,0x87,0x16,0x9a,0x9e,0xac,0x2e,0x9a,0x87,0xbd,0x9d,0x93,0x0f,0x8a,0x8d,0xbd,0x80,0x9c,0x8c,0x8b,0x8e,0x8e,0x8b,0x80,0x91,0x91,0x84,0x35,0x8d,0x83,0xac,0x80,0x8d +,0x8b,0x83,0x85,0x88,0x90,0x83,0x86,0x94,0x87,0xa3,0x9b,0x81,0x30,0x85,0x85,0x96,0x86,0x94,0x8e,0xa6,0x89,0x88,0xac,0x8d,0x55,0x28,0x82,0x37,0x91,0x84,0x78,0x8b +,0x95,0x93,0xa6,0x8d,0x84,0x47,0x97,0x97,0x19,0x84,0xaa,0x36,0x80,0x4c,0x90,0x96,0x9f,0xba,0x35,0x89,0x2f,0x24,0xdf,0x00,0x1e,0x2d,0x01,0xaa,0x10,0x09,0x0d,0x01 +,0x05,0x04,0x10,0x07,0x00,0x05,0x00,0x04,0x0e,0x00,0x0c,0x0a,0x00,0x06,0x01,0x02,0x00,0x07,0x05,0x00,0x05,0x01,0x00,0x0f,0x02,0x02,0x15,0x01,0x05,0x04,0x03,0x00 +,0x06,0x14,0x02,0x05,0x08,0x00,0x13,0x0d,0x02,0xa9,0x0d,0x0c,0x1c,0x15,0x12,0x21,0x91,0x22,0x29,0x9c,0x11,0x96,0x83,0x31,0x84,0x84,0x8a,0x80,0x82,0x84,0x86,0x80 +,0x82,0x84,0x80,0x8a,0x8b,0x80,0x8c,0x84,0x80,0x82,0x80,0x80,0x83,0x83,0x80,0x80,0x84,0x81,0x88,0x99,0x80,0x8b,0x91,0x80,0x89,0x88,0x81,0x84,0x8a,0x88,0x80,0x95 +,0x92,0x86,0x2b,0x90,0x8b,0x10,0x87,0x95,0xae,0x8e,0xd7,0x1b,0x14,0x9b,0x43,0x16,0x2e,0x04,0x05,0x32,0x01,0x25,0x4c,0x03,0x0d,0x08,0x06,0x03,0x13,0x0b,0x03,0x07 +,0x02,0x00,0x17,0x07,0x02,0x1d,0x01,0x07,0x09,0x05,0x02,0x07,0x0b,0x00,0x0b,0x0b,0x00,0x0e,0x0f,0x00,0xbb,0x15,0x08,0x1f,0x0f,0x07,0x0b,0xac,0x1e,0x17,0x29,0x03 +,0x18,0x91,0x08,0x9a,0x92,0x13,0x9f,0xa3,0xa7,0x49,0x8f,0xaa,0x36,0x94,0x4d,0x27,0x83,0x6f,0xee,0x80,0xb0,0x8d,0x87,0x99,0xbf,0x94,0x8d,0xa3,0x8e,0x95,0x17,0x8c +,0x92,0x1e,0x80,0x92,0xa8,0x8d,0x9b,0xb2,0x9b,0x86,0x9f,0xbc,0x9c,0x10,0xce,0x84,0x12,0x96,0x8f,0x13,0x99,0x9f,0xdc,0x22,0xab,0xb6,0x16,0xb1,0x1e,0x09,0x93,0x11 +,0x16,0x85,0x19,0x52,0xaf,0x1c,0x14,0x33,0x97,0x25,0x2a,0x4a,0x00,0x6a,0x9d,0x09,0x89,0xb9,0x1c,0xa3,0x47,0xd1,0x5e,0x91,0xbf,0x1c,0xa3,0x17,0x2c,0x87,0x11,0x9b +,0x88,0x30,0x8b,0x8d,0xa3,0xf5,0x90,0x8d,0xad,0x8d,0xa7,0x11,0x87,0xa4,0x2f,0x80,0xa1,0xa5,0x91,0xa5,0xb9,0x9c,0x85,0xac,0x44,0x9d,0x0b,0xbe,0x8b,0x0d,0x8c,0xa3 +,0x17,0x97,0xc7,0x35,0x1a,0xa9,0x57,0x14,0xbe,0x15,0x09,0x97,0x0b,0x1f,0x8a,0x13,0xc2,0x6e,0x17,0x0c,0x2d,0x9e,0x1f,0x28,0x25,0x00,0x73,0xa8,0x0d,0x87,0x31,0x16 +,0xb3,0x25,0x2f,0x39,0x99,0x4d,0x13,0x43,0x0e,0x1c,0x8b,0x0c,0x9b,0x8f,0x13,0x96,0xaa,0x3f,0x1f,0xab,0x99,0x28,0xdd,0x2e,0x08,0x92,0x3e,0x23,0x80,0x28,0xbb,0xa0 +,0x26,0x25,0xcf,0x91,0xe6,0x25,0xc2,0x08,0x48,0x8b,0x0d,0x8a,0x9d,0x14,0x95,0xb9,0x4b,0x25,0xa0,0x9f,0x15,0xaf,0x26,0x09,0x8c,0x16,0x2e,0x87,0x1a,0xa1,0xcd,0x28 +,0x1c,0x28,0x95,0x24,0x21,0x3c,0x02,0xb0,0xa7,0x0c,0x85,0x37,0x1d,0x9d,0x29,0x2d,0x1e,0x96,0xba,0x11,0xb2,0x0c,0x0f,0x8c,0x0e,0xa3,0x8e,0x13,0x99,0x4b,0x3e,0x22 +,0x37,0x93,0x1f,0x54,0x2a,0x04,0x94,0x2d,0x1c,0x80,0x1b,0xb4,0x9e,0x1e,0x6f,0x46,0x8b,0xe0,0x32,0x9f,0x05,0xcf,0x8b,0x0c,0x88,0x9b,0x1d,0x93,0x3b,0xab,0x1d,0x9d +,0x98,0x15,0xab,0x18,0x0d,0x8b,0x18,0xbc,0x86,0x13,0x98,0xca,0x39,0x2b,0x3f,0x8f,0x1e,0x5d,0xec,0x00,0x9c,0x9a,0x0d,0x83,0x33,0x1f,0xbe,0x2d,0xc4,0x17,0x8e,0xc5 +,0x0d,0xb9,0x09,0x14,0x8c,0x0b,0x9a,0x9d,0x0f,0x9d,0x1f,0x3f,0x13,0x4d,0xa4,0x16,0xbb,0x16,0x05,0x8e,0x1c,0x1b,0x83,0x18,0xe7,0xb7,0x37,0x1b,0x30,0x8d,0x27,0x29 +,0xb5,0x02,0xcd,0x8f,0x0e,0x86,0xb8,0x19,0xa5,0x37,0xd8,0x26,0x91,0xa6,0x1b,0xa4,0x0e,0x18,0x84,0x0f,0x9f,0x89,0x15,0x9b,0xa4,0xbf,0x21,0x9f,0x8d,0x1c,0xae,0x65 +,0x03,0x8d,0xa8,0x21,0x81,0x2f,0xca,0xab,0x70,0x4d,0x2e,0x8e,0xd5,0x1d,0xbf,0x06,0xd2,0x8e,0x0d,0x88,0xad,0x10,0x9d,0x4c,0x45,0x26,0x9a,0xad,0x17,0xa8,0x11,0x0e +,0x89,0x10,0xc8,0x8c,0x10,0xa4,0xcd,0x33,0x1e,0x4e,0x96,0x1e,0x2d,0x1f,0x04,0x98,0x5a,0x18,0x82,0x1f,0x34,0x9b,0x2f,0x2d,0x3e,0x95,0x3c,0x26,0xae,0x09,0xfa,0x8b +,0x0c,0x8d,0x96,0x16,0x95,0xb0,0x4a,0x2b,0x9a,0x9f,0x1b,0xaa,0x19,0x0d,0x88,0x19,0xc3,0x83,0x19,0x9d,0xa4,0x3a,0x20,0xc0,0x8d,0x2b,0xc5,0x54,0x02,0x95,0xa4,0x17 +,0x81,0x5a,0x68,0xa5,0xdd,0x49,0x28,0x8f,0x59,0x1b,0xd2,0x07,0x2e,0x8f,0x0d,0x8d,0x9b,0x1b,0x9f,0xdb,0x3c,0x1b,0x9d,0xae,0x1a,0xbf,0x10,0x0b,0x8e,0x18,0xc1,0x85 +,0x1e,0xaf,0x5b,0x33,0x1d,0x7c,0x96,0x24,0x28,0x20,0x03,0x99,0xa8,0x19,0x82,0x27,0x2d,0xab,0x49,0xeb,0x51,0x92,0x3b,0x1a,0x5e,0x0a,0x50,0x8d,0x0c,0x8d,0x9f,0x25 +,0x98,0xc3,0xd4,0x21,0x9a,0xa9,0x27,0xb5,0x0e,0x12,0x8c,0x12,0x9c,0x86,0x1f,0x9e,0xe5,0x3c,0x1e,0xa0,0x94,0x25,0xbf,0x20,0x06,0x8e,0xbf,0x26,0x84,0x1c,0x61,0xbc +,0x4d,0x3c,0x4e,0x93,0x2f,0x27,0x3c,0x0a,0xa3,0x9c,0x0c,0x88,0xbf,0x27,0x9d,0x35,0x1e,0x1e,0x9a,0x48,0x2a,0xb2,0x0a,0x21,0x8b,0x0f,0x8f,0x94,0x14,0xc8,0x25,0x27 +,0x1d,0x9a,0xa1,0x1d,0xdd,0x0e,0x0c,0x89,0x1e,0xaf,0x8a,0x0f,0xbd,0xfd,0xce,0x2a,0xbf,0x99,0x1a,0x6b,0x30,0x07,0x8e,0x37,0x15,0x82,0x34,0xab,0xaa,0x2e,0x25,0x33 +,0x8e,0x34,0x65,0xb9,0x02,0xa9,0x99,0x0e,0x84,0xb8,0x2b,0xad,0x2f,0xd4,0x37,0x8c,0x53,0x1a,0xba,0x08,0x31,0x8b,0x0c,0x8f,0x97,0x18,0x9b,0xbe,0xac,0x1e,0xa2,0xbf +,0x1c,0x9d,0x14,0x0c,0x8b,0x0f,0x32,0x86,0x1a,0xaa,0xcc,0x33,0x1a,0xa8,0x91,0x23,0xa9,0x23,0x00,0x98,0xc4,0x15,0x82,0x1d,0x23,0xa4,0xb2,0x32,0x5f,0x8b,0x23,0x30 +,0xb6,0x04,0xbe,0x99,0x04,0x91,0xa5,0x45,0x97,0xac,0xba,0x1b,0x97,0xe6,0x26,0xa5,0x08,0x16,0x8e,0x0d,0x97,0x8c,0x24,0x9d,0x3d,0x2c,0x16,0x94,0x9c,0x1b,0xa7,0x13 +,0x0c,0x88,0x1f,0x38,0x85,0x1c,0x6f,0x3a,0xbd,0x2e,0xb0,0x98,0x14,0xd7,0x56,0x07,0x8f,0xc6,0x0e,0x83,0xff,0xad,0x9d,0x49,0x1f,0x24,0x8f,0x23,0x28,0xad,0x01,0x43 +,0x93,0x0d,0x86,0x92,0x40,0xa9,0x37,0x3a,0x14,0x9c,0x2e,0x1d,0x94,0x0e,0x19,0x8e,0x07,0xae,0x8f,0x1d,0xa0,0x4f,0xc3,0x17,0x91,0x93,0x15,0xac,0x15,0x05,0x8d,0x1b +,0x20,0x87,0x2e,0x91,0x9c,0xac,0x14,0x22,0x9c,0x1c,0x5a,0x1d,0x00,0x9e,0xa4,0x2c,0x80,0xc0,0xc4,0xa3,0x57,0x1e,0x1f,0x97,0x23,0x56,0x9c,0x0c,0xb8,0x98,0x09,0x8f +,0x9d,0x2a,0xac,0x1c,0x16,0x1d,0x87,0x9a,0x28,0xb0,0x0b,0x26,0x87,0x0d,0xaa,0x8e,0x27,0x8d,0xac,0x2f,0x0f,0xbd,0xb3,0x0f,0x9d,0x30,0x07,0x96,0x17,0xb6,0x81,0x1f +,0xac,0x5c,0xbb,0x1e,0x1f,0xb1,0x14,0xa9,0x9e,0x0e,0x8f,0x43,0x0c,0x8a,0x28,0x7e,0xad,0x29,0x12,0x22,0x8c,0x44,0xd0,0x9e,0x08,0xac,0x93,0x08,0x8e,0xce,0x51,0x8b +,0xad,0x1e,0x0b,0x9d,0x4b,0x1e,0xa1,0x0b,0x11,0x94,0x10,0x8b,0x88,0x2f,0xa0,0xc2,0xec,0x0b,0xb7,0xa3,0x1f,0x96,0x3f,0x08,0x92,0x1c,0x1e,0x89,0x26,0x9c,0x34,0x1a +,0x0f,0xaf,0x83,0xae,0xb3,0x44,0x05,0x9e,0x44,0x0a,0x87,0x21,0xae,0xa3,0xcb,0x4d,0x23,0x8b,0x56,0x38,0xc2,0x03,0x3b,0x9a,0x0c,0x8a,0xad,0x24,0xa0,0xae,0xa9,0x1f +,0x8e,0xd6,0x1f,0x9b,0x11,0x1f,0x92,0x07,0xbf,0x8d,0x11,0xbc,0xdf,0x4c,0x12,0x9b,0x95,0x1a,0xae,0x17,0x0c,0x8d,0x1c,0x17,0x87,0x4e,0x97,0xa1,0xac,0x1f,0x7c,0x99 +,0x16,0xde,0x2f,0x06,0x9f,0xb7,0x0d,0x86,0xad,0x2c,0xa9,0xb9,0x16,0x11,0x93,0xa7,0x9b,0x92,0x0f,0xbb,0x97,0x01,0x9e,0x93,0x21,0xb4,0xb5,0xb5,0x1d,0x9d,0x3e,0x16 +,0xcd,0x0d,0x14,0x94,0x0c,0xba,0x80,0x95,0x8f,0xa4,0x3d,0x0b,0xbd,0xac,0x11,0x26,0x1e,0x0b,0x92,0xc7,0x18,0x83,0xe5,0xea,0xb5,0x42,0x11,0x1c,0x92,0xa9,0xaf,0xd4 +,0x05,0xb3,0x92,0x0b,0x88,0x9e,0x2e,0xab,0xaa,0xae,0x1b,0x9f,0x2a,0x12,0xcc,0x0a,0x0d,0x91,0x0d,0x9a,0x89,0x68,0x9d,0x6f,0xa6,0x14,0xb2,0xb0,0x0d,0x33,0x28,0x11 +,0x8a,0x34,0x3a,0x84,0x27,0xa7,0x32,0xbe,0x15,0x17,0x9a,0x2f,0xb9,0xac,0x0f,0x97,0x9f,0x0c,0x8c,0x2b,0xa4,0xa6,0x3d,0x41,0x16,0x96,0x29,0x2c,0x9b,0x0e,0x2c,0x98 +,0x06,0x93,0x8e,0xac,0x97,0x3b,0xcc,0x0c,0xa2,0xb2,0x1f,0xa8,0x18,0x16,0x8b,0x14,0x2e,0x88,0x2c,0xa8,0x1b,0x28,0x0e,0x40,0x8f,0x2c,0xa2,0xa8,0x0a,0x99,0xa4,0x0f +,0x85,0x6e,0xc4,0x52,0xca,0xe8,0x15,0x8d,0xbe,0x1f,0xa8,0x08,0x21,0x96,0x0a,0x89,0x99,0x42,0xbb,0x18,0xa6,0x17,0x9e,0x9f,0x17,0xaa,0x16,0x0f,0x88,0x13,0xb3,0x8d +,0x1d,0x9e,0x22,0xa8,0x18,0x32,0x8b,0x2e,0xc8,0x5d,0x09,0x8f,0x3b,0x13,0x87,0x1d,0xa3,0x2f,0x52,0x42,0x1a,0x8c,0x64,0x1e,0x37,0x07,0xa8,0x96,0x0b,0x88,0xc1,0xad +,0xa0,0x42,0xa2,0x16,0x97,0xc5,0x12,0xb7,0x10,0x18,0x8e,0x09,0x9e,0x8e,0x3f,0xa7,0x26,0x9a,0x1a,0xb7,0x96,0x22,0xb6,0x23,0x09,0x92,0x1a,0x24,0x85,0x4a,0x9c,0x36 +,0xa6,0x2c,0x1f,0x8e,0x33,0x1f,0x2d,0x04,0xa2,0xa4,0x0a,0x8b,0xaa,0x98,0xb2,0xb1,0xa9,0x0c,0x95,0xa3,0x19,0xd9,0x0a,0x22,0x93,0x0b,0x8d,0x91,0xa7,0xae,0x22,0xa4 +,0x0d,0xbe,0x95,0x28,0x36,0x0f,0x16,0x8b,0x12,0xa5,0x86,0xae,0xa0,0x19,0xad,0x18,0x22,0x91,0x2f,0x1b,0x10,0x0b,0x8b,0x3c,0x1d,0x86,0xa0,0x94,0x1f,0xb2,0x3b,0x14 +,0x92,0x4f,0x1b,0x1a,0x08,0x99,0xb6,0x0f,0x83,0x99,0xa2,0x1e,0x40,0xa6,0x11,0xa1,0xbf,0x2a,0x20,0x09,0xa2,0x8c,0x12,0x8e,0x90,0x9d,0x29,0x27,0x93,0x0d,0x23,0xb9 +,0x47,0x2a,0x0a,0x2f,0x8a,0x16,0xad,0x8f,0x9d,0xb7,0x1c,0x90,0x17,0x12,0xa8,0xac,0xf4,0x0a,0x0f,0x88,0x20,0x1f,0x8b,0x94,0x9b,0x0c,0xa3,0xbc,0x13,0xa9,0xa9,0xb8 +,0x0d,0x0a,0x85,0xa9,0x11,0x97,0x9d,0x8c,0x0f,0x29,0x9b,0x0b,0x2c,0xa8,0x9d,0x21,0x02,0x90,0x8e,0x0e,0xa3,0x9b,0x89,0x1a,0x0a,0x90,0x24,0x2e,0xbb,0xa0,0xa1,0x02 +,0x61,0x89,0x11,0x5c,0xbc,0x8c,0xae,0x03,0x98,0xa8,0x34,0x39,0x2e,0x98,0x09,0x1c,0x86,0x27,0xd3,0x38,0x9d,0x8b,0x0b,0xb4,0xb8,0x1c,0x3e,0x20,0x8d,0x1c,0x0c,0x91 +,0x4c,0x9e,0xe5,0x46,0x8d,0x18,0x5f,0xc8,0x2d,0x9d,0x19,0xa3,0x3f,0x11,0x99,0x28,0x3b,0x33,0x2f,0x8b,0x30,0x4b,0xb2,0x27,0x9e,0x29,0xaa,0xbf,0x11,0x9b,0x39,0x29 +,0x7c,0x21,0x94,0xa5,0x2a,0x3b,0x2e,0xa5,0x5b,0xcd,0xad,0x1b,0xc3,0x2f,0x27,0xb5,0x25,0xa5,0xa5,0x2f,0xaf,0xaa,0x9e,0xc5,0x29,0xef,0x27,0x3e,0x4c,0x23,0x2d,0x2e +,0xae,0xa4,0xbb,0xba,0xb5,0x9f,0xb3,0x1e,0xfd,0xb6,0x2e,0x2c,0x26,0xd0,0x68,0x28,0xb1,0xae,0xbd,0xab,0xbe,0xed,0x4f,0xbc,0xcd,0x22,0x2b,0x39,0x2c,0x31,0x2d,0xb3 +,0x9f,0x9e,0x9e,0x4e,0xc4,0x3f,0x26,0xb6,0x4f,0x2b,0x2b,0x2b,0x3e,0xdb,0xa5,0x96,0x9c,0x4b,0x2b,0x4a,0x2a,0x1e,0xb3,0x6f,0x28,0x3e,0x39,0xb3,0xb3,0xa8,0xa1,0xaf +,0xf4,0x23,0x2e,0x3f,0x3f,0xc3,0x3e,0x4f,0x4c,0x3c,0xb5,0x66,0xde,0xa0,0x9f,0xad,0x33,0x30,0xda,0x26,0x35,0x2e,0x24,0x41,0x2c,0xd2,0xb2,0xa4,0x99,0xae,0xea,0x2e +,0x3c,0xc7,0x1f,0x23,0x45,0xdc,0xb2,0xcf,0xb5,0xa0,0xa3,0xb2,0x3b,0x36,0x26,0x35,0xb6,0x24,0x2f,0xe3,0xbe,0xa6,0xc4,0xbc,0xbb,0x65,0x42,0x31,0xb3,0xb3,0x37,0x4f +,0x2f,0x40,0xbe,0xcd,0x2c,0x2c,0xc8,0xbb,0xae,0xbf,0xfe,0xb9,0xb1,0x69,0xe1,0x3e,0x25,0x24,0x3a,0x56,0xbd,0x9d,0xaf,0xbf,0x7a,0x2d,0x48,0x53,0x46,0x4f,0x32,0x47 +,0xe3,0xc4,0xb2,0x9f,0x9e,0x46,0x2d,0x20,0x21,0xca,0xa9,0xc7,0x2f,0x44,0x4c,0xd0,0xb3,0xb1,0xad,0xcd,0x2b,0x1e,0x34,0xc4,0xbc,0xa7,0xb6,0x3b,0x5e,0x3b,0x26,0x32 +,0xae,0xa3,0xb7,0x44,0x2e,0xf2,0xad,0xb9,0x54,0x62,0x28,0x29,0x33,0x2c,0xaa,0x9e,0x9e,0xac,0x3e,0x35,0x35,0x47,0x3f,0x3d,0x4b,0x31,0x3d,0x78,0xaa,0x98,0xab,0xc4 +,0x37,0x1f,0x2e,0x3d,0xd6,0xc8,0x2d,0x42,0xd2,0xc5,0xa6,0xb7,0xb6,0xce,0x37,0x3f,0x2f,0x3a,0x5c,0xc2,0xb2,0x3f,0xbc,0x32,0x1e,0xb7,0xc8,0xa1,0xaa,0x2a,0x4b,0xc2 +,0xbd,0xc2,0x53,0x34,0x1e,0x2e,0x5b,0x37,0xac,0xa6,0x9b,0xa7,0x2e,0x3b,0x2e,0x3d,0x41,0x32,0x7c,0x31,0x2c,0xdc,0xac,0x96,0x98,0xaf,0x2d,0x18,0x22,0x6d,0xb5,0x31 +,0x2e,0xc5,0xfa,0xb7,0xb6,0xd3,0xae,0xb5,0xda,0x59,0x3c,0x2f,0x33,0xae,0x78,0xbf,0xc4,0x1e,0x26,0x4f,0xb0,0xb3,0xaf,0xbb,0xc5,0xb4,0xb2,0xcd,0xcf,0x25,0x19,0x39 +,0x2e,0x3e,0xe8,0xbb,0xa2,0x9c,0xaa,0x36,0x3e,0x48,0x36,0x5e,0x3f,0x22,0x28,0xd8,0xa7,0x9a,0x9d,0x5d,0x2d,0x3b,0x3e,0x52,0x5a,0x1e,0x25,0xb7,0xb9,0xae,0xb5,0x48 +,0x4f,0xb6,0xb8,0x52,0x43,0x36,0xd6,0xb4,0x49,0x44,0xae,0x3c,0x2e,0x4d,0xd3,0xb3,0x5c,0xdf,0x42,0xab,0xa2,0x5e,0x3c,0x22,0x22,0x5c,0x34,0x27,0x70,0xa4,0x98,0x9d +,0xae,0x36,0x2d,0x61,0x44,0xdb,0x2f,0x18,0x26,0xd1,0xb0,0x9a,0x9b,0xcd,0x3c,0x39,0x57,0x47,0x5b,0x2d,0x29,0xc4,0xe9,0xad,0xad,0x31,0x66,0xa9,0xb9,0x4b,0x23,0x2f +,0x38,0xb5,0xa0,0x55,0x38,0x1b,0x4a,0x9e,0xdd,0xc7,0xd6,0x49,0xc7,0xb5,0xa5,0xcd,0x5e,0x3d,0x1f,0x27,0x2d,0x32,0xdf,0xa5,0x9f,0xa9,0x3a,0x2d,0x46,0xbe,0xa5,0x7c +,0x2c,0x12,0x23,0x9d,0x9e,0x95,0xa0,0x25,0x1f,0x2e,0xef,0x5b,0x2d,0x31,0x2c,0xb1,0x66,0xbe,0xa1,0xcd,0x9e,0x9f,0x4c,0x1f,0x1e,0x39,0xcc,0xaf,0xa8,0x31,0x22,0x27 +,0xb7,0xa3,0xed,0xad,0xbd,0x32,0x26,0x56,0xba,0xf9,0xb4,0xa3,0x23,0x1d,0x51,0x24,0xa6,0x92,0x95,0xbe,0x1b,0x1b,0x28,0xad,0xa8,0x35,0x1f,0x16,0x3c,0x9d,0x9f,0x94 +,0x9b,0xcb,0x2b,0x2a,0x29,0x28,0x36,0x3f,0x29,0x27,0xa7,0xa2,0xa7,0x9f,0x9f,0x9b,0x1c,0x0f,0x1a,0x28,0xb5,0xb8,0xac,0x1f,0x4d,0x96,0xa4,0x98,0xa6,0xcf,0x2a,0x0f +,0x22,0x3d,0xbb,0x38,0x40,0x2f,0x2c,0xc7,0x46,0xa0,0x99,0x90,0xe1,0x1a,0x12,0x2d,0x8d,0x8c,0xa6,0x11,0x08,0x31,0x51,0x8b,0x84,0x19,0x05,0x08,0xaf,0x8e,0xb7,0x1c +,0x0e,0x0d,0xb4,0x88,0x88,0xae,0x30,0x5d,0xd9,0x15,0x11,0xe7,0xa2,0xac,0x97,0x95,0x2d,0xae,0x39,0xb6,0xac,0xaa,0xa2,0x1b,0x0d,0x08,0x1e,0x91,0xa9,0x0b,0x1f,0x8b +,0x9e,0x2b,0x9a,0x93,0x99,0x29,0x12,0x0b,0x08,0xa0,0x85,0x8c,0x16,0x11,0xad,0x29,0xbb,0x8c,0x8c,0x13,0x05,0x2c,0x9f,0x91,0xbc,0x38,0x1c,0x21,0xab,0x98,0x8f,0xac +,0xb0,0x23,0x0c,0x0a,0x08,0xa5,0x9a,0x1b,0x3d,0x8e,0x87,0xb5,0xc1,0x8c,0xa3,0x1d,0x12,0x2f,0x4d,0xa7,0x99,0x22,0x07,0x06,0x8d,0x8b,0x16,0x1d,0x9c,0x9b,0x1f,0x35 +,0x4f,0x1f,0x35,0x9e,0x8c,0xbc,0x32,0x5c,0x37,0x9f,0x9c,0x92,0x26,0x08,0x08,0x2b,0x88,0x97,0xb7,0x11,0x0f,0x2f,0xc9,0x84,0x8b,0x23,0x0a,0x14,0x49,0x1a,0xdd,0x91 +,0x9d,0x29,0x14,0x8f,0xb8,0xea,0x88,0x95,0x2a,0x02,0x23,0xc1,0x2e,0x9d,0xae,0xda,0x07,0x27,0x88,0xaf,0x31,0x3d,0x8f,0xa3,0x1d,0x36,0x15,0x20,0x3d,0x94,0x98,0x19 +,0x42,0x1d,0xc7,0xb6,0xb2,0x99,0x2e,0x16,0x1b,0x94,0x86,0x9f,0x39,0x12,0x47,0x9b,0xb2,0x99,0x36,0x17,0x11,0x1a,0x15,0x0d,0xbe,0x93,0x9a,0x1e,0x28,0x93,0xb8,0xb4 +,0x8f,0x90,0x1c,0x0b,0x5e,0x9c,0x9e,0xa3,0xad,0x1e,0x05,0xda,0x92,0xc2,0xf1,0x6f,0xa6,0x16,0x1b,0xac,0x3c,0x25,0x2e,0x8e,0x97,0x37,0xc8,0x18,0xb2,0xa4,0xad,0x2d +,0x0c,0x21,0x23,0x9d,0x8d,0x9b,0x9f,0x10,0x3d,0x44,0x4c,0x8d,0x8f,0xa3,0x0b,0x0f,0x14,0x11,0xb4,0x8f,0x95,0x19,0x0e,0x95,0xa2,0x9e,0x9e,0xce,0x0e,0x08,0xae,0xa0 +,0xab,0xae,0xb7,0x2e,0x0c,0xa4,0x86,0xb8,0x6e,0x77,0x99,0xaf,0x4c,0x43,0x0b,0x10,0xdc,0x9b,0x64,0x10,0x9b,0xcb,0xb3,0x9d,0xa2,0xbd,0x0b,0x1d,0x46,0xcd,0x94,0x93 +,0xa4,0x14,0x2b,0x9c,0x1f,0x9e,0xae,0x9d,0x19,0x05,0x24,0x1b,0x49,0x9e,0x98,0xcf,0x0e,0x93,0x8d,0xac,0x8f,0x9b,0xb9,0x09,0xd3,0x98,0x2e,0x38,0x16,0x26,0x0e,0x1c +,0x8f,0x5c,0x75,0xa8,0x92,0xde,0x14,0x38,0x18,0x1f,0x9e,0x97,0x9e,0x0e,0x31,0x8e,0xbd,0x9f,0x9f,0x9c,0x18,0x16,0x33,0x1e,0xba,0x99,0xa8,0x23,0x0b,0xaa,0xb6,0x50 +,0x95,0x97,0xa5,0x09,0x13,0x22,0x30,0x95,0x96,0xd0,0x0a,0x16,0x89,0xa6,0xa3,0xa2,0xaa,0x3b,0x25,0x98,0x65,0x26,0x26,0x2f,0x37,0x0b,0xa1,0x91,0x27,0x9e,0x8e,0x8c +,0x0e,0x0e,0x16,0x0f,0xfb,0xa0,0x95,0x45,0x0e,0xa0,0xbd,0x34,0xa3,0x94,0xa2,0x0a,0xd7,0xaa,0xab,0x9a,0x99,0x9d,0x0d,0x0e,0xbe,0x36,0xad,0x9e,0x94,0x15,0x09,0x29 +,0x2d,0xb1,0xa6,0xa9,0x31,0x1b,0x9b,0x92,0x30,0xc2,0x96,0x96,0x24,0xea,0x3a,0x12,0x1d,0xae,0xaa,0x1e,0x0d,0x9b,0x65,0x28,0x8f,0x89,0x9e,0x0a,0x28,0x1f,0x30,0x97 +,0x8d,0x95,0x17,0x19,0x99,0x10,0x12,0xaa,0x90,0x22,0x0c,0xa8,0x2d,0xce,0x93,0x93,0x48,0x06,0x26,0x94,0x28,0xa5,0x94,0x99,0x12,0x1b,0x9d,0x2a,0x36,0xb0,0xa5,0x59 +,0x18,0xa1,0xaf,0x1c,0xc5,0x93,0x9e,0x0f,0x1c,0x24,0x23,0xab,0x92,0x9d,0x1a,0x1c,0x97,0x3d,0xb5,0x9c,0x9f,0x18,0x0d,0x3c,0x25,0xb8,0x95,0x8c,0xb3,0x13,0x32,0x56 +,0x12,0xac,0x92,0x96,0x1a,0x33,0xb1,0x46,0x9d,0x9e,0xbb,0x11,0x0a,0x9c,0xae,0x1a,0xb1,0xa4,0x4f,0x06,0x5b,0xb8,0x1e,0xb6,0x94,0x92,0x34,0x2e,0x8c,0x5f,0x3b,0x93 +,0x92,0x1f,0x07,0x3d,0x1e,0x16,0xb8,0xa4,0x54,0x1d,0x4f,0x90,0x2e,0xb9,0x9c,0xa8,0x18,0x18,0xad,0x51,0xa8,0x8f,0x9a,0x2b,0x0c,0x4f,0x40,0x1e,0x9e,0x9c,0xa8,0x11 +,0xb1,0xba,0x26,0xb4,0xb2,0xcd,0x11,0x3a,0x89,0x57,0xa6,0x95,0x9f,0x18,0x0a,0x30,0x0f,0x23,0xa3,0x9a,0xf4,0x10,0xa7,0x92,0x2e,0xa3,0x92,0x9b,0x0e,0x22,0xca,0x19 +,0x38,0xa2,0x9d,0x24,0x16,0x9b,0xa0,0x2c,0xa8,0x96,0x63,0x0b,0x3e,0x42,0x2d,0xa9,0x9b,0xab,0x0d,0x17,0x96,0xce,0xb4,0x98,0x8c,0x3b,0x29,0x9d,0x23,0x1d,0x2e,0x3a +,0x22,0x0e,0xb1,0x9d,0x5b,0x9a,0x9d,0xa1,0x12,0x2b,0x23,0x17,0xbe,0x99,0x97,0x2f,0x4d,0x8f,0x66,0x54,0x97,0x9e,0x26,0x0f,0x3c,0x11,0x13,0x52,0xb1,0x36,0x12,0xad +,0x9a,0x2e,0xa4,0x8c,0x95,0x21,0xb3,0x9d,0x24,0x2d,0xaa,0xbe,0x0e,0x0a,0xae,0x3b,0x1e,0x95,0x87,0xa2,0x1e,0x9f,0x42,0x19,0xcd,0xab,0x3c,0x0f,0x2c,0x95,0x49,0xba +,0xa0,0x9f,0x13,0x14,0xc5,0x1b,0x28,0xa1,0x95,0x59,0x1c,0x9a,0xac,0x31,0x9d,0x97,0xa4,0x15,0xdd,0x3b,0x20,0xa7,0x9f,0xc6,0x0a,0x20,0xa3,0x18,0x3e,0xa6,0x9e,0x1f +,0x28,0x9f,0x27,0xf3,0x9b,0x9c,0x1f,0x0a,0xab,0xba,0x24,0x91,0x86,0x9b,0x18,0xaf,0x61,0x11,0xd2,0xa1,0xe6,0x0d,0x2f,0x8e,0x2e,0x2b,0xa4,0x9a,0x0f,0x0b,0xc4,0x21 +,0x39,0x90,0x8c,0xbf,0x15,0x9b,0xab,0x19,0xac,0x97,0xc0,0x0a,0x26,0xcd,0x2b,0xaf,0x98,0x9e,0x12,0x21,0x97,0x26,0x4b,0x95,0x92,0x27,0x17,0xca,0x25,0x3d,0xa8,0xa9 +,0x19,0x08,0xb4,0xaf,0x1f,0x9d,0x8e,0xa0,0x17,0xcb,0xbc,0x1f,0xaf,0x9b,0x9f,0x22,0xc6,0x8e,0x6d,0x45,0x9c,0xac,0x0c,0x05,0x20,0x20,0x3b,0x97,0x92,0x47,0x19,0x92 +,0x9c,0x32,0xb5,0x9d,0x6d,0x0c,0x2c,0xbb,0x34,0x4c,0x9e,0x9e,0x11,0x24,0xa4,0x38,0xb0,0x91,0x91,0x20,0x15,0x38,0x4c,0xdd,0xe9,0x56,0x13,0x12,0xa7,0xab,0x9e,0x92 +,0x91,0xbf,0x17,0x2f,0x1d,0x29,0x58,0xaf,0x39,0x17,0xab,0xa8,0x9e,0x95,0x94,0xd1,0x0a,0x0f,0x26,0xce,0xa0,0x9a,0xaa,0x19,0x35,0xa3,0xbb,0xad,0xa4,0x9f,0x1e,0x1c +,0x2a,0x2e,0xe8,0xbf,0xae,0x1b,0x15,0x3a,0x5a,0x9f,0x94,0x8e,0xab,0x2f,0xcc,0x39,0xa9,0x7c,0x35,0x18,0x0d,0x29,0x1f,0xd8,0x9a,0x92,0x9c,0x29,0x38,0x1a,0x21,0xac +,0xa2,0xa5,0x27,0xbf,0xaf,0xbf,0x90,0x90,0xb3,0x0f,0x13,0x1e,0x23,0xe2,0xbf,0xac,0x1c,0x43,0xa7,0x31,0xd5,0xb3,0x9b,0x35,0x3c,0xab,0xdf,0xab,0xb6,0x9e,0x31,0x15 +,0x28,0x1a,0x43,0xab,0x9c,0xac,0x2e,0xb3,0xbb,0xa5,0xba,0xfd,0x31,0x1b,0x26,0x28,0x36,0xd5,0xa3,0x9b,0x5c,0x75,0x39,0x24,0x30,0xc8,0xa2,0x3b,0x3c,0xe6,0x3d,0xcf +,0xa7,0xa4,0x2a,0x19,0x3e,0xd9,0xac,0x9f,0x98,0x9a,0xd5,0xc9,0xd8,0x25,0x1c,0x35,0xd6,0x1f,0x1f,0x42,0xbc,0xe2,0xc3,0x9f,0x45,0x1c,0x1f,0x2c,0x32,0xc2,0x96,0x9a +,0xa4,0xa1,0x9f,0xa5,0x4d,0x5a,0xdd,0x2d,0x20,0x16,0x1e,0x28,0xbd,0xa0,0x6d,0x30,0x28,0x2c,0x44,0xb0,0xa1,0xaf,0xbc,0xb9,0xc2,0xb5,0xae,0xc5,0x24,0x1d,0x24,0x32 +,0x4e,0xbd,0xa0,0xa9,0xb3,0xca,0x4b,0x39,0x3b,0xad,0xb1,0x6e,0xf5,0xbd,0xa7,0xb9,0xc8,0xbe,0x2f,0x19,0x17,0x1f,0x2a,0x2e,0x79,0xaa,0xa2,0xa7,0xa3,0xb2,0x3c,0x34 +,0xb6,0xaf,0x34,0x3a,0xd7,0xb8,0xc0,0xa9,0xa5,0x37,0x1d,0x1f,0x26,0x37,0xfe,0xad,0xaf,0x47,0xd6,0xb3,0xb8,0x62,0x33,0x32,0x26,0x2c,0xe5,0xb9,0xa3,0x9d,0xa5,0xc4 +,0x35,0x30,0x46,0x42,0xc7,0xdc,0xe3,0xca,0xd7,0xe8,0x55,0xd8,0x39,0x21,0x22,0x30,0x34,0xfe,0xab,0x98,0x99,0xa8,0xaa,0x4d,0x28,0x2d,0x33,0x32,0x1f,0x29,0x6e,0x7c +,0xab,0xa8,0xac,0x75,0x29,0x32,0x38,0xc0,0xb9,0xb1,0xab,0xc5,0xc1,0xc2,0x43,0x2d,0x30,0x28,0x24,0x1e,0x37,0xa4,0xaf,0xa9,0xa4,0xb5,0xd6,0x41,0x47,0x37,0xdb,0xa8 +,0xb7,0xac,0xad,0xb4,0xba,0x2c,0x30,0x2d,0x1e,0x1b,0x1b,0x31,0xc3,0x9f,0x98,0xa6,0xb8,0xd5,0x3b,0x47,0xfd,0xce,0x3e,0x32,0x3f,0x3f,0xbe,0xad,0xa9,0xab,0x35,0x19 +,0x1a,0x37,0x9f,0x99,0xa5,0x4d,0x34,0x3b,0x2c,0x46,0xb2,0xaf,0x4b,0x1a,0x0d,0x1c,0x9d,0x89,0x8f,0x4b,0x25,0x3f,0x3f,0x34,0xdb,0xa6,0xad,0x36,0x19,0x12,0xba,0x8c +,0x8f,0xb6,0x18,0x17,0x28,0xcc,0xe3,0x33,0x9b,0x9a,0x26,0x17,0x1d,0x9d,0x8f,0xaa,0x2d,0x19,0x29,0x6d,0x4c,0x36,0xc1,0xa0,0xcd,0x15,0x1d,0xad,0x94,0x8f,0xa5,0xcd +,0x4a,0x3e,0x62,0x2d,0x20,0x40,0xce,0x26,0x11,0x16,0xc3,0xa0,0x98,0xa4,0x3a,0x55,0xd9,0x4c,0x39,0xb9,0x9b,0x9b,0x39,0x17,0x22,0xa6,0xa3,0x9d,0xaa,0x3d,0x4e,0x22 +,0x27,0x23,0xd7,0xaa,0xd5,0x21,0x1c,0x2f,0xa6,0x97,0xa6,0x4e,0x26,0xef,0x43,0x25,0xb7,0xa0,0xab,0x35,0x19,0x29,0xda,0x99,0x99,0xbb,0xc2,0x2f,0x2c,0x26,0x46,0x9e +,0x9f,0x5a,0x16,0x1a,0xfb,0xb2,0xa6,0xad,0xc0,0xde,0x25,0x1f,0x27,0xac,0x9c,0xb3,0x2d,0x1e,0x3c,0xa9,0xad,0xb6,0xcf,0xeb,0xb3,0x35,0x2e,0xc5,0x9e,0x9e,0x36,0x1c +,0x29,0xcb,0xa9,0x62,0x27,0x34,0x48,0x32,0x1c,0x2c,0xa2,0x9a,0xaf,0x2e,0x26,0xb3,0xa8,0xac,0xad,0xc7,0xb8,0x3b,0x24,0x27,0x50,0x9c,0xa8,0x39,0x25,0x22,0xbd,0xb7 +,0xda,0xec,0x41,0xcd,0x47,0x2e,0x33,0xa6,0x98,0x54,0x1c,0x27,0xaf,0xad,0x56,0x7b,0x31,0x2f,0x35,0x35,0xb8,0x9b,0x9e,0x36,0x2c,0xbe,0xaa,0xdb,0x4a,0xae,0xc6,0x34 +,0x2e,0x1c,0x2c,0xa0,0x9d,0x33,0x13,0x33,0x9d,0xab,0x29,0x3e,0xab,0xd9,0x4a,0x3f,0x28,0xbe,0x99,0xa5,0x2a,0x27,0xb6,0xa6,0xcf,0x32,0x49,0xbb,0x4d,0x27,0x2d,0x29 +,0xa3,0x97,0x3d,0x1c,0x3c,0x9f,0xc9,0x2d,0x3d,0xdb,0xb1,0xcd,0x2a,0x25,0xd7,0x99,0xab,0x37,0x3b,0xbf,0xaf,0x3f,0xd4,0xcd,0x58,0x49,0x27,0x22,0x2c,0xb6,0xab,0xbf +,0xe2,0x2e,0xc5,0xbe,0xaf,0x9c,0xa7,0xab,0x2f,0x19,0x1c,0x3b,0xac,0x43,0x2d,0x31,0x4c,0xa3,0xe0,0xa8,0x96,0x9f,0xbe,0x14,0x14,0x21,0xae,0xad,0x27,0x2d,0x64,0xa8 +,0xac,0xa3,0x9a,0x97,0xbb,0x12,0x13,0x1e,0x3f,0xe4,0x3e,0x3a,0x38,0xb1,0x9d,0x9c,0x99,0x9b,0x9f,0x30,0x0c,0x0f,0x27,0x53,0x54,0x28,0x32,0xac,0xa0,0xa4,0xaf,0x97 +,0x96,0x47,0x18,0x0f,0x25,0x72,0x5d,0x3c,0x39,0xa7,0xa5,0xa5,0xaf,0xa2,0x95,0xc4,0x1f,0x1a,0x1a,0x2e,0x43,0x2e,0x22,0xd8,0xa1,0xaf,0xab,0xae,0xa4,0xa6,0xc7,0x1f +,0x13,0x27,0xe2,0xc5,0x28,0x32,0x9c,0xa0,0xbf,0xcb,0xa5,0x9c,0xbd,0x23,0x15,0x2c,0xb9,0x2c,0x25,0x30,0xa5,0x9a,0xbc,0xe0,0xc8,0xab,0xac,0x50,0x31,0x1c,0x25,0x37 +,0x22,0x33,0xbd,0xa2,0xac,0xaf,0xaa,0xbe,0xb1,0xaa,0x4b,0x27,0x29,0xc2,0x5e,0x19,0x31,0x9c,0x99,0x5d,0x3f,0xc0,0xbe,0x6b,0x2e,0x22,0x28,0x4b,0x39,0x2e,0x27,0xbd +,0x97,0xa6,0xcb,0xab,0x9f,0xb8,0x2d,0x33,0x2b,0x2d,0x2e,0x29,0xf5,0xaf,0xb2,0xb1,0xac,0x3d,0x3c,0xac,0xa4,0xb2,0x29,0x20,0x35,0x35,0x2d,0x3f,0xa0,0x9f,0xc7,0x3e +,0x29,0x40,0xfb,0xba,0xef,0x4c,0x3e,0x29,0x2e,0x47,0xad,0x98,0xa4,0xc0,0x42,0x48,0x5e,0x3f,0xb5,0x39,0x3f,0x2d,0x22,0x32,0x4c,0x9f,0x9a,0xae,0x32,0x2e,0x6e,0xfc +,0xf1,0x5a,0x39,0x36,0x25,0x2a,0x3a,0x9e,0x90,0x9e,0xcb,0x29,0x56,0x72,0x35,0x3d,0xe9,0xcd,0x1f,0x17,0x23,0xaf,0x90,0x96,0xab,0x33,0x27,0x3f,0x4a,0xd1,0x58,0xea +,0x35,0x1e,0x1f,0x3e,0x9c,0x91,0x9c,0x51,0x2b,0x32,0x34,0x59,0x7e,0xe8,0x4f,0x1f,0x12,0x20,0x96,0x8c,0x93,0xad,0x25,0x42,0xdc,0x2e,0x25,0xe3,0xae,0x20,0x12,0x18 +,0xb7,0x92,0x8f,0x96,0xd5,0x28,0x27,0x2b,0x2f,0xb6,0x99,0x3d,0x0c,0x0e,0x44,0x92,0x8e,0x9a,0x3f,0x2d,0x57,0x37,0x2e,0x38,0xa9,0xb7,0x1d,0x12,0x1c,0xaa,0x90,0x8e +,0x9f,0x4d,0x2f,0x21,0x21,0xec,0x9c,0xa4,0x1c,0x0b,0x0e,0x78,0x8d,0x8e,0xa4,0x53,0x42,0x3c,0x3d,0x28,0xea,0x9e,0xb5,0x1c,0x0b,0x24,0x9d,0x97,0x96,0x9f,0xb3,0x2a +,0x17,0x25,0xb8,0x95,0xa4,0x16,0x09,0x18,0x9a,0x90,0x9e,0xd7,0x46,0x47,0x3c,0x2d,0x32,0xaa,0x9d,0xef,0x15,0x11,0x3f,0x9b,0x91,0x9a,0xe2,0x3f,0x1e,0x1c,0x4f,0xa3 +,0x97,0xba,0x15,0x0a,0x2b,0x8e,0x8e,0xa9,0x34,0x4d,0xd5,0x2e,0x1e,0x35,0xa8,0xa6,0x2a,0x10,0x17,0xab,0x94,0x9a,0xa9,0xbc,0x2b,0x1b,0x26,0xbf,0x92,0x98,0x29,0x0b +,0x0f,0xa8,0x8e,0x90,0xad,0x29,0x2d,0x2c,0x2e,0x2e,0xdd,0x98,0xa7,0x18,0x0e,0x21,0x9e,0x8e,0x96,0xd3,0x29,0x25,0x1f,0x1d,0xa3,0x8d,0xa5,0x14,0x08,0x21,0x93,0x8c +,0x98,0x4c,0x27,0x41,0x3b,0x28,0x32,0x9c,0x9d,0x28,0x0f,0x0e,0xe3,0x92,0x8e,0x9b,0x5c,0x2a,0x19,0x1a,0x40,0x9c,0x93,0xc4,0x0c,0x09,0x47,0x8e,0x8e,0xa4,0x39,0x35 +,0x59,0x2e,0x1f,0xc1,0x99,0xad,0x21,0x0b,0x1e,0x97,0x91,0x97,0xad,0x49,0x26,0x16,0x23,0xb8,0x92,0x9b,0x14,0x05,0x10,0x9b,0x8a,0x95,0xb9,0x3e,0x50,0x3b,0x23,0x3a +,0xa2,0x9b,0xca,0x11,0x0c,0x37,0x98,0x91,0xa7,0xf2,0xdd,0x2f,0x27,0x2f,0xa2,0x94,0xe0,0x0f,0x0a,0x2f,0x8e,0x8f,0xbd,0x23,0x31,0x42,0x36,0x37,0xad,0x9b,0xa8,0x20 +,0x0d,0x1c,0xa2,0x8e,0x9e,0x68,0xdf,0x2f,0x1b,0x27,0xac,0x97,0x9e,0x2f,0x0d,0x17,0xa8,0x91,0x98,0x28,0x1a,0x3d,0xbf,0xf6,0x3d,0xb5,0x9f,0x3b,0x15,0x1c,0xa8,0x92 +,0x9c,0xd7,0x28,0x1f,0x31,0x45,0x50,0xa3,0x94,0xb6,0x11,0x11,0xcf,0x94,0x95,0xb3,0x21,0x1f,0x29,0x39,0x63,0xbc,0xad,0xaa,0x30,0x19,0x69,0x9b,0x9a,0xaa,0x35,0x1c +,0x25,0x54,0x4a,0xfa,0xad,0xb8,0x2d,0x16,0x2e,0x94,0x8d,0x9b,0x38,0x19,0x1b,0x3d,0xc0,0xe5,0xb7,0xbc,0x3e,0x1a,0x20,0x9c,0x93,0xa4,0x7c,0x2a,0x20,0x2e,0x47,0x58 +,0xd6,0xb5,0x55,0x22,0x21,0x9f,0x8d,0x9b,0xf9,0x1d,0x1d,0x2c,0xb2,0xbb,0x4e,0x30,0x2d,0x2a,0x26,0xad,0x95,0x96,0xa5,0x31,0x21,0x24,0x30,0x60,0xb1,0xb1,0x37,0x1f +,0x1e,0xba,0x97,0x97,0xac,0x30,0x29,0x33,0x44,0xbe,0xbb,0x49,0x21,0x1d,0x2e,0xb1,0x9e,0x9a,0xa2,0x40,0x22,0x26,0xc6,0xab,0xb6,0x59,0x23,0x1e,0x25,0x5d,0x9c,0x98 +,0x9a,0x48,0x17,0x26,0xc6,0xb4,0xc6,0xd8,0x33,0x27,0x22,0x4a,0x9c,0x95,0x9d,0x32,0x1b,0x2c,0x7c,0xbf,0xba,0x6d,0x31,0x1f,0x27,0xb8,0x9b,0x96,0xa9,0x3a,0x22,0x29 +,0x38,0xaf,0xaa,0x36,0x2b,0x2b,0x3e,0xcd,0xb8,0xa8,0xa7,0xb5,0x3d,0x1f,0x2e,0x56,0xc6,0xd6,0x29,0x3a,0xba,0xbb,0xb9,0xa8,0xa6,0xb8,0x35,0x2f,0x2f,0x2d,0x4b,0x58 +,0xe7,0xbd,0xcf,0x58,0xd4,0xbd,0xa9,0xab,0xdc,0x2b,0x25,0x27,0x2c,0xd0,0xb0,0xbd,0x3b,0x45,0xd0,0xaa,0xa2,0xb5,0xdc,0x42,0x2a,0x2a,0x39,0xec,0xaf,0xb1,0x31,0x2b +,0xf4,0xaf,0x9a,0xa3,0x5e,0x20,0x1f,0x25,0x37,0xc1,0xae,0xac,0x2b,0x1a,0x3c,0x9e,0x97,0x9e,0xdf,0x25,0x1d,0x2b,0xb8,0xae,0xb4,0xcd,0x29,0x22,0x33,0x9d,0x98,0xa9 +,0xbc,0x38,0x28,0x24,0x29,0xac,0x97,0xb2,0x15,0x0e,0x22,0x9d,0x8f,0x95,0xcf,0x1a,0x1b,0x20,0x96,0x88,0xa8,0x0c,0x07,0x17,0x8e,0x88,0x9e,0x20,0x0e,0x0f,0xbb,0x88 +,0x8c,0xac,0x0e,0x02,0x13,0x88,0x86,0xb1,0x13,0x13,0x0f,0x95,0x8a,0x8d,0xb1,0x05,0x02,0x2a,0x83,0x88,0xcb,0x0b,0x0e,0x18,0x8b,0x8a,0x8e,0xcb,0x08,0x01,0x1b,0x81 +,0x87,0x39,0x05,0x0a,0x1c,0x8b,0x82,0x8d,0x2c,0x05,0x04,0x14,0x89,0x80,0xb3,0x07,0x04,0x1f,0xa4,0x86,0x83,0x9e,0x10,0x00,0x0b,0xac,0x80,0x87,0x27,0x03,0x03,0x24 +,0x97,0x83,0x80,0xc9,0x04,0x00,0x18,0x8f,0x84,0x84,0x1b,0x03,0x00,0x22,0x86,0x81,0x81,0x19,0x00,0x01,0x22,0x8c,0x8d,0x88,0xdc,0x05,0x03,0x1d,0x85,0x87,0x84,0xae +,0x03,0x04,0x0c,0x98,0x96,0x89,0x90,0x09,0x04,0x0f,0x86,0x85,0x96,0x97,0x0d,0x07,0x09,0xb4,0x96,0x9d,0x8b,0x1a,0x09,0x16,0x9d,0x8e,0xad,0x8a,0xa1,0x1b,0x04,0x0a +,0xa9,0x99,0x86,0xa7,0x1e,0x0f,0x17,0xde,0x9e,0x81,0x8d,0x16,0x05,0x05,0x01,0x19,0x8b,0x8d,0x1d,0x0d,0x05,0x0c,0x94,0x80,0x81,0xae,0x13,0x0b,0xa7,0x86,0x85,0x83 +,0x90,0x08,0x03,0x2c,0xa9,0x80,0x86,0x1f,0x0a,0x08,0x0f,0xaf,0x85,0x8e,0x06,0x00,0x00,0x0a,0x3d,0xbf,0xaf,0x04,0x06,0x00,0x08,0xa2,0x92,0x8c,0x1a,0x0b,0x0c,0x2c +,0x92,0x8c,0x83,0x8d,0x2f,0x2e,0x98,0x85,0x89,0x89,0x86,0x95,0x87,0x97,0x92,0x80,0x88,0x83,0x99,0xa5,0x84,0xa4,0x1b,0x04,0xa7,0x9f,0x0b,0x2c,0x09,0x03,0x06,0x05 +,0xf1,0xb4,0x0f,0x1b,0x00,0x04,0x06,0x0a,0x34,0x07,0x10,0x0f,0x0d,0x25,0x51,0x8a,0x3d,0x17,0x80,0x8c,0x9d,0x14,0xa6,0x80,0x83,0x80,0x9b,0x97,0xbd,0x84,0x83,0x81 +,0x09,0xb0,0x80,0x1f,0x1a,0x01,0x80,0x96,0x9c,0xb8,0x1d,0x24,0x00,0x18,0x27,0x09,0x04,0x00,0x8b,0x94,0x00,0x01,0x08,0x89,0xac,0x22,0x0e,0x10,0x07,0x07,0x96,0x8e +,0x9c,0x05,0x11,0x80,0x8d,0xc2,0x00,0x4e,0x80,0x81,0x89,0xb5,0x91,0x0c,0xb2,0x83,0x81,0x86,0x0a,0x31,0x80,0x8e,0x25,0x00,0x9a,0x87,0xa8,0x33,0x1d,0x13,0x02,0x0d +,0x27,0x6a,0x0b,0x00,0x09,0x80,0xbc,0x0b,0x00,0x0d,0xa6,0x50,0x90,0x0e,0x1d,0x08,0x0f,0x8b,0x90,0x98,0x00,0xdd,0x80,0x8e,0xca,0x02,0x89,0x81,0x80,0x93,0x97,0x85 +,0x3e,0xb1,0x87,0x8a,0x1e,0x00,0xa7,0x80,0x97,0x0e,0x00,0xab,0xa2,0x98,0x90,0x32,0x12,0x03,0x0a,0xb8,0x19,0x03,0x08,0x84,0x92,0x01,0x00,0x05,0x89,0x86,0xb9,0x0f +,0x0a,0x04,0x06,0x93,0x83,0x8a,0x04,0x27,0x80,0x8c,0xab,0x02,0x88,0x87,0x98,0x0b,0x50,0x80,0xa2,0xa1,0x45,0xbb,0x15,0x95,0x80,0x89,0xa6,0x03,0x14,0x97,0x8a,0x8a +,0x2f,0x1c,0x07,0x01,0x08,0x14,0x1b,0x02,0x87,0xbb,0x01,0x02,0x02,0x8f,0x8a,0x28,0x00,0x1d,0x4e,0x1f,0x16,0x22,0x0f,0xcc,0x80,0x8f,0xb3,0x03,0xbc,0x8a,0x8d,0xae +,0xa7,0x85,0x8f,0xb9,0x48,0x94,0x98,0x80,0x86,0x99,0x0c,0x07,0x4f,0x9b,0x82,0x8a,0x3a,0x03,0x0e,0xaa,0x88,0xa0,0x85,0x15,0x02,0x08,0x2f,0xcb,0x1c,0xd1,0x00,0x0f +,0x07,0x66,0x1b,0x1e,0x09,0x1c,0xbd,0x11,0x0a,0x14,0x9a,0x10,0x1d,0x31,0x9a,0x89,0x93,0xa3,0x49,0x0a,0x88,0x81,0x80,0xaa,0xbc,0x9c,0x24,0x89,0x83,0x86,0xd8,0x4d +,0xa0,0xd3,0x3b,0x87,0x8d,0xa3,0x0f,0x26,0x10,0x28,0xb2,0xa9,0xbd,0x06,0x10,0x07,0x16,0x00,0xcc,0x8f,0x9b,0x07,0x03,0x0f,0x0b,0x35,0x2b,0x9b,0xfa,0x17,0x07,0x12 +,0x09,0x8e,0x94,0x93,0xa7,0x1a,0x3c,0x15,0x8d,0x8d,0x81,0x89,0x9f,0x17,0x07,0xd9,0x86,0x80,0x85,0x37,0x0e,0x19,0x47,0x9b,0x82,0x82,0x45,0x15,0x00,0xb7,0x97,0x8d +,0x94,0xc8,0xb5,0x05,0x0d,0x07,0xb3,0xaa,0x21,0x0b,0x04,0x06,0x14,0x0f,0x07,0x1f,0x1a,0x24,0x0e,0x1d,0x09,0x37,0x9d,0x8d,0xa7,0x2c,0xb1,0x64,0x9e,0x26,0x8c,0x80 +,0x82,0x99,0x5b,0x1d,0x9d,0x88,0x82,0x9d,0xf3,0x3a,0xce,0x2e,0x31,0x88,0x88,0x90,0x06,0x1b,0x29,0xa6,0xa5,0x4a,0x09,0x27,0xd4,0x1d,0x15,0x06,0xd9,0xb2,0x92,0x13 +,0x49,0x20,0x0e,0x1b,0x05,0x26,0x2b,0xc5,0x0d,0x0d,0x05,0x0a,0x94,0x87,0x8f,0x1f,0x3b,0x19,0x09,0x23,0x89,0x89,0x8a,0x1e,0x1a,0x2b,0xca,0x84,0x82,0x80,0x91,0xed +,0x16,0x25,0x8c,0x82,0x87,0x90,0x2e,0x12,0x21,0x17,0xdf,0x88,0x85,0xa3,0x07,0x00,0x11,0xad,0x1e,0x1c,0x0c,0x1d,0x0a,0x11,0x07,0x06,0xb2,0x8e,0x8e,0x06,0x03,0x07 +,0xd7,0x3f,0x2d,0x93,0xa4,0x33,0x48,0xa0,0x4c,0x9d,0x87,0x86,0x9c,0x3f,0x9f,0x88,0x99,0xbc,0x87,0x8c,0x9b,0x24,0xab,0xc6,0xb2,0x8d,0x9f,0xb8,0x2b,0x28,0x11,0x15 +,0x32,0xa3,0xbc,0xa2,0x28,0x11,0xeb,0x22,0x04,0x39,0x84,0x95,0x14,0x09,0x05,0x1d,0x34,0xa9,0xaf,0xcd,0x1f,0x0a,0x0c,0x00,0x3b,0x84,0x81,0x1e,0x04,0x04,0x14,0x98 +,0x85,0x87,0x8a,0x29,0x1e,0x2b,0x07,0x8c,0x83,0x80,0xa0,0x0a,0x1c,0xa7,0x8b,0x98,0x89,0x82,0x8d,0x0f,0x09,0x16,0xc8,0x86,0x8b,0xb9,0x1b,0x06,0x0d,0x2d,0x1e,0x1f +,0xd5,0xa4,0x07,0x07,0x0b,0x0f,0x0e,0x39,0xa3,0xaa,0xac,0x0e,0x07,0x10,0xa3,0x8c,0x8f,0x0d,0x17,0x27,0xb1,0xcf,0x1b,0x88,0x84,0x84,0x1f,0x26,0x9b,0x91,0x89,0x8f +,0x99,0x90,0x55,0x14,0x2b,0x1f,0x87,0x81,0x8d,0x15,0x0d,0x1b,0xba,0x1d,0x24,0x9e,0x9f,0x38,0x00,0x02,0x0e,0xa9,0x87,0x8e,0x27,0x0f,0x04,0x05,0x13,0x6a,0x89,0x95 +,0x07,0x00,0x09,0x37,0xfc,0x8f,0x88,0x96,0xd1,0x18,0x03,0x1f,0x89,0x86,0x88,0xe1,0x0b,0x1a,0x93,0x94,0x8c,0x8c,0x87,0x9d,0x13,0x0e,0x9f,0x8d,0x8d,0x24,0x21,0xa5 +,0x24,0x9d,0x2e,0x10,0xac,0x8a,0xa7,0x1a,0x01,0x28,0x9e,0x13,0x1c,0x25,0xb7,0x4b,0x20,0x0d,0x16,0x2e,0x91,0x8f,0xb2,0x1c,0x0e,0x32,0x07,0x1e,0x93,0x87,0xfd,0x0a +,0x09,0x0b,0x2f,0x93,0x8f,0x89,0x9a,0x0a,0x0b,0x08,0x9a,0x81,0x84,0x87,0x38,0x15,0x2e,0x98,0x8c,0x89,0x83,0x85,0x32,0x02,0x18,0x4d,0x88,0x8e,0xd5,0xb8,0x0c,0x07 +,0x07,0x0d,0xa8,0x83,0xaf,0x07,0x00,0x07,0x1c,0xdc,0x8d,0x2b,0x12,0x27,0x06,0x11,0x41,0x95,0x85,0x8c,0x42,0x0d,0xd0,0x93,0x8f,0x8d,0xa5,0x96,0x33,0x17,0xc8,0xac +,0x95,0xcc,0xb6,0xa9,0x8f,0xba,0x5e,0x27,0x27,0xb0,0xae,0x8f,0x14,0x0f,0x1b,0x32,0x0e,0x46,0x8c,0x8d,0x31,0x11,0x20,0x17,0x96,0xa0,0x47,0xb9,0xd2,0x2c,0x0c,0x02 +,0xa5,0x81,0x84,0x9a,0x06,0x07,0x1c,0xca,0x90,0x95,0xa7,0x1b,0x06,0x0b,0x0b,0x27,0x8a,0x82,0x92,0x07,0x0b,0x13,0x27,0x9f,0x91,0x84,0xa9,0x08,0x04,0x3e,0x92,0x82 +,0x82,0x8b,0x1d,0x12,0x2a,0x2f,0x8d,0x82,0x9b,0x6d,0x17,0x08,0x2e,0x4c,0xb5,0x8b,0xa8,0x1b,0x06,0x05,0x18,0x9b,0x91,0x3d,0x1a,0x04,0x10,0x23,0x95,0x68,0x4f,0x90 +,0x91,0x29,0x12,0x20,0x6b,0x91,0xa9,0x9a,0xa5,0x4e,0x15,0x33,0x29,0x99,0x84,0x8d,0x26,0x0e,0xbb,0x2f,0xca,0xd2,0xb5,0x99,0x8e,0xb1,0x0f,0x0a,0x1d,0x83,0x8d,0xb3 +,0x15,0x18,0x28,0x0c,0x1b,0x9d,0x94,0x9d,0x2b,0x0d,0x1d,0x12,0x99,0x8b,0x89,0xa2,0x1c,0x0a,0x01,0x20,0x96,0x80,0x93,0x10,0x05,0x0f,0x24,0x8d,0x86,0x88,0xaa,0x11 +,0x07,0x0a,0x60,0xab,0x86,0x8c,0x38,0x05,0x0d,0x09,0xc1,0x80,0x80,0x99,0x04,0x00,0x15,0x8d,0x86,0x8a,0xc3,0x1b,0x15,0x16,0x0e,0xae,0x85,0x80,0x9d,0x05,0x0b,0x23 +,0xca,0x9a,0x88,0x8f,0x28,0x08,0x07,0x12,0x9c,0x86,0x8e,0x24,0x04,0x19,0x3e,0xd0,0x78,0xca,0x99,0xb2,0x11,0x0d,0x28,0x3f,0x91,0x95,0xdc,0x10,0x27,0xa3,0xb9,0xb4 +,0xc7,0x9a,0xc0,0x22,0x49,0x90,0x99,0xc1,0xbf,0xa3,0xae,0x9f,0xa1,0x18,0x23,0xaf,0x97,0xb9,0x1f,0xbb,0xb7,0x1e,0xcf,0x9c,0x96,0x4e,0x38,0x3c,0x1b,0x1c,0x20,0xbc +,0xa3,0xa3,0x39,0x19,0x08,0xb3,0x8c,0x8a,0xb7,0x13,0x14,0x10,0x39,0x1f,0xa3,0x96,0x97,0x16,0x05,0x0d,0x9f,0x84,0x8c,0x50,0x16,0x1d,0x12,0x1f,0x1e,0x9b,0x89,0x99 +,0x17,0x06,0x0c,0x8f,0x80,0x89,0x1c,0x0a,0x3e,0x1b,0x2d,0xa2,0x8e,0x90,0x2a,0x0c,0x0b,0x23,0x87,0x85,0x8f,0x17,0x05,0x25,0x21,0xbf,0x9f,0x8e,0xb4,0x0e,0x0a,0x21 +,0xc4,0x90,0x89,0xa1,0xcf,0x0a,0x14,0x1b,0xa7,0x97,0x95,0xb8,0x11,0x0e,0x1c,0xb6,0x9c,0x8e,0x9d,0x2b,0x08,0x3b,0xf7,0xa4,0xa2,0x52,0xc4,0x2d,0xbf,0x43,0x3d,0xb5 +,0x8d,0x8c,0x23,0x0b,0x29,0x38,0xa1,0x52,0x1b,0xa8,0x98,0xad,0x2d,0x13,0xb2,0x89,0x96,0x2f,0x14,0xbd,0x1d,0x1e,0x21,0xb1,0x9b,0xa1,0x49,0x0c,0x17,0x97,0x84,0x95 +,0x2a,0x0f,0xa9,0x1d,0x11,0x13,0xa7,0x8a,0x9d,0x27,0x0b,0x1e,0x8f,0x8a,0xa2,0x41,0x27,0x9a,0x0d,0x14,0x3f,0x9d,0x8e,0x3f,0x28,0x0f,0x0d,0xa8,0x8b,0x8e,0x42,0x19 +,0xa5,0x2d,0x41,0x22,0xac,0xac,0x28,0x1f,0x13,0x1a,0x94,0x84,0x95,0x1e,0x14,0xa1,0x38,0x1b,0x17,0xa2,0xa8,0x2e,0x30,0x14,0x14,0x8d,0x89,0x9c,0x0f,0x0c,0x99,0x4c +,0x29,0x1b,0x9c,0x8c,0x9e,0x2d,0x18,0x10,0x97,0x8b,0x9b,0x11,0x10,0x92,0xa7,0xba,0x0e,0x2b,0x9f,0xa9,0x50,0x1f,0x1e,0x9b,0x99,0x8e,0x43,0x1d,0xa8,0x25,0x28,0x0d +,0xb7,0x94,0xae,0x16,0x08,0x35,0x84,0x8e,0xa5,0x0d,0x10,0xae,0x3b,0xbb,0x1b,0x9c,0x92,0xae,0x28,0x0b,0x11,0x90,0x86,0x8e,0x0d,0x0d,0xc7,0xbf,0x99,0x28,0xa9,0x9c +,0x53,0x0d,0x09,0x26,0x89,0x89,0x8f,0x1d,0x19,0xb9,0x17,0x40,0x28,0x9e,0x9b,0x27,0x1b,0x07,0x18,0x85,0x84,0x91,0x10,0x13,0x21,0x12,0xdc,0xa8,0x8d,0x93,0x1f,0x0e +,0x04,0x1c,0x83,0x8e,0x97,0x14,0x33,0x34,0x0e,0x9a,0xa8,0x8c,0x99,0x21,0x0d,0x00,0x16,0x86,0x82,0x91,0x18,0x1d,0xb9,0x39,0x48,0x26,0x97,0xa0,0x22,0x14,0x06,0x1d +,0x88,0x87,0x8c,0x15,0x1c,0x2b,0x0c,0x32,0x57,0x8d,0x98,0x2b,0x28,0x13,0x1e,0x8c,0x90,0xa3,0x0f,0x25,0x99,0x1f,0x22,0x23,0x8f,0x93,0x25,0x2d,0x0c,0x0b,0x9b,0x89 +,0x89,0x12,0x1a,0x95,0x3f,0xc2,0x1c,0xb4,0x99,0x27,0xc8,0x12,0x0c,0x9b,0x91,0x86,0x1e,0x17,0x96,0x3f,0x31,0x0b,0xd9,0x8f,0x1c,0x2e,0x2e,0x16,0x9e,0xc0,0x8d,0x9a +,0x23,0x9d,0x16,0x0f,0x0a,0x38,0x86,0x99,0xe5,0x15,0x09,0x94,0x8e,0x8a,0xb8,0x0b,0x9c,0x2f,0x7c,0x2f,0x29,0x96,0xa4,0xad,0x2e,0x05,0xd5,0x99,0x92,0x92,0x0f,0x9f +,0xb5,0xe7,0x13,0x06,0x98,0x98,0x35,0x1e,0x06,0xe3,0x94,0x93,0x90,0x1d,0xa5,0x23,0x17,0x2d,0x0e,0xc1,0x8b,0xa3,0x67,0x08,0x1c,0x8b,0x98,0x89,0x11,0x17,0xa3,0x28 +,0xb2,0x1d,0xc1,0x95,0x4a,0xb6,0x0d,0x0d,0x91,0xa9,0x8c,0x9e,0x1d,0xaa,0x42,0xa5,0x13,0x0d,0x95,0xaa,0xaf,0x12,0x08,0x8c,0x8f,0x93,0xaf,0x12,0x9c,0x2c,0x25,0x1d +,0x09,0xa8,0x92,0x9c,0xdc,0x08,0x2c,0x94,0x9b,0x9d,0x11,0x37,0xa8,0x3a,0xaf,0x16,0x48,0x91,0xa9,0x67,0x0d,0x12,0xa0,0xae,0x8f,0x9b,0x1f,0xa6,0xb7,0xb3,0x2a,0x15 +,0xa0,0x91,0x20,0x13,0x1a,0xa7,0x8f,0xaf,0xa0,0x27,0x18,0x4e,0x46,0x2c,0x2f,0x57,0x9e,0x54,0x32,0xa7,0x63,0xea,0x3a,0x41,0x54,0x17,0x2d,0x99,0x9f,0xc3,0x21,0x41 +,0x9a,0xbb,0x41,0x7e,0x1a,0x27,0xc7,0x9b,0x9e,0x57,0xae,0x2b,0x1c,0x23,0xae,0xa3,0x2b,0x1f,0xb0,0x99,0xa7,0xe9,0x27,0x3d,0x5a,0xac,0xad,0x35,0x25,0x20,0xa8,0xa6 +,0xd3,0x9b,0xab,0x30,0x19,0x28,0xaa,0xc8,0xb9,0xaf,0x4a,0x1c,0x32,0xc0,0xc1,0x2a,0x27,0x4a,0x25,0x5e,0x77,0x9a,0xba,0x2b,0xa5,0xac,0x3d,0x26,0xb2,0x3c,0x19,0xc2 +,0x8f,0xb4,0x2f,0x63,0xc7,0xa0,0xd4,0xab,0xab,0x24,0x26,0x3c,0x9b,0xab,0x45,0xae,0x22,0x19,0x25,0xd7,0xa5,0xc1,0x2e,0x52,0x54,0xc7,0xda,0xae,0xbd,0x19,0x3a,0xaf +,0xd9,0x1e,0x3b,0xb5,0x31,0x2e,0x9e,0x9c,0xd1,0x29,0x1b,0x2d,0x2d,0x9c,0x8c,0x9f,0x1f,0x17,0x1e,0xc1,0xa6,0x9d,0xac,0x1c,0x10,0x53,0x8d,0xad,0xc4,0xb2,0x64,0x1c +,0x27,0x9b,0xa5,0x36,0x2f,0xb5,0xe8,0xf5,0xad,0xbf,0x25,0x17,0xc0,0x95,0xba,0x1c,0x27,0x49,0xba,0xaa,0xa3,0xa5,0x28,0x21,0x25,0x36,0x25,0xbe,0x96,0xd4,0x1c,0x29 +,0xda,0x24,0xa2,0x8f,0xa6,0x17,0x16,0xa9,0x93,0xae,0x3a,0xcd,0x3b,0x1d,0x25,0xa3,0x55,0x3e,0xbb,0x97,0xa3,0x2d,0x2b,0x35,0x4a,0x29,0x9b,0xb1,0x23,0x24,0x2c,0x37 +,0xb6,0xa5,0x9d,0x50,0x17,0x1b,0xb5,0xa4,0x29,0xae,0xb1,0xc9,0x39,0xaa,0xac,0x56,0x32,0xb6,0xd3,0x1b,0x38,0x9f,0x99,0x2c,0x2b,0x2c,0x3d,0x4e,0xb3,0xbb,0x4e,0x5b +,0x7a,0x9c,0xd4,0x23,0x6a,0x57,0x28,0x44,0xa2,0xba,0x26,0x2e,0xaf,0xb8,0xad,0xa6,0x3e,0x21,0x10,0xa9,0x8d,0xa7,0x21,0x1c,0xcf,0x3f,0xc6,0xa2,0xbb,0x19,0x1f,0xbf +,0xab,0xbf,0xdf,0xa5,0xaa,0x1f,0x1c,0xb7,0xb7,0xa7,0xaf,0x33,0x17,0x30,0x98,0x9e,0x2b,0x17,0xca,0xb0,0xc5,0x4f,0xbd,0xbc,0x3d,0x60,0xbe,0xb2,0xb3,0x5a,0x41,0x1c +,0x1b,0x9e,0x95,0xa9,0x1f,0x25,0x2b,0xb5,0x98,0xa8,0x29,0x13,0x1e,0xa5,0x96,0xb3,0x6a,0xbd,0x6c,0x25,0xcb,0xae,0xcb,0x28,0x33,0x41,0x3d,0xb0,0xa7,0x58,0x1a,0x2b +,0xac,0x99,0xc5,0x2d,0x2e,0x24,0x29,0xb6,0x9e,0xad,0x2d,0x25,0x2a,0x16,0x44,0x8f,0x91,0xb3,0x1c,0x19,0x47,0x9c,0x96,0xb1,0x21,0x1e,0xb7,0xab,0xb7,0xc6,0xdf,0xa6 +,0xa8,0x43,0x39,0x2a,0x27,0x38,0x49,0xae,0xa5,0x71,0x27,0x2b,0x4c,0xca,0x9f,0x97,0x45,0x16,0x16,0x28,0xa9,0x9e,0xb6,0x1e,0x1a,0x28,0xc2,0x9e,0xa4,0xa6,0xa9,0xcc +,0x21,0x4e,0xbd,0x3d,0xb9,0xd7,0x28,0x1f,0x3a,0xa9,0xc9,0xbe,0xb4,0x65,0xa4,0x71,0x21,0x1c,0x2a,0xc4,0x9d,0x94,0xba,0x28,0x1d,0x26,0xa7,0x92,0x9a,0x72,0x1e,0x1e +,0x1e,0x35,0x9a,0x9c,0xc3,0x2b,0x1c,0x41,0xb2,0xc2,0xeb,0x3c,0xbb,0x61,0x37,0x56,0x26,0x40,0x40,0xca,0xa6,0xc6,0xd8,0xe0,0xb8,0xa7,0x2f,0x3e,0xa3,0xce,0x26,0x17 +,0x23,0xb3,0x91,0x99,0x2b,0x1f,0x4a,0xee,0xb0,0x9f,0xcb,0x30,0x14,0x1e,0x6f,0xc9,0xa1,0xa0,0xa9,0x1a,0x1f,0xb8,0xab,0x9e,0x3f,0x23,0x2c,0xf0,0xbb,0x3a,0xeb,0xd1 +,0xc2,0xa3,0xad,0xd1,0xc7,0x56,0x51,0xc5,0x27,0xed,0xac,0x23,0x19,0x22,0x54,0x97,0x8d,0xa1,0x2b,0x0f,0x1e,0xb3,0xb3,0xac,0x54,0x3b,0x2b,0x2a,0x9e,0xa0,0xd4,0xcd +,0xdd,0xd8,0x30,0x5e,0xbf,0x2d,0x2e,0x24,0xe5,0x99,0x9e,0xba,0x1b,0x1e,0xa4,0xaa,0xa0,0xc7,0x24,0x20,0x2c,0xa5,0xbe,0x2f,0x25,0x32,0xc4,0xb3,0x73,0xd6,0xa4,0xac +,0x2c,0x1b,0x2b,0xa3,0x97,0xdd,0x1a,0x25,0xad,0x9f,0xc7,0xbb,0xa6,0x3e,0xe4,0x2b,0x29,0xb8,0xb4,0x56,0x30,0x1f,0x28,0xa8,0xa0,0xad,0x2b,0x3a,0xc4,0x9c,0xba,0x1d +,0x1a,0x54,0x9a,0xa0,0xbb,0x27,0x33,0x5e,0xb8,0x36,0x36,0x41,0x33,0x2f,0xd4,0xae,0xc4,0xc7,0x59,0xe6,0x42,0xae,0xa7,0xa6,0x2b,0x1c,0x2e,0x3f,0xbe,0x52,0x3a,0x2d +,0x57,0x54,0xe9,0xa1,0xa9,0xc8,0xbe,0xf1,0x53,0x29,0x54,0xa3,0xab,0x24,0x2a,0xa1,0x9e,0xa1,0x25,0x20,0xce,0xc4,0xae,0x3d,0x13,0x1c,0x52,0xa4,0xa2,0x9c,0xb2,0x21 +,0x2b,0xc5,0xb3,0xd1,0xa7,0xc0,0x2a,0x1b,0x20,0xc3,0x9d,0xd9,0x22,0x4d,0xc0,0xc3,0xbe,0xac,0xb5,0x49,0x29,0x37,0x2f,0xbe,0xa2,0xa7,0xce,0x18,0x42,0xae,0xa6,0xbd +,0x1e,0x2b,0xd1,0x6f,0x26,0x2f,0x2d,0xba,0xb3,0xb7,0x9c,0xa1,0xf4,0xc7,0x5d,0xbf,0xa3,0xfd,0x23,0x1d,0x2f,0x3b,0xc8,0xba,0x98,0xaf,0x21,0x3c,0xb4,0xb5,0xeb,0x4b +,0x2f,0x25,0x24,0xb9,0x4e,0x51,0x9e,0xa9,0x49,0x31,0xcc,0xb4,0x47,0x30,0x30,0x3f,0x2d,0x3f,0x2e,0x49,0xb9,0xb1,0xaa,0xa9,0xae,0x37,0x49,0xbd,0xa2,0x4f,0x22,0x41 +,0xc7,0x51,0xc8,0x78,0x3d,0xc6,0xa8,0x4e,0x1a,0x26,0x45,0xab,0xc3,0x45,0x30,0xc1,0xa5,0xc7,0xd5,0xbe,0xbe,0xbd,0xac,0x4c,0x3b,0x29,0x1c,0x25,0xb9,0x9a,0xa6,0x21 +,0x26,0xb4,0xa8,0x98,0xb6,0x5e,0x28,0x25,0x66,0x27,0x28,0x26,0xaa,0xaf,0xd6,0xbd,0x4a,0xae,0xce,0xb9,0xa6,0xee,0x2f,0x39,0x5e,0xbf,0x39,0x3d,0xaa,0xbf,0x29,0x2c +,0x3c,0xbe,0xa5,0xa0,0xaf,0x1c,0x19,0x2a,0xbe,0xa5,0x9f,0xb4,0x29,0x22,0x31,0xa7,0x9b,0xb9,0x30,0x29,0x1a,0x18,0x38,0x9d,0x9b,0xb1,0xa9,0xa9,0x37,0x36,0xc8,0x9f +,0xc6,0x1e,0x3a,0x46,0x1c,0x61,0xa2,0xc2,0x2c,0x2f,0x40,0xa7,0xa8,0xc4,0xa6,0x3a,0xbb,0xa1,0xb0,0x15,0x0b,0x0f,0x91,0x8d,0x29,0x2e,0x2a,0xa0,0x93,0xdd,0x2a,0xc6 +,0x3e,0xbb,0x21,0xe7,0x91,0x36,0x0e,0x04,0x9c,0x80,0x23,0x0f,0x24,0xad,0x92,0x0a,0x05,0x27,0x9d,0x8f,0x10,0x0e,0xb9,0xa9,0x92,0x36,0xab,0x80,0xd3,0x17,0xdf,0x96 +,0x80,0x26,0x10,0x20,0x15,0xe5,0x00,0x18,0x8b,0x92,0xb1,0x05,0x03,0x8e,0x93,0x98,0x8d,0xcd,0x84,0x0d,0x17,0x9e,0x99,0x85,0x0b,0x0b,0x1e,0x18,0x1e,0x04,0x08,0x89 +,0x8b,0x8e,0xbc,0x0f,0xa2,0x16,0x8f,0x83,0x97,0x8a,0x2a,0x42,0xa4,0x29,0x19,0x06,0x06,0x75,0x1d,0x06,0x0c,0x23,0x84,0x97,0x98,0x94,0xc2,0xa9,0x18,0x8a,0x81,0x99 +,0x26,0x06,0x14,0x8e,0x8c,0x23,0x13,0x0e,0x39,0x1c,0x07,0x2e,0xe2,0x8d,0x96,0xac,0xa1,0x0d,0x07,0x07,0x3e,0x83,0x82,0x91,0x32,0x19,0x99,0x9d,0x24,0x9f,0x23,0x23 +,0x19,0x17,0xa6,0x2a,0xb6,0x57,0x1c,0x1d,0x25,0x17,0xa3,0x8a,0x85,0xa8,0x09,0x2d,0x42,0xaa,0x10,0xac,0x80,0x9a,0x1a,0x04,0x08,0x1d,0x28,0x1e,0x91,0x8d,0x93,0x1c +,0x07,0x93,0x86,0x83,0x37,0x20,0x8a,0x92,0x32,0x05,0x09,0x38,0x1d,0x05,0x09,0x15,0x9a,0xa6,0x96,0x85,0x8d,0x7d,0x04,0x2e,0x96,0x94,0x97,0x59,0x9c,0x88,0xc2,0x22 +,0x15,0x45,0x90,0x19,0x18,0x2a,0x2f,0x11,0x04,0x36,0x8f,0xc6,0x07,0x0b,0x9c,0x90,0x91,0x8a,0x8a,0x8c,0x31,0x12,0x1c,0xb7,0x9c,0x29,0x34,0x2e,0x14,0x0b,0x09,0x9f +,0x8a,0x94,0xd8,0x29,0xa5,0x52,0x20,0x9e,0x96,0x9f,0xfd,0xa5,0xb8,0x17,0x0e,0x1b,0x88,0x8f,0x0f,0x08,0x23,0x93,0x4b,0x2d,0x8e,0x92,0xb9,0x0e,0x2f,0x97,0x8e,0x9f +,0x31,0x9b,0x27,0x1b,0x1f,0xc4,0xab,0x1f,0xca,0x3a,0x59,0x1b,0x0c,0x27,0xb6,0xb9,0x2a,0x9d,0x90,0x22,0x46,0x8e,0x82,0x84,0xa6,0x9c,0x9d,0x96,0xaf,0x9d,0x8d,0x1e +,0x08,0x09,0x3d,0xc1,0xba,0xa7,0x94,0xd6,0x05,0x02,0x05,0x61,0x33,0x19,0x2e,0x0f,0x04,0x04,0x20,0x20,0x06,0x05,0x0d,0x27,0x15,0x08,0x05,0x0b,0x18,0x21,0x96,0xb7 +,0x2d,0x1d,0x93,0x81,0x8a,0x8c,0xb0,0x8b,0x9c,0x1e,0xae,0x8c,0x80,0x90,0xc7,0xaf,0x53,0xa9,0xa5,0x8b,0x81,0x83,0x83,0x8b,0x91,0xb3,0xb6,0x96,0x8c,0x8f,0xb5,0x98 +,0xa7,0x1e,0x11,0x40,0x8e,0x40,0x0c,0x08,0x1f,0xba,0xab,0x87,0x8b,0x35,0x05,0x09,0xc8,0xb7,0x50,0x1a,0xcf,0xd0,0x0d,0x11,0x2e,0xaf,0x1a,0x0c,0x0f,0x0b,0x10,0x0f +,0x1f,0x20,0x0e,0x0d,0x16,0xf1,0x16,0x12,0xce,0x8c,0x87,0xab,0x29,0x31,0xc3,0x27,0x18,0x3c,0x38,0x18,0x07,0x10,0xe1,0x5f,0x8c,0x83,0x84,0xbc,0x0a,0x24,0x9c,0x8c +,0xcc,0x9b,0x89,0x9c,0x33,0x1f,0x8f,0x8a,0x9e,0xad,0xa8,0x9a,0xaf,0x2b,0x55,0x9f,0x8f,0x9d,0x9a,0xdd,0x0e,0x0d,0xf5,0x81,0x89,0xc6,0x0f,0x17,0x2c,0x0a,0x09,0x14 +,0x20,0x11,0x00,0x0f,0x18,0x26,0x40,0xa4,0x81,0x8c,0x9b,0x9d,0x8a,0x81,0x9b,0x99,0x86,0x81,0x82,0x8a,0x89,0x92,0xb3,0xf7,0xad,0x8c,0xaa,0x1d,0x2a,0x98,0x89,0xc9 +,0x14,0x0a,0x04,0x03,0x07,0x31,0x6d,0x12,0x02,0x01,0x0d,0x04,0x02,0x00,0x0d,0x40,0x0c,0x0b,0x07,0x0e,0x0d,0x0a,0x20,0x13,0x09,0x03,0x1e,0x8b,0x99,0xd3,0xba,0x90 +,0x88,0x25,0x1d,0x96,0x85,0x8b,0xb6,0xa7,0xc3,0x2a,0x27,0x92,0x80,0x84,0x8e,0xcd,0x92,0x82,0x8b,0x8a,0x8a,0x88,0x93,0x9a,0x85,0x8a,0xab,0x10,0x10,0x97,0xb9,0x1e +,0x29,0xa7,0x90,0x56,0x9f,0x97,0xa4,0xce,0x2b,0x94,0x99,0x29,0x1e,0x22,0x9a,0x33,0x05,0x0e,0x15,0x47,0x0d,0x0b,0x1e,0x10,0x12,0x0e,0x62,0x2f,0x0f,0x0e,0x08,0x33 +,0x2d,0x18,0x20,0x31,0x8f,0x58,0x2e,0x5a,0x0f,0x08,0x0a,0xb2,0x45,0x08,0x05,0x07,0xa2,0x86,0x9c,0xa9,0x1d,0xa4,0xab,0x30,0x94,0xa5,0x9d,0x41,0xb3,0x95,0x26,0x1e +,0x24,0x94,0x85,0x9a,0xac,0x26,0xa3,0x92,0xa6,0x90,0x97,0xa8,0x1c,0x28,0x97,0xd3,0x1c,0x2d,0xb6,0x98,0x1f,0x0d,0x12,0xb0,0x9a,0x0d,0x0c,0x05,0x14,0xaa,0x8f,0x80 +,0x86,0x93,0x37,0x42,0x87,0x82,0x87,0x8b,0x8b,0x80,0x86,0x85,0x84,0x88,0x8a,0x51,0xc4,0x9d,0x15,0x0f,0x0f,0x43,0xa9,0x15,0x0d,0x05,0x13,0x10,0x03,0x0e,0x16,0x1f +,0x14,0x0f,0x09,0x00,0x01,0x00,0x02,0x08,0x06,0x02,0x03,0x27,0x93,0x21,0x0f,0x12,0x46,0xaa,0x26,0xbf,0x1e,0x11,0x29,0x9d,0x80,0x8f,0x3d,0x21,0xa7,0x84,0x8e,0x9c +,0xa6,0xa5,0x8d,0x8d,0x84,0x84,0x99,0xa0,0xb1,0x8c,0x83,0x8b,0x92,0x98,0x86,0x8b,0xe8,0xdc,0xb6,0x94,0xa7,0xc9,0x6e,0x16,0x15,0x19,0x96,0x85,0xb1,0x17,0x26,0xa8 +,0xa9,0x1d,0x2e,0x6d,0x9f,0x8f,0xa5,0x47,0x0b,0x0c,0x13,0x0f,0x20,0x0e,0x03,0x05,0x0e,0x93,0xa0,0x0e,0x0e,0x0c,0x18,0x17,0x43,0xc2,0x15,0x18,0x1e,0xb0,0x9b,0x10 +,0x08,0x1c,0xaa,0xbc,0x13,0x17,0x1c,0xae,0x99,0x3d,0x27,0x22,0x3e,0xb7,0xb0,0x8f,0xa1,0xb5,0x99,0x8d,0x81,0xa4,0x18,0xb9,0x8b,0x8c,0x48,0x3f,0xb4,0x76,0xa2,0x97 +,0x93,0xce,0x0e,0x6d,0x90,0x87,0x96,0x2d,0xc0,0x2d,0xac,0x9f,0x70,0x1a,0x04,0x0b,0x0b,0x18,0x5c,0x0c,0x08,0x1b,0x96,0x8b,0x95,0x8a,0x86,0x83,0x82,0x87,0x83,0x8c +,0x97,0x8b,0x8d,0x8f,0xcb,0xb7,0x8d,0x8d,0x8a,0x9d,0x2a,0x29,0x22,0x1b,0x16,0x11,0x0b,0x09,0x10,0x0a,0x01,0x04,0x03,0x08,0x11,0x2d,0x19,0x01,0x02,0x0e,0x26,0x18 +,0x0a,0x0a,0x04,0x02,0x0b,0x23,0x47,0x10,0x0b,0x3d,0x9e,0x88,0x8e,0xb0,0xba,0xa0,0x91,0xbb,0xbc,0x92,0x89,0x86,0x8f,0x9e,0x9f,0xa4,0x99,0x93,0x86,0x92,0x29,0x90 +,0x82,0x81,0x86,0x8b,0x8a,0x8f,0x96,0xba,0xde,0xbc,0x2a,0xad,0x92,0x97,0xbc,0x10,0x0e,0x1e,0xab,0x90,0xb1,0x23,0xe5,0xb0,0x93,0xa3,0x2e,0x30,0x1a,0x1e,0x26,0xd8 +,0x1e,0x09,0x1f,0xaf,0xd9,0x1b,0x0e,0x0e,0x04,0x07,0x0a,0x03,0x0a,0x21,0xb8,0xac,0xaf,0xbb,0x22,0x2c,0xdb,0x2a,0x17,0x0d,0x16,0x2f,0xeb,0x29,0x13,0x1f,0x1c,0x0d +,0x22,0xb4,0x98,0xad,0xd5,0x8e,0x88,0x88,0xc7,0x2b,0xa2,0x6e,0xa3,0xb5,0x2e,0xc6,0x96,0x86,0x86,0x86,0x98,0x37,0x3f,0xb0,0x96,0x94,0xd7,0xb5,0xb8,0x99,0x9a,0xbb +,0xa4,0x25,0x0c,0x11,0x36,0x2f,0x1a,0x3c,0x93,0x94,0xa8,0x16,0x0f,0x1e,0x32,0xa9,0x2c,0xbc,0x92,0x8b,0x81,0x82,0x81,0x82,0x8c,0x8b,0x88,0x8b,0x9f,0xac,0x8c,0x8f +,0x8a,0xaf,0x06,0x05,0x03,0x08,0x10,0x1b,0x0b,0x02,0x0c,0x42,0x2d,0x13,0x0e,0x11,0x0c,0x00,0x02,0x00,0x07,0x0a,0x08,0x0f,0x0f,0x15,0x0b,0x04,0x12,0x5c,0x2b,0x0e +,0x2e,0x92,0x89,0x8d,0xa6,0xab,0xc4,0x4c,0xb7,0xe5,0xb4,0x9f,0x9a,0x8a,0x85,0x8d,0x9d,0x93,0x8f,0x94,0x96,0xa6,0xb8,0x93,0x87,0x83,0x82,0x85,0x91,0xae,0xa7,0xa3 +,0xa4,0xaa,0xb4,0xa8,0x8e,0x95,0x40,0x21,0x22,0x1e,0x28,0x3b,0x29,0x3e,0xbb,0x9d,0x8f,0x9b,0x45,0x42,0x4e,0x53,0x25,0x10,0x07,0x0b,0x24,0x2c,0xbb,0xb6,0x1e,0x08 +,0x05,0x0f,0x1b,0x0c,0x04,0x0f,0xea,0xbe,0x1d,0x14,0x1b,0x2d,0x1e,0x11,0x1b,0x33,0x19,0x18,0xc9,0x99,0x9b,0x3c,0x17,0x1b,0x26,0x17,0x11,0x1e,0x52,0xa7,0x8f,0x8f +,0x8c,0x8d,0x98,0x96,0x93,0xb0,0x29,0xab,0x8b,0x8c,0x93,0xac,0x56,0xa5,0xbb,0x3b,0x36,0xb1,0x30,0xe7,0x91,0x8b,0x8a,0x99,0xad,0xaf,0x6c,0x1b,0x0a,0x08,0x12,0x1f +,0x2d,0x2f,0xc5,0xc3,0x38,0xbd,0x92,0x9a,0xcd,0x9a,0x85,0x81,0x81,0x8b,0x8f,0x86,0x87,0x8e,0xa8,0x9f,0x93,0xa3,0xa8,0x97,0x8a,0x9c,0x19,0x1d,0x13,0x0d,0x05,0x01 +,0x02,0x09,0x1b,0x0b,0x05,0x0c,0x0d,0x0a,0x0a,0x06,0x08,0x07,0x0a,0x16,0x1a,0x12,0x0f,0x15,0x0e,0x0e,0x0b,0x09,0x19,0x18,0x25,0xac,0x91,0x91,0xa5,0x9a,0x91,0x91 +,0xab,0x4a,0xd1,0xa2,0x91,0x97,0x8d,0x83,0x8b,0x95,0xaf,0xa2,0x9c,0x9c,0x96,0x8b,0x89,0x8a,0x96,0x94,0x89,0x88,0x93,0xae,0xa2,0x3e,0x7e,0x22,0x9c,0xa8,0xc0,0x3a +,0x12,0xda,0x0d,0x0c,0x4e,0x50,0x9d,0x9b,0x64,0xa5,0x8a,0x8e,0x4d,0x9c,0xa9,0x1f,0x3a,0x06,0x1e,0x8b,0xcd,0x35,0x3d,0x18,0x11,0x0c,0x08,0x05,0x04,0x0b,0x12,0x1d +,0x0d,0x1a,0x2a,0x16,0x15,0x02,0x0d,0x0f,0x16,0xda,0x1f,0xca,0x9c,0xa5,0xa3,0x9c,0x92,0x97,0xb8,0x9a,0x91,0x8c,0x8a,0x95,0x8c,0x87,0x86,0x8c,0x97,0x8f,0x91,0x8d +,0x8d,0x87,0x92,0xb1,0x99,0xc8,0x28,0x0d,0x0a,0x09,0x05,0x10,0x15,0x08,0x14,0x14,0x20,0x24,0x1c,0x28,0x03,0x06,0x14,0x18,0x21,0x1d,0xc6,0x99,0xb0,0xc9,0x39,0x58 +,0xc9,0xa8,0x86,0x89,0x83,0x87,0x88,0x80,0x84,0x84,0x99,0x8e,0x94,0x9c,0x8d,0x87,0x8a,0x9a,0x27,0x29,0xa2,0x20,0x07,0x06,0x14,0x06,0x03,0x07,0x11,0x3d,0x17,0x13 +,0x2a,0x0d,0x05,0x04,0x0c,0x1b,0x0a,0x13,0x1f,0xab,0x24,0x0a,0x1d,0x17,0x3c,0x18,0xa1,0x86,0x8e,0xd5,0x2f,0x87,0x97,0x3a,0x9c,0x92,0xd2,0x1b,0xb5,0x95,0x88,0x87 +,0x8e,0x85,0x88,0x8b,0x4e,0x18,0x96,0xb8,0x29,0xab,0x29,0x20,0x16,0x09,0x08,0x30,0x1d,0x05,0x18,0xb0,0x29,0x12,0x18,0xae,0x1e,0x16,0x2c,0x0e,0x27,0x14,0x15,0xcf +,0x8c,0x9d,0x8e,0x81,0x88,0x83,0x8a,0x91,0x92,0x9d,0x89,0x84,0x87,0x8f,0x9c,0x4c,0x9e,0x9e,0x25,0xa7,0x98,0x94,0x31,0x1f,0x1c,0x0f,0x2f,0x97,0x1d,0x0e,0x0f,0x0b +,0x05,0x3a,0x2d,0x0e,0xa8,0xb8,0x1b,0x07,0x09,0x11,0x04,0x13,0xbb,0xc8,0x2e,0x11,0x17,0x14,0x92,0x1b,0x0b,0x4a,0x0d,0x09,0x00,0x1d,0x1a,0x04,0xcb,0x26,0x19,0x27 +,0x36,0x20,0xa0,0x80,0x92,0x85,0x81,0x84,0x87,0x96,0x94,0x38,0xa2,0x8a,0x23,0x4e,0x9a,0xff,0x1a,0x8d,0x94,0x0a,0x9c,0x9c,0xae,0xe6,0x42,0x98,0x1f,0xa5,0x8e,0xa0 +,0x9d,0xa3,0x3b,0x21,0x86,0x2d,0x2f,0x80,0x8c,0x9d,0x34,0x9e,0x1f,0x12,0xc9,0x3d,0x1e,0x19,0x38,0x08,0x14,0x8a,0x2a,0x2f,0xad,0x0d,0x0e,0x0e,0x0f,0x09,0x1a,0x89 +,0x8f,0x9b,0x90,0xaf,0x26,0x8d,0x82,0xb5,0x97,0x98,0xa5,0x14,0x0f,0x1c,0x04,0x1b,0x0e,0x03,0x03,0x0b,0x02,0x00,0xa0,0x39,0x00,0x6b,0xbb,0x06,0x15,0x33,0x41,0x21 +,0x92,0x8d,0x2f,0x89,0x87,0xa4,0x91,0x80,0xac,0x70,0x81,0x8b,0x8e,0x8a,0x8c,0xab,0x44,0x8e,0x91,0xcc,0x85,0x98,0x12,0xb1,0x80,0x94,0x26,0x80,0xdf,0x1d,0xaa,0x24 +,0x1d,0x0e,0xaa,0x10,0x0f,0xa4,0x0f,0x01,0x19,0x9b,0x07,0x1c,0x87,0x0d,0x10,0x18,0x0c,0x13,0x09,0x9e,0x32,0x11,0xaa,0x0c,0x0c,0x9e,0x80,0xa4,0x91,0x80,0xb9,0x8d +,0x80,0x8a,0x8c,0x8a,0x88,0x9a,0x90,0xa4,0x1a,0x13,0x37,0x9b,0x01,0x0e,0x1e,0x00,0x06,0x11,0x04,0x01,0x05,0x06,0x00,0x0a,0x1a,0x01,0x07,0x0a,0x5f,0x03,0x15,0x8b +,0x10,0xd2,0xa5,0x12,0x28,0x4c,0xa5,0x92,0x91,0x8c,0xab,0x38,0x92,0x83,0xa4,0x8a,0x80,0x9e,0x90,0x83,0x97,0x8e,0x8b,0x88,0x8c,0x9c,0x83,0x69,0x31,0x3c,0x84,0xaa +,0x26,0x8d,0x13,0x20,0x2b,0x23,0x2c,0x0f,0x1c,0x26,0x06,0x3b,0x09,0x07,0x15,0xd1,0x12,0x00,0x8d,0x17,0x0e,0x9a,0x2a,0xc7,0xb0,0x98,0x89,0x8d,0x82,0xa3,0x97,0x8d +,0x81,0x8e,0x19,0x80,0xa3,0x12,0x94,0x3a,0x08,0x0e,0x10,0x0b,0x06,0x21,0x0b,0x00,0x0b,0x20,0x2b,0x09,0x89,0xcd,0x07,0xcd,0x1b,0x04,0x1c,0x35,0x13,0x10,0xc6,0x1b +,0x09,0x0e,0x29,0x93,0x07,0x99,0x8c,0x0c,0x4c,0x95,0x16,0xba,0x95,0xaa,0xe3,0xc8,0x94,0xad,0x8f,0x91,0x84,0x3d,0x8f,0x80,0x3e,0x95,0x81,0x9d,0xa4,0x8b,0xca,0xa2 +,0x9c,0x98,0x27,0x1f,0x22,0xaf,0x18,0x0c,0x84,0x1d,0x10,0x9d,0x0c,0x0b,0xa8,0x51,0x22,0x2f,0x96,0x68,0x9f,0xad,0x98,0x85,0xa0,0x80,0x88,0xb5,0x87,0x9a,0x25,0xa9 +,0x1e,0x2b,0x07,0x0e,0x09,0x00,0x06,0x0a,0x17,0x00,0x18,0x1c,0x00,0x26,0x5d,0x09,0x30,0x2a,0x1f,0x15,0x62,0xac,0x10,0x27,0x1c,0x88,0xbe,0xbb,0x80,0x2e,0x9d,0x86 +,0x23,0x38,0x8f,0xae,0xaf,0xa6,0x8f,0x31,0x9f,0x2d,0x9f,0x97,0x1c,0x81,0xab,0x0f,0x97,0xa0,0x14,0x9e,0xd4,0x36,0x29,0xa3,0x18,0x0c,0xbc,0x26,0x9a,0x0f,0xd6,0x8f +,0x14,0x98,0x96,0x04,0x2a,0xc1,0x38,0x30,0x2c,0xb4,0x17,0x9f,0xc0,0x8a,0x97,0x8e,0x80,0x9b,0x86,0x80,0x8c,0x85,0x84,0x8f,0x8c,0x97,0x91,0x0b,0x1f,0x07,0x11,0x1c +,0x00,0xbc,0x0f,0x03,0x13,0x07,0x00,0x14,0x03,0x0a,0x08,0x0c,0x0e,0x05,0x0b,0x0e,0xa6,0x05,0x29,0x98,0x0c,0xac,0xa4,0x11,0xaa,0x9b,0xbc,0xa9,0xa8,0x93,0x3c,0xa3 +,0x40,0x8c,0x9d,0xac,0x80,0xa4,0x9a,0x85,0xbd,0x9a,0x89,0xb2,0x8a,0x97,0x8b,0xa9,0xad,0x9f,0x9e,0x94,0x0b,0x93,0xb9,0x13,0x8e,0x21,0x0a,0xac,0x27,0x33,0x1b,0x21 +,0x13,0x06,0x0b,0x00,0x2a,0x08,0xce,0x8a,0x11,0xa3,0x9a,0x20,0x8c,0x8b,0x8c,0x88,0x85,0x8c,0xa8,0x83,0x9c,0x8c,0x99,0x27,0x84,0x1e,0x0d,0xa5,0x07,0x19,0x1b,0x09 +,0x0c,0x07,0x0e,0x06,0x0a,0x02,0x0c,0x5d,0x06,0xe9,0xaa,0x17,0xa3,0x19,0x06,0x16,0x22,0x2f,0x16,0x1e,0x2c,0x0e,0x14,0x1d,0x8a,0x0f,0xca,0x84,0x13,0x95,0x92,0x46 +,0x8d,0x89,0x9a,0x96,0x98,0x8e,0x78,0xa9,0x68,0x8a,0x8c,0x58,0x83,0xb0,0x9b,0x81,0x2e,0xf8,0x93,0x32,0xac,0x27,0x9e,0x16,0x16,0x1e,0x18,0xd7,0x07,0xa6,0x29,0x03 +,0xbc,0x1a,0x0c,0x8b,0xb0,0xa2,0x8e,0x95,0x9e,0xa6,0x8c,0x8b,0x81,0x8c,0x86,0x80,0xa5,0x8a,0x8b,0x16,0xa3,0x20,0x06,0x07,0x04,0x0c,0x07,0x07,0x04,0x11,0x06,0x05 +,0x2a,0x0b,0x0f,0x9f,0x08,0x0e,0xce,0x29,0xbe,0x3a,0xa6,0x12,0x24,0x26,0xa4,0x9b,0x18,0x85,0x8f,0x2e,0x85,0xd5,0x25,0x8a,0xb9,0xba,0xd7,0x9e,0x3a,0x23,0x50,0x98 +,0x8a,0x19,0xa5,0x8d,0x12,0x91,0x90,0x1e,0xa7,0x59,0xbe,0x31,0xb9,0x9d,0x1a,0x42,0x3b,0xce,0x10,0xf2,0x80,0x1e,0xa1,0xa6,0x04,0x16,0x29,0x13,0x0f,0x1c,0x23,0x1a +,0xba,0x9f,0x82,0x94,0x9f,0x80,0x90,0x8c,0x80,0x9d,0x8d,0x82,0x98,0x94,0xb9,0xae,0x07,0x0e,0x0f,0x0f,0x08,0x04,0x45,0x05,0x0d,0x6b,0x04,0x04,0x0d,0x05,0x13,0x07 +,0x24,0x0b,0x0a,0x36,0xa0,0x1d,0x0d,0x87,0x33,0x1f,0x92,0x0f,0x2d,0x93,0xac,0x90,0xb3,0x95,0x2f,0x1c,0xa7,0x8a,0x9e,0x1a,0x80,0xa1,0xed,0x80,0xb4,0x9f,0x8e,0xb7 +,0x94,0xa6,0x9a,0x39,0x22,0xa6,0x85,0xc5,0x1d,0x83,0x5f,0x39,0x8e,0x0b,0x1b,0xba,0x1e,0xa9,0x19,0x31,0x0f,0x05,0x0b,0x48,0x0b,0x0c,0x89,0x1d,0x36,0x84,0xbc,0x9c +,0x87,0x8a,0x83,0x8c,0x89,0xa7,0xa5,0x8f,0x80,0x9a,0xbe,0x86,0x0e,0x13,0xb3,0x01,0x08,0x08,0x03,0x0b,0x0e,0x10,0x07,0x02,0x0b,0xfd,0x02,0x2d,0xa5,0x06,0x43,0x2f +,0x0a,0x24,0x2a,0xc6,0x2e,0x26,0x1e,0x0c,0x0d,0x9e,0x88,0x28,0x87,0x8e,0x29,0x89,0x9b,0x41,0xa4,0xa3,0x96,0xb8,0x97,0x8e,0x5f,0x1f,0x85,0xa2,0x25,0x80,0xd7,0x26 +,0x94,0x36,0xc5,0x9e,0xa6,0x9c,0x2c,0x69,0x4c,0x0b,0x0f,0x8e,0x0c,0x17,0x87,0x07,0x38,0x5c,0x00,0x1b,0x0f,0x0f,0xb5,0x1b,0xa0,0x9d,0x25,0x8a,0x83,0xa4,0x81,0x81 +,0xab,0x83,0x95,0x64,0x8a,0xa7,0x4d,0xbb,0x32,0x16,0x06,0x00,0x1f,0x07,0x06,0xa1,0x06,0x06,0x15,0x06,0x09,0x16,0x1f,0x0c,0x08,0x1d,0x17,0x00,0x36,0x8e,0x00,0xa2 +,0x86,0x0b,0x90,0x4a,0x1a,0xc2,0x4c,0x99,0x9b,0x8f,0x89,0x35,0x11,0x85,0xa8,0x1f,0x80,0xb3,0x14,0x8c,0x2e,0xa2,0x95,0x8d,0x8f,0xcd,0x8e,0x56,0x0d,0x99,0x86,0x10 +,0x8e,0x8a,0x2f,0x9d,0xbc,0x2f,0x0f,0xc5,0xba,0x09,0x19,0x20,0x00,0xbf,0x8e,0x01,0xcc,0x95,0x20,0x95,0x9e,0xa8,0x48,0x98,0x80,0x8d,0x87,0x81,0x45,0x93,0x80,0x26 +,0x8d,0x86,0x27,0xa9,0x24,0x0f,0x04,0x04,0x16,0x17,0x22,0x07,0x00,0x9a,0x9f,0x04,0xb6,0xaf,0x07,0x06,0x02,0x08,0x0d,0x00,0x0f,0x06,0x00,0x0b,0x00,0x10,0x1b,0x00 +,0x4e,0x45,0x0c,0x17,0x13,0x1a,0x07,0x2a,0xb1,0x28,0x8f,0x94,0x2d,0x86,0x88,0x8b,0x80,0x84,0x89,0x83,0x80,0x84,0x87,0x80,0x82,0x8c,0x80,0x82,0x8c,0x80,0x86,0x8d +,0x80,0x87,0x8d,0x90,0x8b,0xb5,0xe9,0x8c,0x5b,0x35,0x95,0x0f,0x0c,0x98,0x06,0x1c,0x4f,0x07,0x0a,0x03,0x04,0x00,0x02,0x09,0x02,0x02,0x0d,0x00,0x0a,0x0d,0x00,0x0d +,0x09,0x04,0x04,0x00,0x03,0x00,0x06,0x05,0x02,0x0f,0x06,0x00,0x3a,0x05,0x14,0x95,0x2d,0x27,0x0b,0x3f,0x24,0xad,0x80,0xa6,0xa8,0x89,0xbb,0x86,0x83,0x8f,0x80,0x82 +,0x80,0x85,0x82,0x85,0x88,0x80,0x80,0x85,0x80,0x8e,0x8a,0x80,0x86,0x83,0x80,0x82,0x81,0x81,0x81,0x87,0x83,0x81,0x8d,0x89,0x84,0x9b,0x80,0x97,0xa9,0x80,0x8c,0x85 +,0xda,0xa0,0xcc,0x1b,0x9d,0x0f,0x06,0x1c,0x00,0x27,0x3a,0x00,0x1b,0x0e,0x09,0x0a,0x07,0x02,0x00,0x08,0x0a,0x00,0x06,0x04,0x00,0x19,0x00,0x08,0x26,0x04,0x06,0x03 +,0x04,0x00,0x03,0x0d,0x02,0x04,0x06,0x00,0x0b,0x03,0x05,0x2c,0x0d,0x0e,0x05,0x08,0x01,0x07,0x25,0x0a,0x0a,0x1d,0x00,0x20,0x33,0x01,0x8f,0x9e,0x4f,0xcd,0x50,0x24 +,0x1d,0x88,0x8d,0xa0,0x82,0x99,0x8e,0x80,0x92,0x83,0x80,0x81,0x84,0x81,0x87,0x8e,0x81,0x81,0x88,0x81,0x89,0x8c,0x80,0x86,0x81,0x80,0x82,0x83,0x82,0x83,0x8e,0x89 +,0x80,0x8e,0x87,0x88,0xc7,0x80,0x96,0x97,0x80,0x8d,0x9c,0x3f,0x3f,0x0f,0x17,0xa4,0x0f,0x0f,0x4f,0x02,0xa8,0xc7,0x11,0x8b,0x9f,0xa7,0x43,0xa4,0x23,0x1f,0x8b,0x9c +,0xac,0x85,0x2c,0x91,0x85,0x66,0x81,0x86,0x89,0x91,0x85,0x98,0x36,0x8b,0x9e,0x2b,0x86,0x1f,0x30,0x8e,0x04,0xb3,0xaf,0x1b,0x0e,0x09,0x05,0x00,0x08,0x05,0x00,0x07 +,0x01,0x01,0x0e,0x00,0x03,0x09,0x02,0x01,0x01,0x03,0x00,0x01,0x05,0x00,0x03,0x04,0x00,0x0b,0x04,0x00,0x08,0x04,0x03,0x00,0x04,0x00,0x03,0x0c,0x00,0x05,0x0c,0x00 +,0x0e,0x0a,0x01,0x33,0x1f,0x16,0x0c,0x1d,0x0d,0x0f,0x8f,0xc7,0xac,0x88,0xc5,0x86,0x86,0x9c,0x80,0x82,0x80,0x83,0x80,0x83,0x86,0x80,0x81,0x84,0x80,0x89,0x89,0x80 +,0x88,0x80,0x80,0x80,0x82,0x80,0x80,0x84,0x81,0x80,0x88,0x80,0x85,0x8b,0x80,0x91,0x86,0x80,0x84,0x82,0x82,0x84,0x8f,0x84,0x81,0xbb,0x8b,0x8a,0x4b,0x80,0x91,0x9a +,0x80,0x87,0x89,0x89,0x83,0x9e,0xa6,0x83,0xaa,0xb4,0x9d,0x02,0xb2,0x33,0x00,0x35,0x0c,0x06,0x07,0x05,0x01,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x04,0x00,0x02,0x04 +,0x00,0x01,0x01,0x01,0x00,0x04,0x04,0x00,0x04,0x02,0x00,0x17,0x00,0x08,0x1d,0x0c,0x1c,0x1d,0x21,0x0a,0x21,0xa0,0x1d,0x9f,0xb8,0x10,0x85,0xb2,0xbc,0x80,0x8e,0x8d +,0x8c,0x86,0xae,0x9e,0x80,0xb1,0xb1,0x84,0x1d,0x94,0x8a,0x2e,0x85,0x84,0x88,0x9c,0x8f,0xa2,0x49,0x84,0x90,0xb4,0x87,0x24,0xb2,0x80,0x25,0x8d,0x84,0x99,0x9c,0x91 +,0xc3,0x0e,0x93,0x9a,0x10,0x9f,0x1d,0x02,0x99,0x10,0x1b,0x92,0x25,0x18,0x12,0x1c,0x04,0x10,0x3d,0x06,0x12,0x27,0x00,0xa8,0x5c,0x08,0x8e,0x9c,0x49,0x25,0xb2,0x18 +,0x12,0x8f,0x2a,0x15,0x9d,0x0b,0x40,0x88,0x0f,0x97,0x90,0x5f,0xd2,0xaa,0x2b,0x0b,0x9c,0xc6,0x12,0x98,0x1f,0x0a,0x8a,0x18,0x41,0x85,0x9d,0xae,0xa3,0x92,0x23,0x9f +,0x8b,0x35,0xa0,0x8e,0x29,0x85,0x91,0xba,0x80,0x84,0x84,0x89,0x84,0x9d,0x90,0x80,0x89,0x8c,0x80,0x9d,0x91,0x80,0x2d,0x8d,0x87,0xa0,0xa8,0x9d,0x26,0x07,0x37,0x22 +,0x08,0x27,0x0b,0x00,0x1c,0x03,0x07,0x31,0x09,0x05,0x08,0x08,0x00,0x07,0x10,0x01,0x09,0x16,0x00,0x14,0x0f,0x01,0xab,0x54,0x1f,0x1c,0x1b,0x0d,0x18,0x8e,0xa9,0xed +,0x8b,0x25,0xa6,0x81,0x25,0x8c,0x83,0x8d,0x8a,0x88,0x91,0x4b,0x8b,0x86,0xa7,0x8b,0xa2,0x0d,0x89,0xca,0xaf,0x81,0x9d,0xa8,0xac,0x9e,0x2e,0x57,0x9d,0x17,0x34,0x8f +,0x0a,0xba,0xa9,0x0a,0x8b,0x8d,0xb0,0x38,0x34,0x1e,0x15,0x97,0xca,0x0a,0xd3,0x0c,0x0d,0x9b,0x04,0x12,0xad,0x20,0x3f,0x24,0x11,0x00,0x0f,0x32,0x06,0x14,0x12,0x00 +,0x42,0x19,0x0a,0x8e,0x49,0x25,0xcd,0x9b,0x40,0x1c,0x9d,0x2e,0x5f,0x8a,0x1b,0xbb,0x8f,0x10,0x89,0x85,0x97,0x9d,0xa6,0x4f,0x2a,0x8c,0xa7,0x15,0x9d,0x2f,0x17,0x85 +,0x0f,0x18,0x88,0xa1,0x9b,0x96,0xbb,0x0a,0xd1,0x92,0x2a,0xcd,0xbf,0x03,0xa0,0x9d,0x20,0x84,0x9b,0xae,0x9a,0x8c,0xbe,0xfa,0x92,0x9e,0x94,0x81,0xa6,0x93,0x85,0x2f +,0x85,0x81,0x8f,0x9a,0x9f,0x33,0x34,0x8f,0xb7,0x0d,0x33,0x19,0x09,0x9f,0x08,0x08,0xc9,0x18,0x18,0x0d,0x06,0x00,0x05,0x0b,0x06,0x03,0x07,0x00,0x19,0x16,0x03,0xb6 +,0x14,0x0c,0x1d,0x26,0x07,0x08,0x28,0x17,0x34,0x8d,0x16,0x6f,0x8b,0x1c,0x86,0x82,0x8c,0x92,0x8e,0x95,0x9c,0x84,0x89,0xae,0x8b,0x91,0xad,0x80,0x2b,0xa6,0x80,0x88 +,0x8b,0x91,0xa0,0x13,0xbb,0x8c,0xd5,0xb0,0xbc,0x08,0x8d,0x9a,0x23,0x87,0x9f,0xaa,0x9e,0xa5,0x15,0x1a,0xa5,0x2c,0xeb,0x97,0x0b,0x2f,0xb5,0x03,0x99,0xa1,0x0f,0x0d +,0x1a,0x0e,0x09,0xc7,0x14,0x02,0x19,0x06,0x08,0xd7,0x00,0x11,0xae,0x28,0x2c,0x1c,0x11,0x04,0x34,0x9b,0x1a,0xed,0x22,0x0a,0x87,0xa4,0xd1,0x85,0xa4,0xbc,0x9d,0x94 +,0x14,0x24,0x94,0x48,0x95,0x8a,0x17,0x95,0xae,0x16,0x83,0x93,0xb2,0x48,0xab,0xfe,0xbd,0x8d,0x2c,0x1f,0x8f,0x18,0xb5,0x8f,0x08,0x98,0x87,0x90,0x9a,0xa4,0x21,0x0b +,0x90,0x8f,0x2b,0x9a,0x22,0x37,0x80,0xa5,0x8b,0x81,0x8b,0x8a,0x88,0x8a,0x39,0x9a,0x8d,0xae,0x88,0x94,0x0c,0x95,0x20,0x1a,0x8c,0x56,0x12,0x0a,0x1a,0x03,0x0c,0x14 +,0x00,0x05,0x07,0x00,0x0b,0x09,0x00,0x23,0x19,0x1e,0x0f,0x0a,0x04,0x03,0x29,0x0e,0x06,0x1e,0x00,0x1f,0x8e,0x16,0x8c,0x8e,0x97,0x97,0x8c,0x9a,0x1f,0x8b,0x96,0xa5 +,0x80,0xae,0xd7,0x81,0x23,0x8d,0x80,0x8c,0x90,0x92,0x88,0xa7,0x87,0x88,0x23,0x97,0x9e,0x14,0x85,0x41,0x4f,0x85,0x8c,0x88,0xa7,0x9c,0x11,0x22,0x8c,0x18,0x20,0xbc +,0x02,0x92,0x9a,0x16,0x89,0xbf,0x3e,0x2b,0x4e,0x0d,0x06,0xcc,0x0e,0x18,0x9e,0x01,0x14,0x41,0x00,0xab,0xdd,0x15,0x0a,0x0f,0x12,0x03,0xc9,0x1d,0x02,0x2c,0x09,0x0b +,0x9d,0x05,0x3f,0x8f,0x8f,0x99,0xc7,0xb1,0x08,0xa8,0x90,0x12,0x9f,0x54,0x15,0x80,0xa1,0x9a,0x85,0x99,0x99,0x9f,0x99,0x0a,0x1c,0x97,0x1c,0x98,0x95,0x09,0x92,0x47 +,0x20,0x87,0xb7,0x4f,0x1c,0xa2,0x29,0x1f,0x8e,0x1f,0x25,0x8f,0x17,0x94,0x97,0x1c,0x83,0x86,0x81,0x8b,0x8b,0x99,0x68,0x82,0x90,0x62,0x89,0x2a,0x9c,0x80,0xc9,0x88 +,0x90,0xa1,0xad,0xce,0x20,0x00,0x19,0x1f,0x05,0x34,0x0a,0x01,0x21,0x01,0x1d,0x22,0x08,0x0a,0x02,0x0e,0x00,0x0e,0x22,0x01,0x17,0x11,0x00,0x23,0x03,0x0c,0x9e,0xa3 +,0x97,0x2d,0x5b,0x0a,0x1b,0x85,0x41,0xb6,0x9c,0x11,0x87,0x90,0x9e,0x80,0x92,0x83,0x88,0x86,0xab,0x1f,0x89,0x97,0x95,0x80,0x30,0x92,0x8c,0x6d,0x84,0xa3,0x9f,0xca +,0x94,0x8e,0x1f,0x8c,0x9f,0x12,0x88,0xab,0xa8,0x8d,0x0a,0x9c,0x9c,0x98,0x99,0x3f,0x7b,0x0b,0x56,0xc6,0x02,0x16,0x08,0x07,0x92,0x0a,0x25,0xb2,0x18,0x34,0x1c,0x18 +,0x00,0x06,0x28,0x07,0x1b,0x23,0x00,0xb1,0x10,0x2e,0x8e,0x25,0x2e,0x0e,0x2f,0x19,0x18,0x95,0x10,0x1b,0x96,0x09,0xa0,0x1b,0x0b,0x86,0x91,0x88,0x9b,0xa9,0xd6,0x1d +,0x89,0xae,0x0c,0x9e,0x0e,0x9a,0x88,0x1f,0x87,0x8f,0x89,0x88,0x8e,0xa0,0x0d,0xb0,0xa1,0x11,0x8e,0x1a,0x1c,0x8a,0x0f,0x8e,0x8e,0xe1,0xdd,0xaf,0x90,0x56,0x93,0x8a +,0x2c,0x8a,0x8f,0xa7,0x80,0x12,0x9c,0x82,0x8d,0x87,0xac,0xaa,0x25,0xe7,0x8e,0x0e,0x0e,0x14,0x00,0x9c,0x0f,0x11,0xa5,0x17,0x44,0x1e,0x19,0x06,0x00,0x1c,0x0b,0x0b +,0xb2,0x00,0x36,0x27,0x0b,0x8e,0x37,0x19,0x0d,0x1d,0x1e,0x10,0xa1,0x21,0x0f,0x8b,0x25,0x92,0x98,0x07,0x8a,0x91,0x8f,0x97,0xca,0xae,0x1f,0x97,0x98,0x0c,0xc6,0x0b +,0x2f,0x84,0x14,0x8d,0x97,0xb2,0x94,0xb2,0xab,0x0a,0x14,0x99,0x0b,0xa9,0xae,0x14,0x86,0x2f,0x8e,0x85,0xab,0xab,0xd8,0x98,0x35,0xb4,0x8a,0x1c,0x9d,0x8e,0x23,0x81 +,0x14,0x20,0x8a,0xc2,0x9a,0xf9,0xc5,0x12,0x0f,0x96,0x12,0x0a,0x24,0x00,0x9c,0x2a,0x1b,0x8f,0x21,0xa2,0x5e,0xad,0x2e,0x05,0xbd,0x2c,0x0e,0x97,0x0b,0xb7,0xa5,0x16 +,0x86,0xa1,0x38,0x15,0x2c,0x2a,0x08,0xb8,0xff,0x05,0xae,0x13,0x31,0xa9,0x00,0xa6,0xaa,0x33,0x3f,0x35,0x31,0x0e,0xaf,0x92,0x11,0xb9,0x19,0x2b,0x87,0x22,0x8a,0x8a +,0x99,0x8d,0x98,0x8e,0x2f,0x2e,0x8a,0x23,0xb1,0x95,0x3a,0x88,0x3b,0x95,0x84,0x99,0xa3,0x39,0x9e,0x39,0x36,0x89,0x2c,0x42,0x97,0x1e,0x85,0x71,0x2d,0x88,0x9b,0x95 +,0xa9,0xa6,0x23,0x16,0x8d,0x45,0x0e,0x35,0x02,0xcc,0x1e,0x0e,0x97,0x1b,0x1d,0x18,0x1a,0x18,0x02,0x1c,0x1f,0x03,0x35,0x0c,0x31,0x66,0x0f,0x8e,0x9b,0xab,0x21,0x22 +,0xbc,0x10,0xa6,0x96,0x08,0xb3,0x2a,0x57,0x94,0x0d,0xaa,0xa2,0x4d,0x43,0x2b,0x21,0x0b,0x32,0x9a,0x09,0x1e,0x10,0x15,0x93,0x15,0x95,0x8b,0xa5,0x99,0x9e,0x97,0xdc +,0x78,0x86,0xbf,0xac,0x91,0x9d,0x83,0xca,0x91,0x80,0x8d,0x98,0xbf,0x9f,0x3b,0x16,0x89,0x47,0x09,0xc4,0x14,0x9a,0x33,0x16,0x98,0xaf,0x29,0x25,0x4c,0x1a,0x08,0xa6 +,0xba,0x09,0x2b,0x0d,0xa5,0x4e,0x15,0x89,0x99,0x24,0x2c,0x5b,0x35,0x0f,0x24,0xae,0x08,0x0e,0x12,0xb8,0x21,0x09,0xa5,0xa7,0x2c,0x10,0x19,0x22,0x0a,0x1b,0x95,0x12 +,0x10,0x1d,0xa2,0x91,0x29,0x97,0x88,0x90,0x37,0x9c,0x8e,0x23,0x34,0x87,0xa6,0x5d,0x3a,0xa0,0x89,0x1f,0xa1,0x84,0x92,0x1f,0x3d,0x9b,0x31,0x18,0x9d,0xa4,0x29,0x1a +,0xb9,0x86,0x23,0xdb,0x88,0x89,0xa4,0x25,0x9d,0x98,0x1e,0x9e,0x8b,0x3b,0x16,0x1f,0x8a,0xaa,0x22,0x9d,0x8d,0xf6,0x0a,0x2c,0x3e,0x09,0x0f,0xd5,0x25,0x0f,0x05,0xcb +,0xbf,0x14,0x35,0x97,0xa4,0x09,0x17,0xab,0x36,0x1f,0xf5,0xa7,0xb6,0x0c,0xb6,0x93,0x1f,0x48,0x9c,0x8d,0x43,0x0a,0x2f,0xba,0x11,0x1e,0x3a,0x23,0x08,0x11,0xab,0x2e +,0x1d,0x1a,0x9d,0x9d,0x14,0x1f,0xb4,0x28,0x4d,0xb0,0xa0,0xb1,0x1c,0x9b,0x8b,0x93,0x99,0x8c,0x8c,0xa5,0xae,0x96,0x95,0x99,0xa9,0x9b,0x9b,0x1b,0x30,0xb8,0x4b,0x3e +,0xe8,0xa4,0xa9,0x13,0x1f,0xb5,0x2b,0x4c,0x4d,0x2c,0x25,0x1b,0x2e,0xb8,0x27,0x3b,0x9b,0x94,0xe4,0x2e,0x7a,0x29,0xc5,0xb5,0xef,0x5d,0x16,0x1c,0xa9,0x1c,0x16,0x26 +,0x2e,0x43,0x18,0x1c,0x2c,0x12,0x1b,0xc0,0x2f,0x2c,0x1d,0x1b,0x2e,0x31,0x35,0xa7,0x96,0xa3,0xa5,0x98,0xaa,0xb7,0x97,0xa3,0x99,0xa3,0xab,0xa7,0xd2,0xaf,0x99,0x9a +,0xba,0xbb,0x37,0x3e,0x34,0x3e,0xc4,0x47,0x28,0xdd,0xcb,0x1d,0x2e,0x3a,0xcf,0xa2,0xaa,0xa3,0xa0,0x2f,0xa4,0x93,0xa1,0xa1,0xb4,0xb4,0xbf,0xae,0xab,0x9c,0xa6,0xc2 +,0xa2,0xa1,0x31,0x24,0x25,0x20,0x3e,0x1f,0x24,0x22,0x13,0x20,0x4a,0x3b,0x33,0x22,0x28,0x65,0x3c,0x4a,0x3a,0x30,0x75,0x9e,0xa6,0x34,0x3e,0x3d,0xc7,0xab,0xb0,0xa6 +,0xbb,0x2e,0xbf,0xb8,0x3c,0x1f,0x19,0x1e,0x2a,0x2a,0x1d,0x25,0x1b,0x1d,0xfb,0x5a,0x27,0x23,0x1c,0x29,0xd4,0x4f,0xd9,0x3e,0x61,0x9a,0x99,0x9b,0x9e,0xaa,0x9b,0xa1 +,0xa4,0x9c,0x9f,0xaa,0xa1,0x99,0xaa,0x42,0x22,0x21,0xba,0xa2,0x3a,0x5e,0x32,0x1e,0x4f,0x52,0xcb,0x3b,0x2b,0x2c,0x2f,0x3b,0x5b,0xe7,0xbe,0xa1,0x9b,0xaf,0x49,0x3e +,0x35,0xa4,0xad,0xa8,0xab,0x22,0x4b,0xbb,0x51,0xb5,0x2d,0x19,0x26,0x24,0x2e,0x24,0x1f,0x26,0x2d,0x29,0x1f,0x1e,0x16,0x1e,0xe4,0x6c,0x44,0x45,0x2b,0xbc,0xa2,0x9f +,0x9e,0xb7,0xd8,0xac,0x9f,0xa2,0xa2,0xb7,0xad,0xa2,0xba,0xb7,0xb2,0x2a,0x2c,0xcc,0x36,0x4b,0x30,0x2e,0xac,0xc3,0xbc,0xaf,0x2b,0x2b,0xdb,0xaf,0xa3,0xa3,0xb0,0xbc +,0x9f,0xa6,0xaf,0xa0,0xc5,0xad,0x9d,0xa5,0x99,0xaa,0xad,0x99,0xb2,0xb7,0xae,0x31,0x23,0x2e,0x2b,0x30,0x24,0x1b,0x2a,0x3e,0x3c,0x4d,0x2a,0x0f,0x1e,0x2c,0x38,0xb8 +,0x26,0x28,0xc8,0x65,0xbd,0xbb,0x3d,0xe8,0xb7,0xa6,0xac,0xbc,0x4a,0xca,0xbd,0x4e,0xce,0x1a,0x11,0x29,0x27,0x3c,0xc3,0x22,0x2d,0x3f,0x2e,0x48,0x38,0x20,0x25,0x39 +,0x53,0xad,0xb1,0xeb,0xa0,0x9d,0xab,0x9b,0xb0,0xb6,0xa6,0xa8,0x98,0xa7,0x35,0xae,0x98,0x9a,0x98,0xcd,0x1d,0x28,0x40,0xcc,0xb5,0x42,0x1e,0x4b,0x2e,0x27,0x33,0x18 +,0x2c,0x4c,0x34,0xae,0xbf,0x46,0xa8,0xaa,0x9d,0x99,0xbf,0x33,0xfd,0xd8,0xac,0xa3,0xc4,0x4b,0xb8,0x2f,0xe8,0xfb,0x0f,0x30,0x1e,0x19,0xc6,0x1a,0x1b,0x57,0x29,0xc9 +,0x42,0x1b,0x1c,0x2b,0x4f,0xb8,0xa6,0x20,0x2f,0xb6,0x4f,0x9a,0xad,0x2e,0xa9,0x4c,0xab,0x94,0xe5,0xbd,0x9f,0xcb,0xa5,0xb9,0x1b,0x1e,0x23,0x76,0xb8,0xc9,0x27,0x3e +,0x6a,0x2f,0x9d,0x35,0x19,0xbe,0x33,0xa3,0x99,0x3a,0xa9,0x9d,0xa4,0x95,0x9c,0x56,0xb2,0x9f,0xaf,0x9f,0xb1,0x22,0xaf,0xb9,0xbc,0xae,0x19,0x1c,0x2f,0x32,0xae,0xaa +,0x1e,0x22,0x3f,0x4f,0xa6,0x3d,0x14,0x2d,0x2b,0xd5,0xa2,0x24,0x29,0xae,0xaf,0xa9,0xa0,0x1e,0x24,0xc4,0x5c,0x98,0xbe,0x16,0xe5,0x44,0xcf,0xa3,0x1a,0x19,0x2b,0x2e +,0x73,0x4b,0x1b,0x1d,0xc3,0xa8,0xa1,0xec,0x14,0x24,0xbb,0xac,0x93,0xc9,0x32,0xa4,0xaa,0x97,0x9e,0x29,0x2a,0x3e,0xb3,0x91,0xa2,0x18,0x44,0xc9,0xe3,0x96,0x34,0x11 +,0x2f,0x45,0xca,0x9b,0x22,0x16,0xae,0xa9,0x92,0xb2,0x12,0x27,0x24,0xdd,0x98,0xc0,0x3d,0xac,0xa1,0xa4,0xa7,0x2b,0x1f,0xb4,0xcb,0x96,0x9f,0x15,0x2a,0x2b,0xaf,0x91 +,0x5a,0x1a,0x26,0x13,0x3a,0xa5,0x1d,0x27,0xbe,0xba,0x9e,0xc3,0x0b,0x15,0x23,0x3d,0x8c,0x97,0x1a,0x1a,0x23,0xb4,0x98,0xcb,0x4a,0xc6,0x3b,0xdc,0xb4,0xc7,0xa7,0x9d +,0x97,0x8b,0x30,0x06,0x14,0x17,0xa4,0x8e,0x3c,0x1e,0x23,0x24,0x8e,0x93,0x37,0x9f,0xf3,0x20,0x24,0x1f,0x1e,0xcc,0xa2,0x9b,0x90,0x21,0x1a,0xac,0xaf,0x8f,0x89,0xd0 +,0x10,0x0f,0x1c,0x97,0x98,0x46,0x2d,0x1a,0x2e,0x9b,0xae,0x6d,0x96,0x9c,0xa3,0x74,0x06,0x0c,0x2c,0x23,0x9d,0xb0,0x0e,0x31,0xbe,0x99,0x87,0x9a,0x20,0x1b,0x0c,0x15 +,0xab,0x25,0xb0,0xa8,0x6c,0x97,0x92,0xba,0xd3,0xaa,0xd7,0xc2,0x17,0x07,0x15,0x29,0x9c,0x8a,0x1a,0x1b,0x3b,0x56,0x90,0xa8,0xaf,0x2d,0x0d,0x16,0x56,0xba,0x35,0xa7 +,0xbc,0x22,0xa6,0xad,0x97,0x9d,0x9b,0x8c,0xae,0x0c,0x0b,0x1f,0x2b,0x8e,0xa1,0x12,0x2e,0xa8,0x9d,0x8c,0xa0,0xc3,0x27,0x04,0x0c,0x19,0x1f,0xd3,0xa4,0xa7,0x99,0xa9 +,0xb4,0x9b,0x99,0x91,0x95,0x1f,0x09,0x0e,0x18,0x97,0x87,0xce,0x1d,0x27,0x3b,0xab,0xd2,0xa4,0xa4,0x1e,0x0a,0x1b,0x29,0x2b,0x96,0xba,0x4f,0x3a,0x39,0x9a,0xae,0xa1 +,0x8f,0xaf,0x0d,0x0d,0x20,0x2c,0x90,0x91,0x75,0x3e,0x56,0x9f,0x96,0x96,0x96,0xe9,0x0c,0x0a,0x0f,0x10,0xa7,0x8f,0xc4,0xcd,0xcb,0xdc,0x3f,0x33,0x9c,0x94,0x19,0x07 +,0x29,0x47,0x99,0x88,0xa3,0xb5,0x42,0xba,0xa5,0xdb,0xa6,0x98,0xbf,0x1c,0x0f,0x0b,0x31,0xaa,0xba,0x2a,0x22,0x96,0x92,0xc2,0xbb,0x99,0x5a,0x14,0x09,0x11,0xb8,0xa3 +,0x95,0xa3,0x3a,0x51,0x8d,0x26,0x17,0x32,0x0d,0x0f,0x08,0x1c,0x98,0x8b,0x8f,0x8f,0x4f,0x2e,0x9f,0xa9,0x9c,0x9a,0xdb,0x15,0x09,0x0b,0x21,0x91,0x8a,0xa2,0x0d,0x0c +,0x98,0xa6,0x25,0x9a,0x8b,0xc8,0x1b,0x14,0x2b,0xa3,0x97,0xac,0x09,0x0a,0x8f,0x8f,0x48,0x99,0xa5,0x2e,0x0b,0x0e,0x0a,0x12,0x98,0x8a,0x8f,0x24,0xbb,0x90,0x94,0xa0 +,0x2b,0x0d,0x07,0x0a,0x16,0x9f,0x83,0x84,0x8c,0xb1,0xce,0x8f,0x35,0x1d,0x9f,0x9f,0xae,0x1f,0x0e,0x0f,0xb8,0x9b,0x36,0x0e,0x02,0x2a,0x2d,0x21,0x9f,0xb0,0x11,0x06 +,0x28,0xa9,0x9e,0x9b,0x92,0x8b,0xcc,0x97,0x80,0x8d,0x90,0x94,0xaa,0x11,0x00,0x08,0x0d,0xaf,0x98,0xa5,0x30,0x0d,0x8f,0xaf,0x0f,0x3f,0x2a,0x14,0x00,0x13,0xb4,0x9b +,0x84,0x8a,0xaa,0x19,0x65,0xa0,0xc5,0x92,0x96,0xc7,0x29,0xaf,0xa4,0x4e,0x9a,0x90,0xaa,0x05,0x0d,0xae,0x29,0x9a,0xad,0x1c,0x06,0x02,0x22,0x0e,0xad,0x8b,0x97,0x28 +,0x01,0x91,0x92,0xab,0x86,0x86,0x8e,0x0d,0x0f,0x41,0x9b,0x8e,0x8e,0x8c,0x16,0x13,0xc2,0x20,0xb6,0x41,0x19,0x04,0x05,0x29,0x15,0xcc,0x95,0x87,0xb2,0x13,0x9d,0xc3 +,0xab,0x8f,0x8b,0xcf,0x01,0x11,0x45,0xa7,0x8e,0x95,0xc9,0x06,0xb5,0x86,0x2d,0xe8,0x90,0x8d,0x18,0x0a,0x1d,0x27,0x9d,0x87,0x84,0xc8,0x09,0x1e,0xd1,0x4d,0x96,0x96 +,0x0d,0x00,0x11,0xee,0xa8,0xa4,0xab,0xae,0x07,0x28,0x89,0x9a,0x95,0xd0,0x93,0x3d,0x1b,0x36,0xbe,0x88,0x84,0x97,0x0d,0x00,0x49,0x9f,0x9d,0x87,0x8e,0xcf,0x00,0x0d +,0x29,0x25,0xae,0xb2,0x2e,0x08,0x10,0x8f,0x2f,0xca,0x8c,0x9f,0x19,0x08,0x28,0x1a,0xa6,0x81,0x80,0x9a,0x00,0x42,0x88,0x97,0x8f,0x8b,0x7c,0x00,0x0a,0x1b,0xda,0x9a +,0xcd,0xc8,0x18,0x02,0xc9,0x13,0x24,0x8e,0x8f,0xa6,0x00,0x17,0x20,0xa6,0x83,0x88,0x8e,0x08,0x0d,0x8c,0x8f,0x83,0x8e,0x90,0x76,0x0d,0x1e,0x09,0xef,0x94,0x96,0xa0 +,0x0c,0x52,0x3d,0x07,0xb8,0x93,0xe4,0x03,0x01,0x0f,0x3a,0x88,0x89,0x9b,0x1b,0x0c,0x8b,0x93,0xad,0x87,0x85,0x8e,0x1d,0x30,0x2b,0x1d,0x94,0x89,0x9b,0x07,0x07,0xb3 +,0x18,0x29,0xb4,0x99,0x1b,0x00,0x11,0x18,0x9f,0x93,0xab,0xa3,0x14,0x3f,0x8b,0xd5,0xa7,0x93,0x8b,0x11,0x08,0x1c,0x1e,0xa1,0x93,0x87,0xa9,0x08,0x79,0x9a,0xd9,0x8c +,0x8c,0x9d,0x07,0x13,0x2c,0x2d,0x90,0xc2,0x22,0x0c,0x09,0xac,0x41,0x1e,0x9a,0x8a,0x9b,0x05,0x0d,0x19,0x4b,0x8f,0x89,0x92,0x2f,0x10,0xac,0xb6,0x43,0x8b,0x9b,0x33 +,0x0a,0x28,0xab,0xb4,0x97,0x93,0x9c,0x1d,0x10,0x48,0x2c,0xbe,0x86,0x88,0x18,0x00,0x09,0x1a,0xc5,0xa4,0xbe,0x1f,0x0d,0x0a,0xb2,0x63,0xa9,0x87,0x8e,0xc6,0x15,0x5a +,0xad,0x9c,0x87,0x85,0x8d,0x1e,0x0e,0xa8,0x5d,0x6e,0x95,0x9b,0x12,0x02,0x08,0x19,0x27,0xdc,0xa0,0x2c,0x0e,0x04,0xbf,0xad,0xa6,0x87,0x84,0x9f,0x0e,0x4e,0x32,0xc7 +,0x8e,0x8b,0x9e,0x11,0x0f,0x97,0x8e,0xa1,0x97,0x95,0x2a,0x05,0x18,0x24,0x2e,0x9d,0x99,0xae,0x0c,0x02,0x14,0x1d,0x37,0x99,0x8e,0xa5,0x0c,0x0d,0x24,0xd4,0x8e,0x8a +,0x94,0x3f,0x1e,0x9c,0x8e,0xa3,0x8d,0x85,0x92,0x18,0x05,0x0e,0x10,0x69,0xaa,0x3b,0x17,0x09,0x12,0xc6,0xbe,0xae,0x92,0x8e,0x2f,0x16,0x20,0x23,0xad,0x9b,0x8b,0xad +,0x1d,0x14,0x38,0xab,0xaa,0x8d,0x8e,0x3a,0x0a,0x19,0x22,0xad,0x9a,0x8f,0x9b,0x20,0x12,0x36,0x9d,0x9f,0x95,0x96,0x3a,0x07,0x0f,0x14,0x24,0xb8,0x99,0x9c,0x15,0x09 +,0x12,0xb8,0xa1,0x97,0x87,0x91,0x25,0x15,0x16,0x22,0x61,0x90,0x8d,0xb0,0x1e,0x14,0x9f,0x94,0xa6,0x8e,0x91,0x2c,0x0c,0x0d,0x1f,0xaf,0x92,0x93,0x3a,0x11,0x0d,0x1f +,0x2d,0x11,0xed,0x97,0xaa,0x17,0x11,0x19,0x26,0x98,0x8e,0x8e,0x9f,0x16,0x31,0x8c,0x97,0x8c,0x89,0x87,0x28,0x07,0x15,0x0e,0x49,0xaa,0xa3,0x4b,0x08,0x02,0x1c,0x2f +,0xa6,0x98,0x99,0x26,0x05,0x14,0x21,0xa9,0x8c,0x86,0x8e,0xda,0x15,0x25,0xac,0x9e,0x8f,0x83,0x8c,0x17,0x0b,0x0e,0x21,0xa9,0x91,0x97,0x20,0x06,0x0c,0x2d,0xf7,0x9f +,0x9a,0xa4,0x17,0x04,0x08,0x17,0xb2,0x91,0x8c,0x9f,0x1b,0x1c,0xbc,0x9c,0x93,0x88,0x83,0x92,0x1c,0x14,0x1f,0x32,0x9a,0x98,0xce,0x19,0x04,0x0c,0x23,0x28,0x94,0x91 +,0xaa,0x0e,0x04,0x0d,0x20,0x8e,0x87,0x8c,0x9e,0x18,0x1b,0x3f,0x9c,0x90,0x90,0x8c,0x2e,0x0d,0x0f,0x19,0xc1,0x96,0x8e,0x98,0x1a,0x07,0x18,0xc0,0x9f,0x98,0x87,0x91 +,0x0c,0x08,0x0d,0x18,0xb1,0x95,0x92,0x3b,0x0a,0x17,0x59,0xa4,0x98,0x8e,0x8d,0x12,0x0a,0x14,0x29,0x97,0x8a,0x86,0xa0,0x0f,0x15,0x2f,0x34,0x57,0x93,0x8c,0x2b,0x12 +,0x19,0x21,0xd2,0x9b,0x8b,0x9f,0x1e,0x0e,0x15,0x5a,0xc5,0x96,0x8b,0xab,0x0c,0x02,0x0b,0x1f,0xa0,0x92,0x9e,0xb3,0x1c,0x1e,0xa9,0xa3,0x94,0x88,0x88,0xaf,0x0f,0x16 +,0x2b,0xa0,0x8f,0x8f,0x9e,0x0d,0x06,0x1a,0x25,0x31,0xa3,0x9b,0x29,0x07,0x0c,0x14,0x2e,0x98,0x8d,0x93,0x24,0x0c,0x27,0xa7,0x91,0x87,0x86,0x96,0x12,0x0f,0x1c,0xbf +,0x93,0x8e,0x8b,0x43,0x0b,0x12,0x3b,0x4c,0xbc,0x93,0xa2,0x14,0x05,0x08,0x15,0xcd,0x9e,0x8f,0xc1,0x0c,0x10,0x34,0xb6,0x90,0x88,0x89,0xf2,0x10,0x1c,0x4d,0x8f,0x89 +,0x87,0xa5,0x0f,0x0a,0x2e,0x52,0x3d,0xa1,0xa0,0x18,0x08,0x0e,0x0f,0xc1,0x9f,0xa3,0xb8,0x22,0x1b,0xbc,0x9b,0x9e,0x91,0x87,0xa8,0x24,0x23,0x1f,0xb7,0xaa,0x98,0xa0 +,0x2d,0x11,0x2b,0x38,0x44,0x9b,0x99,0x37,0x0e,0x12,0x20,0xcc,0xb2,0x9d,0xaa,0x3f,0x17,0x20,0xda,0xbb,0x9c,0x99,0xb2,0x1d,0x2b,0x32,0x5e,0xa1,0x99,0x9b,0xca,0x47 +,0x30,0xa8,0xb3,0xc7,0x98,0x5f,0x24,0x15,0x0f,0x17,0x2a,0xa7,0xb2,0x3d,0x1e,0x29,0xc3,0xad,0x92,0x8f,0xa6,0x37,0x2b,0x2e,0xa8,0x9c,0xa6,0xcf,0x13,0x1f,0x4c,0x2e +,0xc7,0xc8,0xbf,0x23,0x20,0x21,0x24,0xb2,0xaa,0x9b,0xa8,0x1f,0xa6,0x9d,0xb1,0x96,0x9f,0xa7,0x21,0x29,0x29,0x43,0xcf,0xd3,0xc6,0x1b,0x1b,0xb3,0xfb,0x1e,0xbf,0x9e +,0xaa,0x18,0x20,0x20,0xca,0x9d,0xb0,0xb5,0x1a,0x39,0x9d,0x9f,0x98,0xa1,0xad,0x1f,0x15,0x59,0xc0,0x98,0xa5,0xdd,0x2a,0x17,0xa3,0x97,0x9e,0xad,0xc0,0x2d,0x08,0x0b +,0x17,0xbe,0x90,0xa8,0x30,0x12,0x10,0xad,0x93,0x8f,0x95,0xa7,0x23,0x14,0xd3,0x9e,0x95,0x93,0x9e,0x21,0x0b,0x16,0x2e,0xa6,0x94,0x95,0x46,0x08,0x08,0x1a,0xa7,0x8c +,0x8c,0x78,0x0a,0x13,0xad,0x94,0x8d,0x8d,0x75,0x0e,0x12,0x12,0x29,0x9d,0xa3,0xa6,0x1e,0x1a,0xc6,0xde,0x9c,0x95,0x91,0x32,0x0e,0x15,0x1f,0x95,0x87,0x8e,0xc0,0x0e +,0x3d,0xb3,0xb7,0xa3,0x37,0x2a,0x16,0x1d,0x1e,0xf5,0xab,0x9e,0xca,0x1d,0x3c,0x48,0x3b,0xec,0xa2,0xb7,0x23,0x24,0x1d,0xe8,0x9c,0x9c,0xa4,0x11,0x1f,0x99,0x8c,0x8b +,0x99,0x47,0x0e,0x1b,0xab,0x9b,0x9d,0xc7,0x41,0x12,0x1d,0xb2,0xc8,0xa8,0xf9,0x1c,0x08,0x07,0x13,0xc8,0x8e,0x8f,0x9d,0x1d,0x2b,0xa0,0x95,0x89,0x90,0x75,0x08,0x0e +,0x30,0x9b,0x8b,0x91,0xb9,0x0f,0x1b,0x29,0x2e,0xbd,0xaf,0xcf,0x12,0x0f,0x17,0x21,0x96,0x8b,0x8e,0x34,0x21,0x1c,0x1b,0x97,0x89,0x95,0x16,0x16,0x1b,0x33,0xa1,0x9f +,0xab,0x2a,0xbd,0xa5,0x33,0xae,0xa3,0xce,0x1a,0x1f,0x21,0x18,0xbd,0xc0,0xc6,0x23,0xc8,0xa5,0xc9,0x9f,0x9e,0xe3,0x0e,0x12,0x2a,0x97,0x8d,0x94,0xb4,0x0f,0xc3,0x94 +,0x96,0x9d,0x35,0x0e,0x04,0x0f,0x31,0xa3,0x9c,0xa4,0x39,0x12,0x2d,0xb8,0xa9,0xa6,0x94,0xad,0x18,0x26,0x1f,0x9b,0x8b,0x8a,0xb8,0x0c,0x25,0x40,0xa2,0x9b,0xa2,0x24 +,0x0c,0x18,0x19,0x50,0xa8,0xaa,0x4b,0x2a,0xa3,0xa2,0xb2,0xa7,0xa6,0x23,0x19,0x1a,0x16,0x41,0x9a,0x8b,0xac,0x59,0xac,0xb7,0x99,0x93,0xa6,0x0f,0x0c,0x19,0xc0,0x99 +,0x9a,0xa1,0x11,0x1c,0xea,0xa9,0x9b,0xb9,0x2b,0x05,0x0f,0x23,0xba,0x8e,0x8e,0x92,0x3d,0x77,0xd6,0xb5,0x95,0x8e,0x9d,0x0f,0x0a,0x0c,0x36,0x9b,0x99,0xac,0x0f,0x1e +,0x3f,0xaf,0x9e,0x9a,0xa8,0x15,0x18,0x1b,0xb1,0x9a,0x9d,0x9d,0xb9,0x99,0xce,0xdc,0xbd,0xb1,0x3a,0x14,0x1c,0x0d,0x1f,0xb8,0x92,0xbd,0x43,0xa6,0x32,0xbd,0xc5,0xa5 +,0x20,0x1b,0x3a,0x2e,0xa3,0x9e,0x9e,0x32,0x3c,0x9b,0xa2,0x99,0xb3,0x1f,0x11,0x17,0x2a,0xdb,0x99,0x99,0xa6,0x18,0x4b,0xa8,0x5a,0xb7,0xa8,0xc1,0x09,0x0e,0x1b,0x2b +,0x9e,0x9b,0x9e,0x24,0x70,0x9b,0x9b,0x8d,0x95,0xb0,0x11,0x18,0x28,0xbd,0x9d,0xaf,0x64,0x12,0x40,0xaa,0xbc,0xc6,0x4f,0x1c,0x0b,0x18,0x24,0xb7,0x94,0x98,0xb8,0x2e +,0xa2,0x9b,0x99,0xa4,0xa2,0xd5,0x07,0x17,0x27,0xa9,0x94,0x9f,0x37,0x0b,0x55,0xa6,0x9f,0x9e,0xda,0x2d,0x0b,0x1a,0x30,0xb7,0x90,0x9e,0x35,0x17,0x4c,0xa0,0x9c,0x94 +,0x9c,0x5e,0x10,0x14,0x18,0x33,0x8e,0x8c,0x9f,0x16,0x1e,0xad,0xa6,0x97,0x9d,0xd4,0x0b,0x08,0x16,0x20,0x9e,0x99,0x97,0x26,0x12,0xab,0xd1,0xa1,0x92,0x90,0x39,0x0a +,0x1b,0x22,0x9b,0x8e,0x92,0x40,0x0a,0x22,0xf1,0x99,0x9b,0xa0,0x25,0x09,0x13,0x16,0xd5,0x98,0x9a,0xaf,0x1f,0xc5,0xa3,0xb1,0x94,0x9b,0xad,0x16,0x0f,0x1f,0x1f,0x95 +,0x94,0x9d,0x18,0x0e,0xd2,0x43,0x9c,0x9e,0xb0,0x15,0x0d,0x2a,0x40,0x9d,0x96,0x93,0x45,0x10,0x49,0xba,0xac,0x9e,0x9e,0x3a,0x0d,0x1b,0x28,0xae,0x8f,0x91,0xb2,0x0e +,0x24,0xa2,0xa9,0x97,0xac,0x33,0x0d,0x0f,0x44,0x4d,0xaa,0xb0,0xbf,0x2a,0x18,0xb6,0xa5,0xa0,0x93,0x9f,0x4d,0x16,0x1d,0x50,0xb5,0x95,0xa0,0xf8,0x15,0x19,0xab,0xb7 +,0xa2,0xb9,0x3a,0x20,0x1c,0x2d,0x4a,0x9c,0x9b,0x97,0xae,0x1a,0x3b,0xe4,0xaa,0x96,0x98,0xa5,0x1e,0x19,0x28,0x45,0xa6,0xa7,0x3f,0x17,0x14,0x55,0x48,0xa9,0xad,0xb3 +,0x5d,0x19,0x37,0x51,0xb5,0xb9,0xa1,0xa4,0x22,0x29,0xa9,0xad,0xa7,0x9d,0xa6,0x1f,0x0e,0x1b,0x34,0xa5,0x9f,0x9e,0xb1,0x12,0x1f,0xc4,0x3d,0xa7,0x9d,0xa7,0x1c,0x0e +,0x22,0x3d,0x9c,0x96,0x9c,0x37,0x12,0x3e,0xdb,0xac,0x99,0x9e,0xac,0x1f,0x1a,0x2a,0x4e,0xad,0xc3,0x5d,0x25,0x1b,0xc1,0xba,0xad,0xa2,0xa8,0x5f,0x1a,0x23,0x2f,0xaf +,0x99,0x99,0xa4,0x1d,0x24,0xb0,0xaf,0xa6,0x9e,0xb5,0x21,0x15,0x1b,0x27,0xba,0x9f,0xa7,0x4d,0x15,0x1a,0x61,0xd6,0xab,0x94,0x99,0x3a,0x1c,0x3d,0x4c,0xba,0x9c,0xae +,0xfe,0x1c,0x3c,0x9c,0xc1,0xa7,0x9e,0xa5,0x27,0x12,0x2a,0x18,0x25,0xac,0xba,0xd9,0x20,0x29,0xb9,0xc9,0xb0,0xa8,0xb7,0x28,0x16,0x2b,0xd3,0xa2,0x9a,0xa1,0xba,0x21 +,0x3f,0xa8,0xc4,0xa9,0xa1,0xb5,0x29,0x10,0x21,0x4a,0x48,0xb2,0xbe,0x2f,0x14,0x1f,0xb5,0xb9,0xa3,0x9e,0xa0,0x2f,0x16,0x28,0x45,0xf0,0xa9,0x9f,0x9d,0x59,0x2c,0xb0 +,0x54,0xc5,0x9c,0xa9,0x21,0x0f,0x16,0x23,0xc7,0x9d,0xa2,0xc7,0x20,0x25,0xcf,0xc0,0xbd,0xa2,0xab,0x53,0x20,0x25,0x5f,0x5d,0xa3,0x9d,0xad,0x25,0x17,0x3f,0xab,0xa5 +,0x92,0x95,0xc0,0x13,0x13,0x2e,0x2e,0xa6,0x9a,0xc6,0x25,0x14,0x27,0xa3,0xa8,0x98,0xa4,0x34,0x1a,0x10,0x2b,0xa6,0x94,0x95,0xa7,0x46,0x1e,0x31,0xa0,0xa8,0xac,0xae +,0xd3,0x35,0x17,0x2b,0x50,0x36,0x4d,0x5c,0x3a,0x26,0x2e,0xbc,0xb9,0xbd,0x9e,0x99,0xaa,0x24,0x2a,0x30,0x25,0xc1,0xb3,0xb4,0xd8,0x25,0xd0,0xbe,0x74,0xa3,0xa6,0xb7 +,0x21,0x17,0x21,0x2f,0xbb,0xa0,0x9c,0xad,0x35,0x3a,0x3c,0x3c,0xa1,0x9d,0x9e,0xb9,0x1a,0x19,0x1e,0x47,0x9d,0xa4,0xc4,0x2c,0x15,0x2b,0xad,0x97,0x95,0x99,0xc9,0x0f +,0x17,0x27,0x44,0xb0,0xad,0xc9,0x29,0x1c,0x74,0xa4,0xb2,0x9d,0xa5,0xca,0x22,0x1d,0x37,0x3f,0xba,0xa1,0xa0,0xc1,0x34,0x4a,0x46,0x3b,0xe4,0xf0,0xab,0xc0,0x1b,0x16 +,0x25,0x53,0xad,0xac,0xae,0x3c,0x2a,0xcd,0xa8,0x9c,0xa5,0x99,0xa9,0x25,0x1e,0x20,0xd0,0xc7,0xca,0xb5,0x3c,0x2c,0x47,0x70,0xd1,0xb4,0xa9,0xb3,0x26,0x1d,0x1f,0x38 +,0xb0,0xae,0xaa,0xbf,0x2e,0x27,0xda,0xbc,0xbd,0xa2,0xa8,0x33,0x23,0x30,0x44,0x55,0xb1,0xb5,0xd7,0x3c,0x28,0xce,0xae,0xb2,0xb9,0xc7,0xcd,0x36,0x2f,0x2d,0x42,0x4a +,0x35,0xb9,0xb6,0xbc,0xdd,0x61,0xf5,0xee,0xbe,0xad,0xaf,0x37,0x2b,0x37,0xbf,0xbc,0xab,0xbd,0x2f,0x38,0x45,0xd0,0xb7,0xb5,0xdd,0x3e,0x22,0x26,0x5f,0xb8,0xeb,0xd0 +,0xb6,0x50,0x4e,0xbf,0xbe,0x60,0xd4,0xaa,0xb8,0x38,0x2a,0x22,0x3a,0x49,0xde,0xb6,0xcb,0x37,0x2d,0xea,0xaf,0xa6,0xaa,0xd5,0x46,0x46,0x2f,0x48,0x57,0xda,0xa8,0xbb +,0x3a,0x33,0x42,0xb9,0xae,0xbc,0x4e,0x36,0x48,0x48,0xd8,0xd1,0x36,0x39,0x74,0xd8,0xcc,0xcc,0xeb,0x49,0xd2,0xbf,0xb3,0xb8,0x33,0x2d,0x4e,0xb8,0xbd,0xce,0x3c,0x3c +,0x49,0xb4,0xa4,0xbb,0x67,0x33,0x4b,0x36,0x2f,0x68,0xbc,0x3f,0x2d,0x69,0x53,0x6e,0xb9,0xee,0x3f,0x4f,0x54,0xcb,0xe6,0xc3,0xa6,0xb4,0x41,0x5c,0xc5,0xb6,0xcf,0x3a +,0x2c,0x3c,0xb9,0xc2,0x5e,0x34,0xe5,0xab,0xd1,0x39,0x36,0x33,0xd4,0x6c,0x46,0xc3,0x48,0x43,0x35,0x6e,0xa7,0xb6,0xae,0xcb,0x2d,0xdc,0xb6,0xb4,0xbf,0x5b,0xdd,0x40 +,0x3d,0x29,0x2e,0xbd,0xcd,0xce,0x44,0x2e,0x75,0xb9,0xbc,0xc3,0x5c,0x26,0x36,0xbc,0xbd,0xb1,0xc2,0x36,0x3b,0xb9,0xb9,0xc5,0x39,0x34,0xf6,0xbb,0xb4,0xc8,0xcf,0x49 +,0xdd,0xa9,0xbb,0x35,0x28,0x27,0x39,0xc1,0xaf,0xbf,0x58,0x5f,0x44,0x50,0xbb,0x54,0x59,0xb9,0x52,0x5f,0x6e,0x45,0x4d,0xb5,0xac,0xc8,0x67,0x28,0x28,0x38,0xe5,0xb1 +,0xd0,0xcb,0xbe,0x5e,0x6c,0x34,0x40,0x4c,0xba,0xaf,0x52,0x45,0x30,0x68,0xaf,0xae,0xbe,0x2a,0x1d,0x28,0x6f,0xa0,0xa3,0xa8,0xc4,0x31,0x2e,0xe7,0xb9,0x50,0xda,0x4b +,0x26,0x37,0x61,0xd6,0xa6,0x9c,0xa6,0x2e,0x1c,0x18,0x3f,0xa6,0xa6,0xb9,0x3a,0x40,0xc3,0xaf,0xb9,0xb7,0xbf,0x51,0x28,0x2c,0x3a,0x28,0x3e,0xa9,0xac,0xca,0x30,0x1e +,0x23,0xc3,0x99,0x95,0xb7,0x2c,0x2d,0x49,0xba,0xbc,0xf0,0x23,0x25,0x28,0x35,0xae,0x9f,0xa0,0xc6,0x49,0xef,0x38,0x2e,0x57,0xc9,0x67,0xec,0xf4,0x74,0xb7,0xa8,0xa1 +,0x75,0x2a,0x2d,0x2f,0xc4,0xca,0x32,0x2a,0x3c,0xa3,0x9a,0x9f,0x5f,0x1f,0x1e,0x28,0xda,0xb1,0xab,0x55,0x28,0x43,0x47,0xb5,0xa9,0xae,0xa9,0xa5,0x3b,0x17,0x1e,0x38 +,0xa8,0xb1,0x59,0x23,0x1c,0x7d,0xbf,0xa1,0x9a,0xba,0xbc,0x35,0x2f,0x3b,0x3c,0xb4,0x3b,0x20,0x2f,0xb1,0x9f,0xa3,0x9c,0xa3,0x3c,0x27,0x0e,0x1a,0xb4,0xa0,0xb3,0x25 +,0xb5,0xa1,0xa4,0x9a,0x9d,0xae,0x1c,0x0c,0x0d,0x1b,0xa7,0xac,0x1e,0x2f,0x99,0x8c,0x94,0xa8,0xbb,0x21,0x0e,0x17,0x61,0x57,0xc6,0x4d,0x3c,0xbc,0xaa,0x9f,0x9d,0x93 +,0x8c,0x2f,0x0d,0x0d,0x14,0x30,0xba,0x94,0x22,0x0c,0x28,0x9a,0x8f,0x9c,0x9c,0xba,0x28,0xc5,0x1b,0x2f,0x4d,0x34,0x1b,0x19,0x98,0xa9,0xaf,0xa3,0x8c,0x8f,0x2d,0x17 +,0x15,0xb5,0x93,0xba,0x26,0x17,0x1d,0x13,0xad,0x8f,0xab,0x1f,0x08,0x20,0x40,0x3f,0x9c,0x98,0x94,0x9e,0xb1,0xa8,0x4f,0x1d,0x20,0xb0,0x2e,0x21,0x27,0xc0,0x8c,0x9b +,0xb7,0x2c,0xd8,0x8f,0x3d,0x3d,0x1e,0x06,0x03,0x13,0x9c,0x99,0x8c,0x3c,0x33,0xa5,0x4c,0xa3,0xe5,0x85,0x9c,0x0d,0x15,0x14,0x1b,0x17,0x8d,0x8c,0x99,0xab,0x5a,0x93 +,0x2f,0xa1,0x4f,0x31,0xc5,0x0a,0x19,0x16,0x1e,0x11,0x7e,0x9d,0xac,0x9c,0x9c,0x8b,0xb5,0x27,0x3b,0x13,0x9b,0xab,0x2e,0x5c,0x17,0x10,0x27,0x88,0x87,0x8a,0xbb,0x1d +,0x40,0x15,0x19,0x27,0x21,0x98,0x13,0x02,0x09,0x02,0x1c,0x94,0x90,0x9d,0x2a,0x2b,0x8e,0x93,0x91,0x88,0x98,0x87,0x88,0x9c,0xe9,0x9c,0x10,0x0d,0x8c,0x15,0x90,0x84 +,0x98,0x8e,0xbe,0x0c,0x05,0x22,0x23,0x06,0x05,0x00,0x03,0x00,0x21,0x94,0x45,0xb3,0x13,0x1f,0x0f,0x09,0x20,0xae,0x83,0x96,0x2f,0x20,0x1b,0x1c,0x9c,0x82,0x8e,0x8e +,0x9b,0x96,0x8c,0x3b,0x99,0x8b,0x88,0x83,0x93,0x8f,0x8c,0x8e,0x16,0x90,0x82,0x81,0x3c,0x0b,0xd3,0x05,0x08,0x05,0x07,0xbb,0x1f,0x0d,0xa6,0x08,0x04,0x00,0x1e,0xb3 +,0x00,0x07,0x00,0x0c,0x02,0x13,0xbd,0x9d,0x84,0xb4,0x9e,0xac,0x92,0xaa,0x8e,0x83,0x85,0x85,0x9d,0x8d,0x88,0x94,0x90,0x96,0x88,0x80,0x8a,0x99,0x19,0x1f,0x0a,0x8a +,0x94,0x2b,0x1b,0x0c,0xa9,0x1d,0x1c,0x0b,0x08,0xa4,0x1a,0x0d,0x0c,0x00,0x00,0x04,0xa9,0xc0,0xd6,0x1d,0x07,0xbd,0x13,0x13,0xbc,0x9f,0x84,0x9a,0xa3,0x1b,0x13,0x09 +,0x99,0x80,0x83,0x81,0xa2,0x9b,0xbb,0x45,0x83,0x8e,0x8e,0x80,0x83,0x97,0x0e,0x11,0x1e,0x80,0x8e,0x9f,0x3f,0x10,0x0f,0x00,0x0a,0x0e,0x0a,0x19,0x09,0x03,0x00,0x07 +,0xf0,0x94,0x80,0x45,0x09,0x09,0x07,0x2c,0x06,0x10,0x1e,0xc1,0x80,0x8f,0x22,0x18,0x2c,0x94,0x81,0x88,0x89,0x8b,0x4b,0x4b,0x9f,0x98,0x5b,0x16,0x85,0x82,0x80,0x2f +,0x09,0x08,0x27,0x80,0x83,0x84,0x0e,0x04,0x0e,0x0e,0xbc,0x27,0xbb,0xa7,0x10,0xc4,0x04,0x01,0x00,0x03,0xac,0x87,0x3a,0x0a,0x15,0x04,0x09,0x27,0x85,0x8d,0x81,0x86 +,0x27,0x14,0x5f,0x0e,0x35,0x80,0x85,0x8b,0x09,0x00,0x9e,0x26,0x16,0x28,0x20,0x9e,0x8d,0x10,0x00,0x08,0x04,0x97,0x97,0x8e,0xbc,0x09,0x07,0x12,0x28,0x0b,0x29,0x8c +,0x8c,0x13,0x06,0x06,0x0a,0xab,0x84,0x80,0x8b,0x2e,0x14,0x2b,0x39,0x8e,0x84,0x93,0x84,0x9e,0x8f,0x27,0x1e,0xb1,0x95,0x80,0x8b,0x8d,0xa5,0x89,0x99,0xb7,0x96,0x85 +,0x89,0x8b,0x88,0x8b,0x15,0x00,0x0c,0xcc,0x80,0xbf,0x1a,0x0e,0x0e,0x02,0x09,0xaa,0x0c,0x1a,0x9e,0x2b,0x07,0x00,0x09,0x00,0x12,0x4a,0x19,0x29,0x01,0x05,0x00,0x03 +,0x0a,0x23,0x8c,0x87,0xae,0x00,0x05,0x05,0x21,0x89,0x80,0x81,0x8e,0x27,0x14,0x99,0x8f,0x80,0x81,0x81,0x90,0x8b,0x88,0x24,0xc8,0xbc,0x80,0x83,0x80,0x55,0x05,0xc9 +,0x91,0x22,0x1b,0x4e,0xbd,0xa9,0x00,0x09,0x00,0x13,0x08,0x1e,0x87,0x9e,0x19,0x00,0x0c,0x09,0x0f,0x94,0x92,0x99,0xa9,0x19,0xa9,0x15,0xa0,0x20,0xbf,0x80,0x83,0x80 +,0x8a,0xa7,0x0c,0x3d,0x86,0x82,0x80,0x86,0x82,0x3b,0x0e,0x87,0x52,0x90,0x84,0x82,0x9c,0x0b,0x08,0x04,0x0c,0x0a,0x4e,0x9a,0xb3,0x08,0x00,0x03,0x00,0x01,0x00,0xbd +,0x2b,0x00,0x03,0x00,0x05,0x00,0x0f,0x0c,0x2b,0x2b,0x05,0x03,0x09,0xd1,0x28,0x98,0x80,0x86,0x86,0x8a,0xad,0x89,0x8f,0x84,0x80,0x81,0x81,0x89,0x91,0x47,0x62,0xa7 +,0x8d,0x80,0x81,0x84,0x3a,0x1e,0x40,0x1b,0x9f,0x92,0x85,0x87,0xa5,0x0d,0x19,0x0b,0x12,0x92,0x80,0x8d,0x4e,0x18,0x00,0x08,0x04,0x0f,0x12,0x37,0x8e,0x24,0x07,0x00 +,0x03,0x03,0x10,0x94,0xa3,0xc9,0x09,0x04,0x06,0x07,0xe0,0x35,0xbb,0xc6,0x1a,0x16,0x06,0x10,0x65,0x91,0x86,0x86,0x99,0x18,0x10,0x27,0xa1,0x83,0x80,0x87,0x87,0x95 +,0x28,0x0d,0x16,0x16,0x9c,0x86,0x85,0x98,0x0c,0x0b,0x0e,0x04,0x0a,0xb3,0xa5,0x2f,0x1d,0x0b,0x03,0x06,0x02,0x11,0x93,0x89,0x9e,0x1f,0x09,0x03,0x55,0xb9,0x8f,0x81 +,0x89,0x86,0x89,0x9d,0x3f,0xa6,0x89,0x80,0x82,0x80,0x8f,0xa7,0xda,0x9a,0x85,0x82,0x89,0x9f,0x8e,0x9c,0x95,0xaf,0xd4,0xa9,0x99,0x83,0xb2,0x0e,0x03,0x00,0x03,0x30 +,0x8c,0x1d,0x07,0x0d,0x07,0x00,0x02,0x00,0x04,0x00,0x12,0x2e,0x0d,0x07,0x00,0x02,0x0b,0x11,0x18,0x2a,0x14,0x2b,0x0f,0x09,0x19,0x5d,0xa9,0x84,0x82,0x81,0x8c,0x17 +,0xdb,0x8b,0x81,0x80,0x84,0x84,0x83,0x81,0x90,0x38,0xba,0xa4,0x89,0x80,0x80,0xa5,0x1b,0x13,0x23,0x98,0xb8,0x18,0xe6,0x2c,0x1a,0x17,0x2b,0x0b,0x0e,0x8e,0x91,0x9e +,0x17,0x04,0x00,0x0a,0x28,0xa0,0x97,0xca,0xc5,0xad,0x1f,0x16,0x0c,0x08,0x3d,0x8e,0x8c,0xce,0x1b,0x0c,0x0d,0x12,0xb8,0x8f,0x96,0xa3,0x36,0x13,0x07,0x0f,0x11,0x2c +,0x8b,0x8f,0xc7,0x1d,0x06,0x15,0x19,0xa4,0x86,0x95,0x9a,0xb2,0x46,0x0d,0x0a,0x0e,0x56,0x95,0x8c,0x99,0x1a,0x17,0x0a,0x1c,0xa1,0xa1,0x30,0xc2,0x68,0x0d,0x11,0x1b +,0x4c,0x37,0x87,0x81,0x8c,0x24,0x05,0x13,0xf2,0x8e,0x87,0x87,0x90,0x87,0x9f,0x2e,0x13,0x2f,0x90,0x80,0x82,0x8b,0xa7,0x26,0x9f,0xb0,0x8a,0x86,0x86,0x83,0x8a,0x9c +,0x34,0x12,0x27,0xa8,0x96,0x85,0x93,0x24,0x02,0x03,0x04,0x0d,0x68,0x2a,0x2e,0x20,0x10,0x03,0x00,0x02,0x00,0x0c,0x2f,0x13,0x08,0x00,0x06,0x06,0x2b,0x23,0x12,0x44 +,0x11,0x17,0x06,0x10,0xdd,0xa8,0x82,0x83,0x81,0x9a,0x17,0x9e,0xa1,0x8c,0x80,0x85,0x81,0x85,0x94,0x9e,0xc4,0x32,0x8f,0x80,0x84,0x86,0x49,0x07,0x1c,0x1a,0x2f,0x99 +,0xab,0x74,0x46,0xe2,0x0d,0x02,0x0f,0x2f,0x82,0x82,0x85,0x2e,0x09,0x1d,0x13,0x94,0x90,0x8e,0x82,0x84,0x8d,0x19,0x04,0x0d,0xd6,0x85,0x8b,0x31,0x0c,0x0e,0x0c,0x12 +,0x25,0x27,0x2d,0x13,0x18,0x03,0x00,0x00,0x02,0x78,0x9c,0xc5,0x0f,0x00,0x0c,0x1e,0x22,0x94,0x8e,0x8e,0x90,0x99,0x38,0x0d,0x0c,0x9a,0x80,0x86,0x8f,0x16,0x04,0x12 +,0x2a,0x4b,0xaa,0x8b,0x8c,0x95,0xd4,0x06,0x06,0x15,0x8a,0x82,0x89,0x9b,0x1e,0xbe,0x39,0xa9,0xc6,0xa0,0x93,0x8d,0x8e,0x21,0x18,0x68,0x8a,0x87,0x83,0x9d,0x1b,0x37 +,0xa4,0xb9,0x9a,0x93,0x8c,0x85,0x8b,0x9d,0x1d,0x2e,0x89,0x8d,0x9a,0xa8,0x24,0x39,0x67,0x93,0x4b,0x9f,0x34,0xae,0xc7,0x04,0x03,0x06,0x28,0xa3,0x1f,0x01,0x02,0x03 +,0x01,0x0c,0x18,0x02,0x14,0x0e,0x13,0x0b,0x03,0x08,0xae,0x8e,0x3d,0x19,0x00,0x0f,0x25,0xb2,0x8e,0xac,0xa1,0x98,0xd6,0x0d,0x0c,0x1e,0x8e,0x80,0x88,0x9d,0x35,0x39 +,0x97,0x84,0x89,0x84,0x82,0x88,0x96,0x0e,0x06,0x5f,0x80,0x83,0x80,0xa8,0x13,0xb4,0x19,0x3f,0x9d,0x9e,0x85,0x88,0x1d,0x08,0x04,0x1e,0x81,0x86,0x9d,0x37,0x11,0x17 +,0x2b,0x1c,0x22,0x9a,0x8d,0xa1,0x13,0x07,0x00,0x3a,0x9c,0xaf,0x29,0x01,0x29,0x1f,0x18,0x20,0x07,0x0e,0x33,0x08,0x00,0x04,0x02,0x8f,0x8b,0xbb,0x21,0x0e,0x28,0x96 +,0xaa,0x10,0xef,0xc9,0x9b,0x9e,0x14,0x11,0x8d,0x82,0x88,0xae,0x00,0x12,0x2b,0x98,0x8b,0xaa,0x99,0x87,0x92,0x1b,0x0f,0x19,0x86,0x80,0x83,0xbb,0x09,0x17,0xa6,0x87 +,0xab,0x90,0x9c,0x2e,0x11,0x02,0x02,0xaa,0x80,0x81,0x85,0x11,0x17,0x61,0xb4,0x97,0x8e,0x88,0x83,0x85,0xad,0x2c,0x9c,0x82,0x80,0x85,0x1e,0x14,0x22,0x20,0xa9,0x13 +,0xcb,0x8c,0xa5,0x18,0x07,0x00,0x1b,0xaf,0x10,0x07,0x00,0x06,0x15,0x2e,0x07,0x08,0x09,0x0b,0x07,0x01,0x00,0x0e,0xa5,0xa2,0xc9,0x00,0x0d,0x18,0x1d,0x32,0x12,0x19 +,0x59,0x24,0x0d,0x0b,0xb3,0x81,0x81,0x86,0x23,0x36,0x47,0x9c,0x87,0x8d,0x82,0x80,0x84,0x95,0x0f,0x16,0x82,0x83,0x84,0x38,0x09,0x23,0xa9,0x95,0x9e,0x89,0x8b,0x89 +,0xe0,0x04,0x06,0x90,0x82,0x80,0x8e,0x25,0xa3,0xc4,0xaa,0x39,0x10,0x26,0xa5,0x14,0x07,0x04,0x39,0x8b,0x95,0x15,0x00,0x07,0x0c,0x56,0x13,0x0b,0x15,0x24,0x15,0x0d +,0x00,0x1d,0x8b,0x9b,0x34,0x03,0x07,0x0f,0xaf,0xb2,0xaa,0x96,0x98,0xd8,0x0c,0x00,0x17,0x8e,0x8e,0x8d,0x19,0x1d,0xc6,0xf2,0x19,0x11,0x3a,0x8f,0x8f,0x4a,0x0b,0x2d +,0x83,0x83,0x82,0x36,0x4c,0xbb,0xa0,0x9b,0xc3,0xa6,0x8b,0x8d,0xaf,0x1c,0x1b,0x8e,0x8f,0x9c,0x08,0x0e,0x0f,0x21,0xab,0x3b,0x8d,0x82,0x8b,0xa0,0x20,0x3c,0x80,0x83 +,0x87,0x43,0x46,0x9a,0x86,0x8c,0x39,0x9f,0xa0,0x9b,0x37,0x06,0x0d,0x8d,0x92,0x92,0x0e,0x00,0x0d,0x12,0x1a,0x11,0x1c,0x28,0x54,0x08,0x01,0x03,0x58,0x9d,0x9f,0x0a +,0x02,0x0e,0x0a,0x24,0x0f,0x31,0x8c,0x87,0x31,0x0d,0x00,0xc4,0x88,0x89,0xb2,0x2c,0x99,0x90,0x84,0x4f,0x3e,0xa4,0x9a,0xa1,0x78,0x0a,0x95,0x8c,0x9c,0xa7,0x0f,0xb5 +,0x99,0x91,0x28,0x25,0x13,0x25,0x1b,0x0e,0x14,0x8d,0x87,0x8d,0xb5,0x03,0xca,0xb6,0x91,0x98,0x9f,0x96,0x88,0xb3,0x16,0x0a,0x30,0x85,0x84,0x92,0x0f,0x28,0x0d,0xe3 +,0x3e,0x43,0x8e,0x8b,0xaf,0x1c,0x05,0x16,0x88,0x99,0xa0,0x0f,0x20,0x34,0xa8,0x17,0x14,0xe1,0xab,0x9c,0x1d,0x06,0x26,0x88,0xa2,0xb5,0x00,0x10,0xa4,0x94,0x9e,0x27 +,0x1e,0xb0,0x9e,0x10,0x09,0x08,0x9a,0x91,0x9b,0x07,0x09,0x0f,0x1e,0x9a,0x28,0xa7,0x94,0xb2,0x0e,0x08,0x02,0x8e,0x84,0x87,0xad,0x19,0x62,0x9d,0x8d,0x2d,0x98,0x97 +,0x8e,0xc1,0x07,0x03,0x90,0x85,0x84,0x99,0x12,0x9b,0xa0,0x99,0x3c,0x33,0x6b,0x8b,0xa4,0x1e,0x14,0x98,0x82,0x82,0x8e,0x27,0x92,0xeb,0x8f,0x92,0x9a,0x87,0x85,0xab +,0x2f,0x0d,0xca,0x82,0x9b,0x40,0x02,0x0a,0x09,0x2b,0x0b,0x0d,0xe6,0xd1,0x26,0x08,0x00,0x1a,0x85,0x97,0x90,0x10,0x28,0x96,0x99,0x26,0x11,0x2f,0x98,0x9d,0x05,0x01 +,0x02,0x22,0x19,0x1f,0x02,0x0f,0x17,0x0c,0x1a,0x05,0x10,0xce,0xdb,0x0e,0x09,0x02,0x9e,0x91,0x97,0x37,0x5d,0x98,0x90,0x85,0xa8,0x8c,0x89,0x8a,0x97,0x2f,0x30,0x81 +,0x81,0x80,0x8b,0xcd,0x86,0x86,0x8a,0xba,0xa3,0x96,0x86,0x9a,0x14,0x0b,0x99,0x82,0x81,0x9b,0x04,0x2d,0x14,0x2f,0x0c,0x06,0x3a,0x97,0x26,0x0a,0x02,0x0c,0xb2,0x20 +,0x1e,0x02,0x0f,0x0c,0xc4,0x43,0x20,0x92,0x8a,0x87,0x89,0xb9,0xba,0x86,0xab,0x92,0x15,0x1b,0xd5,0xae,0x29,0x07,0x08,0x0c,0x1d,0x04,0x01,0x02,0x5f,0xaa,0xa4,0x07 +,0x08,0x2d,0xb4,0x93,0x1b,0x17,0x50,0xa1,0x2d,0x15,0x0c,0x8c,0x82,0x82,0xbc,0x0e,0x2c,0xbe,0x89,0xe4,0x9e,0x8f,0x8a,0x8f,0xcc,0x11,0x92,0x82,0x85,0x89,0x23,0xac +,0xaf,0x93,0xaa,0xa6,0x97,0x88,0x89,0xa9,0x21,0xb0,0x87,0x8d,0x99,0x08,0x26,0x1a,0x39,0x1c,0x07,0x0c,0x0e,0x1b,0x19,0x0d,0x06,0x44,0x1c,0x49,0x0f,0x25,0xa3,0x8c +,0x84,0x8e,0x86,0x88,0x85,0x8c,0xa8,0x2b,0x88,0x90,0x9a,0x0f,0x00,0x0f,0x19,0xca,0x11,0x10,0x10,0x12,0x01,0x01,0x00,0x0f,0x9a,0x92,0x35,0x00,0x06,0x09,0xcc,0x39 +,0x1b,0x1f,0xd8,0x33,0x1f,0x0c,0x26,0x84,0x86,0x80,0xad,0xac,0xaa,0xa4,0xae,0x4b,0x8d,0x85,0x81,0x8c,0x2e,0x18,0x8c,0x87,0x84,0x50,0x18,0xbd,0xa7,0x94,0x32,0x22 +,0x47,0x94,0xa4,0xb8,0x08,0x17,0xb0,0xaa,0x33,0x07,0x1a,0x22,0x98,0x49,0x1e,0x2d,0xa7,0x94,0x9d,0x1f,0x51,0x86,0x83,0x82,0xaf,0xb7,0x9f,0x8a,0x89,0x98,0x9e,0x99 +,0xab,0x08,0x02,0x00,0x1d,0xe0,0x32,0x0a,0x00,0x04,0x0a,0x1c,0x08,0x12,0x21,0xaa,0x24,0x0b,0x00,0x0f,0x9c,0x8d,0x8d,0x1e,0x27,0x17,0x3b,0x16,0x25,0xb2,0x8d,0x8a +,0xbf,0x16,0x10,0x8c,0x88,0x84,0xe5,0x4d,0xb4,0x9e,0x9c,0x34,0x9c,0x8e,0x82,0x8c,0xbc,0x0e,0x97,0x8a,0x89,0xb0,0x12,0xa3,0x92,0x87,0x40,0x1e,0x3f,0x89,0x96,0x10 +,0x00,0x06,0xaf,0x93,0xa7,0x03,0x04,0x0d,0xa6,0xa4,0xfe,0xac,0x8b,0x86,0x9f,0x24,0x50,0x81,0x82,0x80,0x96,0xac,0xb8,0xa8,0xa7,0x19,0x21,0x7a,0x99,0x19,0x05,0x00 +,0x07,0x1f,0xc3,0x1d,0x02,0x06,0x09,0x13,0x06,0x05,0x0e,0xa6,0x9b,0x18,0x00,0x02,0x9f,0x86,0x83,0x4b,0x1e,0xdc,0x99,0x8c,0xbb,0xb0,0x90,0x85,0x8a,0x4e,0x0a,0x9f +,0x83,0x82,0x91,0x17,0x23,0xb7,0x95,0xe6,0x2f,0xa7,0x8a,0x93,0x1c,0x00,0x0d,0x8f,0x8b,0x8b,0x14,0x10,0x16,0x1d,0x2f,0x17,0xc7,0xa2,0x9e,0x11,0x03,0x02,0xa3,0x81 +,0x80,0x8a,0xd5,0xa1,0x93,0x81,0x89,0x8d,0x88,0x83,0x84,0x9f,0x06,0x0b,0xb3,0x97,0x93,0x07,0x03,0x01,0x05,0x09,0x06,0x0c,0x1b,0x37,0x0b,0x03,0x00,0x3e,0x94,0x8b +,0x55,0x08,0x12,0x16,0xcd,0x1e,0x1f,0x33,0xa3,0xf7,0x12,0x01,0x17,0x8e,0x84,0x8d,0x16,0x0e,0x10,0xa7,0x99,0xa7,0x9a,0x91,0x8b,0x93,0x27,0x1b,0x8d,0x85,0x80,0x8d +,0x37,0x13,0x1e,0x8d,0x8a,0x8e,0x9f,0xa6,0xb0,0x1a,0x03,0x0e,0xb5,0x8a,0x8e,0x0d,0x05,0x01,0x1c,0xb7,0x3f,0x56,0xab,0x94,0xa1,0x1d,0x20,0x87,0x81,0x80,0x89,0x97 +,0xa6,0x95,0x83,0x8e,0x8f,0x9b,0x92,0xa3,0x0e,0x00,0x0b,0x24,0x9d,0x4b,0x00,0x03,0x00,0x16,0x1f,0x16,0x0b,0x08,0x10,0x0b,0x03,0x02,0x1c,0xb1,0x89,0x1b,0x0b,0x07 +,0x2b,0x88,0x95,0x98,0xbc,0x99,0x94,0x9f,0x2b,0x95,0x87,0x81,0x8b,0x34,0x19,0x1e,0x8b,0x98,0xb2,0x3e,0xa5,0x8e,0xbf,0x08,0x0b,0x92,0x83,0x81,0x2c,0x0b,0x09,0xbd +,0x89,0x9d,0xb0,0x26,0xac,0x4f,0x0f,0x03,0x1c,0xaf,0x8d,0x9d,0x17,0x16,0x14,0x90,0x8e,0x8d,0x8f,0x8b,0x85,0x8d,0xb1,0xd2,0x8c,0x87,0x82,0xa5,0x24,0x0c,0x18,0x27 +,0x0c,0x0f,0x07,0x0f,0x0b,0x02,0x00,0x0c,0x22,0x93,0xf3,0x04,0x0a,0x0c,0xaa,0x47,0x1a,0x11,0x1e,0x54,0x36,0x0f,0x0e,0xa4,0x8e,0x84,0xcd,0x1e,0x10,0x3d,0x95,0x59 +,0xab,0xef,0xa6,0x9a,0x4e,0x19,0xad,0x90,0x84,0x83,0x9f,0x36,0x13,0xa2,0x8c,0x87,0x8c,0x96,0xb1,0x21,0x1c,0x2f,0x9f,0xa2,0x98,0x16,0x0c,0x05,0x0d,0x33,0x0f,0x16 +,0x11,0x30,0x74,0x1b,0x0a,0x45,0x8a,0x83,0x80,0x8b,0x8e,0x90,0x84,0x83,0x83,0x88,0x94,0x98,0x48,0x0d,0x07,0x15,0x33,0x9a,0x13,0x01,0x02,0x01,0x0d,0x0d,0x0d,0x09 +,0x09,0x0b,0x0d,0x06,0x0f,0x4e,0x9b,0x8e,0x51,0x1b,0x0b,0x19,0xd9,0xb9,0x9b,0xac,0xa5,0xc3,0x21,0x19,0xac,0x8d,0x82,0x8a,0x34,0x25,0x18,0x95,0x8d,0x90,0x93,0xa1 +,0x94,0xb1,0x26,0x1d,0x93,0x88,0x87,0xa7,0x21,0x27,0x3b,0x9d,0xed,0xae,0x54,0xaa,0xc6,0x16,0x09,0x11,0xbd,0x99,0x8d,0x1f,0x19,0x0b,0x23,0x9e,0x95,0x89,0x99,0x8e +,0x99,0x96,0xa1,0x8c,0x86,0x82,0x86,0xa3,0xa9,0x14,0x2d,0x19,0x1e,0x1f,0x0c,0x07,0x01,0x03,0x06,0x36,0xbf,0xa4,0x16,0x0b,0x10,0x08,0x19,0x0d,0x21,0x2c,0x23,0x20 +,0x0c,0x04,0x14,0x93,0x8b,0x87,0xc0,0x23,0x15,0x26,0x9e,0x99,0x8a,0x9a,0x8f,0xbe,0x38,0x24,0x70,0x8f,0x8d,0x89,0xab,0xae,0x23,0x52,0xad,0x9e,0x8a,0x95,0x8d,0xa6 +,0x38,0x26,0xb9,0x8e,0x8e,0x8c,0xa1,0xa5,0x25,0x25,0xe3,0x9f,0x96,0x34,0x1a,0x07,0x0c,0x0a,0x1a,0x29,0x2e,0xab,0xad,0xa9,0x20,0x24,0x1c,0xc6,0xaf,0xbe,0x5e,0x16 +,0x1a,0x1e,0x9f,0x98,0x8f,0x9a,0x4d,0x28,0x0b,0x13,0x16,0x29,0x3c,0x1f,0x16,0x17,0x1f,0x18,0xa8,0xaa,0x9d,0xa7,0x21,0x1e,0x11,0xcb,0x9c,0x8a,0x92,0xd4,0x4d,0x1f +,0x40,0x20,0xc2,0xb8,0x98,0x99,0x30,0x2f,0x0e,0xad,0x95,0x8c,0x95,0x30,0x5d,0x4b,0x99,0xb7,0x9d,0x91,0x8b,0x83,0x8d,0x95,0x2d,0xc1,0x96,0x95,0x8f,0xac,0xb1,0x1c +,0x1b,0x0e,0x0f,0x54,0xb3,0x9e,0x21,0x20,0x10,0x17,0x1d,0x14,0x2e,0x12,0x43,0x25,0x1e,0x17,0x09,0xb4,0xc0,0x95,0xa5,0xab,0xe1,0x19,0x1f,0x09,0x13,0x15,0xec,0x98 +,0xa7,0x9a,0x1f,0x34,0xc6,0xac,0x94,0x63,0xaa,0x1a,0x2c,0x19,0x1f,0x9d,0x9b,0x93,0x39,0x2b,0x1a,0x0d,0x2e,0x1f,0xba,0xd3,0x65,0xad,0x25,0xaf,0x33,0x98,0x8d,0x8e +,0x8c,0x9a,0xa5,0x71,0x3b,0x94,0x8a,0x81,0x8b,0x90,0xaa,0x4a,0x98,0x96,0x8d,0x9a,0xa3,0x39,0x1c,0x24,0x13,0x1b,0xaa,0x8f,0x8c,0x52,0xee,0x0a,0x19,0x2a,0x24,0x38 +,0x15,0x1a,0x09,0x0c,0x53,0xb5,0x00,0x37,0x87,0x56,0x15,0x07,0x02,0x00,0x02,0x04,0x0f,0x21,0x00,0x16,0x0e,0x00,0x0d,0x07,0x18,0x0e,0x1d,0x17,0x13,0x08,0x0a,0x18 +,0x0e,0x13,0x09,0x0d,0x1d,0x95,0x8f,0xa1,0xad,0x99,0x80,0x82,0x8a,0x88,0x84,0x80,0x80,0x80,0x81,0x81,0x83,0x84,0x83,0x84,0x87,0x84,0x80,0x80,0x80,0x83,0x86,0x94 +,0x8f,0x8c,0x89,0x87,0x95,0xb5,0x1c,0x1a,0x0b,0x05,0x0b,0x0e,0x12,0x21,0x0b,0x08,0x05,0x04,0x09,0x04,0x09,0x02,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x01,0x05,0x05 +,0x02,0x00,0x00,0x02,0x01,0x03,0x05,0x07,0x04,0x23,0xac,0x3f,0x21,0x2a,0x9b,0x8f,0x91,0x96,0x9d,0x9b,0x8e,0x8c,0x8e,0x92,0x8d,0x96,0x91,0x85,0x83,0x81,0x80,0x80 +,0x80,0x80,0x81,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x83,0x88,0x8a,0x84,0x83,0x80,0x80,0x80,0x8a,0xa2,0x9e,0xac,0x8d,0x87,0x8a,0x9b,0x2e,0x3f,0x23,0x0d +,0x1e,0x28,0xde,0xa5,0x2e,0x1e,0x09,0x0e,0x11,0x15,0x16,0x0a,0x03,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x02,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x04 +,0x0a,0x07,0x07,0x07,0x09,0x21,0x1f,0x1c,0x0d,0x07,0x0a,0x0f,0x1e,0x13,0x08,0x04,0x02,0x06,0x0a,0x1f,0xa6,0xa5,0x94,0x9e,0xad,0x29,0x20,0xa0,0x8a,0x80,0x81,0x80 +,0x84,0x8b,0x87,0x8c,0x8c,0x82,0x83,0x80,0x80,0x80,0x81,0x87,0x86,0x86,0x83,0x81,0x81,0x81,0x85,0x85,0x89,0x94,0x87,0x83,0x83,0x83,0x85,0x82,0x8d,0x8f,0x89,0x86 +,0x84,0x8c,0x9c,0x20,0x12,0x1c,0x12,0x3a,0x39,0x6a,0x2c,0x0f,0x1a,0x0d,0x10,0x17,0x2e,0xbb,0x2a,0x21,0x1b,0x2d,0x99,0x9a,0x8b,0x88,0x86,0x85,0x8d,0x89,0x9b,0x95 +,0x8e,0x8d,0x89,0x96,0xa9,0x2e,0x1a,0x1e,0x0f,0x3d,0x97,0x8c,0x85,0x9b,0xae,0x14,0x0f,0x17,0x1b,0xc7,0xd0,0xe8,0x1b,0x05,0x03,0x00,0x02,0x07,0x0a,0x0d,0x03,0x02 +,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x04,0x02,0x05,0x02,0x01,0x01,0x01,0x08,0x0b,0x18,0x16,0x09,0x08,0x00,0x02,0x00,0x04,0x12,0x16,0x25 +,0x0b,0x04,0x04,0x03,0x0e,0x0f,0x1f,0x30,0x1f,0x2d,0x29,0xb5,0x99,0x89,0x80,0x81,0x80,0x81,0x80,0x82,0x83,0x80,0x80,0x80,0x80,0x80,0x81,0x85,0x85,0x86,0x89,0x82 +,0x81,0x80,0x80,0x80,0x84,0x90,0x8a,0x87,0x85,0x80,0x82,0x80,0x84,0x84,0x89,0x93,0x85,0x84,0x80,0x84,0x8a,0x8b,0x8c,0x82,0x81,0x81,0x81,0x86,0x87,0x8d,0x9a,0x9e +,0xa7,0x88,0x86,0x84,0x8e,0x36,0x18,0x03,0x09,0x0b,0x0e,0x16,0x09,0x06,0x02,0x00,0x00,0x00,0x01,0x01,0x04,0x04,0x01,0x01,0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x01 +,0x00,0x01,0x00,0x05,0x09,0x1b,0x40,0x0f,0x0f,0x03,0x07,0x0e,0x11,0x3a,0x2e,0xc3,0xbd,0x16,0x0e,0x03,0x0d,0x44,0x94,0x83,0x8b,0x8a,0xaa,0xb4,0x98,0x9a,0x88,0x88 +,0x87,0x89,0x95,0x90,0x9a,0x8c,0x84,0x85,0x82,0x8b,0x8d,0xae,0xe1,0x96,0x8f,0x85,0x8a,0x96,0x9f,0x24,0x2a,0x11,0x1d,0xa5,0x9c,0x88,0xaa,0x44,0x17,0x0d,0xbf,0xb2 +,0x90,0x8e,0x98,0x8e,0xbe,0x45,0x10,0x10,0xb0,0xb0,0x8e,0xb1,0x2e,0x17,0x04,0x0b,0x09,0x16,0x28,0x16,0x14,0x04,0x01,0x01,0x02,0x15,0x2b,0x8f,0x92,0x9c,0xb2,0x16 +,0x4e,0x9f,0x8b,0x83,0x8b,0x8c,0xbe,0x20,0x11,0x07,0x46,0xc8,0x8f,0x97,0x3e,0x29,0x0b,0x21,0x26,0x2b,0xd3,0x1d,0x34,0x1d,0x20,0x32,0x25,0x8c,0x8b,0x84,0x8a,0x94 +,0x8f,0xa3,0x89,0x83,0x82,0x80,0x82,0x80,0x8a,0x91,0x92,0xa1,0x87,0x82,0x81,0x81,0x89,0x8e,0x24,0x1a,0x1f,0x20,0xa7,0x3f,0xdd,0x27,0x0b,0x0c,0x00,0x0a,0x0c,0x17 +,0x24,0x0a,0x09,0x01,0x03,0x07,0x08,0x19,0x0d,0x08,0x07,0x00,0x02,0x00,0x04,0x0a,0x28,0x9e,0x3e,0x3e,0x0f,0x13,0x58,0xb4,0x8b,0x8b,0x8e,0x91,0xdf,0xbf,0x17,0x45 +,0x99,0x94,0x88,0x9a,0x92,0x9f,0x9f,0x89,0x8b,0x84,0x8d,0xa2,0xa8,0x1f,0xb8,0x41,0x9e,0x84,0x87,0x80,0x8e,0x96,0x5c,0x1b,0xb6,0xb5,0x95,0x94,0xbd,0xac,0x1b,0x1c +,0x09,0x06,0x18,0x14,0xb4,0x26,0x1b,0x0f,0x07,0x18,0x17,0x2e,0x4f,0x1f,0x56,0x1e,0x23,0x14,0x0f,0xaf,0xb6,0x8e,0xa5,0x2b,0x18,0x07,0x16,0x16,0x24,0x6d,0x1c,0x1b +,0x09,0x05,0x05,0x01,0x14,0x16,0xa5,0xa0,0xa3,0x98,0xd1,0x95,0x8e,0x89,0x82,0x89,0x89,0x9a,0xa1,0xa3,0x2b,0x95,0x9a,0x8d,0x94,0x33,0x2d,0x0d,0x24,0x57,0x3e,0xad +,0x1a,0x1b,0x11,0x0b,0x0f,0x04,0x29,0xe6,0x91,0x8b,0x9a,0x92,0xcc,0x9e,0x93,0x91,0x86,0x8b,0x8a,0x8d,0x95,0x8d,0xa1,0x8c,0x8a,0x87,0x84,0x8e,0x8e,0x51,0x48,0xb3 +,0x7a,0x97,0xaf,0xd0,0x2c,0x0f,0x17,0x06,0x17,0x23,0x34,0xe2,0x0f,0x0e,0x04,0x06,0x0d,0x0a,0x16,0x0e,0x09,0x0a,0x01,0x04,0x00,0x03,0x05,0x0e,0x32,0x19,0x2c,0x18 +,0x1b,0xac,0xaf,0x8e,0x8e,0x93,0x90,0xcb,0xa3,0x3c,0xab,0x90,0x91,0x88,0x98,0x97,0xac,0xba,0x92,0x95,0x88,0x88,0x91,0x95,0x49,0xa7,0xd9,0xa2,0x8a,0x8d,0x83,0x8b +,0x88,0x92,0xa8,0x95,0xa9,0x97,0x9c,0x42,0xc7,0x1a,0x2c,0x12,0x0e,0x25,0x1c,0xb4,0x1f,0x1d,0x11,0x08,0x20,0x20,0xbe,0xab,0x25,0x33,0x0d,0x11,0x0c,0x0d,0xc0,0xbc +,0x90,0xb9,0x3e,0x1b,0x09,0x18,0x13,0x25,0x52,0x1b,0x1f,0x0a,0x08,0x05,0x03,0x0f,0x0f,0x4c,0x26,0x2e,0x6e,0x34,0x96,0x8e,0x87,0x84,0x8f,0x8f,0xb2,0xae,0xbe,0xbc +,0x8b,0x8e,0x86,0x9a,0xc9,0x28,0x0f,0x29,0x2c,0x56,0xa9,0x2e,0x35,0x16,0x18,0x18,0x14,0xb2,0xcf,0x94,0x9f,0x9f,0x96,0xa6,0x8d,0x8f,0x8e,0x89,0x95,0x91,0xa2,0x9e +,0xa1,0xaf,0x8a,0x8b,0x83,0x8a,0x91,0x9c,0x2f,0xac,0x9d,0x93,0x88,0x94,0x97,0x43,0x1d,0x15,0x0b,0x32,0x2b,0xab,0x2e,0x11,0x0f,0x04,0x0d,0x0f,0x13,0x1a,0x09,0x08 +,0x03,0x01,0x02,0x00,0x07,0x06,0x0f,0x0a,0x06,0x0b,0x07,0x1e,0x48,0xab,0x8e,0x99,0x8e,0x9b,0x9e,0xa5,0xc0,0x8d,0x91,0x88,0x8f,0x9a,0x98,0x5a,0x9d,0x9a,0x97,0x8d +,0xa0,0x9e,0xf3,0xce,0xbd,0x5a,0x8f,0x8f,0x86,0x8b,0x93,0x97,0xb4,0x90,0x89,0x88,0x84,0x8e,0x8f,0xa9,0xbf,0x2a,0x16,0xc0,0xed,0x9d,0x3f,0x1b,0x15,0x0a,0x1a,0x1d +,0x2b,0xc5,0x3a,0x4c,0x13,0x0c,0x08,0x07,0x1d,0x1f,0xad,0x2f,0x29,0x3d,0x1b,0x46,0x34,0xca,0xa6,0x44,0x3f,0x15,0x16,0x0f,0x09,0x15,0x0f,0x22,0x11,0x0d,0x0f,0x06 +,0x17,0x28,0xc3,0xa3,0xda,0xb3,0xc4,0xa3,0xa8,0xb1,0x92,0x92,0x87,0x8b,0x8e,0x90,0xb7,0x9e,0xa8,0x9b,0x92,0x9a,0x9c,0x43,0x2d,0x18,0x15,0x2d,0x28,0xae,0x31,0x22 +,0x28,0x10,0x3c,0xce,0x9a,0x8e,0x9c,0x9d,0x75,0xb7,0xce,0x65,0x9a,0x96,0x86,0x88,0x8c,0x8a,0x99,0x89,0x86,0x86,0x84,0x8e,0x8f,0x9c,0x9f,0xb9,0x21,0x26,0x18,0x24 +,0x1a,0x0c,0x0f,0x05,0x0c,0x0e,0x0f,0x1b,0x0f,0x0c,0x07,0x05,0x04,0x04,0x08,0x0a,0x0e,0x0e,0x08,0x0b,0x05,0x0a,0x0e,0x11,0x24,0x23,0x2f,0x38,0x50,0x66,0xd9,0xae +,0xa5,0x92,0x8d,0x91,0x91,0x9e,0x9d,0x96,0x94,0x8d,0x8e,0x8f,0x93,0x91,0x92,0x97,0x9a,0x9e,0x91,0x90,0x99,0x9e,0x3e,0x3f,0xae,0x9a,0x8d,0x8d,0x8f,0x92,0x94,0x9d +,0xae,0xb8,0xdb,0xaa,0xa7,0xc7,0xf6,0x1f,0x28,0x38,0x32,0x5f,0x4c,0x68,0xeb,0xe2,0x25,0x19,0x17,0x0e,0x1b,0x23,0x1a,0x13,0x09,0x08,0x0d,0x14,0x1e,0x29,0x27,0x28 +,0x58,0x39,0x29,0x24,0x17,0x20,0x2a,0x20,0x1e,0x13,0x0f,0x17,0x1d,0x1e,0x1e,0x22,0x2d,0xcf,0xad,0xa8,0xa5,0xb4,0xa6,0x9e,0x96,0x8d,0x92,0x95,0x98,0xa4,0xa4,0x9b +,0x97,0x93,0x8e,0x97,0xdb,0x29,0x26,0x48,0xa4,0x9f,0xbb,0x2d,0x2a,0x39,0x2f,0x3d,0x32,0x60,0xa0,0x9d,0xb5,0xb6,0xae,0xaa,0x8e,0x88,0x84,0x8f,0xa3,0x5c,0xcd,0x8c +,0x87,0x89,0x8d,0xa8,0x25,0x35,0xb6,0x3f,0x38,0x1b,0x16,0x43,0x2e,0x26,0x0f,0x10,0x0d,0x12,0x1d,0x2b,0x19,0x0c,0x0c,0x0a,0x23,0x2c,0x53,0x1d,0x16,0x11,0x18,0x1d +,0x34,0x3d,0x18,0x27,0xcc,0x8c,0x92,0xa5,0x24,0x13,0x1c,0x1f,0xd4,0x3a,0xeb,0xae,0xd1,0x4e,0xbf,0xa0,0xa5,0xa7,0xb5,0x25,0x2c,0x4a,0x3c,0x26,0x22,0x41,0xad,0x96 +,0xb3,0x1e,0x38,0xa4,0x92,0x89,0x8c,0x93,0xaf,0xc8,0xa8,0x9b,0x8f,0x97,0xaf,0x4c,0x27,0x31,0x9c,0x9c,0xab,0xe6,0x32,0x27,0xbd,0xa9,0x4e,0x33,0x2f,0x3a,0x56,0xb1 +,0x46,0x32,0x29,0x2d,0x49,0xae,0xbd,0xdc,0xb3,0xac,0xaa,0xb8,0xae,0x2f,0x15,0x11,0x15,0x35,0xa3,0xbc,0x28,0x15,0x12,0x20,0x43,0x33,0x1a,0x1b,0x1a,0x14,0x13,0x1b +,0x2c,0x43,0xd8,0x47,0x1f,0x26,0x25,0x2c,0x2c,0x46,0x9e,0x8f,0x8e,0xdb,0x2c,0x2f,0x3a,0xc2,0xc6,0x38,0x33,0x2e,0x29,0x3e,0xb0,0x9c,0x94,0x92,0xaa,0xdb,0xac,0x91 +,0x8e,0x93,0x9f,0xdd,0xa8,0x8f,0x8d,0x91,0x9a,0x9a,0x95,0x90,0x90,0x9b,0x91,0x92,0x9d,0x9f,0xaa,0x60,0x3f,0x31,0x1e,0x26,0x5f,0x36,0x1e,0x11,0x12,0x2a,0xd9,0x4e +,0x20,0x13,0x1f,0x4a,0x39,0x1a,0x0d,0x14,0x28,0xc5,0x33,0x1c,0x17,0x0e,0x13,0x31,0x9d,0x9c,0x35,0x14,0x09,0x0e,0xf8,0x8f,0x8d,0xc4,0x14,0x0d,0x24,0xa4,0xa2,0xa6 +,0xbb,0x6c,0x49,0x2b,0x2f,0x41,0xe9,0xbf,0xce,0xcc,0xb3,0xa6,0xb9,0xc1,0xa2,0x93,0x89,0x86,0x86,0x8d,0x9e,0x91,0x88,0x8a,0x9a,0xdf,0x44,0x32,0x2a,0x20,0x25,0x3e +,0x19,0x0c,0x0a,0x0d,0x0f,0x0a,0x08,0x02,0x01,0x05,0x0d,0x13,0x0c,0x0b,0x0d,0x0f,0x15,0x16,0x25,0xa8,0x98,0x8f,0x8f,0x93,0x96,0x97,0x95,0x97,0x90,0x8c,0x8d,0x97 +,0xb9,0xd0,0xa1,0x8d,0x87,0x8d,0x9f,0x47,0xd9,0xa6,0x9d,0x9a,0xa3,0xab,0xb7,0xb6,0xa7,0xa3,0x96,0x91,0x9d,0xb6,0xbb,0xa5,0xb4,0xd3,0x39,0x3e,0xbf,0xaf,0xb4,0x22 +,0x16,0x18,0x1c,0x22,0x2a,0x1d,0x19,0x15,0x11,0x17,0x1e,0x28,0x26,0x1e,0x15,0x18,0x25,0xc7,0xc7,0x24,0x16,0x17,0x3f,0x9d,0x9d,0xa9,0xa7,0xb7,0x51,0xd0,0xae,0xab +,0xa5,0xc4,0x33,0xaf,0xaa,0x62,0xf6,0xde,0x2e,0x25,0xde,0xbd,0x2d,0x14,0x0d,0x1f,0xa9,0x9e,0xdd,0x21,0x1f,0x1b,0x30,0x9f,0x9c,0x9f,0xb5,0x46,0x47,0x99,0x8c,0x89 +,0x86,0x8a,0x94,0x90,0x87,0x86,0x85,0x89,0x8e,0x8b,0x84,0x83,0x87,0x90,0xa8,0xc4,0xbe,0xc4,0x2a,0x10,0x0a,0x06,0x0b,0x17,0x15,0x0f,0x07,0x03,0x04,0x0b,0x17,0x11 +,0x09,0x02,0x01,0x08,0x1b,0x31,0x13,0x07,0x04,0x07,0x12,0x22,0x24,0x16,0x0e,0x0f,0x1d,0x44,0x51,0x41,0x26,0x24,0x36,0xa9,0x9c,0x9f,0xb3,0x55,0xaf,0x95,0x88,0x86 +,0x8c,0x94,0x92,0x89,0x85,0x83,0x87,0x95,0xaa,0x9f,0x8c,0x87,0x87,0x96,0x2d,0x27,0xc7,0x94,0x90,0xad,0x11,0x0b,0x1c,0xbc,0x94,0xb4,0x19,0x15,0x39,0x60,0x5a,0x3d +,0xcc,0x2e,0x1e,0x30,0x6a,0xb4,0xa7,0xca,0x12,0x12,0xb0,0x9e,0x1c,0x0e,0x06,0x0b,0x1c,0x45,0x42,0x19,0x0c,0x05,0x09,0x21,0x5a,0xc0,0x0c,0x0e,0x18,0x1d,0xb7,0x96 +,0x8f,0x4b,0x58,0x0c,0xa3,0x8b,0x8d,0xa7,0x0f,0x1c,0x33,0x96,0x8d,0xbd,0x1f,0x1b,0xdd,0x8e,0x8e,0x98,0x14,0x14,0x18,0x94,0x80,0x89,0x45,0x2e,0x98,0x87,0x81,0x80 +,0x8a,0x73,0xa5,0x8f,0x80,0x81,0x82,0x97,0xc6,0x8f,0x90,0x8e,0x8e,0xa0,0x2c,0x04,0x14,0x32,0x1e,0x15,0x06,0x09,0x00,0x0a,0x28,0x1c,0x05,0x00,0x00,0x02,0x0f,0xdf +,0x0f,0x01,0x00,0x05,0x29,0xb5,0xad,0x0f,0x00,0x0a,0x9a,0x87,0x8e,0x97,0xbd,0x0f,0xd7,0x82,0x82,0x8c,0xec,0x29,0x3c,0x92,0x80,0x84,0x98,0x5b,0xce,0x9f,0x90,0x83 +,0x8b,0x2e,0x16,0x56,0x8c,0x85,0x85,0xa6,0x1f,0x26,0xac,0x89,0x82,0x84,0xc1,0x0f,0x26,0x89,0x80,0x86,0xb1,0x0c,0x0a,0x1b,0x90,0x89,0xd1,0x07,0x04,0x06,0x1c,0xa6 +,0x29,0x07,0x00,0x04,0x1f,0xc4,0xad,0x0e,0x02,0x04,0x17,0x91,0x97,0x36,0x08,0x09,0x0a,0x94,0x85,0x94,0x16,0x01,0x0c,0x16,0x90,0x8a,0x26,0x09,0x06,0x18,0xb5,0x96 +,0x98,0x0d,0x06,0x03,0x1d,0x98,0x8e,0x2d,0x06,0x03,0x19,0x8a,0x80,0x8f,0x34,0x2a,0x6b,0x85,0x80,0x80,0x89,0x9b,0x9b,0x86,0x80,0x80,0x82,0x98,0xcf,0x8e,0x80,0x80 +,0x82,0xa7,0x15,0x16,0x96,0x82,0x8e,0x12,0x04,0x02,0x06,0x2a,0xa1,0x15,0x00,0x02,0x00,0x0a,0x22,0x19,0x04,0x01,0x02,0x07,0x1e,0xcf,0x17,0x02,0x01,0x02,0x22,0x9d +,0xbc,0x10,0x06,0x03,0x15,0x90,0x8d,0x1c,0x0d,0x0b,0x0b,0x8f,0x83,0x8c,0x20,0x15,0x21,0xb2,0x82,0x82,0x98,0x25,0x23,0x8d,0x82,0x80,0x85,0xab,0xe2,0x9e,0x83,0x81 +,0x8b,0x9f,0x59,0xd6,0x95,0x82,0x84,0xc2,0x11,0x0c,0x14,0x9c,0x83,0x9a,0x0c,0x06,0x13,0x33,0x91,0x8a,0x45,0x0d,0x09,0x17,0xa4,0x8b,0xae,0x16,0x09,0x0f,0xa3,0x8e +,0xc3,0x0e,0x0b,0x05,0x0f,0x96,0x87,0x58,0x05,0x02,0x09,0x32,0x92,0x1f,0x02,0x01,0x0a,0x2b,0xab,0xa2,0x18,0x05,0x05,0x1d,0x8c,0x8e,0xbf,0x18,0x0c,0x1e,0x9d,0x84 +,0x92,0x1f,0x1f,0x14,0x2a,0x8a,0x87,0xa0,0x1f,0x46,0x9e,0x8b,0x80,0x88,0x93,0xb1,0xb6,0x89,0x81,0x80,0x86,0x9a,0xaf,0x99,0x80,0x81,0x85,0x94,0xa7,0x9e,0x8f,0x80 +,0x89,0xaa,0x18,0x0d,0x18,0xaf,0xa2,0x0f,0x00,0x02,0x02,0x12,0x2e,0x12,0x03,0x00,0x01,0x06,0x1d,0x17,0x06,0x02,0x01,0x08,0x2a,0x53,0x15,0x08,0x05,0x03,0x33,0x87 +,0x8a,0xb8,0x19,0x21,0xb4,0x8c,0x85,0x91,0x9e,0x3b,0x1b,0xa2,0x88,0x84,0x97,0x2a,0x2a,0x98,0x85,0x85,0x9c,0x29,0x1a,0xb1,0x8b,0x87,0x8c,0x9f,0x3b,0x1e,0x96,0x83 +,0x82,0x94,0x3c,0x4c,0x97,0x84,0x85,0x92,0x34,0x1f,0x23,0xe7,0x9f,0xa3,0x1f,0x0a,0x0c,0x2b,0x9b,0x9c,0xad,0x0f,0x03,0x05,0x21,0xe7,0x1b,0x16,0x0b,0x07,0x08,0x1f +,0x4f,0x29,0x22,0x14,0x0f,0x3c,0x9d,0xbf,0x0e,0x09,0x1f,0x36,0xb2,0x77,0x19,0x09,0x07,0x15,0xa5,0x97,0xa3,0x3b,0x09,0x03,0x10,0xac,0xaf,0x29,0x12,0x0d,0x4e,0x91 +,0x9a,0x36,0x36,0xa1,0x91,0x88,0x82,0x81,0x89,0x95,0x8f,0x83,0x80,0x81,0x85,0xa0,0xae,0x8f,0x82,0x80,0x81,0x84,0x92,0x99,0xa3,0xa0,0xce,0x2e,0x22,0x0e,0x0c,0x12 +,0x19,0x09,0x06,0x06,0x05,0x0b,0x11,0x1a,0x07,0x00,0x00,0x03,0x13,0x29,0x19,0x06,0x01,0x03,0x16,0xc0,0x49,0x18,0x0b,0x12,0xb1,0x9f,0x3e,0x0f,0x17,0x20,0x36,0x9d +,0x9b,0xad,0x1f,0x44,0xa6,0x8b,0x83,0x84,0x8a,0xcc,0x20,0xed,0x8d,0x84,0x88,0x9a,0x4a,0x5d,0xb3,0x8f,0x88,0x83,0x8a,0x9c,0x8d,0x90,0x91,0xae,0xaa,0xb0,0x56,0x9e +,0x95,0x99,0x20,0x20,0x30,0xad,0x92,0x93,0xa6,0x0f,0x07,0x08,0x23,0x9f,0xb8,0x11,0x01,0x06,0x15,0xb3,0xd6,0x46,0x28,0x17,0x2f,0xb6,0x34,0x10,0x14,0x1a,0x17,0x1d +,0xdd,0x3c,0x09,0x08,0x16,0x34,0x9f,0x96,0x9c,0x19,0x08,0x08,0x0e,0x2f,0xc8,0x1c,0x09,0x05,0x11,0xa6,0x98,0x93,0xa9,0xbc,0xbd,0x9b,0x95,0xe3,0xbd,0xaa,0x9c,0x9d +,0x88,0x86,0x93,0x8b,0x89,0x82,0x81,0x81,0x81,0x97,0xaf,0x98,0x82,0x84,0x84,0x94,0xb1,0x30,0x2f,0x86,0x8c,0x8f,0xc7,0xbe,0x49,0x11,0x13,0x04,0x08,0x09,0x09,0x03 +,0x05,0x05,0x01,0x13,0x0a,0x12,0x07,0x18,0xbd,0x03,0x03,0x00,0x19,0x22,0x21,0x12,0x08,0x09,0x07,0x8d,0x93,0x86,0xa9,0xb8,0xa9,0x18,0x9e,0xe8,0x8f,0xbe,0xa3,0xb0 +,0x9f,0x91,0x2c,0x8c,0x95,0x84,0x8a,0x8c,0x89,0x3b,0x3c,0x2a,0x84,0x85,0x8a,0x9f,0xaa,0xac,0x3f,0x81,0x88,0x84,0xa8,0xb2,0x9a,0x1e,0x2c,0x17,0x93,0xa0,0x47,0x2a +,0x11,0x17,0x47,0x84,0x07,0x2f,0x84,0x9f,0x9b,0x17,0x07,0x04,0x2b,0x40,0x0c,0x08,0x02,0x00,0x01,0x07,0x1a,0x0e,0x02,0x04,0x05,0x01,0x01,0x01,0x0f,0x13,0x0c,0x08 +,0x09,0x04,0x0f,0x8b,0x84,0x81,0x9a,0x97,0x84,0x81,0x9f,0x4e,0x80,0x81,0x80,0x8b,0x85,0x8b,0xb9,0x82,0x81,0x80,0x88,0x83,0x84,0x8b,0x9f,0x3f,0x83,0x8a,0x8f,0x8e +,0x8f,0x96,0x1f,0x96,0x84,0x8d,0xaa,0x1f,0x2d,0x10,0x03,0x00,0x10,0x48,0x19,0x09,0x05,0x04,0x00,0x01,0x10,0x0f,0x07,0x01,0x04,0x03,0x00,0x00,0x07,0x2e,0x1e,0x0a +,0x06,0x04,0x02,0x00,0x0c,0x4f,0xa8,0x25,0x15,0x4a,0x0a,0x02,0x06,0xa6,0x8f,0xa8,0xbc,0xdc,0x3a,0x04,0x23,0x83,0x80,0x85,0x89,0x83,0x80,0x98,0x9d,0x84,0x80,0x81 +,0x80,0x83,0x81,0x8d,0x9d,0x83,0x80,0x80,0x81,0x83,0x80,0x8b,0xd9,0x92,0x80,0x80,0x82,0x85,0x83,0x88,0x46,0x9d,0x80,0x82,0x80,0x9c,0x88,0x92,0x1b,0x13,0x1b,0x88 +,0x8d,0x34,0x18,0x0c,0x06,0x00,0x05,0xfe,0x25,0x0e,0x00,0x06,0x01,0x00,0x00,0x05,0x19,0x08,0x01,0x03,0x00,0x02,0x00,0x0c,0x4d,0x0f,0x08,0x00,0x07,0x02,0x00,0x00 +,0x0e,0xcb,0x0d,0x04,0x03,0x00,0x02,0x00,0x28,0xbf,0x2d,0x0f,0x0a,0x18,0x04,0x04,0x0f,0x8a,0x87,0xa1,0x3f,0x3f,0xf7,0x0c,0x19,0x83,0x80,0x81,0x8b,0x8b,0x85,0xb2 +,0x46,0x8b,0x80,0x81,0x83,0x8c,0x90,0x97,0xd4,0x93,0x80,0x80,0x80,0x86,0x81,0x81,0x93,0xb9,0x8b,0x80,0x81,0x85,0x8c,0x88,0x8e,0xae,0x8a,0x80,0x80,0x84,0xaf,0x9a +,0x9e,0x29,0x16,0xa4,0x82,0x89,0x9e,0x40,0xa0,0xbb,0x0f,0xcc,0x83,0x8a,0xcf,0x09,0x1b,0x18,0x06,0x0d,0xac,0x87,0x91,0x3a,0x16,0x17,0x10,0x01,0x1e,0x84,0x85,0xa6 +,0x0c,0x7c,0xba,0x19,0x1b,0x8d,0x80,0x83,0x8e,0xe6,0x21,0x0e,0x03,0x1a,0x87,0x8d,0xa1,0x0a,0x18,0x0e,0x02,0x01,0x0c,0x56,0x0d,0x00,0x00,0x02,0x00,0x00,0x00,0x34 +,0x2f,0x08,0x00,0x00,0x01,0x00,0x00,0x01,0x17,0x0d,0x01,0x01,0x01,0x01,0x00,0x02,0x76,0x20,0x04,0x00,0x00,0x01,0x00,0x00,0x09,0x3c,0x26,0x09,0x03,0x05,0x02,0x02 +,0x0d,0x8a,0x84,0x9d,0x0f,0x0d,0x20,0x16,0x2d,0x8e,0x80,0x81,0x81,0x84,0x8d,0x98,0xa7,0x97,0x80,0x80,0x80,0x84,0x88,0x82,0x86,0x86,0x81,0x80,0x80,0x80,0x80,0x82 +,0x83,0x87,0x86,0x80,0x80,0x80,0x80,0x83,0x82,0x82,0x85,0x86,0x81,0x80,0x81,0x86,0x91,0x93,0x9f,0xcb,0x90,0x80,0x84,0x8e,0x3c,0xac,0x90,0x9e,0xb6,0xa3,0x91,0xa2 +,0x24,0x08,0x05,0x05,0x05,0x08,0x9f,0x94,0x15,0x04,0x00,0x02,0x00,0x03,0x06,0x13,0x16,0x07,0x00,0x00,0x00,0x01,0x01,0x1e,0x93,0x45,0x0b,0x00,0x03,0x01,0x02,0x05 +,0x2e,0x94,0xaf,0x0d,0x02,0x02,0x04,0x07,0x11,0x8d,0x95,0x2e,0x05,0x03,0x0b,0x09,0x0a,0x0f,0x9c,0x8c,0x9a,0x1d,0x0e,0x0a,0x0c,0x14,0x92,0x8b,0x9d,0xd0,0x1c,0xd3 +,0xb3,0xb1,0xa1,0x8b,0x8c,0xaa,0x1a,0x2c,0xbd,0xba,0x5e,0x92,0x81,0x86,0x9c,0x12,0xa0,0x8a,0x86,0x88,0x88,0x81,0x85,0xa9,0x0f,0x24,0x91,0x89,0x88,0x81,0x82,0x8c +,0x2d,0x1a,0x2b,0x2c,0xf3,0xa9,0x8b,0x8c,0x60,0x0b,0x07,0x0e,0x0f,0xc3,0x85,0x80,0x8a,0x1c,0x05,0x19,0x1d,0x19,0x26,0x8f,0x83,0x8e,0x28,0x0a,0x0e,0x16,0x0e,0x17 +,0x91,0x8c,0xa0,0x0d,0x07,0x0c,0x0d,0x14,0x2b,0xae,0x94,0x9e,0x2f,0x38,0x26,0x25,0x2d,0x8f,0x8a,0x96,0xab,0x3d,0x9d,0xbc,0xbc,0x98,0x87,0x84,0xa6,0x17,0x16,0x30 +,0xaf,0xcd,0x9a,0x86,0x93,0xc8,0x08,0x1e,0x9b,0x8e,0x8b,0x93,0x8e,0x91,0x47,0x0d,0x12,0x41,0x9c,0x8f,0x82,0x89,0x96,0x1c,0x0b,0x13,0x24,0x9f,0x99,0x8a,0x8f,0x2c +,0x0c,0x0c,0x1a,0x14,0x26,0x8a,0x80,0x85,0xb9,0x06,0x0c,0x14,0x1d,0x43,0x98,0x8b,0x94,0x1e,0x08,0x0c,0x1a,0x18,0x1b,0xa3,0xb5,0x3e,0x0f,0x0c,0x0d,0x14,0x27,0x43 +,0x48,0xd0,0xac,0x3b,0x33,0x1e,0x18,0x27,0x8d,0x8f,0x9e,0x21,0x16,0xc2,0xae,0xa7,0xa9,0x96,0x9d,0x29,0x0c,0x0c,0x16,0x3a,0x24,0xb7,0x95,0xa2,0x27,0x02,0x08,0x3d +,0x8c,0x86,0x89,0x98,0x49,0x19,0x0c,0x0f,0x35,0x9c,0x87,0x80,0x8b,0xa9,0x0f,0x0c,0x18,0x3a,0xbc,0x9c,0x8e,0x9a,0x1d,0x0a,0x06,0x11,0x18,0x34,0x84,0x85,0x89,0x28 +,0x09,0x11,0x36,0xad,0xad,0x94,0x98,0x9e,0x28,0x0f,0x18,0x2d,0x26,0x98,0x99,0xa9,0x26,0x0b,0x10,0x11,0x2a,0x2e,0xb0,0x2a,0x16,0x1d,0x28,0x45,0xc8,0x1d,0xab,0x99 +,0xb0,0x2b,0x0d,0x2a,0xaf,0x96,0xbb,0x9e,0xa9,0x40,0x12,0x08,0x0e,0x2f,0xc1,0x93,0x8c,0xa1,0x2c,0x08,0x09,0x0f,0x97,0x8b,0x86,0x8a,0xae,0x1f,0x16,0x1d,0x6d,0xd2 +,0x96,0x82,0x8b,0xa1,0x13,0x12,0x1e,0xd6,0xdd,0xaf,0x9b,0xb9,0x19,0x08,0x09,0x14,0x1c,0x2a,0xa4,0x91,0x91,0x33,0x2a,0x1e,0x2b,0x30,0x33,0xa3,0xa8,0x6d,0x2f,0x2e +,0x64,0x44,0x64,0x90,0x97,0x72,0x0d,0x14,0x34,0xad,0xd8,0x37,0xb7,0xc1,0x10,0x07,0x27,0x99,0x98,0x9d,0x8d,0x9e,0xb6,0x0e,0x0e,0x1f,0xc7,0x98,0x96,0x8b,0x99,0x1a +,0x0e,0x10,0x29,0x30,0xa9,0x8a,0x96,0xcd,0x09,0x0f,0x2e,0xcf,0x27,0x9d,0x87,0x88,0x9e,0x17,0x0f,0x27,0x71,0xac,0x89,0x8e,0x8e,0x2f,0x1f,0x2e,0x28,0x3e,0xba,0xa7 +,0xb3,0x26,0x15,0x17,0x2e,0x1d,0x26,0x9c,0xd3,0x35,0x1f,0xdd,0xa5,0x9a,0xba,0xae,0x95,0x9c,0x37,0x11,0x11,0x3d,0xb5,0x96,0x87,0x9f,0xb5,0x10,0x0c,0x16,0x24,0x5c +,0xae,0x9f,0xbf,0x15,0x0b,0x05,0x0a,0x2d,0x8c,0x81,0x87,0xa1,0x0e,0x13,0x1a,0x37,0xa9,0x8f,0x86,0x8a,0xb6,0x1b,0x0b,0x1b,0x2d,0x9c,0x8e,0x9c,0xc7,0x17,0x1b,0x11 +,0x11,0x1b,0xca,0xa9,0x9b,0xb8,0x35,0x19,0x1a,0x19,0x93,0x8d,0x94,0xbb,0x11,0x2c,0x2f,0xbb,0xad,0x9c,0x96,0xa4,0x18,0x0b,0x0a,0x13,0x24,0x8d,0x8e,0x98,0x2a,0x0a +,0x08,0x0f,0x66,0x97,0x85,0x87,0x96,0x1f,0x0a,0x08,0x14,0x42,0x84,0x85,0x89,0x4c,0x0c,0x0d,0x0f,0x1a,0x51,0x96,0x8d,0x97,0x2f,0x09,0x05,0x07,0x1a,0x8f,0x8a,0x83 +,0x99,0x38,0x19,0x13,0x25,0xa5,0x8f,0x8a,0x99,0xd3,0x1c,0x1a,0x1c,0xb2,0x8b,0x92,0x9a,0x1e,0x12,0x0e,0x15,0x29,0xaf,0x98,0x97,0x65,0x0f,0x05,0x0e,0x29,0x8b,0x84 +,0x87,0x94,0x1a,0x0f,0x0b,0x1a,0xbb,0x8c,0x86,0x8c,0xaf,0x17,0x07,0x0b,0x0d,0x9e,0x90,0x8d,0x9b,0x1e,0x14,0x07,0x09,0x15,0x97,0x84,0x86,0x9e,0x16,0x09,0x0b,0x14 +,0x91,0x8a,0x88,0x9b,0xbf,0x40,0x1b,0x14,0x1d,0xa3,0x8d,0x98,0x58,0x12,0x10,0x0d,0x16,0x97,0x9d,0x97,0x2c,0x28,0x22,0x34,0x29,0xb2,0x8c,0x89,0xa0,0x17,0x07,0x0f +,0x1f,0x9e,0x88,0x8f,0x93,0x1f,0x23,0x17,0x14,0x0e,0x28,0x9a,0x8a,0x97,0x1e,0x08,0x06,0x0b,0xa8,0x88,0x86,0x8b,0x53,0x38,0x1b,0x18,0x1a,0xc0,0x91,0x8a,0x98,0x47 +,0x13,0x19,0x12,0xa9,0x9f,0x9a,0x9c,0x35,0x3a,0x14,0x0f,0x0f,0x31,0xa2,0x8f,0xab,0x21,0x1b,0x25,0x3c,0x89,0x95,0x9d,0x30,0x17,0x4d,0xba,0x62,0x45,0xaf,0x96,0x93 +,0xc5,0x24,0x0e,0x0e,0x15,0x97,0xa0,0x95,0x39,0x1d,0x16,0x18,0x21,0x6f,0x8d,0x89,0x8e,0xce,0x1a,0x12,0x15,0x2f,0x8e,0x9b,0x92,0x6d,0xaf,0xb7,0x2f,0x1a,0x1d,0xce +,0x9d,0xa9,0x23,0x0f,0x0d,0x0e,0x23,0x8f,0x95,0x97,0x2c,0x54,0x3e,0xc7,0x61,0x69,0xaa,0x9f,0xb3,0xb2,0xe8,0xda,0x25,0xc8,0x8f,0xa6,0xad,0x19,0x1f,0x1a,0x1c,0x1b +,0xf4,0xa1,0x9a,0x1e,0x0f,0x12,0x1f,0xe6,0x91,0x85,0x8d,0x9b,0x17,0x28,0x26,0x3c,0x26,0xa5,0x93,0x90,0x9e,0xc7,0x28,0x1d,0x11,0x1e,0x97,0x9d,0xc0,0x0f,0x17,0x22 +,0x1e,0x1a,0x3c,0x9f,0x8d,0xab,0x56,0x24,0x1b,0x13,0xd5,0x87,0x8e,0x8e,0x36,0x62,0xbb,0x41,0x1a,0x16,0xd6,0x97,0xa1,0xbc,0x16,0x0f,0x0a,0x19,0x93,0xb1,0xbf,0x14 +,0x2d,0x9e,0x99,0x97,0xaf,0xa0,0x98,0xd4,0x37,0x16,0x1e,0x28,0xb8,0x87,0x8c,0x93,0x1c,0x0e,0x0f,0x19,0x26,0x1d,0x24,0xaa,0x9f,0xa2,0x44,0x19,0x2e,0x2d,0x8f,0x94 +,0x9f,0x36,0x15,0x5e,0xc7,0xa3,0xa7,0x9d,0x95,0xbd,0xf4,0x22,0x12,0x0c,0x08,0xa9,0x8c,0x8c,0xa7,0x1f,0x17,0x0d,0x18,0x14,0x2b,0x96,0x8b,0x92,0xa3,0x2c,0x2a,0x18 +,0x37,0x98,0x98,0x9d,0x1c,0x2f,0xac,0xa0,0xa9,0x3f,0xac,0xa3,0xbb,0x24,0x0b,0x0b,0x0b,0x2f,0x8f,0x96,0x9d,0x2f,0x2a,0xe5,0xcb,0x76,0x1e,0x27,0xae,0x8e,0x8e,0xb9 +,0xce,0xbb,0x37,0xae,0xa6,0xa5,0x2c,0x1d,0xda,0x2d,0x21,0x14,0x15,0x44,0xaf,0xb3,0xcc,0x1d,0x16,0x1d,0x9b,0x8a,0x8b,0x8c,0xcc,0x32,0x1a,0x11,0x1c,0x1d,0xa7,0x8a +,0x8d,0x9b,0x22,0x10,0x0e,0x0e,0xb6,0x9c,0x9c,0x20,0x13,0x2d,0x1d,0x5f,0xa0,0x95,0x8f,0x9f,0xad,0x33,0x1c,0x1e,0x17,0xbd,0x90,0x8c,0x8c,0xa2,0x2d,0x19,0x18,0x15 +,0x12,0xfb,0x9a,0xa6,0x68,0x17,0x10,0x0a,0x0a,0x3c,0x8d,0x85,0x8f,0x9f,0x40,0x1c,0x25,0x34,0x9d,0x92,0x96,0x9b,0xb8,0x21,0x1c,0x15,0x37,0x9c,0x9d,0x9b,0x1b,0x10 +,0x0f,0x13,0x42,0xba,0x9e,0x98,0x9c,0xbb,0x41,0x1c,0x0c,0x0d,0x9e,0x8b,0x88,0x9a,0x1e,0x24,0x1a,0xa9,0x97,0xa9,0x49,0x24,0xad,0x99,0x69,0x19,0x11,0x19,0xa8,0xbb +,0x32,0x0f,0x0d,0xc7,0x9c,0x8f,0xa0,0xb3,0xa7,0x49,0x32,0x1e,0x14,0x1b,0x2d,0x8d,0x82,0x8a,0x9a,0x48,0x30,0x13,0x1b,0x23,0x2e,0xb4,0xfb,0xd0,0x30,0x10,0x0b,0x16 +,0xaf,0x8c,0x8b,0x9e,0x18,0x0d,0x24,0xa8,0x95,0x9c,0xa8,0xbc,0xb1,0xb8,0x3c,0x1f,0x1a,0x25,0xaf,0x96,0x9d,0xaa,0x24,0x13,0x15,0x28,0x38,0x1a,0x2e,0xa3,0x8c,0x8f +,0xb4,0xf2,0x25,0x16,0x1f,0x46,0xa7,0x9a,0xa8,0x94,0x96,0xa7,0x3b,0x1b,0x29,0x47,0xb0,0x2d,0x14,0x11,0x13,0x1f,0xaf,0xab,0x9c,0xa1,0x9a,0x9b,0x6e,0x47,0x0f,0x1f +,0xab,0xa2,0xa1,0xae,0xb0,0x35,0x1e,0x36,0xc5,0xab,0xaf,0x47,0xac,0xb8,0x53,0x2d,0x10,0x11,0x11,0x2e,0xa0,0x9b,0xa2,0xc6,0x35,0xc5,0x9a,0x9b,0x9c,0xb9,0xf1,0x2d +,0x2b,0x25,0x37,0xa0,0x90,0x92,0xa3,0x5f,0x0f,0x07,0x07,0x2a,0xa9,0x9e,0xa8,0x25,0x26,0x1f,0x26,0xc0,0x9d,0x98,0x93,0x9f,0xbd,0x25,0x18,0x18,0x31,0x8d,0x8c,0x92 +,0xa6,0x38,0x2c,0x2d,0x22,0x19,0x27,0xab,0xa4,0x4b,0x16,0x08,0x07,0x10,0xa8,0x8a,0x86,0x8a,0x9b,0xc7,0x31,0x23,0x1d,0x1e,0x4b,0x98,0x8f,0x94,0x2b,0x0f,0x0e,0x23 +,0x8f,0x8e,0x93,0x36,0x14,0x12,0x0e,0x19,0x1d,0x2e,0x9c,0x93,0x97,0xb7,0x19,0x13,0x19,0x98,0x8b,0x8f,0x9e,0x1b,0x1e,0x3f,0xc0,0xa6,0xae,0xaf,0xa9,0xbd,0xc5,0x19 +,0x0f,0x11,0x22,0x99,0x9a,0x48,0x12,0x19,0x3e,0xa8,0x9c,0xa8,0xb8,0xa0,0x9e,0xa5,0x42,0x0e,0x0a,0x20,0x8e,0x89,0x8e,0xaf,0x2c,0x47,0x29,0x2f,0x2e,0x2d,0xad,0xae +,0x58,0x19,0x06,0x07,0x11,0x9c,0x85,0x88,0x94,0x26,0x1e,0x4b,0xaa,0xa3,0x4d,0x31,0xb0,0x9e,0x9e,0x28,0x10,0x17,0xd4,0x8c,0x8f,0xad,0x1e,0x14,0x18,0x1f,0x27,0x19 +,0x1a,0xe7,0xaa,0x98,0x9f,0x37,0x3c,0xbb,0x8e,0x8e,0x9d,0x30,0x10,0x2b,0xbd,0xb6,0xdf,0x28,0xb3,0x9b,0x9b,0xb7,0x16,0x0f,0x0f,0x55,0x9d,0xa7,0x2e,0x0e,0x13,0x40 +,0x98,0x97,0xa8,0xbd,0xa3,0x9a,0x9e,0x1e,0x0b,0x0d,0xb6,0x88,0x89,0x9f,0x21,0x1e,0x36,0xac,0xae,0x4c,0x2f,0x42,0x34,0x28,0x19,0x0c,0x0c,0x36,0x9a,0x8c,0x8e,0xbe +,0x2e,0x3c,0xa8,0x9a,0xab,0x37,0x2d,0xae,0x96,0x4c,0x1a,0x0a,0x1f,0x94,0x8d,0x91,0x35,0x22,0x25,0x44,0x46,0x18,0x0e,0x13,0x33,0x9b,0x98,0xb0,0x18,0x29,0x97,0x8b +,0x86,0xbf,0x16,0x16,0x39,0x9e,0xde,0x2e,0x2d,0x4b,0x9e,0x5e,0x2c,0x1a,0x1e,0x9d,0xa8,0xa1,0x36,0x0f,0x11,0x1a,0xb6,0x9d,0xa5,0xa9,0xbb,0x9a,0xa0,0x5d,0x1c,0x19 +,0x9e,0x94,0x95,0x2c,0x11,0x1f,0x4d,0x97,0xa5,0x3e,0x52,0xe1,0xa3,0x4f,0x11,0x08,0x09,0x4a,0x99,0x8f,0x97,0x3d,0x2f,0x41,0xab,0x9e,0xa9,0xbe,0x33,0xc2,0xbe,0x41 +,0x21,0x23,0xae,0x9a,0x93,0xb1,0x2b,0x26,0x2d,0xbf,0x32,0x22,0x1e,0x1c,0x4a,0x2a,0x26,0x1b,0x43,0x93,0x8f,0x8c,0xab,0x4d,0x32,0x56,0x9c,0xa3,0xbd,0x25,0x1f,0xb7 +,0x38,0x2b,0x11,0x19,0x9b,0x90,0x8d,0x40,0x19,0x18,0x17,0xcf,0x24,0x2d,0xd8,0x3b,0xad,0x2c,0xee,0xdf,0x9e,0x8d,0x98,0x90,0xc6,0x1f,0x1e,0x19,0x5a,0x38,0xc6,0xa6 +,0xb0,0x9b,0xd5,0x23,0x11,0x1b,0xf4,0xb3,0xb2,0x20,0x16,0x24,0xc5,0x9a,0xa3,0xa4,0xa8,0xa9,0xa9,0x32,0x21,0x1d,0xbc,0x9e,0x92,0x9b,0x35,0x27,0x22,0x40,0xb0,0xcd +,0xc0,0x3d,0x41,0x17,0x10,0x17,0x1b,0xa4,0xa0,0x9a,0xc4,0x27,0xc9,0xcc,0x99,0xa3,0x4f,0xa7,0xba,0x9d,0x3a,0x16,0x11,0x1a,0x9b,0x92,0x90,0x9f,0x26,0x22,0x15,0x23 +,0x34,0x2b,0xac,0x39,0xfa,0x1f,0x18,0x1e,0x4a,0x95,0x8c,0x8d,0xa1,0x30,0x38,0xaf,0xa3,0x69,0x2c,0x51,0x4f,0x2f,0x12,0x0d,0x15,0xa1,0x93,0x8c,0x95,0x46,0x2d,0x1f +,0x31,0x2a,0x19,0x23,0x1c,0xd1,0xb3,0xe3,0xca,0xbd,0x8e,0x8e,0x8c,0xa7,0x1e,0x19,0x0f,0x26,0x55,0xbd,0x9f,0xa7,0x9b,0x54,0x1a,0x10,0x13,0xdb,0xa6,0x9f,0x4c,0x22 +,0x2c,0x31,0xbf,0xb0,0xac,0x9a,0xa0,0xb2,0x29,0x1c,0x25,0xb1,0x95,0x8e,0x9e,0x37,0x20,0x13,0x2d,0x54,0xdf,0xd5,0x46,0xcd,0x29,0x31,0x1c,0x1c,0xb0,0xb6,0xaa,0x50 +,0x5e,0xaf,0xf9,0xa8,0xdd,0xb9,0x96,0x9e,0xb3,0x25,0x17,0x19,0x3a,0x9f,0x99,0x98,0xb2,0x33,0x24,0x1e,0x23,0x2e,0xcd,0xad,0xbc,0x2c,0x1b,0x0f,0x1c,0xb4,0x9c,0x92 +,0xaa,0xbe,0xb5,0xad,0xa6,0xc6,0xc2,0xb7,0xbc,0x76,0x19,0x15,0x16,0xdd,0x92,0x94,0x99,0x44,0x3d,0xec,0x30,0x1d,0x0e,0x14,0x25,0x48,0xb4,0x7b,0xe6,0xba,0x9f,0x8e +,0x91,0xb6,0x29,0x29,0x3b,0xd8,0x35,0x3d,0xb6,0x9c,0x98,0xcc,0x20,0x0e,0x19,0x64,0x9f,0xa5,0x37,0x4b,0x4c,0x76,0x5e,0x26,0x3e,0xad,0xaa,0xc5,0x1f,0x1a,0x20,0xab +,0x92,0x8e,0x95,0x46,0x22,0x28,0x34,0x4d,0x2f,0x3c,0xab,0xac,0xb9,0x3a,0x1f,0x2e,0xcd,0xa4,0xab,0x3a,0x25,0x1f,0x2f,0x4b,0x5e,0xb7,0xad,0xa0,0xb0,0x2f,0x1f,0x1d +,0xb3,0x9a,0x97,0x9c,0xae,0x4d,0x1d,0x1d,0x27,0x3e,0xaf,0xb2,0xb3,0x36,0x18,0x16,0x28,0xaa,0x9f,0x9c,0xa3,0xba,0x40,0x27,0x2c,0x3f,0xbc,0x9f,0xa2,0xc4,0x22,0x15 +,0x1b,0xb7,0x9e,0x9b,0xa0,0xa7,0x9e,0x59,0x1a,0x0d,0x16,0xd7,0xa6,0xb7,0x31,0x1e,0x2b,0xab,0x93,0x94,0xac,0x3a,0x37,0x56,0x2a,0x19,0x1d,0x72,0x98,0x8d,0x96,0x59 +,0x18,0x16,0x2c,0xb5,0xb3,0x56,0xc1,0xaa,0xb5,0x36,0x1a,0x1f,0xc2,0x9d,0xa0,0x35,0x16,0x0e,0x24,0xa3,0x94,0x92,0x9f,0xa3,0xc1,0x2a,0x20,0x21,0x5e,0xb3,0xab,0xb2 +,0x49,0x39,0x2f,0x39,0xc9,0xb3,0xee,0x36,0x36,0x3b,0x37,0x36,0x3a,0xb7,0xa0,0xab,0xaf,0x2e,0x20,0x21,0x39,0xa9,0x9d,0x98,0xa4,0xcd,0x2a,0x27,0x4f,0xcb,0x6e,0x3f +,0x33,0x3e,0x32,0x29,0x33,0xbd,0xa2,0x9f,0xaa,0xc7,0x43,0x4a,0x5f,0x39,0x36,0x36,0xd8,0xce,0x38,0x3b,0x33,0x34,0xdf,0xb2,0xa5,0xa3,0xa5,0xac,0xdf,0x30,0x24,0x29 +,0x35,0x30,0x48,0xc7,0xb8,0xf8,0x6b,0xc4,0xbe,0xae,0xc5,0x59,0x30,0x2e,0x32,0x53,0xc6,0xaf,0xa4,0xb4,0x62,0x30,0x2e,0x24,0x29,0x31,0x63,0xaa,0xa7,0xa8,0xc6,0x47 +,0x5c,0xbb,0xc7,0x39,0x30,0x57,0x53,0x36,0xf5,0xb8,0xa3,0x9a,0xb2,0x39,0x34,0x26,0x24,0x26,0x39,0x5a,0xb0,0xa7,0xd4,0x40,0x4f,0xc5,0x41,0x13,0x1a,0xa3,0x95,0x9a +,0xaf,0xa4,0x92,0xb4,0x1b,0x1a,0x1c,0xa3,0xce,0x17,0x0e,0x0a,0xac,0x8d,0x95,0x9e,0xa1,0xa0,0xdc,0x47,0x19,0x11,0x1e,0x2e,0x8d,0x8c,0xb8,0x27,0x28,0x1f,0xcd,0xae +,0xae,0xa7,0xc1,0xc3,0x15,0x14,0x26,0xa2,0x90,0xc7,0x13,0x56,0x92,0x98,0xb1,0x17,0x16,0x5c,0x9d,0xb1,0x1d,0x28,0xa5,0x97,0x40,0x0c,0x3c,0x8c,0x96,0x3b,0x12,0x2a +,0x9e,0xb2,0x1f,0x12,0x39,0x9a,0x8f,0xa3,0x13,0x11,0xb4,0x9f,0xad,0x2f,0x33,0xae,0xac,0xb2,0x44,0xae,0xa4,0xbf,0x1d,0x09,0x0e,0xa3,0x8f,0x9f,0x36,0xa9,0x9d,0xb8 +,0xac,0x22,0x1f,0x23,0x1e,0x3c,0x9e,0x9c,0x9f,0xdf,0x23,0x33,0xbb,0xa6,0xb3,0x30,0x18,0x14,0x27,0xa8,0x9a,0x96,0xd1,0x24,0x30,0xad,0x9b,0xd5,0x22,0x19,0x23,0xad +,0xab,0xaf,0x4c,0xb6,0x9d,0x4e,0x1a,0x23,0xae,0xaf,0x2d,0x1a,0x2f,0xa0,0x9c,0x24,0x17,0x2b,0xa6,0x98,0xa9,0x38,0x47,0x9a,0x9b,0xb3,0x30,0x3f,0xbd,0xdc,0x1d,0x1e +,0xaa,0x95,0xae,0x11,0x08,0x18,0x9c,0x94,0xa1,0x3d,0x75,0xae,0xb3,0x5b,0x22,0x3c,0xaf,0xcf,0x2c,0x3e,0xa8,0x9a,0xc3,0x21,0x2a,0x9f,0x90,0x9d,0x1d,0x0c,0x18,0x47 +,0xdb,0x2f,0x4c,0x7b,0xd9,0xc0,0xae,0x9d,0x95,0xbb,0x1b,0x13,0x1f,0xb6,0x9c,0xa5,0xbf,0xc3,0x41,0x56,0xb9,0xbf,0x3b,0x2c,0x25,0xcc,0xa1,0xaa,0x3e,0x1c,0x22,0xf8 +,0xae,0xb8,0x3b,0x2c,0xbf,0xa2,0xac,0xad,0x9f,0x9e,0x79,0x12,0x16,0xba,0x97,0xac,0x17,0x0d,0x1b,0xae,0x9b,0xa9,0xbb,0xad,0x9b,0xb5,0x15,0x19,0xed,0x9f,0xaf,0x2d +,0x32,0xa4,0x9a,0xb1,0x1d,0x16,0xdd,0x93,0x96,0x2e,0x0f,0x1f,0xb8,0x6f,0x29,0x20,0x54,0xab,0xac,0xbf,0xb7,0xae,0xc8,0x46,0x24,0x1c,0x44,0x9c,0x98,0xa3,0xe3,0x3a +,0xc0,0xa7,0xd9,0x30,0x1e,0x2c,0xc9,0xc1,0xc1,0x3c,0x44,0xdb,0x6a,0xd7,0x4f,0x3a,0x47,0xc7,0xad,0x34,0x32,0xaf,0xb1,0x33,0x14,0x28,0x9e,0x96,0x9d,0x21,0x0d,0x18 +,0xb5,0x96,0x9b,0xa5,0x9d,0x9f,0x4b,0x19,0x1d,0xd0,0x9c,0x9f,0x2f,0x22,0x6e,0xa5,0xb4,0x21,0x12,0x29,0xa3,0xa6,0x24,0x16,0x2f,0xac,0xb4,0x41,0x2c,0x3c,0xad,0xaf +,0xbb,0xb4,0x98,0x93,0xaa,0x1f,0x13,0x34,0x9e,0x94,0xa6,0x2b,0x1e,0x3d,0xa9,0xba,0x20,0x16,0x1c,0x2a,0x2e,0x2c,0x3d,0xf5,0x61,0xc4,0xb5,0xbe,0xaf,0x9e,0x97,0xa2 +,0x4c,0xc5,0xaf,0xb1,0x3a,0x29,0x5e,0x9f,0x97,0xad,0x1e,0x0d,0x10,0x2b,0xaf,0xa7,0xa2,0xa3,0xb4,0x1e,0x15,0x1d,0xed,0xa7,0xb1,0x2f,0x1f,0xaf,0x8f,0x8e,0xb0,0x26 +,0x31,0xaf,0xae,0x57,0x29,0x32,0xc1,0xb5,0x74,0x26,0x26,0x3e,0xc4,0x4c,0x46,0xad,0xa2,0x6c,0x15,0x11,0x2d,0xab,0x98,0x9d,0xc3,0x29,0x53,0xa5,0xa5,0xc3,0x39,0x56 +,0x3f,0x36,0x3d,0xbe,0xbc,0x3b,0x26,0x28,0x61,0xa5,0x99,0x96,0xbc,0x28,0x20,0x2c,0x3f,0x2f,0x34,0xdd,0xa9,0x9f,0x9e,0x5e,0x1c,0x1a,0x2a,0x47,0xbd,0xaf,0xaf,0xc7 +,0x29,0x3c,0xb6,0xa7,0xa8,0xe0,0x22,0x1c,0x35,0x9d,0x96,0xae,0x39,0x41,0xd9,0x3c,0x35,0x2e,0x52,0x47,0x33,0x48,0x37,0x3d,0xe6,0xb5,0xd8,0xec,0xa9,0x99,0xa8,0x20 +,0x16,0x20,0xcf,0x99,0x94,0xa3,0x3c,0x28,0x36,0x66,0x3f,0x37,0x53,0x2b,0x2b,0xff,0xa6,0xac,0x41,0x27,0x2b,0x4d,0xae,0x96,0x95,0xa9,0x48,0x2e,0x34,0x2b,0x26,0x3d +,0xbe,0xcf,0x7e,0xbd,0x68,0x32,0x26,0x46,0x4e,0x41,0x50,0xc0,0xc6,0x34,0x3f,0xc2,0xa9,0xa0,0xa8,0x61,0x1e,0x1f,0xbb,0xa5,0xaa,0xca,0xd7,0x46,0x3e,0xc1,0xad,0xbe +,0x37,0x26,0x26,0x28,0x2f,0x3e,0x55,0xba,0xac,0x97,0x99,0xcb,0x19,0x14,0x24,0x3c,0xc5,0xad,0xa7,0xb3,0xa9,0x9f,0xac,0x49,0x38,0x3e,0x33,0x2b,0x37,0xb0,0xbb,0x4d +,0x2f,0x29,0x2a,0x40,0xa7,0xa4,0xb9,0x34,0x2b,0x4b,0x5f,0xef,0x5a,0x51,0x68,0xc8,0xaf,0xb9,0x3f,0x2e,0x4f,0xbe,0xae,0xa5,0xae,0x31,0x1e,0x23,0x48,0xb2,0xa2,0xb2 +,0x3c,0x2d,0x3b,0xa8,0xa4,0xb8,0x3b,0x32,0x2f,0x27,0x3f,0xb8,0xa9,0xa9,0xcf,0x2f,0x21,0x1f,0x2e,0xd9,0xad,0xa9,0x9f,0x9b,0xab,0x48,0x35,0x3b,0x2b,0x3a,0xc3,0xd0 +,0xdf,0xc6,0xa8,0xac,0xba,0xcc,0x28,0x17,0x15,0x23,0x49,0x6b,0x34,0x2c,0x3d,0xb5,0x9f,0x94,0x96,0xab,0x77,0x2f,0x2e,0x33,0x47,0xcc,0xb9,0xb8,0xbd,0xb9,0x66,0x2a +,0x24,0x2c,0x40,0x4e,0xb4,0xb6,0x36,0x2a,0x46,0xbc,0xaa,0xa9,0x5d,0x2d,0x2e,0xdc,0xa3,0x9e,0xbd,0x36,0x3c,0x34,0x38,0x75,0x61,0x7a,0x4e,0xbe,0xae,0xc0,0xcc,0x40 +,0x24,0x21,0x31,0xc1,0xae,0xae,0xbd,0x5b,0x46,0x31,0x39,0xbf,0xb4,0xce,0xe9,0x5e,0xdf,0xc2,0xaf,0xb1,0x38,0x26,0x2f,0xfc,0xbf,0x31,0x22,0x1f,0x2d,0xaa,0x96,0x91 +,0xa0,0xca,0x2e,0x22,0x2b,0x33,0x32,0x32,0xc1,0xa1,0x9c,0x9e,0xbb,0x39,0x27,0x29,0x2e,0x37,0x2c,0x1f,0x2b,0x49,0xb9,0xa5,0x9f,0xab,0x47,0x29,0x2e,0xd6,0xaf,0xb2 +,0xba,0xc3,0xdb,0xf7,0xd0,0xcc,0xbe,0x5b,0x2d,0x2c,0x35,0xb9,0xb1,0x58,0x32,0x3b,0x41,0xf6,0x51,0x34,0x2c,0x3b,0xd5,0xbd,0xa4,0xac,0xa9,0xa7,0xb4,0xeb,0x4c,0x4c +,0x2e,0x32,0x39,0x6d,0xb4,0xb1,0x76,0x26,0x1e,0x21,0x34,0xb5,0xa2,0x9c,0x9c,0xbd,0x3b,0xde,0xbd,0x70,0x2a,0x24,0x24,0x33,0xb3,0xa8,0xb1,0x5e,0x60,0xcb,0xd6,0x32 +,0x1d,0x19,0x24,0xc9,0x9d,0x97,0xa0,0xc2,0x4a,0xd2,0xb4,0xb5,0x4d,0x22,0x1d,0x33,0xd6,0xae,0xa8,0xa7,0xad,0x57,0x2a,0x1d,0x27,0x3b,0x2f,0x48,0xcb,0xb6,0xa3,0x9f +,0xaa,0x5c,0x23,0x1e,0x33,0xdb,0xaf,0xa7,0xaa,0xcd,0xd4,0xa3,0xac,0x3f,0x2a,0x22,0x2c,0xeb,0xb6,0x48,0x25,0x3b,0xc3,0xb7,0xb5,0xc7,0x3e,0x2c,0x35,0xf6,0xb0,0xab +,0xaf,0xc0,0x59,0x2c,0x2e,0x4a,0x4e,0xd6,0xc6,0xb3,0xc2,0xc8,0xbc,0xea,0x2e,0x1e,0x1d,0x32,0xb2,0xa0,0xa6,0xc7,0xd0,0xb2,0x9e,0x9e,0x75,0x1e,0x17,0x1b,0x39,0xaa +,0x9b,0xa4,0xba,0x7e,0xc4,0xd4,0x2b,0x1a,0x1b,0x2c,0xde,0xa3,0x9d,0xaf,0x5d,0xbb,0xaa,0xa4,0xdd,0x28,0x29,0x2b,0x56,0xb6,0xa9,0xa3,0xac,0xbe,0x41,0x28,0x1e,0x1e +,0x1d,0x21,0x38,0x50,0xbb,0xa6,0x9a,0x9e,0xd0,0x27,0x23,0x3b,0xaf,0xab,0xb2,0x3f,0x37,0xbc,0x9f,0x9f,0x4e,0x28,0x24,0x33,0x43,0x5e,0x4e,0x44,0xbe,0xab,0xa8,0xc0 +,0x2c,0x22,0x34,0xcf,0xb2,0xa7,0xad,0xe0,0x44,0x4a,0x40,0x2e,0x38,0xdf,0xc0,0x50,0x65,0xb9,0xae,0xac,0xb2,0x68,0x22,0x1d,0x2b,0xcb,0x6c,0x4a,0x4a,0xe7,0xad,0x9f +,0x9f,0xcf,0x28,0x1b,0x24,0xc8,0xa3,0xa8,0xbf,0xda,0xb3,0xae,0xc8,0x24,0x14,0x16,0x29,0xeb,0xbe,0xae,0xac,0xa5,0xa2,0x9e,0xa8,0x55,0x2d,0x29,0x2b,0x2a,0x7c,0x9f +,0x9d,0x9f,0xa6,0xc7,0x2b,0x1e,0x22,0x25,0x23,0x23,0x2d,0xea,0xab,0x9a,0x9f,0xc6,0x2c,0x26,0xd3,0xb5,0x64,0x3d,0x3b,0xc9,0xa8,0x9e,0xa5,0xdb,0x29,0x1e,0x2e,0x70 +,0xc9,0x4c,0xed,0xc8,0xba,0xc5,0x44,0x2d,0x25,0x36,0x54,0xbe,0xbd,0xb0,0xb6,0xad,0xa9,0xad,0x79,0x2c,0x41,0x41,0x2f,0x2b,0xdf,0xa6,0xaa,0xbc,0xe2,0x40,0x1f,0x24 +,0x41,0x4e,0xcb,0xff,0xbd,0xa2,0x99,0x9e,0xdb,0x29,0x20,0x2b,0x5d,0xc1,0x4c,0x45,0x4f,0xbb,0xa6,0xa8,0x3f,0x1f,0x1e,0x26,0x2f,0x6a,0xb9,0xb3,0xa6,0xa5,0x9e,0xab +,0x38,0x1c,0x1b,0x20,0x2b,0x5b,0xa9,0x9b,0x9d,0xa3,0xaa,0xba,0x3c,0x2e,0x33,0x2a,0x1b,0x1e,0x34,0xba,0xa7,0xa4,0xaa,0x6e,0x2e,0x3d,0xd0,0x4d,0x27,0x31,0xbb,0x9d +,0x92,0x97,0xb6,0x2e,0x22,0x2f,0x51,0x30,0x2a,0x2a,0x36,0x40,0xd4,0x44,0x44,0xc6,0xb8,0x3b,0x28,0x4e,0xb3,0x9f,0x9e,0xaa,0xd0,0xc6,0x42,0x27,0xd2,0xa9,0xba,0x2c +,0x15,0x14,0xd8,0x97,0x9b,0xaa,0x3a,0x3a,0x2d,0x1b,0x2f,0xa2,0x94,0x9f,0x27,0x10,0x14,0xce,0x9b,0x9a,0x9a,0xaa,0x33,0x1c,0x21,0xb4,0x96,0x9c,0x2e,0x17,0x15,0x37 +,0xaf,0xb8,0xc1,0xaf,0xa8,0x31,0x24,0x3f,0xcb,0xbe,0xae,0x2f,0x30,0xda,0xba,0xba,0xb1,0xae,0xbe,0xcf,0x19,0x25,0x43,0xb8,0x4d,0x2b,0x36,0x4a,0xa7,0xa5,0xa1,0xa1 +,0xaa,0x60,0x2d,0x1e,0x22,0x34,0xc5,0xa9,0xb6,0x40,0x40,0xa9,0x4e,0x34,0xa5,0xa3,0xea,0x17,0x1b,0x3e,0xaf,0xa9,0x3b,0x35,0xe2,0xae,0xaa,0x41,0x36,0xac,0xb5,0x36 +,0x1f,0x4a,0xb3,0xbc,0xc1,0xfe,0xc4,0x57,0x46,0x32,0x3d,0xaa,0xae,0x66,0x1e,0x18,0xbd,0x9f,0xa2,0xcf,0x27,0xca,0xa9,0x56,0x2b,0x2e,0xa1,0x9d,0xd2,0x24,0x22,0xaf +,0xb5,0x59,0x2c,0x37,0xb9,0xc4,0x2c,0x2c,0xb7,0xa3,0xb7,0x2b,0x3a,0xac,0xa5,0xb2,0x33,0x23,0xe4,0xa5,0xad,0x33,0x2e,0xc5,0xb6,0xc6,0x26,0x1a,0x39,0xb2,0xdd,0x24 +,0x2b,0xa1,0x99,0xcb,0x23,0xbd,0xa0,0xd3,0x2c,0x1e,0x3f,0xa3,0xbb,0x22,0x33,0xa5,0x99,0xa1,0xf7,0x4f,0xc5,0x56,0x22,0x24,0x24,0x33,0xad,0x31,0x1b,0x38,0x99,0x97 +,0x4e,0x4c,0xb5,0xb8,0x2f,0x1a,0x45,0x96,0x9b,0x3e,0x16,0x27,0x92,0x92,0x4a,0x1e,0x61,0xc9,0x29,0x1b,0x1a,0xb1,0x98,0x56,0x17,0x19,0x9e,0x8e,0xb4,0x2e,0x35,0xa7 +,0x41,0x23,0x2d,0x63,0x96,0xa2,0x2d,0x23,0x2a,0xa1,0xa7,0x5b,0x58,0x3b,0xbd,0x1f,0x1d,0x38,0xb0,0x96,0xb6,0x16,0x24,0x9b,0x94,0xf8,0x21,0x3a,0xab,0xb7,0x28,0x24 +,0xce,0x9d,0xb7,0x1f,0x15,0x64,0x92,0xaa,0x2a,0x2d,0x49,0xb7,0x55,0x2b,0x26,0xeb,0xa6,0xda,0x5d,0xc6,0xa8,0xa0,0x44,0xe5,0xb5,0xa7,0xb6,0x19,0x14,0x1e,0xab,0xb1 +,0x2a,0x35,0xe6,0x9e,0xab,0x55,0xb5,0xb6,0xa3,0x45,0x19,0x1d,0x54,0xa7,0x70,0x2d,0xce,0xa2,0xa7,0xbc,0xfa,0xbd,0xb1,0x36,0x18,0x19,0x59,0xa8,0xcb,0x2e,0x31,0xaa +,0x9c,0xa9,0xc5,0x44,0xb4,0xaa,0x2e,0x15,0x1c,0xd9,0xb2,0x45,0x3a,0xac,0x99,0xaa,0x2b,0x25,0xcd,0xa0,0xe2,0x18,0x17,0x54,0xa3,0xb1,0x39,0xc8,0xa7,0x9d,0xae,0x3c +,0xbc,0xab,0xb8,0x25,0x13,0x23,0xbb,0xb4,0x41,0x26,0xd1,0xa9,0xaf,0x3d,0x38,0xa3,0xa1,0x2e,0x16,0x1b,0xbd,0x9e,0x7d,0x29,0x54,0x98,0x9e,0xc9,0x37,0xc3,0x9e,0xfe +,0x26,0x1e,0x46,0xc3,0x2f,0x27,0x47,0x9c,0xa3,0x2d,0x2d,0x38,0xab,0x9e,0xc8,0x18,0x17,0xc5,0xb1,0xae,0x6c,0xb9,0xa7,0xaf,0x67,0x26,0xbc,0x99,0x9f,0x27,0x0e,0x25 +,0xad,0xe7,0x32,0x35,0xa6,0xa8,0xc9,0x30,0x3c,0xa1,0xac,0x2f,0x1a,0x2c,0xdf,0x46,0x5f,0xcd,0xa8,0x9d,0xa3,0xbc,0x2b,0x42,0xbd,0x46,0x21,0x1c,0x33,0x2f,0x4b,0xb7 +,0xa9,0xa0,0xa2,0xae,0x25,0x28,0xa7,0x9d,0xcb,0x22,0x25,0x30,0x30,0x59,0xea,0x9d,0x98,0xb7,0x24,0x1c,0x51,0xb9,0x6b,0x2d,0x2c,0x30,0x32,0xc1,0xac,0xb2,0xa8,0xab +,0xd9,0x2b,0xc2,0xad,0x73,0x4a,0x24,0x45,0x4c,0xe0,0xbc,0xbc,0x9a,0xa8,0x3b,0x1c,0x1e,0x58,0x46,0x58,0x43,0x4c,0x6d,0x39,0x73,0xbc,0x96,0x98,0xc0,0x28,0x1c,0x49 +,0x79,0x4b,0xcb,0xc8,0xcb,0x26,0x22,0xc7,0x9a,0x93,0xb6,0x26,0x1b,0x2a,0xdc,0xde,0xd5,0x4f,0x6e,0x30,0x23,0x4a,0xa1,0x95,0xa7,0x3e,0x20,0x21,0xcd,0xbd,0xc2,0x54 +,0xbd,0xd4,0x19,0x1d,0xb3,0x8f,0x91,0xaa,0x2a,0x1c,0x43,0x43,0x31,0x33,0xae,0xa6,0x28,0x1a,0x26,0xa0,0x95,0xa4,0xcc,0x29,0x2d,0x2f,0x2e,0x4e,0xac,0xa5,0x20,0x0f +,0x1e,0x9e,0x8b,0x91,0xbc,0x22,0x28,0x53,0x4a,0x4d,0x5a,0xac,0x4a,0x1b,0x1a,0x3d,0x97,0x90,0x9f,0x2f,0x1f,0x27,0x2a,0x28,0x6b,0x9d,0xae,0x19,0x15,0x3b,0x94,0x8a +,0x96,0x2e,0x1f,0x45,0x33,0x27,0x27,0xbf,0xa8,0xe1,0x24,0x20,0xac,0x95,0x9d,0xca,0x28,0x2b,0x1e,0x1a,0x36,0x9f,0x93,0xbe,0x18,0x13,0xc6,0x8c,0x8d,0xab,0x1b,0x1c +,0x2a,0x2a,0x2b,0x42,0x9e,0x9c,0x3a,0x14,0x1b,0x9f,0x92,0x9f,0x3f,0x26,0x2d,0x1a,0x27,0xb8,0x98,0x94,0x37,0x12,0x1c,0x94,0x89,0x99,0x21,0x14,0x2a,0x31,0x2e,0x32 +,0xc6,0xa6,0xee,0x1d,0x1b,0xe2,0x98,0x9a,0xa6,0x2f,0x27,0x2a,0x2c,0x3d,0xb3,0x94,0x9f,0x1e,0x0c,0x26,0x90,0x8a,0x9b,0x21,0x1b,0x35,0x46,0x33,0x2a,0xb9,0xa0,0x33 +,0x12,0x18,0xa6,0x8d,0x91,0xc0,0x24,0x2b,0x1e,0x1f,0xcd,0x97,0x96,0x24,0x0a,0x12,0x9d,0x87,0x89,0xa7,0x15,0x12,0x20,0x3c,0x4c,0xb9,0xa6,0xe5,0x1b,0x0f,0x30,0x8f +,0x88,0x93,0x2c,0x1b,0x1d,0x1c,0x24,0xb1,0x96,0x9e,0x20,0x09,0x1b,0x8f,0x86,0x97,0x20,0x13,0x25,0x33,0x20,0x4e,0x99,0x9f,0x30,0x12,0x19,0x9b,0x89,0x8f,0xb9,0x1d +,0x19,0x16,0x1b,0xbd,0x8f,0x8e,0x5e,0x0b,0x05,0x40,0x87,0x86,0xa5,0x0f,0x0f,0x20,0x2b,0x3b,0xa1,0x8e,0x9f,0x1f,0x0c,0x1b,0x95,0x8a,0x9d,0x21,0x1c,0x27,0x33,0x44 +,0xa4,0x90,0xa1,0x18,0x06,0x13,0x92,0x85,0x99,0x1d,0x10,0x16,0x3a,0xbe,0xa5,0x97,0x9e,0x3c,0x0f,0x0e,0x4e,0x8d,0x8a,0x9f,0x28,0x18,0x1c,0x22,0x38,0xa3,0x96,0xa4 +,0x11,0x0b,0x3a,0x8d,0x86,0x9c,0x1a,0x0f,0x1e,0xe7,0x65,0x5d,0xae,0x58,0x18,0x0e,0x4c,0x8c,0x86,0x90,0x46,0x10,0x0e,0x1c,0x3e,0x9f,0x95,0xa9,0x19,0x0d,0x1e,0x96 +,0x87,0x89,0xb2,0x0d,0x0d,0x23,0x49,0x3d,0xef,0xae,0xd3,0x1c,0x29,0x9a,0x8c,0x8e,0xe7,0x14,0x12,0x1b,0x2e,0x51,0xa3,0x9d,0x58,0x16,0x16,0x9e,0x85,0x88,0x9f,0x16 +,0x08,0x0c,0x25,0xc9,0x9a,0x98,0xcc,0x1d,0x17,0x36,0x94,0x8b,0x98,0x36,0x0e,0x0e,0x26,0xae,0xa5,0xa1,0xad,0x25,0x15,0x2a,0x90,0x88,0x9a,0x25,0x0c,0x0f,0x49,0xa3 +,0x98,0xa7,0x30,0x14,0x0f,0x27,0x98,0x89,0x95,0xc6,0x18,0x15,0x22,0x70,0x9d,0x9d,0xb6,0x1f,0x14,0x1f,0xa9,0x8f,0x8e,0xab,0x2a,0x1d,0x25,0x59,0xa4,0xb3,0x27,0x13 +,0x12,0x23,0xb5,0x8d,0x8a,0x9f,0x1e,0x17,0x27,0xe5,0xa7,0x97,0xbb,0x14,0x0d,0x17,0xb8,0x8b,0x87,0x97,0x22,0x13,0x1c,0x20,0xcf,0xa2,0xae,0x19,0x0f,0x1b,0xa3,0x8a +,0x8b,0x9b,0x1c,0x16,0x1f,0x2b,0xc2,0xad,0xc9,0x21,0x19,0x34,0xa0,0x8b,0x88,0x9e,0x1f,0x10,0x15,0x39,0xbe,0x68,0x2e,0x29,0x1f,0x2b,0xae,0x92,0x8b,0x9a,0x46,0x11 +,0x11,0x2c,0xcc,0xaa,0x5c,0x2c,0x2c,0x2f,0xa8,0x95,0x91,0x9a,0xf2,0x1b,0x10,0x19,0x3a,0xa7,0x9e,0xc6,0x3a,0x1f,0x37,0xa5,0xa0,0x9d,0xb0,0x39,0x17,0x11,0x29,0xa7 +,0x96,0x9e,0x31,0x18,0x24,0xac,0x9b,0x9c,0xad,0x36,0x1c,0x1d,0x3c,0xa6,0x98,0xa0,0x33,0x12,0x11,0x26,0x98,0x8e,0x9b,0x3d,0x12,0x15,0x23,0x9c,0x8f,0x97,0x4f,0x0a +,0x0a,0x2b,0x93,0x88,0x95,0x3f,0x10,0x15,0x4a,0x9a,0x8e,0xa6,0x27,0x09,0x0b,0x39,0x94,0x89,0x97,0x3f,0x14,0x0d,0x3f,0x95,0x8b,0x96,0x12,0x06,0x08,0x37,0x8c,0x88 +,0x8f,0x39,0x13,0x10,0x26,0x92,0x8c,0xae,0x16,0x0d,0x12,0xde,0xa9,0x94,0x95,0xbb,0x1d,0x16,0x4d,0x9e,0x99,0x63,0x26,0x22,0x20,0x2d,0xac,0x92,0x92,0x4f,0x21,0x17 +,0xea,0x4a,0x4a,0xaa,0xbb,0xef,0x1c,0x2a,0x51,0xa0,0xa2,0x9e,0xaf,0x43,0x1e,0x0d,0x20,0x99,0x8f,0xa9,0x23,0x1b,0x1f,0xcd,0x9f,0x92,0x97,0x33,0x0d,0x0a,0x41,0x94 +,0x92,0xb1,0x22,0x18,0x21,0x2f,0x9a,0x8d,0x91,0x46,0x09,0x0b,0x2e,0x93,0x8e,0x96,0x2e,0x13,0x0b,0x1d,0x92,0x87,0x8d,0x1f,0x0a,0x0d,0x2a,0x8f,0x8b,0x9f,0x17,0x0d +,0x1c,0xac,0x8e,0x94,0xbb,0x21,0x14,0x15,0x2b,0x9b,0x93,0xa0,0x2d,0x0e,0x23,0x5f,0x93,0x96,0xa7,0x53,0x14,0x13,0x21,0x99,0x90,0xa6,0x24,0x19,0x31,0x98,0xa3,0xb0 +,0x7e,0x3a,0x32,0x2a,0x2a,0xea,0xff,0xdc,0x50,0xc0,0x9d,0x38,0x49,0xcb,0x9d,0x9e,0x46,0x1b,0x17,0x2b,0xb4,0xc7,0x96,0xa3,0xb0,0x18,0x28,0xb0,0x9f,0x96,0x2a,0x3a +,0x01,0x04,0x01,0x2c,0x8f,0xa5,0xa5,0x09,0x14,0x94,0x8e,0x8e,0x8a,0xaa,0xd0,0x95,0x9e,0x98,0x84,0x91,0x14,0x56,0x0e,0x28,0x80,0x94,0x9e,0xa6,0x1e,0x14,0x2d,0xd9 +,0x4c,0x0e,0x08,0x00,0x08,0x04,0x0c,0x18,0x20,0x18,0x00,0x18,0x24,0xc8,0x9b,0x9b,0x2f,0x20,0x61,0x3f,0x94,0x97,0x9a,0xa3,0xa0,0x89,0x88,0x8a,0x85,0x8b,0x8d,0x88 +,0x89,0x82,0x8a,0x8e,0x89,0x99,0x8c,0x8d,0x9b,0x1e,0x18,0xac,0x14,0x10,0x08,0x02,0x0c,0x09,0x06,0x15,0x24,0x17,0x0b,0x00,0x0d,0x08,0x03,0x08,0x0e,0x1b,0x18,0x1d +,0x25,0xc2,0x90,0x87,0xb7,0xbb,0x9b,0x8d,0x89,0x8a,0x8b,0x90,0x8a,0x86,0x85,0x86,0x84,0x8b,0x91,0xbc,0x9f,0xd0,0x98,0xb3,0xaa,0x96,0x29,0x37,0x13,0xbe,0xd7,0x14 +,0x0b,0x01,0x05,0x08,0x0c,0x27,0x0c,0x06,0x08,0x0d,0x17,0x11,0x1d,0x0b,0x11,0x2d,0x1f,0xc3,0xbd,0x9a,0x9a,0x96,0x90,0x91,0x9a,0x33,0xaa,0x9f,0x97,0x94,0xaa,0x94 +,0x8d,0x84,0x86,0x8f,0x87,0x85,0x85,0x9a,0x95,0x9b,0x8f,0x91,0x19,0x18,0x31,0x40,0x14,0x17,0x1a,0x0a,0x05,0x05,0x05,0x0b,0x22,0x1a,0x15,0x05,0x0d,0x0d,0x14,0xbd +,0x19,0x28,0x07,0x2c,0xb7,0x9f,0x98,0xf4,0x8f,0xac,0x8e,0x86,0x8c,0x86,0x89,0x8f,0x98,0x8f,0x89,0x8e,0x8b,0x87,0x9f,0xa1,0x29,0x35,0xa5,0x99,0x93,0x17,0x11,0x0d +,0x39,0xec,0xc7,0xa3,0x13,0x06,0x04,0x07,0x50,0xbb,0x23,0x08,0x00,0x00,0x10,0x92,0xb0,0xb9,0x0e,0x08,0x05,0x1d,0x96,0x8d,0x80,0x43,0x09,0x21,0x9c,0x8e,0x80,0x88 +,0x59,0x16,0x10,0x8b,0x80,0x82,0x8f,0x21,0x4d,0x8f,0x88,0x83,0x82,0x88,0xb0,0x0e,0x0d,0xab,0x8b,0xbd,0x31,0x0a,0x05,0x01,0x0c,0x1f,0x18,0x43,0x06,0x03,0x01,0x0f +,0x8e,0xbb,0x0a,0x0d,0x0e,0x19,0x0c,0xaa,0x36,0x5b,0xa8,0x28,0x99,0x23,0x93,0x8f,0x87,0xa9,0xaa,0xa8,0x8c,0x8a,0xa6,0x89,0x84,0x84,0xa2,0x34,0xaf,0x8a,0xb6,0xb8 +,0xd1,0x8d,0xb1,0x09,0x1f,0x8e,0x89,0x9e,0xb8,0x0e,0x00,0x16,0x91,0xa3,0x0b,0x14,0x04,0x06,0x13,0x0e,0x9d,0x38,0xbc,0x02,0x01,0x06,0x36,0x8b,0x29,0xab,0x0b,0x11 +,0x1f,0xac,0x80,0x8b,0x91,0x5a,0x1d,0x30,0x8c,0x80,0x85,0x81,0x3e,0x13,0x8d,0x85,0x8c,0x8f,0xa8,0x8f,0x26,0x22,0xdd,0xb4,0x90,0x9f,0x19,0x0f,0xc6,0x36,0x2f,0x0d +,0xd4,0x26,0x0e,0x08,0x08,0x1d,0xc9,0x1f,0x06,0x0e,0x18,0x15,0x0d,0x66,0x20,0x1d,0x10,0x42,0x1b,0xb1,0xb1,0x22,0x9e,0x3f,0x93,0x9a,0x9d,0xad,0x9d,0x8a,0x92,0x90 +,0x40,0x1d,0x8b,0x88,0x80,0x9d,0x2e,0xdf,0x94,0xa7,0x95,0x81,0x98,0xb9,0x07,0x16,0x92,0x84,0x8d,0x12,0x0f,0x0b,0x07,0x1e,0xdb,0x9d,0x15,0x0c,0x05,0x06,0x0a,0xae +,0x1d,0x06,0x07,0x03,0x14,0x28,0x97,0x5f,0xad,0x24,0x0e,0x23,0x8f,0x8f,0x8f,0x98,0x52,0x9b,0x8e,0x8b,0x8c,0x96,0x88,0x8d,0x91,0x97,0x1e,0x95,0x8f,0x9d,0x9a,0x92 +,0xba,0x14,0x12,0x3f,0x98,0x95,0x32,0x22,0x07,0x09,0xae,0x90,0xb1,0x0e,0x26,0x11,0x2c,0x1d,0x31,0xa3,0x17,0x4d,0x07,0x0a,0x1a,0x4e,0xb8,0x1c,0x1b,0x09,0x12,0xba +,0x91,0x28,0x16,0x3c,0xa3,0x25,0xa5,0xa9,0x98,0x95,0xb3,0x9f,0x98,0x92,0x8c,0x8b,0x93,0x8f,0xa5,0xa3,0xa6,0x80,0x8f,0x96,0xbd,0xcd,0x48,0x3b,0xad,0xb9,0xae,0x13 +,0x14,0x07,0x17,0xb7,0x19,0x0b,0x15,0x1c,0x1a,0x0a,0x0f,0x18,0x3b,0x1b,0x1b,0x18,0x14,0x11,0x22,0xa2,0x13,0xac,0xb4,0x34,0xa7,0x9e,0x9b,0x9e,0x94,0x9c,0xe6,0xa5 +,0x9b,0x8e,0x80,0xb3,0xab,0x9f,0x98,0x8e,0x9c,0x94,0x51,0x9f,0x24,0x0d,0x48,0xae,0xae,0x22,0x23,0xaa,0x1f,0x1c,0x28,0xb5,0xab,0xad,0x17,0x06,0xf8,0x5b,0x1e,0x34 +,0x1e,0x38,0x17,0x11,0x3d,0x26,0xab,0x12,0x1e,0x34,0x14,0x1b,0xb4,0x4a,0x35,0x11,0x19,0xaf,0x99,0x8f,0xa4,0x9e,0x63,0x95,0x52,0x9f,0x83,0x86,0xa4,0x1f,0x57,0x98 +,0x86,0x95,0x9f,0x93,0xa0,0xa9,0xd5,0xaf,0xb1,0x9c,0xc9,0x0f,0x5f,0x9f,0x0c,0x18,0x29,0x10,0x13,0x25,0x1d,0x09,0x3e,0x13,0x0e,0x10,0x2e,0x16,0x20,0x58,0x25,0xcb +,0x29,0x1a,0xae,0x2b,0x1a,0x91,0xb7,0x96,0x3b,0x28,0xa1,0x9f,0x8b,0x8f,0xa2,0x90,0xa5,0xb5,0x9b,0x9c,0x89,0xc5,0xad,0xc5,0xbb,0x8f,0xa3,0x3e,0x98,0xa3,0x3f,0x1a +,0x0a,0xac,0x35,0xb7,0x17,0x12,0x25,0x2c,0xab,0xc3,0x1d,0x10,0x2a,0x0f,0x1f,0x14,0x13,0xb3,0x2a,0x0b,0x15,0x3b,0x1d,0x32,0xb8,0xa0,0xbd,0xc1,0x23,0x1e,0x8b,0x96 +,0x96,0x46,0xc5,0x99,0x94,0x90,0xa8,0x9f,0xa4,0x22,0x3e,0x97,0x92,0x89,0x34,0xce,0x43,0xa1,0xac,0xba,0x9c,0x13,0xaa,0x30,0x23,0x1d,0x1f,0xb7,0x9c,0x3d,0x0d,0x21 +,0x11,0x5c,0xac,0x2c,0x1d,0x35,0x43,0x1f,0x24,0xbf,0x1c,0x2d,0xb0,0x10,0x4b,0xb4,0x24,0x29,0x2f,0x34,0x18,0x62,0x4e,0x24,0x9c,0xae,0xa6,0x19,0x35,0x8a,0x93,0x8e +,0x91,0xa0,0x98,0xc8,0x94,0x8f,0x93,0x92,0x9f,0xbb,0x35,0xc2,0x2b,0xa1,0x3c,0xa8,0x97,0x0c,0x09,0x1c,0x17,0xae,0x2d,0x08,0x0f,0x17,0x1a,0x16,0x30,0xa3,0x0f,0x19 +,0x15,0x16,0x93,0x9d,0x93,0x2d,0x37,0x5a,0x9c,0x88,0x9e,0x9d,0xac,0xa8,0xda,0x1e,0x9e,0xa4,0x95,0x8f,0x2a,0x22,0xaa,0x97,0xaa,0x9a,0x3b,0xae,0x17,0x15,0x3d,0x1c +,0xaa,0xce,0xd4,0x18,0x17,0xad,0xb4,0x2e,0xe5,0x2e,0xba,0xae,0x16,0x2c,0x9b,0x9f,0xb6,0x15,0x1d,0x9b,0xcc,0x9b,0xad,0x28,0x58,0x26,0x58,0x30,0x5a,0xc9,0x33,0x25 +,0x12,0x16,0x1f,0x25,0xde,0xcf,0x9b,0xa6,0x1a,0x21,0x24,0x95,0x95,0xaf,0x1c,0xb7,0x99,0x9a,0x8f,0x9c,0xb1,0x9f,0x97,0x74,0xc6,0x91,0x8c,0x2d,0xc1,0x27,0xda,0xa2 +,0x59,0x1f,0x1f,0x42,0x16,0x0b,0x12,0x4c,0xab,0xc9,0x33,0x0d,0x14,0x3a,0x9f,0x99,0x17,0x0f,0x2e,0xa5,0x2d,0x2b,0x58,0x97,0x9c,0x36,0x3d,0x96,0x9f,0x1e,0x68,0x9d +,0xb4,0x42,0x18,0x17,0x91,0x8c,0xc7,0x36,0x2d,0x3a,0x9e,0x8f,0xab,0x48,0x41,0x2f,0xa4,0x14,0x3a,0xbd,0x98,0xac,0x19,0x3b,0x1e,0x25,0x66,0xc2,0x9e,0x92,0x26,0x16 +,0x1e,0x9d,0x88,0xa7,0x08,0x11,0x2d,0x73,0x9d,0x2c,0x32,0xc5,0x38,0x65,0xaf,0xa1,0x9f,0xd1,0x1f,0x0f,0xbf,0x2d,0x25,0x6c,0x54,0x9e,0xd8,0x37,0x11,0xcc,0x94,0x97 +,0xb4,0x0f,0x22,0x90,0x93,0x9c,0x2a,0x28,0x9f,0x9f,0xdd,0x2c,0xad,0x9e,0xae,0x25,0xec,0xb2,0x9f,0x53,0x24,0x67,0x98,0xad,0x17,0x08,0x0f,0x9e,0xaa,0x38,0x11,0x16 +,0x4f,0x9f,0xaf,0x5f,0xa6,0xed,0x27,0x14,0x19,0x59,0xa6,0xb3,0x29,0x2b,0xe7,0xa3,0x9e,0xa1,0xb2,0xa8,0x2f,0x1e,0xc0,0x9b,0x84,0x98,0x1a,0x0f,0x36,0x8b,0x8d,0xb2 +,0x24,0xb9,0xb5,0x43,0x35,0xbd,0x98,0x95,0xad,0x18,0x1b,0xaf,0xac,0x24,0x1e,0x36,0xe7,0x2e,0x1a,0x25,0x98,0x9d,0x2f,0x18,0x1d,0xa1,0x9b,0x26,0x0c,0x14,0xb3,0xa3 +,0x3d,0x38,0x31,0xa5,0xb8,0x32,0x3e,0x2b,0xc0,0xbe,0x2c,0x31,0xaf,0xec,0x25,0x29,0xd8,0x98,0x9e,0x4f,0x1e,0x37,0x9d,0x94,0xae,0x2c,0x57,0xaf,0xc0,0x3e,0xbe,0xa1 +,0x9d,0x23,0x0c,0x1c,0xa7,0x99,0xa1,0x3a,0x27,0x3c,0x4a,0x28,0xd7,0x99,0xa9,0x1c,0x10,0x1d,0xb9,0x96,0xab,0x35,0x33,0xfa,0x2f,0x2f,0x44,0xa2,0x9b,0x33,0x1b,0x15 +,0x30,0x96,0x98,0x49,0x1f,0x2f,0x55,0x47,0x36,0xb3,0x9f,0xa5,0x2c,0x30,0xc7,0xa1,0x98,0xaf,0x4a,0x38,0xc3,0x26,0x21,0x34,0xb0,0x9e,0xaf,0x20,0x1a,0xac,0x8b,0x9d +,0x24,0x1b,0x29,0x2d,0x2b,0xcb,0xcd,0x99,0xca,0x18,0x1a,0xad,0x9c,0xac,0x4a,0x2b,0xb6,0x48,0x7b,0x3e,0xcf,0xd5,0x49,0x2e,0x24,0x64,0xa3,0x9d,0x38,0xdb,0xac,0xb5 +,0x28,0x2f,0xb5,0x9e,0x9c,0x29,0x32,0xb8,0xbf,0x3e,0x1f,0x7a,0x51,0xc2,0xac,0x2f,0x29,0x34,0x95,0x9a,0x3d,0x2e,0x2f,0x28,0x13,0x28,0xa7,0xbb,0x5a,0x4a,0xd8,0xc2 +,0xb4,0xc4,0xb0,0x19,0x1c,0x5a,0x42,0xc2,0x47,0xb6,0xac,0xad,0x37,0x34,0x21,0xd3,0xb4,0xb9,0xac,0x35,0xb4,0xbc,0x9f,0x9c,0xb2,0xfa,0x16,0x46,0x9e,0xcd,0x21,0x2f +,0xa8,0xa2,0xa4,0x2e,0x1e,0x32,0xb4,0xa6,0xad,0x33,0x27,0x38,0xa7,0xee,0x3e,0xaa,0x30,0x29,0x46,0xd2,0xb8,0x3f,0x1f,0x2f,0x4d,0xbd,0xac,0xae,0x2a,0x1b,0x66,0x98 +,0xc1,0xe4,0xa3,0xd0,0x36,0x1d,0xc6,0xb4,0x4e,0xae,0xb4,0x4c,0x3c,0xb1,0xad,0x44,0x3c,0x6c,0xd4,0x2e,0x33,0xc6,0xcc,0xcb,0xbc,0xa2,0xc0,0xfd,0xbd,0x20,0x1c,0x1e +,0xc3,0x9e,0xae,0x22,0x1f,0xb9,0xab,0xb1,0x57,0xb9,0x1b,0x13,0x31,0x9a,0x9f,0x3d,0xd3,0x20,0x4b,0xb5,0xb3,0xb0,0x24,0x4c,0xaa,0x2b,0x23,0xae,0x8d,0x9a,0x4a,0x48 +,0x1f,0x1d,0x25,0xa2,0xa2,0xc5,0xbc,0xb2,0x63,0x6c,0xb0,0xbf,0x5a,0x1d,0x4c,0xae,0x4f,0x1c,0x30,0x66,0x6c,0xb4,0xb7,0x66,0x19,0x2f,0xb4,0x9f,0x3c,0x24,0x63,0xaf +,0x9a,0xb7,0x51,0x20,0x19,0xb9,0xa5,0x5c,0xc9,0xa2,0xbb,0x1c,0x1f,0xaf,0x96,0xc0,0x24,0x31,0x45,0xb7,0x3a,0x4c,0x9f,0xa7,0x40,0x6e,0x2f,0x26,0xa4,0x9d,0x32,0x22 +,0x59,0xbe,0xcf,0x28,0xf5,0xaa,0xb2,0x3f,0x38,0x36,0x1e,0x2f,0xa7,0x93,0xea,0x17,0x25,0xa5,0x9a,0xbb,0x26,0x1c,0x1c,0x25,0xaf,0xa6,0xa9,0xa5,0xb5,0x3d,0x27,0x1e +,0xab,0x9f,0x47,0xd9,0x5e,0x3e,0x39,0xa2,0xa3,0xdc,0x54,0xae,0x45,0x1d,0xb7,0xaa,0xa1,0x41,0x25,0xeb,0xbc,0x3e,0xaa,0xa8,0x18,0x14,0xe6,0x9c,0xb2,0x37,0x37,0xae +,0xbf,0x3c,0x2e,0x2e,0xfe,0x32,0x41,0x97,0xbe,0x42,0x2e,0x27,0xc6,0x9c,0xa3,0x23,0x1c,0x1a,0xa6,0x9f,0xb2,0x36,0x1a,0x53,0xc3,0xb0,0xb0,0x36,0x2c,0xab,0xa3,0x4a +,0x54,0xad,0xa0,0x28,0x29,0x5a,0x2a,0x44,0x9f,0x97,0x4d,0x21,0x2b,0xa3,0x9c,0x29,0x3a,0x32,0x29,0x40,0xad,0xa3,0x5d,0xcb,0x3d,0xc9,0x24,0x41,0x57,0x27,0x4e,0xaf +,0xa7,0xd2,0x39,0x32,0xb2,0xc0,0xb6,0x39,0x1e,0x17,0x2e,0x9b,0x98,0xa2,0x50,0x28,0x2e,0xb4,0xaa,0xaf,0xcd,0x24,0x2c,0xab,0x44,0x7d,0x9f,0xa0,0xbf,0x19,0x10,0x1e +,0xaa,0xa5,0xa4,0x59,0x24,0xeb,0xaf,0xa7,0x77,0x6b,0x43,0x29,0x2c,0x3d,0x98,0xb2,0x1d,0xba,0xad,0x3d,0xb1,0xbb,0x2d,0x34,0xbc,0xa5,0x45,0x3f,0x3d,0x31,0xc5,0xb3 +,0xb9,0x29,0x16,0x1f,0xa7,0x90,0xbb,0x2c,0x1f,0x33,0xb1,0xe4,0xb4,0x70,0x61,0x28,0x41,0xa8,0x9c,0x9e,0xb7,0xdd,0x18,0x25,0xaf,0xa7,0xee,0x48,0xe8,0x3b,0x52,0xdd +,0xae,0x47,0x46,0x26,0x18,0x1e,0xa8,0x92,0x9f,0xee,0x21,0x1c,0x33,0xa0,0x9a,0xb8,0x14,0x14,0xa0,0x8e,0x72,0x2d,0xdf,0xa8,0xa9,0xcc,0x4b,0x23,0x3a,0x2d,0xbd,0xb9 +,0x44,0xb2,0xc4,0xac,0x63,0x36,0x36,0x2e,0x30,0x2a,0xbf,0xa0,0xa1,0xb3,0x56,0x29,0x2e,0x57,0x39,0x36,0x4c,0x4a,0xab,0x2e,0x3a,0xaf,0xbb,0xc9,0x39,0x43,0x40,0x5c +,0xbf,0xa4,0x4b,0x2f,0x1f,0xb9,0xae,0xae,0xb5,0x24,0x2c,0x2f,0x99,0xac,0x4e,0xbe,0x53,0x31,0x2d,0xa5,0xaa,0x49,0x36,0xd7,0xb5,0xcf,0xa5,0xab,0x2f,0x19,0x25,0xb0 +,0xad,0xaf,0x41,0x33,0xb1,0x9d,0xad,0x22,0x1b,0x2a,0xc3,0xd9,0x4e,0x4a,0xbc,0xbb,0x43,0x2d,0x32,0xba,0xa9,0xb8,0x1e,0x17,0x2f,0xa6,0x96,0xa9,0x29,0xd0,0xb2,0x5f +,0x44,0xbb,0xc4,0x24,0x31,0xb0,0x9c,0xaf,0x55,0x4c,0x2e,0x22,0xe7,0x9f,0xbc,0x3a,0x1a,0x26,0xb5,0xab,0xa2,0xac,0x27,0x1b,0x5a,0xaf,0x2b,0x29,0xb0,0xa4,0xaf,0x39 +,0xb2,0xc7,0x38,0xbb,0xd4,0x39,0x7c,0xb9,0xb5,0x4a,0x1d,0x38,0x72,0xb1,0xcc,0x3e,0xee,0x3c,0xbf,0xba,0xae,0xb9,0x3a,0x26,0x36,0xe3,0xbb,0xb2,0xaf,0x41,0x2c,0xb1 +,0xb1,0x9f,0xa8,0x29,0x11,0x18,0x9d,0x92,0xbf,0x26,0x71,0xb9,0x49,0x3d,0x71,0x4b,0x1d,0x2b,0xc3,0xc7,0xb7,0xb8,0xb3,0x22,0x2a,0xb1,0xac,0xab,0x30,0x2c,0x1f,0x5a +,0xa6,0xaa,0xc0,0xdb,0xab,0x60,0x6e,0x2c,0xd9,0xb7,0x59,0x36,0x5d,0xae,0xb6,0xbc,0xdf,0xf4,0x26,0x2e,0xab,0x9e,0x23,0x1d,0x67,0x9f,0x9d,0x3b,0x37,0x26,0x1c,0xac +,0x95,0xaa,0x38,0x1c,0x41,0x29,0x68,0x9d,0xad,0x34,0x24,0x39,0x4a,0xa9,0xaf,0xb8,0x27,0x1f,0x3a,0xb3,0xac,0x2d,0x5a,0xae,0x5e,0x3a,0xb1,0xaa,0x39,0x2f,0x53,0x33 +,0x1e,0xeb,0x9d,0xa3,0x7b,0x24,0xbe,0x9c,0x9c,0x2e,0x24,0x23,0x28,0x9c,0xab,0xaf,0xbc,0xd0,0xae,0x5f,0xb7,0x44,0x1f,0x14,0x1b,0x9f,0x94,0x9f,0x46,0x2b,0x3d,0x29 +,0x3c,0xa7,0xaf,0x29,0x20,0x48,0x40,0x64,0xc5,0xc1,0x2d,0x38,0xb2,0xb5,0xc0,0xe7,0xba,0x57,0x2f,0x49,0xa8,0xb8,0xba,0xcd,0xd5,0x23,0x23,0xb7,0xac,0xe1,0x26,0x58 +,0xbb,0xad,0xef,0x3a,0x4e,0x66,0x54,0xad,0xa5,0x4b,0x31,0x2c,0x39,0xbb,0xa4,0xa4,0x7e,0x20,0x37,0xbf,0x9e,0x9a,0x37,0x1a,0x17,0x23,0xba,0x9d,0x4f,0x3e,0xc9,0x52 +,0xc5,0xc9,0xbc,0x29,0x25,0x2b,0xbe,0xaf,0xb7,0xbe,0x4f,0xaf,0xce,0xbd,0xc9,0xcd,0xb8,0x4c,0x3e,0x24,0x2d,0xaa,0xaa,0xd2,0xd4,0xaf,0xc7,0x37,0xd4,0xdf,0x25,0x1b +,0x32,0xa2,0xa5,0xaf,0xda,0x2a,0x1d,0x2f,0xa4,0xa7,0x5d,0x1a,0x1a,0xb6,0x99,0xa2,0xc5,0x28,0x2a,0xae,0xa4,0xc9,0x2f,0x36,0x38,0x50,0x72,0xd9,0xbe,0xb2,0x45,0x27 +,0xda,0xb6,0xa8,0xad,0x42,0x1e,0x25,0xad,0xa3,0xb1,0xab,0xbd,0x31,0x23,0xdf,0x9b,0xbf,0x2e,0x21,0x2e,0xbf,0xb8,0xba,0xcd,0x2f,0x2c,0xa6,0xae,0xb8,0xb8,0x24,0x1a +,0x29,0xe7,0xad,0xca,0xf3,0xac,0xc0,0xec,0x5a,0x2d,0x27,0x2d,0x27,0x3b,0xbe,0xaf,0xa7,0xac,0xbe,0x59,0x4c,0xa9,0xad,0x67,0x29,0x17,0x2b,0xaa,0x9a,0xa8,0xaf,0x34 +,0x37,0xa5,0xb8,0xae,0x4b,0x22,0x28,0x1d,0x37,0x99,0x9e,0xca,0x2d,0x35,0xbf,0xb6,0xc8,0x20,0x17,0x32,0xa4,0x9f,0xa8,0xde,0xd0,0x35,0x2a,0x3d,0x2b,0x2e,0x5b,0xcc +,0x27,0xcc,0x9d,0xb0,0x59,0x40,0x47,0xb4,0xad,0x3d,0x58,0x40,0x25,0x43,0xb0,0xa3,0xad,0x44,0x2d,0x36,0xbb,0xb9,0xba,0x55,0x46,0x39,0x2e,0xa7,0xa7,0xa5,0xad,0x2c +,0x2a,0x43,0xd4,0xb1,0x60,0x1c,0x1e,0x32,0xcd,0xad,0xad,0xd8,0x30,0x4b,0xb5,0xb0,0xaa,0x54,0x1f,0x23,0x3e,0x2e,0xb7,0x9e,0xb7,0xb9,0x47,0x3f,0xb7,0xad,0x21,0x24 +,0xc6,0xd2,0xba,0xaa,0xad,0xbc,0xbe,0xcd,0x38,0x2f,0xad,0xb8,0x38,0x19,0x28,0xac,0x9f,0xad,0x36,0x29,0x42,0xba,0xcc,0x57,0x2b,0x20,0x22,0xc8,0xa2,0x9a,0xad,0x75 +,0x32,0x58,0xbb,0x38,0x4d,0x2e,0x26,0x35,0xaf,0xbd,0xad,0xa8,0xbf,0x53,0x38,0x78,0xb6,0xba,0x25,0x2c,0x38,0xb9,0x9e,0xa2,0x45,0x3c,0x3a,0xa9,0xb2,0x5d,0x9a,0x1f +,0x1d,0x23,0xad,0x9c,0x32,0x38,0x2f,0x35,0xc8,0x3f,0xcb,0xcd,0x1a,0x44,0xaf,0xa7,0xb9,0x2c,0xcd,0x31,0x29,0x5d,0xc6,0xb5,0xc4,0x3b,0x11,0x2e,0xa8,0x9a,0x9b,0x5a +,0x1c,0x36,0xaf,0x6b,0xa9,0x38,0x18,0x1a,0xa7,0x98,0x9c,0x9f,0x4d,0x2a,0xcd,0x9e,0xa3,0xd7,0x1d,0x2c,0xe0,0xa3,0x9f,0xf4,0x45,0x34,0x23,0x1f,0x19,0x0e,0x4b,0xaa +,0xb9,0xa3,0xb2,0xc7,0xa8,0xaf,0x9d,0xc0,0x24,0xd8,0xb8,0xac,0xad,0x2a,0x16,0x2c,0xc9,0x93,0x9e,0x2f,0x0e,0x0e,0x10,0x4a,0x8f,0xb4,0xb8,0xe4,0x47,0x96,0x97,0xa7 +,0xcc,0x1d,0xd2,0xaa,0xc8,0xf3,0x27,0x18,0x3a,0xb1,0x9f,0x3d,0x1a,0x0f,0x1a,0x9b,0x93,0x97,0x2e,0x16,0xaf,0xa8,0x54,0xa9,0xcc,0xaf,0xb7,0x60,0x31,0x32,0x2f,0xbe +,0x30,0x2a,0x2c,0x1d,0x25,0x1e,0x9a,0xa4,0xad,0xa6,0x5c,0xba,0xa5,0x31,0x3b,0xad,0xa0,0x99,0x3d,0x1f,0x22,0x1b,0xc9,0xb8,0xd1,0x31,0x11,0x1d,0x38,0x88,0x8d,0x93 +,0x9c,0x1b,0x0f,0x1c,0x1f,0x0f,0xc2,0xbf,0x23,0xad,0x97,0x89,0x95,0x3f,0x20,0x1f,0x35,0x0b,0x0d,0x0f,0xde,0xb1,0x97,0x86,0x8e,0x92,0xaf,0x12,0x18,0x8f,0x8f,0x9a +,0x1a,0x03,0x11,0x2f,0x99,0xaf,0x27,0x67,0x1d,0x29,0x0b,0x1d,0xa1,0x95,0x8d,0x9c,0x8c,0x8a,0xb8,0x2b,0x1c,0x1f,0x9b,0xac,0x22,0x39,0x38,0x42,0x38,0x1c,0x1e,0x3d +,0x49,0x08,0x15,0x2e,0x96,0x85,0x9e,0xb8,0xcb,0xce,0x94,0x8d,0xad,0x9d,0x2b,0x0b,0x25,0x26,0x39,0x29,0x23,0x12,0x30,0x9d,0x4d,0x96,0xd0,0x2e,0x96,0x9a,0xb0,0x79 +,0x0e,0x1e,0x4f,0x95,0x85,0x9b,0x3e,0xd7,0x23,0x1a,0xb1,0x9e,0x2a,0x0f,0x04,0x02,0x31,0x9f,0x88,0x87,0xa6,0xbf,0xab,0x2f,0x1f,0xbf,0x97,0xbd,0x14,0xd0,0x8c,0x93 +,0xc2,0x0b,0x0c,0x29,0xee,0x11,0x1d,0x9b,0x33,0xac,0xab,0xb3,0x8a,0x9a,0x19,0x0b,0x14,0x8d,0x8a,0x30,0x29,0x1d,0x48,0x92,0x90,0xa1,0x1d,0x0d,0x06,0xdf,0x2e,0x18 +,0x9d,0x97,0x8d,0xa3,0x19,0xae,0x9c,0xa1,0x6c,0x11,0x24,0xa3,0x4f,0x1b,0x15,0x1f,0x99,0xa4,0x10,0x1f,0x89,0xae,0x2a,0xba,0x92,0x88,0xf9,0x11,0x1a,0x0f,0x6e,0x99 +,0xa3,0x9d,0x59,0x2b,0x2f,0x17,0x2c,0x40,0x0f,0x08,0x9a,0x84,0x99,0xcc,0x20,0x91,0x89,0x9b,0x2d,0x2a,0x2b,0x3a,0x16,0x2f,0x9e,0xf1,0x3f,0x16,0x0d,0x1a,0xa2,0xbb +,0x6a,0x93,0x27,0x38,0x96,0x87,0x81,0xb7,0x14,0x2b,0x2e,0x16,0x10,0x2c,0x86,0xab,0x1f,0x26,0xad,0x8d,0x93,0x1f,0x0c,0x98,0x9b,0xaf,0x35,0x41,0x87,0x85,0x87,0x88 +,0x8f,0xb0,0x1e,0x09,0x21,0x5b,0x0a,0x0c,0x07,0x00,0x01,0x00,0x0b,0x9f,0x37,0x00,0x09,0x0a,0x16,0x1b,0x0b,0x1b,0x39,0x1e,0x2b,0xc2,0x26,0x95,0x27,0x29,0x9b,0xb8 +,0x32,0x34,0xca,0xa6,0x82,0xeb,0x8e,0x83,0x8b,0x8c,0xa1,0x87,0x80,0x87,0xa2,0x9d,0x9c,0x8d,0x87,0x8d,0x8c,0x98,0x2c,0x20,0x0f,0x1a,0x82,0x8e,0xc8,0xdc,0x4b,0x8d +,0x8e,0x97,0x98,0x2b,0x0c,0x14,0x34,0x1d,0x10,0x18,0x37,0xb2,0x19,0x08,0x13,0x16,0x11,0x17,0x15,0x15,0x1a,0x0e,0x08,0x0c,0x35,0xa2,0x9f,0x23,0x14,0x42,0x2b,0x18 +,0x0e,0x2e,0x3d,0x19,0x18,0x26,0xaa,0xa1,0xb6,0xb7,0xd0,0x21,0x47,0x1f,0x2f,0xb3,0xd1,0x2f,0x21,0x2a,0xb2,0x94,0xd8,0xa5,0x9b,0xa6,0xb0,0x33,0xb5,0xc2,0xb4,0x9a +,0x8a,0x92,0xa7,0x32,0x1b,0x29,0xf4,0x95,0x8b,0x8c,0x90,0x88,0x85,0x84,0x82,0x84,0x97,0x9e,0x9a,0x90,0x86,0x8c,0x8a,0x89,0x89,0x92,0xad,0xb2,0x9c,0x33,0x10,0x0d +,0x0c,0x0c,0x05,0x03,0x01,0x02,0x03,0x04,0x0b,0x0e,0x0c,0x06,0x02,0x06,0x0b,0x10,0x08,0x05,0x0c,0x17,0x38,0xa5,0xa9,0x23,0x11,0x1a,0x33,0x29,0x44,0x29,0x28,0x25 +,0x1e,0xb1,0x9b,0x93,0x8c,0x8b,0x98,0x93,0x8e,0x8f,0x91,0x8c,0x84,0x85,0x8a,0x8d,0x90,0x9a,0xa9,0x36,0x44,0x99,0x8f,0x96,0x9c,0x94,0x92,0x9b,0x9a,0xb7,0x27,0x19 +,0x23,0xb9,0x98,0x9d,0x61,0xb7,0xb2,0xb5,0xab,0x3d,0x20,0x0f,0x10,0x19,0x18,0x1d,0x0f,0x0b,0x16,0x2c,0x2b,0x26,0x2a,0x1b,0x0f,0x0f,0x13,0x1a,0x13,0x10,0x0e,0x19 +,0x22,0x44,0xac,0xaf,0x5d,0x2e,0x33,0x2a,0xe0,0x2f,0x1f,0x1b,0x26,0x12,0x10,0x37,0xac,0xb7,0x2e,0x42,0x5d,0x68,0xca,0xc5,0x24,0x26,0xb9,0x95,0x99,0xa5,0x5b,0x57 +,0x9f,0x8f,0x85,0x84,0x87,0x8f,0x8d,0x87,0x81,0x81,0x85,0x8b,0x94,0x93,0x8f,0x87,0x85,0x8c,0x97,0x9a,0xab,0xc4,0xa0,0xaf,0x2a,0x18,0x08,0x01,0x04,0x09,0x0b,0x07 +,0x07,0x09,0x09,0x0b,0x0d,0x07,0x01,0x02,0x03,0x09,0x06,0x04,0x0a,0x11,0x4f,0xa0,0xaa,0x1e,0x18,0x14,0x19,0xcf,0xb6,0x4a,0x23,0xc5,0xad,0xca,0x9a,0x93,0x8f,0x8e +,0x93,0x93,0x9f,0x94,0x88,0x8e,0x8b,0x8d,0x93,0x99,0x90,0x8e,0x94,0x94,0xb1,0xa1,0x95,0x90,0x8f,0x97,0xa2,0xc8,0x98,0x92,0xae,0x1f,0x2a,0xa8,0xa2,0x99,0xa4,0x37 +,0x2e,0x25,0x1f,0xba,0x65,0x17,0x10,0x1f,0x1d,0x1b,0x13,0x12,0x1a,0x0e,0x24,0x5a,0xdc,0x17,0x32,0x3f,0x17,0x10,0x0a,0x0d,0x0a,0x0c,0x1b,0xac,0xa2,0x6c,0x44,0x38 +,0x16,0x18,0x20,0xb1,0x38,0x0c,0x0f,0x08,0x17,0xa5,0x98,0x9d,0x2e,0x23,0x18,0x26,0x9b,0x9c,0x37,0x1e,0xb7,0x8f,0x8b,0x9a,0xdb,0xa9,0x97,0x8a,0x87,0x8a,0x8b,0x8b +,0x82,0x81,0x81,0x85,0x8b,0x8f,0x8c,0x87,0x87,0x85,0x8c,0x8e,0x8a,0x8c,0xa5,0x4e,0xd4,0x56,0x1a,0x07,0x08,0x07,0x06,0x0c,0x16,0x0e,0x06,0x00,0x05,0x0b,0x0f,0x12 +,0x05,0x02,0x03,0x09,0x0e,0x0d,0x04,0x0c,0x1e,0x3f,0x58,0x36,0x1c,0x1e,0x9d,0x9d,0xf1,0x13,0x0d,0x1c,0xe9,0xea,0xa0,0x97,0x97,0x94,0x8d,0x8a,0x9d,0x9d,0x97,0x90 +,0x8d,0x8d,0x8b,0x91,0x9a,0x8f,0x8c,0x87,0xa4,0xd4,0x9d,0x8f,0x92,0x9f,0x9f,0xa5,0xa0,0x95,0x8d,0x2b,0x16,0x52,0x8f,0x8a,0xa5,0x6f,0xb1,0xdb,0xb7,0x9b,0xa9,0x1a +,0x08,0x11,0x1e,0x2b,0x2e,0x33,0x13,0x0f,0x17,0x1f,0x15,0x0d,0x2f,0x2f,0x21,0x10,0x12,0x16,0x0d,0x0b,0x22,0x2f,0x17,0x1c,0x2b,0xa0,0x3c,0xce,0x3b,0x19,0x15,0x15 +,0x25,0x0f,0x0e,0x23,0x94,0x95,0xdc,0x23,0x2f,0x1e,0x2f,0x99,0xaf,0x2b,0x11,0xbe,0x8c,0x8f,0x90,0x94,0x9a,0x9e,0x9a,0x85,0x85,0x8f,0x8d,0x83,0x83,0x83,0x82,0x88 +,0x8d,0x8d,0x83,0x85,0x96,0xb2,0x92,0x88,0x8e,0x98,0x79,0x2c,0x0f,0x0f,0x15,0x08,0x01,0x04,0x1a,0x1d,0x09,0x08,0x05,0x03,0x07,0x07,0x07,0x05,0x00,0x08,0x1a,0x1a +,0x0e,0x09,0x0d,0x0e,0x12,0xec,0x2d,0x0c,0x1b,0xa5,0x8e,0xa3,0x28,0x22,0x32,0x35,0xac,0x98,0xb6,0x25,0xbd,0x88,0x89,0x86,0x89,0x8e,0x9f,0xbf,0x8c,0x97,0xcd,0x9d +,0x86,0x85,0x8d,0x98,0x95,0x98,0xa5,0x98,0x9c,0xbd,0x21,0x9f,0x8b,0x93,0xa2,0xa8,0xa9,0x36,0x1c,0x51,0x9f,0x52,0x2f,0xad,0x9b,0x9c,0x26,0x0c,0x0d,0x0c,0x18,0x38 +,0x19,0x07,0x0f,0xa9,0x9c,0xe4,0x20,0x18,0x10,0x09,0x0a,0x0c,0x0b,0x0d,0x2a,0xa4,0xc5,0x25,0x54,0x40,0x1a,0x2c,0x2c,0x14,0x07,0x18,0xab,0xbf,0x30,0x2e,0x1f,0x15 +,0x18,0x30,0xbb,0x13,0x1e,0x9d,0x8d,0x8d,0xb8,0xc7,0xac,0x1b,0x4d,0x92,0x9a,0x91,0x89,0x81,0x80,0x81,0x84,0x8a,0x8b,0x8e,0x90,0x8b,0x8f,0x91,0x85,0x80,0x85,0x8c +,0x89,0x88,0x9b,0x5a,0x1e,0x11,0x0b,0x0d,0x0f,0x1b,0x19,0x10,0x0e,0x03,0x02,0x08,0x0d,0x04,0x02,0x0c,0x21,0x17,0x08,0x07,0x05,0x02,0x0a,0x11,0x09,0x0a,0x10,0xb8 +,0x95,0xa6,0xdb,0xbd,0x29,0x1d,0x2f,0x31,0x20,0x24,0x9d,0x89,0x8c,0x8f,0x97,0xa6,0xb2,0xa1,0xa2,0x9e,0x9d,0xc0,0x8c,0x86,0x8b,0x8b,0x8c,0x95,0x99,0x8c,0x94,0xa6 +,0xaa,0x94,0x8a,0x92,0xa3,0xc2,0xb9,0xaa,0x46,0xbd,0xed,0x1a,0x2e,0x8f,0x88,0x90,0xb5,0x2c,0x19,0x1d,0x2e,0x1e,0x0d,0x0a,0x29,0xa8,0xb2,0x2a,0x1f,0x24,0x17,0x0d +,0x0c,0x0b,0x0b,0x0b,0x1f,0xdd,0x33,0xd0,0xef,0x13,0x16,0x1d,0x12,0x11,0x12,0x1a,0xc3,0x9f,0x28,0x1d,0x28,0x1e,0x1e,0x15,0x0b,0x07,0x1c,0x9e,0x9b,0xa6,0x5f,0xbd +,0xaf,0xaa,0x37,0x31,0xbf,0x37,0x9c,0x8b,0x8c,0x8b,0x86,0x85,0x87,0x8b,0x8e,0x8b,0x8b,0x8a,0x86,0x82,0x82,0x85,0x88,0x85,0x8a,0x98,0x9f,0xa7,0x99,0x9c,0x9e,0x9f +,0x23,0x1a,0x0f,0x0d,0x0a,0x02,0x03,0x04,0x0b,0x0c,0x0e,0x13,0x0b,0x0d,0x0d,0x08,0x07,0x04,0x04,0x06,0x0d,0x11,0x0e,0x0e,0x2a,0x2f,0x26,0x18,0x10,0x21,0x3a,0xd6 +,0x42,0xa5,0xae,0x9f,0x9e,0xa9,0xa6,0xbe,0xbb,0xaf,0xab,0x9f,0x8d,0x8e,0x8f,0x9c,0x99,0x8d,0x98,0xb3,0xb6,0x99,0x8c,0x88,0x86,0x86,0x8a,0x8a,0x91,0xa5,0x48,0x22 +,0x38,0xb2,0xc6,0xaf,0x9e,0x9c,0x96,0x9b,0x9f,0xc6,0x34,0x43,0x1d,0x19,0x35,0x49,0x3e,0x4c,0x28,0x30,0x34,0x17,0x18,0x12,0x0f,0x17,0x1e,0x1a,0x0e,0x15,0x2b,0x19 +,0x10,0x0d,0x10,0x1c,0x2d,0x45,0xa6,0x9a,0xac,0xa8,0x52,0xc8,0x1e,0x11,0x18,0x33,0xab,0xc1,0xaf,0xa1,0x93,0x98,0xa0,0x7d,0xd5,0xda,0xae,0xaa,0xcf,0x9c,0x99,0x8e +,0x96,0xce,0x36,0xbf,0xad,0xa0,0x6e,0x2d,0xa6,0xaf,0x4a,0x42,0xce,0xb9,0x3e,0x23,0x27,0x29,0xbf,0xaf,0x9d,0x9d,0xa8,0x9b,0xb0,0x2b,0x1d,0x10,0x16,0x28,0x1c,0x2c +,0x31,0xaf,0x91,0xa7,0xbd,0x3a,0x1f,0x3c,0x18,0x1c,0xe7,0xc5,0x9e,0xa2,0xad,0xcb,0x56,0x4c,0x22,0x27,0x4f,0x36,0xd7,0xb4,0xae,0x92,0x96,0x9c,0xa5,0x37,0x1c,0x22 +,0xcf,0xa3,0x9b,0x99,0xa0,0xa0,0xaa,0x33,0x2c,0x1f,0x23,0x23,0x33,0x27,0xb7,0xa6,0x97,0x8f,0xad,0xea,0x1b,0x22,0x1c,0x12,0x0f,0x1d,0x6b,0xa8,0x36,0x19,0x20,0x28 +,0x20,0x0f,0x0a,0x12,0x42,0x20,0x18,0x27,0x28,0x2c,0x27,0x1e,0x18,0x12,0x29,0xbe,0x9d,0xa3,0xa1,0x8f,0x9c,0xab,0xd3,0xb6,0xa1,0x9a,0xa4,0x98,0x8e,0x8a,0x83,0x84 +,0x84,0x8d,0x96,0x9d,0x9e,0x9f,0x97,0x90,0x94,0x8d,0x95,0xa9,0xbe,0xad,0xb7,0x48,0x21,0x19,0x2d,0x29,0x1e,0x48,0xf1,0x45,0x39,0x1c,0x20,0x1d,0x13,0x19,0x3b,0x36 +,0x34,0x34,0x22,0x1a,0x0e,0x0e,0x12,0x19,0x16,0x11,0x15,0x4b,0x93,0x99,0x45,0x29,0x25,0x2d,0x25,0x1f,0x3d,0xbb,0x9b,0x9d,0xa3,0xaf,0xbb,0xa7,0xa5,0x5b,0x1c,0x23 +,0x39,0x3f,0x3c,0x26,0x17,0x15,0x12,0x0e,0x05,0x06,0x08,0x0d,0x1b,0x14,0x10,0x13,0x1a,0x1b,0x25,0x1d,0x32,0x47,0x33,0xb1,0x9d,0x8e,0x87,0x8a,0x94,0x9d,0x96,0x95 +,0x9b,0x9d,0x8e,0x87,0x86,0x85,0x8c,0x8d,0x8b,0x87,0x8b,0x91,0x96,0x91,0x8a,0x8e,0x8d,0x8e,0x92,0x91,0x9d,0xbb,0x4f,0x1b,0x1b,0xd9,0xaf,0xbc,0x33,0x3b,0x29,0x1c +,0x11,0x0a,0x0c,0x0b,0x09,0x0a,0x16,0x1b,0x1d,0x39,0x24,0x12,0x13,0x14,0x0b,0x11,0x18,0x19,0x20,0x29,0x20,0x1e,0x24,0x22,0x2f,0x27,0x1a,0x12,0x34,0xee,0xb6,0x9c +,0x9c,0xac,0xec,0xbb,0x58,0x45,0xb6,0x9c,0x9c,0xa2,0xb1,0x9e,0xae,0xc8,0xc9,0xdc,0xd4,0x48,0x29,0x2d,0xd4,0xa8,0x9c,0xad,0xaa,0xb6,0xbf,0x31,0x2c,0x46,0xa6,0x95 +,0x8f,0x90,0x94,0x8f,0x8c,0x84,0x83,0x83,0x86,0x88,0x86,0x85,0x83,0x85,0x89,0x8f,0x9d,0x54,0x24,0x27,0x1f,0x10,0x0c,0x0a,0x06,0x06,0x06,0x04,0x05,0x03,0x02,0x05 +,0x05,0x07,0x07,0x0b,0x0f,0x13,0x11,0x0d,0x0f,0x1a,0x16,0x15,0x17,0x19,0x2a,0x26,0x37,0xd3,0xac,0xa4,0xa8,0xb8,0xcd,0xa3,0x9b,0x9f,0x9f,0x97,0x90,0x91,0x96,0x96 +,0x97,0x93,0x8f,0x8c,0x8c,0x92,0x99,0x99,0x98,0x98,0x9a,0x9f,0xa3,0xc6,0xea,0xc8,0xbd,0xaa,0xc1,0xdc,0x49,0x29,0x25,0x3e,0x36,0x2c,0x2d,0x2c,0x27,0x29,0x29,0x2f +,0x4f,0x3d,0x7a,0x2e,0x31,0x31,0xe4,0xc4,0xd0,0xdd,0x30,0xd3,0xc8,0x59,0x33,0x24,0x2d,0x6e,0xc1,0x5c,0x2b,0x2d,0x44,0x5f,0x2f,0x27,0x1c,0x23,0x34,0x2b,0x2e,0xbc +,0xb8,0x3b,0x1e,0x15,0x1c,0x2a,0x2c,0x16,0x17,0x14,0x1d,0x23,0x1e,0x37,0xbb,0xac,0xa3,0x9d,0x9a,0x8e,0x8b,0x8a,0x87,0x85,0x85,0x83,0x83,0x84,0x83,0x86,0x8b,0x8c +,0x8c,0x8a,0x91,0xa0,0xbd,0x45,0x51,0x36,0x18,0x0b,0x08,0x08,0x0a,0x0a,0x07,0x06,0x07,0x08,0x0a,0x09,0x0a,0x0b,0x0c,0x0c,0x0d,0x0b,0x0b,0x0f,0x19,0x26,0x30,0x2e +,0x28,0x29,0x35,0xbe,0xdf,0xc7,0x78,0xd1,0xa7,0x9d,0x9c,0x9d,0x9c,0x91,0x95,0x9f,0xa1,0x9a,0x93,0x93,0x95,0x9d,0x97,0x95,0x96,0x99,0x93,0x97,0x91,0x93,0x9c,0x9d +,0x9e,0x97,0xa1,0xa8,0xa0,0x9f,0xa1,0xab,0x3f,0xae,0xa0,0xae,0x73,0x3e,0x5c,0x4d,0x49,0x2d,0x31,0x43,0x36,0x1f,0x18,0x1d,0x38,0x2b,0x16,0x0e,0x10,0x16,0x14,0x13 +,0x1b,0x21,0x1b,0x17,0x13,0x16,0x1e,0x1a,0x16,0x14,0x1e,0x29,0x2f,0x31,0x2f,0x4b,0x1f,0x1f,0x1c,0x1d,0x1e,0x19,0x2c,0x42,0x33,0x3a,0xc3,0x53,0xe0,0x53,0x5c,0xb5 +,0xa6,0xb6,0xc7,0x97,0x8b,0x87,0x87,0x87,0x86,0x83,0x82,0x85,0x85,0x84,0x83,0x83,0x83,0x85,0x85,0x87,0x91,0x9f,0xa4,0xb4,0x2c,0x14,0x0a,0x09,0x0d,0x0c,0x09,0x07 +,0x05,0x07,0x04,0x04,0x08,0x0d,0x0b,0x09,0x0c,0x0d,0x0f,0x1b,0x1d,0x0f,0x0e,0x0e,0x16,0x1a,0x26,0x24,0x3f,0x73,0x2f,0xbf,0xaa,0xac,0xca,0xab,0xac,0x9d,0x94,0x9c +,0xa0,0x9a,0x99,0x9e,0x97,0x94,0x9b,0x93,0x93,0x9a,0x9b,0x9a,0x98,0x9d,0x9d,0xb2,0xc6,0xac,0xaf,0xa0,0x97,0x98,0xa1,0xa3,0x9e,0xb7,0xce,0x4b,0x56,0xd1,0x4b,0x65 +,0xe2,0xc2,0xbe,0xd0,0x5a,0x3d,0x1c,0x0e,0x14,0x1b,0x23,0x29,0x21,0x2e,0x3b,0x4e,0x2a,0x1f,0x2a,0x1f,0x19,0x10,0x14,0x21,0x2f,0xdd,0x34,0x2a,0x21,0x1f,0x2f,0x26 +,0x1d,0x24,0x21,0x25,0x6c,0xc7,0xcc,0xcc,0x21,0x16,0x1c,0x19,0x1e,0x18,0x1c,0x39,0xbf,0xae,0xa4,0xaa,0xa4,0x9b,0x91,0x8c,0x8a,0x87,0x88,0x84,0x84,0x81,0x82,0x81 +,0x84,0x89,0x8a,0x8a,0x8d,0x8d,0x95,0xae,0xac,0x35,0x1b,0x17,0x18,0x10,0x09,0x07,0x05,0x07,0x0b,0x0d,0x0b,0x07,0x04,0x07,0x0a,0x0a,0x0d,0x11,0x13,0x0f,0x18,0x20 +,0x29,0x23,0x16,0x0f,0x16,0x2a,0x43,0x47,0x38,0xc1,0xa1,0x98,0x9d,0xb5,0xb9,0x66,0xb0,0x9e,0xa1,0x9c,0x92,0x8e,0x91,0x90,0x8e,0x8f,0x9a,0xa3,0xa7,0xa3,0x9d,0x8f +,0x93,0x92,0x8d,0x97,0xa7,0x9f,0x98,0xa4,0xc0,0x4c,0x3c,0xa2,0x97,0x9a,0x9f,0xa6,0x4b,0x26,0xe3,0x28,0x28,0x21,0x26,0x36,0x5b,0x3f,0x3a,0xbc,0x3f,0x22,0x1c,0x18 +,0x13,0x10,0x12,0x22,0x40,0x48,0x1d,0x14,0x13,0x13,0x19,0x2a,0x1a,0x1d,0x1e,0x16,0x22,0x35,0xae,0x36,0x1b,0x1a,0x18,0x1f,0x2b,0x21,0x1a,0x22,0x23,0x28,0x27,0x2c +,0xd1,0xc7,0xc5,0x37,0x56,0x9c,0x8e,0x8a,0x8b,0x8b,0x8b,0x87,0x84,0x84,0x83,0x83,0x84,0x84,0x82,0x83,0x83,0x8b,0x9b,0xa5,0xa1,0x9d,0x4e,0x1c,0x12,0x14,0x1a,0x14 +,0x0d,0x05,0x04,0x02,0x03,0x06,0x08,0x0b,0x07,0x0a,0x0d,0x12,0x15,0x0d,0x0f,0x0d,0x0c,0x0f,0x11,0x1d,0x2b,0xdd,0xb1,0xda,0x2f,0x49,0xc2,0xd6,0x47,0x2a,0x40,0x9e +,0x8c,0x8f,0x91,0x92,0x9d,0x97,0x99,0x98,0x9e,0x9d,0x9e,0x9c,0x8d,0x8b,0x8d,0x93,0xa0,0xaa,0x9b,0xa4,0xbc,0xcf,0xe9,0xab,0x8f,0x8f,0x9e,0x4b,0xc3,0xa5,0xa5,0xb1 +,0x57,0x3a,0x3a,0xce,0x4d,0x9f,0xad,0xc2,0xd0,0x23,0x20,0x17,0x20,0x18,0x20,0x28,0x1f,0x1e,0x1a,0x29,0x32,0x28,0x19,0x1a,0x14,0x20,0x2b,0x26,0x1b,0x10,0x17,0x1b +,0x2b,0x1e,0x14,0x14,0x17,0xb1,0xc2,0x3b,0x26,0x14,0x17,0x1c,0x62,0x35,0x1f,0x1f,0x4e,0x59,0x4f,0xa9,0xa3,0xab,0xab,0xa3,0xa7,0x97,0x8b,0x87,0x83,0x82,0x81,0x82 +,0x81,0x81,0x84,0x84,0x85,0x89,0x8b,0x8b,0x8b,0x90,0x97,0xaa,0x2f,0x25,0x23,0x0e,0x03,0x02,0x07,0x11,0x17,0x0e,0x09,0x06,0x08,0x0e,0x09,0x08,0x08,0x04,0x0c,0x13 +,0x19,0x15,0x13,0x1b,0x27,0x2a,0x20,0x1a,0x10,0x12,0x2e,0x7e,0xc1,0xcf,0x3e,0x9e,0x98,0xa4,0xbd,0x2a,0x39,0xb2,0xa0,0x96,0x9b,0x98,0x91,0x96,0x91,0x90,0xa1,0xc3 +,0x3e,0xad,0x8c,0x8a,0x90,0xc8,0x2f,0x97,0x8a,0x8d,0x9e,0xb2,0xa8,0x91,0x93,0xa2,0xad,0xd8,0x56,0x2f,0xa0,0x9b,0x9b,0x98,0x2e,0x17,0x3a,0xb0,0x98,0x9d,0x1f,0x17 +,0x14,0x1e,0xcc,0x1b,0x0e,0x03,0x0c,0xbf,0x9c,0x92,0x19,0x02,0x06,0x1a,0x9f,0xa1,0x0f,0x0c,0x11,0x43,0x9c,0x15,0x01,0x00,0x10,0xa0,0x88,0x9a,0x0c,0x06,0x0c,0xaa +,0x87,0xac,0x12,0x07,0x0e,0x97,0x8c,0x1e,0x05,0xae,0x83,0x80,0x80,0x8a,0x37,0xc9,0x86,0x80,0x80,0x85,0x8c,0x8f,0x80,0x86,0x90,0x11,0x1e,0x82,0x80,0x8e,0x00,0x1e +,0x0c,0x0a,0x8f,0x2e,0x0d,0x03,0x01,0x05,0x11,0x0b,0x00,0x04,0x00,0x19,0x99,0x06,0x00,0x01,0x00,0x17,0x3f,0x07,0x02,0x00,0x0a,0xf2,0x1e,0x09,0x00,0x9d,0x80,0x80 +,0x86,0x9f,0x8c,0x94,0x8a,0x80,0x81,0x80,0x87,0x87,0x80,0x81,0x89,0xe5,0x88,0x80,0x81,0x80,0x97,0x28,0x24,0x87,0x80,0x84,0x8a,0xab,0xb3,0x8a,0x95,0x14,0x00,0x08 +,0x8e,0x83,0x88,0x0d,0x00,0x02,0x01,0xbc,0x22,0x02,0x02,0x00,0x08,0x0c,0x01,0x00,0x00,0x04,0x55,0x98,0x0a,0x00,0x01,0x00,0x0b,0x41,0x0e,0x01,0x02,0x06,0x1d,0x05 +,0x02,0x00,0x2b,0x88,0x80,0x93,0x04,0x03,0x12,0x8b,0x80,0x83,0x82,0x8e,0x8a,0x81,0x89,0xa9,0x21,0x8c,0x80,0x81,0x80,0x8e,0x1c,0xc0,0x82,0x80,0x80,0x80,0x83,0x83 +,0x81,0x80,0x88,0x9d,0x86,0x80,0x81,0x80,0x89,0x6f,0x1d,0x91,0x80,0x80,0x82,0x88,0xa3,0x92,0x96,0xba,0x0d,0x08,0x93,0x89,0x85,0x17,0x00,0x02,0x00,0x2b,0x9c,0x0d +,0x04,0x01,0x01,0x04,0x00,0x01,0x00,0x08,0x1d,0xfc,0x0b,0x00,0x01,0x00,0x08,0x25,0x0d,0x03,0x00,0x00,0x05,0x00,0x02,0x00,0x0f,0xb9,0xa0,0x39,0x00,0x01,0x00,0x0b +,0x96,0x9c,0xc7,0x11,0x07,0x12,0x12,0x29,0x0a,0xbc,0x85,0x85,0x84,0x1e,0x06,0x0a,0x99,0x80,0x81,0x83,0x8b,0x9e,0x99,0xb0,0xa8,0x9c,0x8c,0x80,0x83,0x80,0x8e,0x2a +,0x1e,0x91,0x80,0x80,0x80,0x87,0x9f,0x9d,0x8f,0x8f,0x90,0x91,0x80,0x81,0x80,0x86,0xc9,0x1c,0x9f,0x80,0x80,0x80,0x86,0x9e,0xaa,0x98,0xa7,0x95,0xc1,0x89,0x8f,0x8c +,0xae,0x00,0x01,0x06,0x94,0x87,0x91,0xb4,0x1e,0x08,0x0f,0x17,0xc6,0x42,0x8f,0x81,0x84,0x85,0x12,0x0b,0x1e,0x88,0x80,0x81,0x88,0xc0,0x11,0xc5,0x92,0x8c,0x9b,0x8f +,0x80,0x85,0x86,0x10,0x07,0x05,0x39,0x84,0x87,0xac,0x09,0x00,0x02,0x04,0x08,0x05,0x06,0x1c,0x0d,0x0d,0x01,0x00,0x00,0x01,0x2f,0x39,0x06,0x00,0x00,0x00,0x00,0x01 +,0x01,0x00,0x0e,0x0c,0x0a,0x01,0x00,0x00,0x00,0x3a,0xa5,0x09,0x00,0x00,0x00,0x02,0x08,0x0a,0x00,0x1e,0x2b,0xb8,0x0c,0x00,0x00,0x04,0x8e,0x81,0xa6,0x0c,0x02,0x12 +,0x9f,0x95,0x8b,0x5b,0x89,0x81,0x80,0x8a,0x0d,0x14,0x99,0x80,0x81,0x80,0x84,0x96,0xa2,0x85,0x80,0x80,0x83,0x81,0x80,0x80,0x80,0x92,0x89,0x80,0x80,0x80,0x80,0x80 +,0x8e,0x98,0x80,0x82,0x80,0x8e,0x8c,0x80,0x82,0x82,0x0d,0x08,0x14,0x91,0x80,0x88,0x2e,0x04,0x00,0x13,0xd0,0x9e,0x0f,0x09,0xac,0x30,0xa7,0x03,0x00,0x00,0x12,0x86 +,0x95,0x0f,0x01,0x00,0x04,0x10,0xd9,0x0e,0x00,0x1b,0x13,0xca,0x07,0x00,0x00,0x0b,0x8c,0x8e,0x1a,0x03,0x00,0x05,0x17,0xcb,0x23,0x00,0x2c,0x2f,0x9f,0x1a,0x00,0x03 +,0x07,0x8e,0x85,0xbb,0x0b,0x00,0x07,0x30,0xaf,0x9c,0x01,0x1b,0x77,0xae,0xbd,0x00,0x05,0x06,0x92,0x80,0x91,0x1d,0x04,0x06,0x56,0xb3,0x88,0x1f,0x1e,0x8e,0x98,0x82 +,0x17,0x0d,0x1b,0x8f,0x80,0x87,0x9b,0x21,0x0f,0xca,0x9f,0x84,0x94,0x11,0x8d,0x8e,0x82,0x2b,0x01,0x14,0xa2,0x80,0x85,0x95,0x29,0x05,0x1f,0x8c,0x82,0x83,0x48,0x87 +,0x80,0x80,0x85,0xb3,0x8b,0x84,0x80,0x80,0x80,0x8b,0x1c,0xc0,0x88,0x89,0x8c,0x07,0x14,0xe9,0x27,0x2a,0x00,0x03,0x00,0x19,0x97,0x19,0x02,0x00,0x00,0x05,0x0c,0x29 +,0x09,0x04,0x30,0x22,0xcb,0x06,0x01,0x0b,0x51,0x81,0x8f,0x5e,0x0f,0x09,0xba,0x93,0x86,0x8c,0x2a,0x89,0x8a,0x83,0x9a,0x19,0x9f,0x8b,0x80,0x81,0x84,0x9a,0x23,0x9c +,0x84,0x84,0x80,0xb2,0x8b,0x85,0x84,0x8c,0x17,0x3e,0xa9,0x85,0x80,0x8b,0xd3,0x06,0x11,0xba,0x9b,0x86,0x1e,0x28,0xba,0xad,0x9d,0x05,0x09,0x13,0x97,0x83,0xaa,0x18 +,0x04,0x03,0x19,0xbc,0x89,0x14,0x0b,0xaf,0xa9,0xa0,0x04,0x05,0x0e,0xd1,0x84,0x92,0x2c,0x06,0x00,0x1a,0xb9,0x94,0x0f,0x08,0xb4,0x3d,0x4a,0x04,0x02,0x07,0x1f,0x85 +,0x96,0x16,0x04,0x00,0x21,0xa5,0x86,0x9b,0xb6,0x80,0x87,0x80,0x98,0xa1,0x88,0x85,0x80,0x81,0x80,0x99,0x36,0x8b,0x8b,0x81,0x9c,0x2b,0x90,0xca,0xc8,0x05,0x00,0x03 +,0x0e,0x8c,0xb2,0x09,0x04,0x00,0x0a,0x0f,0xa8,0x15,0x08,0xb1,0x24,0x54,0x05,0x03,0x0d,0x35,0x81,0x8f,0x2f,0x0b,0x02,0x2c,0x43,0x8d,0x43,0x30,0x8b,0x9c,0x95,0x0b +,0x0e,0x53,0x8e,0x80,0x8b,0xaa,0x14,0x0d,0xa8,0x97,0x89,0xb9,0x9c,0x85,0x8e,0x94,0x09,0x10,0x35,0x8e,0x80,0x8b,0xae,0x0a,0x16,0xbd,0xb7,0xa6,0x2d,0x92,0x94,0x9f +,0x2d,0x02,0x07,0x1a,0x88,0x82,0xb7,0x0f,0x05,0x15,0x17,0x26,0x27,0x2e,0x94,0x9b,0x9e,0x0c,0x00,0x04,0x29,0x83,0x8d,0x5a,0x09,0x06,0x12,0x16,0x2a,0x0e,0xc5,0x94 +,0x98,0x2e,0x00,0x02,0x07,0x99,0x82,0x9b,0x16,0x01,0x0b,0x1a,0x2a,0x1f,0x2d,0x87,0x82,0x84,0xad,0x1b,0xaf,0x87,0x80,0x81,0x80,0x8c,0x8c,0x82,0x81,0x83,0x93,0x87 +,0x81,0x80,0x94,0x09,0x05,0x08,0xac,0x94,0x46,0x0c,0x00,0x04,0x05,0x09,0x02,0x04,0x1b,0x7b,0xd5,0x07,0x00,0x02,0x0e,0x9e,0xa9,0x1f,0x07,0x07,0x14,0x2d,0x1a,0x19 +,0x4d,0x99,0x8e,0x31,0x0d,0x07,0x23,0x8f,0x89,0x8b,0xbd,0x32,0xd7,0x97,0x9e,0xa8,0x8c,0x89,0x87,0xb3,0x4f,0x6f,0xaa,0x89,0x8b,0x8b,0xab,0x2a,0x3f,0x9f,0xba,0xb7 +,0x8a,0x83,0x8e,0x12,0x0a,0x1e,0xa5,0x90,0x97,0x9f,0x1f,0x17,0x27,0xc1,0x23,0x1c,0x97,0x89,0x97,0x08,0x00,0x0a,0xad,0x86,0x8e,0x5f,0x0b,0x06,0x0c,0x27,0x18,0x30 +,0xa1,0x92,0x99,0x0a,0x02,0x03,0x25,0x8d,0x8f,0x2c,0x05,0x03,0x05,0x0e,0x2f,0xa7,0xac,0x65,0x0c,0x03,0x03,0x06,0x24,0x9b,0x8e,0x97,0xaf,0x2c,0xcf,0xa4,0x8b,0x80 +,0x81,0x80,0x8f,0x98,0x88,0x82,0x80,0x81,0x83,0x8b,0x8f,0x9f,0x34,0x15,0xc3,0x91,0x8c,0xd8,0x00,0x02,0x00,0x1b,0x3d,0x10,0x04,0x03,0x06,0x0d,0x0b,0x06,0x23,0x3f +,0xc7,0x0e,0x03,0x02,0x14,0x9e,0x94,0xa7,0x14,0x14,0x12,0x18,0x13,0x9b,0x8a,0x8d,0xb2,0x0c,0x1a,0x4f,0x8b,0x84,0x8a,0xc9,0x55,0x36,0xcb,0x24,0xef,0x82,0x82,0x84 +,0x18,0x0a,0x12,0x97,0x83,0x88,0x93,0x33,0x2f,0xb9,0xab,0x19,0x8f,0x8c,0x81,0xa8,0x05,0x06,0x13,0x8b,0x88,0x8a,0x6e,0x21,0x0b,0x11,0x0d,0xad,0x95,0x94,0xac,0x05 +,0x15,0x0c,0x9e,0x9b,0xa0,0x3b,0x35,0x10,0x0d,0x05,0x0f,0x89,0x8c,0x91,0x05,0x05,0x02,0xb9,0xa0,0x73,0x19,0x0c,0x19,0x18,0x0e,0x04,0xbb,0xbf,0x8e,0x0d,0x02,0x00 +,0x10,0x9d,0x8b,0x8f,0x50,0xb6,0x2b,0x94,0x9b,0x80,0x83,0x80,0x8b,0x8e,0x85,0x88,0x80,0x82,0x81,0x86,0x87,0x4f,0x30,0x06,0x9f,0x89,0x88,0x4c,0x00,0x02,0x01,0xec +,0x17,0x0e,0x02,0x08,0x07,0x0d,0x00,0x0a,0x17,0xae,0x93,0x03,0x05,0x00,0x29,0x9c,0x88,0xe0,0x26,0x0f,0x12,0x13,0x3a,0x95,0xa7,0x90,0x18,0xa1,0x1b,0x9b,0x93,0x8b +,0x8c,0x91,0xa3,0x1d,0x0f,0x15,0x82,0x84,0x80,0x23,0x1f,0x13,0x94,0x89,0x8f,0x97,0x5e,0xa2,0xa7,0x70,0x0d,0x95,0x91,0x80,0xa4,0x1f,0x07,0x12,0x9b,0x8a,0x89,0xa9 +,0xee,0x13,0x2d,0x0b,0x9c,0x35,0x8e,0x21,0x19,0x29,0x11,0xaa,0x25,0x9f,0xb9,0x9b,0x0f,0x13,0x00,0x31,0x97,0x86,0xa7,0x02,0x0b,0x0a,0x8e,0x3e,0x29,0x08,0x10,0x19 +,0x2f,0x05,0x0c,0x25,0xab,0x8c,0x05,0x05,0x00,0x1b,0xa6,0x8a,0xae,0x28,0x28,0xd1,0x9f,0x91,0x80,0x87,0x80,0x92,0x84,0x89,0x84,0x81,0x81,0x81,0x80,0x89,0x9e,0x2f +,0x0e,0x8a,0x88,0x80,0x17,0x04,0x02,0x10,0x3e,0x0a,0x0b,0x01,0x08,0x0a,0x15,0x00,0x0e,0x09,0x9a,0xab,0x04,0x04,0x02,0x29,0x47,0x98,0x20,0x24,0x0e,0x29,0x15,0x9f +,0x34,0x5a,0xb0,0x13,0x9c,0x2b,0x90,0xa4,0x90,0x96,0x89,0xa3,0x2d,0x0d,0x30,0x83,0x84,0x84,0x14,0x2c,0x1d,0x88,0x88,0x94,0x3b,0x2f,0xa0,0x99,0xab,0x0e,0x98,0x99 +,0x80,0xad,0x15,0x03,0x12,0xa3,0x90,0x8b,0x3b,0x31,0x12,0x31,0x0f,0x9b,0x2f,0x9b,0x3a,0x14,0x32,0x10,0x4f,0x29,0x9f,0xb1,0x98,0x0f,0x0b,0x00,0x2e,0x93,0x87,0x9f +,0x04,0x12,0x0f,0x8d,0x9f,0x2e,0x0f,0x2c,0x36,0xad,0x0b,0x0f,0xa6,0x91,0x82,0x16,0x0d,0x00,0x61,0x8f,0x87,0x92,0x44,0x2e,0x57,0x2c,0x27,0x8f,0xaa,0x84,0x2e,0x2b +,0x18,0x2e,0x98,0x93,0x89,0x9c,0x96,0x18,0x13,0x09,0x93,0x8a,0x80,0xa6,0x0f,0x1d,0x28,0x88,0x9a,0xa1,0x26,0xa1,0xdb,0xbe,0x06,0x0f,0xaa,0x8d,0x88,0x0e,0x08,0x00 +,0x3f,0xa6,0x91,0x38,0x18,0x13,0x23,0x0f,0x0d,0x3f,0x1a,0x8e,0x19,0x1e,0x0b,0x16,0x57,0x9b,0x90,0xaf,0xb5,0x10,0x18,0x0e,0x8c,0x8b,0x80,0xb8,0x1c,0x58,0x45,0x87 +,0x9b,0x8f,0xa4,0x8e,0xaa,0xb0,0x08,0x1e,0x88,0x83,0x83,0x17,0x0c,0x05,0x98,0x8f,0x87,0x99,0xb8,0xb2,0xbc,0x2a,0x0c,0xa8,0xb8,0x80,0xc1,0x1e,0x0a,0x0d,0x7e,0x9b +,0x8f,0xd8,0x64,0x03,0x0f,0x00,0x4c,0xae,0x94,0xf4,0x0b,0x18,0x09,0xb0,0x18,0x5f,0x29,0xa4,0x1b,0x13,0x01,0x0a,0x90,0x8f,0x86,0x09,0x06,0x02,0xbc,0xa2,0x9b,0x39 +,0x1f,0xaf,0x29,0x28,0x02,0xb3,0x9e,0x80,0x9a,0x20,0x13,0x15,0x89,0x87,0x84,0x95,0x93,0x1a,0xae,0x18,0x9e,0x83,0x84,0x83,0x68,0xc0,0x16,0x95,0xa3,0x8c,0x8e,0x8d +,0xac,0x16,0x08,0x05,0x8c,0x8c,0x81,0x19,0x02,0x03,0x14,0xb6,0xbe,0xee,0x1f,0xaa,0x0c,0x0b,0x00,0x0c,0xba,0x88,0x8f,0x09,0x07,0x03,0xba,0x9c,0x90,0xb0,0xc7,0x18 +,0x1b,0x0d,0x0b,0x8b,0x8e,0x80,0xc2,0x1b,0x0f,0x2e,0x98,0x8d,0x87,0x92,0x95,0x19,0x19,0x08,0x91,0x86,0x80,0x95,0x0a,0x17,0x13,0x8e,0x8d,0x8b,0x9c,0x94,0x2c,0x1a +,0x07,0x0a,0x89,0x87,0x80,0x18,0x07,0x01,0x35,0x8f,0x8d,0x92,0x2e,0x2c,0x0f,0x12,0x01,0x9f,0x95,0x82,0x9f,0x06,0x09,0x05,0xb5,0x9b,0x89,0xb7,0xa8,0x0c,0x0b,0x03 +,0x18,0x8a,0x89,0x8b,0x07,0x0e,0x04,0xbe,0x9e,0x9b,0xa0,0xb4,0x44,0x0e,0x0c,0x00,0x8e,0x8b,0x80,0x53,0x08,0x09,0x27,0x89,0x8d,0x8b,0x30,0xa0,0x24,0x45,0x0b,0xa4 +,0x87,0x83,0x88,0x0f,0x1f,0x0b,0x93,0x8a,0x88,0xad,0xb5,0x14,0x15,0x10,0x11,0x85,0x91,0x8a,0x0a,0x0a,0x04,0x2f,0x98,0xa9,0xa4,0x1d,0x1e,0x08,0x0b,0x00,0x94,0x91 +,0x88,0x3a,0x00,0x08,0x0f,0x8d,0x92,0x8e,0x24,0xce,0x13,0x14,0x08,0x48,0x85,0x86,0x88,0x09,0x18,0x0a,0x96,0x86,0x89,0x93,0xa6,0x2c,0x18,0x16,0x11,0x82,0x8a,0x80 +,0x26,0x11,0x12,0xc7,0x88,0x8f,0x8b,0xcc,0xc4,0x12,0x10,0x06,0x8e,0x8b,0x85,0xa9,0x02,0x11,0x0c,0x97,0x99,0x96,0x2f,0xd3,0x0f,0x0e,0x06,0x37,0x89,0x8c,0x94,0x01 +,0x0e,0x04,0xa5,0x92,0x9d,0xaf,0x40,0x15,0x11,0x0a,0x0f,0x85,0x90,0x87,0x0e,0x0a,0x0a,0xc4,0x8d,0x97,0x99,0x2b,0x3a,0x15,0x10,0x0c,0x88,0x8d,0x81,0x2f,0x07,0x15 +,0x1c,0x8a,0x8c,0x8f,0xb9,0xa4,0x17,0x24,0x0c,0x98,0x88,0x83,0x9c,0x0c,0x1d,0x12,0x8a,0x8f,0x93,0xb3,0x51,0x13,0x1f,0x07,0x46,0x89,0x91,0x8f,0x0b,0x11,0x0d,0xa8 +,0xb0,0xa1,0x39,0x21,0x16,0x0d,0x06,0x1b,0x8d,0x9a,0x8e,0x06,0x0d,0x0e,0x4b,0x99,0x9f,0xd1,0x72,0x30,0x0f,0x0e,0x0f,0x8a,0x8b,0x87,0x12,0x0d,0x10,0x33,0x8a,0x9a +,0x97,0xa2,0xb5,0x28,0x1a,0x08,0x8d,0x8b,0x85,0xab,0x0c,0x1a,0x25,0x8e,0x99,0x93,0xa9,0xa8,0x2e,0x12,0x03,0xa7,0x8e,0x88,0x92,0x09,0x1f,0x17,0x9b,0x9a,0xb3,0x5e +,0xab,0x2e,0x1c,0x06,0x1e,0x8f,0x8f,0x8f,0x0b,0x14,0x10,0xa8,0x98,0xc1,0xca,0xb6,0x3e,0x25,0x0a,0x12,0x8a,0x94,0x8a,0x19,0x0d,0x1c,0xbe,0x98,0xab,0xcb,0xbe,0xb4 +,0x1b,0x0b,0x0b,0x8c,0x8b,0x87,0x36,0x07,0x1a,0x33,0x94,0x9b,0xcc,0xad,0x9e,0x27,0x10,0x07,0xa0,0x89,0x8a,0xa7,0x0a,0x12,0x24,0x9b,0x98,0xaf,0x9f,0x9b,0x4f,0x15 +,0x04,0xf3,0x8b,0x8d,0x97,0x0f,0x0f,0x2d,0xac,0x9d,0xb7,0xb9,0xa3,0x4c,0x13,0x01,0x2a,0x8e,0x8c,0x92,0x12,0x0e,0x33,0xb0,0x9c,0xb1,0x45,0x9c,0xd1,0x1d,0x06,0x1d +,0x8f,0x8b,0x8f,0x19,0x0e,0x1d,0xbb,0xa3,0xae,0xc3,0x91,0xad,0x26,0x08,0x0f,0x8d,0x8a,0x8f,0x26,0x0c,0x18,0xaa,0xb6,0xe0,0x4f,0x9e,0x9d,0x30,0x09,0x09,0x95,0x8d +,0x8b,0xd5,0x0c,0x1b,0xaa,0xb1,0xb1,0x38,0xb5,0x93,0x42,0x0f,0x08,0xbf,0x92,0x8d,0xc4,0x13,0x1a,0x58,0xb0,0xb8,0x60,0x9d,0x8f,0x3d,0x14,0x05,0x68,0x8a,0x8d,0xaa +,0x18,0x13,0xbd,0xa2,0x33,0x35,0xb1,0x92,0xa6,0x17,0x02,0x24,0x91,0x8b,0x8e,0x1d,0x11,0xe3,0xbb,0x47,0x44,0x3c,0x91,0x9d,0x1a,0x07,0x17,0xa4,0x8e,0x93,0x2a,0x1f +,0x31,0x4b,0x2e,0x26,0xb5,0x89,0x97,0x22,0x07,0x0f,0x90,0x8c,0x9e,0x27,0x13,0x36,0x99,0x2b,0x16,0x35,0x95,0x8b,0xae,0x06,0x09,0x9d,0x8e,0x8d,0x75,0x0c,0x36,0x9a +,0x46,0x31,0x1f,0xac,0x8a,0xaf,0x0c,0x0a,0x38,0x94,0x8d,0x42,0x1a,0x3e,0xa3,0xb0,0x22,0x19,0x99,0x8b,0xaa,0x17,0x03,0x2f,0x8a,0x91,0xcd,0x1c,0x16,0x95,0x96,0x10 +,0x13,0x49,0x95,0x8c,0x2c,0x01,0x2a,0x95,0x8f,0x94,0x19,0x11,0x98,0x99,0x26,0x1f,0x17,0x98,0x8d,0x2e,0x0b,0x16,0xa8,0x8d,0xa3,0x1c,0x2a,0xc3,0x96,0x63,0x0e,0x22 +,0x8e,0x94,0xbb,0x0e,0x07,0x92,0x89,0xe1,0x2a,0x13,0x25,0x87,0xcd,0x09,0x26,0xae,0x8c,0x8d,0x0e,0x03,0xa8,0x8e,0x93,0xbb,0x0c,0x2c,0x8d,0xa5,0x19,0x11,0x2b,0x8b +,0x94,0x21,0x08,0x0f,0x90,0x8e,0x32,0x2b,0x68,0xa9,0x8c,0x1c,0x04,0xb5,0x8f,0x96,0xa4,0x09,0x09,0x8a,0x8e,0x33,0x30,0x14,0xac,0x83,0x32,0x05,0x17,0xb5,0x87,0x92 +,0x0e,0x06,0x71,0x8a,0x8e,0x23,0x11,0x4d,0x9d,0x8f,0x23,0x06,0x63,0x8d,0xa7,0xb9,0x0d,0x09,0x8a,0x8f,0x24,0xd1,0x3a,0x3f,0x8d,0x26,0x09,0xa4,0x95,0x9a,0x58,0x06 +,0x0b,0x8f,0x8b,0xac,0x16,0x1a,0x92,0x95,0x4c,0x0b,0x0a,0x9a,0x80,0xa8,0x0e,0x04,0x0f,0x86,0x85,0x17,0x10,0x55,0xca,0x8b,0x2b,0x01,0x2f,0x8c,0x8b,0x9c,0x0b,0x02 +,0xa2,0x8b,0x92,0x3d,0x17,0xb5,0x9b,0x37,0x1e,0x16,0xd8,0x87,0xba,0x15,0x10,0x1b,0x96,0x89,0x1d,0x1c,0x95,0xbe,0xab,0x1e,0x08,0xab,0x84,0xa0,0x27,0x06,0x0a,0x8c +,0x85,0xab,0x15,0x10,0xb5,0x8a,0x44,0x0f,0x14,0xb1,0x82,0x98,0x0b,0x04,0x19,0x91,0x80,0xc8,0x09,0x28,0x58,0xa2,0x9d,0x0e,0x1b,0x8e,0x9f,0xaf,0x12,0x01,0x2f,0x8a +,0x8b,0x98,0x2a,0x1b,0xb4,0x33,0x29,0xb8,0xc2,0x9e,0x9c,0x0f,0x0d,0x22,0x4a,0x8a,0x94,0x1f,0x7d,0x5b,0x26,0xe0,0x21,0x48,0x8d,0x94,0xde,0x15,0x05,0x16,0x92,0x8e +,0x98,0x2b,0x13,0xa2,0xa8,0x32,0xbd,0x35,0xca,0x8e,0x3d,0x0c,0x0e,0x0f,0x98,0x81,0x94,0x1c,0x0e,0x1b,0x96,0x93,0x35,0x29,0x1b,0x6a,0x94,0x31,0x0e,0x18,0x5f,0x89 +,0x87,0x1a,0x0b,0x32,0xc5,0x8d,0x91,0x19,0x1d,0x26,0x7d,0xa3,0x1c,0x0e,0xc9,0x93,0x96,0x4f,0x0c,0x3a,0x8f,0x9e,0xa4,0x28,0x0c,0x42,0xa5,0x31,0xc0,0x1d,0x1c,0x8e +,0x94,0x28,0x29,0x2c,0xa9,0x97,0x3b,0x1c,0x1e,0x35,0x99,0x9e,0x1c,0x1a,0x1a,0xbc,0x89,0xa1,0x13,0x2f,0xa1,0x99,0x94,0x1a,0x0d,0x26,0xa6,0x8e,0xb7,0x0a,0x09,0x32 +,0x8b,0x85,0xd7,0x0d,0x39,0x9e,0xa4,0xa7,0x11,0x0f,0xa6,0x91,0x9f,0x1c,0x09,0x12,0x99,0x85,0x8f,0x15,0x0b,0xb3,0x96,0x69,0x29,0x15,0x24,0x99,0x8d,0xa5,0x15,0x10 +,0x1e,0x9c,0x8a,0xa5,0x0d,0x18,0xa7,0x93,0x9e,0x4a,0x1d,0x25,0xf1,0x2d,0x23,0x19,0x16,0x2a,0x95,0x8c,0x9e,0x35,0xaa,0x58,0x3e,0x8b,0x9a,0x26,0x1b,0x49,0x97,0x8f +,0x4a,0x04,0x00,0x14,0x88,0x93,0x0d,0x23,0x92,0x96,0x90,0x9d,0x6b,0x69,0x9e,0x8e,0x25,0x0c,0x24,0xb6,0x1f,0x97,0x8c,0x1e,0x0a,0x1c,0x2a,0x29,0xa1,0xa2,0x14,0x06 +,0xb5,0x81,0x8b,0x1b,0x16,0xcd,0x8b,0x88,0x5f,0x1c,0x21,0xed,0x9e,0x58,0x11,0x16,0x4b,0x1e,0x3a,0x90,0xa6,0x0d,0x08,0xab,0x88,0xbc,0x30,0x73,0x22,0xaf,0x83,0x92 +,0x13,0x31,0xa1,0x96,0xa4,0x36,0x08,0x01,0x17,0x94,0x3f,0x14,0x97,0xa4,0x1b,0x96,0x87,0x31,0x25,0xa3,0x8f,0x94,0xab,0x1e,0x01,0x09,0x8b,0x81,0x15,0x04,0x1d,0x31 +,0x98,0x90,0x32,0x1a,0x29,0xa4,0x94,0x3c,0x2c,0xaa,0xa9,0x45,0xa6,0x99,0xa2,0x35,0x19,0x9c,0x98,0x21,0x0d,0x09,0x09,0xaf,0x87,0xaa,0x0b,0x0d,0xad,0x88,0x8a,0xa2 +,0x67,0x1e,0xaf,0x99,0x35,0x16,0x1a,0xac,0x9e,0x96,0xae,0x0f,0x0a,0x12,0xac,0x8f,0xa2,0x37,0x10,0x12,0x97,0x88,0xbf,0x15,0xa8,0x8e,0x8f,0x91,0x4c,0x0e,0x0d,0x30 +,0x9b,0x25,0x0b,0x28,0x3a,0x33,0x9e,0x97,0x33,0x1a,0xe0,0x9b,0xc3,0x29,0xbe,0x27,0x0f,0xb4,0x85,0x98,0x31,0x63,0xb2,0x9a,0xa8,0x1e,0x0c,0x13,0xaa,0x97,0x35,0x16 +,0x21,0x26,0x1d,0xa9,0x94,0xc3,0x5e,0xaf,0x94,0x8f,0x98,0xe3,0x1b,0x3f,0x90,0xa9,0x0b,0x07,0x0d,0x14,0x2f,0x8d,0x8d,0xa3,0xc9,0x5f,0x22,0x0f,0x1e,0xab,0x98,0xb4 +,0xa8,0x92,0x94,0x3e,0x12,0x12,0x4f,0xa1,0x1f,0x0d,0x0d,0x9c,0x80,0x8e,0x15,0x18,0xba,0xa0,0x96,0xbb,0x1a,0x0b,0x0e,0xb9,0x8e,0xb2,0xb6,0x9f,0xa7,0x9f,0x2a,0x09 +,0x0f,0xa3,0x91,0x99,0xa7,0x2b,0x0b,0x02,0x1e,0x8a,0x92,0xa7,0x9c,0xce,0xa5,0x93,0x3d,0x18,0x46,0xa2,0xf9,0x1b,0x0c,0x1c,0x16,0x1c,0x88,0x84,0xa7,0x30,0x1f,0x2c +,0xa5,0x29,0x1f,0x1e,0x45,0x8c,0x89,0x2f,0x12,0x11,0x18,0x95,0x9d,0x12,0x23,0x3a,0x9e,0x8a,0x3b,0x1f,0x4f,0xbc,0x95,0xa3,0x2f,0x5f,0x15,0x0d,0xaf,0x90,0xa6,0xb1 +,0x12,0x1c,0x96,0x5f,0x14,0x1d,0xbe,0x88,0x8e,0xb8,0x29,0x06,0x09,0xc5,0x96,0xc8,0xa2,0xd2,0x9f,0x94,0x97,0xa9,0x33,0x26,0xa3,0xb8,0x16,0x10,0x06,0x04,0x19,0x86 +,0x8a,0x96,0x1f,0xd6,0x98,0x92,0xc0,0x13,0x1f,0x9c,0x8f,0xa3,0x20,0x06,0x0b,0x1f,0x86,0x9e,0x3b,0x1a,0x4a,0x95,0x9b,0xd3,0x1f,0x22,0x45,0xd0,0xbd,0x4e,0x22,0x20 +,0x1d,0x8b,0x8f,0x99,0x2e,0x27,0xaa,0x5a,0x1b,0x0c,0x0e,0xa5,0x95,0x98,0xa9,0x2b,0x13,0x09,0x96,0x96,0x99,0xe3,0x31,0xab,0xea,0xaa,0xb3,0x18,0xad,0x9c,0x9d,0x60 +,0x09,0x07,0x08,0x8d,0x8a,0x9a,0x1e,0x11,0xaa,0x9f,0xb8,0xcb,0x28,0x93,0x8e,0x9b,0xaa,0x13,0x0f,0x09,0x7e,0xc6,0xc1,0x29,0x1b,0xa5,0x92,0xa6,0xb8,0x1f,0x6c,0x9f +,0x9d,0xac,0x11,0x0b,0x0a,0x90,0x8d,0x90,0xc1,0x2f,0xb7,0xa5,0xc4,0x1c,0x0c,0x27,0x98,0x9c,0xa1,0x18,0x0f,0x06,0x92,0x8c,0x95,0x54,0x15,0xcc,0x9b,0x92,0xab,0x1b +,0x1f,0x9f,0x9e,0xaf,0x0a,0x08,0x05,0x9c,0x8a,0x94,0xbe,0x15,0xaf,0x9c,0xad,0x37,0x1c,0x59,0x93,0x95,0x99,0x1b,0x11,0x07,0xc2,0x90,0x9f,0x2e,0x09,0x2c,0x99,0x94 +,0xa1,0x1b,0x29,0x95,0x99,0xa4,0x0e,0x0b,0x08,0x9c,0x85,0x99,0xbe,0x18,0xd1,0x96,0x97,0xb6,0x0e,0x0f,0xce,0xcb,0x99,0x2c,0x12,0x04,0x25,0x8e,0x8e,0x99,0x30,0xb4 +,0x8d,0x92,0xaf,0x17,0x14,0xa2,0xa5,0xa1,0x0c,0x06,0x01,0xc9,0x86,0x86,0xa2,0x13,0x1f,0xa3,0x94,0xa6,0x1d,0x0f,0xad,0x9d,0x8f,0x29,0x13,0x07,0x9b,0x85,0x8f,0x25 +,0x03,0x0f,0xae,0x8e,0xa6,0x15,0x0f,0xa1,0x97,0x8b,0x3a,0x18,0x08,0xa4,0x89,0x8e,0xae,0x0e,0x1c,0xbc,0xa8,0xb5,0x1b,0x16,0xc3,0x9d,0x8b,0x26,0x0e,0x02,0xac,0x88 +,0x8e,0x34,0x04,0x14,0x95,0x87,0x8c,0x2c,0x1e,0xa0,0x98,0x8d,0x0f,0x08,0x00,0x2a,0x93,0x96,0x3f,0x0e,0x26,0x92,0x8a,0x8c,0x2b,0x1b,0xa9,0x9a,0x8c,0x1e,0x08,0x02 +,0xac,0x89,0x8a,0x3c,0x0b,0x10,0xac,0x93,0x9a,0x1e,0x1b,0x7c,0x9f,0x9b,0x13,0x06,0x09,0x8e,0x85,0x82,0xc7,0x0f,0x20,0x9b,0x8a,0x9a,0x0d,0x09,0x0e,0xb0,0x9c,0x21 +,0x08,0x09,0x8f,0x85,0x83,0x57,0x0f,0x1b,0xae,0x94,0x9b,0x13,0x2f,0x47,0x8e,0x99,0x1e,0x09,0x0a,0xa6,0x94,0x8d,0x23,0x0d,0x0f,0x3d,0x91,0x8e,0x25,0x46,0x2c,0x8d +,0x8d,0x35,0x08,0x11,0x92,0x85,0x8b,0x1c,0x03,0x0a,0x27,0x9e,0xa0,0x1c,0x39,0x38,0x8d,0x93,0x3a,0x08,0x21,0xa6,0x86,0x97,0x21,0x0e,0x12,0x9e,0x89,0x8f,0x2d,0x1d +,0x1e,0xab,0x32,0x13,0x01,0x1f,0xae,0x87,0x8f,0x3c,0x1f,0x23,0xa9,0x8e,0xa8,0xd9,0x21,0xcc,0x95,0xb2,0x21,0x07,0x2d,0xa6,0x89,0xa6,0x17,0x07,0x10,0xc7,0x89,0xa8 +,0xba,0x1d,0x44,0x96,0xa9,0x1e,0x0c,0xbd,0x97,0x85,0x99,0x3a,0x0c,0x1a,0x3e,0xa8,0x1e,0x1a,0x11,0x4d,0xa1,0xa4,0x35,0x2e,0xb4,0x93,0x89,0xa8,0x2d,0x0c,0x17,0xb5 +,0x93,0xa7,0xd4,0x1e,0xa0,0xa8,0xbe,0x08,0x0d,0x1b,0x9b,0x8b,0xc0,0x1f,0x0e,0x2e,0x8f,0x8b,0x9d,0x49,0x13,0xa2,0xad,0x9b,0x1b,0x26,0x2f,0xa9,0x9e,0x26,0x12,0x0d +,0x1f,0x94,0x9e,0xe0,0xba,0x28,0x91,0x9a,0xae,0x0e,0x1a,0x2e,0x9a,0x98,0xa2,0x30,0x2d,0x36,0x9b,0xad,0x2d,0x1d,0x0f,0x3e,0x31,0x2a,0x13,0x44,0xb2,0x86,0x8b,0x93 +,0x28,0x12,0x16,0xa0,0x9a,0xa6,0x2d,0x17,0x39,0x64,0xc3,0x16,0x70,0x2f,0x90,0xa4,0x39,0x18,0x17,0x66,0x92,0xa6,0xb9,0x20,0x1d,0xad,0xa8,0x9e,0x1e,0xa7,0xb5,0x92 +,0x9a,0x3c,0x17,0x0a,0x11,0xae,0x2a,0x44,0x21,0x34,0x91,0x95,0x97,0x1d,0xcc,0xad,0x96,0x9a,0x31,0x18,0x13,0x14,0x9c,0xab,0x99,0xcf,0x1b,0x39,0x1d,0xd7,0x1e,0x68 +,0xb9,0x9b,0x9c,0xbc,0x28,0x28,0x2a,0x94,0x98,0xa0,0x74,0x19,0xb0,0xef,0xc7,0x0f,0x16,0x20,0xb4,0x9d,0xc5,0x1f,0x17,0x36,0x98,0x90,0x95,0xab,0x1f,0xdd,0x36,0xd8 +,0x15,0x22,0xc6,0x99,0x8a,0x9b,0x3c,0x0d,0x10,0x52,0xad,0xbe,0x2d,0x0f,0x2c,0x38,0xa0,0x51,0xab,0x93,0x99,0x90,0xba,0x47,0x1b,0x1f,0xca,0xac,0xca,0x3c,0x10,0x2b +,0x3a,0xaa,0x27,0x17,0x3d,0xae,0x89,0x96,0xbd,0x1a,0x1a,0xc6,0x9f,0xaf,0xb5,0x1d,0xb5,0xc7,0xaa,0x40,0x1d,0xc7,0x4e,0x94,0xb8,0x23,0x0e,0x0a,0x28,0x9c,0x99,0x8d +,0x51,0xb6,0xb8,0xae,0xbd,0x16,0xd8,0x34,0x9d,0xa2,0x3e,0x22,0x1c,0x5a,0xa2,0x35,0xce,0x1a,0x2b,0xad,0x4c,0x52,0x0f,0xdf,0xa0,0x8c,0x8d,0xa9,0x29,0x1b,0x2e,0x9d +,0xad,0xbc,0x29,0x1a,0xd0,0x28,0x2b,0x08,0x18,0xbb,0x8e,0x8e,0xa9,0x3e,0x2a,0xbb,0x98,0xa4,0xcf,0xe2,0x1d,0x40,0x1f,0x47,0x1a,0xc6,0xa2,0x97,0x95,0xde,0x1b,0x0f +,0x1b,0xcd,0xb0,0x5b,0xbc,0x2a,0x95,0xa1,0xa7,0x18,0x25,0xab,0x99,0x90,0x4f,0x20,0x18,0x23,0xac,0xac,0x2c,0x35,0x15,0xba,0xc9,0xb9,0x18,0x16,0xb4,0x95,0x86,0x95 +,0x45,0x17,0x18,0xb9,0x9e,0x49,0xae,0x23,0xab,0xb2,0x39,0x11,0x0a,0x37,0xb1,0x96,0xb6,0x2a,0x2e,0xd6,0x9b,0x90,0xb5,0x9f,0x30,0xb5,0xb2,0x21,0x15,0x09,0x3c,0xa9 +,0x89,0x93,0x2e,0x11,0x13,0x47,0x99,0x3b,0x2b,0x1d,0xfb,0x8f,0xae,0xc6,0x0c,0xfc,0x9c,0x8a,0x8d,0xee,0x1d,0x11,0x22,0xaf,0xd4,0x37,0x29,0x18,0xa9,0x26,0x28,0x0a +,0x27,0x91,0x89,0x85,0xb1,0x2a,0x1d,0x35,0x9d,0x6c,0x24,0x4b,0x2d,0x98,0x3d,0x2d,0x09,0x11,0xa5,0x9d,0x8e,0x2c,0x13,0x16,0x3c,0x8e,0x8f,0xa5,0xa5,0x21,0x98,0xab +,0x54,0x0f,0x08,0xd1,0xa5,0x8a,0xa8,0x22,0x16,0x16,0xb9,0xa1,0x23,0xc2,0x26,0xaa,0xa4,0x7a,0x3b,0x0f,0x9e,0x9e,0x8c,0x98,0x2b,0x26,0x18,0x3d,0x9f,0x46,0xc8,0x22 +,0x32,0xae,0x17,0x12,0x01,0x76,0x8e,0x84,0x8b,0xbc,0x3a,0x2d,0xad,0x9e,0x39,0x21,0x2c,0x1e,0x9c,0x2d,0x2a,0x0b,0x1d,0x9f,0x8f,0x8b,0x2c,0x18,0x0f,0x1b,0xa4,0x9a +,0xa2,0x93,0x42,0x98,0x2c,0x2f,0x0f,0x14,0x9f,0xa7,0x91,0x47,0x2c,0x14,0x1b,0x3f,0x9f,0x52,0x9f,0x30,0xa7,0xb4,0x2f,0x35,0x15,0x9c,0x98,0x8c,0xc0,0x1e,0x19,0x24 +,0x50,0x9e,0x41,0xb8,0x56,0xb6,0xa5,0x14,0x0f,0x03,0x6c,0x99,0x89,0x8d,0xae,0x38,0x1f,0x25,0x9f,0xa4,0x9c,0xb4,0x17,0x31,0x0e,0x27,0x0d,0xcf,0x99,0x93,0x90,0x2d +,0x26,0x1d,0x33,0x9d,0x9b,0x9f,0x96,0x1d,0xd1,0x1b,0x24,0x15,0x27,0x9c,0xa3,0x8f,0xb4,0x72,0x18,0x18,0x40,0xba,0x38,0xa5,0x1f,0xba,0xef,0x3d,0x2a,0x1e,0x91,0x95 +,0x8a,0xea,0x21,0x13,0x0f,0x3a,0xa5,0xa4,0x99,0x27,0x3b,0x31,0x1e,0x1c,0x10,0x9f,0xa3,0x8e,0x99,0xb6,0x34,0x24,0x6e,0xa4,0xb8,0x9a,0x3e,0x25,0x32,0x17,0x1f,0x0c +,0xb5,0xa0,0x8f,0xa2,0x30,0x22,0x1c,0x39,0x9a,0x9b,0x92,0xa7,0x1e,0x45,0x17,0x36,0x0d,0xb0,0xa6,0x98,0x93,0x4f,0x2c,0x11,0x27,0xa2,0xa5,0xa6,0xbc,0x1c,0x4a,0x19 +,0xd2,0x19,0xd1,0x9a,0x93,0x91,0x6a,0x4a,0x1e,0x18,0xc7,0xab,0xab,0xab,0x14,0xf1,0x1b,0x27,0x0f,0x29,0x9c,0x93,0x8b,0xa7,0x33,0x17,0x1c,0xac,0x97,0xa1,0x97,0x1c +,0x42,0x16,0x29,0x17,0x1b,0xa2,0x9c,0x92,0x39,0x23,0x1b,0x27,0xaf,0x96,0x9d,0x8f,0x29,0xd6,0x26,0x26,0x1f,0x1a,0xa9,0xfd,0x96,0xa9,0xb5,0x23,0x1d,0x4a,0x9b,0xa8 +,0x9c,0x28,0x1d,0x1d,0x20,0x37,0x19,0xa9,0xa4,0x8c,0x97,0xb0,0x21,0x14,0x1d,0xa7,0xaa,0x9b,0x29,0x1e,0x4c,0x24,0x2a,0x0a,0xbb,0xac,0x8c,0x8f,0x9d,0x3a,0x13,0x29 +,0xa3,0xa4,0x95,0xb9,0x1f,0x23,0x16,0x3b,0x13,0xb4,0xb1,0x96,0x9e,0x3a,0x1f,0x16,0x19,0xae,0x9f,0x8c,0x9a,0x34,0xdd,0x1a,0x3d,0x13,0xa8,0xa2,0x96,0x9f,0x4b,0x1d +,0x15,0x1f,0x9c,0x9e,0xa6,0xc9,0x19,0x6d,0x1e,0xaf,0x16,0x38,0x42,0xa3,0x9c,0xd5,0x35,0x26,0x2b,0xa7,0xa0,0x9b,0x9a,0x1e,0xc4,0x1b,0x2e,0x0b,0x2a,0xa9,0x9a,0x8c +,0x94,0xa8,0x1f,0x15,0x3c,0xae,0x9f,0x96,0x1e,0x2a,0x0a,0x14,0x0e,0x3b,0x9e,0x97,0x8d,0xac,0x2a,0x1a,0x1f,0xb0,0x93,0x90,0x8d,0x25,0x35,0x16,0x2a,0x16,0x3b,0x9c +,0x9c,0x9a,0xc4,0x2e,0x13,0x12,0x35,0xa0,0xb9,0xa0,0x1a,0x37,0x1e,0xd0,0x2a,0x3f,0xa1,0xa2,0x8e,0x98,0xa7,0x27,0x1c,0x32,0xa3,0xad,0x91,0x24,0x37,0x19,0x1f,0x14 +,0x12,0xac,0xac,0x8e,0x9e,0xb1,0x1f,0x0f,0x1c,0xa9,0xa7,0x8d,0xcf,0xa5,0x2b,0x1f,0x21,0x16,0xa1,0xa9,0x8d,0x9c,0xc8,0x1a,0x10,0x1f,0x99,0x98,0x8a,0xc9,0x1c,0x0e +,0x10,0x1e,0x0f,0x9d,0xa7,0x92,0xac,0xbb,0x25,0x17,0x26,0x9d,0x9e,0x94,0xc6,0x2f,0x56,0x22,0xb1,0x20,0xa3,0xd8,0x9d,0x9e,0x69,0x29,0x1f,0x24,0xb5,0x69,0xa6,0xb9 +,0x2a,0xd2,0x19,0x3e,0x0a,0x2f,0xa9,0x92,0x8d,0x9e,0xa5,0x1e,0x18,0xb6,0xa6,0x97,0x99,0x31,0xbc,0x17,0x2e,0x0f,0x24,0xba,0xad,0x90,0xb4,0x2d,0x0f,0x0f,0xaf,0x9b +,0x95,0x8e,0x2b,0x30,0x0f,0x24,0x1b,0x29,0x95,0x9b,0x8f,0xb7,0x7b,0x2e,0x1c,0x3a,0xaa,0xa4,0x95,0x2b,0x41,0x27,0x27,0x2a,0x15,0xbb,0xd9,0x92,0x9c,0xdd,0x29,0x17 +,0x3e,0x9f,0xb7,0x9d,0x39,0x26,0x2e,0x24,0x46,0x0f,0xbc,0xa8,0x8e,0x8d,0xa4,0xbd,0x18,0x14,0x3f,0xc9,0x97,0xae,0x27,0xe0,0x16,0x32,0x0b,0x48,0xab,0xa0,0x8e,0xca +,0x2f,0x15,0x1c,0xa6,0x9f,0x98,0x91,0x3f,0xb4,0x13,0x26,0x11,0x24,0x9b,0x9d,0x8d,0xbb,0x34,0x18,0x16,0x4e,0xab,0xaf,0x98,0x25,0xad,0x3b,0x4a,0x1c,0x10,0xa8,0x3c +,0x92,0x9e,0xb7,0x32,0x1b,0xee,0x9d,0xb4,0x90,0x55,0x33,0x27,0x17,0x2d,0x0a,0x5e,0xee,0x93,0x8d,0xa1,0xc0,0x17,0x17,0xb9,0xcb,0x91,0xac,0x2e,0xb9,0x11,0x25,0x08 +,0x37,0xa2,0x98,0x8d,0xbf,0x47,0x1d,0x23,0x9a,0x9e,0x98,0x9e,0x1a,0x35,0x0f,0x2f,0x12,0x1b,0x9e,0x9e,0x8a,0xa4,0x4b,0x1f,0x14,0x58,0xab,0x9d,0x94,0x25,0xc3,0x1f +,0x2a,0x2f,0x1d,0x9c,0x4a,0x98,0xa5,0x44,0x47,0x19,0x6b,0xab,0xb5,0x94,0x2e,0x64,0x22,0x18,0x2d,0x0b,0xa7,0xab,0x91,0x97,0x41,0xbb,0x1e,0x24,0x46,0x34,0x96,0xab +,0xaf,0xac,0x18,0x37,0x0a,0xd3,0xab,0x9e,0x91,0x2e,0x31,0x15,0x1d,0x9d,0x9f,0x90,0x9c,0x26,0x5f,0x0d,0x2d,0x14,0x3d,0x99,0xa6,0x8f,0x30,0x36,0x2f,0x1f,0xb3,0xba +,0xa1,0x9b,0x29,0xaa,0x1d,0x3e,0x1f,0x1a,0x9d,0x43,0x95,0xd5,0x33,0x4c,0x1e,0xa9,0xa9,0xbb,0x99,0x2c,0xae,0x28,0x16,0x19,0x08,0xa3,0xac,0x8c,0x94,0x3a,0xba,0x12 +,0x31,0xad,0xce,0x94,0x42,0x61,0x45,0x1c,0x3e,0x0c,0xbb,0xa8,0x9e,0x92,0x2b,0x5b,0x1f,0x32,0x99,0xb6,0x92,0xab,0x2f,0x2e,0x08,0x29,0x13,0xc4,0x96,0xab,0x8e,0x64 +,0xb5,0x28,0x1a,0xae,0x39,0xa3,0xad,0x1f,0xaf,0x20,0x4f,0x1f,0x24,0x9c,0x3e,0x93,0xd5,0x52,0xcd,0x21,0x9f,0xbc,0xab,0x9f,0x24,0xc9,0x17,0x1e,0x20,0x0e,0xa3,0x43 +,0x8f,0x99,0xba,0xa5,0x14,0x2e,0x2d,0xce,0x92,0xc2,0x9f,0xd2,0x17,0x31,0x13,0x9b,0xc3,0xbf,0xa7,0x1d,0xaf,0x1d,0x51,0xa9,0xcd,0x8d,0xa3,0x4e,0x39,0x0f,0x3a,0x0f +,0xc9,0x9e,0xbb,0x94,0x1e,0xb3,0x34,0x27,0xa6,0x2f,0xa4,0xae,0x5a,0x9c,0x1a,0xd4,0x20,0x27,0xa6,0x1c,0x9d,0x2a,0xc0,0xcb,0x1f,0x9c,0xe9,0x9f,0x97,0x30,0xb4,0x10 +,0x1a,0x1d,0x16,0x97,0x3a,0x98,0xb3,0xad,0x95,0x1e,0xe2,0x22,0x3b,0x91,0xc9,0x9d,0x2e,0x17,0x2a,0x10,0x9c,0x33,0xaf,0xa0,0x2c,0xa3,0x1e,0xbb,0xac,0xcd,0x8c,0xc8 +,0x42,0x1f,0x0d,0x35,0x0c,0xaa,0x9f,0xa7,0x90,0xdc,0x96,0x21,0x1c,0x59,0x1d,0x9e,0xd7,0x3a,0xd0,0x17,0xa5,0x25,0xdd,0xb5,0x25,0x99,0x2e,0x9e,0xbe,0x29,0xab,0x23 +,0x9b,0x9b,0x43,0x58,0x0b,0x22,0x1a,0x2b,0x95,0x46,0x91,0xb9,0x9d,0xa6,0x16,0x5f,0x22,0xae,0x9e,0x31,0xa2,0x1f,0x42,0x67,0x1a,0xa8,0x1b,0xa1,0xb7,0x51,0xaa,0x19 +,0xb6,0x55,0xa7,0x8b,0xb9,0xb5,0x19,0x19,0x2f,0x0d,0xa3,0x42,0xa8,0x9d,0xc8,0x98,0x19,0x1c,0x23,0x39,0x8e,0xa0,0x9e,0x39,0x15,0xbb,0x1a,0xb2,0x2b,0x29,0xa3,0x22 +,0xab,0x2a,0x74,0x9d,0xaf,0x8e,0xa9,0x3e,0x28,0x10,0x52,0x12,0x2b,0xc3,0xd6,0x8e,0xbb,0x96,0xc2,0x1e,0xce,0x2d,0xa5,0xb4,0x3f,0xaf,0x1a,0x53,0x22,0x2c,0xbe,0x1c +,0x9e,0xcc,0xaa,0xb9,0x22,0xae,0xe2,0x97,0x8e,0xd9,0x55,0x0c,0x16,0x18,0x15,0xa5,0xce,0x90,0x9d,0xa6,0x9f,0x1b,0x31,0x2a,0xbf,0x9c,0x28,0xda,0x1f,0x27,0xee,0x23 +,0x9f,0x39,0xaa,0x9e,0xf1,0xb3,0x18,0x59,0xb2,0xab,0x8f,0xbe,0xec,0x1a,0x18,0x47,0x16,0xd2,0x7e,0xa7,0x94,0xb1,0x9a,0x2d,0x23,0x31,0x2c,0x9c,0x58,0x3f,0x3a,0x1f +,0xbe,0x2d,0xa7,0xbe,0x2b,0xb2,0x2d,0xb4,0x35,0x28,0xa7,0xc2,0x98,0x9e,0xc0,0xbc,0x17,0x2a,0x13,0x1a,0xec,0x7d,0x92,0xac,0xb1,0x3d,0x18,0x3c,0x66,0x95,0x94,0x42 +,0xc9,0x23,0xdc,0x38,0x2b,0xb2,0x26,0xb9,0x36,0x2f,0x2d,0x1c,0xa9,0x9a,0x90,0x8c,0xad,0xc2,0x14,0x13,0x18,0x10,0x5b,0x32,0xa1,0xa3,0xbb,0xa6,0x5a,0xb3,0xad,0xb8 +,0x9f,0x2b,0x35,0x2a,0x28,0x3e,0x1a,0xcf,0x46,0xb3,0xa9,0xc7,0xbc,0x27,0x41,0x9f,0xa4,0x94,0xb9,0x40,0x24,0x0f,0x18,0x10,0x3a,0xd1,0x99,0x8e,0x9b,0xa3,0x39,0x2f +,0xbb,0x56,0x9d,0xf6,0x1e,0x1e,0x15,0x2d,0x23,0x9f,0x96,0x94,0xa3,0x30,0x27,0x19,0x24,0xae,0xad,0x97,0xb9,0x36,0x52,0x17,0x23,0x17,0xc3,0xa8,0x9b,0x9a,0xaf,0x2e +,0x1a,0x4e,0x9f,0xa7,0x98,0x3d,0x1a,0x24,0x0e,0x3a,0x12,0xef,0xa7,0x94,0x8f,0x96,0xc7,0x1a,0x24,0x4c,0x9e,0x91,0x95,0x1a,0xa7,0x09,0x05,0x02,0x0a,0xa9,0x39,0xa1 +,0xf6,0x2b,0xa5,0xa1,0x91,0x8a,0x8a,0xa2,0x9f,0x8c,0x24,0xbe,0x9f,0x2c,0x96,0x8f,0x9e,0x8a,0x95,0x2e,0x2c,0x9a,0xbe,0x9e,0x1e,0x0a,0x0e,0x04,0x06,0x01,0x0d,0x0d +,0x34,0x36,0x1a,0x07,0x08,0x09,0x19,0xa3,0x9b,0x9e,0x3f,0xa4,0xaf,0xb7,0x2a,0xa2,0x8c,0x89,0x80,0x8b,0x9b,0xc0,0x92,0x81,0x83,0x83,0x86,0x8a,0x8e,0x88,0x3b,0x03 +,0x21,0x84,0x83,0x2f,0x1c,0x0b,0x0f,0x4c,0x0e,0x09,0x07,0x03,0x1f,0x9a,0x0d,0x05,0x00,0x0b,0x97,0x1c,0x10,0x00,0x0c,0x2c,0xb3,0xa2,0x15,0x09,0x9e,0x88,0x83,0x88 +,0x18,0x12,0x92,0x80,0x83,0x85,0x9d,0x8f,0x89,0x8e,0xb4,0x98,0x95,0x85,0x8e,0xbc,0x2e,0x15,0xbb,0x9f,0x8c,0x1b,0x23,0x1c,0x20,0x16,0x03,0x05,0x07,0x0c,0x22,0x10 +,0x04,0x0a,0x08,0x08,0x03,0x9f,0x22,0xf1,0xa2,0x17,0x8e,0x43,0x46,0x9f,0xe9,0x8c,0x86,0x93,0xa1,0xe5,0x21,0x1a,0x8b,0x84,0x8c,0x91,0x97,0x83,0x9f,0xbc,0x8b,0x86 +,0x89,0x82,0x9f,0x97,0x9a,0x13,0x04,0x2d,0x89,0x20,0x0e,0x0f,0x13,0x0c,0x03,0x05,0x04,0x1f,0x9f,0x20,0x43,0x0e,0x07,0x00,0x07,0xa0,0x9e,0xac,0x1f,0x1b,0xdf,0xb3 +,0x25,0xa6,0x98,0x82,0x81,0x8c,0x89,0xa9,0x3f,0x5f,0x80,0x84,0x8d,0x98,0xba,0x8c,0x8f,0x9c,0xae,0x1f,0x6c,0xa5,0xaa,0x8b,0x17,0x07,0x02,0xcd,0x86,0xa7,0xa3,0xae +,0x12,0x0f,0x0e,0x65,0xaf,0x12,0x0c,0x04,0x87,0x14,0x07,0x00,0x11,0xf6,0x09,0x18,0x09,0x94,0x19,0x00,0x29,0x66,0x05,0x09,0xc4,0x95,0x25,0x01,0x0f,0x88,0x80,0x94 +,0x36,0x99,0x88,0x80,0x91,0xa2,0x83,0xa2,0x8f,0x93,0x84,0x8f,0x1c,0x30,0x3c,0x8f,0x58,0x0c,0x89,0x98,0xb2,0x22,0x01,0xa5,0x20,0x96,0x86,0xc7,0xa8,0x09,0x0f,0x0e +,0x92,0x89,0x08,0x95,0xa6,0x9d,0x34,0x25,0x91,0x98,0xc4,0x56,0xb7,0x84,0x93,0x1f,0x3f,0x29,0x80,0x13,0x9e,0x88,0x92,0x18,0x00,0x18,0x5e,0x98,0x15,0x16,0xac,0x3a +,0x00,0x26,0x0b,0xbd,0x12,0x0c,0x8d,0x0b,0x4f,0x0f,0x03,0x22,0x00,0x15,0x2f,0x94,0xca,0x00,0x0f,0x00,0xa7,0x99,0xb9,0x90,0x26,0x1c,0x0b,0x9f,0x87,0x97,0x8c,0x89 +,0x95,0x8c,0x9f,0x8c,0x81,0x84,0x87,0x8f,0x80,0x84,0x80,0x83,0x84,0x82,0x80,0x89,0x9c,0x9a,0x80,0x8e,0x08,0x07,0x08,0x9e,0x08,0x06,0x14,0x00,0x06,0x00,0x0a,0x08 +,0x02,0x06,0x08,0x0b,0x03,0x00,0x09,0x04,0x6b,0x05,0x13,0x8a,0x21,0x22,0x00,0x0c,0x1c,0xaa,0x83,0x87,0x98,0x0b,0x0e,0xc9,0x94,0x80,0x8e,0xb9,0x8b,0x86,0x85,0x9c +,0xcc,0x87,0x90,0x9c,0x80,0x8a,0x9f,0x33,0x4f,0x95,0x8b,0x89,0x0b,0x9a,0x94,0xcb,0x19,0x07,0x96,0x11,0x10,0xbf,0x3a,0x0f,0x08,0x05,0x03,0x1e,0x9b,0x01,0x0e,0x9f +,0x19,0x18,0x05,0xaf,0x27,0x9c,0x8e,0xa5,0x84,0x21,0xc3,0x34,0x34,0x81,0xad,0x8f,0x8a,0x3d,0x32,0x0c,0x92,0x9a,0x40,0x9d,0x9c,0x2f,0x0c,0x09,0x07,0x0b,0x94,0x64 +,0x0d,0x26,0x02,0x1a,0x0f,0x4c,0x12,0x12,0xcd,0x11,0x10,0x2a,0x36,0x16,0xb4,0x84,0x8a,0xa6,0x85,0x86,0x86,0x86,0x84,0x83,0x89,0x85,0x8a,0xab,0x91,0x92,0xec,0x0e +,0x4a,0x90,0x06,0x3d,0xd1,0x29,0x1a,0x0d,0x31,0x06,0x0f,0x1f,0x1b,0x1c,0xf5,0x1e,0x0c,0x0f,0x97,0x05,0x12,0xa3,0x17,0xe4,0x06,0x1e,0x08,0x0d,0x9d,0x38,0x09,0x0d +,0x16,0x12,0x06,0x92,0x3d,0x0e,0xa1,0x39,0xce,0x33,0xa8,0x28,0xcc,0xa4,0x97,0x8f,0x9c,0x90,0x8c,0x9f,0x83,0x88,0x4c,0x88,0x87,0x8e,0x92,0x80,0x85,0x2c,0x95,0x91 +,0x9d,0x8d,0x96,0x5d,0x0a,0x49,0x8e,0x23,0x9e,0xa4,0x30,0x27,0xe0,0x40,0x09,0x1b,0x21,0x19,0x90,0xa9,0x0e,0x00,0x14,0x92,0x0c,0x18,0x1b,0x19,0x07,0x0c,0x1b,0x37 +,0x1c,0x1f,0x19,0x19,0x1c,0x0e,0x04,0x08,0x8e,0x0a,0x0e,0xbf,0x38,0x14,0x1f,0x1f,0x35,0x2a,0x2c,0x92,0x8d,0x85,0x8d,0xa4,0x9e,0x81,0x83,0x88,0x81,0x81,0x87,0x87 +,0x80,0x83,0x8d,0x88,0x8d,0x99,0x8a,0x2d,0x0f,0x07,0x32,0x5b,0x00,0x2f,0x08,0x0b,0x03,0x04,0x0c,0x00,0x03,0x03,0x09,0x0c,0x11,0x09,0x00,0x23,0x9b,0x08,0xaa,0xc6 +,0x10,0x14,0xbd,0x8d,0x3e,0x94,0x8f,0x5b,0x9f,0x9a,0x9c,0x46,0x9b,0x83,0x4e,0x8d,0x85,0x97,0xa5,0x8f,0x8d,0x2a,0xa8,0x95,0xa8,0x2a,0x91,0x9d,0x17,0x9e,0x83,0x20 +,0xd6,0x93,0x1e,0x15,0x1b,0xab,0x12,0x21,0x96,0x13,0xc1,0xa3,0x1d,0x0c,0x15,0x91,0x17,0x3d,0x98,0x26,0x19,0x64,0x33,0x36,0x1e,0xb2,0x2d,0xc1,0x96,0x45,0x0f,0x27 +,0x80,0x25,0x2c,0xbb,0xb7,0x4b,0x2f,0x64,0x37,0x1f,0x9b,0xd2,0x16,0xaa,0x11,0x07,0x14,0xa6,0x08,0x0a,0x4f,0x27,0x0e,0x0b,0x40,0x10,0x0d,0x6a,0x25,0x13,0x2c,0xae +,0x34,0x9f,0x80,0x9f,0x94,0x80,0x8a,0x97,0x8a,0x80,0x88,0x88,0x80,0x88,0x89,0x86,0xb3,0x2c,0xaa,0x8d,0x1b,0x1a,0x9e,0x1e,0x0d,0x2a,0x35,0x0b,0x05,0x26,0x1d,0x0a +,0x0a,0x0b,0x04,0x29,0xa0,0x08,0xbd,0x2c,0x0f,0x10,0x0d,0x09,0x09,0x0e,0x1f,0x27,0x0d,0x14,0x10,0x06,0x24,0x63,0xbf,0xb3,0x3e,0xa8,0x27,0x8f,0x97,0x9a,0x8e,0x8b +,0x8c,0x9a,0x90,0x31,0x9c,0x80,0x8e,0x87,0x89,0x93,0xb7,0xcf,0x8c,0xa6,0xcb,0x8f,0x87,0x98,0xa9,0x4b,0x52,0x9b,0x9c,0x16,0xdc,0xaf,0x0a,0x0f,0x20,0x1d,0x0c,0x34 +,0x4b,0xb2,0x37,0x17,0x17,0x0b,0xbf,0x25,0x27,0x8f,0x3b,0x14,0x1e,0x29,0x0e,0x15,0x26,0x16,0x22,0x1f,0x19,0x06,0x29,0x54,0x0d,0x36,0x2f,0x15,0x06,0x1b,0x28,0x08 +,0xd1,0x2d,0x1e,0x66,0x2e,0x14,0x0d,0xa0,0xb4,0xab,0x86,0x85,0x83,0x88,0x82,0x82,0x85,0x81,0x84,0x82,0x83,0x82,0x8f,0x83,0x87,0xa9,0x8c,0xa3,0x13,0x0f,0x08,0x07 +,0x06,0x0f,0x0c,0x09,0x09,0x0d,0x03,0x06,0x32,0x02,0x0b,0x1a,0x0c,0x0d,0x40,0x1e,0x11,0xae,0xac,0x0d,0x18,0x1c,0x04,0xdd,0x8e,0xc0,0xa6,0x93,0xc8,0xa8,0x99,0xa3 +,0x36,0x9f,0x95,0xaa,0x9d,0x9b,0x0f,0xa0,0x82,0xa0,0xac,0x9f,0x25,0x3e,0x97,0xd5,0xa5,0x8c,0x90,0x98,0x8f,0xb6,0x22,0xa0,0x90,0x2b,0x97,0xb7,0x4d,0x58,0x9f,0x95 +,0x1f,0x99,0x9b,0x1d,0xdb,0xc4,0x09,0x8f,0xb7,0x1d,0x84,0xab,0x1a,0xbd,0x32,0x0f,0x1b,0x1b,0x34,0x12,0x23,0x1b,0x25,0x99,0x17,0x26,0x3e,0x28,0x1b,0x23,0xa8,0x13 +,0x46,0x99,0x1c,0x23,0x29,0x05,0x2d,0x3c,0x00,0x2d,0x1b,0x0a,0xbd,0xa2,0x19,0x25,0x45,0x1b,0xcd,0x2a,0x18,0x97,0x85,0x8e,0x80,0x81,0x86,0x82,0x88,0x82,0x8b,0x89 +,0x85,0x8e,0x8f,0x8d,0xa8,0x8d,0x8d,0x24,0x99,0x3f,0x0a,0x0c,0x19,0x02,0x17,0xab,0x06,0x14,0x10,0x00,0x13,0x1d,0x00,0x31,0x1b,0x10,0xd1,0x22,0x25,0x26,0x2c,0x28 +,0x1d,0x0a,0x0d,0x0e,0xbc,0xb8,0x99,0x8f,0x97,0x90,0xbe,0xa0,0x1c,0x36,0x93,0x28,0x49,0x9b,0x26,0x87,0x91,0xc5,0x82,0x99,0xbb,0x9a,0x97,0x25,0x9e,0x89,0xac,0x9a +,0xa9,0x0c,0x92,0xc1,0x0e,0x89,0xda,0x4d,0x98,0xa4,0xa1,0xaa,0xa5,0xa8,0x23,0x1b,0x0c,0x2c,0x3b,0x0f,0x9a,0xb7,0xa5,0xc5,0x76,0xc3,0x0d,0x40,0xeb,0x0c,0x34,0x15 +,0x28,0x8c,0x17,0xaf,0x98,0x26,0x1d,0x3f,0x1c,0x07,0x19,0x23,0x13,0x24,0x0b,0x12,0xa4,0x03,0x24,0x43,0x09,0x1e,0x1e,0x18,0x26,0x73,0xbc,0x42,0x40,0x26,0xbe,0x88 +,0xb3,0x8a,0x81,0x87,0x80,0x82,0x80,0x87,0x87,0x82,0x89,0x8d,0x95,0x5d,0x83,0xa0,0xa4,0x89,0x3b,0x1d,0x15,0x18,0x07,0x06,0x08,0x05,0x09,0x0c,0x01,0x53,0x0e,0x05 +,0xa9,0x10,0x11,0x1a,0x12,0x14,0x38,0x3f,0x1e,0x19,0x17,0x03,0xab,0x34,0x0b,0x98,0x2c,0xa4,0x93,0x98,0xa5,0xc8,0x9a,0x9f,0x2e,0xc4,0x18,0xa3,0x93,0x3a,0x81,0x92 +,0xa1,0x99,0x9d,0x9c,0x2f,0xb0,0xab,0x38,0x9e,0x49,0x97,0x8a,0x23,0x8f,0x93,0xb7,0xb9,0xbb,0xbe,0x26,0x9e,0xab,0x30,0xbc,0x11,0x2e,0x97,0x0b,0x41,0xcc,0x17,0xcd +,0xae,0xa5,0x2f,0xe7,0xc1,0x1c,0x1f,0x0d,0x19,0x9f,0x0e,0xb4,0x98,0x23,0xed,0x3c,0x39,0x24,0x1c,0x3b,0x1f,0x17,0x21,0x27,0x8b,0xc7,0xbb,0x90,0xcd,0xb8,0x67,0xbe +,0x31,0x2b,0x9e,0xa8,0x2a,0x6e,0x1b,0x98,0x48,0x19,0x96,0x35,0x2b,0xaa,0x97,0xac,0xc2,0xac,0x6b,0x20,0x25,0x0c,0xad,0x49,0x0d,0x94,0xbb,0xc3,0xb6,0xb9,0xbd,0x47 +,0xbe,0x40,0x13,0x1c,0x17,0xa0,0x91,0x1f,0x95,0xac,0xc9,0x5f,0x4b,0xae,0x29,0xab,0x90,0xc0,0xc1,0x26,0xc7,0x8b,0x39,0x98,0x9c,0xcc,0xba,0x9f,0x8f,0xac,0xa4,0x94 +,0xb4,0x54,0x1d,0x1b,0xa6,0x0f,0x6d,0xa4,0x3a,0x41,0x21,0xb0,0x36,0x1e,0x28,0x20,0x0f,0x0f,0x0f,0x9f,0x27,0x12,0xb2,0x23,0x1f,0x1d,0xcf,0x1d,0x19,0xbe,0xaf,0x22 +,0x29,0x1e,0x9a,0x99,0x24,0x95,0xb8,0xc5,0xb4,0x97,0x96,0xa0,0xa0,0x92,0xa1,0x34,0x1f,0xb9,0x9a,0x1b,0x91,0x9a,0xa8,0xc4,0xad,0x8f,0xba,0xaf,0x96,0xaa,0x21,0x29 +,0xe5,0x92,0x27,0x3c,0x92,0x9d,0x39,0x3f,0x9d,0x1e,0x2a,0xb9,0xde,0x2e,0x1b,0x15,0x9b,0x32,0x0e,0xbb,0x2f,0x33,0x27,0xd8,0x1c,0x17,0x29,0x37,0x18,0x09,0x0c,0x1b +,0x1c,0x0a,0x30,0x32,0x67,0x21,0xbd,0x9c,0x1c,0x37,0x3b,0x1b,0x11,0x10,0x1a,0x9f,0x3c,0x2f,0x96,0x94,0xa8,0x9a,0x93,0xae,0x97,0x96,0x91,0x97,0xbb,0x9d,0x88,0x94 +,0x9c,0x84,0x8a,0x8d,0x8c,0x87,0x89,0xa4,0xa0,0x93,0x70,0x11,0x16,0x11,0x0b,0x01,0x0b,0x20,0x0d,0x04,0x0d,0x19,0x06,0x08,0x09,0x0a,0x0a,0x04,0x0b,0x28,0x0f,0x09 +,0x4b,0xae,0xa8,0xb0,0x3f,0xec,0xb3,0xae,0x97,0x9d,0xbf,0x9c,0x98,0x8e,0x92,0xa4,0x96,0x89,0x88,0x8e,0x8f,0x9a,0x99,0x8c,0x8c,0x98,0x56,0x29,0xb5,0x79,0x30,0xa3 +,0x4b,0xce,0x97,0x95,0x9b,0x9e,0x93,0x89,0x87,0x93,0x8e,0x8d,0xa5,0xa7,0x95,0x8c,0x97,0x1e,0x0e,0x28,0x1b,0x0a,0x0e,0x06,0x07,0x0c,0x0b,0x0a,0x06,0x05,0x0f,0x1f +,0x17,0x1e,0x0f,0x08,0x12,0x29,0x39,0x21,0x18,0x14,0x1f,0x18,0x1d,0x28,0x28,0xca,0xc3,0x48,0xbd,0xef,0x54,0x9d,0xa8,0xae,0xba,0x30,0xcf,0x99,0x9c,0xa3,0x9e,0xac +,0xa9,0xa9,0xaf,0xa1,0xad,0xea,0x9f,0x8f,0x8e,0x98,0x91,0x87,0x84,0x87,0x85,0x82,0x87,0x90,0x8e,0x87,0x86,0x93,0x2a,0x3c,0x36,0x0f,0x0b,0x0c,0x10,0x0b,0x07,0x0b +,0x0f,0x0b,0x0c,0x14,0x12,0x19,0x18,0x0b,0x0b,0x0d,0x11,0x25,0x25,0x20,0x14,0x15,0x2a,0x7d,0x45,0x2d,0x22,0x16,0x1f,0x3b,0x29,0x26,0x2b,0x3d,0xae,0x55,0xf2,0xb6 +,0xf7,0x3e,0xd7,0xca,0x28,0x26,0x2b,0x4e,0xc3,0x6b,0xaf,0x96,0x93,0x91,0x8c,0x84,0x83,0x8b,0x88,0x84,0x82,0x8b,0x93,0x8b,0x85,0x8f,0xb0,0xb0,0xa0,0x3c,0x1a,0x1e +,0x1d,0x1a,0x0e,0x11,0x18,0x16,0x0f,0x15,0x1b,0x1b,0x1c,0x18,0x1c,0x20,0x1e,0x1d,0x20,0x18,0x1e,0x1d,0x13,0x16,0x1b,0x21,0x2b,0x29,0x2f,0x3b,0x2b,0x2d,0x31,0xb7 +,0xa8,0x3c,0x1e,0x27,0x30,0x2d,0x4c,0xbd,0xcf,0x2f,0x29,0x41,0xbc,0x5d,0xb9,0x98,0x99,0x9f,0x97,0x8c,0x86,0x87,0x8b,0x84,0x81,0x84,0x8e,0x8b,0x86,0x8e,0xa8,0xba +,0x9a,0xbd,0x16,0x0f,0x18,0x1d,0x17,0x0e,0x11,0x0f,0x14,0x17,0x15,0x20,0x1a,0x15,0x16,0x10,0x10,0x16,0x19,0x1b,0x1b,0x19,0x0f,0x19,0x24,0x24,0x34,0x25,0x1d,0x20 +,0x1e,0x27,0x32,0x62,0xcf,0x3f,0xbf,0xca,0xa9,0xb9,0x37,0xc8,0xbd,0xd2,0x32,0x25,0x2e,0x2d,0x2f,0xab,0x95,0x96,0x9b,0x91,0x88,0x88,0x8c,0x87,0x82,0x85,0x8e,0x8f +,0x89,0x87,0x95,0xb1,0xa5,0x9d,0xe4,0x1e,0x1e,0x1c,0x18,0x13,0x15,0x19,0x18,0x11,0x10,0x1b,0x1d,0x1f,0x37,0x27,0x1f,0x25,0x2a,0x45,0x38,0x2d,0x23,0x1a,0x1e,0x22 +,0x3b,0x49,0x24,0x36,0x3d,0x2f,0x2a,0x3f,0xae,0xd0,0x3c,0x31,0x4f,0xcc,0x2c,0x36,0xb6,0x5a,0x21,0x1f,0x2f,0x28,0x1d,0x30,0xa8,0x9e,0xb6,0xa9,0x8f,0x89,0x8e,0x8f +,0x85,0x82,0x87,0x8d,0x8b,0x86,0x8d,0x9b,0x9c,0x9b,0x4f,0x17,0x0f,0x17,0x1f,0x19,0x0f,0x0e,0x0f,0x15,0x16,0x18,0x1a,0x14,0x0f,0x0f,0x1a,0x1f,0x25,0x24,0x23,0x24 +,0x2d,0x34,0x29,0x25,0x21,0x23,0x35,0x57,0x4e,0x3e,0x25,0x28,0xd2,0x9e,0xb8,0x34,0xc7,0xaf,0xa7,0xbc,0xaf,0xad,0x57,0x2a,0x35,0x4a,0x1e,0x1f,0x66,0x9a,0x9a,0x9d +,0x90,0x87,0x8b,0x8e,0x87,0x85,0x88,0x8e,0x8c,0x86,0x8a,0x99,0xa2,0x96,0x96,0x3f,0x19,0x0f,0x13,0x14,0x11,0x14,0x0e,0x0f,0x0b,0x0e,0x14,0x1a,0x1e,0x1b,0x1d,0x1c +,0x18,0x18,0x21,0x34,0x39,0x21,0x18,0x16,0x1d,0x25,0x2c,0x4c,0x44,0x35,0x2e,0x36,0x48,0xf8,0x40,0x3e,0x48,0xae,0xb4,0x2b,0x32,0x4d,0xbf,0xb8,0xba,0x43,0x1b,0x18 +,0x3d,0x9e,0x98,0xaa,0xad,0x93,0x8a,0x8c,0x8c,0x86,0x84,0x89,0x8b,0x86,0x86,0x8d,0xa0,0x98,0x96,0xad,0x1e,0x0e,0x15,0x1e,0x1c,0x17,0x1d,0x14,0x0e,0x0e,0x16,0x19 +,0x18,0x16,0x15,0x18,0x16,0x1f,0x21,0x2c,0xc7,0x49,0x26,0x1c,0x16,0x18,0x1f,0x47,0x5f,0x46,0x25,0x1e,0x2c,0x53,0xae,0x54,0x3c,0xfb,0xb6,0x4f,0x56,0xbd,0xde,0x3d +,0x38,0x35,0x21,0x17,0x18,0xda,0x9e,0x9f,0xa5,0x8f,0x89,0x8c,0x90,0x8a,0x83,0x8a,0x8e,0x8b,0x88,0x8e,0x9b,0x97,0x8c,0x95,0x3a,0x14,0x16,0x2b,0x1e,0x10,0x0f,0x0e +,0x0c,0x12,0x1b,0x1a,0x15,0x16,0x1b,0x28,0x23,0x1e,0x1e,0x1b,0x2b,0x37,0x2f,0x21,0x1d,0x1d,0x35,0x3b,0x34,0x58,0xdd,0x2e,0x25,0x41,0x74,0x3e,0x2a,0x41,0xaf,0xbc +,0x4a,0x51,0xbb,0xc1,0x2a,0x37,0x3d,0x1b,0x12,0x2c,0xa8,0xb8,0x39,0xb4,0x8c,0x89,0x92,0x8e,0x88,0x88,0x89,0x87,0x83,0x85,0x8f,0x9f,0x91,0x8d,0xa6,0x23,0x18,0x17 +,0x1c,0x1c,0x1c,0x1d,0x15,0x11,0x15,0x16,0x15,0x15,0x13,0x19,0x1b,0x1b,0x1c,0x26,0x34,0x42,0x32,0x26,0x1f,0x1c,0x25,0x27,0x1c,0x1e,0x34,0x2b,0x2d,0x36,0x30,0x3f +,0x2d,0x2d,0xac,0xa4,0x4c,0x48,0xbb,0xbf,0x4c,0x36,0x33,0x28,0x10,0x1a,0xb8,0xa8,0xc1,0x44,0x9c,0x89,0x8c,0x8f,0x8b,0x85,0x85,0x8b,0x88,0x84,0x86,0x8d,0x8e,0x8a +,0x92,0xc5,0x1e,0x1f,0x3f,0x27,0x17,0x15,0x0e,0x0e,0x16,0x16,0x17,0x17,0x14,0x17,0x1f,0x1d,0x1b,0x20,0x1e,0x28,0x24,0x25,0x1c,0x11,0x18,0x2a,0x2b,0x2e,0x2f,0x27 +,0x28,0x2e,0xcf,0xb7,0x40,0x19,0x23,0xfe,0xf4,0xe5,0xcc,0xbd,0x5e,0x2b,0x3c,0x4f,0x1e,0x18,0x49,0xaf,0x3a,0x1f,0x4f,0x93,0x8c,0x8e,0x8f,0x87,0x84,0x89,0x8e,0x87 +,0x82,0x8c,0x95,0x90,0x91,0xa6,0x34,0x1c,0x2b,0x37,0x25,0x1d,0x15,0x0f,0x10,0x14,0x1b,0x19,0x11,0x14,0x14,0x18,0x20,0x21,0x1d,0x23,0x26,0x1c,0x27,0x28,0x1e,0x28 +,0x2c,0x28,0x2c,0x20,0x2a,0x36,0x24,0x2d,0x2f,0x1e,0x38,0xa6,0xa5,0xb1,0xb5,0xaf,0xc8,0x32,0x21,0x2f,0x1c,0x12,0x24,0xbf,0xa5,0xe5,0xe2,0x94,0x89,0x8e,0x98,0x92 +,0x89,0x8a,0x8f,0x88,0x82,0x88,0x91,0x8d,0x89,0x89,0x9b,0x1d,0x1c,0x1d,0x1f,0x1e,0x1b,0x14,0x11,0x10,0x16,0x1b,0x14,0x15,0x19,0x15,0x14,0x17,0x1b,0x28,0x33,0x30 +,0x28,0x1d,0x19,0x1d,0x30,0x40,0x4e,0x5a,0x45,0x3e,0x32,0xc7,0xac,0x39,0x19,0x1d,0x2a,0x28,0x2d,0x3c,0xab,0xa2,0x4b,0x3c,0x5f,0x23,0x1a,0x1f,0xb6,0xaf,0x1b,0x2a +,0x95,0x8c,0x8e,0x8b,0x86,0x83,0x86,0x8b,0x86,0x82,0x88,0x8a,0x8e,0x8d,0x94,0x39,0x17,0x2b,0x40,0x25,0x19,0x11,0x13,0x13,0x13,0x1b,0x1d,0x0e,0x10,0x16,0x18,0x25 +,0x1e,0x1c,0x30,0x28,0x3a,0x39,0x25,0x25,0x1e,0x1d,0x30,0x38,0x24,0x2c,0x4e,0x2d,0x4e,0xb0,0xeb,0xac,0x3c,0x07,0x10,0x82,0x91,0x23,0x80,0x9d,0x0e,0xaf,0x17,0x3a +,0x3f,0xa3,0x98,0xb7,0x0a,0x03,0x25,0x00,0x08,0x0b,0x01,0x05,0x01,0x04,0x07,0x12,0xb4,0x29,0x09,0x14,0xa8,0xc2,0xa3,0x9d,0x24,0x43,0x8b,0x8e,0x8e,0x80,0x88,0x91 +,0x9c,0x89,0x80,0x81,0x80,0x83,0x81,0x82,0x82,0x87,0x95,0x87,0x80,0x82,0x82,0xcd,0xbd,0x86,0x83,0x89,0xa1,0xac,0xdd,0x59,0x1b,0x05,0x08,0x05,0x0d,0x16,0x0c,0x40 +,0x1a,0x07,0x09,0x06,0x0a,0x06,0x12,0x19,0x08,0x09,0x06,0x00,0x01,0x00,0x0b,0x0f,0x04,0x03,0x00,0x02,0x05,0x11,0x06,0x08,0x19,0x0a,0x05,0x00,0x0b,0x1f,0x09,0x2f +,0x96,0xe6,0x9b,0x3f,0xac,0x8a,0x84,0x82,0x91,0x87,0x82,0x80,0x80,0x83,0x84,0x9b,0x8b,0x80,0x81,0x80,0x82,0x82,0x80,0x83,0x87,0x83,0x80,0x80,0x81,0x85,0x96,0x8a +,0x89,0x92,0x81,0x81,0x80,0x89,0x22,0x8f,0x84,0x82,0x89,0x93,0x87,0x91,0x8a,0xb0,0x17,0x3c,0x16,0x18,0x12,0x04,0x17,0x08,0x05,0x08,0x03,0x04,0x00,0x05,0x00,0x04 +,0x03,0x02,0x00,0x01,0x00,0x07,0x0f,0x03,0x06,0x00,0x01,0x04,0x03,0x01,0x06,0x19,0x1b,0x0e,0x02,0x09,0x0b,0x07,0x02,0x13,0x11,0x16,0x13,0x05,0x1c,0x12,0x20,0x0e +,0x07,0x12,0xe8,0x37,0x0f,0x0e,0x15,0x2d,0xa2,0x87,0x92,0x8e,0x96,0x8a,0x94,0x9a,0x84,0x85,0x83,0x85,0x86,0x95,0x95,0x8d,0x8b,0x9e,0x8a,0x80,0x83,0x89,0x8c,0x80 +,0x82,0x80,0x85,0x8a,0x87,0x80,0x85,0x8a,0x8e,0x88,0x92,0x0f,0xb6,0xa1,0x94,0xc3,0x0e,0x23,0x1a,0x6a,0x48,0xd8,0x8a,0x85,0x8d,0x9d,0x2c,0x92,0x98,0x8e,0x83,0x8f +,0x88,0x9e,0x91,0x8d,0x94,0x88,0x8d,0x8f,0x8d,0xa3,0x8a,0x87,0x88,0x89,0x29,0x8d,0x8b,0x89,0x8b,0x9f,0x84,0x87,0x91,0xb0,0xbf,0x8d,0x8c,0xe3,0x39,0x08,0x0b,0x02 +,0x06,0x1c,0x16,0xaf,0x0b,0x01,0x06,0x06,0x09,0x04,0x01,0x05,0x02,0x03,0x02,0x00,0x00,0x00,0x06,0x03,0x01,0x01,0x00,0x02,0x01,0x00,0x00,0x01,0x05,0x03,0x00,0x04 +,0x00,0x02,0x00,0x06,0x14,0x18,0x11,0x00,0x01,0x01,0x03,0x04,0x01,0x03,0x0d,0x0b,0x0d,0x04,0x0b,0x09,0x0c,0xa6,0x48,0xb6,0x23,0x2f,0x9e,0x9f,0x8d,0x8b,0x8c,0x87 +,0x85,0x80,0x80,0x81,0x86,0x8a,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x80,0x80,0x80,0x81,0x8b,0x94,0xbe,0x8a,0x81,0x82,0x86,0xc3,0xa9,0x96,0x88,0x84 +,0x87,0x85,0x8a,0x8b,0x89,0x9a,0xac,0x26,0x8f,0x81,0x86,0x90,0x21,0xad,0x9c,0x9d,0xc1,0x1b,0x29,0xaa,0xe3,0xb8,0x2e,0x29,0x0b,0x0f,0xb1,0xa5,0x98,0x15,0x0f,0x15 +,0x1b,0x1d,0x0d,0x06,0x0e,0x0f,0x0f,0x03,0x01,0x00,0x05,0x25,0x1f,0x1b,0x04,0x04,0x0a,0x0a,0x0c,0x08,0x09,0x0f,0x09,0x0d,0x0b,0x04,0x00,0x02,0x16,0x1a,0x17,0x04 +,0x00,0x08,0x0e,0x17,0x0e,0x07,0x1f,0x23,0x38,0x1c,0x07,0x03,0x07,0x9a,0x9b,0xa3,0x1d,0x0b,0x16,0x17,0x3a,0x4c,0x1b,0x2f,0x33,0xcd,0xd1,0x1e,0x1d,0x28,0x88,0x84 +,0x87,0xb1,0x17,0xa5,0x89,0x83,0x88,0x97,0x8f,0x88,0x84,0x82,0x89,0x8e,0x8a,0x80,0x80,0x80,0x82,0x83,0x82,0x80,0x81,0x84,0x92,0x8f,0x94,0x8d,0x96,0x19,0x04,0x00 +,0x1e,0x48,0x28,0x05,0x00,0x01,0x03,0x0b,0x10,0x07,0x14,0x13,0x1f,0x10,0x02,0x03,0x04,0xa4,0x99,0xaa,0x0f,0x00,0x09,0x17,0xae,0x9a,0x1a,0x21,0x18,0xb1,0xa0,0x25 +,0x23,0x1d,0x86,0x82,0x82,0x9f,0x1f,0x9f,0x85,0x82,0x84,0x93,0x8a,0x8b,0x86,0x8e,0x38,0x19,0x1f,0x87,0x82,0x82,0x96,0x3f,0xa6,0x8b,0x81,0x83,0x8e,0x8c,0x99,0x88 +,0x96,0x3c,0x0f,0x1a,0x88,0x84,0x8c,0x15,0x02,0x0a,0x20,0x9a,0xa5,0x16,0x26,0x1e,0x9a,0x2f,0x0c,0x03,0x0f,0x8f,0x8c,0x8f,0x1a,0x08,0x08,0x15,0xa4,0xcb,0x11,0x0c +,0x0b,0xd9,0x10,0x04,0x00,0x0e,0x95,0x8a,0x92,0x0c,0x02,0x03,0x0e,0x99,0xaf,0xce,0x48,0xc1,0x8b,0xaa,0xf3,0x1e,0x90,0x80,0x81,0x80,0x93,0xb8,0x98,0x87,0x80,0x82 +,0x83,0x98,0x9b,0x89,0xa2,0x1e,0x04,0x13,0xc1,0x9d,0x1b,0x00,0x01,0x00,0x05,0x12,0x0b,0x0f,0x09,0x15,0x28,0x0e,0x05,0x02,0x18,0xa8,0x8d,0xa7,0x11,0x07,0x07,0x27 +,0x98,0x9e,0x9e,0x1c,0x3f,0x39,0x1a,0x09,0x0b,0xa3,0x88,0x82,0x8e,0x65,0x20,0x36,0x8d,0x86,0x8b,0x8d,0xa0,0x8f,0xa3,0xc5,0x11,0x28,0xb1,0x8f,0x8b,0xac,0x21,0x0e +,0x1c,0x95,0x8f,0x8d,0x9d,0xb3,0x9b,0xae,0xbe,0x0b,0x23,0xb8,0x8a,0x8b,0xed,0x14,0x08,0x0c,0x21,0x1d,0xbe,0x1e,0x1c,0x28,0x1d,0x17,0x0a,0x4e,0xaf,0x8f,0xac,0x20 +,0x0e,0x0b,0x19,0x3f,0x39,0xdd,0x11,0x19,0x18,0x1e,0x0b,0x04,0x0c,0x1a,0x9d,0x2f,0x1e,0x0e,0x10,0x26,0x3b,0xdc,0xad,0x2b,0xa5,0xc8,0x9f,0x3a,0xae,0x91,0x8b,0x81 +,0x88,0x87,0x93,0x8e,0x85,0x83,0x81,0x83,0x87,0x85,0x8c,0x8a,0xba,0x9b,0xae,0x9a,0x9f,0x1a,0x0d,0x04,0x07,0x0c,0x06,0x0b,0x05,0x05,0x08,0x05,0x0d,0x04,0x20,0x1b +,0xb5,0xea,0x1c,0x1e,0x10,0x1d,0xb3,0x4b,0xa8,0x1b,0x20,0x3b,0x29,0x59,0x17,0xaf,0xdc,0x99,0xa0,0xb1,0xbd,0x60,0xa7,0x93,0x97,0x8c,0x9e,0x95,0x98,0x97,0x9f,0x9f +,0x8a,0x90,0x8d,0xb9,0xbc,0x27,0x1d,0x59,0xad,0xa4,0x9a,0x50,0x9c,0xb5,0x95,0xb6,0xa9,0x90,0x9f,0x90,0xe2,0x4c,0x1d,0x1d,0xb9,0xc5,0xce,0xb8,0x15,0x30,0x0d,0x19 +,0x0e,0x22,0xb8,0xc4,0xa5,0x2a,0x24,0x17,0x1b,0xbd,0xb2,0xad,0xdf,0x0e,0x1a,0x0a,0x14,0x09,0x22,0x2a,0x2b,0x1d,0x0b,0x0a,0x07,0x10,0x39,0x34,0x6c,0x29,0x14,0x26 +,0x14,0x3e,0x25,0x91,0x8f,0x87,0x8a,0x8f,0x8b,0x90,0x88,0x82,0x83,0x81,0x86,0x88,0x88,0x8c,0x89,0x92,0x84,0x88,0x83,0x8e,0xa9,0x28,0x0e,0x0d,0x17,0x0d,0x10,0x07 +,0x04,0x03,0x01,0x02,0x04,0x19,0x1d,0xb0,0x24,0x13,0x0a,0x07,0x10,0xe6,0xdd,0x9f,0x31,0x2b,0x13,0x1b,0x1c,0x2f,0x9c,0x9e,0x8e,0xd8,0x22,0x17,0x1c,0x53,0x9b,0x98 +,0x8b,0x9d,0x99,0x63,0xa0,0xbc,0x9c,0x87,0x89,0x85,0x99,0xad,0x3c,0x27,0xd0,0xa0,0x9e,0x97,0x31,0xc3,0x1f,0xbc,0x2d,0xa9,0x94,0x8e,0x88,0x96,0xa5,0x46,0x24,0x2d +,0xba,0xac,0xa0,0x2a,0x26,0x0a,0x0f,0x07,0x1e,0x3c,0xba,0xa2,0x30,0x25,0x15,0x16,0x27,0xda,0x9c,0x9f,0x73,0x57,0x0d,0x11,0x09,0x22,0x5c,0xbb,0xbe,0x19,0x0c,0x09 +,0x09,0x17,0x1b,0x22,0x23,0x12,0x1a,0x0b,0x18,0x16,0xcd,0x9b,0x97,0x8b,0x90,0x90,0x91,0x9a,0x8d,0x87,0x83,0x82,0x85,0x86,0x8a,0x88,0x8b,0x88,0x83,0x8a,0x8b,0x93 +,0x98,0x9b,0x22,0x24,0x15,0x1c,0x1c,0x0f,0x0e,0x05,0x03,0x03,0x02,0x0a,0x07,0x0c,0x0e,0x0a,0x14,0x0a,0x12,0x18,0x1f,0xc7,0xd1,0xc0,0x32,0x29,0x21,0x1a,0x33,0x3a +,0xd0,0xbd,0xd0,0xc4,0xdd,0x31,0xbe,0xa2,0x9e,0x97,0xa3,0xa3,0x9f,0x97,0x90,0x8e,0x94,0x98,0x9e,0x97,0x92,0x93,0xa0,0xd6,0xfc,0x33,0xbb,0xab,0xaa,0xa1,0xe5,0xbb +,0xa5,0xac,0xab,0xbe,0xb8,0xa5,0x96,0x9e,0x9f,0xbe,0x26,0x2f,0x37,0xe4,0xb8,0x3b,0x36,0x1f,0x23,0x22,0x28,0x2a,0x17,0x28,0x1d,0x35,0x33,0x1d,0x1f,0x1d,0x24,0xbd +,0xc0,0xb8,0x42,0x26,0x17,0x14,0x12,0x12,0x16,0x0b,0x0e,0x12,0x13,0x17,0x16,0x12,0x1b,0x17,0x21,0x43,0xe1,0xae,0xa5,0xa2,0x9a,0x8d,0x88,0x83,0x84,0x87,0x85,0x87 +,0x86,0x83,0x84,0x84,0x85,0x8a,0x92,0x8e,0x92,0x93,0x9a,0xab,0xbd,0x37,0x15,0x0f,0x0c,0x07,0x0a,0x0c,0x0c,0x08,0x08,0x04,0x09,0x0a,0x0d,0x16,0x13,0x17,0x14,0x16 +,0x4f,0x46,0x30,0x2a,0x35,0x3d,0x42,0x75,0x2e,0x2a,0x29,0xc5,0xa9,0xb9,0xdd,0xd7,0x39,0xd8,0xeb,0xc1,0x9d,0x92,0x93,0x9c,0xac,0x9f,0x98,0x93,0x90,0x97,0x94,0x97 +,0x9a,0xad,0xea,0x4c,0xbe,0xa0,0xa5,0x69,0xcb,0x2c,0x35,0xc5,0xc0,0xb7,0x44,0x3c,0x28,0xbc,0xa4,0xa3,0xad,0x2c,0x1e,0x1e,0x3f,0x66,0x3c,0x2d,0x18,0x15,0x23,0x61 +,0x4b,0x6d,0x29,0x24,0x2e,0x4d,0x44,0x3e,0xbd,0xb0,0x98,0xa1,0xb0,0x2b,0x2c,0x34,0x4d,0xb2,0xce,0x30,0x14,0x0f,0x12,0x48,0x97,0x8f,0x9d,0x31,0x16,0x29,0xbf,0xab +,0xa7,0x9f,0xaf,0x2b,0x3e,0x32,0xcc,0xaf,0xbf,0x2f,0x1f,0x29,0x25,0x39,0x33,0x1f,0x2a,0xb6,0x9e,0xb3,0x62,0x4d,0xd3,0xa8,0xa1,0x9f,0xb6,0x32,0x2e,0x30,0xa9,0xa1 +,0xb2,0x27,0x1b,0x1f,0x54,0xa1,0xa9,0xa6,0x4b,0x30,0xd8,0x9a,0x92,0x8f,0x9f,0xef,0x34,0x4e,0xa8,0xa0,0x9c,0xad,0xba,0xaa,0xa8,0xbb,0xd6,0xb2,0xc8,0x42,0xba,0x62 +,0x2c,0x20,0x1a,0x20,0xac,0x9a,0x97,0xc8,0x19,0x0f,0x0f,0x30,0x3a,0x28,0x1b,0x0b,0x05,0x0b,0x1a,0x4f,0x4f,0x39,0x19,0x12,0x1c,0x21,0x48,0xd5,0x38,0xd3,0xb3,0xac +,0xba,0xb6,0xbc,0x51,0xaf,0xa1,0x9c,0x9f,0xab,0xcf,0xb3,0x96,0x8f,0x8e,0x8f,0xa1,0xa9,0x99,0x8f,0x8e,0x93,0xb5,0x36,0xc8,0x9a,0x8f,0x98,0xaf,0x21,0x1c,0x2a,0xce +,0xb4,0xac,0xe9,0x34,0x4c,0x48,0x43,0xae,0xab,0x4f,0x2a,0x25,0x1e,0x1c,0x1d,0x25,0x3f,0x2f,0x1a,0x0f,0x15,0x1b,0x25,0x1d,0x0e,0x0c,0x11,0x20,0x44,0x2e,0x22,0x21 +,0x21,0x2a,0x46,0xb8,0xe1,0x21,0x15,0x10,0x1e,0xa4,0x94,0xa9,0x1d,0x17,0x1f,0xaf,0x92,0x9b,0x9b,0x9a,0xa2,0x99,0x8e,0x8d,0x8e,0x8b,0x8c,0x9c,0x9f,0x93,0x95,0x8e +,0x94,0x99,0x91,0x8b,0x8a,0x94,0x92,0x9f,0xa0,0x9d,0xa9,0xaa,0xad,0xde,0x20,0x1d,0x2a,0x30,0x1e,0x10,0x07,0x09,0x0b,0x0b,0x0a,0x04,0x01,0x01,0x05,0x0b,0x0e,0x0e +,0x09,0x07,0x08,0x0d,0x1a,0x29,0x32,0x28,0x24,0x2f,0x3d,0xb8,0x9d,0x9e,0xa1,0x9a,0x91,0x93,0x94,0x96,0x99,0x93,0x8a,0x85,0x87,0x8d,0x90,0x8f,0x8b,0x88,0x89,0x8d +,0x90,0x91,0x9c,0x92,0x8f,0x8f,0x8d,0x9c,0x4e,0x38,0xb6,0xa6,0xa7,0xb3,0xbd,0xac,0x9b,0xa3,0xcc,0x3d,0x2e,0x2c,0x2c,0x29,0x1b,0x18,0x18,0x13,0x16,0x1c,0x20,0x1d +,0x18,0x13,0x11,0x1e,0x25,0x1b,0x0d,0x0a,0x0e,0x1c,0x61,0x4d,0x29,0x1f,0x21,0x1e,0x29,0x22,0x21,0x28,0x1d,0x17,0x1e,0x2a,0x34,0xbd,0xd1,0xf8,0xcf,0x9e,0x9d,0xa8 +,0xbf,0x46,0xc0,0x9e,0x90,0x95,0xaa,0xb4,0xb0,0x9b,0x91,0x97,0x99,0x9f,0xb1,0xd4,0xa0,0x96,0x92,0x9a,0xb9,0xf5,0xad,0x9f,0xa5,0xbf,0x4a,0x4e,0x53,0xbc,0xce,0x36 +,0x1a,0x10,0x10,0x14,0x10,0x0d,0x0f,0x11,0x11,0x1b,0x39,0xd8,0xb9,0x3f,0x22,0x34,0xa3,0x8f,0x8f,0x98,0xa4,0xa7,0x8b,0x83,0x83,0x86,0x8b,0x8d,0x8b,0x85,0x85,0x8c +,0x96,0xa0,0xad,0xa0,0x9d,0xa6,0x58,0x23,0x14,0x10,0x17,0x18,0x0c,0x04,0x02,0x03,0x07,0x0b,0x08,0x05,0x06,0x07,0x0c,0x0d,0x0f,0x0f,0x0d,0x0c,0x0b,0x12,0x2d,0x33 +,0x21,0x19,0x16,0x28,0xa2,0x9a,0xbf,0x3b,0x5c,0xa2,0x8f,0x8c,0x99,0xb7,0xa6,0x8f,0x8b,0x8c,0x8d,0x96,0xa7,0x9d,0x8d,0x8a,0x88,0x89,0x92,0xa7,0x9d,0x8e,0x8d,0x98 +,0xb8,0x4a,0xb1,0x96,0x8d,0x92,0xb6,0x52,0xb4,0xa0,0xa5,0xa0,0xba,0x27,0x21,0x2b,0x3e,0xbd,0xa4,0x55,0x1d,0x17,0x29,0xa7,0xa6,0x24,0x0a,0x06,0x10,0xce,0xa6,0x27 +,0x0e,0x0d,0x10,0x36,0xa9,0xdf,0x18,0x10,0x14,0x0c,0x28,0xa9,0x26,0x0a,0x0d,0x14,0x18,0xa2,0xa4,0x0f,0x09,0x24,0xb5,0xa8,0xa0,0x3d,0x14,0x23,0xa7,0xa8,0xaf,0xa1 +,0xc1,0x17,0x15,0xa6,0x8e,0x95,0x9c,0xa4,0x59,0x25,0x93,0x82,0x96,0x20,0x2c,0xb7,0xab,0x8b,0x88,0x4b,0x13,0x2a,0xc4,0xb9,0x9e,0xbf,0x0b,0x08,0x26,0x9f,0xbe,0x33 +,0x46,0x19,0x14,0x99,0x82,0x8c,0x3e,0x53,0xac,0x9f,0x88,0x81,0x8b,0xb2,0x9e,0x8e,0x87,0x83,0x81,0x8d,0xad,0x9f,0x9b,0x99,0x8e,0x8a,0x4c,0x09,0x0f,0x31,0xfa,0x2f +,0x1e,0x0a,0x01,0x08,0x27,0x1f,0x05,0x02,0x03,0x02,0x0a,0x24,0x0d,0x01,0x02,0x06,0x0f,0x2f,0xbb,0x10,0x02,0x08,0x23,0xae,0xa7,0xbd,0x1a,0x0a,0x2e,0x8d,0x87,0x95 +,0xe9,0xc0,0xcf,0x94,0x84,0x85,0x9e,0x53,0xa4,0x9c,0x8b,0x82,0x88,0xa2,0xb1,0x99,0x90,0x87,0x83,0x93,0x1f,0x24,0x9e,0x91,0x8b,0x8f,0xfd,0x10,0x1d,0x93,0x86,0x91 +,0x62,0x25,0x18,0x1e,0x95,0x8c,0xdd,0x13,0x0e,0x14,0x2c,0x94,0xa5,0x0f,0x08,0x0f,0x23,0xbe,0xa7,0x19,0x04,0x07,0x1f,0xaa,0xb5,0x20,0x10,0x09,0x0c,0x49,0x8f,0xb0 +,0x0d,0x0a,0x0b,0x12,0xb4,0x98,0x2e,0x0d,0x0c,0x11,0x2c,0x91,0x92,0x25,0x11,0x24,0xb4,0xa0,0x96,0xa9,0x22,0x14,0x37,0x8f,0x8d,0xa0,0xbf,0xba,0x3f,0x9a,0x83,0x88 +,0xb8,0x38,0x2b,0x42,0x8b,0x82,0x98,0x13,0x1b,0x4e,0x9d,0x8a,0x91,0x1d,0x08,0x14,0xbf,0x99,0xa9,0x26,0x0e,0x07,0x0f,0x9a,0x8c,0x54,0x18,0x1f,0x1a,0xc1,0x86,0x88 +,0xbd,0xc7,0x9a,0x96,0x87,0x81,0x88,0x9c,0x99,0x8c,0x8a,0x84,0x84,0x8f,0x7b,0x2a,0xa4,0x8b,0x98,0x2f,0x1c,0x0b,0x05,0x21,0x9d,0x21,0x05,0x05,0x02,0x05,0x24,0x23 +,0x04,0x01,0x01,0x04,0x0f,0x3f,0x16,0x03,0x02,0x09,0xeb,0xad,0x2d,0x0f,0x08,0x04,0x1a,0x8b,0x8f,0x25,0x21,0x41,0x2f,0x92,0x81,0x8c,0x55,0xca,0xa6,0x9c,0x88,0x84 +,0x94,0xc2,0xaf,0x9d,0x8c,0x84,0x87,0x92,0xbe,0xc7,0x8e,0x86,0x8c,0x96,0x97,0x68,0x51,0x8a,0x85,0x9c,0xdb,0xca,0x56,0x97,0x84,0x8d,0x28,0x18,0x19,0x40,0x8e,0x8e +,0x27,0x06,0x09,0x19,0xa9,0x99,0xb2,0x1c,0x09,0x08,0x2b,0x98,0x61,0x0e,0x0c,0x08,0x08,0x3c,0xa6,0x1b,0x0c,0x0f,0x0d,0x18,0xb7,0x3b,0x0f,0x0d,0x0a,0x0a,0x27,0xa4 +,0xbf,0x15,0x0b,0x15,0xc2,0x9e,0xa7,0x78,0x1c,0x0e,0x30,0x8f,0x91,0xab,0xc5,0x2c,0x28,0x8f,0x83,0x90,0xd7,0x2d,0x28,0x9e,0x84,0x86,0xb2,0x1b,0x35,0xac,0x94,0x8d +,0x94,0x46,0x1a,0x5a,0x96,0x93,0xaf,0x3b,0x20,0x0d,0x24,0x96,0x9c,0x2c,0x22,0x21,0x15,0x76,0x8f,0x94,0xa3,0xad,0xcf,0xc2,0x90,0x85,0x8d,0xa4,0xa5,0x94,0x8a,0x84 +,0x82,0x88,0x9d,0xb3,0x90,0x88,0x8d,0x9b,0x4e,0x10,0x11,0xa7,0x9a,0x24,0x0a,0x05,0x05,0x12,0xb9,0x18,0x02,0x01,0x01,0x05,0x0d,0x1d,0x0d,0x03,0x03,0x07,0x14,0x1f +,0x1b,0x14,0x06,0x06,0x1f,0xab,0x57,0x24,0x30,0x1f,0x1b,0xb2,0x98,0x9c,0x9d,0xa8,0xc7,0xa9,0x8c,0x87,0x90,0xb1,0xc4,0xa4,0x8e,0x86,0x89,0x9b,0x75,0xb7,0x90,0x87 +,0x85,0x88,0x9f,0x3c,0xa6,0x87,0x86,0x94,0x53,0x1f,0xd6,0x8d,0x85,0x92,0x37,0x29,0x2a,0x51,0x9c,0x95,0x43,0x12,0x17,0x2d,0xad,0x9f,0xaf,0x1d,0x0d,0x15,0xad,0x9f +,0xbf,0x19,0x0e,0x0b,0x0c,0x26,0x3a,0x36,0x1e,0x0e,0x09,0x11,0x48,0x5d,0x16,0x0b,0x08,0x09,0x1f,0xd3,0x30,0x17,0x0c,0x0f,0x1d,0xc6,0xa7,0x3d,0x15,0x0f,0x47,0x97 +,0x99,0xb0,0x19,0x0e,0x33,0x94,0x8e,0x99,0xcc,0x35,0x23,0xa7,0x88,0x85,0x90,0xc8,0xc1,0x54,0xaa,0x8e,0x98,0x4b,0x2f,0xbd,0x9c,0x97,0x8f,0x98,0xf7,0x1d,0x1c,0x26 +,0xe1,0x9e,0xc2,0x1e,0x0f,0x1d,0xb2,0xb8,0xd2,0xbf,0x24,0x3c,0x96,0x8c,0x95,0xac,0xad,0xa3,0x92,0x83,0x81,0x87,0x8f,0x98,0x8e,0x87,0x84,0x8b,0xa3,0x5f,0x9f,0x98 +,0xa0,0xab,0x77,0x13,0x08,0x07,0x1d,0x19,0x0c,0x0d,0x04,0x03,0x05,0x0c,0x0c,0x07,0x08,0x08,0x07,0x0a,0x1b,0x11,0x09,0x04,0x05,0x1b,0x39,0xa3,0x2c,0x07,0x08,0x16 +,0xc6,0x92,0x9c,0x2f,0x1a,0x32,0x8d,0x8a,0x94,0x4b,0x0f,0x41,0x90,0x83,0x82,0x96,0x3f,0x36,0x97,0x82,0x82,0x89,0x9e,0xbf,0x96,0x96,0x94,0x2d,0x1b,0x4e,0x93,0x80 +,0x84,0x8e,0x41,0x10,0x30,0x8b,0x87,0x8c,0x2e,0x17,0x1f,0x1d,0x18,0x1b,0x9e,0x99,0x8a,0x95,0x1e,0x12,0x16,0x94,0x9f,0x02,0x8e,0x91,0x08,0x4b,0x0e,0x08,0x00,0x0c +,0x17,0xc6,0xaa,0x00,0x03,0x00,0x01,0x06,0x03,0x0d,0x05,0x00,0x05,0x05,0x03,0x00,0x07,0x25,0x9f,0x8a,0x99,0xcf,0x1e,0xde,0x8d,0x86,0x86,0x80,0x84,0x8c,0x85,0x81 +,0x82,0x8a,0x80,0x80,0x80,0x81,0x85,0x8c,0x97,0x89,0x80,0x82,0x80,0x8c,0x91,0x8d,0x9f,0x2a,0x21,0x8a,0x89,0x80,0x8c,0x1e,0x06,0x04,0x14,0xc8,0xd1,0x1c,0x08,0x01 +,0x08,0x02,0x02,0x00,0x08,0x09,0x25,0x1d,0x02,0x00,0x00,0x00,0x0a,0x10,0x0e,0x05,0x00,0x04,0x00,0x03,0x00,0x09,0x10,0xcd,0xae,0x08,0x04,0x01,0x0d,0xad,0x98,0x8d +,0x92,0xa1,0x8d,0x99,0xa4,0x38,0x8e,0x80,0x81,0x80,0x87,0x90,0xb7,0x89,0x80,0x80,0x80,0x82,0x84,0x82,0x84,0x86,0x8e,0x8a,0x80,0x81,0x80,0x82,0x8b,0xc7,0x94,0x80 +,0x80,0x80,0x81,0x8f,0x8a,0x89,0x95,0x3d,0xa7,0x83,0x83,0x80,0xa7,0x0f,0x06,0x0b,0x35,0xa7,0xf8,0x25,0x05,0x0c,0x06,0x01,0x00,0x02,0x18,0x2e,0xb9,0x08,0x00,0x00 +,0x00,0x09,0x13,0x0b,0x07,0x00,0x04,0x02,0x00,0x00,0x00,0x0c,0x2a,0xa9,0x08,0x00,0x01,0x00,0x0c,0x28,0x1f,0x16,0x04,0x07,0x07,0x05,0x03,0x06,0xac,0x90,0x88,0x4f +,0x07,0x04,0x0b,0x97,0x84,0x87,0x8b,0xab,0x92,0x91,0xa8,0x48,0xa4,0x80,0x82,0x80,0x8b,0xc3,0x25,0x9b,0x81,0x80,0x80,0x84,0x97,0x8d,0x88,0x8d,0x9f,0x99,0x80,0x82 +,0x80,0x88,0xb1,0x18,0xbc,0x82,0x80,0x81,0x85,0xa3,0x95,0x97,0x9a,0xe2,0xaa,0x81,0x82,0x80,0x99,0x1f,0x0d,0x25,0x8a,0x82,0x86,0x8e,0xcf,0xa6,0x50,0x37,0x1d,0x55 +,0x84,0x84,0x80,0x9f,0x10,0x08,0x23,0x8b,0x81,0x86,0x8e,0x3c,0xb7,0x5c,0xd8,0x2c,0xd1,0x84,0x85,0x81,0xa1,0x14,0x06,0x15,0x96,0x87,0x89,0x9e,0x0f,0x0f,0x0c,0x0d +,0x07,0x0f,0xc8,0xae,0xa3,0x08,0x00,0x00,0x01,0x12,0x29,0x17,0x09,0x00,0x01,0x00,0x01,0x00,0x02,0x0b,0x1b,0x15,0x01,0x00,0x00,0x00,0x08,0x1a,0x0d,0x07,0x00,0x02 +,0x00,0x02,0x00,0x03,0x0b,0x18,0x27,0x03,0x00,0x00,0x00,0x11,0x54,0x53,0x19,0x01,0x08,0x04,0x0c,0x08,0x16,0x96,0x94,0x8c,0x2e,0x0f,0x0a,0x2a,0x87,0x80,0x81,0x83 +,0x91,0x8f,0x8c,0x87,0x88,0x86,0x80,0x81,0x80,0x84,0x88,0x93,0x8a,0x80,0x80,0x80,0x81,0x86,0x83,0x83,0x81,0x82,0x84,0x80,0x81,0x80,0x82,0x89,0x9d,0x98,0x81,0x80 +,0x80,0x82,0x93,0x8e,0x8e,0x8b,0x91,0x9e,0x82,0x85,0x80,0x8d,0x2d,0x12,0x0e,0x97,0x88,0x8d,0xa1,0x0d,0x0e,0x0d,0x0c,0x0b,0x01,0x1c,0x21,0xc2,0x18,0x00,0x02,0x00 +,0x0c,0x2e,0x1e,0x0b,0x01,0x01,0x02,0x03,0x04,0x00,0x09,0x0e,0x2d,0x14,0x00,0x02,0x00,0x06,0x1f,0x35,0x15,0x02,0x02,0x04,0x04,0x09,0x01,0x11,0x1d,0xad,0x44,0x02 +,0x04,0x00,0x14,0xa2,0x9b,0xa0,0x18,0x17,0x21,0x22,0x2e,0x0d,0xac,0x8f,0x88,0x88,0x2d,0x17,0x09,0xa9,0x83,0x83,0x84,0xa1,0xae,0x98,0x91,0x8f,0x3c,0x96,0x84,0x83 +,0x81,0xa0,0x2f,0x0e,0xa5,0x81,0x82,0x82,0x9d,0xad,0xa4,0xa9,0x95,0x4d,0xa9,0x8b,0x88,0x84,0xdd,0x29,0x0e,0x1e,0x8b,0x88,0x89,0x51,0x21,0x3e,0x22,0x3d,0x0f,0x1b +,0xa1,0x99,0x88,0x20,0x0b,0x04,0x0c,0x98,0x9a,0x93,0x1e,0x0d,0x19,0x1c,0x2c,0x0a,0x0c,0xd5,0xa4,0x87,0xdf,0x0a,0x04,0x06,0xa3,0x92,0x8c,0xd5,0x15,0x1f,0x1e,0xcd +,0x24,0x18,0x98,0x8f,0x83,0x9f,0x27,0x16,0x0f,0x8d,0x88,0x83,0x8f,0xaa,0xaf,0xba,0x96,0xa7,0x4b,0x8a,0x87,0x80,0x8f,0x36,0x1d,0x15,0x8b,0x87,0x81,0x91,0x37,0xc3 +,0xae,0x9f,0x3a,0x14,0xad,0x95,0x84,0x94,0x0f,0x0a,0x03,0xd9,0x98,0x8a,0xa7,0x11,0x16,0x1a,0x40,0x1d,0x0c,0x36,0xa4,0x8d,0x9d,0x0e,0x0a,0x01,0x34,0x9a,0x8d,0x9b +,0x1f,0x1c,0x1c,0x35,0x1e,0x0c,0x3e,0x9c,0x8c,0x97,0x13,0x0c,0x02,0x43,0x98,0x8c,0x9f,0x1a,0x1e,0x1f,0x43,0x25,0x0d,0x2d,0xa0,0x8a,0x8f,0x15,0x0c,0x02,0x3b,0x94 +,0x88,0x93,0x21,0x25,0x1e,0x36,0x2e,0x15,0xea,0xa0,0x8b,0x90,0x21,0x17,0x06,0x3f,0x9a,0x8d,0x94,0x36,0x2b,0x1d,0x39,0x28,0x16,0xb1,0x9b,0x89,0x94,0x1e,0x11,0x05 +,0xca,0x97,0x8a,0x97,0x2c,0x29,0x1f,0xe2,0x26,0x16,0xc2,0x9d,0x86,0x99,0x28,0x0e,0x06,0xd3,0x98,0x89,0x9e,0x1f,0x21,0x1d,0xec,0x25,0x1e,0xa6,0x9c,0x89,0xb9,0x1e +,0x0c,0x0d,0xaf,0x98,0x8c,0xb6,0x22,0x1f,0x24,0x56,0x1b,0x2d,0xa9,0x9c,0x8c,0x36,0x21,0x08,0x12,0xb1,0x99,0x8d,0x38,0x22,0x1c,0x2d,0x54,0x1c,0xb1,0xa8,0x95,0x98 +,0x2c,0x27,0x09,0x1f,0xc1,0x99,0x93,0x54,0x51,0x24,0x34,0x26,0x2c,0x9a,0x9d,0x8f,0xb4,0x29,0x18,0x11,0xdf,0xb2,0x93,0xa9,0x3d,0x2e,0x29,0x35,0x1b,0xad,0x9b,0x92 +,0xa4,0x1d,0x1f,0x12,0x4a,0xb5,0xa2,0x9d,0x40,0xfe,0x24,0x2b,0x1b,0x31,0x90,0x93,0x93,0x18,0x16,0x1b,0x30,0x9a,0xbd,0xa3,0x2b,0x41,0x3b,0x2c,0x25,0x19,0x9b,0x94 +,0x8f,0x49,0x0d,0x17,0x1d,0x98,0x99,0xa4,0x40,0x1e,0x37,0x2b,0x3c,0x1d,0xb2,0x99,0x91,0xaa,0x0e,0x10,0x14,0x99,0x8d,0x91,0x49,0x0e,0x1b,0x25,0xb8,0x23,0xb4,0x9c +,0x8f,0x96,0x17,0x0f,0x08,0xaf,0x8c,0x87,0x9a,0x14,0x18,0x10,0x4f,0x1f,0xa6,0x92,0x8c,0x8f,0x14,0x10,0x07,0x49,0x90,0x89,0x91,0x24,0x1b,0x0d,0x19,0x14,0xb3,0x92 +,0x89,0x8e,0x20,0x15,0x08,0x54,0xa3,0x90,0x96,0xbb,0xf8,0x10,0x13,0x09,0xaf,0x98,0x87,0x94,0x1b,0x16,0x07,0xb3,0xbf,0x95,0xa6,0xb9,0xad,0x19,0x12,0x06,0xc2,0x99 +,0x88,0x9e,0x26,0x17,0x13,0xaf,0xbd,0x9d,0x36,0xb4,0xe6,0x79,0x12,0x13,0xae,0x9d,0x8a,0x2b,0x36,0x10,0x43,0xa1,0xaf,0x9f,0x20,0xcd,0x23,0x40,0x1a,0xa9,0x95,0x93 +,0x9e,0x0f,0x1e,0x17,0x95,0x98,0x98,0xce,0x25,0x32,0x1d,0x27,0x23,0x8c,0x8f,0x8b,0x1b,0x0e,0x0e,0x2a,0x8d,0x9c,0x95,0x27,0x51,0x16,0x17,0x0d,0xb1,0x89,0x88,0x91 +,0x0c,0x0d,0x0b,0x9d,0x92,0x90,0xaf,0x36,0x27,0x10,0x0f,0x15,0x8d,0x8c,0x84,0x2d,0x0e,0x09,0x16,0x9b,0xad,0x97,0x23,0xd8,0x1d,0x1a,0x0e,0xbc,0x8f,0x8b,0x95,0x17 +,0x1e,0x0e,0xa2,0xc3,0x9c,0x54,0x3e,0x29,0x15,0x0d,0x1b,0x8d,0x8d,0x8a,0x0f,0x12,0x0a,0xa3,0x8d,0x98,0xaa,0x1c,0x43,0x16,0x1b,0x0e,0x96,0x90,0x87,0x3d,0x0f,0x11 +,0x26,0x88,0x92,0x90,0x1e,0x4a,0x1f,0x21,0x10,0xbb,0x8d,0x88,0x91,0x0d,0x0d,0x07,0xaa,0x9f,0x8a,0x9a,0xa7,0x2c,0x11,0x0c,0x1d,0x8c,0x8b,0x87,0x15,0x16,0x08,0xaa +,0x9b,0x9d,0xa3,0x52,0x9e,0x26,0x1c,0x0c,0x97,0x94,0x85,0x33,0x18,0x0d,0x1d,0x99,0xde,0xab,0x18,0xa6,0x2f,0x31,0x0d,0xc7,0x9a,0x89,0x9e,0x0d,0x0e,0x0c,0x94,0x99 +,0x8d,0x34,0x4b,0x1c,0x19,0x0f,0xbe,0x8a,0x8c,0x91,0x0d,0x14,0x0c,0x97,0x9c,0x9a,0x35,0x27,0x30,0x17,0x0d,0x0f,0x8e,0x8b,0x82,0x24,0x14,0x06,0x4c,0x96,0x94,0x98 +,0x44,0xc3,0x0f,0x0d,0x0a,0x96,0x8a,0x80,0xb8,0x18,0x09,0x15,0x9a,0x9e,0x96,0x28,0xae,0x1c,0x1b,0x0d,0xc3,0xa4,0x8e,0xb4,0x22,0x2c,0x47,0x93,0xd1,0xaa,0x22,0x9d +,0xcf,0x27,0x0c,0xc4,0x97,0x87,0x94,0x1d,0x19,0x0e,0x9d,0xb4,0x92,0x30,0xb4,0x1f,0x11,0x04,0x14,0x98,0x88,0x8e,0x17,0x25,0x0b,0x91,0x96,0x8b,0xbc,0xf7,0x25,0x18 +,0x0f,0x19,0x8d,0x8e,0x89,0x1c,0x2e,0x0a,0xdf,0xea,0xa1,0xb5,0x4e,0x53,0x0f,0x08,0x07,0xa9,0x92,0x80,0xb8,0x4a,0x08,0x24,0xcb,0x9c,0x97,0xb8,0x9a,0x7d,0x26,0x0f +,0x9b,0xa2,0x85,0xed,0x41,0x0e,0x28,0x96,0xaf,0xa0,0x16,0x2d,0x22,0x28,0x09,0x2f,0x4f,0x8a,0xa5,0x5a,0x27,0x23,0xa7,0x48,0xa4,0x29,0x9f,0xca,0xba,0x18,0x9c,0x99 +,0x87,0xa3,0x13,0x1c,0x15,0x9c,0xc3,0x96,0x5f,0xa6,0x30,0x21,0x02,0x0f,0x4a,0x92,0x91,0x0d,0x19,0x06,0x97,0x98,0x8b,0x9a,0x96,0xa7,0x20,0x0e,0x0e,0x9e,0x9d,0x8a +,0x2d,0xaf,0x14,0xaa,0xae,0xb3,0xb1,0x3c,0xb6,0x16,0x1b,0x0b,0xa2,0xa9,0x8e,0x1a,0x0c,0x0d,0x1f,0xa3,0xf4,0x98,0xa9,0x8e,0xa9,0x4f,0x17,0xaf,0xa7,0x8d,0xac,0x12 +,0x0d,0x15,0x8a,0x8e,0x88,0xca,0xa9,0x2b,0x1e,0x08,0x11,0xae,0xac,0xa1,0x0d,0x19,0x0e,0xa3,0xa4,0x9a,0xc4,0xbf,0xc2,0x28,0x21,0x21,0x8d,0x88,0x80,0xb9,0x2b,0x0a +,0x1e,0xbb,0xca,0xab,0xa0,0x93,0x1f,0x0d,0x05,0xc4,0xab,0x8d,0x1f,0x0f,0x0c,0x1c,0x90,0xa8,0x91,0xb0,0x91,0xc9,0x1e,0x09,0x26,0xa1,0x8b,0x90,0x41,0x3e,0x1f,0x97 +,0xaf,0xa1,0x2b,0x37,0x19,0x0d,0x0a,0x20,0x91,0x8f,0x8c,0x22,0x20,0x09,0x1d,0x2f,0xba,0xad,0x31,0xad,0x31,0x41,0x25,0x94,0x8e,0x85,0xa9,0x49,0x17,0x1d,0x9a,0xa0 +,0x8f,0xb8,0xac,0x12,0x0b,0x00,0x19,0xce,0x93,0x9d,0x1f,0x21,0x0f,0x96,0x98,0x8d,0xa9,0xb1,0x39,0x17,0x0e,0x27,0x91,0x8b,0x89,0x2c,0x33,0x0c,0x6c,0xd8,0xad,0xaf +,0x31,0x58,0x18,0x1c,0x16,0x96,0x9d,0x8f,0x1b,0x1d,0x0c,0x1d,0x9f,0xb3,0x8d,0xb9,0x95,0x25,0x17,0x0e,0x9c,0x86,0x81,0x99,0x28,0x0f,0x0a,0x59,0x28,0x9f,0x29,0xa1 +,0x36,0x1a,0x06,0x10,0xa6,0x94,0x8c,0x2d,0x26,0x08,0x4d,0xa6,0x8b,0x93,0x9d,0x9d,0x3e,0x1c,0x0c,0xa6,0x95,0x85,0xdc,0x1f,0x0a,0x19,0xd7,0x25,0x3e,0x1c,0xb3,0x47 +,0x1c,0x07,0xb8,0x96,0x86,0x98,0xc7,0x21,0x14,0x95,0xbc,0x92,0x38,0x9f,0xa6,0xc9,0x0f,0x1b,0x8e,0x88,0x8b,0x15,0x0f,0x02,0x27,0x34,0xa4,0xad,0xaa,0xae,0x12,0x07 +,0x03,0xf1,0x95,0x84,0xb0,0x4d,0x0f,0xaf,0x8a,0x8d,0x91,0xbb,0x91,0x41,0x0f,0x00,0x20,0x98,0x85,0x93,0x2e,0x13,0x09,0x1f,0x17,0xa9,0x3d,0xa6,0xb5,0x1a,0x0b,0x17 +,0x96,0x8b,0x8a,0x3e,0x1d,0x0f,0xab,0x9d,0x92,0x94,0x92,0x8d,0x4c,0x0c,0x02,0xc6,0xa4,0x93,0x20,0x0e,0x0e,0x1f,0x9a,0xd0,0xb3,0x2d,0xba,0x40,0x19,0x08,0x4b,0x8c +,0x82,0x90,0x2d,0x23,0x12,0x97,0xa8,0x9c,0xad,0xa1,0x9f,0x1b,0x0b,0x1a,0x96,0x8e,0x8e,0x10,0x0d,0x04,0x19,0xe9,0xa9,0x9c,0xb0,0x8f,0x37,0x13,0x0a,0xa3,0x8b,0x85 +,0xa3,0x1b,0x15,0x23,0x97,0xbf,0x97,0xcb,0x9e,0x2e,0x0d,0x03,0x29,0x8f,0x8c,0x91,0x17,0x17,0x08,0xb7,0x3a,0xad,0x4b,0x38,0xb2,0x19,0x18,0x19,0x8b,0x88,0x85,0xf2 +,0x1c,0x0e,0x67,0x96,0x9e,0x9a,0x76,0x9f,0x13,0x0b,0x01,0x3e,0x90,0x8b,0xb0,0x0b,0x0d,0x11,0x98,0x9f,0x9a,0xba,0x9b,0xba,0x13,0x06,0x29,0x88,0x83,0x85,0x1c,0x1a +,0x11,0xa6,0xa7,0xa6,0xc0,0x2d,0x52,0x0f,0x07,0x10,0x9a,0x95,0x8b,0x18,0x15,0x0c,0xd6,0x91,0x9f,0x93,0xb2,0x98,0x37,0x11,0x0a,0x9d,0x89,0x85,0xdd,0x0e,0x0f,0x1c +,0x91,0xa7,0x9b,0x37,0x50,0x1f,0x0b,0x05,0x27,0x91,0x88,0x93,0x0f,0x12,0x0e,0x9c,0x9a,0x95,0xa2,0xae,0xa2,0x1c,0x0f,0x23,0x8f,0x88,0x89,0x17,0x0c,0x0a,0x25,0xa5 +,0xde,0xb8,0x49,0x9e,0x2e,0x0b,0x08,0xac,0x8a,0x86,0xcf,0x0b,0x0f,0x2e,0x8f,0xa4,0x9f,0xab,0xa5,0xb2,0x17,0x0c,0x9f,0x8a,0x86,0x9d,0x0c,0x15,0x0f,0xdb,0x52,0x37 +,0xac,0xcc,0x1f,0x0c,0x03,0xb8,0x8c,0x85,0x8c,0x14,0x2a,0x1c,0xa5,0x98,0xbd,0x9b,0x9b,0xb3,0x24,0x02,0x22,0x90,0x8b,0x8a,0x0d,0x0c,0x0a,0x2f,0x9c,0x4a,0xc4,0xd0 +,0x4e,0x2e,0x08,0x0f,0x97,0x8f,0x84,0xae,0x22,0x28,0x3c,0x9c,0xaa,0xa2,0x9b,0xa9,0x2f,0x0a,0x0c,0x9f,0x94,0x8e,0x51,0x0d,0x18,0x24,0xb3,0xba,0x23,0x6a,0xae,0x51 +,0x15,0x0a,0xae,0x8a,0x87,0xa0,0x14,0x17,0xcf,0x9a,0x98,0xc2,0xa7,0x95,0xa7,0x1b,0x03,0x29,0x95,0x8f,0xba,0x0d,0x0b,0x29,0xe0,0x57,0x3c,0x76,0x96,0xb7,0x1c,0x06 +,0x35,0x89,0x88,0x90,0x29,0x1e,0xba,0xaa,0xbf,0xe5,0x3c,0x91,0xa4,0x25,0x07,0x12,0x98,0x92,0x9d,0x1b,0x0f,0x21,0x2e,0x2a,0x3b,0x2e,0x95,0x9d,0xd3,0x11,0x1c,0x8e +,0x8b,0x8f,0x3f,0x18,0x5e,0xa5,0xe8,0x4a,0x26,0x9e,0xad,0x26,0x08,0x0c,0x98,0x91,0x98,0x27,0x0e,0x28,0xae,0x58,0x37,0x1c,0xa0,0x95,0xa8,0x17,0x09,0xa1,0x8b,0x89 +,0x9f,0x1a,0x28,0xa6,0xac,0xaf,0x1f,0xc1,0x9c,0xc1,0x14,0x02,0x21,0x9c,0x8f,0xaa,0x13,0x18,0xb6,0xb6,0x79,0x1d,0xd6,0x8f,0x96,0x2a,0x06,0x43,0x8c,0x88,0x96,0x1a +,0x1c,0xaa,0xa4,0x32,0x16,0x1f,0x99,0x8f,0x39,0x02,0x0c,0xa9,0x90,0x99,0x17,0x0e,0x51,0x9b,0xac,0x38,0x50,0x9b,0x8d,0xa4,0x0a,0x0c,0x9e,0x8c,0x8e,0xda,0x19,0xcf +,0x95,0xbc,0x19,0x16,0x44,0x97,0xae,0x09,0x05,0x48,0x8e,0x92,0xc9,0x14,0x1b,0x9e,0xb7,0x2b,0x25,0xac,0x8a,0x8c,0x26,0x09,0x49,0x8a,0x8d,0xc8,0x14,0x0e,0xa3,0xa1 +,0x27,0x19,0x23,0x9d,0x94,0x2c,0x02,0x0c,0xa1,0x90,0x9e,0xd6,0x17,0x9e,0x8c,0xb8,0x1d,0x19,0xaa,0x91,0x9c,0x0e,0x0c,0x99,0x8a,0x93,0xa9,0x18,0x33,0x99,0x3e,0x0d +,0x0b,0x3b,0x96,0x99,0x10,0x01,0x62,0x8a,0x95,0xbd,0x13,0x1c,0x8e,0x8c,0x4e,0x17,0xba,0x91,0x89,0xbc,0x02,0x10,0x99,0x97,0xaf,0x32,0x1c,0xaf,0x93,0x23,0x07,0x1f +,0xa3,0x9a,0xda,0x04,0x09,0x97,0x85,0x93,0xaa,0xd9,0x4f,0x97,0xbb,0x0a,0x1c,0x92,0x8a,0x91,0x16,0x05,0x37,0x8a,0x9a,0x22,0x24,0x1a,0xbc,0xa7,0x11,0x0c,0xb7,0x8d +,0x95,0x2c,0x04,0x0b,0x9a,0x8c,0xaa,0xbf,0xc1,0xa0,0x8d,0xa9,0x1c,0x2f,0x92,0x99,0x2b,0x09,0x0b,0x9d,0x8a,0x9e,0x1d,0x16,0x2e,0xa0,0x3f,0x0d,0x0d,0xb2,0x8f,0xa6 +,0x14,0x0c,0x98,0x83,0x8d,0x32,0x12,0x2a,0x93,0x94,0x2a,0x0e,0xc8,0x8c,0x98,0x1e,0x03,0x14,0x99,0x8e,0xdf,0x18,0x1c,0xce,0xa0,0xd0,0x15,0x20,0x98,0x9e,0x36,0x0b +,0x19,0x97,0x88,0x8f,0xe7,0xc9,0xa7,0x9c,0xc5,0x0d,0x0b,0x65,0x92,0x9d,0x13,0x0b,0x2e,0x91,0x90,0x31,0x19,0x1e,0xb7,0xa4,0x28,0x0e,0x2e,0x8e,0x89,0xcc,0x0b,0x15 +,0xa1,0x89,0x9a,0x3e,0x27,0xad,0x92,0xa2,0x27,0x15,0xdb,0x9f,0x31,0x09,0x09,0x49,0x91,0x99,0x48,0x2b,0xfb,0xa7,0x3d,0x15,0x13,0xb3,0x8b,0x96,0x1d,0x0c,0xc6,0x86 +,0x85,0x9c,0x25,0x23,0x49,0x42,0x28,0x12,0x28,0x95,0x92,0x2a,0x05,0x07,0x41,0x8d,0x98,0x2f,0x1e,0x46,0xa9,0x9d,0xc5,0x2e,0xaa,0x97,0x9e,0x16,0x0b,0x2a,0x93,0x8a +,0x9b,0xd9,0x48,0x42,0x45,0x23,0x19,0x26,0xaa,0x9e,0x1a,0x07,0x14,0x96,0x87,0x9b,0x19,0x16,0x3b,0xa6,0xa8,0x2f,0x2c,0xa7,0x8c,0x9c,0x15,0x0b,0x3e,0x8b,0x8c,0xe8 +,0x16,0x1c,0xdf,0xa3,0xb5,0x2b,0x26,0xac,0xaf,0x15,0x06,0x11,0x9c,0x87,0x8f,0xb8,0x39,0x32,0x5d,0xc3,0xce,0x4f,0xa6,0xa9,0x23,0x0d,0x1b,0x96,0x87,0x96,0x2b,0x19 +,0x21,0x3d,0x3d,0x23,0x18,0x5b,0x98,0x9d,0x1a,0x0a,0x1f,0x94,0x89,0x9a,0x3b,0x26,0xc9,0x99,0x9c,0xc8,0xd1,0xa3,0xb6,0x17,0x06,0x0f,0xae,0x8d,0x90,0xba,0x1f,0x18 +,0x3f,0xbd,0x3a,0x21,0x48,0xd3,0x1d,0x0e,0x17,0x96,0x84,0x8a,0xb5,0x22,0x27,0xbf,0xaf,0x34,0x21,0xaf,0x8f,0x9d,0x17,0x07,0x1b,0x8f,0x85,0x9b,0x1c,0x0f,0x29,0xaf +,0xcd,0x20,0x2e,0xa4,0xb9,0x18,0x08,0x13,0xa6,0x8d,0x91,0xb3,0xd7,0xb3,0xab,0xbc,0x2a,0x26,0xa9,0xac,0x1a,0x0d,0x25,0x90,0x8a,0x96,0x4c,0x3c,0xb4,0xc6,0x1f,0x11 +,0x1e,0x9e,0x93,0x2e,0x07,0x0a,0xa6,0x87,0x8b,0x3d,0x12,0x19,0x3d,0xaf,0xbf,0xae,0x9b,0x9c,0x2e,0x0d,0x13,0xbe,0x93,0x98,0xd0,0x4b,0xbe,0xb3,0x36,0x1f,0x3f,0x9a +,0x99,0x20,0x08,0x0d,0xa9,0x8a,0x8f,0xbd,0x27,0x3c,0x3b,0x23,0x13,0x3a,0x8e,0x8c,0xaa,0x20,0x11,0xe6,0x91,0x9e,0x46,0x0f,0x1b,0x40,0xb2,0x18,0x03,0x1a,0x8c,0x8c +,0x5c,0x1f,0x29,0x92,0x85,0x92,0x9c,0x9c,0x9e,0x39,0x0e,0x1f,0xa1,0x85,0x2a,0x02,0x00,0x1e,0x81,0x89,0x94,0xbe,0xad,0x9f,0xd6,0x0c,0x0a,0x2a,0x96,0x9a,0x1b,0x0c +,0x13,0x9f,0x9c,0x1d,0x35,0x90,0x9a,0x48,0x35,0xcc,0x96,0x83,0x88,0xc4,0x11,0x0b,0x29,0x9f,0xad,0x1f,0x25,0xf0,0x1b,0x0c,0x0b,0x1d,0x9b,0x84,0xad,0x06,0x03,0x31 +,0x84,0x82,0x9e,0xbb,0x90,0x91,0xaf,0x0d,0x04,0x15,0x98,0x8c,0xaf,0x16,0x17,0xa2,0x8c,0x46,0x1a,0x47,0xb5,0x5d,0x18,0x0e,0x2a,0x8b,0x84,0x31,0x03,0x00,0x0b,0x86 +,0x81,0x95,0xa2,0x94,0x99,0xd4,0x0f,0x12,0x8e,0x81,0x9e,0x08,0x05,0x0a,0xae,0x90,0x1d,0x0b,0xa1,0x8f,0x9d,0x31,0x07,0x1b,0x8d,0x89,0xb0,0x28,0x0b,0x0a,0x98,0x86 +,0x8a,0x9f,0x13,0x05,0x0e,0xd0,0x9b,0x8c,0x87,0x8c,0xa5,0x19,0x07,0x0d,0x2b,0x9b,0x9a,0xba,0xaa,0xc9,0x18,0x06,0x02,0x0e,0xa9,0x94,0xd8,0x23,0xad,0x9a,0x8e,0x84 +,0x87,0x9f,0x29,0x18,0x25,0xb6,0xd6,0xae,0xa1,0x38,0x0d,0x06,0x12,0xf1,0x44,0xa4,0x8e,0xa0,0x2f,0x2a,0xbc,0x9e,0x47,0x17,0x2b,0x6c,0x37,0x64,0x44,0x20,0x13,0x25 +,0x8b,0x88,0x9f,0xfb,0xcd,0x9d,0x9c,0x1e,0x14,0x23,0xae,0x94,0x9e,0x28,0x12,0x08,0x0a,0xb9,0xa4,0x9d,0xa9,0x5e,0xb5,0xde,0x18,0x2c,0xa7,0x88,0x85,0xbe,0x0d,0x05 +,0x0c,0x9e,0x80,0x8c,0xbe,0x0b,0x1c,0xb2,0x1e,0x17,0xbd,0x95,0x8d,0xcc,0x19,0x19,0x0c,0x0d,0xc7,0x87,0x95,0x7c,0x08,0x05,0x0e,0xae,0x88,0x85,0x88,0x8f,0x2c,0x15 +,0x18,0x2e,0xbe,0x93,0x84,0x99,0xcf,0x07,0x10,0x18,0x14,0x0c,0x13,0xc4,0x8f,0x9f,0xaa,0x3f,0x29,0x19,0xb2,0x8b,0xaf,0xb8,0x24,0x95,0xa4,0x45,0x23,0x2a,0x39,0xb2 +,0xc4,0xa0,0x30,0x1f,0x0e,0xac,0x87,0x8d,0x96,0x0e,0x13,0x0c,0x15,0x21,0xc3,0x94,0x99,0x0d,0x0b,0x0a,0x25,0x2e,0x8b,0x80,0x83,0x9b,0x0b,0x19,0x1e,0xbe,0x93,0x89 +,0x8b,0x9c,0x10,0x0c,0x00,0x05,0x08,0x8c,0x82,0x8b,0x33,0x07,0x15,0x1b,0x4d,0xb4,0xa5,0xa6,0xac,0x1a,0xd3,0x3a,0x98,0x23,0x8f,0x8f,0xa2,0x2e,0x0f,0x9b,0x9f,0xaa +,0x63,0xbe,0x9f,0xef,0x09,0x15,0x0a,0x25,0x09,0x95,0x91,0xab,0x4b,0x11,0xaf,0x2e,0xce,0xab,0x9f,0x8f,0x8d,0xa7,0x9f,0x13,0x23,0x09,0x93,0x87,0x8d,0x4a,0x02,0x0a +,0x08,0x26,0xa1,0x8d,0x89,0x9e,0x16,0x1a,0x08,0x1c,0x0e,0x8a,0x88,0x90,0x3b,0x0a,0x2c,0x0e,0x19,0xc5,0x93,0x89,0x93,0x3b,0x37,0x13,0xae,0x22,0x89,0x89,0xa0,0x1e +,0x03,0x17,0x18,0x2e,0x52,0x27,0xbe,0xb0,0x21,0xbd,0x18,0x32,0x10,0x8e,0x89,0x90,0xa7,0x1f,0x9b,0x4a,0x5d,0xaf,0xc2,0xc5,0x3b,0x13,0x35,0x12,0x75,0x1f,0x8b,0x8b +,0xb1,0x20,0x07,0x2e,0x18,0x2c,0xb5,0x98,0x89,0x94,0x16,0x16,0x03,0x0f,0x09,0x93,0x81,0x85,0x93,0x0f,0x3e,0x16,0x23,0xad,0x9d,0x98,0xa2,0x17,0x3b,0x0c,0x1c,0x06 +,0xa9,0x87,0x9a,0x9f,0x0a,0x32,0x23,0xae,0x9f,0xb3,0x9e,0xa0,0x16,0x27,0x0e,0x54,0x1d,0x97,0x87,0xce,0xdd,0x07,0x9c,0x9b,0x98,0x9a,0x5a,0xa6,0xb5,0x1b,0x38,0x0a +,0x19,0x0b,0xaf,0x82,0xa7,0xad,0x02,0x14,0x11,0x27,0x97,0x96,0x88,0x89,0xb8,0xae,0x14,0x27,0x0b,0x22,0x83,0x94,0x8b,0x0d,0x19,0x0f,0x0a,0x29,0x3a,0x92,0x91,0x2f +,0x35,0x0e,0x24,0x1b,0xaf,0x80,0x92,0x99,0x05,0x0d,0x14,0x30,0x92,0xad,0x9d,0x9c,0x4c,0xac,0x13,0x23,0x18,0x3c,0x80,0x99,0x91,0x0a,0x1b,0xb4,0x2e,0xa1,0x25,0x4e +,0x66,0x0f,0x24,0x10,0x41,0x3a,0x25,0x80,0x9f,0x95,0x12,0x1d,0xb2,0x1d,0x97,0xaf,0x9b,0x93,0x26,0x33,0x16,0x1a,0x1b,0x0d,0x84,0x8f,0x89,0x1d,0x0b,0x3b,0x14,0xa3 +,0x2b,0xc0,0x9e,0x27,0x36,0x0e,0x0b,0x10,0x0a,0x83,0x87,0x82,0xd8,0x10,0xac,0x12,0x9c,0xab,0x9e,0x8e,0x4a,0x47,0x16,0x0b,0x29,0x04,0x90,0xb0,0xba,0xca,0x0e,0x8f +,0x2d,0x95,0xa0,0xbf,0x99,0x2d,0x1f,0x18,0x13,0xaa,0x11,0x8b,0x8a,0xa3,0x2e,0x00,0x4a,0x24,0x8f,0x96,0xa6,0x8f,0xa9,0xb9,0x2c,0x0a,0x22,0x06,0x9d,0x89,0xa7,0xad +,0x00,0x21,0x0d,0xb8,0x9a,0xaf,0x8e,0xa6,0xbe,0x46,0x19,0x9d,0x17,0xa3,0x85,0x98,0x8f,0x05,0x29,0x12,0x27,0xb3,0x2c,0x9a,0xaf,0x69,0xbe,0x15,0x37,0x0c,0x3a,0x83 +,0xb0,0xa2,0x02,0x2d,0x39,0xb1,0x96,0x74,0x97,0xab,0x45,0x2d,0x15,0xcf,0x4f,0xae,0x80,0x9d,0x95,0x06,0x12,0x15,0x1a,0x9f,0x37,0x9c,0x47,0x1b,0x19,0x16,0xde,0x2c +,0x1a,0x85,0x9f,0x8d,0x1b,0x25,0xa8,0x34,0x8f,0x4a,0x9d,0xa1,0x43,0x26,0x0c,0x14,0x1c,0x20,0x80,0x90,0x91,0x10,0x10,0xcc,0x1d,0xa2,0x29,0xb8,0x9c,0xe5,0x38,0x10 +,0x0d,0x17,0x07,0x86,0x93,0x8c,0x41,0x1a,0x94,0x2d,0x8b,0x9d,0x99,0x99,0x36,0x20,0x14,0x11,0x2f,0x08,0x90,0x98,0xb4,0x1f,0x03,0xbd,0x17,0x99,0xba,0xaf,0x94,0xa2 +,0xa7,0x2a,0x10,0x2f,0x19,0x8c,0x87,0x9e,0x2d,0x01,0x7b,0x25,0x8e,0x95,0xa8,0x95,0x6e,0x49,0x19,0x0a,0x23,0x0d,0x97,0x87,0xa0,0xab,0x02,0x29,0x09,0x3e,0x9e,0xaa +,0x8e,0xa3,0xa9,0xbd,0x28,0xaa,0x18,0xb6,0x85,0xac,0x9a,0x05,0x2f,0x22,0x43,0x9e,0x2c,0xa2,0x54,0x25,0x1c,0x0e,0x4e,0x2a,0xab,0x81,0xa5,0x9d,0x03,0x19,0x23,0x30 +,0x9c,0x3e,0x9d,0xa2,0xcf,0x3d,0x22,0xf5,0x3a,0x39,0x80,0x96,0x8b,0x0f,0x11,0x1e,0x1d,0x96,0xcc,0x9e,0x58,0x11,0x0c,0x08,0x16,0x2d,0x20,0x80,0x93,0x88,0x1c,0x17 +,0xb2,0x1f,0x90,0xae,0x90,0x94,0xe5,0x2a,0x0f,0x0d,0x18,0x0a,0x85,0x96,0x99,0x14,0x0a,0xad,0x2b,0x8d,0xa4,0x9d,0xa6,0x3b,0x15,0x0b,0x0b,0x27,0x0f,0x87,0x89,0x8d +,0x2b,0x05,0x55,0x16,0x8d,0x8f,0x8d,0x90,0xc0,0x1b,0x1b,0x19,0xcc,0x0b,0x95,0x90,0xde,0x2d,0x01,0x3c,0x13,0x98,0x97,0x95,0x94,0xed,0x2a,0x14,0x0d,0x34,0x19,0x8c +,0x83,0x90,0xb2,0x00,0x1e,0x0c,0xac,0x91,0x98,0x8c,0x9f,0x37,0x1d,0x0d,0x3c,0x0d,0xaa,0x83,0xc4,0x47,0x00,0x15,0x11,0xad,0x8c,0x97,0x8d,0xb6,0x19,0x17,0x1a,0x9a +,0xb5,0x96,0x80,0x9e,0x9f,0x03,0x19,0x11,0x1e,0xa0,0xf2,0x9b,0xc6,0x1f,0x14,0x0e,0x40,0x24,0xc6,0x80,0x9c,0x9b,0x03,0x1d,0xdb,0x4a,0x91,0xa6,0x8c,0xae,0x11,0x0c +,0x0a,0x2e,0x20,0xca,0x80,0x8d,0x8a,0x08,0x19,0x27,0x16,0x9b,0xaf,0x95,0xb3,0x0e,0x0f,0x0d,0x24,0x18,0x0f,0x82,0x9c,0x92,0x0a,0x18,0x9e,0xb2,0x8c,0x98,0x88,0x8d +,0x1c,0x0c,0x0d,0x1a,0x2d,0x19,0x80,0x92,0x95,0x0b,0x0a,0x29,0x16,0xa5,0x9f,0x90,0xa0,0x1b,0x14,0x22,0x22,0x49,0x0f,0x84,0x95,0xa0,0x0e,0x0b,0xb0,0x30,0x8e,0x8c +,0x83,0x8c,0x23,0x0a,0x15,0x1c,0x29,0x07,0x8a,0x8e,0xa1,0x16,0x04,0x2b,0x09,0x31,0xa4,0x89,0x88,0xb5,0x1c,0x28,0x29,0xb9,0x14,0x88,0x8a,0xa6,0x18,0x02,0x35,0x12 +,0xc4,0x92,0x89,0x89,0x4a,0x0e,0x19,0x15,0x3d,0x13,0x8b,0x87,0x9b,0x27,0x04,0x50,0x0e,0x11,0x2f,0xa8,0x94,0x58,0x18,0x3c,0x26,0x9f,0x21,0x8b,0x87,0xa1,0x38,0x0b +,0x9e,0x1e,0x24,0xa0,0x8e,0x8a,0x62,0x08,0x13,0x0b,0x1b,0x06,0x99,0x84,0xa8,0xd6,0x07,0xb8,0x18,0x0f,0xd7,0x93,0x8a,0xa9,0x12,0xcc,0x1f,0xb1,0x1b,0x96,0x81,0xa5 +,0xaf,0x07,0x3d,0x19,0x11,0xa4,0x8b,0x8c,0xa2,0x09,0x17,0x08,0x0e,0x08,0xcb,0x80,0xd4,0xc7,0x0e,0x97,0xbd,0x13,0xc6,0x8c,0x88,0x94,0x19,0xdd,0x1d,0x19,0x10,0x6d +,0x80,0xb4,0xbd,0x08,0x22,0x12,0x0b,0x9b,0x87,0x8e,0xad,0x0f,0x2c,0x0e,0x0b,0x17,0xa2,0x80,0x26,0x0e,0x06,0xa3,0x94,0x2b,0xa7,0x8d,0x96,0x9f,0x1b,0x9a,0xb0,0x1c +,0x0f,0x12,0x85,0xc9,0xa2,0x2d,0x41,0x18,0x00,0x15,0x9e,0x94,0x8e,0x9c,0x97,0x19,0x00,0x07,0xcf,0x80,0x8e,0x9c,0x15,0x11,0x0c,0x05,0xac,0x81,0x90,0xab,0x10,0x19 +,0x4c,0x1e,0x70,0xa2,0x80,0x2c,0x08,0x0a,0xce,0x9e,0x19,0x1d,0x34,0x0c,0x1f,0x96,0x85,0x8c,0x1a,0x0f,0x0e,0x84,0x9f,0x9f,0x8e,0x96,0x28,0x00,0x0b,0x90,0x88,0x8d +,0x95,0xb5,0x18,0x00,0x05,0x1d,0x80,0x8e,0x5d,0x0c,0x02,0x09,0x10,0x8f,0x81,0x8f,0xb4,0x22,0x1f,0x32,0x10,0x97,0x92,0x80,0x55,0x0b,0xab,0x99,0x9a,0x22,0xe2,0x98 +,0x17,0x0e,0xb1,0x8c,0x92,0x04,0x04,0x00,0x9e,0x8e,0x9e,0x8c,0xbb,0x25,0x01,0x0f,0x93,0x8a,0x86,0x83,0x9e,0x1d,0x00,0x17,0xb1,0x83,0x89,0xeb,0x3e,0x06,0x06,0x0a +,0xa0,0x80,0xa9,0x0b,0x1e,0x27,0xa6,0x16,0x2b,0x3b,0x98,0xa7,0x07,0xcd,0xab,0x8e,0xc2,0x1d,0x69,0x2d,0xa4,0x80,0x86,0x8d,0x16,0x0a,0x05,0x28,0x8d,0xa7,0x84,0x21 +,0x02,0x00,0x0a,0x8e,0x8f,0xa5,0x8d,0x5e,0x16,0x03,0x0a,0xa9,0x86,0x82,0x2a,0x28,0x1f,0xce,0xa0,0x9f,0x8b,0x9e,0x0f,0x31,0x36,0xa6,0x99,0x51,0x0c,0x06,0x4c,0x23 +,0x92,0x9f,0x41,0x1f,0x09,0x0e,0x0f,0x28,0x84,0x80,0x9e,0x0a,0x05,0x2d,0x95,0x80,0x91,0x86,0x99,0x0c,0x04,0x0f,0x94,0x85,0x44,0x1f,0x13,0x0d,0x2a,0x1c,0x2c,0x5a +,0x8a,0x17,0x0d,0x2a,0x61,0x92,0x99,0xc3,0x1e,0x13,0x91,0x84,0x9c,0xa0,0x3e,0x1e,0x0c,0xad,0x55,0x95,0x80,0xe1,0x06,0x02,0x1d,0x94,0xd2,0x97,0x94,0x1b,0x10,0x04 +,0x0b,0x1e,0x82,0x98,0x4b,0x46,0x18,0x57,0x97,0x8c,0x8d,0xc3,0xa3,0x9c,0x0f,0x43,0xad,0xaa,0x10,0x5d,0x0f,0x19,0x8b,0xc4,0x24,0x1c,0x1c,0x17,0x0b,0x2d,0x88,0x91 +,0x95,0x27,0x0b,0x10,0x88,0x8d,0xa0,0x88,0xab,0x16,0x0e,0x1c,0xbe,0x99,0x8e,0x94,0x0d,0x0b,0x17,0x39,0x1b,0x8d,0xa6,0x16,0xae,0x0d,0x09,0x49,0x96,0x9c,0x27,0x22 +,0x8d,0xab,0x92,0xa0,0x6b,0x2d,0x94,0xb1,0x0f,0x8e,0x8e,0x36,0x13,0x0f,0x0d,0x3e,0xa2,0x8a,0x31,0x2e,0x29,0x0c,0x04,0xae,0x8c,0xbf,0x87,0xcf,0x07,0x1b,0x9d,0x9d +,0xb0,0xc8,0x8b,0x5b,0x2d,0x20,0x1d,0xbb,0x89,0x98,0x09,0x9e,0xa1,0x13,0x2c,0xb6,0x21,0x25,0x1b,0x46,0x15,0xad,0x9f,0x1d,0x0f,0xa0,0x8a,0x20,0x88,0x92,0x18,0xb0 +,0x97,0x18,0x23,0xa2,0x8a,0xc6,0x2f,0x24,0x0c,0x13,0xa0,0x95,0x0b,0x99,0xa9,0x09,0x10,0x4c,0x2e,0xb8,0x9e,0x9b,0xab,0x9c,0xa6,0x1e,0x1a,0xa9,0x8b,0x1b,0x95,0x9e +,0x0d,0xb3,0x9b,0x12,0x35,0xa7,0xaa,0xaa,0x41,0x1f,0x0d,0x17,0x38,0xbc,0x13,0x96,0x95,0x0e,0x3a,0x98,0x37,0x9b,0x98,0xde,0xa3,0x9c,0xb5,0x15,0x1e,0xab,0x95,0x27 +,0xa9,0x9b,0x0f,0x2a,0xa8,0x0e,0x26,0xaf,0x28,0xac,0xcf,0x24,0x18,0x27,0xc6,0x8f,0xab,0x9a,0x8e,0x12,0x17,0xa3,0x25,0xc1,0x9a,0x42,0x96,0xa8,0x34,0x36,0x48,0x48 +,0xa4,0x2e,0x17,0xa9,0x1e,0x14,0x58,0x19,0x19,0xb2,0x28,0x9b,0x8c,0xa2,0xa1,0x53,0x20,0xd0,0x9e,0xad,0x99,0xa8,0x15,0x2e,0x28,0x12,0x99,0x97,0x9f,0xa1,0x0d,0x11 +,0x24,0x27,0xbd,0xa9,0x58,0x2a,0x3e,0x10,0x2f,0x8d,0xad,0x9f,0x9c,0x25,0xb0,0xb0,0xa7,0x9f,0x45,0xbf,0x59,0x3e,0x29,0xb6,0xa7,0x21,0x23,0x13,0x10,0xae,0x9d,0xbd +,0x5e,0x60,0x25,0x18,0x3d,0x9c,0x8c,0x8e,0xa4,0x19,0x14,0x29,0x24,0xad,0x99,0x91,0x9b,0x13,0x12,0x6b,0xa9,0x96,0xa6,0x2c,0x1d,0x1b,0x1c,0x25,0x37,0x42,0xc5,0x49 +,0x2c,0x4a,0xae,0x9a,0x94,0xb9,0x2f,0x2e,0xaa,0x98,0xb7,0xb1,0xb5,0x26,0x19,0x23,0xae,0x95,0x9a,0x3e,0x0f,0x0f,0x1a,0x4d,0xbe,0xa9,0x9b,0x31,0x19,0x17,0x2e,0xa0 +,0x9a,0x9c,0x9f,0xbb,0x36,0x23,0xcb,0x9f,0x93,0x9b,0x2f,0x2a,0x1f,0xc6,0xc5,0x2c,0x1c,0x16,0x25,0x5f,0xc5,0x4d,0xfb,0xaa,0x6d,0x28,0x38,0xa8,0x8e,0x98,0xbb,0x16 +,0x19,0x29,0x3c,0x9e,0x99,0x90,0xa3,0x29,0x1d,0x30,0x9b,0x94,0xb2,0x25,0x14,0x15,0x14,0x1b,0x28,0x42,0xb0,0x3b,0x30,0xf6,0xa2,0x9a,0x9d,0xa1,0xb5,0x4c,0xcd,0xae +,0xac,0xa2,0xba,0x23,0x1a,0x33,0xa6,0x9e,0xa8,0x3a,0x18,0x16,0x1d,0x41,0xce,0xb5,0xab,0x32,0x15,0x13,0x39,0x9e,0x94,0x9b,0xdc,0xd7,0x59,0x2e,0xb9,0x9a,0x8d,0x99 +,0x2f,0x1b,0x36,0x9e,0xac,0x42,0x1c,0x17,0x21,0x1f,0x36,0xbc,0xb6,0xd5,0x1c,0x1a,0x21,0xac,0x93,0x94,0x9f,0x20,0x19,0x1f,0xbe,0x97,0x91,0x90,0xac,0x27,0x1d,0x34 +,0x99,0x98,0xb6,0x1f,0x15,0x18,0x12,0x1c,0xdd,0xab,0x63,0x25,0x1f,0xe8,0x9b,0x9b,0xa0,0xa7,0xb8,0x39,0x20,0x41,0x98,0x93,0xbb,0x1b,0x16,0x32,0x9e,0x9a,0xa5,0x6e +,0x30,0x20,0x1b,0x25,0x4a,0xa9,0xb4,0x2a,0x16,0x0f,0x2c,0xa1,0x97,0x9f,0xbe,0xbc,0x56,0x58,0xae,0x98,0x8f,0xa6,0x2a,0x1d,0x79,0x9d,0xdf,0x1e,0x1a,0x25,0x1d,0x21 +,0xd2,0xa4,0x9d,0xed,0x22,0x24,0x36,0xac,0xa7,0xac,0xbb,0x1e,0x19,0x19,0x55,0x9a,0x92,0x95,0xb5,0xcf,0xdc,0xad,0x9a,0x9e,0xc8,0x1f,0x19,0x1a,0x18,0x20,0x3c,0xbf +,0x32,0x1b,0x2a,0xb1,0x9b,0xa5,0xb6,0xac,0x3f,0x1a,0x24,0xb2,0x90,0x94,0xe5,0x1f,0x2d,0x9f,0x96,0x9a,0xa1,0xdb,0x1c,0x11,0x18,0x2a,0xda,0xab,0x63,0x1f,0x13,0x1d +,0x57,0xa3,0x9b,0xc0,0x55,0x3a,0x3f,0xe7,0xaa,0x97,0x9b,0xfc,0x2b,0xf5,0x9a,0x9e,0xce,0x33,0x23,0x21,0x1c,0x2b,0xd1,0x9e,0xb5,0x21,0x22,0x2b,0x3f,0xba,0xae,0xae +,0x31,0x1e,0x23,0x32,0xa6,0x9d,0x9a,0x9e,0xd2,0x36,0xb5,0x95,0x9c,0xdd,0x2b,0x1c,0x1b,0x18,0x23,0xce,0xc9,0x66,0x25,0x22,0xdd,0xa7,0xa2,0xac,0xba,0x73,0x2a,0x27 +,0x38,0x9e,0x9e,0x66,0x3a,0x32,0xab,0x9f,0x9d,0xa1,0xda,0x46,0x24,0x1e,0x3f,0xcd,0xba,0x2d,0x1e,0x1c,0x17,0x4f,0xab,0xa8,0xe3,0x32,0x41,0x49,0xe7,0xa8,0x94,0x9a +,0xd8,0xd0,0xc3,0xcf,0xad,0xad,0xbe,0x29,0x24,0x24,0x1f,0x46,0xae,0xc3,0x3f,0x34,0x53,0x4e,0xcb,0xb8,0x2a,0x1e,0x20,0x2b,0x3f,0xa8,0x9e,0xa5,0xa9,0xbb,0xbc,0xa8 +,0x97,0x95,0xc3,0x32,0x34,0x1c,0x1e,0x29,0x2a,0x56,0xad,0xcf,0x2f,0x3e,0xe8,0xeb,0x3f,0x3e,0x35,0x1d,0x2e,0xaa,0xd3,0x3a,0xcd,0xa9,0xaa,0xa6,0xa2,0xa6,0x9f,0xaf +,0x4a,0x21,0x2b,0xda,0xca,0xb3,0xa9,0x45,0x18,0x12,0x1f,0x77,0x9d,0x9e,0x2f,0x1d,0x17,0x29,0xa6,0x8f,0x8d,0xad,0x21,0x2f,0xbe,0xaa,0xa7,0xc0,0x3b,0x20,0x1d,0x2a +,0x9e,0x95,0xa5,0x26,0x17,0x29,0xbf,0x9f,0x9e,0xdb,0x16,0x0b,0x11,0xdc,0x9c,0x92,0x9c,0x3f,0x17,0x1d,0x9e,0x8e,0x93,0xb7,0x25,0x26,0x35,0xce,0xaf,0xab,0xb0,0x1a +,0x13,0x21,0xa6,0x9a,0xeb,0x34,0x20,0x2b,0x4a,0xae,0x9a,0x98,0xbf,0x13,0x0d,0x3c,0xa0,0x9d,0xb7,0xed,0xd3,0x35,0xed,0xb0,0x98,0xa4,0x2e,0x24,0x30,0x45,0x26,0x1d +,0x3a,0xe9,0x51,0xbd,0xbf,0xca,0x3e,0x3e,0xcc,0xa6,0x9d,0xd4,0x25,0x1e,0x41,0xaf,0x9e,0xae,0xbd,0x1e,0x29,0x2f,0xa5,0x8b,0x31,0x9b,0x0d,0x1c,0xaa,0xdd,0x86,0xb0 +,0x46,0x03,0x0b,0x1e,0x9e,0x8c,0xa1,0xc2,0x0a,0x19,0x4f,0x8c,0x89,0x95,0x19,0x06,0x13,0x25,0x91,0x9d,0xa8,0x18,0x0f,0x4b,0xa5,0x89,0x8f,0x99,0x17,0x0c,0x15,0xc8 +,0x91,0x9e,0x43,0x1c,0x12,0x17,0xaa,0x8f,0x8d,0x3f,0x11,0x0d,0x45,0x97,0x96,0xbe,0x20,0x1e,0x26,0xa5,0x9c,0xb3,0x2c,0x19,0x26,0xda,0xb8,0xa8,0x2d,0xc0,0xbb,0xb8 +,0x95,0x9b,0xa6,0x24,0x18,0x29,0x29,0x2f,0x1b,0x34,0x36,0xad,0xbf,0xaa,0x9e,0x99,0xa1,0x19,0x26,0x29,0x97,0xad,0x2f,0x13,0x1b,0x1b,0xb2,0x8d,0x95,0x9e,0x18,0x10 +,0x23,0x99,0x90,0x9a,0x2d,0x0f,0x1f,0xc2,0x99,0x8a,0xc3,0x24,0x0e,0x2d,0x9c,0x9c,0xc0,0xc8,0x1a,0x00,0x0e,0x13,0x8e,0xbf,0xbe,0x1c,0x03,0x9e,0xac,0x93,0x8b,0x8c +,0xa4,0x97,0x8e,0x98,0x8a,0x83,0x1c,0x0f,0x18,0x0d,0x88,0x8b,0xad,0x50,0xa4,0xe2,0x5c,0x3d,0x1c,0x06,0x01,0x06,0x0a,0x0a,0x06,0x07,0x02,0x16,0x12,0x3b,0xb5,0xbc +,0x1c,0xba,0xae,0x23,0x95,0xfb,0x92,0x93,0xa0,0x99,0x9f,0x85,0x88,0x8d,0xa8,0xad,0x87,0x84,0x88,0x8b,0x8c,0x9d,0x90,0x90,0x9c,0x89,0x8c,0x1f,0x02,0x3c,0xaa,0x25 +,0x22,0x08,0x07,0x0e,0x07,0x1c,0xae,0x26,0x16,0x00,0x09,0x12,0x07,0x0d,0x0e,0x0a,0x08,0x0f,0x12,0xfd,0x46,0xa3,0xb8,0x1c,0xad,0x90,0x86,0x87,0x84,0x92,0x8d,0x85 +,0x83,0x83,0x84,0x8a,0x8e,0x8f,0x8c,0x92,0x9d,0xa3,0xbe,0x90,0xa0,0x37,0x1d,0x10,0x10,0x0e,0x09,0x06,0x03,0x03,0x05,0x0f,0x20,0x07,0x05,0x0f,0x2b,0x20,0x17,0x22 +,0x1c,0xd7,0x2a,0xb1,0xa6,0x9d,0x8f,0x9e,0x97,0x8c,0x93,0x35,0x20,0x4e,0x94,0x9c,0xa4,0x9f,0x54,0x9c,0x8a,0x8f,0x89,0x8d,0x8e,0x92,0x86,0x8a,0x9c,0x87,0xaa,0x1a +,0x47,0xcb,0x25,0x1b,0x29,0x10,0x07,0x05,0x06,0x02,0x0c,0x2f,0x0f,0x09,0x03,0x08,0x0b,0x41,0x26,0x21,0x0f,0x10,0x4f,0xc2,0x8d,0x97,0x9a,0x9d,0x94,0x8b,0x87,0x86 +,0x87,0x84,0x9b,0x9f,0x93,0x9e,0x8a,0x91,0x9f,0xa5,0x20,0x0f,0x9b,0x95,0x91,0xb4,0x0e,0x0a,0x18,0x9e,0xae,0xbc,0x2a,0x14,0x0b,0x09,0x0b,0xb3,0xb2,0x1c,0x04,0x00 +,0x02,0x3b,0x9f,0x9f,0x30,0x02,0x09,0x07,0x9d,0x8b,0x87,0x96,0x10,0x0f,0x3f,0x8e,0x86,0x80,0x91,0xaf,0x0f,0x47,0x80,0x82,0x85,0x9e,0x1e,0x2f,0x92,0x85,0x83,0x83 +,0x8e,0x2e,0x05,0x1d,0x8d,0x91,0xba,0x13,0x00,0x03,0x04,0x17,0x36,0x46,0x1b,0x01,0x05,0x08,0xac,0x8e,0x18,0x0a,0x13,0x0f,0x2f,0x2e,0xfa,0xa5,0xd5,0x26,0x38,0x50 +,0x34,0x9e,0x87,0x8c,0x4e,0x5a,0x9b,0x88,0x95,0x8d,0x8d,0x85,0x8f,0xb2,0x34,0x9d,0xb9,0xb4,0x95,0xa0,0x87,0x3b,0x0e,0xa6,0x89,0x9b,0x93,0x22,0x03,0x05,0xc8,0x8e +,0x1e,0x15,0x0a,0x00,0x05,0x07,0xc7,0x9c,0x2e,0x0e,0x00,0x08,0x18,0x94,0x88,0x98,0x13,0x0d,0x1d,0x23,0x81,0x83,0x8d,0xa8,0x13,0x0e,0x9e,0x80,0x84,0x81,0x45,0x04 +,0x17,0x8e,0x85,0x86,0xc5,0x3c,0xa7,0x2b,0xa0,0x90,0x8f,0x91,0x9d,0x0e,0x26,0xc9,0x98,0x9f,0x25,0x1c,0x05,0x0b,0x03,0x17,0x41,0x2f,0x0c,0x04,0x0b,0x06,0x0d,0xcc +,0xb2,0x23,0x28,0x29,0x1c,0x1f,0xa7,0xa4,0x9c,0x9c,0x9c,0x9b,0x8d,0x84,0x93,0x8c,0xa3,0xbf,0xa5,0x0f,0xa3,0x9d,0x8b,0x8c,0x22,0x12,0x1b,0x8c,0x90,0x80,0x8f,0x27 +,0x28,0x0b,0x96,0x85,0x80,0x92,0x08,0x0a,0x04,0x31,0xaa,0x96,0x1f,0x02,0x04,0x02,0x04,0x26,0x9c,0x0a,0x0a,0x01,0x03,0x0f,0xae,0x99,0x9a,0x2a,0x19,0x1f,0x98,0x82 +,0x8a,0x81,0xa0,0x1c,0x48,0x96,0x86,0x83,0x8f,0xab,0xaa,0xaa,0x0f,0x96,0x8d,0x99,0xbd,0x1d,0x22,0x1e,0x5d,0x9f,0x8e,0x9c,0x30,0x12,0x2f,0x12,0xa2,0xb2,0x40,0x0d +,0x12,0x17,0x0d,0x8c,0x56,0xa9,0x1c,0x0b,0x16,0x02,0x0f,0xe4,0xea,0x1d,0x08,0x0a,0x0d,0xbb,0x8d,0xad,0xc6,0x3b,0x39,0x1b,0xed,0x8c,0x8d,0x8d,0x94,0xcb,0xa6,0x94 +,0x8e,0x84,0x89,0x91,0xcf,0xe0,0xc1,0x85,0x83,0x97,0xb3,0x11,0x0d,0x27,0x95,0x97,0xa2,0x0c,0x04,0x09,0x1d,0xa1,0x98,0x27,0x0b,0x06,0x04,0x12,0xa7,0x9a,0xb3,0x27 +,0x08,0x08,0x0d,0x20,0x35,0x99,0x1f,0x07,0x1a,0x0e,0x28,0x92,0x87,0x8c,0xb6,0xc8,0xaf,0xa4,0x8d,0x8b,0x80,0x8e,0x38,0x9b,0x8e,0x83,0x88,0x8c,0x24,0x0f,0x2d,0x1b +,0x36,0x43,0x1c,0x14,0x18,0x13,0x24,0xe1,0xc7,0xbc,0x28,0xc9,0xb6,0x11,0x36,0x93,0x9b,0xc3,0x2d,0x17,0x2c,0x0f,0x3f,0x5c,0x2c,0x1b,0x01,0x3b,0xa3,0x15,0x78,0xad +,0x0d,0x07,0x02,0x9c,0x8b,0x98,0x9f,0x99,0x3d,0xac,0x9d,0xae,0x84,0x87,0x91,0x1c,0x1f,0xdc,0x95,0x80,0x93,0x9b,0x9b,0x26,0x1b,0x3b,0x9c,0x93,0x3a,0x14,0x19,0x3c +,0x15,0x17,0x8d,0x2f,0x06,0x02,0x3d,0x17,0x19,0x13,0xa1,0xaf,0x0c,0x12,0x0f,0x89,0xa3,0x2f,0x2c,0x27,0xcb,0x9c,0x1f,0xb9,0xc9,0x31,0x27,0x0a,0x33,0xe7,0x8f,0xa4 +,0x2b,0x88,0x8c,0x9e,0x8d,0x9a,0x95,0xb9,0x77,0x8c,0x90,0x9d,0x8e,0x93,0xdd,0x9e,0xcb,0xba,0x0d,0x0f,0x1d,0x12,0x1a,0x00,0xae,0xac,0x7d,0xae,0x12,0x0f,0x0c,0x2a +,0xdc,0xa9,0x29,0x9b,0x94,0x0d,0x0e,0xb8,0x96,0x9e,0x40,0x1b,0x1b,0x19,0x10,0xad,0x8e,0x95,0x9b,0x2a,0x1c,0x10,0xaf,0x8a,0x86,0x9a,0x28,0xb8,0x37,0x91,0x8a,0x85 +,0x9a,0x19,0x0d,0x18,0x95,0xf3,0x87,0x8d,0x23,0x24,0x17,0x2e,0x20,0x19,0x94,0x92,0x04,0x05,0x0e,0xad,0x8c,0x99,0x1d,0x0f,0x14,0x15,0x16,0xcd,0x2d,0xa1,0x8f,0x0e +,0x0d,0x3b,0x88,0x5a,0x1b,0xb7,0xe2,0xdf,0xb8,0x1c,0xad,0x97,0xad,0x2c,0x0c,0x38,0x9d,0x9b,0x93,0x0a,0xa3,0x84,0x90,0x8c,0xa2,0x8e,0xa4,0x5e,0xeb,0x8d,0x9d,0x8d +,0xa6,0x32,0xa6,0x5d,0x23,0x2b,0x0b,0x08,0x1e,0x0e,0x01,0x1e,0xb2,0x3b,0x22,0x0e,0x0c,0x0d,0x48,0xdc,0x95,0xb1,0xba,0x9f,0xc4,0x3f,0x9b,0x81,0x8d,0x5e,0x19,0x4c +,0x9f,0x0f,0x8c,0x8e,0xaa,0x9b,0x15,0x0e,0x0c,0x9e,0x89,0x89,0x34,0x0e,0x2b,0xa8,0xac,0x37,0xa5,0xa2,0x19,0x05,0x10,0x48,0xa3,0x8a,0x9c,0xae,0x2e,0xc9,0xc0,0x0e +,0x5c,0x8f,0xb2,0x1a,0x06,0x27,0x96,0xae,0x9d,0x37,0x16,0x1a,0x0e,0x27,0x28,0x56,0x89,0xbd,0x24,0x0a,0x3d,0x9c,0x3d,0xaf,0xb1,0x97,0xbf,0x1c,0x21,0x5b,0x94,0x93 +,0x34,0x13,0x1a,0xbf,0x8d,0x41,0xbd,0x95,0x9e,0x8e,0x1f,0xa6,0x8d,0x4d,0x9f,0xaa,0xc6,0x9d,0x9e,0xaa,0x1f,0x18,0x45,0x20,0x17,0x09,0x19,0xae,0x0e,0x1f,0x0d,0x26 +,0xbe,0xc6,0xb5,0x10,0x1b,0x9c,0xa2,0xce,0x2c,0xac,0x91,0x35,0x1e,0xb3,0x8f,0xb1,0x0d,0x16,0x96,0xa3,0x87,0x2c,0x3d,0x90,0x98,0xa1,0x12,0x2e,0x90,0x83,0x96,0x1a +,0x1f,0xaa,0xae,0x22,0x1b,0x65,0x4a,0x11,0x0c,0x0a,0x19,0x91,0xb8,0xa9,0x1a,0x61,0xa6,0x1f,0x20,0xae,0x84,0x88,0x28,0x09,0x1a,0xb9,0x8a,0x9e,0x2e,0x14,0x15,0xae +,0x2f,0xaa,0x98,0x6e,0xc7,0x0a,0x14,0x25,0x1e,0x96,0x54,0x3f,0x3a,0xd6,0xdf,0x48,0x95,0x89,0x8e,0x32,0x09,0x11,0x8e,0x8f,0x8b,0x3b,0xdf,0x94,0xce,0x1e,0x0c,0x3a +,0x8d,0x9e,0x21,0x12,0x1b,0xc0,0x21,0x2a,0xad,0x8e,0x39,0x02,0x05,0xc2,0x8f,0x87,0x33,0x12,0xe4,0x9f,0x9a,0x6e,0xaa,0x95,0x95,0x25,0x0d,0x2a,0xa3,0xbd,0x31,0x11 +,0x1f,0x2d,0x13,0x1b,0x1e,0xb3,0x8f,0x4b,0x26,0xa9,0x8b,0x86,0xa7,0x18,0x26,0x95,0x86,0x94,0xac,0x57,0xaa,0xa2,0x4e,0x6f,0x46,0x1e,0x0f,0x0c,0x17,0x98,0x9d,0x2c +,0x0a,0x18,0x5a,0x2e,0xf7,0xb0,0xa6,0x8f,0xa9,0x3c,0x2b,0x55,0x90,0x8e,0xac,0x17,0x11,0x2a,0x25,0x3f,0x98,0xe7,0x9e,0x20,0x0f,0x14,0x2a,0xad,0xb8,0x36,0x27,0x5c +,0x2d,0x20,0x23,0x9e,0x8c,0x9e,0x28,0x11,0x49,0xab,0xab,0x90,0xb0,0x96,0xa8,0x27,0x1d,0x4b,0x8e,0x9c,0x2c,0x13,0x19,0x9e,0xa1,0x1e,0x20,0xcd,0xd8,0x1b,0x0d,0x27 +,0xce,0xa3,0xa9,0x1d,0xb3,0xa1,0x98,0x36,0x1e,0xa6,0x98,0x9d,0x42,0x2c,0x9f,0x9c,0x2d,0x15,0x1a,0xac,0xa0,0x15,0x0b,0x05,0x32,0x97,0x57,0xb0,0xb8,0xa8,0x3c,0x2f +,0xa3,0x85,0x8e,0xa6,0x38,0xe1,0x9c,0xa1,0x3a,0x22,0xbf,0xb9,0x27,0x0a,0x08,0xf9,0x8d,0xab,0xc4,0x21,0x2d,0x24,0x15,0x18,0xa9,0x96,0x9d,0x7a,0x30,0xd4,0xad,0xa3 +,0xa4,0x92,0x9d,0xb3,0x1d,0x10,0x26,0x96,0xa3,0x49,0x22,0x1a,0x1f,0x25,0x55,0xa8,0x9b,0xb2,0x27,0x14,0x27,0xba,0x95,0x99,0xd0,0x26,0x13,0x40,0x37,0x99,0x97,0xbb +,0xba,0xcc,0x6e,0x1f,0xbb,0x90,0x94,0x5e,0xe9,0x2b,0x21,0x20,0x28,0x1d,0x4f,0x97,0xab,0x19,0x1f,0x2a,0xb7,0xcb,0x25,0xb5,0x6e,0xc7,0x15,0x18,0x27,0xae,0x9c,0xa3 +,0x9f,0xb2,0x52,0xbf,0xb1,0x9b,0x96,0x3c,0x1f,0x2c,0x4a,0x54,0x27,0x54,0x99,0xcd,0x24,0x1b,0x2a,0xbc,0xa4,0x97,0xc5,0x41,0x26,0x22,0xc2,0xb7,0xc0,0xb7,0xa7,0x2a +,0xcf,0x20,0x39,0xaf,0x2f,0xa2,0xb6,0x9e,0x46,0x24,0x35,0xbb,0x94,0x9b,0xd9,0x1a,0x24,0x20,0x2e,0xb9,0xb8,0xd7,0x19,0x17,0x21,0x2e,0x2f,0xbb,0xa1,0x3b,0x23,0xd9 +,0xce,0xc1,0xa0,0x99,0x99,0xa5,0x2b,0x27,0x9d,0x9d,0x96,0x98,0xad,0xc7,0x28,0x19,0x19,0x1e,0x28,0x2d,0x2f,0x2b,0x23,0x2e,0x2a,0x47,0xa2,0x99,0x45,0x1f,0x2b,0xe1 +,0x98,0xa2,0xa1,0xad,0x32,0xec,0xca,0xba,0x48,0xbf,0xa5,0x2d,0x1e,0x26,0x2f,0xbf,0xbb,0x37,0x2a,0x18,0x1e,0xf0,0xfd,0x2c,0xc4,0x9a,0x9c,0xa3,0xad,0xa9,0xbe,0x7d +,0xc7,0xa4,0xb4,0x3f,0x4d,0xa5,0xbd,0xe3,0x9e,0xb1,0x2e,0x11,0x17,0x34,0xc9,0x3d,0x53,0xb0,0xc8,0x34,0x1f,0x1f,0x17,0x33,0x76,0x2c,0xe6,0xae,0xa9,0xbd,0xa3,0x98 +,0x97,0xa1,0x29,0x6b,0xb9,0xba,0xb5,0xaf,0xbf,0x29,0x2b,0x1d,0x24,0x29,0x2e,0xed,0x37,0x1a,0x1f,0x43,0xa0,0xa1,0xb3,0xa2,0xb3,0xa8,0xba,0x6c,0x3a,0xac,0x91,0x97 +,0xad,0x2a,0x3a,0x2c,0x52,0xcc,0x22,0x1f,0x0d,0x13,0x2a,0x2f,0xca,0xcb,0x9a,0xa3,0x1f,0x1f,0x6a,0x9c,0x9c,0x9f,0xa7,0xa6,0xc4,0x3f,0xc3,0xea,0xb3,0x97,0xac,0x1c +,0x17,0x1b,0x54,0xa3,0xaa,0xb4,0x3f,0x1a,0x25,0xb8,0x3e,0x1b,0x2e,0xa3,0xa0,0x2e,0x35,0xaf,0xa7,0xb7,0x2b,0x2f,0xf5,0xac,0xa8,0x9b,0xc8,0x23,0x9c,0xad,0x27,0x31 +,0x40,0x2a,0x19,0x2c,0xa5,0xa0,0x2a,0x1b,0x2e,0x23,0x2c,0xa8,0xaf,0x27,0x1d,0x36,0x9a,0x96,0x9d,0x93,0xa7,0x2c,0x33,0xa2,0x9b,0xcd,0xf5,0xb2,0x55,0x1e,0x1a,0x31 +,0xb5,0x2c,0x1e,0x1d,0x0d,0x25,0xbc,0xbe,0xc9,0xa9,0x8d,0xa6,0x60,0xe2,0xad,0xa8,0x3d,0xab,0x99,0x9f,0xb0,0xe4,0x3a,0x3a,0x1e,0x29,0x43,0x1d,0x13,0x19,0x5b,0xa9 +,0xe6,0x48,0xda,0x21,0x27,0xb6,0xa2,0x3d,0xb7,0x90,0x9a,0xdf,0x3a,0x97,0x9e,0x34,0x2f,0x41,0x1f,0x1d,0x53,0xab,0x53,0x4e,0xa8,0x2f,0x1f,0x1b,0x3d,0xa9,0xce,0x58 +,0xba,0x3d,0x39,0xa3,0x9c,0x3a,0x27,0x9f,0xaf,0x18,0x1b,0xaa,0x94,0xa1,0xb4,0xa3,0xe5,0x1c,0x28,0xb8,0x5a,0x2c,0x2e,0xb5,0xb1,0x2b,0x31,0x22,0x3c,0x5e,0x2f,0x2d +,0x24,0x31,0xd8,0x9c,0xaa,0xb3,0x9f,0xad,0x39,0x2e,0xa1,0x95,0xaf,0xc9,0xad,0x36,0x2f,0xaa,0xa2,0x2f,0x10,0x1e,0x33,0x1d,0x17,0xcb,0xae,0x25,0x34,0xde,0xc3,0x45 +,0xa7,0x9d,0xab,0x5a,0xab,0x8d,0xac,0x47,0xae,0xa8,0xaa,0x7a,0xc2,0x27,0x16,0x14,0x2f,0xa9,0x2c,0x2b,0xc9,0x2d,0x10,0x1a,0x4e,0x45,0x69,0xb5,0xa4,0xa2,0xa9,0xa0 +,0xa5,0xad,0xb8,0x9b,0xa0,0xc9,0xc7,0xc5,0xbb,0x35,0x34,0x6e,0x1c,0x0c,0x1e,0xec,0x37,0x1e,0x30,0xb1,0xfc,0x28,0xd4,0xaf,0xab,0xaf,0xac,0xbc,0x3d,0xbd,0x99,0x90 +,0xb8,0xe5,0xa2,0xb3,0x26,0x2f,0xfc,0x3d,0x25,0x20,0x48,0x36,0x25,0x36,0x2b,0x16,0x1c,0xa8,0x9f,0x2d,0x25,0xad,0x9a,0x95,0x94,0x9e,0xf0,0x2c,0xd5,0xb8,0xb7,0xb6 +,0xa1,0xab,0x36,0x21,0x1d,0x2a,0x26,0x23,0xf1,0x45,0x1f,0x25,0x53,0xaa,0x34,0x53,0xad,0xad,0xbf,0x3a,0xae,0xbe,0xd7,0xb5,0x9e,0xac,0xb1,0xb3,0x66,0x37,0x2a,0xaf +,0x42,0x20,0x23,0x51,0xbe,0x3f,0xdf,0x31,0x1a,0x18,0x3f,0xab,0xca,0x38,0xa4,0x95,0xb4,0x46,0x5a,0xc6,0xd7,0xa7,0x99,0xb9,0x5e,0x5d,0xbf,0xab,0xb5,0xc6,0x5f,0x2e +,0x1c,0x1d,0x1e,0x23,0xad,0xa7,0x3a,0x1a,0x26,0xb9,0x3f,0x2b,0xe7,0x9c,0xb3,0x45,0xb3,0x9b,0x97,0xbc,0x52,0x50,0xb2,0x30,0xc7,0x9c,0x2c,0x16,0x2c,0xae,0xc4,0x47 +,0x29,0x1c,0x23,0x25,0x3b,0x57,0xd8,0xaf,0xc0,0xc9,0x3b,0xa6,0x9e,0xad,0xc8,0xc1,0xa4,0xbc,0xa3,0x9b,0xc0,0x27,0x2c,0x42,0x2e,0x2c,0x3a,0x39,0x2d,0x26,0x2c,0x39 +,0xd8,0xad,0x75,0x27,0x42,0x42,0xbd,0x9b,0xb8,0x2e,0xd2,0x9c,0x9d,0xab,0xc6,0x2d,0x27,0xc1,0xa1,0xae,0xce,0x21,0x3c,0xc8,0x1d,0x54,0x38,0x22,0x1e,0xdb,0xb4,0x2e +,0xbd,0x3a,0x3a,0x5e,0xaa,0xaf,0xd8,0x46,0x2f,0x9c,0x9c,0xbf,0x7c,0xbc,0x5f,0xce,0xa9,0x27,0x2c,0x2d,0x71,0xb0,0x41,0x4a,0xd2,0xb5,0x26,0x1a,0x21,0x31,0xbf,0x9e +,0x9c,0x5b,0x2c,0x2c,0xa1,0x8e,0xa4,0x3c,0x20,0xe7,0xd9,0x9c,0x99,0xdb,0x29,0x26,0x47,0x29,0x48,0x21,0x28,0x22,0x25,0xd7,0xac,0xda,0x37,0xc5,0x1d,0x3d,0xa4,0xa7 +,0xaf,0x45,0xaa,0xa5,0xb4,0xc1,0x9b,0x9b,0x3a,0x38,0x37,0xd5,0x37,0xf3,0x52,0x1f,0x1f,0x25,0xb4,0xf1,0x23,0x21,0x23,0x27,0xbb,0x9d,0x9f,0xbc,0xb4,0xaf,0x51,0xef +,0xff,0x9a,0xab,0x33,0x74,0xc7,0xa8,0xc8,0x3e,0x2a,0x25,0x3f,0xd3,0x64,0x30,0x20,0x46,0xac,0xbd,0x24,0x1e,0x5a,0xc6,0xc6,0xb8,0xaa,0x30,0xca,0x99,0x96,0x9d,0x4e +,0x4c,0x49,0xd0,0xb0,0xc4,0x27,0x28,0x39,0x54,0x37,0x23,0x36,0x4f,0x3c,0x32,0x25,0xc2,0x48,0x3b,0xb4,0xaf,0x62,0x3b,0xac,0x5f,0xbb,0xa9,0x34,0x45,0xab,0xac,0x98 +,0xa4,0x2e,0x2c,0x27,0x3b,0xba,0xd4,0x3e,0x1d,0x2b,0xb8,0xbb,0x3e,0x29,0x31,0xac,0xb7,0x2c,0x3f,0xb3,0x9e,0xac,0xb2,0x61,0x51,0xbe,0x95,0xaa,0x22,0x32,0xe5,0x37 +,0x31,0xaf,0xb7,0x50,0x1d,0x28,0x2b,0x2c,0x46,0x2c,0x26,0x2b,0xaa,0x9b,0xcd,0x44,0xb4,0x31,0xd5,0xa0,0x9d,0x9f,0x28,0x29,0xaf,0xa9,0xba,0x3b,0x2c,0x32,0x2c,0x20 +,0xd3,0xd0,0x7e,0xc4,0x5e,0xbd,0x33,0xae,0x31,0x21,0xd4,0x64,0xb8,0xbc,0xa7,0x4b,0x30,0xbb,0xa6,0x96,0xa8,0x3f,0xdf,0xca,0xc4,0x6a,0x44,0x33,0x30,0x28,0x4c,0xcb +,0x28,0x27,0x2f,0x26,0x25,0xc3,0x9a,0x9c,0x3d,0x28,0x31,0xbd,0xbc,0xca,0xda,0xb1,0xa2,0xbb,0xc0,0x63,0xa6,0xcd,0x2f,0x26,0x69,0xa8,0x32,0x1d,0x39,0xd4,0x30,0x39 +,0xbc,0xa8,0x46,0x24,0x20,0xd9,0x4d,0xa8,0x9f,0xcc,0x6e,0x4a,0xbf,0xa7,0xa4,0xaf,0xbb,0x4f,0x1e,0xfe,0xa5,0xaa,0xac,0x1f,0x16,0x1d,0xc4,0xb7,0xe9,0x1c,0x20,0xbc +,0x9d,0xad,0xc4,0x6e,0x4e,0xe7,0xd3,0xd3,0x2e,0xb6,0xb2,0xa3,0x37,0x20,0xad,0x9d,0x66,0x2a,0x4a,0x33,0x37,0x49,0x35,0x3d,0x73,0x61,0xbb,0x4b,0x35,0xa2,0xb5,0x3d +,0x3a,0x7b,0xa7,0xda,0x3c,0x35,0x5c,0xce,0x48,0x4f,0xbf,0x3b,0xba,0x9d,0xb1,0xaf,0x4f,0x23,0x2e,0x4f,0xad,0xbe,0x25,0x1f,0x37,0x39,0xd1,0xae,0xbf,0x9b,0xba,0x22 +,0x4d,0x4a,0x38,0xb7,0xb2,0x3b,0x3e,0xb9,0xc2,0xb5,0x33,0x1d,0xdf,0xa6,0xb8,0xbb,0xb5,0xd1,0x5e,0xd2,0xa8,0x39,0x23,0x2e,0x3e,0xd3,0xb6,0xb5,0xf5,0x22,0x1f,0xbc +,0xa8,0xa3,0x61,0x30,0x39,0xbe,0xcf,0x3b,0x38,0x4d,0xac,0xdf,0x2e,0x1c,0xfb,0x9c,0xa5,0x32,0x22,0x36,0xcb,0xa5,0xb2,0xc8,0x34,0x1e,0xd5,0xac,0xe0,0xea,0x4a,0x2d +,0x23,0xc6,0xa2,0xbf,0x23,0xbb,0xa3,0xb3,0xcb,0xab,0x99,0xba,0x2f,0x26,0xb6,0x33,0x25,0x42,0x45,0x30,0xc2,0xbf,0x28,0xd4,0x54,0xc6,0x31,0x2f,0xba,0xa5,0xaa,0x3c +,0x2f,0x68,0x31,0x3d,0xb1,0xbb,0xae,0xb0,0xb7,0x3f,0x1d,0x18,0x2f,0xad,0xac,0xbb,0xc2,0x46,0x22,0x2a,0xac,0xa7,0x4a,0xd1,0xb0,0xae,0xbb,0x38,0xa7,0xa5,0x34,0x4b +,0x51,0x6b,0xfa,0x40,0x32,0x1f,0x33,0x56,0xb5,0x35,0xd7,0x97,0x9a,0xec,0x1a,0x4b,0x7c,0x4d,0x2f,0x3b,0xac,0xa2,0xaf,0xbe,0xd7,0x26,0x36,0xa2,0xba,0x27,0x30,0x2f +,0x35,0xbf,0xb3,0xe1,0x1d,0x19,0x29,0x43,0xaa,0x9d,0x99,0xcc,0x1e,0x29,0x59,0x20,0xc5,0x8e,0x99,0xdb,0x1e,0x1e,0xab,0x9b,0x94,0x8f,0x34,0x0c,0x0d,0x46,0x98,0x8d +,0xa9,0x0d,0x04,0x0c,0x9c,0x9b,0xab,0xc4,0x12,0x3d,0xbc,0xb7,0x48,0x1f,0x4f,0x8e,0x86,0x9e,0x26,0x11,0x2f,0xb4,0x9c,0x8c,0x90,0x29,0x09,0x06,0x13,0x9b,0x9a,0xa9 +,0x16,0x10,0x4d,0x8c,0x93,0xa7,0xa5,0x64,0x2f,0x08,0x0e,0xb5,0x8f,0xa0,0xb3,0x34,0x39,0xb5,0xb6,0x3c,0x3a,0xa7,0x8e,0x87,0xd8,0x1a,0x19,0x1e,0x23,0xb0,0xa2,0x22 +,0x0c,0x08,0x24,0x9f,0x8e,0xab,0x3b,0x2e,0x12,0xc6,0x99,0x92,0x99,0x97,0xe0,0x2a,0x9d,0x9a,0x9e,0x3f,0x25,0x58,0x32,0x26,0x0a,0x09,0x24,0xea,0x99,0xa0,0xe4,0x18 +,0x27,0xbf,0x5d,0xbf,0x97,0x8c,0x99,0x2f,0x1a,0x32,0xa7,0x95,0xa7,0xd3,0x17,0x0f,0xa8,0x95,0x94,0xaa,0x25,0x1a,0x08,0x0a,0x3d,0x8e,0x91,0x25,0x0b,0x1f,0x9c,0x9e +,0x3c,0x2c,0x73,0x99,0x8f,0xbe,0x1f,0x4c,0xa1,0x9d,0x94,0x96,0xc2,0x1d,0x11,0x0c,0x2c,0x90,0x9a,0x7c,0x13,0x13,0x5e,0xb3,0x9a,0x9b,0x5e,0x16,0x0f,0x1e,0xb1,0x8c +,0x8b,0xa2,0x39,0x19,0x1e,0x4a,0xc4,0x3f,0x49,0x94,0x8f,0xa8,0xb3,0xb7,0x5f,0x18,0x14,0x36,0xc1,0x1f,0x07,0x0e,0x27,0x9d,0x90,0x47,0x12,0x0c,0xb5,0x88,0x85,0x8b +,0x46,0xb5,0x9b,0xa5,0xa9,0x5d,0xa8,0x1d,0x10,0x14,0x18,0x2c,0x27,0x35,0x1b,0x38,0x9a,0x95,0x2f,0x0b,0x35,0x93,0x8f,0xa2,0xf8,0x9a,0x9b,0xa8,0xcb,0xa9,0x90,0xb1 +,0xae,0x2a,0x07,0x25,0x90,0x83,0x88,0x4a,0x1c,0x28,0xc3,0x2a,0xc7,0x99,0x96,0x9e,0x29,0x31,0x33,0x24,0x1a,0x0d,0x0d,0x0e,0x0d,0x0a,0x18,0x4b,0x33,0x15,0x12,0x1d +,0x05,0x05,0x05,0x0b,0x2f,0x2b,0x25,0x11,0x0d,0x12,0x1e,0xb9,0x4d,0x48,0x1f,0x1f,0x9d,0xab,0x86,0x81,0x83,0x9a,0x1c,0xa1,0x90,0x83,0x89,0x8b,0x86,0x8d,0x91,0x9a +,0xa2,0x9e,0xa5,0xa6,0x98,0x8f,0x38,0xb8,0x9c,0x3f,0x38,0xc7,0x91,0x9e,0x3b,0x11,0x37,0x8e,0x91,0x9f,0xab,0x27,0x23,0x17,0xa9,0x8d,0xaf,0xa6,0x3a,0x0d,0x04,0x00 +,0x0b,0xb8,0x55,0x1e,0x3c,0x4d,0x12,0x05,0x0d,0x17,0x19,0x0f,0x1f,0x8a,0x9f,0x26,0x2c,0xad,0x28,0x04,0x0f,0x1f,0x8f,0x8a,0x8e,0x92,0x31,0x0f,0x07,0x0c,0x0b,0x0a +,0x8f,0x84,0x9b,0x2f,0x22,0x9c,0x2d,0x2c,0xb6,0x93,0x84,0x9d,0xda,0x7c,0x99,0x8b,0xab,0xb7,0x1e,0x2e,0x89,0x8d,0x8d,0x98,0x9a,0x99,0x16,0x0e,0x16,0xaa,0x8a,0x9f +,0x9f,0x18,0x05,0x01,0x06,0x0c,0x1b,0x81,0x87,0x98,0x10,0x09,0x1f,0x14,0xce,0x9d,0x8b,0x83,0x98,0x95,0x99,0xbe,0x2a,0x5b,0x25,0x0f,0x86,0x81,0x82,0x88,0xa9,0xa1 +,0x41,0x26,0x9a,0x87,0x81,0x9d,0xbe,0xa2,0x3b,0x09,0x0b,0x0c,0x09,0x86,0x8a,0x24,0x03,0x00,0x04,0x00,0x07,0x13,0xa8,0xbd,0x01,0x02,0x00,0x08,0x05,0x0a,0x06,0x14 +,0x80,0x99,0x5a,0x0d,0x1d,0x2c,0x06,0x17,0x96,0x81,0x8d,0x9c,0x9d,0x8e,0xa6,0x2b,0x37,0x1e,0x8a,0x80,0x88,0x95,0x4a,0xc9,0x17,0x10,0x90,0x80,0x83,0xb7,0x18,0xc0 +,0xa0,0xa4,0x93,0xa6,0x9a,0x80,0x8a,0x23,0x0b,0x26,0xb1,0x22,0x21,0x94,0x80,0x96,0x0c,0x0b,0x35,0x24,0x10,0x0c,0x04,0x89,0x86,0x14,0x05,0x09,0x59,0x0d,0x0b,0xde +,0x88,0x8b,0x1e,0x05,0x19,0x23,0x12,0x17,0x08,0x9a,0x80,0x19,0x00,0x00,0x04,0x18,0x18,0xac,0x82,0x87,0x1d,0x04,0x03,0x11,0x1d,0xd8,0x2b,0xa8,0x80,0x94,0x0c,0x03 +,0x16,0x6f,0x46,0x9f,0x83,0x82,0x40,0x02,0x0c,0x9b,0xb7,0x39,0x16,0x24,0x80,0x8e,0x1f,0x08,0x20,0x9a,0x26,0x9f,0x82,0x80,0xa5,0x02,0x03,0x1e,0x1e,0x12,0x0c,0x2f +,0x80,0x8a,0x0f,0x02,0x04,0x1b,0x24,0x9b,0x82,0x80,0x9f,0x05,0x18,0x96,0x8a,0x8c,0xb5,0xb6,0x80,0x87,0xc2,0x32,0x98,0x80,0x95,0xa9,0x86,0x80,0xa9,0x07,0x12,0xaa +,0x1a,0x03,0x03,0x09,0x85,0x9b,0x00,0x03,0x00,0x09,0x06,0x07,0xdb,0x95,0x33,0x02,0x00,0x0b,0x0a,0x05,0x02,0x08,0x83,0x8c,0x06,0x04,0x0d,0xa1,0xed,0x38,0x8a,0x8c +,0x1f,0x02,0x0b,0x95,0x8f,0xbe,0x1e,0x21,0x81,0x88,0x41,0x31,0x9b,0x80,0x8f,0x97,0x84,0x80,0x8e,0x11,0x18,0x8b,0x8c,0x24,0x07,0x13,0x80,0x88,0xb6,0xff,0x19,0x3c +,0x16,0x23,0x8a,0x80,0x9d,0x05,0x06,0xb2,0x8e,0xca,0x12,0x18,0x80,0xa9,0x02,0x07,0x13,0xa3,0x20,0x3c,0x8c,0x8c,0x0e,0x00,0x04,0x42,0xbc,0x17,0x06,0x0a,0x82,0xa2 +,0x09,0x06,0x08,0x44,0x15,0x0e,0xa8,0x8d,0x1d,0x0a,0xaa,0x84,0xaf,0x06,0x04,0xc4,0x80,0xaa,0x15,0x12,0x20,0xf5,0x48,0x97,0x88,0x94,0x0b,0x01,0x21,0x89,0x8d,0x28 +,0x2a,0x89,0x80,0x55,0x06,0x14,0x8b,0x8a,0x9b,0x88,0x80,0x95,0x06,0x0c,0x9b,0x8a,0x2d,0x0b,0x05,0x91,0x8b,0x09,0x06,0x0c,0x9d,0xfd,0x11,0x1d,0xa3,0xac,0x0c,0x19 +,0x8e,0x82,0x99,0x36,0x9b,0x80,0x88,0x44,0x3c,0x92,0x81,0xad,0xa5,0x87,0x8a,0xb3,0x11,0x5e,0xa2,0xbc,0x2c,0x17,0x2b,0x80,0xee,0x01,0x03,0x23,0xa8,0x03,0x08,0x18 +,0x1b,0x02,0x00,0x0b,0x3e,0x17,0x08,0x03,0x0f,0x9c,0x09,0x02,0x08,0x34,0xa7,0x0a,0x0d,0x31,0x4e,0x0d,0x07,0x48,0x8a,0x8a,0x4b,0x08,0xa2,0x80,0x94,0xb3,0xcd,0x8c +,0x94,0x26,0x8e,0x81,0x80,0x9a,0x1d,0xad,0x8c,0x8f,0xa9,0x13,0xa8,0x80,0x97,0x45,0x0b,0x9f,0x8b,0x2a,0xa5,0x87,0x8b,0x0f,0x06,0xac,0x82,0x83,0xb6,0x0e,0xde,0x80 +,0xa6,0x19,0x07,0x0e,0x99,0x34,0x2c,0xb6,0xa2,0x0e,0x00,0x06,0xab,0xb1,0x07,0x01,0x10,0x80,0x8f,0x17,0x08,0x09,0x5f,0x1c,0x6a,0xa1,0xb0,0x1f,0x0a,0x24,0x9b,0x9e +,0x0f,0x0a,0x07,0x97,0x97,0x05,0x05,0x06,0x95,0x8e,0x9f,0x8f,0x97,0x37,0x0d,0x18,0xa0,0x8f,0x9a,0xb6,0x16,0x92,0x80,0xb8,0x23,0x1b,0x9a,0x8d,0xca,0x97,0x85,0x83 +,0x9c,0x2c,0x99,0x8f,0x35,0x10,0x06,0x0e,0x8c,0xb5,0x3e,0x28,0x11,0x27,0x1a,0xaf,0x9c,0x99,0xaf,0x08,0x0d,0x8d,0x80,0x87,0xae,0x19,0x92,0x86,0x9f,0x3d,0x11,0xa1 +,0x8c,0x86,0x83,0x88,0x89,0xb6,0x1c,0x3d,0x8b,0x9f,0x0b,0x03,0x3a,0x80,0x88,0xbb,0x09,0x00,0x09,0x0f,0x1e,0x1b,0x15,0x0e,0x06,0x06,0x0d,0x12,0x04,0x03,0x00,0x34 +,0x95,0x07,0x02,0x04,0xbb,0x89,0x94,0xb9,0x3a,0x1f,0x0c,0x08,0x36,0x98,0x9b,0x99,0xab,0x8e,0x80,0x8c,0x3a,0x0d,0x1b,0x9c,0x9c,0x9c,0x93,0x8b,0x87,0x99,0xa1,0x8e +,0x9e,0xa2,0xa4,0x2e,0x90,0x81,0x8a,0xda,0x11,0xaf,0x8d,0xb1,0xc1,0x9e,0xaa,0x17,0x0b,0xaf,0x88,0x82,0x8d,0x19,0x26,0x8c,0x92,0x25,0x05,0x09,0xfe,0x9f,0xa8,0xaf +,0x3b,0x16,0x04,0x03,0x0d,0x36,0x52,0x0b,0x09,0x9b,0x81,0x9a,0x1e,0x07,0x09,0x28,0x25,0x14,0x1b,0x1e,0x28,0x18,0x15,0x3c,0x9d,0x2a,0x08,0x0a,0xa0,0x8f,0x16,0x0d +,0x1c,0x8d,0x91,0xbb,0xa7,0x2c,0x50,0x1b,0x05,0x1e,0x8d,0x81,0x93,0x19,0x3b,0x83,0x88,0xb8,0x14,0x13,0xaf,0x9b,0x8d,0x86,0x85,0x8d,0xcb,0x1f,0xb3,0x95,0xbe,0x1b +,0x0b,0x38,0x87,0x9b,0x13,0x02,0x13,0xba,0xb6,0x6a,0x0f,0x0e,0x15,0x34,0x8e,0x82,0x83,0x91,0xd1,0xb0,0x83,0x85,0x9e,0x1b,0x4d,0x84,0x81,0x87,0x91,0x8d,0xa2,0x23 +,0x1c,0x1d,0x35,0x26,0x0f,0x0c,0xce,0x8a,0xb6,0x08,0x02,0x08,0x19,0x11,0x09,0x13,0x17,0x0d,0x08,0x07,0x0f,0x10,0x07,0x04,0x00,0x26,0xbc,0x22,0x12,0x15,0xa1,0xb4 +,0x9f,0xc1,0x1b,0x0c,0x09,0x0d,0xe9,0x89,0x92,0x1f,0x0c,0x92,0x80,0x89,0x37,0x0e,0x93,0x86,0x89,0x85,0x85,0x84,0x8b,0xa1,0xa5,0x90,0x99,0x34,0x10,0xa8,0x80,0x89 +,0x3d,0x08,0x2d,0x93,0x9d,0xa2,0x38,0x29,0x28,0x34,0xad,0x8c,0x88,0x9b,0x21,0x2a,0x88,0x9d,0x15,0x0c,0xad,0x91,0xae,0xb1,0x31,0xce,0x19,0x05,0x04,0x0c,0x17,0x15 +,0x00,0x0d,0xa3,0x31,0x17,0x04,0x3d,0x22,0x11,0xa6,0xa6,0x91,0xae,0x15,0x25,0x8b,0x8a,0x2e,0x1b,0x9e,0x8f,0xa9,0x04,0x0f,0x86,0x8b,0x93,0x90,0x8f,0xb1,0x0a,0x03 +,0x02,0x1f,0x5b,0x0f,0x09,0xba,0x8f,0x33,0x0d,0x03,0x2b,0xb4,0xba,0xaa,0x8b,0x8e,0x26,0xb5,0x89,0x85,0xa8,0x0e,0xc2,0x87,0x98,0x2d,0x15,0x9a,0x8b,0x8f,0x90,0x8c +,0x84,0x96,0x29,0xcf,0x8a,0x82,0x92,0x4a,0x86,0x82,0x9a,0x0a,0x00,0x17,0x11,0x1b,0x0d,0x17,0x0c,0x02,0x02,0x1b,0x4d,0x10,0x02,0x05,0x59,0x0f,0x04,0x00,0x33,0x8b +,0x8e,0x8f,0xae,0x57,0x1c,0x1f,0x96,0x84,0x84,0x91,0x91,0x80,0x82,0x95,0x0e,0x3a,0x91,0xb0,0x99,0x8f,0x8c,0xad,0x13,0x18,0x9b,0x99,0x0e,0x02,0x9b,0x9f,0x2a,0x06 +,0x07,0x28,0x29,0xa6,0x2a,0x31,0x09,0x01,0x00,0x08,0x1f,0x1c,0x14,0x8c,0x87,0xfb,0x06,0x0a,0x27,0x49,0x98,0x9b,0x96,0xe8,0x0a,0x0d,0x96,0x90,0x90,0x2d,0x88,0x87 +,0xa4,0x2a,0x39,0x80,0x84,0x80,0x85,0x90,0x9a,0x24,0x08,0x2d,0xa1,0xa6,0x11,0x97,0x8a,0x1c,0x08,0x01,0x13,0x35,0xaa,0x19,0xdb,0xe7,0x0c,0x0d,0xc3,0xa9,0x27,0x09 +,0x98,0x82,0x2b,0x0a,0x05,0x95,0x8c,0x93,0x8d,0x95,0x8e,0x2e,0x0e,0xfe,0x8f,0x90,0xbb,0x83,0x85,0x8c,0x18,0x00,0x5f,0x97,0x96,0x99,0x99,0xa3,0x21,0x02,0x42,0xa5 +,0x9c,0x09,0xa2,0x96,0x06,0x04,0x04,0x9f,0xcb,0xba,0x37,0x3f,0x5d,0x03,0x03,0x19,0xda,0x27,0x13,0x82,0x92,0xe4,0x06,0x09,0xa8,0x41,0x28,0x0c,0x1d,0x1b,0x0c,0x11 +,0x1b,0xde,0x69,0x1a,0x84,0x94,0x28,0x03,0x4a,0x86,0x90,0x8b,0x94,0x84,0x90,0x17,0x12,0xae,0x92,0x20,0xa9,0x80,0x8b,0xcd,0x03,0x34,0x98,0xab,0xab,0x9d,0x95,0x22 +,0x05,0x18,0xbe,0x8d,0xba,0x98,0x80,0xa6,0x0f,0x02,0x3c,0x8d,0x87,0x8d,0x89,0x86,0xab,0x09,0x33,0x2f,0x9d,0x1f,0x98,0x87,0x23,0x0d,0x00,0x43,0xba,0x27,0x18,0x3a +,0x2c,0x04,0x08,0x2b,0x98,0x83,0x9d,0x82,0x85,0x99,0x11,0x0f,0x88,0x99,0xa4,0x9b,0x50,0x1c,0x08,0x01,0x05,0x05,0x04,0x08,0x92,0x12,0x03,0x00,0x05,0x2b,0x27,0xe0 +,0x2c,0x98,0x39,0x07,0x1f,0x9a,0x8c,0xac,0x87,0x80,0x82,0x91,0x06,0x4b,0x8e,0x87,0x8c,0x86,0x81,0x9e,0x15,0x2c,0x99,0x8e,0xab,0x82,0x86,0xa0,0x0d,0x05,0x98,0xaa +,0x8a,0xc0,0x90,0xa3,0x08,0x0f,0x0e,0xaa,0x3b,0xa5,0x83,0xa7,0x37,0x07,0x03,0x20,0x39,0x3f,0x0f,0x2f,0x12,0x01,0x04,0x03,0x3a,0x0f,0x9f,0x87,0xb6,0x30,0x07,0x8d +,0x87,0x86,0x82,0x88,0x80,0x93,0xa8,0xcf,0x8c,0x8f,0xbb,0x80,0x98,0xbe,0x0a,0x00,0x0c,0x0c,0x2f,0x06,0x0c,0x12,0x02,0x04,0x01,0x0b,0x03,0x0e,0x8b,0x1a,0x15,0x05 +,0x00,0x0d,0x44,0x9a,0x20,0x9e,0x3a,0x0e,0x1c,0x32,0x96,0xb8,0x87,0x85,0x90,0x99,0x11,0x8e,0x8f,0x89,0x85,0x8d,0x83,0xb3,0xd2,0xa7,0x9a,0x87,0x9b,0x81,0x85,0x8c +,0x4e,0x0c,0x9e,0x94,0x8a,0x9c,0xa7,0x95,0x0f,0x0b,0x0e,0x13,0x27,0x0d,0x88,0x2a,0x07,0x03,0x03,0x28,0x17,0x3f,0x0f,0xc8,0x9f,0x13,0x1e,0x3a,0x90,0x8c,0x8c,0x80 +,0x86,0x86,0x1a,0xc2,0x8e,0x8f,0x84,0xa0,0xa3,0x1f,0x02,0x0a,0x13,0x1b,0x0d,0x0e,0x8f,0x28,0x0e,0x02,0x0f,0xa0,0x47,0xa6,0xab,0x8e,0xcd,0x07,0x04,0x19,0xa4,0x1e +,0x22,0x8d,0xaf,0x15,0x00,0x12,0xc0,0xaf,0xb2,0x3a,0x9e,0x1d,0x06,0x06,0x23,0x92,0x3c,0x2f,0x84,0x96,0x25,0x07,0xad,0x83,0x8a,0x8f,0x8d,0x83,0x89,0x29,0x1b,0x8c +,0x89,0x92,0x9a,0x82,0x8c,0xe8,0x03,0x12,0x93,0x9c,0x2a,0x1c,0x2e,0x19,0x08,0x04,0x14,0x1d,0xf8,0x3f,0x84,0x8b,0xaa,0x18,0x23,0x80,0x85,0x85,0x86,0x83,0x8e,0xc0 +,0x16,0xcc,0x9d,0x63,0x0b,0x1d,0xa4,0x04,0x02,0x00,0x0d,0x0e,0x21,0x0f,0x0b,0x0d,0x03,0x05,0x0f,0x31,0xb1,0x20,0x33,0x82,0x55,0x1f,0x09,0xc6,0x95,0x98,0x8c,0x9e +,0x8e,0xe9,0x1b,0x35,0x90,0x94,0xc7,0x16,0x8a,0x8b,0xbd,0x0b,0x12,0x8c,0xa7,0x91,0xb6,0x97,0xba,0x2f,0x13,0x32,0x8c,0x9a,0x20,0xa7,0x83,0x6a,0x22,0x09,0x34,0x9c +,0x9b,0xd3,0xbd,0x42,0x1b,0x0f,0x0d,0x2e,0x2d,0x1f,0x0c,0x95,0xac,0x14,0x09,0x23,0x86,0x84,0x87,0x8f,0x84,0x8a,0x97,0x9c,0x88,0x82,0x85,0xaa,0x96,0x80,0x95,0x20 +,0x01,0x37,0x18,0x11,0x08,0x09,0x26,0x03,0x05,0x00,0x0e,0x18,0x0a,0x00,0x5b,0xb4,0x0c,0x06,0x0c,0xae,0xd1,0x29,0x13,0xb6,0x3a,0x12,0x0c,0x3c,0x97,0xb3,0x44,0x32 +,0x82,0x87,0x9b,0x13,0xaf,0x8f,0xa7,0x9c,0x99,0x83,0x99,0xde,0x45,0x92,0x92,0xd3,0x0f,0x9c,0x80,0x8a,0x9f,0x15,0x91,0x99,0xb3,0xbd,0xa9,0xa1,0x18,0x0d,0x0e,0xba +,0x2b,0x10,0x12,0xa4,0x98,0x0c,0x04,0x06,0x17,0x11,0x0f,0x99,0x89,0x9d,0x18,0x2d,0x8e,0x87,0x8f,0x9e,0x8d,0x80,0x86,0x8f,0xaa,0x97,0x93,0x27,0x69,0x9d,0xab,0x14 +,0x0a,0x08,0x1c,0x13,0x13,0x09,0x25,0x95,0x17,0x06,0x03,0x12,0x15,0x36,0x22,0xad,0xc5,0x0d,0x09,0x12,0x1b,0x24,0x1e,0x14,0x8c,0x8c,0x2b,0x0a,0x1d,0x95,0xa9,0x8f +,0x90,0x96,0xa4,0x18,0x30,0x9f,0x8d,0x95,0xc0,0x93,0x85,0x8f,0x48,0x15,0xa9,0xa0,0x99,0x9e,0x8e,0x89,0xbe,0x17,0x0e,0xaf,0xc4,0xde,0x15,0x99,0x8b,0x4a,0x0e,0x04 +,0x27,0x2b,0x1d,0x1d,0x4d,0x22,0x0d,0x0e,0x9e,0x8f,0x92,0x94,0x99,0x80,0x89,0x97,0x65,0x9a,0x83,0x8f,0x8e,0x8d,0x8d,0x24,0x0c,0x08,0x11,0x12,0x05,0x02,0x1b,0x93 +,0x13,0x02,0x02,0x0f,0x1b,0x0f,0x14,0x51,0x55,0x0f,0x04,0x0e,0xad,0xbb,0x24,0x1a,0x96,0x90,0xbf,0x1c,0x1b,0xa0,0x9f,0x96,0x95,0x85,0x8c,0x73,0xcd,0xa9,0x9d,0xa4 +,0x30,0x9e,0x81,0x8c,0xbb,0x16,0xbb,0xaa,0xc2,0xb9,0x92,0x90,0x3f,0x16,0x1d,0xa5,0x49,0x27,0x32,0x87,0x8b,0x1e,0x06,0x09,0xf8,0x54,0x2c,0x46,0x38,0x11,0x0a,0x0b +,0x1c,0xe4,0xd9,0x2e,0xaa,0x82,0x8a,0x95,0xac,0x92,0x89,0x89,0x85,0x88,0x87,0x92,0xa8,0x31,0xa9,0x25,0x22,0x10,0x2f,0xaf,0x04,0x02,0x01,0x08,0x0d,0x2e,0x36,0x2f +,0x0f,0x05,0x04,0x0d,0x24,0x19,0x19,0x30,0x8b,0xa1,0x0e,0x05,0x18,0xa7,0x9f,0x9b,0xaf,0xa7,0x3c,0x23,0xaa,0x93,0x9c,0xd1,0x4b,0x8c,0x84,0xab,0x10,0x16,0x95,0x94 +,0x8d,0x88,0x89,0x92,0x26,0x1d,0xa5,0x90,0xa2,0xad,0x9f,0x83,0x96,0x1f,0x0e,0x1c,0xa2,0x53,0xbc,0x3d,0x4e,0x0d,0x07,0x14,0x2e,0x20,0x0e,0x0c,0x1f,0x9f,0x0f,0x0e +,0x25,0x91,0x89,0x8a,0x84,0x85,0x88,0x9d,0x93,0x8a,0x8b,0x9f,0x99,0x95,0x88,0x5c,0x04,0x06,0x0c,0x37,0x15,0x1c,0x14,0x0c,0x05,0x07,0x17,0x2f,0x1b,0x12,0x0c,0x24 +,0xbd,0x08,0x07,0x0a,0xb9,0x9e,0xb0,0x5f,0x6a,0x6a,0x18,0x18,0x44,0x9c,0x9c,0xa2,0xbb,0x8a,0x9a,0x29,0x24,0xa4,0x8c,0xa7,0xaf,0xac,0x96,0xac,0x2b,0xbc,0x92,0x9b +,0xa9,0x43,0x8e,0x8d,0x17,0x0e,0x26,0x88,0x93,0xa1,0xc7,0xa0,0xa6,0x15,0x0f,0x23,0x3d,0x43,0x16,0x3a,0x96,0x0d,0x08,0x03,0xb9,0xae,0x61,0xa2,0x93,0x8a,0xa9,0x9b +,0x8e,0x88,0x87,0x8d,0x8e,0x80,0x98,0xdf,0x28,0x9f,0xd2,0x1a,0x2f,0xb4,0xbe,0x08,0x01,0x02,0x0a,0x0d,0x0d,0x14,0x94,0x19,0x04,0x03,0x1e,0xba,0x10,0x0c,0x24,0x97 +,0x36,0x0f,0x11,0x2c,0x33,0x3c,0x4e,0x82,0x9c,0x1c,0x0d,0xb8,0x8a,0xa5,0x91,0x92,0x85,0x9a,0x31,0x29,0xa4,0x9a,0xa3,0x9c,0x80,0x93,0x54,0x19,0xb1,0x8e,0xf3,0x9e +,0xa4,0x8a,0x91,0x27,0x19,0x2f,0xc4,0xa4,0x37,0x8d,0x29,0x11,0x0c,0x0f,0x4f,0x10,0x1f,0x31,0x9a,0x4b,0x0e,0x0d,0x17,0xb3,0x8f,0x8f,0x80,0x92,0x94,0x9f,0x8a,0x83 +,0x8c,0x87,0x86,0x85,0xad,0x15,0x14,0x18,0x15,0x13,0x27,0x90,0x0a,0x02,0x06,0x21,0x03,0x0a,0x8a,0xb8,0x9b,0x1a,0x05,0x0d,0x04,0x0f,0x0e,0x5d,0xc9,0x06,0x06,0x00 +,0x0b,0x05,0x07,0x07,0x0c,0x24,0x0b,0x03,0x08,0x0b,0x1e,0x1c,0xa3,0x87,0x9e,0x2b,0x16,0x8d,0xaa,0x9c,0x80,0x80,0x81,0x8f,0x90,0x81,0x83,0x82,0x83,0x80,0x80,0x81 +,0x90,0x9f,0x85,0x86,0x86,0x86,0x82,0x85,0x9d,0x3a,0xa2,0xa5,0x99,0xa9,0x82,0x8b,0x32,0x09,0x07,0x13,0x0f,0x21,0x0f,0x32,0x19,0x03,0x02,0x01,0x01,0x02,0x0b,0xa8 +,0x0f,0x00,0x01,0x00,0x00,0x01,0x04,0x0d,0x0e,0x02,0x01,0x01,0x02,0x03,0x01,0x1b,0x97,0x17,0x06,0x02,0x16,0x14,0x0e,0x38,0x8c,0x8e,0xa8,0xac,0xab,0x9b,0x9e,0x89 +,0x80,0x80,0x83,0x92,0x90,0x81,0x85,0x84,0x83,0x80,0x82,0x85,0x86,0x87,0x88,0x88,0x83,0x80,0x80,0x82,0x8f,0x89,0x86,0x8b,0x85,0x83,0x80,0x84,0x91,0x8f,0x8e,0x8c +,0x9c,0x8a,0x80,0x82,0x8d,0x2a,0x9e,0xaf,0xaf,0xa5,0x98,0x93,0x26,0x0c,0x0a,0x05,0x06,0x01,0x1a,0x33,0x0d,0x06,0x00,0x02,0x00,0x02,0x04,0x07,0x06,0x01,0x01,0x00 +,0x00,0x00,0x01,0x1e,0x0c,0x05,0x02,0x01,0x02,0x01,0x05,0x0d,0x15,0x05,0x01,0x02,0x02,0x04,0x01,0x11,0xa8,0x29,0x0e,0x05,0x0c,0x0b,0x06,0x1b,0xa4,0x99,0x48,0x1d +,0x1b,0x28,0x5f,0x2e,0x8c,0x83,0x85,0x8c,0x9a,0x8e,0x98,0x8a,0x84,0x81,0x81,0x85,0x8a,0x8d,0x8e,0x8e,0x8a,0x80,0x80,0x82,0x88,0x88,0x86,0x89,0x85,0x82,0x81,0x82 +,0x84,0x86,0x88,0x8a,0x8c,0x86,0x80,0x82,0x85,0x95,0x94,0xaa,0xb2,0x99,0x92,0x97,0xbe,0x27,0x18,0x0c,0x0e,0x0b,0x71,0xa1,0x2f,0x2a,0x12,0x21,0x0b,0x18,0xd7,0x99 +,0x9f,0x37,0x32,0x37,0x43,0xc6,0xaa,0x8a,0x87,0x8f,0x93,0x9e,0x94,0xa5,0x9c,0x8a,0x83,0x8b,0x9b,0xb2,0xb7,0x49,0xe3,0x29,0x94,0x97,0xbf,0x26,0x0e,0x12,0x05,0x08 +,0x0c,0x18,0x0b,0x04,0x03,0x03,0x01,0x02,0x00,0x0e,0x0a,0x04,0x03,0x02,0x03,0x00,0x02,0x05,0x0d,0x04,0x02,0x01,0x02,0x00,0x01,0x00,0x0c,0x0b,0x04,0x03,0x03,0x04 +,0x00,0x02,0x06,0x0e,0x08,0x06,0x05,0x07,0x04,0x06,0x08,0x2d,0x2a,0x1d,0x27,0x38,0xbc,0x2c,0xa4,0x92,0x87,0x88,0x88,0x85,0x88,0x8a,0x8a,0x86,0x80,0x81,0x82,0x82 +,0x82,0x82,0x85,0x82,0x82,0x81,0x81,0x81,0x80,0x82,0x87,0x84,0x83,0x80,0x81,0x82,0x80,0x81,0x82,0x89,0x85,0x83,0x83,0x86,0x85,0x83,0x87,0x8f,0x8d,0x8d,0x86,0x87 +,0x8c,0x84,0x85,0x84,0x90,0x8c,0x87,0x87,0x89,0x8d,0x8a,0x8c,0x9f,0x9e,0xa6,0x97,0x9e,0x1a,0x2a,0x23,0x1c,0x08,0x04,0x05,0x05,0x05,0x02,0x02,0x01,0x00,0x00,0x00 +,0x00,0x03,0x00,0x01,0x01,0x02,0x01,0x00,0x00,0x00,0x02,0x03,0x02,0x03,0x02,0x01,0x02,0x02,0x0d,0x08,0x0b,0x11,0x16,0x1b,0x0f,0x1e,0x20,0x4c,0xad,0xa9,0xa9,0xbe +,0xbb,0xa4,0xaf,0x93,0x8d,0x95,0x8c,0x8e,0x8c,0x9a,0x9d,0x9a,0x98,0x93,0x93,0x97,0x9a,0x9d,0x9c,0xa0,0x9f,0x90,0xa5,0x95,0x8e,0x8b,0x8e,0xa3,0x96,0x91,0x90,0x94 +,0x9a,0x96,0x9b,0xa2,0xa8,0xe4,0x98,0xaa,0xaf,0x99,0x9f,0xb1,0x17,0x18,0x22,0x29,0x24,0x19,0x1f,0x21,0x11,0x0f,0x0c,0x1a,0x2c,0x13,0x2a,0x46,0xba,0x2e,0x1a,0x20 +,0x3c,0xc7,0x32,0x35,0xdf,0x79,0x2a,0x25,0x26,0xb3,0x56,0x31,0xb9,0xa8,0xb0,0x28,0x1d,0x36,0xbe,0x49,0x2e,0x2b,0x6f,0x30,0x2f,0x29,0x28,0xb4,0xd8,0xaa,0xa2,0xa5 +,0xa8,0xd0,0xad,0x9b,0x96,0x99,0xa1,0xa6,0x9b,0x9d,0x9b,0x9e,0x8e,0x86,0x88,0x86,0x89,0x8a,0x8d,0x8d,0x89,0x84,0x83,0x85,0x88,0x8d,0x90,0x9a,0xa0,0xaf,0x9a,0x94 +,0xa8,0xbd,0x22,0x1b,0x14,0x12,0x17,0x15,0x0e,0x08,0x07,0x06,0x08,0x05,0x05,0x06,0x0b,0x0e,0x0a,0x06,0x04,0x06,0x0a,0x0f,0x14,0x13,0x13,0x14,0x0f,0x19,0x1a,0x1d +,0x27,0x37,0xa3,0x9b,0xa3,0xaf,0xa0,0x98,0x93,0x8f,0x8e,0x90,0x8e,0x90,0x91,0x90,0x91,0x8e,0x8f,0x8d,0x91,0x99,0xa7,0xac,0x9f,0x9d,0x99,0x9f,0xc4,0x52,0x3f,0xda +,0xce,0x3d,0xe6,0xbe,0xae,0xbb,0x37,0x36,0xdb,0xb4,0xb8,0xc0,0xe4,0x31,0x22,0x21,0x2b,0x38,0x32,0x2b,0x4e,0x43,0x21,0x12,0x0c,0x12,0x1c,0x1e,0x1b,0x17,0x14,0x0f +,0x0d,0x0c,0x0e,0x15,0x14,0x23,0x38,0x3d,0x1e,0x1a,0x28,0xcf,0xa9,0xac,0xa9,0xca,0x58,0xd8,0xaf,0xa5,0xa1,0xaa,0x9f,0x97,0x99,0xa6,0xcb,0xc3,0xac,0x9e,0x9d,0xa3 +,0xba,0x3c,0x2d,0x34,0xcc,0xc1,0x4c,0x46,0x49,0xc8,0xfa,0x46,0x3f,0x5e,0xb7,0xaa,0xab,0x3c,0x24,0x2b,0x3b,0xbe,0xaf,0xa3,0x9e,0x9f,0x9f,0xa2,0x9b,0x9d,0x9a,0x8f +,0x89,0x88,0x8f,0x96,0x94,0x8f,0x93,0x9b,0x99,0x95,0x96,0x9f,0xb3,0xd3,0x71,0x36,0x27,0x3a,0x25,0x0f,0x09,0x09,0x0f,0x0f,0x0a,0x0a,0x0a,0x0b,0x0a,0x08,0x07,0x06 +,0x08,0x0d,0x16,0x12,0x0b,0x09,0x0a,0x11,0x18,0x19,0x1e,0x28,0x29,0x3b,0xc6,0xb6,0xaf,0xa8,0x94,0x8c,0x8e,0x9a,0xa3,0x98,0x92,0x8d,0x8b,0x8a,0x89,0x8f,0x92,0x8f +,0x94,0x95,0x99,0x8f,0x8c,0x91,0x9a,0xad,0xbe,0xdc,0xc7,0xa8,0xaf,0xae,0xbd,0xbe,0xb3,0xe0,0x3a,0x46,0xb2,0xa6,0xac,0xef,0x2f,0x39,0x2a,0x2c,0x5e,0xc8,0xce,0x30 +,0x33,0x37,0x1f,0x0d,0x0e,0x1b,0x2a,0x29,0x19,0x0f,0x0c,0x09,0x0b,0x0f,0x11,0x0f,0x0f,0x17,0x26,0x23,0x16,0x15,0x21,0xd5,0xaa,0xb7,0x3b,0x32,0x2c,0xc8,0x9b,0x9b +,0xaa,0xac,0xa5,0x9b,0xa3,0x6c,0x5b,0xbd,0xa3,0x9b,0x9b,0xa8,0xcc,0x40,0xc9,0xa6,0xa7,0x3f,0x52,0xac,0x99,0x9b,0xbd,0x6e,0xbf,0xb3,0xa8,0xa3,0xc7,0x35,0x2d,0x78 +,0xa3,0xa0,0xea,0x44,0xbb,0x9b,0x98,0xb6,0xb7,0xa8,0x99,0x8d,0x89,0x8b,0x94,0x9b,0x99,0x8b,0x8c,0x96,0x99,0x95,0x8f,0x8e,0x94,0xab,0xc7,0x46,0xbb,0xcf,0x21,0x11 +,0x0b,0x0a,0x0e,0x0e,0x09,0x08,0x08,0x08,0x09,0x08,0x05,0x05,0x05,0x0b,0x19,0x12,0x0a,0x09,0x0b,0x17,0x18,0x14,0x1b,0x1f,0x2e,0xcd,0xb9,0xb6,0xb7,0xbc,0xa3,0x90 +,0x96,0xa3,0xa5,0xa3,0x8f,0x8b,0x90,0x94,0x96,0x92,0x8e,0x8f,0x96,0x94,0x95,0x92,0x8b,0x8c,0x94,0x9c,0xac,0xa7,0x96,0xa0,0xa3,0xa6,0xaf,0x96,0x99,0xbc,0xde,0x57 +,0xae,0xa4,0xbf,0x37,0x2f,0x26,0x2d,0xb5,0xcd,0x3e,0x2f,0x20,0x4c,0xdc,0x22,0x1d,0x16,0x1d,0x41,0x32,0x1a,0x16,0x12,0x12,0x20,0x15,0x0f,0x0e,0x0c,0x17,0x21,0x1b +,0x18,0x17,0x15,0x26,0x40,0x1b,0x18,0x18,0x25,0x9f,0xa8,0xcf,0xb0,0xca,0xa6,0x9d,0xb6,0xaa,0xa4,0xb5,0x9c,0x90,0x98,0xad,0x4f,0x45,0x97,0x97,0xbb,0x4d,0x29,0xc7 +,0xa2,0xad,0xbd,0xbd,0x30,0xe3,0xb4,0x3c,0x31,0x1d,0x1e,0xa4,0x9a,0xb4,0xba,0x50,0xaa,0x93,0x9e,0xa9,0x9d,0x9d,0x91,0x88,0x8d,0x91,0x93,0x9f,0x8d,0x8a,0x94,0x94 +,0x99,0x99,0x8e,0x90,0x9d,0xa5,0x65,0xf9,0xbb,0x2d,0x19,0x0f,0x0a,0x15,0x25,0x13,0x0c,0x08,0x07,0x14,0x12,0x0d,0x09,0x06,0x07,0x0d,0x0e,0x0a,0x0f,0x0c,0x0f,0x14 +,0x08,0x0b,0x0c,0x15,0x47,0xac,0xb4,0x1f,0x1d,0x1a,0x96,0x9e,0xa5,0xaf,0x58,0x9b,0x8f,0x95,0x97,0x9a,0x97,0x8a,0x8c,0x87,0x9c,0x99,0xaa,0x8e,0x8a,0x98,0x97,0xa7 +,0x96,0x95,0xaf,0x2e,0x38,0xa8,0x98,0x94,0x91,0xa2,0xb5,0xbb,0x98,0x97,0xa3,0xba,0x23,0x39,0xb1,0xbe,0x38,0x24,0x23,0x2d,0x3e,0x29,0x1f,0x18,0x13,0x2e,0x34,0x25 +,0x1a,0x0c,0x12,0x25,0x1f,0x0b,0x0b,0x0b,0x1a,0x29,0x22,0x1c,0x1a,0x21,0x27,0xd9,0x1c,0x24,0x1b,0x1d,0xbb,0x45,0x63,0x28,0x19,0x2d,0xb7,0xb9,0x3d,0x34,0x28,0xa1 +,0x98,0x9f,0xcc,0xd7,0xa9,0x9a,0x9a,0x34,0xb4,0xc3,0x9e,0x92,0x98,0xa5,0xab,0x9e,0x99,0x8e,0xa0,0xea,0x62,0x3e,0xa9,0xa4,0xb9,0x2f,0x2d,0x47,0xad,0x9e,0x4e,0x50 +,0xdf,0xa5,0x8c,0x8e,0x9f,0x9a,0x92,0x8c,0x87,0x92,0x9c,0xa8,0xa5,0x8c,0x88,0x8d,0xa7,0xa8,0xab,0x9e,0xa9,0x19,0x13,0x0e,0x0f,0x1b,0x14,0x0d,0x0d,0x0c,0x12,0x1e +,0x0d,0x05,0x06,0x0e,0x2a,0x27,0x0f,0x08,0x11,0x17,0x2a,0x23,0x12,0x14,0x15,0x2b,0xab,0xa3,0xd9,0xc7,0xa7,0x90,0x91,0xad,0x49,0xb5,0xa4,0x9a,0x9c,0xb0,0xb5,0xab +,0x9b,0x90,0x98,0x36,0x1e,0x6c,0x9c,0x91,0xab,0x2c,0x3b,0x56,0xab,0xba,0x27,0x1c,0x27,0x3e,0xa9,0xa9,0x48,0x3d,0xb1,0x9a,0x97,0xad,0x2d,0x2b,0xc3,0x9d,0x91,0xa6 +,0x39,0xe4,0xaa,0x97,0x9a,0xda,0x26,0x3a,0xb9,0x9f,0xae,0x35,0x2a,0x2d,0x3e,0xc5,0x29,0x18,0x1b,0x39,0xb7,0xaf,0x37,0x20,0x42,0xd0,0xae,0xc1,0x23,0x19,0x23,0x44 +,0xa5,0xb4,0x2b,0x27,0x3f,0xca,0xd7,0x23,0x18,0x28,0x4d,0x56,0x40,0x1c,0x16,0x25,0x29,0xec,0x31,0x14,0x11,0x22,0x48,0xc0,0x2e,0x18,0x2a,0xd1,0xb5,0xbd,0x27,0x1d +,0x42,0xbf,0xa7,0x9c,0xb2,0xb3,0xa5,0x9d,0x97,0xa9,0x2a,0x36,0xa4,0x9b,0x9c,0x4a,0x24,0xcd,0xaa,0xa7,0xa2,0xc7,0x41,0xb9,0xa6,0x95,0x8f,0x9c,0x99,0x8e,0x8c,0x8d +,0x9d,0xce,0x9e,0x8f,0x8e,0x8f,0x9a,0x9f,0x9b,0x98,0xa1,0xa5,0x2f,0x1d,0x31,0x3e,0x42,0x23,0x0e,0x11,0x1c,0x17,0x18,0x0d,0x0c,0x10,0x1a,0x20,0x28,0x1e,0x16,0x39 +,0xcb,0x40,0x2a,0x0f,0x1a,0xef,0xb6,0xb2,0x3b,0x20,0x2b,0xe8,0x2f,0x49,0x20,0x12,0x1c,0x23,0x34,0x2c,0x14,0x13,0x28,0x37,0x2d,0x1c,0x0e,0x1c,0x49,0xeb,0xab,0xba +,0x63,0xa7,0x98,0x97,0x96,0xb2,0xdd,0x9d,0x8f,0x8a,0x8d,0x9d,0x9a,0x8f,0x92,0x90,0x9c,0xb4,0xa0,0x99,0x9c,0x9e,0xb5,0x5e,0xae,0xa6,0xa4,0xae,0x25,0x1e,0xbf,0xa4 +,0xa2,0xa7,0x4a,0xb6,0xa6,0xbd,0xca,0x2f,0x20,0x3e,0xbb,0xda,0xec,0x1f,0x1a,0x31,0x53,0x38,0x2a,0x14,0x15,0x2f,0x1f,0x1b,0x17,0x0e,0x17,0x27,0x21,0x1e,0x11,0x0a +,0x14,0x27,0x22,0x2a,0x22,0x2c,0xaf,0xc8,0x38,0x36,0x20,0x33,0xa3,0x9f,0x9f,0xa9,0x4b,0xb3,0x9a,0xa2,0xa3,0xad,0xd1,0xa0,0xa0,0xba,0xb3,0x68,0xea,0xa3,0xa8,0xaf +,0xc1,0x30,0x69,0x9e,0xa5,0xa4,0x9d,0xa3,0x98,0x94,0x9b,0x9b,0xa5,0xb3,0x96,0x92,0x97,0x95,0xa1,0xa4,0x9b,0xa6,0xb7,0xb9,0x3b,0x69,0xbd,0x25,0x1f,0x1e,0x1b,0x2a +,0x28,0x18,0x17,0x11,0x0f,0x1e,0x21,0x20,0x30,0x20,0x22,0xf3,0x3e,0x2d,0x2e,0x29,0xca,0xac,0x5c,0xee,0xe4,0x3e,0xb6,0xb8,0x4b,0xdf,0x2b,0x1f,0x36,0x30,0x20,0x1f +,0x1e,0x33,0xd5,0x24,0x17,0x1b,0x18,0x20,0x38,0x39,0xba,0xbd,0x62,0xae,0xb5,0xd0,0xb7,0xc1,0xa5,0x93,0x96,0x9f,0x9e,0x9d,0x99,0x95,0x9f,0x9f,0x9e,0xba,0xbd,0xad +,0xdb,0xc4,0xec,0xd2,0xaa,0xcf,0x2c,0x2b,0x2c,0x3b,0xc4,0x44,0x46,0xbe,0xbd,0xc0,0xec,0x3a,0x45,0x3c,0x41,0xb2,0xa6,0xdd,0x4c,0xeb,0xd0,0xad,0x4e,0x2d,0x4f,0x3b +,0x30,0x2a,0x1f,0x26,0x2b,0x2b,0x2e,0x2b,0x1d,0x16,0x18,0x1c,0x35,0x4c,0x2a,0x30,0x3b,0x50,0xdb,0x47,0x71,0xb5,0xb8,0xb8,0xb4,0xaf,0xa6,0xa1,0xa6,0x9e,0x9d,0xaa +,0xb5,0xd7,0xc2,0xae,0xbf,0x43,0xd8,0xbf,0xc5,0x45,0x29,0x28,0x2f,0x2c,0x32,0xd7,0xc6,0xc3,0x64,0x48,0xb8,0xb4,0xd0,0xb3,0xac,0xa2,0xa6,0xb7,0xaf,0x9f,0x9b,0x9c +,0x99,0x9d,0xaf,0xf6,0x3c,0xcd,0xc5,0x3f,0x42,0x48,0x42,0x2a,0x1e,0x1b,0x1f,0x1e,0x21,0x2c,0x2f,0x2c,0x2f,0x44,0xc1,0xbc,0x6c,0x51,0xf3,0xb4,0xaa,0xb3,0xbe,0xab +,0x9e,0xa2,0xa5,0xa8,0xc3,0x62,0x38,0x4e,0x4b,0x4d,0x56,0x46,0x3d,0x28,0x26,0x1e,0x1b,0x1d,0x26,0x30,0x2c,0x24,0x2a,0x3a,0xea,0x6c,0xdd,0xbc,0xcb,0xdd,0xe1,0xbb +,0xa9,0x9f,0x9d,0x9c,0x9b,0xa6,0xb9,0xc3,0xc0,0xb2,0xb9,0xce,0xce,0xc4,0x59,0x43,0x37,0x28,0x25,0x23,0x2d,0x49,0x34,0x2f,0x42,0xfb,0xc6,0xcf,0xc7,0xb4,0xb3,0xf1 +,0x6e,0xc6,0xda,0xb9,0xad,0xa5,0x9f,0xb0,0x70,0x3e,0x3b,0x43,0x4d,0x3e,0xd5,0xb6,0x3a,0x2a,0x2d,0x3c,0x39,0x20,0x1e,0x2b,0x25,0x1e,0x2b,0x3c,0xe8,0xdb,0x3b,0x37 +,0x54,0x3e,0x4c,0xcd,0xc8,0xaa,0xac,0xaa,0x9f,0x9e,0xac,0xbc,0xe6,0xcd,0xb1,0xd5,0xbd,0xb6,0x76,0x6b,0x4f,0x3d,0x3d,0x2d,0x24,0x2e,0x2e,0x24,0x30,0x32,0x5f,0xab +,0xb0,0xb3,0xcd,0x2e,0x40,0xb4,0xab,0x9f,0xa0,0xad,0xa1,0x9f,0xb0,0xad,0xc7,0xd6,0xac,0xcb,0xca,0xbf,0x3d,0x4a,0xbb,0xc1,0x4c,0x28,0x1a,0x25,0x2d,0x20,0x2e,0x27 +,0x26,0xc6,0xc7,0xb8,0xc4,0x27,0x2f,0xce,0xb2,0xa3,0x9f,0xae,0x9e,0x9b,0xad,0xa9,0xd4,0x3d,0xb0,0xd8,0xe0,0xc4,0x25,0x26,0x46,0x44,0x6d,0x2f,0x16,0x1e,0x23,0x1b +,0x31,0x35,0x29,0xd4,0x4e,0xfa,0xa9,0x3d,0x2f,0xcb,0x52,0xaa,0xa4,0x5f,0xab,0x9d,0xa3,0x9e,0xba,0x25,0xc8,0xb8,0xbb,0xa4,0x36,0x22,0x44,0x4b,0xb3,0xc2,0x1a,0x1f +,0x2b,0x1d,0x4c,0x5b,0x27,0xcb,0xdd,0x67,0xa7,0x43,0x2d,0xaa,0xbc,0xa0,0x96,0xd5,0xbe,0x9d,0xad,0x9d,0xa1,0x34,0xbb,0x3a,0x21,0xb9,0x41,0x20,0xdc,0x3d,0x56,0xb2 +,0x19,0x19,0x51,0x23,0x59,0xbc,0x1d,0x41,0xba,0x4d,0xa0,0xc8,0x1f,0x68,0x3a,0xe4,0x9c,0x43,0x2d,0xa5,0xc1,0x9f,0x9b,0x29,0x4a,0x5c,0x1f,0xb0,0xb6,0x1c,0x48,0x4f +,0x5d,0x9f,0x23,0x15,0x2f,0x1c,0x39,0xa7,0x1e,0x2a,0xbd,0x3d,0x9a,0x9c,0x2a,0xb9,0xb8,0x45,0x97,0xc0,0x2b,0x9a,0xa4,0x9d,0x92,0x34,0x28,0xbe,0x23,0xb2,0x9e,0x1b +,0x33,0xcb,0x42,0x98,0xba,0x18,0x32,0x1f,0x28,0x99,0x39,0x1f,0xba,0x3c,0x9e,0x94,0x24,0x35,0xbe,0x34,0x9a,0x9e,0x28,0xae,0xad,0xb2,0x8f,0xbd,0x1e,0x57,0x1d,0x4d +,0x9d,0x1c,0x1e,0x4a,0x20,0xae,0xb1,0x18,0x30,0x2b,0x1e,0xa3,0x3c,0x0f,0x70,0x4b,0xa8,0x8d,0x5b,0x2e,0xb6,0x27,0xaa,0x9b,0x1e,0x45,0xbf,0xd2,0x8d,0xa1,0x13,0x27 +,0x1c,0x2d,0x95,0x2e,0x17,0xb9,0x44,0xab,0x99,0x1a,0x20,0x6d,0x30,0x98,0xad,0x0e,0x27,0x4d,0xb3,0x8c,0xa6,0x2d,0xa8,0x35,0xcc,0x96,0x29,0x3c,0xa7,0xc5,0x94,0x9a +,0x1c,0x26,0x26,0x32,0x97,0xda,0x15,0x2a,0x22,0xdc,0x90,0xcc,0x2a,0x49,0x1d,0xaf,0x9f,0x1b,0x1f,0x28,0x2f,0x96,0x9d,0x28,0x30,0x1b,0x2d,0x95,0xc9,0x28,0xda,0x3b +,0x9f,0x95,0x31,0x2d,0x34,0x25,0x9d,0x9f,0x1d,0x23,0x25,0x2a,0x9a,0xad,0x1e,0x33,0x21,0xc7,0x9f,0x1e,0x1e,0xe1,0x39,0x9a,0x98,0x29,0x28,0x26,0xc6,0x8e,0x9d,0x36 +,0x43,0x2d,0xa1,0x91,0xba,0x30,0x2d,0x23,0xad,0x9d,0x40,0x38,0x33,0x2f,0xa2,0xab,0x23,0xaa,0xad,0x9e,0x9a,0x17,0x14,0x25,0x34,0x9f,0x9d,0x37,0x3b,0x30,0x22,0xc8 +,0xc8,0x2b,0x64,0x4d,0xbb,0x96,0x7b,0x28,0x33,0x29,0xb3,0xab,0x4f,0xa6,0xa0,0x2a,0x27,0x2c,0xc3,0x9d,0x4c,0x21,0x2e,0x2e,0x29,0x4a,0x23,0x30,0xa9,0xa9,0x99,0x3a +,0x0c,0x16,0xaf,0x98,0x98,0x0c,0x17,0x86,0x8a,0xa0,0x0a,0x01,0x27,0x87,0x84,0x9a,0x16,0x0a,0xea,0x9d,0xeb,0x49,0x23,0xd8,0x98,0xac,0x1e,0x0c,0x16,0xc9,0x8f,0xa0 +,0x2c,0x37,0x2c,0xac,0x9a,0x39,0xcd,0xbe,0xad,0x99,0xc8,0xad,0xa2,0xd8,0x1a,0x2a,0x2f,0xb7,0x9c,0x4b,0x38,0x43,0x24,0x6f,0xd5,0x37,0x95,0xa9,0x2c,0x20,0x17,0x1b +,0x38,0x0f,0x9e,0x83,0x99,0x60,0x02,0x04,0x2e,0x87,0x87,0x92,0x46,0x10,0x1d,0x2a,0x71,0x9d,0xad,0x99,0x8d,0xeb,0x14,0x14,0x37,0xaa,0x9c,0x24,0x11,0x0d,0x9d,0x85 +,0x9a,0x10,0x01,0x20,0x9b,0x80,0x8e,0x22,0x17,0x2d,0x97,0xa1,0x1a,0x22,0xa9,0x8a,0x95,0x1f,0x06,0x0f,0x24,0x25,0x1c,0x14,0x88,0x82,0x8d,0x11,0x00,0x08,0xaa,0x84 +,0x85,0x9d,0x1e,0x13,0x17,0x31,0xa2,0x8c,0x87,0x88,0x61,0x1e,0x0d,0x01,0x06,0x0f,0x8f,0x80,0x8f,0xb9,0x05,0x00,0x0c,0xad,0x82,0x86,0x8f,0x21,0x17,0x2d,0xab,0x8f +,0x93,0x8d,0x98,0x0e,0x0b,0x02,0x0a,0x13,0x0e,0x88,0x80,0x89,0x16,0x00,0x05,0x3e,0x81,0x8d,0xdc,0xc3,0xa0,0x97,0x9e,0x3b,0x3f,0x13,0x67,0xa3,0x20,0x0a,0x00,0x21 +,0x94,0x82,0x80,0x8f,0x16,0x00,0x0a,0x29,0xa5,0x8d,0x8e,0x96,0x8d,0x90,0x1e,0x06,0x30,0x9d,0xa0,0x24,0x0f,0x1d,0x0d,0x1e,0xce,0x86,0x8a,0x13,0x03,0x02,0x12,0x24 +,0xa5,0x97,0x8b,0x90,0xa1,0x39,0x16,0x2e,0x29,0xb1,0x8d,0x91,0xaf,0x18,0x14,0x9b,0x85,0x80,0x8b,0x17,0x00,0x09,0x16,0x3d,0xa5,0x97,0x9c,0x9d,0x3f,0x06,0x00,0x07 +,0x43,0x95,0xa1,0x4c,0x17,0x0c,0x1c,0x90,0x81,0x90,0x91,0x2e,0x1b,0x19,0x3b,0x96,0x92,0x87,0x81,0xa3,0x09,0x06,0x17,0x9a,0x93,0xa8,0x15,0x19,0x18,0x22,0x37,0x8d +,0x94,0xdc,0x16,0x06,0x0e,0x14,0xb8,0x99,0x8c,0x8e,0x98,0x24,0x15,0x4b,0x99,0x8b,0x96,0x3a,0x10,0x0e,0x26,0xa5,0x81,0x87,0xa5,0x0a,0x00,0x03,0x0f,0x9d,0x9e,0xaf +,0xb3,0xa8,0x15,0x07,0x17,0x8f,0x82,0x86,0xbc,0x18,0x0e,0x2c,0x91,0x83,0x86,0x97,0x1d,0x04,0x0d,0x20,0xb3,0xc0,0x95,0x8e,0x9c,0x13,0x03,0x0c,0xa4,0x83,0x85,0xe4 +,0x09,0x04,0x0c,0x2d,0x8a,0x8d,0x2f,0x0e,0x03,0x0f,0x0f,0x2b,0xba,0x98,0x86,0x89,0x5c,0x03,0x12,0x8c,0x80,0x81,0x9b,0x1d,0x0e,0x22,0x2d,0x8d,0x8e,0xc8,0x26,0x0a +,0x0d,0x0e,0xce,0x97,0x92,0x9b,0x29,0x08,0x03,0x09,0xa5,0x88,0x8c,0xc8,0x1e,0x0f,0x14,0x1e,0x8d,0x8c,0x96,0x34,0x0a,0x23,0x50,0x8f,0x90,0x8e,0x8f,0x98,0xd6,0x0e +,0x0c,0xa7,0x89,0x87,0xd7,0x0c,0x04,0x05,0x13,0x8f,0x8f,0x4a,0x10,0x04,0x13,0x2a,0x92,0x91,0x95,0x8f,0x92,0x6a,0x0a,0x0c,0xa9,0x84,0x81,0x9a,0x1c,0x09,0x0d,0x16 +,0x8f,0x8e,0xa6,0x1f,0x0a,0x1a,0x19,0xc6,0xbf,0xa9,0x98,0xa6,0x10,0x00,0x0b,0x9e,0x83,0x87,0xab,0x12,0x08,0x13,0x4c,0x85,0x84,0x8a,0xaa,0x21,0x26,0x1e,0xc3,0xa0 +,0x8d,0x8b,0x99,0x1d,0x0b,0x0a,0x1b,0x9c,0xa3,0x26,0x0b,0x03,0x04,0x0b,0x92,0x96,0xa3,0x2d,0x16,0x1e,0x1b,0x9a,0x8b,0x88,0x8a,0x95,0x77,0x1d,0x1f,0xa6,0x87,0x89 +,0xb1,0x10,0x10,0x1c,0xd9,0x89,0x8e,0x92,0x1a,0x0a,0x0b,0x17,0xb9,0xc1,0xa1,0xa4,0xcc,0x18,0x07,0x07,0x1b,0x9a,0x95,0x69,0x14,0x05,0x0a,0x48,0x82,0x82,0x83,0x28 +,0x0f,0x1a,0x2a,0xa9,0x98,0x87,0x8d,0x91,0x52,0x12,0x0e,0x14,0xb8,0x96,0x9f,0x30,0x0e,0x0f,0x1b,0x99,0x9b,0x9e,0x28,0x0e,0x0c,0x24,0xa0,0x97,0x8f,0x9a,0x9e,0x3a +,0x0d,0x0a,0x18,0x99,0x8c,0x9c,0x3a,0x0e,0x17,0x2d,0x88,0x85,0x85,0x34,0x09,0x0c,0x15,0xb9,0xbf,0xa8,0xa2,0x9f,0x23,0x07,0x07,0x13,0x9f,0x8d,0x94,0xae,0x18,0x14 +,0x24,0x87,0x84,0x83,0x61,0x13,0x1a,0x22,0x95,0x96,0x8e,0x97,0xc9,0x1c,0x0a,0x08,0x0c,0x2b,0xa1,0x9b,0xb3,0x0e,0x09,0x0c,0x99,0x8e,0x96,0x18,0x08,0x0d,0x1f,0x94 +,0x9b,0x99,0xa0,0x9d,0xae,0x29,0x2b,0xaf,0x8c,0x86,0x94,0xc7,0x1b,0x1e,0x21,0x8e,0x83,0x89,0x4d,0x05,0x05,0x10,0x6c,0x69,0x7e,0x2d,0x1c,0x15,0x0d,0x10,0x19,0xdb +,0x9a,0x97,0x9c,0x16,0x11,0x17,0x8d,0x82,0x84,0x9e,0x07,0x09,0x0e,0xad,0x8b,0x89,0x8f,0xac,0xc8,0x25,0x21,0x42,0xab,0x94,0xa4,0xb4,0x15,0x13,0x0d,0xba,0x8e,0x8e +,0xa6,0x07,0x08,0x08,0x69,0x9c,0xa2,0xb0,0x26,0xd5,0x41,0xc3,0xa8,0xbd,0x9d,0xae,0xa9,0x1f,0x12,0x11,0xb4,0x83,0x83,0x9a,0x05,0x01,0x06,0xc8,0x88,0x8a,0x8f,0xb3 +,0x2e,0x15,0x15,0x33,0x54,0x9b,0xab,0xa7,0xea,0x28,0x1e,0x1e,0x8a,0x8c,0x8e,0x1a,0x02,0x07,0x16,0x92,0x8d,0x8e,0x9d,0xaf,0xba,0x28,0x27,0x33,0xd6,0xac,0xbd,0x2f +,0x0d,0x07,0x07,0xee,0x96,0x9b,0x21,0x04,0x0c,0x2b,0x8a,0x8a,0x90,0xa3,0x4b,0x9f,0x9a,0x8f,0x99,0xae,0x9f,0xa9,0x96,0xc6,0x1d,0x16,0x45,0x8b,0x8f,0xda,0x04,0x01 +,0x0c,0x9e,0x89,0x9d,0x1d,0x0d,0x19,0x20,0x28,0x2c,0x29,0xca,0x44,0xcc,0x21,0x14,0x10,0x20,0x8a,0x8b,0x88,0xd0,0x28,0x30,0x9b,0x86,0x8d,0x94,0x5a,0x3d,0xbe,0xbb +,0xaa,0xe5,0x3b,0x39,0x22,0x1c,0x0b,0x06,0x05,0xb5,0x8e,0x88,0x2f,0x09,0x0d,0x41,0x86,0x8c,0x94,0x31,0x28,0x3a,0xbc,0x9e,0x4c,0x32,0x22,0x23,0x54,0x17,0x11,0x13 +,0x92,0x87,0x86,0xa4,0x0e,0x0d,0x1d,0x8f,0x8e,0x9a,0x1d,0x14,0x25,0xaf,0x96,0xa9,0xcb,0x24,0x2e,0xc5,0x1a,0x1a,0x0b,0xab,0x87,0x82,0x8f,0x13,0x0f,0x19,0x96,0x90 +,0xa7,0x25,0x1b,0x2e,0xc1,0x4a,0x1e,0x16,0x14,0x19,0x3a,0x1e,0x19,0x0a,0x77,0x88,0x83,0x8d,0x0f,0x0d,0x13,0x8e,0x85,0x8d,0xad,0x1c,0xfe,0xa8,0x98,0xa3,0x2a,0x2e +,0x55,0x9f,0xfb,0x20,0x0c,0x30,0x8b,0x84,0x8d,0x10,0x08,0x08,0xc0,0x96,0xa9,0x19,0x05,0x0b,0x15,0xe9,0x3e,0x22,0x3e,0x33,0xa0,0x2b,0x17,0x0e,0xa4,0x80,0x80,0x87 +,0x19,0x0d,0x11,0x90,0x82,0x86,0x9e,0x16,0x1a,0x3b,0xa2,0x49,0x1a,0x1a,0x26,0xaa,0x23,0x0f,0x02,0x13,0x94,0x8a,0x89,0x1a,0x0d,0x0a,0xc9,0x94,0xa0,0x44,0x14,0x1c +,0x39,0xa9,0xaa,0xad,0xb1,0xcd,0xa2,0x69,0x3f,0x1a,0xc2,0x8c,0x8a,0x8c,0x15,0x0f,0x0e,0xa1,0x93,0xab,0x22,0x0a,0x1e,0x46,0xa7,0xa7,0xb9,0xa8,0xa0,0x98,0xb1,0x2f +,0x15,0xd8,0x8d,0x88,0x8d,0x17,0x09,0x06,0x2d,0x9f,0xa4,0x29,0x0a,0x16,0x1d,0xc3,0x43,0x22,0x37,0xe1,0x98,0x3f,0x18,0x0e,0xea,0x8d,0x88,0x8b,0xfd,0x22,0x1a,0x9e +,0x91,0x8c,0xa6,0x28,0xda,0xb6,0x99,0xde,0x37,0xce,0xaa,0x99,0x23,0x0e,0x04,0x26,0x91,0x8b,0x9d,0x0a,0x04,0x05,0x25,0xa9,0x9e,0x3e,0x1b,0x22,0x3e,0xa0,0xac,0xa9 +,0xd0,0xb9,0x98,0xa7,0xc8,0x11,0xbe,0x90,0x89,0x93,0x18,0x0f,0x0f,0xae,0x92,0x8e,0x9e,0x2b,0x2e,0x3f,0xa3,0xa6,0xa3,0xad,0xaa,0xbe,0x27,0x18,0x0a,0xee,0xa3,0x8f +,0xc9,0x09,0x07,0x07,0xc2,0x98,0x9b,0x31,0x0e,0x1e,0x3d,0xa8,0x4a,0x37,0xbd,0x9c,0x91,0xa5,0x2f,0x14,0xa5,0x8d,0x83,0x9c,0x1f,0x0d,0x10,0x9c,0x8e,0x89,0xbc,0x19 +,0x21,0x3b,0x99,0xae,0xb3,0x3b,0x3b,0x3e,0x1e,0x10,0x0d,0xd9,0xa5,0x9c,0x17,0x09,0x06,0x1a,0x9e,0x93,0x8f,0xe4,0x3a,0x24,0x45,0xa0,0xb0,0x98,0xab,0x9e,0xb6,0x38 +,0x18,0x19,0xa2,0x90,0x8b,0x45,0x13,0x09,0x27,0x98,0x89,0x89,0xaf,0x2d,0x1d,0x45,0xbe,0xea,0xaf,0x26,0x2f,0x17,0x1d,0x15,0x2a,0xa9,0x9e,0x96,0x24,0x13,0x08,0x27 +,0x9f,0x8c,0x8e,0xeb,0x1c,0x14,0x3a,0xbe,0xb4,0xb0,0xe7,0xbd,0x28,0x20,0x13,0xb1,0x93,0x8b,0x98,0x17,0x0d,0x0a,0xb8,0x92,0x85,0x8a,0xa9,0x3d,0x36,0x9c,0x9d,0xa7 +,0x31,0x25,0x36,0x26,0x17,0x0a,0x2b,0xb2,0x8b,0x9b,0x1a,0x08,0x03,0x1d,0xab,0x8a,0x97,0xdf,0x1a,0x11,0x31,0x4b,0xa4,0x40,0x2f,0x22,0x29,0x33,0xd0,0x8f,0x8e,0x85 +,0x99,0x3a,0x0d,0x17,0x9b,0x8a,0x83,0x97,0x5c,0x1d,0x28,0xbc,0x5e,0x3d,0x14,0x1b,0x11,0x0e,0x0b,0x1f,0xac,0x96,0x8c,0x69,0x1a,0x03,0x0a,0x25,0x8e,0x84,0x8f,0xac +,0x17,0x2b,0xb8,0xa2,0xc3,0x2c,0x47,0x24,0x28,0x15,0xb9,0x99,0x8b,0x8d,0xb3,0x2b,0x0d,0x2c,0xb7,0x8b,0x8b,0x90,0xa3,0x1c,0x2d,0x31,0xc3,0x25,0x19,0x1b,0x19,0x1d +,0x13,0xbd,0x9e,0x8a,0x93,0x4d,0x0f,0x06,0x12,0x59,0x91,0x99,0xaa,0x24,0x11,0x1c,0x2f,0xa3,0x5e,0x3c,0x1c,0x1c,0x2c,0x78,0x8d,0x8b,0x84,0x93,0xa7,0x1f,0x1b,0x41 +,0x9c,0x8d,0x9e,0xad,0x30,0x33,0x3c,0x2d,0x2d,0x1d,0x1f,0x0f,0x13,0x0e,0x1f,0xa2,0x90,0x8b,0xba,0x2b,0x0a,0x0e,0x26,0x9e,0x8d,0x98,0xa9,0x23,0x2c,0x36,0xb6,0xc5 +,0x29,0x29,0x1e,0x30,0x1f,0xae,0x9f,0x89,0x8a,0xa0,0xc3,0x1e,0x52,0x4b,0xa5,0xae,0xaf,0xc3,0x2d,0x4b,0x2d,0xd8,0x75,0x3f,0x1e,0x15,0x24,0x1b,0xb7,0xa7,0x8e,0xa0 +,0x54,0x16,0x0b,0x1c,0x2b,0xb8,0xbc,0x3a,0x1e,0xe0,0xaf,0xc0,0xb9,0xbf,0x4c,0x2e,0x23,0x28,0x26,0x9a,0x8f,0x87,0x8c,0x9b,0x5e,0x17,0x26,0x38,0x9e,0x9d,0xc5,0x27 +,0x1e,0x3c,0x39,0x4c,0x2c,0x2f,0x25,0x1a,0x1a,0x12,0xc7,0x9b,0x89,0x97,0xc9,0x1f,0x13,0x1e,0x2f,0xa2,0xab,0x4e,0x23,0x25,0xb9,0xc3,0xa4,0xaf,0xcb,0x3b,0x1f,0x21 +,0x29,0x98,0x8d,0x84,0x8f,0x5a,0x0f,0x0f,0x33,0xa9,0x96,0xb3,0x41,0x30,0x63,0xa8,0xa5,0x9c,0xcb,0x38,0x1a,0x17,0x13,0x22,0xb9,0x9d,0x8f,0x2d,0x1a,0x08,0x10,0x39 +,0xa9,0x98,0xec,0x2f,0x1f,0xca,0xa9,0xa5,0xa1,0xb9,0x6c,0x35,0x39,0x22,0xc7,0xa4,0x8d,0x8e,0x9f,0x2f,0x10,0x26,0x47,0xa4,0xa2,0xbb,0x4e,0x26,0x62,0xae,0xb2,0xef +,0x25,0x2c,0x28,0x33,0x1b,0x28,0x4c,0x98,0x96,0xcb,0x1d,0x0d,0x1a,0x2e,0xa1,0x9a,0xc1,0x2e,0x20,0xcf,0xa1,0x9d,0xa5,0x5a,0x3e,0x25,0x2f,0x1d,0x5d,0xb1,0x91,0x92 +,0xac,0x35,0x13,0x3d,0xb5,0x95,0x9b,0xab,0x5e,0x22,0xef,0xca,0xa6,0xc2,0x3d,0x24,0x19,0x1b,0x13,0x2a,0x37,0x9a,0x9a,0xac,0x2a,0x0e,0x19,0x21,0xa2,0x9f,0xad,0x4d +,0x2a,0xb4,0xad,0x99,0x9f,0xdf,0x2e,0x1d,0x37,0x1d,0xec,0xc0,0x99,0x94,0xa7,0xbf,0x1b,0x49,0x31,0x9d,0xa1,0xa8,0xc2,0x3c,0xb0,0xbb,0xa7,0x42,0x28,0x1f,0x1f,0x30 +,0x15,0x1b,0x2c,0xa8,0x96,0xa7,0xb6,0x16,0x1c,0x16,0xc9,0xab,0xa0,0x9f,0xc0,0xae,0x2e,0xc5,0x3f,0xdb,0x54,0x3e,0x55,0x23,0x21,0x77,0xa4,0x8c,0x97,0x9e,0x2f,0x1f +,0x23,0x4a,0x9e,0xab,0xa7,0x2f,0xb9,0x36,0xbd,0xe8,0x3e,0x2a,0x23,0x3d,0x2c,0x20,0x1d,0xdd,0xa9,0x97,0xa1,0xe9,0x19,0x1a,0x29,0xc2,0xa4,0xa7,0xb9,0x33,0x49,0x4e +,0xc5,0x3a,0x43,0x30,0x2c,0x2d,0x24,0xd8,0xbe,0x9a,0x99,0x93,0xaa,0x3e,0x4f,0x63,0xa0,0xab,0x9c,0xac,0xd9,0x2c,0x2b,0x3a,0x31,0x2f,0x22,0x25,0x17,0x19,0x1c,0x3c +,0xa9,0xa4,0xa0,0x43,0x25,0x22,0xd5,0xa4,0x9e,0xa5,0x49,0x3b,0x40,0xa6,0xa3,0xa7,0xbe,0x33,0x2c,0x2d,0x3d,0xbd,0xae,0xc6,0xc2,0xd6,0x2f,0x1d,0x1f,0x39,0xa8,0xa2 +,0xa4,0x69,0x34,0x34,0xbc,0x9d,0xa3,0xab,0x5f,0x31,0x1d,0x35,0xad,0xa7,0xa9,0xbc,0x48,0x20,0x18,0x1a,0x20,0x3b,0x4a,0xc9,0x3e,0x29,0x28,0x2e,0xd3,0xac,0xa3,0xa5 +,0xbb,0x49,0xc3,0xae,0x9d,0x99,0x8f,0x96,0xba,0x24,0x1d,0x2f,0xb8,0xa5,0xaf,0x2a,0x14,0x0f,0x29,0xbb,0xaf,0xba,0x2e,0x1f,0x15,0x2d,0xbc,0xa5,0xa9,0xa2,0xaa,0x3d +,0x27,0x22,0x7c,0xaf,0xaf,0xa1,0xae,0x3f,0x2a,0x3b,0xc8,0xc1,0xc2,0x43,0x46,0x2c,0x41,0xc9,0xb9,0xac,0xab,0xb0,0x4c,0x24,0x25,0xc0,0xa8,0xa4,0xac,0x53,0x2b,0x2c +,0xc2,0xa6,0xa1,0xb0,0x31,0x27,0x1b,0x3e,0xb9,0xa4,0xa4,0xc4,0x4e,0x19,0x17,0x17,0x3c,0xce,0xae,0xac,0x5a,0x24,0x20,0x50,0xa8,0x9e,0xad,0xc9,0x30,0x32,0x67,0x9f +,0x9c,0x9b,0xb9,0xf1,0x44,0x24,0x2c,0x68,0xae,0xa8,0xa5,0xde,0x39,0x28,0x33,0x68,0xcb,0x43,0x35,0x30,0x30,0xe1,0xba,0xdb,0x51,0xe1,0xbb,0xcb,0x2b,0x27,0x35,0xf5 +,0xa9,0x9d,0xaf,0x3a,0x1f,0x2e,0xbf,0xaf,0xe7,0x45,0x38,0x29,0xbd,0xa7,0x9e,0xb6,0x3c,0x3a,0x2e,0x29,0xd5,0xa5,0xa8,0xaf,0xf4,0x49,0x30,0x48,0x6e,0xb1,0xc5,0x2b +,0x27,0x2f,0x44,0xc1,0xa8,0xab,0xc6,0x2b,0x2a,0x29,0x23,0x4f,0xc5,0xab,0xb5,0xb0,0xb4,0x40,0x2b,0x2e,0xac,0xaa,0xbf,0x57,0x5b,0x33,0xca,0xa8,0xa1,0xbb,0x4a,0x42 +,0x37,0x32,0x3a,0xba,0xba,0xab,0xb7,0xbe,0x2f,0x2a,0x32,0xcf,0x5b,0x28,0x29,0x29,0x34,0xd8,0xa5,0xa4,0xae,0x37,0xdd,0x32,0x2f,0x34,0xde,0xa4,0xab,0xa8,0x71,0x2b +,0x1c,0x31,0xad,0xa9,0x4f,0x2c,0x26,0x35,0xc3,0xa2,0x98,0xa9,0x46,0x2d,0x2d,0x53,0xc1,0xab,0xa5,0xaa,0xae,0xb2,0x3e,0x1f,0x2b,0xd3,0x59,0x36,0x33,0x31,0x35,0x40 +,0xae,0xa3,0xac,0x3f,0x46,0x2a,0x21,0x28,0x4c,0xc1,0xc5,0xaa,0xaa,0x42,0x21,0x23,0x41,0xb9,0xb8,0xb5,0xde,0xd2,0xe3,0xa8,0xa5,0xad,0xd6,0xf7,0x43,0x26,0x28,0xee +,0xab,0xa9,0xa6,0xb0,0x37,0x1e,0x24,0x34,0xc4,0x58,0x5a,0x45,0x4f,0x43,0xae,0xa2,0xd3,0x4c,0x33,0x42,0x2d,0x46,0xd8,0xb3,0xba,0xbb,0xb7,0x4e,0x33,0x28,0x43,0x66 +,0xb4,0xc6,0xc2,0x37,0x47,0xb1,0x9f,0x9c,0xb8,0x30,0x18,0x1c,0x29,0xa7,0xa4,0xac,0xc1,0x30,0x29,0x23,0x2f,0x4f,0xc6,0xbb,0xad,0xb3,0x3e,0x4a,0xbd,0x9f,0xa6,0xae +,0x47,0x1f,0x1e,0x29,0xb7,0xba,0xc1,0xc1,0xb9,0xd6,0x2e,0x25,0x2f,0x44,0xb2,0xad,0xb0,0x59,0x53,0xbf,0xb3,0xab,0xba,0x5c,0x28,0x22,0x26,0xbb,0xa7,0xab,0xae,0xbc +,0x45,0x32,0x3a,0x34,0x5b,0xc9,0xae,0xb9,0x43,0x4a,0xe9,0xae,0xd3,0x3f,0x22,0x21,0x21,0x1e,0xea,0xa8,0xa5,0xaf,0xbf,0x3a,0x25,0x27,0x42,0xb7,0xa8,0xa1,0xa9,0x3e +,0x4d,0xd1,0xaf,0xa7,0x42,0x35,0x2c,0x2e,0x36,0x49,0xbf,0xc2,0xa0,0xa7,0xed,0x2f,0x23,0x2b,0x4e,0xbb,0xb9,0xb6,0x38,0x4b,0xb1,0xa2,0xaa,0x2d,0x1d,0x17,0x2e,0xa8 +,0x9d,0xac,0xdd,0xcf,0xb1,0xbe,0x3d,0x21,0x2e,0x7d,0xcd,0xae,0xfb,0xf3,0x3b,0xb3,0xa8,0xa9,0x39,0x1a,0x19,0x1e,0xce,0xa2,0x9f,0xb3,0xac,0xb2,0xca,0x2b,0x1b,0x1f +,0x71,0xa1,0x98,0xac,0x32,0x2c,0xd0,0xa9,0xb8,0x4a,0x2b,0x1f,0x1e,0x3f,0xcb,0xa8,0xa0,0xab,0xa3,0xc4,0x28,0x1a,0x1c,0x64,0xa1,0x99,0xb1,0x45,0x36,0x3f,0xd7,0x4b +,0x39,0x2b,0x21,0x31,0x47,0xb3,0xa6,0xa4,0xa3,0xb8,0x35,0x25,0x2e,0x3c,0xbb,0xa8,0xb5,0x3e,0x3a,0x43,0xab,0xac,0xcd,0x1e,0x16,0x1c,0x36,0xa7,0xa8,0x9f,0xac,0xaa +,0xb6,0x3d,0x2d,0x2b,0x2d,0xdf,0xab,0xa3,0xc9,0x4e,0xd3,0xc7,0xc6,0x59,0x43,0x28,0x29,0x2d,0xd4,0xaa,0x9e,0xa1,0xa5,0xcf,0x2d,0x1f,0x1c,0x27,0x5d,0xa8,0xbd,0xc9 +,0x69,0xd8,0xbe,0x5d,0x36,0x22,0x2c,0x3d,0xa8,0xa4,0xc5,0xc1,0xb3,0xa4,0xb2,0x2c,0x1a,0x1c,0x25,0x4a,0xa8,0xa8,0xbb,0x74,0xeb,0xa8,0xb9,0x69,0x3f,0x2d,0x2d,0xf8 +,0xaa,0xa1,0xa4,0xac,0xb1,0x30,0x22,0x1e,0x24,0x33,0xd2,0xae,0xd3,0xba,0xd8,0xbb,0xca,0x35,0x3c,0x47,0x5e,0x30,0x4f,0x53,0xb7,0xa9,0x9d,0xa5,0xee,0x25,0x19,0x24 +,0x35,0xbc,0xa6,0xaf,0xcb,0xeb,0xdd,0xb7,0x45,0x39,0x2a,0x2d,0x36,0xef,0xbd,0xbb,0xb0,0xb5,0xac,0x50,0x2d,0x26,0x33,0x59,0x57,0xbe,0xae,0xb2,0xb8,0xae,0xba,0x3d +,0x29,0x2e,0x3f,0x3f,0xdf,0xc8,0xb6,0xac,0xaf,0xb4,0x33,0x28,0x28,0x45,0x5e,0x3d,0x39,0x37,0xb5,0x9e,0x98,0xaa,0x2a,0x25,0x27,0x49,0xb0,0xac,0xb3,0x4b,0xe9,0xe0 +,0xa6,0xe7,0x2c,0x28,0x26,0x70,0x37,0xbf,0xba,0xcf,0xca,0xcc,0xec,0x2e,0x2f,0x48,0xc6,0x54,0x6d,0xb1,0xb3,0xae,0xbd,0xc6,0x40,0x36,0x39,0x39,0x2e,0x2f,0xd6,0xa5 +,0xa2,0x9e,0xa3,0xd9,0x27,0x1d,0x3f,0xdf,0xbf,0x3a,0x2d,0x37,0xc1,0x9d,0x9f,0xd8,0x29,0x21,0x37,0x46,0x53,0xbe,0xb8,0xb4,0xb7,0xaf,0x68,0x38,0x22,0x2c,0x37,0x6b +,0xdf,0x5c,0x4e,0x4e,0xb0,0xb4,0xc2,0x3f,0x54,0xcd,0xec,0x4e,0x48,0xb8,0xb2,0xa7,0xae,0x5f,0x2d,0x1e,0x2d,0x32,0x3a,0x3b,0xb1,0xa3,0x9b,0x96,0xa2,0xec,0x28,0x2c +,0x34,0x36,0x1f,0x28,0x30,0xc5,0xaa,0xb3,0x5a,0x20,0x23,0xe4,0xa2,0x9f,0xad,0x51,0x31,0x2b,0x29,0xbb,0xab,0x9e,0x9e,0x5c,0x1c,0x19,0x17,0x23,0x5f,0xd6,0xb8,0x9f +,0x9e,0x94,0x91,0x45,0x3e,0x22,0xa5,0x99,0x8b,0xc6,0x1d,0x35,0x00,0x0b,0x05,0x20,0xaf,0x26,0x98,0x29,0xa8,0x9d,0x42,0xc6,0x98,0x8e,0x97,0x88,0x98,0x2c,0xaa,0x79 +,0x0b,0xa7,0x3b,0x98,0x80,0x8b,0x93,0x96,0x3c,0x17,0x17,0x07,0x0f,0x09,0x09,0x08,0x0c,0x03,0x04,0x03,0x0e,0x19,0x1c,0x38,0x25,0x2f,0x4c,0xbb,0x3a,0x4d,0xac,0x8e +,0x91,0x90,0xaf,0x3d,0xbf,0xd3,0x8c,0x83,0x82,0x80,0x82,0x81,0x95,0x8b,0xc8,0x98,0x82,0x9f,0x9c,0x94,0x89,0x0b,0x07,0x0f,0x00,0xdc,0xa6,0x30,0xdd,0x09,0x04,0x21 +,0x10,0x17,0x10,0x04,0x64,0x0b,0x02,0x01,0x04,0x0b,0x16,0x8e,0x8a,0xad,0x1c,0x1a,0x21,0x8e,0x87,0x83,0x92,0x8a,0x89,0x8d,0x8e,0x93,0x20,0xea,0x88,0x85,0x80,0x83 +,0x88,0x2a,0xb7,0x19,0x8f,0x8d,0xaf,0x18,0x1e,0x3f,0x09,0x02,0x05,0x09,0x1a,0x9e,0x11,0x2a,0x00,0x03,0x00,0x0e,0x24,0x10,0x1e,0x09,0xca,0x1d,0x0f,0x17,0xc1,0x8b +,0x80,0x83,0x87,0x54,0x15,0x32,0xa0,0x88,0x96,0x8c,0x95,0x95,0xa8,0x8c,0xb6,0xaa,0x84,0x80,0x84,0x89,0x29,0x05,0x69,0x4e,0xa5,0xc6,0x9c,0x25,0x00,0x0d,0x0b,0x06 +,0x06,0x1d,0x94,0x70,0x8e,0x0e,0x09,0x0b,0x0d,0x16,0x04,0x0e,0x0c,0xeb,0x3b,0x1f,0x0c,0xb4,0x8d,0x87,0x86,0x87,0xdb,0xb5,0x1e,0x98,0x80,0x85,0x86,0x84,0x8e,0x24 +,0x0c,0x23,0x89,0x81,0x82,0x98,0xa5,0x09,0x24,0x2f,0xa8,0x94,0x98,0xc8,0x1a,0xbc,0x0c,0x0a,0x09,0x03,0x8a,0x8f,0xbd,0x09,0x00,0x03,0x24,0x8f,0xaf,0xaa,0x0c,0x1a +,0x05,0x19,0x0d,0xaf,0x80,0x83,0x90,0x93,0x17,0x00,0x9e,0x8d,0x9c,0x1a,0x02,0x9d,0xaf,0x00,0x08,0x00,0xdb,0x85,0x80,0xb0,0x1f,0x00,0x0c,0x09,0xff,0x88,0x3a,0x22 +,0x0d,0x0d,0x03,0x00,0x1c,0xb0,0x97,0x88,0x25,0xb9,0x0a,0xac,0x88,0x88,0x9d,0x98,0x8f,0xd8,0x8a,0x89,0x9d,0x8f,0x8e,0x80,0x84,0x82,0x8e,0x1d,0x8f,0x17,0x8a,0x8e +,0x80,0x8a,0x50,0xd0,0x1a,0xa9,0xa9,0x88,0x80,0x94,0x1f,0x05,0x04,0x95,0x4f,0xa1,0x98,0x89,0x18,0x02,0x2c,0x00,0x11,0x09,0x8e,0x9e,0x0d,0xb5,0x00,0x03,0x00,0x0b +,0x1c,0x1e,0x9e,0x00,0x02,0x03,0x01,0x2e,0x19,0x8b,0x0d,0xce,0x15,0x1d,0x80,0xa7,0x81,0x8c,0x87,0x90,0xa4,0x96,0x8a,0x80,0x8a,0x5c,0x80,0x87,0x80,0x26,0x1c,0x8c +,0x36,0x80,0x1f,0x55,0x9d,0x8e,0x33,0x00,0x3a,0x15,0x8e,0x93,0x17,0x65,0x00,0x13,0x07,0x0f,0xad,0x1d,0xcd,0x29,0x03,0x03,0x00,0xaa,0xa6,0x8c,0x8f,0x8f,0x88,0x16 +,0xa2,0x09,0x91,0x85,0x83,0x80,0x87,0x9c,0x2c,0x92,0x80,0x80,0x80,0x89,0x9b,0xc6,0x98,0x84,0xbc,0x8b,0x8e,0x16,0x15,0x1d,0x09,0x00,0x04,0x30,0xb9,0x8f,0x09,0x00 +,0x04,0x00,0x05,0x00,0x19,0x16,0x03,0x04,0x03,0x0b,0x00,0x08,0x06,0x24,0x8d,0x08,0x0e,0x00,0x0e,0x1e,0x2b,0x86,0x8b,0x87,0x80,0x98,0x86,0x97,0x90,0x82,0x84,0x80 +,0x84,0x81,0x98,0x89,0x9d,0x90,0x82,0x85,0x8b,0xaf,0x9c,0x91,0x0f,0x32,0x17,0x90,0x8e,0x33,0x45,0x0a,0x26,0x20,0x8a,0x86,0xa9,0x32,0x29,0x03,0x0b,0x04,0x8f,0x3e +,0x9b,0x8a,0x1b,0x24,0x00,0x10,0x00,0x2c,0x3d,0x13,0x10,0x08,0x03,0x06,0x00,0x9c,0x27,0xc5,0xb0,0x0f,0xbc,0x00,0x29,0x0e,0x92,0x91,0x8b,0x8c,0x97,0x98,0xb7,0xbb +,0x86,0x82,0x80,0x88,0x8d,0x99,0x07,0x9e,0x0e,0x9e,0x57,0x2a,0x16,0x08,0x39,0x24,0x0c,0x1a,0x18,0xa1,0x16,0x09,0x17,0x00,0x3c,0x0d,0x9a,0xbc,0xa3,0x1c,0x0a,0x19 +,0x03,0x20,0x98,0x97,0x81,0x96,0x98,0xb2,0x10,0x9b,0x95,0x80,0x83,0x80,0x84,0xb6,0xaf,0xb5,0xb3,0x80,0x85,0x80,0x94,0x89,0xa2,0x25,0xa2,0x3a,0x85,0x93,0x88,0x55 +,0x08,0x05,0x02,0x00,0x0f,0x1e,0xc6,0x0a,0x0f,0x0e,0x00,0x07,0x00,0x0a,0x00,0x0a,0x0b,0x06,0x09,0x00,0x03,0x0f,0x0d,0x29,0x1f,0x14,0x18,0x00,0x12,0x1a,0x8f,0x9c +,0x8c,0x95,0x3c,0x8a,0x44,0x96,0x80,0x84,0x80,0x88,0x85,0x88,0x89,0x80,0x89,0x80,0x88,0x8b,0x8b,0x8c,0x9a,0xb0,0x37,0x97,0xa0,0x91,0x26,0x21,0x1c,0x00,0x0e,0x0b +,0x9a,0x5d,0x96,0x2a,0x07,0x18,0x0b,0x04,0xdc,0xa7,0x8d,0x93,0x19,0xc5,0x0a,0x29,0x24,0x9d,0x31,0x2e,0x1b,0x14,0x29,0x13,0x14,0x12,0x12,0xa1,0x8b,0xa2,0x9c,0x03 +,0x0e,0x00,0xbd,0x99,0x95,0x88,0xc3,0x21,0x14,0x0a,0x6a,0xe6,0xb3,0x87,0x77,0x91,0x0b,0xcd,0x19,0xfc,0x9e,0xd3,0x18,0x0b,0x20,0x13,0x3a,0x5e,0x48,0x9e,0x97,0x39 +,0x9e,0x18,0x47,0x2e,0xa4,0x95,0xa3,0x8f,0xa1,0x9a,0x9b,0x0d,0x36,0x9b,0xa8,0x8a,0x96,0x91,0x39,0x3f,0x6b,0xc3,0x86,0x82,0x8b,0x52,0x1e,0xac,0x9d,0x87,0x80,0x86 +,0x80,0x9b,0x86,0x92,0x24,0xa2,0x37,0x8c,0x87,0x98,0x6e,0x1c,0x0f,0x09,0x07,0x0d,0x04,0x3f,0x28,0x19,0x0f,0x00,0x03,0x01,0x25,0x08,0x0c,0x0a,0x02,0x02,0x02,0x01 +,0x0d,0x16,0x27,0x16,0x0f,0x0f,0x06,0x10,0x0f,0x96,0xc1,0x91,0x8e,0x98,0x86,0x8e,0x8e,0x90,0x9e,0x8d,0x80,0x84,0x80,0x94,0x89,0x93,0x93,0x88,0x83,0x96,0xa6,0x9f +,0x1e,0x1f,0x41,0x36,0x2c,0x96,0x0e,0x29,0x14,0x1d,0x06,0x3b,0xaf,0x3f,0x98,0xdf,0x8f,0x8c,0x91,0xbe,0x92,0x3e,0x8c,0x96,0x83,0x9d,0x5a,0x1f,0x1f,0xb7,0x2e,0xb5 +,0x10,0x11,0x16,0x14,0x0a,0x1d,0x14,0x92,0x0e,0x14,0x07,0x00,0x07,0x07,0x9f,0x2c,0x15,0x13,0x0d,0x16,0xa6,0x18,0xab,0x28,0xa0,0x36,0x98,0xa4,0x22,0xcc,0x21,0x9e +,0x4a,0x92,0x9f,0x36,0xd7,0x1f,0x06,0x38,0x33,0x84,0x86,0x82,0xab,0x08,0x14,0x10,0x8d,0x9a,0x87,0x96,0xab,0xc1,0x26,0x18,0xa1,0x27,0x98,0x93,0x8f,0x9b,0x9f,0x97 +,0x1b,0x8e,0x9e,0x8e,0xa5,0x8c,0x97,0xab,0x95,0x93,0x94,0x80,0x85,0x80,0x8f,0xb6,0x28,0x0a,0x9b,0x9b,0x9a,0xd5,0x39,0x17,0x11,0x0c,0x22,0xdb,0xa2,0x09,0x1c,0x06 +,0x0a,0x0f,0x09,0xaf,0x20,0x09,0x00,0x05,0x01,0x02,0x08,0x12,0x15,0xc6,0x0a,0xcf,0x0c,0x0d,0x07,0x0a,0x24,0xc2,0x95,0xd0,0xc5,0x0b,0x0f,0x9b,0x9f,0x88,0x84,0x9f +,0x83,0x14,0xca,0x9c,0x8c,0x83,0x83,0x89,0xab,0x96,0x10,0x20,0x92,0xba,0x85,0x8d,0x9c,0x8c,0xa7,0xb0,0x74,0x97,0x17,0x92,0x90,0x9d,0x87,0x18,0xdc,0x97,0x9e,0x89 +,0x8e,0xbd,0x19,0x21,0x0a,0x18,0xab,0x23,0x99,0x3f,0x13,0x08,0x04,0x11,0x63,0x9a,0x17,0x1d,0x08,0x09,0xbf,0x1a,0x94,0xb7,0x0b,0x0b,0x06,0x02,0x01,0x1b,0x16,0x8d +,0xb3,0x18,0x2d,0x00,0x16,0x15,0x27,0x4a,0xad,0xba,0xac,0x9c,0x09,0xae,0xca,0xaa,0x86,0xa0,0x9e,0x29,0xae,0x3d,0x89,0x90,0x9c,0x87,0x3d,0x67,0x15,0x38,0xbf,0x8c +,0x93,0x98,0x95,0x0c,0x94,0x6c,0x9d,0x8d,0x17,0x22,0x1f,0x24,0x1f,0x83,0x8b,0x81,0x87,0xd1,0x9e,0x0f,0x30,0x96,0x84,0x88,0x82,0x8c,0xa4,0x92,0x1a,0x97,0x87,0x85 +,0x84,0x99,0x18,0x03,0x14,0x0a,0x97,0x96,0xe2,0x9d,0x15,0x04,0x01,0x0d,0x07,0x96,0x48,0x13,0x1d,0x00,0x04,0x00,0x03,0x05,0x0e,0x09,0x0c,0x07,0x00,0x1d,0x0d,0xb1 +,0xc8,0x1e,0x1f,0x0b,0x12,0x0c,0x91,0xa5,0x8d,0x85,0xaf,0x36,0xac,0x99,0x8c,0x82,0x3f,0x8c,0xb7,0x96,0x80,0x89,0x84,0x8f,0xaa,0x65,0x7d,0x09,0x9e,0x8d,0x88,0x80 +,0x8d,0x96,0x3f,0xa8,0xba,0x85,0xa0,0xbe,0x95,0x32,0x3c,0x42,0x9a,0x92,0x80,0xb5,0x96,0x10,0x02,0x16,0x0a,0xae,0x6b,0xbc,0x0d,0x1a,0x00,0x16,0x7b,0x33,0x96,0x0c +,0x0d,0x00,0x17,0x08,0xd8,0x20,0x08,0xdb,0x06,0x06,0x04,0x1e,0xde,0x80,0xaa,0x38,0x10,0x00,0x4d,0x3e,0x8e,0x98,0x9b,0x19,0x1d,0x07,0x17,0x8f,0x8c,0x82,0x92,0x2e +,0x02,0x23,0x2b,0x8a,0x82,0x91,0x91,0x3c,0x06,0x1c,0x97,0x9c,0x80,0x9f,0x94,0xab,0x5a,0xa2,0x9d,0xa5,0x58,0x90,0x1f,0x1f,0x04,0x17,0x9c,0x81,0x85,0x88,0xa3,0x05 +,0x9c,0x3f,0x8f,0x96,0xc4,0x4b,0x9f,0x16,0x3b,0x89,0x96,0x80,0xa2,0x54,0x05,0x0e,0x08,0x9c,0x94,0xae,0x99,0x0b,0x0a,0x06,0xe7,0xcd,0x86,0x1f,0x1c,0x0a,0x02,0x14 +,0x0f,0x24,0x37,0xa4,0x16,0x17,0x00,0x0d,0x17,0x8b,0x8f,0xa1,0x15,0x02,0xb4,0x23,0x86,0x9c,0xa8,0xcc,0xb4,0x0b,0xf6,0x9c,0xa3,0x80,0xa9,0x99,0x0f,0x1d,0x1d,0x8d +,0x99,0x96,0x9d,0x13,0x10,0x0c,0x9b,0x95,0x81,0x5a,0x9e,0x16,0x1a,0x9d,0xce,0x9b,0x9b,0x93,0xc4,0x2a,0x00,0x3e,0x8f,0x80,0x83,0x8a,0x13,0x05,0x2b,0x1f,0x86,0xb9 +,0xa6,0xad,0x2e,0x07,0x1c,0x1b,0x9d,0x89,0x37,0x3c,0x00,0x06,0x00,0x3f,0x23,0x99,0xa1,0x21,0x0e,0x05,0x1d,0x33,0x8b,0x25,0x9b,0x0b,0x23,0xb4,0x4d,0x99,0xaf,0xa8 +,0xc0,0x20,0x01,0xcb,0x3f,0x88,0xa6,0x27,0x07,0x09,0x2d,0x26,0x8a,0x12,0x1a,0x0f,0x0c,0x08,0xbd,0x9f,0x87,0x83,0x95,0xa3,0x06,0x19,0x34,0x88,0x8a,0x81,0x90,0xb5 +,0x18,0x38,0x86,0x83,0x80,0x8a,0x8b,0x08,0x21,0x1d,0xb9,0x8b,0x89,0x87,0x8c,0x1f,0x04,0x31,0x4c,0x80,0x8c,0x8e,0x0d,0x0f,0x0b,0x12,0xaa,0x1d,0x96,0xa8,0x20,0x08 +,0x1c,0x0e,0x8e,0x9b,0x9c,0xd7,0x0c,0x17,0x11,0xd7,0x10,0xbe,0x16,0x19,0x06,0x0e,0x15,0xaf,0xad,0x19,0x3b,0x03,0x9d,0xb4,0x8c,0x90,0x99,0xa0,0xb7,0x14,0x13,0x96 +,0xa5,0x82,0xa1,0x5f,0x01,0x0b,0x08,0x2a,0x49,0x0a,0x16,0x03,0x03,0x00,0x19,0x1e,0x88,0x9e,0x42,0x0f,0x00,0x08,0x1a,0x8f,0x91,0x80,0x94,0x9f,0x0f,0xbd,0x89,0x82 +,0x81,0x85,0x8e,0x1c,0x94,0xa2,0x86,0x85,0x81,0x83,0x83,0x2a,0x17,0xcc,0xae,0x80,0x91,0x87,0x1f,0xab,0x25,0xd3,0x57,0x14,0xb7,0x28,0x13,0x04,0x14,0x09,0x99,0x1c +,0x28,0x0b,0x02,0x0d,0x08,0x1b,0x03,0x11,0x0a,0x1f,0x1d,0x8f,0x8a,0x84,0x88,0x8b,0x8d,0xbe,0x87,0x9a,0x83,0x8e,0x8f,0x7b,0x0a,0x00,0x08,0x1e,0x33,0xc6,0x01,0x05 +,0x00,0x09,0x09,0xbc,0x72,0x2e,0xac,0x12,0x0b,0x02,0xc3,0x8e,0x80,0x88,0x8a,0x0f,0x0a,0x29,0xaf,0x86,0x9a,0x91,0x45,0x31,0x05,0x2f,0xaf,0x89,0x82,0x85,0x9a,0x0d +,0x27,0x2a,0x82,0x88,0x80,0x8c,0xa1,0x0e,0x39,0x94,0x8f,0x83,0xa2,0x8c,0x2c,0xaf,0x36,0x54,0x20,0xbe,0x9f,0x33,0x0f,0x00,0x11,0x0f,0x97,0x2a,0x1e,0x04,0x04,0x0e +,0x1c,0xa0,0x34,0x9c,0x9a,0x92,0xc3,0x83,0x88,0x80,0x89,0x8f,0xad,0x0c,0x43,0xbe,0x87,0x46,0x28,0x08,0x04,0x00,0x08,0x12,0x42,0xc8,0x00,0x0a,0x00,0x09,0x09,0x42 +,0x38,0x1f,0x17,0x07,0x03,0x00,0x2c,0x99,0x80,0x8b,0x8d,0x0d,0x0f,0x2e,0x9b,0x80,0x8b,0x82,0x95,0xb0,0x0e,0xb4,0x97,0x82,0x82,0x83,0x99,0x0c,0x1e,0x17,0x8d,0x93 +,0x83,0x8f,0xa0,0x0d,0x10,0x43,0x96,0x84,0x9a,0x90,0x05,0x1e,0x0c,0x4a,0x2d,0x1a,0x4f,0x1e,0x0b,0x04,0x2f,0xc7,0x81,0x92,0x89,0x2b,0xb7,0x90,0x87,0x80,0x89,0x81 +,0x92,0x98,0x1b,0xa1,0x9b,0x89,0xc5,0x09,0x04,0x00,0x02,0x08,0x56,0x13,0x13,0x00,0x04,0x00,0x0c,0x32,0x93,0x8b,0x3a,0x1c,0x01,0x1a,0x22,0x8a,0x8f,0x8f,0xb3,0x12 +,0x02,0x06,0x34,0x99,0x80,0x94,0x95,0x06,0x08,0x05,0x3f,0x9c,0x8f,0x84,0x95,0xac,0x08,0xaf,0x98,0x80,0x85,0x80,0xaa,0x2a,0x40,0xc3,0x8b,0x9d,0x85,0x91,0x94,0x0a +,0x1a,0x1a,0xa4,0xa3,0x25,0x25,0x04,0x14,0x09,0x30,0x17,0xdb,0x46,0xc0,0x0f,0x1e,0x90,0x89,0x80,0x86,0x82,0xbb,0x8e,0x95,0x85,0x85,0x87,0x97,0x1b,0x08,0x01,0x1e +,0x36,0x86,0x32,0x12,0x01,0x01,0x00,0x0b,0x39,0x1b,0x38,0x07,0x08,0x00,0x0a,0x0b,0x8e,0x8f,0x9c,0x1e,0x00,0x08,0x04,0x9b,0x9e,0x82,0x8b,0x8f,0x11,0x26,0x9d,0x8a +,0x80,0x86,0x87,0x1f,0xa7,0x1f,0x8e,0x9e,0x8d,0x94,0x94,0xb8,0x1e,0xa6,0x2e,0x8e,0x1b,0xab,0x0e,0x3b,0x22,0x57,0x9f,0xb6,0xa1,0x15,0x17,0x00,0x36,0x1c,0x89,0xae +,0x52,0x14,0x0d,0xb7,0xa3,0x80,0x8a,0x82,0xad,0xa8,0x1a,0x90,0x82,0x80,0x81,0x82,0x9c,0x05,0x0f,0x06,0x44,0x1b,0x33,0x0e,0x04,0x00,0x02,0x06,0x23,0x8c,0x36,0x3a +,0x00,0x06,0x00,0x14,0x2c,0x9c,0x8d,0xa8,0x2d,0x00,0x1e,0x16,0x85,0x91,0x8e,0x26,0x0b,0x1d,0x19,0x91,0xc6,0x8e,0x4d,0xaa,0x0e,0xb6,0xa9,0x8b,0x89,0x9b,0x97,0x1b +,0x8f,0xbb,0x83,0x8d,0x85,0x95,0x9c,0x35,0x25,0x9b,0x9d,0x81,0x9d,0xa2,0x04,0x0a,0x07,0x38,0x9c,0xb2,0x56,0x02,0x04,0x00,0x0f,0x28,0x81,0x89,0x87,0x6d,0x17,0x9a +,0x92,0x80,0x85,0x80,0x8a,0x88,0x1c,0xdd,0x9f,0x8e,0x83,0xa6,0xe3,0x00,0x06,0x00,0x0c,0x07,0x15,0x12,0x09,0x08,0x00,0x16,0x0f,0x90,0x2d,0x25,0x07,0x04,0x0b,0x10 +,0x9f,0x40,0x9d,0x18,0x1e,0x07,0x3c,0x95,0x87,0x84,0xa1,0xbe,0x0a,0xac,0xa4,0x84,0x87,0x85,0x8f,0xa1,0x2d,0x0f,0xa6,0x9b,0x80,0x8a,0x8e,0x0e,0x08,0x11,0x49,0x89 +,0x94,0x8e,0x1e,0x10,0x00,0x09,0x1c,0x91,0x85,0xa2,0xc3,0x04,0x10,0x0b,0xb7,0xa6,0x95,0x97,0xbc,0x3c,0x0e,0x90,0x8d,0x80,0x84,0x80,0x9b,0xd1,0xb0,0x2e,0x97,0x29 +,0xa6,0x18,0x16,0x03,0x08,0x10,0x1e,0x9e,0x0c,0x13,0x00,0x09,0x06,0x2f,0x56,0x1f,0x27,0x09,0x18,0x01,0xd1,0x51,0x8b,0x9d,0x1c,0x14,0x01,0x21,0x21,0x81,0x91,0x8d +,0x41,0x1c,0x17,0x0e,0x8f,0x8f,0x80,0x92,0x8d,0x1c,0x16,0x27,0xac,0x80,0x85,0x81,0x2f,0x26,0x06,0x2a,0x88,0x84,0x80,0x8f,0x9b,0x0c,0x1d,0x0e,0xb9,0xab,0x32,0x2b +,0x06,0x0e,0x00,0x0e,0x0e,0x96,0x93,0xa3,0xaa,0x10,0xcc,0x57,0x86,0x8b,0x83,0x8e,0x8b,0x89,0x94,0x80,0x8f,0x82,0xab,0x3a,0x0f,0x08,0x0d,0x0b,0x2a,0x06,0x0b,0x00 +,0x06,0x04,0x0c,0x1b,0x14,0x3f,0x08,0x1a,0x07,0x13,0x1e,0x49,0x99,0xb6,0x9f,0x15,0x2c,0x0c,0xc0,0x9a,0x8c,0x85,0x98,0x99,0x24,0xa0,0xac,0x8c,0x94,0x9e,0x99,0x28 +,0xe1,0x17,0x31,0xa8,0x8c,0x87,0x8a,0x93,0x48,0xbe,0x39,0xab,0x9e,0x99,0x9b,0xc2,0x37,0x13,0x17,0x1f,0xba,0x96,0xa0,0xc1,0x0f,0x08,0x0a,0x1a,0x2a,0xba,0xae,0xa5 +,0x8f,0xa0,0x9f,0x9f,0x8e,0x84,0x81,0x80,0x88,0x9c,0x2c,0xc1,0xa4,0xbf,0xc9,0x11,0x0e,0x07,0x02,0x03,0x02,0x0b,0x14,0x32,0x14,0x0d,0x07,0x09,0x1f,0x57,0xde,0x45 +,0x14,0x0e,0x0d,0x12,0x24,0xbc,0x9e,0x9f,0x92,0x2c,0x79,0x23,0xb9,0x9a,0x90,0x95,0xc7,0x2a,0x19,0x57,0x99,0x8c,0x86,0x8d,0x9a,0x9e,0x3d,0xb3,0xae,0x92,0x92,0x8c +,0xac,0xbf,0x29,0x19,0x3c,0xc6,0x97,0x93,0xa7,0x32,0x1c,0x19,0x30,0xad,0xab,0x9d,0x9d,0x44,0x20,0x0c,0x07,0x10,0x23,0xc4,0x9b,0x55,0xbd,0x1f,0x20,0x1f,0xcc,0x3b +,0x9d,0xa5,0xb7,0x4a,0x0e,0x0b,0x0f,0xb8,0x94,0x82,0x94,0xae,0x0e,0x09,0x0a,0xd4,0xbe,0x94,0x9f,0x36,0x1f,0x08,0x09,0x0f,0xb0,0x98,0x8b,0xa8,0x3a,0x12,0x0f,0x19 +,0x9d,0x96,0x88,0x8c,0x9f,0xd3,0x1f,0x12,0x73,0x96,0x8d,0x82,0x91,0x98,0xc4,0xbb,0xc8,0x9a,0x9f,0x8f,0x99,0xa7,0x43,0x1d,0x0b,0x0e,0x2e,0xa2,0x8b,0x9d,0xa5,0x1c +,0x1a,0x10,0x79,0x42,0xa4,0x9b,0xab,0xb5,0x1e,0x07,0x04,0x0c,0x1d,0x9d,0xab,0xb7,0x0e,0x11,0x06,0x1a,0x30,0x9c,0x8c,0x91,0x9f,0x20,0x0c,0x05,0x36,0xac,0x83,0x8e +,0x99,0x12,0x08,0x05,0x0f,0x41,0xa6,0x8b,0xaa,0xa0,0x18,0x0c,0x04,0x1a,0xef,0x8a,0x89,0x8f,0xaa,0x1f,0x28,0x25,0x97,0xa0,0x8a,0xac,0xac,0x4b,0x22,0x1e,0xbb,0x94 +,0x8c,0x82,0x86,0x80,0x8d,0x8e,0xb5,0xa1,0xb2,0x91,0x8b,0x89,0x8b,0xb7,0x17,0x0a,0x15,0x1e,0x9e,0xce,0xa1,0x1d,0x0d,0x0a,0x09,0x0c,0x1b,0xc4,0xc7,0xbc,0x0a,0x03 +,0x00,0x04,0x07,0xdf,0x9f,0x90,0xbd,0x0c,0x0d,0x2e,0x8e,0x06,0xe3,0x80,0x8c,0x93,0x0d,0x02,0x07,0x0a,0x25,0xad,0x9d,0x04,0x03,0x04,0x00,0x04,0x03,0x31,0x0a,0x05 +,0x03,0x02,0x00,0x17,0xce,0xae,0x9a,0xad,0x9e,0xa5,0x99,0xaf,0x9d,0xa6,0x87,0x80,0x80,0x80,0x84,0x80,0x80,0x82,0x8f,0x85,0x80,0x80,0x80,0x80,0x8c,0x92,0x87,0x80 +,0x80,0x80,0x81,0x8a,0xa1,0xbb,0x9c,0x9c,0x87,0x85,0x8f,0x26,0x09,0x02,0x00,0x0b,0x24,0x0f,0x00,0x03,0x00,0x00,0x00,0x04,0x01,0x03,0x01,0x02,0x00,0x00,0x01,0x01 +,0x05,0x0b,0x07,0x00,0x02,0x02,0x03,0x01,0x07,0x05,0x0e,0x19,0x18,0x0c,0x07,0x09,0x07,0x12,0xc0,0x95,0xc4,0xad,0xad,0xd1,0xac,0x8b,0x80,0x81,0x80,0x81,0x84,0x86 +,0x81,0x82,0x80,0x80,0x80,0x82,0x83,0x82,0x82,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x83,0x81,0x83,0x89,0x86,0x80,0x83,0x82,0x84,0x88,0xa5,0x90,0x8a,0x8c,0x89,0x8d +,0x9d,0x0f,0x09,0x04,0x0a,0x1d,0x94,0xb0,0x0a,0x03,0x00,0x00,0x01,0x0c,0x1b,0x18,0x0a,0x05,0x00,0x00,0x00,0x02,0x04,0x0a,0x07,0x00,0x00,0x01,0x00,0x00,0x01,0x00 +,0x01,0x02,0x08,0x03,0x03,0x01,0x03,0x04,0x0c,0x15,0x0c,0x0e,0x0b,0x02,0x02,0x08,0x28,0x8e,0x87,0x89,0x40,0x16,0x11,0x22,0x7b,0x92,0x8b,0x9e,0xbb,0xc1,0xaf,0xa0 +,0x85,0x83,0x82,0x85,0x88,0x9a,0x94,0x86,0x81,0x81,0x83,0x82,0x89,0x8b,0x85,0x85,0x85,0x82,0x81,0x80,0x81,0x80,0x85,0x88,0x8c,0x8b,0x8c,0x84,0x81,0x81,0x87,0x94 +,0xa2,0xc8,0x9a,0x8f,0x88,0x8f,0x95,0x1d,0x0b,0x0c,0x35,0x9b,0x8c,0x8b,0xb4,0x13,0x06,0x0a,0x0d,0xc0,0x9b,0x91,0xa4,0x99,0xb6,0xd2,0xc5,0xaa,0x98,0x96,0x8a,0x95 +,0x97,0xaa,0xa5,0xcd,0x9f,0x9b,0x8e,0x8b,0x84,0x87,0x97,0xa7,0xa7,0x8e,0x8b,0x87,0x8f,0xad,0x1e,0x15,0x12,0x7e,0x94,0x8d,0x9e,0x41,0x0d,0x00,0x01,0x02,0x07,0x0a +,0x04,0x01,0x00,0x00,0x00,0x00,0x06,0x08,0x0c,0x03,0x01,0x00,0x00,0x00,0x01,0x02,0x01,0x01,0x01,0x03,0x01,0x01,0x00,0x01,0x01,0x08,0x06,0x08,0x04,0x01,0x01,0x00 +,0x02,0x0a,0x15,0x24,0x1a,0x07,0x02,0x00,0x0b,0x2f,0x92,0xaa,0x3b,0x11,0x0f,0x1c,0xa2,0x83,0x82,0x80,0x83,0x84,0x8e,0x8e,0x86,0x80,0x80,0x80,0x80,0x80,0x82,0x80 +,0x80,0x80,0x80,0x80,0x81,0x82,0x82,0x82,0x87,0x87,0x82,0x81,0x80,0x81,0x81,0x8a,0x88,0x8c,0x86,0x86,0x81,0x81,0x82,0x89,0xa6,0x2f,0xc6,0x85,0x81,0x80,0x81,0x80 +,0x88,0x87,0x8a,0x84,0x83,0x83,0x8b,0xa6,0x69,0x1d,0x17,0x19,0x30,0x1f,0x1c,0x07,0x03,0x01,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06 +,0x05,0x07,0x00,0x00,0x00,0x00,0x01,0x06,0x04,0x03,0x01,0x01,0x00,0x01,0x0b,0x30,0xa8,0x48,0x14,0x03,0x02,0x0a,0xbd,0x91,0x87,0x8f,0x98,0xb4,0xaf,0x4d,0xa1,0x8b +,0x85,0x82,0x86,0x86,0x97,0x8d,0x8d,0x84,0x85,0x84,0x8e,0x8f,0x97,0x96,0xb0,0xbf,0x97,0x8e,0x86,0x8a,0x8c,0xbf,0x70,0xbb,0x93,0x89,0x85,0x8a,0x8f,0xb7,0x23,0x0d +,0x19,0xa6,0x8b,0x8a,0x8f,0xb0,0x12,0x10,0x1b,0xad,0x9a,0x8f,0xb0,0x38,0x0c,0x0a,0x03,0x10,0x2c,0xa7,0xaa,0x45,0x35,0x0c,0x0f,0x0c,0x1b,0x23,0x3f,0x1d,0x23,0x11 +,0x13,0x09,0x13,0x23,0xbc,0x98,0x99,0x94,0xd8,0xfe,0x49,0x9f,0x95,0x8c,0x9a,0x9d,0x2b,0x21,0x14,0x2d,0xa5,0x8d,0x8a,0x9b,0xd5,0x0e,0x0e,0x14,0xac,0x99,0x8f,0xa3 +,0xac,0x2d,0x3a,0x2d,0xaa,0x8f,0x87,0x82,0x85,0x82,0x8a,0x87,0x88,0x81,0x82,0x80,0x81,0x80,0x85,0x89,0x9f,0xae,0x9b,0x8f,0x87,0x8e,0x9a,0x19,0x08,0x05,0x06,0x09 +,0x13,0x0f,0x17,0x08,0x05,0x00,0x01,0x06,0x0e,0x1c,0x0d,0x0b,0x02,0x03,0x06,0x17,0x15,0x1f,0x0e,0x0f,0x09,0x0a,0x07,0x09,0x1c,0x20,0xa1,0xd3,0x9f,0x30,0x2d,0x2e +,0xcb,0x9f,0x8f,0x8d,0x88,0x8c,0x95,0xbd,0x28,0x9f,0x9a,0x83,0x86,0x82,0x8e,0x99,0x9f,0x97,0x8c,0x88,0x87,0x89,0x8f,0xbb,0x29,0x0f,0x30,0x3e,0x90,0x96,0x98,0xcd +,0x1a,0x1c,0x22,0x4f,0x5e,0x4e,0x3f,0x2f,0x28,0x19,0x09,0x10,0x0f,0xd2,0x43,0xbf,0x29,0x0e,0x0d,0x12,0x2f,0x4d,0xce,0x2e,0x1e,0x10,0x0d,0x04,0x14,0x20,0x9a,0x98 +,0xaa,0x27,0x05,0x06,0x09,0x1e,0x5d,0xa4,0xba,0x49,0x1e,0x15,0x0b,0x19,0xea,0x96,0x8b,0x8f,0x91,0xc3,0xb5,0xad,0x93,0x8d,0x8a,0x8a,0x89,0x8f,0xa5,0x17,0x13,0x1d +,0xbc,0x8e,0x97,0x97,0x1e,0x14,0x0d,0x1a,0x2c,0xb4,0xad,0xb4,0x39,0x1c,0x0e,0x0c,0x29,0xbd,0x8a,0x92,0x8c,0xa5,0xa8,0x98,0x8c,0x81,0x84,0x80,0x86,0x89,0x92,0xa1 +,0x53,0x9a,0x95,0x86,0x8c,0x8f,0xdb,0x0e,0x0e,0x0c,0x1e,0x22,0x3c,0x1a,0x0e,0x03,0x04,0x00,0x05,0x0a,0x2d,0x6b,0x1e,0x13,0x01,0x03,0x02,0x0c,0x1a,0x46,0x24,0x1c +,0x0a,0x08,0x00,0x04,0x0f,0x43,0x93,0x9e,0x9b,0x24,0x29,0x2a,0xb7,0x99,0x8f,0x8c,0x8b,0x8b,0x90,0xa3,0xfd,0xa3,0x91,0x86,0x87,0x85,0x8e,0x99,0x9e,0x96,0x8a,0x87 +,0x87,0x8b,0x99,0xa5,0x43,0x24,0xac,0x99,0x88,0x91,0x93,0x37,0x13,0x17,0x24,0x9f,0x95,0x93,0xb0,0x32,0x13,0x10,0x06,0x17,0x2e,0x99,0xa1,0x3d,0x1c,0x05,0x09,0x0b +,0x3f,0xba,0xa1,0x6a,0x1f,0x0c,0x08,0x02,0x05,0x17,0xd5,0x9a,0xb0,0xea,0x0c,0x09,0x08,0x16,0x45,0xb1,0xc2,0x3d,0x27,0x19,0x0d,0x0c,0x25,0xab,0x8b,0x8f,0x8c,0xb4 +,0xbe,0xdd,0x9a,0x8a,0x89,0x87,0x8e,0x94,0xae,0xcb,0x1a,0xc1,0xbe,0x92,0xa1,0x9e,0x57,0x16,0x20,0x1f,0x9f,0xa1,0x99,0x62,0x3c,0x19,0x1a,0x0f,0x3c,0x98,0x8a,0x8b +,0x9a,0xa0,0x1e,0xaa,0xa0,0x83,0x81,0x83,0x85,0x8f,0x9e,0xaa,0xb7,0xa1,0x8b,0x85,0x85,0x94,0x9d,0x18,0x17,0x12,0x2f,0xc0,0xb8,0xc2,0x1c,0x0d,0x04,0x04,0x00,0x0a +,0x0b,0x19,0x14,0x10,0x0a,0x02,0x04,0x06,0x13,0x18,0x1e,0x0e,0x0b,0x04,0x06,0x01,0x0c,0x1b,0xb4,0x99,0x9e,0x9f,0x31,0xb3,0xb4,0x88,0x8a,0x87,0x8d,0x9b,0xa2,0xaa +,0xc2,0xa0,0x8f,0x8e,0x8a,0x95,0x97,0xcb,0x9c,0x9b,0x8a,0x8a,0x8a,0x8d,0x9f,0xbc,0x3c,0x2f,0xa5,0x8b,0x89,0x87,0x9a,0xa5,0x29,0x52,0xc3,0x97,0x91,0x96,0x9e,0x30 +,0x18,0x0d,0x0b,0x09,0x2e,0x39,0x9d,0x2e,0x1c,0x0b,0x07,0x09,0x1a,0xbd,0xb2,0xa9,0x1a,0x15,0x08,0x0b,0x07,0x2a,0x3c,0x9b,0xad,0x6b,0x1f,0x0b,0x10,0x11,0xeb,0x78 +,0xa3,0x24,0x18,0x09,0x0b,0x05,0x19,0x27,0xab,0xba,0x4a,0xb4,0x36,0x9a,0x9d,0x87,0x8f,0x8b,0x9d,0x9c,0xa0,0x9f,0xbd,0xa0,0x98,0x91,0x8e,0xb4,0xb7,0x17,0xe0,0x4b +,0x98,0xa9,0xac,0x29,0x19,0x15,0x11,0x15,0x32,0xac,0xa8,0x9d,0x35,0xb1,0x24,0xb4,0xab,0x8b,0x87,0x85,0x86,0x90,0x97,0x9f,0x95,0x8b,0x85,0x85,0x84,0x90,0x8f,0xc7 +,0x4f,0x38,0xae,0xa6,0x9e,0xba,0x19,0x0b,0x03,0x02,0x00,0x08,0x0b,0x1b,0x0b,0x0a,0x04,0x03,0x04,0x0b,0x10,0x16,0x12,0x09,0x0c,0x08,0x0b,0x0b,0x19,0x1d,0xb6,0x26 +,0xc4,0x3d,0x39,0xc9,0xa2,0x8f,0x8c,0x8a,0x98,0x9a,0xb5,0xad,0x7d,0x9a,0xa1,0x8d,0xa2,0x95,0x96,0x9a,0x8d,0x91,0x8c,0x92,0x8a,0x9e,0x99,0xb6,0xc7,0xcf,0x91,0x8a +,0x82,0x8d,0x97,0xac,0x22,0xc6,0xc3,0x98,0x9a,0x95,0x5d,0x29,0x0f,0x0c,0x0b,0x1b,0x2f,0xa5,0xaf,0xf9,0x30,0x0e,0x0f,0x10,0x32,0x48,0x9b,0x32,0x1c,0x0b,0x09,0x07 +,0x17,0x2f,0x5c,0x3a,0x15,0x1c,0x0a,0x0e,0x0f,0x1d,0x1e,0x45,0x20,0x1f,0x12,0x0e,0x0b,0x1b,0x46,0xb4,0xa9,0x33,0x5f,0x23,0x9f,0x9c,0x8f,0x9b,0x97,0xa0,0x97,0xa0 +,0xa6,0xbb,0xac,0x95,0x90,0x8e,0xbd,0x9f,0x29,0x32,0x1e,0xb2,0xad,0x92,0x9a,0xb7,0x2a,0x1b,0x19,0x16,0x70,0xab,0x92,0x96,0x8f,0x38,0x52,0x43,0x9f,0x91,0x87,0x84 +,0x8c,0xa5,0x28,0x15,0xa4,0x84,0x83,0x81,0x93,0xb3,0x1a,0x3e,0x27,0xaf,0x3b,0x27,0x38,0xbd,0x3e,0x11,0x09,0x04,0x0f,0x18,0x44,0x0f,0x0b,0x04,0x0a,0x1d,0xaa,0xe9 +,0x1d,0x0d,0x0a,0x0e,0x11,0x24,0x19,0x3d,0x39,0x9f,0x9e,0x90,0xd8,0x23,0x14,0x25,0xa1,0x92,0x8e,0x9f,0x9c,0x1e,0x1c,0x17,0xb0,0x8f,0x87,0x9a,0x49,0x11,0x12,0x2f +,0xbe,0xa7,0xa1,0x99,0x9e,0xaa,0x1b,0x14,0x0e,0xae,0x8c,0x81,0x89,0x95,0x10,0x09,0x1c,0x9b,0x87,0x95,0xa7,0x19,0x23,0x26,0x58,0x21,0x43,0x17,0x4e,0xc0,0xa4,0xac +,0x28,0x27,0x17,0xd8,0xaa,0x97,0xb6,0x68,0x20,0xe5,0xa9,0x91,0x8f,0x88,0x92,0x9b,0xc1,0x2d,0x39,0x45,0xbc,0x1f,0xd7,0xb2,0x9b,0xc4,0x17,0x02,0x0a,0x14,0x9a,0x97 +,0xad,0x12,0x03,0x0a,0x1c,0x9e,0x9b,0x98,0x37,0x1b,0x0e,0x0e,0x0f,0x3f,0xba,0x8d,0x8d,0x8c,0xbc,0x11,0x0b,0x07,0x26,0xbb,0x9a,0xbe,0x2a,0x08,0x06,0x08,0x38,0x9f +,0x8b,0xa2,0x3c,0x19,0x15,0xee,0xa0,0x90,0x35,0x2e,0x26,0xa3,0x99,0x9e,0x24,0x30,0xb8,0x8b,0x89,0x85,0x94,0x2f,0x51,0xaa,0x89,0x8a,0x89,0xa0,0x9e,0x9c,0x9b,0xc1 +,0x9f,0xad,0x8e,0x91,0x8e,0x9d,0x4c,0xd9,0x43,0x9b,0xc4,0xb2,0x2f,0x51,0x23,0x19,0x0b,0x13,0x1b,0xa3,0xa2,0x93,0x6b,0x09,0x06,0x09,0x3c,0x96,0x85,0x97,0xb3,0x18 +,0x12,0x0d,0x3c,0x33,0xa2,0x38,0x28,0x1a,0x0e,0x0d,0x06,0x0e,0x0d,0x14,0x06,0x08,0x03,0x02,0x00,0x06,0x0e,0xa6,0xb3,0xa9,0x22,0x09,0x0f,0x22,0x9c,0x9c,0x9c,0x2c +,0x42,0xb0,0x9a,0x99,0x8c,0x8e,0x8b,0x99,0x8f,0x8d,0x8b,0x8b,0x96,0x95,0x94,0x88,0x8a,0x86,0x90,0xbe,0x60,0x9a,0x8c,0x83,0x85,0x82,0x8c,0x9a,0xae,0xa1,0x94,0x99 +,0x91,0x99,0x9c,0xad,0x26,0x0b,0x09,0x0a,0xb5,0xa5,0x9a,0x1e,0x04,0x03,0x05,0x14,0x3b,0x73,0x17,0x0d,0x08,0x07,0x09,0x29,0xbc,0x9c,0x3d,0x34,0x1b,0x16,0x1a,0x1f +,0x37,0x30,0x37,0x34,0x26,0x22,0x12,0x0f,0x27,0x28,0xc4,0x18,0x1d,0x0e,0x16,0x23,0xbf,0x95,0x9c,0xa6,0x2b,0x28,0xbf,0xb4,0xc6,0xa9,0xd9,0x97,0x92,0x87,0x8e,0xaa +,0x26,0x2f,0xa4,0x97,0x92,0x95,0x94,0x9f,0xe9,0x46,0xaa,0x9a,0x88,0x8a,0x86,0x8b,0x8c,0x90,0x8c,0x8f,0x8a,0x85,0x83,0x83,0x8e,0xa8,0x20,0xa6,0x96,0x87,0x90,0x92 +,0x20,0x09,0x09,0x0f,0x1e,0x1b,0x0f,0x05,0x05,0x04,0x07,0x02,0x09,0x02,0x0c,0x09,0x13,0x0a,0x02,0x04,0x07,0x0f,0x12,0x0f,0x03,0x07,0x02,0x0b,0x0a,0x47,0x4e,0x9a +,0xbb,0xc1,0x9f,0x9c,0x8e,0x95,0x95,0xaf,0x8b,0x8a,0x80,0x8c,0x92,0x56,0xa3,0x93,0x8b,0x8b,0x92,0x94,0x42,0xaa,0xb6,0x8e,0x93,0x8a,0x9f,0x9b,0x9f,0xa1,0x27,0x27 +,0x36,0xaf,0x88,0x8a,0x87,0x45,0x7d,0x2d,0x8f,0x8e,0x8b,0x9c,0xd7,0x1f,0x1c,0x1c,0x18,0x40,0x16,0x21,0x08,0x0f,0x08,0x19,0x13,0x12,0x0b,0x13,0x18,0x19,0x1f,0x0c +,0x0a,0x0d,0x6e,0x1d,0xaf,0x2e,0xde,0x1f,0x35,0xce,0xb7,0x9c,0xa5,0xb9,0x1f,0xe4,0x5b,0x30,0x08,0x0f,0x0e,0xc1,0x9e,0xad,0x1e,0x03,0x0f,0x2d,0x95,0xa6,0xa3,0x1f +,0x29,0xbb,0xac,0xb6,0xa7,0x8a,0x8c,0x84,0x8b,0x84,0x89,0x89,0x92,0x8a,0x84,0x82,0x80,0x84,0x87,0x9c,0x8e,0x9e,0x89,0x95,0xa4,0x1e,0x1d,0x21,0x0e,0x3c,0x1b,0x0e +,0x02,0x10,0x07,0x10,0x17,0x04,0x00,0x01,0x06,0x07,0x17,0x07,0x05,0x02,0x10,0x18,0x0f,0x15,0x1b,0x4b,0x1c,0x79,0x30,0x20,0x08,0x18,0xa5,0xac,0xa6,0x8f,0x8d,0x15 +,0x2f,0x9a,0x8d,0x8d,0x83,0x94,0x18,0x4f,0x97,0x8d,0x96,0x88,0x99,0x32,0x9b,0x88,0x85,0x90,0x8e,0x8c,0x90,0x90,0x84,0x80,0x99,0x46,0x98,0x8e,0xd7,0x95,0x93,0x0f +,0x0d,0xdb,0x6c,0x0e,0x1b,0x15,0x07,0x0e,0xb7,0xcb,0x13,0x1b,0x18,0x0d,0x0c,0x7b,0x9c,0x28,0x13,0x1c,0x22,0x17,0xb2,0x8f,0x29,0x0d,0x33,0xcd,0x1a,0x5e,0xbe,0x0d +,0x04,0x10,0x18,0x0e,0x1d,0x16,0x08,0x06,0x23,0x47,0x25,0x21,0x1a,0x18,0x17,0x9a,0x87,0x9b,0x18,0x26,0xa2,0x9d,0x8b,0x81,0x98,0x1e,0xd0,0x98,0x9b,0x8d,0x87,0x9c +,0xaa,0x89,0x84,0x89,0x87,0x88,0x8f,0x8e,0x84,0x80,0x84,0x8f,0x9c,0x9c,0xa3,0x91,0x85,0x8f,0x2b,0x42,0x9e,0xd1,0xaf,0x97,0x25,0x04,0x09,0x1a,0x14,0x19,0x12,0x02 +,0x00,0x01,0x0b,0x15,0x12,0x0a,0x01,0x00,0x04,0x19,0x1e,0x0a,0x08,0x0f,0x0e,0x13,0xc1,0x2c,0x07,0x0c,0xd6,0xa8,0xa8,0x95,0xd2,0x16,0xbf,0x89,0x86,0x85,0x88,0xa8 +,0x2e,0x95,0x83,0x83,0x88,0x96,0xa9,0x5a,0xab,0x8c,0x8a,0xae,0x42,0x9e,0x9a,0x98,0x89,0x8a,0x54,0x29,0xa6,0x9b,0x95,0x89,0x9c,0x12,0x18,0xa2,0x90,0x8f,0x8f,0xad +,0x1c,0x24,0x9a,0x8f,0xdd,0x15,0x15,0x15,0x17,0xae,0x9f,0x0d,0x00,0x04,0x09,0x10,0xc4,0xbd,0x0a,0x01,0x08,0x13,0x1d,0x42,0x26,0x0b,0x0a,0x27,0xaf,0xfc,0x3c,0x3f +,0x2f,0x35,0xa1,0x8f,0x3b,0x0b,0x0f,0x30,0x5a,0x98,0x8c,0xd6,0x0b,0x0c,0x24,0x3b,0x97,0x92,0x3b,0x0e,0x15,0xd9,0x9d,0x8f,0x91,0xae,0xf8,0x8d,0x82,0x81,0x84,0x85 +,0x84,0x86,0x82,0x80,0x80,0x8b,0xa3,0x92,0x8c,0x8a,0x86,0x95,0x26,0x1b,0x42,0xc9,0x40,0x1c,0x09,0x01,0x06,0x0f,0x10,0x08,0x04,0x01,0x01,0x02,0x0f,0x1d,0x09,0x04 +,0x05,0x06,0x0c,0x30,0xb8,0x1f,0x0f,0x12,0x11,0x1c,0xc6,0xb7,0x20,0x1d,0x33,0xc6,0xa4,0xa2,0x24,0x0b,0x16,0xa2,0x8c,0x8e,0x9a,0xac,0x67,0xae,0x87,0x81,0x87,0x9d +,0xb4,0xb0,0x9b,0x86,0x82,0x89,0x9b,0x93,0x8d,0x8c,0x8c,0x8f,0xb3,0xc2,0x9d,0x96,0x96,0x98,0xaf,0x1f,0x15,0x2b,0xc3,0x39,0x32,0x3c,0x2b,0x19,0x2c,0xad,0xd4,0x1e +,0x21,0x1f,0x21,0xb2,0x99,0xf3,0x10,0x0d,0x11,0x2c,0x97,0x9b,0x0d,0x01,0x03,0x0a,0x0f,0x19,0x1e,0x0d,0x06,0x0f,0xd7,0xd8,0x1b,0x0f,0x19,0x1d,0x3a,0x9c,0xa5,0x1e +,0x18,0x2c,0x2b,0x30,0x67,0x30,0x1d,0x4f,0xa9,0xb2,0xac,0x99,0xa5,0x21,0x1d,0xc3,0x9d,0x9a,0x90,0x91,0x98,0x98,0x8a,0x83,0x85,0x87,0x86,0x8a,0x8a,0x82,0x80,0x81 +,0x88,0x8b,0x8b,0x85,0x81,0x89,0x42,0x15,0x3f,0xc1,0x3b,0x2a,0x19,0x07,0x05,0x0c,0x16,0x0b,0x03,0x02,0x01,0x01,0x07,0x1d,0x14,0x06,0x07,0x08,0x06,0x06,0x0c,0x0d +,0x0f,0x1d,0x1e,0x1b,0x25,0xd2,0x2f,0x0f,0x15,0x20,0x3e,0xb3,0x9e,0xa6,0x34,0x49,0x9e,0x90,0x91,0x94,0x9b,0xbd,0xa1,0x88,0x84,0x8c,0xa9,0xb7,0x96,0x87,0x83,0x8b +,0xb1,0xba,0x96,0x8f,0x8c,0x89,0x90,0xae,0xae,0x9d,0x9d,0xa4,0xa6,0xa6,0x2d,0x2d,0x98,0x91,0xa7,0x3a,0x30,0x1f,0x1c,0x1f,0x2d,0x3d,0x30,0x31,0x1b,0x1a,0x77,0xbf +,0x25,0x11,0x0e,0x0e,0x1d,0xb9,0xfb,0x15,0x07,0x09,0x0f,0x1a,0x25,0x16,0x09,0x0a,0x19,0xaf,0xb8,0x1b,0x0f,0x0a,0x14,0xb8,0xa7,0x33,0x12,0x18,0x1f,0x11,0xa7,0x90 +,0xcf,0x29,0x2a,0x3e,0x2b,0xad,0x9b,0xae,0x34,0xa5,0x8b,0x89,0x89,0x8b,0x8d,0x96,0x92,0x8a,0x85,0x82,0x82,0x84,0x89,0x86,0x82,0x82,0x89,0x96,0x9d,0x9f,0x8c,0x83 +,0x8d,0x49,0x1e,0x2d,0x21,0x1f,0x3e,0x15,0x07,0x0a,0x0f,0x0f,0x0b,0x09,0x05,0x00,0x05,0x0f,0x0d,0x07,0x08,0x0a,0x06,0x08,0x13,0x1d,0x0f,0x0a,0x10,0x0f,0x0c,0x1d +,0x42,0x16,0x14,0xbc,0x9c,0x9a,0x94,0x96,0xbe,0x2b,0xbd,0x9c,0x8d,0x89,0x8e,0xa5,0xbc,0x8f,0x89,0x8d,0xa4,0xab,0x97,0x92,0x88,0x86,0x8e,0xa9,0xad,0x9a,0x9e,0x9f +,0x92,0x98,0xa8,0x98,0x8c,0x8e,0x8a,0x8e,0xb7,0xb5,0xa0,0x9a,0xb8,0x1f,0x2f,0x38,0x3c,0xd0,0x22,0x3a,0x33,0x20,0x20,0x1e,0x29,0x9d,0xab,0x1a,0x0c,0x11,0x11,0x20 +,0x24,0x10,0x0f,0x08,0x26,0x17,0x25,0xa4,0x8b,0x16,0x09,0x84,0xb0,0x0d,0x17,0x00,0x0e,0x12,0x44,0x1e,0x0f,0x0f,0x02,0x1f,0x00,0x0e,0x0f,0x08,0x0e,0x02,0x08,0x02 +,0x02,0x11,0x0c,0x2a,0x16,0xc0,0x9d,0x9e,0x88,0xa3,0x84,0x8d,0x8b,0x87,0x80,0x8c,0x34,0x87,0x80,0x80,0x81,0x83,0x80,0x81,0x80,0x81,0x86,0x82,0x84,0x82,0x90,0x8b +,0xf8,0xa3,0x82,0x95,0x82,0xc8,0x95,0xa6,0xa7,0xae,0x0d,0xaa,0x2e,0x2e,0x0d,0x00,0x08,0x00,0x0f,0x0a,0x0f,0x18,0x02,0x1d,0x02,0x03,0x00,0x02,0x0a,0x02,0x06,0x00 +,0x04,0x00,0x01,0x09,0x06,0x4a,0x07,0x1e,0x12,0x05,0x0c,0x00,0x42,0x20,0x9d,0x12,0x05,0x15,0x06,0x87,0x9d,0x8c,0x8f,0xa8,0x80,0x8d,0x83,0xac,0x89,0x81,0x83,0x86 +,0x8f,0x80,0x8a,0x83,0x80,0x80,0x80,0x87,0x81,0x86,0x86,0x84,0x93,0x80,0x84,0x80,0x8d,0x97,0x8c,0xa6,0x80,0x89,0x80,0x8c,0xa0,0x85,0x93,0x8e,0x14,0x9f,0x86,0x8a +,0x8a,0x18,0x2c,0x0c,0x02,0xaa,0x15,0x9e,0x0f,0x09,0x12,0x00,0x08,0x00,0x04,0x07,0x04,0x04,0x00,0x03,0x00,0x02,0x0e,0x03,0x0e,0x01,0x0f,0x09,0x00,0x04,0x00,0x0d +,0x14,0x0d,0x08,0x00,0x07,0x00,0x13,0x1d,0x27,0x3e,0x05,0xae,0x0e,0x23,0x09,0x0c,0x96,0x9c,0x95,0xba,0x29,0x2e,0x2e,0x80,0x86,0x80,0x8b,0x93,0x87,0xb2,0x93,0x29 +,0x89,0x81,0x82,0x87,0xbd,0xad,0x2b,0x2e,0x80,0x87,0x80,0x9f,0x91,0x8b,0xab,0x9a,0x0d,0x9b,0x84,0x80,0x84,0xa3,0xa8,0x4c,0xb4,0x80,0x8a,0x80,0x22,0x9e,0x9c,0xa7 +,0xa4,0x1f,0x8d,0x97,0x83,0x96,0xa9,0xaa,0x25,0x24,0x84,0x90,0x80,0x20,0x9b,0x92,0x95,0x8a,0x52,0x84,0x87,0x81,0x94,0x38,0x30,0x2e,0xb8,0x80,0x89,0x80,0x41,0x96 +,0xa8,0x9a,0x96,0x6b,0x87,0x88,0x80,0xa3,0x1e,0x0f,0x0c,0x0c,0x86,0x87,0x80,0x1a,0x0d,0x0c,0x09,0x0b,0x02,0x0e,0x0d,0x1c,0x02,0x04,0x00,0x03,0x00,0x18,0x16,0x1e +,0x0c,0x00,0x04,0x00,0x01,0x00,0x02,0x07,0x08,0x02,0x07,0x00,0x04,0x00,0x0f,0x13,0x08,0x05,0x00,0x01,0x00,0x02,0x00,0x05,0x09,0x0c,0x03,0x07,0x00,0x06,0x00,0x39 +,0x99,0xa9,0x29,0x02,0x13,0x05,0xa5,0x8d,0x83,0x80,0x84,0x86,0x8e,0x9c,0x94,0xa2,0x85,0x80,0x80,0x80,0x96,0x83,0x9e,0x85,0x80,0x81,0x80,0x81,0x80,0x88,0x8f,0x8e +,0x8f,0x84,0x80,0x82,0x80,0x8d,0x81,0x94,0x8b,0x86,0x87,0x80,0x83,0x80,0x89,0x8d,0xaa,0x9e,0xa3,0x81,0x85,0x80,0x9c,0xb6,0xbd,0xb7,0x8d,0xb0,0x8b,0xbc,0x8d,0x28 +,0x2c,0xf7,0xb1,0x1b,0xa0,0x90,0xb2,0xef,0x00,0x16,0x02,0x22,0x0f,0x28,0x17,0x1d,0x0a,0x00,0x05,0x05,0x0a,0x04,0x9c,0x18,0x11,0x02,0x04,0x00,0x0b,0x09,0x26,0xc8 +,0x20,0x2c,0x00,0x05,0x00,0x08,0x02,0xad,0x99,0x1c,0x0e,0x00,0x07,0x00,0x17,0x13,0x57,0x1c,0xda,0x0a,0x07,0x00,0x08,0x06,0x0f,0x87,0x46,0x8f,0x0d,0x24,0x0e,0x1b +,0x26,0x49,0xc5,0xab,0x9e,0x0d,0x1a,0x0a,0x55,0x0e,0x8f,0x91,0x88,0xa9,0x2f,0xce,0x19,0x92,0xec,0x88,0x9a,0x8b,0x9e,0x3d,0x9e,0x87,0x8b,0x89,0x82,0x95,0x86,0x23 +,0x8d,0x9c,0x8a,0x88,0x8d,0x8c,0x99,0x94,0x37,0x98,0xa6,0x88,0xe7,0x89,0x95,0x8f,0x37,0x0d,0x1f,0x19,0x9f,0xaa,0x88,0x39,0x9e,0x0d,0x0d,0x0d,0x1f,0x1c,0x1a,0x8d +,0xae,0xb4,0x04,0x0c,0x03,0x1f,0xab,0x98,0xab,0x18,0x16,0x04,0x15,0x11,0xbf,0x0c,0x96,0xa1,0x92,0xaf,0x11,0x40,0x0f,0x9f,0xa9,0x89,0xad,0x8d,0xaf,0xa6,0x54,0xad +,0xab,0x56,0x83,0x87,0x81,0xd6,0xaf,0x21,0x9b,0x8f,0x8b,0x95,0xa5,0x96,0xe9,0x91,0x9e,0x8d,0x3e,0x93,0x92,0x8d,0xbb,0x0f,0x23,0x1f,0x95,0xb1,0x98,0x1d,0x4f,0x18 +,0xbb,0x52,0xcd,0x1f,0x07,0x9b,0xbb,0x92,0x0c,0x11,0x0a,0x30,0xa8,0x95,0x9f,0x39,0x3a,0x09,0x5c,0x13,0xa9,0x0f,0xa9,0x99,0xb5,0x2b,0x04,0x16,0x14,0x8c,0x96,0x8c +,0x26,0x1f,0x0e,0x1c,0x38,0x30,0x3e,0x07,0x95,0xaa,0x88,0x3c,0x24,0x2a,0x25,0x97,0xa6,0xb2,0x2f,0xd0,0x27,0xa6,0x1f,0xbc,0x0b,0x2b,0x8c,0x88,0x8a,0x0f,0x12,0x0d +,0xae,0x8f,0x8f,0xba,0x28,0x17,0x2b,0x46,0x9a,0xa2,0x17,0xb2,0xa1,0x8f,0x1f,0x13,0x17,0x29,0xa1,0xab,0x3b,0x16,0x15,0x1e,0xae,0xae,0xad,0x0d,0x0b,0xba,0x92,0x8e +,0x1d,0x11,0x11,0x4c,0x97,0x8e,0x94,0x6d,0x2c,0x26,0x39,0x3f,0xd0,0x1e,0xb4,0x8f,0x8b,0xde,0x0b,0x07,0x14,0xa5,0x8b,0x95,0x3c,0x15,0x15,0x3e,0xb2,0xb7,0x20,0x0a +,0x2c,0x8f,0x8c,0x90,0x14,0x1f,0x19,0x9c,0x8f,0x97,0xa5,0x2f,0x4e,0x2b,0x2e,0x25,0x16,0x18,0x8b,0x86,0x87,0x1b,0x04,0x08,0x1b,0x8e,0x94,0xa0,0x16,0x1a,0x1a,0x38 +,0x9f,0xb3,0x21,0x29,0x94,0x91,0x9a,0x0d,0x11,0x19,0xa3,0x8f,0xa3,0x3d,0x15,0xba,0xcc,0x9c,0x38,0x19,0x0b,0xa2,0x85,0x86,0x3c,0x02,0x08,0x12,0x94,0x8a,0x8d,0xc3 +,0x40,0x1b,0x23,0x24,0x3a,0x21,0x3f,0x89,0x8e,0xa1,0x09,0x04,0x10,0xad,0x82,0x8c,0x9f,0x18,0x1d,0x36,0xaf,0xa7,0x4c,0x14,0xb2,0x8d,0x95,0xab,0x08,0x1c,0x17,0x91 +,0x8e,0x96,0x45,0x1c,0x1f,0x14,0x25,0x21,0x1c,0x21,0x87,0x8c,0x93,0x0a,0x07,0x0e,0x9f,0x81,0x8b,0x9d,0x0c,0x14,0x18,0x63,0x9d,0x9b,0xbf,0x95,0x8b,0xa2,0x11,0x02 +,0x0e,0x2c,0x87,0x8e,0xa3,0x0f,0x0a,0x37,0xad,0x93,0xd5,0x1f,0x17,0x8e,0x90,0xa7,0x0a,0x0c,0x24,0x91,0x82,0x97,0xa5,0x14,0x53,0x2b,0xbe,0x24,0x1f,0x19,0x93,0x8b +,0x9b,0x0e,0x03,0x0f,0xb6,0x80,0x8b,0x9d,0x06,0x0e,0x15,0x9a,0x9c,0xaf,0x11,0xb3,0x8c,0x8d,0x43,0x03,0x1d,0x44,0x81,0x8c,0xa4,0x09,0x0c,0x14,0x9a,0x95,0xcf,0x08 +,0x13,0x99,0x8b,0x95,0x0b,0x12,0x0e,0x8d,0x8b,0x8e,0x25,0x13,0x13,0x4e,0xa6,0xa9,0x1b,0x35,0x87,0x8a,0x94,0x09,0x0e,0x0d,0x95,0x8e,0x90,0x1f,0x0d,0x11,0x19,0xa9 +,0x9d,0xc4,0xc2,0x97,0xa2,0xb6,0x06,0x1a,0x19,0x8d,0x8d,0x8e,0x2c,0x1d,0x26,0x39,0xa3,0xec,0xc6,0xcd,0x8c,0xa1,0xc6,0x04,0x15,0x19,0x8e,0x96,0xa8,0x31,0x7c,0xa2 +,0xc3,0x2b,0x11,0x15,0xf9,0x83,0x8f,0xa1,0x04,0x10,0x1e,0x88,0x8a,0xa2,0x18,0x1f,0xba,0x9f,0xbc,0x16,0x0b,0x20,0x87,0x8c,0x9f,0x03,0x0b,0x1a,0x86,0x86,0x9b,0x0b +,0x07,0x1a,0x9f,0x94,0xaa,0x10,0x26,0x94,0x8d,0xab,0x03,0x09,0x0f,0x85,0x85,0x86,0x14,0x0d,0x0c,0x2c,0x75,0x2a,0x0e,0x38,0x8b,0x85,0x96,0x0b,0x11,0x0d,0x8f,0x93 +,0x8e,0x1d,0x1d,0x11,0xe9,0xad,0x45,0x18,0xb9,0x8e,0x8b,0xe1,0x0c,0x18,0x1a,0x96,0xac,0xa2,0x1c,0x3c,0x1c,0x3f,0xe9,0x64,0x39,0x8f,0x8c,0x95,0x0b,0x08,0x19,0x93 +,0x88,0x97,0x44,0x0b,0x23,0x2b,0x9e,0x21,0x1c,0x1d,0x8a,0x85,0x94,0x06,0x02,0x05,0x95,0x84,0x87,0x46,0x0e,0x26,0xc9,0x9b,0x31,0x13,0x16,0x8b,0x85,0x88,0x0d,0x0c +,0x08,0x9a,0x92,0x90,0x1c,0x0c,0x1e,0xaf,0x97,0xc9,0x10,0x28,0x96,0x8d,0xaf,0x07,0x0a,0x0e,0x89,0x86,0x85,0x34,0x14,0x0f,0xca,0x9b,0xb8,0x1a,0xc3,0x9a,0x8b,0x2d +,0x0c,0x09,0x1f,0x90,0x8c,0x8f,0x27,0x1a,0x07,0x18,0x1d,0x2f,0xa6,0x8e,0x8d,0x9a,0x0c,0x14,0x19,0x8f,0x8c,0x92,0x42,0x26,0x6d,0xd5,0xbd,0x1b,0x0f,0x36,0x91,0x86 +,0xb1,0x0a,0x0c,0x0f,0x8b,0x8f,0x98,0x0d,0x0d,0x1b,0xaa,0x9b,0x5d,0x15,0xae,0x90,0x85,0xd1,0x0b,0x08,0x17,0x8d,0x88,0x8a,0x39,0x22,0x13,0x23,0x39,0x0e,0x1e,0x96 +,0x8b,0x8a,0x0f,0x07,0x06,0xa7,0x88,0x87,0x6b,0x0d,0x0b,0x19,0x9e,0xa4,0x4e,0xa5,0x95,0x89,0x9a,0x14,0x0d,0x09,0xa7,0xa7,0x92,0xb3,0x3b,0x1f,0xb4,0xa6,0xad,0x27 +,0x4f,0x55,0x96,0x2c,0x30,0x1c,0x1e,0xa3,0x53,0xaa,0x2a,0xb8,0x2d,0x2f,0x1f,0x2a,0xb9,0x89,0x89,0x88,0x0d,0x06,0x02,0x2e,0x9a,0x8b,0x93,0x58,0xae,0x23,0x3a,0x13 +,0x0d,0xb2,0x97,0x8e,0xac,0x04,0x11,0x19,0x89,0x87,0x85,0x45,0x11,0x11,0x20,0x7d,0x2f,0x1d,0x9b,0x89,0x88,0x23,0x05,0x08,0x1d,0x92,0xa6,0x3b,0x13,0xa5,0x94,0x8e +,0xae,0x20,0x0a,0x5d,0xa4,0x89,0x21,0x15,0x13,0xbe,0x8a,0x8e,0x92,0x1e,0x0f,0x0b,0x29,0x19,0x15,0x1b,0x88,0x84,0x82,0x13,0x0e,0x06,0xdd,0x8f,0xa2,0x30,0x0b,0x19 +,0x39,0x94,0x98,0xac,0x4b,0x9d,0xa2,0x91,0x08,0x0b,0x09,0x94,0x8a,0x89,0xb9,0x1e,0x21,0x39,0xb2,0x17,0x0f,0x0b,0x8e,0x85,0x81,0x19,0x0c,0x01,0x28,0xb5,0x8c,0xfc +,0x1d,0x2a,0xc0,0x8e,0xb9,0xc0,0x54,0x91,0x9f,0xa4,0x04,0x07,0x07,0x8e,0x83,0x82,0x25,0x08,0x08,0x17,0x98,0x9c,0xff,0x12,0xaf,0x95,0x88,0x2e,0x2e,0x18,0x8f,0x97 +,0x9c,0x0d,0x06,0x07,0xd2,0x8e,0x9d,0x63,0x49,0x8e,0x96,0x8e,0x0a,0x0c,0x03,0xa4,0x8b,0x83,0xb8,0x20,0x18,0x30,0x2e,0x1e,0x13,0x2a,0x88,0x8b,0x84,0x15,0x0e,0x02 +,0xa5,0x91,0x88,0x2c,0x08,0x07,0x19,0x8d,0x8f,0x45,0x13,0xaa,0x92,0x8a,0x17,0x12,0x00,0x2a,0x8e,0x82,0x9f,0x12,0x0f,0x51,0x91,0x9a,0x29,0x13,0xb1,0xaa,0x8e,0x1b +,0x17,0x08,0xaf,0x90,0x89,0x66,0x0e,0x0d,0x63,0x8c,0x89,0x91,0x0c,0x22,0x26,0x9a,0x12,0x17,0x0d,0xa1,0x89,0x84,0xa9,0x06,0x09,0x0f,0x99,0xb5,0x31,0x0d,0x8d,0x88 +,0x80,0x9f,0x0f,0x04,0x09,0xba,0x90,0x8a,0x23,0x18,0x09,0x47,0xab,0x96,0x19,0x2c,0xe0,0x8f,0xa3,0x0b,0x0d,0x11,0x8a,0x8a,0x83,0x4c,0x24,0x07,0x44,0x44,0xa3,0xde +,0x2d,0x8e,0x8b,0x93,0x0f,0x1b,0x05,0x66,0xb5,0x8d,0x12,0x0f,0x1e,0xba,0x8d,0x9e,0x38,0x09,0x29,0xc2,0x90,0x18,0x2e,0x18,0x8f,0x8b,0x88,0x9c,0x12,0x0e,0x14,0x96 +,0x9b,0xa8,0x07,0x34,0xa6,0x86,0x9f,0x1d,0x09,0x0c,0xad,0x94,0x9b,0x0c,0x0d,0x1e,0x8e,0x9b,0x9b,0x1c,0x7e,0x94,0x8b,0xb5,0x0a,0x11,0x23,0x89,0x8c,0x8a,0x23,0x16 +,0x08,0x19,0xa8,0xdc,0x24,0x1f,0x97,0x91,0x90,0x16,0x09,0x04,0x4f,0x94,0x8d,0xb5,0x1a,0x22,0xa2,0x8d,0x9f,0x5e,0x09,0x78,0x9e,0x86,0xae,0x1c,0x0a,0x14,0xa5,0x91 +,0x8e,0x45,0x2a,0x16,0xc1,0x2a,0x46,0x0b,0x38,0x9e,0x8b,0x94,0x45,0x1e,0x0d,0xd3,0xa8,0x8f,0x37,0xe3,0x23,0xb1,0xb6,0x5f,0x1c,0x15,0xb2,0x9a,0x90,0x26,0x1f,0x19 +,0xc0,0xa5,0x95,0xc5,0x16,0x1f,0x3c,0xb8,0x6f,0xca,0x1b,0xa3,0x8f,0x92,0x2c,0x0c,0x13,0x29,0x90,0x93,0x98,0x20,0x25,0x26,0x58,0xa0,0xb4,0xff,0x23,0x41,0xcb,0x9e +,0x2a,0x1f,0x10,0x2b,0xae,0x90,0x90,0xad,0xca,0x17,0x39,0x19,0xe4,0x31,0xa6,0x9a,0x91,0xc6,0x0f,0x12,0x0d,0xa4,0x96,0x88,0xb1,0x39,0x15,0x14,0x3a,0xd8,0xa6,0x32 +,0xb4,0xdd,0x96,0x73,0xcf,0x26,0x35,0xa8,0xb5,0x9b,0x2b,0x37,0x1d,0x54,0x28,0xd9,0x21,0x2d,0xa4,0x95,0x91,0x2e,0x22,0x0a,0x2e,0xae,0x8d,0xa9,0x32,0x19,0x1e,0xa1 +,0x9f,0x8e,0x3f,0xb1,0x79,0x59,0x22,0x27,0x20,0x2a,0x5e,0xb6,0x9e,0x3c,0x2f,0x16,0xbb,0xa1,0x9a,0x3c,0x12,0x41,0xa5,0x90,0xcd,0x14,0x10,0x29,0x94,0x8a,0x96,0x39 +,0x17,0x12,0x3f,0xb3,0x9b,0x23,0x39,0x3d,0xab,0x9e,0x1b,0x32,0x1c,0x95,0x96,0x94,0x19,0x10,0x18,0xad,0x96,0xb3,0x24,0x07,0x3d,0x9d,0x82,0x98,0xcc,0x0b,0x0c,0x34 +,0x98,0x8d,0xae,0x35,0x0f,0x4d,0x6e,0xaa,0x1d,0x21,0xab,0x97,0x96,0x17,0x14,0x0e,0xab,0x8f,0x8f,0xbf,0x1b,0x17,0x2e,0x96,0xa2,0x9c,0x0f,0x26,0x4a,0x95,0x99,0x42 +,0x2c,0x0c,0x38,0xd0,0x9d,0xc4,0xbc,0xb6,0x9c,0xb6,0x25,0x0c,0x10,0x90,0x8d,0x8c,0x13,0x0a,0x09,0x2a,0x8b,0x8a,0x88,0x2d,0x19,0x0f,0x1e,0xc3,0xab,0x23,0x29,0xb7 +,0x93,0xa1,0x1f,0x1e,0x13,0x98,0x9d,0x8f,0x2c,0x26,0xdd,0x3b,0xab,0x1f,0x2f,0x15,0xac,0x97,0x8b,0xac,0x18,0x09,0x10,0xa7,0x8f,0x8a,0x49,0x3f,0x10,0x28,0x23,0x66 +,0x4a,0xb2,0x8b,0x8f,0x9e,0x09,0x0b,0x0e,0xa0,0x8b,0x8a,0xbb,0x1e,0x19,0x16,0xab,0xb4,0x9e,0x15,0x5a,0xad,0x94,0xad,0x16,0x14,0x19,0x98,0x9a,0x99,0x1c,0x2d,0x25 +,0xb1,0x78,0x2c,0x1c,0x34,0x8a,0x8a,0x98,0x0a,0x0e,0x0a,0xaa,0x8e,0x86,0x9a,0x20,0x11,0x10,0xc6,0xc7,0xad,0x19,0xb4,0xa4,0x94,0x19,0x0e,0x1a,0xa3,0x86,0x92,0xa7 +,0x0c,0x1c,0x1c,0xa4,0xb3,0xe2,0x1e,0x2f,0x9b,0x96,0xa3,0x14,0x1b,0x19,0x94,0x97,0x95,0x24,0x13,0x1f,0x33,0xb5,0x27,0x1a,0x27,0x8e,0x89,0x8f,0x0f,0x0e,0x0b,0xa5 +,0x8c,0x8e,0x9f,0x15,0x20,0x18,0xac,0xbe,0xae,0x24,0xa4,0x9c,0x9f,0x1b,0x0b,0x1b,0x35,0x8a,0x95,0x9b,0x15,0x1e,0x28,0xa9,0xb0,0x2d,0x15,0x2c,0x90,0x91,0x99,0x17 +,0x27,0x17,0xb4,0xc8,0xb1,0xbe,0x4b,0xc7,0xc9,0xbc,0x4d,0x23,0x1f,0x99,0x9e,0x9d,0x0d,0x0f,0x0f,0xac,0x8c,0x8e,0x94,0x28,0x37,0x18,0x2d,0x2c,0xce,0x2f,0x9f,0xa5 +,0xa7,0x2f,0x1a,0x44,0x2d,0x96,0xbe,0xa8,0x26,0x2a,0x32,0x35,0xb7,0xed,0x2f,0xf4,0x9b,0x9d,0xaf,0x1e,0x4b,0x26,0xd5,0x68,0xa5,0x9b,0xa7,0x4b,0x0f,0x0d,0x1e,0x55 +,0xa3,0x8c,0x9b,0xa2,0x16,0x1f,0x1f,0xc2,0x9e,0xbc,0xc5,0x26,0x42,0x24,0x36,0xbc,0xae,0xaf,0x96,0xb1,0x4c,0x14,0x19,0xbb,0xac,0x9b,0xe5,0xaf,0xb0,0x6a,0x1e,0x11 +,0x1d,0xc9,0xda,0x93,0x96,0xa3,0x30,0x13,0x2e,0x27,0xa9,0x69,0xd6,0xaf,0x9c,0xa5,0x2a,0x1e,0x28,0x3b,0x9d,0x8d,0xbb,0x19,0x08,0x17,0x30,0x9b,0x96,0x96,0x9a,0xa0 +,0x39,0x13,0x16,0x20,0x23,0x4c,0x8f,0x9b,0xc0,0x11,0x2c,0xa1,0x90,0xa8,0x44,0x28,0x31,0x2f,0x22,0x34,0x45,0xf0,0xbb,0x94,0xac,0x35,0x12,0x3f,0xbd,0x9e,0xca,0xb7 +,0xa9,0xb8,0xd4,0x1c,0x1b,0x1b,0x18,0x40,0x8b,0x8b,0x96,0x18,0x19,0x1e,0xda,0xa9,0xb8,0xaf,0xc5,0x48,0x1a,0x15,0x43,0x6d,0x96,0x89,0x9b,0x2c,0x0a,0x1a,0x2a,0xad +,0xa1,0xab,0xa4,0xa9,0x26,0x18,0x1d,0x63,0xc4,0xb1,0x92,0xa9,0x3a,0x1b,0xd5,0xa0,0xad,0x25,0x12,0x31,0x9d,0xa1,0xc4,0x22,0x22,0x2d,0xa5,0x8a,0x94,0x2a,0x0e,0x16 +,0x53,0xd9,0x37,0xb9,0x9f,0x8e,0xab,0x3a,0x0e,0x0b,0x11,0xb2,0x88,0x91,0x26,0x0e,0x38,0x9f,0x8f,0xa0,0xcb,0x25,0xe3,0x35,0x27,0x1e,0x1b,0x34,0x98,0x8a,0x9d,0x24 +,0x13,0x29,0xb4,0x9f,0xd2,0x24,0x1e,0xd5,0xb3,0x9f,0x70,0x15,0x10,0xbb,0x8c,0x93,0x50,0x11,0x1b,0xbd,0x99,0x96,0xe5,0x38,0x73,0x4b,0xc6,0x1f,0x15,0x16,0xa1,0x8b +,0x8e,0xaf,0x17,0x11,0x1c,0x34,0xa1,0xa9,0x34,0x5f,0x58,0xa1,0xbd,0x24,0x17,0x33,0x9b,0x99,0xb5,0x28,0x23,0xb6,0x9a,0x9a,0xb4,0x25,0x1c,0x1b,0xab,0xa0,0xbb,0x26 +,0x25,0x29,0x3f,0xb1,0x46,0xf6,0x36,0xba,0xa4,0xa6,0x4e,0x1d,0x27,0xa5,0x93,0xa6,0x34,0x22,0x3a,0xc4,0xae,0x5e,0x28,0x1e,0x29,0xa8,0x8e,0x95,0x2d,0x0e,0x0f,0x24 +,0x56,0xb2,0xb0,0xaf,0xa7,0x9d,0xa0,0x59,0x19,0x23,0xb2,0x9b,0xb1,0x1f,0x28,0xb9,0x9c,0xab,0x47,0x2d,0x1d,0x26,0xac,0xa5,0x60,0x22,0x17,0x2c,0xa7,0x9e,0xb7,0x3e +,0xcd,0xae,0xac,0xd5,0x1f,0x17,0x3f,0x98,0x92,0xba,0x2a,0x2b,0xab,0x97,0xb1,0x20,0x1d,0x2e,0x34,0xbd,0xa8,0xc9,0x20,0x1b,0x2b,0x51,0x2f,0x3a,0x4a,0x9a,0x95,0x9e +,0xc6,0x27,0xcf,0xb2,0xa5,0xd7,0x27,0x27,0xc1,0x99,0xa7,0x2a,0x1c,0x27,0xb1,0xb0,0xf8,0x2e,0x3a,0x4b,0x37,0x3e,0x27,0x24,0x2a,0xa0,0x94,0x9d,0xca,0x18,0x28,0xaa +,0x92,0x9a,0xae,0xc8,0x32,0xd5,0xdf,0x2a,0x10,0x17,0xd3,0xd7,0xb3,0xd5,0x34,0xaf,0xab,0xb7,0x2d,0x21,0x21,0x3e,0x9e,0xa2,0xc7,0x3f,0x39,0xae,0x9e,0x9e,0x69,0x2d +,0x5c,0x5c,0x76,0xcc,0x57,0x49,0x9e,0xe7,0x6c,0x38,0x0a,0x0e,0x46,0x2f,0x5d,0x9b,0xe8,0x1e,0x9e,0x8e,0x9b,0x9d,0x12,0x11,0xe5,0x94,0xad,0xef,0xac,0xd8,0x94,0x9e +,0x1f,0x0a,0x23,0x33,0xc9,0xaf,0xbd,0xc6,0x1e,0x09,0x15,0x92,0x9a,0xb1,0x2e,0xbe,0x6d,0x2b,0x39,0x30,0xc5,0xa4,0x88,0x8a,0xc6,0x1a,0x41,0x9c,0xbe,0x1a,0x0d,0x1a +,0x5d,0x5c,0x27,0x2a,0x13,0x1b,0xb7,0x27,0x54,0x93,0x96,0x7d,0xa3,0x92,0x9d,0x2c,0x2a,0xea,0x94,0x8f,0x2f,0x37,0x34,0x17,0x1f,0x9c,0xdd,0x0e,0x13,0x2a,0xa4,0x8f +,0xad,0x28,0x1f,0x1b,0x36,0xa3,0xa4,0x28,0xd5,0x9d,0xa2,0xa3,0xa3,0x41,0x22,0x60,0xb9,0x41,0x2a,0xd4,0x9c,0xa9,0x1b,0x12,0xc5,0x98,0xa0,0xb2,0xdc,0x1f,0x09,0x0a +,0x49,0xbf,0xaf,0x96,0x96,0xa2,0x5d,0x8f,0x91,0x39,0x0f,0x12,0xb4,0xa6,0x21,0x1e,0x2b,0x34,0xa9,0xab,0x1d,0x0c,0x9a,0x8a,0x9c,0xef,0x2f,0x31,0x23,0x3d,0x9f,0x8d +,0xb5,0x18,0x13,0x25,0x32,0x4c,0x9b,0xee,0x0e,0x0e,0x43,0x9b,0x94,0x99,0x9d,0xb2,0x25,0x2b,0xc5,0xab,0xa5,0x95,0xae,0x17,0x0c,0x16,0xcb,0xb0,0xce,0xba,0x3e,0x1e +,0xb0,0x96,0x9f,0x3a,0x22,0x4a,0xa8,0xbd,0x25,0x26,0x4d,0x5b,0x32,0xbe,0x28,0x1f,0x9e,0x8d,0x8f,0x99,0xa1,0x3e,0x17,0x0d,0x16,0x4b,0xaf,0x24,0x1e,0x2e,0x29,0xa9 +,0x9a,0x4a,0x1e,0x9e,0x8d,0x99,0x2f,0x1d,0x57,0xa5,0xbb,0xc1,0xa1,0x9c,0xae,0x38,0x1e,0x11,0x1e,0xd7,0xb5,0x21,0x19,0x1c,0x45,0x7d,0xa2,0x91,0xa1,0x2e,0x17,0x19 +,0x38,0x95,0x86,0x8a,0xb7,0x19,0x12,0x23,0x27,0x3b,0x9e,0x96,0xba,0x2c,0x20,0x18,0x25,0xe1,0x96,0x94,0xb2,0x19,0x0e,0x1f,0x2e,0x47,0xbb,0x52,0x27,0x58,0xa1,0x99 +,0x98,0x90,0x8e,0x9d,0x30,0x14,0x1f,0x2b,0x3d,0x53,0x3f,0x24,0x27,0x47,0x2b,0x24,0x54,0x97,0x93,0xbc,0x2d,0x4e,0x45,0x1a,0x1c,0xb0,0x92,0x93,0xbd,0x1e,0x12,0x1a +,0x38,0xad,0xaa,0x4f,0x59,0xa4,0xa7,0xab,0xb5,0xc6,0xad,0x49,0x1e,0x1b,0xca,0x98,0x98,0xbd,0x26,0x19,0x2c,0x24,0x1d,0xd7,0xab,0xa5,0xd6,0xbe,0x76,0x41,0x31,0xe3 +,0xa1,0xa9,0xde,0x39,0x32,0x26,0x31,0xc8,0xae,0xc1,0xbb,0xd4,0xa6,0x9f,0xa2,0xaa,0x27,0x1b,0x15,0x28,0x37,0xbc,0xbb,0x43,0x2f,0x27,0x39,0x3e,0xdf,0xae,0x96,0x96 +,0xb4,0x2b,0x3c,0xca,0xbd,0x72,0xbd,0x9c,0x99,0xc0,0x20,0x1d,0x27,0x2b,0x29,0x2b,0x1d,0x19,0x30,0xa1,0x91,0x9a,0xa5,0xac,0x2f,0x19,0x1b,0xb7,0x94,0x9b,0x56,0x3c +,0x25,0x27,0x31,0xb6,0xbb,0xe7,0xaf,0xae,0x4c,0x23,0x2b,0x6c,0xaf,0xbd,0xc3,0x3a,0x2f,0x22,0x23,0x37,0xca,0xca,0xa5,0xaa,0xad,0xa0,0x9c,0x9c,0xb3,0x30,0x1b,0x1b +,0x1e,0x32,0xca,0xb1,0xe0,0x4b,0x1e,0x1c,0x20,0x74,0xaa,0xa6,0xac,0xc2,0xb7,0x9d,0x9b,0xc3,0xd9,0xd5,0xa7,0xa4,0xa6,0xbf,0x3e,0x24,0x25,0x3b,0x1b,0x0c,0x17,0x57 +,0xb1,0xab,0x9d,0xa0,0x36,0x1f,0x23,0x3a,0x6d,0xac,0x9a,0x9f,0x52,0x31,0x40,0x3c,0xdb,0xb0,0x96,0x91,0xba,0x1e,0x1d,0x4d,0x3e,0x3c,0x3b,0x51,0xcf,0x45,0x2a,0x18 +,0x14,0x1f,0xc7,0x99,0xa7,0x5e,0xab,0x9f,0x96,0x98,0x9b,0x4a,0x16,0x13,0x25,0xc2,0xb5,0xa4,0xb6,0x34,0x29,0x37,0x31,0x29,0x36,0xbb,0xb5,0xc6,0xbd,0xb3,0xaf,0xbe +,0xee,0xb8,0xb3,0xc5,0xbf,0xcc,0x3e,0x28,0x27,0x2b,0x2c,0x2e,0x59,0xc7,0xc6,0xb8,0xa5,0xa6,0x41,0x26,0x23,0x36,0xa7,0x9f,0xab,0xe5,0x2c,0x1f,0x23,0x37,0xdf,0x9d +,0x9f,0xbb,0xfb,0x3e,0x63,0x48,0x5e,0xbc,0xcc,0xdf,0xba,0xbe,0xd6,0x3e,0x2b,0x37,0x24,0x2a,0x67,0xd7,0xba,0xb6,0x9f,0xa4,0xc7,0x28,0x1f,0x2f,0x39,0xbb,0xa8,0xaa +,0xe4,0x37,0xc9,0xba,0x50,0x37,0x4d,0xd0,0xc8,0xbd,0xae,0xd2,0x3b,0xd5,0xae,0xb0,0x3a,0x2a,0x21,0x2b,0x22,0x27,0x28,0x1f,0x3a,0xc8,0xa0,0x99,0x98,0x9b,0x9e,0xca +,0x2c,0x1f,0x28,0xc7,0xa5,0x9b,0x9d,0xce,0x26,0x1c,0x1c,0x34,0xd8,0xf1,0x39,0xfe,0xb7,0xc3,0x4f,0x34,0x33,0x28,0x3a,0xaf,0xac,0xcb,0x46,0xc8,0xbf,0xdf,0x54,0xc3 +,0xb6,0xa4,0x9f,0xa8,0xb3,0x5d,0x3f,0x2f,0x3f,0x48,0x2e,0x32,0x3c,0x3f,0x26,0x1e,0x27,0x23,0x2b,0x32,0xb6,0xa8,0xad,0xb1,0xae,0x9d,0xa5,0xc1,0xbf,0x9f,0x9f,0xa6 +,0xd3,0x2b,0x23,0x1c,0x18,0x1f,0x35,0x2f,0x59,0x9f,0x99,0xa2,0xce,0x3f,0x34,0x1e,0x2d,0x51,0xbd,0xb6,0xae,0xaa,0x3e,0x27,0x31,0xe4,0xb8,0xbc,0xb3,0xab,0xdb,0xca +,0xbf,0xdf,0x42,0x32,0x44,0x37,0x39,0x5e,0x37,0x40,0x40,0x3f,0x3a,0xc6,0x9e,0x9b,0xa7,0xcd,0x6b,0x2a,0x1d,0x1d,0x5a,0xa6,0xa2,0xc5,0x47,0x30,0x2b,0x2b,0x3c,0xfb +,0x2f,0x3e,0xb6,0xa1,0xa8,0xb5,0xa0,0x9e,0xc6,0x2f,0x2e,0xbc,0x43,0xb8,0xb8,0x4a,0x35,0x20,0x2f,0x2a,0x2a,0xc4,0xb0,0xb7,0xc7,0xca,0xa5,0x6e,0x32,0x2f,0xfd,0x3a +,0x32,0x5a,0xf3,0xce,0xfb,0xc3,0xd7,0x3f,0x3a,0xa4,0x9c,0x9e,0xb6,0x3d,0x25,0x20,0x3b,0xbc,0xb8,0xc8,0xc2,0x3d,0x29,0x1f,0x21,0x2b,0xbc,0xae,0xad,0xac,0xb2,0xb9 +,0x3e,0x39,0x39,0xca,0xbf,0xc5,0xbe,0xa9,0xac,0xcc,0x2a,0x26,0x32,0x21,0x2e,0x4e,0xad,0xc3,0xac,0x9b,0xa0,0xc3,0xdf,0xba,0x45,0x3c,0x33,0x28,0x1e,0x2b,0x3e,0xd1 +,0x3b,0x30,0x4f,0xd7,0xb1,0xba,0xc3,0x7d,0xc9,0xaf,0xa1,0xad,0xb3,0xb8,0xef,0x38,0x36,0x2f,0x21,0x28,0x2f,0xcd,0xac,0x9c,0xa4,0xaf,0x3f,0x2c,0x23,0x23,0x36,0x3a +,0x67,0x42,0xc3,0xb1,0xaf,0x50,0x4a,0xd1,0xd0,0xde,0xab,0x9f,0xa9,0xba,0x51,0x4a,0x4b,0x6a,0xbf,0xcd,0x25,0x2c,0x40,0x46,0x2d,0x25,0x3b,0xde,0x4b,0x4d,0xb5,0xb0 +,0xb9,0xc3,0xaa,0xa8,0xbe,0xc7,0xc1,0xc6,0x2b,0x1f,0x2d,0x25,0x26,0x44,0xb4,0xb5,0xb9,0xa8,0xa6,0xbf,0x2d,0x25,0x2d,0xea,0xac,0xa1,0xaa,0x6a,0x30,0xba,0xa6,0xdd +,0x28,0x1b,0x20,0x4f,0xa9,0x9f,0xb4,0x56,0x40,0x3d,0x4d,0x2f,0x26,0x29,0x4a,0xc6,0xaf,0xad,0xc9,0x47,0xdb,0xa7,0xaa,0x76,0x3c,0x47,0xbd,0x60,0x6a,0xb1,0xac,0xa5 +,0xa8,0xb5,0x2c,0x1b,0x1c,0x20,0x1f,0x1d,0x1f,0x2e,0x55,0x9e,0x99,0x9f,0xc9,0x33,0xce,0xa9,0x9f,0xac,0xb8,0x36,0x37,0xb9,0xb4,0x37,0x21,0x22,0x37,0x70,0xb7,0xae +,0xb5,0xbe,0xd1,0xb3,0xb8,0x3e,0x2d,0x4a,0x47,0x2e,0x2c,0x34,0x3d,0x3f,0xe4,0xeb,0x61,0xc0,0xb9,0xa9,0xaf,0xb6,0xbf,0xb8,0xc3,0xcc,0xf1,0x3a,0x29,0x28,0xe6,0xca +,0xbf,0x46,0x37,0x39,0xac,0xa9,0xb7,0x3f,0x22,0x26,0x39,0xbf,0xab,0xab,0xdb,0x43,0x41,0xb5,0x69,0x22,0x1d,0x2a,0x54,0xb0,0xa4,0xa0,0xa5,0xab,0xb2,0xbb,0xfb,0x3e +,0x3a,0x32,0x2f,0x3b,0xb5,0xad,0xbf,0x53,0xd9,0x59,0x2f,0x28,0x2d,0x34,0x34,0x31,0x51,0xa7,0x9f,0xaa,0xbd,0x3b,0x25,0x3b,0xb3,0xbf,0x49,0x2c,0x2e,0xbc,0x9f,0x9e +,0xae,0x49,0x29,0x2b,0x37,0xdf,0xbc,0xcd,0xda,0x4f,0xcc,0xb8,0x46,0x28,0x2c,0x4e,0x4d,0x57,0x4a,0xbb,0xaa,0xb3,0xb6,0xbd,0x6a,0xbe,0xb1,0xc0,0x64,0x33,0x34,0x51 +,0xee,0x3e,0x35,0x1f,0x24,0x57,0xb0,0xaa,0xa9,0xc9,0xb1,0x9d,0x99,0x9f,0x3b,0x19,0x15,0x2f,0xdc,0xc9,0x27,0x1d,0x2d,0xdb,0xae,0xaf,0xeb,0x30,0x3c,0xd6,0xa5,0x9f +,0xbb,0xd6,0xc5,0xb0,0xa4,0xba,0x23,0x1a,0x1f,0x35,0x5f,0x5e,0xc2,0xa4,0x9e,0xa3,0xbd,0x2a,0x27,0x2b,0x3f,0x3e,0x36,0x32,0xca,0xa8,0xaa,0xa6,0x4b,0x28,0x29,0xcc +,0xb0,0xcc,0x2c,0x35,0xb7,0x9a,0x91,0x9c,0x58,0x1e,0x22,0x35,0xcd,0x26,0x1a,0x1c,0x29,0xd7,0xb2,0xac,0xa6,0xb3,0x2f,0x29,0x4b,0xab,0xac,0xad,0xb6,0xb5,0xb9,0x3d +,0x2a,0xb9,0x98,0x97,0x45,0x0d,0x09,0x20,0x93,0x94,0xb1,0x34,0x4e,0xf8,0x25,0x2d,0xb8,0x9f,0xad,0x26,0x0e,0x12,0xb8,0x94,0x99,0x9a,0x9d,0xc7,0x1c,0x10,0x27,0x98 +,0x8d,0xbb,0x0e,0x08,0x35,0x8f,0x8e,0xb4,0x2a,0x34,0x18,0x10,0x24,0x9d,0x93,0x93,0x27,0x0f,0x25,0x9f,0x9f,0xa4,0x99,0xa7,0x39,0x0b,0x0c,0x28,0x8e,0x88,0xa5,0x0e +,0x08,0xce,0x8d,0x8e,0x9b,0xbc,0x36,0x1c,0x0e,0x15,0xab,0x8a,0x8e,0x2c,0x0a,0x0f,0x6d,0xa8,0x9f,0x94,0xa6,0x2f,0x0d,0x0a,0x3d,0x8a,0x84,0xa4,0x0e,0x08,0x22,0xa7 +,0x99,0x9c,0xab,0x3f,0x18,0x0f,0x17,0x9f,0x86,0x8d,0x3d,0x0b,0x0b,0x2e,0xab,0x98,0x93,0xa5,0x36,0x0d,0x0b,0x5a,0x8a,0x87,0xc3,0x0f,0x0b,0x1e,0xae,0x9e,0x9d,0x99 +,0x9a,0x20,0x08,0x0d,0xa3,0x84,0x8f,0x20,0x09,0x0d,0x66,0xac,0x9a,0x93,0x9c,0xf8,0x0e,0x0c,0x3f,0x8c,0x87,0xcc,0x0e,0x0e,0x6e,0x9d,0xa6,0x9f,0xa0,0xb2,0x1b,0x0a +,0x0e,0xbd,0x89,0x91,0x1c,0x0a,0x14,0xa4,0x99,0x97,0x97,0xa0,0x2e,0x0d,0x0b,0x37,0x89,0x87,0xce,0x0f,0x11,0x4c,0xa0,0xa9,0x9f,0x9d,0xae,0x12,0x08,0x18,0x9a,0x86 +,0xa2,0x0d,0x0d,0x33,0xa3,0xa9,0xa8,0xaa,0xb0,0x2d,0x11,0x1b,0x9a,0x83,0x90,0x19,0x0a,0x2b,0x9e,0xa6,0x4e,0xc7,0xb6,0x33,0x0b,0x09,0x63,0x87,0x86,0x3f,0x09,0x11 +,0xa1,0xa9,0xb2,0x9e,0x98,0xb9,0x19,0x0a,0x1c,0x8e,0x87,0xb2,0x14,0x15,0x2f,0xad,0x43,0xae,0xa4,0xa9,0x2a,0x15,0x1a,0xa6,0x88,0x95,0x1d,0x0b,0x1c,0xb5,0x9f,0xa9 +,0xa8,0xad,0x3a,0x12,0x0f,0x3d,0x8a,0x89,0x38,0x0b,0x0f,0xb1,0x9e,0x9f,0xa8,0xb2,0x6e,0x16,0x0c,0x1c,0x96,0x87,0x9d,0x21,0x13,0x29,0xa8,0x9f,0x9a,0xa7,0xb5,0x22 +,0x0c,0x0f,0x48,0x8e,0x90,0x2d,0x0d,0x10,0xa8,0x92,0x97,0xa4,0xcd,0x7b,0x1d,0x0f,0x21,0x98,0x8c,0xa9,0x17,0x0e,0x27,0x9d,0x97,0x9d,0xa4,0xaf,0x1c,0x0c,0x13,0xad +,0x8c,0x99,0x1e,0x0d,0x1b,0xa4,0x92,0x9a,0xaf,0xca,0x4c,0x17,0x0f,0x2f,0x98,0x8e,0xaa,0x17,0x16,0x2b,0xb0,0x9e,0x9e,0xa2,0xc6,0x19,0x0d,0x1e,0x9b,0x8c,0x9c,0x21 +,0x11,0x1f,0xad,0x9e,0xa3,0xaf,0xbc,0x42,0x22,0x1c,0x4e,0x94,0x98,0x47,0x14,0x13,0x3a,0xa0,0x9e,0xa6,0xc3,0x3a,0x1a,0x10,0x20,0x95,0x8b,0xae,0x1b,0x18,0x47,0xa6 +,0x9a,0xa8,0xb5,0xcc,0x2a,0x19,0x18,0x50,0x9c,0x9d,0xd5,0x1e,0x22,0xd8,0xaf,0x9c,0xaa,0xc0,0xc9,0x2b,0x18,0x20,0xa4,0x9f,0xc5,0x23,0x1a,0x46,0x9f,0x9d,0xab,0x3d +,0x45,0x47,0x2a,0x2b,0xbb,0x9d,0xba,0x32,0x27,0x33,0x6e,0xab,0x9d,0xae,0x41,0x2d,0x24,0x1d,0x34,0xab,0xa0,0xa7,0xcd,0x2f,0x3a,0xb4,0xb0,0x3d,0x22,0x2d,0x64,0x3e +,0x33,0xd9,0xb4,0xb7,0xb5,0xa9,0xb4,0xb7,0xae,0x2e,0x2f,0x5b,0x5f,0x2f,0x27,0xb3,0xaa,0xeb,0x40,0x39,0xbf,0xba,0xb8,0xbe,0x29,0x26,0x2b,0xcb,0xc9,0xf8,0xda,0x38 +,0xbc,0xae,0xb4,0xb9,0xb0,0xbf,0x25,0x2e,0xd8,0xbe,0xcd,0x31,0x42,0x3a,0x47,0xc1,0xad,0x9c,0xa5,0x65,0x1a,0x17,0x35,0xb1,0xaa,0xb1,0x5d,0x25,0x1e,0x49,0x9e,0x94 +,0xa2,0x4f,0x3c,0x29,0x3b,0x5f,0xba,0xb8,0x42,0x27,0x1e,0x2d,0xb6,0x9d,0x9a,0xb8,0x29,0x19,0x23,0xaf,0xa4,0xb2,0x3c,0x43,0x26,0x1f,0xcf,0x9b,0x91,0x9f,0x42,0x1a +,0x19,0x2a,0xbe,0xa2,0xb6,0xe2,0x21,0x11,0x23,0x96,0x88,0x91,0xb6,0x19,0x0d,0x1f,0xaf,0x9d,0xab,0x48,0x1f,0x14,0x2d,0xa6,0x8f,0x8f,0xa2,0x29,0x0e,0x13,0x46,0x9c +,0x9d,0xb0,0x2d,0x0e,0x0f,0xd4,0x8d,0x88,0x9c,0x20,0x0c,0x14,0xeb,0x99,0x97,0xb6,0x45,0x1a,0x13,0x2d,0x9d,0x8d,0x90,0xad,0x17,0x0b,0x13,0x68,0x92,0x92,0xa6,0x1b +,0x0a,0x13,0xb1,0x89,0x89,0x9f,0x17,0x08,0x13,0xb8,0x92,0x96,0xac,0x34,0x13,0x12,0x2f,0x8f,0x8a,0x97,0x45,0x0d,0x0d,0x1e,0xa2,0x8d,0x91,0xfc,0x0c,0x0a,0x22,0x93 +,0x87,0x93,0x36,0x0d,0x0e,0x28,0xa2,0x95,0xa2,0xbf,0x20,0x11,0x18,0xc8,0x8b,0x8a,0x9a,0x1d,0x0a,0x17,0x2c,0x9e,0x95,0x9f,0x3c,0x0e,0x0d,0x3e,0x8a,0x85,0x9a,0x1e +,0x0d,0x15,0x28,0xb3,0x9c,0xa6,0x4b,0x12,0x0e,0x1d,0x99,0x86,0x8c,0xa4,0x10,0x08,0x15,0xa7,0x8d,0x92,0xc9,0x12,0x0b,0x19,0x9c,0x86,0x8b,0xbf,0x10,0x0c,0x1c,0xbc +,0x99,0xa5,0xab,0x4b,0x0f,0x0e,0xe3,0x8a,0x86,0x98,0x1d,0x09,0x0d,0x22,0xaa,0x90,0x90,0xef,0x0b,0x09,0x49,0x8a,0x85,0x95,0x36,0x0e,0x0c,0x1c,0xc3,0x96,0x93,0xac +,0x1d,0x0d,0x0f,0xb2,0x87,0x85,0x98,0x11,0x04,0x0f,0xc0,0x92,0x91,0x9e,0x1a,0x07,0x0b,0xb7,0x85,0x85,0xa8,0x0f,0x0a,0x1b,0xb9,0x9e,0x94,0x95,0x2d,0x0a,0x08,0x2d +,0x89,0x83,0x8f,0x3b,0x0d,0x0a,0x16,0xa8,0x8b,0x8d,0x70,0x0a,0x04,0x15,0x95,0x84,0x89,0xda,0x0d,0x0f,0x2c,0xbb,0xa1,0x95,0x9f,0x1e,0x0a,0x0b,0xca,0x86,0x84,0x9c +,0x12,0x0c,0x17,0x40,0x99,0x8d,0x90,0x25,0x05,0x03,0x3d,0x84,0x82,0x98,0x0e,0x07,0x0d,0x2b,0x9f,0x8d,0x8f,0x59,0x0e,0x09,0x1f,0x93,0x83,0x89,0x5d,0x0c,0x0a,0x13 +,0xc3,0x94,0x90,0xaa,0x1c,0x0a,0x17,0x92,0x85,0x8a,0x39,0x09,0x0b,0x26,0xb7,0x9f,0x9e,0xb3,0x1c,0x0c,0x11,0xa8,0x86,0x86,0x9d,0x1b,0x0c,0x0c,0x1e,0xa4,0x8c,0x8d +,0xd8,0x0c,0x0a,0x30,0x8b,0x85,0x92,0x22,0x08,0x0c,0x2a,0xa9,0x9e,0xa3,0x67,0x15,0x0d,0x2b,0x8f,0x86,0x8e,0x44,0x0d,0x0d,0x1c,0xaf,0x94,0x91,0xb5,0x15,0x08,0x1a +,0x8f,0x82,0x8a,0x7c,0x0c,0x08,0x19,0xba,0x9d,0x9f,0xb4,0x1e,0x0e,0x11,0xaf,0x8a,0x8a,0x9b,0x32,0x0f,0x12,0x2e,0xac,0x9b,0xa0,0x49,0x12,0x0e,0x49,0x89,0x85,0x96 +,0x1a,0x0a,0x0f,0x30,0xa3,0x9c,0xb2,0x20,0x0f,0x0d,0x2d,0x8e,0x85,0x8b,0xb4,0x12,0x0e,0x1b,0xcb,0x9d,0x9a,0xe7,0x14,0x0f,0x2c,0x93,0x89,0x8e,0xe5,0x14,0x14,0x20 +,0xdd,0x9d,0xae,0x20,0x10,0x16,0x3c,0x9a,0x8a,0x8e,0xc0,0x1a,0x1a,0x26,0x6e,0xad,0x9e,0xb9,0x1f,0x14,0x23,0xa1,0x8d,0x8d,0xa6,0x20,0x12,0x1b,0x27,0x48,0xab,0xba +,0x29,0x1c,0x21,0xae,0x91,0x8e,0x9c,0x24,0x17,0x1b,0x36,0xa9,0xae,0xd5,0x2a,0x1f,0x2d,0xaa,0x8f,0x8d,0x9c,0x28,0x13,0x17,0x29,0xb0,0xb0,0xd9,0x3a,0x23,0x1f,0x3e +,0x9c,0x95,0x9b,0xc5,0x1a,0x15,0x30,0xab,0xaf,0x40,0x2f,0x33,0x44,0xb0,0x9f,0x99,0xa1,0x55,0x23,0x1e,0x36,0xd5,0x7d,0x4d,0xd3,0xc7,0x35,0x33,0xde,0xb8,0x9f,0xa0 +,0xdd,0x1a,0x15,0x2e,0xbd,0x9f,0xa1,0x42,0x24,0x2a,0x69,0xa2,0x9a,0x9e,0x51,0x1f,0x1b,0x20,0xb9,0x94,0x9d,0x2d,0x12,0x18,0x48,0x9d,0x91,0x9a,0xcb,0x15,0x0d,0x1a +,0x9e,0x8d,0x93,0x2f,0x08,0x0e,0x60,0x8d,0x8b,0x9d,0x2e,0x15,0x1d,0x3b,0x9e,0x94,0xa5,0x1c,0x08,0x0f,0xbd,0x8d,0x8f,0xb6,0x29,0x21,0x3a,0x60,0xad,0x96,0x9c,0x28 +,0x0b,0x0e,0xd0,0x96,0x95,0xae,0x34,0x2e,0x2e,0x3e,0xa7,0x9a,0xdc,0x1f,0x1e,0x2e,0x63,0xf6,0xc9,0xc9,0xd2,0xb2,0xaf,0xbf,0xdb,0x3d,0x3e,0xc1,0xa9,0xe0,0x1e,0x1b +,0x41,0x97,0x90,0xaa,0x1f,0x1e,0x22,0x29,0xbc,0xa4,0x9e,0x6c,0x1a,0x12,0x32,0x9c,0x92,0x98,0xa9,0x20,0x0e,0x14,0xc5,0x8d,0x91,0xbc,0x0f,0x0e,0x2b,0x9c,0x8a,0x8e +,0x6b,0x0a,0x07,0x21,0x94,0x8b,0xa7,0x19,0x0f,0x18,0x70,0x98,0x8c,0x8d,0x42,0x09,0x09,0x3b,0x8f,0x8d,0xa6,0x1c,0x16,0x17,0x42,0x95,0x8c,0x98,0x20,0x0a,0x0f,0xb6 +,0x8b,0x97,0x28,0x0f,0x17,0xb3,0x97,0x94,0xab,0x24,0x1b,0x21,0xd5,0x9c,0xa6,0x2f,0x1b,0x2b,0xc4,0x9b,0x95,0xb2,0x1f,0x1d,0x58,0xa8,0xc7,0x2a,0x2a,0x3e,0x3b,0x35 +,0xaf,0x91,0x8f,0x35,0x0d,0x11,0xc3,0x8d,0x94,0x23,0x0f,0x0f,0x2a,0x9f,0x8e,0x8a,0xb5,0x0e,0x0b,0xf0,0x88,0x88,0xd4,0x08,0x08,0x22,0x9d,0x86,0x8c,0xc7,0x08,0x0c +,0x35,0x91,0x8e,0xcc,0x2f,0x00,0x03,0x07,0xe0,0x8e,0xb3,0xb6,0x05,0x16,0x93,0x8b,0x8a,0x9a,0xb4,0x45,0x9a,0x99,0x8b,0x80,0x9c,0x06,0x11,0x18,0x97,0x80,0x9e,0x21 +,0x32,0x22,0x20,0x98,0xd1,0x13,0x00,0x02,0x08,0x26,0x1b,0x07,0x03,0x05,0x0c,0x0e,0xa6,0x41,0x17,0x11,0x1d,0xc1,0x98,0xa1,0xbc,0xc4,0xae,0x9f,0xa6,0x87,0x84,0x83 +,0x91,0x9a,0x8a,0x89,0x80,0x85,0x88,0x8a,0x9c,0x8d,0x8d,0x85,0x83,0x9a,0x04,0x07,0x95,0xa4,0x3a,0x07,0x00,0x06,0x05,0x03,0x29,0x37,0x0f,0x05,0x00,0x17,0x0e,0x08 +,0x04,0x05,0x16,0x18,0x2b,0xbf,0xa0,0xad,0x9f,0xb0,0x9a,0x88,0x86,0x87,0x8f,0x8e,0x8d,0x8c,0x84,0x84,0x89,0x8d,0x9c,0x8e,0x93,0x8f,0xb0,0xab,0xce,0xc5,0xa6,0xa9 +,0x9e,0x36,0x17,0x09,0x10,0x19,0x10,0x0a,0x04,0x05,0x0d,0x0c,0x0c,0x13,0x1c,0x10,0x09,0x06,0x0f,0x29,0xb9,0x29,0x2f,0x3d,0x48,0x9e,0x8e,0x87,0x8c,0xbb,0x21,0x48 +,0x9b,0x88,0x8c,0x95,0x7a,0xa5,0x85,0x85,0x81,0x87,0x89,0x90,0x98,0x88,0xa1,0x99,0x9e,0x2a,0x1a,0x18,0x29,0x10,0x0f,0x18,0x0b,0x09,0x09,0x0b,0x02,0x13,0x1b,0x0c +,0x09,0x0d,0x10,0x10,0x4b,0x2f,0x39,0x0e,0x26,0x2c,0xa5,0x8c,0xb9,0xb1,0xc8,0x90,0x82,0x8b,0x8f,0x89,0x8a,0x8d,0x8b,0x89,0x8a,0x8e,0x92,0xaa,0x9d,0x9c,0xa6,0xad +,0xb6,0x9f,0x1f,0x16,0x17,0x5a,0x69,0x1c,0x27,0x1a,0x0c,0x0c,0x06,0x1e,0xbc,0x1c,0x04,0x03,0x00,0x18,0xae,0x19,0x2a,0x0d,0x14,0x07,0x56,0xa1,0x99,0x89,0x4d,0x2a +,0xb9,0x89,0x93,0x89,0x8e,0xa6,0xdb,0x2b,0x85,0x83,0x8c,0x9c,0x24,0x9e,0x89,0x82,0x89,0x8a,0x97,0x48,0x29,0x27,0x95,0x99,0x1a,0x0a,0x0b,0x0b,0x0b,0x0f,0x0f,0x07 +,0x12,0x06,0x0e,0x16,0x13,0x5e,0x14,0x04,0x15,0xd2,0x24,0x26,0x38,0x1d,0x1d,0x2e,0x9d,0x83,0x9c,0xa6,0x29,0x96,0x9e,0x9a,0x89,0x89,0x8c,0x26,0x9f,0x86,0x80,0x95 +,0xa6,0x4b,0x5d,0x21,0xb2,0x91,0x86,0xa2,0x04,0x0a,0x9b,0x88,0x97,0xa5,0x0b,0x0b,0x08,0xe3,0x59,0x17,0x9d,0x08,0x01,0x04,0x0e,0xa6,0x2f,0x2c,0x05,0x02,0x0c,0x1d +,0x95,0xa4,0x43,0x07,0x1d,0x52,0x9f,0x80,0x93,0x98,0xba,0xc1,0x9c,0x8a,0x88,0x8a,0x8a,0xc3,0x2b,0x89,0x80,0x9e,0xb9,0x9f,0x89,0x96,0x9b,0xb4,0x1c,0x1f,0x3d,0xbe +,0xb2,0xa4,0x19,0x16,0x06,0x21,0x2e,0x20,0x27,0x08,0x0d,0x08,0x0e,0x0c,0x9f,0xc0,0x0b,0x08,0x0c,0x28,0xc0,0xae,0x9f,0x24,0x0f,0x1d,0x23,0x94,0xa1,0x8d,0x9c,0x9b +,0xab,0x9e,0x83,0x93,0x85,0x33,0x2b,0x9d,0x9b,0x83,0x8f,0xa3,0x27,0x96,0xa7,0x98,0x81,0xa0,0x49,0x12,0x38,0xa2,0x94,0x9d,0x0a,0x13,0x0f,0x16,0x26,0x19,0x79,0x0d +,0x08,0x0e,0x1b,0x0f,0x18,0x0a,0x0b,0x12,0x09,0x14,0x48,0xa6,0x1b,0xdc,0x4b,0xba,0x9d,0x8c,0xb5,0xaf,0x9b,0xba,0x8f,0x8b,0x89,0x90,0xa0,0xa1,0x8e,0x86,0x8e,0x3f +,0x97,0xa5,0x4c,0xc3,0x92,0x99,0xb0,0x0e,0x1e,0xdd,0x9c,0x9e,0x53,0x1f,0x0b,0xd0,0x1d,0x23,0x1d,0xa1,0x14,0x1d,0x0e,0x29,0x2f,0x1e,0x97,0x13,0x0b,0x09,0x19,0x1e +,0x28,0x1d,0x1c,0x0e,0x2e,0x36,0xbf,0xc1,0x97,0xad,0x1c,0xb6,0xa6,0x9d,0xa1,0xa7,0xd5,0x8c,0xa7,0x8b,0x8f,0x8e,0x88,0x9b,0xad,0x9b,0x85,0x8f,0x9d,0xbb,0xad,0x27 +,0x95,0xe9,0xa7,0xa7,0x1b,0x1b,0x09,0x1a,0x29,0x23,0x05,0x08,0x12,0x1b,0x15,0x1e,0x15,0x15,0x0f,0x15,0xc4,0x29,0x10,0x14,0x29,0x09,0xb0,0x96,0xb1,0x9f,0xa0,0x98 +,0xb9,0x99,0x9f,0x8d,0x90,0x9d,0x95,0x89,0xa5,0xa4,0x87,0x9d,0x8f,0xb0,0x9a,0xae,0x9b,0x9a,0x18,0xfa,0xb7,0x2f,0x0e,0x2e,0xcb,0x3a,0x29,0x27,0xc3,0x1e,0x9b,0x40 +,0x0c,0x20,0x32,0x1f,0x26,0x1c,0x27,0x1c,0x0b,0x21,0x16,0xc2,0x16,0x49,0xbe,0x19,0x12,0x3a,0x1f,0x2a,0x1c,0x1b,0xa2,0xa4,0xaa,0xad,0x8f,0xa7,0x85,0xb7,0xd6,0x91 +,0x8b,0x97,0x25,0x9a,0x9b,0x8e,0x8b,0xa7,0x8d,0x8e,0xb4,0x41,0xbb,0x9b,0x9e,0x2f,0x0d,0x2d,0xdc,0x0d,0x24,0xb3,0x23,0x0b,0x2a,0x2e,0x09,0x1f,0x06,0x0c,0x14,0x19 +,0x17,0x1d,0xc6,0x2a,0x1e,0x22,0x2c,0x97,0x2e,0x20,0xa1,0x3f,0xab,0x1d,0xa8,0x9b,0x8d,0x88,0xa9,0x9a,0x8b,0x8b,0x9a,0x5a,0x9c,0x8b,0x6f,0xb3,0x98,0x99,0x9b,0x9b +,0x2a,0xbb,0x9e,0x50,0x1d,0x0e,0xad,0x25,0x34,0x1b,0x16,0xce,0x1a,0x1e,0x3d,0x2f,0x20,0x25,0x19,0x2e,0x13,0x0d,0xa5,0x1d,0x09,0x1a,0x32,0x3a,0x2b,0x2b,0xb9,0xbb +,0x9a,0xae,0x27,0x98,0x91,0x93,0x38,0xab,0x9e,0x99,0xa7,0x8f,0x97,0xc4,0x98,0xb9,0x9a,0xab,0x96,0x93,0x22,0x0e,0xa5,0xcc,0x9b,0x9f,0x11,0xad,0x9c,0x37,0x0e,0x1b +,0x9b,0x8a,0x12,0x02,0x0e,0x1b,0x2f,0xb1,0xb2,0x21,0xe5,0x35,0x2a,0x30,0x4d,0x16,0x1f,0x2c,0x11,0x16,0x90,0xa7,0x23,0x31,0x63,0x41,0x9b,0xd4,0x0c,0x92,0x63,0xab +,0x2a,0x29,0x88,0x93,0x97,0x8e,0xa4,0x92,0x9c,0x97,0x97,0x9d,0x8f,0xe7,0x26,0x79,0x95,0x9d,0x9d,0x14,0x2f,0x9d,0x1b,0x14,0x0f,0x0b,0xbe,0xde,0x0a,0x0c,0x0e,0x44 +,0x2b,0x26,0x25,0x07,0x35,0x67,0x1c,0xbb,0xcb,0x96,0x38,0xde,0x9c,0x95,0x89,0x3a,0xbf,0xa5,0x8b,0x95,0x1f,0xad,0xb1,0x95,0x93,0x1c,0x19,0xa4,0x90,0xad,0x2e,0x36 +,0xdb,0xa8,0xc7,0x1d,0x20,0xbd,0xa1,0x57,0x0a,0x13,0xbc,0xbc,0x2a,0xc6,0x33,0xc9,0x98,0x15,0x1e,0xa8,0x9f,0x6d,0x07,0x20,0xab,0x9d,0x9b,0xc1,0x30,0x58,0x98,0x44 +,0x38,0x4c,0xb4,0x1c,0x0a,0x0a,0xd4,0x9a,0x24,0xda,0x0f,0xa7,0x8e,0x3b,0x25,0x13,0x9e,0x8f,0xbe,0x11,0x36,0x95,0x8f,0x88,0x9f,0x2e,0x8f,0x8b,0x97,0x1f,0xb5,0xa2 +,0x2e,0xae,0x18,0xa7,0x9b,0x69,0x0d,0x11,0xdd,0x2e,0x0b,0x09,0x39,0x9e,0x26,0x17,0x0a,0x1b,0x3d,0xa1,0x94,0x12,0x2f,0x6c,0xc5,0xd3,0xad,0xbf,0x9d,0x9f,0x25,0x1c +,0x95,0x9a,0xbb,0x19,0xbb,0x8e,0xf7,0x3e,0x12,0x8c,0x87,0xa2,0x16,0x14,0xa6,0x8d,0x8d,0x11,0x1a,0x28,0x9e,0x98,0x17,0xa5,0x5c,0x9a,0x4f,0x06,0x1c,0x2d,0x5b,0x2d +,0x1c,0xa3,0x95,0x51,0x19,0x17,0x9d,0x90,0xaa,0x06,0x0e,0xbe,0x97,0xad,0x20,0x1c,0xab,0x8a,0xa8,0xbc,0x31,0xb0,0x9f,0x24,0x0b,0xbd,0xa9,0xaa,0x2c,0x1c,0x98,0x9b +,0xa4,0x12,0x1a,0x8b,0x94,0x3b,0x0c,0x14,0x92,0x95,0x99,0x23,0x27,0xa3,0xa0,0x2d,0x2d,0x48,0x9a,0x9c,0x26,0x24,0x27,0xa4,0xb8,0x36,0xb5,0x94,0xa8,0x0d,0x06,0x2c +,0x8a,0x8e,0x11,0x07,0x19,0x9a,0x8f,0xac,0x16,0x3a,0xda,0x4f,0x1e,0x14,0xa3,0x9d,0xb1,0x0c,0x22,0xa2,0x96,0xaf,0x53,0x75,0x32,0x9f,0x20,0x30,0x90,0x8a,0x8d,0x25 +,0x14,0x4f,0x8e,0x92,0x21,0x18,0x2c,0x8f,0x9d,0x1f,0x3a,0xa5,0x9e,0xbf,0x1b,0x2c,0xab,0xcd,0x1b,0x15,0xb8,0x9b,0x2b,0x11,0x30,0x93,0x8e,0x32,0x0e,0x0d,0xa5,0x98 +,0xae,0x22,0x18,0xbe,0xa0,0x3e,0x3d,0xa7,0xaa,0xb9,0x1c,0x1b,0x1c,0xb1,0xad,0x58,0x1c,0x48,0x9e,0x3c,0x2b,0x3e,0xab,0xb1,0x37,0x1c,0x19,0x9d,0x8d,0xb9,0x38,0x24 +,0xa8,0xa1,0x3c,0xa5,0xaf,0xbb,0x26,0x1c,0x52,0x9d,0x92,0xae,0x2b,0x1e,0xb7,0xb4,0x1e,0x2b,0xa3,0xb7,0x1c,0x1a,0x48,0xab,0x94,0xa0,0x1b,0x1c,0x5a,0x6a,0x34,0x48 +,0x45,0xc1,0xc2,0x3c,0x26,0xab,0x94,0xa1,0x1a,0x14,0x26,0x38,0xb2,0xdb,0xd5,0xad,0xcc,0x33,0x49,0x9e,0x93,0x9f,0xa9,0x12,0x24,0xb1,0xbe,0x3c,0x1f,0xae,0x9a,0xa5 +,0x1e,0x25,0xb5,0x92,0x9c,0x26,0x15,0x36,0xaf,0x3e,0x2d,0xb5,0xbd,0x49,0x23,0x18,0xb0,0xa4,0xb3,0x3e,0xfe,0xc4,0xad,0x42,0x71,0xa6,0xbf,0xce,0x26,0x27,0x29,0x5f +,0x9e,0x9c,0xaa,0xaa,0xaa,0x1f,0x20,0xe1,0x9f,0xb5,0x1d,0x2c,0x43,0xaf,0xad,0xb6,0x2a,0x2b,0xe1,0xa8,0x9a,0x24,0x27,0xac,0x2d,0x2d,0xea,0x51,0xb7,0x23,0xce,0xc9 +,0x4f,0xa5,0x62,0xbc,0x38,0x4c,0xeb,0x41,0x21,0x15,0x57,0xb9,0xc4,0xa8,0xa9,0xb1,0x2f,0x7a,0xac,0x17,0x36,0xaf,0xd5,0x3f,0x21,0xcb,0xad,0x90,0xa7,0xba,0xb8,0x12 +,0x2d,0xaa,0xc6,0xde,0x36,0xb9,0x9c,0x4c,0x5b,0xe1,0x53,0x2e,0x2b,0xc4,0x34,0xbf,0xa2,0xb5,0x50,0x2f,0xa4,0xa7,0x34,0x1e,0x1e,0xce,0x2d,0x3b,0xc7,0xd8,0xbf,0xa1 +,0x9e,0x4f,0x2b,0x25,0x57,0x46,0x36,0xe8,0xa0,0xa5,0xe4,0x5b,0x1d,0x2c,0x9c,0x9f,0x1a,0x2b,0xc8,0xcf,0xaa,0x35,0x43,0xb9,0xa9,0x29,0xcb,0xac,0x25,0xd2,0xad,0xab +,0x42,0x2c,0x2e,0x38,0x2f,0xe2,0xba,0xaa,0x2e,0x24,0xbc,0x39,0xab,0xa2,0xae,0x1a,0x19,0xcd,0xa2,0xa3,0x55,0x55,0x23,0x34,0x71,0xa6,0xb6,0x1c,0x29,0x33,0xde,0xab +,0xc0,0x9b,0x9b,0x45,0x41,0x1d,0xc9,0x2f,0x36,0x41,0x23,0x9e,0x96,0xa4,0x57,0xba,0x53,0x4a,0x2a,0x2f,0x32,0x4b,0x3a,0x52,0xa8,0x7b,0x9d,0x9b,0x58,0x1d,0x19,0x22 +,0xb7,0xd0,0x36,0x51,0xae,0x9c,0xb0,0xe1,0x30,0x2d,0x70,0xaf,0x2f,0x28,0x49,0xa7,0xb0,0x31,0xb9,0xab,0xdc,0x35,0x2a,0x21,0x32,0x5f,0xae,0xbc,0xa2,0xba,0x3e,0xa2 +,0xc9,0x6b,0xdb,0x39,0x1f,0x22,0xb7,0xb2,0xb4,0xd9,0xa5,0xa0,0xd2,0x34,0x1c,0x30,0x35,0xb5,0xb2,0xb0,0x4d,0x1f,0x61,0xaa,0xb8,0xdd,0x36,0x1b,0x19,0xba,0xa6,0x43 +,0x9f,0xa3,0xd3,0x22,0x2b,0xbe,0xa0,0x63,0x2b,0x42,0xa5,0x9a,0x5e,0x32,0x20,0xbe,0xae,0xc7,0x3b,0x3c,0x6b,0xa1,0xaa,0x38,0x3d,0x3f,0xba,0x42,0x2b,0x1e,0x22,0xa7 +,0x94,0xe6,0x33,0x4c,0xc9,0xac,0x38,0x1e,0x20,0x50,0xcd,0x7e,0xbe,0xbf,0x98,0x9c,0x36,0x2c,0x3b,0xbd,0x38,0x1a,0x18,0x48,0x9d,0xa2,0x62,0x2d,0x2f,0xb2,0x96,0xdf +,0x1d,0x16,0x24,0x95,0xa0,0xa4,0x9b,0x43,0x28,0x27,0x6f,0xd7,0xce,0xbe,0x5f,0x28,0x2b,0xab,0x9e,0x9d,0xbd,0x3c,0x26,0x17,0x3d,0xc2,0x54,0x4d,0xbc,0x9c,0x3e,0x38 +,0xc1,0xeb,0x62,0x2b,0x2b,0x3f,0xbe,0xad,0xa7,0x41,0x2a,0xbe,0x9d,0xb0,0x1d,0x18,0x38,0xa1,0xb0,0x53,0xde,0x36,0xcf,0xc9,0x3a,0xb9,0xfb,0xcd,0xd6,0x2e,0x74,0x98 +,0x9c,0x65,0x17,0x18,0x2a,0x2d,0x9f,0xa4,0x36,0x2b,0x9e,0x9c,0x46,0x2a,0x26,0x4c,0xc1,0x2e,0x27,0xac,0xaa,0xb4,0xa4,0xce,0x34,0xad,0xa6,0x26,0x18,0x1c,0xd5,0x9e +,0xa4,0xb3,0xad,0x47,0x39,0xb8,0x2f,0x1c,0x1c,0xc5,0xb7,0x37,0x4c,0xbe,0xa5,0xb4,0xda,0xbe,0x2e,0x2a,0x31,0x54,0xbb,0xc1,0x98,0x9b,0xc2,0x45,0x21,0xab,0xae,0x1d +,0x29,0x1c,0x36,0xa6,0x9a,0xb4,0x1d,0x46,0xb1,0x2f,0x1c,0xbb,0x9a,0xa8,0x1a,0x18,0xc1,0xb9,0xa9,0x98,0xad,0x0f,0x17,0x9e,0x94,0xe7,0x2a,0x32,0xb4,0xa1,0xae,0xd3 +,0x2d,0x23,0x2b,0xb8,0x4f,0x5a,0x9c,0x9f,0x26,0x10,0x2d,0xb8,0x4a,0xac,0xad,0x4c,0x33,0xd8,0x99,0xa7,0x27,0x2f,0x5b,0xe2,0x2d,0x33,0x97,0xa2,0x1e,0x35,0xab,0xda +,0x3b,0x41,0x3d,0x13,0x20,0x97,0x9f,0xe9,0xdb,0xa7,0xd8,0x1e,0x32,0xc4,0x36,0x22,0x41,0xa9,0x2f,0x65,0x92,0x9c,0x2f,0x18,0xb7,0x9d,0x49,0x31,0x25,0x2d,0x33,0xaa +,0x8f,0xa1,0x29,0x26,0xc5,0xd3,0x28,0x35,0xc8,0xdb,0xc7,0xa7,0xb7,0x27,0x4d,0x9d,0xf2,0x18,0x25,0xa1,0xac,0x27,0x36,0xbc,0x3a,0x2a,0xae,0x9f,0x3f,0x17,0x39,0x9e +,0xb2,0x31,0xa6,0xa9,0x1e,0x27,0xb1,0x9d,0x47,0x2b,0xbc,0xe5,0x42,0xe3,0xa3,0x2e,0x19,0xbc,0xa3,0x61,0x25,0xdb,0xa8,0x32,0x5b,0xa1,0x68,0x18,0x1b,0xd4,0xab,0x2d +,0x3a,0x91,0xa7,0x27,0x45,0x9c,0xaa,0x29,0xaf,0xad,0x22,0x2b,0xb2,0xa4,0x3e,0x2a,0xa7,0xa9,0x30,0x25,0xb4,0x21,0x17,0x57,0x9f,0xa5,0x2e,0xc0,0xa8,0x3b,0x20,0xaf +,0xad,0x27,0x1d,0x38,0xa0,0xb9,0xaf,0xaa,0xf0,0x21,0x21,0xa0,0x9c,0x3a,0x25,0xce,0x45,0x2e,0xbd,0x9e,0xd7,0x1d,0x2f,0x34,0xc6,0xff,0xb1,0xa1,0x18,0x20,0xa6,0x9f +,0x4d,0x34,0x9d,0x55,0x29,0xa5,0x99,0x4b,0x29,0xd0,0x46,0x3a,0x1f,0xab,0x9c,0xe3,0x25,0x3c,0xb2,0x37,0xb4,0xbc,0x3b,0x18,0x1b,0xa9,0x9b,0xc3,0x3a,0xcd,0x2b,0x3d +,0xaa,0x9e,0x34,0x0f,0x3e,0xa0,0xad,0xbd,0xa0,0x9e,0x1f,0x1c,0xb3,0xb8,0x35,0xde,0xb7,0x43,0x34,0x32,0xa9,0xac,0xc8,0x5d,0x3b,0x5a,0x25,0xbe,0xb7,0x3a,0x2b,0x3c +,0xad,0xd8,0xa4,0xa6,0x27,0x17,0x2c,0xc3,0x4b,0x6d,0x7d,0x9b,0xaf,0x21,0x55,0xa9,0xee,0x21,0xb6,0xa8,0xc9,0x3b,0xb7,0x9d,0x31,0x23,0x47,0xcc,0xc1,0x4a,0x5a,0xc0 +,0xcd,0xc8,0x78,0x41,0x45,0xba,0xb4,0x2f,0x2c,0x5b,0xb6,0x5a,0x47,0xae,0xb6,0x24,0x26,0xc1,0xbb,0xc6,0x3f,0xba,0x9e,0xf8,0x65,0xcc,0x49,0x2b,0x31,0xb0,0x2a,0x2b +,0x33,0xc1,0xc5,0x36,0x46,0xf0,0xae,0x35,0xca,0xb4,0x27,0x28,0xa8,0xa9,0xd7,0xa6,0xcd,0x38,0xb9,0xa9,0xa8,0x59,0x1b,0x2b,0x5b,0xa4,0x9b,0xaa,0x41,0x19,0x24,0xd0 +,0xb3,0xb8,0xae,0x2f,0x45,0x2e,0x1f,0xa6,0xb0,0x33,0x23,0xb6,0xc7,0x4b,0x52,0x50,0xaf,0xd6,0xaa,0xc6,0x48,0x68,0xb7,0x3c,0x2b,0x2c,0xc9,0xa1,0x40,0x62,0x58,0x43 +,0x47,0x5e,0xb4,0x53,0x31,0x6f,0x3d,0xce,0xa9,0xb7,0x2c,0x22,0x52,0xcd,0xf6,0xbe,0xbb,0x6d,0xaa,0xbc,0x53,0xb3,0x68,0x56,0xdc,0x38,0x29,0x56,0xa7,0xa3,0xcc,0x25 +,0x22,0x74,0xb4,0xc0,0x45,0x2d,0x56,0xe5,0xac,0xc8,0x34,0x5c,0xb4,0xc1,0x5d,0xbb,0xb8,0x33,0x29,0x5d,0xcd,0x99,0xc9,0x1a,0x1f,0xb5,0x9f,0x2f,0x25,0x3a,0xb0,0xa1 +,0xb4,0x6e,0xc0,0x51,0x2c,0x56,0xaa,0xb5,0x19,0x43,0xa6,0x2f,0x2e,0xe3,0xae,0x30,0x22,0x26,0xb2,0xbc,0x32,0xaf,0x98,0xac,0x32,0xb8,0x7d,0x38,0xaa,0xc2,0x19,0x1f +,0x64,0x9b,0xac,0x4d,0x36,0xc9,0x96,0x2c,0x22,0xf6,0xa3,0x5b,0x1e,0x34,0xad,0x9a,0x5d,0x25,0x1b,0x43,0xaa,0xa9,0x2c,0x22,0xe7,0xa3,0xb6,0x3f,0xa1,0xdd,0x24,0x24 +,0xca,0xa5,0xdb,0x45,0x65,0x3c,0x50,0xa8,0xaf,0x29,0x64,0x3d,0x2b,0x5f,0x49,0xb9,0x44,0x36,0xa8,0xb9,0x4f,0x67,0xe5,0xcc,0x2e,0x39,0xda,0xbc,0x52,0xb0,0xde,0xe8 +,0xa4,0xab,0xf4,0x4d,0x39,0x2a,0xb9,0xbf,0xa4,0x3c,0x2f,0x21,0x1f,0xce,0x69,0xaf,0x58,0x42,0xcd,0xa8,0x55,0xb7,0xbe,0x37,0xb5,0x5b,0x1f,0x2d,0xb6,0xb8,0x32,0x27 +,0xb2,0x9b,0xac,0x1d,0x2e,0x30,0xcb,0xa7,0xad,0xc8,0x2e,0x75,0xa8,0xb3,0x23,0xad,0xa2,0x35,0x1c,0x23,0xb9,0xcd,0xdf,0x4a,0x38,0x72,0xc9,0x5b,0xcd,0xb1,0x2e,0x28 +,0xc2,0x9d,0xa4,0x5b,0x43,0x4e,0xca,0x59,0x2f,0x2f,0x35,0x3c,0xd1,0xb4,0xb5,0xa3,0xaf,0x3c,0x4a,0xab,0xb9,0x2d,0xc6,0x38,0x24,0x30,0xbd,0x9c,0xb3,0x23,0x3d,0xaa +,0xd9,0x38,0xc9,0x32,0x1a,0x55,0xa6,0xad,0x39,0x2e,0x44,0x6b,0xb1,0x9e,0xb4,0x24,0x1e,0x2c,0xa8,0x95,0x9a,0x32,0x13,0x31,0xb1,0xfe,0xd0,0x4c,0xbb,0xb7,0x28,0x1a +,0x38,0x9f,0xae,0xbe,0x28,0x1c,0xb7,0xa9,0xad,0xb3,0x53,0x2c,0xc5,0xa2,0x28,0x2b,0xc8,0x4c,0x2e,0xc8,0xa5,0xae,0x45,0x1c,0xc9,0xc0,0x9d,0x9b,0x5e,0x6f,0x30,0xbe +,0xa7,0xcb,0x24,0x33,0x31,0x27,0x3b,0xd0,0x5b,0x1d,0x3c,0xb5,0x7e,0x41,0x35,0xb7,0xc8,0xca,0xd6,0x41,0xe1,0xa6,0x9a,0xae,0xc8,0xdc,0xb0,0x9a,0xce,0x2e,0x25,0x14 +,0xc4,0xbc,0x25,0x26,0x23,0x1f,0xcf,0xb6,0x3c,0x3a,0xf1,0xb5,0x1c,0xc3,0x95,0xa0,0xa7,0x9f,0xa3,0xa1,0xb8,0x57,0xb8,0x49,0xad,0x60,0x22,0x18,0x29,0xa9,0x39,0x1f +,0x25,0x0f,0x1d,0x31,0x6d,0xab,0x36,0xa6,0x8e,0x98,0xbe,0xb3,0xaa,0x9c,0xaf,0xc1,0x2f,0x28,0x5e,0x5a,0xba,0xb8,0x4b,0x1e,0x13,0x26,0x32,0x1f,0x3c,0x39,0xad,0x9d +,0xb9,0x3b,0x36,0x2c,0x23,0x24,0x9d,0x8a,0x94,0xe7,0x1f,0x98,0x83,0xa7,0xc1,0x21,0x02,0x07,0x1a,0x3a,0x39,0x91,0x89,0xa5,0x17,0x08,0x3a,0x9d,0x90,0xb0,0x14,0x1f +,0x21,0x91,0x84,0x98,0x26,0x9b,0xab,0x2a,0x2c,0x1b,0x0e,0x09,0x1f,0x9f,0x8f,0x20,0x1a,0x2f,0xc0,0xb0,0x94,0x8c,0xc3,0x17,0x1c,0xec,0x9e,0x8b,0x8d,0xb2,0x0b,0x09 +,0x47,0xad,0x1f,0x17,0x39,0x2f,0x31,0x3c,0xae,0x90,0xa5,0x9f,0x52,0x0a,0x13,0x90,0x8a,0x1c,0x07,0x4a,0x8a,0x8e,0x28,0x0e,0xa7,0x90,0x92,0xaf,0x15,0x00,0x0b,0x91 +,0xa0,0xca,0x8f,0x89,0xbd,0x0b,0x13,0x9c,0x8e,0x9a,0x1f,0x19,0x17,0x24,0x96,0x94,0x22,0x3c,0x8d,0xb6,0x12,0x00,0xb5,0x88,0x39,0x2f,0x1c,0x9d,0x8e,0xcb,0x37,0x1d +,0x3d,0x8a,0x89,0x59,0x05,0x0d,0x61,0xe0,0x9e,0x90,0x42,0x04,0x04,0x18,0x8b,0x90,0x9e,0xdd,0x1b,0xb0,0xac,0x94,0x8d,0x4c,0xab,0x9e,0x10,0x12,0xa5,0x86,0x1f,0x04 +,0x17,0xa8,0x58,0x0f,0x0f,0x2a,0x83,0x8a,0x9a,0x41,0x0d,0x3f,0xa4,0x14,0x28,0x8c,0x80,0xac,0x05,0x0e,0x99,0x88,0xb6,0x12,0x05,0x09,0x0f,0x2e,0x32,0x9a,0x89,0x8f +,0x93,0x12,0x32,0x8b,0xa7,0x1e,0x0c,0xa3,0x9b,0x22,0x9d,0xa1,0xae,0x25,0x24,0x4d,0x33,0x0d,0x08,0x0b,0x41,0x81,0x89,0x98,0x0c,0x0f,0x8b,0x9d,0x5d,0x58,0xb3,0x9b +,0x0f,0x1f,0x8a,0x80,0x98,0x0a,0x02,0x0c,0x29,0xa0,0x43,0x08,0x9f,0x90,0xa7,0x2a,0x2c,0x8d,0x8c,0x9c,0xbf,0xa2,0x8f,0xb1,0x1a,0xbc,0x98,0x8d,0x94,0xd9,0x37,0x1c +,0x30,0xa4,0xc8,0x89,0x88,0xcb,0x14,0x09,0xa3,0x88,0x2d,0x0a,0x0f,0xb4,0x2c,0x01,0x0c,0x15,0x0d,0x01,0x01,0x00,0x09,0x16,0x0c,0x00,0x11,0x90,0xa9,0x21,0x05,0x12 +,0x93,0xad,0xfd,0xab,0x8c,0x89,0xef,0x9c,0x8b,0x84,0x89,0xde,0x21,0xac,0x92,0x8a,0x93,0x92,0x84,0x95,0xaa,0xb6,0x88,0x80,0x96,0xcb,0xaf,0x92,0x89,0xb5,0xa1,0x88 +,0x82,0x94,0x21,0x15,0x1d,0x31,0x1b,0x0c,0x0a,0x93,0x8e,0xc4,0x12,0x19,0x91,0xb3,0x0e,0x09,0x09,0x19,0x0b,0x0f,0xec,0x90,0x9c,0x0f,0x0c,0x13,0x27,0x1e,0x0d,0x02 +,0x22,0x1c,0x16,0x21,0x47,0x8e,0xc0,0x1e,0x1e,0x2b,0xa5,0x24,0x15,0x38,0xa4,0x90,0xbc,0x19,0x1f,0xcf,0xd3,0x20,0x0d,0x99,0x97,0x76,0x2d,0x1f,0x84,0x89,0xb8,0x19 +,0x0e,0xc2,0xd4,0x2d,0xa7,0x8d,0x91,0x33,0x11,0x1d,0xa0,0x92,0x9b,0xaa,0x87,0x83,0x83,0x8a,0x8c,0x80,0x87,0x95,0x8d,0x88,0x81,0x82,0x8c,0x8a,0x8a,0x89,0x36,0x0d +,0x0c,0x1e,0x10,0x0d,0x0a,0x26,0x2f,0x0b,0x0b,0x08,0x15,0x0c,0x03,0x00,0x02,0x08,0x0b,0x06,0x09,0x14,0xfc,0x10,0x02,0x02,0x05,0x0b,0x0d,0x06,0x1e,0xb5,0x3f,0xc5 +,0xdd,0x88,0x8b,0x9f,0x40,0x36,0x92,0x97,0x98,0x8f,0x88,0x84,0x99,0x23,0x2e,0x97,0x8c,0x9a,0x2c,0x96,0x8c,0x92,0x97,0x9c,0x89,0x8a,0x8b,0x8f,0x92,0x87,0x90,0xbd +,0x3f,0xae,0x9b,0xc6,0x29,0x25,0xa9,0xad,0x36,0x0f,0x35,0x3b,0x1b,0x27,0x14,0x3d,0x6e,0xab,0x42,0x2f,0xd3,0x20,0x2f,0x49,0x56,0x1f,0x0c,0x09,0x04,0x0b,0x18,0x14 +,0x0e,0x2f,0x42,0x2e,0x2c,0x18,0x2c,0x1e,0x2f,0x35,0x3e,0xbe,0xcd,0xc9,0xcb,0xa9,0xa5,0xaf,0x14,0x09,0x10,0x1f,0x1a,0x25,0x9f,0x43,0x1e,0x1e,0x3e,0xa3,0xae,0xb4 +,0xc3,0xb6,0x5a,0x3a,0xa0,0x8d,0x83,0x86,0x8a,0x90,0x8c,0x85,0x8a,0x8e,0x89,0x88,0x88,0x84,0x87,0x81,0x83,0x84,0x8e,0x8e,0x8d,0x2d,0x12,0x1b,0x38,0xd1,0x3c,0x12 +,0x05,0x04,0x08,0x09,0x08,0x08,0x06,0x01,0x03,0x01,0x09,0x0b,0x06,0x0d,0x15,0x1b,0x0e,0x0d,0x12,0x15,0x1d,0x0f,0x09,0x05,0x0e,0x27,0x30,0xf5,0x9e,0x97,0x9e,0x4a +,0x34,0x96,0x89,0x8a,0x92,0x90,0x8d,0x99,0x98,0x8d,0x86,0x87,0x92,0xad,0x34,0xaa,0x98,0x95,0x99,0x94,0x8f,0x8e,0x90,0x94,0x86,0x94,0xd9,0xb2,0xa3,0x8f,0x9d,0xc2 +,0xbe,0x94,0x88,0xa2,0x24,0x0b,0x0a,0x0f,0x1b,0x19,0x1a,0x29,0x25,0x36,0x1d,0xef,0xab,0xb4,0x26,0x14,0x25,0x11,0x0f,0x18,0x42,0x5f,0x14,0x10,0x0a,0x13,0x2e,0x22 +,0x0f,0x03,0x0a,0x0c,0x0e,0x0f,0x24,0xb7,0x6b,0xa0,0x5e,0xb0,0xb9,0x10,0x25,0xcc,0x98,0xaf,0x1f,0x1c,0x0d,0x27,0xc1,0xad,0x2e,0x23,0xa4,0xba,0xce,0x3e,0x98,0x8c +,0x91,0x86,0x86,0x83,0x82,0x81,0x80,0x81,0x85,0x8a,0x8b,0x8b,0x86,0x80,0x85,0x8d,0xaa,0x9d,0x89,0xba,0x1b,0x0d,0x14,0x23,0x0d,0x15,0x0d,0x16,0x47,0x32,0x17,0x06 +,0x03,0x02,0x01,0x07,0x09,0x07,0x02,0x03,0x0a,0x0f,0x23,0x0f,0x0d,0x09,0x07,0x16,0x0a,0x0f,0x0f,0x37,0x8d,0x98,0x99,0xac,0x9c,0x99,0xb1,0x94,0x96,0x9d,0xa1,0x9d +,0x8e,0xa4,0x9c,0x97,0x99,0x94,0x90,0x8b,0xa3,0xbc,0x98,0x8e,0x87,0x8d,0x8f,0x8b,0x8b,0x86,0x8e,0x92,0xa6,0xcf,0xaa,0x95,0x99,0x40,0x24,0xbe,0xa5,0xa3,0xd1,0x1c +,0x1d,0x0f,0x1e,0x3a,0x79,0x37,0x1f,0xef,0xb8,0x96,0x99,0x24,0x16,0x0d,0x13,0x10,0x0f,0x1a,0x0b,0x0f,0x23,0x1c,0x10,0x0e,0x28,0x67,0x18,0x0c,0x05,0x16,0x51,0x2c +,0xae,0xaf,0xfa,0x24,0x23,0x4f,0x2e,0x2d,0x19,0x3b,0xa8,0x3a,0x1d,0x0a,0x0a,0x16,0x49,0xa1,0x22,0x16,0x38,0x9d,0x89,0x8a,0x8c,0x99,0x9c,0x91,0x8d,0x82,0x84,0x8e +,0x87,0x83,0x81,0x85,0x85,0x88,0x9a,0x89,0x90,0x91,0x8f,0x93,0x88,0x96,0x96,0xa6,0x1d,0x30,0x21,0x36,0x1a,0x06,0x07,0x0c,0x1c,0x0e,0x07,0x03,0x00,0x05,0x04,0x01 +,0x02,0x00,0x0c,0x14,0x3a,0x5c,0x15,0x14,0x05,0x0b,0x1e,0xc7,0x2c,0x05,0x1b,0xa0,0x8c,0x99,0x27,0x25,0x35,0x97,0xdf,0x21,0x26,0xc5,0x8c,0x92,0x8b,0x88,0x89,0x8f +,0xcb,0x91,0x8b,0x9d,0xaf,0x97,0x8c,0x8b,0x8a,0x9f,0x53,0xba,0x8e,0x99,0xb7,0x26,0x63,0x8a,0x94,0x92,0x97,0x9c,0x9c,0x31,0xaf,0x9e,0xae,0x2e,0x13,0xa9,0x9a,0xed +,0x0e,0x0d,0x16,0x1d,0x75,0x1a,0x0a,0x08,0x79,0x9c,0x6d,0x24,0x13,0x23,0x1b,0x12,0x1e,0x19,0x26,0x1b,0x1d,0x2f,0x1a,0x18,0x0e,0x04,0x06,0x0c,0x14,0x0b,0x16,0x91 +,0x98,0xa0,0xb3,0x2c,0xc9,0x44,0x6a,0x49,0x2c,0x1e,0x1c,0x99,0x97,0x3a,0x16,0x1a,0x1d,0x46,0xa0,0xa6,0xba,0x9e,0x82,0x81,0x80,0x82,0x87,0x83,0x89,0x86,0x81,0x81 +,0x86,0x89,0x81,0x82,0x88,0x8d,0x96,0x3e,0x1b,0x11,0x0e,0x0c,0x18,0x2f,0x1b,0x39,0x24,0x15,0x15,0x06,0x0a,0x0a,0x03,0x02,0x03,0x17,0x13,0x0a,0x05,0x01,0x01,0x0f +,0x14,0x05,0x03,0x09,0x27,0xb5,0xa4,0x29,0x3f,0xa6,0x4b,0x9c,0x9a,0xa9,0x43,0xb9,0x91,0x90,0x96,0xa2,0x1f,0x37,0xb5,0x47,0xba,0xb2,0x93,0x8e,0x8b,0x83,0x89,0x88 +,0x8e,0x98,0x89,0x92,0x99,0xa4,0x8f,0x89,0x95,0x97,0x63,0xe7,0x96,0xac,0xb1,0x40,0x23,0xb6,0xae,0x8d,0x95,0xbc,0xba,0x21,0x48,0xbf,0x48,0x13,0x1c,0xae,0xa9,0xb0 +,0x1c,0x05,0x09,0x1c,0x0d,0x0b,0x07,0x0e,0x25,0x1f,0xae,0xb2,0x9c,0xca,0x0d,0x1d,0x13,0x10,0x08,0x0d,0x10,0x16,0xc8,0x26,0x0a,0x14,0x25,0x15,0x14,0x06,0x14,0x28 +,0xab,0x8f,0x9e,0xa8,0xaa,0x99,0x9f,0xcb,0x2b,0x17,0x20,0xa9,0x8e,0x90,0x9b,0x9d,0x89,0x89,0x8f,0x8c,0x90,0x8c,0x88,0x82,0x80,0x80,0x81,0x84,0x82,0x82,0x85,0x90 +,0xac,0xa2,0xb4,0xbb,0xb4,0x12,0x09,0x0e,0x0d,0x12,0x06,0x02,0x0c,0x0c,0x13,0x13,0x18,0x0e,0x0b,0x1d,0x10,0x0c,0x06,0x03,0x08,0x11,0x18,0x0e,0x02,0x02,0x11,0x1a +,0x16,0x09,0x19,0x45,0x54,0x92,0x8f,0x95,0x8e,0x94,0x96,0x9e,0x9a,0xa7,0xda,0xad,0x9e,0x91,0x92,0xba,0x22,0xae,0xa7,0xae,0x2f,0x47,0x9b,0x90,0x85,0x85,0x8a,0x88 +,0x8a,0x89,0x96,0xac,0xc3,0xa9,0x89,0x99,0xa1,0xad,0x52,0x49,0x9e,0x79,0x1b,0x0f,0x0e,0x2d,0x38,0x99,0x9d,0xa9,0x9d,0xa5,0x97,0xb2,0x26,0x11,0x0d,0x1f,0x0d,0x1b +,0x19,0x08,0x0a,0x1f,0x1f,0x08,0x09,0x09,0x1d,0x1f,0x20,0xb6,0xaf,0xa4,0x6f,0xaf,0xa3,0x21,0x17,0x0f,0x70,0xa0,0x3f,0x1d,0x28,0xa8,0xae,0xc7,0x1c,0x19,0x2d,0x9d +,0x8c,0x9e,0xa9,0x9f,0x8f,0x8a,0x95,0x96,0x4d,0x41,0xfb,0xac,0x96,0xa1,0xc8,0x1e,0x3f,0x33,0xc2,0xdd,0x1a,0x1e,0x42,0x9a,0x98,0x9f,0x98,0x99,0x8d,0x97,0x60,0x32 +,0x1d,0xbd,0xaf,0x9a,0x9b,0x2d,0x4a,0xa4,0x9c,0x2b,0x21,0x1b,0x17,0xc3,0xca,0x99,0x96,0x9f,0x8d,0x97,0x99,0x47,0x18,0x2b,0x2c,0x9f,0x39,0x34,0x29,0x24,0x9c,0xb4 +,0xb7,0x13,0x09,0x16,0x0f,0x29,0x2d,0xcb,0xcd,0x17,0x4b,0x51,0xbd,0x29,0x09,0x16,0x27,0x3f,0x17,0x0c,0x39,0xb4,0xa4,0x3a,0x0a,0x0c,0x13,0x2c,0x42,0x19,0x24,0x4a +,0x96,0x92,0xa9,0xbe,0x31,0xb9,0x63,0xa1,0x90,0x9c,0xac,0xce,0x93,0x88,0x97,0xc4,0xaf,0x91,0x8c,0x8f,0x90,0x9b,0x97,0x8e,0x8d,0x92,0xb5,0x26,0x19,0x48,0x9d,0x9b +,0xa6,0xee,0x4c,0xae,0xaf,0x4b,0x1f,0x1c,0x30,0x2b,0x59,0xbd,0xe2,0xb9,0xaa,0x3e,0x14,0x09,0x06,0x0c,0x18,0x22,0x17,0x16,0x11,0x15,0xda,0xad,0x50,0x17,0x0e,0x11 +,0x1b,0xc0,0xa7,0xb6,0xb0,0x9f,0xa5,0xcb,0x1b,0x0a,0x12,0x1f,0xc5,0xb6,0x25,0x12,0x1c,0x9b,0x8e,0xe3,0x13,0x15,0x2a,0xad,0xa8,0x99,0x97,0x90,0x8e,0x92,0x97,0xa6 +,0xa6,0xa0,0xa9,0xab,0xa4,0x9b,0x97,0x8e,0x8a,0x99,0x9e,0xcb,0xbe,0x9b,0x91,0x91,0x99,0x9a,0x9d,0x9d,0x97,0x94,0xb0,0x22,0x19,0x28,0x3b,0x31,0x19,0x0e,0x0c,0x09 +,0x05,0x02,0x01,0x00,0x03,0x05,0x03,0x04,0x08,0x09,0x0b,0x09,0x0a,0x0a,0x0e,0x16,0x17,0xb4,0x9d,0xa2,0xa3,0x96,0x8e,0x96,0x90,0x94,0x94,0x93,0x94,0x8e,0x88,0x83 +,0x84,0x85,0x87,0x8b,0x95,0x9d,0x93,0x8c,0x88,0x86,0x8c,0x8a,0x86,0x85,0x84,0x87,0x9a,0xbe,0x9b,0x9a,0x9e,0x98,0x97,0xa8,0xbd,0x30,0x1d,0x1b,0x0c,0x06,0x06,0x06 +,0x08,0x0c,0x12,0x16,0x12,0x1c,0x1b,0x0d,0x0d,0x0d,0x0d,0x0e,0x15,0x1f,0x1d,0x20,0x29,0x2d,0x26,0x17,0x1b,0x25,0x23,0x0f,0x0f,0x1c,0x29,0x40,0x29,0x24,0x2b,0x2f +,0x46,0x3e,0xda,0xba,0xc2,0xab,0xae,0xa5,0x9c,0xa5,0xc2,0xe8,0x9f,0x9a,0xa4,0xb1,0xba,0xb4,0x60,0xcf,0xb0,0xa3,0xa6,0xa5,0x94,0x8f,0x8c,0x89,0x89,0x89,0x8b,0x8a +,0x86,0x86,0x85,0x86,0x83,0x82,0x85,0x88,0x8b,0x8e,0x96,0xaa,0x2e,0x1c,0x14,0x0d,0x07,0x09,0x0a,0x06,0x06,0x02,0x02,0x03,0x03,0x02,0x03,0x03,0x08,0x0a,0x07,0x09 +,0x0e,0x13,0x19,0x0f,0x0c,0x09,0x0d,0x1b,0x32,0xbd,0x34,0x29,0x2d,0xb7,0x9e,0xa5,0xb2,0xae,0xa2,0x9d,0x9c,0x99,0x91,0x8e,0x8c,0x8c,0x8d,0x8c,0x8c,0x90,0x8f,0x8c +,0x8d,0x91,0x99,0x9f,0x94,0x8e,0x9a,0xad,0xb5,0xa3,0xb3,0x68,0x4f,0x40,0xb9,0xb9,0xb7,0xb2,0xd2,0x42,0x41,0x4e,0xcf,0x4e,0x20,0x1e,0x26,0x47,0xed,0x42,0x2d,0x2f +,0xcf,0x3e,0x57,0xe9,0xf0,0x35,0x2e,0x29,0x26,0xd9,0x3e,0x50,0x43,0x2a,0x1f,0x4b,0x34,0x15,0x12,0x1d,0x58,0x36,0x1d,0x17,0x2e,0x3a,0x25,0x24,0x2f,0x3d,0x2c,0x1d +,0x25,0x3e,0x21,0x1a,0x24,0x32,0x59,0x43,0xc4,0xa6,0xa6,0x9e,0x97,0x8d,0x8b,0x8b,0x8c,0x86,0x83,0x84,0x84,0x84,0x83,0x84,0x88,0x92,0x8f,0x8e,0x93,0xa5,0x2b,0x1b +,0x1c,0x18,0x13,0x12,0x0b,0x06,0x03,0x04,0x08,0x0c,0x09,0x07,0x08,0x0b,0x11,0x12,0x12,0x11,0x12,0x0f,0x0e,0x0f,0x17,0x27,0x38,0x3e,0x21,0x26,0x2c,0x50,0x3b,0x4e +,0x5d,0x5a,0xaf,0xae,0x9c,0x95,0x94,0x9c,0x98,0x97,0x90,0x8e,0x9b,0xa2,0x9c,0x94,0x8f,0x8f,0x98,0x9b,0x98,0x95,0x92,0x9c,0xa5,0xa2,0xa7,0xa1,0x99,0x9b,0xa6,0xa3 +,0xaf,0xd0,0xb3,0xac,0xb5,0xad,0x5b,0x36,0xb3,0xf4,0x38,0x41,0x33,0x26,0x24,0x22,0x26,0x1f,0x18,0x1a,0x17,0x12,0x15,0x17,0x11,0x0f,0x0e,0x12,0x21,0x23,0x16,0x10 +,0x1c,0x1e,0x15,0x15,0x21,0x2e,0x1a,0x1b,0x2d,0xd7,0x4e,0x1b,0x1f,0x2d,0x30,0x29,0x29,0x23,0x30,0x70,0x63,0xbb,0xb3,0xa8,0xa1,0xa8,0xba,0xa3,0x93,0x8c,0x8b,0x8b +,0x86,0x84,0x82,0x83,0x85,0x83,0x84,0x85,0x86,0x85,0x84,0x88,0x8a,0x93,0x9e,0x9c,0xaf,0x35,0x1b,0x0e,0x08,0x0a,0x0b,0x0d,0x0a,0x07,0x07,0x09,0x08,0x07,0x08,0x06 +,0x09,0x09,0x0d,0x0f,0x0e,0x0f,0x17,0x19,0x15,0x21,0x21,0x28,0x2c,0x27,0x49,0xd6,0xbf,0xa6,0xa3,0xb2,0xaf,0xbb,0xaa,0xa1,0xa1,0xa4,0x9f,0x98,0x9b,0x9f,0x9c,0x97 +,0x98,0x98,0x9e,0x99,0x96,0x95,0x91,0x96,0x98,0x98,0x9b,0x9c,0xa7,0xbd,0xb5,0x9f,0x9d,0xa9,0xab,0xa6,0x9f,0xc8,0x42,0x36,0x78,0x3d,0x28,0x2e,0x37,0x46,0x2d,0xc2 +,0x45,0x1b,0x1a,0x1f,0x2d,0x28,0x18,0x1a,0x1d,0x22,0x24,0x2a,0x52,0x1c,0x11,0x13,0x1d,0x28,0x20,0x1f,0x32,0x76,0x2f,0x32,0x48,0x40,0x21,0x1c,0x21,0x22,0x1f,0x24 +,0x33,0x2c,0x25,0x1c,0x1d,0x20,0x29,0x2b,0x1e,0x1e,0x3a,0xa7,0x98,0x90,0x8e,0x8f,0x8c,0x88,0x87,0x88,0x87,0x85,0x85,0x85,0x82,0x82,0x88,0x8a,0x8e,0x90,0x91,0x9b +,0xa5,0xd9,0x35,0x1d,0x15,0x10,0x13,0x11,0x07,0x05,0x08,0x0a,0x0d,0x0b,0x0a,0x0a,0x0d,0x0e,0x0d,0x0f,0x0f,0x0f,0x0f,0x12,0x17,0x23,0x2e,0x2b,0x2c,0x3a,0x30,0x2c +,0x31,0x49,0x2c,0x4a,0x9e,0x9f,0x9c,0x9e,0xa1,0xae,0x9e,0x97,0x98,0x9b,0xaa,0xa8,0x9c,0x93,0x8e,0x8a,0x8f,0x9f,0xaf,0x9c,0x98,0x99,0x99,0x9c,0xa2,0xa3,0x9a,0x90 +,0x8e,0xa8,0x6c,0xca,0xb0,0xbe,0x47,0xab,0xa7,0xaf,0xbc,0x4a,0xd4,0xf2,0x3a,0x2c,0x28,0x34,0x28,0x2e,0x33,0x33,0x2a,0x1d,0x23,0x20,0x26,0x1b,0x16,0x1e,0x1b,0x23 +,0x23,0x23,0x22,0x1c,0x18,0x15,0x20,0x1c,0x1c,0x16,0x15,0x1f,0x26,0x3b,0x1e,0x1b,0x16,0x1c,0x20,0x1c,0x2e,0x23,0x29,0x3e,0x34,0x33,0xe3,0xb8,0xb9,0xb3,0xa9,0x9c +,0x92,0x8c,0x8a,0x87,0x86,0x88,0x84,0x84,0x87,0x89,0x84,0x84,0x89,0x8a,0x8d,0x8a,0x8f,0xa0,0x4b,0x37,0x22,0x16,0x11,0x0d,0x0e,0x0e,0x0f,0x0b,0x0b,0x08,0x08,0x0b +,0x0b,0x0a,0x05,0x04,0x0a,0x0f,0x16,0x1a,0x1c,0x18,0x0f,0x13,0x1d,0x29,0x24,0x27,0x34,0x4d,0xbd,0xaa,0xa6,0xaa,0xb7,0xa2,0x9a,0xa8,0xbe,0xae,0x99,0x99,0x8f,0x93 +,0x98,0x98,0x98,0x97,0x98,0x98,0xa4,0x97,0x94,0x94,0x9c,0x9f,0x96,0x9c,0xa9,0xb0,0xae,0xbb,0xf8,0xb0,0x9e,0xa9,0xc6,0x29,0xbc,0x9a,0xb2,0x38,0x2b,0x4a,0xc9,0xc5 +,0xd3,0x5f,0x24,0x21,0x24,0x25,0x27,0x1e,0x20,0x1d,0x21,0x3e,0x3b,0x27,0x1e,0x18,0x13,0x1b,0x2b,0x1b,0x13,0x14,0x19,0x1d,0x27,0x2f,0x1d,0x1a,0x1e,0x1b,0x19,0x1b +,0x26,0x3f,0x2b,0x21,0x1e,0x39,0x6a,0x36,0x33,0x1e,0x1c,0x2a,0x72,0x9f,0x96,0x92,0x96,0x9b,0x8a,0x8a,0x88,0x89,0x8e,0x88,0x86,0x84,0x84,0x83,0x86,0x8b,0x86,0x86 +,0x95,0x9e,0xa2,0xb4,0x4a,0xc1,0x39,0x16,0x16,0x11,0x0d,0x0c,0x08,0x05,0x03,0x08,0x0d,0x09,0x09,0x09,0x0f,0x19,0x15,0x10,0x08,0x0c,0x13,0x1e,0x27,0x13,0x17,0x2f +,0x2b,0x4c,0xbe,0x5f,0x21,0x28,0xbf,0xb7,0x9f,0xac,0x3d,0xad,0x9a,0x93,0x9a,0xc7,0xaf,0xad,0x91,0x95,0x97,0x9c,0xac,0x94,0x91,0x8e,0xa4,0xaf,0x99,0x9f,0x97,0x94 +,0x9d,0x95,0xa3,0x9f,0x97,0x9b,0x9d,0x37,0xa8,0x9a,0xaa,0xb7,0x3b,0xa7,0xbd,0xaf,0x5d,0x29,0x2a,0x24,0xce,0xb3,0x4e,0x2b,0x2b,0x41,0xc7,0x2c,0x2e,0x0d,0x14,0x26 +,0x22,0xda,0x16,0x11,0x19,0x1b,0x2b,0x1c,0x14,0x10,0x13,0x1b,0x1f,0x1d,0x11,0x13,0x60,0xe4,0x66,0x1a,0x0e,0x16,0x17,0xcd,0x27,0x29,0x3e,0xc3,0xae,0xb2,0xcf,0xb7 +,0x98,0x80,0xad,0x0e,0x80,0x84,0x89,0x80,0x84,0x84,0x9a,0x8d,0x9f,0x88,0xa6,0x0a,0xd6,0x02,0x0a,0x07,0x03,0x07,0x00,0x02,0x03,0x04,0x04,0x05,0x01,0x07,0x08,0x09 +,0x0c,0x13,0x19,0x17,0x24,0x28,0x9d,0x80,0x86,0x94,0x8e,0x80,0x81,0x84,0x82,0x81,0x82,0x83,0x81,0x85,0x84,0x84,0x84,0x86,0x8c,0x8c,0x8d,0x8b,0x8b,0x8c,0x8d,0x98 +,0x91,0x9f,0xbe,0x2b,0x1a,0x24,0x1a,0x14,0x0f,0x09,0x0c,0x0b,0x07,0x08,0x02,0x03,0x05,0x05,0x04,0x04,0x07,0x02,0x01,0x01,0x04,0x03,0x01,0x01,0x02,0x03,0x02,0x05 +,0x04,0x09,0x0a,0x08,0x05,0x0a,0x0f,0x11,0x1d,0x11,0x1c,0x22,0xae,0x99,0x96,0x8f,0x96,0x8b,0x85,0x82,0x83,0x82,0x83,0x81,0x82,0x82,0x81,0x82,0x82,0x82,0x80,0x80 +,0x82,0x81,0x81,0x81,0x80,0x81,0x81,0x83,0x82,0x83,0x81,0x84,0x84,0x83,0x84,0x83,0x84,0x85,0x88,0x89,0x89,0x88,0x88,0x96,0x97,0x91,0xb2,0xaf,0x2d,0x1b,0x0d,0x0c +,0x14,0x18,0x0e,0x06,0x04,0x05,0x07,0x05,0x05,0x02,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01,0x01,0x01,0x04,0x06,0x0a,0x04,0x09,0x07,0x06,0x05,0x04 +,0x06,0x03,0x06,0x05,0x08,0x08,0x06,0x0c,0x0d,0x18,0x1a,0x24,0xd5,0xd0,0x9c,0xad,0x97,0x95,0x9a,0x8d,0x8f,0x8e,0x9a,0x8e,0x8e,0x8e,0x85,0x8b,0x8a,0x89,0x87,0x86 +,0x86,0x83,0x84,0x81,0x81,0x83,0x81,0x84,0x82,0x84,0x87,0x8c,0x8a,0x8d,0x91,0x8b,0x91,0x93,0x90,0x96,0x8f,0x89,0x86,0x8a,0x8b,0x86,0x86,0x87,0x8b,0x8c,0x8d,0x8b +,0x96,0xa4,0xab,0xad,0x9f,0xa3,0x8f,0x9c,0x96,0x8d,0x88,0x86,0x8b,0x84,0x8b,0x9d,0xb6,0xb5,0xae,0x15,0x09,0x06,0x0c,0x0c,0x01,0x08,0x09,0x08,0x15,0x1b,0x2c,0x60 +,0xb0,0x9b,0x97,0x92,0x3b,0xb8,0xdb,0x25,0x43,0x2c,0x17,0x10,0x42,0x19,0x57,0x4d,0x1f,0x1d,0x1e,0xd5,0x15,0x19,0x0b,0x04,0x09,0x03,0x01,0x01,0x03,0x00,0x02,0x04 +,0x00,0x04,0x0a,0x03,0x07,0x11,0x05,0x05,0x0c,0x02,0x03,0x05,0x00,0x00,0x03,0x01,0x00,0x04,0x00,0x02,0x06,0x05,0x02,0x0e,0x07,0x02,0x1e,0x09,0x06,0x0b,0x02,0x03 +,0x1e,0x0a,0x0f,0x6a,0x21,0xaa,0x8d,0x8c,0x92,0x80,0x86,0x88,0x80,0x82,0x86,0x81,0x89,0x8b,0x80,0x92,0x84,0x80,0x84,0x80,0x81,0x80,0x82,0x80,0x81,0x80,0x80,0x84 +,0x86,0x80,0x8b,0x85,0x81,0x89,0x80,0x85,0x80,0x80,0x80,0x81,0x80,0x80,0x80,0x80,0x80,0x81,0x80,0x83,0x90,0x80,0xa5,0x92,0x88,0xb9,0x86,0xad,0x12,0x1a,0x12,0x06 +,0x05,0x07,0x01,0x00,0x01,0x00,0x06,0x04,0x00,0x0a,0x00,0x05,0x0e,0x01,0x04,0x07,0x08,0x06,0x05,0x05,0x00,0x02,0x00,0x03,0x07,0x00,0x0c,0x06,0x01,0x1c,0x09,0x04 +,0x19,0x0a,0x0f,0x14,0x12,0x06,0x0b,0x0b,0x16,0x7d,0x08,0xb5,0xac,0x2a,0x91,0x9f,0x1d,0x92,0xa9,0xaf,0x9f,0x9e,0x3b,0x27,0x2b,0x3d,0x96,0x11,0x8c,0x96,0x32,0x89 +,0x96,0x2d,0x8b,0x99,0xa2,0x95,0x97,0x7a,0x3f,0xfc,0xad,0x8b,0x1f,0x86,0x8a,0xba,0x84,0x8b,0x41,0x87,0x8b,0x95,0x93,0x92,0xc2,0xf9,0x39,0x2e,0x8e,0x12,0x98,0xaa +,0x0e,0x8f,0xa9,0x05,0xc6,0x3c,0x12,0x0e,0x1f,0x0e,0x07,0x09,0x17,0x9f,0x0d,0x8f,0x96,0xb8,0x83,0x87,0x97,0x82,0x82,0x84,0x83,0x80,0x85,0x8d,0x8a,0x84,0x88,0xb1 +,0x80,0x90,0x1b,0x8d,0xcc,0x05,0x25,0x13,0x06,0x05,0x0c,0x02,0x02,0x00,0x10,0x14,0x00,0xaa,0x22,0x03,0x9c,0xc9,0x0d,0xaf,0xba,0xce,0x3c,0x8e,0xb5,0x19,0x20,0x8b +,0x9c,0x24,0x80,0x99,0x20,0x88,0x89,0x62,0x91,0x8a,0x95,0xbf,0x8f,0xa4,0x1d,0x25,0x88,0xa2,0x3c,0x80,0x94,0x19,0x8b,0x8a,0x5a,0x9a,0x8f,0x98,0x3e,0x8f,0xa3,0x0f +,0x19,0x87,0x58,0x17,0x84,0xa4,0x0a,0xb8,0x9e,0x15,0x20,0xb8,0x28,0x0a,0x2b,0x18,0x04,0x05,0x99,0x18,0x12,0x86,0xae,0x08,0x32,0x9b,0x24,0x12,0xb6,0xb0,0x0e,0x2c +,0x2b,0x0f,0x0e,0x95,0x17,0x1f,0x8a,0x2d,0x03,0x12,0x71,0x14,0x0a,0x30,0x1b,0x02,0x0d,0x0d,0x03,0x04,0x68,0x0d,0x12,0x97,0xbc,0x1f,0xa3,0x88,0x8b,0x96,0x83,0x83 +,0x8b,0x84,0x80,0x86,0x89,0x80,0x86,0x84,0x80,0x86,0x9d,0x9c,0x97,0x9a,0x22,0x56,0x1f,0x04,0x07,0x06,0x00,0x02,0x12,0x04,0x0a,0x2c,0x0f,0x04,0x07,0x0f,0x1b,0x09 +,0x1f,0x26,0x0c,0x1c,0x36,0x0f,0x14,0x9b,0x1d,0xcc,0x8f,0xbd,0x1d,0x21,0xc8,0x9a,0xd7,0x9c,0x9d,0x2a,0xd9,0xaf,0x25,0x21,0x92,0x3f,0x97,0x82,0x90,0xa8,0x9e,0x96 +,0x8d,0x96,0x8d,0x8d,0xb8,0x9c,0x99,0xab,0xb8,0x87,0xa8,0x9d,0x87,0x8f,0xdc,0x20,0x4e,0xad,0x7b,0xc5,0xfa,0x13,0x1a,0x11,0x0e,0x0b,0x61,0x12,0x14,0x9c,0xa2,0x22 +,0x0d,0x26,0xaf,0x75,0xc2,0x9e,0x28,0x1f,0x19,0x25,0x1c,0xb8,0x27,0x24,0x93,0xa0,0x18,0x08,0x11,0x27,0x2b,0x29,0x5f,0x0f,0x08,0x08,0x11,0x08,0x18,0x1a,0x0c,0xbf +,0xab,0x2b,0x1e,0x3c,0x9c,0x90,0x8e,0x84,0x87,0x88,0x86,0x80,0x83,0x83,0x81,0x85,0x81,0x80,0x87,0x91,0x97,0x8d,0x8c,0xab,0xa3,0x3b,0x0e,0x0a,0x07,0x02,0x01,0x09 +,0x04,0x07,0x21,0x10,0x03,0x02,0x0b,0x16,0x0e,0x17,0x2d,0x0e,0x0f,0x27,0x24,0x10,0xab,0xd6,0x1e,0x91,0x9d,0x2f,0x18,0x1f,0x9f,0x94,0x9f,0x91,0x3a,0x25,0x33,0x4e +,0x1e,0x2d,0x97,0x40,0x93,0x87,0x8e,0xbd,0x46,0x91,0x87,0x8f,0x91,0x8e,0x97,0x9b,0x9d,0x9a,0xad,0x92,0xaf,0xa1,0x86,0x96,0x2d,0x10,0x3c,0x95,0xb0,0x49,0xa5,0x21 +,0x1b,0x18,0x1c,0x0c,0x16,0x52,0x26,0x94,0x9c,0x22,0x0b,0x0e,0xce,0x9a,0x30,0xce,0x45,0x2e,0xd7,0x36,0x32,0x0f,0xc9,0xd2,0x3c,0xac,0x1e,0x0b,0x06,0x16,0xb4,0x22 +,0x0d,0x14,0x0f,0x19,0x0d,0x04,0x03,0x0c,0x23,0x29,0xa3,0xa2,0x49,0x21,0x55,0x8a,0x88,0x91,0x88,0x84,0x82,0x80,0x87,0x8a,0x88,0x82,0x81,0x83,0x85,0x86,0x96,0xb7 +,0xa1,0x8c,0xaf,0x1c,0x18,0x1c,0x22,0x04,0x01,0x01,0x05,0x19,0x16,0x0b,0x15,0x0e,0x06,0x0b,0x19,0x24,0x10,0x0f,0x2a,0xbd,0x2d,0x09,0x0d,0x0b,0x33,0x97,0x2e,0xd9 +,0xb5,0x3b,0xb9,0x9a,0x99,0x9b,0x38,0xb0,0x95,0x9c,0x3e,0x16,0x17,0x3e,0x85,0x90,0xbe,0x98,0x90,0x94,0xa4,0xad,0x95,0x9f,0xaf,0x8a,0x86,0x8f,0x1c,0x11,0x2a,0x8f +,0x89,0xcf,0xb6,0x99,0x98,0xad,0xea,0xaa,0xad,0x23,0xae,0x9f,0x5b,0x10,0x02,0x0d,0x2f,0x90,0xc1,0x11,0x28,0xa6,0xa3,0x1c,0x16,0x1e,0x1d,0x30,0x9e,0xa3,0xb8,0x0e +,0x07,0x13,0xb3,0x99,0x12,0x0f,0xba,0x95,0x40,0x0c,0x0b,0x1d,0x1d,0x36,0x1c,0x0f,0x07,0x00,0x09,0x14,0xb1,0x25,0x14,0x4f,0x86,0x88,0xa3,0xa3,0x8b,0x80,0x81,0x80 +,0x82,0x80,0x8b,0x8c,0x83,0x83,0x80,0x8e,0x94,0x86,0x80,0xa4,0x0b,0x0b,0x1f,0x2f,0x0a,0x01,0x06,0x01,0x01,0x01,0x08,0x23,0x09,0x01,0x16,0xa1,0x1e,0x04,0x02,0x18 +,0x99,0xad,0x1b,0x21,0x1c,0x12,0x20,0x1b,0x97,0x9a,0x23,0xc8,0x8a,0x85,0xa5,0x1a,0x2c,0x95,0x8e,0x35,0x1d,0x34,0x5e,0xb7,0x3a,0x91,0x89,0xa0,0xa8,0x84,0x84,0x95 +,0x12,0x12,0x92,0x83,0x8f,0xe0,0xf5,0xb1,0x9a,0x2c,0x9c,0x90,0xa5,0xa9,0x90,0x89,0xc0,0x11,0x15,0x53,0x93,0x4b,0x0d,0x11,0x1a,0x2d,0x11,0xab,0xad,0xd8,0xb1,0x97 +,0x91,0x2d,0x0b,0x06,0x1b,0x98,0xc8,0x13,0x0f,0x16,0x19,0x0a,0x2e,0x1e,0x20,0x1f,0xbc,0xb3,0x11,0x05,0x05,0x14,0xae,0x22,0x0b,0x07,0x0b,0x0c,0x0e,0xaf,0x26,0xa8 +,0x99,0x88,0x87,0xa6,0xb3,0xa2,0x87,0x80,0x80,0x84,0x89,0x87,0x89,0x82,0x82,0x85,0x8a,0x8d,0x86,0x8e,0x34,0x18,0x1e,0xd8,0xb8,0x10,0x03,0x01,0x02,0x00,0x20,0x1a +,0x0e,0x0f,0x14,0x42,0x15,0x07,0x09,0x0f,0x1a,0x36,0x1d,0x0f,0x14,0x09,0x2e,0x8d,0xa8,0x37,0x28,0x47,0xca,0x2d,0x22,0x45,0x99,0x9d,0xb0,0x53,0x25,0x13,0x14,0x97 +,0x89,0x86,0x92,0x92,0x8a,0x98,0x97,0xa3,0x96,0x8b,0xa9,0x28,0xb1,0x5d,0x28,0x97,0x97,0x8e,0x8b,0xbb,0xc4,0x24,0x11,0x47,0x37,0xf3,0xba,0x18,0x0e,0x24,0x0c,0x11 +,0x47,0x1a,0x9c,0x8f,0x9b,0x37,0x13,0x14,0xb5,0x97,0x9d,0x25,0x0d,0x19,0x19,0x4c,0xaa,0xcd,0x99,0x95,0x8c,0xbe,0x03,0x07,0x06,0xaf,0x89,0x4d,0x15,0x0c,0x0d,0x38 +,0x9a,0x2f,0x3b,0xb2,0xa0,0x93,0x13,0x0b,0x20,0x9e,0x83,0x8b,0x3f,0x20,0x14,0x66,0x85,0x89,0x8d,0x8f,0x8b,0x83,0x9e,0x20,0x1b,0x73,0x90,0xa3,0x3e,0x29,0x0e,0x1b +,0x98,0x94,0x90,0xbd,0x1f,0x3d,0x0a,0x09,0x0d,0x19,0xbb,0x44,0x16,0x2f,0x16,0x17,0x9a,0x27,0x9e,0x9b,0xba,0x4d,0x08,0x0b,0x28,0xa7,0xa1,0x2a,0x0f,0x17,0x1b,0x96 +,0x96,0xa4,0x99,0x9e,0x89,0x76,0x03,0x0c,0x25,0x8c,0x84,0x39,0x28,0x2d,0xba,0x80,0x8b,0x90,0x95,0x94,0x83,0x9a,0x23,0x1d,0xb3,0x86,0x89,0xcd,0x19,0x07,0xa8,0x88 +,0xa1,0x98,0x26,0xa5,0xa0,0x0a,0x0e,0x0e,0x1d,0x6b,0x08,0x05,0x09,0x0a,0x95,0x99,0xa8,0xa3,0x37,0xab,0x13,0x08,0x0d,0x25,0x8f,0xbc,0x0a,0x0c,0x0b,0x9f,0x89,0x1a +,0x21,0x1f,0xb0,0xc5,0x05,0x03,0x0e,0xa5,0x99,0x1b,0x06,0x02,0x0d,0x8e,0x94,0xa0,0xb8,0xbb,0x86,0xa8,0x1e,0x3c,0xa4,0x80,0x88,0xa3,0xa7,0x3c,0x88,0x80,0x8a,0x89 +,0x8f,0x85,0x8d,0x1a,0x19,0xb6,0x89,0x89,0x2c,0x18,0x0b,0x47,0x8a,0x35,0xc4,0x16,0x22,0x98,0x0c,0x05,0x06,0x2e,0x8a,0x3f,0x06,0x01,0x08,0x8c,0x8d,0xa7,0x1c,0x18 +,0x99,0x17,0x08,0x05,0x0f,0xa5,0xc9,0x0f,0x0a,0x03,0xbc,0x8b,0x9b,0x9d,0x28,0xad,0x37,0x0c,0x0d,0x1f,0x8a,0x87,0xa5,0x27,0x14,0x92,0x81,0x89,0x8b,0xa2,0x8a,0x87 +,0x28,0x10,0x2a,0x8d,0x81,0x9e,0x17,0x08,0x2d,0x86,0x8e,0x95,0x19,0x32,0x95,0x1d,0x13,0x04,0x14,0x94,0x73,0x12,0x03,0x09,0x8b,0x88,0x8d,0xbe,0x22,0x96,0x3b,0x1f +,0x11,0x33,0x89,0x99,0x3c,0x09,0x07,0x93,0x8a,0x8d,0xa9,0x0e,0x2d,0x1c,0x0f,0x0c,0x0c,0xaf,0xab,0x1d,0x06,0x01,0x27,0x98,0x8d,0x9d,0x1c,0xaf,0x65,0x27,0x22,0x1c +,0x93,0x8a,0x93,0xe3,0x13,0x9b,0x86,0x85,0x89,0xa6,0x95,0xb9,0x54,0x2d,0x18,0x9f,0x9b,0xa8,0x3b,0x09,0xe4,0x9a,0x9a,0x9b,0x13,0x22,0x1b,0x1f,0x1d,0x11,0xbb,0xbe +,0x45,0x20,0x04,0xe7,0x92,0x93,0x90,0x1c,0x3d,0x26,0x14,0x1a,0x13,0x7b,0xab,0x2f,0x14,0x02,0x17,0xaa,0x96,0x8a,0x2a,0x39,0x1e,0x0d,0x21,0x11,0xbd,0x92,0xa2,0xb8 +,0x11,0x37,0x8b,0x89,0x83,0x94,0x8c,0x93,0xd6,0xa9,0x21,0x9d,0x8e,0x9f,0xa0,0x11,0x2a,0x90,0x96,0x8f,0x40,0x3a,0xdb,0x1b,0x1e,0x0b,0x1a,0x3e,0x21,0x22,0x05,0x0e +,0xaf,0x9d,0x8b,0x51,0x21,0x55,0x1d,0x48,0x3f,0xbd,0x9f,0xb8,0x49,0x0f,0x18,0x9f,0x94,0x87,0xab,0x39,0xc3,0x14,0x20,0x19,0x2c,0xa4,0x2c,0x15,0x0a,0x09,0x57,0xa4 +,0x8e,0xad,0x36,0xc1,0x1e,0xbc,0x33,0xa7,0x8d,0x9d,0x9f,0x25,0x17,0x92,0x8b,0x83,0x8d,0xb0,0x9f,0x3f,0xb9,0x4d,0xa7,0x93,0xb2,0x38,0x0b,0x0c,0xac,0xbd,0x8e,0x9e +,0x16,0x48,0x13,0x17,0x1d,0x1f,0xa6,0xbe,0x2b,0x0f,0x09,0xd7,0x9b,0x88,0x9a,0x25,0xb9,0x16,0x2a,0x2e,0x22,0x9a,0xb9,0x26,0x17,0x04,0x2f,0xa5,0x94,0x95,0x27,0x23 +,0x0d,0x1a,0x15,0x1c,0xa1,0xc5,0xe3,0x1d,0x07,0xb2,0x96,0x8c,0x86,0xdf,0x9b,0xb0,0xed,0xbe,0xb6,0x91,0x94,0x96,0xba,0x14,0xf2,0x9d,0x8c,0x86,0x42,0xb2,0x20,0x1a +,0x3d,0x12,0x2d,0x45,0x1f,0x1e,0x0b,0x11,0xbb,0x9f,0x92,0xc7,0x52,0x1c,0x1c,0x3f,0x28,0x99,0xa3,0x64,0xb7,0x18,0x28,0x97,0x9a,0x87,0x9e,0x60,0x49,0x19,0x2e,0x26 +,0xb6,0xc9,0x3a,0x1e,0x08,0x0d,0x3b,0xb5,0x89,0xac,0x35,0xda,0x0e,0x29,0x1f,0xb1,0x95,0xc6,0x56,0x24,0x1a,0xa8,0x95,0x8a,0x8d,0x9a,0x9d,0x1c,0x2f,0x24,0xba,0x95 +,0xad,0xb7,0x19,0x0a,0x38,0xb0,0x9e,0x94,0x20,0x3e,0x1c,0x0f,0x16,0x1e,0xab,0xb2,0x54,0x1c,0x0c,0x24,0xa5,0x8e,0x88,0xb3,0x99,0x58,0x1c,0xb9,0x41,0x98,0x9a,0xee +,0x39,0x10,0x15,0x9c,0x99,0x93,0xa9,0x51,0x2a,0x12,0x17,0x11,0xc5,0x9e,0xdb,0x23,0x0a,0x08,0xba,0x9d,0x8b,0x93,0x3b,0xa5,0x25,0x37,0xdb,0xb4,0x96,0x94,0xa4,0x21 +,0x0b,0x20,0x9a,0x8a,0x8c,0xb6,0xc4,0x11,0x1a,0x23,0x1e,0xb5,0xcc,0x33,0x1b,0x09,0x10,0xdf,0xaf,0x8e,0xa8,0xc0,0x33,0x17,0x26,0x2e,0x9c,0x94,0x96,0xb0,0x19,0x1a +,0xa7,0x90,0x88,0x98,0xc9,0xcb,0x1b,0x44,0x27,0x30,0xa6,0xb8,0x71,0x19,0x08,0x16,0xb6,0x98,0x8e,0x73,0x23,0x0f,0x19,0x31,0x5d,0xa0,0xc1,0xa9,0x2b,0x15,0x29,0xac +,0x95,0x85,0x93,0x9b,0x4e,0x0f,0x34,0x46,0x92,0x91,0xa8,0x2a,0x0c,0x09,0x2c,0x9f,0x91,0x9d,0x3a,0x20,0x0d,0x1e,0x10,0x2a,0xac,0xb9,0x9e,0x1b,0x0a,0x1e,0xa1,0x8a +,0x82,0x9a,0xaf,0x25,0x1d,0xe0,0xcf,0xa5,0xa2,0x9f,0x35,0x18,0x10,0x29,0xa9,0x8d,0x95,0xbd,0x1c,0x06,0x17,0x16,0xba,0x95,0xaf,0x3e,0x13,0x0a,0x2d,0x9e,0x90,0x8b +,0xba,0xa9,0x33,0x25,0x21,0x41,0x95,0x8f,0x8d,0x34,0x0c,0x0f,0x55,0x91,0x85,0xa3,0x3f,0x1b,0x0f,0x29,0x13,0x31,0xae,0xb1,0x3f,0x17,0x07,0x15,0xac,0x8b,0x88,0x9b +,0xbb,0x19,0x24,0x27,0x9f,0x8f,0x9c,0x9f,0x22,0x0f,0x2b,0xb0,0x98,0x88,0xa2,0xab,0x2e,0x0e,0x14,0x12,0xb6,0x8e,0x94,0x24,0x08,0x03,0x1a,0x94,0x87,0x99,0xce,0x2d +,0x16,0x24,0x16,0x4e,0x98,0x96,0x90,0x54,0x09,0x12,0xbf,0x8e,0x80,0x92,0x4f,0x0f,0x0c,0x1f,0xc5,0x9e,0xa9,0xb5,0x1f,0x0d,0x0d,0x1a,0xb4,0x8d,0x96,0x93,0xc9,0x09 +,0x0e,0x14,0x9c,0x85,0x8d,0xaf,0x16,0x06,0x31,0x96,0x8d,0x89,0xbb,0x5e,0x1d,0x1e,0x11,0x1d,0xa2,0x9c,0x8f,0x37,0x04,0x08,0x27,0x91,0x81,0x98,0xbe,0x12,0x05,0x1e +,0x3e,0xa9,0xa1,0xad,0x4c,0x1f,0x0f,0x21,0xad,0x8b,0x87,0x8b,0xa9,0x07,0x0e,0x17,0x98,0x84,0x96,0xfb,0x10,0x02,0x20,0x9f,0x9d,0x90,0xb3,0xa1,0x21,0x0f,0x0d,0x1a +,0x9a,0x8e,0x8b,0x22,0x04,0x04,0x1a,0x93,0x80,0x8e,0xa7,0x1c,0x0a,0x45,0x3d,0xab,0x98,0x9b,0xa1,0x36,0x0a,0x0f,0x50,0x90,0x81,0x88,0xc1,0x05,0x06,0x10,0x9b,0x8a +,0x9d,0x56,0x0f,0x07,0x1d,0xca,0xba,0x8a,0x9d,0x99,0xba,0x09,0x0e,0x13,0x9b,0x86,0x89,0x2e,0x09,0x03,0x1e,0x8d,0x84,0x8e,0xea,0x19,0x0f,0xb7,0x20,0x2f,0x97,0x9d +,0x99,0x29,0x04,0x0a,0x33,0x91,0x80,0x92,0x28,0x0b,0x07,0x19,0xad,0x99,0xa0,0xab,0x1e,0x0e,0x0f,0x29,0x9b,0x83,0x8e,0x9f,0x2f,0x09,0x17,0x18,0x97,0x83,0x8f,0x38 +,0x0b,0x01,0x13,0x96,0x8a,0x88,0xac,0x25,0x15,0x18,0x14,0x33,0x95,0x93,0x97,0x19,0x01,0x06,0x4a,0x8b,0x80,0x91,0x3b,0x19,0x06,0x21,0xe8,0xa7,0x8e,0x96,0x3a,0x19 +,0x0a,0x1e,0x8f,0x84,0x87,0x9f,0x2b,0x07,0x15,0x10,0xaf,0x88,0xa0,0x4a,0x0d,0x00,0x0f,0x9b,0x93,0x86,0xa4,0x41,0x4a,0x14,0x20,0xbc,0x93,0x8b,0x8d,0x1d,0x07,0x05 +,0x24,0x89,0x80,0x93,0x27,0x19,0x08,0x20,0x1f,0xc1,0x8f,0xa4,0xcb,0x13,0x01,0x16,0x8d,0x8b,0x85,0xa5,0x1f,0x0f,0x09,0x12,0xba,0x8c,0x8f,0x95,0x16,0x07,0x14,0x9b +,0x88,0x83,0xb5,0x3b,0xae,0x0d,0x22,0x1f,0xa8,0x8a,0x99,0x17,0x08,0x00,0x19,0x8a,0x8b,0x8e,0x3c,0x1e,0x1b,0x33,0x14,0xb5,0x8a,0x8d,0x92,0x14,0x02,0x0e,0x8f,0x87 +,0x84,0xbe,0x34,0x31,0x0a,0x1d,0x18,0xa1,0x8c,0xb1,0x0c,0x05,0x0b,0x8f,0x83,0x8e,0xa9,0x1d,0xaf,0x13,0x0f,0x15,0xab,0x8d,0x86,0xa3,0x05,0x05,0x0d,0x93,0x81,0x88 +,0x14,0x1b,0x1a,0xc5,0x34,0x00,0xa1,0x80,0xa0,0x0e,0x04,0x05,0x8c,0x83,0x88,0xaa,0x23,0x2e,0x05,0x00,0x0c,0x82,0x85,0x9e,0x97,0x0f,0x09,0x8e,0x83,0x87,0x8f,0x2e +,0x9a,0x11,0x02,0x02,0x23,0x81,0x8f,0x0e,0x00,0x06,0x10,0x9b,0x9d,0x94,0xad,0x97,0x1f,0x0a,0x8d,0x8d,0x87,0x8d,0x9d,0x1a,0x07,0x03,0xa8,0x8a,0x8b,0x8e,0x4c,0x28 +,0x0d,0x2b,0x1a,0x8c,0x82,0xa6,0x0b,0x03,0x0c,0x3d,0x8d,0x8b,0x8b,0x07,0x0d,0x1d,0x20,0x07,0x24,0x85,0x8a,0xc2,0x04,0x00,0x0a,0x87,0x87,0x9b,0x25,0x8e,0x8c,0x17 +,0x26,0xa8,0x80,0x85,0xa0,0x0b,0x09,0x07,0xc0,0x9a,0x6a,0x9b,0xbc,0xbc,0x09,0x06,0x06,0x9c,0x80,0xa0,0x0a,0x03,0x13,0x94,0x87,0xbd,0x8f,0x8e,0x8b,0x11,0x01,0x19 +,0x8c,0x80,0x92,0x56,0x09,0x15,0x18,0xb5,0x9b,0x83,0x9a,0x16,0x0d,0x04,0x0f,0x36,0x84,0x88,0x3f,0x04,0x07,0x04,0xdc,0x86,0x86,0x92,0x26,0x2e,0x04,0x0e,0xee,0x88 +,0x88,0xa3,0xd8,0x0d,0x03,0xac,0x80,0x82,0x88,0xad,0xc8,0x0e,0x05,0x07,0x39,0x8f,0xc9,0x09,0x00,0x04,0x14,0x8c,0x90,0x8f,0x92,0xa2,0x1e,0x04,0x1f,0x8f,0x81,0x86 +,0xa5,0x06,0x07,0x2c,0x86,0x88,0x8f,0x9c,0x2f,0x19,0x02,0x08,0x4b,0x80,0x85,0x30,0x02,0x0c,0x1f,0xa0,0x93,0x9a,0x8d,0x4f,0x0f,0x00,0x08,0xa9,0x80,0x8a,0x0f,0x01 +,0x07,0x12,0x37,0x89,0x8b,0x85,0x86,0x8d,0x1a,0x06,0xb8,0x87,0x83,0x2a,0x14,0x0e,0x20,0x19,0xa5,0x90,0x9c,0xda,0x09,0x06,0x00,0x0a,0x52,0x8e,0x93,0x8d,0x3d,0x1a +,0x1e,0x96,0x84,0x91,0x8e,0xbf,0x1e,0x06,0x10,0x9a,0x82,0x85,0xaa,0x0b,0x08,0x0b,0x3b,0x8c,0x8e,0x8d,0x38,0x2a,0x0c,0x08,0x13,0x95,0x83,0x66,0x06,0x03,0x09,0x30 +,0x8a,0x8b,0x88,0x99,0xb8,0x0c,0x00,0x0a,0x95,0x80,0x8f,0xd0,0x37,0x5e,0xbd,0x89,0x88,0x8a,0x9b,0xb3,0x16,0x00,0x0b,0xa0,0x82,0x9d,0x0d,0x00,0x05,0x0b,0xcd,0xc3 +,0x9e,0x8d,0xa3,0x2b,0x06,0x3e,0x8f,0x80,0x8f,0x1c,0x11,0x13,0x17,0xac,0x88,0x87,0x85,0xc4,0x1d,0x04,0x12,0xb7,0x8e,0x86,0xb5,0x20,0x0d,0x0d,0x15,0x9c,0x91,0x8d +,0x26,0x08,0x04,0x08,0x24,0x9b,0x83,0x95,0x33,0x0b,0x05,0x0b,0x9d,0x88,0x88,0x95,0x9c,0xa3,0x20,0xf9,0x8f,0x80,0x8d,0xd3,0x0d,0x0c,0x0e,0xbb,0x95,0xaf,0xb6,0x13 +,0x08,0x00,0x07,0x2c,0x8f,0x96,0x4a,0x17,0x1e,0x26,0x97,0x88,0x96,0x8e,0xab,0x4d,0x0c,0x13,0xaa,0x86,0x84,0xa7,0x14,0x0b,0x0e,0x2a,0x8e,0x90,0x87,0x9c,0x2e,0x0c +,0x0a,0x2d,0x9f,0x98,0x4a,0x0e,0x05,0x09,0x0b,0x9e,0x8b,0x86,0x94,0x28,0x0c,0x04,0x28,0x9c,0x88,0x97,0x59,0xc7,0xce,0x29,0x8f,0x88,0x86,0x8e,0x2f,0x1a,0x0d,0x2a +,0x4b,0x9c,0x44,0x16,0x0b,0x04,0x03,0x28,0x8f,0x8f,0x98,0x32,0x4c,0x15,0xf9,0x9c,0x8d,0x90,0x58,0x18,0x0c,0x0d,0x3f,0x86,0x84,0x89,0xaa,0x28,0x0b,0x14,0xcd,0x99 +,0x8c,0xac,0x1a,0x0d,0x0a,0x2a,0x8f,0x92,0x95,0xe3,0x22,0x08,0x0b,0x24,0x9c,0x8a,0xbf,0x1e,0x0b,0x0c,0x13,0xa4,0x90,0x90,0x96,0xaa,0x53,0x27,0xbb,0x94,0x89,0x91 +,0x6f,0x16,0x2a,0x22,0x9b,0x8f,0x9e,0xb7,0x1d,0x0d,0x02,0x0d,0x25,0xab,0x45,0x1f,0x1b,0x46,0x24,0xa3,0x85,0x8b,0x8c,0x2f,0x13,0x0a,0x1b,0x9d,0x8e,0x97,0xb7,0x26 +,0x23,0x1a,0x56,0x8b,0x8e,0x8c,0xd5,0x22,0x0d,0x17,0xce,0xaa,0xa9,0x32,0x19,0x15,0x10,0x18,0x8e,0x92,0x98,0x3e,0x1d,0x10,0x0d,0x1f,0x33,0xa1,0xa6,0x49,0x4d,0xdc +,0xd0,0x88,0x87,0x8a,0x9e,0xba,0x29,0x17,0xcc,0xb5,0xa0,0xd9,0x19,0x0d,0x0d,0x0b,0xbf,0x9d,0xa6,0x3f,0x1b,0x29,0x12,0x3e,0x9d,0x8d,0x9c,0x31,0x1c,0x1d,0x21,0xa6 +,0x8b,0x8d,0x90,0xce,0x2b,0x0c,0x1b,0xa8,0x8f,0x95,0x3d,0x27,0x25,0x1d,0x3b,0x92,0x9c,0xa4,0x2d,0x17,0x07,0x17,0x66,0x9c,0x9b,0x3d,0x26,0x1a,0x17,0x0e,0x9f,0x9b +,0x97,0x5d,0x23,0x28,0xbd,0x90,0x8a,0x8b,0xa2,0xb0,0x23,0x37,0x1c,0x97,0x90,0x96,0x32,0x0f,0x0f,0x06,0x21,0xbf,0xa3,0x26,0x1a,0x10,0x1d,0x1b,0x97,0x88,0x90,0xa2 +,0x1e,0x1e,0x13,0x4f,0x9f,0x8e,0x96,0xae,0x29,0x26,0x10,0xb9,0x8e,0x9b,0x98,0x29,0x2a,0x11,0x28,0xa7,0x95,0x9c,0x35,0x15,0x11,0x0b,0x1e,0x8f,0x9a,0x96,0x24,0x3d +,0x19,0x12,0xaf,0xa6,0x9d,0x2d,0x10,0x15,0x20,0xbc,0x86,0x8a,0x89,0xa1,0xca,0x29,0x19,0x9b,0x92,0x8f,0x2f,0x0f,0x14,0x0b,0x0a,0xc4,0xa9,0xa7,0x2b,0x16,0x14,0x0f +,0xa0,0x8c,0x88,0xa1,0x1e,0x1e,0x1b,0x0e,0xb5,0x93,0x8e,0x92,0xbe,0xec,0x12,0xc3,0x95,0x95,0xb4,0x1b,0x1b,0x1a,0x13,0xbd,0x8e,0x8e,0x9f,0x4d,0x3c,0x0f,0x19,0x39 +,0xa0,0xb8,0x26,0x1d,0x18,0x0f,0x2c,0x91,0x9a,0xa5,0x1c,0x1d,0x14,0x38,0x91,0x87,0x89,0xaa,0x3d,0x5f,0x1e,0x30,0x90,0x96,0x99,0x2f,0x42,0x0f,0x0f,0x25,0xb9,0xac +,0x1a,0x0b,0x06,0x0c,0x13,0x8e,0x86,0x89,0x99,0x9d,0x35,0x18,0x24,0xae,0x99,0xc4,0x47,0x20,0x2f,0x17,0x94,0x89,0x8a,0x9b,0x37,0x19,0x0b,0x20,0xa3,0x8e,0xdb,0x1d +,0x0e,0x1d,0x0f,0xbb,0x99,0xa4,0xa7,0x2f,0x45,0x12,0x35,0xa6,0x93,0xad,0x1b,0x0c,0x17,0x0f,0xc5,0x87,0x88,0x88,0x9f,0xa2,0x1b,0x2c,0xa5,0x91,0x9e,0x1d,0x0b,0x16 +,0x12,0x1f,0x95,0xa2,0x9c,0x19,0x16,0x08,0x0d,0xbd,0x93,0x8d,0xa2,0x38,0x38,0x31,0x39,0x8a,0x8f,0x96,0x2c,0x24,0x1d,0x18,0xb8,0x99,0x90,0xb6,0x19,0x12,0x0d,0x0d +,0x9a,0x8e,0x91,0xde,0x24,0x2f,0x1c,0xc8,0xad,0x9e,0xbe,0x18,0x13,0x1c,0x1e,0x8f,0x88,0x90,0xd9,0x1b,0x1d,0x08,0x1d,0xb6,0x8e,0x95,0x4d,0x3d,0xb0,0xb5,0x99,0x8a +,0x9c,0x5d,0x1e,0x27,0x0f,0x0e,0x23,0xad,0xb1,0x2b,0x13,0x11,0x0f,0x27,0x8e,0x8f,0x94,0xaa,0x9e,0x72,0x40,0xa3,0x92,0x9d,0x23,0x17,0x1e,0x1f,0x1a,0x99,0x98,0xa4 +,0xc3,0x3f,0x18,0x0c,0x1e,0xa4,0x96,0xb7,0x2c,0x24,0x3e,0x28,0x92,0x8d,0x9d,0xd5,0x3f,0x42,0x14,0x2f,0xa1,0x90,0xaa,0x39,0x14,0x0f,0x05,0x1b,0x9b,0x9e,0xad,0x2f +,0xc0,0x23,0xaa,0x8f,0x89,0x97,0x5b,0x24,0x26,0x0f,0x37,0x98,0xa8,0xad,0x27,0x58,0x0e,0x13,0x2b,0x97,0x95,0xa4,0x7c,0x47,0x1f,0x3d,0x8b,0x95,0xac,0x11,0x1c,0x0b +,0x0d,0x2f,0x9b,0x97,0xac,0x39,0x22,0x17,0x17,0x95,0x8f,0x92,0x66,0xd9,0x1e,0x29,0x96,0x88,0x87,0xad,0x18,0x14,0x16,0x15,0x9c,0xa9,0xa9,0x2c,0x2d,0x17,0x04,0x10 +,0x3a,0x97,0xb4,0x2a,0x1d,0x1e,0x21,0x90,0x84,0x85,0x97,0xbd,0x35,0x0f,0x2f,0xa4,0x96,0xaa,0x2f,0x1c,0x1c,0x0d,0x24,0x9d,0x98,0xa3,0x4f,0x2c,0x10,0x37,0x95,0x87 +,0x97,0x2c,0x0f,0x0f,0x0a,0x1f,0x9e,0xa7,0xb4,0x37,0xa8,0x1d,0x1e,0xbd,0x8f,0x8e,0xa2,0x2b,0x14,0x0e,0x1f,0x89,0x84,0x8b,0xd1,0x2c,0x0e,0x12,0xec,0x99,0x99,0x36 +,0x19,0x0e,0x0d,0x0c,0xa5,0xa0,0xaa,0xc6,0xc2,0x22,0x0c,0x71,0x8b,0x81,0x8c,0xb6,0x1c,0x15,0x0f,0xa7,0x9e,0xbf,0x4a,0xb6,0x2f,0x0a,0x12,0xec,0x96,0x9b,0xaa,0x27 +,0x14,0x09,0xa8,0x87,0x87,0x8f,0xba,0x22,0x05,0x15,0xa8,0x8f,0xcb,0x1e,0x1c,0x2f,0x1a,0x40,0x9c,0x9d,0x91,0x9d,0xae,0x06,0x09,0xcf,0x8d,0x8a,0x9c,0x4c,0x1a,0x0b +,0x19,0x8f,0x8f,0x9c,0xd6,0xb4,0x11,0x0a,0x1e,0xb0,0x96,0x9e,0x67,0x16,0x07,0x09,0x95,0x85,0x83,0x93,0x9e,0x1a,0x0d,0x4d,0x9f,0x99,0x2a,0x23,0x1c,0x0f,0x0b,0x65 +,0x9f,0x9b,0x9d,0x91,0xed,0x05,0x0a,0x6a,0x86,0x89,0x92,0x3a,0x15,0x0b,0xec,0x8f,0x9f,0xb8,0xb8,0x76,0x07,0x0d,0x38,0x8f,0x8e,0x9c,0x57,0x13,0x04,0x10,0x9b,0x8f +,0x8f,0x98,0x98,0x0d,0x0c,0x3c,0x92,0x96,0xba,0xc1,0x2e,0x0f,0x0f,0xbe,0xb0,0x96,0x95,0x91,0x0f,0x00,0x0d,0x9f,0x87,0x89,0x8f,0x54,0x14,0x0b,0xa4,0x92,0x9c,0xbb +,0xe1,0x18,0x04,0x10,0x47,0x95,0x91,0x94,0x9e,0x1d,0x05,0x1e,0x9c,0x96,0x8f,0x8f,0xa4,0x07,0x09,0x39,0x9d,0x93,0x96,0xce,0x22,0x08,0x16,0x9d,0x97,0x8c,0x91,0x9a +,0x08,0x01,0x0e,0xac,0x89,0x8c,0x95,0x32,0x0c,0x14,0x91,0x96,0xa1,0xaa,0x96,0x1b,0x04,0x13,0x2e,0xa3,0x9d,0x96,0xc9,0x11,0x06,0x30,0xaa,0x99,0x8c,0x86,0xa4,0x08 +,0x19,0xcf,0x94,0x9e,0x9f,0x5a,0x14,0x04,0x12,0xa8,0xaa,0x94,0x8b,0x95,0x0a,0x07,0x2d,0x9a,0x94,0x8f,0x98,0x2c,0x0a,0x10,0xab,0xbc,0x9e,0x97,0x8f,0x11,0x05,0x12 +,0x38,0x95,0x8f,0x8a,0xaf,0x0d,0x01,0x28,0xa7,0x94,0x8b,0x89,0x5b,0x05,0x0e,0x4e,0x96,0x90,0x8c,0xc9,0x0e,0x02,0x1b,0xaf,0xa7,0x92,0x8a,0xa3,0x04,0x0a,0x28,0x9c +,0x8e,0x8a,0x9a,0x29,0x0a,0x17,0x9b,0xaa,0x9b,0x98,0x97,0x0c,0x03,0x16,0xb6,0x98,0x95,0x96,0x2b,0x0b,0x0b,0xa8,0xa9,0x95,0x89,0x86,0x2c,0x03,0x10,0x4a,0x9e,0x9e +,0x94,0xc1,0x19,0x05,0x2b,0xbf,0xb7,0x8d,0x87,0x9a,0x05,0x0c,0x19,0xde,0xa3,0x8d,0x92,0x37,0x08,0x1b,0xab,0x3e,0x94,0x89,0x89,0x0c,0x04,0x0e,0x1f,0xdf,0x94,0x8c +,0x53,0x0b,0x0a,0xa2,0xc7,0x94,0x88,0x83,0x3b,0x03,0x10,0x32,0x9f,0x9a,0x8e,0x4f,0x0c,0x00,0x37,0x4e,0xaf,0x8b,0x84,0x93,0x06,0x09,0x17,0xa7,0x97,0x8a,0x96,0x21 +,0x05,0x1d,0xae,0xd8,0x8f,0x88,0x8c,0x08,0x04,0x0f,0x5b,0xa1,0x8e,0x8e,0x49,0x0b,0x09,0xb8,0x2c,0x9b,0x89,0x84,0x28,0x04,0x14,0x48,0xa7,0x9d,0x8f,0xce,0x10,0x07 +,0xaf,0x4c,0x4b,0x99,0x89,0x9b,0x07,0x10,0x20,0xb9,0x9e,0x87,0x8d,0x39,0x08,0x24,0xbd,0x24,0xa4,0x8d,0x8d,0x0a,0x07,0x11,0x46,0xa9,0x8f,0x8c,0x4f,0x0b,0x10,0x9d +,0x3a,0x97,0x87,0x85,0x1f,0x03,0x11,0x28,0xa9,0x98,0x8d,0x52,0x0b,0x06,0xb5,0x31,0x3b,0x90,0x85,0xa1,0x03,0x0d,0x16,0xd3,0x98,0x84,0x8e,0x1f,0x05,0x2a,0xa7,0x39 +,0x91,0x86,0x8b,0x0b,0x0a,0x16,0x2c,0x4e,0x9a,0x93,0x27,0x08,0x11,0xa4,0x1c,0xa6,0x89,0x82,0x2d,0x09,0x1c,0x28,0x60,0xa6,0x8c,0xb9,0x0e,0x0b,0x9a,0x41,0x36,0x91 +,0x83,0x9e,0x07,0x16,0x1d,0xd0,0xb2,0x8b,0x99,0x14,0x01,0x23,0x5f,0x1c,0x99,0x84,0x8d,0x09,0x0e,0x22,0xdc,0xd0,0x90,0x89,0xf3,0x08,0x16,0x9c,0x28,0x9d,0x87,0x81 +,0x1e,0x05,0x0f,0x1b,0x2a,0xb0,0x8b,0xb2,0x0b,0x08,0xaf,0x27,0x27,0x97,0x82,0xae,0x0a,0x1e,0x3d,0xae,0xad,0x87,0x8f,0x1c,0x08,0xac,0xa8,0x20,0xa6,0x86,0x91,0x08 +,0x0e,0x21,0x68,0x1f,0xab,0x97,0x22,0x07,0x22,0x9c,0x22,0xb4,0x89,0x84,0x17,0x0a,0x19,0x71,0x6d,0xa1,0x89,0x9f,0x0e,0x11,0x98,0x4e,0x3c,0x98,0x83,0x3e,0x07,0x11 +,0x2c,0x46,0x40,0x8e,0x99,0x16,0x08,0xcf,0x42,0x2c,0x9d,0x83,0x95,0x0c,0x10,0x22,0x3f,0x25,0x99,0x90,0x3d,0x0c,0xf6,0xa3,0x41,0xa3,0x87,0x89,0x12,0x0d,0x16,0x40 +,0x1d,0xc4,0x96,0x57,0x0b,0x26,0x9d,0x24,0x34,0x96,0x85,0x2f,0x11,0x1a,0xcb,0x64,0xaf,0x8d,0x9b,0x13,0x13,0xa6,0x45,0x5a,0x9e,0x84,0xbb,0x0c,0x0f,0x2f,0x5c,0x3b +,0x9b,0xa7,0x18,0x0c,0xb6,0x6f,0xda,0x9c,0x83,0x97,0x0e,0x0d,0x21,0xb1,0x4b,0x9a,0x99,0x34,0x0d,0xb6,0xb6,0x2f,0x3c,0x91,0x8f,0x19,0x11,0x19,0xba,0x2b,0xac,0x94 +,0xa6,0x15,0x3e,0xc5,0x1f,0x35,0x95,0x87,0x2b,0x18,0x17,0x43,0x28,0x45,0x98,0xa3,0x18,0x1c,0xa9,0x50,0xbc,0x97,0x85,0x55,0x0e,0x0f,0x2f,0x3d,0x34,0x9b,0x9c,0x20 +,0x19,0xa8,0x5f,0xd2,0xb6,0x8c,0xb4,0x13,0x19,0x33,0xb2,0x3d,0x9d,0x9a,0x2f,0x18,0xaf,0xdb,0x3d,0x55,0x8d,0x97,0x1b,0x16,0x1c,0x6b,0x21,0x56,0xa6,0x3b,0x13,0xc9 +,0xb3,0xec,0xb3,0x8c,0x8c,0x2a,0x1e,0x1c,0xec,0x2f,0x4f,0xa9,0xc1,0x1c,0xc6,0xae,0x2b,0x2d,0xa9,0x8d,0x36,0x1b,0x18,0x2e,0x35,0x4f,0x99,0x9f,0x23,0x61,0xb0,0x2d +,0x46,0x9e,0x88,0xc3,0x1e,0x1c,0x32,0x40,0x38,0xae,0xbe,0x1a,0x25,0xa5,0x44,0x45,0xaa,0x89,0xa1,0x23,0x21,0x2b,0x3c,0x28,0x52,0xb4,0x23,0x1d,0x9e,0x4e,0x35,0x4e +,0x92,0xa9,0x1c,0x2a,0x37,0xcc,0x2f,0xb2,0x9f,0xe1,0x26,0x9a,0xe0,0x28,0x2a,0x98,0x95,0x20,0x26,0x2d,0xc0,0x26,0x3b,0xc3,0x3d,0x19,0xa5,0xa5,0x3a,0x3b,0x9a,0x8f +,0x2c,0x2e,0x32,0x4b,0x1e,0x2b,0xbb,0xa9,0x25,0xa4,0x98,0x37,0x2c,0xb6,0x8f,0x2b,0x1c,0x1c,0x32,0x2e,0x3a,0xa8,0xa5,0x2a,0xbe,0x92,0xde,0x2c,0x2f,0x96,0x4a,0x28 +,0x35,0xdd,0x2a,0x1a,0x2e,0xeb,0x2b,0x3b,0x94,0x6e,0x3b,0x4b,0x8d,0x9b,0x47,0x3c,0x43,0x57,0x1d,0x26,0x40,0x56,0x38,0x90,0xaf,0x2c,0x28,0x9b,0x9e,0x1f,0x28,0x27 +,0x38,0x21,0x53,0xae,0xb1,0x2c,0x9a,0xa9,0x57,0x45,0xa8,0x9e,0x1b,0x2f,0x50,0xad,0x25,0x24,0x3f,0xdd,0x27,0xa5,0x9d,0x36,0x36,0xab,0x8d,0x47,0x2d,0x30,0x51,0x1d +,0x19,0x36,0xb9,0x22,0xbf,0x94,0xbe,0xf3,0x4b,0x94,0x2c,0x1d,0x23,0xdb,0x56,0x2b,0xb5,0xa9,0x43,0x5e,0x8e,0xaa,0x46,0x1a,0xa6,0xcb,0x25,0x36,0xbf,0xb5,0x24,0x5a +,0x65,0x2e,0x22,0x98,0xb5,0x3f,0x29,0x9d,0x9f,0x1f,0x32,0x77,0xa7,0x21,0x2a,0x3d,0x3e,0x29,0x92,0x93,0xc0,0x34,0xad,0x9f,0x17,0x16,0x1f,0xb2,0x31,0x2f,0x57,0xcb +,0x34,0x95,0x8f,0xc6,0x27,0x2b,0xa5,0x1f,0x2a,0x42,0xa9,0x37,0x24,0xe7,0xb5,0x2a,0x6c,0x9b,0x77,0x46,0xc9,0x8e,0xdf,0x22,0x34,0xa7,0xb7,0x1b,0x24,0x26,0x20,0x53 +,0x8e,0x9f,0xc6,0x3b,0xa4,0xf6,0x19,0x28,0xcf,0xaf,0x25,0x25,0x7a,0x37,0x49,0x8d,0x99,0xd2,0x1c,0xbc,0xb4,0x19,0x27,0x55,0x9d,0x61,0x33,0x4d,0x2d,0x1a,0xa9,0xa0 +,0xba,0x4e,0xa1,0x96,0x1f,0x24,0x4c,0xa4,0x44,0x18,0x21,0x23,0x1d,0x98,0x90,0xa0,0x36,0xb6,0x92,0x28,0x17,0x1a,0xa6,0x5b,0x21,0x2e,0xb5,0x3f,0xa5,0x8b,0xab,0x2d +,0x18,0xa1,0x37,0x1a,0x28,0xc0,0x9f,0x39,0xd1,0xb1,0x23,0x21,0x9c,0xa6,0x69,0x2b,0x9b,0xaf,0x19,0x23,0xaf,0x9b,0x22,0x14,0x23,0x2f,0x3e,0x8e,0x97,0xa8,0x2f,0xa1 +,0x98,0x18,0x12,0x15,0xc3,0x29,0x2c,0xba,0xba,0x38,0x9b,0x8f,0xa8,0x2d,0xc6,0x95,0x20,0x13,0x1b,0xb5,0xb6,0x3a,0xb9,0xb9,0x1b,0x32,0x9e,0xac,0xc6,0xdb,0x97,0x3b +,0x1f,0x2e,0x9f,0xa3,0x16,0x17,0x2f,0x22,0x3e,0x92,0x9e,0xaf,0xd3,0x8d,0x9f,0x16,0x0e,0x21,0xad,0x2d,0x39,0xd3,0x30,0x21,0x98,0x96,0xa9,0x20,0xb4,0xad,0x15,0x15 +,0x2c,0x97,0xaf,0xc3,0xbd,0x55,0x15,0xc5,0x9a,0xa4,0x4c,0xbc,0x97,0x26,0x1f,0x2e,0x98,0xb1,0x19,0x1f,0x32,0x1e,0xf6,0x99,0xab,0xb1,0xa7,0x8c,0xcf,0x0f,0x0c,0x2a +,0xad,0x3a,0x30,0x3f,0x26,0xbc,0x8c,0x8f,0xa6,0x1d,0xbf,0x2b,0x16,0x1d,0xca,0xa1,0x42,0x3d,0xbb,0xd4,0x2a,0x9e,0xa6,0xbc,0x20,0xb0,0xac,0x1c,0x1e,0x40,0x9b,0x33 +,0x1b,0x29,0xce,0x3f,0x9b,0x9c,0xa5,0xb7,0x9d,0x8f,0x21,0x0e,0x0c,0x39,0xd4,0x47,0x4e,0x41,0x2b,0x9d,0x8a,0x90,0xb8,0x23,0xac,0x1f,0x14,0x0f,0x39,0xb9,0x33,0xac +,0x9f,0x3c,0x2a,0xa2,0xc6,0xc3,0x3e,0x93,0xa9,0x1e,0x1a,0x35,0x9d,0x33,0x2a,0x27,0x24,0x1f,0xa8,0xa8,0xa5,0xca,0x91,0x91,0x1c,0x0d,0x0f,0xa2,0xb2,0x4e,0x2c,0x2f +,0x26,0x96,0x8c,0xa6,0x39,0x48,0x9c,0x23,0x15,0x13,0x4f,0xb1,0xad,0x9e,0x96,0x39,0x25,0xac,0x2e,0x55,0x29,0x98,0x44,0x13,0x1a,0xb8,0x93,0xc6,0xdc,0xcd,0x27,0x16 +,0xa8,0xbe,0xad,0xbe,0x99,0x9f,0x19,0x12,0x2d,0x98,0x55,0x34,0x30,0x1f,0x23,0xaa,0xa1,0xbb,0xbe,0x9a,0x87,0x57,0x0f,0x0d,0x36,0x9a,0xa7,0xa6,0x1d,0x57,0x0f,0x0b +,0x14,0x0a,0xa8,0xa4,0xce,0x0e,0x04,0x9d,0x96,0x9a,0x8f,0x8c,0xb2,0xa0,0x82,0xaf,0x9f,0x8e,0xaf,0x96,0x10,0x04,0x8e,0x86,0x9f,0xa5,0x93,0x27,0x12,0x15,0x15,0x0f +,0x04,0x0d,0x1b,0x05,0x02,0x02,0x10,0x2d,0x09,0x09,0x11,0x0e,0xd7,0x8b,0xa1,0xba,0xa8,0x88,0x9d,0x1a,0x1e,0xaf,0x8e,0x8d,0x8c,0x8a,0x9c,0x94,0x81,0x80,0x80,0x8a +,0x81,0x8b,0x89,0x1d,0x0f,0xa4,0x8f,0x8e,0x0d,0x2f,0x02,0x0d,0xbd,0x0b,0x11,0x2e,0x12,0x03,0x0e,0x0a,0x35,0x07,0x0a,0x10,0x01,0x03,0x0f,0xaf,0x15,0x1b,0xa0,0x8e +,0x0c,0x07,0x0e,0x96,0x80,0x87,0x89,0xa5,0x26,0xa3,0x80,0x84,0x82,0xcc,0x84,0x8b,0x8f,0x8b,0xa1,0x8f,0x98,0x8d,0x95,0x9f,0x11,0x2d,0x19,0x4f,0x29,0x48,0x22,0x00 +,0x03,0x05,0x23,0x12,0x0a,0x02,0x09,0x00,0x0d,0x3c,0x0f,0x0a,0x2b,0x86,0x16,0x0b,0x09,0xa5,0x83,0x86,0x83,0x8f,0x18,0x12,0x86,0x86,0x8e,0xd6,0x85,0x8f,0x12,0xab +,0x8a,0x99,0x8d,0x83,0x80,0x90,0x1e,0x29,0xb3,0x86,0xc8,0x96,0xae,0x00,0x04,0x00,0x9c,0x72,0x09,0x07,0x06,0x01,0x0f,0x93,0x23,0x49,0xa3,0x9e,0x02,0x01,0x00,0x1f +,0x8c,0x8e,0x94,0x24,0x21,0x05,0x98,0x80,0x84,0x82,0x88,0x8c,0x2a,0x2b,0x9f,0x87,0x83,0x87,0x8e,0x3a,0x0a,0x3e,0x89,0x8b,0x8e,0x9a,0x8e,0x17,0x13,0x37,0xa0,0xa5 +,0x1f,0x95,0xd9,0x08,0x0c,0x01,0x34,0x88,0xa7,0x4c,0x03,0x00,0x04,0x9d,0x9b,0x99,0x1b,0x00,0x06,0x00,0x2e,0x0d,0x9e,0x4e,0x22,0xe2,0x02,0x00,0x04,0x8b,0x8a,0xbe +,0x04,0x15,0x8e,0x34,0x87,0x70,0x3a,0x8c,0x80,0x86,0x22,0x1f,0xb4,0x89,0x87,0x80,0x9d,0x0f,0x07,0x9f,0xa7,0xae,0x24,0x9d,0xbe,0x03,0x13,0x0b,0xac,0xa5,0x86,0x80 +,0x34,0x00,0x24,0xc2,0x92,0x82,0x87,0x8e,0x05,0x01,0x20,0x88,0x80,0x8c,0x99,0x2b,0x0b,0x0c,0x8b,0x82,0x91,0x93,0x86,0x8d,0x07,0x04,0x1b,0x80,0x9a,0x39,0x0c,0x0d +,0x1f,0x09,0xa7,0x89,0x9d,0x0d,0xa6,0x0c,0x01,0x05,0x2e,0x9e,0x15,0x9a,0x1c,0x00,0x01,0x02,0x1c,0x3e,0x8f,0xb8,0x00,0x04,0x00,0xc5,0x8c,0x8b,0x1f,0x1a,0x0f,0x00 +,0x89,0x87,0x81,0x8d,0x85,0x8a,0x1d,0x17,0xa5,0x80,0x80,0x88,0x91,0x88,0x88,0x87,0x81,0x80,0x80,0x81,0x81,0x10,0x0e,0x8c,0x81,0x8e,0x9a,0x52,0x0c,0x05,0x00,0x09 +,0x0c,0xb6,0x0c,0x08,0x03,0x00,0x00,0x0e,0xa2,0x0b,0x06,0x07,0x09,0x00,0x04,0x24,0x93,0xe5,0xa4,0x0d,0x00,0x00,0x1e,0x81,0x82,0x88,0x0d,0x09,0x01,0x9a,0x80,0x88 +,0x82,0x9e,0x80,0x90,0x1f,0xcf,0x8f,0x80,0x86,0x80,0x8e,0x12,0x0e,0xa6,0x80,0x81,0x85,0x9b,0x17,0x04,0x09,0x18,0x9e,0x88,0x39,0x0d,0x09,0x02,0x07,0x0d,0x1c,0xab +,0x9a,0x22,0x00,0x00,0x0e,0x96,0x84,0x94,0x9c,0x0e,0x11,0xb5,0x94,0x80,0x91,0x86,0x8a,0xa4,0x14,0x0f,0x99,0x84,0x87,0x92,0x13,0x11,0x0b,0x0f,0xb2,0x89,0x8a,0x18 +,0x03,0x00,0x09,0x0a,0x3c,0x94,0x93,0x0b,0x06,0x01,0x10,0x15,0x3b,0x8d,0x96,0xad,0x05,0x01,0x06,0x89,0x80,0x85,0x89,0x95,0xc4,0x1f,0x89,0x80,0x81,0x80,0x80,0x8b +,0x09,0x1b,0x87,0x85,0x84,0x8b,0xce,0x0a,0x01,0x0f,0xa7,0x8f,0x9b,0x29,0x12,0x01,0x01,0x0f,0x9d,0x80,0x8c,0xc7,0x0c,0x03,0x00,0x18,0x97,0xa8,0xb0,0x13,0x05,0x01 +,0x00,0x2d,0x8e,0x42,0x17,0x06,0x04,0x00,0x18,0xda,0x9a,0x8e,0x3f,0xcd,0x09,0x04,0x1f,0x83,0x86,0x85,0x88,0x1b,0x26,0x91,0x84,0x80,0x82,0x8b,0x89,0xcb,0x1a,0xa8 +,0x80,0x80,0x85,0x89,0x23,0x1d,0x18,0x99,0xaa,0xa1,0x90,0x9d,0x28,0x00,0x07,0x1c,0x88,0x88,0xa9,0x0f,0x04,0x04,0x23,0x84,0x89,0xba,0xb3,0xa9,0x03,0x00,0x14,0xb0 +,0x8e,0x18,0x13,0x06,0x02,0x00,0x23,0x9c,0xb5,0x1a,0x09,0x08,0x00,0x0b,0x10,0x89,0x93,0x28,0x0a,0x07,0x00,0xcf,0x8a,0x91,0x83,0x8d,0x97,0x11,0x62,0x88,0x81,0x80 +,0x81,0x87,0x95,0x9d,0x88,0x80,0x82,0x80,0x83,0x87,0x48,0x0e,0x13,0xa1,0x83,0x9e,0x12,0x00,0x04,0x00,0x16,0x1b,0x12,0x1c,0x0b,0x04,0x00,0x03,0x0f,0x90,0x97,0x13 +,0x07,0x06,0x01,0x1c,0x4b,0x7c,0xa6,0x26,0x3d,0x02,0x0a,0x54,0x98,0x80,0x8a,0x94,0x1a,0x0d,0xca,0x8f,0x83,0x83,0x8f,0x96,0xca,0x08,0x1a,0x89,0x81,0x80,0xb5,0xc1 +,0x31,0x10,0x90,0x85,0x81,0x91,0xae,0x2a,0x0a,0x05,0x32,0x8b,0x8a,0x9d,0x09,0x07,0x05,0x09,0xbb,0x93,0x9d,0x26,0x25,0x0c,0x03,0x0e,0x89,0x84,0x88,0x1f,0x0e,0x24 +,0x1e,0x91,0x8b,0x82,0x8c,0x94,0x19,0x06,0x0d,0xa4,0x83,0x86,0xd9,0x0c,0x02,0x0d,0x47,0xdf,0x90,0x36,0x20,0x0e,0x00,0x02,0x04,0xc1,0x88,0xa4,0x05,0x07,0x00,0x06 +,0xc0,0xa1,0x99,0xe1,0x94,0x28,0x0b,0xaf,0x87,0x80,0x82,0x86,0xa8,0xb3,0x95,0x80,0x81,0x80,0x82,0x82,0x8a,0x0d,0x42,0x91,0x86,0x85,0xbd,0x25,0x0d,0x02,0x2b,0xc9 +,0xa3,0xb7,0x1d,0x29,0x04,0x00,0x0a,0x92,0x8f,0xb0,0x0f,0x08,0x04,0x01,0xfd,0x21,0x2b,0x24,0x0d,0x05,0x00,0x08,0x1c,0x8f,0xca,0x06,0x05,0x0a,0x00,0x1d,0x92,0x90 +,0x86,0x96,0x9d,0x18,0x54,0x90,0x84,0x80,0x87,0x8f,0xa7,0xaf,0x94,0x87,0x83,0x82,0x8e,0x98,0x0e,0x08,0x9f,0x85,0x87,0x87,0x4e,0x18,0x09,0x0d,0x9f,0x30,0xa8,0x4e +,0x51,0x15,0x00,0x09,0xa6,0x89,0x87,0xc5,0x0d,0x18,0x06,0x46,0x8c,0x88,0x8d,0x9e,0x65,0x09,0x03,0x0d,0x8c,0x94,0x35,0x0c,0x04,0x00,0x08,0x38,0x4a,0x9a,0x28,0x09 +,0x02,0x00,0x07,0xe5,0x8d,0x95,0x10,0x0b,0x01,0x0b,0xaf,0x95,0x93,0x95,0x88,0x28,0x18,0x9d,0x89,0x80,0x81,0x81,0x8a,0x9b,0x8e,0x87,0x80,0x80,0x80,0x81,0x8c,0x38 +,0x0e,0x3f,0x8e,0x99,0x2b,0x07,0x06,0x00,0x10,0x16,0x1a,0x3b,0x06,0x12,0x00,0x02,0x02,0xd8,0x9a,0xa6,0x0f,0x06,0x09,0x07,0x1a,0x28,0x36,0x18,0xaf,0x08,0x02,0x08 +,0xa9,0x81,0x86,0xa7,0x1d,0x12,0x13,0x91,0x8c,0x89,0x8f,0x8d,0x97,0x1b,0x10,0x37,0x80,0x85,0x8e,0xa0,0x14,0x2b,0x96,0x91,0x86,0x89,0xa6,0x97,0x17,0x0c,0x25,0x8c +,0x87,0x86,0x4f,0x10,0x27,0x27,0xb3,0xa1,0xbe,0xb9,0x98,0x02,0x06,0x0c,0xe5,0x85,0x8a,0x38,0x26,0x08,0x09,0x94,0x5a,0x9e,0x9a,0x93,0x18,0x0a,0x09,0x32,0x86,0x97 +,0xcf,0x11,0x02,0x0d,0xbf,0xd7,0x8b,0xa2,0xa9,0x23,0x00,0x02,0x0a,0x49,0xad,0x2d,0x08,0x05,0x05,0x17,0x3d,0xb1,0x29,0x94,0x6c,0x02,0x0d,0x1b,0x84,0x80,0x80,0x82 +,0x89,0x9a,0x87,0x82,0x86,0x80,0x82,0x80,0x8e,0xaf,0x3e,0x83,0x84,0x90,0xa6,0x0b,0x01,0x11,0x0c,0x13,0x51,0x11,0xa8,0x0a,0x00,0x03,0x09,0x1e,0xb8,0x15,0x04,0x0b +,0x0f,0x37,0x37,0x1e,0x29,0x92,0x0a,0x02,0x08,0x0c,0x8e,0x8c,0x44,0xae,0x0d,0x06,0x99,0x3a,0x2a,0xab,0x97,0x5f,0x1d,0x07,0x26,0x80,0x8b,0x89,0x88,0x19,0xa6,0x89 +,0xad,0x81,0x8f,0x8c,0x81,0x25,0x0e,0x2e,0xc9,0x8e,0x86,0xc9,0x1e,0x1c,0x25,0xac,0x94,0x37,0x8e,0x8d,0x09,0x15,0x04,0x0d,0x8e,0xcb,0xd6,0x94,0x0a,0x23,0x94,0x27 +,0xab,0x9c,0xc6,0x2b,0x16,0x06,0xa4,0x89,0xc0,0x98,0x21,0x02,0x2f,0x13,0x0e,0xcf,0x06,0x44,0x3c,0x00,0x0d,0x0c,0x10,0x9f,0x22,0x05,0x0c,0x05,0x0f,0xa3,0x9d,0x27 +,0x8f,0x4e,0x13,0x3a,0x0e,0x98,0x82,0x8e,0x83,0x84,0x94,0x83,0x84,0x85,0x80,0x84,0x83,0x81,0xa3,0x9f,0x85,0x88,0x86,0x88,0x3b,0x20,0x1b,0x01,0x1e,0x14,0x08,0x25 +,0x24,0x08,0x08,0x01,0x06,0xaf,0x15,0x0f,0x18,0x02,0x04,0x11,0x12,0x7b,0x38,0x06,0x23,0x13,0x03,0x1e,0x1c,0x34,0x8e,0xbe,0x2e,0xa3,0x19,0x39,0x8b,0x9f,0x8d,0x95 +,0x1d,0x9a,0x94,0x9b,0x87,0x87,0x9a,0x8c,0xae,0x33,0x97,0xcf,0x9f,0x8a,0xa1,0xae,0x9a,0x1f,0xc8,0x9b,0xb2,0x8e,0xa7,0x0d,0x22,0x43,0x23,0x98,0xab,0x2d,0xaa,0x17 +,0x18,0xad,0x12,0x3a,0x94,0xaa,0xa5,0x2f,0x10,0x36,0xba,0x28,0x9a,0xcd,0x13,0x2a,0x1c,0x33,0x99,0x61,0x1e,0xeb,0x0f,0x18,0x27,0x0c,0x1f,0x5a,0x2c,0xa8,0xc3,0x18 +,0xb0,0xa7,0x9f,0x94,0xc0,0x1e,0xa3,0xd0,0xab,0x8d,0x5a,0xba,0xec,0x2d,0xbe,0xbc,0x1e,0x9d,0x9d,0x34,0xab,0x23,0x1a,0x3a,0x33,0x4c,0xa7,0x18,0x0e,0x22,0x1a,0xc0 +,0x98,0xbf,0xb0,0xea,0x17,0x33,0x2f,0x34,0x9d,0x9b,0xa1,0x94,0x33,0x1d,0xa3,0xae,0x8f,0x8e,0xab,0x4c,0x23,0x1c,0xce,0x9c,0xac,0xb8,0x3d,0x18,0x2f,0x1f,0x1b,0x9c +,0xa3,0x9c,0x99,0x31,0x29,0x3a,0xc7,0x98,0x95,0x47,0x46,0xb9,0x43,0xa5,0x9f,0x9e,0x9e,0x65,0x2d,0xbf,0x39,0x23,0xdd,0x2b,0x2f,0x3b,0x0e,0x10,0x16,0x15,0x39,0x1d +,0x0f,0x15,0x13,0x14,0x37,0x59,0x28,0x2f,0x19,0x24,0xcd,0x2d,0xab,0x97,0xa2,0x9e,0x9b,0xa1,0x99,0x99,0x91,0x89,0x94,0xbf,0xc7,0xcc,0xb1,0x96,0xa3,0xa1,0xa5,0x36 +,0x29,0x43,0x28,0xb3,0x9a,0xb4,0xae,0x66,0x2a,0x69,0xa9,0x9d,0x96,0xb0,0x35,0xd9,0x27,0x2a,0x99,0x97,0x90,0x93,0xca,0xcb,0x4e,0x2c,0xc0,0xb2,0x40,0x2c,0x22,0x14 +,0x16,0x0e,0x0f,0x29,0x15,0x12,0x11,0x0d,0x14,0x1e,0x1d,0x54,0x76,0x1f,0x1b,0x1b,0x15,0x25,0x52,0x49,0xaf,0x66,0xc8,0x9c,0x95,0x94,0x8c,0x97,0x9b,0x93,0x9e,0x97 +,0x8b,0x8a,0x8c,0x94,0xa6,0xa4,0xac,0x30,0x2a,0xbf,0x2c,0x15,0x08,0x0a,0x16,0x0a,0x09,0x0f,0x0f,0x0a,0x04,0x09,0x29,0x3d,0x2c,0x3e,0xfc,0x69,0x42,0x1f,0x28,0xa7 +,0xa6,0xab,0x6d,0x22,0x2f,0xbf,0xb7,0x96,0x9b,0xde,0xa9,0xad,0xa5,0x92,0x93,0x92,0x8a,0x8c,0x8f,0x94,0x9f,0x9a,0x8b,0x90,0x9c,0xaa,0x22,0x2e,0xad,0x9d,0x92,0xa3 +,0xc9,0x9e,0x9e,0x99,0x8e,0x91,0x8e,0x8e,0x93,0x8e,0x9b,0x1d,0x25,0xa0,0xac,0x1c,0x06,0x04,0x11,0x0e,0x09,0x0f,0x07,0x05,0x0b,0x0e,0x15,0x14,0x0f,0x17,0x30,0x34 +,0x26,0x1e,0x10,0x22,0xb6,0xbc,0x32,0x0c,0x09,0x19,0x65,0xa9,0xbf,0x1e,0x1d,0x29,0x44,0xb6,0xba,0x4f,0xac,0x99,0x9e,0xa8,0x44,0xd6,0x97,0x8f,0x93,0xa7,0x29,0x2d +,0x9f,0x98,0x99,0xa3,0xae,0x98,0x93,0x98,0x8d,0x8a,0x8b,0x8a,0x88,0x84,0x83,0x96,0xb2,0x8d,0x88,0x92,0x56,0x1a,0x28,0x22,0x11,0x25,0x35,0x13,0x0e,0x0f,0x18,0x24 +,0x16,0x14,0x27,0x26,0x1d,0x16,0x0f,0x0f,0x1e,0x34,0x39,0x1a,0x06,0x07,0x0d,0x0f,0x1e,0x1c,0x0f,0x0d,0x0b,0x16,0x2c,0x1f,0x22,0x4d,0x66,0x46,0x30,0x25,0x4b,0xa9 +,0x9f,0x9a,0xb0,0x39,0xcc,0x9f,0x96,0x91,0x93,0x8e,0x8b,0x8e,0x86,0x84,0x86,0x88,0x87,0x83,0x81,0x8b,0x96,0x8c,0x87,0x8e,0xa4,0xcd,0x3d,0x2f,0x13,0x19,0x2c,0x16 +,0x11,0x10,0x0f,0x13,0x17,0x14,0x23,0x2d,0x29,0x24,0x1a,0x19,0x17,0x19,0x24,0x2b,0x16,0x0e,0x0d,0x0e,0x19,0x27,0x25,0x26,0x1a,0x14,0x18,0x11,0x1c,0xdb,0xb0,0xcf +,0x27,0x24,0x34,0xc1,0x9f,0x95,0x93,0xb1,0x2e,0x32,0xee,0xa2,0x98,0x8c,0x8d,0x9c,0x98,0x89,0x83,0x84,0x85,0x83,0x82,0x88,0x90,0x8b,0x88,0x8d,0xa1,0x60,0x40,0x1d +,0x0d,0x11,0x1b,0x17,0x15,0x0f,0x10,0x14,0x13,0x15,0x23,0x2a,0x27,0x21,0x16,0x17,0x20,0x1f,0x25,0x2e,0x1e,0x15,0x14,0x12,0x13,0x13,0x14,0x18,0x0f,0x10,0x14,0x18 +,0x15,0x1e,0x29,0x29,0x2b,0x2d,0x3b,0x2d,0x26,0x3c,0xb4,0xc6,0x54,0x34,0x39,0x39,0xb6,0x96,0x8f,0x8f,0x91,0x8a,0x85,0x8a,0x88,0x85,0x83,0x86,0x8f,0x8f,0x88,0x89 +,0x9d,0xaa,0xa0,0xd0,0x19,0x0e,0x0f,0x1a,0x18,0x17,0x13,0x16,0x18,0x18,0x20,0x37,0xd2,0x6b,0xfc,0x3e,0x2a,0x1d,0x35,0x6d,0xce,0x45,0x21,0x17,0x16,0x1e,0x30,0x3c +,0x23,0x1c,0x15,0x13,0x12,0x1f,0x4a,0x3f,0x34,0x24,0x29,0xee,0x7b,0xce,0xb9,0xc1,0xc9,0x5c,0x42,0x2a,0x3b,0xa8,0x96,0x94,0xa3,0x96,0x8c,0x8a,0x88,0x87,0x83,0x83 +,0x8b,0x8f,0x8b,0x8e,0xa5,0x36,0x5b,0x34,0x16,0x0d,0x0d,0x16,0x10,0x14,0x17,0x1c,0x19,0x12,0x16,0x1e,0x26,0x3c,0x3b,0x30,0x3a,0x33,0x51,0x35,0x2d,0x24,0x30,0x34 +,0x1f,0x18,0x12,0x19,0x21,0x32,0x27,0x1b,0x12,0x16,0x2a,0x4c,0xaa,0xb3,0xae,0xb2,0x5d,0x3d,0x6c,0xac,0xad,0xa6,0xb2,0xd1,0x4d,0xae,0x94,0x8f,0x93,0x96,0x8c,0x8a +,0x8f,0x8c,0x88,0x86,0x89,0x8c,0x8a,0x8a,0x99,0xcc,0xaf,0xa9,0x48,0x18,0x0d,0x0c,0x0d,0x0e,0x16,0x17,0x10,0x0e,0x0f,0x16,0x23,0x32,0x33,0x38,0x2d,0x25,0x23,0x1c +,0x1e,0x29,0x2d,0x31,0x26,0x1c,0x1b,0x2b,0x56,0x49,0x4d,0x2b,0x1f,0x1b,0x20,0x33,0x2e,0x2b,0x2b,0x56,0x45,0x32,0x2a,0x29,0x3e,0xd9,0xa8,0xb9,0x29,0x1f,0x46,0x9f +,0x97,0x99,0x94,0x8c,0x8b,0x89,0x86,0x82,0x85,0x8c,0x8b,0x84,0x87,0x98,0xac,0xa9,0xb1,0x50,0x2b,0x1c,0x15,0x0f,0x0f,0x14,0x19,0x15,0x17,0x14,0x15,0x1b,0x2a,0x4f +,0x2b,0x1f,0x1d,0x1d,0x19,0x1c,0x1b,0x1f,0x22,0x1e,0x22,0x1b,0x1e,0x29,0x3b,0x1e,0x1b,0x23,0x2d,0xd1,0xc6,0xbd,0x60,0xb2,0xa8,0x9c,0xbb,0x2f,0x29,0x2b,0xbc,0xb5 +,0xd2,0x43,0xc8,0xa1,0x95,0x9a,0x94,0x8a,0x89,0x90,0x8f,0x89,0x86,0x8a,0x8b,0x86,0x8a,0x91,0xb6,0xcd,0xbc,0x45,0x28,0x1a,0x16,0x0e,0x0c,0x0d,0x0e,0x0e,0x0e,0x14 +,0x1c,0x23,0x19,0x1c,0x1c,0x25,0xdd,0x69,0x24,0x13,0x11,0x14,0x29,0x2a,0x25,0x1b,0x17,0x18,0x26,0x2f,0x3d,0x30,0x17,0x34,0x4b,0x34,0x51,0xe6,0xcc,0xba,0xbb,0xb9 +,0x4e,0x2a,0xc5,0x9f,0x9e,0xa7,0xb4,0xac,0xa0,0xb9,0xb4,0x8f,0x8a,0x8a,0x8b,0x8a,0x86,0x8a,0x8a,0x84,0x84,0x89,0x9f,0xf8,0xbd,0xaf,0xbf,0x26,0x2e,0x20,0x12,0x0f +,0x13,0x19,0x1b,0x14,0x11,0x25,0x1d,0x20,0x1b,0x18,0x26,0x24,0x21,0x1a,0x11,0x0e,0x18,0x1b,0x2b,0x60,0x26,0x1f,0x23,0x1d,0x21,0x2d,0x24,0x2a,0x48,0x2f,0x2c,0x32 +,0xc3,0x9d,0x9e,0xc4,0x6c,0x24,0x23,0xc5,0xcb,0xd9,0x38,0xc7,0x9b,0x96,0xa4,0x9e,0x8f,0x90,0x8a,0x87,0x85,0x86,0x8f,0x8b,0x82,0x82,0x85,0x8f,0x9b,0x9e,0xd2,0x4b +,0x3d,0x1d,0x0f,0x0c,0x0d,0x0a,0x0d,0x0a,0x0d,0x1c,0x1e,0x27,0x1d,0x15,0x1d,0x33,0x53,0x44,0x34,0x0e,0x0d,0x1a,0x1a,0x3c,0x21,0x1f,0x37,0x2c,0x28,0x3c,0x2a,0x2c +,0xc1,0xc2,0xc9,0x2d,0x19,0x26,0xb7,0xa5,0xa6,0x2b,0x14,0x1d,0x49,0xb6,0xbb,0xc6,0xaa,0xab,0x73,0xc0,0x91,0x8d,0x8e,0x88,0x85,0x82,0x86,0x89,0x84,0x81,0x82,0x87 +,0x99,0xa1,0xb8,0x30,0x30,0x31,0x17,0x0d,0x0d,0x08,0x0a,0x0b,0x0b,0x16,0x1d,0x1c,0x20,0x0f,0x0d,0x14,0x25,0x49,0x55,0x1c,0x11,0x18,0x19,0x64,0xa9,0x3a,0x21,0x19 +,0x11,0x22,0x1f,0x24,0x3b,0x3d,0x33,0x55,0xde,0x34,0xb9,0xd6,0xca,0xc3,0x1e,0x1f,0x35,0x3f,0x3d,0x63,0xa6,0x9d,0xc1,0x26,0xa4,0x8f,0x92,0x8b,0x86,0x81,0x82,0x88 +,0x85,0x81,0x81,0x84,0x8c,0x9d,0xaa,0xd7,0x32,0x32,0x1b,0x10,0x0e,0x0c,0x08,0x05,0x05,0x0b,0x17,0x22,0xeb,0xb0,0x27,0x21,0x41,0xf6,0xae,0x48,0x16,0x0b,0x04,0x06 +,0x12,0x19,0x3e,0x78,0x4d,0xb1,0xb0,0xb8,0x3a,0x35,0xe3,0xc5,0xc3,0x1b,0x28,0xaf,0xb7,0xca,0x17,0x0e,0x18,0x29,0x24,0x77,0x96,0x8a,0x8f,0x4c,0xba,0x9a,0x9b,0xa0 +,0x91,0x83,0x80,0x89,0x9c,0x8e,0x84,0x81,0x83,0x86,0x88,0x91,0xcc,0x14,0x1c,0x1d,0x20,0x22,0x0c,0x13,0x19,0x09,0x09,0x09,0x16,0xb9,0x18,0x14,0x25,0xc5,0xa0,0x1d +,0x10,0x17,0x1a,0x16,0x17,0x2b,0x41,0x19,0x10,0x0d,0x21,0xa6,0x1a,0x43,0x96,0x89,0x8e,0x23,0x27,0x2e,0xb4,0xa2,0x18,0x22,0x9b,0x21,0x03,0x0a,0x85,0xa4,0x00,0x85 +,0x81,0x83,0x8a,0x0f,0xa2,0x93,0x95,0x0f,0x41,0x88,0x0f,0x0f,0x00,0x04,0x0e,0x0e,0x1b,0x03,0x0d,0xa9,0x0e,0x00,0x05,0x0f,0x16,0x04,0xd8,0x9f,0x1b,0x1d,0x1f,0x19 +,0xbb,0x86,0x80,0x8a,0x96,0x84,0x81,0x81,0x84,0x85,0x83,0x82,0x80,0x85,0x8d,0x88,0x82,0x86,0x85,0x85,0x81,0x86,0x81,0x85,0xa1,0x88,0x93,0x2a,0x21,0x9f,0x86,0x1c +,0x04,0x05,0x00,0x0d,0x04,0x06,0x0b,0x0e,0x0a,0x00,0x01,0x00,0x03,0x04,0x05,0x00,0x02,0x00,0x01,0x00,0x0d,0x3b,0x0d,0x11,0x0c,0x0d,0x0d,0x07,0x0d,0x06,0x1d,0xe9 +,0x1c,0x20,0x39,0xc2,0x0e,0x23,0x88,0x93,0xc0,0x98,0x83,0x81,0x91,0x96,0x89,0x84,0x80,0x83,0x83,0x81,0x80,0x8a,0xaf,0x87,0x80,0x80,0x81,0x80,0x80,0x80,0x84,0x87 +,0x82,0x80,0x80,0x81,0x85,0x87,0x86,0x9a,0x8e,0x86,0x88,0x8c,0x8c,0x8c,0xb0,0x1e,0x19,0x1f,0x42,0x2a,0x0f,0x26,0x0d,0x01,0x00,0x0b,0xbe,0x20,0x18,0x2b,0x33,0x35 +,0x0c,0x02,0x00,0x19,0xc5,0x06,0x00,0x08,0x07,0x00,0x00,0x07,0x10,0x03,0x00,0x01,0x04,0x05,0x01,0x01,0x01,0x0b,0x0b,0x01,0x05,0x0c,0x05,0x00,0x07,0x1e,0x0f,0x0b +,0x20,0xb4,0x26,0x08,0x02,0x06,0x2d,0x9f,0x2b,0x1a,0xcf,0x22,0x03,0x04,0xfd,0x99,0xe2,0x28,0xca,0x9f,0x63,0x16,0x4a,0x8c,0x82,0x88,0x98,0xa5,0xb0,0x97,0x8a,0x82 +,0x82,0x81,0x81,0x82,0x81,0x80,0x83,0x84,0x80,0x80,0x82,0x86,0x81,0x81,0x8e,0xae,0x8a,0x81,0x88,0x94,0x8b,0x80,0x80,0x88,0x36,0x99,0x82,0x80,0x8f,0x97,0x88,0x8d +,0xad,0xbe,0x86,0x84,0x85,0x85,0x8a,0x89,0x8e,0xaf,0xcf,0x91,0x84,0x88,0x98,0x8f,0x9b,0x40,0x1e,0xa5,0x9b,0x19,0x18,0x1f,0x1e,0x0a,0x00,0x01,0x07,0x0d,0x08,0x01 +,0x01,0x01,0x00,0x01,0x03,0x13,0x16,0x0d,0x07,0x09,0x1f,0x0b,0x01,0x07,0x18,0x26,0x0b,0x06,0x06,0x04,0x05,0x02,0x05,0x03,0x02,0x02,0x08,0x1e,0x0c,0x00,0x06,0x10 +,0x0d,0x03,0x05,0x17,0x0b,0x02,0x01,0x07,0x1a,0x0d,0x0e,0x0e,0x20,0x19,0x01,0x00,0x07,0x30,0x30,0x08,0x09,0x09,0x03,0x03,0x02,0x1a,0x27,0x26,0x1c,0x16,0x2e,0x1c +,0x18,0xd4,0x94,0x91,0xb4,0x44,0xa4,0x93,0x89,0x86,0x82,0x80,0x84,0x83,0x81,0x80,0x80,0x84,0x82,0x80,0x80,0x81,0x83,0x80,0x81,0x80,0x85,0x88,0x80,0x82,0x83,0x81 +,0x81,0x80,0x84,0x86,0x82,0x82,0x81,0x83,0x82,0x85,0x85,0x85,0x87,0x82,0x80,0x81,0x80,0x81,0x80,0x85,0x8b,0x81,0x80,0x80,0x88,0x8a,0x86,0x9f,0x2c,0x0e,0x1d,0x2e +,0x06,0x05,0x04,0x06,0x03,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x02,0x04,0x01,0x03,0x00,0x05,0x06,0x03,0x03,0x02,0x04,0x04,0x04,0x06 +,0x01,0x07,0x06,0x02,0x0f,0x1c,0xbf,0x1b,0x13,0x44,0x29,0x53,0x30,0xac,0x99,0x9d,0x97,0x57,0xb3,0x8b,0x8f,0x88,0x8a,0x88,0x8c,0xa0,0x8a,0x8a,0x86,0x86,0x89,0x8e +,0xac,0xa8,0xa7,0xaf,0x90,0x9e,0xa2,0x95,0x98,0x8f,0xab,0x8e,0x89,0x8f,0xa8,0x27,0xb1,0xa6,0xa5,0xa5,0xac,0x95,0x96,0x4f,0xae,0xa2,0x8e,0x96,0xbe,0x9c,0xb0,0xb6 +,0x22,0x25,0x52,0x1f,0x17,0x0d,0x0a,0x0b,0x09,0x10,0x25,0x14,0x16,0x10,0x25,0x30,0x18,0x1d,0x1f,0xe0,0xc9,0xb0,0x90,0x88,0x88,0x89,0x89,0x85,0x86,0x88,0x86,0x86 +,0x82,0x84,0x86,0x8a,0x8c,0x8b,0x8d,0x9b,0xb6,0xf3,0x2a,0x13,0x0e,0x0d,0x09,0x09,0x0d,0x0f,0x0a,0x08,0x07,0x08,0x0d,0x14,0x21,0x46,0xb5,0xd7,0x45,0xee,0x59,0x55 +,0xb4,0xa5,0x9a,0x98,0xa1,0x64,0x33,0xc8,0xa2,0xa1,0xba,0x70,0x71,0x4a,0x47,0xc9,0xae,0xa3,0x9a,0x9c,0xa9,0xb4,0xb8,0xb6,0xba,0xa3,0x95,0x91,0x94,0x93,0x94,0x91 +,0x93,0x9b,0xae,0xb1,0x9e,0x9e,0x9c,0xa1,0xbc,0xcf,0x47,0x35,0x2d,0x2a,0xd6,0x46,0x25,0x1d,0x1d,0x24,0x28,0x3c,0x4d,0x38,0x1e,0x14,0x11,0x16,0x23,0xc7,0xbb,0x37 +,0x2d,0x2d,0x35,0x23,0x19,0x24,0x48,0x46,0x29,0x24,0x29,0x1f,0x17,0x15,0x16,0x15,0x0c,0x08,0x09,0x0a,0x0d,0x0e,0x12,0x1a,0x1c,0x1e,0x21,0x23,0x1f,0x2a,0xbb,0x96 +,0x8d,0x8c,0x89,0x86,0x84,0x84,0x84,0x84,0x83,0x83,0x84,0x84,0x84,0x87,0x8c,0x93,0x9d,0xa3,0xc9,0x2c,0x1a,0x0e,0x0c,0x09,0x09,0x09,0x0a,0x09,0x06,0x04,0x03,0x03 +,0x06,0x0a,0x0e,0x14,0x1a,0x2d,0x2b,0x26,0x24,0x26,0x4d,0x75,0x38,0x38,0x33,0x28,0x25,0x3d,0xc0,0xb8,0xbd,0x3c,0x32,0x3e,0xc8,0xa7,0xa6,0x9f,0x9a,0x9f,0x9f,0x9e +,0x9c,0x9b,0x97,0x93,0x94,0x96,0x98,0x96,0x92,0x95,0x9a,0xa0,0xad,0xaf,0xb4,0xaa,0x9e,0x9e,0xad,0x54,0x43,0x54,0x4e,0x39,0x2d,0x2f,0x26,0x19,0x13,0x1b,0x38,0x3e +,0x27,0x22,0x21,0x1a,0x13,0x1a,0x30,0x49,0xfd,0x51,0x5c,0x3b,0x24,0x2c,0x61,0xbf,0x46,0x2c,0x28,0x1e,0x17,0x14,0x19,0x21,0x1d,0x11,0x0b,0x0a,0x0f,0x12,0x18,0x1f +,0x21,0x24,0x1e,0x23,0x30,0xd4,0xaa,0xa7,0x9d,0x95,0x8d,0x88,0x84,0x82,0x82,0x82,0x83,0x83,0x83,0x83,0x83,0x84,0x85,0x88,0x8d,0x95,0x9d,0xb2,0x4d,0x20,0x10,0x0a +,0x06,0x05,0x07,0x0a,0x0c,0x09,0x06,0x05,0x05,0x05,0x07,0x0d,0x12,0x16,0x18,0x16,0x1c,0x23,0x22,0x29,0x34,0x35,0x29,0x1c,0x18,0x1f,0x34,0x53,0xcb,0x56,0x38,0x32 +,0x3e,0xb6,0xa7,0x9d,0x97,0x97,0x9a,0x9c,0x96,0x90,0x90,0x94,0x9a,0x98,0x97,0x99,0x94,0x92,0x90,0x94,0x9f,0xa7,0xab,0xa7,0xa1,0xa1,0xa2,0xb0,0xe0,0x4c,0x53,0xcd +,0x78,0xbe,0xbb,0x42,0x1f,0x17,0x22,0x38,0x66,0x6f,0x49,0x30,0x1f,0x1a,0x21,0x2e,0x45,0x4f,0x3e,0x31,0x1f,0x1f,0x28,0x2d,0x2e,0x2f,0x2b,0x1c,0x13,0x17,0x1f,0x25 +,0x1e,0x15,0x12,0x0e,0x0d,0x0f,0x15,0x1b,0x1b,0x18,0x1a,0x2a,0x43,0xd8,0xb3,0xab,0xa6,0xa5,0xa0,0x96,0x8c,0x87,0x85,0x84,0x84,0x83,0x84,0x84,0x82,0x82,0x84,0x86 +,0x8a,0x8d,0x96,0xa0,0xa6,0xaa,0xfc,0x1f,0x14,0x0f,0x0d,0x0c,0x0c,0x0e,0x0e,0x0b,0x06,0x04,0x04,0x07,0x08,0x07,0x0b,0x0d,0x0f,0x14,0x19,0x2a,0x2e,0x28,0x2c,0x3b +,0x36,0x2c,0x2f,0x2f,0x61,0xb0,0xb7,0xaf,0xae,0xac,0x9f,0x9e,0x9a,0x9a,0x9e,0xa3,0xa2,0x99,0x95,0x9c,0xa5,0xa6,0xa1,0xa5,0x9f,0x96,0x99,0x9d,0xa8,0xaa,0xa1,0xad +,0xba,0xae,0xa7,0xa0,0xa5,0xa9,0xa4,0xa7,0xa1,0x9f,0x9d,0xa0,0xb2,0x5c,0x2d,0x2e,0x3b,0x2d,0x35,0x48,0x2c,0x1e,0x19,0x1e,0x22,0x1f,0x1c,0x1b,0x16,0x14,0x19,0x24 +,0x2a,0x1f,0x1f,0x20,0x25,0x36,0xc7,0xd8,0x38,0x35,0x30,0x26,0x20,0x1f,0x1e,0x1e,0x13,0x13,0x1a,0x18,0x1d,0x23,0x36,0x5c,0xd5,0x4d,0xcf,0xb4,0xa5,0x92,0x8d,0x8a +,0x87,0x87,0x87,0x84,0x83,0x82,0x82,0x82,0x83,0x86,0x89,0x89,0x8c,0x96,0xa7,0x3c,0x2a,0x20,0x14,0x0f,0x0b,0x0b,0x0a,0x09,0x0b,0x0a,0x07,0x03,0x04,0x06,0x07,0x0b +,0x0d,0x0c,0x14,0x17,0x1a,0x26,0x1f,0x23,0x2a,0x2a,0x3c,0x3c,0x48,0xbd,0xbe,0xb2,0xaa,0xa9,0xa5,0xa2,0xad,0xb2,0x9f,0xa2,0x9e,0x98,0x9b,0x96,0x98,0xa4,0xa1,0xa0 +,0xa7,0xa8,0x9e,0x94,0x99,0x96,0x95,0xa0,0xa4,0xaf,0xa4,0xa3,0xab,0xb1,0x34,0x4e,0xba,0xad,0x9e,0xa9,0xd8,0xb5,0xd6,0x3f,0x2e,0x28,0x32,0x29,0x24,0x27,0x2b,0x25 +,0x2f,0x2d,0x27,0x1f,0x24,0x20,0x29,0x46,0x29,0x26,0x1e,0x19,0x27,0x2c,0x1f,0x2b,0x1d,0x1b,0x23,0x22,0x17,0x1a,0x17,0x10,0x19,0x12,0x11,0x0e,0x0f,0x18,0x1e,0x29 +,0x32,0x2c,0x34,0xa7,0x9e,0x92,0x8f,0x90,0x8e,0x8d,0x87,0x87,0x86,0x86,0x87,0x85,0x82,0x82,0x82,0x84,0x88,0x99,0xa5,0xa5,0xce,0xdf,0x35,0x1d,0x0e,0x09,0x07,0x0a +,0x10,0x11,0x0d,0x0c,0x0e,0x0f,0x0d,0x0a,0x05,0x0d,0x23,0x23,0x15,0x16,0x17,0x1a,0x3c,0xb1,0xac,0x2e,0x23,0x0e,0x2b,0x98,0x95,0x94,0xa2,0x3c,0x2a,0xa2,0x97,0x9b +,0x9b,0xb5,0xc3,0x99,0x8f,0x92,0xa1,0xe2,0x64,0xa3,0x93,0x93,0xe6,0x5b,0x3a,0xa9,0x8f,0x8f,0x9d,0xdd,0x35,0x1d,0x3c,0xc8,0x9b,0xd0,0x2d,0x2e,0xab,0x8e,0x91,0xa4 +,0x29,0x0e,0x11,0x44,0x4e,0x2b,0x1f,0x2b,0x3a,0xd3,0xb5,0x3a,0x21,0xc3,0x1f,0x1a,0x2b,0x32,0x3c,0x14,0x18,0x12,0x26,0xa0,0x57,0x23,0x4a,0xbe,0x96,0x8f,0x91,0xb2 +,0x13,0x15,0x1d,0xb9,0xb5,0x4a,0x1e,0x15,0x0f,0x27,0x93,0x8f,0x98,0x7d,0x14,0x16,0xc8,0xa5,0xac,0x21,0x21,0x30,0xb9,0x9a,0xa1,0xb2,0xce,0xab,0x95,0x8e,0x94,0x98 +,0x9c,0x9f,0xad,0x97,0x92,0x98,0x9e,0x39,0x3e,0x9d,0x8a,0x8f,0xaf,0x23,0x10,0x11,0x38,0xcb,0x14,0x0d,0x15,0x18,0x1f,0x2b,0xca,0xc3,0x33,0x1e,0x14,0x16,0x1f,0x2f +,0x17,0x09,0x1a,0xa9,0x40,0xa5,0xae,0x45,0x36,0x59,0x8c,0x9b,0xac,0xaf,0x2d,0xbc,0xad,0xb8,0xb6,0x27,0xae,0x16,0x1c,0x8a,0x89,0x88,0xba,0x48,0xa5,0xa3,0x86,0x8d +,0xb3,0xcf,0x25,0x3f,0x1e,0x9d,0xaa,0x20,0xa7,0xaa,0x9b,0xac,0xa0,0x8f,0x2d,0x43,0xa9,0xbf,0x9e,0x18,0x0d,0x02,0x0c,0x19,0x04,0x15,0x24,0x32,0x2a,0x10,0x53,0x1c +,0x2a,0x8f,0x3e,0x3f,0x17,0x12,0x05,0x0b,0x78,0x08,0x12,0x24,0x1f,0x3f,0xb2,0x84,0x92,0x2a,0x4d,0x1a,0xa1,0xa1,0xe2,0x0e,0x02,0x2e,0x12,0xad,0x87,0x8c,0x87,0xa5 +,0x89,0x85,0x98,0x80,0x96,0x9f,0xa7,0x9a,0x88,0x9d,0x87,0xe8,0x23,0x82,0x84,0x80,0x95,0x96,0x8a,0x13,0xaa,0xca,0x1f,0x26,0x00,0x04,0x00,0x0d,0x16,0x03,0x18,0x03 +,0x07,0x06,0x16,0x9c,0x02,0x08,0x09,0x03,0x0f,0x06,0x10,0x02,0x1d,0xa8,0x04,0x9c,0x88,0x86,0x90,0x31,0x84,0x9e,0x8d,0x82,0x2a,0xab,0x3d,0x97,0xb0,0xa2,0x86,0x1b +,0x91,0x80,0x83,0x81,0x94,0x81,0xb7,0x2f,0x83,0x9d,0x84,0x8f,0x56,0x0a,0x0f,0x80,0xae,0x94,0x84,0x91,0x8b,0xa7,0x85,0xca,0x0f,0x95,0x0e,0x1d,0x19,0x09,0x06,0x03 +,0xed,0x07,0x0a,0x95,0xaa,0x3c,0x05,0x14,0x14,0x0b,0x94,0x0c,0x05,0x0b,0x0d,0x14,0x0f,0x8c,0x17,0x0c,0x92,0x9d,0xa6,0x1c,0xa7,0x2a,0x08,0xa3,0x1b,0x34,0x9e,0x15 +,0x09,0x02,0x8d,0xa5,0x1f,0x8c,0x40,0xc8,0x3f,0x8f,0x9f,0x10,0x94,0x32,0xa9,0x84,0x96,0xb6,0x2d,0x85,0x9e,0xbe,0x80,0x82,0x86,0xcb,0xbc,0xce,0xf4,0x84,0xac,0x15 +,0x31,0x14,0x15,0x15,0x93,0x21,0x01,0xb0,0x2e,0x11,0x09,0x17,0x13,0x00,0x38,0x21,0x1e,0x97,0x20,0x07,0x07,0x8a,0x85,0x94,0x81,0x8d,0x9d,0x8e,0x81,0x84,0x95,0x85 +,0x90,0xa8,0x84,0x8e,0xa6,0x24,0x8d,0xc8,0x0f,0x89,0x8c,0xa3,0x14,0x08,0x06,0x04,0x4f,0x1b,0x00,0x07,0x02,0x02,0x03,0x3a,0x15,0x00,0x22,0x2e,0x18,0x1a,0x1a,0x0e +,0x01,0x18,0x27,0x13,0x95,0x1a,0x02,0x00,0x5c,0x8f,0x2e,0x85,0xa9,0x1e,0x47,0x9b,0x8c,0xbc,0x98,0x92,0xab,0x8a,0x92,0x99,0xa6,0x8c,0x8a,0x51,0x83,0x81,0x84,0x89 +,0x99,0x9b,0xa1,0x87,0x81,0xa0,0xa7,0xa0,0xa8,0xae,0x99,0x93,0x08,0xbd,0x8e,0x3b,0xae,0x4b,0x19,0x0a,0x1d,0xa9,0x30,0x93,0x9c,0x0d,0x04,0x10,0x8e,0x33,0x9d,0x93 +,0x0b,0x1d,0xe1,0xaf,0x1c,0x21,0xba,0x0f,0x23,0xb2,0x0f,0x03,0x08,0x40,0x05,0x13,0x84,0x39,0x0a,0x0e,0x0c,0x06,0x2f,0x8f,0x14,0x05,0x23,0x10,0x14,0x44,0x8d,0x2c +,0x11,0x83,0x9a,0x9f,0x88,0x91,0x30,0x14,0xa8,0x9f,0xab,0x8c,0xda,0x14,0x05,0xaa,0x86,0x36,0x8c,0x9c,0x3f,0xbd,0x9e,0x9c,0x1b,0x23,0x22,0x16,0xa6,0x5f,0x1f,0x0b +,0x19,0xa7,0x1c,0x87,0x87,0xa2,0xb4,0x11,0x1a,0x92,0x84,0x90,0xac,0x8b,0xca,0x39,0x87,0x8b,0x87,0xa9,0x8a,0x84,0x90,0x81,0x8c,0xa7,0xc8,0xa8,0x8e,0x95,0x88,0x9d +,0x08,0x0b,0x0f,0x93,0x17,0x16,0xa7,0x02,0x08,0x24,0x26,0x03,0x0b,0x1b,0x01,0x04,0x49,0x0e,0x00,0x01,0x08,0x04,0x03,0x96,0x2d,0x0a,0x0e,0x08,0x08,0x16,0x9f,0xe1 +,0x18,0xac,0xb8,0xbc,0x38,0x9b,0x86,0x2d,0x8b,0x80,0x85,0x8b,0x94,0x8c,0xa2,0x8c,0x80,0x8c,0x8b,0x93,0x2a,0x1d,0xa2,0x80,0x40,0x9b,0x86,0x40,0xac,0xa5,0xaf,0x3b +,0xbd,0xb6,0x2a,0x98,0x98,0x1b,0x3f,0x2a,0xab,0xa7,0x95,0x87,0x5b,0xa7,0xc7,0x1f,0xbc,0x49,0x39,0x18,0x14,0x3c,0x16,0x14,0x07,0x0f,0x11,0x01,0x9c,0xa3,0x17,0x1b +,0x0a,0x03,0x04,0xad,0xdc,0x09,0xd3,0x22,0x04,0x09,0x59,0xa1,0x0c,0x95,0x8f,0x21,0x9e,0xa7,0x26,0x27,0x98,0x94,0xb8,0x96,0x9b,0x18,0x0e,0x0d,0x93,0xbd,0x28,0x88 +,0xae,0x28,0x27,0x9e,0x9d,0xbd,0x8c,0x9f,0xe7,0x8c,0x91,0xa7,0x2e,0x92,0xa4,0x1e,0x82,0x8f,0xaf,0xa0,0xcc,0x78,0x9e,0x94,0x48,0x21,0xe3,0x0f,0x0f,0x20,0x0f,0x1a +,0x0b,0xae,0x9c,0xaa,0x8c,0xc6,0x29,0xad,0x8d,0x86,0x88,0x81,0x8a,0xb7,0xb3,0x9b,0x84,0x8c,0x89,0x80,0x9a,0x98,0x91,0xaf,0x2b,0xa7,0x9d,0x0e,0x15,0x3d,0x04,0x01 +,0x01,0x0b,0x06,0x06,0xc4,0x09,0x00,0x05,0x05,0x05,0x0c,0x15,0x08,0x00,0x10,0x0d,0x08,0x11,0x15,0x4a,0x09,0xa1,0x86,0xa3,0x97,0xa4,0xa0,0xb3,0x9d,0x88,0x9f,0xab +,0x9e,0x4b,0xba,0xb9,0x8a,0xa8,0x9c,0x81,0x96,0x98,0x97,0xa9,0xfe,0xaa,0x97,0x91,0x8a,0x8d,0x31,0x3c,0x4c,0x97,0x88,0x8e,0x80,0x91,0x9b,0x91,0xb2,0x93,0x93,0x98 +,0xa5,0x20,0xbf,0x1c,0x15,0x0f,0x0a,0x23,0x0d,0x98,0xa0,0x14,0x1b,0x10,0x0d,0x17,0xa8,0x3d,0x0d,0x17,0x0f,0x04,0x16,0x46,0xcd,0x0a,0x49,0x98,0x1d,0xc5,0x76,0x17 +,0x0c,0x19,0x35,0x12,0x22,0x2b,0x02,0x04,0x0b,0xab,0x20,0x1d,0x8c,0x2e,0x21,0xc8,0xdd,0x3a,0x41,0x98,0xb1,0xc1,0x89,0xa4,0x4c,0x3d,0xa2,0x92,0x9a,0x80,0x86,0xa7 +,0xb6,0xc9,0xbc,0xac,0x8f,0x92,0x1f,0x32,0x2c,0x24,0x2b,0xbf,0x9d,0x0d,0xb2,0x93,0x37,0x3b,0x1a,0x0f,0x14,0x56,0xa8,0x47,0xc7,0x54,0x25,0xaf,0x9e,0x85,0x95,0x8c +,0x84,0x92,0x85,0x87,0x8e,0x8e,0x88,0x89,0x98,0x8e,0x8b,0x51,0x2c,0x33,0x9e,0x19,0x59,0x87,0x1f,0x0a,0x08,0x02,0x0a,0x37,0x14,0x00,0x02,0x08,0x01,0x02,0x08,0x14 +,0x06,0x06,0xa0,0x1c,0x09,0x1b,0x0a,0x04,0x0f,0xa4,0x9f,0x2d,0x4d,0x0e,0x0e,0x1d,0x99,0xb9,0xd2,0x87,0x95,0xa3,0xa6,0x9d,0xa6,0xb4,0xa1,0xa2,0x9b,0x90,0xa3,0xa9 +,0x58,0x96,0x97,0x8d,0x80,0x87,0x8a,0x93,0xad,0x9c,0x87,0x83,0x8f,0xad,0x9f,0x3e,0x96,0x9b,0x92,0x2f,0x34,0x88,0xac,0xaf,0xb3,0x16,0x05,0x15,0xa3,0xa9,0xce,0x3b +,0x06,0x03,0x0d,0x90,0xa9,0x2c,0x99,0x2c,0x14,0x27,0x35,0x0f,0x1d,0xae,0x29,0x12,0x5c,0x1e,0x0d,0x06,0x2b,0x0e,0x14,0x8f,0x4a,0x13,0x05,0x07,0x0a,0x12,0xb3,0x2b +,0x16,0x13,0x0b,0x1a,0xc4,0x8d,0x2e,0x4c,0x92,0x98,0x8a,0x9a,0x2e,0x28,0x5a,0x8f,0x8b,0x82,0x8a,0x21,0x10,0xb7,0x8b,0xa2,0x85,0x87,0x32,0x1a,0xd5,0xae,0x48,0xa4 +,0x94,0x3d,0xb1,0x6d,0x0c,0x08,0xb4,0xa9,0x0f,0x8d,0x8b,0xa3,0x1a,0x09,0x16,0x1a,0x9e,0x84,0x88,0x9a,0x1a,0x1d,0xb4,0x87,0x84,0x84,0x82,0x8f,0x90,0x93,0x8e,0x8f +,0x97,0x9e,0x97,0x87,0x8a,0x5f,0x0b,0x17,0x28,0x06,0xa0,0x8a,0x0f,0x01,0x02,0x08,0x02,0x10,0x27,0x05,0x03,0x08,0x06,0x03,0x1a,0x0c,0x02,0x31,0x2a,0x0f,0x0e,0x12 +,0x10,0x07,0x15,0x35,0x8f,0x95,0x16,0x0e,0x15,0x9d,0xed,0x8f,0x80,0xba,0xa8,0x9f,0x3f,0x2f,0x95,0x89,0xa9,0x8d,0x87,0x9b,0xa8,0x84,0xb0,0x15,0x83,0x81,0x8d,0xa3 +,0x2e,0x0f,0x11,0x8d,0x80,0x86,0x98,0x1c,0x11,0xd3,0x8e,0x9e,0x8c,0x98,0x44,0x2e,0x18,0x1e,0x14,0x48,0x9e,0x32,0xd2,0x3c,0x09,0x18,0x87,0x9e,0x00,0x92,0x80,0x1b +,0x1c,0x08,0x07,0x08,0x23,0x26,0x08,0x14,0x00,0x03,0x06,0x03,0x04,0x05,0x09,0x00,0x02,0x02,0x04,0x00,0x06,0x16,0x12,0x1e,0x16,0x0b,0x2d,0x8e,0x95,0x89,0x81,0x8b +,0x83,0x85,0x94,0x92,0x84,0x80,0x82,0x86,0x82,0x89,0x88,0x80,0x83,0x83,0x80,0x82,0x89,0x98,0x98,0xa4,0x9e,0x88,0x8c,0x8d,0x99,0x61,0x56,0x96,0x23,0x37,0x8f,0x31 +,0x18,0x05,0x03,0x00,0x04,0x18,0x0c,0x0a,0x07,0x00,0x02,0x0c,0x05,0x02,0x0e,0x07,0x03,0x00,0x00,0x00,0x00,0x06,0x03,0x08,0x0f,0x02,0x00,0x11,0x04,0x13,0xa8,0xf3 +,0x1d,0x08,0x0d,0x09,0x1d,0x95,0x93,0x8f,0x8a,0xaa,0x9c,0x82,0x8c,0x84,0x80,0x83,0x86,0x89,0x86,0x9d,0x89,0x80,0x86,0x81,0x80,0x87,0x88,0x80,0x86,0x80,0x81,0x80 +,0x86,0x89,0x86,0x8e,0x83,0x80,0x83,0x82,0x8c,0xa7,0x84,0x83,0x8b,0x80,0x8b,0x9a,0x2a,0x27,0x3a,0x0f,0xa7,0xd5,0x0d,0x1e,0x09,0x00,0x1e,0x09,0x11,0x38,0x0f,0x0d +,0x00,0x02,0x00,0x02,0x0d,0x0a,0x06,0x03,0x00,0x01,0x0d,0x01,0x15,0x29,0x04,0x05,0x00,0x05,0x00,0x09,0x14,0x07,0x07,0x03,0x00,0x0f,0x0a,0x08,0x60,0x11,0x13,0x05 +,0x04,0x06,0x02,0x2e,0x1d,0x17,0x1d,0x04,0x06,0xc3,0x1e,0xa4,0x90,0xaf,0x3b,0x0d,0xaf,0x6e,0x92,0x83,0x91,0x9a,0x9a,0xa7,0x89,0x83,0x90,0x80,0x83,0x86,0xa3,0x90 +,0x8a,0x90,0x82,0x80,0x89,0x86,0x91,0x9c,0x80,0x8e,0x83,0x80,0x82,0x8e,0xb3,0x93,0x9e,0x88,0x80,0x86,0x8a,0x99,0x29,0x8a,0x85,0x8c,0x80,0x86,0x8b,0xa5,0xa2,0xb3 +,0xa6,0x85,0x87,0x96,0x8d,0xb9,0xac,0x81,0xa3,0x89,0x81,0x8b,0x9a,0x4f,0xa6,0x23,0x99,0x81,0x8f,0x96,0xa5,0x14,0x8c,0x96,0xa9,0x81,0x9c,0xcf,0x12,0x1a,0x0d,0x0c +,0xbc,0x1e,0x06,0x0a,0x00,0x0b,0x1e,0x01,0x21,0x0f,0x02,0x03,0x00,0x03,0x00,0x08,0x0c,0x01,0x01,0x01,0x00,0x0a,0x03,0x07,0x0f,0x02,0x02,0x00,0x01,0x00,0x04,0x0e +,0x05,0x00,0x02,0x00,0x07,0x0a,0x02,0x1b,0x09,0x02,0x01,0x00,0x03,0x00,0x19,0x1c,0x05,0x0a,0x01,0x07,0x2e,0x05,0xa7,0x9d,0xdf,0x24,0x0a,0x1c,0x14,0x92,0x83,0x89 +,0x8b,0x9a,0xa0,0x81,0x88,0x86,0x80,0x81,0x83,0x8a,0x83,0x86,0x82,0x80,0x80,0x81,0x81,0x85,0x81,0x80,0x82,0x80,0x81,0x80,0x86,0x84,0x84,0x88,0x80,0x80,0x81,0x81 +,0x8a,0x87,0x80,0x89,0x80,0x81,0x80,0x93,0xa3,0x8d,0xae,0x89,0x81,0x8b,0x96,0xbd,0x30,0x87,0xa0,0x9d,0x86,0xa6,0x2a,0x07,0x13,0x09,0x0e,0xc3,0x22,0x0b,0x0c,0x00 +,0x13,0x1c,0x05,0x3e,0x1a,0x0d,0x02,0x00,0x02,0x00,0x0e,0x11,0x07,0x05,0x00,0x02,0x10,0x01,0x1a,0x2b,0x0c,0x07,0x00,0x05,0x00,0x0d,0x21,0x0f,0x0b,0x06,0x02,0x2d +,0x0b,0x13,0x99,0x3c,0x1c,0x05,0x19,0x08,0x0b,0x9f,0xb6,0x35,0x20,0x0e,0xa9,0xc7,0x1a,0x89,0x8e,0xa0,0x25,0x2b,0x21,0x14,0x94,0x8f,0xb2,0xa2,0x24,0x56,0x89,0xc3 +,0x8d,0x84,0x8f,0xa9,0x2a,0xb4,0x2f,0x97,0x85,0x95,0x9e,0xb1,0x23,0x8a,0x9e,0xa8,0x80,0x8d,0x9b,0x1f,0xd4,0x25,0x20,0x89,0x8d,0xaf,0xc0,0x19,0xaf,0xba,0x18,0x89 +,0x90,0xa0,0x1c,0x14,0x17,0x0b,0xaf,0x93,0xb5,0x42,0x19,0x1f,0x9c,0x0c,0xa3,0x8d,0xaf,0x36,0x16,0x21,0x0a,0x2e,0x9a,0xd2,0x5a,0x57,0x14,0x95,0x36,0x28,0x8e,0x9b +,0xb2,0x1a,0x37,0x19,0x26,0x97,0x9c,0xbc,0xac,0x23,0x99,0x8e,0xc1,0x88,0x86,0x94,0x29,0xbf,0xb4,0x26,0x8f,0x87,0x9a,0xa8,0xfe,0x9f,0x8c,0xc7,0x8e,0x83,0x93,0xdd +,0x2b,0xaf,0x1a,0xc3,0x8c,0xa0,0xd1,0x2b,0x17,0xa2,0x2a,0x27,0x8d,0xa1,0x55,0x0c,0x14,0x11,0x11,0xaa,0xa1,0x27,0x28,0x09,0x2c,0xc4,0x0d,0x92,0x9e,0x4d,0x0f,0x10 +,0x17,0x0d,0xc2,0x9c,0x46,0x40,0x14,0x1c,0x99,0x12,0xc2,0x8e,0x9d,0x1e,0x15,0x3e,0x10,0x37,0x93,0x9a,0xbe,0x2e,0x16,0xa2,0x4e,0x22,0x8b,0x8d,0xbd,0x0f,0x25,0x19 +,0x18,0x97,0x93,0xe5,0x4e,0x16,0x3c,0xa4,0x1f,0x98,0x98,0xa9,0x17,0x0d,0x21,0x16,0x5b,0x96,0xc3,0x2c,0x18,0x19,0x9e,0x15,0x5b,0x8e,0xa5,0x2b,0x0b,0x1c,0x0f,0x1b +,0x9a,0x9e,0x38,0x1a,0x0f,0xad,0x39,0x1a,0x8e,0x97,0x36,0x0a,0x11,0x11,0x1c,0xaa,0x99,0x59,0x1e,0x10,0x26,0x98,0x19,0x98,0x8b,0xa5,0x14,0x0f,0x1d,0x10,0xb6,0x8f +,0x9e,0x3f,0x1c,0x19,0x9a,0x2d,0xb5,0x86,0x8f,0x34,0x0e,0x1f,0x15,0x2d,0x8f,0x92,0x4b,0x26,0x15,0xa3,0xaf,0x2b,0x8a,0x8e,0xa6,0x12,0x25,0x2d,0x1d,0xa2,0x93,0xb1 +,0x27,0x17,0xdc,0x97,0x1a,0x99,0x8b,0x9e,0x17,0x11,0x27,0x12,0xbe,0x95,0xac,0x2a,0x10,0x15,0x9e,0x22,0xaa,0x8d,0x99,0x1d,0x08,0x2b,0x0f,0x2d,0x92,0x9e,0x29,0x18 +,0x0d,0xae,0xd5,0x27,0x8f,0x94,0xdd,0x05,0x1d,0x1d,0x0f,0x9d,0x92,0x3c,0x1e,0x0e,0x29,0xc7,0x1c,0x8f,0x91,0x9f,0x10,0x0d,0x1f,0x0f,0xaa,0x8b,0xa2,0x35,0x13,0x17 +,0xa6,0x29,0x9d,0x88,0x8e,0x24,0x0c,0x2b,0x1a,0x3b,0x8f,0x8e,0xc7,0x1e,0x14,0x9e,0xe6,0x2f,0x87,0x8e,0x4e,0x0d,0x1c,0x14,0x1b,0x94,0x8e,0xbb,0x2c,0x0e,0x31,0xad +,0x26,0x8c,0x89,0x9b,0x0d,0x0d,0x18,0x0f,0xb1,0x8d,0x9a,0x36,0x0d,0x1e,0x9a,0x1a,0x9e,0x8a,0x98,0x1b,0x0b,0x18,0x0f,0x2d,0x9c,0x9f,0x38,0x16,0x15,0x98,0x29,0x43 +,0x8b,0x97,0xcb,0x0c,0x18,0x13,0x20,0x9b,0x93,0xa5,0x20,0x0d,0x9e,0xce,0x1c,0x8c,0x88,0xa0,0x0d,0x1e,0x11,0x1c,0xa0,0x90,0xa8,0x23,0x10,0x5b,0x95,0x20,0x91,0x89 +,0x96,0x18,0x14,0x24,0x1c,0xab,0x8e,0x95,0xb2,0x17,0x2a,0x8f,0x20,0xad,0x88,0x88,0x2e,0x0e,0x27,0x11,0x3a,0x90,0x8e,0xa6,0x1e,0x12,0x9d,0x1f,0x32,0x88,0x8b,0x79 +,0x09,0x1f,0x0f,0x25,0x90,0x8f,0xa5,0x22,0x0c,0xa4,0xd8,0x1c,0x91,0x8a,0xa7,0x06,0x1b,0x12,0x13,0xa8,0x92,0x9f,0x39,0x0d,0x35,0xab,0x0e,0x9f,0x8b,0x98,0x0d,0x0f +,0x15,0x0e,0xaf,0x8c,0x98,0xdd,0x12,0x1a,0x97,0x17,0xa4,0x89,0x94,0x11,0x07,0x27,0x16,0xd2,0x8b,0x91,0xcc,0x15,0x16,0x8d,0x26,0x2c,0x8b,0x8f,0x2c,0x0a,0x33,0x19 +,0x29,0x92,0x92,0x9e,0x32,0x0f,0x95,0x3f,0x19,0x8f,0x89,0xa0,0x09,0x1f,0x1b,0x1a,0x9a,0x8f,0xa1,0x26,0x0a,0xa3,0xa1,0x1e,0x94,0x8b,0x98,0x08,0x12,0x27,0x1b,0xb0 +,0x92,0xa0,0x3f,0x0d,0xe9,0x92,0x14,0xab,0x8f,0x92,0x14,0x10,0x2b,0x16,0x37,0x99,0x96,0xbd,0x0f,0x19,0x97,0x10,0x79,0x87,0x89,0x27,0x08,0x1f,0x11,0x27,0x92,0x8f +,0xbc,0x0f,0x0e,0x97,0x3e,0x55,0x8e,0x8b,0xc4,0x09,0x28,0x20,0x1d,0xa7,0x9b,0xa2,0x26,0x0e,0x95,0x5a,0x16,0x9a,0x88,0x97,0x12,0x2a,0x23,0x16,0xbc,0x97,0x9c,0xb7 +,0x09,0xa9,0xa7,0x15,0x95,0x87,0x89,0x14,0x0f,0x26,0x19,0xbe,0x92,0xa6,0x5e,0x08,0x41,0x8d,0x28,0x9e,0x8f,0x8f,0x13,0x0d,0x5e,0x1e,0x21,0x9f,0xa4,0xbb,0x13,0x2c +,0x8c,0x1a,0x2f,0x90,0x88,0x32,0x0b,0x26,0x13,0x1c,0xa7,0x96,0x98,0x17,0x0e,0x98,0x30,0x2a,0x94,0x87,0x4f,0x06,0x17,0x1d,0x1f,0xab,0x97,0xb7,0x1a,0x0d,0x8e,0x97 +,0x3f,0x9e,0x93,0xb7,0x0c,0x1f,0x3d,0x22,0x30,0xa1,0xa2,0xaa,0x14,0xa4,0xa3,0x15,0xb6,0x8b,0x8a,0x16,0x0f,0x1c,0x14,0x29,0x94,0x98,0xaa,0x0d,0x46,0x8d,0x37,0x9c +,0x8e,0x8f,0x13,0x06,0x27,0x27,0x33,0xa6,0xad,0xa6,0x11,0x41,0x85,0x6f,0x35,0xa9,0x8f,0x25,0x09,0x26,0x2c,0x1d,0x30,0xa3,0x8f,0x2e,0x18,0x8d,0x2d,0x29,0x9b,0x89 +,0xa2,0x05,0x15,0x24,0x2e,0xa5,0xa5,0xa2,0x1c,0x09,0x93,0x96,0xbe,0x9a,0x89,0x9e,0x03,0x0b,0x51,0x30,0x3a,0xa4,0x91,0xa5,0x0f,0xad,0xac,0x14,0x28,0x95,0x93,0x0f +,0x0d,0x3d,0xad,0xa4,0x9e,0x95,0xa1,0x0a,0x3b,0x9c,0x17,0x2f,0x98,0x85,0x2a,0x0c,0x24,0x3d,0xd9,0xab,0x9f,0xed,0x09,0x14,0x8f,0x9e,0xa3,0x9b,0x8b,0x42,0x08,0x1d +,0x6b,0x71,0xa1,0xa8,0xa6,0x25,0x28,0x91,0xd4,0x2b,0x3c,0x8c,0x6b,0x01,0x0a,0xbd,0x89,0x8d,0x9d,0xbf,0x15,0x0e,0x96,0xba,0x1c,0x31,0x94,0x8a,0x1d,0x13,0x1d,0xbf +,0xbd,0xed,0xae,0x22,0x08,0x37,0x9c,0x9b,0x9c,0x90,0x8e,0x0e,0x0f,0x2e,0x56,0x28,0x25,0xc6,0xaa,0x1e,0xab,0x96,0xbb,0x2a,0xc1,0x8a,0x1c,0x06,0x0d,0xa8,0x94,0x9f +,0xa5,0xaf,0x10,0x1d,0x93,0xc0,0x32,0x26,0x87,0x8b,0x23,0x12,0x1a,0x45,0x28,0xb0,0xa7,0x0e,0x04,0x4e,0x98,0x8c,0x8f,0x84,0x8d,0x0d,0x0b,0x19,0xac,0x2c,0x1b,0x9f +,0xab,0x0f,0x37,0xa5,0xad,0xbf,0x8e,0x85,0x18,0x03,0x06,0x9f,0x8b,0x8f,0x9b,0x51,0x08,0x20,0x95,0x5d,0x22,0x3e,0x85,0xd4,0x0c,0x13,0x65,0xa1,0xb4,0xa5,0xc7,0x0b +,0x0b,0x99,0x8f,0x8f,0xb5,0x8f,0xac,0x0a,0x10,0x34,0x9f,0x20,0x3c,0x9a,0xda,0x1e,0x99,0x9a,0xd6,0xe4,0x95,0xa5,0x05,0x03,0x12,0x9f,0xa3,0xba,0xa8,0xcb,0x0e,0xa8 +,0x8a,0xa7,0x45,0xa8,0x89,0x1d,0x0a,0x17,0xc9,0xa0,0x2f,0xdd,0xa1,0x19,0x2e,0x93,0xa0,0xc8,0x5d,0x88,0xcf,0x04,0x07,0x18,0xae,0xb3,0x8f,0x87,0xad,0x39,0x9f,0xec +,0x2f,0x1e,0x91,0x9e,0x09,0x0c,0x1e,0x97,0xc9,0x34,0xb1,0x45,0x10,0x49,0xa7,0x5b,0xa2,0x87,0x85,0x18,0x0a,0x0c,0xbc,0xc4,0x32,0xbb,0xba,0x1d,0x21,0x99,0xbd,0xb8 +,0xaa,0x8a,0x27,0x02,0x0a,0x35,0x9a,0x95,0x8d,0x9a,0x16,0x0e,0x9b,0xa2,0xb7,0x3d,0x91,0xa1,0x0d,0x1e,0xbb,0x99,0x3c,0x2d,0xa6,0x29,0x06,0x2a,0x47,0x3e,0xa3,0x89 +,0x8b,0x0e,0x0a,0x18,0x93,0xa0,0x2b,0x60,0xb1,0x16,0xe3,0x8d,0xd4,0x49,0xa7,0x87,0x1a,0x06,0x0d,0x48,0x9a,0xa2,0x96,0x97,0x2a,0x12,0x9f,0xc4,0x25,0x24,0x8e,0x98 +,0x0f,0x13,0x48,0x95,0xbd,0xb5,0x9b,0x2c,0x0b,0x31,0x59,0x2f,0xa2,0x87,0x88,0x16,0x07,0x19,0x9d,0xce,0x2d,0xb2,0xe1,0x13,0x4f,0x98,0x5a,0x5d,0x9c,0x8b,0x23,0x06 +,0x08,0xd6,0xaa,0xb7,0x98,0x97,0x1c,0x0e,0x98,0xb0,0xb3,0xa2,0x8a,0x9e,0x0c,0x12,0x59,0xa8,0xe2,0x5a,0xaf,0x1f,0x08,0xb7,0xa4,0xa1,0x9e,0x89,0x8c,0x0b,0x08,0x15 +,0xac,0xdd,0x29,0xad,0xdf,0x13,0xc1,0x99,0xb7,0xb8,0x93,0x84,0x20,0x05,0x0d,0x49,0xab,0xb8,0x9c,0xa1,0x16,0x24,0x9e,0xbc,0xba,0xae,0x83,0xaf,0x06,0x06,0x25,0x9c +,0x3b,0xc2,0xa6,0x24,0x12,0xa3,0xa2,0xa8,0xa1,0x86,0x8e,0x0c,0x09,0x16,0xa4,0x3f,0x2f,0xa0,0xab,0x10,0x2e,0x9f,0xad,0xc2,0x98,0x8a,0x16,0x07,0x0c,0xad,0xa7,0xca +,0x9a,0x9b,0x22,0x1a,0x9e,0xac,0xac,0xae,0x87,0xc9,0x06,0x08,0x24,0x9a,0x52,0xb0,0xa4,0x3f,0x15,0xac,0xb8,0x5f,0xb2,0x8c,0x90,0x0e,0x07,0x0f,0x9e,0xac,0xa8,0x96 +,0xa0,0x15,0x2d,0xa6,0xce,0xbd,0x9c,0x8d,0x16,0x07,0x0c,0xee,0xa6,0xb0,0x9d,0x99,0x24,0x29,0xa1,0xc9,0xa6,0xaa,0x88,0x52,0x06,0x05,0x27,0x97,0xb7,0xb0,0xa4,0x3e +,0x18,0xad,0xe6,0xb2,0xaf,0x8a,0x9e,0x0b,0x0d,0x1a,0x92,0xb1,0xac,0x9a,0xf9,0x0e,0x1b,0xc4,0xaa,0xa8,0x96,0x94,0x16,0x0c,0x10,0x9b,0xad,0xba,0x9f,0xab,0x27,0x1c +,0xa4,0xba,0xbe,0x9f,0x8c,0xb4,0x15,0x07,0x24,0xab,0xa6,0x9f,0xc6,0x25,0x0c,0xb2,0xcd,0xc8,0xab,0x8f,0x95,0x1c,0x10,0x1c,0xb2,0xb8,0xa5,0xaa,0x6e,0x0c,0x1e,0xd2 +,0xad,0x9a,0x97,0x90,0x25,0x13,0x16,0xad,0xa4,0xc8,0x3e,0xec,0x25,0x2d,0xa9,0x58,0xa3,0xa0,0x88,0xc0,0x10,0x0b,0x1b,0xa3,0x3e,0xbf,0x3e,0x33,0x1d,0xb8,0xaf,0x9f +,0x9a,0x90,0x9e,0x1f,0x15,0x1a,0xa9,0x31,0xc8,0x53,0x3c,0x19,0x24,0xb9,0xa6,0x95,0x92,0x92,0x37,0x19,0x0f,0x3e,0x27,0x2c,0x63,0xc9,0x1e,0x18,0x9b,0x9d,0x98,0x94 +,0x8c,0x9f,0x1d,0x09,0x14,0x31,0x51,0x40,0x3e,0x3f,0x19,0xbf,0xa2,0x98,0x9a,0x8e,0x94,0x2b,0x10,0x19,0x50,0x36,0x49,0x2f,0x26,0x13,0x25,0xa8,0xa1,0x9c,0x8f,0x8b +,0xbb,0x12,0x15,0x4a,0xc9,0x49,0x2c,0x37,0x21,0x22,0xb4,0xa8,0x9c,0x9d,0x91,0xab,0x1a,0x10,0x34,0xa4,0x35,0x2e,0x38,0x26,0x1d,0xe4,0xb2,0xa6,0xa6,0x93,0x9b,0x3a +,0x26,0x2e,0xb1,0x3f,0x2c,0x30,0x38,0x21,0x23,0xf5,0xa4,0xba,0x9b,0x99,0xbc,0x33,0x19,0xdc,0xda,0x69,0xc8,0xcd,0x29,0x1f,0xee,0xaf,0x37,0xc6,0x9a,0xb0,0x45,0x1d +,0xbe,0xba,0xc5,0xb3,0x2f,0x29,0x1e,0x30,0x34,0x41,0xb2,0x94,0x95,0xb7,0x1c,0x32,0xab,0xbb,0xb8,0x3c,0x3d,0x1e,0x2b,0xc7,0x4c,0xca,0x9b,0x9c,0x5b,0x1a,0x22,0xc1 +,0xb2,0xa6,0xd5,0xde,0x1f,0x2e,0x4f,0x31,0xe4,0xa9,0x9b,0xae,0x22,0x1e,0xa9,0xa1,0xb3,0x4f,0xc2,0x1c,0x18,0x1f,0x3c,0xb4,0xa3,0x8e,0x9f,0x4f,0x25,0xad,0xb3,0x78 +,0x29,0x2e,0x16,0x17,0x2c,0x4b,0xa6,0xdd,0x94,0xa1,0xa5,0x2c,0x3b,0xae,0xcc,0x51,0x49,0x2e,0x1c,0x4a,0x3d,0xb6,0x29,0xaa,0xab,0xa8,0xbb,0x4b,0x9e,0xb7,0x5f,0x4e +,0x2e,0x1d,0x25,0x1f,0x47,0x2a,0xa4,0x9b,0xa0,0xbd,0x28,0xa1,0xa7,0xbb,0x34,0x1d,0x1e,0x21,0x2b,0xbf,0x49,0xa9,0x9d,0xa0,0xab,0x2b,0xd9,0x76,0x43,0x7d,0x39,0x3b +,0x31,0x2c,0x47,0x26,0xcb,0x9d,0x9c,0x9f,0x24,0x49,0xe8,0xc8,0xae,0xcd,0xe6,0x2a,0x1f,0x1c,0x23,0xaf,0x97,0x9c,0xa3,0x28,0x31,0xcd,0xbb,0xb5,0x34,0x2b,0x1e,0x25 +,0x2d,0x4a,0xa3,0x9b,0x9b,0xa3,0x39,0x2b,0x28,0x38,0xc2,0xe2,0x36,0x24,0x29,0x48,0xce,0xa5,0x9a,0x9f,0xb6,0x25,0x1f,0x2c,0xb6,0xa4,0xc3,0x40,0x2b,0x28,0x2e,0x2e +,0xb2,0x9d,0xa0,0xb1,0x2f,0x3b,0x4e,0xa8,0xab,0x65,0x2b,0x18,0x22,0x32,0x55,0xb0,0xa5,0xaa,0xac,0xb9,0xad,0xdf,0x3d,0x53,0x47,0x35,0x23,0x2f,0x33,0x35,0xaf,0x9d +,0xa9,0xb9,0x27,0x51,0x59,0xcb,0xa3,0xdf,0x40,0x23,0x2f,0x58,0x38,0xca,0xaf,0x47,0x3f,0x2a,0xb5,0xad,0xb2,0xa1,0x4b,0x3b,0x29,0x2e,0xb9,0x3f,0x4a,0xb1,0x41,0xe2 +,0xd7,0xa0,0xa0,0x40,0x37,0x24,0x3b,0xed,0x3e,0xc8,0x2c,0x37,0xa6,0xb0,0xbf,0x34,0x5c,0xac,0x4a,0xcd,0x6c,0x37,0x5a,0x5a,0xac,0xe3,0x3a,0x3c,0x2f,0x39,0x38,0xb3 +,0x9f,0x48,0x3f,0xec,0xcf,0xa5,0xbd,0xd3,0x26,0x1e,0x36,0xcc,0x68,0xd0,0xa5,0x98,0xc8,0x24,0x32,0x2c,0xad,0xd0,0xea,0x25,0x1a,0xd6,0xa8,0x9f,0xa4,0xb5,0xb7,0x37 +,0x27,0x4a,0x2b,0x42,0x2f,0xf4,0xb7,0xdd,0xb6,0x3a,0x45,0xce,0xaa,0xa1,0xd9,0x29,0x2d,0x37,0xaf,0xb1,0xb8,0x42,0x1f,0x3d,0x49,0xb4,0xcd,0xce,0x9e,0xaa,0xcd,0x2e +,0x1e,0x57,0x54,0x64,0x28,0x1d,0x3f,0xef,0x9c,0x99,0xa4,0xa5,0xce,0xeb,0x2f,0x20,0x3c,0x24,0x3f,0x46,0xc4,0xa5,0x2c,0x3a,0x4f,0xab,0x95,0xb8,0x5d,0x13,0x1a,0xaf +,0xab,0xa6,0x37,0x42,0x3e,0x2d,0xbb,0xbd,0x55,0xb5,0xd7,0xa4,0x39,0x27,0x30,0x2f,0xcb,0xe5,0xa7,0xc9,0x2a,0x35,0xc0,0xa0,0x98,0xbc,0x6e,0x1a,0x21,0x3a,0x23,0x3f +,0x5f,0x98,0x9b,0x48,0x25,0x1f,0xa2,0xa2,0xb3,0x6a,0x0a,0x1a,0x3e,0xb4,0x8f,0x8e,0x92,0x24,0x0f,0x37,0xb9,0xa6,0x1b,0x21,0x1f,0x1d,0x9e,0x41,0x9d,0xa0,0x90,0x90 +,0x1d,0x1b,0x0e,0xf3,0xab,0x58,0xb0,0x0f,0xaf,0xac,0x60,0x94,0x9d,0x91,0x0f,0x10,0x22,0x20,0x9b,0x28,0xa5,0x4e,0x37,0x90,0x28,0xb3,0xb2,0x8e,0x9a,0x09,0x12,0x0d +,0xa9,0xa3,0xbd,0xb2,0x0c,0x98,0x93,0x98,0x90,0xca,0x66,0x05,0x14,0x2b,0xc3,0xc7,0x18,0xb1,0x22,0x90,0x86,0xaf,0x9f,0xcb,0xaf,0x0e,0x06,0x10,0x13,0x9b,0xaa,0x8d +,0x30,0x1e,0x8a,0x9d,0x8f,0xc9,0xac,0x14,0x02,0x17,0x19,0x9b,0x9a,0x98,0xc3,0x0e,0x99,0xa1,0xc4,0xca,0x36,0xbd,0x0e,0x1d,0x19,0xab,0x8a,0x8a,0xaf,0x0a,0x95,0x86 +,0xa2,0x5f,0xc1,0x1d,0x03,0x1b,0xbd,0xba,0xc9,0x28,0x2a,0x03,0x08,0xeb,0xab,0xa2,0x8c,0x8a,0x1f,0x18,0x3b,0xed,0x8e,0x87,0x82,0x9e,0x1b,0xa7,0xbd,0x99,0x92,0x9f +,0x0d,0x00,0x06,0x03,0x42,0x8f,0x85,0x68,0x07,0xcc,0x67,0x25,0x9c,0x88,0x9b,0x08,0x0a,0x0b,0x20,0x8a,0x82,0x84,0x17,0x24,0xa6,0x3a,0x97,0x8c,0x9a,0x08,0x0f,0x18 +,0x14,0xb0,0x99,0x96,0x12,0x1d,0x40,0x1c,0xad,0xc3,0x6d,0x1a,0xb9,0x9d,0x0b,0x0c,0x78,0x84,0x8f,0x9a,0x8b,0x27,0x4f,0x93,0x8d,0x22,0x05,0x38,0x1b,0x3c,0x9d,0x8c +,0xfb,0x0b,0x9f,0x2a,0x21,0xab,0xa0,0x0e,0x00,0x10,0x16,0x9e,0x8a,0x8a,0xbc,0x14,0x93,0xa4,0x9b,0x84,0x88,0xbc,0x02,0x25,0x2a,0xa5,0x8a,0x94,0xc8,0x00,0x1d,0x4d +,0x0e,0x61,0x9b,0xac,0x04,0x1b,0x2b,0x14,0xb6,0x9d,0x87,0x71,0x97,0x96,0x1f,0xa8,0x88,0x87,0x13,0x0c,0x0b,0x0d,0x9f,0x95,0x88,0xce,0xcd,0xa2,0x05,0x11,0x9d,0x85 +,0x2b,0x0b,0x18,0x0b,0xb8,0xad,0xa2,0x1a,0x3c,0x83,0x1d,0x0c,0xca,0x86,0xaf,0x19,0xb9,0x21,0x9b,0x8e,0x88,0xbe,0x1b,0x8c,0x47,0x0f,0x25,0xa9,0x1e,0x01,0x27,0x1b +,0xe2,0x9f,0x6e,0x1b,0x04,0x90,0x90,0x76,0x9e,0x9a,0xbd,0x08,0xaf,0xbf,0x23,0x91,0x8d,0x8e,0x1f,0x91,0x8a,0x1c,0xc2,0x9e,0xb7,0x02,0x0b,0x14,0x07,0xa7,0x8e,0x8f +,0x0e,0x15,0x92,0x10,0x19,0x96,0x87,0xbe,0x15,0x2f,0x08,0xb4,0x84,0x80,0x9c,0x14,0x9b,0x12,0x11,0x96,0x90,0x40,0x0e,0x26,0x07,0x19,0x93,0x8c,0xb0,0x07,0x98,0x9f +,0x20,0xd0,0x70,0x1e,0x0a,0xa9,0x2c,0x0c,0xd3,0x92,0x8d,0x4c,0x8c,0x8a,0x1e,0xc6,0xa2,0xab,0x19,0xb4,0xc0,0x0e,0xaf,0x99,0x9f,0x0e,0x1c,0x9b,0x14,0x1b,0x69,0xb0 +,0x0e,0x10,0xab,0x17,0xb4,0x8f,0x8f,0xb6,0x23,0x87,0xa3,0x39,0x98,0x95,0x27,0x03,0x43,0x1b,0x33,0x8b,0x8f,0x4e,0x01,0x19,0xae,0x3a,0x8e,0x89,0xc0,0x07,0x0d,0x1c +,0x11,0x93,0x8b,0x8f,0x1e,0x15,0x95,0x29,0xa2,0x84,0x8f,0x15,0x0b,0x39,0x0f,0x3f,0x8b,0x91,0xd1,0x0b,0xa3,0x24,0x0b,0x9c,0x8e,0xb0,0x10,0xd9,0x1f,0x0e,0xa7,0x96 +,0x95,0x47,0x2f,0x9f,0x08,0x24,0x8a,0x91,0x28,0x0e,0x32,0x0c,0xad,0x85,0x8b,0x98,0x17,0x9a,0x2c,0x13,0x95,0x94,0xcb,0x0f,0x1c,0x0b,0x0c,0xb1,0xc6,0x5f,0x1b,0xcd +,0x8b,0x19,0xb3,0x8b,0xa3,0x1f,0x43,0x94,0x27,0xa2,0x92,0xf0,0x24,0x17,0x8c,0xbc,0x0e,0xa4,0xb2,0x1c,0x0c,0xdd,0x20,0x13,0x99,0x9d,0xb3,0x16,0x2a,0x92,0x1b,0x9f +,0x89,0xa3,0x10,0x0c,0xbf,0x26,0x9a,0x84,0x99,0x2f,0x08,0xaf,0xb0,0x27,0x8c,0x8d,0x3c,0x06,0x10,0x12,0x18,0x93,0x8e,0xa4,0x0e,0x0d,0xaa,0x2d,0xa1,0x89,0x97,0x0b +,0x0a,0x4a,0x2e,0x9a,0x84,0x8f,0xd9,0x0d,0xb2,0x9d,0x21,0x8d,0x8b,0xb6,0x0b,0x18,0x18,0x0b,0xa7,0x90,0xae,0x20,0x0b,0xab,0x0b,0x13,0x8d,0xa1,0x36,0x0e,0x49,0x18 +,0x2a,0x81,0x88,0x91,0x2c,0xce,0x95,0x0f,0x91,0x84,0x9c,0x16,0x0a,0x17,0x04,0x23,0x95,0x3b,0x1c,0x0c,0x99,0xb1,0x1b,0x8f,0xa8,0x3b,0x13,0xb4,0xbe,0x1e,0x8f,0x96 +,0xbb,0x2d,0x2d,0x8c,0x1c,0x3d,0x93,0xa0,0x50,0x1f,0xa9,0x12,0x21,0x95,0xca,0xb0,0x1d,0xc8,0xa0,0x09,0xa7,0xb7,0x31,0x18,0x10,0x29,0x0b,0x9e,0x8c,0xc1,0xb3,0x1e +,0x8f,0xad,0xf3,0x83,0x9a,0xb8,0x11,0x31,0x23,0x19,0x8c,0x9f,0x31,0x11,0x1d,0x96,0x14,0xb6,0x9a,0x2b,0x0f,0x0a,0x2a,0x15,0xad,0x8a,0xae,0xbf,0x1a,0x9c,0x8c,0x27 +,0x8b,0x89,0xa0,0x1c,0x1b,0x27,0x0d,0xa1,0x8d,0xe1,0x23,0x0a,0xf6,0x19,0x18,0x8b,0x9a,0x6a,0x0a,0x1c,0x1b,0x1c,0x86,0x8f,0xb1,0x1a,0x23,0x94,0x1e,0x97,0x86,0xa1 +,0x19,0x0f,0x23,0x0b,0x7d,0x87,0xa8,0x2c,0x17,0xb8,0xc6,0x12,0x8f,0x90,0xc9,0x18,0x27,0x26,0x0a,0xaf,0x8e,0x6c,0x2b,0x1b,0xaf,0x11,0x21,0x84,0x8d,0x98,0x5d,0x5f +,0x0f,0x14,0x86,0x8c,0x9e,0x3d,0x19,0x3e,0x05,0x3d,0x8f,0xb8,0x1e,0x10,0x1a,0x08,0x38,0x8b,0xc7,0xc3,0x23,0x4c,0xb8,0x26,0x87,0x86,0x94,0x3e,0x35,0x1e,0x0e,0x9c +,0x8e,0xb9,0x52,0x16,0x4a,0x11,0x10,0x9b,0x9f,0x65,0x13,0x23,0x0f,0x16,0x8e,0x94,0xaa,0x33,0x1d,0xad,0x15,0xa2,0x86,0x8d,0xe7,0x16,0x39,0x19,0xae,0x86,0x9f,0x3d +,0x10,0x1e,0xc0,0x13,0x9a,0x92,0xd4,0x0f,0x11,0x1a,0x15,0x97,0x8c,0x57,0x28,0x0c,0x57,0xb8,0x42,0x87,0x91,0xce,0x18,0x1b,0x1b,0x2e,0x8a,0x93,0xb4,0xcb,0x20,0x98 +,0x1f,0xa9,0x8b,0xb7,0x43,0x0e,0x0d,0x06,0x22,0x8d,0x7b,0x2c,0x0c,0x0f,0x59,0x2f,0x88,0x8a,0x9b,0x24,0x1f,0x32,0x42,0x87,0x86,0xa8,0x37,0x0f,0x4a,0x64,0xd8,0x89 +,0xa7,0x23,0x0c,0x0e,0x0f,0x13,0x97,0xac,0x2a,0x21,0x0e,0x97,0x62,0xa8,0x87,0xa1,0x32,0x12,0x1f,0x15,0x4a,0x8b,0x9b,0x9d,0x41,0x3c,0xad,0x27,0x8f,0x8a,0xae,0x10 +,0x0f,0x17,0x16,0xab,0x94,0x4e,0x21,0x12,0x3b,0x43,0x2e,0x8c,0x9b,0x28,0x15,0x17,0x1d,0x2c,0x8c,0x91,0x40,0x3a,0x2a,0x99,0x4e,0x97,0x83,0xa6,0x29,0x1f,0x22,0x0f +,0x34,0x99,0x1f,0x2e,0x27,0x69,0xad,0x13,0x97,0x93,0x20,0x15,0x13,0x0e,0x0f,0x94,0x88,0xad,0xaf,0x39,0x9d,0xa5,0xa6,0x85,0x9f,0x1f,0x1b,0x1e,0x18,0x2a,0x8e,0x57 +,0x1a,0x13,0x0e,0xab,0x1e,0x9b,0x8a,0x42,0x29,0x1e,0x25,0x1b,0x9e,0x8e,0x2b,0x3f,0x1a,0xab,0x9d,0x49,0x88,0xa0,0x54,0xf8,0x22,0x18,0x13,0x98,0x9f,0x44,0xf4,0x26 +,0xa4,0x19,0xab,0x89,0x31,0x14,0x0e,0x11,0x0e,0xaf,0x88,0xc5,0x33,0x2a,0xab,0xae,0x2c,0x89,0x91,0x2c,0x25,0x44,0x21,0x29,0x8a,0x95,0x2b,0x15,0x12,0xae,0x17,0xca +,0x87,0x59,0x16,0x1e,0x26,0x13,0xe6,0x97,0x22,0x1e,0x20,0x97,0x9b,0x28,0x89,0x8c,0xce,0x4f,0x4c,0x13,0x15,0x8f,0x93,0x6c,0x1f,0x30,0xa0,0x16,0xa9,0x8c,0x1b,0x08 +,0x11,0x12,0x0d,0x9f,0x87,0xa8,0x28,0x23,0x9f,0xde,0x36,0x87,0x90,0x24,0x1f,0x3f,0x21,0x57,0x88,0x94,0x1d,0x0c,0x1a,0xa4,0x24,0x9d,0x8b,0x28,0x11,0x24,0x2f,0x1d +,0xb2,0xab,0x1f,0x21,0x22,0x9d,0xc4,0x25,0x8c,0x92,0x2b,0x1b,0x1b,0x17,0xc0,0x8c,0x8f,0xa2,0x28,0xa4,0x91,0x33,0x8f,0x8a,0x13,0x09,0x10,0x0b,0x15,0xab,0xa8,0x55 +,0x1e,0x1c,0xaf,0x1c,0x39,0x8a,0xa0,0x1f,0x22,0x2e,0x3d,0x96,0x87,0x99,0x2f,0x14,0xae,0x9d,0xd0,0x8c,0xa0,0x15,0x1a,0x2a,0x19,0x24,0xda,0x21,0x26,0x17,0x4f,0x9d +,0x1e,0x99,0x8f,0x66,0x25,0x1b,0x0f,0x17,0x8e,0x93,0x9c,0xae,0x29,0x8f,0xa9,0x9e,0x88,0x32,0x12,0x10,0x14,0x11,0xaf,0x8f,0xc5,0x5a,0x20,0xa9,0x32,0x18,0x8d,0xae +,0x15,0x18,0x10,0x0e,0xb6,0x86,0x9c,0x2e,0x0f,0x2d,0xa0,0xe6,0x87,0x8a,0x36,0x27,0xba,0x23,0x22,0x8e,0xdb,0x1c,0x1e,0x1f,0xa0,0x15,0xbd,0x89,0x2e,0x1d,0x1b,0x08 +,0x05,0xae,0x8f,0xb1,0xe5,0xe8,0x91,0x9f,0x9c,0x81,0xa0,0x14,0x25,0x1e,0x0e,0xd9,0x8e,0xab,0x57,0x30,0xa6,0x43,0x0c,0x9b,0x9d,0x11,0x19,0x18,0x0c,0x32,0x89,0x8b +,0xb0,0x16,0x2a,0x5f,0x23,0x95,0x8e,0x28,0x18,0xc9,0x50,0x33,0x92,0x9e,0x34,0x2a,0xfe,0x9c,0x22,0xc9,0x92,0x40,0x29,0x1f,0x0e,0x08,0x2e,0xa5,0xad,0x33,0x2d,0x9a +,0x3d,0x98,0x85,0xae,0x20,0x1c,0x16,0x0e,0xa3,0x90,0xaf,0xa1,0xa1,0x93,0xd7,0x41,0x99,0x3d,0x1b,0x22,0x14,0x06,0x27,0x8d,0x98,0xa2,0x2f,0x23,0x10,0x0f,0x8c,0x9d +,0x16,0x27,0x27,0x16,0xb6,0x86,0x90,0xa2,0x55,0xaf,0xa9,0x1d,0x8c,0x8f,0x15,0x2f,0x45,0x09,0x09,0x38,0xb1,0x9f,0xb9,0x3d,0x1a,0x0a,0x97,0x82,0xbe,0x20,0x5a,0x18 +,0x0e,0xb2,0x99,0x9f,0xaa,0xa4,0x9e,0x16,0xb5,0x80,0xbd,0x13,0xb9,0x4c,0x0c,0x17,0x1f,0xb0,0x90,0xa9,0xa4,0x09,0x0a,0x8b,0x97,0x28,0x15,0x17,0x1b,0x28,0xd6,0xbc +,0x9a,0x96,0x90,0x2d,0x17,0x8e,0x8f,0x6e,0x4d,0x29,0x23,0x41,0x3b,0x19,0x6f,0x8d,0x8b,0x30,0x01,0x25,0x98,0xb9,0xc6,0x26,0x12,0x1b,0x69,0x2a,0x27,0x9f,0x87,0x8c +,0x17,0x25,0x9d,0xaa,0xc4,0xab,0xb8,0xbd,0xa8,0x1c,0x13,0x2f,0x8e,0x86,0x25,0x0c,0x1d,0x1c,0xe9,0xd3,0x17,0x15,0xb9,0xb6,0x16,0x26,0x94,0x83,0x96,0x36,0xb3,0x29 +,0x30,0xb2,0xcd,0x24,0xa0,0x98,0x0e,0x09,0x7d,0x82,0x8a,0x19,0x21,0x1d,0x0e,0xbf,0x7d,0x19,0xb9,0x91,0x32,0x0a,0x0b,0x95,0x84,0xb6,0xaa,0xb7,0x14,0x1a,0x53,0x25 +,0xb6,0x87,0x95,0x17,0x0b,0xb1,0x81,0x95,0x58,0x5a,0x12,0x18,0x48,0x12,0x0d,0xa0,0x92,0x2c,0x07,0x0d,0x8d,0x8d,0xaf,0x9f,0x25,0x16,0x2e,0x36,0x21,0x95,0x86,0xa1 +,0x15,0x09,0x99,0x80,0x97,0xb6,0x78,0x15,0x23,0x27,0x10,0x23,0x98,0x9c,0x26,0x08,0x10,0x8c,0x97,0xcf,0xce,0x35,0x28,0x27,0x1f,0x2e,0x92,0x8e,0x4a,0x10,0x17,0x8b +,0x82,0xb9,0x3a,0xd2,0xc1,0x2b,0x0e,0x16,0xb9,0x99,0xe1,0x15,0x0a,0xdc,0x86,0xb0,0x28,0xd0,0xae,0x36,0x0f,0x16,0xd7,0x91,0xa1,0x30,0x15,0x1c,0x88,0x8a,0x3b,0xb9 +,0xaa,0xac,0x23,0x11,0x2a,0xa9,0x9a,0x38,0x19,0x0a,0xb2,0x8a,0xcc,0x36,0xb6,0xb1,0x26,0x0c,0x12,0xd1,0x97,0x9a,0x27,0x10,0x2b,0x86,0x8f,0xb3,0xaf,0xa0,0x9d,0x1d +,0x0c,0x21,0xa7,0x9e,0x2c,0x0d,0x10,0x9f,0x8f,0xdb,0x5b,0xac,0xa1,0x44,0x12,0x11,0xb6,0x91,0xaa,0x15,0x0b,0x24,0x8e,0x91,0xa4,0xb5,0x9f,0x98,0x33,0x18,0x20,0x9e +,0x97,0x1f,0x0b,0x14,0xbd,0x9a,0x44,0x30,0xa2,0x97,0xa7,0x2a,0x15,0x3c,0x9a,0xc3,0x19,0x0e,0x2b,0x9f,0xa0,0xc1,0x58,0xa0,0x99,0x9e,0xcc,0x1f,0xce,0xa4,0xda,0x19 +,0x15,0x3b,0xba,0xb4,0x4a,0xb7,0xa9,0xcf,0xb8,0x37,0x31,0x3f,0x24,0x28,0x30,0x4c,0x27,0x27,0xa2,0x97,0x99,0xa5,0xcb,0xa1,0x9d,0xb9,0x2c,0x1a,0x2e,0xb5,0xbf,0x1b +,0x0e,0x2b,0xa0,0x9a,0xae,0x2a,0x65,0xa0,0xa6,0x2a,0x0a,0x16,0x9b,0x96,0x7d,0x14,0x2d,0xa6,0xa5,0x9b,0xa9,0x9e,0x9c,0xb8,0x24,0x18,0x2d,0xb9,0xcf,0x32,0x36,0x2d +,0x1c,0x2b,0xac,0x9c,0x9b,0xa0,0xc4,0x19,0x1d,0x31,0x4e,0xb1,0xbe,0x4f,0x20,0x1e,0x2f,0xcc,0x98,0x8c,0x93,0xc0,0x28,0x3d,0x3b,0x2b,0xd6,0xa7,0xb6,0x31,0x19,0x0e +,0x2d,0xa4,0xa1,0xae,0xb6,0xac,0x37,0x1e,0x29,0xbf,0xaf,0xdc,0xc8,0x32,0x25,0x47,0x38,0x5e,0xa5,0x9b,0x9d,0xb1,0xcf,0x6b,0x4f,0xed,0xba,0x56,0x1e,0x2a,0xae,0x3c +,0x1b,0x20,0x6f,0xaf,0xae,0xab,0xc3,0xba,0xc3,0x39,0x1f,0x36,0xad,0xae,0xf6,0xc6,0xbb,0x2a,0x29,0xc1,0xa5,0xab,0xad,0xab,0x4b,0x24,0x39,0x2a,0x2e,0xb1,0xae,0xc7 +,0x42,0xef,0xcf,0x59,0x69,0xed,0x2e,0x21,0xfe,0xac,0x42,0x2d,0x69,0xda,0xec,0xb6,0xae,0xa1,0x9a,0xac,0x43,0x25,0x2e,0x37,0x28,0x42,0xb0,0xae,0x3d,0x21,0x2e,0x6a +,0xa9,0xa6,0xbb,0x59,0x2f,0x38,0x31,0x4f,0xd8,0x57,0xbd,0x3c,0x38,0xb7,0xad,0xa0,0xad,0x51,0x2d,0x29,0x3d,0xdf,0xb5,0xb8,0xaf,0xc4,0x1b,0x27,0xb4,0xa3,0xaf,0x4c +,0x39,0x2e,0x39,0x20,0x27,0xc0,0xa2,0xa7,0x59,0x3b,0xbd,0x9f,0xa0,0xb1,0xd0,0x39,0x25,0x1c,0x1f,0xc3,0xa2,0xb2,0x2d,0x23,0x61,0xb8,0xa7,0xb4,0x72,0xc6,0x5f,0x2e +,0x2c,0x2e,0x5a,0xa4,0xaf,0x3e,0x40,0xe2,0xde,0xb4,0xae,0xd4,0x3e,0x2a,0x2b,0x40,0xcf,0xa2,0xa7,0x6b,0x2f,0x6d,0xaf,0xb5,0xb8,0x2a,0x2c,0x30,0x2c,0x2a,0x29,0xbb +,0xa7,0xad,0x51,0x4f,0xb3,0xc1,0xb3,0xad,0xb2,0xdd,0x1f,0x2a,0xec,0xb5,0xad,0x46,0x40,0xbd,0xb0,0x4d,0x32,0x3d,0x39,0x36,0x2a,0x34,0xc3,0xbf,0xb3,0xad,0xf3,0x3f +,0xfd,0xb7,0xab,0xaf,0x3a,0x32,0x34,0x23,0x36,0x70,0xa5,0x9e,0xce,0x2b,0xcb,0x9c,0xab,0x40,0x2c,0x48,0x68,0x2c,0x1e,0x2a,0xbe,0xb1,0xbe,0x42,0x5c,0xa7,0x55,0x48 +,0xbe,0x43,0x30,0x21,0x37,0xea,0xa8,0xa5,0xc5,0xca,0xd2,0xa4,0xaa,0xaf,0xb5,0x2f,0x26,0x23,0x33,0x27,0x29,0xa7,0xae,0x39,0x2e,0xc3,0xa3,0xb2,0xb4,0x43,0x36,0x3a +,0x20,0x1f,0x3a,0x9b,0x9e,0x3b,0x39,0xa0,0x93,0xb4,0x3e,0x3f,0x44,0x31,0x1b,0x1f,0x2d,0xb6,0xaa,0x3b,0x31,0x48,0xa6,0x9f,0xa5,0xa5,0x60,0x2a,0x1e,0x22,0x26,0x46 +,0xa2,0xb5,0x26,0x26,0xaa,0x96,0x9e,0xd3,0x2a,0x3c,0xca,0x33,0x1a,0x27,0xaa,0xad,0x39,0x2b,0xa5,0x92,0xa6,0xce,0x49,0x3d,0x2c,0x1e,0x25,0x38,0xb1,0xd0,0x1e,0x1e +,0xca,0x97,0x9a,0xad,0xc9,0x47,0x38,0x36,0x2d,0x2f,0xb4,0xa4,0xdd,0x2f,0x31,0xa5,0x9a,0xac,0x37,0x24,0x45,0x34,0x22,0x1f,0x5b,0xa2,0x5e,0x1c,0x2b,0x9c,0x8c,0x9b +,0x36,0x24,0x4d,0xf1,0x30,0x2c,0x50,0xa6,0xcf,0x22,0x2c,0xbc,0x9f,0xa0,0xbf,0x3c,0x33,0x24,0x1f,0x2b,0x45,0xc7,0xbc,0x47,0x2d,0xac,0x91,0x94,0xb7,0x22,0x29,0xce +,0xc1,0x4f,0x27,0x29,0x3f,0x2e,0x1e,0x3e,0x93,0x8e,0xab,0x1e,0x27,0x37,0x2b,0x2e,0x3a,0xaf,0xa7,0x40,0x19,0x2a,0x97,0x8b,0x93,0xb3,0x1f,0x1c,0x29,0x2f,0x39,0x38 +,0x4b,0x42,0x26,0x1d,0xae,0x90,0x94,0xab,0x2a,0x1e,0x1f,0x34,0x47,0x3d,0xb2,0xd3,0x24,0x1c,0xbe,0x8a,0x88,0x9b,0x2f,0x1f,0x1f,0x24,0x24,0x27,0xee,0xc8,0x27,0x19 +,0x31,0x99,0x8f,0x97,0xb9,0x25,0x25,0x33,0x2e,0x29,0x52,0xb7,0x4d,0x23,0x2c,0x99,0x8b,0x92,0xb1,0x21,0x1d,0x25,0x50,0x27,0x1c,0x2e,0x2c,0x1e,0x2a,0x9e,0x8d,0x8f +,0x9d,0x37,0x21,0x2f,0x32,0x35,0x32,0x49,0x39,0x1f,0x2c,0x9f,0x8e,0x91,0x9e,0x36,0x1d,0x2b,0x2a,0x38,0x3b,0x24,0x19,0x13,0x29,0xa3,0x90,0x8d,0x97,0xcb,0x24,0x38 +,0xb6,0xc0,0xeb,0x61,0x28,0x12,0x1b,0xdc,0x97,0x8f,0x9a,0x5f,0x1c,0x21,0x4b,0x46,0x3b,0x48,0x22,0x1b,0x19,0x37,0x9b,0x8e,0x8e,0xaf,0x26,0x4b,0xbc,0xb2,0xb1,0x72 +,0x29,0x13,0x19,0x4d,0xa9,0x94,0x96,0x41,0x1e,0x2d,0x3e,0xf3,0xcd,0x2b,0x27,0x21,0x1f,0x57,0xab,0x96,0x92,0x9d,0xb8,0x2a,0x34,0xb6,0xaa,0x4e,0x1e,0x1c,0x21,0x33 +,0xb9,0x9f,0xa1,0xaf,0x3b,0x25,0x36,0xc5,0x4f,0x2e,0x2a,0x5d,0xed,0x32,0xbf,0x9e,0x96,0x97,0xa4,0x56,0x24,0x2b,0x5d,0x46,0x41,0x23,0x1f,0x1c,0x24,0xbd,0x9f,0x9d +,0xb3,0xe2,0x2a,0x28,0xc2,0xab,0xab,0xaf,0x2e,0x3e,0xc8,0xba,0xa2,0xa6,0xaf,0x33,0x14,0x0f,0x2b,0xa4,0x9a,0xa9,0x1b,0x0d,0x15,0xee,0x8f,0x94,0xa8,0xc4,0x3f,0x43 +,0xa9,0x8e,0x8f,0xa7,0x16,0x07,0x09,0x1d,0x9d,0x9e,0xeb,0x41,0x4b,0x48,0x3f,0xa8,0x94,0xb4,0x1d,0x13,0x2e,0x96,0x93,0x9a,0xa9,0x68,0x3f,0x24,0x37,0xa4,0xaf,0x1a +,0x06,0x09,0x22,0xa4,0x96,0x9a,0xa4,0x38,0x41,0xbb,0x9d,0x8c,0x99,0xd1,0x27,0x1f,0x2f,0x1f,0xcb,0x99,0xa4,0x29,0x0a,0x0c,0x35,0xa4,0x9f,0x9e,0xd6,0x24,0x14,0x1e +,0xa0,0x8b,0x8e,0xaf,0x35,0xd9,0xaf,0xc1,0xa6,0x9f,0xa0,0x19,0x09,0x0a,0x17,0x45,0x31,0xad,0x99,0x9a,0x2f,0x1c,0xaa,0x9b,0x9d,0xc5,0x23,0xe1,0x2c,0x28,0xaf,0x8f +,0x83,0xaf,0x0b,0x0b,0x24,0xa8,0xb1,0x17,0x0e,0x23,0x25,0xa6,0x8f,0x8c,0x98,0x1e,0x18,0x6a,0x99,0x98,0x67,0xfb,0xe3,0x2f,0xbf,0x50,0xa5,0xbd,0x14,0x0b,0x14,0x17 +,0x1e,0x9d,0x9e,0x94,0x33,0x1c,0x92,0x97,0x9d,0x34,0x23,0x9d,0xaf,0x3a,0x38,0x3c,0x8e,0x9a,0x1d,0x0e,0x17,0xb6,0x50,0x08,0x0b,0x97,0x8d,0x8b,0x31,0x3c,0x93,0xb5 +,0xa6,0xa4,0x48,0xa6,0x19,0x40,0x92,0x9d,0x96,0x17,0x08,0x13,0x1b,0x29,0x94,0x17,0x26,0x46,0x2d,0x8a,0x9f,0xc8,0x8f,0x1e,0x05,0x07,0x04,0x8e,0x98,0xa6,0x32,0x03 +,0x92,0x96,0xd2,0xa2,0xce,0xa1,0x49,0x1d,0x92,0x82,0x80,0xaf,0x06,0x9f,0x4d,0xa1,0x87,0x1e,0x9b,0x89,0x0d,0xbd,0x9d,0x4e,0x1f,0x00,0x01,0x06,0x07,0x07,0x02,0x01 +,0x94,0x0e,0x0e,0x95,0x2f,0x96,0x1d,0x0a,0x93,0xbb,0x95,0x93,0x54,0x81,0xb4,0xcf,0x84,0x94,0x8b,0xc8,0x1e,0x8d,0x90,0x83,0x81,0x8e,0x84,0x84,0x97,0x8a,0x9a,0x8f +,0x94,0x00,0xcc,0xa8,0x3e,0xa2,0x07,0x0a,0x0a,0x00,0x05,0x16,0x0b,0x0d,0x00,0x1e,0xa5,0x02,0x1c,0x06,0x11,0x15,0x06,0xb0,0x1c,0x9f,0x82,0xbc,0x9d,0x88,0x8c,0x80 +,0x93,0x8c,0x8b,0x1b,0x99,0x88,0x8a,0x80,0xaf,0x9f,0x83,0x9b,0x8e,0x16,0x68,0x97,0x2a,0x9f,0xb1,0xa1,0x98,0x10,0x0c,0x0d,0x05,0x07,0x02,0x00,0x0c,0x04,0x14,0x50 +,0x05,0x9d,0x1b,0x05,0x10,0x01,0x55,0x23,0x1d,0x8b,0xa2,0x98,0x8f,0x94,0x86,0xa9,0x19,0x34,0x2e,0x9f,0x9d,0x4f,0x80,0x9a,0x9f,0x80,0x8f,0x84,0xac,0x91,0x84,0xa6 +,0x87,0x8f,0x8f,0x9a,0x1a,0x2d,0x14,0x08,0x0c,0x0c,0x03,0x08,0x00,0x2f,0xab,0x00,0xa7,0x1d,0x07,0x03,0x01,0x1b,0x10,0x1c,0x9d,0x1c,0x48,0xa7,0xb9,0x88,0x2e,0x2e +,0xdf,0x1d,0x8f,0x9c,0xa3,0x80,0x8a,0x88,0x86,0x8c,0x86,0xa1,0x99,0x8c,0x22,0x8d,0xc2,0x94,0x8c,0x9c,0x9e,0x0b,0x0a,0x12,0x2f,0x1d,0x18,0x01,0xa3,0x17,0x0a,0x29 +,0x3c,0x40,0x04,0x04,0x04,0x00,0x98,0x91,0x36,0x9a,0x06,0x0b,0x0e,0xcb,0x98,0x9e,0xbb,0x0f,0x0d,0x8a,0x82,0x94,0x80,0x99,0x29,0x0f,0x1b,0x81,0x89,0x8a,0x99,0x1d +,0x89,0x88,0x80,0x89,0x92,0xb1,0x0b,0x03,0x26,0x9f,0x90,0xa7,0x07,0x13,0x08,0x0f,0x16,0x0f,0x1c,0x0a,0x00,0x12,0x18,0x92,0x97,0x14,0x01,0x09,0x29,0x0b,0x15,0x18 +,0x09,0x2e,0x88,0x91,0x8c,0x9e,0x9a,0x95,0x57,0xdd,0xb6,0x90,0x80,0xa1,0x8e,0x85,0x80,0x86,0x9e,0x39,0x29,0xda,0x17,0x30,0xa1,0x80,0x10,0x0c,0x4d,0x8a,0x8f,0x28 +,0xaa,0x03,0x03,0x23,0x87,0x96,0x12,0x1c,0x00,0x06,0x06,0x24,0x3a,0x0d,0x16,0x00,0x0f,0x0d,0x8c,0x85,0x5d,0x0b,0x00,0xb7,0xb5,0x8b,0x84,0x8d,0x9d,0x2e,0xa5,0x8d +,0x81,0x86,0x8c,0xba,0x09,0x14,0x87,0x80,0x99,0x95,0x9e,0x94,0x98,0x9c,0xa3,0x25,0x39,0x9d,0x0f,0x38,0xaa,0xae,0x2e,0x05,0x0e,0x0a,0x48,0x0e,0x04,0x07,0xe6,0x12 +,0x0c,0xb6,0x2c,0x0a,0x04,0xbd,0x1d,0x9d,0xa0,0xa4,0x19,0x12,0x9e,0xb5,0x9d,0x42,0xae,0x33,0x31,0xfd,0x8f,0x80,0x8e,0x8a,0x2e,0x5d,0x98,0x8f,0x80,0xce,0x1e,0x34 +,0x8c,0x90,0x8c,0x83,0xdd,0x30,0x11,0xca,0x9c,0x9c,0x1a,0x01,0x25,0x0b,0x1f,0xb6,0x91,0x2e,0x00,0x0a,0x0a,0x14,0x32,0xad,0x0d,0x05,0x08,0x07,0x1c,0xad,0x42,0x19 +,0x0d,0x11,0xbf,0x88,0x86,0x92,0x8c,0xa4,0x21,0xb7,0x85,0x88,0x8b,0x8e,0x96,0x8b,0x8c,0x8b,0x8e,0x92,0x20,0x0d,0x24,0x76,0x22,0x16,0x2b,0x2f,0x9b,0x99,0xb4,0x5f +,0x0c,0x23,0x20,0x47,0x2a,0x22,0xbb,0x0f,0x15,0x0e,0xc5,0x2d,0x2c,0x4b,0x08,0x06,0x15,0x98,0x28,0x2e,0x25,0x10,0x1a,0x2e,0x98,0xa7,0x9e,0x93,0x48,0x2f,0xa7,0x95 +,0x89,0xa5,0x0d,0x1e,0x9c,0xb8,0x90,0x8c,0x86,0x97,0x9a,0x96,0x84,0x82,0xea,0xa8,0x2c,0x4f,0x56,0x8d,0xa1,0xa3,0x56,0x17,0x1a,0x03,0x1d,0x22,0x09,0x00,0x06,0x18 +,0x17,0x1e,0x2a,0xb0,0x28,0x07,0x2c,0xb0,0xaf,0x18,0xbc,0x3d,0x0f,0xbb,0x4b,0xa6,0xa8,0xd3,0x27,0x48,0xc3,0x98,0x86,0x8e,0x9e,0x8e,0x89,0x29,0x9e,0x8e,0x97,0x97 +,0xa4,0x9a,0x91,0x8e,0xa2,0x67,0xc0,0x24,0x0c,0x0e,0x28,0x1a,0x14,0x40,0x32,0xbe,0x97,0x8d,0x24,0x0d,0x3d,0xcb,0x26,0xd4,0x1a,0x26,0x0f,0x27,0x2e,0x36,0xce,0x0d +,0x1d,0x10,0x09,0x17,0x98,0x15,0x27,0x16,0x27,0xa8,0x9b,0xa1,0x9a,0x8f,0x98,0x92,0xc8,0x85,0x87,0x8f,0x2e,0x26,0x3a,0xdf,0x8d,0x9e,0x9e,0x8b,0x96,0x21,0xd4,0x8e +,0x8f,0xb4,0x12,0x14,0xb0,0x44,0x0f,0xb4,0xb5,0x2d,0x18,0x2f,0x0c,0x0e,0x28,0x04,0x09,0x06,0x14,0x13,0x1c,0x5b,0x39,0x3b,0x1f,0xdf,0x99,0x45,0x99,0x9d,0xba,0xa2 +,0x2c,0x98,0x96,0x92,0xa0,0xb5,0x93,0x9c,0x94,0x9a,0xa6,0x91,0x9c,0xca,0x98,0xbd,0xdc,0xa4,0xaf,0x48,0x8f,0x9f,0xac,0x23,0x21,0x90,0x38,0x42,0x0f,0x18,0x10,0x0f +,0x2f,0x33,0x1a,0x28,0x25,0x0c,0x23,0x0c,0x2a,0xa7,0x09,0x08,0x17,0x2a,0x57,0xce,0x98,0x91,0xe6,0x99,0x23,0xce,0x8e,0xa3,0x9b,0x20,0x2e,0xa2,0x97,0xac,0x8f,0x9b +,0x9d,0x3e,0xab,0x89,0x93,0x90,0xa6,0x2a,0x2d,0x96,0xab,0x90,0x2c,0x1a,0x9b,0x3c,0x28,0x15,0x23,0xa0,0xb7,0x07,0x06,0x0d,0x1a,0x25,0x27,0x2c,0x42,0x9f,0xbd,0xde +,0xac,0xb5,0x30,0xb9,0x1b,0x0f,0x1c,0xe7,0x1e,0x13,0xb4,0x34,0x21,0xbe,0x11,0x27,0xa0,0xaf,0xc7,0x0f,0x99,0x84,0x98,0x8d,0x8e,0x8c,0x8b,0x97,0x8e,0x9a,0x8e,0x94 +,0xa5,0x14,0x2e,0x3b,0x4a,0x29,0x11,0xa2,0x46,0x0b,0x0a,0x15,0x3d,0x9c,0x1a,0x06,0x10,0x24,0x15,0x1b,0xfb,0xde,0x1c,0xd2,0x0c,0x20,0x9e,0xa4,0x9a,0x0e,0x1a,0x26 +,0x91,0x92,0xa7,0x8d,0x8b,0x8d,0xc1,0xb2,0x91,0x94,0x8a,0x9e,0x1b,0x16,0x8e,0x98,0xca,0x3f,0x1c,0xa6,0x1a,0x1f,0x15,0x1f,0x48,0x28,0x1e,0x18,0x1b,0xa9,0x6a,0x34 +,0x91,0xa5,0x9b,0xba,0x25,0xc8,0x9d,0x9c,0x18,0x09,0x1b,0xc5,0x3b,0x23,0x21,0x28,0xa2,0x49,0x23,0x26,0x9f,0xa4,0xbc,0x27,0x13,0xbe,0x3c,0xc2,0x9b,0xa0,0x93,0xda +,0x1b,0x15,0x24,0x8c,0x96,0x19,0x07,0x1c,0xcc,0x91,0x8d,0x9d,0x9b,0x93,0x94,0xb6,0x98,0x85,0x9a,0xaf,0x62,0x29,0xbf,0x49,0x29,0x0f,0x1b,0x27,0x0f,0x06,0x10,0x60 +,0xaf,0x32,0x0e,0x0a,0x15,0x39,0x9a,0xa1,0x4e,0xa6,0xa8,0xaf,0x96,0x99,0x99,0xa3,0x4d,0x13,0x1f,0x9f,0x46,0x19,0x27,0x94,0xa6,0x3c,0x14,0x30,0x8c,0x8a,0x9d,0x2d +,0x1f,0xa9,0x94,0xa3,0x39,0xed,0xd6,0xa8,0x26,0x12,0x38,0x2c,0xaf,0x13,0x0f,0x1e,0x1a,0x1b,0x32,0x42,0x8e,0x93,0x3e,0x14,0x32,0x8a,0x88,0x9c,0x0f,0x19,0x21,0xac +,0xa5,0x2a,0x25,0xcc,0x1f,0x35,0xfd,0xaa,0x9c,0xb8,0x13,0x18,0x9c,0x41,0xa4,0xbc,0xa6,0x9a,0x9a,0xf7,0x1a,0xb8,0x96,0x97,0x20,0x07,0x15,0xcf,0xb4,0xb4,0x1b,0x25 +,0xaf,0x4a,0x2f,0xb8,0x97,0x8c,0x90,0x40,0x20,0xa8,0xa8,0xab,0x3e,0x4d,0xa1,0x24,0x10,0x12,0x28,0x9a,0xa2,0x15,0x05,0x13,0x9e,0x9d,0x38,0x2a,0xbc,0x98,0xa0,0x38 +,0x54,0x9a,0x92,0x52,0x19,0x11,0x25,0xad,0xaf,0x1e,0x25,0xa7,0xa4,0x28,0x19,0x9e,0x88,0x8d,0x2b,0x11,0xb3,0x86,0x8f,0x3a,0x3b,0x9c,0x92,0x69,0x1b,0x19,0xad,0x9b +,0x17,0x0b,0x1e,0xab,0x2c,0x16,0x1d,0xcb,0x8f,0xa6,0x1b,0x50,0x8f,0x8d,0xc7,0x24,0x3f,0xe1,0xa2,0x23,0x0b,0x27,0x9d,0xf1,0x13,0x1f,0x3d,0xce,0xe8,0x58,0x1f,0x6a +,0xac,0x44,0xfe,0xaf,0x95,0xa2,0x2c,0x34,0xbf,0x9a,0x99,0x19,0x0e,0x1e,0xaf,0xe9,0x16,0x1c,0xc6,0xaf,0x6c,0x2b,0xa7,0x8c,0x9d,0xa5,0x5d,0xec,0x9f,0x96,0xb8,0x1a +,0x2b,0x3c,0x1e,0x1d,0x66,0x39,0xb5,0x43,0x1d,0x1c,0x26,0x9e,0xae,0x2d,0x60,0xa9,0x9e,0xa8,0xd0,0x9b,0x91,0xd0,0x27,0x1c,0x1e,0xa5,0xb4,0x13,0x10,0x1f,0x36,0x31 +,0x21,0xb7,0xa9,0xc7,0x2c,0xd2,0x90,0x8b,0x8f,0x23,0x1b,0xa9,0x9e,0xd9,0x20,0x34,0xaa,0x40,0x10,0x14,0x4f,0x99,0xa6,0x1d,0x1a,0x5c,0x98,0xb0,0xc7,0x9f,0x95,0x9e +,0x4b,0x4e,0x58,0xa0,0xaa,0x29,0x17,0x29,0xc7,0x24,0x25,0x39,0x2d,0x2a,0x24,0x32,0xaf,0xd6,0xa4,0x98,0xb0,0xa1,0x9b,0x9c,0x48,0x1c,0x28,0xd5,0x43,0x35,0x4e,0x1b +,0x2e,0x3f,0x3f,0x21,0x42,0xad,0xcc,0xac,0x21,0xb1,0x8d,0x90,0xa3,0xaf,0xa5,0xbd,0x2e,0x15,0x13,0x3e,0x97,0xc3,0x17,0x38,0x6f,0x24,0x16,0x1c,0xcf,0xa8,0x45,0x31 +,0x9c,0x91,0x9f,0xb1,0x9a,0xb8,0x28,0x21,0x16,0x24,0x61,0x36,0x18,0x2b,0xb1,0xe5,0x2f,0x30,0x59,0x9c,0xa2,0x2a,0x44,0x96,0x8d,0x9b,0x9e,0xb3,0x25,0x1e,0xb3,0xbb +,0x42,0x2b,0x21,0xbe,0x3e,0x36,0x27,0x34,0x37,0x25,0x3f,0xed,0xbe,0xa9,0x97,0x9c,0x9f,0x93,0x92,0x4c,0x10,0x0e,0x2d,0xd1,0x16,0x22,0x34,0x26,0x2e,0x31,0xb9,0x22 +,0x49,0x9b,0xd6,0x66,0xb6,0x95,0x8f,0x9e,0xbb,0xc2,0x39,0x2a,0x36,0xb0,0x1d,0x0b,0xe3,0xac,0x3a,0x31,0x22,0x1f,0x37,0xbd,0xa4,0xba,0xa8,0x95,0x97,0x9b,0x9e,0x94 +,0x94,0x1b,0x08,0x19,0xe5,0x4d,0x15,0x22,0x29,0x1e,0x67,0xca,0xc1,0x31,0x3d,0xb5,0xae,0xaf,0xb6,0x9a,0x8d,0x95,0xb8,0x4b,0x1a,0x29,0x43,0x21,0x14,0x24,0x9c,0x2e +,0x11,0x25,0xcd,0x9f,0x9f,0x3d,0x4a,0xa4,0xa9,0x9e,0x8f,0x93,0x5d,0xba,0xab,0x18,0x1a,0x1c,0x28,0x2c,0x28,0x20,0x1a,0xd2,0xa4,0xa4,0xe7,0x23,0x27,0x9f,0x97,0xbc +,0xa5,0x8d,0x9e,0x41,0xc5,0x3e,0x23,0x27,0x1f,0x19,0x1c,0x1b,0x2c,0xb8,0xbd,0xde,0x34,0x5d,0xa8,0xbe,0xa9,0xa9,0x3a,0xab,0x92,0xac,0xb9,0xf7,0x43,0xaa,0xb8,0xc2 +,0x15,0x13,0x12,0x15,0xb7,0x9c,0xae,0x2a,0x2b,0xad,0x93,0x9d,0xa6,0x23,0x20,0xa3,0x96,0xb3,0x35,0xac,0x3f,0x21,0x1c,0x37,0xce,0x14,0x0f,0x20,0x51,0xac,0x9b,0x9a +,0xa9,0xcd,0xb0,0xa0,0xa5,0xb5,0x56,0xca,0xe1,0x53,0xa5,0xc6,0x30,0x1e,0x1d,0x27,0x0d,0x16,0x9f,0x98,0x2f,0x47,0xa2,0x95,0x97,0xb6,0xb8,0x33,0xaf,0xbe,0xe6,0xf9 +,0x2f,0xba,0x32,0x3f,0xfd,0x22,0x15,0x17,0x17,0x52,0x9c,0x3d,0xea,0xa3,0xa8,0x52,0x9f,0x8f,0x54,0x21,0x39,0xa9,0x97,0x52,0x1c,0x2e,0x30,0x1f,0x1a,0x2a,0x28,0x23 +,0xad,0xa4,0xac,0x9c,0x99,0x92,0xa2,0xb9,0xb7,0x1d,0x2e,0xa6,0xb2,0x26,0x1c,0xa9,0xa3,0x1d,0x11,0x19,0x1f,0x1e,0x3a,0xaa,0xaa,0xcd,0xae,0x97,0x8e,0x9d,0xb3,0xc7 +,0x14,0x1c,0xde,0x9e,0x9c,0x1c,0x17,0x29,0x2f,0x34,0x6b,0x37,0x16,0x1a,0xbc,0x99,0x9e,0x98,0x9a,0x9a,0xca,0x2b,0x48,0xbd,0x41,0x3c,0x9f,0x1f,0x17,0xb8,0xa2,0x2a +,0x17,0x17,0x4d,0x32,0x19,0xbc,0x8d,0x96,0xcc,0x9c,0x98,0x9d,0xa8,0xac,0x23,0x1f,0x23,0x57,0x51,0x2c,0x4e,0x29,0x1d,0x1d,0xb4,0x33,0x0e,0x1f,0x95,0x92,0xb0,0xc1 +,0xdc,0x94,0x95,0xd5,0x54,0x32,0xea,0x2d,0xdb,0x26,0x29,0xad,0xea,0x17,0x19,0xcb,0x4e,0x3e,0x29,0xb3,0xa1,0xa0,0x9e,0x94,0x99,0xd1,0x49,0x4d,0x27,0x29,0xbf,0xa8 +,0xc3,0x19,0x18,0x28,0x20,0x1e,0xc3,0x49,0x18,0x1e,0x9d,0x9c,0xac,0x97,0x96,0x90,0x9e,0xd7,0x32,0x2a,0x32,0x3b,0xaf,0x24,0x15,0xf3,0xd8,0x1e,0x22,0x6c,0x27,0x2b +,0x36,0x9c,0x9c,0x58,0xad,0x94,0x92,0x37,0xea,0xae,0xc2,0x2f,0x35,0xac,0x3c,0x1c,0x2f,0x2e,0x1f,0x22,0x27,0x37,0x19,0x31,0x98,0x96,0xbb,0xb6,0x9a,0x9f,0x4a,0x2a +,0xd0,0xbe,0x34,0xcd,0xbc,0x1c,0x22,0xcb,0x44,0x1c,0xde,0xb2,0xc5,0x20,0x23,0xa3,0x9d,0x9d,0xaa,0x97,0xb2,0x2b,0xcc,0x9e,0xb2,0x39,0x46,0xb6,0x52,0x1e,0x36,0x37 +,0x1a,0x16,0x47,0xd0,0x2e,0x28,0x9f,0x99,0x54,0xcf,0xac,0x45,0x2c,0xa6,0x9a,0x76,0x22,0x4b,0x97,0xbd,0x25,0xe0,0x2c,0x1c,0x22,0xce,0x3f,0x26,0x29,0x9d,0x9d,0x47 +,0xbb,0xb6,0x67,0x2b,0x9b,0x97,0xb8,0x31,0x33,0x47,0x31,0x62,0xc2,0xde,0x15,0x17,0x40,0xa7,0xe7,0xbe,0x98,0xcd,0x25,0xc6,0x9c,0xbd,0x2f,0xba,0xa5,0x42,0xc8,0xb7 +,0xa2,0x4f,0x24,0x33,0x22,0x1e,0x2b,0xbc,0x27,0x21,0x3d,0x9e,0xb2,0xb8,0xa6,0xea,0x2b,0x2c,0xa0,0xa4,0xde,0xc5,0xe5,0xcf,0x3f,0x3d,0xa9,0xa8,0x2a,0x1c,0xa0,0xae +,0x25,0x30,0xba,0x35,0x1f,0xaa,0x9c,0x2b,0x14,0x38,0xa7,0xa3,0xbf,0xa5,0xa8,0x1e,0x28,0xbc,0x3d,0x2d,0xcc,0x9c,0x54,0x2b,0xa8,0xd4,0x4c,0xc7,0xad,0x45,0x23,0x1e +,0x49,0xa2,0xd3,0x42,0x6d,0xc8,0x58,0xa9,0xae,0x3e,0x2e,0xd3,0xab,0xc1,0xe6,0x4e,0x4d,0x3b,0xc5,0xd6,0xdc,0x21,0x29,0xaa,0xa6,0x44,0x30,0xa3,0xd9,0x1c,0x2c,0xc1 +,0x3f,0x27,0xa8,0x9a,0xbe,0xb6,0xac,0x9f,0xc4,0x39,0x39,0x3a,0x1b,0x18,0xaa,0xab,0x26,0x28,0x46,0xc3,0xb3,0xab,0xb0,0x1d,0x20,0x39,0x44,0xaa,0xb3,0xbd,0x9d,0xc3 +,0xf6,0x96,0x9f,0x1f,0x23,0xb9,0xbe,0xc6,0x4e,0x33,0x1f,0x2f,0xc3,0xc4,0xe7,0x25,0x3e,0xa5,0x9c,0xa7,0xed,0x4c,0x28,0x2a,0xb3,0xa4,0x5c,0x2b,0x42,0x35,0x3f,0xb2 +,0xa9,0xca,0x2a,0x2f,0x2f,0x2d,0x3b,0xb3,0xaa,0xdd,0xbf,0xa9,0x56,0x32,0xb8,0xa1,0xb0,0x1b,0x21,0x4d,0x31,0x65,0xae,0xd4,0x57,0xf1,0x4c,0x52,0x38,0x3c,0xac,0xb3 +,0xd4,0xae,0x33,0x26,0x2f,0xab,0x9b,0xa9,0x37,0x1a,0x3d,0xab,0x97,0x9c,0xc1,0x29,0x16,0x2e,0xa4,0xcc,0x42,0xc1,0x33,0x2e,0xc3,0xab,0xc7,0x6e,0x2d,0x3e,0xd8,0x25 +,0x33,0x4a,0x51,0xbe,0xa6,0xac,0xc3,0xb6,0xd3,0xb9,0x2d,0x26,0xb3,0xcf,0xd3,0x3c,0x2e,0x34,0x62,0xa5,0xbe,0x3f,0x2a,0x3c,0x59,0xe0,0xac,0xc6,0x36,0x23,0x26,0x4d +,0xa7,0x9b,0xa1,0xd5,0x2b,0x69,0x98,0xa1,0x4f,0x2a,0x1f,0x4a,0x31,0x2d,0xa7,0xb3,0x4c,0x40,0x45,0xd9,0xa9,0xac,0x25,0x1c,0x26,0xb9,0xa3,0xaf,0x4a,0x1e,0x4b,0xb2 +,0xb4,0xae,0xac,0x72,0x21,0x23,0x26,0x7c,0x9f,0xb2,0x2b,0x36,0xcc,0xa5,0xad,0x3e,0x57,0xa8,0xc0,0xae,0xc4,0xcf,0x33,0x1d,0x49,0x31,0x57,0x41,0xb0,0xac,0xb4,0xaf +,0xbe,0x2a,0x25,0x2f,0x32,0xe8,0x32,0xd1,0xb1,0xac,0xae,0x77,0x46,0xc7,0xbd,0xbb,0x30,0x1e,0x22,0xd5,0xbf,0x59,0xae,0x41,0x52,0xc1,0xa8,0xa1,0xa6,0xdd,0x2c,0x28 +,0x2b,0xa9,0xbd,0x34,0x2c,0x24,0xcc,0x9e,0xaf,0x3e,0x32,0x60,0xa0,0xa3,0x50,0x45,0x27,0x25,0x2a,0x30,0xd0,0x9f,0xa8,0x49,0xb4,0xa5,0xa2,0x37,0x26,0x2c,0x2c,0x3b +,0x3f,0xd6,0xe9,0x2a,0xe0,0xad,0x58,0x63,0xaf,0x63,0x36,0x46,0x23,0x45,0xc5,0xb4,0xeb,0x2f,0xcc,0xa8,0xa4,0xac,0xab,0x2e,0x28,0xda,0xac,0xaa,0x5e,0x1e,0x1f,0xee +,0xaa,0xa5,0x5a,0xc3,0x37,0xc9,0xa8,0xb1,0x64,0x26,0x33,0x26,0x28,0x29,0xb7,0xa6,0xce,0x2c,0x41,0xae,0x9a,0xaf,0x22,0x28,0xcc,0xa7,0xb7,0x32,0x34,0xbb,0x78,0xb8 +,0x2e,0xee,0xae,0xb2,0x60,0x1e,0x2c,0x37,0x4d,0x37,0x30,0x29,0xa3,0x9c,0xad,0xbd,0x27,0x36,0x41,0xbd,0x9f,0xb8,0xbb,0x35,0x20,0x58,0xbb,0xb1,0xb7,0xf6,0x2e,0xcc +,0xb9,0xbf,0xad,0xb5,0x2e,0x1f,0x49,0xb9,0xb7,0xae,0x53,0x28,0x3d,0xb3,0xb2,0x3c,0x2e,0x32,0xe3,0x55,0xc2,0xbb,0x6b,0xf1,0x2e,0x60,0xb9,0xe4,0x46,0x3f,0x47,0x38 +,0xba,0xb9,0x3e,0x33,0x28,0xb5,0xa2,0x9f,0xaa,0xc0,0x3e,0x22,0x38,0x3f,0x58,0x6d,0xb9,0x3b,0x21,0x2b,0xa5,0x9c,0xac,0x2f,0x17,0xb0,0x9d,0x9f,0xb4,0x26,0x26,0xc3 +,0xec,0xc0,0x9f,0xe4,0x2c,0x22,0x35,0x9d,0xab,0x2c,0x34,0x28,0x4f,0xac,0xb1,0xaf,0x4b,0x21,0xcf,0xa8,0xe6,0x27,0x39,0xaf,0x45,0xae,0x25,0x20,0x4b,0x2e,0xab,0xb3 +,0xbc,0xba,0xae,0xaf,0xaf,0x2a,0x1e,0xb9,0xb3,0x27,0x27,0x28,0xbf,0x96,0x99,0xbf,0x26,0x75,0x37,0xa4,0xc1,0x2c,0x2e,0x20,0x1f,0xa7,0xa2,0xdb,0xbe,0x63,0xbe,0x2e +,0xba,0xce,0xa6,0x5d,0x2d,0x2a,0xac,0xdc,0x1a,0x4c,0xb8,0x5f,0x45,0xa9,0x29,0xbf,0xaa,0xbc,0x35,0x32,0x32,0x4e,0xb3,0xbb,0x26,0x2c,0x9d,0x9c,0xaa,0xb7,0xec,0x21 +,0xb3,0xd0,0x1f,0x37,0x33,0x1c,0xa8,0x99,0xd3,0xcb,0x28,0xe0,0x3b,0xad,0xaf,0x24,0x53,0x22,0x9d,0xa5,0x30,0xde,0x99,0x94,0x1d,0x15,0x0e,0x1f,0xff,0xa5,0x9d,0x1f +,0x22,0x20,0x38,0x8e,0x8a,0xa9,0x0b,0x0b,0xac,0x88,0x86,0xc2,0x12,0x13,0x2f,0x46,0x10,0x21,0x9c,0x91,0x9a,0xae,0x1d,0x18,0x0b,0x41,0x8b,0xb3,0x99,0x16,0x14,0xa6 +,0x17,0xa8,0xab,0xa2,0x8d,0xe1,0x8c,0x19,0x4a,0x0c,0x0c,0x8a,0x27,0xac,0x04,0xa1,0x85,0x9b,0x8c,0x0e,0xa7,0x35,0x1b,0x5d,0x00,0x19,0x04,0x9d,0x85,0x2c,0xaa,0x04 +,0x86,0x92,0xaf,0x8e,0x16,0x83,0x15,0x33,0x1a,0x03,0x08,0x04,0x84,0x9f,0x84,0x96,0x93,0x82,0x0d,0x9a,0x18,0xba,0xb0,0x09,0xaf,0x0c,0x03,0x03,0x90,0x8c,0x87,0x8b +,0x94,0x80,0x07,0x1e,0x0f,0x96,0x8a,0x04,0x11,0x10,0xab,0x0e,0x8e,0x9c,0x98,0x8e,0xa9,0x8b,0x01,0x0b,0x10,0x95,0x86,0x5d,0x2e,0x0f,0x04,0x01,0x8f,0x80,0x84,0xa9 +,0x29,0x8f,0x14,0x19,0x2a,0xe3,0x8d,0x50,0x25,0x0d,0x07,0x02,0x99,0x85,0x9c,0xa5,0x1c,0x80,0x36,0x0c,0x10,0x17,0x89,0xa6,0x93,0x10,0x06,0x01,0xc2,0x80,0x9f,0x9a +,0x0b,0x80,0x90,0x17,0x23,0x0e,0x85,0x20,0x3d,0x0c,0x06,0x06,0x11,0x83,0x98,0x87,0x2d,0x97,0x8d,0x0c,0x6b,0x0d,0x93,0x5a,0xca,0x9d,0x0f,0x08,0x0d,0x85,0xe0,0x9a +,0x41,0x8a,0x80,0x0d,0x0a,0x00,0x89,0x9b,0xa8,0x2b,0x09,0x16,0x07,0x85,0x2a,0x99,0x2b,0x95,0x85,0x0d,0xac,0x0e,0x92,0x29,0x1b,0xa0,0x38,0x0f,0x0e,0x82,0x89,0x88 +,0x41,0xb5,0x9e,0x02,0x09,0x05,0x99,0x94,0x95,0x92,0xba,0x12,0x0c,0x8a,0x94,0x94,0x3a,0x8b,0x80,0x37,0x3f,0x16,0x9a,0x9e,0xc5,0x34,0x11,0x04,0x0d,0x88,0xbd,0xa9 +,0x0c,0x2e,0x26,0x00,0x06,0x00,0xc3,0x3a,0x1b,0x05,0x03,0x00,0x0b,0x8d,0x36,0x9f,0x12,0xb5,0x9e,0x07,0x0c,0x0a,0x8a,0x87,0x83,0x8e,0x17,0x06,0x1e,0x80,0x85,0x86 +,0x4d,0x84,0x86,0xad,0x9f,0x1c,0x86,0x87,0x88,0xbd,0x0f,0x18,0x97,0x80,0x8b,0x8a,0x1f,0x8e,0xaa,0x0f,0x23,0xaf,0x80,0x9b,0xa9,0x1c,0x0e,0x08,0xa2,0x8e,0x9b,0xa4 +,0x15,0x8d,0x0c,0x07,0x03,0x17,0x96,0x1f,0x18,0x03,0x04,0x00,0x91,0x8a,0x8f,0x70,0x11,0xaa,0x00,0x0f,0x0a,0xac,0x96,0x10,0x11,0x0c,0x0c,0x08,0x89,0x90,0x94,0x0e +,0x1c,0x8e,0x0c,0x0f,0x0b,0x8e,0x8f,0xa2,0x2c,0x09,0x00,0x13,0x80,0x8a,0x8a,0x1c,0x8d,0x95,0x0c,0x2a,0xb0,0x80,0x95,0x92,0xb6,0xad,0x19,0xaf,0x86,0x98,0x92,0x19 +,0x86,0xa3,0xc7,0x30,0x29,0x90,0xb4,0x9e,0x14,0x0d,0x00,0x9b,0x84,0x8b,0x33,0x02,0xa7,0x06,0x08,0x00,0xb3,0x8c,0x95,0x8a,0x0e,0x0b,0x05,0x88,0x93,0x93,0x5f,0xa4 +,0x80,0x98,0x89,0x53,0x8b,0x88,0x84,0x8c,0xbe,0x2f,0xcd,0x80,0x8f,0x88,0x1a,0x9f,0xa7,0x0e,0x0a,0x02,0xa3,0x2e,0xd1,0x09,0x03,0x00,0x0d,0x3b,0x09,0x22,0x00,0x13 +,0x05,0x00,0x03,0x03,0xb6,0x1c,0xab,0x0c,0x07,0x00,0x24,0xd9,0x11,0x9c,0x26,0x87,0xb7,0x3a,0x10,0x3b,0x83,0x86,0x89,0x19,0x25,0x27,0x86,0x84,0x85,0x91,0x4e,0x88 +,0xc2,0xcd,0x0f,0x94,0x80,0x84,0x82,0xa3,0xb0,0x09,0x8e,0x94,0x8b,0x89,0xb0,0x8d,0x1e,0xa3,0x13,0x99,0x85,0x8b,0x8c,0x08,0x09,0x00,0xa3,0x89,0x85,0x9b,0x05,0x1e +,0x08,0x2c,0x07,0x1f,0xa0,0x1d,0xbc,0x13,0x1b,0x00,0x3a,0x99,0xa3,0x9c,0x09,0x2a,0x05,0x0b,0x14,0x52,0x88,0x95,0xa3,0x00,0x05,0x00,0x1f,0x8b,0xa4,0x99,0x0e,0xb8 +,0x35,0x0e,0x0d,0x15,0x8a,0x93,0x8a,0x2f,0x1a,0x13,0x1c,0x8c,0xd3,0x8e,0x43,0xa5,0x8d,0xaf,0xc3,0x0f,0x91,0x84,0x80,0x9a,0x08,0x0b,0x0d,0x88,0x90,0x8f,0xc9,0x08 +,0xc6,0x1b,0x1d,0x0e,0xd0,0x88,0x8c,0x97,0x09,0x07,0x00,0x20,0x8a,0x8f,0x87,0x21,0x9b,0xb4,0x2d,0x1e,0x1f,0x83,0x86,0x80,0x96,0xc6,0x22,0x4c,0x82,0x84,0x80,0xa0 +,0x97,0x8b,0x90,0x91,0x3f,0xab,0x9a,0x8b,0xbb,0x0d,0x05,0x00,0x0e,0x1c,0xc6,0x2c,0x08,0x0b,0x02,0x01,0x01,0x07,0x18,0x1d,0x0f,0x01,0x03,0x00,0x02,0x1f,0x68,0x9e +,0x17,0x0f,0x22,0x1c,0x14,0x0a,0xb7,0x88,0x8b,0x92,0xa9,0x24,0x0b,0xba,0x82,0x83,0x89,0x9a,0x8c,0xaa,0xcb,0xa7,0x92,0x80,0x8b,0x8a,0x9e,0xb9,0x20,0x30,0x84,0x91 +,0x88,0x93,0x89,0x8d,0x19,0x1a,0x14,0x92,0x83,0x83,0x89,0x19,0x09,0x0a,0x8e,0x8c,0xa2,0x3d,0x0a,0x23,0x0f,0x19,0x08,0x15,0x8d,0x8c,0xac,0x05,0x03,0x00,0x14,0x98 +,0xae,0x97,0x25,0x2b,0x2d,0x09,0x07,0x00,0x2e,0x8f,0x90,0x3e,0x04,0x04,0x03,0x95,0x8c,0xa8,0x14,0x08,0x45,0x1e,0x38,0x13,0x5f,0x9a,0x9c,0x98,0x15,0x0a,0x03,0x2b +,0x8a,0x8c,0x8a,0xab,0x9c,0x36,0x25,0xb5,0x5d,0x92,0x8b,0x85,0xab,0x12,0x13,0x22,0x88,0x89,0x85,0xb4,0x10,0x40,0x22,0x3a,0x0b,0x49,0x89,0x87,0x9b,0x0a,0x08,0x00 +,0x2b,0x9a,0x88,0x96,0x20,0xac,0x10,0x3b,0x1b,0x9a,0x81,0x87,0x9a,0x15,0x45,0xbb,0x83,0x83,0x81,0x8e,0x4c,0x86,0xa8,0x3d,0x3a,0x97,0x80,0x86,0x80,0x5f,0x09,0x00 +,0x19,0x9e,0xbf,0xa6,0x05,0x12,0x03,0x05,0x06,0x03,0x28,0x23,0x1d,0x00,0x04,0x00,0x1d,0x93,0x3e,0x43,0x07,0x16,0x09,0x06,0x05,0x07,0xb6,0x8d,0x81,0x32,0x06,0x00 +,0xf9,0x87,0x88,0x83,0xb9,0xaf,0x28,0x8e,0x8b,0x8b,0x80,0x84,0x86,0x17,0x0e,0x11,0x91,0x84,0x89,0x85,0xa6,0x89,0x95,0x9a,0x4f,0x9e,0x80,0x8b,0x94,0x18,0x20,0x38 +,0x8a,0x85,0x88,0x44,0x0d,0xd5,0x25,0x1e,0x07,0xd1,0x8c,0x8c,0x30,0x06,0x03,0x05,0x8f,0x8f,0xeb,0x05,0x09,0x35,0x4c,0xad,0x11,0x39,0x68,0x1b,0x0c,0x0c,0x00,0x0a +,0x9e,0x8e,0x8f,0x0b,0x2b,0x16,0x12,0x07,0x0b,0x34,0x2f,0xba,0x0c,0x0f,0x01,0x92,0x87,0x8e,0x22,0x04,0xaa,0x1f,0xce,0x28,0x8e,0x8d,0x89,0x96,0x16,0x08,0x16,0x83 +,0x86,0x88,0x13,0x9b,0x86,0x8f,0xa3,0x66,0x8d,0x92,0x8b,0x1a,0x09,0x00,0xab,0x82,0x84,0x9c,0x05,0x15,0x0e,0x1f,0x1c,0xb3,0xa1,0xb7,0xab,0x23,0x0d,0x44,0x80,0x8b +,0x96,0x0d,0xd9,0x97,0xa1,0x93,0x95,0x81,0x88,0x81,0x95,0x1a,0x13,0x8b,0x83,0x86,0xc5,0x35,0x89,0x9d,0x98,0x2a,0x21,0x28,0xb3,0x0e,0x04,0x00,0x08,0x93,0xa0,0x2a +,0x01,0x07,0x02,0x08,0x09,0x0a,0x08,0x0e,0x17,0x07,0x03,0x03,0x97,0xb6,0x1c,0x01,0x0d,0x26,0x33,0x37,0x1b,0x91,0x8a,0x84,0xd0,0x08,0x0a,0x8a,0x83,0x88,0x1d,0x20 +,0x84,0x87,0x87,0xa8,0x8f,0x87,0x80,0x95,0x0d,0x03,0x8c,0x81,0x80,0xae,0x0d,0x95,0xb4,0x99,0x29,0x9d,0x94,0x88,0x9d,0x1a,0x0e,0xa5,0x82,0x85,0x98,0x08,0xac,0x26 +,0x57,0x0e,0x12,0x9d,0x88,0x99,0x07,0x00,0x03,0x91,0x8c,0xa7,0x03,0x0e,0x5c,0x9c,0x58,0x0c,0x1a,0xc2,0x9e,0x13,0x00,0x00,0xaf,0x84,0x8e,0x09,0x04,0x12,0xb2,0x1a +,0x04,0x13,0xe1,0x9e,0x27,0x08,0x11,0x97,0x91,0x8e,0x0b,0x0e,0x56,0xa3,0x59,0x16,0xc6,0x8b,0x80,0x97,0x11,0x08,0x98,0x85,0x80,0xde,0x1a,0x39,0x8a,0x85,0x97,0xab +,0xa2,0x8d,0xa7,0x15,0x07,0x9f,0x98,0x85,0xb4,0x1e,0x17,0xbe,0x9e,0x15,0x17,0x0f,0xc7,0xdb,0x17,0x12,0x8e,0x88,0x84,0xad,0xb8,0x9f,0x8f,0x8d,0xdc,0xaa,0x8c,0x80 +,0x8d,0x3f,0x24,0x85,0x85,0x80,0x3b,0x0e,0x2c,0x9b,0x87,0xbb,0x47,0x24,0xa1,0x43,0x0e,0x00,0x17,0xab,0xa0,0x0d,0x01,0x02,0x11,0x35,0x00,0x03,0x01,0x0c,0x09,0x04 +,0x00,0x17,0xa6,0x97,0x16,0x0a,0x0f,0x18,0xb8,0x0b,0x0d,0x24,0x8a,0x90,0x17,0x03,0xaf,0x87,0x80,0xb7,0x13,0xa3,0x90,0x83,0x8b,0x8b,0x91,0x82,0x8b,0x61,0x1b,0x91 +,0x8b,0x85,0xa4,0x38,0x99,0xa2,0x8b,0xa8,0x9b,0x97,0x8e,0xb8,0x13,0x0e,0x97,0x86,0x80,0x9a,0x1b,0x38,0x2a,0x93,0x3a,0x1b,0x26,0x8d,0x9b,0x29,0x00,0x1f,0x95,0x86 +,0xa6,0x01,0x04,0x04,0xa6,0x0f,0x12,0x0a,0x34,0xd0,0x0d,0x06,0x0b,0x56,0x8e,0xa0,0x0d,0x28,0x20,0x98,0x9a,0x48,0x19,0x99,0x9c,0x09,0x04,0x08,0x94,0x80,0x8e,0x2c +,0x3b,0x1e,0x8d,0x9b,0x0e,0x01,0x0e,0xa0,0x1d,0x02,0x02,0xc4,0x88,0x8b,0x0e,0x00,0x0b,0x9f,0x8e,0x98,0xb8,0xbb,0x8d,0x8c,0x59,0xd2,0x8e,0x86,0x8a,0x32,0xa0,0xb5 +,0x87,0x8e,0x96,0x8d,0x8c,0x82,0x8d,0x36,0x18,0x8b,0x82,0x80,0xab,0xdc,0x1e,0xaa,0xa8,0x14,0x08,0x04,0x0a,0x0a,0x05,0x00,0x08,0x11,0x99,0x0c,0x05,0x06,0x05,0x0f +,0x17,0x17,0x0e,0x35,0xac,0x5a,0x29,0xa3,0x9f,0x88,0xbc,0x9f,0x98,0x8f,0x80,0x8e,0x87,0x89,0x81,0x85,0x5e,0x1a,0xa0,0x8a,0x80,0x93,0xa5,0x2a,0x31,0x8c,0xa7,0x24 +,0x0a,0x18,0x25,0x15,0x04,0x0c,0x12,0xc7,0x53,0x0b,0x0c,0x00,0x0c,0x0f,0x0a,0x06,0x18,0xcf,0x14,0x04,0x2d,0x99,0x82,0x97,0x06,0x19,0x2b,0x88,0x8c,0x1b,0x17,0xac +,0x88,0x97,0x0c,0x0e,0x90,0x81,0x80,0x8f,0xa6,0xb1,0x86,0x80,0x87,0x99,0x2f,0xa0,0x9a,0x10,0x05,0x1b,0xc5,0x8c,0x2a,0x09,0x07,0x06,0x35,0x28,0x09,0x19,0x26,0x5f +,0x0f,0x03,0x1b,0xc8,0x87,0xa5,0x21,0x0f,0x6e,0x88,0x99,0xbf,0x2e,0x87,0x80,0x87,0xa6,0x34,0x8a,0x80,0x81,0x91,0x92,0xbe,0x8c,0x84,0x97,0x21,0x15,0x6c,0xaa,0x2c +,0x10,0x1f,0x19,0x9b,0xaf,0x4e,0x0a,0x09,0x2d,0x18,0x17,0x0b,0x28,0xeb,0x11,0x01,0x0a,0xb6,0xa1,0x18,0x04,0x05,0x0e,0x9c,0xbd,0x0d,0x15,0x23,0xaf,0x10,0x00,0x0a +,0x2b,0x98,0xc0,0x10,0x0f,0x07,0x36,0x97,0x9b,0x1f,0x30,0x90,0x96,0x98,0x9e,0x8e,0x82,0x81,0x88,0x8c,0x1e,0x3f,0x91,0x97,0x9d,0xa2,0x9c,0xa3,0x1b,0x0a,0x99,0xa2 +,0x8c,0xa7,0x2e,0xb9,0x17,0x8f,0x92,0xab,0xac,0x93,0x94,0x3f,0x0e,0x1d,0x99,0x8c,0x85,0x9f,0x9f,0x2d,0xae,0x89,0x9d,0xa6,0x13,0xa0,0xa8,0x0e,0x0c,0x14,0x20,0x98 +,0x91,0x18,0x0e,0x02,0x1d,0x29,0x14,0x20,0x2e,0x90,0x8b,0x25,0x28,0x96,0x86,0x82,0x98,0x98,0x1d,0x11,0x96,0x12,0x0a,0x1d,0x10,0x19,0x00,0x01,0x00,0x08,0xef,0x1d +,0x05,0x06,0x03,0x15,0xa3,0x0d,0x13,0x49,0x9c,0x93,0x0d,0x1a,0x8f,0x86,0x80,0x8c,0x98,0xb6,0xc1,0x8a,0x88,0xb3,0x8f,0x87,0x84,0x9b,0x19,0xb8,0x8d,0x84,0x83,0x8f +,0x2a,0xbf,0x4d,0x94,0xb7,0x5d,0x4f,0xea,0x2e,0x0a,0x0f,0x1b,0x93,0x9b,0xaf,0x19,0x06,0x0f,0x24,0x12,0x0d,0x16,0x1e,0x13,0x08,0x04,0x0e,0x30,0xb4,0xa9,0xb7,0x16 +,0x27,0x29,0x48,0x9d,0x8e,0x86,0x88,0x8c,0x29,0x8f,0x83,0x81,0x81,0x81,0x8f,0xa5,0xa5,0x32,0x9c,0xe3,0x33,0x18,0x0c,0x06,0x00,0x08,0x0b,0x22,0x19,0x08,0x07,0x04 +,0x06,0x0a,0x19,0x0b,0x11,0x08,0x09,0x07,0x04,0x13,0x58,0x9d,0xa8,0x96,0x21,0x1f,0xad,0x86,0x89,0x8b,0x95,0xa9,0x93,0xa0,0x8e,0x8c,0x88,0x84,0x88,0x8e,0x9e,0xaa +,0x8c,0x87,0x8a,0x97,0x97,0x9e,0xcc,0x29,0xae,0x94,0x97,0xa3,0xcb,0x25,0x13,0x2c,0xd1,0x56,0x1d,0x1c,0x0b,0x14,0x07,0x08,0x14,0x10,0x21,0x11,0x17,0x0f,0x0e,0x36 +,0xa7,0x9a,0x8f,0x9c,0xa1,0x88,0x8f,0x99,0x8a,0x86,0x8a,0x8d,0x99,0xb6,0xd0,0x2f,0x27,0x34,0x13,0x0d,0x0d,0x0c,0x0c,0x0d,0x14,0x21,0x27,0x0d,0x1b,0x1c,0x1f,0x26 +,0x19,0x0d,0x19,0x13,0x13,0x1e,0x0d,0x15,0x1f,0x2b,0x18,0x20,0xcd,0xae,0xfc,0x2a,0x1b,0xb6,0xcc,0xbb,0xa6,0xc9,0xa8,0xbe,0xa4,0x67,0x9f,0x8f,0x8f,0x8c,0xa8,0xaf +,0x9e,0x8b,0x8b,0x98,0x96,0x91,0x8b,0x8f,0x2b,0xac,0x8c,0x99,0x94,0xb3,0x3f,0x16,0x24,0x2d,0x2f,0x2d,0x17,0x22,0x14,0x1d,0x1d,0x27,0xbc,0x98,0x93,0x9d,0x88,0x95 +,0xa0,0x8c,0x8a,0x8c,0x8b,0x93,0x96,0x9f,0x61,0x27,0x10,0x2a,0x13,0x10,0x0d,0x08,0x02,0x06,0x03,0x09,0x07,0x0b,0x11,0x08,0x10,0x16,0x24,0x16,0x42,0x21,0x3d,0x4a +,0xbb,0x34,0x2b,0xac,0xab,0x93,0x96,0xa7,0x9c,0x8d,0x97,0xa0,0xbd,0x9d,0x92,0x91,0xa2,0x9d,0xa3,0x1e,0xf9,0xa7,0xa3,0xab,0x98,0x41,0x1a,0xad,0x39,0x21,0x36,0xaa +,0xa2,0xbe,0x2c,0x12,0x20,0x5e,0x62,0x9d,0xca,0xbd,0x3b,0x1c,0x36,0x1e,0x1a,0x29,0xae,0xac,0x27,0x3f,0xd3,0xad,0x90,0x96,0x8c,0x84,0x8c,0x8a,0x89,0x87,0x84,0x83 +,0x88,0x89,0x8a,0x91,0xab,0x19,0x2a,0x0a,0x13,0x0c,0x06,0x0c,0x04,0x08,0x07,0x07,0x03,0x0e,0x0a,0x10,0x0b,0x08,0x0e,0x09,0x0e,0x1e,0x2c,0x15,0x1e,0x1a,0x1f,0x2b +,0xad,0xa9,0xa6,0x92,0xb6,0x9b,0xa7,0xa3,0xaa,0xa5,0x9a,0x91,0x94,0x91,0x93,0x9b,0x8d,0x97,0x96,0x9b,0x96,0x98,0x9a,0xbf,0xaa,0x93,0x9f,0x9a,0x94,0xb8,0xb9,0x54 +,0x36,0xaa,0x3f,0x25,0x29,0x28,0x26,0x27,0x12,0x17,0x18,0x1c,0x15,0x0b,0x1b,0x18,0xbf,0xbc,0x55,0x6e,0xbf,0x99,0x9a,0x8a,0x89,0x8c,0x87,0x88,0x8d,0x8b,0x8a,0x8b +,0x9f,0xc2,0xbb,0x25,0x25,0x1c,0x08,0x0d,0x0d,0x16,0x19,0x0d,0x07,0x07,0x0a,0x0a,0x0e,0x12,0x2f,0x19,0x1c,0x29,0x0e,0x0d,0x1a,0x1f,0x31,0x22,0x14,0x19,0x19,0x18 +,0x24,0xb0,0x9b,0xb5,0x94,0xbc,0x29,0xa3,0xae,0x8e,0x8f,0x8c,0x98,0x9e,0x9a,0x9f,0x98,0x9c,0x92,0x92,0x90,0x8f,0xae,0xaf,0x8d,0x95,0xad,0xa9,0x3e,0x25,0x63,0x5f +,0x9f,0x2d,0x1a,0x28,0x1f,0x20,0x11,0x15,0x16,0x0f,0x10,0x10,0x18,0xab,0xab,0x99,0x8a,0x8e,0x8c,0x8f,0x96,0x89,0x8a,0x88,0x83,0x86,0x8b,0x9f,0xe3,0xf3,0x4a,0x35 +,0x20,0x0a,0x08,0x06,0x0b,0x08,0x06,0x07,0x06,0x0e,0x09,0x0e,0x0e,0x0c,0x12,0x1f,0x2e,0x5c,0x35,0x28,0x3e,0x2a,0x2d,0x47,0xaf,0xdb,0xa5,0x94,0x8b,0x90,0x97,0xa8 +,0x9f,0x93,0xb8,0xa9,0xab,0xa3,0xa7,0xc3,0xa5,0x9b,0xb6,0xb6,0xca,0xa0,0x9b,0x9b,0xc7,0x3e,0x27,0x37,0xa2,0x9f,0x9e,0xd2,0xad,0xbb,0x38,0x18,0x1c,0xb3,0x9e,0xaa +,0x31,0x12,0x11,0x14,0x25,0x20,0x25,0x37,0x5a,0xa7,0xa8,0x9c,0x8c,0x8e,0x96,0x93,0x8c,0x86,0x86,0x88,0x8c,0x89,0x93,0x94,0xc3,0x36,0x1d,0x11,0x14,0x07,0x05,0x03 +,0x06,0x0b,0x16,0x17,0x10,0x0b,0x0b,0x0a,0x0a,0x08,0x0e,0x1b,0x25,0x28,0x1f,0x17,0x1d,0x2f,0xb4,0xa5,0xb3,0x32,0x32,0xad,0xad,0x94,0xa1,0xa8,0x78,0x5f,0xa0,0x98 +,0x9b,0xac,0xa1,0x9b,0x98,0x8f,0x8e,0x92,0x97,0xc9,0xab,0x9d,0x9e,0xac,0x9e,0x93,0x8f,0xa4,0x2f,0x2f,0x3b,0xbf,0x3c,0xc0,0x37,0x2a,0x26,0x1e,0x24,0x1f,0x23,0x1a +,0x13,0x0b,0x0d,0x0f,0x1b,0x49,0xae,0x93,0x8e,0x8c,0x8d,0x88,0x85,0x85,0x88,0x92,0x90,0x8a,0x8d,0x95,0x5f,0x18,0x17,0x12,0x19,0x17,0x0e,0x0d,0x0c,0x0c,0x0f,0x0e +,0x0e,0x08,0x07,0x0c,0x16,0x18,0x0d,0x0e,0x1c,0x29,0x3d,0x68,0xba,0xb6,0x27,0x26,0x2a,0x25,0x2b,0xb5,0x93,0x91,0x9f,0xac,0x99,0x97,0x9d,0x9e,0xae,0xaf,0x9b,0x9b +,0x9e,0x9c,0xad,0xaf,0xa4,0x92,0x8e,0x99,0x4d,0x24,0x2f,0xac,0x9a,0x9a,0x99,0xa3,0xae,0x20,0x33,0x24,0x1f,0x35,0x35,0xcf,0x2f,0x14,0x08,0x09,0x0c,0x1e,0x41,0x5e +,0x58,0xb4,0xbf,0xb6,0x98,0x89,0x86,0x87,0x85,0x86,0x94,0xa8,0x95,0x92,0x8e,0x91,0x9d,0xa8,0x38,0x0e,0x0b,0x08,0x04,0x07,0x06,0x0b,0x0e,0x08,0x05,0x06,0x0d,0x28 +,0xb2,0x56,0x0e,0x08,0x0b,0x19,0x1e,0x25,0x2d,0x3d,0xb5,0xa8,0x5b,0x1d,0x20,0xbc,0x95,0x8e,0x8d,0x9a,0xac,0xc2,0xa3,0x93,0x9b,0xae,0xb7,0x9b,0x9b,0xad,0xca,0xb7 +,0xa5,0x96,0x8d,0x8e,0x9c,0xd4,0x30,0xbd,0x9c,0xa8,0x9c,0x99,0x9f,0xab,0x39,0x18,0x0d,0x16,0xc4,0xa0,0xca,0x1c,0x0f,0x10,0x27,0x20,0x1d,0x2a,0x33,0xcb,0xab,0xa5 +,0xc7,0xa8,0x8c,0x82,0x81,0x82,0x8b,0x8e,0x8f,0x94,0xa1,0x2f,0x3b,0x6e,0x24,0x0f,0x08,0x04,0x07,0x38,0xa3,0x00,0x16,0x8e,0x0d,0x12,0x11,0x03,0x04,0x03,0x09,0x0a +,0x19,0x00,0x07,0x0b,0x01,0x0f,0x04,0x09,0x05,0x03,0x06,0x05,0x03,0x03,0x15,0x77,0x4c,0x1a,0x2d,0x9b,0x8f,0x88,0x87,0x95,0x90,0x81,0x80,0x8a,0x9d,0x8e,0x80,0x80 +,0x80,0x82,0x85,0x82,0x80,0x81,0x81,0x8a,0x87,0x83,0x80,0x8a,0x63,0x27,0x2c,0x8d,0x80,0x89,0x27,0x2b,0x8b,0x90,0x1e,0x0e,0x09,0x19,0xa7,0x19,0x03,0x00,0x02,0x00 +,0x0f,0x13,0x05,0x03,0x0e,0x21,0x08,0x00,0x00,0x02,0x08,0x0c,0x02,0x00,0x00,0x01,0x00,0x0e,0x29,0x04,0x03,0x2f,0x2b,0x00,0x06,0x0a,0x10,0xb5,0xa8,0x06,0x0b,0x7b +,0x0f,0xb9,0x80,0x89,0xa5,0x84,0x80,0x89,0x8d,0x86,0x83,0x84,0x80,0x87,0x92,0x80,0x89,0x9e,0x82,0x80,0x88,0x84,0x80,0x80,0x85,0x83,0x8c,0x89,0x80,0x83,0x9d,0x89 +,0x84,0x15,0x96,0x80,0x87,0x92,0x83,0x84,0x8b,0x88,0x19,0x72,0x81,0x8a,0x22,0xb6,0xf2,0x09,0x00,0x2a,0x85,0x2c,0x06,0x09,0x1b,0x0d,0x01,0x00,0x0b,0x0e,0x07,0x01 +,0x03,0x02,0x02,0x00,0x1a,0xa2,0x00,0x03,0x05,0x07,0x02,0x01,0x00,0x16,0x12,0x01,0x03,0x04,0x04,0x01,0x00,0xc3,0xae,0x00,0x06,0x09,0x0f,0x03,0x00,0x0c,0xb4,0x0d +,0x0a,0x0d,0x1b,0x1d,0x00,0x0d,0x80,0x98,0x07,0x8f,0x8a,0x8b,0xc3,0xcd,0x86,0x80,0x90,0x87,0x83,0x80,0x9c,0x11,0x93,0x80,0x95,0xa0,0x80,0x80,0x83,0xad,0x99,0x80 +,0x85,0x8e,0x82,0x82,0x80,0xaa,0x2b,0x86,0x80,0xa8,0x8c,0x80,0x81,0xa4,0x12,0x9c,0x80,0xb2,0x45,0x88,0x98,0x2b,0x03,0x02,0x90,0x88,0x00,0x45,0xb1,0x3d,0x07,0x01 +,0x44,0x89,0x08,0x29,0x93,0x99,0x2e,0x02,0x16,0x82,0x8d,0x0c,0x85,0x8f,0x8a,0x17,0x27,0x85,0x88,0x17,0x86,0x88,0x8b,0x30,0x0a,0x18,0x81,0xa7,0x0b,0x8d,0x53,0xc4 +,0x01,0x04,0x2f,0x25,0x00,0x27,0x06,0x0d,0x01,0x00,0x00,0xd2,0x0e,0x00,0x10,0x00,0x09,0x00,0x01,0x0a,0x09,0x00,0x18,0x04,0x09,0x00,0x02,0x00,0xc8,0x09,0x04,0x12 +,0x05,0x08,0x00,0x00,0x0e,0x0a,0x00,0x11,0x04,0x0a,0x00,0x03,0x00,0x96,0x14,0x0e,0xc0,0x1a,0x27,0x01,0x14,0x8a,0xa6,0x2d,0x80,0x86,0x84,0x9e,0xa2,0x8d,0x80,0x87 +,0x87,0x80,0x81,0x82,0x8a,0x83,0x80,0x86,0x88,0x80,0x82,0x80,0x87,0x8e,0x88,0x80,0x86,0x86,0x80,0x81,0x83,0x8c,0x89,0x80,0x89,0x8d,0x80,0x81,0x82,0x9f,0xab,0x98 +,0x80,0x8a,0x92,0x83,0x83,0x8a,0x51,0x90,0x80,0x8c,0x8e,0x80,0x83,0x88,0x2b,0x23,0xb3,0x80,0x8d,0xab,0x88,0xa3,0x36,0x05,0x0b,0xdd,0x09,0x03,0x19,0x0b,0x07,0x00 +,0x02,0x00,0x09,0x0c,0x00,0x08,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0x07,0x01,0x02,0x00,0x02,0x00,0x0a,0x1e,0x02,0x1e,0x0a,0x05,0x02,0x02,0x2a,0x10,0x0f,0x9b,0xad +,0xbc,0x17,0x1e,0x18,0x9c,0x86,0xca,0x85,0x8c,0x8e,0x4c,0x66,0x88,0x97,0xae,0x82,0x85,0x8d,0xb1,0x3c,0x1f,0xa2,0x80,0x46,0x86,0x8b,0x8f,0xbf,0x27,0x8d,0x8d,0x92 +,0x83,0x81,0x91,0xb2,0x3b,0x22,0xed,0x80,0xb1,0x8b,0x8d,0x97,0x4f,0x13,0xa1,0xad,0x22,0xbd,0xa6,0x1f,0x12,0x08,0x07,0x04,0x88,0x1b,0x24,0xa8,0x19,0x13,0x00,0x17 +,0xef,0x1d,0x4b,0x99,0x28,0x28,0x0e,0x0e,0x07,0x87,0x9e,0x57,0x8b,0xb5,0x44,0x05,0x25,0xa1,0x1d,0x29,0x8d,0xc5,0x4d,0x18,0x17,0x03,0x9d,0x8d,0x24,0x8d,0x36,0x4f +,0x0e,0x18,0xac,0x2c,0xc9,0x85,0x8c,0x9b,0x2d,0xd7,0x0e,0xb9,0x80,0xd5,0x88,0x8c,0x87,0xa2,0xa8,0x89,0x87,0x8a,0x82,0x80,0x87,0x8c,0x8b,0x9b,0xa5,0x80,0x91,0x89 +,0x88,0x90,0x3f,0x23,0x9f,0x94,0x1e,0xb7,0x9b,0x0f,0x11,0x02,0x06,0x00,0xdb,0x1f,0x06,0x1f,0x07,0x08,0x00,0x04,0x09,0x04,0x07,0x21,0x09,0x07,0x01,0x05,0x00,0x1c +,0x93,0x09,0xb6,0x22,0x1d,0x0c,0x0e,0x9b,0xa9,0x9a,0x87,0x88,0x98,0x9f,0xa7,0x3a,0xac,0x80,0x93,0x8b,0x84,0x8c,0xa8,0x49,0x90,0x91,0x9c,0x8e,0x83,0x94,0x9c,0xd8 +,0x1e,0x08,0x8a,0x8f,0x1d,0x90,0xc1,0x37,0x0b,0x28,0xa6,0x70,0xdf,0x8d,0x93,0x2d,0x12,0x0c,0x02,0x19,0x84,0x23,0xb7,0xba,0x1e,0x0b,0x02,0x2b,0x1a,0x0e,0xf2,0x9e +,0x16,0x07,0x00,0x06,0x00,0x9d,0xd8,0x0a,0x4e,0x0f,0x0f,0x03,0x1a,0x4c,0x33,0xa7,0x8c,0xa9,0x25,0x10,0x21,0x15,0xae,0x80,0xaf,0x8d,0x8f,0xaf,0x33,0x16,0x9c,0x97 +,0x9c,0x8c,0x8c,0xde,0x1d,0x3a,0x1e,0x10,0x86,0x8d,0x15,0x97,0x32,0x2d,0x09,0x1a,0x8c,0xab,0x9d,0x99,0x3c,0x0f,0x13,0x13,0x0e,0x4e,0x80,0x34,0xb1,0x9c,0xb0,0x41 +,0x10,0x88,0x88,0x8d,0x89,0x85,0x90,0xa1,0xca,0x9c,0x3e,0x89,0x87,0x3e,0x8b,0x94,0x9d,0x13,0xd0,0x93,0x3b,0x3a,0xce,0x1a,0x06,0x03,0x05,0x05,0x03,0x95,0x16,0x04 +,0x16,0x00,0x06,0x00,0x0c,0x0c,0x0a,0x17,0x1c,0x05,0x03,0x0a,0x11,0x04,0x1d,0x89,0x0b,0xb7,0xb3,0xae,0x27,0x41,0x87,0x95,0x8f,0x88,0x8b,0xcf,0x8d,0x87,0x8f,0xa2 +,0x82,0x87,0x95,0x85,0x8c,0x95,0x31,0x8e,0x86,0x8f,0x89,0x8b,0xb2,0xaa,0xab,0xcd,0x15,0x1d,0x80,0x34,0xae,0x8d,0xa5,0x20,0x16,0x90,0xad,0xaa,0xe3,0xd5,0x3a,0x49 +,0x39,0x23,0x07,0x98,0x8e,0x09,0xa3,0x27,0x0d,0x02,0x12,0x57,0x20,0x13,0x13,0x15,0x09,0x0a,0x08,0x06,0x00,0x97,0x2a,0x15,0x99,0x16,0x0c,0x05,0xdd,0xb4,0x18,0x2c +,0x9e,0xa7,0x66,0xa2,0xa4,0x09,0x33,0x80,0x3e,0x97,0x90,0x2d,0x10,0x2b,0x8c,0xa4,0x9f,0x8c,0x92,0xe6,0xb1,0xb5,0x14,0x06,0x8a,0x86,0xa8,0x87,0xaf,0x1a,0x0f,0xa9 +,0x96,0xb1,0xa0,0x97,0x9b,0xa5,0xa8,0x26,0x03,0x1b,0x80,0xa0,0x9e,0x8e,0xb0,0x2d,0xb4,0x83,0x89,0x8e,0x89,0x82,0x8e,0x96,0xa8,0x1a,0x1d,0x8b,0x80,0xa1,0x8d,0xa2 +,0x12,0x08,0x18,0x5b,0x0c,0x16,0x5d,0x1c,0x09,0x01,0x01,0x00,0x01,0x95,0x19,0x00,0x0f,0x00,0x04,0x03,0x15,0x0c,0x09,0x24,0x5c,0x0d,0x07,0x0d,0x08,0x08,0x96,0x81 +,0x26,0x9b,0xaa,0x23,0x23,0xa8,0x8d,0x9b,0x8b,0x82,0x86,0x9f,0x9b,0x70,0x35,0x9b,0x80,0x98,0xaa,0x89,0x99,0x93,0xa0,0x86,0x91,0x90,0x88,0x89,0xaf,0x3c,0x46,0x1c +,0x3b,0x85,0x88,0x17,0x9a,0xad,0x36,0x12,0x36,0xac,0x4d,0x95,0x8c,0xb6,0x1d,0x10,0x07,0x0a,0xf9,0x82,0x0d,0x1a,0x4c,0x11,0x0c,0x0b,0x20,0x0f,0x1b,0xce,0x18,0x07 +,0x06,0x00,0x09,0x14,0x84,0x25,0x09,0x63,0x0b,0x0b,0x08,0x1d,0x22,0x38,0x93,0x8f,0x40,0x2a,0x14,0x1a,0x30,0x83,0x8f,0x18,0x8a,0x9a,0xa9,0xdf,0xae,0xad,0xb3,0x8b +,0x8a,0x2a,0x17,0x14,0x1b,0x36,0x8a,0x88,0x0b,0x9f,0xa9,0x25,0x14,0x1e,0x2d,0x57,0x8a,0x8a,0xca,0x25,0x32,0x2c,0x22,0x9c,0x81,0x1c,0x8e,0x84,0x8f,0x95,0x92,0x90 +,0x96,0x83,0x83,0x93,0xc1,0xa4,0xad,0xb8,0x94,0x80,0x22,0xb3,0x93,0x27,0x10,0x09,0x0d,0x06,0x3d,0x92,0x0f,0x02,0x05,0x02,0x03,0x04,0x9b,0x08,0x08,0x1d,0x08,0x05 +,0x08,0x0e,0x04,0x13,0xa8,0x0c,0x00,0x08,0x0b,0x0f,0x1a,0x80,0x1a,0x18,0x95,0xa7,0x3f,0x2f,0x9c,0x2c,0x96,0x80,0x89,0x9d,0xa8,0xa8,0xab,0xa5,0x80,0xad,0xb1,0x82 +,0x8d,0x9e,0xa9,0x8c,0x9d,0x9f,0x82,0x9f,0x2a,0x2e,0x3d,0xb0,0xae,0x80,0x49,0xb0,0x88,0x9b,0xad,0x4b,0xaa,0x21,0x16,0x8c,0x9e,0x2f,0x2b,0x0b,0x0e,0x1c,0x88,0x09 +,0x15,0xab,0x18,0x1a,0x13,0x1f,0x0c,0x0d,0x9e,0x16,0x0a,0x06,0x01,0x04,0x1b,0x87,0x07,0x41,0xa5,0x18,0x23,0x16,0x1f,0x0d,0x18,0x99,0x33,0xbd,0x1d,0x0c,0x0d,0x98 +,0x87,0x09,0x9d,0xab,0x29,0xa5,0xa0,0xa4,0x39,0xa8,0x86,0xaf,0x9e,0x21,0x12,0x25,0x89,0x86,0x24,0x85,0x93,0xa8,0x99,0x9d,0xf2,0x2c,0x9c,0x8c,0xbb,0x9e,0x28,0x19 +,0x21,0x84,0x93,0x1e,0x8b,0xff,0x50,0xa6,0x91,0x9a,0xb1,0x8b,0x8c,0x9d,0xae,0x12,0x0f,0x1a,0x80,0xab,0x9c,0x8c,0x2e,0x3a,0x57,0xaa,0x1d,0x15,0xb0,0x22,0x1b,0x1c +,0x06,0x08,0x15,0x89,0x11,0x3d,0x24,0x06,0x0c,0x16,0x3f,0x14,0x1f,0xa9,0x1c,0xd1,0x14,0x04,0x00,0x1d,0x8f,0x10,0x86,0xb5,0x22,0x2f,0xa5,0x94,0x2b,0xac,0x96,0x23 +,0x9d,0xea,0x11,0x10,0x8c,0x8a,0x45,0x83,0x28,0x15,0x17,0xaf,0x9e,0x2e,0x97,0x90,0x1f,0x94,0xcf,0x0c,0x04,0x8e,0xa9,0x26,0x81,0x60,0xbc,0x2c,0x92,0x94,0xe3,0x8d +,0x94,0xc7,0x9c,0xa6,0x1d,0x12,0x82,0xbb,0x98,0x85,0x1f,0x15,0x0a,0x2c,0x4e,0x27,0x9c,0x66,0x1b,0x1b,0x15,0x07,0x07,0x96,0x0a,0xac,0x9e,0x14,0x10,0x11,0xc5,0xd3 +,0xb9,0x9e,0x2b,0x2c,0x2a,0x28,0x0d,0x2f,0x8c,0x11,0x8d,0x92,0x3b,0x0a,0x13,0x28,0x12,0xbe,0xc8,0x1f,0x5f,0x25,0x21,0x00,0x2d,0xb1,0x0a,0x8e,0xa6,0xb8,0x0d,0x58 +,0x9f,0x49,0x89,0x92,0xb5,0x98,0xa0,0xab,0x1a,0x87,0x8a,0x97,0x80,0x88,0x8d,0x1e,0x9a,0x9e,0xc3,0x88,0x8d,0xa4,0x97,0xa0,0xc5,0x0e,0x8e,0x2b,0x24,0x9c,0xce,0xb2 +,0x0a,0xae,0x3a,0x22,0x97,0xec,0x23,0x1e,0x38,0x27,0x0b,0x8c,0x1a,0xad,0x99,0xca,0x50,0x09,0x28,0x17,0x16,0x54,0x2b,0x19,0x19,0x18,0x0d,0x08,0xa5,0x05,0x20,0x41 +,0x4a,0x2e,0x12,0xa7,0x37,0xe6,0x9d,0xa6,0x51,0x2d,0xdd,0x1f,0x22,0x8b,0x13,0xa2,0x91,0x8f,0x5c,0x16,0xac,0x23,0x33,0xb6,0xb7,0x34,0x37,0xa9,0x15,0x1c,0x8e,0x17 +,0xb6,0xa3,0x97,0xdb,0x44,0x8b,0x9e,0x99,0x8f,0x91,0x9b,0xab,0x95,0x64,0xa7,0x82,0xbb,0x93,0x96,0x8b,0xa4,0x2d,0x99,0x1f,0x1e,0x2e,0x27,0x45,0x12,0x29,0x12,0x0f +,0xb7,0x08,0x1b,0x16,0x34,0x23,0x0c,0xbe,0x18,0x1b,0xdc,0x38,0xb1,0x1d,0x2d,0x1d,0x16,0x97,0x1b,0xcd,0xb1,0xa4,0xb5,0x0e,0xab,0x22,0x16,0x69,0x1c,0x6e,0x1d,0x1d +,0x25,0x10,0x9f,0x18,0x18,0x36,0x32,0xa8,0x1b,0x9d,0x94,0xa4,0x8e,0xaf,0x95,0x8f,0xad,0x92,0xa5,0x8c,0x91,0xb3,0x96,0x96,0x8b,0x9f,0x9e,0x8f,0xa6,0xb0,0x2e,0x56 +,0x95,0xbc,0xaf,0x36,0x24,0xaf,0x22,0x12,0x21,0x3d,0x2e,0x34,0x46,0xbe,0xc9,0xbd,0xc2,0xa6,0xa9,0xaa,0xa5,0x3a,0xad,0xa4,0x27,0x4b,0xc1,0xfa,0xd0,0x2b,0x3d,0x2e +,0x1f,0x24,0x30,0x37,0x4b,0xbd,0x27,0x17,0x21,0x13,0x15,0x11,0x18,0x48,0x33,0x2b,0x33,0x3c,0x5c,0xb0,0xbb,0xa7,0x95,0xa8,0x28,0x34,0x39,0xb3,0x2f,0x2f,0xa6,0xb0 +,0x41,0x36,0x27,0x1e,0x69,0x52,0x41,0xa1,0xd3,0x16,0x1b,0x1c,0xd2,0x28,0x1c,0xc7,0xa0,0xb8,0xc6,0xab,0xc0,0x9b,0x98,0x9f,0x8f,0x8f,0x9b,0x9f,0xb7,0x95,0x95,0xbc +,0xc1,0x99,0xa6,0x34,0x39,0x21,0x27,0x4e,0x38,0x48,0x52,0x3b,0x2a,0x17,0x20,0x52,0x26,0x16,0x2e,0x53,0x2f,0x25,0x1c,0x23,0xaa,0x9d,0xa8,0xb0,0xa9,0xa4,0xe0,0x2f +,0xa5,0xa5,0x33,0x3d,0x4b,0x3b,0x1f,0x16,0x11,0x46,0xb1,0x3c,0x21,0x1b,0x2e,0x28,0x0f,0x24,0xbe,0x2b,0x28,0x27,0x39,0xd0,0x4f,0x38,0x9a,0x8f,0x99,0x9d,0xb7,0xa0 +,0x8e,0x9d,0x9e,0x93,0x9b,0x9e,0xaa,0x63,0xaa,0xbe,0x29,0x43,0xcd,0xb3,0xbc,0x21,0x2a,0xab,0x47,0x2c,0xcc,0x72,0x50,0xc2,0x2b,0x36,0x55,0x51,0xcd,0x54,0xb1,0x98 +,0xbe,0x5a,0x9e,0x9a,0x97,0x9d,0xa7,0xab,0xad,0x3d,0x29,0x22,0x29,0x34,0x26,0x1f,0xde,0x23,0x1a,0x2b,0x28,0x67,0x3d,0x20,0x2a,0x31,0x2b,0x32,0x1f,0x27,0xfe,0xea +,0x2b,0xae,0xb3,0xca,0xaa,0xc0,0xa7,0xa2,0xbd,0xa9,0xaf,0x2f,0x51,0x48,0x2b,0x24,0x37,0x38,0x34,0x1f,0x1c,0x22,0x19,0x26,0xb8,0x32,0x39,0xd4,0x43,0xcf,0x5c,0xca +,0xb8,0xac,0xb1,0xac,0xcc,0x38,0xaf,0xa5,0x9c,0x97,0xa7,0x9b,0x97,0xa7,0xaa,0x9e,0xa8,0xef,0xdf,0x37,0x27,0x21,0x1e,0x27,0x18,0x1f,0xce,0x35,0x36,0x5d,0xca,0xc0 +,0xa9,0xad,0xaf,0xb0,0xd0,0xac,0xc4,0x27,0x31,0x4c,0x5a,0xb6,0xed,0xb4,0xac,0x36,0x6e,0xb0,0xf4,0x6f,0xc0,0x36,0x29,0x2c,0x1d,0x1e,0x16,0x15,0x2a,0x19,0x15,0x20 +,0x1e,0x28,0x78,0xc3,0xa1,0x9e,0xbb,0xab,0xa0,0xc6,0xb6,0xaa,0xaf,0xaa,0xb2,0xa9,0xb2,0x26,0x56,0x9e,0xb3,0xa6,0x99,0xc0,0xc7,0xbc,0x41,0xcb,0xd3,0x3c,0x58,0xce +,0x2f,0x2b,0x23,0x2c,0xdd,0x7a,0x9c,0x9a,0x4a,0xb1,0xa0,0xc6,0x9e,0x95,0xa1,0x9f,0x9c,0x9f,0xaa,0x3c,0x4e,0xa9,0xea,0x5b,0xbe,0x20,0x20,0x2f,0x29,0xbe,0x36,0x1f +,0xc0,0xcf,0x20,0x25,0x1b,0x15,0x29,0x2a,0x3d,0x61,0x1e,0x28,0x59,0x25,0xda,0xa4,0xbb,0xb1,0xa2,0xa7,0xa9,0x5e,0x35,0xb7,0x37,0xd1,0xaf,0x24,0x1b,0x1e,0x1b,0x2f +,0x36,0x1d,0x3d,0xc3,0x27,0x34,0xdc,0x2f,0xde,0xb9,0x9d,0x9d,0x4e,0xb2,0xa4,0x3f,0xd4,0xa9,0x4b,0xb9,0x9c,0xa2,0x9c,0x9e,0xc2,0xa3,0x9b,0x92,0x90,0xca,0x2e,0x3a +,0x23,0x36,0x43,0x1d,0x29,0x52,0x1a,0x27,0x38,0x1a,0x2d,0x3e,0xa6,0x9b,0xd7,0xd5,0xa8,0x43,0x71,0x9e,0xba,0xcf,0xa0,0xcf,0xb5,0xbb,0x1d,0x3f,0x33,0x2f,0xba,0x2b +,0x1b,0x27,0x28,0x2e,0x3f,0x21,0x2c,0xba,0x2e,0x4a,0x5c,0x13,0x1c,0x37,0x34,0xb6,0xde,0x2f,0xe1,0x3e,0xc4,0x9d,0xac,0xba,0x9f,0xa0,0x9b,0x9d,0x35,0xbe,0xa2,0x46 +,0xae,0xad,0x21,0x1d,0x24,0x2f,0xae,0x69,0x2b,0x5a,0x2c,0xb6,0xa6,0x28,0x45,0xab,0xca,0x9e,0x97,0xb1,0xb5,0xdd,0xcf,0x9d,0xbf,0x2d,0xb6,0xb7,0x9b,0x93,0x4b,0xd3 +,0xb3,0x39,0xae,0xa4,0x35,0x1e,0x1e,0x2b,0xb5,0x36,0x1f,0x2b,0x1e,0x27,0xb4,0x1f,0x19,0x3b,0x33,0xae,0xaa,0x46,0x2f,0x2d,0xde,0x9c,0xa4,0x57,0xc1,0xdd,0xc8,0xa1 +,0x63,0x25,0x27,0x1e,0x41,0xcb,0x1f,0x1c,0x1d,0x3c,0xa5,0xbe,0x55,0x6c,0x3c,0xf7,0xa1,0xb0,0x2a,0x22,0x42,0xa4,0x9b,0xb7,0xcc,0x3d,0xc9,0x99,0xad,0x50,0x44,0x46 +,0xb9,0x9f,0x9e,0xc8,0x27,0x3d,0xa4,0x9a,0xcf,0x2f,0x26,0x41,0xa5,0xb4,0x76,0x2c,0x25,0x2d,0xc2,0x37,0x1f,0x19,0x25,0xa9,0x9e,0xa8,0xb2,0x3f,0xe8,0x9e,0x9d,0xa9 +,0x4e,0x62,0xb5,0xa2,0xaa,0xcf,0x26,0x1b,0x3f,0xdc,0x27,0x1a,0x0b,0x13,0xc9,0xa8,0xaf,0x30,0x21,0x35,0x9e,0xa1,0x3d,0x20,0x24,0xb7,0x9e,0xad,0xc9,0x23,0x22,0xa8 +,0x9d,0xb3,0x2b,0x1b,0x32,0xa0,0xa7,0xbd,0x43,0x28,0xbd,0x9e,0xa9,0xbc,0x24,0x21,0xab,0x9f,0xad,0xb0,0x29,0x2d,0x9e,0xa7,0xd9,0x2a,0x1a,0x4a,0x9f,0xab,0xd5,0x28 +,0x1d,0xbc,0x9e,0xbf,0xf7,0x24,0x26,0xac,0xa9,0xbf,0x3a,0x22,0xc6,0x93,0x97,0xb8,0x2c,0x1d,0xbc,0x9e,0xba,0xbd,0x29,0x1f,0xfa,0xb7,0xef,0x20,0x14,0x1f,0xc9,0xd8 +,0x26,0x1d,0x16,0xd5,0xa3,0xb9,0xb1,0x38,0x37,0xb1,0x9d,0x9f,0xaf,0x40,0xbb,0x9a,0x9d,0xcd,0x2e,0x19,0x2b,0xb6,0x34,0x3f,0x23,0x1a,0x37,0xb4,0xce,0x27,0x1b,0x2b +,0xaf,0xad,0x4a,0x54,0x30,0xac,0x9c,0xa2,0x9b,0xb4,0x4d,0x65,0xa2,0xb0,0x54,0x2f,0x42,0xa3,0xa2,0xec,0x34,0x2f,0x32,0xb8,0xb9,0x47,0x28,0x1d,0x2a,0xaa,0xd0,0x26 +,0x21,0x2c,0xab,0xa6,0x3e,0x3c,0xcd,0xba,0x9d,0x99,0xa9,0xad,0xbd,0x28,0xad,0xab,0x3b,0x2b,0x23,0xdd,0xbb,0x2e,0x24,0x28,0x1c,0x29,0xbf,0x55,0x50,0x3b,0x25,0xa7 +,0x9d,0xf7,0xb6,0x35,0x57,0xa1,0x6a,0x4f,0x3f,0x25,0x49,0xad,0x56,0xbb,0xb1,0x38,0xb9,0xb8,0x32,0xe7,0x2b,0x1f,0xa5,0xac,0xb3,0xb7,0x3c,0x5d,0xa4,0x2e,0x6c,0xa3 +,0x22,0x5e,0x45,0x2a,0x2a,0x4c,0x3c,0xa3,0xae,0x26,0xaf,0x36,0x53,0x9f,0xbd,0xcf,0x5a,0x33,0x45,0xac,0xae,0x58,0xef,0xca,0xbd,0x3f,0xc0,0x42,0x2f,0x2d,0xc8,0x8c +,0x9b,0x3c,0x20,0x1b,0x2b,0x4e,0x2e,0x2d,0xce,0x36,0xef,0xac,0xc4,0x23,0x26,0x6e,0x9e,0xa6,0x1c,0x1c,0x20,0x2d,0xb6,0x96,0x9c,0xa1,0xa9,0x2f,0x4a,0x28,0x0c,0x0c +,0xcb,0x89,0x8d,0xc2,0x46,0xa2,0x95,0x9f,0x1b,0x11,0x30,0xaa,0xa2,0x94,0x8d,0x2a,0x13,0x16,0x13,0x21,0x1f,0x12,0x13,0xc4,0x8c,0x91,0x56,0xac,0x9d,0x9d,0xb0,0x1e +,0x0d,0x0f,0xb1,0x89,0x8d,0x39,0x18,0xcd,0xa9,0x58,0x16,0x0a,0x1b,0x4b,0x25,0x23,0x96,0x87,0x85,0x88,0x88,0x8c,0x25,0x06,0x13,0x34,0x9d,0x9f,0xb4,0xa2,0xa0,0x51 +,0x07,0x05,0x0b,0x06,0x03,0x0f,0x9a,0x8b,0x8f,0x8b,0x9a,0x2e,0x22,0x11,0xf3,0xa8,0x95,0x84,0x83,0x86,0xdc,0x1c,0x2f,0xae,0x24,0x0d,0x07,0x0f,0x17,0xa4,0x8f,0xd3 +,0x9e,0x4b,0x1e,0x1a,0x1f,0x13,0x03,0x0f,0x8e,0x8f,0xab,0xb5,0xfc,0x9b,0x9d,0xb2,0x19,0x18,0xf4,0xa7,0x89,0x80,0x8b,0xa2,0xb6,0x99,0xa7,0x0a,0x04,0x02,0x10,0x91 +,0x9c,0x2f,0x2a,0x49,0xf4,0x0c,0x04,0x08,0x19,0xb1,0x8f,0x80,0x95,0x79,0xab,0x8f,0x8f,0x27,0x16,0xe8,0x94,0x8b,0x8f,0xaa,0xb1,0x6d,0x36,0x37,0x1c,0x1b,0x16,0x0f +,0x07,0x13,0x28,0x0e,0x3f,0x99,0x96,0x9d,0xd9,0x44,0x1d,0x1a,0x99,0x8b,0x8d,0x96,0x71,0xa0,0xa2,0x2b,0x14,0x29,0xaf,0x1f,0x2a,0x50,0xa3,0x9c,0x2a,0xee,0xb7,0x2e +,0x1e,0x18,0xb8,0x90,0x96,0x95,0xa1,0x2d,0x2e,0x1a,0x19,0x12,0x19,0x0f,0x1d,0x8d,0x96,0xb1,0x0c,0x13,0x97,0xad,0x2b,0x20,0x56,0x86,0x88,0x94,0x8f,0x3c,0xd9,0xaf +,0xa7,0xc7,0x0e,0x14,0x0e,0xbb,0x9e,0x67,0x37,0x14,0x9c,0x99,0x1c,0x11,0x0b,0x20,0x9f,0xb3,0x95,0x99,0xa4,0xa7,0x28,0x18,0x0a,0x0b,0x0c,0x9b,0x80,0x88,0x8f,0xc1 +,0x9f,0x9f,0xcd,0xab,0x1a,0x15,0xb5,0xac,0x9f,0xa4,0xcd,0x4e,0x24,0x14,0x03,0x03,0x02,0x16,0x90,0xa3,0x9d,0xad,0xbb,0xb6,0x24,0x30,0xaa,0x9e,0x8e,0x8c,0x8a,0x87 +,0x97,0x8b,0x91,0x43,0x0d,0x0d,0x1e,0x13,0x36,0x34,0x44,0x31,0x1c,0x4e,0x1e,0x16,0x21,0x15,0x0e,0x16,0x1e,0x96,0x8a,0x85,0x8c,0xd9,0x20,0x0c,0x13,0x1c,0xb3,0x8e +,0x88,0x87,0x96,0x98,0x9f,0x1f,0x21,0x2b,0x42,0xb9,0x1e,0x2b,0x9c,0x9f,0x5e,0x10,0x08,0x07,0x0c,0x0a,0x1e,0x9e,0xb7,0x9d,0xbb,0x9c,0x9a,0x32,0x53,0xb7,0x9c,0x8f +,0x9f,0xab,0x8c,0x89,0x8f,0x35,0x13,0x1c,0x35,0x14,0x11,0x42,0x23,0x3a,0x1f,0x2e,0xaf,0x20,0x26,0xc6,0x9b,0x9f,0xeb,0x30,0xbf,0xac,0xa4,0xae,0x58,0x39,0x2c,0x0c +,0x0c,0xbc,0x65,0x9d,0xae,0x9e,0x8d,0xc8,0x42,0x65,0x52,0xb3,0xa0,0x94,0x8f,0x99,0xa4,0x2e,0x27,0x19,0x15,0x0c,0x13,0xbe,0x22,0xda,0x27,0x1f,0x2f,0x13,0x3d,0xc9 +,0xba,0xa1,0xa0,0x96,0x8f,0xa5,0x32,0x30,0xb5,0xc4,0xb9,0x43,0x3a,0x98,0xa9,0x99,0xcb,0x28,0xe7,0x19,0x2f,0xae,0xb4,0xa9,0xec,0xb4,0xa6,0x29,0x13,0x0a,0x10,0x16 +,0x3d,0x2e,0x0f,0xde,0x49,0x71,0xd3,0x4c,0x97,0x9c,0x8e,0x8c,0x96,0x8d,0x95,0x9a,0x95,0xa4,0xaa,0x30,0x23,0x1a,0x16,0x10,0x08,0x24,0x25,0x2c,0x2f,0x13,0x32,0x24 +,0x10,0x17,0x2a,0x9a,0x8e,0x91,0x8e,0x8f,0x9a,0x48,0x28,0x29,0x49,0x9d,0xb7,0xa1,0x9c,0xb1,0xb3,0x1b,0x37,0xb4,0x27,0x2c,0x2c,0x44,0xa7,0xb5,0x53,0x3c,0x2c,0x1d +,0x17,0x19,0x18,0x3e,0x2e,0xd5,0x9e,0xae,0xc4,0x22,0x39,0xaf,0xa5,0x99,0x99,0x97,0x94,0x99,0xb2,0xb6,0xb0,0xbe,0x69,0x39,0x2b,0x1b,0x0e,0x0e,0x27,0x2d,0x28,0x1c +,0x43,0xa0,0x9f,0xad,0xcf,0xb0,0xbb,0xba,0xb6,0x9d,0x99,0xac,0x42,0x1c,0x1a,0x1d,0x1c,0x3c,0xc7,0xd1,0xbe,0x33,0x2e,0xae,0xb3,0xa4,0x96,0x9a,0x9e,0xa5,0x9f,0xaf +,0xab,0x5b,0x2f,0x25,0x1d,0x1c,0x16,0x1e,0x20,0x2c,0x24,0x21,0x17,0x1b,0xbb,0xbd,0xa1,0x9c,0x9a,0x96,0xab,0xd3,0xab,0x93,0x9f,0xb1,0xcc,0x9f,0x9e,0xaf,0x1e,0x18 +,0x4e,0x1d,0x1e,0x12,0x4e,0x9e,0xb2,0xcb,0x35,0x3d,0x3b,0x1e,0x24,0x3b,0xc1,0x39,0x1e,0x35,0x2f,0x46,0x4f,0x3c,0xb7,0x98,0x96,0x99,0xc1,0x9d,0x98,0x99,0x95,0xce +,0xac,0xad,0xc1,0x36,0x1f,0x2b,0x1f,0x1e,0x21,0x1d,0x1c,0x17,0x18,0x17,0x1c,0x28,0x2a,0x3a,0xc4,0xa6,0x93,0x94,0x9a,0x9e,0xa3,0x9b,0x99,0x94,0xa4,0xad,0x9f,0xee +,0x36,0x33,0x1e,0x26,0x1c,0x19,0x1b,0x20,0xc6,0x26,0x1d,0x29,0x1a,0x28,0x2a,0x50,0xb0,0xa4,0x90,0x9d,0xa5,0xac,0xb3,0xa6,0x64,0x40,0x53,0xa6,0x98,0xa6,0xa7,0xb1 +,0x3d,0x2a,0x27,0x1d,0x27,0x2e,0x25,0x25,0x3c,0xd7,0x3d,0x4c,0x21,0x27,0xc8,0xbb,0xb2,0xc0,0xb8,0xa1,0xa0,0xb6,0x3c,0xe4,0xbc,0x5f,0x4e,0x1f,0x20,0x4f,0xa9,0xa1 +,0xba,0xbb,0x58,0x31,0x45,0x39,0x33,0x3b,0xb9,0xa0,0xac,0xa3,0xa5,0xb0,0xb1,0xdb,0x41,0x2b,0x23,0x21,0x2a,0x7b,0xbf,0x3c,0x21,0x1f,0x24,0x24,0x2f,0x3c,0x4d,0xae +,0x9e,0x9f,0xa9,0xb7,0xae,0xa4,0xad,0xb7,0xc0,0xa7,0xa1,0xa6,0xad,0xd8,0xcd,0x28,0x1d,0x1f,0x2c,0x48,0x2b,0x1d,0x20,0x20,0x25,0x32,0x29,0xbd,0xe0,0x66,0x2d,0x29 +,0x3b,0x5b,0x97,0x91,0x94,0x9b,0xa4,0x99,0x98,0x9b,0x99,0xc7,0xd8,0x32,0x2b,0x3c,0x21,0x20,0x14,0x15,0x1e,0x17,0x1a,0x19,0x23,0x35,0x32,0xbe,0xe8,0xb3,0xae,0xad +,0x9f,0xa4,0xa8,0x9f,0xa4,0xa2,0xa0,0xa3,0x9f,0xa4,0xaa,0x65,0x3d,0x3d,0x36,0x33,0x1f,0x1d,0x2f,0x1e,0x1e,0x2d,0x3d,0x6f,0x2e,0x1e,0x18,0x23,0xb0,0xb7,0xae,0xad +,0xaa,0x9a,0xa9,0x9a,0xac,0xb3,0xa7,0x67,0xbc,0xaf,0x9d,0x9e,0xb5,0xe1,0x23,0x26,0x2a,0x18,0x1a,0x17,0x28,0x26,0x16,0x2e,0x46,0xb3,0xbc,0x3f,0xf6,0xbe,0xa1,0xaa +,0xa4,0x9a,0x98,0x9e,0xb1,0xbf,0xb4,0x3b,0x30,0x55,0x39,0x55,0x3b,0x2c,0x32,0x3e,0xbd,0x3d,0x20,0x24,0x1f,0x66,0xae,0xae,0x49,0x2c,0xb6,0xae,0xaf,0xb8,0x66,0xac +,0x43,0x42,0xb5,0xbe,0xa4,0xcf,0xea,0x47,0x2b,0x33,0x22,0x32,0xbe,0xbe,0xaf,0x34,0x48,0x40,0x32,0xb6,0xc0,0x4c,0x2e,0x36,0xb2,0xbc,0xce,0xf3,0xcd,0x9d,0xbc,0xb7 +,0xbf,0xbc,0xa9,0xb9,0xaf,0xc2,0x26,0x1f,0x1f,0x31,0xcd,0x2e,0x1e,0x13,0x21,0x32,0xcf,0xb5,0xc6,0xac,0xae,0xa3,0x9a,0xa6,0xab,0xa0,0xa7,0xbb,0x3f,0xde,0xd8,0xc7 +,0xc5,0x55,0xc7,0x38,0x26,0x22,0x22,0x3f,0x40,0x1f,0x24,0x3d,0xcf,0xc8,0x49,0xca,0x62,0xa7,0xb3,0xd4,0xdb,0x39,0xb0,0xb6,0xa6,0xaa,0x52,0x4f,0xca,0xba,0xca,0x34 +,0x4e,0x3d,0x61,0xa1,0x9b,0xab,0x2c,0x24,0x21,0x58,0xbe,0x2c,0x1e,0x1f,0x53,0xa5,0xc0,0x33,0x2f,0x3a,0xc3,0xb7,0xc7,0x4a,0xc7,0xab,0xae,0xad,0xb7,0xb8,0xbf,0x3c +,0x40,0x2f,0x27,0x2b,0x36,0xdf,0xa2,0xa8,0x5f,0x23,0x48,0x9e,0xa6,0xb9,0x28,0x45,0xa9,0x9d,0xaf,0x30,0x36,0x2d,0x2f,0x50,0x39,0x1d,0x18,0x1a,0x2a,0xc0,0xa2,0xbb +,0x3c,0x3e,0xb2,0x9f,0xaa,0xea,0x47,0xa8,0x99,0x94,0x9c,0x7a,0x31,0x49,0xbb,0xbd,0x2c,0x1f,0x2d,0x2b,0x31,0x4a,0x33,0x38,0x32,0x2e,0x39,0xed,0x36,0x27,0x40,0xae +,0xaa,0xbb,0x4d,0x3f,0xbc,0xa4,0xae,0x2b,0x1d,0x5f,0x9c,0x96,0x9e,0xbb,0xec,0x42,0x9f,0x9d,0x5c,0x1d,0x1d,0x27,0x3c,0x49,0x2e,0x22,0x1b,0x2a,0x3d,0xcf,0x46,0x1f +,0x1c,0xb8,0x95,0x91,0x9f,0xad,0xad,0xa5,0x9d,0xb1,0x3b,0x41,0xd4,0xbf,0xcc,0x33,0x2f,0x28,0x2f,0x35,0x26,0x1c,0x16,0x1f,0x76,0xd7,0xb2,0xbc,0xbd,0xad,0x9b,0x96 +,0xcb,0x24,0x28,0xa7,0x93,0x98,0xfa,0x32,0xf6,0xa6,0xa6,0x47,0x1f,0x15,0x1a,0x3a,0xaf,0xad,0x43,0x18,0x2d,0xbc,0xb2,0xba,0x1f,0x1c,0x37,0xb1,0xa0,0xa8,0xb5,0xbf +,0xb1,0x9f,0xb3,0x2e,0x25,0xb9,0xa0,0xa5,0xab,0xee,0xfe,0xab,0xb6,0x39,0x21,0x12,0x1a,0x21,0x2d,0x37,0x34,0x38,0x49,0xc0,0xb8,0xb4,0x43,0x2a,0xaf,0x97,0x92,0x9e +,0xe9,0xcb,0xa2,0x96,0xa3,0x35,0x14,0x19,0x2f,0x4e,0xe2,0x27,0x1e,0x1d,0x2e,0xc2,0xca,0x31,0x28,0x28,0x54,0xa0,0x9b,0x9b,0xab,0x9f,0x9e,0xa8,0xcf,0x27,0x37,0xd0 +,0xbb,0x42,0x32,0x2a,0x3f,0xbd,0xb5,0x42,0x20,0x1b,0x23,0xb7,0xc0,0xfd,0x2f,0xd3,0xc8,0xae,0xae,0x33,0x24,0x25,0xb4,0x9d,0xa1,0xdc,0x3e,0xbc,0x95,0x96,0xb1,0x23 +,0x1a,0x30,0x58,0xb0,0xb5,0x36,0x20,0x27,0x2c,0x39,0x3d,0x29,0x32,0x2e,0x36,0x58,0xb8,0xa1,0x9e,0x9c,0x9a,0xb0,0x2f,0x21,0x71,0x9f,0xa9,0x4e,0x36,0x4b,0xb1,0xb1 +,0x58,0x28,0x15,0x1f,0x25,0x3e,0x4d,0xec,0xbe,0xbe,0xc2,0x4a,0x47,0x4e,0xbf,0xa1,0x9f,0xac,0xbd,0x41,0x53,0xa8,0x98,0xa7,0x2e,0x16,0x13,0x2c,0xaf,0xb6,0xad,0x3e +,0x25,0x34,0x4f,0xde,0x3b,0x39,0x37,0x4e,0x5e,0x4e,0xac,0x9e,0xa2,0xb1,0x46,0x45,0x36,0xd8,0xa8,0x9a,0xa7,0x2c,0x2b,0x3d,0xb7,0xa2,0xc0,0x24,0x19,0x16,0x26,0x41 +,0xc2,0xad,0x5a,0x34,0x38,0x2f,0x51,0xbc,0xa7,0x9d,0xa7,0xbc,0xce,0xda,0xb4,0xa2,0xa4,0x42,0x1f,0x22,0x36,0xaf,0xba,0xd9,0x2f,0x20,0x22,0x40,0xbb,0xc9,0x43,0x3c +,0x37,0x2c,0x45,0xa7,0xa2,0xaa,0x9f,0xdb,0x3f,0x37,0x3d,0xb0,0xa2,0xb0,0x62,0x1d,0x22,0xdb,0xb0,0xa9,0x4d,0x2e,0x27,0x2e,0x3c,0xb0,0xba,0x6c,0x31,0x3b,0x39,0xd2 +,0xbc,0xc7,0xbb,0xf6,0x52,0x53,0xbc,0xad,0xa2,0xac,0xa5,0x34,0x29,0x32,0x6e,0xaf,0xcc,0xc6,0x2d,0x25,0x28,0xc5,0xbd,0x53,0x3f,0x24,0x2f,0x2f,0xca,0xac,0xad,0xac +,0xb5,0x4d,0x34,0xba,0xac,0xac,0xae,0xc5,0x2f,0x2a,0x4b,0xad,0xa2,0xd2,0x1f,0x1a,0x1e,0x3b,0xd3,0xad,0xb3,0x28,0x20,0x38,0xbf,0xa6,0x9b,0xaa,0xe6,0xc2,0xe6,0xbf +,0xaf,0xb7,0xaf,0x43,0x25,0x27,0x35,0xf2,0xae,0xad,0xdb,0x2f,0x21,0x30,0xbe,0xb7,0xc2,0x42,0x3f,0x45,0x38,0xcc,0xb7,0xb5,0xc9,0xbf,0xcc,0xc9,0xd5,0xe5,0xc0,0xba +,0xbd,0x45,0x2b,0x2a,0x75,0xc6,0xe9,0x3f,0x2b,0x24,0x3c,0xb5,0xb0,0xaf,0x3a,0x24,0x3a,0x5d,0xa9,0xa6,0xa5,0xb8,0xcc,0xbd,0xb7,0xae,0x4e,0x46,0x4a,0x65,0x52,0x43 +,0x3c,0x42,0x36,0x38,0x58,0x47,0x47,0x4a,0x3b,0x33,0x39,0xe8,0xc0,0xa7,0xa4,0xb9,0xd0,0x4a,0x4f,0xd3,0xab,0xb2,0xc0,0xd9,0x2f,0x28,0x44,0x3b,0x2c,0x39,0xdd,0xae +,0x63,0x3e,0x3f,0x61,0xbf,0xb8,0xb7,0xcf,0x45,0x2a,0xc6,0xbd,0xcf,0xdf,0x45,0xbf,0xc6,0xa7,0xb4,0x47,0x33,0x34,0x47,0xe9,0xbd,0xc4,0x5e,0x40,0x3a,0x2e,0x36,0x2e +,0x44,0xbc,0xdb,0x48,0x4e,0x53,0xcb,0xb5,0xad,0xb3,0xe1,0xda,0xad,0xb0,0xcf,0xbe,0x44,0xd2,0xac,0xb7,0xfd,0x2a,0x1d,0x1e,0x38,0xda,0xd1,0xd3,0x5b,0x2a,0x2b,0x4f +,0xf3,0x45,0x67,0xa9,0xad,0xb3,0xba,0xc0,0xaf,0xbb,0xb1,0xac,0xe4,0x39,0x34,0x3d,0x6c,0x5a,0x45,0xe6,0x39,0x35,0xe1,0x6a,0x32,0x30,0x42,0x4a,0xfa,0xed,0xb3,0xb5 +,0xd5,0x7e,0x4e,0x37,0x39,0xc1,0xad,0xa4,0xc4,0x41,0x4a,0x33,0xf9,0xbc,0xbb,0x66,0x3c,0x4f,0xbd,0x45,0x36,0xc4,0xca,0xdf,0x71,0x4b,0x25,0x24,0x26,0xd5,0xa8,0xbb +,0xc4,0x4a,0xc3,0xb5,0xc8,0xb9,0xc1,0x52,0xda,0xa8,0xa8,0xbe,0x4f,0x4a,0x3a,0x4f,0xd9,0x49,0x36,0x2c,0x5f,0x35,0x27,0x3d,0xbe,0x6f,0xbc,0xbc,0x39,0x2e,0x3a,0xa8 +,0xa0,0x9f,0xc6,0x52,0xe3,0xbf,0xba,0xfd,0x5d,0x24,0x28,0x5e,0xb8,0xb9,0x48,0x53,0x36,0x2f,0x44,0x5a,0xc9,0x3d,0xdf,0xc9,0x48,0xf7,0xcb,0xc8,0xbe,0xc7,0xce,0xd0 +,0x38,0x37,0xb6,0xa7,0xe5,0xfb,0xc7,0xcb,0x77,0x35,0xe9,0xd0,0x37,0xdb,0xf6,0xd7,0x3b,0x42,0xb5,0x38,0x2f,0x33,0xcc,0xcc,0xcd,0xba,0xbb,0x7c,0xf2,0xb7,0xad,0xb8 +,0xd6,0xbe,0x3f,0x33,0x3f,0xba,0x52,0x3c,0x55,0x4d,0x3c,0x36,0x3b,0x58,0x45,0x3a,0x59,0x57,0xc6,0xdb,0xb2,0xae,0x50,0x31,0xc2,0xa7,0xb7,0xc6,0xbe,0xe0,0x41,0x5c +,0xb7,0xc0,0x38,0x31,0x3f,0x37,0x3a,0xed,0x4b,0x2e,0x3b,0x53,0xbc,0xd3,0x3e,0xb8,0xf7,0x43,0xb8,0xa8,0xae,0xc9,0xbf,0xca,0xfb,0xcc,0xbd,0xc0,0x47,0x4a,0x60,0x65 +,0x38,0x3b,0xcf,0xc9,0x42,0x3b,0xdf,0x42,0x33,0x41,0x65,0x3f,0x39,0x47,0xc0,0x64,0xd5,0xb3,0xbd,0x54,0x3e,0x74,0xc3,0xae,0xb6,0xb5,0xca,0x41,0x3b,0x4e,0x57,0x4b +,0xdb,0xf0,0x48,0x39,0x3f,0xbf,0xb5,0x40,0xe6,0x6d,0x3a,0x48,0xce,0xb8,0x62,0x5c,0xba,0xbd,0x33,0x5e,0xb3,0xdf,0x45,0x4d,0x62,0xbe,0xbb,0xcc,0xb3,0xbd,0x39,0x57 +,0x4f,0x3d,0x2d,0x33,0x4e,0x3c,0xc4,0xc0,0xe0,0x65,0xcb,0xd7,0xbe,0xb8,0x40,0x43,0x52,0x4d,0xb6,0xaf,0x7e,0x36,0x3c,0x35,0x6c,0xd5,0xd8,0xc5,0x2f,0x4a,0xcb,0xba +,0xfb,0x70,0x56,0x48,0x47,0x56,0xc2,0x63,0xbc,0xb8,0xb2,0xce,0xc6,0xbf,0xc7,0x4f,0x4d,0xef,0x6f,0x6b,0x47,0x4f,0x39,0x3c,0x42,0x7d,0x4e,0x6b,0xde,0x4c,0x3b,0x62 +,0xac,0xae,0xc4,0x6b,0x47,0x56,0x44,0xd9,0x5f,0x3a,0xe4,0xc9,0xb0,0xb3,0xc7,0x57,0x47,0x47,0x36,0x45,0xb8,0x62,0x31,0x33,0x3d,0x6f,0xdf,0x69,0x3b,0x38,0x46,0xc3 +,0xb7,0xbb,0xac,0xb4,0xce,0xbc,0xae,0xaf,0x4d,0x2d,0x2a,0x3c,0x6b,0xc4,0xb7,0xce,0x73,0xcc,0xc8,0xf3,0x49,0x3d,0x31,0x2c,0x46,0xdf,0xfe,0x47,0x5a,0xd5,0xb8,0xae +,0xad,0xb3,0x57,0x39,0xc4,0xb1,0xc2,0xcc,0x5e,0x4b,0x36,0x2b,0x27,0x34,0x4c,0xd3,0xc4,0xc9,0xcb,0xc3,0xb8,0xc5,0x7d,0x3e,0x48,0xe6,0xc7,0xd1,0x4c,0x31,0x44,0xb7 +,0xac,0xac,0x53,0x2d,0x2e,0x38,0xbe,0xa6,0xb3,0xdc,0xcc,0xc1,0xc5,0x58,0x37,0x38,0x29,0x2e,0xce,0xc0,0xaf,0xaf,0xce,0x3a,0x45,0x58,0xba,0xbc,0x3c,0x4f,0x58,0x47 +,0xc6,0xae,0xb7,0xcd,0x36,0x30,0x45,0x3e,0x65,0xed,0xde,0xb5,0xae,0xb6,0x5a,0x2a,0x22,0x2c,0x3a,0xbd,0xaa,0xbe,0x59,0x7c,0xb3,0xac,0xb9,0x62,0x3b,0x2e,0x38,0xd5 +,0xbc,0xc3,0x60,0xdf,0xc4,0xd8,0x4a,0x48,0x67,0x39,0x36,0x54,0xcb,0xbe,0xad,0xa7,0xb5,0x2e,0x24,0x2b,0x4a,0xc2,0xc8,0xc5,0xdc,0xaf,0xa6,0xb4,0x48,0x33,0x2d,0x3f +,0x65,0xda,0x5f,0x2a,0x30,0xc0,0xa5,0xad,0x40,0x25,0x28,0x40,0xc4,0xab,0xaa,0xce,0x56,0xc8,0xb8,0xca,0x33,0x2a,0x2b,0x2a,0x38,0xb8,0xa5,0xa9,0xb5,0xc4,0xda,0x5b +,0x40,0x62,0x7e,0x3e,0x35,0x37,0x53,0xb2,0xa6,0xad,0x50,0x2d,0x31,0x4d,0xf0,0xea,0xd7,0x79,0xb9,0xa7,0xa5,0xb6,0x28,0x1a,0x28,0x78,0xbf,0xda,0x45,0x43,0xbf,0xa8 +,0xa6,0xb3,0x3a,0x30,0x35,0x31,0x4b,0xca,0x4f,0x54,0xe4,0xbc,0xbb,0x51,0x38,0x40,0x4c,0x39,0x4e,0xcf,0xb4,0xa9,0xab,0xc3,0x3e,0x2a,0x3c,0xc3,0xbd,0xef,0x3a,0x4a +,0xc4,0xb3,0xb3,0xb8,0x37,0x28,0x4f,0xca,0x4d,0x40,0x3e,0xcf,0xad,0xa6,0xac,0x42,0x2b,0x2a,0x44,0xc3,0xcf,0x68,0x40,0x49,0xbb,0xaa,0xb1,0x37,0x21,0x2a,0x4b,0xbf +,0xbc,0xcc,0xea,0x78,0xce,0xb0,0xb0,0xcf,0xe3,0x53,0x2e,0x2a,0x2c,0x4b,0xbb,0xb5,0xb3,0x5b,0x28,0x2a,0xe8,0xac,0xb1,0x42,0x3f,0xb1,0xa7,0xb3,0xbe,0x3a,0x28,0x37 +,0x50,0xf7,0x46,0x33,0x43,0xbc,0xa2,0x99,0xab,0x32,0x25,0x2c,0x5c,0xe5,0x32,0x2d,0x33,0x66,0xa3,0x9e,0xbd,0x34,0x2a,0x30,0x4d,0x70,0xcc,0xbe,0xbc,0xba,0xba,0xe1 +,0x3c,0x32,0x3b,0xe7,0x49,0x30,0x32,0x5a,0xad,0xa3,0xa9,0xbe,0x3d,0x35,0x43,0x3b,0x31,0x33,0x41,0xc2,0xab,0xa8,0xe3,0x2d,0x2f,0x54,0xb2,0xb0,0x5e,0x3f,0x4f,0xb4 +,0x9e,0xa6,0xdc,0x28,0x1f,0x2e,0x46,0x44,0x3d,0x36,0x63,0xb8,0xb0,0xaf,0xee,0x7e,0xba,0x4f,0x38,0x37,0x2e,0x3c,0xc3,0xde,0xb8,0xbd,0xbf,0xa9,0xcf,0x2e,0x46,0x26 +,0x2c,0x6c,0x38,0x35,0xc1,0x9d,0x95,0x90,0xc8,0xc7,0x21,0x35,0xc3,0x9d,0x61,0x3d,0xcc,0x03,0x11,0x06,0x2e,0xad,0x13,0xb2,0x0e,0xb3,0x95,0xae,0x8f,0x8d,0x8c,0x92 +,0x88,0xad,0x31,0x8f,0x9d,0x0e,0xbc,0x15,0xc6,0x81,0x9a,0xb2,0x9a,0xc1,0x1d,0x1a,0x05,0x0a,0x05,0x03,0x08,0x0f,0x05,0x10,0x06,0x0b,0x15,0x09,0x1b,0x1f,0x14,0xaa +,0x91,0xbd,0xa4,0x9e,0x94,0xaf,0xa4,0xbb,0x9f,0x98,0x94,0x8a,0x89,0x93,0x85,0x89,0x84,0x82,0x84,0x8b,0x9a,0x83,0x1f,0x2b,0xc7,0x8c,0x14,0x09,0xab,0x07,0x0f,0x0f +,0x0e,0x0e,0x11,0x0b,0xcc,0x1c,0x0a,0x0a,0x00,0x13,0x05,0x04,0x06,0x16,0x28,0x15,0x30,0xc4,0x14,0x22,0x9c,0x4b,0x8d,0x84,0x87,0x9c,0x93,0x8f,0x8a,0x85,0x81,0x8a +,0x99,0x8f,0x8b,0x80,0x89,0x8e,0x44,0xa1,0xa4,0x95,0x8f,0x46,0x15,0x12,0x2e,0x2f,0x36,0x0c,0x01,0x07,0x0b,0x0c,0x0c,0x03,0x04,0x0a,0x0d,0x0d,0x0c,0x0a,0x01,0x36 +,0xc8,0x99,0xa1,0x28,0x8c,0x8d,0x8b,0x8d,0x41,0x21,0x9c,0x92,0x94,0xfe,0x99,0x90,0x99,0x8d,0x80,0x89,0x9c,0x92,0x84,0x82,0x8c,0x9b,0x09,0x15,0x36,0xd3,0x99,0x1e +,0x08,0x04,0x1f,0x9a,0x0e,0x01,0x1a,0x1a,0x15,0x2f,0x0e,0x1b,0x10,0x06,0x03,0x0c,0x0e,0x1c,0x13,0x37,0x81,0xcd,0x9e,0x25,0xad,0x89,0x8e,0x86,0x46,0x90,0x96,0x38 +,0xa8,0x8b,0x84,0x81,0x90,0xba,0x91,0xa2,0x85,0x4b,0xa5,0x8e,0x9f,0x8e,0x18,0xae,0xad,0x0d,0x06,0x38,0x99,0x8f,0x49,0x03,0x04,0x15,0xa8,0x11,0x0d,0x0e,0x00,0xa2 +,0xab,0x27,0xa7,0x01,0x01,0x27,0x8c,0x84,0x9a,0x90,0x8b,0xa0,0x8e,0x2b,0x05,0x8e,0x84,0xa7,0x0c,0x02,0x95,0xd6,0x00,0x20,0x07,0x14,0x8f,0x9a,0xa1,0x1a,0x10,0x0c +,0x06,0xaf,0x98,0xc4,0x0f,0x15,0x0e,0x03,0x05,0x13,0xa5,0xaf,0x8d,0x39,0x92,0x1e,0x24,0x85,0x8b,0x87,0x92,0x8f,0xab,0x8f,0x86,0x92,0x14,0x13,0x8b,0x81,0x81,0x88 +,0x89,0x8f,0x21,0xc4,0x91,0x80,0x8c,0x92,0x95,0x87,0xad,0x0a,0x0f,0xa7,0x84,0xa9,0xac,0x05,0x8a,0xd2,0x15,0xc8,0x38,0x1f,0x00,0x8e,0x5d,0x0e,0x00,0x05,0x00,0x07 +,0x93,0x0f,0x1f,0x07,0x00,0x0a,0x26,0x9c,0x00,0x05,0x01,0x14,0x8b,0x4e,0x25,0x00,0x03,0x05,0x95,0x80,0x81,0x90,0x2a,0x8f,0x9b,0x89,0x9c,0x85,0x80,0x8a,0x9d,0x89 +,0x85,0xd9,0x2d,0x0c,0x86,0x82,0x83,0x51,0x0a,0xa4,0x87,0xce,0x13,0x14,0x0e,0xc3,0x22,0xb8,0x0a,0x06,0x0b,0x00,0x0c,0xae,0xa7,0x34,0x1c,0x09,0x05,0x0b,0x97,0xae +,0x18,0x27,0x95,0x84,0x8a,0xed,0x04,0x09,0x2f,0x80,0x82,0x80,0xa6,0x0f,0x63,0x9a,0x80,0x84,0x89,0xe1,0x97,0x80,0x86,0x86,0x53,0x13,0x02,0x25,0x84,0x95,0xb2,0x04 +,0x01,0x08,0x14,0x0d,0x00,0x07,0x00,0x04,0x05,0x08,0x09,0x00,0x02,0x00,0x0f,0x21,0xb4,0x0d,0x02,0x08,0x0a,0x0b,0x1c,0x9f,0xa9,0x3a,0x91,0x94,0x97,0x84,0x2d,0x97 +,0x8d,0x83,0x80,0x81,0x85,0x96,0xab,0x87,0x84,0x86,0x9a,0x8d,0x83,0x8a,0x8d,0x8e,0x95,0x0a,0x00,0x26,0x82,0x82,0x8a,0x0c,0x0d,0x04,0xa4,0x88,0x8b,0xda,0x14,0x91 +,0x31,0xb4,0x11,0x05,0x05,0x00,0x96,0x89,0x92,0x1c,0x00,0x02,0x04,0xb3,0xba,0x2e,0x23,0x0c,0x0d,0x0e,0xa8,0x1a,0x00,0x05,0x05,0x8e,0x96,0x89,0x42,0x18,0x15,0x2a +,0x91,0x8c,0x85,0x8e,0x94,0x8c,0x81,0x8c,0x8d,0xba,0x18,0x20,0x80,0x8a,0x80,0xd8,0x05,0x05,0x0d,0xa1,0x89,0xb3,0x0f,0x0d,0x0d,0x0e,0x11,0x36,0x05,0x05,0x04,0xa4 +,0x89,0x87,0x09,0x01,0x08,0x09,0x89,0x8a,0x91,0x8f,0xa3,0x9f,0x9c,0x8e,0x97,0xaa,0x90,0x94,0x80,0x81,0x80,0x8b,0xa2,0xa9,0x8a,0x80,0x81,0x8b,0x99,0xa7,0x97,0xba +,0x95,0x96,0x2e,0x44,0x05,0x67,0x4d,0x91,0x12,0x03,0x0f,0x00,0x08,0x1a,0xe0,0x0c,0x06,0x00,0x04,0x00,0x05,0x04,0x03,0x00,0x06,0x14,0xa5,0x21,0x00,0x07,0x00,0x1b +,0xbf,0x94,0x9b,0x9d,0x15,0xb1,0x98,0x92,0x86,0x9f,0x9b,0x8d,0x80,0x82,0x80,0x8b,0x98,0x96,0x8c,0x84,0x80,0x82,0x89,0xa1,0x95,0xa7,0x8f,0x8e,0xb8,0x4a,0x0e,0x0f +,0x9d,0x89,0x4e,0x0a,0x06,0x06,0x16,0x92,0x9e,0xe2,0x29,0x0f,0x02,0x16,0xa9,0xbe,0x46,0x04,0x0f,0xa9,0x8e,0x8b,0x1e,0x02,0x03,0x0d,0xb4,0x91,0x8f,0x9b,0x0b,0x06 +,0x07,0xbd,0x8f,0x33,0x0b,0x04,0x28,0x92,0x85,0xa3,0x20,0x15,0x00,0x1a,0x97,0x83,0x9b,0x0d,0xdd,0x19,0xac,0x97,0xa4,0x2a,0x01,0x38,0x91,0x89,0xa3,0x21,0x0a,0x0f +,0x29,0x42,0x86,0xa1,0x18,0x0b,0x0e,0x16,0xa8,0x9f,0x5f,0x11,0x1b,0xb3,0x8b,0x80,0x73,0xb4,0x0f,0x1c,0x9e,0x87,0x81,0x82,0xa1,0x1d,0x22,0xa3,0x80,0x8b,0x94,0x47 +,0x98,0x93,0x81,0x81,0x84,0x99,0x0d,0xc9,0x88,0x81,0x86,0x8f,0x66,0x9f,0x2d,0xaa,0xa2,0x2c,0x0b,0x05,0x1d,0x20,0x92,0x21,0x04,0x03,0x04,0x03,0x27,0x26,0x07,0x05 +,0x04,0x01,0x04,0x0f,0x04,0x05,0x05,0x0b,0x0d,0xa3,0x30,0x13,0x09,0x00,0xc3,0x92,0x83,0x81,0x89,0xa0,0x4c,0x94,0x89,0x8e,0x88,0x8e,0x94,0x85,0x83,0x80,0x8a,0xb6 +,0xcc,0x1e,0x2d,0x8f,0x82,0x88,0xa3,0x25,0x09,0x2e,0x9d,0x24,0x16,0x0e,0x21,0x16,0x90,0x8a,0xa9,0xa5,0x0b,0x26,0xaa,0x89,0x8b,0x8b,0xdb,0x12,0x43,0x95,0x93,0x98 +,0x22,0x0e,0x4b,0x44,0x89,0x3d,0x11,0x0f,0x07,0x0f,0xae,0x8f,0xa2,0x07,0x01,0x02,0x05,0x18,0x0d,0x1b,0x04,0x09,0x28,0xc0,0xa2,0x30,0x09,0x07,0x0d,0x5b,0x8b,0x81 +,0x89,0x4a,0x0e,0x19,0x98,0xa7,0x9a,0x1b,0x0b,0xb9,0xa8,0x89,0xa0,0x7a,0x1e,0x07,0xde,0xa2,0x8b,0x88,0x1b,0x52,0x0d,0x67,0x92,0xa8,0x8d,0x15,0xaa,0xa0,0x8d,0x8e +,0xae,0x5c,0x0a,0xb1,0x88,0x8a,0x80,0x8b,0x42,0x12,0x1e,0x8d,0x8b,0x82,0x9e,0x9e,0x8d,0x8c,0x80,0x9d,0xab,0x0f,0x07,0x9c,0x86,0x83,0x8f,0xd8,0x0c,0x0a,0x14,0x3d +,0xb7,0x16,0x00,0x14,0x0e,0xd4,0xea,0x03,0x0d,0x00,0x04,0x0c,0x33,0x12,0x06,0x03,0x01,0x05,0x24,0x51,0x34,0x0c,0x07,0x18,0x32,0x8b,0x78,0x1a,0x0b,0x19,0x9c,0x88 +,0x80,0x9b,0x27,0x3c,0x19,0x85,0x8f,0x90,0x91,0x1e,0x8d,0x85,0x80,0x8d,0x97,0x13,0x1d,0x9c,0x8a,0x81,0x82,0xab,0x9f,0x38,0x2d,0x8c,0xab,0xa0,0x29,0xb8,0xa9,0x83 +,0x91,0x9e,0x9f,0x04,0x31,0x90,0x9c,0x82,0xaa,0x05,0x14,0x0e,0xa1,0x9a,0x9f,0x0e,0x14,0x28,0xd6,0x89,0x0f,0x13,0x09,0x02,0xa7,0x92,0x9e,0xa2,0x0c,0x00,0x08,0x0d +,0x0c,0x2b,0x0a,0x00,0x41,0x17,0x8f,0x9b,0x0b,0x0c,0x02,0x08,0x98,0x89,0x8f,0x97,0x1e,0x0a,0xa3,0x98,0xb7,0x92,0x05,0x3c,0x8e,0x8c,0x86,0x8e,0x14,0x0b,0xa5,0xa1 +,0x80,0x88,0x1f,0x23,0x0c,0x10,0x82,0x9e,0x98,0xca,0x1a,0xb6,0x89,0x9e,0x2a,0xd8,0x01,0x2e,0x91,0x8e,0x80,0x8f,0x17,0xdd,0x16,0xa2,0x82,0x8f,0xa3,0x8e,0x8b,0x89 +,0x80,0x9a,0x95,0x23,0x09,0x9a,0x88,0x96,0x89,0x23,0x06,0x20,0x58,0x3d,0xa2,0x0e,0x00,0x23,0x07,0xed,0x2a,0x02,0x01,0x03,0x00,0x1e,0x2d,0x07,0x08,0x01,0x00,0x10 +,0x18,0x0d,0x45,0x01,0x1b,0x9a,0x9f,0x9e,0x2e,0x00,0x08,0x24,0xb2,0x80,0x80,0x9a,0xa5,0x34,0x18,0x81,0x97,0x9c,0x9a,0x8f,0x89,0x80,0x8a,0x91,0x9b,0x08,0x99,0x89 +,0x88,0x82,0x94,0x17,0xa7,0xc0,0x97,0x86,0x98,0x1d,0x95,0x7d,0x9e,0x83,0x27,0x9f,0x2d,0x3b,0x9c,0x87,0x98,0x95,0x1d,0x01,0x0c,0x22,0x1f,0x98,0x16,0x0c,0xac,0x1b +,0x9f,0x1a,0x08,0x00,0x09,0x05,0x9e,0x8c,0x2c,0x1d,0x0a,0x00,0x2d,0x1f,0x0f,0x1a,0x01,0x24,0x97,0x88,0x5f,0x41,0x03,0x0f,0xb1,0xb2,0x88,0x99,0x11,0x22,0x1e,0x2d +,0x8e,0xc4,0x20,0x26,0x9f,0xa6,0x80,0x38,0x35,0x31,0x0d,0x8f,0x85,0x89,0x87,0x9b,0x1b,0xc3,0x4f,0xaa,0x90,0x9a,0x26,0x88,0xa5,0x8b,0x95,0x12,0x0e,0x0a,0x1d,0x9b +,0x83,0x92,0x93,0x4f,0x1c,0xb0,0x8c,0xa7,0x92,0x15,0xdb,0x8b,0x84,0x8a,0x9f,0x1f,0x09,0x9c,0xa2,0x88,0x92,0x13,0x0d,0x23,0x14,0x99,0x4f,0x0d,0x09,0x0d,0x20,0x95 +,0xc0,0x04,0x0f,0x00,0x1f,0xad,0xa4,0xb5,0x21,0x03,0x08,0x08,0x11,0x4a,0x33,0x0c,0x2d,0xa5,0x9a,0x82,0x29,0x2c,0x0a,0x0d,0xac,0x86,0x89,0x91,0x33,0x0e,0x2a,0x99 +,0x93,0x95,0x1d,0x08,0x9e,0x96,0x80,0x9d,0x1c,0x04,0x12,0xb4,0x8b,0x88,0x25,0x0b,0x0a,0x17,0x96,0x8e,0x3d,0x2a,0x0a,0xa6,0x8e,0x83,0xa4,0xd6,0x13,0x1a,0x89,0x8a +,0x84,0x94,0x1d,0x1b,0xde,0xb9,0x8a,0xa9,0x2d,0x18,0xa8,0x97,0x80,0x9b,0x17,0x12,0x01,0x2b,0x97,0x8b,0x98,0x23,0x06,0x1b,0x33,0x98,0xaf,0x1a,0x02,0x1c,0xa7,0x89 +,0x88,0x0f,0x0a,0x03,0x26,0x95,0x87,0xa5,0x1b,0x05,0x0a,0x2b,0x96,0xcf,0x1d,0x03,0x0a,0xb4,0xad,0x98,0x0b,0x08,0x01,0x1f,0xaa,0x8c,0x97,0x16,0x09,0x0b,0x18,0x92 +,0x98,0x42,0x1e,0x0b,0x92,0x8a,0x80,0xba,0x2a,0x08,0x15,0x99,0x8f,0x87,0xaf,0x12,0x1f,0xb7,0x94,0x87,0xd7,0x23,0x0d,0x9a,0x8f,0x80,0x96,0x4b,0x2c,0x0e,0x8d,0x84 +,0x84,0x8e,0x44,0x1a,0x98,0x8e,0x84,0x8e,0xa8,0x0e,0x9e,0x90,0x88,0x8c,0x0a,0x0b,0x02,0x1f,0xa0,0x8e,0x29,0x0a,0x02,0x06,0x14,0xa3,0x2b,0x1e,0x09,0x1e,0x89,0x8b +,0x83,0x30,0x19,0x02,0x17,0xa3,0x88,0xad,0x07,0x01,0x07,0x0d,0x2b,0x1d,0x04,0x04,0x00,0x13,0x2b,0x9a,0x0c,0x07,0x01,0x10,0x9c,0x92,0x99,0x33,0x12,0x26,0x9a,0x8f +,0x80,0x90,0xa0,0x7c,0x85,0x85,0x80,0x8d,0x97,0x9d,0xbd,0x81,0x81,0x80,0x84,0x98,0x22,0x9a,0x90,0x82,0x91,0x39,0x08,0xa8,0x88,0x82,0x8a,0x0b,0x0a,0x05,0xbb,0x94 +,0x94,0x17,0x0d,0x04,0x0e,0x18,0xac,0x1e,0x04,0x00,0x07,0x9d,0xa1,0x9f,0x05,0x12,0x19,0x97,0x87,0x87,0x86,0x8f,0xdc,0x33,0xb3,0x8f,0x83,0x2a,0x0c,0x00,0x1f,0xd2 +,0x9f,0x0e,0x00,0x00,0x03,0x2a,0xa1,0x9c,0x14,0x04,0x04,0x22,0xc0,0x8c,0x1a,0x0c,0x08,0xac,0x85,0x82,0x8e,0x11,0x19,0x0d,0x92,0x8a,0x8d,0xb5,0x3d,0x1e,0x95,0x96 +,0x8b,0x95,0x2c,0x22,0x40,0x84,0x88,0x80,0x34,0x37,0x1f,0x9d,0x82,0x81,0x8d,0xab,0x11,0x1e,0x9b,0x8e,0x88,0x25,0x0f,0x08,0x96,0x98,0x90,0x0f,0x00,0x01,0x04,0xbf +,0x8f,0xa9,0x08,0x02,0x05,0xb8,0x95,0x86,0x34,0x20,0x40,0x84,0x80,0x80,0x8b,0x1e,0xb5,0xbd,0x89,0x8d,0x9a,0x0f,0x07,0x05,0x1d,0x13,0x20,0x0d,0x01,0x04,0x03,0x23 +,0x16,0x24,0x03,0x07,0x01,0x0d,0x3f,0xa9,0x2f,0x10,0x05,0x0e,0x32,0xa5,0x8d,0x2c,0x1c,0x12,0x8b,0x86,0x80,0x9b,0x1f,0x46,0xb2,0x82,0x80,0x86,0x9c,0x77,0xd4,0x8a +,0x8f,0x89,0xca,0x28,0x20,0x95,0x83,0x88,0x8e,0x0a,0x16,0x13,0xa0,0x88,0x95,0x18,0x10,0x0d,0x31,0xb7,0xe7,0x2f,0x0a,0x0a,0x0a,0x90,0x94,0x89,0xed,0x19,0x45,0x9e +,0x81,0x81,0x89,0xa6,0xaf,0x9d,0x86,0x8e,0x8c,0x2e,0x14,0x07,0x26,0xb5,0x23,0x12,0x00,0x05,0x02,0x20,0x2d,0x23,0x09,0x09,0x05,0x1b,0x1f,0x2a,0x1a,0x06,0x0c,0x1b +,0x88,0x95,0x95,0x09,0x0d,0x14,0xdf,0x8d,0x9d,0xc9,0x21,0x27,0x5e,0x98,0xc7,0x9e,0x1b,0x2b,0x16,0x8e,0x89,0x8b,0xa0,0x0f,0xa7,0xa4,0x86,0x8a,0x8f,0xaa,0x97,0xb0 +,0x8f,0x95,0x8f,0x9d,0x2c,0x19,0x59,0x85,0x9b,0xba,0x00,0x0a,0x0b,0x3f,0xa8,0x20,0x0f,0x14,0x1d,0x33,0xa6,0xb7,0x8c,0x9f,0x98,0x99,0x80,0x83,0x80,0x96,0x31,0x94 +,0xab,0x8b,0x9d,0x5a,0x17,0x17,0x07,0x13,0x08,0x0c,0x07,0x03,0x03,0x0d,0xc5,0x1c,0x24,0x00,0x0d,0x08,0x18,0x3e,0x23,0x18,0x22,0x17,0x1e,0xae,0x56,0x97,0x32,0x42 +,0x2c,0x84,0x8f,0x87,0xba,0x1e,0x96,0xab,0x89,0x8e,0x8f,0xa1,0x9b,0x2d,0x99,0xae,0x98,0x56,0x26,0x1f,0x99,0x8c,0xb0,0xa5,0x04,0x28,0x14,0x55,0xa1,0x9f,0x6a,0x41 +,0x12,0x17,0x41,0x2f,0x50,0x0c,0x0f,0x2c,0x80,0x8e,0x86,0x30,0x2c,0x8f,0x93,0x81,0x83,0x85,0x88,0x88,0x9a,0x89,0xa8,0xa9,0x1b,0x09,0x05,0x3d,0x49,0x14,0x11,0x00 +,0x0b,0x05,0x17,0x1b,0x15,0x0a,0x29,0x0e,0x17,0x1d,0x10,0x2b,0x19,0x0f,0x1f,0x8d,0x2f,0x9e,0x09,0x0b,0x2c,0x31,0x9f,0x9d,0xcf,0xdb,0xb4,0x0f,0xc6,0x2c,0xa9,0xac +,0xcf,0x2e,0x84,0x89,0x87,0x8e,0x0b,0xc1,0xb2,0x8c,0x84,0x89,0xa8,0x8a,0xb5,0xa7,0xa5,0x2d,0xea,0xde,0x10,0x2d,0x8e,0x26,0x93,0x0b,0x05,0x0c,0x0c,0x1f,0xac,0x1b +,0x3a,0xa1,0x28,0x8c,0x8b,0x88,0x86,0x8f,0xa0,0x80,0x84,0x80,0x89,0x26,0x9f,0x9c,0xc1,0x9e,0xd3,0x07,0x17,0x03,0x04,0x0b,0x07,0x03,0x08,0x00,0x0f,0x9f,0x0e,0x22 +,0x06,0x03,0x0f,0x11,0x11,0x9a,0x54,0x4c,0xac,0x0e,0x44,0xa0,0x6e,0xb9,0x67,0x15,0x83,0x87,0x86,0x8c,0x1f,0x35,0x9f,0xad,0x8f,0x85,0x9e,0x91,0x43,0x1e,0x9b,0x9c +,0x21,0x21,0x07,0xb9,0x80,0x8e,0x9a,0x11,0x0a,0x3f,0xa5,0x33,0x9a,0xdb,0x1f,0x43,0x10,0x1f,0xa9,0x1e,0x15,0x14,0x0e,0x8a,0x86,0x8d,0x92,0x2f,0xd3,0x8e,0x87,0x85 +,0x80,0x8c,0x8e,0xa1,0x2a,0xbf,0xcd,0x13,0x13,0x03,0x0f,0x9f,0x2e,0x10,0x04,0x00,0x03,0x0e,0x0d,0x35,0x29,0x10,0x29,0x17,0x18,0x2e,0x14,0x0a,0x0c,0x08,0xa1,0x8b +,0x98,0xb6,0x19,0x0f,0x2d,0xab,0x9d,0x8b,0xa6,0xb8,0xb9,0xad,0x94,0x8e,0xaa,0xec,0x24,0xb3,0x83,0x84,0x87,0xa5,0x22,0x28,0x94,0x8b,0x87,0x95,0x45,0xbf,0xa6,0xa1 +,0xb4,0x1b,0x08,0x0a,0x0f,0xa7,0x98,0x4a,0x0c,0x04,0x07,0x1c,0xb5,0xdb,0xb1,0xc5,0x99,0x8c,0x8b,0x8a,0x89,0x91,0x91,0x8d,0x87,0x80,0x85,0x8d,0xcf,0x23,0x17,0x1e +,0x15,0x13,0x0d,0x06,0x0b,0x09,0x0c,0x0a,0x07,0x02,0x04,0x05,0x14,0x2f,0x1f,0x16,0x10,0x18,0x2d,0xad,0xbf,0xc4,0x38,0x60,0xb1,0xa5,0x9b,0x9c,0xa4,0x45,0x33,0xcc +,0x99,0x93,0xa8,0x2f,0xec,0xb0,0x98,0x95,0x93,0x96,0xa1,0xa5,0xd7,0xaf,0x9f,0x9d,0xb4,0x52,0xfe,0x9e,0x8f,0x97,0x41,0x1b,0x1d,0x5a,0xc3,0xcd,0x47,0x1c,0x22,0x29 +,0x4a,0xc8,0x2d,0x22,0x27,0xc6,0x9c,0x94,0x96,0x8d,0x8a,0x8d,0x89,0x88,0x8b,0x89,0x8d,0x99,0xa6,0x3a,0x2a,0x21,0x1f,0x1b,0x0f,0x08,0x06,0x07,0x0b,0x0d,0x14,0x0a +,0x07,0x0b,0x13,0x24,0x1f,0x12,0x0e,0x14,0x1f,0x36,0x25,0x29,0xb0,0x98,0x9b,0xa0,0x5a,0x3b,0x5e,0xba,0xad,0x9f,0xac,0xac,0xb8,0x9d,0x95,0x99,0xb2,0xd4,0xac,0x98 +,0x8a,0x8e,0x95,0xb0,0xa8,0xb6,0xa4,0xd1,0xa7,0xaf,0xbb,0x4f,0x40,0xbf,0xbb,0xa8,0x38,0xc3,0xcd,0x9e,0xa2,0xa0,0xc4,0x45,0x1e,0x36,0xe3,0xc8,0xe4,0x23,0x21,0x17 +,0x27,0x21,0xdc,0x2d,0x27,0x22,0x3d,0xc0,0xa6,0xea,0x24,0x26,0x23,0x4e,0xd7,0xac,0x45,0x41,0x1c,0x21,0x2c,0x21,0x1d,0x1c,0x1f,0x33,0xc5,0x4d,0x37,0x25,0x27,0x2f +,0x52,0xda,0xa2,0xa6,0xa1,0x9d,0xca,0xdf,0x71,0x45,0x4b,0x33,0x1f,0x36,0xb5,0xbe,0x46,0x39,0x2f,0xb7,0xa8,0xa4,0xbd,0x24,0x2b,0x25,0x37,0x54,0x67,0x27,0x45,0xbd +,0x9f,0x9a,0xbc,0x43,0xc2,0xa8,0x9a,0x8b,0x8e,0x8c,0x8d,0x8a,0x8c,0x90,0x9c,0xad,0xae,0x78,0xc2,0x50,0x46,0x2b,0x20,0x22,0x1b,0x0d,0x09,0x0d,0x11,0x1d,0x1b,0x15 +,0x0e,0x16,0x1e,0x3b,0xf3,0x2d,0x1d,0x1c,0x2b,0x65,0xb6,0xcf,0x48,0x39,0xa7,0xa6,0xc6,0x1e,0x1f,0x1b,0x26,0x38,0x37,0x72,0xb0,0xc4,0x36,0xbf,0xe3,0x41,0x1f,0x1d +,0x22,0x6d,0xe9,0xad,0xbc,0x5e,0xef,0x46,0x3b,0xbb,0xb3,0x78,0xf1,0x2d,0x3f,0x5c,0xab,0xaf,0x5e,0x32,0xdf,0xac,0x94,0x8b,0x93,0x98,0x98,0x95,0x8d,0x89,0x8d,0x97 +,0x9d,0x9b,0x91,0x98,0xa2,0xad,0xc6,0xaa,0x9a,0xb3,0x36,0xa0,0xc0,0x28,0x95,0x8a,0x02,0x14,0x92,0x10,0x35,0x20,0x17,0x0c,0x03,0x06,0x03,0x06,0x00,0x08,0x05,0x00 +,0x05,0x06,0x0d,0x0a,0x04,0x04,0x08,0x08,0x0a,0x0e,0xbe,0x47,0x0c,0x0e,0x11,0x1f,0x20,0x95,0x85,0x8b,0x87,0x8a,0x9c,0x8a,0x81,0x80,0x82,0x84,0x80,0x81,0x82,0x82 +,0x82,0x84,0x81,0x81,0x81,0x85,0x88,0x9a,0xaf,0x9c,0xa2,0xac,0x92,0x83,0x83,0x8e,0x91,0x8d,0x9a,0x9e,0x9b,0xac,0xc0,0x46,0x0c,0x03,0x03,0x03,0x01,0x01,0x05,0x02 +,0x00,0x00,0x00,0x02,0x04,0x05,0x05,0x03,0x02,0x02,0x02,0x08,0x13,0x0c,0x04,0x07,0x0e,0x0a,0x09,0x0e,0x08,0x03,0x06,0x11,0x3e,0x44,0x1e,0x0c,0x19,0xa9,0x99,0x93 +,0x8b,0x82,0x84,0x85,0x85,0x85,0x83,0x82,0x80,0x80,0x80,0x81,0x8a,0x88,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x84,0x84,0x83,0x81,0x81,0x82,0x83,0x83,0x85,0x87,0x84 +,0x8e,0xfc,0xd7,0x8c,0x83,0x86,0x8f,0x98,0xb7,0xef,0x9b,0xa5,0xcf,0x1d,0x0c,0x03,0x08,0x0d,0x0b,0x06,0x09,0x08,0x01,0x01,0x03,0x06,0x08,0x08,0x03,0x03,0x02,0x01 +,0x00,0x00,0x00,0x07,0x08,0x02,0x02,0x00,0x00,0x02,0x01,0x01,0x05,0x03,0x07,0x08,0x06,0x0c,0x07,0x0a,0x0d,0x05,0x11,0x20,0x11,0x10,0x02,0x0b,0x1f,0x0e,0x30,0xaa +,0x98,0xa7,0x0b,0x05,0xa6,0x88,0x84,0x8b,0x9c,0x87,0x84,0x86,0x84,0x89,0x88,0x85,0x89,0x85,0x83,0x80,0x84,0x85,0x81,0x81,0x83,0x84,0x83,0x81,0x80,0x81,0x82,0x82 +,0x80,0x81,0x82,0x84,0x80,0x87,0x94,0xa7,0x9e,0x46,0x9e,0x85,0xaf,0xb6,0x1d,0x13,0xa8,0xaf,0x9d,0x9e,0x16,0x1b,0x0e,0x23,0x96,0xa5,0x99,0x95,0xbb,0x39,0x17,0x1e +,0xeb,0x0a,0x98,0x92,0x3b,0x89,0x93,0x8c,0xae,0x0e,0x92,0x8d,0x8f,0x86,0x9c,0x85,0x92,0xaf,0x8f,0x97,0x91,0xb3,0x16,0xab,0x1e,0x0b,0x93,0x1a,0xe4,0xaa,0x23,0x30 +,0x00,0x07,0x0d,0x02,0x09,0x06,0x09,0x09,0x00,0x02,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x08,0x0d,0x02,0x07,0x01,0x09,0x02,0x00,0x09,0x05,0x01,0x03,0x00,0x09,0x05 +,0x07,0x09,0x01,0x01,0x00,0x00,0x03,0x01,0x0d,0x9f,0x11,0x10,0x0c,0x0d,0x16,0x07,0xaf,0x8e,0x93,0x8c,0x9c,0x8b,0x8e,0x90,0x81,0x82,0x81,0x8d,0x8c,0x83,0x85,0x83 +,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x82,0x80,0x84,0x81,0x81,0x81,0x80,0x82,0x82,0x85,0x83,0x86,0x85,0x86,0x8f,0xab,0x89,0x80,0x86,0x80,0x83,0x81,0x91,0x9e,0x85 +,0x89,0x88,0x86,0x88,0x80,0x86,0x83,0x87,0x88,0x8a,0x8f,0x8f,0x8d,0xab,0x94,0x84,0x31,0x33,0x14,0x0e,0x04,0x00,0x06,0x03,0x03,0x02,0x00,0x00,0x00,0x00,0x02,0x02 +,0x01,0x00,0x00,0x00,0x00,0x01,0x15,0x05,0x08,0x05,0x01,0x03,0x00,0x05,0x04,0x04,0x05,0x01,0x0b,0x03,0x08,0x0b,0x08,0x0b,0x05,0x0b,0x0d,0x08,0x14,0x8d,0xd4,0x95 +,0x8b,0x8d,0x91,0x2a,0x8f,0x8f,0x90,0x8a,0x90,0x81,0x86,0x84,0x86,0x92,0x97,0xbf,0xaa,0x99,0xa3,0x97,0x80,0x9f,0x9d,0xa9,0x9e,0x9b,0x27,0x8e,0x9b,0xce,0xa5,0xac +,0x8c,0x9e,0x95,0x89,0x93,0x98,0xc8,0x3a,0x21,0x0d,0x26,0x85,0xa0,0x96,0x9e,0xb5,0x24,0x00,0x23,0x16,0x19,0x2c,0x1f,0xb6,0x0c,0x0d,0x15,0x0c,0x0d,0x0c,0x15,0x18 +,0x07,0x34,0x90,0x1c,0xb3,0xb6,0x9d,0x24,0x05,0x6f,0x18,0x44,0xa2,0xa2,0x8f,0x2d,0xaa,0xb0,0x6d,0x30,0x1f,0x2e,0x20,0x0e,0x9a,0x8c,0x2a,0xb8,0x2e,0xbc,0x0f,0x17 +,0x8f,0xa9,0xab,0x64,0xb3,0xb5,0x2e,0x99,0x8f,0x91,0x9f,0xac,0x9a,0xac,0xb1,0x83,0x84,0x85,0x80,0x83,0x83,0x97,0x87,0x80,0x85,0x80,0x86,0x80,0x92,0xa4,0x9e,0xab +,0x47,0x0b,0x0a,0x09,0x02,0x03,0x2d,0x09,0x03,0x08,0x07,0x09,0x00,0x13,0x0b,0x03,0x07,0x08,0x1a,0x0b,0x16,0x1a,0x16,0x13,0x09,0x0e,0x15,0x09,0x2c,0x95,0x1a,0x25 +,0x20,0xc0,0x1a,0x16,0x91,0xb4,0x9b,0xa1,0x9c,0x92,0xbc,0x94,0x8f,0x8e,0x8d,0xa3,0x9f,0xa8,0x4e,0x84,0x8b,0x91,0x85,0x88,0x84,0xb2,0x95,0x8a,0xb5,0x99,0x9e,0x8e +,0x9a,0x3b,0x44,0x1e,0x1a,0x13,0x0c,0x19,0x0e,0x0f,0x9a,0x15,0x2d,0xef,0xb8,0xaf,0x0f,0x9b,0xba,0x33,0xeb,0x2f,0xbd,0x1d,0x2b,0xde,0x1e,0x0f,0x0a,0x04,0x0e,0x02 +,0x2e,0xac,0x0d,0xda,0x20,0x3b,0x0c,0x0d,0xce,0x16,0x3f,0xc6,0x9c,0xa6,0x34,0xc8,0xb8,0xad,0x37,0x2d,0x20,0x1c,0x0f,0x8d,0x94,0x9f,0x88,0x91,0x8d,0x2d,0x8f,0x8e +,0xb3,0x96,0x98,0x8d,0xa6,0xae,0xb5,0x2c,0x13,0x0d,0x09,0x11,0x0c,0x1f,0x88,0x29,0xbc,0x38,0x3b,0x2b,0x14,0x8e,0xb4,0xb1,0xa7,0x9a,0x8f,0xa1,0x8c,0x8a,0x8a,0x8f +,0x99,0x98,0x9b,0xa2,0x87,0x83,0x8a,0x84,0x88,0x8b,0x2b,0x6e,0x97,0x2a,0x42,0x1f,0x2c,0x14,0x08,0x0c,0x08,0x06,0x05,0x00,0x02,0x02,0x04,0x48,0x0a,0x0a,0x0e,0x12 +,0x15,0x01,0x44,0x1d,0x10,0x22,0x2d,0x9d,0x31,0x67,0x77,0x28,0x17,0x0d,0x0a,0x1c,0x19,0x96,0x85,0xa8,0x8d,0x98,0x8c,0xac,0xa0,0x80,0x8f,0x8b,0x8b,0x8a,0x8a,0x92 +,0x8b,0x8d,0x98,0x9a,0x9b,0xa1,0x9b,0x2c,0x89,0x90,0xb0,0x8d,0x9e,0x9b,0x0f,0x37,0xb0,0x0f,0x1c,0x27,0xcb,0x2e,0x21,0x24,0x1e,0x15,0x19,0x0f,0x15,0x13,0x19,0x8a +,0x42,0xd6,0xb4,0xbf,0x29,0x0a,0xb0,0x2f,0x0f,0x1a,0x1c,0x2c,0x13,0x1b,0x19,0x0f,0x08,0x07,0x04,0x0c,0x07,0x29,0x90,0x18,0xb9,0x2c,0xb1,0x21,0x22,0x8a,0xab,0x9f +,0x94,0x9a,0x9d,0x32,0xa4,0xa9,0xb6,0xba,0xc7,0xb9,0xab,0x2e,0x8b,0x8c,0xa8,0x8c,0x9b,0x8f,0x1f,0xdf,0x93,0x20,0x4f,0xed,0xa4,0xa6,0xac,0x97,0xb2,0x35,0x19,0x1f +,0x1b,0x5c,0x2a,0x87,0x99,0xba,0x8f,0xa0,0x96,0x29,0x90,0x86,0x9b,0x8b,0x8c,0x89,0x8a,0x8b,0x85,0x8b,0x98,0xb3,0xd6,0x36,0xd3,0x36,0x85,0x2d,0x25,0x58,0x1c,0x16 +,0x00,0x0e,0x0a,0x03,0x06,0x05,0x0a,0x05,0x06,0x09,0x06,0x03,0x04,0x03,0x04,0x02,0x09,0x9f,0x0d,0x29,0x66,0x67,0x37,0x0c,0xa1,0x39,0x1f,0xbe,0xb8,0x93,0xac,0x95 +,0x8c,0x96,0xba,0x63,0x47,0x9d,0xa8,0x8f,0x82,0xab,0x8b,0x91,0x8d,0xa7,0xe0,0x88,0x95,0x98,0x8c,0x8b,0x88,0x9c,0x90,0x8e,0x91,0xa5,0xab,0x2f,0x31,0x16,0xa0,0x87 +,0x23,0x9c,0xd9,0xb6,0x1a,0x0d,0xac,0x1d,0x1b,0x33,0x35,0xad,0x1a,0x47,0x55,0x18,0x0f,0x0c,0x0a,0x0d,0x03,0xb5,0xa1,0x0f,0xb7,0x30,0xbd,0x0c,0x0c,0xcc,0x14,0x1c +,0x29,0x3f,0x37,0x0c,0x2a,0x31,0x1f,0x13,0x16,0x16,0x19,0x0d,0x8f,0x97,0x25,0x9e,0xc0,0x9e,0x1c,0xd7,0x8b,0xa9,0xa2,0x97,0x8f,0x8f,0xaf,0x8b,0x8c,0x9b,0xb1,0xbf +,0xeb,0x2e,0x14,0x8c,0xa6,0x2e,0x99,0xa0,0x9e,0x0d,0x2f,0xa6,0x28,0x2e,0xcf,0xa4,0x52,0x1a,0xab,0xa5,0xbf,0xcf,0xbe,0xad,0xa6,0xa6,0x80,0x8d,0x8f,0x82,0x84,0x87 +,0xab,0x8d,0x85,0x95,0x8f,0x8f,0x8f,0xb3,0x1f,0xbb,0x29,0x0d,0x08,0x01,0x03,0x02,0x03,0x32,0x07,0x05,0x0a,0x0e,0x0d,0x00,0x0d,0x0e,0x08,0x0e,0x15,0x29,0x0b,0x0e +,0x34,0x33,0x25,0x1e,0x13,0x13,0x0e,0x17,0x8a,0x30,0xae,0x93,0x8d,0x98,0x23,0x8f,0x93,0xb7,0x9c,0x90,0x88,0x9c,0x95,0x88,0x8f,0x9b,0x9f,0xb3,0xa4,0x3a,0xa5,0x81 +,0xce,0x8f,0x8b,0x85,0x91,0x5a,0x89,0x92,0xa0,0x9b,0x9c,0x9c,0x11,0x2e,0xa6,0xd2,0x1c,0x16,0x15,0x19,0x0a,0x24,0x8f,0x12,0xde,0xa6,0x98,0x2c,0x0e,0x9e,0xeb,0x19 +,0x2f,0x2f,0x31,0x05,0x11,0x2b,0x19,0x0b,0x0a,0x08,0x0b,0x01,0x1d,0xa2,0x07,0x29,0x3d,0x9e,0x16,0x0b,0xa3,0xbd,0xe6,0x9d,0x94,0x96,0x17,0x75,0x9c,0xa0,0xb4,0x3b +,0x20,0x1d,0x16,0x8f,0x83,0xbf,0x93,0x93,0x88,0xbd,0x2d,0x8a,0x9a,0x9e,0x9c,0xa8,0xaf,0x13,0xb9,0x9c,0xa7,0x3e,0xe7,0x36,0x20,0x03,0xbc,0x95,0x4f,0x8b,0x9b,0x8e +,0x1a,0x1e,0x89,0x88,0x87,0x8c,0x94,0xad,0x1e,0x8b,0x83,0x82,0x8b,0xb5,0x19,0x1c,0x1c,0x8a,0x8b,0x19,0x23,0x3c,0x8e,0x0c,0x08,0x1a,0x05,0x0f,0x1d,0x1e,0x0a,0x00 +,0x03,0x05,0x1f,0x2c,0x1d,0x0b,0x05,0x00,0xc7,0xac,0x2c,0x99,0xb6,0xb3,0x08,0xad,0x82,0x98,0xcf,0x11,0xbc,0xae,0x23,0xab,0x2a,0x52,0x4b,0xa6,0xaa,0x2c,0x0e,0x93 +,0x9f,0x3b,0x93,0x93,0x8d,0x09,0x1e,0xa1,0xa1,0x89,0x8f,0x95,0x1c,0x17,0x8d,0x83,0x84,0xa8,0x1e,0x15,0x0b,0x12,0x83,0x99,0x2e,0xd3,0x48,0xcc,0x0d,0x9a,0x8a,0x4c +,0x20,0x29,0x92,0xc8,0x1c,0x29,0x1b,0x28,0xaa,0x8d,0x62,0x07,0x07,0x8c,0x91,0x8b,0x89,0x8f,0xa2,0x07,0xc3,0x95,0xa8,0x5c,0x2e,0x3f,0x04,0x0f,0x9c,0x8e,0xaf,0x0f +,0x0a,0x0a,0x0e,0x2c,0x8c,0x18,0x16,0x56,0xa0,0xac,0x06,0x26,0xdc,0x22,0x3a,0xf1,0xa7,0x13,0x26,0x2f,0xa7,0x99,0x8f,0xa0,0x16,0x02,0x0e,0x8a,0xab,0x9b,0x3a,0x35 +,0x0d,0x05,0x93,0x8f,0x9a,0xa3,0xa3,0xa7,0x14,0x3d,0x98,0x8c,0xa4,0x1d,0x18,0x44,0x23,0x93,0x92,0x19,0x8f,0x8d,0x80,0xa0,0x2b,0x93,0xa2,0x8a,0x91,0x8a,0x94,0x24 +,0xa9,0xa0,0x91,0x98,0xa9,0xbd,0x17,0x09,0x96,0xb3,0x4a,0x42,0x24,0xc2,0x07,0x19,0x23,0x13,0x18,0xcb,0x92,0x32,0x15,0x21,0x1f,0x2f,0xda,0xcb,0x39,0x08,0x0e,0x5b +,0x11,0xb2,0x99,0x90,0x1a,0x00,0x16,0x2f,0xa9,0x5d,0xc7,0x3c,0x18,0x30,0x39,0xc2,0x4d,0x27,0x22,0x21,0x17,0x9c,0xae,0x25,0x9c,0x97,0x80,0x8c,0x8b,0x8c,0x38,0x9d +,0x8c,0x81,0x8e,0x1c,0x13,0x25,0x4f,0x21,0x11,0x10,0x06,0x08,0x1e,0x0a,0x0b,0x0b,0x11,0x09,0x00,0x0d,0x12,0x15,0x12,0x1b,0x4f,0xca,0x9e,0xa8,0x43,0x49,0x99,0x8e +,0x8b,0xa7,0x94,0x8c,0xbd,0x8f,0x96,0x86,0x93,0x97,0x8c,0xbb,0xa5,0x96,0x82,0x8a,0xaa,0xd8,0xb4,0x92,0x93,0x96,0x45,0x29,0x29,0x92,0x9c,0x24,0xb5,0x9d,0x8c,0x43 +,0xd4,0xb8,0x2c,0x26,0x2d,0xaf,0xe3,0xb2,0xa4,0x26,0x0d,0x0a,0x14,0x23,0x10,0x06,0x12,0x0a,0x09,0x13,0x2a,0x62,0x0d,0x1b,0x18,0x11,0x1a,0x7b,0xa4,0x2f,0x14,0x18 +,0xaf,0x9e,0xa4,0xaf,0xab,0x4f,0x29,0x90,0x93,0x3a,0x6f,0x95,0x87,0x93,0x99,0xa0,0x5b,0xad,0xa6,0x9a,0xa8,0xbc,0xc2,0x31,0x1b,0x11,0x4b,0xa5,0x28,0x06,0x0d,0x44 +,0x40,0xa8,0x8f,0x8a,0xa3,0x3f,0x9d,0x8f,0x8f,0x8f,0x87,0x83,0x8f,0x92,0x89,0x83,0x89,0x91,0x88,0x8a,0x92,0x9b,0x90,0x97,0x24,0xaf,0x8c,0x91,0x17,0x03,0x0f,0x0b +,0x0c,0x0f,0x18,0x19,0x06,0x06,0x07,0x0a,0x13,0x12,0x0d,0x02,0x01,0x00,0x0f,0x42,0x0f,0x0b,0x0f,0x1b,0x0d,0x0a,0x13,0x12,0x0e,0x0c,0x24,0x58,0x38,0x28,0x2e,0x9f +,0xaa,0xa4,0x98,0x9c,0xc3,0x1c,0x3e,0x88,0x80,0x86,0x8b,0x8a,0x88,0x92,0x89,0x84,0x8b,0xa0,0xc0,0x8d,0x8b,0x8e,0x8b,0x8e,0x94,0x45,0x4b,0xa3,0x9c,0xad,0x2a,0x1b +,0x28,0xa4,0xa9,0xcf,0x25,0x20,0x4a,0x2d,0x2f,0x29,0x1d,0x14,0x21,0xbf,0xcc,0x67,0x29,0x27,0x1f,0x18,0x2d,0xa7,0x5d,0x17,0x08,0x0a,0x09,0x2a,0xaf,0x0f,0x0c,0x0b +,0x27,0x12,0x11,0x1d,0x12,0x1c,0x1a,0x2a,0x35,0x43,0x4d,0x3e,0x9f,0xa9,0xb8,0x95,0x9a,0xc6,0x18,0x24,0xb5,0xd3,0xb6,0xa1,0xcc,0xad,0xa1,0x8b,0x8a,0x30,0x2d,0x62 +,0xc7,0xbc,0x8c,0x82,0x9a,0xaa,0x8e,0x8c,0x86,0x84,0x8a,0x8e,0x8f,0x86,0x88,0x84,0x83,0x8d,0x99,0x86,0x8b,0x96,0x9e,0xa5,0xa5,0x0d,0x13,0x18,0x11,0x0b,0x09,0x0f +,0x05,0x01,0x12,0x0b,0x01,0x03,0x02,0x01,0x05,0x2a,0x0e,0x00,0x04,0x04,0x06,0x08,0x4a,0xfe,0x0d,0x14,0x35,0x94,0xa4,0xb6,0x9a,0xc1,0xc5,0x96,0x85,0x98,0x9c,0x89 +,0xa4,0xc2,0x88,0x86,0x3d,0xae,0x8b,0xae,0xd2,0x8f,0x8c,0x34,0xb6,0x8f,0xaf,0x91,0x87,0x88,0xa5,0x20,0x93,0x89,0x8d,0x8d,0x89,0xa5,0x16,0x9a,0x88,0x9c,0xab,0x8d +,0x3e,0x0a,0xce,0x9b,0x24,0x0f,0x1a,0x09,0x07,0x1e,0x27,0x11,0x08,0x0d,0x0d,0x0c,0x1a,0x1a,0x0d,0x03,0x0e,0x53,0x39,0x1d,0x48,0x3a,0x08,0x2f,0x9a,0x31,0x15,0x36 +,0x2e,0x0b,0xbd,0x9f,0x30,0x1e,0x3c,0x16,0x0a,0x32,0xca,0x2d,0x18,0x13,0x15,0x13,0x26,0xb7,0xbe,0x13,0x18,0x9b,0x9e,0xaf,0x8d,0x87,0xe9,0x95,0x80,0x84,0x88,0x84 +,0x88,0x9b,0x85,0x80,0x83,0x86,0x87,0x85,0x88,0x89,0x82,0x88,0xa5,0x2b,0xac,0x94,0xb3,0x5b,0x1e,0x0b,0x04,0x12,0x0f,0x04,0x0f,0x0b,0x01,0x03,0x16,0x0d,0x03,0x0d +,0x0e,0x04,0x09,0x19,0x0e,0x0f,0x0d,0x08,0x09,0x14,0x34,0x2a,0x0d,0x0b,0x1d,0x29,0x15,0x24,0xa7,0x10,0x03,0x77,0x90,0x93,0x9e,0x90,0xc5,0x22,0x8b,0x8c,0x8d,0x8a +,0x8e,0xa1,0x92,0x83,0x85,0x8f,0x9c,0x8d,0x8a,0x86,0x89,0x85,0x93,0x23,0xa7,0x87,0x92,0x38,0xad,0x3c,0x19,0xbc,0x92,0xad,0x67,0x6b,0x0f,0x0d,0xb2,0x9c,0x4c,0x2c +,0x1b,0x12,0x1f,0xbe,0x96,0xba,0x1d,0x2a,0x1e,0x3e,0x22,0xbb,0x43,0x05,0x0c,0x3b,0x30,0x43,0x3c,0x14,0x09,0x0d,0xb3,0x1c,0x0e,0x0d,0x06,0x0f,0xb7,0xa5,0x24,0x08 +,0x07,0x14,0x1f,0xa3,0x95,0x94,0x20,0x0a,0x25,0x9d,0x9f,0x9f,0x9d,0x3c,0x35,0x9c,0x95,0xac,0x9c,0x91,0xa9,0xa1,0x90,0x8b,0x89,0x91,0x98,0x93,0x85,0x81,0x83,0x88 +,0x8c,0x8c,0x87,0x85,0x84,0x83,0x8e,0xa3,0x98,0x89,0x8d,0x92,0xae,0x1e,0x0c,0x18,0x2b,0x18,0x0f,0x03,0x01,0x03,0x13,0x18,0x06,0x02,0x00,0x01,0x09,0x18,0x10,0x06 +,0x01,0x05,0x07,0xb5,0xb4,0x18,0x0b,0x01,0x2d,0x9c,0x9b,0xa7,0xac,0xb8,0xc4,0xa9,0x96,0x96,0x94,0xa1,0x58,0x9d,0x8b,0x89,0x9d,0x60,0x5f,0xc8,0x9b,0x8f,0x8c,0x93 +,0xa6,0xbc,0xa4,0x8e,0x8c,0x8a,0x9a,0xf4,0xa3,0x8a,0x84,0x88,0x9f,0x33,0x31,0x95,0x86,0x90,0xbc,0x1d,0x1e,0x16,0x9b,0x8b,0xa7,0x1f,0x07,0x15,0x3b,0xb8,0xc5,0x1d +,0x13,0x0f,0x0f,0x1e,0x1e,0x29,0x19,0x0c,0x0b,0x16,0x29,0x32,0x2e,0x0e,0x07,0x0e,0xbf,0xa6,0x20,0x0f,0x10,0x12,0x1e,0xd5,0xa3,0x2e,0x19,0x10,0x1d,0xcc,0xb0,0x4e +,0x16,0x04,0x11,0x8d,0x8a,0x9e,0x0d,0x0b,0x33,0x9d,0x8e,0x9b,0xac,0xb0,0x3f,0xf1,0x90,0x84,0x83,0x86,0x89,0x88,0x83,0x82,0x81,0x8b,0x99,0x8e,0x83,0x80,0x81,0x86 +,0x97,0xa7,0xae,0xac,0x9d,0xb7,0x14,0x0d,0x19,0x1b,0x22,0x09,0x02,0x02,0x03,0x04,0x07,0x0c,0x0e,0x05,0x01,0x01,0x09,0x45,0x3f,0x14,0x01,0x03,0x02,0x9a,0x88,0xe9 +,0x0e,0x00,0x1b,0xa8,0x98,0xb5,0x16,0x1b,0xe1,0xa2,0x9b,0xb8,0x37,0x65,0x4c,0xab,0x91,0x8e,0x8a,0x9f,0x2b,0xb1,0x91,0x85,0x84,0x8b,0xc3,0x1d,0x90,0x84,0x81,0x89 +,0xac,0xc9,0x9d,0x87,0x84,0x8e,0xb0,0x39,0x3f,0xd5,0xa4,0x99,0x9f,0x2d,0x1a,0x10,0x1a,0x1d,0x1b,0xa6,0x32,0x35,0x24,0x29,0xb6,0x1e,0x0e,0x0d,0x1d,0x98,0x92,0xd0 +,0x15,0x02,0x0b,0x2d,0x93,0x96,0x28,0x09,0x07,0x00,0x18,0x98,0x5d,0x21,0x02,0x09,0x18,0x65,0xa1,0x17,0x13,0x0e,0x17,0x66,0xbc,0xb3,0x28,0x0d,0x1e,0x97,0x9d,0x46 +,0x0b,0x17,0xbd,0x91,0x81,0xa9,0x1d,0x18,0xa6,0x88,0x8a,0x84,0x88,0x8d,0x86,0x85,0x86,0x85,0x82,0x82,0x88,0x8b,0x8b,0xac,0x8c,0x82,0x81,0x8a,0x19,0xbf,0x9a,0x9e +,0xa8,0x0f,0x0a,0x0f,0x2c,0xac,0x0b,0x00,0x00,0x07,0x1e,0x45,0x0e,0x00,0x00,0x06,0x1c,0x9c,0xb1,0x00,0x02,0x00,0x2c,0x9c,0x1e,0x12,0x0b,0x17,0x5f,0x3e,0x24,0x33 +,0x28,0x9b,0xb2,0x1a,0x08,0x5f,0x82,0x84,0x86,0x52,0x25,0xa1,0x8c,0x86,0x9e,0x9f,0x94,0x8c,0x84,0x91,0x46,0x18,0x9c,0x83,0x81,0x96,0x1c,0x06,0xa5,0x82,0x80,0x92 +,0x07,0x07,0x18,0x89,0x82,0x93,0x38,0x1b,0x35,0x96,0xea,0xa6,0xa5,0x96,0x1f,0x06,0x83,0x0b,0x15,0x8f,0xad,0xa0,0x00,0x05,0x00,0x1a,0x15,0x02,0x0f,0x00,0x04,0x00 +,0x08,0x09,0x01,0x00,0x0b,0x08,0x08,0x00,0x13,0xc9,0x98,0xa3,0x09,0x0e,0x0b,0x8b,0x82,0x83,0x82,0x82,0x91,0x95,0x83,0x80,0x80,0x85,0x88,0x86,0x8e,0x89,0x80,0x82 +,0x80,0x89,0x99,0x2f,0x91,0x80,0x81,0x83,0x93,0x51,0x54,0xc3,0x9a,0x99,0x24,0x17,0x0f,0x19,0x04,0x29,0x3f,0xd9,0x19,0x00,0x02,0x00,0x13,0x1a,0x1a,0x0c,0x03,0x02 +,0x02,0x00,0x05,0x01,0x0b,0x03,0x03,0x00,0x06,0x1c,0xd4,0xbd,0x00,0x02,0x00,0x09,0xaf,0x8f,0x93,0x1f,0x0d,0x20,0x44,0x8f,0xa9,0x9a,0x9c,0xa1,0xa6,0xc5,0x80,0x84 +,0x80,0x8c,0xa4,0x51,0xa6,0x80,0x80,0x80,0x85,0x93,0x87,0x82,0x82,0x80,0x87,0x86,0x8c,0x86,0x8e,0x81,0x80,0x80,0x85,0x98,0x93,0xa2,0x86,0x80,0x81,0x80,0x8f,0x90 +,0x8b,0x8c,0x84,0x8f,0x85,0x9c,0xa1,0x1e,0xac,0x84,0x8a,0x8c,0x09,0x09,0x02,0x0b,0xd2,0x9f,0x22,0x04,0x00,0x01,0x02,0x0c,0x07,0x03,0x04,0x00,0x02,0x00,0x0f,0x0e +,0x11,0x05,0x00,0x00,0x00,0x0c,0x16,0x10,0x03,0x00,0x00,0x02,0x05,0x09,0x06,0x0b,0x00,0x05,0x00,0x0a,0x21,0x30,0x67,0x03,0x04,0x00,0x19,0xae,0xa5,0x9b,0x38,0x26 +,0x36,0x30,0xa4,0xa2,0x93,0x96,0x9d,0xb3,0x3f,0x81,0x84,0x80,0x93,0x5b,0xcb,0xeb,0x80,0x81,0x80,0x82,0x89,0x8e,0x8c,0x86,0x83,0x83,0x83,0x8c,0x89,0x8b,0x84,0x80 +,0x81,0x80,0xaa,0xa7,0xa9,0x8a,0x80,0x83,0x80,0x8a,0x91,0x8f,0x93,0x88,0x8c,0x89,0x8a,0xa2,0x99,0x45,0x87,0x85,0x81,0x90,0x0f,0x25,0x0c,0xa4,0x8f,0x8d,0x8e,0x25 +,0x18,0x11,0x11,0x31,0x1f,0x3f,0x11,0x08,0x05,0x07,0x9a,0x97,0x96,0x0b,0x01,0x01,0x0a,0xac,0x9e,0x9d,0x1d,0x05,0x0a,0x11,0x23,0x28,0x0f,0x13,0x05,0x0a,0x00,0x17 +,0xad,0xaf,0xbf,0x00,0x03,0x00,0x06,0x17,0x22,0x1a,0x05,0x01,0x02,0x03,0x07,0x06,0x04,0x03,0x00,0x02,0x00,0x09,0x0c,0x25,0x0e,0x00,0x01,0x00,0x05,0x0e,0x3c,0x10 +,0x03,0x01,0x01,0x0a,0x1d,0x1a,0x12,0x03,0x04,0x02,0x0f,0x9c,0x9d,0x8a,0x17,0x16,0x10,0x2e,0x87,0x89,0x82,0x8c,0x93,0x8d,0x87,0x83,0x80,0x82,0x82,0x89,0x86,0x8b +,0x81,0x80,0x80,0x81,0x8a,0x85,0x8c,0x81,0x80,0x80,0x80,0x81,0x82,0x81,0x81,0x80,0x80,0x80,0x82,0x85,0x8b,0x8c,0x80,0x83,0x80,0x8e,0xa1,0xab,0x9e,0x80,0x82,0x80 +,0x89,0xae,0xb5,0xa1,0x8f,0x8c,0x99,0x96,0x1f,0x2a,0x0c,0x28,0x9a,0xab,0x9f,0x04,0x03,0x00,0x0c,0x2d,0x4a,0x1c,0x03,0x01,0x00,0x03,0x09,0x08,0x04,0x03,0x00,0x02 +,0x00,0x0b,0x0c,0x12,0x0a,0x00,0x01,0x00,0x08,0x10,0x32,0x11,0x03,0x02,0x01,0x07,0x15,0x13,0x1f,0x08,0x0b,0x06,0x10,0x95,0x9d,0x89,0x0e,0x0b,0x07,0x15,0x8d,0x8c +,0x86,0xac,0x27,0x25,0x3a,0x9e,0xa0,0x9c,0xae,0x1b,0x3a,0x17,0x8a,0x89,0x84,0x93,0x0c,0x1b,0x0d,0x8e,0x87,0x84,0x89,0xae,0xa8,0xa9,0x96,0x89,0x94,0x8c,0x9d,0xa8 +,0xb9,0x9d,0x80,0x87,0x80,0x47,0x2e,0x1f,0x49,0x84,0x87,0x81,0xa2,0x2a,0x43,0x4d,0x98,0x98,0x97,0xab,0x13,0x1e,0x0b,0x95,0x8e,0x8a,0x9b,0x06,0x10,0x07,0x9d,0x91 +,0x8f,0x9c,0x12,0x14,0x25,0xab,0x9e,0x5a,0xb4,0x17,0x16,0x12,0x25,0x8b,0x99,0x8a,0x14,0x0d,0x0a,0x1c,0x8c,0x91,0x8c,0x4e,0x1b,0x20,0x2c,0x95,0x98,0x9c,0x9b,0x23 +,0x58,0x1e,0x8d,0x8a,0x85,0x8f,0x15,0x33,0x17,0x8d,0x84,0x85,0x88,0x2e,0x2c,0x2e,0xa8,0x8c,0x99,0x90,0x1e,0x22,0x15,0xb1,0x87,0x9a,0x90,0x08,0x0c,0x08,0x2d,0x8f +,0x99,0x8e,0x1b,0x0b,0x19,0x22,0x9e,0x43,0xa6,0xe8,0x18,0x24,0x19,0x88,0x92,0x89,0x5f,0x0d,0x0f,0x12,0x8b,0x89,0x89,0x96,0x1f,0x20,0x21,0xa9,0x99,0xbc,0xa6,0x18 +,0x20,0x0c,0xad,0x93,0x8e,0x9b,0x06,0x09,0x03,0x33,0x92,0x8f,0x9d,0x15,0x0d,0x0f,0x19,0x9f,0x4f,0xa3,0x16,0x0d,0x0d,0x3b,0x88,0x91,0x8c,0x0e,0x0a,0x06,0x2d,0x8f +,0x8b,0x8d,0xb3,0x19,0x1c,0x22,0xa5,0xa7,0xa8,0xf7,0x1c,0x13,0x13,0x89,0x8d,0x86,0x27,0x0c,0x09,0x11,0x94,0x8e,0x8f,0xa7,0x1c,0x1b,0x20,0xaa,0x9f,0xad,0xa2,0x25 +,0x1f,0x0e,0x96,0x8f,0x82,0xa8,0x11,0x0d,0x0c,0x9b,0x8b,0x87,0x9c,0x21,0x1c,0x18,0xcf,0x98,0xa4,0x9c,0x1b,0x1e,0x08,0x99,0x8e,0x89,0xa9,0x09,0x09,0x07,0xb3,0x93 +,0x8d,0xa3,0x1f,0x0f,0x15,0x1c,0xa8,0xc5,0x9e,0x19,0x18,0x07,0xe7,0x8f,0x8a,0x98,0x0a,0x0e,0x04,0x3d,0x99,0x8d,0x9c,0x33,0x14,0x12,0x0f,0xb6,0x3b,0x9e,0x31,0x1f +,0x0b,0x2b,0x91,0x8e,0x8b,0x11,0x18,0x07,0x72,0x91,0x88,0x8a,0xab,0x1f,0x2d,0x18,0xa3,0xa9,0x8f,0xaa,0x3b,0x18,0x2f,0x8a,0x8e,0x8a,0x11,0x12,0x05,0x24,0x97,0x8d +,0x96,0xc4,0x0e,0x1a,0x13,0xbb,0x2a,0xb5,0x2a,0x14,0x0d,0x22,0x8e,0x94,0x8b,0x0f,0x16,0x04,0x31,0x98,0x88,0x91,0xe2,0x14,0x26,0x20,0x9d,0xae,0xa0,0x6b,0x20,0x16 +,0x34,0x8c,0x94,0x8e,0x0f,0x17,0x05,0x68,0x96,0x8b,0x95,0x55,0x0f,0x13,0x1a,0xa8,0xb7,0xa7,0x30,0x1c,0x18,0xc6,0x8d,0x8c,0x92,0x0e,0x17,0x09,0xb1,0x8e,0x88,0x94 +,0x3e,0x1d,0x1c,0x36,0x9d,0xba,0xc7,0x24,0x1e,0x1e,0x9c,0x8e,0x8b,0xc3,0x0e,0x0f,0x0c,0x9a,0x95,0x8a,0xae,0x1f,0x12,0x1c,0xa8,0xa4,0xac,0x2a,0x18,0x13,0xc8,0x8c +,0x8a,0x91,0x0e,0x09,0x06,0x2c,0x8e,0x8d,0x8d,0x1a,0x17,0x0e,0x3c,0xa9,0xb7,0xfb,0x10,0x0c,0x13,0x8f,0x8a,0x88,0x2a,0x0d,0x07,0x10,0x97,0x8e,0x89,0xcd,0x24,0x13 +,0x1f,0x9b,0x95,0x9c,0x22,0x0c,0x16,0x99,0x86,0x84,0xaf,0x0f,0x0c,0x0f,0x95,0x93,0x8a,0xb9,0x36,0x22,0x1e,0xad,0xae,0xa3,0x2a,0x17,0x10,0x9e,0x8f,0x86,0xdf,0x0d +,0x0b,0x0e,0x99,0x99,0x8c,0x44,0x1a,0x16,0x1f,0x9c,0xbb,0xb6,0x20,0x12,0x11,0x97,0x8b,0x88,0x26,0x0c,0x0f,0x18,0x8c,0x93,0x89,0x23,0x16,0x18,0x31,0x9b,0xac,0xd7 +,0x18,0x0c,0x19,0x8e,0x8a,0x88,0x16,0x09,0x05,0x25,0x8c,0x8d,0x8f,0x15,0x11,0x11,0xc2,0x93,0x90,0xbf,0x19,0x04,0x2c,0x8d,0x85,0x89,0x0f,0x0e,0x05,0xad,0x8a,0x86 +,0x95,0x17,0x11,0x10,0xbd,0xa2,0x9a,0x4e,0x19,0x0b,0xa3,0x8e,0x84,0xad,0x0b,0x0d,0x09,0x95,0x95,0x88,0xbe,0x22,0x1b,0x2e,0xaf,0xad,0x4b,0x22,0x0f,0x23,0x8e,0x8d +,0x86,0x0f,0x15,0x08,0x38,0x91,0x94,0x96,0x17,0x1c,0x1f,0xae,0x9f,0xa6,0x1f,0x15,0x09,0x93,0x8e,0x86,0xd7,0x0b,0x19,0x0e,0x8f,0xa3,0x8d,0x2a,0x1e,0x16,0x2b,0xa1 +,0x9a,0xa8,0x1e,0x0a,0x20,0x8c,0x8b,0x8d,0x06,0x18,0x0a,0x96,0x8c,0x8d,0x9d,0x13,0x1e,0x13,0x58,0xe1,0xab,0x3b,0x25,0x16,0x90,0x97,0x85,0x19,0x0b,0x0a,0x15,0x8c +,0x97,0x8a,0x21,0x2a,0x19,0xc4,0xb3,0xae,0x28,0x1e,0x0c,0x9f,0x90,0x88,0x9e,0x0a,0x23,0x0d,0x8d,0x9c,0x8d,0x30,0x1e,0x1f,0x3d,0xac,0xb4,0x45,0x1e,0x16,0x3e,0x8e +,0x98,0x91,0x05,0x28,0x0c,0x9e,0x99,0x9e,0xa7,0x18,0x54,0x29,0xa2,0xb8,0xdf,0x1e,0x19,0x2c,0x8b,0x9c,0x8c,0x0c,0x1b,0x1b,0xad,0x8c,0xa1,0x99,0x10,0x4a,0x20,0xaa +,0x44,0x38,0x24,0x2c,0x26,0x8b,0x99,0x8e,0x14,0x0b,0x1b,0x1f,0x8c,0xfc,0x95,0x18,0xdf,0x4d,0xa6,0xce,0x27,0x1b,0x22,0x1a,0x90,0x93,0x8d,0x3a,0x06,0x2a,0x1a,0x85 +,0xa9,0x96,0x15,0x14,0x2c,0xcb,0xa0,0x34,0x15,0x1d,0x1b,0x8d,0x8a,0x8f,0xbd,0x02,0x24,0x0c,0x8d,0x9c,0x91,0xdd,0x21,0xcc,0xc8,0xa9,0xbb,0x1a,0x11,0x08,0xa1,0x82 +,0x88,0x8e,0x03,0x25,0x10,0x8e,0xa4,0xa3,0x3b,0x20,0xbe,0x43,0x57,0x38,0x1c,0x1a,0x0d,0x2d,0x8a,0x9a,0x89,0x08,0x34,0x12,0x91,0x95,0xab,0x3f,0x06,0x24,0x3c,0x92 +,0x93,0xad,0x1f,0x0e,0x1a,0x8b,0xa0,0x8f,0x05,0x10,0x0d,0xa9,0x81,0x8e,0x93,0x0c,0x1e,0x23,0x9f,0xa2,0x4c,0x1e,0x0e,0x2e,0x80,0x8f,0x8d,0x09,0x08,0x0d,0x23,0x85 +,0x23,0x9c,0x1d,0xa2,0xa9,0xb4,0x9f,0x29,0xb7,0x1a,0x0a,0x95,0xa9,0x83,0xc8,0x15,0x17,0x12,0x86,0x41,0x8d,0x0e,0x1f,0x1b,0x18,0x9c,0xaa,0x9d,0x2b,0x0e,0x93,0x92 +,0x89,0x1f,0x06,0x20,0x12,0x83,0xad,0x8c,0x20,0x19,0x1c,0x3d,0x92,0x3d,0x1b,0x10,0x0a,0x96,0x89,0x87,0xab,0x08,0xb1,0x0a,0x90,0xd4,0x9f,0xc8,0x3d,0xad,0x19,0xc4 +,0x3c,0x3f,0x2c,0x0a,0x27,0x9a,0x9a,0x8e,0x10,0xab,0x10,0x8e,0x94,0x9f,0xb2,0x0d,0x36,0x1e,0x94,0xa7,0xc4,0x19,0x0c,0x17,0x8a,0x8d,0x8b,0x0c,0x0a,0x08,0xac,0x80 +,0x8c,0x92,0x08,0x38,0x1e,0xaf,0x38,0x37,0x21,0x1c,0x1d,0x8e,0x92,0x8c,0x21,0x0f,0x33,0x0f,0x8b,0x2d,0x96,0x15,0xd7,0x6b,0xb0,0x99,0x4d,0x51,0x1c,0x15,0x9d,0x8d +,0x92,0xa3,0x08,0x36,0x0a,0x8c,0xa5,0xa8,0x13,0x0d,0x22,0x27,0x98,0xc4,0xb7,0x14,0x13,0xcd,0x81,0x8d,0x8f,0x07,0x11,0x0c,0x97,0x89,0x9b,0x3e,0x08,0x40,0x35,0x8f +,0xac,0xad,0x0d,0x11,0x19,0x8c,0x8d,0x8f,0x16,0x07,0x12,0x34,0x80,0x8c,0x8b,0x1c,0x79,0x14,0x2d,0x2f,0x37,0x1f,0x1a,0x1d,0x9a,0x88,0x98,0x4b,0x02,0x17,0x10,0x89 +,0xce,0xb9,0x29,0x9d,0x8c,0x9b,0x9a,0x1e,0x25,0x0a,0x0e,0x16,0x8c,0x95,0x89,0x0e,0x18,0x11,0xa7,0x95,0xd8,0xac,0x0d,0xbb,0x23,0x96,0xa0,0x98,0x1b,0x1b,0x19,0x8c +,0x8b,0x8e,0x1e,0x08,0x2e,0x2a,0x85,0xc0,0xa8,0x0e,0x2e,0x2e,0xcd,0x52,0x2a,0x15,0x17,0x2b,0x9e,0x87,0x9d,0x9c,0x06,0xeb,0x15,0x92,0x9b,0xc3,0xcb,0x18,0xb3,0x27 +,0x9f,0x49,0xd6,0x1e,0x21,0x1d,0x92,0x9f,0x8d,0x19,0x15,0x2b,0x32,0x89,0x46,0x9b,0x13,0x79,0x26,0xb2,0xa5,0xdd,0x30,0x1a,0x1b,0xa0,0x8a,0x96,0xd5,0x02,0x23,0x17 +,0x87,0x9d,0x9c,0x42,0x1f,0xaf,0x1c,0xac,0x23,0xbe,0x2e,0x2d,0x19,0x93,0xa8,0x90,0x0f,0x1b,0x17,0x1f,0x93,0x32,0x8a,0x2a,0x98,0x25,0xc6,0x64,0x3c,0x50,0x2c,0x19 +,0x9a,0x93,0x92,0xbf,0x09,0xc8,0x0f,0x8b,0x31,0x9c,0x25,0x28,0x7c,0x26,0x9e,0x2f,0xb2,0x2a,0x22,0x21,0x8f,0xa7,0x8b,0x0b,0x29,0x0f,0xde,0x9a,0xed,0x8e,0x22,0x98 +,0x10,0x4f,0x19,0xb4,0xc8,0xcb,0x19,0xa0,0x98,0x8f,0xb7,0x0f,0x45,0x0f,0x91,0x20,0x93,0x2e,0xa6,0x30,0x26,0x2f,0x2c,0xa9,0x60,0x2a,0x24,0x8c,0xa1,0x8e,0x0b,0x48 +,0x14,0xa6,0xbe,0xc0,0x9a,0x2f,0x9f,0x12,0xbb,0x17,0xa9,0x31,0x35,0x10,0x9b,0x98,0x8d,0x3c,0x0d,0x3d,0x1c,0x8b,0x2c,0x8f,0x26,0xa4,0x29,0x2b,0x2d,0x28,0xa1,0x79 +,0x2a,0x1d,0x97,0xb2,0x8d,0x0a,0x3b,0x09,0xb9,0xa1,0x98,0x8b,0x48,0xa5,0x0e,0xb8,0x1f,0x9b,0x5f,0x34,0x0a,0x9c,0xa2,0x8d,0x39,0x0f,0x38,0x0d,0x94,0x1d,0x8b,0x37 +,0x9c,0x2b,0x58,0x44,0x47,0xad,0x3c,0x22,0x2b,0x8c,0xb0,0x93,0x05,0x3a,0x0e,0xa3,0xae,0x9b,0x95,0x34,0xb2,0x0f,0xbf,0x1b,0x9d,0x28,0x4b,0x0e,0x96,0x95,0x89,0xcc +,0x12,0x1c,0x0a,0xa6,0x45,0x85,0xbf,0x9d,0x0e,0x1c,0x1c,0xae,0x9a,0x3a,0x1a,0x1c,0x8d,0x92,0x8c,0x0c,0x37,0x0b,0xa9,0xba,0x98,0x99,0x3f,0xb0,0x13,0x52,0x16,0x9e +,0x29,0x36,0x10,0x98,0x9b,0x8a,0x27,0x14,0x2b,0x14,0x93,0x2e,0x88,0x38,0x9e,0x14,0x1c,0x1e,0xdb,0xa4,0x3c,0x18,0x2c,0x8d,0x91,0x8a,0x08,0x2e,0x07,0x9f,0x9f,0x8e +,0x95,0x39,0xbf,0x0f,0xe9,0x23,0xa9,0x25,0x1b,0x0b,0x8f,0x95,0x82,0x2e,0x0f,0x11,0x0e,0x95,0xc0,0x88,0x3e,0xa0,0x19,0x39,0x37,0xaf,0xb6,0x39,0x11,0x26,0x8e,0x93 +,0x8d,0x0a,0x23,0x08,0xae,0xb1,0x95,0x95,0xd4,0xc2,0x16,0x50,0x2b,0xa8,0x28,0x1e,0x0e,0x90,0x8b,0x86,0x22,0x0a,0x0d,0x1c,0x90,0xb9,0x94,0x2e,0x9b,0x26,0x5a,0x2b +,0xcc,0xb6,0x21,0x13,0x1f,0x89,0x8b,0x8c,0x09,0x0f,0x07,0xa9,0xa0,0x9d,0x9b,0x5e,0xa3,0x17,0xc0,0x19,0xaa,0x32,0x21,0x0e,0x9c,0x8d,0x85,0xcb,0x10,0x17,0x0e,0x9b +,0x2e,0x8e,0x3b,0x9b,0x2a,0x3a,0x2b,0x28,0xfd,0x1e,0x17,0x2f,0x8a,0x8e,0x8c,0x0d,0x1e,0x0d,0xa1,0xa5,0xa9,0xa0,0xe0,0x9e,0x22,0x4a,0x18,0x40,0x1d,0x1f,0x10,0x8f +,0x8b,0x84,0xd9,0x0a,0x11,0x0f,0x96,0x43,0x92,0xb9,0x98,0xc0,0x4b,0x1e,0x27,0x2c,0x17,0x11,0x33,0x86,0x8d,0x8e,0x0e,0x1b,0x11,0xf2,0x2e,0xcf,0xab,0x99,0x98,0xd5 +,0xce,0x1d,0xb5,0x10,0x1d,0x0f,0x92,0x8d,0x88,0xc7,0x1c,0x22,0x28,0xc0,0x19,0xbb,0x36,0x95,0x3d,0xac,0x32,0xfe,0x37,0x1c,0x1a,0x69,0x90,0x93,0x9f,0x1c,0x25,0x1c +,0xab,0x3a,0xb1,0x60,0xb1,0xaa,0xca,0x6f,0x2e,0x36,0x24,0x19,0x3e,0x99,0x9b,0x94,0x2c,0x7d,0x1d,0x39,0x24,0x21,0xb1,0xb2,0x98,0x4e,0x41,0x2f,0xcb,0x30,0x20,0x1d +,0xdb,0xa0,0x9c,0xac,0xeb,0x9f,0xb7,0xb0,0x20,0x26,0x4b,0xcb,0xb5,0x4e,0x66,0x3d,0x2e,0x26,0x2d,0xba,0x9c,0xad,0x34,0x1d,0xd0,0xa5,0x9a,0xb4,0x2d,0x36,0xd7,0xad +,0x4d,0x52,0x2a,0x69,0x23,0x29,0x3e,0xb0,0x9f,0xb3,0x45,0x24,0x2d,0x4f,0xaa,0xb5,0xa7,0x59,0xa6,0xd7,0x58,0x4b,0x2a,0xd7,0x26,0x3a,0x1f,0x64,0xac,0xae,0x5c,0xd7 +,0xc2,0xae,0xb3,0x39,0x4f,0x3d,0x9e,0xd7,0xb3,0x39,0x3c,0x60,0x35,0x37,0x2e,0xd8,0x3b,0x2d,0x1e,0x44,0xc8,0x97,0xa8,0xa7,0xd6,0xeb,0xfa,0x39,0xae,0xbe,0xad,0x22 +,0x27,0x20,0xb2,0x9e,0xae,0x25,0x16,0x1c,0x32,0xaa,0xa6,0x9d,0xb2,0xcb,0x47,0xb7,0xac,0xa1,0x50,0x5a,0x22,0x27,0x30,0x38,0xb7,0xc2,0xae,0x24,0x32,0x23,0xb7,0xb3 +,0xaa,0x64,0x5e,0xb5,0xae,0x99,0x7e,0xac,0x27,0x5c,0x2a,0x20,0x23,0x27,0xbe,0xcd,0xc1,0xca,0xbb,0x5f,0x36,0x24,0xad,0xae,0x99,0xb0,0xbd,0xc2,0xbe,0xa1,0xe3,0x2e +,0x11,0x19,0x25,0xc6,0x78,0xc6,0x3c,0xbf,0x4b,0x45,0xb7,0xd9,0xa1,0xb8,0xae,0xd9,0xbe,0xb2,0xaf,0xc0,0x5b,0x29,0x2a,0x32,0xfc,0xce,0x2c,0x24,0x1e,0x7d,0xb0,0xa1 +,0xad,0xc1,0x6b,0xb8,0xa5,0xae,0xbc,0x33,0x2e,0x32,0xb6,0xaa,0xb5,0x38,0x1e,0x1c,0x28,0xe2,0xc5,0x4c,0x37,0xee,0xb3,0xa2,0xa9,0xb8,0x70,0x5c,0x43,0x54,0xc5,0xba +,0xab,0xb8,0x32,0x24,0x2c,0x2f,0xcf,0x4f,0xcc,0x22,0x21,0x4e,0xba,0x96,0xa4,0xa9,0x31,0x3f,0xb9,0xae,0xa3,0x45,0x28,0x28,0x52,0xb4,0xbb,0x3c,0x26,0x1f,0x38,0x36 +,0x2f,0x27,0x3b,0xaf,0x9a,0x97,0xa9,0xc7,0x7d,0xb7,0xac,0xab,0x3c,0x2f,0x3f,0xb4,0xca,0xc9,0x36,0x1f,0x1c,0x1b,0x28,0x20,0x30,0x41,0x9f,0x9d,0xa8,0xb2,0xbb,0x9f +,0x9f,0xa1,0xc9,0x2f,0x35,0x39,0xb9,0xbf,0x53,0x2f,0x22,0x36,0x3c,0x4b,0x1e,0x14,0x21,0xb8,0x99,0x9a,0xb1,0x64,0xcb,0x9e,0x97,0xa6,0x31,0x1a,0x34,0xb5,0xae,0xbd +,0x36,0x2b,0x26,0x24,0x2e,0x2a,0x2e,0x33,0xde,0xba,0xa6,0x9e,0xa8,0xbd,0xbc,0xaf,0xd8,0x49,0x3d,0xae,0xa4,0xab,0x35,0x1d,0x1f,0x3a,0xc4,0xc1,0x1e,0x15,0x22,0x68 +,0xa5,0xb1,0xb1,0xe9,0xb8,0xae,0x9e,0x9d,0xce,0x28,0x2e,0xa9,0x9d,0xac,0x2c,0x1d,0x2a,0xb4,0xbb,0x27,0x11,0x1b,0x66,0xac,0xaa,0xbd,0xc7,0x3d,0x57,0xb3,0xa5,0xb2 +,0xe1,0xf3,0xac,0xab,0xa1,0xb3,0x30,0x28,0x31,0x4f,0x29,0x1e,0x1e,0x3d,0xcb,0xdc,0x2b,0x39,0xba,0x9f,0xa1,0xb1,0x33,0x29,0xc3,0xa3,0x9c,0xa7,0x42,0x2b,0xb6,0x9e +,0x9e,0x4b,0x15,0x0f,0x25,0xaf,0xa5,0xdc,0x2c,0x29,0xd9,0xa1,0xbe,0x28,0x1c,0x31,0xad,0x9f,0x9d,0xaf,0xb9,0xb2,0xb1,0xae,0xed,0x2a,0x21,0x2e,0x53,0xad,0xb3,0x3a +,0x1f,0x25,0xf0,0xb2,0x3e,0x20,0xe2,0x99,0x92,0x1d,0x0a,0x28,0x97,0x8b,0xa0,0x20,0x1d,0xa3,0x9d,0xe2,0x2a,0x0d,0x30,0x92,0x9e,0xa1,0x3d,0x15,0x0c,0x0a,0x0e,0xad +,0x8b,0x96,0x9b,0x26,0x3b,0x96,0x93,0xaf,0x2b,0xac,0x93,0x94,0xb9,0x12,0x0b,0x2f,0x41,0xc0,0x7e,0x12,0x0f,0x1e,0x5a,0x39,0xc8,0xbb,0xa0,0x98,0xb7,0x29,0xba,0x8f +,0x89,0x94,0xad,0x23,0x12,0xe3,0x2f,0x21,0x18,0x0c,0x0e,0x1a,0x4c,0xaf,0x99,0x4e,0xb8,0x9c,0x96,0x8c,0x94,0xb6,0x14,0x0e,0x1c,0xc1,0xa7,0xac,0xbd,0xaa,0xaf,0xc4 +,0x10,0x04,0x13,0x3c,0x8f,0x93,0x9b,0xa9,0x1c,0x5b,0x29,0x2d,0xad,0xe9,0xa0,0xa9,0xa4,0x27,0x3d,0xae,0x38,0xc2,0x21,0x54,0x27,0xee,0x5b,0x1f,0xaf,0x2c,0xaf,0x9e +,0xa0,0x9c,0x1e,0x1e,0x19,0xcf,0x97,0xaf,0x9b,0x23,0x35,0xbf,0x9e,0x99,0x4e,0x30,0x12,0x2a,0x1b,0x31,0x60,0x3f,0xa9,0x1d,0xd9,0xcc,0xae,0x9b,0x29,0x99,0x98,0x92 +,0x9b,0x66,0xa6,0x42,0x2f,0x08,0x0d,0x0d,0x1f,0x9c,0xa7,0x8f,0xbc,0x4b,0x1d,0x1e,0xab,0xb7,0x8f,0x98,0xa3,0xdd,0x16,0x21,0x17,0x9c,0x94,0xb0,0x1e,0x0b,0x13,0x15 +,0xa7,0xa6,0x97,0x9b,0xaa,0x96,0xbb,0xba,0x39,0xe8,0x2b,0x12,0xac,0xad,0xaa,0x26,0x18,0xbb,0x4b,0x2d,0x12,0x25,0x26,0xa1,0x92,0xaf,0x9d,0xa9,0x97,0x9c,0xba,0x2c +,0x1e,0x37,0x1a,0x2a,0x64,0x62,0xbb,0xc1,0x9f,0x2e,0x22,0x30,0xab,0x36,0x38,0xed,0x41,0xa9,0x2d,0xba,0x59,0xc1,0x9b,0xa6,0xa4,0x24,0x2a,0xaa,0x48,0xd2,0x1e,0xa4 +,0x8f,0xa4,0x1c,0x09,0x06,0x0d,0x99,0x9a,0x93,0x9c,0xa0,0xbf,0x19,0x1d,0x37,0x9d,0x90,0x9c,0x9d,0x5d,0x2b,0x38,0xca,0xc9,0x13,0x12,0x1a,0x1f,0x1c,0xa0,0x4a,0xc4 +,0xdc,0x33,0xa8,0xb8,0x8f,0x9a,0xa2,0xa8,0xb3,0x97,0x9d,0x40,0x17,0x15,0x33,0x29,0x1c,0x10,0x14,0x1b,0x98,0x98,0xbe,0xa8,0xba,0x8e,0xa7,0xa4,0xd2,0x38,0x3f,0x12 +,0x1c,0x1c,0xb2,0x97,0x93,0x9e,0x17,0x0c,0x0f,0x1e,0x1c,0xa5,0x96,0x9a,0x8e,0xa4,0xc8,0x1c,0x4d,0xa6,0xbc,0x9f,0xba,0x9b,0xbd,0x1d,0x0d,0x12,0xa1,0x9a,0xa4,0x1e +,0x11,0x0c,0xbe,0xa5,0x46,0xb6,0x2e,0xa6,0x59,0x4b,0xae,0xcc,0x9a,0xb9,0xb6,0x6c,0xb5,0x93,0xa3,0x9c,0x3a,0x27,0x21,0x3c,0x15,0x1b,0x26,0x13,0xb9,0x3a,0xcd,0x29 +,0x2f,0xaf,0x46,0x9d,0xad,0xa9,0x9c,0xa5,0x9c,0xc6,0x95,0xb6,0x19,0x0a,0x0b,0x20,0x94,0x83,0xa7,0xcf,0x18,0x17,0x1d,0x28,0xa4,0xc8,0x9f,0x9f,0x2e,0x1b,0x18,0xbf +,0x35,0xb0,0xba,0x5b,0xbf,0xcd,0x21,0x18,0xc5,0x2f,0x8c,0x93,0x99,0xb5,0xf9,0x99,0x4c,0xb2,0x2f,0x14,0x1b,0x1c,0x40,0x54,0xc1,0xbd,0x22,0x11,0x10,0x26,0xa0,0x89 +,0xb8,0xad,0xb4,0xa7,0x91,0xb1,0xad,0x1f,0x29,0x62,0x3e,0x34,0x24,0xdc,0x5b,0xbe,0x69,0x39,0x49,0x38,0x3c,0x27,0x9d,0xcc,0xb8,0xbf,0x18,0x26,0x28,0x8f,0x8c,0x96 +,0xa9,0x1e,0x1f,0x1b,0xc2,0xbe,0x4f,0xab,0xe4,0x37,0x1a,0x1f,0x14,0x5d,0xc8,0x29,0xa2,0xa7,0x9e,0xce,0xd8,0x44,0x29,0xa1,0xa4,0xa6,0xad,0xb2,0x9a,0x5a,0xae,0x26 +,0x14,0x11,0x15,0x18,0x34,0x9c,0x26,0xa9,0x5e,0xe2,0xb2,0x9c,0x8c,0xa7,0xa9,0x60,0x3e,0x4f,0x3d,0xad,0x2c,0x27,0x4a,0x23,0x1e,0x1e,0x28,0x19,0xbd,0x41,0xb4,0x91 +,0x9e,0x90,0xa6,0x9b,0xae,0x3f,0x3d,0x19,0x1b,0x23,0xaf,0xa7,0xad,0x9e,0x42,0x1d,0x0f,0x18,0x16,0x16,0x9c,0x4f,0x9e,0x99,0xa3,0xa6,0x3e,0xaa,0x34,0xb6,0x9f,0xc3 +,0xc7,0x3f,0x46,0x37,0xbe,0x9d,0x3d,0x36,0x23,0x57,0x23,0x5d,0xc0,0x10,0x2f,0x27,0xb5,0xbb,0xa5,0x9c,0x3e,0x38,0x21,0x4d,0x9c,0x96,0x8f,0xa4,0xac,0xb0,0x27,0x3a +,0x24,0x1c,0x0b,0xc0,0x2c,0x19,0x9c,0xa4,0x9e,0x1c,0xc6,0xbb,0x2d,0xa8,0xbc,0xa9,0xb5,0xad,0x9b,0xed,0xd3,0x1c,0x18,0x16,0x1e,0x2d,0x27,0x8c,0x28,0x2e,0x9a,0xad +,0x9e,0x32,0xa1,0x36,0x20,0xa2,0xc6,0xc5,0x47,0xab,0xac,0x3f,0xab,0xf5,0x3c,0x15,0x0f,0x22,0x0e,0x9c,0x99,0xba,0x8a,0x9e,0x9e,0x2c,0x2c,0x29,0x0c,0xc5,0xd7,0x50 +,0xb1,0x9d,0xa1,0x2a,0xb4,0xa8,0x32,0xd6,0x43,0x4f,0x15,0x1c,0x8d,0x2d,0xc7,0x9f,0x37,0x1f,0x17,0xb1,0x2b,0x2d,0xa3,0x38,0xd3,0xb0,0x9a,0x9f,0xb5,0x9c,0x3b,0x3d +,0x3a,0x1d,0x25,0x17,0x24,0x96,0x1b,0xa4,0x99,0x2e,0x3c,0x25,0x9c,0x5e,0xca,0x94,0x2f,0xcd,0x9e,0xa1,0xb3,0x21,0xaf,0x1d,0x1a,0x5a,0x58,0x4a,0x18,0x0e,0xe7,0x1a +,0x35,0x8f,0x9f,0x9a,0xa3,0x8f,0x9f,0x39,0xa8,0x27,0x13,0x2d,0x2c,0xd9,0x38,0xad,0xb2,0x43,0xa9,0xbe,0x3b,0x2f,0x16,0x25,0xac,0x1a,0xad,0xaa,0xc2,0xc9,0x2d,0xab +,0x27,0xcc,0x9b,0x1f,0x3a,0xcc,0xba,0x9c,0x96,0x8d,0xbe,0xcf,0x4f,0x1f,0x1b,0x17,0x0d,0x21,0x48,0x22,0x95,0x9a,0xab,0xbd,0x46,0xe3,0x24,0xc0,0xb0,0x2b,0xaf,0xa4 +,0x9b,0x9e,0xa6,0xaa,0x1d,0x1d,0x24,0x21,0x22,0x28,0x17,0x38,0x3e,0x3c,0x92,0xa2,0x9f,0xad,0xac,0xa2,0x31,0xad,0xc7,0x1c,0x6f,0x3e,0x64,0x3e,0x2f,0x4d,0x23,0xb3 +,0xb7,0xc5,0xb9,0x3b,0x1f,0xc5,0x6d,0x34,0xa7,0x47,0x6a,0x39,0xc4,0xa8,0xcb,0x9f,0xac,0x2e,0x35,0x1c,0x2f,0xab,0x9c,0x93,0xa7,0xcb,0x68,0x31,0x39,0x23,0x0c,0x1d +,0x1a,0x1d,0x9f,0xaa,0x9d,0xb1,0xb4,0xa4,0x30,0xd6,0x36,0x27,0xc0,0x9f,0x93,0x9e,0xaa,0xb6,0x2a,0x3f,0x2c,0x22,0x1a,0x0f,0x0e,0x1c,0x9f,0xb9,0x8f,0x93,0xa8,0x9c +,0x5c,0xbc,0x26,0x2f,0x79,0x20,0x43,0xea,0xb8,0x9f,0xbe,0xaf,0x27,0x2d,0xb3,0xf0,0xb3,0x37,0x38,0x1d,0xa7,0xa1,0x25,0xb1,0x1b,0x27,0x56,0xbf,0x98,0x40,0xac,0xc8 +,0x2d,0xba,0x49,0xb8,0xc2,0xbc,0xab,0xde,0xa3,0xf3,0x53,0x33,0x1c,0x10,0x10,0x41,0x16,0xb7,0x9b,0xa8,0xa2,0xb0,0x99,0xb5,0x3a,0xdc,0x27,0x4c,0x9d,0xa9,0xa9,0x5e +,0xad,0xa8,0xbd,0xb0,0x16,0x0d,0x0d,0x13,0x24,0x9b,0x97,0x51,0x99,0xa7,0x9f,0xa9,0x2b,0x2a,0x0e,0x27,0xbe,0x56,0x98,0x9a,0xa8,0xa6,0xaa,0xa3,0x3a,0x3c,0x2f,0x1f +,0x43,0x41,0x2d,0x1f,0x9b,0x2d,0x1f,0xbc,0x18,0x2d,0x22,0xcf,0xcb,0x2c,0x9d,0xaf,0xa4,0x8e,0xa6,0xaa,0x39,0xb1,0xa0,0xce,0xac,0x1d,0x2a,0x24,0x23,0x19,0x1f,0x28 +,0x11,0xaf,0xad,0xc5,0xaa,0xb5,0x9a,0xb5,0x98,0x99,0x1c,0x4d,0x39,0xb8,0xae,0xac,0x9f,0x2c,0x40,0x33,0x24,0x20,0x1a,0x19,0x2b,0x9e,0x4f,0xae,0x97,0xac,0xab,0x32 +,0x2c,0x17,0x1e,0xa4,0xe0,0xc4,0xad,0xae,0x9a,0x9b,0x91,0xaf,0x1e,0x24,0x1c,0x33,0x2f,0x22,0x17,0xe3,0xd8,0x45,0x98,0x33,0x1c,0x0f,0x2c,0xaf,0xce,0x98,0xa3,0xa0 +,0x90,0x93,0x96,0xca,0x2e,0x3b,0x19,0x32,0x2c,0x43,0x58,0x28,0x21,0xc9,0xbc,0x12,0x2d,0x2d,0xec,0x4d,0xfa,0x9e,0xb4,0x90,0x97,0x53,0x37,0x28,0xa9,0xa7,0xca,0xcc +,0x1e,0x35,0x3e,0x66,0xe2,0x41,0x1b,0x20,0xad,0x37,0x9e,0xb4,0x3d,0x27,0x2a,0x9f,0x45,0x79,0x2e,0x2b,0xa6,0xaa,0x9d,0xb1,0xb1,0x93,0xa9,0xa3,0x2b,0x16,0x1d,0x15 +,0x17,0x44,0xb8,0x2d,0xaa,0xaf,0xdf,0x38,0x39,0x35,0x28,0xab,0x9d,0xe4,0xa2,0x98,0x92,0x93,0xa8,0xc8,0x0f,0x20,0x31,0x2e,0x2a,0x0f,0x0f,0xb3,0xb5,0xdb,0xa4,0x2a +,0x2b,0x26,0xac,0x9d,0xb1,0x9a,0xbb,0xdb,0x9a,0x9c,0x9e,0x1a,0x15,0x29,0x24,0xcb,0x31,0x4c,0xaa,0x3d,0xa7,0x95,0x27,0x42,0x36,0x38,0x1f,0x15,0x41,0x58,0x9d,0x9b +,0xad,0xa2,0x3d,0x69,0xaa,0x5c,0xaf,0xde,0x5c,0x3a,0xae,0x9d,0x5a,0x0d,0x27,0x5c,0x29,0xaa,0x2c,0x2d,0x23,0xd9,0xbc,0x29,0xad,0xc0,0xae,0xa4,0xc3,0x9d,0xac,0x99 +,0xa9,0x49,0xb3,0x2c,0x19,0x0c,0x0b,0xa6,0x8d,0x38,0x17,0x0d,0x54,0x98,0x92,0x90,0x30,0xb5,0xbf,0x1b,0x2a,0xb1,0x8a,0x99,0x2f,0x13,0x11,0x31,0xab,0xae,0xa8,0x1f +,0x1f,0x62,0x14,0xb2,0x8f,0x8c,0xe2,0x0a,0x0e,0x23,0x9d,0x8d,0xb7,0xae,0xaa,0x9d,0x2c,0x15,0x9d,0x96,0x94,0x15,0x08,0x17,0x32,0xb1,0x99,0x36,0xad,0xab,0x29,0x19 +,0x13,0x90,0x9c,0x48,0x16,0x0b,0xca,0x90,0x88,0x8f,0xa6,0x9d,0x3f,0x17,0x0b,0x23,0x9a,0xbe,0x0d,0x13,0x15,0xb9,0x92,0xa9,0x99,0xd4,0x9f,0x1c,0x0d,0xcb,0x96,0x89 +,0xa6,0x18,0x15,0x3d,0x93,0x9c,0xda,0x49,0x21,0x1f,0x08,0x0b,0x97,0x94,0x9a,0xb5,0x1d,0x41,0x30,0x9d,0xaa,0xd2,0xa0,0x46,0x2b,0x0f,0xd4,0x8e,0x8b,0x9a,0x12,0x10 +,0x2a,0xf5,0xed,0x22,0x31,0x98,0x3c,0x15,0x19,0xac,0x8a,0xa6,0x3c,0x12,0x16,0xa4,0xd8,0xab,0xa6,0x93,0x93,0x1b,0x1b,0x3c,0x97,0x8d,0x21,0x0b,0x05,0x16,0x8d,0xa5 +,0xb9,0x66,0xad,0xa0,0x0f,0x1b,0xc8,0x91,0x8d,0x1d,0x19,0x21,0x90,0x8e,0x6c,0x9f,0xc7,0x40,0x16,0x09,0x1e,0xbd,0xa7,0xa2,0x0e,0x1d,0xa7,0x92,0x96,0x35,0x9c,0xa4 +,0x2b,0x16,0x0e,0xab,0x98,0x97,0x36,0x0e,0x6c,0xa0,0x9b,0xac,0x2d,0x41,0x19,0x0b,0x3b,0x3d,0x8b,0x95,0x34,0x1e,0x11,0x94,0x9f,0xb4,0xa3,0x5a,0xb4,0x14,0x13,0xbf +,0x9a,0x8b,0x38,0x10,0x1a,0xb8,0x97,0x22,0x1b,0xa1,0x31,0x2b,0x18,0x2f,0x97,0x98,0x92,0x1c,0x14,0x6f,0x9d,0x94,0x30,0x55,0x9f,0xb6,0xef,0x19,0x3c,0x9a,0xa6,0x29 +,0x04,0x10,0x98,0xb8,0xb2,0x34,0xa1,0x96,0x22,0x4f,0x27,0x9e,0x8e,0xfd,0x2a,0x0d,0xd5,0x93,0xb4,0xae,0x2b,0xbf,0x30,0x11,0x1a,0x1b,0x9f,0x8f,0x1c,0x1f,0x1e,0x91 +,0x8a,0x59,0x9b,0xdd,0xb6,0x2e,0x0e,0x33,0x79,0x97,0xd0,0x13,0x28,0x4f,0x96,0x9d,0x2f,0x46,0x27,0x2b,0x2d,0x10,0xbb,0xb8,0x9a,0xb3,0x11,0xa9,0x9e,0x8f,0x99,0x46 +,0xa0,0x34,0x2d,0x1e,0x19,0xac,0xb9,0xc8,0x1b,0x0f,0x69,0xc2,0xaf,0x9e,0x2d,0xa7,0x31,0x18,0x29,0x2b,0x8d,0x9a,0x47,0x72,0x32,0x94,0x9a,0xce,0xaf,0x6d,0x59,0x10 +,0x14,0x3b,0x2c,0xbb,0x22,0x13,0xdb,0xdd,0x92,0x9d,0xab,0x9a,0x2e,0xaa,0x37,0x23,0xa7,0xbe,0xa6,0x1c,0x1b,0xad,0xa3,0x9b,0x24,0x28,0xb1,0x37,0x1f,0x0d,0x1b,0x96 +,0xca,0x45,0x1f,0xb6,0x95,0xe6,0x98,0xa5,0xab,0xa2,0x33,0x3d,0x26,0x3e,0xa6,0x38,0x33,0x1d,0x44,0xa5,0xb3,0x48,0x23,0x2e,0xa3,0x1c,0x17,0x34,0x68,0x97,0x1a,0x2e +,0xae,0x94,0x8b,0xbf,0xa6,0xa3,0xad,0x7b,0x17,0x33,0x30,0x2b,0x33,0x1a,0x28,0x28,0xc8,0xa7,0x3e,0xb6,0xac,0x51,0xb2,0x25,0x27,0xd2,0xcc,0xa5,0x46,0xa5,0x97,0x9d +,0xb3,0x3d,0xae,0x7d,0x25,0x1d,0x16,0x19,0x27,0x28,0xb7,0xb0,0xb2,0xa5,0x39,0xa9,0xab,0xdd,0xaf,0x3f,0xb7,0x78,0x2b,0xaa,0xbd,0xa4,0xb6,0xb5,0xb1,0x2d,0x4f,0x25 +,0x29,0x2a,0x1c,0x1b,0x27,0x39,0xb6,0xb1,0xa1,0x9a,0xb2,0x53,0x42,0xcb,0xa3,0xac,0xbc,0x5c,0x25,0x3c,0xd4,0x9d,0xa2,0xad,0x4a,0x1c,0x1b,0x29,0x39,0x34,0xd5,0x24 +,0x1d,0x1e,0xd0,0xa7,0x9b,0x99,0xab,0xca,0x66,0xac,0xa9,0xab,0xaf,0xcd,0x27,0x1d,0x24,0x63,0xab,0xa0,0xc1,0x2f,0x22,0x2f,0x77,0x54,0x45,0x22,0x2c,0x2a,0x1d,0x2a +,0xa3,0x91,0x90,0xa9,0x3e,0xef,0xb7,0x9d,0xb4,0x3f,0x39,0x35,0x17,0x13,0x52,0x95,0x97,0xc2,0x37,0x1a,0x3d,0xc6,0x41,0x2b,0x3b,0x33,0x18,0x1e,0xab,0x90,0x8d,0x90 +,0xaa,0x2d,0x24,0xbc,0xb9,0x46,0x32,0x2b,0x18,0x17,0x2b,0xaf,0x9b,0x96,0xce,0x1e,0x45,0x68,0xb2,0x2d,0x28,0x4c,0x4a,0x28,0x26,0xa1,0x94,0x92,0x9a,0x3c,0x28,0x3e +,0xfe,0xe6,0x37,0xc6,0x38,0x1b,0x18,0x28,0x9e,0x98,0x9e,0xcd,0x1e,0x27,0x3c,0x2d,0xed,0xcd,0xc1,0x2e,0x20,0x3a,0xa9,0x8f,0x9a,0xb4,0x32,0x32,0xb8,0xcf,0xb4,0xab +,0xbf,0x1e,0x10,0x2a,0xb4,0xa3,0xa7,0x3c,0x21,0x2b,0xe0,0xcc,0x4a,0x5c,0x35,0x38,0x2e,0x24,0xb7,0x99,0x91,0xa3,0x38,0x35,0xa5,0xa7,0x6b,0x5a,0x3a,0x57,0x2c,0x1c +,0x2b,0xa5,0x9c,0xb4,0x20,0x22,0xc8,0x3d,0x1f,0x26,0x47,0xe7,0x2a,0x23,0xe0,0x9a,0x90,0x9f,0xa9,0xb1,0xce,0x46,0x3d,0xb3,0xbc,0x46,0x24,0x17,0x22,0xd8,0x9d,0x9b +,0xd0,0x2f,0x26,0x39,0x33,0x2d,0x37,0x3f,0xc2,0x27,0x19,0x70,0x92,0x8e,0x9c,0x54,0x45,0xaa,0xb8,0x2b,0x4b,0xaf,0xc5,0x1f,0x11,0x27,0x9b,0x94,0xc7,0x4f,0x4b,0x43 +,0x2e,0x19,0x29,0xd2,0xbb,0x31,0x19,0x24,0xb3,0x92,0x91,0x99,0xa9,0x4e,0x47,0x27,0x30,0xbd,0xa9,0xbd,0x1c,0x10,0x25,0x99,0x95,0xb1,0x3f,0x2d,0x67,0x5c,0x1e,0x2b +,0xb0,0xc3,0x1c,0x0f,0x20,0x90,0x8b,0x9a,0xaf,0x47,0xbc,0x52,0x29,0x51,0xa7,0xb5,0x1d,0x0f,0x1b,0xa5,0x93,0xa6,0xc0,0x40,0x37,0xbd,0x2a,0x21,0x64,0xb9,0x39,0x1e +,0x1e,0x46,0x9b,0x9c,0xae,0x6e,0xbc,0xa8,0xc9,0x32,0x4d,0xac,0xb4,0x21,0x12,0x2b,0x9a,0x98,0xb6,0x33,0x45,0xb9,0x4b,0x23,0x38,0xab,0xae,0x1e,0x12,0x20,0xad,0x97 +,0xa4,0xaf,0xc3,0xbd,0x38,0x1e,0x2b,0xab,0xa5,0xda,0x1b,0x2c,0xaa,0x9d,0x99,0xf0,0x53,0x57,0xfc,0x33,0x2d,0x3f,0xd0,0x2a,0x18,0x1a,0xdd,0x94,0x95,0xa8,0xff,0xdb +,0x2f,0x2c,0x28,0x7c,0xaa,0xb2,0x25,0x18,0x4a,0x9d,0x97,0xa3,0xb1,0x7b,0x37,0x36,0x26,0x34,0xc4,0x38,0x2b,0x20,0x38,0x9e,0x96,0x9f,0xaf,0xca,0x3e,0x2b,0x1f,0x22 +,0x42,0x40,0x2a,0x1f,0x22,0xa8,0x8e,0x92,0xa1,0xd8,0x36,0x2a,0x26,0x2a,0x58,0xb5,0x47,0x23,0x1b,0xba,0x94,0x95,0xa5,0xa9,0x56,0x27,0x27,0x20,0x24,0x29,0x29,0x1f +,0x1f,0x41,0x94,0x90,0x9e,0xb7,0x5a,0x48,0x46,0x43,0x5a,0x78,0x2c,0x20,0x1c,0x2e,0x9d,0x8f,0x98,0xa9,0xcd,0xf0,0x37,0x1f,0x21,0x3a,0x2f,0x1e,0x1a,0x37,0xa5,0x9e +,0x97,0xac,0xcb,0xaf,0x58,0x2f,0x29,0x56,0x5a,0x1c,0x1d,0x44,0xad,0x9c,0x97,0x9a,0xbe,0xcf,0xbe,0x33,0x3b,0x5a,0x3a,0x16,0x15,0x28,0x48,0xa6,0x9c,0x9d,0xb1,0x3e +,0x4e,0xe3,0x3a,0x5e,0x3d,0x33,0x2c,0x23,0xd1,0xa9,0x99,0x9b,0x77,0x4a,0xcc,0xcb,0x56,0x3b,0x31,0x1f,0x1f,0x28,0xde,0xa2,0x98,0xa1,0x48,0x40,0xc6,0x55,0x3b,0x30 +,0x2f,0x6f,0x2f,0x2c,0x2d,0xd2,0xa2,0xa4,0x9f,0xb2,0x3e,0x47,0x44,0x3a,0x29,0x2a,0x70,0x4b,0x3b,0x7d,0xa7,0x9d,0xa3,0xaf,0x4c,0x32,0x35,0x2f,0x2d,0x50,0xbc,0x3f +,0x27,0x2e,0x58,0xa6,0x98,0xa0,0x33,0x19,0x2a,0xcf,0xbe,0xb0,0x6a,0x27,0x26,0x5a,0xa7,0x9e,0x9c,0x9d,0x45,0x1f,0x24,0x35,0xaf,0xaa,0x3b,0x1b,0x1c,0x2e,0xbd,0xa1 +,0xa3,0xad,0x5f,0x1d,0x1d,0xc3,0x9d,0x97,0xbf,0x12,0x0f,0x27,0x9a,0x94,0xa0,0xa9,0x46,0x29,0x2e,0xc2,0x9c,0xa1,0x3d,0x12,0x0f,0x29,0x9f,0x99,0xad,0xcd,0x36,0x35 +,0x3e,0xdd,0xa2,0x9b,0x5f,0x15,0x0f,0x25,0x9f,0x98,0x9e,0xbe,0x48,0xbf,0x6d,0xaa,0x9e,0xc8,0x2d,0x1a,0x26,0x34,0x2b,0x64,0xc3,0xb8,0xc3,0x6e,0xb7,0xba,0xd7,0x43 +,0x2f,0xb6,0xb2,0x24,0x10,0x2d,0x9b,0x99,0x9d,0xf6,0xc1,0xc6,0x2a,0x2f,0xd6,0xaa,0xac,0x21,0x15,0x2c,0xb6,0xa4,0xa5,0x9c,0xba,0x1a,0x11,0x20,0x9d,0x95,0xb1,0x24 +,0x13,0x22,0xbc,0x96,0x8e,0x9e,0x1f,0x0b,0x1e,0xa1,0x91,0xa6,0x1e,0x1c,0x37,0x5d,0xad,0x9c,0x93,0xaf,0x0f,0x0c,0x23,0x98,0x98,0xbd,0x33,0x2f,0x26,0x26,0xb4,0x93 +,0x99,0x2a,0x10,0x17,0xad,0x95,0xa1,0x43,0x39,0x39,0xde,0xa7,0x9e,0xa9,0x32,0x1f,0x2c,0xaf,0xeb,0x31,0x22,0x32,0xba,0x40,0xde,0xaa,0xce,0x24,0x29,0xb8,0xa0,0x65 +,0x1f,0x27,0xa8,0x9c,0xb7,0x39,0xb7,0x93,0xb5,0x1d,0x1f,0xb9,0x99,0xb3,0x1d,0x1c,0x34,0x5d,0xc3,0xaf,0x9e,0xc4,0x1b,0x16,0xf2,0x94,0x9a,0x39,0x1b,0x1f,0x4d,0xb6 +,0x93,0x98,0xb5,0x17,0x19,0xaa,0x93,0x9a,0x1b,0xaf,0x0c,0x06,0x05,0x12,0x97,0x48,0x4c,0x08,0x22,0x8d,0x94,0xa0,0x92,0x8e,0xa9,0x95,0x9d,0xa6,0x83,0x8c,0x13,0xe7 +,0x1e,0xc8,0x86,0x9e,0xa4,0x9c,0xdb,0x16,0x3e,0x2c,0x17,0x05,0x05,0x0a,0x0f,0x07,0x05,0x07,0x0e,0x1c,0x04,0x19,0x28,0x1e,0x17,0x34,0xa1,0x9c,0x4b,0x35,0x98,0x8f +,0x96,0x50,0x92,0x83,0x84,0x91,0x9d,0x89,0x80,0x84,0x8c,0x88,0x84,0x8d,0x90,0xaf,0x98,0x8c,0xb0,0x0c,0x08,0x8f,0x30,0x0d,0x0b,0x03,0x17,0x08,0x00,0x1a,0x26,0x0d +,0x09,0x00,0x19,0x13,0x00,0x07,0x0d,0x24,0x1b,0x1e,0x1c,0x3e,0x30,0xcf,0xa4,0x94,0x8d,0x94,0x8e,0x87,0x83,0x92,0x8c,0x86,0x81,0x88,0x8e,0x96,0x86,0x82,0xa4,0x23 +,0xac,0x93,0x99,0xa6,0x68,0xb4,0x2c,0x19,0x0c,0x27,0xd3,0x0c,0x00,0x03,0x0a,0x2b,0x10,0x01,0x0b,0x16,0x16,0x06,0x15,0x2c,0x2a,0x19,0x0f,0xa9,0xa2,0xaa,0xa9,0x93 +,0x87,0x8c,0xa2,0xce,0x97,0x91,0x8f,0xa1,0x92,0x93,0xc8,0x8d,0x8b,0x83,0x8a,0x9e,0x89,0x8b,0x84,0xc0,0x34,0xa3,0x63,0x1e,0x12,0x29,0x1d,0x0f,0x16,0x0c,0x0c,0x0f +,0x09,0x02,0x17,0x32,0x0b,0x08,0x08,0x0a,0x0f,0x2a,0x0c,0x25,0x22,0x28,0x1e,0x3c,0x8a,0xa6,0xa0,0xb2,0x8e,0x80,0x8a,0x89,0x88,0x86,0x90,0x8e,0x8b,0x89,0x8d,0x8f +,0x99,0x53,0x68,0x29,0xbe,0x98,0xa9,0x1a,0x0f,0x0d,0xaf,0xa7,0x2a,0x1d,0x18,0x14,0x0f,0x09,0x1d,0x9d,0x23,0x08,0x00,0x02,0x0a,0xb6,0x21,0x3d,0x1d,0x09,0x01,0x0a +,0x8a,0x8c,0x89,0x1e,0x1a,0x90,0x8c,0x8f,0x8a,0x86,0x8c,0x5e,0x12,0x8a,0x80,0x84,0x9c,0x35,0xb5,0x8a,0x87,0x88,0x8f,0x92,0x5d,0x0a,0x0d,0x3b,0x87,0x37,0x23,0x14 +,0x05,0x0a,0x07,0xb9,0x4b,0x10,0x0b,0x02,0x17,0x17,0x53,0x38,0x06,0x0e,0x11,0x0a,0x0c,0x29,0x0f,0xbd,0x36,0xae,0x96,0xa7,0x8a,0xac,0x83,0xac,0x39,0x8b,0x8a,0x83 +,0x91,0x8d,0x80,0x8b,0x8b,0x9a,0x98,0x8d,0x11,0x0c,0x13,0x32,0x92,0x22,0x0d,0x8e,0x98,0x90,0xbe,0x0b,0x11,0x07,0x58,0x48,0x0c,0x90,0x0f,0x04,0x0a,0x0d,0x8b,0x22 +,0x18,0x01,0x01,0x05,0x08,0x12,0x8c,0xa3,0x12,0x27,0x29,0x85,0x8b,0x89,0xaf,0x23,0x99,0xb4,0x89,0x80,0x87,0x80,0x38,0x21,0x8e,0x80,0x91,0x9f,0x24,0x29,0x0e,0x2a +,0x89,0xa1,0x98,0x15,0x91,0x2a,0x08,0x0f,0x1f,0xf1,0x9e,0x0c,0x08,0x33,0x26,0xce,0x0b,0x1c,0x02,0x1b,0x0e,0x08,0x06,0x14,0x0b,0x35,0x9e,0xb5,0x99,0x18,0x8c,0x0e +,0x0b,0x2a,0x9f,0x86,0x88,0x98,0x8f,0x87,0x85,0x90,0x4f,0x9e,0x8f,0x94,0x9d,0x3c,0x1b,0x18,0x2a,0x80,0x8b,0x80,0xaf,0x21,0xa5,0x0e,0xd3,0xba,0x98,0x29,0x2c,0x1d +,0x54,0x2f,0xaf,0x9e,0x09,0x05,0x05,0x0d,0x0f,0x0e,0x00,0x05,0x01,0xb4,0x0f,0xa0,0x9d,0xcf,0x94,0x00,0x13,0x1b,0x8b,0x87,0x90,0x8f,0xa4,0x9c,0x82,0x96,0x84,0x9b +,0x9a,0x93,0xff,0x3c,0x27,0x93,0xa7,0x86,0x1f,0x8b,0xc8,0xb6,0xc0,0x06,0xd1,0x48,0x1d,0x93,0x59,0x29,0x91,0x17,0x36,0x00,0x9d,0x26,0x2c,0x16,0x0b,0x1f,0x07,0x0e +,0x14,0x8f,0x2b,0xb3,0x09,0x14,0x25,0x04,0x15,0x22,0x9c,0x86,0x2c,0xc4,0x9f,0x45,0x8e,0x1a,0xbb,0xb4,0x9a,0x98,0xfe,0x1d,0xa6,0xa9,0x8c,0x80,0x9a,0x8d,0x28,0x80 +,0xa8,0x23,0x2f,0x1b,0x90,0x86,0x91,0x98,0x9e,0x18,0x2f,0x02,0x21,0xaa,0xe6,0x03,0x01,0x03,0x21,0x0f,0x1b,0x9b,0x2e,0xae,0x05,0xcf,0x1e,0x13,0x19,0x1b,0x1c,0x9f +,0x88,0x9c,0x96,0x96,0xa2,0x1f,0x9a,0x9e,0x8a,0x8f,0xd6,0x21,0xa4,0x23,0x9c,0x80,0x8d,0x88,0x2f,0x94,0x12,0x22,0x5d,0x12,0xa1,0x8b,0xa0,0x13,0x37,0x9a,0xa6,0x14 +,0x16,0x2b,0xa8,0x9f,0x1d,0x00,0x12,0x0d,0x65,0x9a,0x28,0xa0,0x19,0x2c,0x07,0x0a,0x2f,0x0f,0xa3,0x98,0xa5,0x1b,0xe1,0x53,0x15,0x2d,0x0f,0xbb,0x8e,0xa6,0xa8,0x19 +,0x1b,0xae,0x9e,0x85,0x86,0x83,0x1f,0x24,0xc4,0x33,0x93,0x8b,0x8a,0x87,0x86,0x9b,0x3d,0xbb,0xaa,0xbb,0x21,0x08,0x3c,0x99,0x13,0x03,0x16,0x06,0x2b,0x93,0x73,0x12 +,0x17,0x31,0x01,0x05,0x0b,0x13,0x8f,0x8b,0xad,0x1f,0x1a,0xa4,0x8f,0x28,0x19,0x9f,0xc4,0x5e,0x2a,0x09,0x4f,0xd2,0x84,0x8e,0x99,0x87,0x9a,0x8a,0x16,0x1e,0xa6,0xa8 +,0x8c,0x8a,0x8a,0x9a,0x9b,0x41,0x1e,0xa5,0x9b,0x3a,0x0c,0xaf,0x17,0x00,0x0a,0x04,0x8e,0x97,0xbd,0xa1,0x0e,0xc2,0x21,0x11,0x08,0x0f,0xbf,0x8d,0x91,0x0a,0x0f,0x23 +,0x43,0x42,0x30,0xa8,0x9b,0x9a,0xe7,0x00,0x36,0x14,0x99,0x87,0xb9,0x91,0x2c,0x89,0x5a,0x41,0x25,0x2b,0x86,0x8e,0x88,0x8b,0xa2,0x48,0x06,0x69,0x9d,0x96,0x8a,0x1a +,0xba,0x0f,0x14,0x06,0x14,0x88,0x88,0x9e,0x00,0x1b,0x17,0x19,0x57,0x0b,0x4c,0x94,0x84,0xa5,0x0f,0xac,0x1d,0x40,0x1f,0x07,0xc1,0x90,0x9a,0x0c,0x00,0x0b,0x18,0x86 +,0x99,0x39,0x2c,0x31,0xca,0x0a,0x3b,0xa2,0x8a,0x8c,0x84,0x93,0x8a,0x8d,0x9d,0x9e,0x40,0x9a,0x8c,0x9a,0xc0,0xc8,0x0a,0xcb,0x09,0xa8,0x88,0xa4,0x4a,0x03,0x05,0x0e +,0xbe,0x0d,0x09,0x1f,0xb7,0xb8,0x2e,0xda,0x0c,0x2e,0xb6,0x0e,0x2c,0x3f,0x8a,0xae,0x0d,0x13,0x23,0x88,0x88,0x93,0x8d,0x4d,0x98,0x2e,0x0f,0x4d,0xcc,0x80,0xaa,0xb6 +,0xa9,0x90,0xac,0x77,0x2b,0x6d,0xa1,0x74,0xb5,0x15,0x2e,0x0a,0x0e,0x09,0xce,0x8e,0x8c,0x28,0x30,0x3c,0x15,0x94,0x0a,0x18,0x9b,0x83,0x8d,0x1a,0x13,0x1f,0x9d,0x98 +,0xa7,0x21,0xa2,0x9b,0x3d,0x05,0x08,0x13,0x3b,0x98,0xc7,0xbe,0x10,0x27,0x1d,0x18,0x17,0xcd,0x9c,0x95,0x95,0xa7,0x8e,0xb6,0x17,0x2a,0xaa,0x90,0x84,0x92,0xa9,0xb8 +,0x2c,0x1b,0x11,0x8d,0x86,0x93,0x6d,0x0a,0x20,0x2d,0x3a,0x0c,0x25,0xa4,0x93,0x2f,0x10,0x10,0x18,0xb3,0x28,0x15,0x0c,0xab,0x95,0x99,0x06,0x03,0x0d,0xb9,0x87,0x91 +,0x8f,0xb8,0x31,0x17,0x2a,0xb2,0xa3,0xa9,0x9e,0x86,0x8f,0xa6,0x1e,0x0b,0xb4,0x89,0x91,0xa6,0x48,0x28,0xbd,0x2f,0x16,0x05,0xbc,0x85,0x88,0x27,0x09,0x0d,0xc5,0xaa +,0x0e,0x26,0x38,0x8b,0x8d,0x41,0x1b,0x35,0xa3,0x29,0x1d,0xb6,0x87,0x8c,0x0f,0x00,0x05,0x1e,0x47,0x8a,0x96,0x94,0x3c,0x0e,0x38,0x1c,0x9d,0x9d,0x9e,0x1c,0x9c,0xad +,0xad,0xb0,0x11,0x1f,0xa7,0x8b,0x4c,0x65,0x65,0xad,0x22,0x05,0x01,0xa9,0x80,0x86,0xb3,0x07,0x2c,0xd0,0xc2,0xac,0x4a,0x9e,0x8c,0x94,0xcf,0x25,0x1d,0x74,0xcb,0xad +,0x9b,0xa4,0x33,0x09,0x07,0x0d,0x4b,0x2a,0x2c,0xc4,0x95,0x9e,0x12,0x16,0x21,0xad,0xa9,0xb1,0x28,0x99,0x8e,0xa6,0x21,0x0b,0xeb,0x8f,0x8e,0x9d,0x49,0xaa,0xae,0x13 +,0x06,0x30,0x93,0x80,0x90,0x19,0x1a,0x29,0x8f,0xfc,0x37,0x1d,0x6b,0x91,0x90,0xb7,0x43,0x3a,0x1e,0xad,0x3c,0x9f,0xa6,0x37,0x1b,0x0f,0x0e,0x18,0x1d,0x16,0x8e,0x89 +,0x8d,0x12,0x08,0x21,0xad,0x93,0x1d,0x24,0xde,0x8b,0x96,0x37,0x25,0xee,0x97,0xac,0x3d,0x18,0xb0,0xe9,0x16,0x09,0x1b,0x32,0x2f,0x8f,0xa8,0x95,0xba,0x1a,0x18,0x16 +,0x43,0x96,0x90,0xac,0xa5,0x3f,0xb5,0x25,0x27,0x9a,0x91,0x93,0x13,0x0e,0x23,0x3c,0x23,0x2f,0x16,0xdf,0x8e,0x9e,0xad,0x0e,0x55,0x2b,0x22,0x1e,0xb9,0x89,0x87,0xa6 +,0x14,0x1e,0x19,0x93,0xa7,0xa0,0xef,0x2b,0x1f,0x11,0x10,0x25,0x9d,0x1a,0x9e,0xa5,0x99,0xc5,0x15,0x36,0x26,0xc9,0x6c,0x46,0x9c,0x83,0x8a,0xd7,0x05,0x0e,0xa9,0xa2 +,0xe4,0x28,0x2c,0xae,0x1e,0x07,0x0e,0x45,0x80,0x87,0x8f,0x22,0x0b,0x19,0x25,0xb9,0x38,0xa4,0x91,0x8a,0x37,0x1e,0x39,0x9d,0xa2,0x51,0xa6,0x2b,0xd3,0x1e,0x15,0x15 +,0x27,0x18,0xa7,0x8f,0x93,0x92,0x1c,0x14,0x1c,0xb3,0x6a,0xd2,0xa4,0x89,0x91,0x23,0x0f,0x1e,0xae,0xa2,0xa4,0x30,0x19,0x20,0x1e,0x0e,0x12,0x14,0x8c,0x84,0x90,0x26 +,0x0b,0x1d,0x33,0xa9,0x66,0xcb,0xa2,0x87,0xa5,0x41,0x2d,0x43,0xa5,0x55,0x33,0x19,0x2d,0x2a,0x1b,0x2a,0x27,0x19,0x8d,0x91,0x95,0x1f,0x0e,0x20,0x40,0xeb,0x3d,0x95 +,0x90,0x87,0x9f,0x38,0x09,0x28,0xa7,0x9d,0x63,0x21,0x27,0x73,0x31,0x2a,0x0f,0x1f,0x8a,0x91,0x90,0x0b,0x16,0x21,0x9f,0x9f,0xda,0xa2,0x8b,0x9d,0x1c,0x1a,0x1d,0xb1 +,0x9f,0xa7,0x1a,0x43,0x39,0x2f,0x1e,0x1c,0x12,0x91,0x8b,0x95,0x4e,0x14,0x58,0x2f,0xdb,0x1f,0x2a,0x91,0x86,0xde,0x19,0x1a,0xaf,0x97,0xa6,0x41,0x27,0x1b,0x17,0x0f +,0x1c,0x10,0xab,0x86,0x8c,0x99,0x0d,0x11,0x18,0xce,0xc1,0xee,0xbf,0x8a,0x94,0xef,0x2e,0xcd,0x98,0x9b,0x34,0x14,0x14,0x4f,0xba,0x18,0x0f,0x19,0x8a,0x8c,0x90,0x18 +,0x07,0x14,0xbd,0xb7,0x3f,0xae,0x88,0x83,0x99,0x19,0x08,0x1f,0xa2,0x8a,0x3b,0x13,0x20,0x2e,0x1a,0x14,0x1c,0x8f,0x89,0x8f,0x1e,0x07,0x0c,0x29,0x9f,0x96,0xa2,0xa6 +,0x89,0xe9,0x14,0x16,0xb0,0x8e,0x93,0x31,0x1b,0x25,0xc4,0x1d,0x13,0x04,0x2d,0x86,0x83,0x95,0x0d,0x0b,0x15,0xb2,0xa2,0x99,0xae,0x90,0x95,0x60,0x0d,0x11,0xb6,0x8a +,0x8c,0x9f,0x26,0x11,0x0b,0x05,0x0c,0xb9,0x86,0x8e,0x93,0x0e,0x16,0x28,0x32,0x54,0xc0,0xa6,0x94,0x9b,0x2e,0x11,0x36,0x95,0x91,0x98,0x26,0x2d,0xd9,0x22,0x0f,0x08 +,0x02,0x9c,0x85,0x81,0xad,0x19,0x19,0x24,0x29,0x1e,0xa6,0x8b,0x88,0xbf,0x12,0x0e,0xbe,0x8c,0x8b,0xc5,0x2f,0x25,0x21,0x08,0x08,0x0f,0x93,0x86,0x87,0xa8,0x09,0x14 +,0x28,0xb2,0x1e,0x1a,0xa3,0x82,0x9f,0x1f,0x0f,0xc2,0x8f,0x98,0x4c,0x20,0x30,0x3c,0x0f,0x0f,0x0d,0x40,0x86,0x8a,0x8b,0x18,0x16,0x16,0x1e,0x1d,0x6f,0x93,0x84,0x90 +,0x23,0x0c,0x17,0x98,0x90,0xbb,0x3c,0xeb,0x9f,0x1d,0x07,0x14,0x16,0x8e,0x8e,0x91,0x0d,0x0e,0xc9,0x98,0x46,0x10,0x40,0x8e,0x83,0x9d,0x2b,0x05,0x1c,0xaf,0x94,0x9e +,0xb4,0xa3,0xa8,0x0e,0x08,0x05,0xbd,0x8f,0x94,0x9b,0x19,0x47,0x34,0x25,0x2f,0xc0,0x96,0x85,0x54,0x0c,0x0a,0x9f,0x88,0x90,0x3f,0x29,0xb5,0xa4,0x2d,0x0f,0x06,0x0d +,0x8d,0x8c,0x97,0x18,0xfe,0xa4,0x2e,0x0b,0x0e,0x2e,0x94,0x89,0x96,0x37,0x1a,0xab,0xa7,0x98,0x2e,0x4f,0xd1,0x4c,0x0b,0x09,0x19,0x99,0x88,0x8f,0xdd,0x0f,0x45,0xba +,0x3d,0x0a,0x2d,0x98,0x86,0x99,0x56,0x45,0x3b,0xac,0xac,0x2b,0x1d,0x2d,0xb8,0x99,0x18,0x0e,0x11,0x96,0x9b,0x9d,0xcf,0x2b,0x22,0x12,0x24,0xb9,0x94,0x8f,0x8c,0x6b +,0x1b,0x16,0xb8,0x9c,0xc4,0x2c,0x9f,0xbf,0x24,0x0a,0x19,0x1c,0xb6,0x8e,0x39,0x4e,0x16,0x95,0xa1,0x39,0x11,0x24,0xa1,0x94,0x92,0xad,0x20,0x0f,0xb0,0x8f,0x99,0x55 +,0x9c,0xb4,0x1f,0x0d,0x1b,0x0d,0xac,0x98,0x92,0x99,0x19,0xcb,0x18,0x29,0x16,0xa9,0x97,0xb5,0x46,0xed,0x9d,0xbb,0x4c,0xcb,0xb9,0xb2,0x4c,0x2f,0x1c,0x0c,0x18,0x29 +,0x8b,0x9c,0xcd,0x2e,0xcd,0xda,0x1a,0x21,0x15,0xa7,0x91,0x88,0xa1,0x20,0x2f,0xf1,0xaf,0xaa,0xbb,0xc1,0x24,0x1f,0x19,0x4b,0x16,0x40,0x89,0xd5,0x3d,0x26,0x99,0xdc +,0x1e,0x19,0xc0,0x9a,0xa2,0x98,0xae,0x3d,0x2c,0x6e,0x37,0x46,0x3d,0x92,0x95,0x2b,0x0a,0x15,0x0f,0xbf,0xa4,0xae,0x9e,0x2b,0xa7,0x2b,0x1e,0x1a,0xad,0x95,0xad,0x5a +,0xbc,0xaa,0xb8,0x2b,0xa0,0x96,0xb5,0xbf,0x21,0x19,0x0e,0x22,0x36,0x97,0x2c,0x34,0x97,0x9d,0xbd,0x18,0x28,0x13,0xbd,0x8f,0x9d,0xe6,0x27,0xac,0x96,0x6b,0x21,0x32 +,0xb8,0x2c,0x28,0x24,0x28,0x12,0x33,0x8e,0xa7,0xa6,0x5e,0xa3,0x28,0x2c,0x3d,0x29,0xad,0xdc,0x98,0x95,0xca,0x3c,0xda,0xdd,0x3e,0x2f,0xd2,0xc6,0x1e,0x17,0xbe,0x50 +,0xe0,0x3b,0x72,0x50,0x4e,0x9a,0x45,0x26,0x15,0xa5,0x8c,0xab,0x5c,0x3c,0x4c,0x31,0xbe,0x8f,0xac,0x1e,0x28,0x48,0x1b,0x1a,0x31,0x4e,0xd0,0x23,0xa6,0xbf,0xa2,0xcd +,0x55,0xc7,0x1e,0xb2,0xaf,0x9f,0x6a,0xa6,0xb8,0x3d,0xcf,0xbb,0xa2,0xa8,0x2b,0x0a,0x23,0x1f,0x27,0x9f,0xb7,0x54,0x3d,0xa2,0x97,0x3e,0x21,0x2c,0x59,0x4a,0xa7,0x92 +,0xb1,0x25,0x47,0xaa,0xbf,0xa8,0xae,0x38,0x12,0x10,0xd1,0xb1,0x3c,0x2f,0xa9,0xae,0x2f,0x53,0xb7,0x49,0x1c,0x2d,0x9c,0xa3,0x5e,0xa9,0x9f,0xc6,0x44,0x3d,0xd2,0x38 +,0xd8,0xa2,0x53,0x18,0x16,0xd1,0x2e,0x47,0xf5,0x30,0x32,0x2b,0xaf,0xae,0xdc,0x3e,0xa9,0x99,0x99,0xad,0xb7,0x2f,0x1c,0xa4,0x9b,0x9d,0x9e,0x39,0x2b,0x26,0x19,0x15 +,0x22,0x3d,0x24,0xac,0x9d,0xaa,0x28,0x19,0x3d,0xb7,0xa9,0x9b,0x9b,0x28,0x1e,0xd4,0x9f,0xd8,0xcb,0x95,0xba,0x29,0x20,0x35,0x28,0x1e,0x37,0xd3,0xa5,0xcd,0x64,0x24 +,0x29,0x34,0x73,0x48,0x27,0x94,0x99,0xac,0x2d,0x2e,0xa9,0xe4,0xab,0xa1,0x9f,0xbf,0x1f,0x2a,0x2e,0x3a,0x53,0x35,0x2e,0x48,0x4e,0x3d,0x5e,0x22,0x28,0x4e,0x98,0x8f +,0xa1,0x4d,0x11,0x17,0xd7,0x9b,0x9d,0xa1,0xa3,0xb9,0x3b,0x25,0x2c,0xc3,0x3a,0x38,0x4f,0x23,0x21,0x2d,0x5e,0xd7,0x2c,0x2c,0x9d,0xa2,0xb8,0x2c,0x23,0x4c,0x4b,0x96 +,0x90,0x9f,0xb2,0xbd,0x58,0x2d,0x2d,0xc6,0xe1,0x28,0xa9,0xb9,0x2b,0x1b,0x17,0x22,0x16,0xce,0x9e,0xa5,0xca,0x16,0x29,0xcb,0x9c,0x9a,0xad,0xb5,0x9f,0xa7,0xad,0x35 +,0x21,0x9f,0xad,0xa9,0xb9,0x21,0x24,0x2e,0x24,0x1e,0x29,0xb1,0x9e,0xad,0x31,0x0f,0x17,0xda,0xa2,0xaa,0xae,0xad,0x32,0x4f,0xb8,0xa4,0x9d,0xcc,0x4d,0xe1,0x1f,0xec +,0xa2,0x32,0x26,0x24,0xbc,0xa8,0x98,0xa9,0x14,0x0b,0x1c,0xa3,0x99,0xa9,0xd2,0xba,0x2b,0x27,0xc1,0xbb,0xd3,0x65,0x2e,0x36,0xc4,0xb2,0x61,0xc9,0xfb,0x3a,0xc6,0x9f +,0x9f,0xd0,0x1c,0x13,0x2a,0xaf,0x93,0xa8,0xda,0x3f,0x35,0xb7,0x34,0xde,0xa2,0xbd,0xb4,0x28,0x1b,0xe9,0xc3,0x4e,0x33,0x26,0xb3,0x98,0xad,0x2c,0x1b,0x38,0x4f,0x9f +,0x9a,0xa4,0x44,0x1d,0x29,0x2e,0x47,0xcb,0x9f,0xcd,0x4a,0xc5,0xbb,0x6d,0x2e,0x52,0xe3,0xbd,0xad,0xac,0xbf,0x16,0x13,0x68,0xad,0xb1,0xd5,0xc9,0x6f,0x3a,0x2e,0x41 +,0xab,0xa2,0xb8,0xcd,0x3f,0x54,0xb3,0xad,0xaf,0x1c,0x2b,0xb9,0x9c,0x98,0x32,0x24,0x0e,0x1c,0xa4,0x9f,0x9d,0x4c,0x2e,0x20,0x45,0xdc,0xcb,0x9c,0xba,0xc0,0x2f,0x21 +,0x2c,0xbc,0xc7,0x35,0x2a,0x4b,0x97,0x9f,0x25,0x24,0x1e,0x33,0x9d,0x9f,0xad,0x56,0x29,0x2c,0xb0,0x42,0xa9,0xa8,0x58,0x20,0x27,0xfe,0x6d,0xb4,0x45,0x32,0x64,0xae +,0xbc,0xaf,0x23,0x1a,0x32,0xb2,0xa4,0x9b,0xa7,0x68,0x49,0x2f,0xc4,0xde,0xb4,0xb9,0x29,0x25,0x35,0xb6,0xae,0xae,0x2f,0x17,0x55,0x9e,0xa1,0xb2,0x1d,0x18,0x39,0xa9 +,0x92,0xa7,0x19,0x22,0xc0,0xbb,0xa0,0xb7,0xe3,0x3d,0x29,0x5a,0xa8,0x58,0x24,0x2f,0x22,0x2d,0xa5,0x9d,0xbf,0x3f,0x28,0x3e,0xac,0x95,0xa9,0xc7,0x2d,0x26,0xb3,0xb9 +,0xcd,0x23,0x44,0x64,0x25,0x1d,0xbe,0x9b,0xcf,0x35,0x1e,0x30,0x98,0x9b,0xc2,0x2f,0x23,0x28,0xbb,0xb0,0xc7,0xb8,0x2f,0xbb,0xc8,0xb6,0xad,0xdf,0x2a,0x23,0xaf,0xcb +,0xa0,0xaa,0x24,0x1e,0x2e,0xae,0xac,0xd8,0x34,0x29,0x1e,0x35,0x9f,0x9b,0xb5,0x5e,0x3d,0x2f,0x30,0xbf,0x9e,0xb3,0xc6,0x45,0x2e,0x2a,0x35,0xf5,0xec,0x28,0x2e,0xa5 +,0x98,0xab,0x20,0x28,0x2b,0xa9,0xac,0x3a,0x1a,0xe3,0x61,0x4f,0xc2,0xb7,0xa6,0x5c,0x56,0x19,0xad,0x95,0x97,0x28,0xe2,0xcd,0x28,0xcd,0x42,0x2d,0xf4,0xbf,0x5a,0x3d +,0x1b,0x1f,0x3e,0x92,0xac,0xc2,0x2c,0xb5,0x9f,0x34,0x1c,0x1a,0xa4,0x95,0x9f,0xca,0x36,0x1a,0x25,0x2d,0xfd,0xa8,0xd4,0x2c,0x2d,0x97,0xa1,0x4d,0x2a,0x21,0xa8,0x31 +,0x24,0xa9,0x9d,0x37,0x0d,0x13,0x93,0x8c,0x1f,0x25,0x8e,0x94,0xcb,0x0e,0x0b,0xc9,0x8b,0x89,0x50,0x1b,0x0f,0x9f,0x8f,0x11,0x20,0xa0,0xb8,0x12,0x38,0x1b,0x1e,0x20 +,0xcb,0x83,0x9a,0x5b,0x0a,0x2e,0x2c,0x14,0xa0,0x8a,0x9d,0x8d,0x90,0xcc,0x1f,0x12,0xa5,0x3d,0x25,0x15,0xbf,0x27,0x03,0x17,0x99,0x3f,0x9c,0x8e,0x96,0x94,0x9a,0x95 +,0xb2,0x0b,0x04,0x3b,0x82,0xa0,0x0f,0xa1,0xb3,0x8e,0xbd,0x12,0x0f,0x22,0x34,0x92,0x36,0x07,0x08,0x76,0x8b,0x27,0xa8,0x3c,0xad,0x9a,0x8f,0x50,0x4d,0xad,0xa6,0x97 +,0x3e,0x23,0xa8,0xab,0x0a,0x0c,0xb7,0x99,0x43,0x0c,0x0c,0xac,0xc6,0x9f,0x95,0x9e,0x1c,0xaa,0x8b,0x27,0x11,0x18,0x9a,0x8c,0xa7,0x98,0xa4,0x24,0x5a,0xd2,0xce,0x0b +,0x0c,0x9b,0x9a,0x0f,0x0b,0x15,0x18,0xa5,0x88,0x85,0x8d,0x45,0x2b,0xee,0x1e,0x08,0x1d,0x88,0x9d,0xa6,0xa5,0x2d,0x24,0xc8,0x3a,0x0c,0x31,0xa7,0x99,0x26,0x03,0x19 +,0x8a,0x8f,0x1e,0x9e,0x9d,0xaa,0xbc,0xfd,0x2b,0xb8,0xa1,0xa8,0xc5,0x13,0x22,0xb4,0x8b,0x16,0x0e,0x2b,0xa8,0xa5,0x21,0x1c,0x32,0x26,0xa5,0x8e,0x34,0x19,0x20,0xae +,0x5c,0xf5,0xbf,0x9d,0x22,0x9f,0x98,0x8f,0xa6,0x20,0x20,0x1f,0x0c,0x14,0x8e,0xc1,0x23,0x0c,0x1f,0x26,0xbf,0x91,0x8c,0x8c,0xb5,0xa2,0xa0,0x0f,0x13,0x1d,0x98,0xad +,0x98,0xa4,0xcf,0x9f,0x23,0xcb,0x0c,0x72,0x9e,0x9d,0x2a,0x02,0x13,0xb0,0x9a,0x9c,0xad,0x98,0x8e,0x51,0x0f,0x1e,0x96,0x92,0x94,0x64,0x19,0x8e,0x99,0x91,0x29,0x1d +,0x97,0x9c,0xe4,0x1a,0x95,0xee,0xa7,0xab,0x8f,0x92,0xdc,0xac,0xbf,0x29,0x1e,0x1c,0x10,0x13,0x10,0x3d,0x27,0x17,0x04,0x01,0x03,0x00,0x0e,0x0b,0x0c,0x0c,0x04,0x08 +,0x0b,0x0f,0x23,0xb6,0x9b,0x9c,0x9f,0xab,0x54,0x2a,0xaa,0x8c,0x8c,0x8b,0x85,0x92,0x8d,0x8e,0x9f,0x8e,0xb9,0x8a,0x94,0x9d,0x9b,0xab,0x8b,0x9b,0x8a,0x89,0x87,0x87 +,0x8d,0x90,0x9b,0xcc,0x96,0xb1,0xbe,0x4e,0x9f,0x8d,0x1e,0x2c,0x18,0x3e,0xbe,0x1b,0x15,0x0f,0xed,0x1f,0x12,0x1a,0x0c,0x24,0x14,0x27,0x0d,0x24,0xdf,0x12,0x11,0x0c +,0xa9,0x97,0x9f,0x19,0x04,0x04,0x09,0x1d,0x9a,0x1f,0x0e,0x16,0x17,0x1d,0x18,0x2a,0x9b,0x94,0x96,0x97,0x3e,0x2b,0xc6,0x1d,0x2a,0x32,0xa7,0x8a,0xbf,0xaf,0x58,0x3a +,0x6a,0xce,0x9a,0x21,0x0c,0x11,0x39,0xce,0x2e,0x9c,0x8f,0x94,0x98,0xac,0xa0,0x9a,0xab,0x9c,0x9e,0x8c,0x85,0x80,0x84,0x87,0x8b,0x8b,0x84,0x8b,0x8c,0x93,0x87,0x89 +,0x8d,0x97,0xa9,0x42,0xbc,0x9a,0x9a,0x19,0x17,0x16,0x0e,0x0a,0x02,0x19,0x10,0x0a,0x02,0x01,0x00,0x06,0x04,0x09,0x03,0x06,0x0b,0x05,0x03,0x03,0x04,0x0b,0x26,0xd9 +,0xa1,0x2d,0x1c,0x0f,0x1d,0x1b,0xa5,0xa6,0x98,0x89,0x9a,0x91,0x98,0xa7,0x9e,0x98,0x9a,0xb3,0x43,0xaa,0x9a,0x8a,0x87,0x87,0x8b,0x8c,0x84,0x88,0x87,0x99,0xae,0x9f +,0xa7,0x8f,0x8e,0x8f,0x9c,0x3f,0x9e,0x8f,0xc4,0x3d,0x12,0xa5,0x9d,0xc6,0x2a,0x0e,0x26,0x1c,0xb7,0x54,0x1e,0x2c,0x3c,0x45,0x1d,0x19,0x1e,0x34,0x46,0x3e,0x0e,0x0b +,0x09,0x0f,0x1f,0x1b,0x15,0x0c,0x15,0x0d,0x1f,0x1c,0x1f,0x1d,0xc4,0xb8,0x9a,0xa4,0x3b,0x12,0x09,0x1e,0x4b,0x90,0x9f,0x35,0x0e,0x2e,0x37,0x3b,0x29,0x1a,0x0d,0x11 +,0x1b,0x25,0xaf,0x38,0x98,0xa0,0xa2,0x92,0x9e,0x8c,0x8a,0x8d,0x8d,0x91,0x91,0x8e,0x85,0x85,0x82,0x81,0x84,0x84,0x86,0x87,0x8b,0x8e,0x8b,0x87,0x9e,0x97,0x40,0x3a +,0x96,0x9f,0x93,0x1c,0x12,0x03,0x03,0x0a,0x12,0x1a,0x0a,0x03,0x01,0x00,0x06,0x0c,0x01,0x05,0x00,0x09,0x04,0x05,0x07,0x0c,0x2c,0x2f,0x25,0x18,0x1d,0x22,0xb1,0x73 +,0x41,0x25,0x47,0x93,0x8c,0x90,0x93,0xa2,0x98,0x9c,0xbc,0xae,0xb0,0x9c,0x94,0x88,0x8a,0x8e,0x8f,0x8c,0x87,0x84,0x85,0x8c,0xc7,0xaf,0x8d,0x8e,0x8a,0x8d,0x9a,0x4c +,0x9a,0x97,0x9c,0xa0,0xba,0x7c,0xc4,0xae,0x1f,0x14,0x10,0x22,0x2a,0x9c,0xac,0x1b,0x1b,0xd2,0x2f,0x1c,0x10,0x19,0x37,0x2c,0x26,0x0d,0x0d,0x08,0x17,0x2c,0x1e,0x08 +,0x06,0x08,0x19,0x0d,0x19,0x12,0x12,0x59,0x25,0xae,0x2e,0x1e,0x21,0x37,0x1f,0x25,0x28,0x2f,0x1d,0xaf,0x92,0xa4,0x1b,0x05,0x0b,0x0f,0xc6,0xac,0xc2,0x31,0x55,0x9d +,0x8e,0x89,0x8d,0x8a,0x89,0x93,0x8f,0x89,0x8a,0x84,0x80,0x80,0x83,0x8a,0x8a,0x82,0x80,0x82,0x88,0x8e,0x93,0x9d,0xa6,0x99,0xc4,0x27,0x21,0xaf,0xca,0x0c,0x0c,0x08 +,0x0c,0x10,0x1c,0x0d,0x02,0x02,0x02,0x06,0x09,0x07,0x03,0x03,0x03,0x0c,0x0c,0x08,0x05,0x06,0x09,0x0c,0x1c,0x5b,0xc5,0xe5,0xae,0xa3,0x3e,0x21,0x2d,0xa4,0x8d,0x97 +,0x98,0x91,0x93,0x9a,0xa3,0xa7,0x54,0xc5,0x99,0x8f,0x8e,0x92,0x8f,0x89,0x88,0x89,0x88,0x87,0x93,0xab,0x9c,0x8e,0x8d,0x9d,0x9d,0x96,0x99,0x93,0x97,0x9a,0xca,0xb5 +,0xa8,0xb9,0x3b,0x18,0x1b,0x24,0x76,0xa8,0xaf,0x1c,0x14,0x1f,0xd3,0xbf,0x3a,0x2d,0x1e,0x1a,0x13,0x0e,0x0b,0x11,0x15,0x19,0x1f,0x15,0x16,0x10,0x14,0x14,0x14,0x13 +,0x04,0x09,0x2b,0x9f,0x9d,0xd9,0xca,0x2c,0x24,0x1c,0x11,0x29,0x34,0xb4,0xa8,0xa8,0x20,0x0b,0x11,0x1d,0x2b,0x29,0x35,0x27,0x1d,0xae,0x89,0x86,0x89,0x92,0x98,0x91 +,0x8c,0x89,0x89,0x89,0x89,0x85,0x81,0x81,0x80,0x81,0x84,0x88,0x86,0x8b,0x9c,0xa4,0x9c,0x93,0x98,0xb2,0x3b,0x39,0x38,0x1b,0x0b,0x07,0x04,0x07,0x11,0x18,0x0c,0x05 +,0x04,0x04,0x06,0x06,0x02,0x02,0x03,0x0a,0x13,0x16,0x0b,0x06,0x0a,0x0a,0x0c,0x10,0x1e,0x24,0x1d,0xc4,0x89,0x8d,0xa2,0x5c,0xcd,0x9a,0x98,0x9a,0xbd,0xfa,0xab,0x97 +,0x90,0x8f,0x8f,0x93,0x9e,0xac,0x96,0x93,0x93,0x8c,0x87,0x87,0x8a,0x8d,0x93,0x9b,0x91,0x94,0xa8,0xb2,0xb9,0x93,0x88,0x8b,0x9a,0xca,0xad,0x48,0x10,0x1b,0x2f,0x29 +,0x1f,0x3f,0x96,0x95,0x35,0x10,0x15,0x28,0x26,0x19,0x14,0x12,0x18,0xc2,0xa3,0x2e,0x11,0x0d,0x0d,0x0d,0x0c,0x09,0x09,0x10,0x26,0x29,0x18,0x14,0x1a,0x1b,0x20,0x1a +,0x1b,0x1d,0x19,0x2f,0xa2,0x95,0xa2,0xb2,0xca,0x1e,0x10,0x17,0x18,0x16,0x16,0x35,0x94,0x91,0xa3,0xb9,0xbb,0xc2,0xab,0x97,0x95,0x8e,0x86,0x81,0x80,0x82,0x84,0x89 +,0x88,0x87,0x84,0x83,0x85,0x89,0x87,0x82,0x82,0x87,0x96,0x9f,0xd2,0x28,0x1a,0x14,0x0c,0x13,0x18,0x1d,0x1f,0x0f,0x0a,0x03,0x02,0x07,0x0a,0x03,0x01,0x07,0x16,0x17 +,0x0c,0x06,0x02,0x04,0x0a,0x09,0x04,0x03,0x0a,0x2c,0xb7,0xd4,0x2e,0xf1,0xc3,0x3b,0xdf,0xab,0xae,0xb7,0x96,0x87,0x84,0x8b,0x9e,0xe8,0x57,0xc4,0xac,0x9d,0x98,0x9c +,0x8d,0x85,0x84,0x88,0x8b,0x97,0x9d,0x8d,0x90,0xa5,0xad,0x8e,0x88,0x8b,0x94,0x9c,0x98,0xa1,0xac,0xbb,0x2e,0x18,0x25,0x9f,0x9b,0xae,0x27,0x18,0x18,0x1f,0x38,0x20 +,0x10,0x12,0xc6,0x8f,0x9b,0x24,0x15,0x1c,0x22,0x15,0x08,0x07,0x09,0x10,0x2a,0xcc,0xbd,0x31,0x1b,0x0b,0x0f,0x0e,0x06,0x0a,0x0b,0x1e,0x9f,0x8f,0x51,0x22,0x3b,0x40 +,0xbd,0x18,0x0b,0x0c,0x1e,0xa7,0xa4,0x53,0x1c,0x37,0x4b,0x41,0x4c,0x1f,0x28,0x2d,0xa4,0x88,0x85,0x89,0x87,0x86,0x89,0x85,0x84,0x8c,0x98,0x8b,0x80,0x80,0x80,0x86 +,0x89,0x87,0x89,0x95,0x9d,0xad,0xc6,0xa5,0x9d,0xa4,0x1b,0x0f,0x0d,0x0c,0x0c,0x02,0x01,0x03,0x05,0x09,0x1c,0x1c,0x07,0x06,0x0d,0x0b,0x08,0x02,0x01,0x05,0x14,0x2b +,0x0f,0x06,0x07,0x0f,0x22,0x14,0x0b,0x19,0x30,0xcc,0x9c,0x8e,0x9b,0x9b,0x8f,0x95,0x9e,0xa1,0x5b,0x27,0x4e,0x98,0x86,0x84,0x95,0xa9,0x99,0x8d,0x8d,0xb9,0x2a,0xd5 +,0x8f,0x83,0x85,0x8e,0x92,0x8a,0x87,0x98,0xad,0x1f,0xb7,0x8d,0x8e,0x8f,0xa9,0xcf,0x4a,0x99,0x99,0x37,0x0b,0x05,0x0a,0x31,0xa9,0xaa,0x16,0x19,0x34,0x2d,0xa9,0x1a +,0x0c,0x0f,0x23,0x1c,0x2e,0x2d,0x12,0x14,0xbe,0x2a,0x15,0x0d,0x0c,0x12,0x1b,0x9f,0xdb,0xaf,0x2c,0x33,0xb2,0x9f,0x3e,0x11,0x16,0x32,0x95,0x94,0x9e,0xb6,0x8f,0x91 +,0xa9,0x3d,0x1c,0x13,0x2c,0x9c,0xa0,0xba,0x59,0xac,0xb8,0xa9,0xa4,0x48,0x19,0x12,0x27,0xac,0x8d,0x9c,0x2b,0xea,0xa1,0x9b,0xa6,0x1b,0x0f,0x2e,0xa7,0x9f,0xcc,0x55 +,0xbf,0x98,0xa6,0x33,0x13,0x14,0x20,0x1d,0xa8,0xac,0x48,0xc6,0x97,0x9d,0x92,0x9a,0x2c,0x1f,0x37,0xad,0x9c,0x98,0xb7,0x9e,0x96,0x8f,0xda,0x14,0x13,0x12,0x33,0xa6 +,0xa7,0x4c,0xb9,0x97,0x9c,0x9e,0x9f,0x34,0x2f,0x2e,0x6e,0x9b,0x95,0xa6,0x30,0x2c,0x4b,0x3e,0x28,0x0f,0x0d,0x1c,0x3b,0x21,0x0f,0x26,0xa9,0x91,0xa3,0x0f,0x03,0x06 +,0x19,0x1b,0x26,0x25,0x25,0x5b,0xbc,0x3e,0x1e,0x17,0x06,0x05,0x16,0xc7,0xca,0x21,0x16,0xed,0x8e,0x8f,0xac,0x20,0x46,0xa8,0x93,0x87,0x8a,0x8e,0x8b,0x82,0x85,0x87 +,0x9c,0x50,0xa7,0xa2,0x8c,0x8c,0x8f,0x9f,0x95,0x8b,0x8b,0x9a,0x25,0x2f,0x2b,0xae,0xa0,0xb9,0xae,0x9a,0xac,0xab,0x50,0x17,0x10,0x17,0x27,0x17,0x15,0x11,0x0e,0x2e +,0xaf,0x6c,0x29,0x14,0x09,0x09,0x18,0x37,0x72,0x34,0x22,0x24,0x3f,0x1f,0x0c,0x0d,0x13,0x18,0x2f,0x1e,0x19,0x1c,0xaa,0x94,0x72,0x1e,0x14,0x1f,0x27,0x49,0xb9,0xad +,0xad,0xb7,0x36,0xe2,0xcb,0x26,0x16,0x1b,0xbe,0xa8,0xa5,0xa9,0xa5,0x8d,0x84,0x89,0x8a,0x9d,0xb2,0x95,0x8f,0x8a,0x87,0x8c,0x90,0x8e,0x8a,0x8c,0x97,0x99,0x97,0x93 +,0x8f,0x97,0xa3,0x9f,0x95,0x98,0xad,0x10,0x03,0x01,0x04,0x12,0x1e,0x1a,0x06,0x07,0x06,0x07,0x0a,0x04,0x04,0x02,0x06,0x07,0x0e,0x12,0x13,0x16,0x17,0x15,0x0e,0x0e +,0x0c,0x0c,0x09,0x1f,0xab,0xb2,0xbc,0xb9,0x99,0x8b,0x8d,0x8a,0x8c,0x8d,0x85,0x8a,0x89,0x85,0x82,0x80,0x82,0x81,0x82,0x84,0x88,0x8b,0x87,0x85,0x86,0x89,0x98,0xa1 +,0xa5,0xb8,0x27,0x10,0x0f,0x0e,0x2f,0xa0,0xa7,0x9f,0xa9,0x38,0x2a,0x1f,0x19,0x23,0x1b,0x14,0x2a,0x2b,0x1d,0x25,0x1b,0x12,0x0e,0x0c,0x08,0x06,0x05,0x08,0x0d,0x0f +,0x0f,0x09,0x08,0x0f,0x3c,0xc9,0x3d,0x2e,0x3c,0xc0,0x9e,0xb7,0x3a,0x29,0x2b,0xac,0xa3,0x95,0xa4,0xd5,0x3c,0x57,0xa3,0xa7,0xab,0x2a,0x22,0x1d,0x13,0x18,0x19,0x1b +,0x2c,0x8e,0x93,0x9a,0x93,0xac,0x94,0x94,0x9e,0x91,0x88,0x84,0x82,0x82,0x82,0x81,0x81,0x82,0x82,0x83,0x86,0x8d,0x8f,0x8e,0x92,0xaf,0x23,0x13,0x0e,0xae,0xcc,0x15 +,0x0c,0x01,0x02,0x03,0x08,0x04,0x03,0x03,0x02,0x07,0x06,0x09,0x07,0x0d,0x0d,0x0d,0x07,0x04,0x08,0x0b,0x12,0x11,0x0e,0x07,0x07,0x0c,0x97,0x8f,0x8f,0x9a,0x35,0xad +,0xa4,0x94,0x9d,0x90,0x91,0x8a,0x85,0x8c,0x8d,0x90,0x88,0x89,0x8e,0x94,0x9d,0xa6,0xa7,0x98,0x95,0x9e,0xce,0x1f,0x9c,0x80,0x87,0x8f,0xce,0x41,0xa1,0x9c,0xbc,0x22 +,0xcf,0xdf,0x9f,0xa0,0x62,0x42,0x2e,0xa7,0xad,0xb4,0x1e,0x17,0x10,0x12,0x2a,0x16,0x14,0x0d,0x0a,0xb0,0x89,0xab,0xdb,0x1c,0x2c,0xaa,0xb2,0x20,0x0c,0x1a,0x1b,0xa9 +,0xa2,0x4f,0x1d,0x1a,0x6d,0xdf,0x35,0x0f,0x07,0x07,0x0e,0x16,0x10,0x09,0x06,0x04,0x38,0x8b,0xa0,0xdc,0x10,0x14,0xcf,0x93,0x9b,0xd4,0x9b,0x8e,0x82,0x81,0x83,0x84 +,0x82,0x81,0x82,0x83,0x88,0x87,0x87,0x86,0x88,0x8e,0xa8,0x29,0x10,0xa4,0x83,0xa9,0x1f,0x0a,0x09,0x11,0x15,0x0a,0x01,0x06,0x07,0x0a,0x0a,0x06,0x06,0x08,0x14,0x14 +,0x0c,0x05,0x03,0x04,0x0b,0x1c,0x10,0x09,0x05,0x04,0x2d,0x84,0x92,0x9a,0xbb,0x27,0x98,0x95,0x9f,0x2c,0xbf,0x99,0x8b,0x8b,0x9e,0xa6,0xae,0x8e,0x8d,0x94,0xa3,0xae +,0xb5,0xae,0x93,0xac,0xe0,0xca,0x26,0x98,0x81,0x8a,0x89,0x8f,0x9c,0x8e,0x8f,0x98,0x58,0xbd,0x9c,0x91,0x95,0xa8,0xdc,0x28,0x9d,0xa4,0x48,0x1c,0x0e,0x0e,0x0f,0x10 +,0x0d,0x0f,0x0d,0x05,0x20,0x8e,0xb7,0x34,0x0f,0x0a,0x22,0x27,0x13,0x06,0x0f,0x1e,0x2f,0x21,0x20,0x16,0x0e,0x1e,0x24,0x27,0x1c,0x15,0x10,0x1b,0x25,0x1b,0x10,0x0f +,0x06,0x1b,0x89,0x99,0x9f,0x34,0x2e,0x99,0x97,0x97,0xdb,0xa4,0x8e,0x87,0x84,0x84,0x86,0x86,0x80,0x80,0x81,0x81,0x84,0x86,0x83,0x86,0x8c,0x93,0x9d,0x37,0x9f,0x83 +,0x97,0x33,0x0d,0x07,0x0e,0x0d,0x08,0x01,0x02,0x04,0x09,0x0c,0x07,0x03,0x04,0x0b,0x0e,0x0c,0x0c,0x09,0x08,0x11,0x0f,0x0e,0x0b,0x08,0x02,0x0e,0x91,0x98,0x9e,0xac +,0xca,0x98,0x91,0x9d,0x28,0x65,0x9c,0x94,0x8f,0x9a,0x9c,0x94,0x8a,0x8a,0x8d,0x9c,0x5c,0xc4,0xab,0xaa,0xb9,0xb1,0x6c,0x20,0xa2,0x81,0x87,0x8f,0x97,0xa8,0x98,0x9c +,0xa3,0x2f,0x4a,0xa5,0x99,0x8e,0xb7,0x25,0x19,0xd4,0x9a,0xa9,0x2d,0x13,0x19,0x2e,0x2e,0x26,0x19,0x0c,0x04,0x08,0x94,0x90,0x7d,0x29,0x1d,0xaf,0xb1,0xf9,0x0f,0x0d +,0x20,0x27,0xd3,0x27,0x1f,0x1a,0x29,0xa5,0x58,0x1d,0x11,0x12,0x1b,0x1c,0x0e,0x0c,0x11,0x09,0x10,0x96,0x97,0xbe,0x33,0x22,0xbe,0xa6,0xa2,0x4b,0x47,0x99,0x8a,0x85 +,0x87,0x8b,0x8f,0x87,0x81,0x81,0x81,0x82,0x84,0x83,0x83,0x87,0x8f,0xb2,0x22,0x53,0x88,0x8e,0xc0,0x2b,0x1c,0x20,0x14,0x0c,0x04,0x01,0x03,0x06,0x07,0x05,0x06,0x03 +,0x0a,0x17,0x16,0x0d,0x05,0x05,0x06,0x09,0x0b,0x0b,0x0b,0x06,0x28,0x8e,0x9a,0xac,0x42,0x3a,0xb5,0xa8,0x99,0xb1,0xbd,0x9a,0x8c,0x8b,0x9b,0xbf,0xbb,0x97,0x8d,0x97 +,0x9d,0xa0,0x9d,0x9b,0x93,0x93,0xac,0x27,0x1c,0x8e,0x83,0x8d,0x9b,0x99,0x8a,0x8d,0x8f,0x9e,0x2d,0x35,0x9d,0x8f,0xa6,0xdc,0x2a,0x29,0x98,0x9b,0xc8,0x2f,0x26,0x1a +,0x18,0x1c,0x15,0x15,0x09,0x0f,0x96,0x99,0x2a,0x1a,0x1d,0x33,0x41,0x3f,0x11,0x08,0x18,0xb5,0xd5,0x19,0x0f,0x0a,0x10,0x2f,0x27,0x17,0x0e,0x13,0x19,0x1c,0x27,0x10 +,0x0a,0x02,0x0f,0x99,0xaf,0x2e,0x1f,0x3a,0xaa,0x9b,0x95,0x43,0x26,0xb3,0x8c,0x89,0x8e,0x8b,0x8a,0x83,0x80,0x80,0x81,0x84,0x83,0x86,0x83,0x86,0x8d,0x9f,0xa9,0x85 +,0x80,0x8c,0xcd,0x2c,0x4c,0x21,0x25,0x0c,0x01,0x02,0x0b,0x17,0x0a,0x03,0x02,0x02,0x08,0x0e,0x08,0x02,0x06,0x09,0x0c,0x11,0x0b,0x0a,0x04,0x06,0xa8,0x9d,0x24,0x14 +,0x21,0x9d,0x8d,0x8a,0xa6,0x23,0xfc,0x92,0x89,0x97,0xac,0x4b,0xaa,0x89,0x88,0x91,0xa9,0x9b,0x9c,0x9e,0xa7,0x43,0x46,0x1f,0x96,0x80,0x87,0x93,0xac,0x8f,0x89,0x87 +,0x8e,0x2d,0x2d,0x9b,0x87,0x95,0x3c,0x2a,0x22,0x3a,0xb4,0xaf,0x19,0x0b,0x1a,0x29,0xd7,0x37,0x16,0x09,0x08,0xa4,0x94,0xcc,0x18,0x14,0x2a,0x4d,0x94,0xba,0x10,0x17 +,0x29,0x45,0x11,0x08,0x09,0x0b,0xd5,0xaa,0x27,0x0e,0x0d,0x1a,0x1a,0x1f,0x12,0x07,0x01,0x19,0x95,0x9c,0xce,0x17,0x3e,0xb2,0xa4,0x9a,0x17,0x08,0x1b,0x8c,0x84,0x9d +,0xaf,0xb0,0x8f,0x82,0x82,0x87,0x93,0x8a,0x84,0x82,0x82,0x81,0x8c,0x94,0x82,0x80,0x85,0x95,0x56,0x70,0xbc,0x9a,0xb3,0x0c,0x07,0x0e,0x15,0x07,0x02,0x01,0x01,0x0a +,0x0d,0x05,0x01,0x04,0x0e,0x0d,0x0a,0x06,0x03,0x00,0x0c,0x94,0xa0,0x2a,0x11,0x1d,0xc2,0x9a,0x8f,0x24,0x0c,0x2e,0x8f,0x93,0xdc,0xcd,0xc6,0xad,0x90,0x97,0xad,0x2e +,0x5c,0x9d,0x92,0x9d,0xae,0xca,0xbd,0x84,0x82,0x96,0xda,0xa9,0x8d,0x8d,0x89,0x97,0x3c,0x9f,0x8c,0x87,0x90,0xba,0x57,0xc5,0x9e,0x9f,0xbe,0x2c,0x3d,0x9d,0xa5,0x25 +,0x18,0x14,0x06,0x1e,0x8a,0xa0,0x1c,0x21,0xc1,0xae,0x4e,0xbc,0x1a,0x0b,0x24,0xa4,0x29,0x0f,0x0e,0x0e,0x19,0x3f,0xe2,0x19,0x06,0x08,0x0e,0x0d,0x17,0x0e,0x08,0x0f +,0x8f,0x92,0x32,0x1b,0x30,0x88,0x81,0x3b,0x00,0x8c,0x85,0x8b,0x84,0x13,0x26,0x2b,0xc8,0x55,0x3b,0x12,0x00,0x16,0x02,0x05,0x06,0x00,0x07,0x00,0x15,0xab,0x0d,0x0b +,0x10,0x1d,0x1e,0x17,0x47,0x1c,0x35,0x91,0x86,0x9b,0xbb,0x8b,0x80,0x82,0x8b,0x86,0x81,0x81,0x81,0x83,0x85,0x88,0x88,0x8a,0x83,0x80,0x81,0x83,0x85,0x82,0x84,0x89 +,0x8d,0x9b,0x9f,0x8f,0x8d,0x99,0x38,0x5c,0x2d,0x17,0x2e,0x0f,0x07,0x07,0x04,0x05,0x00,0x03,0x00,0x02,0x00,0x0c,0x1a,0x02,0x01,0x01,0x03,0x00,0x01,0x02,0x00,0x01 +,0x06,0x05,0x00,0x01,0x07,0x05,0x07,0x07,0x06,0x05,0x0a,0x1b,0x08,0x0d,0x13,0x1b,0x27,0xa0,0x80,0x87,0x90,0x85,0x81,0x82,0x84,0x82,0x85,0x86,0x80,0x81,0x80,0x82 +,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x80,0x83,0x81,0x82,0x80,0x8a,0x8d,0x80,0x80,0x82,0x85,0x81,0x80,0x84,0x84,0x88,0xa7,0x90,0x82,0x8e,0xae,0x97,0x94,0x49,0xca +,0x21,0x08,0x07,0x07,0x04,0x00,0x02,0x02,0x00,0x00,0x00,0x1c,0x16,0x01,0x01,0x01,0x03,0x02,0x00,0x00,0x00,0x05,0x06,0x01,0x01,0x06,0x06,0x02,0x05,0x02,0x01,0x03 +,0x04,0x03,0x02,0x06,0x03,0x04,0x01,0x08,0x91,0xb1,0x08,0x0d,0x25,0xcc,0x13,0x0c,0x09,0x2a,0x96,0xa3,0x5e,0xaa,0x86,0x8f,0xaf,0x9b,0xac,0xa0,0x96,0x93,0xa0,0x92 +,0x8a,0x9c,0x8d,0x94,0x8e,0x80,0x81,0x8a,0x89,0x80,0x82,0x8e,0x8f,0x8c,0x86,0x80,0x86,0x89,0x83,0x80,0x83,0x8a,0x89,0x8a,0x85,0x81,0x85,0x89,0x83,0x84,0x88,0x83 +,0x8c,0x8e,0x80,0x82,0xcf,0x97,0x81,0x99,0x08,0x15,0x2d,0x15,0x49,0x1b,0x2a,0xb5,0x99,0x76,0x39,0x3b,0x1e,0x3d,0xb4,0xaf,0xb2,0x93,0xa2,0xdb,0x8e,0x95,0xaf,0x87 +,0x80,0x9c,0x96,0x86,0x8b,0xa0,0xa0,0x9a,0xa7,0x85,0x9b,0xdd,0x87,0x85,0xb9,0x1b,0x22,0x0c,0x13,0x11,0x05,0x0b,0x0c,0x02,0x01,0x04,0x03,0x00,0x01,0x1a,0x08,0x00 +,0x03,0x00,0x01,0x00,0x00,0x00,0x04,0x02,0x00,0x06,0x07,0x03,0x01,0x00,0x00,0x00,0x01,0x00,0x02,0x01,0x02,0x00,0x01,0x00,0x01,0x00,0x0e,0xa6,0x00,0x06,0x0f,0x0d +,0x0c,0x04,0x04,0x10,0x9f,0x0c,0x4a,0x91,0x9e,0xa3,0x1d,0xcd,0x93,0x90,0xf3,0x8d,0x82,0x86,0x8f,0xa3,0x84,0x87,0x8c,0x87,0x80,0x83,0x89,0x80,0x80,0x80,0x80,0x81 +,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x81,0x80,0x80,0x85,0x94,0x88,0x97,0xaf,0x1a,0x86,0x8b,0x08,0xad,0xbd,0xa0,0x0d,0x01,0x08,0xad,0x1a +,0x04,0x30,0x26,0x28,0x07,0x04,0x09,0x0b,0x01,0x05,0x14,0x0d,0x08,0x01,0x06,0x05,0x03,0x00,0x08,0x96,0x08,0x06,0x1b,0x12,0x0b,0x00,0x01,0x16,0x26,0x00,0x0f,0x27 +,0x2b,0x0e,0x04,0x09,0x11,0x05,0x05,0x12,0x20,0x16,0x07,0x06,0x13,0x0b,0x09,0x00,0x99,0x9a,0x08,0xbc,0xd9,0xb3,0x10,0x05,0x1b,0x9a,0x14,0x23,0x99,0x8d,0xc3,0x2f +,0x36,0xad,0x38,0x0e,0xb0,0x8e,0x9b,0x2d,0xaa,0x9b,0xa2,0x2f,0x29,0xb8,0x80,0xe8,0xa1,0x82,0x88,0xa6,0x16,0xd8,0x88,0x9a,0x31,0x89,0x86,0x8d,0x1e,0xc9,0xaa,0x43 +,0x1f,0xb4,0x8f,0x91,0x5d,0x9a,0x87,0x89,0x8f,0x90,0x8e,0x80,0x83,0x88,0x80,0x81,0x80,0x8a,0x8e,0x82,0x83,0x99,0x8b,0x8b,0x85,0x22,0x0b,0x10,0x07,0x03,0x01,0x03 +,0x0b,0x05,0x04,0x04,0x03,0x00,0x04,0x00,0x19,0x9d,0x00,0x1e,0x1a,0x2c,0x18,0x01,0x17,0xb0,0x11,0x2d,0xa3,0x8b,0x8f,0x1e,0x9c,0x9a,0xb1,0x44,0xa0,0x89,0x89,0x9e +,0x8d,0x8c,0x9c,0x91,0xad,0x93,0x80,0x99,0x8b,0x81,0x85,0x87,0xbc,0x9a,0x80,0x90,0x90,0x8c,0x86,0x86,0x3d,0x97,0x98,0x25,0x26,0x21,0xae,0x9a,0x2a,0xb3,0x2e,0x13 +,0x11,0x0e,0x06,0x95,0xb1,0x16,0x93,0x7d,0xca,0x16,0x0c,0x33,0x1d,0x19,0xaf,0x2a,0x97,0x41,0x1b,0x36,0x09,0x0e,0x14,0x0d,0x38,0x2b,0x33,0x1d,0x07,0x0d,0x0e,0x01 +,0x2b,0x94,0x0c,0x33,0x14,0x16,0x11,0x00,0x1f,0x22,0x0c,0x16,0x0e,0x9f,0xa7,0x2a,0x8f,0xae,0xa1,0x9d,0x8d,0x80,0x84,0x83,0x84,0x86,0x86,0x85,0x8f,0x8a,0x80,0x8f +,0x8a,0x8a,0x92,0xb1,0x06,0x12,0x21,0x08,0x09,0x06,0x1f,0x1e,0x01,0x0c,0x0b,0x00,0x04,0x03,0x0f,0x0e,0x09,0x20,0x0d,0x0b,0x08,0x05,0x06,0x9c,0xab,0x20,0x9e,0xf9 +,0xc7,0x14,0x1e,0xa5,0x6d,0x3b,0xb0,0x91,0x87,0x97,0xb6,0x96,0xbe,0x35,0xad,0x9f,0x92,0xb1,0x9e,0x98,0xcd,0x45,0x3b,0x27,0x86,0x8c,0xb4,0x8b,0x9d,0x99,0x4f,0x29 +,0x9c,0xb6,0xab,0xad,0xab,0x88,0xb4,0x37,0xa3,0x1c,0x23,0x18,0x16,0x2d,0x1d,0x68,0x1a,0x0f,0x11,0x12,0x04,0x2f,0x8f,0x23,0x71,0x36,0xa0,0x33,0x08,0x19,0x1c,0x19 +,0x15,0x2a,0x8d,0xb0,0x12,0x1e,0x14,0x0e,0x0d,0x11,0x1f,0x0d,0x1a,0x13,0x0e,0x0a,0x0e,0x09,0x1c,0x90,0x1a,0xf4,0x4e,0xc7,0xbc,0x24,0x9e,0x99,0x8f,0x88,0x85,0x80 +,0x83,0x84,0x81,0x82,0x84,0x84,0x82,0x82,0x8a,0x86,0x8b,0x9a,0x2a,0x2f,0x16,0x1d,0x90,0x0d,0x19,0x15,0x0c,0x0b,0x01,0x09,0x05,0x03,0x05,0x0c,0x4f,0x12,0x0e,0x19 +,0x0b,0x0c,0x06,0x0e,0x11,0x10,0x1f,0x1c,0x1d,0x0d,0x17,0x0e,0x35,0x87,0x3b,0x9e,0x99,0x9a,0xa4,0x22,0x9e,0xaf,0xab,0x98,0x8f,0x87,0x9c,0x9a,0x98,0xa5,0x97,0xa2 +,0x98,0xa7,0x9e,0x9b,0xa6,0x59,0x2d,0xb5,0x24,0x8e,0x84,0x9a,0x92,0xa8,0x97,0xbc,0x50,0xca,0x2c,0xb9,0xb9,0x93,0x9a,0xb0,0xbd,0x21,0x2a,0x37,0x2d,0x1e,0x0d,0x18 +,0x2d,0x32,0x19,0x1b,0x0e,0x1c,0x99,0x34,0xd7,0x3a,0xcf,0x27,0x1f,0xd8,0x17,0x15,0x1b,0x2b,0xac,0x21,0x12,0x12,0x0e,0x18,0x0f,0x1a,0x10,0x0a,0x09,0x14,0x14,0x09 +,0x06,0x33,0x92,0xa1,0x8b,0x89,0x84,0x8c,0x8f,0x82,0x82,0x86,0x85,0x82,0x80,0x80,0x81,0x83,0x83,0x88,0x91,0x98,0xbf,0x2d,0x10,0x0f,0x27,0x0c,0x02,0x18,0x10,0x0a +,0x0c,0x0c,0x0d,0x02,0x05,0x0e,0x19,0x13,0x05,0x0c,0x15,0x17,0x17,0x0f,0x19,0x11,0x16,0x26,0x1f,0x14,0x10,0x0f,0x1d,0x28,0x31,0x9a,0xbe,0x9c,0x92,0x8e,0x8c,0xab +,0xa1,0xae,0x9a,0x93,0xa1,0xa3,0xb4,0x8b,0x87,0x8f,0x8d,0x9b,0x9b,0x9f,0x5e,0xfa,0x2e,0x2d,0x30,0x34,0x8b,0x8c,0xa8,0xaf,0xa4,0x8b,0xac,0x38,0xcc,0xbf,0x9b,0xba +,0xac,0xad,0x24,0x1a,0x4b,0xa7,0x2f,0x16,0x15,0x2d,0x3c,0x26,0x19,0x16,0x0b,0x15,0x65,0x37,0xf6,0x18,0x23,0xb6,0xdc,0xbc,0x1e,0x2a,0x4b,0x1f,0x24,0x0e,0x0c,0x0b +,0x0f,0x2c,0x23,0x15,0x0d,0x0d,0x10,0x0e,0x0b,0x08,0x06,0x20,0xa2,0x94,0x96,0x97,0x8d,0x8b,0x85,0x82,0x82,0x83,0x83,0x81,0x80,0x81,0x82,0x86,0x84,0x87,0x8d,0x94 +,0xb1,0x43,0x22,0x1f,0x25,0x0f,0x05,0x04,0x0d,0x0f,0x09,0x03,0x02,0x07,0x07,0x0f,0x1c,0x1b,0x14,0x0e,0x1e,0x20,0x0e,0x0a,0x0f,0x2b,0x30,0x2e,0x69,0x29,0x1b,0x25 +,0xda,0xd1,0x1b,0x13,0x59,0x96,0x90,0x93,0x9d,0xa6,0x9b,0x98,0x8f,0x96,0xa8,0xa3,0x97,0x8b,0x8a,0x92,0x9f,0x9c,0x94,0x95,0x9f,0xcb,0x32,0xbb,0x9b,0x93,0x97,0xca +,0x46,0xa3,0x99,0x9c,0xd3,0x24,0x2d,0xca,0xa8,0xa8,0xc9,0xcd,0xa5,0xab,0xbf,0x2a,0x17,0x1b,0x3d,0x9e,0x9a,0xbe,0x1f,0x1f,0x46,0xaf,0x33,0x13,0x0e,0x0f,0x29,0xc7 +,0x65,0x27,0x17,0x1e,0x2e,0x1d,0x0d,0x08,0x0d,0x1d,0x2e,0x1e,0x18,0x0f,0x12,0x1e,0x1f,0x15,0x0a,0x0a,0x14,0x2f,0xbe,0xc0,0xbb,0x9c,0x8e,0x87,0x87,0x8c,0x8d,0x8b +,0x85,0x82,0x82,0x83,0x84,0x85,0x81,0x86,0x95,0xa2,0xd9,0xd3,0xa6,0xb4,0x2f,0x13,0x0e,0x13,0x0f,0x0a,0x04,0x02,0x02,0x09,0x18,0x15,0x0c,0x0c,0x19,0x1c,0x1b,0x0f +,0x0c,0x10,0x19,0x3e,0xcf,0x27,0x1d,0x28,0x4f,0xa7,0x32,0x18,0x1e,0x34,0xb1,0x9f,0xa1,0x9f,0xad,0xa8,0x94,0x94,0xae,0x3b,0xbe,0x9c,0x8e,0x93,0x9b,0x9f,0x9e,0x91 +,0x8d,0x9a,0x3c,0x2b,0xbb,0x96,0x93,0xa6,0xda,0xb3,0x9f,0x97,0x9a,0x33,0x25,0x28,0x3d,0xa5,0xb7,0x41,0x3d,0xb6,0x9b,0x9e,0x26,0x14,0x1b,0x27,0xb7,0xaa,0x32,0x27 +,0x24,0xc4,0xa1,0x2e,0x10,0x0f,0x1b,0x24,0x6a,0x50,0x34,0x3f,0x38,0xab,0xb9,0x1e,0x0f,0x13,0x2b,0xb4,0xa7,0x26,0x2a,0x4b,0xb7,0x9e,0x51,0x15,0x1a,0x1f,0xc4,0x9d +,0x37,0x29,0x3f,0xaf,0x9e,0xaa,0x1f,0x1c,0x27,0x4d,0xac,0xd5,0x31,0xd7,0xac,0x9c,0x94,0xb3,0x20,0x29,0xcd,0xa0,0x99,0xc1,0xad,0x9c,0x99,0x91,0x98,0x3d,0x24,0x62 +,0xac,0x95,0xa7,0x50,0xaa,0xa1,0x99,0x9e,0x2d,0x1d,0x2a,0x3f,0xb8,0xa8,0x32,0x20,0x2e,0x5d,0xba,0x1f,0x0a,0x0e,0x1b,0x20,0x2b,0x1a,0x10,0x1b,0x24,0x42,0x3a,0x15 +,0x0f,0x21,0x32,0x4f,0x37,0x15,0x2d,0xb4,0xa8,0x9a,0xb3,0x25,0x66,0xb9,0xa8,0x9a,0xb7,0xde,0x9f,0x94,0x95,0x99,0xcc,0xd2,0xa5,0x9f,0x95,0x99,0xac,0x9a,0x8f,0x91 +,0x91,0xaf,0x32,0xbe,0xba,0x9f,0x9b,0xb5,0xcb,0xa1,0x9d,0x9d,0xc5,0x15,0x1f,0x2b,0x2b,0x5f,0x25,0x18,0x20,0x2c,0x4d,0x3b,0x13,0x0f,0x1d,0x2e,0x37,0x2a,0x17,0x19 +,0x35,0x2b,0x37,0x2d,0x12,0x18,0x33,0x30,0x2d,0x1d,0x12,0x26,0x5c,0x5f,0x2d,0x12,0x11,0x1d,0x2f,0x35,0x2c,0x1c,0x2e,0xa9,0xa7,0xae,0x6a,0x25,0x3c,0xa3,0xa6,0xa7 +,0xb5,0xae,0x95,0x8e,0x8c,0x8f,0x9e,0x99,0x91,0x8f,0x8d,0x8f,0x99,0x94,0x8d,0x8d,0x93,0xac,0xdd,0xab,0x9c,0xac,0xb2,0xcd,0x48,0xc2,0xbe,0x27,0x18,0x0d,0x0e,0x28 +,0x1f,0x1b,0x18,0x0f,0x1b,0x24,0x1c,0x1a,0x11,0x0e,0x19,0x1d,0x17,0x1c,0x14,0x1a,0x37,0x4d,0x51,0x4c,0x27,0x2c,0xbf,0xc0,0xbc,0x3e,0x43,0xad,0x99,0xa2,0xa7,0xa8 +,0xc2,0x9b,0x99,0x9d,0x9c,0xa2,0xa7,0x95,0x96,0x9e,0xa4,0xfb,0xac,0x9c,0xa2,0xa9,0xac,0xb8,0xa4,0x9e,0xad,0xbd,0x35,0x2c,0xbc,0xa9,0xc9,0x37,0x36,0x6f,0xaf,0xb8 +,0x38,0x26,0x25,0x29,0x5b,0xd7,0x26,0x2d,0x1f,0x27,0xbd,0x2e,0x28,0x29,0x30,0xcb,0xbe,0x2f,0x27,0x2c,0x2c,0xc5,0xbe,0x47,0x26,0x23,0x30,0x58,0x39,0x24,0x33,0x3d +,0x3e,0xf0,0x4f,0x2a,0x36,0x3d,0xce,0xab,0x38,0x33,0xe0,0xad,0x9a,0x9b,0xaa,0xb1,0xac,0xa5,0x99,0xa8,0xae,0xa7,0xab,0xa0,0x9b,0xa4,0xca,0xac,0xb6,0xa3,0xac,0xfd +,0xdb,0x42,0x6d,0x5a,0x4e,0x2a,0x26,0x1f,0x28,0x5f,0x2b,0x1c,0x1b,0x1e,0x27,0x29,0x1a,0x24,0x2f,0x25,0x2b,0x27,0x1d,0x1a,0x1d,0x27,0xea,0x2d,0x21,0x3a,0x49,0xbb +,0xb6,0xde,0xc6,0xd1,0xbc,0xac,0xa5,0xbb,0xc2,0xb4,0xa5,0x94,0xa2,0xaa,0xa5,0x9d,0x9e,0x9b,0xa0,0xb3,0xab,0xcb,0xad,0xaa,0xdd,0xd2,0xae,0xae,0xa6,0xba,0x34,0xb1 +,0x65,0x5a,0xb1,0x4e,0x2f,0x38,0x39,0x31,0x34,0x21,0x22,0x37,0xe4,0x35,0x37,0x2a,0x22,0x2d,0x2b,0x36,0x27,0x1e,0x38,0x4c,0xfc,0xb5,0x46,0x32,0xd4,0xc4,0x6a,0x3d +,0x2a,0x37,0x47,0x38,0x4e,0x65,0x4b,0xeb,0xc0,0xad,0xd5,0x3f,0xb4,0xaa,0xb3,0xb5,0xbe,0x45,0xe8,0xc2,0xc6,0xb4,0xb3,0xb8,0xa4,0x9e,0xa6,0xad,0xae,0xbf,0xaf,0xaf +,0xc9,0xc5,0x44,0xe4,0xb9,0xbb,0xa8,0xa6,0xc3,0xb8,0xba,0x5e,0xea,0x2c,0x2b,0x2f,0x28,0x4b,0x46,0x37,0x2c,0x34,0x32,0x4e,0x3a,0x27,0x2a,0x21,0x27,0x24,0x29,0x1e +,0x25,0x37,0x30,0x32,0x2e,0x2a,0x37,0x34,0xf9,0xbc,0x3d,0x40,0x6c,0xc0,0xc6,0x4a,0x44,0xbe,0xcd,0xb2,0x9e,0xae,0xbc,0xba,0xb4,0xa8,0xba,0xb4,0x60,0x4d,0xb9,0xab +,0xb1,0xce,0xb3,0xaf,0xa0,0x9d,0xb9,0xe8,0x4f,0x3d,0xbe,0xb7,0xf3,0x64,0x5d,0x5e,0x5a,0x36,0x3a,0x43,0x4f,0x40,0xb1,0x46,0x2d,0x51,0x32,0x50,0x4f,0x33,0x34,0x3a +,0x38,0xbc,0xc8,0xdf,0xd3,0x46,0xcd,0xbc,0x44,0x35,0x3d,0x35,0xd8,0xb5,0xd8,0xbc,0xc3,0xb6,0xb5,0xc5,0x6b,0x51,0x43,0x3a,0xb0,0x47,0x30,0x4b,0x32,0x46,0x69,0x55 +,0xc3,0xf1,0x35,0xc6,0xbd,0x6e,0xac,0xb6,0xce,0xc2,0x47,0x57,0xbf,0x31,0x3c,0xb8,0xd1,0xb9,0xc6,0xf4,0xcc,0x3b,0x55,0xbc,0x2d,0x27,0xd8,0xdf,0x67,0xbd,0x40,0x64 +,0xb7,0xba,0xb2,0xcd,0x2d,0x4d,0xce,0x3d,0xcf,0x4e,0x3f,0xbd,0x5d,0x3a,0xba,0x2f,0x3d,0xae,0x6c,0xb1,0xaf,0x2f,0x32,0xce,0x55,0xaa,0xde,0x33,0xbd,0x43,0xc8,0xab +,0xc0,0x5a,0xc6,0xed,0xc2,0xc8,0x2c,0x41,0xd6,0x3d,0xc7,0xbe,0x31,0x59,0xc6,0x5e,0xae,0x31,0x23,0xcd,0x3f,0x61,0xb0,0x37,0x29,0x46,0x4e,0xb5,0xca,0x34,0xb6,0xb7 +,0xf6,0xa6,0xd4,0x2a,0xf0,0x44,0x4c,0x59,0x25,0x2f,0x3c,0x40,0xa9,0x9f,0x6d,0x5f,0x60,0x4e,0xa7,0xf0,0x38,0xc3,0xea,0xce,0xab,0xee,0x52,0xb3,0xb8,0xb0,0xb1,0x2c +,0x3e,0x48,0x26,0xbb,0x36,0x25,0x49,0x3b,0xde,0xa5,0x49,0x47,0xb8,0x38,0xaf,0xa7,0x3e,0x42,0x3b,0x3c,0xac,0x4e,0x2e,0xbf,0x3e,0x52,0xa1,0xc8,0x35,0xe2,0x36,0xb9 +,0xb7,0x1f,0x49,0x69,0x28,0xb9,0xa3,0x33,0xd3,0xcd,0xd6,0xa0,0x3e,0x35,0xd9,0x2d,0x64,0xa2,0x2a,0x36,0x59,0x3a,0xa5,0xb8,0x3e,0xab,0xde,0x31,0xa7,0x42,0x1d,0x3c +,0x2e,0x50,0xa7,0x35,0x3a,0x5c,0x2d,0xa8,0x9f,0x46,0xba,0x69,0x39,0xa5,0xdc,0x28,0xd7,0x30,0x4f,0x9a,0xfe,0x2d,0x58,0x30,0xae,0xa7,0x2a,0x55,0x38,0x1e,0xa3,0xac +,0x25,0xcb,0x3d,0xfd,0x9b,0xd0,0x5f,0xaa,0x2b,0xb7,0x9b,0x2c,0x2f,0xf2,0x36,0xaa,0xae,0x1f,0x38,0x2a,0x2c,0x9b,0xb6,0x30,0xbc,0x2c,0xc4,0x99,0x5a,0x3a,0xef,0x27 +,0xaf,0x9e,0x21,0x3a,0x4e,0x3c,0x9b,0xac,0x2d,0xe3,0x20,0x2c,0x9d,0x3f,0x28,0xe2,0x2a,0xbe,0xa5,0x33,0xbe,0xe0,0x24,0x9f,0xaf,0x22,0x4b,0x30,0x3e,0x9f,0xd2,0x2d +,0xe6,0x28,0xae,0x97,0x42,0x39,0xdb,0x2e,0xa1,0x9f,0x2b,0x3e,0x24,0x2b,0x9e,0x43,0x1f,0xce,0x3b,0xe8,0x9c,0xc6,0x53,0x41,0x1d,0xa2,0x9c,0x2b,0x48,0x3a,0x28,0x9f +,0xab,0x3b,0xb2,0x33,0xe3,0x9b,0x37,0x21,0x32,0x1d,0xbd,0xa2,0x29,0x2e,0x3e,0x3b,0x9f,0xa8,0x32,0xbf,0x4b,0x4f,0x99,0xc6,0x28,0x35,0x1d,0xbc,0x9d,0x2a,0x2b,0x36 +,0x20,0xaa,0x9b,0x4c,0x49,0x2a,0x36,0x99,0xb9,0x20,0x3a,0x29,0xbd,0x97,0x58,0x77,0xe6,0x27,0xad,0xa6,0x35,0x45,0x2c,0x28,0xa2,0xb0,0x27,0x2f,0x1f,0x40,0x9a,0xc4 +,0xf2,0xce,0x25,0xb4,0x9c,0x58,0xf2,0x36,0x40,0x93,0xa0,0x27,0x39,0x26,0x34,0x99,0xb9,0x35,0x3e,0x1d,0x5c,0xa5,0x28,0x2a,0x27,0x1d,0xb1,0xb3,0x39,0xc1,0x48,0xba +,0x91,0x9e,0xcd,0xc3,0x27,0xeb,0x99,0xd6,0x2f,0x2e,0x21,0xb1,0xa9,0x2a,0x34,0x21,0x1b,0xb9,0x54,0x1e,0x2f,0x1f,0x3b,0x97,0xb0,0xe0,0xa7,0xaf,0x99,0x92,0xc2,0x51 +,0x3e,0x33,0x9f,0xa8,0x2c,0x2a,0x14,0x17,0xe6,0x28,0x1c,0x2f,0x26,0xd0,0x9d,0x4f,0x71,0xbc,0x3d,0xa2,0x9a,0xba,0xae,0xc1,0xc5,0x91,0xa0,0xd6,0xb6,0x23,0x33,0xbc +,0x1f,0x1b,0x1e,0x13,0x47,0xac,0x25,0x2c,0x2a,0x2e,0x9c,0x9d,0xaf,0xa2,0xb2,0xa3,0x91,0xa4,0xd4,0xcb,0x30,0xa5,0xa1,0x24,0x20,0x1e,0x16,0xbc,0xba,0x1d,0x36,0x23 +,0x1c,0xbf,0x37,0x1d,0x74,0x3a,0x9e,0x8d,0xa1,0x9b,0x9c,0xbb,0x99,0x9e,0x2e,0x55,0x26,0x26,0xa2,0x3a,0x15,0x2a,0x15,0x1e,0xba,0x29,0x26,0x38,0x1d,0xe3,0x9e,0xcc +,0x9d,0xaa,0xc3,0x95,0x9a,0xc9,0x9c,0xb1,0xb6,0x96,0xfd,0x34,0x4b,0x10,0x19,0xbe,0x1b,0x20,0x1e,0x11,0x24,0xc7,0x33,0xa8,0xaf,0xb5,0x90,0xa6,0xa6,0x9d,0x40,0x66 +,0x99,0xb6,0xb8,0xb5,0x30,0x31,0xb5,0x28,0x3a,0x58,0x12,0x1e,0x2f,0x1b,0x1c,0x2b,0x26,0x9d,0x95,0xa1,0xcb,0x48,0x31,0xac,0xac,0x7c,0xaa,0x34,0x9c,0x86,0x99,0x1f +,0x14,0x0d,0x31,0x9c,0x1e,0x0d,0x0f,0x29,0x8f,0x90,0x17,0x15,0x95,0x8e,0x95,0x38,0x04,0x07,0x1c,0x93,0x80,0x88,0x98,0xb0,0x2b,0x2c,0x9c,0x25,0x10,0x28,0x15,0x1c +,0x98,0x4f,0x06,0x1f,0xb9,0x92,0xa0,0x17,0x0d,0x4d,0x88,0x82,0xa3,0x09,0x39,0x8f,0x9f,0x9f,0x44,0x12,0x13,0x0f,0xb6,0x87,0x93,0x26,0x37,0x0f,0x15,0x3e,0x06,0x08 +,0xc2,0x89,0x80,0x90,0x0b,0x28,0x8b,0x8c,0x91,0x23,0x19,0x36,0x18,0x17,0xad,0x29,0x2f,0x8d,0x25,0x15,0xc2,0x15,0x05,0x1b,0xac,0x88,0x8a,0x1a,0x1e,0x95,0x87,0x8c +,0x1a,0x0b,0xe1,0x8f,0x89,0x96,0x15,0x00,0x18,0x10,0x3a,0xcf,0x0b,0x28,0xab,0xb6,0x8e,0x9a,0xac,0x8c,0x97,0xa5,0x43,0xd4,0x18,0x0d,0x45,0x8f,0x8d,0x9b,0x21,0x35 +,0x47,0x59,0x0e,0x02,0x05,0x14,0x8d,0x86,0x98,0x1c,0x1e,0xa7,0xad,0x70,0x8a,0xa5,0x28,0x9f,0xcf,0xa0,0x9f,0x10,0xb0,0xa5,0xb4,0x15,0x03,0x00,0x15,0x84,0x8d,0xa1 +,0x1e,0x1f,0x98,0xa7,0xd9,0xab,0x15,0x91,0x92,0x32,0x97,0x94,0x7c,0x4f,0xdb,0x32,0xd5,0x15,0x06,0x06,0x2a,0xe6,0x9c,0x0c,0x0d,0x8b,0x87,0x8f,0x3f,0x10,0x28,0xc2 +,0x98,0x85,0x9a,0x9b,0x8e,0xac,0x18,0x1a,0x1b,0x55,0xbf,0x9e,0x22,0x0a,0x02,0x09,0x9d,0x39,0x97,0x8b,0x3c,0xaa,0x99,0x8f,0x8d,0x1a,0x2f,0xac,0x9d,0xab,0x0e,0x13 +,0xec,0x9c,0x8b,0x39,0x10,0x0c,0x0e,0xbe,0x0c,0x30,0x24,0x28,0x84,0x8e,0x99,0x99,0x60,0x3e,0x0d,0xac,0x8f,0x3b,0xa3,0x2f,0x33,0x94,0x9a,0x29,0x18,0x41,0x90,0x10 +,0x07,0x05,0x40,0x8c,0x2f,0xa5,0x9e,0xab,0x9e,0xaa,0xc0,0x31,0x1a,0x9e,0x4a,0xa9,0x88,0xac,0x1e,0x23,0x0d,0x26,0x6b,0x29,0x2e,0x27,0x97,0x2a,0x9f,0x1d,0x16,0x8b +,0x9e,0xa7,0x33,0x0f,0x3c,0x1f,0xa2,0x8b,0xad,0x8b,0x4b,0x0e,0x2d,0xe9,0x5b,0xad,0x5e,0x41,0x1a,0x53,0x18,0x15,0xa2,0x14,0x96,0x90,0x27,0xad,0x9f,0x94,0x98,0x1e +,0x2e,0x12,0x34,0x8d,0x28,0x23,0xb4,0xf2,0xb8,0x3d,0xa8,0xa8,0x31,0x5e,0x04,0xc5,0xdb,0x0c,0x9e,0x47,0x9e,0x8b,0xa7,0x3b,0x0f,0xc5,0x95,0x3b,0x99,0xbb,0x30,0xa0 +,0xa7,0xe9,0x3c,0x2b,0x40,0x16,0x39,0x1c,0x18,0xa8,0x0c,0x2f,0x8e,0x9b,0xad,0x57,0x25,0x33,0xbf,0x9a,0x2e,0xa6,0x82,0x99,0x39,0xd7,0x1e,0x22,0x3c,0x32,0x47,0x16 +,0x2f,0x0d,0xd5,0xbe,0x2b,0x96,0x2d,0x1f,0xb8,0xcb,0xc8,0x55,0xc7,0xaa,0x2f,0x89,0x8d,0x3b,0xa9,0x99,0xb3,0xb9,0x15,0x0f,0x09,0x27,0x49,0x1b,0xa9,0x06,0x2a,0x9f +,0xbc,0x8d,0x92,0x95,0x9f,0x27,0xa4,0x2a,0x35,0x94,0xdc,0xbc,0xb5,0x30,0x16,0x1d,0xbb,0xac,0xde,0x49,0x04,0x5e,0xba,0x1b,0x93,0x3d,0x54,0x9d,0xab,0xaa,0x38,0xb1 +,0x9e,0x27,0x9a,0x99,0x3c,0x3b,0x3a,0x39,0xa7,0xbc,0x18,0x04,0x23,0xf7,0x32,0x92,0x0c,0x20,0x93,0xe9,0x9d,0x99,0x9c,0x9b,0xaa,0x9a,0x39,0x1e,0xc5,0x34,0x2c,0x9f +,0xce,0x1a,0x1e,0x1b,0x28,0x29,0xa2,0x1a,0xe3,0x96,0x1d,0x8e,0xa1,0x11,0xae,0xa6,0xa1,0xb5,0x2e,0x39,0x11,0xdb,0x8d,0xae,0xb8,0xa3,0x2f,0xfa,0x47,0x28,0x11,0x1b +,0xbb,0x11,0x9a,0xbe,0x15,0x90,0x36,0xad,0x8c,0xbf,0x31,0x14,0xc4,0x98,0x2f,0x9e,0x2e,0x1b,0x98,0xa3,0xc4,0xc5,0x39,0x1c,0x0d,0xc6,0x2b,0x21,0x8d,0x1d,0x67,0x90 +,0x2a,0x29,0x3f,0x50,0x9d,0xa7,0xaf,0x14,0x15,0x92,0xac,0xaf,0x9a,0xb8,0xb7,0x9f,0xfb,0x20,0x10,0x52,0x17,0x39,0x9b,0x0c,0x35,0x2f,0x14,0x99,0x8f,0xa5,0xae,0x2f +,0x9e,0xf7,0xa5,0x97,0x15,0x3e,0x9e,0x40,0xd0,0x33,0x2b,0x32,0x3b,0xa0,0x0a,0x3f,0xca,0x11,0x8d,0xad,0x16,0xcf,0x42,0xae,0xa7,0xa8,0x97,0x19,0xa5,0x9f,0x2c,0x97 +,0x9a,0xb3,0xb1,0xbb,0x26,0x0a,0x0e,0x12,0x0d,0x8c,0x4f,0x13,0xa1,0x24,0xba,0x8e,0xaa,0xcb,0xce,0xa5,0xad,0x25,0x95,0xa1,0x2a,0x9b,0x9c,0x38,0xce,0x1f,0x0d,0x0c +,0x68,0x24,0x0c,0x94,0x25,0xb1,0x88,0x26,0x4c,0x9f,0xcc,0xa6,0xdf,0xa8,0xd0,0x19,0x99,0xc7,0x2e,0x91,0xa6,0x25,0x38,0xc1,0x2b,0x10,0x6d,0x0c,0x1d,0x92,0x0f,0xfe +,0x9b,0x26,0xa0,0x9b,0xad,0xaa,0xad,0x8f,0xd6,0x59,0xb1,0x14,0x17,0xa4,0x9c,0x32,0x64,0x36,0x11,0x19,0xb6,0x11,0xac,0x8e,0x17,0xab,0x9f,0x22,0xc4,0x9d,0xd0,0xb8 +,0xc8,0xbf,0x26,0x29,0x97,0xa9,0x5f,0x9c,0xfc,0x30,0xa2,0xd3,0x16,0x12,0x39,0x10,0xaa,0x9d,0x13,0x9a,0x9b,0x1c,0xa8,0xb4,0x2d,0xb1,0xc5,0x9c,0x3b,0x5e,0xbe,0x2b +,0x4e,0x9c,0xb2,0x22,0xcb,0x40,0x15,0x30,0xdd,0x0f,0x96,0xaa,0x20,0x95,0x3e,0x1c,0xae,0xac,0x44,0xbb,0xbb,0x58,0x27,0x45,0xa9,0xc1,0xcf,0x92,0x9c,0xbc,0xa5,0x34 +,0x1d,0x32,0x19,0x0f,0xaf,0x23,0x19,0x9c,0xd9,0x2b,0x98,0x68,0x3b,0x9f,0xb8,0xaa,0x2f,0x37,0xab,0xcc,0xb0,0x99,0xf5,0xad,0xbb,0x25,0x1b,0x1d,0x16,0x15,0x95,0x2c +,0x30,0x93,0x36,0x2f,0xbf,0x45,0xad,0xdd,0x3b,0xbf,0xb7,0xaf,0xac,0xa5,0x9e,0x99,0xa5,0xc4,0x35,0x18,0x16,0x44,0x0d,0x20,0xa6,0x18,0x44,0xa0,0x46,0x36,0xf8,0xdc +,0xa0,0x99,0x9f,0xa0,0xa7,0x3e,0xb6,0x5d,0xbd,0xa9,0x2b,0xcd,0x28,0x18,0x2e,0x2b,0x17,0x62,0xa1,0x29,0x32,0xab,0x4a,0x2d,0x7b,0x2f,0x9d,0x9b,0xb1,0xa8,0x4c,0xad +,0xa5,0x64,0xa9,0xa7,0xb1,0xbe,0x24,0x1c,0x1d,0x19,0x0d,0x3b,0x54,0x19,0xc8,0xa4,0xb0,0x9f,0xaf,0xb7,0x9d,0x9c,0x9b,0x30,0x30,0x6c,0xcc,0xf5,0xb2,0xa7,0xb7,0xbb +,0x2a,0x17,0x16,0x16,0x18,0xde,0x55,0x67,0xb3,0xb0,0xb3,0xa2,0x9d,0xc7,0xb9,0xb3,0xd6,0x34,0x22,0xc5,0xa1,0xb0,0x9f,0xc3,0xbd,0xb9,0x2a,0x27,0x1e,0x1d,0x18,0x20 +,0x5e,0xcf,0xad,0xc0,0x43,0xbb,0x61,0xca,0x9f,0x9b,0x98,0xb7,0x5e,0xba,0x6a,0xb3,0xca,0x3f,0x2f,0x25,0x2c,0x21,0x28,0x3f,0x39,0xbb,0xb5,0x6e,0x47,0x25,0x29,0x30 +,0xc2,0xae,0xb3,0xb4,0xbf,0xad,0xa9,0xa0,0xad,0xbb,0xad,0xc9,0x4c,0xcd,0x54,0x73,0x2e,0x21,0x1a,0x16,0x2d,0x3b,0xe6,0xde,0x3c,0x32,0x5d,0xae,0x98,0x9f,0xab,0xea +,0x2c,0xc3,0xcb,0xa4,0xa4,0xa7,0xa7,0xc5,0xca,0x49,0x2d,0x29,0x1e,0x1e,0x1d,0x23,0x37,0x30,0x54,0x5b,0xbc,0xc1,0x33,0x3f,0x6c,0xc8,0x9f,0xa4,0x9d,0x9d,0xa1,0x98 +,0xa1,0xaa,0xed,0x2a,0x3f,0x34,0x1d,0x1a,0x16,0x1f,0x26,0x24,0x1f,0x1f,0x3e,0xb6,0xb1,0xbf,0xcd,0xba,0x9e,0x96,0x92,0x94,0xa2,0x40,0x46,0x38,0x5c,0xba,0xef,0xfc +,0x3f,0x5f,0x4e,0x2c,0x1b,0x12,0x1a,0x27,0x26,0x36,0x30,0x39,0x48,0xb3,0x9e,0x9d,0x97,0x9d,0x9c,0x9d,0xb0,0xc4,0xbf,0xc0,0xa8,0xe9,0x31,0x30,0x25,0x2d,0x1d,0x1c +,0x19,0x1d,0x5e,0xb1,0xa9,0xd4,0x29,0x2e,0x38,0xbb,0xaa,0xbb,0xb7,0xb5,0xac,0xa0,0x9c,0xa5,0xba,0x70,0xcb,0xb7,0xce,0x2d,0x2c,0xfc,0xf1,0xca,0xeb,0x28,0x16,0x17 +,0x23,0x2f,0x38,0x2d,0x2b,0xc8,0xaf,0xac,0xa6,0xa4,0xa3,0xaa,0x9f,0xaf,0xd1,0xb8,0xbf,0xb2,0xbb,0xb8,0xdb,0x38,0xce,0xcc,0x2d,0x1c,0x15,0x18,0x3c,0xbf,0x40,0x24 +,0x1f,0x29,0x4c,0xac,0x7d,0x47,0xbe,0xa3,0x92,0x8e,0x93,0xa9,0xc2,0xf0,0xd1,0xb4,0x62,0x1f,0x19,0x23,0x3d,0x5e,0x54,0x2b,0x23,0x2c,0x3a,0x28,0x24,0xea,0xbb,0xaf +,0xc5,0x56,0xb2,0xab,0xaf,0xa9,0xba,0xbe,0x6e,0xc6,0x9e,0xa9,0xbe,0x4a,0x4c,0xad,0xa1,0xbb,0x2a,0x16,0x16,0x20,0x5c,0x6b,0x25,0x24,0x25,0xc4,0x9e,0xa6,0x66,0x24 +,0x28,0xbc,0xa2,0x9c,0xa8,0xd4,0xbf,0xb8,0xa2,0xa4,0x66,0x34,0x40,0xae,0xa0,0xaa,0xaa,0x45,0x1d,0x1e,0x1a,0x0e,0x0e,0x1b,0x29,0x3e,0x52,0x48,0xb8,0xa0,0xa0,0xa0 +,0xa4,0xac,0xa8,0xa2,0x9e,0xa1,0xad,0xab,0xae,0xdf,0xb3,0x37,0x19,0x1e,0x20,0xdc,0xb6,0x28,0x16,0x12,0x1c,0xae,0xa2,0xc1,0x26,0x21,0x4e,0xac,0x93,0x9a,0x9f,0xaf +,0xd2,0xa4,0x9a,0x9a,0xa8,0x2d,0x28,0x36,0x57,0x34,0xff,0xbf,0x38,0x2f,0x1b,0x14,0x13,0x2d,0x24,0x45,0xc8,0xad,0xa4,0xb8,0xa9,0xbd,0xaf,0xb0,0xab,0xbd,0xb9,0x2d +,0x2c,0xa5,0x9c,0x9c,0xab,0x32,0x15,0x29,0xcc,0xaa,0xab,0x2d,0x16,0x16,0x21,0x40,0x29,0x18,0x35,0x3c,0xaf,0x97,0xa5,0xa6,0x9e,0xef,0xbc,0xd0,0x49,0xaa,0xac,0xaf +,0xc9,0x54,0xd3,0xc2,0xbf,0xbd,0x4f,0x5d,0x6b,0x22,0x1c,0x25,0x1f,0x1e,0x17,0x20,0xb6,0xbb,0xab,0xbf,0xc8,0x9b,0x9d,0x9f,0x9f,0xaf,0xab,0x9a,0xc0,0x49,0xb8,0x2a +,0x2b,0x2b,0x21,0x66,0xbd,0x33,0x3b,0x25,0xbd,0xba,0x2a,0x1a,0x0c,0x26,0xab,0xa5,0xab,0xa9,0xae,0xa6,0xaa,0xbe,0xa6,0xa2,0x9d,0xad,0x2f,0xe9,0xd0,0x36,0xaf,0x60 +,0x31,0xbe,0x1f,0x23,0x2b,0x3c,0x77,0x1d,0x19,0x0f,0x42,0x9a,0xaa,0xaf,0xd6,0xb8,0x9b,0xb5,0xcb,0x9c,0x9e,0xa4,0x3a,0x1e,0xba,0xb9,0x4d,0xb2,0xbc,0xbc,0xb7,0x25 +,0x24,0x47,0x5f,0xd2,0x1a,0x18,0x0f,0x23,0xa5,0x32,0x49,0xa9,0xa0,0x9b,0xb1,0xb3,0x9b,0xa3,0xa9,0xaa,0x44,0xaf,0xd6,0x23,0xf6,0xee,0x3d,0x4c,0x28,0x2c,0xbd,0x56 +,0x36,0x1b,0x13,0x0b,0x30,0x9a,0xde,0xbc,0xb5,0xac,0xa6,0xd7,0xa5,0x8f,0xa3,0xa2,0xac,0x54,0x9e,0x3a,0x1e,0x3f,0x2d,0x22,0x3a,0x32,0x6c,0x3e,0x29,0x2e,0x26,0x12 +,0x16,0x99,0xb3,0x44,0xa5,0xa7,0xa8,0xae,0xc5,0x95,0x9e,0x48,0xa6,0x35,0xd3,0xb9,0x42,0xb1,0xb7,0x22,0x34,0x34,0x26,0x2b,0x1d,0x4a,0x2a,0x1b,0x0f,0xcc,0x9a,0x3a +,0xbb,0xb5,0x59,0xd1,0xb4,0x97,0x8e,0xbd,0xae,0xca,0x30,0xac,0xa7,0x9d,0xa6,0x1f,0x37,0xd7,0x2c,0x2c,0x1a,0x27,0x27,0x17,0x0a,0x24,0xa7,0x26,0xb6,0x95,0xa9,0xc5 +,0x30,0xbb,0x95,0xb1,0x94,0x90,0xbd,0xa8,0xaa,0xaa,0xa3,0x2d,0xd5,0x3e,0x13,0x24,0x11,0x19,0x1e,0x1d,0x11,0x15,0xca,0x21,0xc0,0x92,0xa5,0xbd,0xc3,0xa8,0x92,0x9f +,0x8f,0x95,0x3d,0xa8,0xb9,0xbe,0xa2,0x69,0xb4,0x3a,0x1f,0xfa,0x14,0x0e,0x0f,0x11,0x12,0x31,0xb0,0x20,0xe2,0xaa,0xae,0xa3,0xa8,0x93,0x92,0xbe,0x9a,0xab,0x73,0x9d +,0xa9,0xa5,0xbb,0x29,0x46,0x20,0x1e,0x49,0x1c,0x23,0x17,0x1a,0x14,0x25,0xb3,0x15,0xbe,0x9d,0xa9,0x9a,0xc3,0x9f,0x99,0xbf,0x8e,0x9c,0xdf,0xac,0x45,0xa1,0xb2,0x46 +,0xb8,0x24,0x23,0x2d,0x1e,0x23,0x14,0x14,0x0b,0x23,0xbb,0x1d,0xa2,0x9e,0x9d,0xa0,0xcc,0x9a,0xac,0xca,0x93,0xa1,0xaa,0xab,0xd7,0xa2,0xcb,0xed,0xd9,0x23,0x2e,0x3a +,0x21,0x1b,0x13,0x19,0x10,0x57,0xa4,0x2e,0xd8,0x2c,0xdb,0xb6,0xc3,0x91,0x9c,0xbb,0x9e,0xab,0x9f,0xae,0xd8,0xa5,0x61,0xcc,0xc9,0x35,0x3f,0x1e,0x20,0x26,0x1c,0x1f +,0x0f,0x39,0xb3,0x29,0xa8,0xab,0xaa,0xcc,0x37,0x9f,0xab,0xb6,0xa2,0xa8,0xa9,0xbb,0xba,0x9c,0xb3,0xc6,0xba,0x2b,0x27,0x19,0x1f,0x38,0x24,0x2a,0x1e,0x20,0xd6,0x3c +,0xc7,0xb5,0x5c,0xbf,0x5a,0xc1,0xad,0xb6,0xa2,0xa6,0xb6,0xa9,0xdc,0xeb,0xdf,0xd5,0xa3,0xc6,0xfc,0xd9,0x31,0x31,0x35,0x42,0x3a,0x1e,0x21,0x69,0xc9,0x54,0x49,0xe9 +,0x6c,0x54,0xe3,0xd5,0x52,0xce,0x7c,0x48,0x7c,0xcf,0xaa,0x9f,0x9f,0xa7,0xc1,0x47,0x30,0x3f,0xac,0xac,0xde,0x33,0x2c,0x2e,0xcb,0xb1,0x79,0x28,0x1e,0x2c,0x4b,0x3b +,0x2e,0xcf,0xf2,0x2c,0x30,0xb3,0xa9,0xb9,0xba,0xaf,0xb9,0xe9,0xbf,0xb0,0xaf,0xb8,0x6d,0x37,0x34,0x2a,0x6c,0xb6,0x68,0x4e,0x5b,0xc7,0xd3,0x6b,0x5f,0x3f,0x2e,0x38 +,0x4b,0x3f,0x67,0x4e,0xbd,0xb4,0x72,0xfc,0x57,0x51,0x47,0xcc,0xb9,0xe5,0xe7,0xaf,0xaf,0xc3,0xce,0xcd,0x49,0x39,0x5b,0xc1,0xbd,0x5b,0x48,0x62,0x75,0x48,0x46,0x49 +,0x39,0x35,0x38,0x2f,0x28,0x49,0xbb,0xb9,0xe0,0x53,0xd9,0xc7,0xb1,0xc3,0xad,0xb0,0x6f,0xdd,0xb0,0xac,0xbf,0x5b,0x3f,0x2c,0x29,0x66,0x50,0x3a,0x33,0x43,0xc3,0xc5 +,0x4f,0xef,0x5d,0x35,0x39,0xb0,0xa8,0xee,0xd2,0xbc,0xf6,0xc4,0xae,0xb0,0xcb,0x33,0x47,0x5c,0x48,0x5e,0x66,0xc4,0xd3,0x33,0x3c,0x61,0x4b,0x56,0xc3,0xde,0x33,0x34 +,0x4b,0xc8,0xbb,0xc7,0xcb,0x51,0x2b,0x3d,0xf3,0xc6,0xaa,0xac,0xb5,0x5c,0x3d,0x5f,0x50,0x38,0x41,0x62,0x37,0x35,0xd0,0xb3,0xae,0xaf,0xe2,0x44,0x2c,0x29,0xd9,0xb8 +,0xbb,0xc0,0xd8,0xbe,0x47,0x45,0xaf,0xaf,0xdf,0x3e,0x46,0x41,0x57,0xbe,0xc0,0x6c,0x3d,0x38,0x68,0x3f,0x30,0x4b,0x38,0x44,0xc3,0xaf,0xab,0xc4,0xcc,0xc6,0xc6,0xdc +,0x62,0x5f,0x4d,0x50,0xc3,0xad,0xc8,0x3c,0x2e,0x33,0x2d,0x29,0x2e,0x35,0x40,0xeb,0xb6,0xa8,0xae,0xb2,0xb2,0xc8,0xd1,0x45,0x5b,0xcd,0xc8,0xcc,0xf4,0x54,0x59,0xe9 +,0xd6,0x6f,0x44,0x3e,0x2f,0x51,0xd9,0xc6,0xc7,0x38,0x3e,0x45,0x60,0xdc,0x65,0xbe,0xbc,0xc6,0xae,0xad,0xc7,0xcf,0xd3,0x4c,0x34,0x2f,0x2c,0x2b,0x56,0xb6,0xac,0xaf +,0x40,0x37,0x38,0x4c,0x4a,0x36,0xda,0xbc,0xda,0xd7,0xc5,0xd7,0xb8,0xb3,0xc7,0x35,0x20,0x37,0xc0,0xaa,0xa7,0xbe,0xc0,0x4b,0x56,0xbe,0xd3,0x3e,0x25,0x2d,0x3c,0xd8 +,0xb5,0xd2,0x4d,0xd0,0xc1,0x66,0x3d,0x3c,0x41,0x47,0xbb,0xb2,0xbe,0xc7,0xcc,0xc7,0xb3,0xc8,0x54,0xd8,0x3e,0x36,0xcf,0xba,0xcf,0x4f,0xef,0x6c,0x32,0x2a,0x20,0x2a +,0x48,0x60,0xb9,0xb5,0xbc,0xc0,0xae,0xb0,0x4c,0x3d,0x45,0xc3,0xb4,0xb0,0xd5,0x4e,0x4b,0xc9,0xbc,0xe9,0x6c,0x24,0x23,0x35,0xe3,0xb9,0xb2,0xae,0xcb,0xce,0x48,0x58 +,0x5d,0x34,0x4d,0x5d,0x49,0x45,0xbd,0xad,0xa7,0xc7,0x3c,0x39,0x2b,0xcb,0xc3,0xce,0xb8,0x59,0xd9,0xba,0xcc,0x40,0x32,0x23,0x2f,0x48,0x40,0xc5,0xc7,0xb7,0xa5,0xa0 +,0xb2,0x34,0x20,0x26,0x50,0xda,0xbe,0xba,0x45,0x69,0xae,0xbf,0xd9,0xde,0x1f,0x28,0x58,0xc0,0xb6,0xb3,0xb8,0xfd,0xf8,0xc9,0xda,0x2c,0x60,0x3f,0xde,0xcd,0xc3,0xad +,0xb1,0xa2,0xe3,0x3e,0x1e,0x1a,0x3e,0xe5,0x5e,0xf1,0x51,0x72,0xad,0x9e,0xb9,0x2c,0x46,0x25,0x54,0xbc,0xbd,0x5c,0xb9,0xae,0xbc,0xac,0x2a,0x36,0x1f,0x39,0xe6,0xcd +,0xbf,0x3f,0xbc,0xbc,0xaf,0xbf,0x30,0x1e,0x20,0x21,0xdc,0xaf,0xaa,0x9f,0xa4,0xc8,0xb0,0x47,0x34,0xbf,0x35,0xaf,0x30,0x46,0xb9,0x5e,0x99,0xac,0x2e,0x40,0x17,0x28 +,0xb9,0x2a,0xc9,0x4a,0xb2,0xab,0xb5,0x9a,0x2b,0x25,0x56,0x32,0xb9,0x3e,0xbc,0x4c,0xc2,0xa1,0xad,0xb2,0x21,0x3a,0x27,0x2c,0xcf,0x50,0xe0,0x55,0xfd,0xfb,0xf1,0xbe +,0x38,0x1f,0x40,0xc9,0x47,0xbd,0xad,0xa2,0x9e,0xb2,0xaf,0x1f,0x33,0xc3,0x3d,0xba,0x1e,0x3f,0xbd,0xc5,0xad,0xb6,0xc3,0x22,0x31,0x45,0x45,0x66,0xf0,0x43,0xc6,0xa5 +,0xa6,0xb4,0x2b,0x20,0x2a,0x49,0xb0,0xd4,0x49,0xb8,0xc0,0x9d,0xaa,0x4e,0x26,0x16,0x33,0x4f,0xb9,0xbc,0x39,0xde,0x4d,0xbe,0xba,0x4b,0x59,0x2f,0x4c,0x4b,0x3a,0xb6 +,0xae,0xa8,0xa1,0xa8,0x5c,0x2c,0x39,0xae,0xad,0x48,0x3a,0x30,0x53,0xcb,0xab,0x32,0x1a,0x22,0x1e,0x29,0x64,0x73,0xab,0xa0,0x97,0x91,0x9f,0x9b,0x37,0x21,0x69,0x59 +,0x5b,0x2c,0x2e,0x39,0x42,0xa5,0x1f,0x1f,0x1d,0x0f,0xca,0x2e,0xdb,0xa7,0xa5,0x9e,0xba,0x9a,0xa3,0xb4,0xad,0xb9,0xac,0x35,0xc7,0x41,0x48,0xb2,0x60,0x24,0x1c,0x12 +,0x1a,0xbe,0x1b,0x3c,0x30,0xf4,0x99,0xa3,0x9b,0xb9,0xba,0xb5,0xbe,0x9e,0xbd,0xad,0xac,0xa6,0x98,0xa5,0xbc,0x26,0x0e,0x0e,0x11,0x0f,0x34,0x14,0x25,0xb6,0xb9,0x99 +,0xa7,0xaf,0xab,0xa1,0x98,0xbe,0xa4,0xa0,0xb9,0xb1,0x31,0xc4,0x23,0xdb,0xd4,0x1f,0x18,0x19,0x0d,0x2f,0x26,0x17,0xad,0x4d,0xbb,0x94,0x97,0x9f,0x39,0xa6,0x96,0x99 +,0x86,0x2c,0x9a,0x11,0x06,0x0b,0x04,0xb6,0x0f,0x0c,0x11,0x0f,0xa1,0x90,0xba,0x8f,0x8e,0xba,0x93,0x8d,0x9d,0x98,0x8a,0xd8,0xc6,0x9c,0x13,0x89,0x8b,0x3f,0x9d,0xc9 +,0x1f,0x32,0x09,0x01,0x06,0x03,0x0d,0x0b,0x09,0x06,0x06,0x13,0x29,0x16,0x12,0x09,0x38,0x2e,0x93,0x9d,0x1c,0x9a,0xad,0x97,0x95,0xaa,0xaf,0xa1,0x9d,0x8b,0x8b,0x87 +,0x96,0x90,0x80,0x82,0x81,0x85,0xa0,0x84,0x95,0x52,0xa2,0x90,0x93,0x08,0x9d,0x2e,0x0b,0x0c,0x02,0x13,0x0e,0x00,0x06,0x0f,0x12,0x14,0x00,0x1a,0x10,0x00,0x0b,0x17 +,0xb0,0x19,0x17,0x9f,0x17,0x17,0x8e,0xa6,0x9c,0x86,0x85,0x88,0x9d,0x8a,0x9e,0x93,0x83,0x83,0x8b,0x2d,0xa9,0x80,0x88,0x96,0xa7,0x36,0x8f,0x9b,0x82,0x8f,0x0a,0x0c +,0x28,0x28,0x16,0x0c,0x02,0x02,0x0c,0x0e,0x01,0x07,0x00,0x0f,0x11,0x15,0xb2,0x0e,0x07,0x19,0x93,0x8e,0x9c,0x33,0xaa,0x9e,0x8c,0x88,0x95,0x22,0x1a,0x94,0x8b,0x91 +,0x92,0x31,0xaf,0xa0,0x8e,0x80,0x25,0x94,0x83,0x81,0x88,0x84,0x9e,0xc9,0x8f,0xa8,0x94,0x22,0x1a,0x07,0x00,0x2b,0x11,0x0b,0x03,0x00,0x03,0x0a,0x1b,0x06,0x12,0x18 +,0x0a,0x0b,0x17,0x0b,0x5f,0x3a,0x96,0x98,0xfe,0x8d,0x20,0xa4,0x86,0x84,0x86,0xa6,0x98,0x87,0x87,0x88,0x92,0x8e,0x9d,0xbe,0x94,0x8e,0x8f,0x88,0xa3,0xcf,0x3a,0xc2 +,0x8f,0x9c,0x2e,0x3c,0x28,0x24,0x6a,0x18,0xb1,0x50,0x03,0x13,0xba,0xc5,0x0d,0x02,0x00,0x0a,0x8f,0x12,0x1f,0x2e,0x12,0x08,0x00,0x12,0x09,0xe5,0x1a,0x07,0x0f,0x11 +,0x03,0x06,0x92,0x99,0x43,0x04,0x1c,0x80,0x98,0x8d,0x1b,0x25,0x86,0x80,0x80,0x83,0x8d,0x93,0xa9,0xa5,0x80,0x89,0x8d,0xba,0xb2,0xbf,0xb2,0x1c,0xcb,0x23,0x2a,0xac +,0x0b,0x44,0x06,0x2f,0x95,0x21,0x9c,0xd1,0x1a,0x53,0x8f,0x87,0x1c,0x17,0x21,0x22,0x94,0x93,0x8e,0x8a,0x25,0x0d,0x9e,0x87,0x80,0x8e,0x12,0x1f,0x9d,0x1e,0x1c,0x9a +,0x8c,0x0f,0x10,0x1d,0xa7,0x8f,0x01,0x0f,0xba,0x3f,0x01,0x0e,0x28,0x19,0x14,0x10,0x13,0x00,0x98,0x67,0x00,0x07,0x00,0x06,0x08,0x8d,0xab,0x00,0x0e,0x0e,0x9f,0xa2 +,0xae,0x26,0x0f,0x17,0x15,0x86,0x89,0x8a,0x8f,0x9c,0x8f,0x8e,0x82,0x83,0x80,0x81,0x9a,0x97,0x80,0x83,0x80,0x82,0x80,0x82,0x80,0x89,0x11,0x9e,0x82,0x86,0x1d,0x08 +,0x06,0x3a,0x1a,0x00,0x06,0x00,0x09,0x01,0x03,0x00,0x02,0x00,0x06,0x64,0x0a,0x02,0x0d,0x1c,0x2c,0x0b,0x0a,0x2a,0x0b,0x39,0x11,0x00,0x0e,0x95,0x85,0x89,0x9b,0x09 +,0xa2,0x98,0x80,0x90,0xb2,0xa2,0x18,0x82,0x85,0x84,0x87,0x88,0x86,0x9f,0x94,0x8c,0x98,0x94,0xa6,0x8e,0x8d,0x86,0xa7,0x2b,0xae,0x1c,0xbd,0x2b,0x9e,0x0a,0x00,0x09 +,0x28,0xa1,0x15,0x13,0x16,0x2e,0x2b,0x0b,0x00,0x1e,0x2c,0x27,0x36,0x35,0x1e,0x8c,0x94,0x6e,0x8a,0x0f,0x95,0x93,0x26,0x32,0xee,0xa6,0xa6,0x8d,0xba,0xa4,0x8a,0x99 +,0xb7,0xc5,0x1e,0x17,0x0e,0x0f,0x2a,0x16,0xc9,0x9e,0x3a,0x0f,0x02,0x2d,0xa6,0x1e,0x05,0x0f,0x0e,0x04,0x0f,0x8b,0x8f,0xa7,0x82,0x85,0x87,0x91,0xdc,0x8d,0x87,0x84 +,0x82,0x8d,0x84,0x83,0x83,0x9f,0x98,0x8c,0xb6,0xae,0x42,0x0c,0x0b,0x03,0x1f,0x88,0x44,0x17,0x14,0x0f,0x38,0x0e,0x0a,0x1a,0x9e,0xa7,0xc6,0x21,0x15,0x17,0x1f,0x3a +,0x0f,0x15,0x13,0x14,0x08,0x01,0x0e,0x06,0x0b,0x96,0xcd,0xe5,0x22,0x23,0x6b,0x19,0x0a,0x14,0xbd,0x90,0xa2,0x22,0x9f,0xce,0x8d,0x86,0x97,0x97,0x85,0x84,0x94,0x9d +,0xac,0x6d,0x92,0x80,0x83,0x80,0x8c,0xae,0x87,0x99,0x21,0xbc,0x9d,0xa3,0x28,0x1d,0x2e,0x8d,0x9b,0x21,0x3f,0x13,0x2d,0x19,0x0e,0x06,0x07,0x03,0xcd,0x82,0x1d,0x0c +,0x11,0x1c,0x28,0x1e,0x01,0x0e,0x08,0x28,0x20,0x1d,0x22,0x0d,0x23,0x1e,0x1e,0x04,0x0a,0x1f,0x25,0x06,0x06,0x0c,0x36,0x8d,0x9f,0x1a,0xcf,0x1f,0x36,0x90,0xa5,0x8e +,0x88,0x86,0x83,0x82,0x80,0x82,0x80,0x82,0x84,0x89,0x80,0x82,0x88,0x92,0xbf,0x50,0x9a,0x8f,0x2e,0xcb,0x0e,0x06,0x0c,0x0b,0x00,0x07,0x05,0x02,0x0e,0x04,0x06,0x07 +,0x11,0x0d,0x13,0x03,0x05,0x1b,0x10,0x05,0x14,0x06,0x0d,0x87,0xc1,0x9d,0x9f,0x92,0x8d,0x9b,0x1f,0xdc,0x85,0x86,0x88,0x8b,0x93,0x8a,0x82,0x8c,0x90,0xaf,0xa0,0xbe +,0xac,0x18,0x56,0x0f,0xb1,0x83,0x98,0x9c,0xbc,0xa9,0x37,0x36,0x0a,0x15,0x28,0xa3,0xc8,0xd6,0x9a,0x48,0x9e,0xdf,0x1b,0x0c,0x35,0xae,0x1c,0x10,0x0f,0x0c,0x26,0x84 +,0x70,0xc8,0x35,0x2c,0xb9,0x9d,0x28,0x29,0x97,0xa3,0x88,0xa1,0x2c,0x33,0x8f,0x9e,0x2f,0x0f,0x4c,0x2b,0x2c,0x16,0x0b,0x17,0x0e,0x9b,0x48,0x15,0x13,0x0a,0x1b,0xd4 +,0x0c,0x07,0x1a,0x21,0x15,0x1a,0x21,0xaa,0xa1,0xaa,0x96,0xa8,0x84,0x97,0x93,0x8c,0x8e,0x91,0x8a,0x80,0x84,0x82,0x82,0x86,0x8a,0x80,0x19,0x9f,0x98,0x9e,0x9d,0x15 +,0xc0,0xbb,0x26,0x0e,0x0c,0x08,0x08,0x0b,0x08,0x01,0x0a,0x02,0xab,0x90,0x28,0x18,0x26,0x17,0x18,0x1c,0x00,0x06,0x1d,0x17,0x12,0x1d,0x12,0xba,0xd7,0x13,0x0e,0x0f +,0xcc,0x29,0x14,0x2b,0x23,0x5d,0x84,0x84,0x99,0x8d,0x8b,0x92,0x80,0xa2,0xe0,0x87,0x8c,0x86,0x9a,0x9a,0x9e,0x8c,0x92,0xa3,0xc0,0xa6,0x82,0xa1,0x1b,0x1d,0xdc,0x27 +,0x8c,0x9d,0x0f,0x36,0x18,0x22,0xb7,0x08,0x0b,0xab,0xbf,0x8f,0x1e,0x03,0xab,0x98,0x19,0x25,0x2e,0x3f,0x28,0x18,0x09,0x0f,0x09,0x2a,0x93,0x1b,0x1e,0x15,0x1e,0x36 +,0xcb,0x0a,0x0f,0x2f,0x18,0x1a,0x0a,0x21,0x9a,0x25,0x20,0x10,0x16,0x1d,0x13,0x0e,0x0b,0x1a,0x5d,0x83,0x86,0x85,0x80,0x81,0x81,0x80,0x88,0x8b,0x82,0x82,0x80,0x82 +,0x87,0x82,0x83,0x90,0x8d,0x25,0x2d,0x1e,0x03,0x01,0x03,0x04,0x03,0xd3,0x0d,0x0d,0x0c,0x02,0x0e,0x07,0x00,0x0e,0x1e,0x1a,0x28,0x09,0x1b,0x97,0xbf,0x0b,0x1d,0x0d +,0x1d,0x3c,0x1a,0x1b,0x1f,0x1e,0x8b,0x8a,0xf7,0xa5,0xab,0x94,0x8c,0x4d,0x3e,0x88,0xa2,0x8d,0x9a,0x9d,0x9e,0x8d,0xaf,0x97,0x9a,0x2c,0x8d,0xa3,0x1f,0xb9,0xb7,0x30 +,0x82,0xc5,0xa8,0xa5,0xad,0x9c,0xa8,0x0e,0xf8,0x8d,0xc7,0xaa,0x1a,0x2e,0x9f,0x9f,0x2e,0xbb,0x6f,0xae,0xd2,0x1a,0x04,0x13,0x09,0xc1,0x8e,0x15,0x39,0x1c,0xab,0x99 +,0x27,0x1b,0x38,0x1f,0x36,0x10,0x15,0xdf,0xae,0xbc,0x9f,0xac,0x36,0x1a,0x11,0x0d,0x05,0x08,0x02,0x3f,0x1d,0x1b,0x2e,0x25,0xb3,0x45,0x0e,0x3f,0xb0,0xb9,0x92,0x9f +,0x89,0x81,0x83,0x82,0x81,0x83,0x83,0x87,0x91,0x9a,0x90,0x9d,0x85,0x83,0x89,0x8a,0x98,0xad,0xc4,0x0f,0x09,0x14,0x07,0x1f,0x13,0x0d,0x16,0x1b,0x0b,0x0a,0x0c,0x0a +,0x04,0x05,0x03,0x0c,0x10,0x0f,0x98,0x66,0x4d,0x2c,0x19,0x2d,0x2d,0x0f,0x2e,0x9c,0x9b,0x99,0x9f,0x9c,0x9b,0xb1,0x2f,0xa2,0x9f,0x3b,0x39,0xb8,0x43,0x9c,0x37,0x9c +,0x89,0xa4,0x93,0x94,0x9e,0x9d,0xa8,0xaa,0x8e,0x96,0xb1,0xb0,0xa2,0xba,0xb1,0x3d,0x36,0x9a,0x96,0xa1,0x97,0x36,0x2f,0x25,0x0f,0xab,0xd7,0x34,0x5a,0x50,0x48,0xf8 +,0x2f,0x38,0xb6,0xd7,0x1a,0x1f,0x21,0x1b,0x3d,0x1c,0x54,0x96,0xd8,0x23,0x1b,0x08,0x15,0x0d,0x10,0x1e,0x0e,0x18,0x2a,0xea,0x23,0x13,0x11,0x13,0x1d,0x13,0x0a,0x19 +,0x15,0x25,0xb5,0x29,0xcd,0xa8,0x52,0xa1,0x9e,0xcb,0x98,0x99,0x8a,0x80,0x82,0x80,0x81,0x82,0x84,0x84,0x85,0x88,0x88,0x8d,0x8c,0x87,0x97,0xa0,0x3a,0x0e,0x1c,0x18 +,0x09,0x04,0x02,0x00,0x09,0x06,0x0b,0x17,0x0a,0x0e,0x16,0x16,0x18,0x0f,0x0c,0x1b,0xb7,0x46,0x3f,0x58,0x18,0x31,0x2b,0x1b,0x52,0x27,0x28,0xab,0xbc,0x53,0xaa,0x6f +,0x55,0x94,0xa0,0xa5,0x9a,0x3b,0x9d,0x8f,0x94,0x8d,0x96,0x9a,0x91,0x9a,0xab,0xa4,0x7d,0x43,0x99,0x93,0x95,0x93,0x5f,0xd6,0x9e,0xd3,0xb2,0x34,0x2a,0xad,0xa3,0xb7 +,0xdd,0x66,0x24,0x3f,0x47,0x2f,0xdc,0x1d,0x1c,0xd8,0x4f,0xae,0xb6,0x2b,0x35,0x31,0x1d,0x2b,0x28,0x1b,0x24,0x37,0x3d,0xcb,0x28,0x17,0x29,0x1d,0x24,0x3a,0x1c,0x24 +,0xa4,0xac,0x93,0x91,0xb2,0x9c,0xa5,0xbe,0xb3,0x27,0x18,0xcb,0xbd,0xaf,0x9c,0x5b,0x3c,0xac,0xd6,0xd9,0x3a,0x14,0x22,0xb6,0xd7,0xa0,0xb8,0x2b,0xb7,0x6f,0x4c,0xaf +,0x3d,0x2f,0xb5,0x42,0xad,0xa0,0xc5,0xbf,0xac,0x43,0xaf,0xb1,0x1c,0x61,0xc9,0x4f,0x9d,0xc4,0x2a,0xc0,0x2f,0x37,0x48,0x19,0x1e,0xc5,0x40,0xae,0xb1,0x36,0xc9,0xac +,0xb0,0xa2,0xc2,0x34,0xaa,0xae,0xa3,0x9b,0xb0,0xd0,0xa0,0xbb,0xa0,0xae,0x2a,0xc2,0xc5,0xcf,0xa0,0xae,0x5b,0xad,0x48,0x4e,0xb3,0x43,0x35,0xbe,0x31,0xc8,0xad,0x28 +,0x2c,0x2b,0x15,0x21,0x20,0x12,0x21,0x1c,0x20,0xc6,0x2c,0x29,0xd5,0x2a,0x38,0x2c,0x17,0x1d,0x30,0x2a,0xc9,0xae,0x64,0x9f,0xa6,0xbe,0x9d,0xcd,0x2c,0xae,0x46,0xcc +,0x9c,0xb7,0xa5,0x96,0xa5,0x9b,0x97,0xc3,0xa6,0xa8,0x61,0xa2,0xa3,0xb1,0x9b,0xa9,0xca,0xa2,0xb6,0xba,0x9f,0xc7,0xb0,0x9a,0xbb,0x9e,0x98,0xbb,0xab,0xd3,0x3e,0xb1 +,0x58,0x2c,0xc7,0x50,0x28,0x57,0x2e,0x2a,0x2e,0x11,0x1d,0x2d,0x18,0x22,0x22,0x1a,0x53,0x2d,0x1d,0x29,0x18,0x13,0x18,0x12,0x17,0x28,0x1b,0x1f,0x3e,0x2b,0x30,0x62 +,0x26,0xb4,0x9f,0xb3,0x9f,0x9f,0x95,0x8b,0x92,0x94,0x8b,0x8f,0x99,0x9b,0x96,0x96,0xaa,0x23,0xc8,0xa4,0x1c,0x0e,0x0d,0x10,0x0d,0x06,0x08,0x16,0x16,0x0d,0x14,0x1b +,0x20,0x1f,0x0f,0x11,0x15,0x13,0x21,0x27,0x24,0x44,0xbd,0xa6,0x96,0x9f,0xa6,0x9b,0xa1,0x9a,0x91,0x9a,0x91,0x8e,0x8f,0x8a,0x8f,0x97,0x94,0x91,0x92,0x90,0x9e,0xc3 +,0x9e,0x96,0xa2,0xbf,0x2e,0xbf,0x9d,0xff,0xca,0xa7,0xaf,0xae,0xae,0x92,0x85,0x92,0xad,0x98,0x8c,0x8f,0xae,0x3b,0xb2,0xb0,0x1c,0x13,0x1c,0x0f,0x06,0x05,0x0a,0x0e +,0x0b,0x07,0x09,0x0f,0x0f,0x14,0x13,0x14,0x19,0x17,0x1e,0x1c,0x13,0x14,0x1d,0x2f,0x4f,0x34,0x3d,0x3c,0x38,0x44,0x4f,0xbb,0xbc,0xb3,0xa8,0xa6,0xa3,0xab,0xa5,0x99 +,0xa0,0x9f,0x9e,0xad,0x9f,0x9e,0xa5,0xad,0xee,0x63,0xc0,0x3e,0x27,0x59,0xab,0xa4,0xb6,0x94,0x86,0x85,0x8c,0x92,0x87,0x85,0x8b,0x98,0x8f,0x87,0x98,0x34,0xa8,0xa0 +,0x30,0x12,0x10,0x1d,0x17,0x0b,0x09,0x0d,0x0d,0x11,0x14,0x1b,0x1d,0x1d,0x22,0x2b,0x20,0x11,0x15,0x12,0x11,0x16,0x16,0x1a,0x15,0x0f,0x16,0x25,0x2d,0x21,0x1e,0x17 +,0x15,0x23,0x2b,0x38,0x36,0x31,0x64,0x58,0x4e,0xad,0xb6,0x3e,0x29,0x28,0xa9,0xa0,0x41,0x5b,0x9c,0x8f,0x99,0x90,0x86,0x83,0x87,0x8d,0x87,0x81,0x85,0x8c,0x8a,0x83 +,0x88,0xa6,0xab,0xa5,0x7a,0x24,0x14,0x19,0x1f,0x11,0x0e,0x18,0x17,0x10,0x14,0x18,0x18,0x14,0x0f,0x0e,0x12,0x17,0x17,0x1f,0x13,0x16,0x1b,0x1d,0x2e,0x20,0x1f,0x1c +,0x19,0x24,0x79,0xce,0x59,0x36,0x38,0x3b,0xd6,0xb5,0xad,0xae,0x36,0x22,0x30,0x57,0x2b,0x33,0xdf,0xaf,0x2a,0x21,0xa3,0x8e,0x91,0xa4,0x8e,0x82,0x86,0x8c,0x85,0x82 +,0x83,0x8d,0x8e,0x85,0x86,0x93,0xee,0xbd,0xc4,0x21,0x16,0x15,0x19,0x11,0x0b,0x10,0x13,0x11,0x0e,0x0e,0x18,0x1a,0x1c,0x1d,0x1e,0x20,0x1d,0x1e,0x20,0x1a,0x1a,0x18 +,0x16,0x16,0x14,0x1b,0x1e,0x1f,0x2b,0x2b,0x26,0x2f,0x36,0x33,0x2f,0x2e,0x31,0xd8,0xd7,0x66,0xbd,0xc3,0x28,0x1c,0x3a,0xb5,0xc0,0x24,0x2c,0xaa,0xa2,0xab,0x94,0x89 +,0x86,0x8c,0x8b,0x83,0x82,0x87,0x8e,0x87,0x87,0x92,0xa6,0xa3,0x9a,0xf9,0x1a,0x18,0x1c,0x1d,0x17,0x12,0x15,0x13,0x1a,0x1e,0x2f,0x28,0x17,0x19,0x1f,0x31,0x38,0x25 +,0x1f,0x20,0x28,0x3c,0x37,0x60,0x2c,0x23,0x27,0x2a,0x72,0xcf,0x45,0x41,0x2c,0x2f,0x54,0x33,0x79,0xcf,0x61,0x33,0x6d,0xbd,0x2f,0x1c,0x23,0x3e,0x31,0x18,0x16,0xbf +,0x9f,0xb8,0xb4,0x94,0x87,0x8a,0x8d,0x88,0x84,0x87,0x95,0x8c,0x86,0x89,0x9b,0xa9,0x9a,0xad,0x2a,0x18,0x1c,0x18,0x0e,0x0c,0x12,0x16,0x14,0x0f,0x13,0x1c,0x1e,0x25 +,0x1f,0x19,0x16,0x16,0x1f,0x2e,0x2b,0x1f,0x1c,0x29,0x2b,0x27,0x26,0x27,0x28,0x27,0x2f,0x42,0x51,0xdc,0xbb,0xdd,0xd7,0xd5,0xb3,0xbe,0xdf,0xb2,0xb3,0x45,0x37,0xa7 +,0xa0,0x35,0x1e,0xce,0x9a,0x9c,0x51,0x9f,0x89,0x86,0x8b,0x89,0x81,0x83,0x8b,0x8e,0x88,0x88,0x8f,0xab,0xac,0xb1,0x4b,0x19,0x19,0x1b,0x11,0x0d,0x0d,0x0f,0x0e,0x0f +,0x10,0x1a,0x18,0x1a,0x16,0x15,0x1b,0x1e,0x1f,0x19,0x15,0x18,0x23,0x2c,0x2b,0x1f,0x1d,0x1e,0x2a,0x22,0x24,0x2d,0x27,0x2c,0x4d,0xe7,0xc3,0xcf,0x4b,0xd4,0xd0,0xa7 +,0xa4,0x47,0x1b,0x23,0xbd,0xbd,0x28,0x2a,0xbf,0xbc,0x3d,0xa8,0x88,0x85,0x8b,0x8e,0x86,0x81,0x85,0x8a,0x86,0x83,0x88,0x93,0x9b,0x99,0xa8,0x46,0x26,0x26,0x18,0x0d +,0x0a,0x0d,0x0e,0x17,0x19,0x15,0x12,0x11,0x19,0x1b,0x1e,0x1a,0x1e,0x1f,0x1c,0x1d,0x1e,0x2d,0x41,0x2b,0x27,0x1e,0x1c,0x22,0x28,0x3f,0xcf,0xd5,0x4b,0x59,0xe8,0xde +,0xae,0xc8,0x40,0xcb,0xbb,0x6e,0x26,0x2d,0x9f,0xa0,0x22,0x17,0x46,0x9e,0xb6,0x45,0x9f,0x89,0x8c,0x8f,0x86,0x81,0x84,0x8c,0x8a,0x83,0x84,0x93,0xa8,0xa6,0xa6,0xb8 +,0x33,0x1e,0x13,0x0a,0x09,0x0f,0x15,0x10,0x0d,0x0c,0x10,0x20,0x22,0x1c,0x19,0x12,0x15,0x1f,0x1f,0x1c,0x19,0x1a,0x31,0x4f,0x3a,0x29,0x24,0x26,0x3c,0x3e,0x39,0x41 +,0x2e,0x37,0x57,0xc0,0xae,0xb2,0x36,0x3c,0xa5,0x9f,0xca,0x2b,0x3f,0xae,0x34,0x18,0x2a,0xb9,0xb8,0x2c,0xbc,0x8a,0x87,0x8f,0x8b,0x83,0x81,0x85,0x89,0x87,0x83,0x89 +,0x93,0x91,0x92,0xa6,0x43,0x2e,0x27,0x1e,0x0d,0x0d,0x0e,0x0f,0x13,0x14,0x15,0x15,0x12,0x12,0x16,0x17,0x19,0x17,0x1c,0x18,0x1e,0x1e,0x20,0x24,0x1f,0x1c,0x19,0x1c +,0x27,0x29,0x29,0x3b,0x4b,0xb9,0xbb,0x5a,0x57,0x79,0x34,0x33,0xd9,0xab,0xbf,0x2d,0x2d,0xab,0x9d,0x3a,0x1d,0x2e,0xc3,0x4d,0x3f,0x9b,0x8a,0x8e,0x92,0x87,0x81,0x82 +,0x88,0x89,0x83,0x83,0x8a,0x94,0x95,0x97,0xaa,0xe5,0x3b,0x19,0x09,0x07,0x0e,0x16,0x16,0x13,0x0e,0x12,0x17,0x21,0x2e,0x19,0x11,0x11,0x15,0x1b,0x1f,0x1e,0x1c,0x2a +,0xfe,0xc9,0x30,0x1c,0x1a,0x27,0x37,0x43,0x35,0x29,0x2b,0x31,0xc1,0xa0,0xad,0x34,0x22,0x5f,0xa7,0x48,0x21,0x3b,0xc8,0x2f,0x19,0x1f,0xbe,0xcc,0x2d,0xbb,0x8e,0x89 +,0x8f,0x8f,0x85,0x81,0x83,0x88,0x86,0x83,0x88,0x8e,0x8f,0x8d,0x9c,0x4c,0x29,0x1e,0x13,0x0f,0x0f,0x13,0x16,0x10,0x0f,0x0f,0x10,0x12,0x1a,0x1d,0x16,0x11,0x12,0x1a +,0x21,0x1e,0x1f,0x1f,0x1e,0x1d,0x1b,0x1e,0x1f,0x2b,0x32,0x33,0x3d,0x5a,0xc4,0xff,0x3e,0x61,0xc7,0x36,0x29,0xc3,0xa0,0xa7,0x3a,0x50,0xa5,0xab,0x28,0x16,0x2f,0xba +,0x36,0x30,0x9d,0x8c,0x8d,0x90,0x88,0x81,0x84,0x8d,0x8d,0x85,0x84,0x87,0x8a,0x8d,0x91,0x9d,0xa5,0xb6,0x23,0x0d,0x08,0x0a,0x0f,0x17,0x15,0x13,0x12,0x16,0x19,0x1c +,0x15,0x0f,0x0c,0x0d,0x1c,0x25,0x27,0x1f,0x20,0x3c,0x40,0x2b,0x20,0x1c,0x19,0x1e,0x43,0xaf,0xb7,0x38,0x2f,0x3a,0xcd,0xaf,0x2a,0x17,0x2b,0xb2,0x38,0x2d,0xa5,0x9c +,0x68,0x1e,0x38,0xc1,0x29,0x13,0x2d,0x98,0x8b,0x8b,0x8e,0x88,0x82,0x82,0x86,0x84,0x82,0x88,0x90,0x8d,0x88,0x8c,0x9d,0xa1,0xbf,0x22,0x1b,0x0f,0x0a,0x0a,0x11,0x0e +,0x0c,0x10,0x0f,0x15,0x1d,0x1a,0x13,0x0e,0x16,0x31,0x21,0x1f,0x31,0x27,0x4c,0xc4,0xea,0x35,0x1a,0x17,0x1f,0x2e,0x33,0x33,0x25,0x15,0x22,0xaa,0xb8,0xa9,0x25,0x1c +,0x5c,0x84,0xc3,0x08,0x80,0x93,0xa2,0x91,0x28,0x1e,0x15,0x9b,0x2f,0x22,0x09,0x00,0x3d,0x06,0x0e,0x09,0x07,0x0a,0x00,0x0e,0xd7,0xab,0x1d,0x2e,0x0d,0x0a,0x2e,0xa2 +,0x26,0x16,0x37,0x91,0xac,0x1c,0x8a,0x80,0x82,0x91,0x88,0x80,0x88,0x84,0x83,0x81,0x8a,0x8b,0x88,0x83,0x80,0x84,0x82,0x82,0x85,0x86,0x9d,0x9a,0x8a,0x9c,0x34,0x1c +,0x20,0x1a,0x18,0x0c,0x0a,0x3d,0x28,0x0e,0x07,0x08,0x29,0x2a,0x09,0x08,0x09,0x00,0x04,0x06,0x07,0x07,0x03,0x00,0x03,0x00,0x06,0x0c,0x04,0x02,0x07,0x0a,0x04,0x03 +,0x06,0x16,0x1c,0x0a,0x07,0x00,0x0a,0xae,0xec,0x17,0x1a,0xb6,0x96,0x9a,0x90,0x81,0x81,0x87,0x85,0x82,0x84,0x81,0x81,0x82,0x80,0x83,0x85,0x85,0x87,0x89,0x81,0x82 +,0x80,0x90,0xe3,0x86,0x80,0x82,0x84,0x8a,0x84,0x87,0x89,0x82,0x80,0x81,0x82,0x81,0x81,0x84,0x84,0x85,0x83,0x95,0x4c,0xa5,0x1f,0xa8,0xb8,0x29,0xa0,0xa9,0x0e,0x08 +,0x17,0xd6,0xa6,0x0a,0x05,0x13,0x0a,0x00,0x07,0x08,0x03,0x00,0x02,0x01,0x00,0x00,0x01,0x02,0x00,0x04,0x01,0x01,0x05,0x01,0x05,0x17,0x06,0x01,0x00,0x03,0x28,0x0f +,0x00,0x04,0x04,0x03,0x03,0x03,0x04,0x05,0x03,0x02,0x03,0x00,0x11,0x27,0x04,0x20,0xb0,0x1f,0xa3,0x9f,0x92,0x80,0x86,0x8a,0x86,0x91,0x8c,0x80,0x85,0x86,0x8c,0x8c +,0x83,0x85,0x87,0x83,0x82,0x84,0x80,0x89,0x8a,0x80,0x82,0x82,0x80,0x82,0x81,0x86,0x89,0x80,0x80,0x83,0x82,0x87,0x8f,0x85,0x84,0x83,0x8e,0x5e,0xec,0xb8,0x1a,0x30 +,0x8d,0x17,0xcb,0x94,0x0a,0x0d,0x67,0xe5,0xa4,0x20,0x13,0x57,0x13,0x21,0x91,0x91,0x99,0x96,0xd9,0xac,0x8b,0x87,0x8e,0x9b,0xa8,0x85,0x86,0xb7,0x86,0x83,0x90,0x84 +,0x8c,0x42,0x53,0xb1,0x8f,0x8f,0x2c,0x46,0x44,0x0d,0x2e,0x9d,0xae,0x39,0x16,0x09,0x02,0x08,0x08,0x17,0x07,0x00,0x0c,0x03,0x00,0x03,0x01,0x02,0x04,0x01,0x01,0x00 +,0x01,0x05,0x02,0x00,0x01,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,0x06,0x00,0x05,0x07,0x00,0x02,0x06,0x01,0x02,0x03,0x03,0x0d,0x0e,0x0e,0x06,0x05,0x26,0xa0,0x1f +,0x20,0x19,0x18,0x0e,0x24,0x35,0xa3,0x8d,0x16,0x8f,0x88,0x8f,0x81,0x83,0x88,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x81,0x81,0x81 +,0x80,0x80,0x82,0x80,0x80,0x89,0x82,0x87,0x8b,0x80,0x8a,0x8a,0x8e,0x8f,0x8f,0x71,0xb9,0x8c,0x90,0x9f,0x41,0x10,0x0d,0x14,0x49,0x14,0x4f,0x18,0x03,0xa3,0x24,0x18 +,0x98,0x1b,0x16,0x3a,0x12,0x2e,0x19,0x1f,0x17,0x07,0x09,0x07,0x02,0x08,0x0e,0x0f,0x0c,0x00,0x03,0x00,0x35,0x1a,0x0b,0xff,0x04,0x05,0x27,0x0c,0x0f,0x31,0x15,0x14 +,0x07,0x0c,0x0a,0x04,0x18,0x18,0x09,0x14,0x0e,0x0b,0x0b,0x16,0x1f,0x19,0xb8,0x03,0x19,0x8f,0x1b,0xc1,0xb8,0x09,0x1f,0x4a,0x2e,0x45,0x27,0xb2,0x18,0x0f,0x3e,0x1e +,0x1e,0xa2,0x5c,0xcd,0x2b,0x2a,0x27,0xa7,0x82,0xc6,0x8b,0x8c,0x0e,0xa5,0x8e,0x3c,0xa7,0x32,0x25,0xc7,0xaa,0x8f,0xa0,0x93,0x87,0x93,0x8d,0x83,0x85,0x83,0x83,0x85 +,0x8a,0x80,0x85,0x8d,0x80,0x81,0x85,0x80,0x90,0xa4,0x87,0x8d,0x8e,0xb0,0x2e,0x1f,0x06,0x0e,0x13,0x06,0x0e,0x15,0x06,0x05,0x02,0x04,0x00,0x1d,0x10,0x01,0x18,0x02 +,0x01,0x29,0x12,0x0f,0x38,0x0c,0x0e,0x1c,0xa9,0xa8,0x38,0xaa,0xa5,0x58,0x93,0x8e,0x9f,0x8f,0x8f,0xac,0x41,0x89,0x3a,0xa1,0x80,0xa4,0x93,0x87,0xa9,0x8e,0x82,0x84 +,0x81,0x87,0x82,0x93,0x92,0x83,0x8c,0xa0,0x89,0x9a,0xcd,0xbb,0x2e,0x24,0x49,0x88,0x20,0xa7,0x91,0x0c,0xb3,0x92,0x1b,0x36,0x41,0x1a,0x22,0x4e,0x9a,0x25,0x2f,0xcc +,0x0f,0x18,0xc0,0x10,0x0e,0x0e,0x0a,0x03,0x0f,0x22,0x01,0x9b,0x9c,0x0c,0xbd,0x2a,0x0c,0x3d,0xc9,0x3a,0x18,0x19,0x1c,0x04,0x10,0x17,0x06,0x0d,0x14,0x03,0x0e,0x10 +,0x0c,0x0b,0x9b,0x97,0x1c,0x80,0x8e,0x97,0x81,0x83,0x86,0x80,0x83,0x84,0x83,0x80,0x85,0x98,0x89,0x9a,0x4d,0x92,0x9a,0x20,0x3b,0x14,0x09,0x03,0x25,0x0b,0x06,0xc2 +,0x05,0x02,0x16,0x06,0x09,0x27,0x12,0x0c,0x08,0x0f,0x07,0x0a,0x2e,0x0e,0x05,0x25,0x0e,0x10,0xb6,0x48,0x1c,0xd0,0x89,0x16,0x9b,0x82,0x1f,0x97,0x8b,0x2b,0xac,0x9c +,0xc9,0x5d,0x9e,0x8d,0xc9,0xa0,0x8e,0xe2,0x9a,0x85,0xa4,0x9c,0x95,0xb4,0x21,0x90,0x8e,0x19,0x87,0x9c,0x0e,0x9b,0xb8,0x1c,0x9f,0xae,0x49,0x37,0xc4,0xbf,0x3a,0x92 +,0xa1,0x18,0xc8,0x2f,0x15,0xb2,0x4b,0x17,0x0f,0xa7,0x0c,0x0f,0x8f,0x0d,0x17,0xad,0x0a,0x09,0x23,0x18,0x18,0x24,0xc9,0x14,0x14,0xdf,0x16,0x2f,0x95,0x2b,0x24,0x1b +,0x0f,0x04,0x22,0x3a,0x00,0x3d,0x14,0x00,0x3d,0x4a,0x18,0x94,0x95,0x93,0x8e,0x85,0x87,0x8a,0x80,0x84,0x86,0x80,0x83,0x85,0x81,0x84,0x89,0x8f,0x80,0x48,0xa0,0x88 +,0x13,0x33,0xab,0x09,0x13,0x18,0x09,0x0d,0x0e,0x17,0x06,0x0e,0x14,0x03,0x0e,0x18,0x07,0x0c,0x0a,0x07,0x02,0x26,0x1c,0x06,0x9d,0x14,0x0d,0x92,0x33,0x27,0x9b,0xac +,0xb9,0x9b,0x8d,0xa6,0x9f,0x89,0xa8,0xb6,0x8f,0x4c,0xb5,0x46,0x34,0x1c,0xb3,0x9c,0x17,0x87,0x8d,0xaf,0x84,0x8f,0xa6,0x8d,0x8f,0x9b,0x9e,0x91,0x33,0x2d,0x98,0x42 +,0x33,0x95,0xd0,0x36,0x46,0x2c,0x1a,0xa3,0x9c,0x0a,0x8f,0xb6,0x0b,0x91,0xa1,0x2f,0x9a,0xad,0x40,0x45,0x9e,0x36,0x15,0xcf,0x0f,0x0a,0x1a,0x0d,0x16,0x12,0x14,0x0b +,0x39,0x45,0x06,0x90,0xc0,0x0b,0x94,0x2a,0x0a,0x2e,0x18,0x15,0x19,0x2b,0x0e,0x0b,0x18,0x0b,0x10,0x2d,0x3e,0xf8,0xcf,0xaa,0xb6,0x89,0x87,0x90,0x80,0x83,0x84,0x80 +,0x83,0x85,0x80,0x83,0x8a,0x8a,0x94,0xb9,0xba,0x9e,0x2f,0x1e,0x25,0x14,0x0a,0x0b,0x06,0x05,0x19,0x06,0x0b,0x21,0x00,0x0e,0x3a,0x0b,0x16,0x1e,0x0e,0x0d,0x17,0x1a +,0x0d,0x1d,0x16,0x0c,0x1a,0x1b,0x37,0x3c,0xde,0x27,0x96,0x93,0x29,0x81,0x94,0x3e,0x85,0x9d,0x28,0x94,0xbd,0xdd,0xa7,0xa3,0xa4,0xce,0x96,0x9d,0xaa,0x91,0x90,0xc4 +,0x9a,0xd0,0x9a,0x89,0x20,0x89,0x8a,0x25,0x8d,0x9f,0x2f,0x9e,0xbe,0x37,0x39,0xf3,0x5e,0x2d,0x59,0xd8,0x29,0x25,0xbc,0x13,0x28,0x18,0x34,0x9f,0x0d,0x8e,0xad,0x10 +,0x9c,0x2e,0x11,0xf9,0x1a,0x16,0x19,0x16,0x1a,0x14,0x1f,0x25,0x15,0x14,0x2f,0x0d,0x1a,0x11,0xd3,0x1b,0x0e,0x90,0x0e,0x11,0xb2,0x0a,0x0e,0x4d,0x0f,0x22,0xb6,0xce +,0x9d,0x8c,0x8c,0x89,0x87,0x83,0x85,0x86,0x86,0x86,0x80,0x8b,0x82,0x80,0x91,0x85,0x8b,0xaf,0x90,0xbc,0x2d,0x1e,0x0e,0x16,0x0c,0x0b,0x14,0x05,0x09,0x0b,0x02,0x0a +,0x01,0x1f,0x0b,0x0c,0xb8,0x04,0x0f,0x4c,0x06,0x1a,0x2e,0x19,0x21,0x23,0xc8,0x1c,0x46,0x98,0x21,0x64,0xac,0x16,0xa5,0xc8,0x8b,0x9d,0xaa,0x84,0xf5,0xac,0x89,0x3c +,0xc5,0x9d,0xdd,0xaa,0xa6,0x8b,0xa9,0x97,0x88,0xad,0x9f,0x8e,0x32,0xb0,0x2d,0x8e,0xea,0x29,0x80,0x1d,0xca,0x8b,0x1b,0xbc,0x9c,0x24,0xdf,0xc3,0xab,0x31,0x60,0x9e +,0x1c,0x32,0x47,0x0d,0x22,0x1a,0x9b,0x1a,0x22,0x8c,0x10,0xab,0x96,0x09,0x19,0x27,0x0a,0x15,0x1c,0x23,0x0d,0x2a,0x6d,0x0d,0xdb,0x1a,0x0a,0x0f,0x0d,0x26,0x06,0x3a +,0xd9,0x06,0x3d,0x1e,0x0c,0x41,0x2a,0x1e,0x39,0xa8,0x9c,0x9a,0x83,0x87,0x86,0x80,0x86,0x82,0x85,0x81,0x85,0x8f,0x80,0x88,0x94,0x80,0xa4,0xeb,0x9a,0x2e,0x22,0x19 +,0x2f,0x0d,0x0a,0x27,0x05,0x0a,0x0b,0x01,0x06,0x02,0x1f,0x0b,0x0d,0xb8,0x03,0x1d,0x9c,0x0d,0x24,0x15,0x10,0x1f,0x24,0x9f,0x12,0x2a,0xb1,0x0c,0xad,0x29,0x38,0xa1 +,0x9f,0x8f,0x12,0x92,0x8b,0xbd,0x84,0x99,0x2a,0x8f,0x9c,0xa4,0x58,0xbc,0x96,0xaf,0x88,0x9f,0x41,0x97,0x1f,0xab,0xca,0xa9,0xa6,0x24,0x89,0x4e,0xa1,0x81,0xc2,0xac +,0x2b,0x0a,0xc7,0xc3,0x9d,0xc8,0x0f,0x26,0x16,0xae,0x3a,0x11,0x16,0x0b,0xb1,0x17,0x4b,0x92,0x0b,0xb8,0x96,0x20,0x95,0xb7,0x34,0x36,0x18,0xb1,0x24,0xd5,0x33,0x06 +,0x23,0x1e,0xa6,0x95,0x9f,0xec,0x07,0x9a,0x9d,0xbf,0x87,0xaf,0x17,0xbe,0x26,0xba,0x96,0x9d,0xb3,0x10,0x22,0x1a,0xc7,0x99,0x15,0x0f,0x09,0xa4,0x98,0xba,0x86,0x1c +,0x2b,0x8d,0xb5,0x9b,0x4d,0x0f,0x1f,0x1f,0x93,0x98,0xb8,0x9e,0x0b,0x11,0x24,0xfc,0x9e,0x41,0xb2,0x05,0x25,0x85,0xab,0x8c,0x9a,0x0d,0x4d,0xa3,0x95,0x98,0xbf,0xc2 +,0x0f,0xad,0x91,0x3a,0xa3,0x1c,0x1c,0x10,0xac,0x8a,0x26,0x8a,0xb4,0x16,0x89,0x89,0x8c,0x95,0x1d,0x16,0x19,0x92,0x90,0x26,0xf8,0x0d,0x0b,0xbc,0x2b,0xb5,0x16,0x3d +,0x14,0x05,0x97,0x1c,0x2d,0x4f,0x04,0x13,0x40,0x9d,0xa4,0x18,0x1e,0x0c,0x2b,0x98,0x1b,0x18,0x0a,0x09,0x28,0x1d,0x8a,0xbe,0xb9,0x88,0x22,0x8d,0x84,0x90,0x89,0x36 +,0x2b,0xb1,0x91,0x80,0x8f,0x9d,0xd8,0x27,0x94,0x9f,0xa0,0x39,0x27,0x8e,0x1e,0x95,0x88,0x45,0x8d,0xae,0x1b,0x95,0xa3,0x99,0x2f,0x2e,0xb4,0x1a,0xad,0x1e,0x0d,0x2a +,0x0e,0x20,0x0d,0x13,0x41,0x06,0x92,0x9f,0x14,0xa3,0x18,0x0e,0x27,0x10,0x28,0x19,0x24,0x11,0x05,0xc9,0x5d,0x48,0x32,0x03,0x0c,0x06,0xb1,0x9c,0x10,0x8e,0x1f,0x24 +,0x88,0x9d,0x8d,0x8e,0x9a,0x98,0x33,0x8d,0x8f,0x9a,0x87,0x3b,0x9c,0x86,0x98,0x8a,0x3a,0x8f,0x8a,0xa0,0x80,0x9a,0x9d,0x8b,0x25,0x9e,0xa1,0xed,0xae,0x09,0x1a,0x08 +,0x12,0xb7,0x0c,0x09,0x03,0x00,0x06,0x03,0x21,0x0d,0x00,0x15,0x03,0x1e,0xeb,0x06,0x23,0x0f,0x15,0xdd,0x1f,0x9c,0x28,0x3c,0xa0,0x1f,0x95,0xa2,0x2c,0xaa,0x16,0x8c +,0x8e,0x90,0x80,0xa4,0x8e,0x81,0x8a,0x80,0x8b,0x95,0x91,0xa1,0x86,0x92,0x88,0x87,0xac,0x9c,0x36,0x1d,0xa0,0x2d,0x89,0x2e,0x22,0x84,0xaf,0x88,0x90,0x1a,0xce,0x2b +,0xb9,0x9e,0x1b,0x35,0x0a,0x1d,0x32,0x0f,0x2b,0x11,0x09,0x10,0x00,0xa7,0x2b,0x13,0xa0,0x03,0x15,0x4f,0x3a,0x9c,0x17,0x0f,0x1a,0x15,0x98,0x1b,0x1c,0x2c,0x13,0x22 +,0x1a,0x1a,0x2c,0x0c,0x9d,0x19,0x0f,0x84,0xc5,0xa4,0xa4,0x2b,0xb2,0xac,0x8c,0x8e,0xd6,0x92,0x38,0x94,0x86,0x9d,0xc2,0x2b,0x24,0x4d,0x1d,0x88,0x92,0x37,0x85,0x4e +,0x9a,0x87,0x99,0x9d,0x2c,0xe3,0x9c,0x5a,0x8c,0x2d,0x1b,0x22,0x1c,0x1b,0x1c,0x0c,0x0a,0x01,0x21,0x2f,0x08,0x8c,0x36,0x1f,0x28,0x2e,0x9b,0x97,0x8b,0x8d,0x29,0x8e +,0x88,0x85,0x81,0x8c,0x99,0xa5,0x8e,0x8a,0x93,0x8d,0x8c,0x1f,0x8d,0x91,0x91,0x98,0x48,0x2f,0x0a,0x0d,0x2a,0x0d,0x0e,0x05,0x01,0x07,0x06,0x0d,0x06,0x01,0x02,0x03 +,0x03,0x28,0x05,0x12,0x13,0x0c,0x18,0x0e,0xb9,0x2f,0x15,0x2a,0x1b,0x3f,0x9b,0xa6,0xa8,0x1a,0xdc,0x99,0xa0,0x99,0xa0,0x17,0x95,0x91,0x8e,0x83,0x94,0x8a,0xb2,0x9d +,0x87,0x91,0x8b,0x8a,0x9d,0x94,0x9c,0x8a,0x89,0x97,0xa6,0x3d,0xbc,0x91,0xa0,0x97,0xaf,0x1c,0x9f,0xd5,0x95,0x96,0x6e,0x3e,0x30,0xb9,0xa8,0x46,0x9f,0xbb,0x1a,0x2c +,0x1a,0xa4,0xab,0x1c,0x0e,0x07,0x19,0x2c,0xd7,0x1d,0x12,0x0d,0x17,0x22,0x28,0x3a,0x0f,0x15,0x17,0x1d,0x45,0x9f,0x32,0x0c,0x1d,0x2e,0x4f,0xa0,0xeb,0x0f,0x09,0x1d +,0x55,0x56,0x5d,0x2e,0x0f,0x26,0xac,0x24,0xe3,0xb4,0xa5,0x33,0x2a,0xa1,0x9e,0x9a,0x97,0x97,0x9f,0x56,0x99,0x89,0x9f,0xef,0x4b,0xce,0xad,0xa2,0x92,0x29,0x0a,0x28 +,0x21,0x3b,0xaf,0xc1,0x1e,0x0f,0xbf,0x95,0x9d,0xab,0x48,0x1c,0x24,0x96,0x87,0x96,0x2e,0xb4,0xa3,0x9e,0x8e,0x85,0x8c,0xda,0x8d,0x86,0x8d,0x88,0x82,0x85,0x8b,0x8b +,0x8d,0x8f,0x8c,0x89,0xae,0x1a,0x1f,0x3e,0x20,0x0d,0x11,0x06,0x01,0x02,0x0d,0x11,0x00,0x05,0x08,0x01,0x07,0x1a,0x0f,0x07,0x07,0x0a,0x0b,0x19,0x2a,0x0d,0x07,0x11 +,0x1d,0x29,0x22,0x1f,0x16,0x0f,0x26,0x97,0x91,0x2e,0x3e,0x9d,0xa4,0x99,0x84,0x84,0x9d,0x94,0x8a,0x8c,0x8a,0x84,0x8a,0xa4,0x9a,0x99,0xa5,0x9d,0x8d,0xa4,0xde,0x3e +,0x9a,0x8f,0xae,0x8e,0x92,0xb5,0x2f,0x9b,0x84,0x9a,0xb4,0x99,0x58,0x38,0x8f,0x91,0x30,0x1c,0x27,0x0d,0x10,0x9f,0x14,0x06,0x06,0x12,0x23,0x17,0xbc,0x30,0x0d,0x0b +,0x1d,0x9b,0xad,0x19,0x3a,0x16,0x0d,0x1e,0xb3,0x1d,0x07,0x13,0x0c,0x04,0x4a,0x27,0x07,0x0d,0x23,0x27,0x0f,0x9e,0xa7,0x20,0x31,0xbd,0x95,0x92,0x9c,0x95,0xb4,0x41 +,0xc4,0x8f,0x8d,0x3d,0xa4,0xb9,0x12,0xaa,0x8b,0x9f,0x4f,0xa6,0x9f,0x1c,0x8c,0x84,0x9d,0xda,0xb9,0xa2,0xa4,0x91,0x93,0x46,0x22,0x3b,0xbe,0x9c,0x33,0x23,0x15,0x06 +,0x0a,0xb7,0x46,0x0d,0x11,0x2e,0x10,0x2c,0x82,0x8c,0x9f,0x96,0x8e,0x8e,0x85,0x80,0x85,0x8e,0x89,0x8b,0x8c,0x87,0x88,0x88,0xca,0x2b,0xa4,0x9d,0x1d,0x13,0x2f,0x11 +,0x02,0x20,0xbd,0x0c,0x0a,0x09,0x07,0x06,0x45,0x25,0x03,0x04,0x05,0x06,0x0c,0x2c,0x15,0x03,0x00,0x07,0x15,0x18,0x0e,0x18,0x0d,0x04,0x19,0x9a,0x9d,0xc1,0xa0,0xc9 +,0x34,0x8d,0x81,0x91,0x96,0x8e,0x99,0x95,0x87,0x83,0x93,0xab,0xa0,0x9c,0x9c,0x8e,0x90,0xa7,0x22,0xdf,0x8a,0x8f,0x8c,0x8c,0x90,0xd6,0xa9,0x85,0x86,0x8d,0x95,0xa9 +,0x40,0x97,0x87,0x93,0xcf,0x48,0x13,0x15,0xc0,0xa2,0x1f,0x03,0x08,0x15,0x33,0x3a,0x5e,0x38,0x0a,0x0c,0x45,0xaa,0xbe,0x3c,0x14,0x08,0x10,0xa9,0xa2,0x1d,0x1b,0x0f +,0x06,0x0f,0x2b,0x20,0x0c,0x0c,0x05,0x07,0x10,0x5a,0x47,0x0b,0x0b,0x19,0xd9,0xda,0x9b,0xa0,0x32,0x1d,0xa7,0x8b,0x8e,0x93,0x9d,0x23,0x31,0x8f,0x8d,0x9a,0xbe,0x2c +,0x13,0xce,0x8a,0x88,0xae,0x23,0x20,0xd0,0xa1,0x8d,0x8d,0xec,0x26,0xbd,0x8d,0x8d,0x8e,0x91,0xc7,0x15,0x34,0x9a,0x9e,0x4d,0x26,0x0b,0x0a,0x2c,0xbf,0x31,0x34,0x33 +,0x22,0x39,0x9a,0x84,0x8e,0x9e,0xa4,0x8f,0x83,0x81,0x80,0x85,0x91,0x8f,0x86,0x87,0x87,0x8c,0xbc,0x10,0x1c,0xbb,0xee,0x19,0x08,0x01,0x00,0x09,0x1c,0x0f,0x01,0x01 +,0x01,0x07,0x0e,0x22,0x18,0x08,0x05,0x0b,0x1a,0x20,0x38,0x1c,0x08,0x07,0x1e,0xb9,0xb3,0x35,0x12,0x0e,0x10,0x24,0xcf,0xd8,0x23,0x2a,0x28,0xa3,0x88,0x87,0x89,0x9f +,0x9c,0x8f,0x87,0x82,0x84,0x8f,0xad,0xa1,0x8b,0x82,0x82,0x89,0xbd,0xe6,0xa2,0x8c,0x89,0x9c,0x1a,0x09,0x19,0x98,0x8a,0x9f,0xb4,0x2f,0x33,0xa9,0x8f,0x89,0x96,0x56 +,0x2f,0xc3,0x95,0x8a,0x8e,0x4e,0x0d,0x11,0x44,0xa9,0x6f,0x14,0x07,0x04,0x0a,0x15,0x29,0x18,0x0b,0x05,0x05,0x1b,0x6d,0xab,0x20,0x0a,0x09,0x1a,0x9b,0x8d,0x9f,0x1d +,0x0c,0x0f,0x55,0xa1,0xaa,0x14,0x08,0x09,0x1e,0x9d,0xa3,0x3b,0x0b,0x06,0x18,0x9a,0x97,0x9f,0x39,0x20,0x6a,0x9d,0x81,0x82,0x88,0x9d,0xc8,0x9f,0x88,0x84,0x89,0xe0 +,0x12,0x2c,0xad,0x8e,0x9a,0xe1,0x0f,0x09,0x15,0x24,0x52,0x46,0x13,0x0a,0x10,0x37,0x8e,0x97,0x56,0x1e,0x18,0xa7,0x89,0x82,0x8c,0x4a,0x3e,0x91,0x84,0x81,0x81,0x91 +,0xb6,0xa4,0x8b,0x85,0x84,0x9b,0x29,0x19,0x36,0x91,0x8f,0x9c,0x1b,0x0d,0x05,0x16,0xb3,0x57,0x0d,0x04,0x03,0x0d,0x1d,0x1e,0x11,0x00,0x02,0x03,0x0a,0x0b,0x0a,0x05 +,0x01,0x02,0x02,0x19,0x45,0x1a,0x0a,0x04,0x0e,0xa5,0x8d,0x9e,0x3a,0x15,0xc2,0x8e,0x85,0x84,0x92,0xa3,0xaa,0x90,0x8d,0x89,0x8f,0xa7,0x2b,0xad,0x95,0x8b,0x8c,0xb5 +,0x27,0x20,0x8f,0x86,0x86,0x93,0xe8,0xbf,0x91,0x86,0x82,0x8b,0xa0,0xba,0xa8,0x93,0x8b,0x8b,0xa5,0x23,0x16,0x2c,0xc2,0xaf,0x23,0x1d,0x0e,0x0d,0x28,0x10,0x33,0x98 +,0xe8,0x00,0xb6,0x84,0x2a,0x9a,0x1d,0x1c,0x0e,0x15,0x18,0x0c,0x19,0x00,0x05,0x00,0x01,0x04,0x02,0x01,0x00,0x00,0x02,0x00,0x04,0x05,0x07,0x19,0x15,0x1b,0xb1,0x9c +,0x9d,0x94,0x8f,0x87,0x8a,0x81,0x80,0x8c,0x85,0x81,0x80,0x82,0x82,0x83,0x8a,0x87,0x84,0x85,0x85,0x8f,0x96,0x85,0x82,0x85,0x87,0x88,0x8b,0x8d,0x93,0x94,0x9d,0x8d +,0x9f,0x31,0x31,0x38,0x66,0x0f,0x09,0x04,0x02,0x07,0x03,0x02,0x01,0x00,0x01,0x00,0x0b,0x0f,0x0b,0x06,0x00,0x04,0x02,0x01,0x01,0x01,0x0b,0x03,0x08,0x0f,0x12,0x1b +,0x02,0x06,0x0c,0x16,0x1f,0x0a,0x1a,0x1b,0x15,0x2e,0x2f,0x85,0x82,0x83,0x8b,0x8f,0x80,0x8b,0x8a,0x88,0x86,0x80,0x82,0x80,0x80,0x80,0x81,0x89,0x82,0x81,0x81,0x80 +,0x84,0x82,0x86,0x85,0x83,0x86,0x80,0x82,0x82,0x83,0x89,0x80,0x91,0x98,0x8c,0x88,0x80,0x8a,0x82,0x91,0x90,0x9d,0x20,0xa2,0x5c,0x3f,0x11,0x07,0x0f,0x04,0x06,0x01 +,0x06,0x2c,0x07,0x0c,0x06,0x02,0x05,0x00,0x03,0x00,0x1d,0x17,0x03,0x07,0x03,0x06,0x01,0x01,0x04,0x02,0x02,0x01,0x03,0x05,0x00,0x04,0x00,0x1c,0x27,0x0d,0x16,0x01 +,0x10,0x01,0x05,0x0b,0x21,0x90,0x1d,0x1b,0x23,0x2b,0x24,0x0b,0x14,0x26,0xdb,0x38,0x1b,0xc3,0x1b,0x27,0x0d,0x54,0x80,0x8e,0x86,0xbf,0xa4,0xa1,0x2c,0x8d,0x8a,0x80 +,0x84,0x8c,0x8b,0x89,0x84,0x91,0x8f,0x85,0x84,0x83,0x89,0x84,0x8d,0x90,0x9a,0x92,0x80,0x84,0x80,0x8f,0x99,0x88,0x9e,0x8f,0x87,0x83,0x81,0x8e,0x8b,0x89,0x85,0xa6 +,0x76,0x8e,0x8f,0x88,0x96,0x95,0xac,0x9c,0xb3,0xbe,0x80,0x87,0x82,0xb1,0x3a,0x97,0xae,0x95,0x8d,0x83,0x85,0x92,0x90,0x90,0x87,0x99,0xc5,0x8e,0x99,0x8a,0xab,0x57 +,0x27,0x26,0x20,0x11,0x85,0x9c,0x5b,0x0c,0x00,0x0d,0x00,0x09,0x08,0x1c,0x1e,0x03,0x03,0x01,0x08,0x01,0x00,0x02,0x04,0x0b,0x00,0x00,0x00,0x00,0x01,0x00,0x18,0x0b +,0x03,0x04,0x00,0x03,0x00,0x03,0x00,0x08,0x0e,0x01,0x01,0x01,0x02,0x02,0x00,0x05,0x0b,0x10,0x03,0x01,0x00,0x03,0x04,0x07,0x98,0xbe,0x2c,0x09,0x03,0x15,0x0d,0x38 +,0x4d,0x8d,0x82,0x98,0x9f,0x93,0x88,0x8d,0x8e,0x82,0x81,0x80,0x84,0x85,0x84,0x81,0x82,0x82,0x80,0x80,0x80,0x89,0x84,0x81,0x82,0x80,0x81,0x80,0x80,0x80,0x83,0x82 +,0x80,0x83,0x84,0x80,0x81,0x80,0x89,0x96,0x8f,0x84,0x8b,0x87,0x80,0x83,0x85,0x29,0xaf,0x97,0xa7,0x96,0x9d,0x83,0x8b,0xec,0x20,0x19,0xd5,0x16,0x2a,0x4e,0xdc,0x3b +,0x02,0x05,0x00,0x10,0x06,0x16,0xa8,0x10,0x10,0x00,0x02,0x02,0x03,0x05,0x06,0x38,0x10,0x01,0x03,0x00,0x07,0x01,0x05,0x08,0x0b,0x0b,0x00,0x01,0x01,0x0c,0x05,0x2a +,0x5e,0x10,0x0d,0x00,0x09,0x04,0x0f,0x16,0x26,0x93,0x2f,0x14,0x0c,0x11,0x29,0x1a,0x46,0xb9,0x9c,0x3f,0x0a,0x0b,0x1e,0xac,0x5b,0x85,0x8a,0x8f,0x55,0x11,0xb2,0x48 +,0x92,0x8f,0x8a,0x82,0x91,0xb1,0x2e,0xa3,0x96,0xa2,0x8f,0x8f,0x89,0xa7,0x1f,0x1e,0xa6,0x97,0x95,0x80,0x8e,0x8c,0x29,0x20,0xc9,0xe9,0x8f,0x9b,0x89,0x86,0x9d,0x36 +,0x1e,0xb2,0xb1,0xba,0x9b,0xa7,0x9f,0x13,0x0d,0x0c,0x2e,0x3b,0xa1,0x86,0xaf,0xad,0x08,0x0e,0x14,0x1c,0xca,0x59,0x8c,0x96,0x23,0x14,0x17,0x5c,0x41,0xb5,0xa2,0xae +,0xb9,0x0d,0x0e,0x14,0xaf,0xc3,0x8a,0x89,0x98,0xab,0x0a,0x3e,0x48,0x9d,0x92,0x8f,0x83,0x8f,0xc3,0x34,0xd3,0x98,0x97,0x8b,0x8d,0x8d,0x9b,0x20,0x1e,0xcd,0x95,0xa5 +,0x84,0x8a,0x8f,0x48,0x0f,0xbb,0x7e,0x96,0x9b,0x8d,0x86,0xa9,0x26,0x12,0x3f,0xb5,0xba,0x9d,0xec,0x9d,0x1d,0x08,0x07,0x1b,0x30,0x1e,0x8b,0xa0,0xe8,0x0c,0x07,0x1b +,0x1a,0xba,0x3e,0x98,0x8f,0x28,0x17,0x11,0xca,0xa5,0xa8,0xa6,0x41,0xa7,0x0e,0x08,0x0a,0xee,0x34,0xb5,0x86,0xab,0xb5,0x08,0x11,0x21,0x31,0x9b,0xab,0x8a,0x92,0x2f +,0x1a,0x13,0xa0,0xa2,0x99,0xa7,0xbd,0xa1,0x0e,0x0e,0x0c,0xb7,0x2d,0x93,0x88,0xde,0xd1,0x06,0x17,0x1e,0x61,0x90,0x9e,0x87,0x98,0x23,0x15,0x0c,0xa7,0xaa,0x97,0xad +,0xe6,0xb7,0x0f,0x0c,0x0d,0xda,0x37,0x8b,0x8f,0xda,0x42,0x07,0x1b,0x1b,0xa8,0x95,0x99,0x86,0xa2,0x23,0x11,0x13,0x9b,0xa2,0x92,0xb3,0xc3,0xb9,0x0f,0x0d,0x0c,0xe2 +,0x4e,0x88,0x91,0xb2,0x30,0x08,0x27,0x23,0xa1,0xa1,0x93,0x86,0xae,0x27,0x0e,0x18,0x9b,0xa8,0x8f,0xc5,0xad,0x52,0x0f,0x13,0x0c,0xb3,0x3a,0x8a,0x90,0xc3,0x2f,0x06 +,0x2d,0x1e,0xb5,0x9c,0x91,0x85,0xd9,0x28,0x0e,0x1a,0x9a,0xad,0x92,0x7e,0xb3,0x6e,0x0f,0x18,0x0c,0xa8,0x3b,0x8f,0x8d,0x33,0x3d,0x04,0x2b,0x23,0xc1,0x98,0x9a,0x87 +,0xad,0x29,0x0d,0x16,0x99,0xa1,0x96,0xb1,0xaf,0xd8,0x0f,0x17,0x0f,0xa6,0x2d,0x95,0x8c,0x54,0xd5,0x04,0x20,0x1f,0xca,0x99,0xa6,0x87,0xa9,0x27,0x0e,0x1a,0x92,0xa5 +,0x99,0xab,0xc7,0x63,0x10,0x18,0x0f,0xb5,0x2a,0x9e,0x8b,0x44,0xca,0x07,0x20,0x25,0x47,0x9b,0xac,0x87,0x9d,0x2f,0x16,0x1c,0x9a,0xae,0x99,0xa9,0x49,0xb4,0x1c,0x22 +,0x11,0xc7,0x26,0xab,0x8c,0x40,0xbd,0x09,0x18,0x24,0x49,0x98,0xa8,0x8a,0x9d,0x35,0x1d,0x19,0x9d,0xa2,0x98,0xb7,0x31,0xb7,0x19,0x1c,0x10,0xbe,0x3e,0xae,0x8b,0x49 +,0xb4,0x0b,0x14,0x2d,0x35,0x98,0xba,0x8f,0xa0,0x24,0x1a,0x18,0x9c,0x9d,0x9e,0xc2,0x2a,0xdb,0x16,0x1a,0x15,0xc2,0x35,0xbd,0x8b,0xc8,0xad,0x0b,0x15,0x29,0x3e,0x99 +,0xc9,0x8d,0xa0,0x28,0x1b,0x16,0xa5,0xc3,0xa3,0xad,0x43,0xab,0x1c,0x2d,0x15,0x4b,0x34,0xb4,0x88,0xac,0x9f,0x0f,0x16,0x2f,0x35,0x97,0xae,0x8c,0x9c,0x2c,0x1f,0x10 +,0xac,0xae,0xa4,0xc8,0x24,0xad,0x2a,0x4c,0x1c,0xba,0x72,0xb5,0x8a,0xb1,0x9f,0x10,0x1c,0x69,0x2f,0x9d,0xbf,0x8e,0x9d,0x2f,0x23,0x11,0xa6,0xa5,0xab,0x58,0x24,0xac +,0x28,0x2c,0x1b,0xbf,0x2a,0xbf,0x8b,0xad,0x9f,0x0d,0x1d,0x3d,0x31,0xa1,0xe3,0x8d,0x9f,0x29,0x19,0x10,0xa2,0xad,0xa4,0xe2,0x2c,0xb3,0x19,0x23,0x16,0x35,0x19,0xa9 +,0x8b,0xb9,0xa6,0x0f,0x36,0x36,0xca,0xa3,0xaf,0x8b,0xa6,0x42,0x12,0x18,0xae,0xbf,0x9f,0x25,0x33,0xc5,0x22,0x36,0x19,0xcf,0x1e,0x97,0x92,0x7c,0xaf,0x0e,0x3d,0x2a +,0xc1,0xa9,0x9d,0x8b,0xaa,0x28,0x14,0x33,0x9e,0x9f,0x9d,0x2c,0x49,0x3a,0x1d,0x1c,0x20,0xb1,0x2c,0x8d,0xa0,0xb9,0x2c,0x09,0x25,0x1a,0xae,0xb4,0x92,0x8a,0xaf,0x25 +,0x0f,0xeb,0xa1,0xa0,0xaa,0x1e,0xc8,0x1f,0x1d,0x0f,0x24,0x3b,0x2d,0x8a,0xc8,0x9e,0x1a,0x19,0xdf,0x37,0x99,0xca,0x8e,0x97,0x37,0x14,0x0e,0xb7,0xad,0x99,0xbd,0x28 +,0xc1,0x21,0x37,0x13,0x3d,0x1d,0xa9,0x8d,0x42,0xb4,0x0d,0x4a,0x3b,0xbc,0x9c,0xac,0x86,0x9c,0x53,0x14,0x23,0x95,0x9d,0x93,0x2a,0x2a,0x2b,0x1a,0x26,0x1a,0xb7,0x27 +,0x8e,0x95,0xb1,0x3d,0x0a,0x3c,0x1b,0xa5,0xa3,0x97,0x88,0x46,0x1c,0x0a,0x3d,0x96,0x95,0x8f,0x29,0xcc,0x1e,0x1e,0x1a,0x21,0x6c,0x31,0x8b,0xc1,0xb2,0x14,0x0e,0x1d +,0x0e,0x9d,0xa6,0x87,0x8a,0x2b,0x10,0x09,0xb8,0xa6,0x93,0xa4,0x36,0xa3,0x1e,0x3f,0x1c,0xbb,0x27,0xb5,0x8e,0x2d,0xb8,0x0a,0x27,0x14,0x15,0xef,0x32,0x87,0x98,0x2b +,0x12,0x1a,0x93,0x99,0x8a,0xb4,0xe3,0xba,0x12,0x1f,0x0f,0xbd,0x55,0x8a,0x8e,0xa6,0xd4,0x0a,0x2d,0x12,0x3d,0x7d,0xa3,0x8d,0x1b,0x0e,0x07,0x1f,0x90,0x90,0x86,0xc6 +,0x48,0x1f,0x15,0x23,0x46,0x9c,0xab,0x86,0xa2,0x9f,0x20,0x0f,0x2a,0x1b,0xa4,0xb6,0x8a,0x8a,0x42,0x15,0x04,0x1a,0xbc,0xaa,0xab,0x14,0x66,0x1c,0x29,0x18,0x2e,0xbc +,0xaf,0x89,0x3a,0xaf,0x11,0x27,0x56,0xb4,0x8d,0x97,0x83,0x94,0x18,0x0a,0x0d,0xbf,0xac,0x96,0x9a,0x9c,0xac,0x0c,0x07,0x06,0x2a,0x3b,0x8c,0xaa,0x21,0x0e,0x0d,0xb3 +,0x34,0x94,0x8e,0x89,0x86,0xab,0x15,0x0b,0x18,0x9b,0x8b,0x87,0xa8,0xaa,0x20,0x0d,0x0b,0x1c,0x1b,0x27,0x87,0x8d,0x97,0x0e,0x0b,0x08,0x15,0xaa,0xa6,0x93,0x9b,0x3b +,0x3b,0x37,0xb9,0xa7,0x8f,0x94,0xc2,0xba,0x1f,0x09,0x02,0x31,0x93,0x80,0x89,0x93,0x1b,0x08,0x19,0x08,0x1b,0x21,0xc9,0x8b,0x90,0x3a,0x0b,0x15,0x1c,0x49,0x97,0xa1 +,0xa0,0x1b,0x13,0x0e,0xb3,0x9f,0x8f,0x83,0x8c,0x8e,0x0f,0x12,0x06,0x13,0x8f,0x88,0x86,0xa8,0x14,0x08,0x07,0x1d,0x12,0x3b,0xbb,0x99,0x8c,0xd8,0x18,0x0f,0xb6,0x65 +,0x8a,0x90,0x9c,0x1c,0x0c,0x36,0x27,0x91,0x92,0x8c,0x8e,0x9f,0x38,0x07,0x06,0x05,0x25,0x89,0x89,0x8d,0x1f,0x0d,0x04,0x0e,0x19,0xa1,0x8d,0x9d,0x99,0x1d,0x3a,0x1c +,0x2a,0x98,0x8b,0x81,0x94,0xc8,0x0c,0x0f,0xce,0xc4,0x9b,0xd4,0x99,0x37,0x18,0x08,0x04,0x0d,0x57,0x83,0x8a,0x8c,0x17,0x16,0x13,0x0d,0x2d,0xb2,0x8b,0x91,0xa5,0x41 +,0x29,0xb3,0x30,0xa3,0x9c,0x8d,0x95,0x19,0x09,0x02,0x12,0x34,0x86,0x8f,0x92,0x4d,0x0d,0x13,0x06,0x19,0x43,0x8d,0x85,0x96,0xc4,0x18,0x21,0x1c,0x1e,0xa8,0x8e,0x80 +,0x91,0x3b,0x17,0x1d,0x0a,0xc9,0x90,0x9e,0xad,0x0c,0x18,0x0c,0x12,0x14,0x39,0x89,0x93,0xa4,0x23,0x0f,0x1f,0x34,0x8d,0x94,0x88,0x8d,0x43,0x18,0x0e,0x13,0x1a,0x8d +,0x8f,0x8b,0x37,0x1f,0x14,0x08,0x12,0x1b,0x8f,0x8f,0xbd,0x1a,0x1e,0xaf,0x29,0x3e,0xb1,0x99,0x8c,0x9d,0x2d,0x0a,0x1c,0x29,0x8c,0x87,0x89,0xa3,0x17,0x32,0x09,0x0f +,0x14,0x2a,0x9a,0x9f,0x9b,0x36,0x63,0x20,0x0d,0x2c,0x2b,0x9b,0xb1,0x2b,0x10,0x37,0xaf,0x9d,0x88,0x91,0x8a,0x6d,0x5f,0x17,0x0a,0x16,0x38,0x89,0x8d,0x96,0xba,0x22 +,0x2e,0x0b,0x0e,0x17,0x5d,0x9e,0xc6,0x31,0x15,0x24,0x19,0x96,0x8f,0x8c,0x9d,0x1a,0x2f,0x1f,0x9f,0xa6,0x93,0x8f,0x9d,0xa0,0x1f,0x24,0x19,0x0d,0x21,0x2f,0x9d,0xb2 +,0x34,0x13,0x0d,0x17,0x17,0x9e,0xa5,0x9a,0xc8,0x9f,0xa9,0x26,0xc8,0xc5,0x8f,0x95,0x96,0xb5,0xad,0xa8,0x1e,0x25,0x1d,0x45,0xa9,0xdb,0x2e,0x0c,0x15,0x0b,0x26,0x91 +,0x9e,0x8f,0x32,0xb7,0x1f,0x16,0x29,0x2b,0x8f,0x9d,0x98,0xa3,0x9e,0x9d,0x34,0x22,0x2a,0xa1,0xb6,0x2e,0x19,0x10,0x27,0x1c,0xa4,0x99,0x95,0xa3,0x1b,0x3e,0x0f,0x22 +,0x19,0x34,0x9f,0x9f,0x92,0xf6,0x9f,0xe7,0x41,0xb9,0xd7,0x9a,0xa8,0xab,0x43,0x22,0x3d,0x14,0xac,0xa1,0xb6,0x5a,0x1a,0x6c,0x12,0x16,0x13,0x43,0x9c,0xa2,0xaa,0xbc +,0x9a,0xca,0x38,0x1f,0xbe,0x92,0x9a,0xa0,0x1f,0x2b,0x3b,0x1f,0x9e,0xa5,0x97,0x73,0x1f,0x3c,0x12,0x24,0x13,0x2d,0xab,0xb8,0xb3,0x3c,0xac,0xc7,0x60,0xb3,0xb9,0xaa +,0xbc,0x36,0x1f,0x42,0xb3,0x3a,0x9f,0x9d,0x9a,0xa9,0x3c,0x5f,0x24,0x2c,0x12,0x1f,0x5c,0x37,0x62,0x3c,0xac,0xa8,0xa9,0x5a,0x2e,0xa5,0xb8,0xb9,0x29,0x1b,0x30,0x28 +,0x9f,0x9f,0x9d,0xa9,0x3b,0xb9,0x37,0xdc,0x3f,0x4a,0xb6,0x31,0x46,0x33,0x31,0x49,0x2d,0x4f,0xc6,0xb4,0xcd,0x28,0x29,0x3c,0xb2,0xee,0xbc,0xbf,0xb4,0xb5,0x78,0x40 +,0x5e,0xad,0xae,0x9b,0xad,0xb1,0x69,0x26,0x31,0x3d,0xae,0xcd,0x1c,0x21,0x1e,0x6e,0x4b,0x31,0x57,0x3c,0xb9,0xcb,0x74,0xb3,0x4a,0xdf,0xb2,0xb0,0x9f,0xc9,0xac,0xc7 +,0xbb,0xbb,0x35,0x2f,0x5e,0xb5,0xa6,0xc0,0x2e,0x21,0x1c,0x28,0x36,0x56,0xcc,0x31,0x2b,0x43,0x3e,0xcc,0x3c,0xab,0xaf,0x95,0x9e,0x39,0x37,0x25,0xae,0x9e,0x9b,0xa6 +,0xa3,0xaf,0x28,0x1d,0x2c,0x37,0xc8,0x2a,0x22,0x29,0x1e,0x1f,0x1c,0x3c,0xc6,0xb2,0xc5,0xcd,0x5f,0xad,0xb6,0xb6,0xa4,0x9d,0x95,0xa7,0xa7,0xc6,0xbc,0xfe,0x2f,0xdc +,0xd4,0xdf,0xc8,0x28,0x23,0x19,0x13,0x18,0x15,0x3a,0x33,0xab,0x43,0x30,0xce,0x7a,0x9c,0x98,0x92,0x95,0x9c,0xa9,0xc2,0x3b,0xb4,0xa9,0xa9,0xae,0x38,0x2c,0x1d,0x19 +,0x18,0x1c,0x31,0x3a,0x4c,0x2d,0x1d,0x20,0x24,0x3e,0xa3,0xa5,0x9f,0xa2,0xa8,0xa5,0xb1,0xa7,0x9d,0x98,0xa1,0xce,0xe5,0x3b,0x2c,0x23,0x1a,0x39,0xe3,0xbd,0x2e,0x1a +,0x1a,0x1c,0x22,0x32,0xca,0xa3,0xb2,0x4a,0x3a,0x2e,0xb9,0xb0,0x99,0x9b,0x94,0x90,0xa3,0xb0,0x37,0x3f,0x66,0x49,0x58,0x53,0x48,0x26,0x18,0x1b,0x1f,0x29,0xc2,0x42 +,0x2c,0x28,0x1c,0x24,0x31,0xa4,0x9b,0x9e,0x95,0xa9,0xac,0xc8,0x5c,0xb0,0xb8,0x99,0x9f,0xa2,0xbb,0x1e,0x21,0x1d,0x21,0x43,0x34,0x47,0x32,0x31,0x2f,0x1a,0x32,0x57 +,0xbf,0xb0,0xbe,0x3d,0x2c,0x44,0xb1,0xb0,0x9f,0x96,0x98,0x93,0xb2,0x30,0x26,0x27,0x43,0xfd,0xb2,0xc0,0x55,0x2c,0x16,0x1a,0x2d,0x49,0xc9,0xc8,0xb4,0xd0,0x3d,0x43 +,0x29,0xb3,0xa2,0xa4,0xbc,0x31,0x39,0x1f,0x6c,0xc8,0x9f,0x97,0xa7,0xa3,0x3b,0x2b,0x22,0x1d,0x33,0x45,0xbd,0xa5,0xbc,0xbe,0xc4,0x5e,0x3d,0x23,0x4d,0x37,0x4f,0xc3 +,0x3b,0x33,0x32,0x54,0xb3,0xa4,0xa6,0xb7,0x26,0x2c,0x25,0x7b,0xaa,0xad,0xa4,0xb9,0xae,0x36,0x28,0x30,0x29,0xb3,0xa9,0x9f,0x9c,0xbb,0x36,0x26,0x30,0x33,0x47,0x56 +,0x4f,0x21,0x1c,0x1b,0x35,0xad,0xab,0xa8,0x5f,0xd5,0xef,0x30,0x2f,0x3b,0xa5,0x9f,0xa2,0x9a,0xa7,0x9f,0xd6,0x3c,0x38,0x2f,0xc0,0xc2,0xb0,0xcd,0x27,0x23,0x20,0x24 +,0x2c,0x2e,0x3c,0x3a,0x2d,0x23,0x26,0x6b,0xad,0xa8,0x9f,0xba,0xd8,0x54,0x3d,0xb2,0xaa,0x9c,0x98,0x9b,0x98,0xa6,0xbc,0x4a,0x2b,0x35,0x23,0x28,0x28,0x25,0x2a,0x1c +,0x21,0x27,0x2a,0x35,0x25,0x2d,0x3a,0x43,0x3e,0x53,0xb2,0x97,0x8e,0x94,0x9d,0xba,0xce,0xec,0xac,0x9d,0x9c,0xa6,0xe2,0xd1,0x40,0x25,0x1e,0x17,0x1b,0x24,0x26,0x21 +,0x1f,0x29,0x23,0x57,0x3f,0x60,0x6f,0x2d,0xd2,0x4e,0xa2,0x9f,0x99,0x95,0x9c,0x93,0x96,0x9a,0xc4,0x32,0x2e,0x30,0x3a,0x3f,0x29,0x38,0xe0,0x29,0x1c,0x16,0x1c,0x2c +,0x2e,0x31,0x33,0x37,0x5b,0x3a,0xb3,0xb1,0xa4,0xa1,0xc7,0xae,0xbe,0xa9,0xad,0xa2,0x96,0x97,0x9f,0xcf,0x28,0x24,0x2c,0x2c,0x4d,0x3b,0x2f,0x22,0x20,0x45,0x44,0x38 +,0x1e,0x1f,0x3e,0x31,0xbf,0xc5,0xb9,0xa9,0xae,0xa2,0xae,0xad,0xc3,0xe4,0xb5,0x5b,0xc9,0x55,0xbc,0xa5,0xb3,0xc1,0x3e,0x2e,0x2a,0x31,0x36,0x39,0x35,0x65,0xbe,0xac +,0xa9,0x5a,0x2f,0x25,0x36,0x42,0x54,0x67,0x37,0x47,0xbe,0xa6,0xa1,0xc6,0x2b,0x2b,0x4c,0xcd,0x57,0x6b,0x3c,0xb6,0xa3,0xa2,0xaa,0x57,0x36,0x28,0x68,0xb9,0xc7,0x3e +,0x5f,0x68,0xaa,0xa1,0xb2,0x42,0x24,0x34,0x29,0x2d,0x1f,0x1f,0x2b,0xc9,0xb0,0xca,0x4e,0x33,0x45,0x59,0xb9,0xcb,0xc2,0xa9,0xa1,0x98,0x9c,0xb2,0xd6,0xdc,0xab,0xaf +,0xf8,0x26,0x1c,0x44,0xb1,0xb4,0x3c,0x1b,0x15,0x1e,0xf3,0x4a,0x2d,0x1e,0x1f,0x3e,0xb8,0xa0,0xaf,0xb7,0xef,0xd5,0xa8,0xa6,0xa1,0xa6,0xab,0x97,0x98,0x9f,0xd0,0x1f +,0x29,0x3c,0x38,0x22,0x1c,0x21,0x67,0xc3,0xde,0x1d,0x19,0x2b,0x3b,0xbf,0x38,0x1a,0x1e,0x51,0x9b,0x98,0xa2,0xae,0x3e,0xad,0xa3,0x9f,0xa6,0x3d,0x46,0xae,0x97,0x9a +,0xc5,0x26,0x26,0xae,0x9f,0x67,0x17,0x16,0x24,0x56,0xc9,0x2f,0x2e,0x1f,0x26,0x28,0x35,0x38,0x1f,0x2a,0xcc,0xa2,0x99,0x98,0xa1,0xad,0xa1,0x9e,0xbc,0x2a,0x2c,0xae +,0x9f,0x9b,0xbe,0x3a,0x63,0xb9,0xa6,0x3a,0x17,0x0e,0x17,0x2c,0x38,0x4d,0x2e,0x2b,0x3a,0xb3,0x98,0xa4,0x31,0x18,0x29,0x9e,0x94,0x98,0xda,0x46,0xaf,0xa2,0xa7,0x2e +,0x1f,0x36,0xb3,0xa5,0xbf,0x5e,0x2c,0x20,0x2b,0x28,0x1e,0x0d,0x18,0xd1,0xa5,0xa0,0xae,0x9c,0x9e,0xbb,0xb7,0xbc,0xa6,0xba,0xaf,0x9b,0x9d,0xa8,0x54,0x5b,0x1c,0x33 +,0x93,0x68,0x03,0x00,0x0e,0x9c,0x5e,0x0d,0x0c,0x0d,0xa1,0x82,0x81,0x86,0xc6,0x9b,0x85,0xae,0x25,0x16,0xa3,0xbf,0xad,0x92,0x8d,0xbe,0x0f,0x15,0x5c,0x6f,0x49,0x4f +,0x10,0x1b,0x17,0x30,0x0e,0x01,0x15,0x2a,0x17,0xbb,0x96,0x85,0x89,0x8f,0x88,0x9c,0xa8,0x1c,0x5d,0x8f,0x9f,0xae,0x2c,0x39,0xbc,0xba,0x98,0x1c,0x06,0x0f,0x6f,0xa1 +,0x22,0x0c,0x0d,0x1c,0xa4,0xad,0x29,0xaa,0x97,0x9a,0xfb,0x11,0x18,0xd4,0xa3,0xbf,0x9a,0x83,0x86,0x96,0xb2,0xa8,0x9b,0x9e,0x3f,0x29,0xb3,0xaa,0xff,0x26,0x0a,0x00 +,0x01,0x0b,0x0d,0x0a,0x15,0x9a,0x8a,0x86,0x8f,0x48,0x9b,0x95,0x8c,0x97,0xa2,0x8e,0x90,0x95,0xb2,0xac,0x9b,0x16,0x02,0x06,0x2d,0x9e,0x48,0x22,0x15,0x1d,0x1f,0x21 +,0x2f,0x27,0x19,0xd1,0xa7,0xca,0x72,0xfb,0x8b,0xa5,0xd0,0xaf,0xad,0x90,0x9f,0x9f,0xa7,0x9e,0x9c,0xeb,0xbb,0xaa,0x9b,0xad,0x13,0x08,0x12,0x2c,0x0c,0x02,0x0c,0x7d +,0x53,0xa2,0xab,0xaf,0x94,0xba,0x98,0xdd,0x3e,0xb9,0xd7,0x95,0x92,0x8e,0x8e,0xa9,0x74,0x24,0x3d,0xc1,0x4d,0x74,0x33,0xbd,0x9f,0xc1,0x11,0x07,0x04,0x08,0x03,0x1e +,0x7b,0xb4,0x8e,0xad,0x90,0xa9,0xbd,0x9d,0xbd,0x8d,0x8b,0x8e,0x8f,0x96,0x8b,0x9d,0x3c,0x14,0x06,0x0b,0x0e,0x28,0x36,0x1f,0x11,0x0e,0x17,0x2a,0x0b,0x29,0x8a,0x8f +,0x8c,0x50,0x9f,0x9b,0x53,0xae,0x20,0x99,0x8f,0xae,0x37,0x1f,0xa6,0x9a,0xb6,0x1a,0x0e,0x9c,0x8b,0x8f,0xac,0x29,0x19,0x0b,0x06,0x06,0x04,0x1c,0x8f,0x9a,0xa8,0x1f +,0xad,0x94,0x3c,0x24,0x1b,0x9e,0x86,0x88,0x85,0x8a,0x94,0xc1,0x15,0x10,0x11,0x3f,0x4b,0x2b,0x30,0xb9,0xb6,0x1f,0x0a,0x04,0x06,0x07,0x9a,0x8d,0x8a,0x99,0x24,0xa5 +,0x39,0x2f,0x3c,0xb6,0x8a,0x8c,0x90,0x8e,0x9c,0x97,0xc1,0x3a,0x35,0x2e,0xc2,0x27,0x1e,0x17,0x0b,0x09,0x09,0x0c,0x1f,0x0b,0x26,0x98,0x8d,0x89,0x40,0xab,0xa6,0xac +,0x9f,0xb5,0x8d,0x84,0x94,0xa8,0x30,0x39,0x5b,0x1b,0x19,0x0a,0x1f,0x9e,0x93,0x9b,0x31,0x1d,0x13,0x0e,0x11,0x0f,0x16,0x95,0x91,0x91,0x2e,0x0f,0xd8,0x30,0x25,0x19 +,0xca,0x84,0x84,0x8d,0x9c,0x9f,0x92,0xa7,0x7b,0x51,0x26,0x55,0x1f,0x17,0x19,0x1e,0x24,0x0f,0x06,0x0a,0x07,0x16,0x98,0x98,0x8f,0xbe,0x9d,0x89,0x94,0xa9,0x2b,0xaf +,0x93,0x9e,0xa1,0x99,0x9e,0xaa,0x1c,0x22,0x37,0x3a,0xaf,0x27,0x2f,0x28,0x2b,0x1e,0x0d,0x0d,0x12,0x0e,0x15,0x9d,0x97,0x92,0x47,0x2e,0x9c,0x9c,0x9d,0xc8,0xae,0x8c +,0x8f,0x92,0x95,0xa6,0xa5,0x1e,0x11,0x0a,0x0f,0xae,0xe9,0xc8,0x2e,0x2e,0x37,0x1a,0x12,0x11,0x0c,0x1b,0x8c,0x8a,0x89,0xaf,0x2f,0xdb,0x1a,0x15,0x16,0x47,0x8e,0x8c +,0x8e,0x93,0x9b,0x99,0x39,0x2d,0x27,0xf0,0x95,0xa8,0xcc,0x33,0x28,0x13,0x08,0x06,0x0c,0x09,0x06,0xb7,0x95,0x88,0x8f,0xa3,0x95,0xbd,0x45,0x42,0xb8,0x8a,0x8a,0x8e +,0xab,0x2a,0xb4,0x2e,0x18,0x0e,0x16,0xb5,0xae,0xd9,0x44,0x21,0x1a,0x0b,0x14,0x29,0x32,0x17,0xae,0x8b,0x95,0xa6,0x20,0x51,0xc7,0x5c,0xd1,0xaf,0x8f,0x8a,0x97,0xa7 +,0x4b,0xab,0xa7,0x24,0x15,0x22,0xb1,0xab,0x2d,0x34,0x28,0x1f,0x0e,0x0b,0x14,0x1d,0x2a,0x2b,0x92,0x8e,0x8a,0x98,0xbd,0xc5,0x1e,0x1d,0x20,0xbe,0x89,0x8a,0x9a,0xf4 +,0x2e,0xa9,0x4c,0x2e,0x2e,0x5e,0xb3,0x5e,0xb7,0xaf,0x25,0x17,0x07,0x09,0x08,0x13,0x17,0x1a,0x8f,0x90,0x8a,0x9f,0xa0,0x8e,0xa9,0x38,0x27,0x9d,0x84,0x89,0x94,0xb9 +,0x36,0x23,0x0b,0x13,0x16,0x2b,0x4e,0x21,0x27,0x26,0x39,0x29,0x15,0x22,0x2a,0xc2,0x51,0x59,0x8b,0x93,0x96,0xe7,0x27,0xa2,0x42,0xd8,0x39,0x63,0x94,0x9e,0xa1,0x58 +,0x31,0xb0,0xe9,0xcd,0x64,0xba,0xa9,0x30,0x1d,0x0d,0x0e,0x11,0x16,0x22,0x22,0x30,0xb3,0x5a,0xb6,0x94,0x94,0x93,0xc7,0xcc,0xa4,0xa7,0xbd,0x4d,0xa8,0x94,0xa7,0x55 +,0x2b,0x3a,0xa8,0xb7,0xd3,0x27,0x25,0x39,0x2b,0x2d,0x23,0x2a,0x1e,0x15,0x1b,0x36,0xb2,0x3d,0x2e,0x25,0x9f,0x92,0x8e,0x93,0xb9,0xa7,0xab,0x64,0x33,0x4a,0x91,0x94 +,0xd4,0x30,0x1c,0x2d,0x17,0x10,0x13,0x18,0x3c,0xbb,0xa8,0xb0,0xe2,0xa8,0xb9,0xcc,0xbd,0xc5,0xac,0x27,0x29,0x1e,0xad,0x94,0xb7,0x61,0x19,0x23,0x4c,0x70,0xbf,0xea +,0x92,0x8c,0xa2,0xac,0x4f,0xbc,0x5e,0x1a,0x1a,0x1b,0x33,0x43,0x44,0x45,0x2a,0x30,0xc7,0x44,0x3f,0x53,0xb7,0x51,0x39,0xab,0xae,0x8a,0x8f,0xa3,0xbd,0x17,0x2c,0x21 +,0x12,0x14,0x1d,0x9e,0xa1,0x4b,0x2c,0x2a,0xae,0xf6,0x4e,0x4c,0xdb,0x9b,0x9a,0x9b,0xa2,0xae,0xc9,0x2f,0x28,0x24,0x3d,0xfc,0x28,0x1f,0x27,0x2b,0x9f,0x96,0xa1,0x37 +,0x13,0x29,0x27,0x1b,0x1c,0x2f,0x9c,0x97,0xab,0xb3,0xa9,0xa2,0xa9,0xb0,0xda,0x53,0x9d,0x9a,0x9e,0xb4,0xdb,0x59,0x1f,0x1c,0x19,0x1b,0x1c,0x23,0x27,0x2b,0x1f,0x3b +,0x98,0x9f,0xc2,0x2c,0x4a,0xb3,0x31,0x28,0x2b,0xb7,0x99,0xa0,0xa3,0x3e,0x29,0x7d,0x47,0xbb,0xa9,0x9b,0x92,0x98,0x99,0x9f,0x9f,0x52,0x23,0x1a,0x14,0x16,0x16,0x11 +,0x0b,0x09,0x10,0xa5,0xa3,0xac,0x3f,0x37,0x9f,0xa2,0x9a,0x9b,0x9b,0x8b,0x8c,0x95,0xd3,0x4a,0xb0,0x24,0x1f,0x19,0x32,0xa3,0xb7,0xae,0x36,0x27,0x22,0x19,0x1e,0x17 +,0x2b,0xdc,0x5b,0x23,0x15,0x1a,0xb6,0x97,0xa8,0x3e,0x20,0xc1,0x9c,0xa9,0xb1,0xae,0x8f,0x8b,0xa0,0xcb,0x3a,0xb2,0xaa,0x47,0x36,0x21,0x3c,0xb5,0xc2,0x29,0x16,0x1c +,0x23,0x2d,0x25,0x23,0xe3,0xf0,0x2b,0x2a,0x1a,0x74,0x98,0x98,0x9c,0x36,0xbb,0xa8,0xb6,0xaf,0xb1,0x94,0x96,0xa1,0xaa,0x5a,0xb6,0x4a,0x2f,0x1e,0x11,0x25,0x34,0x52 +,0x1f,0x17,0x27,0x22,0x35,0x2e,0x51,0xad,0xa9,0x9e,0xa6,0x4e,0xac,0x93,0x98,0x9e,0x33,0x57,0xbf,0x28,0x26,0x1e,0xc6,0xca,0x3c,0x44,0x29,0xbc,0xbd,0xd2,0xc2,0xd5 +,0x99,0x99,0xa5,0xf9,0x21,0x2f,0x24,0x23,0x31,0x28,0x33,0x3b,0xd3,0x5e,0x1d,0xc9,0x9f,0x9b,0xa5,0x3b,0xa8,0xa4,0xbf,0x37,0x20,0xde,0x6b,0x2c,0x1f,0x1b,0xb2,0xad +,0x4a,0x22,0x2e,0x9c,0x93,0x99,0x4f,0x3f,0xb1,0xae,0xb3,0x4b,0x35,0x49,0x3a,0x2c,0x12,0x0f,0xd9,0xa2,0xa2,0x3c,0x25,0xb6,0xbb,0xc7,0x29,0x2a,0xb8,0xe7,0xbd,0x40 +,0xb6,0x9b,0xac,0xec,0x23,0xbf,0x8f,0x93,0x99,0xb9,0xc8,0xbc,0x54,0x3f,0x2c,0x38,0x2a,0x1c,0x15,0x08,0x0e,0x3f,0xb7,0xbd,0x1a,0x29,0xc0,0xaa,0xa1,0xc2,0xa2,0x99 +,0x99,0x9a,0xa4,0x9b,0x98,0xaf,0x33,0x1c,0xc1,0xa7,0x61,0x24,0x1c,0x3b,0x64,0x38,0x2c,0x28,0xc8,0xb4,0xe1,0x1e,0x0b,0x2a,0xc1,0xb4,0x3a,0x1e,0xb8,0xc1,0x45,0x32 +,0x3a,0x9e,0x9f,0xa2,0x9f,0x9f,0x8d,0x96,0x9e,0xa7,0xa1,0x92,0xa6,0x2c,0x18,0x19,0x22,0x16,0x12,0x0d,0x0f,0x19,0x1b,0x1e,0x0c,0x2b,0xa5,0x9a,0x9a,0xf5,0x9a,0x99 +,0x9d,0xa5,0xcd,0x96,0x9e,0xab,0xac,0xaf,0x92,0xa4,0xc8,0x2f,0x3e,0x9d,0xa7,0x2b,0x0e,0x13,0x20,0x1c,0x18,0x12,0x21,0x39,0x2e,0x27,0x1a,0xb9,0x9d,0x9f,0xb3,0x3d +,0xa8,0x9e,0x9e,0xa3,0xa4,0x96,0x9c,0xbd,0x4e,0x34,0xad,0xbf,0x55,0x38,0x35,0xa2,0x99,0xa9,0x27,0x16,0x24,0x26,0x20,0x15,0x15,0x22,0x1d,0x21,0x11,0x2b,0xde,0x6d +,0xcb,0x39,0x99,0x97,0x96,0x95,0x98,0x87,0x89,0x92,0xb4,0x2f,0xc3,0x2e,0x20,0x15,0x16,0x2c,0x41,0x33,0x18,0x0d,0x1a,0x28,0x2b,0x19,0x1a,0xd1,0xa6,0x98,0xa8,0x91 +,0x8c,0x93,0xa1,0x39,0x58,0x57,0x39,0x2a,0x2a,0xa4,0x99,0x9e,0xad,0x1e,0x25,0x22,0x33,0x57,0x2c,0xa6,0xa1,0xa4,0x49,0x0d,0x0e,0x1c,0xb3,0xc4,0x18,0x0c,0x0b,0xae +,0x8e,0x85,0x88,0x95,0xa4,0x15,0x1c,0x31,0xa6,0x9c,0x7d,0x68,0x2e,0x7b,0x90,0x90,0xa1,0xaa,0x21,0x1c,0x0c,0x0a,0x1e,0x1b,0x22,0x14,0x06,0x0c,0xb6,0x80,0x8e,0xb0 +,0x6a,0x0f,0x36,0x95,0x80,0x86,0x89,0x82,0x9a,0x04,0x0e,0x9a,0xeb,0x1c,0x10,0x09,0x06,0x03,0x03,0x13,0x4c,0x87,0x95,0x11,0x0b,0x25,0x9a,0x96,0x92,0xa8,0xaf,0x39 +,0x1e,0x9c,0x8b,0x8d,0x99,0x97,0x87,0x8a,0x90,0x9c,0x89,0x8b,0x8a,0xae,0x08,0x09,0x1d,0x8d,0x3e,0x00,0x00,0x00,0x01,0x0d,0x09,0x18,0x8b,0x89,0x96,0xab,0xa9,0x8e +,0x81,0x8e,0x29,0x10,0x13,0x9e,0x9d,0x8b,0x80,0x81,0x8c,0x46,0x1c,0xdd,0x8f,0xa4,0x09,0x06,0x1f,0x98,0x88,0xcc,0xdd,0x9a,0x7c,0x06,0x00,0x00,0x0a,0xcc,0x36,0x0a +,0x07,0x2f,0x8e,0x99,0xad,0x91,0x90,0xb3,0x13,0x17,0x8e,0x80,0x82,0x9a,0x1f,0xaa,0x8a,0x87,0xa9,0xa3,0x93,0x9d,0x44,0x09,0x0d,0x9e,0x88,0x9d,0x0e,0x16,0x9b,0xa4 +,0x1d,0x08,0x06,0x08,0x01,0x00,0x00,0x08,0xbd,0x25,0x08,0x0a,0x9c,0x82,0x81,0x87,0x8c,0x83,0x84,0x8c,0xa3,0x8f,0x82,0x80,0x86,0xc5,0x20,0xa6,0x41,0x1c,0x23,0x2b +,0x24,0x0d,0x07,0x07,0x23,0xe7,0x0c,0x01,0x00,0x09,0x0b,0x03,0x01,0x0c,0xad,0xab,0x31,0x1f,0x99,0x82,0x8a,0x9b,0xa1,0x88,0x80,0x81,0x80,0x82,0x80,0x88,0xad,0x2b +,0xbf,0x8f,0x9b,0x15,0x03,0x04,0x0f,0x16,0x05,0x06,0x07,0x06,0x01,0x02,0x00,0x0d,0x8f,0xa3,0x18,0x16,0xad,0x94,0x9c,0x9b,0x99,0x8f,0x89,0x8f,0x98,0x89,0x84,0x8a +,0x5b,0x2b,0xa1,0x8e,0x8b,0x90,0x99,0x9f,0xa0,0x43,0x17,0x25,0xb0,0xaf,0x1e,0x0c,0x0c,0x0f,0x2f,0xca,0x2f,0x0f,0x05,0x04,0x01,0x03,0x0e,0x35,0xc7,0x2e,0xf8,0x91 +,0x91,0x99,0x9f,0x96,0x98,0xa8,0x45,0xbc,0x8a,0x82,0x87,0x90,0x93,0x8d,0x89,0x90,0x9f,0xbd,0xa7,0x3d,0x43,0xa3,0x9d,0x95,0xc4,0x12,0x06,0x06,0x06,0x02,0x02,0x07 +,0x0a,0x0f,0x07,0x03,0x04,0x17,0xab,0xa6,0xa9,0x9b,0x85,0x83,0x8d,0x92,0x89,0x82,0x85,0xa1,0x54,0x99,0x8a,0x9d,0xcd,0x9b,0x8a,0x84,0x94,0x43,0x26,0x3b,0x26,0x09 +,0x04,0x0c,0x29,0x62,0x12,0x09,0x09,0x17,0x22,0x11,0x09,0x12,0xd9,0x46,0x18,0x09,0x22,0x98,0xa2,0x37,0x21,0xa0,0x9d,0x37,0x41,0x94,0x87,0x86,0x91,0x78,0x9a,0x88 +,0x89,0xa0,0xa7,0x88,0x81,0x85,0x8f,0x9a,0x9e,0xac,0x29,0x0a,0x05,0x0d,0x13,0x09,0x07,0x07,0x0b,0x13,0x0b,0x08,0x06,0x0a,0x0a,0x05,0x05,0x1a,0x97,0x92,0x95,0x9a +,0x8f,0x8b,0x94,0x9a,0xa4,0x8d,0x83,0x84,0x83,0x83,0x83,0x85,0x8f,0x98,0x9a,0xaa,0xca,0x27,0x27,0x1c,0x0f,0x0c,0x06,0x0c,0x0c,0x05,0x02,0x03,0x04,0x0b,0x20,0x36 +,0x37,0x2e,0x33,0x76,0x4b,0x22,0x25,0x57,0xba,0xb6,0xa7,0x8a,0x86,0x88,0x91,0x9f,0x91,0x8e,0x93,0x9c,0x95,0x8b,0x9c,0xba,0xad,0x9b,0x90,0xb0,0x35,0x1e,0x19,0x1d +,0x2e,0xb4,0xb4,0x2f,0x0e,0x0a,0x10,0x1a,0x27,0x1d,0x0e,0x0a,0x0b,0x12,0x0f,0x11,0x15,0x1a,0x1c,0x1b,0x21,0x37,0xa5,0x90,0x94,0x9f,0x8d,0x87,0x87,0x89,0x8a,0x86 +,0x8a,0xa5,0xb2,0x8f,0x84,0x84,0x90,0xc9,0x1c,0x15,0x1a,0x14,0x0f,0x11,0x15,0x21,0x17,0x16,0x35,0xcc,0x3b,0x19,0x09,0x06,0x07,0x0b,0x0d,0x0a,0x17,0x29,0x2f,0x19 +,0x21,0xa2,0x9e,0xdc,0x2e,0xa3,0x92,0x8b,0x8e,0x9f,0x8b,0x85,0x8b,0x8d,0x88,0x83,0x81,0x83,0x89,0x97,0xad,0xf8,0x25,0x1b,0x16,0x20,0x0d,0x01,0x08,0x26,0x63,0x1d +,0x08,0x04,0x08,0x0f,0x0e,0x08,0x09,0x0e,0x12,0x0a,0x11,0x3a,0x98,0x92,0x93,0x94,0x96,0x8e,0x92,0x95,0x8d,0x88,0x8c,0x9d,0xa5,0x92,0x87,0x82,0x87,0x95,0xaa,0x9c +,0x97,0x9e,0x3f,0x22,0x2c,0x1c,0x0b,0x09,0x1a,0x32,0x1c,0x0d,0x0d,0x16,0x16,0x0f,0x0d,0x12,0x20,0x13,0x05,0x05,0x17,0xaa,0xcb,0x2f,0x2a,0xb5,0x93,0x99,0x9d,0xa2 +,0xa9,0xa6,0xa8,0xaf,0x95,0x86,0x84,0x89,0x8d,0x92,0x8b,0x8b,0x8f,0x8d,0x97,0x99,0xbf,0x2b,0x33,0x9f,0x91,0x31,0x0b,0x04,0x0b,0x0e,0x06,0x04,0x04,0x09,0x08,0x05 +,0x08,0x1b,0xa9,0x36,0x1a,0x1c,0x32,0xad,0xa1,0x95,0x9c,0x96,0x97,0xb5,0xb3,0x94,0x86,0x89,0x97,0xb3,0xc4,0xa9,0x9e,0x96,0x9b,0xa8,0x97,0x97,0xab,0xa1,0x89,0x84 +,0x88,0x98,0x5b,0x4b,0x3b,0x29,0x16,0x16,0x1c,0x0c,0x04,0x02,0x09,0x19,0x0d,0x06,0x04,0x05,0x0b,0x0e,0x0f,0x12,0x34,0x2d,0x1e,0x40,0xb1,0x90,0x8f,0x91,0x8e,0x8c +,0x8a,0x8f,0x87,0x83,0x81,0x81,0x87,0x8d,0x8a,0x85,0x86,0x8f,0xbb,0x2c,0xdd,0x41,0x14,0x0d,0x0e,0x12,0x09,0x04,0x02,0x0a,0x1f,0x0e,0x06,0x06,0x08,0x09,0x04,0x06 +,0x0d,0x2a,0x29,0x11,0x0f,0xcb,0x8b,0x8e,0xa2,0xb6,0x9b,0x8d,0x8d,0x95,0x92,0x8c,0x8c,0x8e,0x8a,0x84,0x81,0x81,0x84,0x8d,0x93,0x8c,0x93,0xa3,0xb8,0xb2,0xcd,0x14 +,0x05,0x08,0x29,0xb5,0x15,0x04,0x01,0x06,0x0a,0x05,0x02,0x03,0x09,0x09,0x05,0x05,0x14,0xc5,0xe1,0x2c,0x23,0xae,0x94,0x92,0x97,0x94,0x8b,0x8b,0x88,0x87,0x83,0x80 +,0x82,0x86,0x96,0x99,0x8b,0x8a,0x8f,0xa6,0xae,0xbe,0x45,0x28,0x1c,0x3e,0x5f,0x1c,0x0a,0x0a,0x0c,0x0a,0x07,0x06,0x0a,0x0f,0x0d,0x08,0x07,0x0f,0x15,0x0e,0x0c,0x0b +,0x15,0x1a,0x1b,0x26,0x4d,0xc4,0xa1,0x97,0x94,0x8a,0x85,0x86,0x87,0x89,0x88,0x86,0x85,0x85,0x87,0x86,0x84,0x87,0x8d,0x8a,0x86,0x8b,0x9d,0x26,0x0d,0x0a,0x08,0x06 +,0x03,0x02,0x03,0x02,0x01,0x02,0x08,0x0a,0x09,0x09,0x07,0x0b,0x12,0x15,0x14,0x15,0x37,0xb5,0xa8,0x95,0x88,0x84,0x85,0x87,0x8c,0x8d,0x88,0x86,0x87,0x8b,0x8f,0x8d +,0x92,0x8d,0x86,0x85,0x89,0x8e,0x95,0xae,0x47,0x20,0x13,0x14,0x10,0x0b,0x06,0x06,0x0d,0x0f,0x0c,0x09,0x07,0x08,0x08,0x09,0x0c,0x0c,0x0a,0x0e,0x12,0x29,0xbf,0xbe +,0xb6,0x5b,0xbb,0xa1,0x96,0x8c,0x8c,0x89,0x87,0x89,0x92,0x8d,0x84,0x82,0x84,0x86,0x8a,0x90,0x94,0x9e,0x3a,0x1d,0x16,0x14,0x16,0x12,0x22,0x47,0x47,0x33,0x1a,0x12 +,0x1a,0x22,0x1b,0x0f,0x0a,0x0b,0x0c,0x13,0x24,0x27,0x27,0x2b,0x16,0x0b,0x0f,0x15,0x1c,0x1c,0x12,0x22,0xaf,0xa1,0x96,0x8d,0x88,0x89,0x8b,0x92,0x95,0x8d,0x8d,0x91 +,0x9e,0xa2,0x8f,0x86,0x83,0x89,0x8d,0x8c,0x8e,0x9e,0xc9,0x28,0x14,0x0e,0x0a,0x09,0x0b,0x0f,0x0b,0x05,0x02,0x06,0x1a,0x22,0x0e,0x07,0x05,0x0a,0x1b,0x4b,0xbc,0xb9 +,0xc3,0x40,0xd8,0xa3,0x9b,0x94,0x96,0xae,0xec,0x9e,0x8c,0x89,0x8a,0x98,0xa4,0x96,0x8c,0x87,0x87,0x89,0x8c,0xa4,0xef,0xa8,0x8e,0x89,0x8f,0x31,0x0a,0x0d,0x29,0xa9 +,0x4c,0x17,0x0c,0x09,0x06,0x0d,0x1f,0x24,0x10,0x03,0x00,0x03,0x15,0x55,0x23,0x0f,0x0a,0x0e,0x2b,0xa7,0x93,0x8f,0x97,0x68,0x2a,0x9f,0x86,0x83,0x89,0x93,0x9a,0x8d +,0x88,0x86,0x82,0x86,0x99,0x74,0xb7,0x90,0x8d,0x95,0xa6,0x2b,0x1e,0x21,0x31,0x3a,0x16,0x09,0x04,0x0b,0x19,0x14,0x09,0x04,0x07,0x0c,0x10,0x12,0x12,0x0f,0x08,0x07 +,0x15,0xca,0x99,0xa7,0x24,0x19,0x40,0x93,0x85,0x82,0x86,0xa1,0x27,0xb6,0x89,0x82,0x83,0x91,0x3b,0x1f,0xb4,0x85,0x81,0x80,0x9a,0x0f,0x16,0xa1,0x87,0x86,0x97,0x1c +,0x0c,0x0b,0x1b,0xab,0x9d,0x26,0x04,0x01,0x00,0x09,0x1d,0x1a,0x07,0x00,0x01,0x02,0x14,0x9a,0x9e,0x18,0x07,0x08,0x1b,0x9d,0x87,0x8f,0xa9,0xc3,0x91,0x80,0x81,0x80 +,0x85,0x94,0x92,0x89,0x84,0x81,0x85,0x95,0xad,0xa3,0x91,0x88,0x8c,0x3f,0x0c,0x0a,0x0e,0x0d,0x07,0x06,0x04,0x03,0x04,0x08,0x0d,0x14,0x0a,0x01,0x01,0x04,0x15,0xad +,0xcd,0x0d,0x09,0x18,0x9c,0x86,0x81,0x86,0x9c,0xcb,0xa4,0x86,0x81,0x82,0x88,0x9c,0xa0,0x89,0x80,0x80,0x83,0xae,0x0c,0x1f,0x5a,0x98,0x5d,0x16,0x0b,0x00,0x0a,0x08 +,0x9c,0x2d,0x0a,0x0c,0x00,0x0a,0x0f,0x06,0x16,0x42,0x4a,0x9f,0x80,0x83,0x88,0x80,0x2e,0xac,0x87,0x95,0x80,0x82,0x80,0x85,0x53,0x17,0x8e,0x8d,0x0f,0x00,0x00,0x00 +,0x04,0x03,0x03,0x00,0x09,0x5a,0x0f,0x10,0x19,0x03,0x03,0x0f,0x09,0x10,0xa1,0x8c,0x81,0x84,0x8f,0x96,0x8b,0x82,0x80,0x91,0xa2,0x83,0x80,0x80,0x81,0x84,0x87,0x92 +,0x93,0x9e,0x12,0x12,0x0b,0x02,0x00,0x02,0x09,0x1a,0x37,0x09,0x06,0x0a,0x21,0x9d,0x8d,0x55,0x0b,0x01,0x03,0x2b,0x0d,0x09,0x10,0x18,0x22,0x57,0xa5,0xaa,0x97,0xbc +,0xa4,0xad,0xa7,0x8a,0x87,0x88,0x83,0x92,0x6e,0x20,0x69,0xbe,0x0d,0x0f,0x11,0x98,0x9a,0x99,0x80,0x81,0x80,0x85,0x97,0x92,0xa8,0x12,0x15,0x0e,0xc4,0x8b,0x27,0x19 +,0x1b,0x1e,0x2b,0x02,0x02,0x00,0x00,0x02,0x08,0xdf,0xd4,0xb3,0x94,0x9d,0x3a,0x05,0x04,0x0b,0x10,0x1a,0x05,0x36,0x81,0x81,0x81,0xa0,0x1b,0xaa,0x32,0x98,0x82,0x85 +,0x80,0x82,0x80,0x82,0x80,0x83,0x85,0x8f,0x23,0x07,0x0d,0x35,0x1e,0x10,0x0d,0x09,0x02,0x01,0x00,0x00,0x00,0x09,0x02,0x01,0x00,0x21,0xbe,0x1d,0x09,0x01,0x0d,0x18 +,0x23,0xa7,0x87,0x82,0x80,0x85,0x83,0x82,0x81,0x80,0x81,0x81,0x83,0x85,0x81,0x82,0x89,0x9b,0x9b,0x1c,0x06,0x00,0x11,0x10,0x17,0x0b,0x00,0x03,0x06,0x86,0x99,0x37 +,0x0e,0x00,0x04,0x04,0x04,0xa3,0x8e,0x8f,0x28,0x01,0x02,0x0d,0x8d,0x8d,0x7a,0x12,0x09,0x27,0x80,0x85,0x80,0x8e,0x16,0x21,0xaa,0x96,0x8c,0x80,0x8a,0x2c,0x0a,0x37 +,0x85,0x80,0x84,0x45,0x04,0x00,0x12,0xb7,0xaa,0x8f,0x95,0x9f,0x13,0x04,0x33,0x1f,0x1d,0x13,0x00,0x03,0x06,0x96,0x83,0x8e,0x9e,0x08,0x17,0x1d,0x1b,0x8c,0xa9,0xe5 +,0xbd,0x09,0x07,0x1c,0x8a,0x81,0x8a,0xd6,0x13,0x0b,0x12,0x18,0xc9,0x97,0x1b,0xdf,0x0b,0x1a,0x10,0x15,0x91,0x8e,0xa1,0x13,0xc2,0x87,0x81,0x93,0xad,0xaf,0x8e,0x6d +,0x0c,0x91,0x80,0x83,0x8b,0x40,0x14,0x09,0x95,0x80,0x91,0x21,0x05,0x00,0x0a,0x07,0xb7,0x8d,0x96,0x9c,0x00,0x04,0x01,0x3a,0x9b,0x0a,0x00,0x03,0x0f,0x49,0x89,0x87 +,0x9f,0x11,0x05,0x06,0x1c,0x8c,0x84,0x82,0x8a,0x16,0x34,0x87,0x82,0x80,0x81,0x8d,0x43,0x2d,0x9b,0xaf,0x87,0x82,0x80,0x92,0x11,0x09,0x1a,0x9d,0xc2,0x18,0x00,0x05 +,0x00,0x13,0x1b,0x0c,0x03,0x00,0x01,0x01,0x02,0x3f,0xa7,0x1e,0x0c,0x0d,0x10,0x26,0x80,0x8c,0x8c,0x49,0x20,0x89,0x87,0x84,0x80,0x81,0x80,0x86,0xcd,0x0b,0xbb,0x87 +,0x85,0x8a,0xdb,0x22,0x2c,0x9a,0x2f,0x9a,0xad,0x09,0x04,0x00,0x0c,0xc2,0xb7,0x13,0x01,0x05,0x00,0xb9,0x93,0x99,0x99,0x00,0x04,0x02,0x0b,0x8e,0x82,0x84,0x8f,0x0c +,0x02,0x0c,0x8b,0x80,0x85,0x87,0xaa,0xc0,0x94,0x86,0x94,0x89,0xae,0x0e,0x0b,0x14,0xae,0x8a,0x90,0x2a,0x14,0x00,0x0e,0x9a,0x87,0x9a,0x00,0x04,0x07,0x08,0x7a,0x97 +,0x81,0x85,0x32,0x08,0x09,0x0a,0x8e,0x86,0x82,0x93,0x8e,0x89,0xb8,0x88,0x8c,0x80,0xc5,0x16,0x25,0x04,0x0c,0x07,0x16,0x21,0x00,0x0f,0x18,0x09,0x14,0x09,0x07,0x19 +,0x26,0xbd,0x8e,0x83,0x86,0x9b,0x10,0x04,0x0f,0x2f,0xa6,0x85,0x84,0x81,0x95,0x1a,0x16,0x89,0x80,0x8b,0x8f,0x4f,0x27,0x29,0x97,0x8f,0x82,0xa4,0x8a,0xbf,0x10,0xbc +,0xdc,0xba,0x0b,0x04,0x13,0x2e,0xab,0x4f,0x0f,0x0c,0x00,0x04,0x03,0x0a,0x1b,0x9b,0x36,0x02,0x02,0x01,0x09,0x3e,0x9b,0x41,0x1a,0x08,0x1f,0xa4,0x8b,0x80,0x84,0x80 +,0x8e,0x8d,0x9d,0xa4,0x81,0x87,0x8c,0x92,0x8c,0x89,0x8a,0x95,0x99,0x27,0x35,0x9c,0xae,0x9c,0xa0,0x9d,0x1a,0x06,0x11,0x02,0x0a,0x2f,0x13,0x07,0x02,0x02,0x0a,0x03 +,0x0a,0x29,0x85,0xa7,0x01,0x04,0x00,0x13,0x2e,0x98,0xb6,0xa0,0xa5,0x5d,0x9d,0x9a,0xae,0x88,0x90,0x93,0x80,0x88,0x80,0x81,0x87,0x9b,0x92,0x81,0x83,0x83,0x89,0xc8 +,0x2b,0x23,0x19,0x0b,0x2f,0x89,0x3e,0x05,0x00,0x00,0x05,0x07,0x20,0x1a,0x0e,0x09,0x08,0x00,0x07,0x2a,0x49,0x0e,0x0d,0xcf,0x9c,0x80,0x8b,0x97,0x90,0x99,0x85,0x86 +,0x8f,0x88,0xa8,0xde,0xac,0x25,0xac,0x88,0x80,0x83,0xaf,0x0a,0x12,0x8f,0x96,0x8e,0x87,0x8e,0xa0,0x15,0x0b,0x0f,0x9e,0xe1,0x0b,0x10,0x08,0x0b,0x06,0x03,0x09,0x11 +,0x1d,0x04,0x04,0x0b,0x12,0x19,0x1f,0x0d,0x34,0xa3,0x95,0x80,0x8e,0x88,0x99,0xbe,0x9b,0x8d,0x81,0x85,0x80,0x80,0x93,0x17,0xb3,0x35,0x8b,0x8b,0xba,0xa1,0x1d,0x24 +,0x07,0x1d,0x49,0x31,0x0e,0x0b,0x05,0x08,0x03,0x13,0x1f,0x0a,0x01,0x0d,0x8a,0xe9,0x39,0x04,0x0c,0xb5,0xbe,0x91,0x8e,0x8a,0x80,0x90,0x0e,0x1d,0x9b,0x82,0x83,0x80 +,0x89,0x94,0x89,0x8d,0x8c,0x83,0x87,0x96,0xa2,0x0d,0x02,0x13,0xc3,0x18,0x03,0x00,0x1a,0xb9,0x0d,0x02,0x00,0x04,0x0d,0x08,0x01,0x17,0x8e,0x79,0x19,0x0c,0x06,0xc6 +,0xa6,0x8d,0x88,0x88,0x84,0x8a,0x97,0x87,0x80,0x82,0x80,0x8a,0x89,0x97,0x2c,0x9b,0x9c,0xa1,0x9b,0x83,0x91,0x26,0x15,0x00,0x1c,0x36,0x05,0x01,0x17,0x19,0x0f,0x02 +,0x06,0x09,0x09,0x17,0x0b,0x3b,0x1d,0x13,0x0d,0x0c,0x1c,0x18,0x22,0x45,0xaa,0x92,0xb5,0x14,0xb9,0x95,0x94,0x8e,0x83,0x81,0x8a,0xb1,0xd6,0xa6,0x96,0x88,0x81,0x81 +,0x81,0x8a,0x95,0xb8,0xbe,0x8b,0x9d,0x94,0x96,0x23,0x1b,0x0b,0x0b,0x09,0x03,0x0c,0x0b,0x07,0x05,0x01,0x00,0x04,0x05,0x06,0x01,0xba,0x95,0x1f,0x0b,0x00,0x12,0x32 +,0xa8,0x8b,0x8f,0x80,0x89,0x4a,0x1e,0xae,0x85,0x82,0x84,0x88,0x83,0x87,0x86,0x85,0x89,0x8d,0x81,0x83,0x8a,0x9b,0x8e,0xc7,0x1a,0x16,0x0c,0x0e,0x1d,0xac,0x04,0x01 +,0x00,0x00,0x05,0x05,0x0e,0x24,0x2b,0x14,0x02,0x02,0x07,0xa2,0x9c,0x0a,0x22,0x9f,0x9f,0xbf,0x3f,0x99,0x88,0x8b,0x9e,0x95,0x87,0x95,0x9e,0x91,0x85,0x83,0x87,0x84 +,0x80,0x81,0x8c,0x31,0x2f,0x7a,0xa0,0x88,0x89,0x9b,0xbf,0x09,0x07,0x03,0x03,0x0b,0x08,0xcd,0x0d,0x04,0x02,0x04,0x0c,0x15,0x0b,0x07,0x0c,0x08,0x04,0x02,0x21,0x92 +,0xab,0x0b,0xa3,0x83,0x80,0x8a,0xd4,0xa1,0x86,0x84,0x86,0x81,0x82,0x80,0x92,0x2d,0x1f,0x9c,0x97,0x89,0x8f,0xb3,0xbc,0x3f,0x27,0x14,0x3b,0x28,0x21,0x11,0x07,0x0a +,0x07,0x0c,0x14,0x0b,0x02,0x0f,0x8f,0x48,0x0d,0x00,0x05,0x1b,0x0c,0x34,0xc9,0x96,0xa8,0x17,0x16,0x1a,0x30,0xb9,0x9d,0x87,0x85,0x8c,0x89,0x91,0x87,0x89,0x85,0x83 +,0x86,0x88,0x97,0x97,0x94,0x8d,0x98,0xb5,0x2b,0x90,0x9e,0x1e,0x0d,0x00,0x18,0x0e,0x0d,0x15,0x2a,0x3e,0x0d,0x03,0x00,0x02,0x04,0x10,0x32,0x1e,0x07,0x0b,0x0c,0x26 +,0x2e,0x2e,0x9a,0x98,0x94,0x8f,0xa6,0x9b,0x87,0x89,0x8f,0x9e,0x83,0x80,0x88,0x9b,0xa8,0x87,0x82,0x84,0x82,0x83,0x80,0x97,0x15,0x0f,0x24,0x55,0x1b,0x11,0x08,0x07 +,0x03,0x02,0x01,0x02,0x00,0x01,0x01,0x02,0x02,0x05,0x01,0x06,0x0b,0x16,0x44,0xae,0x83,0x8d,0x9e,0xab,0x92,0x82,0x8b,0x84,0x80,0x80,0x81,0x8a,0x8d,0x9a,0x8e,0x92 +,0x93,0x8d,0x87,0x8e,0x24,0x19,0x2b,0x39,0x17,0x12,0x33,0x2a,0x0a,0x05,0x0a,0x4d,0x18,0x0a,0x06,0x25,0x97,0x14,0x07,0x00,0x0c,0x26,0x0c,0x06,0x13,0xf5,0xf7,0x10 +,0x0c,0x17,0x41,0xad,0x99,0x92,0x8c,0x8a,0x8c,0x96,0x8c,0x84,0x84,0x86,0x8b,0x8c,0x8a,0x8e,0xa3,0x97,0x9c,0x9e,0xb4,0x92,0xa7,0x23,0x15,0x0e,0x23,0x14,0x17,0x23 +,0x1b,0x2a,0x15,0x05,0x12,0x14,0x1c,0x0e,0x0d,0x24,0x2a,0x43,0xac,0x25,0x2d,0x37,0xc3,0xaa,0x26,0x1f,0x1d,0x1f,0x20,0xd1,0xb2,0xa9,0x8c,0x81,0x91,0x4e,0x1d,0x98 +,0x82,0x93,0xb7,0x93,0x85,0x80,0x88,0xad,0x2e,0x1f,0x17,0x05,0x04,0x15,0x42,0x0c,0x02,0x00,0x0a,0x0f,0xbc,0xa7,0x1b,0x4a,0x86,0x82,0x62,0x0a,0x09,0xcb,0x86,0x85 +,0x31,0x07,0x1a,0xb3,0x9a,0x80,0x92,0x93,0xbc,0x1c,0xa3,0x9c,0xac,0x1e,0x28,0x0d,0x13,0x21,0x19,0x13,0x54,0x24,0x11,0xa8,0x82,0x8c,0xae,0x9e,0x06,0x06,0x16,0x17 +,0x09,0x12,0x3c,0x1b,0x17,0x0e,0xa9,0x88,0x83,0x84,0x87,0x82,0x8b,0xa0,0x8d,0xa5,0xd2,0x94,0x8a,0x8a,0x8d,0x87,0x8f,0xa2,0x32,0x10,0x09,0x13,0x13,0x0b,0x02,0x00 +,0x02,0x03,0x04,0x05,0x1e,0x9b,0x96,0xc2,0x26,0xa9,0x88,0x81,0x89,0xab,0x92,0xa9,0x0b,0x08,0x19,0xbb,0x43,0x47,0x91,0x87,0x89,0x8e,0x99,0x99,0x9a,0x89,0x8f,0x9a +,0xa6,0x1b,0x20,0xe6,0x9f,0xa7,0x1b,0xba,0x91,0x8d,0x9b,0x0e,0x27,0x1c,0x2a,0x1c,0x15,0x36,0x04,0x00,0x01,0x00,0x0a,0x07,0x08,0xbb,0xb1,0x2b,0x1e,0xbe,0xb0,0x96 +,0x84,0x93,0x8b,0x86,0x8d,0x9d,0x91,0x83,0x86,0x88,0x83,0x80,0x85,0xb6,0x29,0x99,0x89,0x95,0x9f,0xca,0x09,0x01,0x00,0x06,0x0a,0x07,0x05,0x08,0x1f,0xc9,0x1b,0x0d +,0x10,0x0b,0x1c,0x25,0x1c,0x18,0x11,0x14,0x0f,0x1f,0x17,0x2d,0x8d,0x82,0x8d,0x40,0x1e,0x9f,0x87,0x88,0x84,0x86,0x82,0x8a,0xc2,0xa7,0x92,0x8e,0x9a,0xa7,0x8d,0x92 +,0x8d,0xb9,0xbf,0xa9,0x1e,0x18,0x0e,0x0f,0x07,0x05,0x0d,0x14,0x0b,0x04,0x11,0x97,0x4b,0x0f,0x01,0x03,0x18,0x9f,0x8a,0x9d,0x8f,0x9d,0x0f,0x03,0x09,0x30,0x9d,0xbd +,0x5e,0x9a,0x8c,0x8e,0x8a,0x8c,0x87,0x90,0x99,0x99,0x3c,0x2f,0x3a,0x8f,0x8d,0xab,0x8e,0x80,0x88,0x9b,0x17,0x20,0x9f,0x9a,0x29,0x1a,0xbb,0x36,0x23,0x1a,0x07,0x05 +,0x0f,0x0d,0x0e,0x1f,0x1c,0x09,0x04,0x0e,0x17,0x1f,0x18,0x19,0x12,0x00,0x0c,0xbb,0x8f,0xaf,0xa8,0x8e,0x94,0xa3,0x46,0x9d,0x8c,0x83,0x82,0x81,0x81,0x86,0x98,0xab +,0xb7,0x90,0x88,0x99,0xa8,0x93,0x8e,0xa8,0x20,0x0f,0x32,0xab,0x24,0x0c,0x00,0x02,0x0f,0x3e,0x16,0x0b,0xa1,0x25,0x08,0x02,0x00,0x0a,0x11,0x1e,0x1f,0xa8,0x99,0x2a +,0x25,0xaa,0x9f,0x8c,0x8f,0xac,0xe0,0xc5,0x8e,0x87,0x8b,0x9e,0xc4,0x97,0x8a,0x8a,0xbd,0x4c,0x9e,0x93,0x8c,0x88,0x85,0x9a,0x2e,0x0f,0x11,0x1a,0x19,0xdb,0x95,0x8e +,0x36,0x06,0x06,0x0b,0x28,0x3d,0x3a,0x35,0x13,0x0f,0x0d,0x28,0xbb,0x52,0xde,0x40,0x0f,0x06,0x08,0x0c,0x0f,0x39,0x87,0x82,0x9d,0x1a,0x0c,0x2d,0x8b,0x8a,0x8f,0xb3 +,0x9b,0x8c,0xb6,0x30,0x22,0x41,0xc9,0xa0,0x8d,0x8e,0xa2,0x24,0x36,0x94,0x8c,0x95,0x8e,0x89,0xb1,0x23,0x2b,0xb0,0x28,0x46,0x90,0x41,0x0e,0x01,0x09,0x14,0x0c,0x29 +,0xa8,0x97,0xba,0x0e,0x1a,0x10,0x14,0x12,0x1c,0xaf,0xbc,0xbb,0x12,0x0b,0x12,0x39,0xa2,0xbb,0xbc,0xa3,0xa2,0xde,0x39,0x30,0x9b,0x8f,0xb3,0xf3,0x18,0x46,0xa6,0x34 +,0x9b,0x8b,0x82,0x86,0xad,0xaa,0x8f,0x85,0x8b,0x8e,0x85,0x88,0x9a,0x3d,0x5b,0x26,0x27,0x56,0x2f,0x15,0x07,0x0e,0x1b,0x0a,0x06,0x55,0x78,0x07,0x03,0x03,0x0d,0x0d +,0x0b,0x0d,0x1a,0x64,0x4d,0x24,0x0b,0x17,0x5a,0x8e,0x93,0x9e,0x95,0x9c,0xa2,0xab,0x8d,0x8f,0xa7,0xd6,0xb9,0x9b,0x93,0x8b,0x94,0x9e,0x87,0x80,0x86,0xc7,0x28,0x94 +,0x87,0x90,0x8d,0x87,0x87,0xad,0x0b,0x10,0x23,0x21,0x16,0x24,0x1d,0x06,0x03,0x01,0x05,0x0a,0x11,0x17,0x05,0x00,0x02,0x0f,0x09,0x09,0x10,0xbc,0xaa,0x37,0x2f,0x11 +,0x1d,0xd1,0x89,0x81,0x84,0x83,0x87,0xa0,0xa7,0x89,0x80,0x85,0x8a,0x84,0x8a,0x9d,0xaf,0x94,0x92,0xc0,0x3e,0xaa,0xab,0x33,0x9f,0x8f,0x2d,0x10,0xa0,0x8a,0x26,0x06 +,0x07,0x0f,0x0d,0x07,0x22,0xac,0xb0,0x13,0x00,0x02,0x03,0x0b,0x19,0x0e,0x11,0x1f,0x2b,0x0e,0x09,0x1f,0x3b,0xbd,0x25,0x9c,0x95,0x3a,0x35,0xa0,0x8e,0x86,0x80,0x83 +,0x8c,0x17,0x21,0x8e,0x8c,0x8e,0x8c,0x80,0x89,0xa5,0xb8,0x9c,0x9a,0xa8,0x9b,0x8f,0xa9,0x3b,0xba,0x1e,0x13,0x0f,0x23,0x19,0x0e,0x14,0x0e,0x08,0x0a,0x0a,0x18,0x97 +,0xb9,0x1a,0x08,0x00,0x08,0x22,0x2d,0x3f,0x24,0xaa,0xb4,0x0e,0x16,0x1a,0xbf,0x19,0x44,0x8c,0x8c,0x95,0xa8,0x93,0x89,0x89,0x93,0x93,0xb5,0xc3,0x93,0x8c,0x9e,0xe8 +,0x92,0x80,0x8b,0x99,0x3e,0x0e,0x1e,0x65,0x94,0x97,0x9f,0x8c,0x98,0x19,0x0e,0x1d,0xb5,0x30,0x17,0x31,0x2e,0x1a,0x09,0x10,0x08,0x09,0x1d,0x0c,0x0f,0x08,0x08,0x18 +,0x1c,0x10,0x0d,0x97,0x87,0x9f,0x21,0x0e,0x28,0xa9,0x98,0x8f,0x8a,0x85,0x91,0x34,0xb7,0xa5,0x95,0x9d,0x52,0x8e,0x8b,0x88,0xa7,0x2b,0xac,0x30,0x27,0x2c,0xb9,0x2a +,0x1a,0x4e,0xaf,0xc9,0x29,0x97,0x81,0x8b,0x4c,0x0b,0x17,0xa3,0xbe,0xa9,0xa6,0xb4,0x9b,0x1f,0x0a,0x0e,0x15,0x17,0x0a,0x20,0x45,0xbd,0xa3,0x46,0x27,0x20,0x25,0x1e +,0x26,0x0f,0x0e,0x19,0x31,0x22,0x1c,0x14,0xb1,0x8b,0xb2,0x1f,0x0e,0x26,0xa6,0xd4,0xa6,0x88,0x85,0x8e,0x29,0x23,0x41,0xa5,0x95,0xaa,0x96,0x99,0x8d,0x99,0xa4,0x9b +,0x96,0x92,0x9d,0x92,0x93,0x8f,0xab,0x9f,0xcf,0x22,0x34,0x9b,0x8c,0xde,0x11,0x01,0x0a,0x18,0x1a,0x1f,0xaf,0xa1,0x15,0x00,0x03,0x08,0x08,0x09,0x08,0x24,0x2b,0x1e +,0x17,0x19,0x1b,0x21,0x33,0xaf,0x9f,0xa2,0x9d,0x45,0x8f,0x8a,0x8f,0x9e,0x91,0x80,0x87,0x99,0x2d,0x9e,0x85,0x8b,0x91,0x88,0x86,0x84,0x9f,0x13,0x1e,0x35,0xa5,0x96 +,0xaa,0xb4,0x2c,0xed,0x9c,0xa1,0x9f,0x24,0x25,0x1c,0x0b,0x0b,0x07,0x07,0x0e,0x0d,0x09,0x02,0x1f,0xa7,0x07,0x04,0x00,0x0d,0xc9,0x18,0x20,0x2a,0x9c,0x94,0x31,0x3a +,0xae,0x95,0x92,0x91,0x8a,0x89,0x8f,0x8d,0x8b,0x8c,0x9c,0xaf,0xa5,0x98,0x9d,0x2f,0x1e,0xc1,0x8c,0x91,0xcf,0x25,0x8c,0x80,0x92,0x35,0x1b,0xa8,0xc3,0x3b,0xa9,0x99 +,0x8b,0x45,0x0a,0x0c,0x07,0x18,0x35,0x2d,0xcb,0x1f,0x15,0x12,0x0e,0x15,0x07,0x0b,0x1a,0x3b,0x19,0x08,0x0f,0x1c,0xc6,0x2d,0x13,0x2c,0x89,0x86,0xb5,0x12,0x14,0xb9 +,0xbe,0x1c,0xc3,0x91,0x87,0x9b,0x2c,0x2d,0x1a,0xab,0x8f,0x87,0x88,0x95,0x96,0x8d,0x8b,0x97,0x96,0x8a,0x87,0x8e,0xa3,0xa6,0x92,0x94,0x9d,0xaf,0x18,0x2a,0x8a,0x92 +,0x18,0x04,0x00,0x09,0x0d,0x0b,0x13,0x21,0x25,0x0c,0x04,0x0f,0x3f,0xaa,0x27,0x28,0xe0,0x17,0x0e,0x0d,0x0e,0x0a,0x09,0x1c,0x29,0xab,0x2b,0x18,0x25,0x3a,0x90,0xa4 +,0x37,0xa4,0x83,0x82,0x97,0x29,0x46,0x88,0x85,0x89,0x87,0x84,0x82,0x8a,0xbb,0xb1,0x8c,0x88,0x8a,0x8f,0x8f,0x9c,0x65,0x36,0x27,0x1c,0x0f,0x0f,0x16,0x1e,0x0e,0x05 +,0x0e,0x0b,0x0c,0x0b,0x0c,0x14,0x65,0x92,0x20,0x05,0x00,0x0c,0x46,0x19,0x2b,0xb4,0xa6,0x4c,0x0d,0x11,0x11,0x17,0x35,0x2e,0xb6,0x96,0x97,0x95,0xa4,0x96,0x8f,0x9d +,0x93,0x97,0x98,0xa1,0xa8,0x9b,0xdf,0x3f,0xa2,0x9f,0x93,0x86,0x81,0x8d,0xb7,0x2c,0x9c,0x8b,0x9c,0x94,0x8e,0x8a,0xa9,0x18,0x26,0xbe,0xd6,0x19,0x0a,0x14,0x1e,0x1c +,0x1e,0x11,0x0b,0x06,0x0a,0x10,0x0d,0x10,0x15,0x0a,0x07,0x01,0x12,0x22,0x0b,0x07,0xb3,0x8d,0xa0,0x3b,0x0b,0x22,0x9b,0x9a,0x89,0x8c,0x99,0x92,0x93,0x90,0x9e,0x98 +,0x90,0x9c,0x8e,0x89,0x8c,0xa6,0x9b,0x91,0xa7,0x98,0x91,0x8c,0x8b,0x8e,0xaa,0x38,0x21,0xae,0x8f,0xa3,0x33,0xb7,0x94,0xc6,0x11,0x08,0x1c,0x23,0x09,0x03,0x10,0xc6 +,0x1d,0x02,0x03,0x09,0x0c,0x11,0x20,0x76,0x2f,0x16,0x0f,0x18,0x1a,0x30,0xf2,0x57,0x3b,0x39,0x36,0x1b,0x9a,0x8e,0x8f,0x91,0xbd,0xa5,0x8a,0x81,0x8d,0x2a,0x19,0x91 +,0x83,0x9d,0xac,0x9d,0x88,0x89,0x37,0x36,0x2b,0x3d,0x3a,0x36,0x99,0x94,0xac,0x1d,0x22,0x58,0x29,0xc1,0x1f,0x09,0x05,0x13,0x2a,0x3b,0x28,0xcc,0x8b,0x9a,0xff,0x8c +,0x8a,0x0c,0x08,0xad,0x84,0x82,0xab,0x1f,0xa6,0xaf,0x0d,0x00,0x09,0x08,0x5b,0x1a,0x00,0x00,0x0c,0x95,0x0c,0x04,0x2f,0x86,0x80,0x88,0x80,0x83,0x80,0x86,0x9d,0x0c +,0x12,0xbb,0xbe,0x0a,0x08,0x86,0x80,0x9e,0x00,0x1b,0x80,0x85,0x84,0x84,0xa0,0x2b,0x07,0x07,0xbe,0x49,0x1d,0x07,0x09,0x0e,0x1a,0x07,0x02,0x03,0x0a,0xc4,0xb1,0x2d +,0x8e,0x89,0x4f,0xaf,0x9f,0x88,0x87,0x85,0x8e,0x10,0x1c,0x08,0x06,0x3c,0x06,0x0a,0x36,0xba,0x8a,0x80,0x86,0x91,0x94,0xa2,0x8a,0x81,0x94,0xad,0x16,0x0b,0x02,0x16 +,0x8f,0x11,0x01,0x00,0xe9,0x88,0xb2,0x5d,0x0f,0x1d,0x40,0xa6,0x37,0x10,0xc7,0x87,0x88,0x17,0x05,0x10,0x6a,0x22,0x13,0x99,0x89,0x89,0x8f,0x24,0x1d,0x14,0x12,0x11 +,0x92,0x80,0x82,0x8d,0x3e,0xc1,0x92,0x8d,0x4c,0x22,0x10,0x2d,0x57,0x34,0x16,0x0c,0x15,0x0a,0x0e,0x2a,0x88,0x88,0x1e,0x0d,0x09,0x2c,0x28,0x08,0xa5,0x88,0x8b,0x9b +,0x18,0x1b,0x3b,0xc2,0xad,0x9f,0x8b,0x8b,0x90,0xc1,0x2c,0xbd,0xa8,0x96,0x9e,0x22,0x09,0x0c,0x25,0x17,0x42,0x29,0x0d,0x08,0x0a,0xb4,0xbd,0x36,0x0f,0x15,0x4c,0x2a +,0x9f,0x88,0x8f,0xaf,0x1a,0x1e,0x8f,0x84,0x8c,0x9a,0x8e,0x8b,0x8e,0x8f,0x9f,0x33,0xaf,0xab,0x38,0x95,0x8e,0xcd,0x10,0x00,0x0b,0x4c,0x5d,0x24,0x29,0xb8,0x18,0x09 +,0x05,0x0d,0xa6,0xa3,0x5c,0xac,0xb3,0xa3,0xa7,0x3d,0xad,0x91,0x8d,0x8c,0x8b,0x84,0x8c,0x2b,0x0a,0x08,0x1c,0x18,0x09,0x0b,0x2d,0xb2,0x93,0x9b,0x2b,0x20,0x1f,0xb8 +,0x8b,0x80,0x8f,0x30,0x13,0x0e,0xbf,0xd2,0xa1,0x8b,0x9b,0x4e,0x0c,0x17,0x43,0x25,0x22,0x1d,0x34,0xac,0x32,0x0c,0x03,0x02,0x08,0x0c,0x1f,0x1a,0x15,0x17,0x08,0x03 +,0x12,0xb8,0xf2,0x10,0xb4,0x87,0x89,0x84,0x95,0xb0,0x30,0x17,0xb0,0x86,0x81,0x85,0xd6,0x1e,0x1a,0x31,0x8f,0x99,0xaf,0x41,0xbe,0x9e,0x8c,0x8f,0x97,0x98,0x93,0x8b +,0x8c,0x8a,0xc2,0xa8,0x9c,0xac,0xb2,0x90,0x85,0x1e,0x01,0x04,0x2c,0x8e,0x8b,0x90,0xa6,0x9f,0xa0,0xcd,0xa6,0xac,0xe8,0x3c,0x18,0x18,0x2b,0xfe,0x23,0x0e,0x07,0x0a +,0x14,0x1b,0x1d,0x15,0x0f,0x03,0x09,0x0e,0x0b,0x06,0x0b,0x2d,0x1a,0x08,0x01,0x0d,0x0a,0x0b,0x21,0x91,0x83,0x8b,0xae,0x2d,0xc5,0xaa,0x8c,0x84,0x84,0x88,0x8e,0xb7 +,0x68,0x9b,0x8c,0x8f,0xaf,0x2a,0x26,0xfb,0x8c,0x84,0x8a,0x96,0x9f,0x82,0x8c,0x20,0x0d,0x1a,0xd3,0x24,0xa5,0x89,0x8f,0xaf,0x1b,0x1d,0x4e,0x99,0x96,0xce,0x29,0x4b +,0x68,0x18,0x14,0x0c,0x08,0x0b,0x19,0x1b,0x27,0x2b,0x1e,0x37,0xea,0xb9,0x3c,0x8e,0x8b,0x99,0x2b,0x0e,0xa6,0x96,0x8d,0x89,0x89,0x8e,0xd6,0x26,0x2c,0x1e,0x0b,0x0d +,0x3e,0x97,0x99,0x28,0x0b,0x06,0x0f,0x17,0x35,0xa9,0xaf,0x1f,0x06,0x0a,0x31,0xce,0x28,0xaa,0xbb,0x2a,0x20,0x19,0x26,0x4a,0x4f,0xbf,0x94,0x92,0x43,0x0f,0x18,0x2d +,0xda,0x2c,0x20,0x20,0x2f,0x2d,0x1f,0x32,0xc0,0x92,0x9f,0x2a,0x15,0x0c,0x0b,0x25,0x9a,0xa9,0xc1,0x98,0x9d,0xbb,0x31,0x13,0x1e,0xae,0x8f,0x84,0x86,0x85,0x8c,0xe8 +,0x3a,0xaf,0x8c,0x86,0x87,0x85,0x85,0x87,0x92,0xa4,0xaa,0x9f,0x92,0x9d,0xa4,0xa3,0x2f,0x27,0x47,0x25,0xd2,0x92,0x9f,0x26,0x02,0x01,0x07,0x07,0x17,0x39,0xbf,0x23 +,0x09,0x09,0x0f,0x2b,0xac,0xc2,0x45,0x1b,0x11,0x0a,0x03,0x09,0x0b,0x0e,0x10,0x13,0x0d,0x02,0x01,0x07,0x1c,0x3d,0x94,0x8c,0xbb,0x23,0x10,0xb1,0x8f,0x92,0x8e,0x90 +,0x88,0x86,0x8a,0x8f,0x95,0x8f,0x8e,0x8a,0x87,0x83,0x86,0x88,0x86,0x90,0x9d,0xbc,0x99,0xa2,0x39,0x1c,0x07,0x0e,0x0f,0x09,0x43,0x9d,0x9e,0xad,0x1d,0xd8,0xba,0xb4 +,0x8a,0x81,0x82,0x83,0x96,0x2d,0x34,0xa7,0x8e,0x8a,0x90,0xa4,0x23,0x13,0x13,0x20,0x30,0x22,0x1a,0x13,0x13,0x06,0x02,0x05,0x0b,0x25,0x92,0x31,0x06,0x03,0x00,0x09 +,0x0b,0x0e,0x1d,0xab,0x9f,0x28,0x09,0x07,0x14,0x2f,0x5d,0xa5,0x9f,0x48,0x6f,0xa1,0xac,0x56,0x3a,0x9d,0x92,0x92,0x90,0xa6,0xa9,0xa0,0x98,0xa1,0x88,0x86,0x91,0x9c +,0x2f,0x33,0x19,0x2e,0xa3,0x8e,0x83,0x8e,0xb8,0x27,0x2d,0x27,0xb9,0x89,0x87,0x8f,0x50,0x29,0x2a,0x23,0x14,0x1b,0xce,0x3f,0x26,0x0d,0x0e,0x14,0x14,0xa9,0x82,0x82 +,0x9c,0x0d,0x09,0x2b,0x1f,0x4e,0xa6,0xa5,0x97,0x61,0x16,0x05,0x0f,0xbe,0xba,0xae,0xac,0x9d,0x41,0x2a,0x4e,0x3a,0x1f,0x14,0x16,0x0f,0x0d,0x13,0x2c,0xdf,0x0d,0x0a +,0x9c,0xa6,0x1f,0x0f,0x07,0x1c,0x20,0x61,0x8e,0x88,0x8f,0x9e,0xae,0xe1,0x1e,0x2d,0xa2,0x8c,0x84,0x81,0x88,0xa7,0x4b,0x26,0xce,0x5a,0x9f,0x95,0x4b,0x0b,0x10,0x25 +,0x11,0x08,0x1e,0x8f,0x1e,0x05,0x01,0x07,0x0f,0x1f,0x8e,0x83,0x84,0x94,0x32,0x1d,0x20,0xe6,0xa2,0x8f,0x86,0x8e,0x92,0xa1,0x3c,0xd5,0x9e,0x99,0xab,0x96,0x86,0x89 +,0x8b,0x85,0x84,0x90,0x95,0x83,0x85,0x9d,0xc5,0x21,0xc6,0x36,0x1d,0x9a,0xae,0xa5,0x3f,0x10,0x0a,0x02,0x05,0x12,0x1f,0x1e,0x26,0x0c,0x03,0x01,0x00,0x00,0x01,0x02 +,0x04,0x0c,0x06,0x00,0x07,0x0c,0x0d,0xa0,0x83,0x93,0x23,0x14,0xb8,0x87,0x88,0x85,0x80,0x82,0x87,0xc6,0x39,0x1f,0x1d,0x96,0x85,0x88,0x89,0x87,0xad,0x3b,0x9e,0x8b +,0xa2,0x69,0x9f,0x95,0x90,0x98,0x94,0x91,0x9a,0x24,0xb4,0x85,0x8d,0xb3,0x1c,0x1f,0xce,0xbb,0xab,0x9d,0x91,0x9f,0x1d,0x15,0x1c,0x1e,0x3b,0xa8,0x9b,0x8d,0x96,0x29 +,0x0c,0x0f,0x2d,0x1f,0x1e,0x67,0xa3,0xb1,0x0e,0x05,0x06,0x06,0x02,0x04,0x25,0x0b,0x00,0x02,0x05,0x1a,0x24,0xe5,0x97,0xaa,0x54,0x1b,0x0d,0x1f,0xad,0x9d,0x6a,0xab +,0x8e,0xbb,0x15,0x1d,0x2e,0xeb,0xec,0xb3,0x8e,0x8b,0x99,0xa2,0xa6,0xe2,0x41,0x3a,0xcc,0x85,0x80,0x88,0x99,0xa9,0x8d,0x9f,0xb7,0x89,0x88,0x8c,0x9f,0x0c,0x0d,0x35 +,0x9a,0x99,0x9d,0xa1,0x30,0x0c,0x02,0x07,0x15,0x25,0x4f,0x9e,0x98,0xb5,0x28,0x1c,0x19,0xc5,0x9d,0xad,0x97,0x84,0x86,0x93,0xcf,0x8f,0x89,0x43,0x1f,0xa8,0x8d,0x95 +,0x29,0x1f,0xa1,0xae,0x1d,0x0a,0x19,0x19,0x09,0x09,0x03,0x04,0x05,0x0d,0x1f,0x24,0x55,0x11,0x0b,0x0a,0x05,0x11,0x0b,0x0d,0x96,0x87,0x9f,0x0e,0x00,0x0e,0x0f,0x1a +,0x24,0x31,0x97,0x1c,0x16,0xb2,0xa2,0x8a,0x9a,0xa2,0xa6,0xad,0x91,0xa4,0xb5,0x97,0x89,0x89,0x93,0x95,0x99,0xc5,0x51,0xbf,0xa4,0xb8,0x9b,0x84,0x80,0x80,0x88,0xa8 +,0xa7,0x9b,0x74,0xbd,0x8f,0x8a,0x89,0x96,0x3e,0x29,0x0c,0x0b,0x0a,0x17,0x1a,0x0e,0x12,0x04,0x0a,0x27,0x3a,0x2a,0x21,0x18,0x09,0x09,0x07,0x01,0x0d,0x1e,0x98,0x80 +,0x87,0xaf,0x19,0x0e,0x21,0x3b,0x2a,0xdc,0x9f,0x8a,0x92,0x42,0x2e,0x0b,0x06,0x08,0x12,0x2d,0x14,0x11,0x24,0xb6,0x3a,0x19,0x2c,0x99,0xa0,0xc7,0x40,0x1a,0x09,0x0e +,0xa2,0x8d,0x85,0x80,0x86,0x6e,0x0f,0x1f,0xcf,0xa0,0x94,0x85,0x81,0x80,0x8f,0x1e,0x1d,0x27,0x2c,0x25,0x17,0x17,0x16,0x3a,0x4f,0x56,0x2a,0x14,0xb6,0xbc,0x2c,0x1c +,0x18,0x17,0x1d,0x8d,0x84,0xa7,0x99,0x83,0x8c,0xac,0x19,0x26,0xd7,0xaf,0x87,0x81,0x80,0x8d,0xae,0xae,0x9f,0x95,0x6e,0x3b,0xa6,0x90,0x93,0x9f,0x4d,0x11,0x0b,0x08 +,0x09,0x06,0x03,0x01,0x04,0x05,0x14,0xa2,0x66,0x11,0xb1,0x9c,0x12,0x04,0x02,0x0d,0x1d,0x2a,0x25,0x29,0x2f,0x0e,0x10,0x15,0x09,0x0a,0x0f,0xaa,0x8d,0x8c,0x8b,0x89 +,0x88,0x8f,0x9e,0x9b,0xa2,0xba,0x5d,0xa5,0x8e,0x9d,0xa3,0x48,0x2f,0x4f,0x96,0x9f,0x11,0x06,0x12,0x93,0x8a,0x8d,0x8a,0x82,0x81,0x8f,0xaa,0x46,0x77,0xa5,0x94,0x8b +,0x89,0x9b,0xd2,0x4e,0xb6,0x2b,0x15,0x1f,0x19,0xce,0x12,0x1f,0x23,0x11,0x6f,0x33,0xa1,0x1d,0x72,0x8c,0x3f,0x39,0xac,0xb5,0x24,0x9b,0x8f,0x9e,0x93,0x23,0x04,0x0e +,0x03,0x0c,0x96,0x8e,0x9f,0x27,0x17,0x0f,0x0f,0x04,0x00,0x03,0x0f,0x19,0x0f,0x02,0x07,0x0c,0x12,0x14,0x0a,0x15,0xae,0x86,0x89,0x99,0xd4,0x91,0x84,0x89,0x8d,0x8c +,0x89,0xa4,0x48,0xda,0x8f,0x88,0x9a,0x9e,0x86,0x83,0x85,0x8c,0x39,0xb3,0x8f,0x87,0x89,0x94,0x8a,0x87,0x8e,0x2f,0x06,0x09,0x0b,0x09,0x0b,0x24,0x1c,0x02,0x03,0x01 +,0x0b,0x0f,0x07,0x03,0x04,0x23,0x1d,0x0b,0x0c,0x28,0x97,0x8a,0x94,0x99,0xa5,0x9a,0x93,0x8a,0x87,0x8f,0x8a,0x85,0x80,0x8a,0x8f,0xa2,0xd2,0x0e,0x1d,0x99,0x88,0x8e +,0x91,0x8d,0x9b,0xa3,0x12,0x1a,0x12,0x1a,0xa0,0x9b,0x32,0x10,0x0e,0x23,0x0c,0x03,0x03,0x01,0x0e,0x06,0x06,0x0a,0x12,0x0d,0x1a,0xa0,0xaf,0x94,0xbe,0x23,0x39,0x56 +,0x3a,0xba,0xdb,0x2f,0xcd,0xb1,0x8e,0x30,0x25,0x1f,0x54,0x86,0x88,0x83,0x82,0x80,0x80,0x91,0xbc,0xe7,0xce,0xbf,0xab,0x9d,0xa6,0x1c,0x14,0x0e,0x18,0x19,0x08,0x18 +,0x2d,0x12,0x4e,0x50,0x16,0x16,0xc0,0x9d,0x2c,0x14,0x0c,0xa6,0x3e,0x1f,0x1f,0x1f,0xb1,0xd4,0x96,0x8c,0x8e,0x8c,0x9d,0x33,0xb6,0x96,0x8e,0x87,0x89,0x89,0x8b,0x95 +,0xe1,0x32,0x2b,0xb5,0x96,0xb1,0xb9,0x0d,0x1c,0xa9,0xc9,0x0d,0x0a,0x0e,0x0b,0x0c,0x38,0xa8,0x1d,0x1c,0x0f,0x17,0x31,0x0d,0x0f,0x9f,0xa8,0xb4,0x2b,0x2a,0x18,0xb6 +,0x9f,0x6e,0xc3,0x18,0x1d,0x0a,0x0b,0x0a,0x0f,0x1d,0x19,0x48,0xab,0xc2,0x10,0x0d,0x1c,0x1f,0xad,0xb4,0xb8,0x88,0x97,0xa8,0xc3,0x1a,0x11,0x1e,0xae,0xae,0x94,0x8f +,0xa5,0x28,0xe9,0x8e,0x74,0x53,0xb9,0x9b,0x8f,0xc1,0x9d,0x96,0xa9,0xa2,0x8e,0x8d,0xa2,0x9b,0xa7,0xc8,0x34,0x1e,0x91,0x8b,0x8b,0x8a,0x80,0x88,0x90,0x37,0x3f,0x96 +,0x38,0xa2,0xb4,0x9f,0xab,0x23,0x1a,0x0f,0x07,0x10,0x19,0x17,0xf7,0xa1,0xb4,0x97,0x9b,0x9c,0x8e,0x90,0x8a,0xaa,0xc9,0x2c,0x0a,0x1c,0x0a,0x09,0x13,0x04,0x0d,0x04 +,0x02,0x00,0x00,0x02,0x06,0x11,0x14,0x22,0x2c,0xd8,0x14,0x12,0x33,0x50,0x4b,0xa5,0x8b,0x87,0x89,0x92,0x8d,0x83,0x8c,0x92,0x8c,0x95,0x9d,0x96,0x95,0xa2,0x95,0x8e +,0x8e,0x93,0x8f,0x87,0x8e,0x49,0x28,0x9e,0x8d,0xa7,0x8f,0x9a,0x9c,0xa0,0x0e,0x1f,0x27,0x2b,0x0e,0x2b,0xa1,0x76,0x1f,0x2e,0x14,0x0d,0x0d,0x0b,0x0d,0x0d,0x18,0x0e +,0x0b,0x08,0x35,0x4e,0x1e,0xb1,0x8c,0x88,0x9e,0x9e,0x95,0x89,0x85,0x89,0x81,0x82,0x80,0x8b,0x90,0x9e,0x59,0x39,0x1b,0xaa,0x4e,0x18,0x0c,0x06,0x07,0x00,0x05,0x07 +,0x0a,0x08,0x04,0x09,0x04,0x0c,0x0f,0x0d,0x0a,0x40,0xee,0x0c,0x0c,0x0a,0x26,0xc8,0xbe,0x9d,0x89,0x8f,0xa0,0xc9,0x9e,0xbd,0x6b,0x92,0x98,0x88,0x93,0x92,0x91,0xa1 +,0x9f,0xb7,0x8f,0x86,0x8e,0x8e,0xac,0xcf,0x95,0x8c,0x8a,0x8c,0x8a,0x92,0x97,0xbf,0x2a,0x9b,0x98,0x94,0x8a,0x96,0xb6,0x1c,0x1a,0x0a,0x07,0x09,0x14,0x3d,0x0e,0x0a +,0x08,0x0d,0x1a,0x22,0x3b,0xd1,0xdc,0xa7,0xba,0x2f,0x9a,0x92,0x8a,0x8c,0x8c,0x8b,0x9b,0xba,0x1a,0x23,0x20,0x23,0x9d,0xb7,0x37,0x1e,0x0a,0x0f,0x0c,0x0f,0x0f,0xbf +,0x34,0x20,0x1a,0x1e,0x68,0x2d,0x19,0x13,0x27,0x19,0x2f,0x02,0x17,0x25,0x0f,0x12,0xac,0x8c,0x1a,0x09,0x02,0x09,0x19,0x1d,0xcb,0x8c,0x8e,0xb1,0x1d,0x9c,0x9f,0xa5 +,0x8c,0x86,0x82,0x87,0x8b,0x8d,0x87,0x8e,0x8d,0x85,0x89,0x8e,0x8a,0x2d,0xda,0x9d,0x2d,0x37,0xa1,0x95,0x1b,0x0a,0x04,0x09,0x17,0x11,0x14,0x2a,0xae,0x9a,0x70,0x38 +,0x6d,0xb0,0x98,0x85,0x89,0x8f,0x8a,0x8d,0x91,0x93,0xa2,0xb6,0xad,0x1e,0x10,0x02,0x08,0x0b,0x0a,0x06,0x12,0x1e,0x14,0x05,0x02,0x0b,0x0b,0x1b,0x2a,0x9b,0x8c,0x9f +,0x15,0x3f,0x2d,0x19,0x3c,0xa7,0x9c,0x40,0x3d,0x22,0x47,0xab,0xb8,0x9e,0xa0,0x2b,0x10,0x11,0x2a,0xae,0xa6,0xa2,0x8d,0x80,0xaf,0x44,0xb5,0x9c,0x9b,0xa4,0x8c,0x93 +,0x87,0xa4,0x21,0xf6,0x9e,0x44,0x4a,0x98,0x9e,0xbc,0x2f,0x23,0xdd,0x32,0x1b,0x40,0x28,0x34,0x0a,0x05,0x10,0x10,0x1b,0x1d,0x9e,0x87,0x91,0xa3,0xb8,0x95,0x8a,0x8f +,0x85,0x81,0x80,0x82,0x8d,0x96,0x99,0x91,0xa0,0xb4,0x2c,0x28,0x09,0x01,0x02,0x01,0x05,0x06,0x0b,0x0b,0x07,0x00,0x09,0x08,0x0f,0x0c,0x16,0x8e,0xb6,0x1e,0x0f,0x26 +,0x48,0x35,0xa2,0x8d,0x8d,0x9b,0x2d,0x1f,0xa1,0xba,0x9a,0x98,0x8b,0x92,0xc3,0x62,0x6a,0xa3,0xa0,0x90,0x8f,0x92,0x98,0x3f,0x1e,0x9b,0xbb,0xa1,0x87,0x84,0x84,0xa9 +,0x2e,0xad,0xca,0x56,0xa5,0x9a,0x8d,0xbf,0x0e,0x09,0x06,0x0e,0x1d,0x22,0x28,0x16,0x0d,0x0a,0x04,0x08,0x0a,0x24,0x95,0x91,0xa3,0x28,0xb2,0x90,0x8f,0x8a,0x85,0x80 +,0x81,0x8c,0x9b,0x9f,0x94,0xb7,0xb3,0x96,0x9e,0xc2,0x10,0x06,0x08,0x05,0x0b,0x22,0x3c,0x26,0x1b,0x12,0x0f,0x0f,0x0a,0x2b,0x2f,0xbb,0xb7,0x10,0x0a,0x1a,0x1a,0x0f +,0x4e,0xa7,0xac,0x2a,0x1b,0x19,0x5c,0xc5,0x36,0x9b,0x8a,0x9b,0xb8,0x34,0xc1,0xda,0xc3,0x9d,0x8f,0x89,0x9e,0xd8,0x34,0xbf,0xb3,0xe0,0xb0,0x9b,0x9a,0x99,0xdc,0x4c +,0xae,0x60,0xc7,0x8a,0x8f,0xaf,0x1b,0x11,0x4e,0x19,0x1f,0xe0,0x9f,0xba,0x17,0x0e,0x1c,0x19,0xdc,0xa5,0x91,0x85,0x8f,0x9f,0x9f,0x98,0x9a,0x8e,0x8a,0x8c,0x91,0x9b +,0xc2,0x13,0x1b,0x2d,0x11,0x40,0xc1,0x3d,0x15,0x09,0x08,0x0e,0x19,0x23,0xc8,0xda,0x1e,0x0b,0x0b,0x0c,0x0a,0x0d,0x1d,0xc2,0xb0,0xb0,0x38,0x1a,0x15,0x1d,0x2e,0xa4 +,0x99,0x9d,0xb9,0x1b,0x1b,0x38,0xa6,0xb8,0x8c,0x8a,0x9a,0x4a,0x11,0x5d,0x9b,0xaa,0x91,0x89,0x89,0x9e,0xb2,0xf1,0x27,0x26,0x21,0x96,0x95,0x9d,0xbd,0x38,0x29,0x18 +,0x0f,0x1d,0x2a,0xbc,0x4f,0x2b,0x10,0x09,0x15,0x10,0x17,0x99,0x89,0x97,0xa5,0xbc,0x91,0x8a,0x89,0x85,0x81,0x80,0x84,0x89,0x8d,0x98,0x90,0x9b,0x8b,0x92,0xb9,0xd9 +,0x0f,0x0b,0x04,0x01,0x09,0x0c,0x07,0x0c,0x08,0x05,0x01,0x08,0x0b,0x0d,0x30,0x1a,0x0f,0x0b,0x0d,0x23,0x14,0x12,0x3a,0xa8,0x9b,0x27,0x15,0x18,0x12,0x1e,0xb4,0x9d +,0x8f,0x97,0xac,0xa0,0x9e,0x91,0x9c,0x8e,0x8e,0x8c,0x89,0x8a,0x8d,0x9d,0x9a,0x9a,0xa4,0x8c,0x8b,0x96,0xa5,0xdb,0xa7,0x4f,0x37,0xa7,0x99,0x94,0xda,0x0d,0x0e,0x08 +,0x0a,0x0c,0x12,0x1d,0x0d,0x0d,0x0d,0x12,0x1d,0x1f,0xa3,0x8f,0x89,0x87,0x88,0x86,0x8a,0x87,0x83,0x8b,0x8a,0x83,0x88,0x89,0xb3,0x1d,0x1c,0x0b,0x0e,0x0e,0x1a,0x12 +,0x05,0x0b,0x0d,0x0d,0x09,0x05,0x08,0x12,0x2a,0x3c,0x1a,0x0b,0x06,0x0a,0x18,0x3d,0xba,0x3e,0x40,0x2a,0x15,0x29,0x27,0x1e,0x8b,0x83,0x8a,0x9b,0x6e,0xae,0x5e,0x66 +,0xa1,0x92,0x8d,0xb3,0x2c,0xb5,0x3a,0x2c,0x26,0xc8,0x96,0x92,0x8d,0x9c,0xd1,0x3a,0xcd,0x9d,0x95,0x95,0xa9,0xa5,0x94,0xa4,0x1a,0x12,0x0d,0x19,0x99,0x98,0xaf,0x1c +,0x0c,0x0f,0x0c,0x1d,0x9e,0x8f,0x89,0x8d,0x89,0x8b,0xa6,0xa5,0x8d,0x82,0x81,0x86,0x8d,0x9e,0xa8,0x3f,0x18,0x2b,0x2a,0x21,0x16,0x15,0x0a,0x00,0x01,0x02,0x09,0x0b +,0x2e,0x2d,0x0e,0x0a,0x05,0x0d,0x09,0x03,0x0f,0xc5,0x93,0x2c,0x0e,0x0d,0x0b,0x16,0x26,0xa4,0x9c,0xb0,0xb5,0xb9,0xa9,0xbe,0x3c,0xa9,0x9a,0x8c,0x89,0x90,0xa5,0x43 +,0x36,0x95,0x8b,0x8d,0x83,0x84,0x88,0x90,0xae,0x65,0x33,0xb7,0x88,0x84,0x88,0xaa,0xce,0xbe,0x25,0x1f,0x0e,0x16,0x23,0x2a,0x1f,0x13,0x08,0x06,0x08,0x13,0x2d,0x27 +,0x28,0x3d,0xa5,0x9c,0xa6,0x9c,0x8d,0x8a,0x80,0x80,0x80,0x89,0xc3,0xa0,0x92,0x92,0x90,0xa3,0x99,0xb3,0x1f,0x13,0x05,0x01,0x03,0x04,0x12,0x1a,0x0c,0x0c,0x0e,0x10 +,0x0f,0x0f,0x07,0x0d,0x16,0x1e,0x26,0x1a,0x0a,0x0a,0x2d,0x32,0x27,0xa7,0x9b,0xbc,0x45,0x37,0x3c,0x14,0x0f,0xa7,0x86,0x85,0x96,0x42,0x23,0x1f,0x3d,0xc8,0xb8,0x96 +,0x8d,0x88,0x86,0x8d,0xc0,0x19,0x5b,0x8f,0x8f,0xaa,0xc5,0xcf,0xaf,0xb4,0xb1,0xcc,0x18,0x2d,0x89,0x81,0x90,0x1f,0x0d,0x30,0xae,0x9d,0xa8,0xa5,0x8d,0x96,0x9f,0x9d +,0x34,0x16,0x1e,0x9c,0x8c,0x95,0x22,0x27,0x28,0x1c,0x1e,0x1d,0x30,0x4a,0x9f,0xcf,0x2c,0x0d,0x07,0x06,0x13,0x2a,0x2a,0x2f,0xa1,0xab,0x3f,0x1c,0x0d,0x0f,0x09,0x28 +,0x9b,0x98,0xd7,0x24,0x24,0xb8,0xf9,0x25,0x35,0xd2,0xa8,0x99,0xb9,0xec,0x1e,0x13,0x5c,0xb1,0x94,0xae,0x1f,0x1f,0x24,0x29,0x10,0x18,0x3e,0xa3,0x96,0x88,0x8e,0x1f +,0x19,0x1d,0xa3,0x9e,0x64,0x4d,0x94,0x85,0x8c,0xa3,0x32,0x22,0x1a,0xbb,0x90,0x9c,0xb1,0x16,0x2a,0xac,0xad,0xd1,0x1c,0x29,0x9c,0x8f,0xb0,0xae,0x28,0x45,0x91,0x87 +,0x8c,0xc7,0xa4,0x8e,0x9f,0x57,0x17,0x15,0xf5,0xdc,0x93,0x99,0x5e,0x1c,0x14,0x2c,0xbf,0x1d,0x0d,0x1d,0x3f,0x8f,0x9f,0x2b,0x0f,0x0d,0x16,0x38,0x24,0x17,0x19,0x11 +,0xe1,0x2d,0x0c,0x09,0x0e,0x1f,0x28,0x34,0x9c,0x9b,0x45,0x16,0x1f,0x44,0xd0,0x37,0xab,0x9d,0x9a,0x48,0x24,0xbd,0x2d,0x48,0x5a,0x56,0xad,0xb2,0x3d,0x45,0x23,0x26 +,0xa3,0x94,0x8d,0x8d,0xa2,0xc9,0xa2,0xa5,0x52,0x9b,0xaf,0x99,0x9b,0x91,0x89,0x48,0x1c,0x18,0xaa,0x95,0xa2,0xcd,0xa8,0x8c,0x8a,0xad,0x42,0x2c,0x41,0x9e,0x9d,0xa9 +,0x32,0x5d,0xe6,0x98,0xa5,0x2a,0x1a,0x17,0xc3,0xd1,0x25,0x0f,0x0e,0x12,0xb8,0x9d,0x16,0x0e,0x10,0x4f,0xb0,0x16,0x13,0x11,0x22,0xbb,0xad,0xa1,0x75,0x1d,0x4d,0x46 +,0x5b,0x1e,0x12,0x4a,0x9e,0x86,0xa1,0x2d,0x1c,0x0f,0xeb,0x4d,0x2d,0x17,0x1b,0x2c,0xe3,0xca,0x0f,0x12,0x0d,0x1e,0xb1,0x3f,0x55,0xba,0x57,0xa6,0x96,0xa2,0xaf,0xd9 +,0x94,0x85,0x97,0xb7,0x23,0xc5,0x98,0x99,0x98,0xaf,0xad,0xb1,0xac,0xb4,0xab,0x32,0x49,0xa6,0x8a,0x8a,0x95,0x27,0x15,0x67,0x9d,0x97,0x37,0x21,0xa3,0x8b,0x8b,0xa9 +,0x1e,0x1e,0x16,0x1e,0xbc,0xc2,0x40,0x3b,0x1f,0x96,0x38,0x1f,0x1a,0x17,0xc7,0x30,0x39,0x1b,0x0d,0x09,0x21,0xbd,0xac,0x1d,0x09,0x14,0x10,0x1d,0x18,0x19,0x28,0x1e +,0x90,0x88,0x90,0x29,0x25,0x3c,0x9a,0xad,0x44,0xa9,0xad,0x8f,0x95,0x9e,0x22,0x13,0x0f,0xd7,0x9d,0x3c,0x2a,0x23,0xaf,0xa7,0xaf,0x5a,0x1c,0x52,0x4b,0xa9,0x23,0x1f +,0x26,0x28,0x9f,0x9f,0x8a,0xa9,0x1a,0x14,0x42,0xaf,0x3b,0x17,0xb6,0x85,0x85,0x8a,0x4e,0x24,0x1a,0x38,0xa5,0x9e,0xae,0x19,0xa4,0x97,0x90,0xd5,0x19,0x1a,0x38,0xa1 +,0xdb,0x3e,0x16,0xe2,0xb1,0x95,0xa0,0xb2,0x9f,0x1b,0x33,0x38,0xad,0x4a,0x10,0x9c,0x91,0x8a,0xa1,0x10,0x11,0x16,0x12,0x3e,0x24,0x1b,0x3a,0x38,0x99,0x2b,0x13,0x0f +,0x15,0x20,0x48,0x2a,0x12,0x10,0x2b,0x9e,0xa7,0x69,0xee,0xc7,0xbc,0xc8,0xbf,0xca,0x24,0x24,0x95,0x87,0x8b,0xcc,0x0d,0x2e,0xcc,0x99,0xa1,0x46,0xb9,0xb8,0x95,0x95 +,0x69,0x18,0x15,0x2d,0xad,0xa7,0xc3,0x29,0x1f,0x8f,0x9d,0x9e,0xd9,0xce,0x96,0x52,0x99,0x47,0x2d,0x28,0xa8,0x8b,0x90,0x94,0x33,0x1b,0x3d,0x24,0xca,0x1f,0x1b,0x53 +,0xe6,0xae,0x29,0x0e,0x0d,0x19,0x31,0xb2,0x29,0x1d,0x0e,0x36,0xae,0xad,0x25,0x22,0xac,0x29,0xd8,0x26,0x37,0x23,0x2c,0x8f,0x89,0x8c,0x2c,0x2e,0xec,0xb0,0xaf,0x46 +,0xab,0x2d,0xbd,0x9e,0xad,0x2f,0x19,0x18,0x32,0xc3,0xae,0x4e,0x0f,0xd0,0x65,0xa7,0xb8,0x1b,0xaa,0xa1,0xa8,0x5d,0x40,0x27,0x2c,0xc0,0x89,0x88,0xa8,0x1f,0x14,0x47 +,0xd0,0xb4,0xae,0x9d,0xb6,0x9f,0x98,0xd4,0x1b,0x0c,0x39,0xa0,0xbb,0x7c,0x13,0x11,0x26,0x35,0x49,0x77,0xca,0x3c,0x60,0xbf,0xa7,0x20,0x10,0x31,0x88,0x88,0x92,0x7b +,0x1d,0x44,0x37,0xa8,0x55,0xcd,0x62,0xb8,0x9c,0xa1,0x1c,0x0a,0x14,0x5b,0x9e,0xd4,0x17,0x16,0x4b,0x9a,0xb3,0xa8,0xb2,0x24,0x3a,0x9d,0x97,0xd5,0x14,0x1d,0x8e,0x90 +,0x92,0x16,0x12,0x1f,0x2e,0xad,0x2f,0x2d,0x1b,0xb2,0xa0,0xae,0x1b,0x0b,0x16,0x3d,0x9e,0xae,0x1c,0x17,0x33,0xa6,0xa1,0x9e,0xa1,0x29,0x21,0xa9,0xa7,0xcc,0x1a,0xb7 +,0x8b,0x8a,0x8f,0x31,0x2b,0x20,0x32,0xab,0x9d,0xa6,0x35,0xab,0xa0,0xa9,0xdf,0x1d,0x20,0xd5,0xa7,0xab,0x2b,0x22,0x51,0x2f,0xd0,0x96,0x9c,0x32,0x1f,0x1c,0x53,0xb8 +,0x1e,0xcb,0xd1,0xa3,0x99,0x32,0x2a,0x0e,0x16,0x44,0x9c,0x9e,0x2e,0x3f,0x3b,0xdf,0x59,0x2f,0x31,0x33,0x57,0xa5,0xf4,0x25,0x22,0x16,0x34,0x94,0x8b,0x66,0x21,0x21 +,0x63,0xa3,0x2c,0xc3,0xcf,0x9e,0x9a,0xae,0x24,0x0c,0x10,0x25,0x96,0x99,0xcd,0xb4,0xb6,0x47,0xbb,0x25,0x23,0x4c,0x31,0x9a,0xaa,0x25,0x30,0x19,0x36,0x92,0x8e,0xa6 +,0x2d,0x23,0x3e,0xb5,0x3c,0xc2,0xb6,0x92,0x95,0xab,0xbb,0x14,0x18,0x2a,0xa0,0x94,0xb9,0xbb,0xad,0x29,0x2a,0x2c,0x16,0x28,0x29,0xbc,0x99,0x24,0x2f,0x34,0x1f,0xa0 +,0x8e,0xa0,0x39,0x29,0x23,0xad,0x72,0xbc,0x9c,0xa4,0x94,0xa1,0x39,0x17,0x0e,0x10,0x3a,0x9c,0x92,0xce,0x44,0x2f,0x12,0x29,0x15,0x1c,0x1d,0x30,0x9e,0x31,0x1a,0x1e +,0x11,0x19,0x8e,0x98,0x3e,0x27,0x17,0xaf,0xac,0xa7,0xa6,0xa1,0x94,0x94,0x98,0xa5,0x1b,0x13,0x45,0x97,0x88,0x9a,0xab,0x30,0x22,0xce,0x27,0x26,0x17,0x28,0x97,0x94 +,0x3e,0x24,0x1c,0x11,0x98,0x8b,0x99,0x39,0x1c,0x2c,0xa6,0xaa,0xc1,0xb2,0xad,0x9c,0x9a,0x3d,0x13,0x0c,0x0d,0xf4,0x8d,0x9c,0xb7,0x32,0x16,0xcb,0x26,0x30,0x17,0x15 +,0x47,0x93,0xbd,0x18,0x1e,0x1a,0x36,0x9a,0x89,0xad,0x6c,0x15,0x37,0x9d,0x2d,0xa1,0xbd,0xae,0x90,0xb9,0x2a,0x1c,0x0e,0x1d,0x9a,0x9a,0x95,0xb5,0x45,0x54,0xdd,0xad +,0x2a,0x1b,0x1d,0x96,0x94,0x72,0x1e,0x1a,0x1a,0x23,0x98,0x94,0x9f,0x1a,0x18,0xc3,0x3e,0x28,0x26,0x56,0x99,0x9e,0xb7,0x3c,0x0d,0x0c,0x43,0x95,0x91,0xac,0x4b,0x30 +,0xed,0xab,0x35,0x4b,0x1d,0xbb,0x8f,0x97,0x6b,0x0e,0x14,0xc7,0xbb,0xa4,0x8f,0x23,0xe5,0x9e,0x9f,0x9d,0x1b,0x38,0xa6,0x8e,0x94,0xc0,0x2a,0x11,0x20,0xae,0xa9,0xdb +,0x3e,0x2f,0xa5,0xb7,0x1a,0x1a,0x0e,0x1a,0x5e,0xa7,0xad,0x22,0x09,0x1a,0xa0,0x29,0x2a,0xaf,0xa3,0x9e,0x9b,0xc5,0xbf,0x1b,0x14,0x9e,0xa4,0xab,0xdd,0x1b,0xb4,0x9d +,0xba,0x6e,0x4a,0x2c,0x9e,0x9a,0xb3,0xaf,0x1c,0x43,0xcd,0xb1,0xa3,0xe1,0x7b,0x38,0x46,0xac,0x38,0x16,0x20,0x97,0x8e,0xae,0xbd,0xab,0x1c,0x2e,0x37,0xd1,0xa8,0x27 +,0x55,0x94,0xa3,0x40,0x2e,0x0b,0x27,0x41,0xa9,0xa1,0xd4,0x2d,0x40,0xb7,0x3e,0xf5,0x35,0x35,0xa3,0x3a,0x1d,0x38,0x0f,0x0f,0x94,0x8a,0xa0,0xe7,0x1b,0xc9,0x5a,0x1a +,0x22,0xba,0x53,0x9b,0x8c,0x98,0x3a,0x13,0x11,0x4d,0x55,0x2d,0xae,0x29,0xb9,0x9f,0xb8,0x3a,0x21,0x38,0xa9,0x95,0x9d,0x11,0x16,0x21,0x58,0xa1,0x8c,0x8e,0xaf,0x46 +,0xaa,0x75,0x0b,0x0f,0x22,0xa6,0x8e,0x8e,0xad,0x36,0x12,0x35,0x42,0x27,0x2a,0x2d,0xae,0x9b,0xa0,0x2a,0x1c,0x1a,0x1d,0x98,0xaf,0x4b,0x1a,0x0d,0xb2,0xa6,0xc9,0xab +,0x8e,0x9c,0x92,0xcf,0x26,0x15,0x0e,0x50,0x90,0x87,0x93,0xb7,0x3e,0xe9,0x34,0x25,0x1c,0x22,0x1f,0xa7,0x8c,0xfb,0x55,0x1c,0x1b,0xb6,0x2a,0x4d,0x12,0x15,0x23,0xd8 +,0xaa,0x3a,0x1c,0xd6,0x8b,0x9e,0x2c,0x12,0x10,0x18,0xdd,0x8d,0x95,0x91,0xbd,0xc9,0x9b,0x37,0x1c,0x1b,0x30,0xc4,0x93,0xb4,0xaf,0x36,0xf3,0x99,0xa4,0x2a,0x18,0x21 +,0x1c,0x97,0xaf,0xef,0xc0,0x24,0xb2,0x8b,0x92,0x19,0x2b,0x19,0x3e,0x9b,0x37,0x9c,0xa5,0xbd,0xb2,0xaa,0x14,0x0e,0x0f,0x18,0x9c,0xc7,0xcc,0x32,0x36,0x5b,0xa2,0x35 +,0x0e,0x15,0x19,0xaa,0x92,0x6c,0x23,0xa9,0xfd,0xca,0x96,0x6b,0xcf,0x31,0xca,0x9b,0x60,0x1f,0xba,0xa9,0x9c,0x89,0xc7,0x3b,0x16,0x1b,0xc5,0x9e,0xb0,0x63,0x9d,0xb4 +,0x9a,0xb2,0x11,0x1c,0x16,0x2b,0x9a,0xa7,0x28,0x26,0x36,0xa2,0xa9,0x13,0x34,0x3c,0x2e,0xad,0x97,0x2e,0x1d,0x23,0xa8,0x8f,0x9c,0x2e,0x35,0x5a,0x1b,0xd1,0x1f,0x23 +,0xb5,0xb2,0x96,0x9d,0x1d,0x12,0x1f,0x2c,0xb3,0xa0,0x28,0xab,0x3c,0xfe,0x9f,0xba,0x16,0x1d,0x9a,0x9c,0x93,0x47,0x1f,0x2f,0x32,0xa5,0x91,0xe5,0xbe,0xa1,0xae,0x9f +,0x2b,0x0e,0x2c,0xd9,0xaf,0x99,0x6e,0x10,0x27,0x24,0x3e,0xbb,0x2a,0x2e,0xaf,0x9d,0x5c,0xcf,0x1e,0x2a,0x31,0x46,0x8a,0x98,0x17,0xcb,0xaf,0xcb,0xd9,0x28,0x32,0xab +,0xb2,0x9d,0xae,0x13,0x0c,0x23,0xaf,0xb1,0xbf,0x1c,0x3e,0xbb,0xbe,0xb3,0xb9,0x33,0xba,0xaa,0x97,0x9b,0x1a,0x15,0xae,0xb1,0xae,0x5d,0xc9,0xaa,0xd6,0x9d,0xb7,0x3e +,0x0e,0x26,0xa7,0xa1,0xa6,0xce,0x29,0x3b,0x2f,0x37,0xb3,0x15,0x1b,0x9e,0xb0,0xa9,0xf4,0x20,0xc3,0xbc,0xad,0xa1,0x26,0x11,0x29,0x24,0x9a,0xbf,0x2c,0x29,0x9e,0x90 +,0xcf,0xdc,0x18,0x35,0xdf,0xb0,0x9b,0xac,0x3f,0xa9,0x93,0xac,0x34,0x17,0x1b,0x36,0xe2,0xa1,0xbe,0x3d,0x1d,0xb2,0xbf,0xd6,0x31,0x16,0x29,0x26,0xba,0x35,0x4a,0x1a +,0xbb,0xa0,0xa0,0x95,0x16,0x38,0xaa,0xa0,0xb4,0x3f,0xe7,0xaf,0x96,0x9d,0x99,0x26,0x18,0x30,0xbe,0xc2,0xaa,0x4d,0x21,0x9f,0xd9,0x9f,0x2f,0x14,0x1e,0x4b,0xab,0x2b +,0x27,0x0b,0x5b,0xb4,0x2d,0xdd,0x49,0xb0,0x46,0xa9,0xc8,0xc4,0x1c,0x1d,0xa0,0x9e,0x9a,0xa8,0x46,0x5e,0xa7,0x41,0xac,0x3a,0x1d,0xa8,0x9e,0x9d,0xba,0x30,0x28,0x43 +,0xbd,0xa7,0xe5,0x14,0x41,0x67,0x9f,0xd0,0x2f,0x1e,0x21,0x8f,0x37,0xb5,0x32,0x22,0xd4,0xdd,0xb7,0xcf,0x34,0x4f,0x9b,0xcd,0xc9,0x40,0x1b,0x23,0x62,0xa1,0xa9,0xb4 +,0x26,0x42,0xab,0x3d,0x54,0x1f,0x2c,0xbe,0xb8,0x34,0xb7,0x1d,0x2a,0xb6,0xe0,0x96,0x26,0x31,0xe3,0xa8,0xbb,0x3c,0xbe,0x28,0x9a,0x98,0x99,0xaa,0x26,0x21,0xf8,0xcd +,0x46,0xaa,0x29,0xad,0xae,0xbc,0x2f,0x1c,0x25,0xc6,0xb1,0x42,0x2c,0x1e,0x3b,0x32,0xb5,0x3f,0xa1,0xd8,0x26,0x99,0x3f,0x3f,0x44,0x2c,0xbe,0xa6,0x9a,0xae,0xc7,0x19 +,0x50,0xbb,0x3b,0x63,0x1e,0xcb,0xa9,0xaf,0x3e,0x37,0x20,0x32,0xb2,0x5f,0xc8,0x1e,0x2f,0x3f,0xb4,0xb1,0x38,0xa1,0xbf,0xa8,0x9c,0x3a,0x31,0x47,0x34,0x8c,0x9d,0x9a +,0xa3,0x1b,0xac,0x40,0x65,0x70,0x20,0x33,0xe5,0xef,0x39,0x3c,0x1e,0x1a,0x46,0x37,0x3f,0x1d,0x19,0x32,0xa8,0x2d,0x44,0xca,0x9b,0xb0,0xc1,0xac,0x19,0x30,0x1a,0x9a +,0x94,0xa9,0x96,0xad,0xaf,0xde,0x47,0x41,0x2b,0xc4,0xac,0x9d,0xe9,0x78,0xd1,0x33,0x45,0xc0,0x1f,0x1d,0x16,0x16,0xa5,0x22,0x29,0x3d,0x9c,0xa0,0x3b,0xb8,0x2a,0x24 +,0x23,0xb0,0x9a,0xa6,0x9e,0x97,0xa2,0x4f,0x3a,0x1d,0x34,0x5e,0xa9,0x97,0xa8,0xaf,0xc2,0x60,0x31,0xbb,0x2a,0x2d,0x1c,0x0f,0xd8,0x58,0x3b,0x2d,0xae,0x94,0xcf,0xb3 +,0x29,0x23,0x1f,0x1a,0x9e,0xa1,0xaf,0x98,0xa5,0xa8,0xaf,0x21,0x2a,0x1a,0x36,0xac,0xa1,0xbe,0x50,0xdb,0x25,0x2f,0x29,0x1f,0x1e,0x10,0x24,0xc3,0x2e,0x36,0xb7,0x90 +,0xa6,0x9d,0xb4,0x27,0x27,0x1a,0x9c,0x98,0xa8,0x8e,0x9a,0x9d,0xae,0x2a,0x35,0x18,0x2d,0xbb,0xa4,0xce,0x44,0xcb,0xbf,0x45,0x24,0x22,0x1e,0x1b,0x45,0xa1,0xdd,0x29 +,0xb1,0x97,0xa3,0xaa,0xa8,0x50,0x2b,0x18,0xbc,0xaf,0x62,0x95,0xb5,0xa2,0xbc,0x30,0x1f,0x16,0x1c,0x4a,0xe7,0xdd,0x46,0xbd,0x48,0x3c,0x3d,0x1d,0x15,0x0f,0x35,0x4f +,0x77,0x43,0x94,0x98,0x37,0xa7,0xb3,0x34,0x40,0x27,0x9a,0xa4,0xa3,0xa8,0xb8,0xd6,0xdb,0xa3,0x2f,0x38,0x29,0x3b,0xad,0xa9,0xbc,0xaf,0x50,0xb2,0xa7,0xee,0x1e,0x21 +,0x22,0x32,0x2e,0xad,0x8b,0x9c,0x38,0xa1,0x3b,0x1b,0x1f,0x1a,0xcc,0xa2,0x9b,0xae,0xcc,0x1c,0x29,0x4f,0x27,0x4a,0x4f,0x23,0xce,0xbc,0x4b,0x2f,0x2a,0x34,0xb3,0x25 +,0x1d,0x43,0x19,0x1c,0x30,0x92,0x93,0xb9,0xb4,0xa0,0xcf,0x2c,0xb7,0x4e,0x57,0x96,0x8c,0x93,0xa7,0x2c,0x43,0x49,0x1c,0xc1,0x49,0x34,0xde,0xaf,0xbf,0xe7,0x2e,0x2b +,0xb5,0x18,0x2a,0x38,0x18,0x1a,0xb1,0x8b,0xa8,0xba,0x3c,0x2e,0x2e,0x28,0xb5,0x46,0xb0,0x98,0x98,0xa3,0xa7,0x20,0x2d,0x3b,0x25,0xbc,0x3a,0x31,0x60,0xad,0x5b,0xe5 +,0x1e,0x1b,0x21,0x13,0x2a,0x39,0x17,0x1b,0x8d,0x96,0xb4,0x9c,0x2f,0x53,0x18,0xc2,0x97,0xc6,0x9a,0x8f,0x98,0xab,0xa9,0x2a,0x28,0x30,0xe5,0xa7,0xe6,0x1f,0xb4,0xaf +,0x30,0xba,0x2c,0x28,0x18,0x18,0x44,0x3b,0x16,0xa7,0x8b,0x41,0x9b,0xb5,0x1b,0x25,0x15,0x9e,0xa2,0xad,0xa7,0x9b,0xac,0x33,0xb3,0x1b,0x1e,0x2b,0x2c,0xa9,0xad,0x1c +,0xb2,0x77,0x25,0xac,0x30,0x23,0x21,0x27,0xc3,0xca,0x28,0x8e,0x8f,0xaa,0x93,0x6a,0x24,0x17,0x47,0xc6,0x9d,0x93,0x6c,0x99,0x3e,0x64,0xad,0x11,0x1b,0x32,0x32,0xab +,0xa6,0x23,0xca,0x37,0x1f,0xc9,0x1f,0x14,0x1e,0x2b,0x1f,0xae,0xa0,0xa5,0xa1,0xbf,0xaf,0xc3,0x15,0x1c,0xb4,0x2b,0x8f,0x92,0x3f,0x90,0xc3,0x5d,0xa9,0x1a,0x19,0x6b +,0x3b,0xac,0x90,0x3f,0x45,0xfe,0x1b,0xc6,0xdd,0x0e,0x2c,0xd5,0x22,0x97,0x8f,0xc3,0x9e,0xc0,0x48,0xb8,0x0d,0x1a,0xb8,0x2d,0x8d,0x93,0x54,0xa0,0x29,0x2c,0xb5,0x43 +,0x18,0xbb,0x3d,0x47,0x8c,0x2c,0x2d,0xb3,0x1d,0x42,0x3a,0x0c,0x20,0x3c,0x12,0x91,0x8f,0x36,0x9c,0x2c,0x3c,0xd0,0x13,0x26,0xbc,0xd6,0x91,0x8e,0xc0,0xc8,0xec,0x21 +,0xc6,0xaa,0x14,0xb3,0x54,0xe3,0x8d,0x57,0x2b,0xb1,0x1d,0x2d,0xac,0x14,0x20,0x37,0x13,0x8f,0x8c,0x42,0x9d,0xcd,0x22,0xce,0x1b,0x1a,0xad,0x36,0x9e,0x8f,0xa7,0x34 +,0xc5,0x1d,0x3b,0xa9,0x18,0xc8,0xbc,0x3f,0x90,0xc3,0x15,0xd5,0x1e,0x25,0xae,0x16,0x18,0x2f,0x0f,0x99,0x8b,0xe6,0x9e,0xae,0x19,0xba,0x7d,0x29,0xbd,0xb5,0x9e,0x8c +,0x9d,0x3d,0xb3,0x1d,0x36,0xa6,0x1f,0x3c,0xc3,0x2b,0x9d,0xb3,0x25,0x4c,0x23,0x1f,0xd5,0x1d,0x25,0x2e,0x19,0x9f,0x88,0xee,0xc3,0xa7,0x1d,0xc1,0x3b,0x23,0x3b,0x2e +,0xa8,0x95,0x9c,0xd6,0xbb,0x1f,0x2c,0x9d,0x26,0x4c,0xb0,0xca,0xa8,0x9d,0x23,0x2d,0x26,0x24,0xbe,0x23,0x2e,0x2d,0x12,0x43,0x89,0xa9,0x4d,0xa2,0x32,0x30,0x38,0x44 +,0x36,0xe2,0xa7,0xa1,0x96,0x46,0xba,0x26,0x1b,0xad,0xce,0x36,0xe5,0xa6,0xa7,0xa7,0x32,0x26,0x1c,0x27,0x48,0x6d,0x2c,0x2e,0x2a,0x1a,0x90,0x9e,0x54,0xac,0x3a,0x44 +,0x2f,0x3f,0x23,0x33,0xab,0x9e,0x94,0xa4,0x58,0x4e,0x28,0x35,0xab,0x33,0xcf,0xb5,0xbb,0x9d,0x27,0x29,0x2d,0x28,0x53,0x6e,0x28,0x2a,0xc0,0x16,0xa8,0x92,0x6d,0xae +,0xab,0xc6,0x3e,0x41,0x2a,0xd5,0x5d,0xa8,0x96,0xa5,0xed,0x3c,0x4b,0x24,0xc5,0x20,0x45,0xa8,0x2d,0xa2,0xed,0x33,0x29,0x36,0x38,0xc7,0x2b,0x17,0xbf,0x1c,0x22,0x9c +,0x95,0x38,0xb1,0xe6,0xc0,0xc8,0x1f,0xa9,0x41,0xac,0xa7,0xa7,0xb5,0xbe,0xb1,0x26,0xa8,0x37,0x26,0xac,0xbf,0xc4,0xb2,0x3c,0x2a,0xcf,0x1b,0xa4,0xc5,0x16,0x36,0x56 +,0x21,0x22,0x96,0xab,0xcd,0xad,0xc0,0xbb,0x18,0x24,0xb5,0x37,0xb0,0x95,0xae,0xb2,0xee,0x1c,0xb9,0x20,0x31,0xf8,0xe8,0x2f,0xc2,0x9c,0xa9,0x9e,0xe1,0x4e,0x24,0x41 +,0x22,0x1f,0x30,0x29,0xa3,0x90,0x9c,0x3f,0x2c,0x27,0x34,0x11,0x1e,0xbe,0x18,0x8e,0x86,0x8e,0x9c,0x29,0x1b,0x29,0x22,0x15,0x18,0x1c,0x8b,0x84,0x89,0x9d,0x22,0x0d +,0x0e,0x33,0x16,0x14,0x1a,0x28,0xa4,0x2b,0xd6,0xad,0xbb,0x95,0x93,0x27,0x0b,0x0f,0x17,0xae,0x88,0x83,0x9a,0xb7,0x27,0x38,0xac,0x1a,0x2e,0x22,0xdf,0x94,0xae,0x46 +,0xbb,0x6a,0x23,0xa6,0x28,0x2a,0x4a,0x3d,0xa5,0x95,0x3b,0x09,0x27,0xca,0xcf,0xb2,0xa8,0x33,0x0c,0x04,0x2a,0x94,0x94,0x88,0x97,0xa6,0x97,0xb4,0xbc,0x68,0xc3,0xdb +,0xbb,0x2f,0xb5,0xcb,0x13,0x20,0xa2,0xa5,0x12,0x08,0x01,0x0e,0xa9,0x96,0x37,0xef,0x8a,0x85,0x94,0x9e,0x54,0x09,0x18,0x8c,0x9c,0x4c,0xd2,0xe2,0x9d,0xab,0x1d,0x0d +,0x0a,0x15,0x9c,0x91,0x94,0xc8,0x27,0x26,0x9d,0x92,0xaf,0x21,0x0d,0x2e,0xa4,0xda,0x46,0x3c,0x31,0xb6,0x9f,0x40,0x1d,0x0e,0x10,0xab,0x8e,0x91,0xb2,0xa4,0x94,0x8c +,0xc5,0x25,0x0f,0x12,0xf6,0xb5,0xdb,0xbc,0x46,0x1e,0xaf,0xae,0x23,0x42,0x46,0x2b,0xbe,0x3f,0x4f,0xad,0x92,0xa3,0x2a,0x1c,0xb9,0x2c,0x22,0xad,0x95,0x9c,0x25,0x10 +,0x0d,0x1d,0x31,0x9f,0x9d,0xc2,0x27,0xbc,0xa3,0x95,0x9a,0x1a,0x22,0xa1,0x99,0xae,0xd7,0x6e,0xc9,0xa8,0x29,0x16,0x0c,0x0d,0x2b,0xb0,0xb1,0xaf,0x48,0x2b,0xa0,0x8f +,0x9c,0x1d,0x19,0x1e,0xb6,0xaf,0x98,0x86,0x86,0x8d,0xa9,0x27,0x0d,0x05,0x0e,0xb8,0xb5,0x2e,0x2d,0xb6,0x99,0x9f,0x3a,0x14,0x0c,0x0d,0x20,0x15,0x11,0x93,0x90,0x97 +,0x9e,0x96,0xe9,0x27,0x56,0x29,0x39,0x41,0x9f,0x8e,0x8c,0x8e,0x9f,0x21,0x1e,0x17,0x0f,0x1b,0xb8,0xb9,0xa8,0xa0,0xb7,0x1c,0x12,0x1b,0xb7,0x9e,0xae,0x5c,0x3c,0xba +,0xad,0x99,0x2d,0x12,0x19,0x2e,0x9c,0xad,0xb9,0xa5,0x1a,0x24,0x53,0xc5,0xa5,0xb9,0xa3,0x96,0xcf,0x22,0x30,0xb5,0xa5,0x99,0xab,0x23,0x15,0x1f,0xd0,0xb9,0xaf,0x4c +,0x49,0x2b,0x34,0x1e,0x17,0x4a,0xa4,0xcc,0x5e,0x2e,0x3e,0x9a,0x93,0x97,0xad,0x6b,0x47,0x16,0x10,0x33,0xc3,0xa3,0xac,0x58,0x1a,0x1f,0xbb,0x90,0x8e,0xba,0x26,0x37 +,0xad,0x9d,0x98,0xa9,0x3f,0x1b,0x10,0x17,0x2d,0xbe,0xbb,0xac,0x30,0x10,0x13,0x0f,0x3b,0x9b,0x8d,0x8f,0xc3,0x3d,0xcd,0xb3,0xab,0xc0,0xb7,0xbe,0x42,0x72,0xeb,0x58 +,0xe2,0xae,0x3e,0x1f,0x18,0x17,0x2b,0xaf,0xa3,0xad,0x46,0x5f,0xb9,0xa3,0xee,0x4d,0xc8,0x1b,0x1f,0x3c,0xb4,0x96,0xa1,0xc5,0xc1,0x1f,0x18,0x1b,0x2f,0x9c,0x9f,0xac +,0xaf,0xbc,0x97,0x99,0xae,0x47,0x29,0x36,0x2a,0x16,0x17,0x1e,0xbf,0xa8,0x36,0x24,0x1d,0x40,0xac,0xbc,0xaa,0xb3,0xbd,0x96,0xaa,0xc2,0xa0,0x4c,0x20,0x22,0x2f,0x9d +,0xa0,0xa1,0xac,0x2d,0x1e,0x17,0x16,0x3c,0x98,0x92,0xa0,0x31,0x4f,0xb7,0xa9,0xaf,0xcf,0x39,0x2e,0x3d,0x39,0xd9,0xaf,0x3e,0x32,0x27,0x1b,0x15,0x1a,0x22,0x2e,0xae +,0xaa,0xb0,0xa8,0xa6,0xac,0x9e,0xac,0x30,0x23,0x4c,0xaf,0x94,0x91,0x97,0xba,0x1b,0x16,0x0c,0x1b,0xb6,0xa6,0xa4,0x3d,0x26,0xca,0xb4,0xa9,0x9e,0x43,0x54,0x29,0x0f +,0x17,0x1d,0x63,0x97,0x9b,0xb1,0x32,0x1e,0xaf,0xab,0xad,0xd8,0xf9,0x9c,0x9c,0x99,0x9c,0xb5,0x4b,0x1d,0x1c,0x2d,0xed,0x9e,0xaa,0xdc,0x3f,0x23,0x0e,0x0b,0x14,0xc2 +,0xad,0xac,0x2f,0x12,0x27,0xbc,0x92,0x98,0xc8,0xab,0xc0,0x3f,0x38,0x6d,0x9a,0xa9,0xac,0x6f,0x28,0x4f,0x2f,0x2f,0xbf,0xaf,0xa1,0xd8,0x39,0xef,0xc7,0xaa,0x40,0x20 +,0x34,0xbf,0x9c,0xa1,0x7c,0x3f,0x16,0x14,0x26,0x28,0xab,0xa1,0x5d,0xad,0x37,0xbd,0xad,0xa6,0xa4,0xdc,0xac,0xc0,0x34,0x2e,0x2a,0xcb,0x9e,0xb0,0xe0,0x22,0x28,0xce +,0xd7,0x4f,0x3a,0x59,0xab,0xa3,0xc2,0x28,0x21,0x14,0x11,0x17,0x20,0x9c,0x99,0xbb,0x9f,0x6d,0x37,0x29,0x28,0xae,0xae,0x9c,0xa7,0xdf,0xc5,0x9a,0x91,0x98,0xc3,0x1e +,0x28,0x3f,0x6f,0xca,0x5c,0x56,0xb8,0x3c,0x18,0x14,0x14,0x1f,0x1e,0x4a,0x3c,0x6d,0x9d,0xd4,0x9e,0x9c,0x54,0x46,0x4b,0xb2,0xa3,0xab,0x99,0xab,0xf9,0xb8,0xed,0xec +,0xde,0xcf,0xef,0x39,0x46,0x26,0x33,0xa9,0xa8,0xbb,0x33,0x20,0x15,0x1c,0x1a,0x22,0x2e,0x38,0xa8,0xc2,0xcc,0xa1,0xdc,0xa3,0xaa,0xcc,0xa2,0xab,0x9e,0xb6,0x31,0x3e +,0xcb,0x5c,0x49,0x41,0x49,0x54,0xc9,0x42,0x27,0x3d,0x2c,0x1e,0x37,0x44,0x47,0x32,0xd8,0x2c,0xcb,0xaf,0xa0,0x9d,0x3e,0x9a,0xbd,0xef,0xdf,0x57,0xab,0xa3,0x4a,0x26 +,0x1c,0x45,0xc2,0xac,0x9e,0xad,0xa4,0xc2,0x3f,0x2f,0x37,0x2e,0x2b,0x5a,0xee,0x66,0x36,0x1f,0x3c,0x1e,0x1d,0x15,0x2e,0xb0,0x5f,0x96,0x9d,0xbd,0xba,0xae,0xa7,0xb4 +,0xa7,0xc7,0x55,0x37,0x76,0xcf,0x37,0xa7,0xa8,0x68,0x34,0x23,0x18,0x36,0xcd,0xa6,0xab,0xac,0xaf,0xae,0xbd,0x1b,0x15,0x17,0x26,0x37,0x47,0x9d,0x9a,0xba,0xdb,0x36 +,0x39,0x3f,0x44,0x5c,0xbd,0xad,0xa4,0xa5,0xa4,0x9c,0x94,0x9d,0x4d,0x36,0x1c,0x1f,0x3b,0xd2,0xbf,0xee,0x35,0x1d,0x1f,0x13,0x14,0x19,0x54,0xb9,0x3d,0x95,0x9c,0xad +,0xa3,0xa3,0x3a,0x21,0x3b,0xdf,0xb7,0xa2,0x9a,0xb3,0x3b,0x44,0xb6,0xce,0xd8,0xb7,0x2a,0x22,0x2c,0x70,0xb4,0xac,0xb8,0x32,0x30,0x15,0x15,0x1a,0x3e,0xc4,0xda,0xa2 +,0xc2,0xb3,0xbe,0xbf,0xaa,0xbd,0xae,0xb7,0xb8,0xa4,0x9b,0xa4,0xb7,0xaf,0xd9,0xe2,0x24,0x27,0x27,0x3a,0x3c,0x2a,0x29,0x39,0x31,0x1e,0x3a,0x1d,0x24,0x2e,0xb5,0xc6 +,0xac,0x8d,0x96,0xa9,0xed,0x6e,0xc8,0xfe,0xae,0xa8,0x56,0xcd,0x49,0x1e,0x2d,0x4a,0xc7,0xd6,0x42,0xd1,0x3b,0x37,0x44,0xbd,0xbe,0xce,0x2a,0x1d,0x46,0x36,0x3a,0x38 +,0xab,0x45,0x2c,0xa4,0x47,0xf4,0xcc,0xb5,0x49,0xc6,0xa7,0xa2,0x9f,0xa5,0xa8,0x3f,0x3d,0x2e,0x36,0x79,0xa6,0xae,0x39,0x1a,0x19,0x29,0x66,0x9e,0xd0,0x50,0x2f,0x20 +,0x3a,0xc3,0x98,0xaf,0xb2,0xa1,0x3a,0x21,0x38,0xce,0xe4,0xcd,0xdd,0x3e,0x31,0x7c,0x3f,0x33,0x37,0x4f,0x49,0xc0,0x9e,0xa0,0x9e,0xa3,0x5e,0x2d,0x23,0xe7,0x51,0x4f +,0xcb,0x28,0x23,0x23,0x48,0x1f,0xc9,0x9e,0xc4,0x49,0x3a,0x5c,0xc9,0xad,0x9f,0x9f,0xb2,0xb8,0x27,0x47,0x59,0xe8,0xdb,0x41,0xc7,0x42,0xdc,0x50,0xe6,0x48,0x25,0x37 +,0x32,0x2c,0xd9,0x41,0x2d,0xba,0xa9,0x48,0x3c,0xb4,0x4f,0xc9,0xba,0x57,0x3e,0x32,0xa6,0xa4,0x9e,0xa6,0xae,0xc5,0xcb,0xac,0x3e,0x5f,0xde,0x5d,0xad,0xcb,0x24,0x1e +,0x29,0xdb,0x31,0x1e,0x1b,0x19,0x1e,0x41,0xa1,0xcf,0xf9,0xa6,0x6c,0xa5,0x9c,0xa1,0x9f,0xc4,0xbb,0xb4,0x9f,0x9a,0xc1,0x4a,0x34,0x3b,0x1f,0x16,0x1e,0x28,0x30,0x4f +,0x3e,0x2b,0x33,0x5d,0xb7,0x24,0x5d,0x3d,0x1f,0x42,0x97,0x99,0xc8,0x98,0xb7,0x3d,0xc6,0xb8,0x30,0x2c,0xad,0xa1,0xa0,0xa7,0xbc,0x7b,0xaf,0xbd,0x3f,0x21,0x1f,0x1d +,0x25,0xcd,0xbf,0xc8,0x2e,0x22,0x2c,0x5b,0x47,0x56,0x23,0x18,0xb0,0x8e,0x9c,0x99,0xa3,0x32,0xd6,0xb6,0xbe,0x2a,0x35,0xb3,0xfb,0xbd,0xb1,0x35,0x33,0x24,0x2b,0x1f +,0x20,0x32,0x33,0xa3,0x9e,0xa9,0xbc,0xc5,0xbe,0x9f,0xbc,0x24,0x25,0x18,0x26,0x9d,0x92,0x38,0x33,0x3a,0x2a,0xab,0xaa,0x45,0x1a,0x33,0xac,0x9f,0x9d,0xa2,0xf2,0x36 +,0xd4,0xb9,0xca,0x2b,0x2c,0x2b,0xbd,0x9c,0xcd,0x1f,0x21,0x3e,0xaa,0xed,0x21,0x22,0x1e,0x2d,0x9b,0xa9,0x2e,0xae,0xc6,0x79,0xc6,0xc0,0x2c,0x1e,0xbf,0xa6,0xba,0xa8 +,0xac,0x71,0xb0,0xa2,0xa6,0x23,0x19,0x39,0xaa,0x95,0x9f,0x2e,0x1b,0x3a,0xb3,0xa3,0x3f,0x10,0x0e,0x12,0x28,0xb4,0xa9,0x1f,0x27,0xa8,0x9a,0x97,0x9c,0x4c,0x25,0xab +,0x9c,0x9c,0x9e,0xa9,0x6b,0x4e,0xb0,0x3c,0x17,0x18,0x26,0xde,0x3b,0x2e,0x25,0x4d,0xb4,0xc4,0xaf,0xda,0x1f,0x24,0xb4,0x37,0x3b,0xad,0xa9,0xce,0x9a,0x9a,0x3e,0x1a +,0x1e,0xe9,0xb6,0x92,0xad,0x2b,0xf4,0xa3,0x9b,0xaf,0x40,0x13,0x17,0x42,0xb2,0xae,0x33,0x27,0x23,0x34,0x53,0xb1,0x6e,0x28,0x19,0x1b,0xaa,0xb4,0xcc,0x9d,0xa2,0x9f +,0x8e,0xbc,0x1d,0x32,0xa8,0x9d,0xac,0xca,0x2f,0x2c,0xc3,0xb7,0x2a,0x1c,0x1b,0x21,0xb1,0xac,0xbc,0xb9,0xbb,0xac,0xb9,0xa2,0x3d,0x19,0x1f,0x43,0xbf,0xdb,0x23,0x0e +,0x2b,0x96,0x99,0xb7,0x2f,0x17,0x26,0xa3,0x93,0x9c,0x63,0xd1,0x2b,0xc2,0xa2,0xc0,0xb2,0xd6,0x2d,0x2f,0xee,0xf3,0xcf,0x5e,0xae,0xcf,0x45,0x1f,0x13,0x37,0xa9,0xae +,0x4d,0x1f,0x38,0xac,0xfc,0xae,0xc0,0x25,0xa9,0xb1,0xb8,0xb7,0x44,0xa6,0xda,0x53,0xf9,0x5e,0x44,0x37,0xdf,0xae,0xa3,0xaf,0x31,0x2d,0xbd,0x9b,0xa4,0x2b,0x10,0x10 +,0x1d,0xce,0xb1,0xcf,0x3e,0x20,0x1b,0x42,0xad,0x53,0x98,0xa8,0xc6,0xa2,0x9c,0xac,0xb5,0xad,0x47,0xbf,0x33,0x2e,0x1f,0x40,0xa2,0xc8,0x2b,0x2d,0x41,0x5f,0xa5,0xa5 +,0x2e,0x1f,0x23,0x2b,0xbd,0xa1,0xac,0xbc,0xe0,0x22,0x20,0x34,0xaf,0x3f,0xe1,0xa5,0xb0,0xb9,0x5b,0x3e,0xea,0x9c,0xa5,0xbd,0x1f,0x40,0xb5,0x53,0xb7,0x4b,0x54,0x33 +,0x4b,0x44,0x37,0x41,0x51,0x2f,0x22,0xe0,0xde,0xaf,0x5a,0x49,0xb3,0xc7,0x54,0x30,0x3e,0xbf,0x9d,0x3c,0x24,0x24,0x22,0xbe,0x9e,0x9b,0x4e,0x35,0x37,0x34,0xab,0xa2 +,0xa9,0x7b,0xd9,0xb0,0xbd,0xdc,0xc5,0x30,0x2c,0xb3,0x68,0x6e,0x36,0x38,0xec,0xb2,0xc2,0x22,0x2b,0x37,0xb0,0xbf,0xd1,0x4b,0x38,0x44,0xc9,0x9c,0xb4,0xa1,0xd9,0x34 +,0x2e,0x37,0xb1,0x42,0x71,0x47,0xc2,0x36,0x3a,0x2c,0x2b,0x58,0xbc,0xc1,0x2a,0x5b,0x66,0x9f,0xb6,0x35,0x28,0x20,0x3a,0xc4,0x9d,0xab,0x42,0x16,0x2c,0xdb,0xb2,0x99 +,0xa5,0x67,0x2a,0xa6,0xad,0xba,0xb1,0x38,0xbf,0xcb,0x59,0x24,0x21,0x2c,0x3a,0xb8,0xb6,0xe0,0x37,0xee,0x4c,0xac,0xae,0xa8,0xb4,0xed,0xad,0x5d,0xb8,0x49,0xee,0xcc +,0xf2,0x29,0x25,0x2b,0x23,0xc6,0x41,0x36,0x1d,0x34,0xe5,0xb9,0xa7,0xdb,0x3a,0x2c,0xb1,0xa8,0x9b,0xa3,0xde,0x3b,0x33,0xae,0xa7,0xa9,0xac,0x4a,0x45,0xd0,0xee,0x2e +,0x20,0x28,0xe0,0xc5,0x46,0x39,0x1f,0x20,0x31,0x57,0xe8,0xb4,0xbd,0x3b,0x2e,0x4f,0xb9,0x47,0x9c,0x99,0x9b,0xa8,0x3f,0x42,0x2d,0xae,0xa9,0xb8,0x42,0x4d,0x3b,0x74 +,0x3c,0x1b,0x23,0x26,0xbf,0xb4,0xce,0x37,0x27,0x2c,0x46,0x9f,0xa2,0xad,0xdc,0x4b,0xe2,0xba,0xb6,0x5d,0x63,0xc4,0x9e,0xb2,0x45,0x29,0x1b,0x1e,0x29,0x79,0xb5,0xb1 +,0x6f,0xdf,0x4b,0x39,0x2e,0x4c,0xa7,0xa5,0xa1,0xb3,0x65,0x49,0x68,0xbd,0xb2,0xaf,0xfc,0xc5,0x3c,0x39,0x3c,0x1f,0x32,0x38,0xb0,0xa9,0x38,0x21,0x20,0x21,0x43,0xbe +,0xbb,0xaf,0x2a,0xce,0xbc,0xc8,0xd0,0x3f,0xb0,0xbe,0xad,0x9e,0x9f,0xbb,0xc4,0xc9,0xb3,0xb5,0x3b,0x3d,0x2c,0x2d,0x2d,0x2c,0x2d,0x3e,0x27,0x2f,0xd0,0x27,0x48,0x47 +,0xef,0xad,0xc2,0xa3,0x9f,0xa8,0x9f,0xa5,0x45,0x3d,0x3e,0xd9,0xaa,0xc9,0xad,0x35,0x31,0x4e,0x51,0xcb,0x26,0x2c,0x31,0x2e,0x2d,0x58,0x3f,0x3f,0x5d,0xe7,0xb5,0x45 +,0x28,0x27,0x4c,0xb8,0xad,0xb0,0xb8,0xb9,0xd5,0xa8,0xb2,0xf6,0x39,0x43,0xda,0xd0,0xb3,0xaf,0xb9,0x4f,0xc0,0x3a,0x39,0x42,0x28,0x46,0x2e,0x2d,0x5f,0xcf,0xbc,0xba +,0xca,0x36,0x30,0x35,0xc7,0xbc,0xa7,0xbc,0x4b,0xca,0xc7,0xa6,0xab,0xc8,0x31,0x3d,0x41,0x6c,0xd9,0xc7,0xbb,0x44,0x5b,0xbe,0xb7,0xd7,0x45,0x2f,0x49,0x4d,0xb5,0x9e +,0x79,0x48,0x2b,0x37,0x3f,0x2c,0x41,0x3b,0x30,0x28,0x3b,0xc1,0xc3,0x45,0xb9,0xd7,0x5b,0xb3,0xb9,0xae,0x59,0x5e,0xbe,0xbb,0xaf,0xbd,0xae,0x5a,0x2d,0x3c,0xc7,0xc8 +,0xe3,0xed,0xf2,0x4d,0x2f,0xc4,0x5c,0x33,0x36,0x3e,0xbc,0x43,0x3c,0xb8,0x50,0x42,0xdd,0x4f,0x40,0x3d,0x42,0xbe,0x55,0x4c,0xc2,0xae,0xae,0xda,0xbc,0xca,0xca,0xd1 +,0xb6,0xe3,0x4a,0x4c,0xb7,0xb9,0xf9,0x42,0x35,0x2b,0x1f,0x56,0xba,0xcf,0x2c,0x35,0xbf,0xb9,0xc8,0xb6,0xb9,0x2d,0x29,0xef,0xb6,0xaa,0xab,0xac,0xd6,0x41,0xcf,0xbe +,0xc9,0x35,0x2f,0x47,0x3d,0x43,0xbd,0xc6,0xc6,0xde,0xbf,0xbd,0x3b,0x36,0xdf,0x49,0x35,0x34,0x6e,0xf9,0x34,0x4d,0xc6,0x37,0x2d,0x2e,0x53,0xb6,0x64,0xaa,0xaf,0xc9 +,0xc2,0xc9,0xb4,0xbe,0x65,0xd8,0xf3,0x49,0x47,0xcb,0xb4,0xdc,0xc8,0xb6,0xfe,0x3c,0x39,0x5d,0x4f,0x39,0x6a,0xbb,0x55,0x2b,0x6a,0xd1,0x77,0x49,0x3c,0x4d,0x5c,0xc4 +,0xab,0xae,0xc8,0xc6,0xbd,0xc9,0x4b,0x3f,0x52,0x3e,0xcd,0xa9,0xc4,0x4c,0x34,0x39,0xc5,0xbf,0xdd,0x4a,0x29,0x24,0x2c,0xef,0xb2,0xe5,0x3e,0x3f,0x30,0x2d,0x4e,0x50 +,0xc3,0x55,0xd6,0xa3,0xab,0xaf,0xad,0xb1,0xd4,0x5b,0xff,0xc4,0x43,0xe3,0xad,0xae,0xca,0x3c,0x40,0x39,0x3f,0x4c,0xe1,0x38,0x44,0xbe,0xfd,0xd9,0x4e,0x60,0xee,0x30 +,0x30,0x36,0x38,0x49,0xce,0xaa,0xa8,0xca,0xc2,0xcb,0x2e,0x3b,0xdb,0xdf,0x53,0xdb,0xaf,0xaa,0xbe,0xdd,0xcc,0x3a,0x2d,0x27,0x2e,0x3f,0xd3,0xcc,0xc2,0xc4,0x73,0xc9 +,0x59,0x3a,0x27,0x2f,0x3f,0xcf,0xab,0xae,0xac,0xc7,0xb2,0xac,0xbc,0x37,0x26,0x2d,0x3b,0xaf,0xba,0xa7,0xbe,0x52,0xb0,0xc2,0x3f,0x2b,0x30,0x2a,0x42,0xbf,0xb1,0xbc +,0x34,0x44,0xc7,0xef,0x38,0x49,0x2d,0x2e,0xc5,0xb1,0xae,0xb7,0xbb,0xce,0xbd,0x3b,0x31,0x27,0x2b,0x4b,0xc7,0xa9,0xb0,0xaf,0xc6,0xc2,0xcc,0x32,0x2b,0x27,0x53,0xdd +,0xbb,0xba,0xe6,0xbf,0xb6,0xcb,0x2d,0x2b,0x21,0x2e,0xfc,0xab,0xa0,0xa5,0xbb,0xbc,0xb3,0xd3,0x58,0x2d,0x41,0x36,0x3d,0xbd,0xc4,0xa9,0xbe,0xb6,0xd3,0x2b,0x29,0x27 +,0x3c,0x40,0xcb,0xbe,0xb1,0xbf,0xaf,0x59,0x29,0x28,0x23,0x3a,0x43,0xbe,0xbb,0xb4,0xa0,0xa1,0xa9,0x3f,0x1f,0x22,0x4c,0xdc,0xac,0xaf,0xd9,0xae,0xcc,0xa2,0xb5,0x47 +,0x1e,0x1b,0x2a,0x39,0xc9,0xd6,0xab,0xbd,0xab,0xbb,0x71,0x2d,0x1f,0x2b,0x38,0xc9,0xba,0xa3,0xb2,0xae,0xaa,0xca,0x36,0x23,0x2a,0x2a,0xcf,0xbf,0xb3,0xad,0xaa,0x9f +,0xb5,0x41,0x1d,0x2c,0x3c,0x37,0x5a,0xdb,0xc4,0xee,0xb6,0xb2,0xb6,0x24,0x1a,0x1e,0x2f,0xbd,0xa9,0x9b,0xaf,0xa7,0xb1,0xc7,0x39,0x1e,0x1d,0x1e,0x3e,0xf2,0xa7,0xac +,0xa0,0xa7,0xba,0xaa,0x44,0x36,0x2c,0x3e,0x51,0xd0,0xc9,0xc0,0xad,0xb9,0xb2,0x28,0x1e,0x25,0x2b,0x32,0x43,0xb4,0xae,0xa1,0xad,0xac,0x49,0x26,0x23,0x2e,0xc9,0x4a +,0xe3,0xe0,0xb4,0xa5,0x9f,0xa8,0x39,0x27,0x27,0x3f,0x6d,0xce,0xd0,0xd3,0xb7,0xb8,0xab,0x3b,0x27,0x1d,0x27,0x3c,0xc3,0xbb,0xe3,0xae,0xb1,0xa3,0xc3,0x47,0x23,0x2a +,0xdf,0xea,0xbe,0x6a,0xb2,0xaf,0xac,0xaa,0xd1,0x2e,0x22,0x35,0x47,0xee,0x3e,0x54,0xb8,0xa1,0x9d,0xb6,0x2b,0x16,0x1c,0x36,0xb9,0xc1,0xd3,0x4b,0xd0,0xa4,0x9d,0xab +,0x26,0x1f,0x23,0x4a,0xb1,0xb7,0xc2,0xca,0xaf,0xa9,0xa9,0x3d,0x28,0x29,0x26,0x41,0x5f,0xec,0xb6,0xaa,0xb2,0xae,0x7e,0x20,0x20,0x2d,0xc0,0xb9,0xb7,0xbd,0xa8,0xa6 +,0xab,0xbf,0x25,0x21,0x1d,0x30,0x2e,0x30,0xcc,0xad,0x9d,0x9d,0x99,0xb2,0x2f,0x1c,0x23,0x63,0x69,0x4f,0x2c,0xc1,0xb4,0x9d,0xa9,0x2f,0x20,0x1b,0x3c,0x3c,0x4d,0xf0 +,0xb4,0xa9,0x9e,0xa3,0x59,0x37,0x1c,0x2a,0x3b,0xd5,0xc9,0xd5,0xb7,0xbd,0xa3,0xb6,0x3f,0x22,0x2a,0x3e,0x65,0x43,0xe2,0xa8,0x9f,0x9c,0xa9,0xbe,0x1f,0x1d,0x30,0x6b +,0xd8,0x3b,0x4f,0xb7,0xa3,0x9a,0xa2,0x75,0x1e,0x1b,0x1f,0x31,0x33,0x30,0x63,0xbb,0xa3,0xa7,0xab,0x37,0x2e,0xd1,0xd8,0x61,0x42,0x2f,0x3b,0xc2,0x4b,0xba,0xb3,0xc5 +,0xa9,0xcf,0x2e,0x2b,0x30,0x3c,0xbf,0x37,0x2d,0xd5,0x74,0xa8,0xb4,0xca,0x55,0xce,0xaf,0xa4,0xaf,0x33,0x46,0x5e,0xb6,0xb3,0x4f,0x1f,0x21,0x3b,0xbd,0xb2,0x50,0x3a +,0xe7,0xa8,0xa7,0xab,0x3b,0x26,0x4a,0x46,0xb8,0xd6,0x26,0x3d,0xba,0xb4,0xb8,0x30,0x1c,0x4f,0xb0,0xa7,0xb0,0x21,0x29,0x68,0x9f,0x9f,0xc6,0x26,0x29,0xc2,0xad,0xbd +,0x20,0x1b,0x29,0xa1,0x9b,0xb5,0x1f,0x1c,0x4e,0x9e,0x98,0xd1,0x1f,0x21,0xab,0x96,0xa0,0x5e,0x18,0x29,0xaa,0x9d,0xb3,0x23,0x17,0x2f,0xa3,0xa0,0xb7,0x16,0x1d,0xd9 +,0x9f,0x9e,0x48,0x18,0x23,0xa3,0x91,0x97,0x2d,0x16,0x21,0xad,0x98,0xa8,0x1d,0x10,0x2d,0xa1,0x9d,0xbb,0x15,0x1b,0xb3,0x97,0x9b,0x3e,0x14,0x20,0x9e,0x93,0x9c,0x23 +,0x12,0x2b,0xa9,0xa4,0xb4,0x1a,0x0f,0xd7,0x9c,0x97,0xbd,0x18,0x1e,0xab,0x96,0x97,0xc4,0x19,0x40,0xab,0x9d,0xa7,0x1b,0x10,0x27,0x9c,0xa0,0xd2,0x13,0x10,0xd1,0x9a +,0x98,0xb9,0x1b,0x1c,0xae,0x9b,0x9a,0x61,0x18,0x28,0xa1,0x95,0xac,0x1f,0x12,0x31,0x9d,0x9d,0xbf,0x17,0x14,0x3f,0x9a,0x9d,0x57,0x17,0x20,0x9e,0x97,0x9c,0x32,0x17 +,0x27,0xa4,0x9d,0xad,0x26,0x14,0x40,0xa6,0xa0,0xe0,0x16,0x1c,0xad,0x95,0x9c,0xde,0x17,0x29,0xa5,0x94,0xa4,0x28,0x16,0x22,0xaa,0xa9,0xc9,0x23,0x23,0xc9,0xaf,0xc8 +,0xd0,0x62,0xad,0xb9,0x52,0x4f,0x32,0xfc,0xaa,0x3b,0x2c,0x26,0x2d,0xb6,0xb7,0x44,0x34,0x2a,0x62,0x99,0xa4,0xd8,0x3f,0x3f,0xa6,0x9b,0xcb,0x31,0x27,0x36,0x9e,0xa8 +,0x28,0x22,0x1a,0x73,0x9f,0xb4,0x2b,0x1c,0x25,0xbd,0x9c,0xb2,0x42,0x38,0x55,0xa0,0x9a,0x3d,0x29,0x24,0x37,0x9c,0xa5,0x2d,0x25,0x20,0xca,0x98,0xb6,0x2a,0x1f,0x27 +,0x9e,0x99,0xcc,0x20,0x1c,0x5d,0x9d,0x9e,0x2c,0x19,0x1f,0xc8,0xa0,0xb5,0x28,0x1f,0x4f,0xa0,0x98,0xb0,0x25,0x23,0xe2,0x9b,0x93,0xb2,0x1f,0x1e,0x33,0xa2,0xa1,0x2a +,0x1a,0x1b,0x45,0xa4,0xbb,0x29,0x25,0x27,0xa8,0x97,0xa8,0x3c,0x26,0xbe,0x9d,0x9d,0x5a,0x25,0x28,0x3e,0xb0,0xaa,0x2e,0x1a,0x28,0xd9,0xa1,0xab,0x2e,0x2d,0x3c,0xb9 +,0xad,0xbe,0x41,0x48,0xe5,0xac,0xa9,0x37,0x27,0x33,0xbf,0xab,0xb9,0x39,0x2b,0x2d,0xbf,0xa9,0xbd,0x31,0x34,0x4a,0xae,0xab,0xc8,0x38,0x3c,0xbc,0xaf,0xc7,0x3e,0x2a +,0x29,0xfa,0xb5,0xb6,0x3a,0x2f,0x47,0xb5,0xa7,0xbe,0x35,0x32,0xbf,0xa5,0xa9,0xbb,0x2d,0x2e,0x42,0xb6,0xc8,0x2e,0x21,0x27,0xbe,0xb7,0xcb,0x32,0x27,0x3b,0xaf,0xac +,0xb0,0x35,0x3c,0xaf,0xa4,0xa1,0xb8,0x45,0x3d,0x5d,0xb7,0x69,0x3b,0x25,0x32,0xc8,0xdb,0xdd,0x36,0x3a,0x45,0xb1,0xde,0xb8,0xe2,0x52,0xbf,0xbe,0xb5,0x45,0x43,0xfd +,0xbd,0xc2,0x59,0x37,0x3a,0x5d,0xbf,0xc3,0x54,0xfb,0x3b,0x41,0xeb,0x5d,0xd6,0x30,0x60,0xc7,0xba,0xbd,0xfb,0x76,0x52,0x59,0xed,0xd9,0x38,0x35,0x2e,0x37,0x4a,0xd1 +,0xbe,0xc5,0xb4,0xb1,0xb5,0xb0,0xbe,0xbb,0xc5,0xe7,0xca,0x56,0x38,0x3a,0x36,0x36,0x36,0x2e,0x43,0x4f,0xe5,0xe0,0x5a,0xe6,0xf1,0xba,0xba,0xb1,0xbc,0x5a,0xde,0xc3 +,0xbe,0xc8,0xd4,0x5d,0xf8,0x48,0x38,0x37,0x35,0x2f,0x5b,0xe9,0xca,0xc8,0x3f,0x66,0xb9,0xc9,0xcd,0xbe,0xcf,0xc2,0xc3,0x44,0x5a,0x39,0x2f,0x57,0x49,0xc8,0x4a,0x57 +,0xd7,0xc2,0xbf,0x41,0x43,0xed,0xe5,0xb9,0xcd,0xec,0xba,0xbf,0xb5,0xb7,0x69,0x3a,0x30,0x2c,0x32,0x39,0x2f,0x3b,0xda,0xc9,0xad,0xb9,0xba,0xaf,0xb3,0xb6,0xb3,0x7a +,0x49,0x59,0x51,0xdb,0x3a,0x38,0x3b,0x35,0x31,0x36,0x35,0x36,0x55,0xb2,0xaf,0xb1,0xc5,0xd4,0xc4,0xd6,0x5f,0xdc,0x6a,0xcf,0xbc,0xbf,0xaf,0xcb,0x4d,0x3a,0x39,0x2a +,0x25,0x27,0x30,0xe0,0xc8,0xaf,0xa7,0xa9,0xab,0xb2,0xe1,0xd6,0x4a,0x35,0xfc,0xd9,0xd4,0xca,0x57,0x3d,0x4a,0x3c,0x37,0x3c,0x3c,0x4c,0xe4,0xb8,0xad,0xb7,0xc2,0xc3 +,0xc1,0xde,0x3b,0x40,0x35,0x4f,0xef,0xc8,0xb5,0xce,0x3e,0x38,0x30,0x2d,0x3d,0x33,0xca,0xad,0xa5,0x9f,0xa1,0xab,0xc0,0x42,0x31,0x34,0x28,0x26,0x25,0x2f,0x4a,0x6b +,0xd8,0x75,0xbb,0xcb,0x5e,0x54,0x3c,0x38,0xdb,0xb3,0xad,0xa2,0xb0,0xaa,0xb4,0xcf,0xdb,0x37,0x31,0x3a,0x5c,0x51,0x61,0x48,0x44,0x41,0x41,0x35,0x41,0x53,0x6d,0xaf +,0xb0,0xab,0xa8,0xc1,0xcb,0x52,0x32,0x2b,0x25,0x24,0x2d,0x4a,0x4e,0xbc,0xb7,0xb0,0xb1,0xbc,0x50,0x4d,0x32,0x2a,0xea,0xce,0xb0,0xaa,0xb2,0xb0,0xbb,0x42,0x3e,0x32 +,0x26,0x2b,0x32,0x55,0xbb,0xb7,0xb6,0xb2,0xb7,0xb8,0xb2,0xdb,0xd5,0xbe,0xc1,0xc2,0xcb,0x5c,0x3d,0x38,0x2d,0x2c,0x28,0x24,0x33,0x4a,0xcb,0xb6,0xbb,0xb4,0xc4,0xee +,0x54,0x3f,0x30,0x3b,0x53,0xaf,0xaa,0xad,0xac,0xb9,0xc4,0x3e,0x3a,0x2a,0x25,0x2a,0x41,0xe6,0xb0,0xaf,0xaf,0xa7,0xb1,0xaf,0xca,0x3b,0x67,0x5e,0x54,0x56,0x4f,0xfd +,0x46,0x42,0x44,0x35,0x2f,0x3b,0x58,0xbd,0xcb,0xaf,0xaf,0xc7,0xbc,0xcd,0x4a,0x39,0x3c,0x3a,0x43,0x3b,0xd3,0xcb,0xfa,0xe5,0x33,0x2c,0x2f,0x2b,0x4d,0xc2,0xb9,0xa8 +,0xab,0xa9,0x9e,0xa6,0xbb,0xd2,0x38,0x34,0x2d,0x2b,0x30,0x4d,0x42,0xd9,0xc2,0x4b,0xee,0x4f,0x3c,0x49,0x5d,0x3e,0xbf,0xaf,0xb1,0xa9,0xb3,0xc9,0xc2,0x3b,0x2f,0x43 +,0x32,0x4b,0xca,0x38,0x7d,0x56,0x3b,0x67,0x3e,0x31,0xf4,0x68,0xbd,0x9f,0xae,0xa7,0xa2,0xb6,0xbf,0x67,0x1f,0x22,0x1f,0x1e,0x40,0xf5,0x4a,0xaf,0xb3,0xb5,0xa7,0xd9 +,0x45,0x6b,0x34,0x45,0xb2,0x4a,0xb8,0xa8,0xba,0xb5,0xce,0x21,0x2c,0x28,0x1f,0x51,0x33,0x39,0xaf,0xb5,0xab,0xaa,0x49,0x4a,0x46,0x38,0xb4,0xab,0xbb,0xa9,0xba,0xe0 +,0xc7,0x36,0x24,0x2b,0x1b,0x26,0x6f,0x5e,0xa4,0x9f,0xa5,0x9d,0xac,0x44,0x4e,0x24,0x24,0xdd,0x3e,0xd8,0xa9,0xbc,0xa9,0xab,0x39,0x36,0x26,0x16,0x2d,0x2f,0x2a,0xb7 +,0xba,0xb2,0x9b,0xad,0xc5,0xb1,0x33,0xde,0xa7,0x35,0x50,0xca,0x2b,0xb8,0xbc,0x20,0x2e,0x1c,0x14,0xbf,0x5e,0xcd,0x9a,0xaa,0xa1,0x94,0xcb,0x4c,0xc8,0x1d,0x43,0xda +,0x1f,0x44,0xde,0x32,0x9d,0xaa,0x2b,0xb9,0x24,0x1d,0xb7,0x2c,0x2f,0x9e,0xbd,0x9e,0x8f,0xec,0xc2,0xbd,0x1d,0x40,0x2f,0x14,0x4f,0x57,0x33,0x98,0xb8,0x2b,0xab,0x25 +,0x2a,0xa7,0x22,0x3d,0x9e,0x5d,0x9b,0x96,0x32,0xa7,0xbe,0x1a,0x67,0x1d,0x0f,0xca,0x38,0xca,0x8f,0xda,0xc9,0xa3,0x1b,0x2d,0x4b,0x16,0xdd,0xa4,0xe7,0x95,0x9d,0x68 +,0x9b,0x53,0x19,0x3f,0x15,0x13,0xcd,0x23,0xfc,0x97,0xf0,0xa0,0x98,0x2f,0xb3,0xcd,0x17,0xc2,0x4c,0x27,0x97,0xa9,0xbb,0x97,0x2b,0x21,0x3b,0x0f,0x1c,0x54,0x20,0xad +,0x99,0xb1,0x97,0xa5,0x33,0xad,0x44,0x24,0xc2,0x2f,0x30,0x9e,0xac,0xad,0x9f,0x2f,0x28,0x3d,0x16,0x1f,0x2b,0x18,0xb4,0x9f,0xaf,0x95,0xa1,0x65,0xae,0x29,0x20,0x3a +,0x1d,0x40,0xa0,0xae,0x9d,0x9d,0x3b,0x60,0x34,0x1c,0x2b,0x1e,0x17,0x3c,0xf3,0xb9,0x96,0xa5,0xaf,0xa2,0x49,0x6c,0xda,0x24,0x44,0xc1,0x6b,0xa7,0xaa,0x3b,0x4e,0x2d +,0x1e,0x2b,0x1f,0x1f,0xe4,0xb8,0x9d,0x90,0x9e,0xa5,0xb3,0x37,0x46,0x2c,0x1a,0x1f,0x28,0x3f,0x9e,0xa1,0xb1,0xaf,0x36,0x3e,0x3a,0x24,0x2a,0x2a,0x3c,0x9d,0x98,0x9e +,0x9b,0xfb,0x59,0xd7,0x29,0x29,0x1a,0x15,0x38,0xbc,0xb1,0xa7,0x4c,0x3d,0xc1,0x60,0x48,0x37,0x2b,0x6a,0x9c,0x98,0x99,0xa8,0x31,0x7b,0x41,0x2a,0x29,0x1a,0x19,0x5c +,0xb8,0xab,0x9f,0x32,0x3d,0xbc,0x39,0x5a,0x2f,0x1c,0x69,0xa3,0x9f,0x92,0xa4,0x4e,0xae,0x4b,0x32,0x2c,0x15,0x17,0x38,0x6b,0xa4,0xa5,0xe0,0xbc,0xca,0xba,0xb2,0xdd +,0x27,0x34,0xcd,0xb2,0xa1,0xbe,0x41,0x4c,0x36,0x3a,0x3e,0x1e,0x1c,0x38,0xc3,0x9c,0x9e,0xb0,0xb6,0xbe,0xca,0xcc,0x35,0x1f,0x2b,0x4e,0xa6,0x9f,0xab,0x50,0x36,0x31 +,0x3a,0x31,0x1e,0x22,0x26,0xdb,0x9e,0xa5,0xae,0xb2,0xb6,0xaa,0xaa,0x3b,0x25,0x27,0x2e,0xad,0xa4,0xb2,0xd5,0x3c,0x2b,0x50,0x33,0x1e,0x1e,0x24,0xca,0x9f,0x9e,0xa7 +,0xb8,0x56,0xc3,0xaf,0x58,0x3b,0x2d,0x3d,0xac,0xa6,0xbf,0x3d,0x2d,0x24,0xe3,0x4a,0x29,0x2b,0x2c,0xc0,0x9a,0x9c,0xa4,0xad,0x5c,0xcc,0xd2,0x2a,0x1c,0x1a,0x24,0xcf +,0xa2,0xaf,0xf2,0x48,0x4e,0xb2,0xbb,0x49,0x2a,0x3b,0xc4,0x9e,0x9d,0xb1,0xcc,0x3b,0x59,0xc4,0x35,0x22,0x21,0x28,0xd7,0xa8,0xba,0xe9,0x39,0x35,0xcc,0xd9,0x39,0x2e +,0x50,0xbe,0x9e,0x9c,0xb0,0xd1,0xf3,0x3e,0xea,0x33,0x19,0x27,0x2b,0xce,0x9c,0xaf,0xcb,0xc6,0x47,0xc6,0xd4,0x27,0x26,0x38,0x7b,0x9e,0x9f,0xcf,0xc4,0x70,0x3b,0xbf +,0x35,0x20,0x2d,0x2b,0xca,0xa4,0x6f,0xec,0xb6,0x4a,0xac,0xb2,0x2f,0x4f,0x6a,0x47,0xa6,0xae,0x4e,0xc8,0x33,0x2e,0x67,0x23,0x21,0x69,0x3c,0xb0,0x9c,0xbc,0xae,0xb3 +,0x34,0xd0,0x3b,0x23,0x5b,0x54,0x38,0xa1,0xbe,0x5b,0xa4,0x5b,0x4e,0xba,0x1f,0x23,0x4e,0x22,0xd0,0xaa,0x39,0xa8,0xa6,0x3a,0xac,0xd2,0x29,0xb9,0x63,0x4e,0xa0,0x58 +,0x5d,0xaa,0x2e,0x30,0xfe,0x1d,0x2d,0xef,0x24,0xb0,0xaa,0x4d,0x9e,0xaa,0x3a,0xad,0x3d,0x28,0xb4,0x30,0x3c,0xa6,0x43,0xc4,0xa4,0x2d,0x3e,0x44,0x1a,0x3c,0x4a,0x32 +,0xa7,0xa3,0xb2,0x97,0xa4,0x4e,0xb8,0x28,0x1f,0x38,0x1e,0x28,0xbe,0x23,0xcf,0x9f,0x44,0xaf,0xb7,0x25,0xc5,0xee,0x3a,0xa0,0xb8,0xda,0x9c,0xbe,0x5e,0xbc,0x1f,0x21 +,0x3f,0x2c,0xe5,0xb4,0x29,0xb4,0xb5,0x3a,0xad,0x38,0x25,0xe0,0x37,0x52,0xa0,0xcb,0xb4,0x9d,0xb6,0xb1,0xd0,0x1c,0x24,0x3d,0x25,0xc3,0x56,0x25,0xab,0xad,0xb1,0xa1 +,0x41,0x24,0xda,0x38,0xb9,0xab,0x24,0x6b,0xa6,0xbd,0xae,0xde,0x1d,0x38,0xe3,0x67,0xb7,0x28,0x20,0xb1,0xab,0xab,0xa9,0x2d,0x28,0xb2,0xb6,0xac,0xde,0x1e,0x5b,0xab +,0xbd,0xbd,0x2d,0x15,0x3c,0xc5,0xb8,0xb5,0x27,0x34,0xa7,0x9e,0x9f,0xae,0x1f,0x2e,0xce,0xc6,0xb4,0x2d,0x1e,0xdc,0xa4,0xaa,0xa9,0x23,0x20,0xc2,0xbd,0xaf,0x36,0x13 +,0x1f,0xaf,0xa6,0x9c,0xcc,0x25,0x4e,0xc1,0xaa,0xaf,0x2b,0x2b,0xba,0xa6,0xab,0xe4,0x27,0x37,0xb0,0xa8,0xbd,0x2c,0x1e,0x4c,0xa5,0xab,0xab,0x2a,0x23,0x59,0xba,0xb5 +,0x2f,0x1a,0x24,0xbc,0xa3,0xa2,0x56,0x1d,0x28,0xc6,0xa2,0xaa,0x47,0x26,0x5a,0xab,0x9f,0xa0,0x39,0x33,0x45,0xb1,0xac,0x3e,0x1c,0x1f,0x39,0xb3,0xac,0x40,0x29,0x2d +,0xb5,0xa1,0xaa,0x54,0x24,0x32,0xca,0xaf,0xab,0x59,0x2e,0x3c,0xbd,0xae,0xad,0xcc,0xc7,0xca,0x73,0xe9,0x35,0x42,0x5b,0xbf,0xbf,0x3c,0x3b,0x4c,0xd4,0xbd,0xd9,0x28 +,0x2e,0x2f,0xd7,0xa9,0x62,0x2f,0x27,0x3d,0xad,0xa4,0xd0,0x3f,0x30,0x3e,0xaa,0xab,0xfe,0x33,0x3c,0xbe,0xa0,0xa8,0x3f,0x28,0x33,0xb2,0xa4,0xb9,0x2f,0x29,0x34,0xb0 +,0xa1,0xbd,0x35,0x23,0x27,0xe7,0xb4,0xb8,0xc3,0x4c,0x4a,0xda,0x49,0x53,0xde,0xe3,0xe4,0x48,0x2f,0x2a,0xe5,0xb2,0xa5,0xb7,0x3e,0x2e,0x2f,0xbf,0xa8,0xb2,0x47,0x3b +,0x2d,0xf2,0xc4,0xc2,0x5b,0x3b,0x4c,0xd1,0xba,0xf3,0xee,0x3d,0x49,0xb6,0xb7,0x6b,0x4d,0x38,0x4d,0xbf,0xc8,0xbc,0xc4,0xd3,0xbe,0x53,0x3e,0x3f,0x3a,0xec,0xbf,0xb6 +,0xc3,0xd6,0x54,0x4b,0x46,0x6d,0xe0,0x5c,0x51,0x40,0x3e,0x39,0xda,0xd4,0xc5,0xdc,0x31,0x2d,0x38,0x45,0xcc,0xb6,0xd0,0xce,0xe8,0xe1,0xb2,0xbb,0xbd,0xbe,0x63,0x4f +,0xd1,0x55,0xd3,0xb0,0xbc,0xcc,0x3d,0x2e,0x36,0x47,0xcf,0xc4,0x52,0x38,0x41,0xdf,0xc2,0xb8,0xce,0x4b,0x43,0x5c,0x6f,0xd2,0x45,0x57,0x58,0xd3,0xbc,0x66,0xec,0x56 +,0x4d,0x5c,0xc1,0xcf,0xbe,0x7c,0x45,0x48,0x4f,0xca,0xc1,0xe8,0x3c,0x34,0x40,0x49,0xcb,0xc8,0xe6,0xd9,0xd4,0xb0,0xae,0xbf,0x55,0x38,0x2e,0x5d,0xbe,0xb4,0xdf,0x37 +,0x3a,0x45,0xd3,0xbb,0xd6,0x39,0x35,0x3d,0xdd,0xd0,0x70,0x6a,0x42,0xc7,0xb0,0xb6,0xd2,0x3a,0x3d,0xdf,0xbc,0xbc,0xc9,0x5d,0xd6,0xbc,0xba,0xe8,0x35,0x2b,0x2e,0x4d +,0xc4,0xdc,0x63,0x41,0x52,0xbe,0xb7,0xbf,0x4a,0x35,0x3f,0xd5,0xbc,0xb9,0xc8,0xdb,0xe3,0xbc,0xce,0x3c,0x2e,0x30,0x4f,0xbc,0xb8,0xd0,0xe2,0xcf,0xc2,0xc8,0x49,0x2d +,0x2e,0x42,0x70,0xb8,0xd0,0x49,0xd9,0xf7,0xc1,0xc4,0x3d,0x3e,0x42,0x6d,0xc1,0xbc,0xb4,0xb6,0xb2,0xb2,0x4c,0x30,0x3e,0x3d,0x6d,0x4c,0x39,0x5d,0xc8,0xb0,0xaf,0x4b +,0x2f,0x2c,0x38,0x5b,0x6f,0xdb,0x35,0x4a,0xba,0xb4,0xaf,0xd3,0x3b,0x45,0xee,0xc8,0xc2,0x50,0x4f,0xba,0xb6,0xb6,0xcf,0x3d,0x3d,0x56,0xc9,0xd2,0x4b,0x3a,0x64,0xb7 +,0xad,0xb3,0x4b,0x2e,0x3a,0x4d,0xd9,0x55,0x36,0x31,0x3f,0xc2,0xc2,0x5a,0x31,0x37,0xef,0xb9,0xae,0xbd,0x3a,0x31,0x6b,0xae,0xab,0xc7,0x41,0x2c,0x34,0xc9,0xb2,0xb0 +,0xbf,0xe5,0x55,0x4f,0x78,0x62,0x41,0x46,0xc2,0xb9,0xcf,0x39,0x46,0x4e,0xbf,0xb6,0x7a,0x37,0x26,0x2c,0xde,0xa9,0xa6,0xa6,0xc7,0x47,0x3b,0x2f,0x3c,0x3e,0x3e,0x51 +,0x51,0xd1,0xbb,0xb2,0xac,0xad,0x75,0x45,0x2a,0x27,0x35,0x38,0xcc,0xbd,0xbe,0xba,0xd8,0x3d,0x4b,0x3e,0xe2,0xed,0x5a,0x49,0x49,0xb7,0xaa,0xa2,0xae,0x4f,0x39,0x2e +,0x30,0x61,0x3e,0x3a,0xbe,0xb3,0xa8,0xad,0x3b,0x31,0x2d,0x55,0xb3,0xcd,0x2d,0x26,0x35,0xc6,0xa6,0xae,0x48,0x28,0x24,0x3f,0xae,0xb3,0xba,0x4e,0x3b,0xaf,0xa9,0xaf +,0xc2,0x3f,0x38,0xd4,0xcb,0xc9,0xd2,0x38,0x56,0xbe,0xb3,0xd0,0x34,0x27,0x3a,0xb9,0xbb,0xba,0x45,0x2a,0x3a,0x51,0x5b,0xf5,0x33,0x2d,0xd5,0xb8,0xac,0xa8,0xc9,0xc7 +,0xbe,0xc4,0xd7,0x37,0x21,0x32,0x5f,0xe3,0xaf,0xbc,0xc9,0xc3,0xd7,0xdd,0x6a,0x2d,0x31,0x4e,0xce,0xb0,0xb8,0x65,0xdd,0xce,0xde,0xcb,0x36,0x25,0x34,0x3e,0xb9,0xa2 +,0xac,0xb8,0xce,0x3d,0x41,0xe6,0x37,0x3f,0x37,0x28,0x4d,0xba,0xb6,0xae,0xbd,0x3a,0x58,0x3a,0x33,0xb5,0x3e,0x3f,0xca,0xcf,0xa6,0xab,0x57,0x6b,0x34,0x2d,0xbc,0xc8 +,0x51,0x7c,0x4c,0xd7,0xab,0xaa,0xb9,0x4c,0x23,0x2c,0x58,0x3e,0xfb,0x52,0x3d,0xe1,0xc9,0xee,0xb2,0xd6,0xfd,0xad,0xdc,0x6e,0x3e,0x2f,0x6e,0xab,0xb5,0xda,0x2b,0x17 +,0x37,0xb1,0xac,0xa5,0x60,0x2c,0x4c,0xba,0xab,0xad,0x2a,0x25,0x4d,0x5f,0xb4,0xb6,0x34,0x3d,0xae,0xa8,0xa1,0xfa,0x1c,0x2a,0x43,0xb0,0xa2,0xea,0x2c,0x39,0x48,0xac +,0xa4,0x39,0x22,0x21,0x2c,0xc5,0xa9,0xd6,0x5a,0x73,0x41,0xb4,0xd1,0x33,0x4e,0x45,0x55,0xad,0xc9,0x54,0xd4,0x5e,0xab,0xa9,0xdb,0x6d,0x37,0x36,0xb9,0xbb,0x6d,0xef +,0x32,0x2c,0x4d,0x2d,0x36,0xda,0xd0,0xab,0xaa,0x57,0x53,0x4f,0xe6,0xa5,0xae,0x44,0x32,0x2b,0x30,0xb2,0xb8,0xef,0x4b,0x29,0x2f,0xca,0x60,0xb6,0xae,0x41,0xc5,0xb3 +,0xdd,0xb9,0x5a,0x2d,0x35,0x1f,0x30,0xb0,0xb2,0xac,0xa5,0xc7,0xb7,0xaf,0x5a,0x45,0x2c,0x1d,0x2c,0x52,0xde,0xb2,0xc4,0xb6,0xa4,0xa9,0xb9,0x41,0x1c,0x1b,0x2f,0x5f +,0xb1,0xad,0x4b,0x52,0xb1,0xad,0xb0,0x4b,0x1e,0x20,0x28,0xda,0x9d,0xa4,0xc8,0xba,0xc3,0xb5,0xb2,0x33,0x22,0x1d,0x24,0x54,0xba,0xc6,0xb2,0xb4,0xaf,0xa6,0xc3,0x2c +,0x2b,0x2d,0xe4,0xa6,0xb4,0xc4,0xe9,0x69,0xad,0xab,0x39,0x2b,0x20,0x22,0x5a,0xca,0x4d,0xd7,0xbe,0xb1,0xa3,0xce,0x25,0x26,0x23,0x7c,0xa2,0xbf,0xdb,0xcc,0x5d,0xad +,0xa0,0xb9,0x5d,0x2a,0x25,0x64,0xb9,0xc0,0xb1,0x5d,0x41,0xcb,0x30,0x3c,0xce,0x37,0x58,0x63,0x3c,0xbb,0xc5,0xbd,0xa9,0xe8,0x27,0x28,0x25,0xdc,0xa9,0xbf,0xdc,0x4d +,0x40,0xab,0xa0,0xe1,0x3b,0x26,0x1f,0x6c,0xb8,0xd2,0xda,0x34,0xd4,0x96,0xad,0x23,0x14,0x0e,0x32,0x8f,0x99,0xaa,0x9a,0xba,0xa1,0x93,0x99,0xd8,0x0d,0x09,0x1f,0x35 +,0xb1,0xaf,0x2c,0xb6,0x4f,0x0c,0x05,0x29,0x93,0x8a,0x88,0x96,0x21,0x08,0x16,0x93,0x8b,0x90,0xac,0x0a,0x09,0xac,0xa9,0x25,0xaa,0x9e,0xc6,0x6f,0x3c,0xae,0xda,0x33 +,0xa4,0x3f,0x1e,0xd8,0xc3,0xc1,0x95,0xa4,0x0a,0x05,0x1c,0xaa,0x9c,0xac,0x9f,0xdd,0x15,0x2c,0x9d,0x90,0x86,0x8e,0x3f,0x64,0x2e,0x0a,0x0e,0x5a,0xa4,0xa2,0x15,0x0f +,0x20,0x2e,0xa2,0x9f,0xab,0xca,0x1b,0x0d,0x3c,0x8d,0x91,0xa3,0x9d,0xb1,0xc5,0xa8,0xa4,0xa1,0x3d,0x20,0x23,0x1a,0xbd,0x9a,0x1e,0x1e,0xfc,0x0d,0x06,0x16,0x9b,0x84 +,0x8a,0x9b,0x3b,0x0d,0x11,0x39,0xbd,0x96,0x8c,0xbe,0x0f,0x2e,0xaa,0x46,0x44,0x9c,0x9a,0x60,0x14,0x13,0x28,0xa4,0x8d,0x9e,0x2e,0x37,0x23,0x1f,0xa0,0x9e,0x28,0x0d +,0x0c,0x50,0x97,0x9d,0x9b,0xa3,0x2f,0x1b,0x13,0x39,0x89,0x83,0x92,0x67,0x28,0x11,0x11,0x40,0xa9,0xa4,0x1e,0x07,0x0b,0x30,0x90,0x95,0xb7,0x9d,0xb4,0x12,0x0c,0x22 +,0xaa,0x94,0x8e,0x8d,0x9f,0x3f,0x32,0x72,0xac,0x9f,0x4b,0x0c,0x1b,0x9f,0xa3,0x3c,0x52,0x1e,0x09,0x08,0x1b,0x90,0x87,0x8e,0xa8,0x1b,0x17,0x2e,0x2f,0xa5,0x89,0x94 +,0x25,0x0e,0x19,0xde,0xb0,0xa7,0xa3,0xc2,0x1c,0x11,0x1a,0x9e,0x8b,0x97,0xd9,0x3d,0x36,0x21,0x32,0xcd,0x5a,0x28,0x18,0x24,0xaa,0x9f,0xb0,0x51,0xcb,0x9e,0x3d,0x1b +,0xa0,0x8e,0x8f,0x9f,0x49,0x1e,0x18,0x21,0xc8,0xa3,0xe6,0x16,0x07,0x0f,0x9e,0x8f,0xae,0xb7,0xa7,0x2c,0x12,0x10,0x1c,0x52,0x9a,0x8c,0x8b,0x98,0x5d,0x25,0x22,0x9e +,0x96,0x35,0x17,0x2e,0xaf,0xb7,0xdb,0x25,0x1a,0x0f,0x17,0xb4,0x99,0x95,0xa3,0x47,0x4e,0xbe,0x2d,0x2c,0xaa,0x9d,0xa9,0x26,0x12,0x18,0xdf,0xa3,0x8f,0x8f,0xaf,0x1e +,0x0b,0x1d,0xa0,0x9d,0xbd,0xf9,0x34,0x26,0x38,0x3d,0x6f,0xca,0x4d,0x20,0x1e,0x31,0x46,0x5a,0xa8,0x8d,0x9b,0x2c,0x24,0xb3,0x90,0x8b,0x98,0x25,0x0f,0x0e,0xcf,0x97 +,0x94,0xb9,0x0a,0x03,0x18,0x9a,0x94,0x98,0xaf,0x2c,0x17,0x0f,0x1f,0xd7,0x9c,0x91,0x90,0x9a,0xc2,0x21,0x24,0x9f,0x8e,0xa1,0x17,0x10,0x25,0xb3,0xb3,0x2d,0x1a,0x10 +,0x18,0x47,0x97,0x8d,0x94,0xdd,0x35,0x55,0x22,0x27,0x32,0xa2,0x93,0xa9,0x2d,0x15,0x22,0xac,0x92,0x95,0xad,0x1a,0x0d,0x23,0x97,0x8c,0x9f,0x2c,0x16,0x16,0x1f,0x3f +,0x57,0x52,0x37,0x29,0x35,0x57,0xad,0x58,0x2a,0xc8,0xb0,0xcb,0x4c,0xaf,0x97,0x8d,0x94,0xb4,0x36,0x36,0xc5,0xbf,0x5e,0x28,0x14,0x0b,0x12,0x5f,0xa4,0x9c,0xa1,0xab +,0xcd,0x1e,0x11,0x15,0x3c,0x98,0x8b,0x8f,0x98,0x48,0x1b,0x32,0xaf,0xa4,0x4e,0x20,0x22,0xd1,0xb5,0x3e,0x1e,0x19,0x1a,0x24,0xba,0x9b,0x95,0xaa,0xc7,0xab,0xb4,0xc3 +,0x39,0x2c,0x52,0xd0,0x37,0x30,0x2e,0xd4,0xa5,0xa5,0x9b,0xb1,0x21,0x1b,0x26,0xcd,0xa7,0xaa,0xaf,0xb7,0x45,0x2c,0x1f,0x1d,0x2f,0x3d,0xc3,0xc6,0x40,0x25,0x1d,0xee +,0x9d,0x98,0xa4,0x73,0x37,0xc8,0xa8,0x9f,0xa2,0xa9,0xaf,0x74,0x52,0x32,0x1e,0x13,0x17,0x24,0x3d,0xc2,0xd0,0xa9,0x9f,0x9f,0x3b,0x15,0x14,0x29,0x9c,0x8d,0x8b,0x9f +,0x2a,0x1c,0x3e,0xa2,0x9d,0xa9,0x32,0x1f,0x24,0x22,0x1c,0x20,0x2a,0x39,0xec,0x53,0x46,0x34,0xbb,0x97,0x92,0xa1,0x26,0x17,0x20,0xb3,0xa4,0xb1,0x37,0x2a,0x4e,0xa8 +,0x92,0x99,0xc7,0x1f,0x1f,0x47,0xb1,0xa4,0xab,0xba,0xe8,0x2f,0x18,0x1c,0x26,0x5b,0xa9,0xb4,0x37,0x1e,0x20,0x33,0xa4,0xa4,0xb7,0xd3,0x4c,0xac,0xa6,0xad,0xbd,0xbf +,0xc2,0xaf,0xab,0x51,0x2d,0x1f,0x22,0x2a,0x28,0x26,0x36,0xcd,0xa1,0xa2,0x38,0x1c,0x15,0x2c,0x9f,0x8f,0x92,0xa3,0xf0,0x36,0xbf,0xa7,0xa4,0xb0,0x37,0x26,0x2d,0x30 +,0x2b,0x35,0x26,0x22,0x29,0x20,0x38,0xc2,0xa9,0x9a,0x9d,0xab,0xca,0x37,0x37,0x48,0x3d,0x2f,0x25,0x31,0xc9,0x9c,0x9b,0xa4,0xbf,0x2a,0x2c,0x3a,0xd7,0xb6,0xa7,0xb0 +,0xb1,0x5b,0x1e,0x1d,0x25,0x57,0xad,0xb5,0x30,0x1d,0x1c,0x45,0xa2,0x9f,0xa9,0xf5,0x32,0xce,0xa9,0xad,0xb7,0xde,0xcf,0xaa,0xa8,0xbe,0x37,0x27,0x26,0x2a,0x21,0x20 +,0x2a,0x2f,0xba,0xa4,0xb9,0x34,0x1f,0x24,0xd1,0x9d,0x95,0x99,0xad,0xc1,0xbe,0xbd,0xa7,0xa1,0xb1,0x3d,0x2d,0x20,0x24,0x37,0x3e,0x3d,0x26,0x1a,0x18,0x25,0xbb,0x9b +,0x9d,0xaa,0xaf,0xd4,0xc9,0xbc,0x32,0x21,0x1d,0x28,0x7b,0xa6,0x9e,0xa3,0xb6,0x6e,0xd9,0xcd,0x6a,0xbc,0xb5,0xba,0xc2,0x36,0x2d,0x31,0x4a,0xcf,0xc9,0x45,0x33,0x27 +,0x25,0x61,0xba,0xc4,0xbf,0xdd,0xf5,0xbd,0xb7,0xb7,0xb2,0xc3,0xc8,0xae,0xb3,0xa5,0xaa,0x3a,0x31,0x22,0x1a,0x20,0x27,0x36,0xe4,0x34,0x2a,0x2a,0x28,0x4b,0xab,0xa5 +,0xa1,0xa4,0xba,0xae,0xa5,0xa7,0xa9,0xab,0xb0,0xba,0x42,0x2a,0x28,0x2b,0x3d,0xdb,0x40,0x24,0x1d,0x18,0x32,0xa1,0x9a,0x9c,0xab,0x58,0x57,0xdd,0x4c,0x3f,0x26,0x1f +,0x2a,0x37,0xac,0x9f,0xab,0xbd,0xe9,0x45,0x41,0xcd,0xb9,0xb3,0xba,0x49,0x39,0x36,0x2f,0x46,0x40,0x45,0xbb,0x4c,0x2a,0x2b,0x2f,0x66,0xaa,0xa8,0xb1,0xbb,0x39,0xd6 +,0xad,0xa7,0x9d,0xa3,0xb4,0xb4,0xd1,0x34,0x3a,0x2f,0x2c,0x2f,0x23,0x23,0x20,0x1d,0x2a,0x44,0x4c,0xd4,0xca,0x5a,0xbb,0xaf,0xa2,0x99,0x9c,0xa8,0xb2,0x4b,0x3e,0xbb +,0xcf,0xcc,0x53,0x2c,0x35,0x3f,0x45,0x60,0x39,0x20,0x24,0x26,0x36,0xb8,0xa8,0x9d,0x9c,0xaa,0xda,0x36,0x20,0x2c,0x36,0x33,0x5d,0x7e,0x3b,0xcf,0xae,0xb1,0xa3,0xa8 +,0xc6,0xd0,0x3f,0x41,0x43,0x36,0x53,0xcb,0x44,0x47,0xda,0x2c,0x2e,0x2f,0x37,0xc9,0xde,0x49,0xdc,0xf0,0xbf,0xa8,0xa9,0xa7,0xa7,0xb8,0xbb,0xaf,0xb8,0xb5,0xbf,0x3d +,0x45,0x32,0x20,0x27,0x28,0x22,0x27,0x24,0x20,0x31,0x2d,0x55,0xab,0xaf,0xa4,0xa4,0xb0,0xa5,0x9e,0xa9,0xa6,0xb2,0x3c,0x41,0x2b,0x26,0x3a,0x36,0x3e,0xc2,0x35,0x2f +,0x3d,0x2c,0xee,0xac,0xa6,0xa9,0xab,0xe5,0x7b,0xdb,0x46,0xba,0xdd,0x38,0x35,0x2f,0x2f,0xcf,0xc6,0xc3,0xb4,0x51,0xbc,0xb5,0xd6,0xbb,0x5a,0x29,0x30,0x34,0x32,0x53 +,0x33,0x30,0xc8,0xca,0xc9,0xcb,0x38,0x31,0x46,0x4c,0xbd,0x64,0x2d,0xd6,0xae,0x9f,0x94,0x95,0x9f,0xa5,0xd1,0x3a,0xd6,0x52,0x38,0x2c,0x1a,0x18,0x21,0x25,0x3a,0x3b +,0x25,0x3e,0x46,0xd3,0xa7,0xb3,0xba,0xa6,0xa2,0xa1,0x9e,0xbd,0xc4,0x55,0x2b,0x37,0x3f,0x3b,0x6f,0x3a,0x20,0x2e,0x35,0x3f,0xd7,0x36,0x33,0x75,0xbc,0xa2,0x9e,0xb4 +,0xd6,0x4d,0x4a,0xad,0xb0,0xed,0x5d,0x38,0x2a,0x65,0xda,0xf8,0xb1,0x4c,0x43,0xd2,0xd1,0xaa,0xa9,0xca,0xe0,0x51,0x3c,0x4d,0x38,0x22,0x1f,0x19,0x29,0xb5,0xae,0xc1 +,0x3d,0x31,0xbf,0xa3,0xae,0xae,0xd7,0x43,0xae,0xa2,0xa2,0x9f,0xbf,0x4c,0xde,0x40,0x3b,0x32,0x1d,0x18,0x1d,0x1e,0x38,0xb5,0xd5,0x7b,0x4b,0x4b,0xa6,0xa2,0xa8,0xa9 +,0xc3,0xd1,0xa2,0x9e,0x9e,0xae,0x2c,0x22,0x2c,0x28,0x2a,0x35,0x1c,0x1c,0x29,0x39,0xb6,0x9f,0xa1,0xa8,0xea,0x39,0xcf,0xc0,0xbe,0xbf,0x32,0x34,0xbf,0xa7,0xa2,0xbc +,0x39,0x3e,0xbd,0xcc,0xcd,0x39,0x22,0x33,0xc8,0xba,0xb0,0xe9,0x39,0x3f,0x36,0x3c,0x58,0x4d,0x49,0x3d,0x2a,0x2a,0x40,0xcb,0xad,0xcb,0x28,0x35,0xce,0xa7,0x98,0x9d +,0xb6,0xab,0xaf,0xa9,0xa0,0xbd,0x48,0x30,0x1b,0x1c,0x28,0x25,0x2d,0x26,0x1f,0x36,0xc9,0xb6,0xa3,0xa7,0xb5,0xa8,0xab,0xb0,0xad,0x65,0x45,0x63,0xc0,0xaf,0xac,0x3e +,0x1e,0x23,0x31,0xce,0x66,0x1f,0x14,0x20,0xbb,0x9d,0x9c,0xa9,0x4b,0x2a,0x2e,0x5c,0xbe,0x9b,0x97,0xc8,0x1e,0x1d,0x2f,0xa7,0x9a,0xc3,0x30,0xcf,0xa3,0xaa,0x3b,0x17 +,0x1d,0xa8,0x91,0x9a,0x37,0x1c,0x18,0x2c,0xa3,0xa2,0x38,0x1b,0x19,0x11,0x2f,0x9a,0x92,0x9b,0x2f,0x0e,0x1b,0x9c,0x8c,0x8e,0xcc,0x16,0x27,0x95,0x8d,0xae,0x19,0x12 +,0x1b,0x4f,0xc0,0x1f,0x12,0x1b,0x5b,0x9a,0x97,0x9c,0xae,0xe7,0x1d,0x1c,0x9b,0x8a,0x90,0x1f,0x08,0x09,0xa8,0x82,0x86,0xb8,0x08,0x08,0x20,0x9f,0x9f,0x37,0x1b,0x1b +,0x2a,0xb2,0x96,0x9d,0xb0,0x30,0x10,0x1a,0xa3,0x91,0xa9,0x1b,0x0e,0x3f,0x8a,0x84,0xa8,0x0d,0x07,0x1d,0x8c,0x85,0xa2,0x0d,0x07,0x10,0xa4,0x87,0x8b,0xad,0x17,0x0c +,0x0d,0xf5,0x8e,0x90,0xde,0x0b,0x05,0x2d,0x87,0x88,0xa4,0x16,0x0d,0xd2,0x8b,0x8d,0x37,0x11,0x19,0xb7,0x8f,0x92,0xea,0x18,0x0e,0x0c,0x2a,0x99,0x96,0x6e,0x0d,0x02 +,0x11,0x8c,0x80,0x89,0x26,0x06,0x10,0x99,0x84,0x92,0x2e,0x0e,0x0e,0x28,0x96,0x92,0x9c,0xbe,0x1a,0x0e,0x1d,0xa9,0x9e,0xb3,0x1a,0x0f,0x4e,0x8b,0x8a,0xaf,0x13,0x0b +,0x36,0x8e,0x8e,0xd6,0x11,0x0e,0x1a,0x9f,0x8e,0x95,0xa2,0x26,0x0f,0x16,0xa1,0x8f,0x92,0x38,0x06,0x08,0x41,0x88,0x89,0xba,0x0c,0x08,0x2b,0x9a,0x9e,0x3c,0x29,0x1f +,0x5a,0x94,0x92,0x99,0xa7,0x2f,0x1e,0x3b,0x9d,0x9f,0x46,0x16,0x0f,0x29,0xa2,0x99,0xae,0x25,0x1b,0x2b,0xcc,0x4b,0x33,0x40,0xac,0xa1,0xad,0xaa,0xb4,0xcf,0x3d,0xce +,0xca,0xd0,0xd3,0x29,0x1e,0x2c,0xa0,0x98,0xa8,0x28,0x10,0x1c,0x78,0xaf,0xbe,0x40,0x23,0x27,0xae,0xa7,0xa2,0x9f,0xad,0x3f,0x25,0x2f,0xd5,0xa4,0x59,0x20,0x2f,0xa1 +,0x8e,0x9b,0x3d,0x14,0x18,0xa4,0x91,0xa0,0x1a,0x0a,0x0d,0x34,0x93,0x90,0x9c,0x3a,0x14,0x10,0x3a,0x93,0x8f,0x9e,0x17,0x08,0x18,0x95,0x86,0x8f,0x3f,0x0d,0x16,0xc2 +,0x9d,0xb2,0x2c,0x1b,0x1e,0x77,0xa1,0xa3,0xb7,0x3b,0x21,0x28,0xb6,0x9c,0xa6,0x2a,0x10,0x13,0xac,0x88,0x8b,0xa9,0x19,0x14,0x40,0x96,0x96,0xc2,0x1c,0x12,0x10,0x34 +,0x98,0x93,0x99,0x61,0x15,0x10,0x33,0xa9,0xa6,0x4e,0x1c,0x21,0xab,0x8e,0x9d,0x47,0x22,0x24,0xae,0x9f,0xb8,0x20,0x1a,0x1d,0x38,0x9e,0x94,0xa0,0x45,0x1c,0x16,0xd0 +,0x91,0x93,0xce,0x10,0x08,0x18,0x9d,0x8c,0x98,0x31,0x16,0x1d,0xb8,0x98,0xa2,0xc6,0x3c,0x2f,0xee,0x9f,0x9d,0x9f,0xb3,0x29,0x1a,0x2a,0xbe,0xfa,0x24,0x12,0x15,0x6a +,0x93,0x91,0xbc,0x1e,0x17,0x4a,0x94,0x94,0xae,0x23,0x17,0x17,0xe5,0x9a,0x94,0x9b,0x30,0x10,0x13,0xb1,0x97,0x9e,0x26,0x0d,0x18,0xaf,0x8e,0x93,0xdb,0x1c,0x1e,0xbe +,0x9c,0xb1,0x2c,0x1e,0x1d,0x73,0xa1,0x99,0x9c,0xcf,0x1e,0x1a,0x62,0x93,0x8f,0xb0,0x16,0x09,0x1a,0x99,0x89,0x96,0x2c,0x0f,0x0f,0x63,0x9b,0x9e,0x3b,0x17,0x14,0x21 +,0xac,0x9a,0x98,0xa9,0x29,0x21,0xf3,0x9d,0x9b,0xeb,0x1c,0x18,0x2a,0xa1,0x97,0xbe,0x1f,0x18,0x2e,0xa7,0x9c,0xa7,0x2c,0x12,0x17,0x45,0x94,0x8b,0x9e,0x26,0x0f,0x1d +,0xaa,0x8d,0x8f,0x29,0x10,0x16,0xe5,0x91,0x8d,0xb3,0x19,0x1b,0x36,0xc6,0xa9,0xba,0x1a,0x12,0x24,0xbb,0xa8,0x9b,0xa3,0x2d,0x2f,0xb7,0x9d,0xa6,0x4f,0x1a,0x0f,0x2e +,0x9c,0x91,0xb0,0x20,0x17,0x1e,0xba,0x9c,0x9b,0x2b,0x18,0x1b,0x23,0xac,0x90,0x8e,0xbe,0x1c,0x16,0x37,0x97,0x96,0xd7,0x11,0x0c,0x21,0x99,0x8d,0x9b,0x37,0x1e,0x25 +,0x9b,0x8b,0xa9,0x20,0x1c,0x12,0x21,0x8d,0x8b,0x1e,0x0d,0x2a,0x26,0xa6,0x8b,0xb7,0x0d,0x0f,0x3c,0xec,0x9a,0x8f,0x49,0x1a,0x41,0x5e,0x35,0x9c,0x93,0x38,0x0e,0x17 +,0xc3,0xb8,0xb3,0xa2,0xa6,0x19,0x0e,0x96,0x8b,0xcc,0x25,0x2a,0x13,0x20,0x89,0x89,0x22,0x0d,0x1e,0x42,0x99,0x8a,0xbe,0x07,0x0b,0xab,0x91,0x9d,0x9f,0xb1,0x0f,0x0c +,0x95,0x86,0xce,0x20,0xc8,0x15,0x0c,0x97,0x88,0x2c,0x1e,0xbc,0x18,0x18,0x9a,0x96,0x24,0x2a,0x3a,0x18,0x32,0x8f,0x8f,0x1f,0x0f,0x2e,0xa2,0xb2,0x9f,0x91,0x1f,0x04 +,0x2c,0x86,0x98,0x3b,0x9c,0x1f,0x06,0xbf,0x85,0xa1,0x1c,0x2e,0x12,0x14,0x99,0x8c,0x2c,0x0f,0x2f,0xbb,0xc9,0xad,0x97,0x5d,0x0c,0x2f,0x8b,0x9b,0x1b,0xc9,0xae,0x10 +,0x63,0x86,0xa4,0x10,0x46,0x55,0x16,0xa5,0x8b,0xe3,0x1a,0x4f,0x25,0x14,0xa2,0x8c,0xa7,0x16,0x18,0x2d,0x31,0xd6,0x99,0xa4,0x0c,0x08,0xaa,0x95,0x48,0xaa,0xa1,0x0d +,0x13,0x8c,0x8f,0x41,0xdd,0xd6,0x19,0xaa,0x85,0x9f,0x14,0x1c,0x40,0x73,0x9f,0x92,0xaa,0x11,0x0c,0xb3,0x90,0xc1,0x3d,0x9f,0x1c,0x0a,0xa6,0x8d,0x30,0x33,0x9e,0x1a +,0x13,0x98,0x9e,0x19,0xd2,0xa0,0x16,0x1d,0x95,0x9f,0x1d,0x1e,0xd1,0x4e,0x3d,0xa8,0x9d,0x2c,0x09,0x30,0x8d,0xa6,0x30,0xa0,0x2e,0x0a,0xa5,0x85,0xae,0x25,0xac,0x1c +,0x0f,0x91,0x8a,0x26,0x15,0xd9,0x31,0x38,0x97,0x96,0x2b,0x11,0x34,0x96,0xa0,0x2c,0xbc,0xc8,0x0e,0x23,0x8b,0xa4,0x12,0x37,0x33,0x0a,0x48,0x87,0xad,0x1b,0xad,0x3e +,0x12,0xa1,0x88,0xa9,0x1a,0x23,0x27,0x1c,0x50,0x92,0x99,0x15,0x0c,0xbe,0xa0,0x1f,0xb0,0x96,0x16,0x12,0x8f,0x8e,0x1f,0xc1,0x9e,0x1d,0x4d,0x89,0x9c,0x13,0x1f,0xbe +,0x4b,0xb4,0x91,0xb8,0x0e,0x0e,0xbb,0x98,0xce,0x43,0xad,0x1c,0x09,0xaf,0x8c,0xdf,0x2b,0x9d,0x2e,0x10,0x9f,0x92,0x34,0x2a,0xb9,0x25,0x1e,0x9b,0x9c,0x27,0x28,0xed +,0x3d,0x2f,0xae,0x9e,0x2b,0x0d,0x2b,0x97,0xb8,0x3d,0x9f,0xcb,0x0f,0x3a,0x8c,0xa1,0x2d,0xc3,0x35,0x1b,0xa5,0x8f,0xba,0x2e,0xcf,0x2f,0x33,0x9c,0x9d,0x1f,0x0f,0x2b +,0xac,0xb6,0xd6,0xb4,0xd7,0x15,0x29,0x93,0x98,0x2e,0x29,0x2c,0x10,0x2e,0x92,0x9b,0x48,0xc5,0x38,0x1d,0xb9,0x93,0xb3,0x21,0x41,0x2d,0x1a,0xd9,0x96,0xa9,0x1b,0x16 +,0x3f,0xae,0xb4,0xa1,0xb5,0x1a,0x1b,0xaa,0x98,0xc4,0xc3,0xe9,0x20,0xcd,0x8f,0x9e,0x25,0x21,0x24,0x1e,0xa6,0x88,0xa1,0x13,0x14,0x48,0xd7,0xd9,0xa1,0xb8,0x17,0x19 +,0xa9,0x9c,0xb0,0xbb,0xc8,0x20,0x1c,0xa2,0x98,0xc8,0xbe,0x64,0x18,0x21,0xa1,0xa0,0x34,0xdd,0xaf,0x27,0x21,0xa6,0xa2,0x1c,0x0f,0x23,0xe8,0xbf,0x9e,0x9d,0x35,0x17 +,0x42,0x9f,0xa9,0xb5,0xba,0x24,0x1c,0xa0,0x94,0xad,0x2d,0x27,0x22,0xd8,0x8b,0x8d,0x25,0x0c,0x1c,0x35,0x52,0x9f,0x98,0x49,0x1c,0x53,0xa3,0xad,0xbd,0xb9,0x1e,0x0d +,0x24,0x97,0x92,0xa5,0x6b,0x1e,0x1a,0x42,0xa0,0xac,0xc5,0xb6,0x2e,0x1f,0xd9,0x97,0xa7,0x20,0x1c,0x25,0x2b,0xb0,0x97,0x42,0x0d,0x0e,0x43,0x9d,0x9b,0x9e,0xdc,0x29 +,0x58,0x98,0x95,0xab,0x26,0x0f,0x17,0xaa,0x8c,0x9a,0x2c,0x1c,0x1c,0x20,0xc0,0x94,0xa2,0x1a,0x15,0x2f,0xb0,0x9e,0x99,0xaf,0x1c,0x18,0xb4,0x92,0x91,0x9f,0x28,0x12 +,0x1c,0x6c,0xa8,0x9a,0x9d,0x66,0x13,0x1e,0xa1,0x99,0xe1,0x1a,0x16,0x15,0x4f,0x90,0x93,0x2f,0x0f,0x19,0x43,0xa0,0x97,0xac,0x1e,0x19,0xc3,0x9a,0x95,0xa4,0x1f,0x0c +,0x20,0x93,0x8f,0xb8,0x1f,0x15,0x0f,0x20,0x97,0x8b,0xaa,0x23,0x20,0x2c,0xcd,0x9a,0x9a,0x21,0x0e,0x1f,0xa6,0x95,0x94,0x9f,0x29,0x1e,0x2f,0x57,0xb6,0x98,0xa0,0x1d +,0x10,0x34,0x94,0x9a,0xc9,0x1f,0x0f,0x17,0x9f,0x8d,0xb6,0x10,0x0c,0x23,0xae,0x97,0x8d,0xae,0x1e,0x25,0xb4,0x9b,0x92,0xa5,0x11,0x0a,0x32,0x90,0x91,0xa9,0x29,0x0f +,0x0c,0x44,0x8d,0x95,0x2a,0x18,0x23,0x39,0xb7,0x9d,0xa8,0x1b,0x16,0xc9,0xab,0x9f,0x9d,0xad,0x22,0x16,0x27,0x71,0x95,0x8e,0xaa,0x10,0x15,0xa8,0x95,0xaa,0x28,0x18 +,0x11,0x3d,0x93,0x8f,0x54,0x15,0x1e,0x22,0x3e,0x9a,0x94,0x42,0x16,0x1f,0xac,0x8d,0x8a,0xc1,0x0a,0x10,0xa3,0x8c,0x96,0x6e,0x17,0x09,0x19,0x96,0x8d,0xb0,0x1e,0x1e +,0x24,0x2b,0xa8,0x91,0xc6,0x12,0x15,0x2c,0xa9,0x8f,0x8f,0x46,0x16,0x18,0x28,0xa3,0x8b,0x92,0x1d,0x0d,0x2b,0x9e,0x9e,0xab,0x2c,0x13,0x0f,0x39,0x93,0x99,0x31,0x13 +,0x10,0x11,0xa7,0x86,0x92,0x24,0x10,0x20,0x9e,0x86,0x8a,0x1c,0x07,0x2a,0x91,0x94,0x9d,0xbf,0x12,0x0a,0x23,0x9a,0x99,0xbd,0x39,0x21,0x0e,0x27,0x8c,0x8a,0x2e,0x0f +,0x18,0x20,0x9e,0x88,0x94,0x1a,0x12,0x1f,0x24,0x98,0x86,0x95,0x15,0x0c,0x23,0xcc,0xa1,0x98,0xe5,0x0a,0x08,0x7e,0x8b,0x96,0x53,0x1a,0x0a,0x12,0x94,0x84,0xac,0x19 +,0x19,0x27,0x9b,0x86,0x94,0x12,0x16,0xc3,0xad,0xab,0x9c,0xbd,0x0c,0x09,0x2b,0x92,0x91,0xa0,0xd5,0x11,0x08,0xcf,0x85,0x94,0x18,0x15,0x18,0x1f,0x92,0x87,0x9f,0x24 +,0x1f,0x15,0x1c,0x8f,0x83,0xa2,0x0c,0x0b,0x26,0xa2,0x8e,0x97,0x1e,0x04,0x0e,0x90,0x88,0xaa,0x1e,0x12,0x07,0x26,0x87,0x89,0x44,0x18,0x19,0x25,0x8e,0x83,0x9a,0x10 +,0x0f,0x26,0xc3,0x96,0x91,0x33,0x07,0x06,0x2c,0x8e,0x8f,0x9e,0x36,0x0a,0x0d,0x98,0x87,0xa9,0x27,0x1f,0x10,0x29,0x8d,0x89,0xad,0x23,0x10,0x0c,0xb4,0x84,0x88,0x27 +,0x08,0x0c,0x4a,0x8f,0x8c,0xa5,0x0c,0x03,0x28,0x8b,0x8e,0xa9,0x31,0x0d,0x08,0xb3,0x86,0x92,0xba,0x1d,0x0d,0x1e,0x8c,0x88,0xd6,0x16,0x1a,0x2d,0xa7,0x8d,0x96,0x1c +,0x06,0x0c,0xaf,0x91,0x93,0xa8,0x13,0x05,0x1c,0x8b,0x89,0x9e,0x31,0x0e,0x08,0xad,0x86,0x90,0x45,0x16,0x09,0x0f,0x90,0x80,0x8e,0x19,0x0c,0x18,0xbb,0x8f,0x8f,0x54 +,0x08,0x0c,0xc4,0x9f,0xab,0xa2,0x39,0x09,0x14,0x92,0x89,0x9d,0xb4,0x1b,0x0a,0xbb,0x87,0x8d,0x23,0x12,0x15,0x1f,0x9b,0x87,0x90,0x13,0x04,0x0f,0xab,0x91,0x8e,0xac +,0x09,0x03,0x34,0x89,0x8c,0x9b,0x33,0x0a,0x13,0x8f,0x86,0x9b,0x1f,0x0c,0x08,0x22,0x8a,0x87,0xb7,0x0e,0x14,0x69,0x99,0x8f,0x96,0x1f,0x06,0x13,0xaa,0x9f,0xa0,0xab +,0x15,0x08,0x26,0x8d,0x8b,0x93,0xb9,0x0f,0x0b,0xa9,0x88,0x94,0x2e,0x16,0x13,0x25,0x96,0x89,0x9e,0x12,0x09,0x21,0xa5,0x95,0x91,0x28,0x04,0x09,0xa3,0x87,0x8c,0xaf +,0x12,0x07,0x2b,0x88,0x89,0xa8,0x18,0x09,0x0d,0xac,0x86,0x8b,0x38,0x0d,0x10,0x35,0x9b,0x8f,0x9b,0x1a,0x0c,0x23,0xa9,0x9e,0x9c,0xcc,0x0d,0x0c,0xeb,0x91,0x96,0xa3 +,0x2c,0x11,0x2d,0x8f,0x8a,0xa3,0x2c,0x13,0x10,0x3b,0x93,0x8e,0x53,0x0e,0x0c,0x25,0x9a,0x89,0x8e,0x18,0x03,0x0e,0x9c,0x8a,0x8e,0xbc,0x0d,0x0a,0x40,0x8d,0x8e,0xa1 +,0x1d,0x0a,0x11,0x9f,0x88,0x96,0x25,0x0e,0x13,0xc1,0x8f,0x8c,0xaf,0x0b,0x0c,0x55,0x98,0x92,0xa2,0x1e,0x09,0x0f,0xa7,0x8f,0x93,0xaa,0x1a,0x0e,0x44,0x8e,0x8d,0xa4 +,0x25,0x18,0x18,0xc0,0x90,0x94,0x42,0x0d,0x10,0x31,0x9d,0x8e,0xa6,0x0f,0x07,0x1d,0x97,0x8b,0x90,0x4c,0x0c,0x0f,0xb8,0x8e,0x93,0xaf,0x12,0x07,0x1e,0x91,0x84,0x90 +,0x22,0x0b,0x0f,0xb4,0x8d,0x90,0x2e,0x0b,0x0f,0x3a,0x98,0x91,0x9e,0x1d,0x0d,0x1a,0xb9,0x98,0x9a,0xeb,0x16,0x21,0x98,0x8d,0x91,0xad,0x1b,0x0e,0x1b,0x9d,0x91,0x9f +,0x25,0x0e,0x16,0xcc,0x91,0x90,0x51,0x0d,0x08,0x1c,0x9d,0x8b,0x91,0x2d,0x0f,0x1e,0xa9,0x98,0x90,0xaf,0x0f,0x0a,0x35,0x94,0x93,0xad,0x22,0x16,0x23,0xa4,0x96,0xa0 +,0x30,0x1b,0x2b,0xc5,0xa1,0x9f,0x3b,0x13,0x13,0x33,0xb5,0x9a,0x95,0xef,0x18,0x45,0x9b,0x9c,0xa1,0xe4,0x19,0x13,0x29,0x9f,0x96,0x9e,0x3b,0x19,0x1d,0x3c,0x9f,0x9b +,0x39,0x16,0x1d,0x41,0xa1,0x92,0xa1,0x1a,0x16,0x41,0xab,0x9c,0x9b,0x2c,0x10,0x1f,0xa5,0x93,0x9c,0x4e,0x16,0x16,0x25,0xac,0x94,0x9f,0x2c,0x1d,0x2d,0x59,0xa1,0x9c +,0x42,0x19,0x21,0x44,0xbe,0x9c,0xa9,0x24,0x22,0xb6,0xa0,0xa9,0xaa,0x51,0x20,0x21,0x5e,0x9c,0x9a,0xe5,0x19,0x12,0x1e,0xe4,0x9a,0x9f,0x2a,0x1e,0x2f,0xbb,0x96,0x90 +,0xbe,0x15,0x1a,0x32,0xcf,0x99,0x93,0xc6,0x1e,0x2d,0x7c,0xa4,0xa2,0xf6,0x1f,0x18,0x29,0xed,0x9f,0xaa,0x3a,0x32,0x2e,0x3d,0xb1,0xae,0x27,0x27,0x5a,0xc5,0xa6,0x97 +,0xa6,0x24,0x26,0x30,0x44,0xa8,0x9d,0xbd,0x28,0x2a,0x3c,0xaf,0xa2,0x5d,0x24,0x1f,0x1f,0x38,0xb1,0xb2,0x45,0x7b,0xca,0x6a,0xa7,0xa0,0xdb,0x35,0x43,0x38,0xff,0xa1 +,0xa2,0x56,0x2f,0x48,0xfb,0xc0,0xbe,0x35,0x2f,0x2c,0x37,0xbd,0xa9,0xb8,0x46,0x52,0x33,0x3c,0xdb,0xcc,0x3e,0x47,0xec,0x3d,0xba,0xa2,0xbd,0x2b,0x38,0xcb,0xbf,0xbc +,0xef,0x3e,0x32,0xd0,0xb8,0xb3,0xc7,0x2f,0x2c,0x3c,0x58,0xd0,0xb4,0x61,0x37,0x38,0x3f,0x79,0xa5,0x9d,0x5f,0x2f,0x58,0x3e,0x3c,0xbd,0xae,0xd5,0xcc,0xbf,0x54,0x39 +,0x39,0x38,0x44,0xd4,0xde,0xbe,0xbb,0xc9,0x43,0x42,0x54,0xc8,0xa4,0xb9,0x2f,0x31,0x43,0x3d,0xc9,0xa6,0xe6,0x2d,0x49,0xbf,0x54,0xe0,0x6d,0x34,0x32,0x36,0x49,0xc4 +,0xab,0xbd,0x58,0x47,0x3c,0x4d,0xba,0xee,0x4b,0xbe,0xca,0x6e,0xbb,0xc4,0x28,0x3f,0xae,0xbc,0xda,0xc2,0xce,0x30,0x34,0x44,0x56,0xb7,0xb2,0x54,0x33,0x3a,0x39,0xbc +,0xaa,0xbf,0x46,0x3a,0x4d,0xbd,0xa5,0xb9,0x3f,0xc8,0x4f,0x26,0x3d,0xb5,0xbb,0xbe,0xba,0x4a,0x35,0x58,0x66,0x32,0x34,0x3c,0x70,0xb4,0xba,0x3d,0x2a,0x36,0x49,0xbf +,0xb2,0xce,0x7d,0xcd,0x3c,0x4d,0xaf,0xb4,0xde,0xdb,0xd9,0x2e,0x4c,0xae,0xb7,0x42,0x35,0x48,0xf4,0xae,0xb9,0x49,0x34,0x35,0x2f,0x3a,0xd0,0xc8,0xb1,0xb4,0xcc,0xbc +,0xbc,0xd8,0xd9,0xe6,0x2c,0x2a,0xaf,0xa4,0xb7,0x3f,0x43,0x48,0x50,0xbd,0xf5,0x30,0x31,0x3a,0x44,0xce,0xc2,0xce,0x51,0x3e,0x2e,0x34,0x47,0xb9,0xac,0xd1,0x3c,0xe0 +,0xa9,0xcb,0x41,0x4d,0x4c,0x4f,0xbb,0xa9,0xde,0x3d,0x3e,0x70,0xcd,0xbf,0xb9,0x48,0x3c,0x33,0x2d,0x3b,0xbe,0xac,0xcc,0x37,0x3c,0xd9,0xcd,0xb9,0xae,0xbc,0x4d,0x5f +,0xb2,0xc3,0x3a,0x48,0xed,0xed,0xd6,0xcf,0xde,0x3d,0x4b,0x40,0x3d,0xbc,0xb4,0x5d,0x2c,0x2f,0x3e,0xd8,0xaf,0xad,0xd8,0x23,0x2b,0xe0,0xba,0xdc,0x46,0xd4,0xed,0xc2 +,0xc9,0xc8,0xe1,0xcf,0xd1,0x2f,0x37,0xd7,0xb3,0xc6,0xc4,0xc5,0x4c,0xc6,0xac,0xd7,0x25,0x26,0x39,0xcc,0xc6,0xbb,0xbb,0xd9,0xde,0xbc,0xb0,0xc2,0xce,0x3d,0x26,0x25 +,0x4a,0xb5,0xaf,0xae,0xbf,0x67,0x63,0xaf,0xbb,0x2c,0x24,0x2b,0x4b,0xbf,0xa9,0xb5,0x55,0x3d,0x3d,0x3b,0x49,0xdd,0xdd,0x66,0x36,0x57,0xbe,0xb3,0xab,0x73,0x29,0x20 +,0x2e,0xb3,0xab,0xb0,0xbb,0xc5,0xc8,0xb4,0xbd,0x3c,0x28,0x2b,0x3f,0xe9,0xb9,0xac,0xb3,0x75,0x45,0x3f,0xf8,0xf2,0xf3,0x30,0x2a,0x49,0xae,0x9d,0xaa,0x5d,0x23,0x27 +,0x38,0xc8,0xad,0xd4,0xca,0x67,0xdf,0xc1,0xb6,0xb4,0x55,0x29,0x1e,0x25,0x47,0xa7,0xaa,0xe5,0x67,0xdd,0xb4,0xc6,0x39,0x1f,0x1f,0x3a,0xc7,0xa5,0xa7,0xbe,0x5c,0xcd +,0xbd,0xb1,0xb0,0x46,0x2e,0x2b,0x2f,0xdd,0xa4,0x9e,0xba,0x2b,0x22,0x34,0xaf,0xa9,0xc9,0x36,0x2b,0x42,0xbf,0xb0,0xba,0x3d,0x2d,0x38,0xe6,0xbc,0xb2,0xca,0x4e,0x3b +,0x3d,0xb7,0xa9,0xbb,0x2b,0x23,0x32,0xca,0xa7,0xb3,0x38,0x28,0x3e,0xbe,0xb0,0xbc,0x3e,0x29,0x26,0x39,0xd4,0xaf,0xac,0xb4,0xde,0x2d,0x2d,0xbf,0xa9,0xb2,0xc6,0xe9 +,0xd7,0xb7,0xac,0xd8,0x25,0x1f,0x2d,0xd2,0xa7,0xa4,0xbe,0x56,0x6d,0xbd,0xba,0xd5,0x44,0x23,0x1d,0x2c,0xb5,0x9f,0xa1,0xaf,0x44,0x32,0x2f,0xec,0xcb,0x3c,0x2e,0x34 +,0x4c,0xd2,0xa5,0xab,0xbf,0xd8,0x3d,0x2c,0x2f,0xd3,0xc9,0x3d,0x2c,0x2f,0xe1,0xaf,0xa7,0xcf,0x2a,0x24,0x45,0xa7,0xaa,0xdf,0x3d,0x4a,0xbf,0xaf,0xbb,0x46,0x1f,0x1c +,0x2f,0xcf,0xa7,0x97,0x98,0xab,0xca,0x4d,0x49,0xe9,0x2a,0x1d,0x26,0xab,0x92,0x96,0x44,0x19,0x17,0x1b,0x3b,0x41,0xc8,0x2d,0x28,0xae,0x94,0x90,0x98,0xc1,0x17,0x21 +,0x3b,0x2c,0x1d,0x27,0xad,0x93,0x90,0xaa,0x24,0x1b,0x26,0x43,0x37,0x1e,0x1d,0x23,0xb4,0x93,0x94,0x9e,0xbc,0x56,0x2d,0x2d,0x27,0x27,0x33,0xca,0x9b,0x8e,0x9d,0x1f +,0x19,0x1e,0x4a,0xb2,0x2e,0x0d,0x1f,0x8e,0x88,0x98,0x4d,0x26,0x2d,0x44,0x24,0x16,0x18,0x28,0x9b,0x8c,0x93,0xb6,0x3f,0x2e,0x18,0x2b,0x5e,0x2c,0x1b,0x17,0xa9,0x8a +,0x8e,0xad,0x43,0xc5,0xad,0x3d,0x12,0x0e,0x18,0xa8,0x8e,0x97,0xbe,0x38,0x31,0x1b,0x26,0xbf,0xb6,0x22,0x1f,0xbd,0x91,0x8f,0xae,0x68,0x49,0xc0,0x26,0x1a,0x0e,0x12 +,0x96,0x83,0x8f,0x1f,0x1a,0x21,0x25,0x3b,0x29,0x18,0x19,0x34,0x93,0x8a,0x91,0x9b,0x9b,0xbe,0x16,0x19,0x27,0x17,0x0e,0xcb,0x92,0x93,0xcd,0x1e,0x21,0x43,0xa2,0xb3 +,0x22,0x0d,0x1e,0x95,0x86,0x91,0xad,0xe6,0x2d,0x27,0x18,0x1b,0x14,0x17,0xa9,0x98,0x9f,0xc2,0xda,0xbf,0x4b,0xf9,0xd1,0x47,0x1e,0x23,0x97,0x8d,0xa6,0x48,0xb9,0xbb +,0x2d,0x28,0x20,0x1b,0x27,0xb5,0x97,0x9b,0xbd,0x3e,0xc1,0x50,0x22,0x39,0x3f,0x19,0x1d,0xb4,0xa6,0xc5,0xc8,0xbd,0x4a,0x58,0x3a,0x35,0x24,0x25,0xb9,0x96,0x91,0xc2 +,0x62,0xb6,0xaf,0x4c,0x30,0x3e,0x36,0x3c,0x4d,0x59,0x32,0x3b,0x6e,0x2d,0x1b,0x1e,0x4e,0x95,0x91,0x9a,0x96,0x9c,0x22,0x17,0x34,0x31,0x1e,0x2b,0xaa,0xab,0xbc,0x5d +,0x2f,0x20,0x4e,0xb6,0xb4,0x26,0x11,0x3f,0x8f,0x8e,0xb6,0xbc,0x63,0x2e,0x23,0x21,0x32,0x28,0xc8,0x9f,0xbe,0x37,0x3c,0x64,0x44,0x32,0x44,0xd1,0x5a,0x27,0xb0,0x8e +,0x9a,0x5a,0xdf,0xb1,0x45,0x2f,0x46,0x25,0x1f,0x46,0xa6,0x95,0x9f,0x42,0x42,0xb8,0x30,0x20,0x51,0x25,0x11,0x2b,0x9f,0xa2,0xb2,0xa9,0x4f,0x28,0x2e,0x24,0x2a,0x20 +,0x28,0xad,0x98,0x9e,0xd7,0xa0,0x9e,0xd6,0x2f,0x2f,0x24,0x1f,0xdd,0xa2,0xa6,0xa9,0xa5,0xab,0x43,0x14,0x14,0x25,0x5c,0x3f,0xbf,0x9b,0xaa,0x65,0xcf,0xad,0xe3,0xe4 +,0xe4,0x1f,0x14,0x3f,0x97,0x90,0x98,0xcb,0xdc,0xba,0x2c,0x1a,0x2f,0x2b,0x27,0xdf,0xc8,0x6e,0x4d,0xa5,0xb0,0x30,0x29,0x22,0x29,0x40,0x3d,0xc0,0xa0,0xac,0xbe,0xb0 +,0xc8,0x2e,0x4e,0xfe,0x3a,0xe0,0xaf,0xa5,0xac,0xb5,0xad,0xb7,0xef,0x28,0x20,0x26,0x2f,0x53,0xb8,0xa3,0xba,0x51,0x6c,0x4c,0x29,0x21,0x3e,0x3a,0x31,0xf0,0xba,0xb5 +,0xbe,0xd7,0xb9,0xa4,0xb3,0x3e,0x37,0x38,0x53,0xab,0xa8,0xb6,0xb7,0xae,0x5c,0x24,0x2e,0x32,0x30,0x2c,0x20,0x2f,0xbf,0xb7,0x52,0x39,0x49,0xcc,0xaf,0xb7,0x2f,0x52 +,0x9f,0x9e,0xa2,0xab,0xbf,0xc3,0x6c,0x20,0x23,0x44,0x72,0x44,0x3a,0x39,0x5c,0xb2,0xb9,0xd3,0x3b,0x31,0x55,0x43,0x3a,0xb9,0xaf,0xb6,0x6d,0x31,0x3a,0xdb,0xb7,0xb7 +,0xc3,0x3e,0x2d,0x4c,0xb7,0xc0,0xc0,0xba,0xc6,0x48,0x56,0x52,0x35,0x6c,0x69,0xbb,0xae,0xe7,0x37,0x31,0x2e,0x35,0xbf,0xd4,0x51,0x7c,0xd8,0x63,0xbf,0xb1,0xaf,0xb0 +,0x36,0x25,0x35,0xc5,0xbc,0xbc,0x5e,0xc8,0xb0,0xba,0xde,0x3a,0x39,0xe3,0xc2,0x3a,0x2a,0x38,0xb2,0xab,0x7b,0x2d,0x40,0xc3,0xbd,0x44,0x2f,0xfd,0xb0,0xbf,0x3c,0x37 +,0xbf,0xab,0xce,0x35,0x30,0xdc,0xc5,0x4c,0x2a,0x32,0xac,0xa5,0xb9,0x3e,0x2e,0x3e,0xbc,0xbd,0xf5,0xda,0xca,0xb1,0xb6,0xdf,0x3e,0x3b,0x3e,0x49,0x5e,0xdc,0x5a,0x2e +,0x2e,0x4b,0xb3,0xa7,0xaa,0xca,0x44,0x3a,0x4e,0xcd,0xbc,0xb6,0xd6,0x3a,0x2f,0x39,0xfe,0xbe,0xbc,0x3e,0x2c,0x2f,0x36,0xe2,0xb4,0xb4,0xc5,0x6f,0x38,0x57,0xac,0xae +,0xb2,0x68,0x25,0x38,0xbb,0xaf,0xcd,0x33,0x38,0xbf,0xc9,0x3a,0x31,0x3c,0xc9,0xb2,0xba,0x5d,0xc4,0xaf,0xc7,0x32,0x37,0xdc,0xad,0xbd,0x2d,0x22,0x2f,0xac,0xa6,0xb4 +,0x58,0x3a,0x4c,0x6a,0x31,0x36,0xdb,0xbf,0xbf,0x54,0x5f,0xb7,0xb3,0x4d,0x39,0x41,0xf5,0xc7,0x50,0x3b,0x5e,0xee,0xc5,0xbe,0xde,0x47,0x56,0x47,0x35,0x63,0xd1,0xc1 +,0xb3,0xb2,0xdb,0x53,0x5d,0xca,0xbb,0x57,0x43,0x2f,0x38,0xc9,0xb7,0xb7,0x58,0x2a,0x3d,0xe5,0x49,0xd1,0x4e,0x58,0xba,0xbc,0x66,0xc5,0xad,0xbb,0xb8,0x56,0x2c,0x4f +,0x49,0x42,0x4a,0x3d,0xea,0xbc,0x54,0x2e,0x38,0x6f,0xb0,0xbd,0x61,0x41,0x4c,0xb9,0xb7,0x7a,0x65,0xc6,0xb2,0xcd,0x3c,0x40,0x66,0xc0,0x59,0x35,0x2b,0x3f,0xb2,0xbd +,0x47,0x56,0xfa,0xcd,0xba,0xbc,0xbf,0xb8,0x5a,0x2e,0x4d,0x4f,0x5e,0xc3,0x4a,0x3b,0x49,0x4e,0x51,0xd8,0xcc,0xe4,0xd3,0xb4,0xaf,0xd3,0x4f,0x47,0x34,0x3b,0x70,0xd6 +,0x67,0x72,0xd9,0x61,0xff,0x43,0xc8,0xc9,0x3e,0x3e,0x39,0x3e,0xb9,0xae,0xb9,0xbc,0xd5,0xba,0xb9,0x5b,0x37,0x34,0x2a,0x44,0xba,0xd3,0x6a,0xdf,0xd2,0xb3,0xbd,0xe2 +,0xec,0x47,0x4d,0x35,0x38,0x5a,0xb0,0xb6,0xe1,0x48,0x40,0xe0,0xf6,0xdd,0x64,0x59,0xd4,0xd0,0x4c,0xe9,0xa5,0xac,0x31,0x1e,0x1e,0x2d,0xbc,0xaf,0xb7,0xbd,0x5b,0xee +,0xbe,0xcd,0xd6,0xcc,0x3a,0x2a,0x32,0x3d,0xbf,0xab,0xa4,0xa3,0x59,0x34,0x2f,0x32,0x3d,0xf7,0x3a,0x3b,0x69,0xcb,0xa8,0xaa,0xaf,0xbd,0xc4,0x43,0x37,0x33,0x3e,0x58 +,0x42,0x4c,0xbd,0xcc,0x4c,0x3d,0x35,0x56,0xcd,0x5e,0xba,0xaa,0xbd,0xbd,0xb3,0xc8,0x5d,0x60,0x2a,0x25,0x1f,0x2c,0xc5,0xa8,0x9d,0xa9,0x59,0x29,0x2e,0x6a,0xc6,0x3b +,0x31,0x55,0xce,0xb3,0xa9,0xa8,0xbb,0xbc,0x45,0x26,0x2a,0x34,0x53,0xe3,0xfe,0x51,0xc9,0x4c,0xed,0xbb,0xba,0xb1,0x4a,0x2b,0x43,0xc4,0xb5,0xa7,0xb5,0x40,0x35,0x24 +,0x29,0x58,0x71,0x5b,0x59,0x5c,0xbb,0x9f,0xa1,0xae,0x46,0x35,0x30,0x24,0x27,0x45,0xb6,0xae,0xb1,0x56,0xc7,0xb2,0xdb,0x3b,0x2f,0x2f,0x40,0x4c,0x4d,0xb6,0xa2,0xa8 +,0xc4,0x41,0x35,0x3c,0x56,0x5f,0x57,0x54,0x5f,0xbc,0xce,0xcf,0x65,0x40,0x4b,0xdd,0x4b,0x3b,0x40,0x35,0xb9,0xa8,0xa6,0xab,0x4c,0x28,0x23,0x2f,0x4f,0xbc,0xdc,0xe8 +,0xc9,0xc5,0xa8,0xa0,0xc3,0x2d,0x2a,0x22,0x27,0x30,0x4d,0xb2,0xa8,0xab,0xb1,0x65,0x39,0x3e,0xd7,0xe6,0x7e,0x41,0x3b,0x5d,0xbe,0xa2,0xa3,0xc3,0x2a,0x25,0x26,0x37 +,0x36,0xe1,0xa7,0xa1,0xb1,0x62,0x3b,0x4e,0xc4,0xcc,0x56,0x2e,0x34,0x32,0x54,0xad,0x9d,0x9e,0x4d,0x1f,0x1f,0x35,0xde,0x4a,0x3f,0x57,0xaf,0xab,0x9e,0xab,0x75,0x3d +,0x2e,0x2e,0x26,0x26,0x3a,0xae,0xa9,0xa5,0xb3,0x69,0x38,0x33,0x53,0x3d,0x32,0x3a,0xcd,0xb5,0xa6,0x9e,0xae,0x49,0x32,0x37,0x30,0x3b,0x28,0x20,0x33,0xae,0x98,0xa0 +,0x4a,0x2a,0x3c,0xc8,0x66,0x3e,0x2c,0x3c,0xc2,0xaa,0x9f,0xab,0xbb,0x2f,0x25,0x29,0x47,0x39,0x3a,0x4b,0xc0,0x9f,0x9f,0xae,0x33,0x32,0x41,0x39,0x1f,0x1f,0x3c,0xa6 +,0x98,0x9e,0xae,0x6b,0x39,0x2f,0x3a,0x49,0x2a,0x2a,0x33,0x53,0xa7,0x9d,0xad,0x53,0xec,0xc3,0xf8,0x29,0x1c,0x22,0xb3,0x9c,0x9e,0xbe,0x2f,0x2d,0x46,0xaf,0xbd,0x2e +,0x1e,0x1f,0xec,0x9f,0x99,0xa6,0x49,0x2a,0x2a,0x4f,0x53,0x32,0x2e,0xc5,0xad,0x9f,0x9f,0xb9,0x2e,0x28,0x45,0x37,0x1f,0x1b,0x31,0xad,0x9b,0x9f,0xad,0xd4,0x52,0xb7 +,0xca,0x2b,0x1b,0x25,0xbd,0xa8,0x9d,0xad,0x3b,0x22,0x3b,0xaf,0xb8,0x2f,0x18,0x1c,0xcc,0x9a,0x9b,0xb4,0x2f,0x46,0xa5,0xa7,0x32,0x19,0x26,0xbd,0xa3,0xa4,0xb7,0x44 +,0x29,0x2d,0x5c,0xb8,0x2d,0x1c,0x24,0xbd,0x9c,0x98,0x9f,0x75,0x44,0xcc,0xce,0x24,0x15,0x1f,0xb6,0x9d,0xa6,0xcb,0x3c,0xdc,0xb2,0xbc,0x3d,0x22,0x20,0x3f,0xae,0xad +,0xb4,0xdf,0x4e,0xc9,0xa3,0xa6,0x34,0x16,0x14,0x37,0x9d,0x98,0xaa,0x39,0x25,0x3f,0xa0,0xa9,0x20,0x14,0x29,0xab,0xa3,0xa8,0xb9,0xbd,0xc4,0xc6,0xba,0x3f,0x1f,0x1c +,0x37,0xbc,0xad,0xa3,0xb4,0x28,0x30,0xb3,0xf6,0x25,0x2d,0x4b,0xb3,0x9e,0xcd,0xc7,0x97,0x8c,0x93,0x20,0x05,0x00,0xbd,0x8c,0x9b,0x98,0x9c,0x29,0x0e,0x1c,0x1f,0xb0 +,0xa0,0xa3,0xa9,0x1f,0x0e,0x18,0x24,0x0d,0x2b,0x89,0x80,0x86,0x29,0x0a,0x1e,0x9c,0x89,0x8f,0xbd,0x14,0x25,0x28,0x0d,0x12,0x1b,0x3e,0x2f,0x1e,0x1b,0x6d,0x99,0xb3 +,0xb3,0xae,0x29,0x2d,0x8e,0x92,0xa4,0x91,0x99,0xa2,0x9d,0xb8,0x23,0x1c,0x0c,0x02,0x0d,0xd7,0x3d,0xad,0xd1,0x37,0xa5,0x9f,0xab,0x5e,0xbc,0x2c,0xca,0x8d,0x8a,0xa4 +,0x1b,0x0c,0x13,0xa0,0x8f,0x99,0x35,0x25,0xd0,0x2b,0x1d,0x13,0x2d,0x98,0x99,0x9d,0x31,0x0f,0x0b,0x0b,0x1e,0xc1,0x95,0x84,0x83,0xa1,0x17,0x29,0xb4,0xa7,0xaa,0xbd +,0x5a,0xad,0x1c,0x0a,0x37,0xaa,0xba,0x24,0x0c,0x07,0x1c,0x97,0x96,0xc4,0x58,0x49,0x9f,0x8d,0x97,0x9d,0x97,0xa6,0xad,0xa0,0x38,0x14,0x1d,0x2e,0x0e,0x0c,0x20,0x26 +,0x25,0x20,0x9f,0x89,0x9a,0x2e,0x28,0xdf,0xb6,0x9f,0x8e,0x8f,0xcd,0x19,0x12,0x1a,0x2c,0xa2,0x8b,0x9a,0x2b,0x28,0x17,0x0e,0x17,0xb2,0x8d,0x99,0x77,0x26,0x37,0x27 +,0x11,0x1d,0x3b,0x3b,0x9b,0x87,0x8f,0x38,0x2c,0xa5,0x9a,0xa1,0xcc,0xdb,0xf9,0x16,0x0d,0x47,0xcc,0x20,0x21,0x1d,0x17,0x2b,0x99,0x9f,0x20,0x25,0xaa,0x99,0xa4,0xad +,0x92,0x8c,0x97,0xaa,0xb9,0x27,0x12,0x25,0xcc,0x19,0x0a,0x15,0x3d,0x39,0x1d,0xbe,0x8e,0x99,0xcc,0x2b,0x2f,0x55,0xac,0x8e,0x89,0x99,0x21,0x0e,0x0d,0x0d,0x4b,0x88 +,0x89,0xaa,0x23,0x1a,0x16,0x1f,0xb4,0x98,0xc6,0x1e,0x23,0xb4,0x38,0x0d,0x1e,0xbb,0x6b,0xb0,0x91,0x95,0xbf,0xb9,0x98,0x9c,0x67,0x36,0xbe,0xae,0x27,0x19,0x4f,0x4a +,0x1d,0x1d,0x1f,0x18,0x24,0xa0,0x98,0x37,0x17,0x34,0xac,0xb5,0xa0,0x89,0x87,0x98,0x46,0x27,0x30,0x2f,0x45,0x6c,0x19,0x0a,0x16,0xbd,0xcd,0x20,0x51,0x91,0x8f,0xa2 +,0x34,0x1b,0x1a,0x31,0x99,0x8e,0xa1,0x22,0x1a,0x13,0x0a,0x26,0x8c,0x89,0x9e,0x57,0x25,0x16,0x1b,0xae,0x95,0xb1,0x2d,0xde,0xab,0x50,0x28,0x4a,0xfb,0x1d,0x1e,0xa5 +,0x93,0x9b,0xb5,0xe9,0x30,0x29,0xc5,0x9f,0xba,0x1d,0x1d,0xdd,0xb9,0x28,0x17,0x12,0x14,0x45,0x8d,0x8b,0xbf,0x1a,0x27,0xbf,0xa9,0x91,0x87,0x8b,0xa2,0x35,0x22,0x1c +,0x1d,0x37,0x3a,0x12,0x07,0x0c,0x21,0x2d,0x3a,0xa1,0x8f,0x95,0xa2,0xb2,0x44,0x2e,0xbd,0x96,0x91,0x97,0xa2,0xb3,0x1a,0x0a,0x19,0x9a,0x8e,0x9e,0x3c,0x18,0x10,0x19 +,0xd9,0xc9,0x1e,0x15,0x2c,0xb2,0xb6,0xd9,0x59,0x2e,0x26,0xcc,0x95,0x8e,0x90,0x9b,0xab,0x4e,0x3e,0xad,0x9d,0xa8,0x77,0x3e,0x33,0x1a,0x0f,0x0e,0x0d,0x0f,0x22,0xac +,0xa0,0x49,0x23,0x2e,0x3a,0xbe,0x93,0x87,0x87,0x90,0xa9,0xd1,0xf6,0xa8,0x9d,0x6f,0x0f,0x07,0x0d,0x1f,0x2a,0x2c,0xcd,0xa4,0x9d,0xa3,0xbb,0x23,0x17,0x26,0xba,0x9f +,0x9d,0x9c,0xa5,0x34,0x1f,0x32,0xa6,0x99,0x9c,0xaf,0x34,0x21,0x28,0x48,0x4b,0x2c,0x2e,0xda,0xde,0x37,0x28,0x2f,0x23,0x18,0x27,0xb3,0x98,0x8f,0x93,0xa4,0x31,0x20 +,0x3b,0xaf,0xb0,0xb3,0xa8,0xa8,0xc0,0x27,0x18,0x0e,0x0d,0x1f,0xaa,0x9c,0xaf,0x36,0x2d,0x3c,0xaf,0x93,0x8c,0x93,0xad,0x47,0x35,0x37,0xce,0xad,0xcb,0x1e,0x10,0x15 +,0x1b,0x1e,0x2b,0xc9,0xa5,0x9f,0x9b,0x9b,0xb5,0x46,0x38,0x66,0xc7,0xb0,0xa7,0xb2,0x29,0x16,0x25,0xb4,0x99,0x99,0xa8,0x2c,0x17,0x1b,0x2c,0x35,0x2a,0x34,0xdd,0xad +,0xac,0xad,0xba,0x30,0x1b,0x1a,0x2a,0xc5,0x98,0x8d,0x8f,0xa2,0x45,0x35,0x3a,0x42,0xcd,0xab,0xa9,0x48,0x24,0x1a,0x18,0x18,0x24,0x52,0x4f,0x3a,0x3a,0x3f,0x36,0xbc +,0x99,0x8c,0x8e,0x95,0x9d,0xca,0x4c,0x5d,0xcd,0x3b,0x1b,0x17,0x1c,0x1e,0x1e,0x29,0x41,0xd5,0xbf,0xae,0xb6,0x39,0x32,0x5a,0xb6,0xaa,0xa9,0xa4,0xb0,0x47,0x2d,0x3a +,0xb8,0xb2,0xa5,0xa3,0xbb,0x5d,0x45,0x36,0x20,0x18,0x1a,0x21,0x33,0xb7,0x9f,0x9e,0xb6,0x23,0x1c,0x24,0x4a,0xa0,0x95,0x98,0xb2,0xcc,0xb5,0xac,0xa8,0xab,0xa7,0xb2 +,0x35,0x20,0x1c,0x15,0x15,0x1e,0x29,0x36,0x49,0xb9,0x63,0x33,0x43,0xaa,0x99,0x98,0x93,0x98,0x9f,0xb0,0xbc,0xec,0x28,0x1c,0x18,0x15,0x12,0x19,0x29,0xe5,0xb6,0xab +,0x9e,0xa9,0xbf,0xee,0x58,0x42,0xf4,0xac,0x9f,0x9f,0xb0,0x4b,0x3d,0x3e,0x3c,0x4a,0xdf,0x42,0xf1,0xaf,0xbc,0x36,0x22,0x26,0x2b,0x6f,0xba,0xae,0xb7,0x45,0x2c,0x33 +,0x38,0x32,0xbb,0xa1,0x9f,0xa6,0xac,0xf0,0x68,0xb9,0xa3,0x9b,0xa5,0xc6,0x32,0x21,0x14,0x10,0x13,0x14,0x1b,0x4f,0xaa,0xb2,0x6c,0x56,0xa9,0x99,0x94,0x99,0xa6,0xd4 +,0xb7,0xa8,0xa8,0xcc,0x26,0x1c,0x1b,0x1c,0x1e,0x28,0x32,0x39,0xb9,0x9c,0x9d,0xb0,0xc2,0x50,0x29,0x2e,0x4d,0xc4,0xb8,0xb8,0xae,0xa6,0xae,0xde,0xbd,0xd9,0x37,0x5d +,0xce,0x38,0x2b,0x3b,0x34,0x28,0x29,0xbb,0xa5,0xaa,0xc5,0x29,0x1b,0x17,0x2a,0xad,0x9d,0x9e,0xa1,0xaa,0xbe,0xc9,0xbb,0xae,0xae,0xb1,0xb2,0xba,0x35,0x1c,0x1a,0x17 +,0x12,0x13,0x1a,0x35,0xc0,0xc0,0xad,0x9d,0x98,0x90,0x8e,0x96,0xaf,0xce,0xc0,0xd0,0x6b,0x47,0x31,0x1e,0x17,0x1f,0x2c,0x25,0x1a,0x1e,0x36,0xb5,0x9f,0x9c,0xa7,0xdd +,0xb7,0xae,0xcb,0xd5,0xbe,0x5f,0x46,0xc8,0xb3,0xad,0xbf,0xcf,0xbb,0xc2,0x34,0x22,0x19,0x1a,0x2b,0xc0,0xa1,0xa8,0xb0,0xbc,0x45,0x1f,0x1a,0x1b,0x20,0x41,0xb6,0x9d +,0x97,0x9b,0x9c,0x9c,0x9f,0xaa,0xc0,0xd9,0x6e,0x31,0x26,0x20,0x14,0x16,0x27,0x30,0x2a,0x22,0x24,0x33,0xb6,0x9d,0x8f,0x8d,0x98,0x9f,0xa1,0xb1,0x4b,0x3a,0x2f,0x24 +,0x1e,0x28,0x38,0x45,0x5f,0x4f,0x2e,0x20,0x28,0x49,0xcf,0x3d,0x4c,0xb9,0xad,0xa9,0xa1,0x9f,0xbc,0x39,0x2f,0x3b,0x4d,0xce,0xb3,0xad,0xae,0xab,0xb8,0x31,0x1a,0x18 +,0x1e,0x2f,0xc1,0xae,0xaa,0xb8,0x46,0x3c,0x55,0x3d,0x2f,0x32,0x4e,0xbc,0xac,0xa0,0x9b,0x9d,0x9a,0x98,0xa3,0x50,0x20,0x19,0x18,0x16,0x1a,0x28,0x29,0x2c,0x74,0xc1 +,0xe2,0x44,0x42,0xc0,0xa7,0x9c,0x97,0x99,0x9c,0x9a,0x9e,0xc2,0x21,0x16,0x14,0x19,0x1e,0x29,0x37,0x32,0x53,0xb4,0xa5,0xac,0x3b,0x1d,0x23,0xdd,0xa3,0x9b,0xa4,0xaf +,0xb5,0xaa,0xad,0x52,0x2f,0x2d,0x31,0x40,0xd4,0xb6,0xb5,0xbb,0xb8,0xd5,0x3c,0x29,0x2a,0x2f,0x2f,0x2a,0x2c,0x38,0x4f,0xb9,0xa7,0xab,0xe1,0x5e,0x7b,0xb6,0xa3,0x9b +,0x99,0x9c,0x9e,0xab,0xc4,0x21,0x10,0x0b,0x0e,0x17,0x1c,0x25,0x31,0xd0,0xa1,0x98,0x9d,0xa7,0xb5,0xbb,0xac,0xa4,0x9e,0x9f,0xb3,0xd1,0x5e,0x47,0x2c,0x19,0x16,0x1b +,0x2c,0x51,0xc6,0xd1,0xbd,0xad,0xa9,0xbd,0x38,0x2b,0x34,0x47,0xca,0xa5,0xa0,0xa7,0xaa,0xa5,0xa0,0xb8,0x28,0x1a,0x1d,0x26,0x34,0x38,0x30,0xcc,0x9d,0x97,0xa8,0x2d +,0x15,0x16,0x25,0x53,0xc7,0x54,0x3a,0xd6,0xa3,0x96,0x99,0xc2,0x34,0x41,0xb0,0x9d,0x9d,0xae,0x4e,0x28,0x23,0x1f,0x14,0x0f,0x12,0x1e,0x38,0xb6,0xab,0xa0,0x98,0x92 +,0x90,0x9d,0xbf,0x40,0x3e,0x4d,0xc4,0xcc,0x70,0x78,0x4f,0x6b,0x67,0x2a,0x18,0x16,0x1b,0x2d,0x4e,0x5b,0x73,0xad,0x96,0x91,0x9e,0x48,0x25,0x2d,0x7a,0xb9,0x59,0x42 +,0xcb,0xb5,0xa6,0xaa,0x53,0x24,0x20,0x20,0x3e,0xb3,0xae,0xb0,0x79,0x78,0xdc,0x2b,0x16,0x10,0x18,0x37,0xb5,0xa9,0x9f,0x98,0x92,0x8d,0x8e,0x9f,0xcb,0x35,0x28,0x26 +,0x22,0x1b,0x1f,0x28,0x2f,0x46,0x2d,0x1e,0x1c,0x2a,0xc9,0xaf,0xbc,0xae,0x9f,0x93,0x8a,0x8e,0xad,0x25,0x1e,0x2d,0xc1,0x4f,0x22,0x1e,0x23,0x29,0x36,0xc9,0xbe,0x3e +,0x1b,0x12,0x1f,0xa2,0x94,0x9c,0xa5,0xa3,0xa1,0x7a,0x1d,0x27,0xa2,0x90,0xaa,0x0f,0x06,0x1b,0x8d,0x88,0x9c,0x2b,0x27,0x3c,0x23,0x22,0x6a,0xa3,0xbd,0x18,0x08,0x0f +,0x9c,0x8a,0x98,0xba,0xbf,0xae,0xc6,0x28,0x44,0x8f,0x83,0x97,0x0e,0x02,0x10,0x94,0x90,0x38,0x12,0x16,0x22,0x14,0x19,0xae,0x8c,0x8c,0x4c,0x0b,0x13,0x93,0x84,0x8d +,0xa0,0xc4,0x42,0x1b,0x0b,0x14,0x9d,0x86,0x9f,0x08,0x00,0x0d,0x8f,0x83,0x8f,0x2e,0x15,0x23,0x1d,0x1c,0xa4,0x86,0x84,0xb6,0x05,0x06,0xd7,0x89,0x8f,0x9e,0xad,0x56 +,0x13,0x07,0x18,0x95,0x82,0x90,0x0e,0x00,0x0a,0x9e,0x89,0x9c,0x29,0x1b,0x2c,0x1d,0x1a,0xa3,0x84,0x82,0xa1,0x0b,0x05,0xdc,0x8b,0x8c,0xa4,0x3b,0x1c,0x09,0x01,0x16 +,0x8c,0x80,0x98,0x08,0x00,0x12,0x8c,0x85,0x8f,0xa0,0xb9,0x2f,0x0e,0x11,0xa1,0x83,0x86,0x4f,0x05,0x05,0x2b,0x90,0x9e,0xb2,0x54,0x2d,0x10,0x04,0x1a,0x8d,0x80,0x93 +,0x0c,0x01,0x32,0x87,0x8a,0xa0,0xcc,0x4e,0x2d,0x0b,0x09,0xc6,0x84,0x85,0x28,0x03,0x08,0xb1,0x8d,0x90,0x98,0xba,0x18,0x08,0x03,0x1c,0x89,0x80,0x9f,0x09,0x04,0x40 +,0x85,0x86,0x93,0xaf,0x66,0x1f,0x0c,0x0a,0x53,0x84,0x8e,0x0e,0x00,0x0c,0x9c,0x8b,0x96,0xa7,0x5f,0x1f,0x0b,0x15,0x95,0x81,0x84,0x36,0x01,0x0d,0xa0,0x8a,0x92,0xaf +,0x3b,0x1c,0x0b,0x05,0x1c,0x8e,0x84,0xb2,0x08,0x04,0xec,0x8c,0x90,0x96,0x96,0xb7,0x18,0x08,0x0e,0x93,0x80,0x8d,0x0e,0x00,0x0e,0x8e,0x88,0x9f,0xd7,0x4d,0x24,0x0d +,0x08,0x24,0x86,0x82,0x35,0x00,0x08,0xaf,0x8a,0x92,0x9f,0xa7,0xd3,0x12,0x0a,0x3b,0x88,0x80,0x9d,0x07,0x01,0x25,0x90,0x8e,0xa1,0x20,0x14,0x10,0x09,0x12,0xa2,0x83 +,0x87,0x35,0x05,0x0e,0x92,0x86,0x8c,0x9f,0xed,0x27,0x0b,0x05,0x23,0x88,0x83,0x40,0x04,0x03,0x45,0x89,0x8e,0x9c,0x4f,0x2c,0x0e,0x0a,0x1f,0x92,0x82,0x94,0x14,0x07 +,0x1b,0x96,0x87,0x8e,0xa8,0x3c,0x14,0x06,0x0e,0xac,0x85,0x8a,0x1d,0x03,0x07,0xbc,0x89,0x8c,0xa7,0x2b,0x26,0x12,0x0a,0x2d,0x8b,0x83,0x99,0x10,0x08,0x3f,0x91,0x8c +,0x95,0xad,0x39,0x0c,0x04,0x0e,0x9c,0x87,0x96,0x1a,0x09,0x12,0xa2,0x8b,0x8d,0x9b,0xc1,0x29,0x0e,0x0f,0x39,0x8b,0x88,0xbc,0x0d,0x0a,0x3d,0x94,0x90,0xa5,0xc8,0x2e +,0x0e,0x05,0x12,0x92,0x83,0x9c,0x14,0x0d,0x39,0x9e,0x95,0x92,0x9e,0xae,0x18,0x08,0x0e,0xb4,0x8b,0x93,0x34,0x11,0x1d,0xbc,0x9e,0x8f,0x9b,0xec,0x28,0x12,0x0d,0x18 +,0x9b,0x92,0xb4,0x1f,0x12,0x44,0x96,0x8f,0x96,0xa5,0xb6,0x28,0x10,0x13,0xb8,0x91,0xc3,0x19,0x1a,0x2f,0xc7,0xae,0x9d,0x9f,0xab,0x27,0x0e,0x17,0xc6,0x94,0x9a,0xd8 +,0x4a,0x4d,0x48,0xb8,0x9e,0xa2,0xcf,0x2a,0x19,0x16,0x21,0xb7,0xab,0x74,0x38,0xf6,0xb0,0xab,0xa2,0xd6,0x6d,0xaf,0x59,0x21,0x1f,0xbf,0x9f,0xdf,0x38,0x39,0xa6,0x9e +,0xb4,0xba,0x3e,0x38,0x20,0x1f,0x2a,0x64,0xc3,0x20,0x25,0xb9,0xa8,0x9d,0xa9,0xb7,0x35,0x3d,0xbd,0xd9,0xb9,0x49,0xbd,0x6f,0x2e,0x66,0xb4,0x97,0x9d,0x36,0x15,0x13 +,0x34,0x75,0x5c,0x7a,0xd0,0x3b,0x16,0x25,0x9f,0x8a,0x8b,0xbd,0x26,0x26,0x3e,0xc1,0x4c,0xad,0xaa,0x2b,0x10,0x0e,0x5d,0x92,0x8b,0xa1,0x1f,0x0f,0x12,0xf4,0x9e,0x9d +,0xba,0x36,0x1c,0x11,0x33,0x92,0x87,0x8e,0x42,0x0f,0x0e,0x2a,0x9d,0x96,0xa2,0xcf,0x1f,0x09,0x0e,0x99,0x83,0x8a,0x5c,0x0c,0x08,0x19,0xbd,0x9d,0x9d,0xa7,0x2d,0x0d +,0x0e,0xaf,0x86,0x83,0x90,0x25,0x0b,0x0d,0x21,0xa9,0x95,0x98,0x47,0x0a,0x02,0x19,0x8a,0x81,0x8d,0x25,0x0a,0x0f,0x31,0x9e,0x94,0x95,0x9e,0x1e,0x06,0x0c,0x9f,0x84 +,0x87,0xa7,0x0e,0x09,0x0c,0x2a,0x97,0x8c,0x90,0x24,0x03,0x08,0xb0,0x84,0x82,0x93,0x14,0x07,0x10,0x3a,0x9f,0x96,0x94,0xae,0x15,0x07,0x18,0x91,0x84,0x8c,0x56,0x0b +,0x09,0x0d,0x34,0x91,0x88,0x9b,0x0c,0x02,0x12,0x8f,0x80,0x88,0xb6,0x0e,0x0c,0x1d,0xc2,0x99,0x90,0x9a,0x2e,0x09,0x07,0x25,0x8a,0x84,0x93,0x1d,0x07,0x0b,0x13,0xaa +,0x8b,0x8d,0xc4,0x0a,0x04,0x2c,0x85,0x80,0x8e,0x19,0x08,0x16,0x25,0x41,0x9f,0x99,0xaa,0x13,0x07,0x0f,0x9f,0x83,0x8b,0x9e,0x13,0x08,0x0d,0x3c,0x8c,0x88,0x96,0x16 +,0x03,0x07,0xab,0x82,0x84,0x9d,0x14,0x0c,0x16,0x2d,0x9d,0x93,0x96,0xc8,0x09,0x05,0x1e,0x8d,0x84,0x8f,0x2e,0x09,0x0c,0x13,0xcd,0x8a,0x84,0x9c,0x0a,0x01,0x1c,0x88 +,0x80,0x8d,0x49,0x09,0x07,0x14,0x3b,0x9b,0x91,0x98,0x1f,0x07,0x09,0x5f,0x85,0x84,0x91,0x1e,0x0a,0x0d,0x19,0x9e,0x89,0x88,0x42,0x05,0x03,0x22,0x85,0x82,0x97,0x15 +,0x08,0x13,0x22,0xc7,0x96,0x8b,0xa5,0x0d,0x05,0x15,0x8f,0x82,0x8b,0xab,0x0c,0x09,0x0e,0x50,0x8b,0x86,0x92,0x12,0x02,0x07,0xa7,0x81,0x88,0xb2,0x0a,0x0a,0x18,0x28 +,0xac,0x8f,0x8c,0x50,0x0a,0x0c,0x3a,0x87,0x85,0x97,0x1a,0x0b,0x13,0x1b,0x9f,0x8b,0x8c,0x52,0x07,0x03,0x1f,0x89,0x82,0x96,0x16,0x09,0x0f,0x1e,0xab,0x8e,0x8e,0xa3 +,0x1a,0x0e,0x17,0x9c,0x84,0x8a,0xb6,0x0c,0x08,0x0f,0x2a,0x9e,0x94,0x9c,0x24,0x09,0x11,0x98,0x84,0x8a,0xb5,0x10,0x0c,0x18,0x36,0x9e,0x97,0xa1,0x23,0x0e,0x15,0xad +,0x86,0x87,0x99,0x26,0x0d,0x0a,0x19,0xaa,0x92,0x93,0x5e,0x0e,0x0c,0x2c,0x91,0x89,0x8f,0x48,0x0c,0x10,0x2e,0xaf,0xa1,0xa5,0xb1,0x26,0x13,0x23,0x91,0x89,0x92,0x74 +,0x10,0x0b,0x15,0x4d,0xa2,0x97,0xae,0x1c,0x0b,0x1b,0x93,0x84,0x8a,0xa5,0x14,0x0b,0x16,0x45,0xa0,0xa2,0xa8,0x32,0x19,0x19,0xbd,0x8f,0x8f,0xa1,0x22,0x0d,0x15,0xd7 +,0xa2,0xac,0xba,0xdb,0x1d,0x12,0x4d,0x8b,0x8a,0xa2,0x20,0x0e,0x14,0xf8,0x9d,0x9d,0xbb,0x2b,0x1a,0x13,0x4c,0x8f,0x8d,0x97,0x69,0x11,0x0f,0x1e,0xd8,0xa1,0xa2,0xcf +,0x22,0x1b,0x58,0x93,0x91,0x9a,0xe7,0x1a,0x1a,0x20,0xc7,0x9d,0xa8,0x2c,0x16,0x18,0x48,0x9b,0x90,0x98,0xdb,0x17,0x15,0x25,0x5b,0xa0,0x98,0xaf,0x1b,0x1a,0x4a,0xa1 +,0x97,0x97,0xb4,0x1c,0x16,0x1f,0x31,0xc8,0xa4,0xbf,0x24,0x22,0x3e,0xa0,0x94,0x95,0xad,0x15,0x13,0x37,0xd3,0xb9,0xc2,0x58,0x2d,0x25,0xc3,0x9d,0x98,0x93,0xa9,0x18 +,0x13,0x25,0x4d,0xba,0x5d,0x2e,0x3f,0x48,0xc7,0xac,0xa6,0x9f,0xaf,0x32,0x1b,0x24,0xf9,0xb9,0x4f,0x26,0x3a,0xb3,0xa6,0xad,0xb2,0xa9,0xa9,0x40,0x26,0x25,0x24,0x3a +,0x4c,0x50,0xb7,0xaf,0xcc,0x4d,0x45,0xcf,0xa4,0x9c,0xbb,0x25,0x15,0x1d,0x70,0xa3,0x9e,0xbc,0x45,0x2f,0x2f,0xc8,0xa5,0xa6,0xac,0x2f,0x15,0x1b,0xe3,0x9a,0x99,0xbb +,0x1d,0x1a,0x2d,0xa8,0x95,0x9f,0x4d,0x1d,0x13,0x1b,0xc3,0x94,0x8d,0xa7,0x12,0x0e,0x2b,0x98,0x8e,0xa9,0x2d,0x16,0x19,0x3a,0x9e,0x93,0x9a,0x54,0x0f,0x10,0x39,0x93 +,0x92,0xb6,0x1f,0x15,0x25,0xb9,0x96,0x8e,0x9f,0x19,0x0a,0x15,0xa8,0x92,0x9c,0x3a,0x1f,0x1e,0x31,0xb1,0x92,0x90,0x31,0x0f,0x18,0xa5,0x99,0xbe,0x22,0x1f,0x2f,0xc9 +,0xa6,0x9c,0x9b,0x39,0x13,0x17,0xae,0x91,0xaa,0x1d,0x1b,0x30,0xa9,0x9f,0xa6,0x9f,0x42,0x0c,0x0f,0xb4,0x8c,0x96,0x23,0x15,0x1c,0x51,0x9d,0x8d,0x8b,0x5a,0x06,0x04 +,0x28,0x8b,0x8a,0xad,0x14,0x0f,0x20,0xa1,0x8d,0x87,0x98,0x0b,0x00,0x0f,0x91,0x87,0x9d,0x18,0x10,0x1d,0xd1,0x8f,0x88,0x89,0x26,0x02,0x06,0xe8,0x8a,0x8f,0xc3,0x16 +,0x11,0x1a,0xa3,0x88,0x84,0xb4,0x06,0x04,0x1e,0x92,0x8d,0xab,0x1b,0x12,0x18,0xa2,0x89,0x85,0x9f,0x09,0x04,0x1a,0x95,0x91,0xaa,0x1c,0x12,0x24,0xb2,0x8f,0x88,0x9c +,0x0f,0x06,0x18,0x9d,0x9a,0xbc,0x23,0x1a,0x21,0x62,0x91,0x87,0x89,0x1e,0x03,0x0b,0xb1,0x89,0x8f,0x2c,0x09,0x0f,0x30,0x96,0x87,0x87,0x2a,0x03,0x06,0x6c,0x86,0x8c +,0x67,0x0b,0x0b,0x20,0x99,0x89,0x84,0x9f,0x06,0x02,0x1d,0x8e,0x8b,0xae,0x19,0x16,0x18,0x3c,0x8f,0x83,0x8a,0x14,0x02,0x09,0xbd,0x8e,0x9d,0x31,0x1d,0x20,0x1e,0x9c +,0x84,0x82,0x2d,0x01,0x06,0xdb,0x8a,0x98,0x1f,0x0f,0x1b,0x1f,0xa4,0x89,0x85,0xba,0x07,0x0d,0xb8,0x92,0xa4,0x24,0x14,0x20,0x26,0x4d,0x8d,0x84,0xad,0x08,0x0d,0xd6 +,0x90,0x9b,0x40,0x1c,0x1a,0x18,0x1f,0x8f,0x81,0x97,0x08,0x02,0x29,0x8d,0x91,0xac,0x2f,0x1c,0x11,0x1e,0x8f,0x80,0x8a,0x0c,0x00,0x11,0x8f,0x89,0xae,0x25,0x12,0x15 +,0x19,0xa2,0x84,0x87,0x37,0x06,0x0c,0xc1,0x96,0xa9,0x3e,0x2d,0x1f,0x1a,0xcd,0x90,0x87,0x9b,0x11,0x0b,0x1e,0xa3,0x9f,0xac,0x4d,0x18,0x15,0x35,0x93,0x8b,0xa5,0x1b +,0x16,0x34,0xba,0xb8,0x63,0x34,0x2f,0x2d,0xdd,0x92,0x8d,0xb3,0x15,0x12,0xc2,0x9a,0xaa,0x20,0x19,0x27,0x40,0xb9,0xa2,0x96,0x96,0x30,0x0f,0x21,0xae,0xa0,0x42,0x22 +,0x26,0x3b,0x3d,0xb8,0x91,0x8d,0xac,0x0d,0x0d,0x41,0x99,0x97,0xb4,0x1a,0x0d,0x15,0xc0,0x93,0x8b,0x98,0x1d,0x12,0x31,0xa8,0xbd,0xb6,0xac,0x37,0x12,0x1c,0xa4,0x8f +,0x96,0x55,0x22,0x2d,0x3e,0x1e,0x2d,0xa1,0x9c,0x2a,0x0e,0x23,0x96,0x92,0x9c,0xaf,0x3e,0x1f,0x12,0x1d,0xa8,0x99,0xb9,0x23,0x22,0xc3,0xa4,0xa6,0xb8,0xa3,0xbb,0x2b +,0x1b,0x1d,0x48,0xf7,0xba,0xc6,0xc1,0x30,0x26,0xbc,0x93,0x8f,0xcb,0x13,0x13,0x3a,0x9d,0x9e,0xb9,0x63,0x24,0x1d,0x32,0x9f,0x98,0xa8,0x2d,0x16,0x18,0x2a,0xb2,0x98 +,0x9c,0xb8,0x27,0x1b,0x33,0xa5,0x94,0x9e,0x4e,0x15,0x0f,0x20,0xab,0x92,0x97,0xd9,0x18,0x1a,0x7d,0x97,0x99,0xd9,0x1b,0x18,0x1c,0x2d,0xb2,0x99,0x9b,0xc0,0x35,0x33 +,0xbf,0xb1,0xb9,0x3b,0x6a,0xba,0x2f,0x1c,0x25,0xb0,0x9d,0xa2,0xa7,0x45,0x27,0x28,0x37,0x69,0xb0,0xa4,0xc6,0x26,0x12,0x1d,0xce,0x8f,0x87,0x9f,0x0e,0x09,0x1e,0xa1 +,0x96,0x99,0xa8,0x22,0x0d,0x0d,0xaf,0x88,0x83,0xb9,0x04,0x04,0x1f,0x93,0x8f,0x94,0xa2,0x25,0x08,0x0d,0x98,0x82,0x86,0x3b,0x04,0x05,0x1b,0x9a,0x8c,0x92,0xd2,0x15 +,0x0c,0x1a,0x96,0x86,0x8c,0xd6,0x0a,0x06,0x19,0x96,0x8b,0x9e,0x22,0x19,0x2c,0x44,0xad,0x9a,0x94,0xa7,0x1b,0x09,0x11,0x9f,0x8e,0xa9,0x2b,0x52,0xdb,0x3a,0x24,0x3b +,0x9f,0x98,0xc2,0x14,0x11,0x40,0x97,0x9e,0xae,0xa8,0x9f,0x49,0x13,0x12,0x33,0x91,0x8c,0xbf,0x09,0x0a,0x2c,0x97,0x8c,0x97,0xbc,0x23,0x0f,0x0d,0x40,0x8d,0x84,0xa5 +,0x09,0x04,0x23,0x8f,0x8b,0x91,0xc1,0x1b,0x0d,0x0c,0x3b,0x8a,0x82,0x9f,0x0a,0x00,0x0d,0x9a,0x84,0x8a,0xd3,0x0d,0x0a,0x12,0xaf,0x89,0x85,0x95,0x12,0x04,0x0c,0x9a +,0x85,0x8f,0x30,0x0e,0x15,0x1b,0x54,0x9f,0x8d,0x8e,0x5d,0x0c,0x07,0x42,0x8b,0x8e,0x7a,0x14,0x0f,0x1e,0x4f,0x9f,0x97,0x90,0x9f,0x1b,0x0e,0x20,0x95,0x96,0xa6,0x26 +,0x1c,0x2c,0x22,0x22,0x37,0x92,0x8b,0xa8,0x0f,0x0a,0x2c,0x90,0x8f,0xa0,0x31,0x1f,0x1f,0x18,0xcc,0x90,0x88,0xa7,0x0f,0x05,0x14,0x9b,0x92,0x9b,0x3b,0x2d,0x27,0x1b +,0x28,0x9b,0x86,0x8d,0x1c,0x03,0x08,0xc9,0x89,0x8e,0xa9,0x1d,0x14,0x13,0x4e,0x91,0x89,0x8e,0x20,0x08,0x07,0x54,0x8e,0x90,0xbe,0x1b,0x1c,0x1e,0x39,0xad,0x95,0x8a +,0x95,0x15,0x05,0x12,0x94,0x88,0x9a,0x1d,0x0d,0x1f,0x44,0xae,0x9f,0x8f,0xa3,0x18,0x09,0x0f,0x99,0x8b,0x9e,0x1e,0x1a,0x4f,0x4c,0x48,0xb5,0x93,0x8f,0x54,0x0e,0x0a +,0x29,0x8e,0x8e,0xb1,0x1c,0x1d,0x26,0x3b,0xa5,0x9d,0x9d,0x28,0x1a,0x14,0x1c,0x99,0x91,0xa9,0x1f,0x1f,0xcd,0xaa,0xac,0xe4,0xae,0x98,0xb1,0x12,0x07,0x29,0x8b,0x8e +,0x31,0x0d,0x2a,0xb3,0xa0,0xa2,0xb2,0x9e,0x5b,0x13,0x0b,0x29,0x92,0x94,0x42,0x14,0x30,0xa7,0xc7,0x44,0xb3,0x97,0x9b,0x3e,0x12,0x0e,0xb7,0x8c,0x97,0x26,0x0d,0x16 +,0x3a,0x9b,0x96,0xab,0x7a,0x34,0x2c,0x1b,0x68,0x8e,0x8c,0x3e,0x0c,0x14,0x4c,0x9f,0xaf,0x73,0xb8,0xa7,0x46,0x0e,0x0f,0x96,0x86,0xa0,0x0f,0x0b,0x3e,0x9c,0x97,0xa9 +,0xf9,0x33,0x29,0x1e,0x23,0xa1,0x90,0xa8,0x16,0x0f,0x30,0x9e,0x94,0xa2,0xc6,0x35,0x3f,0x34,0x17,0x27,0x9d,0x96,0xb5,0x13,0x0d,0xd8,0x8f,0x8f,0xaa,0x38,0x37,0xc6 +,0x2e,0x1c,0xc5,0x98,0xae,0x10,0x0e,0x46,0x9c,0x9d,0xb7,0x5e,0xb6,0xad,0x47,0x14,0x28,0x94,0x95,0x2a,0x0c,0x19,0xb7,0x96,0x97,0xad,0x45,0xe9,0x43,0x1c,0x24,0x9d +,0x93,0x49,0x0f,0x13,0x2d,0xb8,0x9b,0x9e,0xb7,0xc5,0x38,0x1e,0x1e,0xab,0x8d,0x94,0x22,0x0a,0x17,0xa8,0x8f,0x94,0xdf,0x18,0x1c,0x2e,0x24,0x47,0x8f,0x8e,0x3e,0x0a +,0x0e,0xaa,0x8d,0x90,0xbd,0x1c,0x17,0x21,0x1f,0x33,0x97,0x8b,0xb2,0x0a,0x09,0xd1,0x8c,0x87,0x97,0x26,0x10,0x18,0x2f,0x4b,0xa4,0x99,0xb9,0x12,0x0c,0x39,0x91,0x8c +,0x94,0x59,0x12,0x15,0xb5,0xaa,0xb4,0xa0,0xa9,0x1f,0x08,0x12,0xa2,0x8d,0x8d,0xb7,0x0d,0x0f,0x54,0x9d,0x9f,0x9d,0xa0,0x2f,0x11,0x12,0x5e,0x9a,0x94,0xa6,0x22,0x17 +,0x23,0xac,0xae,0xb7,0xa1,0xb6,0x1f,0x0f,0x25,0x9c,0x8f,0x9d,0x2b,0x10,0x1c,0xb9,0x9b,0xa7,0xc7,0xb0,0x2e,0x15,0x1e,0xa4,0x95,0x9b,0xaf,0x27,0x17,0x21,0xca,0xb2 +,0xa4,0xa5,0x4a,0x15,0x0e,0x45,0x96,0x8f,0x9c,0x40,0x12,0x1b,0xa6,0x9e,0xbc,0x4e,0x46,0x29,0x19,0x2b,0xa6,0x98,0x97,0xb9,0x29,0x1e,0x3a,0xb8,0xf2,0xb6,0xbb,0x20 +,0x0e,0x14,0xad,0x8e,0x8e,0xa4,0x25,0x19,0x34,0x9b,0xa0,0xdc,0x5c,0x33,0x22,0x19,0x2e,0xb5,0x9d,0x97,0xc6,0x24,0x2e,0x53,0x4e,0xbd,0x9b,0x9a,0x2b,0x0b,0x10,0xae +,0x91,0x96,0x4c,0x17,0x1b,0x52,0xa3,0xad,0xb2,0xb1,0x31,0x26,0x26,0x59,0x9c,0x95,0xa4,0x2a,0x12,0x16,0xdd,0xae,0xa0,0x9a,0xad,0x1c,0x0e,0x1f,0x9a,0x88,0x8f,0x1d +,0x0a,0x1f,0xa5,0x9b,0x44,0x2e,0x7b,0x3a,0x23,0x33,0xb4,0x9d,0xa0,0x4e,0x28,0x33,0xf6,0xce,0xb9,0xa7,0xad,0x30,0x1f,0x1a,0x3a,0x9f,0x98,0xa6,0x1b,0x12,0x57,0x9b +,0xa9,0x30,0x3a,0xa0,0xab,0x24,0x12,0x22,0xa5,0x9a,0xa6,0x49,0x3e,0x4d,0x33,0x3b,0x9b,0x8d,0xac,0x13,0x0c,0x1f,0xa6,0x95,0x9f,0x28,0x18,0x1f,0xba,0x9b,0xa5,0xa9 +,0xad,0x39,0x17,0x13,0x27,0x9a,0x8e,0xab,0x14,0x13,0x3c,0xac,0x9e,0x98,0x97,0x3a,0x0c,0x0e,0xb0,0x8f,0x8f,0x40,0x0f,0x1a,0x3d,0xc0,0xae,0xac,0xaa,0xce,0x2a,0x2b +,0x38,0xa8,0x9f,0xa2,0xba,0x35,0x22,0x26,0x3c,0xab,0xa1,0xee,0x28,0x16,0x1a,0xaa,0x91,0x9c,0x3c,0x1e,0xc3,0xa9,0xc7,0x41,0x63,0xac,0xbc,0x1f,0x11,0x23,0x9c,0x91 +,0xae,0x2c,0x2b,0x29,0x28,0xec,0x9b,0x93,0xb2,0x15,0x0c,0x21,0x9a,0x91,0xa5,0x28,0x1f,0x44,0xc1,0xb7,0xab,0xa3,0xb3,0x39,0x1c,0x1d,0xb1,0x98,0x9f,0x3a,0x12,0x1a +,0x46,0xca,0xa0,0x9a,0xb0,0x2a,0x19,0x1b,0xaa,0x8d,0x99,0x26,0x15,0x2d,0xcd,0xcb,0xb4,0xa9,0xa5,0xd6,0x23,0x1b,0x2e,0x9e,0x99,0xf3,0x1f,0x22,0x28,0x38,0xc6,0xa6 +,0x9d,0xc2,0x21,0x1a,0x38,0x98,0x8e,0xaa,0x1c,0x1c,0x46,0x6c,0x4c,0xb2,0x9f,0xa4,0x2b,0x10,0x1a,0xa4,0x90,0x9c,0x35,0x1a,0x29,0x38,0x3d,0xa9,0x99,0xa2,0x24,0x0e +,0x18,0xa4,0x8d,0x99,0x28,0x18,0x24,0x2f,0xd0,0xa6,0x9d,0x9a,0xfe,0x17,0x13,0x2d,0x91,0x8c,0x3c,0x11,0x14,0x26,0xc3,0xa6,0x9a,0x9e,0xcc,0x1a,0x12,0xd9,0x8c,0x8c +,0xb4,0x12,0x13,0x4a,0x4f,0x2c,0x45,0xa8,0x98,0x4b,0x0b,0x14,0x98,0x86,0x93,0x27,0x16,0x29,0x43,0x40,0xb6,0xa4,0xb5,0x30,0x16,0x12,0xc0,0x8f,0x9a,0x3b,0x2d,0xf7 +,0xbc,0xd1,0x2f,0xaf,0xa6,0x32,0x1a,0x1a,0x2e,0xa2,0x93,0xb1,0x4a,0xc9,0xb9,0x28,0x21,0xb7,0x9c,0xaa,0x18,0x1d,0xb0,0x9d,0xa5,0x38,0x28,0x32,0x71,0x44,0x2e,0x2b +,0xce,0x96,0xa3,0x26,0x2c,0xa8,0xa7,0x3c,0x2e,0x51,0xf3,0x42,0x2f,0x34,0xaa,0x99,0x9d,0xce,0x13,0x18,0xbd,0xb9,0x2d,0x5c,0x9e,0xd6,0x4a,0x41,0x48,0xc7,0x43,0xc5 +,0xb8,0xf0,0x20,0x36,0xc9,0x9c,0x97,0xbd,0x2a,0x13,0x36,0xa3,0xaf,0x28,0x2a,0xbf,0xae,0xac,0xcc,0x38,0x3a,0xe4,0xc3,0xbe,0x2d,0x2a,0xb6,0x9c,0xae,0x3b,0xb5,0xc4 +,0x18,0x1e,0xb5,0xa1,0xbd,0x24,0x20,0x44,0x9b,0x99,0xa3,0x25,0x10,0x25,0xb1,0xcc,0x2d,0xa4,0x9d,0xb4,0xe0,0x49,0x25,0x23,0xa1,0xa6,0x2c,0x1d,0x2d,0xa7,0x9f,0xbd +,0x4e,0xd3,0x2c,0x1d,0xcb,0xaf,0x2f,0x69,0xaa,0xa8,0xa7,0xc6,0x3f,0x25,0x24,0xd6,0xb3,0xc5,0x2c,0x1f,0xc3,0x9b,0x9c,0xa4,0xb2,0x18,0x0d,0x3b,0x9a,0x9b,0xcf,0x35 +,0x1b,0x32,0xa3,0x98,0xa9,0x1d,0x21,0x2f,0x5a,0x25,0xea,0x8f,0x94,0x37,0x21,0x2b,0x24,0x45,0xab,0xde,0x1b,0x4e,0xa7,0xa2,0xa7,0xad,0xb9,0x45,0x1d,0x1a,0xc6,0xbf +,0x34,0xfe,0xae,0x5d,0xb6,0xa1,0xd4,0x13,0x19,0xa9,0x9c,0xb7,0x1f,0x22,0xb0,0x8e,0x9a,0xc6,0x24,0x0e,0x1f,0xb3,0xad,0xbb,0xb9,0xb7,0x3a,0x49,0xa6,0x9e,0xc5,0x1d +,0x1e,0x27,0x3b,0x4f,0xd4,0xa1,0x9c,0xc5,0x4d,0xe4,0x2b,0x3e,0xa3,0x52,0x19,0x28,0x46,0xa3,0xa6,0xb9,0xae,0xb3,0x4c,0x1f,0x29,0x2d,0x1d,0x43,0x95,0x9e,0x3a,0xf0 +,0xad,0xb7,0xfd,0xca,0x33,0x12,0x13,0x47,0x93,0x98,0xb6,0xb3,0x4b,0x21,0x2f,0xa2,0xa8,0x20,0x19,0xed,0xaa,0xaf,0xae,0xab,0x34,0x36,0xad,0x4b,0x1c,0x26,0xcd,0xac +,0xa2,0x43,0xd8,0xad,0x3c,0x3f,0xae,0x2f,0x17,0xd4,0x9a,0xd3,0x28,0xe8,0xaf,0x9d,0xb4,0x22,0x16,0x27,0x79,0xba,0x98,0xb6,0x2c,0x53,0xcf,0xaa,0x9e,0xb6,0x1f,0x0d +,0x19,0xae,0x8f,0x9a,0x43,0x25,0x23,0xe5,0xaf,0xaf,0x2b,0x1c,0x2f,0x9c,0x99,0xb0,0xaf,0xc9,0x24,0x20,0xcc,0x44,0x20,0x5a,0xa2,0xd1,0xd2,0x3b,0xd6,0x99,0xac,0x3a +,0x1a,0x13,0x24,0x9f,0x93,0xc3,0x38,0xaa,0xb6,0xb7,0xc4,0x21,0x1b,0x1e,0x46,0xa6,0x9a,0xae,0x32,0x66,0xba,0xae,0xa8,0x58,0x0f,0x0e,0x34,0x99,0x90,0xab,0x34,0x22 +,0x39,0xae,0xb0,0xd4,0x1d,0x1d,0xbf,0xab,0xaa,0x9e,0xa4,0xae,0x1f,0x16,0x1f,0x27,0xcc,0xa0,0xa2,0x34,0xd5,0xaf,0xce,0xbc,0xb9,0x7a,0x26,0x14,0x1d,0x9b,0x95,0xce +,0x3b,0xac,0xae,0xd5,0xcf,0x24,0x15,0x34,0xc4,0xaf,0xa2,0xa2,0xba,0x27,0x37,0xbd,0xae,0x2c,0x10,0x1f,0x9d,0x9b,0xa1,0xb8,0x25,0x2b,0x4c,0xad,0x4c,0x2a,0x1e,0x2c +,0xa1,0xa7,0xab,0xa4,0xaf,0x3d,0x2e,0x26,0x37,0x3c,0x39,0xa9,0xda,0x4e,0xa8,0xa6,0x44,0x21,0x4b,0x31,0x1b,0x48,0x9f,0x9a,0xaf,0x33,0x3a,0xf8,0xb6,0xae,0xc1,0x1d +,0x0e,0x3c,0x97,0xa3,0xa4,0xb2,0x32,0x4f,0xc0,0xb3,0x38,0x1c,0x18,0x3e,0x9d,0xa0,0xa1,0xb7,0x22,0x1d,0xbc,0xb9,0x2a,0x2c,0x56,0xab,0xc9,0xd2,0xa6,0x9b,0xcd,0x1e +,0x2a,0x2d,0x5a,0xae,0xbb,0x41,0x2f,0xd8,0xaa,0xbe,0xdb,0x38,0x28,0x1a,0x19,0xad,0x8f,0x98,0xb5,0x28,0x1f,0x43,0xb4,0xa3,0x39,0x19,0x1b,0xb4,0x99,0xac,0x9f,0xbc +,0x1e,0x19,0xaf,0x9d,0xcd,0x2c,0x27,0xf6,0x50,0xa1,0x9e,0xb7,0x22,0x1c,0xb8,0x3f,0x2e,0xc8,0xb9,0xbf,0xac,0x9f,0xc8,0x32,0x33,0x32,0x37,0x30,0x3a,0xac,0xa4,0x52 +,0x46,0xd7,0x3c,0x32,0xc4,0xaa,0x35,0x19,0x1a,0xa7,0x91,0xa0,0xa8,0x2f,0x19,0x1f,0x9e,0x9f,0x1f,0x1f,0x43,0xa3,0xb4,0xa0,0xb3,0x28,0x17,0x29,0x9c,0xc1,0x53,0x4b +,0x6b,0x37,0xbe,0x99,0xd1,0x20,0x1b,0x54,0xa8,0x47,0x2f,0xb8,0xa7,0xd1,0xb3,0xac,0xfa,0x22,0x45,0xa7,0x2c,0x38,0xb5,0x9e,0xc9,0x27,0xcc,0x4e,0x2f,0x2f,0xa9,0x45 +,0x1a,0x49,0x9d,0x9c,0xea,0xb6,0x3f,0x1f,0x1e,0xbf,0x97,0xd9,0x26,0x24,0xcc,0xc9,0xaf,0x9a,0xc8,0x1a,0x13,0xc6,0x9d,0xb6,0xec,0xbc,0x3d,0x1f,0xb5,0x9a,0xc8,0x14 +,0x2c,0xb0,0xdc,0xca,0xae,0xa5,0x25,0x21,0xaa,0xb1,0x3b,0x40,0xaa,0x33,0x1d,0xab,0x9a,0xa1,0x3d,0x3e,0x39,0x28,0x21,0xbd,0x98,0xdc,0x37,0x29,0xc5,0xce,0xa9,0x9e +,0x2f,0x14,0x13,0xa8,0x92,0xa5,0x2c,0x34,0x39,0x39,0x9f,0x9e,0x32,0x11,0x33,0xa6,0xbc,0xbb,0xa5,0xa1,0x1d,0x1e,0xba,0xbf,0x3e,0x37,0xab,0x3f,0x29,0x4e,0xaa,0xaf +,0x38,0xbc,0xe6,0x28,0x1a,0xb9,0x9a,0xb8,0x4c,0xdf,0xb7,0x28,0x4f,0xae,0xdd,0x23,0x23,0xb1,0xbe,0x45,0xc3,0xa3,0xe0,0x29,0xc2,0xa9,0x2b,0x1a,0xa1,0x9e,0xc2,0x58 +,0x40,0xb0,0x37,0x4c,0xc6,0x5a,0x28,0x22,0xad,0xab,0xbd,0xb1,0xae,0x34,0x20,0x34,0xaa,0xaa,0x2a,0x38,0x60,0x3f,0xbc,0xa4,0xb5,0x1a,0x1c,0xcc,0xad,0xd1,0x3b,0xac +,0xae,0x36,0xae,0x99,0x39,0x1f,0x3f,0xbb,0x2e,0x1e,0xb1,0xb6,0x4f,0x39,0xc4,0xa8,0x58,0x38,0xf1,0x45,0x24,0x57,0xa4,0xa6,0xb4,0xae,0x37,0x1d,0x24,0xbb,0x97,0xa9 +,0x27,0x21,0x2b,0x5e,0x9e,0x99,0xac,0x1d,0x16,0x39,0xaf,0xbd,0xbb,0xad,0x5b,0x2b,0x4e,0xaf,0x55,0x42,0x4b,0xc4,0x39,0x27,0xb3,0xa9,0xb4,0x57,0xdf,0xb5,0x4a,0x3c +,0xe1,0x32,0x26,0x3f,0xa0,0xb4,0x2a,0x57,0xcf,0xea,0xed,0xdf,0xc3,0x52,0x20,0xc0,0xaa,0x57,0xca,0xae,0xcf,0x1c,0x20,0x5e,0xbc,0xb2,0xac,0xe8,0xd1,0xe5,0xf5,0xe9 +,0x3a,0xb8,0xb4,0xce,0x28,0x36,0xa4,0xb7,0x5f,0x53,0x46,0xcf,0x4d,0x28,0x2f,0x3d,0xd7,0xaa,0xa3,0xb4,0x2c,0x2f,0xbf,0xb2,0x55,0x3a,0xd3,0xd1,0x3c,0xc0,0xaf,0x3e +,0x3d,0xd7,0xc7,0x2f,0x29,0x61,0xda,0x37,0x5d,0xaa,0xa8,0xaa,0xbb,0x37,0x1a,0x35,0xae,0xab,0x36,0x31,0xa5,0xcf,0xf5,0xda,0x62,0x3d,0x46,0x2c,0x31,0x4d,0xce,0xa2 +,0xad,0xcf,0x3e,0xbe,0xc8,0xe0,0x79,0x26,0x29,0xe5,0xc6,0xbe,0x6b,0x54,0xc0,0xb4,0xa1,0x59,0x2c,0x46,0xdd,0xc3,0xf1,0x2d,0xc2,0xb3,0x39,0x41,0x28,0xdc,0xb0,0xad +,0x39,0x1f,0xbe,0xab,0xa9,0xb5,0x7c,0x38,0x3b,0x2c,0x2f,0x46,0xe9,0xa7,0xbc,0x36,0x4c,0xa6,0xb5,0x31,0x5c,0x3b,0x3f,0xbc,0xbf,0xce,0x26,0x29,0xa1,0xa0,0x4f,0x28 +,0x28,0x36,0xbf,0xba,0xc7,0x45,0x5c,0xb1,0x55,0x5d,0xba,0xa6,0xb9,0xce,0x2b,0x26,0xb9,0xad,0x9f,0xe1,0x1a,0x1c,0xcc,0xbc,0xdf,0x40,0x31,0xce,0xb0,0xaa,0xc0,0xab +,0xc1,0x2f,0x5d,0x3e,0x2b,0x32,0xd5,0xb8,0x5e,0x49,0xc7,0xb0,0xcc,0x25,0x38,0xb8,0xb2,0xde,0x3a,0x41,0xbc,0xb3,0xbd,0xed,0x2c,0xbc,0xcf,0x4e,0x2f,0x30,0xb4,0xfe +,0x36,0x2a,0x3f,0xb1,0x9c,0xbb,0x23,0x1d,0x2b,0x9d,0x9b,0xb4,0x38,0x31,0x3e,0xb3,0xa4,0x60,0x2e,0x2b,0x4d,0x43,0x3b,0xbf,0xaf,0xa3,0x9f,0x3b,0x1d,0x3e,0xc4,0xb3 +,0xbe,0x2d,0x2d,0xf6,0xcf,0xb9,0x3f,0x2f,0xbe,0xa6,0xc0,0x3e,0xd8,0x51,0x3d,0x4d,0xa4,0xae,0x2e,0x1d,0x1e,0x3f,0xac,0x9f,0xaf,0x2a,0x17,0x3d,0xa1,0x98,0x9a,0x2a +,0x1e,0x4b,0xd4,0x4b,0x42,0xee,0xba,0xb7,0x59,0x1f,0x20,0xbc,0xa4,0xaf,0x5c,0x21,0x39,0xa7,0xa2,0xac,0x47,0x2a,0x48,0x9b,0xe2,0x21,0x40,0x54,0x65,0x5e,0xba,0xcf +,0x2f,0x1f,0x6d,0xa3,0x9e,0xa8,0x3e,0x3c,0x33,0xcb,0xa6,0xd9,0x22,0x20,0x46,0xb3,0xa9,0xe4,0x24,0x21,0x2e,0xa9,0x9f,0xbc,0x41,0xd8,0xb5,0xb2,0xe7,0x39,0xe5,0x46 +,0x39,0x2d,0x33,0xb5,0xa5,0xa6,0x3c,0x1d,0x28,0xea,0xa7,0xae,0x47,0x24,0x34,0x3f,0xb7,0x9f,0xbe,0x4e,0x6f,0xca,0x2c,0x3f,0xde,0xd2,0xd8,0xbb,0xa2,0xc4,0x2b,0x25 +,0x4e,0xc9,0xb2,0xa1,0xba,0x1a,0x1c,0xa9,0x9a,0xa6,0x2c,0x1d,0x34,0x54,0xd2,0x41,0x39,0xab,0x97,0xa7,0x3b,0x30,0x25,0x3b,0xe8,0x45,0x3e,0x3b,0x5b,0xcc,0xa3,0xa6 +,0xe7,0x3d,0x31,0x28,0x17,0x1d,0xb5,0x8c,0x9c,0xe1,0x8d,0x8d,0x1a,0x09,0x1f,0xde,0x9b,0x1c,0x0b,0x17,0x29,0xb0,0x95,0x18,0x03,0x9d,0x80,0x85,0xba,0x18,0x14,0x6b +,0xa5,0x96,0x8d,0xb0,0x0f,0x2f,0xa8,0x0d,0x06,0x13,0x15,0x14,0x90,0x88,0x8b,0x91,0xb8,0xa5,0xb5,0x11,0x20,0x8b,0x97,0x1a,0x25,0xc0,0x18,0x13,0x1e,0x16,0x34,0xae +,0xa6,0x9c,0x3a,0x38,0x8a,0x95,0x07,0x11,0x88,0x86,0xbf,0x13,0x19,0xbe,0x96,0xd1,0x0d,0x00,0x04,0x94,0x80,0x9c,0x14,0xae,0x8e,0xb9,0xc9,0x57,0x36,0x2d,0x1c,0xb2 +,0xb3,0x12,0x14,0xaa,0x18,0x11,0x90,0x85,0x97,0x42,0xc4,0x5a,0xd3,0x1c,0x2c,0x93,0x94,0xb4,0x9b,0x51,0x06,0x11,0x57,0x18,0x09,0x2a,0x97,0x88,0x8d,0xa3,0xc7,0x1c +,0x0b,0xab,0x81,0x9f,0x0c,0x13,0xba,0xb6,0xb1,0x28,0x0e,0x0c,0x4e,0x87,0x8d,0x14,0x09,0x95,0x8c,0x2d,0x1d,0xa9,0x9d,0xb7,0xba,0xbe,0x3d,0x1d,0x28,0x20,0x07,0x07 +,0x97,0x84,0xa8,0xd9,0x8f,0x8f,0x3e,0x20,0x49,0xab,0xe6,0x1f,0x2d,0x29,0x0e,0xf2,0x92,0x17,0x08,0xab,0x89,0x8f,0x9b,0x5e,0x36,0x23,0x24,0x9f,0x90,0xd2,0x20,0x96 +,0xad,0x0e,0x0c,0x18,0x0e,0x0e,0xa8,0x8c,0x8e,0xad,0xa8,0x91,0xb3,0x0e,0x38,0x8f,0xa8,0x2f,0x5c,0x3e,0x1e,0x21,0x3a,0x25,0x0d,0x1c,0x91,0x90,0x1e,0x25,0x9b,0x9d +,0xc5,0xb3,0xae,0xd5,0xbf,0xc3,0xae,0x2a,0x23,0xb2,0x4c,0x09,0x09,0x99,0x8e,0xb1,0xae,0x99,0x9f,0xdc,0x58,0xde,0xb0,0x35,0x23,0xb1,0x33,0x0b,0x28,0x9e,0x1d,0x15 +,0xab,0x91,0x94,0x9b,0xa6,0xc3,0x1e,0x0e,0x39,0xa0,0x5b,0xa9,0x8d,0x9a,0x1c,0x0f,0x15,0x0d,0x0c,0xc5,0x8e,0x9b,0xa9,0xa1,0x99,0xac,0x22,0xc2,0xb9,0x39,0x76,0xac +,0x3b,0x17,0x24,0xd5,0xd4,0x17,0x1f,0x97,0x9c,0x21,0x3b,0xb2,0xb9,0xa6,0xa8,0xac,0xb6,0xb5,0xa9,0xa6,0x23,0x0e,0x2b,0xb4,0x11,0x0c,0xba,0x95,0x9e,0x9e,0x99,0x9e +,0xba,0x3d,0xe2,0x51,0x27,0x22,0xa8,0xbd,0x14,0x2b,0x63,0x17,0x0f,0xb6,0x98,0xa2,0x9c,0x98,0xa3,0x2d,0x1e,0x4b,0xae,0xd2,0x96,0x91,0xce,0x16,0x0f,0x1a,0x0e,0x0b +,0x33,0x92,0x9b,0xae,0x9b,0x99,0xa7,0xe4,0x5f,0x35,0x4a,0xa2,0x9a,0xb2,0x19,0x0e,0x26,0xba,0x1f,0x17,0xa8,0x9c,0xbd,0xa8,0xbe,0xca,0xb2,0xd8,0x5f,0x61,0xdd,0xaa +,0xa0,0x67,0x1b,0x20,0x5c,0x1e,0x19,0x2f,0x4c,0xd6,0x9b,0x91,0x9b,0xa2,0xab,0xb2,0x29,0x1b,0x2a,0x4c,0x54,0x2a,0x2d,0x27,0x1b,0x1e,0xb3,0x96,0x9b,0xa3,0xa2,0xa9 +,0x59,0x1f,0x24,0xed,0xb1,0x98,0x9f,0xb1,0x40,0x15,0x12,0x16,0x0e,0x1e,0x9c,0x95,0x9e,0xa0,0x9c,0xa8,0xb9,0x22,0x1d,0x3e,0x9c,0x92,0xa5,0x2e,0x12,0x21,0x41,0x2d +,0x1c,0x2c,0x60,0xc7,0xa8,0xca,0xbe,0xa4,0x9f,0xa9,0xd5,0xc3,0xa4,0xb1,0x5c,0x1f,0x17,0x1f,0x20,0x22,0x29,0x49,0xcf,0xa1,0x97,0x99,0x9b,0xa5,0x67,0x2b,0x2c,0x42 +,0xb5,0xb9,0x36,0x12,0x12,0x28,0x38,0x52,0xa7,0x9f,0xaa,0x9c,0x9a,0xa4,0x25,0x11,0x20,0xb1,0x98,0x9e,0x9f,0xac,0x2f,0x1e,0x19,0x11,0x12,0x2f,0xad,0xa6,0x9d,0xa2 +,0xb2,0xab,0xc5,0x32,0x56,0x9c,0x9c,0xcc,0x27,0x1d,0x1a,0x1f,0x36,0x3d,0x57,0x6e,0xaf,0xbe,0x68,0xb0,0x9e,0xad,0x45,0x4b,0xb1,0x99,0x9b,0xa5,0x1a,0x08,0x0f,0x33 +,0x4e,0x26,0x4f,0xb1,0xa7,0x99,0x93,0x9b,0xbb,0x4d,0x2e,0x2c,0x3c,0x32,0xc7,0xae,0x3e,0x22,0x24,0x2a,0x1e,0x25,0xe5,0x9f,0x9b,0x9d,0x9e,0xb7,0x27,0x1d,0xb7,0x9e +,0xa2,0xa4,0xb3,0x2e,0x19,0x1f,0x22,0x20,0x24,0x2e,0x2b,0xe7,0x9c,0x95,0x9b,0xd3,0x45,0xe0,0xa5,0x97,0x9e,0x49,0x19,0x14,0x14,0x1b,0x26,0x2f,0xa9,0x9b,0xa1,0xb9 +,0xbd,0xbd,0x3e,0x3d,0xc2,0x9f,0xb9,0xf9,0xa7,0xbc,0x1d,0x19,0x5e,0x44,0x1f,0x19,0x22,0xcb,0xa2,0x8f,0x8f,0x9a,0xbe,0x2b,0x2d,0x55,0xc9,0x4a,0x2c,0x1d,0x24,0x43 +,0xb6,0xbc,0x31,0x1f,0x26,0xad,0x9d,0x9a,0xac,0x25,0x2c,0xbb,0x9d,0x9e,0xa9,0xb9,0x27,0x1a,0x20,0x3e,0x20,0x16,0x21,0x38,0xd5,0x9f,0x8c,0x8f,0xaa,0x2a,0x23,0xd1 +,0xa6,0x95,0x98,0x52,0x12,0x0c,0x19,0x2c,0x2c,0x36,0xdc,0xce,0xb0,0xa0,0x9d,0xb9,0x41,0xda,0x9f,0x9d,0x32,0x3b,0x4d,0x26,0x45,0xb8,0xb4,0x27,0x15,0x16,0x25,0xb7 +,0xa2,0x9b,0xa0,0xa1,0xa4,0xb5,0xca,0xd4,0xcd,0x2b,0x1a,0x18,0x26,0x6f,0xe2,0xba,0xda,0x3c,0x30,0x51,0x98,0x96,0xbe,0x39,0x38,0x42,0x69,0xa9,0x93,0xa7,0x2f,0x3b +,0x36,0x18,0x06,0x0d,0x2b,0xbd,0x96,0x8f,0x94,0xa8,0x5b,0x34,0xbc,0x9d,0x9d,0xab,0x29,0x16,0x18,0x26,0x3d,0x48,0x78,0x3a,0x28,0x3b,0xb4,0x9c,0xa0,0xa2,0xaf,0xc2 +,0xb7,0x3b,0xd0,0xcd,0x1f,0x22,0x69,0x45,0x2d,0x28,0x26,0x1f,0x42,0x99,0x94,0xa5,0xc5,0xa1,0xa8,0xcf,0xe7,0x5b,0x4e,0x21,0x24,0xcf,0xc7,0x24,0x16,0x22,0x2d,0x39 +,0xad,0x99,0x99,0xad,0xc3,0xbf,0xbb,0x7e,0xc8,0x9d,0xa7,0x4a,0x3e,0x3f,0x1a,0x0b,0x13,0x24,0x2e,0xac,0x94,0x9a,0xb7,0xc1,0xc1,0xc8,0x9b,0x94,0xa7,0x27,0x14,0x30 +,0x4d,0x26,0x2b,0x2a,0x2e,0x1b,0x23,0x9e,0x92,0x9b,0xa7,0xa8,0xbe,0xc4,0x3e,0x2b,0x46,0x33,0x52,0xa1,0xa5,0x21,0x12,0x1e,0x1e,0x2c,0xac,0x9a,0xae,0x3b,0xab,0xa2 +,0xa4,0x9e,0x9f,0xb5,0x1d,0x13,0x2b,0x33,0x24,0x1c,0x2b,0x33,0x30,0x95,0x90,0xa9,0xb6,0xac,0x4f,0x18,0x1c,0xb6,0x94,0x96,0x9f,0xb6,0x32,0x1e,0x15,0x0f,0x12,0x11 +,0x27,0x95,0x95,0xa0,0x93,0x93,0xb1,0xaf,0xae,0xc7,0x27,0x0d,0x1f,0xbb,0xbb,0xbb,0x5a,0x46,0x15,0x0d,0x4e,0x9b,0xb8,0xcf,0x97,0x99,0xa8,0xa1,0xad,0xaf,0x5f,0x21 +,0x2d,0x13,0x0a,0x18,0x68,0xb2,0xa9,0x94,0x93,0xae,0x2a,0xb2,0xc1,0x1c,0x39,0xa0,0xaa,0xcb,0xa8,0xac,0x38,0x1e,0x19,0x18,0x18,0x15,0xcb,0x97,0xa3,0x9f,0x92,0x93 +,0x30,0x16,0x2c,0xb9,0xb4,0xc6,0xa4,0x9d,0xaa,0x68,0x15,0x13,0x12,0x14,0xdb,0x33,0x17,0xb7,0x8b,0x8e,0x8d,0x89,0x90,0x51,0x0d,0x13,0x1e,0x11,0x15,0x40,0x62,0x3d +,0x4f,0x9c,0x91,0xb6,0x36,0xaa,0x33,0x0f,0x41,0xa0,0x9b,0x93,0x98,0xac,0x19,0x0c,0x19,0x1d,0x14,0x1d,0xb1,0x90,0x93,0x9d,0x97,0x9e,0x22,0x26,0xb0,0x1d,0x0e,0x3b +,0x96,0x93,0x92,0x9a,0x3e,0x10,0x05,0x0d,0x33,0x35,0x25,0xa6,0x8e,0x97,0x9e,0x8f,0x8a,0x9b,0x45,0x1c,0x0e,0x09,0x12,0x1f,0x38,0xb0,0xaa,0xa5,0x37,0x1a,0xae,0x8f +,0xdd,0x1e,0xa3,0x8b,0x91,0xa8,0xb0,0x50,0x10,0x11,0x1e,0x0c,0x09,0x1b,0x9c,0x8c,0x8e,0x99,0x98,0xc0,0x17,0x31,0x52,0x22,0x1f,0xac,0x91,0x96,0xa5,0xb0,0x2d,0x15 +,0x13,0x14,0x15,0x13,0x1b,0x9d,0x86,0x8c,0x93,0x98,0xfe,0x20,0xca,0xbf,0x1a,0x12,0x29,0xad,0xc7,0x23,0x2c,0xa9,0xbc,0x2f,0x32,0x2d,0x1b,0x28,0x93,0x89,0x8b,0x93 +,0xa4,0x32,0x14,0x1d,0x15,0x08,0x09,0x36,0x92,0x92,0xa7,0xac,0x9b,0xaf,0x2c,0x25,0x29,0x1f,0x26,0xa0,0x8f,0x95,0x9b,0xaf,0x1b,0x12,0x18,0x17,0x1a,0x22,0x4a,0x90 +,0x89,0x9e,0xd7,0x9f,0xa1,0xcd,0x1e,0x0e,0x0e,0x24,0x9f,0x9e,0xa9,0x44,0xe3,0xba,0x30,0x26,0x2c,0x40,0x2a,0xb3,0x8e,0x8e,0xa4,0xaa,0xa0,0xf8,0x20,0x17,0x0d,0x07 +,0x0c,0xe1,0x8e,0x8d,0x9f,0xc7,0xb1,0xb7,0x43,0x27,0x25,0xe0,0x9d,0x8c,0x8e,0xc4,0x2d,0x2a,0x1b,0x14,0x0d,0x0a,0x0e,0x1e,0xaf,0x8c,0x84,0x91,0xa3,0x97,0xa0,0xf2 +,0x20,0x11,0x12,0xdf,0xa4,0x3f,0x18,0x1d,0xaf,0x9f,0x48,0x14,0x22,0xd4,0xc4,0xa4,0x8f,0x90,0x99,0xa3,0xca,0x48,0x2b,0x1d,0x0e,0x0f,0x28,0x9e,0x9b,0x37,0x1e,0x5f +,0x9a,0xa4,0x20,0x12,0x1e,0xa2,0x8f,0x8d,0x8e,0xa3,0xa9,0xcb,0x18,0x0c,0x09,0x0c,0x23,0xb3,0xbb,0xa7,0x9c,0xa3,0xa7,0x98,0x9d,0x3e,0x24,0x19,0x27,0xa5,0x9b,0xc2 +,0x37,0x46,0xd0,0xdc,0x1d,0x0f,0x1b,0xac,0x9f,0x97,0x9a,0x55,0xbb,0x9a,0xa8,0x26,0x15,0x11,0x11,0x23,0xaa,0x95,0x90,0x9f,0xbe,0xab,0xb8,0x28,0x0e,0x0a,0x27,0x92 +,0x95,0xcd,0xf8,0x9f,0x95,0xa5,0x1e,0x0c,0x0e,0x14,0x3a,0xc0,0xae,0x97,0x8c,0x94,0xa6,0xad,0x3e,0x1f,0x19,0x26,0xf2,0x9b,0xba,0x0f,0x17,0xaf,0x9e,0x75,0x13,0x0c +,0x1d,0x9d,0x93,0x95,0x90,0x93,0x8d,0x8e,0x40,0x0d,0x09,0x0b,0x15,0x36,0xcc,0x37,0x3c,0xaa,0xa4,0x97,0x9a,0x2c,0x18,0x1d,0xc2,0x94,0x96,0xaa,0xa5,0x98,0x9f,0x28 +,0x0a,0x07,0x0d,0x3a,0xa4,0xb7,0x2f,0x39,0x93,0x8e,0x98,0xa9,0x2e,0x19,0x17,0x39,0x9f,0x8e,0x99,0x39,0x5a,0xad,0x28,0x0c,0x07,0x0a,0x45,0x98,0xaa,0xb6,0xa4,0x8e +,0x85,0x88,0x6d,0x0a,0x0f,0x14,0x15,0x20,0x55,0xbd,0x99,0x92,0xa9,0xd9,0x2d,0x15,0x0f,0x3a,0x9b,0x8f,0xa9,0x24,0xa7,0x90,0x9b,0x28,0x0d,0x0b,0x0f,0x2d,0xa5,0xa4 +,0xb1,0x98,0x8a,0x90,0xbc,0x15,0x0b,0x0f,0x29,0xc3,0xb6,0xaf,0x75,0xb3,0x9a,0x91,0xaf,0x1c,0x13,0x0d,0x26,0xab,0xae,0xac,0x8f,0x8c,0x95,0xbd,0x13,0x0e,0x1f,0x35 +,0x20,0x29,0x31,0x23,0xa4,0x97,0x9e,0xa7,0x67,0x1c,0x1a,0xc0,0x9b,0x90,0x9e,0xa5,0x9b,0xa2,0x1c,0x05,0x08,0x11,0x47,0x9c,0xb6,0x19,0x1e,0x92,0x84,0x8e,0xcd,0x19 +,0x1c,0x27,0x61,0xa6,0xa7,0xad,0xac,0xb1,0xe5,0x22,0x0d,0x0e,0x12,0x20,0xb6,0x99,0x9f,0xa0,0x90,0x93,0x94,0xa6,0x27,0x0f,0x1a,0x2f,0x5d,0xa5,0xad,0xa8,0x9e,0xa5 +,0x1c,0x0f,0x1a,0x1f,0x3c,0xa9,0xa0,0xa5,0xa5,0x9c,0x99,0xae,0x17,0x09,0x11,0x1b,0x1f,0x47,0xbf,0xbe,0x9b,0x91,0x9e,0x4b,0x27,0x3d,0xc7,0xa6,0x9e,0xa1,0xc9,0x40 +,0xbc,0xb2,0xc0,0x30,0x1c,0x0e,0x0c,0x18,0xac,0x93,0x9a,0x97,0x98,0x9d,0xdf,0x1d,0x17,0x1b,0x3f,0x5f,0x2f,0x36,0xd5,0xa0,0x94,0xa2,0x3a,0x26,0x2c,0x29,0x3b,0xac +,0xaa,0x9d,0x92,0x9a,0x3e,0x1c,0x16,0x19,0x1c,0x1c,0x22,0x47,0xe5,0x52,0xa7,0x94,0x9d,0x66,0x35,0x2a,0x34,0xbe,0x9f,0xa0,0xb3,0xb6,0xb0,0xb3,0x38,0x1f,0x1d,0x1d +,0x23,0x4d,0xbe,0xc2,0xae,0x99,0x96,0xa2,0xc6,0x3c,0x28,0x1a,0x1a,0x25,0x45,0xb6,0xa7,0xba,0x32,0x1e,0x1e,0xf1,0xa9,0xaa,0xbe,0xbd,0xad,0x9f,0x97,0xa2,0xc3,0xd6 +,0x33,0x1f,0x1f,0x24,0x48,0xb9,0x5e,0x3d,0xc2,0xbd,0x3c,0x21,0x1d,0x2d,0xbd,0xa5,0xac,0xe7,0x49,0xaf,0xa2,0xa9,0x6b,0x2f,0x31,0x2f,0x2e,0x50,0xa9,0xa1,0xac,0x5e +,0x4d,0xba,0xaf,0xc1,0x2e,0x24,0x2d,0x46,0x42,0x45,0xea,0x4c,0x6f,0xe1,0x39,0x2f,0x3a,0x5e,0xaa,0x99,0x9e,0xb1,0xc6,0x51,0x3f,0x39,0x35,0x30,0x37,0x3a,0x31,0x34 +,0x4f,0xc2,0xab,0xa1,0xbd,0x2d,0x2a,0x48,0xaf,0xa7,0xc6,0x68,0xbf,0x45,0x3d,0x65,0x4c,0x3b,0x35,0x29,0x2a,0xe4,0xae,0xac,0xaf,0xc4,0xad,0x9d,0xaf,0x3c,0x23,0x28 +,0xcd,0xb0,0xe4,0x2f,0x38,0x74,0xce,0x3c,0x25,0x34,0xbe,0xc1,0x33,0x37,0xad,0x9a,0x9e,0xce,0x2d,0x32,0x5d,0x40,0x31,0x35,0x36,0xde,0xc5,0x3c,0xdf,0xab,0xaf,0xc1 +,0xcd,0x6c,0x5f,0x4e,0x41,0x4a,0xc2,0xba,0xb1,0xac,0xe9,0x2a,0x1f,0x28,0x48,0xb4,0xab,0xbe,0x41,0x3a,0xc8,0xa6,0xaa,0x62,0x33,0x2c,0x2d,0x38,0xe3,0xb0,0xaa,0xb8 +,0x67,0x3d,0x3e,0x4c,0x50,0x5a,0xd6,0xba,0xc9,0x41,0x3b,0x5d,0xc4,0xb4,0xcf,0x2c,0x29,0x3d,0x74,0xbd,0xba,0x48,0xbe,0xa8,0xb7,0xdd,0x3e,0x48,0xae,0xb8,0x2c,0x26 +,0x3a,0xbe,0xac,0xba,0x38,0x2f,0x33,0x31,0x3c,0xd4,0xc4,0xbc,0xb3,0xb6,0xb1,0xab,0xbb,0x31,0x2d,0x52,0xc0,0xbe,0x43,0x2d,0x3c,0xf1,0xc8,0xc9,0x6e,0x41,0x53,0x4f +,0x3d,0x5d,0xb9,0xb2,0xad,0xb8,0x3f,0x3f,0x3f,0x3c,0xc4,0xb9,0x31,0x23,0x2e,0xdc,0xa7,0xaa,0x4d,0x47,0xfc,0xe8,0xc8,0x5d,0x3b,0xf1,0xb6,0xbd,0xc8,0xce,0xca,0x3e +,0x43,0x4e,0x2e,0x34,0x33,0x42,0xb4,0xa8,0xae,0xab,0xd0,0x2f,0x3d,0x54,0x78,0xcb,0x6c,0x35,0x5e,0xc8,0x6d,0xe8,0xdb,0x6a,0xc9,0xea,0x3b,0x3b,0x72,0xb7,0xb8,0x52 +,0x3c,0x56,0xbe,0xd8,0x35,0x33,0x33,0xe3,0xb6,0xbd,0xc5,0xc2,0xc4,0xd5,0xd6,0x6f,0x63,0x42,0x2b,0x37,0xc0,0xb8,0xbe,0xc8,0xce,0xda,0xca,0x43,0x2b,0x3c,0x3f,0x3c +,0xd0,0xb2,0xad,0xad,0xc6,0x7d,0xc7,0x4a,0x2f,0x34,0x48,0x60,0xc3,0xbe,0x4a,0x49,0xba,0xc6,0x33,0x39,0x55,0xc8,0xb5,0xce,0x3d,0x46,0xd2,0xc7,0xaf,0xce,0x30,0x2e +,0x26,0x35,0xeb,0xc1,0xb3,0xb2,0xb4,0xb6,0xc0,0x4a,0x5b,0x52,0x4a,0x45,0x32,0x4b,0xb4,0xaa,0xae,0xad,0xbd,0x2e,0x1f,0x22,0x31,0x5f,0xb9,0xca,0x6b,0xb5,0xa6,0xac +,0xc6,0xe9,0x44,0x3f,0x2d,0x27,0x44,0xaf,0xb3,0xc3,0xcb,0x35,0x31,0x3f,0x5f,0xd3,0xc7,0x3b,0x30,0x78,0xb4,0xa7,0xae,0x5f,0x2f,0x32,0x3f,0x4c,0x3b,0x4e,0xb7,0xad +,0xad,0xb4,0xc3,0xc9,0x43,0x28,0x2c,0x35,0x4b,0xcd,0xbd,0xb5,0xaa,0xb1,0xd0,0x4c,0x34,0x3a,0x35,0x2b,0x3c,0xc4,0xb5,0xa7,0xae,0xda,0x5a,0x41,0x3c,0xed,0xf2,0x38 +,0x35,0x4c,0xb2,0xa9,0xb3,0x7a,0x4d,0x2f,0x25,0x2e,0xec,0xae,0xbd,0x63,0xef,0xbe,0xaf,0xb4,0x39,0x28,0x33,0x46,0x4e,0x40,0xdd,0xab,0xa2,0xb5,0xd5,0xc8,0x41,0x2f +,0x29,0x24,0x3b,0xbd,0xbc,0xb3,0xac,0xaa,0xab,0x4c,0x25,0x28,0x34,0x4a,0x41,0x3b,0xbb,0xa3,0xaf,0xc9,0xde,0x5a,0x4d,0x36,0x2e,0x42,0xfe,0xd0,0xb6,0xae,0xad,0xb9 +,0x3b,0x2c,0x30,0x37,0x52,0x3b,0x3e,0xbb,0xae,0xb6,0xad,0xb7,0x4b,0x3f,0x2c,0x2a,0x3d,0x7b,0xba,0xa4,0xaa,0xc1,0xef,0x40,0x3b,0x3d,0x38,0x33,0x30,0x3e,0xbc,0xac +,0xa8,0xab,0xb3,0xeb,0x2f,0x25,0x2d,0x46,0x39,0x5b,0xae,0xa5,0xae,0x76,0x35,0x3d,0x64,0x5c,0x3c,0x27,0x2a,0xbb,0x9f,0xa2,0xad,0x5c,0x32,0x2f,0x29,0x36,0xc3,0xeb +,0x52,0xcf,0xb7,0xac,0xad,0x4f,0x2c,0x37,0x4e,0x56,0x2b,0x2c,0xd8,0xa2,0x9d,0xa4,0xbe,0x3b,0x28,0x22,0x32,0x4d,0x36,0x64,0xaf,0xab,0xaa,0xb9,0xd4,0xcc,0x48,0x2b +,0x2b,0x27,0x29,0xd8,0x9f,0x9d,0xa8,0xe4,0x3d,0x40,0x4d,0xc9,0x45,0x23,0x21,0x5d,0xa7,0x9e,0xa7,0x56,0x2e,0x2f,0x47,0x5f,0x4d,0x43,0x53,0xc9,0xb5,0xb0,0xb0,0xce +,0x33,0x36,0xd7,0x5c,0x29,0x2d,0x58,0xab,0x9e,0xad,0x42,0x38,0x3f,0x52,0x48,0x28,0x23,0x62,0xab,0xae,0xac,0xa8,0xae,0x52,0x2c,0x2c,0x2d,0x2f,0x35,0x48,0xb0,0xa8 +,0xb8,0x3e,0x44,0xc6,0xa8,0xaf,0x2a,0x1f,0x2c,0xb4,0xa3,0xa4,0xc5,0x33,0x35,0x63,0xe1,0x3b,0x29,0x2a,0x44,0xaf,0x9d,0xa4,0xdc,0x29,0x2b,0xc6,0xa6,0xdd,0x23,0x2a +,0x4f,0xb1,0x9e,0xa5,0xcc,0x4b,0x40,0x33,0x20,0x1d,0x26,0xb3,0xa1,0xac,0xcc,0x78,0xb8,0xab,0xa8,0x6e,0x22,0x1d,0x22,0x4a,0xa2,0x9d,0xbc,0x2d,0x2c,0xbe,0xa2,0xbc +,0x1f,0x18,0x29,0xae,0x9d,0xa8,0x6c,0x34,0x6f,0xab,0xae,0x37,0x23,0x2c,0x48,0xc2,0xab,0xac,0xdf,0x34,0x47,0xba,0xc5,0x29,0x1d,0x3c,0xad,0x9e,0xab,0x40,0x36,0xba +,0x9e,0xb4,0x22,0x17,0x1f,0xe3,0xab,0xb4,0xc1,0xb4,0xb6,0xba,0xb6,0x4c,0x1e,0x1e,0x39,0xb2,0xa4,0xb3,0x2d,0x2e,0xb5,0x99,0x9a,0x36,0x12,0x19,0xde,0xa1,0xa6,0x68 +,0x2a,0x38,0xaa,0xa1,0xdc,0x22,0x1e,0x36,0xc2,0xae,0xae,0xbe,0xda,0x7b,0xb7,0xae,0xd8,0x28,0x22,0x3e,0xc4,0xbf,0xe2,0x4a,0x5b,0xa7,0x9f,0x45,0x19,0x1d,0x39,0xb9 +,0xac,0xce,0x4e,0xb2,0x9f,0xa3,0xc2,0x25,0x23,0x27,0x2e,0xb6,0x9e,0xce,0x2d,0x37,0xce,0xa7,0xc8,0x2d,0x23,0x2d,0x36,0xaa,0xa8,0xdf,0xb1,0xa0,0xac,0x24,0x28,0x56 +,0xb2,0x32,0x1f,0xec,0xab,0xad,0x53,0x42,0x4f,0x51,0xba,0xb7,0x34,0x1e,0xd5,0x9d,0xbe,0x47,0xb1,0xa9,0x3d,0x1f,0x2d,0x3a,0x46,0xb6,0xe9,0x40,0xb4,0xa1,0x9c,0xbe +,0x20,0x25,0x59,0x40,0x26,0xb9,0xab,0x5c,0xce,0xe0,0x45,0x2d,0x68,0xc8,0xcc,0x49,0x30,0x40,0xb4,0x9b,0xa8,0xaf,0x2d,0x22,0xbc,0xc0,0x29,0x21,0x4b,0xde,0xad,0xa8 +,0x6f,0x25,0x39,0xba,0xad,0xb3,0x36,0x46,0x78,0xcb,0xb6,0xb2,0xa0,0x4a,0x16,0x1e,0xc3,0xaa,0x41,0x3a,0x2b,0xca,0x9f,0xa2,0xb8,0x2d,0x25,0x2d,0xad,0x3f,0x30,0xb2 +,0xa0,0xab,0xd0,0x35,0x16,0x3d,0x9d,0xce,0x21,0x3a,0xcb,0xac,0xac,0xc3,0xb8,0xba,0x27,0x1e,0xbf,0xc8,0x35,0xc7,0xc1,0xc0,0xb2,0xd8,0x5f,0x20,0x2e,0xb5,0xb3,0xb8 +,0x2e,0x24,0xe1,0x9c,0x9a,0xa7,0x36,0x18,0x1c,0xb8,0x9c,0xb9,0x45,0x21,0x1a,0x68,0xa0,0x9b,0xc5,0x31,0x39,0x2d,0x40,0x33,0xae,0x8f,0x9c,0x23,0x1d,0x28,0x29,0x3b +,0xb0,0x58,0x27,0xb1,0xb3,0xb3,0xa1,0xac,0xb2,0x54,0x1b,0x1f,0xcd,0x61,0x3f,0xbf,0xe6,0x42,0xab,0xad,0x1f,0x14,0x3a,0x98,0x95,0x3a,0x17,0x2b,0x98,0x8e,0xa5,0x42 +,0x1a,0x13,0x2d,0xb0,0xa3,0xd6,0x48,0xbf,0x2e,0x38,0xb2,0x9d,0xaf,0x35,0x1f,0x23,0xdd,0xa5,0xb2,0xc8,0xb7,0x2c,0x3d,0x2d,0x30,0xa0,0x9b,0x37,0x34,0x4b,0x2a,0x72 +,0xed,0x3d,0x40,0xad,0xbf,0x3c,0xc7,0xce,0x77,0xb5,0xcf,0x2e,0x23,0x1f,0xbc,0x9d,0xa1,0xaa,0x2d,0x27,0x2d,0xd6,0x9c,0xa6,0xdf,0x1e,0x1b,0x30,0xac,0x96,0x94,0xc4 +,0x18,0x15,0x24,0xb4,0xa8,0xea,0x27,0xb9,0xa3,0x6d,0x5e,0xb5,0xb1,0xa6,0x34,0x12,0x21,0xd9,0xa5,0xa6,0x56,0x2a,0xce,0xb8,0x3a,0x25,0x40,0x4f,0xb4,0x99,0xba,0x24 +,0x36,0x99,0x9c,0xd8,0x23,0x16,0x1d,0x23,0xbf,0x98,0x9d,0xa9,0x32,0x1e,0x2d,0xa4,0x95,0xbd,0x1b,0x11,0x2d,0xa7,0x93,0x95,0xbb,0x19,0x1e,0xc8,0x3a,0x21,0x27,0xd0 +,0xad,0xa2,0xdd,0xbc,0x9b,0xa1,0x2f,0x1c,0x19,0x13,0xc5,0x96,0x9b,0xc0,0x1c,0x2f,0xa0,0xa1,0x4e,0x1e,0x33,0x2f,0x51,0xae,0xc1,0xb2,0x9d,0xad,0x1e,0x2b,0xcb,0x38 +,0x18,0x23,0xa4,0x9a,0xaa,0xdd,0x2e,0x35,0xa7,0x95,0xad,0x0f,0x09,0x2d,0x8d,0x92,0xb3,0x3d,0x2c,0x29,0xee,0x4e,0xd9,0x45,0x5b,0xdd,0x25,0x6a,0xa9,0x8f,0x9d,0x3b +,0x14,0x11,0x1f,0x42,0x8f,0x97,0xd0,0x32,0x49,0x39,0x39,0xc3,0xb7,0x3c,0x1a,0x1c,0xb9,0x90,0x99,0xcf,0x48,0x25,0x27,0xb0,0xb2,0x21,0x17,0x47,0x9e,0xa4,0x63,0x31 +,0x2d,0xbe,0x9d,0xa7,0x27,0x0c,0x29,0x95,0x94,0xb6,0x51,0xaa,0x29,0x1d,0x6b,0xbd,0x44,0x30,0xc0,0x3b,0x39,0xa6,0x96,0xab,0x27,0x1f,0x31,0x5b,0x26,0x5b,0xa3,0xa6 +,0xcd,0x4e,0x2d,0x36,0x9e,0x9f,0x2a,0x0b,0x16,0xa0,0x8e,0x95,0xba,0x26,0x1a,0x32,0xab,0x9a,0xd0,0x0d,0x1e,0x9e,0x9d,0x59,0x48,0xbb,0x29,0x66,0xb6,0xd5,0x2c,0x24 +,0xab,0x9f,0xb9,0x4d,0xaf,0x4e,0x21,0x33,0xac,0x58,0x1e,0x3e,0xcf,0xba,0xaf,0x97,0xac,0x21,0x2a,0x5d,0x41,0x1f,0x34,0x9f,0x93,0x55,0x21,0x37,0x45,0xa9,0x9b,0xae +,0x0f,0x0b,0xb9,0x8d,0x93,0xc3,0x2d,0x28,0x21,0xcc,0xa9,0xcd,0x2f,0x25,0xd0,0xbe,0xbc,0xa6,0xa4,0x34,0x12,0x26,0xa2,0xaa,0x2b,0x6e,0xae,0xb8,0xdc,0xcb,0xda,0x2a +,0x28,0xd0,0x9d,0x38,0x19,0xd1,0xa0,0xdb,0xbf,0xa7,0x2a,0x1f,0x53,0xaa,0x39,0x25,0xaa,0x9e,0xb4,0x34,0xe1,0x70,0x22,0xc8,0xae,0x59,0x1c,0x25,0x9c,0x9f,0xb2,0xb4 +,0xb6,0x20,0x1a,0xb4,0x9c,0xdb,0x1b,0x27,0xcc,0x9d,0xa4,0xbb,0x29,0x11,0x23,0xa7,0x96,0xcd,0x22,0xda,0xaa,0xad,0xa9,0xd8,0x1c,0x23,0xb5,0xa3,0x3b,0x22,0xd5,0xad +,0xaa,0x2c,0x3a,0xbc,0x27,0x38,0xb7,0xa5,0x26,0x2f,0x9e,0xac,0x5a,0x36,0xcd,0x2d,0x2d,0xc1,0xa8,0x39,0x1c,0x75,0x9f,0x9f,0xdf,0x62,0x2a,0x1b,0xe4,0x99,0x9f,0x21 +,0x23,0xbb,0xad,0xab,0xac,0x3f,0x17,0x1d,0xec,0x9d,0xa5,0x60,0x42,0xbb,0xd4,0x27,0xb4,0xac,0x3e,0x2b,0x2c,0xbc,0xc5,0xb2,0xa7,0xcb,0x33,0x1b,0x49,0xca,0x3b,0xbb +,0xa0,0xaf,0x27,0x3a,0xfb,0xbc,0x59,0xaa,0xd8,0x16,0x1f,0xb1,0x94,0xbf,0x2c,0x48,0xd9,0x4e,0xcc,0xb5,0x45,0x23,0x56,0x99,0xbf,0x24,0x2d,0xb4,0xad,0x62,0xbe,0x38 +,0x1f,0x26,0x74,0x9a,0xa5,0x49,0x32,0x71,0x4f,0x4f,0xa4,0x37,0x20,0x2d,0x9f,0x9d,0xc7,0x69,0x26,0x58,0x57,0xe1,0x41,0x27,0x25,0xab,0x8f,0xbf,0x19,0x2f,0xa8,0xd5 +,0x3c,0xc7,0x4f,0x28,0xbc,0x9b,0xb1,0x2a,0x24,0xa9,0xb5,0x26,0x3c,0x4f,0x35,0x39,0xa3,0x9a,0x33,0x1f,0x30,0xb9,0xb7,0xbe,0xaf,0x24,0x1a,0x35,0x9f,0x9e,0xa8,0x55 +,0x26,0x39,0x22,0xca,0xa7,0xb5,0x32,0x39,0xac,0xc2,0xc9,0xb6,0xae,0x3a,0x1f,0x1d,0xc6,0xbb,0xba,0x9d,0xad,0x38,0x1e,0xbc,0xbf,0x2d,0x5d,0xb3,0x64,0x2f,0xb6,0xaf +,0x58,0x2e,0xcd,0xb4,0x2d,0x26,0xb6,0xae,0x37,0x2f,0xac,0x9c,0xb6,0x5e,0x2d,0x2e,0x2f,0xad,0xa6,0x39,0x1e,0x24,0xb5,0xae,0xc6,0x62,0xbf,0x38,0x37,0x69,0xbd,0xc7 +,0xb9,0xb0,0xdd,0xc1,0x37,0x68,0x2d,0x3b,0xc3,0xc3,0x5c,0x2a,0xbb,0xa9,0xc2,0x2f,0x3b,0xc5,0xfc,0x2e,0xc4,0xad,0x45,0x4f,0xaa,0xb3,0x46,0x29,0x2f,0xae,0x5e,0xbc +,0xb5,0x41,0x25,0x50,0x9c,0xb3,0x34,0x3a,0x32,0x29,0xc2,0xb1,0xc7,0x2f,0x5b,0xab,0xac,0xd7,0x2c,0xcb,0x3f,0x39,0xc5,0x40,0x36,0xaf,0xa8,0x55,0x2f,0x30,0xbf,0xb6 +,0x59,0x2f,0x29,0x5b,0xaf,0xb4,0xac,0xac,0xdc,0x2d,0x27,0x3b,0xea,0xab,0xcb,0x30,0x31,0xbe,0x9c,0xdf,0x21,0x2f,0xbc,0xca,0xc9,0xbd,0xef,0x26,0x40,0xa6,0xac,0xae +,0x34,0x45,0x33,0x3b,0xbb,0xce,0x45,0x4f,0xc0,0x39,0x3e,0x74,0xb9,0xd8,0x57,0x3f,0x44,0xe5,0xbe,0xa4,0xb4,0x2b,0x35,0xc4,0xbc,0x54,0x3a,0xba,0x36,0x67,0xcc,0xf9 +,0xae,0x50,0x38,0x79,0x2c,0x25,0xb6,0xbe,0xd1,0x40,0x42,0xaf,0xa1,0xab,0x2a,0x2b,0xe3,0xaf,0xb9,0x34,0x37,0x38,0x3e,0x4f,0x3b,0xb8,0xa7,0xc5,0x2e,0x29,0xd5,0x9d +,0xaf,0x4a,0x3f,0x37,0xac,0xaa,0xd9,0x20,0x1d,0xbc,0xd1,0x3d,0xbc,0xaf,0x70,0x34,0xc2,0xb6,0xc1,0x56,0xe8,0x3e,0x23,0x31,0xab,0xa9,0xba,0xae,0x29,0x2b,0x50,0xa9 +,0x9f,0x2d,0x1e,0x2a,0xf9,0xab,0xa8,0x42,0x2d,0x2f,0x66,0xb4,0xcb,0xb5,0xc9,0x3d,0x5f,0x5d,0xc4,0xae,0xbd,0x3a,0x44,0xec,0x29,0xc9,0xde,0x3a,0x39,0x34,0xa4,0x9f +,0x43,0x26,0xe9,0x5d,0x58,0x3a,0xb2,0xa4,0xcf,0x51,0x27,0x4a,0xac,0xa5,0xcd,0x21,0x1d,0x67,0x9e,0xb7,0x2b,0x2e,0xd2,0xb4,0xc3,0xca,0x43,0x3f,0xde,0xc8,0x47,0x74 +,0xa3,0xb5,0x7b,0x22,0x29,0xaf,0xc9,0xbe,0xca,0x25,0x1d,0x58,0x9c,0x9c,0x58,0x1e,0x29,0x40,0xb0,0xaa,0x4d,0x35,0x44,0xb7,0xad,0x9f,0xc7,0x31,0x2b,0x23,0x31,0x46 +,0xa6,0xec,0x22,0x3c,0xa3,0xa4,0xb6,0x44,0x2c,0xc8,0x4c,0xa4,0x99,0x49,0x26,0x36,0x38,0x2c,0x47,0xaf,0xc9,0x48,0x2c,0x26,0x4d,0x9e,0x93,0xb3,0x1f,0x16,0x5e,0xa0 +,0xa7,0x4b,0x30,0x32,0x43,0xb3,0xc5,0xb5,0x31,0x4c,0xbb,0xd7,0x6a,0xc0,0xda,0x2e,0x26,0x2a,0x9f,0xa7,0x33,0x2b,0x34,0x53,0xb9,0xaa,0xae,0x47,0x2d,0x73,0xa8,0xba +,0x52,0x46,0x36,0x42,0x3a,0xd9,0xcd,0x51,0x5d,0x51,0x2b,0x2d,0xa4,0x98,0xaf,0x25,0x37,0xba,0xb5,0xb7,0x38,0x33,0x2b,0xbe,0x9e,0xad,0x27,0x1c,0x4d,0x3e,0x49,0x5b +,0xa8,0xbd,0x46,0xca,0xbc,0xaf,0xb8,0xa4,0x3b,0x22,0x1f,0x3b,0xb2,0xee,0x4e,0xc3,0xac,0xbc,0x38,0x28,0x42,0x3a,0xc4,0xac,0x30,0x2d,0xab,0xa2,0xe9,0x27,0x31,0xa2 +,0x9c,0x5f,0x24,0x28,0x2d,0xb7,0xa1,0xb5,0x26,0x23,0x56,0xcf,0xbc,0x71,0xc1,0x48,0x38,0xbd,0xa9,0xb4,0xd8,0xb0,0xd8,0x44,0x26,0x3d,0xaf,0x6c,0x3c,0xbe,0xb9,0x29 +,0x21,0x37,0xb9,0xab,0xab,0xcd,0x32,0x35,0xa8,0x9c,0xcc,0x1f,0x1d,0xdd,0x9f,0xce,0x27,0x2e,0x3d,0x9a,0x97,0xd9,0x1d,0x1a,0x2c,0xc0,0xae,0x73,0xbd,0x5a,0xcb,0xdb +,0xba,0xbf,0x29,0x4d,0xbb,0x4c,0x26,0xc5,0xb4,0x63,0x48,0xb2,0x9e,0xb8,0x26,0x1c,0x3e,0x4b,0x59,0x44,0x3e,0xca,0x9b,0x97,0x65,0x27,0x37,0x9e,0x9e,0x2f,0x1b,0x1e +,0x3d,0x9a,0x9d,0x25,0x12,0x19,0xe2,0x94,0x9a,0x2c,0x32,0x35,0xfd,0xa0,0x9d,0xc6,0x3b,0x48,0x58,0xc5,0x37,0xdc,0x58,0x2d,0x28,0x2a,0xd8,0xab,0x38,0x29,0xb4,0xad +,0x9c,0xa5,0x34,0x1e,0x2b,0x41,0x31,0x37,0xd4,0x9b,0x9a,0x37,0x1a,0x34,0x9e,0x99,0xce,0x1e,0x11,0x1b,0x9e,0x8e,0xc9,0x19,0x28,0xad,0x99,0xa6,0x47,0x1f,0x23,0x63 +,0xad,0x9f,0xaf,0x4a,0x5d,0x2f,0x2d,0x6f,0xb7,0xc8,0x1e,0x1d,0x44,0xa1,0x91,0xa5,0x21,0x20,0x4b,0xb0,0xa0,0xb2,0x24,0x44,0xaf,0x24,0x22,0xbd,0xac,0xc3,0x26,0x20 +,0x3c,0xb7,0x9d,0x9e,0x4f,0x1e,0x2b,0xae,0x9d,0x2e,0x1a,0x2c,0xc1,0x9b,0x95,0xb8,0x18,0x1e,0x3d,0xbd,0xbb,0xd7,0x4e,0x57,0x2b,0x2d,0xca,0x9a,0x93,0x3b,0x18,0x16 +,0x2f,0x9b,0x97,0x3e,0x23,0xcb,0x95,0x96,0xaf,0x23,0x16,0x1f,0x1c,0x25,0xc8,0xa9,0xc8,0xaf,0xba,0xb2,0xa1,0x9b,0xae,0x16,0x14,0x2d,0x9b,0x91,0xb4,0x19,0x18,0x32 +,0xad,0xac,0x4d,0x12,0x21,0xad,0x3e,0xcb,0x99,0x95,0xa8,0x2f,0x19,0x3a,0xf6,0xa4,0xe4,0x19,0x20,0x69,0x97,0x9a,0x38,0x16,0x30,0xa8,0x9d,0xa0,0x3c,0x1c,0x2d,0x4c +,0xb5,0x97,0xad,0x26,0x24,0x1c,0x3c,0xa7,0x92,0x92,0x2c,0x1a,0x31,0xbf,0xa2,0xa9,0x14,0x0b,0x30,0x98,0x9a,0xb6,0x2b,0x2d,0xb7,0x2e,0x4c,0xa9,0xb9,0xc1,0xde,0x3c +,0xc5,0xa9,0x9f,0x42,0x10,0x13,0x2e,0xa2,0x9d,0xdf,0x1a,0x35,0x9f,0x9f,0xab,0xad,0x1e,0x21,0xba,0x3d,0xba,0xaf,0xb0,0xbd,0x26,0x1d,0xcf,0xa5,0xaa,0x4b,0x20,0x31 +,0xb9,0xa0,0xad,0x28,0x17,0x68,0x9b,0xbb,0xd5,0x4a,0x23,0xe5,0xbc,0xa8,0x98,0xc0,0x26,0x1d,0x1f,0xbe,0x9c,0x9e,0xb7,0x14,0x13,0x42,0xb0,0xa1,0xaa,0x2d,0x1c,0xb1 +,0x96,0x98,0xa3,0x2e,0x28,0x39,0x20,0x1e,0x28,0x4e,0xc3,0xc3,0xbd,0xbc,0xc8,0xb7,0x5e,0x28,0x30,0xbf,0x99,0x9d,0x4f,0x1e,0x3d,0xa2,0xc6,0x2f,0x37,0x1e,0x1a,0xdb +,0xab,0x9d,0x97,0x9e,0x3b,0x17,0x1f,0xb9,0xa8,0xb6,0x3e,0x20,0x1d,0xb2,0x97,0xaf,0x36,0x1c,0x59,0xac,0xed,0xad,0xa7,0xc3,0xe5,0x53,0x35,0x4c,0x23,0x1a,0x1d,0x48 +,0xa6,0xaa,0xa1,0xa4,0x5e,0x3e,0x9f,0xac,0x29,0x22,0x2f,0x36,0xd7,0xa4,0xa8,0xc2,0x25,0x26,0x2c,0x29,0x39,0xb9,0xa0,0xa6,0xb6,0xad,0xcf,0xd1,0xad,0x38,0x19,0x11 +,0x2e,0xa1,0x97,0x9f,0x40,0x2f,0x49,0xb8,0xe3,0x71,0x22,0x18,0x36,0xa7,0x9c,0xa4,0xba,0x24,0x26,0x7e,0xa8,0xab,0x38,0x24,0x41,0xaa,0xa2,0xb9,0x2c,0x37,0x35,0xbd +,0xaf,0x2d,0x1e,0x27,0xad,0x9f,0xaf,0x4f,0x58,0xb1,0xc2,0x3c,0x3f,0x38,0x40,0xbf,0xa9,0x59,0x27,0x46,0x70,0xaf,0xb2,0x48,0x1c,0x1e,0xab,0x96,0x9c,0x56,0x1f,0x15 +,0x3e,0x97,0x99,0x46,0x1b,0x21,0xaf,0x9c,0xa4,0xd7,0x1e,0x1e,0x30,0xa7,0x9d,0xb0,0x2b,0x1e,0xcc,0xa8,0xc1,0x27,0x32,0xab,0xf5,0xde,0xc7,0x29,0x37,0xa8,0x96,0xcb +,0x1d,0x26,0x45,0xb2,0xb9,0xb7,0x31,0x25,0x38,0xd1,0xb4,0x4b,0x43,0xbe,0xa2,0xa6,0x52,0x1e,0x1e,0xbb,0x97,0x9a,0xb3,0x19,0x0d,0x2d,0x9b,0x8f,0xae,0x22,0x15,0x18 +,0xae,0x9b,0xaa,0x37,0x2f,0x4b,0x54,0xae,0xad,0xc3,0xd6,0xca,0xc1,0x1f,0x1a,0x2e,0xa1,0x90,0x9e,0xce,0x15,0x11,0x2a,0xb2,0xa1,0xcf,0x64,0x62,0xb3,0xae,0x50,0x2b +,0xea,0x9c,0xb5,0x26,0x22,0x24,0x3a,0x9c,0x8e,0x9c,0x1a,0x0b,0x17,0xaa,0x8f,0x9f,0x33,0x13,0x1a,0xbc,0x99,0x91,0xe9,0x1e,0x1f,0x2d,0xb3,0x4f,0x57,0xb0,0xa8,0xae +,0xbc,0xc7,0x1d,0x20,0xbe,0xab,0x5b,0x24,0x4a,0xba,0xa5,0x9e,0xdd,0x1d,0x27,0xad,0xa9,0x42,0x1e,0x21,0xba,0x9a,0x96,0x9d,0x23,0x0e,0x1a,0xa9,0xa4,0x29,0x38,0xb4 +,0x9f,0xa2,0xc2,0x39,0x12,0x1d,0xa8,0x94,0xa0,0x1b,0x1e,0x7a,0xaa,0x9c,0x9a,0x53,0x0e,0x18,0xbc,0xaf,0x3b,0x2f,0xad,0x9e,0xae,0x57,0x4f,0x45,0x45,0xb4,0xb3,0x2a +,0x11,0x27,0x92,0x8e,0x9a,0x54,0x0f,0x0c,0x1c,0x9e,0x94,0x44,0x2a,0x7d,0xa0,0xb2,0x39,0xee,0x25,0x2f,0xa0,0x99,0x2b,0x0d,0x36,0x96,0x97,0x9d,0xba,0x18,0x09,0x1a +,0x97,0x8d,0xbd,0x1e,0x4d,0xaa,0x5b,0x2d,0xb3,0xc8,0x2a,0xc6,0xaa,0x4e,0x1a,0x22,0x9d,0x97,0xb1,0x39,0x20,0x2c,0x42,0xa9,0xa7,0x1c,0x1a,0xbb,0x96,0xad,0xf0,0xbc +,0x1d,0x2b,0xac,0xa7,0x39,0x19,0x3b,0x9d,0x99,0xb6,0x37,0x28,0x21,0x35,0x9c,0x9c,0x1a,0x10,0xdf,0x99,0xa8,0xdc,0xb3,0xce,0x2d,0x41,0xa9,0xb8,0x18,0x15,0xae,0x9c +,0xb2,0xaa,0xa3,0x3f,0x17,0x3c,0xc8,0x18,0x26,0xa2,0x9a,0xf7,0x43,0xae,0xef,0xae,0xad,0xfa,0x1f,0x0f,0x1c,0x9a,0x8b,0x9b,0xc3,0x26,0x1b,0x2a,0xd6,0x35,0x1d,0x35 +,0xa1,0x98,0xa8,0x38,0x32,0x6f,0x54,0x59,0xab,0xc5,0x0f,0x12,0x97,0x8c,0xae,0xc2,0xbd,0x25,0x13,0x31,0xa8,0x2d,0x1e,0x38,0x97,0xa2,0xdf,0xa2,0xa3,0xcc,0x1f,0x30 +,0x24,0x11,0x1e,0x97,0x8c,0x9e,0xbd,0x1d,0x20,0xad,0xad,0x24,0x19,0x23,0xbf,0x96,0x99,0xaa,0xca,0x36,0x1e,0x24,0x5d,0x4e,0x19,0x26,0x97,0x94,0x9c,0xba,0x27,0x36 +,0x27,0x1f,0xc6,0xcc,0x1c,0x2c,0x90,0x92,0xc2,0x31,0x3d,0x58,0x28,0xcf,0x41,0x16,0x18,0xa6,0x8c,0x99,0xae,0xc9,0xc4,0x23,0x17,0x25,0x26,0x28,0xb5,0x95,0xa1,0x6d +,0xd6,0xe7,0x33,0xda,0x49,0x1e,0x1d,0x53,0x9b,0x96,0x98,0xdc,0x21,0x25,0x21,0x1d,0x2f,0xbf,0xde,0xa9,0x96,0x9d,0x9d,0xee,0x13,0x1d,0x2c,0x52,0x52,0x20,0x18,0x9f +,0x87,0x95,0xe6,0x2f,0xcb,0x1d,0x11,0x2c,0x5e,0x3c,0xda,0x9c,0x9c,0xb9,0x48,0xae,0xab,0x2e,0x18,0x1d,0x20,0x2c,0xad,0x94,0x8e,0xa6,0x2f,0x1b,0x19,0x44,0xc7,0x25 +,0x1f,0xbe,0x9a,0x94,0x91,0xa8,0x22,0x1e,0x26,0x3d,0x29,0x19,0x1c,0x9b,0x88,0x9e,0xe7,0x2c,0x2a,0x2a,0x1e,0x20,0x49,0xbf,0x43,0xa2,0x91,0x97,0xf7,0x3e,0xbb,0x29 +,0x15,0x1d,0x1f,0x21,0xb5,0x9a,0x9b,0xb3,0xb7,0xc5,0x3f,0x36,0x4b,0x3f,0x1d,0x2e,0x9c,0x91,0x9c,0x3f,0x1c,0x1f,0x25,0xbd,0x38,0x15,0x23,0x9b,0x8c,0x94,0xa1,0x27 +,0x1f,0x36,0x3d,0x18,0x14,0x36,0xbc,0x99,0x91,0x9c,0xb5,0x47,0x1e,0x1b,0x30,0x5c,0x2a,0x25,0x7b,0x97,0x8e,0xa9,0x2f,0x37,0x1f,0x1a,0x32,0xc4,0x2c,0x2e,0x9a,0x8f +,0x97,0x2a,0x24,0xac,0x9f,0x3c,0x0e,0x0d,0x1b,0xa0,0x91,0x95,0xa5,0x25,0x2b,0x3d,0x44,0x3b,0x19,0x1a,0xba,0x8f,0x8f,0x9d,0xb7,0x2f,0x22,0x29,0x27,0x16,0x15,0x2d +,0xa7,0x93,0x8f,0xa9,0xc7,0xca,0x2c,0x21,0x1d,0x2b,0x34,0x3f,0xa9,0x90,0x8e,0xc1,0x23,0x47,0xae,0x2d,0x0c,0x0d,0x1f,0x9e,0x8d,0x9f,0x22,0x2f,0x96,0x9c,0xd8,0x1b +,0x12,0x2a,0xd1,0x9c,0x96,0xa5,0x64,0x5f,0xcf,0x3e,0x1e,0x13,0x10,0x1d,0xa6,0x91,0x8f,0xa7,0xdb,0x62,0x53,0xb5,0x2d,0x13,0x1c,0xaf,0x97,0x93,0xa8,0x26,0x36,0xe7 +,0x3d,0x1d,0x13,0x1a,0x2a,0x9f,0x94,0x97,0xb5,0x46,0x9d,0x9d,0x32,0x0d,0x0f,0x28,0xbc,0x9b,0x9a,0xbb,0x2e,0xcc,0x9f,0x9f,0x2f,0x0f,0x14,0x67,0x9e,0xab,0xb7,0xc1 +,0xaa,0xbd,0x37,0x3a,0x29,0x26,0x20,0xd4,0x94,0x8e,0xa1,0x2f,0x35,0x40,0xbd,0x23,0x0a,0x0a,0x27,0x97,0x8e,0x97,0xf0,0xc8,0x96,0x9b,0x24,0x0b,0x19,0xb6,0xa3,0xa3 +,0xba,0x32,0x2e,0x9d,0x8f,0x9f,0x14,0x05,0x00,0x2a,0x83,0x84,0x8b,0x2a,0x3c,0x90,0x96,0x35,0x0b,0x06,0x3e,0x86,0x2b,0x04,0x2c,0xa8,0x87,0x88,0xa8,0x1f,0x0b,0x0a +,0x2a,0x88,0x82,0xbd,0x04,0x02,0x8f,0x83,0x26,0x0a,0x00,0x2d,0x8a,0x86,0x93,0x9f,0x91,0x8f,0x8f,0x12,0x00,0x08,0x17,0x8e,0x8b,0x3e,0x0e,0x0e,0x96,0x83,0x89,0xb6 +,0x0f,0x08,0x02,0xac,0x80,0x8b,0x25,0x06,0x53,0x89,0x96,0x17,0x07,0x0d,0xaa,0x88,0xdb,0x06,0xa2,0x84,0x83,0x98,0x09,0x01,0x02,0x5e,0x87,0x8a,0xac,0x1d,0x1f,0x39 +,0x8d,0x85,0xbe,0x1a,0x09,0x0f,0x9b,0x8f,0x1c,0x0f,0x9f,0x81,0x99,0x04,0x00,0x1a,0x88,0x85,0x8c,0xaa,0x2e,0x9f,0x92,0x92,0x8f,0x1b,0x01,0x00,0x09,0x8c,0x86,0xd9 +,0x20,0xae,0x8b,0x8a,0x5f,0x0b,0x25,0xd5,0xa0,0x94,0x0e,0x00,0xa8,0x80,0x85,0xc4,0x05,0x01,0x0f,0xab,0x90,0x8c,0xa2,0xb0,0xa8,0xd5,0x93,0xbb,0x09,0x06,0x14,0xa6 +,0x92,0xc4,0x0b,0xbf,0x87,0x82,0x90,0x06,0x01,0x2e,0x91,0x8e,0x9b,0x0e,0x09,0x9b,0x80,0x92,0x12,0x02,0x0b,0x10,0x1e,0x8b,0x8d,0xa2,0x9c,0x9d,0x92,0x8d,0x1c,0x02 +,0x0f,0xa7,0x93,0xde,0x01,0x09,0x89,0x80,0x8f,0x14,0x0d,0x1f,0x7c,0xad,0xa5,0xaa,0x1c,0x2c,0xa8,0x9b,0x98,0x1c,0x0b,0x15,0x37,0x91,0x8a,0xc7,0x20,0x99,0x8c,0x93 +,0x16,0x00,0x04,0x9c,0x81,0x8d,0x1e,0x08,0x42,0x86,0x81,0x98,0x1e,0x0f,0x17,0x0c,0x2a,0x91,0xc8,0x1d,0xb6,0x92,0x9f,0x1c,0x07,0x0b,0xde,0x94,0x8d,0x96,0x16,0x35 +,0x8a,0x85,0x9c,0x0b,0x04,0x0b,0xa4,0x8e,0xae,0x20,0x2c,0x97,0x93,0xa6,0x3e,0x16,0x31,0x39,0x2f,0xa5,0xb3,0x19,0x20,0x8e,0x8b,0xcc,0x08,0x00,0x0c,0x94,0x85,0x8d +,0xc8,0x28,0xbe,0x8f,0x8d,0x38,0x0e,0x0e,0x35,0x2f,0x24,0xe7,0xb6,0x99,0x8f,0x8f,0x9b,0x32,0x19,0x14,0x26,0xa3,0x9a,0x32,0x08,0x1d,0x8d,0x8b,0x39,0x06,0x0a,0x1f +,0x9b,0x8e,0x9d,0x9f,0x99,0x94,0xaf,0x3a,0x1d,0x0d,0x2d,0xbb,0x3e,0x2c,0x25,0x2d,0xa6,0x8b,0x93,0xbf,0x17,0x05,0x0d,0xab,0x8f,0x99,0x34,0x21,0xa8,0x8b,0x98,0x1c +,0x0e,0x1b,0xf8,0xfc,0x3d,0xb7,0xa5,0x9d,0x9f,0xa6,0xe8,0x15,0x12,0x34,0xa1,0xa0,0xc5,0x20,0x1a,0xbb,0x8e,0x8e,0xb3,0x19,0x13,0x1c,0xf9,0xa8,0x37,0x29,0xad,0x9f +,0x2c,0x0f,0x16,0x3a,0x97,0x8f,0xa1,0xb4,0xae,0xb1,0xa1,0x95,0x9e,0x25,0x09,0x07,0x21,0x98,0x9b,0x5b,0x25,0x25,0x61,0x9b,0x9e,0x2a,0x1e,0x34,0xcf,0xf5,0x2f,0x26 +,0xb9,0x93,0x95,0xbd,0x1d,0x15,0x36,0xa0,0x9a,0x9a,0xa9,0x2b,0x16,0x26,0xa9,0xa6,0x2d,0x15,0x19,0x4d,0xa7,0xb1,0xdf,0xb7,0x9c,0x9b,0xde,0x1e,0x20,0x4a,0xa1,0x97 +,0xbb,0x1d,0x1b,0x2d,0xaf,0x9b,0xb0,0x1e,0x0f,0x0e,0x37,0x90,0x8c,0x9a,0xbc,0x38,0xca,0xa3,0x47,0x18,0x21,0xc6,0xb7,0x27,0x14,0x1e,0xb5,0x95,0x97,0xb0,0x3e,0x23 +,0x2b,0xb0,0x9e,0xa1,0xcd,0x23,0x1d,0x49,0xa6,0xa7,0xd5,0x26,0x21,0xd2,0xa9,0xac,0xab,0xbb,0xc3,0x67,0x17,0x0c,0x18,0x65,0x99,0x96,0xd7,0x2c,0xdf,0xa7,0x9d,0x9e +,0xae,0x70,0x20,0x14,0x22,0xd0,0xc1,0xde,0x3c,0x3b,0xc4,0xb9,0xe6,0x30,0x35,0xad,0xa0,0xb8,0xec,0xec,0xad,0x9e,0xb6,0x2b,0x22,0x22,0x2f,0xc6,0xbb,0xb2,0xc1,0x21 +,0x19,0x2d,0xae,0x97,0x9a,0x48,0x25,0x36,0x4c,0xdd,0xb3,0xa7,0xa2,0xca,0x1a,0x14,0x28,0xad,0x9b,0xa0,0xbf,0x38,0x36,0x47,0x76,0x5a,0x3f,0x2c,0x1d,0x1d,0x4b,0xa0 +,0x9a,0xa1,0xb7,0xd0,0xba,0xa4,0xa4,0xbf,0x67,0x47,0x1f,0x14,0x14,0x1e,0xbc,0x9e,0xaf,0x3e,0x28,0x2e,0xae,0x9e,0x9b,0x95,0x9f,0x37,0x1e,0x1d,0x22,0xcb,0xa5,0xb9 +,0x3a,0x2d,0x2e,0x3a,0xe0,0xb1,0xaa,0xbe,0x2d,0x1f,0x34,0xab,0xa2,0xba,0x3d,0x46,0xb6,0xad,0xbe,0x7d,0x6a,0x4c,0x2b,0x22,0x2c,0xc4,0xab,0xb4,0xd4,0x49,0x33,0x2b +,0x2f,0x4b,0xaa,0x9d,0xb5,0x29,0x22,0x4c,0xa5,0x9a,0x9f,0xb0,0xda,0x3a,0x32,0x21,0x24,0x3e,0x51,0x2e,0x24,0x2d,0x40,0xc3,0xab,0xa4,0xa5,0xa0,0xa1,0xad,0xb1,0xb6 +,0x58,0x22,0x14,0x18,0x3e,0xb5,0xc5,0x49,0x2a,0x2b,0xbd,0xa4,0xa2,0xaa,0xbe,0x3e,0x39,0x2d,0x28,0x37,0xc7,0xa6,0xa8,0xbf,0x58,0x56,0xce,0xb3,0xaa,0xb2,0x43,0x22 +,0x1c,0x27,0x54,0xdb,0x34,0x2d,0x43,0xb2,0xa5,0xaf,0xb9,0xb3,0xb9,0x61,0x5f,0xbf,0xb1,0xaa,0xaa,0x5d,0x1f,0x1e,0x26,0x37,0xcc,0xbc,0x67,0x28,0x1b,0x28,0xab,0x9a +,0x9c,0xa1,0xb7,0xbd,0xba,0x6b,0x2e,0x3b,0xd5,0x3f,0x29,0x1b,0x1a,0x21,0x53,0xa9,0xa5,0xa5,0xac,0xb6,0xb1,0xa9,0xad,0xc6,0x31,0x25,0x2a,0x2f,0x55,0xb9,0xb6,0xb3 +,0xb5,0xbd,0xe0,0x4b,0x4f,0xe7,0x3e,0x27,0x21,0x1f,0x2d,0xab,0x97,0x9f,0xb5,0xd1,0x56,0xc4,0xb8,0xbe,0xc8,0xc0,0x45,0x2e,0x24,0x1e,0x26,0x36,0x45,0x5f,0x56,0x39 +,0x44,0xbb,0xa1,0x9f,0xae,0xcf,0x3f,0x4f,0xb9,0xb7,0x5b,0x41,0x58,0xce,0xbb,0xd7,0x3f,0x30,0x24,0x21,0x2e,0x57,0xbb,0xb0,0xb3,0xaa,0xa1,0xac,0xbd,0x5b,0x45,0x7c +,0x36,0x24,0x28,0x48,0xb9,0xaf,0xb8,0xd7,0xcd,0xbb,0xb9,0xc6,0x3d,0x22,0x1e,0x29,0x51,0xb8,0xb3,0xbf,0x3e,0x43,0xb8,0xa3,0x9b,0x9e,0xb3,0x7d,0x5a,0x2f,0x28,0x20 +,0x15,0x17,0x2b,0x70,0xcf,0xc6,0xb5,0x9f,0x98,0x9c,0x9f,0xb0,0x4d,0x3e,0x2e,0x20,0x2a,0x3d,0x4d,0x78,0x61,0xcf,0x75,0x36,0x32,0x4a,0x63,0x58,0xfc,0xff,0xb7,0xa8 +,0xa7,0xb8,0x54,0x6c,0xcd,0xe4,0x4c,0x51,0x45,0x60,0x65,0x4e,0xbf,0xce,0x2e,0x2e,0x4c,0x58,0x43,0x30,0x36,0xba,0xa8,0xb2,0xc0,0x54,0x3e,0x5f,0xd3,0xca,0xb0,0xa7 +,0xa4,0xa7,0xc7,0x3b,0x26,0x1e,0x21,0x28,0x2a,0x2b,0x2e,0x37,0xc0,0xa0,0x97,0x96,0xa1,0xb5,0xc5,0x40,0x2c,0x2a,0x29,0x35,0x4d,0x45,0x48,0x35,0x2a,0x68,0xb0,0xb3 +,0xc6,0x3a,0x36,0xb1,0xa5,0xb5,0xe0,0x2e,0x2a,0x47,0xcc,0xcf,0xc2,0xc7,0xbd,0xad,0xb5,0xc9,0x3e,0x2d,0x2b,0x2e,0x39,0x2f,0x23,0x29,0xbc,0x9d,0x97,0x9c,0xbf,0x39 +,0x3b,0x47,0xc3,0xb1,0xcf,0xf7,0xd8,0x64,0x4f,0x31,0x28,0x37,0x40,0x2f,0x22,0x1d,0x2c,0xab,0x97,0x97,0x9c,0xac,0xb8,0xb7,0xbf,0x47,0x2f,0x24,0x25,0x3c,0x3f,0x3f +,0x3b,0x36,0x32,0x47,0xbd,0xbf,0x66,0xc2,0xa3,0x9f,0xa6,0xce,0x2f,0x2f,0x35,0x38,0x49,0x38,0x26,0x3e,0xa7,0x9d,0x9e,0xaf,0x3c,0x34,0x35,0x2b,0x1f,0x1c,0x22,0x51 +,0xad,0xa8,0xac,0xaa,0xa7,0xac,0xb8,0x53,0x32,0x34,0xd5,0xb5,0xce,0x5c,0x33,0x2b,0x32,0x60,0xcc,0x37,0x21,0x24,0xc2,0x9e,0x9c,0xad,0xca,0xba,0xb3,0xbb,0x4c,0x25 +,0x1e,0x4f,0xa4,0xa0,0xb1,0x2a,0x19,0x23,0xfb,0xb2,0xc8,0x2e,0x24,0xd2,0x9e,0x9b,0x9d,0xa8,0xbf,0x40,0x2e,0x1c,0x18,0x25,0xcd,0xa9,0xa8,0xb0,0xfc,0xdb,0xaf,0xaa +,0xb9,0x2e,0x17,0x15,0x29,0xcb,0xa4,0xa1,0xbb,0xf2,0xb8,0xa8,0xaf,0x44,0x2d,0x7b,0xab,0xb1,0x3f,0x23,0x22,0x3a,0xca,0xd2,0x2a,0x19,0x1f,0xaf,0x97,0x98,0xa0,0xc4 +,0x58,0xbc,0xb8,0x45,0x24,0x1b,0x1f,0xdc,0xa0,0x9f,0xc2,0x3c,0x41,0xc1,0xb3,0x39,0x1f,0x24,0x41,0xfb,0xd7,0xc8,0xb2,0x9f,0x9f,0xb5,0x36,0x1f,0x1e,0x4b,0xa5,0xa3 +,0xb4,0x40,0x2c,0xcc,0x9c,0x9d,0x31,0x10,0x10,0x30,0xa8,0xae,0x3c,0x32,0xb9,0x9d,0x9c,0xbf,0x29,0x2c,0xbd,0xa1,0xa2,0xb2,0x31,0x23,0x2b,0xe4,0xbe,0x2b,0x17,0x15 +,0x2c,0xae,0x9f,0xa4,0xaa,0x9f,0x99,0xa0,0x4c,0x1c,0x1a,0x2e,0x6a,0x4b,0x3f,0x49,0xbf,0xa5,0xa7,0x69,0x29,0x28,0x34,0xd9,0xd8,0x31,0x2c,0x5a,0xac,0x9d,0x9d,0xb9 +,0x3e,0x35,0x56,0xc2,0xf1,0x36,0x35,0x4a,0x6c,0x3c,0x20,0x1c,0x34,0xa6,0x98,0x9e,0xcf,0x28,0x21,0x4d,0x9f,0x9a,0xa2,0xc2,0x34,0x27,0x2d,0xfb,0xaf,0xac,0xbb,0x7b +,0x33,0x1d,0x18,0x1c,0x2f,0xcd,0xb5,0xbc,0xb7,0xa6,0x9f,0x9e,0x9f,0xaa,0xc1,0x3f,0x2f,0x29,0x26,0x27,0x2a,0x2f,0x2f,0x35,0xbc,0x9e,0x9a,0xa3,0xfd,0x26,0x21,0x2d +,0x38,0x41,0x54,0xd9,0xc2,0xbe,0xba,0xb3,0xb2,0xc4,0xdc,0xc7,0xb4,0xaf,0x5b,0x20,0x1b,0x20,0x31,0x4b,0xca,0xab,0xa1,0xa2,0xa7,0xb5,0x4c,0x2e,0x37,0xd8,0xb9,0xc4 +,0x3c,0x20,0x1a,0x28,0xb0,0x9c,0xa1,0xca,0x35,0x38,0x48,0x38,0x2a,0x30,0xbf,0xa1,0x9d,0x9f,0xaa,0xd1,0x32,0x2c,0x3a,0x55,0x4f,0x35,0x2a,0x2b,0x32,0x35,0x2e,0x33 +,0xbe,0x9c,0x95,0x9a,0xae,0x36,0x26,0x2a,0x30,0x3c,0x50,0xcc,0xbb,0xc4,0xea,0x6b,0xea,0xcc,0xb6,0xb4,0xd2,0x3a,0x2b,0x20,0x1d,0x2c,0xbf,0xaf,0xb4,0xad,0xa0,0x9f +,0xb4,0x43,0x35,0x44,0x67,0x41,0x37,0x4a,0xcf,0x74,0x2e,0x28,0x39,0xbf,0xaf,0xbb,0xcd,0xbf,0xb7,0xce,0x3e,0x43,0xca,0xc0,0x4a,0x37,0xc9,0xaa,0xb3,0x38,0x25,0x2d +,0xe4,0xb0,0xac,0xad,0xba,0x53,0x2a,0x1c,0x1d,0x38,0xb1,0xa4,0xa5,0xb2,0x45,0x2b,0x2c,0x36,0xcd,0xac,0xa9,0xba,0x48,0x37,0x3e,0xf8,0xeb,0x51,0xcf,0xbb,0xc7,0x50 +,0xed,0xb2,0xad,0xb6,0x49,0x3b,0xc9,0xbd,0x45,0x2b,0x2e,0x5c,0xb6,0xb2,0xc9,0x61,0x45,0x2b,0x1f,0x22,0x36,0x78,0xca,0xb3,0xaa,0xa7,0xac,0xc3,0x43,0x36,0x45,0x5c +,0x50,0x3b,0x43,0xb9,0xaf,0xe9,0x2e,0x2b,0x35,0xdd,0xad,0xa9,0xad,0xba,0x7e,0x36,0x2a,0x34,0xc5,0xab,0xa7,0xab,0xb0,0xbd,0x57,0x43,0x67,0xbc,0xbd,0x4a,0x2c,0x24 +,0x2d,0x33,0x2f,0x37,0xf7,0xb2,0xb5,0xbf,0x57,0x41,0x50,0x41,0x3d,0x3d,0x5f,0xd7,0xd2,0x7d,0x41,0x69,0xbd,0xbb,0xbf,0xb9,0xb2,0xb8,0xea,0x41,0xe5,0xa9,0xa5,0xbb +,0x4d,0x3b,0x46,0x5e,0xf7,0x4b,0x35,0x31,0x26,0x1c,0x1c,0x2b,0xbf,0xa7,0xaa,0xc1,0x5e,0x46,0x34,0x3a,0xc6,0xa6,0x9f,0xa8,0xc2,0x67,0xbf,0xb9,0xc5,0xc4,0xbd,0xb7 +,0xbd,0x59,0x3b,0x38,0x2f,0x26,0x1e,0x21,0x35,0xc6,0xaf,0xb0,0xb2,0xb9,0xdd,0x36,0x2d,0x3f,0xca,0xbc,0x74,0x3d,0x47,0xbd,0xaf,0xb9,0xdf,0xdd,0xaf,0xab,0xaf,0xc4 +,0x7e,0xd3,0xf2,0x2c,0x23,0x41,0xbd,0xbf,0xec,0x40,0x3d,0x45,0x37,0x2f,0x37,0x59,0xec,0x39,0x27,0x28,0xf4,0xad,0xa5,0xa5,0xaa,0xb5,0xcd,0xd4,0x4f,0x46,0x5b,0xee +,0x58,0x46,0xce,0xae,0xaa,0xaf,0xc5,0x3a,0x2f,0x32,0x2f,0x2b,0x3f,0xc0,0x60,0x35,0x33,0xfb,0xaf,0xac,0xb2,0xbb,0xb1,0xb4,0x3f,0x25,0x2a,0x53,0xd5,0x43,0x47,0xc1 +,0xad,0xb8,0xd8,0xcc,0xbc,0xad,0xaa,0xc7,0x2f,0x24,0x20,0x1d,0x1f,0x44,0xaa,0x9e,0xa1,0xb1,0x47,0x37,0x5b,0x5f,0x47,0x4e,0xc6,0xd6,0x39,0x26,0x26,0x64,0xa5,0x9d +,0xa6,0xbf,0xe2,0xe1,0x2f,0x22,0x23,0x2f,0x4e,0xee,0xc1,0xb9,0xae,0xb5,0x7c,0x3e,0xe4,0xae,0xb0,0x5a,0x3b,0x43,0x4e,0x5a,0xe7,0xb4,0xac,0xa6,0xae,0x42,0x33,0x3c +,0x3f,0x2f,0x28,0x2a,0x2d,0x29,0x23,0x2c,0xcf,0xa8,0x9c,0x9b,0xa1,0xa3,0xa7,0xbf,0x32,0x27,0x2d,0x45,0xea,0xe1,0xd7,0xb6,0xaa,0xbf,0x2e,0x2d,0xd9,0xba,0x55,0x29 +,0x23,0x23,0x24,0x27,0x2f,0xd0,0xa4,0x9c,0xa5,0xb2,0xb9,0xbe,0xd4,0x48,0x3c,0x4c,0x66,0x40,0x2f,0x31,0xcc,0xaa,0xab,0xbf,0xcf,0xb8,0xcb,0x33,0x23,0x24,0x35,0x59 +,0x4e,0x42,0x70,0xb9,0xab,0xae,0xb2,0xab,0xa7,0xb8,0x38,0x2a,0x35,0x4e,0x4d,0x48,0xeb,0xb7,0xae,0xc2,0x4a,0x4e,0xcd,0xc7,0x4b,0x2d,0x28,0x29,0x2a,0x2d,0x34,0xf6 +,0xa7,0x9d,0xa7,0xba,0xb9,0xb4,0xcb,0x3a,0x32,0x48,0xec,0x62,0x3f,0x3d,0x54,0xbd,0xad,0xae,0xb4,0xc4,0x3b,0x23,0x19,0x18,0x25,0x59,0xc9,0xc3,0xb1,0xa2,0x9f,0xaa +,0xad,0xa4,0xa2,0xae,0x4e,0x2a,0x23,0x26,0x29,0x2c,0x39,0x4c,0x69,0x5a,0xed,0xbd,0xb8,0xcd,0x41,0x2b,0x29,0x3c,0x57,0x77,0xc9,0xad,0x9f,0xa2,0xb4,0xba,0xb5,0xac +,0xab,0xcc,0x38,0x2b,0x26,0x24,0x29,0x3c,0xc1,0xab,0xad,0xbf,0xc4,0xbc,0xc9,0x33,0x1c,0x1c,0x2d,0x46,0x53,0xd9,0xbd,0xb3,0xb0,0xae,0xa7,0xa7,0xac,0xba,0x46,0x28 +,0x22,0x2b,0x33,0x3c,0xfa,0xac,0xa0,0xab,0xf8,0x40,0x3d,0x3d,0x34,0x2a,0x28,0x2d,0x3e,0x4b,0x53,0xc3,0xb1,0xab,0x9f,0x9c,0x9e,0xa9,0xcf,0x2d,0x1f,0x22,0x33,0x32 +,0x2e,0x41,0xc4,0xb1,0xb4,0xb2,0xb6,0xd1,0xe8,0x46,0x30,0x32,0x30,0x26,0x27,0x44,0xb2,0xa2,0x9a,0x96,0x9c,0xb6,0x4b,0x3b,0x2c,0x23,0x29,0x2d,0x25,0x23,0x29,0x3c +,0xba,0x9f,0x97,0x9c,0xb3,0x45,0x29,0x24,0x2e,0x3d,0x3a,0x35,0x40,0xd7,0xb1,0xa3,0x9f,0xa7,0xae,0xbb,0xef,0x31,0x26,0x25,0x1f,0x1e,0x35,0xbf,0xb4,0xaf,0xab,0xa6 +,0xad,0xf0,0x31,0x21,0x1e,0x2e,0x4a,0x41,0x3e,0x3f,0xec,0xa9,0x99,0x94,0x97,0xa0,0xaf,0x4e,0x24,0x1e,0x1d,0x1a,0x1b,0x2c,0x5e,0xb9,0xae,0xab,0xa1,0xa1,0xab,0xb7 +,0x4c,0x2d,0x28,0x25,0x27,0x2f,0x49,0xc5,0xa7,0x9a,0x97,0x9c,0xb3,0x37,0x24,0x1e,0x23,0x23,0x1e,0x23,0x38,0x52,0xc6,0xa8,0x9e,0x9c,0x9e,0xa6,0xb4,0x3a,0x21,0x1c +,0x18,0x1a,0x2d,0xb8,0xa2,0x9e,0xa1,0xa7,0xad,0xc2,0xc7,0xd7,0x3f,0x30,0x1f,0x16,0x1b,0x2f,0xc4,0xa5,0x9d,0x9c,0xa2,0xb3,0xcd,0x47,0x2d,0x2d,0x2c,0x24,0x22,0x2b +,0xde,0xaa,0x9f,0x9d,0x9d,0x9e,0xa8,0xc6,0x3c,0x2a,0x1d,0x13,0x11,0x1c,0x3d,0xb3,0x9d,0x95,0x97,0x9a,0xa2,0xbc,0x34,0x21,0x23,0x20,0x1b,0x1e,0x2c,0x43,0xb9,0x9f +,0x97,0x96,0x9d,0xbf,0x3c,0x2c,0x24,0x22,0x1c,0x1b,0x22,0x37,0xb3,0x9d,0x98,0x99,0x9c,0xa3,0xba,0x38,0x27,0x24,0x1d,0x19,0x1b,0x21,0x32,0xca,0xa4,0x9b,0x9a,0x9e +,0xb4,0x45,0x2f,0x2f,0x3a,0x31,0x27,0x29,0x37,0xc2,0xa2,0x9a,0x9a,0x9d,0xad,0x37,0x22,0x1f,0x23,0x1d,0x19,0x1e,0x32,0xd4,0xa5,0x96,0x90,0x8f,0x95,0xa5,0x4a,0x1e +,0x17,0x18,0x18,0x1d,0x27,0x36,0xc6,0xaa,0x9e,0x98,0x97,0x9e,0xb8,0x3c,0x26,0x1e,0x18,0x18,0x1e,0x2e,0xc7,0xa1,0x99,0x9b,0xa2,0xa7,0xbc,0x3b,0x32,0x2f,0x24,0x1a +,0x1a,0x24,0x3e,0xb4,0x9f,0x9a,0x98,0x98,0xa1,0xd5,0x2d,0x20,0x1e,0x1d,0x1a,0x1b,0x20,0x37,0xb4,0x9d,0x96,0x94,0x9b,0xb0,0x56,0x43,0x4d,0x2f,0x1c,0x1a,0x1f,0x3d +,0xa8,0x9c,0x9a,0x9b,0xa0,0xae,0x4a,0x29,0x20,0x1b,0x16,0x15,0x19,0x22,0x6a,0xa1,0x92,0x8d,0x8d,0x96,0xb4,0x2f,0x26,0x2a,0x27,0x1b,0x17,0x1a,0x27,0xd4,0xa6,0x9c +,0x9b,0x9d,0xa6,0xbb,0x4c,0x2d,0x20,0x1a,0x1a,0x1f,0x2a,0xd3,0xa5,0x9d,0x99,0x99,0xa2,0xd3,0x37,0x37,0x41,0x36,0x25,0x1b,0x18,0x1e,0xe9,0x9f,0x96,0x90,0x94,0xa7 +,0x36,0x1f,0x21,0x23,0x1c,0x19,0x1a,0x1e,0x3f,0xa8,0x97,0x8e,0x8c,0x92,0xa6,0xdb,0x3f,0x2c,0x1d,0x18,0x18,0x1c,0x2b,0x6e,0xb4,0x9f,0x99,0x9b,0xab,0x59,0x2d,0x2a +,0x29,0x21,0x1a,0x17,0x1f,0xe3,0x9e,0x92,0x8e,0x91,0x9f,0xbc,0x4f,0x41,0x34,0x20,0x19,0x18,0x1a,0x27,0x5c,0xbb,0xab,0x9c,0x99,0xa3,0xcf,0x3a,0x36,0x37,0x2c,0x1e +,0x18,0x1b,0x3b,0xa4,0x93,0x8d,0x90,0x9f,0xf8,0x29,0x22,0x26,0x20,0x16,0x11,0x17,0x2d,0xba,0xa4,0x96,0x8d,0x8f,0x9a,0xaa,0x51,0x2a,0x1f,0x1b,0x16,0x12,0x1a,0x3c +,0xac,0x97,0x8e,0x8e,0x97,0xa8,0xcb,0x3b,0x2f,0x23,0x16,0x0f,0x11,0x1e,0x55,0xad,0x9e,0x98,0x9a,0xa4,0xb6,0xc9,0xc4,0x4f,0x22,0x16,0x13,0x1c,0x40,0xab,0x9a,0x96 +,0x98,0x9e,0xaa,0x51,0x2f,0x47,0x24,0x1d,0x26,0x26,0x1f,0x34,0x52,0xac,0x9e,0xbc,0x7b,0xbf,0xc2,0x55,0xa4,0xae,0xd3,0xb7,0xbd,0x1c,0x11,0x2e,0xa5,0x98,0xc8,0x5e +,0xa0,0xa3,0x4d,0x2e,0x32,0x1e,0x1e,0x5a,0x2f,0x1d,0x28,0x9f,0x8f,0x9f,0xaa,0xa7,0xd8,0x15,0x1d,0xbb,0x3e,0x3d,0x5c,0x38,0xee,0xa2,0x9c,0x9f,0x3e,0x1d,0x60,0xca +,0x22,0x21,0xa7,0xa9,0x57,0xce,0x6b,0x2a,0x24,0x3d,0xc7,0xa6,0x2e,0x29,0xbf,0xa7,0xa5,0x9f,0xa6,0x1b,0x2a,0xad,0x3c,0x20,0x2b,0xcd,0x9d,0xa2,0x63,0x3a,0x31,0x2b +,0x4b,0xa4,0xbd,0x2a,0x51,0xa8,0xae,0xb9,0xb2,0xb4,0x23,0x13,0x28,0xa4,0xbd,0x20,0xd8,0xbb,0xaf,0x9a,0x9d,0x27,0x16,0x20,0xbe,0xab,0x20,0x5c,0x9a,0x9f,0xfe,0xc1 +,0x3d,0x17,0xcd,0xa4,0x2d,0x1e,0x37,0xae,0xa4,0xc2,0xe8,0xa9,0xc0,0x1a,0x1f,0xbe,0x30,0x57,0x9a,0xa0,0xa4,0xbe,0x21,0x1c,0x20,0x53,0xaf,0xaf,0x2c,0x1a,0xb7,0x99 +,0x99,0x95,0xa1,0x1c,0x0e,0x1c,0xab,0x95,0xf4,0x36,0x33,0x38,0xd2,0xa9,0xb6,0x19,0x2b,0xbf,0xe2,0x2b,0x2c,0x9c,0x8f,0xa3,0x6d,0x37,0x1a,0x16,0x2f,0xaa,0x2d,0x72 +,0x91,0xa8,0x4c,0xca,0xba,0xaf,0x32,0x17,0x29,0x3d,0x21,0xeb,0x97,0xaf,0xbc,0x9b,0x4d,0x0d,0x12,0xd1,0x9a,0xa6,0x21,0x26,0xac,0x8e,0x96,0xb1,0x2b,0x0c,0x1d,0xb3 +,0xbf,0xbe,0xbf,0xb3,0xb6,0xbc,0xb5,0xab,0x43,0x17,0x23,0x63,0x41,0x43,0xa5,0xa7,0xa7,0x5f,0x3d,0xbd,0x20,0x1f,0xb7,0xa2,0xcc,0xc5,0xbc,0x4a,0x2c,0xf3,0xb9,0x32 +,0x26,0x1e,0x43,0x9f,0xa6,0xa1,0x9f,0x21,0x0f,0x3f,0x9e,0xa7,0x59,0xee,0xdc,0x24,0xe3,0xa4,0x99,0x33,0x15,0x3b,0x36,0x34,0x3f,0xa2,0x9f,0xba,0xba,0xcc,0x1f,0x1f +,0xda,0xad,0x3d,0x26,0x9d,0x9f,0x2d,0xd7,0xac,0xe3,0x3a,0x1f,0x3c,0x48,0x2a,0xce,0x94,0x9b,0x2d,0xb7,0xa7,0x1d,0x12,0x61,0xab,0xaf,0x21,0x19,0x62,0x94,0x8c,0xac +,0x2c,0x0d,0x19,0x9b,0xa1,0x37,0x2f,0xbb,0xa9,0xa0,0xaa,0xc5,0x1f,0x10,0x20,0x49,0x40,0x3d,0x9b,0x93,0xb3,0x4d,0xe9,0xa5,0x34,0x14,0x27,0x24,0x1b,0x43,0x8f,0x8e +,0xb7,0xb2,0xa9,0x1e,0x13,0x20,0x4c,0xac,0x3a,0x70,0xa9,0xb6,0x9d,0x9b,0x3d,0x09,0x16,0x96,0xad,0x1e,0x22,0xbd,0x97,0x91,0xa2,0x3a,0x12,0x16,0xbd,0xa6,0xc9,0x1f +,0xae,0x94,0xa9,0xa6,0xa3,0xc6,0x1b,0x0b,0x16,0x21,0xba,0x93,0x99,0xba,0x22,0xca,0x95,0x55,0x13,0x32,0xce,0xf2,0x1d,0xd3,0x94,0xa0,0xa3,0xb5,0x27,0x09,0x1f,0x98 +,0xa7,0x1f,0x1f,0xab,0x91,0x95,0xe5,0x3d,0x0f,0x0f,0xbc,0x9c,0x39,0x18,0xac,0x9d,0xb3,0xa3,0xb2,0x27,0x16,0x2a,0xa4,0x39,0x2b,0x9e,0x95,0xae,0x29,0xaf,0x92,0x2d +,0x0d,0x1d,0x65,0xb9,0x66,0xa1,0xaf,0x3d,0xac,0xac,0xe3,0x15,0x1b,0xae,0xb1,0x24,0x39,0x9b,0x8f,0xa1,0x1e,0x1c,0x10,0x3d,0x8f,0x9b,0x17,0x0c,0x9f,0x8c,0x9f,0xbe +,0xbd,0x28,0x10,0x19,0xb4,0xaf,0x2b,0xb2,0x9a,0xc4,0x1d,0xb1,0x94,0x1e,0x10,0x3a,0xc1,0xb5,0xaf,0xa6,0x77,0x33,0xbf,0xa5,0xc5,0x10,0x1b,0xac,0xc5,0x2b,0xa7,0x99 +,0xae,0x5b,0xd3,0xb9,0x16,0x1d,0xa6,0x9e,0x1e,0x19,0x95,0x8d,0x9d,0x36,0x25,0x1f,0x21,0x40,0x9f,0xee,0x1c,0xc6,0x9d,0xa3,0x55,0xa6,0xad,0x12,0x0e,0x32,0x9c,0x9e +,0xc8,0xc6,0x29,0x1e,0xaa,0x94,0xcf,0x07,0x12,0x95,0x9b,0x3d,0xa6,0x97,0xf8,0x29,0xe0,0xda,0x17,0x1c,0xa8,0x9d,0x27,0x19,0x9c,0x98,0x57,0x34,0x34,0x1c,0x1c,0xa8 +,0x9f,0x3b,0x29,0xa4,0x93,0xa3,0x3c,0xe4,0x3f,0x14,0x20,0xa6,0x99,0xe1,0x2e,0xae,0xbf,0x42,0xeb,0x9f,0x4f,0x08,0x1f,0x95,0x9d,0x41,0x58,0xb4,0x3f,0xc6,0xae,0x77 +,0x12,0x13,0xb1,0x93,0xbf,0x38,0x93,0xad,0x21,0x28,0xc2,0x36,0x2d,0xa8,0xaf,0x26,0x19,0xa8,0x8f,0xb8,0x14,0x2f,0xb9,0x1e,0x24,0xac,0x9e,0x3f,0x62,0x9b,0x5c,0x28 +,0x3d,0xca,0x29,0x15,0xc0,0x9c,0xa3,0x47,0xca,0xbe,0x43,0xab,0xa1,0xdb,0x10,0x1a,0xa7,0x91,0xad,0x4b,0xb5,0x29,0x21,0x2e,0xa5,0x4a,0x1d,0x3f,0xa8,0x9e,0x41,0xac +,0x9b,0x35,0x11,0x4a,0x9f,0x2d,0x32,0xac,0xad,0x26,0xbd,0xa0,0x5d,0x2c,0x23,0xc4,0x28,0x15,0xae,0x8f,0x9d,0x2a,0x37,0x3a,0x23,0xa4,0x99,0x55,0x0f,0x19,0xa9,0x93 +,0xb2,0x39,0xbf,0x29,0x2d,0x30,0xaf,0x38,0x24,0xb2,0xa1,0xaa,0x2d,0xd9,0xaa,0x58,0x1e,0x5f,0xc2,0x2c,0x72,0xaa,0xa7,0xf6,0xc1,0xaf,0xd9,0x2b,0x1e,0xb4,0x7b,0x1e +,0xaa,0x96,0xa3,0x27,0x77,0x49,0x24,0x3b,0xc2,0xaf,0x27,0x32,0xaa,0x95,0x2c,0x1e,0xa7,0xbf,0x2c,0x33,0xad,0x24,0x32,0xa1,0xa7,0xc7,0x2d,0xc1,0xc5,0x2b,0x23,0xc9 +,0xae,0x2e,0x37,0xa9,0xa9,0x3b,0xab,0xb6,0x1f,0x1b,0x1f,0xa2,0xaa,0x2b,0x2e,0xc7,0xa4,0xc9,0xad,0xb7,0x26,0x1d,0x54,0x9c,0xa7,0xc9,0xae,0x9b,0x2e,0x29,0xbb,0x44 +,0x26,0x2a,0xab,0x29,0x25,0xbc,0xa2,0xa3,0x44,0x44,0xca,0x22,0x21,0x97,0x9f,0x2c,0x2d,0xb3,0xc7,0x2f,0xa6,0xc8,0x22,0x21,0x2c,0xa5,0xa2,0x36,0x2c,0xb6,0xaa,0xbc +,0xac,0x4c,0x1c,0x26,0x4c,0xfe,0xc1,0xb3,0xaf,0xaa,0x2a,0x20,0x2f,0xc4,0xb7,0x42,0xba,0x2a,0x1f,0xbf,0x99,0x9f,0xe8,0x30,0x32,0x2c,0x35,0xa6,0xae,0x7e,0x34,0xb9 +,0xbc,0x2c,0x4b,0xbb,0xaf,0x41,0x36,0xb1,0xe5,0x34,0xb7,0xb8,0x58,0x33,0xc1,0xc8,0x2b,0x43,0xb7,0xc2,0xc5,0xba,0xb4,0xab,0x1f,0x3c,0xad,0x3a,0x2e,0x2e,0xc9,0x29 +,0x35,0xa6,0xa8,0xb0,0x45,0x1f,0x2d,0xbd,0xbd,0xcc,0xdb,0xb9,0xb8,0xb2,0x4e,0x24,0x60,0xf7,0x3a,0x48,0x2a,0xbe,0xaa,0x37,0x37,0xc3,0xb0,0xd2,0x5f,0x3e,0x24,0x37 +,0x9d,0x9d,0xdf,0xc7,0xbd,0xf3,0x28,0x3f,0xa5,0x54,0x37,0x34,0xba,0x4b,0x36,0xa7,0xb8,0xdf,0x3d,0xfa,0x3e,0x34,0xc8,0xcf,0x2f,0xd3,0xa8,0xaa,0xe5,0x39,0xc6,0x2c +,0x26,0x3c,0xdd,0xbe,0xc6,0x32,0x4a,0xc6,0xb6,0xaa,0xb4,0x3e,0x29,0xfa,0xad,0xa9,0xc9,0x3e,0x20,0x2e,0x38,0xba,0xc0,0x28,0x2c,0x3a,0x9f,0xca,0x4e,0xa4,0xc2,0x46 +,0x68,0x2e,0x55,0xbb,0x40,0x43,0x40,0xc9,0xa7,0xa4,0x5b,0x2a,0xb3,0xa0,0x46,0x2d,0x37,0x56,0x3e,0x36,0x66,0xbb,0xac,0xaf,0x41,0x1b,0x2d,0xaf,0xa1,0x4c,0x3d,0xac +,0xb1,0xda,0x32,0xbe,0x3c,0x27,0xb7,0xd3,0x39,0x45,0x5f,0xdb,0x67,0xc6,0xd7,0xf4,0x36,0x3f,0x65,0x53,0xba,0xbb,0xb2,0xb5,0x56,0x32,0xc6,0xbd,0xbc,0x34,0x1d,0x27 +,0x33,0xcb,0xa5,0xaa,0x3c,0x3a,0x5c,0xb1,0xa5,0xa8,0xf9,0x1f,0x2a,0xac,0xd4,0x66,0xba,0xb3,0x3e,0x25,0x4c,0x6e,0xb5,0x37,0x64,0xb1,0xba,0xc7,0x4f,0x53,0x39,0xcf +,0xcd,0xf6,0x58,0xa9,0xa9,0x41,0x1d,0x20,0xa1,0x9b,0x69,0x1c,0x22,0x44,0xba,0xc2,0x40,0x40,0x49,0xa1,0xa9,0x5a,0xbc,0xe1,0x62,0x34,0x37,0xd3,0xcd,0x43,0x48,0x46 +,0x3d,0xb5,0xbf,0x2d,0x3f,0x59,0x3c,0xb5,0xb2,0xb3,0xc1,0x59,0x2a,0x29,0x5b,0xb3,0xbc,0x3e,0xf0,0xe9,0xb4,0xaa,0x9f,0xb0,0x2d,0x1c,0x5b,0xb0,0x46,0x66,0x4a,0xf8 +,0x2d,0x58,0xd4,0xbb,0x56,0x52,0xba,0xba,0xa4,0x3d,0x25,0x3a,0xdc,0xcc,0xb7,0xb5,0xd8,0x32,0x2e,0x21,0x29,0xa5,0x99,0xbb,0x22,0x1d,0x3d,0x99,0x9b,0xb4,0x2f,0x22 +,0x3c,0xae,0xca,0x52,0xc7,0x3f,0x29,0x19,0xd7,0xaa,0x5b,0x2a,0x40,0xb1,0xa9,0xa1,0x39,0x5f,0xbc,0xbe,0xa2,0xbd,0x20,0x28,0xbf,0x78,0x49,0x47,0x58,0xde,0xf3,0xb7 +,0xae,0x5e,0x39,0xce,0xc0,0x36,0x26,0x4a,0xb5,0xa6,0x9f,0xae,0x29,0x1b,0x28,0xba,0xb1,0xbd,0xb8,0x34,0x49,0xae,0xa6,0x41,0x26,0x1e,0x36,0xa3,0xc1,0x4b,0x2c,0xda +,0xcf,0xaa,0x9d,0xaf,0x29,0x1b,0x31,0x32,0xad,0xb0,0x6d,0x3b,0x4a,0xae,0xa1,0x3e,0x17,0xf8,0xa7,0xb8,0x22,0x1b,0xe2,0xa1,0xa1,0xad,0x45,0x3f,0xad,0xc3,0x34,0x40 +,0x2b,0x36,0xa9,0xb8,0xba,0xcf,0x3e,0x23,0x56,0xa7,0xbd,0x3f,0x23,0x3d,0xb9,0x92,0x99,0x33,0x14,0x1b,0xbf,0xa7,0xa1,0x43,0x3a,0x40,0x3d,0x3c,0xe8,0x48,0x2c,0xb6 +,0xae,0x46,0x29,0x33,0xb7,0x92,0x99,0x43,0x38,0x2f,0x29,0xcf,0xbb,0x3b,0x1c,0x21,0xae,0xad,0xc1,0x2d,0x1d,0x23,0x9f,0x9e,0x5f,0x36,0x2b,0xa2,0x99,0x98,0xbe,0x2d +,0x1e,0x1f,0x3c,0x5e,0xbc,0x2d,0x35,0xba,0x99,0x90,0xa9,0x1b,0x1a,0x65,0xcb,0xae,0x2a,0x18,0xc6,0x93,0xa0,0x26,0x27,0x2a,0xb9,0xa1,0x6a,0x28,0x29,0xb4,0x9e,0xb5 +,0x2d,0x22,0x5e,0xaa,0x9e,0xbb,0x2a,0x17,0x10,0xbd,0x8e,0x97,0x3f,0x27,0x19,0x5d,0x9b,0xa9,0xbf,0x1e,0x19,0x59,0x9c,0xc3,0x26,0x1c,0x39,0xa5,0xa2,0xa5,0x29,0x1e +,0xc2,0x9c,0xab,0xb5,0xd5,0x23,0x56,0xa4,0x5d,0x47,0x3c,0x4a,0xa8,0xcb,0x1a,0x14,0xd4,0x99,0x9c,0xd5,0x2e,0x21,0xb9,0x93,0x9b,0x3b,0x0f,0x17,0xbc,0x99,0xaf,0x5c +,0xc1,0x2e,0x19,0xbd,0x9a,0xc0,0x2c,0x1c,0x27,0xae,0x96,0xad,0x17,0x17,0xb4,0x95,0x9b,0xee,0x1f,0x1c,0x70,0xac,0x68,0xbc,0x38,0x2f,0xb5,0x2b,0x21,0xbe,0xa9,0xae +,0xb6,0x32,0x37,0xab,0xa8,0xbb,0x3f,0x38,0x20,0x3d,0x9c,0xa5,0x2e,0x20,0x5a,0x43,0xbc,0xa4,0x3b,0x1f,0x2c,0xc5,0x98,0x96,0xab,0xc8,0x28,0x1e,0x26,0xb7,0xab,0x21 +,0x1c,0x38,0xaf,0x95,0x98,0xb6,0x1b,0x18,0x36,0xbc,0xb2,0x45,0x28,0x5b,0xad,0x3e,0xb5,0xaa,0xc0,0x4e,0x1f,0x19,0x5c,0x92,0x9a,0x20,0x1b,0xc4,0x94,0x96,0x48,0x17 +,0x0d,0x20,0x30,0xce,0x9c,0xa9,0x4f,0xa5,0xbf,0x2a,0xa8,0xa1,0xa4,0x2b,0x18,0x36,0x96,0xa2,0x2d,0x2e,0x28,0x2e,0x3b,0xb2,0x4a,0x21,0x37,0xa3,0x9b,0x9c,0xa1,0x27 +,0x1a,0x3b,0x42,0xba,0xae,0xb4,0x2f,0x1b,0x2d,0xaf,0x94,0xb9,0x1e,0x18,0x25,0xad,0x92,0x96,0x45,0x14,0x1c,0xa8,0xa3,0xae,0x2e,0x1c,0x3c,0xc6,0x2d,0xb4,0x98,0xaf +,0x37,0x33,0x22,0x39,0xae,0xb8,0x2c,0x19,0x36,0x96,0x8f,0xd7,0x24,0x1e,0xc8,0xa9,0xda,0xab,0x3d,0x37,0xb5,0x40,0x24,0xaf,0xa4,0x32,0x21,0x1f,0xec,0x98,0x9c,0xdf +,0x25,0x2b,0xac,0x9d,0x68,0x1d,0x1b,0x7d,0x9e,0xb0,0xdf,0x3a,0x1f,0x22,0xb7,0xab,0xa0,0xa3,0x5e,0x33,0x1f,0x2e,0xbb,0x9c,0xbb,0x12,0x10,0x3e,0x99,0x93,0x9c,0xdb +,0x1b,0x2b,0xb5,0xa3,0xad,0x27,0x20,0x37,0xcd,0x31,0xbb,0xa5,0x68,0x2e,0x33,0x2b,0x68,0x9e,0xba,0x4d,0x71,0x9e,0x9b,0xb9,0x35,0x2d,0x1d,0x1f,0x50,0x33,0x6e,0x5c +,0xb0,0x9e,0x34,0x1f,0xaf,0x9e,0x6b,0x25,0x2d,0xb9,0x90,0x98,0x35,0x1f,0x25,0xd3,0x3a,0x2e,0x20,0x18,0x61,0x8e,0x90,0xbc,0x35,0x1f,0x28,0x59,0xad,0xa7,0x58,0x1e +,0x27,0xfd,0xad,0x9c,0xaa,0x29,0x10,0x27,0xa5,0x9f,0x9e,0x9f,0xc0,0x1d,0x2c,0x4f,0x2f,0x59,0xda,0x3d,0x25,0x2b,0xbd,0x9b,0x8e,0x99,0x37,0x19,0x14,0x55,0xa0,0xaf +,0x2d,0x1e,0x62,0xa4,0xa0,0xd2,0x2c,0x21,0x4f,0xdf,0x37,0x61,0x46,0x4d,0x9d,0x91,0xb9,0x2e,0x1d,0x17,0x1d,0xb8,0x98,0x9c,0xdb,0x1d,0x55,0x9f,0x98,0x48,0x12,0x16 +,0x1e,0xb7,0x9b,0xac,0xb5,0xa2,0xac,0x2e,0x29,0x3a,0x33,0xb2,0xa2,0xfa,0x1d,0x25,0xa4,0x97,0xa4,0x27,0x16,0x18,0x35,0x9f,0x97,0xc0,0x1b,0x25,0xad,0x9c,0xa4,0xcb +,0x23,0x2b,0xc9,0xb7,0x47,0x4c,0x55,0x22,0xb8,0x99,0xae,0x1a,0x14,0x35,0xb4,0x9a,0x9e,0xe0,0x27,0x3c,0x9c,0xa5,0x3f,0x1c,0x1a,0x4c,0xbe,0xab,0xac,0x51,0x65,0xaf +,0xd5,0x20,0x28,0x4a,0xb2,0xa7,0xc1,0x25,0x22,0xb7,0x9c,0xa9,0x3f,0x22,0x16,0x45,0x95,0x94,0xb6,0x28,0x19,0x1f,0xa2,0x9a,0xa8,0x25,0x19,0x44,0xb7,0xaf,0x36,0x2d +,0x39,0xbe,0x97,0x9f,0x2a,0x16,0x33,0xa0,0xa2,0xbd,0x26,0x1c,0x41,0x9d,0x94,0xae,0x1d,0x0c,0x1d,0xa4,0xa0,0xcc,0x55,0xb6,0xcb,0x47,0x2b,0x2d,0xb6,0x9b,0x9c,0xc1 +,0x20,0x15,0x1c,0xad,0x8d,0x9a,0x37,0x0f,0x16,0xa6,0x94,0x9c,0x2c,0x17,0x11,0x2e,0x93,0x93,0xa7,0x31,0x39,0xf6,0x33,0x25,0x1c,0x50,0x9b,0x97,0xa3,0x46,0x15,0x12 +,0xaf,0x99,0xae,0x2d,0x1c,0x28,0xbd,0x97,0x9b,0xca,0x41,0x2d,0x2a,0x2d,0x2d,0xd5,0xa8,0x9e,0xa9,0x3b,0x22,0x17,0x54,0x92,0x9b,0x2d,0x11,0x1e,0xb2,0x93,0x97,0x44 +,0x25,0x1a,0x3e,0x99,0x9a,0x2a,0x0e,0x1c,0x61,0x99,0x92,0xa5,0x22,0x1b,0xa9,0xc3,0x1c,0x18,0x2b,0x9b,0x98,0x9f,0xb5,0x36,0x1b,0x27,0x9d,0xae,0x19,0x18,0xb1,0x90 +,0x96,0xa5,0x40,0x12,0x16,0x3c,0xac,0xc6,0x1b,0x3c,0x9a,0x9a,0x3e,0x27,0x44,0x6b,0x9f,0x9f,0x35,0x0d,0x13,0xa7,0x8d,0x8a,0xae,0x15,0x0c,0x17,0xa1,0x98,0xbd,0x17 +,0x1d,0x9e,0xa2,0xb3,0xc5,0xb9,0xd8,0x3b,0xb4,0x3c,0x15,0x14,0xac,0x88,0x8f,0x32,0x1e,0x1e,0x1e,0x46,0xa9,0x41,0x1a,0xc3,0x8f,0x96,0x31,0x2e,0x35,0x27,0x3c,0x3b +,0xf9,0x25,0x36,0x94,0x8b,0x9d,0x14,0x11,0x1f,0x37,0x99,0x9a,0x2f,0x0f,0x24,0x96,0x93,0xa5,0x2c,0x29,0x3a,0x42,0xaf,0xb6,0x25,0x14,0xc2,0x8d,0x99,0x30,0x1e,0x22 +,0x2d,0xb2,0xa6,0x28,0x18,0x3f,0x9a,0x92,0x65,0x31,0xc8,0x53,0x2a,0x32,0xaa,0x1d,0x12,0xa6,0x88,0x95,0x1c,0x28,0x47,0x2e,0x2b,0x33,0xda,0x2c,0xd0,0x8f,0x96,0x2b +,0x13,0x2f,0xb0,0xbd,0xa8,0xbe,0x14,0x0e,0xac,0x8a,0x8d,0xb1,0x1d,0x19,0x26,0x3e,0xcd,0x48,0x24,0x31,0xa1,0x99,0x49,0x45,0xbc,0xc3,0x28,0x25,0xb7,0x25,0x20,0xab +,0x89,0x8f,0x1e,0x1b,0x4c,0x22,0x11,0x3f,0x9c,0x4e,0x2e,0x94,0x8f,0x3a,0x1a,0xc1,0xbb,0x20,0x2c,0x53,0x1e,0x1e,0x94,0x84,0x91,0x1a,0x0c,0x1a,0x25,0x2e,0xaa,0xa6 +,0x2c,0x2a,0x9d,0x8e,0x9e,0x3d,0x1b,0x26,0x3a,0x2f,0x35,0x22,0x2e,0xb2,0x8b,0x8b,0x2c,0x1d,0x3a,0x22,0x13,0x37,0xa5,0xd4,0xea,0x9e,0x91,0xa9,0x21,0x2c,0x2d,0x12 +,0x29,0x9f,0xca,0x1d,0xaf,0x86,0x8e,0x1c,0x17,0x2d,0x15,0x18,0x47,0xac,0xbd,0x67,0x96,0x8a,0xab,0x18,0x18,0x2d,0x2d,0x2d,0x3a,0x2c,0x57,0xae,0x8d,0x8f,0xe7,0x33 +,0x17,0x0e,0x21,0xb0,0xa4,0xb2,0x4b,0xad,0x96,0xa6,0x29,0x2d,0x3a,0x18,0x1b,0xce,0xc5,0x46,0xa1,0x8b,0x93,0x2e,0x1c,0x1c,0x13,0x13,0x3c,0x92,0x99,0x35,0x9b,0x88 +,0x60,0x0a,0x15,0x4a,0x2e,0x2f,0x3f,0x2c,0xcd,0x96,0x85,0x8f,0x23,0x1b,0x11,0x0b,0x16,0xbe,0x96,0x9f,0x47,0xa5,0x95,0xb5,0xcd,0x39,0x18,0x1a,0x3f,0x3e,0x41,0xdf +,0xa5,0x8d,0x92,0x7c,0x1d,0x0f,0x12,0x24,0x2d,0xa0,0xab,0x64,0x8e,0x8b,0x47,0x1d,0x2b,0x38,0x20,0x12,0x27,0xc6,0xd9,0xb4,0x89,0x89,0x3b,0x16,0x19,0x1b,0x14,0x5a +,0x99,0xbc,0x34,0x9d,0x90,0x9f,0xc0,0x2e,0x1d,0x10,0x13,0x3b,0xad,0xba,0xaa,0x94,0x99,0xb4,0xc3,0x19,0x0d,0x1e,0xa0,0x9a,0x2e,0x25,0x99,0x8f,0x4f,0x1f,0x1c,0x3b +,0x42,0x27,0x27,0x49,0xb2,0x9d,0x88,0x92,0x3f,0x1e,0x17,0x1a,0x1a,0x2d,0xb3,0x74,0x36,0xa0,0x8e,0x9b,0x34,0x19,0x28,0x22,0x21,0x9f,0xa0,0x2a,0x47,0x8d,0x8e,0xbf +,0x1a,0x0e,0x0d,0x1a,0xc5,0xad,0xda,0xdb,0x96,0x92,0xa7,0x69,0x43,0x3c,0x1c,0x1f,0x4b,0x34,0xd0,0x9a,0x8d,0xa4,0x22,0x26,0x1d,0x22,0x1f,0x38,0x40,0x58,0xb6,0x95 +,0x8e,0xb3,0x2a,0x2f,0xd0,0x20,0x19,0x2c,0x4e,0x2e,0xb0,0x8e,0x8b,0x97,0x20,0x0c,0x11,0x21,0x2e,0xc2,0x3a,0x44,0x93,0x91,0xa5,0x3d,0x33,0xb9,0x37,0x23,0x1e,0x29 +,0xcf,0x9a,0x8d,0xa8,0x2c,0x34,0xe9,0x31,0x10,0x18,0x3c,0x62,0xbf,0x9c,0x94,0xae,0x4d,0xd0,0xd3,0x2c,0x2a,0x25,0x22,0x4f,0xa1,0x93,0x97,0xcc,0x1b,0x1d,0x2b,0x4e +,0x35,0x3a,0x2a,0x28,0x9a,0x90,0xa1,0x6a,0x2d,0x37,0x42,0x2b,0x1c,0x50,0xaf,0x9f,0x8d,0x98,0xce,0x1b,0x21,0x28,0x15,0x13,0x1e,0xbc,0x99,0x9b,0x3e,0x14,0x9b,0x89 +,0xa2,0x2d,0x33,0x94,0x3f,0x0e,0x19,0xab,0x87,0x8a,0x9d,0x0f,0x00,0x04,0x02,0xad,0x89,0x89,0xad,0x10,0x8a,0x86,0x3e,0x1e,0x9f,0xa1,0x04,0x26,0x90,0xaf,0xd8,0x15 +,0x8e,0x91,0x2c,0x15,0x03,0x1e,0xa9,0x9c,0x0d,0x0a,0x9a,0x8b,0x82,0x8d,0xc1,0x0d,0x00,0xe0,0x8d,0x9c,0xb2,0xac,0x98,0xb6,0xa4,0x21,0x0b,0x1a,0x08,0x3a,0xac,0x98 +,0xaf,0x08,0xa2,0x81,0x8d,0x0f,0x0e,0x8f,0x91,0xf9,0x0e,0x25,0x95,0x39,0x96,0x8d,0xa2,0x1d,0x02,0x00,0x09,0x8b,0x87,0x48,0xd1,0x92,0x82,0x39,0x0a,0x57,0x9f,0x97 +,0x96,0x4a,0x07,0x05,0xa8,0x83,0x89,0x3d,0x0d,0x06,0x06,0xb0,0xa5,0xac,0x8d,0xa4,0x25,0x4b,0x8c,0x91,0x26,0x0e,0x21,0xad,0x1e,0x29,0x9c,0x90,0x86,0x97,0x0f,0x02 +,0x05,0x13,0xb8,0x8d,0x8f,0xd7,0x06,0x1a,0x81,0x85,0xa7,0x39,0xa7,0x32,0x09,0x0d,0x24,0xa1,0x90,0x8f,0x8f,0x1d,0x03,0x02,0x0e,0x92,0x89,0x95,0x1d,0x1b,0x8d,0x83 +,0x9d,0x1d,0xbd,0x14,0x07,0x3c,0xb1,0xba,0xc5,0xfd,0xae,0xa7,0x9d,0x27,0x0f,0x14,0x37,0xa5,0x29,0x31,0xe6,0x90,0x81,0x88,0x29,0x01,0x05,0xad,0x8f,0xfd,0x1a,0x6f +,0x95,0x96,0x97,0x32,0x1e,0x22,0x1f,0x15,0x20,0x98,0xdf,0x14,0xb8,0x89,0x89,0xb8,0x16,0x20,0xba,0xb9,0x19,0x1c,0x21,0xbb,0x89,0x87,0x9c,0x0d,0x03,0x01,0x16,0x89 +,0x8a,0xb5,0xc4,0x9e,0xa1,0xbf,0xaa,0xcb,0xde,0xae,0x42,0x19,0x07,0x0b,0x9f,0x86,0x87,0xa0,0x0c,0x01,0x0f,0x95,0x90,0xab,0xb8,0xc1,0x56,0xaf,0x8c,0x99,0x1e,0x10 +,0x1d,0x1e,0x26,0xb5,0xc7,0x9a,0x94,0xa8,0x34,0x0d,0x09,0x1d,0x93,0x83,0x98,0x0e,0x00,0x23,0x86,0x80,0x9b,0x0c,0x15,0x1a,0x1b,0x48,0xb0,0x99,0x89,0x99,0x21,0x17 +,0x0e,0x0d,0x1a,0x4f,0x96,0x8f,0x31,0x2b,0x9c,0x8a,0x99,0xc9,0x1b,0x07,0x11,0xac,0xa0,0x28,0x26,0xae,0xa0,0x95,0x91,0x20,0x11,0x1e,0x3b,0x32,0x26,0x35,0xb8,0x93 +,0x8c,0x8f,0x1e,0x03,0x0c,0xa6,0x8a,0x8c,0x38,0x14,0xdd,0x97,0x8e,0xa3,0x26,0x19,0x16,0x13,0xb9,0x95,0x3f,0x1e,0x71,0xb4,0xd6,0x2a,0x25,0x2f,0xc6,0xde,0x2b,0x2b +,0x31,0x9e,0x8f,0x8e,0xa3,0x17,0x07,0x02,0x26,0x86,0x8c,0x30,0x2c,0x9d,0x97,0x9c,0xb7,0x5d,0xa9,0xa1,0x3a,0x0e,0x06,0x0f,0x9e,0x8b,0x92,0xaf,0x1b,0x0d,0x1a,0x6b +,0x9d,0x9c,0xda,0x2c,0x3e,0x98,0x8c,0x9d,0x1d,0x10,0x1b,0x33,0x41,0x23,0x20,0x9f,0x8b,0x9d,0x2b,0x1d,0x2a,0x2c,0xc5,0xa5,0xf6,0x19,0x12,0x47,0x92,0x8c,0xa2,0x2b +,0x27,0x28,0x37,0xe0,0x2d,0x3a,0x97,0x93,0xac,0x4a,0x1b,0x13,0x2a,0xaa,0xa1,0x3f,0x16,0x23,0x9c,0x93,0xbd,0x2b,0x2c,0x2e,0xb3,0x9a,0xa1,0x3f,0x1b,0x1a,0x3e,0x9b +,0x9f,0x3c,0x1c,0x1a,0x2d,0xac,0x9f,0xbd,0x57,0x9d,0x92,0xaf,0x19,0x10,0x26,0xa2,0x99,0xb9,0x28,0x2a,0xad,0x9f,0x54,0x3b,0x5c,0x3a,0x26,0x16,0x26,0xad,0xbf,0x33 +,0xbd,0xa4,0xbb,0x3c,0x37,0xa9,0x90,0x9b,0x29,0x11,0x15,0xb5,0x8d,0x8f,0xbb,0x1d,0x13,0x0f,0x21,0xb1,0x9d,0xa6,0xca,0x48,0x2b,0x2e,0xf4,0xb3,0x9f,0x99,0xa9,0x34 +,0x18,0x15,0x44,0x9a,0x96,0xb4,0x25,0x1f,0x32,0x35,0x38,0xba,0xaa,0xb2,0xc5,0x56,0x36,0xd5,0xb4,0xc1,0x3e,0x1f,0x1f,0x35,0xcc,0xa6,0xa1,0xbc,0xf0,0x6e,0x45,0x6f +,0xad,0xa2,0xbf,0x1f,0x1a,0x38,0xa9,0xab,0x43,0xea,0x9f,0xab,0x28,0x1c,0x2b,0xb0,0x9c,0xab,0x52,0x5f,0x3f,0x23,0x1d,0x23,0x43,0xab,0xac,0xfa,0x59,0xce,0xb5,0xbd +,0x5a,0xd4,0xa7,0xac,0x3a,0x21,0x26,0xe3,0xba,0xd2,0xd6,0xae,0xa1,0xbb,0x1d,0x10,0x1f,0xc0,0xa8,0x9d,0x9d,0xb3,0x35,0x24,0x5e,0xa1,0x9e,0xbd,0x21,0x19,0x2d,0xba +,0xb5,0xb7,0xdb,0x57,0xc8,0x5f,0x2c,0x28,0x39,0xab,0xa1,0x58,0x1d,0x28,0xaf,0x99,0x99,0xdd,0x23,0x1f,0x28,0xdd,0xa3,0x9a,0x9f,0x3c,0x18,0x16,0x23,0x4c,0xd9,0xbb +,0xa0,0xa0,0x4c,0x1d,0x1d,0xb5,0x8b,0x8a,0xaa,0x12,0x0b,0x1a,0xbc,0x9f,0xa4,0xd2,0x3f,0x39,0x2a,0x27,0x5c,0xb2,0xcf,0x5f,0xdc,0xd2,0x7b,0x41,0xdb,0xa2,0x9b,0xb6 +,0x20,0x19,0x39,0x9c,0x9d,0x58,0x23,0x28,0x4f,0xcd,0xb7,0xb6,0x41,0x2c,0x29,0x2e,0x3f,0xb7,0xa3,0xa5,0xa6,0xcb,0x29,0x25,0x2b,0x4c,0xa6,0x9d,0xaf,0x36,0x26,0x37 +,0xb7,0xbe,0x2d,0x1d,0x27,0xd3,0xb6,0xc0,0x42,0x3d,0xb1,0x9b,0x9a,0xa1,0xb6,0x2e,0x1e,0x22,0x38,0xbe,0xad,0xbc,0x56,0x27,0x26,0x3d,0x3a,0x3b,0xb6,0x9e,0xa7,0x39 +,0x22,0x48,0xa4,0x9d,0xa8,0x34,0x22,0x40,0xe7,0x3f,0x5e,0xba,0xc3,0x7e,0x2e,0x26,0x3b,0x4f,0x4c,0x39,0x45,0xcf,0xd5,0xc7,0xa9,0x98,0x9a,0xba,0x27,0x1b,0x2f,0xbb +,0xae,0xaa,0xca,0x2f,0x2e,0x28,0x29,0xd4,0xb4,0xc3,0x4d,0x2c,0x24,0x37,0xb5,0x9f,0x9a,0x9b,0xa6,0x3b,0x1f,0x23,0x40,0xb9,0xaf,0xcf,0x36,0x3d,0x2f,0x2d,0x4f,0x4b +,0xe5,0xdb,0x3f,0x40,0x4d,0xc5,0xa9,0x9e,0xa8,0x48,0x28,0x3f,0xd1,0x38,0x33,0x75,0xdc,0x54,0xed,0xea,0xad,0xa5,0xec,0x29,0x1f,0x25,0x3e,0xd5,0xdc,0xae,0x9d,0xa4 +,0xb0,0xcc,0x4a,0xf1,0xb6,0xb0,0x61,0x31,0x2f,0x2d,0x2c,0x44,0xbb,0xcd,0x76,0x2f,0x1f,0x3a,0xb9,0xbd,0xb1,0xa1,0x9f,0xa9,0x6c,0x2f,0x35,0x4c,0x4b,0x6a,0x43,0x28 +,0x29,0x31,0xcf,0xfb,0x41,0x3f,0x2f,0x3d,0xbb,0xaf,0xbe,0xac,0xa9,0xa8,0xa2,0xaf,0xca,0x51,0x3e,0x36,0x2e,0x2c,0x2b,0x4b,0xbc,0xb1,0xb8,0x3e,0x25,0x24,0x59,0xb5 +,0xce,0x7e,0xbe,0xb0,0xa7,0xa2,0xae,0xc6,0x4c,0x2b,0x28,0x48,0xdd,0x4c,0x2f,0x2b,0x4c,0xbf,0xbf,0x56,0x3d,0x3a,0x3c,0x39,0x2f,0xba,0x9a,0x92,0x9c,0x34,0x21,0x32 +,0xdd,0xdb,0x48,0x2f,0x35,0x49,0x32,0x40,0xbb,0xb6,0xce,0x3c,0x44,0x46,0x38,0x3b,0xcc,0xa7,0x9e,0xa1,0xb5,0xec,0x3c,0x4a,0x6a,0x37,0x28,0x2c,0x37,0x39,0xcc,0xb9 +,0xbc,0xcf,0x6c,0x34,0x28,0x35,0xe7,0xaa,0x9f,0x9e,0xb1,0x32,0x36,0xb5,0xa7,0xba,0x3c,0x25,0x1f,0x27,0x43,0xb9,0xb7,0x46,0x2d,0x32,0x35,0x31,0x35,0xda,0x9c,0x95 +,0x9e,0xb8,0xed,0xbf,0xcb,0xbf,0xc4,0x3b,0x20,0x1d,0x27,0x39,0xae,0xac,0xe7,0x2e,0x28,0x57,0xb3,0xbf,0x3e,0x51,0xb4,0xa4,0xa5,0xc6,0xcb,0xa6,0xad,0x2b,0x1a,0x1c +,0x32,0xd8,0xbb,0xb8,0xe7,0x38,0x30,0x36,0x44,0xd6,0xc2,0x4e,0x45,0xc4,0xa9,0xa6,0xad,0xad,0xb5,0xc9,0x38,0x28,0x21,0x27,0x67,0xb7,0xb7,0x45,0x34,0x3e,0xde,0xad +,0xac,0x33,0x1c,0x2b,0xb4,0x9d,0x9a,0xa8,0xd6,0x55,0x71,0xd4,0xf6,0x39,0x29,0x2b,0x2d,0x2f,0x36,0x59,0xb0,0xa6,0xb0,0x31,0x20,0x27,0xca,0x9f,0x96,0x9e,0xe1,0x3f +,0xdb,0xc0,0x77,0x43,0x2d,0x26,0x25,0x39,0xbd,0xce,0x45,0x37,0x41,0xb7,0xb4,0x32,0x1e,0x61,0x9c,0x98,0xac,0x3a,0x5e,0xab,0xa0,0xad,0x45,0x1b,0x16,0x22,0x34,0x7b +,0xc3,0xd8,0x3f,0x3e,0xe2,0xc2,0xdb,0x47,0xfd,0xac,0x9f,0xa8,0xce,0xd7,0xaf,0xab,0xbf,0x32,0x1c,0x1b,0x26,0x3f,0xbf,0xcb,0x5b,0x4d,0xbe,0xad,0xb4,0x41,0x24,0x37 +,0xb3,0x9f,0xaa,0x68,0x4f,0xba,0xa1,0xa5,0x41,0x1a,0x1a,0x34,0xbc,0xbc,0x35,0x24,0x2f,0xb9,0x9d,0x9e,0xc5,0x23,0x1e,0x34,0xaf,0xa2,0xa5,0xaf,0xca,0xc9,0xbc,0xcf +,0x2f,0x26,0x24,0x35,0xe9,0x3b,0x2c,0x3c,0xac,0x9e,0xaf,0x29,0x1e,0x41,0xa6,0x9e,0xaf,0x38,0x37,0xb1,0x9b,0x9f,0x50,0x1b,0x15,0x1e,0x48,0xad,0xbe,0x2e,0x24,0x49 +,0x9e,0x9a,0xc6,0x24,0x2e,0xb6,0xa9,0xbd,0x4c,0x58,0xbb,0xa4,0x9f,0xb5,0x29,0x1c,0x21,0x36,0x4c,0x3d,0x2f,0x28,0x32,0xba,0xa4,0xaa,0xbd,0xb8,0xa9,0xa8,0xe8,0x2c +,0x3a,0xb8,0xab,0xcd,0x2b,0x21,0x28,0x30,0xdf,0xac,0xa9,0xb3,0xd8,0x35,0x23,0x24,0x3d,0xbb,0xa2,0x9b,0xa2,0x4b,0x1f,0x2d,0xab,0x9b,0xa5,0x48,0x28,0x26,0x2e,0x33 +,0x28,0x21,0x27,0x5f,0xab,0xa1,0xa5,0xba,0x56,0x54,0xdc,0xc3,0xb1,0xac,0xba,0x56,0x39,0x2c,0x26,0x29,0xda,0x9e,0x98,0xa8,0x2e,0x18,0x16,0x1e,0x42,0xb8,0xb6,0xd3 +,0x52,0xc0,0xa3,0x9c,0x9f,0xb0,0x4f,0x2a,0x2b,0xe7,0xaf,0xc9,0x2a,0x1f,0x23,0x2f,0x7e,0xac,0xa0,0xa7,0xc8,0x34,0x27,0x28,0x39,0xb5,0xa2,0xa2,0xae,0x47,0x26,0x26 +,0xef,0xa8,0xa7,0xbd,0x32,0x29,0x2d,0x32,0x33,0x31,0x3d,0xc7,0xa9,0x9e,0x9e,0xa5,0xc7,0x33,0x24,0x24,0x3d,0xbf,0xb5,0xea,0x2e,0x26,0x26,0x2d,0xfa,0xa0,0x95,0x97 +,0xac,0x29,0x19,0x1c,0x2c,0xe0,0xae,0xa7,0xa8,0xb3,0xef,0x46,0x4b,0x64,0xcd,0xe5,0x3d,0x2e,0x32,0x42,0x31,0x2c,0x4c,0xbb,0xb8,0xb8,0xa9,0xa3,0xad,0x44,0x25,0x2b +,0x5a,0xbc,0xb9,0xb4,0xae,0xbf,0x37,0x27,0x2a,0xee,0xb0,0xb7,0x4c,0x31,0x30,0x2f,0x35,0x41,0xbb,0xa7,0xae,0xff,0x64,0xad,0xa4,0xb0,0x3f,0x28,0x2f,0xda,0xbd,0xc3 +,0xcc,0xd6,0x52,0x2b,0x1e,0x28,0xd1,0xaf,0xac,0xad,0xc4,0x44,0x2e,0x28,0x2f,0xba,0xa2,0xaa,0xc4,0xe5,0xce,0xc1,0xc9,0x64,0x39,0x33,0x33,0x2c,0x36,0xe0,0xbb,0xbc +,0xde,0xd9,0xae,0xa0,0xaa,0xe2,0x30,0x22,0x1f,0x29,0x41,0xde,0xaf,0xa4,0xc3,0x29,0x23,0x35,0xbb,0xa4,0xa2,0xae,0xbc,0x4f,0x22,0x1e,0x3e,0xa5,0x9b,0xa5,0xb4,0xb7 +,0xb9,0x3b,0x23,0x29,0x36,0x66,0x5f,0x40,0x3b,0x3c,0x4b,0x33,0x2d,0x40,0xc0,0xad,0xb6,0x5f,0x33,0x37,0x49,0x57,0xbc,0xa9,0xa4,0xad,0x56,0x40,0xce,0xaa,0xa7,0xba +,0x53,0x2a,0x26,0x26,0x2e,0xd3,0xa3,0x9b,0xb5,0x33,0x2d,0x3a,0x65,0x7e,0x5f,0x37,0x28,0x1d,0x16,0x1d,0x55,0xa1,0x9a,0xa5,0xbc,0x7c,0xd1,0xcc,0xd9,0xc7,0xcf,0xb6 +,0xb6,0xfb,0x3d,0xd6,0xa9,0xbd,0x69,0xc5,0xae,0xae,0xd1,0x3a,0x2c,0x36,0x33,0x28,0x2e,0x5e,0xb7,0xb9,0x67,0x4e,0xd1,0xbc,0x69,0x30,0x29,0x25,0x37,0x5a,0x73,0xb5 +,0xa0,0xa2,0x5d,0x2c,0x3b,0xbc,0xa6,0xa8,0xb0,0xc4,0x45,0x29,0x1d,0x28,0xb8,0x9d,0x9f,0xc8,0x3d,0x2f,0x33,0x37,0x30,0x33,0x3c,0x52,0x2e,0x28,0x3b,0xb7,0xa3,0xa9 +,0xb3,0xb9,0xbb,0xbc,0xc0,0x6f,0x3c,0x4b,0xea,0x38,0x35,0xbf,0xa3,0xa7,0x7c,0x2f,0x31,0x47,0x3f,0x2e,0x2b,0x3b,0xe5,0x48,0x37,0x5e,0xb0,0xac,0xb2,0xbb,0xbb,0xb2 +,0xb4,0xe2,0x3c,0x36,0x39,0x3a,0x35,0x58,0xad,0xa2,0xb6,0x36,0x2b,0x2f,0xd1,0xae,0xc4,0x40,0x37,0x38,0x2b,0x2d,0xd2,0xa7,0x9e,0xa9,0xd6,0x35,0x35,0x71,0xef,0x48 +,0x53,0xbc,0xd4,0x33,0x2f,0x64,0xac,0xa9,0xc4,0x38,0x36,0x44,0x48,0x30,0x26,0x27,0x35,0x36,0x41,0xb5,0xa4,0x9f,0xa8,0xb9,0x46,0x47,0xeb,0x58,0xfe,0xb5,0xaa,0xb0 +,0xc4,0x78,0xd7,0xc6,0xd6,0x57,0x47,0x53,0x64,0x3d,0x23,0x1e,0x27,0x39,0xf1,0xbc,0xb7,0xaf,0xb0,0xd3,0x35,0x3e,0xad,0x9e,0xa1,0xcf,0x2e,0x2a,0x29,0x2e,0x77,0xa4 +,0x9a,0xa5,0x38,0x1a,0x1c,0x2c,0x3b,0x4d,0xd6,0xb8,0xca,0x34,0x24,0x2d,0xb6,0x9d,0x9a,0xa4,0xb8,0x59,0x33,0x2a,0x27,0x3e,0xbc,0xb2,0xb3,0xb7,0xb6,0xc4,0x50,0x3d +,0x3c,0x6b,0xbe,0xd8,0x2b,0x1e,0x29,0x3c,0x5c,0xd1,0xb8,0xa9,0xa6,0xb5,0x42,0x38,0x4d,0xcd,0xd0,0x6d,0xe0,0x5b,0x40,0x39,0x5d,0xad,0xa5,0xab,0x6e,0x31,0x3a,0x4b +,0x3e,0x2c,0x2d,0x43,0xf6,0x5c,0x35,0x38,0xb6,0x9f,0xa5,0xb5,0xbd,0xc4,0xd6,0x42,0x38,0x4c,0xd7,0xbe,0xbe,0xd4,0xca,0xbd,0xc9,0x40,0x37,0x42,0x3b,0x29,0x1d,0x1e +,0x2f,0x5f,0x5b,0x6b,0xb0,0xa2,0xa4,0xac,0xb8,0xbf,0xc0,0x5e,0x3c,0x34,0x37,0x7a,0xca,0xce,0xcf,0xe9,0x76,0xdd,0xf7,0xcf,0xba,0xd2,0x32,0x20,0x1f,0x2f,0xfc,0xb6 +,0xaa,0xa6,0xa6,0xab,0xbd,0x4a,0x3e,0xe9,0xbd,0xc1,0x4d,0x34,0x30,0x3b,0x66,0xd2,0xbc,0xad,0xbb,0x3d,0x31,0x44,0x64,0x32,0x1f,0x22,0x31,0x46,0xcf,0xbd,0xb1,0xa8 +,0xa5,0xa9,0xb3,0xb4,0xb1,0xe4,0x38,0x2e,0x33,0x47,0x54,0x64,0xc7,0xb0,0xac,0xb9,0xe3,0x5f,0x4b,0x31,0x24,0x1f,0x1e,0x24,0x46,0xb3,0xab,0xaf,0xb7,0xc0,0x68,0x65 +,0xb3,0xa4,0xa9,0xdf,0x2e,0x29,0x2d,0x3a,0xdb,0xb3,0xaa,0xa8,0xb4,0x59,0x2d,0x2a,0x30,0x35,0x45,0x5e,0x4a,0x41,0x47,0xe7,0xb8,0xa6,0x9c,0x9e,0xac,0xb9,0xde,0x35 +,0x23,0x1d,0x28,0x3e,0xdd,0xca,0xe6,0xef,0xc4,0xc5,0xcd,0xbd,0xdc,0x2e,0x24,0x2b,0x3b,0x4e,0x4c,0x42,0x48,0xb7,0x9d,0x9a,0xa2,0xae,0xb6,0x4e,0x2b,0x2c,0x38,0x34 +,0x32,0x63,0xc1,0xde,0x56,0x4f,0x55,0xed,0xc6,0xd8,0x30,0x21,0x20,0x29,0x4c,0xaf,0xa5,0xa6,0xa5,0xa2,0xa3,0xab,0xbd,0x5a,0x31,0x2f,0x30,0x29,0x27,0x2a,0x36,0x3e +,0x5e,0xb0,0xa6,0xa6,0xa9,0xb5,0x4d,0x2f,0x29,0x29,0x2f,0x65,0xb4,0xb7,0xd6,0xbb,0xaa,0xa8,0xaa,0xa8,0xad,0x3f,0x1e,0x18,0x1b,0x28,0x48,0xbe,0xba,0xbf,0xbe,0xbb +,0xb2,0xa9,0xa6,0xb9,0x32,0x22,0x1f,0x25,0x2d,0x3e,0xc5,0xa7,0x9e,0xa5,0xb5,0xc1,0xbc,0xc7,0x53,0x39,0x26,0x1a,0x1c,0x2e,0xc6,0xaa,0xa2,0xa0,0xa9,0xb9,0xd1,0x42 +,0x2b,0x2a,0x34,0x3b,0x39,0x31,0x31,0x43,0xb8,0x9d,0x97,0x9d,0xaf,0xd6,0x3f,0x37,0x31,0x27,0x1f,0x1f,0x2a,0x3e,0xcb,0xaa,0x9f,0x9e,0x9f,0xa8,0xba,0x45,0x29,0x22 +,0x21,0x29,0x2f,0x2f,0x51,0xae,0x9f,0x9b,0x9e,0xa7,0xbe,0x30,0x25,0x22,0x1f,0x24,0x3b,0x5a,0x6f,0xd5,0xb6,0xa4,0xa2,0xa6,0xac,0xda,0x2f,0x27,0x25,0x25,0x29,0x29 +,0x2f,0xcf,0xa9,0x9e,0x9e,0xab,0xc0,0x5d,0x33,0x29,0x28,0x2c,0x3c,0xd3,0xc9,0xef,0xe7,0xb7,0xa2,0x9a,0x99,0xa9,0x30,0x19,0x18,0x20,0x30,0x5e,0xcd,0x74,0xdf,0xb7 +,0xa6,0x9e,0x9e,0xa0,0xac,0x5b,0x2b,0x1b,0x14,0x18,0x2b,0x5c,0xed,0xdc,0xbd,0xad,0xa3,0x9e,0x9d,0xaa,0x54,0x29,0x1e,0x1f,0x2d,0x45,0xc8,0xaf,0xac,0xb0,0xc1,0xde +,0x77,0x56,0x4d,0x57,0x3a,0x26,0x23,0x29,0x3c,0xb9,0xa0,0x99,0x99,0x9f,0xbb,0x36,0x25,0x27,0x2f,0x28,0x27,0x2f,0x36,0x35,0x4e,0xb5,0xa8,0xa1,0x9e,0xa0,0xb2,0x38 +,0x23,0x1e,0x1f,0x30,0x5b,0x4d,0x6a,0xb3,0xa0,0x9b,0x9c,0xa6,0xc6,0x3b,0x36,0x38,0x29,0x1f,0x1d,0x1d,0x25,0x6c,0xa6,0x9d,0x9c,0x9b,0x9d,0xae,0x48,0x27,0x1b,0x1c +,0x2e,0x40,0x3d,0x4a,0xce,0xb6,0xa9,0xa3,0xa9,0xc7,0x3c,0x3d,0x42,0x2f,0x29,0x2b,0x28,0x36,0xb1,0x9f,0x9c,0x9e,0xa7,0xca,0x2c,0x21,0x25,0x28,0x29,0x34,0x40,0x36 +,0x3a,0x79,0xb2,0x9b,0x93,0x95,0xa4,0x4e,0x24,0x18,0x16,0x20,0x33,0x35,0x3b,0x4f,0xc8,0xa5,0x98,0x95,0x9c,0xab,0xd4,0x2e,0x1b,0x18,0x1f,0x27,0x32,0xd8,0xbb,0xb1 +,0xa9,0xa6,0xa3,0xa4,0xa6,0xbb,0x29,0x1b,0x1e,0x27,0x2b,0x42,0xc5,0xb0,0xa4,0x9f,0xa3,0xb4,0xec,0x40,0x2c,0x27,0x29,0x27,0x1f,0x21,0x32,0xbb,0x9c,0x94,0x99,0xac +,0xca,0xef,0x3c,0x29,0x24,0x2a,0x27,0x24,0x2f,0x42,0xe5,0xa8,0x9a,0x99,0x9e,0xac,0x4e,0x20,0x1a,0x1e,0x26,0x27,0x2c,0x3e,0xda,0xa1,0x92,0x92,0x98,0xa2,0xaf,0xe4 +,0x2e,0x22,0x1d,0x19,0x1a,0x1f,0x2a,0xec,0xa7,0xa4,0xa7,0xa1,0x9e,0xa6,0x5d,0x28,0x25,0x23,0x23,0x2c,0x37,0xd8,0xa4,0x9b,0x9f,0xaf,0xc0,0xde,0x3f,0x3e,0x48,0x2d +,0x1f,0x1d,0x1e,0x2a,0xb4,0x97,0x94,0x9e,0xad,0xc5,0x36,0x23,0x25,0x2e,0x2c,0x25,0x22,0x29,0x50,0xa4,0x97,0x98,0x9b,0x9e,0xaf,0x3f,0x27,0x1f,0x1f,0x20,0x22,0x23 +,0x21,0x53,0xad,0xaf,0x9f,0x95,0x9e,0xb9,0xcd,0x3c,0x46,0x27,0x1e,0x2a,0x61,0x3f,0xcb,0xab,0xce,0xa1,0x94,0xa7,0x1e,0x1c,0x30,0xd6,0x5b,0x28,0xce,0xa4,0xb4,0x3d +,0x4b,0x40,0x2c,0xaf,0xad,0x3c,0x22,0x34,0xb0,0xb4,0xbd,0xb8,0xb0,0x21,0x13,0x3c,0xaa,0xae,0x9f,0xad,0x30,0xdd,0xa9,0xae,0x37,0x15,0x22,0xcc,0x46,0x24,0xdf,0xa0 +,0xb6,0xa3,0xa5,0x4b,0x1d,0x1e,0x3b,0xb4,0xaf,0x39,0xe1,0xb4,0xa3,0xa8,0xab,0x22,0x18,0xa2,0xa9,0x22,0x1f,0xd5,0xa1,0x9f,0xdd,0x2e,0x2c,0x2b,0x3b,0xae,0xae,0x2c +,0x48,0x9e,0xa8,0xc5,0xb0,0xad,0x31,0x13,0x1e,0xbb,0x9e,0x34,0x28,0xd3,0xbb,0x9c,0x97,0x48,0x0d,0x19,0xd5,0x9e,0x3f,0x30,0x9f,0x9c,0xb3,0x4f,0xca,0x19,0x1f,0x9e +,0xab,0x1f,0x23,0xcb,0xa0,0xa5,0x6e,0xcc,0xef,0x1f,0x20,0xc9,0x3d,0x2c,0xa0,0x94,0xa6,0xb9,0x2d,0x1c,0x1c,0x28,0xa7,0xa6,0x38,0x1c,0x6c,0x9b,0xa6,0xa0,0x95,0x56 +,0x0c,0x13,0xc1,0x91,0xb7,0x2c,0x50,0x2c,0xc8,0xac,0xa9,0x21,0x18,0xc1,0xac,0x2c,0x22,0xa6,0x90,0x9d,0x4c,0x64,0x1f,0x15,0x26,0xaf,0x51,0x29,0x9c,0x94,0x51,0x30 +,0xad,0xa9,0x64,0x13,0x23,0xc3,0x2b,0x2f,0xa5,0x9f,0x62,0xbb,0xa4,0x1e,0x0c,0x2d,0xa3,0x9a,0x2f,0x20,0xb7,0x99,0x8f,0x9e,0x69,0x0d,0x0e,0xaf,0x98,0xd8,0x3d,0xbf +,0xc0,0x44,0xbb,0x99,0xb8,0x11,0x18,0xba,0xb2,0x2f,0x42,0x9b,0xa3,0xbc,0x2f,0x38,0x3c,0x20,0xaf,0x9e,0x24,0x2a,0xa9,0xa0,0xad,0x34,0x2c,0x1c,0x1d,0xb7,0x94,0x97 +,0x44,0x19,0x4d,0xae,0x43,0x4b,0xd1,0x2a,0x1d,0x50,0x94,0xa8,0x2f,0xc2,0xaa,0xb2,0x17,0x24,0x6f,0x43,0xb6,0xa1,0x96,0xca,0x19,0x2d,0xb6,0x54,0x34,0xce,0x3f,0x14 +,0x3f,0x90,0x9f,0x2e,0xba,0xac,0xd7,0x1d,0x19,0xc6,0xc6,0x5c,0xa2,0x96,0x1f,0x13,0xa0,0x8e,0x3e,0x14,0x1e,0x29,0xdd,0xa8,0x92,0x9f,0x44,0x1b,0x40,0xa4,0x29,0x2b +,0x37,0x15,0x17,0x9e,0x88,0x9a,0x2b,0xd0,0xa6,0x2b,0x17,0x48,0xbf,0x36,0x45,0x9a,0x99,0x41,0x27,0xad,0xa3,0x18,0x14,0x29,0x2e,0x2f,0x98,0x8a,0x3d,0x0f,0xae,0x93 +,0xf3,0x1d,0x16,0x2e,0xcb,0xd4,0x9e,0xae,0x25,0x6e,0x91,0xa3,0x0c,0x18,0xc8,0x32,0x5d,0x93,0x8b,0xc3,0x1d,0x28,0xbd,0xb9,0x37,0x26,0x1d,0x0e,0x2a,0x8a,0x8b,0xcf +,0x29,0xb6,0xef,0x20,0x2d,0x62,0x3b,0xc8,0xaa,0xa9,0x32,0x2c,0x95,0x8f,0x24,0x0b,0x1c,0xab,0xac,0x4f,0x95,0xa0,0x1f,0x19,0xa8,0xb1,0x17,0xe4,0x41,0x2a,0x2e,0xb2 +,0x93,0xa9,0x1c,0xda,0x9b,0x36,0x16,0x2f,0xb8,0x1a,0xd8,0x8b,0x9a,0x2f,0x2f,0xc5,0x47,0x38,0x67,0x2c,0x18,0x1f,0xa0,0x8c,0xaf,0x18,0xc7,0x9e,0x23,0x1d,0xcc,0xaa +,0x3b,0x7d,0xaa,0x4a,0xc2,0xc7,0xa0,0xd0,0x0d,0x1a,0xac,0xa6,0xcb,0xb7,0x9a,0xaf,0x1c,0x5d,0x9f,0x3e,0x1e,0x35,0x2e,0x17,0xa5,0x88,0x96,0x1d,0x10,0xc6,0xa2,0xf3 +,0x2d,0x30,0x25,0x1e,0xa5,0x8d,0x74,0x19,0x9a,0xa2,0x19,0x20,0x4d,0xf7,0x24,0x3a,0xa4,0xa4,0xbe,0x3d,0xad,0x34,0x10,0x39,0x9d,0xb3,0x3e,0xa6,0xa1,0x43,0x44,0x9b +,0xb3,0x1b,0x12,0x23,0xa9,0x66,0xa5,0x9b,0xab,0x20,0x1e,0xa7,0x9e,0x43,0x1e,0x29,0x15,0x44,0x8f,0x8a,0xd1,0x0e,0x2e,0xaf,0xc8,0x42,0xcb,0xd4,0x2e,0x3d,0x9d,0x9e +,0xe1,0x3c,0xaa,0x1f,0x0c,0xb3,0x95,0x72,0x1b,0x4a,0xbb,0xdc,0xbe,0xa8,0x44,0x1f,0x23,0xfe,0xaa,0x28,0xbf,0x92,0xa0,0x20,0x2c,0xab,0xb9,0x46,0x25,0x1e,0x28,0xaa +,0x98,0x99,0x2f,0x13,0x42,0xa6,0xb3,0x39,0x3a,0x48,0x23,0xfd,0x98,0x9f,0x41,0x23,0x5e,0x2a,0x22,0xa9,0xa4,0x38,0x20,0xae,0x98,0xa1,0x47,0x59,0x42,0x1d,0x3a,0x9f +,0x9d,0x1c,0x2a,0xaf,0xe9,0x3e,0xe2,0xb2,0x2e,0x2d,0x3c,0xc9,0xfa,0xe9,0xa8,0xa4,0x29,0x1b,0xab,0xa7,0x38,0x24,0x38,0x67,0x4b,0x9f,0x9d,0x35,0x23,0x35,0xa8,0x5b +,0x28,0x3c,0xbe,0xb9,0x3e,0xb1,0xa5,0xac,0x2d,0x2f,0x27,0x30,0xad,0xa1,0xaf,0x17,0x29,0xab,0x99,0xa8,0x3b,0x31,0x1b,0x2c,0xaa,0x96,0xb9,0x1f,0x42,0xbe,0x26,0x2c +,0x98,0xaa,0x1b,0x1b,0xea,0xa7,0xa5,0x9b,0xbc,0x25,0x21,0x52,0x9d,0xbc,0x38,0x38,0x29,0x2a,0x51,0xa2,0xa6,0xaa,0x3b,0x1a,0x1a,0x64,0x9d,0x9d,0xba,0x17,0x2b,0xbe +,0x9d,0xa9,0x28,0x29,0x1d,0x5d,0xa3,0x9c,0xda,0x1f,0xef,0xa5,0x3f,0x35,0xad,0xed,0x30,0x2e,0xc7,0xa9,0xb1,0xaa,0x44,0x1e,0x1d,0x4b,0x9a,0x6e,0x31,0x46,0x3f,0x64 +,0xb5,0xa6,0xef,0xd2,0x49,0xba,0x3e,0x5d,0xa5,0x9e,0xbd,0x15,0x42,0xab,0xaa,0x66,0x29,0x25,0x1f,0xb1,0xad,0xda,0x4e,0xd9,0xa9,0xbf,0x2f,0x27,0x4c,0x63,0x49,0x76 +,0xbb,0xbe,0xbf,0xaa,0x28,0x27,0x34,0xcc,0xa4,0x28,0x25,0xc6,0x95,0x9c,0x4a,0x2e,0x20,0x2d,0x6d,0xa6,0xb7,0x28,0x1e,0xb1,0xa1,0x58,0xaa,0x5c,0x29,0x2b,0x47,0xc7 +,0x4d,0xa6,0xb6,0x3b,0x30,0x4f,0xa7,0xb3,0x39,0xbc,0x5c,0x1c,0x50,0xa7,0xa4,0x6a,0xd6,0xb0,0x35,0x6f,0xe3,0x6d,0x4e,0x1f,0x20,0xbf,0x9a,0x9d,0xca,0x20,0x15,0x39 +,0x9f,0x9d,0xc0,0x1c,0x1d,0xba,0x9b,0xa7,0xb2,0x31,0x22,0x26,0x2e,0x4c,0x45,0xb1,0xad,0x49,0x20,0x48,0xa0,0xa2,0xda,0x46,0x38,0x42,0xb4,0xa8,0xb6,0x23,0x2f,0xbe +,0xbe,0x5e,0x2d,0x46,0x52,0x34,0xba,0xb0,0xae,0xd8,0xd6,0xc0,0x20,0x46,0xa6,0xae,0x2f,0x27,0x38,0xa6,0xa2,0xb4,0xa6,0x29,0x18,0x25,0xb2,0xb0,0xc8,0xb0,0xbf,0x4c +,0x49,0x3f,0x66,0xaf,0xd8,0x2e,0x28,0xc5,0xac,0xad,0x45,0x19,0x35,0xa8,0xb6,0x63,0x1c,0x1e,0xb9,0x9f,0x9d,0xb8,0x39,0x2b,0xc2,0xb9,0x32,0x4b,0xac,0xa3,0x2c,0x19 +,0xfb,0xa7,0xa9,0xc2,0x49,0x26,0x25,0xd6,0xad,0xd7,0x27,0xc8,0xb1,0xad,0xc4,0xcb,0xc9,0x28,0x35,0x50,0x2d,0x58,0x9c,0x9f,0xc7,0x23,0xb9,0xa4,0xc4,0x41,0x1e,0x2b +,0xce,0xa6,0xc4,0x54,0x29,0x27,0xc0,0xb6,0x3a,0xcc,0xb5,0xdd,0x4e,0x2c,0xc0,0xaf,0xad,0xb6,0x2f,0x17,0x2d,0xaf,0x9e,0xbc,0x18,0x3d,0xa9,0xa9,0xaf,0x44,0x20,0x3b +,0xb9,0xae,0x4e,0x2d,0x4e,0xa6,0xa4,0x36,0xc4,0xaa,0xc7,0x1d,0x14,0x2a,0xcc,0xa8,0xb1,0x44,0xd6,0xb2,0xa7,0xcf,0x28,0x60,0xa6,0xb3,0x53,0x55,0x4e,0xe5,0x30,0x51 +,0x57,0x1d,0x39,0xa3,0xb3,0x36,0x41,0xb2,0x9d,0xa6,0x41,0x26,0x21,0x59,0xa4,0xd0,0x1f,0x21,0x36,0x9f,0x9c,0x4c,0xb7,0xec,0x32,0x6e,0x24,0x29,0xe1,0xce,0x56,0x4b +,0x36,0xac,0x9a,0xab,0x3c,0x28,0x56,0x41,0x45,0xad,0xb0,0x2d,0x30,0xb7,0xb9,0x34,0x2e,0x3d,0xb4,0xbc,0x4e,0xa7,0xac,0xd6,0x28,0x20,0x31,0xbc,0xa5,0xb7,0x1d,0x2a +,0xa4,0xa5,0xb6,0x2b,0xb1,0x9c,0xb9,0x2e,0x27,0x2e,0x3f,0xec,0x38,0x3e,0x31,0xb9,0x98,0xb5,0x2c,0x3a,0xbb,0xb4,0xfe,0x2c,0x28,0x35,0xbc,0x9c,0xb8,0x23,0x1d,0x1d +,0xc4,0x9f,0xe7,0x49,0xc2,0xbd,0xa9,0xb5,0x33,0x3a,0x77,0xba,0xb9,0x34,0x76,0xab,0xb4,0x44,0x53,0xda,0x33,0x1b,0x24,0xa9,0xba,0x3c,0x3c,0xcf,0xcc,0xbb,0xaf,0xb6 +,0xcd,0xbb,0x9b,0xb9,0x2a,0x19,0x18,0xde,0x99,0x9e,0x4b,0x1c,0x1e,0xb6,0x96,0xa0,0x24,0x29,0xb9,0xb3,0x56,0x6d,0x37,0xdd,0x4f,0x2f,0x48,0x39,0x33,0xc0,0xa5,0x49 +,0xb9,0xae,0xc3,0x23,0x23,0xb1,0xa9,0x42,0x2e,0xbd,0x4f,0xf3,0x43,0x4f,0xaf,0xca,0xb8,0xa7,0x3b,0x26,0x4d,0xd1,0x30,0x3b,0xbb,0xc0,0x5d,0xce,0xa2,0xd4,0x25,0x28 +,0xc5,0xc2,0x2d,0x31,0xb5,0x9d,0xaa,0xb7,0x4f,0x27,0x2b,0xc7,0xa5,0xe2,0x78,0xe3,0x3c,0x4b,0x3f,0x54,0x56,0x7b,0x35,0xba,0xdf,0x26,0x3a,0xa1,0x99,0xb8,0xae,0xc9 +,0x2b,0x1a,0x2e,0xc1,0xce,0x3f,0x34,0x3f,0x3d,0xee,0xa2,0xa3,0x29,0x3f,0xaa,0xbc,0x1d,0x19,0x6c,0x94,0x9b,0xae,0xd0,0x2b,0x3a,0x47,0x41,0x2c,0x3d,0x43,0xb7,0xe9 +,0x3f,0xcb,0xbd,0x4f,0x2f,0xa5,0xbe,0x29,0x2a,0xa8,0x9b,0xa0,0xc8,0x1d,0x1e,0x24,0xb9,0x9f,0xb8,0x1f,0x24,0xba,0xa5,0xa9,0xac,0xbe,0x34,0x56,0xaa,0xba,0x1c,0x14 +,0x2c,0x9b,0x96,0xce,0x24,0x21,0x1f,0xcd,0x99,0xbc,0x29,0x2a,0xb7,0xaa,0xcb,0x4c,0x3c,0x37,0xf9,0xa3,0x3c,0x1a,0x1c,0xa7,0x8f,0x97,0xaa,0x28,0x1f,0x1d,0x2e,0xc4 +,0xb8,0x3d,0x3e,0xad,0xa9,0xa9,0x4d,0x1b,0x1d,0xb2,0xa2,0xb9,0x1c,0x11,0xba,0x89,0x8b,0x4d,0x1f,0x27,0x39,0xa7,0x9d,0x40,0x19,0x17,0x45,0xa5,0xb1,0x40,0xd4,0xc0 +,0x33,0xb2,0xbe,0x2c,0x1f,0xb0,0x95,0x9f,0x36,0x1e,0x2a,0x24,0xbf,0xc8,0x3f,0x2f,0x33,0xc3,0xae,0xe2,0x38,0xbd,0xab,0xa2,0xb9,0x3a,0x18,0x1a,0xa5,0x92,0xa1,0x25 +,0x1a,0x24,0x4f,0x9d,0xa0,0x3d,0x1c,0x26,0xa3,0x9b,0x39,0x12,0x28,0xa0,0x9a,0x9b,0xae,0x21,0x1c,0xb0,0xa2,0xb4,0x29,0x1c,0xca,0xc4,0x2f,0x6a,0x9f,0xad,0x2e,0x47 +,0xbb,0x4c,0x48,0xb3,0xc6,0x68,0xc8,0x56,0x22,0x2f,0xa7,0x9c,0xbe,0x18,0x1d,0x4d,0xb7,0xa8,0xd2,0x34,0x38,0xd9,0x9f,0xd1,0x18,0x1c,0xc9,0x9e,0x9c,0xa7,0x29,0x1e +,0x27,0xb5,0x9d,0x9f,0x2a,0x18,0xd7,0xb6,0xb8,0xb4,0x9d,0xd8,0x1e,0x2a,0x2c,0x2b,0x33,0xc7,0xa7,0xab,0x5f,0xa5,0xa4,0x38,0x27,0x42,0xb6,0x49,0xba,0xa2,0x3e,0x37 +,0xcf,0x55,0x40,0xd0,0xbe,0x27,0x14,0x18,0xaf,0x8e,0x8e,0xab,0x2a,0x25,0xe7,0x98,0xb0,0x18,0x0b,0x1e,0xa4,0xbc,0xd1,0xbf,0xaa,0xab,0x2c,0x2c,0x2d,0x44,0x38,0x47 +,0xa8,0x9b,0xab,0xa3,0xad,0x15,0x1e,0x3f,0xad,0x6f,0x27,0x2b,0x6e,0xad,0xb1,0x98,0x9d,0x42,0x1a,0x1d,0x24,0x32,0x9f,0x92,0xaf,0x26,0x51,0x4f,0x3d,0x9f,0x49,0x1c +,0x1e,0xca,0x90,0xa4,0x30,0x21,0xc7,0xb5,0xaa,0xac,0x2c,0x13,0x17,0xa6,0x9b,0xa2,0xba,0xae,0x31,0x1a,0x22,0x2f,0x9f,0xa4,0x28,0x23,0x76,0xa2,0x9e,0xa9,0x35,0x18 +,0x23,0xbc,0xc2,0x2f,0x6b,0xa4,0x9d,0x39,0x30,0xfa,0xd0,0xbf,0x23,0x6e,0xc4,0xb8,0x99,0xb7,0x14,0x1f,0x9f,0xa9,0xe1,0x24,0x1b,0x23,0xb0,0x95,0xa2,0x6c,0x25,0x6e +,0xde,0x40,0xb1,0xaa,0xa3,0x2f,0x1a,0x36,0xbb,0xc1,0xa5,0x4b,0x19,0x22,0xf3,0x98,0xa3,0x31,0x1c,0x3d,0xa3,0xac,0xaf,0xbd,0x2e,0x24,0x5b,0x9c,0xac,0x2f,0x2c,0x1b +,0x1b,0x2e,0xaf,0x9d,0x9e,0x30,0x32,0xac,0xa0,0xa1,0x4f,0x26,0x1a,0xc1,0xad,0x35,0x26,0xb6,0x97,0xbd,0x1e,0x1f,0x2d,0x36,0xa2,0xad,0xb0,0xb4,0xab,0x97,0x3f,0x0d +,0x14,0xae,0x9e,0xd9,0x2a,0x20,0x3d,0x9a,0x96,0x9a,0xc8,0x1c,0x16,0x1f,0xd6,0xa3,0xa5,0xa8,0xba,0x19,0x28,0xc5,0x51,0x2f,0x2f,0xeb,0x44,0xb0,0xa1,0xa6,0xc6,0xe2 +,0xb9,0x64,0x19,0x1e,0xb2,0xb3,0xba,0xdb,0xac,0xaf,0xb5,0xab,0x23,0x0f,0x1b,0xac,0x9c,0xa8,0x42,0x28,0x75,0x98,0x96,0xcf,0x14,0x0d,0x2b,0x9d,0x9e,0xf6,0x55,0xca +,0xbf,0x6e,0xb9,0x3f,0x1e,0x1b,0x24,0xa1,0x95,0x99,0xa7,0xc3,0x29,0x1d,0x39,0xd3,0x24,0x1c,0x4a,0xab,0x9f,0xb1,0xac,0xa8,0xbb,0x32,0x16,0x19,0x3d,0x9e,0x98,0xc7 +,0x21,0x34,0xa4,0x9e,0xc4,0x3c,0x1e,0x19,0xcf,0x9b,0xba,0x2a,0x34,0xb9,0x9f,0xab,0x48,0x1d,0x1a,0x2f,0xa8,0x98,0xa7,0x3f,0x27,0x3a,0xc9,0xaf,0xb7,0x41,0x23,0x1f +,0x3c,0xa4,0x93,0xa7,0x5a,0x63,0x35,0x1e,0x20,0xdf,0xd8,0xb7,0xa8,0x4b,0x20,0x30,0x9f,0x9d,0x63,0x21,0x20,0xbc,0x9e,0xa4,0x48,0x1c,0x23,0xac,0x97,0xa9,0x20,0x10 +,0x1f,0xaa,0x97,0xa5,0x30,0x22,0x23,0xfd,0x9e,0x98,0xcc,0x21,0x2a,0x50,0xb7,0xae,0xcd,0x25,0x4b,0xa3,0xa7,0x3a,0x1f,0x26,0x27,0xba,0x9f,0xa7,0x5f,0x2c,0xc8,0xaa +,0xb5,0x33,0x33,0xca,0xe5,0x32,0x24,0x30,0xbd,0xa1,0x9b,0xb4,0x21,0x11,0x26,0x93,0x8f,0x54,0x1b,0x1c,0x2a,0xac,0x9a,0x9c,0x6e,0x37,0x3f,0x25,0x2e,0x3f,0x40,0x39 +,0xad,0x99,0x9e,0x42,0x17,0x27,0xc8,0xb5,0x4b,0x4c,0x4f,0x30,0xb5,0xa3,0x9d,0xdd,0x24,0x2d,0x2f,0x36,0x23,0xbe,0x94,0x9a,0xb9,0x2a,0x1a,0x1d,0xb1,0x92,0xa6,0x18 +,0x0e,0x1d,0xac,0x8f,0x91,0xb5,0x1b,0x19,0x53,0xa2,0x6d,0x18,0x32,0x9e,0x97,0x9e,0xb1,0x23,0x0e,0x1f,0x9c,0x97,0x2b,0x16,0x1c,0xd8,0xa0,0x9e,0x92,0xb3,0x1d,0x21 +,0x33,0x28,0x1c,0xd0,0x97,0x93,0x97,0xc2,0x14,0x0e,0x2d,0xa5,0xa9,0x35,0x29,0xcf,0x9f,0x9e,0xae,0xb0,0x2e,0x1c,0x32,0xb8,0x42,0x18,0x41,0x92,0x93,0xc8,0x21,0x1e +,0x21,0x2e,0xa3,0x99,0x1e,0x13,0x44,0x99,0x95,0xa4,0x9d,0x3d,0x13,0x1d,0x33,0x2b,0x2d,0xaa,0x96,0x96,0xbb,0x23,0x1e,0x21,0x3b,0xa2,0x9f,0x29,0x18,0x74,0x9c,0xa6 +,0x76,0xa7,0xc7,0x1f,0x2b,0x2b,0x2d,0x20,0xcf,0x89,0x8a,0x37,0x0f,0x15,0x23,0xbb,0x98,0x9c,0x1b,0x14,0x4e,0xa2,0xa6,0xb3,0xaa,0x3d,0x23,0x2b,0xbb,0xb4,0x1d,0x26 +,0x99,0x91,0xc2,0x2b,0x53,0xd3,0x36,0x56,0xb1,0x1d,0x13,0x2e,0xa1,0x95,0xb1,0xa5,0x9f,0x2a,0x17,0x25,0xe5,0x22,0x2f,0x92,0x95,0x30,0x2b,0xc6,0x59,0x5a,0xae,0x5c +,0x14,0x17,0x30,0xa2,0x98,0xa5,0x98,0xaf,0x1d,0x22,0xd1,0x3f,0x17,0x24,0x97,0x92,0xbe,0x38,0x28,0x4f,0xc9,0x37,0xb7,0x61,0x12,0x14,0xa3,0x8e,0xa0,0x9d,0x99,0x2b +,0x17,0x1d,0x27,0x1a,0x27,0x95,0x8e,0xaf,0x2b,0xf6,0xb9,0x2b,0x21,0xc0,0x29,0x12,0x2a,0x98,0x92,0x9f,0x95,0xb2,0x18,0x1e,0xc2,0x2a,0x0f,0x16,0xa2,0x8c,0x99,0xad +,0x6a,0x48,0x2c,0x2e,0xaa,0x4e,0x0e,0x19,0xa2,0x9a,0x9d,0x96,0xae,0x1a,0x18,0x1d,0x3c,0x33,0x1e,0xa4,0x8d,0x9b,0xdd,0xc9,0xb3,0x24,0x1a,0xbc,0x3d,0x0d,0x15,0xa1 +,0x8c,0x8d,0x9b,0xb7,0x29,0x0f,0x11,0x2f,0x29,0x25,0x9c,0x8d,0xa4,0xaf,0xa1,0xcf,0x18,0x1b,0xa3,0x36,0x0c,0x1f,0xa8,0x9c,0x99,0x93,0x9f,0x2c,0x18,0x17,0x29,0x28 +,0x31,0x94,0x93,0xd8,0x4e,0xa7,0xd0,0x19,0x15,0x3c,0xb4,0x2e,0x1d,0xdd,0x8c,0x8a,0x9f,0xce,0x3c,0x0c,0x0b,0x2b,0x28,0x2a,0x92,0x89,0xa5,0xbe,0xc1,0xba,0x3b,0x17 +,0x22,0x1e,0x0d,0x1d,0x9e,0x8b,0x8d,0x92,0x9b,0x1f,0x0b,0x19,0xbf,0x1e,0x1d,0xac,0xa2,0x9f,0x9a,0xa8,0x2e,0x1a,0x1d,0xb4,0xde,0x19,0x1d,0x9f,0x8b,0x92,0xa2,0x9f +,0x35,0x09,0x0d,0x1e,0x1e,0x3f,0xa4,0x9a,0x9a,0x97,0xa4,0xaf,0x52,0x16,0x2d,0x2b,0x0d,0x0e,0xa6,0x86,0x8b,0x99,0xbf,0x25,0x19,0x19,0x1c,0x1d,0x21,0x42,0xa9,0x90 +,0x93,0x99,0xa5,0x17,0x13,0xae,0xad,0x0e,0x0e,0xc3,0x96,0x91,0x97,0xa6,0x23,0x12,0x31,0x6f,0x1f,0x2e,0xb0,0x95,0x9a,0xad,0xcf,0xcb,0x21,0x14,0x2e,0x1b,0x18,0x28 +,0xa8,0x8d,0x8c,0x91,0xad,0x2c,0x1c,0x1c,0x28,0x29,0x1b,0x1a,0xa9,0x8e,0x9e,0xac,0xb7,0x25,0x43,0xab,0x1e,0x0a,0x18,0x9d,0x8b,0x8c,0x9e,0xac,0x38,0x0f,0x17,0x2d +,0x2b,0x1c,0x3d,0x9f,0xa1,0x96,0x9a,0x41,0x18,0x27,0xa7,0x2f,0x18,0x1d,0xbf,0x8e,0x90,0xa1,0xac,0xc7,0x1a,0x12,0x14,0x14,0x21,0xc9,0x9c,0x93,0x9b,0x99,0xaa,0x2d +,0xdc,0x3b,0x1c,0x0f,0x0f,0x4d,0x8a,0x85,0x9b,0x3e,0x25,0x27,0x48,0x1c,0x0d,0x12,0x3a,0x9f,0x9d,0x97,0x99,0x9a,0xb4,0x34,0x22,0x1c,0x1e,0x13,0xd4,0x92,0x9c,0xa3 +,0xa6,0x31,0x14,0x25,0x51,0x27,0x1e,0x44,0x9e,0x8f,0x9e,0x50,0x5a,0xb1,0xa6,0x3a,0x0f,0x0b,0x21,0xaf,0x91,0x92,0xaa,0xad,0xe8,0x3f,0x30,0x17,0x17,0x22,0x2b,0xbc +,0x91,0x8f,0xbc,0x44,0x45,0xbb,0xb9,0x1d,0x0e,0x12,0xa0,0x8e,0x9d,0xc0,0xbd,0xae,0xbc,0x2d,0x12,0x19,0x29,0x32,0xc5,0xa0,0xa1,0x9a,0xb1,0x2a,0x4e,0xb7,0x69,0x19 +,0x1d,0xbe,0x90,0x90,0xc4,0x1e,0x1e,0xf2,0x2c,0x0e,0x0e,0x21,0x9b,0x8f,0x99,0xb9,0xb3,0x96,0x9a,0xac,0x25,0x0f,0x0f,0x19,0x2b,0xbc,0x93,0x89,0x99,0x11,0x0b,0x27 +,0x5b,0x1d,0x00,0x35,0x80,0x89,0xa0,0x8a,0x84,0xad,0x1a,0x0e,0x10,0x1d,0x21,0x14,0x01,0x0a,0x85,0x81,0x30,0x08,0x10,0x2c,0x9a,0x88,0x90,0xbd,0x9c,0x84,0xab,0x00 +,0x0e,0x89,0x36,0x0d,0xe4,0xa7,0xb8,0xee,0xb4,0xbb,0x97,0x8b,0x29,0x00,0x01,0x95,0x8a,0x29,0xc2,0x8f,0x85,0x83,0x9d,0x11,0x0f,0x55,0x95,0x14,0x00,0x19,0x84,0x94 +,0xd9,0xa7,0x4b,0x2a,0x1d,0x0d,0x0f,0x93,0x83,0x96,0x04,0x16,0x82,0x82,0x57,0x0c,0x12,0x5a,0xdf,0x0f,0x0f,0x37,0x91,0x83,0xb0,0x00,0x1c,0x94,0x1b,0x0f,0x9e,0x8a +,0x92,0xa0,0xaa,0xc4,0xc4,0x96,0x56,0x00,0x0a,0x90,0x95,0x18,0x2c,0x9f,0x8a,0x8b,0x29,0x07,0x08,0x22,0x9e,0x19,0x01,0xa1,0x80,0x8a,0x98,0x8b,0x8c,0x34,0x0d,0x0a +,0x0c,0x30,0xa3,0x2b,0x05,0x1b,0x87,0x8f,0x22,0x0c,0x18,0x97,0x8c,0xb3,0x3c,0xa1,0x8b,0x83,0xcd,0x02,0x1c,0x95,0x2a,0x04,0x0e,0x4b,0xa0,0xba,0x9f,0x9e,0xa3,0x9b +,0x19,0x00,0x11,0x88,0x86,0xa4,0x4c,0x9d,0x8d,0x96,0x2a,0x0e,0x0c,0x5a,0xa1,0x0e,0x00,0x29,0x84,0x8a,0x9a,0x95,0xa2,0x10,0x0e,0x1f,0x1d,0xa9,0x89,0xbe,0x0b,0xac +,0x84,0x8e,0x1c,0x0b,0x1f,0xaa,0xb1,0x1b,0x20,0xe4,0x93,0x98,0x0c,0x02,0x23,0x91,0x94,0xb8,0x9f,0x91,0x97,0xc3,0xb8,0xa6,0x91,0xab,0x08,0x00,0x08,0xb7,0x93,0xb5 +,0xd1,0x90,0x89,0xaa,0x0e,0x09,0x1f,0x8f,0x8e,0x17,0x06,0xba,0x80,0x89,0x47,0x28,0x24,0x16,0x34,0x3b,0x1c,0x38,0x9d,0x3d,0x11,0x4d,0x8f,0x93,0x1c,0x0b,0x28,0x9e +,0x98,0x9a,0x94,0x90,0x88,0x8e,0x11,0x00,0x11,0x9e,0xae,0x22,0x2a,0x2d,0x3e,0x5c,0x20,0x1a,0x48,0x5c,0x1e,0x17,0x31,0x96,0x8b,0x99,0x96,0x8c,0x97,0xca,0x0e,0x0b +,0x21,0xf3,0x1d,0x06,0x0e,0x93,0x80,0x8a,0x47,0x1a,0x1c,0x2e,0xa3,0xab,0xd0,0xac,0x9e,0x25,0x0f,0x1e,0x9c,0x9d,0x1e,0x1a,0x46,0xaf,0x52,0x34,0xab,0x99,0x8d,0x9a +,0x0b,0x01,0x1d,0x95,0xb8,0x31,0xc5,0x9f,0x8a,0x8b,0xb1,0x1b,0x21,0x36,0x22,0x0f,0x19,0xbd,0x9f,0xca,0x47,0x3c,0x2f,0x48,0x3a,0x59,0xb2,0xa4,0x4f,0x17,0x45,0x8b +,0x82,0x8e,0x37,0x12,0x10,0x35,0xc5,0x27,0x17,0x27,0xad,0xbb,0x23,0x22,0x4f,0x4f,0x3e,0xad,0x9a,0x99,0xa2,0xc2,0xb4,0x58,0x3a,0x2b,0x0d,0x11,0xa4,0x92,0xba,0x29 +,0x3b,0xa5,0x91,0x97,0x2e,0x17,0x2a,0x41,0x1b,0x0e,0x29,0x8e,0x86,0x94,0xbb,0x2e,0x1d,0x21,0x2d,0x3c,0xc3,0xb4,0x21,0x0a,0x14,0xa8,0x94,0xae,0x2c,0x26,0xc0,0x8f +,0x93,0xbd,0x4d,0x9c,0x8e,0xa6,0x17,0x12,0x23,0x37,0x28,0x1d,0x25,0xcd,0xab,0xb5,0xb5,0x57,0x3e,0x2e,0x18,0x21,0x9e,0x8f,0x96,0x9c,0xa3,0xbb,0x4d,0x2a,0x1f,0x29 +,0x5b,0xe1,0x24,0x13,0x1e,0xa9,0x97,0xa3,0xd2,0x5e,0x51,0x2e,0x26,0x26,0x2f,0xaf,0xab,0x4e,0xac,0x96,0xa1,0x43,0x29,0x41,0xa1,0x9a,0xb9,0x21,0x1e,0x31,0x34,0x17 +,0x0d,0x21,0xa4,0x9b,0xac,0xc0,0x9e,0x90,0x93,0xa0,0x63,0x30,0xfe,0x26,0x0b,0x0c,0x28,0xaf,0xac,0x4c,0x3b,0xb3,0xa9,0xe2,0x29,0x2f,0xab,0x9f,0x70,0x2d,0xc1,0x95 +,0x91,0xef,0x1a,0x24,0x61,0xab,0xaf,0x2d,0x1f,0x2c,0x2e,0x2a,0x5a,0xac,0xad,0xdc,0x34,0x4b,0xbe,0xb3,0xa9,0xae,0xa5,0x9e,0xc5,0x1e,0x15,0x21,0xb2,0xa4,0xc5,0xc9 +,0xb6,0xcf,0x3e,0x1f,0x14,0x1d,0x4c,0xc9,0xda,0xce,0xb5,0xa5,0x9d,0x94,0x90,0x9e,0x4a,0x20,0x1a,0x24,0x30,0x1f,0x15,0x17,0x48,0x9c,0x9f,0x3f,0x32,0xad,0x9b,0x9b +,0xc0,0x2a,0xd1,0x9b,0x9e,0x35,0x14,0x15,0x22,0x58,0xa7,0x9d,0xa5,0xb8,0x36,0x1f,0x32,0xba,0xba,0x38,0x1d,0x1f,0x65,0xce,0x52,0xa2,0x90,0x8e,0x99,0x31,0x16,0x22 +,0xbf,0xb9,0x29,0x1f,0x34,0xeb,0xba,0xb8,0x3f,0x26,0x29,0x2e,0x4e,0xac,0xb0,0xfd,0x4f,0xcc,0x9e,0x9a,0xb6,0x74,0xb4,0xae,0xd2,0x27,0x16,0x19,0x35,0xc5,0xf6,0x27 +,0x24,0x3a,0xe8,0xaf,0x9b,0x95,0x9d,0x9f,0xad,0xda,0xfa,0x2c,0x1c,0x17,0x1b,0x3d,0xac,0xb0,0xc0,0xb7,0xaf,0xaf,0xd0,0x2e,0x37,0xbe,0xbf,0x29,0x14,0x19,0xbe,0x98 +,0x92,0x99,0xc0,0x4e,0xe2,0x3c,0x2c,0x3c,0x6e,0xe4,0x29,0x19,0x23,0x34,0x42,0x4f,0xbb,0xa2,0x9a,0xa3,0x5f,0xde,0xa4,0x9a,0xb7,0x1c,0x1c,0x32,0xe7,0xef,0x3c,0x35 +,0x79,0xc3,0x3a,0x42,0xc8,0xda,0x38,0x27,0x28,0x65,0xa6,0x9c,0x97,0x98,0xa0,0x4f,0x1d,0x1c,0x30,0xcf,0xda,0x27,0x1e,0x3a,0xde,0x69,0xb6,0xad,0xb0,0xb3,0xd7,0x2c +,0x2b,0x34,0x2e,0x55,0x4a,0xe1,0xb2,0xb0,0xab,0xb2,0xb5,0xab,0xaa,0xb1,0xb0,0x6d,0x25,0x1b,0x11,0x0f,0x1c,0x3d,0xab,0x9d,0x9c,0x9c,0x98,0x9a,0xa2,0xa8,0xcb,0x33 +,0x22,0x17,0x13,0x24,0xb7,0xa7,0x5c,0x2d,0x4e,0xb3,0xa9,0xc6,0x37,0x30,0x4a,0x4c,0xc7,0xa8,0xa8,0xb4,0x3e,0x26,0x25,0x3b,0xc6,0xad,0xaa,0xcb,0x39,0x24,0x1e,0x2e +,0xbe,0xa9,0xc4,0x31,0x47,0xb7,0xa6,0xa2,0xa8,0xb7,0xbd,0x45,0x25,0x2a,0x2c,0x35,0x6f,0xb2,0xa3,0x9f,0xb4,0x63,0x47,0x30,0x2b,0x1d,0x19,0x1f,0x41,0xb8,0x9d,0x9b +,0xa0,0xa1,0xad,0xb1,0xb2,0xcc,0x37,0x2b,0x1f,0x1b,0x21,0x28,0x45,0xba,0xbd,0x4a,0x40,0xc2,0xa4,0x9d,0xa3,0xad,0xbc,0xdc,0x2c,0x19,0x1d,0x38,0x6d,0x64,0xcf,0xab +,0x9c,0x9c,0xb5,0x51,0x3b,0x2b,0x22,0x1a,0x1d,0x40,0xbc,0xce,0xc4,0xb4,0x9f,0x99,0xa3,0xb7,0x5c,0x2f,0x27,0x1f,0x21,0xbb,0x9d,0xa9,0x53,0x2a,0x28,0x2d,0x38,0x57 +,0xba,0xca,0x4b,0x4f,0xce,0xa4,0x9c,0xa7,0xbc,0x4b,0x2f,0x31,0x3f,0xbd,0xb0,0x4a,0x22,0x20,0x1d,0x21,0x7a,0xb8,0xbb,0xc2,0xb3,0xa2,0x98,0x98,0x9b,0xa7,0x3a,0x1c +,0x14,0x14,0x1c,0x39,0xb3,0xa5,0xaf,0xc8,0xc4,0xb0,0xa6,0xad,0xce,0x37,0x1e,0x15,0x1b,0x4f,0x9f,0x99,0xad,0x3a,0x7e,0xb2,0xac,0xb1,0xd8,0x59,0x4e,0x32,0x2d,0x33 +,0x2a,0x30,0x33,0x26,0x2e,0xdf,0xae,0xa0,0x9c,0x9d,0xa6,0xe7,0x2a,0x2a,0x39,0xca,0xce,0x3a,0x42,0xc3,0xb2,0xb3,0xcb,0x46,0x37,0x28,0x24,0x29,0x26,0x27,0xb8,0x99 +,0x95,0x99,0xae,0x5f,0x5a,0x4e,0x49,0x2e,0x1d,0x1d,0x31,0xbf,0xa8,0xa6,0xbf,0x6e,0x4c,0xe6,0xbe,0x52,0x33,0x2e,0x3b,0x56,0xbe,0xbe,0xc3,0xb1,0xb0,0xc1,0x3d,0x3e +,0xb9,0xa8,0xaa,0xb3,0x4f,0x27,0x19,0x17,0x21,0x44,0x42,0x37,0xcf,0xa2,0x96,0x97,0xa9,0xba,0xb1,0xc6,0x38,0x1c,0x13,0x1a,0xe6,0xa9,0xb7,0xdb,0xe1,0xc7,0xcb,0xba +,0xca,0x2e,0x1f,0x21,0x4c,0xa1,0x99,0xa5,0xe0,0x3f,0x59,0xae,0xc1,0x30,0x32,0x57,0xcb,0xc4,0x6d,0x30,0x2e,0x3a,0xfa,0x52,0x36,0x37,0x4f,0xbe,0xac,0xa9,0xac,0xae +,0xbd,0x4a,0x3d,0x2c,0x21,0x3c,0x9f,0x93,0x9d,0x5f,0x1f,0x1f,0x2d,0x59,0x38,0x19,0x11,0x1b,0xad,0x97,0x98,0x9b,0x9d,0xa4,0xa9,0xaa,0x5d,0x26,0x1c,0x1b,0x23,0x7b +,0xb5,0x5e,0x32,0x36,0xd4,0xb2,0x4c,0x2b,0x42,0xac,0xa4,0xb0,0xcf,0x4d,0xd5,0xb7,0xb9,0x3a,0x28,0x37,0xc2,0xad,0xb0,0xcc,0x4b,0x3c,0x2f,0x42,0x4a,0x25,0x19,0x25 +,0xaf,0x9c,0x9e,0xb5,0xbe,0xa6,0x9e,0xa6,0x36,0x19,0x1a,0x42,0xa7,0xb1,0x46,0x2f,0x32,0x3c,0xb8,0xab,0x3a,0x1b,0x1a,0x27,0xc8,0x9e,0x9a,0x9f,0xa8,0xa8,0xa4,0xb0 +,0x2f,0x26,0x3b,0x4a,0x2f,0x2c,0x2b,0x2e,0x3f,0xd9,0x4c,0x2c,0x39,0xb1,0xa1,0xaf,0xd9,0xde,0xaa,0x9d,0xa5,0xc8,0x27,0x1c,0x1f,0x5f,0xab,0xb6,0x5d,0x3c,0x4e,0xc7 +,0xaf,0xca,0x1e,0x11,0x1b,0xdd,0xa7,0xab,0xb5,0xad,0x9f,0x9c,0x9c,0xac,0x3b,0x28,0x2b,0x31,0x2c,0x30,0x37,0x33,0x34,0x5b,0xbc,0xba,0xd4,0x47,0x39,0x3d,0xc1,0xab +,0xb0,0xe7,0x32,0x29,0x3a,0xa9,0x9a,0x9a,0xa7,0x50,0x23,0x19,0x21,0x55,0xb7,0xb6,0xe1,0x33,0x2a,0x3d,0xb4,0xa6,0xa9,0xb2,0xb7,0xc5,0x3c,0x2b,0x28,0x2c,0x61,0xae +,0xad,0xbc,0x7c,0x3c,0x3a,0xd9,0xbe,0xcf,0x51,0x4b,0x58,0x3e,0x35,0x35,0x3f,0x4c,0xeb,0xae,0x9d,0x95,0x9c,0x4e,0x1a,0x15,0x1f,0x37,0x72,0xc9,0xda,0x39,0x2d,0x44 +,0xbe,0xaa,0xa3,0xa6,0xb2,0xbf,0xb7,0xbe,0x3a,0x2e,0x36,0x3f,0x49,0xef,0xc7,0x63,0x49,0x4e,0x4d,0x39,0x2c,0x37,0xc5,0xaa,0xa5,0xaf,0x3b,0x1f,0x2b,0xb6,0x9e,0x9b +,0xaa,0x41,0x24,0x20,0x26,0x2f,0xd9,0xaa,0xa0,0xa7,0xbc,0x45,0x24,0x1f,0x2a,0x40,0xc4,0xae,0xaf,0xd1,0x39,0x34,0x36,0x3f,0xd2,0xa9,0x9b,0x9a,0xa0,0xca,0x20,0x14 +,0x18,0x29,0xcf,0xac,0xb0,0xc9,0x50,0x38,0x3d,0xd2,0xa9,0x9d,0x9f,0xbb,0x2a,0x1c,0x1d,0x26,0x69,0xa9,0xa2,0xac,0xd2,0x4a,0x36,0x2c,0x2c,0x4a,0xaf,0xa7,0xad,0xbb +,0xbd,0xd3,0x35,0x28,0x2b,0x4c,0xb4,0xad,0xbb,0x45,0x2e,0x2a,0x2c,0x4f,0xaa,0x9d,0xa8,0x52,0x2a,0x29,0x39,0x4e,0xd4,0xc2,0xc7,0xb7,0xae,0xb4,0xba,0xb7,0xb8,0xf4 +,0x32,0x27,0x26,0x28,0x26,0x36,0xd6,0xcd,0x53,0x40,0x76,0xaf,0xa0,0xa6,0xbd,0x63,0x4a,0x45,0x60,0xb8,0xac,0xbf,0x3e,0x2a,0x24,0x34,0xca,0xba,0xc9,0x5f,0x59,0xcb +,0xcc,0x4f,0x4d,0x63,0x55,0x5f,0xc9,0xba,0xb0,0xa9,0xc9,0x24,0x1a,0x1e,0x36,0xb2,0x9a,0x95,0x9c,0xb2,0x2a,0x14,0x14,0x2b,0xb2,0xa7,0xa9,0xad,0xc4,0x4e,0x3b,0xff +,0xb3,0xae,0xac,0xc0,0x3b,0x25,0x1f,0x21,0x23,0x2d,0x42,0x4e,0x51,0xfd,0x68,0xe8,0xb6,0xa8,0xa0,0x9f,0xa3,0xb2,0x41,0x29,0x2d,0x4b,0xba,0xa9,0xa4,0xac,0x57,0x29 +,0x1f,0x27,0x53,0xad,0xab,0x7e,0x3a,0x38,0x33,0x33,0x48,0xc9,0xc8,0x4e,0x2f,0x2b,0x3e,0xc3,0xb1,0xba,0x4b,0x3c,0x3e,0x5f,0xbf,0xb1,0xab,0xb0,0xbb,0xdb,0x3e,0x38 +,0xdf,0xb7,0xcf,0xca,0xb3,0xae,0xab,0xa8,0xb4,0xec,0x3e,0x2b,0x23,0x23,0x28,0x2e,0x33,0x32,0x3f,0x7c,0x6e,0x57,0x6a,0xfb,0x6a,0xce,0xcb,0xbd,0xa7,0xa8,0xe3,0x27 +,0x24,0x38,0xd6,0xad,0xa5,0x9e,0xa5,0x6a,0x2d,0x27,0x36,0xcb,0xb1,0xb7,0x50,0x3c,0x3d,0xfa,0xc6,0xd5,0xd3,0xdc,0x3e,0x28,0x27,0x3e,0xb4,0xad,0xca,0x3e,0x3d,0x45 +,0x6f,0xba,0xb6,0xb4,0xb2,0xbe,0x4a,0x3e,0x5c,0xdd,0x54,0x35,0x39,0xfe,0xbd,0xb4,0xaf,0xb5,0xd5,0x38,0x29,0x29,0x35,0x45,0x68,0xbb,0xb4,0xb6,0xb5,0xb9,0xb8,0xb7 +,0xdf,0x35,0x2f,0x2e,0x32,0x61,0xdf,0x39,0x2f,0x37,0x4f,0xbc,0xb6,0xb6,0xb1,0xbf,0x4c,0x3b,0x55,0xba,0xaa,0xae,0x53,0x34,0x36,0xf8,0xb4,0xaf,0xaf,0xb1,0xc0,0x38 +,0x24,0x20,0x29,0x3b,0x3b,0x2a,0x30,0xd6,0xbd,0xbc,0xb9,0xca,0x55,0x46,0x38,0x40,0xc1,0xa9,0xa4,0xaf,0x6d,0x46,0xc7,0xb8,0xb0,0xa9,0xac,0xbc,0xf0,0x3a,0x2b,0x2f +,0x3e,0x3f,0x52,0xc9,0xbc,0xca,0x43,0x30,0x2e,0x2f,0x38,0x4a,0x51,0x50,0xd2,0xe4,0x34,0x2f,0xc9,0xa0,0x9b,0x9f,0xbd,0x36,0x2a,0x2a,0x39,0xd1,0xaa,0xa8,0x4b,0x1f +,0x1a,0x25,0x47,0xb6,0xa5,0xa3,0xa7,0xc2,0x2c,0x1e,0x25,0xce,0xa9,0xab,0xb8,0xbf,0xb2,0xb2,0xd7,0x45,0xe7,0xb9,0xc7,0x52,0x38,0x36,0x39,0x2c,0x2c,0x39,0xce,0xb3 +,0xb7,0xfa,0x45,0x64,0xfe,0xd9,0xdc,0xc9,0xaf,0xb7,0x3e,0x2d,0x43,0xb8,0xad,0xb0,0xbd,0xcf,0x6e,0x39,0x2a,0x2b,0x41,0xdd,0x58,0x3b,0x36,0x5c,0xbd,0xbb,0xca,0xce +,0xbd,0xc3,0x4e,0x30,0x3a,0xbb,0xb5,0xd3,0xda,0xbe,0xaf,0xb4,0xd8,0x7d,0xc3,0xba,0xcb,0x42,0x2d,0x2e,0x3a,0x35,0x2a,0x28,0x3a,0xd8,0xe9,0x3f,0x52,0xb3,0xaf,0xe2 +,0x41,0x5b,0xbf,0xcd,0x6d,0xc8,0xb2,0xac,0xb8,0xc4,0xc5,0xb8,0xaf,0xce,0x35,0x26,0x22,0x2b,0x34,0x3c,0xc5,0xa8,0xa9,0xcf,0x38,0x37,0xdc,0xb7,0xba,0xc4,0xcf,0xc9 +,0x7e,0x3c,0x42,0xcb,0xb4,0xb0,0xbd,0x4f,0x46,0xfd,0x4f,0x31,0x29,0x2d,0x3f,0x2f,0x28,0x36,0xc9,0xad,0xbc,0x44,0x59,0xb5,0xac,0xae,0xc9,0xe0,0xcd,0x5c,0x3f,0x4c +,0xc0,0xad,0xae,0xcc,0x50,0xc5,0xaf,0xcf,0x2e,0x2a,0x39,0x42,0x2f,0x2f,0x58,0xc9,0xc3,0xf9,0x39,0x37,0xdd,0xb0,0xac,0xbd,0x54,0x39,0x2d,0x2b,0x45,0xa8,0x9d,0xa3 +,0xbe,0x41,0x48,0xf1,0x4a,0x38,0x36,0x4c,0xe8,0x41,0x2c,0x2c,0x3b,0xf8,0xb6,0xae,0xad,0xa9,0xaa,0xbd,0x59,0x54,0x6e,0x5e,0x4a,0xee,0xbd,0xd8,0x4e,0x34,0x2e,0xd5 +,0xae,0xc5,0x2e,0x24,0x2c,0x33,0x2e,0x37,0x64,0x5e,0x4a,0xc0,0xab,0xa9,0xa8,0xaf,0x6d,0x31,0x3e,0xc0,0xb9,0xd6,0xbd,0xaf,0xdb,0x40,0x5a,0xbb,0xac,0xb6,0x49,0x26 +,0x1d,0x1f,0x28,0x2e,0x47,0xbe,0xc5,0xdf,0xb8,0xa9,0xa4,0x9f,0xa4,0xc8,0x35,0x35,0x3a,0x39,0x4d,0xcc,0x60,0x36,0x4f,0xc1,0xbc,0xb8,0xbb,0x3b,0x1c,0x1e,0x45,0xc3 +,0xc0,0xb8,0xc4,0x42,0x45,0xbd,0xa9,0xa1,0x9d,0xa2,0x56,0x24,0x29,0x37,0x34,0x34,0x75,0x5b,0x2c,0x28,0x3f,0xae,0xa0,0xa5,0xea,0x22,0x20,0x2d,0x38,0x6b,0xb6,0xb2 +,0xbd,0xba,0xae,0xa7,0xa4,0xaa,0xd9,0x2d,0x2a,0x2e,0x27,0x26,0x3b,0xcb,0xd3,0xea,0xbc,0xaf,0xad,0xa9,0xaf,0x55,0x2c,0x32,0x4d,0x3f,0x33,0x32,0x2f,0x31,0xc1,0x9f +,0x9d,0xa2,0xb1,0x4f,0x2b,0x2b,0x48,0x50,0x38,0x3b,0x3f,0x48,0xc7,0xb3,0xae,0xaa,0xae,0xdd,0x2c,0x27,0x3d,0xee,0x3f,0x30,0x2d,0x38,0xc9,0xaa,0xa4,0xa3,0xa3,0xb8 +,0x31,0x26,0x34,0x45,0x32,0x2d,0x32,0x35,0x44,0xb6,0xa7,0xa4,0x9e,0xa3,0x5e,0x24,0x20,0x30,0x3f,0x2d,0x2c,0x35,0x72,0xb0,0xa0,0x9d,0x9f,0xae,0x35,0x23,0x27,0x39 +,0x5e,0x3f,0x30,0x2a,0x28,0x3a,0xb3,0x9e,0x9a,0x99,0xa2,0x4e,0x23,0x22,0x38,0xdc,0xcc,0x62,0x2f,0x2a,0x3f,0xb6,0xa6,0xa1,0xa5,0xcf,0x2b,0x29,0x3e,0xc9,0xd8,0x4d +,0x3a,0x32,0x48,0xbb,0xb0,0xba,0xb4,0xbd,0x2f,0x1d,0x21,0x3e,0xee,0x55,0x45,0x48,0xc5,0xa8,0xa0,0xa0,0xa1,0xaa,0x5c,0x2a,0x24,0x2b,0x30,0x28,0x20,0x22,0x33,0xaf +,0x9a,0x96,0x98,0x9f,0xcd,0x27,0x23,0x34,0xd8,0xd3,0x43,0x28,0x1e,0x29,0xc9,0xa5,0xa1,0xa2,0xa8,0x66,0x28,0x25,0x2c,0x36,0x3f,0x3e,0x36,0x3e,0xcd,0xaf,0xaa,0xa9 +,0xa6,0xae,0xd5,0xdd,0xc4,0xb6,0xca,0x2e,0x1c,0x1a,0x2c,0xaf,0x9f,0xa3,0xaf,0x56,0x29,0x24,0x2e,0x4b,0xcd,0xe4,0x40,0x32,0x55,0xac,0xa5,0xa4,0x9f,0xa5,0xd1,0x2f +,0x29,0x27,0x27,0x25,0x1b,0x16,0x1d,0xcb,0x98,0x90,0x93,0x9b,0xb3,0x35,0x35,0x67,0xc8,0xc5,0x3c,0x1f,0x18,0x1c,0x36,0xad,0x9c,0x99,0x9e,0xbd,0x3c,0x35,0x2e,0x39 +,0x4e,0x31,0x21,0x24,0x48,0xb6,0xac,0xa7,0xa4,0xad,0xcc,0xcb,0xce,0x6b,0xd1,0x4d,0x28,0x1e,0x24,0x52,0xae,0xa6,0xa3,0xad,0x5e,0x3c,0x42,0x3e,0x48,0x3a,0x21,0x1c +,0x2a,0xb3,0x9c,0x98,0x9c,0xa6,0xc9,0x3a,0x35,0x2f,0x34,0x48,0x2f,0x1c,0x17,0x1e,0x3d,0xaa,0x97,0x93,0x9c,0xb9,0x37,0x2c,0x3d,0xb9,0xc0,0x2b,0x1c,0x1e,0x31,0xba +,0xa0,0x9d,0x9e,0xac,0xca,0x5d,0x38,0x36,0x3d,0x2e,0x22,0x1f,0x25,0x3b,0xb7,0xa4,0xa1,0xa3,0xac,0xba,0xce,0xc9,0xaf,0xc2,0x2b,0x1d,0x1d,0x2f,0xb0,0x9d,0x9f,0xaa +,0xc8,0x3a,0x2b,0x29,0x3f,0x46,0x23,0x1b,0x1d,0x2e,0xb6,0x9b,0x96,0x9a,0xa4,0xba,0xe1,0x50,0xdf,0xc9,0x30,0x18,0x0f,0x12,0x25,0xad,0x95,0x92,0x97,0xa6,0x4d,0x2e +,0x40,0xb9,0xb9,0x37,0x1c,0x16,0x19,0x2a,0xc0,0x9e,0x96,0x99,0xaa,0xbd,0xbd,0xb4,0xbb,0x32,0x1b,0x17,0x1d,0x35,0xba,0xa5,0xa7,0xb4,0xd7,0x5a,0x5f,0xea,0xac,0xdf +,0x2a,0x38,0x69,0x3e,0xb8,0xa9,0xad,0xb6,0x25,0x18,0x22,0x53,0x56,0xa4,0xa8,0xc7,0xa7,0xa1,0xe6,0x22,0x40,0xab,0xa4,0x26,0x17,0x6d,0xab,0xb7,0x34,0x2c,0x35,0x41 +,0xb6,0xb4,0x58,0x27,0xac,0x98,0xd5,0x2c,0xcf,0xb4,0x24,0x1d,0x36,0x4e,0xb2,0xa3,0xcb,0xe9,0xa6,0x9d,0xa1,0x23,0x11,0x34,0xc9,0x38,0x2a,0xb7,0xb7,0xc6,0xb1,0x53 +,0x4c,0x27,0x4b,0xaa,0xb1,0x28,0x2b,0xba,0x9f,0x94,0xbd,0x36,0x1c,0x29,0xa8,0xda,0x1e,0x1f,0xb7,0x9f,0xa9,0x64,0x27,0x2d,0xd6,0xb4,0xae,0x5a,0x29,0xc9,0x9f,0xaf +,0x3c,0xb8,0x9d,0x1e,0x0f,0x2f,0xa4,0xa0,0x32,0x26,0x37,0xa7,0x9e,0xa1,0x46,0x11,0x1b,0xd0,0xb0,0x25,0x6e,0x9b,0x9b,0xa3,0x4c,0x1f,0x12,0xaf,0x95,0x33,0x17,0x25 +,0xa1,0x93,0xb3,0x2b,0xe3,0x53,0x28,0x2f,0xe0,0x2a,0x2f,0xa4,0xa0,0x9e,0xbb,0x3c,0x31,0x1c,0x2f,0xaf,0xaf,0xe3,0x1f,0x2a,0xa5,0x96,0x9a,0xa4,0x1f,0x0a,0x24,0x9b +,0x96,0x50,0x3e,0x22,0x27,0xaa,0xa8,0xa9,0x23,0x26,0x41,0x68,0x21,0x2b,0x8f,0x89,0xbc,0x1d,0x25,0x1b,0x30,0xe0,0xce,0x1e,0x30,0x9b,0x9d,0xac,0xbe,0xab,0xb3,0x24 +,0x13,0x2d,0xd9,0x36,0x65,0xa5,0xbd,0xd6,0xa3,0xb5,0x14,0x0d,0xb9,0x92,0x9d,0x1a,0x18,0xca,0x8c,0x8a,0xad,0x27,0x0a,0x0f,0xb6,0x9e,0xbe,0x49,0xac,0xcb,0x2f,0xc9 +,0x9d,0xa6,0x2c,0x1c,0x1f,0x36,0xcc,0xb7,0xa9,0xa1,0x46,0x31,0xc4,0x2a,0x28,0x9e,0x9d,0x34,0xe8,0x52,0xdb,0xcd,0x31,0x49,0x36,0x23,0x1d,0xd6,0x9b,0xa6,0xbd,0xb4 +,0x39,0x16,0x29,0x9e,0x9a,0xc7,0x49,0xc9,0x31,0x65,0xb1,0x9f,0xc6,0x18,0x27,0x38,0x2c,0x2b,0xaa,0x92,0xa6,0x27,0x3d,0x44,0x2e,0x4f,0xab,0x3d,0x16,0xbd,0x9f,0xa8 +,0xad,0xac,0xd9,0x35,0x1e,0x2b,0xa8,0x38,0x27,0xac,0x9c,0x77,0x6b,0xaf,0x31,0x14,0x7e,0x9c,0xba,0x1d,0x0f,0x4d,0x8f,0x87,0xa1,0x25,0x11,0x0f,0xb1,0x98,0xae,0x2a +,0x2f,0xb4,0xc4,0xb3,0xab,0x73,0x1d,0x13,0x1e,0x34,0xad,0x9f,0x9b,0x9c,0xbd,0x35,0xc5,0x45,0x1e,0x41,0xd2,0x18,0x10,0xa6,0x8b,0x94,0xb8,0xdc,0x1e,0x1a,0x26,0x4d +,0x9e,0x46,0x1b,0xf5,0x9e,0x9a,0x9e,0xcb,0x11,0x0d,0xa2,0x99,0x38,0x1f,0x26,0xaa,0x96,0x97,0xc7,0x22,0x18,0x1e,0xae,0xa8,0x3a,0x3d,0xac,0xa6,0xa9,0x97,0x9e,0x2a +,0x0d,0x0f,0x25,0xce,0x9d,0xa6,0xa8,0xce,0x32,0xcb,0xf4,0x27,0x54,0xaf,0xbb,0x19,0x12,0x9f,0x8d,0x8f,0xad,0x26,0x09,0x13,0x9c,0x9b,0xbc,0x1c,0x1f,0xa3,0x98,0xa7 +,0xa9,0x35,0x0e,0x0f,0xa7,0x9f,0x2f,0x41,0xb9,0xb7,0x9d,0x9c,0x2b,0x1c,0x21,0xc4,0xad,0xdc,0x49,0xb6,0xa0,0xcf,0xf3,0x98,0xb8,0x16,0x1a,0x1d,0x33,0x6c,0xa7,0xa2 +,0xa3,0xa3,0x4a,0x3a,0x29,0x21,0xb4,0xa8,0x2a,0x1b,0x2f,0x90,0x91,0x69,0x26,0x17,0x17,0xb8,0x95,0xaf,0x22,0x22,0xb4,0x9f,0x9a,0xa5,0x3c,0x1b,0x0e,0x26,0xa2,0xaf +,0x4d,0xb7,0xb5,0x2f,0xbb,0x96,0x38,0x17,0x2d,0x3b,0xc0,0xb6,0xc4,0xb7,0xaf,0xc3,0x3c,0xb6,0x35,0x1f,0x54,0x3e,0x29,0xb7,0x9d,0xb3,0xb6,0xc3,0x60,0x23,0x22,0x4f +,0xa7,0xbd,0x1e,0x31,0x9d,0x8e,0x94,0xd8,0x12,0x0e,0x1f,0x99,0x97,0xe9,0x24,0x1d,0xbd,0xa5,0x9a,0x9e,0x23,0x0d,0x13,0x48,0x94,0x9b,0xbf,0x2e,0x26,0x73,0xa3,0x9d +,0x19,0x12,0xcc,0xab,0x5c,0xa8,0x9d,0xbc,0x51,0x39,0x58,0x21,0x2b,0xbe,0xab,0x54,0x17,0x46,0xa0,0xaa,0xa4,0xf7,0x1a,0x1a,0x64,0x9c,0xa4,0xb9,0x2e,0x2d,0xa7,0x9a +,0x9e,0x62,0x0f,0x0c,0x51,0x93,0x96,0xbd,0x30,0x22,0x2f,0xab,0x9a,0xa0,0x18,0x12,0x29,0xc1,0xa7,0x9a,0xa4,0x22,0x28,0xdc,0xa6,0x2d,0x1e,0x36,0xcb,0xab,0xcc,0x9d +,0xb3,0x49,0xcb,0xec,0x2b,0x1e,0xb0,0xa8,0x75,0x2e,0x2d,0xb5,0xbc,0x3e,0xb6,0xbe,0x1b,0x18,0xbc,0x9c,0xa8,0xe2,0xbc,0x29,0x27,0xaa,0x9e,0xf0,0x0f,0x1f,0xc1,0x9e +,0x9f,0x9e,0x4f,0x17,0x56,0x9f,0x9d,0x1e,0x1e,0x31,0xb8,0xa0,0xaa,0xa0,0x21,0x1c,0x3c,0xa5,0xae,0x25,0x38,0x45,0xba,0xbc,0xa9,0x9e,0x3b,0x1d,0x37,0xb5,0x27,0x2d +,0x9f,0xa1,0x2d,0x2d,0xae,0x4b,0x3a,0xd2,0xaf,0x22,0x13,0xc0,0x9c,0x9e,0xbe,0xbb,0x26,0x12,0xab,0x91,0xa6,0x1a,0x16,0x28,0xa3,0x98,0xa4,0xad,0x17,0x19,0x31,0x9e +,0xa8,0x26,0x40,0x36,0xbe,0xb4,0xa2,0xa1,0x2c,0x16,0x2e,0xad,0x4e,0xc6,0xa5,0xc3,0x21,0xcf,0x97,0xbe,0x2e,0x2d,0xcb,0x2a,0x1c,0x9f,0x99,0xa5,0x39,0x5b,0x29,0x18 +,0xe2,0x9e,0x9e,0x1a,0x1b,0x52,0x9c,0x9f,0xaf,0xa8,0x19,0x15,0x38,0x96,0xab,0x2e,0xdc,0x30,0x43,0xd0,0x9b,0xae,0x1a,0x19,0x50,0xa5,0x3b,0x6a,0xa9,0xcc,0x24,0xa6 +,0x99,0x20,0x1b,0x1e,0xad,0xac,0x67,0xce,0x3f,0xcf,0x42,0xa0,0xa6,0x26,0x1f,0x4b,0xa9,0xba,0xb3,0xa9,0xa3,0x66,0x4c,0xb6,0x1f,0x1c,0x3b,0x9d,0x52,0x1a,0xdb,0xb7 +,0xa8,0xbe,0xa7,0x43,0x13,0x1f,0x9c,0x9c,0x33,0xdb,0xff,0x63,0x2a,0xa4,0xa0,0x2b,0x1b,0x1e,0xa5,0xa9,0xbf,0x54,0x3c,0x3f,0xb7,0x9a,0xba,0x1a,0x1b,0x2b,0xd0,0xac +,0xa5,0xa2,0xed,0x1e,0x22,0xc2,0xba,0xc0,0xc2,0xbe,0x1e,0x18,0xae,0x96,0x9c,0x6c,0x35,0x29,0x1e,0x3e,0xa6,0xaa,0x49,0x3c,0xbe,0xc9,0x2b,0xba,0xa4,0xdc,0x32,0x2a +,0xac,0xbf,0xd1,0xb3,0x56,0x39,0x2b,0xaa,0xb1,0x23,0x24,0xc5,0xb4,0xb1,0xae,0xb7,0xbd,0x1e,0x4d,0xa0,0x4d,0x25,0x32,0xdf,0x2c,0x39,0xa5,0xa3,0xb2,0x3f,0x1b,0x23 +,0xd9,0xb0,0xaa,0x58,0x41,0xb5,0xa7,0xca,0x26,0x5a,0x50,0x38,0x44,0x2f,0xc0,0xc4,0x40,0xce,0xb0,0xc5,0x5c,0xc7,0x39,0x1d,0x26,0xa6,0x98,0xab,0x76,0xdc,0xe2,0x37 +,0x61,0xab,0x36,0x2c,0xda,0xb3,0xee,0x30,0xbb,0xb0,0xbc,0x39,0x47,0x3b,0x34,0xc6,0xc9,0x2a,0x4b,0x9f,0x9f,0xbb,0x1e,0xcc,0x49,0x25,0x3a,0x65,0xbb,0xcb,0x52,0x45 +,0xb8,0xcf,0xae,0xb0,0x49,0x20,0x38,0xac,0xac,0xa6,0x46,0x20,0x28,0x4b,0xba,0xf4,0x1e,0x27,0xd2,0x9f,0xae,0x4b,0xb3,0xbf,0xbf,0xbf,0x2d,0x30,0x5d,0x2c,0xdb,0x61 +,0xc8,0xa5,0xa3,0xd0,0x1f,0xc3,0xa1,0xb3,0x39,0x2c,0x2a,0xf1,0xbe,0xbb,0xb9,0x31,0xd6,0xbe,0x26,0x22,0xbd,0xac,0xcf,0xbf,0xb6,0xc4,0xbf,0xdf,0xb7,0x35,0x17,0xd3 +,0x9c,0xbe,0x25,0x24,0xce,0x9f,0xa6,0x66,0x20,0x1c,0x54,0xc1,0xd0,0xd5,0xb3,0xb3,0xb3,0xd2,0x30,0xb6,0xbb,0xbd,0x39,0x18,0x1d,0xce,0xac,0xb9,0xbb,0x31,0xf7,0xb4 +,0xad,0x67,0xc7,0xb4,0x29,0x53,0xac,0xc2,0x35,0x44,0xbf,0xc6,0x26,0x2e,0xbb,0xb2,0x3c,0x2d,0xaa,0x9c,0xb2,0x2f,0x26,0x2a,0xc1,0xae,0xb0,0x32,0x5e,0xad,0xbe,0x4a +,0x27,0xb0,0xb0,0x60,0x2d,0x22,0x25,0xb2,0xac,0x47,0x4a,0x2d,0x9d,0x98,0xcc,0x23,0x26,0x5d,0xaa,0x9f,0x42,0x19,0x1f,0xba,0xaa,0xbe,0x4d,0x30,0x2e,0xc2,0x56,0x2e +,0xab,0x9d,0xb4,0x4f,0x29,0x24,0xe0,0x57,0x5d,0x42,0x36,0xb8,0x9e,0xaa,0x3b,0xae,0xa9,0x55,0x23,0x50,0xb2,0x39,0x2c,0x3a,0xb8,0xc0,0xae,0xce,0x2c,0x1c,0x3b,0x9f +,0x9f,0x9f,0x26,0x11,0x3a,0x9e,0x9f,0xc9,0x28,0x3a,0xc7,0xe6,0x28,0x26,0xb0,0x9d,0xb2,0x3b,0x1e,0x1f,0xa6,0x9f,0xad,0xf2,0x2a,0x3b,0x9c,0xae,0x16,0x2f,0xc7,0xc0 +,0x3c,0x2e,0x2a,0x26,0x2e,0xaf,0x97,0xa4,0xaf,0x2a,0x29,0xc1,0xb0,0x97,0xa4,0x20,0x18,0x30,0xb9,0xad,0xba,0x21,0x24,0xe6,0x96,0x98,0x2b,0x1c,0x34,0xac,0xae,0xe1 +,0x28,0x39,0xbc,0xad,0xab,0x44,0x36,0x3c,0x43,0x2d,0x26,0xac,0xa3,0xa8,0xaf,0x38,0x1e,0x32,0xb8,0xde,0xa2,0x42,0x23,0x36,0xba,0xbb,0xb6,0x9e,0xc6,0x34,0x17,0x2b +,0x4f,0x44,0xe5,0xc9,0xa7,0xae,0xb0,0xb5,0x28,0x11,0xc9,0x95,0xac,0x24,0x11,0x25,0x9e,0x96,0x9f,0x43,0x2e,0xc8,0xc5,0x29,0x2b,0x53,0xd8,0x9e,0xa7,0xcb,0x2e,0x29 +,0x2e,0xcc,0xa3,0xcc,0x2c,0x2c,0xc3,0xbe,0xa0,0x9f,0xf5,0x29,0x18,0x2e,0xaf,0xce,0x42,0xb7,0xaa,0xc4,0xc1,0x3a,0x19,0x1b,0xb3,0x94,0xa9,0x22,0x17,0x3f,0x94,0x8d +,0xad,0x2a,0x26,0x20,0xbc,0x51,0x1b,0x23,0xe0,0x9c,0xa9,0x30,0x19,0x1b,0x2f,0xa5,0x96,0xba,0x2e,0x2d,0x9f,0x9a,0xa4,0xae,0x2d,0x23,0x23,0x31,0x28,0x30,0x31,0xb8 +,0x97,0x95,0x94,0x51,0x0f,0x17,0xab,0x9a,0xa7,0x1e,0x12,0xe7,0x98,0x9f,0x2d,0x28,0x2a,0x42,0xac,0x71,0x1c,0x26,0x9d,0x8c,0xa1,0x1b,0x11,0x42,0xa3,0x9c,0x9b,0x27 +,0x0f,0x1a,0x9f,0x97,0xaa,0x24,0x1f,0x31,0xc5,0x9f,0x3a,0x22,0x29,0xb5,0x9d,0x9f,0x34,0x16,0x17,0x3a,0x99,0x97,0xa5,0x18,0x16,0xb3,0x98,0x9e,0x3e,0x2e,0x3e,0xce +,0xa6,0xb4,0x2c,0x28,0xb2,0x99,0xc5,0x15,0x0f,0x44,0x9d,0x9f,0xad,0x4c,0x2b,0xb6,0x93,0xbd,0x1b,0x12,0x33,0x94,0x9f,0x2e,0x1d,0x38,0xd6,0xaa,0x9b,0xba,0x18,0x18 +,0x33,0xae,0x99,0x9b,0xbb,0x15,0x17,0xb3,0x94,0xa7,0x26,0x24,0x39,0xbc,0xbb,0x46,0x2c,0x30,0x4c,0xa7,0x3f,0x1b,0x35,0xb4,0xaf,0xa8,0xa4,0xa9,0xb8,0x3b,0xd5,0x2b +,0x25,0x1e,0xac,0x8f,0x4f,0x13,0x1d,0xa7,0xa5,0xa4,0xb5,0x26,0x12,0x33,0x97,0x92,0xab,0x42,0xa9,0xc5,0x26,0x1e,0x3d,0x31,0x1f,0x2f,0xa6,0xb6,0xab,0x9d,0x5a,0x1f +,0x21,0xaf,0xaf,0x32,0x1f,0x44,0xb4,0x9f,0xac,0xa5,0xb8,0x1c,0x2d,0x1e,0x20,0x3a,0x97,0x97,0x21,0x17,0xbb,0x8c,0x9b,0x2c,0x17,0x16,0x22,0x31,0xba,0xa5,0xbd,0x4c +,0x97,0x9c,0x21,0x30,0x5c,0x3c,0x36,0xbf,0x9a,0xa2,0x27,0x2b,0xb4,0xbf,0x2b,0x33,0xb2,0x2e,0x14,0x39,0x96,0x96,0x9e,0x9c,0x2c,0x0e,0x30,0xcd,0xad,0x3f,0x3d,0xb1 +,0x3d,0x2f,0x4d,0x9b,0xcb,0x1e,0x1c,0x65,0xbc,0xac,0x97,0xbe,0x1a,0x27,0x94,0x9a,0x33,0x18,0x18,0x43,0xb3,0x5d,0xa8,0xb4,0x27,0x2d,0xad,0xed,0x21,0xc1,0xa5,0x35 +,0x16,0xdb,0x93,0x90,0x49,0x2d,0x37,0x64,0xee,0x21,0xb0,0x45,0x2f,0xa2,0xa9,0x1c,0x2e,0x9f,0x4b,0x28,0x4f,0xa3,0xa6,0x64,0x53,0xbe,0xe8,0x73,0xa7,0xdc,0x1c,0x15 +,0x35,0x98,0xb9,0x3f,0xb4,0x28,0x17,0xba,0x9a,0xa1,0xb0,0x42,0xd7,0x2e,0x2a,0x48,0xaa,0xb1,0x1b,0x17,0xfa,0x9f,0xae,0xa4,0x9f,0x21,0x1c,0xb9,0xa4,0xba,0x1c,0x1f +,0xcd,0xae,0xbb,0xb7,0xb7,0x38,0x23,0xd3,0xb4,0x24,0xbf,0xa0,0x56,0x23,0xab,0x95,0xab,0x41,0x28,0x25,0x23,0x38,0x4e,0xbb,0xc9,0xb9,0x9e,0xf4,0x18,0x28,0x9d,0xac +,0x21,0x34,0xb0,0x9b,0x9b,0xd6,0xcd,0x2f,0x33,0x36,0x23,0x20,0x17,0x32,0x8f,0x8f,0xd7,0xe0,0x3b,0x21,0x2d,0xa5,0x9c,0xc0,0x23,0x1d,0x4a,0xe4,0xab,0xa5,0xed,0x16 +,0x14,0xc3,0x9a,0xa6,0xb2,0xa0,0x35,0x24,0xc8,0xfc,0x3c,0x3c,0x5a,0x52,0x32,0xbf,0xa9,0x9f,0xa4,0x32,0x32,0x29,0x21,0x6b,0xa5,0x49,0x19,0x43,0x9d,0x98,0xa7,0x32 +,0x23,0x3c,0xd8,0xf0,0x5a,0x49,0x28,0x2b,0x9c,0x9d,0x39,0x3a,0x3c,0x1c,0x23,0xa3,0x94,0xa1,0x28,0x35,0xbd,0xa8,0xbe,0x1c,0x1a,0x1b,0x3e,0x9c,0xa0,0xf6,0xb5,0x9f +,0xcc,0x2f,0xe8,0x3f,0x44,0xbf,0x37,0x1c,0x24,0xa6,0x9d,0xaa,0xe1,0x2b,0x2e,0xcd,0xbf,0xae,0xbb,0x25,0x1f,0x47,0xa4,0x9f,0xab,0x38,0x2c,0x2d,0xdd,0xbe,0xdc,0xc4 +,0x1c,0x2d,0x9b,0x99,0x41,0x24,0x2d,0x1e,0x3c,0xa0,0x9c,0xbb,0x31,0xc2,0xaa,0xaf,0xc9,0x20,0x23,0x2a,0x2b,0xba,0xab,0xc1,0xc1,0xba,0x3d,0x3e,0xe4,0xb3,0xb7,0x4d +,0x25,0x26,0xb3,0x9d,0xb3,0x37,0x39,0x20,0x3d,0xa2,0xa3,0xdd,0x30,0x23,0x1c,0xb3,0x98,0x98,0xc3,0x1f,0x23,0x30,0xb2,0xbb,0x49,0x3a,0x31,0xb7,0x9c,0xac,0x2a,0x2a +,0x54,0x37,0x2d,0x56,0xb7,0xb0,0xab,0xa5,0xa8,0xed,0x1a,0x1a,0x3d,0xfa,0x3d,0xbc,0x9d,0xba,0x2f,0x26,0x3b,0xb6,0x9e,0xa1,0x60,0x28,0x1b,0x1f,0xc7,0x93,0xa1,0x5f +,0x2e,0x1f,0x41,0xb3,0xa4,0xbc,0x2f,0x1a,0x1c,0xb1,0x93,0x97,0xc6,0x2b,0x25,0x2b,0x37,0x3d,0xd7,0xc8,0xd2,0xac,0x9c,0xbb,0x1a,0x27,0x49,0x3b,0x6b,0xaf,0xab,0x38 +,0x3d,0xc4,0xa6,0x9b,0xad,0x2a,0x15,0x12,0x29,0x9f,0x95,0x9c,0x34,0x24,0x29,0x33,0xa9,0xa8,0xce,0x27,0x2b,0xbb,0x9f,0xaf,0x36,0x45,0x3d,0x4e,0xab,0x9f,0x3d,0x18 +,0x1b,0x25,0xb5,0x96,0x91,0xbe,0x1a,0x3e,0x4f,0x2e,0x3e,0xf3,0xce,0x2f,0x6d,0x9f,0x9b,0xad,0x2f,0x26,0x1d,0x17,0x29,0x98,0x8c,0x9f,0x29,0x2a,0x3f,0x2e,0x42,0xb7 +,0xba,0x21,0x22,0xae,0xa7,0x4f,0x38,0xb3,0xab,0xb2,0xce,0x35,0x19,0x1c,0x5d,0xa4,0x91,0x9a,0xeb,0x1d,0x17,0x3e,0xba,0xaf,0xb0,0x38,0x2f,0x23,0x35,0xa9,0x9a,0x9c +,0x56,0x2b,0x2c,0x26,0x27,0x64,0xa3,0xa9,0x47,0xb1,0xa8,0x34,0x2a,0x2e,0x24,0x20,0xb0,0x92,0xa8,0x26,0xd8,0xa6,0xc6,0x4f,0x27,0x20,0x1d,0x42,0x97,0x9b,0xa5,0x2b +,0x1f,0x2d,0x28,0xa9,0xa0,0xaa,0x35,0x16,0x1c,0xed,0x99,0x9a,0xa0,0xa3,0x3f,0x23,0x29,0x27,0x20,0x2f,0xac,0xa1,0xb1,0xaf,0xe6,0x24,0x4c,0xb5,0x37,0x2c,0xd6,0xb3 +,0x3b,0x26,0xa3,0x8f,0xa3,0x2f,0x1b,0x1b,0x14,0x1e,0x9d,0x8f,0x9d,0x3f,0xb7,0xb8,0x2c,0x29,0x1d,0x37,0xed,0x4b,0xa4,0xa4,0xb0,0xdb,0xcd,0xc8,0x27,0x3b,0xe6,0x24 +,0x1c,0x60,0xa7,0x9f,0x98,0xa0,0x31,0x23,0x3a,0x67,0x3d,0x26,0x34,0x41,0x44,0x5d,0x9b,0x91,0xad,0x25,0x15,0x1b,0x1f,0xae,0x96,0xa0,0xb3,0x31,0xc3,0xa9,0x37,0x1d +,0x1e,0x3c,0x3e,0xcf,0x98,0xab,0x2f,0xcd,0x9a,0xaf,0x1b,0x2e,0x2f,0x16,0x1d,0x9c,0x89,0x97,0xb2,0x2c,0x15,0x15,0x21,0xa8,0x9f,0x32,0x2d,0x7a,0xd8,0xa8,0x94,0xa6 +,0x3f,0xdc,0x34,0x18,0x0f,0x31,0x9f,0xa4,0x9d,0xce,0xb0,0xa1,0x27,0x16,0x26,0x3e,0x25,0xa8,0x97,0xcc,0xd7,0xaa,0x99,0xbb,0x0e,0x1f,0xd7,0x1f,0x1b,0xbd,0x8a,0x8f +,0xcc,0x42,0x3c,0x10,0x15,0xae,0x6a,0x26,0xbf,0x9d,0x9b,0xa3,0x9d,0xa4,0x26,0x13,0x16,0x1c,0x16,0x2f,0x9c,0x8e,0x9a,0x49,0x99,0xa5,0x15,0x19,0xe1,0x6a,0x2c,0x68 +,0xd1,0x49,0xab,0xa5,0x9a,0xa4,0x15,0x17,0x21,0x1e,0x26,0x9e,0x8e,0x98,0xa8,0xac,0x3c,0x0d,0x10,0x71,0xcc,0x4a,0xbc,0x9c,0x8c,0xa4,0x1d,0x3e,0x7e,0x15,0x1d,0x2d +,0x0e,0x1c,0x96,0x83,0x89,0xc8,0xaa,0xd2,0x0a,0x0a,0x1b,0xc9,0xaf,0x47,0x42,0xa2,0xa1,0x9d,0x8d,0xbd,0x0f,0x23,0x28,0x0f,0x1d,0x9c,0x8b,0x9a,0xad,0xac,0x28,0x0f +,0x1a,0x36,0x56,0x2e,0x20,0x98,0x89,0x9f,0xc9,0xa8,0x4a,0x13,0x11,0x16,0x13,0x2b,0x99,0x87,0x84,0x9d,0x5c,0x24,0x0d,0x08,0x19,0xbe,0x4b,0x2d,0xa5,0x8e,0x97,0x95 +,0x8d,0xc6,0x0a,0x0c,0x11,0x17,0x26,0xaf,0x8d,0x8f,0xac,0xac,0xb5,0x19,0x18,0xbb,0xa3,0x1e,0x0f,0xa1,0x8b,0xac,0xda,0xc9,0x33,0x29,0x1c,0x0f,0x15,0xe7,0x99,0x86 +,0x8a,0xa6,0xa3,0x3e,0x0c,0x08,0x1c,0x4b,0x18,0x1b,0x9c,0x89,0x8d,0x99,0xb8,0x3a,0x19,0x0e,0x1e,0x32,0x18,0x3e,0x88,0x85,0x9d,0x50,0x2e,0x11,0x13,0x2c,0x30,0x1d +,0x17,0xaa,0x8d,0x96,0xa4,0xae,0xc1,0x2d,0x1b,0x26,0x2b,0x24,0xa8,0x87,0x8f,0x3c,0x49,0x1e,0x0e,0x12,0x25,0x27,0x1e,0x2c,0x99,0x84,0x8c,0xa0,0xd0,0xba,0x1f,0x0b +,0x10,0x1b,0x17,0x6e,0x8a,0x87,0x8b,0xaa,0x12,0x0c,0x16,0x18,0x20,0x1d,0x23,0x92,0x84,0x8e,0xbc,0xb9,0x9d,0x41,0x0e,0x0a,0x0f,0x23,0xa8,0x8c,0x90,0xa1,0xea,0x2d +,0x26,0x19,0x22,0x32,0x2f,0x1f,0xa8,0x88,0x8c,0xa2,0xf2,0xfa,0x26,0x19,0x0e,0x0a,0x1c,0x9b,0x8a,0x8b,0x99,0x3a,0x24,0x34,0x2b,0x13,0x19,0x1d,0x20,0x9a,0x89,0x8f +,0xa0,0xb5,0x4c,0x4f,0x19,0x07,0x10,0x2f,0xbd,0x8d,0x84,0x94,0x24,0x1d,0x39,0x22,0x1b,0x12,0x19,0x58,0x95,0x98,0x98,0x91,0xf4,0x25,0xaa,0x9f,0x1d,0x0b,0x0d,0x20 +,0x61,0x96,0x88,0x9f,0x18,0x1a,0x22,0x26,0x39,0x0c,0x07,0x92,0x81,0x87,0x82,0x8f,0xb4,0xcc,0x0f,0x00,0x14,0x90,0x9e,0x23,0xa1,0x84,0x4a,0x00,0x0c,0x98,0x9f,0x38 +,0x26,0x00,0x24,0x80,0x81,0x89,0x88,0x83,0x44,0x00,0x05,0x0c,0x06,0xaf,0x85,0x1f,0x1c,0x89,0xc6,0x00,0x1d,0x95,0xa8,0x1c,0x0f,0x9b,0x84,0x81,0x84,0x18,0x02,0x95 +,0x9c,0x02,0x07,0xb5,0xa0,0x53,0x20,0xc4,0x85,0x8d,0x77,0x1c,0x0b,0x08,0x0d,0x07,0xac,0x80,0x81,0x83,0xa0,0x08,0x17,0xcb,0x0f,0x12,0x6f,0x46,0x21,0xa7,0x8d,0xc2 +,0x0f,0x46,0x9e,0x09,0x0c,0xbe,0x16,0x9d,0x80,0x9c,0xc6,0x84,0x89,0x2b,0x0b,0x0f,0x10,0x04,0x11,0x8a,0x8d,0x99,0x88,0x24,0x00,0x14,0xa9,0x1a,0x1e,0x9e,0x8a,0x8f +,0x9e,0x93,0x9f,0xb5,0x8a,0xc0,0x00,0x02,0x26,0xab,0x30,0xa2,0x8b,0x85,0xa8,0x08,0x0d,0xe4,0xa0,0x18,0x03,0xc2,0x81,0x84,0x8f,0x9b,0xb9,0xab,0x13,0x00,0x08,0x9b +,0x89,0x8f,0x99,0x1f,0x1d,0x3c,0x38,0xf3,0x2f,0x1f,0x3a,0x08,0x0f,0x8a,0x80,0x83,0x82,0x9e,0x06,0x06,0x0d,0x06,0x06,0xac,0x83,0x99,0x22,0xa0,0x9c,0x41,0x9c,0xbf +,0x0a,0x0b,0xc4,0x9a,0xa1,0x8e,0x89,0x9f,0x1d,0x1c,0x12,0x09,0x1e,0xcd,0x2b,0x2c,0x95,0x88,0x86,0x8f,0x28,0x18,0x0a,0x03,0x05,0x13,0x90,0x80,0x89,0x43,0xb4,0x8b +,0xa5,0x0f,0x08,0x19,0xb6,0x29,0x0d,0xb1,0x87,0x8f,0xbb,0x1a,0x12,0x1b,0xc9,0x22,0x0b,0xb0,0x88,0x93,0xb3,0x8c,0x8a,0x9f,0x20,0x08,0x01,0x06,0x93,0x84,0x9b,0xc6 +,0x94,0xa2,0x09,0x03,0x12,0x98,0x8b,0xac,0x16,0x20,0x8e,0x85,0x8d,0xa1,0xda,0x14,0x02,0x01,0x10,0x9b,0x89,0x86,0x9a,0x2a,0xa3,0xa0,0x1d,0x14,0x1f,0x0e,0x13,0x45 +,0x9b,0x8c,0x86,0x89,0x9f,0x1d,0x03,0x05,0x21,0xa5,0x9f,0x97,0x91,0x44,0x19,0x2c,0xef,0xac,0xbb,0x27,0x09,0x08,0x58,0x8c,0x86,0x86,0x83,0xa5,0x06,0x00,0x10,0x49 +,0xd8,0x9d,0x9c,0x9e,0x90,0x8d,0xa1,0x17,0x15,0x2b,0x1e,0x11,0x1b,0x6d,0x91,0x86,0x9b,0x16,0x1f,0xad,0x19,0x0b,0x14,0x2d,0xac,0xde,0xbd,0x94,0x85,0x8a,0x5a,0x09 +,0x05,0x11,0x1a,0x15,0xd4,0x87,0x83,0x8d,0x9c,0xb6,0x32,0x31,0xf0,0x26,0x0e,0x19,0xca,0x9b,0x9c,0x2e,0x1f,0x1c,0x0e,0x16,0x3d,0x39,0x21,0xdd,0x97,0x8d,0x84,0x82 +,0x8b,0x48,0x10,0x0c,0x05,0x07,0x2b,0x94,0x8d,0x8f,0xad,0x1a,0x16,0x1e,0x2a,0xb5,0xb9,0x2a,0x1a,0x30,0xa4,0x96,0x8e,0x91,0xab,0x13,0x0a,0x10,0x1c,0x2c,0xae,0x8d +,0x8d,0xaf,0x38,0x2b,0x55,0x9a,0xa1,0x14,0x05,0x1b,0x94,0x87,0x89,0x9a,0x53,0x19,0x09,0x0b,0x3a,0x99,0x98,0xaa,0x2c,0x19,0x1c,0x3e,0xbb,0xc4,0xb2,0xb2,0x1e,0x0d +,0x15,0x9f,0x86,0x82,0x88,0xb9,0x16,0x0f,0x18,0x1d,0x26,0xc8,0xab,0xac,0x44,0x26,0x38,0xb9,0xad,0xdd,0x21,0x17,0x1d,0x4b,0x9d,0x8f,0xa6,0x1c,0x1f,0xc2,0xab,0x9f +,0xa7,0x29,0x1b,0x2d,0xa7,0x93,0x96,0xa2,0xcf,0x27,0x15,0x0f,0x0f,0x24,0xab,0x99,0x95,0x9d,0xb5,0xdf,0x35,0x2d,0xbf,0xb0,0x3f,0x1b,0x1d,0xb9,0xa3,0x4d,0x1f,0x25 +,0xc0,0x9f,0xb4,0x24,0x23,0x63,0xa8,0x9d,0x9d,0x99,0x8f,0x90,0x51,0x0a,0x03,0x0c,0xdf,0x9d,0xa0,0xb0,0x27,0x19,0x20,0x6a,0x9f,0x90,0x95,0x4b,0x1a,0x2e,0xaa,0x9d +,0x9d,0xa6,0xc1,0x4d,0x28,0x14,0x16,0x2c,0xae,0x9d,0xab,0x75,0x57,0xd4,0xaf,0xb3,0x26,0x10,0x12,0x1d,0x59,0x96,0x8d,0x91,0xa2,0x3d,0x1d,0x26,0x6e,0xb0,0xa5,0xb5 +,0x29,0x11,0x0d,0x22,0x99,0x8b,0x95,0x3d,0x10,0x0c,0x1a,0xcc,0x90,0x85,0x8a,0xb0,0x19,0x18,0x2b,0x6d,0x65,0x26,0x1c,0x36,0xc2,0x3e,0x3d,0xba,0xa2,0x9e,0xc7,0x1d +,0x1b,0x5f,0x9d,0x99,0xb9,0x32,0x62,0xbb,0xb9,0xad,0xca,0x28,0x1b,0x16,0x1e,0xb2,0x94,0x94,0xa6,0x3f,0x1e,0x17,0x19,0x20,0x6b,0xa3,0x9c,0xa5,0x75,0x41,0xa7,0x93 +,0x96,0xb5,0x1f,0x13,0x23,0xd9,0x3c,0x27,0x27,0x2d,0x49,0xb4,0xb6,0x50,0x37,0x31,0x52,0x9f,0x95,0x99,0x9b,0xa2,0xb8,0x33,0x10,0x0b,0x1d,0xc7,0xa3,0xab,0x2b,0x22 +,0xda,0xad,0xad,0xa1,0x9e,0xca,0x23,0x19,0x1f,0xc8,0x98,0x95,0xb0,0x48,0x36,0x21,0x1f,0x2a,0x52,0xa9,0xbb,0x25,0x26,0xbb,0x94,0x93,0x32,0x0e,0x14,0x2b,0xb3,0x9d +,0xa3,0xb1,0xab,0xbb,0x53,0xbc,0xa9,0xa5,0xb5,0x2c,0x1a,0x18,0x1a,0x2f,0xab,0xa1,0xaf,0x4b,0x1f,0x19,0x2f,0xad,0x96,0x90,0x9a,0xad,0xba,0xbb,0x55,0x2f,0x2b,0x1e +,0x1b,0x1f,0x22,0x2d,0xaf,0xa5,0xad,0xac,0x5e,0x36,0xce,0xbb,0x7d,0xd6,0x3f,0x30,0xc7,0xae,0x9e,0x9b,0xcd,0x24,0x24,0x2b,0x3c,0x4e,0x6f,0xaf,0xa5,0xb8,0x28,0x18 +,0x1f,0x44,0xbd,0xda,0xed,0xb1,0xab,0xab,0xa5,0x9b,0x99,0xa1,0x36,0x16,0x19,0x28,0x2a,0x27,0x35,0x4f,0xb3,0xaf,0x41,0x42,0xcf,0xc3,0xce,0x44,0xd3,0xa0,0x95,0x9e +,0xb8,0xeb,0x26,0x1a,0x22,0x27,0x22,0x2b,0x28,0x2a,0x56,0xa8,0x9c,0x9a,0x9d,0xae,0x76,0x35,0x28,0x37,0xbc,0xbd,0xc7,0xbb,0xce,0xe1,0xd0,0x3c,0x34,0x4c,0x46,0x46 +,0xc3,0xb7,0xb5,0xca,0x33,0x34,0x2b,0x29,0x33,0x45,0xb8,0xa4,0xad,0xc1,0xa4,0x9c,0x9d,0xac,0x40,0x27,0x1a,0x14,0x17,0x29,0x54,0x43,0x33,0x71,0xb8,0xbc,0xb8,0xef +,0x44,0xa6,0x9a,0xab,0xbb,0xb3,0xad,0xab,0x5c,0x23,0x22,0x28,0x27,0x2a,0x2e,0x33,0xc7,0xb3,0xbd,0xac,0xa6,0xb2,0x50,0x3c,0x42,0xcb,0xb2,0xb0,0xbb,0xb3,0xa3,0xb9 +,0x2e,0x1f,0x1d,0x27,0x6c,0xc9,0x5e,0x4f,0x3d,0x4b,0xb7,0xaf,0xba,0x48,0x26,0x2c,0x70,0xbe,0xa4,0x9b,0x9d,0xa4,0xe3,0x3b,0xda,0x37,0x1d,0x18,0x16,0x1d,0x36,0x46 +,0xc7,0x9f,0xa2,0xbb,0xce,0xaf,0x9f,0xa0,0xaa,0xbd,0x76,0x55,0x53,0x32,0x35,0x39,0x26,0x1e,0x1a,0x21,0xca,0xa7,0xb9,0xb4,0xa9,0xa4,0xa2,0xb7,0x32,0x2e,0x3c,0x37 +,0x4f,0xbd,0xa9,0xa7,0xd3,0x31,0x48,0xe5,0xff,0x37,0x28,0x36,0x69,0x54,0x3b,0x3d,0x43,0xc8,0xbd,0xe1,0x50,0x45,0x50,0xb1,0xa0,0x9e,0x9d,0xa6,0xbf,0x2f,0x25,0x2f +,0x2f,0x26,0x27,0x22,0x1f,0x3f,0xb0,0xae,0xb5,0xbe,0xae,0xa9,0xc0,0xc9,0xab,0xa2,0xaa,0xb5,0x32,0x23,0x35,0x35,0x29,0x20,0x24,0x27,0x25,0x3d,0xa6,0x98,0x98,0xa7 +,0x3f,0x2d,0x3e,0x67,0xef,0x48,0x7a,0xb4,0xbb,0x40,0x3c,0xcb,0xb2,0xb2,0x4a,0x25,0x20,0x25,0x2d,0xe1,0xae,0xab,0xbf,0x39,0x5a,0xae,0xae,0xbf,0xd8,0x4f,0xc4,0xa5 +,0xa6,0xb4,0xd9,0x3f,0x3d,0x27,0x1c,0x1a,0x21,0x42,0xdd,0xdd,0xd2,0xb8,0xb6,0xa4,0xa0,0xad,0xaf,0xbd,0x58,0xe8,0xc2,0xcc,0xc6,0xde,0x33,0x2a,0x25,0x1e,0x1e,0x25 +,0xd0,0x9f,0xa8,0xde,0x3e,0xd6,0x9d,0x9a,0xb5,0x28,0x1f,0x2e,0xbf,0xac,0xb8,0xb3,0x65,0x36,0x76,0xbc,0xc4,0x35,0x21,0x1c,0x24,0x41,0xbf,0xd3,0x48,0xaf,0xa0,0xb6 +,0x41,0x2e,0xba,0x97,0x98,0xb0,0x49,0x37,0x2f,0x42,0x3b,0x28,0x1e,0x19,0x1a,0x2f,0xbd,0xa5,0xa4,0xab,0xa4,0x9b,0x9e,0x5f,0x2b,0x3e,0xad,0xae,0x5e,0x2c,0x1e,0x3a +,0xa8,0xb3,0x2d,0x1c,0x1b,0x25,0xd8,0xab,0xa8,0xad,0xbe,0xa7,0x9d,0xa2,0xc0,0x2b,0x21,0x2f,0xcd,0xb8,0xd1,0x27,0x2a,0xb2,0x9f,0xb6,0x29,0x19,0x21,0x6a,0xd5,0x71 +,0x5a,0xbe,0xab,0xab,0xce,0x4a,0xc5,0xb9,0xbb,0xca,0xc4,0xce,0x4d,0xb8,0xa8,0xbf,0x28,0x13,0x0f,0x1b,0xba,0xa1,0xc7,0x21,0x24,0x9e,0x8b,0x8f,0xa7,0x37,0x2a,0x33 +,0x4d,0xeb,0xd9,0x34,0x27,0x42,0xb4,0xb2,0x44,0x22,0x1e,0x2f,0xbf,0xae,0x48,0x2e,0xdc,0xa2,0x9f,0xac,0xba,0xbe,0xaf,0xbf,0x31,0x22,0x29,0x3d,0xec,0xbd,0xbe,0x3c +,0x1e,0x1f,0xc7,0x9c,0x9a,0xb4,0x23,0x17,0x24,0xac,0x9b,0x9f,0xae,0xbe,0xc5,0x4e,0x3f,0x53,0xcc,0xcc,0xed,0xe1,0x57,0x29,0x1a,0x19,0x22,0x38,0xcd,0xb2,0xab,0xa1 +,0x9b,0x9a,0xa1,0xc5,0x39,0x3d,0xcd,0xd2,0x36,0x22,0x1d,0x21,0x24,0x36,0xa7,0x95,0x95,0xaa,0x2d,0x18,0x16,0x25,0xe5,0xac,0xa2,0xa1,0xaf,0x48,0x32,0x54,0xaf,0xa9 +,0xbe,0x42,0x37,0x41,0x37,0x28,0x2c,0x4a,0xcf,0x4f,0x48,0xbe,0xa4,0xa1,0xb8,0x3c,0x2d,0x33,0xd4,0xab,0xa7,0xb3,0x4d,0x22,0x18,0x23,0xbc,0x9e,0x9f,0xc3,0x2e,0x27 +,0x24,0x1f,0x27,0xc5,0x9c,0x94,0x97,0xa1,0xbe,0x42,0x3e,0x3a,0x2b,0x27,0x2a,0x2e,0x31,0x30,0x30,0x2e,0x2e,0x3d,0xaa,0x91,0x8d,0x97,0x68,0x1b,0x16,0x1e,0x49,0xad +,0xa5,0xaa,0xb3,0x52,0x23,0x1e,0x33,0xb3,0xa2,0xa7,0xce,0x29,0x1d,0x1e,0x28,0xdb,0xa7,0xa7,0xc2,0xcc,0xa5,0x9e,0xac,0x38,0x25,0x31,0xe4,0xc1,0xc8,0xce,0x5b,0x2f +,0x23,0x23,0x3e,0xaf,0xa6,0xae,0x6f,0x34,0x30,0x30,0x3a,0xba,0x9e,0x9d,0xb6,0x30,0x2f,0xc1,0xae,0xcb,0x2e,0x29,0x43,0xdf,0xe1,0xc7,0xb5,0xbf,0x33,0x1f,0x1e,0x3e +,0xaf,0xab,0xac,0xaa,0xb0,0x47,0x24,0x25,0x4a,0xb1,0xb1,0xdf,0x3c,0x3e,0xc9,0xae,0xad,0xc4,0x44,0x42,0x2f,0x29,0x46,0xba,0xb6,0xd9,0x47,0xc9,0xa0,0x9b,0xa8,0x5b +,0x27,0x1e,0x1c,0x1e,0x2f,0xb1,0x9e,0xb2,0x2b,0x1c,0x24,0xbe,0x9b,0x96,0x9b,0xa7,0xcf,0x1f,0x17,0x27,0xbd,0xa5,0xa6,0xb6,0x5d,0x4b,0x4a,0x2a,0x28,0x35,0xd8,0xc1 +,0x52,0x43,0x38,0x3f,0x3d,0x29,0x24,0x3f,0xa5,0x9b,0xa3,0xca,0x4d,0x4d,0x2e,0x2e,0xbe,0xa5,0xac,0xe1,0x3f,0xde,0xaa,0xa1,0xa9,0xbb,0x59,0x31,0x26,0x22,0x37,0xaf +,0x9e,0xa8,0x46,0x28,0x28,0x41,0xda,0x65,0x33,0x2b,0x28,0x19,0x18,0x30,0xab,0x9e,0xa2,0xae,0xb5,0xae,0xa7,0xb2,0xca,0xca,0xb0,0xb3,0x3c,0x2b,0x2f,0x51,0x48,0x39 +,0x4e,0xb7,0x9e,0x9d,0xb0,0x34,0x2d,0x2d,0x1f,0x21,0x3e,0xd1,0xeb,0x53,0x4c,0x4e,0xcd,0xba,0x56,0x2d,0x29,0x3d,0x6c,0x52,0xb4,0xa0,0xa3,0xd9,0x28,0x29,0xd2,0x9e +,0x99,0x9f,0xaa,0xfb,0x27,0x1b,0x1f,0xd9,0xaa,0xa8,0xc0,0x38,0x29,0x2e,0x5a,0x3f,0x38,0x43,0xe5,0x42,0x2b,0x34,0xc7,0xa5,0xa5,0xb6,0xc7,0xaf,0xa2,0xa3,0xc0,0x36 +,0x2b,0x26,0x24,0x2d,0xec,0xbc,0xaf,0xbe,0x3f,0x33,0x49,0xcc,0xe0,0x3e,0x33,0x4a,0x4c,0x3d,0x59,0xc8,0xc1,0xbb,0xbc,0xcb,0xb8,0xa8,0xad,0xdd,0x2f,0x20,0x21,0x2e +,0x64,0xb4,0xab,0xac,0xf2,0x2e,0x2b,0xc6,0xa5,0xb0,0xc4,0xd5,0x3d,0x26,0x27,0x3a,0xbe,0xa4,0xa7,0xe6,0x3e,0xf9,0xb0,0xaf,0xc8,0x52,0x44,0x3f,0x3d,0x4d,0x52,0xc5 +,0xb1,0x4c,0x29,0x39,0xd7,0xe1,0x43,0x2f,0x29,0x28,0x29,0x35,0xc0,0xa5,0x99,0x9b,0xad,0xc4,0xc6,0xc7,0xf3,0xe0,0x5b,0x48,0xe7,0xbd,0xbe,0x5a,0x40,0x3c,0x33,0x35 +,0xd0,0xb2,0xca,0x36,0x23,0x1a,0x1c,0x30,0xc2,0xab,0xa3,0xa2,0xbd,0x34,0x39,0xaf,0x9d,0x9e,0xb4,0x2d,0x1e,0x1f,0x2a,0x40,0xb7,0xa1,0xad,0x34,0x27,0x2d,0x45,0xca +,0xb7,0xbd,0xfc,0x4f,0x39,0x39,0x43,0xc9,0xa6,0xa5,0xb2,0xc0,0xbd,0xb9,0xcf,0x34,0x26,0x35,0xce,0xba,0xbb,0xd6,0xd2,0xda,0x45,0x4a,0xc8,0xb5,0xcf,0x32,0x22,0x20 +,0x2b,0x46,0xbb,0xb0,0xad,0xad,0xcd,0x3b,0x5e,0xb3,0xad,0xbc,0x44,0x29,0x26,0x32,0x58,0xba,0xab,0xab,0xc9,0x34,0x2f,0x3e,0x5f,0xd7,0xfb,0x3c,0x30,0x2e,0x2e,0x31 +,0x3f,0xb3,0x9e,0xa3,0xad,0xa7,0xa4,0xad,0xd4,0x3b,0x38,0x3c,0x47,0x48,0x3c,0x3d,0x4b,0x4f,0x3f,0x46,0xe9,0xd7,0x4c,0x2d,0x26,0x2c,0x3c,0x4c,0xef,0xb7,0xa5,0xa0 +,0xa8,0xaf,0xad,0xae,0xe0,0x34,0x2d,0x30,0x45,0xf9,0xe7,0xf0,0x47,0x38,0x3e,0x44,0xc4,0xa6,0xaa,0xda,0x30,0x25,0x23,0x31,0xe8,0xb7,0xaa,0xa7,0xaa,0xc4,0x56,0xc9 +,0xbc,0xe4,0x4b,0x39,0x2f,0x34,0x35,0x31,0x38,0x4d,0xc3,0xb9,0xde,0x74,0xbc,0xba,0x59,0x27,0x1f,0x26,0x30,0x5d,0xb8,0xad,0xa5,0xa4,0xac,0xae,0xab,0xa8,0xb4,0x5a +,0x30,0x34,0x4d,0x67,0x3b,0x2d,0x3a,0xe6,0xc6,0xbe,0xb0,0xad,0xc5,0x2e,0x1e,0x1c,0x21,0x2f,0xcb,0xa9,0xa9,0xb7,0xd3,0x46,0x53,0xa8,0x98,0x9e,0xb9,0x3b,0x26,0x20 +,0x22,0x2d,0x46,0xd9,0xbe,0xbc,0xc9,0xeb,0x59,0x3e,0x38,0x47,0x56,0x6c,0xcf,0xc1,0xb9,0xb1,0xb1,0xb0,0xb1,0xb3,0xaf,0xbe,0x3e,0x2f,0x26,0x28,0x34,0x32,0x2b,0x2b +,0x3d,0xc6,0xb1,0xad,0xad,0xc1,0x34,0x27,0x30,0x4f,0xc8,0xc2,0x6e,0x45,0x50,0xbd,0xa5,0x9a,0x96,0x97,0xab,0x2e,0x1e,0x1e,0x29,0x30,0x2b,0x2c,0x34,0x4a,0xcc,0xbc +,0xb2,0xae,0xbd,0x48,0x33,0x34,0x49,0xc5,0xbc,0xce,0xd5,0xbd,0xb5,0xb1,0xaa,0xa8,0xba,0x2c,0x1e,0x29,0x36,0x4b,0x48,0x2c,0x20,0x23,0x47,0xa9,0x9b,0x9a,0xa4,0x77 +,0x31,0x35,0x3c,0x5b,0xc4,0xc6,0x44,0x2e,0x36,0xd4,0xa7,0x9f,0xa3,0xae,0x3e,0x1f,0x19,0x1d,0x3f,0xcf,0x40,0x2d,0x30,0xde,0xac,0x9f,0x9a,0x9a,0xac,0x3f,0x29,0x28 +,0x37,0x4e,0x3b,0x2a,0x34,0xbe,0xae,0xad,0xac,0xa7,0xac,0x4c,0x2f,0x30,0x31,0x38,0x35,0x2d,0x30,0xd9,0xa7,0x9f,0xa5,0xb3,0x65,0x2c,0x26,0x32,0xe9,0xb7,0xd0,0x29 +,0x1f,0x2f,0xbd,0xa5,0x9c,0x9d,0xa7,0xd7,0x39,0x2f,0x28,0x2c,0x39,0x2e,0x20,0x21,0x46,0xab,0x9e,0x9c,0xa1,0xb3,0xd3,0x3f,0x2e,0x2e,0x39,0x3d,0x29,0x26,0x40,0xaf +,0x9f,0x9e,0xa5,0xaf,0xc9,0x3e,0x2a,0x26,0x33,0x53,0x37,0x29,0x2e,0xd1,0xa3,0xa1,0xac,0xb9,0xba,0xc9,0x45,0x3f,0x49,0x3d,0x26,0x1d,0x2b,0xca,0xa5,0x9d,0xa2,0xbb +,0x3e,0x2f,0x2e,0x2f,0x3a,0xd9,0xb8,0x70,0x2d,0x2c,0xcc,0xa0,0x9b,0x9c,0xac,0x3e,0x24,0x20,0x2a,0x43,0xcd,0xda,0x34,0x2d,0x43,0xaf,0x9f,0x9f,0xaa,0xc0,0xed,0x37 +,0x23,0x1d,0x24,0x32,0x31,0x2d,0x34,0xd8,0xa6,0x9c,0x9f,0xab,0xac,0xae,0x6b,0x2b,0x2a,0x30,0x2c,0x29,0x32,0x5d,0xaf,0xa6,0xb7,0x45,0x44,0xbe,0xb5,0xc6,0xcf,0xc0 +,0x76,0x2c,0x2a,0x59,0xaa,0x9c,0x9d,0xb7,0x2d,0x22,0x27,0x2a,0x31,0x49,0xdf,0x5b,0x33,0x2f,0x47,0xb9,0xa4,0x9f,0xab,0xbe,0xde,0x34,0x27,0x2c,0x46,0xda,0x6c,0x53 +,0x70,0xba,0xa0,0x9e,0xbb,0x32,0x3d,0xd1,0x4f,0x32,0x2f,0x27,0x1d,0x1d,0x2b,0xea,0xa3,0x98,0x9b,0xa6,0xac,0xaa,0xc5,0x2d,0x28,0x31,0x2c,0x24,0x23,0x27,0x43,0xae +,0xa8,0xc4,0x4d,0xcf,0xb0,0xae,0xb1,0xba,0x5f,0x2e,0x2c,0x42,0xb9,0x9e,0x9c,0xaf,0x38,0x28,0x2a,0x2d,0x39,0xd4,0xce,0x4e,0x3d,0x31,0x2c,0x4e,0xa4,0x9c,0xa5,0xb9 +,0x61,0x2f,0x23,0x29,0x47,0x63,0x49,0x46,0x3d,0x49,0xad,0x9d,0xa2,0xb0,0xbe,0xce,0x46,0x2f,0x29,0x25,0x26,0x2c,0x2e,0x31,0xc2,0xa2,0xa8,0xb9,0xb7,0xac,0xaa,0xb7 +,0xc7,0x4f,0x2f,0x28,0x23,0x1f,0x34,0xac,0xa4,0xb1,0xcd,0x4d,0x3b,0x37,0x79,0xb6,0xca,0x4a,0x34,0x25,0x2c,0xad,0x9a,0x9c,0xaf,0x6a,0x3d,0x30,0x36,0xde,0xbe,0xd5 +,0x4f,0x36,0x28,0x2c,0xde,0xaf,0xae,0xb1,0xb9,0x55,0x2e,0x2d,0x31,0x3b,0xfc,0xec,0x3e,0x3e,0xaf,0x9c,0x9e,0xa7,0xb4,0xf8,0x5d,0xd0,0xf2,0x30,0x24,0x22,0x1c,0x18 +,0x28,0xb9,0xaf,0xb7,0xad,0xac,0xae,0xac,0xaf,0xbf,0x76,0x48,0x34,0x21,0x27,0xc3,0xac,0xb0,0xc5,0x3c,0x2f,0x37,0xd9,0xaf,0xb4,0xcd,0x3e,0x25,0x26,0xd1,0xa4,0x9f +,0xa3,0xbc,0x3a,0x2e,0x2b,0x38,0xd9,0xbb,0xc2,0x43,0x2e,0x3b,0xbc,0xaa,0xa8,0xad,0xc6,0x46,0x35,0x32,0x33,0x37,0x43,0x47,0x3d,0x3f,0xcb,0xb2,0xbc,0xce,0xdd,0x4b +,0x39,0x3e,0x53,0x52,0x58,0xc8,0xb4,0xb6,0xbc,0xba,0xc5,0xd7,0x78,0x37,0x28,0x26,0x2f,0x5f,0xb8,0xa8,0xa4,0xa9,0xb5,0xc9,0x4d,0x3c,0x3d,0x33,0x28,0x26,0x2b,0x3b +,0xca,0xae,0xa6,0xa8,0xad,0xb1,0xbc,0xce,0xea,0x49,0x30,0x2a,0x28,0x2c,0x3f,0xd8,0xbf,0xb9,0xbb,0xc6,0xc7,0xc8,0xea,0x53,0x55,0x64,0x6a,0x51,0x5f,0xea,0x6b,0x79 +,0xdb,0xe6,0xef,0xd0,0xdc,0x55,0x64,0xda,0x77,0x4c,0x51,0xec,0x7c,0x6c,0xee,0x59,0x55,0xd7,0xce,0xf6,0xe4,0xca,0xd4,0x7b,0x67,0x60,0x5b,0x6e,0xdc,0x71,0x51,0x76 +,0xe5,0x4e,0x47,0x62,0xea,0xdb,0xcd,0xd7,0x7e,0xf1,0xe0,0x6f,0x59,0x72,0xd5,0xd8,0x6e,0x57,0x54,0x61,0xed,0xeb,0xf4,0xde,0xd6,0xfb,0x53,0x49,0x54,0xdf,0xd9,0xe9 +,0xfe,0xe3,0xd6,0xed,0x59,0x66,0xed,0xe0,0xd9,0xde,0xee,0xdd,0xe0,0x57,0x4a,0x58,0xf9,0x6a,0x56,0x54,0x60,0x79,0xdc,0xe2,0x73,0xcf,0xbf,0xd2,0x54,0x58,0x72,0x66 +,0x5c,0x63,0x6a,0xf6,0xdc,0x70,0x4a,0x58,0xd4,0xe3,0x58,0xf1,0xce,0xdc,0x77,0x6b,0x5e,0x62,0xe3,0xd2,0xeb,0x5e,0x7a,0xf9,0x5d,0x61,0x7d,0xfb,0xdf,0xd2,0xe6,0x5e +,0x56,0x59,0x5d,0x5e,0xe2,0xce,0xdd,0x61,0x5b,0x60,0xf0,0xd5,0xdb,0xec,0xea,0xe2,0xe8,0x68,0x53,0x59,0xf4,0xf0,0x69,0x5d,0x5a,0x67,0xf2,0xf6,0x7c,0xea,0xcf,0xcd +,0xdb,0xe2,0xd7,0xe6,0x51,0x49,0x5a,0xec,0xe6,0x7e,0x5a,0x54,0xfe,0xde,0x66,0x5c,0xdc,0xc9,0xd3,0x6f,0x5d,0x68,0xe0,0xd2,0xe7,0x59,0x61,0xf3,0x5f,0x54,0x68,0xdf +,0xda,0xf1,0x6c,0xec,0xdc,0xef,0x5b,0x4e,0x5e,0xd8,0xdb,0x71,0x6f,0xec,0xdc,0xdd,0x6e,0x64,0xe3,0xd5,0xdd,0x70,0x56,0x5e,0x7d,0x60,0x61,0xfb,0x7d,0x6e,0x5c,0x57 +,0x7a,0xd7,0xd9,0xea,0xed,0xdd,0xcf,0xd9,0x66,0x64,0x6e,0x6d,0x66,0x55,0x56,0x77,0xe9,0xf3,0x63,0x55,0x69,0xd5,0xdb,0xee,0xdf,0xdd,0xe3,0xed,0x6c,0x6b,0xf3,0x78 +,0x5d,0x53,0x5a,0xdf,0xdc,0x6b,0x76,0xe5,0xe9,0xe9,0x6f,0x56,0x69,0xe1,0xfc,0x5c,0x5a,0xee,0xd1,0xdf,0x75,0xfe,0xfe,0xe4,0xda,0x68,0x5c,0xdc,0xdb,0x5e,0x53,0x5a +,0x7a,0xf0,0x62,0x57,0x59,0x7e,0xd9,0xe6,0xed,0xca,0xc6,0xeb,0x56,0x59,0x72,0xdc,0xec,0x5a,0x59,0x67,0x79,0x6c,0x5f,0xef,0xd9,0xf7,0x5b,0x53,0x5d,0xd8,0xca,0xd3 +,0xef,0x6b,0x6d,0xef,0xfd,0x65,0xef,0xdf,0x79,0x57,0x50,0x79,0xce,0xd4,0x72,0x5b,0x5e,0x6d,0x62,0x58,0x77,0xd3,0xd6,0x6c,0x55,0x6c,0xd3,0xcf,0xdd,0xfa,0x5e,0x5f +,0xf6,0xfa,0x7a,0xe5,0xe4,0x73,0x4f,0x48,0x56,0xea,0xdd,0xe5,0xf5,0xeb,0xd9,0xdd,0xf4,0xdf,0xd3,0xde,0x5c,0x48,0x54,0xd7,0xd7,0x61,0x58,0x68,0x7c,0x67,0x5b,0xfc +,0xd1,0xd6,0x6d,0x57,0x67,0xdc,0xd8,0xe5,0xe6,0xee,0x5c,0x59,0x5e,0x6d,0xdd,0xd5,0xe7,0x66,0x59,0x5d,0xf7,0xdb,0xdf,0x64,0x52,0x5b,0x78,0x6c,0xef,0xcf,0xd2,0xf5 +,0x65,0x61,0x7d,0xdd,0xdc,0xed,0xfe,0x72,0x64,0x5d,0x74,0xe4,0x6a,0x4f,0x54,0x5f,0x62,0xe8,0xcf,0xcf,0xd9,0xe8,0x6d,0xfe,0xdd,0xdb,0xf8,0x75,0x7b,0x54,0x46,0x55 +,0xd8,0xd8,0x7d,0x74,0x72,0x67,0x69,0x7d,0xdd,0xce,0xce,0xf3,0x51,0x59,0xe5,0xf1,0x66,0xf2,0xe2,0x70,0x5f,0x65,0xec,0xd8,0xd9,0xf9,0x5b,0x58,0x6a,0x77,0x6f,0xeb +,0xe8,0x72,0x76,0xef,0xf5,0xe4,0xd7,0xdc,0x6c,0x56,0x63,0xe2,0xe2,0xf1,0xf4,0x76,0x5f,0x4f,0x4b,0x63,0xd4,0xd7,0xf4,0xff,0xfd,0xf2,0xea,0xeb,0xdd,0xd4,0xdc,0x63 +,0x53,0x5f,0xf8,0x65,0x5f,0xe7,0xed,0x58,0x5c,0xfa,0xea,0xee,0xfb,0xf6,0xee,0xe8,0xdf,0xde,0xdf,0xe1,0x66,0x4b,0x50,0xed,0xe6,0xea,0xde,0xe4,0x6c,0x5d,0x66,0x7d +,0xf8,0xe7,0xe3,0x69,0x55,0x56,0x5b,0x79,0xd0,0xcf,0xdc,0xe9,0x71,0x60,0x6b,0xe8,0xd5,0xda,0x69,0x58,0x5a,0x59,0x58,0x5c,0x7d,0xdb,0xf9,0x59,0x78,0xda,0xd9,0xd6 +,0xd9,0xed,0x74,0x6d,0x6e,0xed,0xe0,0xfd,0x4f,0x49,0x61,0xde,0xfe,0xfa,0xde,0xf3,0x5f,0x62,0x70,0xe5,0xd4,0xd4,0xdd,0xee,0x65,0x58,0x53,0x6d,0xcf,0xd4,0x73,0x59 +,0x52,0x55,0x7b,0xde,0xe5,0xf1,0xef,0x7c,0x67,0x65,0xff,0xf2,0xf1,0xdf,0xee,0x63,0x78,0xe2,0xf8,0x7a,0xe1,0xe8,0x61,0x65,0xe8,0xe0,0x6c,0x53,0x4c,0x4f,0xfa,0xd9 +,0xdf,0xe3,0xe1,0x6f,0x5b,0xfc,0xd1,0xce,0xd4,0xdd,0x7c,0x55,0x4e,0x4d,0x50,0xe9,0xcd,0xe0,0x56,0x58,0x70,0xf8,0xea,0xdb,0xdb,0xec,0x71,0x6e,0x68,0xfb,0xde,0xf9 +,0x5d,0x6a,0xe9,0xe6,0xef,0x75,0x73,0x7e,0x6b,0x59,0x5c,0xec,0xd1,0xdf,0x5a,0x53,0x5d,0x6c,0xdf,0xd2,0xd4,0xd9,0xf0,0x56,0x52,0xff,0xd5,0xdb,0x6b,0x61,0x62,0x5a +,0x55,0x60,0xed,0xd7,0xd7,0xf9,0x60,0x63,0x6d,0xeb,0xdd,0xdb,0xda,0xdf,0xf4,0x68,0x6d,0xf9,0x75,0x59,0x53,0x5d,0x71,0xee,0xdf,0xe8,0xfe,0x79,0xf9,0xea,0xdd,0xd5 +,0xdd,0x6b,0x59,0x5b,0x5e,0x6f,0xdc,0xd3,0xde,0x71,0x57,0x54,0x66,0xe2,0xdd,0xdc,0xdb,0xf1,0x57,0x4e,0x5d,0x7e,0xfa,0xf2,0xea,0xe4,0xe1,0xe6,0xed,0xea,0xde,0xe6 +,0x6b,0x5e,0x66,0x6b,0x64,0x5f,0x63,0x69,0x76,0xf3,0xe4,0xdf,0xe8,0x71,0x5f,0x65,0xf0,0xdc,0xd1,0xd1,0xe6,0x60,0x58,0x59,0x61,0x79,0xf0,0xed,0x74,0x61,0x5e,0x62 +,0x73,0xe3,0xda,0xd9,0xdc,0xf8,0x5a,0x5b,0x78,0xdf,0xde,0xef,0xfb,0x6c,0x5a,0x5d,0x77,0xee,0xea,0xf1,0xfe,0xed,0xe0,0x7e,0x60,0x63,0x70,0x7a,0x66,0x6b,0xe5,0xdf +,0xe5,0xe7,0xea,0xeb,0xe9,0xf1,0xf8,0xee,0x6a,0x54,0x4d,0x53,0x76,0xde,0xe0,0xe5,0xe8,0xf4,0xf3,0xf1,0xf3,0xe6,0xdf,0xde,0xdf,0xfe,0x5b,0x57,0x5e,0x6a,0x79,0xf5 +,0xf2,0x6e,0x61,0xff,0xe1,0xea,0xf1,0xea,0xf2,0xec,0xe8,0x6a,0x57,0x61,0xe4,0xdd,0xe1,0xda,0xdf,0x61,0x55,0x5b,0x60,0x68,0xed,0xdc,0xd9,0xdc,0x7a,0x51,0x4f,0x6d +,0xdc,0xe1,0xef,0xf9,0x62,0x5e,0xed,0xd4,0xd3,0xdb,0xed,0x6d,0x60,0x62,0x5f,0x5a,0x68,0xe1,0xe4,0x6f,0x6a,0x6b,0x67,0xfb,0xe3,0xe1,0xeb,0xf2,0xe0,0xd8,0xda,0xef +,0x5c,0x50,0x56,0x68,0xf3,0xe4,0x79,0x5d,0x69,0xf0,0xe8,0xdf,0xdd,0xe2,0xea,0x73,0x5b,0x58,0x67,0xe3,0xdb,0xdd,0xd7,0xe6,0x57,0x52,0x67,0xf4,0xec,0xef,0x6f,0x6e +,0xf0,0xf4,0x6d,0x6c,0xf7,0xed,0x7c,0xe6,0xda,0xfb,0x60,0x6e,0xf1,0xe6,0xe0,0xec,0x72,0x6c,0x6d,0x64,0x5c,0x61,0xfe,0xec,0xe1,0xda,0xea,0x5c,0x5c,0x76,0xe9,0xe5 +,0xe5,0xe0,0xe3,0xea,0xed,0x7b,0x66,0x61,0x5d,0x62,0xfd,0xef,0x6c,0x5f,0x6d,0xec,0xe0,0xde,0xe2,0xed,0xfd,0x76,0x69,0x62,0x69,0x75,0xdf,0xcf,0xd9,0x69,0x52,0x53 +,0x6b,0xe5,0xe2,0xee,0x7c,0x6a,0x60,0x63,0xfa,0xe7,0xfb,0xff,0xe0,0xe3,0x77,0x6f,0x6c,0x7e,0xdd,0xd9,0xe8,0x61,0x5c,0x72,0x79,0x64,0x63,0x5d,0x5e,0xdf,0xcd,0xde +,0x68,0x69,0x6e,0x68,0x6f,0xdd,0xd7,0xee,0x7d,0x77,0x5f,0x6f,0xe6,0x6e,0x67,0xde,0xe6,0x56,0x4d,0x60,0xe2,0xdd,0xdb,0xdf,0x6d,0x6b,0xdf,0xed,0x5f,0x6e,0xf3,0xf2 +,0xe3,0xe0,0xf0,0x63,0x5a,0x5e,0x61,0x66,0xea,0xde,0xfb,0x70,0xf6,0xea,0xfd,0x5e,0x74,0xd3,0xd5,0x7d,0x5c,0x52,0x5c,0xda,0xce,0xda,0x79,0x68,0x66,0x57,0x54,0x74 +,0xec,0xfa,0xe2,0xe2,0x6c,0x6f,0xe7,0xeb,0x6c,0x6e,0xdf,0xe7,0x5c,0x67,0xdc,0xe0,0xf2,0x6e,0x56,0x5f,0xd4,0xd3,0x63,0x4e,0x5c,0x71,0x64,0xee,0xcf,0xd4,0xea,0x7b +,0x58,0x52,0xf7,0xdb,0xe9,0xe9,0xdf,0xe4,0x64,0x54,0x5c,0xf2,0xdf,0xe8,0x5e,0x4f,0x5f,0xde,0xd9,0xea,0x73,0xec,0xd7,0xeb,0x5e,0x6b,0xea,0xfa,0x6b,0x6c,0xf7,0xe5 +,0xe1,0xf6,0x5f,0x5e,0x6e,0x5d,0x4f,0x6e,0xce,0xce,0xe6,0x6e,0x5f,0x5f,0xeb,0xd6,0xe6,0x63,0x6e,0xed,0x69,0x5e,0x7b,0xe4,0xde,0xdf,0x69,0x4d,0x51,0x78,0xf2,0x76 +,0xdd,0xd0,0xdc,0x79,0x75,0xf9,0xf6,0x75,0x5d,0x5b,0xea,0xcf,0xd7,0x62,0x57,0x65,0xfe,0xf6,0x6e,0x5e,0x5f,0x79,0xee,0xf6,0xfd,0xe2,0xcf,0xcf,0xf2,0x5c,0x5c,0x5e +,0x5c,0x69,0xdf,0xd5,0xdf,0x73,0x5f,0x66,0xee,0xee,0x57,0x4f,0xf7,0xd1,0xdb,0x70,0x70,0xe5,0xdd,0xe4,0x72,0x5b,0x5d,0xf1,0xe5,0x78,0x71,0xf5,0xf7,0xf3,0xe1,0xe3 +,0x6e,0x57,0x4e,0x4f,0x7d,0xca,0xc8,0xe2,0x66,0x79,0xfd,0x61,0x5b,0x61,0xf9,0xd8,0xd9,0x6a,0x56,0x6f,0xdb,0xdb,0xeb,0x6d,0x57,0x4f,0x56,0x74,0xde,0xd5,0xd7,0xe2 +,0xec,0xeb,0xec,0x73,0x5b,0x53,0x62,0xdb,0xd7,0x79,0x61,0xfc,0xe3,0xf1,0x61,0x54,0x58,0xf0,0xda,0xe2,0xf6,0xed,0xee,0x76,0xee,0xdd,0xf8,0x5a,0x55,0x5a,0x6b,0xde +,0xdb,0xed,0xeb,0xdf,0xef,0x5c,0x54,0x57,0x5f,0xee,0xd3,0xdb,0x6b,0x76,0xdd,0xdf,0x7c,0x5d,0x57,0x5e,0xf9,0xe2,0xe3,0xfb,0x6e,0x7a,0xf7,0xe1,0xdd,0x6b,0x50,0x51 +,0x63,0xe3,0xdd,0xe6,0xe5,0xdd,0xe3,0xf6,0x5f,0x52,0x5d,0xe4,0xd2,0xda,0x68,0x5a,0x73,0xe1,0xdf,0x7c,0x58,0x52,0x63,0x7d,0xea,0xda,0xd6,0xe5,0x70,0xf2,0xdb,0xf5 +,0x55,0x55,0x6e,0xe1,0xdf,0x67,0x54,0xfd,0xcd,0xcf,0x6a,0x4d,0x4e,0x5c,0xeb,0xd3,0xd6,0xeb,0xfe,0x73,0x6e,0xf3,0xee,0x63,0x5a,0x70,0xe4,0xe7,0x70,0x61,0x71,0xdc +,0xd2,0xe8,0x53,0x4b,0x5a,0xdf,0xd1,0xde,0x75,0x7e,0xe8,0xe8,0xee,0x72,0x5b,0x58,0x6a,0xe5,0xde,0xeb,0x7a,0x70,0xf3,0xe2,0xfb,0x5a,0x56,0x66,0xea,0xd8,0xdc,0x7a +,0x6e,0xec,0xda,0xda,0x6f,0x50,0x4e,0x67,0xdc,0xdd,0x6f,0x65,0xf3,0xe5,0xe9,0xf7,0x6a,0x5f,0x65,0xf2,0xdd,0xde,0xea,0xf5,0xff,0xfe,0xee,0x70,0x54,0x53,0xff,0xd8 +,0xd9,0xfd,0x5e,0x65,0xe7,0xd8,0xe0,0x67,0x59,0x5f,0x6f,0xed,0xe3,0xe7,0xe9,0xeb,0xfe,0x6e,0x73,0x6c,0x60,0x73,0xdd,0xdb,0x72,0x58,0x63,0xe2,0xda,0xec,0x65,0x5a +,0x5c,0x6d,0xe5,0xd8,0xdd,0xf2,0xfa,0xf0,0xf3,0xfc,0x6b,0x5e,0x71,0xde,0xec,0x5a,0x56,0x75,0xde,0xdf,0xe4,0xfa,0x59,0x53,0x7b,0xd5,0xd3,0xdd,0xf7,0x63,0x65,0x78 +,0xfb,0x72,0x6c,0x79,0x7c,0x69,0x6b,0x70,0x7e,0xdc,0xd3,0xe9,0x5b,0x56,0x65,0xe7,0xdb,0xe1,0xf9,0x64,0x60,0x7e,0xe2,0xdc,0xec,0x5f,0x5a,0x6d,0xf3,0xf5,0x7d,0xfc +,0xe5,0xe7,0x68,0x5a,0x60,0x7e,0xe5,0xde,0xe2,0x7b,0x5d,0x5f,0xea,0xd7,0xdd,0x75,0x5b,0x5c,0xff,0xf2,0x73,0x78,0xf3,0xef,0xfd,0x7a,0x7c,0x71,0x6e,0xf9,0xea,0xf5 +,0xff,0x79,0xfd,0xe3,0xe1,0x73,0x5a,0x5b,0x68,0xed,0xdc,0xe4,0x67,0x5c,0x75,0xe1,0xe0,0xe6,0xef,0x6f,0x5f,0x5f,0x63,0x7c,0xdc,0xdc,0x77,0x66,0x70,0x6f,0x69,0x7e +,0xdd,0xdb,0x7d,0x58,0x58,0x7d,0xd9,0xd8,0xef,0x65,0x62,0x62,0x6f,0xed,0xe6,0xe8,0xf1,0x72,0x68,0x75,0xf0,0xe9,0xec,0x71,0x66,0x60,0x5f,0x6f,0xed,0xe0,0xdd,0xf4 +,0x5d,0x5e,0x78,0xe5,0xdb,0xe6,0x6f,0x69,0x6b,0x73,0xfe,0xf3,0xe8,0xf0,0x64,0x5b,0x5f,0x6f,0xe8,0xdc,0xe3,0xee,0x7a,0x69,0x72,0xed,0xe5,0xed,0x6d,0x60,0x66,0x71 +,0xf1,0xde,0xe3,0x6f,0x60,0x61,0x6e,0xee,0xea,0xed,0xec,0xef,0x73,0x64,0x69,0xe9,0xde,0xf7,0x66,0x5e,0x62,0xf6,0xdf,0xdc,0xde,0xee,0x64,0x5c,0x63,0x74,0xf1,0xee +,0xf7,0x76,0x69,0x77,0xea,0xf1,0xfc,0xeb,0xeb,0x6c,0x5e,0x68,0xe9,0xda,0xdf,0x7e,0x63,0x64,0x7e,0xfc,0x6c,0x74,0x79,0x6a,0x73,0xea,0xe2,0xe3,0xf1,0x7d,0xff,0x6d +,0x6a,0x79,0xf2,0xe9,0xf2,0x6e,0x6c,0x6f,0x6e,0xf3,0xdf,0xea,0x71,0x5e,0x5e,0xf0,0xde,0xe3,0xf0,0x76,0x71,0x73,0x67,0x68,0xf5,0xee,0xeb,0xe9,0x7c,0x6f,0x78,0x76 +,0xfb,0xf2,0x6f,0x65,0x66,0x6c,0xf4,0xed,0xed,0xed,0x6f,0x6c,0xe7,0xe3,0xfd,0x6a,0x64,0x78,0xe9,0xf5,0x79,0xf3,0xf1,0xfc,0x6d,0x5e,0x60,0x6f,0xf4,0xe6,0xe8,0xf3 +,0xfd,0x6e,0x79,0xe4,0xe6,0x75,0x6e,0x6c,0x6c,0x76,0x79,0xfe,0xfc,0x7b,0xf6,0xee,0x79,0x68,0x66,0x71,0xe6,0xdf,0xf8,0x73,0x7b,0xf6,0xfe,0x67,0x61,0x6e,0xfd,0xef +,0xe5,0xe3,0xed,0x7b,0x6e,0x7c,0xef,0xfe,0x6a,0x64,0x68,0x7a,0xfe,0x6f,0x78,0xea,0xe2,0xe4,0xee,0x70,0x67,0x6c,0xf4,0xe6,0xed,0xf7,0xf1,0x7c,0x6b,0x6a,0x67,0x63 +,0x6e,0xed,0xe3,0xe5,0xef,0x73,0x67,0x7b,0xdf,0xe9,0x68,0x6c,0xf2,0xfd,0x71,0xfc,0xef,0xea,0xe8,0xef,0x76,0x68,0x62,0x5f,0x66,0xee,0xde,0xe5,0xfa,0xfe,0xf3,0xf5 +,0x6e,0x61,0x6a,0xf6,0xeb,0xe9,0xec,0xfc,0x7b,0xfd,0xfa,0xff,0x76,0x6f,0x6e,0x6e,0x6f,0x6e,0x6c,0x7c,0xeb,0xe5,0xe5,0xef,0x6d,0x64,0x6e,0xec,0xdf,0xe5,0xfa,0x77 +,0x6f,0x68,0x67,0x65,0x65,0x6f,0xef,0xe7,0xeb,0xf0,0xf2,0xfa,0xf7,0xeb,0xf5,0x66,0x65,0x76,0x79,0x71,0x7a,0xf2,0xf0,0xef,0xe6,0xe7,0x77,0x63,0x64,0x6b,0x7e,0xec +,0xed,0xf7,0xfc,0xfd,0x77,0x6c,0x6e,0xf8,0xe8,0xe6,0xe9,0xf4,0x73,0x6e,0x79,0xed,0xec,0x73,0x65,0x67,0x6d,0x7b,0xf3,0xf5,0xf7,0xec,0xeb,0xfb,0x77,0x7b,0x7a,0x7b +,0xef,0xe9,0xef,0xfd,0xfd,0x78,0x71,0x7e,0x77,0x5f,0x61,0xf5,0xe5,0xec,0xfb,0x78,0x77,0xf7,0xeb,0xed,0xf5,0xeb,0xe9,0x72,0x61,0x6b,0xfd,0xf3,0xec,0xec,0xf6,0x74 +,0x64,0x60,0x73,0xe4,0xdf,0xee,0x6d,0x6b,0x77,0x7e,0xff,0xfe,0xf4,0xea,0xea,0xfa,0x75,0x7e,0xef,0xef,0xfd,0x6e,0x68,0x68,0x71,0x7b,0x7a,0xf7,0xef,0x7e,0x77,0xed +,0xdf,0xe3,0xf7,0x6a,0x64,0x73,0xea,0xeb,0xfc,0xf7,0xf4,0x6a,0x5e,0x61,0x6f,0xee,0xe3,0xec,0x70,0x6c,0x7a,0xfd,0xfa,0xed,0xe9,0xf1,0x7d,0x6f,0x68,0x7b,0xe5,0xe8 +,0x75,0x6c,0x7a,0x7a,0x6a,0x64,0x72,0xee,0xea,0xf9,0x6e,0x7e,0xe5,0xe8,0x72,0x68,0x71,0xf4,0xea,0xee,0xf7,0xee,0xee,0x74,0x64,0x67,0xf9,0xea,0xf4,0x6c,0x5f,0x65 +,0xff,0xef,0xf8,0xe9,0xdd,0xe6,0x70,0x5f,0x6c,0xe2,0xdb,0xe8,0x73,0x71,0x78,0x6d,0x5f,0x61,0x7c,0xef,0xf8,0x6f,0x6f,0xec,0xdf,0xeb,0x73,0x6d,0xfd,0xea,0xed,0x78 +,0x7e,0xec,0xef,0x74,0x67,0x6e,0xea,0xe5,0x76,0x5d,0x5e,0x79,0xec,0xf7,0xf6,0xe3,0xe6,0x72,0x5e,0x5f,0xf2,0xdd,0xe1,0xf7,0x73,0x74,0x7c,0x79,0x6f,0x7e,0xef,0xfb +,0x6a,0x5f,0x67,0xf4,0xe5,0xec,0x70,0x68,0x7b,0xeb,0xf5,0x7a,0xf4,0xe9,0xec,0x7e,0x73,0xed,0xde,0xe8,0x63,0x57,0x5c,0x69,0x6e,0x79,0xe9,0xe0,0xe9,0x77,0x65,0x6d +,0xe7,0xdc,0xe2,0xf9,0x73,0x70,0x71,0x75,0xff,0xef,0xec,0xf5,0x69,0x5c,0x61,0xfb,0xe7,0xec,0xf7,0xfb,0xf9,0x7e,0x6e,0x6c,0xfc,0xe9,0xef,0x73,0x7e,0xe5,0xe0,0xee +,0x76,0x6a,0x69,0x6f,0x78,0x71,0x75,0xfa,0xfd,0x72,0x6e,0x7a,0xeb,0xe2,0xed,0x72,0x6f,0xfb,0xf4,0xfd,0xf0,0xe3,0xdf,0xe7,0x6c,0x58,0x5d,0x7e,0x79,0x68,0x7b,0xe8 +,0xed,0xfe,0x7c,0x7e,0xf8,0xee,0xf4,0x76,0xf1,0xdf,0xec,0x6c,0x6e,0x7d,0x79,0x7b,0x78,0x6c,0x6e,0x7e,0x79,0x6b,0x76,0xe2,0xdd,0xed,0x71,0x6a,0x63,0x68,0x77,0xfb +,0xea,0xdf,0xe5,0xfd,0x6f,0x7e,0xf4,0x77,0x6c,0x71,0x79,0x76,0x71,0x6d,0x75,0xf2,0xf2,0x7d,0x7a,0x7a,0xfc,0xed,0xee,0xfc,0xfc,0xee,0xeb,0xec,0xf3,0x79,0x68,0x60 +,0x65,0x66,0x6b,0xee,0xe5,0xf4,0x78,0xff,0x77,0x77,0xfa,0xf5,0xee,0xe7,0xec,0x70,0x65,0x78,0xea,0xef,0x7c,0x77,0x6b,0x66,0x6f,0x76,0x7a,0xed,0xe6,0xed,0xfe,0x7b +,0x7e,0x6f,0x6a,0x72,0xf9,0xf0,0xeb,0xee,0x7d,0xf8,0xed,0xf9,0x6e,0x6e,0xfe,0xf5,0xf6,0x73,0x6a,0x6c,0x77,0xfd,0xff,0xf3,0xee,0x7d,0x72,0x7c,0xee,0xe3,0xdf,0xea +,0xfa,0xfa,0x7b,0x69,0x64,0x68,0x6e,0x78,0xf9,0x7e,0x75,0xf8,0xeb,0xf3,0x7a,0xfc,0xf0,0xf4,0xef,0xec,0xf4,0x7c,0x7b,0x79,0x6d,0x75,0xf7,0x7b,0x6b,0x6d,0x76,0x74 +,0x7c,0xee,0xe9,0xee,0xf7,0x78,0x65,0x64,0xfb,0xe8,0xe7,0xeb,0xfd,0x73,0xfe,0xf0,0xf2,0xf8,0xf7,0xfc,0x70,0x67,0x6c,0x7e,0xf9,0xfc,0x78,0x7c,0xf6,0x7d,0x70,0xf3 +,0xe4,0xe9,0xf1,0x7e,0xfe,0xea,0xe8,0x7e,0x67,0x64,0x6c,0x6d,0x6b,0xfb,0xec,0xf9,0x7d,0xfe,0x74,0x7e,0xe9,0xe6,0xeb,0xee,0xf4,0x75,0x6a,0x73,0xee,0xec,0xf8,0x75 +,0x62,0x62,0xf8,0xec,0xfa,0xfc,0xf9,0xf9,0xfd,0x7e,0xf9,0xfb,0x7d,0xf7,0xfb,0x79,0xf9,0xf7,0xf8,0xeb,0xec,0x77,0x6c,0x74,0xf7,0xf1,0xf8,0x79,0x6e,0x67,0x6c,0x7e +,0xef,0xe7,0xee,0x71,0x74,0xf7,0xf8,0xf3,0xeb,0xe7,0xe4,0xf0,0x68,0x60,0x6b,0xf9,0xf7,0x74,0x71,0x6f,0x67,0x6d,0xf5,0xe9,0xe4,0xe9,0x7e,0x75,0xee,0xe9,0xf8,0x71 +,0x76,0xfc,0x7c,0x74,0x70,0x6f,0x7c,0xf1,0x7c,0x66,0x6d,0xed,0xe6,0xeb,0xf1,0xfc,0x70,0x6c,0x6f,0x7d,0xe7,0xdf,0xfa,0x61,0x6a,0xed,0xea,0xfb,0xfb,0xf2,0xf9,0x6e +,0x62,0x63,0xfd,0xe6,0xf2,0x75,0x76,0x79,0x7a,0xfc,0xee,0xeb,0xeb,0xf6,0x7a,0xff,0xef,0xee,0x76,0x67,0x67,0x69,0x6f,0xfe,0x7e,0x74,0xfe,0xf6,0xfe,0x7d,0xf0,0xe5 +,0xe4,0xef,0x78,0x6c,0x6d,0xfe,0xf4,0xed,0xea,0x7d,0x5e,0x5c,0x6c,0xf8,0xef,0xef,0xf9,0xfb,0xf7,0xfc,0x79,0xfb,0xed,0xf5,0x6e,0x71,0xf7,0x78,0x71,0xee,0xe5,0xf3 +,0x6f,0x6c,0x7b,0xf2,0xf1,0x78,0x69,0x6b,0x79,0x7a,0x7c,0xea,0xe7,0xff,0x6c,0x73,0xf8,0xeb,0xe6,0xe9,0xec,0xf7,0x71,0x66,0x64,0x70,0xf1,0xf4,0x74,0x68,0x64,0x71 +,0xec,0xe6,0xea,0xf8,0x79,0x74,0x71,0x77,0xf0,0xed,0x7c,0x71,0x7d,0xf8,0x78,0x6f,0x76,0xfc,0x7b,0x6e,0x6f,0x79,0xee,0xe5,0xed,0x76,0x72,0x7b,0x75,0x73,0xf0,0xe4 +,0xf7,0x69,0x73,0xf0,0xf1,0xfe,0x7e,0x7e,0xfb,0xfa,0x6e,0x63,0x6f,0xec,0xef,0x74,0x6c,0x74,0x7c,0xfd,0xf3,0xed,0xed,0xef,0xf2,0xf1,0xed,0xee,0x79,0x69,0x66,0x6a +,0x6f,0x75,0x7a,0x7c,0xff,0xfc,0xf7,0xfb,0xfa,0xec,0xe9,0xf2,0x7e,0x76,0x77,0xfe,0xf7,0xf1,0xf8,0x6e,0x68,0x6d,0x7a,0xfd,0xfa,0xf9,0xf7,0xf9,0xf7,0xf9,0x7a,0xfe +,0xf6,0x7a,0x6f,0xfd,0xf3,0x7a,0x7c,0xec,0xea,0xfe,0x6a,0x6b,0x7e,0xed,0xf0,0x6e,0x66,0x79,0xec,0xf5,0x7a,0xfe,0xfa,0xfd,0x78,0x73,0x7c,0xef,0xe8,0xee,0xf1,0xed +,0xf6,0x6c,0x64,0x6e,0xfb,0xfc,0x71,0x68,0x6d,0xf3,0xea,0xf5,0x75,0x7a,0xef,0xea,0xf9,0x71,0x79,0xf3,0xee,0xf9,0x7c,0x7c,0x77,0x6f,0x6d,0x72,0x7c,0x7d,0x77,0x78 +,0xef,0xe5,0xed,0x76,0x6c,0x76,0xf8,0xf7,0xfe,0x7c,0x7c,0xfa,0xec,0xee,0xfe,0x78,0x7b,0x7b,0x77,0x73,0x70,0x70,0x79,0xfc,0xfc,0xfd,0xf8,0xf9,0x79,0x79,0xfc,0x7d +,0x7a,0x7d,0xef,0xe5,0xe8,0xfe,0x69,0x65,0x6d,0xfd,0x7d,0x6f,0x71,0x7d,0xf6,0xf6,0x7d,0x7a,0xfc,0xf2,0xf4,0x7e,0x78,0xff,0xfa,0xfc,0xf1,0xeb,0xf7,0x71,0x68,0x6a +,0xfe,0xf2,0x7b,0x6d,0x78,0xec,0xe5,0xef,0x75,0x6e,0x73,0x7c,0x7b,0x79,0xf8,0xee,0xf3,0xf6,0xf2,0xfc,0x76,0x77,0x7b,0xfe,0x7c,0x6c,0x67,0x6e,0xf4,0xe8,0xef,0x74 +,0x6d,0x6f,0x77,0xf7,0xef,0xf5,0xf5,0xf1,0xee,0xef,0x7e,0x72,0x6e,0x6e,0x6f,0x6f,0x6d,0x72,0xf7,0xee,0xf2,0xfc,0x76,0x72,0x7d,0xf7,0xf6,0xfc,0xff,0xfd,0xfe,0xf8 +,0xed,0xee,0x7b,0x6e,0x6b,0x6b,0x6f,0x74,0x7e,0xf2,0xeb,0xf0,0x79,0x6d,0x6f,0xff,0xf7,0xfa,0xfc,0xfe,0xfe,0xfb,0xf0,0xe9,0xf0,0x73,0x6c,0x72,0x77,0x77,0x78,0x79 +,0xfe,0xf4,0xf4,0x79,0x6f,0x7b,0xfc,0x7c,0xff,0xf8,0xfc,0xfe,0xed,0xe7,0xed,0xf9,0x73,0x68,0x68,0x7d,0xf4,0x75,0x71,0xf9,0xf4,0xfd,0xfd,0x7d,0x7a,0xf3,0xed,0x7d +,0x6d,0x7a,0xef,0xf5,0xf5,0xeb,0xf5,0x6f,0x6b,0x6f,0x79,0xfa,0x7e,0x72,0x78,0xee,0xea,0xf9,0x70,0x75,0xfe,0x7a,0x77,0x7a,0xfb,0xef,0xed,0xf3,0xf6,0xfc,0x75,0x77 +,0x7b,0xfc,0xfc,0x75,0x6e,0x74,0xf5,0xe9,0xed,0x79,0x6f,0x72,0x75,0xfb,0xf4,0xfa,0xf7,0xec,0xeb,0xf8,0x77,0x75,0x73,0x70,0x79,0x7c,0x6f,0x6e,0xfa,0xee,0xed,0xef +,0x7c,0x6d,0x72,0xf8,0xf4,0xfb,0xfb,0xfd,0x7c,0xfa,0xec,0xef,0x74,0x6b,0x6c,0x72,0x7b,0x7b,0x75,0xfc,0xe7,0xe5,0xfc,0x6d,0x6e,0x78,0x7e,0xfa,0xf8,0xfd,0x7a,0x7c +,0x7d,0xf9,0xf0,0xfa,0x6f,0x6e,0x7a,0x7d,0x7a,0x74,0x78,0xf0,0xe7,0xf4,0x6c,0x6a,0x77,0xf8,0xf8,0xfe,0x7d,0xfc,0xec,0xec,0xfd,0x7c,0xfc,0x71,0x68,0x6f,0x7e,0xfe +,0xfc,0xfb,0xfa,0xf0,0xef,0x79,0x6c,0x7a,0xee,0xfa,0x71,0x76,0xfd,0xf2,0xe8,0xec,0x78,0x6f,0x73,0x72,0x6e,0x78,0xf7,0xf7,0xf5,0xef,0xf3,0x7e,0xfe,0xfc,0x74,0x70 +,0x7e,0xf9,0xfe,0x7b,0xf7,0xec,0xee,0xf9,0x75,0x6f,0x7a,0xf8,0xfe,0x78,0x7d,0xfa,0xf4,0xf4,0xff,0x77,0x71,0x74,0x75,0x75,0x78,0xfc,0xf1,0xec,0xeb,0xf3,0xff,0x74 +,0x6c,0x6d,0x7d,0xf7,0x7e,0x72,0x71,0xfd,0xee,0xf0,0x7a,0x75,0xfb,0xf9,0x73,0x6d,0x7e,0xf0,0xef,0xef,0xf9,0x7d,0x79,0x72,0x6f,0x70,0x7c,0xfa,0xfc,0xfd,0xee,0xed +,0xf9,0x76,0x6f,0x75,0x7b,0xfc,0xfd,0x79,0x76,0xfb,0xf0,0xf6,0xfd,0xfc,0xfe,0x7c,0x74,0x6c,0x72,0xf8,0xf2,0xf1,0xf1,0xf2,0x7e,0x6d,0x6b,0x72,0xfb,0xee,0xf0,0x7c +,0xf8,0xec,0xf0,0x7e,0x74,0x6f,0x71,0x7c,0x7c,0x70,0x6f,0xfe,0xee,0xf3,0xfe,0x7b,0x7d,0xf9,0xf8,0x72,0x6f,0xf9,0xf0,0xf5,0xf3,0xeb,0xed,0x7a,0x65,0x65,0x72,0xf4 +,0xef,0xfd,0xf9,0xe9,0xed,0x75,0x6c,0x77,0xf3,0xef,0x7e,0x73,0x76,0xfc,0xf2,0xf6,0xf2,0xec,0xef,0x79,0x6e,0x6d,0x71,0xfa,0xf2,0xfa,0xf7,0xef,0xf4,0x7b,0x6d,0x6d +,0x79,0xff,0xfb,0x7e,0xfe,0xed,0xe9,0xf5,0x7c,0x7b,0x77,0x76,0x74,0x73,0x7b,0xfd,0x7d,0x75,0x7b,0xf2,0xed,0xf7,0x7d,0x7d,0x73,0x77,0xf8,0xfa,0xf8,0xec,0xec,0xfd +,0x6e,0x6a,0x6e,0x7b,0xf8,0xfa,0x79,0x7e,0xed,0xf0,0x79,0x7b,0xf9,0xfb,0x75,0x6e,0x74,0xfa,0xf8,0x7b,0x78,0xf6,0xeb,0xf1,0x75,0x73,0x7b,0x7d,0x79,0x78,0x7c,0xf2 +,0xe9,0xf3,0x74,0x6f,0x71,0x75,0x7c,0xfa,0xf5,0xf5,0xf8,0xfa,0x7c,0xfc,0xf4,0xf9,0x74,0x6f,0x75,0x7a,0x7b,0x7a,0xfc,0xef,0xec,0xfa,0x6f,0x72,0xfa,0xf2,0xf9,0x7a +,0x7a,0xfe,0xf3,0xf2,0xf7,0xfa,0x7a,0x6e,0x6a,0x74,0xf8,0xf2,0xf5,0xf7,0xfa,0xfb,0xfb,0xfa,0xfc,0xfd,0xf8,0xfd,0x77,0x74,0x78,0xf8,0xec,0xed,0xfe,0x71,0x71,0x77 +,0x7a,0x7a,0xfa,0xf0,0xf5,0x7a,0x73,0x79,0xf8,0xf5,0x79,0x73,0x7a,0xfd,0xfb,0xfe,0xfd,0xf1,0xed,0xfd,0x6f,0x70,0x7e,0xfd,0x79,0x71,0x74,0xfe,0xf4,0xf2,0xfc,0xf7 +,0xee,0xf9,0x70,0x73,0xfe,0xf8,0xf6,0xfd,0x7e,0xf9,0xfb,0x7d,0x75,0x74,0xff,0xfb,0x77,0x75,0xfd,0xf1,0xee,0xf8,0xff,0xf8,0xfd,0x72,0x72,0x7a,0xfd,0xf9,0x7e,0x79 +,0xfe,0xf2,0xf2,0xf8,0x7a,0x74,0x79,0x77,0x7e,0xf5,0xf5,0xf7,0xfb,0x79,0x76,0x78,0x7c,0xfa,0xf9,0x7d,0x7b,0xff,0xf6,0xee,0xf2,0xfc,0x7d,0x75,0x6e,0x73,0x7b,0xfd +,0xf0,0xee,0xf7,0xfb,0xfa,0xfa,0xfb,0xfc,0xf9,0x7d,0x75,0x77,0xfd,0xf1,0xed,0xf0,0x7e,0x73,0x73,0x7a,0xf7,0xf5,0xf7,0xfb,0x7e,0x7b,0x7c,0xf9,0xee,0xef,0xff,0x70 +,0x70,0x7c,0xfb,0xf7,0xf1,0xed,0xf5,0x75,0x70,0x77,0xfe,0xfc,0xff,0x7a,0x79,0x7c,0x7d,0xf7,0xef,0xef,0xf9,0x75,0x71,0x77,0x7d,0xff,0xfa,0xf4,0xf1,0xf9,0x7d,0x7c +,0x7e,0xff,0xfe,0x76,0x6d,0x72,0xfd,0xf1,0xee,0xf1,0xf9,0x7c,0x7b,0x7d,0xfe,0xfb,0xfa,0xfb,0x78,0x7a,0xfc,0xfb,0xfe,0xfe,0xff,0x78,0x70,0x70,0x7e,0xf1,0xee,0xf1 +,0xfe,0x7b,0x7d,0x7a,0x77,0x7d,0xfc,0x7e,0x7a,0x7c,0xf4,0xee,0xf4,0x7d,0x7d,0x77,0x6f,0x72,0x7d,0xf1,0xf0,0xfb,0xff,0xfe,0x7c,0xfe,0xf4,0xf6,0xfe,0x78,0x6f,0x71 +,0xfb,0xed,0xeb,0xee,0xfd,0x74,0x6f,0x73,0x7a,0xfa,0xf5,0xf3,0xf6,0x7c,0x7a,0x7d,0xff,0xfe,0xfd,0x7d,0x7d,0xf9,0xfb,0xfd,0xf1,0xec,0xf7,0x6f,0x6e,0x7b,0xf6,0xf8 +,0xff,0x7b,0x7e,0x7e,0xfe,0xf4,0xed,0xed,0xf6,0x70,0x6a,0x71,0x79,0x7e,0xf3,0xef,0xef,0xf6,0x77,0x6f,0x78,0x7e,0x7b,0x7d,0x7c,0x76,0x74,0xfc,0xee,0xef,0xfb,0x7e +,0x7e,0x76,0x79,0xfd,0xfd,0x7c,0xfa,0xf3,0xfa,0x7c,0x78,0x75,0x78,0x7d,0x78,0x73,0x7a,0xf5,0xec,0xee,0xfb,0x76,0x75,0x75,0x7a,0xf7,0xf6,0xff,0x76,0x74,0x78,0x7d +,0x76,0x7d,0xf1,0xf9,0x70,0x6f,0x79,0xfb,0xf4,0xf5,0xf5,0xf0,0xf8,0x78,0x6e,0x73,0xfc,0xfc,0x75,0x73,0xf8,0xec,0xee,0xfc,0x73,0x72,0x75,0x74,0x7d,0xef,0xed,0xf5 +,0xfe,0x78,0x72,0x78,0xfc,0xf9,0xfd,0xfc,0x7e,0x76,0x77,0xf6,0xeb,0xea,0xf9,0x6e,0x6b,0x73,0x7c,0x7e,0xfd,0xf8,0xf1,0xf6,0xfe,0x7e,0xfd,0xf7,0xf7,0x7a,0x74,0x7e +,0xfa,0x7d,0xfc,0xef,0xf0,0x7a,0x6e,0x76,0xfd,0xfa,0xf7,0xfd,0x71,0x74,0xf9,0xed,0xee,0xf2,0xfd,0x70,0x6c,0x6e,0x78,0xf9,0xef,0xee,0xf7,0x76,0x6e,0x70,0x7c,0xfa +,0xfa,0xfa,0xfb,0x7d,0x7c,0xf9,0xf1,0xf1,0xfe,0x70,0x71,0x77,0xfc,0xf6,0xfb,0xfd,0xfd,0xfb,0xfc,0xfe,0x7b,0x7d,0xfe,0x77,0x70,0x76,0xfa,0xf0,0xed,0xee,0xf4,0x74 +,0x6b,0x6e,0x78,0xfb,0xf7,0xfb,0x73,0x71,0xfe,0xf7,0xf9,0xfe,0xff,0x78,0x70,0x72,0x7c,0xf4,0xee,0xef,0xf9,0x7b,0x75,0x74,0x79,0x7e,0x7c,0x7e,0x7d,0x78,0x7e,0xf6 +,0xf0,0xfa,0x78,0x71,0x70,0x74,0xfe,0xf0,0xf3,0xfb,0x7e,0x78,0x76,0x7c,0xfd,0xff,0xff,0x7e,0x79,0x74,0x79,0xf9,0xed,0xed,0xf6,0x75,0x6d,0x75,0xfc,0xf7,0xf8,0xfd +,0x7d,0x79,0xfd,0xf7,0xf7,0xfa,0x7e,0x77,0x72,0x78,0xf6,0xf1,0xf2,0xf4,0xff,0x77,0x71,0x75,0x7d,0xf8,0xf5,0xfb,0x7d,0x79,0xfc,0xf2,0xf0,0xfa,0x74,0x6e,0x6e,0x73 +,0x7e,0xf3,0xef,0xf7,0x7e,0x78,0x76,0x7b,0xff,0xfc,0xfb,0xfd,0x7d,0x7b,0xfe,0xf9,0xf2,0xf1,0xfd,0x71,0x6d,0x75,0xfc,0xf8,0xf9,0xfd,0x7c,0x7e,0xfb,0xfa,0xfe,0x7c +,0x7c,0x74,0x71,0x7b,0xf2,0xf0,0xf9,0xfd,0x7d,0x7a,0x75,0x75,0x7c,0xf7,0xf3,0xfc,0x76,0x78,0xf6,0xef,0xf6,0x7b,0x75,0x73,0x78,0x7c,0xfd,0xf4,0xf0,0xf5,0xff,0x7d +,0x7d,0x7c,0x7c,0x7b,0x7d,0x7e,0xfd,0xff,0xfe,0xfd,0xf7,0xf8,0x7d,0x76,0x77,0xfd,0xf9,0xf9,0x7e,0x7e,0x7e,0x7e,0xfb,0xf4,0xf3,0xfe,0x74,0x6e,0x77,0xf8,0xef,0xf3 +,0xf9,0xf8,0xfd,0x77,0x6f,0x76,0xfc,0xf7,0xfa,0x7c,0x7c,0xfe,0xf6,0xf3,0xf9,0x7b,0x74,0x75,0xfe,0xf5,0xf9,0xfe,0xfb,0xf9,0xff,0x7e,0x7c,0x7a,0x7b,0x7a,0x7c,0x7c +,0xfc,0xfa,0xfb,0xfb,0xf3,0xf8,0x76,0x6e,0x75,0xfd,0xf6,0xf7,0xfe,0x7c,0x78,0x79,0x7d,0xfb,0xf9,0xfb,0x7a,0x76,0x77,0x7c,0xf8,0xf6,0xf8,0xf8,0xfc,0x78,0x70,0x71 +,0x7a,0xfb,0xf7,0x7e,0x7d,0xfb,0xf2,0xf1,0x7a,0x70,0x74,0x78,0x7e,0xff,0x7e,0xfe,0xfc,0x7e,0x77,0x78,0x7c,0x7c,0x7b,0xfe,0xfa,0xfe,0x74,0x77,0x7d,0xf8,0xf1,0xfa +,0x77,0x6f,0x73,0x7e,0xfa,0xfa,0xfb,0x7e,0x7b,0x7c,0x7b,0x7b,0xfc,0xfa,0xff,0x7a,0x77,0x7a,0xfc,0xf9,0xff,0x7c,0x79,0x7c,0x7b,0x79,0xff,0xf9,0xfa,0xfd,0x7e,0x7e +,0xf8,0xf3,0xf9,0x7a,0x74,0x74,0x78,0x7b,0xfd,0xf5,0xf2,0xf7,0x7c,0x72,0x73,0x7a,0x7e,0xfa,0xf5,0xf8,0x7c,0x75,0x76,0xfa,0xf0,0xf0,0xfa,0x74,0x71,0x7c,0xfb,0xfa +,0xfc,0xfe,0x79,0x77,0x77,0x7b,0xfb,0xfb,0xfd,0x78,0x71,0x79,0xf7,0xf0,0xf2,0xfb,0x79,0x75,0x74,0x7a,0xfe,0xf9,0xf7,0xfb,0x78,0x73,0x79,0xfb,0xf6,0xf9,0x7b,0x74 +,0x76,0x75,0x7c,0xfa,0xf2,0xf0,0xfd,0x74,0x72,0x7a,0xfc,0xf8,0xf8,0xfb,0xfe,0x79,0x75,0x78,0xfb,0xfa,0xfe,0x71,0x72,0xfe,0xf4,0xf1,0xfc,0x7d,0x7a,0x79,0x78,0xff +,0xf7,0xf4,0xf7,0x78,0x6e,0x74,0xf8,0xef,0xf3,0x7d,0x77,0x74,0x71,0x72,0x7e,0xf4,0xf0,0xf6,0x7a,0x78,0x7a,0xfb,0xf8,0xfb,0xfe,0x7d,0x76,0x71,0x7d,0xf2,0xee,0xf8 +,0x74,0x6f,0x74,0x7d,0xfb,0xf6,0xfc,0x7e,0x7b,0x79,0x7c,0xfa,0xf1,0xf1,0xff,0x6f,0x71,0x79,0xf5,0xef,0xf5,0xfe,0x74,0x73,0x73,0x7d,0xf5,0xef,0xf4,0x79,0x72,0x79 +,0xfe,0xf5,0xf5,0xf9,0xfb,0x79,0x76,0x77,0x7d,0xf9,0xf9,0x7d,0x78,0x7a,0x7b,0xfe,0xf7,0xf9,0x7c,0x79,0x76,0x7a,0xfc,0xf4,0xef,0xf8,0x79,0x73,0x75,0x7d,0xf7,0xf7 +,0xfe,0x7b,0x78,0x73,0x76,0x7e,0xf5,0xf3,0xfb,0x73,0x71,0x7b,0xf6,0xf3,0xf9,0xfb,0x7a,0x75,0x79,0x7c,0x7b,0xfe,0xfc,0x79,0x75,0x7c,0xfc,0xfb,0x7e,0x7e,0x79,0x70 +,0x73,0x7d,0xfa,0xf6,0xf6,0x7c,0x74,0x7a,0xfa,0xf7,0xf6,0xfc,0x7c,0x76,0x72,0x76,0xfe,0xf5,0xf5,0x7e,0x74,0x70,0x72,0x79,0xfb,0xf9,0xfd,0xfe,0x7d,0x7b,0x7e,0xfc +,0xf9,0xfe,0x7b,0x7a,0x7b,0xfe,0xf5,0xf5,0xfe,0x79,0x78,0x77,0x7b,0xf8,0xf7,0xfe,0x7b,0x79,0x7c,0xfd,0xf8,0xf5,0xf9,0xfc,0x7b,0x71,0x73,0x7e,0xf7,0xf7,0xf9,0xfb +,0x79,0x77,0x7e,0xfb,0xfc,0xff,0x7d,0x78,0x7a,0xfd,0xfc,0xfd,0xfa,0xfc,0x7b,0x79,0xff,0xfd,0xfe,0xfe,0x7c,0x7b,0x7b,0x7d,0xff,0x7e,0xfd,0x7c,0x76,0x78,0xfb,0xf6 +,0xf4,0xf3,0xf8,0x7c,0x74,0x77,0x7b,0x7d,0xfe,0xfe,0x7c,0x7a,0x7c,0xfc,0xfd,0xfe,0xfd,0xfd,0x7d,0x7a,0x79,0x7b,0xfd,0xf5,0xf8,0x79,0x75,0x7a,0xfc,0xfc,0x7d,0x7a +,0x79,0x79,0x7d,0xfb,0xf8,0xfa,0x7c,0x78,0x78,0x7a,0xff,0xfe,0xfd,0xfb,0xfd,0x7c,0x77,0x7c,0xfb,0xf8,0xf6,0xf9,0x7e,0x77,0x7c,0xf9,0xf6,0xf7,0xfc,0x7a,0x73,0x75 +,0x7a,0x7b,0xfb,0xf9,0x7e,0xfe,0xfa,0xf8,0xfa,0xfd,0xfe,0xff,0x7c,0x79,0x78,0x7d,0xf9,0xf6,0xfa,0x7c,0x7a,0x7b,0xfb,0xf5,0xf7,0x7e,0x7c,0x7b,0xfe,0xfa,0xfb,0xfc +,0xfd,0xfc,0x7e,0x78,0x79,0xfb,0xf7,0xf4,0xf2,0xf7,0x7c,0x77,0x79,0xfe,0xfa,0xfe,0x76,0x75,0x7c,0xf8,0xf3,0xf7,0xfc,0xfd,0x7d,0x7c,0xfe,0xfd,0xf8,0xf8,0xfe,0x7e +,0xfe,0xfe,0xfe,0xfc,0xfc,0x7e,0x79,0x78,0x7b,0xfc,0xf5,0xef,0xf7,0x7c,0x79,0x7a,0xfd,0xf9,0xfb,0x7b,0x78,0x7b,0x7d,0xfc,0xfa,0xfa,0xfb,0xfd,0xfc,0xfe,0x7a,0xff +,0xff,0x7d,0xfd,0x7e,0x74,0x74,0x7c,0xfa,0xf9,0xfd,0x7c,0x77,0x7d,0xf6,0xf3,0xf8,0x7e,0x79,0x76,0x75,0x7b,0x7c,0xfd,0xf8,0xfc,0x7b,0x7a,0x7e,0xfb,0xf8,0xf9,0xfd +,0x7b,0x79,0x79,0x7b,0xfc,0xf5,0xfd,0x75,0x72,0x75,0x7a,0xfd,0xf8,0xf9,0xfd,0x7d,0x7c,0xfc,0xf8,0xf6,0xf9,0x7d,0x77,0x74,0x77,0x7e,0xfb,0xfc,0xfd,0xfe,0x77,0x77 +,0x7e,0xf8,0xf5,0xfa,0x7a,0x76,0x7c,0xf6,0xf4,0xfd,0x7c,0x7d,0x7b,0x78,0x7b,0xfe,0xfb,0xfb,0xfb,0xfe,0xff,0xff,0x7c,0x7e,0xfe,0x7e,0x78,0x74,0x79,0xff,0xff,0xfb +,0xff,0x7c,0x7e,0xfd,0xfa,0xfc,0xfb,0xfd,0x7d,0x7b,0x79,0x77,0x78,0x7d,0xfa,0x7d,0x78,0x77,0x7c,0xf9,0xf4,0xf3,0xf9,0x7e,0x76,0x75,0x7d,0xf8,0xf7,0xfc,0x7b,0x78 +,0x7a,0xfb,0xf6,0xfc,0x7b,0x78,0x77,0x76,0x7b,0xfd,0xfa,0xfb,0xfc,0x7d,0x77,0x7a,0xfb,0xf9,0xfd,0x7a,0x79,0x79,0x7e,0xf7,0xf5,0xfc,0x79,0x75,0x77,0x7c,0xfe,0x7d +,0x7a,0x7c,0xfc,0xfb,0x7e,0x7c,0x7b,0xfe,0xf9,0xfa,0x7e,0x7a,0x7e,0xfd,0xfd,0xfd,0x7d,0x7b,0x7a,0x7c,0x7e,0x7e,0xfe,0xfe,0xfe,0xfa,0xfa,0xfa,0xfb,0xfb,0xfd,0xff +,0x7d,0x7a,0x7b,0xfc,0xf8,0xfb,0x7e,0x79,0x74,0x75,0xfd,0xf4,0xf6,0x7e,0x7a,0x7a,0xfe,0xf7,0xf7,0x7e,0x78,0x78,0x7c,0xfd,0xf7,0xf6,0xfc,0x7e,0xfd,0xfa,0xfd,0x7c +,0x7a,0x7c,0xff,0x7b,0x79,0x7b,0xfc,0xf6,0xf7,0x7e,0x77,0x77,0x7b,0xfa,0xf7,0xfb,0xff,0x7c,0x7d,0xfb,0xfb,0xfe,0xff,0xfe,0x7d,0x79,0x78,0x79,0x7b,0xfe,0xf8,0xf5 +,0xfa,0x7e,0x79,0x7b,0xfa,0xf6,0xf8,0xff,0x7c,0x7b,0x78,0x7a,0x7e,0xfe,0x7b,0x77,0x7a,0x7d,0xfc,0xfb,0xfc,0xfc,0xfc,0x7d,0x77,0x79,0x7e,0xfd,0xfd,0x7d,0x7d,0x7d +,0xfe,0xf7,0xf4,0xf9,0x78,0x71,0x76,0xfe,0xf9,0xfe,0x7b,0x7a,0x7c,0xfe,0xff,0xfe,0xfb,0xfb,0xfe,0x7c,0x7c,0x7e,0xff,0xfb,0xf7,0xf8,0x7e,0x7b,0x7e,0x7e,0xfd,0x7e +,0xff,0x7e,0xff,0xfd,0xfc,0xfc,0x7e,0x7e,0xfe,0xfe,0xfc,0x7e,0x7e,0xfc,0xfb,0xfc,0x7d,0x7c,0x7e,0xfe,0xfe,0xfe,0xfa,0xf9,0xfc,0x7e,0xfd,0xf7,0xf6,0xfc,0x7c,0x77 +,0x79,0x7e,0xfc,0xfc,0xfd,0xfe,0x7e,0xfc,0xfc,0xfe,0x7d,0x7d,0x7d,0x7a,0x78,0x7a,0xff,0xfa,0xfa,0xfd,0x7b,0x7a,0xfe,0xfc,0xfc,0xfc,0xfd,0x7c,0x7a,0xff,0xfc,0x7e +,0x79,0x77,0x79,0x79,0x7a,0x7b,0xfe,0xf9,0xf5,0xf8,0xfe,0x7b,0x7b,0xfe,0xfe,0x7c,0x7b,0x7c,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7c,0x7b,0x7e,0xfb,0xfd,0x7e,0xfe +,0xfd,0xfe,0x7c,0x7c,0xfe,0xfd,0xfc,0xfe,0x7d,0x7e,0xfb,0xf8,0xfa,0xfb,0x7e,0x7b,0x7b,0x7d,0x7e,0xfd,0xfc,0xfc,0xfe,0xfd,0xfd,0x7e,0x7a,0x7d,0xfa,0xf9,0xf9,0xfd +,0xfd,0xf9,0xf7,0xf9,0x7e,0x78,0x78,0x7b,0xfe,0x7d,0xff,0xfb,0xf9,0xf9,0xfc,0xfb,0xfc,0x7e,0xfc,0xfc,0x7d,0x7b,0x7d,0xfd,0xfd,0xfb,0xfa,0xfb,0xff,0xfd,0xfc,0xfe +,0xfd,0xfa,0xfc,0xfe,0xfb,0xfb,0xfe,0x7d,0x7d,0x7e,0x7e,0x7c,0xff,0xfb,0xf9,0xfa,0xfd,0xfd,0xfc,0xfd,0x7b,0x7a,0x7d,0xfe,0xfd,0x7e,0xff,0xfb,0xfa,0xfa,0xfe,0x7c +,0xfe,0xfb,0xfd,0xff,0x7e,0xfe,0xfb,0xfc,0xfd,0x7e,0x7c,0x7c,0xff,0xfe,0x7e,0x7c,0xfc,0xfb,0xfb,0xf9,0xf9,0xfd,0x78,0x79,0x7e,0x7e,0xfe,0xfe,0x7d,0x7c,0x7d,0xfe +,0x7d,0x7e,0xfd,0xfd,0x79,0x76,0x7e,0xfa,0xf9,0xfa,0x7e,0x7c,0x7d,0xfe,0x7e,0x7c,0xfe,0xfe,0xff,0x7d,0x7d,0xff,0xf8,0xf6,0xfe,0x77,0x78,0x7b,0x7d,0x7e,0x7e,0x7d +,0xff,0xfd,0xfe,0xfd,0xfe,0xfd,0xfd,0xfe,0xfb,0xfa,0xfc,0xfd,0x7e,0xfe,0xfa,0xfc,0x7c,0x79,0xfe,0xfb,0xfe,0x7d,0x7c,0x7d,0xfd,0xfa,0xfe,0x7d,0xfc,0xf6,0xfc,0x7c +,0x7d,0xfc,0xf9,0xf9,0xff,0x7b,0x7b,0x7e,0x7d,0x7d,0xff,0xfa,0xf9,0x7d,0x7c,0x7e,0xfb,0xfa,0xff,0x7d,0x7e,0xfd,0xfc,0x7e,0xfe,0xfc,0xfc,0xfd,0xfe,0xfd,0xfd,0xfd +,0x7e,0x79,0x7b,0xff,0xfe,0xfe,0xfe,0xfc,0xfd,0xff,0x7c,0xff,0xf9,0xf5,0xfa,0x7b,0x79,0x7d,0xfc,0xfc,0x7d,0x79,0x7c,0xfd,0xfb,0x7d,0x7c,0xfe,0xfe,0xfe,0xfe,0x7e +,0x7d,0xfb,0xf9,0xff,0x7b,0x7e,0x7d,0x7d,0xfe,0xfb,0xfd,0x7e,0x7c,0x79,0x7b,0xfe,0xfd,0xff,0xff,0xfc,0xfd,0x7c,0x7e,0x7e,0xfb,0xfa,0xfe,0x7c,0x7b,0x7e,0x7e,0x7d +,0xff,0xfb,0xfb,0xfe,0x7d,0x7c,0x7e,0xfd,0xfd,0x7d,0x7b,0x7e,0xfc,0xfb,0xfc,0xfe,0x7e,0xfd,0xfc,0xfe,0xfe,0xfb,0xfb,0xfd,0x7e,0x7e,0xff,0xfe,0xfc,0xff,0x7e,0x7b +,0x7c,0x7c,0xfc,0xf6,0xf4,0xfa,0xfc,0xfd,0xfc,0xfd,0x7e,0xfe,0x7e,0xfc,0xfc,0xfe,0x7d,0xfd,0xfb,0xfe,0x7c,0x7b,0x7e,0xfc,0xfe,0xff,0x7c,0x7e,0xfe,0x7e,0xfe,0xff +,0xfb,0xfe,0x7a,0x7b,0x7d,0xfe,0xfb,0xfc,0xfd,0xfe,0x7d,0x7b,0x7c,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0xff,0xff,0xfc,0xf9,0xfb,0x7e,0x7d,0x7d,0xff,0xf9,0xfc,0x7a +,0x7b,0x7b,0x7c,0x7c,0x7a,0x77,0x7a,0xfe,0xfe,0xfd,0xfe,0xfb,0xfa,0x7e,0x7d,0x7a,0x7a,0x7d,0x7e,0xfd,0x7e,0x7d,0x7d,0xfd,0xfe,0xfe,0xff,0x7d,0x7d,0x7e,0x7d,0x7c +,0xff,0xff,0xfc,0xfc,0xfd,0xff,0xfe,0xfe,0xfd,0xfd,0x7e,0xff,0xfe,0xfb,0xfb,0xfd,0x7e,0x7d,0xff,0xff,0x7d,0x7d,0xfc,0xfa,0xfb,0xfd,0xfb,0xfc,0xfa,0xfb,0xfe,0x7e +,0x7d,0xfe,0xff,0xfe,0x7d,0xfd,0xfe,0x7d,0xff,0x7d,0xff,0x7e,0xfc,0xfd,0xfc,0xfc,0xfb,0xfb,0xfe,0xfc,0xfc,0x7d,0x7b,0xfe,0xfd,0xff,0x7c,0x7d,0xfe,0xfb,0xf9,0xfe +,0x7c,0xff,0xfd,0xfe,0x7e,0xfe,0xfe,0xfc,0xf9,0xfd,0x7d,0x7d,0xff,0x7e,0x7e,0xfe,0xfe,0xff,0xfd,0xfd,0xfd,0xfe,0xfe,0x7e,0x7c,0x7b,0xff,0x7e,0xfe,0xfb,0xfc,0xfc +,0xfb,0xfd,0xfc,0xf8,0xfd,0x7d,0x7e,0x7e,0x7c,0x7c,0x7e,0xfe,0xfe,0xfd,0xfe,0x7c,0x7d,0xfd,0xfb,0xfc,0xfb,0x7e,0xff,0xfc,0xfb,0xfc,0x7c,0x7b,0x7e,0xfd,0x7b,0x7c +,0x7e,0xfc,0xfa,0xfc,0x7d,0x7b,0xff,0xfc,0xfc,0xff,0xfe,0xff,0x7d,0xfe,0xfb,0xfc,0xfd,0xfc,0x7e,0x7d,0xfd,0xfb,0xfd,0xfc,0xf9,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff +,0x7d,0xfe,0xfd,0xfa,0xfa,0xfa,0xfa,0xfa,0xfc,0x7e,0x7e,0xfe,0xfc,0xfe,0x7e,0x7c,0xff,0xfa,0xf8,0xfb,0xfc,0xfd,0xfc,0xfa,0xfc,0xfb,0xfa,0xfa,0xfc,0xfd,0xfe,0x7d +,0x7d,0xff,0xfe,0xfe,0x7e,0x7c,0xff,0xf9,0xf8,0xfb,0xff,0x7e,0x7d,0xfe,0xfe,0x7e,0xfe,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0x7e,0x7d,0x7c,0x7c,0x7d,0xfc,0xfa,0xfd +,0x7d,0x7b,0x7c,0xfe,0xfd,0xfe,0x7e,0xfd,0xf9,0xfb,0x7c,0x7e,0xfc,0xfd,0x7c,0x77,0x78,0x7b,0x7d,0x7c,0x7b,0x7c,0xfe,0xfe,0x7c,0x7c,0x7d,0xfc,0xfe,0xfe,0x7e,0xfe +,0xfe,0xfe,0xfb,0xfe,0x7e,0x7b,0x79,0x7b,0xff,0xfc,0x7e,0x7d,0x7e,0xfc,0xfd,0xfd,0x7d,0x7e,0xff,0x7e,0x7d,0x7a,0xff,0xfc,0xf8,0xfa,0xfe,0xff,0xfe,0x7e,0xfe,0x7e +,0x7d,0xfe,0xfe,0xff,0x7e,0xff,0xfe,0xfd,0x7d,0x7c,0x7d,0xff,0x7e,0xfd,0xfd,0xfe,0xfc,0xfc,0xfe,0x7e,0xfe,0xfd,0x7e,0x7e,0x7e,0x7d,0x7e,0xfd,0xfc,0xfe,0x7d,0x79 +,0x7c,0x7e,0xfd,0xfd,0xfe,0x7d,0x7d,0xfc,0xfe,0x7e,0x7e,0x7d,0x7c,0x7d,0x7d,0x7d,0x7d,0xfd,0xf9,0xfa,0xfd,0x7e,0x7d,0xfe,0xfc,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfd +,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0xfd,0xfe,0xfe,0x7b,0x7b,0x7c,0x7e,0xfe,0xfd,0x7e,0x7b,0x7c,0x7c,0x7e,0xff,0xfa,0xfb,0xfe,0x7d,0x7c,0x7c,0x7c,0xfe,0xfe,0xff +,0x7c,0xfe,0xfc,0x7e,0xff,0xfd,0xfc,0xfc,0xfd,0xfe,0x7e,0xff,0xfb,0xfc,0xff,0x7c,0x7b,0x7e,0xfe,0xfd,0xfe,0x7c,0x7b,0x7e,0xfd,0xfc,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e +,0x7e,0xfe,0xfc,0xfa,0xfa,0xff,0xff,0xfe,0xfd,0xfb,0xfd,0xfd,0xfe,0xfe,0xfb,0xfe,0xfe,0x7d,0x7e,0xff,0x7c,0x7e,0x7d,0x7e,0xff,0xfd,0xfc,0xfd,0xfc,0xfc,0xfc,0xfd +,0x7e,0x7e,0x7d,0xff,0xfe,0xfe,0xfc,0xfc,0x7e,0x7c,0x7e,0xfe,0xfb,0xfa,0xfc,0x7e,0x7e,0x7d,0x7d,0x7e,0xfe,0xfc,0x7e,0x7e,0x7e,0x7d,0x7d,0xfe,0xfc,0xfb,0xfd,0x7e +,0xff,0xff,0xfd,0xfe,0x7c,0x7d,0x7e,0x7d,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7c,0x7e,0xfc,0xf9,0xfe,0x7a,0x77,0x7a,0x7d,0x7d,0x7b,0x7b,0x7b,0x7d,0xfe,0x7e +,0xfd,0x7e,0xfe,0x7c,0x7b,0x7e,0x7b,0x7d,0x7c,0x7d,0x7e,0x7e,0xff,0x7c,0x7c,0x7e,0xfe,0xfe,0x7e,0xff,0xfe,0x7d,0xff,0x7e,0x7e,0xfe,0x7c,0x7c,0x7d,0x7e,0x7e,0x7c +,0x7c,0xff,0xfe,0xfd,0xfe,0xff,0xfe,0xfd,0x7c,0x7c,0x7e,0x7e,0xfe,0xfe,0xfc,0x7e,0x7e,0x7e,0xfe,0xfc,0xfe,0x7e,0x7e,0xfe,0xfc,0xfe,0xff,0x7e,0xfd,0xfb,0xfe,0xfe +,0x7e,0xfd,0xfc,0xfa,0xfb,0xfe,0xfe,0xfd,0xfc,0xfc,0x7e,0x7c,0x7e,0x7d,0x7c,0x7d,0xfe,0xfe,0x7d,0x7e,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xff,0xff,0x7e,0x7e,0xff +,0x7d,0x7d,0xff,0x7e,0x7b,0x7e,0xfc,0xfb,0xfc,0xfe,0x7c,0x7d,0xfd,0xfd,0x7e,0x7c,0x7e,0xff,0xfe,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0x7d,0x7c,0x7e,0x7e,0x7d,0x7d +,0x7c,0x7d,0x7e,0xfe,0xfe,0xfd,0x7d,0x7d,0xfe,0xfc,0xfb,0xfd,0x7d,0x7e,0x7e,0xff,0x7c,0x7c,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,0xfe,0xff,0xfd,0x7d +,0x7e,0xfe,0xfd,0x7e,0x7d,0xfd,0xfc,0xfd,0xfd,0x7e,0x7d,0x7e,0xfd,0xfd,0xff,0xfd,0xfd,0xfd,0x7e,0x7e,0x7e,0xfe,0xfd,0xff,0xfc,0xfc,0xfe,0x7e,0xff,0xfd,0x7e,0x7d +,0x7d,0x7c,0xfc,0xfb,0xfe,0x7e,0x7e,0xfd,0xfb,0xfa,0xfe,0xfe,0xfc,0xfb,0xfc,0xfc,0xfe,0x7e,0xfd,0xfe,0x7d,0x7d,0x7e,0x7e,0x7e,0xfe,0xfd,0xfd,0xfc,0xfd,0x7e,0xfd +,0xfd,0xfe,0xfd,0xfe,0x7e,0xfe,0xfd,0xff,0x7e,0x7d,0x7e,0x7e,0x7c,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0xfe,0xfe,0xfd,0xfd,0xff,0xfe,0xfe,0xfd,0xfc,0xf7,0xfb +,0x7c,0x7b,0x7e,0x7e,0x7b,0x7b,0x7d,0xfe,0xfd,0xfe,0xfe,0x7d,0xfe,0xfc,0x7e,0x7d,0x7d,0xfd,0xff,0xff,0xfe,0xfd,0xfe,0xfd,0xfd,0x7e,0x7e,0x7d,0x7c,0x7c,0x7e,0xfe +,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0x7c,0xff,0xfe,0xfe,0xfd,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0x7e,0x7d,0xfc,0xf8,0xfa,0xff,0x7c,0x7e,0xfd,0xfd,0xfe,0x7e +,0xff,0xfd,0xf9,0xfa,0xff,0xfe,0xfe,0xfb,0xfd,0xff,0x7e,0x7d,0xff,0xfd,0xfb,0xfd,0x7e,0xfe,0xfc,0xfc,0xfd,0xff,0x7d,0x7d,0x7e,0x7e,0x7e,0xff,0xfe,0xfd,0xfc,0xfd +,0x7d,0x7d,0xfc,0xfd,0xfd,0xfe,0xff,0xfd,0xfc,0xfa,0xfd,0xff,0xfe,0xfe,0xfe,0xfe,0xfc,0xfd,0xfb,0xfe,0xfe,0xfd,0x7e,0xfe,0x7e,0x7d,0x7d,0xfe,0xfc,0xfc,0xff,0x7e +,0xfd,0xfc,0xfd,0xfc,0xfe,0x7c,0x7e,0xff,0xfd,0x7e,0x7e,0x7c,0x7e,0xfc,0xfd,0xfe,0x7d,0x7e,0xfd,0xfc,0xfd,0x7e,0xff,0xfb,0xfa,0xfc,0x7d,0xfe,0xfe,0xfd,0xfc,0xfe +,0xfe,0xfe,0xfe,0xfe,0xfe,0x7d,0x7e,0xfc,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xfc,0xfe,0x7e,0xfe,0xfd,0xfb,0xfd,0xfe,0xfd,0xfd,0xfd,0xfc,0xfc,0xfc,0xfd,0xfe,0xff,0xfe +,0xff,0xfc,0xfb,0xfc,0xfe,0xfe,0xfd,0xfc,0xfb,0xfc,0x7e,0xff,0xfe,0xfc,0xfc,0x7e,0xfc,0xfa,0xfa,0xfc,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0x7e,0xfb,0xf9,0xfb,0xff,0x7d +,0x7c,0x7b,0x7e,0xfd,0xff,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0x7d,0x7e,0xfe,0xfc,0xfe,0x7d,0x7e,0xfe,0xfc,0xfa,0xfe,0x7e,0xfe,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0x7e +,0x7b,0x7d,0xff,0xfd,0xff,0x7d,0x7e,0xfe,0xfc,0xfb,0xfd,0xfe,0x7c,0x7a,0x7c,0x7d,0xff,0xfe,0xfc,0xfe,0x7d,0xff,0xfe,0xfe,0xff,0x7d,0x7e,0x7e,0xfe,0xfc,0xfc,0x7e +,0xfe,0xfb,0xfc,0xfd,0xff,0x7d,0x7d,0xfe,0xfc,0xfe,0x7e,0x7d,0x7e,0xfe,0xff,0x7e,0x7d,0xff,0xfc,0xfc,0xfe,0x7e,0xff,0xfe,0xfc,0xfc,0x7e,0x7e,0xfe,0xfd,0xfd,0xfd +,0xfd,0xfd,0xfd,0xfe,0xfd,0xfe,0x7d,0xfd,0xfd,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfe,0xff,0xfd,0xfb,0xf9,0xfb,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe +,0x7e,0xfd,0xfb,0xff,0x7a,0x7a,0x7d,0x7e,0xff,0x7d,0x7d,0x7e,0xfe,0xfc,0xfd,0x7e,0x7d,0xff,0xfe,0xfe,0xfe,0x7d,0x7e,0xfd,0xfd,0xfe,0x7e,0x7d,0x7e,0xfd,0xfd,0x7d +,0x7c,0x7c,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xff,0x7e,0xff,0xfd,0xfc,0xfd,0x7e,0x7e,0x7e,0x7d,0x7c,0x7c,0x7b,0x7c,0x7e,0x7e,0xff,0xfe,0xfc,0xfc,0xff,0x7e +,0xfe,0xfd,0xfd,0x7e,0x7e,0x7d,0xff,0xfd,0xfd,0xfd,0xfd,0xfc,0xfc,0xfe,0xfe,0xfd,0xfd,0xfe,0xfb,0xfb,0xff,0x7e,0x7e,0xfe,0xfc,0xfd,0xff,0x7d,0xfe,0xfc,0xfa,0xfc +,0xff,0xfc,0xfc,0xfb,0xfd,0x7e,0xff,0xfd,0xfc,0xfd,0xfe,0xff,0xff,0xfd,0xfd,0xfd,0xfd,0xfe,0xfc,0xfd,0xfd,0xfd,0xfb,0xfb,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfb,0xfb +,0xfb,0xfb,0xfb,0xfd,0xff,0xfe,0xff,0x7e,0xfe,0xff,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0xfe,0xfc,0xfd,0xfc,0xfc,0x7d,0x7e,0xfc,0xfb,0xfe,0x7e,0x7d,0xfe,0xfd,0xff,0x7e +,0x7d,0xfe,0xfb,0xfa,0xfe,0x7e,0xfe,0xfc,0xfd,0xfd,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xfd,0xff,0x7e,0x7e,0xff,0x7e,0x7e,0x7d,0x7e,0xfe,0xfd,0xfd +,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0x7e,0x7d,0x7d,0xff,0xfe,0xff,0x7e,0x7e,0x7e,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfc,0xfd,0x7d,0x7e,0xfd,0xfc,0xfe,0x7e +,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xfd,0xfd,0x7e,0x7d,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0xfd +,0xfd,0xfc,0xfb,0xfc,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0x7e,0x7e,0xfd,0xfe,0x7e,0x7c,0x7d,0xfd,0xfc,0xfd,0xfe,0x7e,0xfc,0xfc,0xfe,0x7e,0x7d,0x7e,0xfe,0xfc,0xfd,0x7e +,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0x7e,0x7d,0x7c,0xff,0xff,0xfe,0x7d,0x7d,0xfe,0xfe,0xfb,0xfc,0xfe,0xff,0xfe,0xfc,0xfd,0xff,0x7c,0x7c,0x7d,0x7c,0x7b +,0x7c,0x7e,0xfd,0xfe,0xfd,0xff,0xff,0xfd,0xfe,0xfd,0x7e,0x7e,0x7e,0x7e,0xff,0xff,0xfc,0xfd,0xff,0x7d,0x7b,0x7c,0x7e,0xff,0xfe,0x7e,0xfe,0x7e,0xfe,0xfe,0xfe,0xfd +,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e,0xfe,0xfe,0xfd,0xfc,0x7e,0x7e,0xfe,0xfb,0xfd,0xff,0x7e,0x7e,0xfd,0xff,0x7e,0x7e,0xff,0xfd,0xfc,0xfe,0x7e +,0x7c,0xff,0xff,0xfe,0x7e,0x7d,0xff,0xff,0xfd,0xfe,0xfc,0xfc,0xfc,0xfd,0xfd,0xfe,0xfd,0xfd,0xfc,0xfd,0x7e,0x7d,0x7e,0xfe,0x7e,0xff,0x7d,0x7d,0xff,0xfd,0xfd,0x7e +,0x7e,0xff,0xfe,0xfe,0x7d,0x7c,0x7e,0xfd,0xfd,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7d,0x7d,0xff,0x7e,0x7c,0x7b,0x7d,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0xfe,0xfe,0xff +,0x7d,0x7c,0x7d,0x7d,0x7b,0x7a,0x7a,0x7b,0x7d,0x7d,0x7e,0x7e,0xff,0x7e,0xff,0x7e,0x7d,0x7e,0xff,0x7e,0x7d,0x7b,0x7d,0xfe,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0x7e,0x7d +,0x7c,0x7d,0xff,0x7e,0x7d,0x7c,0x7d,0x7e,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0xff,0x7d,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e +,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0x7c,0x7b,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xfd,0xfe,0xff,0xff,0xfe,0xfe,0x7e,0x7c,0x7a,0x7c,0xfe,0xfc,0xfe,0x7e +,0x7e,0x7e,0xff,0x7e,0x7d,0x7c,0x7c,0x7d,0x7e,0x7c,0x7c,0x7d,0xff,0xfe,0x7e,0x7d,0x7c,0x7d,0x7e,0xff,0xfe,0x7d,0x7e,0xfe,0xff,0xfe,0x7d,0x7d,0x7e,0xfe,0xff,0x7d +,0x7d,0x7d,0xff,0xfe,0xfd,0xfe,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0xfe,0xff,0x7e,0x7e,0x7e,0xff,0xfe,0xfd,0xff,0x7e,0xff,0xff,0x7e,0x7e,0x7d,0xff,0x7e,0xfe,0xff,0x7d +,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfe,0xff,0x7e,0xff,0xff,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfb,0xfb,0xfe +,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e,0xfe,0xfe,0xfc,0xfc,0xff,0x7d,0x7e,0xfd,0xfd,0xff,0xfe,0xfd,0xfc,0xfb,0xfb,0xfd,0x7e,0xfe,0xff,0x7e,0x7e,0x7e,0xfd,0xfd,0xfe,0xfe +,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0x7e,0x7c +,0x7d,0x7e,0x7e,0xfe,0xfe,0x7d,0x7d,0xff,0xfe,0xfd,0xfd,0xfe,0x7e,0x7d,0x7c,0x7b,0x7a,0x7b,0x7d,0x7d,0x7c,0x7c,0x7c,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0x7e +,0x7e,0x7d,0xff,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0xff,0xff,0x7d,0x7d,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0xfd,0xfc,0xfc,0xfd +,0xff,0xfe,0xfe,0x7e,0xff,0xfd,0xff,0x7e,0xfd,0xfe,0x7d,0x7d,0xff,0xff,0xfe,0x7e,0x7e,0xfe,0xfd,0xfc,0xfe,0x7e,0x7e,0xfe,0xfb,0xfc,0x7e,0xff,0xfc,0xfb,0xfc,0xff +,0x7e,0x7e,0x7e,0x7e,0x7d,0x7c,0x7c,0xfe,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0xff,0xfd,0xfb,0xfe,0x7d,0xfe,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd +,0xfd,0xfd,0xfa,0xfc,0x7e,0x7d,0xfd,0xfd,0xfd,0xfc,0xfe,0x7e,0xff,0xfb,0xfc,0xfd,0xfe,0xfe,0xfe,0x7d,0x7b,0x7d,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfc,0xfd,0xfe +,0xfd,0xfc,0xfc,0xff,0x7d,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xff,0x7d,0xff,0x7e,0x7e,0xff,0xfd,0xfe,0x7d,0x7e,0xfd,0xfc,0xfd,0xfe,0xfd,0xfe,0xfe,0xfd +,0xfd,0xfd,0xfd,0xfc,0xfb,0xfd,0xfe,0xfb,0xfc,0xff,0xfd,0xfd,0xfd,0xfc,0xff,0xfc,0xfa,0xfc,0xfd,0xfe,0x7e,0x7e,0xfd,0xfd,0xfb,0xfd,0xfe,0xfc,0xfd,0xfc,0xfa,0xfb +,0xfc,0xfe,0xfd,0xfc,0xfc,0xfe,0xfe,0xfd,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0xfb,0xfe,0x7d,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xfd,0xfc,0xfd,0xff +,0x7e,0xfd,0xfd,0x7d,0x7d,0x7e,0xff,0xfd,0xfd,0xfe,0xfd,0xfe,0x7d,0xfe,0x7e,0xff,0xfd,0xfc,0xfb,0xfc,0xfc,0xfb,0xff,0x7c,0x7b,0x7b,0x7a,0x7b,0x7c,0x7e,0xfe,0x7e +,0xfe,0xfd,0xfe,0xfd,0xff,0x7d,0x7d,0xfd,0xfc,0x7e,0x7d,0xff,0xfc,0xfd,0xff,0x7e,0x7c,0xff,0xfc,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xff,0xfd,0xff,0x7e,0xff,0xfd +,0xfe,0x7e,0x7e,0xfe,0xfc,0xfd,0xfe,0xfc,0xfe,0xfe,0xfc,0xfb,0xfc,0xfd,0xfe,0xfe,0x7d,0x7d,0xff,0x7e,0x7c,0x7c,0xfe,0xfb,0xfb,0xfd,0x7e,0x7c,0x7d,0xfe,0xff,0x7e +,0x7e,0xff,0xfd,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7d,0x7e,0xfd,0xfe,0x7d,0x7d,0xff,0xff,0xfe,0x7d,0x7b,0xff,0x7e,0x7e,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd,0xfe +,0x7e,0xff,0x7e,0xff,0xfc,0xfd,0xfe,0x7e,0xfd,0xfd,0x7d,0x7d,0x7e,0x7e,0x7d,0x7d,0xfe,0xfd,0xfa,0xfd,0xfe,0x7e,0x7d,0xfd,0xfe,0xfd,0xfd,0xfe,0xfe,0x7d,0x7b,0x7c +,0x7d,0x7d,0x7d,0xff,0x7d,0xff,0x7e,0xfe,0xff,0x7e,0xfe,0x7e,0xfe,0xfd,0xff,0xfe,0x7e,0x7e,0xfe,0xfc,0x7e,0x7e,0xfe,0xfe,0xfc,0xfe,0x7d,0x7d,0x7c,0xfe,0xfc,0xfc +,0xff,0x7d,0xfd,0xfe,0x7e,0x7d,0x7e,0xff,0x7e,0xfd,0xfe,0xfd,0xfc,0xfc,0xfc,0xfe,0xff,0xfd,0xfc,0xfc,0xfe,0xff,0xfe,0xfc,0xfc,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd +,0xfe,0xfd,0xfd,0xfd,0xfc,0xfe,0xfe,0xfc,0xfc,0xfc,0xfd,0xfd,0xfb,0xfb,0xfd,0xfe,0xfd,0xfc,0xfd,0xfe,0x7d,0x7c,0x7d,0xfc,0xfa,0xfc,0xfe,0xfe,0xfc,0xfd,0x7e,0x7e +,0x7e,0xfe,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xff,0x7e,0xff,0xfe,0xfd,0xfc,0x7e,0xff,0x7e,0xff,0xff,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xfd,0xfe,0x7e,0xfd,0xfc,0xfb,0xfb +,0xfc,0xfe,0x7e,0x7d,0x7d,0x7d,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0xfd,0xfc,0xfd,0xfe,0x7e,0xfe,0xfc,0xfd,0xfe,0x7e,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd +,0xfe,0x7e,0xff,0x7e,0x7d,0xfe,0x7e,0xfe,0xff,0xfe,0xfe,0x7e,0xff,0xff,0xfe,0xff,0x7d,0xff,0xfb,0xfc,0xfd,0x7e,0xff,0xff,0xfc,0xfe,0xfd,0xff,0x7e,0xff,0xfe,0xff +,0xfe,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfc,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0x7e,0xfe,0xff,0xfe,0xff +,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0x7e,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xfe,0x7e,0x7e,0xfe,0xfc,0xfd,0xfe,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0xff +,0xfe,0xfd,0xfe,0xfe,0xfe,0xfc,0xfc,0xfd,0xfe,0x7d,0x7c,0x7b,0x7c,0x7c,0x7e,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfc,0xfd,0x7e,0x7e,0xfd,0xfd,0xfe +,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd,0xfd,0xfe,0xfd,0xfc,0xfd,0xff,0x7e,0xff,0xfc,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfc,0xfc,0xfc,0xfd,0xfe,0xfe,0x7e +,0xfe,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0xfc,0xfc,0xfd,0xfb,0xfb,0xfb,0xfe,0x7d,0x7e,0x7e,0xfd,0xfe,0x7e +,0xfe,0x7d,0xff,0x7e,0xff,0x7e,0xff,0xfe,0x7e,0x7d,0x7d,0xfe,0xfd,0xfd,0xfe,0x7e,0x7e,0x7e,0x7d,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe +,0xfe,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0x7d,0x7e,0x7c,0x7c,0x7d,0x7d,0xff,0xff,0x7c,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xff,0xfe,0xfe +,0xfe,0xfe,0xfe,0xfe,0x7d,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0x7d,0x7d,0x7c,0x7d,0xff,0xff,0x7d,0x7d,0x7e,0xff,0x7e,0x7d,0x7e,0x7e,0xff,0x7e,0xfe +,0xff,0xfe,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0xfe,0x7d,0x7d,0x7e,0x7e,0xff,0x7e,0x7d,0x7e,0x7d,0xff,0xfe,0x7e,0x7d,0x7d,0x7e,0xff,0x7e,0x7e,0xfe,0xff,0xfe,0xff,0xfd +,0xfd,0xff,0x7e,0x7d,0x7c,0x7b,0x7c,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0xff,0xff,0xfd,0xfe,0xfe,0x7d,0x7d,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0x7c,0x7d +,0x7e,0xff,0xfe,0x7c,0x7d,0x7d,0x7d,0xfe,0xfd,0x7e,0x7c,0x7c,0x7e,0xff,0x7e,0x7e,0xfe,0x7e,0x7d,0x7d,0x7b,0x7b,0x7b,0x7c,0x7d,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e +,0x7e,0xfe,0xfe,0x7e,0xff,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0x7d,0x7e,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xff +,0x7e,0xfd,0xfc,0xfe,0xff,0xfe,0xfd,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfb,0xfd,0xfe,0xfd,0xfd,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0xfd,0xff,0x7e,0x7e,0xfd,0xfd,0xfd,0xfe +,0xfd,0xfb,0xfb,0xfc,0xfd,0xfe,0xff,0xff,0x7e,0x7d,0x7d,0x7c,0x7d,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0xfe,0x7e,0xff,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xff,0x7e,0x7d +,0xff,0xfd,0xfc,0xfc,0xff,0x7d,0x7e,0xfe,0xfe,0xff,0xff,0xff,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xfd,0xfe,0xff,0xfe,0xfe,0x7e,0x7d,0x7a,0x79,0x79,0x7a,0x7c,0x7d,0x7c +,0x7c,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0x7e,0xff,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0x7d,0xfd,0xfe,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xff,0xff,0xfe,0xff,0x7e,0x7e +,0x7d,0xfe,0xfe,0xfc,0xfc,0xfd,0xfd,0xfc,0xfc,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0x7d,0xfe,0xfe,0x7e,0x7d,0xff,0xfc,0xfd,0xfe,0x7e,0xfe,0xff,0x7e,0xff,0x7d +,0x7c,0x7e,0xfd,0xfd,0xfd,0xfc,0xfc,0xfc,0xfc,0xfe,0xfe,0xfe,0xfd,0xfd,0x7d,0x7c,0x7b,0x7d,0xff,0x7d,0xff,0x7e,0xff,0xfe,0xff,0xfe,0xff,0xfd,0xfe,0xfd,0xfd,0xff +,0x7e,0xff,0xfd,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xfd,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xfe,0xfe,0xfd,0xff,0xfe,0xfd,0xfe,0x7e,0xfd,0xfd,0xff,0x7e,0x7c +,0x7d,0x7e,0xff,0x7d,0x7c,0x7b,0x7b,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0xff,0xfc,0xfd,0xfe,0x7e,0xfe,0xfe,0x7e,0xff,0xff,0xfd,0xfe,0x7e,0x7e,0x7e,0xfd,0xfd,0x7e,0x7c +,0x7e,0xfd,0xfd,0xff,0xff,0x7e,0x7d,0x7e,0xff,0x7e,0x7d,0xff,0xfe,0xfe,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0x7e,0x7d,0xfd,0x7e,0x7d,0x7e,0x7e,0xfe,0xfe,0xfd,0x7e +,0x7d,0x7d,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0x7e,0xff,0xfe,0x7e,0x7e,0xff,0xfc,0xfd,0x7d,0x7b,0x7b,0x7c,0x7e,0x7e,0x7d,0x7c,0x7d,0xff,0xfe,0xfd,0x7e +,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0x7d,0xfe,0xff,0x7c,0x7e,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7c,0x7d,0x7d,0x7e,0x7e,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e +,0x7d,0xff,0xff,0x7b,0x79,0x78,0x79,0x7b,0x7b,0x7a,0x7a,0x7c,0x7d,0x7e,0x7d,0x7b,0x7c,0x7c,0x7c,0xff,0x7e,0x7c,0x7c,0x7d,0x7e,0x7d,0x7e,0x7d,0x7d,0x7d,0x7c,0x7d +,0x7d,0xff,0xff,0x7d,0x7c,0x7b,0x7c,0x7d,0x7e,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0x7d,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7d,0x7c,0x7d,0xfe,0xfe,0x7e,0x7d +,0x7c,0x7d,0x7c,0x7d,0x7e,0x7c,0x7e,0x7e,0x7e,0x7d,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0x7e,0xfe,0x7e,0x7d,0x7c,0x7c,0x7d,0x7e,0xfd,0xff,0x7d +,0x7b,0x7c,0x7e,0xff,0xff,0x7d,0x7e,0xfe,0xfe,0xfe,0x7d,0x7d,0x7e,0xfe,0xff,0xff,0xff,0x7e,0x7d,0x7c,0x7d,0x7c,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0xfd,0xfe,0x7e +,0x7e,0x7d,0xff,0xfe,0xff,0x7e,0xfd,0xfd,0x7e,0x7e,0x7c,0x7b,0x7d,0x7d,0x7d,0x7d,0x7c,0x7d,0xfe,0xfd,0xff,0x7e,0xff,0xff,0xfd,0xff,0x7d,0x7e,0xff,0xfe,0x7e,0x7d +,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0x7d,0x7c,0x7d,0x7e,0xfe,0xfd,0xff,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e +,0x7d,0x7e,0xfd,0xfc,0xfe,0x7e,0xff,0x7e,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0x7e,0xfe,0xff,0x7e,0xfe,0x7e,0xfe,0xfd,0xfe,0xfd,0xfd,0xfd,0xfe,0x7e,0x7d +,0x7c,0x7e,0xff,0xfd,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xff,0xfe,0xfd,0xff,0x7d,0x7d,0x7d,0x7e,0xfd,0xfe,0x7e,0x7d,0x7e,0xff,0x7e,0x7d +,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfd,0xfd,0xfe,0x7d,0xfe,0xfe,0x7e,0x7d,0x7c,0x7a,0x79,0x7c,0x7c,0x7b,0x7c,0x7c,0x7e,0xff,0xff,0x7d,0x7d,0x7e,0x7e,0xff,0x7c +,0x7b,0x7e,0x7e,0x7d,0x7d,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7c,0x7d,0x7d,0x7e,0xfd,0x7e,0x7d,0x7e,0x7e,0x7e,0x7c,0x7e,0xfe,0xfe,0xfd,0xff,0x7e +,0x7d,0xff,0xfe,0x7e,0x7e,0x7d,0x7d,0xff,0xfe,0xfd,0xff,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0x7d,0x7e,0x7e,0xff,0xfe,0xfc,0xfe,0x7e,0xfd,0xfe,0xfe,0xfc,0xfe +,0x7d,0xfe,0xfd,0xfd,0xff,0x7e,0x7d,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0x7d,0x7e,0xfd,0xff,0x7e,0x7e +,0x7d,0x7e,0xff,0xfd,0x7d,0x7b,0x7d,0x7e,0x7e,0xff,0xff,0xff,0x7e,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0x7d,0x7b,0x7a,0x7b,0x7d,0x7d,0x7d,0x7c,0x7d,0xff,0xfe,0xff,0x7e +,0x7d,0x7e,0x7d,0x7e,0xfe,0x7e,0xff,0xfc,0xfe,0x7d,0xff,0x7e,0xff,0x7e,0xfe,0x7d,0x7e,0xfe,0xfe,0xfe,0xff,0x7d,0x7e,0xfe,0xff,0xff,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe +,0xfe,0xfc,0xfd,0xfe,0xfe,0xfe,0x7e,0xfd,0xfc,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e,0xff,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe +,0xff,0xfd,0xfb,0xfc,0xfc,0xff,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0xfd,0xfe,0xfe,0xfc,0xfe,0x7d,0xfe,0xfe,0xfd,0xfd,0x7e,0x7e,0xfd,0xfd,0xff,0x7e +,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfe,0xff,0xfe,0xfe,0xfd,0xfc,0xfe,0x7e,0x7d,0xff,0xfe,0xfd,0xfd,0xfe,0xfc,0xfc,0x7e,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e +,0x7d,0xff,0xff,0xff,0x7e,0x7e,0x7d,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7d,0xff,0xff,0xfe,0xfe,0xff,0x7e,0x7e,0x7d,0x7e,0xfe,0x7e,0x7d,0xfd,0xfd,0xfe,0x7e +,0x7e,0x7e,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfd,0xff,0x7d,0xff,0xfd,0xfc,0xfd,0xfe,0x7e,0xfd,0xfe,0xfe,0xfe +,0xff,0xfe,0xfb,0xfc,0xfc,0xfe,0xfd,0xfc,0xfc,0xfd,0xfe,0x7e,0xfd,0xfd,0xfd,0xff,0x7e,0xff,0xfd,0xfd,0x7e,0x7e,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfc,0xfc,0xfe,0xff +,0x7e,0xfe,0xfc,0xff,0x7d,0x7e,0xfe,0xfc,0xfc,0xfd,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xfd,0xfc,0xfc,0xfd,0xfe,0xfd,0xfc,0xfb,0xfd,0xfe,0xfd,0xfb,0xfd,0xfe,0x7e +,0x7c,0x7d,0x7c,0x7c,0x7d,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0x7e,0xfe,0xfc,0xfd,0xfd,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xfe +,0x7e,0x7e,0xfd,0xfd,0xfe,0xfe,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xff,0xfe,0xff,0xfe,0xfd,0xfe,0xff,0xff,0xfd,0xfc,0xfd,0xfe +,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfc,0xfc,0xfe,0xfe,0xfe,0xfe,0xfc,0xfb,0xfc,0xfe,0xfd,0xfe,0xfe,0xff,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xfc,0xfc,0xfd,0xfd +,0x7e,0xff,0xfc,0xfd,0xfd,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0x7e,0xfe,0xfc,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xff,0xfe +,0xfd,0xfb,0xfb,0xff,0x7b,0x7a,0x7b,0x7e,0x7e,0x7c,0x7c,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xff,0x7d,0x7d,0x7d,0x7e,0xff,0x7e,0x7d,0x7c,0x7c,0xfe,0xfe,0x7e,0x7c +,0x7c,0xff,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0x7d,0x7c,0x7d,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0x7e,0xff,0x7d,0x7d,0xfd,0xfd,0xfe,0xfd,0xfd,0xfe,0xff,0x7e,0xfe +,0xfe,0xfd,0xfd,0xfd,0xff,0xfe,0x7e,0xfe,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xff +,0x7d,0x7d,0x7e,0x7e,0x7d,0xff,0x7e,0xfd,0xff,0xff,0xff,0xfe,0xff,0xfe,0xfe,0x7d,0x7d,0x7d,0xff,0xff,0xff,0x7d,0x7c,0x7c,0x7e,0x7e,0x7e,0xfe,0xfd,0x7e,0x7d,0x7e +,0x7e,0x7d,0x7e,0x7e,0x7d,0x7d,0x7e,0xfc,0x7e,0x7e,0x7d,0x7b,0x7c,0x7d,0x7d,0x7c,0x7d,0xff,0xfd,0xfe,0x7e,0x7d,0x7c,0x7e,0xfe,0x7e,0xff,0x7e,0x7e,0xfe,0xfe,0xff +,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0xff,0xfe,0xfd,0xff,0x7c,0x7d,0xff,0xfe,0xff,0xfe,0xff,0xfe,0xff,0xfd,0xfd,0xff,0xfc,0xfc,0xff,0x7e +,0xff,0xfd,0xfd,0xfc,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0x7e,0xff,0xfd,0xfc,0xfd,0xfe,0xfe,0xfd,0xfb,0xfb,0xfa,0xfd,0xff,0xfd,0xfd,0xfe,0x7d +,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0x7e,0x7e,0x7e,0xfe,0xfc,0xfe,0xff,0x7e,0xfe,0xff,0xfd,0xfe,0x7e,0xfe,0xfd,0xff,0xfe,0x7d,0xff,0xfe,0xfd,0xff,0x7c +,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0xfe,0xfe,0xfc,0xfe,0x7d,0x7c,0x7a,0x7b,0x7a,0x7c,0x7b,0x7b,0x7d,0xfd,0xfc,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0x7d +,0xff,0x7e,0xfe,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0xfd,0xff,0x7e,0xfe,0x7e,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e +,0x7d,0x7e,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xff,0xff,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xfd,0xff,0xff,0xfd,0xfd,0xfd,0xff,0xff,0xff,0xfe,0xfd,0xfc,0xfe +,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0xfe,0x7e,0x7c,0x7c,0x7c,0x7e,0xff,0x7e,0x7e,0x7d,0x7d,0xff,0x7e,0x7d,0x7e,0xff,0xff,0x7e,0x7d +,0x7e,0x7e,0x7e,0xfe,0x7e,0xff,0xff,0xff,0xfe,0xfe,0xff,0x7e,0x7e,0xfd,0xff,0x7e,0x7e,0xfd,0xfd,0x7e,0x7d,0x7d,0x7c,0x7c,0x7e,0x7e,0x7e,0x7e,0xff,0xfd,0xfd,0xff +,0x7e,0x7e,0xff,0x7e,0x7d,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xff,0xff +,0xfe,0xfd,0xfc,0xfd,0xfd,0xff,0x7d,0x7e,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xfd,0xff,0xff,0xff,0xfd,0xfd,0xfe,0xfd,0xfd,0xfd,0xfc,0xfe,0x7e,0x7e,0xfe,0xfb,0xfe,0xfe +,0xfe,0xfe,0xfd,0xfc,0xfe,0xff,0x7e,0xfe,0xfd,0x7e,0x7e,0x7e,0xfd,0xfc,0xfd,0xfe,0xfe,0xff,0xfd,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0x7d,0x7e,0x7e,0xfe,0xff,0x7d +,0x7d,0x7e,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfd,0xff,0xff,0x7e,0x7e,0xff,0x7e,0x7e,0x7d,0x7d,0xfe,0x7e,0x7e,0x7d,0xff,0xfc,0xfd,0x7d,0x7c,0x7b,0x7b,0x7b,0x7b,0x7c +,0x7c,0x7b,0x7e,0xff,0x7d,0x7c,0x7c,0x7e,0x7e,0x7d,0x7d,0x7e,0xfd,0xfd,0x7e,0x7d,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0xfd,0xff,0xff,0x7e,0x7e,0xfe,0xff,0x7e +,0x7d,0x7e,0xfd,0xff,0x7e,0xff,0xff,0xfc,0xfe,0xfe,0xfd,0xfe,0xfd,0xfc,0xfd,0xfd,0xff,0xfe,0xfc,0xfd,0x7e,0x7d,0x7e,0xfe,0xff,0x7e,0xfe,0xff,0xfe,0xfe,0xfe,0xfe +,0xff,0xfe,0xfd,0xfd,0x7e,0x7e,0xff,0xfd,0xfc,0xfd,0xfd,0xfe,0xfd,0xfc,0xfe,0x7d,0x7b,0x7c,0xff,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0xfe,0x7e,0xfd,0xfd,0xfd,0xfe +,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfd,0xfc,0xfc,0xfe,0xff,0x7e,0x7e,0xfe,0x7e,0x7e,0xff,0xfe,0xfc,0xfd,0xfe,0xff,0xff,0xff,0xfd,0xfd,0xfe,0xfe,0xfb,0xfb,0xfd,0x7e +,0x7d,0x7e,0x7d,0x7b,0x7c,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0x7d,0xfe,0xfd,0xfe,0xff,0x7e,0xfe,0x7e,0xfd,0xfe,0x7e,0xfd,0xfd,0xfe,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xff +,0xff,0xfd,0xfc,0xfe,0xfe,0xfe,0xff,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfc,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0xff,0xff,0xfc,0xfc,0xfc,0xfd +,0xfe,0xfe,0xfd,0xff,0xfe,0x7e,0xfe,0xfc,0xfa,0xfc,0xfe,0xfd,0xfc,0xfc,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0x7e,0x7e,0x7d,0xfe,0xfe,0xfe,0xff,0x7e,0xfd,0xfd,0xfe,0xff +,0xff,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0xfe,0xfd,0xfd,0xfd,0x7e,0x7e,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0x7d,0xff,0xfe,0xfe,0x7e,0xfe +,0xff,0xfe,0xfa,0xfc,0x7d,0x7c,0x7e,0x7e,0x7d,0x7d,0x7d,0x7c,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0x7d,0x7e,0xff,0x7e,0x7e,0x7c,0x7d,0xfe,0xff,0x7d,0xff +,0xff,0x7e,0xff,0xfd,0x7e,0x7d,0x7e,0x7d,0x7d,0x7c,0x7d,0x7e,0x7e,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0xfd,0xfe,0xfe,0xfd,0xfb,0xfc,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfe +,0x7e,0xfe,0xfd,0xff,0xff,0x7e,0x7e,0x7e,0xfe,0xff,0x7d,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xfd,0xfe,0xfe +,0xfe,0xfe,0xfd,0xfe,0xfe,0x7e,0xff,0xfe,0xfd,0x7e,0xff,0xff,0xff,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfd,0xfe,0xff,0xfd,0xfd,0xfd,0xfe,0x7c,0x7d,0x7e,0xfd,0xfd,0xfe +,0xfe,0xfd,0xfc,0xfc,0xfd,0xfd,0xfd,0xfc,0xfb,0x7e,0x7c,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0xfc,0xfc,0xff,0x7e,0xfe,0xfe,0xff,0xfd,0xfe,0x7e,0xfd,0xfd,0xfe,0xfe +,0xfe,0xfd,0xfe,0xfd,0x7e,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfc,0xfd,0xff,0xfd,0xfd,0xfd,0xfd,0xfd,0x7e,0xfd,0xfd,0xfc,0xfe,0xfd,0xfd,0xfc,0xfb,0xfc,0xfc +,0xfd,0xfd,0xfd,0xfd,0xff,0xfe,0xfe,0xfc,0xfc,0xfc,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfe,0xfd,0xfd,0xfb,0xfc,0xfb,0xfc,0xfb,0xfc,0xfd,0xfe +,0x7e,0x7d,0xfe,0xfe,0x7d,0xff,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xff,0xfe,0xff,0x7d,0xff,0xfd,0xfc,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xff +,0x7e,0xfe,0xfc,0xfe,0x7e,0xff,0xfd,0xfd,0xfd,0xfc,0x7e,0xfe,0xfd,0xfb,0xfc,0x7e,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0xff,0xfd,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0x7e +,0x7c,0x7e,0xff,0x7e,0x7c,0x7c,0x7d,0x7d,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0x7e,0x7e,0xfd,0xfd,0xfe,0xff,0x7e,0x7c,0xff,0xfe,0xff,0x7d +,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfc,0xfe,0x7e,0x7d,0x7e,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0xfe,0xfe,0xfd,0xfe,0x7e,0xff,0xff,0x7e,0x7e,0x7e +,0x7e,0xfe,0xfd,0xfc,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0xfe,0xff,0xff,0x7e,0xfe,0xff,0xfd,0xfd,0xfe,0x7e,0xff,0xfe,0xfd,0x7e,0x7d +,0x7c,0x7c,0xfe,0x7e,0x7d,0x7d,0x7d,0x7e,0xfe,0xff,0x7d,0x7e,0x7e,0x7e,0xff,0x7d,0xff,0xff,0xfc,0xfc,0xff,0x7e,0x7d,0x7d,0x7d,0x7c,0x7c,0x7d,0xff,0xfd,0xfe,0xff +,0x7e,0xff,0xff,0xfe,0xff,0x7e,0xfe,0xfd,0xfc,0xfe,0xfe,0xff,0xff,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0x7e,0xfe,0x7e,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e +,0xff,0x7e,0xfd,0xfc,0xfd,0xfe,0xfe,0xfc,0xfc,0x7e,0xfd,0xfe,0xfe,0xfc,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xff,0x7e +,0x7e,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfc,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0xfe,0x7d,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0x7e,0xfe,0xfd,0xfe,0x7d +,0x7e,0x7e,0xfd,0xfd,0xfe,0xff,0x7e,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0xfe,0xff,0xff,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xfd,0xfc,0x7e,0x7d,0x7c,0x7d,0x7d,0x7c,0x7d +,0x7c,0x7d,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xff,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7c,0xff,0xff,0xff,0x7d +,0x7d,0xfe,0xfe,0x7e,0x7d,0x7c,0x7d,0x7e,0xff,0x7e,0x7e,0xfe,0xfd,0xfc,0xfe,0xff,0xff,0xff,0xfc,0xfc,0xfe,0x7e,0x7e,0xff,0x7d,0x7e,0x7e,0xff,0xfd,0xfe,0xfe,0x7e +,0xfe,0xfd,0xfd,0xfc,0xfe,0xfe,0xfe,0xfc,0xfb,0xfe,0xfc,0xfd,0xfc,0xfb,0xfd,0xfe,0x7d,0xfe,0xfe,0xfe,0xfd,0xff,0x7e,0xfe,0xfd,0xff,0x7e,0xff,0xfc,0xfd,0xfe,0x7e +,0x7e,0xfe,0xfd,0xfd,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0xfd,0xfe,0xfe,0xff,0x7e,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0xfd,0xfe,0xfe,0xfd,0xfb,0xfc,0x7e +,0x7e,0xff,0xfe,0x7e,0xff,0x7e,0x7e,0xff,0xfd,0xfc,0xfd,0xff,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfc,0xfb,0xfd,0xfd,0xfb,0xfa,0xfb,0xfe,0xfd,0xfd,0xfc,0xfb,0xfc,0xfe +,0x7e,0xfd,0xfc,0xfc,0xfd,0xfd,0xfc,0xfb,0xfc,0xfe,0xff,0xfe,0xfc,0xfd,0xfd,0xfe,0xfd,0xfd,0xfc,0xfc,0xfd,0xfd,0xfe,0xfc,0xfd,0xfe,0xfe,0xfe,0xfd,0xfe,0xfd,0xfd +,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfc,0xfd,0xfd,0xfc,0xfa,0xf9,0xfb,0xfc,0xfd,0xfc,0xfb,0xfb,0xfd,0xfe,0x7e,0xfd,0xfe,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0x7e +,0xfe,0xfd,0xfb,0xfb,0xfd,0xfd,0xfd,0xfe,0xfe,0x7e,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfc,0xfc,0xfc,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe +,0xff,0xff,0xfc,0xfc,0xfe,0x7e,0x7c,0x7d,0x7e,0x7d,0x7d,0x7e,0xfe,0xfd,0xfc,0xfd,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0xff,0xfe,0xfd,0xff,0x7e +,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xff,0x7d,0xff,0xfd,0xfd,0xfd,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xff +,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0xff,0xfe,0xfe,0xff,0x7d,0x7e,0xff,0xfd,0xff,0x7e,0x7e,0x7e,0xfd,0xfd,0xfe,0xff,0xfd,0xfb,0xfd,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0x7e +,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xff,0xff,0x7d,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0xff,0xfd,0xfe,0xff +,0xff,0xff,0xfc,0xfc,0xfe,0x7e,0xfe,0xfd,0xfc,0xfe,0x7e,0x7c,0x7d,0xff,0x7e,0x7c,0x7d,0xff,0xff,0xff,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0x7d,0xff,0xfd,0xfd,0xff,0xfe +,0xff,0xff,0xfd,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xfd,0xff,0xfe,0xfd,0xfb,0xfc,0xfd +,0xfe,0xfe,0xfd,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0xfe,0xfd,0xfc,0xfd,0xfd,0xfe,0xfd,0xfb,0xfc,0xfc,0xfe,0xfc,0xfc,0xfb,0xfc,0xfc,0xfc,0xfd,0xfc,0xff,0x7e +,0x7d,0xfe,0xfd,0xfd,0xfd,0x7e,0x7e,0x7e,0xfd,0xfd,0xfd,0xff,0xfb,0xfc,0xfd,0xfd,0xff,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0xfe,0xfd,0x7e,0xff,0x7e,0xff,0xfe,0xfd,0xff +,0x7d,0xff,0xfd,0xfe,0x7e,0xff,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0x7e,0x7c,0x7c,0x7c,0x7c,0x7c,0x7b,0x7c,0xff,0xfd,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe +,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xff,0x7e,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0xfd,0xfe,0xfd,0x7e,0xfe,0xfd,0xfd,0xfd,0xfe +,0xfe,0xff,0xfd,0xfe,0xfe,0x7e,0xff,0xfc,0xfd,0xfe,0xff,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe +,0xff,0xfe,0xff,0xfe,0x7e,0x7d,0x7d,0xfe,0xfe,0x7e,0x7e,0x7d,0xfe,0x7e,0x7e,0x7c,0x7c,0x7d,0xfe,0xfd,0x7e,0xff,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xff,0xff,0xfe,0x7d +,0x7e,0x7e,0xff,0x7e,0x7d,0x7d,0x7c,0x7e,0xff,0xfe,0x7d,0x7e,0x7e,0x7e,0x7d,0x7d,0x7d,0x7e,0xfd,0xfc,0xfe,0x7d,0x7c,0x7b,0x7b,0x7a,0x7b,0x7c,0x7d,0xff,0xfe,0x7d +,0x7d,0x7d,0xfe,0x7e,0x7e,0x7d,0x7e,0xff,0xfe,0xff,0x7d,0x7d,0xff,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0x7d,0x7c,0x7c,0x7e,0x7d,0x7e,0x7c,0x7e,0x7d,0x7d,0x7c,0x7d +,0x7c,0x7d,0xfe,0xff,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0xff,0x7e,0xfd,0xfe,0x7e,0x7d,0xff,0xfe,0xff,0xff +,0x7d,0x7e,0xff,0xfe,0xfe,0xff,0xfe,0xfc,0xfe,0xff,0x7d,0x7c,0x7c,0x7d,0x7d,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0xfe,0xfd,0xfe,0xfe +,0xfe,0xfe,0xff,0xfe,0xff,0x7e,0xff,0xff,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfc,0xfd,0xfd,0x7e,0x7c,0x7d,0x7c,0x7c,0x7b +,0x7b,0x7c,0x7e,0x7e,0x7d,0x7d,0x7e,0x7e,0xfe,0x7d,0x7c,0x7d,0x7e,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xff,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xff +,0x7e,0xfe,0x7e,0x7e,0x7d,0x7e,0xff,0xfe,0xfe,0x7e,0xff,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xff,0x7e +,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0xfe,0xfe,0xfd,0xfc,0xfd,0xff,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0xff,0x7e,0xff,0x7e,0x7e,0x7d,0xfe,0xff,0xff,0x7e +,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0x7e,0x7d,0x7c,0x7c,0x7d,0x7e,0xfd,0xfe,0x7e,0x7d,0xfe,0xfd,0xfd,0xfe +,0x7d,0x7c,0x7c,0x7a,0x79,0x79,0x7b,0xff,0xfd,0xfe,0x7d,0x7e,0xff,0xfe,0xff,0x7d,0x7d,0x7e,0xfe,0x7e,0x7d,0x7c,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0xfe,0xff,0x7c +,0x7d,0x7e,0x7e,0x7d,0x7c,0x7c,0x7d,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfc,0xfd,0xff +,0x7e,0xff,0xfe,0xfe,0x7d,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0x7d,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xfd,0xfd,0xff,0x7d,0x7e,0xfe,0xfe,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff +,0x7e,0xfe,0xfe,0xfe,0x7d,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0x7e,0x7d,0x7d,0x7d,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xff +,0x7d,0x7e,0xfe,0xfd,0xff,0x7c,0x7c,0x7c,0x7c,0x7c,0x7b,0x7c,0x7e,0xfd,0xfe,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfc,0xfe,0x7e,0x7d,0x7e,0x7e,0xff,0x7e +,0x7e,0x7e,0x7e,0xfe,0x7e,0x7c,0x7d,0xff,0xfe,0xff,0x7e,0x7e,0xfd,0xfc,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xfd,0x7e,0xfd,0xfd,0xfd,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0x7e +,0x7d,0x7e,0xff,0xfe,0xff,0xff,0x7e,0xfe,0xfe,0x7e,0x7c,0x7d,0xfe,0xfc,0xfe,0xff,0x7e,0x7e,0xfd,0xfe,0xfe,0xff,0xfd,0xfd,0xfd,0xff,0x7e,0xff,0x7e,0x7e,0xff,0x7e +,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0x7d,0x7c,0x7d,0x7c,0x7b,0x7d,0xff +,0x7d,0x7e,0xfd,0xfd,0xfe,0xff,0x7e,0xfd,0xfd,0xfc,0x7e,0x7c,0x7d,0xff,0x7e,0x7c,0x7d,0x7e,0xfe,0xfd,0xfd,0xff,0xfe,0xfc,0xfc,0xfe,0xff,0x7e,0xfe,0xff,0xff,0xff +,0x7e,0x7d,0x7e,0xfe,0xff,0x7e,0xfe,0xfd,0xfd,0xfd,0xff,0x7e,0xff,0xfd,0xfc,0xfe,0x7e,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfb,0xfd,0xfe,0xfe +,0xfd,0xff,0xfe,0xfc,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xff,0xfd,0xfe,0xfe,0xfe,0xfc,0xfd,0xfd,0xff +,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0x7d,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,0xfc,0xfc,0xfd,0x7e,0xff,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7d +,0x7e,0xfe,0xfe,0xff,0xfe,0xff,0xff,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0x7d,0x7b,0x7c,0x7d,0xff,0xfd,0x7e,0x7d,0x7d,0xfe,0xfe,0xff,0xfe +,0x7d,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0xff,0xff,0x7d,0x7d,0x7d,0xff,0x7e,0x7e,0x7e,0x7d,0x7e,0xfe,0xff,0x7e,0x7e,0xfc,0xfd,0xfd,0xfe +,0xfe,0xfe,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfd,0xff,0xff,0x7e,0x7e,0xff,0x7e,0xff,0x7e,0xfe,0xfe,0xfe,0xfd,0xff,0x7d,0xfe,0xfd,0xfe,0xff +,0xfd,0xfd,0xfe,0xfd,0xff,0x7e,0x7d,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xfe,0x7e,0xff,0x7e,0xff,0xfd,0xff,0x7e,0x7c,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0xfd,0xfd,0x7e,0x7d +,0x7e,0xff,0xff,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfd,0xfe,0xff,0xfe,0xfe,0x7e,0x7d,0x7d,0x7d,0xff,0xfd,0xfd,0x7e +,0x7d,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0xfc,0xfc,0xfe,0xff,0xfe,0xfd,0xfd,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xfd,0xfe +,0xff,0xfd,0xfd,0x7e,0xff,0x7e,0xfe,0xfe,0xfd,0xfd,0xfe,0xfd,0xfc,0xfc,0xfd,0xff,0xff,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xff,0x7e,0xff,0xfe,0xfd,0xfe,0xfd +,0xfe,0xfd,0xfc,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd,0xfe,0x7e,0xff,0xfd,0xfe,0x7e,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0x7e,0xfe,0xfd,0xfd,0xfe,0xff +,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0xff,0xff,0xfd,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0xfd,0x7e,0x7d,0x7d,0x7d,0x7b,0x78 +,0x7a,0x7b,0x7c,0x7d,0x7e,0x7d,0x7e,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0xff,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0xff,0x7e,0xff +,0xff,0xff,0xfe,0xff,0x7e,0x7d,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0xfe +,0xff,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xfd,0x7e,0xfd,0xfc,0xfc,0xfe,0x7e,0x7d,0x7c,0x7e,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0x7d +,0x7c,0x7c,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xff,0x7d,0xff,0xfd,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfd,0xfc,0xfd,0x7e,0xff,0xfd,0xfd,0xfc,0xfc +,0xfd,0xfe,0xfe,0x7e,0x7c,0x7d,0x7e,0xfd,0xfd,0xfe,0xfe,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfb,0xfc,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe +,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfd,0xfd,0x7e,0x7e,0xfe,0xfe,0xfd,0xfc,0xfd,0xfe,0xfd,0xfb,0xfb,0xfc,0xfd,0xfc,0xfc,0xfc,0xfd,0x7e,0x7e,0xff,0xfd,0xfe,0x7e +,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfb,0xfb,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xff,0xfe,0xfd,0xfb,0xfb,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e +,0x7e,0xfd,0xfc,0xfc,0xfd,0xfe,0xff,0xfe,0xfc,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xfe,0x7e,0xfe,0xfc,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0xfe,0xff,0xfe,0xfd,0xfc,0xfe +,0x7e,0xfd,0xfe,0xfd,0xfe,0xff,0x7e,0x7c,0x7d,0x7b,0x7a,0x7b,0x7c,0x7e,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0xfe,0x7d,0x7d,0xff,0x7e,0xfe,0xfe,0xff,0xfe,0xfe,0xff,0xff +,0x7d,0x7d,0xfd,0xfd,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7d,0x7e,0xfc,0xff,0x7e,0xff,0xff,0xfd,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfd,0xfd,0xff +,0x7e,0x7e,0xfd,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xff,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7d,0xfe,0xfd,0xff,0xfe +,0x7e,0x7e,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0xfc,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0x7e +,0x7e,0xff,0xfc,0xfd,0x7e,0x7e,0xfe,0xff,0xfd,0xfc,0xfe,0xfe,0x7e,0x7e,0x7d,0x7b,0x7d,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfc,0xfd,0xfe +,0xfe,0xfe,0xfd,0xfe,0x7e,0xff,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0xfd,0xff,0xff,0xff,0xfe,0x7e,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0x7d,0x7e,0xfd,0xfd,0xfe,0xfd +,0xfe,0xfe,0xfc,0xfc,0xfe,0xff,0xff,0xfe,0xfe,0x7e,0xfe,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,0xfa,0xfd,0xfc,0xfd,0xfc,0xf9,0xfc,0xfe +,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xff,0x7e,0x7e,0xff,0x7e,0xfe,0xfe,0xff,0xff,0xfd,0x7e,0x7d,0x7e,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0x7e +,0x7d,0x7e,0x7e,0x7e,0xff,0x7d,0x7d,0xfe,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0x7c,0x7b,0x7b,0x7b,0x7d,0x7c,0x7c,0x7d,0x7d,0x7e,0xfe,0xfe,0xff +,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7b,0x7e,0x7e,0x7e,0x7c,0x7c,0x7e,0x7e,0x7d,0x7d,0x7d,0x7d,0xff,0x7d,0x7d,0x7d,0x7d,0xfe,0x7e,0x7c,0x7d,0x7d,0x7e,0x7e,0xfd,0x7e +,0x7d,0x7e,0x7d,0x7e,0x7d,0x7d,0x7e,0x7e,0xfe,0xff,0x7e,0x7c,0x7d,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0xff,0x7e,0xfe,0x7d,0x7b,0x7b,0x7b,0x7d,0x7d,0x7e +,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0xff,0x7d,0x7e,0xff,0xff,0x7e,0x7d,0x7e,0x7e,0xff,0xff,0x7e +,0xff,0xfe,0xfd,0xfe,0xfe,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0x7d,0x7e,0x7e,0x7c,0x7d,0x7c,0xff,0xfd,0xfe,0x7e +,0xff,0x7e,0xff,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0x7e,0xff,0x7d,0x7e,0x7e,0x7e,0x7d,0x7e,0x7d,0xff,0xff,0x7e,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e +,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0xfe,0xfd,0xfc,0xfe,0xfe,0xfd,0xfd,0xfd,0xff,0xfe,0xff,0xfe,0xfd,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xff,0xfe,0xff,0xfd,0xfe,0xff +,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfc,0xfc,0xfe,0xff,0x7e,0xfe,0xfe,0xff,0xfe,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0xfe,0x7e,0x7e,0xff,0x7e,0x7e +,0xff,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0xff,0x7e,0x7e,0xfd,0xfe,0xfc,0x7e,0xfe,0xfe,0xfe,0xfc,0xfe,0xfc,0xfd,0x7e,0x7e,0x7c,0x7b +,0x7c,0x7c,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0xff,0x7e,0x7e,0x7d,0x7e,0x7e,0xfe,0xff,0x7e,0x7e,0x7d,0xff,0xff,0xff,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e +,0x7d,0x7d,0x7e,0x7e,0x7e,0x7d,0xff,0x7e,0xfd,0xfd,0xff,0xff,0x7e,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0xfd,0xfe,0xff,0xfe,0xff,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7e +,0xff,0xff,0xfe,0x7e,0x7d,0x7c,0x7c,0x7e,0xfe,0x7e,0xfe,0x7e,0xff,0xfe,0xff,0xfd,0x7d,0xff,0xfe,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0xfe,0xfd,0x7e,0xff +,0xff,0xfe,0xfd,0xff,0x7e,0xff,0x7e,0x7e,0xfe,0xff,0xff,0xff,0xfe,0xfe,0x7e,0xff,0x7e,0x7e,0xff,0xfd,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0x7d,0xfc,0xfe,0xfe +,0xfd,0xfe,0xff,0x7d,0x7c,0x7b,0x7b,0x7e,0x7d,0xff,0x7e,0xfe,0xfe,0xfe,0xfe,0x7d,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0xfd,0xfe,0x7e,0x7e,0x7e,0x7d,0xfe,0x7e,0xff +,0x7e,0x7e,0xfd,0x7e,0xff,0x7d,0x7d,0xff,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0x7e,0xff,0x7e,0xfe,0xff,0xff,0xfd,0xfe,0xfd,0xfc,0xff,0x7e,0xfe,0x7e,0xfe,0xff,0xfe +,0xfe,0x7e,0xfe,0xfe,0x7e,0x7d,0xff,0xff,0xfd,0xff,0x7d,0x7e,0x7e,0xfe,0xfd,0xff,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xfe,0xff,0xff,0x7e +,0x7e,0xfe,0xfe,0xfe,0x7e,0xfe,0x7e,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0x7d,0x7d,0xff,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e +,0xff,0x7e,0xfd,0xfe,0xff,0xff,0x7e,0x7d,0x7b,0x7c,0x7a,0x7a,0x7d,0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e,0x7d,0x7c,0x7c,0x7d,0x7d,0x7e,0xfe,0x7e,0x7e +,0x7c,0x7d,0x7e,0x7d,0xff,0x7d,0x7e,0xff,0x7d,0x7e,0x7e,0x7c,0x7e,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0x7e,0x7d,0xfe,0xfe,0x7e,0xfd,0xff,0xff,0xfe,0x7e,0xfe +,0x7e,0xff,0xfe,0x7e,0xff,0xff,0x7e,0x7e,0xff,0x7e,0x7e,0x7d,0xff,0xfd,0xfe,0x7d,0x7d,0x7d,0x7e,0xff,0xff,0xfe,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0xff,0xfe +,0xff,0x7e,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfe,0xff,0xff,0xfe,0xfd,0xff,0xff,0xfe,0x7d,0xff,0xfe,0xff,0x7e,0x7e,0xfe,0xfc,0xfd,0xfe +,0xff,0x7e,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0xfc,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0xfe,0xfe,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0x7e,0x7e +,0xff,0xfe,0xfd,0xfd,0xfd,0xff,0xfd,0xfd,0xfd,0xfd,0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfe,0xfe,0xfe,0xfe,0xff,0x7e,0x7d,0xff,0xff,0xff,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe +,0x7e,0xfd,0xfd,0xff,0xfe,0xff,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0x7d,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xfc,0xfd +,0xff,0x7e,0xfe,0xff,0xff,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0xfe,0x7e,0xfe,0xfd,0xff,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0x7e +,0xff,0xff,0xfe,0xfe,0xff,0x7d,0x7e,0xfd,0xfe,0xfe,0xfe,0x7e,0x7d,0xfe,0xfe,0xfe,0xfe,0xfd,0x7e,0x7c,0x7b,0x7a,0x7a,0x7c,0x7e,0x7e,0x7d,0x7e,0x7e,0xfe,0xff,0x7d +,0x7e,0x7d,0xfe,0xff,0x7d,0x7d,0x7e,0xff,0xff,0x7d,0x7d,0x7c,0x7e,0x7e,0x7e,0x7e,0x7d,0xff,0x7e,0xff,0x7d,0x7d,0x7e,0x7e,0xff,0x7e,0x7d,0x7d,0xff,0xfd,0xff,0x7d +,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7d,0xff,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0xff,0x7e +,0xfe,0xfe,0xfe,0xff,0xff,0x7d,0x7e,0xfd,0xfe,0xff,0x7d,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0x7e,0x7e,0x7e +,0x7d,0x7e,0xfc,0xfe,0x7e,0x7e,0x7e,0x7e,0xff,0xfe,0x7d,0x7e,0xfe,0xfe,0x7d,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0x7e,0xff,0x7d,0x7c,0x7b,0x7b,0x7e,0x7e,0x7e,0x7d +,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0xff,0xfd,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfd,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xff,0x7d,0x7e,0xfd,0xfe,0xfe,0xfe +,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfe,0x7e,0xfe,0xfd,0xfc,0xfb,0xfd,0xfe,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0xfd,0xfc,0xfe,0xfe,0xfe,0xfc,0xfd,0xfd,0xfe +,0xff,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfc,0xfb,0xfc,0x7e,0xfd,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xfc,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0xfe,0xfe,0xff,0xfd,0xfd,0xfd,0xfe +,0x7e,0xfe,0xff,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0x7d,0x7d,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0xff,0xfd,0xfd,0xff,0xfe,0x7e,0xfd,0xfd,0xff,0xfe,0xfd,0xfd,0x7e,0x7d,0x7a +,0x7a,0x7b,0x7d,0x7e,0x7d,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0xff,0x7d,0x7e,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0xfe,0xff,0x7e +,0x7d,0x7d,0xfe,0xfe,0x7e,0xfe,0xff,0xfd,0xff,0xff,0x7e,0xff,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe +,0x7e,0xff,0xfe,0xfd,0xfe,0x7e,0xfd,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe +,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0xfd,0xff,0x7d,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xff +,0xff,0xfc,0xfe,0xfe,0x7e,0x7d,0x7d,0x7d,0xff,0x7e,0x7d,0xff,0x7e,0xfe,0xff,0xff,0xff,0xfe,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0xff,0xfd,0xfe,0xfe,0xfd,0xfd,0xfe,0x7e +,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfe,0xfd,0xfe,0x7e,0xfe,0xfe,0x7e +,0x7d,0x7e,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xfd,0xfd,0xfc,0xff,0xfd,0xfc,0xfc,0xfc,0xfd,0xfd,0xff,0xfd,0xfd,0xfd,0xff,0xff,0xfe,0xfe,0xff,0xff +,0x7e,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7d,0x7d,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xff,0x7e +,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0x7e,0x7d,0x7c,0x7d,0x7c,0x7e,0x7d,0x7d,0x7d,0x7e,0xfe,0xff,0xff,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xff,0x7e,0x7e +,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0x7e,0x7d,0x7c,0x7d,0x7e,0x7d,0xff,0x7e,0x7e,0x7d,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xfd,0xfe,0xff +,0xff,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0xfe,0xfd,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0x7d,0xff,0xff,0xfd,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0x7e +,0x7e,0xff,0xfe,0x7e,0x7c,0x7d,0x7d,0xff,0xff,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0x7e,0xfd,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfd,0xfd,0x7e,0x7d,0x7d,0x7e,0x7e,0xff,0x7e +,0xff,0xff,0xfe,0xff,0x7e,0x7d,0x7d,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xfe,0x7e,0x7b,0x7c,0x7d,0x7e,0xff,0xff,0xfe,0xff,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0xfe +,0x7e,0xfe,0xfd,0xfc,0xff,0x7e,0xff,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xff,0x7e,0xff,0xfd,0xff,0xfe,0xff,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,0xfd,0xfb,0xfd,0xff +,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0x7e,0xfe,0xff,0xff,0x7e,0xfe,0xfe,0xfc,0xfc,0xfc,0xfb,0xfa,0xf9,0xfb,0xfc +,0xfe,0xff,0xff,0xfe,0xff,0xfe,0xfe,0xfd,0xfd,0xff,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e,0xfd,0xfd,0xfc,0xfe,0xfc,0xfe,0xff,0xfd,0xfd,0xfe +,0x7e,0xfd,0xfd,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xfd,0xff,0xfe,0xfe,0xfd,0xfd,0xff,0xfd,0xfc,0xfc,0xfe,0x7d,0x7c,0x7b,0x7b,0x7e,0x7d,0x7e,0x7e,0xfe,0xff,0x7e,0x7e +,0x7e,0xff,0xfe,0xfd,0x7e,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0x7d,0x7e,0x7e,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0xff,0x7d,0xff,0x7e,0x7e,0x7e +,0x7e,0xfe,0xfe,0xfd,0xff,0xff,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xff,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0x7e +,0x7e,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfd,0xfe,0xfd,0xff,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e,0xfd,0xfe,0xff,0x7e,0xff,0xff,0xff,0xfd,0xff,0x7e +,0xfe,0xff,0xff,0xfe,0x7d,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xff,0xfe,0xff,0xff,0xfd,0xfd,0xfd,0x7e,0x7e,0x7d,0x7e,0x7e,0xff,0x7e +,0x7d,0xfe,0xff,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0xff,0xfd,0xfe,0x7e,0x7d,0x7d,0xff,0xff,0xfe,0x7e +,0x7d,0x7e,0xff,0xfd,0xfe,0x7e,0xfe,0xff,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0xfe,0x7d,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xff,0xfe,0xfe +,0xfe,0xff,0xff,0xfe,0x7d,0x7e,0x7e,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7d +,0x7d,0x7e,0xff,0xff,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7d,0x7e,0x7e,0x7e,0x7d,0x7d,0x7d,0x7d,0xfe,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xfc,0xfd,0x7d,0x7c +,0x7a,0x7b,0x7d,0x7d,0x7d,0x7c,0x7e,0xff,0xff,0x7e,0x7c,0x7c,0x7e,0x7d,0x7e,0x7d,0x7d,0x7c,0x7e,0x7e,0x7c,0x7d,0x7e,0x7e,0xff,0x7e,0x7d,0x7d,0x7d,0x7e,0x7d,0x7d +,0x7b,0x7d,0x7e,0x7d,0x7d,0x7d,0x7c,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,0xff,0xff,0xfe,0xff,0x7e +,0x7d,0xff,0xfe,0xfe,0xff,0xfe,0xfe,0xff,0xfd,0xfe,0xfe,0xff,0xfc,0xfd,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e +,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0x7e,0xff,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfd,0xfe,0xfe,0xfd,0xfe,0xfe,0xfd,0xfc,0xfe,0x7e,0xff,0x7e,0xfe,0xfe,0x7e +,0xfe,0xfd,0xfe,0xff,0x7e,0x7c,0x7c,0x7e,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xff,0x7e,0xfd,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff +,0x7e,0xfe,0xff,0xfe,0x7e,0x7d,0x7d,0x7e,0xfe,0x7e,0x7d,0x7e,0xfe,0xff,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xff,0xff,0xfe,0x7e,0xfe,0xff,0x7e,0x7e +,0x7d,0xff,0x7e,0xfe,0xfe,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0xfe,0x7e,0xfd,0xfd,0xfe,0xff,0x7e,0xfd,0xff,0x7e,0x7e,0xff,0xfe,0xff,0xff,0xfe +,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0x7e,0xfe,0xfe,0xff,0x7d,0x7c,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e +,0x7e,0x7e,0xfd,0xfd,0x7e,0x7e,0x7e,0xfe,0x7d,0x7c,0x7c,0x79,0x7b,0x7d,0x7c,0x7c,0x7c,0x7c,0x7e,0x7e,0xff,0x7d,0x7d,0xff,0x7d,0x7d,0x7d,0x7d,0x7e,0xfe,0xff,0x7d +,0x7d,0x7d,0x7d,0x7d,0x7d,0x7b,0x7c,0x7e,0x7e,0x7e,0x7c,0x7d,0x7c,0x7e,0xfe,0x7d,0x7d,0x7e,0xfe,0xff,0x7c,0x7e,0xff,0xff,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0x7e,0x7c +,0x7c,0x7d,0x7e,0x7e,0x7e,0x7e,0x7d,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xff,0xff,0x7d,0xff,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xff +,0x7e,0xfe,0x7e,0xff,0x7d,0x7d,0x7e,0x7c,0x7e,0x7d,0x7c,0x7d,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfe,0xfd,0x7e,0x7d,0x7e,0x7e,0xfd,0xfe,0x7d,0xff,0xff,0xfe,0x7e,0x7d +,0x7e,0x7e,0xfe,0xff,0x7c,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7d,0xfc,0xfd,0x7e,0x7d,0x7c,0x7d,0x7c,0xfe,0xfe,0x7d,0xff,0xfd,0xfc,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0x7e +,0x7e,0xff,0xfe,0xfd,0xff,0xff,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e,0x7d,0x7e,0x7c,0xfe,0x7e,0x7e,0xfe,0xfe,0xfd,0x7d,0x7e,0x7e,0xff,0xfd,0xfe,0xfd +,0xfe,0xfd,0xfb,0xfc,0xfd,0x7e,0xff,0xfd,0xff,0xff,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0xfe,0xfe,0xfd,0x7e,0x7e,0xff,0xfd,0xfd,0xfe,0xff,0xff,0xfc,0xfc,0xfe,0xff +,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xfd,0xfe,0xfe,0xfd,0xff,0x7e,0xfe,0xfc,0xfe,0xfe,0xfe,0xfe,0xfc,0xfd,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0x7e +,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xfd,0xfc,0xfe,0x7e,0xfd,0xfd,0xfc,0xfd,0xfc,0xfe,0xfd,0xfb,0xfe,0x7c,0x7c,0x7a,0x7c,0x7c,0x7b,0x7b,0x7e,0xff,0xfe,0xfe,0xff +,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0x7e,0x7e,0xff,0x7e,0x7d,0x7d,0x7d,0xfe,0x7e,0x7c,0x7e,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xfe,0xff,0xfd,0xfe,0xfe +,0x7e,0xff,0xfc,0xfd,0xff,0xfe,0xfe,0xfd,0xfe,0xff,0x7e,0x7d,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe +,0x7e,0xfe,0xff,0xff,0xff,0x7d,0xff,0xff,0xfe,0xff,0xff,0x7e,0xfd,0xfc,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfc,0xfc,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xff +,0xfe,0xfd,0xfe,0xfc,0xfe,0x7e,0xff,0xfe,0xfd,0x7e,0x7e,0xfe,0xfe,0xfc,0xfe,0xfe,0x7e,0xfe,0xfc,0xfd,0xff,0xfe,0xfd,0xfb,0xfc,0x7e,0xfe,0x7e,0xfe,0xfd,0xfe,0x7d +,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0x7e,0xfd,0xfc,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0xfd,0xff,0xff,0xfd,0xfc,0xfd,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0xfc,0xfe +,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfb,0xfd,0xfc,0xfd,0xfb,0xfc,0xfd,0xfc,0xfe,0xfd,0xfd,0xfc,0xfd,0xfe,0xff,0xfd,0xfb,0xfe,0xfc,0xfd,0x7e,0xfc,0xfd,0xff +,0xff,0xfd,0xfc,0xfd,0xfe,0x7e,0xfd,0xfc,0xfd,0xfc,0xfe,0xff,0x7e,0xfe,0xfc,0x7e,0xfe,0xfd,0xfe,0xfd,0xfe,0xff,0xfd,0xfd,0xfd,0xff,0x7e,0x7e,0xfe,0xff,0xff,0x7e +,0x7e,0x7d,0xfe,0xfd,0xfd,0xff,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0xfd,0xff,0x7e,0x7e,0xfe,0xff,0xfe,0x7e,0x7d,0xfe,0x7e,0xfd,0x7e,0xff,0xff,0xfd,0xfa,0xff,0x7c +,0x7a,0x7b,0x7c,0x7d,0x7c,0x79,0x7b,0x7d,0xfd,0x7e,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0xfd,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0x7d,0xff,0xff,0x7d +,0x7c,0x7e,0x7e,0x7e,0xfe,0x7d,0x7c,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7d +,0x7d,0xff,0xfe,0xfe,0x7d,0x7d,0x7d,0xfe,0xfe,0xfe,0x7e,0xff,0xfd,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfd,0xfb,0xfd,0x7e,0xfe,0xfe,0xfd,0xfd,0xff,0xfe +,0xfe,0xfd,0xfd,0xff,0x7e,0xff,0x7d,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfc,0xfe,0x7e,0xfd,0xfe,0xfd,0xfc,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e,0x7e,0xfd,0xfe,0xfe,0xff +,0x7e,0xfd,0xfb,0xfd,0x7d,0x7b,0x7d,0x7e,0x7d,0x7d,0x7e,0xff,0xfd,0xfb,0xfd,0xff,0xfe,0xfd,0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0x7e +,0xfe,0x7e,0xfe,0xfe,0x7e,0x7d,0xfe,0xff,0xfe,0xfe,0xff,0xfe,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xff,0xfd,0xfd,0xfc,0xfc,0xfd,0xfd,0xfe,0xfe,0xfd,0xfe,0xff +,0xfd,0xfe,0xfe,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfe,0xfd,0xfe,0xfc,0xfb,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e +,0xff,0xfe,0xfc,0xfd,0xfd,0xfc,0xfe,0xfd,0xfd,0xfd,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfe +,0x7e,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfb,0xfd,0xfe,0x7b,0x7d,0x7c,0x7d,0x7c,0x7b,0x7c,0x7d,0xfe,0xff,0xff,0x7e,0xff,0xfd,0xfd,0x7e,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e +,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfd,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xff,0x7e,0x7e,0x7e,0x7e,0xff,0xff +,0xfe,0xff,0xfe,0xfe,0x7e,0xff,0xfe,0xfd,0xfe,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe +,0xfd,0xfd,0xfe,0xfd,0x7e,0xfe,0xff,0xfe,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0xfe,0xff,0xff,0xfe,0xff,0x7e +,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfc,0xfe,0x7d,0x7c,0x7c,0x7c,0x7e,0x7d,0x7d,0xff,0xfe,0xff,0x7e,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e +,0x7d,0xfe,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xff,0xff,0xfd,0xfe,0xff,0x7e,0x7e,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd +,0xfe,0xfc,0xfc,0xfb,0xfd,0xff,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfd,0xfd,0x7e,0xfe,0xfe,0xfd,0xff,0x7e +,0xfe,0x7e,0xff,0xfd,0xfe,0xfe,0xfe,0xfc,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0x7e,0xfe,0xfe,0xfd,0xff,0x7e,0x7d,0x7e,0xff,0x7e,0x7e +,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xfd,0xfd,0xfd,0x7d,0x7b,0x7b,0x7c,0x7c,0x7b,0x7c,0x7c,0x7d,0xff,0x7e,0x7d +,0x7c,0x7e,0xff,0x7e,0x7e,0x7d,0x7e,0x7e,0xfe,0x7d,0x7c,0x7d,0x7d,0x7d,0x7c,0x7b,0x7b,0x7c,0xff,0x7e,0x7d,0x7c,0x7c,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0x7e +,0x7d,0xfe,0xfe,0xfe,0x7e,0x7d,0x7d,0x7e,0xfe,0xff,0x7e,0x7e,0x7e,0xff,0x7e,0x7d,0x7d,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7d,0xfe,0xfe,0xfe,0xff +,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0xff,0xfe,0xfc,0xfc,0xfe,0x7d,0x7d,0xff,0xff,0xff,0xff,0x7d,0x7d,0x7d,0x7e,0x7c,0x7c,0x7d,0x7e,0xfe,0xff,0x7e +,0x7d,0x7e,0xff,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0xff,0x7e,0x7e,0xff,0xff,0x7e,0x7d,0x7d,0x7e,0x7e,0xff,0x7d,0x7d,0xff,0xfe,0xfd,0x7e,0x7c,0x7b,0x7d,0x7e,0x7d,0x7d +,0x7d,0x7e,0xfe,0xff,0x7e,0x7c,0x7d,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0xff,0xff,0xff,0x7e,0x7e,0xfe,0x7e,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7d,0x7c,0x7e,0xff,0xff,0xff +,0x7e,0xfe,0xff,0x7e,0xff,0x7d,0x7e,0xff,0xfd,0xfe,0x7e,0xfe,0xfe,0xfe,0x7e,0xff,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0x7d,0x7d,0xff,0xfd,0xfe,0x7e +,0x7d,0x7e,0xff,0xff,0x7e,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0x7d,0x7d,0x7e,0xff,0x7e,0x7d,0xfe,0x7e,0xff,0xfe,0x7e +,0x7e,0xff,0xfd,0xfd,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfc,0xfe,0x7c +,0x7a,0x7a,0x7b,0x7b,0x7a,0x79,0x7b,0x7c,0x7d,0x7d,0x7b,0x7c,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0xff,0xff,0x7e,0x7d,0x7d,0x7e,0x7d,0x7d,0x7c,0x7d,0xff,0x7d,0x7c +,0x7b,0x7b,0x7c,0x7e,0x7e,0x7d,0xfe,0xff,0x7e,0x7e,0x7d,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xfe,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e,0xff,0xfe,0x7e,0x7d +,0x7e,0xfe,0xfd,0xfe,0x7e,0x7c,0x7e,0xfe,0xff,0x7e,0x7d,0x7e,0xfd,0xfe,0xfe,0xff,0x7d,0x7d,0x7d,0x7d,0x7e,0x7d,0xff,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0x7d +,0x7e,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfd,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfe,0x7d,0xff,0xfe,0xfe,0xfe,0x7d +,0x7d,0xfe,0xfc,0xfb,0xff,0x7d,0x7d,0x7e,0xfe,0x7e,0x7d,0x7d,0xff,0xfc,0xfd,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xff,0xfe,0xff +,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0xff,0xfc,0xfe,0xfe,0xff,0xfe,0xfd,0xfd,0xfd,0xfe,0xff,0x7e,0xfd,0xfc,0xfd,0xfe +,0xfe,0x7e,0xfd,0xfd,0x7e,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0x7c,0xfe,0xfd,0xfe,0xfe,0xff,0xfd,0xfd,0xfd,0xfe,0xff,0x7e,0xfe,0xfd,0xff,0x7e +,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfc,0xfe,0x7d,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0x7c,0xff,0xfe,0x7e,0x7e +,0x7d,0xff,0xff,0xfe,0xff,0x7e,0xfe,0xfe,0xfc,0x7e,0x7b,0x7c,0x7b,0x7c,0x7b,0x7b,0x7a,0x7b,0x7d,0x7e,0x7c,0x7d,0x7e,0xfe,0xff,0xff,0xff,0x7d,0x7d,0x7e,0x7e,0x7e +,0x7e,0x7e,0xff,0xff,0x7d,0x7d,0x7d,0x7e,0x7e,0x7d,0x7c,0x7d,0x7e,0xff,0x7e,0x7e,0x7d,0xfe,0xff,0xfe,0xfe,0xff,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e +,0x7e,0x7e,0xfe,0xff,0x7d,0x7d,0x7d,0xfe,0xff,0x7e,0x7d,0x7d,0x7e,0xff,0xff,0x7d,0x7d,0xfe,0xfd,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7c,0xff,0xff,0x7d,0x7e +,0x7e,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0xfd,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfe,0x7c,0x7d,0x7e,0xfe,0xff,0x7d,0xff,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0xfe,0xfd +,0xff,0xfe,0xfe,0xfd,0x7e,0x7e,0xff,0x7e,0xfe,0x7e,0x7d,0x7d,0xff,0xfe,0xfc,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7c,0x7d,0xff,0xfe,0xfd,0xfe,0xff,0xfd,0xfd,0xff,0xff +,0x7d,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0x7d,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0xfe +,0xfe,0xfe,0xfc,0xfc,0xfe,0xfe,0xfd,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0xfe,0xfe,0xff,0xfd,0x7e,0x7e,0xff,0xfe,0xfd,0x7d,0xff,0xff,0xff,0xfd,0xfe,0x7e +,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0x7c,0x7d,0x7e,0xfe,0xfe,0x7e,0xfe,0xfd,0xff,0xfe,0x7e,0x7d,0xff,0xfe,0xfc,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xfe +,0x7d,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0x7e,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0x7d,0xff,0xfe,0xfc,0xfe,0xfe,0x7d,0x7c,0x7d,0x7d,0x7c,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d +,0x7c,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0xfd,0xff,0x7d,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0x7d,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0xff,0xfd,0xfd,0xff +,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0xfd,0xfc,0xfe,0xff,0xfe,0xfd,0xff,0xfe,0xfd,0x7e,0xff,0xfd,0xfb,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0x7e,0xfc,0xfd,0x7e +,0xfe,0xff,0xfd,0x7e,0xff,0x7e,0xff,0xfe,0xfd,0xfd,0xff,0x7e,0xfc,0xfc,0x7e,0xfe,0x7e,0xfe,0xfd,0xfb,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0x7e,0xfe,0xfe,0xfd,0xfb,0xff +,0xfe,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0xfd,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0x7e,0xfd,0xfa,0xfb,0xfe,0xff,0xfe,0xfe,0xfe,0x7e +,0xfe,0xfd,0xfd,0xfd,0xfe,0x7e,0xfd,0xfc,0xfd,0xfd,0xfe,0xfe,0xfd,0xfb,0xfc,0xff,0xff,0xfd,0xfc,0xfd,0xfd,0xfe,0xfe,0xfc,0xfb,0xfe,0x7e,0xff,0xfd,0xfd,0xfd,0xfd +,0xfe,0xfe,0xfc,0xfd,0xfe,0xfe,0xfe,0xfa,0xfb,0xfd,0xfd,0xfe,0xfb,0xfb,0xfc,0xfd,0xfe,0xfd,0xfc,0xfc,0xfe,0xfe,0xff,0xfd,0xfc,0xfe,0xff,0xfd,0xfe,0xfb,0xfd,0xfd +,0xfd,0xfe,0xfb,0xfc,0xfe,0x7e,0xfe,0xfc,0xfb,0xfe,0xfc,0xfe,0xff,0xfd,0xfd,0xfc,0xfd,0xfc,0xfa,0xfb,0xff,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0xfd,0xfc,0xfd,0xfe +,0xfd,0xfd,0xfd,0xfe,0xfd,0xfe,0xfe,0xfc,0xfc,0xfe,0x7d,0xff,0xfe,0xfd,0xfe,0x7e,0xff,0xff,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xff,0x7d,0x7e,0xfd,0xfc,0xfc +,0x7c,0x7c,0x7d,0x7e,0x7c,0x7c,0x7d,0x7e,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0xfe,0x7e,0xfe,0xfe,0xfc,0xfe,0x7e,0xfe,0xff,0xfd,0x7e,0x7d +,0xff,0x7d,0xfe,0xff,0x7d,0x7d,0xff,0xfc,0xfd,0xff,0x7e,0x7d,0x7d,0xfd,0xfe,0xfe,0xfe,0xfc,0xfb,0xfd,0xfd,0xfd,0xfe,0xfd,0xfd,0xfe,0x7d,0xff,0xfe,0xfe,0xff,0xff +,0xfe,0xff,0xfd,0xfe,0xff,0x7e,0xff,0xfd,0xfe,0x7e,0xfe,0xfe,0xfd,0xfc,0xfe,0xfe,0xff,0xfe,0xff,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfd,0x7e,0xff,0xff,0xfd,0xfd,0x7e +,0xfe,0xff,0xfe,0x7e,0x7e,0x7d,0x7e,0xff,0xff,0xfe,0x7e,0xff,0xff,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe +,0xfe,0xfe,0xfd,0xfc,0xfb,0xfe,0x7d,0x7e,0xff,0x7d,0x7e,0x7d,0xfe,0xfc,0xfd,0xfe,0xfe,0xfe,0xfb,0xfc,0xff,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0x7d,0xfe,0xfd,0xfe,0x7e +,0x7d,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfc,0xfe,0xfe,0xfd,0xfc,0xfc,0xfe,0xff,0xff,0xfe,0xfa,0xfa,0xfc,0xfe,0xfe,0xfc,0xfb,0xfd,0xfd,0xfd,0xfc,0xfb,0xfd,0x7e +,0x7e,0xfe,0xfc,0xfc,0xfe,0xfd,0xfd,0xfc,0xfd,0xfd,0xfe,0x7e,0xfe,0xfc,0xfd,0xff,0xfe,0xfd,0xfe,0xfe,0xfd,0xfe,0xfe,0xfe,0xfb,0xfc,0xfe,0xfd,0xfd,0xfc,0xfd,0xfd +,0xfe,0xfe,0xfc,0xfe,0x7e,0x7e,0x7d,0xfe,0xfe,0xfd,0xfe,0x7d,0xff,0xfd,0xfd,0x7e,0xff,0xfd,0xfd,0xfc,0xfd,0xfe,0xff,0xff,0xfd,0xfe,0xfd,0xfe,0xff,0xfc,0xff,0xfe +,0xff,0xfd,0xfb,0xfc,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfd,0x7e,0x7e,0x7d,0xfe,0x7e,0x7d,0x7e,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0x7e,0xfd,0xfe,0xfe +,0xff,0x7e,0xfd,0xfe,0xfe,0x7e,0xff,0xfe,0xfc,0xff,0x7d,0x7e,0x7e,0xff,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xfc,0xfc,0xfe +,0xfe,0xfe,0xfe,0xfd,0xff,0x7d,0x7e,0xff,0xfd,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xfe,0xff,0x7e,0xff,0xfd,0xfd,0xfe,0x7e,0x7e,0x7e,0xfd,0xff,0xff +,0xfd,0xfe,0xfc,0xfc,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0xfd,0xfe,0x7e,0x7d,0x7b,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0x7e,0x7e,0xfe,0xfe,0xfc,0xfe,0xfe +,0xfe,0x7e,0xfc,0xfd,0x7e,0x7e,0xfe,0xfd,0xfd,0xfd,0xfe,0xfe,0xfc,0xfc,0xfd,0xfd,0xfe,0xff,0x7e,0x7e,0x7d,0x7c,0x7c,0xfe,0xfc,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0x7e +,0xff,0xfe,0xfd,0xfd,0xfd,0xfe,0xff,0xfe,0xff,0xfe,0x7e,0x7d,0xfe,0xfc,0xfe,0xfe,0x7e,0x7e,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xfc,0xfe,0xfe,0x7e,0xfd,0xfc,0xfd,0xfe +,0xfd,0xfc,0xfb,0xfb,0xfc,0xfe,0xff,0xfe,0xfd,0xfd,0x7e,0x7e,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfc,0xfd,0xff,0xfe,0x7e,0xff,0xfe,0x7e,0xff,0x7e,0xfe,0xfe,0xff,0x7e +,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0xff,0xff,0xff,0xfe,0x7d,0x7e,0x7d,0xff,0xff,0x7e,0x7e +,0x7d,0x7e,0x7e,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0xff,0xfe,0xff,0x7d,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0x7d,0x7c,0x7d,0x7b,0x7c,0x7c,0x7d,0xff,0xfe,0x7e +,0x7e,0xfe,0xfe,0xff,0x7d,0x7e,0x7e,0x7e,0x7e,0xff,0xff,0x7d,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0x7e,0x7d,0x7d,0x7d,0x7e,0xfe,0x7e,0xff,0x7e,0x7e,0x7e,0x7d,0x7d +,0x7c,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xfe,0xff,0xfe,0xfe,0xfd,0xff,0xfd,0xfd,0xff,0xff,0x7d,0xfe,0xff,0x7e,0xff,0xfe,0xfd,0xfe,0xff,0xfe,0x7e,0xfe,0xff,0xfe,0xff +,0x7e,0xfe,0xff,0xfe,0xfe,0x7d,0x7e,0x7d,0x7e,0x7d,0x7e,0xff,0x7e,0xfd,0xff,0x7d,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfd,0xff,0x7e,0x7e,0xff,0x7e,0x7d +,0x7d,0x7e,0x7e,0xff,0xff,0x7e,0x7d,0x7e,0xff,0x7e,0x7d,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xfd,0xfe,0xfe,0xfe,0x7d,0x7c,0x7e,0x7e,0x7d +,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfc,0xfc,0xfe,0xfe,0xff,0x7e,0xff,0xff,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0x7e,0xfd,0xfe,0x7e +,0xff,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0x7e,0x7e,0xff,0x7e,0x7e,0x7e,0xff,0xfd,0xff,0xfe,0xfe,0xff,0xff,0xff,0x7e +,0x7d,0x7e,0x7e,0x7e,0xfe,0xff,0xfe,0xff,0xfe,0xfd,0xff,0xff,0x7e,0xfe,0xfe,0xff,0xfd,0xfe,0xfd,0xfd,0xff,0xfe,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xff,0x7e +,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xff,0xfd,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0x7d,0x7e,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xfe,0xff,0x7e,0x7e,0x7e,0x7e,0xfe,0xff +,0x7e,0x7c,0x7d,0x7c,0x7b,0x7c,0x7b,0x7c,0x7d,0x7d,0x7d,0x7e,0x7d,0xff,0x7e,0x7e,0x7d,0xfe,0xfe,0x7e,0xff,0x7e,0x7e,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0xff,0xfe,0xff +,0x7e,0x7e,0xff,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e,0x7c,0x7b,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xff,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0xff,0x7e,0x7d,0x7e,0xff,0xff +,0x7e,0xfe,0xfe,0x7e,0xff,0xff,0x7e,0x7e,0x7e,0x7e,0x7e,0xff,0x7e,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0x7c,0x7d,0x7e,0xff,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe +,0x7e,0x7e,0xfe,0xfe,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0x7e,0xfe,0x7e,0xfd,0xff,0xff,0xff,0x7e,0xfd,0xfe,0xff,0x7e,0x7e,0x7e,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0xfd,0x7e +,0xff,0x7e,0xfe,0xfe,0xfd,0xfc,0xfe,0xff,0xff,0x7e,0x7d,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0x7e,0xfd,0xfe,0x7e,0xff,0xfe,0xfd,0xfd,0xfd,0xff,0xfe,0xfd,0xfe,0xff,0xff +,0xfe,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0x7e,0x7e,0xff,0xfc,0xfd,0xfe,0xff,0xff,0xfd,0xfb,0xfc,0xfd,0xfc,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xfe,0xfd +,0xff,0xff,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,0xfe,0xfe,0xfd,0x7e,0xfd,0xfc,0xfb,0xfc,0xfd,0xfe +,0xfe,0xfd,0xfc,0xfd,0xfe,0xfe,0xfd,0xff,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfd,0xff,0xfe,0x7e,0xff,0xfe,0xfd,0xfe +,0x7e,0xfe,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xfd,0xfe,0xfd,0xfe,0x7e,0x7c,0x7b,0x7b,0x7a,0x7b,0x7d,0x7d,0x7d,0x7c,0x7e,0x7e,0xff,0x7d,0x7d,0x7c,0x7e,0xfe,0xff,0x7e +,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0x7d,0xfe,0xfe,0x7d,0xff,0x7e,0xff,0xfd,0xfe,0x7e,0x7c,0x7e,0xfd,0xfe,0xff,0xff,0xfe,0xfc,0xfb,0xfd,0xfd,0xfe,0xfe,0xfd,0xfe,0x7e +,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0xff,0xff,0x7e,0xfd,0xfe,0x7e,0x7e,0xfe,0xff,0xfe,0xfe,0xff,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0x7e +,0xfe,0xfd,0xfd,0xff,0xff,0x7e,0x7e,0x7e,0xff,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0x7e,0x7d,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0xfe +,0x7e,0x7e,0xfe,0xff,0xff,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xff,0xfd,0xfc,0x7e,0xff,0x7e,0x7c,0x7d,0x7d,0xfe,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0x7d,0x7d +,0x7d,0x7c,0x7e,0x7e,0x7d,0x7c,0x7d,0xff,0xff,0x7e,0x7c,0x7c,0x7d,0xfe,0x7d,0x7b,0x7c,0x7d,0xfe,0x7e,0x7d,0x7d,0x7d,0xff,0xfe,0xff,0x7e,0x7d,0xfe,0xfd,0xfe,0xff +,0x7e,0x7d,0xfd,0xfc,0xfe,0x7e,0xff,0xfd,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0xfe +,0x7e,0x7d,0x7e,0xff,0x7c,0x7d,0xff,0xfd,0xfe,0xff,0x7e,0x7d,0xfe,0xfe,0xfd,0xff,0x7d,0x7e,0x7e,0xfe,0xff,0x7d,0x7e,0x7d,0xff,0x7e,0x7e,0x7d,0xff,0xff,0x7e,0x7e +,0x7e,0xfe,0xfe,0xff,0xff,0x7c,0x7b,0x7b,0x7c,0x7c,0x7d,0x7e,0x7e,0xfd,0xfe,0xfe,0xfd,0xfe,0xfd,0xfd,0x7e,0xfd,0xfe,0x7d,0x7d,0x7c,0x7c,0x7c,0x7c,0x7d,0x7c,0x7d +,0x7e,0xff,0x7e,0xfe,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7c,0x7c,0x7e,0x7e,0x7d,0x7d,0x7e,0x7e,0x7e,0x7d,0x7c,0x7e,0xff,0x7e,0x7d,0x7d,0x7d,0x7d,0xff,0xfe,0xfe +,0xff,0xfe,0xfd,0x7e,0x7e,0x7e,0xff,0xfe,0xff,0x7d,0x7d,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0x7c,0x7c,0x7e,0xfe,0xfd,0x7d,0x7d,0x7d,0x7d,0xfe,0x7d,0x7c +,0x7d,0xff,0xff,0x7e,0x7d,0x7d,0x7d,0x7e,0x7e,0x7d,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0x7e,0xff,0xff,0x7e,0xff,0xfd,0xfe,0xff,0xff,0xff,0xfd,0xff,0x7e +,0x7d,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xfd,0xfe,0x7e,0xff,0x7e,0x7e,0xff,0xfe,0x7e,0x7d,0xff,0xfd,0xfd,0x7e,0x7e,0xff,0x7e,0xfe,0x7e,0xfe,0xfe,0x7c,0x7e,0x7d,0x7c +,0x7c,0x7e,0xff,0x7d,0x7d,0x7d,0x7c,0x7d,0xff,0x7e,0x7e,0xfe,0x7e,0xfd,0xfe,0x7e,0xff,0xfe,0xfc,0xfd,0xff,0xfd,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0x7e,0x7e +,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfe,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0x7e,0xfd,0xfc,0xfc,0xfd,0xfe,0xfe,0xfc,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe +,0xff,0xfe,0xfd,0xfd,0xfe,0xfd,0xfd,0xfd,0xfb,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfc,0xfc,0xfc,0xfc,0xfe,0xff,0xfd,0xfd,0xfc,0xfe,0xfe,0xfd,0xfd,0xfe,0xff,0x7e +,0x7e,0x7e,0xfd,0xfd,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0x7d,0xfe,0xfd,0xfe,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0x7e,0xff +,0xff,0xff,0x7d,0x7c,0x7b,0x7a,0x7b,0x7c,0x7d,0x7d,0x7e,0xff,0xfe,0xfd,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e +,0xff,0xff,0x7e,0xff,0x7d,0x7d,0x7d,0xff,0xfe,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xff,0xff,0x7e,0x7d,0x7d,0x7e,0xfe,0xfe,0x7d +,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0x7d,0xfe,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfd,0xfd,0x7e +,0xff,0xff,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfd,0xff,0x7d,0x7e,0x7e,0xff,0x7e,0x7e,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0x7e,0xff,0xff,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0x7e +,0x7d,0x7e,0xfe,0xfe,0xfe,0xfd,0xfe,0x7d,0x7d,0x7c,0x7b,0x7c,0x7d,0x7d,0x7c,0x7b,0x7c,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfe,0xfe,0xfe +,0xfe,0xff,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfc,0xfd,0xff,0xff,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0xfd,0xfe,0xff +,0xfe,0x7e,0xfe,0xfe,0xfe,0xff,0xfd,0xfc,0xfd,0xfe,0x7e,0xfe,0xfe,0xfd,0xfc,0xfe,0xfe,0xfe,0xfc,0xfe,0xfd,0xff,0xff,0x7d,0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfe,0x7e +,0xfe,0xfd,0xfd,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0x7e +,0x7e,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfd,0xff,0xfc,0xfd,0xfe,0x7e,0x7d,0x7c,0x7d,0x7e,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe +,0x7e,0xfe,0xfe,0xfd,0xfe,0xff,0xfe,0xff,0xfe,0xfd,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xff,0xfe,0xff,0x7e,0xfe,0xfd,0xfd,0xfd,0x7e,0xff,0xfd,0xfd,0xfd,0xff +,0x7e,0xfe,0xfd,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfb,0xfb,0xfd,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe +,0xfe,0xfc,0xfc,0xfc,0xfe,0x7e,0xfe,0xfd,0xfc,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0x7e,0xfe,0xfd,0xfd,0x7e,0x7d,0x7e,0xfe,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xff +,0xff,0xfe,0xfd,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0x7e,0xff,0x7d,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0xfd,0xfc,0xfd,0xfe +,0x7d,0x7e,0xfc,0xfe,0xff,0xff,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfd,0xfd,0xff,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd +,0xfe,0xfc,0xfb,0xfb,0xfd,0xfe,0xfd,0xfc,0xfe,0xfe,0xff,0xfe,0xfd,0xfd,0xfd,0x7d,0x7e,0xfe,0xfe,0xfd,0xfe,0xfe,0xfd,0xfc,0xfa,0xfc,0xfe,0xfe,0xfe,0xfe,0xfe,0xff +,0xfe,0x7e,0xff,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfe,0xff,0xfe,0xfe,0xfc,0xfd,0x7e,0xff,0xff,0xfd,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfc,0xfd,0xff +,0xff,0xfd,0xfc,0xfc,0xfd,0xfe,0xfe,0xfc,0xfc,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0x7e,0xff,0xfd,0xfe,0x7e,0xfd,0xfc,0xfd,0x7e,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7c +,0x7d,0xfe,0xfc,0xfd,0xfd,0xfe,0xfe,0xfb,0xfc,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0x7d,0x7c,0x7e,0xfe,0x7d,0x7d,0x7d,0x7d,0x7e,0x7d,0x7e,0x7e +,0x7e,0xff,0xfe,0x7d,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0x7d,0xff,0xfd,0xfd,0xfd,0x7e,0xfe,0xfc,0x7e,0xfd,0xfe,0x7e,0xff,0xfd,0xfd,0xff,0x7d,0x7d,0x7e,0xff,0xff,0x7d +,0x7d,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0x7e,0xff,0xfe,0xff,0xff,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xff,0x7e,0x7e,0x7d,0x7e,0x7e,0x7d,0x7d,0x7e,0xff,0x7e,0x7e,0x7d +,0x7c,0xfe,0xfd,0x7e,0x7d,0x7d,0x7e,0xff,0x7e,0x7d,0x7d,0x7d,0x7c,0xff,0x7e,0x7a,0x7b,0x7b,0x7e,0x7d,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7d,0xfd,0xfb,0xff,0x7c,0x7d +,0x7b,0x7c,0x7e,0xfe,0x7e,0x7d,0xfe,0xfe,0xff,0x7c,0x7e,0xff,0xfe,0xfe,0xfd,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e +,0x7e,0x7d,0x7d,0x7e,0xfe,0x7d,0x7d,0xfe,0xff,0xfe,0xff,0x7e,0xfe,0xfd,0xfc,0xfe,0xff,0xfe,0xfc,0xfe,0xfe,0x7e,0x7e,0xfd,0xfe,0xff,0x7e,0xff,0xfe,0xfd,0xfe,0x7e +,0x7e,0x7e,0xff,0xfe,0x7e,0x7e,0x7d,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0x7d,0x7e,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0xff,0xfe,0xfd,0xfd,0x7e,0xfe,0x7e,0x7e,0xfe,0x7e,0x7d +,0xfe,0xfc,0xfd,0x7e,0x7d,0x7e,0x7d,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d +,0x7e,0x7e,0x7d,0x7a,0x7a,0x79,0x79,0x79,0x79,0x7b,0x7b,0x7c,0x7d,0x7e,0x7e,0x7d,0x7c,0x7d,0x7d,0x7d,0x7d,0x7c,0x7c,0x7e,0x7d,0x7d,0x7c,0x7c,0x7c,0x7e,0xfe,0x7d +,0x7d,0x7d,0x7d,0x7d,0x7d,0x7c,0x7c,0x7e,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0xff,0xff,0x7e,0xfe,0xff,0x7e,0x7e,0x7e,0xfe,0x7e,0xfd,0x7e,0x7d,0xff,0x7e,0x7e,0x7e,0x7e +,0x7c,0x7e,0x7d,0x7e,0x7e,0x7c,0x7c,0x7d,0xfe,0x7e,0x7d,0x7d,0x7e,0x7e,0x7e,0x7c,0x7d,0x7d,0x7e,0x7e,0x7c,0x7d,0xff,0xfc,0xfe,0x7e,0x7e,0x7b,0x7d,0xff,0x7e,0x7e +,0x7d,0xff,0xfe,0x7e,0x7d,0xff,0x7e,0xfe,0x7e,0x7e,0x7e,0x7d,0x7e,0xff,0x7d,0x7c,0x7d,0x7b,0x7d,0x7d,0x7e,0x7d,0x7e,0x7e,0x7e,0x7d,0x7d,0x7d,0x7d,0xff,0xff,0x7d +,0x7d,0x7e,0x7e,0x7e,0x7e,0x7d,0xfd,0xfe,0x7d,0x7c,0x7c,0x7b,0x7a,0x7d,0x7b,0x7b,0x7d,0x7e,0x7e,0x7e,0x7d,0x7d,0xff,0xfe,0xff,0x7d,0x7b,0x7c,0x7e,0xff,0x7e,0x7b +,0x7c,0x7e,0x7e,0x7e,0x7c,0x7b,0x7d,0x7d,0xff,0x7c,0x7c,0x7d,0x7d,0xfe,0x7d,0x7d,0x7c,0x7e,0x7e,0x7d,0xff,0x7e,0x7d,0x7e,0xfe,0xff,0x7e,0x7e,0xfd,0xfe,0xfe,0x7d +,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0xfe,0x7d,0x7d,0xff,0xfe,0xfd,0xfd,0x7e,0xfd,0xfd,0xfe,0x7d,0x7d,0x7d,0x7c,0x7d,0x7e,0x7e,0xfe,0xfd,0xfd,0xfd,0xfe +,0xfc,0xfc,0xfb,0xfd,0xff,0xff,0xfe,0xfe,0xfe,0x7d,0x7d,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0x7e,0xfe,0xfd,0x7e,0x7e,0x7e,0xfe,0x7e,0xfe,0x7e,0x7e,0xfe,0xfe,0x7e,0xff +,0x7e,0x7e,0xfe,0xfe,0xfd,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0x7e,0x7c,0x7c,0x7b,0x7e,0x7d,0x7e,0x7c,0x7c,0x7e,0x7e,0xfe,0xff,0x7e,0x7d,0xff,0x7e,0x7e,0x7d +,0x7e,0xff,0xfe,0xfe,0x7e,0x7e,0xff,0x7d,0x7e,0xff,0x7d,0x7e,0xff,0xfd,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfe,0xfd,0xff,0xff,0xfe +,0xfe,0xfd,0xfc,0xfc,0xff,0xff,0xfe,0xfd,0xfd,0xfe,0xff,0x7e,0xfe,0xfe,0xff,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xfd,0xff,0xfe,0xfe,0x7e,0x7e,0x7e +,0xff,0xfe,0xfd,0xfd,0xff,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0xfe,0xfc,0xfe,0xfd,0xff,0xfe,0xfe,0xfd,0xfe,0x7d,0x7d,0x7e,0xfe,0xfc,0xff,0x7e,0x7d,0x7e,0xff,0x7e,0xff +,0xff,0xff,0xfd,0xff,0xff,0xfe,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0xfd,0xfd,0xfc,0xfc,0xff,0x7e,0x7d,0x7d,0x7e,0xfe,0x7e,0xff,0xfe,0xfd,0xfc,0xfc,0xfd +,0xfe,0xfd,0xfe,0xfd,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfe,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xff,0x7e,0xfe,0xfd,0xfc,0xfd,0xfe,0xfd,0xfe,0xfc,0xfc,0xfd +,0xfd,0xfc,0xfb,0xfc,0xfd,0xfe,0xfd,0xfc,0xfa,0xfd,0xfd,0xfc,0xfd,0xfd,0xff,0xfe,0x7e,0xfe,0xfe,0xfd,0xfd,0x7e,0xff,0xfd,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0xfd,0xfe +,0xff,0xfe,0xff,0x7e,0xff,0xfe,0xfe,0xfc,0xfa,0xfc,0xfe,0xfe,0xfc,0xfd,0xfd,0xfe,0x7e,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xfc,0xfe,0x7d,0x7e,0x7d,0xfe,0xfe,0xfe +,0xfe,0xfe,0xfc,0xfc,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfd,0x7e,0xfe,0xfe,0xfd,0xff,0xff,0xfd,0xfd,0xfa,0xfd,0x7e,0x7c,0x7e,0x7d,0xff,0x7d,0x7d +,0x7d,0xff,0xfe,0xfd,0xff,0x7c,0x7e,0xfe,0xfe,0x7e,0x7e,0x7d,0xfe,0xfd,0xfd,0xfe,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0x7d,0x7e,0x7e,0x7e,0x7d,0x7e,0xfe,0x7e,0xff,0xff +,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xfd,0xfb,0xfe,0xfe,0xfe,0xff,0xfd,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0x7e,0x7d,0xfe,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e +,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xfd,0xff,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xfe,0xfd,0xfc,0x7e +,0xfe,0xfe,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0xfe,0xff,0xff,0x7e,0xfe,0xfc,0xff,0xfe,0x7e,0xfc,0xfd,0x7e,0xfe,0xfe,0xf9,0xfc,0x7e,0x7e +,0xff,0xff,0xff,0xfe,0xfe,0xff,0x7e,0xfe,0xfc,0xfd,0xfd,0xfe,0xfd,0xfc,0xfc,0xfd,0xfc,0xfd,0xfc,0xfa,0xfe,0xfd,0xfe,0xfc,0xfc,0xff,0xff,0xfe,0xfd,0xfc,0xfd,0xfd +,0xfd,0xfe,0xfb,0xfc,0xfe,0xff,0xfd,0xfb,0xfd,0xfc,0xfd,0xfb,0xf9,0xf9,0xfc,0xfe,0xfd,0xfc,0xfb,0xfb,0xfd,0xfd,0xfe,0xfc,0xfc,0xfe,0xfd,0xfe,0xfc,0xfc,0xfb,0xfd +,0x7e,0xfd,0xfd,0xfb,0xfe,0xfe,0xfb,0xfc,0xfa,0xfc,0xff,0xfc,0xfd,0xfd,0xfd,0xfd,0xfc,0xfb,0xfa,0xfd,0xfd,0xff,0xfd,0xfa,0xfb,0xfb,0xfe,0x7e,0xfe,0xfc,0xfe,0xfe +,0xfe,0xfd,0xfc,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfd,0xfd,0xfd,0xff,0xfe,0xfd,0xfb,0xfe,0xff,0xfe,0xfd,0xfc,0xfe,0xfe,0xfe,0xfd,0xfc,0xfe,0x7e +,0xff,0xfe,0xfc,0x7e,0x7b,0x7c,0x7e,0xfe,0xff,0x7d,0x7d,0x7e,0xfe,0xfd,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0x7e,0x7d,0xff,0xfe,0xfe,0xff,0x7e +,0xfe,0xfe,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xfc,0xfd,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfb,0xfe,0xfe,0xff,0xfe,0xfe,0xfe,0xff +,0x7e,0xfe,0xfd,0xff,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7d,0x7e,0x7e,0xfb,0xfe,0x7d,0x7e,0x7e,0xfe,0x7e,0x7c,0x7e,0xff,0xfd,0xfc,0xfb,0xfd,0xfe,0xfd,0xfc,0xfe,0x7d +,0x7e,0x7e,0x7e,0xfd,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0xff,0xff,0x7e,0xff,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0xfe,0x7e,0x7d,0xff,0xfd,0xff,0x7e,0x7e,0x7e,0xff,0x7e,0x7e +,0xff,0x7e,0xff,0x7d,0xfe,0x7e,0x7d,0xfc,0xfe,0x7d,0x7c,0x7e,0x7c,0x7d,0xff,0x7c,0x7d,0x7e,0xfd,0xfe,0xfe,0x7e,0xff,0xfd,0xff,0x7e,0xfe,0x7e,0xfe,0xfd,0xfe,0xff +,0x7e,0xfd,0xfe,0xfe,0x7e,0xff,0x7e,0xff,0xfd,0xff,0x7e,0x7e,0xff,0xfd,0xfe,0xff,0xfe,0x7e,0xfd,0xfd,0xfe,0xff,0xfd,0xfd,0xfb,0xfe,0xfc,0xfd,0xff,0xfc,0xfe,0xff +,0x7e,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfd,0xfd,0xfe,0xfd,0xfd,0xfb,0xfd,0xff,0xfe,0xfe,0xfd,0xfa,0xfb,0xfd,0xfd,0xfb,0xfd,0xff,0xfe,0xfe,0xfd,0xfa,0xfb,0xfc +,0xfe,0xfd,0xfb,0xfb,0xfd,0xfd,0xfe,0xfe,0xfb,0xfe,0xff,0xff,0xfe,0xfd,0xfd,0xfe,0xfe,0xfc,0xfb,0xfd,0xfd,0xfe,0x7d,0xfd,0xfd,0xfe,0xff,0xff,0xfe,0xfc,0xfc,0xfe +,0xfe,0xfe,0xfc,0xfd,0xfe,0xfe,0x7e,0xfd,0xfc,0xfe,0xfe,0x7e,0xfd,0xfa,0xff,0x7d,0x7a,0x7c,0x7e,0x7d,0x7d,0x7d,0xfe,0x7e,0xfd,0xfb,0xff,0xff,0xfe,0xfe,0xfe,0x7e +,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0x7d,0x7d,0x7e,0xfe,0xfe,0xff,0xff,0x7d,0xff,0xfd,0xfd,0xff,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xff,0xfe,0xfc,0xfe,0xfe +,0xfe,0xfc,0xfb,0xfd,0xfd,0xfe,0x7e,0xfd,0xfd,0xff,0x7e,0xff,0xfd,0xfe,0x7e,0xfe,0xff,0x7e,0xfe,0xfc,0x7e,0x7c,0x7e,0xfe,0xfc,0xfe,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e +,0xff,0xfc,0xfc,0xfd,0xfd,0xfc,0xfd,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xff,0xff,0xfc,0xff,0xfd,0xfd,0xff,0xff,0x7e,0xfc,0xfe,0x7e,0x7e,0xfe,0xfd,0xfd,0xfe,0xff +,0x7e,0xfe,0xfe,0xff,0xff,0xfe,0xff,0xfe,0xfd,0xfd,0xff,0x7e,0xfd,0xfd,0xfd,0xfe,0xfe,0xfd,0xf9,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d,0x7d,0x7e,0xfe,0xfd,0xfd,0xfd +,0xfe,0xfe,0xfc,0xfd,0xfe,0x7e,0xff,0xfe,0xfb,0xfd,0x7e,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0xfd,0xfd,0xff,0xff,0xfe,0xfc,0xfd,0xfd +,0xfd,0xfc,0xfc,0xfb,0xfc,0xfe,0xfe,0xfd,0xfe,0x7e,0x7d,0x7e,0xfd,0xfe,0xfd,0xfd,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xfe,0xfc,0xfc,0xfe,0xfd,0xfd,0xfc,0xfb,0xfc,0xff +,0xfd,0xfe,0xfe,0xfe,0x7e,0xff,0xfe,0xfd,0xfc,0xfd,0xfd,0xfc,0xfc,0xfb,0xfa,0xfd,0xfe,0xff,0xfd,0xfd,0xfe,0xff,0x7e,0xfe,0xff,0xfd,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe +,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfd,0xfc,0xff,0x7d,0xff,0xff,0xfe,0xfe,0xfe,0x7e,0x7e,0xfd,0xfd,0xfe,0x7e,0xfe,0xfb,0xfc,0x7d,0x7a,0x7c,0x7d,0x7d,0x7d,0x7b +,0x7c,0xfe,0xfe,0xfd,0x7e,0x7d,0x7e,0xfe,0xff,0x7d,0x7d,0xff,0xfe,0xfd,0x7d,0x7e,0xfe,0x7e,0xff,0xfd,0xfe,0x7c,0x7d,0x7e,0xfe,0xff,0x7d,0x7e,0x7d,0xfe,0x7e,0x7d +,0x7e,0x7e,0x7e,0x7d,0x7e,0xfe,0x7e,0xfe,0xfe,0xfe,0xfb,0xfd,0xfe,0xfd,0xfd,0x7e,0xff,0xfd,0xfe,0xfe,0x7e,0xfe,0xfe,0xff,0xfc,0xfe,0xff,0x7e,0x7e,0xfe,0xff,0x7e +,0x7e,0x7e,0xfd,0xfe,0x7e,0x7e,0x7e,0xfd,0xfe,0xfe,0x7e,0x7d,0xff,0xfd,0xfe,0x7e,0xff,0xfe,0xfd,0xfc,0xff,0xfe,0xfe,0xfe,0xfc,0x7e,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe +,0x7e,0xfe,0xfe,0xfe,0xfe,0xff,0xfe,0xfd,0xfc,0xfe,0x7d,0xff,0xfe,0xfe,0x7e,0x7e,0xfd,0xff,0xfd,0xfe,0xfe,0xfe,0xff,0xfd,0xfe,0xfd,0xfe,0xff,0xfc,0xf9,0xfe,0xff +,0xff,0xff,0xfe,0xff,0x7e,0x7d,0xfe,0xff,0xfb,0xfe,0x7e,0x7e,0xfe,0xfd,0xff,0x7e,0xfe,0x7e,0xfe,0xfe,0x7e,0xff,0xfe,0xfe,0xfd,0xfd,0x7e,0x7e,0xff,0xfe,0xfe,0x7e +,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0xff,0xfd,0xfc,0xfd,0xfd,0x7e,0xff,0xfe,0xfd,0xfd,0xff,0xfe,0xfc,0xfc,0xfe,0xfe,0xfc,0xfc,0xfb,0xfd,0xfe +,0xfe,0xff,0xfd,0xfd,0xff,0xff,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0xff,0xfd,0xfd,0xfc,0xfd,0xff,0xfe,0xfc,0xfc,0xfc,0xff,0xfe,0xfd,0xfc,0xfe,0xff +,0xfe,0x7e,0xfd,0xfe,0xff,0x7e,0x7e,0xfd,0xfe,0x7e,0xfe,0x7e,0xfd,0xfd,0xfd,0xff,0x7e,0xfd,0xfd,0xfd,0xff,0xfe,0xff,0xfe,0xfc,0xfd,0xfe,0xff,0xfd,0xfc,0xfd,0xfe +,0xff,0xff,0xfc,0xfe,0x7e,0x7c,0x7d,0x7c,0x7c,0x7d,0x7b,0x7c,0x7c,0x7e,0xff,0x7e,0x7e,0xfe,0xfe,0xfe,0x7e,0x7d,0x7e,0xfe,0x7d,0x7d,0x7e,0x7c,0x7e,0xfe,0x7e,0x7c +,0x7c,0xff,0xff,0x7e,0x7d,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d,0x7e,0x7e,0xfe,0x7e,0x7e,0xff,0xfe,0xfc,0xfc,0xfd,0xfe,0xfe,0xfd,0xff,0xff,0x7e,0x7d,0xff,0xfe,0xfd,0x7e +,0xff,0xfe,0xfe,0xfe,0xff,0xff,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0x7d,0xfe,0xff,0x7d,0x7e,0xfe,0xfe,0xff,0xfe,0xff,0xff,0xfd,0xfc,0xfd,0xfe,0xfe,0xfc,0xfd,0xfd,0xff +,0xff,0xfe,0xfd,0xfc,0xfe,0xfd,0xff,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfd,0xfe,0xfe,0xff,0xff,0xfe,0xfc,0xfe,0x7e,0xff,0xfd,0xfc,0xff,0xfe +,0x7e,0x7e,0xfe,0xfd,0xfe,0xfe,0xfe,0xfd,0xfc,0xfe,0x7d,0x7d,0x7e,0x7d,0x7d,0x7d,0x7d,0x7e,0xfd,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0x7e,0x7d,0x7d,0xfe,0xfd,0xff,0xfe +,0xfe,0x7e,0xfe,0xfd,0x7e,0x7e,0x7e,0xfe,0xfd,0x7e,0x7e,0xff,0x7e,0xff,0x7e,0x7e,0x7d,0x7e,0xfd,0xfe,0xff,0x7e,0xff,0xfd,0xfe,0xfe,0xfe,0xff,0xfe,0xfc,0xfe,0xff +,0xff,0x7e,0xfd,0xfe,0x7e,0x7d,0x7d,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0xff,0xfe,0xfd,0xfe,0x7e,0xff,0xfd,0xfe,0x7d,0x7e,0x7e,0xff,0xfc,0xfe,0x7e +,0x7e,0xfe,0xfd,0xff,0x7e,0x7e,0x7d,0xff,0xfe,0xfe,0x7e,0xff,0xfe,0xff,0x7d,0x7c,0x7d,0x7e,0xff,0x7e,0x7e,0x7e,0x7d,0xfe,0xfe,0xff,0x7e,0x7e,0x7e,0xff,0x7e,0x7e +,0x7e,0x7e,0xfe,0xff,0x7d,0x7e,0x7d,0x7e,0x7e,0xff,0xff,0xfe,0xfe,0xfd,0xfe,0x7c,0x7c,0x7c,0x7d,0x7c,0x7b,0x7d,0x7d,0x7e,0xfe,0x7e,0x7d,0x7d,0xff,0xff,0x7e,0x7d +,0x7d,0x7e,0xfe,0xfe,0x7d,0x7e,0x7e,0x7e,0xff,0x7d,0x7d,0x7d,0x7e,0xfe,0x7e,0x7d,0x7d,0x7e,0xff,0xff,0x7d,0x7e,0xff,0xfe,0xfd,0xfd,0xff,0xff,0xfd,0xfc,0xfe,0xfe +,0xff,0xff,0xff,0xfe,0x7e,0x7d,0x7d,0x7e,0xff,0x7d,0x7e,0x7e,0x7e,0xfe,0xff,0x7e,0x7d,0xff,0xfd,0xfe,0x7e,0x7e,0xfe,0xfe,0xfd,0xfd,0x7e,0x7e,0xfe,0xfd,0xfe,0x7e +,0xff,0xfe,0xfe,0xfe,0xfe,0xfd,0xfd,0xfc,0xfc,0xfe,0xff,0xfe,0xfe,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0xff,0xfd,0xfd,0xff,0xfe,0x7e,0xfe,0xfe,0xfd,0xfc,0xfe +,0xff,0xff,0xfd,0xfe,0xfe,0xfe,0x7e,0xfe,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfd,0xfb,0x7e,0x7c,0x7c,0x7c,0x7c,0x7b,0x7b,0x7c,0x7e,0x7e,0xfe,0xff +,0x7e,0xff,0xfe,0xfe,0x7d,0x7d,0x7e,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0x7e,0xfe,0xfe,0xff,0xfe,0x7e,0x7e,0xff,0xfe,0xfd,0xff,0x7e,0x7e,0x7e,0xff,0xff,0xfe +,0xff,0xfe,0xfe,0xfd,0xfe,0xfe,0xfd,0xfc,0xfb,0xfd,0xfe,0xfe,0xfe,0xfc,0xfd,0xff,0x7e,0x7e,0xfe,0xfe,0x7e,0x7e,0xff,0xfd,0xfd,0xff,0x7c,0x7d,0xff,0xfe,0xfe,0x7e +,0x7e,0xff,0xfe,0xff,0x7d,0x7c,0xff,0xfd,0xfd,0x7e,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0xff,0xfe,0xfc,0xfe,0xff,0x7e,0x7e,0xff,0x7e,0xfe,0x7d,0xff,0xff,0xfe,0xfe,0x7e +,0xff,0xff,0xfe,0x7e,0xfe,0x7d,0x7e,0xfe,0xfd,0xfe,0x7e,0xff,0xfe,0xfd,0xfe,0xfe,0xff,0xfe,0xfe,0xff,0x7d,0x7c,0x7e,0xfe,0xfd,0xfe,0x7c,0x7c,0x7c,0x7d,0x7d,0x7b +,0x7d,0x7e,0xff,0xfe,0x7e,0x7e,0x7e,0xfe,0xfe,0xff,0x7e,0x7d,0xfe,0x7e,0x7d,0x7c,0x7c,0x7e,0x7e,0x7e,0x7d,0x7d,0x7d,0x7d,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0x7e,0x7d +,0x7c,0x7e,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0x7e,0xff,0x7e,0xff,0xfe,0xfe,0x7e,0x7d,0x7d,0xfe,0xfd,0xff,0xff,0x7d,0x7e,0xff,0xfe,0xfe,0xff,0xfe,0xfe,0xfd,0xff,0x7d +,0x7d,0xff,0xfe,0xfe,0x7e,0x7c,0x7d,0xfe,0x7d,0x7d,0x7d,0x7e,0xfe,0xfe,0xfe,0x7e,0xfe,0xfd,0xfc,0xfe,0x7e,0x7e,0xff,0xfe,0xff,0xfe,0x7e,0xff,0xfe,0xfe,0xfe,0x7d +,0x7e,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xff,0xff,0xff,0x7d,0x7d,0xff,0x7e,0x7e,0x7d,0x7b,0x7d,0xff,0x7d,0x7e,0x7e,0xff,0xfd,0xfe,0xfe,0x7d,0x7e,0x7e,0xfe,0xfd,0x7c +,0x7c,0x7c,0x7d,0x7d,0x7c,0x7b,0x7b,0x7e,0x7d,0x7e,0x7e,0x7d,0xfd,0xfe,0xfe,0x7e,0x7e,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0x7d +,0x7e,0x7d,0xfe,0xfe,0x7e,0x7d,0xff,0xfe,0xff,0xfe,0x7e,0xfe,0xfc,0xfd,0xfe,0xfd,0xff,0xfc,0xfd,0xfe,0x7e,0xff,0xff,0xfe,0xfe,0x7e,0xfe,0xfe,0xfd,0xff,0xfe,0x7e +,0xfe,0xfd,0xfd,0xfd,0xff,0xff,0xfe,0xfd,0xfd,0xfe,0xff,0xff,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xfc,0xfe,0xfd,0xfd,0xfd,0xfb,0xfd,0xfd,0xfe,0xff,0xfe,0xfe,0xfe,0x7e +,0x7e,0xfe,0xfe,0xfc,0xfe,0x7e,0x7e,0x7e,0xfe,0x7e,0x7e,0x7d,0xfe,0xfe,0xff,0x7e,0x7d,0x7e,0xff,0xff,0x7e,0x7d,0x7e,0xff,0xfe,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xff +,0x7e,0x7e,0xfe,0xfd,0x7e,0x7d,0x7d,0x7d,0x7e,0x7b,0x7b,0x7a,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xff,0x7d,0x7d,0x7c,0x7e,0x7e,0x7e,0x7e,0x7c +,0x7c,0x7e,0xff,0xfe,0x7e,0x7d,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xfd,0xff,0xff,0x7e,0xfd,0xfe,0xff,0xfe,0x7e,0xfd,0xfe,0xff,0x7d,0xff,0xff,0xfd,0xfe,0x7d,0x7e +,0x7e,0xfe,0xff,0xff,0x7e,0x7e,0x7e,0xfe,0xff,0xff,0x7d,0x7e,0xff,0xff,0x7e,0x7e,0x7d,0xff,0xfe,0x7d,0x7d,0x7d,0x7e,0xfe,0xff,0x7e,0xff,0x7e,0xfe,0xfe,0xff,0xfe +,0x7e,0xff,0xff,0xff,0x7e,0x7e,0x7d,0xff,0xfe,0x7e,0x7c,0x7c,0x7d,0xfe,0xff,0xff,0x7d,0x7d,0x7e,0x7d,0x7e,0x7d,0x7e,0xfe,0xfe,0x7e,0x7d,0x7c,0x7d,0x7e,0x7e,0x7e +,0x7d,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0xff,0xfe,0xfe,0x7d,0x7c,0x7c,0x7e,0x7c,0x7b,0x7b,0x7b,0x7d,0x7e,0x7d,0x7d,0x7e,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfd,0xfe,0x7e +,0x7e,0x7e,0xfe,0x7e,0x7e,0x7e,0x7e,0xfe,0xfe,0x7e,0x7d,0x7e,0xff,0xff,0x7e,0x7e,0x7d,0x7e,0xfe,0x7e,0x7d,0x7e,0xfe,0xfd,0xfc,0xfd,0xfe,0xfd,0xfc,0xfd,0xfe,0xff +,0xfe,0xfe,0xfe,0xfe,0x7e,0x7e,0xfe,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xfe,0xff,0x7e,0xfe,0xfe,0xfe,0xff,0x7e,0x7e,0xff,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xff,0xfe,0x7e +,0xff,0x7e,0x7e,0xff,0x7e,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0x7e,0xff,0xff,0xff,0xfe,0x7e,0x7e,0x7e,0x7e,0xff +,0xff,0xff,0xff,0xff,0xfe,0xfe,0x7e,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0x7e,0xff,0xff,0xff +,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff +,0xff,0xff,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe,0x7e,0xff,0x7e,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xfe +,0x7e,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e +,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff +,0x7e,0xff,0xff,0xff,0xff,0xfe,0x7e,0xff,0x7e,0xff,0x7e,0x7e,0x7e,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0x7e,0xff,0xff,0x7e,0x7e,0xff,0xff,0xff,0xff,0xff +,0xff,0xfe,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xfe,0x7e,0xfe,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xfe,0x7e,0xff,0xfe +,0xff,0xff,0x7e,0xff,0x7e,0xff,0xff,0xff,0xfe,0xff,0x7e,0xff,0x7e,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0x7e,0xff +,0xff,0xff,0xfe,0xff,0xfe,0xfe,0xfe,0xff,0xff,0xff,0x7e,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0x7e,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff +,0x7e,0xfe,0x7e,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xfe,0xfe,0xff,0xff,0xff,0xfe,0xff +,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0x7e,0xfe,0xff,0xff,0xff,0xff,0xff,0xff +,0xff,0xfe,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7e +,0xff,0x7e,0xff,0xfe,0xff,0xff,0xff,0xfe,0xff,0x7e,0xff,0xff,0xfe,0x7e,0x7e,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0x7e,0xff,0x7e,0xff,0xff +,0xff,0x7e,0x7e,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x7e,0xfe,0xff,0xff,0xfe,0x00}; + +#endif diff --git a/USDK/component/common/media/muxer/mp4_encap.h b/USDK/component/common/media/muxer/mp4_encap.h new file mode 100644 index 0000000..6f4b788 --- /dev/null +++ b/USDK/component/common/media/muxer/mp4_encap.h @@ -0,0 +1,110 @@ +#ifndef _MP4_ENCAP_H_ +#define _MP4_ENCAP_H_ + +#include "basic_types.h" +#include "osdep_service.h" + +#define MAX_BOX_CHILD 8 +#define RBUF_SIZE 1024 + +typedef struct _mp4root{ + unsigned int video_len; + unsigned int audio_len; + unsigned int total; + unsigned int keyindex; +}MP4root,*PMP4root; + +#define STORAGE_IDLE 0 +#define STORAGE_START 1 +#define STORAGE_WRITE_ALL 2 +#define STORAGE_WRITE_VIDEO 3 +#define STORAGE_WRITE_AUDIO 4 +#define STORAGE_STOP 5 +#define STORAGE_END 6 + + +#define STORAGE_ALL 0 +#define STORAGE_VIDEO 1 +#define STORAGE_AUDIO 2 + +typedef struct _mp4_payload{ + unsigned char *addr; + unsigned int len; +}mp4_payload,pmp4_payload; + +typedef struct _mp4_write_info{ + int mp4_start_position; + int mp4_end_position; + int mp4_occupy_size; + int mp4_empty_size; + int mp4_write_start_position; + int mp4_write_end_position; + int mp4_write_occupy_size; + int mp4_write_empty_size; + int mp4_write_length; +}mp4_winfo,*pmp4_winfo; + +typedef struct _mp4_context{ + FATFS m_fs; + int drv_num; + char _drv[4]; + FIL m_file; + char filename[32]; + int Fatfs_ok; + int filecount; + int width; + int height; + int sample_rate; + int channel_count; + int frame_rate; + u32 start_time;//rtw_get_current_time() + u32 file_name_index; + u32 storage_state; + MP4root root; + MP4root root_reserve; + int period_time; + int file_total; + int sps_start; + int type; + int sps_len; + int pps_len; + int sps_pps_mark; + unsigned int *video_buffer_index; + unsigned int *video_buffer_size; + int video_size; + unsigned int *audio_buffer_index; + unsigned int *audio_buffer_size; + int audio_size; + unsigned char *moov_box; + int moov_box_size; + unsigned char *h264_buf; + int H264_LENGTH; + mp4_payload payload; + mp4_payload reserved_payload; + int reserved_start_index; + int iframe; + int reserved_type; + _sema start_fatfs_write; + int write_status; + int audio_write_status; + int video_write_status; + int buffer_write_status;//0: real write 1: virtual write + mp4_winfo winfo; + int nal_len; + int h264_extra_len; + int mp4_muxer_enable; +}mp4_context,*pmp4_context; +#define IDLE 0 +#define FATFS_WRITING 1 +#define FATFS_DONE 2 + +void mp4_handle(pmp4_context mp4_ctx,unsigned char *buf,unsigned int size,int type); +void set_mp4_audio_buffer(pmp4_context mp4_ctx,unsigned int *audio_index,unsigned int *audio_size,int size); +void set_mp4_video_buffer(pmp4_context mp4_ctx,unsigned int *video_index,unsigned int *video_size,int size); +void set_mp4_moov_buffer(pmp4_context mp4_ctx,unsigned char *moov,int size); +int mp4_set_record(pmp4_context mp4_ctx,int num); +void mp4_muxer_init(pmp4_context mp4_ctx); +void mp4_muxer_close(pmp4_context mp4_ctx); +int mp4_set_start_status(pmp4_context mp4_ctx); + +#endif \ No newline at end of file diff --git a/USDK/component/common/network/dhcp/dhcps.c b/USDK/component/common/network/dhcp/dhcps.c new file mode 100644 index 0000000..ad5be28 --- /dev/null +++ b/USDK/component/common/network/dhcp/dhcps.c @@ -0,0 +1,580 @@ + +#include "dhcp.h" +#include "dhcps.h" +#include "tcpip.h" + +//static struct dhcp_server_state dhcp_server_state_machine; +static uint8_t dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; +/* recorded the client MAC addr(default sudo mac) */ +//static uint8_t dhcps_record_first_client_mac[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; +/* recorded transaction ID (default sudo id)*/ +static uint8_t dhcp_recorded_xid[4] = {0xff, 0xff, 0xff, 0xff}; + +/* UDP Protocol Control Block(PCB) */ +static struct udp_pcb *dhcps_pcb; + +static struct ip_addr dhcps_send_broadcast_address; +static struct ip_addr dhcps_local_address; +static struct ip_addr dhcps_local_mask; +static struct ip_addr dhcps_local_gateway; +static struct ip_addr dhcps_network_id; +static struct ip_addr dhcps_subnet_broadcast; +static struct ip_addr dhcps_allocated_client_address; +uint8_t dhcps_ip4addr_pool_start, dhcps_ip4addr_pool_end; +#if 0 +static struct ip_addr dhcps_owned_first_ip; +static struct ip_addr dhcps_owned_last_ip; +static uint8_t dhcps_num_of_available_ips; +#endif +static struct dhcps_msg *dhcp_message_repository; +static int dhcp_message_total_options_lenth; + +/* allocated IP range */ +static struct table ip_table; +#define check_bit_ip_in_table(a) (ip_table.ip_range[(uint8_t)a >> 5] & (1 << ((uint8_t)a & ((1 << 5) - 1)))) +#define set_bit_ip_in_table(a) (ip_table.ip_range[(uint8_t)a >> 5] |= (1 << ((uint8_t)a & ((1 << 5) - 1)))) +static struct ip_addr client_request_ip; + +static uint8_t dhcp_client_ethernet_address[16]; +static uint8_t bound_client_ethernet_address[16]; + +static xSemaphoreHandle dhcps_ip_table_semaphore; + +static struct netif * dhcps_netif = NULL; +/** + * @brief latch the specific ip in the ip table. + * @param d the specific index + * @retval None. + */ +#if (!IS_USE_FIXED_IP) +static void mark_ip_in_table(uint8_t d) +{ + xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY); + set_bit_ip_in_table(d); + xSemaphoreGive(dhcps_ip_table_semaphore); +} + +/** + * @brief get one usable ip from the ip table of dhcp server. + * @param: None + * @retval the usable index which represent the ip4_addr(ip) of allocated ip addr. + */ +static uint8_t search_next_ip(void) +{ + uint8_t count; + xSemaphoreTake(dhcps_ip_table_semaphore, portMAX_DELAY); + for(count = dhcps_ip4addr_pool_start; count <= dhcps_ip4addr_pool_end; count++) { + if(check_bit_ip_in_table(count) == 0) { + xSemaphoreGive(dhcps_ip_table_semaphore); + return count; + } + } + xSemaphoreGive(dhcps_ip_table_semaphore); + return 0; +} +#endif + +/** + * @brief fill in the option field with message type of a dhcp message. + * @param msg_option_base_addr: the addr be filled start. + * message_type: the type code you want to fill in + * @retval the start addr of the next dhcp option. + */ +static uint8_t *add_msg_type(uint8_t *msg_option_base_addr, uint8_t message_type) +{ + uint8_t *option_start; + msg_option_base_addr[0] = DHCP_OPTION_CODE_MSG_TYPE; + msg_option_base_addr[1] = DHCP_OPTION_LENGTH_ONE; + msg_option_base_addr[2] = message_type; + option_start = msg_option_base_addr + 3; + if (DHCP_MESSAGE_TYPE_NAK == message_type) + *option_start++ = DHCP_OPTION_CODE_END; + return option_start; +} + + +static uint8_t *fill_one_option_content(uint8_t *option_base_addr, + uint8_t option_code, uint8_t option_length, void *copy_info) +{ + uint8_t *option_data_base_address; + uint8_t *next_option_start_address = NULL; + option_base_addr[0] = option_code; + option_base_addr[1] = option_length; + option_data_base_address = option_base_addr + 2; + switch (option_length) { + case DHCP_OPTION_LENGTH_FOUR: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_FOUR); + next_option_start_address = option_data_base_address + 4; + break; + case DHCP_OPTION_LENGTH_TWO: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_TWO); + next_option_start_address = option_data_base_address + 2; + break; + case DHCP_OPTION_LENGTH_ONE: + memcpy(option_data_base_address, copy_info, DHCP_OPTION_LENGTH_ONE); + next_option_start_address = option_data_base_address + 1; + break; + } + + return next_option_start_address; +} + +/** + * @brief fill in the needed content of the dhcp offer message. + * @param optptr the addr which the tail of dhcp magic field. + * @retval the addr represent to add the end of option. + */ +static void add_offer_options(uint8_t *option_start_address) +{ + uint8_t *temp_option_addr; + /* add DHCP options 1. + The subnet mask option specifies the client's subnet mask */ + temp_option_addr = fill_one_option_content(option_start_address, + DHCP_OPTION_CODE_SUBNET_MASK, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_mask); + + /* add DHCP options 3 (i.e router(gateway)). The time server option + specifies a list of RFC 868 [6] time servers available to the client. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_ROUTER, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_address); + + /* add DHCP options 6 (i.e DNS). + The option specifies a list of DNS servers available to the client. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_DNS_SERVER, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_address); + /* add DHCP options 51. + This option is used to request a lease time for the IP address. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_LEASE_TIME, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcp_option_lease_time_one_day); + /* add DHCP options 54. + The identifier is the IP address of the selected server. */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_SERVER_ID, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_local_address); + /* add DHCP options 28. + This option specifies the broadcast address in use on client's subnet.*/ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_BROADCAST_ADDRESS, DHCP_OPTION_LENGTH_FOUR, + (void *)&dhcps_subnet_broadcast); + /* add DHCP options 26. + This option specifies the Maximum transmission unit to use */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_INTERFACE_MTU, DHCP_OPTION_LENGTH_TWO, + (void *) &dhcp_option_interface_mtu); + /* add DHCP options 31. + This option specifies whether or not the client should solicit routers */ + temp_option_addr = fill_one_option_content(temp_option_addr, + DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY, DHCP_OPTION_LENGTH_ONE, + NULL); +#if LWIP_NETIF_HOSTNAME + /* add DHCP options 12 HostName */ + const char *p = dhcps_netif->hostname; + uint8_t len; + if(p && (len = strlen(p)) != 0) { + *temp_option_addr++ = DHCP_OPTION_HOSTNAME; + *temp_option_addr++ = len; + while(len--) { + *temp_option_addr++ = *p++; + } + } +#endif + *temp_option_addr = DHCP_OPTION_CODE_END; + +} + + +/** + * @brief fill in common content of a dhcp message. + * @param m the pointer which point to the dhcp message store in. + * @retval None. + */ +static void dhcps_initialize_message(struct dhcps_msg *dhcp_message_repository, struct ip_addr yiaddr) +{ + + dhcp_message_repository->op = DHCP_MESSAGE_OP_REPLY; + dhcp_message_repository->htype = DHCP_MESSAGE_HTYPE; + dhcp_message_repository->hlen = DHCP_MESSAGE_HLEN; + dhcp_message_repository->hops = 0; + memcpy((char *)dhcp_recorded_xid, (char *) dhcp_message_repository->xid, + sizeof(dhcp_message_repository->xid)); + dhcp_message_repository->secs = 0; + dhcp_message_repository->flags = htons(BOOTP_BROADCAST); + + memcpy((char *)dhcp_message_repository->yiaddr, + (char *)&yiaddr, + sizeof(dhcp_message_repository->yiaddr)); + + memset((char *)dhcp_message_repository->ciaddr, 0, + sizeof(dhcp_message_repository->ciaddr)); + memset((char *)dhcp_message_repository->siaddr, 0, + sizeof(dhcp_message_repository->siaddr)); + memset((char *)dhcp_message_repository->giaddr, 0, + sizeof(dhcp_message_repository->giaddr)); + memcpy((char *)dhcp_message_repository->chaddr, &dhcp_client_ethernet_address, + sizeof(dhcp_message_repository->chaddr)); + memset((char *)dhcp_message_repository->sname, 0, + sizeof(dhcp_message_repository->sname)); + memset((char *)dhcp_message_repository->file, 0, + sizeof(dhcp_message_repository->file)); + memset((char *)dhcp_message_repository->options, 0, + dhcp_message_total_options_lenth); + memcpy((char *)dhcp_message_repository->options, (char *)dhcp_magic_cookie, + sizeof(dhcp_magic_cookie)); +} + +/** + * @brief init and fill in the needed content of dhcp offer message. + * @param packet_buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_offer(struct pbuf *packet_buffer) +{ + uint8_t temp_ip = 0; + dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload; +#if (!IS_USE_FIXED_IP) + if ((ip4_addr4(&dhcps_allocated_client_address) != 0) && + (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) && + (memcmp((void *)&bound_client_ethernet_address, (void *)&dhcp_client_ethernet_address, 16) == 0)) { + temp_ip = (uint8_t) ip4_addr4(&client_request_ip); + } else if ((ip4_addr1(&client_request_ip) == ip4_addr1(&dhcps_network_id)) && + (ip4_addr2(&client_request_ip) == ip4_addr2(&dhcps_network_id)) && + (ip4_addr3(&client_request_ip) == ip4_addr3(&dhcps_network_id))) { + uint8_t request_ip4 = (uint8_t) ip4_addr4(&client_request_ip); + if ((request_ip4 != 0) + && check_bit_ip_in_table(request_ip4) == 0) { + temp_ip = request_ip4; + } + } + + /* create new client ip */ + if(temp_ip == 0) temp_ip = search_next_ip(); +#if (debug_dhcps) + printf(" temp_ip = %d\n",temp_ip); +#endif + if (temp_ip == 0) { +#if 0 + memset(&ip_table, 0, sizeof(struct table)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address)); + printf("reset ip table!"); +#endif + printf("No useable ip!"); + } + + IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)), + ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), temp_ip); + memcpy(bound_client_ethernet_address, dhcp_client_ethernet_address, sizeof(bound_client_ethernet_address)); +#endif + dhcps_initialize_message(dhcp_message_repository, dhcps_allocated_client_address); + add_offer_options(add_msg_type(&dhcp_message_repository->options[4], + DHCP_MESSAGE_TYPE_OFFER)); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief init and fill in the needed content of dhcp nak message. + * @param packet buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_nak(struct pbuf *packet_buffer) +{ + struct ip_addr zero_address; + IP4_ADDR(&zero_address, 0, 0, 0, 0); + + dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload; + dhcps_initialize_message(dhcp_message_repository, zero_address); + add_msg_type(&dhcp_message_repository->options[4], DHCP_MESSAGE_TYPE_NAK); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief init and fill in the needed content of dhcp ack message. + * @param packet buffer packet buffer for UDP. + * @retval None. + */ +static void dhcps_send_ack(struct pbuf *packet_buffer) +{ + dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload; + dhcps_initialize_message(dhcp_message_repository, dhcps_allocated_client_address); + add_offer_options(add_msg_type(&dhcp_message_repository->options[4], + DHCP_MESSAGE_TYPE_ACK)); + udp_sendto_if(dhcps_pcb, packet_buffer, + &dhcps_send_broadcast_address, DHCP_CLIENT_PORT, dhcps_netif); +} + +/** + * @brief according by the input message type to reflect the correspond state. + * @param option_message_type the input server state + * @retval the server state which already transfer to. + */ +uint8_t dhcps_handle_state_machine_change(uint8_t option_message_type) +{ + switch (option_message_type) { + case DHCP_MESSAGE_TYPE_DECLINE: + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_MESSAGE_TYPE_DISCOVER: + if (dhcp_server_state_machine == DHCP_SERVER_STATE_IDLE) { + dhcp_server_state_machine = DHCP_SERVER_STATE_OFFER; + } + break; + case DHCP_MESSAGE_TYPE_REQUEST: + +#if (!IS_USE_FIXED_IP) + if (dhcp_server_state_machine == DHCP_SERVER_STATE_OFFER) { + if (ip4_addr4(&dhcps_allocated_client_address) != 0) { + if (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) { + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else if (dhcp_server_state_machine == DHCP_SERVER_STATE_IDLE) { + if ((ip4_addr4(&dhcps_allocated_client_address) != 0) && + (memcmp((void *)&dhcps_allocated_client_address, (void *)&client_request_ip, 4) == 0) && + (memcmp((void *)&bound_client_ethernet_address, (void *)&dhcp_client_ethernet_address, 16) == 0)) { + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + } else if ((ip4_addr1(&client_request_ip) == ip4_addr1(&dhcps_network_id)) && + (ip4_addr2(&client_request_ip) == ip4_addr2(&dhcps_network_id)) && + (ip4_addr3(&client_request_ip) == ip4_addr3(&dhcps_network_id))) { + uint8_t request_ip4 = (uint8_t) ip4_addr4(&client_request_ip); + if ((request_ip4 != 0) + && check_bit_ip_in_table(request_ip4) == 0) { + IP4_ADDR(&dhcps_allocated_client_address, (ip4_addr1(&dhcps_network_id)), + ip4_addr2(&dhcps_network_id), ip4_addr3(&dhcps_network_id), request_ip4); + memcpy(bound_client_ethernet_address, dhcp_client_ethernet_address, sizeof(bound_client_ethernet_address)); + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } + } else { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } +#else + if (!(dhcp_server_state_machine == DHCP_SERVER_STATE_ACK || + dhcp_server_state_machine == DHCP_SERVER_STATE_NAK)) { + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; + } +#endif + break; + case DHCP_MESSAGE_TYPE_RELEASE: + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + } + + return dhcp_server_state_machine; +} +/** + * @brief parse the dhcp message option part. + * @param optptr: the addr of the first option field. + * len: the total length of all option fields. + * @retval dhcp server state. + */ +static uint8_t dhcps_handle_msg_options(uint8_t *option_start, int16_t total_option_length) +{ + + int16_t option_message_type = 0; + uint8_t *option_end = option_start + total_option_length; + //dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + + /* begin process the dhcp option info */ + while (option_start < option_end) { + switch ((uint8_t)*option_start) { + case DHCP_OPTION_CODE_MSG_TYPE: + option_message_type = *(option_start + 2); // 2 => code(1)+lenth(1) + break; + case DHCP_OPTION_CODE_REQUEST_IP_ADDRESS : +#if IS_USE_FIXED_IP + if (memcmp((char *)&dhcps_allocated_client_address, + (char *)option_start + 2, 4) == 0) + dhcp_server_state_machine = DHCP_SERVER_STATE_ACK; + else + dhcp_server_state_machine = DHCP_SERVER_STATE_NAK; +#else + memcpy((char *)&client_request_ip, (char *)option_start + 2, 4); +#endif + break; + } + // calculate the options offset to get next option's base addr + option_start += option_start[1] + 2; // optptr[1]: length value + (code(1)+ Len(1)) + } + return dhcps_handle_state_machine_change(option_message_type); +} + +/** + * @brief get message from buffer then check whether it is dhcp related or not. + * if yes , parse it more to undersatnd the client's request. + * @param same as recv callback function definition + * @retval if message is dhcp related then return dhcp server state, + * otherwise return 0 + */ +static uint8_t dhcps_check_msg_and_handle_options(struct pbuf *packet_buffer) +{ + int dhcp_message_option_offset; + dhcp_message_repository = (struct dhcps_msg *)packet_buffer->payload; + memcpy(dhcp_client_ethernet_address, dhcp_message_repository->chaddr, sizeof(dhcp_client_ethernet_address)); + dhcp_message_option_offset = ((int)dhcp_message_repository->options + - (int)packet_buffer->payload); + dhcp_message_total_options_lenth = (packet_buffer->len + - dhcp_message_option_offset); + /* check the magic number,if correct parse the content of options */ + if (memcmp((char *)dhcp_message_repository->options, + (char *)dhcp_magic_cookie, sizeof(dhcp_magic_cookie)) == 0) { + return dhcps_handle_msg_options(&dhcp_message_repository->options[4], + (dhcp_message_total_options_lenth - 4)); + } + + return 0; +} + + +/** + * @brief handle imcoming dhcp message and response message to client + * @param same as recv callback function definition + * @retval None + */ +static void dhcps_receive_udp_packet_handler(void *arg, struct udp_pcb *udp_pcb, +struct pbuf *udp_packet_buffer, struct ip_addr *sender_addr, uint16_t sender_port) +{ + int16_t total_length_of_packet_buffer; + struct pbuf *merged_packet_buffer = NULL; + + dhcp_message_repository = (struct dhcps_msg *)udp_packet_buffer->payload; + if (udp_packet_buffer == NULL) { + printf("Error! System doesn't allocate any buffer\n"); + return; + } + if (sender_port == DHCP_CLIENT_PORT) { + total_length_of_packet_buffer = udp_packet_buffer->tot_len; + if (udp_packet_buffer->next != NULL) { + merged_packet_buffer = pbuf_coalesce(udp_packet_buffer, + PBUF_TRANSPORT); + if (merged_packet_buffer->tot_len != + total_length_of_packet_buffer) { + pbuf_free(udp_packet_buffer); + return; + } + } + switch (dhcps_check_msg_and_handle_options(udp_packet_buffer)) { + case DHCP_SERVER_STATE_OFFER: + dhcps_send_offer(udp_packet_buffer); + break; + case DHCP_SERVER_STATE_ACK: + dhcps_send_ack(udp_packet_buffer); +#if (!IS_USE_FIXED_IP) + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_allocated_client_address)); +#endif + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_SERVER_STATE_NAK: + dhcps_send_nak(udp_packet_buffer); + dhcp_server_state_machine = DHCP_SERVER_STATE_IDLE; + break; + case DHCP_OPTION_CODE_END: + break; + } + } + + /* free the UDP connection, so we can accept new clients */ + udp_disconnect(udp_pcb); + + /* Free the packet buffer */ + if (merged_packet_buffer != NULL) + pbuf_free(merged_packet_buffer); + else + pbuf_free(udp_packet_buffer); +} + +void dhcps_set_addr_pool(int addr_pool_set, struct ip_addr * addr_pool_start, struct ip_addr *addr_pool_end) +{ + dhcps_ip4addr_pool_start = ip4_addr4(addr_pool_start); + dhcps_ip4addr_pool_end = ip4_addr4(addr_pool_end); +} + +/** + * @brief Initialize dhcp server. + * @param None. + * @retval None. + * Note, for now,we assume the server latch ip 192.168.1.1 and support dynamic + * or fixed IP allocation. + */ +void dhcps_init(struct netif * pnetif) +{ +// printf("dhcps_init,wlan:%c\n\r",pnetif->name[1]); + dhcps_netif = pnetif; + dhcps_deinit(); + dhcps_pcb = udp_new(); + if (dhcps_pcb == NULL) { + printf("Error! upd_new error\n"); + return; + } + IP4_ADDR(&dhcps_send_broadcast_address, 255, 255, 255, 255); + + memset(&ip_table, 0, sizeof(struct table)); + if((dhcps_ip4addr_pool_end | dhcps_ip4addr_pool_start) == 0) { + dhcps_ip4addr_pool_start = 2; + dhcps_ip4addr_pool_end = 255; + } + + /* get net info from net interface */ + + memcpy(&dhcps_local_address, &pnetif->ip_addr, + sizeof(struct ip_addr)); + memcpy(&dhcps_local_mask, &pnetif->netmask, + sizeof(struct ip_addr)); + memcpy(&dhcps_local_gateway, &pnetif->gw, + sizeof(struct ip_addr)); + /* calculate the usable network ip range */ + dhcps_network_id.addr = ((pnetif->ip_addr.addr) & + (pnetif->netmask.addr)); + + dhcps_subnet_broadcast.addr = ((dhcps_network_id.addr | + ~(pnetif->netmask.addr))); +#if 0 + dhcps_owned_first_ip.addr = htonl((ntohl(dhcps_network_id.addr) + 1)); + dhcps_owned_last_ip.addr = htonl(ntohl(dhcps_subnet_broadcast.addr) - 1); + dhcps_num_of_available_ips = ((ntohl(dhcps_owned_last_ip.addr) + - ntohl(dhcps_owned_first_ip.addr)) + 1); +#endif + +#if IS_USE_FIXED_IP + IP4_ADDR(&dhcps_allocated_client_address, ip4_addr1(&dhcps_local_address) + , ip4_addr2(&dhcps_local_address), ip4_addr3(&dhcps_local_address), + (ip4_addr4(&dhcps_local_address)) + 1 ); +#else + dhcps_ip_table_semaphore = xSemaphoreCreateMutex(); + + memset(&dhcps_allocated_client_address, 0, sizeof(struct ip_addr)); + memset(bound_client_ethernet_address, 0, sizeof(bound_client_ethernet_address)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_address)); + mark_ip_in_table((uint8_t)ip4_addr4(&dhcps_local_gateway)); +#if 0 + for (i = 1; i < ip4_addr4(&dhcps_local_address); i++) { + mark_ip_in_table(i); + } +#endif +#endif + udp_bind(dhcps_pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + udp_recv(dhcps_pcb, dhcps_receive_udp_packet_handler, NULL); +} + +void dhcps_deinit(void) +{ + if (dhcps_pcb != NULL) { + udp_remove(dhcps_pcb); + dhcps_pcb = NULL; + } + if (dhcps_ip_table_semaphore != NULL) { + vSemaphoreDelete(dhcps_ip_table_semaphore); + dhcps_ip_table_semaphore = NULL; + } +} diff --git a/USDK/component/common/network/dhcp/dhcps.h b/USDK/component/common/network/dhcp/dhcps.h new file mode 100644 index 0000000..a1c7d60 --- /dev/null +++ b/USDK/component/common/network/dhcp/dhcps.h @@ -0,0 +1,120 @@ + +#ifndef __DHCPS_H__ +#define __DHCPS_H__ + +#include "lwip/arch.h" +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "lwip/stats.h" +#include "lwip/sys.h" + +#include + + +#define IS_USE_FIXED_IP 0 +#define debug_dhcps 0 + +/* dhcp server states */ +#define DHCP_SERVER_STATE_OFFER (1) +#define DHCP_SERVER_STATE_DECLINE (2) +#define DHCP_SERVER_STATE_ACK (3) +#define DHCP_SERVER_STATE_NAK (4) +#define DHCP_SERVER_STATE_IDLE (5) + + +#define BOOTP_BROADCAST (0x8000) + +#define DHCP_MESSAGE_OP_REQUEST (1) +#define DHCP_MESSAGE_OP_REPLY (2) + +#define DHCP_MESSAGE_HTYPE (1) +#define DHCP_MESSAGE_HLEN (6) + +#define DHCP_SERVER_PORT (67) +#define DHCP_CLIENT_PORT (68) + +#define DHCP_MESSAGE_TYPE_DISCOVER (1) +#define DHCP_MESSAGE_TYPE_OFFER (2) +#define DHCP_MESSAGE_TYPE_REQUEST (3) +#define DHCP_MESSAGE_TYPE_DECLINE (4) +#define DHCP_MESSAGE_TYPE_ACK (5) +#define DHCP_MESSAGE_TYPE_NAK (6) +#define DHCP_MESSAGE_TYPE_RELEASE (7) + +#define DHCP_OPTION_LENGTH_ONE (1) +#define DHCP_OPTION_LENGTH_TWO (2) +#define DHCP_OPTION_LENGTH_THREE (3) +#define DHCP_OPTION_LENGTH_FOUR (4) + +#define DHCP_OPTION_CODE_SUBNET_MASK (1) +#define DHCP_OPTION_CODE_ROUTER (3) +#define DHCP_OPTION_CODE_DNS_SERVER (6) +#define DHCP_OPTION_CODE_INTERFACE_MTU (26) +#define DHCP_OPTION_CODE_BROADCAST_ADDRESS (28) +#define DHCP_OPTION_CODE_PERFORM_ROUTER_DISCOVERY (31) +#define DHCP_OPTION_CODE_REQUEST_IP_ADDRESS (50) +#define DHCP_OPTION_CODE_LEASE_TIME (51) +#define DHCP_OPTION_CODE_MSG_TYPE (53) +#define DHCP_OPTION_CODE_SERVER_ID (54) +#define DHCP_OPTION_CODE_REQ_LIST (55) +#define DHCP_OPTION_CODE_END (255) + +#define IP_FREE_TO_USE (1) +#define IP_ALREADY_IN_USE (0) + +#define HW_ADDRESS_LENGTH (6) + +/* Reference by RFC 2131 */ +struct dhcps_msg { + uint8_t op; /* Message op code/message type. 1 = BOOTREQUEST, 2 = BOOTREPLY */ + uint8_t htype; /* Hardware address type */ + uint8_t hlen; /* Hardware address length */ + uint8_t hops; /* Client sets to zero, optionally used by relay agents + when booting via a relay agent */ + uint8_t xid[4]; /* Transaction ID, a random number chosen by the client, + used by the client and server to associate messages and + responses between a client and a server */ + uint16_t secs; /* Filled in by client, seconds elapsed since client began address + acquisition or renewal process.*/ + uint16_t flags; /* bit 0: Broadcast flag, bit 1~15:MBZ must 0*/ + uint8_t ciaddr[4]; /* Client IP address; only filled in if client is in BOUND, + RENEW or REBINDING state and can respond to ARP requests. */ + uint8_t yiaddr[4]; /* 'your' (client) IP address */ + uint8_t siaddr[4]; /* IP address of next server to use in bootstrap; + returned in DHCPOFFER, DHCPACK by server. */ + uint8_t giaddr[4]; /* Relay agent IP address, used in booting via a relay agent.*/ + uint8_t chaddr[16]; /* Client hardware address */ + uint8_t sname[64]; /* Optional server host name, null terminated string.*/ + uint8_t file[128]; /* Boot file name, null terminated string; "generic" name or + null in DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER.*/ + uint8_t options[312]; /* Optional parameters field. reference the RFC 2132 */ +}; + +/* use this to check whether the message is dhcp related or not */ +static const uint8_t dhcp_magic_cookie[4] = {99, 130, 83, 99}; +static const uint8_t dhcp_option_lease_time_one_day[] = {0x00, 0x01, 0x51, 0x80}; + +#ifdef CLASS_B_NET +static const uint8_t dhcp_option_interface_mtu[] = {0x05, 0xDC}; // 1500 +#else +static const uint8_t dhcp_option_interface_mtu[] = {0x02, 0x40}; // 576 +#endif + +struct table { + uint32_t ip_range[8]; +}; + +struct address_pool{ + uint32_t start; + uint32_t end; +}; + +/* expose API */ + +extern uint8_t dhcps_ip4addr_pool_start, dhcps_ip4addr_pool_end; +void dhcps_init(struct netif * pnetif); +void dhcps_deinit(void); + +extern struct netif *netif_default; + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/CHANGELOG b/USDK/component/common/network/lwip/lwip_v1.3.2/CHANGELOG new file mode 100644 index 0000000..860d1c4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/CHANGELOG @@ -0,0 +1,2419 @@ +FUTURE + + * TODO: The lwIP source code makes some invalid assumptions on processor + word-length, storage sizes and alignment. See the mailing lists for + problems with exoteric (/DSP) architectures showing these problems. + We still have to fix some of these issues neatly. + + * TODO: the PPP code is broken in a few ways. There are namespace + collisions on BSD systems and many assumptions on word-length + (sizeof(int)). In ppp.c an assumption is made on the availability of + a thread subsystem. Either PPP needs to be moved to contrib/ports/??? + or rearranged to be more generic. + +HISTORY + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ New features: + + + ++ Bugfixes: + + +(STABLE-1.3.2) + + ++ New features: + + 2009-10-27 Simon Goldschmidt/Stephan Lesage + * netifapi.c/.h: Added netifapi_netif_set_addr() + + 2009-10-07 Simon Goldschmidt/Fabian Koch + * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to + support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) + + 2009-08-26 Simon Goldschmidt/Simon Kallweit + * slipif.c/.h: bug #26397: SLIP polling support + + 2009-08-25 Simon Goldschmidt + * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), + New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. + + 2009-08-25 Simon Goldschmidt + * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) + + 2009-08-24 Jakob Stoklund Olesen + * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond + to netif_set_link_up(). + + 2009-08-23 Simon Goldschmidt + * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state + to a human-readable string. + + ++ Bugfixes: + + 2009-12-24: Kieran Mansley + * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing + (BUG#28241) + + 2009-12-06: Simon Goldschmidt + * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can + be statically allocated (like in ucip) + + 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) + * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT + + 2009-12-03: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit + could have non-zero length + + 2009-12-02: Simon Goldschmidt + * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting + tcp_input_pcb until after calling the pcb's callbacks + + 2009-11-29: Simon Goldschmidt + * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- + sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code + + 2009-11-29: Simon Goldschmidt + * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by + queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty + + 2009-11-26: Simon Goldschmidt + * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending + segment + + 2009-11-26: Simon Goldschmidt + * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle + algorithm at PCB level + + 2009-11-22: Simon Goldschmidt + * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent + + 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) + * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when + reusing time-wait pcb + + 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) + * sockets.c: Fixed bug #28062: Data received directly after accepting + does not wake up select + + 2009-11-11: Simon Goldschmidt + * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) + + 2009-10-30: Simon Goldschmidt + * opt.h: Increased default value for TCP_MSS to 536, updated default + value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. + + 2009-10-28: Kieran Mansley + * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code + to follow algorithm from TCP/IP Illustrated + + 2009-10-27: Kieran Mansley + * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK + + 2009-10-25: Simon Goldschmidt + * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if + pcb->recv is NULL to keep rcv_wnd correct) + + 2009-10-25: Simon Goldschmidt + * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state + + 2009-10-23: Simon Goldschmidt (David Empson) + * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes + + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + + 2009-10-19: Simon Goldschmidt + * dhcp.c/.h: Minor code simplification (don't store received pbuf, change + conditional code to assert where applicable), check pbuf length before + testing for valid reply + + 2009-10-19: Simon Goldschmidt + * dhcp.c: Removed most calls to udp_connect since they aren't necessary + when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. + + 2009-10-16: Simon Goldschmidt + * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop + valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is + enabled + + 2009-10-15: Simon Goldschmidt (Oleg Tyshev) + * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit + + 2009-10-15: Simon Goldschmidt + * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() + timeout + + 2009-10-15: Simon Goldschmidt + * autoip.c: Fixed bug #27704: autoip starts with wrong address + LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead + of network byte order + + 2009-10-11 Simon Goldschmidt (Jrg Kesten) + * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments + which are not consecutive when retransmitting unacked segments + + 2009-10-09 Simon Goldschmidt + * opt.h: Fixed default values of some stats to only be enabled if used + Fixes bug #27338: sys_stats is defined when NO_SYS = 1 + + 2009-08-30 Simon Goldschmidt + * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK + function" by checking for loopback before calling ip_frag + + 2009-08-25 Simon Goldschmidt + * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27078: Possible memory leak in pppInit() + + 2009-08-23 Simon Goldschmidt + * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result + is error. + + 2009-08-23 Simon Goldschmidt + * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF + Fixed wrong parenthesis, added check in init.c + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms + + 2009-08-23 Simon Goldschmidt + * many ppp files: bug #27267: Added include to string.h where needed + + 2009-08-23 Simon Goldschmidt + * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) + + +(STABLE-1.3.1) + + ++ New features: + + 2009-05-10 Simon Goldschmidt + * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option + LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only + one pbuf to help MACs that don't support scatter-gather DMA. + + 2009-05-09 Simon Goldschmidt + * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming + ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + + 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen + * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive + extended info about the currently received packet. + + 2009-04-27 Simon Goldschmidt + * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 + + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined + as an external function for lookup. + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for + TCP timestamp options, off by default. Rework tcp_enqueue() to + take option flags rather than specified option data + + 2009-02-18 Simon Goldschmidt + * cc.h: Added printf formatter for size_t: SZT_F + + 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) + * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast + pings + + 2009-02-12 Simon Goldschmidt + * init.h: Added LWIP_VERSION to get the current version of the stack + + 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) + * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead + of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc + is otherwise used) + + 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) + * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() + is only used by UDPLITE at present, so conditionalise it. + + 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) + * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP + "seed" address. This should reduce AUTOIP conflicts if + LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. + + 2008-10-02 Jonathan Larmour and Rishi Khan + * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking + socket. + + 2008-06-30 Simon Goldschmidt + * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from + interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows + mem_free to run between mem_malloc iterations. Added illegal counter for + mem stats. + + 2008-06-27 Simon Goldschmidt + * stats.h/.c, some other files: patch #6483: stats module improvement: + Added defines to display each module's statistic individually, added stats + defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. + + 2008-06-17 Simon Goldschmidt + * err.h: patch #6459: Made err_t overridable to use a more efficient type + (define LWIP_ERR_T in cc.h) + + 2008-06-17 Simon Goldschmidt + * slipif.c: patch #6480: Added a configuration option for slipif for symmetry + to loopif + + 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) + * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly + modified version of patch # 6370: Moved loopif code to netif.c so that + loopback traffic is supported on all netifs (all local IPs). + Added option to limit loopback packets for each netifs. + + + ++ Bugfixes: + 2009-08-12 Kieran Mansley + * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when + out of window or out of order properly + + 2009-08-12 Kieran Mansley + * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 + + 2009-07-28 Simon Goldschmidt + * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s + + 2009-07-27 Kieran Mansley + * api.h api_msg.h netdb.h sockets.h: add missing #include directives + + 2009-07-09 Kieran Mansley + * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for + recv_avail and don't increment counters until message successfully + sent to mbox + + 2009-06-25 Kieran Mansley + * api_msg.c api.h: BUG26722: initialise netconn write variables + in netconn_alloc + + 2009-06-25 Kieran Mansley + * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set + + 2009-06-25 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct + simultaneous close behaviour, and make snd_nxt have the same meaning + as in the RFCs. + + 2009-05-12 Simon Goldschmidt + * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on + arp_table / uses etharp_query" by adding etharp_gratuitous() + + 2009-05-12 Simon Goldschmidt + * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options + to the IP header (used by igmp_ip_output_if) + + 2009-05-06 Simon Goldschmidt + * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if + defined) for SWAP_BYTES_IN_WORD to speed up checksumming. + + 2009-05-05 Simon Goldschmidt + * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() + to crash + + 2009-05-04 Simon Goldschmidt + * init.c: snmp was not initialized in lwip_init() + + 2009-05-04 Frdric Bernon + * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. + + 2009-05-03 Simon Goldschmidt + * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full + (and unsent->next == NULL) + + 2009-05-02 Simon Goldschmidt + * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after + 1.3.0 in CVS only) - fixes compilation of ppp_oe.c + + 2009-05-02 Simon Goldschmidt + * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields + + 2009-05-01 Simon Goldschmidt + * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets + + 2009-05-01 Simon Goldschmidt + * ppp.c: bug #24228: Memory corruption with PPP and DHCP + + 2009-04-29 Frdric Bernon + * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the + SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception + of broadcast packets even when this option wasn't set. Port maintainers + which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. + If you want this option also filter broadcast on recv operations, you also + have to set IP_SOF_BROADCAST_RECV=1 in opt.h. + + 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen + * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and + DHCP/AUTOIP cooperation + + 2009-04-25 Simon Goldschmidt, Oleg Tyshev + * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd + Fixed by sorting the unsent and unacked queues (segments are inserted at the + right place in tcp_output and tcp_rexmit). + + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + + 2009-04-24 Simon Goldschmidt, Frdric Bernon + * inet.c: patch #6765: Fix a small problem with the last changes (incorrect + behavior, with with ip address string not ended by a '\0', a space or a + end of line) + + 2009-04-19 Simon Goldschmidt + * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, + pcb->err is called, not pcb->connected (with an error code). + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with + no-copy-tcpwrite": deallocate option data, only concat segments with same flags + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated + in the header pbuf, not the data pbuf) + + 2009-04-18 Simon Goldschmidt + * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() + + 2009-04-15 Simon Goldschmidt + * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp + + 2009-04-15 Simon Goldschmidt + * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in + + 2009-04-15 Simon Goldschmidt + * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function + ip_hinted_output() (for smaller code mainly) + + 2009-04-15 Simon Goldschmidt + * inet.c: patch #6765: Supporting new line characters in inet_aton() + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; + Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu + is big enough in dhcp_start + + 2009-04-15 Simon Goldschmidt + * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak + + 2009-04-15 Simon Goldschmidt + * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY + + 2009-04-15 Simon Goldschmidt + * sockets.c: bug #26121: set_errno can be overridden + + 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) + * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when + LWIP_TCP==0 + + 2009-04-09 Kieran Mansley (patch from Roy Lee ) + * tcp.h: Patch#6802 Add do-while-clauses to those function like + macros in tcp.h + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window + updates are calculated and sent (BUG20515) + + * tcp_in.c: cope with SYN packets received during established states, + and retransmission of initial SYN. + + * tcp_out.c: set push bit correctly when tcp segments are merged + + 2009-03-27 Kieran Mansley + * tcp_out.c set window correctly on probes (correcting change made + yesterday) + + 2009-03-26 Kieran Mansley + * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping + connections where no reset required (bug #25622) + + * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes + (bug #20779) + + 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) + * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be + too small depending on MEM_ALIGNMENT + + 2009-02-16 Simon Goldschmidt + * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; + converted size argument of netconn_write to 'size_t' + + 2009-02-16 Simon Goldschmidt + * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host + by moving accept callback function pointer to TCP_PCB_COMMON + + 2009-02-12 Simon Goldschmidt + * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" + option) + + 2009-02-11 Simon Goldschmidt + * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) + + 2009-02-11 Simon Goldschmidt + * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: + RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) + + 2009-02-10 Simon Goldschmidt + * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: + Accepts_pending is decrease on a corresponding listen pcb when a connection + in state SYN_RCVD is close. + + 2009-01-28 Jonathan Larmour + * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run + out of pool pbufs. + + 2008-12-19 Simon Goldschmidt + * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 + + 2008-12-10 Tamas Somogyi, Frdric Bernon + * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and + port uses deleted netbuf. + + 2008-10-18 Simon Goldschmidt + * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length + in tcp_parseopt + + 2008-10-15 Simon Goldschmidt + * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers + by packing the struct ip_reass_helper. + + 2008-10-03 David Woodhouse, Jonathan Larmour + * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. + + 2008-10-02 Jonathan Larmour + * dns.c: Hard-code structure sizes, to avoid issues on some compilers where + padding is included. + + 2008-09-30 Jonathan Larmour + * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an + assertion check that addrlen isn't NULL. + + 2008-09-30 Jonathan Larmour + * tcp.c: Fix bug #24227, wrong error message in tcp_bind. + + 2008-08-26 Simon Goldschmidt + * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and + inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h + + 2008-08-14 Simon Goldschmidt + * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when + tcp_close returns != ERR_OK) + + 2008-07-08 Frdric Bernon + * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters + in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). + + 2008-06-24 Jonathan Larmour + * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused + if tcp_seg_copy fails. + + 2008-06-17 Simon Goldschmidt + * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) + and created defines for swapping bytes and folding u32 to u16. + + 2008-05-30 Kieran Mansley + * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd + rather than rcv_ann_wnd when deciding if packets are in-window. + Contributed by + + 2008-05-30 Kieran Mansley + * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow + passing as function pointers when MEM_LIBC_MALLOC is defined. + + 2008-05-09 Jonathan Larmour + * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to + stop it being treated as a fatal error. + + 2008-04-15 Simon Goldschmidt + * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP + (flag now cleared) + + 2008-03-27 Simon Goldschmidt + * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free + from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 + in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs + or heap memory from interrupt context + + 2008-03-26 Simon Goldschmidt + * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote + host sent a zero mss as TCP option. + + +(STABLE-1.3.0) + + ++ New features: + + 2008-03-10 Jonathan Larmour + * inet_chksum.c: Allow choice of one of the sample algorithms to be + made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. + + 2008-01-22 Frdric Bernon + * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in + TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. + + 2008-01-14 Frdric Bernon + * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable + to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the + tcp_recv callback (see rawapi.txt). + + 2008-01-14 Frdric Bernon, Marc Chaland + * ip.c: Integrate patch #6369" ip_input : checking before realloc". + + 2008-01-12 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::sem per netconn::op_completed like suggested for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-12 Frdric Bernon + * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, + DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues + sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 + "Add return value to sys_mbox_post". tcpip_callback is always defined as + "blocking" ("block" parameter = 1). + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-05 Frdric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + + 2008-01-04 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, + tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the + "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add + documentation in the rawapi.txt file. + + 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer + + 2007-12-31 Frdric Bernon, Luca Ceresoli + * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets + in autoip". The change in etharp_raw could be removed, since all calls to + etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be + wrong in the future. + + 2007-12-30 Frdric Bernon, Tom Evans + * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address + Filtering" reported by Tom Evans. + + 2007-12-21 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, + sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API + applications have to call 'tcp_accepted(pcb)' in their accept callback to + keep accepting new connections. + + 2007-12-13 Frdric Bernon + * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" + by err_t type. Add a new err_t code "ERR_INPROGRESS". + + 2007-12-12 Frdric Bernon + * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles + are the one which have ram usage. + + 2007-12-05 Frdric Bernon + * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static + set of variables (=0) or a local one (=1). In this last case, your port should + provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" + which have to do a copy of "h" and return a pointer ont the "per-thread" copy. + + 2007-12-03 Simon Goldschmidt + * ip.c: ip_input: check if a packet is for inp first before checking all other + netifs on netif_list (speeds up packet receiving in most cases) + + 2007-11-30 Simon Goldschmidt + * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access + UDP: move a (connected) pcb selected for input to the front of the list of + pcbs so that it is found faster next time. Same for RAW pcbs that have eaten + a packet. + + 2007-11-28 Simon Goldschmidt + * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS + + 2007-11-25 Simon Goldschmidt + * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy + algorithm. + + 2007-11-24 Simon Goldschmidt + * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c + to the new file netdb.c; included lwip_getaddrinfo. + + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. + + 2007-11-19 Frdric Bernon + * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name + received match the name query), implement DNS_USES_STATIC_BUF (the place where + copy dns payload to parse the response), return an error if there is no place + for a new query, and fix some minor problems. + + 2007-11-16 Simon Goldschmidt + * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c + removed files: core/inet.c, core/inet6.c + Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into + inet and chksum part; changed includes in all lwIP files as appropriate + + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential + dns resolver function for netconn api (netconn_gethostbyname) and socket api + (gethostbyname/gethostbyname_r). + + 2007-11-15 Jim Pettinato, Frdric Bernon + * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name + requests with RAW api interface. Initialization is done in lwip_init() with + build time options. DNS timer is added in tcpip_thread context. DHCP can set + DNS server ip addresses when options are received. You need to set LWIP_DNS=1 + in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get + some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" + list with points to improve. + + 2007-11-06 Simon Goldschmidt + * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly + enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status + for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. + + 2007-11-06 Simon Goldschmidt + * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include + core header files in api.h (ip/tcp/udp/raw.h) to hide the internal + implementation from netconn api applications. + + 2007-11-03 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + + 2007-11-01 Frdric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + + 2007-10-24 Frdric Bernon + * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than + TCP_EVENT_xxx macros to get a code more readable. It could also help to remove + some code (like we have talk in "patch #5919 : Create compile switch to remove + select code"), but it could be done later. + + 2007-10-08 Simon Goldschmidt + * many files: Changed initialization: many init functions are not needed any + more since we now rely on the compiler initializing global and static + variables to zero! + + 2007-10-06 Simon Goldschmidt + * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY + to enqueue the received pbufs so that multiple packets can be reassembled + simultaneously and no static reassembly buffer is needed. + + 2007-10-05 Simon Goldschmidt + * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so + all netifs (or ports) can use it. + + 2007-10-05 Frdric Bernon + * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the + common function to reduce a little bit the footprint (for all functions using + only the "netif" parameter). + + 2007-10-03 Frdric Bernon + * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, + netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce + a little bit the footprint (for all functions using only the "netif" parameter). + + 2007-09-15 Frdric Bernon + * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF + option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for + netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for + IP_MULTICAST_TTL and IP_MULTICAST_IF. + + 2007-09-10 Frdric Bernon + * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles + even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() + each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can + decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but + call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() + or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. + This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside + snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only + when it's queried (any direct call to "sysuptime" is changed by a call to + snmp_get_sysuptime). + + 2007-09-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, + and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags + if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). + igmp_report_groups() is now called inside netif_set_link_up() (need to have + LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait + the next query message to receive the matching multicast streams). + + 2007-09-08 Frdric Bernon + * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains + IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). + Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). + Enable to access to these fields with LWIP_TCP=0. + + 2007-09-05 Frdric Bernon + * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, + ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option + LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). + Be careful, disabling ICMP make your product non-compliant to RFC1122, but + help to reduce footprint, and to reduce "visibility" on the Internet. + + 2007-09-05 Frdric Bernon, Bill Florac + * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list + for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new + parameters have to be provided: a task name, and a task stack size. For this + one, since it's platform dependant, you could define the best one for you in + your lwipopts.h. For port maintainers, you can just add these new parameters + in your sys_arch.c file, and but it's not mandatory, use them in your OS + specific functions. + + 2007-09-05 Frdric Bernon + * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings + inside init.c for task #7142 "Sanity check user-configurable values". + + 2007-09-04 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by + memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the + value). It will avoid potential fragmentation problems, use a counter to know + how many times a group is used on an netif, and free it when all applications + leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity + check if LWIP_IGMP!=0). + + 2007-09-03 Frdric Bernon + * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". + Initialize igmp_mac_filter to NULL in netif_add (this field should be set in + the netif's "init" function). Use the "imr_interface" field (for socket layer) + and/or the "interface" field (for netconn layer), for join/leave operations. + The igmp_join/leavegroup first parameter change from a netif to an ipaddr. + This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). + + 2007-08-30 Frdric Bernon + * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions + from api/api_lib". Now netbuf API is independant of netconn, and can be used + with other API (application based on raw API, or future "socket2" API). Ports + maintainers just have to add src/api/netbuf.c in their makefile/projects. + + 2007-08-30 Frdric Bernon, Jonathan Larmour + * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check + user-configurable values". + + 2007-08-29 Frdric Bernon + * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. + igmp_start is call inside netif_add. Now, igmp initialization is in the same + spirit than the others modules. Modify some IGMP debug traces. + + 2007-08-29 Frdric Bernon + * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" + Add lwip_init function to regroup all modules initializations, and to provide + a place to add code for task #7142 "Sanity check user-configurable values". + Ports maintainers should remove direct initializations calls from their code, + and add init.c in their makefiles. Note that lwip_init() function is called + inside tcpip_init, but can also be used by raw api users since all calls are + disabled when matching options are disabled. Also note that their is new options + in opt.h, you should configure in your lwipopts.h (they are enabled per default). + + 2007-08-26 Marc Boucher + * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL + since they can under certain circumstances be called with an invalid conn + pointer after the connection has been closed (and conn has been freed). + + 2007-08-25 Frdric Bernon (Artem Migaev's Patch) + * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". + Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. + + 2007-08-22 Frdric Bernon + * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK + to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. + + 2007-08-22 Frdric Bernon + * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & + ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the + name is tcpip_input (we keep the name of 1.2.0 function). + + 2007-08-17 Jared Grubb + * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool + settings into new memp_std.h and optional user file lwippools.h. This adds + more dynamic mempools, and allows the user to create an arbitrary number of + mempools for mem_malloc. + + 2007-08-16 Marc Boucher + * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; + otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely + close the connection. + + 2007-08-16 Marc Boucher + * sockets.c: lwip_accept(): check netconn_peer() error return. + + 2007-08-16 Marc Boucher + * mem.c, mem.h: Added mem_calloc(). + + 2007-08-16 Marc Boucher + * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) + for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG + and starving other message types. + Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API + + 2007-08-16 Marc Boucher + * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf + type and flgs (later renamed to flags). + Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. + Improved lwip_recvfrom(). TCP push now propagated. + + 2007-08-16 Marc Boucher + * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global + provided by etharp. + + 2007-08-16 Marc Boucher + * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, + etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: + Added PPPoE support and various PPP improvements. + + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + + 2007-07-25 Simon Goldschmidt + * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with + 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and + other stacks. + + 2007-07-13 Jared Grubb (integrated by Frdric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + + 2007-06-30 Frdric Bernon + * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. + + 2007-06-21 Simon Goldschmidt + * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both + LWIP_AUTOIP =0 and =1 to remove redundant code. + + 2007-06-21 Simon Goldschmidt + * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option + MEM_USE_POOLS to use 4 pools with different sized elements instead of a + heap. This both prevents memory fragmentation and gives a higher speed + at the cost of more memory consumption. Turned off by default. + + 2007-06-21 Simon Goldschmidt + * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of + netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into + int to be able to send a bigger buffer than 64K with one time (mainly + used from lwip_send). + + 2007-06-21 Simon Goldschmidt + * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write + into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. + + 2007-06-21 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in + netconn_write from api_lib.c to api_msg.c to also prevent multiple context- + changes on low memory or empty send-buffer. + + 2007-06-18 Simon Goldschmidt + * etharp.c, etharp.h: Changed etharp to use a defined hardware address length + of 6 to avoid loading netif->hwaddr_len every time (since this file is only + used for ethernet and struct eth_addr already had a defined length of 6). + + 2007-06-17 Simon Goldschmidt + * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets + to disable UDP checksum generation on transmit. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid + pointers or parameters, and let the possibility to redefined it in cc.h. Use + this macro to check "conn" parameter in api_msg.c functions. + + 2007-06-11 Simon Goldschmidt + * sockets.c, sockets.h: Added UDP lite support for sockets + + 2007-06-10 Simon Goldschmidt + * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled + by default) to switch off UDP-Lite support if not needed (reduces udp.c code + size) + + 2007-06-09 Dominik Spies (integrated by Frdric Bernon) + * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: + AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and + LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt + (see TODO mark in the source code). + + 2007-06-09 Simon Goldschmidt + * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for + etharp_output() to match netif->output so etharp_output() can be used + directly as netif->output to save one function call. + + 2007-06-08 Simon Goldschmidt + * netif.h, ethernetif.c, slipif.c, loopif.c: Added define + NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, + added initialization of those to ethernetif, slipif and loopif. + + 2007-05-18 Simon Goldschmidt + * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF + (defaulting to off for now) that can be set to 0 to send fragmented + packets by passing PBUF_REFs down the stack. + + 2007-05-23 Frdric Bernon + * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP + connections, such present in patch #5959. + + 2007-05-23 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx + code in only one part... + + 2007-05-18 Simon Goldschmidt + * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp + elements to overflow. This is achieved by adding some bytes before and after + each pool element (increasing their size, of course), filling them with a + prominent value and checking them on freeing the element. + Set it to 2 to also check every element in every pool each time memp_malloc() + or memp_free() is called (slower but more helpful). + + 2007-05-10 Simon Goldschmidt + * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for + PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce + code size. + + 2007-05-11 Frdric Bernon + * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: + Include a function pointer instead of a table index in the message to reduce + footprint. Disable some part of lwip_send and lwip_sendto if some options are + not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). + + 2007-05-10 Simon Goldschmidt + * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus + \ extern "C" {' in all header files. Now you can write your application using + the lwIP stack in C++ and simply #include the core files. Note I have left + out the netif/ppp/*h header files for now, since I don't know which files are + included by applications and which are for internal use only. + + 2007-05-09 Simon Goldschmidt + * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library + memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for + situations where some compilers might inline the copy and save a function + call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). + + 2007-05-08 Simon Goldschmidt + * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) + to be overriden in case the C-library malloc implementation is not protected + against concurrent access. + + 2007-05-04 Simon Goldschmidt (Atte Kojo) + * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending + multiple packets to the same host. + + 2007-05-04 Frdric Bernon, Jonathan Larmour + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible + to corrupt remote addr/port connection state". Reduce problems "not enought memory" with + netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between + sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. + Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, + these fields are now renamed "addr" & "port". + + 2007-04-11 Jonathan Larmour + * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new + sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return + with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro + by the port in sys_arch.h if desired. + + 2007-04-06 Frdric Bernon, Simon Goldschmidt + * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API + allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp + clients, using new functions from netifapi.h. Disable as default (no port change to do). + + 2007-04-05 Frdric Bernon + * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. + + 2007-04-04 Simon Goldschmidt + * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) + use this for and architecture-independent form to tell the compiler you intentionally + are not using this variable. Can be overriden in cc.h. + + 2007-03-28 Frdric Bernon + * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to + define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded + string, point on one of your's ethernetif field, or alloc a string you will free yourself). + It will be used by DHCP to register a client hostname, but can also be use when you call + snmp_set_sysname. + + 2007-03-28 Frdric Bernon + * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to + initialize a network interface's flag with. It tell this interface is an ethernet + device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility + Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). + + 2007-03-26 Frdric Bernon, Jonathan Larmour + * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build + time if you only use PPP or SLIP. The default is enable. Note we don't have to call + etharp_init in your port's initilization sequence if you use tcpip.c, because this call + is done in tcpip_init function. + + 2007-03-22 Frdric Bernon + * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the + new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in + your lwipopts.h. More, unused counters are not defined in the stats structs, and not + display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined + but never used. Fix msg_in.c with the correct #if test for a stat display. + + 2007-03-21 Kieran Mansley + * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). + Provides callback on netif up/down state change. + + 2007-03-11 Frdric Bernon, Mace Gael, Steve Reynolds + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, + ip.c, netif.h, tcpip.c, opt.h: + New configuration option LWIP_IGMP to enable IGMP processing. Based on only one + filter per all network interfaces. Declare a new function in netif to enable to + control the MAC filter (to reduce lwIP traffic processing). + + 2007-03-11 Frdric Bernon + * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can + be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this + unless you know what you're doing (default are RFC1122 compliant). Note + that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. + + 2007-03-08 Frdric Bernon + * tcp.h: Keepalive values can be configured at compile time, but don't change + this unless you know what you're doing (default are RFC1122 compliant). + + 2007-03-08 Frdric Bernon + * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: + Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO + on UDP sockets/netconn. + + 2007-03-08 Simon Goldschmidt + * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. + + 2007-03-06 Frdric Bernon + * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: + Implement SO_RCVTIMEO on UDP sockets/netconn. + + 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) + * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated + on the stack and remove the API msg type from memp + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * sockets.h, sockets.c: Move socket initialization to new + lwip_socket_init() function. + NOTE: this changes the API with ports. Ports will have to be + updated to call lwip_socket_init() now. + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * api_lib.c: Use memcpy in netbuf_copy_partial. + + + ++ Bug fixes: + + 2008-03-17 Frdric Bernon, Ed Kerekes + * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have + some problems to fill the IP header on some targets, use now the + ip.h macros to do it). + + 2008-03-13 Frdric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + + 2008-03-12 Frdric Bernon, Jonathan Larmour + * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's + recv_raw() does not consume data", and the ping sample (with + LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom + returned the IP payload, without the IP header). + + 2008-03-04 Jonathan Larmour + * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors + and/or warnings on some systems where mem_size_t and size_t differ. + * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. + + 2008-03-04 Kieran Mansley (contributions by others) + * Numerous small compiler error/warning fixes from contributions to + mailing list after 1.3.0 release candidate made. + + 2008-01-25 Cui hengbin (integrated by Frdric Bernon) + * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. + + 2008-01-15 Kieran Mansley + * tcp_out.c: BUG20511. Modify persist timer to start when we are + prevented from sending by a small send window, not just a zero + send window. + + 2008-01-09 Jonathan Larmour + * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid + conflict with Linux system headers. + + 2008-01-06 Jonathan Larmour + * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP + address entirely on receiving a DHCPNAK, and restarting discovery. + + 2007-12-21 Simon Goldschmidt + * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail + is not protected" by using new macros for interlocked access to modify/test + netconn->recv_avail. + + 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) + * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) + + 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling + of silly window avoidance and prevent lwIP from shrinking the window) + + 2007-12-04 Simon Goldschmidt + * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last + data packet was lost): add assert that all segment lists are empty in + tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED + state from LAST_ACK in tcp_process + + 2007-12-02 Simon Goldschmidt + * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET + If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now + has to be set to 0 in lwipopts.h + + 2007-12-02 Simon Goldschmidt + * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always + allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen + netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. + This is a fix for thread-safety and allocates all items needed for a netconn + when the netconn is created. + + 2007-11-30 Simon Goldschmidt + * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple + netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed + to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same + port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) + + 2007-11-27 Simon Goldschmidt + * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by + letting ip_route only use netifs that are up. + + 2007-11-27 Simon Goldschmidt + * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF + and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and + sockets block most operations once they have seen a fatal error. + + 2007-11-27 Simon Goldschmidt + * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the + netif to send as an argument (to be able to send on netifs that are down). + + 2007-11-26 Simon Goldschmidt + * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs + arrive out-of-order + + 2007-11-21 Simon Goldschmidt + * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early + Fixed the nagle algorithm; nagle now also works for all raw API applications + and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' + + 2007-11-12 Frdric Bernon + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most + of the netconn_peer and netconn_addr processing is done inside tcpip_thread + context in do_getaddr. + + 2007-11-10 Simon Goldschmidt + * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can + happen any time). Now the packet simply isn't enqueued when out of memory. + + 2007-11-01 Simon Goldschmidt + * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or + TCP_MSS if that is smaller) as long as no MSS option is received from the + remote host. + + 2007-11-01 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) + is now based on TCP_MSS instead of pcb->mss (on passive open now effectively + sending our configured TCP_MSS instead of the one received). + + 2007-11-01 Simon Goldschmidt + * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was + calculated based on the configured TCP_MSS, not on the MSS option received + with SYN+ACK. + + 2007-10-09 Simon Goldschmidt + * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too + short and also was generated wrong if checksum coverage != tot_len; + receive: checksum was calculated wrong if checksum coverage != tot_len + + 2007-10-08 Simon Goldschmidt + * mem.c: lfree was not updated in mem_realloc! + + 2007-10-07 Frdric Bernon + * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential + crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: + this change cause an API breakage for netconn_addr, since a parameter + type change. Any compiler should cause an error without any changes in + yours netconn_peer calls (so, it can't be a "silent change"). It also + reduce a little bit the footprint for socket layer (lwip_getpeername & + lwip_getsockname use now a common lwip_getaddrname function since + netconn_peer & netconn_addr have the same parameters). + + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + + 2007-09-19 Simon Goldschmidt + * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) + + 2007-09-15 Mike Kleshov + * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) + + 2007-09-06 Frdric Bernon + * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove + it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which + already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" + if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. + + 2007-08-30 Frdric Bernon + * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, + and fix some coding style. + + 2007-08-28 Frdric Bernon + * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any + kind of packets. These packets are considered like Ethernet packets (payload + pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets + are considered like IP packets (payload pointing to iphdr). + + 2007-08-27 Frdric Bernon + * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error + problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state + and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). + + 2007-08-24 Kieran Mansley + * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy + compiler (Paradigm C++) + + 2007-08-09 Frdric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + + 2007-08-09 Frdric Bernon, Bill Florac + * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast + packet on a udp pcb binded on an netif's IP address, and not on "any". + + 2007-08-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. + This is mainly on using lookup/lookfor, and some coding styles... + + 2007-07-26 Frdric Bernon (and "thedoctor") + * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. + + 2007-07-25 Simon Goldschmidt + * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if + tcp_output fails in tcp_close, the code in do_close_internal gets simpler + (tcp_output is called again later from tcp timers). + + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + + 2007-07-25 Simon Goldschmidt + * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: + changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). + + 2007-07-24 Simon Goldschmidt + * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the + correct state (must be CLOSED). + + 2007-07-13 Thomas Taranowski (commited by Jared Grubb) + * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed + allocation. It now returns NULL. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in + all error cases. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, + because current code doesn't follow rawapi.txt documentation. + + 2007-07-13 Kieran Mansley + * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in + out of sequence processing of received packets + + 2007-07-03 Simon Goldschmidt + * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an + assumption is made that this pbuf is in one piece (i.e. not chained). These + assumptions clash with the possibility of converting to fully pool-based + pbuf implementations, where PBUF_RAM pbufs might be chained. + + 2007-07-03 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems + when closing tcp netconns: removed conn->sem, less context switches when + closing, both netconn_close and netconn_delete should safely close tcp + connections. + + 2007-07-02 Simon Goldschmidt + * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, + tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) + to cache ARP table indices with each pcb instead of single-entry cache for + the complete stack. + + 2007-07-02 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent + warnings when assigning to smaller types. + + 2007-06-28 Simon Goldschmidt + * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. + + 2007-06-28 Simon Goldschmidt + * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if + a segment contained chained pbufs) + + 2007-06-28 Frdric Bernon + * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute + a "pseudo-random" value based on netif's MAC and some autoip fields. It's always + possible to define this macro in your own lwipopts.h to always use C library's + rand(). Note that autoip_create_rand_addr doesn't use this macro. + + 2007-06-28 Frdric Bernon + * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option + LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications + in api_lib/api_msg (use pointers and not type with table, etc...) + + 2007-06-26 Simon Goldschmidt + * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload + for udp packets with no matching pcb. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match + could get udp input packets if the remote side matched. + + 2007-06-13 Simon Goldschmidt + * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get + changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. + + 2007-06-13 Simon Goldschmidt + * api_msg.c: pcb_new sets conn->err if protocol is not implemented + -> netconn_new_..() does not allocate a new connection for unsupported + protocols. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * api_lib.c: change return expression in netconn_addr and netconn_peer, because + conn->err was reset to ERR_OK without any reasons (and error was lost)... + + 2007-06-13 Frdric Bernon, Matthias Weisser + * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename + MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid + some macro names collision with some OS macros. + + 2007-06-11 Simon Goldschmidt + * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, + create checksum over the complete packet. On RX, if it's < 8 (and not 0), + discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both + UDP & UDP Lite. + + 2007-06-11 Srinivas Gollakota & Oleg Tyshev + * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" + where TCP flags wasn't initialized in tcp_keepalive. + + 2007-06-03 Simon Goldschmidt + * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function + registered, p->payload was modified without modifying p->len if sending + icmp_dest_unreach() (had no negative effect but was definitively wrong). + + 2007-06-03 Simon Goldschmidt + * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp + re-used the input pbuf even if that didn't have enough space to include the + link headers. Now the space is tested and a new pbuf is allocated for the + echo response packet if the echo request pbuf isn't big enough. + + 2007-06-01 Simon Goldschmidt + * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. + + 2007-05-23 Frdric Bernon + * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only + allocated by do_listen if success) and netconn_accept errors handling. In + most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" + by ASSERT, except for netconn_delete. + + 2007-05-23 Frdric Bernon + * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return + an error code if it's impossible to fetch a pbuf on a TCP connection (and not + directly close the recvmbox). + + 2007-05-22 Simon Goldschmidt + * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of + bound but unconnected (and non-listening) tcp_pcbs. + + 2007-05-22 Frdric Bernon + * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only + used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of + sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features + like "sys_timeout" in their application threads. + + 2007-05-22 Frdric Bernon + * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see + which parameters are used by which do_xxx function, and to avoid "misusing" + parameters (patch #5938). + + 2007-05-22 Simon Goldschmidt + * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: + changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto + is only 8 bits wide. This affects the api, as there, the protocol was + u16_t, too. + + 2007-05-18 Simon Goldschmidt + * memp.c: addition to patch #5913: smaller pointer was returned but + memp_memory was the same size -> did not save memory. + + 2007-05-16 Simon Goldschmidt + * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns + != ERR_OK. + + 2007-05-16 Simon Goldschmidt + * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same + as the one of the netif used for sending to prevent sending from old + addresses after a netif address gets changed (partly fixes bug #3168). + + 2007-05-16 Frdric Bernon + * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work + with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in + tcpip_init) because we have to be sure that network interfaces are already + added (mac filter is updated only in igmp_init for the moment). + + 2007-05-16 Simon Goldschmidt + * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls + into sys_arch_sem_wait calls to prevent timers from running while waiting + for the heap. This fixes bug #19167. + + 2007-05-13 Simon Goldschmidt + * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines + for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from + tcp.h to sockets.h. + + 2007-05-07 Simon Goldschmidt + * mem.c: Another attempt to fix bug #17922. + + 2007-05-04 Simon Goldschmidt + * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() + implementation so that it can be reused (don't allocate the target + pbuf inside pbuf_copy()). + + 2007-05-04 Simon Goldschmidt + * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem + to save a little RAM (next pointer of memp is not used while not in pool). + + 2007-05-03 "maq" + * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. + (patch #3574). + + 2007-04-23 Simon Goldschmidt + * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results + in NULL reference for incoming TCP packets". Loopif has to be configured + (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() + (multithreading environments, e.g. netif->input() = tcpip_input()) or + putting packets on a list that is fed to the stack by calling loopif_poll() + (single-thread / NO_SYS / polling environment where e.g. + netif->input() = ip_input). + + 2007-04-17 Jonathan Larmour + * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold + the difference between two u16_t's. + * sockets.h: FD_SETSIZE needs to match number of sockets, which is + MEMP_NUM_NETCONN in sockets.c right now. + + 2007-04-12 Jonathan Larmour + * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). + + 2007-04-12 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission + timer is reset to fix bug#19434, with help from Oleg Tyshev. + + 2007-04-11 Simon Goldschmidt + * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than + previously thought need to be copied (everything but PBUF_ROM!). Cleaned up + pbuf.c: removed functions no needed any more (by etharp). + + 2007-04-11 Kieran Mansley + * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix + "Constant is long" warnings with 16bit compilers. Contributed by + avatar@mmlab.cse.yzu.edu.tw + + 2007-04-05 Frdric Bernon, Jonathan Larmour + * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on + the mailbox is active". Now, the post is only done during a connect, and do_send, + do_write and do_join_leave_group don't do anything if a previous error was signaled. + + 2007-04-03 Frdric Bernon + * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output + packets. See patch #5834. + + 2007-03-30 Frdric Bernon + * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add + missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. + + 2007-03-30 Frdric Bernon + * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with + others environment defines (these were too "generic"). + + 2007-03-28 Frdric Bernon + * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call + result and can cause a crash. lwip_send now check netbuf_ref result. + + 2007-03-28 Simon Goldschmidt + * sockets.c Remove "#include " from sockets.c to avoid multiple + definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is + defined. This is the way it should have been already (looking at + doc/sys_arch.txt) + + 2007-03-28 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + + IP and TCP headers *and* physical link headers + + 2007-03-26 Frdric Bernon (based on patch from Dmitry Potapov) + * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause + to send some garbage. It is not a definitive solution, but the patch does solve + the problem for most cases. + + 2007-03-22 Frdric Bernon + * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). + + 2007-03-22 Frdric Bernon + * api_lib.c: somes resources couldn't be freed if there was errors during + netconn_new_with_proto_and_callback. + + 2007-03-22 Frdric Bernon + * ethernetif.c: update netif->input calls to check return value. In older ports, + it's a good idea to upgrade them, even if before, there could be another problem + (access to an uninitialized mailbox). + + 2007-03-21 Simon Goldschmidt + * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed + by casting to unsigned). + + 2007-03-21 Frdric Bernon + * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from + api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a + dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. + Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a + faster and more reliable communication between api_lib and tcpip. + + 2007-03-21 Frdric Bernon + * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. + + 2007-03-21 Frdric Bernon + * api_msg.c, igmp.c, igmp.h: Fix C++ style comments + + 2007-03-21 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + + IP and TCP headers + + 2007-03-21 Kieran Mansley + * Fix all uses of pbuf_header to check the return value. In some + cases just assert if it fails as I'm not sure how to fix them, but + this is no worse than before when they would carry on regardless + of the failure. + + 2007-03-21 Kieran Mansley + * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and + comment out missing header include in icmp.c + + 2007-03-20 Frdric Bernon + * memp.h, stats.c: Fix stats_display function where memp_names table wasn't + synchronized with memp.h. + + 2007-03-20 Frdric Bernon + * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, + tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with + network interfaces. Also fix a compiler warning. + + 2007-03-20 Kieran Mansley + * udp.c: Only try and use pbuf_header() to make space for headers if + not a ROM or REF pbuf. + + 2007-03-19 Frdric Bernon + * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() + and api_msg_post(). + + 2007-03-19 Frdric Bernon + * Remove unimplemented "memp_realloc" function from memp.h. + + 2007-03-11 Simon Goldschmidt + * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused + memory corruption. + + 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) + * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 + (missing `const' qualifier in socket functions), to get more compatible to + standard POSIX sockets. + + 2007-03-11 Frdric Bernon (based on patch from Dmitry Potapov) + * sockets.c: Add asserts inside bind, connect and sendto to check input + parameters. Remove excessive set_errno() calls after get_socket(), because + errno is set inside of get_socket(). Move last sock_set_errno() inside + lwip_close. + + 2007-03-09 Simon Goldschmidt + * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory + was allocated too small. + + 2007-03-06 Simon Goldschmidt + * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect + the stack from concurrent access. + + 2007-03-06 Frdric Bernon, Dmitry Potapov + * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy + call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). + + 2007-03-06 Simon Goldschmidt + * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files + if IP_FRAG == 0 and IP_REASSEMBLY == 0 + + 2007-03-06 Frdric Bernon, Simon Goldschmidt + * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration + option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. + Allow to do ARP processing for incoming packets inside tcpip_thread + (protecting ARP layer against concurrent access). You can also disable + old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. + Older ports have to use tcpip_ethinput. + + 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) + * err.h, err.c: fixed compiler warning "initialization dircards qualifiers + from pointer target type" + + 2007-03-05 Frdric Bernon + * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, + ETHARP_TRUST_IP_MAC, review SO_REUSE) + + 2007-03-04 Frdric Bernon + * api_msg.c: Remove some compiler warnings : parameter "pcb" was never + referenced. + + 2007-03-04 Frdric Bernon + * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from + Dmitry Potapov). + The api_msg struct stay on the stack (not moved to netconn struct). + + 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) + * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if + SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) + Also fixed cast warning in pbuf_alloc() + + 2007-03-04 Simon Goldschmidt + * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt + existing pbuf chain when enqueuing multiple pbufs to a pending ARP request + + 2007-03-03 Frdric Bernon + * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" + It is static, and never used in udp.c except udp_init(). + + 2007-03-02 Simon Goldschmidt + * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from + tcpip_thread() to tcpip_init(). This way, raw API connections can be + initialized before tcpip_thread is running (e.g. before OS is started) + + 2007-03-02 Frdric Bernon + * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call + interval. + + 2007-02-28 Kieran Mansley + * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved + outside the region of the pbuf by pbuf_header() + + 2007-02-28 Kieran Mansley + * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero + when supplied timeout is also non-zero + +(STABLE-1.2.0) + + 2006-12-05 Leon Woestenberg + * CHANGELOG: Mention STABLE-1.2.0 release. + + ++ New features: + + 2006-12-01 Christiaan Simons + * mem.h, opt.h: Added MEM_LIBC_MALLOC option. + Note this is a workaround. Currently I have no other options left. + + 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) + * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define + to include/lwip/opt.h. + * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. + Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. + * opt.h: Add above new options. + + 2006-08-18 Christiaan Simons + * tcp_{in,out}.c: added SNMP counters. + * ipv4/ip.c: added SNMP counters. + * ipv4/ip_frag.c: added SNMP counters. + + 2006-08-08 Christiaan Simons + * etharp.{c,h}: added etharp_find_addr() to read + (stable) ethernet/IP address pair from ARP table + + 2006-07-14 Christiaan Simons + * mib_structs.c: added + * include/lwip/snmp_structs.h: added + * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct + + 2006-07-06 Christiaan Simons + * snmp/asn1_{enc,dec}.c added + * snmp/mib2.c added + * snmp/msg_{in,out}.c added + * include/lwip/snmp_asn1.h added + * include/lwip/snmp_msg.h added + * doc/snmp_agent.txt added + + 2006-03-29 Christiaan Simons + * inet.c, inet.h: Added platform byteswap support. + Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and + optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. + + ++ Bug fixes: + + 2006-11-30 Christiaan Simons + * dhcp.c: Fixed false triggers of request_timeout. + + 2006-11-28 Christiaan Simons + * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. + + 2006-10-11 Christiaan Simons + * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: + Partially accepted patch #5449 for ANSI C compatibility / build fixes. + * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol + identifier from 170 to 136 (bug #17574). + + 2006-10-10 Christiaan Simons + * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. + + 2006-08-17 Christiaan Simons + * udp.c: Fixed bug #17200, added check for broadcast + destinations for PCBs bound to a unicast address. + + 2006-08-07 Christiaan Simons + * api_msg.c: Flushing TCP output in do_close() (bug #15926). + + 2006-06-27 Christiaan Simons + * api_msg.c: Applied patch for cold case (bug #11135). + In accept_function() ensure newconn->callback is always initialized. + + 2006-06-15 Christiaan Simons + * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), + facilitate printing of mem_size_t and u16_t statistics. + + 2006-06-14 Christiaan Simons + * api_msg.c: Applied patch #5146 to handle allocation failures + in accept() by Kevin Lawson. + + 2006-05-26 Christiaan Simons + * api_lib.c: Removed conn->sem creation and destruction + from netconn_write() and added sys_sem_new to netconn_new_*. + +(STABLE-1_1_1) + + 2006-03-03 Christiaan Simons + * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap + access and added pbuf_alloc() return value checks. + + 2006-01-01 Leon Woestenberg + * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is + now handled by the checksum routine properly. + + 2006-02-27 Leon Woestenberg + * pbuf.c: Fix alignment; pbuf_init() would not work unless + pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) + + 2005-12-20 Leon Woestenberg + * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch + submitted by Mitrani Hiroshi. + + 2005-12-15 Christiaan Simons + * inet.c: Disabled the added summing routine to preserve code space. + + 2005-12-14 Leon Woestenberg + * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. + Added Curt McDowell's optimized checksumming routine for future + inclusion. Need to create test case for unaliged, aligned, odd, + even length combination of cases on various endianess machines. + + 2005-12-09 Christiaan Simons + * inet.c: Rewrote standard checksum routine in proper portable C. + + 2005-11-25 Christiaan Simons + * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. + * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, + u32_t, s32_t typedefs. This solves most debug word-length assumes. + + 2005-07-17 Leon Woestenberg + * inet.c: Fixed unaligned 16-bit access in the standard checksum + routine by Peter Jolasson. + * slipif.c: Fixed implementation assumption of single-pbuf datagrams. + + 2005-02-04 Leon Woestenberg + * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. + * tcp_{out|in}.c: Applied patch fixing unaligned access. + + 2005-01-04 Leon Woestenberg + * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. + + 2005-01-03 Leon Woestenberg + * udp.c: UDP pcb->recv() was called even when it was NULL. + +(STABLE-1_1_0) + + 2004-12-28 Leon Woestenberg + * etharp.*: Disabled multiple packets on the ARP queue. + This clashes with TCP queueing. + + 2004-11-28 Leon Woestenberg + * etharp.*: Fixed race condition from ARP request to ARP timeout. + Halved the ARP period, doubled the period counts. + ETHARP_MAX_PENDING now should be at least 2. This prevents + the counter from reaching 0 right away (which would allow + too little time for ARP responses to be received). + + 2004-11-25 Leon Woestenberg + * dhcp.c: Decline messages were not multicast but unicast. + * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. + Do not try hard to insert arbitrary packet's source address, + etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. + etharp_query() now always DOES call ETHARP_TRY_HARD so that users + querying an address will see it appear in the cache (DHCP could + suffer from this when a server invalidly gave an in-use address.) + * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are + comparing network addresses (identifiers), not the network masks + themselves. + * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given + IP address actually belongs to the network of the given interface. + + 2004-11-24 Kieran Mansley + * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. + +(STABLE-1_1_0-RC1) + + 2004-10-16 Kieran Mansley + * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, + even if one is already pending, if the rcv_wnd is above a threshold + (currently TCP_WND/2). This avoids waiting for a timer to expire to send a + delayed ACK in order to open the window if the stack is only receiving data. + + 2004-09-12 Kieran Mansley + * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. + + 2004-08-20 Tony Mountifield + * etharp.c: Make sure the first pbuf queued on an ARP entry + is properly ref counted. + + 2004-07-27 Tony Mountifield + * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler + warnings about comparison. + * pbuf.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. Closed an unclosed comment. + * tcp.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. + * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). + * inet.c: Added a couple of casts to quiet the compiler. + No need to test isascii(c) before isdigit(c) or isxdigit(c). + + 2004-07-22 Tony Mountifield + * inet.c: Made data types consistent in inet_ntoa(). + Added casts for return values of checksum routines, to pacify compiler. + * ip_frag.c, tcp_out.c, sockets.c, pbuf.c + Small corrections to some debugging statements, to pacify compiler. + + 2004-07-21 Tony Mountifield + * etharp.c: Removed spurious semicolon and added missing end-of-comment. + * ethernetif.c Updated low_level_output() to match prototype for + netif->linkoutput and changed low_level_input() similarly for consistency. + * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype + of raw_recv() in raw.h and so avoid compiler error. + * sockets.c: Added trivial (int) cast to keep compiler happier. + * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. + +(STABLE-1_0_0) + + ++ Changes: + + 2004-07-05 Leon Woestenberg + * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure + your cc.h file defines this either 1 or 0. If non-defined, + defaults to 1. + * .c: Added and includes where used. + * etharp.c: Made some array indices unsigned. + + 2004-06-27 Leon Woestenberg + * netif.*: Added netif_set_up()/down(). + * dhcp.c: Changes to restart program flow. + + 2004-05-07 Leon Woestenberg + * etharp.c: In find_entry(), instead of a list traversal per candidate, do a + single-pass lookup for different candidates. Should exploit locality. + + 2004-04-29 Leon Woestenberg + * tcp*.c: Cleaned up source comment documentation for Doxygen processing. + * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. + * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by + the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. + + ++ Bug fixes: + + 2004-04-27 Leon Woestenberg + * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution + suggested by Timmy Brolin. Fix for 32-bit processors that cannot access + non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix + is to prefix the 14-bit Ethernet headers with two padding bytes. + + 2004-04-23 Leon Woestenberg + * ip_addr.c: Fix in the ip_addr_isbroadcast() check. + * etharp.c: Fixed the case where the packet that initiates the ARP request + is not queued, and gets lost. Fixed the case where the packets destination + address is already known; we now always queue the packet and perform an ARP + request. + +(STABLE-0_7_0) + + ++ Bug fixes: + + * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. + * Fixed TCP bug in dequeueing of FIN from out of order segment queue. + * Fixed two possible NULL references in rare cases. + +(STABLE-0_6_6) + + ++ Bug fixes: + + * Fixed DHCP which did not include the IP address in DECLINE messages. + + ++ Changes: + + * etharp.c has been hauled over a bit. + +(STABLE-0_6_5) + + ++ Bug fixes: + + * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. + * Packets sent from ARP queue had invalid source hardware address. + + ++ Changes: + + * Pass-by ARP requests do now update the cache. + + ++ New features: + + * No longer dependent on ctype.h. + * New socket options. + * Raw IP pcb support. + +(STABLE-0_6_4) + + ++ Bug fixes: + + * Some debug formatters and casts fixed. + * Numereous fixes in PPP. + + ++ Changes: + + * DEBUGF now is LWIP_DEBUGF + * pbuf_dechain() has been re-enabled. + * Mentioned the changed use of CVS branches in README. + +(STABLE-0_6_3) + + ++ Bug fixes: + + * Fixed pool pbuf memory leak in pbuf_alloc(). + Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. + Reported by Savin Zlobec. + + * PBUF_POOL chains had their tot_len field not set for non-first + pbufs. Fixed in pbuf_alloc(). + + ++ New features: + + * Added PPP stack contributed by Marc Boucher + + ++ Changes: + + * Now drops short packets for ICMP/UDP/TCP protocols. More robust. + + * ARP queueuing now queues the latest packet instead of the first. + This is the RFC recommended behaviour, but can be overridden in + lwipopts.h. + +(0.6.2) + + ++ Bugfixes: + + * TCP has been fixed to deal with the new use of the pbuf->ref + counter. + + * DHCP dhcp_inform() crash bug fixed. + + ++ Changes: + + * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed + pbuf_refresh(). This has sped up pbuf pool operations considerably. + Implemented by David Haas. + +(0.6.1) + + ++ New features: + + * The packet buffer implementation has been enhanced to support + zero-copy and copy-on-demand for packet buffers which have their + payloads in application-managed memory. + Implemented by David Haas. + + Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy + if an outgoing packet can be directly sent on the link, or perform + a copy-on-demand when necessary. + + The application can safely assume the packet is sent, and the RAM + is available to the application directly after calling udp_send() + or similar function. + + ++ Bugfixes: + + * ARP_QUEUEING should now correctly work for all cases, including + PBUF_REF. + Implemented by Leon Woestenberg. + + ++ Changes: + + * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer + to a '0.0.0.0' IP address. + + * The packet buffer implementation is changed. The pbuf->ref counter + meaning has changed, and several pbuf functions have been + adapted accordingly. + + * netif drivers have to be changed to set the hardware address length field + that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). + See the contrib/ports/c16x cs8900 driver as a driver example. + + * netif's have a dhcp field that must be initialized to NULL by the driver. + See the contrib/ports/c16x cs8900 driver as a driver example. + +(0.5.x) This file has been unmaintained up to 0.6.1. All changes are + logged in CVS but have not been explained here. + +(0.5.3) Changes since version 0.5.2 + + ++ Bugfixes: + + * memp_malloc(MEMP_API_MSG) could fail with multiple application + threads because it wasn't protected by semaphores. + + ++ Other changes: + + * struct ip_addr now packed. + + * The name of the time variable in arp.c has been changed to ctime + to avoid conflicts with the time() function. + +(0.5.2) Changes since version 0.5.1 + + ++ New features: + + * A new TCP function, tcp_tmr(), now handles both TCP timers. + + ++ Bugfixes: + + * A bug in tcp_parseopt() could cause the stack to hang because of a + malformed TCP option. + + * The address of new connections in the accept() function in the BSD + socket library was not handled correctly. + + * pbuf_dechain() did not update the ->tot_len field of the tail. + + * Aborted TCP connections were not handled correctly in all + situations. + + ++ Other changes: + + * All protocol header structs are now packed. + + * The ->len field in the tcp_seg structure now counts the actual + amount of data, and does not add one for SYN and FIN segments. + +(0.5.1) Changes since version 0.5.0 + + ++ New features: + + * Possible to run as a user process under Linux. + + * Preliminary support for cross platform packed structs. + + * ARP timer now implemented. + + ++ Bugfixes: + + * TCP output queue length was badly initialized when opening + connections. + + * TCP delayed ACKs were not sent correctly. + + * Explicit initialization of BSS segment variables. + + * read() in BSD socket library could drop data. + + * Problems with memory alignment. + + * Situations when all TCP buffers were used could lead to + starvation. + + * TCP MSS option wasn't parsed correctly. + + * Problems with UDP checksum calculation. + + * IP multicast address tests had endianess problems. + + * ARP requests had wrong destination hardware address. + + ++ Other changes: + + * struct eth_addr changed from u16_t[3] array to u8_t[6]. + + * A ->linkoutput() member was added to struct netif. + + * TCP and UDP ->dest_* struct members where changed to ->remote_*. + + * ntoh* macros are now null definitions for big endian CPUs. + +(0.5.0) Changes since version 0.4.2 + + ++ New features: + + * Redesigned operating system emulation layer to make porting easier. + + * Better control over TCP output buffers. + + * Documenation added. + + ++ Bugfixes: + + * Locking issues in buffer management. + + * Bugfixes in the sequential API. + + * IP forwarding could cause memory leakage. This has been fixed. + + ++ Other changes: + + * Directory structure somewhat changed; the core/ tree has been + collapsed. + +(0.4.2) Changes since version 0.4.1 + + ++ New features: + + * Experimental ARP implementation added. + + * Skeleton Ethernet driver added. + + * Experimental BSD socket API library added. + + ++ Bugfixes: + + * In very intense situations, memory leakage could occur. This has + been fixed. + + ++ Other changes: + + * Variables named "data" and "code" have been renamed in order to + avoid name conflicts in certain compilers. + + * Variable++ have in appliciable cases been translated to ++variable + since some compilers generate better code in the latter case. + +(0.4.1) Changes since version 0.4 + + ++ New features: + + * TCP: Connection attempts time out earlier than data + transmissions. Nagle algorithm implemented. Push flag set on the + last segment in a burst. + + * UDP: experimental support for UDP-Lite extensions. + + ++ Bugfixes: + + * TCP: out of order segments were in some cases handled incorrectly, + and this has now been fixed. Delayed acknowledgements was broken + in 0.4, has now been fixed. Binding to an address that is in use + now results in an error. Reset connections sometimes hung an + application; this has been fixed. + + * Checksum calculation sometimes failed for chained pbufs with odd + lengths. This has been fixed. + + * API: a lot of bug fixes in the API. The UDP API has been improved + and tested. Error reporting and handling has been + improved. Logical flaws and race conditions for incoming TCP + connections has been found and removed. + + * Memory manager: alignment issues. Reallocating memory sometimes + failed, this has been fixed. + + * Generic library: bcopy was flawed and has been fixed. + + ++ Other changes: + + * API: all datatypes has been changed from generic ones such as + ints, to specified ones such as u16_t. Functions that return + errors now have the correct type (err_t). + + * General: A lot of code cleaned up and debugging code removed. Many + portability issues have been fixed. + + * The license was changed; the advertising clause was removed. + + * C64 port added. + + * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri + Kosunen, Mikael Caleres, and Frits Wilmink for reporting and + fixing bugs! + +(0.4) Changes since version 0.3.1 + + * Memory management has been radically changed; instead of + allocating memory from a shared heap, memory for objects that are + rapidly allocated and deallocated is now kept in pools. Allocation + and deallocation from those memory pools is very fast. The shared + heap is still present but is used less frequently. + + * The memory, memory pool, and packet buffer subsystems now support + 4-, 2-, or 1-byte alignment. + + * "Out of memory" situations are handled in a more robust way. + + * Stack usage has been reduced. + + * Easier configuration of lwIP parameters such as memory usage, + TTLs, statistics gathering, etc. All configuration parameters are + now kept in a single header file "lwipopts.h". + + * The directory structure has been changed slightly so that all + architecture specific files are kept under the src/arch + hierarchy. + + * Error propagation has been improved, both in the protocol modules + and in the API. + + * The code for the RTXC architecture has been implemented, tested + and put to use. + + * Bugs have been found and corrected in the TCP, UDP, IP, API, and + the Internet checksum modules. + + * Bugs related to porting between a 32-bit and a 16-bit architecture + have been found and corrected. + + * The license has been changed slightly to conform more with the + original BSD license, including the advertisement clause. + +(0.3.1) Changes since version 0.3 + + * Fix of a fatal bug in the buffer management. Pbufs with allocated + RAM never returned the RAM when the pbuf was deallocated. + + * TCP congestion control, window updates and retransmissions did not + work correctly. This has now been fixed. + + * Bugfixes in the API. + +(0.3) Changes since version 0.2 + + * New and improved directory structure. All include files are now + kept in a dedicated include/ directory. + + * The API now has proper error handling. A new function, + netconn_err(), now returns an error code for the connection in + case of errors. + + * Improvements in the memory management subsystem. The system now + keeps a pointer to the lowest free memory block. A new function, + mem_malloc2() tries to allocate memory once, and if it fails tries + to free some memory and retry the allocation. + + * Much testing has been done with limited memory + configurations. lwIP now does a better job when overloaded. + + * Some bugfixes and improvements to the buffer (pbuf) subsystem. + + * Many bugfixes in the TCP code: + + - Fixed a bug in tcp_close(). + + - The TCP receive window was incorrectly closed when out of + sequence segments was received. This has been fixed. + + - Connections are now timed-out of the FIN-WAIT-2 state. + + - The initial congestion window could in some cases be too + large. This has been fixed. + + - The retransmission queue could in some cases be screwed up. This + has been fixed. + + - TCP RST flag now handled correctly. + + - Out of sequence data was in some cases never delivered to the + application. This has been fixed. + + - Retransmitted segments now contain the correct acknowledgment + number and advertised window. + + - TCP retransmission timeout backoffs are not correctly computed + (ala BSD). After a number of retransmissions, TCP now gives up + the connection. + + * TCP connections now are kept on three lists, one for active + connections, one for listening connections, and one for + connections that are in TIME-WAIT. This greatly speeds up the fast + timeout processing for sending delayed ACKs. + + * TCP now provides proper feedback to the application when a + connection has been successfully set up. + + * More comments have been added to the code. The code has also been + somewhat cleaned up. + +(0.2) Initial public release. diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/COPYING b/USDK/component/common/network/lwip/lwip_v1.3.2/COPYING new file mode 100644 index 0000000..e23898b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/COPYING @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/FILES b/USDK/component/common/network/lwip/lwip_v1.3.2/FILES new file mode 100644 index 0000000..6625319 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/FILES @@ -0,0 +1,4 @@ +src/ - The source code for the lwIP TCP/IP stack. +doc/ - The documentation for lwIP. + +See also the FILES file in each subdirectory. diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/README b/USDK/component/common/network/lwip/lwip_v1.3.2/README new file mode 100644 index 0000000..a62cc4f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/README @@ -0,0 +1,89 @@ +INTRODUCTION + +lwIP is a small independent implementation of the TCP/IP protocol +suite that has been developed by Adam Dunkels at the Computer and +Networks Architectures (CNA) lab at the Swedish Institute of Computer +Science (SICS). + +The focus of the lwIP TCP/IP implementation is to reduce the RAM usage +while still having a full scale TCP. This making lwIP suitable for use +in embedded systems with tens of kilobytes of free RAM and room for +around 40 kilobytes of code ROM. + +FEATURES + + * IP (Internet Protocol) including packet forwarding over multiple network + interfaces + * ICMP (Internet Control Message Protocol) for network maintenance and debugging + * IGMP (Internet Group Management Protocol) for multicast traffic management + * UDP (User Datagram Protocol) including experimental UDP-lite extensions + * TCP (Transmission Control Protocol) with congestion control, RTT estimation + and fast recovery/fast retransmit + * Specialized raw/native API for enhanced performance + * Optional Berkeley-like socket API + * DNS (Domain names resolver) + * SNMP (Simple Network Management Protocol) + * DHCP (Dynamic Host Configuration Protocol) + * AUTOIP (for IPv4, conform with RFC 3927) + * PPP (Point-to-Point Protocol) + * ARP (Address Resolution Protocol) for Ethernet + +LICENSE + +lwIP is freely available under a BSD license. + +DEVELOPMENT + +lwIP has grown into an excellent TCP/IP stack for embedded devices, +and developers using the stack often submit bug fixes, improvements, +and additions to the stack to further increase its usefulness. + +Development of lwIP is hosted on Savannah, a central point for +software development, maintenance and distribution. Everyone can +help improve lwIP by use of Savannah's interface, CVS and the +mailing list. A core team of developers will commit changes to the +CVS source tree. + +The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and +contributions (such as platform ports) are in the 'contrib' module. + +See doc/savannah.txt for details on CVS server access for users and +developers. + +Last night's CVS tar ball can be downloaded from: + http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING] + +The current CVS trees are web-browsable: + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/ + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/ + +Submit patches and bugs via the lwIP project page: + http://savannah.nongnu.org/projects/lwip/ + + +DOCUMENTATION + +The original out-dated homepage of lwIP and Adam Dunkels' papers on +lwIP are at the official lwIP home page: + http://www.sics.se/~adam/lwip/ + +Self documentation of the source code is regularly extracted from the +current CVS sources and is available from this web page: + http://www.nongnu.org/lwip/ + +There is now a constantly growin wiki about lwIP at + http://lwip.wikia.com/wiki/LwIP_Wiki + +Also, there are mailing lists you can subscribe at + http://savannah.nongnu.org/mail/?group=lwip +plus searchable archives: + http://lists.nongnu.org/archive/html/lwip-users/ + http://lists.nongnu.org/archive/html/lwip-devel/ + +Reading Adam's papers, the files in docs/, browsing the source code +documentation and browsing the mailing list archives is a good way to +become familiar with the design of lwIP. + +Adam Dunkels +Leon Woestenberg + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/FILES b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/FILES new file mode 100644 index 0000000..05d356f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/FILES @@ -0,0 +1,6 @@ +savannah.txt - How to obtain the current development source code. +contrib.txt - How to contribute to lwIP as a developer. +rawapi.txt - The documentation for the core API of lwIP. + Also provides an overview about the other APIs and multithreading. +snmp_agent.txt - The documentation for the lwIP SNMP agent. +sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/contrib.txt b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/contrib.txt new file mode 100644 index 0000000..39596fc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/contrib.txt @@ -0,0 +1,63 @@ +1 Introduction + +This document describes some guidelines for people participating +in lwIP development. + +2 How to contribute to lwIP + +Here is a short list of suggestions to anybody working with lwIP and +trying to contribute bug reports, fixes, enhancements, platform ports etc. +First of all as you may already know lwIP is a volunteer project so feedback +to fixes or questions might often come late. Hopefully the bug and patch tracking +features of Savannah help us not lose users' input. + +2.1 Source code style: + +1. do not use tabs. +2. indentation is two spaces per level (i.e. per tab). +3. end debug messages with a trailing newline (\n). +4. one space between keyword and opening bracket. +5. no space between function and opening bracket. +6. one space and no newline before opening curly braces of a block. +7. closing curly brace on a single line. +8. spaces surrounding assignment and comparisons. +9. don't initialize static and/or global variables to zero, the compiler takes care of that. +10. use current source code style as further reference. + +2.2 Source code documentation style: + +1. JavaDoc compliant and Doxygen compatible. +2. Function documentation above functions in .c files, not .h files. + (This forces you to synchronize documentation and implementation.) +3. Use current documentation style as further reference. + +2.3 Bug reports and patches: + +1. Make sure you are reporting bugs or send patches against the latest + sources. (From the latest release and/or the current CVS sources.) +2. If you think you found a bug make sure it's not already filed in the + bugtracker at Savannah. +3. If you have a fix put the patch on Savannah. If it is a patch that affects + both core and arch specific stuff please separate them so that the core can + be applied separately while leaving the other patch 'open'. The prefered way + is to NOT touch archs you can't test and let maintainers take care of them. + This is a good way to see if they are used at all - the same goes for unix + netifs except tapif. +4. Do not file a bug and post a fix to it to the patch area. Either a bug report + or a patch will be enough. + If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. +5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two) + can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded + as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead + for reporting a compiler warning fix. +6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other + trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you + change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than + if it's not to the point and long :) so the chances for it to be applied are greater. + +2.4 Platform porters: + +1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and + you think it could benefit others[1] you might want discuss this on the mailing list. You + can also ask for CVS access to submit and maintain your port in the contrib CVS module. + \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/rawapi.txt b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/rawapi.txt new file mode 100644 index 0000000..8eec6e7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/rawapi.txt @@ -0,0 +1,478 @@ +Raw TCP/IP interface for lwIP + +Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons + +lwIP provides three Application Program's Interfaces (APIs) for programs +to use for communication with the TCP/IP code: +* low-level "core" / "callback" or "raw" API. +* higher-level "sequential" API. +* BSD-style socket API. + +The sequential API provides a way for ordinary, sequential, programs +to use the lwIP stack. It is quite similar to the BSD socket API. The +model of execution is based on the blocking open-read-write-close +paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP +code and the application program must reside in different execution +contexts (threads). + +The socket API is a compatibility API for existing applications, +currently it is built on top of the sequential API. It is meant to +provide all functions needed to run socket API applications running +on other platforms (e.g. unix / windows etc.). However, due to limitations +in the specification of this API, there might be incompatibilities +that require small modifications of existing programs. + +** Threading + +lwIP started targeting single-threaded environments. When adding multi- +threading support, instead of making the core thread-safe, another +approach was chosen: there is one main thread running the lwIP core +(also known as the "tcpip_thread"). The raw API may only be used from +this thread! Application threads using the sequential- or socket API +communicate with this main thread through message passing. + + As such, the list of functions that may be called from + other threads or an ISR is very limited! Only functions + from these API header files are thread-safe: + - api.h + - netbuf.h + - netdb.h + - netifapi.h + - sockets.h + - sys.h + + Additionaly, memory (de-)allocation functions may be + called from multiple threads (not ISR!) with NO_SYS=0 + since they are protected by SYS_LIGHTWEIGHT_PROT and/or + semaphores. + + Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 + and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + pbuf_free() may also be called from another thread or + an ISR (since only then, mem_free - for PBUF_RAM - may + be called from an ISR: otherwise, the HEAP is only + protected by semaphores). + + +** The remainder of this document discusses the "raw" API. ** + +The raw TCP/IP interface allows the application program to integrate +better with the TCP/IP code. Program execution is event based by +having callback functions being called from within the TCP/IP +code. The TCP/IP code and the application program both run in the same +thread. The sequential API has a much higher overhead and is not very +well suited for small systems since it forces a multithreaded paradigm +on the application. + +The raw TCP/IP interface is not only faster in terms of code execution +time but is also less memory intensive. The drawback is that program +development is somewhat harder and application programs written for +the raw TCP/IP interface are more difficult to understand. Still, this +is the preferred way of writing applications that should be small in +code size and memory usage. + +Both APIs can be used simultaneously by different application +programs. In fact, the sequential API is implemented as an application +program using the raw TCP/IP interface. + +--- Callbacks + +Program execution is driven by callbacks. Each callback is an ordinary +C function that is called from within the TCP/IP code. Every callback +function is passed the current TCP or UDP connection state as an +argument. Also, in order to be able to keep program specific state, +the callback functions are called with a program specified argument +that is independent of the TCP/IP state. + +The function for setting the application connection state is: + +- void tcp_arg(struct tcp_pcb *pcb, void *arg) + + Specifies the program specific state that should be passed to all + other callback functions. The "pcb" argument is the current TCP + connection control block, and the "arg" argument is the argument + that will be passed to the callbacks. + + +--- TCP connection setup + +The functions used for setting up connections is similar to that of +the sequential API and of the BSD socket API. A new TCP connection +identifier (i.e., a protocol control block - PCB) is created with the +tcp_new() function. This PCB can then be either set to listen for new +incoming connections or be explicitly connected to another host. + +- struct tcp_pcb *tcp_new(void) + + Creates a new connection identifier (PCB). If memory is not + available for creating the new pcb, NULL is returned. + +- err_t tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port) + + Binds the pcb to a local IP address and port number. The IP address + can be specified as IP_ADDR_ANY in order to bind the connection to + all local IP addresses. + + If another connection is bound to the same port, the function will + return ERR_USE, otherwise ERR_OK is returned. + +- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) + + Commands a pcb to start listening for incoming connections. When an + incoming connection is accepted, the function specified with the + tcp_accept() function will be called. The pcb will have to be bound + to a local port with the tcp_bind() function. + + The tcp_listen() function returns a new connection identifier, and + the one passed as an argument to the function will be + deallocated. The reason for this behavior is that less memory is + needed for a connection that is listening, so tcp_listen() will + reclaim the memory needed for the original connection and allocate a + new smaller memory block for the listening connection. + + tcp_listen() may return NULL if no memory was available for the + listening connection. If so, the memory associated with the pcb + passed as an argument to tcp_listen() will not be deallocated. + +- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) + + Same as tcp_listen, but limits the number of outstanding connections + in the listen queue to the value specified by the backlog argument. + To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. + +- void tcp_accepted(struct tcp_pcb *pcb) + + Inform lwIP that an incoming connection has been accepted. This would + usually be called from the accept callback. This allows lwIP to perform + housekeeping tasks, such as allowing further incoming connections to be + queued in the listen backlog. + +- void tcp_accept(struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, + err_t err)) + + Specified the callback function that should be called when a new + connection arrives on a listening connection. + +- err_t tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port, err_t (* connected)(void *arg, + struct tcp_pcb *tpcb, + err_t err)); + + Sets up the pcb to connect to the remote host and sends the + initial SYN segment which opens the connection. + + The tcp_connect() function returns immediately; it does not wait for + the connection to be properly setup. Instead, it will call the + function specified as the fourth argument (the "connected" argument) + when the connection is established. If the connection could not be + properly established, either because the other host refused the + connection or because the other host didn't answer, the "err" + callback function of this pcb (registered with tcp_err, see below) + will be called. + + The tcp_connect() function can return ERR_MEM if no memory is + available for enqueueing the SYN segment. If the SYN indeed was + enqueued successfully, the tcp_connect() function returns ERR_OK. + + +--- Sending TCP data + +TCP data is sent by enqueueing the data with a call to +tcp_write(). When the data is successfully transmitted to the remote +host, the application will be notified with a call to a specified +callback function. + +- err_t tcp_write(struct tcp_pcb *pcb, void *dataptr, u16_t len, + u8_t copy) + + Enqueues the data pointed to by the argument dataptr. The length of + the data is passed as the len parameter. The copy argument is either + 0 or 1 and indicates whether the new memory should be allocated for + the data to be copied into. If the argument is 0, no new memory + should be allocated and the data should only be referenced by + pointer. + + The tcp_write() function will fail and return ERR_MEM if the length + of the data exceeds the current send buffer size or if the length of + the queue of outgoing segment is larger than the upper limit defined + in lwipopts.h. The number of bytes available in the output queue can + be retrieved with the tcp_sndbuf() function. + + The proper way to use this function is to call the function with at + most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, + the application should wait until some of the currently enqueued + data has been successfully received by the other host and try again. + +- void tcp_sent(struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, + u16_t len)) + + Specifies the callback function that should be called when data has + successfully been received (i.e., acknowledged) by the remote + host. The len argument passed to the callback function gives the + amount bytes that was acknowledged by the last acknowledgment. + + +--- Receiving TCP data + +TCP data reception is callback based - an application specified +callback function is called when new data arrives. When the +application has taken the data, it has to call the tcp_recved() +function to indicate that TCP can advertise increase the receive +window. + +- void tcp_recv(struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err)) + + Sets the callback function that will be called when new data + arrives. The callback function will be passed a NULL pbuf to + indicate that the remote host has closed the connection. If + there are no errors and the callback function is to return + ERR_OK, then it must free the pbuf. Otherwise, it must not + free the pbuf so that lwIP core code can store it. + +- void tcp_recved(struct tcp_pcb *pcb, u16_t len) + + Must be called when the application has received the data. The len + argument indicates the length of the received data. + + +--- Application polling + +When a connection is idle (i.e., no data is either transmitted or +received), lwIP will repeatedly poll the application by calling a +specified callback function. This can be used either as a watchdog +timer for killing connections that have stayed idle for too long, or +as a method of waiting for memory to become available. For instance, +if a call to tcp_write() has failed because memory wasn't available, +the application may use the polling functionality to call tcp_write() +again when the connection has been idle for a while. + +- void tcp_poll(struct tcp_pcb *pcb, u8_t interval, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb)) + + Specifies the polling interval and the callback function that should + be called to poll the application. The interval is specified in + number of TCP coarse grained timer shots, which typically occurs + twice a second. An interval of 10 means that the application would + be polled every 5 seconds. + + +--- Closing and aborting connections + +- err_t tcp_close(struct tcp_pcb *pcb) + + Closes the connection. The function may return ERR_MEM if no memory + was available for closing the connection. If so, the application + should wait and try again either by using the acknowledgment + callback or the polling functionality. If the close succeeds, the + function returns ERR_OK. + + The pcb is deallocated by the TCP code after a call to tcp_close(). + +- void tcp_abort(struct tcp_pcb *pcb) + + Aborts the connection by sending a RST (reset) segment to the remote + host. The pcb is deallocated. This function never fails. + +If a connection is aborted because of an error, the application is +alerted of this event by the err callback. Errors that might abort a +connection are when there is a shortage of memory. The callback +function to be called is set using the tcp_err() function. + +- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, + err_t err)) + + The error callback function does not get the pcb passed to it as a + parameter since the pcb may already have been deallocated. + + +--- Lower layer TCP interface + +TCP provides a simple interface to the lower layers of the +system. During system initialization, the function tcp_init() has +to be called before any other TCP function is called. When the system +is running, the two timer functions tcp_fasttmr() and tcp_slowtmr() +must be called with regular intervals. The tcp_fasttmr() should be +called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and +tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. + + +--- UDP interface + +The UDP interface is similar to that of TCP, but due to the lower +level of complexity of UDP, the interface is significantly simpler. + +- struct udp_pcb *udp_new(void) + + Creates a new UDP pcb which can be used for UDP communication. The + pcb is not active until it has either been bound to a local address + or connected to a remote address. + +- void udp_remove(struct udp_pcb *pcb) + + Removes and deallocates the pcb. + +- err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port) + + Binds the pcb to a local address. The IP-address argument "ipaddr" + can be IP_ADDR_ANY to indicate that it should listen to any local IP + address. The function currently always return ERR_OK. + +- err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port) + + Sets the remote end of the pcb. This function does not generate any + network traffic, but only set the remote address of the pcb. + +- err_t udp_disconnect(struct udp_pcb *pcb) + + Remove the remote end of the pcb. This function does not generate + any network traffic, but only removes the remote address of the pcb. + +- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) + + Sends the pbuf p. The pbuf is not deallocated. + +- void udp_recv(struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, + struct pbuf *p, + struct ip_addr *addr, + u16_t port), + void *recv_arg) + + Specifies a callback function that should be called when a UDP + datagram is received. + + +--- System initalization + +A truly complete and generic sequence for initializing the lwip stack +cannot be given because it depends on the build configuration (lwipopts.h) +and additional initializations for your runtime environment (e.g. timers). + +We can give you some idea on how to proceed when using the raw API. +We assume a configuration using a single Ethernet netif and the +UDP and TCP transport layers, IPv4 and the DHCP client. + +Call these functions in the order of appearance: + +- stats_init() + + Clears the structure where runtime statistics are gathered. + +- sys_init() + + Not of much use since we set the NO_SYS 1 option in lwipopts.h, + to be called for easy configuration changes. + +- mem_init() + + Initializes the dynamic memory heap defined by MEM_SIZE. + +- memp_init() + + Initializes the memory pools defined by MEMP_NUM_x. + +- pbuf_init() + + Initializes the pbuf memory pool defined by PBUF_POOL_SIZE. + +- etharp_init() + + Initializes the ARP table and queue. + Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval + after this initialization. + +- ip_init() + + Doesn't do much, it should be called to handle future changes. + +- udp_init() + + Clears the UDP PCB list. + +- tcp_init() + + Clears the TCP PCB list and clears some internal TCP timers. + Note: you must call tcp_fasttmr() and tcp_slowtmr() at the + predefined regular intervals after this initialization. + +- netif_add(struct netif *netif, struct ip_addr *ipaddr, + struct ip_addr *netmask, struct ip_addr *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use. + + err_t netif_if_init(struct netif *netif) + { + u8_t i; + + for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i]; + init_my_eth_device(); + return ERR_OK; + } + + For ethernet drivers, the input function pointer must point to the lwip + function ethernet_input() declared in "netif/etharp.h". Other drivers + must use ip_input() declared in "lwip/ip.h". + +- netif_set_default(struct netif *netif) + + Registers the default network interface. + +- netif_set_up(struct netif *netif) + + When the netif is fully configured this function must be called. + +- dhcp_start(struct netif *netif) + + Creates a new DHCP client for this interface on the first call. + Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + the predefined regular intervals after starting the client. + + You can peek in the netif->dhcp struct for the actual DHCP status. + + +--- Optimalization hints + +The first thing you want to optimize is the lwip_standard_checksum() +routine from src/core/inet.c. You can override this standard +function with the #define LWIP_CHKSUM . + +There are C examples given in inet.c or you might want to +craft an assembly function for this. RFC1071 is a good +introduction to this subject. + +Other significant improvements can be made by supplying +assembly or inline replacements for htons() and htonl() +if you're using a little-endian architecture. +#define LWIP_PLATFORM_BYTESWAP 1 +#define LWIP_PLATFORM_HTONS(x) +#define LWIP_PLATFORM_HTONL(x) + +Check your network interface driver if it reads at +a higher speed than the maximum wire-speed. If the +hardware isn't serviced frequently and fast enough +buffer overflows are likely to occur. + +E.g. when using the cs8900 driver, call cs8900if_service(ethif) +as frequently as possible. When using an RTOS let the cs8900 interrupt +wake a high priority task that services your driver using a binary +semaphore or event flag. Some drivers might allow additional tuning +to match your application and network. + +For a production release it is recommended to set LWIP_STATS to 0. +Note that speed performance isn't influenced much by simply setting +high values to the memory options. diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/savannah.txt b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/savannah.txt new file mode 100644 index 0000000..409905b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/savannah.txt @@ -0,0 +1,135 @@ +Daily Use Guide for using Savannah for lwIP + +Table of Contents: + +1 - Obtaining lwIP from the CVS repository +2 - Committers/developers CVS access using SSH (to be written) +3 - Merging from DEVEL branch to main trunk (stable branch) +4 - How to release lwIP + + + +1 Obtaining lwIP from the CVS repository +---------------------------------------- + +To perform an anonymous CVS checkout of the main trunk (this is where +bug fixes and incremental enhancements occur), do this: + +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip + +Or, obtain a stable branch (updated with bug fixes only) as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7 -d lwip-0.7 lwip + +Or, obtain a specific (fixed) release as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7_0 -d lwip-0.7.0 lwip + +3 Committers/developers CVS access using SSH +-------------------------------------------- + +The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. +As such, CVS commits to the server occur through a SSH tunnel for project members. +To create a SSH2 key pair in UNIX-like environments, do this: + +ssh-keygen -t dsa + +Under Windows, a recommended SSH client is "PuTTY", freely available with good +documentation and a graphic user interface. Use its key generator. + +Now paste the id_dsa.pub contents into your Savannah account public key list. Wait +a while so that Savannah can update its configuration (This can take minutes). + +Try to login using SSH: + +ssh -v your_login@cvs.sv.gnu.org + +If it tells you: + +Authenticating with public key "your_key_name"... +Server refused to allocate pty + +then you could login; Savannah refuses to give you a shell - which is OK, as we +are allowed to use SSH for CVS only. Now, you should be able to do this: + +export CVS_RSH=ssh +cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip + +after which you can edit your local files with bug fixes or new features and +commit them. Make sure you know what you are doing when using CVS to make +changes on the repository. If in doubt, ask on the lwip-members mailing list. + +(If SSH asks about authenticity of the host, you can check the key + fingerprint against http://savannah.nongnu.org/cvs/?group=lwip) + + +3 Merging from DEVEL branch to main trunk (stable) +-------------------------------------------------- + +Merging is a delicate process in CVS and requires the +following disciplined steps in order to prevent conflicts +in the future. Conflicts can be hard to solve! + +Merging from branch A to branch B requires that the A branch +has a tag indicating the previous merger. This tag is called +'merged_from_A_to_B'. After merging, the tag is moved in the +A branch to remember this merger for future merge actions. + +IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE +REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE +MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME). + +Merge all changes in DEVEL since our last merge to main: + +In the working copy of the main trunk: +cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL + +(This will apply the changes between 'merged_from_DEVEL_to_main' +and 'DEVEL' to your work set of files) + +We can now commit the merge result. +cvs commit -R -m "Merged from DEVEL to main." + +If this worked out OK, we now move the tag in the DEVEL branch +to this merge point, so we can use this point for future merges: + +cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip + +4 How to release lwIP +--------------------- + +First, checkout a clean copy of the branch to be released. Tag this set with +tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example). + +Login CVS using pserver authentication, then export a clean copy of the +tagged tree. Export is similar to a checkout, except that the CVS metadata +is not created locally. + +export CVS_RSH=ssh +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_6_3 -d lwip-0.6.3 lwip + +Archive this directory using tar, gzip'd, bzip2'd and zip'd. + +tar czvf lwip-0.6.3.tar.gz lwip-0.6.3 +tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3 +zip -r lwip-0.6.3.zip lwip-0.6.3 + +Now, sign the archives with a detached GPG binary signature as follows: + +gpg -b lwip-0.6.3.tar.gz +gpg -b lwip-0.6.3.tar.bz2 +gpg -b lwip-0.6.3.zip + +Upload these files using anonymous FTP: +ncftp ftp://savannah.gnu.org/incoming/savannah/lwip + +ncftp>mput *0.6.3.* + +Additionally, you may post a news item on Savannah, like this: + +A new 0.6.3 release is now available here: +http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 + +You will have to submit this via the user News interface, then approve +this via the Administrator News interface. \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/snmp_agent.txt b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/snmp_agent.txt new file mode 100644 index 0000000..9b58616 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/snmp_agent.txt @@ -0,0 +1,181 @@ +SNMPv1 agent for lwIP + +Author: Christiaan Simons + +This is a brief introduction how to use and configure the SNMP agent. +Note the agent uses the raw-API UDP interface so you may also want to +read rawapi.txt to gain a better understanding of the SNMP message handling. + +0 Agent Capabilities +==================== + +SNMPv1 per RFC1157 + This is an old(er) standard but is still widely supported. + For SNMPv2c and v3 have a greater complexity and need many + more lines of code. IMHO this breaks the idea of "lightweight IP". + + Note the S in SNMP stands for "Simple". Note that "Simple" is + relative. SNMP is simple compared to the complex ISO network + management protocols CMIP (Common Management Information Protocol) + and CMOT (CMip Over Tcp). + +MIB II per RFC1213 + The standard lwIP stack management information base. + This is a required MIB, so this is always enabled. + When builing lwIP without TCP, the mib-2.tcp group is omitted. + The groups EGP, CMOT and transmission are disabled by default. + + Most mib-2 objects are not writable except: + sysName, sysLocation, sysContact, snmpEnableAuthenTraps. + Writing to or changing the ARP and IP address and route + tables is not possible. + + Note lwIP has a very limited notion of IP routing. It currently + doen't have a route table and doesn't have a notion of the U,G,H flags. + Instead lwIP uses the interface list with only one default interface + acting as a single gateway interface (G) for the default route. + + The agent returns a "virtual table" with the default route 0.0.0.0 + for the default interface and network routes (no H) for each + network interface in the netif_list. + All routes are considered to be up (U). + +Loading additional MIBs + MIBs can only be added in compile-time, not in run-time. + There is no MIB compiler thus additional MIBs must be hand coded. + +Large SNMP message support + The packet decoding and encoding routines are designed + to use pbuf-chains. Larger payloads then the minimum + SNMP requirement of 484 octets are supported if the + PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your + local requirement. + +1 Building the Agent +==================== + +First of all you'll need to add the following define +to your local lwipopts.h: + +#define LWIP_SNMP 1 + +and add the source files in lwip/src/core/snmp +and some snmp headers in lwip/src/include/lwip to your makefile. + +Note you'll might need to adapt you network driver to update +the mib2 variables for your interface. + +2 Running the Agent +=================== + +The following function calls must be made in your program to +actually get the SNMP agent running. + +Before starting the agent you should supply pointers +to non-volatile memory for sysContact, sysLocation, +and snmpEnableAuthenTraps. You can do this by calling + +snmp_set_syscontact() +snmp_set_syslocation() +snmp_set_snmpenableauthentraps() + +Additionally you may want to set + +snmp_set_sysdescr() +snmp_set_sysobjid() (if you have a private MIB) +snmp_set_sysname() + +Also before starting the agent you need to setup +one or more trap destinations using these calls: + +snmp_trap_dst_enable(); +snmp_trap_dst_ip_set(); + +In the lwIP initialisation sequence call snmp_init() just after +the call to udp_init(). + +Exactly every 10 msec the SNMP uptime timestamp must be updated with +snmp_inc_sysuptime(). You should call this from a timer interrupt +or a timer signal handler depending on your runtime environment. + +An alternative way to update the SNMP uptime timestamp is to do a call like +snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to +a lower frequency). Another one is to not call snmp_inc_sysuptime() or +snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. +This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside +snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only +when it's queried (any function which need "sysuptime" have to call +snmp_get_sysuptime). + + +3 Private MIBs +============== + +If want to extend the agent with your own private MIB you'll need to +add the following define to your local lwipopts.h: + +#define SNMP_PRIVATE_MIB 1 + +You must provide the private_mib.h and associated files yourself. +Note we don't have a "MIB compiler" that generates C source from a MIB, +so you're required to do some serious coding if you enable this! + +Note the lwIP enterprise ID (26381) is assigned to the lwIP project, +ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP +MAINTAINERS! + +If you need to create your own private MIB you'll need +to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html + +You can set it by passing a struct snmp_obj_id to the agent +using snmp_set_sysobjid(&my_object_id), just before snmp_init(). + +Note the object identifiers for thes MIB-2 and your private MIB +tree must be kept in sorted ascending (lexicographical) order. +This to ensure correct getnext operation. + +An example for a private MIB is part of the "minimal Unix" project: +contrib/ports/unix/proj/minimal/lwip_prvmib.c + +The next chapter gives a more detailed description of the +MIB-2 tree and the optional private MIB. + +4 The Gory Details +================== + +4.0 Object identifiers and the MIB tree. + +We have three distinct parts for all object identifiers: + +The prefix + .iso.org.dod.internet + +the middle part + .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress + +and the index part + .1.192.168.0.1 + +Objects located above the .internet hierarchy aren't supported. +Currently only the .mgmt sub-tree is available and +when the SNMP_PRIVATE_MIB is enabled the .private tree +becomes available too. + +Object identifiers from incoming requests are checked +for a matching prefix, middle part and index part +or are expanded(*) for GetNext requests with short +or inexisting names in the request. +(* we call this "expansion" but this also +resembles the "auto-completion" operation) + +The middle part is usually located in ROM (const) +to preserve precious RAM on small microcontrollers. +However RAM location is possible for an dynamically +changing private tree. + +The index part is handled by functions which in +turn use dynamically allocated index trees from RAM. +These trees are updated by e.g. the etharp code +when new entries are made or removed form the ARP cache. + +/** @todo more gory details */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/doc/sys_arch.txt b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/sys_arch.txt new file mode 100644 index 0000000..66310a9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/doc/sys_arch.txt @@ -0,0 +1,228 @@ +sys_arch interface for lwIP 0.6++ + +Author: Adam Dunkels + +The operating system emulation layer provides a common interface +between the lwIP code and the underlying operating system kernel. The +general idea is that porting lwIP to new architectures requires only +small changes to a few header files and a new sys_arch +implementation. It is also possible to do a sys_arch implementation +that does not rely on any underlying operating system. + +The sys_arch provides semaphores and mailboxes to lwIP. For the full +lwIP functionality, multiple threads support can be implemented in the +sys_arch, but this is not required for the basic lwIP +functionality. Previous versions of lwIP required the sys_arch to +implement timer scheduling as well but as of lwIP 0.5 this is +implemented in a higher layer. + +In addition to the source file providing the functionality of sys_arch, +the OS emulation layer must provide several header files defining +macros used throughout lwip. The files required and the macros they +must define are listed below the sys_arch description. + +Semaphores can be either counting or binary - lwIP works with both +kinds. Mailboxes are used for message passing and can be implemented +either as a queue which allows multiple messages to be posted to a +mailbox, or as a rendez-vous point where only one message can be +posted at a time. lwIP works with both kinds, but the former type will +be more efficient. A message in a mailbox is just a pointer, nothing +more. + +Semaphores are represented by the type "sys_sem_t" which is typedef'd +in the sys_arch.h file. Mailboxes are equivalently represented by the +type "sys_mbox_t". lwIP does not place any restrictions on how +sys_sem_t or sys_mbox_t are represented internally. + +The following functions must be implemented by the sys_arch: + +- void sys_init(void) + + Is called to initialize the sys_arch layer. + +- sys_sem_t sys_sem_new(u8_t count) + + Creates and returns a new semaphore. The "count" argument specifies + the initial state of the semaphore. + +- void sys_sem_free(sys_sem_t sem) + + Deallocates a semaphore. + +- void sys_sem_signal(sys_sem_t sem) + + Signals a semaphore. + +- u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) + + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). If the "timeout" argument is zero, the thread should be + blocked until the semaphore is signalled. + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. + +- sys_mbox_t sys_mbox_new(int size) + + Creates an empty mailbox for maximum "size" elements. Elements stored + in mailboxes are pointers. You have to define macros "_MBOX_SIZE" + in your lwipopts.h, or ignore this parameter in your implementation + and use a default size. + +- void sys_mbox_free(sys_mbox_t mbox) + + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. + +- void sys_mbox_post(sys_mbox_t mbox, void *msg) + + Posts the "msg" to the mailbox. This function have to block until + the "msg" is really posted. + +- err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one + is full, else, ERR_OK if the "msg" is posted. + +- u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) + + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). If "timeout" is 0, the thread should + be blocked until a message arrives. The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. + +- u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) + + This is similar to sys_arch_mbox_fetch, however if a message is not + present in the mailbox, it immediately returns with the code + SYS_MBOX_EMPTY. On success 0 is returned. + + To allow for efficient implementations, this can be defined as a + function-like macro in sys_arch.h instead of a normal function. For + example, a naive implementation could be: + #define sys_arch_mbox_tryfetch(mbox,msg) \ + sys_arch_mbox_fetch(mbox,msg,1) + although this would introduce unnecessary delays. + +- struct sys_timeouts *sys_arch_timeouts(void) + + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is repressented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single thread sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. + +If threads are supported by the underlying operating system and if +such functionality is needed in lwIP, the following function will have +to be implemented as well: + +- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) + + Starts a new thread named "name" with priority "prio" that will begin its + execution in the function "thread()". The "arg" argument will be passed as an + argument to the thread() function. The stack size to used for this thread is + the "stacksize" parameter. The id of the new thread is returned. Both the id + and the priority are system dependent. + +- sys_prot_t sys_arch_protect(void) + + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. + +- void sys_arch_unprotect(sys_prot_t pval) + + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. + +Note: + +Be carefull with using mem_malloc() in sys_arch. When malloc() refers to +mem_malloc() you can run into a circular function call problem. In mem.c +mem_init() tries to allcate a semaphore using mem_malloc, which of course +can't be performed when sys_arch uses mem_malloc. + +------------------------------------------------------------------------------- +Additional files required for the "OS support" emulation layer: +------------------------------------------------------------------------------- + +cc.h - Architecture environment, some compiler specific, some + environment specific (probably should move env stuff + to sys_arch.h.) + + Typedefs for the types used by lwip - + u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + + Compiler hints for packing lwip's structures - + PACK_STRUCT_FIELD(x) + PACK_STRUCT_STRUCT + PACK_STRUCT_BEGIN + PACK_STRUCT_END + + Platform specific diagnostic output - + LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + Portability defines for printf formatters: + U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + + "lightweight" synchronization mechanisms - + SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. + SYS_ARCH_PROTECT(x) - enter protection mode. + SYS_ARCH_UNPROTECT(x) - leave protection mode. + + If the compiler does not provide memset() this file must include a + definition of it, or include a file which defines it. + + This file must either include a system-local which defines + the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO + to make lwip/arch.h define the codes which are used throughout. + + +perf.h - Architecture specific performance measurement. + Measurement calls made throughout lwip, these can be defined to nothing. + PERF_START - start measuring something. + PERF_STOP(x) - stop measuring something, and record the result. + +sys_arch.h - Tied to sys_arch.c + + Arch dependent types for the following objects: + sys_sem_t, sys_mbox_t, sys_thread_t, + And, optionally: + sys_prot_t + + Defines to set vars of sys_mbox_t and sys_sem_t to NULL. + SYS_MBOX_NULL NULL + SYS_SEM_NULL NULL diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cc.h new file mode 100644 index 0000000..be882d9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cc.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned int u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + +#define U16_F "d" +#define S16_F "d" +#define X16_F "x" +#define U32_F "d" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + +/* define compiler specific symbols */ +#if defined (__ICCARM__) +#if !defined (__IARSTDLIB__) +#define _STRING +#ifndef memcmp +#define memcmp(dst, src, sz) _memcmp(dst, src, sz) +#endif +#ifndef memset +#define memset(dst, val, sz) _memset(dst, val, sz) +#endif +#ifndef memcpy +#define memcpy(dst, src, sz) _memcpy(dst, src, sz) +#endif +#endif // __IARSTDLIB__ + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cpu.h new file mode 100644 index 0000000..a02f86d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/arch/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.c new file mode 100644 index 0000000..a0f38bd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.c @@ -0,0 +1,274 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" + +#include +#include + +#define netifMTU (1500) +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) + + +#ifdef CONFIG_CONCURRENT_MODE +#define IF2NAME0 'r' +#define IF2NAME1 '2' +#endif + +static void arp_timer(void *arg); + + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ + +static void low_level_init(struct netif *netif) +{ + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set netif maximum transfer unit */ + netif->mtu = 1500; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + /* Wlan interface is initialized later */ +} + + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + + + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; + + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + if (sg_len) + rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len); + + return ERR_OK; +} + + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +//static struct pbuf * low_level_input(struct netif *netif){} + + +/** + * This function is the ethernetif_input task, it is processed when a packet + * is ready to be read from the interface. It uses the function low_level_input() + * that should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +//void ethernetif_input( void * pvParameters ) + + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); + +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = "lwip0"; + else if(netif->name[1] == '1') + netif->hostname = "lwip1"; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + + return ERR_OK; +} + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.h new file mode 100644 index 0000000..7a436d2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/ethernetif.h @@ -0,0 +1,23 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" +//----- ------------------------------------------------------------------ +// Ethernet Buffer +//----- ------------------------------------------------------------------ +struct eth_drv_sg { + unsigned int buf; + unsigned int len; +}; + +#define MAX_ETH_DRV_SG 32 +#define MAX_ETH_MSG 1540 + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.c new file mode 100644 index 0000000..1793f87 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.c @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +sys_mbox_t sys_mbox_new(int size) +{ + xQueueHandle mbox; + + ( void ) size; + + mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + + return mbox; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t mbox) +{ + if( uxQueueMessagesWaiting( mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t mbox, void *data) +{ + while ( xQueueSendToBack(mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} + +/*-----------------------------------------------------------------------------------*/ +// Creates and returns a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +sys_sem_t sys_sem_new(u8_t count) +{ + xSemaphoreHandle xSemaphore; + + vSemaphoreCreateBinary( xSemaphore ); + + if( xSemaphore == NULL ) + { + +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + + return SYS_SEM_NULL; // TODO need assert + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(xSemaphore,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return xSemaphore; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake( sem, portMAX_DELAY ) != pdTRUE ){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t sem) +{ + xSemaphoreGive( sem ); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete( sem ); +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts *sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} + +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( const portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/realtek/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cc.h new file mode 100644 index 0000000..3ca260f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cc.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned long u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + + +#define U16_F "hu" +#define S16_F "d" +#define X16_F "hx" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + + + + + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cpu.h new file mode 100644 index 0000000..a02f86d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/arch/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.c new file mode 100644 index 0000000..9c6f99c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.c @@ -0,0 +1,649 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/icmp.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" + +#include "main.h" // for the definition of CONFIG_WLAN + + +#if !CONFIG_WLAN +#include "stm32f2x7_eth.h" +#else +#include +#endif +#include + +#ifdef CONFIG_DONT_CARE_TP +#define netifMTU (576) +#else +#define netifMTU (1500) +#endif +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) +#define FAKE_PING_REPLY 0 + +#if !CONFIG_WLAN +/* Define those to better describe your network interface. */ +#define IFNAME0 's' +#define IFNAME1 't' + +static struct netif *s_pxNetIf = NULL; +xSemaphoreHandle s_xSemaphore = NULL; + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + +static void ethernetif_input( void * pvParameters ); +#endif + +static void arp_timer(void *arg); + + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ + +static void low_level_init(struct netif *netif) +{ + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + +#if !CONFIG_WLAN + /* set netif MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; +#endif + + /* set netif maximum transfer unit */ + netif->mtu = netifMTU; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if !CONFIG_WLAN + s_pxNetIf =netif; + + /* create binary semaphore used for informing ethernetif of frame reception */ + if (s_xSemaphore == NULL) + { + s_xSemaphore= xSemaphoreCreateCounting(20,0); + } + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable Ethernet Rx interrrupt */ + { + uint32_t i; + for(i=0; itot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_arp = (struct etharp_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_arp = (struct etharp_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = fake_src_mac; + q_arp->opcode = htons(ARP_REPLY); + q_arp->shwaddr = fake_src_mac; + q_arp->sipaddr = p_arp->dipaddr; + q_arp->dhwaddr = p_eth->src; + q_arp->dipaddr = p_arp->sipaddr; + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_arp_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake arp reply \n\r"); +} + +void fake_echo_reply(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q, *tq, *tp; + int q_len, p_len; + struct eth_hdr *p_eth, *q_eth; + struct ip_hdr *p_ip, *q_ip; + struct icmp_echo_hdr *p_echo, *q_echo; + + // Allocate buffer to store received packet + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_ip = (struct ip_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_ip = (struct ip_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + p_echo = (struct icmp_echo_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + q_echo = (struct icmp_echo_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = p_eth->dest; + q_ip->src.addr = p_ip->dest.addr; + q_ip->dest.addr = p_ip->src.addr; + q_ip->_chksum = 0; + q_ip->_chksum = inet_chksum(q_ip, sizeof(struct ip_hdr)); + q_echo->type = ICMP_ER; + q_echo->code = 0; + q_echo->chksum = 0; + q_echo->chksum = inet_chksum(q_echo, q->tot_len - sizeof(struct eth_hdr) - sizeof(struct ip_hdr)); + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_echo_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake echo reply \n\r"); +} +#endif // #if FAKE_PING_REPLY + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ +#if !CONFIG_WLAN + static xSemaphoreHandle xTxSemaphore = NULL; + struct pbuf *q; + uint32_t l = 0; + u8 *buffer ; + + if (xTxSemaphore == NULL) + { + vSemaphoreCreateBinary (xTxSemaphore); + } + + if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME)) + { + buffer = (u8 *)(DMATxDescToSet->Buffer1Addr); + for(q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)&buffer[l], q->payload, q->len); + l = l + q->len; + } + ETH_Prepare_Transmit_Descriptors(l); + xSemaphoreGive(xTxSemaphore); + } +#else + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; + + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + +#if FAKE_PING_REPLY + { + char *header = p->payload; + if(header[12] == 0x08 && header[13] == 0x06) + { // arp packet + if(header[21] == 0x01) + { // arp request packet + printf("\n\rfake_ping: arp request packet."); + if(0) + { + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_arp_reply(netif, p); + return ERR_OK; + } + }else if(header[12] == 0x08 && header[13] == 0x00) + { // ip packet + if(header[15] == 0x00 && header[23] == 0x01) + { // icmp packet + printf("\n\rfake_ping: icmp packet."); + if(0){ + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_echo_reply(netif, p); + return ERR_OK; + } + } + } +#endif // #if FAKE_PING_REPLY + if (sg_len) + rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len); +#endif // #if !CONFIG_WLAN + + return ERR_OK; +} + + +#if !CONFIG_WLAN +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + u16_t len; + uint32_t l=0,i =0; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxNextDesc; + + p = NULL; + + /* Get received frame */ + frame = ETH_Get_Received_Frame_interrupt(); + + /* check that frame has no error */ + if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) + { + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + /* Copy received frame from ethernet driver buffer to stack buffer */ + if (p != NULL) + { + for (q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len); + l = l + q->len; + } + } + } + + /* Release descriptors to DMA */ + /* Check if received frame with multiple DMA buffer segments */ + if (DMA_RX_FRAME_infos->Seg_Count > 1) + { + DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc; + } + else + { + DMARxNextDesc = frame.descriptor; + } + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxNextDesc->Status = ETH_DMARxDesc_OWN; + DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + + +/** + * This function is the ethernetif_input task, it is processed when a packet + * is ready to be read from the interface. It uses the function low_level_input() + * that should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void ethernetif_input( void * pvParameters ) +{ + struct pbuf *p; + + for( ;; ) + { + if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE) + { + p = low_level_input( s_pxNetIf ); + if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) + { + pbuf_free(p); + p=NULL; + } + } + } +} +#endif + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ +#if CONFIG_WLAN + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); +#endif +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if !CONFIG_WLAN + /* ethernet */ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#else + /* wlan interface*/ +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = "lwip0"; + else if(netif->name[1] == '1') + netif->hostname = "lwip1"; +#endif /* LWIP_NETIF_HOSTNAME */ + +#endif // WLAN + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + + return ERR_OK; +} + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.h new file mode 100644 index 0000000..93139d1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/ethernetif.h @@ -0,0 +1,13 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.c new file mode 100644 index 0000000..c2792a8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.c @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +sys_mbox_t sys_mbox_new(int size) +{ + xQueueHandle mbox; + + ( void ) size; + + mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + + return mbox; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t mbox) +{ + if( uxQueueMessagesWaiting( mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t mbox, void *data) +{ + while ( xQueueSendToBack(mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} + +/*-----------------------------------------------------------------------------------*/ +// Creates and returns a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +sys_sem_t sys_sem_new(u8_t count) +{ + xSemaphoreHandle xSemaphore; + + vSemaphoreCreateBinary( xSemaphore ); + + if( xSemaphore == NULL ) + { + +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + + return SYS_SEM_NULL; // TODO need assert + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(xSemaphore,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return xSemaphore; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake( sem, portMAX_DELAY ) != pdTRUE ){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t sem) +{ + xSemaphoreGive( sem ); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete( sem ); +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts *sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} + +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( char const * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.c new file mode 100644 index 0000000..5100fb2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.c @@ -0,0 +1,304 @@ +/** + * @file + * Ethernet Interface for standalone applications (without RTOS) - works only for + * ethernet polling mode (polling for ethernet frame reception) + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/mem.h" +#include "netif/etharp.h" +#include "ethernetif.h" +#include "stm32f2x7_eth.h" +#include "main.h" +#include + +/* Network interface name */ +#define IFNAME0 's' +#define IFNAME1 't' + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Driver Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Driver Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + + + + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void low_level_init(struct netif *netif) +{ +#ifdef CHECKSUM_BY_HARDWARE + int i; +#endif + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ + for(i=0; iBuffer1Addr); + + /* copy frame from pbufs to driver buffers */ + for(q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)&buffer[framelength], q->payload, q->len); + framelength = framelength + q->len; + } + + /* Note: padding and CRC for transmitted frame + are automatically inserted by DMA */ + + /* Prepare transmit descriptors to give to DMA*/ + ETH_Prepare_Transmit_Descriptors(framelength); + + return ERR_OK; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + u16_t len; + int l =0; + FrameTypeDef frame; + u8 *buffer; + uint32_t i=0; + __IO ETH_DMADESCTypeDef *DMARxNextDesc; + + + p = NULL; + + /* get received frame */ + frame = ETH_Get_Received_Frame(); + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + /* copy received frame to pbuf chain */ + if (p != NULL) + { + for (q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len); + l = l + q->len; + } + } + + /* Release descriptors to DMA */ + /* Check if frame with multiple DMA buffer segments */ + if (DMA_RX_FRAME_infos->Seg_Count > 1) + { + DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc; + } + else + { + DMARxNextDesc = frame.descriptor; + } + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxNextDesc->Status = ETH_DMARxDesc_OWN; + DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +err_t ethernetif_input(struct netif *netif) +{ + err_t err; + struct pbuf *p; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + + /* no packet could be read, silently ignore this */ + if (p == NULL) return ERR_MEM; + + /* entry point to the LwIP stack */ + err = netif->input(p, netif); + + if (err != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + return err; +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.h new file mode 100644 index 0000000..9ff1408 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/port/stm32f2x7/standalone/ethernetif.h @@ -0,0 +1,11 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +err_t ethernetif_init(struct netif *netif); +err_t ethernetif_input(struct netif *netif); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_lib.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_lib.c new file mode 100644 index 0000000..8947902 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_lib.c @@ -0,0 +1,568 @@ +/* + * @file + * Sequential API External module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* This is the part of the API that is linked with + the application */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" + +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" + +#include + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is also created. + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) +{ + struct netconn *conn; + struct api_msg msg; + + conn = netconn_alloc(t, callback); + if (conn != NULL ) { + msg.function = do_newconn; + msg.msg.msg.n.proto = proto; + msg.msg.conn = conn; + TCPIP_APIMSG(&msg); + + if (conn->err != ERR_OK) { + LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); + LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL); + LWIP_ASSERT("conn has no recvmbox", conn->recvmbox != SYS_MBOX_NULL); + LWIP_ASSERT("conn->acceptmbox shouldn't exist", conn->acceptmbox == SYS_MBOX_NULL); + sys_sem_free(conn->op_completed); + sys_mbox_free(conn->recvmbox); + memp_free(MEMP_NETCONN, conn); + return NULL; + } + } + return conn; +} + +/** + * Close a netconn 'connection' and free its resources. + * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate + * after this returns. + * + * @param conn the netconn to delete + * @return ERR_OK if the connection was deleted + */ +err_t +netconn_delete(struct netconn *conn) +{ + struct api_msg msg; + + /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ + if (conn == NULL) { + return ERR_OK; + } + + msg.function = do_delconn; + msg.msg.conn = conn; + tcpip_apimsg(&msg); + + conn->pcb.tcp = NULL; + netconn_free(conn); + + return ERR_OK; +} + +/** + * Get the local or remote IP address and port of a netconn. + * For RAW netconns, this returns the protocol instead of a port! + * + * @param conn the netconn to query + * @param addr a pointer to which to save the IP address + * @param port a pointer to which to save the port (or protocol for RAW) + * @param local 1 to get the local IP address, 0 to get the remote one + * @return ERR_CONN for invalid connections + * ERR_OK if the information was retrieved + */ +err_t +netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); + + msg.function = do_getaddr; + msg.msg.conn = conn; + msg.msg.msg.ad.ipaddr = addr; + msg.msg.msg.ad.port = port; + msg.msg.msg.ad.local = local; + TCPIP_APIMSG(&msg); + + return conn->err; +} + +/** + * Bind a netconn to a specific local IP address and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY + * to bind to all addresses) + * @param port the local port to bind the netconn to (not used for RAW) + * @return ERR_OK if bound, any other err_t on failure + */ +err_t +netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_bind; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + TCPIP_APIMSG(&msg); + return conn->err; +} + +/** + * Connect a netconn to a specific remote IP address and port. + * + * @param conn the netconn to connect + * @param addr the remote IP address to connect to + * @param port the remote port to connect to (no used for RAW) + * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise + */ +err_t +netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_connect; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + /* This is the only function which need to not block tcpip_thread */ + tcpip_apimsg(&msg); + return conn->err; +} + +/** + * Disconnect a netconn from its current peer (only valid for UDP netconns). + * + * @param conn the netconn to disconnect + * @return TODO: return value is not set here... + */ +err_t +netconn_disconnect(struct netconn *conn) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_disconnect; + msg.msg.conn = conn; + TCPIP_APIMSG(&msg); + return conn->err; +} + +/** + * Set a TCP netconn into listen mode + * + * @param conn the tcp netconn to set to listen mode + * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 + * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns + * don't return any error (yet?)) + */ +err_t +netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) +{ + struct api_msg msg; + + /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ + LWIP_UNUSED_ARG(backlog); + + LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_listen; + msg.msg.conn = conn; +#if TCP_LISTEN_BACKLOG + msg.msg.msg.lb.backlog = backlog; +#endif /* TCP_LISTEN_BACKLOG */ + TCPIP_APIMSG(&msg); + return conn->err; +} + +/** + * Accept a new connection on a TCP listening netconn. + * + * @param conn the TCP listen netconn + * @return the newly accepted netconn or NULL on timeout + */ +struct netconn * +netconn_accept(struct netconn *conn) +{ + struct netconn *newconn; + + LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return NULL;); + LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return NULL;); + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + newconn = NULL; + } else +#else + sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + +#if TCP_LISTEN_BACKLOG + if (newconn != NULL) { + /* Let the stack know that we have accepted the connection. */ + struct api_msg msg; + msg.function = do_recv; + msg.msg.conn = conn; + TCPIP_APIMSG(&msg); + } +#endif /* TCP_LISTEN_BACKLOG */ + } + + return newconn; +} + +/** + * Receive data (in form of a netbuf containing a packet buffer) from a netconn + * + * @param conn the netconn from which to receive data + * @return a new netbuf containing received data or NULL on memory error or timeout + */ +struct netbuf * +netconn_recv(struct netconn *conn) +{ + struct api_msg msg; + struct netbuf *buf = NULL; + struct pbuf *p; + u16_t len; + + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return NULL;); + + if (conn->recvmbox == SYS_MBOX_NULL) { + /* @todo: should calling netconn_recv on a TCP listen conn be fatal (ERR_CONN)?? */ + /* TCP listen conns don't have a recvmbox! */ + conn->err = ERR_CONN; + return NULL; + } + + if (ERR_IS_FATAL(conn->err)) { + return NULL; + } + + if (conn->type == NETCONN_TCP) { +#if LWIP_TCP + if (conn->state == NETCONN_LISTEN) { + /* @todo: should calling netconn_recv on a TCP listen conn be fatal?? */ + conn->err = ERR_CONN; + return NULL; + } + + buf = memp_malloc(MEMP_NETBUF); + + if (buf == NULL) { + conn->err = ERR_MEM; + return NULL; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) { + memp_free(MEMP_NETBUF, buf); + conn->err = ERR_TIMEOUT; + return NULL; + } +#else + sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + + if (p != NULL) { + len = p->tot_len; + SYS_ARCH_DEC(conn->recv_avail, len); + } else { + len = 0; + } + + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); + + /* If we are closed, we indicate that we no longer wish to use the socket */ + if (p == NULL) { + memp_free(MEMP_NETBUF, buf); + /* Avoid to lose any previous error code */ + if (conn->err == ERR_OK) { + conn->err = ERR_CLSD; + } + return NULL; + } + + buf->p = p; + buf->ptr = p; + buf->port = 0; + buf->addr = NULL; + + /* Let the stack know that we have taken the data. */ + msg.function = do_recv; + msg.msg.conn = conn; + if (buf != NULL) { + msg.msg.msg.r.len = buf->p->tot_len; + } else { + msg.msg.msg.r.len = 1; + } + TCPIP_APIMSG(&msg); +#endif /* LWIP_TCP */ + } else { +#if (LWIP_UDP || LWIP_RAW) +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) { + buf = NULL; + } +#else + sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + if (buf!=NULL) { + SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len); + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len); + } +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err)); + + return buf; +} + +/** + * Send data (in form of a netbuf) to a specific remote IP address and port. + * Only to be used for UDP and RAW netconns (not TCP). + * + * @param conn the netconn over which to send data + * @param buf a netbuf containing the data to send + * @param addr the remote IP address to which to send the data + * @param port the remote port to which to send the data + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_sendto(struct netconn *conn, struct netbuf *buf, struct ip_addr *addr, u16_t port) +{ + if (buf != NULL) { + buf->addr = addr; + buf->port = port; + return netconn_send(conn, buf); + } + return ERR_VAL; +} + +/** + * Send data over a UDP or RAW netconn (that is already connected). + * + * @param conn the UDP or RAW netconn over which to send data + * @param buf a netbuf containing the data to send + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_send(struct netconn *conn, struct netbuf *buf) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); + msg.function = do_send; + msg.msg.conn = conn; + msg.msg.msg.b = buf; + TCPIP_APIMSG(&msg); + return conn->err; +} + +/** + * Send data over a TCP netconn. + * + * @param conn the TCP netconn over which to send data + * @param dataptr pointer to the application buffer that contains the data to send + * @param size size of the application data to send + * @param apiflags combination of following flags : + * - NETCONN_COPY (0x01) data will be copied into memory belonging to the stack + * - NETCONN_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;); + + msg.function = do_write; + msg.msg.conn = conn; + msg.msg.msg.w.dataptr = dataptr; + msg.msg.msg.w.apiflags = apiflags; + msg.msg.msg.w.len = size; + /* For locking the core: this _can_ be delayed on low memory/low send buffer, + but if it is, this is done inside api_msg.c:do_write(), so we can use the + non-blocking version here. */ + TCPIP_APIMSG(&msg); + return conn->err; +} + +/** + * Close a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_close(struct netconn *conn) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_close; + msg.msg.conn = conn; + tcpip_apimsg(&msg); + return conn->err; +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * + * @param conn the UDP netconn for which to change multicast addresses + * @param multiaddr IP address of the multicast group to join or leave + * @param interface the IP address of the network interface on which to send + * the igmp message + * @param join_or_leave flag whether to send a join- or leave-message + * @return ERR_OK if the action was taken, any err_t on error + */ +err_t +netconn_join_leave_group(struct netconn *conn, + struct ip_addr *multiaddr, + struct ip_addr *interface, + enum netconn_igmp join_or_leave) +{ + struct api_msg msg; + + LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_join_leave_group; + msg.msg.conn = conn; + msg.msg.msg.jl.multiaddr = multiaddr; + msg.msg.msg.jl.interface = interface; + msg.msg.msg.jl.join_or_leave = join_or_leave; + TCPIP_APIMSG(&msg); + return conn->err; +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Execute a DNS query, only one IP address is returned + * + * @param name a string representation of the DNS host name to query + * @param addr a preallocated struct ip_addr where to store the resolved IP address + * @return ERR_OK: resolving succeeded + * ERR_MEM: memory error, try again later + * ERR_ARG: dns client not initialized or invalid hostname + * ERR_VAL: dns server response was invalid + */ +err_t +netconn_gethostbyname(const char *name, struct ip_addr *addr) +{ + struct dns_api_msg msg; + err_t err; + sys_sem_t sem; + + LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); + + sem = sys_sem_new(0); + if (sem == SYS_SEM_NULL) { + return ERR_MEM; + } + + msg.name = name; + msg.addr = addr; + msg.err = &err; + msg.sem = sem; + + tcpip_callback(do_gethostbyname, &msg); + sys_sem_wait(sem); + sys_sem_free(sem); + + return err; +} +#endif /* LWIP_DNS*/ + +err_t netconn_abort(struct netconn *conn) +{ + if (conn->acceptmbox != SYS_MBOX_NULL) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + sys_mbox_post(conn->acceptmbox, NULL); + } + return ERR_OK; +} + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_msg.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_msg.c new file mode 100644 index 0000000..8920139 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/api_msg.c @@ -0,0 +1,1243 @@ +/* + * @file + * Sequential API Internal module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" + +#include "lwip/ip.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" + +#include "lwip/memp.h" +#include "lwip/tcpip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" + +#include + +/* forward declarations */ +#if LWIP_TCP +static err_t do_writemore(struct netconn *conn); +static void do_close_internal(struct netconn *conn); +#endif + +#if LWIP_RAW +/** + * Receive callback function for RAW netconns. + * Doesn't 'eat' the packet, only references it and sends it to + * conn->recvmbox + * + * @see raw.h (struct raw_pcb.recv) for parameters and return value + */ +static u8_t +recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + struct ip_addr *addr) +{ + struct pbuf *q; + struct netbuf *buf; + struct netconn *conn; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + LWIP_UNUSED_ARG(addr); + conn = arg; + +#if LWIP_SO_RCVBUF + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) && + ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ + if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) { +#endif /* LWIP_SO_RCVBUF */ + /* copy the whole packet into new pbufs */ + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(q != NULL) { + if (pbuf_copy(q, p) != ERR_OK) { + pbuf_free(q); + q = NULL; + } + } + + if(q != NULL) { + buf = memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(q); + return 0; + } + + buf->p = q; + buf->ptr = q; + buf->addr = &(((struct ip_hdr*)(q->payload))->src); + buf->port = pcb->protocol; + + if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return 0; + } else { + SYS_ARCH_INC(conn->recv_avail, q->tot_len); + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len); + } + } + } + + return 0; /* do not eat the packet */ +} +#endif /* LWIP_RAW*/ + +#if LWIP_UDP +/** + * Receive callback function for UDP netconns. + * Posts the packet to conn->recvmbox or deletes it on memory error. + * + * @see udp.h (struct udp_pcb.recv) for parameters + */ +static void +recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + struct ip_addr *addr, u16_t port) +{ + struct netbuf *buf; + struct netconn *conn; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ + LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_udp must have an argument", arg != NULL); + conn = arg; + LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); + +#if LWIP_SO_RCVBUF + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) || + ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ + if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) { +#endif /* LWIP_SO_RCVBUF */ + pbuf_free(p); + return; + } + + buf = memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); + return; + } else { + buf->p = p; + buf->ptr = p; + buf->addr = addr; + buf->port = port; +#if LWIP_NETBUF_RECVINFO + { + const struct ip_hdr* iphdr = ip_current_header(); + /* get the UDP header - always in the first pbuf, ensured by udp_input */ + const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr)); + buf->toaddr = (struct ip_addr*)&iphdr->dest; + buf->toport = udphdr->dest; + } +#endif /* LWIP_NETBUF_RECVINFO */ + } + + if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; + } else { + SYS_ARCH_INC(conn->recv_avail, p->tot_len); + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len); + } +} +#endif /* LWIP_UDP */ + +#if LWIP_TCP +/** + * Receive callback function for TCP netconns. + * Posts the packet to conn->recvmbox, but doesn't delete it on errors. + * + * @see tcp.h (struct tcp_pcb.recv) for parameters and return value + */ +static err_t +recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct netconn *conn; + u16_t len; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); + conn = arg; + LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); + + if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) { + return ERR_VAL; + } + + conn->err = err; + if (p != NULL) { + len = p->tot_len; + SYS_ARCH_INC(conn->recv_avail, len); + } else { + len = 0; + } + + if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) { + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + + return ERR_OK; +} + +/** + * Poll callback function for TCP netconns. + * Wakes up an application thread that waits for a connection to close + * or data to be sent. The application thread then takes the + * appropriate action to go on. + * + * Signals the conn->sem. + * netconn_close waits for conn->sem if closing failed. + * + * @see tcp.h (struct tcp_pcb.poll) for parameters and return value + */ +static err_t +poll_tcp(void *arg, struct tcp_pcb *pcb) +{ + struct netconn *conn = arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + + return ERR_OK; +} + +/** + * Sent callback function for TCP netconns. + * Signals the conn->sem and calls API_EVENT. + * netconn_write waits for conn->sem if send buffer is low. + * + * @see tcp.h (struct tcp_pcb.sent) for parameters and return value + */ +static err_t +sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct netconn *conn = arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + + if (conn) { + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) { + API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); + } + } + + return ERR_OK; +} + +/** + * Error callback function for TCP netconns. + * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. + * The application thread has then to decide what to do. + * + * @see tcp.h (struct tcp_pcb.err) for parameters + */ +static void +err_tcp(void *arg, err_t err) +{ + struct netconn *conn; + + conn = arg; + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + conn->pcb.tcp = NULL; + + conn->err = err; + if (conn->recvmbox != SYS_MBOX_NULL) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + sys_mbox_post(conn->recvmbox, NULL); + } + if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) { + conn->state = NETCONN_NONE; + sys_sem_signal(conn->op_completed); + } + if (conn->acceptmbox != SYS_MBOX_NULL) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + sys_mbox_post(conn->acceptmbox, NULL); + } + if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) { + /* calling do_writemore/do_close_internal is not necessary + since the pcb has already been deleted! */ + conn->state = NETCONN_NONE; + /* wake up the waiting task */ + sys_sem_signal(conn->op_completed); + } +} + +/** + * Setup a tcp_pcb with the correct callback function pointers + * and their arguments. + * + * @param conn the TCP netconn to setup + */ +static void +setup_tcp(struct netconn *conn) +{ + struct tcp_pcb *pcb; + + pcb = conn->pcb.tcp; + tcp_arg(pcb, conn); + tcp_recv(pcb, recv_tcp); + tcp_sent(pcb, sent_tcp); + tcp_poll(pcb, poll_tcp, 4); + tcp_err(pcb, err_tcp); +} + +/** + * Accept callback function for TCP netconns. + * Allocates a new netconn and posts that to conn->acceptmbox. + * + * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value + */ +static err_t +accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + struct netconn *newconn; + struct netconn *conn; + +#if API_MSG_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(newpcb->state); +#endif /* TCP_DEBUG */ +#endif /* API_MSG_DEBUG */ + conn = (struct netconn *)arg; + + LWIP_ERROR("accept_function: invalid conn->acceptmbox", + conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;); + + /* We have to set the callback here even though + * the new socket is unknown. conn->socket is marked as -1. */ + newconn = netconn_alloc(conn->type, conn->callback); + if (newconn == NULL) { + return ERR_MEM; + } + newconn->pcb.tcp = newpcb; + setup_tcp(newconn); + newconn->err = err; + + if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) { + /* When returning != ERR_OK, the connection is aborted in tcp_process(), + so do nothing here! */ + newconn->pcb.tcp = NULL; + netconn_free(newconn); + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Create a new pcb of a specific type. + * Called from do_newconn(). + * + * @param msg the api_msg_msg describing the connection type + * @return msg->conn->err, but the return value is currently ignored + */ +static err_t +pcb_new(struct api_msg_msg *msg) +{ + msg->conn->err = ERR_OK; + + LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); + + /* Allocate a PCB for this connection */ + switch(NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->pcb.raw = raw_new(msg->msg.n.proto); + if(msg->conn->pcb.raw == NULL) { + msg->conn->err = ERR_MEM; + break; + } + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp = udp_new(); + if(msg->conn->pcb.udp == NULL) { + msg->conn->err = ERR_MEM; + break; + } +#if LWIP_UDPLITE + if (msg->conn->type==NETCONN_UDPLITE) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } +#endif /* LWIP_UDPLITE */ + if (msg->conn->type==NETCONN_UDPNOCHKSUM) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->pcb.tcp = tcp_new(); + if(msg->conn->pcb.tcp == NULL) { + msg->conn->err = ERR_MEM; + break; + } + setup_tcp(msg->conn); + break; +#endif /* LWIP_TCP */ + default: + /* Unsupported netconn type, e.g. protocol disabled */ + msg->conn->err = ERR_VAL; + break; + } + + return msg->conn->err; +} + +/** + * Create a new pcb of a specific type inside a netconn. + * Called from netconn_new_with_proto_and_callback. + * + * @param msg the api_msg_msg describing the connection type + */ +void +do_newconn(struct api_msg_msg *msg) +{ + if(msg->conn->pcb.tcp == NULL) { + pcb_new(msg); + } + /* Else? This "new" connection already has a PCB allocated. */ + /* Is this an error condition? Should it be deleted? */ + /* We currently just are happy and return. */ + + TCPIP_APIMSG_ACK(msg); +} + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is NOT created! + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_alloc(enum netconn_type t, netconn_callback callback) +{ + struct netconn *conn; + int size = 0; + + conn = memp_malloc(MEMP_NETCONN); + if (conn == NULL) { + return NULL; + } + + conn->err = ERR_OK; + conn->type = t; + conn->pcb.tcp = NULL; + +#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \ + (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE) + size = DEFAULT_RAW_RECVMBOX_SIZE; +#else + switch(NETCONNTYPE_GROUP(t)) { +#if LWIP_RAW + case NETCONN_RAW: + size = DEFAULT_RAW_RECVMBOX_SIZE; + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + size = DEFAULT_UDP_RECVMBOX_SIZE; + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + size = DEFAULT_TCP_RECVMBOX_SIZE; + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); + break; + } +#endif + + if ((conn->op_completed = sys_sem_new(0)) == SYS_SEM_NULL) { + memp_free(MEMP_NETCONN, conn); + return NULL; + } + if ((conn->recvmbox = sys_mbox_new(size)) == SYS_MBOX_NULL) { + sys_sem_free(conn->op_completed); + memp_free(MEMP_NETCONN, conn); + return NULL; + } + + conn->acceptmbox = SYS_MBOX_NULL; + conn->state = NETCONN_NONE; + /* initialize socket to -1 since 0 is a valid socket */ + conn->socket = -1; + conn->callback = callback; + conn->recv_avail = 0; +#if LWIP_TCP + conn->write_msg = NULL; + conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + conn->write_delayed = 0; +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_TCP */ +#if LWIP_SO_RCVTIMEO + conn->recv_timeout = 0; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; +#endif /* LWIP_SO_RCVBUF */ + return conn; +} + +/** + * Delete a netconn and all its resources. + * The pcb is NOT freed (since we might not be in the right thread context do this). + * + * @param conn the netconn to free + */ +void +netconn_free(struct netconn *conn) +{ + void *mem; + LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); + + /* Drain the recvmbox. */ + if (conn->recvmbox != SYS_MBOX_NULL) { + while (sys_mbox_tryfetch(conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { + if (conn->type == NETCONN_TCP) { + if(mem != NULL) { + pbuf_free((struct pbuf *)mem); + } + } else { + netbuf_delete((struct netbuf *)mem); + } + } + sys_mbox_free(conn->recvmbox); + conn->recvmbox = SYS_MBOX_NULL; + } + + /* Drain the acceptmbox. */ + if (conn->acceptmbox != SYS_MBOX_NULL) { + while (sys_mbox_tryfetch(conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { + netconn_delete((struct netconn *)mem); + } + sys_mbox_free(conn->acceptmbox); + conn->acceptmbox = SYS_MBOX_NULL; + } + + sys_sem_free(conn->op_completed); + conn->op_completed = SYS_SEM_NULL; + + memp_free(MEMP_NETCONN, conn); +} + +#if LWIP_TCP +/** + * Internal helper function to close a TCP netconn: since this sometimes + * doesn't work at the first attempt, this function is called from multiple + * places. + * + * @param conn the TCP netconn to close + */ +static void +do_close_internal(struct netconn *conn) +{ + err_t err; + + LWIP_ASSERT("invalid conn", (conn != NULL)); + LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP)); + LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); + + /* Set back some callback pointers */ + tcp_arg(conn->pcb.tcp, NULL); + if (conn->pcb.tcp->state == LISTEN) { + tcp_accept(conn->pcb.tcp, NULL); + } else { + tcp_recv(conn->pcb.tcp, NULL); + tcp_accept(conn->pcb.tcp, NULL); + /* some callbacks have to be reset if tcp_close is not successful */ + tcp_sent(conn->pcb.tcp, NULL); + tcp_poll(conn->pcb.tcp, NULL, 4); + tcp_err(conn->pcb.tcp, NULL); + } + /* Try to close the connection */ + err = tcp_close(conn->pcb.tcp); + if (err == ERR_OK) { + /* Closing succeeded */ + conn->state = NETCONN_NONE; + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + conn->err = ERR_OK; + /* Trigger select() in socket layer. This send should something else so the + errorfd is set, not the read and write fd! */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + /* wake up the application task */ + sys_sem_signal(conn->op_completed); + } else { + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); + tcp_sent(conn->pcb.tcp, sent_tcp); + tcp_poll(conn->pcb.tcp, poll_tcp, 4); + tcp_err(conn->pcb.tcp, err_tcp); + tcp_arg(conn->pcb.tcp, conn); + } + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ +} +#endif /* LWIP_TCP */ + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_delconn(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + raw_remove(msg->conn->pcb.raw); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp->recv_arg = NULL; + udp_remove(msg->conn->pcb.udp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->state = NETCONN_CLOSE; + do_close_internal(msg->conn); + /* API_EVENT is called inside do_close_internal, before releasing + the application thread, so we can return at this point! */ + return; +#endif /* LWIP_TCP */ + default: + break; + } + } + /* tcp netconns don't come here! */ + + /* Trigger select() in socket layer. This send should something else so the + errorfd is set, not the read and write fd! */ + API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); + + if (msg->conn->op_completed != SYS_SEM_NULL) { + sys_sem_signal(msg->conn->op_completed); + } +} + +/** + * Bind a pcb contained in a netconn + * Called from netconn_bind. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to bind to + */ +void +do_bind(struct api_msg_msg *msg) +{ + if (!ERR_IS_FATAL(msg->conn->err)) { + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_TCP */ + default: + break; + } + } else { + /* msg->conn->pcb is NULL */ + msg->conn->err = ERR_VAL; + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * TCP callback function if a connection (opened by tcp_connect/do_connect) has + * been established (or reset by the remote host). + * + * @see tcp.h (struct tcp_pcb.connected) for parameters and return values + */ +static err_t +do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct netconn *conn; + + LWIP_UNUSED_ARG(pcb); + + conn = arg; + + if (conn == NULL) { + return ERR_VAL; + } + + conn->err = err; + if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) { + setup_tcp(conn); + } + conn->state = NETCONN_NONE; + sys_sem_signal(conn->op_completed); + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Connect a pcb contained inside a netconn + * Called from netconn_connect. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to connect to + */ +void +do_connect(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.tcp == NULL) { + sys_sem_signal(msg->conn->op_completed); + return; + } + + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + sys_sem_signal(msg->conn->op_completed); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + sys_sem_signal(msg->conn->op_completed); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->state = NETCONN_CONNECT; + setup_tcp(msg->conn); + msg->conn->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port, + do_connected); + /* sys_sem_signal() is called from do_connected (or err_tcp()), + * when the connection is established! */ + break; +#endif /* LWIP_TCP */ + default: + LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL; + sys_sem_signal(msg->conn->op_completed); }while(0)); + break; + } +} + +/** + * Connect a pcb contained inside a netconn + * Only used for UDP netconns. + * Called from netconn_disconnect. + * + * @param msg the api_msg_msg pointing to the connection to disconnect + */ +void +do_disconnect(struct api_msg_msg *msg) +{ +#if LWIP_UDP + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + udp_disconnect(msg->conn->pcb.udp); + } +#endif /* LWIP_UDP */ + TCPIP_APIMSG_ACK(msg); +} + +/** + * Set a TCP pcb contained in a netconn into listen mode + * Called from netconn_listen. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_listen(struct api_msg_msg *msg) +{ +#if LWIP_TCP + if (!ERR_IS_FATAL(msg->conn->err)) { + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { + if (msg->conn->pcb.tcp->state == CLOSED) { +#if TCP_LISTEN_BACKLOG + struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + if (lpcb == NULL) { + msg->conn->err = ERR_MEM; + } else { + /* delete the recvmbox and allocate the acceptmbox */ + if (msg->conn->recvmbox != SYS_MBOX_NULL) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(msg->conn->recvmbox); + msg->conn->recvmbox = SYS_MBOX_NULL; + } + if (msg->conn->acceptmbox == SYS_MBOX_NULL) { + if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) { + msg->conn->err = ERR_MEM; + } + } + if (msg->conn->err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } + } + } else { + msg->conn->err = ERR_CONN; + } + } + } + } +#endif /* LWIP_TCP */ + TCPIP_APIMSG_ACK(msg); +} + +/** + * Send some data on a RAW or UDP pcb contained in a netconn + * Called from netconn_send + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_send(struct api_msg_msg *msg) +{ + if (!ERR_IS_FATAL(msg->conn->err)) { + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (msg->msg.b->addr == NULL) { + msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); + } else { + msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr); + } + break; +#endif +#if LWIP_UDP + case NETCONN_UDP: + if (msg->msg.b->addr == NULL) { + msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); + } else { + msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port); + } + break; +#endif /* LWIP_UDP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Indicate data has been received from a TCP pcb contained in a netconn + * Called from netconn_recv + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_recv(struct api_msg_msg *msg) +{ +#if LWIP_TCP + if (!ERR_IS_FATAL(msg->conn->err)) { + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { +#if TCP_LISTEN_BACKLOG + if (msg->conn->pcb.tcp->state == LISTEN) { + tcp_accepted(msg->conn->pcb.tcp); + } else +#endif /* TCP_LISTEN_BACKLOG */ + { + tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len); + } + } + } + } +#endif /* LWIP_TCP */ + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ +static err_t +do_writemore(struct netconn *conn) +{ + err_t err; + void *dataptr; + u16_t len, available; + u8_t write_finished = 0; + size_t diff; + + LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); + + dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset; + diff = conn->write_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; +#if LWIP_TCPIP_CORE_LOCKING + conn->write_delayed = 1; +#endif + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; +#if LWIP_TCPIP_CORE_LOCKING + conn->write_delayed = 1; +#endif + } + + err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags); + LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len)); + if (err == ERR_OK) { + conn->write_offset += len; + if (conn->write_offset == conn->write_msg->msg.w.len) { + /* everything was written */ + write_finished = 1; + conn->write_msg = NULL; + conn->write_offset = 0; + /* API_EVENT might call tcp_tmr, so reset conn->state now */ + conn->state = NETCONN_NONE; + } + err = tcp_output_nagle(conn->pcb.tcp); + conn->err = err; + if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) { + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + } + } else if (err == ERR_MEM) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called + we do NOT return to the application thread, since ERR_MEM is + only a temporary error! */ + + /* tcp_enqueue returned ERR_MEM, try tcp_output anyway */ + err = tcp_output(conn->pcb.tcp); + +#if LWIP_TCPIP_CORE_LOCKING + conn->write_delayed = 1; +#endif + } else { + /* On errors != ERR_MEM, we don't try writing any more but return + the error to the application thread. */ + conn->err = err; + write_finished = 1; + } + + if (write_finished) { + /* everything was written: set back connection state + and back to application task */ + conn->state = NETCONN_NONE; +#if LWIP_TCPIP_CORE_LOCKING + if (conn->write_delayed != 0) +#endif + { + sys_sem_signal(conn->op_completed); + } + } +#if LWIP_TCPIP_CORE_LOCKING + else + return ERR_MEM; +#endif + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a TCP pcb contained in a netconn + * Called from netconn_write + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_write(struct api_msg_msg *msg) +{ + if (!ERR_IS_FATAL(msg->conn->err)) { + if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { +#if LWIP_TCP + msg->conn->state = NETCONN_WRITE; + /* set all the variables used by do_writemore */ + LWIP_ASSERT("already writing", msg->conn->write_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->write_msg = msg; + msg->conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + msg->conn->write_delayed = 0; + if (do_writemore(msg->conn) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(msg->conn->op_completed, 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); + } +#else + do_writemore(msg->conn); +#endif + /* for both cases: if do_writemore was called, don't ACK the APIMSG! */ + return; +#endif /* LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) + } else { + msg->conn->err = ERR_VAL; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Return a connection's local or remote address + * Called from netconn_getaddr + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_getaddr(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.ip != NULL) { + *(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip); + + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + } else { + /* return an error as connecting is only a helper for upper layers */ + msg->conn->err = ERR_CONN; + } + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + } else { + if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { + msg->conn->err = ERR_CONN; + } else { + *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + } + } + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); + break; +#endif /* LWIP_TCP */ + } + } else { + msg->conn->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Close a TCP pcb contained in a netconn + * Called from netconn_close + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_close(struct api_msg_msg *msg) +{ +#if LWIP_TCP + if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { + msg->conn->state = NETCONN_CLOSE; + do_close_internal(msg->conn); + /* for tcp netconns, do_close_internal ACKs the message */ + } else +#endif /* LWIP_TCP */ + { + msg->conn->err = ERR_VAL; + sys_sem_signal(msg->conn->op_completed); + } +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * Called from netconn_join_leave_group + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_join_leave_group(struct api_msg_msg *msg) +{ + if (!ERR_IS_FATAL(msg->conn->err)) { + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { +#if LWIP_UDP + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr); + } else { + msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr); + } +#endif /* LWIP_UDP */ +#if (LWIP_TCP || LWIP_RAW) + } else { + msg->conn->err = ERR_VAL; +#endif /* (LWIP_TCP || LWIP_RAW) */ + } + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Callback function that is called when DNS name is resolved + * (or on timeout). A waiting application thread is waked up by + * signaling the semaphore. + */ +static void +do_dns_found(const char *name, struct ip_addr *ipaddr, void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); + + if (ipaddr == NULL) { + /* timeout or memory error */ + *msg->err = ERR_VAL; + } else { + /* address was resolved */ + *msg->err = ERR_OK; + *msg->addr = *ipaddr; + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); +} + +/** + * Execute a DNS query + * Called from netconn_gethostbyname + * + * @param arg the dns_api_msg pointing to the query + */ +void +do_gethostbyname(void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg); + if (*msg->err != ERR_INPROGRESS) { + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); + } +} +#endif /* LWIP_DNS */ + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/err.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/err.c new file mode 100644 index 0000000..c8266ab --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/err.c @@ -0,0 +1,74 @@ +/* + * @file + * Error Management module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/err.h" + +#ifdef LWIP_DEBUG + +static const char *err_strerr[] = { + "Ok.", /* ERR_OK 0 */ + "Out of memory error.", /* ERR_MEM -1 */ + "Buffer error.", /* ERR_BUF -2 */ + "Timeout.", /* ERR_TIMEOUT -3 */ + "Routing problem.", /* ERR_RTE -4 */ + "Connection aborted.", /* ERR_ABRT -5 */ + "Connection reset.", /* ERR_RST -6 */ + "Connection closed.", /* ERR_CLSD -7 */ + "Not connected.", /* ERR_CONN -8 */ + "Illegal value.", /* ERR_VAL -9 */ + "Illegal argument.", /* ERR_ARG -10 */ + "Address in use.", /* ERR_USE -11 */ + "Low-level netif error.", /* ERR_IF -12 */ + "Already connected.", /* ERR_ISCONN -13 */ + "Operation in progress." /* ERR_INPROGRESS -14 */ +}; + +/** + * Convert an lwip internal error to a string representation. + * + * @param err an lwip internal err_t + * @return a string representation for err + */ +const char * +lwip_strerr(err_t err) +{ + return err_strerr[-err]; + +} + +#endif /* LWIP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netbuf.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netbuf.c new file mode 100644 index 0000000..5cb24f1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netbuf.c @@ -0,0 +1,240 @@ +/** + * @file + * Network buffer management + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netbuf.h" +#include "lwip/memp.h" + +#include + +/** + * Create (allocate) and initialize a new netbuf. + * The netbuf doesn't yet contain a packet buffer! + * + * @return a pointer to a new netbuf + * NULL on lack of memory + */ +struct +netbuf *netbuf_new(void) +{ + struct netbuf *buf; + + buf = memp_malloc(MEMP_NETBUF); + if (buf != NULL) { + buf->p = NULL; + buf->ptr = NULL; + buf->addr = NULL; + buf->port = 0; +#if LWIP_NETBUF_RECVINFO + buf->toaddr = NULL; + buf->toport = 0; +#endif /* LWIP_NETBUF_RECVINFO */ + return buf; + } else { + return NULL; + } +} + +/** + * Deallocate a netbuf allocated by netbuf_new(). + * + * @param buf pointer to a netbuf allocated by netbuf_new() + */ +void +netbuf_delete(struct netbuf *buf) +{ + if (buf != NULL) { + if (buf->p != NULL) { + pbuf_free(buf->p); + buf->p = buf->ptr = NULL; + } + memp_free(MEMP_NETBUF, buf); + } +} + +/** + * Allocate memory for a packet buffer for a given netbuf. + * + * @param buf the netbuf for which to allocate a packet buffer + * @param size the size of the packet buffer to allocate + * @return pointer to the allocated memory + * NULL if no memory could be allocated + */ +void * +netbuf_alloc(struct netbuf *buf, u16_t size) +{ + LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); + + /* Deallocate any previously allocated memory. */ + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); + if (buf->p == NULL) { + return NULL; + } + LWIP_ASSERT("check that first pbuf can hold size", + (buf->p->len >= size)); + buf->ptr = buf->p; + return buf->p->payload; +} + +/** + * Free the packet buffer included in a netbuf + * + * @param buf pointer to the netbuf which contains the packet buffer to free + */ +void +netbuf_free(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = buf->ptr = NULL; +} + +/** + * Let a netbuf reference existing (non-volatile) data. + * + * @param buf netbuf which should reference the data + * @param dataptr pointer to the data to reference + * @param size size of the data + * @return ERR_OK if data is referenced + * ERR_MEM if data couldn't be referenced due to lack of memory + */ +err_t +netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) +{ + LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (buf->p == NULL) { + buf->ptr = NULL; + return ERR_MEM; + } + buf->p->payload = (void*)dataptr; + buf->p->len = buf->p->tot_len = size; + buf->ptr = buf->p; + return ERR_OK; +} + +/** + * Chain one netbuf to another (@see pbuf_chain) + * + * @param head the first netbuf + * @param tail netbuf to chain after head, freed by this function, may not be reference after returning + */ +void +netbuf_chain(struct netbuf *head, struct netbuf *tail) +{ + LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); + LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); + pbuf_cat(head->p, tail->p); + head->ptr = head->p; + memp_free(MEMP_NETBUF, tail); +} + +/** + * Get the data pointer and length of the data inside a netbuf. + * + * @param buf netbuf to get the data from + * @param dataptr pointer to a void pointer where to store the data pointer + * @param len pointer to an u16_t where the length of the data is stored + * @return ERR_OK if the information was retreived, + * ERR_BUF on error. + */ +err_t +netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) +{ + LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); + + if (buf->ptr == NULL) { + return ERR_BUF; + } + *dataptr = buf->ptr->payload; + *len = buf->ptr->len; + return ERR_OK; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the next part. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + * @return -1 if there is no next part + * 1 if moved to the next part but now there is no next part + * 0 if moved to the next part and there are still more parts + */ +s8_t +netbuf_next(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;); + if (buf->ptr->next == NULL) { + return -1; + } + buf->ptr = buf->ptr->next; + if (buf->ptr->next == NULL) { + return 1; + } + return 0; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the beginning of the packet. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + */ +void +netbuf_first(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + buf->ptr = buf->p; +} + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netdb.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netdb.c new file mode 100644 index 0000000..dc91837 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netdb.c @@ -0,0 +1,346 @@ +/** + * @file + * API functions for name resolving + * + **/ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/netdb.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include "lwip/err.h" +#include "lwip/mem.h" +#include "lwip/ip_addr.h" +#include "lwip/api.h" + +#include +#include + +/** helper struct for gethostbyname_r to access the char* buffer */ +struct gethostbyname_r_helper { + struct ip_addr *addrs; + struct ip_addr addr; + char *aliases; +}; + +/** h_errno is exported in netdb.h for access by applications. */ +#if LWIP_DNS_API_DECLARE_H_ERRNO +int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ + +/** define "hostent" variables storage: 0 if we use a static (but unprotected) + * set of variables for lwip_gethostbyname, 1 if we use a local storage */ +#ifndef LWIP_DNS_API_HOSTENT_STORAGE +#define LWIP_DNS_API_HOSTENT_STORAGE 0 +#endif + +/** define "hostent" variables storage */ +#if LWIP_DNS_API_HOSTENT_STORAGE +#define HOSTENT_STORAGE +#else +#define HOSTENT_STORAGE static +#endif /* LWIP_DNS_API_STATIC_HOSTENT */ + +/** + * Returns an entry containing addresses of address family AF_INET + * for the host with name name. + * Due to dns_gethostbyname limitations, only one address is returned. + * + * @param name the hostname to resolve + * @return an entry containing addresses of address family AF_INET + * for the host with name name + */ +struct hostent* +lwip_gethostbyname(const char *name) +{ + err_t err; + struct ip_addr addr; + + /* buffer variables for lwip_gethostbyname() */ + HOSTENT_STORAGE struct hostent s_hostent; + HOSTENT_STORAGE char *s_aliases; + HOSTENT_STORAGE struct ip_addr s_hostent_addr; + HOSTENT_STORAGE struct ip_addr *s_phostent_addr; + + /* query host IP address */ + err = netconn_gethostbyname(name, &addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + h_errno = HOST_NOT_FOUND; + return NULL; + } + + /* fill hostent */ + s_hostent_addr = addr; + s_phostent_addr = &s_hostent_addr; + s_hostent.h_name = (char*)name; + s_hostent.h_aliases = &s_aliases; + s_hostent.h_addrtype = AF_INET; + s_hostent.h_length = sizeof(struct ip_addr); + s_hostent.h_addr_list = (char**)&s_phostent_addr; + +#if DNS_DEBUG + /* dump hostent */ + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); + if (s_hostent.h_aliases != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_aliases[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx])); + } + } + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); + if (s_hostent.h_addr_list != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa(s_hostent.h_addr_list[idx]))); + } + } +#endif /* DNS_DEBUG */ + +#if LWIP_DNS_API_HOSTENT_STORAGE + /* this function should return the "per-thread" hostent after copy from s_hostent */ + return sys_thread_hostent(&s_hostent); +#else + return &s_hostent; +#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ +} + +/** + * Thread-safe variant of lwip_gethostbyname: instead of using a static + * buffer, this function takes buffer and errno pointers as arguments + * and uses these for the result. + * + * @param name the hostname to resolve + * @param ret pre-allocated struct where to store the result + * @param buf pre-allocated buffer where to store additional data + * @param buflen the size of buf + * @param result pointer to a hostent pointer that is set to ret on success + * and set to zero on error + * @param h_errnop pointer to an int where to store errors (instead of modifying + * the global h_errno) + * @return 0 on success, non-zero on error, additional error information + * is stored in *h_errnop instead of h_errno to be thread-safe + */ +int +lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + err_t err; + struct gethostbyname_r_helper *h; + char *hostname; + size_t namelen; + int lh_errno; + + if (h_errnop == NULL) { + /* ensure h_errnop is never NULL */ + h_errnop = &lh_errno; + } + + if (result == NULL) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + /* first thing to do: set *result to nothing */ + *result = NULL; + if ((name == NULL) || (ret == NULL) || (buf == 0)) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + + namelen = strlen(name); + if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { + /* buf can't hold the data needed + a copy of name */ + *h_errnop = ERANGE; + return -1; + } + + h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); + hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); + + /* query host IP address */ + err = netconn_gethostbyname(name, &(h->addr)); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + *h_errnop = ENSRNOTFOUND; + return -1; + } + + /* copy the hostname into buf */ + MEMCPY(hostname, name, namelen); + hostname[namelen] = 0; + + /* fill hostent */ + h->addrs = &(h->addr); + h->aliases = NULL; + ret->h_name = (char*)hostname; + ret->h_aliases = &(h->aliases); + ret->h_addrtype = AF_INET; + ret->h_length = sizeof(struct ip_addr); + ret->h_addr_list = (char**)&(h->addrs); + + /* set result != NULL */ + *result = ret; + + /* return success */ + return 0; +} + +/** + * Frees one or more addrinfo structures returned by getaddrinfo(), along with + * any additional storage associated with those structures. If the ai_next field + * of the structure is not null, the entire list of structures is freed. + * + * @param ai struct addrinfo to free + */ +void +lwip_freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + while (ai != NULL) { + next = ai->ai_next; + mem_free(ai); + ai = next; + } +} + +/** + * Translates the name of a service location (for example, a host name) and/or + * a service name and returns a set of socket addresses and associated + * information to be used in creating a socket with which to address the + * specified service. + * Memory for the result is allocated internally and must be freed by calling + * lwip_freeaddrinfo()! + * + * Due to a limitation in dns_gethostbyname, only the first address of a + * host is returned. + * Also, service names are not supported (only port numbers)! + * + * @param nodename descriptive name or address string of the host + * (may be NULL -> local address) + * @param servname port number as string of NULL + * @param hints structure containing input values that set socktype and protocol + * @param res pointer to a pointer where to store the result (set to NULL on failure) + * @return 0 on success, non-zero on failure + */ +int +lwip_getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + err_t err; + struct ip_addr addr; + struct addrinfo *ai; + struct sockaddr_in *sa = NULL; + int port_nr = 0; + size_t total_size; + size_t namelen = 0; + + if (res == NULL) { + return EAI_FAIL; + } + *res = NULL; + if ((nodename == NULL) && (servname == NULL)) { + return EAI_NONAME; + } + + if (servname != NULL) { + /* service name specified: convert to port number + * @todo?: currently, only ASCII integers (port numbers) are supported! */ + port_nr = atoi(servname); + if ((port_nr <= 0) || (port_nr > 0xffff)) { + return EAI_SERVICE; + } + } + + if (nodename != NULL) { + /* service location specified, try to resolve */ + err = netconn_gethostbyname(nodename, &addr); + if (err != ERR_OK) { + return EAI_FAIL; + } + } else { + /* service location specified, use loopback address */ + addr.addr = htonl(INADDR_LOOPBACK); + } + + total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in); + if (nodename != NULL) { + namelen = strlen(nodename); + LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); + total_size += namelen + 1; + } + ai = mem_malloc(total_size); + if (ai == NULL) { + goto memerr; + } + memset(ai, 0, total_size); + sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo)); + /* set up sockaddr */ + sa->sin_addr.s_addr = addr.addr; + sa->sin_family = AF_INET; + sa->sin_len = sizeof(struct sockaddr_in); + sa->sin_port = htons(port_nr); + + /* set up addrinfo */ + ai->ai_family = AF_INET; + if (hints != NULL) { + /* copy socktype & protocol from hints if specified */ + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + if (nodename != NULL) { + /* copy nodename to canonname if specified */ + ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + MEMCPY(ai->ai_canonname, nodename, namelen); + ai->ai_canonname[namelen] = 0; + } + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr = (struct sockaddr*)sa; + + *res = ai; + + return 0; +memerr: + if (ai != NULL) { + mem_free(ai); + } + return EAI_MEMORY; +} + +#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netifapi.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netifapi.c new file mode 100644 index 0000000..6ee58dc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/netifapi.c @@ -0,0 +1,162 @@ +/** + * @file + * Network Interface Sequential API module + * + **/ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netifapi.h" +#include "lwip/tcpip.h" + +/** + * Call netif_add() inside the tcpip_thread context. + */ +void +do_netifapi_netif_add( struct netifapi_msg_msg *msg) +{ + if (!netif_add( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw, + msg->msg.add.state, + msg->msg.add.init, + msg->msg.add.input)) { + msg->err = ERR_IF; + } else { + msg->err = ERR_OK; + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_set_addr() inside the tcpip_thread context. + */ +void +do_netifapi_netif_set_addr( struct netifapi_msg_msg *msg) +{ + netif_set_addr( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw); + msg->err = ERR_OK; + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the + * tcpip_thread context. + */ +void +do_netifapi_netif_common( struct netifapi_msg_msg *msg) +{ + if (msg->msg.common.errtfunc!=NULL) { + msg->err = + msg->msg.common.errtfunc(msg->netif); + } else { + msg->err = ERR_OK; + msg->msg.common.voidfunc(msg->netif); + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_add() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_add() + */ +err_t +netifapi_netif_add(struct netif *netif, + struct ip_addr *ipaddr, + struct ip_addr *netmask, + struct ip_addr *gw, + void *state, + err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_add; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + msg.msg.msg.add.state = state; + msg.msg.msg.add.init = init; + msg.msg.msg.add.input = input; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * Call netif_set_addr() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_set_addr() + */ +err_t +netifapi_netif_set_addr(struct netif *netif, + struct ip_addr *ipaddr, + struct ip_addr *netmask, + struct ip_addr *gw) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_set_addr; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe + * way by running that function inside the tcpip_thread context. + * + * @note use only for functions where there is only "netif" parameter. + */ +err_t +netifapi_netif_common( struct netif *netif, + void (* voidfunc)(struct netif *netif), + err_t (* errtfunc)(struct netif *netif) ) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_common; + msg.msg.netif = netif; + msg.msg.msg.common.voidfunc = voidfunc; + msg.msg.msg.common.errtfunc = errtfunc; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +#endif /* LWIP_NETIF_API */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/sockets.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/sockets.c new file mode 100644 index 0000000..bf09d46 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/sockets.c @@ -0,0 +1,1971 @@ +/** + * @file + * Sockets BSD-Like API module + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sockets.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcpip.h" + +#include + +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** Contains all internal pointers and states used for a socket */ +struct lwip_socket { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + struct netbuf *lastdata; + /** offset in the data that was left from the previous read */ + u16_t lastoffset; + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was received, set by event_callback(), + tested by select */ + u16_t sendevent; + /** socket flags (currently, only used for O_NONBLOCK) */ + u16_t flags; + /** last error that occurred on this socket */ + int err; +}; + +/** Description for a task waiting in select */ +struct lwip_select_cb { + /** Pointer to the next waiting task */ + struct lwip_select_cb *next; + /** readset passed to select */ + fd_set *readset; + /** writeset passed to select */ + fd_set *writeset; + /** unimplemented: exceptset passed to select */ + fd_set *exceptset; + /** don't signal the same semaphore twice: set to 1 when signalled */ + int sem_signalled; + /** semaphore to wake up a task waiting for select */ + sys_sem_t sem; +}; + +/** This struct is used to pass data to the set/getsockopt_internal + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket struct for which to change options */ + struct lwip_socket *sock; + /** socket index for which to change options */ + int s; + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ + void *optval; + /** size of *optval */ + socklen_t *optlen; + /** if an error occures, it is temporarily stored here */ + err_t err; +}; + +/** The global array of available sockets */ +static struct lwip_socket sockets[NUM_SOCKETS]; +/** The global list of tasks waiting for select */ +static struct lwip_select_cb *select_cb_list; + +/** Semaphore protecting the sockets array */ +static sys_sem_t socksem; +/** Semaphore protecting select_cb_list */ +static sys_sem_t selectsem; + +/** Table to quickly map an lwIP error (err_t) to a socket error + * by using -err as an index */ +static const int err_to_errno_table[] = { + 0, /* ERR_OK 0 No error, everything OK. */ + ENOMEM, /* ERR_MEM -1 Out of memory error. */ + ENOBUFS, /* ERR_BUF -2 Buffer error. */ + ETIMEDOUT, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + ECONNABORTED, /* ERR_ABRT -5 Connection aborted. */ + ECONNRESET, /* ERR_RST -6 Connection reset. */ + ESHUTDOWN, /* ERR_CLSD -7 Connection closed. */ + ENOTCONN, /* ERR_CONN -8 Not connected. */ + EINVAL, /* ERR_VAL -9 Illegal value. */ + EIO, /* ERR_ARG -10 Illegal argument. */ + EADDRINUSE, /* ERR_USE -11 Address in use. */ + -1, /* ERR_IF -12 Low-level netif error */ + -1, /* ERR_ISCONN -13 Already connected. */ + EINPROGRESS /* ERR_INPROGRESS -14 Operation in progress */ +}; + +#define ERR_TO_ERRNO_TABLE_SIZE \ + (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) + +#define err_to_errno(err) \ + ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ + err_to_errno_table[-(err)] : EIO) + +#ifdef ERRNO +#ifndef set_errno +#define set_errno(err) errno = (err) +#endif +#else +#define set_errno(err) +#endif + +#define sock_set_errno(sk, e) do { \ + sk->err = (e); \ + set_errno(sk->err); \ +} while (0) + +/* Forward delcaration of some functions */ +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); +static void lwip_getsockopt_internal(void *arg); +static void lwip_setsockopt_internal(void *arg); + +/** + * Initialize this module. This function has to be called before any other + * functions in this module! + */ +void +lwip_socket_init(void) +{ + socksem = sys_sem_new(1); + selectsem = sys_sem_new(1); +} + +/** + * Map a externally used socket index to the internal socket representation. + * + * @param s externally used socket index + * @return struct lwip_socket for the socket or NULL if not found + */ +static struct lwip_socket * +get_socket(int s) +{ + struct lwip_socket *sock; + + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); + set_errno(EBADF); + return NULL; + } + + sock = &sockets[s]; + + if (!sock->conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); + set_errno(EBADF); + return NULL; + } + + return sock; +} + +/** + * Allocate a new socket for a given netconn. + * + * @param newconn the netconn for which to allocate a socket + * @return the index of the new socket; -1 on error + */ +static int +alloc_socket(struct netconn *newconn) +{ + int i; + + /* Protect socket array */ + sys_sem_wait(socksem); + + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + if (!sockets[i].conn) { + sockets[i].conn = newconn; + sockets[i].lastdata = NULL; + sockets[i].lastoffset = 0; + sockets[i].rcvevent = 0; + sockets[i].sendevent = 1; /* TCP send buf is empty */ + sockets[i].flags = 0; + sockets[i].err = 0; + sys_sem_signal(socksem); + return i; + } + } + sys_sem_signal(socksem); + return -1; +} + +/* Below this, the well-known socket functions are implemented. + * Use google.com or opengroup.org to get a good description :-) + * + * Exceptions are documented! + */ + +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct lwip_socket *sock, *nsock; + struct netconn *newconn; + struct ip_addr naddr; + u16_t port; + int newsock; + struct sockaddr_in sin; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) + return -1; + + if ((sock->flags & O_NONBLOCK) && (sock->rcvevent <= 0)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + newconn = netconn_accept(sock->conn); + if (!newconn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) failed, err=%d\n", s, sock->conn->err)); + sock_set_errno(sock, err_to_errno(sock->conn->err)); + return -1; + } + + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { + netconn_delete(newconn); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if (NULL != addr) { + LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = naddr.addr; + + if (*addrlen > sizeof(sin)) + *addrlen = sizeof(sin); + + MEMCPY(addr, &sin, *addrlen); + } + + newsock = alloc_socket(newconn); + if (newsock == -1) { + netconn_delete(newconn); + sock_set_errno(sock, ENFILE); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); + newconn->callback = event_callback; + nsock = &sockets[newsock]; + LWIP_ASSERT("invalid socket pointer", nsock != NULL); + + sys_sem_wait(socksem); + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + nsock->rcvevent += -1 - newconn->socket; + newconn->socket = newsock; + sys_sem_signal(socksem); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + + sock_set_errno(sock, 0); + return newsock; +} + +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_socket *sock; + struct ip_addr local_addr; + u16_t local_port; + err_t err; + + sock = get_socket(s); + if (!sock) + return -1; + + LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((((const struct sockaddr_in *)name)->sin_family) == AF_INET)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + + local_addr.addr = ((const struct sockaddr_in *)name)->sin_addr.s_addr; + local_port = ((const struct sockaddr_in *)name)->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); + + err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_close(int s) +{ + struct lwip_socket *sock; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + netconn_delete(sock->conn); + + sys_sem_wait(socksem); + if (sock->lastdata) { + netbuf_delete(sock->lastdata); + } + sock->lastdata = NULL; + sock->lastoffset = 0; + sock->conn = NULL; + sock_set_errno(sock, 0); + sys_sem_signal(socksem); + return 0; +} + +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_socket *sock; + err_t err; + + sock = get_socket(s); + if (!sock) + return -1; + + LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((((const struct sockaddr_in *)name)->sin_family) == AF_INET)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + + if (((const struct sockaddr_in *)name)->sin_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + struct ip_addr remote_addr; + u16_t remote_port; + + remote_addr.addr = ((const struct sockaddr_in *)name)->sin_addr.s_addr; + remote_port = ((const struct sockaddr_in *)name)->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); + + err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); + } + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +/** + * Set a socket into listen mode. + * The socket may not have been used for another connection previously. + * + * @param s the socket to set to listening mode + * @param backlog (ATTENTION: need TCP_LISTEN_BACKLOG=1) + * @return 0 on success, non-zero on failure + */ +int +lwip_listen(int s, int backlog) +{ + struct lwip_socket *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + + sock = get_socket(s); + if (!sock) + return -1; + + /* limit the "backlog" parameter to fit in an u8_t */ + if (backlog < 0) { + backlog = 0; + } + if (backlog > 0xff) { + backlog = 0xff; + } + + err = netconn_listen_with_backlog(sock->conn, backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + struct lwip_socket *sock; + struct netbuf *buf; + u16_t buflen, copylen, off = 0; + struct ip_addr *addr; + u16_t port; + u8_t done = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) + return -1; + + do { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", (void*)sock->lastdata)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata) { + buf = sock->lastdata; + } else { + /* If this is non-blocking call, then check first */ + if (((flags & MSG_DONTWAIT) || (sock->flags & O_NONBLOCK)) && + (sock->rcvevent <= 0)) { + if (off > 0) { + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* No data was left from the previous operation, so we try to get + some from the network. */ + sock->lastdata = buf = netconn_recv(sock->conn); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv netbuf=%p\n", (void*)buf)); + + if (!buf) { + if (off > 0) { + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL!\n", s)); + sock_set_errno(sock, (((sock->conn->pcb.ip != NULL) && (sock->conn->err == ERR_OK)) + ? ETIMEDOUT : err_to_errno(sock->conn->err))); + return 0; + } + } + + buflen = netbuf_len(buf); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%"U16_F" sock->lastoffset=%"U16_F"\n", + buflen, len, off, sock->lastoffset)); + + buflen -= sock->lastoffset; + + if (len > buflen) { + copylen = buflen; + } else { + copylen = (u16_t)len; + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + netbuf_copy_partial(buf, (u8_t*)mem + off, copylen, sock->lastoffset); + + off += copylen; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); + len -= copylen; + if ( (len <= 0) || + (buf->p->flags & PBUF_FLAG_PUSH) || + (sock->rcvevent <= 0) || + ((flags & MSG_PEEK)!=0)) { + done = 1; + } + } else { + done = 1; + } + + /* Check to see from where the data was.*/ + if (done) { + if (from && fromlen) { + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = addr->addr; + + if (*fromlen > sizeof(sin)) { + *fromlen = sizeof(sin); + } + + MEMCPY(from, &sin, *fromlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%"U16_F"\n", port, off)); + } else { + #if SOCKETS_DEBUG + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = (struct ip_addr*)&(sin.sin_addr.s_addr); + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%"U16_F"\n", port, off)); + #endif /* SOCKETS_DEBUG */ + } + } + + /* If we don't peek the incoming message... */ + if ((flags & MSG_PEEK)==0) { + /* If this is a TCP socket, check if there is data left in the + buffer. If so, it should be saved in the sock structure for next + time around. */ + if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) { + sock->lastdata = buf; + sock->lastoffset += copylen; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", (void*)buf)); + } else { + sock->lastdata = NULL; + sock->lastoffset = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", (void*)buf)); + netbuf_delete(buf); + } + } + } while (!done); + + sock_set_errno(sock, 0); + return off; +} + +int +lwip_read(int s, void *mem, size_t len) +{ + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); +} + +int +lwip_recv(int s, void *mem, size_t len, int flags) +{ + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); +} + +int +lwip_send(int s, const void *data, size_t size, int flags) +{ + struct lwip_socket *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); + + sock = get_socket(s); + if (!sock) + return -1; + + if (sock->conn->type != NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + return lwip_sendto(s, data, size, flags, NULL, 0); +#else + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + err = netconn_write(sock->conn, data, size, NETCONN_COPY | ((flags & MSG_MORE)?NETCONN_MORE:0)); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size)); + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? (int)size : -1); +} + +int +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + struct lwip_socket *sock; + struct ip_addr remote_addr; + err_t err; + u16_t short_size; +#if !LWIP_TCPIP_CORE_LOCKING + struct netbuf buf; + u16_t remote_port; +#endif + + sock = get_socket(s); + if (!sock) + return -1; + + if (sock->conn->type == NETCONN_TCP) { +#if LWIP_TCP + return lwip_send(s, data, size, flags); +#else + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* LWIP_TCP */ + } + + LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + ((tolen == sizeof(struct sockaddr_in)) && + ((((const struct sockaddr_in *)to)->sin_family) == AF_INET))), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + +#if LWIP_TCPIP_CORE_LOCKING + /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */ + { struct pbuf* p; + + p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (p == NULL) { + err = ERR_MEM; + } else { + p->payload = (void*)data; + p->len = p->tot_len = short_size; + + remote_addr.addr = ((const struct sockaddr_in *)to)->sin_addr.s_addr; + + LOCK_TCPIP_CORE(); + if (sock->conn->type==NETCONN_RAW) { + err = sock->conn->err = raw_sendto(sock->conn->pcb.raw, p, &remote_addr); + } else { + err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((const struct sockaddr_in *)to)->sin_port)); + } + UNLOCK_TCPIP_CORE(); + + pbuf_free(p); + } + } +#else + /* initialize a buffer */ + buf.p = buf.ptr = NULL; + if (to) { + remote_addr.addr = ((const struct sockaddr_in *)to)->sin_addr.s_addr; + remote_port = ntohs(((const struct sockaddr_in *)to)->sin_port); + buf.addr = &remote_addr; + buf.port = remote_port; + } else { + remote_addr.addr = 0; + remote_port = 0; + buf.addr = NULL; + buf.port = 0; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + + /* make the buffer point to the data that should be sent */ +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { + err = netbuf_take(&buf, data, short_size); + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { + /* send the data */ + err = netconn_send(sock->conn, &buf); + } + + /* deallocated the buffer */ + netbuf_free(&buf); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? short_size : -1); +} + +int +lwip_socket(int domain, int type, int protocol) +{ + struct netconn *conn; + int i; + + LWIP_UNUSED_ARG(domain); + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ? + NETCONN_UDPLITE : NETCONN_UDP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(NETCONN_TCP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } + + i = alloc_socket(conn); + + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->socket = i; + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; +} + +int +lwip_write(int s, const void *data, size_t size) +{ + return lwip_send(s, data, size, 0); +} + +/** + * Go through the readset and writeset lists and see which socket of the sockets + * set in the sets has events. On return, readset, writeset and exceptset have + * the sockets enabled that had events. + * + * exceptset is not used for now!!! + * + * @param maxfdp1 the highest socket index in the sets + * @param readset in: set of sockets to check for read events; + * out: set of sockets that had read events + * @param writeset in: set of sockets to check for write events; + * out: set of sockets that had write events + * @param exceptset not yet implemented + * @return number of sockets that had events (read+write) + */ +static int +lwip_selscan(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset) +{ + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_socket *p_sock; + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for(i = 0; i < maxfdp1; i++) { + if (FD_ISSET(i, readset)) { + /* See if netconn of this socket is ready for read */ + p_sock = get_socket(i); + if (p_sock && (p_sock->lastdata || (p_sock->rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + } + if (FD_ISSET(i, writeset)) { + /* See if netconn of this socket is ready for write */ + p_sock = get_socket(i); + if (p_sock && p_sock->sendevent) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + } + } + *readset = lreadset; + *writeset = lwriteset; + FD_ZERO(exceptset); + + return nready; +} + + +/** + * Processing exceptset is not yet implemented. + */ +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) +{ + int i; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + struct lwip_select_cb select_cb; + struct lwip_select_cb *p_selcb; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (long)timeout->tv_sec : (long)-1, + timeout ? (long)timeout->tv_usec : (long)-1)); + + select_cb.next = 0; + select_cb.readset = readset; + select_cb.writeset = writeset; + select_cb.exceptset = exceptset; + select_cb.sem_signalled = 0; + + /* Protect ourselves searching through the list */ + sys_sem_wait(selectsem); + + if (readset) + lreadset = *readset; + else + FD_ZERO(&lreadset); + if (writeset) + lwriteset = *writeset; + else + FD_ZERO(&lwriteset); + if (exceptset) + lexceptset = *exceptset; + else + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset); + + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + sys_sem_signal(selectsem); + if (readset) + FD_ZERO(readset); + if (writeset) + FD_ZERO(writeset); + if (exceptset) + FD_ZERO(exceptset); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + set_errno(0); + + return 0; + } + + /* add our semaphore to list */ + /* We don't actually need any dynamic memory. Our entry on the + * list is only valid while we are in this function, so it's ok + * to use local variables */ + + select_cb.sem = sys_sem_new(0); + /* Note that we are still protected */ + /* Put this select_cb on top of list */ + select_cb.next = select_cb_list; + select_cb_list = &select_cb; + + /* Now we can safely unprotect */ + sys_sem_signal(selectsem); + + /* Now just wait to be woken */ + if (timeout == 0) + /* Wait forever */ + msectimeout = 0; + else { + msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); + if(msectimeout == 0) + msectimeout = 1; + } + + i = sys_sem_wait_timeout(select_cb.sem, msectimeout); + + /* Take us off the list */ + sys_sem_wait(selectsem); + if (select_cb_list == &select_cb) + select_cb_list = select_cb.next; + else + for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next) { + if (p_selcb->next == &select_cb) { + p_selcb->next = select_cb.next; + break; + } + } + + sys_sem_signal(selectsem); + + sys_sem_free(select_cb.sem); + if (i == 0) { + /* Timeout */ + if (readset) + FD_ZERO(readset); + if (writeset) + FD_ZERO(writeset); + if (exceptset) + FD_ZERO(exceptset); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + set_errno(0); + + return 0; + } + + if (readset) + lreadset = *readset; + else + FD_ZERO(&lreadset); + if (writeset) + lwriteset = *writeset; + else + FD_ZERO(&lwriteset); + if (exceptset) + lexceptset = *exceptset; + else + FD_ZERO(&lexceptset); + + /* See what's set */ + nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset); + } else + sys_sem_signal(selectsem); + + if (readset) + *readset = lreadset; + if (writeset) + *writeset = lwriteset; + if (exceptset) + *exceptset = lexceptset; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); + set_errno(0); + + return nready; +} + +/** + * Callback registered in the netconn layer for each socket-netconn. + * Processes recvevent (data available) and wakes up tasks waiting for select. + */ +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s; + struct lwip_socket *sock; + struct lwip_select_cb *scb; + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + sys_sem_wait(socksem); + if (conn->socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + conn->socket--; + } + sys_sem_signal(socksem); + return; + } + s = conn->socket; + sys_sem_signal(socksem); + } + + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + sys_sem_wait(selectsem); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + break; + case NETCONN_EVT_SENDPLUS: + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + sys_sem_signal(selectsem); + + /* Now decide if anyone is waiting for this socket */ + /* NOTE: This code is written this way to protect the select link list + but to avoid a deadlock situation by releasing socksem before + signalling for the select. This means we need to go through the list + multiple times ONLY IF a select was actually waiting. We go through + the list the number of waiting select calls + 1. This list is + expected to be small. */ + while (1) { + sys_sem_wait(selectsem); + for (scb = select_cb_list; scb; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* Test this select call for our socket */ + if (scb->readset && FD_ISSET(s, scb->readset)) + if (sock->rcvevent > 0) + break; + if (scb->writeset && FD_ISSET(s, scb->writeset)) + if (sock->sendevent) + break; + } + } + if (scb) { + scb->sem_signalled = 1; + sys_sem_signal(scb->sem); + sys_sem_signal(selectsem); + } else { + sys_sem_signal(selectsem); + break; + } + } +} + +/** + * Unimplemented: Close one end of a full-duplex connection. + * Currently, the full connection is closed. + */ +int +lwip_shutdown(int s, int how) +{ + LWIP_UNUSED_ARG(how); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); + return lwip_close(s); /* XXX temporary hack until proper implementation */ +} + +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +{ + struct lwip_socket *sock; + struct sockaddr_in sin; + struct ip_addr naddr; + + sock = get_socket(s); + if (!sock) + return -1; + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + + /* get the IP address and port */ + netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); + + sin.sin_port = htons(sin.sin_port); + sin.sin_addr.s_addr = naddr.addr; + + if (*namelen > sizeof(sin)) + *namelen = sizeof(sin); + + MEMCPY(name, &sin, *namelen); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 0); +} + +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 1); +} + +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + err_t err = ERR_OK; + struct lwip_socket *sock = get_socket(s); + struct lwip_setgetsockopt_data data; + + if (!sock) + return -1; + + if ((NULL == optval) || (NULL == optlen)) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_ERROR: + case SO_KEEPALIVE: + /* UNIMPL case SO_CONTIMEO: */ + /* UNIMPL case SO_SNDTIMEO: */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + case SO_TYPE: + /* UNIMPL case SO_USELOOPBACK: */ + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; + + case SO_NO_CHECK: + if (*optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (*optlen < sizeof(u8_t)) { + err = EINVAL; + } + break; + case IP_MULTICAST_IF: + if (*optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + break; +#endif /* LWIP_IGMP */ + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) + return 0; + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE*/ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + /* Now do the actual option processing */ + data.sock = sock; + data.level = level; + data.optname = optname; + data.optval = optval; + data.optlen = optlen; + data.err = err; + tcpip_callback(lwip_getsockopt_internal, &data); + sys_arch_sem_wait(sock->conn->op_completed, 0); + /* maybe lwip_getsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_getsockopt_internal(void *arg) +{ + struct lwip_socket *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /*case SO_USELOOPBACK: UNIMPL */ + *(int*)optval = sock->conn->pcb.ip->so_options & optname; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; + + case SO_TYPE: + switch (NETCONNTYPE_GROUP(sock->conn->type)) { + case NETCONN_RAW: + *(int*)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int*)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int*)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int*)optval = sock->conn->type; + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (sock->conn->type) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + if (sock->err == 0) { + sock_set_errno(sock, err_to_errno(sock->conn->err)); + } + *(int *)optval = sock->err; + sock->err = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + *(int *)optval = sock->conn->recv_timeout; + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + *(int *)optval = sock->conn->recv_bufsize; + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; +#endif /* LWIP_UDP*/ + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + *(int*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + *(int*)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + *(u8_t*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + ((struct in_addr*) optval)->s_addr = sock->conn->pcb.udp->multicast_ip.addr; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; +#endif /* LWIP_IGMP */ + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int*)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + } /* switch (level) */ + sys_sem_signal(sock->conn->op_completed); +} + +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + struct lwip_socket *sock = get_socket(s); + int err = ERR_OK; + struct lwip_setgetsockopt_data data; + + if (!sock) + return -1; + + if (NULL == optval) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case case SO_CONTIMEO: */ + /* UNIMPL case case SO_SNDTIMEO: */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (optlen < sizeof(int)) { + err = EINVAL; + } + break; + case SO_NO_CHECK: + if (optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (optlen < sizeof(int)) { + err = EINVAL; + } + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_MULTICAST_IF: + if (optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + if (optlen < sizeof(struct ip_mreq)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) + return 0; + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE */ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch (level) */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + + /* Now do the actual option processing */ + data.sock = sock; + data.level = level; + data.optname = optname; + data.optval = (void*)optval; + data.optlen = &optlen; + data.err = err; + tcpip_callback(lwip_setsockopt_internal, &data); + sys_arch_sem_wait(sock->conn->op_completed, 0); + /* maybe lwip_setsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_setsockopt_internal(void *arg) +{ + struct lwip_socket *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + const void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (*(int*)optval) { + sock->conn->pcb.ip->so_options |= optname; + } else { + sock->conn->pcb.ip->so_options &= ~optname; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + sock->conn->recv_timeout = ( *(int*)optval ); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + sock->conn->recv_bufsize = ( *(int*)optval ); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + if (*(int*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); + } + break; +#endif /* LWIP_UDP */ + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); + break; + case IP_MULTICAST_IF: + sock->conn->pcb.udp->multicast_ip.addr = ((struct in_addr*) optval)->s_addr; + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + { + /* If this is a TCP or a RAW socket, ignore these options. */ + struct ip_mreq *imr = (struct ip_mreq *)optval; + if(optname == IP_ADD_MEMBERSHIP){ + data->err = igmp_joingroup((struct ip_addr*)&(imr->imr_interface.s_addr), (struct ip_addr*)&(imr->imr_multiaddr.s_addr)); + } else { + data->err = igmp_leavegroup((struct ip_addr*)&(imr->imr_interface.s_addr), (struct ip_addr*)&(imr->imr_multiaddr.s_addr)); + } + if(data->err != ERR_OK) { + data->err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IGMP */ + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + if (*(int*)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(int *)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + + } /* switch (optname) */ + break; +#endif /* LWIP_TCP*/ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(int*)optval != 0) && (*(int*)optval < 8)) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = *(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(int*)optval != 0) && (*(int*)optval < 8)) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = *(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + } /* switch (level) */ + sys_sem_signal(sock->conn->op_completed); +} + +int +lwip_ioctl(int s, long cmd, void *argp) +{ + struct lwip_socket *sock = get_socket(s); + u16_t buflen = 0; + s16_t recv_avail; + + if (!sock) + return -1; + + switch (cmd) { + case FIONREAD: + if (!argp) { + sock_set_errno(sock, EINVAL); + return -1; + } + + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) + recv_avail = 0; + *((u16_t*)argp) = (u16_t)recv_avail; + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata) { + buflen = netbuf_len(sock->lastdata); + buflen -= sock->lastoffset; + + *((u16_t*)argp) += buflen; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); + sock_set_errno(sock, 0); + return 0; + + case FIONBIO: + if (argp && *(u32_t*)argp) + sock->flags |= O_NONBLOCK; + else + sock->flags &= ~O_NONBLOCK; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, !!(sock->flags & O_NONBLOCK))); + sock_set_errno(sock, 0); + return 0; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + return -1; + } /* switch (cmd) */ +} + +#endif /* LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/tcpip.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/tcpip.c new file mode 100644 index 0000000..002df90 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/api/tcpip.c @@ -0,0 +1,596 @@ +/** + * @file + * Sequential API Main thread module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/ip_frag.h" +#include "lwip/tcp.h" +#include "lwip/autoip.h" +#include "lwip/dhcp.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/tcpip.h" +#include "lwip/init.h" +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +/* global variables */ +static void (* tcpip_init_done)(void *arg); +static void *tcpip_init_done_arg; +static sys_mbox_t mbox = SYS_MBOX_NULL; + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +sys_sem_t lock_tcpip_core; +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_TCP +/* global variable that shows if the tcp timer is currently scheduled or not */ +static int tcpip_tcp_timer_active; + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +#if !NO_SYS +/** + * Called from TCP_REG when registering a new PCB: + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} +#endif /* !NO_SYS */ +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +/** + * Timer callback function that calls ip_reass_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +} +#endif /* IP_REASSEMBLY */ + +#if LWIP_ARP +/** + * Timer callback function that calls etharp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} +#endif /* LWIP_ARP */ + +#if LWIP_DHCP +/** + * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_coarse(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); + dhcp_coarse_tmr(); + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); +} + +/** + * Timer callback function that calls dhcp_fine_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_fine(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: dhcp_fine_tmr()\n")); + dhcp_fine_tmr(); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +} +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP +/** + * Timer callback function that calls autoip_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +autoip_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: autoip_tmr()\n")); + autoip_tmr(); + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +} +#endif /* LWIP_AUTOIP */ + +#if LWIP_IGMP +/** + * Timer callback function that calls igmp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +igmp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: igmp_tmr()\n")); + igmp_tmr(); + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Timer callback function that calls dns_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dns_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip: dns_tmr()\n")); + dns_tmr(); + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +} +#endif /* LWIP_DNS */ + +/** + * The main lwIP thread. This thread has exclusive access to lwIP core functions + * (unless access to them is not locked). Other threads communicate with this + * thread using message boxes. + * + * It also starts all the timers to make sure they are running in the right + * thread context. + * + * @param arg unused argument + */ +static void +tcpip_thread(void *arg) +{ + struct tcpip_msg *msg; + LWIP_UNUSED_ARG(arg); + +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +#endif /* LWIP_ARP */ +#if LWIP_DHCP + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ + + if (tcpip_init_done != NULL) { + tcpip_init_done(tcpip_init_done_arg); + } + + LOCK_TCPIP_CORE(); + while (1) { /* MAIN Loop */ + sys_mbox_fetch(mbox, (void *)&msg); + switch (msg->type) { +#if LWIP_NETCONN + case TCPIP_MSG_API: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); + msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); + break; +#endif /* LWIP_NETCONN */ + + case TCPIP_MSG_INPKT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); +#if LWIP_ARP + if (msg->msg.inp.netif->flags & NETIF_FLAG_ETHARP) { + ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); + } else +#endif /* LWIP_ARP */ + { ip_input(msg->msg.inp.p, msg->msg.inp.netif); + } + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + break; + +#if LWIP_NETIF_API + case TCPIP_MSG_NETIFAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); + msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); + break; +#endif /* LWIP_NETIF_API */ + + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.f(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_TIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); + sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + case TCPIP_MSG_UNTIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); + sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + default: + break; + } + } +} + +/** + * Pass a received packet to tcpip_thread for input processing + * + * @param p the received packet, p->payload pointing to the Ethernet header or + * to an IP header (if netif doesn't got NETIF_FLAG_ETHARP flag) + * @param inp the network interface on which the packet was received + */ +err_t +tcpip_input(struct pbuf *p, struct netif *inp) +{ + struct tcpip_msg *msg; + + if (mbox != SYS_MBOX_NULL) { + msg = memp_malloc(MEMP_TCPIP_MSG_INPKT); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_INPKT; + msg->msg.inp.p = p; + msg->msg.inp.netif = inp; + if (sys_mbox_trypost(mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + return ERR_OK; + } + return ERR_VAL; +} + +/** + * Call a specific function in the thread context of + * tcpip_thread for easy access synchronization. + * A function called in that way may access lwIP core code + * without fearing concurrent access. + * + * @param f the function to call + * @param ctx parameter passed to f + * @param block 1 to block until the request is posted, 0 to non-blocking mode + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block) +{ + struct tcpip_msg *msg; + + if (mbox != SYS_MBOX_NULL) { + msg = memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.f = f; + msg->msg.cb.ctx = ctx; + if (block) { + sys_mbox_post(mbox, msg); + } else { + if (sys_mbox_trypost(mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_API, msg); + return ERR_MEM; + } + } + return ERR_OK; + } + return ERR_VAL; +} + +/** + * call sys_timeout in tcpip_thread + * + * @param msec time in miliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (mbox != SYS_MBOX_NULL) { + msg = memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_TIMEOUT; + msg->msg.tmo.msecs = msecs; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + +/** + * call sys_untimeout in tcpip_thread + * + * @param msec time in miliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_untimeout(sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (mbox != SYS_MBOX_NULL) { + msg = memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_UNTIMEOUT; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_NETCONN +/** + * Call the lower part of a netconn_* function + * This function is then running in the thread context + * of tcpip_thread and has exclusive access to lwIP core code. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_apimsg(struct api_msg *apimsg) +{ + struct tcpip_msg msg; + + if (mbox != SYS_MBOX_NULL) { + msg.type = TCPIP_MSG_API; + msg.msg.apimsg = apimsg; + sys_mbox_post(mbox, &msg); + sys_arch_sem_wait(apimsg->msg.conn->op_completed, 0); + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_CORE_LOCKING +/** + * Call the lower part of a netconn_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_apimsg()) + */ +err_t +tcpip_apimsg_lock(struct api_msg *apimsg) +{ + LOCK_TCPIP_CORE(); + apimsg->function(&(apimsg->msg)); + UNLOCK_TCPIP_CORE(); + return ERR_OK; + +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +#if LWIP_NETIF_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_netifapi(struct netifapi_msg* netifapimsg) +{ + struct tcpip_msg msg; + + if (mbox != SYS_MBOX_NULL) { + netifapimsg->msg.sem = sys_sem_new(0); + if (netifapimsg->msg.sem == SYS_SEM_NULL) { + netifapimsg->msg.err = ERR_MEM; + return netifapimsg->msg.err; + } + + msg.type = TCPIP_MSG_NETIFAPI; + msg.msg.netifapimsg = netifapimsg; + sys_mbox_post(mbox, &msg); + sys_sem_wait(netifapimsg->msg.sem); + sys_sem_free(netifapimsg->msg.sem); + return netifapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a netifapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_netifapi()) + */ +err_t +tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) +{ + LOCK_TCPIP_CORE(); + netifapimsg->function(&(netifapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return netifapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +/** + * Initialize this module: + * - initialize all sub modules + * - start the tcpip_thread + * + * @param initfunc a function to call when tcpip_thread is running and finished initializing + * @param arg argument to pass to initfunc + */ +void +tcpip_init(void (* initfunc)(void *), void *arg) +{ + lwip_init(); + + tcpip_init_done = initfunc; + tcpip_init_done_arg = arg; + mbox = sys_mbox_new(TCPIP_MBOX_SIZE); +#if LWIP_TCPIP_CORE_LOCKING + lock_tcpip_core = sys_sem_new(1); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); +} + +/** + * Simple callback function used with tcpip_callback to free a pbuf + * (pbuf_free has a wrong signature for tcpip_callback) + * + * @param p The pbuf (chain) to be dereferenced. + */ +static void +pbuf_free_int(void *p) +{ + struct pbuf *q = p; + pbuf_free(q); +} + +/** + * A simple wrapper function that allows you to free a pbuf from interrupt context. + * + * @param p The pbuf (chain) to be dereferenced. + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +pbuf_free_callback(struct pbuf *p) +{ + return tcpip_callback_with_block(pbuf_free_int, p, 0); +} + +/** + * A simple wrapper function that allows you to free heap memory from + * interrupt context. + * + * @param m the heap memory to free + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +mem_free_callback(void *m) +{ + return tcpip_callback_with_block(mem_free, m, 0); +} + +#endif /* !NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dhcp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dhcp.c new file mode 100644 index 0000000..7087107 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dhcp.c @@ -0,0 +1,1778 @@ +/* + * @file + * Dynamic Host Configuration Protocol client + * + */ + +/* + * + * Copyright (c) 2001-2004 Leon Woestenberg + * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. + * + * Author: Leon Woestenberg + * + * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform + * with RFC 2131 and RFC 2132. + * + * TODO: + * - Proper parsing of DHCP messages exploiting file/sname field overloading. + * - Add JavaDoc style documentation (API, internals). + * - Support for interfaces other than Ethernet (SLIP, PPP, ...) + * + * Please coordinate changes and requests with Leon Woestenberg + * + * + * Integration with your code: + * + * In lwip/dhcp.h + * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) + * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) + * + * Then have your application call dhcp_coarse_tmr() and + * dhcp_fine_tmr() on the defined intervals. + * + * dhcp_start(struct netif *netif); + * starts a DHCP client instance which configures the interface by + * obtaining an IP address lease and maintaining it. + * + * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif) + * to remove the DHCP client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/inet.h" +#include "lwip/sys.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/dns.h" +#include "netif/etharp.h" + +#include + +/** Default for DHCP_GLOBAL_XID is 0xABCD0000 + * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. + * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" + * #define DHCP_GLOBAL_XID rand() + */ +#ifdef DHCP_GLOBAL_XID_HEADER +#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ +#endif + +/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU + * MTU is checked to be big enough in dhcp_start */ +#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) +#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 +/** Minimum length for reply before packet is parsed */ +#define DHCP_MIN_REPLY_LEN 44 + +#define REBOOT_TRIES 2 + +/* DHCP client state machine functions */ +static void dhcp_handle_ack(struct netif *netif); +static void dhcp_handle_nak(struct netif *netif); +static void dhcp_handle_offer(struct netif *netif); + +static err_t dhcp_discover(struct netif *netif); +static err_t dhcp_select(struct netif *netif); +static void dhcp_bind(struct netif *netif); +#if DHCP_DOES_ARP_CHECK +static void dhcp_check(struct netif *netif); +static err_t dhcp_decline(struct netif *netif); +#endif /* DHCP_DOES_ARP_CHECK */ +static err_t dhcp_rebind(struct netif *netif); +static err_t dhcp_reboot(struct netif *netif); +static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); + +/* receive, unfold, parse and free incoming messages */ +static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); +static err_t dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p); +static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type); +static u8_t dhcp_get_option_byte(u8_t *ptr); +#if 0 +static u16_t dhcp_get_option_short(u8_t *ptr); +#endif +static u32_t dhcp_get_option_long(u8_t *ptr); +static void dhcp_free_reply(struct dhcp *dhcp); + +/* set the DHCP timers */ +static void dhcp_timeout(struct netif *netif); +static void dhcp_t1_timeout(struct netif *netif); +static void dhcp_t2_timeout(struct netif *netif); + +/* build outgoing messages */ +/* create a DHCP request, fill in common headers */ +static err_t dhcp_create_request(struct netif *netif); +/* free a DHCP request */ +static void dhcp_delete_request(struct netif *netif); +/* add a DHCP option (type, then length in bytes) */ +static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); +/* add option values */ +static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); +static void dhcp_option_short(struct dhcp *dhcp, u16_t value); +static void dhcp_option_long(struct dhcp *dhcp, u32_t value); +/* always add the DHCP options trailer to end and pad */ +static void dhcp_option_trailer(struct dhcp *dhcp); + +/** + * Back-off the DHCP client (because of a received NAK response). + * + * Back-off the DHCP client because of a received NAK. Receiving a + * NAK means the client asked for something non-sensible, for + * example when it tries to renew a lease obtained on another network. + * + * We clear any existing set IP address and restart DHCP negotiation + * afresh (as per RFC2131 3.2.3). + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_nak(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Set the interface down since the address must no longer be used, as per RFC2131 */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + /* Change to a defined state */ + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* We can immediately restart discovery */ + dhcp_discover(netif); +} + +#if DHCP_DOES_ARP_CHECK +/** + * Checks if the offered IP address is already in use. + * + * It does so by sending an ARP request for the offered address and + * entering CHECKING state. If no ARP reply is received within a small + * interval, the address is assumed to be free for use by us. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_check(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], + (s16_t)netif->name[1])); + dhcp_set_state(dhcp, DHCP_CHECKING); + /* create an ARP query for the offered IP address, expecting that no host + responds, as the IP address should not be in use. */ + result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); + if (result != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); + } + dhcp->tries++; + msecs = 500; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); +} +#endif /* DHCP_DOES_ARP_CHECK */ + +/** + * Remember the configuration offered by a DHCP server. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_offer(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + /* obtain the server address */ + u8_t *option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SERVER_ID); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + if (option_ptr != NULL) { + dhcp->server_ip_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", dhcp->server_ip_addr.addr)); + /* remember offered address */ + ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr)); + + dhcp_select(netif); + } +} + +/** + * Select a DHCP server offer out of all offers. + * + * Simply select the first offer received. + * + * @param netif the netif under DHCP control + * @return lwIP specific error (see error.h) + */ +static err_t +dhcp_select(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; +#if LWIP_NETIF_HOSTNAME + const char *p; +#endif /* LWIP_NETIF_HOSTNAME */ + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + dhcp_set_state(dhcp, DHCP_REQUESTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_REQUEST); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + /* MUST request the offered IP address */ + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + +#if LWIP_NETIF_HOSTNAME + p = (const char*)netif->hostname; + if (p != NULL) { + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p)); + while (*p) { + dhcp_option_byte(dhcp, *p++); + } + } +#endif /* LWIP_NETIF_HOSTNAME */ + + dhcp_option_trailer(dhcp); + /* shrink the pbuf to the actual content length */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* send broadcast to any DHCP server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * The DHCP timer that checks for lease renewal/rebind timeouts. + * + */ +void +dhcp_coarse_tmr() +{ + struct netif *netif = netif_list; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); + /* iterate through all network interfaces */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and triggers (zeroes) now? */ + if (netif->dhcp->t2_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); + /* this clients' rebind timeout triggered */ + dhcp_t2_timeout(netif); + /* timer is active (non zero), and triggers (zeroes) now */ + } else if (netif->dhcp->t1_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); + /* this clients' renewal timeout triggered */ + dhcp_t1_timeout(netif); + } + } + /* proceed to next netif */ + netif = netif->next; + } +} + +/** + * DHCP transaction timeout handling + * + * A DHCP server is expected to respond within a short period of time. + * This timer checks whether an outstanding DHCP request is timed out. + * + */ +void +dhcp_fine_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and is about to trigger now */ + if (netif->dhcp->request_timeout > 1) { + netif->dhcp->request_timeout--; + } + else if (netif->dhcp->request_timeout == 1) { + netif->dhcp->request_timeout--; + /* { netif->dhcp->request_timeout == 0 } */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); + /* this clients' request timeout triggered */ + dhcp_timeout(netif); + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * A DHCP negotiation transaction, or ARP request, has timed out. + * + * The timer that was started with the DHCP or ARP request has + * timed out, indicating no response was received in time. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); + /* back-off period has passed, or server selection timed out */ + if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); + dhcp_discover(netif); + /* receiving the requested lease timed out */ + } else if (dhcp->state == DHCP_REQUESTING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); + if (dhcp->tries <= 5) { + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); + dhcp_release(netif); + dhcp_discover(netif); + } +#if DHCP_DOES_ARP_CHECK + /* received no ARP reply for the offered address (which is good) */ + } else if (dhcp->state == DHCP_CHECKING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); + if (dhcp->tries <= 1) { + dhcp_check(netif); + /* no ARP replies on the offered address, + looks like the IP address is indeed free */ + } else { + /* bind the interface to the offered address */ + dhcp_bind(netif); + } +#endif /* DHCP_DOES_ARP_CHECK */ + } + /* did not get response to renew request? */ + else if (dhcp->state == DHCP_RENEWING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); + /* just retry renewal */ + /* note that the rebind timer will eventually time-out if renew does not work */ + dhcp_renew(netif); + /* did not get response to rebind request? */ + } else if (dhcp->state == DHCP_REBINDING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); + if (dhcp->tries <= 8) { + dhcp_rebind(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); + dhcp_release(netif); + dhcp_discover(netif); + } + } else if (dhcp->state == DHCP_REBOOTING) { + if (dhcp->tries < REBOOT_TRIES) { + dhcp_reboot(netif); + } else { + dhcp_discover(netif); + } + } +} + +/** + * The renewal period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t1_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { + /* just retry to renew - note that the rebind timer (t2) will + * eventually time-out if renew tries fail. */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t1_timeout(): must renew\n")); + dhcp_renew(netif); + } +} + +/** + * The rebind period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t2_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING)) { + /* just retry to rebind */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout(): must rebind\n")); + dhcp_rebind(netif); + } +} + +/** + * Handle a DHCP ACK packet + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_ack(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + u8_t *option_ptr; + /* clear options we might not get from the ACK */ + dhcp->offered_sn_mask.addr = 0; + dhcp->offered_gw_addr.addr = 0; + dhcp->offered_bc_addr.addr = 0; + + /* lease time given? */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_LEASE_TIME); + if (option_ptr != NULL) { + /* remember offered lease time */ + dhcp->offered_t0_lease = dhcp_get_option_long(option_ptr + 2); + } + /* renewal period given? */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T1); + if (option_ptr != NULL) { + /* remember given renewal period */ + dhcp->offered_t1_renew = dhcp_get_option_long(option_ptr + 2); + } else { + /* calculate safe periods for renewal */ + dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; + } + + /* renewal period given? */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_T2); + if (option_ptr != NULL) { + /* remember given rebind period */ + dhcp->offered_t2_rebind = dhcp_get_option_long(option_ptr + 2); + } else { + /* calculate safe periods for rebinding */ + dhcp->offered_t2_rebind = dhcp->offered_t0_lease; + } + + /* (y)our internet address */ + ip_addr_set(&dhcp->offered_ip_addr, &dhcp->msg_in->yiaddr); + +/** + * Patch #1308 + * TODO: we must check if the file field is not overloaded by DHCP options! + */ +#if 0 + /* boot server address */ + ip_addr_set(&dhcp->offered_si_addr, &dhcp->msg_in->siaddr); + /* boot file name */ + if (dhcp->msg_in->file[0]) { + dhcp->boot_file_name = mem_malloc(strlen(dhcp->msg_in->file) + 1); + strcpy(dhcp->boot_file_name, dhcp->msg_in->file); + } +#endif + + /* subnet mask */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_SUBNET_MASK); + /* subnet mask given? */ + if (option_ptr != NULL) { + dhcp->offered_sn_mask.addr = htonl(dhcp_get_option_long(&option_ptr[2])); + } + + /* gateway router */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_ROUTER); + if (option_ptr != NULL) { + dhcp->offered_gw_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); + } + + /* broadcast address */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_BROADCAST); + if (option_ptr != NULL) { + dhcp->offered_bc_addr.addr = htonl(dhcp_get_option_long(&option_ptr[2])); + } + + /* DNS servers */ + option_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_DNS_SERVER); + if (option_ptr != NULL) { + u8_t n; + dhcp->dns_count = dhcp_get_option_byte(&option_ptr[1]) / (u32_t)sizeof(struct ip_addr); + /* limit to at most DHCP_MAX_DNS DNS servers */ + if (dhcp->dns_count > DHCP_MAX_DNS) + dhcp->dns_count = DHCP_MAX_DNS; + for (n = 0; n < dhcp->dns_count; n++) { + dhcp->offered_dns_addr[n].addr = htonl(dhcp_get_option_long(&option_ptr[2 + n * 4])); +#if LWIP_DNS + dns_setserver( n, (struct ip_addr *)(&(dhcp->offered_dns_addr[n].addr))); +#endif /* LWIP_DNS */ + } +#if LWIP_DNS + dns_setserver( n, (struct ip_addr *)(&ip_addr_any)); +#endif /* LWIP_DNS */ + } +} + +/** + * Start DHCP negotiation for a network interface. + * + * If no DHCP client instance was attached to this interface, + * a new client is created first. If a DHCP client instance + * was already present, it restarts negotiation. + * + * @param netif The lwIP network interface + * @return lwIP error code + * - ERR_OK - No error + * - ERR_MEM - Out of memory + */ +err_t +dhcp_start(struct netif *netif) +{ + struct dhcp *dhcp; + err_t result = ERR_OK; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); + dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Remove the flag that says this netif is handled by DHCP, + it is set when we succeeded starting. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + /* check MTU of the netif */ + if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); + return ERR_MEM; + } + + /* no DHCP client attached yet? */ + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); + dhcp = mem_malloc(sizeof(struct dhcp)); + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); + return ERR_MEM; + } + /* store this dhcp client in the netif */ + netif->dhcp = dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); + /* already has DHCP client attached */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + } + LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL && + dhcp->options_in == NULL && dhcp->options_in_len == 0); + } + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* allocate UDP PCB */ + dhcp->pcb = udp_new(); + if (dhcp->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); + mem_free((void *)dhcp); + netif->dhcp = dhcp = NULL; + return ERR_MEM; + } +#if IP_SOF_BROADCAST + dhcp->pcb->so_options|=SOF_BROADCAST; +#endif /* IP_SOF_BROADCAST */ + /* set up local and remote port for the pcb */ + udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + /* set up the recv callback and argument */ + udp_recv(dhcp->pcb, dhcp_recv, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); + /* (re)start the DHCP negotiation */ + result = dhcp_discover(netif); + if (result != ERR_OK) { + /* free resources allocated above */ + dhcp_stop(netif); + return ERR_MEM; + } + /* Set the flag that says this netif is handled by DHCP. */ + netif->flags |= NETIF_FLAG_DHCP; + return result; +} + +/** + * Inform a DHCP server of our manual configuration. + * + * This informs DHCP servers of our fixed IP address configuration + * by sending an INFORM message. It does not involve DHCP address + * configuration, it is just here to be nice to the network. + * + * @param netif The lwIP network interface + */ +void +dhcp_inform(struct netif *netif) +{ + struct dhcp *dhcp, *old_dhcp; + err_t result = ERR_OK; + dhcp = mem_malloc(sizeof(struct dhcp)); + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not allocate dhcp\n")); + return; + } + memset(dhcp, 0, sizeof(struct dhcp)); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): allocated dhcp\n")); + dhcp->pcb = udp_new(); + if (dhcp->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); + goto free_dhcp_and_return; + } + old_dhcp = netif->dhcp; + netif->dhcp = dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_INFORM); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + +#if IP_SOF_BROADCAST + dhcp->pcb->so_options|=SOF_BROADCAST; +#endif /* IP_SOF_BROADCAST */ + udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); + } + + udp_remove(dhcp->pcb); + dhcp->pcb = NULL; + netif->dhcp = old_dhcp; +free_dhcp_and_return: + mem_free((void *)dhcp); +} + +/** Handle a possible change in the network configuration. + * + * This enters the REBOOTING state to verify that the currently bound + * address is still valid. + */ +void +dhcp_network_changed(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + if (!dhcp) + return; + switch (dhcp->state) { + case DHCP_REBINDING: + case DHCP_RENEWING: + case DHCP_BOUND: + case DHCP_REBOOTING: + netif_set_down(netif); + dhcp->tries = 0; + dhcp_reboot(netif); + break; + case DHCP_OFF: + /* stay off */ + break; + default: + dhcp->tries = 0; + dhcp_discover(netif); + break; + } +} + +#if DHCP_DOES_ARP_CHECK +/** + * Match an ARP reply with the offered IP address. + * + * @param netif the network interface on which the reply was received + * @param addr The IP address we received a reply from + */ +void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr) +{ + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); + /* is a DHCP client doing an ARP check? */ + if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", addr->addr)); + /* did a host respond with the address we + were offered by the DHCP server? */ + if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { + /* we will not accept the offered address */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); + dhcp_decline(netif); + } + } +} + +/** + * Decline an offered lease. + * + * Tell the DHCP server we do not accept the offered address. + * One reason to decline the lease is when we find out the address + * is already in use by another host (through ARP). + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_decline(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_DECLINE); + + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option_trailer(dhcp); + /* resize pbuf to reflect true size of options */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* per section 4.4.4, broadcast DECLINE messages */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_decline: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = 10*1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} +#endif + + +/** + * Start the DHCP process, discover a DHCP server. + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_discover(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); + ip_addr_set(&dhcp->offered_ip_addr, IP_ADDR_ANY); + dhcp_set_state(dhcp, DHCP_SELECTING); + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_DISCOVER); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + + dhcp_option_trailer(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); + } + dhcp->tries++; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; + autoip_start(netif); + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Bind the interface to the offered IP address. + * + * @param netif network interface to bind to the offered address + */ +static void +dhcp_bind(struct netif *netif) +{ + u32_t timeout; + struct dhcp *dhcp; + struct ip_addr sn_mask, gw_addr; + LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + + /* temporary DHCP lease? */ + if (dhcp->offered_t1_renew != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); + timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t1_timeout = (u16_t)timeout; + if (dhcp->t1_timeout == 0) { + dhcp->t1_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); + } + /* set renewal period timer */ + if (dhcp->offered_t2_rebind != 0xffffffffUL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); + timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t2_timeout = (u16_t)timeout; + if (dhcp->t2_timeout == 0) { + dhcp->t2_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); + } + /* copy offered network mask */ + ip_addr_set(&sn_mask, &dhcp->offered_sn_mask); + + /* subnet mask not given? */ + /* TODO: this is not a valid check. what if the network mask is 0? */ + if (sn_mask.addr == 0) { + /* choose a safe subnet mask given the network class */ + u8_t first_octet = ip4_addr1(&sn_mask); + if (first_octet <= 127) { + sn_mask.addr = htonl(0xff000000); + } else if (first_octet >= 192) { + sn_mask.addr = htonl(0xffffff00); + } else { + sn_mask.addr = htonl(0xffff0000); + } + } + + ip_addr_set(&gw_addr, &dhcp->offered_gw_addr); + /* gateway address not given? */ + if (gw_addr.addr == 0) { + /* copy network address */ + gw_addr.addr = (dhcp->offered_ip_addr.addr & sn_mask.addr); + /* use first host address on network as gateway */ + gw_addr.addr |= htonl(0x00000001); + } + +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", dhcp->offered_ip_addr.addr)); + netif_set_ipaddr(netif, &dhcp->offered_ip_addr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", sn_mask.addr)); + netif_set_netmask(netif, &sn_mask); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", gw_addr.addr)); + netif_set_gw(netif, &gw_addr); + /* bring the interface up */ + netif_set_up(netif); + /* netif is now bound to DHCP leased address */ + dhcp_set_state(dhcp, DHCP_BOUND); +} + +/** + * Renew an existing DHCP lease at the involved DHCP server. + * + * @param netif network interface which must renew its lease + */ +err_t +dhcp_renew(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; +#if LWIP_NETIF_HOSTNAME + const char *p; +#endif /* LWIP_NETIF_HOSTNAME */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); + dhcp_set_state(dhcp, DHCP_RENEWING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_REQUEST); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if LWIP_NETIF_HOSTNAME + p = (const char*)netif->hostname; + if (p != NULL) { + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p)); + while (*p) { + dhcp_option_byte(dhcp, *p++); + } + } +#endif /* LWIP_NETIF_HOSTNAME */ + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); +#endif + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + /* append DHCP message trailer */ + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); + } + dhcp->tries++; + /* back-off on retries, but to a maximum of 20 seconds */ + msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Rebind with a DHCP server for an existing DHCP lease. + * + * @param netif network interface which must rebind with a DHCP server + */ +static err_t +dhcp_rebind(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; +#if LWIP_NETIF_HOSTNAME + const char *p; +#endif /* LWIP_NETIF_HOSTNAME */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); + dhcp_set_state(dhcp, DHCP_REBINDING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_REQUEST); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if LWIP_NETIF_HOSTNAME + p = (const char*)netif->hostname; + if (p != NULL) { + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, strlen(p)); + while (*p) { + dhcp_option_byte(dhcp, *p++); + } + } +#endif /* LWIP_NETIF_HOSTNAME */ + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Enter REBOOTING state to verify an existing lease + * + * @param netif network interface which must reboot + */ +static err_t +dhcp_reboot(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); + dhcp_set_state(dhcp, DHCP_REBOOTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_REQUEST); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, 576); + + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_OFF); + /* clean old DHCP offer */ + dhcp->server_ip_addr.addr = 0; + dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0; + dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0; + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + dhcp->dns_count = 0; + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_RELEASE); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release_unicast(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_RELEASING); + /* clean old DHCP offer *//* + dhcp->server_ip_addr.addr = 0; + dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0; + dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0; + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + dhcp->dns_count = 0;*/ + + /* create and initialize the DHCP message header */ + result = dhcp_create_request(netif); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_RELEASE); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_request(netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Remove the DHCP client from the interface. + * + * @param netif The network interface to stop DHCP on + */ +void +dhcp_stop(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); + /* Remove the flag that says this netif is handled by DHCP. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); + /* netif is DHCP configured? */ + if (dhcp != NULL) { +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + dhcp->pcb = NULL; + } + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL && + dhcp->options_in == NULL && dhcp->options_in_len == 0); + mem_free((void *)dhcp); + netif->dhcp = NULL; + } +} + +/* + * Set the DHCP state of a DHCP client. + * + * If the state changed, reset the number of tries. + * + * TODO: we might also want to reset the timeout here? + */ +static void +dhcp_set_state(struct dhcp *dhcp, u8_t new_state) +{ + if (new_state != dhcp->state) { + dhcp->state = new_state; + dhcp->tries = 0; + } +} + +/* + * Concatenate an option type and length field to the outgoing + * DHCP message. + * + */ +static void +dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) +{ + LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = option_type; + dhcp->msg_out->options[dhcp->options_out_len++] = option_len; +} +/* + * Concatenate a single byte to the outgoing DHCP message. + * + */ +static void +dhcp_option_byte(struct dhcp *dhcp, u8_t value) +{ + LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = value; +} + +static void +dhcp_option_short(struct dhcp *dhcp, u16_t value) +{ + LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); +} + +static void +dhcp_option_long(struct dhcp *dhcp, u32_t value) +{ + LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); +} + +/** + * Extract the DHCP message and the DHCP options. + * + * Extract the DHCP message and the DHCP options, each into a contiguous + * piece of memory. As a DHCP message is variable sized by its options, + * and also allows overriding some fields for options, the easy approach + * is to first unfold the options into a conitguous piece of memory, and + * use that further on. + * + */ +static err_t +dhcp_unfold_reply(struct dhcp *dhcp, struct pbuf *p) +{ + u16_t ret; + LWIP_ERROR("dhcp != NULL", (dhcp != NULL), return ERR_ARG;); + /* free any left-overs from previous unfolds */ + dhcp_free_reply(dhcp); + /* options present? */ + if (p->tot_len > (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)) { + dhcp->options_in_len = p->tot_len - (sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); + dhcp->options_in = mem_malloc(dhcp->options_in_len); + if (dhcp->options_in == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_unfold_reply(): could not allocate dhcp->options\n")); + dhcp->options_in_len = 0; + return ERR_MEM; + } + } + dhcp->msg_in = mem_malloc(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); + if (dhcp->msg_in == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_unfold_reply(): could not allocate dhcp->msg_in\n")); + if (dhcp->options_in != NULL) { + mem_free(dhcp->options_in); + dhcp->options_in = NULL; + dhcp->options_in_len = 0; + } + return ERR_MEM; + } + + /** copy the DHCP message without options */ + ret = pbuf_copy_partial(p, dhcp->msg_in, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN, 0); + LWIP_ASSERT("ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN", ret == sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes into dhcp->msg_in[]\n", + sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN)); + + if (dhcp->options_in != NULL) { + /** copy the DHCP options */ + ret = pbuf_copy_partial(p, dhcp->options_in, dhcp->options_in_len, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN); + LWIP_ASSERT("ret == dhcp->options_in_len", ret == dhcp->options_in_len); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_unfold_reply(): copied %"U16_F" bytes to dhcp->options_in[]\n", + dhcp->options_in_len)); + } + LWIP_UNUSED_ARG(ret); + return ERR_OK; +} + +/** + * Free the incoming DHCP message including contiguous copy of + * its DHCP options. + */ +static void dhcp_free_reply(struct dhcp *dhcp) +{ + if (dhcp->msg_in != NULL) { + mem_free((void *)dhcp->msg_in); + dhcp->msg_in = NULL; + } + if (dhcp->options_in) { + mem_free(dhcp->options_in); + dhcp->options_in = NULL; + dhcp->options_in_len = 0; + } + LWIP_DEBUGF(DHCP_DEBUG, ("dhcp_free_reply(): free'd\n")); +} + +/** + * If an incoming DHCP message is in response to us, then trigger the state machine + */ +static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + struct netif *netif = (struct netif *)arg; + struct dhcp *dhcp = netif->dhcp; + struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; + u8_t *options_ptr; + u8_t msg_type; + u8_t i; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, + (u16_t)(ntohl(addr->addr) >> 24 & 0xff), (u16_t)(ntohl(addr->addr) >> 16 & 0xff), + (u16_t)(ntohl(addr->addr) >> 8 & 0xff), (u16_t)(ntohl(addr->addr) & 0xff), port)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); + /* prevent warnings about unused arguments */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL && + dhcp->options_in == NULL && dhcp->options_in_len == 0); + + if (p->len < DHCP_MIN_REPLY_LEN) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message too short\n")); + goto free_pbuf_and_return; + } + + if (reply_msg->op != DHCP_BOOTREPLY) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); + goto free_pbuf_and_return; + } + /* iterate through hardware address and match against DHCP message */ + for (i = 0; i < netif->hwaddr_len; i++) { + if (netif->hwaddr[i] != reply_msg->chaddr[i]) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", + (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); + goto free_pbuf_and_return; + } + } + /* match transaction ID against what we expected */ + if (ntohl(reply_msg->xid) != dhcp->xid) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid)); + goto free_pbuf_and_return; + } + /* option fields could be unfold? */ + if (dhcp_unfold_reply(dhcp, p) != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("problem unfolding DHCP message - too short on memory?\n")); + goto free_pbuf_and_return; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); + /* obtain pointer to DHCP message type */ + options_ptr = dhcp_get_option_ptr(dhcp, DHCP_OPTION_MESSAGE_TYPE); + if (options_ptr == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); + goto free_pbuf_and_return; + } + + /* read DHCP message type */ + msg_type = dhcp_get_option_byte(options_ptr + 2); + /* message type is DHCP ACK? */ + if (msg_type == DHCP_ACK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); + /* in requesting state? */ + if (dhcp->state == DHCP_REQUESTING) { + dhcp_handle_ack(netif); + dhcp->request_timeout = 0; +#if DHCP_DOES_ARP_CHECK + /* check if the acknowledged lease address is already in use */ + dhcp_check(netif); +#else + /* bind interface to the acknowledged lease address */ + dhcp_bind(netif); +#endif + } + /* already bound to the given lease address? */ + else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { + dhcp->request_timeout = 0; + dhcp_bind(netif); + } + } + /* received a DHCP_NAK in appropriate state? */ + else if ((msg_type == DHCP_NAK) && + ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || + (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); + dhcp->request_timeout = 0; + dhcp_handle_nak(netif); + } + /* received a DHCP_OFFER in DHCP_SELECTING state? */ + else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n")); + dhcp->request_timeout = 0; + /* remember offered lease */ + dhcp_handle_offer(netif); + } +free_pbuf_and_return: + dhcp_free_reply(dhcp); + pbuf_free(p); +} + +/** + * Create a DHCP request, fill in common headers + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_create_request(struct netif *netif) +{ + struct dhcp *dhcp; + u16_t i; +#ifndef DHCP_GLOBAL_XID + /** default global transaction identifier starting value (easy to match + * with a packet analyser). We simply increment for each new request. + * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one + * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ + static u32_t xid = 0xABCD0000; +#else + static u32_t xid; + static u8_t xid_initialised = 0; + if (!xid_initialised) { + xid = DHCP_GLOBAL_XID; + xid_initialised = !xid_initialised; + } +#endif + LWIP_ERROR("dhcp_create_request: netif != NULL", (netif != NULL), return ERR_ARG;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_create_request: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); + LWIP_ASSERT("dhcp_create_request: dhcp->p_out == NULL", dhcp->p_out == NULL); + LWIP_ASSERT("dhcp_create_request: dhcp->msg_out == NULL", dhcp->msg_out == NULL); + dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); + if (dhcp->p_out == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_create_request(): could not allocate pbuf\n")); + return ERR_MEM; + } + LWIP_ASSERT("dhcp_create_request: check that first pbuf can hold struct dhcp_msg", + (dhcp->p_out->len >= sizeof(struct dhcp_msg))); + + /* reuse transaction identifier in retransmissions */ + if (dhcp->tries==0) + xid++; + dhcp->xid = xid; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("transaction id xid(%"X32_F")\n", xid)); + + dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; + + dhcp->msg_out->op = DHCP_BOOTREQUEST; + /* TODO: make link layer independent */ + dhcp->msg_out->htype = DHCP_HTYPE_ETH; + /* TODO: make link layer independent */ + dhcp->msg_out->hlen = DHCP_HLEN_ETH; + dhcp->msg_out->hops = 0; + dhcp->msg_out->xid = htonl(dhcp->xid); + dhcp->msg_out->secs = 0; + dhcp->msg_out->flags = 0; + dhcp->msg_out->ciaddr.addr = 0; + if (dhcp->state==DHCP_BOUND || dhcp->state==DHCP_RENEWING || dhcp->state==DHCP_REBINDING || dhcp->state == DHCP_RELEASING) { + dhcp->msg_out->ciaddr.addr = netif->ip_addr.addr; + } + dhcp->msg_out->yiaddr.addr = 0; + dhcp->msg_out->siaddr.addr = 0; + dhcp->msg_out->giaddr.addr = 0; + for (i = 0; i < DHCP_CHADDR_LEN; i++) { + /* copy netif hardware address, pad with zeroes */ + dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/; + } + for (i = 0; i < DHCP_SNAME_LEN; i++) { + dhcp->msg_out->sname[i] = 0; + } + for (i = 0; i < DHCP_FILE_LEN; i++) { + dhcp->msg_out->file[i] = 0; + } + dhcp->msg_out->cookie = htonl(0x63825363UL); + dhcp->options_out_len = 0; + /* fill options field with an incrementing array (for debugging purposes) */ + for (i = 0; i < DHCP_OPTIONS_LEN; i++) { + dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ + } + return ERR_OK; +} + +/** + * Free previously allocated memory used to send a DHCP request. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_delete_request(struct netif *netif) +{ + struct dhcp *dhcp; + LWIP_ERROR("dhcp_delete_request: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_delete_request: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_delete_request: dhcp->p_out != NULL", dhcp->p_out != NULL); + LWIP_ASSERT("dhcp_delete_request: dhcp->msg_out != NULL", dhcp->msg_out != NULL); + if (dhcp->p_out != NULL) { + pbuf_free(dhcp->p_out); + } + dhcp->p_out = NULL; + dhcp->msg_out = NULL; +} + +/** + * Add a DHCP message trailer + * + * Adds the END option to the DHCP message, and if + * necessary, up to three padding bytes. + * + * @param dhcp DHCP state structure + */ +static void +dhcp_option_trailer(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); + LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; + /* packet is too small, or not 4 byte aligned? */ + while ((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) { + /* LWIP_DEBUGF(DHCP_DEBUG,("dhcp_option_trailer:dhcp->options_out_len=%"U16_F", DHCP_OPTIONS_LEN=%"U16_F, dhcp->options_out_len, DHCP_OPTIONS_LEN)); */ + LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + /* add a fill/padding byte */ + dhcp->msg_out->options[dhcp->options_out_len++] = 0; + } +} + +/** + * Find the offset of a DHCP option inside the DHCP message. + * + * @param dhcp DHCP client + * @param option_type + * + * @return a byte offset into the UDP message where the option was found, or + * zero if the given option was not found. + */ +static u8_t *dhcp_get_option_ptr(struct dhcp *dhcp, u8_t option_type) +{ + u8_t overload = DHCP_OVERLOAD_NONE; + + /* options available? */ + if ((dhcp->options_in != NULL) && (dhcp->options_in_len > 0)) { + /* start with options field */ + u8_t *options = (u8_t *)dhcp->options_in; + u16_t offset = 0; + /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ + while ((offset < dhcp->options_in_len) && (options[offset] != DHCP_OPTION_END)) { + /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ + /* are the sname and/or file field overloaded with options? */ + if (options[offset] == DHCP_OPTION_OVERLOAD) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded message detected\n")); + /* skip option type and length */ + offset += 2; + overload = options[offset++]; + } + /* requested option found */ + else if (options[offset] == option_type) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset %"U16_F" in options\n", offset)); + return &options[offset]; + /* skip option */ + } else { + LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", options[offset])); + /* skip option type */ + offset++; + /* skip option length, and then length bytes */ + offset += 1 + options[offset]; + } + } + /* is this an overloaded message? */ + if (overload != DHCP_OVERLOAD_NONE) { + u16_t field_len; + if (overload == DHCP_OVERLOAD_FILE) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); + options = (u8_t *)&dhcp->msg_in->file; + field_len = DHCP_FILE_LEN; + } else if (overload == DHCP_OVERLOAD_SNAME) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); + options = (u8_t *)&dhcp->msg_in->sname; + field_len = DHCP_SNAME_LEN; + /* TODO: check if else if () is necessary */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); + options = (u8_t *)&dhcp->msg_in->sname; + field_len = DHCP_FILE_LEN + DHCP_SNAME_LEN; + } + offset = 0; + + /* at least 1 byte to read and no end marker */ + while ((offset < field_len) && (options[offset] != DHCP_OPTION_END)) { + if (options[offset] == option_type) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("option found at offset=%"U16_F"\n", offset)); + return &options[offset]; + /* skip option */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("skipping option %"U16_F"\n", options[offset])); + /* skip option type */ + offset++; + offset += 1 + options[offset]; + } + } + } + } + return NULL; +} + +/** + * Return the byte of DHCP option data. + * + * @param client DHCP client. + * @param ptr pointer obtained by dhcp_get_option_ptr(). + * + * @return byte value at the given address. + */ +static u8_t +dhcp_get_option_byte(u8_t *ptr) +{ + LWIP_DEBUGF(DHCP_DEBUG, ("option byte value=%"U16_F"\n", (u16_t)(*ptr))); + return *ptr; +} + +#if 0 /* currently unused */ +/** + * Return the 16-bit value of DHCP option data. + * + * @param client DHCP client. + * @param ptr pointer obtained by dhcp_get_option_ptr(). + * + * @return byte value at the given address. + */ +static u16_t +dhcp_get_option_short(u8_t *ptr) +{ + u16_t value; + value = *ptr++ << 8; + value |= *ptr; + LWIP_DEBUGF(DHCP_DEBUG, ("option short value=%"U16_F"\n", value)); + return value; +} +#endif + +/** + * Return the 32-bit value of DHCP option data. + * + * @param client DHCP client. + * @param ptr pointer obtained by dhcp_get_option_ptr(). + * + * @return byte value at the given address. + */ +static u32_t dhcp_get_option_long(u8_t *ptr) +{ + u32_t value; + value = (u32_t)(*ptr++) << 24; + value |= (u32_t)(*ptr++) << 16; + value |= (u32_t)(*ptr++) << 8; + value |= (u32_t)(*ptr++); + LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%"U32_F"\n", value)); + return value; +} + +#endif /* LWIP_DHCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dns.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dns.c new file mode 100644 index 0000000..b18a360 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/dns.c @@ -0,0 +1,980 @@ +/* + * @file + * DNS - host name to IP address resolver. + * + */ + +/** + + * This file implements a DNS host name to IP address resolver. + + * Port to lwIP from uIP + * by Jim Pettinato April 2007 + + * uIP version Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * DNS.C + * + * The lwIP DNS resolver functions are used to lookup a host name and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the dns_lookup() function. + * New hostnames can be resolved using the dns_query() function. + * + * The lwIP version of the resolver also adds a non-blocking version of + * gethostbyname() that will work with a raw API application. This function + * checks for an IP address string first and converts it if it is valid. + * gethostbyname() then does a dns_lookup() to see if the name is + * already in the table. If so, the IP is returned. If not, a query is + * issued and the function returns with a ERR_INPROGRESS status. The app + * using the dns client must then go into a waiting state. + * + * Once a hostname has been resolved (or found to be non-existent), + * the resolver code calls a specified callback function (which + * must be implemented by the module that uses the resolver). + */ + +/*----------------------------------------------------------------------------- + * RFC 1035 - Domain names - implementation and specification + * RFC 2181 - Clarifications to the DNS Specification + *----------------------------------------------------------------------------*/ + +/** @todo: define good default values (rfc compliance) */ +/** @todo: improve answer parsing, more checkings... */ +/** @todo: check RFC1035 - 7.3. Processing responses */ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/mem.h" +#include "lwip/dns.h" + +#include + +/** DNS server IP address */ +#ifndef DNS_SERVER_ADDRESS +#define DNS_SERVER_ADDRESS inet_addr("208.67.222.222") /* resolver1.opendns.com */ +#endif + +/** DNS server port address */ +#ifndef DNS_SERVER_PORT +#define DNS_SERVER_PORT 53 +#endif + +/** DNS maximum number of retries when asking for a name, before "timeout". */ +#ifndef DNS_MAX_RETRIES +#define DNS_MAX_RETRIES 4 +#endif + +/** DNS resource record max. TTL (one week as default) */ +#ifndef DNS_MAX_TTL +#define DNS_MAX_TTL 604800 +#endif + +/* DNS protocol flags */ +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + +/* DNS protocol states */ +#define DNS_STATE_UNUSED 0 +#define DNS_STATE_NEW 1 +#define DNS_STATE_ASKING 2 +#define DNS_STATE_DONE 3 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS message header */ +struct dns_hdr { + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u8_t flags1); + PACK_STRUCT_FIELD(u8_t flags2); + PACK_STRUCT_FIELD(u16_t numquestions); + PACK_STRUCT_FIELD(u16_t numanswers); + PACK_STRUCT_FIELD(u16_t numauthrr); + PACK_STRUCT_FIELD(u16_t numextrarr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_HDR 12 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS query message structure */ +struct dns_query { + /* DNS query record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + PACK_STRUCT_FIELD(u16_t type); + PACK_STRUCT_FIELD(u16_t class); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_QUERY 4 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS answer message structure */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + PACK_STRUCT_FIELD(u16_t type); + PACK_STRUCT_FIELD(u16_t class); + PACK_STRUCT_FIELD(u32_t ttl); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_ANSWER 10 + +/** DNS table entry */ +struct dns_table_entry { + u8_t state; + u8_t numdns; + u8_t tmr; + u8_t retries; + u8_t seqno; + u8_t err; + u32_t ttl; + char name[DNS_MAX_NAME_LENGTH]; + struct ip_addr ipaddr; + /* pointer to callback on DNS query done */ + dns_found_callback found; + void *arg; +}; + +#if DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + u32_t addr; + struct local_hostlist_entry *next; +}; + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Local host-list. For hostnames in this list, no + * external name resolution is performed */ +static struct local_hostlist_entry *local_hostlist_dynamic; +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE +#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST +#define DNS_LOCAL_HOSTLIST_STORAGE_POST +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ +DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] + DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; + +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +static void dns_init_local(); +#endif /* DNS_LOCAL_HOSTLIST */ + + +/* forward declarations */ +static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); +static void dns_check_entries(void); + +/*----------------------------------------------------------------------------- + * Globales + *----------------------------------------------------------------------------*/ + +/* DNS variables */ +static struct udp_pcb *dns_pcb; +static u8_t dns_seqno; +static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; +static struct ip_addr dns_servers[DNS_MAX_SERVERS]; + +#if (DNS_USES_STATIC_BUF == 1) +static u8_t dns_payload[DNS_MSG_SIZE]; +#endif /* (DNS_USES_STATIC_BUF == 1) */ + +/** + * Initialize the resolver: set up the UDP pcb and configure the default server + * (DNS_SERVER_ADDRESS). + */ +void +dns_init() +{ + struct ip_addr dnsserver; + + /* initialize default DNS server address */ + dnsserver.addr = DNS_SERVER_ADDRESS; + + LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); + + /* if dns client not yet initialized... */ + if (dns_pcb == NULL) { + dns_pcb = udp_new(); + + if (dns_pcb != NULL) { + /* initialize DNS table not needed (initialized to zero since it is a + * global variable) */ + LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", + DNS_STATE_UNUSED == 0); + + /* initialize DNS client */ + udp_bind(dns_pcb, IP_ADDR_ANY, 0); + udp_recv(dns_pcb, dns_recv, NULL); + + /* initialize default DNS primary server */ + dns_setserver(0, &dnsserver); + } + } +#if DNS_LOCAL_HOSTLIST + dns_init_local(); +#endif +} + +/** + * Initialize one of the DNS servers. + * + * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS + * @param dnsserver IP address of the DNS server to set + */ +void +dns_setserver(u8_t numdns, struct ip_addr *dnsserver) +{ + if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) && + (dnsserver != NULL) && (dnsserver->addr !=0 )) { + dns_servers[numdns] = (*dnsserver); + } +} + +/** + * Obtain one of the currently configured DNS server. + * + * @param numdns the index of the DNS server + * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS + * server has not been configured. + */ +struct ip_addr +dns_getserver(u8_t numdns) +{ + if (numdns < DNS_MAX_SERVERS) { + return dns_servers[numdns]; + } else { + return *IP_ADDR_ANY; + } +} + +/** + * The DNS resolver client timer - handle retries and timeouts and should + * be called every DNS_TMR_INTERVAL milliseconds (every second by default). + */ +void +dns_tmr(void) +{ + if (dns_pcb != NULL) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); + dns_check_entries(); + } +} + +#if DNS_LOCAL_HOSTLIST +static void +dns_init_local() +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) + int i; + struct local_hostlist_entry *entry; + /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ + struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; + for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { + entry = mem_malloc(sizeof(struct local_hostlist_entry)); + LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); + if (entry != NULL) { + struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; + entry->name = init_entry->name; + entry->addr = init_entry->addr; + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ +} + +/** + * Scans the local host-list for a hostname. + * + * @param hostname Hostname to look for in the local host-list + * @return The first IP address for the hostname in the local host-list or + * INADDR_NONE if not found. + */ +static u32_t +dns_lookup_local(const char *hostname) +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC + struct local_hostlist_entry *entry = local_hostlist_dynamic; + while(entry != NULL) { + if(strcmp(entry->name, hostname) == 0) { + return entry->addr; + } + entry = entry->next; + } +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + int i; + for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { + if(strcmp(local_hostlist_static[i].name, hostname) == 0) { + return local_hostlist_static[i].addr; + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + return INADDR_NONE; +} + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Remove all entries from the local host-list for a specific hostname + * and/or IP addess + * + * @param hostname hostname for which entries shall be removed from the local + * host-list + * @param addr address for which entries shall be removed from the local host-list + * @return the number of removed entries + */ +int +dns_local_removehost(const char *hostname, const struct ip_addr *addr) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist_dynamic; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (((hostname == NULL) || !strcmp(entry->name, hostname)) && + ((addr == NULL) || (entry->addr == addr->addr))) { + struct local_hostlist_entry *free_entry; + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist_dynamic = entry->next; + } + free_entry = entry; + entry = entry->next; + mem_free(free_entry); + removed++; + } else { + last_entry = entry; + entry = entry->next; + } + } + return removed; +} + +/** + * Add a hostname/IP address pair to the local host-list. + * Duplicates are not checked. + * + * @param hostname hostname of the new entry + * @param addr IP address of the new entry + * @return ERR_OK if succeeded or ERR_MEM on memory error + */ +err_t +dns_local_addhost(const char *hostname, const struct ip_addr *addr) +{ + struct local_hostlist_entry *entry; + entry = mem_malloc(sizeof(struct local_hostlist_entry)); + if (entry == NULL) { + return ERR_MEM; + } + entry->name = hostname; + entry->addr = addr->addr; + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + return ERR_OK; +} +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** + * Look up a hostname in the array of known hostnames. + * + * @note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function dns_enqueue() can be used to send a query + * for a hostname. + * + * @param name the hostname to look up + * @return the hostname's IP address, as u32_t (instead of struct ip_addr to + * better check for failure: != INADDR_NONE) or INADDR_NONE if the hostname + * was not found in the cached dns_table. + */ +static u32_t +dns_lookup(const char *name) +{ + u8_t i; +#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) + u32_t addr; +#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ +#if DNS_LOCAL_HOSTLIST + if ((addr = dns_lookup_local(name)) != INADDR_NONE) { + return addr; + } +#endif /* DNS_LOCAL_HOSTLIST */ +#ifdef DNS_LOOKUP_LOCAL_EXTERN + if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != INADDR_NONE) { + return addr; + } +#endif /* DNS_LOOKUP_LOCAL_EXTERN */ + + /* Walk through name list, return entry if found. If not, return NULL. */ + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + if ((dns_table[i].state == DNS_STATE_DONE) && + (strcmp(name, dns_table[i].name) == 0)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); + ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + return dns_table[i].ipaddr.addr; + } + } + + return INADDR_NONE; +} + +#if DNS_DOES_NAME_CHECK +/** + * Compare the "dotted" name "query" with the encoded name "response" + * to make sure an answer from the DNS server matches the current dns_table + * entry (otherwise, answers might arrive late for hostname not on the list + * any more). + * + * @param query hostname (not encoded) from the dns_table + * @param response encoded hostname in the DNS response + * @return 0: names equal; 1: names differ + */ +static u8_t +dns_compare_name(unsigned char *query, unsigned char *response) +{ + unsigned char n; + + do { + n = *response++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + if ((*query) != (*response)) { + return 1; + } + ++response; + ++query; + --n; + }; + ++query; + } + } while (*response != 0); + + return 0; +} +#endif /* DNS_DOES_NAME_CHECK */ + +/** + * Walk through a compact encoded DNS name and return the end of the name. + * + * @param query encoded DNS name in the DNS server response + * @return end of the name + */ +static unsigned char * +dns_parse_name(unsigned char *query) +{ + unsigned char n; + + do { + n = *query++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + ++query; + --n; + }; + } + } while (*query != 0); + + return query + 1; +} + +/** + * Send a DNS query packet. + * + * @param numdns index of the DNS server in the dns_servers table + * @param name hostname to query + * @param id index of the hostname in dns_table, used as transaction ID in the + * DNS query packet + * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise + */ +static err_t +dns_send(u8_t numdns, const char* name, u8_t id) +{ + err_t err; + struct dns_hdr *hdr; + struct dns_query qry; + struct pbuf *p; + char *query, *nptr; + const char *pHostname; + u8_t n; + + LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", + (u16_t)(numdns), name)); + LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); + LWIP_ASSERT("dns server has no IP address set", dns_servers[numdns].addr != 0); + + /* if here, we have either a new query or a retry on a previous query to process */ + p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH + + SIZEOF_DNS_QUERY, PBUF_RAM); + if (p != NULL) { + LWIP_ASSERT("pbuf must be in one piece", p->next == NULL); + /* fill dns header */ + hdr = (struct dns_hdr*)p->payload; + memset(hdr, 0, SIZEOF_DNS_HDR); + hdr->id = htons(id); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = htons(1); + query = (char*)hdr + SIZEOF_DNS_HDR; + pHostname = name; + --pHostname; + + /* convert hostname into suitable query format. */ + do { + ++pHostname; + nptr = query; + ++query; + for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) { + *query = *pHostname; + ++query; + ++n; + } + *nptr = n; + } while(*pHostname != 0); + *query++='\0'; + + /* fill dns query */ + qry.type = htons(DNS_RRTYPE_A); + qry.class = htons(DNS_RRCLASS_IN); + MEMCPY( query, &qry, SIZEOF_DNS_QUERY); + + /* resize pbuf to the exact dns query */ + pbuf_realloc(p, (query + SIZEOF_DNS_QUERY) - ((char*)(p->payload))); + + /* connect to the server for faster receiving */ + udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT); + /* send dns packet */ + err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT); + + /* free pbuf */ + pbuf_free(p); + } else { + err = ERR_MEM; + } + + return err; +} + +/** + * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. + * Check an entry in the dns_table: + * - send out query for new entries + * - retry old pending entries on timeout (also with different servers) + * - remove completed entries from the table if their TTL has expired + * + * @param i index of the dns_table entry to check + */ +static void +dns_check_entry(u8_t i) +{ + struct dns_table_entry *pEntry = &dns_table[i]; + + LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); + + switch(pEntry->state) { + + case DNS_STATE_NEW: { + /* initialize new entry */ + pEntry->state = DNS_STATE_ASKING; + pEntry->numdns = 0; + pEntry->tmr = 1; + pEntry->retries = 0; + + /* send DNS packet for this entry */ + dns_send(pEntry->numdns, pEntry->name, i); + break; + } + + case DNS_STATE_ASKING: { + if (--pEntry->tmr == 0) { + if (++pEntry->retries == DNS_MAX_RETRIES) { + if ((pEntry->numdns+1numdns+1].addr!=0)) { + /* change of server */ + pEntry->numdns++; + pEntry->tmr = 1; + pEntry->retries = 0; + break; + } else { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name)); + /* call specified callback function if provided */ + if (pEntry->found) + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + break; + } + } + + /* wait longer for the next retry */ + pEntry->tmr = pEntry->retries; + + /* send DNS packet for this entry */ + dns_send(pEntry->numdns, pEntry->name, i); + } + break; + } + + case DNS_STATE_DONE: { + /* if the time to live is nul */ + if (--pEntry->ttl == 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name)); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + } + break; + } + case DNS_STATE_UNUSED: + /* nothing to do */ + break; + default: + LWIP_ASSERT("unknown dns_table entry state:", 0); + break; + } +} + +/** + * Call dns_check_entry for each entry in dns_table - check all entries. + */ +static void +dns_check_entries(void) +{ + u8_t i; + + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + dns_check_entry(i); + } +} + +/** + * Receive input function for DNS response packets arriving for the dns UDP pcb. + * + * @params see udp.h + */ +static void +dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + u8_t i; + char *pHostname; + struct dns_hdr *hdr; + struct dns_answer ans; + struct dns_table_entry *pEntry; + u8_t nquestions, nanswers; +#if (DNS_USES_STATIC_BUF == 0) + u8_t dns_payload[DNS_MSG_SIZE]; +#endif /* (DNS_USES_STATIC_BUF == 0) */ +#if (DNS_USES_STATIC_BUF == 2) + u8_t* dns_payload; +#endif /* (DNS_USES_STATIC_BUF == 2) */ + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + /* is the dns message too big ? */ + if (p->tot_len > DNS_MSG_SIZE) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); + /* free pbuf and return */ + goto memerr1; + } + + /* is the dns message big enough ? */ + if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); + /* free pbuf and return */ + goto memerr1; + } + +#if (DNS_USES_STATIC_BUF == 2) + dns_payload = mem_malloc(p->tot_len); + if (dns_payload == NULL) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: mem_malloc error\n")); + /* free pbuf and return */ + goto memerr1; + } +#endif /* (DNS_USES_STATIC_BUF == 2) */ + + /* copy dns payload inside static buffer for processing */ + if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) { + /* The ID in the DNS header should be our entry into the name table. */ + hdr = (struct dns_hdr*)dns_payload; + i = htons(hdr->id); + if (i < DNS_TABLE_SIZE) { + pEntry = &dns_table[i]; + if(pEntry->state == DNS_STATE_ASKING) { + /* This entry is now completed. */ + pEntry->state = DNS_STATE_DONE; + pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Check for error. If so, call callback to inform. */ + if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + +#if DNS_DOES_NAME_CHECK + /* Check if the name in the "question" part match with the name in the entry. */ + if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } +#endif /* DNS_DOES_NAME_CHECK */ + + /* Skip the name in the "question" part */ + pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY; + + while(nanswers > 0) { + /* skip answer resource record's host name */ + pHostname = (char *) dns_parse_name((unsigned char *)pHostname); + + /* Check for IP address type and Internet class. Others are discarded. */ + MEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER); + if((ntohs(ans.type) == DNS_RRTYPE_A) && (ntohs(ans.class) == DNS_RRCLASS_IN) && (ntohs(ans.len) == sizeof(struct ip_addr)) ) { + /* read the answer resource record's TTL, and maximize it if needed */ + pEntry->ttl = ntohl(ans.ttl); + if (pEntry->ttl > DNS_MAX_TTL) { + pEntry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + MEMCPY( &(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(struct ip_addr)); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + /* call specified callback function if provided */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg); + } + /* deallocate memory and return */ + goto memerr2; + } else { + pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len); + } + --nanswers; + } + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + } + } + + /* deallocate memory and return */ + goto memerr2; + +responseerr: + /* ERROR: call specified callback function with NULL as name to indicate an error */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + } + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + +memerr2: +#if (DNS_USES_STATIC_BUF == 2) + /* free dns buffer */ + mem_free(dns_payload); +#endif /* (DNS_USES_STATIC_BUF == 2) */ + +memerr1: + /* free pbuf */ + pbuf_free(p); + return; +} + +/** + * Queues a new hostname to resolve and sends out a DNS query for that hostname + * + * @param name the hostname that is to be queried + * @param found a callback founction to be called on success, failure or timeout + * @param callback_arg argument to pass to the callback function + * @return @return a err_t return code. + */ +static err_t +dns_enqueue(const char *name, dns_found_callback found, void *callback_arg) +{ + u8_t i; + u8_t lseq, lseqi; + struct dns_table_entry *pEntry = NULL; + + /* search an unused entry, or the oldest one */ + lseq = lseqi = 0; + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + pEntry = &dns_table[i]; + /* is it an unused entry ? */ + if (pEntry->state == DNS_STATE_UNUSED) + break; + + /* check if this is the oldest completed entry */ + if (pEntry->state == DNS_STATE_DONE) { + if ((dns_seqno - pEntry->seqno) > lseq) { + lseq = dns_seqno - pEntry->seqno; + lseqi = i; + } + } + } + + /* if we don't have found an unused entry, use the oldest completed one */ + if (i == DNS_TABLE_SIZE) { + if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { + /* no entry can't be used now, table is full */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); + return ERR_MEM; + } else { + /* use the oldest completed one */ + i = lseqi; + pEntry = &dns_table[i]; + } + } + + /* use this entry */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); + + /* fill the entry */ + pEntry->state = DNS_STATE_NEW; + pEntry->seqno = dns_seqno++; + pEntry->found = found; + pEntry->arg = callback_arg; + strcpy(pEntry->name, name); + + /* force to send query without waiting timer */ + dns_check_entry(i); + + /* dns query is enqueued */ + return ERR_INPROGRESS; +} + +/** + * Resolve a hostname (string) into an IP address. + * NON-BLOCKING callback version for use with raw API!!! + * + * Returns immediately with one of err_t return codes: + * - ERR_OK if hostname is a valid IP address string or the host + * name is already in the local names table. + * - ERR_INPROGRESS enqueue a request to be sent to the DNS server + * for resolution if no errors are present. + * + * @param hostname the hostname that is to be queried + * @param addr pointer to a struct ip_addr where to store the address if it is already + * cached in the dns_table (only valid if ERR_OK is returned!) + * @param found a callback function to be called on success, failure or timeout (only if + * ERR_INPROGRESS is returned!) + * @param callback_arg argument to pass to the callback function + * @return a err_t return code. + */ +err_t +dns_gethostbyname(const char *hostname, struct ip_addr *addr, dns_found_callback found, + void *callback_arg) +{ + /* not initialized or no valid server yet, or invalid addr pointer + * or invalid hostname or invalid hostname length */ + if ((dns_pcb == NULL) || (addr == NULL) || + (!hostname) || (!hostname[0]) || + (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) { + return ERR_VAL; + } + +#if LWIP_HAVE_LOOPIF + if (strcmp(hostname,"localhost")==0) { + addr->addr = htonl(INADDR_LOOPBACK); + return ERR_OK; + } +#endif /* LWIP_HAVE_LOOPIF */ + + /* host name already in octet notation? set ip addr and return ERR_OK + * already have this address cached? */ + if (((addr->addr = inet_addr(hostname)) != INADDR_NONE) || + ((addr->addr = dns_lookup(hostname)) != INADDR_NONE)) { + return ERR_OK; + } + + /* queue query with specified callback */ + return dns_enqueue(hostname, found, callback_arg); +} + +#endif /* LWIP_DNS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/init.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/init.c new file mode 100644 index 0000000..2a76d4c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/init.c @@ -0,0 +1,274 @@ +/** + * @file + * Modules initialization + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/init.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/sockets.h" +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/snmp_msg.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "netif/etharp.h" + +/* Compile-time sanity checks for configuration errors. + * These can be done independently of LWIP_DEBUG, without penalty. + */ +#ifndef BYTE_ORDER + #error "BYTE_ORDER is not defined, you have to define it in your cc.h" +#endif +#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) + #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" +#endif +#if (!LWIP_ARP && ARP_QUEUEING) + #error "If you want to use ARP Queueing, you have to define LWIP_ARP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_UDPLITE) + #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DHCP) + #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_IGMP) + #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DNS) + #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) + #error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) + #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" +#endif +#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) + #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) + #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) + #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_WND > 0xffff)) + #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) + #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) + #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" +#endif +#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) + #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" +#endif +#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) + #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" +#endif +#if (PPP_SUPPORT && (NO_SYS==1)) + #error "If you want to use PPP, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if (LWIP_NETIF_API && (NO_SYS==1)) + #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) + #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) + #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" +#endif +#if (!LWIP_NETCONN && LWIP_SOCKET) + #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) + #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) + #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" +#endif +#if (!LWIP_ARP && LWIP_AUTOIP) + #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) + #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) + #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) + #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" +#endif +/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ +#if ((NO_SYS==0) && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT))) + #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" +#endif +#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) + #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" +#endif +#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) + #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" +#endif +#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) + #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" +#endif +#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) + #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" +#endif +#if (TCP_QUEUE_OOSEQ && !LWIP_TCP) + #error "TCP_QUEUE_OOSEQ requires LWIP_TCP" +#endif +#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) + #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" +#endif +#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT + #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on" +#endif + + +/* Compile-time checks for deprecated options. + */ +#ifdef MEMP_NUM_TCPIP_MSG + #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef MEMP_NUM_API_MSG + #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef TCP_REXMIT_DEBUG + #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef RAW_STATS + #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_QUEUE_FIRST + #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_ALWAYS_INSERT + #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." +#endif +#if SO_REUSE +/* I removed the lot since this was an ugly hack. It broke the raw-API. + It also came with many ugly goto's, Christiaan Simons. */ + #error "SO_REUSE currently unavailable, this was a hack" +#endif + +#ifdef LWIP_DEBUG +static void +lwip_sanity_check(void) +{ + /* Warnings */ +#if LWIP_NETCONN + if (MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN\n")); +#endif /* LWIP_NETCONN */ +#if LWIP_TCP + if (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN\n")); + if (TCP_SND_BUF < 2 * TCP_MSS) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly\n")); + if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF/TCP_MSS))) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n")); + if (TCP_SNDLOWAT > TCP_SND_BUF) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n")); + if (TCP_WND > (PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE)) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n")); + if (TCP_WND < TCP_MSS) + LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n")); +#endif /* LWIP_TCP */ +} +#else /* LWIP_DEBUG */ +#define lwip_sanity_check() +#endif /* LWIP_DEBUG */ + +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + /* Sanity check user-configurable values */ + lwip_sanity_check(); + + /* Modules initialization */ + stats_init(); + sys_init(); + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); +#if LWIP_SOCKET + lwip_socket_init(); +#endif /* LWIP_SOCKET */ + ip_init(); +#if LWIP_ARP + etharp_init(); +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); +#endif /* LWIP_TCP */ +#if LWIP_SNMP + snmp_init(); +#endif /* LWIP_SNMP */ +#if LWIP_AUTOIP + autoip_init(); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + igmp_init(); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/autoip.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/autoip.c new file mode 100644 index 0000000..ff89e44 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/autoip.c @@ -0,0 +1,497 @@ +/* + * @file + * AutoIP Automatic LinkLocal IP Configuration + * + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +/******************************************************************************* + * USAGE: + * + * define LWIP_AUTOIP 1 in your lwipopts.h + * + * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): + * - First, call autoip_init(). + * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, + * that should be defined in autoip.h. + * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. + * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * + * Without DHCP: + * - Call autoip_start() after netif_add(). + * + * With DHCP: + * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. + * - Configure your DHCP Client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#include +#include + +/* 169.254.0.0 */ +#define AUTOIP_NET 0xA9FE0000 +/* 169.254.1.0 */ +#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) +/* 169.254.254.255 */ +#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) + + +/** Pseudo random macro based on netif informations. + * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ +#ifndef LWIP_AUTOIP_RAND +#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ + ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ + ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ + ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ + (netif->autoip?netif->autoip->tried_llipaddr:0)) +#endif /* LWIP_AUTOIP_RAND */ + +/** + * Macro that generates the initial IP address to be tried by AUTOIP. + * If you want to override this, define it to something else in lwipopts.h. + */ +#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR +#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ + htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ + ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) +#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ + +/* static functions */ +static void autoip_handle_arp_conflict(struct netif *netif); + +/* creates a pseudo random LL IP-Address for a network interface */ +static void autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr); + +/* sends an ARP probe */ +static err_t autoip_arp_probe(struct netif *netif); + +/* sends an ARP announce */ +static err_t autoip_arp_announce(struct netif *netif); + +/* configure interface for use with current LL IP-Address */ +static err_t autoip_bind(struct netif *netif); + +/* start sending probes for llipaddr */ +static void autoip_start_probing(struct netif *netif); + +/** + * Initialize this module + */ +void +autoip_init(void) +{ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_init()\n")); +} + +/** + * Handle a IP address conflict after an ARP conflict detection + */ +static void +autoip_handle_arp_conflict(struct netif *netif) +{ + /* Somehow detect if we are defending or retreating */ + unsigned char defend = 1; /* tbd */ + + if(defend) { + if(netif->autoip->lastconflict > 0) { + /* retreat, there was a conflicting ARP in the last + * DEFEND_INTERVAL seconds + */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); + + /* TODO: close all TCP sessions */ + autoip_start(netif); + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); + autoip_arp_announce(netif); + netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); + /* TODO: close all TCP sessions */ + autoip_start(netif); + } +} + +/** + * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * + * @param netif network interface on which create the IP-Address + * @param ipaddr ip address to initialize + */ +static void +autoip_create_addr(struct netif *netif, struct ip_addr *ipaddr) +{ + /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * compliant to RFC 3927 Section 2.1 + * We have 254 * 256 possibilities */ + + u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); + addr += netif->autoip->tried_llipaddr; + addr = AUTOIP_NET | (addr & 0xffff); + /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ + + if (addr < AUTOIP_RANGE_START) { + addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + if (addr > AUTOIP_RANGE_END) { + addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && + (addr <= AUTOIP_RANGE_END)); + ipaddr->addr = htonl(addr); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_create_addr(): tried_llipaddr=%"U16_F", 0x%08"X32_F"\n", + (u16_t)(netif->autoip->tried_llipaddr), (u32_t)(ipaddr->addr))); +} + +/** + * Sends an ARP probe from a network interface + * + * @param netif network interface used to send the probe + */ +static err_t +autoip_arp_probe(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Sends an ARP announce from a network interface + * + * @param netif network interface used to send the announce + */ +static err_t +autoip_arp_announce(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Configure interface for use with current LL IP-Address + * + * @param netif network interface to configure with current LL IP-Address + */ +static err_t +autoip_bind(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + struct ip_addr sn_mask, gw_addr; + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_bind(netif=%p) %c%c%"U16_F" 0x%08"X32_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, autoip->llipaddr.addr)); + + IP4_ADDR(&sn_mask, 255, 255, 0, 0); + IP4_ADDR(&gw_addr, 0, 0, 0, 0); + + netif_set_ipaddr(netif, &autoip->llipaddr); + netif_set_netmask(netif, &sn_mask); + netif_set_gw(netif, &gw_addr); + + /* bring the interface up */ + netif_set_up(netif); + + return ERR_OK; +} + +/** + * Start AutoIP client + * + * @param netif network interface on which start the AutoIP client + */ +err_t +autoip_start(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + err_t result = ERR_OK; + + if(netif_is_up(netif)) { + netif_set_down(netif); + } + + /* Set IP-Address, Netmask and Gateway to 0 to make sure that + * ARP Packets are formed correctly + */ + netif->ip_addr.addr = 0; + netif->netmask.addr = 0; + netif->gw.addr = 0; + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], + netif->name[1], (u16_t)netif->num)); + if(autoip == NULL) { + /* no AutoIP client attached yet? */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): starting new AUTOIP client\n")); + autoip = mem_malloc(sizeof(struct autoip)); + if(autoip == NULL) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): could not allocate autoip\n")); + return ERR_MEM; + } + memset( autoip, 0, sizeof(struct autoip)); + /* store this AutoIP client in the netif */ + netif->autoip = autoip; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); + } else { + autoip->state = AUTOIP_STATE_OFF; + autoip->ttw = 0; + autoip->sent_num = 0; + memset(&autoip->llipaddr, 0, sizeof(struct ip_addr)); + autoip->lastconflict = 0; + } + + autoip_create_addr(netif, &(autoip->llipaddr)); + autoip->tried_llipaddr++; + autoip_start_probing(netif); + + return result; +} + +static void +autoip_start_probing(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + + autoip->state = AUTOIP_STATE_PROBING; + autoip->sent_num = 0; + + /* time to wait to first probe, this is randomly + * choosen out of 0 to PROBE_WAIT seconds. + * compliant to RFC 3927 Section 2.2.1 + */ + autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); + + /* + * if we tried more then MAX_CONFLICTS we must limit our rate for + * accquiring and probing address + * compliant to RFC 3927 Section 2.2.1 + */ + if(autoip->tried_llipaddr > MAX_CONFLICTS) { + autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } +} + +/** + * Handle a possible change in the network configuration. + * + * If there is an AutoIP address configured, take the interface down + * and begin probing with the same address. + */ +void +autoip_network_changed(struct netif *netif) +{ + if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) { + netif_set_down(netif); + autoip_start_probing(netif); + } +} + +/** + * Stop AutoIP client + * + * @param netif network interface on which stop the AutoIP client + */ +err_t +autoip_stop(struct netif *netif) +{ + netif->autoip->state = AUTOIP_STATE_OFF; + netif_set_down(netif); + return ERR_OK; +} + +/** + * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds + */ +void +autoip_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on AutoIP configured interfaces */ + if (netif->autoip != NULL) { + if(netif->autoip->lastconflict > 0) { + netif->autoip->lastconflict--; + } + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", + (u16_t)(netif->autoip->state), netif->autoip->ttw)); + + switch(netif->autoip->state) { + case AUTOIP_STATE_PROBING: + if(netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if(netif->autoip->sent_num >= PROBE_NUM) { + netif->autoip->state = AUTOIP_STATE_ANNOUNCING; + netif->autoip->sent_num = 0; + netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; + } else { + autoip_arp_probe(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() PROBING Sent Probe\n")); + netif->autoip->sent_num++; + /* calculate time to wait to next probe */ + netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % + ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + + PROBE_MIN * AUTOIP_TICKS_PER_SECOND); + } + } + break; + + case AUTOIP_STATE_ANNOUNCING: + if(netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if(netif->autoip->sent_num == 0) { + /* We are here the first time, so we waited ANNOUNCE_WAIT seconds + * Now we can bind to an IP address and use it. + * + * autoip_bind calls netif_set_up. This triggers a gratuitous ARP + * which counts as an announcement. + */ + autoip_bind(netif); + } else { + autoip_arp_announce(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() ANNOUNCING Sent Announce\n")); + } + netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; + netif->autoip->sent_num++; + + if(netif->autoip->sent_num >= ANNOUNCE_NUM) { + netif->autoip->state = AUTOIP_STATE_BOUND; + netif->autoip->sent_num = 0; + netif->autoip->ttw = 0; + } + } + break; + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * Handles every incoming ARP Packet, called by etharp_arp_input. + * + * @param netif network interface to use for autoip processing + * @param hdr Incoming ARP packet + */ +void +autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) +{ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); + if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) { + /* when ip.src == llipaddr && hw.src != netif->hwaddr + * + * when probing ip.dst == llipaddr && hw.src != netif->hwaddr + * we have a conflict and must solve it + */ + struct ip_addr sipaddr, dipaddr; + struct eth_addr netifaddr; + netifaddr.addr[0] = netif->hwaddr[0]; + netifaddr.addr[1] = netif->hwaddr[1]; + netifaddr.addr[2] = netif->hwaddr[2]; + netifaddr.addr[3] = netif->hwaddr[3]; + netifaddr.addr[4] = netif->hwaddr[4]; + netifaddr.addr[5] = netif->hwaddr[5]; + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). + */ + SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr)); + SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr)); + + if ((netif->autoip->state == AUTOIP_STATE_PROBING) || + ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && + (netif->autoip->sent_num == 0))) { + /* RFC 3927 Section 2.2.1: + * from beginning to after ANNOUNCE_WAIT + * seconds we have a conflict if + * ip.src == llipaddr OR + * ip.dst == llipaddr && hw.src != own hwaddr + */ + if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) || + (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Probe Conflict detected\n")); + autoip_start(netif); + } + } else { + /* RFC 3927 Section 2.5: + * in any state we have a conflict if + * ip.src == llipaddr && hw.src != own hwaddr + */ + if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); + autoip_handle_arp_conflict(netif); + } + } + } +} + +#endif /* LWIP_AUTOIP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/icmp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/icmp.c new file mode 100644 index 0000000..7b0a02e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/icmp.c @@ -0,0 +1,340 @@ +/** + * @file + * ICMP - Internet Control Message Protocol + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" + +#include + +/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be + * used to modify and send a response packet (and to 1 if this is not the case, + * e.g. when link header is stripped of when receiving) */ +#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + +/* The amount of data from the original packet to return in a dest-unreachable */ +#define ICMP_DEST_UNREACH_DATASIZE 8 + +static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); + +/** + * Processes ICMP input packets, called from ip_input(). + * + * Currently only processes icmp echo requests and sends + * out the echo response. + * + * @param p the icmp echo request packet, p->payload pointing to the ip header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; +#ifdef LWIP_DEBUG + u8_t code; +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + struct ip_addr tmpaddr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + snmp_inc_icmpinmsgs(); + + + iphdr = p->payload; + hlen = IPH_HL(iphdr) * 4; + if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(&iphdr->dest)) { + accepted = 0; + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(&iphdr->dest, inp)) { + accepted = 0; + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not acceptd? */ + if (!accepted) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + pbuf_free(p); + return; + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + ICMP_STATS_INC(icmp.chkerr); + snmp_inc_icmpinerrors(); + return; + } +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* switch p->payload to ip header */ + if (pbuf_header(p, hlen)) { + LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); + goto memerr; + } + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the whole packet including ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + iphdr = r->payload; + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + /* we now have an identical copy of p that has room for link headers */ + p = r; + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = p->payload; + tmpaddr.addr = iphdr->src.addr; + iphdr->src.addr = iphdr->dest.addr; + iphdr->dest.addr = tmpaddr.addr; + ICMPH_TYPE_SET(iecho, ICMP_ER); + + +/* This part of code has been modified by ST's MCD Application Team */ +/* To use the Checksum Offload Engine for the putgoing ICMP packets, + the ICMP checksum field should be set to 0, this is required only for Tx ICMP*/ +#ifdef CHECKSUM_BY_HARDWARE + iecho->chksum = 0; +#else + /* adjust the checksum */ + if (iecho->chksum >= htons(0xffff - (ICMP_ECHO << 8))) { + iecho->chksum += htons(ICMP_ECHO << 8) + 1; + } else { + iecho->chksum += htons(ICMP_ECHO << 8); + } +#endif + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + ret = ip_output_if(p, &(iphdr->src), IP_HDRINCL, + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + pbuf_free(p); + return; +lenerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + snmp_inc_icmpinerrors(); + return; +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.err); + snmp_inc_icmpinerrors(); + return; +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + +/** + * Send an icmp 'destination unreachable' packet, called from ip_input() if + * the transport layer protocol is unknown and from udp_input() if the local + * port is not bound. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + icmp_send_response(p, ICMP_DUR, t); +} + +#if IP_FORWARD || IP_REASSEMBLY +/** + * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. + * + * @param p the input packet for which the 'time exceeded' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + icmp_send_response(p, ICMP_TE, t); +} + +#endif /* IP_FORWARD || IP_REASSEMBLY */ + +/** + * Send an icmp packet in response to an incoming packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + PBUF_RAM); + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = p->payload; + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = q->payload; + icmphdr->type = type; + icmphdr->code = code; + icmphdr->id = 0; + icmphdr->seqno = 0; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; + icmphdr->chksum = inet_chksum(icmphdr, q->len); + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_output(q, NULL, &(iphdr->src), ICMP_TTL, 0, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/igmp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/igmp.c new file mode 100644 index 0000000..b89a06b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/igmp.c @@ -0,0 +1,757 @@ +/** + * @file + * IGMP - Internet Group Management Protocol + * + **/ + +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +/*------------------------------------------------------------- +Note 1) +Although the rfc requires V1 AND V2 capability +we will only support v2 since now V1 is very old (August 1989) +V1 can be added if required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 2) +A query for a specific group address (as opposed to ALLHOSTS) +has now been implemented as I am unsure if it is required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 3) +The router alert rfc 2113 is implemented in outgoing packets +but not checked rigorously incoming +------------------------------------------------------------- +Steve Reynolds +------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * RFC 988 - Host extensions for IP multicasting - V0 + * RFC 1054 - Host extensions for IP multicasting - + * RFC 1112 - Host extensions for IP multicasting - V1 + * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) + * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 + * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ + * RFC 2113 - IP Router Alert Option - + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/igmp.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/stats.h" + +#include "string.h" + +/*----------------------------------------------------------------------------- + * Globales + *----------------------------------------------------------------------------*/ + +static struct igmp_group* igmp_group_list; +static struct ip_addr allsystems; +static struct ip_addr allrouters; + +/** + * Initialize the IGMP module + */ +void +igmp_init(void) +{ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); + + IP4_ADDR(&allsystems, 224, 0, 0, 1); + IP4_ADDR(&allrouters, 224, 0, 0, 2); +} + +#ifdef LWIP_DEBUG +/** + * Dump global IGMP groups list + */ +void +igmp_dump_group_list() +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state))); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->interface)); + group = group->next; + } + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); +} +#else +#define igmp_dump_group_list() +#endif /* LWIP_DEBUG */ + +/** + * Start IGMP processing on interface + * + * @param netif network interface on which start IGMP processing + */ +err_t +igmp_start(struct netif *netif) +{ + struct igmp_group* group; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif)); + + group = igmp_lookup_group(netif, &allsystems); + + if (group != NULL) { + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->use++; + + /* Allow the igmp messages at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, &allsystems); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter( netif, &allsystems, IGMP_ADD_MAC_FILTER); + } + + return ERR_OK; + } + + return ERR_MEM; +} + +/** + * Stop IGMP processing on interface + * + * @param netif network interface on which stop IGMP processing + */ +err_t +igmp_stop(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + struct igmp_group *prev = NULL; + struct igmp_group *next; + + /* look for groups joined on this interface further down the list */ + while (group != NULL) { + next = group->next; + /* is it a group joined on this interface? */ + if (group->interface == netif) { + /* is it the first group of the list? */ + if (group == igmp_group_list) { + igmp_group_list = next; + } + /* is there a "previous" group defined? */ + if (prev != NULL) { + prev->next = next; + } + /* disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER); + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + } else { + /* change the "previous" */ + prev = group; + } + /* move to "next" */ + group = next; + } + return ERR_OK; +} + +/** + * Report IGMP memberships for this interface + * + * @param netif network interface on which report IGMP memberships + */ +void +igmp_report_groups( struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); + + while (group != NULL) { + if (group->interface == netif) { + igmp_delaying_member( group, IGMP_JOIN_DELAYING_MEMBER_TMR); + } + group = group->next; + } +} + +/** + * Search for a group in the global igmp_group_list + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search for + * @return a struct igmp_group* if the group has been found, + * NULL if the group wasn't found. + */ +struct igmp_group * +igmp_lookfor_group(struct netif *ifp, struct ip_addr *addr) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if ((group->interface == ifp) && (ip_addr_cmp(&(group->group_address), addr))) { + return group; + } + group = group->next; + } + + /* to be clearer, we return NULL here instead of + * 'group' (which is also NULL at this point). + */ + return NULL; +} + +/** + * Search for a specific igmp group and create a new one if not found- + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search + * @return a struct igmp_group*, + * NULL on memory error. + */ +struct igmp_group * +igmp_lookup_group(struct netif *ifp, struct ip_addr *addr) +{ + struct igmp_group *group = igmp_group_list; + + /* Search if the group already exists */ + group = igmp_lookfor_group(ifp, addr); + if (group != NULL) { + /* Group already exists. */ + return group; + } + + /* Group doesn't exist yet, create a new one */ + group = memp_malloc(MEMP_IGMP_GROUP); + if (group != NULL) { + group->interface = ifp; + ip_addr_set(&(group->group_address), addr); + group->timer = 0; /* Not running */ + group->group_state = IGMP_GROUP_NON_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; + group->next = igmp_group_list; + + igmp_group_list = group; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); + ip_addr_debug_print(IGMP_DEBUG, addr); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp)); + + return group; +} + +/** + * Remove a group in the global igmp_group_list + * + * @param group the group to remove from the global igmp_group_list + * @return ERR_OK if group was removed from the list, an err_t otherwise + */ +err_t +igmp_remove_group(struct igmp_group *group) +{ + err_t err = ERR_OK; + + /* Is it the first group? */ + if (igmp_group_list == group) { + igmp_group_list = group->next; + } else { + /* look for group further down the list */ + struct igmp_group *tmpGroup; + for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { + if (tmpGroup->next == group) { + tmpGroup->next = group->next; + break; + } + } + /* Group not found in the global igmp_group_list */ + if (tmpGroup == NULL) + err = ERR_ARG; + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + + return err; +} + +/** + * Called from ip_input() if a new IGMP packet is received. + * + * @param p received igmp packet, p->payload pointing to the ip header + * @param inp network interface on which the packet was received + * @param dest destination ip address of the igmp packet + */ +void +igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest) +{ + struct ip_hdr * iphdr; + struct igmp_msg* igmp; + struct igmp_group* group; + struct igmp_group* groupref; + + /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ + iphdr = p->payload; + if (pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.lenerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); + return; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp)); + + /* Now calculate and check the checksum */ + igmp = (struct igmp_msg *)p->payload; + if (inet_chksum(igmp, p->len)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.chkerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); + return; + } + + /* Packet is ok so find an existing group */ + group = igmp_lookfor_group(inp, dest); /* use the incoming IP address! */ + + /* If group can be found or create... */ + if (!group) { + pbuf_free(p); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); + return; + } + + /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ + switch (igmp->igmp_msgtype) { + case IGMP_MEMB_QUERY: { + /* IGMP_MEMB_QUERY to the "all systems" address ? */ + if ((ip_addr_cmp(dest, &allsystems)) && (igmp->igmp_group_address.addr == 0)) { + /* THIS IS THE GENERAL QUERY */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + + if (igmp->igmp_maxresp == 0) { + IGMP_STATS_INC(igmp.v1_rxed); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); + igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; + } + + IGMP_STATS_INC(igmp.group_query_rxed); + groupref = igmp_group_list; + while (groupref) { + /* Do not send messages on the all systems group address! */ + if ((groupref->interface == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) { + igmp_delaying_member( groupref, igmp->igmp_maxresp); + } + groupref = groupref->next; + } + } else { + /* IGMP_MEMB_QUERY to a specific group ? */ + if (group->group_address.addr != 0) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + if (ip_addr_cmp (dest, &allsystems)) { + LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + /* we first need to re-lookfor the group since we used dest last time */ + group = igmp_lookfor_group(inp, &igmp->igmp_group_address); + } else { + LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + } + + if (group != NULL) { + IGMP_STATS_INC(igmp.unicast_query); + igmp_delaying_member( group, igmp->igmp_maxresp); + } + } + } + break; + } + case IGMP_V2_MEMB_REPORT: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); + + IGMP_STATS_INC(igmp.report_rxed); + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + /* This is on a specific group we have already looked up */ + group->timer = 0; /* stopped */ + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + } + break; + } + default: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", + igmp->igmp_msgtype, group->group_state, &group, group->interface)); + break; + } + } + + pbuf_free(p); + return; +} + +/** + * Join a group on one network interface. + * + * @param ifaddr ip address of the network interface which should join a new group + * @param groupaddr the ip address of the group which to join + * @return ERR_OK if group was joined on the netif(s), an err_t otherwise + */ +err_t +igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we join this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group or create a new one if not found */ + group = igmp_lookup_group(netif, groupaddr); + + if (group != NULL) { + /* This should create a new group, check the state to make sure */ + if (group->group_state != IGMP_GROUP_NON_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n")); + } else { + /* OK - it was new group */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If first use of the group, allow the group at the MAC level */ + if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER); + } + + IGMP_STATS_INC(igmp.join_sent); + igmp_send(group, IGMP_V2_MEMB_REPORT); + + igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } + /* Increment group use */ + group->use++; + /* Join on this interface */ + err = ERR_OK; + } else { + /* Return an error even if some network interfaces are joined */ + /** @todo undo any other netif already joined */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n")); + return ERR_MEM; + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * Leave a group on one network interface. + * + * @param ifaddr ip address of the network interface which should leave a group + * @param groupaddr the ip address of the group which to leave + * @return ERR_OK if group was left on the netif(s), an err_t otherwise + */ +err_t +igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we leave this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group */ + group = igmp_lookfor_group(netif, groupaddr); + + if (group != NULL) { + /* Only send a leave if the flag is set according to the state diagram */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If there is no other use of the group */ + if (group->use <= 1) { + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n")); + IGMP_STATS_INC(igmp.leave_sent); + igmp_send(group, IGMP_LEAVE_GROUP); + } + + /* Disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER); + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* Free the group */ + igmp_remove_group(group); + } else { + /* Decrement group use */ + group->use--; + } + /* Leave on this interface */ + err = ERR_OK; + } else { + /* It's not a fatal error on "leavegroup" */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n")); + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * The igmp timer function (both for NO_SYS=1 and =0) + * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). + */ +void +igmp_tmr(void) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if (group->timer != 0) { + group->timer -= 1; + if (group->timer == 0) { + igmp_timeout(group); + } + } + group = group->next; + } +} + +/** + * Called if a timeout for one group is reached. + * Sends a report for this group. + * + * @param group an igmp_group for which a timeout is reached + */ +void +igmp_timeout(struct igmp_group *group) +{ + /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */ + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); + ip_addr_debug_print(IGMP_DEBUG, &(group->group_address)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->interface)); + + igmp_send(group, IGMP_V2_MEMB_REPORT); + } +} + +/** + * Start a timer for an igmp group + * + * @param group the igmp_group for which to start a timer + * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with + * every call to igmp_tmr()) + */ +void +igmp_start_timer(struct igmp_group *group, u8_t max_time) +{ + /** + * @todo Important !! this should be random 0 -> max_time. Find out how to do this + */ + group->timer = max_time; +} + +/** + * Stop a timer for an igmp_group + * + * @param group the igmp_group for which to stop the timer + */ +void +igmp_stop_timer(struct igmp_group *group) +{ + group->timer = 0; +} + +/** + * Delaying membership report for a group if necessary + * + * @param group the igmp_group for which "delaying" membership report + * @param maxresp query delay + */ +void +igmp_delaying_member( struct igmp_group *group, u8_t maxresp) +{ + if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || + ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && (maxresp > group->timer))) { + igmp_start_timer(group, (maxresp)/2); + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } +} + + +/** + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + */ +err_t +igmp_ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto, struct netif *netif) +{ + /* This is the "router alert" option */ + u16_t ra[2]; + ra[0] = htons (ROUTER_ALERT); + ra[1] = 0x0000; /* Router shall examine packet */ + return ip_output_if_opt(p, src, dest, ttl, 0, proto, netif, ra, ROUTER_ALERTLEN); +} + +/** + * Send an igmp packet to a specific group. + * + * @param group the group to which to send the packet + * @param type the type of igmp packet to send + */ +void +igmp_send(struct igmp_group *group, u8_t type) +{ + struct pbuf* p = NULL; + struct igmp_msg* igmp = NULL; + struct ip_addr src = {0}; + struct ip_addr* dest = NULL; + + /* IP header + "router alert" option + IGMP header */ + p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); + + if (p) { + igmp = p->payload; + LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", + (p->len >= sizeof(struct igmp_msg))); + ip_addr_set(&src, &((group->interface)->ip_addr)); + + if (type == IGMP_V2_MEMB_REPORT) { + dest = &(group->group_address); + IGMP_STATS_INC(igmp.report_sent); + ip_addr_set(&(igmp->igmp_group_address), &(group->group_address)); + group->last_reporter_flag = 1; /* Remember we were the last to report */ + } else { + if (type == IGMP_LEAVE_GROUP) { + dest = &allrouters; + ip_addr_set(&(igmp->igmp_group_address), &(group->group_address)); + } + } + + if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { + igmp->igmp_msgtype = type; + igmp->igmp_maxresp = 0; + igmp->igmp_checksum = 0; + igmp->igmp_checksum = inet_chksum( igmp, IGMP_MINLEN); + + igmp_ip_output_if(p, &src, dest, IGMP_TTL, IP_PROTO_IGMP, group->interface); + } + + pbuf_free(p); + } else { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); + } +} + +#endif /* LWIP_IGMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet.c new file mode 100644 index 0000000..5e0a6aa --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet.c @@ -0,0 +1,278 @@ +/** + * @file + * Functions common to all TCP/IPv4 modules, such as the byte order functions. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet.h" + +/* Here for now until needed in other places in lwIP */ +#ifndef isprint +#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#endif + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @return ip address in network order + */ +u32_t +inet_addr(const char *cp) +{ + struct in_addr val; + + if (inet_aton(cp, &val)) { + return (val.s_addr); + } + return (INADDR_NONE); +} + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + u32_t val; + u8_t base; + char c; + u32_t parts[4]; + u32_t *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; + base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') { + base = 16; + c = *++cp; + } else + base = 8; + } + for (;;) { + if (isdigit(c)) { + val = (val * base) + (int)(c - '0'); + c = *++cp; + } else if (base == 16 && isxdigit(c)) { + val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +/** + * Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * represenation of addr + */ +char * +inet_ntoa(struct in_addr addr) +{ + static char str[16]; + u32_t s_addr = addr.s_addr; + char inv[3]; + char *rp; + u8_t *ap; + u8_t rem; + u8_t n; + u8_t i; + + rp = str; + ap = (u8_t *)&s_addr; + for(n = 0; n < 4; n++) { + i = 0; + do { + rem = *ap % (u8_t)10; + *ap /= (u8_t)10; + inv[i++] = '0' + rem; + } while(*ap); + while(i--) + *rp++ = inv[i]; + *rp++ = '.'; + ap++; + } + *--rp = 0; + return str; +} + +/** + * These are reference implementations of the byte swapping functions. + * Again with the aim of being simple, correct and fully portable. + * Byte swapping is the second thing you would want to optimize. You will + * need to port it to your architecture and in your cc.h: + * + * #define LWIP_PLATFORM_BYTESWAP 1 + * #define LWIP_PLATFORM_HTONS(x) + * #define LWIP_PLATFORM_HTONL(x) + * + * Note ntohs() and ntohl() are merely references to the htonx counterparts. + */ + +#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) + +/** + * Convert an u16_t from host- to network byte order. + * + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +htons(u16_t n) +{ + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); +} + +/** + * Convert an u16_t from network- to host byte order. + * + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +ntohs(u16_t n) +{ + return htons(n); +} + +/** + * Convert an u32_t from host- to network byte order. + * + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +htonl(u32_t n) +{ + return ((n & 0xff) << 24) | + ((n & 0xff00) << 8) | + ((n & 0xff0000UL) >> 8) | + ((n & 0xff000000UL) >> 24); +} + +/** + * Convert an u32_t from network- to host byte order. + * + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +ntohl(u32_t n) +{ + return htonl(n); +} + +#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet_chksum.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet_chksum.c new file mode 100644 index 0000000..739854a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/inet_chksum.c @@ -0,0 +1,438 @@ +/** + * @file + * Incluse internet checksum functions. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet_chksum.h" +#include "lwip/inet.h" + +#include + +/* These are some reference implementations of the checksum algorithm, with the + * aim of being simple, correct and fully portable. Checksumming is the + * first thing you would want to optimize for your platform. If you create + * your own version, link it in and in your cc.h put: + * + * #define LWIP_CHKSUM + * + * Or you can select from the implementations below by defining + * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. + */ + +#ifndef LWIP_CHKSUM +# define LWIP_CHKSUM lwip_standard_chksum +# ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 1 +# endif +#endif +/* If none set: */ +#ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 0 +#endif + +/** Like the name says... */ +#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) +/* little endian and PLATFORM_BYTESWAP defined */ +#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) +#else +/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ +#define SWAP_BYTES_IN_WORD(w) ((w & 0xff) << 8) | ((w & 0xff00) >> 8) +#endif + +/** Split an u32_t in two u16_ts and add them up */ +#define FOLD_U32T(u) ((u >> 16) + (u & 0x0000ffffUL)) + +#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ +/** + * lwip checksum + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * @note accumulator size limits summable length to 64k + * @note host endianess is irrelevant (p3 RFC1071) + */ +static u16_t +lwip_standard_chksum(void *dataptr, u16_t len) +{ + u32_t acc; + u16_t src; + u8_t *octetptr; + + acc = 0; + /* dataptr may be at odd or even addresses */ + octetptr = (u8_t*)dataptr; + while (len > 1) { + /* declare first octet as most significant + thus assume network order, ignoring host order */ + src = (*octetptr) << 8; + octetptr++; + /* declare second octet as least significant */ + src |= (*octetptr); + octetptr++; + acc += src; + len -= 2; + } + if (len > 0) { + /* accumulate remaining octet */ + src = (*octetptr) << 8; + acc += src; + } + /* add deferred carry bits */ + acc = (acc >> 16) + (acc & 0x0000ffffUL); + if ((acc & 0xffff0000UL) != 0) { + acc = (acc >> 16) + (acc & 0x0000ffffUL); + } + /* This maybe a little confusing: reorder sum using htons() + instead of ntohs() since it has a little less call overhead. + The caller must invert bits for Internet sum ! */ + return htons((u16_t)acc); +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ +/* + * Curt McDowell + * Broadcom Corp. + * csm@broadcom.com + * + * IP checksum two bytes at a time with support for + * unaligned buffer. + * Works for len up to and including 0x20000. + * by Curt McDowell, Broadcom Corp. 12/08/2005 + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = dataptr; + u16_t *ps, t = 0; + u32_t sum = 0; + int odd = ((u32_t)pb & 1); + + /* Get aligned to u16_t */ + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + /* Add the bulk of the data */ + ps = (u16_t *)pb; + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* Consume left-over byte, if any */ + if (len > 0) { + ((u8_t *)&t)[0] = *(u8_t *)ps;; + } + + /* Add end bytes */ + sum += t; + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + /* Swap if alignment was odd */ + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return sum; +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ +/** + * An optimized checksum routine. Basically, it uses loop-unrolling on + * the checksum loop, treating the head and tail bytes specially, whereas + * the inner loop acts on 8 bytes at a time. + * + * @arg start of buffer to be checksummed. May be an odd byte address. + * @len number of bytes in the buffer to be checksummed. + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * by Curt McDowell, Broadcom Corp. December 8th, 2005 + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = dataptr; + u16_t *ps, t = 0; + u32_t *pl; + u32_t sum = 0, tmp; + /* starts at odd byte address? */ + int odd = ((u32_t)pb & 1); + + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + ps = (u16_t *)pb; + + if (((u32_t)ps & 3) && len > 1) { + sum += *ps++; + len -= 2; + } + + pl = (u32_t *)ps; + + while (len > 7) { + tmp = sum + *pl++; /* ping */ + if (tmp < sum) { + tmp++; /* add back carry */ + } + + sum = tmp + *pl++; /* pong */ + if (sum < tmp) { + sum++; /* add back carry */ + } + + len -= 8; + } + + /* make room in upper bits */ + sum = FOLD_U32T(sum); + + ps = (u16_t *)pl; + + /* 16-bit aligned word remaining? */ + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* dangling tail byte remaining? */ + if (len > 0) { /* include odd byte */ + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + sum += t; /* add end bytes */ + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return sum; +} +#endif + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u16_t proto_len) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + acc += (src->addr & 0xffffUL); + acc += ((src->addr >> 16) & 0xffffUL); + acc += (dest->addr & 0xffffUL); + acc += ((dest->addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +/* Currently only used by UDPLITE, although this could change in the future. */ +#if LWIP_UDPLITE +u16_t +inet_chksum_pseudo_partial(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + u16_t chklen; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + chklen = q->len; + if (chklen > chksum_len) { + chklen = chksum_len; + } + acc += LWIP_CHKSUM(q->payload, chklen); + chksum_len -= chklen; + LWIP_ASSERT("delete me", chksum_len < 0x7fff); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* fold the upper bit down */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + acc += (src->addr & 0xffffUL); + acc += ((src->addr >> 16) & 0xffffUL); + acc += (dest->addr & 0xffffUL); + acc += ((dest->addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} +#endif /* LWIP_UDPLITE */ + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarily for IP + * and ICMP. + * + * @param dataptr start of the buffer to calculate the checksum (no alignment needed) + * @param len length of the buffer to calculate the checksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + return ~LWIP_CHKSUM(dataptr, len); +} + +/** + * Calculate a checksum over a chain of pbufs (without pseudo-header, much like + * inet_chksum only pbufs are used). + * + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += LWIP_CHKSUM(q->payload, q->len); + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + return (u16_t)~(acc & 0xffffUL); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip.c new file mode 100644 index 0000000..df6946c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip.c @@ -0,0 +1,768 @@ +/** + * @file + * This is the IPv4 layer implementation for incoming and outgoing IP traffic. + * + * @see ip_frag.c + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip_frag.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/igmp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/stats.h" +#include "arch/perf.h" + +#include + +/** + * The interface that provided the packet for the current callback + * invocation. + */ +struct netif *current_netif; + +/** + * Header of the input packet currently being processed. + */ +const struct ip_hdr *current_header; + +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(struct ip_addr *dest) +{ + struct netif *netif; + + /* iterate through netifs */ + for(netif = netif_list; netif != NULL; netif = netif->next) { + /* network mask matches? */ + if (netif_is_up(netif)) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + snmp_inc_ipoutnoroutes(); + return NULL; + } + /* no matching netif found, use default netif */ + return netif_default; +} + +#if IP_FORWARD +/** + * Forwards an IP packet. It finds an appropriate route for the + * packet, decrements the TTL value of the packet, adjusts the + * checksum and outputs the packet on the appropriate interface. + * + * @param p the packet to forward (p->payload points to IP header) + * @param iphdr the IP header of the input packet + * @param inp the netif on which this packet was received + * @return the netif on which the packet was sent (NULL if it wasn't sent) + */ +static struct netif * +ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) +{ + struct netif *netif; + + PERF_START; + /* Find network interface where to forward this IP packet to. */ + netif = ip_route((struct ip_addr *)&(iphdr->dest)); + if (netif == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for 0x%"X32_F" found\n", + iphdr->dest.addr)); + snmp_inc_ipoutnoroutes(); + return (struct netif *)NULL; + } + /* Do not forward packets onto the same network interface on which + * they arrived. */ +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP + if(netif->flags & NETIF_FLAG_IPSWITCH == 0) { + if (netif == inp) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); + snmp_inc_ipoutnoroutes(); + return (struct netif *)NULL; + } + } +#endif +/* Realtek Modified End */ + + /* decrement TTL */ + IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); + /* send ICMP if TTL == 0 */ + if (IPH_TTL(iphdr) == 0) { + snmp_inc_ipinhdrerrors(); +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + return (struct netif *)NULL; + } + + /* Incrementally update the IP checksum. */ + if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); + } else { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); + } + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%"X32_F"\n", + iphdr->dest.addr)); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + snmp_inc_ipforwdatagrams(); + + PERF_STOP("ip_forward"); +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if ((netif->flags & NETIF_FLAG_IPSWITCH) && netif->mtu && (p->tot_len > netif->mtu)) { + ip_frag(p,netif,(struct ip_addr *)&(iphdr->dest)); + return netif; + } +#endif +#endif +/* Realtek Modified End */ + /* transmit pbuf on chosen interface */ + netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); + return netif; +} +#endif /* IP_FORWARD */ + +/** + * This function is called by the network interface device driver when + * an IP packet is received. The function does the basic checks of the + * IP header such as packet size being at least larger than the header + * size etc. If the packet was not destined for us, the packet is + * forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + * + * @param p the received IP packet (p->payload points to IP header) + * @param inp the netif on which this packet was received + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if LWIP_DHCP || LWIP_UPNP + int check_ip_src=1; +#endif /* LWIP_DHCP || LWIP_UPNP */ + + IP_STATS_INC(ip.recv); + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = p->payload; + if (IPH_V(iphdr) != 4) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + if (iphdr_hlen > p->len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_hlen, p->len)); + } + if (iphdr_len > p->tot_len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.lenerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipindiscards(); + return ERR_OK; + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.chkerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + + /* match packet against an interface, i.e. is this packet for us? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(&(iphdr->dest))) { + if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &(iphdr->dest)))) { + netif = inp; + } else { + netif = NULL; + } + } else +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + netif = inp; + do { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", + iphdr->dest.addr, netif->ip_addr.addr, + iphdr->dest.addr & netif->netmask.addr, + netif->ip_addr.addr & netif->netmask.addr, + iphdr->dest.addr & ~(netif->netmask.addr))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + /* unicast to this interface address? */ + if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) || + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(&(iphdr->dest), netif)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } + } + if (first) { + first = 0; + netif = netif_list; + } else { + netif = netif->next; + } + if (netif == inp) { + netif = netif->next; + } + } while(netif != NULL); + } + +#if LWIP_DHCP + /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed + * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. + * According to RFC 1542 section 3.1.1, referred by RFC 2131). + */ + if (netif == NULL) { + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest))); + if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest) == DHCP_CLIENT_PORT) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + check_ip_src = 0; + } + } + } +#endif /* LWIP_DHCP */ + +/* This part of code has been modified by ST's MCD Application Team */ +/* To use the UPnP responder for device discovery */ +#if LWIP_UPNP + /* Pass UPNP messages regardless of destination address. UPNP traffic is addressed + * using multicast addressing so we must not filter on IP. + */ + if (netif == NULL) { + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: UDP packet to UPNP client port %"U16_F"\n", + ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest))); + if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen))->dest) == 1900) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, ("ip_input: UPNP packet accepted.\n")); + netif = inp; + check_ip_src = 0; + } + } + } +#endif /* LWIP_UPNP */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if LWIP_DHCP || LWIP_UPNP + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + if (check_ip_src && (iphdr->src.addr != 0)) +#endif /* LWIP_DHCP || LWIP_UPNP */ + { if ((ip_addr_isbroadcast(&(iphdr->src), inp)) || + (ip_addr_ismulticast(&(iphdr->src)))) { + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.drop); + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + } + } + + /* packet not for us? */ + if (netif == NULL) { + /* packet not for us, route or discard */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); +#if IP_FORWARD +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP + if(inp->flags & NETIF_FLAG_IPSWITCH) +#else +/* Realtek Modified End */ + if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) +#endif + { + /* try to forward IP packet on (other) interfaces */ + ip_forward(p, iphdr, inp); + } + /* non-broadcast packet? */ + else +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + return ERR_OK; + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + /* packet not fully reassembled yet? */ + if (p == NULL) { + return ERR_OK; + } + iphdr = p->payload; +#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", + ntohs(IPH_OFFSET(iphdr)))); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; +#endif /* IP_REASSEMBLY */ + } + +#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ + +#if LWIP_IGMP + /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ + if((iphdr_hlen > IP_HLEN && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { +#else + if (iphdr_hlen > IP_HLEN) { +#endif /* LWIP_IGMP */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); + pbuf_free(p); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; + } +#endif /* IP_OPTIONS_ALLOWED == 0 */ + + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + current_netif = inp; + current_header = iphdr; + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) +#endif /* LWIP_RAW */ + { + + switch (IPH_PROTO(iphdr)) { +#if LWIP_UDP + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + break; +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ +#if LWIP_IGMP + case IP_PROTO_IGMP: + igmp_input(p,inp,&(iphdr->dest)); + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(&(iphdr->dest), inp) && + !ip_addr_ismulticast(&(iphdr->dest))) { + p->payload = iphdr; + icmp_dest_unreach(p, ICMP_DUR_PROTO); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinunknownprotos(); + } + } + + current_netif = NULL; + current_header = NULL; + + return ERR_OK; +} + +/** + * Sends an IP packet on a network interface. This function constructs + * the IP header and calculates the IP header checksum. If the source + * IP address is NULL, the IP address of the outgoing network + * interface is filled in as source address. + * If the destination IP address is IP_HDRINCL, p is assumed to already + * include an IP header and p->payload points to it instead of the data. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + * + * @note ip_id: RFC791 "some host may be able to simply use + * unique identifiers independent of destination" + */ +err_t +ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ +#if IP_OPTIONS_SEND + return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); +} + +/** + * Same as ip_output_if() but with the possibility to include IP options: + * + * @ param ip_options pointer to the IP options, copied into the IP header + * @ param optlen length of ip_options + */ +err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen) +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + static u16_t ip_id = 0; + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + u16_t ip_hlen = IP_HLEN; +#if IP_OPTIONS_SEND + u16_t optlen_aligned = 0; + if (optlen != 0) { + /* round up to a multiple of 4 */ + optlen_aligned = ((optlen + 3) & ~3); + ip_hlen += optlen_aligned; + /* First write in the IP options */ + if (pbuf_header(p, optlen_aligned)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + MEMCPY(p->payload, ip_options, optlen); + if (optlen < optlen_aligned) { + /* zero the remaining bytes */ + memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); + } + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + + iphdr = p->payload; + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + IPH_PROTO_SET(iphdr, proto); + + ip_addr_set(&(iphdr->dest), dest); + + IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos); + IPH_LEN_SET(iphdr, htons(p->tot_len)); + IPH_OFFSET_SET(iphdr, 0); + IPH_ID_SET(iphdr, htons(ip_id)); + ++ip_id; + + if (ip_addr_isany(src)) { + ip_addr_set(&(iphdr->src), &(netif->ip_addr)); + } else { + ip_addr_set(&(iphdr->src), src); + } + + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif + } else { + /* IP header already included in p */ + iphdr = p->payload; + dest = &(iphdr->dest); + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); + ip_debug_print(p); + +#if ENABLE_LOOPBACK + if (ip_addr_cmp(dest, &netif->ip_addr)) { + /* Packet to self, enqueue it for loopback */ + LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); + return netif_loop_output(netif, p, dest); + } +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip_frag(p,netif,dest); + } +#endif + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); +} + +/** + * Simple interface to ip_output_if. It finds the outgoing network + * interface and calls upon ip_output_if to do the actual work. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + struct netif *netif; + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint + * before calling ip_output_if. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param addr_hint address hint pointer set to netif->addr_hint before + * calling ip_output_if() + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + netif->addr_hint = addr_hint; + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + netif->addr_hint = NULL; + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +/* Print an IP header by using LWIP_DEBUGF + * @param p an IP packet, p->payload pointing to the IP header + */ +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = p->payload; + u8_t *payload; + + payload = (u8_t *)iphdr + IP_HLEN; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", + IPH_V(iphdr), + IPH_HL(iphdr), + IPH_TOS(iphdr), + ntohs(IPH_LEN(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", + ntohs(IPH_ID(iphdr)), + ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, + ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", + IPH_TTL(iphdr), + IPH_PROTO(iphdr), + ntohs(IPH_CHKSUM(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", + ip4_addr1(&iphdr->src), + ip4_addr2(&iphdr->src), + ip4_addr3(&iphdr->src), + ip4_addr4(&iphdr->src))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", + ip4_addr1(&iphdr->dest), + ip4_addr2(&iphdr->dest), + ip4_addr3(&iphdr->dest), + ip4_addr4(&iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_addr.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_addr.c new file mode 100644 index 0000000..30a165b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_addr.c @@ -0,0 +1,84 @@ +/** + * @file + * This is the IPv4 address tools implementation. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/inet.h" +#include "lwip/netif.h" + +#define IP_ADDR_ANY_VALUE 0x00000000UL +#define IP_ADDR_BROADCAST_VALUE 0xffffffffUL + +/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ +const struct ip_addr ip_addr_any = { IP_ADDR_ANY_VALUE }; +const struct ip_addr ip_addr_broadcast = { IP_ADDR_BROADCAST_VALUE }; + +/** + * Determine if an address is a broadcast address on a network interface + * + * @param addr address to be checked + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif) +{ + u32_t addr2test; + + addr2test = addr->addr; + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr2test == IP_ADDR_ANY_VALUE) || + (addr2test == IP_ADDR_ANY_VALUE)) + return 1; + /* no broadcast support on this network interface? */ + else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + /* address matches network interface address exactly? => no broadcast */ + else if (addr2test == netif->ip_addr.addr) + return 0; + /* on the same (sub) network... */ + else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask)) + /* ...and host identifier bits are all ones? =>... */ + && ((addr2test & ~netif->netmask.addr) == + (IP_ADDR_BROADCAST_VALUE & ~netif->netmask.addr))) + /* => network broadcast address */ + return 1; + else + return 0; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_frag.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_frag.c new file mode 100644 index 0000000..59afe94 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv4/ip_frag.c @@ -0,0 +1,792 @@ +/** + * @file + * This is the IPv4 packet segmentation and reassembly implementation. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * Simon Goldschmidt + * original reassembly code by Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_frag.h" +#include "lwip/ip.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/stats.h" +#include "lwip/icmp.h" + +#include + +#if IP_REASSEMBLY +/** + * The IP reassembly code currently has the following limitations: + * - IP header options are not supported + * - fragments must not overlap (e.g. due to different routes), + * currently, overlapping or duplicate fragments are thrown away + * if IP_REASS_CHECK_OVERLAP=1 (the default)! + * + * @todo: work with IP header options + */ + +/** Setting this to 0, you can turn off checking the fragments for overlapping + * regions. The code gets a little smaller. Only use this if you know that + * overlapping won't occur on your network! */ +#ifndef IP_REASS_CHECK_OVERLAP +#define IP_REASS_CHECK_OVERLAP 1 +#endif /* IP_REASS_CHECK_OVERLAP */ + +/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is + * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. + * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA + * is set to 1, so one datagram can be reassembled at a time, only. */ +#ifndef IP_REASS_FREE_OLDEST +#define IP_REASS_FREE_OLDEST 1 +#endif /* IP_REASS_FREE_OLDEST */ + +#define IP_REASS_FLAG_LASTFRAG 0x01 + +/** This is a helper struct which holds the starting + * offset and the ending offset of this fragment to + * easily chain the fragments. + * It has to be packed since it has to fit inside the IP header. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_reass_helper { + PACK_STRUCT_FIELD(struct pbuf *next_pbuf); + PACK_STRUCT_FIELD(u16_t start); + PACK_STRUCT_FIELD(u16_t end); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ + (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ + ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ + IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 + +/* global variables */ +static struct ip_reassdata *reassdatagrams; +static u16_t ip_reass_pbufcount; + +/* function prototypes */ +static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); +static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); + +/** + * Reassembly timer base function + * for both NO_SYS == 0 and 1 (!). + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + struct ip_reassdata *r, *prev = NULL; + + r = reassdatagrams; + while (r != NULL) { + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + r->timer--; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + r = r->next; + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + /* get the next pointer before freeing */ + r = r->next; + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + } + } +} + +/** + * Free a datagram (struct ip_reassdata) and all its pbufs. + * Updates the total count of enqueued pbufs (ip_reass_pbufcount), + * SNMP counters and sends an ICMP time exceeded packet. + * + * @param ipr datagram to free + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + int pbufs_freed = 0; + struct pbuf *p; + struct ip_reass_helper *iprh; + + LWIP_ASSERT("prev != ipr", prev != ipr); + if (prev != NULL) { + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + icmp_time_exceeded(p, ICMP_TE_FRAG); + pbufs_freed += pbuf_clen(p); + pbuf_free(p); + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + while (p != NULL) { + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + pcur = p; + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + pbufs_freed += pbuf_clen(pcur); + pbuf_free(pcur); + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + + return pbufs_freed; +} + +#if IP_REASS_FREE_OLDEST +/** + * Free the oldest datagram to make room for enqueueing new fragments. + * The datagram 'fraghdr' belongs to is not freed! + * + * @param fraghdr IP header of the current fragment + * @param pbufs_needed number of pbufs needed to enqueue + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + prev = NULL; + other_datagrams = 0; + r = reassdatagrams; + while (r != NULL) { + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + /* Not the same datagram as fraghdr */ + other_datagrams++; + if (oldest == NULL) { + oldest = r; + } else if (r->timer <= oldest->timer) { + /* older than the previous oldest */ + oldest = r; + } + } + if (r->next != NULL) { + prev = r; + } + r = r->next; + } + if (oldest != NULL) { + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + pbufs_freed += pbufs_freed_current; + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + return pbufs_freed; +} +#endif /* IP_REASS_FREE_OLDEST */ + +/** + * Enqueues a new fragment into the fragment queue + * @param fraghdr points to the new fragments IP hdr + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = memp_malloc(MEMP_REASSDATA); + if (ipr == NULL) { +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + ipr = memp_malloc(MEMP_REASSDATA); + } + if (ipr == NULL) +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + ipr->timer = IP_REASS_MAXAGE; + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + reassdatagrams = ipr; + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + return ipr; +} + +/** + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + /* it was the first in the list */ + reassdatagrams = ipr->next; + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); +} + +/** + * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list + * will grow over time as new pbufs are rx. + * Also checks that the datagram passes basic continuity checks (if the last + * fragment was received at least once). + * @param root_p points to the 'root' pbuf for the current datagram being assembled. + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + iprh->next_pbuf = NULL; + iprh->start = offset; + iprh->end = offset + len; + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + iprh_tmp = (struct ip_reass_helper*)q->payload; + if (iprh->start < iprh_tmp->start) { + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + if (iprh_prev != NULL) { + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + } else if(iprh->start == iprh_tmp->start) { + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + if (iprh_prev->end != iprh_tmp->start) { + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + } + } + } + q = iprh_tmp->next_pbuf; + iprh_prev = iprh_tmp; + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + if (iprh_prev != NULL) { + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + if (iprh_prev->end != iprh->start) { + valid = 0; + } + } else { +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + /* and had no wholes so far */ + if (valid) { + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { + valid = 0; + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + q = iprh->next_pbuf; + while (q != NULL) { + iprh = (struct ip_reass_helper*)q->payload; + if (iprh_prev->end != iprh->start) { + valid = 0; + break; + } + iprh_prev = iprh; + q = iprh->next_pbuf; + } + /* if still valid, all fragments are received + * (because to the MF==0 already arrived */ + if (valid) { + LWIP_ASSERT("sanity check", ipr->p != NULL); + LWIP_ASSERT("sanity check", + ((struct ip_reass_helper*)ipr->p->payload) != iprh); + LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", + iprh->next_pbuf == NULL); + LWIP_ASSERT("validate_datagram:datagram end!=datagram len", + iprh->end == ipr->datagram_len); + } + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ +#if IP_REASS_CHECK_OVERLAP +freepbuf: + ip_reass_pbufcount -= pbuf_clen(new_p); + pbuf_free(new_p); + return 0; +#endif /* IP_REASS_CHECK_OVERLAP */ +} + +/** + * Reassembles incoming IP fragments into an IP datagram. + * + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + struct pbuf *r; + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + struct ip_reassdata *ipr_prev = NULL; + + IPFRAG_STATS_INC(ip_frag.recv); + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + goto nullreturn; + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + break; + } + ipr_prev = ipr; + } + + if (ipr == NULL) { + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + /* Bail if unable to enqueue */ + if(ipr == NULL) { + goto nullreturn; + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((ntohs(IPH_OFFSET(fraghdr)) & IP_MF) == 0) { + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + ipr->datagram_len = offset + len; + LWIP_DEBUGF(IP_REASS_DEBUG, + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + IPH_OFFSET_SET(fraghdr, 0); + IPH_CHKSUM_SET(fraghdr, 0); + /* @todo: do we need to set calculate the correct checksum? */ + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); + + p = ipr->p; + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + iprh = (struct ip_reass_helper*)r->payload; + + /* hide the ip header for every succeding fragment */ + pbuf_header(r, -IP_HLEN); + pbuf_cat(p, r); + r = iprh->next_pbuf; + } + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + + /* Return the pbuf chain */ + return p; + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + pbuf_free(p); + return NULL; +} +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if IP_FRAG_USES_STATIC_BUF +static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)]; +#endif /* IP_FRAG_USES_STATIC_BUF */ + +/** + * Fragment an IP datagram if too large for the netif. + * + * Chop the datagram in MTU sized chunks and send them in order + * by using a fixed size static memory buffer (PBUF_REF) or + * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF). + * + * @param p ip packet to send + * @param netif the netif on which to send + * @param dest destination ip address to which to send + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest) +{ + struct pbuf *rambuf; +#if IP_FRAG_USES_STATIC_BUF + struct pbuf *header; +#else + struct pbuf *newpbuf; + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF + u16_t newpbuflen = 0; + u16_t left_to_copy; +#endif + + /* Get a RAM based MTU sized pbuf */ +#if IP_FRAG_USES_STATIC_BUF + /* When using a static buffer, we use a PBUF_REF, which we will + * use to reference the packet (without link header). + * Layer and length is irrelevant. + */ + rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF); + if (rambuf == NULL) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n")); + return ERR_MEM; + } + rambuf->tot_len = rambuf->len = mtu; + rambuf->payload = LWIP_MEM_ALIGN((void *)buf); + + /* Copy the IP header in it */ + iphdr = rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = p->payload; + iphdr = original_iphdr; +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + ofo = tmp & IP_OFFMASK; + omf = tmp & IP_MF; + + left = p->tot_len - IP_HLEN; + + nfb = (mtu - IP_HLEN) / 8; + + while (left) { + last = (left <= mtu - IP_HLEN); + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + if (!last) + tmp = tmp | IP_MF; + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + +#if IP_FRAG_USES_STATIC_BUF + poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); +#else /* IP_FRAG_USES_STATIC_BUF */ + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = rambuf->payload; + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + p->len -= poff; + + left_to_copy = cop; + while (left_to_copy) { + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + /* Is this pbuf already empty? */ + if (!newpbuflen) { + p = p->next; + continue; + } + newpbuf = pbuf_alloc(PBUF_RAW, 0, PBUF_REF); + if (newpbuf == NULL) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf->payload = p->payload; + newpbuf->len = newpbuf->tot_len = newpbuflen; + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + left_to_copy -= newpbuflen; + if (left_to_copy) + p = p->next; + } + poff = newpbuflen; +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + IPH_CHKSUM_SET(iphdr, 0); + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + +#if IP_FRAG_USES_STATIC_BUF + if (last) + pbuf_realloc(rambuf, left + IP_HLEN); + + /* This part is ugly: we alloc a RAM based pbuf for + * the link level header for each chunk and then + * free it.A PBUF_ROM style pbuf for which pbuf_header + * worked would make things simpler. + */ + header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); + if (header != NULL) { + pbuf_chain(header, rambuf); + netif->output(netif, header, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + snmp_inc_ipfragcreates(); + pbuf_free(header); + } else { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n")); + pbuf_free(rambuf); + return ERR_MEM; + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + + /* Unfortunately we can't reuse rambuf - the hardware may still be + * using the buffer. Instead we free it (and the ensuing chain) and + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + ofo += nfb; + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; +} +#endif /* IP_FRAG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/README b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/README new file mode 100644 index 0000000..3620004 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/README @@ -0,0 +1 @@ +IPv6 support in lwIP is very experimental. diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/icmp6.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/icmp6.c new file mode 100644 index 0000000..4fcc895 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/icmp6.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" + +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + struct ip_addr tmpaddr; + + ICMP_STATS_INC(icmp.recv); + + /* TODO: check length before accessing payload! */ + + type = ((u8_t *)p->payload)[0]; + + switch (type) { + case ICMP6_ECHO: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + return; + } + iecho = p->payload; + iphdr = (struct ip_hdr *)((u8_t *)p->payload - IP_HLEN); + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len))); + ICMP_STATS_INC(icmp.chkerr); + /* return;*/ + } + LWIP_DEBUGF(ICMP_DEBUG, ("icmp: p->len %"S16_F" p->tot_len %"S16_F"\n", p->len, p->tot_len)); + ip_addr_set(&tmpaddr, &(iphdr->src)); + ip_addr_set(&(iphdr->src), &(iphdr->dest)); + ip_addr_set(&(iphdr->dest), &tmpaddr); + iecho->type = ICMP6_ER; + /* adjust the checksum */ + if (iecho->chksum >= htons(0xffff - (ICMP6_ECHO << 8))) { + iecho->chksum += htons(ICMP6_ECHO << 8) + 1; + } else { + iecho->chksum += htons(ICMP6_ECHO << 8); + } + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo (%"X16_F")\n", inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest), IP_PROTO_ICMP, p->tot_len))); + ICMP_STATS_INC(icmp.xmit); + + /* LWIP_DEBUGF("icmp: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/ + ip_output_if (p, &(iphdr->src), IP_HDRINCL, + iphdr->hoplim, IP_PROTO_ICMP, inp); + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" not supported.\n", (s16_t)type)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + + pbuf_free(p); +} + +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + struct icmp_dur_hdr *idur; + + /* @todo: can this be PBUF_LINK instead of PBUF_IP? */ + q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + /* ICMP header + IP header + 8 bytes of data */ + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n")); + pbuf_free(p); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (8 + IP_HLEN + 8))); + + iphdr = p->payload; + + idur = q->payload; + idur->type = (u8_t)ICMP6_DUR; + idur->icode = (u8_t)t; + + SMEMCPY((u8_t *)q->payload + 8, p->payload, IP_HLEN + 8); + + /* calculate checksum */ + idur->chksum = 0; + idur->chksum = inet_chksum(idur, q->len); + ICMP_STATS_INC(icmp.xmit); + + ip_output(q, NULL, + (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); + pbuf_free(q); +} + +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + struct icmp_te_hdr *tehdr; + + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded\n")); + + /* @todo: can this be PBUF_LINK instead of PBUF_IP? */ + q = pbuf_alloc(PBUF_IP, 8 + IP_HLEN + 8, PBUF_RAM); + /* ICMP header + IP header + 8 bytes of data */ + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_dest_unreach: failed to allocate pbuf for ICMP packet.\n")); + pbuf_free(p); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (8 + IP_HLEN + 8))); + + iphdr = p->payload; + + tehdr = q->payload; + tehdr->type = (u8_t)ICMP6_TE; + tehdr->icode = (u8_t)t; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + 8, (u8_t *)p->payload, IP_HLEN + 8); + + /* calculate checksum */ + tehdr->chksum = 0; + tehdr->chksum = inet_chksum(tehdr, q->len); + ICMP_STATS_INC(icmp.xmit); + ip_output(q, NULL, + (struct ip_addr *)&(iphdr->src), ICMP_TTL, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/inet6.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/inet6.c new file mode 100644 index 0000000..c3de85c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/inet6.c @@ -0,0 +1,163 @@ +/** + * @file + * Functions common to all TCP/IPv6 modules, such as the Internet checksum and the + * byte order functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/inet.h" + +/* chksum: + * + * Sums up all 16 bit words in a memory portion. Also includes any odd byte. + * This function is used by the other checksum functions. + * + * For now, this is not optimized. Must be optimized for the particular processor + * arcitecture on which it is to run. Preferebly coded in assembler. + */ + +static u32_t +chksum(void *dataptr, u16_t len) +{ + u16_t *sdataptr = dataptr; + u32_t acc; + + + for(acc = 0; len > 1; len -= 2) { + acc += *sdataptr++; + } + + /* add up any odd byte */ + if (len == 1) { + acc += htons((u16_t)(*(u8_t *)dataptr) << 8); + } + + return acc; + +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + */ + +u16_t +inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u32_t proto_len) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped, i; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += chksum(q->payload, q->len); + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + } + + if (swapped) { + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + + for(i = 0; i < 8; i++) { + acc += ((u16_t *)src->addr)[i] & 0xffff; + acc += ((u16_t *)dest->addr)[i] & 0xffff; + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + } + acc += (u16_t)htons((u16_t)proto); + acc += ((u16_t *)&proto_len)[0] & 0xffff; + acc += ((u16_t *)&proto_len)[1] & 0xffff; + + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + return ~(acc & 0xffff); +} + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarely for IP + * and ICMP. + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + u32_t acc, sum; + + acc = chksum(dataptr, len); + sum = (acc & 0xffff) + (acc >> 16); + sum += (sum >> 16); + return ~(sum & 0xffff); +} + +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += chksum(q->payload, q->len); + while (acc >> 16) { + acc = (acc & 0xffff) + (acc >> 16); + } + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8); + } + } + + if (swapped) { + acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8); + } + return ~(acc & 0xffff); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6.c new file mode 100644 index 0000000..7e43420 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6.c @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + + +/* ip.c + * + * This is the code for the IP layer for IPv6. + * + */ + + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip.h" +#include "lwip/inet.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" + +#include "lwip/stats.h" + +#include "arch/perf.h" + +/* ip_init: + * + * Initializes the IP layer. + */ + +void +ip_init(void) +{ +} + +/* ip_route: + * + * Finds the appropriate network interface for a given IP address. It searches the + * list of network interfaces linearly. A match is found if the masked IP address of + * the network interface equals the masked IP address given to the function. + */ + +struct netif * +ip_route(struct ip_addr *dest) +{ + struct netif *netif; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + return netif; + } + } + + return netif_default; +} + +/* ip_forward: + * + * Forwards an IP packet. It finds an appropriate route for the packet, decrements + * the TTL value of the packet, adjusts the checksum and outputs the packet on the + * appropriate interface. + */ + +static void +ip_forward(struct pbuf *p, struct ip_hdr *iphdr) +{ + struct netif *netif; + + PERF_START; + + if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) { + + LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for ")); +#if IP_DEBUG + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); +#endif /* IP_DEBUG */ + LWIP_DEBUGF(IP_DEBUG, ("\n")); + pbuf_free(p); + return; + } + /* Decrement TTL and send ICMP if ttl == 0. */ + if (--iphdr->hoplim == 0) { +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (iphdr->nexthdr != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + return; + } + + /* Incremental update of the IP checksum. */ + /* if (iphdr->chksum >= htons(0xffff - 0x100)) { + iphdr->chksum += htons(0x100) + 1; + } else { + iphdr->chksum += htons(0x100); + }*/ + + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to ")); +#if IP_DEBUG + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); +#endif /* IP_DEBUG */ + LWIP_DEBUGF(IP_DEBUG, ("\n")); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + + PERF_STOP("ip_forward"); + + netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); +} + +/* ip_input: + * + * This function is called by the network interface device driver when an IP packet is + * received. The function does the basic checks of the IP header such as packet size + * being at least larger than the header size etc. If the packet was not destined for + * us, the packet is forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + */ + +void +ip_input(struct pbuf *p, struct netif *inp) { + struct ip_hdr *iphdr; + struct netif *netif; + + + PERF_START; + +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + + + IP_STATS_INC(ip.recv); + + /* identify the IP header */ + iphdr = p->payload; + + + if (iphdr->v != 6) { + LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n")); +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + return; + } + + /* is this packet for us? */ + for(netif = netif_list; netif != NULL; netif = netif->next) { +#if IP_DEBUG + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest ")); + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr ")); + ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("\n")); +#endif /* IP_DEBUG */ + if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) { + break; + } + } + + + if (netif == NULL) { + /* packet not for us, route or discard */ +#if IP_FORWARD + ip_forward(p, iphdr); +#endif + pbuf_free(p); + return; + } + + pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len)); + + /* send to upper layers */ +#if IP_DEBUG + /* LWIP_DEBUGF("ip_input: \n"); + ip_debug_print(p); + LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/ +#endif /* IP_DEBUG */ + + if(pbuf_header(p, -IP_HLEN)) { + LWIP_ASSERT("Can't move over header in packet", 0); + return; + } + + switch (iphdr->nexthdr) { + case IP_PROTO_UDP: + udp_input(p, inp); + break; + case IP_PROTO_TCP: + tcp_input(p, inp); + break; +#if LWIP_ICMP + case IP_PROTO_ICMP: + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable */ + icmp_dest_unreach(p, ICMP_DUR_PROTO); +#endif /* LWIP_ICMP */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n", + iphdr->nexthdr)); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + } + PERF_STOP("ip_input"); +} + + +/* ip_output_if: + * + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + */ + +err_t +ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, + u8_t proto, struct netif *netif) +{ + struct ip_hdr *iphdr; + + PERF_START; + + LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n")); + IP_STATS_INC(ip.err); + + return ERR_BUF; + } + LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); + + iphdr = p->payload; + + + if (dest != IP_HDRINCL) { + LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n")); + iphdr->hoplim = ttl; + iphdr->nexthdr = proto; + iphdr->len = htons(p->tot_len - IP_HLEN); + ip_addr_set(&(iphdr->dest), dest); + + iphdr->v = 6; + + if (ip_addr_isany(src)) { + ip_addr_set(&(iphdr->src), &(netif->ip_addr)); + } else { + ip_addr_set(&(iphdr->src), src); + } + + } else { + dest = &(iphdr->dest); + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len)); +#if IP_DEBUG + ip_debug_print(p); +#endif /* IP_DEBUG */ + + PERF_STOP("ip_output_if"); + return netif->output(netif, p, dest); +} + +/* ip_output: + * + * Simple interface to ip_output_if. It finds the outgoing network interface and + * calls upon ip_output_if to do the actual work. + */ + +err_t +ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto) +{ + struct netif *netif; + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if (p, src, dest, ttl, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +err_t +ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + netif->addr_hint = addr_hint; + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + netif->addr_hint = NULL; + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = p->payload; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" | %"X16_F"%"X16_F" | %"X16_F"%"X16_F" | (v, traffic class, flow label)\n", + iphdr->v, + iphdr->tclass1, iphdr->tclass2, + iphdr->flow1, iphdr->flow2)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" | %2"U16_F" | %2"U16_F" | (len, nexthdr, hoplim)\n", + ntohs(iphdr->len), + iphdr->nexthdr, + iphdr->hoplim)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[0]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[0]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[1]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[1]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[2]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[2]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", + (ntohl(iphdr->src.addr[3]) >> 16) & 0xffff, + ntohl(iphdr->src.addr[3]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[0]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[0]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[1]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[1]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[2]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[2]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", + (ntohl(iphdr->dest.addr[3]) >> 16) & 0xffff, + ntohl(iphdr->dest.addr[3]) & 0xffff)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6_addr.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6_addr.c new file mode 100644 index 0000000..2da6cea --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/ipv6/ip6_addr.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/inet.h" + +u8_t +ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2, + struct ip_addr *mask) +{ + return((addr1->addr[0] & mask->addr[0]) == (addr2->addr[0] & mask->addr[0]) && + (addr1->addr[1] & mask->addr[1]) == (addr2->addr[1] & mask->addr[1]) && + (addr1->addr[2] & mask->addr[2]) == (addr2->addr[2] & mask->addr[2]) && + (addr1->addr[3] & mask->addr[3]) == (addr2->addr[3] & mask->addr[3])); + +} + +u8_t +ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2) +{ + return(addr1->addr[0] == addr2->addr[0] && + addr1->addr[1] == addr2->addr[1] && + addr1->addr[2] == addr2->addr[2] && + addr1->addr[3] == addr2->addr[3]); +} + +void +ip_addr_set(struct ip_addr *dest, struct ip_addr *src) +{ + SMEMCPY(dest, src, sizeof(struct ip_addr)); + /* dest->addr[0] = src->addr[0]; + dest->addr[1] = src->addr[1]; + dest->addr[2] = src->addr[2]; + dest->addr[3] = src->addr[3];*/ +} + +u8_t +ip_addr_isany(struct ip_addr *addr) +{ + if (addr == NULL) return 1; + return((addr->addr[0] | addr->addr[1] | addr->addr[2] | addr->addr[3]) == 0); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/mem.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/mem.c new file mode 100644 index 0000000..008c2c9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/mem.c @@ -0,0 +1,633 @@ +/** + * @file + * Dynamic memory manager + * + * This is a lightweight replacement for the standard C library malloc(). + * + * If you want to use the standard C library malloc() instead, define + * MEM_LIBC_MALLOC to 1 in your lwipopts.h + * + * To let mem_malloc() use pools (prevents fragmentation and is much faster than + * a heap but might waste some memory), define MEM_USE_POOLS to 1, define + * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list + * of pools like this (more pools can be added between _START and _END): + * + * Define three pools with sizes 256, 512, and 1512 bytes + * LWIP_MALLOC_MEMPOOL_START + * LWIP_MALLOC_MEMPOOL(20, 256) + * LWIP_MALLOC_MEMPOOL(10, 512) + * LWIP_MALLOC_MEMPOOL(5, 1512) + * LWIP_MALLOC_MEMPOOL_END + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" + +#include + +#if MEM_USE_POOLS +/* lwIP head implemented with different sized pools */ + +/** + * Allocate memory: determine the smallest pool that is big enough + * to contain an element of 'size' and get an element from that pool. + * + * @param size the size in bytes of the memory needed + * @return a pointer to the allocated memory or NULL if the pool is empty + */ +void * +mem_malloc(mem_size_t size) +{ + struct memp_malloc_helper *element; + memp_t poolnr; + mem_size_t required_size = size + sizeof(struct memp_malloc_helper); + + for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr++) { +#if MEM_USE_POOLS_TRY_BIGGER_POOL +again: +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + /* is this pool big enough to hold an element of the required size + plus a struct memp_malloc_helper that saves the pool this element came from? */ + if (required_size <= memp_sizes[poolnr]) { + break; + } + } + if (poolnr > MEMP_POOL_LAST) { + LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); + return NULL; + } + element = (struct memp_malloc_helper*)memp_malloc(poolnr); + if (element == NULL) { + /* No need to DEBUGF or ASSERT: This error is already + taken care of in memp.c */ +#if MEM_USE_POOLS_TRY_BIGGER_POOL + /** Try a bigger pool if this one is empty! */ + if (poolnr < MEMP_POOL_LAST) { + poolnr++; + goto again; + } +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + return NULL; + } + + /* save the pool number this element came from */ + element->poolnr = poolnr; + /* and return a pointer to the memory directly after the struct memp_malloc_helper */ + element++; + + return element; +} + +/** + * Free memory previously allocated by mem_malloc. Loads the pool number + * and calls memp_free with that pool number to put the element back into + * its pool + * + * @param rmem the memory element to free + */ +void +mem_free(void *rmem) +{ + struct memp_malloc_helper *hmem = (struct memp_malloc_helper*)rmem; + + LWIP_ASSERT("rmem != NULL", (rmem != NULL)); + LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); + + /* get the original struct memp_malloc_helper */ + hmem--; + + LWIP_ASSERT("hmem != NULL", (hmem != NULL)); + LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); + LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); + + /* and put it in the pool we saved earlier */ + memp_free(hmem->poolnr, hmem); +} + +#else /* MEM_USE_POOLS */ +/* lwIP replacement for your libc malloc() */ + +/** + * The heap is made up as a list of structs of this type. + * This does not have to be aligned since for getting its size, + * we only use the macro SIZEOF_STRUCT_MEM, which automatically alignes. + */ +struct mem { + /** index (-> ram[next]) of the next struct */ + mem_size_t next; + /** index (-> ram[next]) of the next struct */ + mem_size_t prev; + /** 1: this area is used; 0: this area is unused */ + u8_t used; +}; + +/** All allocated blocks will be MIN_SIZE bytes big, at least! + * MIN_SIZE can be overridden to suit your needs. Smaller values save space, + * larger values could prevent too small blocks to fragment the RAM too much. */ +#ifndef MIN_SIZE +#define MIN_SIZE 12 +#endif /* MIN_SIZE */ +/* some alignment macros: we define them here for better source code layout */ +#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) +#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) +#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) + +/** the heap. we need one struct mem at the end and some room for alignment */ +static u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]; +/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ +static u8_t *ram; +/** the last entry, always unused! */ +static struct mem *ram_end; +/** pointer to the lowest free block, this is used for faster search */ +static struct mem *lfree; + +/** concurrent access protection */ +static sys_sem_t mem_sem; + +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + +static volatile u8_t mem_free_count; + +/* Allow mem_free from other (e.g. interrupt) context */ +#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) +#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) +#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) +#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) + +#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + +/* Protect the heap only by using a semaphore */ +#define LWIP_MEM_FREE_DECL_PROTECT() +#define LWIP_MEM_FREE_PROTECT() sys_arch_sem_wait(mem_sem, 0) +#define LWIP_MEM_FREE_UNPROTECT() sys_sem_signal(mem_sem) +/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ +#define LWIP_MEM_ALLOC_DECL_PROTECT() +#define LWIP_MEM_ALLOC_PROTECT() +#define LWIP_MEM_ALLOC_UNPROTECT() + +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + +/** + * "Plug holes" by combining adjacent empty struct mems. + * After this function is through, there should not exist + * one empty struct mem pointing to another empty struct mem. + * + * @param mem this points to a struct mem which just has been freed + * @internal this function is only called by mem_free() and mem_realloc() + * + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + struct mem *nmem; + struct mem *pmem; + + LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); + LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)&ram[mem->next]; + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + lfree = mem; + } + mem->next = nmem->next; + ((struct mem *)&ram[nmem->next])->prev = (u8_t *)mem - ram; + } + + /* plug hole backward */ + pmem = (struct mem *)&ram[mem->prev]; + if (pmem != mem && pmem->used == 0) { + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + lfree = pmem; + } + pmem->next = mem->next; + ((struct mem *)&ram[mem->next])->prev = (u8_t *)pmem - ram; + } +} + +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + struct mem *mem; + + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = LWIP_MEM_ALIGN(ram_heap); + /* initialize the start of the heap */ + mem = (struct mem *)ram; + mem->next = MEM_SIZE_ALIGNED; + mem->prev = 0; + mem->used = 0; + /* initialize the end of the heap */ + ram_end = (struct mem *)&ram[MEM_SIZE_ALIGNED]; + ram_end->used = 1; + ram_end->next = MEM_SIZE_ALIGNED; + ram_end->prev = MEM_SIZE_ALIGNED; + + mem_sem = sys_sem_new(1); + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)ram; + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); +} + +/** + * Put a struct mem back on the heap + * + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); + return; + } + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return; + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + + if (mem < lfree) { + /* the newly freed struct is now the lowest */ + lfree = mem; + } + + MEM_STATS_DEC_USED(used, mem->next - ((u8_t *)mem - ram)); + + /* finally, see if prev or next are free also */ + plug_holes(mem); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + +/** + * In contrast to its name, mem_realloc can only shrink memory, not expand it. + * Since the only use (for now) is in pbuf_realloc (which also can only shrink), + * this shouldn't be a problem! + * + * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked + * @param newsize required size after shrinking (needs to be smaller than or + * equal to the previous size) + * @return for compatibility reasons: is always == rmem, at the moment + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_realloc(void *rmem, mem_size_t newsize) +{ + mem_size_t size; + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + + if(newsize < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + } + + if (newsize > MEM_SIZE_ALIGNED) { + return NULL; + } + + LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_realloc: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return rmem; + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... and its offset pointer */ + ptr = (u8_t *)mem - ram; + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + LWIP_ASSERT("mem_realloc can only shrink memory", newsize <= size); + if (newsize > size) { + /* not supported */ + return NULL; + } + if (newsize == size) { + /* No change in size, simply return */ + return rmem; + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + MEM_STATS_DEC_USED(used, (size - newsize)); + + mem2 = (struct mem *)&ram[mem->next]; + if(mem2->used == 0) { + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + if (lfree == mem2) { + lfree = (struct mem *)&ram[ptr2]; + } + mem2 = (struct mem *)&ram[ptr2]; + mem2->used = 0; + /* restore the next pointer */ + mem2->next = next; + /* link it back to mem */ + mem2->prev = ptr; + /* link mem to it */ + mem->next = ptr2; + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)&ram[mem2->next])->prev = ptr2; + } + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + /* Next struct is used but there's room for another struct mem with + * at least MIN_SIZE_ALIGNED of data. + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + mem2 = (struct mem *)&ram[ptr2]; + if (mem2 < lfree) { + lfree = mem2; + } + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)&ram[mem2->next])->prev = ptr2; + } + /* the original mem->next is used, so no need to plug holes! */ + } + /* else { + next struct mem is used but size between mem and mem2 is not big enough + to create another struct mem + -> don't do anyhting. + -> the remaining space stays unused since it is too small + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; +} + +/** + * Adam's mem_malloc() plus solution for bug #17922 + * Allocate a block of memory with a minimum of 'size' bytes. + * + * @param size is the minimum size of the requested block in bytes. + * @return pointer to allocated memory or NULL if no free memory was found. + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + return NULL; + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + + if(size < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + } + + if (size > MEM_SIZE_ALIGNED) { + return NULL; + } + + /* protect the heap from concurrent access */ + sys_arch_sem_wait(mem_sem, 0); + LWIP_MEM_ALLOC_PROTECT(); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* run as long as a mem_free disturbed mem_malloc */ + do { + local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE_ALIGNED - size; + ptr = ((struct mem *)&ram[ptr])->next) { + mem = (struct mem *)&ram[ptr]; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* allow mem_free to run */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + local_mem_free_count = mem_free_count; + } + mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing + * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') + * -> split large block, create empty remainder, + * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if + * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + /* create mem2 struct */ + mem2 = (struct mem *)&ram[ptr2]; + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + /* and insert it between mem and mem->next */ + mem->next = ptr2; + mem->used = 1; + + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + } else { + /* (a mem2 struct does no fit into the user data space of mem and mem->next will always + * be used at this point: if not we have 2 unused structs in a row, plug_holes should have + * take care of this). + * -> near fit or excact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + MEM_STATS_INC_USED(used, mem->next - ((u8_t *)mem - ram)); + } + + if (mem == lfree) { + /* Find next free block after mem and update lowest free pointer */ + while (lfree->used && lfree != ram_end) { + LWIP_MEM_ALLOC_UNPROTECT(); + /* prevent high interrupt latency... */ + LWIP_MEM_ALLOC_PROTECT(); + lfree = (struct mem *)&ram[lfree->next]; + } + LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); + } + LWIP_MEM_ALLOC_UNPROTECT(); + sys_sem_signal(mem_sem); + LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", + (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + } + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + LWIP_MEM_ALLOC_UNPROTECT(); + sys_sem_signal(mem_sem); + return NULL; +} + +#endif /* MEM_USE_POOLS */ +/** + * Contiguously allocates enough space for count objects that are size bytes + * of memory each and returns a pointer to the allocated memory. + * + * The allocated memory is filled with bytes of value zero. + * + * @param count number of objects to allocate + * @param size size of the objects to allocate + * @return pointer to allocated memory / NULL pointer if there is an error + */ +void *mem_calloc(mem_size_t count, mem_size_t size) +{ + void *p; + + /* allocate 'count' objects of size 'size' */ + p = mem_malloc(count * size); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } + return p; +} + +#endif /* !MEM_LIBC_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/memp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/memp.c new file mode 100644 index 0000000..8a34c4b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/memp.c @@ -0,0 +1,386 @@ +/** + * @file + * Dynamic pool memory manager + * + * lwIP has dedicated pools for many structures (netconn, protocol control blocks, + * packet buffers, ...). All these pools are managed here. + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/udp.h" +#include "lwip/raw.h" +#include "lwip/tcp.h" +#include "lwip/igmp.h" +#include "lwip/api.h" +#include "lwip/api_msg.h" +#include "lwip/tcpip.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "netif/etharp.h" +#include "lwip/ip_frag.h" + +#include + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +struct memp { + struct memp *next; +#if MEMP_OVERFLOW_CHECK + const char *file; + int line; +#endif /* MEMP_OVERFLOW_CHECK */ +}; + +#if MEMP_OVERFLOW_CHECK +/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning + * and at the end of each element, initialize them as 0xcd and check + * them later. */ +/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, + * every single element in each pool is checked! + * This is VERY SLOW but also very helpful. */ +/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in + * lwipopts.h to change the amount reserved for checking. */ +#ifndef MEMP_SANITY_REGION_BEFORE +#define MEMP_SANITY_REGION_BEFORE 16 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#if MEMP_SANITY_REGION_BEFORE > 0 +#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) +#else +#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#ifndef MEMP_SANITY_REGION_AFTER +#define MEMP_SANITY_REGION_AFTER 16 +#endif /* MEMP_SANITY_REGION_AFTER*/ +#if MEMP_SANITY_REGION_AFTER > 0 +#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) +#else +#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_AFTER*/ + +/* MEMP_SIZE: save space for struct memp and for sanity check */ +#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) + +#else /* MEMP_OVERFLOW_CHECK */ + +/* No sanity checks + * We don't need to preserve the struct memp while not allocated, so we + * can save a little space and set MEMP_SIZE to 0. + */ +#define MEMP_SIZE 0 +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_OVERFLOW_CHECK */ + +/** This array holds the first free element of each pool. + * Elements form a linked list. */ +static struct memp *memp_tab[MEMP_MAX]; + +#else /* MEMP_MEM_MALLOC */ + +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_MEM_MALLOC */ + +/** This array holds the element sizes of each pool. */ +#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC +static +#endif +const u16_t memp_sizes[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), +#include "lwip/memp_std.h" +}; + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +/** This array holds the number of elements in each pool. */ +static const u16_t memp_num[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (num), +#include "lwip/memp_std.h" +}; + +/** This array holds a textual description of each pool. */ +#ifdef LWIP_DEBUG +static const char *memp_desc[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (desc), +#include "lwip/memp_std.h" +}; +#endif /* LWIP_DEBUG */ + +/** This is the actual memory used by the pools. */ +static u8_t memp_memory[MEM_ALIGNMENT - 1 +#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) +#include "lwip/memp_std.h" +]; + +#if MEMP_SANITY_CHECK +/** + * Check that memp-lists don't form a circle + */ +static int +memp_sanity(void) +{ + s16_t i, c; + struct memp *m, *n; + + for (i = 0; i < MEMP_MAX; i++) { + for (m = memp_tab[i]; m != NULL; m = m->next) { + c = 1; + for (n = memp_tab[i]; n != NULL; n = n->next) { + if (n == m && --c < 0) { + return 0; + } + } + } + } + return 1; +} +#endif /* MEMP_SANITY_CHECK*/ +#if MEMP_OVERFLOW_CHECK +/** + * Check if a memp element was victim of an overflow + * (e.g. the restricted area after it has been altered) + * + * @param p the memp element to check + * @param memp_size the element size of the pool p comes from + */ +static void +memp_overflow_check_element(struct memp *p, u16_t memp_size) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { + if (m[k] != 0xcd) { + LWIP_ASSERT("detected memp underflow!", 0); + } + } +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_size; + for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { + if (m[k] != 0xcd) { + LWIP_ASSERT("detected memp overflow!", 0); + } + } +#endif +} + +/** + * Do an overflow check for all elements in every pool. + * + * @see memp_overflow_check_element for a description of the check + */ +static void +memp_overflow_check_all(void) +{ + u16_t i, j; + struct memp *p; + + p = LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element(p, memp_sizes[i]); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} + +/** + * Initialize the restricted areas of all memp elements in every pool. + */ +static void +memp_overflow_init(void) +{ + u16_t i, j; + struct memp *p; + u8_t *m; + + p = LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; + memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); +#endif + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} +#endif /* MEMP_OVERFLOW_CHECK */ + +/** + * Initialize this module. + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + MEMP_STATS_AVAIL(used, i, 0); + MEMP_STATS_AVAIL(max, i, 0); + MEMP_STATS_AVAIL(err, i, 0); + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + } + + memp = LWIP_MEM_ALIGN(memp_memory); + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + memp_tab[i] = NULL; + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + memp->next = memp_tab[i]; + memp_tab[i] = memp; + memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] +#if MEMP_OVERFLOW_CHECK + + MEMP_SANITY_REGION_AFTER_ALIGNED +#endif + ); + } + } +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + +/** + * Get an element from a specific pool. + * + * @param type the pool to get an element from + * + * the debug version has two more parameters: + * @param file file name calling this function + * @param line number of line where this function is called + * + * @return a pointer to the allocated memory or a NULL pointer on error + */ +void * +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + + if (memp != NULL) { + memp_tab[type] = memp->next; +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; +} + +/** + * Put an element back into its pool. + * + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)((u8_t*)mem - MEMP_SIZE); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#else + memp_overflow_check_element(memp, memp_sizes[type]); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + + memp->next = memp_tab[type]; + memp_tab[type] = memp; + +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + +#endif /* MEMP_MEM_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/netif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/netif.c new file mode 100644 index 0000000..6c697e7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/netif.c @@ -0,0 +1,687 @@ +/** + * @file + * lwIP network interface abstraction + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/tcp.h" +#include "lwip/snmp.h" +#include "lwip/igmp.h" +#include "netif/etharp.h" +#if ENABLE_LOOPBACK +#include "lwip/sys.h" +#if LWIP_NETIF_LOOPBACK_MULTITHREADING +#include "lwip/tcpip.h" +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_AUTOIP +#include "lwip/autoip.h" +#endif /* LWIP_AUTOIP */ +#if LWIP_DHCP +#include "lwip/dhcp.h" +#endif /* LWIP_DHCP */ + +#if LWIP_NETIF_STATUS_CALLBACK +#define NETIF_STATUS_CALLBACK(n) { if (n->status_callback) (n->status_callback)(n); } +#else +#define NETIF_STATUS_CALLBACK(n) { /* NOP */ } +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +#define NETIF_LINK_CALLBACK(n) { if (n->link_callback) (n->link_callback)(n); } +#else +#define NETIF_LINK_CALLBACK(n) { /* NOP */ } +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +struct netif *netif_list; +struct netif *netif_default; + +/** + * Add a network interface to the list of lwIP netifs. + * + * @param netif a pre-allocated netif structure + * @param ipaddr IP address for the new netif + * @param netmask network mask for the new netif + * @param gw default gateway IP address for the new netif + * @param state opaque data passed to the new netif + * @param init callback function that initializes the interface + * @param input callback function that is called to pass + * ingress packets up in the protocol layer stack. + * + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, + struct ip_addr *gw, + void *state, + err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) +{ + static u8_t netifnum = 0; + + /* reset new interface configuration state */ + netif->ip_addr.addr = 0; + netif->netmask.addr = 0; + netif->gw.addr = 0; + netif->flags = 0; +#if LWIP_DHCP + /* netif not under DHCP control by default */ + netif->dhcp = NULL; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /* netif not under AutoIP control by default */ + netif->autoip = NULL; +#endif /* LWIP_AUTOIP */ +#if LWIP_NETIF_STATUS_CALLBACK + netif->status_callback = NULL; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + netif->link_callback = NULL; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_IGMP + netif->igmp_mac_filter = NULL; +#endif /* LWIP_IGMP */ +#if ENABLE_LOOPBACK + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + netif->num = netifnum++; + netif->input = input; +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = NULL; +#endif /* LWIP_NETIF_HWADDRHINT*/ +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + return NULL; + } + + /* add this netif to the list */ + netif->next = netif_list; + netif_list = netif; + snmp_inc_iflist(); + +#if LWIP_IGMP + /* start IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_start( netif); + } +#endif /* LWIP_IGMP */ + + LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", + netif->name[0], netif->name[1])); + ip_addr_debug_print(NETIF_DEBUG, ipaddr); + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; +} + +/** + * Change IP address configuration for a network interface (including netmask + * and default gateway). + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * @param netmask the new netmask + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, + struct ip_addr *gw) +{ + netif_set_ipaddr(netif, ipaddr); + netif_set_netmask(netif, netmask); + netif_set_gw(netif, gw); +} + +/** + * Remove a network interface from the list of lwIP netifs. + * + * @param netif the network interface to remove + */ +void netif_remove(struct netif * netif) +{ + if ( netif == NULL ) return; + +#if LWIP_IGMP + /* stop IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_stop( netif); + } +#endif /* LWIP_IGMP */ + + snmp_delete_ipaddridx_tree(netif); + + /* is it the first netif? */ + if (netif_list == netif) { + netif_list = netif->next; + snmp_dec_iflist(); + } + else { + /* look for netif further down the list */ + struct netif * tmpNetif; + for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { + if (tmpNetif->next == netif) { + tmpNetif->next = netif->next; + snmp_dec_iflist(); + break; + } + } + if (tmpNetif == NULL) + return; /* we didn't find any netif today */ + } + /* this netif is default? */ + if (netif_default == netif) + /* reset default netif */ + netif_set_default(NULL); + LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); +} + +/** + * Find a network interface by searching for its name + * + * @param name the name of the netif (like netif->name) plus concatenated number + * in ascii representation (e.g. 'en0') + */ +struct netif * +netif_find(char *name) +{ + struct netif *netif; + u8_t num; + + if (name == NULL) { + return NULL; + } + + num = name[2] - '0'; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (num == netif->num && + name[0] == netif->name[0] && + name[1] == netif->name[1]) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); + return netif; + } + } + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); + return NULL; +} + +/** + * Change the IP address of a network interface + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr) +{ + /* TODO: Handling of obsolete pcbs */ + /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) + { + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + while (pcb != NULL) { + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + pcb = next; + } else { + pcb = pcb->next; + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(&(lpcb->local_ip), ipaddr); + } + } + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + snmp_insert_ipaddridx_tree(netif); + snmp_insert_iprteidx_tree(0,netif); + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1(&netif->ip_addr), + ip4_addr2(&netif->ip_addr), + ip4_addr3(&netif->ip_addr), + ip4_addr4(&netif->ip_addr))); +} + +/** + * Change the default gateway for a network interface + * + * @param netif the network interface to change + * @param gw the new default gateway + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, struct ip_addr *gw) +{ + ip_addr_set(&(netif->gw), gw); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1(&netif->gw), + ip4_addr2(&netif->gw), + ip4_addr3(&netif->gw), + ip4_addr4(&netif->gw))); +} + +/** + * Change the netmask of a network interface + * + * @param netif the network interface to change + * @param netmask the new netmask + * + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, struct ip_addr *netmask) +{ + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + snmp_insert_iprteidx_tree(0, netif); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1(&netif->netmask), + ip4_addr2(&netif->netmask), + ip4_addr3(&netif->netmask), + ip4_addr4(&netif->netmask))); +} + +#if LWIP_NETIF_HOSTNAME +void netif_set_hostname(struct netif *netif, char* hostname){ + netif->hostname = hostname; +} +#endif + +/** + * Set a network interface as the default network interface + * (used to output all packets for which no specific route is found) + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + if (netif == NULL) + { + /* remove default route */ + snmp_delete_iprteidx_tree(1, netif); + } + else + { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + +/** + * Bring an interface up, available for processing + * traffic. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_up(struct netif *netif) +{ + if ( !(netif->flags & NETIF_FLAG_UP )) { + netif->flags |= NETIF_FLAG_UP; + +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif /* LWIP_SNMP */ + + NETIF_LINK_CALLBACK(netif); + NETIF_STATUS_CALLBACK(netif); + +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } +} + +/** + * Bring an interface down, disabling any traffic processing. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_down(struct netif *netif) +{ + if ( netif->flags & NETIF_FLAG_UP ) + { + netif->flags &= ~NETIF_FLAG_UP; +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif + + NETIF_LINK_CALLBACK(netif); + NETIF_STATUS_CALLBACK(netif); + } +} + +/** + * Ask if an interface is up + */ +u8_t netif_is_up(struct netif *netif) +{ + return (netif->flags & NETIF_FLAG_UP)?1:0; +} + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Set callback to be called when interface is brought up/down + */ +void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif )) +{ + if ( netif ) + netif->status_callback = status_callback; +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Called by a driver when its link goes up + */ +void netif_set_link_up(struct netif *netif ) +{ + netif->flags |= NETIF_FLAG_LINK_UP; + +#if LWIP_DHCP + if (netif->dhcp) { + dhcp_network_changed(netif); + } +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP + if (netif->autoip) { + autoip_network_changed(netif); + } +#endif /* LWIP_AUTOIP */ + + if (netif->flags & NETIF_FLAG_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } + NETIF_LINK_CALLBACK(netif); +} + +/** + * Called by a driver when its link goes down + */ +void netif_set_link_down(struct netif *netif ) +{ + netif->flags &= ~NETIF_FLAG_LINK_UP; + NETIF_LINK_CALLBACK(netif); +} + +/** + * Ask if a link is up + */ +u8_t netif_is_link_up(struct netif *netif) +{ + return (netif->flags & NETIF_FLAG_LINK_UP) ? 1 : 0; +} + +/** + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif )) +{ + if (netif) { + netif->link_callback = link_callback; + } +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if ENABLE_LOOPBACK +/** + * Send an IP packet to be received on the same netif (loopif-like). + * The pbuf is simply copied and handed back to netif->input. + * In multithreaded mode, this is done directly since netif->input must put + * the packet on a queue. + * In callback mode, the packet is put on an internal queue and is fed to + * netif->input by netif_poll(). + * + * @param netif the lwip network interface structure + * @param p the (IP) packet to 'send' + * @param ipaddr the ip address to send the packet to (not used) + * @return ERR_OK if the packet has been sent + * ERR_MEM if the pbuf used to copy the packet couldn't be allocated + */ +err_t +netif_loop_output(struct netif *netif, struct pbuf *p, + struct ip_addr *ipaddr) +{ + struct pbuf *r; + err_t err; + struct pbuf *last; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = 0; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + SYS_ARCH_DECL_PROTECT(lev); + LWIP_UNUSED_ARG(ipaddr); + + /* Allocate a new pbuf */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + return ERR_MEM; + } +#if LWIP_LOOPBACK_MAX_PBUFS + clen = pbuf_clen(r); + /* check for overflow or too many pbuf on queue */ + if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || + ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { + pbuf_free(r); + r = NULL; + return ERR_MEM; + } + netif->loop_cnt_current += clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + + /* Copy the whole pbuf queue p into the single pbuf r */ + if ((err = pbuf_copy(r, p)) != ERR_OK) { + pbuf_free(r); + r = NULL; + return err; + } + + /* Put the packet on a linked list which gets emptied through calling + netif_poll(). */ + + /* let last point to the last pbuf in chain r */ + for (last = r; last->next != NULL; last = last->next); + + SYS_ARCH_PROTECT(lev); + if(netif->loop_first != NULL) { + LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); + netif->loop_last->next = r; + netif->loop_last = last; + } else { + netif->loop_first = r; + netif->loop_last = last; + } + SYS_ARCH_UNPROTECT(lev); + +#if LWIP_NETIF_LOOPBACK_MULTITHREADING + /* For multithreading environment, schedule a call to netif_poll */ + tcpip_callback((void (*)(void *))(netif_poll), netif); +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ + + return ERR_OK; +} + +/** + * Call netif_poll() in the main loop of your application. This is to prevent + * reentering non-reentrant functions like tcp_input(). Packets passed to + * netif_loop_output() are put on a list that is passed to netif->input() by + * netif_poll(). + */ +void +netif_poll(struct netif *netif) +{ + struct pbuf *in; + SYS_ARCH_DECL_PROTECT(lev); + + do { + /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ + SYS_ARCH_PROTECT(lev); + in = netif->loop_first; + if(in != NULL) { + struct pbuf *in_end = in; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = pbuf_clen(in); + /* adjust the number of pbufs on queue */ + LWIP_ASSERT("netif->loop_cnt_current underflow", + ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); + netif->loop_cnt_current -= clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + while(in_end->len != in_end->tot_len) { + LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); + in_end = in_end->next; + } + /* 'in_end' now points to the last pbuf from 'in' */ + if(in_end == netif->loop_last) { + /* this was the last pbuf in the list */ + netif->loop_first = netif->loop_last = NULL; + } else { + /* pop the pbuf off the list */ + netif->loop_first = in_end->next; + LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); + } + /* De-queue the pbuf from its successors on the 'loop_' list. */ + in_end->next = NULL; + } + SYS_ARCH_UNPROTECT(lev); + + if(in != NULL) { + /* loopback packets are always IP packets! */ + if(ip_input(in, netif) != ERR_OK) { + pbuf_free(in); + } + /* Don't reference the packet any more! */ + in = NULL; + } + /* go on while there is a packet on the list */ + } while(netif->loop_first != NULL); +} + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +/** + * Calls netif_poll() for every netif on the netif_list. + */ +void +netif_poll_all(void) +{ + struct netif *netif = netif_list; + /* loop through netifs */ + while (netif != NULL) { + netif_poll(netif); + /* proceed to next network interface */ + netif = netif->next; + } +} +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/pbuf.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/pbuf.c new file mode 100644 index 0000000..59de5bc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/pbuf.c @@ -0,0 +1,929 @@ +/** + * @file + * Packet buffer management + * + * Packets are built from the pbuf data structure. It supports dynamic + * memory allocation for packet contents or can reference externally + * managed packet contents both in RAM and ROM. Quick allocation for + * incoming packets is provided through pools with fixed sized pbufs. + * + * A packet may span over multiple pbufs, chained as a singly linked + * list. This is called a "pbuf chain". + * + * Multiple packets may be queued, also using this singly linked list. + * This is called a "packet queue". + * + * So, a packet queue consists of one or more pbuf chains, each of + * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE + * NOT SUPPORTED!!! Use helper structs to queue multiple packets. + * + * The differences between a pbuf chain and a packet queue are very + * precise but subtle. + * + * The last pbuf of a packet has a ->tot_len field that equals the + * ->len field. It can be found by traversing the list. If the last + * pbuf of a packet has a ->next field other than NULL, more packets + * are on the queue. + * + * Therefore, looping through a pbuf of a single packet, has an + * loop end condition (tot_len == p->len), NOT (next == NULL). + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/stats.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "arch/perf.h" +#if TCP_QUEUE_OOSEQ +#include "lwip/tcp.h" +#endif + +#include + +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) +/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically + aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ +#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) + +#if !TCP_QUEUE_OOSEQ || NO_SYS +#define PBUF_POOL_IS_EMPTY() +#else /* !TCP_QUEUE_OOSEQ || NO_SYS */ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ + +#if PBUF_POOL_FREE_OOSEQ +#include "lwip/tcpip.h" +#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() +static u8_t pbuf_free_ooseq_queued; +/** + * Attempt to reclaim some memory from queued out-of-sequence TCP segments + * if we run out of pool pbufs. It's better to give priority to new packets + * if we're running out. + * + * This must be done in the correct thread context therefore this function + * can only be used with NO_SYS=0 and through tcpip_callback. + */ +static void +pbuf_free_ooseq(void* arg) +{ + struct tcp_pcb* pcb; + SYS_ARCH_DECL_PROTECT(old_level); + LWIP_UNUSED_ARG(arg); + + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_queued = 0; + SYS_ARCH_UNPROTECT(old_level); + + for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { + if (NULL != pcb->ooseq) { + /** Free the ooseq pbufs of one PCB only */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + return; + } + } +} + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ + u8_t queued; + SYS_ARCH_DECL_PROTECT(old_level); + + SYS_ARCH_PROTECT(old_level); + queued = pbuf_free_ooseq_queued; + pbuf_free_ooseq_queued = 1; + SYS_ARCH_UNPROTECT(old_level); + + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + if(tcpip_callback_with_block(pbuf_free_ooseq, NULL, 0) != ERR_OK) { + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_queued = 0; + SYS_ARCH_UNPROTECT(old_level); + } + } +} +#endif /* PBUF_POOL_FREE_OOSEQ */ +#endif /* !TCP_QUEUE_OOSEQ || NO_SYS */ + +/** + * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). + * + * The actual memory allocated for the pbuf is determined by the + * layer at which the pbuf is allocated and the requested size + * (from the size parameter). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type this parameter decides how and where the pbuf + * should be allocated as follows: + * + * - PBUF_RAM: buffer memory for pbuf is allocated as one large + * chunk. This includes protocol headers as well. + * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for + * protocol headers. Additional headers must be prepended + * by allocating another pbuf and chain in to the front of + * the ROM pbuf. It is assumed that the memory used is really + * similar to ROM in that it is immutable and will not be + * changed. Memory which is dynamic should generally not + * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. + * - PBUF_REF: no buffer memory is allocated for the pbuf, even for + * protocol headers. It is assumed that the pbuf is only + * being used in a single thread. If the pbuf gets queued, + * then pbuf_take should be called to copy the buffer. + * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from + * the pbuf pool that is allocated during pbuf_init(). + * + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + struct pbuf *p, *q, *r; + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + offset = 0; + switch (layer) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset += PBUF_TRANSPORT_HLEN; + /* FALLTHROUGH */ + case PBUF_IP: + /* add room for IP layer header */ + offset += PBUF_IP_HLEN; + /* FALLTHROUGH */ + case PBUF_LINK: + /* add room for link layer header */ + offset += PBUF_LINK_HLEN; + break; + case PBUF_RAW: + break; + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + } + + switch (type) { + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = memp_malloc(MEMP_PBUF_POOL); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + PBUF_POOL_IS_EMPTY(); + return NULL; + } + p->type = type; + p->next = NULL; + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + /* remaining length to be allocated */ + rem_len = length - p->len; + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + q = memp_malloc(MEMP_PBUF_POOL); + if (q == NULL) { + PBUF_POOL_IS_EMPTY(); + /* free chain so far allocated */ + pbuf_free(p); + /* bail out unsuccesfully */ + return NULL; + } + q->type = type; + q->flags = 0; + q->next = NULL; + /* make previous pbuf point to this pbuf */ + r->next = q; + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + /* calculate remaining length to be allocated */ + rem_len -= q->len; + /* remember this pbuf for linkage in next iteration */ + r = q; + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + if (p == NULL) { + return NULL; + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = memp_malloc(MEMP_PBUF); + if (p == NULL) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + break; + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + } + /* set reference count */ + p->ref = 1; + /* set flags */ + p->flags = 0; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; +} + + +/** + * Shrink a pbuf chain to a desired length. + * + * @param p pbuf to shrink. + * @param new_len desired new length of pbuf chain + * + * Depending on the desired length, the first few pbufs in a chain might + * be skipped and left unchanged. The new last pbuf in the chain will be + * resized, and any remaining pbufs will be freed. + * + * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. + * @note May not be called on a packet queue. + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + /* enlarging not yet supported */ + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + q = p; + /* should this pbuf be kept? */ + while (rem_len > q->len) { + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + /* proceed to next pbuf in chain */ + q = q->next; + LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); + } + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + /* reallocate and adjust the length of the pbuf that will be split */ + q = mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len); + LWIP_ASSERT("mem_realloc give q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + q->tot_len = q->len; + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + /* free remaining pbufs in chain */ + pbuf_free(q->next); + } + /* q is last packet in chain */ + q->next = NULL; + +} + +/** + * Adjusts the payload pointer to hide or reveal headers in the payload. + * + * Adjusts the ->payload pointer so that space for a header + * (dis)appears in the pbuf payload. + * + * The ->payload, ->tot_len and ->len fields are adjusted. + * + * @param p pbuf to change the header size. + * @param header_size_increment Number of bytes to increment header size which + * increases the size of the pbuf. New space is on the front. + * (Using a negative value decreases the header size.) + * If hdr_size_inc is 0, this function does nothing and returns succesful. + * + * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so + * the call will fail. A check is made that the increase in header size does + * not move the payload pointer in front of the start of the buffer. + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) + return 0; + + if (header_size_increment < 0){ + increment_magnitude = -header_size_increment; + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + } else { + increment_magnitude = header_size_increment; +#if 0 + /* Can't assert these as some callers speculatively call + pbuf_header() to see if it's OK. Will return 1 below instead. */ + /* Check that we've got the correct type of pbuf to work with */ + LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", + p->type == PBUF_RAM || p->type == PBUF_POOL); + /* Check that we aren't going to move off the beginning of the pbuf */ + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + /* remember current payload pointer */ + payload = p->payload; + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + /* bail out unsuccesfully */ + return 1; + } + /* pbuf types refering to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccesfully */ + return 1; + } + } + else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + } + /* modify pbuf length fields */ + p->len += header_size_increment; + p->tot_len += header_size_increment; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; +} + +/** + * Dereference a pbuf chain or queue and deallocate any no-longer-used + * pbufs at the head of this chain or queue. + * + * Decrements the pbuf reference count. If it reaches zero, the pbuf is + * deallocated. + * + * For a pbuf chain, this is repeated for each pbuf in the chain, + * up to the first pbuf which has a non-zero reference count after + * decrementing. So, when all reference counts are one, the whole + * chain is free'd. + * + * @param p The pbuf (chain) to be dereferenced. + * + * @return the number of pbufs that were de-allocated + * from the head of the chain. + * + * @note MUST NOT be called on a packet queue (Not verified to work yet). + * @note the reference counter of a pbuf equals the number of pointers + * that refer to the pbuf (or into the pbuf). + * + * @internal examples: + * + * Assuming existing chains a->b->c with the following reference + * counts, calling pbuf_free(a) results in: + * + * 1->2->3 becomes ...1->3 + * 3->3->3 becomes 2->3->3 + * 1->1->2 becomes ......1 + * 2->1->1 becomes 1->1->1 + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + u16_t ref; + SYS_ARCH_DECL_PROTECT(old_level); + /* Since decrementing ref cannot be guaranteed to be a single machine operation + * we must protect it. We put the new ref into a local variable to prevent + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + /* remember next pbuf in chain for next iteration */ + q = p->next; + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + memp_free(MEMP_PBUF_POOL, p); + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + memp_free(MEMP_PBUF, p); + /* type == PBUF_RAM */ + } else { + mem_free(p); + } + count++; + /* proceed to next pbuf */ + p = q; + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; +} + +/** + * Count number of pbufs in a chain + * + * @param p first pbuf of chain + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + u8_t len; + + len = 0; + while (p != NULL) { + ++len; + p = p->next; + } + return len; +} + +/** + * Increment the reference count of the pbuf. + * + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Concatenate two pbufs (each may be a pbuf chain) and take over + * the caller's reference of the tail pbuf. + * + * @note The caller MAY NOT reference the tail pbuf afterwards. + * Use pbuf_chain() for that purpose. + * + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +/** + * Chain two pbufs (or pbuf chains) together. + * + * The caller MUST call pbuf_free(t) once it has stopped + * using it. Use pbuf_cat() instead if you no longer use t. + * + * @param h head pbuf (chain) + * @param t tail pbuf (chain) + * @note The pbufs MUST belong to the same packet. + * @note MAY NOT be called on a packet queue. + * + * The ->tot_len fields of all pbufs of the head chain are adjusted. + * The ->next field of the last pbuf of the head chain is adjusted. + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + pbuf_cat(h, t); + /* t is now referenced by h */ + pbuf_ref(t); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + +/** + * Dechains the first pbuf from its succeeding pbufs in the chain. + * + * Makes p->tot_len field equal to p->len. + * @param p pbuf to dechain + * @return remainder of the pbuf chain, or NULL if it was de-allocated. + * @note May not be called on a packet queue. + */ +struct pbuf * +pbuf_dechain(struct pbuf *p) +{ + struct pbuf *q; + u8_t tail_gone = 1; + /* tail */ + q = p->next; + /* pbuf has successor in chain? */ + if (q != NULL) { + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); + /* enforce invariant if assertion is disabled */ + q->tot_len = p->tot_len - p->len; + /* decouple pbuf from remainder */ + p->next = NULL; + /* total length of pbuf p is its own length only */ + p->tot_len = p->len; + /* q is no longer referenced by p, free it */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); + tail_gone = pbuf_free(q); + if (tail_gone > 0) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, + ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); + } + /* return remaining tail or NULL if deallocated */ + } + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); + return ((tail_gone > 0) ? NULL : q); +} + +/** + * + * Create PBUF_RAM copies of pbufs. + * + * Used to queue packets on behalf of the lwIP stack, such as + * ARP based queueing. + * + * @note You MUST explicitly use p = pbuf_take(p); + * + * @note Only one packet is copied, no packet queue! + * + * @param p_to pbuf destination of the copy + * @param p_from pbuf source of the copy + * + * @return ERR_OK if pbuf was copied + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + u16_t offset_to=0, offset_from=0, len; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); + + /* iterate through pbuf chain */ + do + { + LWIP_ASSERT("p_to != NULL", p_to != NULL); + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + offset_to += len; + offset_from += len; + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + if (offset_to == p_to->len) { + /* on to next p_to (if any) */ + offset_to = 0; + p_to = p_to->next; + } + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + /* on to next p_from (if any) */ + offset_from = 0; + p_from = p_from->next; + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; +} + +/** + * Copy (part of) the contents of a packet buffer + * to an application supplied buffer. + * + * @param buf the pbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough). No more + * than buf->tot_len will be copied, irrespective of len + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + + left = 0; + + if((buf == NULL) || (dataptr == NULL)) { + return 0; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + if ((offset != 0) && (offset >= p->len)) { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + if (buf_copy_len > len) + buf_copy_len = len; + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + copied_total += buf_copy_len; + left += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + return copied_total; +} + +/** + * Copy application supplied data into a pbuf. + * This function can only be used to copy the equivalent of buf->tot_len data. + * + * @param buf pbuf to fill with data + * @param dataptr application supplied data buffer + * @param len length of the application supplied data buffer + * + * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough + */ +err_t +pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) +{ + struct pbuf *p; + u16_t buf_copy_len; + u16_t total_copy_len = len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;); + + if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { + return ERR_ARG; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; total_copy_len != 0; p = p->next) { + LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); + buf_copy_len = total_copy_len; + if (buf_copy_len > p->len) { + /* this pbuf cannot hold all remaining data */ + buf_copy_len = p->len; + } + /* copy the necessary parts of the buffer */ + MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len); + total_copy_len -= buf_copy_len; + copied_total += buf_copy_len; + } + LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); + return ERR_OK; +} + +/** + * Creates a single pbuf out of a queue of pbufs. + * + * @remark: The source pbuf 'p' is not freed by this function because that can + * be illegal in some places! + * + * @param p the source pbuf + * @param layer pbuf_layer of the new pbuf + * + * @return a new, single pbuf (p->next is NULL) + * or the old pbuf if allocation fails + */ +struct pbuf* +pbuf_coalesce(struct pbuf *p, pbuf_layer layer) +{ + struct pbuf *q; + err_t err; + if (p->next == NULL) { + return p; + } + q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); + if (q == NULL) { + /* @todo: what do we do now? */ + return p; + } + err = pbuf_copy(q, p); + LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); + pbuf_free(p); + return q; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/raw.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/raw.c new file mode 100644 index 0000000..57acd07 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/raw.c @@ -0,0 +1,353 @@ +/** + * @file + * Implementation of raw protocol PCBs for low-level handling of + * different types of protocols besides (or overriding) those + * already available in lwIP. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/inet.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/raw.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" + +#include + +/** The list of RAW PCBs */ +static struct raw_pcb *raw_pcbs; + +/** + * Determine if in incoming IP packet is covered by a RAW PCB + * and if so, pass it to a user-provided receive callback function. + * + * Given an incoming IP datagram (as a chain of pbufs) this function + * finds a corresponding RAW PCB and calls the corresponding receive + * callback function. + * + * @param p pbuf to be demultiplexed to a RAW PCB. + * @param inp network interface on which the datagram was received. + * @return - 1 if the packet has been eaten by a RAW PCB receive + * callback function. The caller MAY NOT not reference the + * packet any longer, and MAY NOT call pbuf_free(). + * @return - 0 if packet is not eaten (pbuf is still referenced by the + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + + LWIP_UNUSED_ARG(inp); + + iphdr = p->payload; + proto = IPH_PROTO(iphdr); + + prev = NULL; + pcb = raw_pcbs; + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + if (pcb->protocol == proto) { +#if IP_SOF_BROADCAST_RECV + /* broadcast filter? */ + if ((pcb->so_options & SOF_BROADCAST) || !ip_addr_isbroadcast(&(iphdr->dest), inp)) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv != NULL) { + /* the receive callback function did not eat the packet? */ + if (pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src)) != 0) { + /* receive function ate the packet */ + p = NULL; + eaten = 1; + if (prev != NULL) { + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + } + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + pcb = pcb->next; + } + return eaten; +} + +/** + * Bind a RAW PCB. + * + * @param pcb RAW PCB to be bound with a local address ipaddr. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified IP address is already bound to by + * another RAW PCB. + * + * @see raw_disconnect() + */ +err_t +raw_bind(struct raw_pcb *pcb, struct ip_addr *ipaddr) +{ + ip_addr_set(&pcb->local_ip, ipaddr); + return ERR_OK; +} + +/** + * Connect an RAW PCB. This function is required by upper layers + * of lwip. Using the raw api you could use raw_sendto() instead + * + * This will associate the RAW PCB with the remote address. + * + * @param pcb RAW PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * + * @return lwIP error code + * + * @see raw_disconnect() and raw_sendto() + */ +err_t +raw_connect(struct raw_pcb *pcb, struct ip_addr *ipaddr) +{ + ip_addr_set(&pcb->remote_ip, ipaddr); + return ERR_OK; +} + + +/** + * Set the callback function for received packets that match the + * raw PCB's protocol and binding. + * + * The callback function MUST either + * - eat the packet by calling pbuf_free() and returning non-zero. The + * packet will not be passed to other raw PCBs or other protocol layers. + * - not free the packet, and return zero. The packet will be matched + * against further PCBs and/or forwarded to another protocol layers. + * + * @return non-zero if the packet was free()d, zero if the packet remains + * available for others. + */ +void +raw_recv(struct raw_pcb *pcb, + u8_t (* recv)(void *arg, struct raw_pcb *upcb, struct pbuf *p, + struct ip_addr *addr), + void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Send the raw IP packet to the given address. Note that actually you cannot + * modify the IP headers (this is inconsistent with the receive callback where + * you actually get the IP headers), you can only specify the IP payload here. + * It requires some more changes in lwIP. (there will be a raw_send() function + * then.) + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * @param ipaddr the destination address of the IP packet + * + */ +err_t +raw_sendto(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr) +{ + err_t err; + struct netif *netif; + struct ip_addr *src_ip; + struct pbuf *q; /* q will be sent down the stack */ + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); + + /* not enough space to add an IP header to first pbuf in given p chain? */ + if (pbuf_header(p, IP_HLEN)) { + /* allocate header in new pbuf */ + q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); + return ERR_MEM; + } + /* chain header q in front of given pbuf p */ + pbuf_chain(q, p); + /* { first pbuf q points to header pbuf } */ + LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* first pbuf q equals given pbuf */ + q = p; + if(pbuf_header(q, -IP_HLEN)) { + LWIP_ASSERT("Can't restore header we just removed!", 0); + return ERR_MEM; + } + } + + if ((netif = ip_route(ipaddr)) == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to 0x%"X32_F"\n", ipaddr->addr)); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_RTE; + } + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(ipaddr, netif) ) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* use RAW PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = &(pcb->addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT*/ + err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = NULL; +#endif /* LWIP_NETIF_HWADDRHINT*/ + + /* did we chain a header earlier? */ + if (q != p) { + /* free the header */ + pbuf_free(q); + } + return err; +} + +/** + * Send the raw IP packet to the address given by raw_connect() + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * + */ +err_t +raw_send(struct raw_pcb *pcb, struct pbuf *p) +{ + return raw_sendto(pcb, p, &pcb->remote_ip); +} + +/** + * Remove an RAW PCB. + * + * @param pcb RAW PCB to be removed. The PCB is removed from the list of + * RAW PCB's and the data structure is freed from memory. + * + * @see raw_new() + */ +void +raw_remove(struct raw_pcb *pcb) +{ + struct raw_pcb *pcb2; + /* pcb to be removed is first in list? */ + if (raw_pcbs == pcb) { + /* make list start at 2nd pcb */ + raw_pcbs = raw_pcbs->next; + /* pcb not 1st in list */ + } else { + for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in raw_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_RAW_PCB, pcb); +} + +/** + * Create a RAW PCB. + * + * @return The RAW PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) + * + * @see raw_remove() + */ +struct raw_pcb * +raw_new(u8_t proto) { + struct raw_pcb *pcb; + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); + + pcb = memp_malloc(MEMP_RAW_PCB); + /* could allocate RAW PCB? */ + if (pcb != NULL) { + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct raw_pcb)); + pcb->protocol = proto; + pcb->ttl = RAW_TTL; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + return pcb; +} + +#endif /* LWIP_RAW */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_dec.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_dec.c new file mode 100644 index 0000000..650fb40 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_dec.c @@ -0,0 +1,657 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) decoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Retrieves type field from incoming pbuf chain. + * + * @param p points to a pbuf holding an ASN1 coded type field + * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field + * @param type return ASN1 type + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + *type = *msg_ptr; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes length field from incoming pbuf chain into host length. + * + * @param p points to a pbuf holding an ASN1 coded length + * @param ofs points to the offset within the pbuf chain of the ASN1 coded length + * @param octets_used returns number of octets used by the length code + * @param length return host order length, upto 64k + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + if (*msg_ptr < 0x80) + { + /* primitive definite length format */ + *octets_used = 1; + *length = *msg_ptr; + return ERR_OK; + } + else if (*msg_ptr == 0x80) + { + /* constructed indefinite length format, termination with two zero octets */ + u8_t zeros; + u8_t i; + + *length = 0; + zeros = 0; + while (zeros != 2) + { + i = 2; + while (i > 0) + { + i--; + (*length) += 1; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (*msg_ptr == 0) + { + zeros++; + if (zeros == 2) + { + /* stop while (i > 0) */ + i = 0; + } + } + else + { + zeros = 0; + } + } + } + *octets_used = 1; + return ERR_OK; + } + else if (*msg_ptr == 0x81) + { + /* constructed definite length format, one octet */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *length = *msg_ptr; + *octets_used = 2; + return ERR_OK; + } + else if (*msg_ptr == 0x82) + { + u8_t i; + + /* constructed definite length format, two octets */ + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *length |= *msg_ptr; + } + else + { + /* most significant length octet */ + *length = (*msg_ptr) << 8; + } + } + *octets_used = 3; + return ERR_OK; + } + else + { + /* constructed definite length format 3..127 octets, this is too big (>64k) */ + /** @todo: do we need to accept inefficient codings with many leading zero's? */ + *octets_used = 1 + ((*msg_ptr) & 0x7f); + return ERR_ARG; + } + } + p = p->next; + } + + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes positive integer (counter, gauge, timeticks) into u32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +err_t +snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 6)) + { + /* start from zero */ + *value = 0; + if (*msg_ptr & 0x80) + { + /* negative, expecting zero sign bit! */ + return ERR_ARG; + } + else + { + /* positive */ + if ((len > 1) && (*msg_ptr == 0)) + { + /* skip leading "sign byte" octet 0x00 */ + len--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + } + /* OR octets with value */ + while (len > 1) + { + len--; + *value |= *msg_ptr; + *value <<= 8; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + *value |= *msg_ptr; + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes integer into s32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed! + */ +err_t +snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t *lsb_ptr = (u8_t*)value; +#endif +#if BYTE_ORDER == BIG_ENDIAN + u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; +#endif + u8_t sign; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 5)) + { + if (*msg_ptr & 0x80) + { + /* negative, start from -1 */ + *value = -1; + sign = 1; + } + else + { + /* positive, start from 0 */ + *value = 0; + sign = 0; + } + /* OR/AND octets with value */ + while (len > 1) + { + len--; + if (sign) + { + *lsb_ptr &= *msg_ptr; + *value <<= 8; + *lsb_ptr |= 255; + } + else + { + *lsb_ptr |= *msg_ptr; + *value <<= 8; + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (sign) + { + *lsb_ptr &= *msg_ptr; + } + else + { + *lsb_ptr |= *msg_ptr; + } + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes object identifier from incoming message into array of s32_t. + * + * @param p points to a pbuf holding an ASN1 coded object identifier + * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier + * @param len length of the coded object identifier + * @param oid return object identifier struct + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid) +{ + u16_t plen, base; + u8_t *msg_ptr; + s32_t *oid_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + oid->len = 0; + oid_ptr = &oid->id[0]; + if (len > 0) + { + /* first compressed octet */ + if (*msg_ptr == 0x2B) + { + /* (most) common case 1.3 (iso.org) */ + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = 3; + oid_ptr++; + } + else if (*msg_ptr < 40) + { + *oid_ptr = 0; + oid_ptr++; + *oid_ptr = *msg_ptr; + oid_ptr++; + } + else if (*msg_ptr < 80) + { + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 40; + oid_ptr++; + } + else + { + *oid_ptr = 2; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 80; + oid_ptr++; + } + oid->len = 2; + } + else + { + /* accepting zero length identifiers e.g. for + getnext operation. uncommon but valid */ + return ERR_OK; + } + len--; + if (len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) + { + /* sub-identifier uses multiple octets */ + if (*msg_ptr & 0x80) + { + s32_t sub_id = 0; + + while ((*msg_ptr & 0x80) && (len > 1)) + { + len--; + sub_id = (sub_id << 7) + (*msg_ptr & ~0x80); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (!(*msg_ptr & 0x80) && (len > 0)) + { + /* last octet sub-identifier */ + len--; + sub_id = (sub_id << 7) + *msg_ptr; + *oid_ptr = sub_id; + } + } + else + { + /* !(*msg_ptr & 0x80) sub-identifier uses single octet */ + len--; + *oid_ptr = *msg_ptr; + } + if (len > 0) + { + /* remaining oid bytes available ... */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + oid_ptr++; + oid->len++; + } + if (len == 0) + { + /* len == 0, end of oid */ + return ERR_OK; + } + else + { + /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ + return ERR_ARG; + } + + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) + * from incoming message into array. + * + * @param p points to a pbuf holding an ASN1 coded raw data + * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data + * @param len length of the coded raw data (zero is valid, e.g. empty string!) + * @param raw_len length of the raw return value + * @param raw return raw bytes + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + if (len > 0) + { + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + if (raw_len >= len) + { + while (len > 1) + { + /* copy len - 1 octets */ + len--; + *raw = *msg_ptr; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* copy last octet */ + *raw = *msg_ptr; + return ERR_OK; + } + else + { + /* raw_len < len, not enough dst space */ + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; + } + else + { + /* len == 0, empty string */ + return ERR_OK; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_enc.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_enc.c new file mode 100644 index 0000000..77af6b4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/asn1_enc.c @@ -0,0 +1,611 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) encoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Returns octet count for length. + * + * @param length + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) +{ + if (length < 0x80U) + { + *octets_needed = 1; + } + else if (length < 0x100U) + { + *octets_needed = 2; + } + else + { + *octets_needed = 3; + } +} + +/** + * Returns octet count for an u32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +void +snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) +{ + if (value < 0x80UL) + { + *octets_needed = 1; + } + else if (value < 0x8000UL) + { + *octets_needed = 2; + } + else if (value < 0x800000UL) + { + *octets_needed = 3; + } + else if (value < 0x80000000UL) + { + *octets_needed = 4; + } + else + { + *octets_needed = 5; + } +} + +/** + * Returns octet count for an s32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. + */ +void +snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) +{ + if (value < 0) + { + value = ~value; + } + if (value < 0x80L) + { + *octets_needed = 1; + } + else if (value < 0x8000L) + { + *octets_needed = 2; + } + else if (value < 0x800000L) + { + *octets_needed = 3; + } + else + { + *octets_needed = 4; + } +} + +/** + * Returns octet count for an object identifier. + * + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed) +{ + s32_t sub_id; + u8_t cnt; + + cnt = 0; + if (ident_len > 1) + { + /* compressed prefix in one octet */ + cnt++; + ident_len -= 2; + ident += 2; + } + while(ident_len > 0) + { + ident_len--; + sub_id = *ident; + + sub_id >>= 7; + cnt++; + while(sub_id > 0) + { + sub_id >>= 7; + cnt++; + } + ident++; + } + *octets_needed = cnt; +} + +/** + * Encodes ASN type field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param type input ASN1 type + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + *msg_ptr = type; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes host order length field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode length into + * @param ofs points to the offset within the pbuf chain + * @param length is the host order length to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + if (length < 0x80) + { + *msg_ptr = length; + return ERR_OK; + } + else if (length < 0x100) + { + *msg_ptr = 0x81; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *msg_ptr = length; + return ERR_OK; + } + else + { + u8_t i; + + /* length >= 0x100 && length <= 0xFFFF */ + *msg_ptr = 0x82; + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *msg_ptr = length; + } + else + { + /* most significant length octet */ + *msg_ptr = length >> 8; + } + } + return ERR_OK; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) + * @param value is the host order u32_t value to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_u32t_cnt() + */ +err_t +snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, u32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + if (octets_needed == 5) + { + /* not enough bits in 'value' add leading 0x00 */ + octets_needed--; + *msg_ptr = 0x00; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = value >> (octets_needed << 3); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes s32_t integer into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) + * @param value is the host order s32_t value to be encoded + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_s32t_cnt() + */ +err_t +snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, s32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = value >> (octets_needed << 3); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes object identifier into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode oid into + * @param ofs points to the offset within the pbuf chain + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + if (ident_len > 1) + { + if ((ident[0] == 1) && (ident[1] == 3)) + { + /* compressed (most common) prefix .iso.org */ + *msg_ptr = 0x2b; + } + else + { + /* calculate prefix */ + *msg_ptr = (ident[0] * 40) + ident[1]; + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + ident_len -= 2; + ident += 2; + } + else + { +/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ + /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ + return ERR_ARG; + } + while (ident_len > 0) + { + s32_t sub_id; + u8_t shift, tail; + + ident_len--; + sub_id = *ident; + tail = 0; + shift = 28; + while(shift > 0) + { + u8_t code; + + code = sub_id >> shift; + if ((code != 0) || (tail != 0)) + { + tail = 1; + *msg_ptr = code | 0x80; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + shift -= 7; + } + *msg_ptr = (u8_t)sub_id & 0x7F; + if (ident_len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* proceed to next sub-identifier */ + ident++; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode raw data into + * @param ofs points to the offset within the pbuf chain + * @param raw_len raw data length + * @param raw points raw data + * @return ERR_OK if successfull, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u8_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = p->payload; + msg_ptr += ofs - base; + + while (raw_len > 1) + { + /* copy raw_len - 1 octets */ + raw_len--; + *msg_ptr = *raw; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (raw_len > 0) + { + /* copy last or single octet */ + *msg_ptr = *raw; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib2.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib2.c new file mode 100644 index 0000000..bc5830d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib2.c @@ -0,0 +1,4128 @@ +/** + * @file + * Management Information Base II (RFC1213) objects and functions. + * + * @note the object identifiers for this MIB-2 and private MIB tree + * must be kept in sorted ascending order. This to ensure correct getnext operation. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" +#include "lwip/netif.h" +#include "lwip/ip.h" +#include "lwip/ip_frag.h" +#include "lwip/tcp.h" +#include "lwip/udp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_structs.h" +#include "netif/etharp.h" + +/** + * IANA assigned enterprise ID for lwIP is 26381 + * @see http://www.iana.org/assignments/enterprise-numbers + * + * @note this enterprise ID is assigned to the lwIP project, + * all object identifiers living under this ID are assigned + * by the lwIP maintainers (contact Christiaan Simons)! + * @note don't change this define, use snmp_set_sysobjid() + * + * If you need to create your own private MIB you'll need + * to apply for your own enterprise ID with IANA: + * http://www.iana.org/numbers.html + */ +#define SNMP_ENTERPRISE_ID 26381 +#define SNMP_SYSOBJID_LEN 7 +#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID} + +#ifndef SNMP_SYSSERVICES +#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) +#endif + +#ifndef SNMP_GET_SYSUPTIME +#define SNMP_GET_SYSUPTIME(sysuptime) +#endif + +static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void system_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t system_set_test(struct obj_def *od, u16_t len, void *value); +static void system_set_value(struct obj_def *od, u16_t len, void *value); +static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void interfaces_get_value(struct obj_def *od, u16_t len, void *value); +static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ifentry_get_value(struct obj_def *od, u16_t len, void *value); +#if !SNMP_SAFE_REQUESTS +static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value); +static void ifentry_set_value (struct obj_def *od, u16_t len, void *value); +#endif /* SNMP_SAFE_REQUESTS */ +static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void atentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value); +static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value); +static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void icmp_get_value(struct obj_def *od, u16_t len, void *value); +#if LWIP_TCP +static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcp_get_value(struct obj_def *od, u16_t len, void *value); +#ifdef THIS_SEEMS_UNUSED +static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value); +#endif +#endif +static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udp_get_value(struct obj_def *od, u16_t len, void *value); +static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udpentry_get_value(struct obj_def *od, u16_t len, void *value); +static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void snmp_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value); +static void snmp_set_value(struct obj_def *od, u16_t len, void *value); + + +/* snmp .1.3.6.1.2.1.11 */ +const mib_scalar_node snmp_scalar = { + &snmp_get_object_def, + &snmp_get_value, + &snmp_set_test, + &snmp_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t snmp_ids[28] = { + 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30 +}; +struct mib_node* const snmp_nodes[28] = { + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar, + (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar +}; +const struct mib_array_node snmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 28, + snmp_ids, + snmp_nodes +}; + +/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ +/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ +/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ + +/* udp .1.3.6.1.2.1.7 */ +/** index root node for udpTable */ +struct mib_list_rootnode udp_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t udpentry_ids[2] = { 1, 2 }; +struct mib_node* const udpentry_nodes[2] = { + (struct mib_node* const)&udp_root, (struct mib_node* const)&udp_root, +}; +const struct mib_array_node udpentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + udpentry_ids, + udpentry_nodes +}; + +s32_t udptable_id = 1; +struct mib_node* udptable_node = (struct mib_node* const)&udpentry; +struct mib_ram_array_node udptable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &udptable_id, + &udptable_node +}; + +const mib_scalar_node udp_scalar = { + &udp_get_object_def, + &udp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const udp_nodes[5] = { + (struct mib_node* const)&udp_scalar, (struct mib_node* const)&udp_scalar, + (struct mib_node* const)&udp_scalar, (struct mib_node* const)&udp_scalar, + (struct mib_node* const)&udptable +}; +const struct mib_array_node udp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + udp_ids, + udp_nodes +}; + +/* tcp .1.3.6.1.2.1.6 */ +#if LWIP_TCP +/* only if the TCP protocol is available may implement this group */ +/** index root node for tcpConnTable */ +struct mib_list_rootnode tcpconntree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const tcpconnentry_nodes[5] = { + (struct mib_node* const)&tcpconntree_root, (struct mib_node* const)&tcpconntree_root, + (struct mib_node* const)&tcpconntree_root, (struct mib_node* const)&tcpconntree_root, + (struct mib_node* const)&tcpconntree_root +}; +const struct mib_array_node tcpconnentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + tcpconnentry_ids, + tcpconnentry_nodes +}; + +s32_t tcpconntable_id = 1; +struct mib_node* tcpconntable_node = (struct mib_node* const)&tcpconnentry; +struct mib_ram_array_node tcpconntable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, +/** @todo update maxlength when inserting / deleting from table + 0 when table is empty, 1 when more than one entry */ + 0, + &tcpconntable_id, + &tcpconntable_node +}; + +const mib_scalar_node tcp_scalar = { + &tcp_get_object_def, + &tcp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +struct mib_node* const tcp_nodes[15] = { + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcpconntable, (struct mib_node* const)&tcp_scalar, + (struct mib_node* const)&tcp_scalar +}; +const struct mib_array_node tcp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 15, + tcp_ids, + tcp_nodes +}; +#endif + +/* icmp .1.3.6.1.2.1.5 */ +const mib_scalar_node icmp_scalar = { + &icmp_get_object_def, + &icmp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; +struct mib_node* const icmp_nodes[26] = { + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar, + (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar +}; +const struct mib_array_node icmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 26, + icmp_ids, + icmp_nodes +}; + +/** index root node for ipNetToMediaTable */ +struct mib_list_rootnode ipntomtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 }; +struct mib_node* const ipntomentry_nodes[4] = { + (struct mib_node* const)&ipntomtree_root, (struct mib_node* const)&ipntomtree_root, + (struct mib_node* const)&ipntomtree_root, (struct mib_node* const)&ipntomtree_root +}; +const struct mib_array_node ipntomentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 4, + ipntomentry_ids, + ipntomentry_nodes +}; + +s32_t ipntomtable_id = 1; +struct mib_node* ipntomtable_node = (struct mib_node* const)&ipntomentry; +struct mib_ram_array_node ipntomtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipntomtable_id, + &ipntomtable_node +}; + +/** index root node for ipRouteTable */ +struct mib_list_rootnode iprtetree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; +struct mib_node* const iprteentry_nodes[13] = { + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root, + (struct mib_node* const)&iprtetree_root +}; +const struct mib_array_node iprteentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 13, + iprteentry_ids, + iprteentry_nodes +}; + +s32_t iprtetable_id = 1; +struct mib_node* iprtetable_node = (struct mib_node* const)&iprteentry; +struct mib_ram_array_node iprtetable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iprtetable_id, + &iprtetable_node +}; + +/** index root node for ipAddrTable */ +struct mib_list_rootnode ipaddrtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const ipaddrentry_nodes[5] = { + (struct mib_node* const)&ipaddrtree_root, + (struct mib_node* const)&ipaddrtree_root, + (struct mib_node* const)&ipaddrtree_root, + (struct mib_node* const)&ipaddrtree_root, + (struct mib_node* const)&ipaddrtree_root +}; +const struct mib_array_node ipaddrentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + ipaddrentry_ids, + ipaddrentry_nodes +}; + +s32_t ipaddrtable_id = 1; +struct mib_node* ipaddrtable_node = (struct mib_node* const)&ipaddrentry; +struct mib_ram_array_node ipaddrtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipaddrtable_id, + &ipaddrtable_node +}; + +/* ip .1.3.6.1.2.1.4 */ +const mib_scalar_node ip_scalar = { + &ip_get_object_def, + &ip_get_value, + &ip_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; +struct mib_node* const ip_nodes[23] = { + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar, + (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ipaddrtable, + (struct mib_node* const)&iprtetable, (struct mib_node* const)&ipntomtable, + (struct mib_node* const)&ip_scalar +}; +const struct mib_array_node mib2_ip = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 23, + ip_ids, + ip_nodes +}; + +/** index root node for atTable */ +struct mib_list_rootnode arptree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t atentry_ids[3] = { 1, 2, 3 }; +struct mib_node* const atentry_nodes[3] = { + (struct mib_node* const)&arptree_root, + (struct mib_node* const)&arptree_root, + (struct mib_node* const)&arptree_root +}; +const struct mib_array_node atentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 3, + atentry_ids, + atentry_nodes +}; + +const s32_t attable_id = 1; +struct mib_node* const attable_node = (struct mib_node* const)&atentry; +const struct mib_array_node attable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + &attable_id, + &attable_node +}; + +/* at .1.3.6.1.2.1.3 */ +s32_t at_id = 1; +struct mib_node* mib2_at_node = (struct mib_node* const)&attable; +struct mib_ram_array_node at = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &at_id, + &mib2_at_node +}; + +/** index root node for ifTable */ +struct mib_list_rootnode iflist_root = { + &ifentry_get_object_def, + &ifentry_get_value, +#if SNMP_SAFE_REQUESTS + &noleafs_set_test, + &noleafs_set_value, +#else /* SNMP_SAFE_REQUESTS */ + &ifentry_set_test, + &ifentry_set_value, +#endif /* SNMP_SAFE_REQUESTS */ + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; +struct mib_node* const ifentry_nodes[22] = { + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root, + (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root +}; +const struct mib_array_node ifentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 22, + ifentry_ids, + ifentry_nodes +}; + +s32_t iftable_id = 1; +struct mib_node* iftable_node = (struct mib_node* const)&ifentry; +struct mib_ram_array_node iftable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iftable_id, + &iftable_node +}; + +/* interfaces .1.3.6.1.2.1.2 */ +const mib_scalar_node interfaces_scalar = { + &interfaces_get_object_def, + &interfaces_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t interfaces_ids[2] = { 1, 2 }; +struct mib_node* const interfaces_nodes[2] = { + (struct mib_node* const)&interfaces_scalar, (struct mib_node* const)&iftable +}; +const struct mib_array_node interfaces = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + interfaces_ids, + interfaces_nodes +}; + + +/* 0 1 2 3 4 5 6 */ +/* system .1.3.6.1.2.1.1 */ +const mib_scalar_node sys_tem_scalar = { + &system_get_object_def, + &system_get_value, + &system_set_test, + &system_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 }; +struct mib_node* const sys_tem_nodes[7] = { + (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar, + (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar, + (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar, + (struct mib_node* const)&sys_tem_scalar +}; +/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */ +const struct mib_array_node sys_tem = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 7, + sys_tem_ids, + sys_tem_nodes +}; + +/* mib-2 .1.3.6.1.2.1 */ +#if LWIP_TCP +#define MIB2_GROUPS 8 +#else +#define MIB2_GROUPS 7 +#endif +const s32_t mib2_ids[MIB2_GROUPS] = +{ + 1, + 2, + 3, + 4, + 5, +#if LWIP_TCP + 6, +#endif + 7, + 11 +}; +struct mib_node* const mib2_nodes[MIB2_GROUPS] = { + (struct mib_node* const)&sys_tem, + (struct mib_node* const)&interfaces, + (struct mib_node* const)&at, + (struct mib_node* const)&mib2_ip, + (struct mib_node* const)&icmp, +#if LWIP_TCP + (struct mib_node* const)&tcp, +#endif + (struct mib_node* const)&udp, + (struct mib_node* const)&snmp +}; + +const struct mib_array_node mib2 = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + MIB2_GROUPS, + mib2_ids, + mib2_nodes +}; + +/* mgmt .1.3.6.1.2 */ +const s32_t mgmt_ids[1] = { 1 }; +struct mib_node* const mgmt_nodes[1] = { (struct mib_node* const)&mib2 }; +const struct mib_array_node mgmt = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + mgmt_ids, + mgmt_nodes +}; + +/* internet .1.3.6.1 */ +#if SNMP_PRIVATE_MIB +s32_t internet_ids[2] = { 2, 4 }; +struct mib_node* const internet_nodes[2] = { (struct mib_node* const)&mgmt, (struct mib_node* const)&private }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + internet_ids, + internet_nodes +}; +#else +const s32_t internet_ids[1] = { 2 }; +struct mib_node* const internet_nodes[1] = { (struct mib_node* const)&mgmt }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + internet_ids, + internet_nodes +}; +#endif + +/** mib-2.system.sysObjectID */ +static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID}; +/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */ +static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}}; +/** mib-2.system.sysServices */ +static const s32_t sysservices = SNMP_SYSSERVICES; + +/** mib-2.system.sysDescr */ +static const u8_t sysdescr_len_default = 4; +static const u8_t sysdescr_default[] = "lwIP"; +static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default; +static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0]; +/** mib-2.system.sysContact */ +static const u8_t syscontact_len_default = 0; +static const u8_t syscontact_default[] = ""; +static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default; +static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0]; +/** mib-2.system.sysName */ +static const u8_t sysname_len_default = 8; +static const u8_t sysname_default[] = "FQDN-unk"; +static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default; +static u8_t* sysname_ptr = (u8_t*)&sysname_default[0]; +/** mib-2.system.sysLocation */ +static const u8_t syslocation_len_default = 0; +static const u8_t syslocation_default[] = ""; +static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default; +static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0]; +/** mib-2.snmp.snmpEnableAuthenTraps */ +static const u8_t snmpenableauthentraps_default = 2; /* disabled */ +static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; + +/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */ +static const struct snmp_obj_id ifspecific = {2, {0, 0}}; +/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ +static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; + + + +/* mib-2.system counter(s) */ +static u32_t sysuptime = 0; + +/* mib-2.ip counter(s) */ +static u32_t ipinreceives = 0, + ipinhdrerrors = 0, + ipinaddrerrors = 0, + ipforwdatagrams = 0, + ipinunknownprotos = 0, + ipindiscards = 0, + ipindelivers = 0, + ipoutrequests = 0, + ipoutdiscards = 0, + ipoutnoroutes = 0, + ipreasmreqds = 0, + ipreasmoks = 0, + ipreasmfails = 0, + ipfragoks = 0, + ipfragfails = 0, + ipfragcreates = 0, + iproutingdiscards = 0; +/* mib-2.icmp counter(s) */ +static u32_t icmpinmsgs = 0, + icmpinerrors = 0, + icmpindestunreachs = 0, + icmpintimeexcds = 0, + icmpinparmprobs = 0, + icmpinsrcquenchs = 0, + icmpinredirects = 0, + icmpinechos = 0, + icmpinechoreps = 0, + icmpintimestamps = 0, + icmpintimestampreps = 0, + icmpinaddrmasks = 0, + icmpinaddrmaskreps = 0, + icmpoutmsgs = 0, + icmpouterrors = 0, + icmpoutdestunreachs = 0, + icmpouttimeexcds = 0, + icmpoutparmprobs = 0, + icmpoutsrcquenchs = 0, + icmpoutredirects = 0, + icmpoutechos = 0, + icmpoutechoreps = 0, + icmpouttimestamps = 0, + icmpouttimestampreps = 0, + icmpoutaddrmasks = 0, + icmpoutaddrmaskreps = 0; +/* mib-2.tcp counter(s) */ +static u32_t tcpactiveopens = 0, + tcppassiveopens = 0, + tcpattemptfails = 0, + tcpestabresets = 0, + tcpinsegs = 0, + tcpoutsegs = 0, + tcpretranssegs = 0, + tcpinerrs = 0, + tcpoutrsts = 0; +/* mib-2.udp counter(s) */ +static u32_t udpindatagrams = 0, + udpnoports = 0, + udpinerrors = 0, + udpoutdatagrams = 0; +/* mib-2.snmp counter(s) */ +static u32_t snmpinpkts = 0, + snmpoutpkts = 0, + snmpinbadversions = 0, + snmpinbadcommunitynames = 0, + snmpinbadcommunityuses = 0, + snmpinasnparseerrs = 0, + snmpintoobigs = 0, + snmpinnosuchnames = 0, + snmpinbadvalues = 0, + snmpinreadonlys = 0, + snmpingenerrs = 0, + snmpintotalreqvars = 0, + snmpintotalsetvars = 0, + snmpingetrequests = 0, + snmpingetnexts = 0, + snmpinsetrequests = 0, + snmpingetresponses = 0, + snmpintraps = 0, + snmpouttoobigs = 0, + snmpoutnosuchnames = 0, + snmpoutbadvalues = 0, + snmpoutgenerrs = 0, + snmpoutgetrequests = 0, + snmpoutgetnexts = 0, + snmpoutsetrequests = 0, + snmpoutgetresponses = 0, + snmpouttraps = 0; + + + +/* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */ +/** + * Copy octet string. + * + * @param dst points to destination + * @param src points to source + * @param n number of octets to copy. + */ +void ocstrncpy(u8_t *dst, u8_t *src, u8_t n) +{ + while (n > 0) + { + n--; + *dst++ = *src++; + } +} + +/** + * Copy object identifier (s32_t) array. + * + * @param dst points to destination + * @param src points to source + * @param n number of sub identifiers to copy. + */ +void objectidncpy(s32_t *dst, s32_t *src, u8_t n) +{ + while(n > 0) + { + n--; + *dst++ = *src++; + } +} + +/** + * Initializes sysDescr pointers. + * + * @param str if non-NULL then copy str pointer + * @param len points to string length, excluding zero terminator + */ +void snmp_set_sysdesr(u8_t *str, u8_t *len) +{ + if (str != NULL) + { + sysdescr_ptr = str; + sysdescr_len_ptr = len; + } +} + +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid) +{ + *oid = &sysobjid; +} + +/** + * Initializes sysObjectID value. + * + * @param oid points to stuct snmp_obj_id to copy + */ +void snmp_set_sysobjid(struct snmp_obj_id *oid) +{ + sysobjid = *oid; +} + +/** + * Must be called at regular 10 msec interval from a timer interrupt + * or signal handler depending on your runtime environment. + */ +void snmp_inc_sysuptime(void) +{ + sysuptime++; +} + +void snmp_add_sysuptime(u32_t value) +{ + sysuptime+=value; +} + +void snmp_get_sysuptime(u32_t *value) +{ + SNMP_GET_SYSUPTIME(sysuptime); + *value = sysuptime; +} + +/** + * Initializes sysContact pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syscontact_ptr = ocstr; + syscontact_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysName pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + sysname_ptr = ocstr; + sysname_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysLocation pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syslocation_ptr = ocstr; + syslocation_len_ptr = ocstrlen; + } +} + + +void snmp_add_ifinoctets(struct netif *ni, u32_t value) +{ + ni->ifinoctets += value; +} + +void snmp_inc_ifinucastpkts(struct netif *ni) +{ + (ni->ifinucastpkts)++; +} + +void snmp_inc_ifinnucastpkts(struct netif *ni) +{ + (ni->ifinnucastpkts)++; +} + +void snmp_inc_ifindiscards(struct netif *ni) +{ + (ni->ifindiscards)++; +} + +void snmp_add_ifoutoctets(struct netif *ni, u32_t value) +{ + ni->ifoutoctets += value; +} + +void snmp_inc_ifoutucastpkts(struct netif *ni) +{ + (ni->ifoutucastpkts)++; +} + +void snmp_inc_ifoutnucastpkts(struct netif *ni) +{ + (ni->ifoutnucastpkts)++; +} + +void snmp_inc_ifoutdiscards(struct netif *ni) +{ + (ni->ifoutdiscards)++; +} + +void snmp_inc_iflist(void) +{ + struct mib_list_node *if_node = NULL; + + snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node); + /* enable getnext traversal on filled table */ + iftable.maxlength = 1; +} + +void snmp_dec_iflist(void) +{ + snmp_mib_node_delete(&iflist_root, iflist_root.tail); + /* disable getnext traversal on empty table */ + if(iflist_root.count == 0) iftable.maxlength = 0; +} + +/** + * Inserts ARP table indexes (.xIfIndex.xNetAddress) + * into arp table index trees (both atTable and ipNetToMediaTable). + */ +void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip) +{ + struct mib_list_rootnode *at_rn; + struct mib_list_node *at_node; + struct ip_addr hip; + s32_t arpidx[5]; + u8_t level, tree; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_netiftoifindex(ni, &arpidx[0]); + hip.addr = ntohl(ip->addr); + snmp_iptooid(&hip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + for (level = 0; level < 5; level++) + { + at_node = NULL; + snmp_mib_node_insert(at_rn, arpidx[level], &at_node); + if ((level != 4) && (at_node != NULL)) + { + if (at_node->nptr == NULL) + { + at_rn = snmp_mib_lrn_alloc(); + at_node->nptr = (struct mib_node*)at_rn; + if (at_rn != NULL) + { + if (level == 3) + { + if (tree == 0) + { + at_rn->get_object_def = atentry_get_object_def; + at_rn->get_value = atentry_get_value; + } + else + { + at_rn->get_object_def = ip_ntomentry_get_object_def; + at_rn->get_value = ip_ntomentry_get_value; + } + at_rn->set_test = noleafs_set_test; + at_rn->set_value = noleafs_set_value; + } + } + else + { + /* at_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full")); + break; + } + } + else + { + at_rn = (struct mib_list_rootnode*)at_node->nptr; + } + } + } + } + /* enable getnext traversal on filled tables */ + at.maxlength = 1; + ipntomtable.maxlength = 1; +} + +/** + * Removes ARP table indexes (.xIfIndex.xNetAddress) + * from arp table index trees. + */ +void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip) +{ + struct mib_list_rootnode *at_rn, *next, *del_rn[5]; + struct mib_list_node *at_n, *del_n[5]; + struct ip_addr hip; + s32_t arpidx[5]; + u8_t fc, tree, level, del_cnt; + + snmp_netiftoifindex(ni, &arpidx[0]); + hip.addr = ntohl(ip->addr); + snmp_iptooid(&hip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + /* mark nodes for deletion */ + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + level = 0; + del_cnt = 0; + while ((level < 5) && (at_rn != NULL)) + { + fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n); + if (fc == 0) + { + /* arpidx[level] does not exist */ + del_cnt = 0; + at_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = at_rn; + del_n[del_cnt] = at_n; + del_cnt++; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + at_rn = del_rn[del_cnt]; + at_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(at_rn, at_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty tables */ + if(arptree_root.count == 0) at.maxlength = 0; + if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0; +} + +void snmp_inc_ipinreceives(void) +{ + ipinreceives++; +} + +void snmp_inc_ipinhdrerrors(void) +{ + ipinhdrerrors++; +} + +void snmp_inc_ipinaddrerrors(void) +{ + ipinaddrerrors++; +} + +void snmp_inc_ipforwdatagrams(void) +{ + ipforwdatagrams++; +} + +void snmp_inc_ipinunknownprotos(void) +{ + ipinunknownprotos++; +} + +void snmp_inc_ipindiscards(void) +{ + ipindiscards++; +} + +void snmp_inc_ipindelivers(void) +{ + ipindelivers++; +} + +void snmp_inc_ipoutrequests(void) +{ + ipoutrequests++; +} + +void snmp_inc_ipoutdiscards(void) +{ + ipoutdiscards++; +} + +void snmp_inc_ipoutnoroutes(void) +{ + ipoutnoroutes++; +} + +void snmp_inc_ipreasmreqds(void) +{ + ipreasmreqds++; +} + +void snmp_inc_ipreasmoks(void) +{ + ipreasmoks++; +} + +void snmp_inc_ipreasmfails(void) +{ + ipreasmfails++; +} + +void snmp_inc_ipfragoks(void) +{ + ipfragoks++; +} + +void snmp_inc_ipfragfails(void) +{ + ipfragfails++; +} + +void snmp_inc_ipfragcreates(void) +{ + ipfragcreates++; +} + +void snmp_inc_iproutingdiscards(void) +{ + iproutingdiscards++; +} + +/** + * Inserts ipAddrTable indexes (.ipAdEntAddr) + * into index tree. + */ +void snmp_insert_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn; + struct mib_list_node *ipa_node; + struct ip_addr ip; + s32_t ipaddridx[4]; + u8_t level; + + LWIP_ASSERT("ni != NULL", ni != NULL); + ip.addr = ntohl(ni->ip_addr.addr); + snmp_iptooid(&ip, &ipaddridx[0]); + + level = 0; + ipa_rn = &ipaddrtree_root; + while (level < 4) + { + ipa_node = NULL; + snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node); + if ((level != 3) && (ipa_node != NULL)) + { + if (ipa_node->nptr == NULL) + { + ipa_rn = snmp_mib_lrn_alloc(); + ipa_node->nptr = (struct mib_node*)ipa_rn; + if (ipa_rn != NULL) + { + if (level == 2) + { + ipa_rn->get_object_def = ip_addrentry_get_object_def; + ipa_rn->get_value = ip_addrentry_get_value; + ipa_rn->set_test = noleafs_set_test; + ipa_rn->set_value = noleafs_set_value; + } + } + else + { + /* ipa_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full")); + break; + } + } + else + { + ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr; + } + } + level++; + } + /* enable getnext traversal on filled table */ + ipaddrtable.maxlength = 1; +} + +/** + * Removes ipAddrTable indexes (.ipAdEntAddr) + * from index tree. + */ +void snmp_delete_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn, *next, *del_rn[4]; + struct mib_list_node *ipa_n, *del_n[4]; + struct ip_addr ip; + s32_t ipaddridx[4]; + u8_t fc, level, del_cnt; + + LWIP_ASSERT("ni != NULL", ni != NULL); + ip.addr = ntohl(ni->ip_addr.addr); + snmp_iptooid(&ip, &ipaddridx[0]); + + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + ipa_rn = &ipaddrtree_root; + while ((level < 4) && (ipa_rn != NULL)) + { + fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n); + if (fc == 0) + { + /* ipaddridx[level] does not exist */ + del_cnt = 0; + ipa_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = ipa_rn; + del_n[del_cnt] = ipa_n; + del_cnt++; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + ipa_rn = del_rn[del_cnt]; + ipa_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(ipa_rn, ipa_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + /* disable getnext traversal on empty table */ + if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0; +} + +/** + * Inserts ipRouteTable indexes (.ipRouteDest) + * into index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte + * + * @todo record sysuptime for _this_ route when it is installed + * (needed for ipRouteAge) in the netif. + */ +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t insert = 0; + struct ip_addr dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + dst.addr = 0; + insert = 1; + } + else + { + /* route to the network address */ + dst.addr = ntohl(ni->ip_addr.addr & ni->netmask.addr); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (dst.addr != 0) insert = 1; + } + if (insert) + { + struct mib_list_rootnode *iprte_rn; + struct mib_list_node *iprte_node; + s32_t iprteidx[4]; + u8_t level; + + snmp_iptooid(&dst, &iprteidx[0]); + level = 0; + iprte_rn = &iprtetree_root; + while (level < 4) + { + iprte_node = NULL; + snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node); + if ((level != 3) && (iprte_node != NULL)) + { + if (iprte_node->nptr == NULL) + { + iprte_rn = snmp_mib_lrn_alloc(); + iprte_node->nptr = (struct mib_node*)iprte_rn; + if (iprte_rn != NULL) + { + if (level == 2) + { + iprte_rn->get_object_def = ip_rteentry_get_object_def; + iprte_rn->get_value = ip_rteentry_get_value; + iprte_rn->set_test = noleafs_set_test; + iprte_rn->set_value = noleafs_set_value; + } + } + else + { + /* iprte_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full")); + break; + } + } + else + { + iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr; + } + } + level++; + } + } + /* enable getnext traversal on filled table */ + iprtetable.maxlength = 1; +} + +/** + * Removes ipRouteTable indexes (.ipRouteDest) + * from index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte or NULL + * for default route to be removed. + */ +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t delete = 0; + struct ip_addr dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + dst.addr = 0; + delete = 1; + } + else + { + /* route to the network address */ + dst.addr = ntohl(ni->ip_addr.addr & ni->netmask.addr); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (dst.addr != 0) delete = 1; + } + if (delete) + { + struct mib_list_rootnode *iprte_rn, *next, *del_rn[4]; + struct mib_list_node *iprte_n, *del_n[4]; + s32_t iprteidx[4]; + u8_t fc, level, del_cnt; + + snmp_iptooid(&dst, &iprteidx[0]); + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + iprte_rn = &iprtetree_root; + while ((level < 4) && (iprte_rn != NULL)) + { + fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n); + if (fc == 0) + { + /* iprteidx[level] does not exist */ + del_cnt = 0; + iprte_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = iprte_rn; + del_n[del_cnt] = iprte_n; + del_cnt++; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + iprte_rn = del_rn[del_cnt]; + iprte_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(iprte_rn, iprte_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (iprtetree_root.count == 0) iprtetable.maxlength = 0; +} + + +void snmp_inc_icmpinmsgs(void) +{ + icmpinmsgs++; +} + +void snmp_inc_icmpinerrors(void) +{ + icmpinerrors++; +} + +void snmp_inc_icmpindestunreachs(void) +{ + icmpindestunreachs++; +} + +void snmp_inc_icmpintimeexcds(void) +{ + icmpintimeexcds++; +} + +void snmp_inc_icmpinparmprobs(void) +{ + icmpinparmprobs++; +} + +void snmp_inc_icmpinsrcquenchs(void) +{ + icmpinsrcquenchs++; +} + +void snmp_inc_icmpinredirects(void) +{ + icmpinredirects++; +} + +void snmp_inc_icmpinechos(void) +{ + icmpinechos++; +} + +void snmp_inc_icmpinechoreps(void) +{ + icmpinechoreps++; +} + +void snmp_inc_icmpintimestamps(void) +{ + icmpintimestamps++; +} + +void snmp_inc_icmpintimestampreps(void) +{ + icmpintimestampreps++; +} + +void snmp_inc_icmpinaddrmasks(void) +{ + icmpinaddrmasks++; +} + +void snmp_inc_icmpinaddrmaskreps(void) +{ + icmpinaddrmaskreps++; +} + +void snmp_inc_icmpoutmsgs(void) +{ + icmpoutmsgs++; +} + +void snmp_inc_icmpouterrors(void) +{ + icmpouterrors++; +} + +void snmp_inc_icmpoutdestunreachs(void) +{ + icmpoutdestunreachs++; +} + +void snmp_inc_icmpouttimeexcds(void) +{ + icmpouttimeexcds++; +} + +void snmp_inc_icmpoutparmprobs(void) +{ + icmpoutparmprobs++; +} + +void snmp_inc_icmpoutsrcquenchs(void) +{ + icmpoutsrcquenchs++; +} + +void snmp_inc_icmpoutredirects(void) +{ + icmpoutredirects++; +} + +void snmp_inc_icmpoutechos(void) +{ + icmpoutechos++; +} + +void snmp_inc_icmpoutechoreps(void) +{ + icmpoutechoreps++; +} + +void snmp_inc_icmpouttimestamps(void) +{ + icmpouttimestamps++; +} + +void snmp_inc_icmpouttimestampreps(void) +{ + icmpouttimestampreps++; +} + +void snmp_inc_icmpoutaddrmasks(void) +{ + icmpoutaddrmasks++; +} + +void snmp_inc_icmpoutaddrmaskreps(void) +{ + icmpoutaddrmaskreps++; +} + +void snmp_inc_tcpactiveopens(void) +{ + tcpactiveopens++; +} + +void snmp_inc_tcppassiveopens(void) +{ + tcppassiveopens++; +} + +void snmp_inc_tcpattemptfails(void) +{ + tcpattemptfails++; +} + +void snmp_inc_tcpestabresets(void) +{ + tcpestabresets++; +} + +void snmp_inc_tcpinsegs(void) +{ + tcpinsegs++; +} + +void snmp_inc_tcpoutsegs(void) +{ + tcpoutsegs++; +} + +void snmp_inc_tcpretranssegs(void) +{ + tcpretranssegs++; +} + +void snmp_inc_tcpinerrs(void) +{ + tcpinerrs++; +} + +void snmp_inc_tcpoutrsts(void) +{ + tcpoutrsts++; +} + +void snmp_inc_udpindatagrams(void) +{ + udpindatagrams++; +} + +void snmp_inc_udpnoports(void) +{ + udpnoports++; +} + +void snmp_inc_udpinerrors(void) +{ + udpinerrors++; +} + +void snmp_inc_udpoutdatagrams(void) +{ + udpoutdatagrams++; +} + +/** + * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort) + * into index tree. + */ +void snmp_insert_udpidx_tree(struct udp_pcb *pcb) +{ + struct mib_list_rootnode *udp_rn; + struct mib_list_node *udp_node; + struct ip_addr ip; + s32_t udpidx[5]; + u8_t level; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + ip.addr = ntohl(pcb->local_ip.addr); + snmp_iptooid(&ip, &udpidx[0]); + udpidx[4] = pcb->local_port; + + udp_rn = &udp_root; + for (level = 0; level < 5; level++) + { + udp_node = NULL; + snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node); + if ((level != 4) && (udp_node != NULL)) + { + if (udp_node->nptr == NULL) + { + udp_rn = snmp_mib_lrn_alloc(); + udp_node->nptr = (struct mib_node*)udp_rn; + if (udp_rn != NULL) + { + if (level == 3) + { + udp_rn->get_object_def = udpentry_get_object_def; + udp_rn->get_value = udpentry_get_value; + udp_rn->set_test = noleafs_set_test; + udp_rn->set_value = noleafs_set_value; + } + } + else + { + /* udp_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full")); + break; + } + } + else + { + udp_rn = (struct mib_list_rootnode*)udp_node->nptr; + } + } + } + udptable.maxlength = 1; +} + +/** + * Removes udpTable indexes (.udpLocalAddress.udpLocalPort) + * from index tree. + */ +void snmp_delete_udpidx_tree(struct udp_pcb *pcb) +{ + struct mib_list_rootnode *udp_rn, *next, *del_rn[5]; + struct mib_list_node *udp_n, *del_n[5]; + struct ip_addr ip; + s32_t udpidx[5]; + u8_t bindings, fc, level, del_cnt; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + ip.addr = ntohl(pcb->local_ip.addr); + snmp_iptooid(&ip, &udpidx[0]); + udpidx[4] = pcb->local_port; + + /* count PCBs for a given binding + (e.g. when reusing ports or for temp output PCBs) */ + bindings = 0; + pcb = udp_pcbs; + while ((pcb != NULL)) + { + if ((pcb->local_ip.addr == ip.addr) && + (pcb->local_port == udpidx[4])) + { + bindings++; + } + pcb = pcb->next; + } + if (bindings == 1) + { + /* selectively remove */ + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + udp_rn = &udp_root; + while ((level < 5) && (udp_rn != NULL)) + { + fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n); + if (fc == 0) + { + /* udpidx[level] does not exist */ + del_cnt = 0; + udp_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = udp_rn; + del_n[del_cnt] = udp_n; + del_cnt++; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + udp_rn = del_rn[del_cnt]; + udp_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(udp_rn, udp_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (udp_root.count == 0) udptable.maxlength = 0; +} + + +void snmp_inc_snmpinpkts(void) +{ + snmpinpkts++; +} + +void snmp_inc_snmpoutpkts(void) +{ + snmpoutpkts++; +} + +void snmp_inc_snmpinbadversions(void) +{ + snmpinbadversions++; +} + +void snmp_inc_snmpinbadcommunitynames(void) +{ + snmpinbadcommunitynames++; +} + +void snmp_inc_snmpinbadcommunityuses(void) +{ + snmpinbadcommunityuses++; +} + +void snmp_inc_snmpinasnparseerrs(void) +{ + snmpinasnparseerrs++; +} + +void snmp_inc_snmpintoobigs(void) +{ + snmpintoobigs++; +} + +void snmp_inc_snmpinnosuchnames(void) +{ + snmpinnosuchnames++; +} + +void snmp_inc_snmpinbadvalues(void) +{ + snmpinbadvalues++; +} + +void snmp_inc_snmpinreadonlys(void) +{ + snmpinreadonlys++; +} + +void snmp_inc_snmpingenerrs(void) +{ + snmpingenerrs++; +} + +void snmp_add_snmpintotalreqvars(u8_t value) +{ + snmpintotalreqvars += value; +} + +void snmp_add_snmpintotalsetvars(u8_t value) +{ + snmpintotalsetvars += value; +} + +void snmp_inc_snmpingetrequests(void) +{ + snmpingetrequests++; +} + +void snmp_inc_snmpingetnexts(void) +{ + snmpingetnexts++; +} + +void snmp_inc_snmpinsetrequests(void) +{ + snmpinsetrequests++; +} + +void snmp_inc_snmpingetresponses(void) +{ + snmpingetresponses++; +} + +void snmp_inc_snmpintraps(void) +{ + snmpintraps++; +} + +void snmp_inc_snmpouttoobigs(void) +{ + snmpouttoobigs++; +} + +void snmp_inc_snmpoutnosuchnames(void) +{ + snmpoutnosuchnames++; +} + +void snmp_inc_snmpoutbadvalues(void) +{ + snmpoutbadvalues++; +} + +void snmp_inc_snmpoutgenerrs(void) +{ + snmpoutgenerrs++; +} + +void snmp_inc_snmpoutgetrequests(void) +{ + snmpoutgetrequests++; +} + +void snmp_inc_snmpoutgetnexts(void) +{ + snmpoutgetnexts++; +} + +void snmp_inc_snmpoutsetrequests(void) +{ + snmpoutsetrequests++; +} + +void snmp_inc_snmpoutgetresponses(void) +{ + snmpoutgetresponses++; +} + +void snmp_inc_snmpouttraps(void) +{ + snmpouttraps++; +} + +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid) +{ + *oid = &snmpgrp_id; +} + +void snmp_set_snmpenableauthentraps(u8_t *value) +{ + if (value != NULL) + { + snmpenableauthentraps_ptr = value; + } +} + +void snmp_get_snmpenableauthentraps(u8_t *value) +{ + *value = *snmpenableauthentraps_ptr; +} + +void +noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + LWIP_UNUSED_ARG(ident_len); + LWIP_UNUSED_ARG(ident); + od->instance = MIB_OBJECT_NONE; +} + +void +noleafs_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + +u8_t +noleafs_set_test(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* can't set */ + return 0; +} + +void +noleafs_set_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + + +/** + * Returns systems object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param od points to object definition. + */ +static void +system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* sysDescr */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysdescr_len_ptr; + break; + case 2: /* sysObjectID */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = sysobjid.len * sizeof(s32_t); + break; + case 3: /* sysUpTime */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 4: /* sysContact */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syscontact_len_ptr; + break; + case 5: /* sysName */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysname_len_ptr; + break; + case 6: /* sysLocation */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syslocation_len_ptr; + break; + case 7: /* sysServices */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns system object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +system_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* sysDescr */ + ocstrncpy(value,sysdescr_ptr, len); + break; + case 2: /* sysObjectID */ + objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t))); + break; + case 3: /* sysUpTime */ + { + snmp_get_sysuptime(value); + } + break; + case 4: /* sysContact */ + ocstrncpy(value,syscontact_ptr,len); + break; + case 5: /* sysName */ + ocstrncpy(value,sysname_ptr,len); + break; + case 6: /* sysLocation */ + ocstrncpy(value,syslocation_ptr,len); + break; + case 7: /* sysServices */ + { + s32_t *sint_ptr = value; + *sint_ptr = sysservices; + } + break; + }; +} + +static u8_t +system_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(value); + set_ok = 0; + id = od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + if ((syscontact_ptr != syscontact_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 5: /* sysName */ + if ((sysname_ptr != sysname_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 6: /* sysLocation */ + if ((syslocation_ptr != syslocation_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + }; + return set_ok; +} + +static void +system_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + id = od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + ocstrncpy(syscontact_ptr,value,len); + *syscontact_len_ptr = len; + break; + case 5: /* sysName */ + ocstrncpy(sysname_ptr,value,len); + *sysname_len_ptr = len; + break; + case 6: /* sysLocation */ + ocstrncpy(syslocation_ptr,value,len); + *syslocation_len_ptr = len; + break; + }; +} + +/** + * Returns interfaces.ifnumber object definition. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns interfaces.ifnumber object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +interfaces_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(len); + if (od->id_inst_ptr[0] == 1) + { + s32_t *sint_ptr = value; + *sint_ptr = iflist_root.count; + } +} + +/** + * Returns ifentry object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id)); + switch (id) + { + case 1: /* ifIndex */ + case 3: /* ifType */ + case 4: /* ifMtu */ + case 8: /* ifOperStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ifDescr */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + /** @todo this should be some sort of sizeof(struct netif.name) */ + od->v_len = 2; + break; + case 5: /* ifSpeed */ + case 21: /* ifOutQLen */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + case 6: /* ifPhysAddress */ + { + struct netif *netif; + + snmp_ifindextonetif(ident[1], &netif); + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = netif->hwaddr_len; + } + break; + case 7: /* ifAdminStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ifLastChange */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 10: /* ifInOctets */ + case 11: /* ifInUcastPkts */ + case 12: /* ifInNUcastPkts */ + case 13: /* ifInDiscarts */ + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + case 16: /* ifOutOctets */ + case 17: /* ifOutUcastPkts */ + case 18: /* ifOutNUcastPkts */ + case 19: /* ifOutDiscarts */ + case 20: /* ifOutErrors */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 22: /* ifSpecific */ + /** @note returning zeroDotZero (0.0) no media specific MIB support */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = ifspecific.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns ifentry object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +ifentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ifIndex */ + { + s32_t *sint_ptr = value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ifDescr */ + ocstrncpy(value,(u8_t*)netif->name,len); + break; + case 3: /* ifType */ + { + s32_t *sint_ptr = value; + *sint_ptr = netif->link_type; + } + break; + case 4: /* ifMtu */ + { + s32_t *sint_ptr = value; + *sint_ptr = netif->mtu; + } + break; + case 5: /* ifSpeed */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->link_speed; + } + break; + case 6: /* ifPhysAddress */ + ocstrncpy(value,netif->hwaddr,len); + break; + case 7: /* ifAdminStatus */ +#if LWIP_NETIF_LINK_CALLBACK + { + s32_t *sint_ptr = value; + if (netif_is_up(netif)) + { + if (netif_is_link_up(netif)) + { + *sint_ptr = 1; /* up */ + } + else + { + *sint_ptr = 7; /* lowerLayerDown */ + } + } + else + { + *sint_ptr = 2; /* down */ + } + } + break; +#endif + case 8: /* ifOperStatus */ + { + s32_t *sint_ptr = value; + if (netif_is_up(netif)) + { + *sint_ptr = 1; + } + else + { + *sint_ptr = 2; + } + } + break; + case 9: /* ifLastChange */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ts; + } + break; + case 10: /* ifInOctets */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifinoctets; + } + break; + case 11: /* ifInUcastPkts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifinucastpkts; + } + break; + case 12: /* ifInNUcastPkts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifinnucastpkts; + } + break; + case 13: /* ifInDiscarts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifindiscards; + } + break; + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + /** @todo add these counters! */ + { + u32_t *uint_ptr = value; + *uint_ptr = 0; + } + break; + case 16: /* ifOutOctets */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifoutoctets; + } + break; + case 17: /* ifOutUcastPkts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifoutucastpkts; + } + break; + case 18: /* ifOutNUcastPkts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifoutnucastpkts; + } + break; + case 19: /* ifOutDiscarts */ + { + u32_t *uint_ptr = value; + *uint_ptr = netif->ifoutdiscards; + } + break; + case 20: /* ifOutErrors */ + /** @todo add this counter! */ + { + u32_t *uint_ptr = value; + *uint_ptr = 0; + } + break; + case 21: /* ifOutQLen */ + /** @todo figure out if this must be 0 (no queue) or 1? */ + { + u32_t *uint_ptr = value; + *uint_ptr = 0; + } + break; + case 22: /* ifSpecific */ + objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t))); + break; + }; +} + +#if !SNMP_SAFE_REQUESTS +static u8_t +ifentry_set_test (struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id, set_ok; + + set_ok = 0; + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = value; + if (*sint_ptr == 1 || *sint_ptr == 2) + set_ok = 1; + } + break; + } + return set_ok; +} + +static void +ifentry_set_value (struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = value; + if (*sint_ptr == 1) + { + netif_set_up(netif); + } + else if (*sint_ptr == 2) + { + netif_set_down(netif); + } + } + break; + } +} +#endif /* SNMP_SAFE_REQUESTS */ + +/** + * Returns atentry object definitions. + * + * @param ident_len the address length (6) + * @param ident points to objectname.atifindex.atnetaddress + * @param od points to object definition. + */ +static void +atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* atIfIndex */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* atPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* atNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +atentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + struct ip_addr* ipaddr_ret; +#endif /* LWIP_ARP */ + struct ip_addr ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + ip.addr = htonl(ip.addr); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* atIfIndex */ + { + s32_t *sint_ptr = value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* atPhysAddress */ + { + struct eth_addr *dst = value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* atNetAddress */ + { + struct ip_addr *dst = value; + + *dst = *ipaddr_ret; + } + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* ipForwarding */ + case 2: /* ipDefaultTTL */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 3: /* ipInReceives */ + case 4: /* ipInHdrErrors */ + case 5: /* ipInAddrErrors */ + case 6: /* ipForwDatagrams */ + case 7: /* ipInUnknownProtos */ + case 8: /* ipInDiscards */ + case 9: /* ipInDelivers */ + case 10: /* ipOutRequests */ + case 11: /* ipOutDiscards */ + case 12: /* ipOutNoRoutes */ + case 14: /* ipReasmReqds */ + case 15: /* ipReasmOKs */ + case 16: /* ipReasmFails */ + case 17: /* ipFragOKs */ + case 18: /* ipFragFails */ + case 19: /* ipFragCreates */ + case 23: /* ipRoutingDiscards */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 13: /* ipReasmTimeout */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ + { + s32_t *sint_ptr = value; +#if IP_FORWARD + /* forwarding */ + *sint_ptr = 1; +#else + /* not-forwarding */ + *sint_ptr = 2; +#endif + } + break; + case 2: /* ipDefaultTTL */ + { + s32_t *sint_ptr = value; + *sint_ptr = IP_DEFAULT_TTL; + } + break; + case 3: /* ipInReceives */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipinreceives; + } + break; + case 4: /* ipInHdrErrors */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipinhdrerrors; + } + break; + case 5: /* ipInAddrErrors */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipinaddrerrors; + } + break; + case 6: /* ipForwDatagrams */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipforwdatagrams; + } + break; + case 7: /* ipInUnknownProtos */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipinunknownprotos; + } + break; + case 8: /* ipInDiscards */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipindiscards; + } + break; + case 9: /* ipInDelivers */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipindelivers; + } + break; + case 10: /* ipOutRequests */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipoutrequests; + } + break; + case 11: /* ipOutDiscards */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipoutdiscards; + } + break; + case 12: /* ipOutNoRoutes */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipoutnoroutes; + } + break; + case 13: /* ipReasmTimeout */ + { + s32_t *sint_ptr = value; +#if IP_REASSEMBLY + *sint_ptr = IP_REASS_MAXAGE; +#else + *sint_ptr = 0; +#endif + } + break; + case 14: /* ipReasmReqds */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipreasmreqds; + } + break; + case 15: /* ipReasmOKs */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipreasmoks; + } + break; + case 16: /* ipReasmFails */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipreasmfails; + } + break; + case 17: /* ipFragOKs */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipfragoks; + } + break; + case 18: /* ipFragFails */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipfragfails; + } + break; + case 19: /* ipFragCreates */ + { + u32_t *uint_ptr = value; + *uint_ptr = ipfragcreates; + } + break; + case 23: /* ipRoutingDiscards */ + /** @todo can lwIP discard routes at all?? hardwire this to 0?? */ + { + u32_t *uint_ptr = value; + *uint_ptr = iproutingdiscards; + } + break; + }; +} + +/** + * Test ip object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + * + * @note we allow set if the value matches the hardwired value, + * otherwise return badvalue. + */ +static u8_t +ip_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + s32_t *sint_ptr = value; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ +#if IP_FORWARD + /* forwarding */ + if (*sint_ptr == 1) +#else + /* not-forwarding */ + if (*sint_ptr == 2) +#endif + { + set_ok = 1; + } + break; + case 2: /* ipDefaultTTL */ + if (*sint_ptr == IP_DEFAULT_TTL) + { + set_ok = 1; + } + break; + }; + return set_ok; +} + +static void +ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + case 3: /* ipAdEntNetMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipAdEntIfIndex */ + case 4: /* ipAdEntBcastAddr */ + case 5: /* ipAdEntReasmMaxSize */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + u16_t ifidx; + struct ip_addr ip; + struct netif *netif = netif_list; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], &ip); + ip.addr = htonl(ip.addr); + ifidx = 0; + while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) + { + netif = netif->next; + ifidx++; + } + + if (netif != NULL) + { + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + { + struct ip_addr *dst = value; + *dst = netif->ip_addr; + } + break; + case 2: /* ipAdEntIfIndex */ + { + s32_t *sint_ptr = value; + *sint_ptr = ifidx + 1; + } + break; + case 3: /* ipAdEntNetMask */ + { + struct ip_addr *dst = value; + *dst = netif->netmask; + } + break; + case 4: /* ipAdEntBcastAddr */ + { + s32_t *sint_ptr = value; + + /* lwIP oddity, there's no broadcast + address in the netif we can rely on */ + *sint_ptr = ip_addr_broadcast.addr & 1; + } + break; + case 5: /* ipAdEntReasmMaxSize */ + { + s32_t *sint_ptr = value; +#if IP_REASSEMBLY + /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, + * but only if receiving one fragmented packet at a time. + * The current solution is to calculate for 2 simultaneous packets... + */ + *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * + (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN))); +#else + /** @todo returning MTU would be a bad thing and + returning a wild guess like '576' isn't good either */ + *sint_ptr = 0; +#endif + } + break; + } + } +} + +/** + * @note + * lwIP IP routing is currently using the network addresses in netif_list. + * if no suitable network IP is found in netif_list, the default_netif is used. + */ +static void +ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + case 7: /* ipRouteNextHop */ + case 11: /* ipRouteMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipRouteIfIndex */ + case 3: /* ipRouteMetric1 */ + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 8: /* ipRouteType */ + case 10: /* ipRouteAge */ + case 12: /* ipRouteMetric5 */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ipRouteProto */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 13: /* ipRouteInfo */ + /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = iprouteinfo.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + struct ip_addr dest; + s32_t *ident; + u8_t id; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &dest); + dest.addr = htonl(dest.addr); + + if (dest.addr == 0) + { + /* ip_route() uses default netif for default route */ + netif = netif_default; + } + else + { + /* not using ip_route(), need exact match! */ + netif = netif_list; + while ((netif != NULL) && + !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) ) + { + netif = netif->next; + } + } + if (netif != NULL) + { + id = ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + { + struct ip_addr *dst = value; + + if (dest.addr == 0) + { + /* default rte has 0.0.0.0 dest */ + dst->addr = 0; + } + else + { + /* netifs have netaddress dest */ + dst->addr = netif->ip_addr.addr & netif->netmask.addr; + } + } + break; + case 2: /* ipRouteIfIndex */ + { + s32_t *sint_ptr = value; + + snmp_netiftoifindex(netif, sint_ptr); + } + break; + case 3: /* ipRouteMetric1 */ + { + s32_t *sint_ptr = value; + + if (dest.addr == 0) + { + /* default rte has metric 1 */ + *sint_ptr = 1; + } + else + { + /* other rtes have metric 0 */ + *sint_ptr = 0; + } + } + break; + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 12: /* ipRouteMetric5 */ + { + s32_t *sint_ptr = value; + /* not used */ + *sint_ptr = -1; + } + break; + case 7: /* ipRouteNextHop */ + { + struct ip_addr *dst = value; + + if (dest.addr == 0) + { + /* default rte: gateway */ + *dst = netif->gw; + } + else + { + /* other rtes: netif ip_addr */ + *dst = netif->ip_addr; + } + } + break; + case 8: /* ipRouteType */ + { + s32_t *sint_ptr = value; + + if (dest.addr == 0) + { + /* default rte is indirect */ + *sint_ptr = 4; + } + else + { + /* other rtes are direct */ + *sint_ptr = 3; + } + } + break; + case 9: /* ipRouteProto */ + { + s32_t *sint_ptr = value; + /* locally defined routes */ + *sint_ptr = 2; + } + break; + case 10: /* ipRouteAge */ + { + s32_t *sint_ptr = value; + /** @todo (sysuptime - timestamp last change) / 100 + @see snmp_insert_iprteidx_tree() */ + *sint_ptr = 0; + } + break; + case 11: /* ipRouteMask */ + { + struct ip_addr *dst = value; + + if (dest.addr == 0) + { + /* default rte use 0.0.0.0 mask */ + dst->addr = 0; + } + else + { + /* other rtes use netmask */ + *dst = netif->netmask; + } + } + break; + case 13: /* ipRouteInfo */ + objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t))); + break; + } + } +} + +static void +ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + case 4: /* ipNetToMediaType */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ipNetToMediaPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* ipNetToMediaNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + struct ip_addr* ipaddr_ret; +#endif /* LWIP_ARP */ + struct ip_addr ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + ip.addr = htonl(ip.addr); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + { + s32_t *sint_ptr = value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ipNetToMediaPhysAddress */ + { + struct eth_addr *dst = value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* ipNetToMediaNetAddress */ + { + struct ip_addr *dst = value; + + *dst = *ipaddr_ret; + } + break; + case 4: /* ipNetToMediaType */ + { + s32_t *sint_ptr = value; + /* dynamic (?) */ + *sint_ptr = 3; + } + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 27)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +icmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = value; + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* icmpInMsgs */ + *uint_ptr = icmpinmsgs; + break; + case 2: /* icmpInErrors */ + *uint_ptr = icmpinerrors; + break; + case 3: /* icmpInDestUnreachs */ + *uint_ptr = icmpindestunreachs; + break; + case 4: /* icmpInTimeExcds */ + *uint_ptr = icmpintimeexcds; + break; + case 5: /* icmpInParmProbs */ + *uint_ptr = icmpinparmprobs; + break; + case 6: /* icmpInSrcQuenchs */ + *uint_ptr = icmpinsrcquenchs; + break; + case 7: /* icmpInRedirects */ + *uint_ptr = icmpinredirects; + break; + case 8: /* icmpInEchos */ + *uint_ptr = icmpinechos; + break; + case 9: /* icmpInEchoReps */ + *uint_ptr = icmpinechoreps; + break; + case 10: /* icmpInTimestamps */ + *uint_ptr = icmpintimestamps; + break; + case 11: /* icmpInTimestampReps */ + *uint_ptr = icmpintimestampreps; + break; + case 12: /* icmpInAddrMasks */ + *uint_ptr = icmpinaddrmasks; + break; + case 13: /* icmpInAddrMaskReps */ + *uint_ptr = icmpinaddrmaskreps; + break; + case 14: /* icmpOutMsgs */ + *uint_ptr = icmpoutmsgs; + break; + case 15: /* icmpOutErrors */ + *uint_ptr = icmpouterrors; + break; + case 16: /* icmpOutDestUnreachs */ + *uint_ptr = icmpoutdestunreachs; + break; + case 17: /* icmpOutTimeExcds */ + *uint_ptr = icmpouttimeexcds; + break; + case 18: /* icmpOutParmProbs */ + *uint_ptr = icmpoutparmprobs; + break; + case 19: /* icmpOutSrcQuenchs */ + *uint_ptr = icmpoutsrcquenchs; + break; + case 20: /* icmpOutRedirects */ + *uint_ptr = icmpoutredirects; + break; + case 21: /* icmpOutEchos */ + *uint_ptr = icmpoutechos; + break; + case 22: /* icmpOutEchoReps */ + *uint_ptr = icmpoutechoreps; + break; + case 23: /* icmpOutTimestamps */ + *uint_ptr = icmpouttimestamps; + break; + case 24: /* icmpOutTimestampReps */ + *uint_ptr = icmpouttimestampreps; + break; + case 25: /* icmpOutAddrMasks */ + *uint_ptr = icmpoutaddrmasks; + break; + case 26: /* icmpOutAddrMaskReps */ + *uint_ptr = icmpoutaddrmaskreps; + break; + } +} + +#if LWIP_TCP +/** @todo tcp grp */ +static void +tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpRtoAlgorithm */ + case 2: /* tcpRtoMin */ + case 3: /* tcpRtoMax */ + case 4: /* tcpMaxConn */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 5: /* tcpActiveOpens */ + case 6: /* tcpPassiveOpens */ + case 7: /* tcpAttemptFails */ + case 8: /* tcpEstabResets */ + case 10: /* tcpInSegs */ + case 11: /* tcpOutSegs */ + case 12: /* tcpRetransSegs */ + case 14: /* tcpInErrs */ + case 15: /* tcpOutRsts */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 9: /* tcpCurrEstab */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = value; + s32_t *sint_ptr = value; + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* tcpRtoAlgorithm, vanj(4) */ + *sint_ptr = 4; + break; + case 2: /* tcpRtoMin */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 1000; + break; + case 3: /* tcpRtoMax */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 60000; + break; + case 4: /* tcpMaxConn */ + *sint_ptr = MEMP_NUM_TCP_PCB; + break; + case 5: /* tcpActiveOpens */ + *uint_ptr = tcpactiveopens; + break; + case 6: /* tcpPassiveOpens */ + *uint_ptr = tcppassiveopens; + break; + case 7: /* tcpAttemptFails */ + *uint_ptr = tcpattemptfails; + break; + case 8: /* tcpEstabResets */ + *uint_ptr = tcpestabresets; + break; + case 9: /* tcpCurrEstab */ + { + u16_t tcpcurrestab = 0; + struct tcp_pcb *pcb = tcp_active_pcbs; + while (pcb != NULL) + { + if ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT)) + { + tcpcurrestab++; + } + pcb = pcb->next; + } + *uint_ptr = tcpcurrestab; + } + break; + case 10: /* tcpInSegs */ + *uint_ptr = tcpinsegs; + break; + case 11: /* tcpOutSegs */ + *uint_ptr = tcpoutsegs; + break; + case 12: /* tcpRetransSegs */ + *uint_ptr = tcpretranssegs; + break; + case 14: /* tcpInErrs */ + *uint_ptr = tcpinerrs; + break; + case 15: /* tcpOutRsts */ + *uint_ptr = tcpoutrsts; + break; + } +} +#ifdef THIS_SEEMS_UNUSED +static void +tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (10) */ + ident_len += 10; + ident -= 10; + + if (ident_len == 11) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpConnState */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* tcpConnLocalAddress */ + case 4: /* tcpConnRemAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 3: /* tcpConnLocalPort */ + case 5: /* tcpConnRemPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct ip_addr lip, rip; + u16_t lport, rport; + s32_t *ident; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &lip); + lip.addr = htonl(lip.addr); + lport = ident[5]; + snmp_oidtoip(&ident[6], &rip); + rip.addr = htonl(rip.addr); + rport = ident[10]; + + /** @todo find matching PCB */ +} +#endif /* if 0 */ +#endif + +static void +udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 6)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = value; + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpInDatagrams */ + *uint_ptr = udpindatagrams; + break; + case 2: /* udpNoPorts */ + *uint_ptr = udpnoports; + break; + case 3: /* udpInErrors */ + *uint_ptr = udpinerrors; + break; + case 4: /* udpOutDatagrams */ + *uint_ptr = udpoutdatagrams; + break; + } +} + +static void +udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* udpLocalAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* udpLocalPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udpentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + struct udp_pcb *pcb; + struct ip_addr ip; + u16_t port; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], &ip); + ip.addr = htonl(ip.addr); + port = od->id_inst_ptr[5]; + + pcb = udp_pcbs; + while ((pcb != NULL) && + !((pcb->local_ip.addr == ip.addr) && + (pcb->local_port == port))) + { + pcb = pcb->next; + } + + if (pcb != NULL) + { + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpLocalAddress */ + { + struct ip_addr *dst = value; + *dst = pcb->local_ip; + } + break; + case 2: /* udpLocalPort */ + { + s32_t *sint_ptr = value; + *sint_ptr = pcb->local_port; + } + break; + } + } +} + +static void +snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + switch (id) + { + case 1: /* snmpInPkts */ + case 2: /* snmpOutPkts */ + case 3: /* snmpInBadVersions */ + case 4: /* snmpInBadCommunityNames */ + case 5: /* snmpInBadCommunityUses */ + case 6: /* snmpInASNParseErrs */ + case 8: /* snmpInTooBigs */ + case 9: /* snmpInNoSuchNames */ + case 10: /* snmpInBadValues */ + case 11: /* snmpInReadOnlys */ + case 12: /* snmpInGenErrs */ + case 13: /* snmpInTotalReqVars */ + case 14: /* snmpInTotalSetVars */ + case 15: /* snmpInGetRequests */ + case 16: /* snmpInGetNexts */ + case 17: /* snmpInSetRequests */ + case 18: /* snmpInGetResponses */ + case 19: /* snmpInTraps */ + case 20: /* snmpOutTooBigs */ + case 21: /* snmpOutNoSuchNames */ + case 22: /* snmpOutBadValues */ + case 24: /* snmpOutGenErrs */ + case 25: /* snmpOutGetRequests */ + case 26: /* snmpOutGetNexts */ + case 27: /* snmpOutSetRequests */ + case 28: /* snmpOutGetResponses */ + case 29: /* snmpOutTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 30: /* snmpEnableAuthenTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +snmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = value; + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + switch (id) + { + case 1: /* snmpInPkts */ + *uint_ptr = snmpinpkts; + break; + case 2: /* snmpOutPkts */ + *uint_ptr = snmpoutpkts; + break; + case 3: /* snmpInBadVersions */ + *uint_ptr = snmpinbadversions; + break; + case 4: /* snmpInBadCommunityNames */ + *uint_ptr = snmpinbadcommunitynames; + break; + case 5: /* snmpInBadCommunityUses */ + *uint_ptr = snmpinbadcommunityuses; + break; + case 6: /* snmpInASNParseErrs */ + *uint_ptr = snmpinasnparseerrs; + break; + case 8: /* snmpInTooBigs */ + *uint_ptr = snmpintoobigs; + break; + case 9: /* snmpInNoSuchNames */ + *uint_ptr = snmpinnosuchnames; + break; + case 10: /* snmpInBadValues */ + *uint_ptr = snmpinbadvalues; + break; + case 11: /* snmpInReadOnlys */ + *uint_ptr = snmpinreadonlys; + break; + case 12: /* snmpInGenErrs */ + *uint_ptr = snmpingenerrs; + break; + case 13: /* snmpInTotalReqVars */ + *uint_ptr = snmpintotalreqvars; + break; + case 14: /* snmpInTotalSetVars */ + *uint_ptr = snmpintotalsetvars; + break; + case 15: /* snmpInGetRequests */ + *uint_ptr = snmpingetrequests; + break; + case 16: /* snmpInGetNexts */ + *uint_ptr = snmpingetnexts; + break; + case 17: /* snmpInSetRequests */ + *uint_ptr = snmpinsetrequests; + break; + case 18: /* snmpInGetResponses */ + *uint_ptr = snmpingetresponses; + break; + case 19: /* snmpInTraps */ + *uint_ptr = snmpintraps; + break; + case 20: /* snmpOutTooBigs */ + *uint_ptr = snmpouttoobigs; + break; + case 21: /* snmpOutNoSuchNames */ + *uint_ptr = snmpoutnosuchnames; + break; + case 22: /* snmpOutBadValues */ + *uint_ptr = snmpoutbadvalues; + break; + case 24: /* snmpOutGenErrs */ + *uint_ptr = snmpoutgenerrs; + break; + case 25: /* snmpOutGetRequests */ + *uint_ptr = snmpoutgetrequests; + break; + case 26: /* snmpOutGetNexts */ + *uint_ptr = snmpoutgetnexts; + break; + case 27: /* snmpOutSetRequests */ + *uint_ptr = snmpoutsetrequests; + break; + case 28: /* snmpOutGetResponses */ + *uint_ptr = snmpoutgetresponses; + break; + case 29: /* snmpOutTraps */ + *uint_ptr = snmpouttraps; + break; + case 30: /* snmpEnableAuthenTraps */ + *uint_ptr = *snmpenableauthentraps_ptr; + break; + }; +} + +/** + * Test snmp object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + */ +static u8_t +snmp_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + id = od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = value; + + if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default) + { + /* we should have writable non-volatile mem here */ + if ((*sint_ptr == 1) || (*sint_ptr == 2)) + { + set_ok = 1; + } + } + else + { + /* const or hardwired value */ + if (*sint_ptr == snmpenableauthentraps_default) + { + set_ok = 1; + } + } + } + return set_ok; +} + +static void +snmp_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + id = od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = value; + *snmpenableauthentraps_ptr = *sint_ptr; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib_structs.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib_structs.c new file mode 100644 index 0000000..39a2949 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/mib_structs.c @@ -0,0 +1,1183 @@ +/** + * @file + * MIB tree access/construction functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_structs.h" +#include "lwip/mem.h" + +/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ +const s32_t prefix[4] = {1, 3, 6, 1}; + +#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) +/** node stack entry (old news?) */ +struct nse +{ + /** right child */ + struct mib_node* r_ptr; + /** right child identifier */ + s32_t r_id; + /** right child next level */ + u8_t r_nl; +}; +static u8_t node_stack_cnt; +static struct nse node_stack[NODE_STACK_SIZE]; + +/** + * Pushes nse struct onto stack. + */ +static void +push_node(struct nse* node) +{ + LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); + if (node_stack_cnt < NODE_STACK_SIZE) + { + node_stack[node_stack_cnt] = *node; + node_stack_cnt++; + } +} + +/** + * Pops nse struct from stack. + */ +static void +pop_node(struct nse* node) +{ + if (node_stack_cnt > 0) + { + node_stack_cnt--; + *node = node_stack[node_stack_cnt]; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); +} + +/** + * Conversion from ifIndex to lwIP netif + * @param ifindex is a s32_t object sub-identifier + * @param netif points to returned netif struct pointer + */ +void +snmp_ifindextonetif(s32_t ifindex, struct netif **netif) +{ + struct netif *nif = netif_list; + u16_t i, ifidx; + + ifidx = ifindex - 1; + i = 0; + while ((nif != NULL) && (i < ifidx)) + { + nif = nif->next; + i++; + } + *netif = nif; +} + +/** + * Conversion from lwIP netif to ifIndex + * @param netif points to a netif struct + * @param ifidx points to s32_t object sub-identifier + */ +void +snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) +{ + struct netif *nif = netif_list; + u16_t i; + + i = 0; + while ((nif != NULL) && (nif != netif)) + { + nif = nif->next; + i++; + } + *ifidx = i+1; +} + +/** + * Conversion from oid to lwIP ip_addr + * @param ident points to s32_t ident[4] input + * @param ip points to output struct + */ +void +snmp_oidtoip(s32_t *ident, struct ip_addr *ip) +{ + u32_t ipa; + + ipa = ident[0]; + ipa <<= 8; + ipa |= ident[1]; + ipa <<= 8; + ipa |= ident[2]; + ipa <<= 8; + ipa |= ident[3]; + ip->addr = ipa; +} + +/** + * Conversion from lwIP ip_addr to oid + * @param ip points to input struct + * @param ident points to s32_t ident[4] output + */ +void +snmp_iptooid(struct ip_addr *ip, s32_t *ident) +{ + u32_t ipa; + + ipa = ip->addr; + ident[0] = (ipa >> 24) & 0xff; + ident[1] = (ipa >> 16) & 0xff; + ident[2] = (ipa >> 8) & 0xff; + ident[3] = ipa & 0xff; +} + +struct mib_list_node * +snmp_mib_ln_alloc(s32_t id) +{ + struct mib_list_node *ln; + + ln = (struct mib_list_node *)mem_malloc(sizeof(struct mib_list_node)); + if (ln != NULL) + { + ln->prev = NULL; + ln->next = NULL; + ln->objid = id; + ln->nptr = NULL; + } + return ln; +} + +void +snmp_mib_ln_free(struct mib_list_node *ln) +{ + mem_free(ln); +} + +struct mib_list_rootnode * +snmp_mib_lrn_alloc(void) +{ + struct mib_list_rootnode *lrn; + + lrn = (struct mib_list_rootnode*)mem_malloc(sizeof(struct mib_list_rootnode)); + if (lrn != NULL) + { + lrn->get_object_def = noleafs_get_object_def; + lrn->get_value = noleafs_get_value; + lrn->set_test = noleafs_set_test; + lrn->set_value = noleafs_set_value; + lrn->node_type = MIB_NODE_LR; + lrn->maxlength = 0; + lrn->head = NULL; + lrn->tail = NULL; + lrn->count = 0; + } + return lrn; +} + +void +snmp_mib_lrn_free(struct mib_list_rootnode *lrn) +{ + mem_free(lrn); +} + +/** + * Inserts node in idx list in a sorted + * (ascending order) fashion and + * allocates the node if needed. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param insn points to a pointer to the inserted node + * used for constructing the tree. + * @return -1 if failed, 1 if inserted, 2 if present. + */ +s8_t +snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) +{ + struct mib_list_node *nn; + s8_t insert; + + LWIP_ASSERT("rn != NULL",rn != NULL); + + /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ + insert = 0; + if (rn->head == NULL) + { + /* empty list, add first node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + rn->head = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + insert = -1; + } + } + else + { + struct mib_list_node *n; + /* at least one node is present */ + n = rn->head; + while ((n != NULL) && (insert == 0)) + { + if (n->objid == objid) + { + /* node is already there */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); + *insn = n; + insert = 2; + } + else if (n->objid < objid) + { + if (n->next == NULL) + { + /* alloc and insert at the tail */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + nn->next = NULL; + nn->prev = n; + n->next = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + else + { + /* there's more to explore: traverse list */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); + n = n->next; + } + } + else + { + /* n->objid > objid */ + /* alloc and insert between n->prev and n */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + if (n->prev == NULL) + { + /* insert at the head */ + nn->next = n; + nn->prev = NULL; + rn->head = nn; + n->prev = nn; + } + else + { + /* insert in the middle */ + nn->next = n; + nn->prev = n->prev; + n->prev->next = nn; + n->prev = nn; + } + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + } + } + if (insert == 1) + { + rn->count += 1; + } + LWIP_ASSERT("insert != 0",insert != 0); + return insert; +} + +/** + * Finds node in idx list and returns deletion mark. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param fn returns pointer to found node + * @return 0 if not found, 1 if deletable, + * 2 can't delete (2 or more children), 3 not a list_node + */ +s8_t +snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) +{ + s8_t fc; + struct mib_list_node *n; + + LWIP_ASSERT("rn != NULL",rn != NULL); + n = rn->head; + while ((n != NULL) && (n->objid != objid)) + { + n = n->next; + } + if (n == NULL) + { + fc = 0; + } + else if (n->nptr == NULL) + { + /* leaf, can delete node */ + fc = 1; + } + else + { + struct mib_list_rootnode *r; + + if (n->nptr->node_type == MIB_NODE_LR) + { + r = (struct mib_list_rootnode *)n->nptr; + if (r->count > 1) + { + /* can't delete node */ + fc = 2; + } + else + { + /* count <= 1, can delete node */ + fc = 1; + } + } + else + { + /* other node type */ + fc = 3; + } + } + *fn = n; + return fc; +} + +/** + * Removes node from idx list + * if it has a single child left. + * + * @param rn points to the root node + * @param n points to the node to delete + * @return the nptr to be freed by caller + */ +struct mib_list_rootnode * +snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) +{ + struct mib_list_rootnode *next; + + LWIP_ASSERT("rn != NULL",rn != NULL); + LWIP_ASSERT("n != NULL",n != NULL); + + /* caller must remove this sub-tree */ + next = (struct mib_list_rootnode*)(n->nptr); + rn->count -= 1; + + if (n == rn->head) + { + rn->head = n->next; + if (n->next != NULL) + { + /* not last node, new list begin */ + n->next->prev = NULL; + } + } + else if (n == rn->tail) + { + rn->tail = n->prev; + if (n->prev != NULL) + { + /* not last node, new list end */ + n->prev->next = NULL; + } + } + else + { + /* node must be in the middle */ + n->prev->next = n->next; + n->next->prev = n->prev; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); + snmp_mib_ln_free(n); + if (rn->count == 0) + { + rn->head = NULL; + rn->tail = NULL; + } + return next; +} + + + +/** + * Searches tree for the supplied (scalar?) object identifier. + * + * @param node points to the root of the tree ('.internet') + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param np points to the found object instance (rerurn) + * @return pointer to the requested parent (!) node if success, NULL otherwise + */ +struct mib_node * +snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) +{ + u8_t node_type, ext_level; + + ext_level = 0; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); + while (node != NULL) + { + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + if (ident_len > 0) + { + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + i = 0; + while ((i < an->maxlength) && (an->objid[i] != *ident)) + { + i++; + } + if (i < an->maxlength) + { + /* found it, if available proceed to child, otherwise inspect leaf */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + if (an->nptr[i] == NULL) + { + /* a scalar leaf OR table, + inspect remaining instance number / table index */ + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)an; + } + else + { + /* follow next child pointer */ + ident++; + ident_len--; + node = an->nptr[i]; + } + } + else + { + /* search failed, identifier mismatch (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + if (ident_len > 0) + { + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid != *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + /* found it, proceed to child */; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + if (ln->nptr == NULL) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)lrn; + } + else + { + /* follow next child pointer */ + ident_len--; + ident++; + node = ln->nptr; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + u16_t i, len; + + if (ident_len > 0) + { + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) + { + i++; + } + if (i < len) + { + s32_t debug_id; + + en->get_objid(en->addr_inf,ext_level,i,&debug_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); + if ((ext_level + 1) == en->tree_levels) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)en; + } + else + { + /* found it, proceed to child */ + ident_len--; + ident++; + ext_level++; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); + return NULL; + } + } + else if (node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + sn = (mib_scalar_node *)node; + if ((ident_len == 1) && (*ident == 0)) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)sn; + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); + return NULL; + } + } + else + { + /* unknown node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test table for presence of at least one table entry. + */ +static u8_t +empty_table(struct mib_node *node) +{ + u8_t node_type; + u8_t empty = 0; + + if (node != NULL) + { + node_type = node->node_type; + if (node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + lrn = (struct mib_list_rootnode *)node; + if ((lrn->count == 0) || (lrn->head == NULL)) + { + empty = 1; + } + } + else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + an = (struct mib_array_node *)node; + if ((an->maxlength == 0) || (an->nptr == NULL)) + { + empty = 1; + } + } + else if (node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + en = (struct mib_external_node *)node; + if (en->tree_levels == 0) + { + empty = 1; + } + } + } + return empty; +} + +/** + * Tree expansion. + */ +struct mib_node * +snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + u8_t node_type, ext_level, climb_tree; + + ext_level = 0; + /* reset node stack */ + node_stack_cnt = 0; + while (node != NULL) + { + climb_tree = 0; + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + if (ident_len > 0) + { + i = 0; + while ((i < an->maxlength) && (an->objid[i] < *ident)) + { + i++; + } + if (i < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + /* add identifier to oidret */ + oidret->id[oidret->len] = an->objid[i]; + (oidret->len)++; + + if (an->nptr[i] == NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node (e.g. in a fixed size table) */ + if (an->objid[i] > *ident) + { + return (struct mib_node*)an; + } + else if ((i + 1) < an->maxlength) + { + /* an->objid[i] == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = an->objid[i + 1]; + (oidret->len)++; + return (struct mib_node*)an; + } + else + { + /* (i + 1) == an->maxlength */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u8_t j; + struct nse cur_node; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + j = i + 1; + while ((j < an->maxlength) && (empty_table(an->nptr[j]))) + { + j++; + } + if (j < an->maxlength) + { + cur_node.r_ptr = an->nptr[j]; + cur_node.r_id = an->objid[j]; + cur_node.r_nl = 0; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (an->objid[i] == *ident) + { + ident_len--; + ident++; + } + else + { + /* an->objid[i] < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = an->nptr[i]; + } + } + else + { + /* i == an->maxlength */ + climb_tree = 1; + } + } + else + { + u8_t j; + /* ident_len == 0, complete with leftmost '.thing' */ + j = 0; + while ((j < an->maxlength) && empty_table(an->nptr[j])) + { + j++; + } + if (j < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); + oidret->id[oidret->len] = an->objid[j]; + (oidret->len)++; + if (an->nptr[j] == NULL) + { + /* leaf node */ + return (struct mib_node*)an; + } + else + { + /* no leaf, continue */ + node = an->nptr[j]; + } + } + else + { + /* j == an->maxlength */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + if (ident_len > 0) + { + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid < *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + oidret->id[oidret->len] = ln->objid; + (oidret->len)++; + if (ln->nptr == NULL) + { + /* leaf node */ + if (ln->objid > *ident) + { + return (struct mib_node*)lrn; + } + else if (ln->next != NULL) + { + /* ln->objid == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = ln->next->objid; + (oidret->len)++; + return (struct mib_node*)lrn; + } + else + { + /* ln->next == NULL */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + struct nse cur_node; + + /* non-leaf, store right child ptr and id */ + jn = ln->next; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + cur_node.r_ptr = jn->nptr; + cur_node.r_id = jn->objid; + cur_node.r_nl = 0; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (ln->objid == *ident) + { + ident_len--; + ident++; + } + else + { + /* ln->objid < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = ln->nptr; + } + + } + else + { + /* ln == NULL */ + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + /* ident_len == 0, complete with leftmost '.thing' */ + jn = lrn->head; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); + oidret->id[oidret->len] = jn->objid; + (oidret->len)++; + if (jn->nptr == NULL) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); + return (struct mib_node*)lrn; + } + else + { + /* no leaf, continue */ + node = jn->nptr; + } + } + else + { + /* jn == NULL */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + s32_t ex_id; + + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + if (ident_len > 0) + { + u16_t i, len; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) + { + i++; + } + if (i < len) + { + /* add identifier to oidret */ + en->get_objid(en->addr_inf,ext_level,i,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + + if ((ext_level + 1) == en->tree_levels) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node */ + if (ex_id > *ident) + { + return (struct mib_node*)en; + } + else if ((i + 1) < len) + { + /* ex_id == *ident */ + en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); + (oidret->len)--; + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + return (struct mib_node*)en; + } + else + { + /* (i + 1) == len */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u8_t j; + struct nse cur_node; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + j = i + 1; + if (j < len) + { + /* right node is the current external node */ + cur_node.r_ptr = node; + en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); + cur_node.r_nl = ext_level + 1; + } + else + { + cur_node.r_ptr = NULL; + } + push_node(&cur_node); + if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) + { + ident_len--; + ident++; + } + else + { + /* external id < *ident */ + ident_len = 0; + } + /* proceed to child */ + ext_level++; + } + } + else + { + /* i == len (en->level_len()) */ + climb_tree = 1; + } + } + else + { + /* ident_len == 0, complete with leftmost '.thing' */ + en->get_objid(en->addr_inf,ext_level,0,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + if ((ext_level + 1) == en->tree_levels) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); + return (struct mib_node*)en; + } + else + { + /* no leaf, proceed to child */ + ext_level++; + } + } + } + else if(node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + /* scalar node */ + sn = (mib_scalar_node *)node; + if (ident_len > 0) + { + /* at .0 */ + climb_tree = 1; + } + else + { + /* ident_len == 0, complete object identifier */ + oidret->id[oidret->len] = 0; + (oidret->len)++; + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); + return (struct mib_node*)sn; + } + } + else + { + /* unknown/unhandled node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + + if (climb_tree) + { + struct nse child; + + /* find right child ptr */ + child.r_ptr = NULL; + child.r_id = 0; + child.r_nl = 0; + while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) + { + pop_node(&child); + /* trim returned oid */ + (oidret->len)--; + } + if (child.r_ptr != NULL) + { + /* incoming ident is useless beyond this point */ + ident_len = 0; + oidret->id[oidret->len] = child.r_id; + oidret->len++; + node = child.r_ptr; + ext_level = child.r_nl; + } + else + { + /* tree ends here ... */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); + return NULL; + } + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test object identifier for the iso.org.dod.internet prefix. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @return 1 if it matches, 0 otherwise + */ +u8_t +snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) +{ + if ((ident_len > 3) && + (ident[0] == 1) && (ident[1] == 3) && + (ident[2] == 6) && (ident[3] == 1)) + { + return 1; + } + else + { + return 0; + } +} + +/** + * Expands object identifier to the iso.org.dod.internet + * prefix for use in getnext operation. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param oidret points to returned expanded object identifier + * @return 1 if it matches, 0 otherwise + * + * @note ident_len 0 is allowed, expanding to the first known object id!! + */ +u8_t +snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + const s32_t *prefix_ptr; + s32_t *ret_ptr; + u8_t i; + + i = 0; + prefix_ptr = &prefix[0]; + ret_ptr = &oidret->id[0]; + ident_len = ((ident_len < 4)?ident_len:4); + while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) + { + *ret_ptr++ = *prefix_ptr++; + ident++; + i++; + } + if (i == ident_len) + { + /* match, complete missing bits */ + while (i < 4) + { + *ret_ptr++ = *prefix_ptr++; + i++; + } + oidret->len = i; + return 1; + } + else + { + /* i != ident_len */ + return 0; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_in.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_in.c new file mode 100644 index 0000000..d0c3c75 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_in.c @@ -0,0 +1,1454 @@ +/** + * @file + * SNMP input message processing (RFC1157). + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip_addr.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" +#include "lwip/snmp_structs.h" + +#include + +/* public (non-static) constants */ +/** SNMP v1 == 0 */ +const s32_t snmp_version = 0; +/** default SNMP community string */ +const char snmp_publiccommunity[7] = "public"; + +/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */ +struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS]; +/* UDP Protocol Control Block */ +struct udp_pcb *snmp1_pcb; + +static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); +static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); +static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); + + +/** + * Starts SNMP Agent. + * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161. + */ +void +snmp_init(void) +{ + struct snmp_msg_pstat *msg_ps; + u8_t i; + + snmp1_pcb = udp_new(); + if (snmp1_pcb != NULL) + { + udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT); + udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT); + } + msg_ps = &msg_input_list[0]; + for (i=0; istate = SNMP_MSG_EMPTY; + msg_ps->error_index = 0; + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps++; + } + trap_msg.pcb = snmp1_pcb; + /* The coldstart trap will only be output + if our outgoing interface is up & configured */ + snmp_coldstart_trap(); +} + +static void +snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) +{ + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + msg_ps->error_status = error; + msg_ps->error_index = 1 + msg_ps->vb_idx; + snmp_send_response(msg_ps); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +static void +snmp_ok_response(struct snmp_msg_pstat *msg_ps) +{ + err_t err_ret; + + err_ret = snmp_send_response(msg_ps); + if (err_ret == ERR_MEM) + { + /* serious memory problem, can't return tooBig */ + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status)); + } + /* free varbinds (if available) */ + snmp_varbind_list_free(&msg_ps->invb); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +/** + * Service an internal or external event for SNMP GET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + /* allocate output varbind */ + vb = (struct snmp_varbind *)mem_malloc(sizeof(struct snmp_varbind)); + LWIP_ASSERT("vb != NULL",vb != NULL); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is refereced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = msg_ps->ext_object_def.asn_type; + vb->value_len = msg_ps->ext_object_def.v_len; + if (vb->value_len > 0) + { + vb->value = mem_malloc(vb->value_len); + LWIP_ASSERT("vb->value != NULL",vb->value != NULL); + if (vb->value != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + mem_free(vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL); + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if (object_def.instance != MIB_OBJECT_NONE) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + /* allocate output varbind */ + vb = (struct snmp_varbind *)mem_malloc(sizeof(struct snmp_varbind)); + LWIP_ASSERT("vb != NULL",vb != NULL); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is refereced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = object_def.asn_type; + vb->value_len = object_def.v_len; + if (vb->value_len > 0) + { + vb->value = mem_malloc(vb->value_len); + LWIP_ASSERT("vb->value != NULL",vb->value != NULL); + if (vb->value != NULL) + { + mn->get_value(&object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + mem_free(vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP GETNEXT. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + vb = snmp_varbind_alloc(&msg_ps->ext_oid, + msg_ps->ext_object_def.asn_type, + msg_ps->ext_object_def.v_len); + if (vb != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_obj_id oid; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid)) + { + if (msg_ps->vb_ptr->ident_len > 3) + { + /* can offset ident_len and ident */ + mn = snmp_expand_tree((struct mib_node*)&internet, + msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &oid); + } + else + { + /* can't offset ident_len -4, ident + 4 */ + mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid); + } + } + else + { + mn = NULL; + } + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_oid = oid; + + en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]); + } + else + { + /* internal object */ + struct obj_def object_def; + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(1, &oid.id[oid.len - 1], &object_def); + + vb = snmp_varbind_alloc(&oid, object_def.asn_type, object_def.v_len); + if (vb != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + mn->get_value(&object_def, object_def.v_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP SET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the assosicated message process state + */ +static void +snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST; + en->set_test_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST) + { + struct mib_external_node *en; + + /* set_test() answer*/ + en = msg_ps->ext_mib_node; + + if (msg_ps->ext_object_def.access == MIB_OBJECT_READ_WRITE) + { + if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) && + (en->set_test_a(request_id,&msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE; + en->set_value_q(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* set_value failed, object has disappeared for some odd reason?? */ + snmp_error_response(msg_ps,SNMP_ES_GENERROR); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE) + { + struct mib_external_node *en; + + /** set_value_a() */ + en = msg_ps->ext_mib_node; + en->set_value_a(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value); + + /** @todo use set_value_pc() if toobig */ + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + msg_ps->vb_idx += 1; + } + + /* test all values before setting */ + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if (object_def.instance != MIB_OBJECT_NONE) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST; + + if (object_def.access == MIB_OBJECT_READ_WRITE) + { + if ((object_def.asn_type == msg_ps->vb_ptr->value_type) && + (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + msg_ps->vb_idx = 0; + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + } + + /* set all values "atomically" (be as "atomic" as possible) */ + while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /* skip iso prefix test, was done previously while settesting() */ + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + /* check if object is still available + (e.g. external hot-plug thingy present?) */ + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S; + mn->get_object_def(np.ident_len, np.ident, &object_def); + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + msg_ps->vb_idx += 1; + } + } + } + if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + /* simply echo the input if we can set it + @todo do we need to return the actual value? + e.g. if value is silently modified or behaves sticky? */ + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + snmp_ok_response(msg_ps); + } +} + + +/** + * Handle one internal or external event. + * Called for one async event. (recv external/private answer) + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + */ +void +snmp_msg_event(u8_t request_id) +{ + struct snmp_msg_pstat *msg_ps; + + if (request_id < SNMP_CONCURRENT_REQUESTS) + { + msg_ps = &msg_input_list[request_id]; + if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) + { + snmp_msg_getnext_event(request_id, msg_ps); + } + else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) + { + snmp_msg_get_event(request_id, msg_ps); + } + else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_msg_set_event(request_id, msg_ps); + } + } +} + + +/* lwIP UDP receive callback function */ +static void +snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) +{ + struct udp_hdr *udphdr; + + /* suppress unused argument warning */ + LWIP_UNUSED_ARG(arg); + /* peek in the UDP header (goto IP payload) */ + if(pbuf_header(p, UDP_HLEN)){ + LWIP_ASSERT("Can't move to UDP header", 0); + pbuf_free(p); + return; + } + udphdr = p->payload; + + /* check if datagram is really directed at us (including broadcast requests) */ + if ((pcb == snmp1_pcb) && (ntohs(udphdr->dest) == SNMP_IN_PORT)) + { + struct snmp_msg_pstat *msg_ps; + u8_t req_idx; + + /* traverse input message process list, look for SNMP_MSG_EMPTY */ + msg_ps = &msg_input_list[0]; + req_idx = 0; + while ((req_idxstate != SNMP_MSG_EMPTY)) + { + req_idx++; + msg_ps++; + } + if (req_idx != SNMP_CONCURRENT_REQUESTS) + { + err_t err_ret; + u16_t payload_len; + u16_t payload_ofs; + u16_t varbind_ofs = 0; + + /* accepting request */ + snmp_inc_snmpinpkts(); + /* record used 'protocol control block' */ + msg_ps->pcb = pcb; + /* source address (network order) */ + msg_ps->sip = *addr; + /* source port (host order (lwIP oddity)) */ + msg_ps->sp = port; + /* read UDP payload length from UDP header */ + payload_len = ntohs(udphdr->len) - UDP_HLEN; + + /* adjust to UDP payload */ + payload_ofs = UDP_HLEN; + + /* check total length, version, community, pdu type */ + err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps); + if (((msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) || + (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) || + (msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)) && + ((msg_ps->error_status == SNMP_ES_NOERROR) && + (msg_ps->error_index == 0)) ) + { + /* Only accept requests and requests without error (be robust) */ + err_ret = err_ret; + } + else + { + /* Reject response and trap headers or error requests as input! */ + err_ret = ERR_ARG; + } + if (err_ret == ERR_OK) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community)); + + /* Builds a list of variable bindings. Copy the varbinds from the pbuf + chain to glue them when these are divided over two or more pbuf's. */ + err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps); + if ((err_ret == ERR_OK) && (msg_ps->invb.count > 0)) + { + /* we've decoded the incoming message, release input msg now */ + pbuf_free(p); + + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps->error_index = 0; + /* find object for each variable binding */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + /* first variable binding from list to inspect */ + msg_ps->vb_idx = 0; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count)); + + /* handle input event and as much objects as possible in one go */ + snmp_msg_event(req_idx); + } + else + { + /* varbind-list decode failed, or varbind list empty. + drop request silently, do not return error! + (errors are only returned for a specific varbind failure) */ + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n")); + } + } + else + { + /* header check failed + drop request silently, do not return error! */ + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n")); + } + } + else + { + /* exceeding number of concurrent requests */ + pbuf_free(p); + } + } + else + { + /* datagram not for us */ + pbuf_free(p); + } +} + +/** + * Checks and decodes incoming SNMP message header, logs header errors. + * + * @param p points to pbuf chain of SNMP message (UDP payload) + * @param ofs points to first octet of SNMP message + * @param pdu_len the length of the UDP payload + * @param ofs_ret returns the ofset of the variable bindings + * @param m_stat points to the current message request state return + * @return + * - ERR_OK SNMP header is sane and accepted + * - ERR_ARG SNMP header is either malformed or rejected + */ +static err_t +snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, ofs_base; + u8_t len_octets; + u8_t type; + s32_t version; + + ofs_base = ofs; + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (pdu_len != (1 + len_octets + len)) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (version) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + if (version != 0) + { + /* not version 1 */ + snmp_inc_snmpinbadversions(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR))) + { + /* can't decode or no octet string (community) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* add zero terminator */ + len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN)); + m_stat->community[len] = 0; + m_stat->com_strlen = len; + if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0) + { + /** @todo: move this if we need to check more names */ + snmp_inc_snmpinbadcommunitynames(); + snmp_authfail_trap(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch(type) + { + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ): + /* GetRequest PDU */ + snmp_inc_snmpingetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ): + /* GetNextRequest PDU */ + snmp_inc_snmpingetnexts(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP): + /* GetResponse PDU */ + snmp_inc_snmpingetresponses(); + derr = ERR_ARG; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ): + /* SetRequest PDU */ + snmp_inc_snmpinsetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP): + /* Trap PDU */ + snmp_inc_snmpintraps(); + derr = ERR_ARG; + break; + default: + snmp_inc_snmpinasnparseerrs(); + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + /* unsupported input PDU for this agent (no parse error) */ + return ERR_ARG; + } + m_stat->rt = type & 0x1F; + ofs += (1 + len_octets); + if (len != (pdu_len - (ofs - ofs_base))) + { + /* decoded PDU length does not equal actual payload length */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (request ID) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-status) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be noError (0) for incoming requests. + log errors for mib-2 completeness and for debug purposes */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch (m_stat->error_status) + { + case SNMP_ES_TOOBIG: + snmp_inc_snmpintoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpinnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpinbadvalues(); + break; + case SNMP_ES_READONLY: + snmp_inc_snmpinreadonlys(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpingenerrs(); + break; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-index) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be 0 for incoming requests. + decode anyway to catch bad integers (and dirty tricks) */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + *ofs_ret = ofs; + return ERR_OK; +} + +static err_t +snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, vb_len; + u8_t len_octets; + u8_t type; + + /* variable binding list */ + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + + /* start with empty list */ + m_stat->invb.count = 0; + m_stat->invb.head = NULL; + m_stat->invb.tail = NULL; + + while (vb_len > 0) + { + struct snmp_obj_id oid, oid_value; + struct snmp_varbind *vb; + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) || + (len == 0) || (len > vb_len)) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets); + vb_len -= (1 + len_octets); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID))) + { + /* can't decode object name length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid); + if (derr != ERR_OK) + { + /* can't decode object name */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + /* can't decode object value length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + + switch (type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t)); + if (vb != NULL) + { + s32_t *vptr = vb->value; + + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t)); + if (vb != NULL) + { + u32_t *vptr = vb->value; + + derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + vb = snmp_varbind_alloc(&oid, type, len); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + vb = snmp_varbind_alloc(&oid, type, 0); + if (vb != NULL) + { + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value); + if (derr == ERR_OK) + { + vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t)); + if (vb != NULL) + { + u8_t i = oid_value.len; + s32_t *vptr = vb->value; + + while(i > 0) + { + i--; + vptr[i] = oid_value.id[i]; + } + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + if (len == 4) + { + /* must be exactly 4 octets! */ + vb = snmp_varbind_alloc(&oid, type, 4); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + } + else + { + derr = ERR_ARG; + } + break; + default: + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + } + + if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_add_snmpintotalsetvars(m_stat->invb.count); + } + else + { + snmp_add_snmpintotalreqvars(m_stat->invb.count); + } + + *ofs_ret = ofs; + return ERR_OK; +} + +struct snmp_varbind* +snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) +{ + struct snmp_varbind *vb; + + vb = (struct snmp_varbind *)mem_malloc(sizeof(struct snmp_varbind)); + LWIP_ASSERT("vb != NULL",vb != NULL); + if (vb != NULL) + { + u8_t i; + + vb->next = NULL; + vb->prev = NULL; + i = oid->len; + vb->ident_len = i; + if (i > 0) + { + /* allocate array of s32_t for our object identifier */ + vb->ident = (s32_t*)mem_malloc(sizeof(s32_t) * i); + LWIP_ASSERT("vb->ident != NULL",vb->ident != NULL); + if (vb->ident == NULL) + { + mem_free(vb); + return NULL; + } + while(i > 0) + { + i--; + vb->ident[i] = oid->id[i]; + } + } + else + { + /* i == 0, pass zero length object identifier */ + vb->ident = NULL; + } + vb->value_type = type; + vb->value_len = len; + if (len > 0) + { + /* allocate raw bytes for our object value */ + vb->value = mem_malloc(len); + LWIP_ASSERT("vb->value != NULL",vb->value != NULL); + if (vb->value == NULL) + { + if (vb->ident != NULL) + { + mem_free(vb->ident); + } + mem_free(vb); + return NULL; + } + } + else + { + /* ASN1_NUL type, or zero length ASN1_OC_STR */ + vb->value = NULL; + } + } + return vb; +} + +void +snmp_varbind_free(struct snmp_varbind *vb) +{ + if (vb->value != NULL ) + { + mem_free(vb->value); + } + if (vb->ident != NULL ) + { + mem_free(vb->ident); + } + mem_free(vb); +} + +void +snmp_varbind_list_free(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb, *prev; + + vb = root->tail; + while ( vb != NULL ) + { + prev = vb->prev; + snmp_varbind_free(vb); + vb = prev; + } + root->count = 0; + root->head = NULL; + root->tail = NULL; +} + +void +snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb) +{ + if (root->count == 0) + { + /* add first varbind to list */ + root->head = vb; + root->tail = vb; + } + else + { + /* add nth varbind to list tail */ + root->tail->next = vb; + vb->prev = root->tail; + root->tail = vb; + } + root->count += 1; +} + +struct snmp_varbind* +snmp_varbind_tail_remove(struct snmp_varbind_root *root) +{ + struct snmp_varbind* vb; + + if (root->count > 0) + { + /* remove tail varbind */ + vb = root->tail; + root->tail = vb->prev; + vb->prev->next = NULL; + root->count -= 1; + } + else + { + /* nothing to remove */ + vb = NULL; + } + return vb; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_out.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_out.c new file mode 100644 index 0000000..b705aac --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/snmp/msg_out.c @@ -0,0 +1,683 @@ +/** + * @file + * SNMP output message processing (RFC1157). + * + * Output responses and traps are build in two passes: + * + * Pass 0: iterate over the output message backwards to determine encoding lengths + * Pass 1: the actual forward encoding of internal form into ASN1 + * + * The single-pass encoding method described by Comer & Stevens + * requires extra buffer space and copying for reversal of the packet. + * The buffer requirement can be prohibitively large for big payloads + * (>= 484) therefore we use the two encoding passes. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" + +struct snmp_trap_dst +{ + /* destination IP address in network order */ + struct ip_addr dip; + /* set to 0 when disabled, >0 when enabled */ + u8_t enable; +}; +struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; + +/** TRAP message structure */ +struct snmp_msg_trap trap_msg; + +static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len); +static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len); +static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root); + +static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p); +static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p); +static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs); + +/** + * Sets enable switch for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param enable switch if 0 destination is disabled >0 enabled. + */ +void +snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + trap_dst[dst_idx].enable = enable; + } +} + +/** + * Sets IPv4 address for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param dst IPv4 address in host order. + */ +void +snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + trap_dst[dst_idx].dip.addr = htonl(dst->addr); + } +} + +/** + * Sends a 'getresponse' message to the request originator. + * + * @param m_stat points to the current message request state source + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the m_stat + * and provide error-status and index (except for tooBig errors) ... + */ +err_t +snmp_send_response(struct snmp_msg_pstat *m_stat) +{ + struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0}; + struct pbuf *p; + u16_t tot_len; + err_t err; + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&m_stat->outvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + + /* try allocating pbuf(s) for complete response */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n")); + + /* can't construct reply, return error-status tooBig */ + m_stat->error_status = SNMP_ES_TOOBIG; + m_stat->error_index = 0; + /* pass 0, recalculate lengths, for empty varbind-list */ + tot_len = snmp_varbind_list_sum(&emptyvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + /* retry allocation once for header and empty varbind-list */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + } + if (p != NULL) + { + /* first pbuf alloc try or retry alloc success */ + u16_t ofs; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n")); + + /* pass 1, size error, encode packet ino the pbuf(s) */ + ofs = snmp_resp_header_enc(m_stat, p); + if (m_stat->error_status == SNMP_ES_TOOBIG) + { + snmp_varbind_list_enc(&emptyvb, p, ofs); + } + else + { + snmp_varbind_list_enc(&m_stat->outvb, p, ofs); + } + + switch (m_stat->error_status) + { + case SNMP_ES_TOOBIG: + snmp_inc_snmpouttoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpoutnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpoutbadvalues(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpoutgenerrs(); + break; + } + snmp_inc_snmpoutgetresponses(); + snmp_inc_snmpoutpkts(); + + /** @todo do we need separate rx and tx pcbs for threaded case? */ + /** connect to the originating source */ + udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp); + err = udp_send(m_stat->pcb, p); + if (err == ERR_MEM) + { + /** @todo release some memory, retry and return tooBig? tooMuchHassle? */ + err = ERR_MEM; + } + else + { + err = ERR_OK; + } + /** disassociate remote address and port with this pcb */ + udp_disconnect(m_stat->pcb); + + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n")); + return err; + } + else + { + /* first pbuf alloc try or retry alloc failed + very low on memory, couldn't return tooBig */ + return ERR_MEM; + } +} + + +/** + * Sends an generic or enterprise specific trap message. + * + * @param generic_trap is the trap code + * @param eoid points to enterprise object identifier + * @param specific_trap used for enterprise traps when generic_trap == 6 + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the trap_msg + * @note the use of the enterpise identifier field + * is per RFC1215. + * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps + * and .iso.org.dod.internet.private.enterprises.yourenterprise + * (sysObjectID) for specific traps. + */ +err_t +snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) +{ + struct snmp_trap_dst *td; + struct netif *dst_if; + struct ip_addr dst_ip; + struct pbuf *p; + u16_t i,tot_len; + + for (i=0, td = &trap_dst[0]; ienable != 0) && (td->dip.addr != 0)) + { + /* network order trap destination */ + trap_msg.dip.addr = td->dip.addr; + /* lookup current source address for this dst */ + dst_if = ip_route(&td->dip); + dst_ip.addr = ntohl(dst_if->ip_addr.addr); + trap_msg.sip_raw[0] = dst_ip.addr >> 24; + trap_msg.sip_raw[1] = dst_ip.addr >> 16; + trap_msg.sip_raw[2] = dst_ip.addr >> 8; + trap_msg.sip_raw[3] = dst_ip.addr; + trap_msg.gen_trap = generic_trap; + trap_msg.spc_trap = specific_trap; + if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) + { + /* enterprise-Specific trap */ + trap_msg.enterprise = eoid; + } + else + { + /* generic (MIB-II) trap */ + snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); + } + snmp_get_sysuptime(&trap_msg.ts); + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&trap_msg.outvb); + tot_len = snmp_trap_header_sum(&trap_msg, tot_len); + + /* allocate pbuf(s) */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p != NULL) + { + u16_t ofs; + + /* pass 1, encode packet ino the pbuf(s) */ + ofs = snmp_trap_header_enc(&trap_msg, p); + snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); + + snmp_inc_snmpouttraps(); + snmp_inc_snmpoutpkts(); + + /** connect to the TRAP destination */ + udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT); + udp_send(trap_msg.pcb, p); + /** disassociate remote address and port with this pcb */ + udp_disconnect(trap_msg.pcb); + + pbuf_free(p); + } + else + { + return ERR_MEM; + } + } + } + return ERR_OK; +} + +void +snmp_coldstart_trap(void) +{ + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0); +} + +void +snmp_authfail_trap(void) +{ + u8_t enable; + snmp_get_snmpenableauthentraps(&enable); + if (enable == 1) + { + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0); + } +} + +/** + * Sums response header field lengths from tail to head and + * returns resp_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param rhl points to returned header lengths + * @return the required lenght for encoding the response header + */ +static u16_t +snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_resp_header_lengths *rhl; + + rhl = &m_stat->rhl; + tot_len = vb_len; + snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen); + snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen); + tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen; + + snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen); + snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen); + tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen; + + snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen); + snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen); + tot_len += 1 + rhl->ridlenlen + rhl->ridlen; + + rhl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen); + tot_len += 1 + rhl->pdulenlen; + + rhl->comlen = m_stat->com_strlen; + snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen); + tot_len += 1 + rhl->comlenlen + rhl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen); + snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen); + tot_len += 1 + rhl->verlen + rhl->verlenlen; + + rhl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen); + tot_len += 1 + rhl->seqlenlen; + + return tot_len; +} + +/** + * Sums trap header field lengths from tail to head and + * returns trap_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param thl points to returned header lengths + * @return the required lenght for encoding the trap header + */ +static u16_t +snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_trap_header_lengths *thl; + + thl = &m_trap->thl; + tot_len = vb_len; + + snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen); + snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen); + tot_len += 1 + thl->tslen + thl->tslenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen); + snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen); + tot_len += 1 + thl->strplen + thl->strplenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen); + snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen); + tot_len += 1 + thl->gtrplen + thl->gtrplenlen; + + thl->aaddrlen = 4; + snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen); + tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen; + + snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen); + snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen); + tot_len += 1 + thl->eidlen + thl->eidlenlen; + + thl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen); + tot_len += 1 + thl->pdulenlen; + + thl->comlen = sizeof(snmp_publiccommunity) - 1; + snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen); + tot_len += 1 + thl->comlenlen + thl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen); + snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen); + tot_len += 1 + thl->verlen + thl->verlenlen; + + thl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen); + tot_len += 1 + thl->seqlenlen; + + return tot_len; +} + +/** + * Sums varbind lengths from tail to head and + * annotates lengths in varbind for second encoding pass. + * + * @param root points to the root of the variable binding list + * @return the required lenght for encoding the variable bindings + */ +static u16_t +snmp_varbind_list_sum(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb; + u32_t *uint_ptr; + s32_t *sint_ptr; + u16_t tot_len; + + tot_len = 0; + vb = root->tail; + while ( vb != NULL ) + { + /* encoded value lenght depends on type */ + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = vb->value; + snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = vb->value; + snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + vb->vlen = vb->value_len; + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = vb->value; + snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen); + break; + default: + /* unsupported type */ + vb->vlen = 0; + break; + }; + /* encoding length of value length field */ + snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen); + snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen); + snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen); + + vb->seqlen = 1 + vb->vlenlen + vb->vlen; + vb->seqlen += 1 + vb->olenlen + vb->olen; + snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen); + + /* varbind seq */ + tot_len += 1 + vb->seqlenlen + vb->seqlen; + + vb = vb->prev; + } + + /* varbind-list seq */ + root->seqlen = tot_len; + snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen); + tot_len += 1 + root->seqlenlen; + + return tot_len; +} + +/** + * Encodes response header from head to tail. + */ +static u16_t +snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen); + ofs += m_stat->rhl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen); + ofs += m_stat->rhl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version); + ofs += m_stat->rhl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen); + ofs += m_stat->rhl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community); + ofs += m_stat->rhl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen); + ofs += m_stat->rhl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen); + ofs += m_stat->rhl.ridlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid); + ofs += m_stat->rhl.ridlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen); + ofs += m_stat->rhl.errstatlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status); + ofs += m_stat->rhl.errstatlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen); + ofs += m_stat->rhl.erridxlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index); + ofs += m_stat->rhl.erridxlen; + + return ofs; +} + +/** + * Encodes trap header from head to tail. + */ +static u16_t +snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen); + ofs += m_trap->thl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen); + ofs += m_trap->thl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version); + ofs += m_trap->thl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen); + ofs += m_trap->thl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]); + ofs += m_trap->thl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen); + ofs += m_trap->thl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen); + ofs += m_trap->thl.eidlenlen; + snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]); + ofs += m_trap->thl.eidlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen); + ofs += m_trap->thl.aaddrlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]); + ofs += m_trap->thl.aaddrlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen); + ofs += m_trap->thl.gtrplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap); + ofs += m_trap->thl.gtrplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen); + ofs += m_trap->thl.strplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap); + ofs += m_trap->thl.strplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen); + ofs += m_trap->thl.tslenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts); + ofs += m_trap->thl.tslen; + + return ofs; +} + +/** + * Encodes varbind list from head to tail. + */ +static u16_t +snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs) +{ + struct snmp_varbind *vb; + s32_t *sint_ptr; + u32_t *uint_ptr; + u8_t *raw_ptr; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, root->seqlen); + ofs += root->seqlenlen; + + vb = root->head; + while ( vb != NULL ) + { + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->seqlen); + ofs += vb->seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->olen); + ofs += vb->olenlen; + snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]); + ofs += vb->olen; + + snmp_asn1_enc_type(p, ofs, vb->value_type); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->vlen); + ofs += vb->vlenlen; + + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = vb->value; + snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = vb->value; + snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + raw_ptr = vb->value; + snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = vb->value; + snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr); + break; + default: + /* unsupported type */ + break; + }; + ofs += vb->vlen; + vb = vb->next; + } + return ofs; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/stats.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/stats.c new file mode 100644 index 0000000..2ef179d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/stats.c @@ -0,0 +1,149 @@ +/** + * @file + * Statistics module + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/mem.h" + +#include + +struct stats_ lwip_stats; + +#if LWIP_STATS_DISPLAY +void +stats_display_proto(struct stats_proto *proto, char *name) +{ + LWIP_PLATFORM_DIAG("\n\r%s\n\r\t", name); + LWIP_PLATFORM_DIAG("xmit: %"STAT_COUNTER_F"\n\r\t", proto->xmit); + LWIP_PLATFORM_DIAG("recv: %"STAT_COUNTER_F"\n\r\t", proto->recv); + LWIP_PLATFORM_DIAG("fw: %"STAT_COUNTER_F"\n\r\t", proto->fw); + LWIP_PLATFORM_DIAG("drop: %"STAT_COUNTER_F"\n\r\t", proto->drop); + LWIP_PLATFORM_DIAG("chkerr: %"STAT_COUNTER_F"\n\r\t", proto->chkerr); + LWIP_PLATFORM_DIAG("lenerr: %"STAT_COUNTER_F"\n\r\t", proto->lenerr); + LWIP_PLATFORM_DIAG("memerr: %"STAT_COUNTER_F"\n\r\t", proto->memerr); + LWIP_PLATFORM_DIAG("rterr: %"STAT_COUNTER_F"\n\r\t", proto->rterr); + LWIP_PLATFORM_DIAG("proterr: %"STAT_COUNTER_F"\n\r\t", proto->proterr); + LWIP_PLATFORM_DIAG("opterr: %"STAT_COUNTER_F"\n\r\t", proto->opterr); + LWIP_PLATFORM_DIAG("err: %"STAT_COUNTER_F"\n\r\t", proto->err); + LWIP_PLATFORM_DIAG("cachehit: %"STAT_COUNTER_F"\n\r", proto->cachehit); +} + +#if IGMP_STATS +void +stats_display_igmp(struct stats_igmp *igmp) +{ + LWIP_PLATFORM_DIAG("\n\rIGMP\n\r\t")); + LWIP_PLATFORM_DIAG("lenerr: %"STAT_COUNTER_F"\n\r\t", igmp->lenerr); + LWIP_PLATFORM_DIAG("chkerr: %"STAT_COUNTER_F"\n\r\t", igmp->chkerr); + LWIP_PLATFORM_DIAG("v1_rxed: %"STAT_COUNTER_F"\n\r\t", igmp->v1_rxed); + LWIP_PLATFORM_DIAG("join_sent: %"STAT_COUNTER_F"\n\r\t", igmp->join_sent); + LWIP_PLATFORM_DIAG("leave_sent: %"STAT_COUNTER_F"\n\r\t", igmp->leave_sent); + LWIP_PLATFORM_DIAG("unicast_query: %"STAT_COUNTER_F"\n\r\t", igmp->unicast_query); + LWIP_PLATFORM_DIAG("report_sent: %"STAT_COUNTER_F"\n\r\t", igmp->report_sent); + LWIP_PLATFORM_DIAG("report_rxed: %"STAT_COUNTER_F"\n\r\t", igmp->report_rxed); + LWIP_PLATFORM_DIAG("group_query_rxed: %"STAT_COUNTER_F"\n\r", igmp->group_query_rxed); +} +#endif /* IGMP_STATS */ + +#if MEM_STATS || MEMP_STATS +void +stats_display_mem(struct stats_mem *mem, char *name) +{ + LWIP_PLATFORM_DIAG("\n\rMEM %s\n\r\t", name); + LWIP_PLATFORM_DIAG("avail: %"U32_F"\n\r\t", (u32_t)mem->avail); + LWIP_PLATFORM_DIAG("used: %"U32_F"\n\r\t", (u32_t)mem->used); + LWIP_PLATFORM_DIAG("max: %"U32_F"\n\r\t", (u32_t)mem->max); + LWIP_PLATFORM_DIAG("err: %"U32_F"\n\r", (u32_t)mem->err); +} + +#if MEMP_STATS +void +stats_display_memp(struct stats_mem *mem, int index) +{ + char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + if(index < MEMP_MAX) { + stats_display_mem(mem, memp_names[index]); + } +} +#endif /* MEMP_STATS */ +#endif /* MEM_STATS || MEMP_STATS */ + +#if SYS_STATS +void +stats_display_sys(struct stats_sys *sys) +{ + LWIP_PLATFORM_DIAG("\n\rSYS\n\r\t"); + LWIP_PLATFORM_DIAG("sem.used: %"U32_F"\n\r\t", (u32_t)sys->sem.used); + LWIP_PLATFORM_DIAG("sem.max: %"U32_F"\n\r\t", (u32_t)sys->sem.max); + LWIP_PLATFORM_DIAG("sem.err: %"U32_F"\n\r\t", (u32_t)sys->sem.err); + LWIP_PLATFORM_DIAG("mbox.used: %"U32_F"\n\r\t", (u32_t)sys->mbox.used); + LWIP_PLATFORM_DIAG("mbox.max: %"U32_F"\n\r\t", (u32_t)sys->mbox.max); + LWIP_PLATFORM_DIAG("mbox.err: %"U32_F"\n\r\t", (u32_t)sys->mbox.err); +} +#endif /* SYS_STATS */ + +void +stats_display(void) +{ + s16_t i; + + LINK_STATS_DISPLAY(); + ETHARP_STATS_DISPLAY(); + IPFRAG_STATS_DISPLAY(); + IP_STATS_DISPLAY(); + IGMP_STATS_DISPLAY(); + ICMP_STATS_DISPLAY(); + UDP_STATS_DISPLAY(); + TCP_STATS_DISPLAY(); + MEM_STATS_DISPLAY(); + for (i = 0; i < MEMP_MAX; i++) { + MEMP_STATS_DISPLAY(i); + } + SYS_STATS_DISPLAY(); +} +#endif /* LWIP_STATS_DISPLAY */ + +#endif /* LWIP_STATS */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/sys.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/sys.c new file mode 100644 index 0000000..cb5e86a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/sys.c @@ -0,0 +1,346 @@ +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/tcpip.h" + +/** + * Struct used for sys_sem_wait_timeout() to tell wether the time + * has run out or the semaphore has really become available. + */ +struct sswt_cb +{ + s16_t timeflag; + sys_sem_t *psem; +}; + +/** + * Wait (forever) for a message to arrive in an mbox. + * While waiting, timeouts (for this thread) are processed. + * + * @param mbox the mbox to fetch the message from + * @param msg the place to store the message + */ +void +sys_mbox_fetch(sys_mbox_t mbox, void **msg) +{ + u32_t time_needed; + struct sys_timeouts *timeouts; + struct sys_timeo *tmptimeout; + sys_timeout_handler h; + void *arg; + + again: + timeouts = sys_arch_timeouts(); + + if (!timeouts || !timeouts->next) { + UNLOCK_TCPIP_CORE(); + time_needed = sys_arch_mbox_fetch(mbox, msg, 0); + LOCK_TCPIP_CORE(); + } else { + if (timeouts->next->time > 0) { + UNLOCK_TCPIP_CORE(); + time_needed = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time); + LOCK_TCPIP_CORE(); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = timeouts->next; + timeouts->next = tmptimeout->next; + h = tmptimeout->h; + arg = tmptimeout->arg; + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (h != NULL) { + LWIP_DEBUGF(SYS_DEBUG, ("smf calling h=%p(%p)\n", *(void**)&h, arg)); + h(arg); + } + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < timeouts->next->time) { + timeouts->next->time -= time_needed; + } else { + timeouts->next->time = 0; + } + } + } +} + +/** + * Wait (forever) for a semaphore to become available. + * While waiting, timeouts (for this thread) are processed. + * + * @param sem semaphore to wait for + */ +void +sys_sem_wait(sys_sem_t sem) +{ + u32_t time_needed; + struct sys_timeouts *timeouts; + struct sys_timeo *tmptimeout; + sys_timeout_handler h; + void *arg; + + again: + + timeouts = sys_arch_timeouts(); + + if (!timeouts || !timeouts->next) { + sys_arch_sem_wait(sem, 0); + } else { + if (timeouts->next->time > 0) { + time_needed = sys_arch_sem_wait(sem, timeouts->next->time); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = timeouts->next; + timeouts->next = tmptimeout->next; + h = tmptimeout->h; + arg = tmptimeout->arg; + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (h != NULL) { + LWIP_DEBUGF(SYS_DEBUG, ("ssw h=%p(%p)\n", *(void**)&h, (void *)arg)); + h(arg); + } + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < timeouts->next->time) { + timeouts->next->time -= time_needed; + } else { + timeouts->next->time = 0; + } + } + } +} + +/** + * Create a one-shot timer (aka timeout). Timeouts are processed in the + * following cases: + * - while waiting for a message using sys_mbox_fetch() + * - while waiting for a semaphore using sys_sem_wait() or sys_sem_wait_timeout() + * - while sleeping using the inbuilt sys_msleep() + * + * @param msecs time in milliseconds after that the timer should expire + * @param h callback function to call when msecs have elapsed + * @param arg argument to pass to the callback function + */ +void +sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *timeout, *t; + + timeout = memp_malloc(MEMP_SYS_TIMEOUT); + if (timeout == NULL) { + LWIP_ASSERT("sys_timeout: timeout != NULL", timeout != NULL); + return; + } + timeout->next = NULL; + timeout->h = h; + timeout->arg = arg; + timeout->time = msecs; + + timeouts = sys_arch_timeouts(); + + LWIP_DEBUGF(SYS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" h=%p arg=%p\n", + (void *)timeout, msecs, *(void**)&h, (void *)arg)); + + if (timeouts == NULL) { + LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL); + return; + } + + if (timeouts->next == NULL) { + timeouts->next = timeout; + return; + } + + if (timeouts->next->time > msecs) { + timeouts->next->time -= msecs; + timeout->next = timeouts->next; + timeouts->next = timeout; + } else { + for(t = timeouts->next; t != NULL; t = t->next) { + timeout->time -= t->time; + if (t->next == NULL || t->next->time > timeout->time) { + if (t->next != NULL) { + t->next->time -= timeout->time; + } + timeout->next = t->next; + t->next = timeout; + break; + } + } + } +} + +/** + * Go through timeout list (for this task only) and remove the first matching + * entry, even though the timeout has not triggered yet. + * + * @note This function only works as expected if there is only one timeout + * calling 'h' in the list of timeouts. + * + * @param h callback function that would be called by the timeout + * @param arg callback argument that would be passed to h +*/ +void +sys_untimeout(sys_timeout_handler h, void *arg) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *prev_t, *t; + + timeouts = sys_arch_timeouts(); + + if (timeouts == NULL) { + LWIP_ASSERT("sys_untimeout: timeouts != NULL", timeouts != NULL); + return; + } + if (timeouts->next == NULL) { + return; + } + + for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { + if ((t->h == h) && (t->arg == arg)) { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) { + timeouts->next = t->next; + } else { + prev_t->next = t->next; + } + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) { + t->next->time += t->time; + } + memp_free(MEMP_SYS_TIMEOUT, t); + return; + } + } + return; +} + +/** + * Timeout handler function for sys_sem_wait_timeout() + * + * @param arg struct sswt_cb* used to signal a semaphore and end waiting. + */ +static void +sswt_handler(void *arg) +{ + struct sswt_cb *sswt_cb = (struct sswt_cb *) arg; + + /* Timeout. Set flag to TRUE and signal semaphore */ + sswt_cb->timeflag = 1; + sys_sem_signal(*(sswt_cb->psem)); +} + +/** + * Wait for a semaphore with timeout (specified in ms) + * + * @param sem semaphore to wait + * @param timeout timeout in ms (0: wait forever) + * @return 0 on timeout, 1 otherwise + */ +int +sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout) +{ + struct sswt_cb sswt_cb; + + sswt_cb.psem = &sem; + sswt_cb.timeflag = 0; + + /* If timeout is zero, then just wait forever */ + if (timeout > 0) { + /* Create a timer and pass it the address of our flag */ + sys_timeout(timeout, sswt_handler, &sswt_cb); + } + sys_sem_wait(sem); + /* Was it a timeout? */ + if (sswt_cb.timeflag) { + /* timeout */ + return 0; + } else { + /* Not a timeout. Remove timeout entry */ + sys_untimeout(sswt_handler, &sswt_cb); + return 1; + } +} + +/** + * Sleep for some ms. Timeouts are processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + sys_sem_t delaysem = sys_sem_new(0); + + sys_sem_wait_timeout(delaysem, ms); + + sys_sem_free(delaysem); +} + + +#endif /* NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp.c new file mode 100644 index 0000000..81c4432 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp.c @@ -0,0 +1,1461 @@ +/** + * @file + * Transmission Control Protocol for IP + * + * This file contains common functions for the TCP implementation, such as functinos + * for manipulating the data structures and the TCP timer functions. TCP functions + * related to input and output is found in tcp_in.c and tcp_out.c respectively. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/snmp.h" +#include "lwip/tcp.h" +#include "lwip/debug.h" +#include "lwip/stats.h" + +#include + +const char *tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; + +/* Incremented every coarse grained timer shot (typically every 500 ms). */ +u32_t tcp_ticks; +const u8_t tcp_backoff[13] = + { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; + /* Times per slowtmr hits */ +const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; + +/* The TCP PCB lists. */ + +/** List of all TCP PCBs bound but not yet (connected || listening) */ +struct tcp_pcb *tcp_bound_pcbs; +/** List of all TCP PCBs in LISTEN state */ +union tcp_listen_pcbs_t tcp_listen_pcbs; +/** List of all TCP PCBs that are in a state in which + * they accept or send data. */ +struct tcp_pcb *tcp_active_pcbs; +/** List of all TCP PCBs in TIME-WAIT state */ +struct tcp_pcb *tcp_tw_pcbs; + +struct tcp_pcb *tcp_tmp_pcb; + +static u8_t tcp_timer; +static u16_t tcp_new_port(void); + +/** + * Called periodically to dispatch TCP timers. + * + */ +void +tcp_tmr(void) +{ + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + + if (++tcp_timer & 1) { + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + } +} + +/** + * Closes the connection held by the PCB. + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it. + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ + err_t err; + +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + switch (pcb->state) { + case CLOSED: + /* Closing a pcb in the CLOSED state might seem erroneous, + * however, it is in this state once allocated and as yet unused + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + TCP_RMV(&tcp_bound_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + break; + case LISTEN: + err = ERR_OK; + tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb); + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + pcb = NULL; + break; + case SYN_SENT: + err = ERR_OK; + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + snmp_inc_tcpattemptfails(); + break; + case SYN_RCVD: + err = tcp_send_ctrl(pcb, TCP_FIN); + if (err == ERR_OK) { + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + } + break; + case ESTABLISHED: + err = tcp_send_ctrl(pcb, TCP_FIN); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + } + break; + case CLOSE_WAIT: + err = tcp_send_ctrl(pcb, TCP_FIN); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + } + break; + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + pcb = NULL; + break; + } + + if (pcb != NULL && err == ERR_OK) { + /* To ensure all data has been sent when tcp_close returns, we have + to make sure tcp_output doesn't fail. + Since we don't really have to ensure all data has been sent when tcp_close + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + /* @todo: When implementing SO_LINGER, this must be changed somehow: + If SOF_LINGER is set, the data should be sent when tcp_close returns. */ + tcp_output(pcb); + } + return err; +} + +/** + * Abandons a connection and optionally sends a RST to the remote + * host. Deletes the local protocol control block. This is done when + * a connection is killed because of shortage of memory. + * + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + u32_t seqno, ackno; + u16_t remote_port, local_port; + struct ip_addr remote_ip, local_ip; +#if LWIP_CALLBACK_API + void (* errf)(void *arg, err_t err); +#endif /* LWIP_CALLBACK_API */ + void *errf_arg; + + + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + seqno = pcb->snd_nxt; + ackno = pcb->rcv_nxt; + ip_addr_set(&local_ip, &(pcb->local_ip)); + ip_addr_set(&remote_ip, &(pcb->remote_ip)); + local_port = pcb->local_port; + remote_port = pcb->remote_port; +#if LWIP_CALLBACK_API + errf = pcb->errf; +#endif /* LWIP_CALLBACK_API */ + errf_arg = pcb->callback_arg; + tcp_pcb_remove(&tcp_active_pcbs, pcb); + if (pcb->unacked != NULL) { + tcp_segs_free(pcb->unacked); + } + if (pcb->unsent != NULL) { + tcp_segs_free(pcb->unsent); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + tcp_segs_free(pcb->ooseq); + } +#endif /* TCP_QUEUE_OOSEQ */ + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + if (reset) { + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); + tcp_rst(seqno, ackno, &local_ip, &remote_ip, local_port, remote_port); + } + } +} + +/** + * Binds the connection to a local portnumber and IP address. If the + * IP address is not given (i.e., ipaddr == NULL), the IP address of + * the outgoing network interface is used instead. + * + * @param pcb the tcp_pcb to bind (no check is done whether this pcb is + * already bound!) + * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind + * to any local address + * @param port the local port to bind to + * @return ERR_USE if the port is already in use + * ERR_OK if bound + */ +err_t +tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) +{ + struct tcp_pcb *cpcb; + + LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + + if (port == 0) { + port = tcp_new_port(); + } + /* Check if the address already is in use. */ + /* Check the listen pcbs. */ + for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; + cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + /* Check the connected pcbs. */ + for(cpcb = tcp_active_pcbs; + cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + /* Check the bound, not yet connected pcbs. */ + for(cpcb = tcp_bound_pcbs; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + /* @todo: until SO_REUSEADDR is implemented (see task #6995 on savannah), + * we have to check the pcbs in TIME-WAIT state, also: */ + for(cpcb = tcp_tw_pcbs; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { + if (ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + + if (!ip_addr_isany(ipaddr)) { + pcb->local_ip = *ipaddr; + } + pcb->local_port = port; + TCP_REG(&tcp_bound_pcbs, pcb); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); + return ERR_OK; +} +#if LWIP_CALLBACK_API +/** + * Default accept callback if no accept callback is specified by the user. + */ +static err_t +tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(err); + + return ERR_ABRT; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Set the state of the connection to be LISTEN, which means that it + * is able to accept incoming connections. The protocol control block + * is reallocated in order to consume less memory. Setting the + * connection to LISTEN is an irreversible process. + * + * @param pcb the original tcp_pcb + * @param backlog the incoming connections queue limit + * @return tcp_pcb used for listening, consumes less memory. + * + * @note The original tcp_pcb is freed. This function therefore has to be + * called like this: + * tpcb = tcp_listen(tpcb); + */ +struct tcp_pcb * +tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb_listen *lpcb; + + LWIP_UNUSED_ARG(backlog); + LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); + + /* already listening? */ + if (pcb->state == LISTEN) { + return pcb; + } + lpcb = memp_malloc(MEMP_TCP_PCB_LISTEN); + if (lpcb == NULL) { + return NULL; + } + lpcb->callback_arg = pcb->callback_arg; + lpcb->local_port = pcb->local_port; + lpcb->state = LISTEN; + lpcb->so_options = pcb->so_options; + lpcb->so_options |= SOF_ACCEPTCONN; + lpcb->ttl = pcb->ttl; + lpcb->tos = pcb->tos; + ip_addr_set(&lpcb->local_ip, &pcb->local_ip); + TCP_RMV(&tcp_bound_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); +#if LWIP_CALLBACK_API + lpcb->accept = tcp_accept_null; +#endif /* LWIP_CALLBACK_API */ +#if TCP_LISTEN_BACKLOG + lpcb->accepts_pending = 0; + lpcb->backlog = (backlog ? backlog : 1); +#endif /* TCP_LISTEN_BACKLOG */ + TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb); + return (struct tcp_pcb *)lpcb; +} + +/** + * Update the state that tracks the available window space to advertise. + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + return new_right_edge - pcb->rcv_ann_right_edge; + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + } else { + /* keep the right edge of window constant */ + pcb->rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; + } + return 0; + } +} + +/** + * This function should be called by the application when it has + * processed the data. The purpose is to advertise a larger window + * when the data has been processed. + * + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + int wnd_inflation; + + LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", + len <= 0xffff - pcb->rcv_wnd ); + + pcb->rcv_wnd += len; + if (pcb->rcv_wnd > TCP_WND) + pcb->rcv_wnd = TCP_WND; + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/2), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) + tcp_ack_now(pcb); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + +/** + * A nastly hack featuring 'goto' statements that allocates a + * new TCP local port. + * + * @return a new (free) local TCP port number + */ +static u16_t +tcp_new_port(void) +{ + struct tcp_pcb *pcb; +#ifndef TCP_LOCAL_PORT_RANGE_START +#define TCP_LOCAL_PORT_RANGE_START 4096 +#define TCP_LOCAL_PORT_RANGE_END 0x7fff +#endif + static u16_t port = TCP_LOCAL_PORT_RANGE_START; + + again: + if (++port > TCP_LOCAL_PORT_RANGE_END) { + port = TCP_LOCAL_PORT_RANGE_START; + } + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == port) { + goto again; + } + } + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == port) { + goto again; + } + } + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == port) { + goto again; + } + } + return port; +} + +/** + * Connects to another host. The function given as the "connected" + * argument will be called when the connection has been established. + * + * @param pcb the tcp_pcb used to establish the connection + * @param ipaddr the remote ip address to connect to + * @param port the remote tcp port to connect to + * @param connected callback function to call when connected (or on error) + * @return ERR_VAL if invalid arguments are given + * ERR_OK if connect request has been sent + * other err_t values if connect request couldn't be sent + */ +err_t +tcp_connect(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port, + err_t (* connected)(void *arg, struct tcp_pcb *tpcb, err_t err)) +{ + err_t ret; + u32_t iss; + + LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); + if (ipaddr != NULL) { + pcb->remote_ip = *ipaddr; + } else { + return ERR_VAL; + } + pcb->remote_port = port; + if (pcb->local_port == 0) { + pcb->local_port = tcp_new_port(); + } + iss = tcp_next_iss(); + pcb->rcv_nxt = 0; + pcb->snd_nxt = iss; + pcb->lastack = iss - 1; + pcb->snd_lbb = iss - 1; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->snd_wnd = TCP_WND; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + pcb->cwnd = 1; + pcb->ssthresh = pcb->mss * 10; + pcb->state = SYN_SENT; +#if LWIP_CALLBACK_API + pcb->connected = connected; +#endif /* LWIP_CALLBACK_API */ + TCP_RMV(&tcp_bound_pcbs, pcb); + TCP_REG(&tcp_active_pcbs, pcb); + + snmp_inc_tcpactiveopens(); + + ret = tcp_enqueue(pcb, NULL, 0, TCP_SYN, 0, TF_SEG_OPTS_MSS +#if LWIP_TCP_TIMESTAMPS + | TF_SEG_OPTS_TS +#endif + ); + if (ret == ERR_OK) { + tcp_output(pcb); + } + return ret; +} + +/** + * Called every 500 ms and implements the retransmission timer and the timer that + * removes PCBs that have been in TIME-WAIT for enough time. It also increments + * various timers such as the inactivity timer in each PCB. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + struct tcp_pcb *pcb, *pcb2, *prev; + u16_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + + ++tcp_ticks; + + /* Steps through all of the active PCBs. */ + prev = NULL; + pcb = tcp_active_pcbs; + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + + pcb_remove = 0; + pcb_reset = 0; + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + pcb->persist_cnt = 0; + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + pcb->persist_backoff++; + } + tcp_zero_window_probe(pcb); + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) + ++pcb->rtime; + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + /* Time for a retransmission. */ + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + pcb->ssthresh = eff_wnd >> 1; + if (pcb->ssthresh < pcb->mss) { + pcb->ssthresh = pcb->mss * 2; + } + pcb->cwnd = pcb->mss; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F + " ssthresh %"U16_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + } + } + + /* Check if KEEPALIVE should be sent */ + if((pcb->so_options & SOF_KEEPALIVE) && + ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT))) { +#if LWIP_TCP_KEEPALIVE + if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + (pcb->keep_cnt*pcb->keep_intvl)) + / TCP_SLOW_INTERVAL) +#else + if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + TCP_MAXIDLE) / TCP_SLOW_INTERVAL) +#endif /* LWIP_TCP_KEEPALIVE */ + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", + ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), + ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip))); + + ++pcb_remove; + ++pcb_reset; + } +#if LWIP_TCP_KEEPALIVE + else if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + pcb->keep_cnt_sent * pcb->keep_intvl) + / TCP_SLOW_INTERVAL) +#else + else if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEPINTVL_DEFAULT) + / TCP_SLOW_INTERVAL) +#endif /* LWIP_TCP_KEEPALIVE */ + { + tcp_keepalive(pcb); + pcb->keep_cnt_sent++; + } + } + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + } + + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT); + if (pcb_reset) { + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + } + + pcb2 = pcb->next; + memp_free(MEMP_TCP_PCB, pcb); + pcb = pcb2; + } else { + + /* We check if we should poll the connection. */ + ++pcb->polltmr; + if (pcb->polltmr >= pcb->pollinterval) { + pcb->polltmr = 0; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + TCP_EVENT_POLL(pcb, err); + if (err == ERR_OK) { + tcp_output(pcb); + } + } + + prev = pcb; + pcb = pcb->next; + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + pcb = tcp_tw_pcbs; + while (pcb != NULL) { + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + } + + + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + } + pcb2 = pcb->next; + memp_free(MEMP_TCP_PCB, pcb); + pcb = pcb2; + } else { + prev = pcb; + pcb = pcb->next; + } + } +} + +/** + * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously + * "refused" by upper layer (application) and sends delayed ACKs. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + struct tcp_pcb *pcb; + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + /* Notify again application with data previously received. */ + err_t err; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_fasttmr: notify kept packet\n")); + TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); + if (err == ERR_OK) { + pcb->refused_data = NULL; + } + } + + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + } +} + +/** + * Deallocates a list of TCP segments (tcp_seg structures). + * + * @param seg tcp_seg list of TCP segments to free + * @return the number of pbufs that were deallocated + */ +u8_t +tcp_segs_free(struct tcp_seg *seg) +{ + u8_t count = 0; + struct tcp_seg *next; + while (seg != NULL) { + next = seg->next; + count += tcp_seg_free(seg); + seg = next; + } + return count; +} + +/** + * Frees a TCP segment (tcp_seg structure). + * + * @param seg single tcp_seg to free + * @return the number of pbufs that were deallocated + */ +u8_t +tcp_seg_free(struct tcp_seg *seg) +{ + u8_t count = 0; + + if (seg != NULL) { + if (seg->p != NULL) { + count = pbuf_free(seg->p); +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + } + return count; +} + +/** + * Sets the priority of a connection. + * + * @param pcb the tcp_pcb to manipulate + * @param prio new priority + */ +void +tcp_setprio(struct tcp_pcb *pcb, u8_t prio) +{ + pcb->prio = prio; +} +#if TCP_QUEUE_OOSEQ + +/** + * Returns a copy of the given TCP segment. + * The pbuf and data are not copied, only the pointers + * + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + struct tcp_seg *cseg; + + cseg = memp_malloc(MEMP_TCP_SEG); + if (cseg == NULL) { + return NULL; + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + pbuf_ref(cseg->p); + return cseg; +} +#endif + +#if LWIP_CALLBACK_API +/** + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } else if (err == ERR_OK) { + return tcp_close(pcb); + } + return ERR_OK; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Kills the oldest active connection that has lower priority than prio. + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + u8_t mprio; + + + mprio = TCP_PRIO_MAX; + + /* We kill the oldest active connection that has lower priority than prio. */ + inactivity = 0; + inactive = NULL; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->prio <= prio && + pcb->prio <= mprio && + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + mprio = pcb->prio; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + inactive = NULL; + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Allocate a new tcp_pcb structure. + * + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + struct tcp_pcb *pcb; + u32_t iss; + + pcb = memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + /* Try to allocate a tcp_pcb again. */ + pcb = memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + /* Try to allocate a tcp_pcb again. */ + pcb = memp_malloc(MEMP_TCP_PCB); + if (pcb != NULL) { + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + memset(pcb, 0, sizeof(struct tcp_pcb)); + pcb->prio = TCP_PRIO_NORMAL; + pcb->snd_buf = TCP_SND_BUF; + pcb->snd_queuelen = 0; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->tos = 0; + pcb->ttl = TCP_TTL; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + pcb->sa = 0; + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + pcb->rtime = -1; + pcb->cwnd = 1; + iss = tcp_next_iss(); + pcb->snd_wl2 = iss; + pcb->snd_nxt = iss; + pcb->lastack = iss; + pcb->snd_lbb = iss; + pcb->tmr = tcp_ticks; + + pcb->polltmr = 0; + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + } + return pcb; +} + +/** + * Creates a new TCP protocol control block but doesn't place it on + * any of the TCP PCB lists. + * The pcb is not put on any list until binding using tcp_bind(). + * + * @internal: Maybe there should be a idle TCP PCB list where these + * PCBs are put on. Port reservation using tcp_bind() is implemented but + * allocated pcbs that are not bound can't be killed automatically if wanting + * to allocate a pcb with higher prio (@see tcp_kill_prio()) + * + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_new(void) +{ + return tcp_alloc(TCP_PRIO_NORMAL); +} + +/** + * Used to specify the argument that should be passed callback + * functions. + * + * @param pcb tcp_pcb to set the callback argument + * @param arg void pointer argument to pass to callback functions + */ +void +tcp_arg(struct tcp_pcb *pcb, void *arg) +{ + pcb->callback_arg = arg; +} +#if LWIP_CALLBACK_API + +/** + * Used to specify the function that should be called when a TCP + * connection receives data. + * + * @param pcb tcp_pcb to set the recv callback + * @param recv callback function to call for this pcb when data is received + */ +void +tcp_recv(struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)) +{ + pcb->recv = recv; +} + +/** + * Used to specify the function that should be called when TCP data + * has been successfully delivered to the remote host. + * + * @param pcb tcp_pcb to set the sent callback + * @param sent callback function to call for this pcb when data is successfully sent + */ +void +tcp_sent(struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, u16_t len)) +{ + pcb->sent = sent; +} + +/** + * Used to specify the function that should be called when a fatal error + * has occured on the connection. + * + * @param pcb tcp_pcb to set the err callback + * @param errf callback function to call for this pcb when a fatal error + * has occured on the connection + */ +void +tcp_err(struct tcp_pcb *pcb, + void (* errf)(void *arg, err_t err)) +{ + pcb->errf = errf; +} + +/** + * Used for specifying the function that should be called when a + * LISTENing connection has been connected to another host. + * + * @param pcb tcp_pcb to set the accept callback + * @param accept callback function to call for this pcb when LISTENing + * connection has been connected to another host + */ +void +tcp_accept(struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err)) +{ + pcb->accept = accept; +} +#endif /* LWIP_CALLBACK_API */ + + +/** + * Used to specify the function that should be called periodically + * from TCP. The interval is specified in terms of the TCP coarse + * timer interval, which is called twice a second. + * + */ +void +tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), u8_t interval) +{ +#if LWIP_CALLBACK_API + pcb->poll = poll; +#endif /* LWIP_CALLBACK_API */ + pcb->pollinterval = interval; +} + +/** + * Purges a TCP PCB. Removes any buffered data and frees the buffer memory + * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + if (pcb->state != CLOSED && + pcb->state != TIME_WAIT && + pcb->state != LISTEN) { + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); + +#if TCP_LISTEN_BACKLOG + if (pcb->state == SYN_RCVD) { + /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ + struct tcp_pcb_listen *lpcb; + LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", + tcp_listen_pcbs.listen_pcbs != NULL); + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((lpcb->local_port == pcb->local_port) && + (ip_addr_isany(&lpcb->local_ip) || + ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) { + /* port and address of the listen pcb match the timed-out pcb */ + LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", + lpcb->accepts_pending > 0); + lpcb->accepts_pending--; + break; + } + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + if (pcb->unsent != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); + } + if (pcb->unacked != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); + } +#if TCP_QUEUE_OOSEQ /* LW */ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; +#endif /* TCP_QUEUE_OOSEQ */ + tcp_segs_free(pcb->unsent); + tcp_segs_free(pcb->unacked); + pcb->unacked = pcb->unsent = NULL; + } +} + +/** + * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. + * + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + pcb->state != LISTEN && + pcb->flags & TF_ACK_DELAY) { + pcb->flags |= TF_ACK_NOW; + tcp_output(pcb); + } + + if (pcb->state != LISTEN) { + LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); + LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + +/** + * Calculates a new initial sequence number for new connections. + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + return iss; +} + +#if TCP_CALCULATE_EFF_SEND_MSS +/** + * Calcluates the effective send mss that can be used for a specific IP address + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr) +{ + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + if ((outif != NULL) && (outif->mtu != 0)) { + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_enqueue(), and don't support + * IP options + */ + sendmss = LWIP_MIN(sendmss, mss_s); + } + return sendmss; +} +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +const char* +tcp_debug_state_str(enum tcp_state s) +{ + return tcp_state_str[s]; +} + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +/** + * Print a tcp header for debugging purposes. + * + * @param tcphdr pointer to a struct tcp_hdr + */ +void +tcp_debug_print(struct tcp_hdr *tcphdr) +{ + LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(tcphdr->src), ntohs(tcphdr->dest))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", + ntohl(tcphdr->seqno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", + ntohl(tcphdr->ackno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", + TCPH_HDRLEN(tcphdr), + TCPH_FLAGS(tcphdr) >> 5 & 1, + TCPH_FLAGS(tcphdr) >> 4 & 1, + TCPH_FLAGS(tcphdr) >> 3 & 1, + TCPH_FLAGS(tcphdr) >> 2 & 1, + TCPH_FLAGS(tcphdr) >> 1 & 1, + TCPH_FLAGS(tcphdr) & 1, + ntohs(tcphdr->wnd))); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", + ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); +} + +/** + * Print a tcp state for debugging purposes. + * + * @param s enum tcp_state to print + */ +void +tcp_debug_print_state(enum tcp_state s) +{ + LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); +} + +/** + * Print tcp flags for debugging purposes. + * + * @param flags tcp flags, all active flags are printed + */ +void +tcp_debug_print_flags(u8_t flags) +{ + if (flags & TCP_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); + } + if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); + } + if (flags & TCP_RST) { + LWIP_DEBUGF(TCP_DEBUG, ("RST ")); + } + if (flags & TCP_PSH) { + LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); + } + if (flags & TCP_ACK) { + LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); + } + if (flags & TCP_URG) { + LWIP_DEBUGF(TCP_DEBUG, ("URG ")); + } + if (flags & TCP_ECE) { + LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); + } + if (flags & TCP_CWR) { + LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); + } + LWIP_DEBUGF(TCP_DEBUG, ("\n")); +} + +/** + * Print all tcp_pcbs in every list for debugging purposes. + */ +void +tcp_debug_print_pcbs(void) +{ + struct tcp_pcb *pcb; + LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } +} + +/** + * Check state consistency of the tcp_pcb lists. + */ +s16_t +tcp_pcbs_sane(void) +{ + struct tcp_pcb *pcb; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + } + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + } + return 1; +} +#endif /* TCP_DEBUG */ + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_in.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_in.c new file mode 100644 index 0000000..9c79898 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_in.c @@ -0,0 +1,1506 @@ +/** + * @file + * Transmission Control Protocol, incoming traffic + * + * The input processing functions of the TCP layer. + * + * These functions are generally called in the order (ip_input() ->) + * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" + +/* These variables are global to all functions involved in the input + processing of TCP segments. They are set by the tcp_input() + function. */ +static struct tcp_seg inseg; +static struct tcp_hdr *tcphdr; +static struct ip_hdr *iphdr; +static u32_t seqno, ackno; +static u8_t flags; +static u16_t tcplen; + +static u8_t recv_flags; +static struct pbuf *recv_data; + +struct tcp_pcb *tcp_input_pcb; + +/* Forward declarations. */ +static err_t tcp_process(struct tcp_pcb *pcb); +static void tcp_receive(struct tcp_pcb *pcb); +static void tcp_parseopt(struct tcp_pcb *pcb); + +static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); +static err_t tcp_timewait_input(struct tcp_pcb *pcb); + +/** + * The initial input processing of TCP. It verifies the TCP header, demultiplexes + * the segment between the PCBs and passes it on to tcp_process(), which implements + * the TCP finite state machine. This function is called by the IP layer (in + * ip_input()). + * + * @param p received TCP segment to process (p->payload pointing to the IP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + struct tcp_pcb *pcb, *prev; + struct tcp_pcb_listen *lpcb; + u8_t hdrlen; + err_t err; + + PERF_START; + + TCP_STATS_INC(tcp.recv); + snmp_inc_tcpinsegs(); + + iphdr = p->payload; + tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); + +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* remove header from payload */ + if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); + return; + } + + /* Don't even process incoming broadcasts/multicasts. */ + if (ip_addr_isbroadcast(&(iphdr->dest), inp) || + ip_addr_ismulticast(&(iphdr->dest))) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); + return; + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), + (struct ip_addr *)&(iphdr->dest), + IP_PROTO_TCP, p->tot_len) != 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", + inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), (struct ip_addr *)&(iphdr->dest), + IP_PROTO_TCP, p->tot_len))); +#if TCP_DEBUG + tcp_debug_print(tcphdr); +#endif /* TCP_DEBUG */ + TCP_STATS_INC(tcp.chkerr); + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); + return; + } +#endif + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + if(pbuf_header(p, -(hdrlen * 4))){ + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); + return; + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + tcphdr->dest = ntohs(tcphdr->dest); + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + tcphdr->wnd = ntohs(tcphdr->wnd); + + flags = TCPH_FLAGS(tcphdr); + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && + ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { + + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + prev->next = pcb->next; + pcb->next = tcp_active_pcbs; + tcp_active_pcbs = pcb; + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + } + prev = pcb; + } + + if (pcb == NULL) { + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) && + ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) { + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + pbuf_free(p); + return; + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((ip_addr_isany(&(lpcb->local_ip)) || + ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) && + lpcb->local_port == tcphdr->dest) { + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + pbuf_free(p); + return; + } + prev = (struct tcp_pcb *)lpcb; + } + } + +#if TCP_INPUT_DEBUG + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + /* The incoming segment belongs to a connection. */ +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + inseg.len = p->tot_len; + inseg.dataptr = p->payload; + inseg.p = p; + inseg.tcphdr = tcphdr; + + recv_data = NULL; + recv_flags = 0; + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err); + if (err == ERR_OK) { + pcb->refused_data = NULL; + } else { + /* drop incoming packets, because pcb is "full" */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); + return; + } + } + tcp_input_pcb = pcb; + err = tcp_process(pcb); + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + if (recv_flags & TF_RESET) { + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else if (recv_flags & TF_CLOSED) { + /* The connection has been closed and we will deallocate the + PCB. */ + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + err = ERR_OK; + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + TCP_EVENT_SENT(pcb, pcb->acked, err); + } + + if (recv_data != NULL) { + if(flags & TCP_PSH) { + recv_data->flags |= PBUF_FLAG_PUSH; + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { + pcb->refused_data = recv_data; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + TCP_EVENT_RECV(pcb, NULL, ERR_OK, err); + } + + tcp_input_pcb = NULL; + /* Try to send something out. */ + tcp_output(pcb); +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + } + } + tcp_input_pcb = NULL; + + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + { + pbuf_free(inseg.p); + inseg.p = NULL; + } + } else { + + /* If no matching PCB was found, send a TCP RST (reset) to the + sender. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); + tcp_rst(ackno, seqno + tcplen, + &(iphdr->dest), &(iphdr->src), + tcphdr->dest, tcphdr->src); + } + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); +} + +/** + * Called by tcp_input() when a segment arrives for a listening + * connection (from tcp_input()). + * + * @param pcb the tcp_pcb_listen for which a segment arrived + * @return ERR_OK if the segment was processed + * another err_t on error + * + * @note the return value is not (yet?) used in tcp_input() + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + struct tcp_pcb *npcb; + err_t rc; + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno + 1, seqno + tcplen, + &(iphdr->dest), &(iphdr->src), + tcphdr->dest, tcphdr->src); + } else if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); +#if TCP_LISTEN_BACKLOG + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ + ip_addr_set(&(npcb->local_ip), &(iphdr->dest)); + npcb->local_port = pcb->local_port; + ip_addr_set(&(npcb->remote_ip), &(iphdr->src)); + npcb->remote_port = tcphdr->src; + npcb->state = SYN_RCVD; + npcb->rcv_nxt = seqno + 1; + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + npcb->snd_wnd = tcphdr->wnd; + npcb->ssthresh = npcb->snd_wnd; + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + npcb->callback_arg = pcb->callback_arg; +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & (SOF_DEBUG|SOF_DONTROUTE|SOF_KEEPALIVE|SOF_OOBINLINE|SOF_LINGER); + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG(&tcp_active_pcbs, npcb); + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue(npcb, NULL, 0, TCP_SYN | TCP_ACK, 0, TF_SEG_OPTS_MSS +#if LWIP_TCP_TIMESTAMPS + /* and maybe include the TIMESTAMP option */ + | (npcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0) +#endif + ); + if (rc != ERR_OK) { + tcp_abandon(npcb, 0); + return rc; + } + return tcp_output(npcb); + } + return ERR_OK; +} + +/** + * Called by tcp_input() when a segment arrives for a connection in + * TIME_WAIT. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + return ERR_OK; + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcphdr->dest, tcphdr->src); + return ERR_OK; + } + } else if (flags & TCP_FIN) { + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + } + + if ((tcplen > 0)) { + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + return tcp_output(pcb); + } + return ERR_OK; +} + +/** + * Implements the TCP state machine. Called by tcp_input. In some + * states tcp_receive() is called to receive data. The tcp_seg + * argument will be freed by the caller (tcp_input()) unless the + * recv_data pointer in the pcb is set. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + struct tcp_seg *rseg; + u8_t acceptable = 0; + err_t err; + + err = ERR_OK; + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + if (ackno == pcb->snd_nxt) { + acceptable = 1; + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + } + } + + if (acceptable) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + pcb->flags &= ~TF_ACK_DELAY; + return ERR_RST; + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + return ERR_OK; + } + + /* Update the PCB (in)activity timer. */ + pcb->tmr = tcp_ticks; + pcb->keep_cnt_sent = 0; + + tcp_parseopt(pcb); + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + pcb->snd_buf++; + pcb->rcv_nxt = seqno + 1; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->lastack = ackno; + pcb->snd_wnd = tcphdr->wnd; + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + pcb->state = ESTABLISHED; + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + + pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + pcb->unacked = rseg->next; + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else { + pcb->rtime = 0; + pcb->nrtx = 0; + } + + tcp_seg_free(rseg); + + /* Call the user specified function to call when sucessfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + tcp_ack_now(pcb); + } + /* received ACK? possibly a half-open connection */ + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcphdr->dest, tcphdr->src); + } + break; + case SYN_RCVD: + if (flags & TCP_ACK) { + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + u16_t old_cwnd; + pcb->state = ESTABLISHED; + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + if (err != ERR_OK) { + /* If the accept function returns with an error, we abort + * the connection. */ + tcp_abort(pcb); + return ERR_ABRT; + } + old_cwnd = pcb->cwnd; + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + pcb->acked--; + } + + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + + if (recv_flags & TF_GOT_FIN) { + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + } + /* incorrect ACK number */ + else { + /* send RST */ + tcp_rst(ackno, seqno + tcplen, &(iphdr->dest), &(iphdr->src), + tcphdr->dest, tcphdr->src); + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { /* passive close */ + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + break; + case FIN_WAIT_1: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV(&tcp_active_pcbs, pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + tcp_ack_now(pcb); + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + case FIN_WAIT_2: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV(&tcp_active_pcbs, pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case CLOSING: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + TCP_RMV(&tcp_active_pcbs, pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case LAST_ACK: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + } + break; + default: + break; + } + return ERR_OK; +} + +#if TCP_QUEUE_OOSEQ +/** + * Insert segment into the list (segments covered with new one will be deleted) + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + /* received segment overlaps all following segments */ + tcp_segs_free(next); + next = NULL; + } + else { + /* delete some following segments + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + TCPH_FLAGS_SET(cseg->tcphdr, TCPH_FLAGS(cseg->tcphdr) | TCP_FIN); + } + old_seg = next; + next = next->next; + tcp_seg_free(old_seg); + } + if (next && + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + pbuf_realloc(cseg->p, cseg->len); + } + } + cseg->next = next; +} +#endif + +/** + * Called by tcp_process. Checks if the given segment is an ACK for outstanding + * data, and if so frees the memory of the buffered data. Next, is places the + * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment + * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until + * i it has been removed from the buffer. + * + * If the incoming segment constitutes an ACK for a segment that was used for RTT + * estimation, the RTT is estimated here as well. + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + struct tcp_seg *next; +#if TCP_QUEUE_OOSEQ + struct tcp_seg *prev, *cseg; +#endif + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; + + if (flags & TCP_ACK) { + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + pcb->snd_wnd = tcphdr->wnd; + pcb->snd_wl1 = seqno; + pcb->snd_wl2 = ackno; + if (pcb->snd_wnd > 0 && pcb->persist_backoff > 0) { + pcb->persist_backoff = 0; + } + LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); +#if TCP_WND_DEBUG + } else { + if (pcb->snd_wnd != tcphdr->wnd) { + LWIP_DEBUGF(TCP_WND_DEBUG, + ("tcp_receive: no window update lastack %"U32_F" ackno %" + U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", + pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); + } +#endif /* TCP_WND_DEBUG */ + } + + /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a + * duplicate ack if: + * 1) It doesn't ACK new data + * 2) length of received packet is zero (i.e. no payload) + * 3) the advertised window hasn't changed + * 4) There is outstanding unacknowledged data (retransmission timer running) + * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) + * + * If it passes all five, should process as a dupack: + * a) dupacks < 3: do nothing + * b) dupacks == 3: fast retransmit + * c) dupacks > 3: increase cwnd + * + * If it only passes 1-3, should reset dupack counter (and add to + * stats, which we don't do in lwIP) + * + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + pcb->acked = 0; + /* Clause 2 */ + if (tcplen == 0) { + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + /* Clause 4 */ + if (pcb->rtime >= 0) { + /* Clause 5 */ + if (pcb->lastack == ackno) { + found_dupack = 1; + if (pcb->dupacks + 1 > pcb->dupacks) + ++pcb->dupacks; + if (pcb->dupacks > 3) { + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + } else if (pcb->dupacks == 3) { + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + } + } + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + pcb->dupacks = 0; + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + pcb->flags &= ~TF_INFR; + pcb->cwnd = pcb->ssthresh; + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + /* Update the send buffer space. Diff between the two can never exceed 64K? */ + pcb->acked = (u16_t)(ackno - pcb->lastack); + + pcb->snd_buf += pcb->acked; + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + pcb->lastack = ackno; + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + if (pcb->cwnd < pcb->ssthresh) { + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); + } else { + u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + if (new_cwnd > pcb->cwnd) { + pcb->cwnd = new_cwnd; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); + } + } + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", + ackno, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno): 0, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowlegdes them. */ + while (pcb->unacked != NULL && + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked), ackno)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + pcb->unacked = pcb->unacked->next; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else + pcb->rtime = 0; + + pcb->polltmr = 0; + } else { + /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + } + + /* We go through the ->unsent list to see if any of the segments + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + pcb->unsent = pcb->unsent->next; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + } + /* End of ACK for new data processing. */ + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + pcb->sa += m; + if (m < 0) { + m = -m; + } + m = m - (pcb->sv >> 2); + pcb->sv += m; + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + } + } + + /* If the incoming segment contains data, we must process it + further. */ + if (tcplen > 0) { + /* This code basically does three things: + + +) If the incoming segment contains data that is the next + in-sequence data, this data is passed to the application. This + might involve trimming the first edge of the data. The rcv_nxt + variable and the advertised window are adjusted. + + +) If the incoming segment has data that is above the next + sequence number expected (->rcv_nxt), the segment is placed on + the ->ooseq queue. This is done by finding the appropriate + place in the ->ooseq queue (which is ordered by sequence + number) and trim the segment in both ends if needed. An + immediate ACK is sent to indicate that we received an + out-of-sequence segment. + + +) Finally, we check if the first segment on the ->ooseq queue + now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If + rcv_nxt > ooseq->seqno, we must trim the first edge of the + segment on ->ooseq before we adjust rcv_nxt. The data in the + segments that are now on sequence are chained onto the + incoming segment so that we only need to call the application + once. + */ + + /* First, we check if we must trim the first edge. We have to do + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + /* Trimming the first edge is done by pushing the payload + pointer in the pbuf downwards. This is somewhat tricky since + we do not want to discard the full contents of the pbuf up to + the new starting point of the data since we have to keep the + TCP header which is present in the first pbuf in the chain. + + What is done is really quite a nasty hack: the first pbuf in + the pbuf chain is pointed to by inseg.p. Since we need to be + able to deallocate the whole pbuf, we cannot change this + inseg.p pointer to point to any of the later pbufs in the + chain. Instead, we point the ->payload pointer in the first + pbuf to data in one of the later pbufs. We also set the + inseg.data pointer to point to the right place. This way, the + ->p pointer will still point to the first pbuf, but the + ->p->payload pointer will point to data in another pbuf. + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + p = inseg.p; + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + while (p->len < off) { + off -= p->len; + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + p->len = 0; + p = p->next; + } + if(pbuf_header(p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + /* KJM following line changed to use p->payload rather than inseg->p->payload + to fix bug #9076 */ + inseg.dataptr = p->payload; + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + } + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + + if (tcplen > pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U32_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue + * rcv_nxt + * . |--ooseq--| + * .==seg============|FIN + */ + while (pcb->ooseq != NULL) { + struct tcp_seg *old_ooseq = pcb->ooseq; + pcb->ooseq = pcb->ooseq->next; + tcp_seg_free(old_ooseq); + } + } + else { + struct tcp_seg* next = pcb->ooseq; + struct tcp_seg *old_seg; + /* rcv_nxt + * . |--ooseq--| + * .==seg============| + */ + while (next && + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg doesn't have FIN (already processed) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + TCPH_FLAGS_SET(inseg.tcphdr, + TCPH_FLAGS(inseg.tcphdr) | TCP_FIN); + tcplen = TCP_TCPLEN(&inseg); + } + old_seg = next; + next = next->next; + tcp_seg_free(old_seg); + } + /* rcv_nxt + * . |--ooseq--| + * .==seg============| + */ + if (next && + TCP_SEQ_GT(seqno + tcplen, + next->tcphdr->seqno)) { + /* FIN in inseg already handled by dropping whole ooseq queue */ + inseg.len = (u16_t)(pcb->ooseq->tcphdr->seqno - seqno); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == pcb->ooseq->tcphdr->seqno); + } + pcb->ooseq = next; + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + + tcp_update_rcv_ann_wnd(pcb); + + /* If there is data in the segment, we make preparations to + pass this up to the application. The ->recv_data variable + is used for holding the pbuf that goes to the + application. The code for reassembling out-of-sequence data + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + recv_data = inseg.p; + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + is now in sequence. */ + while (pcb->ooseq != NULL && + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + seqno = pcb->ooseq->tcphdr->seqno; + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + + tcp_update_rcv_ann_wnd(pcb); + + if (cseg->p->tot_len > 0) { + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + if (recv_data) { + pbuf_cat(recv_data, cseg->p); + } else { + recv_data = cseg->p; + } + cseg->p = NULL; + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + pcb->state = CLOSE_WAIT; + } + } + + pcb->ooseq = cseg->next; + tcp_seg_free(cseg); + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + pcb->ooseq = tcp_seg_copy(&inseg); + } else { + /* If the queue is not empty, we walk through the queue and + try to find a place where the sequence number of the + incoming segment is between the sequence numbers of the + previous and the next segment on the ->ooseq queue. That is + the place where we put the incoming segment. If needed, we + trim the second edges of the previous and the incoming + segment so that it will fit into the sequence. + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + for(next = pcb->ooseq; next != NULL; next = next->next) { + if (seqno == next->tcphdr->seqno) { + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (prev != NULL) { + prev->next = cseg; + } else { + pcb->ooseq = cseg; + } + tcp_oos_insert_segment(cseg, next); + } + break; + } else { + /* Either the lenghts are the same or the incoming + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + pcb->ooseq = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + pbuf_realloc(prev->p, prev->len); + } + prev->next = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + if (next->next != NULL) { + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + pbuf_realloc(next->p, next->len); + } + } + break; + } + } + prev = next; + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + } + } else { + /* The incoming segment is not withing the window. */ + tcp_send_empty_ack(pcb); + } + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + tcp_ack_now(pcb); + } + } +} + +/** + * Parses the options contained in the incoming segment. + * + * Called from tcp_listen_input() and tcp_process(). + * Currently, only the MSS option is supported! + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + u16_t c, max_c; + u16_t mss; + u8_t *opts, opt; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + opts = (u8_t *)tcphdr + TCP_HLEN; + + /* Parse the TCP MSS option, if present. */ + if(TCPH_HDRLEN(tcphdr) > 0x5) { + max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + for (c = 0; c < max_c; ) { + opt = opts[c]; + switch (opt) { + case 0x00: + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case 0x01: + /* NOP option. */ + ++c; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + case 0x02: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (opts[c + 2] << 8) | opts[c + 3]; + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + /* Advance to next option */ + c += 0x04; + break; +#if LWIP_TCP_TIMESTAMPS + case 0x08: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); + if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* TCP timestamp option with valid length */ + tsval = (opts[c+2]) | (opts[c+3] << 8) | + (opts[c+4] << 16) | (opts[c+5] << 24); + if (flags & TCP_SYN) { + pcb->ts_recent = ntohl(tsval); + pcb->flags |= TF_TIMESTAMP; + } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { + pcb->ts_recent = ntohl(tsval); + } + /* Advance to next option */ + c += 0x0A; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + if (opts[c + 1] == 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + /* If the length field is zero, the options are malformed + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + c += opts[c + 1]; + } + } + } +} + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_out.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_out.c new file mode 100644 index 0000000..3880704 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/tcp_out.c @@ -0,0 +1,1058 @@ +/** + * @file + * Transmission Control Protocol, outgoing traffic + * + * The output functions of TCP. + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" + +#include + +/* Forward declarations.*/ +static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); + +static struct tcp_hdr * +tcp_output_set_header(struct tcp_pcb *pcb, struct pbuf *p, int optlen, + u32_t seqno_be /* already in network byte order */) +{ + struct tcp_hdr *tcphdr = p->payload; + tcphdr->src = htons(pcb->local_port); + tcphdr->dest = htons(pcb->remote_port); + tcphdr->seqno = seqno_be; + tcphdr->ackno = htonl(pcb->rcv_nxt); + TCPH_FLAGS_SET(tcphdr, TCP_ACK); + tcphdr->wnd = htons(pcb->rcv_ann_wnd); + tcphdr->urgp = 0; + TCPH_HDRLEN_SET(tcphdr, (5 + optlen / 4)); + tcphdr->chksum = 0; + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + + return tcphdr; +} + +/** + * Called by tcp_close() to send a segment including flags but not data. + * + * @param pcb the tcp_pcb over which to send a segment + * @param flags the flags to set in the segment header + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags) +{ + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue(pcb, NULL, 0, flags, TCP_WRITE_FLAG_COPY, 0); +} + +/** + * Write data for sending (but does not send it immediately). + * + * It waits in the expectation of more data being sent soon (as + * it can send them more efficiently by combining them together). + * To prompt the system to send data now, call tcp_output() after + * calling tcp_write(). + * + * @param pcb Protocol control block of the TCP connection to enqueue data for. + * @param data pointer to the data to send + * @param len length (in bytes) of the data to send + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, + * @return ERR_OK if enqueued, another err_t on error + * + * @see tcp_write() + */ +err_t +tcp_write(struct tcp_pcb *pcb, const void *data, u16_t len, u8_t apiflags) +{ + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", (void *)pcb, + data, len, (u16_t)apiflags)); + /* connection is in valid state for data transmission? */ + if (pcb->state == ESTABLISHED || + pcb->state == CLOSE_WAIT || + pcb->state == SYN_SENT || + pcb->state == SYN_RCVD) { + if (len > 0) { +#if LWIP_TCP_TIMESTAMPS + return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, + pcb->flags & TF_TIMESTAMP ? TF_SEG_OPTS_TS : 0); +#else + return tcp_enqueue(pcb, (void *)data, len, 0, apiflags, 0); +#endif + } + return ERR_OK; + } else { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); + return ERR_CONN; + } +} + +/** + * Enqueue data and/or TCP options for transmission + * + * Called by tcp_connect(), tcp_listen_input(), tcp_send_ctrl() and tcp_write(). + * + * @param pcb Protocol control block for the TCP connection to enqueue data for. + * @param arg Pointer to the data to be enqueued for sending. + * @param len Data length in bytes + * @param flags tcp header flags to set in the outgoing segment + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, + * @param optflags options to include in segment later on (see definition of struct tcp_seg) + */ +err_t +tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len, + u8_t flags, u8_t apiflags, u8_t optflags) +{ + struct pbuf *p; + struct tcp_seg *seg, *useg, *queue; + u32_t seqno; + u16_t left, seglen; + void *ptr; + u16_t queuelen; + u8_t optlen; + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_enqueue(pcb=%p, arg=%p, len=%"U16_F", flags=%"X16_F", apiflags=%"U16_F")\n", + (void *)pcb, arg, len, (u16_t)flags, (u16_t)apiflags)); + LWIP_ERROR("tcp_enqueue: packet needs payload, options, or SYN/FIN (programmer violates API)", + ((len != 0) || (optflags != 0) || ((flags & (TCP_SYN | TCP_FIN)) != 0)), + return ERR_ARG;); + LWIP_ERROR("tcp_enqueue: len != 0 || arg == NULL (programmer violates API)", + ((len != 0) || (arg == NULL)), return ERR_ARG;); + + /* fail on too much data */ + if (len > pcb->snd_buf) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("tcp_enqueue: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", len, pcb->snd_buf)); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + left = len; + ptr = arg; + + optlen = LWIP_TCP_OPT_LENGTH(optflags); + + /* seqno will be the sequence number of the first segment enqueued + * by the call to this function. */ + seqno = pcb->snd_lbb; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + /* If total number of pbufs on the unsent/unacked queues exceeds the + * configured maximum, return an error */ + queuelen = pcb->snd_queuelen; + /* check for configured max queuelen and possible overflow */ + if ((queuelen >= TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("tcp_enqueue: too long queue %"U16_F" (max %"U16_F")\n", queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + if (queuelen != 0) { + LWIP_ASSERT("tcp_enqueue: pbufs on queue => at least one queue non-empty", + pcb->unacked != NULL || pcb->unsent != NULL); + } else { + LWIP_ASSERT("tcp_enqueue: no pbufs on queue => both queues empty", + pcb->unacked == NULL && pcb->unsent == NULL); + } + + /* First, break up the data into segments and tuck them together in + * the local "queue" variable. */ + useg = queue = seg = NULL; + seglen = 0; + while (queue == NULL || left > 0) { + /* The segment length (including options) should be at most the MSS */ + seglen = left > (pcb->mss - optlen) ? (pcb->mss - optlen) : left; + + /* Allocate memory for tcp_seg, and fill in fields. */ + seg = memp_malloc(MEMP_TCP_SEG); + if (seg == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("tcp_enqueue: could not allocate memory for tcp_seg\n")); + goto memerr; + } + seg->next = NULL; + seg->p = NULL; + + /* first segment of to-be-queued data? */ + if (queue == NULL) { + queue = seg; + } + /* subsequent segments of to-be-queued data */ + else { + /* Attach the segment to the end of the queued segments */ + LWIP_ASSERT("useg != NULL", useg != NULL); + useg->next = seg; + } + /* remember last segment of to-be-queued data for next iteration */ + useg = seg; + + /* If copy is set, memory should be allocated + * and data copied into pbuf, otherwise data comes from + * ROM or other static memory, and need not be copied. */ + if (apiflags & TCP_WRITE_FLAG_COPY) { + if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, seglen + optlen, PBUF_RAM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("tcp_enqueue : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold the complete seglen", + (seg->p->len >= seglen + optlen)); + queuelen += pbuf_clen(seg->p); + if (arg != NULL) { + MEMCPY((char *)seg->p->payload + optlen, ptr, seglen); + } + seg->dataptr = seg->p->payload; + } + /* do not copy data */ + else { + /* First, allocate a pbuf for the headers. */ + if ((seg->p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("tcp_enqueue: could not allocate memory for header pbuf\n")); + goto memerr; + } + queuelen += pbuf_clen(seg->p); + + /* Second, allocate a pbuf for holding the data. + * since the referenced data is available at least until it is sent out on the + * link (as it has to be ACKed by the remote party) we can safely use PBUF_ROM + * instead of PBUF_REF here. + */ + if (left > 0) { + if ((p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { + /* If allocation fails, we have to deallocate the header pbuf as well. */ + pbuf_free(seg->p); + seg->p = NULL; + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("tcp_enqueue: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } + ++queuelen; + /* reference the non-volatile payload data */ + p->payload = ptr; + seg->dataptr = ptr; + + /* Concatenate the headers and data pbufs together. */ + pbuf_cat(seg->p/*header*/, p/*data*/); + p = NULL; + } + } + + /* Now that there are more segments queued, we check again if the + length of the queue exceeds the configured maximum or overflows. */ + if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("tcp_enqueue: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN)); + goto memerr; + } + + seg->len = seglen; + + /* build TCP header */ + if (pbuf_header(seg->p, TCP_HLEN)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_enqueue: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + goto memerr; + } + seg->tcphdr = seg->p->payload; + seg->tcphdr->src = htons(pcb->local_port); + seg->tcphdr->dest = htons(pcb->remote_port); + seg->tcphdr->seqno = htonl(seqno); + seg->tcphdr->urgp = 0; + TCPH_FLAGS_SET(seg->tcphdr, flags); + /* don't fill in tcphdr->ackno and tcphdr->wnd until later */ + + seg->flags = optflags; + + /* Set the length of the header */ + TCPH_HDRLEN_SET(seg->tcphdr, (5 + optlen / 4)); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_enqueue: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + left -= seglen; + seqno += seglen; + ptr = (void *)((u8_t *)ptr + seglen); + } + + /* Now that the data to be enqueued has been broken up into TCP + segments in the queue variable, we add them to the end of the + pcb->unsent queue. */ + if (pcb->unsent == NULL) { + useg = NULL; + } + else { + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + } + /* { useg is last segment on the unsent queue, NULL if list is empty } */ + + /* If there is room in the last pbuf on the unsent queue, + chain the first pbuf on the queue together with that. */ + if (useg != NULL && + TCP_TCPLEN(useg) != 0 && + !(TCPH_FLAGS(useg->tcphdr) & (TCP_SYN | TCP_FIN)) && + (!(flags & (TCP_SYN | TCP_FIN)) || (flags == TCP_FIN)) && + /* fit within max seg size */ + (useg->len + queue->len <= pcb->mss) && + /* only concatenate segments with the same options */ + (useg->flags == queue->flags) && + /* segments are consecutive */ + (ntohl(useg->tcphdr->seqno) + useg->len == ntohl(queue->tcphdr->seqno)) ) { + /* Remove TCP header from first segment of our to-be-queued list */ + if(pbuf_header(queue->p, -(TCP_HLEN + optlen))) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + TCP_STATS_INC(tcp.err); + goto memerr; + } + if (queue->p->len == 0) { + /* free the first (header-only) pbuf if it is now empty (contained only headers) */ + struct pbuf *old_q = queue->p; + queue->p = queue->p->next; + old_q->next = NULL; + queuelen--; + pbuf_free(old_q); + } + if (flags & TCP_FIN) { + /* the new segment contains only FIN, no data -> put the FIN into the last segment */ + LWIP_ASSERT("FIN enqueued together with data", queue->p == NULL && queue->len == 0); + TCPH_SET_FLAG(useg->tcphdr, TCP_FIN); + } else { + LWIP_ASSERT("zero-length pbuf", (queue->p != NULL) && (queue->p->len > 0)); + pbuf_cat(useg->p, queue->p); + useg->len += queue->len; + useg->next = queue->next; + } + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("tcp_enqueue: chaining segments, new len %"U16_F"\n", useg->len)); + if (seg == queue) { + seg = useg; + seglen = useg->len; + } + memp_free(MEMP_TCP_SEG, queue); + } + else { + /* empty list */ + if (useg == NULL) { + /* initialize list with this segment */ + pcb->unsent = queue; + } + /* enqueue segment */ + else { + useg->next = queue; + } + } + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + ++len; + } + if (flags & TCP_FIN) { + pcb->flags |= TF_FIN; + } + pcb->snd_lbb += len; + + pcb->snd_buf -= len; + + /* update number of segments on the queues */ + pcb->snd_queuelen = queuelen; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_enqueue: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + /* Set the PSH flag in the last segment that we enqueued, but only + if the segment has data (indicated by seglen > 0). */ + if (seg != NULL && seglen > 0 && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { + TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); + } + + return ERR_OK; +memerr: + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + + if (queue != NULL) { + tcp_segs_free(queue); + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_enqueue: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_enqueue: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); + return ERR_MEM; +} + + +#if LWIP_TCP_TIMESTAMPS +/* Build a timestamp option (12 bytes long) at the specified options pointer) + * + * @param pcb tcp_pcb + * @param opts option pointer where to store the timestamp option + */ +static void +tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) +{ + /* Pad with two NOP options to make everything nicely aligned */ + opts[0] = htonl(0x0101080A); + opts[1] = htonl(sys_now()); + opts[2] = htonl(pcb->ts_recent); +} +#endif + +/** Send an ACK without data. + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + u8_t optlen = 0; + +#if LWIP_TCP_TIMESTAMPS + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_RAM); + if (p == NULL) { + p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen, PBUF_POOL); + } + + if (p == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + + tcphdr = tcp_output_set_header(pcb, p, optlen, htonl(pcb->snd_nxt)); + + /* NB. MSS option is only sent on SYNs, so ignore it here */ +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (pcb->flags & TF_TIMESTAMP) { + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), + IP_PROTO_TCP, p->tot_len); +#endif +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + + return ERR_OK; +} + +/** + * Find out what we can send and send it + * + * @param pcb Protocol control block for the TCP connection to send data + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg, *useg; + u32_t wnd, snd_nxt; +#if TCP_CWND_DEBUG + s16_t i = 0; +#endif /* TCP_CWND_DEBUG */ + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + return ERR_OK; + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + + seg = pcb->unsent; + + /* If the TF_ACK_NOW flag is set and no data will be sent (either + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + return tcp_send_empty_ack(pcb); + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + if (useg != NULL) { + for (; useg->next != NULL; useg = useg->next); + } + +#if TCP_OUTPUT_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", + (void*)pcb->unsent)); + } +#endif /* TCP_OUTPUT_DEBUG */ +#if TCP_CWND_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F + ", cwnd %"U16_F", wnd %"U32_F + ", seg == NULL, ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); + } else { + LWIP_DEBUGF(TCP_CWND_DEBUG, + ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F + ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); + /* Stop sending if the nagle algorithm would prevent it + * Don't stop: + * - if tcp_enqueue had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_enqueue/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + break; + } +#if TCP_CWND_DEBUG + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) + seg->len - + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + + if (pcb->state != SYN_SENT) { + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + tcp_output_segment(seg, pcb); + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + pcb->snd_nxt = snd_nxt; + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + seg->next = NULL; + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + pcb->unacked = seg; + useg = seg; + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))){ + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = (*cur_seg); + (*cur_seg) = seg; + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + useg = useg->next; + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + } + seg = pcb->unsent; + } + + if (seg != NULL && pcb->persist_backoff == 0 && + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > pcb->snd_wnd) { + /* prepare for persist timer */ + pcb->persist_cnt = 0; + pcb->persist_backoff = 1; + } + + pcb->flags &= ~TF_NAGLEMEMERR; + return ERR_OK; +} + +/** + * Called by tcp_output() to actually send a TCP segment over IP. + * + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + u16_t len; + struct netif *netif; + u32_t *opts; + + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + + /* advertise our receive window size in this TCP segment */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(seg->tcphdr + 1); + if (seg->flags & TF_SEG_OPTS_MSS) { + TCP_BUILD_MSS_OPTION(*opts); + opts += 1; + } +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (seg->flags & TF_SEG_OPTS_TS) { + tcp_build_timestamp_option(pcb, opts); + opts += 3; + } +#endif + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ip_addr_isany(&(pcb->local_ip))) { + netif = ip_route(&(pcb->remote_ip)); + if (netif == NULL) { + return; + } + ip_addr_set(&(pcb->local_ip), &(netif->ip_addr)); + } + + /* Set retransmission timer running if it is not currently enabled */ + if(pcb->rtime == -1) + pcb->rtime = 0; + + if (pcb->rttest == 0) { + pcb->rttest = tcp_ticks; + pcb->rtseq = ntohl(seg->tcphdr->seqno); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + + seg->p->len -= len; + seg->p->tot_len -= len; + + seg->p->payload = seg->tcphdr; + + seg->tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, + &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + +/** + * Send a TCP RESET packet (empty segment with RST flag set) either to + * abort a connection or to show that there is no matching local connection + * for a received segment. + * + * Called by tcp_abort() (to abort a local connection), tcp_input() (if no + * matching local pcb was found), tcp_listen_input() (if incoming segment + * has ACK flag set) and tcp_process() (received segment in the wrong state) + * + * Since a RST segment is in most cases not sent for an active connection, + * tcp_rst() has a number of arguments that are taken from a tcp_pcb for + * most other segment output functions. + * + * @param seqno the sequence number to use for the outgoing segment + * @param ackno the acknowledge number to use for the outgoing segment + * @param local_ip the local IP address to send the segment from + * @param remote_ip the remote IP address to send the segment to + * @param local_port the local TCP port to send the segment from + * @param remote_port the remote TCP port to send the segment to + */ +void +tcp_rst(u32_t seqno, u32_t ackno, + struct ip_addr *local_ip, struct ip_addr *remote_ip, + u16_t local_port, u16_t remote_port) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + if (p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = p->payload; + tcphdr->src = htons(local_port); + tcphdr->dest = htons(remote_port); + tcphdr->seqno = htonl(seqno); + tcphdr->ackno = htonl(ackno); + TCPH_FLAGS_SET(tcphdr, TCP_RST | TCP_ACK); + tcphdr->wnd = htons(TCP_WND); + tcphdr->urgp = 0; + TCPH_HDRLEN_SET(tcphdr, 5); + + tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + snmp_inc_tcpoutrsts(); + /* Send output with hardcoded TTL since we have no access to the pcb */ + ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + pbuf_free(p); + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + +/** + * Requeue all unacked segments for retransmission + * + * Called by tcp_slowtmr() for slow retransmission. + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + /* unacked queue is now empty */ + pcb->unacked = NULL; + + /* increment number of retransmissions */ + ++pcb->nrtx; + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission */ + tcp_output(pcb); +} + +/** + * Requeue the first unacked segment for retransmission + * + * Called by tcp_receive() for fast retramsmit. + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + pcb->unacked = seg->next; + + cur_seg = &(pcb->unsent); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = *cur_seg; + *cur_seg = seg; + + ++pcb->nrtx; + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + + +/** + * Handle retransmission after three dupacks received + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + /* This is fast retransmit. Retransmit the first unacked segment. */ + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) + pcb->ssthresh = pcb->snd_wnd / 2; + else + pcb->ssthresh = pcb->cwnd / 2; + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < 2*pcb->mss) { + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + pcb->flags |= TF_INFR; + } +} + + +/** + * Send keepalive packets to keep a connection active although + * no data is sent over it. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), + ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = tcp_output_set_header(pcb, p, 0, htonl(pcb->snd_nxt - 1)); + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + + +/** + * Send persist timer zero-window probes to keep a connection active + * when a window update is lost. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + struct tcp_seg *seg; + u16_t len; + u8_t is_fin; + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: sending ZERO WINDOW probe to %" + U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), + ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + + if(seg == NULL) + seg = pcb->unsent; + + if(seg == NULL) + return; + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + len = is_fin ? TCP_HLEN : TCP_HLEN + 1; + + p = pbuf_alloc(PBUF_IP, len, PBUF_RAM); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = tcp_output_set_header(pcb, p, 0, seg->tcphdr->seqno); + + if (is_fin) { + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + *((char *)p->payload + sizeof(struct tcp_hdr)) = *(char *)seg->dataptr; + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/udp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/udp.c new file mode 100644 index 0000000..31bbf8c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/core/udp.c @@ -0,0 +1,848 @@ +/** + * @file + * User Datagram Protocol module + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +/* udp.c + * + * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). + * + */ + +/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! + */ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/inet.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" +#include "lwip/dhcp.h" + +#include + +/* The list of UDP PCBs */ +/* exported in udp.h (was static) */ +struct udp_pcb *udp_pcbs; + +/** + * Process an incoming UDP datagram. + * + * Given an incoming UDP datagram (as a chain of pbufs) this function + * finds a corresponding UDP PCB and hands over the pbuf to the pcbs + * recv function. If no pcb is found or the datagram is incorrect, the + * pbuf is freed. + * + * @param p pbuf to be demultiplexed to a UDP PCB. + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + struct udp_hdr *udphdr; + struct udp_pcb *pcb, *prev; + struct udp_pcb *uncon_pcb; + struct ip_hdr *iphdr; + u16_t src, dest; + u8_t local_match; + u8_t broadcast; + + PERF_START; + + UDP_STATS_INC(udp.recv); + + iphdr = p->payload; + + /* Check minimum length (IP header + UDP header) + * and move payload pointer to UDP header */ + if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) { + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + + udphdr = (struct udp_hdr *)p->payload; + + /* is broadcast packet ? */ + broadcast = ip_addr_isbroadcast(&(iphdr->dest), inp); + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + dest = ntohs(udphdr->dest); + + udp_debug_print(udphdr); + + /* print the UDP source and destination */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest), + ip4_addr3(&iphdr->dest), ip4_addr4(&iphdr->dest), ntohs(udphdr->dest), + ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src), + ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src))); + +#if LWIP_DHCP + pcb = NULL; + /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by + the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */ + if (dest == DHCP_CLIENT_PORT) { + /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */ + if (src == DHCP_SERVER_PORT) { + if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { + /* accept the packe if + (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! + - inp->dhcp->pcb->remote == ANY or iphdr->src */ + if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) || + ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), &(iphdr->src)))) { + pcb = inp->dhcp->pcb; + } + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + local_match = 0; + uncon_pcb = NULL; + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + local_match = 0; + /* print the PCB local and remote address */ + LWIP_DEBUGF(UDP_DEBUG, + ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1(&pcb->local_ip), ip4_addr2(&pcb->local_ip), + ip4_addr3(&pcb->local_ip), ip4_addr4(&pcb->local_ip), pcb->local_port, + ip4_addr1(&pcb->remote_ip), ip4_addr2(&pcb->remote_ip), + ip4_addr3(&pcb->remote_ip), ip4_addr4(&pcb->remote_ip), pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if ((pcb->local_port == dest) && + ((!broadcast && ip_addr_isany(&pcb->local_ip)) || + ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)) || +#if LWIP_IGMP + ip_addr_ismulticast(&(iphdr->dest)) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && (pcb->so_options & SOF_BROADCAST)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast))) { +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + if ((uncon_pcb == NULL) && + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + (pcb->remote_port == src) && + (ip_addr_isany(&pcb->remote_ip) || + ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)))) { + /* the first fully matching PCB */ + if (prev != NULL) { + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + } +/* This part of code has been modified by ST's MCD Application Team */ +/* To use the UPnP responder for device discovery */ +#if LWIP_UPNP + if((local_match != 0) && (dest == 1900)) { + break; + } +#endif /* LWIP_UPNP */ + prev = pcb; + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + pcb = uncon_pcb; + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, &iphdr->dest)) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); +#if LWIP_UDPLITE + if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) { + /* Do the UDP Lite checksum */ +#if CHECKSUM_CHECK_UDP + u16_t chklen = ntohs(udphdr->len); + if (chklen < sizeof(struct udp_hdr)) { + if (chklen == 0) { + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet (See RFC 3828 chap. 3.1) */ + chklen = p->tot_len; + } else { + /* At least the UDP-Lite header must be covered by the + checksum! (Again, see RFC 3828 chap. 3.1) */ + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } + if (inet_chksum_pseudo_partial(p, (struct ip_addr *)&(iphdr->src), + (struct ip_addr *)&(iphdr->dest), + IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP Lite datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } +#endif /* CHECKSUM_CHECK_UDP */ + } else +#endif /* LWIP_UDPLITE */ + { +#if CHECKSUM_CHECK_UDP + if (udphdr->chksum != 0) { + if (inet_chksum_pseudo(p, (struct ip_addr *)&(iphdr->src), + (struct ip_addr *)&(iphdr->dest), + IP_PROTO_UDP, p->tot_len) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } +#endif /* CHECKSUM_CHECK_UDP */ + } + if(pbuf_header(p, -UDP_HLEN)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + if (pcb != NULL) { + snmp_inc_udpindatagrams(); + /* callback */ + if (pcb->recv != NULL) { + /* now the recv function is responsible for freeing p */ + pcb->recv(pcb->recv_arg, pcb, p, &iphdr->src, src); + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + goto end; + } + } else { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && + !ip_addr_ismulticast(&iphdr->dest)) { + /* move payload pointer back to ip header */ + pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); + LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); + icmp_dest_unreach(p, ICMP_DUR_PORT); + } +#endif /* LWIP_ICMP */ + UDP_STATS_INC(udp.proterr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpnoports(); + pbuf_free(p); + } + } else { + pbuf_free(p); + } +end: + PERF_STOP("udp_input"); +} + +/** + * Send data using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * + * The datagram will be sent to the current remote_ip & remote_port + * stored in pcb. If the pcb is not bound to a port, it will + * automatically be bound to a random port. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_MEM. Out of memory. + * - ERR_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. + * + * @see udp_disconnect() udp_sendto() + */ +err_t +udp_send(struct udp_pcb *pcb, struct pbuf *p) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); +} + +/** + * Send data to a specified address using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * If the PCB already has a remote address association, it will + * be restored after the data is sent. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + struct ip_addr *dst_ip, u16_t dst_port) +{ + struct netif *netif; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); + + /* find the outgoing network interface for this packet */ +#if LWIP_IGMP + netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); +#else + netif = ip_route(dst_ip); +#endif /* LWIP_IGMP */ + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to 0x%"X32_F"\n", dst_ip->addr)); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); +} + +/** + * Send data to a specified address using UDP. + * The netif used for sending can be specified. + * + * This function exists mainly for DHCP, to be able to send UDP packets + * on a netif that is still down. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * @param netif the netif used for sending. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif) +{ + struct udp_hdr *udphdr; + struct ip_addr *src_ip; + err_t err; + struct pbuf *q; /* q will be sent down the stack */ + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + } + /* chain header q in front of given pbuf p */ + pbuf_chain(q, p); + /* first pbuf q points to header pbuf */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = q->payload; + udphdr->src = htons(pcb->local_port); + udphdr->dest = htons(dst_port); + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + + /* PCB local address is IP_ANY_ADDR? */ + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + /* local_ip doesn't match, drop the packet */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + return ERR_VAL; + } + /* use UDP PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); + +#if LWIP_UDPLITE + /* UDP Lite protocol? */ + if (pcb->flags & UDP_FLAGS_UDPLITE) { + u16_t chklen, chklen_hdr; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); + /* set UDP message length in UDP header */ + chklen_hdr = chklen = pcb->chksum_len_tx; + if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { + if (chklen != 0) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); + } + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet. (See RFC 3828 chap. 3.1) + At least the UDP-Lite header must be covered by the + checksum, therefore, if chksum_len has an illegal + value, we generate the checksum over the complete + packet to be safe. */ + chklen_hdr = 0; + chklen = q->tot_len; + } + udphdr->len = htons(chklen_hdr); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, + IP_PROTO_UDPLITE, q->tot_len, chklen); + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) + udphdr->chksum = 0xffff; +#endif /* CHECKSUM_CHECK_UDP */ + /* output to IP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n")); +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = &(pcb->addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT*/ + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = NULL; +#endif /* LWIP_NETIF_HWADDRHINT*/ + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + udphdr->chksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff; + } +#endif /* CHECKSUM_CHECK_UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); + /* output to IP */ +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = &(pcb->addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT*/ + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); +#if LWIP_NETIF_HWADDRHINT + netif->addr_hint = NULL; +#endif /* LWIP_NETIF_HWADDRHINT*/ + } + /* TODO: must this be increased even if error occured? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + return err; +} + +/** + * Bind an UDP PCB. + * + * @param pcb UDP PCB to be bound with a local address ipaddr and port. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * @param port local UDP port to bind with. Use 0 to automatically bind + * to a random port between UDP_LOCAL_PORT_RANGE_START and + * UDP_LOCAL_PORT_RANGE_END. + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified ipaddr and port are already bound to by + * another UDP PCB. + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + u8_t rebind; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ip_addr_debug_print(UDP_DEBUG, ipaddr); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + } + + /* this code does not allow upper layer to share a UDP port for + listening to broadcast or multicast traffic (See SO_REUSE_ADDR and + SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR + combine with implementation of UDP PCB flags. Leon Woestenberg. */ +#ifdef LWIP_UDP_TODO + /* port matches that of PCB in list? */ + else + if ((ipcb->local_port == port) && + /* IP address matches, or one is IP_ADDR_ANY? */ + (ip_addr_isany(&(ipcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(ipcb->local_ip), ipaddr))) { + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + } +#endif + } + + ip_addr_set(&pcb->local_ip, ipaddr); + + /* no port specified? */ + if (port == 0) { +#ifndef UDP_LOCAL_PORT_RANGE_START +#define UDP_LOCAL_PORT_RANGE_START 4096 +#define UDP_LOCAL_PORT_RANGE_END 0x7fff +#endif + port = UDP_LOCAL_PORT_RANGE_START; + ipcb = udp_pcbs; + while ((ipcb != NULL) && (port != UDP_LOCAL_PORT_RANGE_END)) { + if (ipcb->local_port == port) { + /* port is already used by another udp_pcb */ + port++; + /* restart scanning all udp pcbs */ + ipcb = udp_pcbs; + } else + /* go on with next udp pcb */ + ipcb = ipcb->next; + } + if (ipcb != NULL) { + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + } + } + pcb->local_port = port; + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n", + (u16_t)((ntohl(pcb->local_ip.addr) >> 24) & 0xff), + (u16_t)((ntohl(pcb->local_ip.addr) >> 16) & 0xff), + (u16_t)((ntohl(pcb->local_ip.addr) >> 8) & 0xff), + (u16_t)(ntohl(pcb->local_ip.addr) & 0xff), pcb->local_port)); + return ERR_OK; +} +/** + * Connect an UDP PCB. + * + * This will associate the UDP PCB with the remote address. + * + * @param pcb UDP PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * @param port remote UDP port to connect with. + * + * @return lwIP error code + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * The udp pcb is bound to a random local port if not already bound. + * + * @see udp_disconnect() + */ +err_t +udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + + if (pcb->local_port == 0) { + err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) + return err; + } + + ip_addr_set(&pcb->remote_ip, ipaddr); + pcb->remote_port = port; + pcb->flags |= UDP_FLAGS_CONNECTED; +/** TODO: this functionality belongs in upper layers */ +#ifdef LWIP_UDP_TODO + /* Nail down local IP for netconn_addr()/getsockname() */ + if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) { + struct netif *netif; + + if ((netif = ip_route(&(pcb->remote_ip))) == NULL) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr)); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } + /** TODO: this will bind the udp pcb locally, to the interface which + is used to route output packets to the remote address. However, we + might want to accept incoming packets on any interface! */ + pcb->local_ip = netif->ip_addr; + } else if (ip_addr_isany(&pcb->remote_ip)) { + pcb->local_ip.addr = 0; + } +#endif + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n", + (u16_t)((ntohl(pcb->remote_ip.addr) >> 24) & 0xff), + (u16_t)((ntohl(pcb->remote_ip.addr) >> 16) & 0xff), + (u16_t)((ntohl(pcb->remote_ip.addr) >> 8) & 0xff), + (u16_t)(ntohl(pcb->remote_ip.addr) & 0xff), pcb->remote_port)); + + /* Insert UDP PCB into the list of active UDP PCBs. */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + if (pcb == ipcb) { + /* already on the list, just return */ + return ERR_OK; + } + } + /* PCB not yet on the list, add PCB now */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + return ERR_OK; +} + +/** + * Disconnect a UDP PCB + * + * @param pcb the udp pcb to disconnect. + */ +void +udp_disconnect(struct udp_pcb *pcb) +{ + /* reset remote address association */ + ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY); + pcb->remote_port = 0; + /* mark PCB as unconnected */ + pcb->flags &= ~UDP_FLAGS_CONNECTED; +} + +/** + * Set a receive callback for a UDP PCB + * + * This callback will be called when receiving a datagram for the pcb. + * + * @param pcb the pcb for wich to set the recv callback + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p, + struct ip_addr *addr, u16_t port), + void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Remove an UDP PCB. + * + * @param pcb UDP PCB to be removed. The PCB is removed from the list of + * UDP PCB's and the data structure is freed from memory. + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + /* pcb not 1st in list */ + } else + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + memp_free(MEMP_UDP_PCB, pcb); +} + +/** + * Create a UDP PCB. + * + * @return The UDP PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + struct udp_pcb *pcb; + pcb = memp_malloc(MEMP_UDP_PCB); + /* could allocate UDP PCB? */ + if (pcb != NULL) { + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + pcb->ttl = UDP_TTL; + } + return pcb; +} + +#if UDP_DEBUG +/** + * Print UDP header information for debug purposes. + * + * @param udphdr pointer to the udp header in memory. + */ +void +udp_debug_print(struct udp_hdr *udphdr) +{ + LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(udphdr->src), ntohs(udphdr->dest))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", + ntohs(udphdr->len), ntohs(udphdr->chksum))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* UDP_DEBUG */ + +#endif /* LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/autoip.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/autoip.h new file mode 100644 index 0000000..f711a61 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/autoip.h @@ -0,0 +1,116 @@ +/** + * @file + * + * AutoIP Automatic LinkLocal IP Configuration + **/ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +#ifndef __LWIP_AUTOIP_H__ +#define __LWIP_AUTOIP_H__ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* AutoIP Timing */ +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 + +struct autoip +{ + struct ip_addr llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ + u8_t state; /* current AutoIP state machine state */ + u8_t sent_num; /* sent number of probes or announces, dependent on state */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ + u8_t lastconflict; /* ticks until a conflict can be solved by defending */ + u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ +}; + + +/** Init srand, has to be called before entering mainloop */ +void autoip_init(void); + +/** Start AutoIP client */ +err_t autoip_start(struct netif *netif); + +/** Stop AutoIP client */ +err_t autoip_stop(struct netif *netif); + +/** Handles every incoming ARP Packet, called by etharp_arp_input */ +void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); + +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); + +/** Handle a possible change in the network configuration */ +void autoip_network_changed(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_AUTOIP */ + +#endif /* __LWIP_AUTOIP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/icmp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/icmp.h new file mode 100644 index 0000000..9e9faf6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/icmp.h @@ -0,0 +1,111 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is splitted to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) + +/** Combines type and code to an u16_t */ +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +void icmp_input(struct pbuf *p, struct netif *inp); +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +#endif /* LWIP_ICMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ICMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/igmp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/igmp.h new file mode 100644 index 0000000..86108ae --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/igmp.h @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +**/ + +#ifndef __LWIP_IGMP_H__ +#define __LWIP_IGMP_H__ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * IGMP constants + */ +#define IP_PROTO_IGMP 2 +#define IGMP_TTL 1 +#define IGMP_MINLEN 8 +#define ROUTER_ALERT 0x9404 +#define ROUTER_ALERTLEN 4 + +/* + * IGMP message types, including version number. + */ +#define IGMP_MEMB_QUERY 0x11 /* Membership query */ +#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ + +/* IGMP timer */ +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + +/* MAC Filter Actions */ +#define IGMP_DEL_MAC_FILTER 0 +#define IGMP_ADD_MAC_FILTER 1 + +/* Group membership states */ +#define IGMP_GROUP_NON_MEMBER 0 +#define IGMP_GROUP_DELAYING_MEMBER 1 +#define IGMP_GROUP_IDLE_MEMBER 2 + +/* + * IGMP packet format. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct igmp_msg { + PACK_STRUCT_FIELD(u8_t igmp_msgtype); + PACK_STRUCT_FIELD(u8_t igmp_maxresp); + PACK_STRUCT_FIELD(u16_t igmp_checksum); + PACK_STRUCT_FIELD(struct ip_addr igmp_group_address); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* + * now a group structure - there is + * a list of groups for each interface + * these should really be linked from the interface, but + * if we keep them separate we will not affect the lwip original code + * too much + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ + +struct igmp_group { + struct igmp_group *next; + struct netif *interface; + struct ip_addr group_address; + u8_t last_reporter_flag; /* signifies we were the last person to report */ + u8_t group_state; + u16_t timer; + u8_t use; /* counter of simultaneous uses */ +}; + + +/* Prototypes */ +void igmp_init(void); + +err_t igmp_start( struct netif *netif); + +err_t igmp_stop( struct netif *netif); + +void igmp_report_groups( struct netif *netif); + +struct igmp_group *igmp_lookfor_group( struct netif *ifp, struct ip_addr *addr); + +struct igmp_group *igmp_lookup_group( struct netif *ifp, struct ip_addr *addr); + +err_t igmp_remove_group( struct igmp_group *group); + +void igmp_input( struct pbuf *p, struct netif *inp, struct ip_addr *dest); + +err_t igmp_joingroup( struct ip_addr *ifaddr, struct ip_addr *groupaddr); + +err_t igmp_leavegroup( struct ip_addr *ifaddr, struct ip_addr *groupaddr); + +void igmp_tmr(void); + +void igmp_timeout( struct igmp_group *group); + +void igmp_start_timer( struct igmp_group *group, u8_t max_time); + +void igmp_stop_timer( struct igmp_group *group); + +void igmp_delaying_member( struct igmp_group *group, u8_t maxresp); + +err_t igmp_ip_output_if( struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, u8_t ttl, u8_t proto, struct netif *netif); + +void igmp_send( struct igmp_group *group, u8_t type); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IGMP */ + +#endif /* __LWIP_IGMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet.h new file mode 100644 index 0000000..6f259c7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* For compatibility with BSD code */ +struct in_addr { + u32_t s_addr; +}; + +#define INADDR_NONE ((u32_t)0xffffffffUL) /* 255.255.255.255 */ +#define INADDR_LOOPBACK ((u32_t)0x7f000001UL) /* 127.0.0.1 */ +#define INADDR_ANY ((u32_t)0x00000000UL) /* 0.0.0.0 */ +#define INADDR_BROADCAST ((u32_t)0xffffffffUL) /* 255.255.255.255 */ + +u32_t inet_addr(const char *cp); +int inet_aton(const char *cp, struct in_addr *addr); +char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */ + +#ifdef htons +#undef htons +#endif /* htons */ +#ifdef htonl +#undef htonl +#endif /* htonl */ +#ifdef ntohs +#undef ntohs +#endif /* ntohs */ +#ifdef ntohl +#undef ntohl +#endif /* ntohl */ + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#if BYTE_ORDER == BIG_ENDIAN +#define htons(x) (x) +#define ntohs(x) (x) +#define htonl(x) (x) +#define ntohl(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#ifdef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ +#define htons lwip_htons +#define ntohs lwip_ntohs +#define htonl lwip_htonl +#define ntohl lwip_ntohl +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ +#if LWIP_PLATFORM_BYTESWAP +#define htons(x) LWIP_PLATFORM_HTONS(x) +#define ntohs(x) LWIP_PLATFORM_HTONS(x) +#define htonl(x) LWIP_PLATFORM_HTONL(x) +#define ntohl(x) LWIP_PLATFORM_HTONL(x) +#else /* LWIP_PLATFORM_BYTESWAP */ +u16_t htons(u16_t x); +u16_t ntohs(u16_t x); +u32_t htonl(u32_t x); +u32_t ntohl(u32_t x); +#endif /* LWIP_PLATFORM_BYTESWAP */ + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet_chksum.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet_chksum.h new file mode 100644 index 0000000..ba64ce8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/inet_chksum.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_INET_CHKSUM_H__ +#define __LWIP_INET_CHKSUM_H__ + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *dataptr, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u16_t proto_len); +#if LWIP_UDPLITE +u16_t inet_chksum_pseudo_partial(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip.h new file mode 100644 index 0000000..fbf5a22 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip.h @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the function ip_output_if_opt() is only used with IGMP */ +#define IP_OPTIONS_SEND LWIP_IGMP + +#define IP_HLEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + /* ip addresses in network byte order */ \ + struct ip_addr local_ip; \ + struct ip_addr remote_ip; \ + /* Socket options */ \ + u16_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX. + */ +#define SOF_DEBUG (u16_t)0x0001U /* turn on debugging info recording */ +#define SOF_ACCEPTCONN (u16_t)0x0002U /* socket has had listen() */ +#define SOF_REUSEADDR (u16_t)0x0004U /* allow local address reuse */ +#define SOF_KEEPALIVE (u16_t)0x0008U /* keep connections alive */ +#define SOF_DONTROUTE (u16_t)0x0010U /* just use interface addresses */ +#define SOF_BROADCAST (u16_t)0x0020U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +#define SOF_USELOOPBACK (u16_t)0x0040U /* bypass hardware when possible */ +#define SOF_LINGER (u16_t)0x0080U /* linger on close if data present */ +#define SOF_OOBINLINE (u16_t)0x0100U /* leave received OOB data in line */ +#define SOF_REUSEPORT (u16_t)0x0200U /* allow local address & port reuse */ + + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_hdr { + /* version / header length / type of service */ + PACK_STRUCT_FIELD(u16_t _v_hl_tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + /* time to live / protocol*/ + PACK_STRUCT_FIELD(u16_t _ttl_proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FIELD(struct ip_addr src); + PACK_STRUCT_FIELD(struct ip_addr dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IPH_V(hdr) (ntohs((hdr)->_v_hl_tos) >> 12) +#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f) +#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) (ntohs((hdr)->_ttl_proto) >> 8) +#define IPH_PROTO(hdr) (ntohs((hdr)->_ttl_proto) & 0xff) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos))) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl_proto = (htons(IPH_PROTO(hdr) | ((u16_t)(ttl) << 8))) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_ttl_proto = (htons((proto) | (IPH_TTL(hdr) << 8))) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + +/** The interface that provided the packet for the current callback invocation. */ +extern struct netif *current_netif; +/** Header of the input packet currently being processed. */ +extern const struct ip_hdr *current_header; + +#define ip_init() /* Compatibility define, not init needed. */ +struct netif *ip_route(struct ip_addr *dest); +err_t ip_input(struct pbuf *p, struct netif *inp); +err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, + struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if IP_OPTIONS_SEND +err_t ip_output_if_opt(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +#endif /* IP_OPTIONS_SEND */ +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (current_netif) +/** Get the IP header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_header() (current_header) +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#else +#define ip_debug_print(p) +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_addr.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_addr.h new file mode 100644 index 0000000..2fcccc2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_addr.h @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" + +#include "lwip/inet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +struct netif; + +extern const struct ip_addr ip_addr_any; +extern const struct ip_addr ip_addr_broadcast; + +/** IP_ADDR_ can be used as a fixed IP address + * for the wildcard and the broadcast address + */ +#define IP_ADDR_ANY ((struct ip_addr *)&ip_addr_any) +#define IP_ADDR_BROADCAST ((struct ip_addr *)&ip_addr_broadcast) + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ + +#define IN_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSA_NSHIFT 24 +#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) +#define IN_CLASSA_MAX 128 + +#define IN_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSB_NSHIFT 16 +#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) +#define IN_CLASSB_MAX 65536 + +#define IN_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) +#define IN_CLASSC_NET 0xffffff00 +#define IN_CLASSC_NSHIFT 8 +#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) + +#define IN_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) +#define IN_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IN_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IN_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IN_MULTICAST(a) IN_CLASSD(a) + +#define IN_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) +#define IN_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) + +#define IN_LOOPBACKNET 127 /* official! */ + +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = htonl(((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff)) + +#define ip_addr_set(dest, src) (dest)->addr = \ + ((src) == NULL? 0:\ + (src)->addr) +/** + * Determine if two address are on the same network. + * + * @arg addr1 IP address 1 + * @arg addr2 IP address 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) +#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) + +#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == 0) + +u8_t ip_addr_isbroadcast(struct ip_addr *, struct netif *); + +#define ip_addr_ismulticast(addr1) (((addr1)->addr & ntohl(0xf0000000UL)) == ntohl(0xe0000000UL)) + +#define ip_addr_islinklocal(addr1) (((addr1)->addr & ntohl(0xffff0000UL)) == ntohl(0xa9fe0000UL)) + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ + ipaddr != NULL ? \ + (u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff : 0, \ + ipaddr != NULL ? \ + (u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff : 0, \ + ipaddr != NULL ? \ + (u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff : 0, \ + ipaddr != NULL ? \ + (u16_t)ntohl((ipaddr)->addr) & 0xff : 0)) + +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 24) & 0xff) +#define ip4_addr2(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 16) & 0xff) +#define ip4_addr3(ipaddr) ((u16_t)(ntohl((ipaddr)->addr) >> 8) & 0xff) +#define ip4_addr4(ipaddr) ((u16_t)(ntohl((ipaddr)->addr)) & 0xff) + +/** + * Same as inet_ntoa() but takes a struct ip_addr* + */ +#define ip_ntoa(addr) ((addr != NULL) ? inet_ntoa(*((struct in_addr*)(addr))) : "NULL") + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_frag.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_frag.h new file mode 100644 index 0000000..ee18728 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv4/lwip/ip_frag.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * + **/ + +#ifndef __LWIP_IP_FRAG_H__ +#define __LWIP_IP_FRAG_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_REASSEMBLY +/* The IP reassembly timer interval in milliseconds. */ +#define IP_TMR_INTERVAL 1000 + +/* IP reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip_reassdata { + struct ip_reassdata *next; + struct pbuf *p; + struct ip_hdr iphdr; + u16_t datagram_len; + u8_t flags; + u8_t timer; +}; + +void ip_reass_init(void); +void ip_reass_tmr(void); +struct pbuf * ip_reass(struct pbuf *p); +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +err_t ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest); +#endif /* IP_FRAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_FRAG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/icmp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/icmp.h new file mode 100644 index 0000000..87e9ffd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/icmp.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP6_DUR 1 +#define ICMP6_TE 3 +#define ICMP6_ECHO 128 /* echo */ +#define ICMP6_ER 129 /* echo reply */ + + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +void icmp_input(struct pbuf *p, struct netif *inp); + +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +struct icmp_echo_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u16_t id; + u16_t seqno; +}; + +struct icmp_dur_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +struct icmp_te_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ICMP */ + +#endif /* __LWIP_ICMP_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/inet.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/inet.h new file mode 100644 index 0000000..de1a0b6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/inet.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *data, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u32_t proto_len); + +u32_t inet_addr(const char *cp); +s8_t inet_aton(const char *cp, struct in_addr *addr); + +#ifndef _MACHINE_ENDIAN_H_ +#ifndef _NETINET_IN_H +#ifndef _LINUX_BYTEORDER_GENERIC_H +u16_t htons(u16_t n); +u16_t ntohs(u16_t n); +u32_t htonl(u32_t n); +u32_t ntohl(u32_t n); +#endif /* _LINUX_BYTEORDER_GENERIC_H */ +#endif /* _NETINET_IN_H */ +#endif /* _MACHINE_ENDIAN_H_ */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip.h new file mode 100644 index 0000000..a01cfc6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_HLEN 40 + +#define IP_PROTO_ICMP 58 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB struct ip_addr local_ip; \ + struct ip_addr remote_ip; \ + /* Socket options */ \ + u16_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl; \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + + +/* The IPv6 header. */ +struct ip_hdr { +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t tclass1:4, v:4; + u8_t flow1:4, tclass2:4; +#else + u8_t v:4, tclass1:4; + u8_t tclass2:8, flow1:4; +#endif + u16_t flow2; + u16_t len; /* payload length */ + u8_t nexthdr; /* next header */ + u8_t hoplim; /* hop limit (TTL) */ + struct ip_addr src, dest; /* source and destination IP addresses */ +}; + +#define IPH_PROTO(hdr) (iphdr->nexthdr) + +void ip_init(void); + +#include "lwip/netif.h" + +struct netif *ip_route(struct ip_addr *dest); + +void ip_input(struct pbuf *p, struct netif *inp); + +/* source and destination addresses in network byte order, please */ +err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto); + +err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto, + struct netif *netif); + +#define ip_current_netif() NULL +#define ip_current_header() NULL + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip_addr.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip_addr.h new file mode 100644 index 0000000..b2d8ae5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/ipv6/lwip/ip_addr.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_ADDR_ANY 0 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN + struct ip_addr { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \ + (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \ + (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \ + (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0) + +u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2, + struct ip_addr *mask); +u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2); +void ip_addr_set(struct ip_addr *dest, struct ip_addr *src); +u8_t ip_addr_isany(struct ip_addr *addr); + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \ + (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[0]) & 0xffff, \ + (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[1]) & 0xffff, \ + (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[2]) & 0xffff, \ + (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[3]) & 0xffff)); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api.h new file mode 100644 index 0000000..578d48f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api.h @@ -0,0 +1,227 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_API_H__ +#define __LWIP_API_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/netbuf.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define port_netconn_recv(conn , buf, ret) do{buf = netconn_recv(conn);}while(0); +#define port_netconn_accept(conn , newconn, ret) do{newconn = netconn_accept(conn);}while(0); + +/* Throughout this file, IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for netconn_write */ +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY 0x01 +#define NETCONN_MORE 0x02 + +/* Helpers to process several netconn_types by the same code */ +#define NETCONNTYPE_GROUP(t) (t&0xF0) +#define NETCONNTYPE_DATAGRAM(t) (t&0xE0) + +enum netconn_type { + NETCONN_INVALID = 0, + /* NETCONN_TCP Group */ + NETCONN_TCP = 0x10, + /* NETCONN_UDP Group */ + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM= 0x22, + /* NETCONN_RAW Group */ + NETCONN_RAW = 0x40 +}; + +enum netconn_state { + NETCONN_NONE, + NETCONN_WRITE, + NETCONN_LISTEN, + NETCONN_CONNECT, + NETCONN_CLOSE +}; + +enum netconn_evt { + NETCONN_EVT_RCVPLUS, + NETCONN_EVT_RCVMINUS, + NETCONN_EVT_SENDPLUS, + NETCONN_EVT_SENDMINUS +}; + +#if LWIP_IGMP +enum netconn_igmp { + NETCONN_JOIN, + NETCONN_LEAVE +}; +#endif /* LWIP_IGMP */ + +/* forward-declare some structs to avoid to include their headers */ +struct ip_pcb; +struct tcp_pcb; +struct udp_pcb; +struct raw_pcb; +struct netconn; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); + +/** A netconn descriptor */ +struct netconn { + /** type of the netconn (TCP, UDP or RAW) */ + enum netconn_type type; + /** current state of the netconn */ + enum netconn_state state; + /** the lwIP internal protocol control block */ + union { + struct ip_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + /** the last error this netconn had */ + err_t err; + /** sem that is used to synchroneously execute functions in the core context */ + sys_sem_t op_completed; + /** mbox where received packets are stored until they are fetched + by the netconn application thread (can grow quite big) */ + sys_mbox_t recvmbox; + /** mbox where new connections are stored until processed + by the application thread */ + sys_mbox_t acceptmbox; + /** only used for socket layer */ + int socket; +#if LWIP_SO_RCVTIMEO + /** timeout to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + /** maximum amount of bytes queued in recvmbox */ + int recv_bufsize; +#endif /* LWIP_SO_RCVBUF */ + s16_t recv_avail; +#if LWIP_TCP + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. */ + struct api_msg_msg *write_msg; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores how much is already sent. */ + size_t write_offset; +#if LWIP_TCPIP_CORE_LOCKING + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ + u8_t write_delayed; +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_TCP */ + /** A callback function that is informed about events for this netconn */ + netconn_callback callback; +}; + +/* Register an Network connection event */ +#define API_EVENT(c,e,l) if (c->callback) { \ + (*c->callback)(c, e, l); \ + } + +/* Network connection functions: */ +#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) +#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) +struct +netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, + netconn_callback callback); +err_t netconn_delete (struct netconn *conn); +/** Get the type of a netconn (as enum netconn_type). */ +#define netconn_type(conn) (conn->type) + +err_t netconn_getaddr (struct netconn *conn, + struct ip_addr *addr, + u16_t *port, + u8_t local); +#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) +#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) + +err_t netconn_bind (struct netconn *conn, + struct ip_addr *addr, + u16_t port); +err_t netconn_connect (struct netconn *conn, + struct ip_addr *addr, + u16_t port); +err_t netconn_disconnect (struct netconn *conn); +err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); +#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) +struct netconn * netconn_accept (struct netconn *conn); +struct netbuf * netconn_recv (struct netconn *conn); +err_t netconn_sendto (struct netconn *conn, + struct netbuf *buf, struct ip_addr *addr, u16_t port); +err_t netconn_send (struct netconn *conn, + struct netbuf *buf); +err_t netconn_write (struct netconn *conn, + const void *dataptr, size_t size, + u8_t apiflags); +err_t netconn_close (struct netconn *conn); + +err_t netconn_abort(struct netconn *conn); + +#if LWIP_IGMP +err_t netconn_join_leave_group (struct netconn *conn, + struct ip_addr *multiaddr, + struct ip_addr *interface, + enum netconn_igmp join_or_leave); +#endif /* LWIP_IGMP */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, struct ip_addr *addr); +#endif /* LWIP_DNS */ + +#define netconn_err(conn) ((conn)->err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api_msg.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api_msg.h new file mode 100644 index 0000000..a1e1924 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/api_msg.h @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_API_MSG_H__ +#define __LWIP_API_MSG_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ +/** This struct includes everything that is necessary to execute a function + for a netconn in another thread context (mainly used to process netconns + in the tcpip_thread context to be thread safe). */ +struct api_msg_msg { + /** The netconn which to process - always needed: it includes the semaphore + which is used to block the application thread until the function finished. */ + struct netconn *conn; + /** Depending on the executed function, one of these union members is used */ + union { + /** used for do_send */ + struct netbuf *b; + /** used for do_newconn */ + struct { + u8_t proto; + } n; + /** used for do_bind and do_connect */ + struct { + struct ip_addr *ipaddr; + u16_t port; + } bc; + /** used for do_getaddr */ + struct { + struct ip_addr *ipaddr; + u16_t *port; + u8_t local; + } ad; + /** used for do_write */ + struct { + const void *dataptr; + size_t len; + u8_t apiflags; + } w; + /** used for do_recv */ + struct { + u16_t len; + } r; +#if LWIP_IGMP + /** used for do_join_leave_group */ + struct { + struct ip_addr *multiaddr; + struct ip_addr *interface; + enum netconn_igmp join_or_leave; + } jl; +#endif /* LWIP_IGMP */ +#if TCP_LISTEN_BACKLOG + struct { + u8_t backlog; + } lb; +#endif /* TCP_LISTEN_BACKLOG */ + } msg; +}; + +/** This struct contains a function to execute in another thread context and + a struct api_msg_msg that serves as an argument for this function. + This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ +struct api_msg { + /** function to execute in tcpip_thread context */ + void (* function)(struct api_msg_msg *msg); + /** arguments for this function */ + struct api_msg_msg msg; +}; + +#if LWIP_DNS +/** As do_gethostbyname requires more arguments but doesn't require a netconn, + it has its own struct (to avoid struct api_msg getting bigger than necessary). + do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg + (see netconn_gethostbyname). */ +struct dns_api_msg { + /** Hostname to query or dotted IP address string */ + const char *name; + /** Rhe resolved address is stored here */ + struct ip_addr *addr; + /** This semaphore is posted when the name is resolved, the application thread + should wait on it. */ + sys_sem_t sem; + /** Errors are given back here */ + err_t *err; +}; +#endif /* LWIP_DNS */ + +void do_newconn ( struct api_msg_msg *msg); +void do_delconn ( struct api_msg_msg *msg); +void do_bind ( struct api_msg_msg *msg); +void do_connect ( struct api_msg_msg *msg); +void do_disconnect ( struct api_msg_msg *msg); +void do_listen ( struct api_msg_msg *msg); +void do_send ( struct api_msg_msg *msg); +void do_recv ( struct api_msg_msg *msg); +void do_write ( struct api_msg_msg *msg); +void do_getaddr ( struct api_msg_msg *msg); +void do_close ( struct api_msg_msg *msg); +#if LWIP_IGMP +void do_join_leave_group( struct api_msg_msg *msg); +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +void do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + +struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); +void netconn_free(struct netconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_MSG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/arch.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/arch.h new file mode 100644 index 0000000..19d5734 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/arch.h @@ -0,0 +1,233 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ARCH_H__ +#define __LWIP_ARCH_H__ + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#include "arch/cc.h" + +/** Temporary: define format string for size_t if not defined in cc.h */ +#ifndef SZT_F +#define SZT_F U32_F +#endif /* SZT_F */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PACK_STRUCT_BEGIN +#define PACK_STRUCT_BEGIN +#endif /* PACK_STRUCT_BEGIN */ + +#ifndef PACK_STRUCT_END +#define PACK_STRUCT_END +#endif /* PACK_STRUCT_END */ + +#ifndef PACK_STRUCT_FIELD +#define PACK_STRUCT_FIELD(x) x +#endif /* PACK_STRUCT_FIELD */ + + +#ifndef LWIP_UNUSED_ARG +#define LWIP_UNUSED_ARG(x) (void)x +#endif /* LWIP_UNUSED_ARG */ + + +#ifdef LWIP_PROVIDE_ERRNO + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + + +#define ENSROK 0 /* DNS server returned answer with no data */ +#define ENSRNODATA 160 /* DNS server returned answer with no data */ +#define ENSRFORMERR 161 /* DNS server claims query was misformatted */ +#define ENSRSERVFAIL 162 /* DNS server returned general failure */ +#define ENSRNOTFOUND 163 /* Domain name not found */ +#define ENSRNOTIMP 164 /* DNS server does not implement requested operation */ +#define ENSRREFUSED 165 /* DNS server refused query */ +#define ENSRBADQUERY 166 /* Misformatted DNS query */ +#define ENSRBADNAME 167 /* Misformatted domain name */ +#define ENSRBADFAMILY 168 /* Unsupported address family */ +#define ENSRBADRESP 169 /* Misformatted DNS reply */ +#define ENSRCONNREFUSED 170 /* Could not contact DNS servers */ +#define ENSRTIMEOUT 171 /* Timeout while contacting DNS servers */ +#define ENSROF 172 /* End of file */ +#define ENSRFILE 173 /* Error reading file */ +#define ENSRNOMEM 174 /* Out of memory */ +#define ENSRDESTRUCTION 175 /* Application terminated lookup */ +#define ENSRQUERYDOMAINTOOLONG 176 /* Domain name is too long */ +#define ENSRCNAMELOOP 177 /* Domain name is too long */ + +#ifndef errno +extern int errno; +#endif + +#endif /* LWIP_PROVIDE_ERRNO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ARCH_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/debug.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/debug.h new file mode 100644 index 0000000..f9eff83 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/debug.h @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEBUG_H__ +#define __LWIP_DEBUG_H__ + +#include "lwip/arch.h" +#include + +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + +#ifndef LWIP_NOASSERT +#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ + LWIP_PLATFORM_ASSERT(message); } while(0) +#else /* LWIP_NOASSERT */ +#define LWIP_ASSERT(message, assertion) +#endif /* LWIP_NOASSERT */ + +/** if "expression" isn't true, then print "message" and execute "handler" expression */ +#ifndef LWIP_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + LWIP_PLATFORM_ASSERT(message); handler;}} while(0) +#endif /* LWIP_ERROR */ + +#ifdef LWIP_DEBUG +/** print debug message only if debug message type is enabled... + * AND is of correct type AND is at least LWIP_DBG_LEVEL + */ + + +#define LWIP_PLATFORM_DIAG printf +#define LWIP_DEBUGF(debug, message) do { \ + if ( \ + ((debug) & LWIP_DBG_ON) && \ + ((debug) & LWIP_DBG_TYPES_ON) && \ + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + LWIP_PLATFORM_DIAG message; \ + if ((debug) & LWIP_DBG_HALT) { \ + while(1); \ + } \ + } \ + } while(0) + +#else /* LWIP_DEBUG */ +#define LWIP_DEBUGF(debug, message) +#endif /* LWIP_DEBUG */ + +#endif /* __LWIP_DEBUG_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/def.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/def.h new file mode 100644 index 0000000..0e84852 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/def.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEF_H__ +#define __LWIP_DEF_H__ + +/* this might define NULL already */ +#include "lwip/arch.h" + +#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) +#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) + +#ifndef NULL +#define NULL ((void *)0) +#endif + + +#endif /* __LWIP_DEF_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dhcp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dhcp.h new file mode 100644 index 0000000..f93fcd0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dhcp.h @@ -0,0 +1,247 @@ +/** @file + **/ + +#ifndef __LWIP_DHCP_H__ +#define __LWIP_DHCP_H__ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** period (in seconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_SECS 60 +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +#define DHCP_FINE_TIMER_MSECS 500 + +struct dhcp +{ + /** transaction identifier of last sent request */ + u32_t xid; + /** our connection to the DHCP server */ + struct udp_pcb *pcb; + /** incoming msg */ + struct dhcp_msg *msg_in; + /** incoming msg options */ + void *options_in; + /** ingoing msg options length */ + u16_t options_in_len; + /** current DHCP state machine state */ + u8_t state; + /** retries of current request */ + u8_t tries; + + struct pbuf *p_out; /* pbuf of outcoming msg */ + struct dhcp_msg *msg_out; /* outgoing msg */ + u16_t options_out_len; /* outgoing msg options length */ + u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */ + struct ip_addr offered_ip_addr; + struct ip_addr offered_sn_mask; + struct ip_addr offered_gw_addr; + struct ip_addr offered_bc_addr; +#define DHCP_MAX_DNS 2 + u32_t dns_count; /* actual number of DNS servers obtained */ + struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */ + + u32_t offered_t0_lease; /* lease period (in seconds) */ + u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ +#if LWIP_DHCP_AUTOIP_COOP + u8_t autoip_coop_state; +#endif +/** Patch #1308 + * TODO: See dhcp.c "TODO"s + */ +#if 0 + struct ip_addr offered_si_addr; + u8_t *boot_file_name; +#endif +}; + +/* MUST be compiled with "pack structs" or equivalent! */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FIELD(u8_t op); + PACK_STRUCT_FIELD(u8_t htype); + PACK_STRUCT_FIELD(u8_t hlen); + PACK_STRUCT_FIELD(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(struct ip_addr ciaddr); + PACK_STRUCT_FIELD(struct ip_addr yiaddr); + PACK_STRUCT_FIELD(struct ip_addr siaddr); + PACK_STRUCT_FIELD(struct ip_addr giaddr); +#define DHCP_CHADDR_LEN 16U + PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); +#define DHCP_SNAME_LEN 64U + PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); +#define DHCP_FILE_LEN 128U + PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** start DHCP configuration */ +err_t dhcp_start(struct netif *netif); +/** enforce early lease renewal (not needed normally)*/ +err_t dhcp_renew(struct netif *netif); +/** release the DHCP lease, usually called before dhcp_stop()*/ +err_t dhcp_release(struct netif *netif); +err_t dhcp_release_unicast(struct netif *netif); +/** stop DHCP configuration */ +void dhcp_stop(struct netif *netif); +/** inform server of our manual IP address */ +void dhcp_inform(struct netif *netif); +/** Handle a possible change in the network configuration */ +void dhcp_network_changed(struct netif *netif); + +/** if enabled, check whether the offered IP address is not in use, using ARP */ +#if DHCP_DOES_ARP_CHECK +void dhcp_arp_reply(struct netif *netif, struct ip_addr *addr); +#endif + +/** to be called every minute */ +void dhcp_coarse_tmr(void); +/** to be called every half second */ +void dhcp_fine_tmr(void); + +/** DHCP message item offsets and length */ +#define DHCP_MSG_OFS (UDP_DATA_OFS) + #define DHCP_OP_OFS (DHCP_MSG_OFS + 0) + #define DHCP_HTYPE_OFS (DHCP_MSG_OFS + 1) + #define DHCP_HLEN_OFS (DHCP_MSG_OFS + 2) + #define DHCP_HOPS_OFS (DHCP_MSG_OFS + 3) + #define DHCP_XID_OFS (DHCP_MSG_OFS + 4) + #define DHCP_SECS_OFS (DHCP_MSG_OFS + 8) + #define DHCP_FLAGS_OFS (DHCP_MSG_OFS + 10) + #define DHCP_CIADDR_OFS (DHCP_MSG_OFS + 12) + #define DHCP_YIADDR_OFS (DHCP_MSG_OFS + 16) + #define DHCP_SIADDR_OFS (DHCP_MSG_OFS + 20) + #define DHCP_GIADDR_OFS (DHCP_MSG_OFS + 24) + #define DHCP_CHADDR_OFS (DHCP_MSG_OFS + 28) + #define DHCP_SNAME_OFS (DHCP_MSG_OFS + 44) + #define DHCP_FILE_OFS (DHCP_MSG_OFS + 108) +#define DHCP_MSG_LEN 236 + +#define DHCP_COOKIE_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN) +#define DHCP_OPTIONS_OFS (DHCP_MSG_OFS + DHCP_MSG_LEN + 4) + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +/** DHCP client states */ +#define DHCP_REQUESTING 1 +#define DHCP_INIT 2 +#define DHCP_REBOOTING 3 +#define DHCP_REBINDING 4 +#define DHCP_RENEWING 5 +#define DHCP_SELECTING 6 +#define DHCP_INFORMING 7 +#define DHCP_CHECKING 8 +#define DHCP_PERMANENT 9 +#define DHCP_BOUND 10 +#define DHCP_RELEASING 11 +#define DHCP_BACKING_OFF 12 +#define DHCP_OFF 13 + +/** AUTOIP cooperatation flags */ +#define DHCP_AUTOIP_COOP_STATE_OFF 0 +#define DHCP_AUTOIP_COOP_STATE_ON 1 + +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +#define DHCP_HTYPE_ETH 1 + +#define DHCP_HLEN_ETH 6 + +#define DHCP_BROADCAST_FLAG 15 +#define DHCP_BROADCAST_MASK (1 << DHCP_FLAG_BROADCAST) + +/** BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_END 255 + +/** DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/** possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DHCP */ + +#endif /*__LWIP_DHCP_H__*/ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dns.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dns.h new file mode 100644 index 0000000..be91d49 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/dns.h @@ -0,0 +1,97 @@ +/** + * lwip DNS resolver header file. + + * Author: Jim Pettinato + * April 2007 + + * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **/ + +#ifndef __LWIP_DNS_H__ +#define __LWIP_DNS_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +/** DNS timer period */ +#define DNS_TMR_INTERVAL 1000 + +/** DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ + +/** DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +/** Callback which is invoked when a hostname is found. + * A function of this type must be implemented by the application using the DNS resolver. + * @param name pointer to the name that was looked up. + * @param ipaddr pointer to a struct ip_addr containing the IP address of the hostname, + * or NULL if the name could not be found (or on any other error). + * @param callback_arg a user-specified callback argument passed to dns_gethostbyname +*/ +typedef void (*dns_found_callback)(const char *name, struct ip_addr *ipaddr, void *callback_arg); + + +void dns_init(void); + +void dns_tmr(void); + +void dns_setserver(u8_t numdns, struct ip_addr *dnsserver); + +struct ip_addr dns_getserver(u8_t numdns); + +err_t dns_gethostbyname(const char *hostname, struct ip_addr *addr, + dns_found_callback found, void *callback_arg); + +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehost(const char *hostname, const struct ip_addr *addr); +err_t dns_local_addhost(const char *hostname, const struct ip_addr *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#endif /* LWIP_DNS */ + +#endif /* __LWIP_DNS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/err.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/err.h new file mode 100644 index 0000000..2cd5819 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/err.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ERR_H__ +#define __LWIP_ERR_H__ + +#include "lwip/opt.h" +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define LWIP_ERR_T in cc.h if you want to use + * a different type for your platform (must be signed). */ +#ifdef LWIP_ERR_T +typedef LWIP_ERR_T err_t; +#else /* LWIP_ERR_T */ + typedef s8_t err_t; +#endif /* LWIP_ERR_T*/ + +/* Definitions for error constants. */ + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ + +#define ERR_IS_FATAL(e) ((e) < ERR_RTE) + +#define ERR_ABRT -5 /* Connection aborted. */ +#define ERR_RST -6 /* Connection reset. */ +#define ERR_CLSD -7 /* Connection closed. */ +#define ERR_CONN -8 /* Not connected. */ + +#define ERR_VAL -9 /* Illegal value. */ + +#define ERR_ARG -10 /* Illegal argument. */ + +#define ERR_USE -11 /* Address in use. */ + +#define ERR_IF -12 /* Low-level netif error */ +#define ERR_ISCONN -13 /* Already connected. */ + +#define ERR_INPROGRESS -14 /* Operation in progress */ + + +#ifdef LWIP_DEBUG +extern const char *lwip_strerr(err_t err); +#else +#define lwip_strerr(x) "" +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ERR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/init.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/init.h new file mode 100644 index 0000000..86be6da --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/init.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_INIT_H__ +#define __LWIP_INIT_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** X.x.x: Major version of the stack */ +#define LWIP_VERSION_MAJOR 1U +/** x.X.x: Minor version of the stack */ +#define LWIP_VERSION_MINOR 3U +/** x.x.X: Revision of the stack */ +#define LWIP_VERSION_REVISION 2U +/** For release candidates, this is set to 1..254 + * For official releases, this is set to 255 (LWIP_RC_RELEASE) + * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ +#define LWIP_VERSION_RC 255U + +/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ +#define LWIP_RC_RELEASE 255U +/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ +#define LWIP_RC_DEVELOPMENT 0U + +#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) +#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) +#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) + +/** Provides the version of the stack */ +#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ + LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) + +/* Modules initialization */ +void lwip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INIT_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/mem.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/mem.h new file mode 100644 index 0000000..7976462 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/mem.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_MEM_H__ +#define __LWIP_MEM_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MEM_LIBC_MALLOC + +#include /* for size_t */ + +typedef size_t mem_size_t; + +/* aliases for C library malloc() */ +#define mem_init() +/* in case C library malloc() needs extra protection, + * allow these defines to be overridden. + */ +#ifndef mem_free +#define mem_free free +#endif +#ifndef mem_malloc +#define mem_malloc malloc +#endif +#ifndef mem_calloc +#define mem_calloc calloc +#endif +#ifndef mem_realloc +static void *mem_realloc(void *mem, mem_size_t size) +{ + LWIP_UNUSED_ARG(size); + return mem; +} +#endif +#else /* MEM_LIBC_MALLOC */ + +/* MEM_SIZE would have to be aligned, but using 64000 here instead of + * 65535 leaves some room for alignment... + */ +#if MEM_SIZE > 64000l +typedef u32_t mem_size_t; +#else +typedef u16_t mem_size_t; +#endif /* MEM_SIZE > 64000 */ + +#if MEM_USE_POOLS +/** mem_init is not used when using pools instead of a heap */ +#define mem_init() +/** mem_realloc is not used when using pools instead of a heap: + we can't free part of a pool element and don't want to copy the rest */ +#define mem_realloc(mem, size) (mem) +#else /* MEM_USE_POOLS */ +/* lwIP alternative malloc */ +void mem_init(void); +void *mem_realloc(void *mem, mem_size_t size); +#endif /* MEM_USE_POOLS */ +void *mem_malloc(mem_size_t size); +void *mem_calloc(mem_size_t count, mem_size_t size); +void mem_free(void *mem); +#endif /* MEM_LIBC_MALLOC */ + +#ifndef LWIP_MEM_ALIGN_SIZE +#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) +#endif + +#ifndef LWIP_MEM_ALIGN +#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEM_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp.h new file mode 100644 index 0000000..33046db --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp.h @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_MEMP_H__ +#define __LWIP_MEMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ +typedef enum { +#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, +#include "lwip/memp_std.h" + MEMP_MAX +} memp_t; + +#if MEM_USE_POOLS +/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ +typedef enum { + /* Get the first (via: + MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ + MEMP_POOL_HELPER_FIRST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START 1 +#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 +#define LWIP_MALLOC_MEMPOOL_END +#include "lwip/memp_std.h" + ) , + /* Get the last (via: + MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ + MEMP_POOL_HELPER_LAST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * +#define LWIP_MALLOC_MEMPOOL_END 1 +#include "lwip/memp_std.h" + ) +} memp_pool_helper_t; + +/* The actual start and stop values are here (cast them over) + We use this helper type and these defines so we can avoid using const memp_t values */ +#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) +#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) +#endif /* MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC || MEM_USE_POOLS +extern const u16_t memp_sizes[MEMP_MAX]; +#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC + +#include "mem.h" + +#define memp_init() +#define memp_malloc(type) mem_malloc(memp_sizes[type]) +#define memp_free(type, mem) mem_free(mem) + +#else /* MEMP_MEM_MALLOC */ + +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +}; +#endif /* MEM_USE_POOLS */ + +void memp_init(void); + +#if MEMP_OVERFLOW_CHECK +void *memp_malloc_fn(memp_t type, const char* file, const int line); +#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) +#else +void *memp_malloc(memp_t type); +#endif +void memp_free(memp_t type, void *mem); + +#endif /* MEMP_MEM_MALLOC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp_std.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp_std.h new file mode 100644 index 0000000..0d25696 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/memp_std.h @@ -0,0 +1,102 @@ +/** + * SETUP: Make sure we define everything we will need. + * + * We have create three types of pools: + * 1) MEMPOOL - standard pools + * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c + * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct + * + * If the include'r doesn't require any special treatment of each of the types + * above, then will declare #2 & #3 to be just standard mempools. + */ +#ifndef LWIP_MALLOC_MEMPOOL +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL_END +#endif /* LWIP_MALLOC_MEMPOOL */ + +#ifndef LWIP_PBUF_MEMPOOL +/* This treats "pbuf pools" just like any other pool. + * Allocates buffers for a pbuf struct AND a payload size */ +#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) +#endif /* LWIP_PBUF_MEMPOOL */ + + +/* + * A list of internal pools used by LWIP. + * + * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + */ +#if LWIP_RAW +LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") +#endif /* LWIP_RAW */ + +#if LWIP_UDP +LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") +#endif /* LWIP_UDP */ + +#if LWIP_TCP +LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") +LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") +LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") +#endif /* IP_REASSEMBLY */ + +#if LWIP_NETCONN +LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") +LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") +#endif /* LWIP_NETCONN */ + +#if NO_SYS==0 +LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") +#endif /* NO_SYS==0 */ + +#if ARP_QUEUEING +LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") +#endif /* ARP_QUEUEING */ + +#if LWIP_IGMP +LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") +#endif /* LWIP_IGMP */ + +#if NO_SYS==0 +LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") +#endif /* NO_SYS==0 */ + + +/* + * A list of pools of pbuf's used by LWIP. + * + * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + * This allocates enough space for the pbuf struct and a payload. + * (Example: pbuf_payload_size=0 allocates only size for the struct) + */ +LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") +LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") + + +/* + * Allow for user-defined pools; this must be explicitly set in lwipopts.h + * since the default is to NOT look for lwippools.h + */ +#if MEMP_USE_CUSTOM_POOLS +#include "lwippools.h" +#endif /* MEMP_USE_CUSTOM_POOLS */ + +/* + * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later + * (#undef is ignored for something that is not defined) + */ +#undef LWIP_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL_START +#undef LWIP_MALLOC_MEMPOOL_END +#undef LWIP_PBUF_MEMPOOL diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netbuf.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netbuf.h new file mode 100644 index 0000000..0dfb367 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netbuf.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETBUF_H__ +#define __LWIP_NETBUF_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct netbuf { + struct pbuf *p, *ptr; + struct ip_addr *addr; + u16_t port; +#if LWIP_NETBUF_RECVINFO + struct ip_addr *toaddr; + u16_t toport; +#endif /* LWIP_NETBUF_RECVINFO */ +}; + +/* Network buffer functions: */ +struct netbuf * netbuf_new (void); +void netbuf_delete (struct netbuf *buf); +void * netbuf_alloc (struct netbuf *buf, u16_t size); +void netbuf_free (struct netbuf *buf); +err_t netbuf_ref (struct netbuf *buf, + const void *dataptr, u16_t size); +void netbuf_chain (struct netbuf *head, + struct netbuf *tail); + +u16_t netbuf_len (struct netbuf *buf); +err_t netbuf_data (struct netbuf *buf, + void **dataptr, u16_t *len); +s8_t netbuf_next (struct netbuf *buf); +void netbuf_first (struct netbuf *buf); + + +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) +#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) +#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) +#define netbuf_len(buf) ((buf)->p->tot_len) +#define netbuf_fromaddr(buf) ((buf)->addr) +#define netbuf_fromport(buf) ((buf)->port) +#if LWIP_NETBUF_RECVINFO +#define netbuf_destaddr(buf) ((buf)->toaddr) +#define netbuf_destport(buf) ((buf)->toport) +#endif /* LWIP_NETBUF_RECVINFO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETBUF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netdb.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netdb.h new file mode 100644 index 0000000..00cc172 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netdb.h @@ -0,0 +1,111 @@ +/** + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + **/ + +#include "lwip/opt.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include /* for size_t */ + +#include "lwip/sockets.h" + +/* some rarely used options */ +#ifndef LWIP_DNS_API_DECLARE_H_ERRNO +#define LWIP_DNS_API_DECLARE_H_ERRNO 1 +#endif + +#ifndef LWIP_DNS_API_DEFINE_ERRORS +#define LWIP_DNS_API_DEFINE_ERRORS 1 +#endif + +#ifndef LWIP_DNS_API_DECLARE_STRUCTS +#define LWIP_DNS_API_DECLARE_STRUCTS 1 +#endif + +#if LWIP_DNS_API_DEFINE_ERRORS +/** Errors used by the DNS API functions, h_errno can be one of them */ +#define EAI_NONAME 200 +#define EAI_SERVICE 201 +#define EAI_FAIL 202 +#define EAI_MEMORY 203 + +#define HOST_NOT_FOUND 210 +#define NO_DATA 211 +#define NO_RECOVERY 212 +#define TRY_AGAIN 213 +#endif /* LWIP_DNS_API_DEFINE_ERRORS */ + +#if LWIP_DNS_API_DECLARE_STRUCTS +struct hostent { + char *h_name; /* Official name of the host. */ + char **h_aliases; /* A pointer to an array of pointers to alternative host names, + terminated by a null pointer. */ + int h_addrtype; /* Address type. */ + int h_length; /* The length, in bytes, of the address. */ + char **h_addr_list; /* A pointer to an array of pointers to network addresses (in + network byte order) for the host, terminated by a null pointer. */ +#define h_addr h_addr_list[0] /* for backward compatibility */ +}; + +struct addrinfo { + int ai_flags; /* Input flags. */ + int ai_family; /* Address family of socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol of socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address of socket. */ + char *ai_canonname; /* Canonical name of service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ + +#if LWIP_DNS_API_DECLARE_H_ERRNO +/* application accessable error code set by the DNS API functions */ +extern int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ + +struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); +void lwip_freeaddrinfo(struct addrinfo *ai); +int lwip_getaddrinfo(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + +#if LWIP_COMPAT_SOCKETS +#define gethostbyname(name) lwip_gethostbyname(name) +#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ + lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) +#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) +#define getaddrinfo(nodname, servname, hints, res) \ + lwip_getaddrinfo(nodname, servname, hints, res) +#endif /* LWIP_COMPAT_SOCKETS */ + +#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netif.h new file mode 100644 index 0000000..59869ac --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netif.h @@ -0,0 +1,269 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETIF_H__ +#define __LWIP_NETIF_H__ + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" + +#include "lwip/inet.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** must be the maximum of all used hardware address lengths + across all types of interfaces in use */ +#define NETIF_MAX_HWADDR_LEN 6U + +/** TODO: define the use (where, when, whom) of netif flags */ + +/** whether the network interface is 'up'. this is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + */ +#define NETIF_FLAG_UP 0x01U +/** if set, the netif has broadcast capability */ +#define NETIF_FLAG_BROADCAST 0x02U +/** if set, the netif is one end of a point-to-point connection */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** if set, the interface is configured using DHCP */ +#define NETIF_FLAG_DHCP 0x08U +/** if set, the interface has an active link + * (set by the network interface driver) */ +#define NETIF_FLAG_LINK_UP 0x10U +/** if set, the netif is an device using ARP */ +#define NETIF_FLAG_ETHARP 0x20U +/** if set, the netif has IGMP capability */ +#define NETIF_FLAG_IGMP 0x40U +/** if set, the netif has IP layer switch capability */ +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP +#define NETIF_FLAG_IPSWITCH 0x80U +#endif +/* Realtek Modified End */ + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ + +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + struct ip_addr ip_addr; + struct ip_addr netmask; + struct ip_addr gw; + + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. */ + err_t (* input)(struct pbuf *p, struct netif *inp); + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + err_t (* output)(struct netif *netif, struct pbuf *p, + struct ip_addr *ipaddr); + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. */ + err_t (* linkoutput)(struct netif *netif, struct pbuf *p); +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + void (* status_callback)(struct netif *netif); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + void (* link_callback)(struct netif *netif); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. */ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) */ + u16_t mtu; + /** number of bytes used in hwaddr */ + u8_t hwaddr_len; + /** link level hardware address of this interface */ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) */ + u8_t flags; + /** descriptive abbreviation */ + char name[2]; + /** number of this interface */ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/ + err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action); +#endif /* LWIP_IGMP */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + netif->link_type = type; \ + /* your link speed here (units: bits per second) */ \ + netif->link_speed = speed; \ + netif->ts = 0; \ + netif->ifinoctets = 0; \ + netif->ifinucastpkts = 0; \ + netif->ifinnucastpkts = 0; \ + netif->ifindiscards = 0; \ + netif->ifoutoctets = 0; \ + netif->ifoutucastpkts = 0; \ + netif->ifoutnucastpkts = 0; \ + netif->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +#define netif_init() /* Compatibility define, not init needed. */ + +struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, + struct ip_addr *gw, + void *state, + err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)); + +void +netif_set_addr(struct netif *netif,struct ip_addr *ipaddr, struct ip_addr *netmask, + struct ip_addr *gw); +void netif_remove(struct netif * netif); + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name); + +void netif_set_default(struct netif *netif); + +void netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr); +void netif_set_netmask(struct netif *netif, struct ip_addr *netmask); +void netif_set_gw(struct netif *netif, struct ip_addr *gw); + +void netif_set_up(struct netif *netif); +void netif_set_down(struct netif *netif); +u8_t netif_is_up(struct netif *netif); + +#if LWIP_NETIF_STATUS_CALLBACK +/* + * Set callback to be called when interface is brought up/down + */ +void netif_set_status_callback(struct netif *netif, void (* status_callback)(struct netif *netif)); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_up(struct netif *netif); +void netif_set_link_down(struct netif *netif); +u8_t netif_is_link_up(struct netif *netif); +/* + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback(struct netif *netif, void (* link_callback)(struct netif *netif)); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#ifdef __cplusplus +} +#endif + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p, struct ip_addr *dest_ip); +void netif_poll(struct netif *netif); +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void); +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#endif /* __LWIP_NETIF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netifapi.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netifapi.h new file mode 100644 index 0000000..4145dd7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/netifapi.h @@ -0,0 +1,105 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_NETIFAPI_H__ +#define __LWIP_NETIFAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct netifapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + err_t err; + struct netif *netif; + union { + struct { + struct ip_addr *ipaddr; + struct ip_addr *netmask; + struct ip_addr *gw; + void *state; + err_t (* init) (struct netif *netif); + err_t (* input)(struct pbuf *p, struct netif *netif); + } add; + struct { + void (* voidfunc)(struct netif *netif); + err_t (* errtfunc)(struct netif *netif); + } common; + } msg; +}; + +struct netifapi_msg { + void (* function)(struct netifapi_msg_msg *msg); + struct netifapi_msg_msg msg; +}; + + +/* API for application */ +err_t netifapi_netif_add ( struct netif *netif, + struct ip_addr *ipaddr, + struct ip_addr *netmask, + struct ip_addr *gw, + void *state, + err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif) ); + +err_t netifapi_netif_set_addr ( struct netif *netif, + struct ip_addr *ipaddr, + struct ip_addr *netmask, + struct ip_addr *gw ); + +err_t netifapi_netif_common ( struct netif *netif, + void (* voidfunc)(struct netif *netif), + err_t (* errtfunc)(struct netif *netif) ); + +#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) +#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) +#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) +#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) +#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) +#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) +#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) +#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETIF_API */ + +#endif /* __LWIP_NETIFAPI_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/opt.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/opt.h new file mode 100644 index 0000000..69162cf --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/opt.h @@ -0,0 +1,1841 @@ +/* + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_OPT_H__ +#define __LWIP_OPT_H__ + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of simultaneously IP packets queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT 3 +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 16 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Outgoing packets are queued during hardware address + * resolution. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 1 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 1 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented. + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 1 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 1 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 1 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS use a local buffer if DNS_USES_STATIC_BUF=0, a static one if + DNS_USES_STATIC_BUF=1, or a dynamic one if DNS_USES_STATIC_BUF=2. + The buffer will be of size DNS_MSG_SIZE */ +#ifndef DNS_USES_STATIC_BUF +#define DNS_USES_STATIC_BUF 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF 256 +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than or equal + * to TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable. + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT ((TCP_SND_BUF)/2) +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. + */ +#ifndef LWIP_EVENT_API +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#else +#define LWIP_EVENT_API 1 +#define LWIP_CALLBACK_API 0 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN 14 +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accomodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 1 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "TCP_IP" +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppMain thread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppMain" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppMain thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppMain thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 1 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#ifndef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 1 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR and SO_REUSEPORT options. DO NOT USE! + */ +#ifndef SO_REUSE +#define SO_REUSE 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +#else + +#define LINK_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define ETHARP_STATS 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/pbuf.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/pbuf.h new file mode 100644 index 0000000..4156c36 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/pbuf.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_PBUF_H__ +#define __LWIP_PBUF_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PBUF_TRANSPORT_HLEN 20 +#define PBUF_IP_HLEN 20 + +typedef enum { + PBUF_TRANSPORT, + PBUF_IP, + PBUF_LINK, + PBUF_RAW +} pbuf_layer; + +typedef enum { + PBUF_RAM, /* pbuf data is stored in RAM */ + PBUF_ROM, /* pbuf data is stored in ROM */ + PBUF_REF, /* pbuf comes from the pbuf pool */ + PBUF_POOL /* pbuf payload refers to RAM */ +} pbuf_type; + + +/** indicates this packet's data should be immediately passed to the application */ +#define PBUF_FLAG_PUSH 0x01U + +struct pbuf { + /** next pbuf in singly linked pbuf chain */ + struct pbuf *next; + + /** pointer to the actual data in the buffer */ + void *payload; + + /** + * total length of this buffer and all next buffers in chain + * belonging to the same packet. + * + * For non-queue packet chains this is the invariant: + * p->tot_len == p->len + (p->next? p->next->tot_len: 0) + */ + u16_t tot_len; + + /** length of this buffer */ + u16_t len; + + /** pbuf_type as u8_t instead of enum to save space */ + u8_t /*pbuf_type*/ type; + + /** misc flags */ + u8_t flags; + + /** + * the reference count always equals the number of pointers + * that refer to this pbuf. This can be pointers from an application, + * the stack itself, or pbuf->next pointers from a chain. + */ + u16_t ref; + +}; + +/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ +#define pbuf_init() + +struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_type type); +void pbuf_realloc(struct pbuf *p, u16_t size); +u8_t pbuf_header(struct pbuf *p, s16_t header_size); +void pbuf_ref(struct pbuf *p); +void pbuf_ref_chain(struct pbuf *p); +u8_t pbuf_free(struct pbuf *p); +u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *head, struct pbuf *tail); +void pbuf_chain(struct pbuf *head, struct pbuf *tail); +struct pbuf *pbuf_dechain(struct pbuf *p); +err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); +err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); +struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_PBUF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/raw.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/raw.h new file mode 100644 index 0000000..659ad9d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/raw.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_RAW_H__ +#define __LWIP_RAW_H__ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/inet.h" +#include "lwip/ip.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct raw_pcb { +/* Common members of all PCB types */ + IP_PCB; + + struct raw_pcb *next; + + u8_t protocol; + + /* receive callback function + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ + u8_t (* recv)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + struct ip_addr *addr); + /* user-supplied argument for the recv callback */ + void *recv_arg; +}; + +/* The following functions is the application layer interface to the + RAW code. */ +struct raw_pcb * raw_new (u8_t proto); +void raw_remove (struct raw_pcb *pcb); +err_t raw_bind (struct raw_pcb *pcb, struct ip_addr *ipaddr); +err_t raw_connect (struct raw_pcb *pcb, struct ip_addr *ipaddr); + +void raw_recv (struct raw_pcb *pcb, + u8_t (* recv)(void *arg, struct raw_pcb *pcb, + struct pbuf *p, + struct ip_addr *addr), + void *recv_arg); +err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr); +err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); + +/* The following functions are the lower layer interface to RAW. */ +u8_t raw_input (struct pbuf *p, struct netif *inp); +#define raw_init() /* Compatibility define, not init needed. */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_RAW */ + +#endif /* __LWIP_RAW_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sio.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sio.h new file mode 100644 index 0000000..28ae2f2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sio.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ + +#ifndef __SIO_H__ +#define __SIO_H__ + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If you want to define sio_fd_t elsewhere or differently, + define this in your cc.h file. */ +#ifndef __sio_fd_t_defined +typedef void * sio_fd_t; +#endif + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +#ifndef sio_open +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum); +#endif + +#ifndef sio_send +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd); +#endif + +#ifndef sio_recv +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd); +#endif + +#ifndef sio_read +/** + * Reads from the serial device. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * + * @note This function will block until data can be received. The blocking + * can be cancelled by calling sio_read_abort(). + */ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_tryread +/** + * Tries to read from the serial device. Same as sio_read but returns + * immediately if no data is available and never blocks. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received + */ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_write +/** + * Writes to the serial device. + * + * @param fd serial device handle + * @param data pointer to data to send + * @param len length (in bytes) of data to send + * @return number of bytes actually sent + * + * @note This function will block until all data can be sent. + */ +u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_read_abort +/** + * Aborts a blocking sio_read() call. + * + * @param fd serial device handle + */ +void sio_read_abort(sio_fd_t fd); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SIO_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp.h new file mode 100644 index 0000000..20bbce5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp.h @@ -0,0 +1,364 @@ +/** + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + **/ +#ifndef __LWIP_SNMP_H__ +#define __LWIP_SNMP_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @see RFC1213, "MIB-II, 6. Definitions" + */ +enum snmp_ifType { + snmp_ifType_other=1, /* none of the following */ + snmp_ifType_regular1822, + snmp_ifType_hdh1822, + snmp_ifType_ddn_x25, + snmp_ifType_rfc877_x25, + snmp_ifType_ethernet_csmacd, + snmp_ifType_iso88023_csmacd, + snmp_ifType_iso88024_tokenBus, + snmp_ifType_iso88025_tokenRing, + snmp_ifType_iso88026_man, + snmp_ifType_starLan, + snmp_ifType_proteon_10Mbit, + snmp_ifType_proteon_80Mbit, + snmp_ifType_hyperchannel, + snmp_ifType_fddi, + snmp_ifType_lapb, + snmp_ifType_sdlc, + snmp_ifType_ds1, /* T-1 */ + snmp_ifType_e1, /* european equiv. of T-1 */ + snmp_ifType_basicISDN, + snmp_ifType_primaryISDN, /* proprietary serial */ + snmp_ifType_propPointToPointSerial, + snmp_ifType_ppp, + snmp_ifType_softwareLoopback, + snmp_ifType_eon, /* CLNP over IP [11] */ + snmp_ifType_ethernet_3Mbit, + snmp_ifType_nsip, /* XNS over IP */ + snmp_ifType_slip, /* generic SLIP */ + snmp_ifType_ultra, /* ULTRA technologies */ + snmp_ifType_ds3, /* T-3 */ + snmp_ifType_sip, /* SMDS */ + snmp_ifType_frame_relay +}; + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** SNMP "sysuptime" Interval */ +#define SNMP_SYSUPTIME_INTERVAL 10 + +/** fixed maximum length for object identifier type */ +#define LWIP_SNMP_OBJ_ID_LEN 32 + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + s32_t id[LWIP_SNMP_OBJ_ID_LEN]; +}; + +/* system */ +void snmp_set_sysdesr(u8_t* str, u8_t* len); +void snmp_set_sysobjid(struct snmp_obj_id *oid); +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); +void snmp_inc_sysuptime(void); +void snmp_add_sysuptime(u32_t value); +void snmp_get_sysuptime(u32_t *value); +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); + +/* network interface */ +void snmp_add_ifinoctets(struct netif *ni, u32_t value); +void snmp_inc_ifinucastpkts(struct netif *ni); +void snmp_inc_ifinnucastpkts(struct netif *ni); +void snmp_inc_ifindiscards(struct netif *ni); +void snmp_add_ifoutoctets(struct netif *ni, u32_t value); +void snmp_inc_ifoutucastpkts(struct netif *ni); +void snmp_inc_ifoutnucastpkts(struct netif *ni); +void snmp_inc_ifoutdiscards(struct netif *ni); +void snmp_inc_iflist(void); +void snmp_dec_iflist(void); + +/* ARP (for atTable and ipNetToMediaTable) */ +void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip); +void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip); + +/* IP */ +void snmp_inc_ipinreceives(void); +void snmp_inc_ipinhdrerrors(void); +void snmp_inc_ipinaddrerrors(void); +void snmp_inc_ipforwdatagrams(void); +void snmp_inc_ipinunknownprotos(void); +void snmp_inc_ipindiscards(void); +void snmp_inc_ipindelivers(void); +void snmp_inc_ipoutrequests(void); +void snmp_inc_ipoutdiscards(void); +void snmp_inc_ipoutnoroutes(void); +void snmp_inc_ipreasmreqds(void); +void snmp_inc_ipreasmoks(void); +void snmp_inc_ipreasmfails(void); +void snmp_inc_ipfragoks(void); +void snmp_inc_ipfragfails(void); +void snmp_inc_ipfragcreates(void); +void snmp_inc_iproutingdiscards(void); +void snmp_insert_ipaddridx_tree(struct netif *ni); +void snmp_delete_ipaddridx_tree(struct netif *ni); +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); + +/* ICMP */ +void snmp_inc_icmpinmsgs(void); +void snmp_inc_icmpinerrors(void); +void snmp_inc_icmpindestunreachs(void); +void snmp_inc_icmpintimeexcds(void); +void snmp_inc_icmpinparmprobs(void); +void snmp_inc_icmpinsrcquenchs(void); +void snmp_inc_icmpinredirects(void); +void snmp_inc_icmpinechos(void); +void snmp_inc_icmpinechoreps(void); +void snmp_inc_icmpintimestamps(void); +void snmp_inc_icmpintimestampreps(void); +void snmp_inc_icmpinaddrmasks(void); +void snmp_inc_icmpinaddrmaskreps(void); +void snmp_inc_icmpoutmsgs(void); +void snmp_inc_icmpouterrors(void); +void snmp_inc_icmpoutdestunreachs(void); +void snmp_inc_icmpouttimeexcds(void); +void snmp_inc_icmpoutparmprobs(void); +void snmp_inc_icmpoutsrcquenchs(void); +void snmp_inc_icmpoutredirects(void); +void snmp_inc_icmpoutechos(void); +void snmp_inc_icmpoutechoreps(void); +void snmp_inc_icmpouttimestamps(void); +void snmp_inc_icmpouttimestampreps(void); +void snmp_inc_icmpoutaddrmasks(void); +void snmp_inc_icmpoutaddrmaskreps(void); + +/* TCP */ +void snmp_inc_tcpactiveopens(void); +void snmp_inc_tcppassiveopens(void); +void snmp_inc_tcpattemptfails(void); +void snmp_inc_tcpestabresets(void); +void snmp_inc_tcpinsegs(void); +void snmp_inc_tcpoutsegs(void); +void snmp_inc_tcpretranssegs(void); +void snmp_inc_tcpinerrs(void); +void snmp_inc_tcpoutrsts(void); + +/* UDP */ +void snmp_inc_udpindatagrams(void); +void snmp_inc_udpnoports(void); +void snmp_inc_udpinerrors(void); +void snmp_inc_udpoutdatagrams(void); +void snmp_insert_udpidx_tree(struct udp_pcb *pcb); +void snmp_delete_udpidx_tree(struct udp_pcb *pcb); + +/* SNMP */ +void snmp_inc_snmpinpkts(void); +void snmp_inc_snmpoutpkts(void); +void snmp_inc_snmpinbadversions(void); +void snmp_inc_snmpinbadcommunitynames(void); +void snmp_inc_snmpinbadcommunityuses(void); +void snmp_inc_snmpinasnparseerrs(void); +void snmp_inc_snmpintoobigs(void); +void snmp_inc_snmpinnosuchnames(void); +void snmp_inc_snmpinbadvalues(void); +void snmp_inc_snmpinreadonlys(void); +void snmp_inc_snmpingenerrs(void); +void snmp_add_snmpintotalreqvars(u8_t value); +void snmp_add_snmpintotalsetvars(u8_t value); +void snmp_inc_snmpingetrequests(void); +void snmp_inc_snmpingetnexts(void); +void snmp_inc_snmpinsetrequests(void); +void snmp_inc_snmpingetresponses(void); +void snmp_inc_snmpintraps(void); +void snmp_inc_snmpouttoobigs(void); +void snmp_inc_snmpoutnosuchnames(void); +void snmp_inc_snmpoutbadvalues(void); +void snmp_inc_snmpoutgenerrs(void); +void snmp_inc_snmpoutgetrequests(void); +void snmp_inc_snmpoutgetnexts(void); +void snmp_inc_snmpoutsetrequests(void); +void snmp_inc_snmpoutgetresponses(void); +void snmp_inc_snmpouttraps(void); +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); +void snmp_set_snmpenableauthentraps(u8_t *value); +void snmp_get_snmpenableauthentraps(u8_t *value); + +/* LWIP_SNMP support not available */ +/* define everything to be empty */ +#else + +/* system */ +#define snmp_set_sysdesr(str, len) +#define snmp_set_sysobjid(oid); +#define snmp_get_sysobjid_ptr(oid) +#define snmp_inc_sysuptime() +#define snmp_add_sysuptime(value) +#define snmp_get_sysuptime(value) +#define snmp_set_syscontact(ocstr, ocstrlen); +#define snmp_set_sysname(ocstr, ocstrlen); +#define snmp_set_syslocation(ocstr, ocstrlen); + +/* network interface */ +#define snmp_add_ifinoctets(ni,value) +#define snmp_inc_ifinucastpkts(ni) +#define snmp_inc_ifinnucastpkts(ni) +#define snmp_inc_ifindiscards(ni) +#define snmp_add_ifoutoctets(ni,value) +#define snmp_inc_ifoutucastpkts(ni) +#define snmp_inc_ifoutnucastpkts(ni) +#define snmp_inc_ifoutdiscards(ni) +#define snmp_inc_iflist() +#define snmp_dec_iflist() + +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) + +/* IP */ +#define snmp_inc_ipinreceives() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() +#define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#define snmp_inc_ipoutdiscards() +#define snmp_inc_ipoutnoroutes() +#define snmp_inc_ipreasmreqds() +#define snmp_inc_ipreasmoks() +#define snmp_inc_ipreasmfails() +#define snmp_inc_ipfragoks() +#define snmp_inc_ipfragfails() +#define snmp_inc_ipfragcreates() +#define snmp_inc_iproutingdiscards() +#define snmp_insert_ipaddridx_tree(ni) +#define snmp_delete_ipaddridx_tree(ni) +#define snmp_insert_iprteidx_tree(dflt, ni) +#define snmp_delete_iprteidx_tree(dflt, ni) + +/* ICMP */ +#define snmp_inc_icmpinmsgs() +#define snmp_inc_icmpinerrors() +#define snmp_inc_icmpindestunreachs() +#define snmp_inc_icmpintimeexcds() +#define snmp_inc_icmpinparmprobs() +#define snmp_inc_icmpinsrcquenchs() +#define snmp_inc_icmpinredirects() +#define snmp_inc_icmpinechos() +#define snmp_inc_icmpinechoreps() +#define snmp_inc_icmpintimestamps() +#define snmp_inc_icmpintimestampreps() +#define snmp_inc_icmpinaddrmasks() +#define snmp_inc_icmpinaddrmaskreps() +#define snmp_inc_icmpoutmsgs() +#define snmp_inc_icmpouterrors() +#define snmp_inc_icmpoutdestunreachs() +#define snmp_inc_icmpouttimeexcds() +#define snmp_inc_icmpoutparmprobs() +#define snmp_inc_icmpoutsrcquenchs() +#define snmp_inc_icmpoutredirects() +#define snmp_inc_icmpoutechos() +#define snmp_inc_icmpoutechoreps() +#define snmp_inc_icmpouttimestamps() +#define snmp_inc_icmpouttimestampreps() +#define snmp_inc_icmpoutaddrmasks() +#define snmp_inc_icmpoutaddrmaskreps() +/* TCP */ +#define snmp_inc_tcpactiveopens() +#define snmp_inc_tcppassiveopens() +#define snmp_inc_tcpattemptfails() +#define snmp_inc_tcpestabresets() +#define snmp_inc_tcpinsegs() +#define snmp_inc_tcpoutsegs() +#define snmp_inc_tcpretranssegs() +#define snmp_inc_tcpinerrs() +#define snmp_inc_tcpoutrsts() + +/* UDP */ +#define snmp_inc_udpindatagrams() +#define snmp_inc_udpnoports() +#define snmp_inc_udpinerrors() +#define snmp_inc_udpoutdatagrams() +#define snmp_insert_udpidx_tree(pcb) +#define snmp_delete_udpidx_tree(pcb) + +/* SNMP */ +#define snmp_inc_snmpinpkts() +#define snmp_inc_snmpoutpkts() +#define snmp_inc_snmpinbadversions() +#define snmp_inc_snmpinbadcommunitynames() +#define snmp_inc_snmpinbadcommunityuses() +#define snmp_inc_snmpinasnparseerrs() +#define snmp_inc_snmpintoobigs() +#define snmp_inc_snmpinnosuchnames() +#define snmp_inc_snmpinbadvalues() +#define snmp_inc_snmpinreadonlys() +#define snmp_inc_snmpingenerrs() +#define snmp_add_snmpintotalreqvars(value) +#define snmp_add_snmpintotalsetvars(value) +#define snmp_inc_snmpingetrequests() +#define snmp_inc_snmpingetnexts() +#define snmp_inc_snmpinsetrequests() +#define snmp_inc_snmpingetresponses() +#define snmp_inc_snmpintraps() +#define snmp_inc_snmpouttoobigs() +#define snmp_inc_snmpoutnosuchnames() +#define snmp_inc_snmpoutbadvalues() +#define snmp_inc_snmpoutgenerrs() +#define snmp_inc_snmpoutgetrequests() +#define snmp_inc_snmpoutgetnexts() +#define snmp_inc_snmpoutsetrequests() +#define snmp_inc_snmpoutgetresponses() +#define snmp_inc_snmpouttraps() +#define snmp_get_snmpgrpid_ptr(oid) +#define snmp_set_snmpenableauthentraps(value) +#define snmp_get_snmpenableauthentraps(value) + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SNMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_asn1.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_asn1.h new file mode 100644 index 0000000..8a60288 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_asn1.h @@ -0,0 +1,101 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_ASN1_H__ +#define __LWIP_SNMP_ASN1_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/snmp.h" + +#if LWIP_SNMP + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_UNIV (!0x80 | !0x40) +#define SNMP_ASN1_APPLIC (!0x80 | 0x40) +#define SNMP_ASN1_CONTXT ( 0x80 | !0x40) + +#define SNMP_ASN1_CONSTR (0x20) +#define SNMP_ASN1_PRIMIT (!0x20) + +/* universal tags */ +#define SNMP_ASN1_INTEG 2 +#define SNMP_ASN1_OC_STR 4 +#define SNMP_ASN1_NUL 5 +#define SNMP_ASN1_OBJ_ID 6 +#define SNMP_ASN1_SEQ 16 + +/* application specific (SNMP) tags */ +#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ +#define SNMP_ASN1_COUNTER 1 /* u32_t */ +#define SNMP_ASN1_GAUGE 2 /* u32_t */ +#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ +#define SNMP_ASN1_OPAQUE 4 /* octet string */ + +/* context specific (SNMP) tags */ +#define SNMP_ASN1_PDU_GET_REQ 0 +#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_PDU_GET_RESP 2 +#define SNMP_ASN1_PDU_SET_REQ 3 +#define SNMP_ASN1_PDU_TRAP 4 + +err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); +err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); +err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); +err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); +err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); +err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); +err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, u32_t value); +err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u8_t octets_needed, s32_t value); +err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); +err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u8_t raw_len, u8_t *raw); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_ASN1_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_msg.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_msg.h new file mode 100644 index 0000000..32ba8fb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_msg.h @@ -0,0 +1,311 @@ +/** + * @file + * SNMP Agent message handling structures. + **/ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_MSG_H__ +#define __LWIP_SNMP_MSG_H__ + +#include "lwip/opt.h" +#include "lwip/snmp.h" +#include "lwip/snmp_structs.h" + +#if LWIP_SNMP + +#if SNMP_PRIVATE_MIB +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +#define SNMP_ES_NOERROR 0 +#define SNMP_ES_TOOBIG 1 +#define SNMP_ES_NOSUCHNAME 2 +#define SNMP_ES_BADVALUE 3 +#define SNMP_ES_READONLY 4 +#define SNMP_ES_GENERROR 5 + +#define SNMP_GENTRAP_COLDSTART 0 +#define SNMP_GENTRAP_WARMSTART 1 +#define SNMP_GENTRAP_AUTHFAIL 4 +#define SNMP_GENTRAP_ENTERPRISESPC 6 + +struct snmp_varbind +{ + /* next pointer, NULL for last in list */ + struct snmp_varbind *next; + /* previous pointer, NULL for first in list */ + struct snmp_varbind *prev; + + /* object identifier length (in s32_t) */ + u8_t ident_len; + /* object identifier array */ + s32_t *ident; + + /* object value ASN1 type */ + u8_t value_type; + /* object value length (in u8_t) */ + u8_t value_len; + /* object value */ + void *value; + + /* encoding varbind seq length length */ + u8_t seqlenlen; + /* encoding object identifier length length */ + u8_t olenlen; + /* encoding object value length length */ + u8_t vlenlen; + /* encoding varbind seq length */ + u16_t seqlen; + /* encoding object identifier length */ + u16_t olen; + /* encoding object value length */ + u16_t vlen; +}; + +struct snmp_varbind_root +{ + struct snmp_varbind *head; + struct snmp_varbind *tail; + /* number of variable bindings in list */ + u8_t count; + /* encoding varbind-list seq length length */ + u8_t seqlenlen; + /* encoding varbind-list seq length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_resp_header_lengths +{ + /* encoding error-index length length */ + u8_t erridxlenlen; + /* encoding error-status length length */ + u8_t errstatlenlen; + /* encoding request id length length */ + u8_t ridlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding error-index length */ + u16_t erridxlen; + /* encoding error-status length */ + u16_t errstatlen; + /* encoding request id length */ + u16_t ridlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_trap_header_lengths +{ + /* encoding timestamp length length */ + u8_t tslenlen; + /* encoding specific-trap length length */ + u8_t strplenlen; + /* encoding generic-trap length length */ + u8_t gtrplenlen; + /* encoding agent-addr length length */ + u8_t aaddrlenlen; + /* encoding enterprise-id length length */ + u8_t eidlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding timestamp length */ + u16_t tslen; + /* encoding specific-trap length */ + u16_t strplen; + /* encoding generic-trap length */ + u16_t gtrplen; + /* encoding agent-addr length */ + u16_t aaddrlen; + /* encoding enterprise-id length */ + u16_t eidlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/* Accepting new SNMP messages. */ +#define SNMP_MSG_EMPTY 0 +/* Search for matching object for variable binding. */ +#define SNMP_MSG_SEARCH_OBJ 1 +/* Perform SNMP operation on in-memory object. + Pass-through states, for symmetry only. */ +#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 +#define SNMP_MSG_INTERNAL_GET_VALUE 3 +#define SNMP_MSG_INTERNAL_SET_TEST 4 +#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 +#define SNMP_MSG_INTERNAL_SET_VALUE 6 +/* Perform SNMP operation on object located externally. + In theory this could be used for building a proxy agent. + Practical use is for an enterprise spc. app. gateway. */ +#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 +#define SNMP_MSG_EXTERNAL_GET_VALUE 8 +#define SNMP_MSG_EXTERNAL_SET_TEST 9 +#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 +#define SNMP_MSG_EXTERNAL_SET_VALUE 11 + +#define SNMP_COMMUNITY_STR_LEN 64 +struct snmp_msg_pstat +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* source IP address */ + struct ip_addr sip; + /* source UDP port */ + u16_t sp; + /* request type */ + u8_t rt; + /* request ID */ + s32_t rid; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* community name (zero terminated) */ + u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u8_t com_strlen; + /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ + u8_t state; + /* saved arguments for MSG_EXTERNAL_x */ + struct mib_external_node *ext_mib_node; + struct snmp_name_ptr ext_name_ptr; + struct obj_def ext_object_def; + struct snmp_obj_id ext_oid; + /* index into input variable binding list */ + u8_t vb_idx; + /* ptr into input variable binding list */ + struct snmp_varbind *vb_ptr; + /* list of variable bindings from input */ + struct snmp_varbind_root invb; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output response lengths used in ASN encoding */ + struct snmp_resp_header_lengths rhl; +}; + +struct snmp_msg_trap +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* destination IP address in network order */ + struct ip_addr dip; + + /* source enterprise ID (sysObjectID) */ + struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + u8_t sip_raw[4]; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output trap lengths used in ASN encoding */ + struct snmp_trap_header_lengths thl; +}; + +/** Agent Version constant, 0 = v1 oddity */ +extern const s32_t snmp_version; +/** Agent default "public" community string */ +extern const char snmp_publiccommunity[7]; + +extern struct snmp_msg_trap trap_msg; + +/** Agent setup, start listening to port 161. */ +void snmp_init(void); +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst); + +/** Varbind-list functions. */ +struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); +void snmp_varbind_free(struct snmp_varbind *vb); +void snmp_varbind_list_free(struct snmp_varbind_root *root); +void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); +struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); + +/** Handle an internal (recv) or external (private response) event. */ +void snmp_msg_event(u8_t request_id); +err_t snmp_send_response(struct snmp_msg_pstat *m_stat); +err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_MSG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_structs.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_structs.h new file mode 100644 index 0000000..aa3f02e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/snmp_structs.h @@ -0,0 +1,262 @@ +/** + * @file + * Generic MIB tree structures. + * + * @todo namespace prefixes + **/ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_STRUCTS_H__ +#define __LWIP_SNMP_STRUCTS_H__ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" + +#if SNMP_PRIVATE_MIB +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MIB object instance */ +#define MIB_OBJECT_NONE 0 +#define MIB_OBJECT_SCALAR 1 +#define MIB_OBJECT_TAB 2 + +/* MIB object access */ +#define MIB_OBJECT_READ_ONLY 0 +#define MIB_OBJECT_READ_WRITE 1 +#define MIB_OBJECT_WRITE_ONLY 2 +#define MIB_OBJECT_NOT_ACCESSIBLE 3 + +/** object definition returned by (get_object_def)() */ +struct obj_def +{ + /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ + u8_t instance; + /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ + u8_t access; + /* ASN type for this object */ + u8_t asn_type; + /* value length (host length) */ + u16_t v_len; + /* length of instance part of supplied object identifier */ + u8_t id_inst_len; + /* instance part of supplied object identifier */ + s32_t *id_inst_ptr; +}; + +struct snmp_name_ptr +{ + u8_t ident_len; + s32_t *ident; +}; + +/** MIB const scalar (.0) node */ +#define MIB_NODE_SC 0x01 +/** MIB const array node */ +#define MIB_NODE_AR 0x02 +/** MIB array node (mem_malloced from RAM) */ +#define MIB_NODE_RA 0x03 +/** MIB list root node (mem_malloced from RAM) */ +#define MIB_NODE_LR 0x04 +/** MIB node for external objects */ +#define MIB_NODE_EX 0x05 + +/** node "base class" layout, the mandatory fields for a node */ +struct mib_node +{ + /** returns struct obj_def for the given object identifier */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + /** returns object value for the given object identifier, + @note the caller must allocate at least len bytes for the value */ + void (*get_value)(struct obj_def *od, u16_t len, void *value); + /** tests length and/or range BEFORE setting */ + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + /** sets object value, only to be called when set_test() */ + void (*set_value)(struct obj_def *od, u16_t len, void *value); + /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ + const u8_t node_type; + /* array or max list length */ + const u16_t maxlength; +}; + +/** derived node for scalars .0 index */ +typedef struct mib_node mib_scalar_node; + +/** derived node, points to a fixed size const array + of sub-identifiers plus a 'child' pointer */ +struct mib_array_node +{ + /* inherited "base class" members */ + void (* const get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (* const get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + const u8_t node_type; + const u16_t maxlength; + + /* aditional struct members */ + const s32_t *objid; + struct mib_node* const *nptr; +}; + +/** derived node, points to a fixed size mem_malloced array + of sub-identifiers plus a 'child' pointer */ +struct mib_ram_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + s32_t *objid; + struct mib_node **nptr; +}; + +struct mib_list_node +{ + struct mib_list_node *prev; + struct mib_list_node *next; + s32_t objid; + struct mib_node *nptr; +}; + +/** derived node, points to a doubly linked list + of sub-identifiers plus a 'child' pointer */ +struct mib_list_rootnode +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + struct mib_list_node *head; + struct mib_list_node *tail; + /* counts list nodes in list */ + u16_t count; +}; + +/** derived node, has access functions for mib object in external memory or device + using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ +struct mib_external_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + /** points to an extenal (in memory) record of some sort of addressing + information, passed to and interpreted by the funtions below */ + void* addr_inf; + /** tree levels under this node */ + u8_t tree_levels; + /** number of objects at this level */ + u16_t (*level_length)(void* addr_inf, u8_t level); + /** compares object sub identifier with external id + return zero when equal, nonzero when unequal */ + s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); + void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + + /** async Questions */ + void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_q)(u8_t rid, struct obj_def *od); + void (*set_test_q)(u8_t rid, struct obj_def *od); + void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Answers */ + void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Panic Close (agent returns error reply, + e.g. used for external transaction cleanup) */ + void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_pc)(u8_t rid, struct obj_def *od); + void (*set_test_pc)(u8_t rid, struct obj_def *od); + void (*set_value_pc)(u8_t rid, struct obj_def *od); +}; + +/** export MIB tree from mib2.c */ +extern const struct mib_array_node internet; + +/** dummy function pointers for non-leaf MIB nodes from mib2.c */ +void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); +void noleafs_set_value(struct obj_def *od, u16_t len, void *value); + +void snmp_oidtoip(s32_t *ident, struct ip_addr *ip); +void snmp_iptooid(struct ip_addr *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct mib_list_node* snmp_mib_ln_alloc(s32_t id); +void snmp_mib_ln_free(struct mib_list_node *ln); +struct mib_list_rootnode* snmp_mib_lrn_alloc(void); +void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); + +s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); +s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); +struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); + +struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); +struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); +u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); +u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_STRUCTS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sockets.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sockets.h new file mode 100644 index 0000000..44a18e6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sockets.h @@ -0,0 +1,357 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ + + +#ifndef __LWIP_SOCKETS_H__ +#define __LWIP_SOCKETS_H__ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/inet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* members are in network byte order */ +struct sockaddr_in { + u8_t sin_len; + u8_t sin_family; + u16_t sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +struct sockaddr { + u8_t sa_len; + u8_t sa_family; + char sa_data[14]; +}; + +#ifndef socklen_t +# define socklen_t u32_t +#endif + +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 + +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h! + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* Unimplemented: allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ + +#define SO_DONTLINGER ((int)(~SO_LINGER)) + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ + + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ + + +#define AF_UNSPEC 0 +#define AF_INET 2 +#define PF_INET AF_INET +#define PF_UNSPEC AF_UNSPEC + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#define IPPROTO_UDPLITE 136 + +/* Flags we can use with send and recv. */ +#define MSG_PEEK 0x01 /* Peeks at an incoming message */ +#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ +#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ +#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ + + +/* + * Options for level IPPROTO_IP + */ +#define IP_TOS 1 +#define IP_TTL 2 + +#if LWIP_TCP +/* + * Options for level IPPROTO_TCP + */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ +#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ +#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ +#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#endif /* LWIP_TCP */ + +#if LWIP_UDP && LWIP_UDPLITE +/* + * Options for level IPPROTO_UDPLITE + */ +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif /* LWIP_UDP && LWIP_UDPLITE*/ + + +#if LWIP_IGMP +/* + * Options and types for UDP multicast traffic handling + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +} ip_mreq; +#endif /* LWIP_IGMP */ + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWCOST 0x02 +#define IPTOS_MINCOST IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * lwip_ioctl only supports FIONREAD and FIONBIO, for now + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#if !defined(FIONREAD) || !defined(FIONBIO) +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#endif + +/* Socket I/O Controls: unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#endif + +/* Socket flags: */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 04000U +#endif + +/* FD_SET used for lwip_select */ +#ifndef FD_SET + #undef FD_SETSIZE + /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ + #define FD_SETSIZE MEMP_NUM_NETCONN + #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) + #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) + #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) + #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) + + typedef struct fd_set { + unsigned char fd_bits [(FD_SETSIZE+7)/8]; + } fd_set; + +#endif /* FD_SET */ + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 1 +#endif + +#if LWIP_TIMEVAL_PRIVATE +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif /* LWIP_TIMEVAL_PRIVATE */ + +void lwip_socket_init(void); + +int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_shutdown(int s, int how); +int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); +int lwip_close(int s); +int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_listen(int s, int backlog); +int lwip_recv(int s, void *mem, size_t len, int flags); +int lwip_read(int s, void *mem, size_t len); +int lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); +int lwip_send(int s, const void *dataptr, size_t size, int flags); +int lwip_sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +int lwip_socket(int domain, int type, int protocol); +int lwip_write(int s, const void *dataptr, size_t size); +int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +int lwip_ioctl(int s, long cmd, void *argp); + +#if LWIP_COMPAT_SOCKETS +#define accept(a,b,c) lwip_accept(a,b,c) +#define bind(a,b,c) lwip_bind(a,b,c) +#define shutdown(a,b) lwip_shutdown(a,b) +#define closesocket(s) lwip_close(s) +#define connect(a,b,c) lwip_connect(a,b,c) +#define getsockname(a,b,c) lwip_getsockname(a,b,c) +#define getpeername(a,b,c) lwip_getpeername(a,b,c) +#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) +#define listen(a,b) lwip_listen(a,b) +#define recv(a,b,c,d) lwip_recv(a,b,c,d) +#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) +#define send(a,b,c,d) lwip_send(a,b,c,d) +#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) +#define socket(a,b,c) lwip_socket(a,b,c) +#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) +#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) + +#if LWIP_POSIX_SOCKETS_IO_NAMES +#define read(a,b,c) lwip_read(a,b,c) +#define write(a,b,c) lwip_write(a,b,c) +#define close(s) lwip_close(s) +#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ + +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SOCKET */ + +#endif /* __LWIP_SOCKETS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/stats.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/stats.h new file mode 100644 index 0000000..99878dc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/stats.h @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_STATS_H__ +#define __LWIP_STATS_H__ + +#include "lwip/opt.h" + +#include "lwip/mem.h" +#include "lwip/memp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_STATS + +#ifndef LWIP_STATS_LARGE +#define LWIP_STATS_LARGE 0 +#endif + +#if LWIP_STATS_LARGE +#define STAT_COUNTER u32_t +#define STAT_COUNTER_F U32_F +#else +#define STAT_COUNTER u16_t +#define STAT_COUNTER_F U16_F +#endif + +struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER cachehit; +}; + +struct stats_igmp { + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER v1_rxed; /* */ + STAT_COUNTER join_sent; /* */ + STAT_COUNTER leave_sent; /* */ + STAT_COUNTER unicast_query; /* */ + STAT_COUNTER report_sent; /* */ + STAT_COUNTER report_rxed; /* */ + STAT_COUNTER group_query_rxed; /* */ +}; + +struct stats_mem { + mem_size_t avail; + mem_size_t used; + mem_size_t max; + STAT_COUNTER err; + STAT_COUNTER illegal; +}; + +struct stats_syselem { + STAT_COUNTER used; + STAT_COUNTER max; + STAT_COUNTER err; +}; + +struct stats_sys { + struct stats_syselem sem; + struct stats_syselem mbox; +}; + +struct stats_ { +#if LINK_STATS + struct stats_proto link; +#endif +#if ETHARP_STATS + struct stats_proto etharp; +#endif +#if IPFRAG_STATS + struct stats_proto ip_frag; +#endif +#if IP_STATS + struct stats_proto ip; +#endif +#if ICMP_STATS + struct stats_proto icmp; +#endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif +#if UDP_STATS + struct stats_proto udp; +#endif +#if TCP_STATS + struct stats_proto tcp; +#endif +#if MEM_STATS + struct stats_mem mem; +#endif +#if MEMP_STATS + struct stats_mem memp[MEMP_MAX]; +#endif +#if SYS_STATS + struct stats_sys sys; +#endif +}; + +extern struct stats_ lwip_stats; + +#define stats_init() /* Compatibility define, not init needed. */ + +#define STATS_INC(x) ++lwip_stats.x +#define STATS_DEC(x) --lwip_stats.x +#else +#define stats_init() +#define STATS_INC(x) +#define STATS_DEC(x) +#endif /* LWIP_STATS */ + +#if TCP_STATS +#define TCP_STATS_INC(x) STATS_INC(x) +#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") +#else +#define TCP_STATS_INC(x) +#define TCP_STATS_DISPLAY() +#endif + +#if UDP_STATS +#define UDP_STATS_INC(x) STATS_INC(x) +#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") +#else +#define UDP_STATS_INC(x) +#define UDP_STATS_DISPLAY() +#endif + +#if ICMP_STATS +#define ICMP_STATS_INC(x) STATS_INC(x) +#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") +#else +#define ICMP_STATS_INC(x) +#define ICMP_STATS_DISPLAY() +#endif + +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp) +#else +#define IGMP_STATS_INC(x) +#define IGMP_STATS_DISPLAY() +#endif + +#if IP_STATS +#define IP_STATS_INC(x) STATS_INC(x) +#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") +#else +#define IP_STATS_INC(x) +#define IP_STATS_DISPLAY() +#endif + +#if IPFRAG_STATS +#define IPFRAG_STATS_INC(x) STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") +#else +#define IPFRAG_STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() +#endif + +#if ETHARP_STATS +#define ETHARP_STATS_INC(x) STATS_INC(x) +#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") +#else +#define ETHARP_STATS_INC(x) +#define ETHARP_STATS_DISPLAY() +#endif + +#if LINK_STATS +#define LINK_STATS_INC(x) STATS_INC(x) +#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") +#else +#define LINK_STATS_INC(x) +#define LINK_STATS_DISPLAY() +#endif + +#if MEM_STATS +#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y +#define MEM_STATS_INC(x) STATS_INC(mem.x) +#define MEM_STATS_INC_USED(x, y) do { lwip_stats.mem.used += y; \ + if (lwip_stats.mem.max < lwip_stats.mem.used) { \ + lwip_stats.mem.max = lwip_stats.mem.used; \ + } \ + } while(0) +#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y +#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") +#else +#define MEM_STATS_AVAIL(x, y) +#define MEM_STATS_INC(x) +#define MEM_STATS_INC_USED(x, y) +#define MEM_STATS_DEC_USED(x, y) +#define MEM_STATS_DISPLAY() +#endif + +#if MEMP_STATS +#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y +#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) +#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) +#define MEMP_STATS_INC_USED(x, i) do { ++lwip_stats.memp[i].used; \ + if (lwip_stats.memp[i].max < lwip_stats.memp[i].used) { \ + lwip_stats.memp[i].max = lwip_stats.memp[i].used; \ + } \ + } while(0) +#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) +#else +#define MEMP_STATS_AVAIL(x, i, y) +#define MEMP_STATS_INC(x, i) +#define MEMP_STATS_DEC(x, i) +#define MEMP_STATS_INC_USED(x, i) +#define MEMP_STATS_DISPLAY(i) +#endif + +#if SYS_STATS +#define SYS_STATS_INC(x) STATS_INC(sys.x) +#define SYS_STATS_DEC(x) STATS_DEC(sys.x) +#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) +#else +#define SYS_STATS_INC(x) +#define SYS_STATS_DEC(x) +#define SYS_STATS_DISPLAY() +#endif + +/* Display of statistics */ +#if LWIP_STATS_DISPLAY +void stats_display(void); +void stats_display_proto(struct stats_proto *proto, char *name); +void stats_display_igmp(struct stats_igmp *igmp); +void stats_display_mem(struct stats_mem *mem, char *name); +void stats_display_memp(struct stats_mem *mem, int index); +void stats_display_sys(struct stats_sys *sys); +#else +#define stats_display() +#define stats_display_proto(proto, name) +#define stats_display_igmp(igmp) +#define stats_display_mem(mem, name) +#define stats_display_memp(mem, index) +#define stats_display_sys(sys) +#endif /* LWIP_STATS_DISPLAY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_STATS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sys.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sys.h new file mode 100644 index 0000000..b9a85ee --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/sys.h @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_SYS_H__ +#define __LWIP_SYS_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ +typedef u8_t sys_sem_t; +typedef u8_t sys_mbox_t; +struct sys_timeo {u8_t dummy;}; + +#define sys_init() +#define sys_timeout(m,h,a) +#define sys_untimeout(m,a) +#define sys_sem_new(c) c +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_sem_wait_timeout(s,t) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_mbox_new(s) 0 +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) + +#define sys_thread_new(n,t,a,s,p) + +#else /* NO_SYS */ + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/* sys_mbox_tryfetch returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +typedef void (* sys_timeout_handler)(void *arg); + +struct sys_timeo { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +}; + +struct sys_timeouts { + struct sys_timeo *next; +}; + +/* sys_init() must be called before anthing else. */ +void sys_init(void); + +/* + * sys_timeout(): + * + * Schedule a timeout a specified amount of milliseconds in the + * future. When the timeout occurs, the specified timeout handler will + * be called. The handler will be passed the "arg" argument when + * called. + * + */ +void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +void sys_untimeout(sys_timeout_handler h, void *arg); +struct sys_timeouts *sys_arch_timeouts(void); + +/* Semaphore functions. */ +sys_sem_t sys_sem_new(u8_t count); +void sys_sem_signal(sys_sem_t sem); +u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout); +void sys_sem_free(sys_sem_t sem); +void sys_sem_wait(sys_sem_t sem); +int sys_sem_wait_timeout(sys_sem_t sem, u32_t timeout); + +/* Time functions. */ +#ifndef sys_msleep +void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ +#endif +#ifndef sys_jiffies +u32_t sys_jiffies(void); /* since power up. */ +#endif + +/* Mailbox functions. */ +sys_mbox_t sys_mbox_new(int size); +void sys_mbox_post(sys_mbox_t mbox, void *msg); +err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg); +u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout); +#ifndef sys_arch_mbox_tryfetch /* Allow port to override with a macro */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg); +#endif +/* For now, we map straight to sys_arch implementation. */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +void sys_mbox_free(sys_mbox_t mbox); +void sys_mbox_fetch(sys_mbox_t mbox, void **msg); + +/* Thread functions. */ +sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio); + +#endif /* NO_SYS */ + +/** Returns the current time in milliseconds. */ +u32_t sys_now(void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SYS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcp.h new file mode 100644 index 0000000..43004de --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcp.h @@ -0,0 +1,707 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_H__ +#define __LWIP_TCP_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct tcp_pcb; + +/* Functions for interfacing with TCP: */ + +/* Lower layer interface to TCP: */ +#define tcp_init() /* Compatibility define, not init needed. */ +void tcp_tmr (void); /* Must be called every + TCP_TMR_INTERVAL + ms. (Typically 250 ms). */ +/* Application program's interface: */ +struct tcp_pcb * tcp_new (void); +struct tcp_pcb * tcp_alloc (u8_t prio); + +void tcp_arg (struct tcp_pcb *pcb, void *arg); +void tcp_accept (struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, + err_t err)); +void tcp_recv (struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err)); +void tcp_sent (struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, + u16_t len)); +void tcp_poll (struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval); +void tcp_err (struct tcp_pcb *pcb, + void (* err)(void *arg, err_t err)); + +#define tcp_mss(pcb) ((pcb)->mss) +#define tcp_sndbuf(pcb) ((pcb)->snd_buf) +#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) +#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) +#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) + +#if TCP_LISTEN_BACKLOG +#define tcp_accepted(pcb) (((struct tcp_pcb_listen *)(pcb))->accepts_pending--) +#else /* TCP_LISTEN_BACKLOG */ +#define tcp_accepted(pcb) +#endif /* TCP_LISTEN_BACKLOG */ + +void tcp_recved (struct tcp_pcb *pcb, u16_t len); +err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port); +err_t tcp_connect (struct tcp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port, err_t (* connected)(void *arg, + struct tcp_pcb *tpcb, + err_t err)); + +struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +void tcp_abandon (struct tcp_pcb *pcb, int reset); +#define tcp_abort(pcb) tcp_abandon((pcb), 1) +err_t tcp_close (struct tcp_pcb *pcb); + +/* Flags for "apiflags" parameter in tcp_write and tcp_enqueue */ +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + +err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); + +void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); + +#define TCP_PRIO_MIN 1 +#define TCP_PRIO_NORMAL 64 +#define TCP_PRIO_MAX 127 + +/* It is also possible to call these two functions at the right + intervals (instead of calling tcp_tmr()). */ +void tcp_slowtmr (void); +void tcp_fasttmr (void); + + +/* Only used by IP to pass a TCP segment to TCP: */ +void tcp_input (struct pbuf *p, struct netif *inp); +/* Used within the TCP code only: */ +err_t tcp_send_empty_ack(struct tcp_pcb *pcb); +err_t tcp_output (struct tcp_pcb *pcb); +void tcp_rexmit (struct tcp_pcb *pcb); +void tcp_rexmit_rto (struct tcp_pcb *pcb); +void tcp_rexmit_fast (struct tcp_pcb *pcb); +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); + +/** + * This is the Nagle algorithm: try to combine user data to send as few TCP + * segments as possible. Only send if + * - no previously transmitted data on the connection remains unacknowledged or + * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or + * - the only unsent segment is at least pcb->mss bytes long (or there is more + * than one unsent segment - with lwIP, this can happen although unsent->len < mss) + * - or if we are in fast-retransmit (TF_INFR) + */ +#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ + ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ + (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ + ((tpcb)->unsent->len >= (tpcb)->mss))) \ + ) ? 1 : 0) +#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) + + +#define TCP_SEQ_LT(a,b) ((s32_t)((a)-(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((a)-(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((a)-(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((a)-(b)) >= 0) +/* is b<=a<=c? */ +#if 0 /* see bug #10548 */ +#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) +#endif +#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U + +#define TCP_FLAGS 0x3fU + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +#ifndef TCP_TMR_INTERVAL +#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ +#endif /* TCP_TMR_INTERVAL */ + +#ifndef TCP_FAST_INTERVAL +#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ +#endif /* TCP_FAST_INTERVAL */ + +#ifndef TCP_SLOW_INTERVAL +#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ +#endif /* TCP_SLOW_INTERVAL */ + +#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ +#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ + +#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ + +#ifndef TCP_MSL +#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ +#endif + +/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ +#ifndef TCP_KEEPIDLE_DEFAULT +#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ +#endif + +#ifndef TCP_KEEPINTVL_DEFAULT +#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ +#endif + +#ifndef TCP_KEEPCNT_DEFAULT +#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ +#endif + +#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define TCPH_OFFSET(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 8) +#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) +#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) + +#define TCPH_OFFSET_SET(phdr, offset) (phdr)->_hdrlen_rsvd_flags = htons(((offset) << 8) | TCPH_FLAGS(phdr)) +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & htons((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) + +#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) + +enum tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + +/** Flags used on input processing, not on pcb->flags +*/ +#define TF_RESET (u8_t)0x08U /* Connection was reset. */ +#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ +#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ + + +#if LWIP_CALLBACK_API + /* Function to call when a listener has been connected. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb a new tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: accept the new connection, + * any other err_t abortsthe new connection + */ +#define DEF_ACCEPT_CALLBACK err_t (* accept)(void *arg, struct tcp_pcb *newpcb, err_t err) +#else /* LWIP_CALLBACK_API */ +#define DEF_ACCEPT_CALLBACK +#endif /* LWIP_CALLBACK_API */ + +/** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +#define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + void *callback_arg; \ + /* ports are in host byte order */ \ + u16_t local_port; \ + /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ + DEF_ACCEPT_CALLBACK + + +/* the TCP protocol control block */ +struct tcp_pcb { +/** common PCB members */ + IP_PCB; +/** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); + + /* ports are in host byte order */ + u16_t remote_port; + + u8_t flags; +#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ +#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ +#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ +#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ +#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ + + /* the rest of the fields are in host byte order + as we have to do some math with them */ + /* receiver variables */ + u32_t rcv_nxt; /* next seqno expected */ + u16_t rcv_wnd; /* receiver window available */ + u16_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ + + /* Timers */ + u32_t tmr; + u8_t polltmr, pollinterval; + + /* Retransmission timer. */ + s16_t rtime; + + u16_t mss; /* maximum segment size */ + + /* RTT (round trip time) estimation variables */ + u32_t rttest; /* RTT estimate in 500ms ticks */ + u32_t rtseq; /* sequence number being timed */ + s16_t sa, sv; /* @todo document this */ + + s16_t rto; /* retransmission time-out */ + u8_t nrtx; /* number of retransmissions */ + + /* fast retransmit/recovery */ + u32_t lastack; /* Highest acknowledged seqno. */ + u8_t dupacks; + + /* congestion avoidance/control variables */ + u16_t cwnd; + u16_t ssthresh; + + /* sender variables */ + u32_t snd_nxt; /* next new seqno to be sent */ + u16_t snd_wnd; /* sender window */ + u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last + window update. */ + u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + + u16_t acked; + + u16_t snd_buf; /* Available buffer space for sending (in bytes). */ +#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3) + u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ + + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +#if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ +#endif /* TCP_QUEUE_OOSEQ */ + + struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ + +#if LWIP_CALLBACK_API + /* Function to be called when more send buffer space is available. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb the tcp_pcb which has send buffer space available + * @param space the amount of bytes available + * @return ERR_OK: try to send some data by calling tcp_output + */ + err_t (* sent)(void *arg, struct tcp_pcb *pcb, u16_t space); + + /* Function to be called when (in-sequence) data has arrived. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb the tcp_pcb for which data has arrived + * @param p the packet buffer which arrived + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: try to send some data by calling tcp_output + */ + err_t (* recv)(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); + + /* Function to be called when a connection has been set up. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb the tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return value is currently ignored + */ + err_t (* connected)(void *arg, struct tcp_pcb *pcb, err_t err); + + /* Function which is called periodically. + * The period can be adjusted in multiples of the TCP slow timer interval + * by changing tcp_pcb.polltmr. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb the tcp_pcb to poll for + * @return ERR_OK: try to send some data by calling tcp_output + */ + err_t (* poll)(void *arg, struct tcp_pcb *pcb); + + /* Function to be called whenever a fatal error occurs. + * There is no pcb parameter since most of the times, the pcb is + * already deallocated (or there is no pcb) when this function is called. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param err an indication why the error callback is called: + * ERR_ABRT: aborted through tcp_abort or by a TCP timer + * ERR_RST: the connection was reset by the remote host + */ + void (* errf)(void *arg, err_t err); +#endif /* LWIP_CALLBACK_API */ + +#if LWIP_TCP_TIMESTAMPS + u32_t ts_lastacksent; + u32_t ts_recent; +#endif /* LWIP_TCP_TIMESTAMPS */ + + /* idle time before KEEPALIVE is sent */ + u32_t keep_idle; +#if LWIP_TCP_KEEPALIVE + u32_t keep_intvl; + u32_t keep_cnt; +#endif /* LWIP_TCP_KEEPALIVE */ + + /* Persist timer counter */ + u32_t persist_cnt; + /* Persist timer back-off */ + u8_t persist_backoff; + + /* KEEPALIVE counter */ + u8_t keep_cnt_sent; +}; + +struct tcp_pcb_listen { +/* Common members of all PCB types */ + IP_PCB; +/* Protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb_listen); + +#if TCP_LISTEN_BACKLOG + u8_t backlog; + u8_t accepts_pending; +#endif /* TCP_LISTEN_BACKLOG */ +}; + +#if LWIP_EVENT_API + +enum lwip_event { + LWIP_EVENT_ACCEPT, + LWIP_EVENT_SENT, + LWIP_EVENT_RECV, + LWIP_EVENT_CONNECTED, + LWIP_EVENT_POLL, + LWIP_EVENT_ERR +}; + +err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, + enum lwip_event, + struct pbuf *p, + u16_t size, + err_t err); + +#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_ACCEPT, NULL, 0, err) +#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_SENT, NULL, space, ERR_OK) +#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, (p), 0, (err)) +#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_CONNECTED, NULL, 0, (err)) +#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_POLL, NULL, 0, ERR_OK) +#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ + LWIP_EVENT_ERR, NULL, 0, (err)) +#else /* LWIP_EVENT_API */ + +#define TCP_EVENT_ACCEPT(pcb,err,ret) \ + do { \ + if((pcb)->accept != NULL) \ + (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_SENT(pcb,space,ret) \ + do { \ + if((pcb)->sent != NULL) \ + (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_RECV(pcb,p,err,ret) \ + do { \ + if((pcb)->recv != NULL) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err)); \ + } else { \ + (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ + } \ + } while (0) + +#define TCP_EVENT_CONNECTED(pcb,err,ret) \ + do { \ + if((pcb)->connected != NULL) \ + (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_POLL(pcb,ret) \ + do { \ + if((pcb)->poll != NULL) \ + (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_ERR(errf,arg,err) \ + do { \ + if((errf) != NULL) \ + (errf)((arg),(err)); \ + } while (0) + +#endif /* LWIP_EVENT_API */ + +/* This structure represents a TCP segment on the unsent and unacked queues */ +struct tcp_seg { + struct tcp_seg *next; /* used when putting segements on a queue */ + struct pbuf *p; /* buffer containing data + TCP header */ + void *dataptr; /* pointer to the TCP data in the pbuf */ + u16_t len; /* the TCP length of this segment */ + u8_t flags; +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ + struct tcp_hdr *tcphdr; /* the TCP header */ +}; + +#define LWIP_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ + (flags & TF_SEG_OPTS_TS ? 12 : 0) + +/** This returns a TCP header option for MSS in an u32_t */ +#define TCP_BUILD_MSS_OPTION(x) (x) = htonl(((u32_t)2 << 24) | \ + ((u32_t)4 << 16) | \ + (((u32_t)TCP_MSS / 256) << 8) | \ + (TCP_MSS & 255)) + +/* Internal functions and global variables: */ +struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); +void tcp_pcb_purge(struct tcp_pcb *pcb); +void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); + +u8_t tcp_segs_free(struct tcp_seg *seg); +u8_t tcp_seg_free(struct tcp_seg *seg); +struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); + +#define tcp_ack(pcb) \ + do { \ + if((pcb)->flags & TF_ACK_DELAY) { \ + (pcb)->flags &= ~TF_ACK_DELAY; \ + (pcb)->flags |= TF_ACK_NOW; \ + tcp_output(pcb); \ + } \ + else { \ + (pcb)->flags |= TF_ACK_DELAY; \ + } \ + } while (0) + +#define tcp_ack_now(pcb) \ + do { \ + (pcb)->flags |= TF_ACK_NOW; \ + tcp_output(pcb); \ + } while (0) + +err_t tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags); +err_t tcp_enqueue(struct tcp_pcb *pcb, void *dataptr, u16_t len, + u8_t flags, u8_t apiflags, u8_t optflags); + +void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); + +void tcp_rst(u32_t seqno, u32_t ackno, + struct ip_addr *local_ip, struct ip_addr *remote_ip, + u16_t local_port, u16_t remote_port); + +u32_t tcp_next_iss(void); + +void tcp_keepalive(struct tcp_pcb *pcb); +void tcp_zero_window_probe(struct tcp_pcb *pcb); + +#if TCP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss(u16_t sendmss, struct ip_addr *addr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +#if LWIP_CALLBACK_API +err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +#endif /* LWIP_CALLBACK_API */ + +extern struct tcp_pcb *tcp_input_pcb; +extern u32_t tcp_ticks; + +const char* tcp_debug_state_str(enum tcp_state s); +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +void tcp_debug_print(struct tcp_hdr *tcphdr); +void tcp_debug_print_flags(u8_t flags); +void tcp_debug_print_state(enum tcp_state s); +void tcp_debug_print_pcbs(void); +s16_t tcp_pcbs_sane(void); +#else +# define tcp_debug_print(tcphdr) +# define tcp_debug_print_flags(flags) +# define tcp_debug_print_state(s) +# define tcp_debug_print_pcbs() +# define tcp_pcbs_sane() 1 +#endif /* TCP_DEBUG */ + +#if NO_SYS +#define tcp_timer_needed() +#else +void tcp_timer_needed(void); +#endif + +/* The TCP PCB lists. */ +union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ + struct tcp_pcb_listen *listen_pcbs; + struct tcp_pcb *pcbs; +}; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ + +/* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. + 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. + 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. +*/ + +/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB + with a PCB list or removes a PCB from a list, respectively. */ +#if 0 +#define TCP_REG(pcbs, npcb) do {\ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", npcb, npcb->local_port)); \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != npcb); \ + } \ + LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", npcb->state != CLOSED); \ + npcb->next = *pcbs; \ + LWIP_ASSERT("TCP_REG: npcb->next != npcb", npcb->next != npcb); \ + *(pcbs) = npcb; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + tcp_timer_needed(); \ + } while(0) +#define TCP_RMV(pcbs, npcb) do { \ + LWIP_ASSERT("TCP_RMV: pcbs != NULL", *pcbs != NULL); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", npcb, *pcbs)); \ + if(*pcbs == npcb) { \ + *pcbs = (*pcbs)->next; \ + } else for(tcp_tmp_pcb = *pcbs; tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == npcb) { \ + tcp_tmp_pcb->next = npcb->next; \ + break; \ + } \ + } \ + npcb->next = NULL; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", npcb, *pcbs)); \ + } while(0) + +#else /* LWIP_DEBUG */ + +#define TCP_REG(pcbs, npcb) \ + do { \ + npcb->next = *pcbs; \ + *(pcbs) = npcb; \ + tcp_timer_needed(); \ + } while (0) + +#define TCP_RMV(pcbs, npcb) \ + do { \ + if(*(pcbs) == npcb) { \ + (*(pcbs)) = (*pcbs)->next; \ + } \ + else { \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == npcb) { \ + tcp_tmp_pcb->next = npcb->next; \ + break; \ + } \ + } \ + } \ + npcb->next = NULL; \ + } while(0) + +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcpip.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcpip.h new file mode 100644 index 0000000..8bfbaf7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/tcpip.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ +#ifndef __LWIP_TCPIP_H__ +#define __LWIP_TCPIP_H__ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" +#include "lwip/netifapi.h" +#include "lwip/pbuf.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_sem_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_sem_wait(lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_sem_signal(lock_tcpip_core) +#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m) +#define TCPIP_APIMSG_ACK(m) +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) +#else +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG(m) tcpip_apimsg(m) +#define TCPIP_APIMSG_ACK(m) sys_sem_signal(m->conn->op_completed) +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(m->sem) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +void tcpip_init(void (* tcpip_init_done)(void *), void *arg); + +#if LWIP_NETCONN +err_t tcpip_apimsg(struct api_msg *apimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_apimsg_lock(struct api_msg *apimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +err_t tcpip_input(struct pbuf *p, struct netif *inp); + +#if LWIP_NETIF_API +err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +err_t tcpip_callback_with_block(void (*f)(void *ctx), void *ctx, u8_t block); +#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) + +/* free pbufs or heap memory from another context without blocking */ +err_t pbuf_free_callback(struct pbuf *p); +err_t mem_free_callback(void *m); + +err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +err_t tcpip_untimeout(sys_timeout_handler h, void *arg); + +enum tcpip_msg_type { +#if LWIP_NETCONN + TCPIP_MSG_API, +#endif /* LWIP_NETCONN */ + TCPIP_MSG_INPKT, +#if LWIP_NETIF_API + TCPIP_MSG_NETIFAPI, +#endif /* LWIP_NETIF_API */ + TCPIP_MSG_CALLBACK, + TCPIP_MSG_TIMEOUT, + TCPIP_MSG_UNTIMEOUT +}; + +struct tcpip_msg { + enum tcpip_msg_type type; + sys_sem_t *sem; + union { +#if LWIP_NETCONN + struct api_msg *apimsg; +#endif /* LWIP_NETCONN */ +#if LWIP_NETIF_API + struct netifapi_msg *netifapimsg; +#endif /* LWIP_NETIF_API */ + struct { + struct pbuf *p; + struct netif *netif; + } inp; + struct { + void (*f)(void *ctx); + void *ctx; + } cb; + struct { + u32_t msecs; + sys_timeout_handler h; + void *arg; + } tmo; + } msg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !NO_SYS */ + +#endif /* __LWIP_TCPIP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/udp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/udp.h new file mode 100644 index 0000000..e441dac --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/lwip/udp.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_UDP_H__ +#define __LWIP_UDP_H__ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define UDP_FLAGS_NOCHKSUM 0x01U +#define UDP_FLAGS_UDPLITE 0x02U +#define UDP_FLAGS_CONNECTED 0x04U + +struct udp_pcb { +/* Common members of all PCB types */ + IP_PCB; + +/* Protocol specific PCB members */ + + struct udp_pcb *next; + + u8_t flags; + /* ports are in host byte order */ + u16_t local_port, remote_port; + +#if LWIP_IGMP + /* outgoing network interface for multicast packets */ + struct ip_addr multicast_ip; +#endif /* LWIP_IGMP */ + +#if LWIP_UDPLITE + /* used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +#endif /* LWIP_UDPLITE */ + + /* receive callback function + * addr and port are in same byte order as in the pcb + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf + * makes 'addr' invalid, too. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @param port the remote port from which the packet was received + */ + void (* recv)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + struct ip_addr *addr, u16_t port); + /* user-supplied argument for the recv callback */ + void *recv_arg; +}; +/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ +extern struct udp_pcb *udp_pcbs; + +/* The following functions is the application layer interface to the + UDP code. */ +struct udp_pcb * udp_new (void); +void udp_remove (struct udp_pcb *pcb); +err_t udp_bind (struct udp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port); +err_t udp_connect (struct udp_pcb *pcb, struct ip_addr *ipaddr, + u16_t port); +void udp_disconnect (struct udp_pcb *pcb); +void udp_recv (struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, + struct pbuf *p, + struct ip_addr *addr, + u16_t port), + void *recv_arg); +err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif); +err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port); +err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); + +#define udp_flags(pcb) ((pcb)->flags) +#define udp_setflags(pcb, f) ((pcb)->flags = (f)) + +/* The following functions are the lower layer interface to UDP. */ +void udp_input (struct pbuf *p, struct netif *inp); + +#define udp_init() /* Compatibility define, not init needed. */ + +#if UDP_DEBUG +void udp_debug_print(struct udp_hdr *udphdr); +#else +#define udp_debug_print(udphdr) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_UDP */ + +#endif /* __LWIP_UDP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/etharp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/etharp.h new file mode 100644 index 0000000..847f605 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/etharp.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + **/ + +#ifndef __NETIF_ETHARP_H__ +#define __NETIF_ETHARP_H__ + +#include "lwip/opt.h" + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN 6 +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FIELD(struct eth_addr dest); + PACK_STRUCT_FIELD(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#if ETHARP_SUPPORT_VLAN + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t tpid); + PACK_STRUCT_FIELD(u16_t prio_vid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) + +#endif /* ETHARP_SUPPORT_VLAN */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FIELD(u16_t _hwlen_protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FIELD(struct eth_addr shwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); + PACK_STRUCT_FIELD(struct eth_addr dhwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 +#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) + +/** 5 seconds period */ +#define ARP_TMR_INTERVAL 1000 + +#define ETHTYPE_ARP 0x0806 +#define ETHTYPE_IP 0x0800 +#define ETHTYPE_VLAN 0x8100 +#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */ + +/** ARP message types (opcodes) */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +#if ARP_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct etharp_q_entry { + struct etharp_q_entry *next; + struct pbuf *p; +}; +#endif /* ARP_QUEUEING */ + +#define etharp_init() /* Compatibility define, not init needed. */ +void etharp_tmr(void); +s8_t etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr, + struct eth_addr **eth_ret, struct ip_addr **ip_ret); +void etharp_ip_input(struct netif *netif, struct pbuf *p); +void etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, + struct pbuf *p); +err_t etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr); +err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q); +err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr); +/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; + * this is an ARP packet sent by a node in order to spontaneously cause other + * nodes to update an entry in their ARP cache. + * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ +#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) + +err_t ethernet_input(struct pbuf *p, struct netif *netif); + +#if LWIP_AUTOIP +err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const struct ip_addr *ipsrc_addr, + const struct eth_addr *hwdst_addr, const struct ip_addr *ipdst_addr, + const u16_t opcode); +#endif /* LWIP_AUTOIP */ + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) + +extern const struct eth_addr ethbroadcast, ethzero; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ARP */ + +#endif /* __NETIF_ARP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/loopif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/loopif.h new file mode 100644 index 0000000..304af4b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/loopif.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_LOOPIF_H__ +#define __NETIF_LOOPIF_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +#define loopif_poll netif_poll +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ + +err_t loopif_init(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETIF_LOOPIF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/ppp_oe.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/ppp_oe.h new file mode 100644 index 0000000..ee9408a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/ppp_oe.h @@ -0,0 +1,161 @@ +/** +* ppp_oe.h - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +**/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PPP_OE_H +#define PPP_OE_H + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT > 0 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoehdr { + PACK_STRUCT_FIELD(u8_t vertype); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t session); + PACK_STRUCT_FIELD(u16_t plen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoetag { + PACK_STRUCT_FIELD(u16_t tag); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#define PPPOE_STATE_INITIAL 0 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +#define PPPOE_STATE_CLOSING 4 +/* passive */ +#define PPPOE_STATE_PADO_SENT 1 + +#define PPPOE_HEADERLEN sizeof(struct pppoehdr) +#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ + +#define PPPOE_TAG_EOL 0x0000 /* end of list */ +#define PPPOE_TAG_SNAME 0x0101 /* service name */ +#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ +#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ +#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ +#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ +#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ +#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ +#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ +#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ + +#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ +#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ +#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ +#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ +#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ + +#ifndef ETHERMTU +#define ETHERMTU 1500 +#endif + +/* two byte PPP protocol discriminator, then IP data */ +#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) + +struct pppoe_softc; + + +void pppoe_init(void); + +err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_destroy(struct netif *ifp); + +int pppoe_connect(struct pppoe_softc *sc); +void pppoe_disconnect(struct pppoe_softc *sc); + +void pppoe_disc_input(struct netif *netif, struct pbuf *p); +void pppoe_data_input(struct netif *netif, struct pbuf *p); + +err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); + +extern int pppoe_hdrlen; + +#endif /* PPPOE_SUPPORT */ + +#endif /* PPP_OE_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/slipif.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/slipif.h new file mode 100644 index 0000000..ccd03c8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/include/netif/slipif.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_SLIPIF_H__ +#define __NETIF_SLIPIF_H__ + +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +err_t slipif_init(struct netif * netif); +void slipif_poll(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/FILES b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/FILES new file mode 100644 index 0000000..099dbf3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/FILES @@ -0,0 +1,29 @@ +This directory contains generic network interface device drivers that +do not contain any hardware or architecture specific code. The files +are: + +etharp.c + Implements the ARP (Address Resolution Protocol) over + Ethernet. The code in this file should be used together with + Ethernet device drivers. Note that this module has been + largely made Ethernet independent so you should be able to + adapt this for other link layers (such as Firewire). + +ethernetif.c + An example of how an Ethernet device driver could look. This + file can be used as a "skeleton" for developing new Ethernet + network device drivers. It uses the etharp.c ARP code. + +loopif.c + A "loopback" network interface driver. It requires configuration + through the define LWIP_LOOPIF_MULTITHREADING (see opt.h). + +slipif.c + A generic implementation of the SLIP (Serial Line IP) + protocol. It requires a sio (serial I/O) module to work. + +ppp/ Point-to-Point Protocol stack + The PPP stack has been ported from ucip (http://ucip.sourceforge.net). + It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although + compared to that, it has some modifications for embedded systems and + the source code has been reordered a bit. \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/etharp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/etharp.c new file mode 100644 index 0000000..28b2111 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/etharp.c @@ -0,0 +1,1235 @@ +/* + * @file + * Address Resolution Protocol module for IP over Ethernet + * + * Functionally, ARP is divided into two parts. The first maps an IP address + * to a physical address when sending a packet, and the second part answers + * requests from other machines for our physical address. + * + * This implementation complies with RFC 826 (Ethernet ARP). It supports + * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 + * if an interface calls etharp_gratuitous(our_netif) upon address change. + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/inet.h" +#include "lwip/ip.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include + +/** the time an ARP entry stays valid after its last update, + * for ARP_TMR_INTERVAL = 5000, this is + * (240 * 5) seconds = 20 minutes. + */ +#define ARP_MAXAGE 240 +/** the time an ARP entry stays pending after first request, + * for ARP_TMR_INTERVAL = 5000, this is + * (2 * 5) seconds = 10 seconds. + * + * @internal Keep this number at least 2, otherwise it might + * run out instantly if the timeout occurs directly after a request. + */ +#define ARP_MAXPENDING 2 + +#define HWTYPE_ETHERNET 1 + +#define ARPH_HWLEN(hdr) (ntohs((hdr)->_hwlen_protolen) >> 8) +#define ARPH_PROTOLEN(hdr) (ntohs((hdr)->_hwlen_protolen) & 0xff) + +#define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons(ARPH_PROTOLEN(hdr) | ((len) << 8)) +#define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = htons((len) | (ARPH_HWLEN(hdr) << 8)) + +enum etharp_state { + ETHARP_STATE_EMPTY = 0, + ETHARP_STATE_PENDING, + ETHARP_STATE_STABLE +}; + +struct etharp_entry { +#if ARP_QUEUEING + /** + * Pointer to queue of pending outgoing packets on this ARP entry. + */ + struct etharp_q_entry *q; +#endif + struct ip_addr ipaddr; + struct eth_addr ethaddr; + enum etharp_state state; + u8_t ctime; + struct netif *netif; +}; + +const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; +const struct eth_addr ethzero = {{0,0,0,0,0,0}}; +static struct etharp_entry arp_table[ARP_TABLE_SIZE]; +#if !LWIP_NETIF_HWADDRHINT +static u8_t etharp_cached_entry; +#endif + +/** + * Try hard to create a new entry - we want the IP address to appear in + * the cache (even if this means removing an active entry or so). */ +#define ETHARP_TRY_HARD 1 +#define ETHARP_FIND_ONLY 2 + +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ + *((netif)->addr_hint) = (hint); +static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif); +#else /* LWIP_NETIF_HWADDRHINT */ +static s8_t find_entry(struct ip_addr *ipaddr, u8_t flags); +#endif /* LWIP_NETIF_HWADDRHINT */ + +static err_t update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags); + + +/* Some checks, instead of etharp_init(): */ +#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) + #error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h" +#endif + + +#if ARP_QUEUEING +/** + * Free a complete queue of etharp entries + * + * @param q a qeueue of etharp_q_entry's to free + */ +static void +free_etharp_q(struct etharp_q_entry *q) +{ + struct etharp_q_entry *r; + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("q->p != NULL", q->p != NULL); + while (q) { + r = q; + q = q->next; + LWIP_ASSERT("r->p != NULL", (r->p != NULL)); + pbuf_free(r->p); + memp_free(MEMP_ARP_QUEUE, r); + } +} +#endif + +/** + * Clears expired entries in the ARP table. + * + * This function should be called every ETHARP_TMR_INTERVAL microseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + arp_table[i].ctime++; + if (((arp_table[i].state == ETHARP_STATE_STABLE) && + (arp_table[i].ctime >= ARP_MAXAGE)) || + ((arp_table[i].state == ETHARP_STATE_PENDING) && + (arp_table[i].ctime >= ARP_MAXPENDING))) { + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state == ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); +#if ARP_QUEUEING + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + arp_table[i].q = NULL; + } +#endif + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; + } +#if ARP_QUEUEING + /* still pending entry? (not expired) */ + if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* resend an ARP query here? */ + } +#endif + } +} + +/** + * Search the ARP table for a matching or new entry. + * + * If an IP address is given, return a pending or stable ARP entry that matches + * the address. If no match is found, create a new entry with this address set, + * but in state ETHARP_EMPTY. The caller must check and possibly change the + * state of the returned entry. + * + * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. + * + * In all cases, attempt to create new entries from an empty entry. If no + * empty entries are available and ETHARP_TRY_HARD flag is set, recycle + * old entries. Heuristic choose the least important entry for recycling. + * + * @param ipaddr IP address to find in ARP cache, or to add if not found. + * @param flags + * - ETHARP_TRY_HARD: Try hard to create a entry by allowing recycling of + * active (stable or pending) entries. + * + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +#if LWIP_NETIF_HWADDRHINT +find_entry(struct ip_addr *ipaddr, u8_t flags, struct netif *netif) +#else /* LWIP_NETIF_HWADDRHINT */ +find_entry(struct ip_addr *ipaddr, u8_t flags) +#endif /* LWIP_NETIF_HWADDRHINT */ +{ + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + s8_t empty = ARP_TABLE_SIZE; + u8_t i = 0, age_pending = 0, age_stable = 0; +#if ARP_QUEUEING + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + /* its age */ + u8_t age_queue = 0; +#endif + + /* First, test if the last call to this function asked for the + * same address. If so, we're really fast! */ + if (ipaddr) { + /* ipaddr to search for was given */ +#if LWIP_NETIF_HWADDRHINT + if ((netif != NULL) && (netif->addr_hint != NULL)) { + /* per-pcb cached entry was given */ + u8_t per_pcb_cache = *(netif->addr_hint); + if ((per_pcb_cache < ARP_TABLE_SIZE) && arp_table[per_pcb_cache].state == ETHARP_STATE_STABLE) { + /* the per-pcb-cached entry is stable */ + if (ip_addr_cmp(ipaddr, &arp_table[per_pcb_cache].ipaddr)) { + /* per-pcb cached entry was the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + return per_pcb_cache; + } + } + } +#else /* #if LWIP_NETIF_HWADDRHINT */ + if (arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE) { + /* the cached entry is stable */ + if (ip_addr_cmp(ipaddr, &arp_table[etharp_cached_entry].ipaddr)) { + /* cached entry was the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + return etharp_cached_entry; + } + } +#endif /* #if LWIP_NETIF_HWADDRHINT */ + } + + /** + * a) do a search through the cache, remember candidates + * b) select candidate entry + * c) create new entry + */ + + /* a) in a single search sweep, do all of this + * 1) remember the first empty entry (if any) + * 2) remember the oldest stable entry (if any) + * 3) remember the oldest pending entry without queued packets (if any) + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (arp_table[i].state == ETHARP_STATE_EMPTY)) { + LWIP_DEBUGF(ETHARP_DEBUG, ("find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + } + /* pending entry? */ + else if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching pending entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ +#if LWIP_NETIF_HWADDRHINT + NETIF_SET_HINT(netif, i); +#else /* #if LWIP_NETIF_HWADDRHINT */ + etharp_cached_entry = i; +#endif /* #if LWIP_NETIF_HWADDRHINT */ + return i; +#if ARP_QUEUEING + /* pending with queued packets? */ + } else if (arp_table[i].q != NULL) { + if (arp_table[i].ctime >= age_queue) { + old_queue = i; + age_queue = arp_table[i].ctime; + } +#endif + /* pending without queued packets? */ + } else { + if (arp_table[i].ctime >= age_pending) { + old_pending = i; + age_pending = arp_table[i].ctime; + } + } + } + /* stable entry? */ + else if (arp_table[i].state == ETHARP_STATE_STABLE) { + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: found matching stable entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ +#if LWIP_NETIF_HWADDRHINT + NETIF_SET_HINT(netif, i); +#else /* #if LWIP_NETIF_HWADDRHINT */ + etharp_cached_entry = i; +#endif /* #if LWIP_NETIF_HWADDRHINT */ + return i; + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + } else if (arp_table[i].ctime >= age_stable) { + old_stable = i; + age_stable = arp_table[i].ctime; + } + } + } + /* { we have no match } => try to create a new entry */ + + /* no empty entry found and not allowed to recycle? */ + if (((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_TRY_HARD) == 0)) + /* or don't create new entry, only search? */ + || ((flags & ETHARP_FIND_ONLY) != 0)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + } + + /* b) choose the least destructive entry to recycle: + * 1) empty entry + * 2) oldest stable entry + * 3) oldest pending entry without queued packets + * 4) oldest pending entry with queued packets + * + * { ETHARP_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + i = empty; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } + /* 2) found recyclable stable entry? */ + else if (old_stable < ARP_TABLE_SIZE) { + /* recycle oldest stable*/ + i = old_stable; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); +#if ARP_QUEUEING + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); +#endif + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + /* recycle oldest pending */ + i = old_pending; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); +#if ARP_QUEUEING + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + /* recycle oldest pending */ + i = old_queue; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + arp_table[i].q = NULL; +#endif + /* no empty or recyclable entries found */ + } else { + return (s8_t)ERR_MEM; + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + + if (arp_table[i].state != ETHARP_STATE_EMPTY) + { + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + } + /* recycle entry (no-op for an already empty entry) */ + arp_table[i].state = ETHARP_STATE_EMPTY; + + /* IP address given? */ + if (ipaddr != NULL) { + /* set IP address */ + ip_addr_set(&arp_table[i].ipaddr, ipaddr); + } + arp_table[i].ctime = 0; +#if LWIP_NETIF_HWADDRHINT + NETIF_SET_HINT(netif, i); +#else /* #if LWIP_NETIF_HWADDRHINT */ + etharp_cached_entry = i; +#endif /* #if LWIP_NETIF_HWADDRHINT */ + return (err_t)i; +} + +/** + * Send an IP packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = p->payload; + u8_t k; + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + k = ETHARP_HWADDR_LEN; + while(k > 0) { + k--; + ethhdr->dest.addr[k] = dst->addr[k]; + ethhdr->src.addr[k] = src->addr[k]; + } + ethhdr->type = htons(ETHTYPE_IP); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} + +/** + * Update (or insert) a IP/MAC address pair in the ARP cache. + * + * If a pending entry is resolved, any queued packets will be sent + * at this point. + * + * @param ipaddr IP address of the inserted ARP entry. + * @param ethaddr Ethernet address of the inserted ARP entry. + * @param flags Defines behaviour: + * - ETHARP_TRY_HARD Allows ARP to insert this as a new item. If not specified, + * only existing ARP entries will be updated. + * + * @return + * - ERR_OK Succesfully updated ARP cache. + * - ERR_MEM If we could not add a new ARP entry when ETHARP_TRY_HARD was set. + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + * @see pbuf_free() + */ +static err_t +update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + s8_t i; + u8_t k; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry()\n")); + LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + /* find or create ARP entry */ +#if LWIP_NETIF_HWADDRHINT + i = find_entry(ipaddr, flags, netif); +#else /* LWIP_NETIF_HWADDRHINT */ + i = find_entry(ipaddr, flags); +#endif /* LWIP_NETIF_HWADDRHINT */ + /* bail out if no entry could be found */ + if (i < 0) + return (err_t)i; + + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + /* record network interface */ + arp_table[i].netif = netif; + + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + k = ETHARP_HWADDR_LEN; + while (k > 0) { + k--; + arp_table[i].ethaddr.addr[k] = ethaddr->addr[k]; + } + /* reset time stamp */ + arp_table[i].ctime = 0; +#if ARP_QUEUEING + /* this is where we will send out queued packets! */ + while (arp_table[i].q != NULL) { + struct pbuf *p; + /* remember remainder of queue */ + struct etharp_q_entry *q = arp_table[i].q; + /* pop first item off the queue */ + arp_table[i].q = q->next; + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + /* free the queued IP packet */ + pbuf_free(p); + } +#endif + return ERR_OK; +} + +/** + * Finds (stable) ethernet/IP address pair from ARP table + * using interface and IP address index. + * @note the addresses in the ARP table are in network order! + * + * @param netif points to interface index + * @param ipaddr points to the (network order) IP address index + * @param eth_ret points to return pointer + * @param ip_ret points to return pointer + * @return table index if found, -1 otherwise + */ +s8_t +etharp_find_addr(struct netif *netif, struct ip_addr *ipaddr, + struct eth_addr **eth_ret, struct ip_addr **ip_ret) +{ + s8_t i; + + LWIP_UNUSED_ARG(netif); + +#if LWIP_NETIF_HWADDRHINT + i = find_entry(ipaddr, ETHARP_FIND_ONLY, NULL); +#else /* LWIP_NETIF_HWADDRHINT */ + i = find_entry(ipaddr, ETHARP_FIND_ONLY); +#endif /* LWIP_NETIF_HWADDRHINT */ + if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) { + *eth_ret = &arp_table[i].ethaddr; + *ip_ret = &arp_table[i].ipaddr; + return i; + } + return -1; +} + +/** + * Updates the ARP table using the given IP packet. + * + * Uses the incoming IP packet's source address to update the + * ARP cache for the local network. The function does not alter + * or free the packet. This function must be called before the + * packet p is passed to the IP layer. + * + * @param netif The lwIP network interface on which the IP packet pbuf arrived. + * @param p The IP packet that arrived on netif. + * + * @return NULL + * + * @see pbuf_free() + */ +void +etharp_ip_input(struct netif *netif, struct pbuf *p) +{ + struct eth_hdr *ethhdr; + struct ip_hdr *iphdr; + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + /* Only insert an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + ethhdr = p->payload; + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == ETHTYPE_VLAN) { + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* source is not on the local network? */ + if (!ip_addr_netcmp(&(iphdr->src), &(netif->ip_addr), &(netif->netmask))) { + /* do nothing */ + return; + } + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); + /* update ARP table */ + /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk + * back soon (for example, if the destination IP address is ours. */ + update_arp_entry(netif, &(iphdr->src), &(ethhdr->src), 0); +} + + +/** + * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache + * send out queued IP packets. Updates cache with snooped address pairs. + * + * Should be called for incoming ARP packets. The pbuf in the argument + * is freed by this function. + * + * @param netif The lwIP network interface on which the ARP packet pbuf arrived. + * @param ethaddr Ethernet address of netif. + * @param p The ARP packet that arrived on netif. Is freed by this function. + * + * @return NULL + * + * @see pbuf_free() + */ +void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + struct etharp_hdr *hdr; + struct eth_hdr *ethhdr; + /* these are aligned properly, whereas the ARP header fields might not be */ + struct ip_addr sipaddr, dipaddr; + u8_t i; + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + + ethhdr = p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == ETHTYPE_VLAN) { + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != htons(HWTYPE_ETHERNET)) || + (hdr->_hwlen_protolen != htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr))) || + (hdr->proto != htons(ETHTYPE_IP)) || + (ethhdr->type != htons(ETHTYPE_ARP))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, ARPH_HWLEN(hdr), hdr->proto, ARPH_PROTOLEN(hdr), ethhdr->type)); + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + ETHARP_STATS_INC(etharp.recv); + +#if LWIP_AUTOIP + /* We have to check if a host already has configured our random + * created link local address and continously check if there is + * a host with this IP-address so we can detect collisions */ + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + SMEMCPY(&sipaddr, &hdr->sipaddr, sizeof(sipaddr)); + SMEMCPY(&dipaddr, &hdr->dipaddr, sizeof(dipaddr)); + + /* this interface is not configured? */ + if (netif->ip_addr.addr == 0) { + for_us = 0; + } else { + /* ARP packet directed to us? */ + for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + } + + /* ARP message directed to us? */ + if (for_us) { + /* add IP address in ARP cache; assume requester wants to talk to us. + * can result in directly sending the queued packets for this host. */ + update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD); + /* ARP message not directed to us? */ + } else { + /* update the source IP address in the cache, if present */ + update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0); + } + + /* now act on the message itself */ + switch (htons(hdr->opcode)) { + /* ARP request? */ + case ARP_REQUEST: + /* ARP request. If it asked for our address, we send out a + * reply. In any case, we time-stamp any existing ARP entry, + * and possiby send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + + hdr->dipaddr = hdr->sipaddr; + SMEMCPY(&hdr->sipaddr, &netif->ip_addr, sizeof(hdr->sipaddr)); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + i = ETHARP_HWADDR_LEN; +#if LWIP_AUTOIP + /* If we are using Link-Local, ARP packets must be broadcast on the + * link layer. (See RFC3927 Section 2.5) */ + ethdst_hwaddr = ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + while(i > 0) { + i--; + hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i]; +#if LWIP_AUTOIP + ethhdr->dest.addr[i] = ethdst_hwaddr[i]; +#else /* LWIP_AUTOIP */ + ethhdr->dest.addr[i] = hdr->shwaddr.addr[i]; +#endif /* LWIP_AUTOIP */ + hdr->shwaddr.addr[i] = ethaddr->addr[i]; + ethhdr->src.addr[i] = ethaddr->addr[i]; + } + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + /* we are not configured? */ + } else if (netif->ip_addr.addr == 0) { + /* { for_us == 0 and netif->ip_addr.addr == 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); + /* request was not directed to us */ + } else { + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP + if(netif->flags & NETIF_FLAG_IPSWITCH) + netif->linkoutput(netif, p); + else +#endif +/* Realtek Modified End */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + case ARP_REPLY: + /* ARP reply. We already updated the ARP cache earlier. */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); +#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) + /* DHCP wants to know about ARP replies from any host with an + * IP address also offered to us by the DHCP server. We do not + * want to take a duplicate IP address on a single network. + * @todo How should we handle redundant (fail-over) interfaces? */ + dhcp_arp_reply(netif, &sipaddr); +#endif +/* Realtek Modified Start */ +#ifdef CONFIG_DONT_CARE_TP + if(netif->flags & NETIF_FLAG_IPSWITCH) + netif->linkoutput(netif, p); +#endif +/* Realtek Modified End */ + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + break; + } + /* free ARP packet */ + pbuf_free(p); +} + +/** + * Resolve and fill-in Ethernet address header for outgoing IP packet. + * + * For IP multicast and broadcast, corresponding Ethernet addresses + * are selected and the packet is transmitted on the link. + * + * For unicast addresses, the packet is submitted to etharp_query(). In + * case the IP address is outside the local network, the IP address of + * the gateway is used. + * + * @param netif The lwIP network interface which the IP packet will be sent on. + * @param q The pbuf(s) containing the IP packet to be sent. + * @param ipaddr The IP address of the packet destination. + * + * @return + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, struct ip_addr *ipaddr) +{ + struct eth_addr *dest, mcastaddr; + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + + /* assume unresolved Ethernet address */ + dest = NULL; + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = 0x01; + mcastaddr.addr[1] = 0x00; + mcastaddr.addr[2] = 0x5e; + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + mcastaddr.addr[4] = ip4_addr3(ipaddr); + mcastaddr.addr[5] = ip4_addr4(ipaddr); + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + /* unicast destination IP address? */ + } else { + /* outside local network? */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) { + /* interface has default gateway? */ + if (netif->gw.addr != 0) { + /* send to hardware address of default gateway IP address */ + ipaddr = &(netif->gw); + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + } + } + /* queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, ipaddr, q); + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); +} + +/** + * Send an ARP request for the given IP address and/or queue a packet. + * + * If the IP address was not yet in the cache, a pending ARP cache entry + * is added and an ARP request is sent for the given address. The packet + * is queued on this entry. + * + * If the IP address was already pending in the cache, a new ARP request + * is sent for the given address. The packet is queued on this entry. + * + * If the IP address was already stable in the cache, and a packet is + * given, it is directly sent and no ARP request is sent out. + * + * If the IP address was already stable in the cache, and no packet is + * given, an ARP request is sent out. + * + * @param netif The lwIP network interface on which ipaddr + * must be queried for. + * @param ipaddr The IP address to be resolved. + * @param q If non-NULL, a pbuf that must be delivered to the IP address. + * q is not freed by this function. + * + * @note q must only be ONE packet, not a packet queue! + * + * @return + * - ERR_BUF Could not make room for Ethernet header. + * - ERR_MEM Hardware address unknown, and no more ARP entries available + * to query for address or queue the packet. + * - ERR_MEM Could not queue packet due to memory shortage. + * - ERR_RTE No route to destination (no gateway to external networks). + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q) +{ + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + err_t result = ERR_MEM; + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr) || + ip_addr_isany(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ +#if LWIP_NETIF_HWADDRHINT + i = find_entry(ipaddr, ETHARP_TRY_HARD, netif); +#else /* LWIP_NETIF_HWADDRHINT */ + i = find_entry(ipaddr, ETHARP_TRY_HARD); +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* could not find or create entry? */ + if (i < 0) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + } + return (err_t)i; + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + arp_table[i].state = ETHARP_STATE_PENDING; + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state == ETHARP_STATE_STABLE))); + + /* do we have a pending entry? or an implicit query request? */ + if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + if (result != ERR_OK) { + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + } + + /* packet given? */ + if (q != NULL) { + /* stable entry? */ + if (arp_table[i].state == ETHARP_STATE_STABLE) { + /* we have a valid IP->Ethernet address mapping */ + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { +#if ARP_QUEUEING /* queue the given q packet */ + struct pbuf *p; + int copy_needed = 0; + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + while (p) { + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + copy_needed = 1; + break; + } + p = p->next; + } + if(copy_needed) { + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(p != NULL) { + if (pbuf_copy(p, q) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + pbuf_ref(p); + } + /* packet could be taken over? */ + if (p != NULL) { + /* queue packet ... */ + struct etharp_q_entry *new_entry; + /* allocate a new arp queue entry */ + new_entry = memp_malloc(MEMP_ARP_QUEUE); + if (new_entry != NULL) { + new_entry->next = 0; + new_entry->p = p; + if(arp_table[i].q != NULL) { + /* queue was already existent, append the new entry to the end */ + struct etharp_q_entry *r; + r = arp_table[i].q; + while (r->next != NULL) { + r = r->next; + } + r->next = new_entry; + } else { + /* queue did not exist, first item in queue */ + arp_table[i].q = new_entry; + } + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + result = ERR_OK; + } else { + /* the pool MEMP_ARP_QUEUE is empty */ + pbuf_free(p); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + /* { result == ERR_MEM } through initialization */ + } + } else { + ETHARP_STATS_INC(etharp.memerr); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + /* { result == ERR_MEM } through initialization */ + } +#else /* ARP_QUEUEING == 0 */ + /* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */ + /* { result == ERR_MEM } through initialization */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q)); +#endif + } + } + return result; +} + +/** + * Send a raw ARP packet (opcode and all addresses can be modified) + * + * @param netif the lwip network interface on which to send the ARP packet + * @param ethsrc_addr the source MAC address for the ethernet header + * @param ethdst_addr the destination MAC address for the ethernet header + * @param hwsrc_addr the source MAC address for the ARP protocol header + * @param ipsrc_addr the source IP address for the ARP protocol header + * @param hwdst_addr the destination MAC address for the ARP protocol header + * @param ipdst_addr the destination IP address for the ARP protocol header + * @param opcode the type of the ARP packet + * @return ERR_OK if the ARP packet has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +#if !LWIP_AUTOIP +static +#endif /* LWIP_AUTOIP */ +err_t +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const struct ip_addr *ipsrc_addr, + const struct eth_addr *hwdst_addr, const struct ip_addr *ipdst_addr, + const u16_t opcode) +{ + struct pbuf *p; + err_t result = ERR_OK; + u8_t k; /* ARP entry index */ + struct eth_hdr *ethhdr; + struct etharp_hdr *hdr; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET)); + + ethhdr = p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + k = ETHARP_HWADDR_LEN; +#if LWIP_AUTOIP + /* If we are using Link-Local, ARP packets must be broadcast on the + * link layer. (See RFC3927 Section 2.5) */ + ethdst_hwaddr = ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write MAC-Addresses (combined loop for both headers) */ + while(k > 0) { + k--; + /* Write the ARP MAC-Addresses */ + hdr->shwaddr.addr[k] = hwsrc_addr->addr[k]; + hdr->dhwaddr.addr[k] = hwdst_addr->addr[k]; + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ethhdr->dest.addr[k] = ethdst_hwaddr[k]; +#else /* LWIP_AUTOIP */ + ethhdr->dest.addr[k] = ethdst_addr->addr[k]; +#endif /* LWIP_AUTOIP */ + ethhdr->src.addr[k] = ethsrc_addr->addr[k]; + } + hdr->sipaddr = *(struct ip_addr2 *)ipsrc_addr; + hdr->dipaddr = *(struct ip_addr2 *)ipdst_addr; + + hdr->hwtype = htons(HWTYPE_ETHERNET); + hdr->proto = htons(ETHTYPE_IP); + /* set hwlen and protolen together */ + hdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(struct ip_addr)); + + ethhdr->type = htons(ETHTYPE_ARP); + /* send ARP query */ + result = netif->linkoutput(netif, p); + ETHARP_STATS_INC(etharp.xmit); + /* free ARP query packet */ + pbuf_free(p); + p = NULL; + /* could not allocate pbuf for ARP request */ + + return result; +} + +/** + * Send an ARP request packet asking for ipaddr. + * + * @param netif the lwip network interface on which to send the request + * @param ipaddr the IP address for which to ask + * @return ERR_OK if the request has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, struct ip_addr *ipaddr) +{ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + ipaddr, ARP_REQUEST); +} + +/** + * Process received ethernet frames. Using this function instead of directly + * calling ip_input and passing ARP frames through etharp in ethernetif_input, + * the ARP cache is protected from concurrent access. + * + * @param p the recevied packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + struct eth_hdr* ethhdr; + u16_t type; + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, + ("ethernet_input: dest:%02x:%02x:%02x:%02x:%02x:%02x, src:%02x:%02x:%02x:%02x:%02x:%02x, type:%2hx\n", + (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = htons(ethhdr->type); +#if ETHARP_SUPPORT_VLAN + if (type == ETHTYPE_VLAN) { + struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); +#ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */ + if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { + /* silently ignore this packet: not for our VLAN */ + pbuf_free(p); + return ERR_OK; + } +#endif /* ETHARP_VLAN_CHECK */ + type = htons(vlan->tpid); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + switch (type) { + /* IP packet? */ + case ETHTYPE_IP: +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { + LWIP_ASSERT("Can't move over header in packet", 0); + pbuf_free(p); + p = NULL; + } else { + /* pass to IP layer */ + ip_input(p, netif); + } + break; + + case ETHTYPE_ARP: + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + break; + +#if PPPOE_SUPPORT + case ETHTYPE_PPPOEDISC: /* PPP Over Ethernet Discovery Stage */ + pppoe_disc_input(netif, p); + break; + + case ETHTYPE_PPPOE: /* PPP Over Ethernet Session Stage */ + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + + default: + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + p = NULL; + break; + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; +} +#endif /* LWIP_ARP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/loopif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/loopif.c new file mode 100644 index 0000000..cbcda78 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/loopif.c @@ -0,0 +1,66 @@ +/** + * @file + * Loop Interface + * + **/ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#include "lwip/opt.h" + +#if LWIP_HAVE_LOOPIF + +#include "netif/loopif.h" +#include "lwip/snmp.h" + +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ +err_t +loopif_init(struct netif *netif) +{ + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); + + netif->name[0] = 'l'; + netif->name[1] = 'o'; + netif->output = netif_loop_output; + return ERR_OK; +} + +#endif /* LWIP_HAVE_LOOPIF */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.c new file mode 100644 index 0000000..cbd3eb2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.c @@ -0,0 +1,990 @@ +/***************************************************************************** +* auth.c - Network Authentication and Phase Control program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Ported from public pppd code. +*****************************************************************************/ +/* + * auth.c - PPP authentication and phase control. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "fsm.h" +#include "lcp.h" +#include "pap.h" +#include "chap.h" +#include "auth.h" +#include "ipcp.h" + +#if CBCP_SUPPORT +#include "cbcp.h" +#endif /* CBCP_SUPPORT */ + +#include + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +/* Bits in auth_pending[] */ +#define PAP_WITHPEER 1 +#define PAP_PEER 2 +#define CHAP_WITHPEER 4 +#define CHAP_PEER 8 + + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ +/* Used for storing a sequence of words. Usually malloced. */ +struct wordlist { + struct wordlist *next; + char word[1]; +}; + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +extern char *crypt (const char *, const char *); + +/* Prototypes for procedures local to this file. */ + +static void network_phase (int); +static void check_idle (void *); +static void connect_time_expired (void *); +#if 0 +static int login (char *, char *, char **, int *); +#endif +static void logout (void); +static int null_login (int); +static int get_pap_passwd (int, char *, char *); +static int have_pap_secret (void); +static int have_chap_secret (char *, char *, u32_t); +static int ip_addr_check (u32_t, struct wordlist *); +#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +static void set_allowed_addrs(int unit, struct wordlist *addrs); +static void free_wordlist (struct wordlist *); +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ +#if CBCP_SUPPORT +static void callback_phase (int); +#endif /* CBCP_SUPPORT */ + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +#if PAP_SUPPORT || CHAP_SUPPORT +/* The name by which the peer authenticated itself to us. */ +static char peer_authname[MAXNAMELEN]; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + +/* Records which authentication operations haven't completed yet. */ +static int auth_pending[NUM_PPP]; + +/* Set if we have successfully called login() */ +static int logged_in; + +/* Set if we have run the /etc/ppp/auth-up script. */ +static int did_authup; + +/* List of addresses which the peer may use. */ +static struct wordlist *addresses[NUM_PPP]; + +/* Number of network protocols which we have opened. */ +static int num_np_open; + +/* Number of network protocols which have come up. */ +static int num_np_up; + +#if PAP_SUPPORT || CHAP_SUPPORT +/* Set if we got the contents of passwd[] from the pap-secrets file. */ +static int passwd_from_file; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * An Open on LCP has requested a change from Dead to Establish phase. + * Do what's necessary to bring the physical layer up. + */ +void +link_required(int unit) +{ + LWIP_UNUSED_ARG(unit); + + AUTHDEBUG((LOG_INFO, "link_required: %d\n", unit)); +} + +/* + * LCP has terminated the link; go to the Dead phase and take the + * physical layer down. + */ +void +link_terminated(int unit) +{ + AUTHDEBUG((LOG_INFO, "link_terminated: %d\n", unit)); + if (lcp_phase[unit] == PHASE_DEAD) { + return; + } + if (logged_in) { + logout(); + } + lcp_phase[unit] = PHASE_DEAD; + AUTHDEBUG((LOG_NOTICE, "Connection terminated.\n")); + pppLinkTerminated(unit); +} + +/* + * LCP has gone down; it will either die or try to re-establish. + */ +void +link_down(int unit) +{ + int i; + struct protent *protp; + + AUTHDEBUG((LOG_INFO, "link_down: %d\n", unit)); + if (did_authup) { + /* XXX Do link down processing. */ + did_authup = 0; + } + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (!protp->enabled_flag) { + continue; + } + if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) { + (*protp->lowerdown)(unit); + } + if (protp->protocol < 0xC000 && protp->close != NULL) { + (*protp->close)(unit, "LCP down"); + } + } + num_np_open = 0; + num_np_up = 0; + if (lcp_phase[unit] != PHASE_DEAD) { + lcp_phase[unit] = PHASE_TERMINATE; + } + pppLinkDown(unit); +} + +/* + * The link is established. + * Proceed to the Dead, Authenticate or Network phase as appropriate. + */ +void +link_established(int unit) +{ + int auth; + int i; + struct protent *protp; + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *go = &lcp_gotoptions[unit]; +#if PAP_SUPPORT || CHAP_SUPPORT + lcp_options *ho = &lcp_hisoptions[unit]; +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + + AUTHDEBUG((LOG_INFO, "link_established: %d\n", unit)); + /* + * Tell higher-level protocols that LCP is up. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol != PPP_LCP && protp->enabled_flag && protp->lowerup != NULL) { + (*protp->lowerup)(unit); + } + } + if (ppp_settings.auth_required && !(go->neg_chap || go->neg_upap)) { + /* + * We wanted the peer to authenticate itself, and it refused: + * treat it as though it authenticated with PAP using a username + * of "" and a password of "". If that's not OK, boot it out. + */ + if (!wo->neg_upap || !null_login(unit)) { + AUTHDEBUG((LOG_WARNING, "peer refused to authenticate\n")); + lcp_close(unit, "peer refused to authenticate"); + return; + } + } + + lcp_phase[unit] = PHASE_AUTHENTICATE; + auth = 0; +#if CHAP_SUPPORT + if (go->neg_chap) { + ChapAuthPeer(unit, ppp_settings.our_name, go->chap_mdtype); + auth |= CHAP_PEER; + } +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT && CHAP_SUPPORT + else +#endif /* PAP_SUPPORT && CHAP_SUPPORT */ +#if PAP_SUPPORT + if (go->neg_upap) { + upap_authpeer(unit); + auth |= PAP_PEER; + } +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + if (ho->neg_chap) { + ChapAuthWithPeer(unit, ppp_settings.user, ho->chap_mdtype); + auth |= CHAP_WITHPEER; + } +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT && CHAP_SUPPORT + else +#endif /* PAP_SUPPORT && CHAP_SUPPORT */ +#if PAP_SUPPORT + if (ho->neg_upap) { + if (ppp_settings.passwd[0] == 0) { + passwd_from_file = 1; + if (!get_pap_passwd(unit, ppp_settings.user, ppp_settings.passwd)) { + AUTHDEBUG((LOG_ERR, "No secret found for PAP login\n")); + } + } + upap_authwithpeer(unit, ppp_settings.user, ppp_settings.passwd); + auth |= PAP_WITHPEER; + } +#endif /* PAP_SUPPORT */ + auth_pending[unit] = auth; + + if (!auth) { + network_phase(unit); + } +} + +/* + * The peer has failed to authenticate himself using `protocol'. + */ +void +auth_peer_fail(int unit, u16_t protocol) +{ + LWIP_UNUSED_ARG(protocol); + + AUTHDEBUG((LOG_INFO, "auth_peer_fail: %d proto=%X\n", unit, protocol)); + /* + * Authentication failure: take the link down + */ + lcp_close(unit, "Authentication failed"); +} + + +#if PAP_SUPPORT || CHAP_SUPPORT +/* + * The peer has been successfully authenticated using `protocol'. + */ +void +auth_peer_success(int unit, u16_t protocol, char *name, int namelen) +{ + int pbit; + + AUTHDEBUG((LOG_INFO, "auth_peer_success: %d proto=%X\n", unit, protocol)); + switch (protocol) { + case PPP_CHAP: + pbit = CHAP_PEER; + break; + case PPP_PAP: + pbit = PAP_PEER; + break; + default: + AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n", protocol)); + return; + } + + /* + * Save the authenticated name of the peer for later. + */ + if (namelen > sizeof(peer_authname) - 1) { + namelen = sizeof(peer_authname) - 1; + } + BCOPY(name, peer_authname, namelen); + peer_authname[namelen] = 0; + + /* + * If there is no more authentication still to be done, + * proceed to the network (or callback) phase. + */ + if ((auth_pending[unit] &= ~pbit) == 0) { + network_phase(unit); + } +} + +/* + * We have failed to authenticate ourselves to the peer using `protocol'. + */ +void +auth_withpeer_fail(int unit, u16_t protocol) +{ + int errCode = PPPERR_AUTHFAIL; + + LWIP_UNUSED_ARG(protocol); + + AUTHDEBUG((LOG_INFO, "auth_withpeer_fail: %d proto=%X\n", unit, protocol)); + if (passwd_from_file) { + BZERO(ppp_settings.passwd, MAXSECRETLEN); + } + /* + * XXX Warning: the unit number indicates the interface which is + * not necessarily the PPP connection. It works here as long + * as we are only supporting PPP interfaces. + */ + pppIOCtl(unit, PPPCTLS_ERRCODE, &errCode); + + /* + * We've failed to authenticate ourselves to our peer. + * He'll probably take the link down, and there's not much + * we can do except wait for that. + */ +} + +/* + * We have successfully authenticated ourselves with the peer using `protocol'. + */ +void +auth_withpeer_success(int unit, u16_t protocol) +{ + int pbit; + + AUTHDEBUG((LOG_INFO, "auth_withpeer_success: %d proto=%X\n", unit, protocol)); + switch (protocol) { + case PPP_CHAP: + pbit = CHAP_WITHPEER; + break; + case PPP_PAP: + if (passwd_from_file) { + BZERO(ppp_settings.passwd, MAXSECRETLEN); + } + pbit = PAP_WITHPEER; + break; + default: + AUTHDEBUG((LOG_WARNING, "auth_peer_success: unknown protocol %x\n", protocol)); + pbit = 0; + } + + /* + * If there is no more authentication still being done, + * proceed to the network (or callback) phase. + */ + if ((auth_pending[unit] &= ~pbit) == 0) { + network_phase(unit); + } +} +#endif /* PAP_SUPPORT || CHAP_SUPPORT */ + + +/* + * np_up - a network protocol has come up. + */ +void +np_up(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG((LOG_INFO, "np_up: %d proto=%X\n", unit, proto)); + if (num_np_up == 0) { + AUTHDEBUG((LOG_INFO, "np_up: maxconnect=%d idle_time_limit=%d\n",ppp_settings.maxconnect,ppp_settings.idle_time_limit)); + /* + * At this point we consider that the link has come up successfully. + */ + if (ppp_settings.idle_time_limit > 0) { + TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit); + } + + /* + * Set a timeout to close the connection once the maximum + * connect time has expired. + */ + if (ppp_settings.maxconnect > 0) { + TIMEOUT(connect_time_expired, 0, ppp_settings.maxconnect); + } + } + ++num_np_up; +} + +/* + * np_down - a network protocol has gone down. + */ +void +np_down(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG((LOG_INFO, "np_down: %d proto=%X\n", unit, proto)); + if (--num_np_up == 0 && ppp_settings.idle_time_limit > 0) { + UNTIMEOUT(check_idle, NULL); + } +} + +/* + * np_finished - a network protocol has finished using the link. + */ +void +np_finished(int unit, u16_t proto) +{ + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(proto); + + AUTHDEBUG((LOG_INFO, "np_finished: %d proto=%X\n", unit, proto)); + if (--num_np_open <= 0) { + /* no further use for the link: shut up shop. */ + lcp_close(0, "No network protocols running"); + } +} + +/* + * auth_reset - called when LCP is starting negotiations to recheck + * authentication options, i.e. whether we have appropriate secrets + * to use for authenticating ourselves and/or the peer. + */ +void +auth_reset(int unit) +{ + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ao = &lcp_allowoptions[0]; + ipcp_options *ipwo = &ipcp_wantoptions[0]; + u32_t remote; + + AUTHDEBUG((LOG_INFO, "auth_reset: %d\n", unit)); + ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(unit, NULL, NULL)); + ao->neg_chap = !ppp_settings.refuse_chap && ppp_settings.passwd[0] != 0 /*have_chap_secret(ppp_settings.user, ppp_settings.remote_name, (u32_t)0)*/; + + if (go->neg_upap && !have_pap_secret()) { + go->neg_upap = 0; + } + if (go->neg_chap) { + remote = ipwo->accept_remote? 0: ipwo->hisaddr; + if (!have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote)) { + go->neg_chap = 0; + } + } +} + +#if PAP_SUPPORT +/* + * check_passwd - Check the user name and passwd against the PAP secrets + * file. If requested, also check against the system password database, + * and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Authentication failed. + * UPAP_AUTHACK: Authentication succeeded. + * In either case, msg points to an appropriate message. + */ +int +check_passwd( int unit, char *auser, int userlen, char *apasswd, int passwdlen, char **msg, int *msglen) +{ +#if 1 + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(auser); + LWIP_UNUSED_ARG(userlen); + LWIP_UNUSED_ARG(apasswd); + LWIP_UNUSED_ARG(passwdlen); + LWIP_UNUSED_ARG(msglen); + *msg = (char *) 0; + return UPAP_AUTHACK; /* XXX Assume all entries OK. */ +#else + int ret = 0; + struct wordlist *addrs = NULL; + char passwd[256], user[256]; + char secret[MAXWORDLEN]; + static u_short attempts = 0; + + /* + * Make copies of apasswd and auser, then null-terminate them. + */ + BCOPY(apasswd, passwd, passwdlen); + passwd[passwdlen] = '\0'; + BCOPY(auser, user, userlen); + user[userlen] = '\0'; + *msg = (char *) 0; + + /* XXX Validate user name and password. */ + ret = UPAP_AUTHACK; /* XXX Assume all entries OK. */ + + if (ret == UPAP_AUTHNAK) { + if (*msg == (char *) 0) { + *msg = "Login incorrect"; + } + *msglen = strlen(*msg); + /* + * Frustrate passwd stealer programs. + * Allow 10 tries, but start backing off after 3 (stolen from login). + * On 10'th, drop the connection. + */ + if (attempts++ >= 10) { + AUTHDEBUG((LOG_WARNING, "%d LOGIN FAILURES BY %s\n", attempts, user)); + /*ppp_panic("Excess Bad Logins");*/ + } + if (attempts > 3) { + sys_msleep((attempts - 3) * 5); + } + if (addrs != NULL) { + free_wordlist(addrs); + } + } else { + attempts = 0; /* Reset count */ + if (*msg == (char *) 0) { + *msg = "Login ok"; + } + *msglen = strlen(*msg); + set_allowed_addrs(unit, addrs); + } + + BZERO(passwd, sizeof(passwd)); + BZERO(secret, sizeof(secret)); + + return ret; +#endif +} +#endif /* PAP_SUPPORT */ + + +/* + * auth_ip_addr - check whether the peer is authorized to use + * a given IP address. Returns 1 if authorized, 0 otherwise. + */ +int +auth_ip_addr(int unit, u32_t addr) +{ + return ip_addr_check(addr, addresses[unit]); +} + +/* + * bad_ip_adrs - return 1 if the IP address is one we don't want + * to use, such as an address in the loopback net or a multicast address. + * addr is in network byte order. + */ +int +bad_ip_adrs(u32_t addr) +{ + addr = ntohl(addr); + return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET + || IN_MULTICAST(addr) || IN_BADCLASS(addr); +} + + +#if CHAP_SUPPORT +/* + * get_secret - open the CHAP secret file and return the secret + * for authenticating the given client on the given server. + * (We could be either client or server). + */ +int get_secret( int unit, char *client, char *server, char *secret, int *secret_len, int save_addrs) +{ +#if 1 + int len; + struct wordlist *addrs; + + LWIP_UNUSED_ARG(unit); + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(save_addrs); + + addrs = NULL; + + if(!client || !client[0] || strcmp(client, ppp_settings.user)) { + return 0; + } + + len = strlen(ppp_settings.passwd); + if (len > MAXSECRETLEN) { + AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server)); + len = MAXSECRETLEN; + } + + BCOPY(ppp_settings.passwd, secret, len); + *secret_len = len; + + return 1; +#else + int ret = 0, len; + struct wordlist *addrs; + char secbuf[MAXWORDLEN]; + + addrs = NULL; + secbuf[0] = 0; + + /* XXX Find secret. */ + if (ret < 0) { + return 0; + } + + if (save_addrs) { + set_allowed_addrs(unit, addrs); + } + + len = strlen(secbuf); + if (len > MAXSECRETLEN) { + AUTHDEBUG((LOG_ERR, "Secret for %s on %s is too long\n", client, server)); + len = MAXSECRETLEN; + } + + BCOPY(secbuf, secret, len); + BZERO(secbuf, sizeof(secbuf)); + *secret_len = len; + + return 1; +#endif +} +#endif /* CHAP_SUPPORT */ + + +#if 0 /* UNUSED */ +/* + * auth_check_options - called to check authentication options. + */ +void +auth_check_options(void) +{ + lcp_options *wo = &lcp_wantoptions[0]; + int can_auth; + ipcp_options *ipwo = &ipcp_wantoptions[0]; + u32_t remote; + + /* Default our_name to hostname, and user to our_name */ + if (ppp_settings.our_name[0] == 0 || ppp_settings.usehostname) { + strcpy(ppp_settings.our_name, ppp_settings.hostname); + } + + if (ppp_settings.user[0] == 0) { + strcpy(ppp_settings.user, ppp_settings.our_name); + } + + /* If authentication is required, ask peer for CHAP or PAP. */ + if (ppp_settings.auth_required && !wo->neg_chap && !wo->neg_upap) { + wo->neg_chap = 1; + wo->neg_upap = 1; + } + + /* + * Check whether we have appropriate secrets to use + * to authenticate the peer. + */ + can_auth = wo->neg_upap && have_pap_secret(); + if (!can_auth && wo->neg_chap) { + remote = ipwo->accept_remote? 0: ipwo->hisaddr; + can_auth = have_chap_secret(ppp_settings.remote_name, ppp_settings.our_name, remote); + } + + if (ppp_settings.auth_required && !can_auth) { + ppp_panic("No auth secret"); + } +} +#endif + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ +/* + * Proceed to the network phase. + */ +static void +network_phase(int unit) +{ + int i; + struct protent *protp; + lcp_options *go = &lcp_gotoptions[unit]; + + /* + * If the peer had to authenticate, run the auth-up script now. + */ + if ((go->neg_chap || go->neg_upap) && !did_authup) { + /* XXX Do setup for peer authentication. */ + did_authup = 1; + } + +#if CBCP_SUPPORT + /* + * If we negotiated callback, do it now. + */ + if (go->neg_cbcp) { + lcp_phase[unit] = PHASE_CALLBACK; + (*cbcp_protent.open)(unit); + return; + } +#endif /* CBCP_SUPPORT */ + + lcp_phase[unit] = PHASE_NETWORK; + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol < 0xC000 && protp->enabled_flag && protp->open != NULL) { + (*protp->open)(unit); + if (protp->protocol != PPP_CCP) { + ++num_np_open; + } + } + } + + if (num_np_open == 0) { + /* nothing to do */ + lcp_close(0, "No network protocols running"); + } +} + +/* + * check_idle - check whether the link has been idle for long + * enough that we can shut it down. + */ +static void +check_idle(void *arg) +{ + struct ppp_idle idle; + u_short itime; + + LWIP_UNUSED_ARG(arg); + if (!get_idle_time(0, &idle)) { + return; + } + itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); + if (itime >= ppp_settings.idle_time_limit) { + /* link is idle: shut it down. */ + AUTHDEBUG((LOG_INFO, "Terminating connection due to lack of activity.\n")); + lcp_close(0, "Link inactive"); + } else { + TIMEOUT(check_idle, NULL, ppp_settings.idle_time_limit - itime); + } +} + +/* + * connect_time_expired - log a message and close the connection. + */ +static void +connect_time_expired(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + AUTHDEBUG((LOG_INFO, "Connect time expired\n")); + lcp_close(0, "Connect time expired"); /* Close connection */ +} + +#if 0 +/* + * login - Check the user name and password against the system + * password database, and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Login failed. + * UPAP_AUTHACK: Login succeeded. + * In either case, msg points to an appropriate message. + */ +static int +login(char *user, char *passwd, char **msg, int *msglen) +{ + /* XXX Fail until we decide that we want to support logins. */ + return (UPAP_AUTHNAK); +} +#endif + +/* + * logout - Logout the user. + */ +static void +logout(void) +{ + logged_in = 0; +} + +/* + * null_login - Check if a username of "" and a password of "" are + * acceptable, and iff so, set the list of acceptable IP addresses + * and return 1. + */ +static int +null_login(int unit) +{ + LWIP_UNUSED_ARG(unit); + /* XXX Fail until we decide that we want to support logins. */ + return 0; +} + +/* + * get_pap_passwd - get a password for authenticating ourselves with + * our peer using PAP. Returns 1 on success, 0 if no suitable password + * could be found. + */ +static int +get_pap_passwd(int unit, char *user, char *passwd) +{ + LWIP_UNUSED_ARG(unit); +/* normally we would reject PAP if no password is provided, + but this causes problems with some providers (like CHT in Taiwan) + who incorrectly request PAP and expect a bogus/empty password, so + always provide a default user/passwd of "none"/"none" +*/ + if(user) { + strcpy(user, "none"); + } + if(passwd) { + strcpy(passwd, "none"); + } + return 1; +} + +/* + * have_pap_secret - check whether we have a PAP file with any + * secrets that we could possibly use for authenticating the peer. + */ +static int +have_pap_secret(void) +{ + /* XXX Fail until we set up our passwords. */ + return 0; +} + +/* + * have_chap_secret - check whether we have a CHAP file with a + * secret that we could possibly use for authenticating `client' + * on `server'. Either can be the null string, meaning we don't + * know the identity yet. + */ +static int +have_chap_secret(char *client, char *server, u32_t remote) +{ + LWIP_UNUSED_ARG(client); + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(remote); + /* XXX Fail until we set up our passwords. */ + return 0; +} + +#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +/* + * set_allowed_addrs() - set the list of allowed addresses. + */ +static void +set_allowed_addrs(int unit, struct wordlist *addrs) +{ + if (addresses[unit] != NULL) { + free_wordlist(addresses[unit]); + } + addresses[unit] = addrs; + +#if 0 + /* + * If there's only one authorized address we might as well + * ask our peer for that one right away + */ + if (addrs != NULL && addrs->next == NULL) { + char *p = addrs->word; + struct ipcp_options *wo = &ipcp_wantoptions[unit]; + u32_t a; + struct hostent *hp; + + if (wo->hisaddr == 0 && *p != '!' && *p != '-' && strchr(p, '/') == NULL) { + hp = gethostbyname(p); + if (hp != NULL && hp->h_addrtype == AF_INET) { + a = *(u32_t *)hp->h_addr; + } else { + a = inet_addr(p); + } + if (a != (u32_t) -1) { + wo->hisaddr = a; + } + } + } +#endif +} +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ + +static int +ip_addr_check(u32_t addr, struct wordlist *addrs) +{ + /* don't allow loopback or multicast address */ + if (bad_ip_adrs(addr)) { + return 0; + } + + if (addrs == NULL) { + return !ppp_settings.auth_required; /* no addresses authorized */ + } + + /* XXX All other addresses allowed. */ + return 1; +} + +#if 0 /* PAP_SUPPORT || CHAP_SUPPORT */ +/* + * free_wordlist - release memory allocated for a wordlist. + */ +static void +free_wordlist(struct wordlist *wp) +{ + struct wordlist *next; + + while (wp != NULL) { + next = wp->next; + free(wp); + wp = next; + } +} +#endif /* 0 */ /* PAP_SUPPORT || CHAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.h new file mode 100644 index 0000000..86ff049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/auth.h @@ -0,0 +1,111 @@ +/***************************************************************************** +* auth.h - PPP Authentication and phase control header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD pppd.h. +*****************************************************************************/ +/* + * pppd.h - PPP daemon global declarations. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef AUTH_H +#define AUTH_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* we are starting to use the link */ +void link_required (int); + +/* we are finished with the link */ +void link_terminated (int); + +/* the LCP layer has left the Opened state */ +void link_down (int); + +/* the link is up; authenticate now */ +void link_established (int); + +/* a network protocol has come up */ +void np_up (int, u16_t); + +/* a network protocol has gone down */ +void np_down (int, u16_t); + +/* a network protocol no longer needs link */ +void np_finished (int, u16_t); + +/* peer failed to authenticate itself */ +void auth_peer_fail (int, u16_t); + +/* peer successfully authenticated itself */ +void auth_peer_success (int, u16_t, char *, int); + +/* we failed to authenticate ourselves */ +void auth_withpeer_fail (int, u16_t); + +/* we successfully authenticated ourselves */ +void auth_withpeer_success (int, u16_t); + +/* check authentication options supplied */ +void auth_check_options (void); + +/* check what secrets we have */ +void auth_reset (int); + +/* Check peer-supplied username/password */ +int check_passwd (int, char *, int, char *, int, char **, int *); + +/* get "secret" for chap */ +int get_secret (int, char *, char *, char *, int *, int); + +/* check if IP address is authorized */ +int auth_ip_addr (int, u32_t); + +/* check if IP address is unreasonable */ +int bad_ip_adrs (u32_t); + +#endif /* AUTH_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.c new file mode 100644 index 0000000..b3ea6b2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.c @@ -0,0 +1,903 @@ +/*** WARNING - THIS HAS NEVER BEEN FINISHED ***/ +/***************************************************************************** +* chap.c - Network Challenge Handshake Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD chap.c. +*****************************************************************************/ +/* + * chap.c - Challenge Handshake Authentication Protocol. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1991 Gregory M. Christy. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Gregory M. Christy. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "magic.h" +#include "randm.h" +#include "auth.h" +#include "md5.h" +#include "chap.h" +#include "chpms.h" + +#include + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +/* + * Protocol entry points. + */ +static void ChapInit (int); +static void ChapLowerUp (int); +static void ChapLowerDown (int); +static void ChapInput (int, u_char *, int); +static void ChapProtocolReject (int); +#if 0 +static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *); +#endif + +static void ChapChallengeTimeout (void *); +static void ChapResponseTimeout (void *); +static void ChapReceiveChallenge (chap_state *, u_char *, int, int); +static void ChapRechallenge (void *); +static void ChapReceiveResponse (chap_state *, u_char *, int, int); +static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len); +static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len); +static void ChapSendStatus (chap_state *, int); +static void ChapSendChallenge (chap_state *); +static void ChapSendResponse (chap_state *); +static void ChapGenChallenge (chap_state *); + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */ + +struct protent chap_protent = { + PPP_CHAP, + ChapInit, + ChapInput, + ChapProtocolReject, + ChapLowerUp, + ChapLowerDown, + NULL, + NULL, +#if 0 + ChapPrintPkt, + NULL, +#endif + 1, + "CHAP", +#if 0 + NULL, + NULL, + NULL +#endif +}; + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * ChapAuthWithPeer - Authenticate us with our peer (start client). + * + */ +void +ChapAuthWithPeer(int unit, char *our_name, int digest) +{ + chap_state *cstate = &chap[unit]; + + cstate->resp_name = our_name; + cstate->resp_type = digest; + + if (cstate->clientstate == CHAPCS_INITIAL || + cstate->clientstate == CHAPCS_PENDING) { + /* lower layer isn't up - wait until later */ + cstate->clientstate = CHAPCS_PENDING; + return; + } + + /* + * We get here as a result of LCP coming up. + * So even if CHAP was open before, we will + * have to re-authenticate ourselves. + */ + cstate->clientstate = CHAPCS_LISTEN; +} + + +/* + * ChapAuthPeer - Authenticate our peer (start server). + */ +void +ChapAuthPeer(int unit, char *our_name, int digest) +{ + chap_state *cstate = &chap[unit]; + + cstate->chal_name = our_name; + cstate->chal_type = digest; + + if (cstate->serverstate == CHAPSS_INITIAL || + cstate->serverstate == CHAPSS_PENDING) { + /* lower layer isn't up - wait until later */ + cstate->serverstate = CHAPSS_PENDING; + return; + } + + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); /* crank it up dude! */ + cstate->serverstate = CHAPSS_INITIAL_CHAL; +} + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ +/* + * ChapInit - Initialize a CHAP unit. + */ +static void +ChapInit(int unit) +{ + chap_state *cstate = &chap[unit]; + + BZERO(cstate, sizeof(*cstate)); + cstate->unit = unit; + cstate->clientstate = CHAPCS_INITIAL; + cstate->serverstate = CHAPSS_INITIAL; + cstate->timeouttime = CHAP_DEFTIMEOUT; + cstate->max_transmits = CHAP_DEFTRANSMITS; + /* random number generator is initialized in magic_init */ +} + + +/* + * ChapChallengeTimeout - Timeout expired on sending challenge. + */ +static void +ChapChallengeTimeout(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending challenges, don't worry. then again we */ + /* probably shouldn't be here either */ + if (cstate->serverstate != CHAPSS_INITIAL_CHAL && + cstate->serverstate != CHAPSS_RECHALLENGE) { + return; + } + + if (cstate->chal_transmits >= cstate->max_transmits) { + /* give up on peer */ + CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n")); + cstate->serverstate = CHAPSS_BADAUTH; + auth_peer_fail(cstate->unit, PPP_CHAP); + return; + } + + ChapSendChallenge(cstate); /* Re-send challenge */ +} + + +/* + * ChapResponseTimeout - Timeout expired on sending response. + */ +static void +ChapResponseTimeout(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending a response, don't worry. */ + if (cstate->clientstate != CHAPCS_RESPONSE) { + return; + } + + ChapSendResponse(cstate); /* re-send response */ +} + + +/* + * ChapRechallenge - Time to challenge the peer again. + */ +static void +ChapRechallenge(void *arg) +{ + chap_state *cstate = (chap_state *) arg; + + /* if we aren't sending a response, don't worry. */ + if (cstate->serverstate != CHAPSS_OPEN) { + return; + } + + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); + cstate->serverstate = CHAPSS_RECHALLENGE; +} + + +/* + * ChapLowerUp - The lower layer is up. + * + * Start up if we have pending requests. + */ +static void +ChapLowerUp(int unit) +{ + chap_state *cstate = &chap[unit]; + + if (cstate->clientstate == CHAPCS_INITIAL) { + cstate->clientstate = CHAPCS_CLOSED; + } else if (cstate->clientstate == CHAPCS_PENDING) { + cstate->clientstate = CHAPCS_LISTEN; + } + + if (cstate->serverstate == CHAPSS_INITIAL) { + cstate->serverstate = CHAPSS_CLOSED; + } else if (cstate->serverstate == CHAPSS_PENDING) { + ChapGenChallenge(cstate); + ChapSendChallenge(cstate); + cstate->serverstate = CHAPSS_INITIAL_CHAL; + } +} + + +/* + * ChapLowerDown - The lower layer is down. + * + * Cancel all timeouts. + */ +static void +ChapLowerDown(int unit) +{ + chap_state *cstate = &chap[unit]; + + /* Timeout(s) pending? Cancel if so. */ + if (cstate->serverstate == CHAPSS_INITIAL_CHAL || + cstate->serverstate == CHAPSS_RECHALLENGE) { + UNTIMEOUT(ChapChallengeTimeout, cstate); + } else if (cstate->serverstate == CHAPSS_OPEN + && cstate->chal_interval != 0) { + UNTIMEOUT(ChapRechallenge, cstate); + } + if (cstate->clientstate == CHAPCS_RESPONSE) { + UNTIMEOUT(ChapResponseTimeout, cstate); + } + cstate->clientstate = CHAPCS_INITIAL; + cstate->serverstate = CHAPSS_INITIAL; +} + + +/* + * ChapProtocolReject - Peer doesn't grok CHAP. + */ +static void +ChapProtocolReject(int unit) +{ + chap_state *cstate = &chap[unit]; + + if (cstate->serverstate != CHAPSS_INITIAL && + cstate->serverstate != CHAPSS_CLOSED) { + auth_peer_fail(unit, PPP_CHAP); + } + if (cstate->clientstate != CHAPCS_INITIAL && + cstate->clientstate != CHAPCS_CLOSED) { + auth_withpeer_fail(unit, PPP_CHAP); + } + ChapLowerDown(unit); /* shutdown chap */ +} + + +/* + * ChapInput - Input CHAP packet. + */ +static void +ChapInput(int unit, u_char *inpacket, int packet_len) +{ + chap_state *cstate = &chap[unit]; + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (packet_len < CHAP_HEADERLEN) { + CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < CHAP_HEADERLEN) { + CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n")); + return; + } + if (len > packet_len) { + CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n")); + return; + } + len -= CHAP_HEADERLEN; + + /* + * Action depends on code (as in fact it usually does :-). + */ + switch (code) { + case CHAP_CHALLENGE: + ChapReceiveChallenge(cstate, inp, id, len); + break; + + case CHAP_RESPONSE: + ChapReceiveResponse(cstate, inp, id, len); + break; + + case CHAP_FAILURE: + ChapReceiveFailure(cstate, inp, id, len); + break; + + case CHAP_SUCCESS: + ChapReceiveSuccess(cstate, inp, id, len); + break; + + default: /* Need code reject? */ + CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code)); + break; + } +} + + +/* + * ChapReceiveChallenge - Receive Challenge and send Response. + */ +static void +ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len) +{ + int rchallenge_len; + u_char *rchallenge; + int secret_len; + char secret[MAXSECRETLEN]; + char rhostname[256]; + MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; + + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id)); + if (cstate->clientstate == CHAPCS_CLOSED || + cstate->clientstate == CHAPCS_PENDING) { + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n", + cstate->clientstate)); + return; + } + + if (len < 2) { + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n")); + return; + } + + GETCHAR(rchallenge_len, inp); + len -= sizeof (u_char) + rchallenge_len; /* now name field length */ + if (len < 0) { + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n")); + return; + } + rchallenge = inp; + INCPTR(rchallenge_len, inp); + + if (len >= sizeof(rhostname)) { + len = sizeof(rhostname) - 1; + } + BCOPY(inp, rhostname, len); + rhostname[len] = '\000'; + + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n", rhostname)); + + /* Microsoft doesn't send their name back in the PPP packet */ + if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) { + strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname)); + rhostname[sizeof(rhostname) - 1] = 0; + CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n", rhostname)); + } + + /* get secret for authenticating ourselves with the specified host */ + if (!get_secret(cstate->unit, cstate->resp_name, rhostname, secret, &secret_len, 0)) { + secret_len = 0; /* assume null secret if can't find one */ + CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname)); + } + + /* cancel response send timeout if necessary */ + if (cstate->clientstate == CHAPCS_RESPONSE) { + UNTIMEOUT(ChapResponseTimeout, cstate); + } + + cstate->resp_id = id; + cstate->resp_transmits = 0; + + /* generate MD based on negotiated type */ + switch (cstate->resp_type) { + + case CHAP_DIGEST_MD5: + MD5Init(&mdContext); + MD5Update(&mdContext, &cstate->resp_id, 1); + MD5Update(&mdContext, (u_char*)secret, secret_len); + MD5Update(&mdContext, rchallenge, rchallenge_len); + MD5Final(hash, &mdContext); + BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE); + cstate->resp_length = MD5_SIGNATURE_SIZE; + break; + +#ifdef CHAPMS + case CHAP_MICROSOFT: + ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len); + break; +#endif + + default: + CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type)); + return; + } + + BZERO(secret, sizeof(secret)); + ChapSendResponse(cstate); +} + + +/* + * ChapReceiveResponse - Receive and process response. + */ +static void +ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len) +{ + u_char *remmd, remmd_len; + int secret_len, old_state; + int code; + char rhostname[256]; + MD5_CTX mdContext; + char secret[MAXSECRETLEN]; + u_char hash[MD5_SIGNATURE_SIZE]; + + CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id)); + + if (cstate->serverstate == CHAPSS_CLOSED || + cstate->serverstate == CHAPSS_PENDING) { + CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n", + cstate->serverstate)); + return; + } + + if (id != cstate->chal_id) { + return; /* doesn't match ID of last challenge */ + } + + /* + * If we have received a duplicate or bogus Response, + * we have to send the same answer (Success/Failure) + * as we did for the first Response we saw. + */ + if (cstate->serverstate == CHAPSS_OPEN) { + ChapSendStatus(cstate, CHAP_SUCCESS); + return; + } + if (cstate->serverstate == CHAPSS_BADAUTH) { + ChapSendStatus(cstate, CHAP_FAILURE); + return; + } + + if (len < 2) { + CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n")); + return; + } + GETCHAR(remmd_len, inp); /* get length of MD */ + remmd = inp; /* get pointer to MD */ + INCPTR(remmd_len, inp); + + len -= sizeof (u_char) + remmd_len; + if (len < 0) { + CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n")); + return; + } + + UNTIMEOUT(ChapChallengeTimeout, cstate); + + if (len >= sizeof(rhostname)) { + len = sizeof(rhostname) - 1; + } + BCOPY(inp, rhostname, len); + rhostname[len] = '\000'; + + CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n", rhostname)); + + /* + * Get secret for authenticating them with us, + * do the hash ourselves, and compare the result. + */ + code = CHAP_FAILURE; + if (!get_secret(cstate->unit, rhostname, cstate->chal_name, secret, &secret_len, 1)) { + /* CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */ + CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n", + rhostname)); + } else { + /* generate MD based on negotiated type */ + switch (cstate->chal_type) { + + case CHAP_DIGEST_MD5: /* only MD5 is defined for now */ + if (remmd_len != MD5_SIGNATURE_SIZE) { + break; /* it's not even the right length */ + } + MD5Init(&mdContext); + MD5Update(&mdContext, &cstate->chal_id, 1); + MD5Update(&mdContext, (u_char*)secret, secret_len); + MD5Update(&mdContext, cstate->challenge, cstate->chal_len); + MD5Final(hash, &mdContext); + + /* compare local and remote MDs and send the appropriate status */ + if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0) { + code = CHAP_SUCCESS; /* they are the same! */ + } + break; + + default: + CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type)); + } + } + + BZERO(secret, sizeof(secret)); + ChapSendStatus(cstate, code); + + if (code == CHAP_SUCCESS) { + old_state = cstate->serverstate; + cstate->serverstate = CHAPSS_OPEN; + if (old_state == CHAPSS_INITIAL_CHAL) { + auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len); + } + if (cstate->chal_interval != 0) { + TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval); + } + } else { + CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n")); + cstate->serverstate = CHAPSS_BADAUTH; + auth_peer_fail(cstate->unit, PPP_CHAP); + } +} + +/* + * ChapReceiveSuccess - Receive Success + */ +static void +ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len) +{ + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(inp); + + CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id)); + + if (cstate->clientstate == CHAPCS_OPEN) { + /* presumably an answer to a duplicate response */ + return; + } + + if (cstate->clientstate != CHAPCS_RESPONSE) { + /* don't know what this is */ + CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n", cstate->clientstate)); + return; + } + + UNTIMEOUT(ChapResponseTimeout, cstate); + + /* + * Print message. + */ + if (len > 0) { + PRINTMSG(inp, len); + } + + cstate->clientstate = CHAPCS_OPEN; + + auth_withpeer_success(cstate->unit, PPP_CHAP); +} + + +/* + * ChapReceiveFailure - Receive failure. + */ +static void +ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len) +{ + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(inp); + + CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id)); + + if (cstate->clientstate != CHAPCS_RESPONSE) { + /* don't know what this is */ + CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n", cstate->clientstate)); + return; + } + + UNTIMEOUT(ChapResponseTimeout, cstate); + + /* + * Print message. + */ + if (len > 0) { + PRINTMSG(inp, len); + } + + CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n")); + auth_withpeer_fail(cstate->unit, PPP_CHAP); +} + + +/* + * ChapSendChallenge - Send an Authenticate challenge. + */ +static void +ChapSendChallenge(chap_state *cstate) +{ + u_char *outp; + int chal_len, name_len; + int outlen; + + chal_len = cstate->chal_len; + name_len = strlen(cstate->chal_name); + outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */ + + PUTCHAR(CHAP_CHALLENGE, outp); + PUTCHAR(cstate->chal_id, outp); + PUTSHORT(outlen, outp); + + PUTCHAR(chal_len, outp); /* put length of challenge */ + BCOPY(cstate->challenge, outp, chal_len); + INCPTR(chal_len, outp); + + BCOPY(cstate->chal_name, outp, name_len); /* append hostname */ + + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id)); + + TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime); + ++cstate->chal_transmits; +} + + +/* + * ChapSendStatus - Send a status response (ack or nak). + */ +static void +ChapSendStatus(chap_state *cstate, int code) +{ + u_char *outp; + int outlen, msglen; + char msg[256]; + + if (code == CHAP_SUCCESS) { + strcpy(msg, "Welcome!"); + } else { + strcpy(msg, "I don't like you. Go 'way."); + } + msglen = strlen(msg); + + outlen = CHAP_HEADERLEN + msglen; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); /* paste in a header */ + + PUTCHAR(code, outp); + PUTCHAR(cstate->chal_id, outp); + PUTSHORT(outlen, outp); + BCOPY(msg, outp, msglen); + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code, cstate->chal_id)); +} + +/* + * ChapGenChallenge is used to generate a pseudo-random challenge string of + * a pseudo-random length between min_len and max_len. The challenge + * string and its length are stored in *cstate, and various other fields of + * *cstate are initialized. + */ + +static void +ChapGenChallenge(chap_state *cstate) +{ + int chal_len; + u_char *ptr = cstate->challenge; + int i; + + /* pick a random challenge length between MIN_CHALLENGE_LENGTH and + MAX_CHALLENGE_LENGTH */ + chal_len = (unsigned) + ((((magic() >> 16) * + (MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16) + + MIN_CHALLENGE_LENGTH); + cstate->chal_len = chal_len; + cstate->chal_id = ++cstate->id; + cstate->chal_transmits = 0; + + /* generate a random string */ + for (i = 0; i < chal_len; i++ ) { + *ptr++ = (char) (magic() & 0xff); + } +} + +/* + * ChapSendResponse - send a response packet with values as specified + * in *cstate. + */ +/* ARGSUSED */ +static void +ChapSendResponse(chap_state *cstate) +{ + u_char *outp; + int outlen, md_len, name_len; + + md_len = cstate->resp_length; + name_len = strlen(cstate->resp_name); + outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len; + outp = outpacket_buf[cstate->unit]; + + MAKEHEADER(outp, PPP_CHAP); + + PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */ + PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */ + PUTSHORT(outlen, outp); /* packet length */ + + PUTCHAR(md_len, outp); /* length of MD */ + BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */ + INCPTR(md_len, outp); + + BCOPY(cstate->resp_name, outp, name_len); /* append our name */ + + /* send the packet */ + pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN); + + cstate->clientstate = CHAPCS_RESPONSE; + TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime); + ++cstate->resp_transmits; +} + +#if 0 +static char *ChapCodenames[] = { + "Challenge", "Response", "Success", "Failure" +}; +/* + * ChapPrintPkt - print the contents of a CHAP packet. + */ +static int +ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + int code, id, len; + int clen, nlen; + u_char x; + + if (plen < CHAP_HEADERLEN) { + return 0; + } + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < CHAP_HEADERLEN || len > plen) { + return 0; + } + if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) { + printer(arg, " %s", ChapCodenames[code-1]); + } else { + printer(arg, " code=0x%x", code); + } + printer(arg, " id=0x%x", id); + len -= CHAP_HEADERLEN; + switch (code) { + case CHAP_CHALLENGE: + case CHAP_RESPONSE: + if (len < 1) { + break; + } + clen = p[0]; + if (len < clen + 1) { + break; + } + ++p; + nlen = len - clen - 1; + printer(arg, " <"); + for (; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, "%.2x", x); + } + printer(arg, ">, name = %.*Z", nlen, p); + break; + case CHAP_FAILURE: + case CHAP_SUCCESS: + printer(arg, " %.*Z", len, p); + break; + default: + for (clen = len; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, " %.2x", x); + } + } + + return len + CHAP_HEADERLEN; +} +#endif + +#endif /* CHAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.h new file mode 100644 index 0000000..83dafd7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chap.h @@ -0,0 +1,166 @@ +/***************************************************************************** +* chap.h - Network Challenge Handshake Authentication Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-03 Guy Lancaster , Global Election Systems Inc. +* Original built from BSD network code. +******************************************************************************/ +/* + * chap.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1993 The Australian National University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Australian National University. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Copyright (c) 1991 Gregory M. Christy + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the author. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: chap.h,v 1.4 2007/12/19 20:47:22 fbernon Exp $ + */ + +#ifndef CHAP_H +#define CHAP_H + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ + +/* Code + ID + length */ +#define CHAP_HEADERLEN 4 + +/* + * CHAP codes. + */ + +#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */ +#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ +#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */ +#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ + +#define CHAP_CHALLENGE 1 +#define CHAP_RESPONSE 2 +#define CHAP_SUCCESS 3 +#define CHAP_FAILURE 4 + +/* + * Challenge lengths (for challenges we send) and other limits. + */ +#define MIN_CHALLENGE_LENGTH 32 +#define MAX_CHALLENGE_LENGTH 64 +#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */ + +/* + * Client (peer) states. + */ +#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */ +#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */ +#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */ +#define CHAPCS_LISTEN 3 /* Listening for a challenge */ +#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */ +#define CHAPCS_OPEN 5 /* We've received Success */ + +/* + * Server (authenticator) states. + */ +#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */ +#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */ +#define CHAPSS_PENDING 2 /* Auth peer when lower up */ +#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */ +#define CHAPSS_OPEN 4 /* We've sent a Success msg */ +#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */ +#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */ + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * Each interface is described by a chap structure. + */ + +typedef struct chap_state { + int unit; /* Interface unit number */ + int clientstate; /* Client state */ + int serverstate; /* Server state */ + u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */ + u_char chal_len; /* challenge length */ + u_char chal_id; /* ID of last challenge */ + u_char chal_type; /* hash algorithm for challenges */ + u_char id; /* Current id */ + char *chal_name; /* Our name to use with challenge */ + int chal_interval; /* Time until we challenge peer again */ + int timeouttime; /* Timeout time in seconds */ + int max_transmits; /* Maximum # of challenge transmissions */ + int chal_transmits; /* Number of transmissions of challenge */ + int resp_transmits; /* Number of transmissions of response */ + u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */ + u_char resp_length; /* length of response */ + u_char resp_id; /* ID for response messages */ + u_char resp_type; /* hash algorithm for responses */ + char *resp_name; /* Our name to send with response */ +} chap_state; + + +/****************** +*** PUBLIC DATA *** +******************/ +extern chap_state chap[]; + +extern struct protent chap_protent; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +void ChapAuthWithPeer (int, char *, int); +void ChapAuthPeer (int, char *, int); + +#endif /* CHAP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.c new file mode 100644 index 0000000..582cfd2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.c @@ -0,0 +1,399 @@ +/*** WARNING - THIS CODE HAS NOT BEEN FINISHED! ***/ +/*** The original PPPD code is written in a way to require either the UNIX DES + encryption functions encrypt(3) and setkey(3) or the DES library libdes. + Since both is not included in lwIP, MSCHAP currently does not work! */ +/***************************************************************************** +* chpms.c - Network MicroSoft Challenge Handshake Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD chap_ms.c. +*****************************************************************************/ +/* + * chap_ms.c - Microsoft MS-CHAP compatible implementation. + * + * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. + * http://www.strataware.com/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Eric Rosenquist. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 + * + * Implemented LANManager type password response to MS-CHAP challenges. + * Now pppd provides both NT style and LANMan style blocks, and the + * prefered is set by option "ms-lanman". Default is to use NT. + * The hash text (StdText) was taken from Win95 RASAPI32.DLL. + * + * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 + */ + +#define USE_CRYPT + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "md4.h" +#ifndef USE_CRYPT +#include "des.h" +#endif +#include "chap.h" +#include "chpms.h" + + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ +typedef struct { + u_char LANManResp[24]; + u_char NTResp[24]; + u_char UseNT; /* If 1, ignore the LANMan response field */ +} MS_ChapResponse; +/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse), + in case this struct gets padded. */ + + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ + +/* XXX Don't know what to do with these. */ +extern void setkey(const char *); +extern void encrypt(char *, int); + +static void DesEncrypt (u_char *, u_char *, u_char *); +static void MakeKey (u_char *, u_char *); + +#ifdef USE_CRYPT +static void Expand (u_char *, u_char *); +static void Collapse (u_char *, u_char *); +#endif + +static void ChallengeResponse( + u_char *challenge, /* IN 8 octets */ + u_char *pwHash, /* IN 16 octets */ + u_char *response /* OUT 24 octets */ +); +static void ChapMS_NT( + char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response +); +static u_char Get7Bits( + u_char *input, + int startBit +); + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +void +ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len) +{ + MS_ChapResponse response; +#ifdef MSLANMAN + extern int ms_lanman; +#endif + +#if 0 + CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret)); +#endif + BZERO(&response, sizeof(response)); + + /* Calculate both always */ + ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response); + +#ifdef MSLANMAN + ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response); + + /* prefered method is set by option */ + response.UseNT = !ms_lanman; +#else + response.UseNT = 1; +#endif + + BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN); + cstate->resp_length = MS_CHAP_RESPONSE_LEN; +} + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ +static void +ChallengeResponse( u_char *challenge, /* IN 8 octets */ + u_char *pwHash, /* IN 16 octets */ + u_char *response /* OUT 24 octets */) +{ + char ZPasswordHash[21]; + + BZERO(ZPasswordHash, sizeof(ZPasswordHash)); + BCOPY(pwHash, ZPasswordHash, 16); + +#if 0 + log_packet(ZPasswordHash, sizeof(ZPasswordHash), "ChallengeResponse - ZPasswordHash", LOG_DEBUG); +#endif + + DesEncrypt(challenge, ZPasswordHash + 0, response + 0); + DesEncrypt(challenge, ZPasswordHash + 7, response + 8); + DesEncrypt(challenge, ZPasswordHash + 14, response + 16); + +#if 0 + log_packet(response, 24, "ChallengeResponse - response", LOG_DEBUG); +#endif +} + + +#ifdef USE_CRYPT +static void +DesEncrypt( u_char *clear, /* IN 8 octets */ + u_char *key, /* IN 7 octets */ + u_char *cipher /* OUT 8 octets */) +{ + u_char des_key[8]; + u_char crypt_key[66]; + u_char des_input[66]; + + MakeKey(key, des_key); + + Expand(des_key, crypt_key); + setkey(crypt_key); + +#if 0 + CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", + clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); +#endif + + Expand(clear, des_input); + encrypt(des_input, 0); + Collapse(des_input, cipher); + +#if 0 + CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); +#endif +} + +#else /* USE_CRYPT */ + +static void +DesEncrypt( u_char *clear, /* IN 8 octets */ + u_char *key, /* IN 7 octets */ + u_char *cipher /* OUT 8 octets */) +{ + des_cblock des_key; + des_key_schedule key_schedule; + + MakeKey(key, des_key); + + des_set_key(&des_key, key_schedule); + +#if 0 + CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n", + clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7])); +#endif + + des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1); + +#if 0 + CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7])); +#endif +} + +#endif /* USE_CRYPT */ + + +static u_char +Get7Bits( u_char *input, int startBit) +{ + register unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +#ifdef USE_CRYPT + +/* in == 8-byte string (expanded version of the 56-bit key) + * out == 64-byte string where each byte is either 1 or 0 + * Note that the low-order "bit" is always ignored by by setkey() + */ +static void +Expand(u_char *in, u_char *out) +{ + int j, c; + int i; + + for(i = 0; i < 64; in++){ + c = *in; + for(j = 7; j >= 0; j--) { + *out++ = (c >> j) & 01; + } + i += 8; + } +} + +/* The inverse of Expand + */ +static void +Collapse(u_char *in, u_char *out) +{ + int j; + int i; + unsigned int c; + + for (i = 0; i < 64; i += 8, out++) { + c = 0; + for (j = 7; j >= 0; j--, in++) { + c |= *in << j; + } + *out = c & 0xff; + } +} +#endif + +static void +MakeKey( u_char *key, /* IN 56 bit DES key missing parity bits */ + u_char *des_key /* OUT 64 bit DES key with parity bits added */) +{ + des_key[0] = Get7Bits(key, 0); + des_key[1] = Get7Bits(key, 7); + des_key[2] = Get7Bits(key, 14); + des_key[3] = Get7Bits(key, 21); + des_key[4] = Get7Bits(key, 28); + des_key[5] = Get7Bits(key, 35); + des_key[6] = Get7Bits(key, 42); + des_key[7] = Get7Bits(key, 49); + +#ifndef USE_CRYPT + des_set_odd_parity((des_cblock *)des_key); +#endif + +#if 0 + CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n", + key[0], key[1], key[2], key[3], key[4], key[5], key[6])); + CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n", + des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7])); +#endif +} + +static void +ChapMS_NT( char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response) +{ + int i; + MDstruct md4Context; + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + static int low_byte_first = -1; + + /* Initialize the Unicode version of the secret (== password). */ + /* This implicitly supports 8-bit ISO8859/1 characters. */ + BZERO(unicodePassword, sizeof(unicodePassword)); + for (i = 0; i < secret_len; i++) { + unicodePassword[i * 2] = (u_char)secret[i]; + } + MDbegin(&md4Context); + MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */ + + if (low_byte_first == -1) { + low_byte_first = (htons((unsigned short int)1) != 1); + } + if (low_byte_first == 0) { + MDreverse((u_long *)&md4Context); /* sfb 961105 */ + } + + MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */ + + ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp); +} + +#ifdef MSLANMAN +static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ + +static void +ChapMS_LANMan( char *rchallenge, + int rchallenge_len, + char *secret, + int secret_len, + MS_ChapResponse *response) +{ + int i; + u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ + u_char PasswordHash[16]; + + /* LANMan password is case insensitive */ + BZERO(UcasePassword, sizeof(UcasePassword)); + for (i = 0; i < secret_len; i++) { + UcasePassword[i] = (u_char)toupper(secret[i]); + } + DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 ); + DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 ); + ChallengeResponse(rchallenge, PasswordHash, response->LANManResp); +} +#endif + +#endif /* MSCHAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.h new file mode 100644 index 0000000..df070fb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/chpms.h @@ -0,0 +1,64 @@ +/***************************************************************************** +* chpms.h - Network Microsoft Challenge Handshake Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-01-30 Guy Lancaster , Global Election Systems Inc. +* Original built from BSD network code. +******************************************************************************/ +/* + * chap.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1995 Eric Rosenquist, Strata Software Limited. + * http://www.strataware.com/ + * + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Eric Rosenquist. The name of the author may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: chpms.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $ + */ + +#ifndef CHPMS_H +#define CHPMS_H + +#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */ + +void ChapMS (chap_state *, char *, int, char *, int); + +#endif /* CHPMS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.c new file mode 100644 index 0000000..ee549f2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.c @@ -0,0 +1,908 @@ +/***************************************************************************** +* fsm.c - Network Control Protocol Finite State Machine program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-01 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD fsm.c. +*****************************************************************************/ +/* + * fsm.c - {Link, IP} Control Protocol Finite State Machine. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * TODO: + * Randomize fsm id on link/init. + * Deal with variable outgoing MTU. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "fsm.h" + +#include + + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +#if PPP_DEBUG + +static const char *ppperr_strerr[] = { + "LS_INITIAL", /* LS_INITIAL 0 */ + "LS_STARTING", /* LS_STARTING 1 */ + "LS_CLOSED", /* LS_CLOSED 2 */ + "LS_STOPPED", /* LS_STOPPED 3 */ + "LS_CLOSING", /* LS_CLOSING 4 */ + "LS_STOPPING", /* LS_STOPPING 5 */ + "LS_REQSENT", /* LS_REQSENT 6 */ + "LS_ACKRCVD", /* LS_ACKRCVD 7 */ + "LS_ACKSENT", /* LS_ACKSENT 8 */ + "LS_OPENED" /* LS_OPENED 9 */ +}; + +#endif /* PPP_DEBUG */ + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +static void fsm_timeout (void *); +static void fsm_rconfreq (fsm *, u_char, u_char *, int); +static void fsm_rconfack (fsm *, int, u_char *, int); +static void fsm_rconfnakrej (fsm *, int, int, u_char *, int); +static void fsm_rtermreq (fsm *, int, u_char *, int); +static void fsm_rtermack (fsm *); +static void fsm_rcoderej (fsm *, u_char *, int); +static void fsm_sconfreq (fsm *, int); + +#define PROTO_NAME(f) ((f)->callbacks->proto_name) + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +int peer_mru[NUM_PPP]; + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ + +/* + * fsm_init - Initialize fsm. + * + * Initialize fsm state. + */ +void +fsm_init(fsm *f) +{ + f->state = LS_INITIAL; + f->flags = 0; + f->id = 0; /* XXX Start with random id? */ + f->timeouttime = FSM_DEFTIMEOUT; + f->maxconfreqtransmits = FSM_DEFMAXCONFREQS; + f->maxtermtransmits = FSM_DEFMAXTERMREQS; + f->maxnakloops = FSM_DEFMAXNAKLOOPS; + f->term_reason_len = 0; +} + + +/* + * fsm_lowerup - The lower layer is up. + */ +void +fsm_lowerup(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_INITIAL: + f->state = LS_CLOSED; + break; + + case LS_STARTING: + if( f->flags & OPT_SILENT ) { + f->state = LS_STOPPED; + } else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + } + break; + + default: + FSMDEBUG((LOG_INFO, "%s: Up event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } + + FSMDEBUG((LOG_INFO, "%s: lowerup state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_lowerdown - The lower layer is down. + * + * Cancel all timeouts and inform upper layers. + */ +void +fsm_lowerdown(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_CLOSED: + f->state = LS_INITIAL; + break; + + case LS_STOPPED: + f->state = LS_STARTING; + if( f->callbacks->starting ) { + (*f->callbacks->starting)(f); + } + break; + + case LS_CLOSING: + f->state = LS_INITIAL; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case LS_STOPPING: + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + f->state = LS_STARTING; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case LS_OPENED: + if( f->callbacks->down ) { + (*f->callbacks->down)(f); + } + f->state = LS_STARTING; + break; + + default: + FSMDEBUG((LOG_INFO, "%s: Down event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } + + FSMDEBUG((LOG_INFO, "%s: lowerdown state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_open - Link is allowed to come up. + */ +void +fsm_open(fsm *f) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + switch( f->state ) { + case LS_INITIAL: + f->state = LS_STARTING; + if( f->callbacks->starting ) { + (*f->callbacks->starting)(f); + } + break; + + case LS_CLOSED: + if( f->flags & OPT_SILENT ) { + f->state = LS_STOPPED; + } else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + } + break; + + case LS_CLOSING: + f->state = LS_STOPPING; + /* fall through */ + case LS_STOPPED: + case LS_OPENED: + if( f->flags & OPT_RESTART ) { + fsm_lowerdown(f); + fsm_lowerup(f); + } + break; + } + + FSMDEBUG((LOG_INFO, "%s: open state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_close - Start closing connection. + * + * Cancel timeouts and either initiate close or possibly go directly to + * the LS_CLOSED state. + */ +void +fsm_close(fsm *f, char *reason) +{ + int oldState = f->state; + + LWIP_UNUSED_ARG(oldState); + + f->term_reason = reason; + f->term_reason_len = (reason == NULL? 0: strlen(reason)); + switch( f->state ) { + case LS_STARTING: + f->state = LS_INITIAL; + break; + case LS_STOPPED: + f->state = LS_CLOSED; + break; + case LS_STOPPING: + f->state = LS_CLOSING; + break; + + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + case LS_OPENED: + if( f->state != LS_OPENED ) { + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + } else if( f->callbacks->down ) { + (*f->callbacks->down)(f); /* Inform upper layers we're down */ + } + /* Init restart counter, send Terminate-Request */ + f->retransmits = f->maxtermtransmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = LS_CLOSING; + break; + } + + FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d (%s) -> %d (%s)\n", + PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state])); +} + + +/* + * fsm_sdata - Send some data. + * + * Used for all packets sent to our peer by this module. + */ +void +fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen) +{ + u_char *outp; + int outlen; + + /* Adjust length to be smaller than MTU */ + outp = outpacket_buf[f->unit]; + if (datalen > peer_mru[f->unit] - (int)HEADERLEN) { + datalen = peer_mru[f->unit] - HEADERLEN; + } + if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) { + BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen); + } + outlen = datalen + HEADERLEN; + MAKEHEADER(outp, f->protocol); + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN); + FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n", + PROTO_NAME(f), code, id, outlen)); +} + + +/* + * fsm_input - Input packet. + */ +void +fsm_input(fsm *f, u_char *inpacket, int l) +{ + u_char *inp = inpacket; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + if (l < HEADERLEN) { + FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n", + f->protocol)); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < HEADERLEN) { + FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n", + f->protocol)); + return; + } + if (len > l) { + FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n", + f->protocol)); + return; + } + len -= HEADERLEN; /* subtract header length */ + + if( f->state == LS_INITIAL || f->state == LS_STARTING ) { + FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d (%s).\n", + f->protocol, f->state, ppperr_strerr[f->state])); + return; + } + FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l)); + /* + * Action depends on code. + */ + switch (code) { + case CONFREQ: + fsm_rconfreq(f, id, inp, len); + break; + + case CONFACK: + fsm_rconfack(f, id, inp, len); + break; + + case CONFNAK: + case CONFREJ: + fsm_rconfnakrej(f, code, id, inp, len); + break; + + case TERMREQ: + fsm_rtermreq(f, id, inp, len); + break; + + case TERMACK: + fsm_rtermack(f); + break; + + case CODEREJ: + fsm_rcoderej(f, inp, len); + break; + + default: + if( !f->callbacks->extcode || + !(*f->callbacks->extcode)(f, code, id, inp, len) ) { + fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); + } + break; + } +} + + +/* + * fsm_protreject - Peer doesn't speak this protocol. + * + * Treat this as a catastrophic error (RXJ-). + */ +void +fsm_protreject(fsm *f) +{ + switch( f->state ) { + case LS_CLOSING: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + case LS_CLOSED: + f->state = LS_CLOSED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_STOPPING: + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + case LS_STOPPED: + f->state = LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_OPENED: + if( f->callbacks->down ) { + (*f->callbacks->down)(f); + } + /* Init restart counter, send Terminate-Request */ + f->retransmits = f->maxtermtransmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + + f->state = LS_STOPPING; + break; + + default: + FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } +} + + + + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +/* + * fsm_timeout - Timeout expired. + */ +static void +fsm_timeout(void *arg) +{ + fsm *f = (fsm *) arg; + + switch (f->state) { + case LS_CLOSING: + case LS_STOPPING: + if( f->retransmits <= 0 ) { + FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* + * We've waited for an ack long enough. Peer probably heard us. + */ + f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + } else { + FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* Send Terminate-Request */ + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, f->timeouttime); + --f->retransmits; + } + break; + + case LS_REQSENT: + case LS_ACKRCVD: + case LS_ACKSENT: + if (f->retransmits <= 0) { + FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + f->state = LS_STOPPED; + if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + } else { + FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + /* Retransmit the configure-request */ + if (f->callbacks->retransmit) { + (*f->callbacks->retransmit)(f); + } + fsm_sconfreq(f, 1); /* Re-send Configure-Request */ + if( f->state == LS_ACKRCVD ) { + f->state = LS_REQSENT; + } + } + break; + + default: + FSMDEBUG((LOG_INFO, "%s: UNHANDLED timeout event in state %d (%s)!\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + } +} + + +/* + * fsm_rconfreq - Receive Configure-Request. + */ +static void +fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) +{ + int code, reject_if_disagree; + + FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + switch( f->state ) { + case LS_CLOSED: + /* Go away, we're closed */ + fsm_sdata(f, TERMACK, id, NULL, 0); + return; + case LS_CLOSING: + case LS_STOPPING: + return; + + case LS_OPENED: + /* Go down and restart negotiation */ + if( f->callbacks->down ) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + break; + + case LS_STOPPED: + /* Negotiation started by our peer */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } + + /* + * Pass the requested configuration options + * to protocol-specific code for checking. + */ + if (f->callbacks->reqci) { /* Check CI */ + reject_if_disagree = (f->nakloops >= f->maxnakloops); + code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); + } else if (len) { + code = CONFREJ; /* Reject all CI */ + } else { + code = CONFACK; + } + + /* send the Ack, Nak or Rej to the peer */ + fsm_sdata(f, (u_char)code, id, inp, len); + + if (code == CONFACK) { + if (f->state == LS_ACKRCVD) { + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = LS_OPENED; + if (f->callbacks->up) { + (*f->callbacks->up)(f); /* Inform upper layers */ + } + } else { + f->state = LS_ACKSENT; + } + f->nakloops = 0; + } else { + /* we sent CONFACK or CONFREJ */ + if (f->state != LS_ACKRCVD) { + f->state = LS_REQSENT; + } + if( code == CONFNAK ) { + ++f->nakloops; + } + } +} + + +/* + * fsm_rconfack - Receive Configure-Ack. + */ +static void +fsm_rconfack(fsm *f, int id, u_char *inp, int len) +{ + FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + if (id != f->reqid || f->seen_ack) { /* Expected id? */ + return; /* Nope, toss... */ + } + if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) { + /* Ack is bad - ignore it */ + FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n", + PROTO_NAME(f), len)); + return; + } + f->seen_ack = 1; + + switch (f->state) { + case LS_CLOSED: + case LS_STOPPED: + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); + break; + + case LS_REQSENT: + f->state = LS_ACKRCVD; + f->retransmits = f->maxconfreqtransmits; + break; + + case LS_ACKRCVD: + /* Huh? an extra valid Ack? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + break; + + case LS_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = LS_OPENED; + f->retransmits = f->maxconfreqtransmits; + if (f->callbacks->up) { + (*f->callbacks->up)(f); /* Inform upper layers */ + } + break; + + case LS_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } +} + + +/* + * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. + */ +static void +fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) +{ + int (*proc) (fsm *, u_char *, int); + int ret; + + FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + if (id != f->reqid || f->seen_ack) { /* Expected id? */ + return; /* Nope, toss... */ + } + proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci; + if (!proc || !((ret = proc(f, inp, len)))) { + /* Nak/reject is bad - ignore it */ + FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n", + PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len)); + return; + } + f->seen_ack = 1; + + switch (f->state) { + case LS_CLOSED: + case LS_STOPPED: + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); + break; + + case LS_REQSENT: + case LS_ACKSENT: + /* They didn't agree to what we wanted - try another request */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + if (ret < 0) { + f->state = LS_STOPPED; /* kludge for stopping CCP */ + } else { + fsm_sconfreq(f, 0); /* Send Configure-Request */ + } + break; + + case LS_ACKRCVD: + /* Got a Nak/reject when we had already had an Ack?? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = LS_REQSENT; + break; + + case LS_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = LS_REQSENT; + break; + } +} + + +/* + * fsm_rtermreq - Receive Terminate-Req. + */ +static void +fsm_rtermreq(fsm *f, int id, u_char *p, int len) +{ + LWIP_UNUSED_ARG(p); + + FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n", + PROTO_NAME(f), id, f->state, ppperr_strerr[f->state])); + + switch (f->state) { + case LS_ACKRCVD: + case LS_ACKSENT: + f->state = LS_REQSENT; /* Start over but keep trying */ + break; + + case LS_OPENED: + if (len > 0) { + FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p)); + } else { + FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f))); + } + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + f->retransmits = 0; + f->state = LS_STOPPING; + TIMEOUT(fsm_timeout, f, f->timeouttime); + break; + } + + fsm_sdata(f, TERMACK, (u_char)id, NULL, 0); +} + + +/* + * fsm_rtermack - Receive Terminate-Ack. + */ +static void +fsm_rtermack(fsm *f) +{ + FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + + switch (f->state) { + case LS_CLOSING: + UNTIMEOUT(fsm_timeout, f); + f->state = LS_CLOSED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_STOPPING: + UNTIMEOUT(fsm_timeout, f); + f->state = LS_STOPPED; + if( f->callbacks->finished ) { + (*f->callbacks->finished)(f); + } + break; + + case LS_ACKRCVD: + f->state = LS_REQSENT; + break; + + case LS_OPENED: + if (f->callbacks->down) { + (*f->callbacks->down)(f); /* Inform upper layers */ + } + fsm_sconfreq(f, 0); + break; + } +} + + +/* + * fsm_rcoderej - Receive an Code-Reject. + */ +static void +fsm_rcoderej(fsm *f, u_char *inp, int len) +{ + u_char code, id; + + FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d (%s)\n", + PROTO_NAME(f), f->state, ppperr_strerr[f->state])); + + if (len < HEADERLEN) { + FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n", + PROTO_NAME(f), code, id)); + + if( f->state == LS_ACKRCVD ) { + f->state = LS_REQSENT; + } +} + + +/* + * fsm_sconfreq - Send a Configure-Request. + */ +static void +fsm_sconfreq(fsm *f, int retransmit) +{ + u_char *outp; + int cilen; + + if( f->state != LS_REQSENT && f->state != LS_ACKRCVD && f->state != LS_ACKSENT ) { + /* Not currently negotiating - reset options */ + if( f->callbacks->resetci ) { + (*f->callbacks->resetci)(f); + } + f->nakloops = 0; + } + + if( !retransmit ) { + /* New request - reset retransmission counter, use new ID */ + f->retransmits = f->maxconfreqtransmits; + f->reqid = ++f->id; + } + + f->seen_ack = 0; + + /* + * Make up the request packet + */ + outp = outpacket_buf[f->unit] + PPP_HDRLEN + HEADERLEN; + if( f->callbacks->cilen && f->callbacks->addci ) { + cilen = (*f->callbacks->cilen)(f); + if( cilen > peer_mru[f->unit] - (int)HEADERLEN ) { + cilen = peer_mru[f->unit] - HEADERLEN; + } + if (f->callbacks->addci) { + (*f->callbacks->addci)(f, outp, &cilen); + } + } else { + cilen = 0; + } + + /* send the request to our peer */ + fsm_sdata(f, CONFREQ, f->reqid, outp, cilen); + + /* start the retransmit timer */ + --f->retransmits; + TIMEOUT(fsm_timeout, f, f->timeouttime); + + FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n", + PROTO_NAME(f), f->reqid)); +} + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.h new file mode 100644 index 0000000..14034ec --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/fsm.h @@ -0,0 +1,169 @@ +/***************************************************************************** +* fsm.h - Network Control Protocol Finite State Machine header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD code. +*****************************************************************************/ +/* + * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: fsm.h,v 1.4 2007/12/19 20:47:23 fbernon Exp $ + */ + +#ifndef FSM_H +#define FSM_H + +/***************************************************************************** +************************* PUBLIC DEFINITIONS ********************************* +*****************************************************************************/ +/* + * LCP Packet header = Code, id, length. + */ +#define HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) + + +/* + * CP (LCP, IPCP, etc.) codes. + */ +#define CONFREQ 1 /* Configuration Request */ +#define CONFACK 2 /* Configuration Ack */ +#define CONFNAK 3 /* Configuration Nak */ +#define CONFREJ 4 /* Configuration Reject */ +#define TERMREQ 5 /* Termination Request */ +#define TERMACK 6 /* Termination Ack */ +#define CODEREJ 7 /* Code Reject */ + +/* + * Link states. + */ +#define LS_INITIAL 0 /* Down, hasn't been opened */ +#define LS_STARTING 1 /* Down, been opened */ +#define LS_CLOSED 2 /* Up, hasn't been opened */ +#define LS_STOPPED 3 /* Open, waiting for down event */ +#define LS_CLOSING 4 /* Terminating the connection, not open */ +#define LS_STOPPING 5 /* Terminating, but open */ +#define LS_REQSENT 6 /* We've sent a Config Request */ +#define LS_ACKRCVD 7 /* We've received a Config Ack */ +#define LS_ACKSENT 8 /* We've sent a Config Ack */ +#define LS_OPENED 9 /* Connection available */ + +/* + * Flags - indicate options controlling FSM operation + */ +#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ +#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ +#define OPT_SILENT 4 /* Wait for peer to speak first */ + + +/***************************************************************************** +************************* PUBLIC DATA TYPES ********************************** +*****************************************************************************/ +/* + * Each FSM is described by an fsm structure and fsm callbacks. + */ +typedef struct fsm { + int unit; /* Interface unit number */ + u_short protocol; /* Data Link Layer Protocol field value */ + int state; /* State */ + int flags; /* Contains option bits */ + u_char id; /* Current id */ + u_char reqid; /* Current request id */ + u_char seen_ack; /* Have received valid Ack/Nak/Rej to Req */ + int timeouttime; /* Timeout time in milliseconds */ + int maxconfreqtransmits; /* Maximum Configure-Request transmissions */ + int retransmits; /* Number of retransmissions left */ + int maxtermtransmits; /* Maximum Terminate-Request transmissions */ + int nakloops; /* Number of nak loops since last ack */ + int maxnakloops; /* Maximum number of nak loops tolerated */ + struct fsm_callbacks* callbacks; /* Callback routines */ + char* term_reason; /* Reason for closing protocol */ + int term_reason_len; /* Length of term_reason */ +} fsm; + + +typedef struct fsm_callbacks { + void (*resetci)(fsm*); /* Reset our Configuration Information */ + int (*cilen)(fsm*); /* Length of our Configuration Information */ + void (*addci)(fsm*, u_char*, int*); /* Add our Configuration Information */ + int (*ackci)(fsm*, u_char*, int); /* ACK our Configuration Information */ + int (*nakci)(fsm*, u_char*, int); /* NAK our Configuration Information */ + int (*rejci)(fsm*, u_char*, int); /* Reject our Configuration Information */ + int (*reqci)(fsm*, u_char*, int*, int); /* Request peer's Configuration Information */ + void (*up)(fsm*); /* Called when fsm reaches LS_OPENED state */ + void (*down)(fsm*); /* Called when fsm leaves LS_OPENED state */ + void (*starting)(fsm*); /* Called when we want the lower layer */ + void (*finished)(fsm*); /* Called when we don't want the lower layer */ + void (*protreject)(int); /* Called when Protocol-Reject received */ + void (*retransmit)(fsm*); /* Retransmission is necessary */ + int (*extcode)(fsm*, int, u_char, u_char*, int); /* Called when unknown code received */ + char *proto_name; /* String name for protocol (for messages) */ +} fsm_callbacks; + + +/***************************************************************************** +*********************** PUBLIC DATA STRUCTURES ******************************* +*****************************************************************************/ +/* + * Variables + */ +extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */ + + +/***************************************************************************** +************************** PUBLIC FUNCTIONS ********************************** +*****************************************************************************/ + +/* + * Prototypes + */ +void fsm_init (fsm*); +void fsm_lowerup (fsm*); +void fsm_lowerdown (fsm*); +void fsm_open (fsm*); +void fsm_close (fsm*, char*); +void fsm_input (fsm*, u_char*, int); +void fsm_protreject (fsm*); +void fsm_sdata (fsm*, u_char, u_char, u_char*, int); + +#endif /* FSM_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.c new file mode 100644 index 0000000..0ff4ce3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.c @@ -0,0 +1,1427 @@ +/***************************************************************************** +* ipcp.c - Network PPP IP Control Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-08 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ +/* + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "auth.h" +#include "fsm.h" +#include "vj.h" +#include "ipcp.h" + +#include + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ +/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */ + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ +#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ +#define CILEN_ADDR 6 /* new-style single address option */ +#define CILEN_ADDRS 10 /* old-style dual address option */ + + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipcp_resetci (fsm *); /* Reset our CI */ +static int ipcp_cilen (fsm *); /* Return length of our CI */ +static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ +static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ +static int ipcp_nakci (fsm *, u_char *, int); /* Peer nak'd our CI */ +static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ +static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ +static void ipcp_up (fsm *); /* We're UP */ +static void ipcp_down (fsm *); /* We're DOWN */ +#if 0 +static void ipcp_script (fsm *, char *); /* Run an up/down script */ +#endif +static void ipcp_finished (fsm *); /* Don't need lower layer */ + +/* + * Protocol entry points from main code. + */ +static void ipcp_init (int); +static void ipcp_open (int); +static void ipcp_close (int, char *); +static void ipcp_lowerup (int); +static void ipcp_lowerdown (int); +static void ipcp_input (int, u_char *, int); +static void ipcp_protrej (int); + +static void ipcp_clear_addrs (int); + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +/* global vars */ +ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ + +fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ + +struct protent ipcp_protent = { + PPP_IPCP, + ipcp_init, + ipcp_input, + ipcp_protrej, + ipcp_lowerup, + ipcp_lowerdown, + ipcp_open, + ipcp_close, +#if 0 + ipcp_printpkt, + NULL, +#endif + 1, + "IPCP", +#if 0 + ip_check_options, + NULL, + ip_active_pkt +#endif +}; + + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +/* local vars */ +static int cis_received[NUM_PPP]; /* # Conf-Reqs received */ +static int default_route_set[NUM_PPP]; /* Have set up a default route */ + +static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ + ipcp_resetci, /* Reset our Configuration Information */ + ipcp_cilen, /* Length of our Configuration Information */ + ipcp_addci, /* Add our Configuration Information */ + ipcp_ackci, /* ACK our Configuration Information */ + ipcp_nakci, /* NAK our Configuration Information */ + ipcp_rejci, /* Reject our Configuration Information */ + ipcp_reqci, /* Request peer's Configuration Information */ + ipcp_up, /* Called when fsm reaches LS_OPENED state */ + ipcp_down, /* Called when fsm leaves LS_OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + NULL, /* Called to handle protocol-specific codes */ + "IPCP" /* String name of protocol */ +}; + + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +#define inet_ntoa(addr) ip_ntoa(((struct ip_addr*)&(addr))) + +/* + * ipcp_init - Initialize IPCP. + */ +static void +ipcp_init(int unit) +{ + fsm *f = &ipcp_fsm[unit]; + ipcp_options *wo = &ipcp_wantoptions[unit]; + ipcp_options *ao = &ipcp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_IPCP; + f->callbacks = &ipcp_callbacks; + fsm_init(&ipcp_fsm[unit]); + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->neg_addr = 1; + wo->ouraddr = 0; +#if VJ_SUPPORT + wo->neg_vj = 1; +#else /* VJ_SUPPORT */ + wo->neg_vj = 0; +#endif /* VJ_SUPPORT */ + wo->vj_protocol = IPCP_VJ_COMP; + wo->maxslotindex = MAX_SLOTS - 1; + wo->cflag = 0; + wo->default_route = 1; + + ao->neg_addr = 1; +#if VJ_SUPPORT + ao->neg_vj = 1; +#else /* VJ_SUPPORT */ + ao->neg_vj = 0; +#endif /* VJ_SUPPORT */ + ao->maxslotindex = MAX_SLOTS - 1; + ao->cflag = 1; + ao->default_route = 1; +} + + +/* + * ipcp_open - IPCP is allowed to come up. + */ +static void +ipcp_open(int unit) +{ + fsm_open(&ipcp_fsm[unit]); +} + + +/* + * ipcp_close - Take IPCP down. + */ +static void +ipcp_close(int unit, char *reason) +{ + fsm_close(&ipcp_fsm[unit], reason); +} + + +/* + * ipcp_lowerup - The lower layer is up. + */ +static void +ipcp_lowerup(int unit) +{ + fsm_lowerup(&ipcp_fsm[unit]); +} + + +/* + * ipcp_lowerdown - The lower layer is down. + */ +static void +ipcp_lowerdown(int unit) +{ + fsm_lowerdown(&ipcp_fsm[unit]); +} + + +/* + * ipcp_input - Input IPCP packet. + */ +static void +ipcp_input(int unit, u_char *p, int len) +{ + fsm_input(&ipcp_fsm[unit], p, len); +} + + +/* + * ipcp_protrej - A Protocol-Reject was received for IPCP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void +ipcp_protrej(int unit) +{ + fsm_lowerdown(&ipcp_fsm[unit]); +} + + +/* + * ipcp_resetci - Reset our CI. + */ +static void +ipcp_resetci(fsm *f) +{ + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + + wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr; + if (wo->ouraddr == 0) { + wo->accept_local = 1; + } + if (wo->hisaddr == 0) { + wo->accept_remote = 1; + } + /* Request DNS addresses from the peer */ + wo->req_dns1 = ppp_settings.usepeerdns; + wo->req_dns2 = ppp_settings.usepeerdns; + ipcp_gotoptions[f->unit] = *wo; + cis_received[f->unit] = 0; +} + + +/* + * ipcp_cilen - Return length of our CI. + */ +static int +ipcp_cilen(fsm *f) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + +#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) +#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0) +#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0) + + /* + * First see if we want to change our options to the old + * forms because we have received old forms from the peer. + */ + if (wo->neg_addr && !go->neg_addr && !go->old_addrs) { + /* use the old style of address negotiation */ + go->neg_addr = 1; + go->old_addrs = 1; + } + if (wo->neg_vj && !go->neg_vj && !go->old_vj) { + /* try an older style of VJ negotiation */ + if (cis_received[f->unit] == 0) { + /* keep trying the new style until we see some CI from the peer */ + go->neg_vj = 1; + } else { + /* use the old style only if the peer did */ + if (ho->neg_vj && ho->old_vj) { + go->neg_vj = 1; + go->old_vj = 1; + go->vj_protocol = ho->vj_protocol; + } + } + } + + return (LENCIADDR(go->neg_addr, go->old_addrs) + + LENCIVJ(go->neg_vj, go->old_vj) + + LENCIDNS(go->req_dns1) + + LENCIDNS(go->req_dns2)); +} + + +/* + * ipcp_addci - Add our desired CIs to a packet. + */ +static void +ipcp_addci(fsm *f, u_char *ucp, int *lenp) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + int len = *lenp; + +#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + if (!old) { \ + PUTCHAR(maxslotindex, ucp); \ + PUTCHAR(cflag, ucp); \ + } \ + len -= vjlen; \ + } else { \ + neg = 0; \ + } \ + } + +#define ADDCIADDR(opt, neg, old, val1, val2) \ + if (neg) { \ + int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ + if (len >= addrlen) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(addrlen, ucp); \ + l = ntohl(val1); \ + PUTLONG(l, ucp); \ + if (old) { \ + l = ntohl(val2); \ + PUTLONG(l, ucp); \ + } \ + len -= addrlen; \ + } else { \ + neg = 0; \ + } \ + } + +#define ADDCIDNS(opt, neg, addr) \ + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(addr); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else { \ + neg = 0; \ + } \ + } + + ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + *lenp -= len; +} + + +/* + * ipcp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +ipcp_ackci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_short cilen, citype, cishort; + u32_t cilong; + u_char cimaxslotindex, cicflag; + + /* + * CIs must be in exactly the same order that we sent... + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ + +#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if ((len -= vjlen) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != vjlen || \ + citype != opt) { \ + goto bad; \ + } \ + GETSHORT(cishort, p); \ + if (cishort != val) { \ + goto bad; \ + } \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslotindex) { \ + goto bad; \ + } \ + GETCHAR(cicflag, p); \ + if (cicflag != cflag) { \ + goto bad; \ + } \ + } \ + } + +#define ACKCIADDR(opt, neg, old, val1, val2) \ + if (neg) { \ + int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \ + u32_t l; \ + if ((len -= addrlen) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != addrlen || \ + citype != opt) { \ + goto bad; \ + } \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val1 != cilong) { \ + goto bad; \ + } \ + if (old) { \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val2 != cilong) { \ + goto bad; \ + } \ + } \ + } + +#define ACKCIDNS(opt, neg, addr) \ + if (neg) { \ + u32_t l; \ + if ((len -= CILEN_ADDR) < 0) { \ + goto bad; \ + } \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || \ + citype != opt) { \ + goto bad; \ + } \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (addr != cilong) { \ + goto bad; \ + } \ + } + + ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + return (1); + +bad: + IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n")); + return (0); +} + +/* + * ipcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPCP is in the LS_OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +ipcp_nakci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, cicflag; + u_char citype, cilen, *next; + u_short cishort; + u32_t ciaddr1, ciaddr2, l, cidnsaddr; + ipcp_options no; /* options we've seen Naks for */ + ipcp_options try; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIADDR(opt, neg, old, code) \ + if (go->neg && \ + len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + if (old) { \ + GETLONG(l, p); \ + ciaddr2 = htonl(l); \ + no.old_addrs = 1; \ + } else { \ + ciaddr2 = 0; \ + } \ + no.neg = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIDNS(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cidnsaddr = htonl(l); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} address, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs, + if (go->accept_local && ciaddr1) { /* Do we know our address? */ + try.ouraddr = ciaddr1; + IPCPDEBUG((LOG_INFO, "local IP address %s\n", + inet_ntoa(ciaddr1))); + } + if (go->accept_remote && ciaddr2) { /* Does he know his? */ + try.hisaddr = ciaddr2; + IPCPDEBUG((LOG_INFO, "remote IP address %s\n", + inet_ntoa(ciaddr2))); + } + ); + + /* + * Accept the peer's value of maxslotindex provided that it + * is less than what we asked for. Turn off slot-ID compression + * if the peer wants. Send old-style compress-type option if + * the peer wants. + */ + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + if (cilen == CILEN_VJ) { + GETCHAR(cimaxslotindex, p); + GETCHAR(cicflag, p); + if (cishort == IPCP_VJ_COMP) { + try.old_vj = 0; + if (cimaxslotindex < go->maxslotindex) { + try.maxslotindex = cimaxslotindex; + } + if (!cicflag) { + try.cflag = 0; + } + } else { + try.neg_vj = 0; + } + } else { + if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { + try.old_vj = 1; + try.vj_protocol = cishort; + } else { + try.neg_vj = 0; + } + } + ); + + NAKCIDNS(CI_MS_DNS1, req_dns1, + try.dnsaddr[0] = cidnsaddr; + IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr))); + ); + + NAKCIDNS(CI_MS_DNS2, req_dns2, + try.dnsaddr[1] = cidnsaddr; + IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr))); + ); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If they want to negotiate about IP addresses, we comply. + * If they want us to ask for compression, we refuse. + */ + while (len > CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if( (len -= cilen) < 0 ) { + goto bad; + } + next = p + cilen - 2; + + switch (citype) { + case CI_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { + goto bad; + } + no.neg_vj = 1; + break; + case CI_ADDRS: + if ((go->neg_addr && go->old_addrs) || no.old_addrs + || cilen != CILEN_ADDRS) { + goto bad; + } + try.neg_addr = 1; + try.old_addrs = 1; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) { + try.ouraddr = ciaddr1; + } + GETLONG(l, p); + ciaddr2 = htonl(l); + if (ciaddr2 && go->accept_remote) { + try.hisaddr = ciaddr2; + } + no.old_addrs = 1; + break; + case CI_ADDR: + if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) { + goto bad; + } + try.old_addrs = 0; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) { + try.ouraddr = ciaddr1; + } + if (try.ouraddr != 0) { + try.neg_addr = 1; + } + no.neg_addr = 1; + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) { + goto bad; + } + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + + return 1; + +bad: + IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n")); + return 0; +} + + +/* + * ipcp_rejci - Reject some of our CIs. + */ +static int +ipcp_rejci(fsm *f, u_char *p, int len) +{ + ipcp_options *go = &ipcp_gotoptions[f->unit]; + u_char cimaxslotindex, ciflag, cilen; + u_short cishort; + u32_t cilong; + ipcp_options try; /* options to request next time */ + + try = *go; + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIADDR(opt, neg, old, val1, val2) \ + if (go->neg && \ + len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \ + p[1] == cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val1) { \ + goto bad; \ + } \ + if (old) { \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val2) { \ + goto bad; \ + } \ + } \ + try.neg = 0; \ + } + +#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ + if (go->neg && \ + p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) { \ + goto bad; \ + } \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslot) { \ + goto bad; \ + } \ + GETCHAR(ciflag, p); \ + if (ciflag != cflag) { \ + goto bad; \ + } \ + } \ + try.neg = 0; \ + } + +#define REJCIDNS(opt, neg, dnsaddr) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != dnsaddr) { \ + goto bad; \ + } \ + try.neg = 0; \ + } + + REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, + go->old_addrs, go->ouraddr, go->hisaddr); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); + + REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + /* + * Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + return 1; + +bad: + IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n")); + return 0; +} + + +/* + * ipcp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + */ +static int +ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested CIs */,int reject_if_disagree) +{ + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *ao = &ipcp_allowoptions[f->unit]; +#ifdef OLD_CI_ADDRS + ipcp_options *go = &ipcp_gotoptions[f->unit]; +#endif + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + u32_t tl, ciaddr1; /* Parsed address values */ +#ifdef OLD_CI_ADDRS + u32_t ciaddr2; /* Parsed address values */ +#endif + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *ucp = inp; /* Pointer to current output char */ + int l = *len; /* Length left */ + u_char maxslotindex, cflag; + int d; + + cis_received[f->unit] = 1; + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ +#ifdef OLD_CI_ADDRS /* Need to save space... */ + case CI_ADDRS: + IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n")); + if (!ao->neg_addr || + cilen != CILEN_ADDRS) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1))); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * If neither we nor he knows his address, reject the option. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + /* + * If he doesn't know our address, or if we both have our address + * but disagree about it, then NAK it with our idea. + */ + GETLONG(tl, p); /* Parse desination address (ours) */ + ciaddr2 = htonl(tl); + IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2))); + if (ciaddr2 != wo->ouraddr) { + if (ciaddr2 == 0 || !wo->accept_local) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->ouraddr); + PUTLONG(tl, p); + } + } else { + go->ouraddr = ciaddr2; /* accept peer's idea */ + } + } + + ho->neg_addr = 1; + ho->old_addrs = 1; + ho->hisaddr = ciaddr1; + ho->ouraddr = ciaddr2; + break; +#endif + + case CI_ADDR: + if (!ao->neg_addr) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n")); + orc = CONFREJ; /* Reject CI */ + break; + } else if (cilen != CILEN_ADDR) { /* Check CI length */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n")); + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1))); + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * Don't ACK an address of 0.0.0.0 - reject it instead. + */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1))); + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + ho->neg_addr = 1; + ho->hisaddr = ciaddr1; + IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1))); + break; + + case CI_MS_DNS1: + case CI_MS_DNS2: + /* Microsoft primary or secondary DNS request */ + d = citype == CI_MS_DNS2; + + /* If we do not have a DNS address then we cannot send it */ + if (ao->dnsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1)); + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->dnsaddr[d]) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n", + d+1, inet_ntoa(tl))); + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->dnsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1)); + break; + + case CI_MS_WINS1: + case CI_MS_WINS2: + /* Microsoft primary or secondary WINS request */ + d = citype == CI_MS_WINS2; + IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1)); + + /* If we do not have a DNS address then we cannot send it */ + if (ao->winsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->winsaddr[d]) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->winsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; + + case CI_COMPRESSTYPE: + if (!ao->neg_vj) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen)); + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + if (!(cishort == IPCP_VJ_COMP || + (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort)); + orc = CONFREJ; + break; + } + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + if (cilen == CILEN_VJ) { + GETCHAR(maxslotindex, p); + if (maxslotindex > ao->maxslotindex) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex)); + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(1, p); + PUTCHAR(ao->maxslotindex, p); + } + } + GETCHAR(cflag, p); + if (cflag && !ao->cflag) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag)); + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(1, p); + PUTCHAR(wo->cflag, p); + } + } + ho->maxslotindex = maxslotindex; + ho->cflag = cflag; + } else { + ho->old_vj = 1; + ho->maxslotindex = MAX_SLOTS - 1; + ho->cflag = 1; + } + IPCPDEBUG((LOG_INFO, + "ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n", + ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag)); + break; + + default: + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype)); + orc = CONFREJ; + break; + } + +endswitch: + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) { /* but prior CI wasnt? */ + continue; /* Don't send this one */ + } + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree) { /* Getting fed up with sending NAKs? */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n")); + orc = CONFREJ; /* Get tough if so */ + } else { + if (rc == CONFREJ) { /* Rejecting prior CI? */ + continue; /* Don't send this one */ + } + if (rc == CONFACK) { /* Ack'd all prior CIs? */ + rc = CONFNAK; /* Not anymore... */ + ucp = inp; /* Backup */ + } + } + } + + if (orc == CONFREJ && /* Reject this CI */ + rc != CONFREJ) { /* but no prior ones? */ + rc = CONFREJ; + ucp = inp; /* Backup */ + } + + /* Need to move CI? */ + if (ucp != cip) { + BCOPY(cip, ucp, cilen); /* Move it */ + } + + /* Update output pointer */ + INCPTR(cilen, ucp); + } + + /* + * If we aren't rejecting this packet, and we want to negotiate + * their address, and they didn't send their address, then we + * send a NAK with a CI_ADDR option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_addr && + wo->req_addr && !reject_if_disagree) { + IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n")); + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_addr = 0; /* don't ask again */ + } + PUTCHAR(CI_ADDR, ucp); + PUTCHAR(CILEN_ADDR, ucp); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, ucp); + } + + *len = (int)(ucp - inp); /* Compute output length */ + IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +#if 0 +/* + * ip_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void +ip_check_options(u_long localAddr) +{ + ipcp_options *wo = &ipcp_wantoptions[0]; + + /* + * Load our default IP address but allow the remote host to give us + * a new address. + */ + if (wo->ouraddr == 0 && !ppp_settings.disable_defaultip) { + wo->accept_local = 1; /* don't insist on this default value */ + wo->ouraddr = htonl(localAddr); + } +} +#endif + + +/* + * ipcp_up - IPCP has come UP. + * + * Configure the IP network interface appropriately and bring it up. + */ +static void +ipcp_up(fsm *f) +{ + u32_t mask; + ipcp_options *ho = &ipcp_hisoptions[f->unit]; + ipcp_options *go = &ipcp_gotoptions[f->unit]; + ipcp_options *wo = &ipcp_wantoptions[f->unit]; + + np_up(f->unit, PPP_IP); + IPCPDEBUG((LOG_INFO, "ipcp: up\n")); + + /* + * We must have a non-zero IP address for both ends of the link. + */ + if (!ho->neg_addr) { + ho->hisaddr = wo->hisaddr; + } + + if (ho->hisaddr == 0) { + IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n")); + ipcp_close(f->unit, "Could not determine remote IP address"); + return; + } + if (go->ouraddr == 0) { + IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n")); + ipcp_close(f->unit, "Could not determine local IP address"); + return; + } + + if (ppp_settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + /*pppGotDNSAddrs(go->dnsaddr[0], go->dnsaddr[1]);*/ + } + + /* + * Check that the peer is allowed to use the IP address it wants. + */ + if (!auth_ip_addr(f->unit, ho->hisaddr)) { + IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n", + inet_ntoa(ho->hisaddr))); + ipcp_close(f->unit, "Unauthorized remote IP address"); + return; + } + + /* set tcp compression */ + sifvjcomp(f->unit, ho->neg_vj, ho->cflag, ho->maxslotindex); + + /* + * Set IP addresses and (if specified) netmask. + */ + mask = GetMask(go->ouraddr); + + if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) { + IPCPDEBUG((LOG_WARNING, "sifaddr failed\n")); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + + /* bring the interface up for IP */ + if (!sifup(f->unit)) { + IPCPDEBUG((LOG_WARNING, "sifup failed\n")); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + + sifnpmode(f->unit, PPP_IP, NPMODE_PASS); + + /* assign a default route through the interface if required */ + if (ipcp_wantoptions[f->unit].default_route) { + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) { + default_route_set[f->unit] = 1; + } + } + + IPCPDEBUG((LOG_NOTICE, "local IP address %s\n", inet_ntoa(go->ouraddr))); + IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr))); + if (go->dnsaddr[0]) { + IPCPDEBUG((LOG_NOTICE, "primary DNS address %s\n", inet_ntoa(go->dnsaddr[0]))); + } + if (go->dnsaddr[1]) { + IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1]))); + } +} + + +/* + * ipcp_down - IPCP has gone DOWN. + * + * Take the IP network interface down, clear its addresses + * and delete routes through it. + */ +static void +ipcp_down(fsm *f) +{ + IPCPDEBUG((LOG_INFO, "ipcp: down\n")); + np_down(f->unit, PPP_IP); + sifvjcomp(f->unit, 0, 0, 0); + + sifdown(f->unit); + ipcp_clear_addrs(f->unit); +} + + +/* + * ipcp_clear_addrs() - clear the interface addresses, routes, etc. + */ +static void +ipcp_clear_addrs(int unit) +{ + u32_t ouraddr, hisaddr; + + ouraddr = ipcp_gotoptions[unit].ouraddr; + hisaddr = ipcp_hisoptions[unit].hisaddr; + if (default_route_set[unit]) { + cifdefaultroute(unit, ouraddr, hisaddr); + default_route_set[unit] = 0; + } + cifaddr(unit, ouraddr, hisaddr); +} + + +/* + * ipcp_finished - possibly shut down the lower layers. + */ +static void +ipcp_finished(fsm *f) +{ + np_finished(f->unit, PPP_IP); +} + +#if 0 +static int +ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + LWIP_UNUSED_ARG(p); + LWIP_UNUSED_ARG(plen); + LWIP_UNUSED_ARG(printer); + LWIP_UNUSED_ARG(arg); + return 0; +} + +/* + * ip_active_pkt - see if this IP packet is worth bringing the link up for. + * We don't bring the link up for IP fragments or for TCP FIN packets + * with no data. + */ +#define IP_HDRLEN 20 /* bytes */ +#define IP_OFFMASK 0x1fff +#define IPPROTO_TCP 6 +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 + +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define net_short(x) (((x)[0] << 8) + (x)[1]) +#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) +#define get_ipoff(x) net_short((unsigned char *)(x) + 6) +#define get_ipproto(x) (((unsigned char *)(x))[9]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int +ip_active_pkt(u_char *pkt, int len) +{ + u_char *tcp; + int hlen; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP_HDRLEN) { + return 0; + } + if ((get_ipoff(pkt) & IP_OFFMASK) != 0) { + return 0; + } + if (get_ipproto(pkt) != IPPROTO_TCP) { + return 1; + } + hlen = get_iphl(pkt) * 4; + if (len < hlen + TCP_HDRLEN) { + return 0; + } + tcp = pkt + hlen; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) { + return 0; + } + return 1; +} +#endif + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.h new file mode 100644 index 0000000..dfcf4fb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ipcp.h @@ -0,0 +1,124 @@ +/***************************************************************************** +* ipcp.h - PPP IP NCP: Internet Protocol Network Control Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: ipcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $ + */ + +#ifndef IPCP_H +#define IPCP_H + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ +/* + * Options. + */ +#define CI_ADDRS 1 /* IP Addresses */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ +#define CI_ADDR 3 + +#define CI_MS_WINS1 128 /* Primary WINS value */ +#define CI_MS_DNS1 129 /* Primary DNS value */ +#define CI_MS_WINS2 130 /* Secondary WINS value */ +#define CI_MS_DNS2 131 /* Secondary DNS value */ + +#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ +#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ +#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ + /* maxslot and slot number compression) */ + +#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option */ +#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ + /* compression option */ + + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +typedef struct ipcp_options { + u_int neg_addr : 1; /* Negotiate IP Address? */ + u_int old_addrs : 1; /* Use old (IP-Addresses) option? */ + u_int req_addr : 1; /* Ask peer to send IP address? */ + u_int default_route : 1; /* Assign default route through interface? */ + u_int proxy_arp : 1; /* Make proxy ARP entry for peer? */ + u_int neg_vj : 1; /* Van Jacobson Compression? */ + u_int old_vj : 1; /* use old (short) form of VJ option? */ + u_int accept_local : 1; /* accept peer's value for ouraddr */ + u_int accept_remote : 1; /* accept peer's value for hisaddr */ + u_int req_dns1 : 1; /* Ask peer to send primary DNS address? */ + u_int req_dns2 : 1; /* Ask peer to send secondary DNS address? */ + u_short vj_protocol; /* protocol value to use in VJ option */ + u_char maxslotindex; /* VJ slots - 1. */ + u_char cflag; /* VJ slot compression flag. */ + u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ + u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ + u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ +} ipcp_options; + + +/***************************** +*** PUBLIC DATA STRUCTURES *** +*****************************/ + +extern fsm ipcp_fsm[]; +extern ipcp_options ipcp_wantoptions[]; +extern ipcp_options ipcp_gotoptions[]; +extern ipcp_options ipcp_allowoptions[]; +extern ipcp_options ipcp_hisoptions[]; + +extern struct protent ipcp_protent; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +#endif /* IPCP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.c new file mode 100644 index 0000000..85a0add --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.c @@ -0,0 +1,2035 @@ +/***************************************************************************** +* lcp.c - Network Link Control Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-01 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + +/* + * lcp.c - PPP Link Control Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "fsm.h" +#include "chap.h" +#include "magic.h" +#include "auth.h" +#include "lcp.h" + +#include + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#else +#define PPPOE_MAXMTU PPP_MAXMRU +#endif + + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ +/* + * Length of each type of configuration option (in octets) + */ +#define CILEN_VOID 2 +#define CILEN_CHAR 3 +#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */ +#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */ +#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */ +#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */ +#define CILEN_CBCP 3 + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void lcp_resetci (fsm*); /* Reset our CI */ +static int lcp_cilen (fsm*); /* Return length of our CI */ +static void lcp_addci (fsm*, u_char*, int*); /* Add our CI to pkt */ +static int lcp_ackci (fsm*, u_char*, int); /* Peer ack'd our CI */ +static int lcp_nakci (fsm*, u_char*, int); /* Peer nak'd our CI */ +static int lcp_rejci (fsm*, u_char*, int); /* Peer rej'd our CI */ +static int lcp_reqci (fsm*, u_char*, int*, int); /* Rcv peer CI */ +static void lcp_up (fsm*); /* We're UP */ +static void lcp_down (fsm*); /* We're DOWN */ +static void lcp_starting (fsm*); /* We need lower layer up */ +static void lcp_finished (fsm*); /* We need lower layer down */ +static int lcp_extcode (fsm*, int, u_char, u_char*, int); + +static void lcp_rprotrej (fsm*, u_char*, int); + +/* + * routines to send LCP echos to peer + */ +static void lcp_echo_lowerup (int); +static void lcp_echo_lowerdown (int); +static void LcpEchoTimeout (void*); +static void lcp_received_echo_reply (fsm*, int, u_char*, int); +static void LcpSendEchoRequest (fsm*); +static void LcpLinkFailure (fsm*); +static void LcpEchoCheck (fsm*); + +/* + * Protocol entry points. + * Some of these are called directly. + */ +static void lcp_input (int, u_char *, int); +static void lcp_protrej (int); + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ") + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +/* global vars */ +LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ +lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */ +lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */ +lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */ +lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */ +ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */ + + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/ +static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ +static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ +static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */ +static u32_t lcp_echo_number = 0; /* ID number of next echo frame */ +static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */ + +static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */ + +static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ + lcp_resetci, /* Reset our Configuration Information */ + lcp_cilen, /* Length of our Configuration Information */ + lcp_addci, /* Add our Configuration Information */ + lcp_ackci, /* ACK our Configuration Information */ + lcp_nakci, /* NAK our Configuration Information */ + lcp_rejci, /* Reject our Configuration Information */ + lcp_reqci, /* Request peer's Configuration Information */ + lcp_up, /* Called when fsm reaches LS_OPENED state */ + lcp_down, /* Called when fsm leaves LS_OPENED state */ + lcp_starting, /* Called when we want the lower layer up */ + lcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + lcp_extcode, /* Called to handle LCP-specific codes */ + "LCP" /* String name of protocol */ +}; + +struct protent lcp_protent = { + PPP_LCP, + lcp_init, + lcp_input, + lcp_protrej, + lcp_lowerup, + lcp_lowerdown, + lcp_open, + lcp_close, +#if 0 + lcp_printpkt, + NULL, +#endif + 1, + "LCP", +#if 0 + NULL, + NULL, + NULL +#endif +}; + +int lcp_loopbackfail = DEFLOOPBACKFAIL; + + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * lcp_init - Initialize LCP. + */ +void +lcp_init(int unit) +{ + fsm *f = &lcp_fsm[unit]; + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + + f->unit = unit; + f->protocol = PPP_LCP; + f->callbacks = &lcp_callbacks; + + fsm_init(f); + + wo->passive = 0; + wo->silent = 0; + wo->restart = 0; /* Set to 1 in kernels or multi-line implementations */ + wo->neg_mru = 1; + wo->mru = PPP_DEFMRU; + wo->neg_asyncmap = 1; + wo->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ + wo->neg_chap = 0; /* Set to 1 on server */ + wo->neg_upap = 0; /* Set to 1 on server */ + wo->chap_mdtype = CHAP_DIGEST_MD5; + wo->neg_magicnumber = 1; + wo->neg_pcompression = 1; + wo->neg_accompression = 1; + wo->neg_lqr = 0; /* no LQR implementation yet */ + wo->neg_cbcp = 0; + + ao->neg_mru = 1; + ao->mru = PPP_MAXMRU; + ao->neg_asyncmap = 1; + ao->asyncmap = 0x00000000l; /* Assume don't need to escape any ctl chars. */ + ao->neg_chap = (CHAP_SUPPORT != 0); + ao->chap_mdtype = CHAP_DIGEST_MD5; + ao->neg_upap = (PAP_SUPPORT != 0); + ao->neg_magicnumber = 1; + ao->neg_pcompression = 1; + ao->neg_accompression = 1; + ao->neg_lqr = 0; /* no LQR implementation yet */ + ao->neg_cbcp = (CBCP_SUPPORT != 0); + + /* + * Set transmit escape for the flag and escape characters plus anything + * set for the allowable options. + */ + memset(xmit_accm[unit], 0, sizeof(xmit_accm[0])); + xmit_accm[unit][15] = 0x60; + xmit_accm[unit][0] = (u_char)((ao->asyncmap & 0xFF)); + xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n", + xmit_accm[unit][0], + xmit_accm[unit][1], + xmit_accm[unit][2], + xmit_accm[unit][3])); + + lcp_phase[unit] = PHASE_INITIALIZE; +} + + +/* + * lcp_open - LCP is allowed to come up. + */ +void +lcp_open(int unit) +{ + fsm *f = &lcp_fsm[unit]; + lcp_options *wo = &lcp_wantoptions[unit]; + + f->flags = 0; + if (wo->passive) { + f->flags |= OPT_PASSIVE; + } + if (wo->silent) { + f->flags |= OPT_SILENT; + } + fsm_open(f); + + lcp_phase[unit] = PHASE_ESTABLISH; +} + + +/* + * lcp_close - Take LCP down. + */ +void +lcp_close(int unit, char *reason) +{ + fsm *f = &lcp_fsm[unit]; + + if (lcp_phase[unit] != PHASE_DEAD) { + lcp_phase[unit] = PHASE_TERMINATE; + } + if (f->state == LS_STOPPED && f->flags & (OPT_PASSIVE|OPT_SILENT)) { + /* + * This action is not strictly according to the FSM in RFC1548, + * but it does mean that the program terminates if you do an + * lcp_close() in passive/silent mode when a connection hasn't + * been established. + */ + f->state = LS_CLOSED; + lcp_finished(f); + } else { + fsm_close(&lcp_fsm[unit], reason); + } +} + + +/* + * lcp_lowerup - The lower layer is up. + */ +void +lcp_lowerup(int unit) +{ + lcp_options *wo = &lcp_wantoptions[unit]; + + /* + * Don't use A/C or protocol compression on transmission, + * but accept A/C and protocol compressed packets + * if we are going to ask for A/C and protocol compression. + */ + ppp_set_xaccm(unit, &xmit_accm[unit]); + ppp_send_config(unit, PPP_MRU, 0xffffffffl, 0, 0); + ppp_recv_config(unit, PPP_MRU, 0x00000000l, + wo->neg_pcompression, wo->neg_accompression); + peer_mru[unit] = PPP_MRU; + lcp_allowoptions[unit].asyncmap = (u_long)xmit_accm[unit][0] + | ((u_long)xmit_accm[unit][1] << 8) + | ((u_long)xmit_accm[unit][2] << 16) + | ((u_long)xmit_accm[unit][3] << 24); + LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n", + xmit_accm[unit][3], + xmit_accm[unit][2], + xmit_accm[unit][1], + xmit_accm[unit][0])); + + fsm_lowerup(&lcp_fsm[unit]); +} + + +/* + * lcp_lowerdown - The lower layer is down. + */ +void +lcp_lowerdown(int unit) +{ + fsm_lowerdown(&lcp_fsm[unit]); +} + +/* + * lcp_sprotrej - Send a Protocol-Reject for some protocol. + */ +void +lcp_sprotrej(int unit, u_char *p, int len) +{ + /* + * Send back the protocol and the information field of the + * rejected packet. We only get here if LCP is in the LS_OPENED state. + */ + + fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len); +} + + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ +/* + * lcp_input - Input LCP packet. + */ +static void +lcp_input(int unit, u_char *p, int len) +{ + fsm *f = &lcp_fsm[unit]; + + fsm_input(f, p, len); +} + + +/* + * lcp_extcode - Handle a LCP-specific code. + */ +static int +lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len) +{ + u_char *magp; + + switch( code ){ + case PROTREJ: + lcp_rprotrej(f, inp, len); + break; + + case ECHOREQ: + if (f->state != LS_OPENED) { + break; + } + LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id)); + magp = inp; + PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp); + fsm_sdata(f, ECHOREP, id, inp, len); + break; + + case ECHOREP: + lcp_received_echo_reply(f, id, inp, len); + break; + + case DISCREQ: + break; + + default: + return 0; + } + return 1; +} + + +/* + * lcp_rprotrej - Receive an Protocol-Reject. + * + * Figure out which protocol is rejected and inform it. + */ +static void +lcp_rprotrej(fsm *f, u_char *inp, int len) +{ + int i; + struct protent *protp; + u_short prot; + + if (len < sizeof (u_short)) { + LCPDEBUG((LOG_INFO, "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n")); + return; + } + + GETSHORT(prot, inp); + + LCPDEBUG((LOG_INFO, "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot)); + + /* + * Protocol-Reject packets received in any state other than the LCP + * LS_OPENED state SHOULD be silently discarded. + */ + if( f->state != LS_OPENED ) { + LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n", f->state)); + return; + } + + /* + * Upcall the proper Protocol-Reject routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == prot && protp->enabled_flag) { + (*protp->protrej)(f->unit); + return; + } + } + + LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n", prot)); +} + + +/* + * lcp_protrej - A Protocol-Reject was received. + */ +static void +lcp_protrej(int unit) +{ + LWIP_UNUSED_ARG(unit); + /* + * Can't reject LCP! + */ + LCPDEBUG((LOG_WARNING, "lcp_protrej: Received Protocol-Reject for LCP!\n")); + fsm_protreject(&lcp_fsm[unit]); +} + + +/* + * lcp_resetci - Reset our CI. + */ +static void +lcp_resetci(fsm *f) +{ + lcp_wantoptions[f->unit].magicnumber = magic(); + lcp_wantoptions[f->unit].numloops = 0; + lcp_gotoptions[f->unit] = lcp_wantoptions[f->unit]; + peer_mru[f->unit] = PPP_MRU; + auth_reset(f->unit); +} + + +/* + * lcp_cilen - Return length of our CI. + */ +static int lcp_cilen(fsm *f) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + +#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) +#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) +#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) +#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) +#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) + /* + * NB: we only ask for one of CHAP and UPAP, even if we will + * accept either. + */ + return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) + + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + + LENCICHAP(go->neg_chap) + + LENCISHORT(!go->neg_chap && go->neg_upap) + + LENCILQR(go->neg_lqr) + + LENCICBCP(go->neg_cbcp) + + LENCILONG(go->neg_magicnumber) + + LENCIVOID(go->neg_pcompression) + + LENCIVOID(go->neg_accompression)); +} + + +/* + * lcp_addci - Add our desired CIs to a packet. + */ +static void +lcp_addci(fsm *f, u_char *ucp, int *lenp) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char *start_ucp = ucp; + +#define ADDCIVOID(opt, neg) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_VOID, ucp); \ + } +#define ADDCISHORT(opt, neg, val) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_SHORT, ucp); \ + PUTSHORT(val, ucp); \ + } +#define ADDCICHAP(opt, neg, val, digest) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAP, ucp); \ + PUTSHORT(val, ucp); \ + PUTCHAR(digest, ucp); \ + } +#define ADDCILONG(opt, neg, val) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LONG, ucp); \ + PUTLONG(val, ucp); \ + } +#define ADDCILQR(opt, neg, val) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LQR, ucp); \ + PUTSHORT(PPP_LQR, ucp); \ + PUTLONG(val, ucp); \ + } +#define ADDCICHAR(opt, neg, val) \ + if (neg) { \ + LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } + + ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); + ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); + ADDCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); + ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); + + if (ucp - start_ucp != *lenp) { + /* this should never happen, because peer_mtu should be 1500 */ + LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n")); + } +} + + +/* + * lcp_ackci - Ack our CIs. + * This should not modify any state if the Ack is bad. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int +lcp_ackci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cilen, citype, cichar; + u_short cishort; + u32_t cilong; + + /* + * CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define ACKCIVOID(opt, neg) \ + if (neg) { \ + if ((len -= CILEN_VOID) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_VOID || citype != opt) \ + goto bad; \ + } +#define ACKCISHORT(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_SHORT) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_SHORT || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + } +#define ACKCICHAR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR || citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != val) \ + goto bad; \ + } +#define ACKCICHAP(opt, neg, val, digest) \ + if (neg) { \ + if ((len -= CILEN_CHAP) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAP || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != digest) \ + goto bad; \ + } +#define ACKCILONG(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LONG) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LONG || citype != opt) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } +#define ACKCILQR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LQR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LQR || citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != PPP_LQR) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } + + ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); + ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl, go->asyncmap); + ACKCICHAP(CI_AUTHTYPE, go->neg_chap, PPP_CHAP, go->chap_mdtype); + ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); + ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); + ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n")); + return (1); +bad: + LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n")); + return (0); +} + + +/* + * lcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if LCP is in the LS_OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int +lcp_nakci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *wo = &lcp_wantoptions[f->unit]; + u_char citype, cichar, *next; + u_short cishort; + u32_t cilong; + lcp_options no; /* options we've seen Naks for */ + lcp_options try; /* options to request next time */ + int looped_back = 0; + int cilen; + + BZERO(&no, sizeof(no)); + try = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIVOID(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + no.neg = 1; \ + code \ + } +#define NAKCICHAP(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#define NAKCICHAR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[1] == CILEN_CHAR && \ + p[0] == opt) { \ + len -= CILEN_CHAR; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#define NAKCISHORT(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } +#define NAKCILONG(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } +#define NAKCILQR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } + + /* + * We don't care if they want to send us smaller packets than + * we want. Therefore, accept any MRU less than what we asked for, + * but then ignore the new value when setting the MRU in the kernel. + * If they send us a bigger MRU than what we asked, accept it, up to + * the limit of the default MRU we'd get if we didn't negotiate. + */ + if (go->neg_mru && go->mru != PPP_DEFMRU) { + NAKCISHORT(CI_MRU, neg_mru, + if (cishort <= wo->mru || cishort < PPP_DEFMRU) { + try.mru = cishort; + } + ); + } + + /* + * Add any characters they want to our (receive-side) asyncmap. + */ + if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) { + NAKCILONG(CI_ASYNCMAP, neg_asyncmap, + try.asyncmap = go->asyncmap | cilong; + ); + } + + /* + * If they've nak'd our authentication-protocol, check whether + * they are proposing a different protocol, or a different + * hash algorithm for CHAP. + */ + if ((go->neg_chap || go->neg_upap) + && len >= CILEN_SHORT + && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { + cilen = p[1]; + len -= cilen; + no.neg_chap = go->neg_chap; + no.neg_upap = go->neg_upap; + INCPTR(2, p); + GETSHORT(cishort, p); + if (cishort == PPP_PAP && cilen == CILEN_SHORT) { + /* + * If we were asking for CHAP, they obviously don't want to do it. + * If we weren't asking for CHAP, then we were asking for PAP, + * in which case this Nak is bad. + */ + if (!go->neg_chap) { + goto bad; + } + try.neg_chap = 0; + + } else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + GETCHAR(cichar, p); + if (go->neg_chap) { + /* + * We were asking for CHAP/MD5; they must want a different + * algorithm. If they can't do MD5, we'll have to stop + * asking for CHAP. + */ + if (cichar != go->chap_mdtype) { + try.neg_chap = 0; + } + } else { + /* + * Stop asking for PAP if we were asking for it. + */ + try.neg_upap = 0; + } + + } else { + /* + * We don't recognize what they're suggesting. + * Stop asking for what we were asking for. + */ + if (go->neg_chap) { + try.neg_chap = 0; + } else { + try.neg_upap = 0; + } + p += cilen - CILEN_SHORT; + } + } + + /* + * If they can't cope with our link quality protocol, we'll have + * to stop asking for LQR. We haven't got any other protocol. + * If they Nak the reporting period, take their value XXX ? + */ + NAKCILQR(CI_QUALITY, neg_lqr, + if (cishort != PPP_LQR) { + try.neg_lqr = 0; + } else { + try.lqr_period = cilong; + } + ); + + /* + * Only implementing CBCP...not the rest of the callback options + */ + NAKCICHAR(CI_CALLBACK, neg_cbcp, + try.neg_cbcp = 0; + ); + + /* + * Check for a looped-back line. + */ + NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, + try.magicnumber = magic(); + looped_back = 1; + ); + + /* + * Peer shouldn't send Nak for protocol compression or + * address/control compression requests; they should send + * a Reject instead. If they send a Nak, treat it as a Reject. + */ + NAKCIVOID(CI_PCOMPRESSION, neg_pcompression, + try.neg_pcompression = 0; + ); + NAKCIVOID(CI_ACCOMPRESSION, neg_accompression, + try.neg_accompression = 0; + ); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If we see an option that we requested, or one we've already seen + * in this packet, then this packet is bad. + * If we wanted to respond by starting to negotiate on the requested + * option(s), we could, but we don't, because except for the + * authentication type and quality protocol, if we are not negotiating + * an option, it is because we were told not to. + * For the authentication type, the Nak from the peer means + * `let me authenticate myself with you' which is a bit pointless. + * For the quality protocol, the Nak means `ask me to send you quality + * reports', but if we didn't ask for them, we don't want them. + * An option we don't recognize represents the peer asking to + * negotiate some option we don't support, so ignore it. + */ + while (len > CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if (cilen < CILEN_VOID || (len -= cilen) < 0) { + goto bad; + } + next = p + cilen - 2; + + switch (citype) { + case CI_MRU: + if ((go->neg_mru && go->mru != PPP_DEFMRU) + || no.neg_mru || cilen != CILEN_SHORT) { + goto bad; + } + GETSHORT(cishort, p); + if (cishort < PPP_DEFMRU) { + try.mru = cishort; + } + break; + case CI_ASYNCMAP: + if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFFl) + || no.neg_asyncmap || cilen != CILEN_LONG) { + goto bad; + } + break; + case CI_AUTHTYPE: + if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap) { + goto bad; + } + break; + case CI_MAGICNUMBER: + if (go->neg_magicnumber || no.neg_magicnumber || + cilen != CILEN_LONG) { + goto bad; + } + break; + case CI_PCOMPRESSION: + if (go->neg_pcompression || no.neg_pcompression + || cilen != CILEN_VOID) { + goto bad; + } + break; + case CI_ACCOMPRESSION: + if (go->neg_accompression || no.neg_accompression + || cilen != CILEN_VOID) { + goto bad; + } + break; + case CI_QUALITY: + if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) { + goto bad; + } + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) { + goto bad; + } + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != LS_OPENED) { + if (looped_back) { + if (++try.numloops >= lcp_loopbackfail) { + LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n")); + lcp_close(f->unit, "Loopback detected"); + } + } else { + try.numloops = 0; + } + *go = try; + } + + return 1; + +bad: + LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n")); + return 0; +} + + +/* + * lcp_rejci - Peer has Rejected some of our CIs. + * This should not modify any state if the Reject is bad + * or if LCP is in the LS_OPENED state. + * + * Returns: + * 0 - Reject was bad. + * 1 - Reject was good. + */ +static int +lcp_rejci(fsm *f, u_char *p, int len) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + u_char cichar; + u_short cishort; + u32_t cilong; + lcp_options try; /* options to request next time */ + + try = *go; + + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIVOID(opt, neg) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \ + } +#define REJCISHORT(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \ + } +#define REJCICHAP(opt, neg, val, digest) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cishort != val || cichar != digest) { \ + goto bad; \ + } \ + try.neg = 0; \ + try.neg_upap = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \ + } +#define REJCILONG(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cilong != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \ + } +#define REJCILQR(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cishort != PPP_LQR || cilong != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \ + } +#define REJCICBCP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CBCP && \ + p[1] == CILEN_CBCP && \ + p[0] == opt) { \ + len -= CILEN_CBCP; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cichar != val) { \ + goto bad; \ + } \ + try.neg = 0; \ + LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \ + } + + REJCISHORT(CI_MRU, neg_mru, go->mru); + REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); + REJCICHAP(CI_AUTHTYPE, neg_chap, PPP_CHAP, go->chap_mdtype); + if (!go->neg_chap) { + REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); + } + REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); + REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); + REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); + REJCIVOID(CI_PCOMPRESSION, neg_pcompression); + REJCIVOID(CI_ACCOMPRESSION, neg_accompression); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) { + goto bad; + } + /* + * Now we can update state. + */ + if (f->state != LS_OPENED) { + *go = try; + } + return 1; + +bad: + LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n")); + return 0; +} + + +/* + * lcp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + */ +static int +lcp_reqci(fsm *f, + u_char *inp, /* Requested CIs */ + int *lenp, /* Length of requested CIs */ + int reject_if_disagree) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ho = &lcp_hisoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; + u_char *cip, *next; /* Pointer to current and next CIs */ + int cilen, citype, cichar; /* Parsed len, type, char value */ + u_short cishort; /* Parsed short value */ + u32_t cilong; /* Parse long value */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *rejp; /* Pointer to next char in reject frame */ + u_char *nakp; /* Pointer to next char in Nak frame */ + int l = *lenp; /* Length left */ +#if TRACELCP > 0 + char traceBuf[80]; + int traceNdx = 0; +#endif + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + nakp = nak_buffer; + rejp = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + citype = 0; + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_MRU: + if (!ao->neg_mru) { /* Allow option? */ + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n")); + orc = CONFREJ; /* Reject CI */ + break; + } else if (cilen != CILEN_SHORT) { /* Check CI length */ + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n")); + orc = CONFREJ; /* Reject CI */ + break; + } + GETSHORT(cishort, p); /* Parse MRU */ + + /* + * He must be able to receive at least our minimum. + * No need to check a maximum. If he sends a large number, + * we'll just ignore it. + */ + if (cishort < PPP_MINMRU) { + LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n")); + orc = CONFNAK; /* Nak CI */ + PUTCHAR(CI_MRU, nakp); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_MINMRU, nakp); /* Give him a hint */ + break; + } + ho->neg_mru = 1; /* Remember he sent MRU */ + ho->mru = cishort; /* And remember value */ +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MRU %d", cishort); + traceNdx = strlen(traceBuf); +#endif + break; + + case CI_ASYNCMAP: + if (!ao->neg_asyncmap) { + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_LONG) { + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n")); + orc = CONFREJ; + break; + } + GETLONG(cilong, p); + + /* + * Asyncmap must have set at least the bits + * which are set in lcp_allowoptions[unit].asyncmap. + */ + if ((ao->asyncmap & ~cilong) != 0) { + LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n", + cilong, ao->asyncmap)); + orc = CONFNAK; + PUTCHAR(CI_ASYNCMAP, nakp); + PUTCHAR(CILEN_LONG, nakp); + PUTLONG(ao->asyncmap | cilong, nakp); + break; + } + ho->neg_asyncmap = 1; + ho->asyncmap = cilong; +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ASYNCMAP=%lX", cilong); + traceNdx = strlen(traceBuf); +#endif + break; + + case CI_AUTHTYPE: + if (cilen < CILEN_SHORT) { + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n")); + orc = CONFREJ; + break; + } else if (!(ao->neg_upap || ao->neg_chap)) { + /* + * Reject the option if we're not willing to authenticate. + */ + LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n")); + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + /* + * Authtype must be UPAP or CHAP. + * + * Note: if both ao->neg_upap and ao->neg_chap are set, + * and the peer sends a Configure-Request with two + * authenticate-protocol requests, one for CHAP and one + * for UPAP, then we will reject the second request. + * Whether we end up doing CHAP or UPAP depends then on + * the ordering of the CIs in the peer's Configure-Request. + */ + + if (cishort == PPP_PAP) { + if (ho->neg_chap) { /* we've already accepted CHAP */ + LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_SHORT) { + LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n")); + orc = CONFREJ; + break; + } + if (!ao->neg_upap) { /* we don't want to do PAP */ + LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n")); + orc = CONFNAK; /* NAK it and suggest CHAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + break; + } + ho->neg_upap = 1; +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PAP (%X)", cishort); + traceNdx = strlen(traceBuf); +#endif + break; + } + if (cishort == PPP_CHAP) { + if (ho->neg_upap) { /* we've already accepted PAP */ + LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n")); + orc = CONFREJ; + break; + } else if (cilen != CILEN_CHAP) { + LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n")); + orc = CONFREJ; + break; + } + if (!ao->neg_chap) { /* we don't want to do CHAP */ + LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n")); + orc = CONFNAK; /* NAK it and suggest PAP */ + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_PAP, nakp); + break; + } + GETCHAR(cichar, p); /* get digest type*/ + if (cichar != CHAP_DIGEST_MD5 +#ifdef CHAPMS + && cichar != CHAP_MICROSOFT +#endif + ) { + LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar)); + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + break; + } +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, cichar); + traceNdx = strlen(traceBuf); +#endif + ho->chap_mdtype = cichar; /* save md type */ + ho->neg_chap = 1; + break; + } + + /* + * We don't recognize the protocol they're asking for. + * Nak it with something we're willing to do. + * (At this point we know ao->neg_upap || ao->neg_chap.) + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakp); + if (ao->neg_chap) { + LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort)); + PUTCHAR(CILEN_CHAP, nakp); + PUTSHORT(PPP_CHAP, nakp); + PUTCHAR(ao->chap_mdtype, nakp); + } else { + LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort)); + PUTCHAR(CILEN_SHORT, nakp); + PUTSHORT(PPP_PAP, nakp); + } + break; + + case CI_QUALITY: + GETSHORT(cishort, p); + GETLONG(cilong, p); +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " QUALITY (%x %x)", cishort, (unsigned int) cilong); + traceNdx = strlen(traceBuf); +#endif + + if (!ao->neg_lqr || + cilen != CILEN_LQR) { + orc = CONFREJ; + break; + } + + /* + * Check the protocol and the reporting period. + * XXX When should we Nak this, and what with? + */ + if (cishort != PPP_LQR) { + orc = CONFNAK; + PUTCHAR(CI_QUALITY, nakp); + PUTCHAR(CILEN_LQR, nakp); + PUTSHORT(PPP_LQR, nakp); + PUTLONG(ao->lqr_period, nakp); + break; + } + break; + + case CI_MAGICNUMBER: + if (!(ao->neg_magicnumber || go->neg_magicnumber) || + cilen != CILEN_LONG) { + orc = CONFREJ; + break; + } + GETLONG(cilong, p); +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " MAGICNUMBER (%lX)", cilong); + traceNdx = strlen(traceBuf); +#endif + + /* + * He must have a different magic number. + */ + if (go->neg_magicnumber && + cilong == go->magicnumber) { + cilong = magic(); /* Don't put magic() inside macro! */ + orc = CONFNAK; + PUTCHAR(CI_MAGICNUMBER, nakp); + PUTCHAR(CILEN_LONG, nakp); + PUTLONG(cilong, nakp); + break; + } + ho->neg_magicnumber = 1; + ho->magicnumber = cilong; + break; + + + case CI_PCOMPRESSION: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " PCOMPRESSION"); + traceNdx = strlen(traceBuf); +#endif + if (!ao->neg_pcompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_pcompression = 1; + break; + + case CI_ACCOMPRESSION: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " ACCOMPRESSION"); + traceNdx = strlen(traceBuf); +#endif + if (!ao->neg_accompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_accompression = 1; + break; + + case CI_MRRU: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_MRRU"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + case CI_SSNHF: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_SSNHF"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + case CI_EPDISC: +#if TRACELCP > 0 + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CI_EPDISC"); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + + default: +#if TRACELCP + snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " unknown %d", citype); + traceNdx = strlen(traceBuf); +#endif + orc = CONFREJ; + break; + } + + endswitch: +#if TRACELCP + if (traceNdx >= 80 - 32) { + LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf)); + traceNdx = 0; + } +#endif + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) { /* but prior CI wasnt? */ + continue; /* Don't send this one */ + } + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree /* Getting fed up with sending NAKs? */ + && citype != CI_MAGICNUMBER) { + orc = CONFREJ; /* Get tough if so */ + } else { + if (rc == CONFREJ) { /* Rejecting prior CI? */ + continue; /* Don't send this one */ + } + rc = CONFNAK; + } + } + if (orc == CONFREJ) { /* Reject this CI */ + rc = CONFREJ; + if (cip != rejp) { /* Need to move rejected CI? */ + BCOPY(cip, rejp, cilen); /* Move it */ + } + INCPTR(cilen, rejp); /* Update output pointer */ + } + } + + /* + * If we wanted to send additional NAKs (for unsent CIs), the + * code would go here. The extra NAKs would go at *nakp. + * At present there are no cases where we want to ask the + * peer to negotiate an option. + */ + + switch (rc) { + case CONFACK: + *lenp = (int)(next - inp); + break; + case CONFNAK: + /* + * Copy the Nak'd options from the nak_buffer to the caller's buffer. + */ + *lenp = (int)(nakp - nak_buffer); + BCOPY(nak_buffer, inp, *lenp); + break; + case CONFREJ: + *lenp = (int)(rejp - inp); + break; + } + +#if TRACELCP > 0 + if (traceNdx > 0) { + LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf)); + } +#endif + LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +/* + * lcp_up - LCP has come UP. + */ +static void +lcp_up(fsm *f) +{ + lcp_options *wo = &lcp_wantoptions[f->unit]; + lcp_options *ho = &lcp_hisoptions[f->unit]; + lcp_options *go = &lcp_gotoptions[f->unit]; + lcp_options *ao = &lcp_allowoptions[f->unit]; + + if (!go->neg_magicnumber) { + go->magicnumber = 0; + } + if (!ho->neg_magicnumber) { + ho->magicnumber = 0; + } + + /* + * Set our MTU to the smaller of the MTU we wanted and + * the MRU our peer wanted. If we negotiated an MRU, + * set our MRU to the larger of value we wanted and + * the value we got in the negotiation. + */ + ppp_send_config(f->unit, LWIP_MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)), + (ho->neg_asyncmap? ho->asyncmap: 0xffffffffl), + ho->neg_pcompression, ho->neg_accompression); + /* + * If the asyncmap hasn't been negotiated, we really should + * set the receive asyncmap to ffffffff, but we set it to 0 + * for backwards contemptibility. + */ + ppp_recv_config(f->unit, (go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU), + (go->neg_asyncmap? go->asyncmap: 0x00000000), + go->neg_pcompression, go->neg_accompression); + + if (ho->neg_mru) { + peer_mru[f->unit] = ho->mru; + } + + lcp_echo_lowerup(f->unit); /* Enable echo messages */ + + link_established(f->unit); +} + + +/* + * lcp_down - LCP has gone DOWN. + * + * Alert other protocols. + */ +static void +lcp_down(fsm *f) +{ + lcp_options *go = &lcp_gotoptions[f->unit]; + + lcp_echo_lowerdown(f->unit); + + link_down(f->unit); + + ppp_send_config(f->unit, PPP_MRU, 0xffffffffl, 0, 0); + ppp_recv_config(f->unit, PPP_MRU, + (go->neg_asyncmap? go->asyncmap: 0x00000000), + go->neg_pcompression, go->neg_accompression); + peer_mru[f->unit] = PPP_MRU; +} + + +/* + * lcp_starting - LCP needs the lower layer up. + */ +static void +lcp_starting(fsm *f) +{ + link_required(f->unit); +} + + +/* + * lcp_finished - LCP has finished with the lower layer. + */ +static void +lcp_finished(fsm *f) +{ + link_terminated(f->unit); +} + + +#if 0 +/* + * print_string - print a readable representation of a string using + * printer. + */ +static void +print_string( char *p, int len, void (*printer) (void *, char *, ...), void *arg) +{ + int c; + + printer(arg, "\""); + for (; len > 0; --len) { + c = *p++; + if (' ' <= c && c <= '~') { + if (c == '\\' || c == '"') { + printer(arg, "\\"); + } + printer(arg, "%c", c); + } else { + switch (c) { + case '\n': + printer(arg, "\\n"); + break; + case '\r': + printer(arg, "\\r"); + break; + case '\t': + printer(arg, "\\t"); + break; + default: + printer(arg, "\\%.3o", c); + } + } + } + printer(arg, "\""); +} + + +/* + * lcp_printpkt - print the contents of an LCP packet. + */ +static char *lcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej", "ProtRej", + "EchoReq", "EchoRep", "DiscReq" +}; + +static int +lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg) +{ + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + u32_t cilong; + + if (plen < HEADERLEN) { + return 0; + } + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) { + return 0; + } + + if (code >= 1 && code <= sizeof(lcp_codenames) / sizeof(char *)) { + printer(arg, " %s", lcp_codenames[code-1]); + } else { + printer(arg, " code=0x%x", code); + } + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_MRU: + if (olen == CILEN_SHORT) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "mru %d", cishort); + } + break; + case CI_ASYNCMAP: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "asyncmap 0x%lx", cilong); + } + break; + case CI_AUTHTYPE: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "auth "); + GETSHORT(cishort, p); + switch (cishort) { + case PPP_PAP: + printer(arg, "pap"); + break; + case PPP_CHAP: + printer(arg, "chap"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_QUALITY: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "quality "); + GETSHORT(cishort, p); + switch (cishort) { + case PPP_LQR: + printer(arg, "lqr"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_CALLBACK: + if (olen >= CILEN_CHAR) { + p += 2; + printer(arg, "callback "); + GETSHORT(cishort, p); + switch (cishort) { + case CBCP_OPT: + printer(arg, "CBCP"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_MAGICNUMBER: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "magic 0x%x", cilong); + } + break; + case CI_PCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "pcomp"); + } + break; + case CI_ACCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "accomp"); + } + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + print_string((char*)p, len, printer, arg); + p += len; + len = 0; + } + break; + + case ECHOREQ: + case ECHOREP: + case DISCREQ: + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + p += 4; + len -= 4; + } + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return (int)(p - pstart); +} +#endif + +/* + * Time to shut down the link because there is nothing out there. + */ +static void +LcpLinkFailure (fsm *f) +{ + if (f->state == LS_OPENED) { + LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending)); + LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n")); + lcp_close(f->unit, "Peer not responding"); + } +} + +/* + * Timer expired for the LCP echo requests from this process. + */ +static void +LcpEchoCheck (fsm *f) +{ + LcpSendEchoRequest (f); + + /* + * Start the timer for the next interval. + */ + LWIP_ASSERT("lcp_echo_timer_running == 0", lcp_echo_timer_running == 0); + + TIMEOUT (LcpEchoTimeout, f, lcp_echo_interval); + lcp_echo_timer_running = 1; +} + +/* + * LcpEchoTimeout - Timer expired on the LCP echo + */ +static void +LcpEchoTimeout (void *arg) +{ + if (lcp_echo_timer_running != 0) { + lcp_echo_timer_running = 0; + LcpEchoCheck ((fsm *) arg); + } +} + +/* + * LcpEchoReply - LCP has received a reply to the echo + */ +static void +lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len) +{ + u32_t magic; + + LWIP_UNUSED_ARG(id); + + /* Check the magic number - don't count replies from ourselves. */ + if (len < 4) { + LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len)); + return; + } + GETLONG(magic, inp); + if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) { + LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n")); + return; + } + + /* Reset the number of outstanding echo frames */ + lcp_echos_pending = 0; +} + +/* + * LcpSendEchoRequest - Send an echo request frame to the peer + */ +static void +LcpSendEchoRequest (fsm *f) +{ + u32_t lcp_magic; + u_char pkt[4], *pktp; + + /* + * Detect the failure of the peer at this point. + */ + if (lcp_echo_fails != 0) { + if (lcp_echos_pending++ >= lcp_echo_fails) { + LcpLinkFailure(f); + lcp_echos_pending = 0; + } + } + + /* + * Make and send the echo request frame. + */ + if (f->state == LS_OPENED) { + lcp_magic = lcp_gotoptions[f->unit].magicnumber; + pktp = pkt; + PUTLONG(lcp_magic, pktp); + fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt)); + } +} + +/* + * lcp_echo_lowerup - Start the timer for the LCP frame + */ + +static void +lcp_echo_lowerup (int unit) +{ + fsm *f = &lcp_fsm[unit]; + + /* Clear the parameters for generating echo frames */ + lcp_echos_pending = 0; + lcp_echo_number = 0; + lcp_echo_timer_running = 0; + + /* If a timeout interval is specified then start the timer */ + if (lcp_echo_interval != 0) { + LcpEchoCheck (f); + } +} + +/* + * lcp_echo_lowerdown - Stop the timer for the LCP frame + */ + +static void +lcp_echo_lowerdown (int unit) +{ + fsm *f = &lcp_fsm[unit]; + + if (lcp_echo_timer_running != 0) { + UNTIMEOUT (LcpEchoTimeout, f); + lcp_echo_timer_running = 0; + } +} + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.h new file mode 100644 index 0000000..1a5e5a4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/lcp.h @@ -0,0 +1,167 @@ +/***************************************************************************** +* lcp.h - Network Link Control Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * lcp.h - Link Control Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: lcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $ + */ + +#ifndef LCP_H +#define LCP_H + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ +/* + * Options. + */ +#define CI_MRU 1 /* Maximum Receive Unit */ +#define CI_ASYNCMAP 2 /* Async Control Character Map */ +#define CI_AUTHTYPE 3 /* Authentication Type */ +#define CI_QUALITY 4 /* Quality Protocol */ +#define CI_MAGICNUMBER 5 /* Magic Number */ +#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ +#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ +#define CI_CALLBACK 13 /* callback */ +#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ +#define CI_SSNHF 18 /* short sequence numbers for multilink */ +#define CI_EPDISC 19 /* endpoint discriminator */ + +/* + * LCP-specific packet types. + */ +#define PROTREJ 8 /* Protocol Reject */ +#define ECHOREQ 9 /* Echo Request */ +#define ECHOREP 10 /* Echo Reply */ +#define DISCREQ 11 /* Discard Request */ +#define CBCP_OPT 6 /* Use callback control protocol */ + + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * The state of options is described by an lcp_options structure. + */ +typedef struct lcp_options { + u_int passive : 1; /* Don't die if we don't get a response */ + u_int silent : 1; /* Wait for the other end to start first */ + u_int restart : 1; /* Restart vs. exit after close */ + u_int neg_mru : 1; /* Negotiate the MRU? */ + u_int neg_asyncmap : 1; /* Negotiate the async map? */ + u_int neg_upap : 1; /* Ask for UPAP authentication? */ + u_int neg_chap : 1; /* Ask for CHAP authentication? */ + u_int neg_magicnumber : 1; /* Ask for magic number? */ + u_int neg_pcompression : 1; /* HDLC Protocol Field Compression? */ + u_int neg_accompression : 1; /* HDLC Address/Control Field Compression? */ + u_int neg_lqr : 1; /* Negotiate use of Link Quality Reports */ + u_int neg_cbcp : 1; /* Negotiate use of CBCP */ +#ifdef PPP_MULTILINK + u_int neg_mrru : 1; /* Negotiate multilink MRRU */ + u_int neg_ssnhf : 1; /* Negotiate short sequence numbers */ + u_int neg_endpoint : 1; /* Negotiate endpoint discriminator */ +#endif + u_short mru; /* Value of MRU */ +#ifdef PPP_MULTILINK + u_short mrru; /* Value of MRRU, and multilink enable */ +#endif + u_char chap_mdtype; /* which MD type (hashing algorithm) */ + u32_t asyncmap; /* Value of async map */ + u32_t magicnumber; + int numloops; /* Number of loops during magic number neg. */ + u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#ifdef PPP_MULTILINK + struct epdisc endpoint; /* endpoint discriminator */ +#endif +} lcp_options; + +/* + * Values for phase from BSD pppd.h based on RFC 1661. + */ +typedef enum { + PHASE_DEAD = 0, + PHASE_INITIALIZE, + PHASE_ESTABLISH, + PHASE_AUTHENTICATE, + PHASE_CALLBACK, + PHASE_NETWORK, + PHASE_TERMINATE +} LinkPhase; + + +/***************************** +*** PUBLIC DATA STRUCTURES *** +*****************************/ + +extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */ +extern lcp_options lcp_wantoptions[]; +extern lcp_options lcp_gotoptions[]; +extern lcp_options lcp_allowoptions[]; +extern lcp_options lcp_hisoptions[]; +extern ext_accm xmit_accm[]; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +void lcp_init (int); +void lcp_open (int); +void lcp_close (int, char *); +void lcp_lowerup (int); +void lcp_lowerdown(int); +void lcp_sprotrej (int, u_char *, int); /* send protocol reject */ + +extern struct protent lcp_protent; + +/* Default number of times we receive our magic number from the peer + before deciding the link is looped-back. */ +#define DEFLOOPBACKFAIL 10 + +#endif /* LCP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.c new file mode 100644 index 0000000..d3922bb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.c @@ -0,0 +1,82 @@ +/***************************************************************************** +* magic.c - Network Random Number Generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original based on BSD magic.c. +*****************************************************************************/ +/* + * magic.c - PPP Magic Number routines. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT + +#include "ppp.h" +#include "randm.h" +#include "magic.h" + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * magicInit - Initialize the magic number generator. + * + * Since we use another random number generator that has its own + * initialization, we do nothing here. + */ +void magicInit() +{ + return; +} + +/* + * magic - Returns the next magic number. + */ +u32_t magic() +{ + return avRandom(); +} + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.h new file mode 100644 index 0000000..bc51749 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/magic.h @@ -0,0 +1,67 @@ +/***************************************************************************** +* magic.h - Network Random Number Generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * magic.h - PPP Magic Number definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: magic.h,v 1.2 2007/12/02 22:35:55 fbernon Exp $ + */ + +#ifndef MAGIC_H +#define MAGIC_H + +/***************************************************************************** +************************** PUBLIC FUNCTIONS ********************************** +*****************************************************************************/ + +/* Initialize the magic number generator */ +void magicInit(void); + +/* Returns the next magic number */ +u32_t magic(void); + +#endif /* MAGIC_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.c new file mode 100644 index 0000000..7a60d78 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.c @@ -0,0 +1,320 @@ +/* + *********************************************************************** + ** md5.c -- the source code for MD5 routines ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if CHAP_SUPPORT || MD5_SUPPORT + +#include "ppp.h" +#include "pppdebug.h" + +#include "md5.h" + +#include + +/* + *********************************************************************** + ** Message-digest routines: ** + ** To form the message digest for a message M ** + ** (1) Initialize a context buffer mdContext using MD5Init ** + ** (2) Call MD5Update on mdContext and M ** + ** (3) Call MD5Final on mdContext ** + ** The message digest is now in mdContext->digest[0...15] ** + *********************************************************************** + */ + +/* forward declaration */ +static void Transform (u32_t *buf, u32_t *in); + +static unsigned char PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + {(a) += F ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + {(a) += G ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + {(a) += H ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + {(a) += I ((b), (c), (d)) + (x) + (u32_t)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +#ifdef __STDC__ +#define UL(x) x##UL +#else +#ifdef WIN32 +#define UL(x) x##UL +#else +#define UL(x) x +#endif +#endif + +/* The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. + */ +void +MD5Init (MD5_CTX *mdContext) +{ + mdContext->i[0] = mdContext->i[1] = (u32_t)0; + + /* Load magic initialization constants. */ + mdContext->buf[0] = (u32_t)0x67452301UL; + mdContext->buf[1] = (u32_t)0xefcdab89UL; + mdContext->buf[2] = (u32_t)0x98badcfeUL; + mdContext->buf[3] = (u32_t)0x10325476UL; +} + +/* The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. + */ +void +MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) +{ + u32_t in[16]; + int mdi; + unsigned int i, ii; + +#if 0 + ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf); + ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf); +#endif + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* update number of bits */ + if ((mdContext->i[0] + ((u32_t)inLen << 3)) < mdContext->i[0]) { + mdContext->i[1]++; + } + mdContext->i[0] += ((u32_t)inLen << 3); + mdContext->i[1] += ((u32_t)inLen >> 29); + + while (inLen--) { + /* add new character to buffer, increment mdi */ + mdContext->in[mdi++] = *inBuf++; + + /* transform if necessary */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) { + in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | + (((u32_t)mdContext->in[ii+2]) << 16) | + (((u32_t)mdContext->in[ii+1]) << 8) | + ((u32_t)mdContext->in[ii]); + } + Transform (mdContext->buf, in); + mdi = 0; + } + } +} + +/* The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. + */ +void +MD5Final (unsigned char hash[], MD5_CTX *mdContext) +{ + u32_t in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + /* save number of bits */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* compute number of bytes mod 64 */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* pad out to 56 mod 64 */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + MD5Update (mdContext, PADDING, padLen); + + /* append length in bits and transform */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) { + in[i] = (((u32_t)mdContext->in[ii+3]) << 24) | + (((u32_t)mdContext->in[ii+2]) << 16) | + (((u32_t)mdContext->in[ii+1]) << 8) | + ((u32_t)mdContext->in[ii]); + } + Transform (mdContext->buf, in); + + /* store buffer in digest */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii+1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii+2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii+3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } + SMEMCPY(hash, mdContext->digest, 16); +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void +Transform (u32_t *buf, u32_t *in) +{ + u32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */ + FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */ + FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */ + FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */ + FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */ + FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */ + FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */ + FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */ + FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */ + FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */ + FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */ + FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */ + FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */ + FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */ + FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */ + FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */ + + /* Round 2 */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */ + GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */ + GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */ + GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */ + GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */ + GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */ + GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */ + GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */ + GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */ + GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */ + GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */ + GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */ + GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */ + GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */ + GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */ + GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */ + + /* Round 3 */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */ + HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */ + HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */ + HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */ + HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */ + HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */ + HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */ + HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */ + HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */ + HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */ + HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */ + HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */ + HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */ + HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */ + HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */ + HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */ + + /* Round 4 */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */ + II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */ + II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */ + II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */ + II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */ + II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */ + II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */ + II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */ + II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */ + II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */ + II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */ + II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */ + II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */ + II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */ + II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */ + II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif /* CHAP_SUPPORT || MD5_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.h new file mode 100644 index 0000000..e129533 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/md5.h @@ -0,0 +1,55 @@ +/* + *********************************************************************** + ** md5.h -- header file for implementation of MD5 ** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** + ** Revised (for MD5): RLR 4/27/91 ** + ** -- G modified to have y&~z instead of y&z ** + ** -- FF, GG, HH modified to add in last register done ** + ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** + ** -- distinct additive constant for each step ** + ** -- round 4 added, working mod 7 ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#ifndef MD5_H +#define MD5_H + +/* Data structure for MD5 (Message-Digest) computation */ +typedef struct { + u32_t i[2]; /* number of _bits_ handled mod 2^64 */ + u32_t buf[4]; /* scratch buffer */ + unsigned char in[64]; /* input buffer */ + unsigned char digest[16]; /* actual digest after MD5Final call */ +} MD5_CTX; + +void MD5Init ( MD5_CTX *mdContext); +void MD5Update( MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen); +void MD5Final ( unsigned char hash[], MD5_CTX *mdContext); + +#endif /* MD5_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.c new file mode 100644 index 0000000..e8c45df --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.c @@ -0,0 +1,622 @@ +/***************************************************************************** +* pap.c - Network Password Authentication Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-12 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ +/* + * upap.c - User/Password Authentication Protocol. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "auth.h" +#include "pap.h" + +#include + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +/* + * Protocol entry points. + */ +static void upap_init (int); +static void upap_lowerup (int); +static void upap_lowerdown (int); +static void upap_input (int, u_char *, int); +static void upap_protrej (int); + +static void upap_timeout (void *); +static void upap_reqtimeout(void *); +static void upap_rauthreq (upap_state *, u_char *, int, int); +static void upap_rauthack (upap_state *, u_char *, int, int); +static void upap_rauthnak (upap_state *, u_char *, int, int); +static void upap_sauthreq (upap_state *); +static void upap_sresp (upap_state *, u_char, u_char, char *, int); + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +struct protent pap_protent = { + PPP_PAP, + upap_init, + upap_input, + upap_protrej, + upap_lowerup, + upap_lowerdown, + NULL, + NULL, +#if 0 + upap_printpkt, + NULL, +#endif + 1, + "PAP", +#if 0 + NULL, + NULL, + NULL +#endif +}; + +upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ + + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Set the default login name and password for the pap sessions + */ +void +upap_setloginpasswd(int unit, const char *luser, const char *lpassword) +{ + upap_state *u = &upap[unit]; + + /* Save the username and password we're given */ + u->us_user = luser; + u->us_userlen = strlen(luser); + u->us_passwd = lpassword; + u->us_passwdlen = strlen(lpassword); +} + + +/* + * upap_authwithpeer - Authenticate us with our peer (start client). + * + * Set new state and send authenticate's. + */ +void +upap_authwithpeer(int unit, char *user, char *password) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n", + unit, user, password, u->us_clientstate)); + + upap_setloginpasswd(unit, user, password); + + u->us_transmits = 0; + + /* Lower layer up yet? */ + if (u->us_clientstate == UPAPCS_INITIAL || + u->us_clientstate == UPAPCS_PENDING) { + u->us_clientstate = UPAPCS_PENDING; + return; + } + + upap_sauthreq(u); /* Start protocol */ +} + + +/* + * upap_authpeer - Authenticate our peer (start server). + * + * Set new state. + */ +void +upap_authpeer(int unit) +{ + upap_state *u = &upap[unit]; + + /* Lower layer up yet? */ + if (u->us_serverstate == UPAPSS_INITIAL || + u->us_serverstate == UPAPSS_PENDING) { + u->us_serverstate = UPAPSS_PENDING; + return; + } + + u->us_serverstate = UPAPSS_LISTEN; + if (u->us_reqtimeout > 0) { + TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); + } +} + + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ +/* + * upap_init - Initialize a UPAP unit. + */ +static void +upap_init(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit)); + u->us_unit = unit; + u->us_user = NULL; + u->us_userlen = 0; + u->us_passwd = NULL; + u->us_passwdlen = 0; + u->us_clientstate = UPAPCS_INITIAL; + u->us_serverstate = UPAPSS_INITIAL; + u->us_id = 0; + u->us_timeouttime = UPAP_DEFTIMEOUT; + u->us_maxtransmits = 10; + u->us_reqtimeout = UPAP_DEFREQTIME; +} + +/* + * upap_timeout - Retransmission timer for sending auth-reqs expired. + */ +static void +upap_timeout(void *arg) +{ + upap_state *u = (upap_state *) arg; + + UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n", + u->us_unit, u->us_timeouttime, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { + return; + } + + if (u->us_transmits >= u->us_maxtransmits) { + /* give up in disgust */ + UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n")); + u->us_clientstate = UPAPCS_BADAUTH; + auth_withpeer_fail(u->us_unit, PPP_PAP); + return; + } + + upap_sauthreq(u); /* Send Authenticate-Request */ +} + + +/* + * upap_reqtimeout - Give up waiting for the peer to send an auth-req. + */ +static void +upap_reqtimeout(void *arg) +{ + upap_state *u = (upap_state *) arg; + + if (u->us_serverstate != UPAPSS_LISTEN) { + return; /* huh?? */ + } + + auth_peer_fail(u->us_unit, PPP_PAP); + u->us_serverstate = UPAPSS_BADAUTH; +} + + +/* + * upap_lowerup - The lower layer is up. + * + * Start authenticating if pending. + */ +static void +upap_lowerup(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate)); + + if (u->us_clientstate == UPAPCS_INITIAL) { + u->us_clientstate = UPAPCS_CLOSED; + } else if (u->us_clientstate == UPAPCS_PENDING) { + upap_sauthreq(u); /* send an auth-request */ + } + + if (u->us_serverstate == UPAPSS_INITIAL) { + u->us_serverstate = UPAPSS_CLOSED; + } else if (u->us_serverstate == UPAPSS_PENDING) { + u->us_serverstate = UPAPSS_LISTEN; + if (u->us_reqtimeout > 0) { + TIMEOUT(upap_reqtimeout, u, u->us_reqtimeout); + } + } +} + + +/* + * upap_lowerdown - The lower layer is down. + * + * Cancel all timeouts. + */ +static void +upap_lowerdown(int unit) +{ + upap_state *u = &upap[unit]; + + UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate)); + + if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */ + UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ + } + if (u->us_serverstate == UPAPSS_LISTEN && u->us_reqtimeout > 0) { + UNTIMEOUT(upap_reqtimeout, u); + } + + u->us_clientstate = UPAPCS_INITIAL; + u->us_serverstate = UPAPSS_INITIAL; +} + + +/* + * upap_protrej - Peer doesn't speak this protocol. + * + * This shouldn't happen. In any case, pretend lower layer went down. + */ +static void +upap_protrej(int unit) +{ + upap_state *u = &upap[unit]; + + if (u->us_clientstate == UPAPCS_AUTHREQ) { + UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n")); + auth_withpeer_fail(unit, PPP_PAP); + } + if (u->us_serverstate == UPAPSS_LISTEN) { + UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n")); + auth_peer_fail(unit, PPP_PAP); + } + upap_lowerdown(unit); +} + + +/* + * upap_input - Input UPAP packet. + */ +static void +upap_input(int unit, u_char *inpacket, int l) +{ + upap_state *u = &upap[unit]; + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (l < UPAP_HEADERLEN) { + UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < UPAP_HEADERLEN) { + UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n")); + return; + } + if (len > l) { + UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n")); + return; + } + len -= UPAP_HEADERLEN; + + /* + * Action depends on code. + */ + switch (code) { + case UPAP_AUTHREQ: + upap_rauthreq(u, inp, id, len); + break; + + case UPAP_AUTHACK: + upap_rauthack(u, inp, id, len); + break; + + case UPAP_AUTHNAK: + upap_rauthnak(u, inp, id, len); + break; + + default: /* XXX Need code reject */ + break; + } +} + + +/* + * upap_rauth - Receive Authenticate. + */ +static void +upap_rauthreq(upap_state *u, u_char *inp, int id, int len) +{ + u_char ruserlen, rpasswdlen; + char *ruser, *rpasswd; + int retcode; + char *msg; + int msglen; + + UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id)); + + if (u->us_serverstate < UPAPSS_LISTEN) { + return; + } + + /* + * If we receive a duplicate authenticate-request, we are + * supposed to return the same status as for the first request. + */ + if (u->us_serverstate == UPAPSS_OPEN) { + upap_sresp(u, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ + return; + } + if (u->us_serverstate == UPAPSS_BADAUTH) { + upap_sresp(u, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ + return; + } + + /* + * Parse user/passwd. + */ + if (len < sizeof (u_char)) { + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n")); + return; + } + GETCHAR(ruserlen, inp); + len -= sizeof (u_char) + ruserlen + sizeof (u_char); + if (len < 0) { + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n")); + return; + } + ruser = (char *) inp; + INCPTR(ruserlen, inp); + GETCHAR(rpasswdlen, inp); + if (len < rpasswdlen) { + UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n")); + return; + } + rpasswd = (char *) inp; + + /* + * Check the username and password given. + */ + retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen); + BZERO(rpasswd, rpasswdlen); + + upap_sresp(u, retcode, id, msg, msglen); + + if (retcode == UPAP_AUTHACK) { + u->us_serverstate = UPAPSS_OPEN; + auth_peer_success(u->us_unit, PPP_PAP, ruser, ruserlen); + } else { + u->us_serverstate = UPAPSS_BADAUTH; + auth_peer_fail(u->us_unit, PPP_PAP); + } + + if (u->us_reqtimeout > 0) { + UNTIMEOUT(upap_reqtimeout, u); + } +} + + +/* + * upap_rauthack - Receive Authenticate-Ack. + */ +static void +upap_rauthack(upap_state *u, u_char *inp, int id, int len) +{ + u_char msglen; + char *msg; + + LWIP_UNUSED_ARG(id); + + UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ + return; + } + + /* + * Parse message. + */ + if (len < sizeof (u_char)) { + UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n")); + return; + } + GETCHAR(msglen, inp); + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + + UNTIMEOUT(upap_timeout, u); /* Cancel timeout */ + u->us_clientstate = UPAPCS_OPEN; + + auth_withpeer_success(u->us_unit, PPP_PAP); +} + + +/* + * upap_rauthnak - Receive Authenticate-Nakk. + */ +static void +upap_rauthnak(upap_state *u, u_char *inp, int id, int len) +{ + u_char msglen; + char *msg; + + LWIP_UNUSED_ARG(id); + + UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate)); + + if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */ + return; + } + + /* + * Parse message. + */ + if (len < sizeof (u_char)) { + UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n")); + } else { + GETCHAR(msglen, inp); + if(msglen > 0) { + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + } + } + + u->us_clientstate = UPAPCS_BADAUTH; + + UPAPDEBUG((LOG_ERR, "PAP authentication failed\n")); + auth_withpeer_fail(u->us_unit, PPP_PAP); +} + + +/* + * upap_sauthreq - Send an Authenticate-Request. + */ +static void +upap_sauthreq(upap_state *u) +{ + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + + u->us_userlen + u->us_passwdlen; + outp = outpacket_buf[u->us_unit]; + + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(UPAP_AUTHREQ, outp); + PUTCHAR(++u->us_id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(u->us_userlen, outp); + BCOPY(u->us_user, outp, u->us_userlen); + INCPTR(u->us_userlen, outp); + PUTCHAR(u->us_passwdlen, outp); + BCOPY(u->us_passwd, outp, u->us_passwdlen); + + pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); + + UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id)); + + TIMEOUT(upap_timeout, u, u->us_timeouttime); + ++u->us_transmits; + u->us_clientstate = UPAPCS_AUTHREQ; +} + + +/* + * upap_sresp - Send a response (ack or nak). + */ +static void +upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen) +{ + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; + outp = outpacket_buf[u->us_unit]; + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(msglen, outp); + BCOPY(msg, outp, msglen); + pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN); + + UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate)); +} + +#if 0 +/* + * upap_printpkt - print the contents of a PAP packet. + */ +static int upap_printpkt( + u_char *p, + int plen, + void (*printer) (void *, char *, ...), + void *arg +) +{ + LWIP_UNUSED_ARG(p); + LWIP_UNUSED_ARG(plen); + LWIP_UNUSED_ARG(printer); + LWIP_UNUSED_ARG(arg); + return 0; +} +#endif /* 0 */ + +#endif /* PAP_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.h new file mode 100644 index 0000000..0a09fc8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pap.h @@ -0,0 +1,131 @@ +/***************************************************************************** +* pap.h - PPP Password Authentication Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-12-04 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ +/* + * upap.h - User/Password Authentication Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef PAP_H +#define PAP_H + +#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ +/* + * Packet header = Code, id, length. + */ +#define UPAP_HEADERLEN (sizeof (u_char) + sizeof (u_char) + sizeof (u_short)) + + +/* + * UPAP codes. + */ +#define UPAP_AUTHREQ 1 /* Authenticate-Request */ +#define UPAP_AUTHACK 2 /* Authenticate-Ack */ +#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ + +/* + * Client states. + */ +#define UPAPCS_INITIAL 0 /* Connection down */ +#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ +#define UPAPCS_OPEN 4 /* We've received an Ack */ +#define UPAPCS_BADAUTH 5 /* We've received a Nak */ + +/* + * Server states. + */ +#define UPAPSS_INITIAL 0 /* Connection down */ +#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ +#define UPAPSS_OPEN 4 /* We've sent an Ack */ +#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ + + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * Each interface is described by upap structure. + */ +typedef struct upap_state { + int us_unit; /* Interface unit number */ + const char *us_user; /* User */ + int us_userlen; /* User length */ + const char *us_passwd; /* Password */ + int us_passwdlen; /* Password length */ + int us_clientstate; /* Client state */ + int us_serverstate; /* Server state */ + u_char us_id; /* Current id */ + int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */ + int us_transmits; /* Number of auth-reqs sent */ + int us_maxtransmits; /* Maximum number of auth-reqs to send */ + int us_reqtimeout; /* Time to wait for auth-req from peer */ +} upap_state; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +extern upap_state upap[]; + +void upap_setloginpasswd(int unit, const char *luser, const char *lpassword); +void upap_authwithpeer (int, char *, char *); +void upap_authpeer (int); + +extern struct protent pap_protent; + +#endif /* PAP_SUPPORT */ + +#endif /* PAP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.c new file mode 100644 index 0000000..13fa5ed --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.c @@ -0,0 +1,1989 @@ +/***************************************************************************** +* ppp.c - Network Point to Point Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + +/* + * ppp_defs.h - PPP definitions. + * + * if_pppvar.h - private structures and declarations for PPP. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip.h" /* for ip_input() */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "randm.h" +#include "fsm.h" +#if PAP_SUPPORT +#include "pap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "chap.h" +#endif /* CHAP_SUPPORT */ +#include "ipcp.h" +#include "lcp.h" +#include "magic.h" +#include "auth.h" +#if VJ_SUPPORT +#include "vj.h" +#endif /* VJ_SUPPORT */ +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +/* + * The basic PPP frame. + */ +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} PPPDevStates; + +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & pppACCMMask[c & 0x07]) + +/************************/ +/*** LOCAL DATA TYPES ***/ +/************************/ +/* + * PPP interface control block. + */ +typedef struct PPPControl_s { + char openFlag; /* True when in use. */ +#if PPPOE_SUPPORT + struct netif *ethif; + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ + int if_up; /* True when the interface is up. */ + int errCode; /* Code indicating why interface is down. */ +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ + int kill_link; /* Shut the link down. */ + int sig_hup; /* Carrier lost. */ + struct pbuf *inHead, *inTail; /* The input packet. */ + PPPDevStates inState; /* The input process state. */ + char inEscaped; /* Escape next character. */ + u16_t inProtocol; /* The input protocol code. */ + u16_t inFCS; /* Input Frame Check Sequence value. */ +#endif /* PPPOS_SUPPORT */ + int mtu; /* Peer's mru */ + int pcomp; /* Does peer accept protocol compression? */ + int accomp; /* Does peer accept addr/ctl compression? */ + u_long lastXMit; /* Time of last transmission. */ + ext_accm inACCM; /* Async-Ctl-Char-Map for input. */ + ext_accm outACCM; /* Async-Ctl-Char-Map for output. */ +#if PPPOS_SUPPORT && VJ_SUPPORT + int vjEnabled; /* Flag indicating VJ compression enabled. */ + struct vjcompress vjComp; /* Van Jacobson compression header. */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + struct netif netif; + + struct ppp_addrs addrs; + + void (*linkStatusCB)(void *ctx, int errCode, void *arg); + void *linkStatusCtx; + +} PPPControl; + + +/* + * Ioctl definitions. + */ + +struct npioctl { + int protocol; /* PPP procotol, e.g. PPP_IP */ + enum NPmode mode; +}; + + + +/***********************************/ +/*** LOCAL FUNCTION DECLARATIONS ***/ +/***********************************/ +#if PPPOS_SUPPORT +static void pppMain(void *pd); +static void pppDrop(PPPControl *pc); +static void pppInProc(int pd, u_char *s, int l); +#endif /* PPPOS_SUPPORT */ + + +/******************************/ +/*** PUBLIC DATA STRUCTURES ***/ +/******************************/ +u_long subnetMask; + +static PPPControl pppControl[NUM_PPP]; /* The PPP interface control blocks. */ + +/* + * PPP Data Link Layer "protocol" table. + * One entry per supported protocol. + * The last entry must be NULL. + */ +struct protent *ppp_protocols[] = { + &lcp_protent, +#if PAP_SUPPORT + &pap_protent, +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + &chap_protent, +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT + &cbcp_protent, +#endif /* CBCP_SUPPORT */ + &ipcp_protent, +#if CCP_SUPPORT + &ccp_protent, +#endif /* CCP_SUPPORT */ + NULL +}; + + +/* + * Buffers for outgoing packets. This must be accessed only from the appropriate + * PPP task so that it doesn't need to be protected to avoid collisions. + */ +u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; + + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ + +#if PPPOS_SUPPORT +/* + * FCS lookup table as calculated by genfcstab. + */ +static const u_short fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/* PPP's Asynchronous-Control-Character-Map. The mask array is used + * to select the specific bit for a character. */ +static u_char pppACCMMask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 +}; + + +void +pppMainWakeup(int pd) +{ + PPPDEBUG((LOG_DEBUG, "pppMainWakeup: unit %d\n", pd)); + sio_read_abort(pppControl[pd].fd); +} +#endif /* PPPOS_SUPPORT */ + +void +pppLinkTerminated(int pd) +{ + PPPDEBUG((LOG_DEBUG, "pppLinkTerminated: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if(pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + pppMainWakeup(pd); +#endif /* PPPOS_SUPPORT */ + } +} + +void +pppLinkDown(int pd) +{ + PPPDEBUG((LOG_DEBUG, "pppLinkDown: unit %d\n", pd)); + +#if PPPOE_SUPPORT + if(pppControl[pd].ethif) { + pppoe_disconnect(pppControl[pd].pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + pppMainWakeup(pd); +#endif /* PPPOS_SUPPORT */ + } +} + +/* these callbacks are necessary because lcp_* functions + must be called in the same context as pppInput(), + namely the tcpip_thread(), essentially because + they manipulate timeouts which are thread-private +*/ + +static void +pppStartCB(void *arg) +{ + int pd = (int)arg; + + PPPDEBUG((LOG_DEBUG, "pppStartCB: unit %d\n", pd)); + lcp_lowerup(pd); + lcp_open(pd); /* Start protocol */ +} + +static void +pppStopCB(void *arg) +{ + int pd = (int)arg; + + PPPDEBUG((LOG_DEBUG, "pppStopCB: unit %d\n", pd)); + lcp_close(pd, "User request"); +} + +static void +pppHupCB(void *arg) +{ + int pd = (int)arg; + + PPPDEBUG((LOG_DEBUG, "pppHupCB: unit %d\n", pd)); + lcp_lowerdown(pd); + link_terminated(pd); +} + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* Initialize the PPP subsystem. */ + +struct ppp_settings ppp_settings; + +void +pppInit(void) +{ + struct protent *protp; + int i, j; + + memset(&ppp_settings, 0, sizeof(ppp_settings)); + ppp_settings.usepeerdns = 1; + pppSetAuth(PPPAUTHTYPE_NONE, NULL, NULL); + + magicInit(); + + subnetMask = htonl(0xffffff00); + + for (i = 0; i < NUM_PPP; i++) { + pppControl[i].openFlag = 0; + + /* + * Initialize to the standard option set. + */ + for (j = 0; (protp = ppp_protocols[j]) != NULL; ++j) { + (*protp->init)(i); + } + } + +#if PPPOE_SUPPORT + pppoe_init(); +#endif /* PPPOE_SUPPORT */ +} + +void +pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd) +{ + switch(authType) { + case PPPAUTHTYPE_NONE: + default: +#ifdef LWIP_PPP_STRICT_PAP_REJECT + ppp_settings.refuse_pap = 1; +#else /* LWIP_PPP_STRICT_PAP_REJECT */ + /* some providers request pap and accept an empty login/pw */ + ppp_settings.refuse_pap = 0; +#endif /* LWIP_PPP_STRICT_PAP_REJECT */ + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_ANY: + /* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 0; + break; + + case PPPAUTHTYPE_PAP: + ppp_settings.refuse_pap = 0; + ppp_settings.refuse_chap = 1; + break; + + case PPPAUTHTYPE_CHAP: + ppp_settings.refuse_pap = 1; + ppp_settings.refuse_chap = 0; + break; + } + + if(user) { + strncpy(ppp_settings.user, user, sizeof(ppp_settings.user)-1); + ppp_settings.user[sizeof(ppp_settings.user)-1] = '\0'; + } else { + ppp_settings.user[0] = '\0'; + } + + if(passwd) { + strncpy(ppp_settings.passwd, passwd, sizeof(ppp_settings.passwd)-1); + ppp_settings.passwd[sizeof(ppp_settings.passwd)-1] = '\0'; + } else { + ppp_settings.passwd[0] = '\0'; + } +} + +#if PPPOS_SUPPORT +/* Open a new PPP connection using the given I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. If this port + * connects to a modem, the modem connection must be + * established before calling this. + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. */ +int +pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + /* Find a free PPP session descriptor. Critical region? */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pppControl[pd].openFlag = !0; + } + + /* Launch a deamon thread. */ + if (pd >= 0) { + pppControl[pd].openFlag = 1; + + lcp_init(pd); + pc = &pppControl[pd]; + pc->fd = fd; +#if PPPOE_SUPPORT + pc->ethif= NULL; +#endif /* PPPOE_SUPPORT */ + pc->kill_link = 0; + pc->sig_hup = 0; + pc->if_up = 0; + pc->errCode = 0; + pc->inState = PDIDLE; + pc->inHead = NULL; + pc->inTail = NULL; + pc->inEscaped = 0; + pc->lastXMit = 0; + +#if VJ_SUPPORT + pc->vjEnabled = 0; + vj_compress_init(&pc->vjComp); +#endif /* VJ_SUPPORT */ + + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + memset(pc->inACCM, 0, sizeof(ext_accm)); + pc->inACCM[15] = 0x60; + memset(pc->outACCM, 0, sizeof(ext_accm)); + pc->outACCM[15] = 0x60; + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + sys_thread_new(PPP_THREAD_NAME, pppMain, (void*)pd, PPP_THREAD_STACKSIZE, PPP_THREAD_PRIO); + if(!linkStatusCB) { + while(pd >= 0 && !pc->if_up) { + sys_msleep(500); + if (lcp_phase[pd] == PHASE_DEAD) { + pppClose(pd); + if (pc->errCode) { + pd = pc->errCode; + } else { + pd = PPPERR_CONNECT; + } + } + } + } + } + + return pd; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static void pppOverEthernetLinkStatusCB(int pd, int up); + +void +pppOverEthernetClose(int pd) +{ + PPPControl* pc = &pppControl[pd]; + + /* *TJL* There's no lcp_deinit */ + lcp_close(pd, NULL); + + pppoe_destroy(&pc->netif); +} + +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx) +{ + PPPControl *pc; + int pd; + + LWIP_UNUSED_ARG(service_name); + LWIP_UNUSED_ARG(concentrator_name); + + /* Find a free PPP session descriptor. Critical region? */ + for (pd = 0; pd < NUM_PPP && pppControl[pd].openFlag != 0; pd++); + if (pd >= NUM_PPP) { + pd = PPPERR_OPEN; + } else { + pppControl[pd].openFlag = !0; + } + + /* PPP session descriptor found, start PPPoE */ + if (pd >= 0) { + + pppControl[pd].openFlag = 1; + + lcp_init(pd); + + lcp_wantoptions[pd].mru = PPPOE_MAXMTU; + lcp_wantoptions[pd].neg_asyncmap = 0; + lcp_wantoptions[pd].neg_pcompression = 0; + lcp_wantoptions[pd].neg_accompression = 0; + + lcp_allowoptions[pd].mru = PPPOE_MAXMTU; + lcp_allowoptions[pd].neg_asyncmap = 0; + lcp_allowoptions[pd].neg_pcompression = 0; + lcp_allowoptions[pd].neg_accompression = 0; + + pc = &pppControl[pd]; + pc->if_up = 0; + pc->errCode = 0; + pc->lastXMit = 0; +#if PPPOS_SUPPORT + pc->kill_link = 0; + pc->sig_hup = 0; + pc->inState = PDIDLE; + pc->inHead = NULL; + pc->inTail = NULL; + pc->inEscaped = 0; +#if VJ_SUPPORT + pc->vjEnabled = 0; +#endif /* VJ_SUPPORT */ +#endif /* PPPOS_SUPPORT */ + pc->ethif= ethif; + + memset(pc->inACCM, 0, sizeof(ext_accm)); + memset(pc->outACCM, 0, sizeof(ext_accm)); + + pc->linkStatusCB = linkStatusCB; + pc->linkStatusCtx = linkStatusCtx; + + if(pppoe_create(ethif, pd, pppOverEthernetLinkStatusCB, &pc->pppoe_sc) != ERR_OK) { + pc->openFlag = 0; + return PPPERR_OPEN; + } + + pppoe_connect(pc->pppoe_sc); + + if(!linkStatusCB) { + while(pd >= 0 && !pc->if_up) { + sys_msleep(500); + if (lcp_phase[pd] == PHASE_DEAD) { + pppClose(pd); + if (pc->errCode) { + pd = pc->errCode; + } else { + pd = PPPERR_CONNECT; + } + } + } + } + } + + return pd; +} +#endif /* PPPOE_SUPPORT */ + + +/* Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. */ +int +pppClose(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + /* Disconnect */ +#if PPPOE_SUPPORT + if(pc->ethif) { + PPPDEBUG((LOG_DEBUG, "pppClose: unit %d kill_link -> pppStopCB\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + tcpip_callback(pppStopCB, (void*)pd); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + pc->kill_link = !0; + pppMainWakeup(pd); +#endif /* PPPOS_SUPPORT */ + } + + if(!pc->linkStatusCB) { + while(st >= 0 && lcp_phase[pd] != PHASE_DEAD) { + sys_msleep(500); + break; + } + } + + return st; +} + +/* This function is called when carrier is lost on the PPP channel. */ +void +pppSigHUP(int pd) +{ + PPPControl *pc = &pppControl[pd]; + +#if PPPOE_SUPPORT + if(pc->ethif) { + PPPDEBUG((LOG_DEBUG, "pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd)); + tcpip_callback(pppHupCB, (void*)pd); + } else +#endif /* PPPOE_SUPPORT */ + { +#if PPPOS_SUPPORT + pc->sig_hup = 1; + pppMainWakeup(pd); +#endif /* PPPOS_SUPPORT */ + } +} + +#if PPPOS_SUPPORT +static void +nPut(PPPControl *pc, struct pbuf *nb) +{ + struct pbuf *b; + int c; + + for(b = nb; b != NULL; b = b->next) { + if((c = sio_write(pc->fd, b->payload, b->len)) != b->len) { + PPPDEBUG((LOG_WARNING, + "PPP nPut: incomplete sio_write(%d,, %u) = %d\n", pc->fd, b->len, c)); + LINK_STATS_INC(link.err); + pc->lastXMit = 0; /* prepend PPP_FLAG to next packet */ + break; + } + } + + pbuf_free(nb); + LINK_STATS_INC(link.xmit); +} + +/* + * pppAppend - append given character to end of given pbuf. If outACCM + * is not NULL and the character needs to be escaped, do so. + * If pbuf is full, append another. + * Return the current pbuf. + */ +static struct pbuf * +pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM) +{ + struct pbuf *tb = nb; + + /* Make sure there is room for the character and an escape code. + * Sure we don't quite fill the buffer if the character doesn't + * get escaped but is one character worth complicating this? */ + /* Note: We assume no packet header. */ + if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { + tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (tb) { + nb->next = tb; + } else { + LINK_STATS_INC(link.memerr); + } + nb = tb; + } + + if (nb) { + if (outACCM && ESCAPE_P(*outACCM, c)) { + *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; + *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; + } else { + *((u_char*)nb->payload + nb->len++) = c; + } + } + + return tb; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static err_t +pppifOutputOverEthernet(int pd, struct pbuf *p) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + u_short protocol = PPP_IP; + int i=0; + + pb = pbuf_alloc(PBUF_LINK, pppoe_hdrlen + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + return ERR_MEM; + } + + pbuf_header(pb, -pppoe_hdrlen); + + pc->lastXMit = sys_jiffies(); + + if (!pc->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + return PPPERR_DEVICE; + } + + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + +/* Send a packet on the given connection. */ +static err_t +pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr) +{ + int pd = (int)netif->state; + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_short protocol = PPP_IP; + u_int fcsOut = PPP_INITFCS; + struct pbuf *headMB = NULL, *tailMB = NULL, *p; + u_char c; +#endif /* PPPOS_SUPPORT */ + + LWIP_UNUSED_ARG(ipaddr); + + /* Validate parameters. */ + /* We let any protocol value go through - it can't hurt us + * and the peer will just drop it if it's not accepting it. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag || !pb) { + PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad parms prot=%d pb=%p\n", + pd, PPP_IP, pb)); + LINK_STATS_INC(link.opterr); + LINK_STATS_INC(link.drop); + return ERR_ARG; + } + + /* Check that the link is up. */ + if (lcp_phase[pd] == PHASE_DEAD) { + PPPDEBUG((LOG_ERR, "pppifOutput[%d]: link not up\n", pd)); + LINK_STATS_INC(link.rterr); + LINK_STATS_INC(link.drop); + return ERR_RTE; + } + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppifOutputOverEthernet(pd, pb); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + /* Grab an output buffer. */ + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: first alloc fail\n", pd)); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + return ERR_MEM; + } + +#if VJ_SUPPORT + /* + * Attempt Van Jacobson header compression if VJ is configured and + * this is an IP packet. + */ + if (protocol == PPP_IP && pc->vjEnabled) { + switch (vj_compress_tcp(&pc->vjComp, pb)) { + case TYPE_IP: + /* No change... + protocol = PPP_IP_PROTOCOL; */ + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + break; + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + default: + PPPDEBUG((LOG_WARNING, "pppifOutput[%d]: bad IP packet\n", pd)); + LINK_STATS_INC(link.proterr); + LINK_STATS_INC(link.drop); + pbuf_free(headMB); + return ERR_VAL; + } + } +#endif /* VJ_SUPPORT */ + + tailMB = headMB; + + /* Build the PPP header. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + + pc->lastXMit = sys_jiffies(); + if (!pc->accomp) { + fcsOut = PPP_FCS(fcsOut, PPP_ALLSTATIONS); + tailMB = pppAppend(PPP_ALLSTATIONS, tailMB, &pc->outACCM); + fcsOut = PPP_FCS(fcsOut, PPP_UI); + tailMB = pppAppend(PPP_UI, tailMB, &pc->outACCM); + } + if (!pc->pcomp || protocol > 0xFF) { + c = (protocol >> 8) & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + c = protocol & 0xFF; + fcsOut = PPP_FCS(fcsOut, c); + tailMB = pppAppend(c, tailMB, &pc->outACCM); + + /* Load packet. */ + for(p = pb; p; p = p->next) { + int n; + u_char *sPtr; + + sPtr = (u_char*)p->payload; + n = p->len; + while (n-- > 0) { + c = *sPtr++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. */ + if (!tailMB) { + PPPDEBUG((LOG_WARNING, + "pppifOutput[%d]: Alloc err - dropping proto=%d\n", + pd, protocol)); + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + return ERR_MEM; + } + + /* Send it. */ + PPPDEBUG((LOG_INFO, "pppifOutput[%d]: proto=0x%04X\n", pd, protocol)); + + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return ERR_OK; +} + +/* Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. */ +int +pppIOCtl(int pd, int cmd, void *arg) +{ + PPPControl *pc = &pppControl[pd]; + int st = 0; + + if (pd < 0 || pd >= NUM_PPP) { + st = PPPERR_PARAM; + } else { + switch(cmd) { + case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ + if (arg) { + *(int *)arg = (int)(pc->if_up); + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLS_ERRCODE: /* Set the PPP error code. */ + if (arg) { + pc->errCode = *(int *)arg; + } else { + st = PPPERR_PARAM; + } + break; + case PPPCTLG_ERRCODE: /* Get the PPP error code. */ + if (arg) { + *(int *)arg = (int)(pc->errCode); + } else { + st = PPPERR_PARAM; + } + break; +#if PPPOS_SUPPORT + case PPPCTLG_FD: + if (arg) { + *(sio_fd_t *)arg = pc->fd; + } else { + st = PPPERR_PARAM; + } + break; +#endif /* PPPOS_SUPPORT */ + default: + st = PPPERR_PARAM; + break; + } + } + + return st; +} + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_int +pppMTU(int pd) +{ + PPPControl *pc = &pppControl[pd]; + u_int st; + + /* Validate parameters. */ + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + } else { + st = pc->mtu; + } + + return st; +} + +#if PPPOE_SUPPORT +int +pppWriteOverEthernet(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *pb; + + /* skip address & flags */ + s += 2; + n -= 2; + + pb = pbuf_alloc(PBUF_LINK, pppoe_hdrlen + n, PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + return PPPERR_ALLOC; + } + + pbuf_header(pb, -pppoe_hdrlen); + + pc->lastXMit = sys_jiffies(); + + MEMCPY(pb->payload, s, n); + + if(pppoe_xmit(pc->pppoe_sc, pb) != ERR_OK) { + LINK_STATS_INC(link.err); + return PPPERR_DEVICE; + } + + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written + * -1 Failed to write to device + */ +int +pppWrite(int pd, const u_char *s, int n) +{ + PPPControl *pc = &pppControl[pd]; +#if PPPOS_SUPPORT + u_char c; + u_int fcsOut; + struct pbuf *headMB, *tailMB; +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT + if(pc->ethif) { + return pppWriteOverEthernet(pd, s, n); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOS_SUPPORT + headMB = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (headMB == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + return PPPERR_ALLOC; + } + + tailMB = headMB; + + /* If the link has been idle, we'll send a fresh flag character to + * flush any noise. */ + if ((sys_jiffies() - pc->lastXMit) >= PPP_MAXIDLEFLAG) { + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + } + pc->lastXMit = sys_jiffies(); + + fcsOut = PPP_INITFCS; + /* Load output buffer. */ + while (n-- > 0) { + c = *s++; + + /* Update FCS before checking for special characters. */ + fcsOut = PPP_FCS(fcsOut, c); + + /* Copy to output buffer escaping special characters. */ + tailMB = pppAppend(c, tailMB, &pc->outACCM); + } + + /* Add FCS and trailing flag. */ + c = ~fcsOut & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + c = (~fcsOut >> 8) & 0xFF; + tailMB = pppAppend(c, tailMB, &pc->outACCM); + tailMB = pppAppend(PPP_FLAG, tailMB, NULL); + + /* If we failed to complete the packet, throw it away. + * Otherwise send it. */ + if (!tailMB) { + PPPDEBUG((LOG_WARNING, + "pppWrite[%d]: Alloc err - dropping pbuf len=%d\n", pd, headMB->len)); + /*"pppWrite[%d]: Alloc err - dropping %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + pbuf_free(headMB); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + return PPPERR_ALLOC; + } + + PPPDEBUG((LOG_INFO, "pppWrite[%d]: len=%d\n", pd, headMB->len)); + /* "pppWrite[%d]: %d:%.*H", pd, headMB->len, LWIP_MIN(headMB->len * 2, 40), headMB->payload)); */ + nPut(pc, headMB); +#endif /* PPPOS_SUPPORT */ + + return PPPERR_NONE; +} + +/* + * ppp_send_config - configure the transmit characteristics of + * the ppp interface. + */ +void +ppp_send_config( int unit, int mtu, u32_t asyncmap, int pcomp, int accomp) +{ + PPPControl *pc = &pppControl[unit]; + int i; + + pc->mtu = mtu; + pc->pcomp = pcomp; + pc->accomp = accomp; + + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32/8; i++) { + pc->outACCM[i] = (u_char)((asyncmap >> (8 * i)) & 0xFF); + } + PPPDEBUG((LOG_INFO, "ppp_send_config[%d]: outACCM=%X %X %X %X\n", + unit, + pc->outACCM[0], pc->outACCM[1], pc->outACCM[2], pc->outACCM[3])); +} + + +/* + * ppp_set_xaccm - set the extended transmit ACCM for the interface. + */ +void +ppp_set_xaccm(int unit, ext_accm *accm) +{ + SMEMCPY(pppControl[unit].outACCM, accm, sizeof(ext_accm)); + PPPDEBUG((LOG_INFO, "ppp_set_xaccm[%d]: outACCM=%X %X %X %X\n", + unit, + pppControl[unit].outACCM[0], + pppControl[unit].outACCM[1], + pppControl[unit].outACCM[2], + pppControl[unit].outACCM[3])); +} + + +/* + * ppp_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ +void +ppp_recv_config( int unit, int mru, u32_t asyncmap, int pcomp, int accomp) +{ + PPPControl *pc = &pppControl[unit]; + int i; + + LWIP_UNUSED_ARG(accomp); + LWIP_UNUSED_ARG(pcomp); + LWIP_UNUSED_ARG(mru); + + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32 / 8; i++) { + pc->inACCM[i] = (u_char)(asyncmap >> (i * 8)); + } + PPPDEBUG((LOG_INFO, "ppp_recv_config[%d]: inACCM=%X %X %X %X\n", + unit, + pc->inACCM[0], pc->inACCM[1], pc->inACCM[2], pc->inACCM[3])); +} + +#if 0 +/* + * ccp_test - ask kernel whether a given compression method + * is acceptable for use. Returns 1 if the method and parameters + * are OK, 0 if the method is known but the parameters are not OK + * (e.g. code size should be reduced), or -1 if the method is unknown. + */ +int +ccp_test( int unit, int opt_len, int for_transmit, u_char *opt_ptr) +{ + return 0; /* XXX Currently no compression. */ +} + +/* + * ccp_flags_set - inform kernel about the current state of CCP. + */ +void +ccp_flags_set(int unit, int isopen, int isup) +{ + /* XXX */ +} + +/* + * ccp_fatal_error - returns 1 if decompression was disabled as a + * result of an error detected after decompression of a packet, + * 0 otherwise. This is necessary because of patent nonsense. + */ +int +ccp_fatal_error(int unit) +{ + /* XXX */ + return 0; +} +#endif + +/* + * get_idle_time - return how long the link has been idle. + */ +int +get_idle_time(int u, struct ppp_idle *ip) +{ + /* XXX */ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(ip); + + return 0; +} + + +/* + * Return user specified netmask, modified by any mask we might determine + * for address `addr' (in network byte order). + * Here we scan through the system's list of interfaces, looking for + * any non-point-to-point interfaces which might appear to be on the same + * network as `addr'. If we find any, we OR in their netmask to the + * user-specified netmask. + */ +u32_t +GetMask(u32_t addr) +{ + u32_t mask, nmask; + + htonl(addr); + if (IN_CLASSA(addr)) { /* determine network mask for address class */ + nmask = IN_CLASSA_NET; + } else if (IN_CLASSB(addr)) { + nmask = IN_CLASSB_NET; + } else { + nmask = IN_CLASSC_NET; + } + + /* class D nets are disallowed by bad_ip_adrs */ + mask = subnetMask | htonl(nmask); + + /* XXX + * Scan through the system's network interfaces. + * Get each netmask and OR them into our mask. + */ + + return mask; +} + +/* + * sifvjcomp - config tcp header compression + */ +int +sifvjcomp(int pd, int vjcomp, int cidcomp, int maxcid) +{ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPControl *pc = &pppControl[pd]; + + pc->vjEnabled = vjcomp; + pc->vjComp.compressSlot = cidcomp; + pc->vjComp.maxSlotIndex = maxcid; + PPPDEBUG((LOG_INFO, "sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", + vjcomp, cidcomp, maxcid)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + LWIP_UNUSED_ARG(pd); + LWIP_UNUSED_ARG(vjcomp); + LWIP_UNUSED_ARG(cidcomp); + LWIP_UNUSED_ARG(maxcid); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + return 0; +} + +/* + * pppifNetifInit - netif init callback + */ +static err_t +pppifNetifInit(struct netif *netif) +{ + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = pppifOutput; + netif->mtu = pppMTU((int)netif->state); + return ERR_OK; +} + + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +int +sifup(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd)); + } else { + netif_remove(&pc->netif); + if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) { + netif_set_up(&pc->netif); + pc->if_up = 1; + pc->errCode = PPPERR_NONE; + + PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode, &pc->addrs); + } + } else { + st = 0; + PPPDEBUG((LOG_ERR, "sifup[%d]: netif_add failed\n", pd)); + } + } + + return st; +} + +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int +sifnpmode(int u, int proto, enum NPmode mode) +{ + LWIP_UNUSED_ARG(u); + LWIP_UNUSED_ARG(proto); + LWIP_UNUSED_ARG(mode); + return 0; +} + +/* + * sifdown - Config the interface down and disable IP. + */ +int +sifdown(int pd) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd)); + } else { + pc->if_up = 0; + /* make sure the netif status callback is called */ + netif_set_down(&pc->netif); + netif_remove(&pc->netif); + PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL); + } + } + return st; +} + +/** + * sifaddr - Config the interface IP addresses and netmask. + * @param pd Interface unit ??? + * @param o Our IP address ??? + * @param h His IP address ??? + * @param m IP subnet mask ??? + * @param ns1 Primary DNS + * @param ns2 Secondary DNS + */ +int +sifaddr( int pd, u32_t o, u32_t h, u32_t m, u32_t ns1, u32_t ns2) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd)); + } else { + SMEMCPY(&pc->addrs.our_ipaddr, &o, sizeof(o)); + SMEMCPY(&pc->addrs.his_ipaddr, &h, sizeof(h)); + SMEMCPY(&pc->addrs.netmask, &m, sizeof(m)); + SMEMCPY(&pc->addrs.dns1, &ns1, sizeof(ns1)); + SMEMCPY(&pc->addrs.dns2, &ns2, sizeof(ns2)); + } + return st; +} + +/** + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + * @param pd Interface unit ??? + * @param o Our IP address ??? + * @param h IP broadcast address ??? + */ +int +cifaddr( int pd, u32_t o, u32_t h) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(o); + LWIP_UNUSED_ARG(h); + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd)); + } else { + IP4_ADDR(&pc->addrs.our_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.his_ipaddr, 0,0,0,0); + IP4_ADDR(&pc->addrs.netmask, 255,255,255,0); + IP4_ADDR(&pc->addrs.dns1, 0,0,0,0); + IP4_ADDR(&pc->addrs.dns2, 0,0,0,0); + } + return st; +} + +/* + * sifdefaultroute - assign a default route through the address given. + */ +int +sifdefaultroute(int pd, u32_t l, u32_t g) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(l); + LWIP_UNUSED_ARG(g); + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd)); + } else { + netif_set_default(&pc->netif); + } + + /* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */ + + return st; +} + +/* + * cifdefaultroute - delete a default route through the address given. + */ +int +cifdefaultroute(int pd, u32_t l, u32_t g) +{ + PPPControl *pc = &pppControl[pd]; + int st = 1; + + LWIP_UNUSED_ARG(l); + LWIP_UNUSED_ARG(g); + + if (pd < 0 || pd >= NUM_PPP || !pc->openFlag) { + st = 0; + PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd)); + } else { + netif_set_default(NULL); + } + + return st; +} + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +#if PPPOS_SUPPORT +/* The main PPP process function. This implements the state machine according + * to section 4 of RFC 1661: The Point-To-Point Protocol. */ +static void +pppMain(void *arg) +{ + int pd = (int)arg; + struct pbuf *p; + PPPControl* pc; + int c; + + pc = &pppControl[pd]; + + p = pbuf_alloc(PBUF_RAW, PPP_MRU+PPP_HDRLEN, PBUF_RAM); + if (!p) { + LWIP_ASSERT("p != NULL", p); + pc->errCode = PPPERR_ALLOC; + goto out; + } + + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd)); + tcpip_callback(pppStartCB, arg); + while (lcp_phase[pd] != PHASE_DEAD) { + if (pc->kill_link) { + PPPDEBUG((LOG_DEBUG, "pppMain: unit %d kill_link -> pppStopCB\n", pd)); + pc->errCode = PPPERR_USER; + /* This will leave us at PHASE_DEAD. */ + tcpip_callback(pppStopCB, arg); + pc->kill_link = 0; + } else if (pc->sig_hup) { + PPPDEBUG((LOG_DEBUG, "pppMain: unit %d sig_hup -> pppHupCB\n", pd)); + pc->sig_hup = 0; + tcpip_callback(pppHupCB, arg); + } else { + c = sio_read(pc->fd, p->payload, p->len); + if(c > 0) { + pppInProc(pd, p->payload, c); + } else { + /* nothing received, give other tasks a chance to run */ + sys_msleep(1); + } + } + } + PPPDEBUG((LOG_INFO, "pppMain: unit %d: PHASE_DEAD\n", pd)); + pppDrop(pc); /* bug fix #17726 */ + pbuf_free(p); + +out: + PPPDEBUG((LOG_DEBUG, "pppMain: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode)); + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } + + pc->openFlag = 0; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT + +void +pppOverEthernetInitFailed(void* arg) +{ + PPPControl* pc; + int pd = (int)arg; + + pppHupCB(arg); + pppStopCB(arg); + + pc = &pppControl[pd]; + pppoe_destroy(&pc->netif); + pc->openFlag = 0; + + if(pc->linkStatusCB) { + pc->linkStatusCB(pc->linkStatusCtx, pc->errCode ? pc->errCode : PPPERR_PROTOCOL, NULL); + } +} + +static void +pppOverEthernetLinkStatusCB(int pd, int up) +{ + if(up) { + PPPDEBUG((LOG_INFO, "pppMain: unit %d: Connecting\n", pd)); + tcpip_callback(pppStartCB, (void*)pd); + } else { + PPPControl* pc; + pc = &pppControl[pd]; + tcpip_callback(pppOverEthernetInitFailed, (void*)pd); + } +} +#endif /* PPPOE_SUPPORT */ + +struct pbuf * +pppSingleBuf(struct pbuf *p) +{ + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG((LOG_ERR, + "pppSingleBuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + +struct pppInputHeader { + int unit; + u16_t proto; +}; + +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ +static void +pppInput(void *arg) +{ + struct pbuf *nb = (struct pbuf *)arg; + u16_t protocol; + int pd; + + pd = ((struct pppInputHeader *)nb->payload)->unit; + protocol = ((struct pppInputHeader *)nb->payload)->proto; + + if(pbuf_header(nb, -(int)sizeof(struct pppInputHeader))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + LINK_STATS_INC(link.recv); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if((lcp_phase[pd] <= PHASE_AUTHENTICATE) && (protocol != PPP_LCP)) { + if(!((protocol == PPP_LQR) || (protocol == PPP_PAP) || (protocol == PPP_CHAP)) || + (lcp_phase[pd] != PHASE_AUTHENTICATE)) { + PPPDEBUG((LOG_INFO, "pppInput: discarding proto 0x%04X in phase %d\n", protocol, lcp_phase[pd])); + goto drop; + } + } + + switch(protocol) { + case PPP_VJC_COMP: /* VJ compressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_comp in pbuf len=%d\n", pd, nb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if ((vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) && (pppControl[pd].netif.input)) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ compressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG((LOG_INFO, "pppInput[%d]: drop VJ Comp in %d:%s\n", pd, nb->len, nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ +#if PPPOS_SUPPORT && VJ_SUPPORT + PPPDEBUG((LOG_INFO, "pppInput[%d]: vj_un in pbuf len=%d\n", pd, nb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if ((vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) && pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG((LOG_WARNING, "pppInput[%d]: Dropping VJ uncompressed\n", pd)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + /* No handler for this protocol so drop the packet. */ + PPPDEBUG((LOG_INFO, + "pppInput[%d]: drop VJ UnComp in %d:.*H\n", + pd, nb->len, LWIP_MIN(nb->len * 2, 40), nb->payload)); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + break; + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len)); + if (pppControl[pd].netif.input) { + pppControl[pd].netif.input(nb, &pppControl[pd].netif); + return; + } + break; + + default: { + struct protent *protp; + int i; + + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = ppp_protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + PPPDEBUG((LOG_INFO, "pppInput[%d]: %s len=%d\n", pd, protp->name, nb->len)); + nb = pppSingleBuf(nb); + (*protp->input)(pd, nb->payload, nb->len); + goto out; + } + } + + /* No handler for this protocol so reject the packet. */ + PPPDEBUG((LOG_INFO, "pppInput[%d]: rejecting unsupported proto 0x%04X len=%d\n", pd, protocol, nb->len)); + if (pbuf_header(nb, sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } +#if BYTE_ORDER == LITTLE_ENDIAN + protocol = htons(protocol); + SMEMCPY(nb->payload, &protocol, sizeof(protocol)); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + lcp_sprotrej(pd, nb->payload, nb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + +out: + pbuf_free(nb); + return; +} + +#if PPPOS_SUPPORT +/* + * Drop the input packet. + */ +static void +pppDrop(PPPControl *pc) +{ + if (pc->inHead != NULL) { +#if 0 + PPPDEBUG((LOG_INFO, "pppDrop: %d:%.*H\n", pc->inHead->len, min(60, pc->inHead->len * 2), pc->inHead->payload)); +#endif + PPPDEBUG((LOG_INFO, "pppDrop: pbuf len=%d\n", pc->inHead->len)); + if (pc->inTail && (pc->inTail != pc->inHead)) { + pbuf_free(pc->inTail); + } + pbuf_free(pc->inHead); + pc->inHead = NULL; + pc->inTail = NULL; + } +#if VJ_SUPPORT + vj_uncompress_err(&pc->vjComp); +#endif /* VJ_SUPPORT */ + + LINK_STATS_INC(link.drop); +} + +/** + * Process a received octet string. + */ +static void +pppInProc(int pd, u_char *s, int l) +{ + PPPControl *pc = &pppControl[pd]; + struct pbuf *nextNBuf; + u_char curChar; + + PPPDEBUG((LOG_DEBUG, "pppInProc[%d]: got %d bytes\n", pd, l)); + while (l-- > 0) { + curChar = *s++; + + /* Handle special characters. */ + if (ESCAPE_P(pc->inACCM, curChar)) { + /* Check for escape sequences. */ + /* XXX Note that this does not handle an escaped 0x5d character which + * would appear as an escape character. Since this is an ASCII ']' + * and there is no reason that I know of to escape it, I won't complicate + * the code to handle this case. GLL */ + if (curChar == PPP_ESCAPE) { + pc->inEscaped = 1; + /* Check for the flag character. */ + } else if (curChar == PPP_FLAG) { + /* If this is just an extra flag character, ignore it. */ + if (pc->inState <= PDADDRESS) { + /* ignore it */; + /* If we haven't received the packet header, drop what has come in. */ + } else if (pc->inState < PDDATA) { + PPPDEBUG((LOG_WARNING, + "pppInProc[%d]: Dropping incomplete packet %d\n", + pd, pc->inState)); + LINK_STATS_INC(link.lenerr); + pppDrop(pc); + /* If the fcs is invalid, drop the packet. */ + } else if (pc->inFCS != PPP_GOODFCS) { + PPPDEBUG((LOG_INFO, + "pppInProc[%d]: Dropping bad fcs 0x%04X proto=0x%04X\n", + pd, pc->inFCS, pc->inProtocol)); + LINK_STATS_INC(link.chkerr); + pppDrop(pc); + /* Otherwise it's a good packet so pass it on. */ + } else { + /* Trim off the checksum. */ + if(pc->inTail->len >= 2) { + pc->inTail->len -= 2; + + pc->inTail->tot_len = pc->inTail->len; + if (pc->inTail != pc->inHead) { + pbuf_cat(pc->inHead, pc->inTail); + } + } else { + pc->inTail->tot_len = pc->inTail->len; + if (pc->inTail != pc->inHead) { + pbuf_cat(pc->inHead, pc->inTail); + } + + pbuf_realloc(pc->inHead, pc->inHead->tot_len - 2); + } + + /* Dispatch the packet thereby consuming it. */ + if(tcpip_callback(pppInput, pc->inHead) != ERR_OK) { + PPPDEBUG((LOG_ERR, "pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pd)); + pbuf_free(pc->inHead); + LINK_STATS_INC(link.drop); + } + pc->inHead = NULL; + pc->inTail = NULL; + } + + /* Prepare for a new packet. */ + pc->inFCS = PPP_INITFCS; + pc->inState = PDADDRESS; + pc->inEscaped = 0; + /* Other characters are usually control characters that may have + * been inserted by the physical layer so here we just drop them. */ + } else { + PPPDEBUG((LOG_WARNING, + "pppInProc[%d]: Dropping ACCM char <%d>\n", pd, curChar)); + } + /* Process other characters. */ + } else { + /* Unencode escaped characters. */ + if (pc->inEscaped) { + pc->inEscaped = 0; + curChar ^= PPP_TRANS; + } + + /* Process character relative to current state. */ + switch(pc->inState) { + case PDIDLE: /* Idle state - waiting. */ + /* Drop the character if it's not 0xff + * we would have processed a flag character above. */ + if (curChar != PPP_ALLSTATIONS) { + break; + } + + /* Fall through */ + case PDSTART: /* Process start flag. */ + /* Prepare for a new packet. */ + pc->inFCS = PPP_INITFCS; + + /* Fall through */ + case PDADDRESS: /* Process address field. */ + if (curChar == PPP_ALLSTATIONS) { + pc->inState = PDCONTROL; + break; + } + /* Else assume compressed address and control fields so + * fall through to get the protocol... */ + case PDCONTROL: /* Process control field. */ + /* If we don't get a valid control code, restart. */ + if (curChar == PPP_UI) { + pc->inState = PDPROTOCOL1; + break; + } +#if 0 + else { + PPPDEBUG((LOG_WARNING, + "pppInProc[%d]: Invalid control <%d>\n", pd, curChar)); + pc->inState = PDSTART; + } +#endif + case PDPROTOCOL1: /* Process protocol field 1. */ + /* If the lower bit is set, this is the end of the protocol + * field. */ + if (curChar & 1) { + pc->inProtocol = curChar; + pc->inState = PDDATA; + } else { + pc->inProtocol = (u_int)curChar << 8; + pc->inState = PDPROTOCOL2; + } + break; + case PDPROTOCOL2: /* Process protocol field 2. */ + pc->inProtocol |= curChar; + pc->inState = PDDATA; + break; + case PDDATA: /* Process data byte. */ + /* Make space to receive processed data. */ + if (pc->inTail == NULL || pc->inTail->len == PBUF_POOL_BUFSIZE) { + if(pc->inTail) { + pc->inTail->tot_len = pc->inTail->len; + if (pc->inTail != pc->inHead) { + pbuf_cat(pc->inHead, pc->inTail); + } + } + /* If we haven't started a packet, we need a packet header. */ + nextNBuf = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (nextNBuf == NULL) { + /* No free buffers. Drop the input packet and let the + * higher layers deal with it. Continue processing + * the received pbuf chain in case a new packet starts. */ + PPPDEBUG((LOG_ERR, "pppInProc[%d]: NO FREE MBUFS!\n", pd)); + LINK_STATS_INC(link.memerr); + pppDrop(pc); + pc->inState = PDSTART; /* Wait for flag sequence. */ + break; + } + if (pc->inHead == NULL) { + struct pppInputHeader *pih = nextNBuf->payload; + + pih->unit = pd; + pih->proto = pc->inProtocol; + + nextNBuf->len += sizeof(*pih); + + pc->inHead = nextNBuf; + } + pc->inTail = nextNBuf; + } + /* Load character into buffer. */ + ((u_char*)pc->inTail->payload)[pc->inTail->len++] = curChar; + break; + } + + /* update the frame check sequence number. */ + pc->inFCS = PPP_FCS(pc->inFCS, curChar); + } + } + + avRandomize(); +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +void +pppInProcOverEthernet(int pd, struct pbuf *pb) +{ + struct pppInputHeader *pih; + u16_t inProtocol; + + if(pb->len < sizeof(inProtocol)) { + PPPDEBUG((LOG_ERR, "pppInProcOverEthernet: too small for protocol field\n")); + goto drop; + } + + inProtocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + + /* make room for pppInputHeader - should not fail */ + if (pbuf_header(pb, sizeof(*pih) - sizeof(inProtocol)) != 0) { + PPPDEBUG((LOG_ERR, "pppInProcOverEthernet: could not allocate room for header\n")); + goto drop; + } + + pih = pb->payload; + + pih->unit = pd; + pih->proto = inProtocol; + + /* Dispatch the packet thereby consuming it. */ + if(tcpip_callback(pppInput, pb) != ERR_OK) { + PPPDEBUG((LOG_ERR, "pppInProcOverEthernet[%d]: tcpip_callback() failed, dropping packet\n", pd)); + goto drop; + } + + return; + +drop: + LINK_STATS_INC(link.drop); + pbuf_free(pb); + return; +} +#endif /* PPPOE_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.h new file mode 100644 index 0000000..ebc733b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp.h @@ -0,0 +1,465 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#ifndef PPP_H +#define PPP_H + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/sio.h" +#include "lwip/api.h" +#include "lwip/sockets.h" +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/tcpip.h" +#include "lwip/netif.h" + +/* + * pppd.h - PPP daemon global declarations. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ +/* + * ppp_defs.h - PPP definitions. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +#define TIMEOUT(f, a, t) sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a)) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + + +#ifndef __u_char_defined + +/* Type definitions for BSD code. */ +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; + +#endif + +/* + * Constants and structures defined by the internet system, + * Per RFC 790, September 1981, and numerous additions. + */ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#define PPP_COMP 0xfd /* compressed packet */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) + +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_char ext_accm[32]; + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Inline versions of get/put char/short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETCHAR(c, cp) { \ + (c) = *(cp)++; \ +} +#define PUTCHAR(c, cp) { \ + *(cp)++ = (u_char) (c); \ +} + + +#define GETSHORT(s, cp) { \ + (s) = *(cp); (cp)++; (s) <<= 8; \ + (s) |= *(cp); (cp)++; \ +} +#define PUTSHORT(s, cp) { \ + *(cp)++ = (u_char) ((s) >> 8); \ + *(cp)++ = (u_char) (s & 0xff); \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; (l) <<= 8; \ + (l) |= *(cp); (cp)++; \ +} +#define PUTLONG(l, cp) { \ + *(cp)++ = (u_char) ((l) >> 24); \ + *(cp)++ = (u_char) ((l) >> 16); \ + *(cp)++ = (u_char) ((l) >> 8); \ + *(cp)++ = (u_char) (l); \ +} + + +#define INCPTR(n, cp) ((cp) += (n)) +#define DECPTR(n, cp) ((cp) -= (n)) + +#define BCMP(s0, s1, l) memcmp((u_char *)(s0), (u_char *)(s1), (l)) +#define BCOPY(s, d, l) MEMCPY((d), (s), (l)) +#define BZERO(s, n) memset(s, 0, n) + +#if PPP_DEBUG +#define PRINTMSG(m, l) { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); } +#else /* PPP_DEBUG */ +#define PRINTMSG(m, l) +#endif /* PPP_DEBUG */ + +/* + * MAKEHEADER - Add PPP Header fields to a packet. + */ +#define MAKEHEADER(p, t) { \ + PUTCHAR(PPP_ALLSTATIONS, p); \ + PUTCHAR(PPP_UI, p); \ + PUTSHORT(t, p); } + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ + +/* Error codes. */ +#define PPPERR_NONE 0 /* No error. */ +#define PPPERR_PARAM -1 /* Invalid parameter. */ +#define PPPERR_OPEN -2 /* Unable to open PPP session. */ +#define PPPERR_DEVICE -3 /* Invalid I/O device for PPP. */ +#define PPPERR_ALLOC -4 /* Unable to allocate resources. */ +#define PPPERR_USER -5 /* User interrupt. */ +#define PPPERR_CONNECT -6 /* Connection lost. */ +#define PPPERR_AUTHFAIL -7 /* Failed authentication challenge. */ +#define PPPERR_PROTOCOL -8 /* Failed to meet protocol. */ + +/* + * PPP IOCTL commands. + */ +/* + * Get the up status - 0 for down, non-zero for up. The argument must + * point to an int. + */ +#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ +#define PPPCTLS_ERRCODE 101 /* Set the error code */ +#define PPPCTLG_ERRCODE 102 /* Get the error code */ +#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * The following struct gives the addresses of procedures to call + * for a particular protocol. + */ +struct protent { + u_short protocol; /* PPP protocol number */ + /* Initialization procedure */ + void (*init) (int unit); + /* Process a received packet */ + void (*input) (int unit, u_char *pkt, int len); + /* Process a received protocol-reject */ + void (*protrej) (int unit); + /* Lower layer has come up */ + void (*lowerup) (int unit); + /* Lower layer has gone down */ + void (*lowerdown) (int unit); + /* Open the protocol */ + void (*open) (int unit); + /* Close the protocol */ + void (*close) (int unit, char *reason); +#if 0 + /* Print a packet in readable form */ + int (*printpkt) (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); + /* Process a received data packet */ + void (*datainput) (int unit, u_char *pkt, int len); +#endif + int enabled_flag; /* 0 iff protocol is disabled */ + char *name; /* Text name of protocol */ +#if 0 + /* Check requested options, assign defaults */ + void (*check_options) (u_long); + /* Configure interface for demand-dial */ + int (*demand_conf) (int unit); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) (u_char *pkt, int len); +#endif +}; + +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + u_short xmit_idle; /* seconds since last NP packet sent */ + u_short recv_idle; /* seconds since last NP packet received */ +}; + +struct ppp_settings { + + u_int disable_defaultip : 1; /* Don't use hostname for default IP addrs */ + u_int auth_required : 1; /* Peer is required to authenticate */ + u_int explicit_remote : 1; /* remote_name specified with remotename opt */ + u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ + u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ + u_int usehostname : 1; /* Use hostname for our_name */ + u_int usepeerdns : 1; /* Ask peer for DNS adds */ + + u_short idle_time_limit; /* Shut down link if idle for this long */ + int maxconnect; /* Maximum connect time (seconds) */ + + char user [MAXNAMELEN + 1]; /* Username for PAP */ + char passwd [MAXSECRETLEN + 1]; /* Password for PAP, secret for CHAP */ + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +}; + +struct ppp_addrs { + struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2; +}; + +/***************************** +*** PUBLIC DATA STRUCTURES *** +*****************************/ + +/* Buffers for outgoing packets. */ +extern u_char outpacket_buf[NUM_PPP][PPP_MRU+PPP_HDRLEN]; + +extern struct ppp_settings ppp_settings; + +extern struct protent *ppp_protocols[]; /* Table of pointers to supported protocols */ + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* Initialize the PPP subsystem. */ +void pppInit(void); + +/* Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ +enum pppAuthType { + PPPAUTHTYPE_NONE, + PPPAUTHTYPE_ANY, + PPPAUTHTYPE_PAP, + PPPAUTHTYPE_CHAP +}; + +void pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd); + +/* + * Open a new PPP connection using the given serial I/O device. + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. + * Return a new PPP connection descriptor on success or + * an error code (negative) on failure. + */ +int pppOverSerialOpen(sio_fd_t fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx); + +/* + * Open a new PPP Over Ethernet (PPPOE) connection. + */ +int pppOverEthernetOpen(struct netif *ethif, const char *service_name, const char *concentrator_name, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx); + +/* for source code compatibility */ +#define pppOpen(fd,cb,ls) pppOverSerialOpen(fd,cb,ls) + +/* + * Close a PPP connection and release the descriptor. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. + */ +int pppClose(int pd); + +/* + * Indicate to the PPP process that the line has disconnected. + */ +void pppSigHUP(int pd); + +/* + * Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. + */ +int pppIOCtl(int pd, int cmd, void *arg); + +/* + * Return the Maximum Transmission Unit for the given PPP connection. + */ +u_int pppMTU(int pd); + +/* + * Write n characters to a ppp link. + * RETURN: >= 0 Number of characters written, -1 Failed to write to device. + */ +int pppWrite(int pd, const u_char *s, int n); + +void pppInProcOverEthernet(int pd, struct pbuf *pb); + +struct pbuf *pppSingleBuf(struct pbuf *p); + +void pppLinkTerminated(int pd); + +void pppLinkDown(int pd); + +void pppMainWakeup(int pd); + +/* Configure i/f transmit parameters */ +void ppp_send_config (int, int, u32_t, int, int); +/* Set extended transmit ACCM */ +void ppp_set_xaccm (int, ext_accm *); +/* Configure i/f receive parameters */ +void ppp_recv_config (int, int, u32_t, int, int); +/* Find out how long link has been idle */ +int get_idle_time (int, struct ppp_idle *); + +/* Configure VJ TCP header compression */ +int sifvjcomp (int, int, int, int); +/* Configure i/f down (for IP) */ +int sifup (int); +/* Set mode for handling packets for proto */ +int sifnpmode (int u, int proto, enum NPmode mode); +/* Configure i/f down (for IP) */ +int sifdown (int); +/* Configure IP addresses for i/f */ +int sifaddr (int, u32_t, u32_t, u32_t, u32_t, u32_t); +/* Reset i/f IP addresses */ +int cifaddr (int, u32_t, u32_t); +/* Create default route through i/f */ +int sifdefaultroute (int, u32_t, u32_t); +/* Delete default route through i/f */ +int cifdefaultroute (int, u32_t, u32_t); + +/* Get appropriate netmask for address */ +u32_t GetMask (u32_t); + +#endif /* PPP_SUPPORT */ + +#endif /* PPP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp_oe.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp_oe.c new file mode 100644 index 0000000..5a8a45c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/ppp_oe.c @@ -0,0 +1,1227 @@ +/***************************************************************************** +* ppp_oe.c - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "lwip/sys.h" + +#include "netif/ppp_oe.h" +#include "netif/etharp.h" + +#include +#include + +/** @todo Replace this part with a simple list like other lwIP lists */ +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ + + +/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ +#define PPPOE_ADD_16(PTR, VAL) \ + *(PTR)++ = (VAL) / 256; \ + *(PTR)++ = (VAL) % 256 + +/* Add a complete PPPoE header to the buffer pointed to by PTR */ +#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ + *(PTR)++ = PPPOE_VERTYPE; \ + *(PTR)++ = (CODE); \ + PPPOE_ADD_16(PTR, SESS); \ + PPPOE_ADD_16(PTR, LEN) + +#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ +#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ +#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ +#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ + +#ifdef PPPOE_SERVER +/* from if_spppsubr.c */ +#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ +#endif + +struct pppoe_softc { + LIST_ENTRY(pppoe_softc) sc_list; + struct netif *sc_ethif; /* ethernet interface we are using */ + int sc_pd; /* ppp unit number */ + void (*sc_linkStatusCB)(int pd, int up); + + int sc_state; /* discovery phase or session connected */ + struct eth_addr sc_dest; /* hardware address of concentrator */ + u16_t sc_session; /* PPPoE session id */ + + char *sc_service_name; /* if != NULL: requested name of service */ + char *sc_concentrator_name; /* if != NULL: requested concentrator id */ + u8_t *sc_ac_cookie; /* content of AC cookie we must echo back */ + size_t sc_ac_cookie_len; /* length of cookie data */ +#ifdef PPPOE_SERVER + u8_t *sc_hunique; /* content of host unique we must echo back */ + size_t sc_hunique_len; /* length of host unique */ +#endif + int sc_padi_retried; /* number of PADI retries already done */ + int sc_padr_retried; /* number of PADR retries already done */ +}; + +/* input routines */ +static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *); + +/* management routines */ +static int pppoe_do_disconnect(struct pppoe_softc *); +static void pppoe_abort_connect(struct pppoe_softc *); +static void pppoe_clear_softc(struct pppoe_softc *, const char *); + +/* internal timeout handling */ +static void pppoe_timeout(void *); + +/* sending actual protocol controll packets */ +static err_t pppoe_send_padi(struct pppoe_softc *); +static err_t pppoe_send_padr(struct pppoe_softc *); +#ifdef PPPOE_SERVER +static err_t pppoe_send_pado(struct pppoe_softc *); +static err_t pppoe_send_pads(struct pppoe_softc *); +#endif +static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); + +/* internal helper functions */ +static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *); +static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *); + +static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list; + +int pppoe_hdrlen; + +void +pppoe_init(void) +{ + pppoe_hdrlen = sizeof(struct eth_hdr) + PPPOE_HEADERLEN; + LIST_INIT(&pppoe_softc_list); +} + +err_t +pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr) +{ + struct pppoe_softc *sc; + + sc = mem_malloc(sizeof(struct pppoe_softc)); + if(!sc) { + *scptr = NULL; + return ERR_MEM; + } + memset(sc, 0, sizeof(struct pppoe_softc)); + + /* changed to real address later */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + + sc->sc_pd = pd; + sc->sc_linkStatusCB = linkStatusCB; + sc->sc_ethif = ethif; + + LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list); + + *scptr = sc; + + return ERR_OK; +} + +err_t +pppoe_destroy(struct netif *ifp) +{ + struct pppoe_softc * sc; + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc->sc_ethif == ifp) { + break; + } + } + + if(!(sc && (sc->sc_ethif == ifp))) { + return ERR_IF; + } + + tcpip_untimeout(pppoe_timeout, sc); + LIST_REMOVE(sc, sc_list); + + if (sc->sc_concentrator_name) { + mem_free(sc->sc_concentrator_name); + } + if (sc->sc_service_name) { + mem_free(sc->sc_service_name); + } + if (sc->sc_ac_cookie) { + mem_free(sc->sc_ac_cookie); + } + mem_free(sc); + + return ERR_OK; +} + +/* + * Find the interface handling the specified session. + * Note: O(number of sessions open), this is a client-side only, mean + * and lean implementation, so number of open sessions typically should + * be 1. + */ +static struct pppoe_softc * +pppoe_find_softc_by_session(u_int session, struct netif *rcvif) +{ + struct pppoe_softc *sc; + + if (session == 0) { + return NULL; + } + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc->sc_state == PPPOE_STATE_SESSION + && sc->sc_session == session) { + if (sc->sc_ethif == rcvif) { + return sc; + } else { + return NULL; + } + } + } + return NULL; +} + +/* Check host unique token passed and return appropriate softc pointer, + * or NULL if token is bogus. */ +static struct pppoe_softc * +pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) +{ + struct pppoe_softc *sc, *t; + + if (LIST_EMPTY(&pppoe_softc_list)) { + return NULL; + } + + if (len != sizeof sc) { + return NULL; + } + MEMCPY(&t, token, len); + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc == t) { + break; + } + } + + if (sc == NULL) { + PPPDEBUG((LOG_DEBUG, "pppoe: alien host unique tag, no session found\n")); + return NULL; + } + + /* should be safe to access *sc now */ + if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { + printf("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state); + return NULL; + } + if (sc->sc_ethif != rcvif) { + printf("%c%c%"U16_F": wrong interface, not accepting host unique\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + return NULL; + } + return sc; +} + +static void +pppoe_linkstatus_up(void *arg) +{ + struct pppoe_softc *sc = (struct pppoe_softc*)arg; + + sc->sc_linkStatusCB(sc->sc_pd, 1); +} + +/* analyze and handle a single received packet while not in session state */ +static void +pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb) +{ + u16_t tag, len; + u16_t session, plen; + struct pppoe_softc *sc; + const char *err_msg; + char devname[6]; + char *error; + u8_t *ac_cookie; + size_t ac_cookie_len; +#ifdef PPPOE_SERVER + u8_t *hunique; + size_t hunique_len; +#endif + struct pppoehdr *ph; + struct pppoetag pt; + int off, err, errortag; + struct eth_hdr *ethhdr; + + pb = pppSingleBuf(pb); + + strcpy(devname, "pppoe"); /* as long as we don't know which instance */ + err_msg = NULL; + errortag = 0; + if (pb->len < sizeof(*ethhdr)) { + goto done; + } + ethhdr = (struct eth_hdr *)pb->payload; + off = sizeof(*ethhdr); + + ac_cookie = NULL; + ac_cookie_len = 0; +#ifdef PPPOE_SERVER + hunique = NULL; + hunique_len = 0; +#endif + session = 0; + if (pb->len - off < PPPOE_HEADERLEN) { + printf("pppoe: packet too short: %d\n", pb->len); + goto done; + } + + ph = (struct pppoehdr *) (ethhdr + 1); + if (ph->vertype != PPPOE_VERTYPE) { + printf("pppoe: unknown version/type packet: 0x%x\n", ph->vertype); + goto done; + } + session = ntohs(ph->session); + plen = ntohs(ph->plen); + off += sizeof(*ph); + + if (plen + off > pb->len) { + printf("pppoe: packet content does not fit: data available = %d, packet size = %u\n", + pb->len - off, plen); + goto done; + } + if(pb->tot_len == pb->len) { + pb->tot_len = pb->len = off + plen; /* ignore trailing garbage */ + } + tag = 0; + len = 0; + sc = NULL; + while (off + sizeof(pt) <= pb->len) { + MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); + tag = ntohs(pt.tag); + len = ntohs(pt.len); + if (off + sizeof(pt) + len > pb->len) { + printf("pppoe: tag 0x%x len 0x%x is too long\n", tag, len); + goto done; + } + switch (tag) { + case PPPOE_TAG_EOL: + goto breakbreak; + case PPPOE_TAG_SNAME: + break; /* ignored */ + case PPPOE_TAG_ACNAME: + break; /* ignored */ + case PPPOE_TAG_HUNIQUE: + if (sc != NULL) { + break; + } +#ifdef PPPOE_SERVER + hunique = (u8_t*)pb->payload + off + sizeof(pt); + hunique_len = len; +#endif + sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); + if (sc != NULL) { + snprintf(devname, sizeof(devname), "%c%c%"U16_F, sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + } + break; + case PPPOE_TAG_ACCOOKIE: + if (ac_cookie == NULL) { + ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); + ac_cookie_len = len; + } + break; + case PPPOE_TAG_SNAME_ERR: + err_msg = "SERVICE NAME ERROR"; + errortag = 1; + break; + case PPPOE_TAG_ACSYS_ERR: + err_msg = "AC SYSTEM ERROR"; + errortag = 1; + break; + case PPPOE_TAG_GENERIC_ERR: + err_msg = "GENERIC ERROR"; + errortag = 1; + break; + } + if (err_msg) { + error = NULL; + if (errortag && len) { + error = mem_malloc(len+1); + if (error) { + strncpy(error, (char*)pb->payload + off + sizeof(pt), len); + error[len-1] = '\0'; + } + } + if (error) { + printf("%s: %s: %s\n", devname, err_msg, error); + mem_free(error); + } else { + printf("%s: %s\n", devname, err_msg); + } + if (errortag) { + goto done; + } + } + off += sizeof(pt) + len; + } + +breakbreak:; + switch (ph->code) { + case PPPOE_CODE_PADI: +#ifdef PPPOE_SERVER + /* + * got service name, concentrator name, and/or host unique. + * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. + */ + if (LIST_EMPTY(&pppoe_softc_list)) { + goto done; + } + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { + continue; + } + if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + continue; + } + if (sc->sc_state == PPPOE_STATE_INITIAL) { + break; + } + } + if (sc == NULL) { + /* printf("pppoe: free passive interface is not found\n"); */ + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); + sc->sc_state = PPPOE_STATE_PADO_SENT; + pppoe_send_pado(sc); + break; + #endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADR: + #ifdef PPPOE_SERVER + /* + * get sc from ac_cookie if IFF_PASSIVE + */ + if (ac_cookie == NULL) { + /* be quiet if there is not a single pppoe instance */ + printf("pppoe: received PADR but not includes ac_cookie\n"); + goto done; + } + sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (!LIST_EMPTY(&pppoe_softc_list)) { + printf("pppoe: received PADR but could not find request for it\n"); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + printf("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + pppoe_send_pads(sc); + sc->sc_state = PPPOE_STATE_SESSION; + tcpip_timeout (100, pppoe_linkstatus_up, sc); /* notify upper layers */ + break; + #else + /* ignore, we are no access concentrator */ + goto done; + #endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADO: + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (!LIST_EMPTY(&pppoe_softc_list)) { + printf("pppoe: received PADO but could not find request for it\n"); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADI_SENT) { + printf("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + goto done; + } + if (ac_cookie) { + if (sc->sc_ac_cookie) { + mem_free(sc->sc_ac_cookie); + } + sc->sc_ac_cookie = mem_malloc(ac_cookie_len); + if (sc->sc_ac_cookie == NULL) { + goto done; + } + sc->sc_ac_cookie_len = ac_cookie_len; + MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); + } + MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); + tcpip_untimeout(pppoe_timeout, sc); + sc->sc_padr_retried = 0; + sc->sc_state = PPPOE_STATE_PADR_SENT; + if ((err = pppoe_send_padr(sc)) != 0) { + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + case PPPOE_CODE_PADS: + if (sc == NULL) { + goto done; + } + sc->sc_session = session; + tcpip_untimeout(pppoe_timeout, sc); + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); + sc->sc_state = PPPOE_STATE_SESSION; + tcpip_timeout (100, pppoe_linkstatus_up, sc); /* notify upper layers */ + break; + case PPPOE_CODE_PADT: + if (sc == NULL) { + goto done; + } + pppoe_clear_softc(sc, "received PADT"); + break; + default: + if(sc) { + printf("%c%c%"U16_F": unknown code (0x%04x) session = 0x%04x\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + ph->code, session); + } else { + printf("pppoe: unknown code (0x%04x) session = 0x%04x\n", ph->code, session); + } + break; + } + +done: + pbuf_free(pb); + return; +} + +void +pppoe_disc_input(struct netif *netif, struct pbuf *p) +{ + /* avoid error messages if there is not a single pppoe instance */ + if (!LIST_EMPTY(&pppoe_softc_list)) { + pppoe_dispatch_disc_pkt(netif, p); + } else { + pbuf_free(p); + } +} + +void +pppoe_data_input(struct netif *netif, struct pbuf *pb) +{ + u16_t session, plen; + struct pppoe_softc *sc; + struct pppoehdr *ph; +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + u8_t shost[ETHER_ADDR_LEN]; +#endif + +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); +#endif + if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) { + /* bail out */ + PPPDEBUG((LOG_ERR, "pppoe_data_input: pbuf_header failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + pb = pppSingleBuf (pb); + + if (pb->len <= PPPOE_HEADERLEN) { + printf("pppoe (data): dropping too short packet: %d bytes\n", pb->len); + goto drop; + } + + if (pb->len < sizeof(*ph)) { + printf("pppoe_data_input: could not get PPPoE header\n"); + goto drop; + } + ph = (struct pppoehdr *)pb->payload; + + if (ph->vertype != PPPOE_VERTYPE) { + printf("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype); + goto drop; + } + if (ph->code != 0) { + goto drop; + } + + session = ntohs(ph->session); + sc = pppoe_find_softc_by_session(session, netif); + if (sc == NULL) { +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + printf("pppoe: input for unknown session 0x%x, sending PADT\n", session); + pppoe_send_padt(netif, session, shost); +#endif + goto drop; + } + + plen = ntohs(ph->plen); + + if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) { + /* bail out */ + PPPDEBUG((LOG_ERR, "pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + PPPDEBUG((LOG_DEBUG, "pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + pb->len, plen)); + + if (pb->len < plen) { + goto drop; + } + + pppInProcOverEthernet(sc->sc_pd, pb); + + return; + +drop: + pbuf_free(pb); +} + +static err_t +pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) +{ + struct eth_hdr *ethhdr; + u16_t etype; + err_t res; + + if (!sc->sc_ethif) { + pbuf_free(pb); + return ERR_IF; + } + + ethhdr = (struct eth_hdr *)pb->payload; + etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; + ethhdr->type = htons(etype); + MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); + MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr)); + + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, + sc->sc_state, sc->sc_session, + sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], + pb->tot_len)); + + res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); + + pbuf_free(pb); + + return res; +} + +static err_t +pppoe_send_padi(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + int len, l1 = 0, l2 = 0; /* XXX: gcc */ + + if (sc->sc_state >PPPOE_STATE_PADI_SENT) { + PPPDEBUG((LOG_ERR, "ERROR: pppoe_send_padi in state %d", sc->sc_state)); + } + + /* calculate length of frame (excluding ethernet header + pppoe header) */ + len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ + if (sc->sc_service_name != NULL) { + l1 = strlen(sc->sc_service_name); + len += l1; + } + if (sc->sc_concentrator_name != NULL) { + l2 = strlen(sc->sc_concentrator_name); + len += 2 + 2 + l2; + } + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + /* fill in pkt */ + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else { + PPPOE_ADD_16(p, 0); + } + if (sc->sc_concentrator_name != NULL) { + PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); + PPPOE_ADD_16(p, l2); + MEMCPY(p, sc->sc_concentrator_name, l2); + p += l2; + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + /* send pkt */ + return pppoe_output(sc, pb); +} + +static void +pppoe_timeout(void *arg) +{ + int retry_wait, err; + struct pppoe_softc *sc = (struct pppoe_softc*)arg; + + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + + switch (sc->sc_state) { + case PPPOE_STATE_PADI_SENT: + /* + * We have two basic ways of retrying: + * - Quick retry mode: try a few times in short sequence + * - Slow retry mode: we already had a connection successfully + * established and will try infinitely (without user + * intervention) + * We only enter slow retry mode if IFF_LINK1 (aka autodial) + * is not set. + */ + + /* initialize for quick retry mode */ + retry_wait = PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried); + + sc->sc_padi_retried++; + if (sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { +#if 0 + if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { + /* slow retry mode */ + retry_wait = PPPOE_SLOW_RETRY; + } else +#endif + { + pppoe_abort_connect(sc); + return; + } + } + if ((err = pppoe_send_padi(sc)) != 0) { + sc->sc_padi_retried--; + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + tcpip_timeout(retry_wait, pppoe_timeout, sc); + break; + + case PPPOE_STATE_PADR_SENT: + sc->sc_padr_retried++; + if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_state = PPPOE_STATE_PADI_SENT; + sc->sc_padr_retried = 0; + if ((err = pppoe_send_padi(sc)) != 0) { + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); + return; + } + if ((err = pppoe_send_padr(sc)) != 0) { + sc->sc_padr_retried--; + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + case PPPOE_STATE_CLOSING: + pppoe_do_disconnect(sc); + break; + default: + return; /* all done, work in peace */ + } +} + +/* Start a connection (i.e. initiate discovery phase) */ +int +pppoe_connect(struct pppoe_softc *sc) +{ + int err; + + if (sc->sc_state != PPPOE_STATE_INITIAL) { + return EBUSY; + } + +#ifdef PPPOE_SERVER + /* wait PADI if IFF_PASSIVE */ + if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + return 0; + } +#endif + /* save state, in case we fail to send PADI */ + sc->sc_state = PPPOE_STATE_PADI_SENT; + sc->sc_padr_retried = 0; + err = pppoe_send_padi(sc); + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + tcpip_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); + return err; +} + +/* disconnect */ +void +pppoe_disconnect(struct pppoe_softc *sc) +{ + if (sc->sc_state < PPPOE_STATE_SESSION) { + return; + } + /* + * Do not call pppoe_disconnect here, the upper layer state + * machine gets confused by this. We must return from this + * function and defer disconnecting to the timeout handler. + */ + sc->sc_state = PPPOE_STATE_CLOSING; + tcpip_timeout(20, pppoe_timeout, sc); +} + +static int +pppoe_do_disconnect(struct pppoe_softc *sc) +{ + int err; + + if (sc->sc_state < PPPOE_STATE_SESSION) { + err = EBUSY; + } else { + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + } + + /* cleanup softc */ + sc->sc_state = PPPOE_STATE_INITIAL; + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + if (sc->sc_ac_cookie) { + mem_free(sc->sc_ac_cookie); + sc->sc_ac_cookie = NULL; + } + sc->sc_ac_cookie_len = 0; +#ifdef PPPOE_SERVER + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + sc->sc_hunique = NULL; + } + sc->sc_hunique_len = 0; +#endif + sc->sc_session = 0; + + sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ + + return err; +} + +/* Connection attempt aborted */ +static void +pppoe_abort_connect(struct pppoe_softc *sc) +{ + printf("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + sc->sc_state = PPPOE_STATE_CLOSING; + + sc->sc_linkStatusCB(sc->sc_pd, 0); /* notify upper layers */ + + /* clear connection state */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_state = PPPOE_STATE_INITIAL; +} + +/* Send a PADR packet */ +static err_t +pppoe_send_padr(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len, l1 = 0; /* XXX: gcc */ + + if (sc->sc_state != PPPOE_STATE_PADR_SENT) { + return ERR_CONN; + } + + len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } + if (sc->sc_ac_cookie_len > 0) { + len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ + } + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else { + PPPOE_ADD_16(p, 0); + } + if (sc->sc_ac_cookie_len > 0) { + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sc->sc_ac_cookie_len); + MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); + p += sc->sc_ac_cookie_len; + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + return pppoe_output(sc, pb); +} + +/* send a PADT packet */ +static err_t +pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) +{ + struct pbuf *pb; + struct eth_hdr *ethhdr; + err_t res; + u8_t *p; + + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + + ethhdr = (struct eth_hdr *)pb->payload; + ethhdr->type = htons(ETHTYPE_PPPOEDISC); + MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); + MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr)); + + p = (u8_t*)(ethhdr + 1); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); + + res = outgoing_if->linkoutput(outgoing_if, pb); + + pbuf_free(pb); + + return res; +} + +#ifdef PPPOE_SERVER +static err_t +pppoe_send_pado(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len; + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + /* calc length */ + len = 0; + /* include ac_cookie */ + len += 2 + 2 + sizeof(sc); + /* include hunique */ + len += 2 + 2 + sc->sc_hunique_len; + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof(sc)); + p += sizeof(sc); + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} + +static err_t +pppoe_send_pads(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len, l1 = 0; /* XXX: gcc */ + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + sc->sc_session = mono_time.tv_sec % 0xff + 1; + /* calc length */ + len = 0; + /* include hunique */ + len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } + pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + p = (u8_t*)pb->payload + sizeof (struct eth_hdr); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else { + PPPOE_ADD_16(p, 0); + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} +#endif + +err_t +pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) +{ + u8_t *p; + size_t len; + + /* are we ready to process data yet? */ + if (sc->sc_state < PPPOE_STATE_SESSION) { + /*sppp_flush(&sc->sc_sppp.pp_if);*/ + pbuf_free(pb); + return ERR_CONN; + } + + len = pb->tot_len; + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) { + /* bail out */ + PPPDEBUG((LOG_ERR, "pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + + p = (u8_t*)pb->payload + sizeof(struct eth_hdr); + PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); + + return pppoe_output(sc, pb); +} + +#if 0 /*def PFIL_HOOKS*/ +static int +pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) +{ + struct pppoe_softc *sc; + int s; + + if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { + return 0; + } + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc->sc_ethif != ifp) { + continue; + } + if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { + sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); + printf("%c%c%"U16_F": ethernet interface detached, going down\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num); + } + sc->sc_ethif = NULL; + pppoe_clear_softc(sc, "ethernet interface detached"); + } + + return 0; +} +#endif + +static void +pppoe_clear_softc(struct pppoe_softc *sc, const char *message) +{ + LWIP_UNUSED_ARG(message); + + /* stop timer */ + tcpip_untimeout(pppoe_timeout, sc); + PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); + + /* fix our state */ + sc->sc_state = PPPOE_STATE_INITIAL; + + /* notify upper layers */ + sc->sc_linkStatusCB(sc->sc_pd, 0); + + /* clean up softc */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + if (sc->sc_ac_cookie) { + mem_free(sc->sc_ac_cookie); + sc->sc_ac_cookie = NULL; + } + sc->sc_ac_cookie_len = 0; + sc->sc_session = 0; +} + +#endif /* PPPOE_SUPPORT */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pppdebug.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pppdebug.h new file mode 100644 index 0000000..6253863 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/pppdebug.h @@ -0,0 +1,86 @@ +/***************************************************************************** +* pppdebug.h - System debugging utilities. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* portions Copyright (c) 2001 by Cognizant Pty Ltd. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY (please don't use tabs!) +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-07-29 Guy Lancaster , Global Election Systems Inc. +* Original. +* +***************************************************************************** +*/ +#ifndef PPPDEBUG_H +#define PPPDEBUG_H + +/************************ +*** PUBLIC DATA TYPES *** +************************/ +/* Trace levels. */ +typedef enum { +LOG_CRITICAL = 0, +LOG_ERR = 1, +LOG_NOTICE = 2, +LOG_WARNING = 3, +LOG_INFO = 5, +LOG_DETAIL = 6, +LOG_DEBUG = 7 +} LogCodes; + + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ +/* + * ppp_trace - a form of printf to send tracing information to stderr + */ +void ppp_trace(int level, const char *format,...); + +#define TRACELCP PPP_DEBUG + +#if PPP_DEBUG + +#define AUTHDEBUG(a) ppp_trace a +#define IPCPDEBUG(a) ppp_trace a +#define UPAPDEBUG(a) ppp_trace a +#define LCPDEBUG(a) ppp_trace a +#define FSMDEBUG(a) ppp_trace a +#define CHAPDEBUG(a) ppp_trace a +#define PPPDEBUG(a) ppp_trace a + +#else /* PPP_DEBUG */ + +#define AUTHDEBUG(a) +#define IPCPDEBUG(a) +#define UPAPDEBUG(a) +#define LCPDEBUG(a) +#define FSMDEBUG(a) +#define CHAPDEBUG(a) +#define PPPDEBUG(a) + +#endif /* PPP_DEBUG */ + +#endif /* PPPDEBUG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.c new file mode 100644 index 0000000..83c4174 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.c @@ -0,0 +1,249 @@ +/***************************************************************************** +* randm.c - Random number generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-06-03 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "md5.h" +#include "randm.h" + +#include "ppp.h" +#include "pppdebug.h" + +#include + +#if MD5_SUPPORT /* this module depends on MD5 */ +#define RANDPOOLSZ 16 /* Bytes stored in the pool of randomness. */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static char randPool[RANDPOOLSZ]; /* Pool of randomness. */ +static long randCount = 0; /* Pseudo-random incrementer */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Initialize the random number generator. + * + * Since this is to be called on power up, we don't have much + * system randomess to work with. Here all we use is the + * real-time clock. We'll accumulate more randomness as soon + * as things start happening. + */ +void +avRandomInit() +{ + avChurnRand(NULL, 0); +} + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + */ +void +avChurnRand(char *randData, u32_t randLen) +{ + MD5_CTX md5; + + /* ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */ + MD5Init(&md5); + MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); + if (randData) { + MD5Update(&md5, (u_char *)randData, randLen); + } else { + struct { + /* INCLUDE fields for any system sources of randomness */ + char foobar; + } sysData; + + /* Load sysData fields here. */ + MD5Update(&md5, (u_char *)&sysData, sizeof(sysData)); + } + MD5Final((u_char *)randPool, &md5); +/* ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */ +} + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Note: It's important that there be sufficient randomness in randPool + * before this is called for otherwise the range of the result may be + * narrow enough to make a search feasible. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + * + * XXX Why does he not just call churnRand() for each block? Probably + * so that you don't ever publish the seed which could possibly help + * predict future values. + * XXX Why don't we preserve md5 between blocks and just update it with + * randCount each time? Probably there is a weakness but I wish that + * it was documented. + */ +void +avGenRand(char *buf, u32_t bufLen) +{ + MD5_CTX md5; + u_char tmp[16]; + u32_t n; + + while (bufLen > 0) { + n = LWIP_MIN(bufLen, RANDPOOLSZ); + MD5Init(&md5); + MD5Update(&md5, (u_char *)randPool, sizeof(randPool)); + MD5Update(&md5, (u_char *)&randCount, sizeof(randCount)); + MD5Final(tmp, &md5); + randCount++; + MEMCPY(buf, tmp, n); + buf += n; + bufLen -= n; + } +} + +/* + * Return a new random number. + */ +u32_t +avRandom() +{ + u32_t newRand; + + avGenRand((char *)&newRand, sizeof(newRand)); + + return newRand; +} + +#else /* MD5_SUPPORT */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static int avRandomized = 0; /* Set when truely randomized. */ +static u32_t avRandomSeed = 0; /* Seed used for random number generation. */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ +/* + * Initialize the random number generator. + * + * Here we attempt to compute a random number seed but even if + * it isn't random, we'll randomize it later. + * + * The current method uses the fields from the real time clock, + * the idle process counter, the millisecond counter, and the + * hardware timer tick counter. When this is invoked + * in startup(), then the idle counter and timer values may + * repeat after each boot and the real time clock may not be + * operational. Thus we call it again on the first random + * event. + */ +void +avRandomInit() +{ +#if 0 + /* Get a pointer into the last 4 bytes of clockBuf. */ + u32_t *lptr1 = (u32_t *)((char *)&clockBuf[3]); + + /* + * Initialize our seed using the real-time clock, the idle + * counter, the millisecond timer, and the hardware timer + * tick counter. The real-time clock and the hardware + * tick counter are the best sources of randomness but + * since the tick counter is only 16 bit (and truncated + * at that), the idle counter and millisecond timer + * (which may be small values) are added to help + * randomize the lower 16 bits of the seed. + */ + readClk(); + avRandomSeed += *(u32_t *)clockBuf + *lptr1 + OSIdleCtr + + ppp_mtime() + ((u32_t)TM1 << 16) + TM1; +#else + avRandomSeed += sys_jiffies(); /* XXX */ +#endif + + /* Initialize the Borland random number generator. */ + srand((unsigned)avRandomSeed); +} + +/* + * Randomize our random seed value. Here we use the fact that + * this function is called at *truely random* times by the polling + * and network functions. Here we only get 16 bits of new random + * value but we use the previous value to randomize the other 16 + * bits. + */ +void +avRandomize(void) +{ + static u32_t last_jiffies; + + if (!avRandomized) { + avRandomized = !0; + avRandomInit(); + /* The initialization function also updates the seed. */ + } else { + /* avRandomSeed += (avRandomSeed << 16) + TM1; */ + avRandomSeed += (sys_jiffies() - last_jiffies); /* XXX */ + } + last_jiffies = sys_jiffies(); +} + +/* + * Return a new random number. + * Here we use the Borland rand() function to supply a pseudo random + * number which we make truely random by combining it with our own + * seed which is randomized by truely random events. + * Thus the numbers will be truely random unless there have been no + * operator or network events in which case it will be pseudo random + * seeded by the real time clock. + */ +u32_t +avRandom() +{ + return ((((u32_t)rand() << 16) + rand()) + avRandomSeed); +} + +#endif /* MD5_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.h new file mode 100644 index 0000000..a0984b0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/randm.h @@ -0,0 +1,81 @@ +/***************************************************************************** +* randm.h - Random number generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-05-29 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#ifndef RANDM_H +#define RANDM_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ +/* + * Initialize the random number generator. + */ +void avRandomInit(void); + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + */ +void avChurnRand(char *randData, u32_t randLen); + +/* + * Randomize our random seed value. To be called for truely random events + * such as user operations and network traffic. + */ +#if MD5_SUPPORT +#define avRandomize() avChurnRand(NULL, 0) +#else /* MD5_SUPPORT */ +void avRandomize(void); +#endif /* MD5_SUPPORT */ + +/* + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using churnRand(). + * Thus it's important to make sure that the results of this are not + * published directly because one could predict the next result to at + * least some degree. Also, it's important to get a good seed before + * the first use. + */ +void avGenRand(char *buf, u32_t bufLen); + +/* + * Return a new random number. + */ +u32_t avRandom(void); + + +#endif /* RANDM_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.c new file mode 100644 index 0000000..694b702 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.c @@ -0,0 +1,660 @@ +/* + * Routines to compress and uncompess tcp packets (for transmission + * over low speed serial lines. + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * Initial distribution. + * + * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, + * so that the entire packet being decompressed doesn't have + * to be in contiguous memory (just the compressed header). + * + * Modified March 1998 by Guy Lancaster, glanca@gesn.com, + * for a 16 bit processor. + */ + +#include "lwip/opt.h" + +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "ppp.h" +#include "pppdebug.h" + +#include "vj.h" + +#include + +#if VJ_SUPPORT + +#if LINK_STATS +#define INCR(counter) ++comp->stats.counter +#else +#define INCR(counter) +#endif + +#if defined(NO_CHAR_BITFIELDS) +#define getip_hl(base) ((base).ip_hl_v&0xf) +#define getth_off(base) (((base).th_x2_off&0xf0)>>4) +#else +#define getip_hl(base) ((base).ip_hl) +#define getth_off(base) ((base).th_off) +#endif + +void +vj_compress_init(struct vjcompress *comp) +{ + register u_int i; + register struct cstate *tstate = comp->tstate; + +#if MAX_SLOTS == 0 + memset((char *)comp, 0, sizeof(*comp)); +#endif + comp->maxSlotIndex = MAX_SLOTS - 1; + comp->compressSlot = 0; /* Disable slot ID compression by default. */ + for (i = MAX_SLOTS - 1; i > 0; --i) { + tstate[i].cs_id = i; + tstate[i].cs_next = &tstate[i - 1]; + } + tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; + tstate[0].cs_id = 0; + comp->last_cs = &tstate[0]; + comp->last_recv = 255; + comp->last_xmit = 255; + comp->flags = VJF_TOSS; +} + + +/* ENCODE encodes a number that is known to be non-zero. ENCODEZ + * checks for zero (since zero has to be encoded in the long, 3 byte + * form). + */ +#define ENCODE(n) { \ + if ((u_short)(n) >= 256) { \ + *cp++ = 0; \ + cp[1] = (n); \ + cp[0] = (n) >> 8; \ + cp += 2; \ + } else { \ + *cp++ = (n); \ + } \ +} +#define ENCODEZ(n) { \ + if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ + *cp++ = 0; \ + cp[1] = (n); \ + cp[0] = (n) >> 8; \ + cp += 2; \ + } else { \ + *cp++ = (n); \ + } \ +} + +#define DECODEL(f) { \ + if (*cp == 0) {\ + u32_t tmp = ntohl(f) + ((cp[1] << 8) | cp[2]); \ + (f) = htonl(tmp); \ + cp += 3; \ + } else { \ + u32_t tmp = ntohl(f) + (u32_t)*cp++; \ + (f) = htonl(tmp); \ + } \ +} + +#define DECODES(f) { \ + if (*cp == 0) {\ + u_short tmp = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ + (f) = htons(tmp); \ + cp += 3; \ + } else { \ + u_short tmp = ntohs(f) + (u_short)*cp++; \ + (f) = htons(tmp); \ + } \ +} + +#define DECODEU(f) { \ + if (*cp == 0) {\ + (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ + cp += 3; \ + } else { \ + (f) = htons((u_short)*cp++); \ + } \ +} + +/* + * vj_compress_tcp - Attempt to do Van Jacobson header compression on a + * packet. This assumes that nb and comp are not null and that the first + * buffer of the chain contains a valid IP header. + * Return the VJ type code indicating whether or not the packet was + * compressed. + */ +u_int +vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) +{ + register struct ip *ip = (struct ip *)pb->payload; + register struct cstate *cs = comp->last_cs->cs_next; + register u_short hlen = getip_hl(*ip); + register struct tcphdr *oth; + register struct tcphdr *th; + register u_short deltaS, deltaA; + register u_long deltaL; + register u_int changes = 0; + u_char new_seq[16]; + register u_char *cp = new_seq; + + /* + * Check that the packet is IP proto TCP. + */ + if (ip->ip_p != IPPROTO_TCP) { + return (TYPE_IP); + } + + /* + * Bail if this is an IP fragment or if the TCP packet isn't + * `compressible' (i.e., ACK isn't set or some other control bit is + * set). + */ + if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40) { + return (TYPE_IP); + } + th = (struct tcphdr *)&((long *)ip)[hlen]; + if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { + return (TYPE_IP); + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need + * to locate (or create) the connection state. Special case the + * most recently used connection since it's most likely to be used + * again & we don't have to do any reordering if it's used. + */ + INCR(vjs_packets); + if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr + || ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr + || *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) { + /* + * Wasn't the first -- search for it. + * + * States are kept in a circularly linked list with + * last_cs pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + register struct cstate *lcs; + register struct cstate *lastcs = comp->last_cs; + + do { + lcs = cs; cs = cs->cs_next; + INCR(vjs_searches); + if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr + && ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr + && *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) { + goto found; + } + } while (cs != lastcs); + + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * last_cs to update the lru linkage. + */ + INCR(vjs_misses); + comp->last_cs = lcs; + hlen += getth_off(*th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + return (TYPE_IP); + } + goto uncompressed; + + found: + /* + * Found it -- move to the front on the connection list. + */ + if (cs == lastcs) { + comp->last_cs = lcs; + } else { + lcs->cs_next = cs->cs_next; + cs->cs_next = lastcs->cs_next; + lastcs->cs_next = cs; + } + } + + oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen]; + deltaS = hlen; + hlen += getth_off(*th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", hlen)); + return (TYPE_IP); + } + + /* + * Make sure that only what we expect to change changed. The first + * line of the `if' checks the IP protocol version, header length & + * type of service. The 2nd line checks the "Don't fragment" bit. + * The 3rd line checks the time-to-live and protocol (the protocol + * check is unnecessary but costless). The 4th line checks the TCP + * header length. The 5th line checks IP options, if any. The 6th + * line checks TCP options, if any. If any of these things are + * different between the previous & current datagram, we send the + * current datagram `uncompressed'. + */ + if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] + || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] + || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] + || getth_off(*th) != getth_off(*oth) + || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) + || (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2))) { + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if (th->th_flags & TCP_URG) { + deltaS = ntohs(th->th_urp); + ENCODEZ(deltaS); + changes |= NEW_U; + } else if (th->th_urp != oth->th_urp) { + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + + if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) { + ENCODE(deltaS); + changes |= NEW_W; + } + + if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaA = (u_short)deltaL; + ENCODE(deltaA); + changes |= NEW_A; + } + + if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaS = (u_short)deltaL; + ENCODE(deltaS); + changes |= NEW_S; + } + + switch(changes) { + case 0: + /* + * Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if (ip->ip_len != cs->cs_ip.ip_len && + ntohs(cs->cs_ip.ip_len) == hlen) { + break; + } + + /* (fall through) */ + + case SPECIAL_I: + case SPECIAL_D: + /* + * actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + + case NEW_S|NEW_A: + if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + + case NEW_S: + if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) { + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + } + + deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id)); + if (deltaS != 1) { + ENCODEZ(deltaS); + changes |= NEW_I; + } + if (th->th_flags & TCP_PSH) { + changes |= TCP_PUSH_BIT; + } + /* + * Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + deltaA = ntohs(th->th_sum); + BCOPY(ip, &cs->cs_ip, hlen); + + /* + * We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how + * many bytes of the original packet to toss so subtract the two to + * get the new packet size. + */ + deltaS = (u_short)(cp - new_seq); + if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { + comp->last_xmit = cs->cs_id; + hlen -= deltaS + 4; + if(pbuf_header(pb, -hlen)){ + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = changes | NEW_C; + *cp++ = cs->cs_id; + } else { + hlen -= deltaS + 3; + if(pbuf_header(pb, -hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = changes; + } + *cp++ = deltaA >> 8; + *cp++ = deltaA; + BCOPY(new_seq, cp, deltaS); + INCR(vjs_compressed); + return (TYPE_COMPRESSED_TCP); + + /* + * Update connection state cs & send uncompressed packet (that is, + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + BCOPY(ip, &cs->cs_ip, hlen); + ip->ip_p = cs->cs_id; + comp->last_xmit = cs->cs_id; + return (TYPE_UNCOMPRESSED_TCP); +} + +/* + * Called when we may have missed a packet. + */ +void +vj_uncompress_err(struct vjcompress *comp) +{ + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); +} + +/* + * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. + * Return 0 on success, -1 on failure. + */ +int +vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) +{ + register u_int hlen; + register struct cstate *cs; + register struct ip *ip; + + ip = (struct ip *)nb->payload; + hlen = getip_hl(*ip) << 2; + if (ip->ip_p >= MAX_SLOTS + || hlen + sizeof(struct tcphdr) > nb->len + || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2) + > nb->len + || hlen > MAX_HDR) { + PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", + ip->ip_p, hlen, nb->len)); + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return -1; + } + cs = &comp->rstate[comp->last_recv = ip->ip_p]; + comp->flags &=~ VJF_TOSS; + ip->ip_p = IPPROTO_TCP; + BCOPY(ip, &cs->cs_ip, hlen); + cs->cs_hlen = hlen; + INCR(vjs_uncompressedin); + return 0; +} + +/* + * Uncompress a packet of type TYPE_COMPRESSED_TCP. + * The packet is composed of a buffer chain and the first buffer + * must contain an accurate chain length. + * The first buffer must include the entire compressed TCP/IP header. + * This procedure replaces the compressed header with the uncompressed + * header and returns the length of the VJ header. + */ +int +vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) +{ + u_char *cp; + struct tcphdr *th; + struct cstate *cs; + u_short *bp; + struct pbuf *n0 = *nb; + u32_t tmp; + u_int vjlen, hlen, changes; + + INCR(vjs_compressedin); + cp = (u_char *)n0->payload; + changes = *cp++; + if (changes & NEW_C) { + /* + * Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + if (*cp >= MAX_SLOTS) { + PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp)); + goto bad; + } + + comp->flags &=~ VJF_TOSS; + comp->last_recv = *cp++; + } else { + /* + * this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. + */ + if (comp->flags & VJF_TOSS) { + PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n")); + INCR(vjs_tossed); + return (-1); + } + } + cs = &comp->rstate[comp->last_recv]; + hlen = getip_hl(cs->cs_ip) << 2; + th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen]; + th->th_sum = htons((*cp << 8) | cp[1]); + cp += 2; + if (changes & TCP_PUSH_BIT) { + th->th_flags |= TCP_PSH; + } else { + th->th_flags &=~ TCP_PSH; + } + + switch (changes & SPECIALS_MASK) { + case SPECIAL_I: + { + register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->th_ack) + i; + th->th_ack = htonl(tmp); + tmp = ntohl(th->th_seq) + i; + th->th_seq = htonl(tmp); + } + break; + + case SPECIAL_D: + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen; + th->th_seq = htonl(tmp); + break; + + default: + if (changes & NEW_U) { + th->th_flags |= TCP_URG; + DECODEU(th->th_urp); + } else { + th->th_flags &=~ TCP_URG; + } + if (changes & NEW_W) { + DECODES(th->th_win); + } + if (changes & NEW_A) { + DECODEL(th->th_ack); + } + if (changes & NEW_S) { + DECODEL(th->th_seq); + } + break; + } + if (changes & NEW_I) { + DECODES(cs->cs_ip.ip_id); + } else { + cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1; + cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id); + } + + /* + * At this point, cp points to the first byte of data in the + * packet. Fill in the IP total length and update the IP + * header checksum. + */ + vjlen = (u_short)(cp - (u_char*)n0->payload); + if (n0->len < vjlen) { + /* + * We must have dropped some characters (crc should detect + * this but the old slip framing won't) + */ + PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n", + n0->len, vjlen)); + goto bad; + } + +#if BYTE_ORDER == LITTLE_ENDIAN + tmp = n0->tot_len - vjlen + cs->cs_hlen; + cs->cs_ip.ip_len = htons(tmp); +#else + cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen); +#endif + + /* recompute the ip header checksum */ + bp = (u_short *) &cs->cs_ip; + cs->cs_ip.ip_sum = 0; + for (tmp = 0; hlen > 0; hlen -= 2) { + tmp += *bp++; + } + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + cs->cs_ip.ip_sum = (u_short)(~tmp); + + /* Remove the compressed header and prepend the uncompressed header. */ + if(pbuf_header(n0, -((s16_t)(vjlen)))) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { + struct pbuf *np, *q; + u8_t *bufptr; + + np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n")); + goto bad; + } + + if(pbuf_header(np, -cs->cs_hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + bufptr = n0->payload; + for(q = np; q != NULL; q = q->next) { + MEMCPY(q->payload, bufptr, q->len); + bufptr += q->len; + } + + if(n0->next) { + pbuf_chain(np, n0->next); + pbuf_dechain(n0); + } + pbuf_free(n0); + n0 = np; + } + + if(pbuf_header(n0, cs->cs_hlen)) { + struct pbuf *np; + + LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); + np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n")); + goto bad; + } + pbuf_cat(np, n0); + n0 = np; + } + LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); + MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); + + *nb = n0; + + return vjlen; + +bad: + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return (-1); +} + +#endif /* VJ_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.h new file mode 100644 index 0000000..b9617da --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vj.h @@ -0,0 +1,155 @@ +/* + * Definitions for tcp compression routines. + * + * $Id: vj.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +#ifndef VJ_H +#define VJ_H + +#include "vjbsdhdr.h" + +#define MAX_SLOTS 16 /* must be > 2 and < 256 */ +#define MAX_HDR 128 + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + struct cstate *cs_next; /* next most recently used state (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip csu_ip; /* ip/tcp hdr from most recent packet */ + } vjcs_u; +}; +#define cs_ip vjcs_u.csu_ip +#define cs_hdr vjcs_u.csu_hdr + + +struct vjstat { + unsigned long vjs_packets; /* outbound packets */ + unsigned long vjs_compressed; /* outbound compressed packets */ + unsigned long vjs_searches; /* searches for connection state */ + unsigned long vjs_misses; /* times couldn't find conn. state */ + unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned long vjs_compressedin; /* inbound compressed packets */ + unsigned long vjs_errorin; /* inbound unknown type packets */ + unsigned long vjs_tossed; /* inbound packets tossed because of error */ +}; + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct vjcompress { + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; + u_char maxSlotIndex; + u_char compressSlot; /* Flag indicating OK to compress slot ID. */ +#if LINK_STATS + struct vjstat stats; +#endif + struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ + struct cstate rstate[MAX_SLOTS]; /* receive connection states */ +}; + +/* flag values */ +#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ + +extern void vj_compress_init (struct vjcompress *comp); +extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); +extern void vj_uncompress_err (struct vjcompress *comp); +extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); +extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); + +#endif /* VJ_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vjbsdhdr.h b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vjbsdhdr.h new file mode 100644 index 0000000..f462676 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/ppp/vjbsdhdr.h @@ -0,0 +1,75 @@ +#ifndef VJBSDHDR_H +#define VJBSDHDR_H + +#include "lwip/tcp.h" + +/* + * Structure of an internet header, naked of options. + * + * We declare ip_len and ip_off to be short, rather than u_short + * pragmatically since otherwise unsigned comparisons can result + * against negative integers quite easily, and fail in subtle ways. + */ +PACK_STRUCT_BEGIN +struct ip +{ +#if defined(NO_CHAR_BITFIELDS) + u_char ip_hl_v; /* bug in GCC for mips means the bitfield stuff will sometimes break - so we use a char for both and get round it with macro's instead... */ +#else +#if BYTE_ORDER == LITTLE_ENDIAN + unsigned ip_hl:4, /* header length */ + ip_v :4; /* version */ +#elif BYTE_ORDER == BIG_ENDIAN + unsigned ip_v :4, /* version */ + ip_hl:4; /* header length */ +#else + COMPLAIN - NO BYTE ORDER SELECTED! +#endif +#endif + u_char ip_tos; /* type of service */ + u_short ip_len; /* total length */ + u_short ip_id; /* identification */ + u_short ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; +PACK_STRUCT_END + +typedef u32_t tcp_seq; + +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +PACK_STRUCT_BEGIN +struct tcphdr +{ + u_short th_sport; /* source port */ + u_short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +#if defined(NO_CHAR_BITFIELDS) + u_char th_x2_off; +#else +#if BYTE_ORDER == LITTLE_ENDIAN + unsigned th_x2 :4, /* (unused) */ + th_off:4; /* data offset */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + unsigned th_off:4, /* data offset */ + th_x2 :4; /* (unused) */ +#endif +#endif + u_char th_flags; + u_short th_win; /* window */ + u_short th_sum; /* checksum */ + u_short th_urp; /* urgent pointer */ +}; +PACK_STRUCT_END + +#endif /* VJBSDHDR_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/slipif.c b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/slipif.c new file mode 100644 index 0000000..089d2d3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.3.2/src/netif/slipif.c @@ -0,0 +1,367 @@ +/** + * @file + * SLIP Interface + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is built upon the file: src/arch/rtxc/netif/sioslip.c + * + * Author: Magnus Ivarsson + */ + +/* + * This is an arch independent SLIP netif. The specific serial hooks must be + * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send + */ + +#include "netif/slipif.h" +#include "lwip/opt.h" + +#if LWIP_HAVE_SLIPIF + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/sio.h" + +#define SLIP_BLOCK 1 +#define SLIP_DONTBLOCK 0 + +#define SLIP_END 0300 /* 0xC0 */ +#define SLIP_ESC 0333 /* 0xDB */ +#define SLIP_ESC_END 0334 /* 0xDC */ +#define SLIP_ESC_ESC 0335 /* 0xDD */ + +#define SLIP_MAX_SIZE 1500 + +enum slipif_recv_state { + SLIP_RECV_NORMAL, + SLIP_RECV_ESCAPE, +}; + +struct slipif_priv { + sio_fd_t sd; + /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ + struct pbuf *p, *q; + enum slipif_recv_state state; + u16_t i, recved; +}; + +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chaing packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +err_t +slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) +{ + struct slipif_priv *priv; + struct pbuf *q; + u16_t i; + u8_t c; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + LWIP_ASSERT("p != NULL", (p != NULL)); + + LWIP_UNUSED_ARG(ipaddr); + + priv = netif->state; + + /* Send pbuf out on the serial I/O device. */ + sio_send(SLIP_END, priv->sd); + + for (q = p; q != NULL; q = q->next) { + for (i = 0; i < q->len; i++) { + c = ((u8_t *)q->payload)[i]; + switch (c) { + case SLIP_END: + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_END, priv->sd); + break; + case SLIP_ESC: + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_ESC, priv->sd); + break; + default: + sio_send(c, priv->sd); + break; + } + } + } + sio_send(SLIP_END, priv->sd); + return ERR_OK; +} + +/** + * Static function for easy use of blockig or non-blocking + * sio_read + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @param block if 1, call sio_read; if 0, call sio_tryread + * @return return value of sio_read of sio_tryread + */ +static u32_t +slip_sio_read(sio_fd_t fd, u8_t* data, u32_t len, u8_t block) +{ + if (block) { + return sio_read(fd, data, len); + } else { + return sio_tryread(fd, data, len); + } +} + +/** + * Handle the incoming SLIP stream character by character + * + * Poll the serial layer by calling sio_read() or sio_tryread(). + * + * @param netif the lwip network interface structure for this slipif + * @param block if 1, block until data is received; if 0, return when all data + * from the buffer is received (multiple calls to this function will + * return a complete packet, NULL is returned before - used for polling) + * @return The IP packet when SLIP_END is received + */ +static struct pbuf * +slipif_input(struct netif *netif, u8_t block) +{ + struct slipif_priv *priv; + u8_t c; + struct pbuf *t; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = netif->state; + + while (slip_sio_read(priv->sd, &c, 1, block) > 0) { + switch (priv->state) { + case SLIP_RECV_NORMAL: + switch (c) { + case SLIP_END: + if (priv->recved > 0) { + /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ + pbuf_realloc(priv->q, priv->recved); + + LINK_STATS_INC(link.recv); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet\n")); + t = priv->q; + priv->p = priv->q = NULL; + priv->i = priv->recved = 0; + return t; + } + continue; + case SLIP_ESC: + priv->state = SLIP_RECV_ESCAPE; + continue; + } + break; + case SLIP_RECV_ESCAPE: + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + priv->state = SLIP_RECV_NORMAL; + /* FALLTHROUGH */ + } + + /* byte received, packet not yet completely received */ + if (priv->p == NULL) { + /* allocate a new pbuf */ + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); + priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); + + if (priv->p == NULL) { + LINK_STATS_INC(link.drop); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + break; + } + + if (priv->q != NULL) { + /* 'chain' the pbuf to the existing chain */ + pbuf_cat(priv->q, priv->p); + } else { + /* p is the first pbuf in the chain */ + priv->q = priv->p; + } + } + + /* this automatically drops bytes if > SLIP_MAX_SIZE */ + if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { + ((u8_t *)priv->p->payload)[priv->i] = c; + priv->recved++; + priv->i++; + if (priv->i >= priv->p->len) { + /* on to the next pbuf */ + priv->i = 0; + if (priv->p->next != NULL && priv->p->next->len > 0) { + /* p is a chain, on to the next in the chain */ + priv->p = priv->p->next; + } else { + /* p is a single pbuf, set it to NULL so next time a new + * pbuf is allocated */ + priv->p = NULL; + } + } + } + } + + return NULL; +} + +#if !NO_SYS +/** + * The SLIP input thread. + * + * Feed the IP layer with incoming packets + * + * @param nf the lwip network interface structure for this slipif + */ +static void +slipif_loop_thread(void *nf) +{ + struct pbuf *p; + struct netif *netif = (struct netif *)nf; + + while (1) { + p = slipif_input(netif, SLIP_BLOCK); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } +} +#endif /* !NO_SYS */ + +/** + * SLIP netif initialization + * + * Call the arch specific sio_open and remember + * the opened device in the state field of the netif. + * + * @param netif the lwip network interface structure for this slipif + * @return ERR_OK if serial line could be opened, + * ERR_MEM if no memory could be allocated, + * ERR_IF is serial line couldn't be opened + * + * @note netif->num must contain the number of the serial port to open + * (0 by default) + */ +err_t +slipif_init(struct netif *netif) +{ + struct slipif_priv *priv; + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); + + /* Allocate private data */ + priv = mem_malloc(sizeof(struct slipif_priv)); + if (!priv) { + return ERR_MEM; + } + + netif->name[0] = 's'; + netif->name[1] = 'l'; + netif->output = slipif_output; + netif->mtu = SLIP_MAX_SIZE; + netif->flags |= NETIF_FLAG_POINTTOPOINT; + + /* Try to open the serial port (netif->num contains the port number). */ + priv->sd = sio_open(netif->num); + if (!priv->sd) { + /* Opening the serial port failed. */ + mem_free(priv); + return ERR_IF; + } + + /* Initialize private data */ + priv->p = NULL; + priv->q = NULL; + priv->state = SLIP_RECV_NORMAL; + priv->i = 0; + priv->recved = 0; + + netif->state = priv; + + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made without knowing more about the + * serial line! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_slip, 0); + + /* Create a thread to poll the serial line. */ + sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, + SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); + return ERR_OK; +} + +/** + * Polls the serial device and feeds the IP layer with incoming packets. + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_poll(struct netif *netif) +{ + struct pbuf *p; + struct slipif_priv *priv; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = netif->state; + + while ((p = slipif_input(netif, SLIP_DONTBLOCK)) != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } +} + +#endif /* LWIP_HAVE_SLIPIF */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/CHANGELOG b/USDK/component/common/network/lwip/lwip_v1.4.1/CHANGELOG new file mode 100644 index 0000000..af68299 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/CHANGELOG @@ -0,0 +1,3349 @@ +HISTORY + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ New features: + + + ++ Bugfixes: + + + + +(STABLE-1.4.1) + + ++ New features: + + 2012-03-25: Simon Goldschmidt (idea by Mason) + * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h + which are a simple wrapper to the correct lwIP include files. + + 2012-01-16: Simon Goldschmidt + * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP + + 2011-12-17: Simon Goldschmidt + * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) + (fixes bug #35061) + + 2011-09-27: Simon Goldschmidt + * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) + (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) + + 2011-09-21: Simon Goldschmidt + * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on + send (TCP only, bug #33820) + + 2011-09-21: Simon Goldschmidt + * init.c: Converted runtime-sanity-checks into compile-time checks that can + be disabled (since runtime checks can often not be seen on embedded targets) + + 2011-09-11: Simon Goldschmidt + * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file + to get a clear separation of which functions an application or port may use + (task #11281) + + 2011-09-11: Simon Goldschmidt + * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize + initial local TCP/UDP ports (so that different port ranges are used after + a reboot; bug #33818; this one added tcp_init/udp_init functions again) + + 2011-09-03: Simon Goldschmidt + * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) + + 2011-08-24: Simon Goldschmidt + * opt.h, netif.h/.c: added netif remove callback (bug #32397) + + 2011-07-26: Simon Goldschmidt + * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter + function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) + + 2011-07-21: Simon Goldschmidt (patch by hanhui) + * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: + Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. + Also added code to allow ip_forward() to forward non-broadcast packets to + the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). + + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) + * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that + pcb->state != LISTEN + + 2011-05-14: Simon Goldschmidt (patch by Stphane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + + + ++ Bugfixes: + + 2012-09-26: Simon Goldschmidt + * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7843 Fix corner case with dhcp timeouts + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-05-08: Simon Goldschmidt + * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was + a debug-check issue only) + + 2012-03-27: Simon Goldschmidt + * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c + + 2012-03-27: Simon Goldschmidt (patch by Mason) + * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the + send MSS + + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + + 2012-03-20: Simon Goldschmidt (patch by Mason) + * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list + + 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) + * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, + possible bug on little endian system + + 2012-02-23: Simon Goldschmidt + * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt + * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() + (bug #35541: PPP Memory Leak) + + 2012-02-16: Simon Goldschmidt + * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt (patch by Stphane Lesage) + * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed + + 2012-02-15: Simon Goldschmidt + * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with + MEMP_MEM_MALLOC==1 + + 2012-02-12: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on + MSS > pcb->snd_wnd (by not creating segments bigger than half the window) + + 2012-02-11: Simon Goldschmidt + * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait + queue while closing + + 2012-01-22: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) + + 2012-01-21: Simon Goldschmidt + * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb + + 2012-01-20: Simon Goldschmidt + * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths + + 2012-01-20: Simon Goldschmidt + * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy + + 2011-11-25: Simon Goldschmidt + * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt + tcp_active_pcbs in some cases + + 2011-11-23: Simon Goldschmidt + * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with + '#ifndef sys_msleep' + + 2011-11-22: Simon Goldschmidt + * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when + netif is brought down + + 2011-10-28: Simon Goldschmidt + * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks + + 2011-10-23: Simon Goldschmidt + * mem.c: fixed bug #34429: possible memory corruption with + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 + + 2011-10-18: Simon Goldschmidt + * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard + error value + + 2011-10-18: Simon Goldschmidt + * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small + windows (bug #34176 select after non-blocking send times out) + + 2011-10-18: Simon Goldschmidt + * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't + consider netif->mtu, causes slow network + + 2011-10-18: Simon Goldschmidt + * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code + + 2011-10-18: Simon Goldschmidt + * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS + + 2011-10-17: Simon Goldschmidt + * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api + + 2011-10-13: Simon Goldschmidt + * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no + zero window is received) by starting the persist timer when a zero window is + received, not when we have more data queued for sending than fits into the + window + + 2011-10-13: Simon Goldschmidt + * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex + + 2011-10-13: Simon Goldschmidt + * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is + used and not all protocols are enabled + + 2011-10-12: Simon Goldschmidt + * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 + + 2011-10-09: Simon Goldschmidt + * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect + byte value when pcb->unacked != NULL + + 2011-10-09: Simon Goldschmidt + * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong + + 2011-09-27: Simon Goldschmidt + * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... + + 2011-09-27: Simon Goldschmidt + * tcp_in.c: fixed bug #28288: Data after FIN in oos queue + + 2011-09-27: Simon Goldschmidt + * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf + + 2011-09-24: Simon Goldschmidt + * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 + + 2011-09-23: Simon Goldschmidt + * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for + the last packet including FIN can lose data + + 2011-09-22: Simon Goldschmidt + * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into + account + + 2011-09-21: Simon Goldschmidt + * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks + in init.c + + 2011-09-20: Simon Goldschmidt + * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) + + 2011-09-11: Simon Goldschmidt + * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs + (bug #34019) + + 2011-09-09: Simon Goldschmidt + * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if + udp port matches + + 2011-09-03: Simon Goldschmidt + * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet + is aggregated and sent to application + + 2011-09-01: Simon Goldschmidt + * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared + to other options + + 2011-09-01: Simon Goldschmidt + * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno + + 2011-08-24: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling + accept() on UDP connections + + 2011-08-24: Simon Goldschmidt + * sockets.h: fixed bug #34057 socklen_t should be a typedef + + 2011-08-24: Simon Goldschmidt + * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) + + 2011-08-24: Simon Goldschmidt + * dhcp.c: fixed bug #34122 dhcp: hostname can overflow + + 2011-08-24: Simon Goldschmidt + * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr + + 2011-08-22: Simon Goldschmidt + * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This + merely prevents nagle from not transmitting fast after closing.) + + 2011-07-22: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns + always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now + lwip_send() sends as much as possible for non-blocking sockets + + 2011-07-22: Simon Goldschmidt + * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented + for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level. + + 2011-07-21: Simon Goldschmidt + * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by + sending an ARP request when an ARP entry is used in the last minute before + it would time out. + + 2011-07-04: Simon Goldschmidt + * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. + + 2011-06-26: Simon Goldschmidt + * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by + updating its documentation only. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an + unaligned pointer. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" + + 2011-05-25: Simon Goldschmidt + * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) + + + +(STABLE-1.4.0) + + ++ New features: + + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + + 2010-11-21: Simon Goldschmidt + * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif + (fixes bug #31525). + + 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) + * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for + IP_MULTICAST_LOOP at socket- and raw-API level. + + 2010-06-16: Simon Goldschmidt + * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow + link-layer-addressed UDP traffic to be received while a netif is down (just + like DHCP during configuration) + + 2010-05-22: Simon Goldschmidt + * many many files: bug #27352: removed packing from ip_addr_t, the packed + version is now only used in protocol headers. Added global storage for + current src/dest IP address while in input functions. + + 2010-05-16: Simon Goldschmidt + * def.h: task #10391: Add preprocessor-macros for compile-time htonl + calculation (and use them throughout the stack where applicable) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool + instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own + MEMP pool instead of the heap + + 2010-05-13: Simon Goldschmidt + * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added + new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast + packets to more than one pcb. + + 2010-05-02: Simon Goldschmidt + * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending + UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-04-30: Simon Goldschmidt + * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that + take a precalculated checksum, added pbuf_fill_chksum() to copy data + into a pbuf and at the same time calculating the checksum for that data + + 2010-04-29: Simon Goldschmidt + * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying + 2-byte-aligned IP addresses and MAC addresses + + 2010-04-28: Patch by Bill Auerbach + * ip.c: Inline generating IP checksum to save a function call + + 2010-04-14: Simon Goldschmidt + * tcpip.h/.c, timers.c: Added an overridable define to get informed when the + tcpip_thread processes messages or timeouts to implement a watchdog. + + 2010-03-28: Simon Goldschmidt + * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing + fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-03-27: Simon Goldschmidt + * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ + etharp_query to prevent unnecessary function calls (inspired by + patch #7135). + + 2010-03-20: Simon Goldschmidt + * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code + since the linker cannot do this automatically to save space. + + 2010-03-20: Simon Goldschmidt + * opt.h, etharp.c/.h: Added support for static ARP table entries + + 2010-03-14: Simon Goldschmidt + * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum + when creating TCP segments, not when (re-)transmitting them. + + 2010-03-07: Simon Goldschmidt + * sockets.c: bug #28775 (select/event_callback: only check select_cb_list + on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. + This should speed up receiving data on sockets as the select code in + event_callback is only executed when select is waiting. + + 2010-03-06: Simon Goldschmidt + * tcp_out.c: task #7013 (Create option to have all packets delivered to + netif->output in one piece): Always copy to try to create single pbufs + in tcp_write. + + 2010-03-06: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv + by not allocating a netbuf): added function netconn_recv_tcp_pbuf() + for tcp netconns to receive pbufs, not netbufs; use that function + for tcp sockets. + + 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt + * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: + Work on tcp_enqueue: Don't waste memory when chaining segments, + added option TCP_OVERSIZE to prevent creating many small pbufs when + calling tcp_write with many small blocks of data. Instead, pbufs are + allocated larger than needed and the space is used for later calls to + tcp_write. + + 2010-02-21: Simon Goldschmidt + * stats.c/.h: Added const char* name to mem- and memp-stats for easier + debugging. + + 2010-02-21: Simon Goldschmidt + * tcp.h (and usages), added tcp_impl.h: Splitted API and internal + implementation of tcp to make API usage cleare to application programmers + + 2010-02-14: Simon Goldschmidt/Stephane Lesage + * ip_addr.h: Improved some defines working on ip addresses, added faster + macro to copy addresses that cannot be NULL + + 2010-02-13: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- + blocking send operation) + + 2010-02-12: Simon Goldschmidt + * sockets.c/.h: Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + 2010-02-12: Simon Goldschmidt + * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated + memory): added autoip_set_struct() and dhcp_set_struct() to let autoip + and dhcp work with user-allocated structs instead of callin mem_malloc + + 2010-02-12: Simon Goldschmidt/Jeff Barber + * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has + SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT + + 2010-02-12: Simon Goldschmidt + * sys layer: task #10139 (Prefer statically allocated memory): converted + mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; + converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX + to let sys.h use binary semaphores instead of mutexes - as before) + + 2010-02-09: Simon Goldschmidt (Simon Kallweit) + * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 + (Restart system timeout handling) + + 2010-02-09: Simon Goldschmidt + * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into + netif.c) - loopif does not have to be created by the port any more, + just define LWIP_HAVE_LOOPIF to 1. + + 2010-02-08: Simon Goldschmidt + * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa + inet_ntoa_r/ipaddr_ntoa_r + + 2010-02-08: Simon Goldschmidt + * netif.h: Added netif_s/get_igmp_mac_filter() macros + + 2010-02-05: Simon Goldschmidt + * netif.h: Added function-like macros to get/set the hostname on a netif + + 2010-02-04: Simon Goldschmidt + * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to + make changing the actual implementation behind the typedef easier. + + 2010-02-01: Simon Goldschmidt + * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool + for allocating memory when getaddrinfo() is called. + + 2010-01-31: Simon Goldschmidt + * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse + them once instead of parsing for every option. This also removes + the need for mem_malloc from dhcp_recv and makes it possible to + correctly retrieve the BOOTP file. + + 2010-01-30: simon Goldschmidt + * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect + the sockets array. + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, api_msg.c, sockets.c: Added except set support in select + (patch #6860) + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: + Add non-blocking support for connect (partly from patch #6860), + plus many cleanups in socket & netconn API. + + 2010-01-27: Simon Goldschmidt + * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding + to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 + + 2010-01-26: Simon Goldschmidt + * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. + + 2010-01-14: Simon Goldschmidt + * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback + by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() + + 2010-01-13: Simon Goldschmidt + * mem.c: The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + (patch #6966 and bug #26133) + + 2010-01-10: Simon Goldschmidt (Bill Auerbach) + * opt.h, memp.c: patch #6822 (Add option to place memory pools in + separate arrays) + + 2010-01-10: Simon Goldschmidt + * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define + LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) + + 2009-12-31: Simon Goldschmidt + * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h + added timers.c/.h: Separated timer implementation from semaphore/mbox + implementation, moved timer implementation to timers.c/.h, timers are + now only called from tcpip_thread or by explicitly checking them. + (TASK#7235) + + 2009-12-27: Simon Goldschmidt + * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option + LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) + + + ++ Bugfixes: + + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + + 2011-01-24: Simon Goldschmidt + * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems + + 2010-12-02: Simon Goldschmidt + * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. + + 2010-11-23: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for + LWIP_SO_RCVBUF and ioctl/FIONREAD. + + 2010-11-23: Simon Goldschmidt + * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at + least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. + + 2010-11-23: Simon Goldschmidt + * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after + refusing 'refused_data' again. + + 2010-11-22: Simon Goldschmidt + * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS + after a successful nonblocking connection. + + 2010-11-22: Simon Goldschmidt + * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr + must be sent link-local + + 2010-11-22: Simon Goldschmidt + * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for + LWIP_TIMERS==0 + + 2010-11-20: Simon Goldschmidt + * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number + + 2010-11-20: Simon Goldschmidt + * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to + resemble other stacks. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else + no-copy TCP writes will never succeed. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does + not match documentation: return ERR_ARG instead of ERR_VAL if not + initialized or wrong argument. + + 2010-10-20: Simon Goldschmidt + * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 + + 2010-10-05: Simon Goldschmidt + * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when + replugging the network cable after an AutoIP address was assigned. + + 2010-08-10: Simon Goldschmidt + * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs + + 2010-08-03: Simon Goldschmidt + * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) + + 2010-08-01: Simon Goldschmidt (patch by Greg Renda) + * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big + endian architectures) + + 2010-07-28: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP + disabled. + + 2010-07-27: Simon Goldschmidt + * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no + harm but never did anything + + 2010-07-21: Simon Goldschmidt + * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not + add IP options) + + 2010-07-16: Kieran Mansley + * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator + + 2010-07-10: Simon Goldschmidt + * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options + + 2010-06-30: Simon Goldschmidt + * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in + netconn_delete) + + 2010-06-28: Kieran Mansley + * timers.c remove unportable printing of C function pointers + + 2010-06-24: Simon Goldschmidt + * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag + NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading + + 2010-06-24: Simon Goldschmidt + * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly + implemented shutdown at socket level. + + 2010-06-21: Simon Goldschmidt + * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has + problems with zero-copy DMA MACs) by adding custom pbufs and implementing + custom pbufs that reference other (original) pbufs. Additionally set + IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. + + 2010-06-15: Simon Goldschmidt + * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses + + 2010-06-14: Simon Goldschmidt + * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses + + 2010-06-12: Simon Goldschmidt + * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop + state + + 2010-05-17: Simon Goldschmidt + * netdb.c: Correctly NULL-terminate h_addr_list + + 2010-05-16: Simon Goldschmidt + * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent + "symbol already defined" i.e. when linking to winsock + + 2010-05-05: Simon Goldschmidt + * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may + overflow) + + 2010-04-21: Simon Goldschmidt + * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening + connection) + + 2010-03-28: Luca Ceresoli + * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers + + 2010-03-27: Luca Ceresoli + * mib2.c: patch #7130: remove meaningless const qualifiers + + 2010-03-26: Simon Goldschmidt + * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too + + 2010-03-26: Simon Goldschmidt + * various files: Fixed compiling with different options disabled (TCP/UDP), + triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled + + 2010-03-25: Simon Goldschmidt + * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly + + 2010-03-25: Simon Goldschmidt + * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side + overrunning our rcv_wnd in ooseq case. + + 2010-03-22: Simon Goldschmidt + * tcp.c: tcp_listen() did not copy the pcb's prio. + + 2010-03-19: Simon Goldschmidt + * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set + + 2010-03-14: Simon Goldschmidt + * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports + where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h + and basing PBUF_LINK_HLEN on it. + + 2010-03-08: Simon Goldschmidt + * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections + when assiging routable address): when checking incoming packets and + aborting existing connection on address change, filter out link-local + addresses. + + 2010-03-06: Simon Goldschmidt + * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING + + 2010-03-06: Simon Goldschmidt + * ipv4/ip.c: Don't try to forward link-local addresses + + 2010-03-06: Simon Goldschmidt + * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- + addresses to gw + + 2010-03-05: Simon Goldschmidt + * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type + and state. + + 2010-03-05: Simon Goldschmidt + * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split + into multiple calls to tcp_write. + + 2010-02-21: Simon Goldschmidt + * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep + the implementation of DNS_USES_STATIC_BUF==1) + + 2010-02-20: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement + close() vs. shutdown(). Now the application does not get any more + recv callbacks after calling tcp_close(). Added tcp_shutdown(). + + 2010-02-19: Simon Goldschmidt + * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent + confusion with realloc() + + 2010-02-15: Simon Goldschmidt/Stephane Lesage + * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK + (fixes bug #28899) + + 2010-02-14: Simon Goldschmidt + * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with + LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and + admin-status of a netif are up + + 2010-02-14: Simon Goldschmidt + * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet + reception and is not really necessary + + 2010-02-14: Simon Goldschmidt + * etharp.c/.h: Fixed ARP input processing: only add a new entry if a + request was directed as us (RFC 826, Packet Reception), otherwise + only update existing entries; internalized some functions + + 2010-02-14: Simon Goldschmidt + * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be + disabled on netif used for PPPoE) by adding a new netif flag + (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet + device but prevents usage of ARP (so that ethernet_input can be used + for PPPoE). + + 2010-02-12: Simon Goldschmidt + * netif.c: netif_set_link_up/down: only do something if the link state + actually changes + + 2010-02-12: Simon Goldschmidt/Stephane Lesage + * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking + connect) + + 2010-02-12: Simon Goldschmidt + * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) + + 2010-02-09: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 + (recv() makes receive window update for data that wasn't received by + application) + + 2010-02-09: Simon Goldschmidt/Stephane Lesage + * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out + or any netconn_recv() error) + + 2010-02-09: Simon Goldschmidt + * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) + + 2010-02-09: Simon Goldschmidt + * netif.c: For loopback packets, adjust the stats- and snmp-counters + for the loopback netif. + + 2010-02-08: Simon Goldschmidt + * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity + since they are not used anywhere else. + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats + (patch from bug #28798) + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and + another bug when LWIP_RAND() returns zero. + + 2010-02-04: Simon Goldschmidt + * nearly every file: Use macros defined in ip_addr.h (some of them new) + to work with IP addresses (preparation for bug #27352 - Change ip_addr + from struct to typedef (u32_t) - and better code). + + 2010-01-31: Simon Goldschmidt + * netif.c: Don't call the link-callback from netif_set_up/down() since + this invalidly retriggers DHCP. + + 2010-01-29: Simon Goldschmidt + * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the + portability file inet.h and its contents from the stack: moved htonX- + functions to def.h (and the new def.c - they are not ipv4 dependent), + let inet.h depend on ip_addr.h and not the other way round. + This fixes bug #28732. + + 2010-01-28: Kieran Mansley + * tcp.c: Ensure ssthresh >= 2*MSS + + 2010-01-27: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv + callback can lead to accessing unallocated memory. As a consequence, + ERR_ABRT means the application has called tcp_abort()! + + 2010-01-25: Simon Goldschmidt + * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY + not implemented in SNMP): write-only or not-accessible are still + returned by getnext (though not by get) + + 2010-01-24: Simon Goldschmidt + * snmp: Renamed the private mib node from 'private' to 'mib_private' to + not use reserved C/C++ keywords + + 2010-01-23: Simon Goldschmidt + * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less + than 1 ms + + 2010-01-21: Simon Goldschmidt + * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called + if tcp_enqueue fails) both in raw- and netconn-API + + 2010-01-19: Simon Goldschmidt + * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp + + 2010-01-18: Iordan Neshev/Simon Goldschmidt + * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some + bugfix backports from 2.4.x. + + 2010-01-18: Simon Goldschmidt + * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong + + 2010-01-17: Simon Goldschmidt + * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): + task #10102: "netconn: clean up conn->err threading issues" by adding + error return value to struct api_msg_msg + + 2010-01-17: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() + to return err_t (bugs #27709 and #28087) + + 2010-01-14: Simon Goldschmidt + * ...: Use typedef for function prototypes throughout the stack. + + 2010-01-13: Simon Goldschmidt + * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive + window = 0) by correctly draining recvmbox/acceptmbox + + 2010-01-11: Simon Goldschmidt + * pap.c: Fixed bug #13315 (PPP PAP authentication can result in + erroneous callbacks) by copying the code from recent pppd + + 2010-01-10: Simon Goldschmidt + * raw.c: Fixed bug #28506 (raw_bind should filter received packets) + + 2010-01-10: Simon Goldschmidt + * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) + + 2010-01-08: Simon Goldschmidt + * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) + + 2010-01-08: Simon Goldschmidt + * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string + passed to dns_local_addhost() might be volatile + + 2010-01-07: Simon Goldschmidt + * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too + + 2010-01-06: Simon Goldschmidt + * netdb.h: Fixed bug #28496: missing include guards in netdb.h + + 2009-12-31: Simon Goldschmidt + * many ppp files: Reorganised PPP source code from ucip structure to pppd + structure to easily compare our code against the pppd code (around v2.3.1) + + 2009-12-27: Simon Goldschmidt + * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted + unit test + + +(STABLE-1.3.2) + + ++ New features: + + 2009-10-27 Simon Goldschmidt/Stephan Lesage + * netifapi.c/.h: Added netifapi_netif_set_addr() + + 2009-10-07 Simon Goldschmidt/Fabian Koch + * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to + support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) + + 2009-08-26 Simon Goldschmidt/Simon Kallweit + * slipif.c/.h: bug #26397: SLIP polling support + + 2009-08-25 Simon Goldschmidt + * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), + New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. + + 2009-08-25 Simon Goldschmidt + * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) + + 2009-08-24 Jakob Stoklund Olesen + * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond + to netif_set_link_up(). + + 2009-08-23 Simon Goldschmidt + * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state + to a human-readable string. + + ++ Bugfixes: + + 2009-12-24: Kieran Mansley + * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing + (BUG#28241) + + 2009-12-06: Simon Goldschmidt + * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can + be statically allocated (like in ucip) + + 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) + * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT + + 2009-12-03: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit + could have non-zero length + + 2009-12-02: Simon Goldschmidt + * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting + tcp_input_pcb until after calling the pcb's callbacks + + 2009-11-29: Simon Goldschmidt + * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- + sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code + + 2009-11-29: Simon Goldschmidt + * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by + queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty + + 2009-11-26: Simon Goldschmidt + * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending + segment + + 2009-11-26: Simon Goldschmidt + * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle + algorithm at PCB level + + 2009-11-22: Simon Goldschmidt + * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent + + 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) + * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when + reusing time-wait pcb + + 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) + * sockets.c: Fixed bug #28062: Data received directly after accepting + does not wake up select + + 2009-11-11: Simon Goldschmidt + * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) + + 2009-10-30: Simon Goldschmidt + * opt.h: Increased default value for TCP_MSS to 536, updated default + value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. + + 2009-10-28: Kieran Mansley + * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code + to follow algorithm from TCP/IP Illustrated + + 2009-10-27: Kieran Mansley + * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK + + 2009-10-25: Simon Goldschmidt + * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if + pcb->recv is NULL to keep rcv_wnd correct) + + 2009-10-25: Simon Goldschmidt + * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state + + 2009-10-23: Simon Goldschmidt (David Empson) + * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes + + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + + 2009-10-19: Simon Goldschmidt + * dhcp.c/.h: Minor code simplification (don't store received pbuf, change + conditional code to assert where applicable), check pbuf length before + testing for valid reply + + 2009-10-19: Simon Goldschmidt + * dhcp.c: Removed most calls to udp_connect since they aren't necessary + when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. + + 2009-10-16: Simon Goldschmidt + * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop + valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is + enabled + + 2009-10-15: Simon Goldschmidt (Oleg Tyshev) + * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit + + 2009-10-15: Simon Goldschmidt + * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() + timeout + + 2009-10-15: Simon Goldschmidt + * autoip.c: Fixed bug #27704: autoip starts with wrong address + LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead + of network byte order + + 2009-10-11 Simon Goldschmidt (Jrg Kesten) + * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments + which are not consecutive when retransmitting unacked segments + + 2009-10-09 Simon Goldschmidt + * opt.h: Fixed default values of some stats to only be enabled if used + Fixes bug #27338: sys_stats is defined when NO_SYS = 1 + + 2009-08-30 Simon Goldschmidt + * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK + function" by checking for loopback before calling ip_frag + + 2009-08-25 Simon Goldschmidt + * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27078: Possible memory leak in pppInit() + + 2009-08-23 Simon Goldschmidt + * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result + is error. + + 2009-08-23 Simon Goldschmidt + * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF + Fixed wrong parenthesis, added check in init.c + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms + + 2009-08-23 Simon Goldschmidt + * many ppp files: bug #27267: Added include to string.h where needed + + 2009-08-23 Simon Goldschmidt + * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) + + +(STABLE-1.3.1) + + ++ New features: + + 2009-05-10 Simon Goldschmidt + * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option + LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only + one pbuf to help MACs that don't support scatter-gather DMA. + + 2009-05-09 Simon Goldschmidt + * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming + ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + + 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen + * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive + extended info about the currently received packet. + + 2009-04-27 Simon Goldschmidt + * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 + + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined + as an external function for lookup. + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for + TCP timestamp options, off by default. Rework tcp_enqueue() to + take option flags rather than specified option data + + 2009-02-18 Simon Goldschmidt + * cc.h: Added printf formatter for size_t: SZT_F + + 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) + * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast + pings + + 2009-02-12 Simon Goldschmidt + * init.h: Added LWIP_VERSION to get the current version of the stack + + 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) + * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead + of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc + is otherwise used) + + 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) + * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() + is only used by UDPLITE at present, so conditionalise it. + + 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) + * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP + "seed" address. This should reduce AUTOIP conflicts if + LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. + + 2008-10-02 Jonathan Larmour and Rishi Khan + * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking + socket. + + 2008-06-30 Simon Goldschmidt + * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from + interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows + mem_free to run between mem_malloc iterations. Added illegal counter for + mem stats. + + 2008-06-27 Simon Goldschmidt + * stats.h/.c, some other files: patch #6483: stats module improvement: + Added defines to display each module's statistic individually, added stats + defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. + + 2008-06-17 Simon Goldschmidt + * err.h: patch #6459: Made err_t overridable to use a more efficient type + (define LWIP_ERR_T in cc.h) + + 2008-06-17 Simon Goldschmidt + * slipif.c: patch #6480: Added a configuration option for slipif for symmetry + to loopif + + 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) + * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly + modified version of patch # 6370: Moved loopif code to netif.c so that + loopback traffic is supported on all netifs (all local IPs). + Added option to limit loopback packets for each netifs. + + + ++ Bugfixes: + 2009-08-12 Kieran Mansley + * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when + out of window or out of order properly + + 2009-08-12 Kieran Mansley + * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 + + 2009-07-28 Simon Goldschmidt + * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s + + 2009-07-27 Kieran Mansley + * api.h api_msg.h netdb.h sockets.h: add missing #include directives + + 2009-07-09 Kieran Mansley + * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for + recv_avail and don't increment counters until message successfully + sent to mbox + + 2009-06-25 Kieran Mansley + * api_msg.c api.h: BUG26722: initialise netconn write variables + in netconn_alloc + + 2009-06-25 Kieran Mansley + * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set + + 2009-06-25 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct + simultaneous close behaviour, and make snd_nxt have the same meaning + as in the RFCs. + + 2009-05-12 Simon Goldschmidt + * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on + arp_table / uses etharp_query" by adding etharp_gratuitous() + + 2009-05-12 Simon Goldschmidt + * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options + to the IP header (used by igmp_ip_output_if) + + 2009-05-06 Simon Goldschmidt + * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if + defined) for SWAP_BYTES_IN_WORD to speed up checksumming. + + 2009-05-05 Simon Goldschmidt + * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() + to crash + + 2009-05-04 Simon Goldschmidt + * init.c: snmp was not initialized in lwip_init() + + 2009-05-04 Frdric Bernon + * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. + + 2009-05-03 Simon Goldschmidt + * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full + (and unsent->next == NULL) + + 2009-05-02 Simon Goldschmidt + * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after + 1.3.0 in CVS only) - fixes compilation of ppp_oe.c + + 2009-05-02 Simon Goldschmidt + * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields + + 2009-05-01 Simon Goldschmidt + * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets + + 2009-05-01 Simon Goldschmidt + * ppp.c: bug #24228: Memory corruption with PPP and DHCP + + 2009-04-29 Frdric Bernon + * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the + SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception + of broadcast packets even when this option wasn't set. Port maintainers + which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. + If you want this option also filter broadcast on recv operations, you also + have to set IP_SOF_BROADCAST_RECV=1 in opt.h. + + 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen + * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and + DHCP/AUTOIP cooperation + + 2009-04-25 Simon Goldschmidt, Oleg Tyshev + * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd + Fixed by sorting the unsent and unacked queues (segments are inserted at the + right place in tcp_output and tcp_rexmit). + + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + + 2009-04-24 Simon Goldschmidt, Frdric Bernon + * inet.c: patch #6765: Fix a small problem with the last changes (incorrect + behavior, with with ip address string not ended by a '\0', a space or a + end of line) + + 2009-04-19 Simon Goldschmidt + * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, + pcb->err is called, not pcb->connected (with an error code). + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with + no-copy-tcpwrite": deallocate option data, only concat segments with same flags + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated + in the header pbuf, not the data pbuf) + + 2009-04-18 Simon Goldschmidt + * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() + + 2009-04-15 Simon Goldschmidt + * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp + + 2009-04-15 Simon Goldschmidt + * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in + + 2009-04-15 Simon Goldschmidt + * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function + ip_hinted_output() (for smaller code mainly) + + 2009-04-15 Simon Goldschmidt + * inet.c: patch #6765: Supporting new line characters in inet_aton() + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; + Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu + is big enough in dhcp_start + + 2009-04-15 Simon Goldschmidt + * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak + + 2009-04-15 Simon Goldschmidt + * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY + + 2009-04-15 Simon Goldschmidt + * sockets.c: bug #26121: set_errno can be overridden + + 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) + * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when + LWIP_TCP==0 + + 2009-04-09 Kieran Mansley (patch from Roy Lee ) + * tcp.h: Patch#6802 Add do-while-clauses to those function like + macros in tcp.h + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window + updates are calculated and sent (BUG20515) + + * tcp_in.c: cope with SYN packets received during established states, + and retransmission of initial SYN. + + * tcp_out.c: set push bit correctly when tcp segments are merged + + 2009-03-27 Kieran Mansley + * tcp_out.c set window correctly on probes (correcting change made + yesterday) + + 2009-03-26 Kieran Mansley + * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping + connections where no reset required (bug #25622) + + * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes + (bug #20779) + + 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) + * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be + too small depending on MEM_ALIGNMENT + + 2009-02-16 Simon Goldschmidt + * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; + converted size argument of netconn_write to 'size_t' + + 2009-02-16 Simon Goldschmidt + * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host + by moving accept callback function pointer to TCP_PCB_COMMON + + 2009-02-12 Simon Goldschmidt + * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" + option) + + 2009-02-11 Simon Goldschmidt + * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) + + 2009-02-11 Simon Goldschmidt + * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: + RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) + + 2009-02-10 Simon Goldschmidt + * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: + Accepts_pending is decrease on a corresponding listen pcb when a connection + in state SYN_RCVD is close. + + 2009-01-28 Jonathan Larmour + * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run + out of pool pbufs. + + 2008-12-19 Simon Goldschmidt + * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 + + 2008-12-10 Tamas Somogyi, Frdric Bernon + * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and + port uses deleted netbuf. + + 2008-10-18 Simon Goldschmidt + * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length + in tcp_parseopt + + 2008-10-15 Simon Goldschmidt + * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers + by packing the struct ip_reass_helper. + + 2008-10-03 David Woodhouse, Jonathan Larmour + * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. + + 2008-10-02 Jonathan Larmour + * dns.c: Hard-code structure sizes, to avoid issues on some compilers where + padding is included. + + 2008-09-30 Jonathan Larmour + * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an + assertion check that addrlen isn't NULL. + + 2008-09-30 Jonathan Larmour + * tcp.c: Fix bug #24227, wrong error message in tcp_bind. + + 2008-08-26 Simon Goldschmidt + * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and + inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h + + 2008-08-14 Simon Goldschmidt + * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when + tcp_close returns != ERR_OK) + + 2008-07-08 Frdric Bernon + * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters + in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). + + 2008-06-24 Jonathan Larmour + * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused + if tcp_seg_copy fails. + + 2008-06-17 Simon Goldschmidt + * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) + and created defines for swapping bytes and folding u32 to u16. + + 2008-05-30 Kieran Mansley + * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd + rather than rcv_ann_wnd when deciding if packets are in-window. + Contributed by + + 2008-05-30 Kieran Mansley + * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow + passing as function pointers when MEM_LIBC_MALLOC is defined. + + 2008-05-09 Jonathan Larmour + * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to + stop it being treated as a fatal error. + + 2008-04-15 Simon Goldschmidt + * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP + (flag now cleared) + + 2008-03-27 Simon Goldschmidt + * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free + from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 + in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs + or heap memory from interrupt context + + 2008-03-26 Simon Goldschmidt + * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote + host sent a zero mss as TCP option. + + +(STABLE-1.3.0) + + ++ New features: + + 2008-03-10 Jonathan Larmour + * inet_chksum.c: Allow choice of one of the sample algorithms to be + made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. + + 2008-01-22 Frdric Bernon + * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in + TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. + + 2008-01-14 Frdric Bernon + * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable + to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the + tcp_recv callback (see rawapi.txt). + + 2008-01-14 Frdric Bernon, Marc Chaland + * ip.c: Integrate patch #6369" ip_input : checking before realloc". + + 2008-01-12 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::sem per netconn::op_completed like suggested for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-12 Frdric Bernon + * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, + DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues + sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 + "Add return value to sys_mbox_post". tcpip_callback is always defined as + "blocking" ("block" parameter = 1). + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-05 Frdric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + + 2008-01-04 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, + tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the + "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add + documentation in the rawapi.txt file. + + 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer + + 2007-12-31 Frdric Bernon, Luca Ceresoli + * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets + in autoip". The change in etharp_raw could be removed, since all calls to + etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be + wrong in the future. + + 2007-12-30 Frdric Bernon, Tom Evans + * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address + Filtering" reported by Tom Evans. + + 2007-12-21 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, + sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API + applications have to call 'tcp_accepted(pcb)' in their accept callback to + keep accepting new connections. + + 2007-12-13 Frdric Bernon + * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" + by err_t type. Add a new err_t code "ERR_INPROGRESS". + + 2007-12-12 Frdric Bernon + * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles + are the one which have ram usage. + + 2007-12-05 Frdric Bernon + * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static + set of variables (=0) or a local one (=1). In this last case, your port should + provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" + which have to do a copy of "h" and return a pointer ont the "per-thread" copy. + + 2007-12-03 Simon Goldschmidt + * ip.c: ip_input: check if a packet is for inp first before checking all other + netifs on netif_list (speeds up packet receiving in most cases) + + 2007-11-30 Simon Goldschmidt + * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access + UDP: move a (connected) pcb selected for input to the front of the list of + pcbs so that it is found faster next time. Same for RAW pcbs that have eaten + a packet. + + 2007-11-28 Simon Goldschmidt + * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS + + 2007-11-25 Simon Goldschmidt + * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy + algorithm. + + 2007-11-24 Simon Goldschmidt + * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c + to the new file netdb.c; included lwip_getaddrinfo. + + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. + + 2007-11-19 Frdric Bernon + * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name + received match the name query), implement DNS_USES_STATIC_BUF (the place where + copy dns payload to parse the response), return an error if there is no place + for a new query, and fix some minor problems. + + 2007-11-16 Simon Goldschmidt + * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c + removed files: core/inet.c, core/inet6.c + Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into + inet and chksum part; changed includes in all lwIP files as appropriate + + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential + dns resolver function for netconn api (netconn_gethostbyname) and socket api + (gethostbyname/gethostbyname_r). + + 2007-11-15 Jim Pettinato, Frdric Bernon + * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name + requests with RAW api interface. Initialization is done in lwip_init() with + build time options. DNS timer is added in tcpip_thread context. DHCP can set + DNS server ip addresses when options are received. You need to set LWIP_DNS=1 + in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get + some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" + list with points to improve. + + 2007-11-06 Simon Goldschmidt + * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly + enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status + for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. + + 2007-11-06 Simon Goldschmidt + * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include + core header files in api.h (ip/tcp/udp/raw.h) to hide the internal + implementation from netconn api applications. + + 2007-11-03 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + + 2007-11-01 Frdric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + + 2007-10-24 Frdric Bernon + * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than + TCP_EVENT_xxx macros to get a code more readable. It could also help to remove + some code (like we have talk in "patch #5919 : Create compile switch to remove + select code"), but it could be done later. + + 2007-10-08 Simon Goldschmidt + * many files: Changed initialization: many init functions are not needed any + more since we now rely on the compiler initializing global and static + variables to zero! + + 2007-10-06 Simon Goldschmidt + * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY + to enqueue the received pbufs so that multiple packets can be reassembled + simultaneously and no static reassembly buffer is needed. + + 2007-10-05 Simon Goldschmidt + * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so + all netifs (or ports) can use it. + + 2007-10-05 Frdric Bernon + * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the + common function to reduce a little bit the footprint (for all functions using + only the "netif" parameter). + + 2007-10-03 Frdric Bernon + * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, + netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce + a little bit the footprint (for all functions using only the "netif" parameter). + + 2007-09-15 Frdric Bernon + * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF + option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for + netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for + IP_MULTICAST_TTL and IP_MULTICAST_IF. + + 2007-09-10 Frdric Bernon + * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles + even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() + each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can + decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but + call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() + or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. + This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside + snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only + when it's queried (any direct call to "sysuptime" is changed by a call to + snmp_get_sysuptime). + + 2007-09-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, + and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags + if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). + igmp_report_groups() is now called inside netif_set_link_up() (need to have + LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait + the next query message to receive the matching multicast streams). + + 2007-09-08 Frdric Bernon + * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains + IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). + Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). + Enable to access to these fields with LWIP_TCP=0. + + 2007-09-05 Frdric Bernon + * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, + ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option + LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). + Be careful, disabling ICMP make your product non-compliant to RFC1122, but + help to reduce footprint, and to reduce "visibility" on the Internet. + + 2007-09-05 Frdric Bernon, Bill Florac + * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list + for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new + parameters have to be provided: a task name, and a task stack size. For this + one, since it's platform dependant, you could define the best one for you in + your lwipopts.h. For port maintainers, you can just add these new parameters + in your sys_arch.c file, and but it's not mandatory, use them in your OS + specific functions. + + 2007-09-05 Frdric Bernon + * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings + inside init.c for task #7142 "Sanity check user-configurable values". + + 2007-09-04 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by + memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the + value). It will avoid potential fragmentation problems, use a counter to know + how many times a group is used on an netif, and free it when all applications + leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity + check if LWIP_IGMP!=0). + + 2007-09-03 Frdric Bernon + * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". + Initialize igmp_mac_filter to NULL in netif_add (this field should be set in + the netif's "init" function). Use the "imr_interface" field (for socket layer) + and/or the "interface" field (for netconn layer), for join/leave operations. + The igmp_join/leavegroup first parameter change from a netif to an ipaddr. + This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). + + 2007-08-30 Frdric Bernon + * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions + from api/api_lib". Now netbuf API is independant of netconn, and can be used + with other API (application based on raw API, or future "socket2" API). Ports + maintainers just have to add src/api/netbuf.c in their makefile/projects. + + 2007-08-30 Frdric Bernon, Jonathan Larmour + * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check + user-configurable values". + + 2007-08-29 Frdric Bernon + * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. + igmp_start is call inside netif_add. Now, igmp initialization is in the same + spirit than the others modules. Modify some IGMP debug traces. + + 2007-08-29 Frdric Bernon + * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" + Add lwip_init function to regroup all modules initializations, and to provide + a place to add code for task #7142 "Sanity check user-configurable values". + Ports maintainers should remove direct initializations calls from their code, + and add init.c in their makefiles. Note that lwip_init() function is called + inside tcpip_init, but can also be used by raw api users since all calls are + disabled when matching options are disabled. Also note that their is new options + in opt.h, you should configure in your lwipopts.h (they are enabled per default). + + 2007-08-26 Marc Boucher + * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL + since they can under certain circumstances be called with an invalid conn + pointer after the connection has been closed (and conn has been freed). + + 2007-08-25 Frdric Bernon (Artem Migaev's Patch) + * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". + Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. + + 2007-08-22 Frdric Bernon + * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK + to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. + + 2007-08-22 Frdric Bernon + * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & + ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the + name is tcpip_input (we keep the name of 1.2.0 function). + + 2007-08-17 Jared Grubb + * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool + settings into new memp_std.h and optional user file lwippools.h. This adds + more dynamic mempools, and allows the user to create an arbitrary number of + mempools for mem_malloc. + + 2007-08-16 Marc Boucher + * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; + otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely + close the connection. + + 2007-08-16 Marc Boucher + * sockets.c: lwip_accept(): check netconn_peer() error return. + + 2007-08-16 Marc Boucher + * mem.c, mem.h: Added mem_calloc(). + + 2007-08-16 Marc Boucher + * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) + for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG + and starving other message types. + Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API + + 2007-08-16 Marc Boucher + * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf + type and flgs (later renamed to flags). + Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. + Improved lwip_recvfrom(). TCP push now propagated. + + 2007-08-16 Marc Boucher + * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global + provided by etharp. + + 2007-08-16 Marc Boucher + * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, + etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: + Added PPPoE support and various PPP improvements. + + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + + 2007-07-25 Simon Goldschmidt + * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with + 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and + other stacks. + + 2007-07-13 Jared Grubb (integrated by Frdric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + + 2007-06-30 Frdric Bernon + * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. + + 2007-06-21 Simon Goldschmidt + * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both + LWIP_AUTOIP =0 and =1 to remove redundant code. + + 2007-06-21 Simon Goldschmidt + * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option + MEM_USE_POOLS to use 4 pools with different sized elements instead of a + heap. This both prevents memory fragmentation and gives a higher speed + at the cost of more memory consumption. Turned off by default. + + 2007-06-21 Simon Goldschmidt + * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of + netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into + int to be able to send a bigger buffer than 64K with one time (mainly + used from lwip_send). + + 2007-06-21 Simon Goldschmidt + * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write + into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. + + 2007-06-21 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in + netconn_write from api_lib.c to api_msg.c to also prevent multiple context- + changes on low memory or empty send-buffer. + + 2007-06-18 Simon Goldschmidt + * etharp.c, etharp.h: Changed etharp to use a defined hardware address length + of 6 to avoid loading netif->hwaddr_len every time (since this file is only + used for ethernet and struct eth_addr already had a defined length of 6). + + 2007-06-17 Simon Goldschmidt + * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets + to disable UDP checksum generation on transmit. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid + pointers or parameters, and let the possibility to redefined it in cc.h. Use + this macro to check "conn" parameter in api_msg.c functions. + + 2007-06-11 Simon Goldschmidt + * sockets.c, sockets.h: Added UDP lite support for sockets + + 2007-06-10 Simon Goldschmidt + * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled + by default) to switch off UDP-Lite support if not needed (reduces udp.c code + size) + + 2007-06-09 Dominik Spies (integrated by Frdric Bernon) + * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: + AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and + LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt + (see TODO mark in the source code). + + 2007-06-09 Simon Goldschmidt + * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for + etharp_output() to match netif->output so etharp_output() can be used + directly as netif->output to save one function call. + + 2007-06-08 Simon Goldschmidt + * netif.h, ethernetif.c, slipif.c, loopif.c: Added define + NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, + added initialization of those to ethernetif, slipif and loopif. + + 2007-05-18 Simon Goldschmidt + * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF + (defaulting to off for now) that can be set to 0 to send fragmented + packets by passing PBUF_REFs down the stack. + + 2007-05-23 Frdric Bernon + * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP + connections, such present in patch #5959. + + 2007-05-23 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx + code in only one part... + + 2007-05-18 Simon Goldschmidt + * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp + elements to overflow. This is achieved by adding some bytes before and after + each pool element (increasing their size, of course), filling them with a + prominent value and checking them on freeing the element. + Set it to 2 to also check every element in every pool each time memp_malloc() + or memp_free() is called (slower but more helpful). + + 2007-05-10 Simon Goldschmidt + * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for + PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce + code size. + + 2007-05-11 Frdric Bernon + * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: + Include a function pointer instead of a table index in the message to reduce + footprint. Disable some part of lwip_send and lwip_sendto if some options are + not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). + + 2007-05-10 Simon Goldschmidt + * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus + \ extern "C" {' in all header files. Now you can write your application using + the lwIP stack in C++ and simply #include the core files. Note I have left + out the netif/ppp/*h header files for now, since I don't know which files are + included by applications and which are for internal use only. + + 2007-05-09 Simon Goldschmidt + * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library + memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for + situations where some compilers might inline the copy and save a function + call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). + + 2007-05-08 Simon Goldschmidt + * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) + to be overriden in case the C-library malloc implementation is not protected + against concurrent access. + + 2007-05-04 Simon Goldschmidt (Atte Kojo) + * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending + multiple packets to the same host. + + 2007-05-04 Frdric Bernon, Jonathan Larmour + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible + to corrupt remote addr/port connection state". Reduce problems "not enought memory" with + netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between + sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. + Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, + these fields are now renamed "addr" & "port". + + 2007-04-11 Jonathan Larmour + * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new + sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return + with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro + by the port in sys_arch.h if desired. + + 2007-04-06 Frdric Bernon, Simon Goldschmidt + * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API + allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp + clients, using new functions from netifapi.h. Disable as default (no port change to do). + + 2007-04-05 Frdric Bernon + * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. + + 2007-04-04 Simon Goldschmidt + * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) + use this for and architecture-independent form to tell the compiler you intentionally + are not using this variable. Can be overriden in cc.h. + + 2007-03-28 Frdric Bernon + * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to + define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded + string, point on one of your's ethernetif field, or alloc a string you will free yourself). + It will be used by DHCP to register a client hostname, but can also be use when you call + snmp_set_sysname. + + 2007-03-28 Frdric Bernon + * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to + initialize a network interface's flag with. It tell this interface is an ethernet + device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility + Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). + + 2007-03-26 Frdric Bernon, Jonathan Larmour + * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build + time if you only use PPP or SLIP. The default is enable. Note we don't have to call + etharp_init in your port's initilization sequence if you use tcpip.c, because this call + is done in tcpip_init function. + + 2007-03-22 Frdric Bernon + * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the + new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in + your lwipopts.h. More, unused counters are not defined in the stats structs, and not + display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined + but never used. Fix msg_in.c with the correct #if test for a stat display. + + 2007-03-21 Kieran Mansley + * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). + Provides callback on netif up/down state change. + + 2007-03-11 Frdric Bernon, Mace Gael, Steve Reynolds + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, + ip.c, netif.h, tcpip.c, opt.h: + New configuration option LWIP_IGMP to enable IGMP processing. Based on only one + filter per all network interfaces. Declare a new function in netif to enable to + control the MAC filter (to reduce lwIP traffic processing). + + 2007-03-11 Frdric Bernon + * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can + be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this + unless you know what you're doing (default are RFC1122 compliant). Note + that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. + + 2007-03-08 Frdric Bernon + * tcp.h: Keepalive values can be configured at compile time, but don't change + this unless you know what you're doing (default are RFC1122 compliant). + + 2007-03-08 Frdric Bernon + * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: + Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO + on UDP sockets/netconn. + + 2007-03-08 Simon Goldschmidt + * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. + + 2007-03-06 Frdric Bernon + * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: + Implement SO_RCVTIMEO on UDP sockets/netconn. + + 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) + * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated + on the stack and remove the API msg type from memp + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * sockets.h, sockets.c: Move socket initialization to new + lwip_socket_init() function. + NOTE: this changes the API with ports. Ports will have to be + updated to call lwip_socket_init() now. + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * api_lib.c: Use memcpy in netbuf_copy_partial. + + + ++ Bug fixes: + + 2008-03-17 Frdric Bernon, Ed Kerekes + * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have + some problems to fill the IP header on some targets, use now the + ip.h macros to do it). + + 2008-03-13 Frdric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + + 2008-03-12 Frdric Bernon, Jonathan Larmour + * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's + recv_raw() does not consume data", and the ping sample (with + LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom + returned the IP payload, without the IP header). + + 2008-03-04 Jonathan Larmour + * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors + and/or warnings on some systems where mem_size_t and size_t differ. + * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. + + 2008-03-04 Kieran Mansley (contributions by others) + * Numerous small compiler error/warning fixes from contributions to + mailing list after 1.3.0 release candidate made. + + 2008-01-25 Cui hengbin (integrated by Frdric Bernon) + * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. + + 2008-01-15 Kieran Mansley + * tcp_out.c: BUG20511. Modify persist timer to start when we are + prevented from sending by a small send window, not just a zero + send window. + + 2008-01-09 Jonathan Larmour + * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid + conflict with Linux system headers. + + 2008-01-06 Jonathan Larmour + * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP + address entirely on receiving a DHCPNAK, and restarting discovery. + + 2007-12-21 Simon Goldschmidt + * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail + is not protected" by using new macros for interlocked access to modify/test + netconn->recv_avail. + + 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) + * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) + + 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling + of silly window avoidance and prevent lwIP from shrinking the window) + + 2007-12-04 Simon Goldschmidt + * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last + data packet was lost): add assert that all segment lists are empty in + tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED + state from LAST_ACK in tcp_process + + 2007-12-02 Simon Goldschmidt + * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET + If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now + has to be set to 0 in lwipopts.h + + 2007-12-02 Simon Goldschmidt + * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always + allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen + netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. + This is a fix for thread-safety and allocates all items needed for a netconn + when the netconn is created. + + 2007-11-30 Simon Goldschmidt + * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple + netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed + to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same + port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) + + 2007-11-27 Simon Goldschmidt + * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by + letting ip_route only use netifs that are up. + + 2007-11-27 Simon Goldschmidt + * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF + and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and + sockets block most operations once they have seen a fatal error. + + 2007-11-27 Simon Goldschmidt + * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the + netif to send as an argument (to be able to send on netifs that are down). + + 2007-11-26 Simon Goldschmidt + * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs + arrive out-of-order + + 2007-11-21 Simon Goldschmidt + * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early + Fixed the nagle algorithm; nagle now also works for all raw API applications + and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' + + 2007-11-12 Frdric Bernon + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most + of the netconn_peer and netconn_addr processing is done inside tcpip_thread + context in do_getaddr. + + 2007-11-10 Simon Goldschmidt + * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can + happen any time). Now the packet simply isn't enqueued when out of memory. + + 2007-11-01 Simon Goldschmidt + * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or + TCP_MSS if that is smaller) as long as no MSS option is received from the + remote host. + + 2007-11-01 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) + is now based on TCP_MSS instead of pcb->mss (on passive open now effectively + sending our configured TCP_MSS instead of the one received). + + 2007-11-01 Simon Goldschmidt + * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was + calculated based on the configured TCP_MSS, not on the MSS option received + with SYN+ACK. + + 2007-10-09 Simon Goldschmidt + * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too + short and also was generated wrong if checksum coverage != tot_len; + receive: checksum was calculated wrong if checksum coverage != tot_len + + 2007-10-08 Simon Goldschmidt + * mem.c: lfree was not updated in mem_realloc! + + 2007-10-07 Frdric Bernon + * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential + crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: + this change cause an API breakage for netconn_addr, since a parameter + type change. Any compiler should cause an error without any changes in + yours netconn_peer calls (so, it can't be a "silent change"). It also + reduce a little bit the footprint for socket layer (lwip_getpeername & + lwip_getsockname use now a common lwip_getaddrname function since + netconn_peer & netconn_addr have the same parameters). + + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + + 2007-09-19 Simon Goldschmidt + * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) + + 2007-09-15 Mike Kleshov + * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) + + 2007-09-06 Frdric Bernon + * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove + it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which + already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" + if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. + + 2007-08-30 Frdric Bernon + * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, + and fix some coding style. + + 2007-08-28 Frdric Bernon + * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any + kind of packets. These packets are considered like Ethernet packets (payload + pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets + are considered like IP packets (payload pointing to iphdr). + + 2007-08-27 Frdric Bernon + * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error + problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state + and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). + + 2007-08-24 Kieran Mansley + * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy + compiler (Paradigm C++) + + 2007-08-09 Frdric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + + 2007-08-09 Frdric Bernon, Bill Florac + * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast + packet on a udp pcb binded on an netif's IP address, and not on "any". + + 2007-08-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. + This is mainly on using lookup/lookfor, and some coding styles... + + 2007-07-26 Frdric Bernon (and "thedoctor") + * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. + + 2007-07-25 Simon Goldschmidt + * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if + tcp_output fails in tcp_close, the code in do_close_internal gets simpler + (tcp_output is called again later from tcp timers). + + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + + 2007-07-25 Simon Goldschmidt + * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: + changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). + + 2007-07-24 Simon Goldschmidt + * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the + correct state (must be CLOSED). + + 2007-07-13 Thomas Taranowski (commited by Jared Grubb) + * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed + allocation. It now returns NULL. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in + all error cases. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, + because current code doesn't follow rawapi.txt documentation. + + 2007-07-13 Kieran Mansley + * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in + out of sequence processing of received packets + + 2007-07-03 Simon Goldschmidt + * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an + assumption is made that this pbuf is in one piece (i.e. not chained). These + assumptions clash with the possibility of converting to fully pool-based + pbuf implementations, where PBUF_RAM pbufs might be chained. + + 2007-07-03 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems + when closing tcp netconns: removed conn->sem, less context switches when + closing, both netconn_close and netconn_delete should safely close tcp + connections. + + 2007-07-02 Simon Goldschmidt + * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, + tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) + to cache ARP table indices with each pcb instead of single-entry cache for + the complete stack. + + 2007-07-02 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent + warnings when assigning to smaller types. + + 2007-06-28 Simon Goldschmidt + * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. + + 2007-06-28 Simon Goldschmidt + * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if + a segment contained chained pbufs) + + 2007-06-28 Frdric Bernon + * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute + a "pseudo-random" value based on netif's MAC and some autoip fields. It's always + possible to define this macro in your own lwipopts.h to always use C library's + rand(). Note that autoip_create_rand_addr doesn't use this macro. + + 2007-06-28 Frdric Bernon + * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option + LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications + in api_lib/api_msg (use pointers and not type with table, etc...) + + 2007-06-26 Simon Goldschmidt + * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload + for udp packets with no matching pcb. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match + could get udp input packets if the remote side matched. + + 2007-06-13 Simon Goldschmidt + * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get + changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. + + 2007-06-13 Simon Goldschmidt + * api_msg.c: pcb_new sets conn->err if protocol is not implemented + -> netconn_new_..() does not allocate a new connection for unsupported + protocols. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * api_lib.c: change return expression in netconn_addr and netconn_peer, because + conn->err was reset to ERR_OK without any reasons (and error was lost)... + + 2007-06-13 Frdric Bernon, Matthias Weisser + * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename + MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid + some macro names collision with some OS macros. + + 2007-06-11 Simon Goldschmidt + * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, + create checksum over the complete packet. On RX, if it's < 8 (and not 0), + discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both + UDP & UDP Lite. + + 2007-06-11 Srinivas Gollakota & Oleg Tyshev + * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" + where TCP flags wasn't initialized in tcp_keepalive. + + 2007-06-03 Simon Goldschmidt + * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function + registered, p->payload was modified without modifying p->len if sending + icmp_dest_unreach() (had no negative effect but was definitively wrong). + + 2007-06-03 Simon Goldschmidt + * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp + re-used the input pbuf even if that didn't have enough space to include the + link headers. Now the space is tested and a new pbuf is allocated for the + echo response packet if the echo request pbuf isn't big enough. + + 2007-06-01 Simon Goldschmidt + * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. + + 2007-05-23 Frdric Bernon + * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only + allocated by do_listen if success) and netconn_accept errors handling. In + most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" + by ASSERT, except for netconn_delete. + + 2007-05-23 Frdric Bernon + * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return + an error code if it's impossible to fetch a pbuf on a TCP connection (and not + directly close the recvmbox). + + 2007-05-22 Simon Goldschmidt + * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of + bound but unconnected (and non-listening) tcp_pcbs. + + 2007-05-22 Frdric Bernon + * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only + used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of + sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features + like "sys_timeout" in their application threads. + + 2007-05-22 Frdric Bernon + * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see + which parameters are used by which do_xxx function, and to avoid "misusing" + parameters (patch #5938). + + 2007-05-22 Simon Goldschmidt + * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: + changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto + is only 8 bits wide. This affects the api, as there, the protocol was + u16_t, too. + + 2007-05-18 Simon Goldschmidt + * memp.c: addition to patch #5913: smaller pointer was returned but + memp_memory was the same size -> did not save memory. + + 2007-05-16 Simon Goldschmidt + * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns + != ERR_OK. + + 2007-05-16 Simon Goldschmidt + * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same + as the one of the netif used for sending to prevent sending from old + addresses after a netif address gets changed (partly fixes bug #3168). + + 2007-05-16 Frdric Bernon + * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work + with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in + tcpip_init) because we have to be sure that network interfaces are already + added (mac filter is updated only in igmp_init for the moment). + + 2007-05-16 Simon Goldschmidt + * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls + into sys_arch_sem_wait calls to prevent timers from running while waiting + for the heap. This fixes bug #19167. + + 2007-05-13 Simon Goldschmidt + * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines + for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from + tcp.h to sockets.h. + + 2007-05-07 Simon Goldschmidt + * mem.c: Another attempt to fix bug #17922. + + 2007-05-04 Simon Goldschmidt + * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() + implementation so that it can be reused (don't allocate the target + pbuf inside pbuf_copy()). + + 2007-05-04 Simon Goldschmidt + * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem + to save a little RAM (next pointer of memp is not used while not in pool). + + 2007-05-03 "maq" + * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. + (patch #3574). + + 2007-04-23 Simon Goldschmidt + * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results + in NULL reference for incoming TCP packets". Loopif has to be configured + (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() + (multithreading environments, e.g. netif->input() = tcpip_input()) or + putting packets on a list that is fed to the stack by calling loopif_poll() + (single-thread / NO_SYS / polling environment where e.g. + netif->input() = ip_input). + + 2007-04-17 Jonathan Larmour + * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold + the difference between two u16_t's. + * sockets.h: FD_SETSIZE needs to match number of sockets, which is + MEMP_NUM_NETCONN in sockets.c right now. + + 2007-04-12 Jonathan Larmour + * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). + + 2007-04-12 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission + timer is reset to fix bug#19434, with help from Oleg Tyshev. + + 2007-04-11 Simon Goldschmidt + * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than + previously thought need to be copied (everything but PBUF_ROM!). Cleaned up + pbuf.c: removed functions no needed any more (by etharp). + + 2007-04-11 Kieran Mansley + * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix + "Constant is long" warnings with 16bit compilers. Contributed by + avatar@mmlab.cse.yzu.edu.tw + + 2007-04-05 Frdric Bernon, Jonathan Larmour + * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on + the mailbox is active". Now, the post is only done during a connect, and do_send, + do_write and do_join_leave_group don't do anything if a previous error was signaled. + + 2007-04-03 Frdric Bernon + * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output + packets. See patch #5834. + + 2007-03-30 Frdric Bernon + * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add + missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. + + 2007-03-30 Frdric Bernon + * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with + others environment defines (these were too "generic"). + + 2007-03-28 Frdric Bernon + * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call + result and can cause a crash. lwip_send now check netbuf_ref result. + + 2007-03-28 Simon Goldschmidt + * sockets.c Remove "#include " from sockets.c to avoid multiple + definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is + defined. This is the way it should have been already (looking at + doc/sys_arch.txt) + + 2007-03-28 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + + IP and TCP headers *and* physical link headers + + 2007-03-26 Frdric Bernon (based on patch from Dmitry Potapov) + * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause + to send some garbage. It is not a definitive solution, but the patch does solve + the problem for most cases. + + 2007-03-22 Frdric Bernon + * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). + + 2007-03-22 Frdric Bernon + * api_lib.c: somes resources couldn't be freed if there was errors during + netconn_new_with_proto_and_callback. + + 2007-03-22 Frdric Bernon + * ethernetif.c: update netif->input calls to check return value. In older ports, + it's a good idea to upgrade them, even if before, there could be another problem + (access to an uninitialized mailbox). + + 2007-03-21 Simon Goldschmidt + * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed + by casting to unsigned). + + 2007-03-21 Frdric Bernon + * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from + api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a + dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. + Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a + faster and more reliable communication between api_lib and tcpip. + + 2007-03-21 Frdric Bernon + * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. + + 2007-03-21 Frdric Bernon + * api_msg.c, igmp.c, igmp.h: Fix C++ style comments + + 2007-03-21 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + + IP and TCP headers + + 2007-03-21 Kieran Mansley + * Fix all uses of pbuf_header to check the return value. In some + cases just assert if it fails as I'm not sure how to fix them, but + this is no worse than before when they would carry on regardless + of the failure. + + 2007-03-21 Kieran Mansley + * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and + comment out missing header include in icmp.c + + 2007-03-20 Frdric Bernon + * memp.h, stats.c: Fix stats_display function where memp_names table wasn't + synchronized with memp.h. + + 2007-03-20 Frdric Bernon + * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, + tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with + network interfaces. Also fix a compiler warning. + + 2007-03-20 Kieran Mansley + * udp.c: Only try and use pbuf_header() to make space for headers if + not a ROM or REF pbuf. + + 2007-03-19 Frdric Bernon + * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() + and api_msg_post(). + + 2007-03-19 Frdric Bernon + * Remove unimplemented "memp_realloc" function from memp.h. + + 2007-03-11 Simon Goldschmidt + * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused + memory corruption. + + 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) + * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 + (missing `const' qualifier in socket functions), to get more compatible to + standard POSIX sockets. + + 2007-03-11 Frdric Bernon (based on patch from Dmitry Potapov) + * sockets.c: Add asserts inside bind, connect and sendto to check input + parameters. Remove excessive set_errno() calls after get_socket(), because + errno is set inside of get_socket(). Move last sock_set_errno() inside + lwip_close. + + 2007-03-09 Simon Goldschmidt + * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory + was allocated too small. + + 2007-03-06 Simon Goldschmidt + * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect + the stack from concurrent access. + + 2007-03-06 Frdric Bernon, Dmitry Potapov + * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy + call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). + + 2007-03-06 Simon Goldschmidt + * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files + if IP_FRAG == 0 and IP_REASSEMBLY == 0 + + 2007-03-06 Frdric Bernon, Simon Goldschmidt + * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration + option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. + Allow to do ARP processing for incoming packets inside tcpip_thread + (protecting ARP layer against concurrent access). You can also disable + old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. + Older ports have to use tcpip_ethinput. + + 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) + * err.h, err.c: fixed compiler warning "initialization dircards qualifiers + from pointer target type" + + 2007-03-05 Frdric Bernon + * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, + ETHARP_TRUST_IP_MAC, review SO_REUSE) + + 2007-03-04 Frdric Bernon + * api_msg.c: Remove some compiler warnings : parameter "pcb" was never + referenced. + + 2007-03-04 Frdric Bernon + * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from + Dmitry Potapov). + The api_msg struct stay on the stack (not moved to netconn struct). + + 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) + * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if + SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) + Also fixed cast warning in pbuf_alloc() + + 2007-03-04 Simon Goldschmidt + * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt + existing pbuf chain when enqueuing multiple pbufs to a pending ARP request + + 2007-03-03 Frdric Bernon + * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" + It is static, and never used in udp.c except udp_init(). + + 2007-03-02 Simon Goldschmidt + * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from + tcpip_thread() to tcpip_init(). This way, raw API connections can be + initialized before tcpip_thread is running (e.g. before OS is started) + + 2007-03-02 Frdric Bernon + * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call + interval. + + 2007-02-28 Kieran Mansley + * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved + outside the region of the pbuf by pbuf_header() + + 2007-02-28 Kieran Mansley + * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero + when supplied timeout is also non-zero + +(STABLE-1.2.0) + + 2006-12-05 Leon Woestenberg + * CHANGELOG: Mention STABLE-1.2.0 release. + + ++ New features: + + 2006-12-01 Christiaan Simons + * mem.h, opt.h: Added MEM_LIBC_MALLOC option. + Note this is a workaround. Currently I have no other options left. + + 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) + * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define + to include/lwip/opt.h. + * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. + Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. + * opt.h: Add above new options. + + 2006-08-18 Christiaan Simons + * tcp_{in,out}.c: added SNMP counters. + * ipv4/ip.c: added SNMP counters. + * ipv4/ip_frag.c: added SNMP counters. + + 2006-08-08 Christiaan Simons + * etharp.{c,h}: added etharp_find_addr() to read + (stable) ethernet/IP address pair from ARP table + + 2006-07-14 Christiaan Simons + * mib_structs.c: added + * include/lwip/snmp_structs.h: added + * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct + + 2006-07-06 Christiaan Simons + * snmp/asn1_{enc,dec}.c added + * snmp/mib2.c added + * snmp/msg_{in,out}.c added + * include/lwip/snmp_asn1.h added + * include/lwip/snmp_msg.h added + * doc/snmp_agent.txt added + + 2006-03-29 Christiaan Simons + * inet.c, inet.h: Added platform byteswap support. + Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and + optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. + + ++ Bug fixes: + + 2006-11-30 Christiaan Simons + * dhcp.c: Fixed false triggers of request_timeout. + + 2006-11-28 Christiaan Simons + * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. + + 2006-10-11 Christiaan Simons + * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: + Partially accepted patch #5449 for ANSI C compatibility / build fixes. + * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol + identifier from 170 to 136 (bug #17574). + + 2006-10-10 Christiaan Simons + * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. + + 2006-08-17 Christiaan Simons + * udp.c: Fixed bug #17200, added check for broadcast + destinations for PCBs bound to a unicast address. + + 2006-08-07 Christiaan Simons + * api_msg.c: Flushing TCP output in do_close() (bug #15926). + + 2006-06-27 Christiaan Simons + * api_msg.c: Applied patch for cold case (bug #11135). + In accept_function() ensure newconn->callback is always initialized. + + 2006-06-15 Christiaan Simons + * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), + facilitate printing of mem_size_t and u16_t statistics. + + 2006-06-14 Christiaan Simons + * api_msg.c: Applied patch #5146 to handle allocation failures + in accept() by Kevin Lawson. + + 2006-05-26 Christiaan Simons + * api_lib.c: Removed conn->sem creation and destruction + from netconn_write() and added sys_sem_new to netconn_new_*. + +(STABLE-1_1_1) + + 2006-03-03 Christiaan Simons + * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap + access and added pbuf_alloc() return value checks. + + 2006-01-01 Leon Woestenberg + * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is + now handled by the checksum routine properly. + + 2006-02-27 Leon Woestenberg + * pbuf.c: Fix alignment; pbuf_init() would not work unless + pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) + + 2005-12-20 Leon Woestenberg + * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch + submitted by Mitrani Hiroshi. + + 2005-12-15 Christiaan Simons + * inet.c: Disabled the added summing routine to preserve code space. + + 2005-12-14 Leon Woestenberg + * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. + Added Curt McDowell's optimized checksumming routine for future + inclusion. Need to create test case for unaliged, aligned, odd, + even length combination of cases on various endianess machines. + + 2005-12-09 Christiaan Simons + * inet.c: Rewrote standard checksum routine in proper portable C. + + 2005-11-25 Christiaan Simons + * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. + * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, + u32_t, s32_t typedefs. This solves most debug word-length assumes. + + 2005-07-17 Leon Woestenberg + * inet.c: Fixed unaligned 16-bit access in the standard checksum + routine by Peter Jolasson. + * slipif.c: Fixed implementation assumption of single-pbuf datagrams. + + 2005-02-04 Leon Woestenberg + * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. + * tcp_{out|in}.c: Applied patch fixing unaligned access. + + 2005-01-04 Leon Woestenberg + * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. + + 2005-01-03 Leon Woestenberg + * udp.c: UDP pcb->recv() was called even when it was NULL. + +(STABLE-1_1_0) + + 2004-12-28 Leon Woestenberg + * etharp.*: Disabled multiple packets on the ARP queue. + This clashes with TCP queueing. + + 2004-11-28 Leon Woestenberg + * etharp.*: Fixed race condition from ARP request to ARP timeout. + Halved the ARP period, doubled the period counts. + ETHARP_MAX_PENDING now should be at least 2. This prevents + the counter from reaching 0 right away (which would allow + too little time for ARP responses to be received). + + 2004-11-25 Leon Woestenberg + * dhcp.c: Decline messages were not multicast but unicast. + * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. + Do not try hard to insert arbitrary packet's source address, + etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. + etharp_query() now always DOES call ETHARP_TRY_HARD so that users + querying an address will see it appear in the cache (DHCP could + suffer from this when a server invalidly gave an in-use address.) + * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are + comparing network addresses (identifiers), not the network masks + themselves. + * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given + IP address actually belongs to the network of the given interface. + + 2004-11-24 Kieran Mansley + * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. + +(STABLE-1_1_0-RC1) + + 2004-10-16 Kieran Mansley + * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, + even if one is already pending, if the rcv_wnd is above a threshold + (currently TCP_WND/2). This avoids waiting for a timer to expire to send a + delayed ACK in order to open the window if the stack is only receiving data. + + 2004-09-12 Kieran Mansley + * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. + + 2004-08-20 Tony Mountifield + * etharp.c: Make sure the first pbuf queued on an ARP entry + is properly ref counted. + + 2004-07-27 Tony Mountifield + * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler + warnings about comparison. + * pbuf.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. Closed an unclosed comment. + * tcp.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. + * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). + * inet.c: Added a couple of casts to quiet the compiler. + No need to test isascii(c) before isdigit(c) or isxdigit(c). + + 2004-07-22 Tony Mountifield + * inet.c: Made data types consistent in inet_ntoa(). + Added casts for return values of checksum routines, to pacify compiler. + * ip_frag.c, tcp_out.c, sockets.c, pbuf.c + Small corrections to some debugging statements, to pacify compiler. + + 2004-07-21 Tony Mountifield + * etharp.c: Removed spurious semicolon and added missing end-of-comment. + * ethernetif.c Updated low_level_output() to match prototype for + netif->linkoutput and changed low_level_input() similarly for consistency. + * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype + of raw_recv() in raw.h and so avoid compiler error. + * sockets.c: Added trivial (int) cast to keep compiler happier. + * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. + +(STABLE-1_0_0) + + ++ Changes: + + 2004-07-05 Leon Woestenberg + * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure + your cc.h file defines this either 1 or 0. If non-defined, + defaults to 1. + * .c: Added and includes where used. + * etharp.c: Made some array indices unsigned. + + 2004-06-27 Leon Woestenberg + * netif.*: Added netif_set_up()/down(). + * dhcp.c: Changes to restart program flow. + + 2004-05-07 Leon Woestenberg + * etharp.c: In find_entry(), instead of a list traversal per candidate, do a + single-pass lookup for different candidates. Should exploit locality. + + 2004-04-29 Leon Woestenberg + * tcp*.c: Cleaned up source comment documentation for Doxygen processing. + * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. + * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by + the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. + + ++ Bug fixes: + + 2004-04-27 Leon Woestenberg + * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution + suggested by Timmy Brolin. Fix for 32-bit processors that cannot access + non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix + is to prefix the 14-bit Ethernet headers with two padding bytes. + + 2004-04-23 Leon Woestenberg + * ip_addr.c: Fix in the ip_addr_isbroadcast() check. + * etharp.c: Fixed the case where the packet that initiates the ARP request + is not queued, and gets lost. Fixed the case where the packets destination + address is already known; we now always queue the packet and perform an ARP + request. + +(STABLE-0_7_0) + + ++ Bug fixes: + + * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. + * Fixed TCP bug in dequeueing of FIN from out of order segment queue. + * Fixed two possible NULL references in rare cases. + +(STABLE-0_6_6) + + ++ Bug fixes: + + * Fixed DHCP which did not include the IP address in DECLINE messages. + + ++ Changes: + + * etharp.c has been hauled over a bit. + +(STABLE-0_6_5) + + ++ Bug fixes: + + * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. + * Packets sent from ARP queue had invalid source hardware address. + + ++ Changes: + + * Pass-by ARP requests do now update the cache. + + ++ New features: + + * No longer dependent on ctype.h. + * New socket options. + * Raw IP pcb support. + +(STABLE-0_6_4) + + ++ Bug fixes: + + * Some debug formatters and casts fixed. + * Numereous fixes in PPP. + + ++ Changes: + + * DEBUGF now is LWIP_DEBUGF + * pbuf_dechain() has been re-enabled. + * Mentioned the changed use of CVS branches in README. + +(STABLE-0_6_3) + + ++ Bug fixes: + + * Fixed pool pbuf memory leak in pbuf_alloc(). + Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. + Reported by Savin Zlobec. + + * PBUF_POOL chains had their tot_len field not set for non-first + pbufs. Fixed in pbuf_alloc(). + + ++ New features: + + * Added PPP stack contributed by Marc Boucher + + ++ Changes: + + * Now drops short packets for ICMP/UDP/TCP protocols. More robust. + + * ARP queueuing now queues the latest packet instead of the first. + This is the RFC recommended behaviour, but can be overridden in + lwipopts.h. + +(0.6.2) + + ++ Bugfixes: + + * TCP has been fixed to deal with the new use of the pbuf->ref + counter. + + * DHCP dhcp_inform() crash bug fixed. + + ++ Changes: + + * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed + pbuf_refresh(). This has sped up pbuf pool operations considerably. + Implemented by David Haas. + +(0.6.1) + + ++ New features: + + * The packet buffer implementation has been enhanced to support + zero-copy and copy-on-demand for packet buffers which have their + payloads in application-managed memory. + Implemented by David Haas. + + Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy + if an outgoing packet can be directly sent on the link, or perform + a copy-on-demand when necessary. + + The application can safely assume the packet is sent, and the RAM + is available to the application directly after calling udp_send() + or similar function. + + ++ Bugfixes: + + * ARP_QUEUEING should now correctly work for all cases, including + PBUF_REF. + Implemented by Leon Woestenberg. + + ++ Changes: + + * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer + to a '0.0.0.0' IP address. + + * The packet buffer implementation is changed. The pbuf->ref counter + meaning has changed, and several pbuf functions have been + adapted accordingly. + + * netif drivers have to be changed to set the hardware address length field + that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). + See the contrib/ports/c16x cs8900 driver as a driver example. + + * netif's have a dhcp field that must be initialized to NULL by the driver. + See the contrib/ports/c16x cs8900 driver as a driver example. + +(0.5.x) This file has been unmaintained up to 0.6.1. All changes are + logged in CVS but have not been explained here. + +(0.5.3) Changes since version 0.5.2 + + ++ Bugfixes: + + * memp_malloc(MEMP_API_MSG) could fail with multiple application + threads because it wasn't protected by semaphores. + + ++ Other changes: + + * struct ip_addr now packed. + + * The name of the time variable in arp.c has been changed to ctime + to avoid conflicts with the time() function. + +(0.5.2) Changes since version 0.5.1 + + ++ New features: + + * A new TCP function, tcp_tmr(), now handles both TCP timers. + + ++ Bugfixes: + + * A bug in tcp_parseopt() could cause the stack to hang because of a + malformed TCP option. + + * The address of new connections in the accept() function in the BSD + socket library was not handled correctly. + + * pbuf_dechain() did not update the ->tot_len field of the tail. + + * Aborted TCP connections were not handled correctly in all + situations. + + ++ Other changes: + + * All protocol header structs are now packed. + + * The ->len field in the tcp_seg structure now counts the actual + amount of data, and does not add one for SYN and FIN segments. + +(0.5.1) Changes since version 0.5.0 + + ++ New features: + + * Possible to run as a user process under Linux. + + * Preliminary support for cross platform packed structs. + + * ARP timer now implemented. + + ++ Bugfixes: + + * TCP output queue length was badly initialized when opening + connections. + + * TCP delayed ACKs were not sent correctly. + + * Explicit initialization of BSS segment variables. + + * read() in BSD socket library could drop data. + + * Problems with memory alignment. + + * Situations when all TCP buffers were used could lead to + starvation. + + * TCP MSS option wasn't parsed correctly. + + * Problems with UDP checksum calculation. + + * IP multicast address tests had endianess problems. + + * ARP requests had wrong destination hardware address. + + ++ Other changes: + + * struct eth_addr changed from u16_t[3] array to u8_t[6]. + + * A ->linkoutput() member was added to struct netif. + + * TCP and UDP ->dest_* struct members where changed to ->remote_*. + + * ntoh* macros are now null definitions for big endian CPUs. + +(0.5.0) Changes since version 0.4.2 + + ++ New features: + + * Redesigned operating system emulation layer to make porting easier. + + * Better control over TCP output buffers. + + * Documenation added. + + ++ Bugfixes: + + * Locking issues in buffer management. + + * Bugfixes in the sequential API. + + * IP forwarding could cause memory leakage. This has been fixed. + + ++ Other changes: + + * Directory structure somewhat changed; the core/ tree has been + collapsed. + +(0.4.2) Changes since version 0.4.1 + + ++ New features: + + * Experimental ARP implementation added. + + * Skeleton Ethernet driver added. + + * Experimental BSD socket API library added. + + ++ Bugfixes: + + * In very intense situations, memory leakage could occur. This has + been fixed. + + ++ Other changes: + + * Variables named "data" and "code" have been renamed in order to + avoid name conflicts in certain compilers. + + * Variable++ have in appliciable cases been translated to ++variable + since some compilers generate better code in the latter case. + +(0.4.1) Changes since version 0.4 + + ++ New features: + + * TCP: Connection attempts time out earlier than data + transmissions. Nagle algorithm implemented. Push flag set on the + last segment in a burst. + + * UDP: experimental support for UDP-Lite extensions. + + ++ Bugfixes: + + * TCP: out of order segments were in some cases handled incorrectly, + and this has now been fixed. Delayed acknowledgements was broken + in 0.4, has now been fixed. Binding to an address that is in use + now results in an error. Reset connections sometimes hung an + application; this has been fixed. + + * Checksum calculation sometimes failed for chained pbufs with odd + lengths. This has been fixed. + + * API: a lot of bug fixes in the API. The UDP API has been improved + and tested. Error reporting and handling has been + improved. Logical flaws and race conditions for incoming TCP + connections has been found and removed. + + * Memory manager: alignment issues. Reallocating memory sometimes + failed, this has been fixed. + + * Generic library: bcopy was flawed and has been fixed. + + ++ Other changes: + + * API: all datatypes has been changed from generic ones such as + ints, to specified ones such as u16_t. Functions that return + errors now have the correct type (err_t). + + * General: A lot of code cleaned up and debugging code removed. Many + portability issues have been fixed. + + * The license was changed; the advertising clause was removed. + + * C64 port added. + + * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri + Kosunen, Mikael Caleres, and Frits Wilmink for reporting and + fixing bugs! + +(0.4) Changes since version 0.3.1 + + * Memory management has been radically changed; instead of + allocating memory from a shared heap, memory for objects that are + rapidly allocated and deallocated is now kept in pools. Allocation + and deallocation from those memory pools is very fast. The shared + heap is still present but is used less frequently. + + * The memory, memory pool, and packet buffer subsystems now support + 4-, 2-, or 1-byte alignment. + + * "Out of memory" situations are handled in a more robust way. + + * Stack usage has been reduced. + + * Easier configuration of lwIP parameters such as memory usage, + TTLs, statistics gathering, etc. All configuration parameters are + now kept in a single header file "lwipopts.h". + + * The directory structure has been changed slightly so that all + architecture specific files are kept under the src/arch + hierarchy. + + * Error propagation has been improved, both in the protocol modules + and in the API. + + * The code for the RTXC architecture has been implemented, tested + and put to use. + + * Bugs have been found and corrected in the TCP, UDP, IP, API, and + the Internet checksum modules. + + * Bugs related to porting between a 32-bit and a 16-bit architecture + have been found and corrected. + + * The license has been changed slightly to conform more with the + original BSD license, including the advertisement clause. + +(0.3.1) Changes since version 0.3 + + * Fix of a fatal bug in the buffer management. Pbufs with allocated + RAM never returned the RAM when the pbuf was deallocated. + + * TCP congestion control, window updates and retransmissions did not + work correctly. This has now been fixed. + + * Bugfixes in the API. + +(0.3) Changes since version 0.2 + + * New and improved directory structure. All include files are now + kept in a dedicated include/ directory. + + * The API now has proper error handling. A new function, + netconn_err(), now returns an error code for the connection in + case of errors. + + * Improvements in the memory management subsystem. The system now + keeps a pointer to the lowest free memory block. A new function, + mem_malloc2() tries to allocate memory once, and if it fails tries + to free some memory and retry the allocation. + + * Much testing has been done with limited memory + configurations. lwIP now does a better job when overloaded. + + * Some bugfixes and improvements to the buffer (pbuf) subsystem. + + * Many bugfixes in the TCP code: + + - Fixed a bug in tcp_close(). + + - The TCP receive window was incorrectly closed when out of + sequence segments was received. This has been fixed. + + - Connections are now timed-out of the FIN-WAIT-2 state. + + - The initial congestion window could in some cases be too + large. This has been fixed. + + - The retransmission queue could in some cases be screwed up. This + has been fixed. + + - TCP RST flag now handled correctly. + + - Out of sequence data was in some cases never delivered to the + application. This has been fixed. + + - Retransmitted segments now contain the correct acknowledgment + number and advertised window. + + - TCP retransmission timeout backoffs are not correctly computed + (ala BSD). After a number of retransmissions, TCP now gives up + the connection. + + * TCP connections now are kept on three lists, one for active + connections, one for listening connections, and one for + connections that are in TIME-WAIT. This greatly speeds up the fast + timeout processing for sending delayed ACKs. + + * TCP now provides proper feedback to the application when a + connection has been successfully set up. + + * More comments have been added to the code. The code has also been + somewhat cleaned up. + +(0.2) Initial public release. diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/COPYING b/USDK/component/common/network/lwip/lwip_v1.4.1/COPYING new file mode 100644 index 0000000..e23898b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/COPYING @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/FILES b/USDK/component/common/network/lwip/lwip_v1.4.1/FILES new file mode 100644 index 0000000..6625319 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/FILES @@ -0,0 +1,4 @@ +src/ - The source code for the lwIP TCP/IP stack. +doc/ - The documentation for lwIP. + +See also the FILES file in each subdirectory. diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/README b/USDK/component/common/network/lwip/lwip_v1.4.1/README new file mode 100644 index 0000000..a62cc4f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/README @@ -0,0 +1,89 @@ +INTRODUCTION + +lwIP is a small independent implementation of the TCP/IP protocol +suite that has been developed by Adam Dunkels at the Computer and +Networks Architectures (CNA) lab at the Swedish Institute of Computer +Science (SICS). + +The focus of the lwIP TCP/IP implementation is to reduce the RAM usage +while still having a full scale TCP. This making lwIP suitable for use +in embedded systems with tens of kilobytes of free RAM and room for +around 40 kilobytes of code ROM. + +FEATURES + + * IP (Internet Protocol) including packet forwarding over multiple network + interfaces + * ICMP (Internet Control Message Protocol) for network maintenance and debugging + * IGMP (Internet Group Management Protocol) for multicast traffic management + * UDP (User Datagram Protocol) including experimental UDP-lite extensions + * TCP (Transmission Control Protocol) with congestion control, RTT estimation + and fast recovery/fast retransmit + * Specialized raw/native API for enhanced performance + * Optional Berkeley-like socket API + * DNS (Domain names resolver) + * SNMP (Simple Network Management Protocol) + * DHCP (Dynamic Host Configuration Protocol) + * AUTOIP (for IPv4, conform with RFC 3927) + * PPP (Point-to-Point Protocol) + * ARP (Address Resolution Protocol) for Ethernet + +LICENSE + +lwIP is freely available under a BSD license. + +DEVELOPMENT + +lwIP has grown into an excellent TCP/IP stack for embedded devices, +and developers using the stack often submit bug fixes, improvements, +and additions to the stack to further increase its usefulness. + +Development of lwIP is hosted on Savannah, a central point for +software development, maintenance and distribution. Everyone can +help improve lwIP by use of Savannah's interface, CVS and the +mailing list. A core team of developers will commit changes to the +CVS source tree. + +The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and +contributions (such as platform ports) are in the 'contrib' module. + +See doc/savannah.txt for details on CVS server access for users and +developers. + +Last night's CVS tar ball can be downloaded from: + http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING] + +The current CVS trees are web-browsable: + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/ + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/ + +Submit patches and bugs via the lwIP project page: + http://savannah.nongnu.org/projects/lwip/ + + +DOCUMENTATION + +The original out-dated homepage of lwIP and Adam Dunkels' papers on +lwIP are at the official lwIP home page: + http://www.sics.se/~adam/lwip/ + +Self documentation of the source code is regularly extracted from the +current CVS sources and is available from this web page: + http://www.nongnu.org/lwip/ + +There is now a constantly growin wiki about lwIP at + http://lwip.wikia.com/wiki/LwIP_Wiki + +Also, there are mailing lists you can subscribe at + http://savannah.nongnu.org/mail/?group=lwip +plus searchable archives: + http://lists.nongnu.org/archive/html/lwip-users/ + http://lists.nongnu.org/archive/html/lwip-devel/ + +Reading Adam's papers, the files in docs/, browsing the source code +documentation and browsing the mailing list archives is a good way to +become familiar with the design of lwIP. + +Adam Dunkels +Leon Woestenberg + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/UPGRADING b/USDK/component/common/network/lwip/lwip_v1.4.1/UPGRADING new file mode 100644 index 0000000..6501107 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/UPGRADING @@ -0,0 +1,144 @@ +This file lists major changes between release versions that require +ports or applications to be changed. Use it to update a port or an +application written for an older version of lwIP to correctly work +with newer versions. + + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ Application changes: + + * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for + compatibility to old applications, but will be removed in the future). + + * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() + + +++ Raw API: + * Changed the semantics of tcp_close() (since it was rather a + shutdown before): Now the application does *NOT* get any calls to the recv + callback (aside from NULL/closed) after calling tcp_close() + + * When calling tcp_abort() from a raw API TCP callback function, + make sure you return ERR_ABRT to prevent accessing unallocated memory. + (ERR_ABRT now means the applicaiton has called tcp_abort!) + + +++ Netconn API: + * Changed netconn_receive() and netconn_accept() to return + err_t, not a pointer to new data/netconn. + + +++ Socket API: + * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they + now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. + + * Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + +++ all APIs: + * correctly implemented SO(F)_REUSEADDR + + ++ Port changes + + +++ new files: + + * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: + + * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains + the actual application programmer's API + + * Separated timer implementation from sys.h/.c, moved to timers.h/.c; + Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you + still want to use your own timer implementation for NO_SYS==0 (as before). + + +++ sys layer: + + * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ + sys_sem_t; + + * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + + * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use + binary semaphores instead of mutexes - as before) + + +++ new options: + + * Don't waste memory when chaining segments, added option TCP_OVERSIZE to + prevent creating many small pbufs when calling tcp_write with many small + blocks of data. Instead, pbufs are allocated larger than needed and the + space is used for later calls to tcp_write. + + * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs + in tcp_write/udp_send. + + * Added an additional option LWIP_ETHERNET to support ethernet without ARP + (necessary for pure PPPoE) + + * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may + be used to place these pools into user-defined memory by using external + declaration. + + * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT + + +++ new pools: + + * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, + so MEMP_NUM_NETDB has to be set accordingly. + + * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so + MEMP_NUM_LOCALHOSTLIST has to be set accordingly. + + * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have + to be set accordingly. + + * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES + has to be set accordingly + + * Integrated loopif into netif.c - loopif does not have to be created by the + port any more, just define LWIP_HAVE_LOOPIF to 1. + + * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined + in cc.h, e.g. used by igmp) + + * Added printf-formatter X8_F to printf u8_t as hex + + * The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + + * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work + with user-allocated structs instead of calling mem_malloc + + * Added const char* name to mem- and memp-stats for easier debugging. + + * Calculate the TCP/UDP checksum while copying to only fetch data once: + Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum + + * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to + more than one pcb. + + * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned + off any more, if this is set to 0, only one packet (the most recent one) is + queued (like demanded by RFC 1122). + + + ++ Major bugfixes/improvements + + * Implemented tcp_shutdown() to only shut down one end of a connection + * Implemented shutdown() at socket- and netconn-level + * Added errorset support to select() + improved select speed overhead + * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) + * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 + * Use macros defined in ip_addr.h to work with IP addresses + * Implemented many nonblocking socket/netconn functions + * Fixed ARP input processing: only add a new entry if a request was directed as us + * mem_realloc() to mem_trim() to prevent confusion with realloc() + * Some improvements for AutoIP (don't route/forward link-local addresses, don't break + existing connections when assigning a routable address) + * Correctly handle remote side overrunning our rcv_wnd in ooseq case + * Removed packing from ip_addr_t, the packed version is now only used in protocol headers + * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 + * Added support for static ARP table entries + +(STABLE-1.3.2) + + * initial version of this file diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/FILES b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/FILES new file mode 100644 index 0000000..05d356f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/FILES @@ -0,0 +1,6 @@ +savannah.txt - How to obtain the current development source code. +contrib.txt - How to contribute to lwIP as a developer. +rawapi.txt - The documentation for the core API of lwIP. + Also provides an overview about the other APIs and multithreading. +snmp_agent.txt - The documentation for the lwIP SNMP agent. +sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/contrib.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/contrib.txt new file mode 100644 index 0000000..39596fc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/contrib.txt @@ -0,0 +1,63 @@ +1 Introduction + +This document describes some guidelines for people participating +in lwIP development. + +2 How to contribute to lwIP + +Here is a short list of suggestions to anybody working with lwIP and +trying to contribute bug reports, fixes, enhancements, platform ports etc. +First of all as you may already know lwIP is a volunteer project so feedback +to fixes or questions might often come late. Hopefully the bug and patch tracking +features of Savannah help us not lose users' input. + +2.1 Source code style: + +1. do not use tabs. +2. indentation is two spaces per level (i.e. per tab). +3. end debug messages with a trailing newline (\n). +4. one space between keyword and opening bracket. +5. no space between function and opening bracket. +6. one space and no newline before opening curly braces of a block. +7. closing curly brace on a single line. +8. spaces surrounding assignment and comparisons. +9. don't initialize static and/or global variables to zero, the compiler takes care of that. +10. use current source code style as further reference. + +2.2 Source code documentation style: + +1. JavaDoc compliant and Doxygen compatible. +2. Function documentation above functions in .c files, not .h files. + (This forces you to synchronize documentation and implementation.) +3. Use current documentation style as further reference. + +2.3 Bug reports and patches: + +1. Make sure you are reporting bugs or send patches against the latest + sources. (From the latest release and/or the current CVS sources.) +2. If you think you found a bug make sure it's not already filed in the + bugtracker at Savannah. +3. If you have a fix put the patch on Savannah. If it is a patch that affects + both core and arch specific stuff please separate them so that the core can + be applied separately while leaving the other patch 'open'. The prefered way + is to NOT touch archs you can't test and let maintainers take care of them. + This is a good way to see if they are used at all - the same goes for unix + netifs except tapif. +4. Do not file a bug and post a fix to it to the patch area. Either a bug report + or a patch will be enough. + If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. +5. Trivial patches (compiler warning, indentation and spelling fixes or anything obvious which takes a line or two) + can go to the lwip-users list. This is still the fastest way of interaction and the list is not so crowded + as to allow for loss of fixes. Putting bugs on Savannah and subsequently closing them is too much an overhead + for reporting a compiler warning fix. +6. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other + trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you + change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than + if it's not to the point and long :) so the chances for it to be applied are greater. + +2.4 Platform porters: + +1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and + you think it could benefit others[1] you might want discuss this on the mailing list. You + can also ask for CVS access to submit and maintain your port in the contrib CVS module. + \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/rawapi.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/rawapi.txt new file mode 100644 index 0000000..8c19030 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/rawapi.txt @@ -0,0 +1,511 @@ +Raw TCP/IP interface for lwIP + +Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons + +lwIP provides three Application Program's Interfaces (APIs) for programs +to use for communication with the TCP/IP code: +* low-level "core" / "callback" or "raw" API. +* higher-level "sequential" API. +* BSD-style socket API. + +The sequential API provides a way for ordinary, sequential, programs +to use the lwIP stack. It is quite similar to the BSD socket API. The +model of execution is based on the blocking open-read-write-close +paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP +code and the application program must reside in different execution +contexts (threads). + +The socket API is a compatibility API for existing applications, +currently it is built on top of the sequential API. It is meant to +provide all functions needed to run socket API applications running +on other platforms (e.g. unix / windows etc.). However, due to limitations +in the specification of this API, there might be incompatibilities +that require small modifications of existing programs. + +** Threading + +lwIP started targeting single-threaded environments. When adding multi- +threading support, instead of making the core thread-safe, another +approach was chosen: there is one main thread running the lwIP core +(also known as the "tcpip_thread"). The raw API may only be used from +this thread! Application threads using the sequential- or socket API +communicate with this main thread through message passing. + + As such, the list of functions that may be called from + other threads or an ISR is very limited! Only functions + from these API header files are thread-safe: + - api.h + - netbuf.h + - netdb.h + - netifapi.h + - sockets.h + - sys.h + + Additionaly, memory (de-)allocation functions may be + called from multiple threads (not ISR!) with NO_SYS=0 + since they are protected by SYS_LIGHTWEIGHT_PROT and/or + semaphores. + + Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 + and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + pbuf_free() may also be called from another thread or + an ISR (since only then, mem_free - for PBUF_RAM - may + be called from an ISR: otherwise, the HEAP is only + protected by semaphores). + + +** The remainder of this document discusses the "raw" API. ** + +The raw TCP/IP interface allows the application program to integrate +better with the TCP/IP code. Program execution is event based by +having callback functions being called from within the TCP/IP +code. The TCP/IP code and the application program both run in the same +thread. The sequential API has a much higher overhead and is not very +well suited for small systems since it forces a multithreaded paradigm +on the application. + +The raw TCP/IP interface is not only faster in terms of code execution +time but is also less memory intensive. The drawback is that program +development is somewhat harder and application programs written for +the raw TCP/IP interface are more difficult to understand. Still, this +is the preferred way of writing applications that should be small in +code size and memory usage. + +Both APIs can be used simultaneously by different application +programs. In fact, the sequential API is implemented as an application +program using the raw TCP/IP interface. + +--- Callbacks + +Program execution is driven by callbacks. Each callback is an ordinary +C function that is called from within the TCP/IP code. Every callback +function is passed the current TCP or UDP connection state as an +argument. Also, in order to be able to keep program specific state, +the callback functions are called with a program specified argument +that is independent of the TCP/IP state. + +The function for setting the application connection state is: + +- void tcp_arg(struct tcp_pcb *pcb, void *arg) + + Specifies the program specific state that should be passed to all + other callback functions. The "pcb" argument is the current TCP + connection control block, and the "arg" argument is the argument + that will be passed to the callbacks. + + +--- TCP connection setup + +The functions used for setting up connections is similar to that of +the sequential API and of the BSD socket API. A new TCP connection +identifier (i.e., a protocol control block - PCB) is created with the +tcp_new() function. This PCB can then be either set to listen for new +incoming connections or be explicitly connected to another host. + +- struct tcp_pcb *tcp_new(void) + + Creates a new connection identifier (PCB). If memory is not + available for creating the new pcb, NULL is returned. + +- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local IP address and port number. The IP address + can be specified as IP_ADDR_ANY in order to bind the connection to + all local IP addresses. + + If another connection is bound to the same port, the function will + return ERR_USE, otherwise ERR_OK is returned. + +- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) + + Commands a pcb to start listening for incoming connections. When an + incoming connection is accepted, the function specified with the + tcp_accept() function will be called. The pcb will have to be bound + to a local port with the tcp_bind() function. + + The tcp_listen() function returns a new connection identifier, and + the one passed as an argument to the function will be + deallocated. The reason for this behavior is that less memory is + needed for a connection that is listening, so tcp_listen() will + reclaim the memory needed for the original connection and allocate a + new smaller memory block for the listening connection. + + tcp_listen() may return NULL if no memory was available for the + listening connection. If so, the memory associated with the pcb + passed as an argument to tcp_listen() will not be deallocated. + +- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) + + Same as tcp_listen, but limits the number of outstanding connections + in the listen queue to the value specified by the backlog argument. + To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. + +- void tcp_accepted(struct tcp_pcb *pcb) + + Inform lwIP that an incoming connection has been accepted. This would + usually be called from the accept callback. This allows lwIP to perform + housekeeping tasks, such as allowing further incoming connections to be + queued in the listen backlog. + ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed + into the accept callback! + +- void tcp_accept(struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, + err_t err)) + + Specified the callback function that should be called when a new + connection arrives on a listening connection. + +- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, err_t (* connected)(void *arg, + struct tcp_pcb *tpcb, + err_t err)); + + Sets up the pcb to connect to the remote host and sends the + initial SYN segment which opens the connection. + + The tcp_connect() function returns immediately; it does not wait for + the connection to be properly setup. Instead, it will call the + function specified as the fourth argument (the "connected" argument) + when the connection is established. If the connection could not be + properly established, either because the other host refused the + connection or because the other host didn't answer, the "err" + callback function of this pcb (registered with tcp_err, see below) + will be called. + + The tcp_connect() function can return ERR_MEM if no memory is + available for enqueueing the SYN segment. If the SYN indeed was + enqueued successfully, the tcp_connect() function returns ERR_OK. + + +--- Sending TCP data + +TCP data is sent by enqueueing the data with a call to +tcp_write(). When the data is successfully transmitted to the remote +host, the application will be notified with a call to a specified +callback function. + +- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags) + + Enqueues the data pointed to by the argument dataptr. The length of + the data is passed as the len parameter. The apiflags can be one or more of: + - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated + for the data to be copied into. If this flag is not given, no new memory + should be allocated and the data should only be referenced by pointer. This + also means that the memory behind dataptr must not change until the data is + ACKed by the remote host + - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given, + the PSH flag is set in the last segment created by this call to tcp_write. + If this flag is given, the PSH flag is not set. + + The tcp_write() function will fail and return ERR_MEM if the length + of the data exceeds the current send buffer size or if the length of + the queue of outgoing segment is larger than the upper limit defined + in lwipopts.h. The number of bytes available in the output queue can + be retrieved with the tcp_sndbuf() function. + + The proper way to use this function is to call the function with at + most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, + the application should wait until some of the currently enqueued + data has been successfully received by the other host and try again. + +- void tcp_sent(struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, + u16_t len)) + + Specifies the callback function that should be called when data has + successfully been received (i.e., acknowledged) by the remote + host. The len argument passed to the callback function gives the + amount bytes that was acknowledged by the last acknowledgment. + + +--- Receiving TCP data + +TCP data reception is callback based - an application specified +callback function is called when new data arrives. When the +application has taken the data, it has to call the tcp_recved() +function to indicate that TCP can advertise increase the receive +window. + +- void tcp_recv(struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err)) + + Sets the callback function that will be called when new data + arrives. The callback function will be passed a NULL pbuf to + indicate that the remote host has closed the connection. If + there are no errors and the callback function is to return + ERR_OK, then it must free the pbuf. Otherwise, it must not + free the pbuf so that lwIP core code can store it. + +- void tcp_recved(struct tcp_pcb *pcb, u16_t len) + + Must be called when the application has received the data. The len + argument indicates the length of the received data. + + +--- Application polling + +When a connection is idle (i.e., no data is either transmitted or +received), lwIP will repeatedly poll the application by calling a +specified callback function. This can be used either as a watchdog +timer for killing connections that have stayed idle for too long, or +as a method of waiting for memory to become available. For instance, +if a call to tcp_write() has failed because memory wasn't available, +the application may use the polling functionality to call tcp_write() +again when the connection has been idle for a while. + +- void tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval) + + Specifies the polling interval and the callback function that should + be called to poll the application. The interval is specified in + number of TCP coarse grained timer shots, which typically occurs + twice a second. An interval of 10 means that the application would + be polled every 5 seconds. + + +--- Closing and aborting connections + +- err_t tcp_close(struct tcp_pcb *pcb) + + Closes the connection. The function may return ERR_MEM if no memory + was available for closing the connection. If so, the application + should wait and try again either by using the acknowledgment + callback or the polling functionality. If the close succeeds, the + function returns ERR_OK. + + The pcb is deallocated by the TCP code after a call to tcp_close(). + +- void tcp_abort(struct tcp_pcb *pcb) + + Aborts the connection by sending a RST (reset) segment to the remote + host. The pcb is deallocated. This function never fails. + + ATTENTION: When calling this from one of the TCP callbacks, make + sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + or you will risk accessing deallocated memory or memory leaks! + + +If a connection is aborted because of an error, the application is +alerted of this event by the err callback. Errors that might abort a +connection are when there is a shortage of memory. The callback +function to be called is set using the tcp_err() function. + +- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, + err_t err)) + + The error callback function does not get the pcb passed to it as a + parameter since the pcb may already have been deallocated. + + +--- Lower layer TCP interface + +TCP provides a simple interface to the lower layers of the +system. During system initialization, the function tcp_init() has +to be called before any other TCP function is called. When the system +is running, the two timer functions tcp_fasttmr() and tcp_slowtmr() +must be called with regular intervals. The tcp_fasttmr() should be +called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and +tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. + + +--- UDP interface + +The UDP interface is similar to that of TCP, but due to the lower +level of complexity of UDP, the interface is significantly simpler. + +- struct udp_pcb *udp_new(void) + + Creates a new UDP pcb which can be used for UDP communication. The + pcb is not active until it has either been bound to a local address + or connected to a remote address. + +- void udp_remove(struct udp_pcb *pcb) + + Removes and deallocates the pcb. + +- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local address. The IP-address argument "ipaddr" + can be IP_ADDR_ANY to indicate that it should listen to any local IP + address. The function currently always return ERR_OK. + +- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Sets the remote end of the pcb. This function does not generate any + network traffic, but only set the remote address of the pcb. + +- err_t udp_disconnect(struct udp_pcb *pcb) + + Remove the remote end of the pcb. This function does not generate + any network traffic, but only removes the remote address of the pcb. + +- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) + + Sends the pbuf p. The pbuf is not deallocated. + +- void udp_recv(struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, + struct pbuf *p, + ip_addr_t *addr, + u16_t port), + void *recv_arg) + + Specifies a callback function that should be called when a UDP + datagram is received. + + +--- System initalization + +A truly complete and generic sequence for initializing the lwip stack +cannot be given because it depends on the build configuration (lwipopts.h) +and additional initializations for your runtime environment (e.g. timers). + +We can give you some idea on how to proceed when using the raw API. +We assume a configuration using a single Ethernet netif and the +UDP and TCP transport layers, IPv4 and the DHCP client. + +Call these functions in the order of appearance: + +- stats_init() + + Clears the structure where runtime statistics are gathered. + +- sys_init() + + Not of much use since we set the NO_SYS 1 option in lwipopts.h, + to be called for easy configuration changes. + +- mem_init() + + Initializes the dynamic memory heap defined by MEM_SIZE. + +- memp_init() + + Initializes the memory pools defined by MEMP_NUM_x. + +- pbuf_init() + + Initializes the pbuf memory pool defined by PBUF_POOL_SIZE. + +- etharp_init() + + Initializes the ARP table and queue. + Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval + after this initialization. + +- ip_init() + + Doesn't do much, it should be called to handle future changes. + +- udp_init() + + Clears the UDP PCB list. + +- tcp_init() + + Clears the TCP PCB list and clears some internal TCP timers. + Note: you must call tcp_fasttmr() and tcp_slowtmr() at the + predefined regular intervals after this initialization. + +- netif_add(struct netif *netif, ip_addr_t *ipaddr, + ip_addr_t *netmask, ip_addr_t *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use. + + err_t netif_if_init(struct netif *netif) + { + u8_t i; + + for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i]; + init_my_eth_device(); + return ERR_OK; + } + + For ethernet drivers, the input function pointer must point to the lwip + function ethernet_input() declared in "netif/etharp.h". Other drivers + must use ip_input() declared in "lwip/ip.h". + +- netif_set_default(struct netif *netif) + + Registers the default network interface. + +- netif_set_up(struct netif *netif) + + When the netif is fully configured this function must be called. + +- dhcp_start(struct netif *netif) + + Creates a new DHCP client for this interface on the first call. + Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + the predefined regular intervals after starting the client. + + You can peek in the netif->dhcp struct for the actual DHCP status. + + +--- Optimalization hints + +The first thing you want to optimize is the lwip_standard_checksum() +routine from src/core/inet.c. You can override this standard +function with the #define LWIP_CHKSUM . + +There are C examples given in inet.c or you might want to +craft an assembly function for this. RFC1071 is a good +introduction to this subject. + +Other significant improvements can be made by supplying +assembly or inline replacements for htons() and htonl() +if you're using a little-endian architecture. +#define LWIP_PLATFORM_BYTESWAP 1 +#define LWIP_PLATFORM_HTONS(x) +#define LWIP_PLATFORM_HTONL(x) + +Check your network interface driver if it reads at +a higher speed than the maximum wire-speed. If the +hardware isn't serviced frequently and fast enough +buffer overflows are likely to occur. + +E.g. when using the cs8900 driver, call cs8900if_service(ethif) +as frequently as possible. When using an RTOS let the cs8900 interrupt +wake a high priority task that services your driver using a binary +semaphore or event flag. Some drivers might allow additional tuning +to match your application and network. + +For a production release it is recommended to set LWIP_STATS to 0. +Note that speed performance isn't influenced much by simply setting +high values to the memory options. + +For more optimization hints take a look at the lwIP wiki. + +--- Zero-copy MACs + +To achieve zero-copy on transmit, the data passed to the raw API must +remain unchanged until sent. Because the send- (or write-)functions return +when the packets have been enqueued for sending, data must be kept stable +after that, too. + +This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions +must *not* be reused by the application unless their ref-count is 1. + +For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too, +but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while +PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change). + +Also, data passed to tcp_write without the copy-flag must not be changed! + +Therefore, be careful which type of PBUF you use and if you copy TCP data +or not! diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/savannah.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/savannah.txt new file mode 100644 index 0000000..409905b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/savannah.txt @@ -0,0 +1,135 @@ +Daily Use Guide for using Savannah for lwIP + +Table of Contents: + +1 - Obtaining lwIP from the CVS repository +2 - Committers/developers CVS access using SSH (to be written) +3 - Merging from DEVEL branch to main trunk (stable branch) +4 - How to release lwIP + + + +1 Obtaining lwIP from the CVS repository +---------------------------------------- + +To perform an anonymous CVS checkout of the main trunk (this is where +bug fixes and incremental enhancements occur), do this: + +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip + +Or, obtain a stable branch (updated with bug fixes only) as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7 -d lwip-0.7 lwip + +Or, obtain a specific (fixed) release as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7_0 -d lwip-0.7.0 lwip + +3 Committers/developers CVS access using SSH +-------------------------------------------- + +The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. +As such, CVS commits to the server occur through a SSH tunnel for project members. +To create a SSH2 key pair in UNIX-like environments, do this: + +ssh-keygen -t dsa + +Under Windows, a recommended SSH client is "PuTTY", freely available with good +documentation and a graphic user interface. Use its key generator. + +Now paste the id_dsa.pub contents into your Savannah account public key list. Wait +a while so that Savannah can update its configuration (This can take minutes). + +Try to login using SSH: + +ssh -v your_login@cvs.sv.gnu.org + +If it tells you: + +Authenticating with public key "your_key_name"... +Server refused to allocate pty + +then you could login; Savannah refuses to give you a shell - which is OK, as we +are allowed to use SSH for CVS only. Now, you should be able to do this: + +export CVS_RSH=ssh +cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip + +after which you can edit your local files with bug fixes or new features and +commit them. Make sure you know what you are doing when using CVS to make +changes on the repository. If in doubt, ask on the lwip-members mailing list. + +(If SSH asks about authenticity of the host, you can check the key + fingerprint against http://savannah.nongnu.org/cvs/?group=lwip) + + +3 Merging from DEVEL branch to main trunk (stable) +-------------------------------------------------- + +Merging is a delicate process in CVS and requires the +following disciplined steps in order to prevent conflicts +in the future. Conflicts can be hard to solve! + +Merging from branch A to branch B requires that the A branch +has a tag indicating the previous merger. This tag is called +'merged_from_A_to_B'. After merging, the tag is moved in the +A branch to remember this merger for future merge actions. + +IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE +REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE +MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME). + +Merge all changes in DEVEL since our last merge to main: + +In the working copy of the main trunk: +cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL + +(This will apply the changes between 'merged_from_DEVEL_to_main' +and 'DEVEL' to your work set of files) + +We can now commit the merge result. +cvs commit -R -m "Merged from DEVEL to main." + +If this worked out OK, we now move the tag in the DEVEL branch +to this merge point, so we can use this point for future merges: + +cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip + +4 How to release lwIP +--------------------- + +First, checkout a clean copy of the branch to be released. Tag this set with +tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example). + +Login CVS using pserver authentication, then export a clean copy of the +tagged tree. Export is similar to a checkout, except that the CVS metadata +is not created locally. + +export CVS_RSH=ssh +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_6_3 -d lwip-0.6.3 lwip + +Archive this directory using tar, gzip'd, bzip2'd and zip'd. + +tar czvf lwip-0.6.3.tar.gz lwip-0.6.3 +tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3 +zip -r lwip-0.6.3.zip lwip-0.6.3 + +Now, sign the archives with a detached GPG binary signature as follows: + +gpg -b lwip-0.6.3.tar.gz +gpg -b lwip-0.6.3.tar.bz2 +gpg -b lwip-0.6.3.zip + +Upload these files using anonymous FTP: +ncftp ftp://savannah.gnu.org/incoming/savannah/lwip + +ncftp>mput *0.6.3.* + +Additionally, you may post a news item on Savannah, like this: + +A new 0.6.3 release is now available here: +http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 + +You will have to submit this via the user News interface, then approve +this via the Administrator News interface. \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/snmp_agent.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/snmp_agent.txt new file mode 100644 index 0000000..2653230 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/snmp_agent.txt @@ -0,0 +1,181 @@ +SNMPv1 agent for lwIP + +Author: Christiaan Simons + +This is a brief introduction how to use and configure the SNMP agent. +Note the agent uses the raw-API UDP interface so you may also want to +read rawapi.txt to gain a better understanding of the SNMP message handling. + +0 Agent Capabilities +==================== + +SNMPv1 per RFC1157 + This is an old(er) standard but is still widely supported. + For SNMPv2c and v3 have a greater complexity and need many + more lines of code. IMHO this breaks the idea of "lightweight IP". + + Note the S in SNMP stands for "Simple". Note that "Simple" is + relative. SNMP is simple compared to the complex ISO network + management protocols CMIP (Common Management Information Protocol) + and CMOT (CMip Over Tcp). + +MIB II per RFC1213 + The standard lwIP stack management information base. + This is a required MIB, so this is always enabled. + When builing lwIP without TCP, the mib-2.tcp group is omitted. + The groups EGP, CMOT and transmission are disabled by default. + + Most mib-2 objects are not writable except: + sysName, sysLocation, sysContact, snmpEnableAuthenTraps. + Writing to or changing the ARP and IP address and route + tables is not possible. + + Note lwIP has a very limited notion of IP routing. It currently + doen't have a route table and doesn't have a notion of the U,G,H flags. + Instead lwIP uses the interface list with only one default interface + acting as a single gateway interface (G) for the default route. + + The agent returns a "virtual table" with the default route 0.0.0.0 + for the default interface and network routes (no H) for each + network interface in the netif_list. + All routes are considered to be up (U). + +Loading additional MIBs + MIBs can only be added in compile-time, not in run-time. + There is no MIB compiler thus additional MIBs must be hand coded. + +Large SNMP message support + The packet decoding and encoding routines are designed + to use pbuf-chains. Larger payloads than the minimum + SNMP requirement of 484 octets are supported if the + PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your + local requirement. + +1 Building the Agent +==================== + +First of all you'll need to add the following define +to your local lwipopts.h: + +#define LWIP_SNMP 1 + +and add the source files in lwip/src/core/snmp +and some snmp headers in lwip/src/include/lwip to your makefile. + +Note you'll might need to adapt you network driver to update +the mib2 variables for your interface. + +2 Running the Agent +=================== + +The following function calls must be made in your program to +actually get the SNMP agent running. + +Before starting the agent you should supply pointers +to non-volatile memory for sysContact, sysLocation, +and snmpEnableAuthenTraps. You can do this by calling + +snmp_set_syscontact() +snmp_set_syslocation() +snmp_set_snmpenableauthentraps() + +Additionally you may want to set + +snmp_set_sysdescr() +snmp_set_sysobjid() (if you have a private MIB) +snmp_set_sysname() + +Also before starting the agent you need to setup +one or more trap destinations using these calls: + +snmp_trap_dst_enable(); +snmp_trap_dst_ip_set(); + +In the lwIP initialisation sequence call snmp_init() just after +the call to udp_init(). + +Exactly every 10 msec the SNMP uptime timestamp must be updated with +snmp_inc_sysuptime(). You should call this from a timer interrupt +or a timer signal handler depending on your runtime environment. + +An alternative way to update the SNMP uptime timestamp is to do a call like +snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to +a lower frequency). Another one is to not call snmp_inc_sysuptime() or +snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. +This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside +snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only +when it's queried (any function which need "sysuptime" have to call +snmp_get_sysuptime). + + +3 Private MIBs +============== + +If want to extend the agent with your own private MIB you'll need to +add the following define to your local lwipopts.h: + +#define SNMP_PRIVATE_MIB 1 + +You must provide the private_mib.h and associated files yourself. +Note we don't have a "MIB compiler" that generates C source from a MIB, +so you're required to do some serious coding if you enable this! + +Note the lwIP enterprise ID (26381) is assigned to the lwIP project, +ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP +MAINTAINERS! + +If you need to create your own private MIB you'll need +to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html + +You can set it by passing a struct snmp_obj_id to the agent +using snmp_set_sysobjid(&my_object_id), just before snmp_init(). + +Note the object identifiers for thes MIB-2 and your private MIB +tree must be kept in sorted ascending (lexicographical) order. +This to ensure correct getnext operation. + +An example for a private MIB is part of the "minimal Unix" project: +contrib/ports/unix/proj/minimal/lwip_prvmib.c + +The next chapter gives a more detailed description of the +MIB-2 tree and the optional private MIB. + +4 The Gory Details +================== + +4.0 Object identifiers and the MIB tree. + +We have three distinct parts for all object identifiers: + +The prefix + .iso.org.dod.internet + +the middle part + .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress + +and the index part + .1.192.168.0.1 + +Objects located above the .internet hierarchy aren't supported. +Currently only the .mgmt sub-tree is available and +when the SNMP_PRIVATE_MIB is enabled the .private tree +becomes available too. + +Object identifiers from incoming requests are checked +for a matching prefix, middle part and index part +or are expanded(*) for GetNext requests with short +or inexisting names in the request. +(* we call this "expansion" but this also +resembles the "auto-completion" operation) + +The middle part is usually located in ROM (const) +to preserve precious RAM on small microcontrollers. +However RAM location is possible for a dynamically +changing private tree. + +The index part is handled by functions which in +turn use dynamically allocated index trees from RAM. +These trees are updated by e.g. the etharp code +when new entries are made or removed form the ARP cache. + +/** @todo more gory details */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/doc/sys_arch.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/sys_arch.txt new file mode 100644 index 0000000..847cd77 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/doc/sys_arch.txt @@ -0,0 +1,267 @@ +sys_arch interface for lwIP 0.6++ + +Author: Adam Dunkels + +The operating system emulation layer provides a common interface +between the lwIP code and the underlying operating system kernel. The +general idea is that porting lwIP to new architectures requires only +small changes to a few header files and a new sys_arch +implementation. It is also possible to do a sys_arch implementation +that does not rely on any underlying operating system. + +The sys_arch provides semaphores and mailboxes to lwIP. For the full +lwIP functionality, multiple threads support can be implemented in the +sys_arch, but this is not required for the basic lwIP +functionality. Previous versions of lwIP required the sys_arch to +implement timer scheduling as well but as of lwIP 0.5 this is +implemented in a higher layer. + +In addition to the source file providing the functionality of sys_arch, +the OS emulation layer must provide several header files defining +macros used throughout lwip. The files required and the macros they +must define are listed below the sys_arch description. + +Semaphores can be either counting or binary - lwIP works with both +kinds. Mailboxes are used for message passing and can be implemented +either as a queue which allows multiple messages to be posted to a +mailbox, or as a rendez-vous point where only one message can be +posted at a time. lwIP works with both kinds, but the former type will +be more efficient. A message in a mailbox is just a pointer, nothing +more. + +Semaphores are represented by the type "sys_sem_t" which is typedef'd +in the sys_arch.h file. Mailboxes are equivalently represented by the +type "sys_mbox_t". lwIP does not place any restrictions on how +sys_sem_t or sys_mbox_t are represented internally. + +Since lwIP 1.4.0, semaphore and mailbox functions are prototyped in a way that +allows both using pointers or actual OS structures to be used. This way, memory +required for such types can be either allocated in place (globally or on the +stack) or on the heap (allocated internally in the "*_new()" functions). + +The following functions must be implemented by the sys_arch: + +- void sys_init(void) + + Is called to initialize the sys_arch layer. + +- err_t sys_sem_new(sys_sem_t *sem, u8_t count) + + Creates a new semaphore. The semaphore is allocated to the memory that 'sem' + points to (which can be both a pointer or the actual OS structure). + The "count" argument specifies the initial state of the semaphore (which is + either 0 or 1). + If the semaphore has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_sem_free(sys_sem_t *sem) + + Deallocates a semaphore. + +- void sys_sem_signal(sys_sem_t *sem) + + Signals a semaphore. + +- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) + + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). If the "timeout" argument is zero, the thread should be + blocked until the semaphore is signalled. + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. + +- int sys_sem_valid(sys_sem_t *sem) + + Returns 1 if the semaphore is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_sem_set_invalid(sys_sem_t *sem) + + Invalidate a semaphore so that sys_sem_valid() returns 0. + ATTENTION: This does NOT mean that the semaphore shall be deallocated: + sys_sem_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +- err_t sys_mbox_new(sys_mbox_t *mbox, int size) + + Creates an empty mailbox for maximum "size" elements. Elements stored + in mailboxes are pointers. You have to define macros "_MBOX_SIZE" + in your lwipopts.h, or ignore this parameter in your implementation + and use a default size. + If the mailbox has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_mbox_free(sys_mbox_t *mbox) + + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. + +- void sys_mbox_post(sys_mbox_t *mbox, void *msg) + + Posts the "msg" to the mailbox. This function have to block until + the "msg" is really posted. + +- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one + is full, else, ERR_OK if the "msg" is posted. + +- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) + + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). If "timeout" is 0, the thread should + be blocked until a message arrives. The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. + +- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) + + This is similar to sys_arch_mbox_fetch, however if a message is not + present in the mailbox, it immediately returns with the code + SYS_MBOX_EMPTY. On success 0 is returned. + + To allow for efficient implementations, this can be defined as a + function-like macro in sys_arch.h instead of a normal function. For + example, a naive implementation could be: + #define sys_arch_mbox_tryfetch(mbox,msg) \ + sys_arch_mbox_fetch(mbox,msg,1) + although this would introduce unnecessary delays. + +- int sys_mbox_valid(sys_mbox_t *mbox) + + Returns 1 if the mailbox is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_mbox_set_invalid(sys_mbox_t *mbox) + + Invalidate a mailbox so that sys_mbox_valid() returns 0. + ATTENTION: This does NOT mean that the mailbox shall be deallocated: + sys_mbox_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +If threads are supported by the underlying operating system and if +such functionality is needed in lwIP, the following function will have +to be implemented as well: + +- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) + + Starts a new thread named "name" with priority "prio" that will begin its + execution in the function "thread()". The "arg" argument will be passed as an + argument to the thread() function. The stack size to used for this thread is + the "stacksize" parameter. The id of the new thread is returned. Both the id + and the priority are system dependent. + +- sys_prot_t sys_arch_protect(void) + + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. + +- void sys_arch_unprotect(sys_prot_t pval) + + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. + +For some configurations, you also need: + +- u32_t sys_now(void) + + This optional function returns the current time in milliseconds (don't care + for wraparound, this is only used for time diffs). + Not implementing this function means you cannot use some modules (e.g. TCP + timestamps, internal timeouts for NO_SYS==1). + + +Note: + +Be carefull with using mem_malloc() in sys_arch. When malloc() refers to +mem_malloc() you can run into a circular function call problem. In mem.c +mem_init() tries to allcate a semaphore using mem_malloc, which of course +can't be performed when sys_arch uses mem_malloc. + +------------------------------------------------------------------------------- +Additional files required for the "OS support" emulation layer: +------------------------------------------------------------------------------- + +cc.h - Architecture environment, some compiler specific, some + environment specific (probably should move env stuff + to sys_arch.h.) + + Typedefs for the types used by lwip - + u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + + Compiler hints for packing lwip's structures - + PACK_STRUCT_FIELD(x) + PACK_STRUCT_STRUCT + PACK_STRUCT_BEGIN + PACK_STRUCT_END + + Platform specific diagnostic output - + LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + Portability defines for printf formatters: + U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + + "lightweight" synchronization mechanisms - + SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. + SYS_ARCH_PROTECT(x) - enter protection mode. + SYS_ARCH_UNPROTECT(x) - leave protection mode. + + If the compiler does not provide memset() this file must include a + definition of it, or include a file which defines it. + + This file must either include a system-local which defines + the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO + to make lwip/arch.h define the codes which are used throughout. + + +perf.h - Architecture specific performance measurement. + Measurement calls made throughout lwip, these can be defined to nothing. + PERF_START - start measuring something. + PERF_STOP(x) - stop measuring something, and record the result. + +sys_arch.h - Tied to sys_arch.c + + Arch dependent types for the following objects: + sys_sem_t, sys_mbox_t, sys_thread_t, + And, optionally: + sys_prot_t + + Defines to set vars of sys_mbox_t and sys_sem_t to NULL. + SYS_MBOX_NULL NULL + SYS_SEM_NULL NULL diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cc.h new file mode 100644 index 0000000..be882d9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cc.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned int u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + +#define U16_F "d" +#define S16_F "d" +#define X16_F "x" +#define U32_F "d" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + +/* define compiler specific symbols */ +#if defined (__ICCARM__) +#if !defined (__IARSTDLIB__) +#define _STRING +#ifndef memcmp +#define memcmp(dst, src, sz) _memcmp(dst, src, sz) +#endif +#ifndef memset +#define memset(dst, val, sz) _memset(dst, val, sz) +#endif +#ifndef memcpy +#define memcpy(dst, src, sz) _memcpy(dst, src, sz) +#endif +#endif // __IARSTDLIB__ + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cpu.h new file mode 100644 index 0000000..06c2345 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + #ifndef BYTE_ORDER + #define BYTE_ORDER LITTLE_ENDIAN + #endif +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/arch/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.c new file mode 100644 index 0000000..50d883d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.c @@ -0,0 +1,386 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" +#include "lwip_netconf.h" + +//#include "lwip/ethip6.h" //Add for ipv6 + +#include +#include "platform_opts.h" + +#if CONFIG_ETHERNET +#include "ethernet_mii/ethernet_mii.h" +#endif + +#if CONFIG_WLAN +#include +#endif + +#if CONFIG_INIC_HOST +#include "freertos/inic_intf.h" +#endif + +#define netifMTU (1500) +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) + + +#ifdef CONFIG_CONCURRENT_MODE +#define IF2NAME0 'r' +#define IF2NAME1 '2' +#endif + +static void arp_timer(void *arg); + +#if LWIP_NETIF_HOSTNAME +char lwip_host_name[NET_IF_NUM][LWIP_NETIF_HOSTNAME_SIZE] = { + DEF_HOSTNAME"0", + DEF_HOSTNAME"1", + DEF_HOSTNAME"2" +}; +#endif + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ + +static void low_level_init(struct netif *netif) +{ + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set netif maximum transfer unit */ + netif->mtu = 1500; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + /* Wlan interface is initialized later */ +} + + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; +#if CONFIG_WLAN + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; +#endif + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + if (sg_len) { +#if CONFIG_WLAN + if (rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len) == 0) +#elif CONFIG_INIC_HOST + if(rltk_inic_send( sg_list, sg_len, p->tot_len) == 0) +#else + if(1) +#endif + return ERR_OK; + else + return ERR_BUF; // return a non-fatal error + } + return ERR_OK; +} + +#if CONFIG_ETHERNET +/*for ethernet mii interface*/ +static err_t low_level_output_mii(struct netif *netif, struct pbuf *p) +{ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + if (sg_len) { + if(rltk_mii_send(sg_list, sg_len, p->tot_len) == 0) + return ERR_OK; + else + return ERR_BUF; // return a non-fatal error + } + return ERR_OK; +} +#endif + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +//static struct pbuf * low_level_input(struct netif *netif){} + + +/** + * This function is the ethernetif_input task, it is processed when a packet + * is ready to be read from the interface. It uses the function low_level_input() + * that should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +//void ethernetif_input( void * pvParameters ) + + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; +#if CONFIG_WLAN + if(!rltk_wlan_running(netif_get_idx(netif))) + return; +#endif + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); +#if CONFIG_WLAN + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); +#elif CONFIG_INIC_HOST + rltk_inic_recv(sg_list, sg_len); +#endif + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); + +} + +#if CONFIG_ETHERNET +void ethernetif_mii_recv(struct netif *netif, int total_len) +{ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("Cannot allocate pbuf to receive packet\n"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + rltk_mii_recv(sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); + +} +#endif +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = lwip_host_name[0]; + else if(netif->name[1] == '1') + netif->hostname = lwip_host_name[1]; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->output = etharp_output; +//#if LWIP_IPV6 +// netif->output_ip6 = ethip6_output; +//#endif + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + + return ERR_OK; +} + +#if CONFIG_ETHERNET +err_t ethernetif_mii_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + netif->hostname = lwip_host_name[2]; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->output = etharp_output; +//#if LWIP_IPV6 +// netif->output_ip6 = ethip6_output; +//#endif + netif->linkoutput = low_level_output_mii; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + + return ERR_OK; +} +#endif + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.h new file mode 100644 index 0000000..67f1401 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/ethernetif.h @@ -0,0 +1,35 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "autoconf.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#if LWIP_NETIF_HOSTNAME +#ifndef LWIP_NETIF_HOSTNAME_SIZE +#define LWIP_NETIF_HOSTNAME_SIZE 16 +#endif +extern char lwip_host_name[NET_IF_NUM][LWIP_NETIF_HOSTNAME_SIZE]; +#endif + +//----- ------------------------------------------------------------------ +// Ethernet Buffer +//----- ------------------------------------------------------------------ +struct eth_drv_sg { + unsigned int buf; + unsigned int len; +}; + +#define MAX_ETH_DRV_SG 32 +#define MAX_ETH_MSG 1540 + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +err_t ethernetif_mii_init(struct netif *netif); +void ethernetif_mii_recv(struct netif *netif, int total_len); + +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.c new file mode 100644 index 0000000..4981b8f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.c @@ -0,0 +1,632 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "lwip/lwip_timers.h" +#include "autoconf.h" +#include "tcm_heap.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; +extern void * vTaskGetCurrentTCB( void ); +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + (void ) size; + + *mbox = xQueueCreate( size, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + if (*mbox == NULL) + return ERR_MEM; + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t *mbox) +{ + if( uxQueueMessagesWaiting( *mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( *mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t *mbox, void *data) +{ + while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} +/*----------------------------------------------------------------------------------*/ +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (*mbox == SYS_MBOX_NULL) + return 0; + else + return 1; +} +/*-----------------------------------------------------------------------------------*/ +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = SYS_MBOX_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Creates a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + vSemaphoreCreateBinary(*sem ); + if(*sem == NULL) + { + +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(*sem,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t *sem) +{ + xSemaphoreGive(*sem); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t *sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete(*sem); +} +/*-----------------------------------------------------------------------------------*/ +int sys_sem_valid(sys_sem_t *sem) +{ + if (*sem == SYS_SEM_NULL) + return 0; + else + return 1; +} + +/*-----------------------------------------------------------------------------------*/ +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = SYS_SEM_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts *sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} +/*-----------------------------------------------------------------------------------*/ + /* Mutexes*/ +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_COMPAT_MUTEX == 0 +/* Create a new mutex*/ +err_t sys_mutex_new(sys_mutex_t *mutex) { + + *mutex = xSemaphoreCreateMutex(); + if(*mutex == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.mutex.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + +#if SYS_STATS + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } +#endif /* SYS_STATS */ + return ERR_OK; +} +/*-----------------------------------------------------------------------------------*/ +/* Deallocate a mutex*/ +void sys_mutex_free(sys_mutex_t *mutex) +{ +#if SYS_STATS + --lwip_stats.sys.mutex.used; +#endif /* SYS_STATS */ + + vQueueDelete(*mutex); +} +/*-----------------------------------------------------------------------------------*/ +/* Lock a mutex*/ +void sys_mutex_lock(sys_mutex_t *mutex) +{ + sys_arch_sem_wait(*mutex, 0); +} + +/*-----------------------------------------------------------------------------------*/ +/* Unlock a mutex*/ +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + xSemaphoreGive(*mutex); +} +#endif /*LWIP_COMPAT_MUTEX*/ + +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +#if 0 +sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); +#if CONFIG_USE_TCM_HEAP + { + void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int)); + + result = xTaskGenericCreate( + thread, + ( signed portCHAR * ) name, + stacksize, + arg, + prio, + &CreatedTask, + stack_addr, + NULL); + } +#else + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); +#endif + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} +#endif +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +int sys_thread_delete(xTaskHandle pid) +{ + int i, isFind = 0; + struct timeoutlist *tl, *tend = NULL; + + pid = (( pid == NULL)?(xTaskHandle) vTaskGetCurrentTCB() : pid); + + if (s_nextthread) + { + vPortEnterCritical(); + + tend = &(s_timeoutlist[s_nextthread-1]);//the last one + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + {//find the task, exchange with the last one + memcpy(tl, tend, sizeof(struct timeoutlist)); + memset(tend, 0, sizeof(struct timeoutlist)); + s_nextthread --; + isFind = 1; + break; + } + } + + if (isFind) { + vTaskDelete( pid); + } + + vPortExitCritical(); + + if (isFind) + { + return pdPASS; + } + else + { + return pdFAIL; + } + } + else + { + return pdFAIL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} + +u32_t sys_now(void) +{ + return xTaskGetTickCount(); +} + +u32_t sys_jiffies(void) +{ + return xTaskGetTickCount(); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/realtek/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cc.h new file mode 100644 index 0000000..1d6a5fa --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cc.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned int u32_t; +typedef signed int s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + + +#define U16_F "hu" +#define S16_F "d" +#define X16_F "hx" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + + + + + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cpu.h new file mode 100644 index 0000000..a02f86d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/sys_arch.h new file mode 100644 index 0000000..2e841bd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/arch/sys_arch.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xSemaphoreHandle sys_mutex_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/MFC6A0B.tmp b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/MFC6A0B.tmp new file mode 100644 index 0000000..5097f29 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/MFC6A0B.tmp @@ -0,0 +1,489 @@ +/** +* @file +* Ethernet Interface Skeleton +* +*/ + +/* +* Copyright (c) 2001-2004 Swedish Institute of Computer Science. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. The name of the author may not be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +* +* This file is part of the lwIP TCP/IP stack. +* +* Author: Adam Dunkels +* +*/ + +/* +* This file is a skeleton for developing Ethernet network interface +* drivers for lwIP. Add code to the low_level functions and do a +* search-and-replace for the word "ethernetif" to replace it with +* something that better describes your network interface. +*/ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +//#include "lwip/sys.h" +//#include "lwip/tcpip.h" +//#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +//#include "queue.h" + +#include "main.h" // for the definition of CONFIG_WLAN + +#if !CONFIG_WLAN +#include "stm32f2x7_eth.h" +#else +#include +#endif +#include + +#include + + +#define netifMTU (1500) +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) + +#if !CONFIG_WLAN +/* Define those to better describe your network interface. */ +#define IFNAME0 's' +#define IFNAME1 't' + +static struct netif *s_pxNetIf = NULL; +xSemaphoreHandle s_xSemaphore = NULL; + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + + +static void ethernetif_input( void * pvParameters ); +#endif + +static void arp_timer(void *arg); + + +/** +* In this function, the hardware should be initialized. +* Called from ethernetif_init(). +* +* @param netif the already initialized lwip network interface structure +* for this ethernetif +*/ +static void low_level_init(struct netif *netif) +{ + uint32_t i; + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + +#if !CONFIG_WLAN + /* set netif MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; +#endif + + /* set netif maximum transfer unit */ + netif->mtu = 1500; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if !CONFIG_WLAN + s_pxNetIf =netif; + + /* create binary semaphore used for informing ethernetif of frame reception */ + if (s_xSemaphore == NULL) + { + vSemaphoreCreateBinary(s_xSemaphore); + xSemaphoreTake( s_xSemaphore, 0); + } + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable Ethernet Rx interrrupt */ + { + for(i=0; iBuffer1Addr); + bufferoffset = 0; + + for(q = p; q != NULL; q = q->next) + { + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + goto error; + } + + /* Get bytes in current lwIP buffer */ + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) + { + /* Copy data to Tx buffer*/ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); + + /* Point to next descriptor */ + DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); + + /* Check if the buffer is available */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + goto error; + } + + buffer = (u8 *)(DmaTxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); + framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy the remaining bytes */ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy ); + bufferoffset = bufferoffset + byteslefttocopy; + framelength = framelength + byteslefttocopy; + } + + /* Prepare transmit descriptors to give to DMA*/ + ETH_Prepare_Transmit_Descriptors(framelength); + + /* Give semaphore and exit */ + error: + + xSemaphoreGive(xTxSemaphore); + } +#endif // #if !CONFIG_WLAN + + return ERR_OK; +} + + +#if !CONFIG_WLAN +/** +* Should allocate a pbuf and transfer the bytes of the incoming +* packet from the interface into the pbuf. +* +* @param netif the lwip network interface structure for this ethernetif +* @return a pbuf filled with the received packet (including MAC header) +* NULL on memory error +*/ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p= NULL, *q; + u32_t len; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxDesc; + uint32_t bufferoffset = 0; + uint32_t payloadoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t i=0; + + /* get received frame */ + frame = ETH_Get_Received_Frame_interrupt(); + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + if (len > 0) + { + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + } + + if (p != NULL) + { + DMARxDesc = frame.descriptor; + bufferoffset = 0; + for(q = p; q != NULL; q = q->next) + { + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) + { + /* Copy data to pbuf*/ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); + + /* Point to next descriptor */ + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + buffer = (unsigned char *)(DMARxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy remaining data in pbuf */ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy); + bufferoffset = bufferoffset + byteslefttocopy; + } + + /* Release descriptors to DMA */ + DMARxDesc =frame.descriptor; + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxDesc->Status = ETH_DMARxDesc_OWN; + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + /* added for test*/ + } + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + + +/** +* This function is the ethernetif_input task, it is processed when a packet +* is ready to be read from the interface. It uses the function low_level_input() +* that should handle the actual reception of bytes from the network +* interface. Then the type of the received packet is determined and +* the appropriate input function is called. +* +* @param netif the lwip network interface structure for this ethernetif +*/ +void ethernetif_input( void * pvParameters ) +{ + struct pbuf *p; + + for( ;; ) + { + if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE) + { +TRY_GET_NEXT_FRAME: + p = low_level_input( s_pxNetIf ); + if (p != NULL) + { + if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) + { + pbuf_free(p); + } + else + { + goto TRY_GET_NEXT_FRAME; + } + } + + } + } +} +#endif +/** +* Should be called at the beginning of the program to set up the +* network interface. It calls the function low_level_init() to do the +* actual setup of the hardware. +* +* This function should be passed as a parameter to netif_add(). +* +* @param netif the lwip network interface structure for this ethernetif +* @return ERR_OK if the loopif is initialized +* ERR_MEM if private data couldn't be allocated +* any other err_t on error +*/ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if !CONFIG_WLAN + /* ethernet */ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#else + /* wlan interface*/ +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ +#endif // WLAN + + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + + return ERR_OK; +} + + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +/* +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} +*/ +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.c new file mode 100644 index 0000000..0f67357 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.c @@ -0,0 +1,653 @@ +/** +* @file +* Ethernet Interface Skeleton +* +*/ + +/* +* Copyright (c) 2001-2004 Swedish Institute of Computer Science. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. The name of the author may not be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +* +* This file is part of the lwIP TCP/IP stack. +* +* Author: Adam Dunkels +* +*/ + +/* +* This file is a skeleton for developing Ethernet network interface +* drivers for lwIP. Add code to the low_level functions and do a +* search-and-replace for the word "ethernetif" to replace it with +* something that better describes your network interface. +*/ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" + +#include "main.h" // for the definition of CONFIG_WLAN + + +#if !CONFIG_WLAN +#include "stm32f2x7_eth.h" +#else +#include +#endif +#include + +#include + +#ifdef CONFIG_DONT_CARE_TP +#define netifMTU (576) +#else +#define netifMTU (1500) +#endif +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) +#define FAKE_PING_REPLY 0 + +#if !CONFIG_WLAN +/* Define those to better describe your network interface. */ +#define IFNAME0 's' +#define IFNAME1 't' + +static struct netif *s_pxNetIf = NULL; +xSemaphoreHandle s_xSemaphore = NULL; + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + +static void ethernetif_input( void * pvParameters ); +#endif + +static void arp_timer(void *arg); + + +/** +* In this function, the hardware should be initialized. +* Called from ethernetif_init(). +* +* @param netif the already initialized lwip network interface structure +* for this ethernetif +*/ +static void low_level_init(struct netif *netif) +{ + uint32_t i; + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + +#if !CONFIG_WLAN + /* set netif MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; +#endif + + /* set netif maximum transfer unit */ + netif->mtu = netifMTU; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if !CONFIG_WLAN + s_pxNetIf =netif; + + /* create binary semaphore used for informing ethernetif of frame reception */ + if (s_xSemaphore == NULL) + { + s_xSemaphore= xSemaphoreCreateCounting(20,0); + } + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable Ethernet Rx interrrupt */ + { + for(i=0; itot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_arp = (struct etharp_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_arp = (struct etharp_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = fake_src_mac; + q_arp->opcode = htons(ARP_REPLY); + q_arp->shwaddr = fake_src_mac; + q_arp->sipaddr = p_arp->dipaddr; + q_arp->dhwaddr = p_eth->src; + q_arp->dipaddr = p_arp->sipaddr; + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_arp_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake arp reply \n\r"); +} + +void fake_echo_reply(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q, *tq, *tp; + int q_len, p_len; + struct eth_hdr *p_eth, *q_eth; + struct ip_hdr *p_ip, *q_ip; + struct icmp_echo_hdr *p_echo, *q_echo; + + // Allocate buffer to store received packet + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_ip = (struct ip_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_ip = (struct ip_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + p_echo = (struct icmp_echo_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + q_echo = (struct icmp_echo_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = p_eth->dest; + q_ip->src.addr = p_ip->dest.addr; + q_ip->dest.addr = p_ip->src.addr; + q_ip->_chksum = 0; + q_ip->_chksum = inet_chksum(q_ip, sizeof(struct ip_hdr)); + q_echo->type = ICMP_ER; + q_echo->code = 0; + q_echo->chksum = 0; + q_echo->chksum = inet_chksum(q_echo, q->tot_len - sizeof(struct eth_hdr) - sizeof(struct ip_hdr)); + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_echo_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake echo reply \n\r"); +} +#endif // #if FAKE_PING_REPLY + +/** +* This function should do the actual transmission of the packet. The packet is +* contained in the pbuf that is passed to the function. This pbuf +* might be chained. +* +* @param netif the lwip network interface structure for this ethernetif +* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) +* @return ERR_OK if the packet could be sent +* an err_t value if the packet couldn't be sent +* +* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to +* strange results. You might consider waiting for space in the DMA queue +* to become availale since the stack doesn't retry to send a packet +* dropped because of memory failure (except for the TCP timers). +*/ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ +#if !CONFIG_WLAN + static xSemaphoreHandle xTxSemaphore = NULL; + struct pbuf *q; + uint32_t l = 0; + u8 *buffer ; + + if (xTxSemaphore == NULL) + { + vSemaphoreCreateBinary (xTxSemaphore); + } + + if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME)) + { + buffer = (u8 *)(DMATxDescToSet->Buffer1Addr); + for(q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)&buffer[l], q->payload, q->len); + l = l + q->len; + } + ETH_Prepare_Transmit_Descriptors(l); + xSemaphoreGive(xTxSemaphore); + } +#else + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; + + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + +#if FAKE_PING_REPLY + { + char *header = p->payload; + if(header[12] == 0x08 && header[13] == 0x06) + { // arp packet + if(header[21] == 0x01) + { // arp request packet + printf("\n\rfake_ping: arp request packet."); + if(0) + { + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_arp_reply(netif, p); + return ERR_OK; + } + }else if(header[12] == 0x08 && header[13] == 0x00) + { // ip packet + if(header[15] == 0x00 && header[23] == 0x01) + { // icmp packet + printf("\n\rfake_ping: icmp packet."); + if(0){ + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_echo_reply(netif, p); + return ERR_OK; + } + } + } +#endif // #if FAKE_PING_REPLY + if (sg_len) + rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len); +#endif // #if !CONFIG_WLAN + + return ERR_OK; +} + + +#if !CONFIG_WLAN +/** +* Should allocate a pbuf and transfer the bytes of the incoming +* packet from the interface into the pbuf. +* +* @param netif the lwip network interface structure for this ethernetif +* @return a pbuf filled with the received packet (including MAC header) +* NULL on memory error +*/ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + u16_t len; + uint32_t l=0,i =0; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxNextDesc; + + p = NULL; + + /* Get received frame */ + frame = ETH_Get_Received_Frame_interrupt(); + + /* check that frame has no error */ + if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) + { + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + /* Copy received frame from ethernet driver buffer to stack buffer */ + if (p != NULL) + { + for (q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len); + l = l + q->len; + } + } + } + + /* Release descriptors to DMA */ + /* Check if received frame with multiple DMA buffer segments */ + if (DMA_RX_FRAME_infos->Seg_Count > 1) + { + DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc; + } + else + { + DMARxNextDesc = frame.descriptor; + } + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxNextDesc->Status = ETH_DMARxDesc_OWN; + DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + + +/** +* This function is the ethernetif_input task, it is processed when a packet +* is ready to be read from the interface. It uses the function low_level_input() +* that should handle the actual reception of bytes from the network +* interface. Then the type of the received packet is determined and +* the appropriate input function is called. +* +* @param netif the lwip network interface structure for this ethernetif +*/ +void ethernetif_input( void * pvParameters ) +{ + struct pbuf *p; + + for( ;; ) + { + if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE) + { + p = low_level_input( s_pxNetIf ); + if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) + { + pbuf_free(p); + p=NULL; + } + } + } +} +#endif + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ +#if CONFIG_WLAN + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); +#endif +} + +/** +* Should be called at the beginning of the program to set up the +* network interface. It calls the function low_level_init() to do the +* actual setup of the hardware. +* +* This function should be passed as a parameter to netif_add(). +* +* @param netif the lwip network interface structure for this ethernetif +* @return ERR_OK if the loopif is initialized +* ERR_MEM if private data couldn't be allocated +* any other err_t on error +*/ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if !CONFIG_WLAN + /* ethernet */ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#else + /* wlan interface*/ +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = "lwip0"; + else if(netif->name[1] == '1') + netif->hostname = "lwip1"; +#endif /* LWIP_NETIF_HOSTNAME */ + +#endif // WLAN + + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + + return ERR_OK; +} + + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.h new file mode 100644 index 0000000..7a436d2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/ethernetif.h @@ -0,0 +1,23 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" +//----- ------------------------------------------------------------------ +// Ethernet Buffer +//----- ------------------------------------------------------------------ +struct eth_drv_sg { + unsigned int buf; + unsigned int len; +}; + +#define MAX_ETH_DRV_SG 32 +#define MAX_ETH_MSG 1540 + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.c new file mode 100644 index 0000000..3d111c6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.c @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "lwip/lwip_timers.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + (void ) size; + + *mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + if (*mbox == NULL) + return ERR_MEM; + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t *mbox) +{ + if( uxQueueMessagesWaiting( *mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( *mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t *mbox, void *data) +{ + while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} +/*----------------------------------------------------------------------------------*/ +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (*mbox == SYS_MBOX_NULL) + return 0; + else + return 1; +} +/*-----------------------------------------------------------------------------------*/ +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = SYS_MBOX_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Creates a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + vSemaphoreCreateBinary(*sem ); + if(*sem == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(*sem,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t *sem) +{ + xSemaphoreGive(*sem); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t *sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete(*sem); +} +/*-----------------------------------------------------------------------------------*/ +int sys_sem_valid(sys_sem_t *sem) +{ + if (*sem == SYS_SEM_NULL) + return 0; + else + return 1; +} + +/*-----------------------------------------------------------------------------------*/ +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = SYS_SEM_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts* sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} +/*-----------------------------------------------------------------------------------*/ + /* Mutexes*/ +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_COMPAT_MUTEX == 0 +/* Create a new mutex*/ +err_t sys_mutex_new(sys_mutex_t *mutex) { + + *mutex = xSemaphoreCreateMutex(); + if(*mutex == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.mutex.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + +#if SYS_STATS + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } +#endif /* SYS_STATS */ + return ERR_OK; +} +/*-----------------------------------------------------------------------------------*/ +/* Deallocate a mutex*/ +void sys_mutex_free(sys_mutex_t *mutex) +{ +#if SYS_STATS + --lwip_stats.sys.mutex.used; +#endif /* SYS_STATS */ + + vQueueDelete(*mutex); +} +/*-----------------------------------------------------------------------------------*/ +/* Lock a mutex*/ +void sys_mutex_lock(sys_mutex_t *mutex) +{ + sys_arch_sem_wait(*mutex, 0); +} + +/*-----------------------------------------------------------------------------------*/ +/* Unlock a mutex*/ +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + xSemaphoreGive(*mutex); +} +#endif /*LWIP_COMPAT_MUTEX*/ +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.c new file mode 100644 index 0000000..f3b74ee --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.c @@ -0,0 +1,366 @@ +/** + * @file + * Ethernet Interface for standalone applications (without RTOS) - works only for + * ethernet polling mode (polling for ethernet frame reception) + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/mem.h" +#include "netif/etharp.h" +#include "ethernetif.h" +#include "stm32f2x7_eth.h" +#include "main.h" +#include + +/* Network interface name */ +#define IFNAME0 's' +#define IFNAME1 't' + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Driver Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Driver Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void low_level_init(struct netif *netif) +{ +#ifdef CHECKSUM_BY_HARDWARE + int i; +#endif + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ + for(i=0; iBuffer1Addr); + __IO ETH_DMADESCTypeDef *DmaTxDesc; + uint16_t framelength = 0; + uint32_t bufferoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t payloadoffset = 0; + + DmaTxDesc = DMATxDescToSet; + bufferoffset = 0; + + /* copy frame from pbufs to driver buffers */ + for(q = p; q != NULL; q = q->next) + { + /* Is this buffer available? If not, goto error */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + errval = ERR_BUF; + goto error; + } + + /* Get bytes in current lwIP buffer */ + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) + { + /* Copy data to Tx buffer*/ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); + + /* Point to next descriptor */ + DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); + + /* Check if the buffer is available */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + errval = ERR_USE; + goto error; + } + + buffer = (u8 *)(DmaTxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); + framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy the remaining bytes */ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy ); + bufferoffset = bufferoffset + byteslefttocopy; + framelength = framelength + byteslefttocopy; + } + + /* Note: padding and CRC for transmitted frame + are automatically inserted by DMA */ + + /* Prepare transmit descriptors to give to DMA*/ + ETH_Prepare_Transmit_Descriptors(framelength); + + errval = ERR_OK; + +error: + + /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ + if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET) + { + /* Clear TUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_TUS; + + /* Resume DMA transmission*/ + ETH->DMATPDR = 0; + } + return errval; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + uint32_t len; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxDesc; + uint32_t bufferoffset = 0; + uint32_t payloadoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t i=0; + + /* get received frame */ + frame = ETH_Get_Received_Frame(); + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) + { + DMARxDesc = frame.descriptor; + bufferoffset = 0; + for(q = p; q != NULL; q = q->next) + { + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) + { + /* Copy data to pbuf*/ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); + + /* Point to next descriptor */ + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + buffer = (unsigned char *)(DMARxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + /* Copy remaining data in pbuf */ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy); + bufferoffset = bufferoffset + byteslefttocopy; + } + } + + /* Release descriptors to DMA */ + DMARxDesc =frame.descriptor; + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxDesc->Status = ETH_DMARxDesc_OWN; + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +err_t ethernetif_input(struct netif *netif) +{ + err_t err; + struct pbuf *p; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + + /* no packet could be read, silently ignore this */ + if (p == NULL) return ERR_MEM; + + /* entry point to the LwIP stack */ + err = netif->input(p, netif); + + if (err != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + } + return err; +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.h new file mode 100644 index 0000000..9ff1408 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/port/stm32f2x7/standalone/ethernetif.h @@ -0,0 +1,11 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +err_t ethernetif_init(struct netif *netif); +err_t ethernetif_input(struct netif *netif); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/FILES b/USDK/component/common/network/lwip/lwip_v1.4.1/src/FILES new file mode 100644 index 0000000..952aeab --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/FILES @@ -0,0 +1,13 @@ +api/ - The code for the high-level wrapper API. Not needed if + you use the lowel-level call-back/raw API. + +core/ - The core of the TPC/IP stack; protocol implementations, + memory and buffer management, and the low-level raw API. + +include/ - lwIP include files. + +netif/ - Generic network interface device drivers are kept here, + as well as the ARP module. + +For more information on the various subdirectories, check the FILES +file in each directory. diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_lib.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_lib.c new file mode 100644 index 0000000..42e2460 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_lib.c @@ -0,0 +1,792 @@ +/** + * @file + * Sequential API External module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* This is the part of the API that is linked with + the application */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" + +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" + +#include + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is also created. + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) +{ + struct netconn *conn; + struct api_msg msg; + + conn = netconn_alloc(t, callback); + if (conn != NULL) { + msg.function = do_newconn; + msg.msg.msg.n.proto = proto; + msg.msg.conn = conn; + if (TCPIP_APIMSG(&msg) != ERR_OK) { + LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); + LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); + LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ + sys_sem_free(&conn->op_completed); + sys_mbox_free(&conn->recvmbox); + memp_free(MEMP_NETCONN, conn); + return NULL; + } + } + return conn; +} + +/** + * Close a netconn 'connection' and free its resources. + * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate + * after this returns. + * + * @param conn the netconn to delete + * @return ERR_OK if the connection was deleted + */ +err_t +netconn_delete(struct netconn *conn) +{ + struct api_msg msg; + + /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ + if (conn == NULL) { + return ERR_OK; + } + + msg.function = do_delconn; + msg.msg.conn = conn; + tcpip_apimsg(&msg); + + netconn_free(conn); + + /* don't care for return value of do_delconn since it only calls void functions */ + + return ERR_OK; +} + +/** + * Get the local or remote IP address and port of a netconn. + * For RAW netconns, this returns the protocol instead of a port! + * + * @param conn the netconn to query + * @param addr a pointer to which to save the IP address + * @param port a pointer to which to save the port (or protocol for RAW) + * @param local 1 to get the local IP address, 0 to get the remote one + * @return ERR_CONN for invalid connections + * ERR_OK if the information was retrieved + */ +err_t +netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); + + msg.function = do_getaddr; + msg.msg.conn = conn; + msg.msg.msg.ad.ipaddr = addr; + msg.msg.msg.ad.port = port; + msg.msg.msg.ad.local = local; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Bind a netconn to a specific local IP address and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY + * to bind to all addresses) + * @param port the local port to bind the netconn to (not used for RAW) + * @return ERR_OK if bound, any other err_t on failure + */ +err_t +netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_bind; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Connect a netconn to a specific remote IP address and port. + * + * @param conn the netconn to connect + * @param addr the remote IP address to connect to + * @param port the remote port to connect to (no used for RAW) + * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise + */ +err_t +netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_connect; + msg.msg.conn = conn; + msg.msg.msg.bc.ipaddr = addr; + msg.msg.msg.bc.port = port; + /* This is the only function which need to not block tcpip_thread */ + err = tcpip_apimsg(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Disconnect a netconn from its current peer (only valid for UDP netconns). + * + * @param conn the netconn to disconnect + * @return TODO: return value is not set here... + */ +err_t +netconn_disconnect(struct netconn *conn) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_disconnect; + msg.msg.conn = conn; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Set a TCP netconn into listen mode + * + * @param conn the tcp netconn to set to listen mode + * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 + * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns + * don't return any error (yet?)) + */ +err_t +netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) +{ +#if LWIP_TCP + struct api_msg msg; + err_t err; + + /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ + LWIP_UNUSED_ARG(backlog); + + LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_listen; + msg.msg.conn = conn; +#if TCP_LISTEN_BACKLOG + msg.msg.msg.lb.backlog = backlog; +#endif /* TCP_LISTEN_BACKLOG */ + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(backlog); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Accept a new connection on a TCP listening netconn. + * + * @param conn the TCP listen netconn + * @param new_conn pointer where the new connection is stored + * @return ERR_OK if a new connection has been received or an error + * code otherwise + */ +err_t +netconn_accept(struct netconn *conn, struct netconn **new_conn) +{ +#if LWIP_TCP + struct netconn *newconn; + err_t err; +#if TCP_LISTEN_BACKLOG + struct api_msg msg; +#endif /* TCP_LISTEN_BACKLOG */ + + LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); + *new_conn = NULL; + LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on acceptmbox forever! */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + + if (newconn == NULL) { + /* connection has been aborted */ + NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); + return ERR_ABRT; + } +#if TCP_LISTEN_BACKLOG + /* Let the stack know that we have accepted the connection. */ + msg.function = do_recv; + msg.msg.conn = conn; + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); +#endif /* TCP_LISTEN_BACKLOG */ + + *new_conn = newconn; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(new_conn); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Receive data: actual implementation that doesn't care whether pbuf or netbuf + * is received + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf/netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +static err_t +netconn_recv_data(struct netconn *conn, void **new_buf) +{ + void *buf = NULL; + u16_t len; + err_t err; +#if LWIP_TCP + struct api_msg msg; +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on recvmbox forever! */ + /* @todo: this does not allow us to fetch data that has been put into recvmbox + before the fatal error occurred - is that a problem? */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + if (!netconn_get_noautorecved(conn) || (buf == NULL)) { + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + msg.function = do_recv; + msg.msg.conn = conn; + if (buf != NULL) { + msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len; + } else { + msg.msg.msg.r.len = 1; + } + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); + } + + /* If we are closed, we indicate that we no longer wish to use the socket */ + if (buf == NULL) { + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + /* Avoid to lose any previous error code */ + NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); + return ERR_CLSD; + } + len = ((struct pbuf *)buf)->tot_len; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ +#if (LWIP_UDP || LWIP_RAW) + { + LWIP_ASSERT("buf != NULL", buf != NULL); + len = netbuf_len((struct netbuf *)buf); + } +#endif /* (LWIP_UDP || LWIP_RAW) */ + +#if LWIP_SO_RCVBUF + SYS_ARCH_DEC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); + + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +} + +/** + * Receive data (in form of a pbuf) from a TCP netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + * ERR_ARG if conn is not a TCP netconn + */ +err_t +netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) +{ + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) && + netconn_type(conn) == NETCONN_TCP, return ERR_ARG;); + + return netconn_recv_data(conn, (void **)new_buf); +} + +/** + * Receive data (in form of a netbuf containing a packet buffer) from a netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +err_t +netconn_recv(struct netconn *conn, struct netbuf **new_buf) +{ +#if LWIP_TCP + struct netbuf *buf = NULL; + err_t err; +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (conn->type == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + struct pbuf *p = NULL; + /* This is not a listening netconn, since recvmbox is set */ + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + NETCONN_SET_SAFE_ERR(conn, ERR_MEM); + return ERR_MEM; + } + + err = netconn_recv_data(conn, (void **)&p); + if (err != ERR_OK) { + memp_free(MEMP_NETBUF, buf); + return err; + } + LWIP_ASSERT("p != NULL", p != NULL); + + buf->p = p; + buf->ptr = p; + buf->port = 0; + ip_addr_set_any(&buf->addr); + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ + { +#if (LWIP_UDP || LWIP_RAW) + return netconn_recv_data(conn, (void **)new_buf); +#endif /* (LWIP_UDP || LWIP_RAW) */ + } +} + +/** + * TCP: update the receive window: by calling this, the application + * tells the stack that it has processed data and is able to accept + * new data. + * ATTENTION: use with care, this is mainly used for sockets! + * Can only be used when calling netconn_set_noautorecved(conn, 1) before. + * + * @param conn the netconn for which to update the receive window + * @param length amount of data processed (ATTENTION: this must be accurate!) + */ +void +netconn_recved(struct netconn *conn, u32_t length) +{ +#if LWIP_TCP + if ((conn != NULL) && (conn->type == NETCONN_TCP) && + (netconn_get_noautorecved(conn))) { + struct api_msg msg; + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + msg.function = do_recv; + msg.msg.conn = conn; + msg.msg.msg.r.len = length; + /* don't care for the return value of do_recv */ + TCPIP_APIMSG(&msg); + } +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(length); +#endif /* LWIP_TCP */ +} + +/** + * Send data (in form of a netbuf) to a specific remote IP address and port. + * Only to be used for UDP and RAW netconns (not TCP). + * + * @param conn the netconn over which to send data + * @param buf a netbuf containing the data to send + * @param addr the remote IP address to which to send the data + * @param port the remote port to which to send the data + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) +{ + if (buf != NULL) { + ip_addr_set(&buf->addr, addr); + buf->port = port; + return netconn_send(conn, buf); + } + return ERR_VAL; +} + +/** + * Send data over a UDP or RAW netconn (that is already connected). + * + * @param conn the UDP or RAW netconn over which to send data + * @param buf a netbuf containing the data to send + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_send(struct netconn *conn, struct netbuf *buf) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); + msg.function = do_send; + msg.msg.conn = conn; + msg.msg.msg.b = buf; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Send data over a TCP netconn. + * + * @param conn the TCP netconn over which to send data + * @param dataptr pointer to the application buffer that contains the data to send + * @param size size of the application data to send + * @param apiflags combination of following flags : + * - NETCONN_COPY: data will be copied into memory belonging to the stack + * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent + * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once + * @param bytes_written pointer to a location that receives the number of written bytes + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written) +{ + struct api_msg msg; + err_t err; + u8_t dontblock; + + LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;); + if (size == 0) { + return ERR_OK; + } + dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); + if (dontblock && !bytes_written) { + /* This implies netconn_write() cannot be used for non-blocking send, since + it has no way to return the number of bytes written. */ + return ERR_VAL; + } + + /* non-blocking write sends as much */ + msg.function = do_write; + msg.msg.conn = conn; + msg.msg.msg.w.dataptr = dataptr; + msg.msg.msg.w.apiflags = apiflags; + msg.msg.msg.w.len = size; +#if LWIP_SO_SNDTIMEO + if (conn->send_timeout != 0) { + /* get the time we started, which is later compared to + sys_now() + conn->send_timeout */ + msg.msg.msg.w.time_started = sys_now(); + } else { + msg.msg.msg.w.time_started = 0; + } +#endif /* LWIP_SO_SNDTIMEO */ + + /* For locking the core: this _can_ be delayed on low memory/low send buffer, + but if it is, this is done inside api_msg.c:do_write(), so we can use the + non-blocking version here. */ + err = TCPIP_APIMSG(&msg); + if ((err == ERR_OK) && (bytes_written != NULL)) { + if (dontblock +#if LWIP_SO_SNDTIMEO + || (conn->send_timeout != 0) +#endif /* LWIP_SO_SNDTIMEO */ + ) { + /* nonblocking write: maybe the data has been sent partly */ + *bytes_written = msg.msg.msg.w.len; + } else { + /* blocking call succeeded: all data has been sent if it */ + *bytes_written = size; + } + } + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close ot shutdown a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close or shutdown + * @param how fully close or only shutdown one side? + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +static err_t +netconn_close_shutdown(struct netconn *conn, u8_t how) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_close; + msg.msg.conn = conn; + /* shutting down both ends is the same as closing */ + msg.msg.msg.sd.shut = how; + /* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close, + don't use TCPIP_APIMSG here */ + err = tcpip_apimsg(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_close(struct netconn *conn) +{ + /* shutting down both ends is the same as closing */ + return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); +} + +/** + * Shut down one or both sides of a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to shut down + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) +{ + return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)); +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * + * @param conn the UDP netconn for which to change multicast addresses + * @param multiaddr IP address of the multicast group to join or leave + * @param netif_addr the IP address of the network interface on which to send + * the igmp message + * @param join_or_leave flag whether to send a join- or leave-message + * @return ERR_OK if the action was taken, any err_t on error + */ +err_t +netconn_join_leave_group(struct netconn *conn, + ip_addr_t *multiaddr, + ip_addr_t *netif_addr, + enum netconn_igmp join_or_leave) +{ + struct api_msg msg; + err_t err; + + LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); + + msg.function = do_join_leave_group; + msg.msg.conn = conn; + msg.msg.msg.jl.multiaddr = multiaddr; + msg.msg.msg.jl.netif_addr = netif_addr; + msg.msg.msg.jl.join_or_leave = join_or_leave; + err = TCPIP_APIMSG(&msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Execute a DNS query, only one IP address is returned + * + * @param name a string representation of the DNS host name to query + * @param addr a preallocated ip_addr_t where to store the resolved IP address + * @return ERR_OK: resolving succeeded + * ERR_MEM: memory error, try again later + * ERR_ARG: dns client not initialized or invalid hostname + * ERR_VAL: dns server response was invalid + */ +err_t +netconn_gethostbyname(const char *name, ip_addr_t *addr) +{ + struct dns_api_msg msg; + err_t err; + sys_sem_t sem; + + LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); + + err = sys_sem_new(&sem, 0); + if (err != ERR_OK) { + return err; + } + + msg.name = name; + msg.addr = addr; + msg.err = &err; + msg.sem = &sem; + + tcpip_callback(do_gethostbyname, &msg); + sys_sem_wait(&sem); + sys_sem_free(&sem); + + return err; +} +#endif /* LWIP_DNS*/ + +//Realtek add +err_t netconn_abort(struct netconn *conn) +{ + if (conn->acceptmbox != SYS_MBOX_NULL) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + sys_mbox_post(&conn->acceptmbox, NULL); + } + return ERR_OK; +} +//Realtek add end + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_msg.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_msg.c new file mode 100644 index 0000000..ffcdc43 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/api_msg.c @@ -0,0 +1,1565 @@ +/** + * @file + * Sequential API Internal module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" + +#include "lwip/ip.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" + +#include "lwip/memp.h" +#include "lwip/tcpip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" + +#include + +#define SET_NONBLOCKING_CONNECT(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) +#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) + +/* forward declarations */ +#if LWIP_TCP +static err_t do_writemore(struct netconn *conn); +static void do_close_internal(struct netconn *conn); +#endif + +#if LWIP_RAW +/** + * Receive callback function for RAW netconns. + * Doesn't 'eat' the packet, only references it and sends it to + * conn->recvmbox + * + * @see raw.h (struct raw_pcb.recv) for parameters and return value + */ +static u8_t +recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr) +{ + struct pbuf *q; + struct netbuf *buf; + struct netconn *conn; + + LWIP_UNUSED_ARG(addr); + conn = (struct netconn *)arg; + + if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) { +#if LWIP_SO_RCVBUF + int recv_avail; + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { + return 0; + } +#endif /* LWIP_SO_RCVBUF */ + /* copy the whole packet into new pbufs */ + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(q != NULL) { + if (pbuf_copy(q, p) != ERR_OK) { + pbuf_free(q); + q = NULL; + } + } + + if (q != NULL) { + u16_t len; + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(q); + return 0; + } + + buf->p = q; + buf->ptr = q; + ip_addr_copy(buf->addr, *ip_current_src_addr()); + buf->port = pcb->protocol; + + len = q->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return 0; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + } + } + + return 0; /* do not eat the packet */ +} +#endif /* LWIP_RAW*/ + +#if LWIP_UDP +/** + * Receive callback function for UDP netconns. + * Posts the packet to conn->recvmbox or deletes it on memory error. + * + * @see udp.h (struct udp_pcb.recv) for parameters + */ +static void +recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port) +{ + struct netbuf *buf; + struct netconn *conn; + u16_t len; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ + LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_udp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); + +#if LWIP_SO_RCVBUF + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) || + ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) { +#endif /* LWIP_SO_RCVBUF */ + pbuf_free(p); + return; + } + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); + return; + } else { + buf->p = p; + buf->ptr = p; + ip_addr_set(&buf->addr, addr); + buf->port = port; +#if LWIP_NETBUF_RECVINFO + { + const struct ip_hdr* iphdr = ip_current_header(); + /* get the UDP header - always in the first pbuf, ensured by udp_input */ + const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr)); +#if LWIP_CHECKSUM_ON_COPY + buf->flags = NETBUF_FLAG_DESTADDR; +#endif /* LWIP_CHECKSUM_ON_COPY */ + ip_addr_set(&buf->toaddr, ip_current_dest_addr()); + buf->toport_chksum = udphdr->dest; + } +#endif /* LWIP_NETBUF_RECVINFO */ + } + + len = p->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } +} +#endif /* LWIP_UDP */ + +#if LWIP_TCP +/** + * Receive callback function for TCP netconns. + * Posts the packet to conn->recvmbox, but doesn't delete it on errors. + * + * @see tcp.h (struct tcp_pcb.recv) for parameters and return value + */ +static err_t +recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct netconn *conn; + u16_t len; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); + + if (conn == NULL) { + return ERR_VAL; + } + if (!sys_mbox_valid(&conn->recvmbox)) { + /* recvmbox already deleted */ + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } + return ERR_OK; + } + /* Unlike for UDP or RAW pcbs, don't check for available space + using recv_avail since that could break the connection + (data is already ACKed) */ + + /* don't overwrite fatal errors! */ + NETCONN_SET_SAFE_ERR(conn, err); + + if (p != NULL) { + len = p->tot_len; + } else { + len = 0; + } + + if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { + /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ + return ERR_MEM; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + + return ERR_OK; +} + +/** + * Poll callback function for TCP netconns. + * Wakes up an application thread that waits for a connection to close + * or data to be sent. The application thread then takes the + * appropriate action to go on. + * + * Signals the conn->sem. + * netconn_close waits for conn->sem if closing failed. + * + * @see tcp.h (struct tcp_pcb.poll) for parameters and return value + */ +static err_t +poll_tcp(void *arg, struct tcp_pcb *pcb) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + /* @todo: implement connect timeout here? */ + + /* Did a nonblocking write fail before? Then check available write-space. */ + if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + } + + return ERR_OK; +} + +/** + * Sent callback function for TCP netconns. + * Signals the conn->sem and calls API_EVENT. + * netconn_write waits for conn->sem if send buffer is low. + * + * @see tcp.h (struct tcp_pcb.sent) for parameters and return value + */ +static err_t +sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + do_close_internal(conn); + } + + if (conn) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); + } + } + + return ERR_OK; +} + +/** + * Error callback function for TCP netconns. + * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. + * The application thread has then to decide what to do. + * + * @see tcp.h (struct tcp_pcb.err) for parameters + */ +static void +err_tcp(void *arg, err_t err) +{ + struct netconn *conn; + enum netconn_state old_state; + SYS_ARCH_DECL_PROTECT(lev); + + conn = (struct netconn *)arg; + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + conn->pcb.tcp = NULL; + + /* no check since this is always fatal! */ + SYS_ARCH_PROTECT(lev); + conn->last_err = err; + SYS_ARCH_UNPROTECT(lev); + + /* reset conn->state now before waking up other threads */ + old_state = conn->state; + conn->state = NETCONN_NONE; + + /* Notify the user layer about a connection error. Used to signal + select. */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + /* Try to release selects pending on 'read' or 'write', too. + They will get an error if they actually try to read or write. */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + /* pass NULL-message to recvmbox to wake up pending recv */ + if (sys_mbox_valid(&conn->recvmbox)) { + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->recvmbox, NULL); + } + /* pass NULL-message to acceptmbox to wake up pending accept */ + if (sys_mbox_valid(&conn->acceptmbox)) { + /* use trypost to preven deadlock */ + sys_mbox_trypost(&conn->acceptmbox, NULL); + } + + if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || + (old_state == NETCONN_CONNECT)) { + /* calling do_writemore/do_close_internal is not necessary + since the pcb has already been deleted! */ + int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + + if (!was_nonblocking_connect) { + /* set error return code */ + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + conn->current_msg->err = err; + conn->current_msg = NULL; + /* wake up the waiting task */ + sys_sem_signal(&conn->op_completed); + } + } else { + LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); + } +} + +/** + * Setup a tcp_pcb with the correct callback function pointers + * and their arguments. + * + * @param conn the TCP netconn to setup + */ +static void +setup_tcp(struct netconn *conn) +{ + struct tcp_pcb *pcb; + + pcb = conn->pcb.tcp; + tcp_arg(pcb, conn); + tcp_recv(pcb, recv_tcp); + tcp_sent(pcb, sent_tcp); + tcp_poll(pcb, poll_tcp, 4); + tcp_err(pcb, err_tcp); +} + +/** + * Accept callback function for TCP netconns. + * Allocates a new netconn and posts that to conn->acceptmbox. + * + * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value + */ +static err_t +accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + struct netconn *newconn; + struct netconn *conn = (struct netconn *)arg; + + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); + + if (!sys_mbox_valid(&conn->acceptmbox)) { + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); + return ERR_VAL; + } + + /* We have to set the callback here even though + * the new socket is unknown. conn->socket is marked as -1. */ + newconn = netconn_alloc(conn->type, conn->callback); + if (newconn == NULL) { + return ERR_MEM; + } + newconn->pcb.tcp = newpcb; + setup_tcp(newconn); + /* no protection: when creating the pcb, the netconn is not yet known + to the application thread */ + newconn->last_err = err; + + if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { + /* When returning != ERR_OK, the pcb is aborted in tcp_process(), + so do nothing here! */ + /* remove all references to this netconn from the pcb */ + struct tcp_pcb* pcb = newconn->pcb.tcp; + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_poll(pcb, NULL, 4); + tcp_err(pcb, NULL); + /* remove reference from to the pcb from this netconn */ + newconn->pcb.tcp = NULL; + /* no need to drain since we know the recvmbox is empty. */ + sys_mbox_free(&newconn->recvmbox); + sys_mbox_set_invalid(&newconn->recvmbox); + netconn_free(newconn); + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Create a new pcb of a specific type. + * Called from do_newconn(). + * + * @param msg the api_msg_msg describing the connection type + * @return msg->conn->err, but the return value is currently ignored + */ +static void +pcb_new(struct api_msg_msg *msg) +{ + LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); + + /* Allocate a PCB for this connection */ + switch(NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->pcb.raw = raw_new(msg->msg.n.proto); + if(msg->conn->pcb.raw == NULL) { + msg->err = ERR_MEM; + break; + } + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp = udp_new(); + if(msg->conn->pcb.udp == NULL) { + msg->err = ERR_MEM; + break; + } +#if LWIP_UDPLITE + if (msg->conn->type==NETCONN_UDPLITE) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } +#endif /* LWIP_UDPLITE */ + if (msg->conn->type==NETCONN_UDPNOCHKSUM) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->pcb.tcp = tcp_new(); + if(msg->conn->pcb.tcp == NULL) { + msg->err = ERR_MEM; + break; + } + setup_tcp(msg->conn); + break; +#endif /* LWIP_TCP */ + default: + /* Unsupported netconn type, e.g. protocol disabled */ + msg->err = ERR_VAL; + break; + } +} + +/** + * Create a new pcb of a specific type inside a netconn. + * Called from netconn_new_with_proto_and_callback. + * + * @param msg the api_msg_msg describing the connection type + */ +void +do_newconn(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if(msg->conn->pcb.tcp == NULL) { + pcb_new(msg); + } + /* Else? This "new" connection already has a PCB allocated. */ + /* Is this an error condition? Should it be deleted? */ + /* We currently just are happy and return. */ + + TCPIP_APIMSG_ACK(msg); +} + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is NOT created! + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_alloc(enum netconn_type t, netconn_callback callback) +{ + struct netconn *conn; + int size = 0; + + conn = (struct netconn *)memp_malloc(MEMP_NETCONN); + if (conn == NULL) { + return NULL; + } + + conn->last_err = ERR_OK; + conn->type = t; + conn->pcb.tcp = NULL; + +#if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \ + (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE) + size = DEFAULT_RAW_RECVMBOX_SIZE; +#else + switch(NETCONNTYPE_GROUP(t)) { +#if LWIP_RAW + case NETCONN_RAW: + size = DEFAULT_RAW_RECVMBOX_SIZE; + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + size = DEFAULT_UDP_RECVMBOX_SIZE; + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + size = DEFAULT_TCP_RECVMBOX_SIZE; + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); + goto free_and_return; + } +#endif + + if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { + goto free_and_return; + } + if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { + sys_sem_free(&conn->op_completed); + goto free_and_return; + } + +#if LWIP_TCP + sys_mbox_set_invalid(&conn->acceptmbox); +#endif + conn->state = NETCONN_NONE; +#if LWIP_SOCKET + /* initialize socket to -1 since 0 is a valid socket */ + conn->socket = -1; +#endif /* LWIP_SOCKET */ + conn->callback = callback; +#if LWIP_TCP + conn->current_msg = NULL; + conn->write_offset = 0; +#endif /* LWIP_TCP */ +#if LWIP_SO_SNDTIMEO + conn->send_timeout = 0; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + conn->recv_timeout = 0; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; + conn->recv_avail = 0; +#endif /* LWIP_SO_RCVBUF */ + conn->flags = 0; + return conn; +free_and_return: + memp_free(MEMP_NETCONN, conn); + return NULL; +} + +/** + * Delete a netconn and all its resources. + * The pcb is NOT freed (since we might not be in the right thread context do this). + * + * @param conn the netconn to free + */ +void +netconn_free(struct netconn *conn) +{ + LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); + LWIP_ASSERT("recvmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("acceptmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ + + sys_sem_free(&conn->op_completed); + sys_sem_set_invalid(&conn->op_completed); + + memp_free(MEMP_NETCONN, conn); +} + +/** + * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in + * these mboxes + * + * @param conn the netconn to free + * @bytes_drained bytes drained from recvmbox + * @accepts_drained pending connections drained from acceptmbox + */ +static void +netconn_drain(struct netconn *conn) +{ + void *mem; +#if LWIP_TCP + struct pbuf *p; +#endif /* LWIP_TCP */ + + /* This runs in tcpip_thread, so we don't need to lock against rx packets */ + + /* Delete and drain the recvmbox. */ + if (sys_mbox_valid(&conn->recvmbox)) { + while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { +#if LWIP_TCP + if (conn->type == NETCONN_TCP) { + if(mem != NULL) { + p = (struct pbuf*)mem; + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_recved(conn->pcb.tcp, p->tot_len); + } + pbuf_free(p); + } + } else +#endif /* LWIP_TCP */ + { + netbuf_delete((struct netbuf *)mem); + } + } + sys_mbox_free(&conn->recvmbox); + sys_mbox_set_invalid(&conn->recvmbox); + } + + /* Delete and drain the acceptmbox. */ +#if LWIP_TCP + if (sys_mbox_valid(&conn->acceptmbox)) { + while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { + struct netconn *newconn = (struct netconn *)mem; + /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_accepted(conn->pcb.tcp); + } + /* drain recvmbox */ + netconn_drain(newconn); + if (newconn->pcb.tcp != NULL) { + tcp_abort(newconn->pcb.tcp); + newconn->pcb.tcp = NULL; + } + netconn_free(newconn); + } + sys_mbox_free(&conn->acceptmbox); + sys_mbox_set_invalid(&conn->acceptmbox); + } +#endif /* LWIP_TCP */ +} + +#if LWIP_TCP +/** + * Internal helper function to close a TCP netconn: since this sometimes + * doesn't work at the first attempt, this function is called from multiple + * places. + * + * @param conn the TCP netconn to close + */ +static void +do_close_internal(struct netconn *conn) +{ + err_t err; + u8_t shut, shut_rx, shut_tx, close; + + LWIP_ASSERT("invalid conn", (conn != NULL)); + LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP)); + LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + + shut = conn->current_msg->msg.sd.shut; + shut_rx = shut & NETCONN_SHUT_RD; + shut_tx = shut & NETCONN_SHUT_WR; + /* shutting down both ends is the same as closing */ + close = shut == NETCONN_SHUT_RDWR; + + /* Set back some callback pointers */ + if (close) { + tcp_arg(conn->pcb.tcp, NULL); + } + if (conn->pcb.tcp->state == LISTEN) { + tcp_accept(conn->pcb.tcp, NULL); + } else { + /* some callbacks have to be reset if tcp_close is not successful */ + if (shut_rx) { + tcp_recv(conn->pcb.tcp, NULL); + tcp_accept(conn->pcb.tcp, NULL); + } + if (shut_tx) { + tcp_sent(conn->pcb.tcp, NULL); + } + if (close) { + tcp_poll(conn->pcb.tcp, NULL, 4); + tcp_err(conn->pcb.tcp, NULL); + } + } + /* Try to close the connection */ + if (close) { + err = tcp_close(conn->pcb.tcp); + } else { + err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx); + } + if (err == ERR_OK) { + /* Closing succeeded */ + conn->current_msg->err = ERR_OK; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (close) { + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + /* Trigger select() in socket layer. Make sure everybody notices activity + on the connection, error first! */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + } + if (shut_rx) { + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + if (shut_tx) { + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + /* wake up the application task */ + sys_sem_signal(&conn->op_completed); + } else { + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); + tcp_sent(conn->pcb.tcp, sent_tcp); + tcp_poll(conn->pcb.tcp, poll_tcp, 4); + tcp_err(conn->pcb.tcp, err_tcp); + tcp_arg(conn->pcb.tcp, conn); + /* don't restore recv callback: we don't want to receive any more data */ + } + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ +} +#endif /* LWIP_TCP */ + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_delconn(struct api_msg_msg *msg) +{ + /* @todo TCP: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && + (msg->conn->state != NETCONN_LISTEN) && + (msg->conn->state != NETCONN_CONNECT)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else { + LWIP_ASSERT("blocking connect in progress", + (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + + if (msg->conn->pcb.tcp != NULL) { + + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + raw_remove(msg->conn->pcb.raw); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp->recv_arg = NULL; + udp_remove(msg->conn->pcb.udp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->msg.sd.shut = NETCONN_SHUT_RDWR; + msg->conn->current_msg = msg; + do_close_internal(msg->conn); + /* API_EVENT is called inside do_close_internal, before releasing + the application thread, so we can return at this point! */ + return; +#endif /* LWIP_TCP */ + default: + break; + } + msg->conn->pcb.tcp = NULL; + } + /* tcp netconns don't come here! */ + + /* @todo: this lets select make the socket readable and writable, + which is wrong! errfd instead? */ + API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); + } + if (sys_sem_valid(&msg->conn->op_completed)) { + sys_sem_signal(&msg->conn->op_completed); + } +} + +/** + * Bind a pcb contained in a netconn + * Called from netconn_bind. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to bind to + */ +void +do_bind(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_VAL; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_TCP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * TCP callback function if a connection (opened by tcp_connect/do_connect) has + * been established (or reset by the remote host). + * + * @see tcp.h (struct tcp_pcb.connected) for parameters and return values + */ +static err_t +do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct netconn *conn; + int was_blocking; + + LWIP_UNUSED_ARG(pcb); + + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + + LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); + LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", + (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); + + if (conn->current_msg != NULL) { + conn->current_msg->err = err; + } + if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) { + setup_tcp(conn); + } + was_blocking = !IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (!was_blocking) { + NETCONN_SET_SAFE_ERR(conn, ERR_OK); + } + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + if (was_blocking) { + sys_sem_signal(&conn->op_completed); + } + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Connect a pcb contained inside a netconn + * Called from netconn_connect. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to connect to + */ +void +do_connect(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.tcp == NULL) { + /* This may happen when calling netconn_connect() a second time */ + msg->err = ERR_CLSD; + } else { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + /* Prevent connect while doing any other action. */ + if (msg->conn->state != NETCONN_NONE) { + msg->err = ERR_ISCONN; + } else { + setup_tcp(msg->conn); + msg->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, + msg->msg.bc.port, do_connected); + if (msg->err == ERR_OK) { + u8_t non_blocking = netconn_is_nonblocking(msg->conn); + msg->conn->state = NETCONN_CONNECT; + SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); + if (non_blocking) { + msg->err = ERR_INPROGRESS; + } else { + msg->conn->current_msg = msg; + /* sys_sem_signal() is called from do_connected (or err_tcp()), + * when the connection is established! */ + return; + } + } + } + break; +#endif /* LWIP_TCP */ + default: + LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); + break; + } + } + sys_sem_signal(&msg->conn->op_completed); +} + +/** + * Connect a pcb contained inside a netconn + * Only used for UDP netconns. + * Called from netconn_disconnect. + * + * @param msg the api_msg_msg pointing to the connection to disconnect + */ +void +do_disconnect(struct api_msg_msg *msg) +{ +#if LWIP_UDP + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + udp_disconnect(msg->conn->pcb.udp); + msg->err = ERR_OK; + } else +#endif /* LWIP_UDP */ + { + msg->err = ERR_VAL; + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Set a TCP pcb contained in a netconn into listen mode + * Called from netconn_listen. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_listen(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { + if (msg->conn->state == NETCONN_NONE) { +#if TCP_LISTEN_BACKLOG + struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + if (lpcb == NULL) { + /* in this case, the old pcb is still allocated */ + msg->err = ERR_MEM; + } else { + /* delete the recvmbox and allocate the acceptmbox */ + if (sys_mbox_valid(&msg->conn->recvmbox)) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(&msg->conn->recvmbox); + sys_mbox_set_invalid(&msg->conn->recvmbox); + } + msg->err = ERR_OK; + if (!sys_mbox_valid(&msg->conn->acceptmbox)) { + msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); + } + if (msg->err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } else { + /* since the old pcb is already deallocated, free lpcb now */ + tcp_close(lpcb); + msg->conn->pcb.tcp = NULL; + } + } + } + } else { + msg->err = ERR_ARG; + } + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a RAW or UDP pcb contained in a netconn + * Called from netconn_send + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_send(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); + } else { + msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); + } + break; +#endif +#if LWIP_UDP + case NETCONN_UDP: +#if LWIP_CHECKSUM_ON_COPY + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } else { + msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, + &msg->msg.b->addr, msg->msg.b->port, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } +#else /* LWIP_CHECKSUM_ON_COPY */ + if (ip_addr_isany(&msg->msg.b->addr)) { + msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); + } else { + msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + break; +#endif /* LWIP_UDP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Indicate data has been received from a TCP pcb contained in a netconn + * Called from netconn_recv + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_recv(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if (msg->conn->pcb.tcp != NULL) { + if (msg->conn->type == NETCONN_TCP) { +#if TCP_LISTEN_BACKLOG + if (msg->conn->pcb.tcp->state == LISTEN) { + tcp_accepted(msg->conn->pcb.tcp); + } else +#endif /* TCP_LISTEN_BACKLOG */ + { + u32_t remaining = msg->msg.r.len; + do { + u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; + tcp_recved(msg->conn->pcb.tcp, recved); + remaining -= recved; + }while(remaining != 0); + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ +static err_t +do_writemore(struct netconn *conn) +{ + err_t err; + void *dataptr; + u16_t len, available; + u8_t write_finished = 0; + size_t diff; + u8_t dontblock = netconn_is_nonblocking(conn) || + (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK); + u8_t apiflags = conn->current_msg->msg.w.apiflags; + + LWIP_ASSERT("conn != NULL", conn != NULL); + LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); + LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", + conn->write_offset < conn->current_msg->msg.w.len); + +#if LWIP_SO_SNDTIMEO + if ((conn->send_timeout != 0) && + ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { + write_finished = 1; + if (conn->write_offset == 0) { + /* nothing has been written */ + err = ERR_WOULDBLOCK; + conn->current_msg->msg.w.len = 0; + } else { + /* partial write */ + err = ERR_OK; + conn->current_msg->msg.w.len = conn->write_offset; + } + } else +#endif /* LWIP_SO_SNDTIMEO */ + { + dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; + diff = conn->current_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; + if (dontblock){ + if (!len) { + err = ERR_WOULDBLOCK; + goto err_mem; + } + } else { +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } + } + LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); + err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); + /* if OK or memory error, check available space */ + if ((err == ERR_OK) || (err == ERR_MEM)) { +err_mem: + if (dontblock && (len < conn->current_msg->msg.w.len)) { + /* non-blocking write did not write everything: mark the pcb non-writable + and let poll_tcp check writable space to mark the pcb writable again */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + /* The queued byte- or pbuf-count exceeds the configured low-water limit, + let select mark this pcb as non-writable. */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + } + } + + if (err == ERR_OK) { + conn->write_offset += len; + if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length */ + conn->current_msg->msg.w.len = conn->write_offset; + /* everything was written */ + write_finished = 1; + conn->write_offset = 0; + } + tcp_output(conn->pcb.tcp); + } else if ((err == ERR_MEM) && !dontblock) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called + we do NOT return to the application thread, since ERR_MEM is + only a temporary error! */ + + /* tcp_write returned ERR_MEM, try tcp_output anyway */ + tcp_output(conn->pcb.tcp); + +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + } else { + /* On errors != ERR_MEM, we don't try writing any more but return + the error to the application thread. */ + write_finished = 1; + conn->current_msg->msg.w.len = 0; + } + } + if (write_finished) { + /* everything was written: set back connection state + and back to application task */ + conn->current_msg->err = err; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; +#if LWIP_TCPIP_CORE_LOCKING + if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0) +#endif + { + sys_sem_signal(&conn->op_completed); + } + } +#if LWIP_TCPIP_CORE_LOCKING + else + return ERR_MEM; +#endif + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a TCP pcb contained in a netconn + * Called from netconn_write + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_write(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (msg->conn->type == NETCONN_TCP) { +#if LWIP_TCP + if (msg->conn->state != NETCONN_NONE) { + /* netconn is connecting, closing or in blocking write */ + msg->err = ERR_INPROGRESS; + } else if (msg->conn->pcb.tcp != NULL) { + msg->conn->state = NETCONN_WRITE; + /* set all the variables used by do_writemore */ + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); + msg->conn->current_msg = msg; + msg->conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; + if (do_writemore(msg->conn) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(&msg->conn->op_completed, 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + do_writemore(msg->conn); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + /* for both cases: if do_writemore was called, don't ACK the APIMSG + since do_writemore ACKs it! */ + return; + } else { + msg->err = ERR_CONN; + } +#else /* LWIP_TCP */ + msg->err = ERR_VAL; +#endif /* LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Return a connection's local or remote address + * Called from netconn_getaddr + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_getaddr(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.ip != NULL) { + *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip : + msg->conn->pcb.ip->remote_ip); + + msg->err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + } else { + /* return an error as connecting is only a helper for upper layers */ + msg->err = ERR_CONN; + } + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + if (msg->msg.ad.local) { + *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + } else { + if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { + msg->err = ERR_CONN; + } else { + *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + } + } + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("invalid netconn_type", 0); + break; + } + } else { + msg->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Close a TCP pcb contained in a netconn + * Called from netconn_close + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_close(struct api_msg_msg *msg) +{ +#if LWIP_TCP + /* @todo: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { + if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) { + /* LISTEN doesn't support half shutdown */ + msg->err = ERR_CONN; + } else { + if (msg->msg.sd.shut & NETCONN_SHUT_RD) { + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + } + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->conn->current_msg = msg; + do_close_internal(msg->conn); + /* for tcp netconns, do_close_internal ACKs the message */ + return; + } + } else +#endif /* LWIP_TCP */ + { + msg->err = ERR_VAL; + } + sys_sem_signal(&msg->conn->op_completed); +} + +#if LWIP_IGMP +/** + * Join multicast groups for UDP netconns. + * Called from netconn_join_leave_group + * + * @param msg the api_msg_msg pointing to the connection + */ +void +do_join_leave_group(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { +#if LWIP_UDP + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + } else { + msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); + } +#endif /* LWIP_UDP */ +#if (LWIP_TCP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_TCP || LWIP_RAW) */ + } + } else { + msg->err = ERR_CONN; + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Callback function that is called when DNS name is resolved + * (or on timeout). A waiting application thread is waked up by + * signaling the semaphore. + */ +static void +do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); + LWIP_UNUSED_ARG(name); + + if (ipaddr == NULL) { + /* timeout or memory error */ + *msg->err = ERR_VAL; + } else { + /* address was resolved */ + *msg->err = ERR_OK; + *msg->addr = *ipaddr; + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); +} + +/** + * Execute a DNS query + * Called from netconn_gethostbyname + * + * @param arg the dns_api_msg pointing to the query + */ +void +do_gethostbyname(void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg); + if (*msg->err != ERR_INPROGRESS) { + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(msg->sem); + } +} +#endif /* LWIP_DNS */ + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/err.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/err.c new file mode 100644 index 0000000..51b32ea --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/err.c @@ -0,0 +1,75 @@ +/** + * @file + * Error Management module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/err.h" + +#ifdef LWIP_DEBUG + +static const char *err_strerr[] = { + "Ok", /* ERR_OK 0 */ + "Out of memory error", /* ERR_MEM -1 */ + "Buffer error", /* ERR_BUF -2 */ + "Timeout", /* ERR_TIMEOUT -3 */ + "Routing problem", /* ERR_RTE -4 */ + "Operation in progress", /* ERR_INPROGRESS -5 */ + "Illegal value", /* ERR_VAL -6 */ + "Operation would block", /* ERR_WOULDBLOCK -7 */ + "Address in use", /* ERR_USE -8 */ + "Already connected", /* ERR_ISCONN -9 */ + "Connection aborted", /* ERR_ABRT -10 */ + "Connection reset", /* ERR_RST -11 */ + "Connection closed", /* ERR_CLSD -12 */ + "Not connected", /* ERR_CONN -13 */ + "Illegal argument", /* ERR_ARG -14 */ + "Low-level netif error", /* ERR_IF -15 */ +}; + +/** + * Convert an lwip internal error to a string representation. + * + * @param err an lwip internal err_t + * @return a string representation for err + */ +const char * +lwip_strerr(err_t err) +{ + return err_strerr[-err]; + +} + +#endif /* LWIP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netbuf.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netbuf.c new file mode 100644 index 0000000..9390c9e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netbuf.c @@ -0,0 +1,245 @@ +/** + * @file + * Network buffer management + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netbuf.h" +#include "lwip/memp.h" + +#include + +/** + * Create (allocate) and initialize a new netbuf. + * The netbuf doesn't yet contain a packet buffer! + * + * @return a pointer to a new netbuf + * NULL on lack of memory + */ +struct +netbuf *netbuf_new(void) +{ + struct netbuf *buf; + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf != NULL) { + buf->p = NULL; + buf->ptr = NULL; + ip_addr_set_any(&buf->addr); + buf->port = 0; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + buf->flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + buf->toport_chksum = 0; +#if LWIP_NETBUF_RECVINFO + ip_addr_set_any(&buf->toaddr); +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ + return buf; + } else { + return NULL; + } +} + +/** + * Deallocate a netbuf allocated by netbuf_new(). + * + * @param buf pointer to a netbuf allocated by netbuf_new() + */ +void +netbuf_delete(struct netbuf *buf) +{ + if (buf != NULL) { + if (buf->p != NULL) { + pbuf_free(buf->p); + buf->p = buf->ptr = NULL; + } + memp_free(MEMP_NETBUF, buf); + } +} + +/** + * Allocate memory for a packet buffer for a given netbuf. + * + * @param buf the netbuf for which to allocate a packet buffer + * @param size the size of the packet buffer to allocate + * @return pointer to the allocated memory + * NULL if no memory could be allocated + */ +void * +netbuf_alloc(struct netbuf *buf, u16_t size) +{ + LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); + + /* Deallocate any previously allocated memory. */ + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); + if (buf->p == NULL) { + return NULL; + } + LWIP_ASSERT("check that first pbuf can hold size", + (buf->p->len >= size)); + buf->ptr = buf->p; + return buf->p->payload; +} + +/** + * Free the packet buffer included in a netbuf + * + * @param buf pointer to the netbuf which contains the packet buffer to free + */ +void +netbuf_free(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = buf->ptr = NULL; +} + +/** + * Let a netbuf reference existing (non-volatile) data. + * + * @param buf netbuf which should reference the data + * @param dataptr pointer to the data to reference + * @param size size of the data + * @return ERR_OK if data is referenced + * ERR_MEM if data couldn't be referenced due to lack of memory + */ +err_t +netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) +{ + LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (buf->p == NULL) { + buf->ptr = NULL; + return ERR_MEM; + } + buf->p->payload = (void*)dataptr; + buf->p->len = buf->p->tot_len = size; + buf->ptr = buf->p; + return ERR_OK; +} + +/** + * Chain one netbuf to another (@see pbuf_chain) + * + * @param head the first netbuf + * @param tail netbuf to chain after head, freed by this function, may not be reference after returning + */ +void +netbuf_chain(struct netbuf *head, struct netbuf *tail) +{ + LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); + LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); + pbuf_cat(head->p, tail->p); + head->ptr = head->p; + memp_free(MEMP_NETBUF, tail); +} + +/** + * Get the data pointer and length of the data inside a netbuf. + * + * @param buf netbuf to get the data from + * @param dataptr pointer to a void pointer where to store the data pointer + * @param len pointer to an u16_t where the length of the data is stored + * @return ERR_OK if the information was retreived, + * ERR_BUF on error. + */ +err_t +netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) +{ + LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); + + if (buf->ptr == NULL) { + return ERR_BUF; + } + *dataptr = buf->ptr->payload; + *len = buf->ptr->len; + return ERR_OK; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the next part. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + * @return -1 if there is no next part + * 1 if moved to the next part but now there is no next part + * 0 if moved to the next part and there are still more parts + */ +s8_t +netbuf_next(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;); + if (buf->ptr->next == NULL) { + return -1; + } + buf->ptr = buf->ptr->next; + if (buf->ptr->next == NULL) { + return 1; + } + return 0; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the beginning of the packet. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + */ +void +netbuf_first(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + buf->ptr = buf->p; +} + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netdb.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netdb.c new file mode 100644 index 0000000..6a4bac5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netdb.c @@ -0,0 +1,353 @@ +/** + * @file + * API functions for name resolving + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/netdb.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include "lwip/err.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/api.h" +#include "lwip/dns.h" + +#include +#include + +/** helper struct for gethostbyname_r to access the char* buffer */ +struct gethostbyname_r_helper { + ip_addr_t *addr_list[2]; + ip_addr_t addr; + char *aliases; +}; + +/** h_errno is exported in netdb.h for access by applications. */ +#if LWIP_DNS_API_DECLARE_H_ERRNO +int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ + +/** define "hostent" variables storage: 0 if we use a static (but unprotected) + * set of variables for lwip_gethostbyname, 1 if we use a local storage */ +#ifndef LWIP_DNS_API_HOSTENT_STORAGE +#define LWIP_DNS_API_HOSTENT_STORAGE 0 +#endif + +/** define "hostent" variables storage */ +#if LWIP_DNS_API_HOSTENT_STORAGE +#define HOSTENT_STORAGE +#else +#define HOSTENT_STORAGE static +#endif /* LWIP_DNS_API_STATIC_HOSTENT */ + +/** + * Returns an entry containing addresses of address family AF_INET + * for the host with name name. + * Due to dns_gethostbyname limitations, only one address is returned. + * + * @param name the hostname to resolve + * @return an entry containing addresses of address family AF_INET + * for the host with name name + */ +struct hostent* +lwip_gethostbyname(const char *name) +{ + err_t err; + ip_addr_t addr; + + /* buffer variables for lwip_gethostbyname() */ + HOSTENT_STORAGE struct hostent s_hostent; + HOSTENT_STORAGE char *s_aliases; + HOSTENT_STORAGE ip_addr_t s_hostent_addr; + HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; + + /* query host IP address */ + err = netconn_gethostbyname(name, &addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + h_errno = HOST_NOT_FOUND; + return NULL; + } + + /* fill hostent */ + s_hostent_addr = addr; + s_phostent_addr[0] = &s_hostent_addr; + s_phostent_addr[1] = NULL; + s_hostent.h_name = (char*)name; + s_hostent.h_aliases = &s_aliases; + s_hostent.h_addrtype = AF_INET; + s_hostent.h_length = sizeof(ip_addr_t); + s_hostent.h_addr_list = (char**)&s_phostent_addr; + +#if DNS_DEBUG + /* dump hostent */ + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); + if (s_hostent.h_aliases != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_aliases[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %p\n", idx, s_hostent.h_aliases[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases[%i]-> == %s\n", idx, s_hostent.h_aliases[idx])); + } + } + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); + if (s_hostent.h_addr_list != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx]))); + } + } +#endif /* DNS_DEBUG */ + +#if LWIP_DNS_API_HOSTENT_STORAGE + /* this function should return the "per-thread" hostent after copy from s_hostent */ + return sys_thread_hostent(&s_hostent); +#else + return &s_hostent; +#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ +} + +/** + * Thread-safe variant of lwip_gethostbyname: instead of using a static + * buffer, this function takes buffer and errno pointers as arguments + * and uses these for the result. + * + * @param name the hostname to resolve + * @param ret pre-allocated struct where to store the result + * @param buf pre-allocated buffer where to store additional data + * @param buflen the size of buf + * @param result pointer to a hostent pointer that is set to ret on success + * and set to zero on error + * @param h_errnop pointer to an int where to store errors (instead of modifying + * the global h_errno) + * @return 0 on success, non-zero on error, additional error information + * is stored in *h_errnop instead of h_errno to be thread-safe + */ +int +lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + err_t err; + struct gethostbyname_r_helper *h; + char *hostname; + size_t namelen; + int lh_errno; + + if (h_errnop == NULL) { + /* ensure h_errnop is never NULL */ + h_errnop = &lh_errno; + } + + if (result == NULL) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + /* first thing to do: set *result to nothing */ + *result = NULL; + if ((name == NULL) || (ret == NULL) || (buf == NULL)) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + + namelen = strlen(name); + if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { + /* buf can't hold the data needed + a copy of name */ + *h_errnop = ERANGE; + return -1; + } + + h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); + hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); + + /* query host IP address */ + err = netconn_gethostbyname(name, &h->addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + *h_errnop = HOST_NOT_FOUND; + return -1; + } + + /* copy the hostname into buf */ + MEMCPY(hostname, name, namelen); + hostname[namelen] = 0; + + /* fill hostent */ + h->addr_list[0] = &h->addr; + h->addr_list[1] = NULL; + h->aliases = NULL; + ret->h_name = hostname; + ret->h_aliases = &h->aliases; + ret->h_addrtype = AF_INET; + ret->h_length = sizeof(ip_addr_t); + ret->h_addr_list = (char**)&h->addr_list; + + /* set result != NULL */ + *result = ret; + + /* return success */ + return 0; +} + +/** + * Frees one or more addrinfo structures returned by getaddrinfo(), along with + * any additional storage associated with those structures. If the ai_next field + * of the structure is not null, the entire list of structures is freed. + * + * @param ai struct addrinfo to free + */ +void +lwip_freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + while (ai != NULL) { + next = ai->ai_next; + memp_free(MEMP_NETDB, ai); + ai = next; + } +} + +/** + * Translates the name of a service location (for example, a host name) and/or + * a service name and returns a set of socket addresses and associated + * information to be used in creating a socket with which to address the + * specified service. + * Memory for the result is allocated internally and must be freed by calling + * lwip_freeaddrinfo()! + * + * Due to a limitation in dns_gethostbyname, only the first address of a + * host is returned. + * Also, service names are not supported (only port numbers)! + * + * @param nodename descriptive name or address string of the host + * (may be NULL -> local address) + * @param servname port number as string of NULL + * @param hints structure containing input values that set socktype and protocol + * @param res pointer to a pointer where to store the result (set to NULL on failure) + * @return 0 on success, non-zero on failure + */ +int +lwip_getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + err_t err; + ip_addr_t addr; + struct addrinfo *ai; + struct sockaddr_in *sa = NULL; + int port_nr = 0; + size_t total_size; + size_t namelen = 0; + + if (res == NULL) { + return EAI_FAIL; + } + *res = NULL; + if ((nodename == NULL) && (servname == NULL)) { + return EAI_NONAME; + } + + if (servname != NULL) { + /* service name specified: convert to port number + * @todo?: currently, only ASCII integers (port numbers) are supported! */ + port_nr = atoi(servname); + if ((port_nr <= 0) || (port_nr > 0xffff)) { + return EAI_SERVICE; + } + } + + if (nodename != NULL) { + /* service location specified, try to resolve */ + err = netconn_gethostbyname(nodename, &addr); + if (err != ERR_OK) { + return EAI_FAIL; + } + } else { + /* service location specified, use loopback address */ + ip_addr_set_loopback(&addr); + } + + total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in); + if (nodename != NULL) { + namelen = strlen(nodename); + LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); + total_size += namelen + 1; + } + /* If this fails, please report to lwip-devel! :-) */ + LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", + total_size <= NETDB_ELEM_SIZE); + ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); + if (ai == NULL) { + goto memerr; + } + memset(ai, 0, total_size); + sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo)); + /* set up sockaddr */ + inet_addr_from_ipaddr(&sa->sin_addr, &addr); + sa->sin_family = AF_INET; + sa->sin_len = sizeof(struct sockaddr_in); + sa->sin_port = htons((u16_t)port_nr); + + /* set up addrinfo */ + ai->ai_family = AF_INET; + if (hints != NULL) { + /* copy socktype & protocol from hints if specified */ + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + if (nodename != NULL) { + /* copy nodename to canonname if specified */ + ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + MEMCPY(ai->ai_canonname, nodename, namelen); + ai->ai_canonname[namelen] = 0; + } + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr = (struct sockaddr*)sa; + + *res = ai; + + return 0; +memerr: + if (ai != NULL) { + memp_free(MEMP_NETDB, ai); + } + return EAI_MEMORY; +} + +#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netifapi.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netifapi.c new file mode 100644 index 0000000..43e4720 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/netifapi.c @@ -0,0 +1,160 @@ +/** + * @file + * Network Interface Sequential API module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netifapi.h" +#include "lwip/tcpip.h" + +/** + * Call netif_add() inside the tcpip_thread context. + */ +void +do_netifapi_netif_add(struct netifapi_msg_msg *msg) +{ + if (!netif_add( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw, + msg->msg.add.state, + msg->msg.add.init, + msg->msg.add.input)) { + msg->err = ERR_IF; + } else { + msg->err = ERR_OK; + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_set_addr() inside the tcpip_thread context. + */ +void +do_netifapi_netif_set_addr(struct netifapi_msg_msg *msg) +{ + netif_set_addr( msg->netif, + msg->msg.add.ipaddr, + msg->msg.add.netmask, + msg->msg.add.gw); + msg->err = ERR_OK; + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the + * tcpip_thread context. + */ +void +do_netifapi_netif_common(struct netifapi_msg_msg *msg) +{ + if (msg->msg.common.errtfunc != NULL) { + msg->err = msg->msg.common.errtfunc(msg->netif); + } else { + msg->err = ERR_OK; + msg->msg.common.voidfunc(msg->netif); + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_add() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_add() + */ +err_t +netifapi_netif_add(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_add; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + msg.msg.msg.add.state = state; + msg.msg.msg.add.init = init; + msg.msg.msg.add.input = input; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * Call netif_set_addr() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_set_addr() + */ +err_t +netifapi_netif_set_addr(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_set_addr; + msg.msg.netif = netif; + msg.msg.msg.add.ipaddr = ipaddr; + msg.msg.msg.add.netmask = netmask; + msg.msg.msg.add.gw = gw; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +/** + * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe + * way by running that function inside the tcpip_thread context. + * + * @note use only for functions where there is only "netif" parameter. + */ +err_t +netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc) +{ + struct netifapi_msg msg; + msg.function = do_netifapi_netif_common; + msg.msg.netif = netif; + msg.msg.msg.common.voidfunc = voidfunc; + msg.msg.msg.common.errtfunc = errtfunc; + TCPIP_NETIFAPI(&msg); + return msg.msg.err; +} + +#endif /* LWIP_NETIF_API */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/sockets.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/sockets.c new file mode 100644 index 0000000..5669497 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/sockets.c @@ -0,0 +1,2453 @@ +/** + * @file + * Sockets BSD-Like API module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sockets.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcpip.h" +#include "lwip/pbuf.h" +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** Contains all internal pointers and states used for a socket */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + void *lastdata; + /** offset in the data that was left from the previous read */ + u16_t lastoffset; + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** last error that occurred on this socket */ + int err; + /** counter of how many threads are waiting for this socket using select */ + int select_waiting; +}; + +/** Description for a task waiting in select */ +struct lwip_select_cb { + /** Pointer to the next waiting task */ + struct lwip_select_cb *next; + /** Pointer to the previous waiting task */ + struct lwip_select_cb *prev; + /** readset passed to select */ + fd_set *readset; + /** writeset passed to select */ + fd_set *writeset; + /** unimplemented: exceptset passed to select */ + fd_set *exceptset; + /** don't signal the same semaphore twice: set to 1 when signalled */ + int sem_signalled; + /** semaphore to wake up a task waiting for select */ + sys_sem_t sem; +}; + +/** This struct is used to pass data to the set/getsockopt_internal + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket struct for which to change options */ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + /** socket index for which to change options */ + int s; +#endif /* LWIP_DEBUG */ + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ + void *optval; + /** size of *optval */ + socklen_t *optlen; + /** if an error occures, it is temporarily stored here */ + err_t err; +}; + +/** The global array of available sockets */ +static struct lwip_sock sockets[NUM_SOCKETS]; +/** The global list of tasks waiting for select */ +static struct lwip_select_cb *select_cb_list; +/** This counter is increased from lwip_select when the list is chagned + and checked in event_callback to see if it has changed. */ +static volatile int select_cb_ctr; + +/** Table to quickly map an lwIP error (err_t) to a socket error + * by using -err as an index */ +static const int err_to_errno_table[] = { + 0, /* ERR_OK 0 No error, everything OK. */ + ENOMEM, /* ERR_MEM -1 Out of memory error. */ + ENOBUFS, /* ERR_BUF -2 Buffer error. */ + EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + EINVAL, /* ERR_VAL -6 Illegal value. */ + EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ + EALREADY, /* ERR_ISCONN -9 Already connected. */ + ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */ + ECONNRESET, /* ERR_RST -11 Connection reset. */ + ENOTCONN, /* ERR_CLSD -12 Connection closed. */ + ENOTCONN, /* ERR_CONN -13 Not connected. */ + EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ +}; + +#define ERR_TO_ERRNO_TABLE_SIZE \ + (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) + +#define err_to_errno(err) \ + ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ + err_to_errno_table[-(err)] : EIO) + +#ifdef ERRNO +#ifndef set_errno +#define set_errno(err) errno = (err) +#endif +#else /* ERRNO */ +#define set_errno(err) +#endif /* ERRNO */ + +#define sock_set_errno(sk, e) do { \ + sk->err = (e); \ + set_errno(sk->err); \ +} while (0) + +/* Forward delcaration of some functions */ +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); +static void lwip_getsockopt_internal(void *arg); +static void lwip_setsockopt_internal(void *arg); + +/** + * Initialize this module. This function has to be called before any other + * functions in this module! + */ +void +lwip_socket_init(void) +{ +} +/** + * Map a externally used socket index to the internal socket representation. + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +get_socket(int s) +{ + struct lwip_sock *sock; + + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); + set_errno(EBADF); + return NULL; + } + + sock = &sockets[s]; + + if (!sock->conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); + set_errno(EBADF); + return NULL; + } + + return sock; +} + +/* + * pvvx: errno + */ +int lwip_last_err_socket(int s) { + struct lwip_sock * sc = get_socket(s); + if(sc) return sc->err; + else return EBADF; +} +/** + * Same as get_socket but doesn't set errno + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +tryget_socket(int s) +{ + if ((s < 0) || (s >= NUM_SOCKETS)) { + return NULL; + } + if (!sockets[s].conn) { + return NULL; + } + return &sockets[s]; +} + +/** + * Allocate a new socket for a given netconn. + * + * @param newconn the netconn for which to allocate a socket + * @param accepted 1 if socket has been created by accept(), + * 0 if socket has been created by socket() + * @return the index of the new socket; -1 on error + */ +static int +alloc_socket(struct netconn *newconn, int accepted) +{ + int i; + SYS_ARCH_DECL_PROTECT(lev); + + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + if (!sockets[i].conn) { + sockets[i].conn = newconn; + /* The socket is not yet known to anyone, so no need to protect + after having marked it as used. */ + SYS_ARCH_UNPROTECT(lev); + sockets[i].lastdata = NULL; + sockets[i].lastoffset = 0; + sockets[i].rcvevent = 0; + /* TCP sendbuf is empty, but the socket is not yet writable until connected + * (unless it has been created by accept()). */ + sockets[i].sendevent = (newconn->type == NETCONN_TCP ? (accepted != 0) : 1); + sockets[i].errevent = 0; + sockets[i].err = 0; + sockets[i].select_waiting = 0; + return i; + } + SYS_ARCH_UNPROTECT(lev); + } + return -1; +} + +/** Free a socket. The socket's netconn must have been + * delete before! + * + * @param sock the socket to free + * @param is_tcp != 0 for TCP sockets, used to free lastdata + */ +static void +free_socket(struct lwip_sock *sock, int is_tcp) +{ + void *lastdata; + SYS_ARCH_DECL_PROTECT(lev); + + lastdata = sock->lastdata; + sock->lastdata = NULL; + sock->lastoffset = 0; + sock->err = 0; + + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + sock->conn = NULL; + SYS_ARCH_UNPROTECT(lev); + /* don't use 'sock' after this line, as another task might have allocated it */ + + if (lastdata != NULL) { + if (is_tcp) { + pbuf_free((struct pbuf *)lastdata); + } else { + netbuf_delete((struct netbuf *)lastdata); + } + } +} + +/* Below this, the well-known socket functions are implemented. + * Use google.com or opengroup.org to get a good description :-) + * + * Exceptions are documented! + */ + +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct lwip_sock *sock, *nsock; + struct netconn *newconn; + ip_addr_t naddr; + u16_t port; + int newsock; + struct sockaddr_in sin; + err_t err; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + LWIP_ASSERT("newconn != NULL", newconn != NULL); + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(newconn, 1); + + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + netconn_delete(newconn); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if (NULL != addr) { + LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + inet_addr_from_ipaddr(&sin.sin_addr, &naddr); + + if (*addrlen > sizeof(sin)) + *addrlen = sizeof(sin); + + MEMCPY(addr, &sin, *addrlen); + } + + newsock = alloc_socket(newconn, 1); + if (newsock == -1) { + netconn_delete(newconn); + sock_set_errno(sock, ENFILE); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); + LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); + nsock = &sockets[newsock]; + + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + SYS_ARCH_PROTECT(lev); + nsock->rcvevent += (s16_t)(-1 - newconn->socket); + newconn->socket = newsock; + SYS_ARCH_UNPROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + + sock_set_errno(sock, 0); + return newsock; +} + +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + ip_addr_t local_addr; + u16_t local_port; + err_t err; + const struct sockaddr_in *name_in; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check size, familiy and alignment of 'name' */ + LWIP_ERROR("lwip_bind: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + name_in = (const struct sockaddr_in *)(void*)name; + + inet_addr_to_ipaddr(&local_addr, &name_in->sin_addr); + local_port = name_in->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(local_port))); + + err = netconn_bind(sock->conn, &local_addr, ntohs(local_port)); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_close(int s) +{ + struct lwip_sock *sock; + int is_tcp = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if(sock->conn != NULL) { + is_tcp = netconn_type(sock->conn) == NETCONN_TCP; + } else { + LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); + } + + netconn_delete(sock->conn); + + free_socket(sock, is_tcp); + set_errno(0); + return 0; +} + +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + err_t err; + const struct sockaddr_in *name_in; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check size, familiy and alignment of 'name' */ + LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) && + ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + name_in = (const struct sockaddr_in *)(void*)name; + + if (name_in->sin_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + ip_addr_t remote_addr; + u16_t remote_port; + + inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr); + remote_port = name_in->sin_port; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port))); + + err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port)); + } + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +/** + * Set a socket into listen mode. + * The socket may not have been used for another connection previously. + * + * @param s the socket to set to listening mode + * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) + * @return 0 on success, non-zero on failure + */ +int +lwip_listen(int s, int backlog) +{ + struct lwip_sock *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* limit the "backlog" parameter to fit in an u8_t */ + backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); + + err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + struct lwip_sock *sock; + void *buf = NULL; + struct pbuf *p; + u16_t buflen, copylen; + int off = 0; + ip_addr_t *addr; + u16_t port; + u8_t done = 0; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + do { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata) { + buf = sock->lastdata; + } else { + /* If this is non-blocking call, then check first */ + if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && + (sock->rcvevent <= 0)) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* No data was left from the previous operation, so we try to get + some from the network. */ + if (netconn_type(sock->conn) == NETCONN_TCP) { + err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); + } else { + err = netconn_recv(sock->conn, (struct netbuf **)&buf); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", + err, buf)); + + if (err != ERR_OK) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + if (err == ERR_CLSD) { + return 0; + } else { + return -1; + } + } + LWIP_ASSERT("buf != NULL", buf != NULL); + sock->lastdata = buf; + } + + if (netconn_type(sock->conn) == NETCONN_TCP) { + p = (struct pbuf *)buf; + } else { + p = ((struct netbuf *)buf)->p; + } + buflen = p->tot_len; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", + buflen, len, off, sock->lastoffset)); + + buflen -= sock->lastoffset; + + if (len > buflen) { + copylen = buflen; + } else { + copylen = (u16_t)len; + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); + + off += copylen; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); + len -= copylen; + if ( (len <= 0) || + (p->flags & PBUF_FLAG_PUSH) || + (sock->rcvevent <= 0) || + ((flags & MSG_PEEK)!=0)) { + done = 1; + } + } else { + done = 1; + } + + /* Check to see from where the data was.*/ + if (done) { + ip_addr_t fromaddr; + if (from && fromlen) { + struct sockaddr_in sin; + + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = &fromaddr; + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr((struct netbuf *)buf); + port = netbuf_fromport((struct netbuf *)buf); + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + inet_addr_from_ipaddr(&sin.sin_addr, addr); + + if (*fromlen > sizeof(sin)) { + *fromlen = sizeof(sin); + } + + MEMCPY(from, &sin, *fromlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); + } else { +#if SOCKETS_DEBUG + if (netconn_type(sock->conn) == NETCONN_TCP) { + addr = &fromaddr; + netconn_getaddr(sock->conn, addr, &port, 0); + } else { + addr = netbuf_fromaddr((struct netbuf *)buf); + port = netbuf_fromport((struct netbuf *)buf); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); +#endif /* SOCKETS_DEBUG */ + } + } + + /* If we don't peek the incoming message... */ + if ((flags & MSG_PEEK) == 0) { + /* If this is a TCP socket, check if there is data left in the + buffer. If so, it should be saved in the sock structure for next + time around. */ + if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) { + sock->lastdata = buf; + sock->lastoffset += copylen; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); + } else { + sock->lastdata = NULL; + sock->lastoffset = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); + if (netconn_type(sock->conn) == NETCONN_TCP) { + pbuf_free((struct pbuf *)buf); + } else { + netbuf_delete((struct netbuf *)buf); + } + } + } + } while (!done); + + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + } + sock_set_errno(sock, 0); + return off; +} + +int +lwip_read(int s, void *mem, size_t len) +{ + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); +} + +int +lwip_recv(int s, void *mem, size_t len, int flags) +{ + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); +} + +int +lwip_send(int s, const void *data, size_t size, int flags) +{ + struct lwip_sock *sock; + err_t err; + u8_t write_flags; + size_t written; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn->type != NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + return lwip_sendto(s, data, size, flags, NULL, 0); +#else /* (LWIP_UDP || LWIP_RAW) */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + write_flags = NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? (int)written : -1); +} + +int +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + struct lwip_sock *sock; + err_t err; + u16_t short_size; + const struct sockaddr_in *to_in; + u16_t remote_port; +#if !LWIP_TCPIP_CORE_LOCKING + struct netbuf buf; +#endif + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn->type == NETCONN_TCP) { +#if LWIP_TCP + return lwip_send(s, data, size, flags); +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(flags); + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* LWIP_TCP */ + } + + /* @todo: split into multiple sendto's? */ + LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + ((tolen == sizeof(struct sockaddr_in)) && + ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + to_in = (const struct sockaddr_in *)(void*)to; + +#if LWIP_TCPIP_CORE_LOCKING + /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */ + { + struct pbuf* p; + ip_addr_t *remote_addr; + +#if LWIP_NETIF_TX_SINGLE_PBUF + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); + if (p != NULL) { +#if LWIP_CHECKSUM_ON_COPY + u16_t chksum = 0; + if (sock->conn->type != NETCONN_RAW) { + chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + MEMCPY(p->payload, data, size); +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); + if (p != NULL) { + p->payload = (void*)data; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + if (to_in != NULL) { + inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr); + remote_port = ntohs(to_in->sin_port); + } else { + remote_addr = &sock->conn->pcb.ip->remote_ip; +#if LWIP_UDP + if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) { + remote_port = sock->conn->pcb.udp->remote_port; + } else +#endif /* LWIP_UDP */ + { + remote_port = 0; + } + } + + LOCK_TCPIP_CORE(); + if (netconn_type(sock->conn) == NETCONN_RAW) { +#if LWIP_RAW + err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr); +#else /* LWIP_RAW */ + err = ERR_ARG; +#endif /* LWIP_RAW */ + } +#if LWIP_UDP && LWIP_RAW + else +#endif /* LWIP_UDP && LWIP_RAW */ + { +#if LWIP_UDP +#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF + err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, + remote_addr, remote_port, 1, chksum); +#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ + err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, + remote_addr, remote_port); +#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ +#else /* LWIP_UDP */ + err = ERR_ARG; +#endif /* LWIP_UDP */ + } + UNLOCK_TCPIP_CORE(); + + pbuf_free(p); + } else { + err = ERR_MEM; + } + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + /* initialize a buffer */ + buf.p = buf.ptr = NULL; +#if LWIP_CHECKSUM_ON_COPY + buf.flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + if (to) { + inet_addr_to_ipaddr(&buf.addr, &to_in->sin_addr); + remote_port = ntohs(to_in->sin_port); + netbuf_fromport(&buf) = remote_port; + } else { + remote_port = 0; + ip_addr_set_any(&buf.addr); + netbuf_fromport(&buf) = 0; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + + /* make the buffer point to the data that should be sent */ +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { +#if LWIP_CHECKSUM_ON_COPY + if (sock->conn->type != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + err = ERR_OK; + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + err = netbuf_take(&buf, data, short_size); + } + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { + /* send the data */ + err = netconn_send(sock->conn, &buf); + } + + /* deallocated the buffer */ + netbuf_free(&buf); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? short_size : -1); +} + +int +lwip_socket(int domain, int type, int protocol) +{ + struct netconn *conn; + int i; + + LWIP_UNUSED_ARG(domain); + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(NETCONN_RAW, (u8_t)protocol, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback( (protocol == IPPROTO_UDPLITE) ? + NETCONN_UDPLITE : NETCONN_UDP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(NETCONN_TCP, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + if (conn != NULL) { + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(conn, 1); + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } + + i = alloc_socket(conn, 0); + + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->socket = i; + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; +} + +int +lwip_write(int s, const void *data, size_t size) +{ + return lwip_send(s, data, size, 0); +} + +/** + * Go through the readset and writeset lists and see which socket of the sockets + * set in the sets has events. On return, readset, writeset and exceptset have + * the sockets enabled that had events. + * + * exceptset is not used for now! + * + * @param maxfdp1 the highest socket index in the sets + * @param readset_in: set of sockets to check for read events + * @param writeset_in: set of sockets to check for write events + * @param exceptset_in: set of sockets to check for error events + * @param readset_out: set of sockets that had read events + * @param writeset_out: set of sockets that had write events + * @param exceptset_out: set os sockets that had error events + * @return number of sockets that had events (read/write/exception) (>= 0) + */ +static int +lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, + fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) +{ + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for(i = 0; i < maxfdp1; i++) { + void* lastdata = NULL; + s16_t rcvevent = 0; + u16_t sendevent = 0; + u16_t errevent = 0; + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket(i); + if (sock != NULL) { + lastdata = sock->lastdata; + rcvevent = sock->rcvevent; + sendevent = sock->sendevent; + errevent = sock->errevent; + } + SYS_ARCH_UNPROTECT(lev); + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + /* See if netconn of this socket is ready for write */ + if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + /* See if netconn of this socket had an error */ + if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { + FD_SET(i, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); + nready++; + } + } + /* copy local sets to the ones provided as arguments */ + *readset_out = lreadset; + *writeset_out = lwriteset; + *exceptset_out = lexceptset; + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; +} + +/** + * Processing exceptset is not yet implemented. + */ +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) +{ + u32_t waitres = 0; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + struct lwip_select_cb select_cb; + err_t err; + int i; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, + timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); + + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables. */ + + select_cb.next = NULL; + select_cb.prev = NULL; + select_cb.readset = readset; + select_cb.writeset = writeset; + select_cb.exceptset = exceptset; + select_cb.sem_signalled = 0; + err = sys_sem_new(&select_cb.sem, 0); + if (err != ERR_OK) { + /* failed to create semaphore */ + set_errno(ENOMEM); + return -1; + } + + /* Protect the select_cb_list */ + SYS_ARCH_PROTECT(lev); + + /* Put this select_cb on top of list */ + select_cb.next = select_cb_list; + if (select_cb_list != NULL) { + select_cb_list->prev = &select_cb; + } + select_cb_list = &select_cb; + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + + /* Now we can safely unprotect */ + SYS_ARCH_UNPROTECT(lev); + + /* Increase select_waiting for each socket we are interested in */ + for(i = 0; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock = tryget_socket(i); + LWIP_ASSERT("sock != NULL", sock != NULL); + SYS_ARCH_PROTECT(lev); + sock->select_waiting++; + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + SYS_ARCH_UNPROTECT(lev); + } + } + + /* Call lwip_selscan again: there could have been events between + the last scan (whithout us on the list) and putting us on the list! */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout == 0) { + /* Wait forever */ + msectimeout = 0; + } else { + msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); + if (msectimeout == 0) { + /* Wait 1ms at least (0 means wait forever) */ + msectimeout = 1; + } + } + + waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout); + } + /* Increase select_waiting for each socket we are interested in */ + for(i = 0; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock = tryget_socket(i); + LWIP_ASSERT("sock != NULL", sock != NULL); + SYS_ARCH_PROTECT(lev); + sock->select_waiting--; + LWIP_ASSERT("sock->select_waiting >= 0", sock->select_waiting >= 0); + SYS_ARCH_UNPROTECT(lev); + } + } + /* Take us off the list */ + SYS_ARCH_PROTECT(lev); + if (select_cb.next != NULL) { + select_cb.next->prev = select_cb.prev; + } + if (select_cb_list == &select_cb) { + LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); + select_cb_list = select_cb.next; + } else { + LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); + select_cb.prev->next = select_cb.next; + } + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + SYS_ARCH_UNPROTECT(lev); + + sys_sem_free(&select_cb.sem); + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* See what's set */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); +return_copy_fdsets: + set_errno(0); + if (readset) { + *readset = lreadset; + } + if (writeset) { + *writeset = lwriteset; + } + if (exceptset) { + *exceptset = lexceptset; + } + + + return nready; +} + +/** + * Callback registered in the netconn layer for each socket-netconn. + * Processes recvevent (data available) and wakes up tasks waiting for select. + */ +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s; + struct lwip_sock *sock; + struct lwip_select_cb *scb; + int last_select_cb_ctr; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + conn->socket--; + } + SYS_ARCH_UNPROTECT(lev); + return; + } + s = conn->socket; + SYS_ARCH_UNPROTECT(lev); + } + + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + break; + case NETCONN_EVT_SENDPLUS: + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + + if (sock->select_waiting == 0) { + /* noone is waiting for this socket, no need to check select_cb_list */ + SYS_ARCH_UNPROTECT(lev); + return; + } + + /* Now decide if anyone is waiting for this socket */ + /* NOTE: This code goes through the select_cb_list list multiple times + ONLY IF a select was actually waiting. We go through the list the number + of waiting select calls + 1. This list is expected to be small. */ + + /* At this point, SYS_ARCH is still protected! */ +again: + for (scb = select_cb_list; scb != NULL; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* semaphore not signalled yet */ + int do_signal = 0; + /* Test this select call for our socket */ + if (sock->rcvevent > 0) { + if (scb->readset && FD_ISSET(s, scb->readset)) { + do_signal = 1; + } + } + if (sock->sendevent != 0) { + if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { + do_signal = 1; + } + } + if (sock->errevent != 0) { + if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { + do_signal = 1; + } + } + if (do_signal) { + scb->sem_signalled = 1; + /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might + lead to the select thread taking itself off the list, invalidagin the semaphore. */ + sys_sem_signal(&scb->sem); + } + } + /* unlock interrupts with each step */ + last_select_cb_ctr = select_cb_ctr; + SYS_ARCH_UNPROTECT(lev); + /* this makes sure interrupt protection time is short */ + SYS_ARCH_PROTECT(lev); + if (last_select_cb_ctr != select_cb_ctr) { + /* someone has changed select_cb_list, restart at the beginning */ + goto again; + } + } + SYS_ARCH_UNPROTECT(lev); +} + +/** + * Unimplemented: Close one end of a full-duplex connection. + * Currently, the full connection is closed. + */ +int +lwip_shutdown(int s, int how) +{ + struct lwip_sock *sock; + err_t err; + u8_t shut_rx = 0, shut_tx = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn != NULL) { + if (netconn_type(sock->conn) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + } else { + sock_set_errno(sock, ENOTCONN); + return ENOTCONN; + } + + if (how == SHUT_RD) { + shut_rx = 1; + } else if (how == SHUT_WR) { + shut_tx = 1; + } else if(how == SHUT_RDWR) { + shut_rx = 1; + shut_tx = 1; + } else { + sock_set_errno(sock, EINVAL); + return EINVAL; + } + err = netconn_shutdown(sock->conn, shut_rx, shut_tx); + + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? 0 : -1); +} + +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +{ + struct lwip_sock *sock; + struct sockaddr_in sin; + ip_addr_t naddr; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; + + /* get the IP address and port */ + netconn_getaddr(sock->conn, &naddr, &sin.sin_port, local); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ip_addr_debug_print(SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", sin.sin_port)); + + sin.sin_port = htons(sin.sin_port); + inet_addr_from_ipaddr(&sin.sin_addr, &naddr); + + if (*namelen > sizeof(sin)) { + *namelen = sizeof(sin); + } + + MEMCPY(name, &sin, *namelen); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 0); +} + +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 1); +} + +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + err_t err = ERR_OK; + struct lwip_sock *sock = get_socket(s); + struct lwip_setgetsockopt_data data; + + if (!sock) { + return -1; + } + + if ((NULL == optval) || (NULL == optlen)) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_ERROR: + case SO_KEEPALIVE: + /* UNIMPL case SO_CONTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + case SO_TYPE: + /* UNIMPL case SO_USELOOPBACK: */ + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; + + case SO_NO_CHECK: + if (*optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (*optlen < sizeof(int)) { + err = EINVAL; + } + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (*optlen < sizeof(u8_t)) { + err = EINVAL; + } + break; + case IP_MULTICAST_IF: + if (*optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + break; + case IP_MULTICAST_LOOP: + if (*optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; +#endif /* LWIP_IGMP */ + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (*optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) { + return 0; + } + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE*/ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + /* Now do the actual option processing */ + data.sock = sock; +#ifdef LWIP_DEBUG + data.s = s; +#endif /* LWIP_DEBUG */ + data.level = level; + data.optname = optname; + data.optval = optval; + data.optlen = optlen; + data.err = err; + tcpip_callback(lwip_getsockopt_internal, &data); + sys_arch_sem_wait(&sock->conn->op_completed, 0); + /* maybe lwip_getsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_getsockopt_internal(void *arg) +{ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_ACCEPTCONN: + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /*case SO_USELOOPBACK: UNIMPL */ + *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; + + case SO_TYPE: + switch (NETCONNTYPE_GROUP(sock->conn->type)) { + case NETCONN_RAW: + *(int*)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int*)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int*)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int*)optval = sock->conn->type; + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (sock->conn->type) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + /* only overwrite ERR_OK or tempoary errors */ + if ((sock->err == 0) || (sock->err == EINPROGRESS)) { + sock_set_errno(sock, err_to_errno(sock->conn->last_err)); + } + *(int *)optval = sock->err; + sock->err = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + *(int *)optval = netconn_get_sendtimeout(sock->conn); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + *(int *)optval = netconn_get_recvtimeout(sock->conn); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + *(int *)optval = netconn_get_recvbufsize(sock->conn); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; +#endif /* LWIP_UDP*/ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + *(int*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + *(int*)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + *(u8_t*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; + case IP_MULTICAST_LOOP: + if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t*)optval = 1; + } else { + *(u8_t*)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_IGMP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int*)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled level", 0); + break; + } /* switch (level) */ + sys_sem_signal(&sock->conn->op_completed); +} + +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + struct lwip_sock *sock = get_socket(s); + err_t err = ERR_OK; + struct lwip_setgetsockopt_data data; + + if (!sock) { + return -1; + } + + if (NULL == optval) { + sock_set_errno(sock, EFAULT); + return -1; + } + + /* Do length and type checks for the various options first, to keep it readable. */ + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case case SO_CONTIMEO: */ +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: +#endif /* LWIP_SO_RCVBUF */ + /* UNIMPL case SO_OOBINLINE: */ + /* UNIMPL case SO_SNDBUF: */ + /* UNIMPL case SO_RCVLOWAT: */ + /* UNIMPL case SO_SNDLOWAT: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (optlen < sizeof(int)) { + err = EINVAL; + } + break; + case SO_NO_CHECK: + if (optlen < sizeof(int)) { + err = EINVAL; + } +#if LWIP_UDP + if ((sock->conn->type != NETCONN_UDP) || + ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0)) { + /* this flag is only available for UDP, not for UDP lite */ + err = EAFNOSUPPORT; + } +#endif /* LWIP_UDP */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + /* UNIMPL case IP_HDRINCL: */ + /* UNIMPL case IP_RCVDSTADDR: */ + /* UNIMPL case IP_RCVIF: */ + case IP_TTL: + case IP_TOS: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + sock->conn->pcb.udp->tos = *(u8_t*)optval; + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_MULTICAST_IF: + if (optlen < sizeof(struct in_addr)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_MULTICAST_LOOP: + if (optlen < sizeof(u8_t)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + if (optlen < sizeof(struct ip_mreq)) { + err = EINVAL; + } + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP) { + err = EAFNOSUPPORT; + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no TCP socket, ignore any options. */ + if (sock->conn->type != NETCONN_TCP) + return 0; + + switch (optname) { + case TCP_NODELAY: + case TCP_KEEPALIVE: +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + case TCP_KEEPINTVL: + case TCP_KEEPCNT: +#endif /* LWIP_TCP_KEEPALIVE */ + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ +#if LWIP_UDP && LWIP_UDPLITE +/* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + if (optlen < sizeof(int)) { + err = EINVAL; + break; + } + + /* If this is no UDP lite socket, ignore any options. */ + if (sock->conn->type != NETCONN_UDPLITE) + return 0; + + switch (optname) { + case UDPLITE_SEND_CSCOV: + case UDPLITE_RECV_CSCOV: + break; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP && LWIP_UDPLITE */ +/* UNDEFINED LEVEL */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + } /* switch (level) */ + + + if (err != ERR_OK) { + sock_set_errno(sock, err); + return -1; + } + + + /* Now do the actual option processing */ + data.sock = sock; +#ifdef LWIP_DEBUG + data.s = s; +#endif /* LWIP_DEBUG */ + data.level = level; + data.optname = optname; + data.optval = (void*)optval; + data.optlen = &optlen; + data.err = err; + tcpip_callback(lwip_setsockopt_internal, &data); + sys_arch_sem_wait(&sock->conn->op_completed, 0); + /* maybe lwip_setsockopt_internal has changed err */ + err = data.err; + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +static void +lwip_setsockopt_internal(void *arg) +{ + struct lwip_sock *sock; +#ifdef LWIP_DEBUG + int s; +#endif /* LWIP_DEBUG */ + int level, optname; + const void *optval; + struct lwip_setgetsockopt_data *data; + + LWIP_ASSERT("arg != NULL", arg != NULL); + + data = (struct lwip_setgetsockopt_data*)arg; + sock = data->sock; +#ifdef LWIP_DEBUG + s = data->s; +#endif /* LWIP_DEBUG */ + level = data->level; + optname = data->optname; + optval = data->optval; + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* The option flags */ + case SO_BROADCAST: + /* UNIMPL case SO_DEBUG: */ + /* UNIMPL case SO_DONTROUTE: */ + case SO_KEEPALIVE: + /* UNIMPL case SO_OOBINCLUDE: */ +#if SO_REUSE + case SO_REUSEADDR: + case SO_REUSEPORT: +#endif /* SO_REUSE */ + /* UNIMPL case SO_USELOOPBACK: */ + if (*(int*)optval) { + ip_set_option(sock->conn->pcb.ip, optname); + } else { + ip_reset_option(sock->conn->pcb.ip, optname); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + netconn_set_sendtimeout(sock->conn, (s32_t)*(int*)optval); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + netconn_set_recvtimeout(sock->conn, *(int*)optval); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + netconn_set_recvbufsize(sock->conn, *(int*)optval); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + if (*(int*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); + } + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); + break; + case IP_MULTICAST_IF: + inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); + break; + case IP_MULTICAST_LOOP: + if (*(u8_t*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + { + /* If this is a TCP or a RAW socket, ignore these options. */ + struct ip_mreq *imr = (struct ip_mreq *)optval; + ip_addr_t if_addr; + ip_addr_t multi_addr; + inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); + inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); + if(optname == IP_ADD_MEMBERSHIP){ + data->err = igmp_joingroup(&if_addr, &multi_addr); + } else { + data->err = igmp_leavegroup(&if_addr, &multi_addr); + } + if(data->err != ERR_OK) { + data->err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + switch (optname) { + case TCP_NODELAY: + if (*(int*)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(int *)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP*/ +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_ASSERT("unhandled optname", 0); + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + default: + LWIP_ASSERT("unhandled level", 0); + break; + } /* switch (level) */ + sys_sem_signal(&sock->conn->op_completed); +} + +int +lwip_ioctl(int s, long cmd, void *argp) +{ + struct lwip_sock *sock = get_socket(s); + u8_t val; +#if LWIP_SO_RCVBUF + u16_t buflen = 0; + s16_t recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + if (!sock) { + return -1; + } + + switch (cmd) { +#if LWIP_SO_RCVBUF + case FIONREAD: + if (!argp) { + sock_set_errno(sock, EINVAL); + return -1; + } + + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) { + recv_avail = 0; + } + *((u16_t*)argp) = (u16_t)recv_avail; + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata) { + struct pbuf *p = (struct pbuf *)sock->lastdata; + if (netconn_type(sock->conn) != NETCONN_TCP) { + p = ((struct netbuf *)p)->p; + } + buflen = p->tot_len; + buflen -= sock->lastoffset; + + *((u16_t*)argp) += buflen; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); + sock_set_errno(sock, 0); + return 0; +#endif /* LWIP_SO_RCVBUF */ + + case FIONBIO: + val = 0; + if (argp && *(u32_t*)argp) { + val = 1; + } + netconn_set_nonblocking(sock->conn, val); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); + sock_set_errno(sock, 0); + return 0; + + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + return -1; + } /* switch (cmd) */ +} + +/** A minimal implementation of fcntl. + * Currently only the commands F_GETFL and F_SETFL are implemented. + * Only the flag O_NONBLOCK is implemented. + */ +int +lwip_fcntl(int s, int cmd, int val) +{ + struct lwip_sock *sock = get_socket(s); + int ret = -1; + + if (!sock || !sock->conn) { + return -1; + } + + switch (cmd) { + case F_GETFL: + ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; + break; + case F_SETFL: + if ((val & ~O_NONBLOCK) == 0) { + /* only O_NONBLOCK, all other bits are zero */ + netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); + ret = 0; + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + break; + } + return ret; +} + +/************************************************************** +* Added by Realtek Begin * +**************************************************************/ +int lwip_allocsocketsd() +{ + struct netconn *conn; + int i; + + /*new a netconn due to avoid some socket->conn check*/ + conn = netconn_new_with_proto_and_callback(NETCONN_RAW, 0, NULL); + if (!conn) { + printf("\r\n could not create netconn"); + return -1; + } + + /*alloc a socket*/ + i = alloc_socket(conn, 1); + if (i == -1) { + netconn_delete(conn); + printf("\r\n alloc socket fail!"); + return -1; + } + + conn->socket = i; + return i; +} +void lwip_setsockrcvevent(int fd, int rcvevent) +{ + struct lwip_sock *sock = get_socket(fd); + + if(sock){ + if(rcvevent) + sock->rcvevent = 1; + else + sock->rcvevent = 0; + } +} +void lwip_selectevindicate(int fd) +{ + struct lwip_select_cb *scb; + struct lwip_sock *sock; + + sock = get_socket(fd); + SYS_ARCH_DECL_PROTECT(lev); + while (1) { + SYS_ARCH_PROTECT(lev); + for (scb = select_cb_list; scb; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* Test this select call for our socket */ + if (scb->readset && FD_ISSET(fd, scb->readset)) + if (sock->rcvevent > 0) + break; + if (scb->writeset && FD_ISSET(fd, scb->writeset)) + if (sock->sendevent) + break; + } + } + if (scb) { + scb->sem_signalled = 1; + sys_sem_signal(&scb->sem); + SYS_ARCH_UNPROTECT(lev); + } else { + SYS_ARCH_UNPROTECT(lev); + break; + } + } +} +/************************************************************** +* Added by Realtek end * +**************************************************************/ + +#endif /* LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/tcpip.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/tcpip.c new file mode 100644 index 0000000..1cc4224 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/api/tcpip.c @@ -0,0 +1,520 @@ +/** + * @file + * Sequential API Main thread module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/memp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/tcpip.h" +#include "lwip/init.h" +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +#include "osdep_service.h" + +/* global variables */ +static tcpip_init_done_fn tcpip_init_done; +static void *tcpip_init_done_arg; +static sys_mbox_t mbox; + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +sys_mutex_t lock_tcpip_core; +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + +/** + * The main lwIP thread. This thread has exclusive access to lwIP core functions + * (unless access to them is not locked). Other threads communicate with this + * thread using message boxes. + * + * It also starts all the timers to make sure they are running in the right + * thread context. + * + * @param arg unused argument + */ +static void +tcpip_thread(void *arg) +{ + struct tcpip_msg *msg; + LWIP_UNUSED_ARG(arg); + + if (tcpip_init_done != NULL) { + tcpip_init_done(tcpip_init_done_arg); + } + + LOCK_TCPIP_CORE(); + while (1) { /* MAIN Loop */ + UNLOCK_TCPIP_CORE(); + LWIP_TCPIP_THREAD_ALIVE(); + /* wait for a message, timeouts are processed while waiting */ + sys_timeouts_mbox_fetch(&mbox, (void **)&msg); + LOCK_TCPIP_CORE(); + switch (msg->type) { +#if LWIP_NETCONN + case TCPIP_MSG_API: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); + msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); + break; +#endif /* LWIP_NETCONN */ + +#if !LWIP_TCPIP_CORE_LOCKING_INPUT + case TCPIP_MSG_INPKT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); +#if LWIP_ETHERNET + if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); + } else +#endif /* LWIP_ETHERNET */ + { + ip_input(msg->msg.inp.p, msg->msg.inp.netif); + } + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + break; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + +#if LWIP_NETIF_API + case TCPIP_MSG_NETIFAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); + msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); + break; +#endif /* LWIP_NETIF_API */ + +#if LWIP_TCPIP_TIMEOUT + case TCPIP_MSG_TIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); + sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + case TCPIP_MSG_UNTIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); + sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; +#endif /* LWIP_TCPIP_TIMEOUT */ + + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_CALLBACK_STATIC: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + break; + + default: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); + LWIP_ASSERT("tcpip_thread: invalid message", 0); + break; + } + } +} + +/** + * Pass a received packet to tcpip_thread for input processing + * + * @param p the received packet, p->payload pointing to the Ethernet header or + * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or + * NETIF_FLAG_ETHERNET flags) + * @param inp the network interface on which the packet was received + */ +err_t +tcpip_input(struct pbuf *p, struct netif *inp) +{ +#if LWIP_TCPIP_CORE_LOCKING_INPUT + err_t ret; + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); + LOCK_TCPIP_CORE(); +#if LWIP_ETHERNET + if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ret = ethernet_input(p, inp); + } else +#endif /* LWIP_ETHERNET */ + { + ret = ip_input(p, inp); + } + UNLOCK_TCPIP_CORE(); + return ret; +#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + struct tcpip_msg *msg; + + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_INPKT; + msg->msg.inp.p = p; + msg->msg.inp.netif = inp; + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + return ERR_OK; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ +} + +/** + * Call a specific function in the thread context of + * tcpip_thread for easy access synchronization. + * A function called in that way may access lwIP core code + * without fearing concurrent access. + * + * @param f the function to call + * @param ctx parameter passed to f + * @param block 1 to block until the request is posted, 0 to non-blocking mode + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + if (block) { + sys_mbox_post(&mbox, msg); + } else { + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_API, msg); + return ERR_MEM; + } + } + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_TIMEOUT +/** + * call sys_timeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_TIMEOUT; + msg->msg.tmo.msecs = msecs; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + +/** + * call sys_untimeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_untimeout(sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_UNTIMEOUT; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} +#endif /* LWIP_TCPIP_TIMEOUT */ + +#if LWIP_NETCONN +/** + * Call the lower part of a netconn_* function + * This function is then running in the thread context + * of tcpip_thread and has exclusive access to lwIP core code. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_apimsg(struct api_msg *apimsg) +{ + struct tcpip_msg msg; +#ifdef LWIP_DEBUG + /* catch functions that don't set err */ + apimsg->msg.err = ERR_VAL; +#endif + + if (sys_mbox_valid(&mbox)) { + UBaseType_t prio = uxTaskPriorityGet(NULL); // add to prevent switch to tcpip thread between mbox post and sem wait + if((TCPIP_THREAD_PRIO + 1) > prio) + vTaskPrioritySet(NULL, TCPIP_THREAD_PRIO + 1); // set priority higher than tcpip thread + msg.type = TCPIP_MSG_API; + msg.msg.apimsg = apimsg; + sys_mbox_post(&mbox, &msg); + sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0); + vTaskPrioritySet(NULL, prio); // restore to original priority + return apimsg->msg.err; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_CORE_LOCKING +/** + * Call the lower part of a netconn_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_apimsg()) + */ +err_t +tcpip_apimsg_lock(struct api_msg *apimsg) +{ +#ifdef LWIP_DEBUG + /* catch functions that don't set err */ + apimsg->msg.err = ERR_VAL; +#endif + + LOCK_TCPIP_CORE(); + apimsg->function(&(apimsg->msg)); + UNLOCK_TCPIP_CORE(); + return apimsg->msg.err; + +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +#if LWIP_NETIF_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_netifapi(struct netifapi_msg* netifapimsg) +{ + struct tcpip_msg msg; + + if (sys_mbox_valid(&mbox)) { + err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); + if (err != ERR_OK) { + netifapimsg->msg.err = err; + return err; + } + + msg.type = TCPIP_MSG_NETIFAPI; + msg.msg.netifapimsg = netifapimsg; + sys_mbox_post(&mbox, &msg); + sys_sem_wait(&netifapimsg->msg.sem); + sys_sem_free(&netifapimsg->msg.sem); + return netifapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a netifapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_netifapi()) + */ +err_t +tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) +{ + LOCK_TCPIP_CORE(); + netifapimsg->function(&(netifapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return netifapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +/** + * Allocate a structure for a static callback message and initialize it. + * This is intended to be used to send "static" messages from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to function + * @return a struct pointer to pass to tcpip_trycallback(). + */ +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +{ + struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return NULL; + } + msg->type = TCPIP_MSG_CALLBACK_STATIC; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + return (struct tcpip_callback_msg*)msg; +} + +/** + * Free a callback message allocated by tcpip_callbackmsg_new(). + * + * @param msg the message to free + */ +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) +{ + memp_free(MEMP_TCPIP_MSG_API, msg); +} + +/** + * Try to post a callback-message to the tcpip_thread mbox + * This is intended to be used to send "static" messages from interrupt context. + * + * @param msg pointer to the message to post + * @return sys_mbox_trypost() return code + */ +err_t +tcpip_trycallback(struct tcpip_callback_msg* msg) +{ + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + return sys_mbox_trypost(&mbox, msg); +} + +/** + * Initialize this module: + * - initialize all sub modules + * - start the tcpip_thread + * + * @param initfunc a function to call when tcpip_thread is running and finished initializing + * @param arg argument to pass to initfunc + */ +void +tcpip_init(tcpip_init_done_fn initfunc, void *arg) +{ + lwip_init(); + + tcpip_init_done = initfunc; + tcpip_init_done_arg = arg; + if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { + LWIP_ASSERT("failed to create tcpip_thread mbox", 0); + } +#if LWIP_TCPIP_CORE_LOCKING + if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) { + LWIP_ASSERT("failed to create lock_tcpip_core", 0); + } +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#if 0 // CONFIG_USE_TCM_HEAP + sys_thread_new_tcm(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); +#else + sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); +#endif +} + +/** + * Simple callback function used with tcpip_callback to free a pbuf + * (pbuf_free has a wrong signature for tcpip_callback) + * + * @param p The pbuf (chain) to be dereferenced. + */ +static void +pbuf_free_int(void *p) +{ + struct pbuf *q = (struct pbuf *)p; + pbuf_free(q); +} + +/** + * A simple wrapper function that allows you to free a pbuf from interrupt context. + * + * @param p The pbuf (chain) to be dereferenced. + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +pbuf_free_callback(struct pbuf *p) +{ + return tcpip_callback_with_block(pbuf_free_int, p, 0); +} + +/** + * A simple wrapper function that allows you to free heap memory from + * interrupt context. + * + * @param m the heap memory to free + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +mem_free_callback(void *m) +{ + return tcpip_callback_with_block(mem_free, m, 0); +} + +#endif /* !NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs.c new file mode 100644 index 0000000..1bd370e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/apps/httpd_opts.h" +#include "lwip/def.h" +#include "lwip/apps/fs.h" +#include + + +#include HTTPD_FSDATA_FILE + +/*-----------------------------------------------------------------------------------*/ + +#if LWIP_HTTPD_CUSTOM_FILES +int fs_open_custom(struct fs_file *file, const char *name); +void fs_close_custom(struct fs_file *file); +#if LWIP_HTTPD_FS_ASYNC_READ +u8_t fs_canread_custom(struct fs_file *file); +u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); +int fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ +int fs_read_custom(struct fs_file *file, char *buffer, int count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + +/*-----------------------------------------------------------------------------------*/ +err_t +fs_open(struct fs_file *file, const char *name) +{ + const struct fsdata_file *f; + + if ((file == NULL) || (name == NULL)) { + return ERR_ARG; + } + +#if LWIP_HTTPD_CUSTOM_FILES + if (fs_open_custom(file, name)) { + file->is_custom_file = 1; + return ERR_OK; + } + file->is_custom_file = 0; +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + + for (f = FS_ROOT; f != NULL; f = f->next) { + if (!strcmp(name, (const char *)f->name)) { + file->data = (const char *)f->data; + file->len = f->len; + file->index = f->len; + file->pextension = NULL; + file->flags = f->flags; +#if HTTPD_PRECALCULATED_CHECKSUM + file->chksum_count = f->chksum_count; + file->chksum = f->chksum; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ +#if LWIP_HTTPD_FILE_STATE + file->state = fs_state_init(file, name); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + return ERR_OK; + } + } + /* file not found */ + return ERR_VAL; +} + +/*-----------------------------------------------------------------------------------*/ +void +fs_close(struct fs_file *file) +{ +#if LWIP_HTTPD_CUSTOM_FILES + if (file->is_custom_file) { + fs_close_custom(file); + } +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#if LWIP_HTTPD_FILE_STATE + fs_state_free(file, file->state); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + LWIP_UNUSED_ARG(file); +} +/*-----------------------------------------------------------------------------------*/ +#if LWIP_HTTPD_DYNAMIC_FILE_READ +#if LWIP_HTTPD_FS_ASYNC_READ +int +fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg) +#else /* LWIP_HTTPD_FS_ASYNC_READ */ +int +fs_read(struct fs_file *file, char *buffer, int count) +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +{ + int read; + if(file->index == file->len) { + return FS_READ_EOF; + } +#if LWIP_HTTPD_FS_ASYNC_READ + LWIP_UNUSED_ARG(callback_fn); + LWIP_UNUSED_ARG(callback_arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +#if LWIP_HTTPD_CUSTOM_FILES + if (file->is_custom_file) { +#if LWIP_HTTPD_FS_ASYNC_READ + return fs_read_async_custom(file, buffer, count, callback_fn, callback_arg); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ + return fs_read_custom(file, buffer, count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + } +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + + read = file->len - file->index; + if(read > count) { + read = count; + } + + MEMCPY(buffer, (file->data + file->index), read); + file->index += read; + + return(read); +} +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_HTTPD_FS_ASYNC_READ +int +fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg) +{ + if (file != NULL) { +#if LWIP_HTTPD_FS_ASYNC_READ +#if LWIP_HTTPD_CUSTOM_FILES + if (!fs_canread_custom(file)) { + if (fs_wait_read_custom(file, callback_fn, callback_arg)) { + return 0; + } + } +#else /* LWIP_HTTPD_CUSTOM_FILES */ + LWIP_UNUSED_ARG(callback_fn); + LWIP_UNUSED_ARG(callback_arg); +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + } + return 1; +} +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +/*-----------------------------------------------------------------------------------*/ +int +fs_bytes_left(struct fs_file *file) +{ + return file->len - file->index; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/404.html b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/404.html new file mode 100644 index 0000000..40b343a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/404.html @@ -0,0 +1,21 @@ + +lwIP - A Lightweight TCP/IP Stack + + + + +
+ SICS logo + +

lwIP - A Lightweight TCP/IP Stack

+

404 - Page not found

+

+ Sorry, the page you are requesting was not found on this + server. +

+
+   +
+ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/img/sics.gif b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/img/sics.gif new file mode 100644 index 0000000..0a4fc7b Binary files /dev/null and b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/img/sics.gif differ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/index.html b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/index.html new file mode 100644 index 0000000..ab575ef --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fs/index.html @@ -0,0 +1,47 @@ + +lwIP - A Lightweight TCP/IP Stack + + + + +
+ SICS logo + +

lwIP - A Lightweight TCP/IP Stack

+

+ The web page you are watching was served by a simple web + server running on top of the lightweight TCP/IP stack lwIP. +

+

+ lwIP is an open source implementation of the TCP/IP + protocol suite that was originally written by Adam Dunkels + of the Swedish Institute of Computer Science but now is + being actively developed by a team of developers + distributed world-wide. Since it's release, lwIP has + spurred a lot of interest and has been ported to several + platforms and operating systems. lwIP can be used either + with or without an underlying OS. +

+

+ The focus of the lwIP TCP/IP implementation is to reduce + the RAM usage while still having a full scale TCP. This + makes lwIP suitable for use in embedded systems with tens + of kilobytes of free RAM and room for around 40 kilobytes + of code ROM. +

+

+ More information about lwIP can be found at the lwIP + homepage at http://savannah.nongnu.org/projects/lwip/ + or at the lwIP wiki at http://lwip.wikia.com/. +

+
+   +
+ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.c new file mode 100644 index 0000000..45274cd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.c @@ -0,0 +1,297 @@ +#include "lwip/apps/fs.h" +#include "lwip/def.h" + + +#define file_NULL (struct fsdata_file *) NULL + + +static const unsigned int dummy_align__img_sics_gif = 0; +static const unsigned char data__img_sics_gif[] = { +/* /img/sics.gif (14 chars) */ +0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: image/gif + +" (27 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d, +0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a, +/* raw file data (724 bytes) */ +0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39, +0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6, +0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e, +0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99, +0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5, +0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b, +0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00, +0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f, +0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac, +0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31, +0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9, +0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51, +0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78, +0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0, +0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07, +0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42, +0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c, +0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01, +0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10, +0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8, +0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4, +0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86, +0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06, +0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07, +0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29, +0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a, +0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97, +0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9, +0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70, +0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c, +0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01, +0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24, +0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29, +0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73, +0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab, +0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45, +0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8, +0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5, +0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10, +0x41,0x00,0x00,0x3b,}; + +static const unsigned int dummy_align__404_html = 1; +static const unsigned char data__404_html[] = { +/* /404.html (10 chars) */ +0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00, + +/* HTTP header */ +/* "HTTP/1.0 404 File not found +" (29 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c, +0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: text/html + +" (27 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, +0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, +/* raw file data (565 bytes) */ +0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74, +0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69, +0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50, +0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f, +0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63, +0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78, +0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, +0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74, +0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c, +0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20, +0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, +0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69, +0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20, +0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d, +0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c, +0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f, +0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69, +0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09, +0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c, +0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49, +0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20, +0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20, +0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a, +0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72, +0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75, +0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20, +0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e, +0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76, +0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09, +0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e, +0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65, +0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74, +0x6d,0x6c,0x3e,0x0d,0x0a,}; + +static const unsigned int dummy_align__index_html = 2; +static const unsigned char data__index_html[] = { +/* /index.html (12 chars) */ +0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00, + +/* HTTP header */ +/* "HTTP/1.0 200 OK +" (17 bytes) */ +0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, +0x0a, +/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) +" (63 bytes) */ +0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, +0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, +0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, +0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, +/* "Content-type: text/html + +" (27 bytes) */ +0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, +0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, +/* raw file data (1751 bytes) */ +0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74, +0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69, +0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50, +0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f, +0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63, +0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78, +0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20, +0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, +0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74, +0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c, +0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20, +0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, +0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69, +0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20, +0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d, +0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c, +0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f, +0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69, +0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09, +0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c, +0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49, +0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20, +0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77, +0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20, +0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72, +0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20, +0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72, +0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20, +0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67, +0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20, +0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, +0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, +0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c, +0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70, +0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20, +0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20, +0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74, +0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50, +0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63, +0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61, +0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69, +0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20, +0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, +0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f, +0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b, +0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65, +0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75, +0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53, +0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e, +0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e, +0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c, +0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f, +0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20, +0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77, +0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65, +0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c, +0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70, +0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69, +0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20, +0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73, +0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61, +0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61, +0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77, +0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65, +0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68, +0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75, +0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09, +0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a, +0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f, +0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49, +0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e, +0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09, +0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67, +0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61, +0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c, +0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20, +0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69, +0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e, +0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d, +0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20, +0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f, +0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72, +0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34, +0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20, +0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a, +0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d, +0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72, +0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49, +0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61, +0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20, +0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d, +0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70, +0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67, +0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f, +0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61, +0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72, +0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f, +0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74, +0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61, +0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d, +0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b, +0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, +0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c, +0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09, +0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e, +0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72, +0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65, +0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74, +0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,}; + + + +const struct fsdata_file file__img_sics_gif[] = { { +file_NULL, +data__img_sics_gif, +data__img_sics_gif + 16, +sizeof(data__img_sics_gif) - 16, +1, +}}; + +const struct fsdata_file file__404_html[] = { { +file__img_sics_gif, +data__404_html, +data__404_html + 12, +sizeof(data__404_html) - 12, +1, +}}; + +const struct fsdata_file file__index_html[] = { { +file__404_html, +data__index_html, +data__index_html + 12, +sizeof(data__index_html) - 12, +1, +}}; + +#define FS_ROOT file__index_html +#define FS_NUMFILES 3 + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.h new file mode 100644 index 0000000..55b0824 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/fsdata.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_FSDATA_H +#define LWIP_FSDATA_H + +#include "lwip/apps/httpd_opts.h" +#include "lwip/apps/fs.h" + +/* THIS FILE IS DEPRECATED AND WILL BE REMOVED IN THE FUTURE */ +/* content was moved to fs.h to simplify #include structure */ + +#endif /* LWIP_FSDATA_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd.c new file mode 100644 index 0000000..aa2e9b7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd.c @@ -0,0 +1,2620 @@ +/** + * @file + * LWIP HTTP server implementation + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +/** + * @defgroup httpd HTTP server + * @ingroup apps + * + * This httpd supports for a + * rudimentary server-side-include facility which will replace tags of the form + * in any file whose extension is .shtml, .shtm or .ssi with + * strings provided by an include handler whose pointer is provided to the + * module via function http_set_ssi_handler(). + * Additionally, a simple common + * gateway interface (CGI) handling mechanism has been added to allow clients + * to hook functions to particular request URIs. + * + * To enable SSI support, define label LWIP_HTTPD_SSI in lwipopts.h. + * To enable CGI support, define label LWIP_HTTPD_CGI in lwipopts.h. + * + * By default, the server assumes that HTTP headers are already present in + * each file stored in the file system. By defining LWIP_HTTPD_DYNAMIC_HEADERS in + * lwipopts.h, this behavior can be changed such that the server inserts the + * headers automatically based on the extension of the file being served. If + * this mode is used, be careful to ensure that the file system image used + * does not already contain the header information. + * + * File system images without headers can be created using the makefsfile + * tool with the -h command line option. + * + * + * Notes about valid SSI tags + * -------------------------- + * + * The following assumptions are made about tags used in SSI markers: + * + * 1. No tag may contain '-' or whitespace characters within the tag name. + * 2. Whitespace is allowed between the tag leadin "". + * 3. The maximum tag name length is LWIP_HTTPD_MAX_TAG_NAME_LEN, currently 8 characters. + * + * Notes on CGI usage + * ------------------ + * + * The simple CGI support offered here works with GET method requests only + * and can handle up to 16 parameters encoded into the URI. The handler + * function may not write directly to the HTTP output but must return a + * filename that the HTTP server will send to the browser as a response to + * the incoming CGI request. + * + * + * + * The list of supported file types is quite short, so if makefsdata complains + * about an unknown extension, make sure to add it (and its doctype) to + * the 'g_psHTTPHeaders' list. + */ +#include "lwip/init.h" +#include "lwip/apps/httpd.h" +#include "lwip/debug.h" +#include "lwip/stats.h" +#include "lwip/apps/fs.h" +#include "httpd_structs.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/tcp.h" + +#include /* memset */ +#include /* atoi */ +#include + +#if LWIP_TCP + +/** Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes */ +#define MIN_REQ_LEN 7 + +#define CRLF "\r\n" +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE +#define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive" +#define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive" +#endif + +/** These defines check whether tcp_write has to copy data or not */ + +/** This was TI's check whether to let TCP copy data or not + * \#define HTTP_IS_DATA_VOLATILE(hs) ((hs->file < (char *)0x20000000) ? 0 : TCP_WRITE_FLAG_COPY) + */ +#ifndef HTTP_IS_DATA_VOLATILE +#if LWIP_HTTPD_SSI +/* Copy for SSI files, no copy for non-SSI files */ +#define HTTP_IS_DATA_VOLATILE(hs) ((hs)->ssi ? TCP_WRITE_FLAG_COPY : 0) +#else /* LWIP_HTTPD_SSI */ +/** Default: don't copy if the data is sent from file-system directly */ +#define HTTP_IS_DATA_VOLATILE(hs) (((hs->file != NULL) && (hs->handle != NULL) && (hs->file == \ + (const char*)hs->handle->data + hs->handle->len - hs->left)) \ + ? 0 : TCP_WRITE_FLAG_COPY) +#endif /* LWIP_HTTPD_SSI */ +#endif + +/** Default: headers are sent from ROM */ +#ifndef HTTP_IS_HDR_VOLATILE +#define HTTP_IS_HDR_VOLATILE(hs, ptr) 0 +#endif + +/* Return values for http_send_*() */ +#define HTTP_DATA_TO_SEND_BREAK 2 +#define HTTP_DATA_TO_SEND_CONTINUE 1 +#define HTTP_NO_DATA_TO_SEND 0 + +typedef struct +{ + const char *name; + u8_t shtml; +} default_filename; + +const default_filename g_psDefaultFilenames[] = { + {"/index.shtml", 1 }, + {"/index.ssi", 1 }, + {"/index.shtm", 1 }, + {"/index.html", 0 }, + {"/index.htm", 0 } +}; + +#define NUM_DEFAULT_FILENAMES (sizeof(g_psDefaultFilenames) / \ + sizeof(default_filename)) + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST +/** HTTP request is copied here from pbufs for simple parsing */ +static char httpd_req_buf[LWIP_HTTPD_MAX_REQ_LENGTH+1]; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +#if LWIP_HTTPD_SUPPORT_POST +#if LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN > LWIP_HTTPD_MAX_REQUEST_URI_LEN +#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN +#endif +#endif +#ifndef LWIP_HTTPD_URI_BUF_LEN +#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_MAX_REQUEST_URI_LEN +#endif +#if LWIP_HTTPD_URI_BUF_LEN +/* Filename for response file to send when POST is finished or + * search for default files when a directory is requested. */ +static char http_uri_buf[LWIP_HTTPD_URI_BUF_LEN+1]; +#endif + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/* The number of individual strings that comprise the headers sent before each + * requested file. + */ +#define NUM_FILE_HDR_STRINGS 5 +#define HDR_STRINGS_IDX_HTTP_STATUS 0 /* e.g. "HTTP/1.0 200 OK\r\n" */ +#define HDR_STRINGS_IDX_SERVER_NAME 1 /* e.g. "Server: "HTTPD_SERVER_AGENT"\r\n" */ +#define HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE 2 /* e.g. "Content-Length: xy\r\n" and/or "Connection: keep-alive\r\n" */ +#define HDR_STRINGS_IDX_CONTENT_LEN_NR 3 /* the byte count, when content-length is used */ +#define HDR_STRINGS_IDX_CONTENT_TYPE 4 /* the content type (or default answer content type including default document) */ + +/* The dynamically generated Content-Length buffer needs space for CRLF + NULL */ +#define LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET 3 +#ifndef LWIP_HTTPD_MAX_CONTENT_LEN_SIZE +/* The dynamically generated Content-Length buffer shall be able to work with + ~953 MB (9 digits) */ +#define LWIP_HTTPD_MAX_CONTENT_LEN_SIZE (9 + LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) +#endif +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +#if LWIP_HTTPD_SSI + +#define HTTPD_LAST_TAG_PART 0xFFFF + +enum tag_check_state { + TAG_NONE, /* Not processing an SSI tag */ + TAG_LEADIN, /* Tag lead in "" being processed */ + TAG_SENDING /* Sending tag replacement string */ +}; + +struct http_ssi_state { + const char *parsed; /* Pointer to the first unparsed byte in buf. */ +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + const char *tag_started;/* Pointer to the first opening '<' of the tag. */ +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ + const char *tag_end; /* Pointer to char after the closing '>' of the tag. */ + u32_t parse_left; /* Number of unparsed bytes in buf. */ + u16_t tag_index; /* Counter used by tag parsing state machine */ + u16_t tag_insert_len; /* Length of insert in string tag_insert */ +#if LWIP_HTTPD_SSI_MULTIPART + u16_t tag_part; /* Counter passed to and changed by tag insertion function to insert multiple times */ +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + u8_t tag_name_len; /* Length of the tag name in string tag_name */ + char tag_name[LWIP_HTTPD_MAX_TAG_NAME_LEN + 1]; /* Last tag name extracted */ + char tag_insert[LWIP_HTTPD_MAX_TAG_INSERT_LEN + 1]; /* Insert string for tag_name */ + enum tag_check_state tag_state; /* State of the tag processor */ +}; +#endif /* LWIP_HTTPD_SSI */ + +struct http_state { +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + struct http_state *next; +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + struct fs_file file_handle; + struct fs_file *handle; + const char *file; /* Pointer to first unsent byte in buf. */ + + struct tcp_pcb *pcb; +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + struct pbuf *req; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +#if LWIP_HTTPD_DYNAMIC_FILE_READ + char *buf; /* File read buffer. */ + int buf_len; /* Size of file read buffer, buf. */ +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + u32_t left; /* Number of unsent bytes in buf. */ + u8_t retries; +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + u8_t keepalive; +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ +#if LWIP_HTTPD_SSI + struct http_ssi_state *ssi; +#endif /* LWIP_HTTPD_SSI */ +#if LWIP_HTTPD_CGI + char *params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */ + char *param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */ +#endif /* LWIP_HTTPD_CGI */ +#if LWIP_HTTPD_DYNAMIC_HEADERS + const char *hdrs[NUM_FILE_HDR_STRINGS]; /* HTTP headers to be sent. */ + char hdr_content_len[LWIP_HTTPD_MAX_CONTENT_LEN_SIZE]; + u16_t hdr_pos; /* The position of the first unsent header byte in the + current string */ + u16_t hdr_index; /* The index of the hdr string currently being sent. */ +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ +#if LWIP_HTTPD_TIMING + u32_t time_started; +#endif /* LWIP_HTTPD_TIMING */ +#if LWIP_HTTPD_SUPPORT_POST + u32_t post_content_len_left; +#if LWIP_HTTPD_POST_MANUAL_WND + u32_t unrecved_bytes; + u8_t no_auto_wnd; + u8_t post_finished; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ +#endif /* LWIP_HTTPD_SUPPORT_POST*/ +}; + +#if HTTPD_USE_MEM_POOL +LWIP_MEMPOOL_DECLARE(HTTPD_STATE, MEMP_NUM_PARALLEL_HTTPD_CONNS, sizeof(struct http_state), "HTTPD_STATE") +#if LWIP_HTTPD_SSI +LWIP_MEMPOOL_DECLARE(HTTPD_SSI_STATE, MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS, sizeof(struct http_ssi_state), "HTTPD_SSI_STATE") +#define HTTP_FREE_SSI_STATE(x) LWIP_MEMPOOL_FREE(HTTPD_SSI_STATE, (x)) +#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)LWIP_MEMPOOL_ALLOC(HTTPD_SSI_STATE) +#endif /* LWIP_HTTPD_SSI */ +#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)LWIP_MEMPOOL_ALLOC(HTTPD_STATE) +#define HTTP_FREE_HTTP_STATE(x) LWIP_MEMPOOL_FREE(HTTPD_STATE, (x)) +#else /* HTTPD_USE_MEM_POOL */ +#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)mem_malloc(sizeof(struct http_state)) +#define HTTP_FREE_HTTP_STATE(x) mem_free(x) +#if LWIP_HTTPD_SSI +#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)mem_malloc(sizeof(struct http_ssi_state)) +#define HTTP_FREE_SSI_STATE(x) mem_free(x) +#endif /* LWIP_HTTPD_SSI */ +#endif /* HTTPD_USE_MEM_POOL */ + +static err_t http_close_conn(struct tcp_pcb *pcb, struct http_state *hs); +static err_t http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn); +static err_t http_find_file(struct http_state *hs, const char *uri, int is_09); +static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check, char* params); +static err_t http_poll(void *arg, struct tcp_pcb *pcb); +static u8_t http_check_eof(struct tcp_pcb *pcb, struct http_state *hs); +#if LWIP_HTTPD_FS_ASYNC_READ +static void http_continue(void *connection); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +#if LWIP_HTTPD_SSI +/* SSI insert handler function pointer. */ +tSSIHandler g_pfnSSIHandler; +#if !LWIP_HTTPD_SSI_RAW +int g_iNumTags; +const char **g_ppcTags; +#endif /* !LWIP_HTTPD_SSI_RAW */ + +#define LEN_TAG_LEAD_IN 5 +const char * const g_pcTagLeadIn = ""; +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_CGI +/* CGI handler information */ +const tCGI *g_pCGIs; +int g_iNumCGIs; +int http_cgi_paramcount; +#define http_cgi_params hs->params +#define http_cgi_param_vals hs->param_vals +#elif LWIP_HTTPD_CGI_SSI +char *http_cgi_params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */ +char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */ +#endif /* LWIP_HTTPD_CGI */ + +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED +/** global list of active HTTP connections, use to kill the oldest when + running out of memory */ +static struct http_state *http_connections; +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED +static void +http_kill_oldest_connection(u8_t ssi_required) +{ + struct http_state *hs = http_connections; + struct http_state *hs_free_next = NULL; + while(hs && hs->next) { +#if LWIP_HTTPD_SSI + if (ssi_required) { + if (hs->next->ssi != NULL) { + hs_free_next = hs; + } + } else +#else /* LWIP_HTTPD_SSI */ + LWIP_UNUSED_ARG(ssi_required); +#endif /* LWIP_HTTPD_SSI */ + { + hs_free_next = hs; + } + LWIP_ASSERT("broken list", hs != hs->next); + hs = hs->next; + } + if (hs_free_next != NULL) { + LWIP_ASSERT("hs_free_next->next != NULL", hs_free_next->next != NULL); + LWIP_ASSERT("hs_free_next->next->pcb != NULL", hs_free_next->next->pcb != NULL); + /* send RST when killing a connection because of memory shortage */ + http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */ + } +} +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + +#if LWIP_HTTPD_SSI +/** Allocate as struct http_ssi_state. */ +static struct http_ssi_state* +http_ssi_state_alloc(void) +{ + struct http_ssi_state *ret = HTTP_ALLOC_SSI_STATE(); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + if (ret == NULL) { + http_kill_oldest_connection(1); + ret = HTTP_ALLOC_SSI_STATE(); + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + if (ret != NULL) { + memset(ret, 0, sizeof(struct http_ssi_state)); + } + return ret; +} + +/** Free a struct http_ssi_state. */ +static void +http_ssi_state_free(struct http_ssi_state *ssi) +{ + if (ssi != NULL) { + HTTP_FREE_SSI_STATE(ssi); + } +} +#endif /* LWIP_HTTPD_SSI */ + +/** Initialize a struct http_state. + */ +static void +http_state_init(struct http_state* hs) +{ + /* Initialize the structure. */ + memset(hs, 0, sizeof(struct http_state)); +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Indicate that the headers are not yet valid */ + hs->hdr_index = NUM_FILE_HDR_STRINGS; +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ +} + +/** Allocate a struct http_state. */ +static struct http_state* +http_state_alloc(void) +{ + struct http_state *ret = HTTP_ALLOC_HTTP_STATE(); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + if (ret == NULL) { + http_kill_oldest_connection(0); + ret = HTTP_ALLOC_HTTP_STATE(); + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + if (ret != NULL) { + http_state_init(ret); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + /* add the connection to the list */ + if (http_connections == NULL) { + http_connections = ret; + } else { + struct http_state *last; + for(last = http_connections; last->next != NULL; last = last->next); + LWIP_ASSERT("last != NULL", last != NULL); + last->next = ret; + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + } + return ret; +} + +/** Free a struct http_state. + * Also frees the file data if dynamic. + */ +static void +http_state_eof(struct http_state *hs) +{ + if(hs->handle) { +#if LWIP_HTTPD_TIMING + u32_t ms_needed = sys_now() - hs->time_started; + u32_t needed = LWIP_MAX(1, (ms_needed/100)); + LWIP_DEBUGF(HTTPD_DEBUG_TIMING, ("httpd: needed %"U32_F" ms to send file of %d bytes -> %"U32_F" bytes/sec\n", + ms_needed, hs->handle->len, ((((u32_t)hs->handle->len) * 10) / needed))); +#endif /* LWIP_HTTPD_TIMING */ + fs_close(hs->handle); + hs->handle = NULL; + } +#if LWIP_HTTPD_DYNAMIC_FILE_READ + if (hs->buf != NULL) { + mem_free(hs->buf); + hs->buf = NULL; + } +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +#if LWIP_HTTPD_SSI + if (hs->ssi) { + http_ssi_state_free(hs->ssi); + hs->ssi = NULL; + } +#endif /* LWIP_HTTPD_SSI */ +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + if (hs->req) { + pbuf_free(hs->req); + hs->req = NULL; + } +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ +} + +/** Free a struct http_state. + * Also frees the file data if dynamic. + */ +static void +http_state_free(struct http_state *hs) +{ + if (hs != NULL) { + http_state_eof(hs); +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + /* take the connection off the list */ + if (http_connections) { + if (http_connections == hs) { + http_connections = hs->next; + } else { + struct http_state *last; + for(last = http_connections; last->next != NULL; last = last->next) { + if (last->next == hs) { + last->next = hs->next; + break; + } + } + } + } +#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ + HTTP_FREE_HTTP_STATE(hs); + } +} + +/** Call tcp_write() in a loop trying smaller and smaller length + * + * @param pcb tcp_pcb to send + * @param ptr Data to send + * @param length Length of data to send (in/out: on return, contains the + * amount of data sent) + * @param apiflags directly passed to tcp_write + * @return the return value of tcp_write + */ +static err_t +http_write(struct tcp_pcb *pcb, const void* ptr, u16_t *length, u8_t apiflags) +{ + u16_t len, max_len; + err_t err; + LWIP_ASSERT("length != NULL", length != NULL); + len = *length; + if (len == 0) { + return ERR_OK; + } + /* We cannot send more data than space available in the send buffer. */ + max_len = tcp_sndbuf(pcb); + if (max_len < len) { + len = max_len; + } +#ifdef HTTPD_MAX_WRITE_LEN + /* Additional limitation: e.g. don't enqueue more than 2*mss at once */ + max_len = HTTPD_MAX_WRITE_LEN(pcb); + if(len > max_len) { + len = max_len; + } +#endif /* HTTPD_MAX_WRITE_LEN */ + do { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Trying go send %d bytes\n", len)); + err = tcp_write(pcb, ptr, len, apiflags); + if (err == ERR_MEM) { + if ((tcp_sndbuf(pcb) == 0) || + (tcp_sndqueuelen(pcb) >= TCP_SND_QUEUELEN)) { + /* no need to try smaller sizes */ + len = 1; + } else { + len /= 2; + } + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, + ("Send failed, trying less (%d bytes)\n", len)); + } + } while ((err == ERR_MEM) && (len > 1)); + + if (err == ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Sent %d bytes\n", len)); + *length = len; + } else { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); + *length = 0; + } + +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + /* ensure nagle is normally enabled (only disabled for persistent connections + when all data has been enqueued but the connection stays open for the next + request */ + tcp_nagle_enable(pcb); +#endif + + return err; +} + +/** + * The connection shall be actively closed (using RST to close from fault states). + * Reset the sent- and recv-callbacks. + * + * @param pcb the tcp pcb to reset callbacks + * @param hs connection state to free + */ +static err_t +http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn) +{ + err_t err; + LWIP_DEBUGF(HTTPD_DEBUG, ("Closing connection %p\n", (void*)pcb)); + +#if LWIP_HTTPD_SUPPORT_POST + if (hs != NULL) { + if ((hs->post_content_len_left != 0) +#if LWIP_HTTPD_POST_MANUAL_WND + || ((hs->no_auto_wnd != 0) && (hs->unrecved_bytes != 0)) +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + ) { + /* make sure the post code knows that the connection is closed */ + http_uri_buf[0] = 0; + httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN); + } + } +#endif /* LWIP_HTTPD_SUPPORT_POST*/ + + + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_err(pcb, NULL); + tcp_poll(pcb, NULL, 0); + tcp_sent(pcb, NULL); + if (hs != NULL) { + http_state_free(hs); + } + + if (abort_conn) { + tcp_abort(pcb); + return ERR_OK; + } + err = tcp_close(pcb); + if (err != ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Error %d closing %p\n", err, (void*)pcb)); + /* error closing, try again later in poll */ + tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); + } + return err; +} + +/** + * The connection shall be actively closed. + * Reset the sent- and recv-callbacks. + * + * @param pcb the tcp pcb to reset callbacks + * @param hs connection state to free + */ +static err_t +http_close_conn(struct tcp_pcb *pcb, struct http_state *hs) +{ + return http_close_or_abort_conn(pcb, hs, 0); +} + +/** End of file: either close the connection (Connection: close) or + * close the file (Connection: keep-alive) + */ +static void +http_eof(struct tcp_pcb *pcb, struct http_state *hs) +{ + /* HTTP/1.1 persistent connection? (Not supported for SSI) */ +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (hs->keepalive) { +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + struct http_state* next = hs->next; +#endif + http_state_eof(hs); + http_state_init(hs); + /* restore state: */ +#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED + hs->next = next; +#endif + hs->pcb = pcb; + hs->keepalive = 1; + /* ensure nagle doesn't interfere with sending all data as fast as possible: */ + tcp_nagle_disable(pcb); + } else +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + { + http_close_conn(pcb, hs); + } +} + +#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI +/** + * Extract URI parameters from the parameter-part of an URI in the form + * "test.cgi?x=y" @todo: better explanation! + * Pointers to the parameters are stored in hs->param_vals. + * + * @param hs http connection state + * @param params pointer to the NULL-terminated parameter string from the URI + * @return number of parameters extracted + */ +static int +extract_uri_parameters(struct http_state *hs, char *params) +{ + char *pair; + char *equals; + int loop; + + LWIP_UNUSED_ARG(hs); + + /* If we have no parameters at all, return immediately. */ + if(!params || (params[0] == '\0')) { + return(0); + } + + /* Get a pointer to our first parameter */ + pair = params; + + /* Parse up to LWIP_HTTPD_MAX_CGI_PARAMETERS from the passed string and ignore the + * remainder (if any) */ + for(loop = 0; (loop < LWIP_HTTPD_MAX_CGI_PARAMETERS) && pair; loop++) { + + /* Save the name of the parameter */ + http_cgi_params[loop] = pair; + + /* Remember the start of this name=value pair */ + equals = pair; + + /* Find the start of the next name=value pair and replace the delimiter + * with a 0 to terminate the previous pair string. */ + pair = strchr(pair, '&'); + if(pair) { + *pair = '\0'; + pair++; + } else { + /* We didn't find a new parameter so find the end of the URI and + * replace the space with a '\0' */ + pair = strchr(equals, ' '); + if(pair) { + *pair = '\0'; + } + + /* Revert to NULL so that we exit the loop as expected. */ + pair = NULL; + } + + /* Now find the '=' in the previous pair, replace it with '\0' and save + * the parameter value string. */ + equals = strchr(equals, '='); + if(equals) { + *equals = '\0'; + http_cgi_param_vals[loop] = equals + 1; + } else { + http_cgi_param_vals[loop] = NULL; + } + } + + return loop; +} +#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */ + +#if LWIP_HTTPD_SSI +/** + * Insert a tag (found in an shtml in the form of "" into the file. + * The tag's name is stored in ssi->tag_name (NULL-terminated), the replacement + * should be written to hs->tag_insert (up to a length of LWIP_HTTPD_MAX_TAG_INSERT_LEN). + * The amount of data written is stored to ssi->tag_insert_len. + * + * @todo: return tag_insert_len - maybe it can be removed from struct http_state? + * + * @param hs http connection state + */ +static void +get_tag_insert(struct http_state *hs) +{ +#if LWIP_HTTPD_SSI_RAW + const char* tag; +#else /* LWIP_HTTPD_SSI_RAW */ + int tag; +#endif /* LWIP_HTTPD_SSI_RAW */ + size_t len; + struct http_ssi_state *ssi; +#if LWIP_HTTPD_SSI_MULTIPART + u16_t current_tag_part; +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + + LWIP_ASSERT("hs != NULL", hs != NULL); + ssi = hs->ssi; + LWIP_ASSERT("ssi != NULL", ssi != NULL); +#if LWIP_HTTPD_SSI_MULTIPART + current_tag_part = ssi->tag_part; + ssi->tag_part = HTTPD_LAST_TAG_PART; +#endif /* LWIP_HTTPD_SSI_MULTIPART */ +#if LWIP_HTTPD_SSI_RAW + tag = ssi->tag_name; +#endif + + if(g_pfnSSIHandler +#if !LWIP_HTTPD_SSI_RAW + && g_ppcTags && g_iNumTags +#endif /* !LWIP_HTTPD_SSI_RAW */ + ) { + + /* Find this tag in the list we have been provided. */ +#if LWIP_HTTPD_SSI_RAW + { +#else /* LWIP_HTTPD_SSI_RAW */ + for(tag = 0; tag < g_iNumTags; tag++) { + if(strcmp(ssi->tag_name, g_ppcTags[tag]) == 0) +#endif /* LWIP_HTTPD_SSI_RAW */ + { + ssi->tag_insert_len = g_pfnSSIHandler(tag, ssi->tag_insert, + LWIP_HTTPD_MAX_TAG_INSERT_LEN +#if LWIP_HTTPD_SSI_MULTIPART + , current_tag_part, &ssi->tag_part +#endif /* LWIP_HTTPD_SSI_MULTIPART */ +#if LWIP_HTTPD_FILE_STATE + , (hs->handle ? hs->handle->state : NULL) +#endif /* LWIP_HTTPD_FILE_STATE */ + ); +#if LWIP_HTTPD_SSI_RAW + if (ssi->tag_insert_len != HTTPD_SSI_TAG_UNKNOWN) +#endif /* LWIP_HTTPD_SSI_RAW */ + { + return; + } + } + } + } + + /* If we drop out, we were asked to serve a page which contains tags that + * we don't have a handler for. Merely echo back the tags with an error + * marker. */ +#define UNKNOWN_TAG1_TEXT "***UNKNOWN TAG " +#define UNKNOWN_TAG1_LEN 18 +#define UNKNOWN_TAG2_TEXT "***" +#define UNKNOWN_TAG2_LEN 7 + len = LWIP_MIN(sizeof(ssi->tag_name), LWIP_MIN(strlen(ssi->tag_name), + LWIP_HTTPD_MAX_TAG_INSERT_LEN - (UNKNOWN_TAG1_LEN + UNKNOWN_TAG2_LEN))); + MEMCPY(ssi->tag_insert, UNKNOWN_TAG1_TEXT, UNKNOWN_TAG1_LEN); + MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN], ssi->tag_name, len); + MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN + len], UNKNOWN_TAG2_TEXT, UNKNOWN_TAG2_LEN); + ssi->tag_insert[UNKNOWN_TAG1_LEN + len + UNKNOWN_TAG2_LEN] = 0; + + len = strlen(ssi->tag_insert); + LWIP_ASSERT("len <= 0xffff", len <= 0xffff); + ssi->tag_insert_len = (u16_t)len; +} +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/** + * Generate the relevant HTTP headers for the given filename and write + * them into the supplied buffer. + */ +static void +get_http_headers(struct http_state *hs, const char *uri) +{ + size_t content_type; + char *tmp; + char *ext; + char *vars; + u8_t add_content_len; + + /* In all cases, the second header we send is the server identification + so set it here. */ + hs->hdrs[HDR_STRINGS_IDX_SERVER_NAME] = g_psHTTPHeaderStrings[HTTP_HDR_SERVER]; + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = NULL; + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = NULL; + + /* Is this a normal file or the special case we use to send back the + default "404: Page not found" response? */ + if (uri == NULL) { + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (hs->keepalive) { + hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML_PERSISTENT]; + } else +#endif + { + hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML]; + } + + /* Set up to send the first header string. */ + hs->hdr_index = 0; + hs->hdr_pos = 0; + return; + } + /* We are dealing with a particular filename. Look for one other + special case. We assume that any filename with "404" in it must be + indicative of a 404 server error whereas all other files require + the 200 OK header. */ + if (strstr(uri, "404")) { + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; + } else if (strstr(uri, "400")) { + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST]; + } else if (strstr(uri, "501")) { + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL]; + } else { + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK]; + } + + /* Determine if the URI has any variables and, if so, temporarily remove + them. */ + vars = strchr(uri, '?'); + if(vars) { + *vars = '\0'; + } + + /* Get a pointer to the file extension. We find this by looking for the + last occurrence of "." in the filename passed. */ + ext = NULL; + tmp = strchr(uri, '.'); + while (tmp) { + ext = tmp + 1; + tmp = strchr(ext, '.'); + } + if (ext != NULL) { + /* Now determine the content type and add the relevant header for that. */ + for (content_type = 0; content_type < NUM_HTTP_HEADERS; content_type++) { + /* Have we found a matching extension? */ + if(!lwip_stricmp(g_psHTTPHeaders[content_type].extension, ext)) { + break; + } + } + } else { + content_type = NUM_HTTP_HEADERS; + } + + /* Reinstate the parameter marker if there was one in the original URI. */ + if (vars) { + *vars = '?'; + } + +#if LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI + /* Does the URL passed have any file extension? If not, we assume it + is a special-case URL used for control state notification and we do + not send any HTTP headers with the response. */ + if (!ext) { + /* Force the header index to a value indicating that all headers + have already been sent. */ + hs->hdr_index = NUM_FILE_HDR_STRINGS; + return; + } +#endif /* LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI */ + add_content_len = 1; + /* Did we find a matching extension? */ + if(content_type < NUM_HTTP_HEADERS) { + /* yes, store it */ + hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaders[content_type].content_type; + } else if (!ext) { + /* no, no extension found -> use binary transfer to prevent the browser adding '.txt' on save */ + hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_APP; + } else { + /* No - use the default, plain text file type. */ + hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_DEFAULT_TYPE; + } + /* Add content-length header? */ +#if LWIP_HTTPD_SSI + if (hs->ssi != NULL) { + add_content_len = 0; /* @todo: get maximum file length from SSI */ + } else +#endif /* LWIP_HTTPD_SSI */ + if ((hs->handle == NULL) || + ((hs->handle->flags & (FS_FILE_FLAGS_HEADER_INCLUDED|FS_FILE_FLAGS_HEADER_PERSISTENT)) == FS_FILE_FLAGS_HEADER_INCLUDED)) { + add_content_len = 0; + } + if (add_content_len) { + size_t len; + lwip_itoa(hs->hdr_content_len, (size_t)LWIP_HTTPD_MAX_CONTENT_LEN_SIZE, + hs->handle->len); + len = strlen(hs->hdr_content_len); + if (len <= LWIP_HTTPD_MAX_CONTENT_LEN_SIZE - LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) { + SMEMCPY(&hs->hdr_content_len[len], CRLF "\0", 3); + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = hs->hdr_content_len; + } else { + add_content_len = 0; + } + } +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (add_content_len) { + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_KEEPALIVE_LEN]; + } else { + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; + } +#else /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + if (add_content_len) { + hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; + } +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + + /* Set up to send the first header string. */ + hs->hdr_index = 0; + hs->hdr_pos = 0; +} + +/** Sub-function of http_send(): send dynamic headers + * + * @returns: - HTTP_NO_DATA_TO_SEND: no new data has been enqueued + * - HTTP_DATA_TO_SEND_CONTINUE: continue with sending HTTP body + * - HTTP_DATA_TO_SEND_BREAK: data has been enqueued, headers pending, + * so don't send HTTP body yet + */ +static u8_t +http_send_headers(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err; + u16_t len; + u8_t data_to_send = HTTP_NO_DATA_TO_SEND; + u16_t hdrlen, sendlen; + + /* How much data can we send? */ + len = tcp_sndbuf(pcb); + sendlen = len; + + while(len && (hs->hdr_index < NUM_FILE_HDR_STRINGS) && sendlen) { + const void *ptr; + u16_t old_sendlen; + u8_t apiflags; + /* How much do we have to send from the current header? */ + hdrlen = (u16_t)strlen(hs->hdrs[hs->hdr_index]); + + /* How much of this can we send? */ + sendlen = (len < (hdrlen - hs->hdr_pos)) ? len : (hdrlen - hs->hdr_pos); + + /* Send this amount of data or as much as we can given memory + * constraints. */ + ptr = (const void *)(hs->hdrs[hs->hdr_index] + hs->hdr_pos); + old_sendlen = sendlen; + apiflags = HTTP_IS_HDR_VOLATILE(hs, ptr); + if (hs->hdr_index == HDR_STRINGS_IDX_CONTENT_LEN_NR) { + /* content-length is always volatile */ + apiflags |= TCP_WRITE_FLAG_COPY; + } + if (hs->hdr_index < NUM_FILE_HDR_STRINGS - 1) { + apiflags |= TCP_WRITE_FLAG_MORE; + } + err = http_write(pcb, ptr, &sendlen, apiflags); + if ((err == ERR_OK) && (old_sendlen != sendlen)) { + /* Remember that we added some more data to be transmitted. */ + data_to_send = HTTP_DATA_TO_SEND_CONTINUE; + } else if (err != ERR_OK) { + /* special case: http_write does not try to send 1 byte */ + sendlen = 0; + } + + /* Fix up the header position for the next time round. */ + hs->hdr_pos += sendlen; + len -= sendlen; + + /* Have we finished sending this string? */ + if(hs->hdr_pos == hdrlen) { + /* Yes - move on to the next one */ + hs->hdr_index++; + /* skip headers that are NULL (not all headers are required) */ + while ((hs->hdr_index < NUM_FILE_HDR_STRINGS) && + (hs->hdrs[hs->hdr_index] == NULL)) { + hs->hdr_index++; + } + hs->hdr_pos = 0; + } + } + + if ((hs->hdr_index >= NUM_FILE_HDR_STRINGS) && (hs->file == NULL)) { + /* When we are at the end of the headers, check for data to send + * instead of waiting for ACK from remote side to continue + * (which would happen when sending files from async read). */ + if(http_check_eof(pcb, hs)) { + data_to_send = HTTP_DATA_TO_SEND_CONTINUE; + } + } + /* If we get here and there are still header bytes to send, we send + * the header information we just wrote immediately. If there are no + * more headers to send, but we do have file data to send, drop through + * to try to send some file data too. */ + if((hs->hdr_index < NUM_FILE_HDR_STRINGS) || !hs->file) { + LWIP_DEBUGF(HTTPD_DEBUG, ("tcp_output\n")); + return HTTP_DATA_TO_SEND_BREAK; + } + return data_to_send; +} +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +/** Sub-function of http_send(): end-of-file (or block) is reached, + * either close the file or read the next block (if supported). + * + * @returns: 0 if the file is finished or no data has been read + * 1 if the file is not finished and data has been read + */ +static u8_t +http_check_eof(struct tcp_pcb *pcb, struct http_state *hs) +{ + int bytes_left; +#if LWIP_HTTPD_DYNAMIC_FILE_READ + int count; +#ifdef HTTPD_MAX_WRITE_LEN + int max_write_len; +#endif /* HTTPD_MAX_WRITE_LEN */ +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + + /* Do we have a valid file handle? */ + if (hs->handle == NULL) { + /* No - close the connection. */ + http_eof(pcb, hs); + return 0; + } + bytes_left = fs_bytes_left(hs->handle); + if (bytes_left <= 0) { + /* We reached the end of the file so this request is done. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } +#if LWIP_HTTPD_DYNAMIC_FILE_READ + /* Do we already have a send buffer allocated? */ + if(hs->buf) { + /* Yes - get the length of the buffer */ + count = LWIP_MIN(hs->buf_len, bytes_left); + } else { + /* We don't have a send buffer so allocate one now */ + count = tcp_sndbuf(pcb); + if(bytes_left < count) { + count = bytes_left; + } +#ifdef HTTPD_MAX_WRITE_LEN + /* Additional limitation: e.g. don't enqueue more than 2*mss at once */ + max_write_len = HTTPD_MAX_WRITE_LEN(pcb); + if (count > max_write_len) { + count = max_write_len; + } +#endif /* HTTPD_MAX_WRITE_LEN */ + do { + hs->buf = (char*)mem_malloc((mem_size_t)count); + if (hs->buf != NULL) { + hs->buf_len = count; + break; + } + count = count / 2; + } while (count > 100); + + /* Did we get a send buffer? If not, return immediately. */ + if (hs->buf == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("No buff\n")); + return 0; + } + } + + /* Read a block of data from the file. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Trying to read %d bytes.\n", count)); + +#if LWIP_HTTPD_FS_ASYNC_READ + count = fs_read_async(hs->handle, hs->buf, count, http_continue, hs); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ + count = fs_read(hs->handle, hs->buf, count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + if (count < 0) { + if (count == FS_READ_DELAYED) { + /* Delayed read, wait for FS to unblock us */ + return 0; + } + /* We reached the end of the file so this request is done. + * @todo: close here for HTTP/1.1 when reading file fails */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } + + /* Set up to send the block of data we just read */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Read %d bytes.\n", count)); + hs->left = count; + hs->file = hs->buf; +#if LWIP_HTTPD_SSI + if (hs->ssi) { + hs->ssi->parse_left = count; + hs->ssi->parsed = hs->buf; + } +#endif /* LWIP_HTTPD_SSI */ +#else /* LWIP_HTTPD_DYNAMIC_FILE_READ */ + LWIP_ASSERT("SSI and DYNAMIC_HEADERS turned off but eof not reached", 0); +#endif /* LWIP_HTTPD_SSI || LWIP_HTTPD_DYNAMIC_HEADERS */ + return 1; +} + +/** Sub-function of http_send(): This is the normal send-routine for non-ssi files + * + * @returns: - 1: data has been written (so call tcp_ouput) + * - 0: no data has been written (no need to call tcp_output) + */ +static u8_t +http_send_data_nonssi(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err; + u16_t len; + u8_t data_to_send = 0; + + /* We are not processing an SHTML file so no tag checking is necessary. + * Just send the data as we received it from the file. */ + len = (u16_t)LWIP_MIN(hs->left, 0xffff); + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + + return data_to_send; +} + +#if LWIP_HTTPD_SSI +/** Sub-function of http_send(): This is the send-routine for ssi files + * + * @returns: - 1: data has been written (so call tcp_ouput) + * - 0: no data has been written (no need to call tcp_output) + */ +static u8_t +http_send_data_ssi(struct tcp_pcb *pcb, struct http_state *hs) +{ + err_t err = ERR_OK; + u16_t len; + u8_t data_to_send = 0; + + struct http_ssi_state *ssi = hs->ssi; + LWIP_ASSERT("ssi != NULL", ssi != NULL); + /* We are processing an SHTML file so need to scan for tags and replace + * them with insert strings. We need to be careful here since a tag may + * straddle the boundary of two blocks read from the file and we may also + * have to split the insert string between two tcp_write operations. */ + + /* How much data could we send? */ + len = tcp_sndbuf(pcb); + + /* Do we have remaining data to send before parsing more? */ + if(ssi->parsed > hs->file) { + len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff); + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + + /* If the send buffer is full, return now. */ + if(tcp_sndbuf(pcb) == 0) { + return data_to_send; + } + } + + LWIP_DEBUGF(HTTPD_DEBUG, ("State %d, %d left\n", ssi->tag_state, (int)ssi->parse_left)); + + /* We have sent all the data that was already parsed so continue parsing + * the buffer contents looking for SSI tags. */ + while((ssi->parse_left) && (err == ERR_OK)) { + if (len == 0) { + return data_to_send; + } + switch(ssi->tag_state) { + case TAG_NONE: + /* We are not currently processing an SSI tag so scan for the + * start of the lead-in marker. */ + if(*ssi->parsed == g_pcTagLeadIn[0]) { + /* We found what could be the lead-in for a new tag so change + * state appropriately. */ + ssi->tag_state = TAG_LEADIN; + ssi->tag_index = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->tag_started = ssi->parsed; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + + case TAG_LEADIN: + /* We are processing the lead-in marker, looking for the start of + * the tag name. */ + + /* Have we reached the end of the leadin? */ + if(ssi->tag_index == LEN_TAG_LEAD_IN) { + ssi->tag_index = 0; + ssi->tag_state = TAG_FOUND; + } else { + /* Have we found the next character we expect for the tag leadin? */ + if(*ssi->parsed == g_pcTagLeadIn[ssi->tag_index]) { + /* Yes - move to the next one unless we have found the complete + * leadin, in which case we start looking for the tag itself */ + ssi->tag_index++; + } else { + /* We found an unexpected character so this is not a tag. Move + * back to idle state. */ + ssi->tag_state = TAG_NONE; + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + } + break; + + case TAG_FOUND: + /* We are reading the tag name, looking for the start of the + * lead-out marker and removing any whitespace found. */ + + /* Remove leading whitespace between the tag leading and the first + * tag name character. */ + if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || + (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || + (*ssi->parsed == '\r'))) { + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + } + + /* Have we found the end of the tag name? This is signalled by + * us finding the first leadout character or whitespace */ + if((*ssi->parsed == g_pcTagLeadOut[0]) || + (*ssi->parsed == ' ') || (*ssi->parsed == '\t') || + (*ssi->parsed == '\n') || (*ssi->parsed == '\r')) { + + if(ssi->tag_index == 0) { + /* We read a zero length tag so ignore it. */ + ssi->tag_state = TAG_NONE; + } else { + /* We read a non-empty tag so go ahead and look for the + * leadout string. */ + ssi->tag_state = TAG_LEADOUT; + LWIP_ASSERT("ssi->tag_index <= 0xff", ssi->tag_index <= 0xff); + ssi->tag_name_len = (u8_t)ssi->tag_index; + ssi->tag_name[ssi->tag_index] = '\0'; + if(*ssi->parsed == g_pcTagLeadOut[0]) { + ssi->tag_index = 1; + } else { + ssi->tag_index = 0; + } + } + } else { + /* This character is part of the tag name so save it */ + if(ssi->tag_index < LWIP_HTTPD_MAX_TAG_NAME_LEN) { + ssi->tag_name[ssi->tag_index++] = *ssi->parsed; + } else { + /* The tag was too long so ignore it. */ + ssi->tag_state = TAG_NONE; + } + } + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + + break; + + /* We are looking for the end of the lead-out marker. */ + case TAG_LEADOUT: + /* Remove leading whitespace between the tag leading and the first + * tag leadout character. */ + if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || + (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || + (*ssi->parsed == '\r'))) { + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + break; + } + + /* Have we found the next character we expect for the tag leadout? */ + if(*ssi->parsed == g_pcTagLeadOut[ssi->tag_index]) { + /* Yes - move to the next one unless we have found the complete + * leadout, in which case we need to call the client to process + * the tag. */ + + /* Move on to the next character in the buffer */ + ssi->parse_left--; + ssi->parsed++; + + if(ssi->tag_index == (LEN_TAG_LEAD_OUT - 1)) { + /* Call the client to ask for the insert string for the + * tag we just found. */ +#if LWIP_HTTPD_SSI_MULTIPART + ssi->tag_part = 0; /* start with tag part 0 */ +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + get_tag_insert(hs); + + /* Next time through, we are going to be sending data + * immediately, either the end of the block we start + * sending here or the insert string. */ + ssi->tag_index = 0; + ssi->tag_state = TAG_SENDING; + ssi->tag_end = ssi->parsed; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->parsed = ssi->tag_started; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + + /* If there is any unsent data in the buffer prior to the + * tag, we need to send it now. */ + if (ssi->tag_end > hs->file) { + /* How much of the data can we send? */ +#if LWIP_HTTPD_SSI_INCLUDE_TAG + len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff); +#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + /* we would include the tag in sending */ + len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff); +#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + if(ssi->tag_started <= hs->file) { + /* pretend to have sent the tag, too */ + len += ssi->tag_end - ssi->tag_started; + } +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + hs->file += len; + hs->left -= len; + } + } + } else { + ssi->tag_index++; + } + } else { + /* We found an unexpected character so this is not a tag. Move + * back to idle state. */ + ssi->parse_left--; + ssi->parsed++; + ssi->tag_state = TAG_NONE; + } + break; + + /* + * We have found a valid tag and are in the process of sending + * data as a result of that discovery. We send either remaining data + * from the file prior to the insert point or the insert string itself. + */ + case TAG_SENDING: + /* Do we have any remaining file data to send from the buffer prior + * to the tag? */ + if(ssi->tag_end > hs->file) { + /* How much of the data can we send? */ +#if LWIP_HTTPD_SSI_INCLUDE_TAG + len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff); +#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + LWIP_ASSERT("hs->started >= hs->file", ssi->tag_started >= hs->file); + /* we would include the tag in sending */ + len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff); +#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ + if (len != 0) { + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + } else { + err = ERR_OK; + } + if (err == ERR_OK) { + data_to_send = 1; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + if(ssi->tag_started <= hs->file) { + /* pretend to have sent the tag, too */ + len += ssi->tag_end - ssi->tag_started; + } +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + hs->file += len; + hs->left -= len; + } + } else { +#if LWIP_HTTPD_SSI_MULTIPART + if(ssi->tag_index >= ssi->tag_insert_len) { + /* Did the last SSIHandler have more to send? */ + if (ssi->tag_part != HTTPD_LAST_TAG_PART) { + /* If so, call it again */ + ssi->tag_index = 0; + get_tag_insert(hs); + } + } +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + + /* Do we still have insert data left to send? */ + if(ssi->tag_index < ssi->tag_insert_len) { + /* We are sending the insert string itself. How much of the + * insert can we send? */ + len = (ssi->tag_insert_len - ssi->tag_index); + + /* Note that we set the copy flag here since we only have a + * single tag insert buffer per connection. If we don't do + * this, insert corruption can occur if more than one insert + * is processed before we call tcp_output. */ + err = http_write(pcb, &(ssi->tag_insert[ssi->tag_index]), &len, + HTTP_IS_TAG_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + ssi->tag_index += len; + /* Don't return here: keep on sending data */ + } + } else { +#if LWIP_HTTPD_SSI_MULTIPART + if (ssi->tag_part == HTTPD_LAST_TAG_PART) +#endif /* LWIP_HTTPD_SSI_MULTIPART */ + { + /* We have sent all the insert data so go back to looking for + * a new tag. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Everything sent.\n")); + ssi->tag_index = 0; + ssi->tag_state = TAG_NONE; +#if !LWIP_HTTPD_SSI_INCLUDE_TAG + ssi->parsed = ssi->tag_end; +#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ + } + } + break; + default: + break; + } + } + } + + /* If we drop out of the end of the for loop, this implies we must have + * file data to send so send it now. In TAG_SENDING state, we've already + * handled this so skip the send if that's the case. */ + if((ssi->tag_state != TAG_SENDING) && (ssi->parsed > hs->file)) { + len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff); + + err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); + if (err == ERR_OK) { + data_to_send = 1; + hs->file += len; + hs->left -= len; + } + } + return data_to_send; +} +#endif /* LWIP_HTTPD_SSI */ + +/** + * Try to send more data on this pcb. + * + * @param pcb the pcb to send data + * @param hs connection state + */ +static u8_t +http_send(struct tcp_pcb *pcb, struct http_state *hs) +{ + u8_t data_to_send = HTTP_NO_DATA_TO_SEND; + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_send: pcb=%p hs=%p left=%d\n", (void*)pcb, + (void*)hs, hs != NULL ? (int)hs->left : 0)); + +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->unrecved_bytes != 0) { + return 0; + } +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + + /* If we were passed a NULL state structure pointer, ignore the call. */ + if (hs == NULL) { + return 0; + } + +#if LWIP_HTTPD_FS_ASYNC_READ + /* Check if we are allowed to read from this file. + (e.g. SSI might want to delay sending until data is available) */ + if (!fs_is_file_ready(hs->handle, http_continue, hs)) { + return 0; + } +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Do we have any more header data to send for this file? */ + if (hs->hdr_index < NUM_FILE_HDR_STRINGS) { + data_to_send = http_send_headers(pcb, hs); + if ((data_to_send != HTTP_DATA_TO_SEND_CONTINUE) && + (hs->hdr_index < NUM_FILE_HDR_STRINGS)) { + return data_to_send; + } + } +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + + /* Have we run out of file data to send? If so, we need to read the next + * block from the file. */ + if (hs->left == 0) { + if (!http_check_eof(pcb, hs)) { + return 0; + } + } + +#if LWIP_HTTPD_SSI + if(hs->ssi) { + data_to_send = http_send_data_ssi(pcb, hs); + } else +#endif /* LWIP_HTTPD_SSI */ + { + data_to_send = http_send_data_nonssi(pcb, hs); + } + + if((hs->left == 0) && (fs_bytes_left(hs->handle) <= 0)) { + /* We reached the end of the file so this request is done. + * This adds the FIN flag right into the last data segment. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); + http_eof(pcb, hs); + return 0; + } + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("send_data end.\n")); + return data_to_send; +} + +#if LWIP_HTTPD_SUPPORT_EXTSTATUS +/** Initialize a http connection with a file to send for an error message + * + * @param hs http connection state + * @param error_nr HTTP error number + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_find_error_file(struct http_state *hs, u16_t error_nr) +{ + const char *uri1, *uri2, *uri3; + err_t err; + + if (error_nr == 501) { + uri1 = "/501.html"; + uri2 = "/501.htm"; + uri3 = "/501.shtml"; + } else { + /* 400 (bad request is the default) */ + uri1 = "/400.html"; + uri2 = "/400.htm"; + uri3 = "/400.shtml"; + } + err = fs_open(&hs->file_handle, uri1); + if (err != ERR_OK) { + err = fs_open(&hs->file_handle, uri2); + if (err != ERR_OK) { + err = fs_open(&hs->file_handle, uri3); + if (err != ERR_OK) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Error page for error %"U16_F" not found\n", + error_nr)); + return ERR_ARG; + } + } + } + return http_init_file(hs, &hs->file_handle, 0, NULL, 0, NULL); +} +#else /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ +#define http_find_error_file(hs, error_nr) ERR_ARG +#endif /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ + +/** + * Get the file struct for a 404 error page. + * Tries some file names and returns NULL if none found. + * + * @param uri pointer that receives the actual file name URI + * @return file struct for the error page or NULL no matching file was found + */ +static struct fs_file * +http_get_404_file(struct http_state *hs, const char **uri) +{ + err_t err; + + *uri = "/404.html"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.html doesn't exist. Try 404.htm instead. */ + *uri = "/404.htm"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.htm doesn't exist either. Try 404.shtml instead. */ + *uri = "/404.shtml"; + err = fs_open(&hs->file_handle, *uri); + if (err != ERR_OK) { + /* 404.htm doesn't exist either. Indicate to the caller that it should + * send back a default 404 page. + */ + *uri = NULL; + return NULL; + } + } + } + + return &hs->file_handle; +} + +#if LWIP_HTTPD_SUPPORT_POST +static err_t +http_handle_post_finished(struct http_state *hs) +{ +#if LWIP_HTTPD_POST_MANUAL_WND + /* Prevent multiple calls to httpd_post_finished, since it might have already + been called before from httpd_post_data_recved(). */ + if (hs->post_finished) { + return ERR_OK; + } + hs->post_finished = 1; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + /* application error or POST finished */ + /* NULL-terminate the buffer */ + http_uri_buf[0] = 0; + httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN); + return http_find_file(hs, http_uri_buf, 0); +} + +/** Pass received POST body data to the application and correctly handle + * returning a response document or closing the connection. + * ATTENTION: The application is responsible for the pbuf now, so don't free it! + * + * @param hs http connection state + * @param p pbuf to pass to the application + * @return ERR_OK if passed successfully, another err_t if the response file + * hasn't been found (after POST finished) + */ +static err_t +http_post_rxpbuf(struct http_state *hs, struct pbuf *p) +{ + err_t err; + + if (p != NULL) { + /* adjust remaining Content-Length */ + if (hs->post_content_len_left < p->tot_len) { + hs->post_content_len_left = 0; + } else { + hs->post_content_len_left -= p->tot_len; + } + } + err = httpd_post_receive_data(hs, p); + if (err != ERR_OK) { + /* Ignore remaining content in case of application error */ + hs->post_content_len_left = 0; + } + if (hs->post_content_len_left == 0) { +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->unrecved_bytes != 0) { + return ERR_OK; + } +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + /* application error or POST finished */ + return http_handle_post_finished(hs); + } + + return ERR_OK; +} + +/** Handle a post request. Called from http_parse_request when method 'POST' + * is found. + * + * @param p The input pbuf (containing the POST header and body). + * @param hs The http connection state. + * @param data HTTP request (header and part of body) from input pbuf(s). + * @param data_len Size of 'data'. + * @param uri The HTTP URI parsed from input pbuf(s). + * @param uri_end Pointer to the end of 'uri' (here, the rest of the HTTP + * header starts). + * @return ERR_OK: POST correctly parsed and accepted by the application. + * ERR_INPROGRESS: POST not completely parsed (no error yet) + * another err_t: Error parsing POST or denied by the application + */ +static err_t +http_post_request(struct pbuf *inp, struct http_state *hs, + char *data, u16_t data_len, char *uri, char *uri_end) +{ + err_t err; + /* search for end-of-header (first double-CRLF) */ + char* crlfcrlf = lwip_strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data)); + + if (crlfcrlf != NULL) { + /* search for "Content-Length: " */ +#define HTTP_HDR_CONTENT_LEN "Content-Length: " +#define HTTP_HDR_CONTENT_LEN_LEN 16 +#define HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN 10 + char *scontent_len = lwip_strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1)); + if (scontent_len != NULL) { + char *scontent_len_end = lwip_strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN); + if (scontent_len_end != NULL) { + int content_len; + char *content_len_num = scontent_len + HTTP_HDR_CONTENT_LEN_LEN; + content_len = atoi(content_len_num); + if (content_len == 0) { + /* if atoi returns 0 on error, fix this */ + if ((content_len_num[0] != '0') || (content_len_num[1] != '\r')) { + content_len = -1; + } + } + if (content_len >= 0) { + /* adjust length of HTTP header passed to application */ + const char *hdr_start_after_uri = uri_end + 1; + u16_t hdr_len = LWIP_MIN(data_len, crlfcrlf + 4 - data); + u16_t hdr_data_len = LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri); + u8_t post_auto_wnd = 1; + http_uri_buf[0] = 0; + /* trim http header */ + *crlfcrlf = 0; + err = httpd_post_begin(hs, uri, hdr_start_after_uri, hdr_data_len, content_len, + http_uri_buf, LWIP_HTTPD_URI_BUF_LEN, &post_auto_wnd); + if (err == ERR_OK) { + /* try to pass in data of the first pbuf(s) */ + struct pbuf *q = inp; + u16_t start_offset = hdr_len; +#if LWIP_HTTPD_POST_MANUAL_WND + hs->no_auto_wnd = !post_auto_wnd; +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + /* set the Content-Length to be received for this POST */ + hs->post_content_len_left = (u32_t)content_len; + + /* get to the pbuf where the body starts */ + while((q != NULL) && (q->len <= start_offset)) { + start_offset -= q->len; + q = q->next; + } + if (q != NULL) { + /* hide the remaining HTTP header */ + pbuf_header(q, -(s16_t)start_offset); +#if LWIP_HTTPD_POST_MANUAL_WND + if (!post_auto_wnd) { + /* already tcp_recved() this data... */ + hs->unrecved_bytes = q->tot_len; + } +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + pbuf_ref(q); + return http_post_rxpbuf(hs, q); + } else if (hs->post_content_len_left == 0) { + q = pbuf_alloc(PBUF_RAW, 0, PBUF_REF); + return http_post_rxpbuf(hs, q); + } else { + return ERR_OK; + } + } else { + /* return file passed from application */ + return http_find_file(hs, http_uri_buf, 0); + } + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("POST received invalid Content-Length: %s\n", + content_len_num)); + return ERR_ARG; + } + } + } + /* If we come here, headers are fully received (double-crlf), but Content-Length + was not included. Since this is currently the only supported method, we have + to fail in this case! */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Error when parsing Content-Length\n")); + return ERR_ARG; + } + /* if we come here, the POST is incomplete */ +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + return ERR_INPROGRESS; +#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + return ERR_ARG; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ +} + +#if LWIP_HTTPD_POST_MANUAL_WND +/** A POST implementation can call this function to update the TCP window. + * This can be used to throttle data reception (e.g. when received data is + * programmed to flash and data is received faster than programmed). + * + * @param connection A connection handle passed to httpd_post_begin for which + * httpd_post_finished has *NOT* been called yet! + * @param recved_len Length of data received (for window update) + */ +void httpd_post_data_recved(void *connection, u16_t recved_len) +{ + struct http_state *hs = (struct http_state*)connection; + if (hs != NULL) { + if (hs->no_auto_wnd) { + u16_t len = recved_len; + if (hs->unrecved_bytes >= recved_len) { + hs->unrecved_bytes -= recved_len; + } else { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_LEVEL_WARNING, ("httpd_post_data_recved: recved_len too big\n")); + len = (u16_t)hs->unrecved_bytes; + hs->unrecved_bytes = 0; + } + if (hs->pcb != NULL) { + if (len != 0) { + tcp_recved(hs->pcb, len); + } + if ((hs->post_content_len_left == 0) && (hs->unrecved_bytes == 0)) { + /* finished handling POST */ + http_handle_post_finished(hs); + http_send(hs->pcb, hs); + } + } + } + } +} +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + +#endif /* LWIP_HTTPD_SUPPORT_POST */ + +#if LWIP_HTTPD_FS_ASYNC_READ +/** Try to send more data if file has been blocked before + * This is a callback function passed to fs_read_async(). + */ +static void +http_continue(void *connection) +{ + struct http_state *hs = (struct http_state*)connection; + if (hs && (hs->pcb) && (hs->handle)) { + LWIP_ASSERT("hs->pcb != NULL", hs->pcb != NULL); + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("httpd_continue: try to send more data\n")); + if (http_send(hs->pcb, hs)) { + /* If we wrote anything to be sent, go ahead and send it now. */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); + tcp_output(hs->pcb); + } + } +} +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +/** + * When data has been received in the correct state, try to parse it + * as a HTTP request. + * + * @param inp the received pbuf + * @param hs the connection state + * @param pcb the tcp_pcb which received this packet + * @return ERR_OK if request was OK and hs has been initialized correctly + * ERR_INPROGRESS if request was OK so far but not fully received + * another err_t otherwise + */ +static err_t +http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb) +{ + char *data; + char *crlf; + u16_t data_len; + struct pbuf *p = inp; +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + u16_t clen; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ +#if LWIP_HTTPD_SUPPORT_POST + err_t err; +#endif /* LWIP_HTTPD_SUPPORT_POST */ + + LWIP_UNUSED_ARG(pcb); /* only used for post */ + LWIP_ASSERT("p != NULL", p != NULL); + LWIP_ASSERT("hs != NULL", hs != NULL); + + if ((hs->handle != NULL) || (hs->file != NULL)) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Received data while sending a file\n")); + /* already sending a file */ + /* @todo: abort? */ + return ERR_USE; + } + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + + LWIP_DEBUGF(HTTPD_DEBUG, ("Received %"U16_F" bytes\n", p->tot_len)); + + /* first check allowed characters in this pbuf? */ + + /* enqueue the pbuf */ + if (hs->req == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("First pbuf\n")); + hs->req = p; + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("pbuf enqueued\n")); + pbuf_cat(hs->req, p); + } + /* increase pbuf ref counter as it is freed when we return but we want to + keep it on the req list */ + pbuf_ref(p); + + if (hs->req->next != NULL) { + data_len = LWIP_MIN(hs->req->tot_len, LWIP_HTTPD_MAX_REQ_LENGTH); + pbuf_copy_partial(hs->req, httpd_req_buf, data_len, 0); + data = httpd_req_buf; + } else +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + { + data = (char *)p->payload; + data_len = p->len; + if (p->len != p->tot_len) { + LWIP_DEBUGF(HTTPD_DEBUG, ("Warning: incomplete header due to chained pbufs\n")); + } + } + + /* received enough data for minimal request? */ + if (data_len >= MIN_REQ_LEN) { + /* wait for CRLF before parsing anything */ + crlf = lwip_strnstr(data, CRLF, data_len); + if (crlf != NULL) { +#if LWIP_HTTPD_SUPPORT_POST + int is_post = 0; +#endif /* LWIP_HTTPD_SUPPORT_POST */ + int is_09 = 0; + char *sp1, *sp2; + u16_t left_len, uri_len; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("CRLF received, parsing request\n")); + /* parse method */ + if (!strncmp(data, "GET ", 4)) { + sp1 = data + 3; + /* received GET request */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received GET request\"\n")); +#if LWIP_HTTPD_SUPPORT_POST + } else if (!strncmp(data, "POST ", 5)) { + /* store request type */ + is_post = 1; + sp1 = data + 4; + /* received GET request */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received POST request\n")); +#endif /* LWIP_HTTPD_SUPPORT_POST */ + } else { + /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ + data[4] = 0; + /* unsupported method! */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Unsupported request method (not implemented): \"%s\"\n", + data)); + return http_find_error_file(hs, 501); + } + /* if we come here, method is OK, parse URI */ + left_len = (u16_t)(data_len - ((sp1 +1) - data)); + sp2 = lwip_strnstr(sp1 + 1, " ", left_len); +#if LWIP_HTTPD_SUPPORT_V09 + if (sp2 == NULL) { + /* HTTP 0.9: respond with correct protocol version */ + sp2 = lwip_strnstr(sp1 + 1, CRLF, left_len); + is_09 = 1; +#if LWIP_HTTPD_SUPPORT_POST + if (is_post) { + /* HTTP/0.9 does not support POST */ + goto badrequest; + } +#endif /* LWIP_HTTPD_SUPPORT_POST */ + } +#endif /* LWIP_HTTPD_SUPPORT_V09 */ + uri_len = (u16_t)(sp2 - (sp1 + 1)); + if ((sp2 != 0) && (sp2 > sp1)) { + /* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */ + if (lwip_strnstr(data, CRLF CRLF, data_len) != NULL) { + char *uri = sp1 + 1; +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + /* This is HTTP/1.0 compatible: for strict 1.1, a connection + would always be persistent unless "close" was specified. */ + if (!is_09 && (lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) || + lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) { + hs->keepalive = 1; + } else { + hs->keepalive = 0; + } +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ + *sp1 = 0; + uri[uri_len] = 0; + LWIP_DEBUGF(HTTPD_DEBUG, ("Received \"%s\" request for URI: \"%s\"\n", + data, uri)); +#if LWIP_HTTPD_SUPPORT_POST + if (is_post) { +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + struct pbuf *q = hs->req; +#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + struct pbuf *q = inp; +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + err = http_post_request(q, hs, data, data_len, uri, sp2); + if (err != ERR_OK) { + /* restore header for next try */ + *sp1 = ' '; + *sp2 = ' '; + uri[uri_len] = ' '; + } + if (err == ERR_ARG) { + goto badrequest; + } + return err; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + return http_find_file(hs, uri, is_09); + } + } + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("invalid URI\n")); + } + } + } + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + clen = pbuf_clen(hs->req); + if ((hs->req->tot_len <= LWIP_HTTPD_REQ_BUFSIZE) && + (clen <= LWIP_HTTPD_REQ_QUEUELEN)) { + /* request not fully received (too short or CRLF is missing) */ + return ERR_INPROGRESS; + } else +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + { +#if LWIP_HTTPD_SUPPORT_POST +badrequest: +#endif /* LWIP_HTTPD_SUPPORT_POST */ + LWIP_DEBUGF(HTTPD_DEBUG, ("bad request\n")); + /* could not parse request */ + return http_find_error_file(hs, 400); + } +} + +/** Try to find the file specified by uri and, if found, initialize hs + * accordingly. + * + * @param hs the connection state + * @param uri the HTTP header URI + * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_find_file(struct http_state *hs, const char *uri, int is_09) +{ + size_t loop; + struct fs_file *file = NULL; + char *params = NULL; + err_t err; +#if LWIP_HTTPD_CGI + int i; +#endif /* LWIP_HTTPD_CGI */ +#if !LWIP_HTTPD_SSI + const +#endif /* !LWIP_HTTPD_SSI */ + /* By default, assume we will not be processing server-side-includes tags */ + u8_t tag_check = 0; + + /* Have we been asked for the default file (in root or a directory) ? */ +#if LWIP_HTTPD_MAX_REQUEST_URI_LEN + size_t uri_len = strlen(uri); + if ((uri_len > 0) && (uri[uri_len-1] == '/') && + ((uri != http_uri_buf) || (uri_len == 1))) { + size_t copy_len = LWIP_MIN(sizeof(http_uri_buf) - 1, uri_len - 1); + if (copy_len > 0) { + MEMCPY(http_uri_buf, uri, copy_len); + http_uri_buf[copy_len] = 0; + } +#else /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ + if ((uri[0] == '/') && (uri[1] == 0)) { +#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ + /* Try each of the configured default filenames until we find one + that exists. */ + for (loop = 0; loop < NUM_DEFAULT_FILENAMES; loop++) { + const char* file_name; +#if LWIP_HTTPD_MAX_REQUEST_URI_LEN + if (copy_len > 0) { + size_t len_left = sizeof(http_uri_buf) - copy_len - 1; + if (len_left > 0) { + size_t name_len = strlen(g_psDefaultFilenames[loop].name); + size_t name_copy_len = LWIP_MIN(len_left, name_len); + MEMCPY(&http_uri_buf[copy_len], g_psDefaultFilenames[loop].name, name_copy_len); + } + file_name = http_uri_buf; + } else +#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ + { + file_name = g_psDefaultFilenames[loop].name; + } + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Looking for %s...\n", file_name)); + err = fs_open(&hs->file_handle, file_name); + if(err == ERR_OK) { + uri = file_name; + file = &hs->file_handle; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opened.\n")); +#if LWIP_HTTPD_SSI + tag_check = g_psDefaultFilenames[loop].shtml; +#endif /* LWIP_HTTPD_SSI */ + break; + } + } + } + if (file == NULL) { + /* No - we've been asked for a specific file. */ + /* First, isolate the base URI (without any parameters) */ + params = (char *)strchr(uri, '?'); + if (params != NULL) { + /* URI contains parameters. NULL-terminate the base URI */ + *params = '\0'; + params++; + } + +#if LWIP_HTTPD_CGI + http_cgi_paramcount = -1; + /* Does the base URI we have isolated correspond to a CGI handler? */ + if (g_iNumCGIs && g_pCGIs) { + for (i = 0; i < g_iNumCGIs; i++) { + if (strcmp(uri, g_pCGIs[i].pcCGIName) == 0) { + /* + * We found a CGI that handles this URI so extract the + * parameters and call the handler. + */ + http_cgi_paramcount = extract_uri_parameters(hs, params); + uri = g_pCGIs[i].pfnCGIHandler(i, http_cgi_paramcount, hs->params, + hs->param_vals); + break; + } + } + } +#endif /* LWIP_HTTPD_CGI */ + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opening %s\n", uri)); + + err = fs_open(&hs->file_handle, uri); + if (err == ERR_OK) { + file = &hs->file_handle; + } else { + file = http_get_404_file(hs, &uri); + } +#if LWIP_HTTPD_SSI + if (file != NULL) { + /* See if we have been asked for an shtml file and, if so, + enable tag checking. */ + const char* ext = NULL, *sub; + char* param = (char*)strstr(uri, "?"); + if (param != NULL) { + /* separate uri from parameters for now, set back later */ + *param = 0; + } + sub = uri; + ext = uri; + for (sub = strstr(sub, "."); sub != NULL; sub = strstr(sub, ".")) + { + ext = sub; + sub++; + } + tag_check = 0; + for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { + if (!lwip_stricmp(ext, g_pcSSIExtensions[loop])) { + tag_check = 1; + break; + } + } + if (param != NULL) { + *param = '?'; + } + } +#endif /* LWIP_HTTPD_SSI */ + } + if (file == NULL) { + /* None of the default filenames exist so send back a 404 page */ + file = http_get_404_file(hs, &uri); + } + return http_init_file(hs, file, is_09, uri, tag_check, params); +} + +/** Initialize a http connection with a file to send (if found). + * Called by http_find_file and http_find_error_file. + * + * @param hs http connection state + * @param file file structure to send (or NULL if not found) + * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @param uri the HTTP header URI + * @param tag_check enable SSI tag checking + * @param params != NULL if URI has parameters (separated by '?') + * @return ERR_OK if file was found and hs has been initialized correctly + * another err_t otherwise + */ +static err_t +http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, + u8_t tag_check, char* params) +{ + if (file != NULL) { + /* file opened, initialise struct http_state */ +#if LWIP_HTTPD_SSI + if (tag_check) { + struct http_ssi_state *ssi = http_ssi_state_alloc(); + if (ssi != NULL) { + ssi->tag_index = 0; + ssi->tag_state = TAG_NONE; + ssi->parsed = file->data; + ssi->parse_left = file->len; + ssi->tag_end = file->data; + hs->ssi = ssi; + } + } +#else /* LWIP_HTTPD_SSI */ + LWIP_UNUSED_ARG(tag_check); +#endif /* LWIP_HTTPD_SSI */ + hs->handle = file; + hs->file = file->data; + LWIP_ASSERT("File length must be positive!", (file->len >= 0)); +#if LWIP_HTTPD_CUSTOM_FILES + if (file->is_custom_file && (file->data == NULL)) { + /* custom file, need to read data first (via fs_read_custom) */ + hs->left = 0; + } else +#endif /* LWIP_HTTPD_CUSTOM_FILES */ + { + hs->left = file->len; + } + hs->retries = 0; +#if LWIP_HTTPD_TIMING + hs->time_started = sys_now(); +#endif /* LWIP_HTTPD_TIMING */ +#if !LWIP_HTTPD_DYNAMIC_HEADERS + LWIP_ASSERT("HTTP headers not included in file system", + (hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0); +#endif /* !LWIP_HTTPD_DYNAMIC_HEADERS */ +#if LWIP_HTTPD_SUPPORT_V09 + if (is_09 && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) { + /* HTTP/0.9 responses are sent without HTTP header, + search for the end of the header. */ + char *file_start = lwip_strnstr(hs->file, CRLF CRLF, hs->left); + if (file_start != NULL) { + size_t diff = file_start + 4 - hs->file; + hs->file += diff; + hs->left -= (u32_t)diff; + } + } +#endif /* LWIP_HTTPD_SUPPORT_V09*/ +#if LWIP_HTTPD_CGI_SSI + if (params != NULL) { + /* URI contains parameters, call generic CGI handler */ + int count; +#if LWIP_HTTPD_CGI + if (http_cgi_paramcount >= 0) { + count = http_cgi_paramcount; + } else +#endif + { + count = extract_uri_parameters(hs, params); + } + httpd_cgi_handler(uri, count, http_cgi_params, http_cgi_param_vals +#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE + , hs->handle->state +#endif /* LWIP_HTTPD_FILE_STATE */ + ); + } +#else /* LWIP_HTTPD_CGI_SSI */ + LWIP_UNUSED_ARG(params); +#endif /* LWIP_HTTPD_CGI_SSI */ + } else { + hs->handle = NULL; + hs->file = NULL; + hs->left = 0; + hs->retries = 0; + } +#if LWIP_HTTPD_DYNAMIC_HEADERS + /* Determine the HTTP headers to send based on the file extension of + * the requested URI. */ + if ((hs->handle == NULL) || ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) == 0)) { + get_http_headers(hs, uri); + } +#else /* LWIP_HTTPD_DYNAMIC_HEADERS */ + LWIP_UNUSED_ARG(uri); +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + if (hs->keepalive) { +#if LWIP_HTTPD_SSI + if (hs->ssi != NULL) { + hs->keepalive = 0; + } else +#endif /* LWIP_HTTPD_SSI */ + { + if ((hs->handle != NULL) && + ((hs->handle->flags & (FS_FILE_FLAGS_HEADER_INCLUDED|FS_FILE_FLAGS_HEADER_PERSISTENT)) == FS_FILE_FLAGS_HEADER_INCLUDED)) { + hs->keepalive = 0; + } + } + } +#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ + return ERR_OK; +} + +/** + * The pcb had an error and is already deallocated. + * The argument might still be valid (if != NULL). + */ +static void +http_err(void *arg, err_t err) +{ + struct http_state *hs = (struct http_state *)arg; + LWIP_UNUSED_ARG(err); + + LWIP_DEBUGF(HTTPD_DEBUG, ("http_err: %s", lwip_strerr(err))); + + if (hs != NULL) { + http_state_free(hs); + } +} + +/** + * Data has been sent and acknowledged by the remote host. + * This means that more data can be sent. + */ +static err_t +http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct http_state *hs = (struct http_state *)arg; + + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_sent %p\n", (void*)pcb)); + + LWIP_UNUSED_ARG(len); + + if (hs == NULL) { + return ERR_OK; + } + + hs->retries = 0; + + http_send(pcb, hs); + + return ERR_OK; +} + +/** + * The poll function is called every 2nd second. + * If there has been no data sent (which resets the retries) in 8 seconds, close. + * If the last portion of a file has not been sent in 2 seconds, close. + * + * This could be increased, but we don't want to waste resources for bad connections. + */ +static err_t +http_poll(void *arg, struct tcp_pcb *pcb) +{ + struct http_state *hs = (struct http_state *)arg; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: pcb=%p hs=%p pcb_state=%s\n", + (void*)pcb, (void*)hs, tcp_debug_state_str(pcb->state))); + + if (hs == NULL) { + err_t closed; + /* arg is null, close. */ + LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: arg is NULL, close\n")); + closed = http_close_conn(pcb, NULL); + LWIP_UNUSED_ARG(closed); +#if LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR + if (closed == ERR_MEM) { + tcp_abort(pcb); + return ERR_ABRT; + } +#endif /* LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR */ + return ERR_OK; + } else { + hs->retries++; + if (hs->retries == HTTPD_MAX_RETRIES) { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: too many retries, close\n")); + http_close_conn(pcb, hs); + return ERR_OK; + } + + /* If this connection has a file open, try to send some more data. If + * it has not yet received a GET request, don't do this since it will + * cause the connection to close immediately. */ + if(hs && (hs->handle)) { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: try to send more data\n")); + if(http_send(pcb, hs)) { + /* If we wrote anything to be sent, go ahead and send it now. */ + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); + tcp_output(pcb); + } + } + } + + return ERR_OK; +} + +/** + * Data has been received on this pcb. + * For HTTP 1.0, this should normally only happen once (if the request fits in one packet). + */ +static err_t +http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct http_state *hs = (struct http_state *)arg; + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: pcb=%p pbuf=%p err=%s\n", (void*)pcb, + (void*)p, lwip_strerr(err))); + + if ((err != ERR_OK) || (p == NULL) || (hs == NULL)) { + /* error or closed by other side? */ + if (p != NULL) { + /* Inform TCP that we have taken the data. */ + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } + if (hs == NULL) { + /* this should not happen, only to be robust */ + LWIP_DEBUGF(HTTPD_DEBUG, ("Error, http_recv: hs is NULL, close\n")); + } + http_close_conn(pcb, hs); + return ERR_OK; + } + +#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND + if (hs->no_auto_wnd) { + hs->unrecved_bytes += p->tot_len; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ + { + /* Inform TCP that we have taken the data. */ + tcp_recved(pcb, p->tot_len); + } + +#if LWIP_HTTPD_SUPPORT_POST + if (hs->post_content_len_left > 0) { + /* reset idle counter when POST data is received */ + hs->retries = 0; + /* this is data for a POST, pass the complete pbuf to the application */ + http_post_rxpbuf(hs, p); + /* pbuf is passed to the application, don't free it! */ + if (hs->post_content_len_left == 0) { + /* all data received, send response or close connection */ + http_send(pcb, hs); + } + return ERR_OK; + } else +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + if (hs->handle == NULL) { + err_t parsed = http_parse_request(p, hs, pcb); + LWIP_ASSERT("http_parse_request: unexpected return value", parsed == ERR_OK + || parsed == ERR_INPROGRESS ||parsed == ERR_ARG || parsed == ERR_USE); +#if LWIP_HTTPD_SUPPORT_REQUESTLIST + if (parsed != ERR_INPROGRESS) { + /* request fully parsed or error */ + if (hs->req != NULL) { + pbuf_free(hs->req); + hs->req = NULL; + } + } +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + pbuf_free(p); + if (parsed == ERR_OK) { +#if LWIP_HTTPD_SUPPORT_POST + if (hs->post_content_len_left == 0) +#endif /* LWIP_HTTPD_SUPPORT_POST */ + { + LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: data %p len %"S32_F"\n", (const void*)hs->file, hs->left)); + http_send(pcb, hs); + } + } else if (parsed == ERR_ARG) { + /* @todo: close on ERR_USE? */ + http_close_conn(pcb, hs); + } + } else { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: already sending data\n")); + /* already sending but still receiving data, we might want to RST here? */ + pbuf_free(p); + } + } + return ERR_OK; +} + +/** + * A new incoming connection has been accepted. + */ +static err_t +http_accept(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct http_state *hs; + LWIP_UNUSED_ARG(err); + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept %p / %p\n", (void*)pcb, arg)); + + if ((err != ERR_OK) || (pcb == NULL)) { + return ERR_VAL; + } + + /* Set priority */ + tcp_setprio(pcb, HTTPD_TCP_PRIO); + + /* Allocate memory for the structure that holds the state of the + connection - initialized by that function. */ + hs = http_state_alloc(); + if (hs == NULL) { + LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept: Out of memory, RST\n")); + return ERR_MEM; + } + hs->pcb = pcb; + + /* Tell TCP that this is the structure we wish to be passed for our + callbacks. */ + tcp_arg(pcb, hs); + + /* Set up the various callback functions */ + tcp_recv(pcb, http_recv); + tcp_err(pcb, http_err); + tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); + tcp_sent(pcb, http_sent); + + return ERR_OK; +} + +/** + * @ingroup httpd + * Initialize the httpd: set up a listening PCB and bind it to the defined port + */ +void +httpd_init(void) +{ + struct tcp_pcb *pcb; + err_t err; + +#if HTTPD_USE_MEM_POOL + LWIP_MEMPOOL_INIT(HTTPD_STATE); +#if LWIP_HTTPD_SSI + LWIP_MEMPOOL_INIT(HTTPD_SSI_STATE); +#endif +#endif + LWIP_DEBUGF(HTTPD_DEBUG, ("httpd_init\n")); + + pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); + LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL); + tcp_setprio(pcb, HTTPD_TCP_PRIO); + /* set SOF_REUSEADDR here to explicitly bind httpd to multiple interfaces */ + err = tcp_bind(pcb, IP_ANY_TYPE, HTTPD_SERVER_PORT); + LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ + LWIP_ASSERT("httpd_init: tcp_bind failed", err == ERR_OK); + pcb = tcp_listen(pcb); + LWIP_ASSERT("httpd_init: tcp_listen failed", pcb != NULL); + tcp_accept(pcb, http_accept); +} + +#if LWIP_HTTPD_SSI +/** + * Set the SSI handler function. + * + * @param ssi_handler the SSI handler function + * @param tags an array of SSI tag strings to search for in SSI-enabled files + * @param num_tags number of tags in the 'tags' array + */ +void +http_set_ssi_handler(tSSIHandler ssi_handler, const char **tags, int num_tags) +{ + LWIP_DEBUGF(HTTPD_DEBUG, ("http_set_ssi_handler\n")); + + LWIP_ASSERT("no ssi_handler given", ssi_handler != NULL); + g_pfnSSIHandler = ssi_handler; + +#if LWIP_HTTPD_SSI_RAW + LWIP_UNUSED_ARG(tags); + LWIP_UNUSED_ARG(num_tags); +#else /* LWIP_HTTPD_SSI_RAW */ + LWIP_ASSERT("no tags given", tags != NULL); + LWIP_ASSERT("invalid number of tags", num_tags > 0); + + g_ppcTags = tags; + g_iNumTags = num_tags; +#endif /* !LWIP_HTTPD_SSI_RAW */ +} +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_CGI +/** + * Set an array of CGI filenames/handler functions + * + * @param cgis an array of CGI filenames/handler functions + * @param num_handlers number of elements in the 'cgis' array + */ +void +http_set_cgi_handlers(const tCGI *cgis, int num_handlers) +{ + LWIP_ASSERT("no cgis given", cgis != NULL); + LWIP_ASSERT("invalid number of handlers", num_handlers > 0); + + g_pCGIs = cgis; + g_iNumCGIs = num_handlers; +} +#endif /* LWIP_HTTPD_CGI */ + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd_structs.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd_structs.h new file mode 100644 index 0000000..fbd135a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/httpd_structs.h @@ -0,0 +1,114 @@ +#ifndef LWIP_HTTPD_STRUCTS_H +#define LWIP_HTTPD_STRUCTS_H + +#include "lwip/apps/httpd.h" + +#if LWIP_HTTPD_DYNAMIC_HEADERS +/** This struct is used for a list of HTTP header strings for various + * filename extensions. */ +typedef struct +{ + const char *extension; + const char *content_type; +} tHTTPHeader; + +/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and + * RFC 2616 HTTP/1.1 for header field definitions) */ +static const char * const g_psHTTPHeaderStrings[] = +{ + "HTTP/1.0 200 OK\r\n", + "HTTP/1.0 404 File not found\r\n", + "HTTP/1.0 400 Bad Request\r\n", + "HTTP/1.0 501 Not Implemented\r\n", + "HTTP/1.1 200 OK\r\n", + "HTTP/1.1 404 File not found\r\n", + "HTTP/1.1 400 Bad Request\r\n", + "HTTP/1.1 501 Not Implemented\r\n", + "Content-Length: ", + "Connection: Close\r\n", + "Connection: keep-alive\r\n", + "Connection: keep-alive\r\nContent-Length: ", + "Server: "HTTPD_SERVER_AGENT"\r\n", + "\r\n

404: The requested file cannot be found.

\r\n" +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE + ,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n

404: The requested file cannot be found.

\r\n" +#endif +}; + +/* Indexes into the g_psHTTPHeaderStrings array */ +#define HTTP_HDR_OK 0 /* 200 OK */ +#define HTTP_HDR_NOT_FOUND 1 /* 404 File not found */ +#define HTTP_HDR_BAD_REQUEST 2 /* 400 Bad request */ +#define HTTP_HDR_NOT_IMPL 3 /* 501 Not Implemented */ +#define HTTP_HDR_OK_11 4 /* 200 OK */ +#define HTTP_HDR_NOT_FOUND_11 5 /* 404 File not found */ +#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */ +#define HTTP_HDR_NOT_IMPL_11 7 /* 501 Not Implemented */ +#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/ +#define HTTP_HDR_CONN_CLOSE 9 /* Connection: Close (HTTP 1.1) */ +#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */ +#define HTTP_HDR_KEEPALIVE_LEN 11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/ +#define HTTP_HDR_SERVER 12 /* Server: HTTPD_SERVER_AGENT */ +#define DEFAULT_404_HTML 13 /* default 404 body */ +#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE +#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */ +#endif + + +#define HTTP_HDR_HTML "Content-type: text/html\r\n\r\n" +#define HTTP_HDR_SSI "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n" +#define HTTP_HDR_GIF "Content-type: image/gif\r\n\r\n" +#define HTTP_HDR_PNG "Content-type: image/png\r\n\r\n" +#define HTTP_HDR_JPG "Content-type: image/jpeg\r\n\r\n" +#define HTTP_HDR_BMP "Content-type: image/bmp\r\n\r\n" +#define HTTP_HDR_ICO "Content-type: image/x-icon\r\n\r\n" +#define HTTP_HDR_APP "Content-type: application/octet-stream\r\n\r\n" +#define HTTP_HDR_JS "Content-type: application/javascript\r\n\r\n" +#define HTTP_HDR_RA "Content-type: application/javascript\r\n\r\n" +#define HTTP_HDR_CSS "Content-type: text/css\r\n\r\n" +#define HTTP_HDR_SWF "Content-type: application/x-shockwave-flash\r\n\r\n" +#define HTTP_HDR_XML "Content-type: text/xml\r\n\r\n" +#define HTTP_HDR_PDF "Content-type: application/pdf\r\n\r\n" +#define HTTP_HDR_JSON "Content-type: application/json\r\n\r\n" + +#define HTTP_HDR_DEFAULT_TYPE "Content-type: text/plain\r\n\r\n" + +/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES + * and http://www.iana.org/assignments/media-types for registered content types + * and subtypes) */ +static const tHTTPHeader g_psHTTPHeaders[] = +{ + { "html", HTTP_HDR_HTML}, + { "htm", HTTP_HDR_HTML}, + { "shtml",HTTP_HDR_SSI}, + { "shtm", HTTP_HDR_SSI}, + { "ssi", HTTP_HDR_SSI}, + { "gif", HTTP_HDR_GIF}, + { "png", HTTP_HDR_PNG}, + { "jpg", HTTP_HDR_JPG}, + { "bmp", HTTP_HDR_BMP}, + { "ico", HTTP_HDR_ICO}, + { "class",HTTP_HDR_APP}, + { "cls", HTTP_HDR_APP}, + { "js", HTTP_HDR_JS}, + { "ram", HTTP_HDR_RA}, + { "css", HTTP_HDR_CSS}, + { "swf", HTTP_HDR_SWF}, + { "xml", HTTP_HDR_XML}, + { "xsl", HTTP_HDR_XML}, + { "pdf", HTTP_HDR_PDF}, + { "json", HTTP_HDR_JSON} +}; + +#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader)) + +#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ + +#if LWIP_HTTPD_SSI +static const char * const g_pcSSIExtensions[] = { + ".shtml", ".shtm", ".ssi", ".xml" +}; +#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *)) +#endif /* LWIP_HTTPD_SSI */ + +#endif /* LWIP_HTTPD_STRUCTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata new file mode 100644 index 0000000..37b4203 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata @@ -0,0 +1,97 @@ +#!/usr/bin/perl + +open(OUTPUT, "> fsdata.c"); + +chdir("fs"); +open(FILES, "find . -type f |"); + +while($file = ) { + + # Do not include files in CVS directories nor backup files. + if($file =~ /(CVS|~)/) { + next; + } + + chop($file); + + open(HEADER, "> /tmp/header") || die $!; + if($file =~ /404/) { + print(HEADER "HTTP/1.0 404 File not found\r\n"); + } else { + print(HEADER "HTTP/1.0 200 OK\r\n"); + } + print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"); + if($file =~ /\.html$/) { + print(HEADER "Content-type: text/html\r\n"); + } elsif($file =~ /\.gif$/) { + print(HEADER "Content-type: image/gif\r\n"); + } elsif($file =~ /\.png$/) { + print(HEADER "Content-type: image/png\r\n"); + } elsif($file =~ /\.jpg$/) { + print(HEADER "Content-type: image/jpeg\r\n"); + } elsif($file =~ /\.class$/) { + print(HEADER "Content-type: application/octet-stream\r\n"); + } elsif($file =~ /\.ram$/) { + print(HEADER "Content-type: audio/x-pn-realaudio\r\n"); + } else { + print(HEADER "Content-type: text/plain\r\n"); + } + print(HEADER "\r\n"); + close(HEADER); + + unless($file =~ /\.plain$/ || $file =~ /cgi/) { + system("cat /tmp/header $file > /tmp/file"); + } else { + system("cp $file /tmp/file"); + } + + open(FILE, "/tmp/file"); + unlink("/tmp/file"); + unlink("/tmp/header"); + + $file =~ s/\.//; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@files, $file); +} + +for($i = 0; $i < @fvars; $i++) { + $file = $files[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define FS_NUMFILES $i\n"); diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata.c new file mode 100644 index 0000000..366b48a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/makefsdata.c @@ -0,0 +1,1032 @@ +/** + * makefsdata: Converts a directory structure for use with the lwIP httpd. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jim Pettinato + * Simon Goldschmidt + * + * @todo: + * - take TCP_MSS, LWIP_TCP_TIMESTAMPS and + * PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments + */ + +#include +#include +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include "windows.h" +#else +#include +#endif +#include +#include +#include +#include + +/** Makefsdata can generate *all* files deflate-compressed (where file size shrinks). + * Since nearly all browsers support this, this is a good way to reduce ROM size. + * To compress the files, "miniz.c" must be downloaded seperately. + */ +#ifndef MAKEFS_SUPPORT_DEFLATE +#define MAKEFS_SUPPORT_DEFLATE 0 +#endif + +#define COPY_BUFSIZE (1024*1024) /* 1 MByte */ + +#if MAKEFS_SUPPORT_DEFLATE +#include "../miniz.c" + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint; + +#define my_max(a,b) (((a) > (b)) ? (a) : (b)) +#define my_min(a,b) (((a) < (b)) ? (a) : (b)) + +/* COMP_OUT_BUF_SIZE is the size of the output buffer used during compression. + COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE */ +#define COMP_OUT_BUF_SIZE COPY_BUFSIZE + +/* OUT_BUF_SIZE is the size of the output buffer used during decompression. + OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) */ +#define OUT_BUF_SIZE COPY_BUFSIZE +static uint8 s_outbuf[OUT_BUF_SIZE]; +static uint8 s_checkbuf[OUT_BUF_SIZE]; + +/* tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). + This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. */ +tdefl_compressor g_deflator; +tinfl_decompressor g_inflator; + +int deflate_level = 10; /* default compression level, can be changed via command line */ +#define USAGE_ARG_DEFLATE " [-defl<:compr_level>]" +#else /* MAKEFS_SUPPORT_DEFLATE */ +#define USAGE_ARG_DEFLATE "" +#endif /* MAKEFS_SUPPORT_DEFLATE */ + +/* Compatibility defines Win32 vs. DOS */ +#ifdef WIN32 + +#define FIND_T WIN32_FIND_DATAA +#define FIND_T_FILENAME(fInfo) (fInfo.cFileName) +#define FIND_T_IS_DIR(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) +#define FIND_T_IS_FILE(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) +#define FIND_RET_T HANDLE +#define FINDFIRST_FILE(path, result) FindFirstFileA(path, result) +#define FINDFIRST_DIR(path, result) FindFirstFileA(path, result) +#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) +#define FINDFIRST_SUCCEEDED(ret) (ret != INVALID_HANDLE_VALUE) +#define FINDNEXT_SUCCEEDED(ret) (ret == TRUE) + +#define GETCWD(path, len) GetCurrentDirectoryA(len, path) +#define CHDIR(path) SetCurrentDirectoryA(path) +#define CHDIR_SUCCEEDED(ret) (ret == TRUE) + +#else + +#define FIND_T struct ffblk +#define FIND_T_FILENAME(fInfo) (fInfo.ff_name) +#define FIND_T_IS_DIR(fInfo) ((fInfo.ff_attrib & FA_DIREC) == FA_DIREC) +#define FIND_T_IS_FILE(fInfo) (1) +#define FIND_RET_T int +#define FINDFIRST_FILE(path, result) findfirst(path, result, FA_ARCH) +#define FINDFIRST_DIR(path, result) findfirst(path, result, FA_DIREC) +#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) +#define FINDFIRST_SUCCEEDED(ret) (ret == 0) +#define FINDNEXT_SUCCEEDED(ret) (ret == 0) + +#define GETCWD(path, len) getcwd(path, len) +#define CHDIR(path) chdir(path) +#define CHDIR_SUCCEEDED(ret) (ret == 0) + +#endif + +#define NEWLINE "\r\n" +#define NEWLINE_LEN 2 + +/* define this to get the header variables we use to build HTTP headers */ +#define LWIP_HTTPD_DYNAMIC_HEADERS 1 +#define LWIP_HTTPD_SSI 1 +#include "lwip/init.h" +#include "../httpd_structs.h" +#include "lwip/apps/fs.h" + +#include "../core/inet_chksum.c" +#include "../core/def.c" + +/** (Your server name here) */ +const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n"; +char serverIDBuffer[1024]; + +/* change this to suit your MEM_ALIGNMENT */ +#define PAYLOAD_ALIGNMENT 4 +/* set this to 0 to prevent aligning payload */ +#define ALIGN_PAYLOAD 1 +/* define this to a type that has the required alignment */ +#define PAYLOAD_ALIGN_TYPE "unsigned int" +static int payload_alingment_dummy_counter = 0; + +#define HEX_BYTES_PER_LINE 16 + +#define MAX_PATH_LEN 256 + +struct file_entry +{ + struct file_entry* next; + const char* filename_c; +}; + +int process_sub(FILE *data_file, FILE *struct_file); +int process_file(FILE *data_file, FILE *struct_file, const char *filename); +int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len, + u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed); +int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i); +int s_put_ascii(char *buf, const char *ascii_string, int len, int *i); +void concat_files(const char *file1, const char *file2, const char *targetfile); +int check_path(char* path, size_t size); + +/* 5 bytes per char + 3 bytes per line */ +static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)]; + +char curSubdir[MAX_PATH_LEN]; +char lastFileVar[MAX_PATH_LEN]; +char hdr_buf[4096]; + +unsigned char processSubs = 1; +unsigned char includeHttpHeader = 1; +unsigned char useHttp11 = 0; +unsigned char supportSsi = 1; +unsigned char precalcChksum = 0; +unsigned char includeLastModified = 0; +#if MAKEFS_SUPPORT_DEFLATE +unsigned char deflateNonSsiFiles = 0; +size_t deflatedBytesReduced = 0; +size_t overallDataBytes = 0; +#endif + +struct file_entry* first_file = NULL; +struct file_entry* last_file = NULL; + +static void print_usage(void) +{ + printf(" Usage: htmlgen [targetdir] [-s] [-e] [-i] [-11] [-nossi] [-c] [-f:] [-m] [-svr:]" USAGE_ARG_DEFLATE NEWLINE NEWLINE); + printf(" targetdir: relative or absolute path to files to convert" NEWLINE); + printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE); + printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE); + printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE); + printf(" switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE); + printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE); + printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE); + printf(" switch -m: include \"Last-Modified\" header based on file time" NEWLINE); + printf(" switch -svr: server identifier sent in HTTP response header ('Server' field)" NEWLINE); +#if MAKEFS_SUPPORT_DEFLATE + printf(" switch -defl: deflate-compress all non-SSI files (with opt. compr.-level, default=10)" NEWLINE); + printf(" ATTENTION: browser has to support \"Content-Encoding: deflate\"!" NEWLINE); +#endif + printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE); + printf(" process files in subdirectory 'fs'" NEWLINE); +} + +int main(int argc, char *argv[]) +{ + char path[MAX_PATH_LEN]; + char appPath[MAX_PATH_LEN]; + FILE *data_file; + FILE *struct_file; + int filesProcessed; + int i; + char targetfile[MAX_PATH_LEN]; + strcpy(targetfile, "fsdata.c"); + + memset(path, 0, sizeof(path)); + memset(appPath, 0, sizeof(appPath)); + + printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE); + printf(" by Jim Pettinato - circa 2003 " NEWLINE); + printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE); + + strcpy(path, "fs"); + for (i = 1; i < argc; i++) { + if (argv[i] == NULL) { + continue; + } + if (argv[i][0] == '-') { + if (strstr(argv[i], "-svr:") == argv[i]) { + snprintf(serverIDBuffer, sizeof(serverIDBuffer), "Server: %s\r\n", &argv[i][5]); + serverID = serverIDBuffer; + printf("Using Server-ID: \"%s\"\n", serverID); + } else if (strstr(argv[i], "-s") == argv[i]) { + processSubs = 0; + } else if (strstr(argv[i], "-e") == argv[i]) { + includeHttpHeader = 0; + } else if (strstr(argv[i], "-11") == argv[i]) { + useHttp11 = 1; + } else if (strstr(argv[i], "-nossi") == argv[i]) { + supportSsi = 0; + } else if (strstr(argv[i], "-c") == argv[i]) { + precalcChksum = 1; + } else if (strstr(argv[i], "-f:") == argv[i]) { + strncpy(targetfile, &argv[i][3], sizeof(targetfile) - 1); + targetfile[sizeof(targetfile) - 1] = 0; + printf("Writing to file \"%s\"\n", targetfile); + } else if (strstr(argv[i], "-m") == argv[i]) { + includeLastModified = 1; + } else if (strstr(argv[i], "-defl") == argv[i]) { +#if MAKEFS_SUPPORT_DEFLATE + char* colon = strstr(argv[i], ":"); + if (colon) { + if (colon[1] != 0) { + int defl_level = atoi(&colon[1]); + if ((defl_level >= 0) && (defl_level <= 10)) { + deflate_level = defl_level; + } else { + printf("ERROR: deflate level must be [0..10]" NEWLINE); + exit(0); + } + } + } + deflateNonSsiFiles = 1; + printf("Deflating all non-SSI files with level %d (but only if size is reduced)" NEWLINE, deflate_level); +#else + printf("WARNING: Deflate support is disabled\n"); +#endif + } else if ((strstr(argv[i], "-?")) || (strstr(argv[i], "-h"))) { + print_usage(); + exit(0); + } + } else if ((argv[i][0] == '/') && (argv[i][1] == '?') && (argv[i][2] == 0)) { + print_usage(); + exit(0); + } else { + strncpy(path, argv[i], sizeof(path)-1); + path[sizeof(path)-1] = 0; + } + } + + if (!check_path(path, sizeof(path))) { + printf("Invalid path: \"%s\"." NEWLINE, path); + exit(-1); + } + + GETCWD(appPath, MAX_PATH_LEN); + /* if command line param or subdir named 'fs' not found spout usage verbiage */ + if (!CHDIR_SUCCEEDED(CHDIR(path))) { + /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */ + printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path); + print_usage(); + exit(-1); + } + CHDIR(appPath); + + printf("HTTP %sheader will %s statically included." NEWLINE, + (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""), + (includeHttpHeader ? "be" : "not be")); + + sprintf(curSubdir, ""); /* start off in web page's root directory - relative paths */ + printf(" Processing all files in directory %s", path); + if (processSubs) { + printf(" and subdirectories..." NEWLINE NEWLINE); + } else { + printf("..." NEWLINE NEWLINE); + } + + data_file = fopen("fsdata.tmp", "wb"); + if (data_file == NULL) { + printf("Failed to create file \"fsdata.tmp\"\n"); + exit(-1); + } + struct_file = fopen("fshdr.tmp", "wb"); + if (struct_file == NULL) { + printf("Failed to create file \"fshdr.tmp\"\n"); + fclose(data_file); + exit(-1); + } + + CHDIR(path); + + fprintf(data_file, "#include \"lwip/apps/fs.h\"" NEWLINE); + fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE NEWLINE NEWLINE); + + fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE); + /* define FS_FILE_FLAGS_HEADER_INCLUDED to 1 if not defined (compatibility with older httpd/fs) */ + fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_INCLUDED" NEWLINE "#define FS_FILE_FLAGS_HEADER_INCLUDED 1" NEWLINE "#endif" NEWLINE); + /* define FS_FILE_FLAGS_HEADER_PERSISTENT to 0 if not defined (compatibility with older httpd/fs: wasn't supported back then) */ + fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT" NEWLINE "#define FS_FILE_FLAGS_HEADER_PERSISTENT 0" NEWLINE "#endif" NEWLINE); + + /* define alignment defines */ +#if ALIGN_PAYLOAD + fprintf(data_file, "/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */" NEWLINE "#ifndef FSDATA_FILE_ALIGNMENT" NEWLINE "#define FSDATA_FILE_ALIGNMENT 0" NEWLINE "#endif" NEWLINE); +#endif + fprintf(data_file, "#ifndef FSDATA_ALIGN_PRE" NEWLINE "#define FSDATA_ALIGN_PRE" NEWLINE "#endif" NEWLINE); + fprintf(data_file, "#ifndef FSDATA_ALIGN_POST" NEWLINE "#define FSDATA_ALIGN_POST" NEWLINE "#endif" NEWLINE); +#if ALIGN_PAYLOAD + fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==2" NEWLINE "#include \"fsdata_alignment.h\"" NEWLINE "#endif" NEWLINE); +#endif + + sprintf(lastFileVar, "NULL"); + + filesProcessed = process_sub(data_file, struct_file); + + /* data_file now contains all of the raw data.. now append linked list of + * file header structs to allow embedded app to search for a file name */ + fprintf(data_file, NEWLINE NEWLINE); + fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar); + fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed); + + fclose(data_file); + fclose(struct_file); + + CHDIR(appPath); + /* append struct_file to data_file */ + printf(NEWLINE "Creating target file..." NEWLINE NEWLINE); + concat_files("fsdata.tmp", "fshdr.tmp", targetfile); + + /* if succeeded, delete the temporary files */ + if (remove("fsdata.tmp") != 0) { + printf("Warning: failed to delete fsdata.tmp\n"); + } + if (remove("fshdr.tmp") != 0) { + printf("Warning: failed to delete fshdr.tmp\n"); + } + + printf(NEWLINE "Processed %d files - done." NEWLINE, filesProcessed); +#if MAKEFS_SUPPORT_DEFLATE + if (deflateNonSsiFiles) { + printf("(Deflated total byte reduction: %d bytes -> %d bytes (%.02f%%)" NEWLINE, + (int)overallDataBytes, (int)deflatedBytesReduced, (float)((deflatedBytesReduced*100.0)/overallDataBytes)); + } +#endif + printf(NEWLINE); + + while (first_file != NULL) { + struct file_entry* fe = first_file; + first_file = fe->next; + free(fe); + } + + return 0; +} + +int check_path(char* path, size_t size) +{ + size_t slen; + if (path[0] == 0) { + /* empty */ + return 0; + } + slen = strlen(path); + if (slen >= size) { + /* not NULL-terminated */ + return 0; + } + while ((slen > 0) && ((path[slen] == '\\') || (path[slen] == '/'))) { + /* path should not end with trailing backslash */ + path[slen] = 0; + slen--; + } + if (slen == 0) { + return 0; + } + return 1; +} + +static void copy_file(const char *filename_in, FILE *fout) +{ + FILE *fin; + size_t len; + void* buf; + fin = fopen(filename_in, "rb"); + if (fin == NULL) { + printf("Failed to open file \"%s\"\n", filename_in); + exit(-1); + } + buf = malloc(COPY_BUFSIZE); + while ((len = fread(buf, 1, COPY_BUFSIZE, fin)) > 0) { + fwrite(buf, 1, len, fout); + } + free(buf); + fclose(fin); +} + +void concat_files(const char *file1, const char *file2, const char *targetfile) +{ + FILE *fout; + fout = fopen(targetfile, "wb"); + if (fout == NULL) { + printf("Failed to open file \"%s\"\n", targetfile); + exit(-1); + } + copy_file(file1, fout); + copy_file(file2, fout); + fclose(fout); +} + +int process_sub(FILE *data_file, FILE *struct_file) +{ + FIND_T fInfo; + FIND_RET_T fret; + int filesProcessed = 0; + + if (processSubs) { + /* process subs recursively */ + size_t sublen = strlen(curSubdir); + size_t freelen = sizeof(curSubdir) - sublen - 1; + LWIP_ASSERT("sublen < sizeof(curSubdir)", sublen < sizeof(curSubdir)); + fret = FINDFIRST_DIR("*", &fInfo); + if (FINDFIRST_SUCCEEDED(fret)) { + do { + const char *curName = FIND_T_FILENAME(fInfo); + if ((curName[0] == '.') || (strcmp(curName, "CVS") == 0)) { + continue; + } + if (!FIND_T_IS_DIR(fInfo)) { + continue; + } + if (freelen > 0) { + CHDIR(curName); + strncat(curSubdir, "/", freelen); + strncat(curSubdir, curName, freelen - 1); + curSubdir[sizeof(curSubdir) - 1] = 0; + printf("processing subdirectory %s/..." NEWLINE, curSubdir); + filesProcessed += process_sub(data_file, struct_file); + CHDIR(".."); + curSubdir[sublen] = 0; + } else { + printf("WARNING: cannot process sub due to path length restrictions: \"%s/%s\"\n", curSubdir, curName); + } + } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); + } + } + + fret = FINDFIRST_FILE("*.*", &fInfo); + if (FINDFIRST_SUCCEEDED(fret)) { + /* at least one file in directory */ + do { + if (FIND_T_IS_FILE(fInfo)) { + const char *curName = FIND_T_FILENAME(fInfo); + printf("processing %s/%s..." NEWLINE, curSubdir, curName); + if (process_file(data_file, struct_file, curName) < 0) { + printf(NEWLINE "Error... aborting" NEWLINE); + return -1; + } + filesProcessed++; + } + } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); + } + return filesProcessed; +} + +u8_t* get_file_data(const char* filename, int* file_size, int can_be_compressed, int* is_compressed) +{ + FILE *inFile; + size_t fsize = 0; + u8_t* buf; + size_t r; + int rs; + inFile = fopen(filename, "rb"); + if (inFile == NULL) { + printf("Failed to open file \"%s\"\n", filename); + exit(-1); + } + fseek(inFile, 0, SEEK_END); + rs = ftell(inFile); + if (rs < 0) { + printf("ftell failed with %d\n", errno); + exit(-1); + } + fsize = (size_t)rs; + fseek(inFile, 0, SEEK_SET); + buf = (u8_t*)malloc(fsize); + LWIP_ASSERT("buf != NULL", buf != NULL); + r = fread(buf, 1, fsize, inFile); + *file_size = fsize; + *is_compressed = 0; +#if MAKEFS_SUPPORT_DEFLATE + overallDataBytes += fsize; + if (deflateNonSsiFiles) { + if (can_be_compressed) { + if (fsize < OUT_BUF_SIZE) { + u8_t* ret_buf; + tdefl_status status; + size_t in_bytes = fsize; + size_t out_bytes = OUT_BUF_SIZE; + const void *next_in = buf; + void *next_out = s_outbuf; + /* create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). */ + mz_uint comp_flags = s_tdefl_num_probes[MZ_MIN(10, deflate_level)] | ((deflate_level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (!deflate_level) { + comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + } + status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); + if (status != TDEFL_STATUS_OKAY) { + printf("tdefl_init() failed!\n"); + exit(-1); + } + memset(s_outbuf, 0, sizeof(s_outbuf)); + status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, TDEFL_FINISH); + if (status != TDEFL_STATUS_DONE) { + printf("deflate failed: %d\n", status); + exit(-1); + } + LWIP_ASSERT("out_bytes <= COPY_BUFSIZE", out_bytes <= OUT_BUF_SIZE); + if (out_bytes < fsize) { + ret_buf = (u8_t*)malloc(out_bytes); + LWIP_ASSERT("ret_buf != NULL", ret_buf != NULL); + memcpy(ret_buf, s_outbuf, out_bytes); + { + /* sanity-check compression be inflating and comparing to the original */ + tinfl_status dec_status; + tinfl_decompressor inflator; + size_t dec_in_bytes = out_bytes; + size_t dec_out_bytes = OUT_BUF_SIZE; + next_out = s_checkbuf; + + tinfl_init(&inflator); + memset(s_checkbuf, 0, sizeof(s_checkbuf)); + dec_status = tinfl_decompress(&inflator, (const mz_uint8 *)ret_buf, &dec_in_bytes, s_checkbuf, (mz_uint8 *)next_out, &dec_out_bytes, 0); + LWIP_ASSERT("tinfl_decompress failed", dec_status == TINFL_STATUS_DONE); + LWIP_ASSERT("tinfl_decompress size mismatch", fsize == dec_out_bytes); + LWIP_ASSERT("decompressed memcmp failed", !memcmp(s_checkbuf, buf, fsize)); + } + /* free original buffer, use compressed data + size */ + free(buf); + buf = ret_buf; + *file_size = out_bytes; + printf(" - deflate: %d bytes -> %d bytes (%.02f%%)" NEWLINE, (int)fsize, (int)out_bytes, (float)((out_bytes*100.0)/fsize)); + deflatedBytesReduced += (size_t)(fsize - out_bytes); + *is_compressed = 1; + } else { + printf(" - uncompressed: (would be %d bytes larger using deflate)" NEWLINE, (int)(out_bytes - fsize)); + } + } else { + printf(" - uncompressed: (file is larger than deflate bufer)" NEWLINE); + } + } else { + printf(" - SSI file, cannot be compressed" NEWLINE); + } + } +#else + LWIP_UNUSED_ARG(can_be_compressed); +#endif + fclose(inFile); + return buf; +} + +void process_file_data(FILE* data_file, u8_t* file_data, size_t file_size) +{ + size_t written, i, src_off=0; + + size_t off = 0; + for (i = 0; i < file_size; i++) { + LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - 5); + sprintf(&file_buffer_c[off], "0x%02.2x,", file_data[i]); + off += 5; + if ((++src_off % HEX_BYTES_PER_LINE) == 0) { + LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - NEWLINE_LEN); + memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN); + off += NEWLINE_LEN; + } + if (off + 20 >= sizeof(file_buffer_c)) { + written = fwrite(file_buffer_c, 1, off, data_file); + LWIP_ASSERT("written == off", written == off); + off = 0; + } + } + written = fwrite(file_buffer_c, 1, off, data_file); + LWIP_ASSERT("written == off", written == off); +} + +int write_checksums(FILE *struct_file, const char *varname, + u16_t hdr_len, u16_t hdr_chksum, const u8_t* file_data, size_t file_size) +{ + int chunk_size = TCP_MSS; + int offset, src_offset; + size_t len; + int i = 0; +#if LWIP_TCP_TIMESTAMPS + /* when timestamps are used, usable space is 12 bytes less per segment */ + chunk_size -= 12; +#endif + + fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); + fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname); + + if (hdr_len > 0) { + /* add checksum for HTTP header */ + fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len); + i++; + } + src_offset = 0; + for (offset = hdr_len; ; offset += len) { + unsigned short chksum; + void* data = (void*)&file_data[src_offset]; + len = LWIP_MIN(chunk_size, (int)file_size - src_offset); + if (len == 0) { + break; + } + chksum = ~inet_chksum(data, (u16_t)len); + /* add checksum for data */ + fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, offset, chksum, len); + i++; + } + fprintf(struct_file, "};" NEWLINE); + fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); + return i; +} + +static int is_valid_char_for_c_var(char x) +{ + if (((x >= 'A') && (x <= 'Z')) || + ((x >= 'a') && (x <= 'z')) || + ((x >= '0') && (x <= '9')) || + (x == '_')) { + return 1; + } + return 0; +} + +static void fix_filename_for_c(char* qualifiedName, size_t max_len) +{ + struct file_entry* f; + size_t len = strlen(qualifiedName); + char *new_name = (char*)malloc(len + 2); + int filename_ok; + int cnt = 0; + size_t i; + if (len + 3 == max_len) { + printf("File name too long: \"%s\"\n", qualifiedName); + exit(-1); + } + strcpy(new_name, qualifiedName); + for (i = 0; i < len; i++) { + if (!is_valid_char_for_c_var(new_name[i])) { + new_name[i] = '_'; + } + } + do { + filename_ok = 1; + for (f = first_file; f != NULL; f = f->next) { + if (!strcmp(f->filename_c, new_name)) { + filename_ok = 0; + cnt++; + /* try next unique file name */ + sprintf(&new_name[len], "%d", cnt); + break; + } + } + } while (!filename_ok && (cnt < 999)); + if (!filename_ok) { + printf("Failed to get unique file name: \"%s\"\n", qualifiedName); + exit(-1); + } + strcpy(qualifiedName, new_name); + free(new_name); +} + +static void register_filename(const char* qualifiedName) +{ + struct file_entry* fe = (struct file_entry*)malloc(sizeof(struct file_entry)); + fe->filename_c = strdup(qualifiedName); + fe->next = NULL; + if (first_file == NULL) { + first_file = last_file = fe; + } else { + last_file->next = fe; + last_file = fe; + } +} + +int is_ssi_file(const char* filename) +{ + size_t loop; + for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { + if (strstr(filename, g_pcSSIExtensions[loop])) { + return 1; + } + } + return 0; +} + +int process_file(FILE *data_file, FILE *struct_file, const char *filename) +{ + char varname[MAX_PATH_LEN]; + int i = 0; + char qualifiedName[MAX_PATH_LEN]; + int file_size; + u16_t http_hdr_chksum = 0; + u16_t http_hdr_len = 0; + int chksum_count = 0; + u8_t flags = 0; + const char* flags_str; + u8_t has_content_len; + u8_t* file_data; + int is_compressed = 0; + + /* create qualified name (@todo: prepend slash or not?) */ + sprintf(qualifiedName,"%s/%s", curSubdir, filename); + /* create C variable name */ + strcpy(varname, qualifiedName); + /* convert slashes & dots to underscores */ + fix_filename_for_c(varname, MAX_PATH_LEN); + register_filename(varname); +#if ALIGN_PAYLOAD + /* to force even alignment of array, type 1 */ + fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==1" NEWLINE); + fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++); + fprintf(data_file, "#endif" NEWLINE); +#endif /* ALIGN_PAYLOAD */ + fprintf(data_file, "static const unsigned char FSDATA_ALIGN_PRE data_%s[] FSDATA_ALIGN_POST = {" NEWLINE, varname); + /* encode source file name (used by file system, not returned to browser) */ + fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1); + file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i); +#if ALIGN_PAYLOAD + /* pad to even number of bytes to assure payload is on aligned boundary */ + while(i % PAYLOAD_ALIGNMENT != 0) { + fprintf(data_file, "0x%02.2x,", 0); + i++; + } +#endif /* ALIGN_PAYLOAD */ + fprintf(data_file, NEWLINE); + + has_content_len = !is_ssi_file(filename); + file_data = get_file_data(filename, &file_size, includeHttpHeader && has_content_len, &is_compressed); + if (includeHttpHeader) { + file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum, has_content_len, is_compressed); + flags = FS_FILE_FLAGS_HEADER_INCLUDED; + if (has_content_len) { + flags |= FS_FILE_FLAGS_HEADER_PERSISTENT; + } + } + if (precalcChksum) { + chksum_count = write_checksums(struct_file, varname, http_hdr_len, http_hdr_chksum, file_data, file_size); + } + + /* build declaration of struct fsdata_file in temp file */ + fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname); + fprintf(struct_file, "file_%s," NEWLINE, lastFileVar); + fprintf(struct_file, "data_%s," NEWLINE, varname); + fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i); + fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i); + switch(flags) + { + case(FS_FILE_FLAGS_HEADER_INCLUDED): + flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED"; + break; + case(FS_FILE_FLAGS_HEADER_PERSISTENT): + flags_str = "FS_FILE_FLAGS_HEADER_PERSISTENT"; + break; + case(FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT): + flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT"; + break; + default: + flags_str = "0"; + break; + } + fprintf(struct_file, "%s," NEWLINE, flags_str); + if (precalcChksum) { + fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); + fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname); + fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); + } + fprintf(struct_file, "}};" NEWLINE NEWLINE); + strcpy(lastFileVar, varname); + + /* write actual file contents */ + i = 0; + fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size); + process_file_data(data_file, file_data, file_size); + fprintf(data_file, "};" NEWLINE NEWLINE); + free(file_data); + return 0; +} + +int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len, + u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed) +{ + int i = 0; + int response_type = HTTP_HDR_OK; + const char* file_type; + const char *cur_string; + size_t cur_len; + int written = 0; + size_t hdr_len = 0; + u16_t acc; + const char *file_ext; + int j; + u8_t provide_last_modified = includeLastModified; + + memset(hdr_buf, 0, sizeof(hdr_buf)); + + if (useHttp11) { + response_type = HTTP_HDR_OK_11; + } + + fprintf(data_file, NEWLINE "/* HTTP header */"); + if (strstr(filename, "404") == filename) { + response_type = HTTP_HDR_NOT_FOUND; + if (useHttp11) { + response_type = HTTP_HDR_NOT_FOUND_11; + } + } else if (strstr(filename, "400") == filename) { + response_type = HTTP_HDR_BAD_REQUEST; + if (useHttp11) { + response_type = HTTP_HDR_BAD_REQUEST_11; + } + } else if (strstr(filename, "501") == filename) { + response_type = HTTP_HDR_NOT_IMPL; + if (useHttp11) { + response_type = HTTP_HDR_NOT_IMPL_11; + } + } + cur_string = g_psHTTPHeaderStrings[response_type]; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + cur_string = serverID; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + file_ext = filename; + if (file_ext != NULL) { + while(strstr(file_ext, ".") != NULL) { + file_ext = strstr(file_ext, "."); + file_ext++; + } + } + if ((file_ext == NULL) || (*file_ext == 0)) { + printf("failed to get extension for file \"%s\", using default.\n", filename); + file_type = HTTP_HDR_DEFAULT_TYPE; + } else { + file_type = NULL; + for (j = 0; j < NUM_HTTP_HEADERS; j++) { + if (!strcmp(file_ext, g_psHTTPHeaders[j].extension)) { + file_type = g_psHTTPHeaders[j].content_type; + break; + } + } + if (file_type == NULL) { + printf("failed to get file type for extension \"%s\", using default.\n", file_ext); + file_type = HTTP_HDR_DEFAULT_TYPE; + } + } + + /* Content-Length is used for persistent connections in HTTP/1.1 but also for + download progress in older versions + @todo: just use a big-enough buffer and let the HTTPD send spaces? */ + if (provide_content_len) { + char intbuf[MAX_PATH_LEN]; + int content_len = file_size; + memset(intbuf, 0, sizeof(intbuf)); + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, content_len, cur_len+2); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + _itoa(content_len, intbuf, 10); + strcat(intbuf, "\r\n"); + cur_len = strlen(intbuf); + written += file_put_ascii(data_file, intbuf, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], intbuf, cur_len); + hdr_len += cur_len; + } + } + if (provide_last_modified) { + char modbuf[256]; + struct stat stat_data; + struct tm* t; + memset(modbuf, 0, sizeof(modbuf)); + memset(&stat_data, 0, sizeof(stat_data)); + cur_string = modbuf; + strcpy(modbuf, "Last-Modified: "); + if (stat(filename, &stat_data) != 0) { + printf("stat(%s) failed with error %d\n", filename, errno); + exit(-1); + } + t = gmtime(&stat_data.st_mtime); + if (t == NULL) { + printf("gmtime() failed with error %d\n", errno); + exit(-1); + } + strftime(&modbuf[15], sizeof(modbuf)-15, "%a, %d %b %Y %H:%M:%S GMT", t); + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\"\r\n\" (%d+ bytes) */" NEWLINE, cur_string, cur_len+2); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + + modbuf[0] = 0; + strcat(modbuf, "\r\n"); + cur_len = strlen(modbuf); + written += file_put_ascii(data_file, modbuf, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], modbuf, cur_len); + hdr_len += cur_len; + } + } + + /* HTTP/1.1 implements persistent connections */ + if (useHttp11) { + if (provide_content_len) { + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE]; + } else { + /* no Content-Length available, so a persistent connection is no possible + because the client does not know the data length */ + cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; + } + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + } + } + +#if MAKEFS_SUPPORT_DEFLATE + if (is_compressed) { + /* tell the client about the deflate encoding */ + LWIP_ASSERT("error", deflateNonSsiFiles); + cur_string = "Content-Encoding: deflate\r\n"; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + } +#else + LWIP_UNUSED_ARG(is_compressed); +#endif + + /* write content-type, ATTENTION: this includes the double-CRLF! */ + cur_string = file_type; + cur_len = strlen(cur_string); + fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); + written += file_put_ascii(data_file, cur_string, cur_len, &i); + i = 0; + + /* ATTENTION: headers are done now (double-CRLF has been written!) */ + + if (precalcChksum) { + memcpy(&hdr_buf[hdr_len], cur_string, cur_len); + hdr_len += cur_len; + + LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff); + LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len); + acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len); + *http_hdr_len = (u16_t)hdr_len; + *http_hdr_chksum = acc; + } + + return written; +} + +int file_put_ascii(FILE *file, const char* ascii_string, int len, int *i) +{ + int x; + for (x = 0; x < len; x++) { + unsigned char cur = ascii_string[x]; + fprintf(file, "0x%02.2x,", cur); + if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { + fprintf(file, NEWLINE); + } + } + return len; +} + +int s_put_ascii(char *buf, const char *ascii_string, int len, int *i) +{ + int x; + int idx = 0; + for (x = 0; x < len; x++) { + unsigned char cur = ascii_string[x]; + sprintf(&buf[idx], "0x%02.2x,", cur); + idx += 5; + if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { + sprintf(&buf[idx], NEWLINE); + idx += NEWLINE_LEN; + } + } + return len; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/readme.txt b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/readme.txt new file mode 100644 index 0000000..3768585 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/httpd/makefsdata/readme.txt @@ -0,0 +1,13 @@ +This directory contains a script ('makefsdata') to create C code suitable for +httpd for given html pages (or other files) in a directory. + +There is also a plain C console application doing the same and extended a bit. + +Usage: htmlgen [targetdir] [-s] [-i]s + targetdir: relative or absolute path to files to convert + switch -s: toggle processing of subdirectories (default is on) + switch -e: exclude HTTP header from file (header is created at runtime, default is on) + switch -11: include HTTP 1.1 header (1.0 is default) + + if targetdir not specified, makefsdata will attempt to + process files in subdirectory 'fs'. diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/lwiperf/lwiperf.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/lwiperf/lwiperf.c new file mode 100644 index 0000000..54bf2bc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/lwiperf/lwiperf.c @@ -0,0 +1,661 @@ +/** + * @file + * lwIP iPerf server implementation + */ + +/** + * @defgroup iperf Iperf server + * @ingroup apps + * + * This is a simple performance measuring server to check your bandwith using + * iPerf2 on a PC as client. + * It is currently a minimal implementation providing an IPv4 TCP server only. + * + * @todo: implement UDP mode and IPv6 + */ + +/* + * Copyright (c) 2014 Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + */ + +#include "lwip/apps/lwiperf.h" + +#include "lwip/tcp.h" +#include "lwip/sys.h" + +#include + +/* Currently, only TCP-over-IPv4 is implemented (does iperf support IPv6 anyway?) */ +#if LWIP_IPV4 && LWIP_TCP + +/** Specify the idle timeout (in seconds) after that the test fails */ +#ifndef LWIPERF_TCP_MAX_IDLE_SEC +#define LWIPERF_TCP_MAX_IDLE_SEC 10U +#endif +#if LWIPERF_TCP_MAX_IDLE_SEC > 255 +#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t +#endif + +/* File internal memory allocation (struct lwiperf_*): this defaults to + the heap */ +#ifndef LWIPERF_ALLOC +#define LWIPERF_ALLOC(type) mem_malloc(sizeof(type)) +#define LWIPERF_FREE(type, item) mem_free(item) +#endif + +/** If this is 1, check that received data has the correct format */ +#ifndef LWIPERF_CHECK_RX_DATA +#define LWIPERF_CHECK_RX_DATA 0 +#endif + +/** This is the Iperf settings struct sent from the client */ +typedef struct _lwiperf_settings { +#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000 +#define LWIPERF_FLAGS_ANSWER_NOW 0x00000001 + u32_t flags; + u32_t num_threads; /* unused for now */ + u32_t remote_port; + u32_t buffer_len; /* unused for now */ + u32_t win_band; /* TCP window / UDP rate: unused for now */ + u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */ +} lwiperf_settings_t; + +/** Basic connection handle */ +struct _lwiperf_state_base; +typedef struct _lwiperf_state_base lwiperf_state_base_t; +struct _lwiperf_state_base { + /* 1=tcp, 0=udp */ + u8_t tcp; + /* 1=server, 0=client */ + u8_t server; + lwiperf_state_base_t* next; + lwiperf_state_base_t* related_server_state; +}; + +/** Connection handle for a TCP iperf session */ +typedef struct _lwiperf_state_tcp { + lwiperf_state_base_t base; + struct tcp_pcb* server_pcb; + struct tcp_pcb* conn_pcb; + u32_t time_started; + lwiperf_report_fn report_fn; + void* report_arg; + u8_t poll_count; + u8_t next_num; + u32_t bytes_transferred; + lwiperf_settings_t settings; + u8_t have_settings_buf; +} lwiperf_state_tcp_t; + +/** List of active iperf sessions */ +static lwiperf_state_base_t* lwiperf_all_connections; +/** A const buffer to send from: we want to measure sending, not copying! */ +static const u8_t lwiperf_txbuf_const[1600] = { + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', + '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', +}; + +static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb); +static void lwiperf_tcp_err(void *arg, err_t err); + +/** Add an iperf session to the 'active' list */ +static void +lwiperf_list_add(lwiperf_state_base_t* item) +{ + if (lwiperf_all_connections == NULL) { + lwiperf_all_connections = item; + } else { + item = lwiperf_all_connections; + } +} + +/** Remove an iperf session from the 'active' list */ +static void +lwiperf_list_remove(lwiperf_state_base_t* item) +{ + lwiperf_state_base_t* prev = NULL; + lwiperf_state_base_t* iter; + for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) { + if (iter == item) { + if (prev == NULL) { + lwiperf_all_connections = iter->next; + } else { + prev->next = item; + } + /* @debug: ensure this item is listed only once */ + for (iter = iter->next; iter != NULL; iter = iter->next) { + LWIP_ASSERT("duplicate entry", iter != item); + } + break; + } + } +} + +/** Call the report function of an iperf tcp session */ +static void +lwip_tcp_conn_report(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) +{ + if ((conn != NULL) && (conn->report_fn != NULL)) { + u32_t now, duration_ms, bandwidth_kbitpsec; + now = sys_now(); + duration_ms = now - conn->time_started; + if (duration_ms == 0) { + bandwidth_kbitpsec = 0; + } else { + bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U; + } + conn->report_fn(conn->report_arg, report_type, + &conn->conn_pcb->local_ip, conn->conn_pcb->local_port, + &conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port, + conn->bytes_transferred, duration_ms, bandwidth_kbitpsec); + } +} + +/** Close an iperf tcp session */ +static void +lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) +{ + err_t err; + + lwip_tcp_conn_report(conn, report_type); + lwiperf_list_remove(&conn->base); + if (conn->conn_pcb != NULL) { + tcp_arg(conn->conn_pcb, NULL); + tcp_poll(conn->conn_pcb, NULL, 0); + tcp_sent(conn->conn_pcb, NULL); + tcp_recv(conn->conn_pcb, NULL); + tcp_err(conn->conn_pcb, NULL); + err = tcp_close(conn->conn_pcb); + if (err != ERR_OK) { + /* don't want to wait for free memory here... */ + tcp_abort(conn->conn_pcb); + } + } else { + /* no conn pcb, this is the server pcb */ + err = tcp_close(conn->server_pcb); + LWIP_ASSERT("error", err != ERR_OK); + } + LWIPERF_FREE(lwiperf_state_tcp_t, conn); +} + +/** Try to send more data on an iperf tcp session */ +static err_t +lwiperf_tcp_client_send_more(lwiperf_state_tcp_t* conn) +{ + int send_more; + err_t err; + u16_t txlen; + u16_t txlen_max; + void* txptr; + u8_t apiflags; + + LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0)); + + do { + send_more = 0; + if (conn->settings.amount & PP_HTONL(0x80000000)) { + /* this session is time-limited */ + u32_t now = sys_now(); + u32_t diff_ms = now - conn->time_started; + u32_t time = (u32_t)-(s32_t)lwip_htonl(conn->settings.amount); + u32_t time_ms = time * 10; + if (diff_ms >= time_ms) { + /* time specified by the client is over -> close the connection */ + lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); + return ERR_OK; + } + } else { + /* this session is byte-limited */ + u32_t amount_bytes = lwip_htonl(conn->settings.amount); + /* @todo: this can send up to 1*MSS more than requested... */ + if (amount_bytes >= conn->bytes_transferred) { + /* all requested bytes transferred -> close the connection */ + lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); + return ERR_OK; + } + } + + if (conn->bytes_transferred < 24) { + /* transmit the settings a first time */ + txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred]; + txlen_max = (u16_t)(24 - conn->bytes_transferred); + apiflags = TCP_WRITE_FLAG_COPY; + } else if (conn->bytes_transferred < 48) { + /* transmit the settings a second time */ + txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred - 24]; + txlen_max = (u16_t)(48 - conn->bytes_transferred); + apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE; + send_more = 1; + } else { + /* transmit data */ + /* @todo: every x bytes, transmit the settings again */ + txptr = LWIP_CONST_CAST(void*, &lwiperf_txbuf_const[conn->bytes_transferred % 10]); + txlen_max = TCP_MSS; + if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */ + txlen_max = TCP_MSS - 24; + } + apiflags = 0; /* no copying needed */ + send_more = 1; + } + txlen = txlen_max; + do { + err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags); + if (err == ERR_MEM) { + txlen /= 2; + } + } while ((err == ERR_MEM) && (txlen >= (TCP_MSS/2))); + + if (err == ERR_OK) { + conn->bytes_transferred += txlen; + } else { + send_more = 0; + } + } while(send_more); + + tcp_output(conn->conn_pcb); + return ERR_OK; +} + +/** TCP sent callback, try to send more data */ +static err_t +lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; + /* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */ + LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb); + LWIP_UNUSED_ARG(tpcb); + LWIP_UNUSED_ARG(len); + + conn->poll_count = 0; + + return lwiperf_tcp_client_send_more(conn); +} + +/** TCP connected callback (active connection), send data now */ +static err_t +lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; + LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb); + LWIP_UNUSED_ARG(tpcb); + if (err != ERR_OK) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); + return ERR_OK; + } + conn->poll_count = 0; + conn->time_started = sys_now(); + return lwiperf_tcp_client_send_more(conn); +} + +/** Start TCP connection back to the client (either parallel or after the + * receive test has finished. + */ +static err_t +lwiperf_tx_start(lwiperf_state_tcp_t* conn) +{ + err_t err; + lwiperf_state_tcp_t* client_conn; + struct tcp_pcb* newpcb; + ip_addr_t remote_addr; + u16_t remote_port; + + client_conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); + if (client_conn == NULL) { + return ERR_MEM; + } + newpcb = tcp_new(); + if (newpcb == NULL) { + LWIPERF_FREE(lwiperf_state_tcp_t, client_conn); + return ERR_MEM; + } + + MEMCPY(client_conn, conn, sizeof(lwiperf_state_tcp_t)); + client_conn->base.server = 0; + client_conn->server_pcb = NULL; + client_conn->conn_pcb = newpcb; + client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */ + client_conn->poll_count = 0; + client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */ + client_conn->bytes_transferred = 0; + client_conn->settings.flags = 0; /* prevent the remote side starting back as client again */ + + tcp_arg(newpcb, client_conn); + tcp_sent(newpcb, lwiperf_tcp_client_sent); + tcp_poll(newpcb, lwiperf_tcp_poll, 2U); + tcp_err(newpcb, lwiperf_tcp_err); + + ip_addr_copy(remote_addr, conn->conn_pcb->remote_ip); + remote_port = (u16_t)lwip_htonl(client_conn->settings.remote_port); + + err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected); + if (err != ERR_OK) { + lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL); + return err; + } + lwiperf_list_add(&client_conn->base); + return ERR_OK; +} + +/** Receive data on an iperf tcp session */ +static err_t +lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) +{ + u8_t tmp; + u16_t tot_len; + u32_t packet_idx; + struct pbuf* q; + lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; + + LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb); + LWIP_UNUSED_ARG(tpcb); + + if (err != ERR_OK) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); + return ERR_OK; + } + if (p == NULL) { + /* connection closed -> test done */ + if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) == + PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) { + /* client requested transmission after end of test */ + lwiperf_tx_start(conn); + } + lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER); + return ERR_OK; + } + tot_len = p->tot_len; + + conn->poll_count = 0; + + if ((!conn->have_settings_buf) || ((conn->bytes_transferred -24) % (1024*128) == 0)) { + /* wait for 24-byte header */ + if (p->tot_len < sizeof(lwiperf_settings_t)) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); + pbuf_free(p); + return ERR_VAL; + } + if (!conn->have_settings_buf) { + if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL); + pbuf_free(p); + return ERR_VAL; + } + conn->have_settings_buf = 1; + if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) == + PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) { + /* client requested parallel transmission test */ + err_t err2 = lwiperf_tx_start(conn); + if (err2 != ERR_OK) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR); + pbuf_free(p); + return err2; + } + } + } else { + if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); + pbuf_free(p); + return ERR_VAL; + } + } + conn->bytes_transferred += sizeof(lwiperf_settings_t); + if (conn->bytes_transferred <= 24) { + conn->time_started = sys_now(); + tcp_recved(tpcb, p->tot_len); + pbuf_free(p); + return ERR_OK; + } + conn->next_num = 4; /* 24 bytes received... */ + tmp = pbuf_header(p, -24); + LWIP_ASSERT("pbuf_header failed", tmp == 0); + } + + packet_idx = 0; + for (q = p; q != NULL; q = q->next) { +#if LWIPERF_CHECK_RX_DATA + const u8_t* payload = (const u8_t*)q->payload; + u16_t i; + for (i = 0; i < q->len; i++) { + u8_t val = payload[i]; + u8_t num = val - '0'; + if (num == conn->next_num) { + conn->next_num++; + if (conn->next_num == 10) { + conn->next_num = 0; + } + } else { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); + pbuf_free(p); + return ERR_VAL; + } + } +#endif + packet_idx += q->len; + } + LWIP_ASSERT("count mismatch", packet_idx == p->tot_len); + conn->bytes_transferred += packet_idx; + tcp_recved(tpcb, tot_len); + pbuf_free(p); + return ERR_OK; +} + +/** Error callback, iperf tcp session aborted */ +static void +lwiperf_tcp_err(void *arg, err_t err) +{ + lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; + LWIP_UNUSED_ARG(err); + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); +} + +/** TCP poll callback, try to send more data */ +static err_t +lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb) +{ + lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; + LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb); + LWIP_UNUSED_ARG(tpcb); + if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) { + lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL); + return ERR_OK; /* lwiperf_tcp_close frees conn */ + } + + if (!conn->base.server) { + lwiperf_tcp_client_send_more(conn); + } + + return ERR_OK; +} + +/** This is called when a new client connects for an iperf tcp session */ +static err_t +lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + lwiperf_state_tcp_t *s, *conn; + if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) { + return ERR_VAL; + } + + s = (lwiperf_state_tcp_t*)arg; + conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); + if (conn == NULL) { + return ERR_MEM; + } + memset(conn, 0, sizeof(lwiperf_state_tcp_t)); + conn->base.tcp = 1; + conn->base.server = 1; + conn->base.related_server_state = &s->base; + conn->server_pcb = s->server_pcb; + conn->conn_pcb = newpcb; + conn->time_started = sys_now(); + conn->report_fn = s->report_fn; + conn->report_arg = s->report_arg; + + /* setup the tcp rx connection */ + tcp_arg(newpcb, conn); + tcp_recv(newpcb, lwiperf_tcp_recv); + tcp_poll(newpcb, lwiperf_tcp_poll, 2U); + tcp_err(conn->conn_pcb, lwiperf_tcp_err); + + lwiperf_list_add(&conn->base); + return ERR_OK; +} + +/** + * @ingroup iperf + * Start a TCP iperf server on the default TCP port (5001) and listen for + * incoming connections from iperf clients. + * + * @returns a connection handle that can be used to abort the server + * by calling @ref lwiperf_abort() + */ +void* +lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg) +{ + return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT, + report_fn, report_arg); +} + +/** + * @ingroup iperf + * Start a TCP iperf server on a specific IP address and port and listen for + * incoming connections from iperf clients. + * + * @returns a connection handle that can be used to abort the server + * by calling @ref lwiperf_abort() + */ +void* +lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port, + lwiperf_report_fn report_fn, void* report_arg) +{ + err_t err; + struct tcp_pcb* pcb; + lwiperf_state_tcp_t* s; + + if (local_addr == NULL) { + return NULL; + } + + s = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); + if (s == NULL) { + return NULL; + } + memset(s, 0, sizeof(lwiperf_state_tcp_t)); + s->base.tcp = 1; + s->base.server = 1; + s->report_fn = report_fn; + s->report_arg = report_arg; + + pcb = tcp_new(); + if (pcb != NULL) { + err = tcp_bind(pcb, local_addr, local_port); + if (err == ERR_OK) { + s->server_pcb = tcp_listen_with_backlog(pcb, 1); + } + } + if (s->server_pcb == NULL) { + if (pcb != NULL) { + tcp_close(pcb); + } + LWIPERF_FREE(lwiperf_state_tcp_t, s); + return NULL; + } + pcb = NULL; + + tcp_arg(s->server_pcb, s); + tcp_accept(s->server_pcb, lwiperf_tcp_accept); + + lwiperf_list_add(&s->base); + return s; +} + +/** + * @ingroup iperf + * Abort an iperf session (handle returned by lwiperf_start_tcp_server*()) + */ +void +lwiperf_abort(void* lwiperf_session) +{ + lwiperf_state_base_t* i, *dealloc, *last = NULL; + + for (i = lwiperf_all_connections; i != NULL; ) { + if ((i == lwiperf_session) || (i->related_server_state == lwiperf_session)) { + dealloc = i; + i = i->next; + if (last != NULL) { + last->next = i; + } + LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */ + } else { + last = i; + i = i->next; + } + } +} + +#endif /* LWIP_IPV4 && LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mdns/mdns.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mdns/mdns.c new file mode 100644 index 0000000..fc6b176 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mdns/mdns.c @@ -0,0 +1,2197 @@ +/** + * @file + * MDNS responder implementation + * + * @defgroup mdns MDNS + * @ingroup apps + * + * RFC 6762 - Multicast DNS\n + * RFC 6763 - DNS-Based Service Discovery\n + * + * @verbinclude mdns.txt + * + * Things left to implement: + * ------------------------- + * + * - Probing/conflict resolution + * - Sending goodbye messages (zero ttl) - shutdown, DHCP lease about to expire, DHCP turned off... + * - Checking that source address of unicast requests are on the same network + * - Limiting multicast responses to 1 per second per resource record + * - Fragmenting replies if required + * - Subscribe to netif address/link change events and act on them (currently needs to be done manually) + * - Handling multi-packet known answers + * - Individual known answer detection for all local IPv6 addresses + * - Dynamic size of outgoing packet + */ + +/* + * Copyright (c) 2015 Verisure Innovation AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Ekman + * + */ + +#include "lwip/apps/mdns.h" +#include "lwip/apps/mdns_priv.h" +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/mem.h" +#include "lwip/dns.h" +#include "ipv4/lwip/ip_addr.h" + +#ifndef lwip_itoa +/* This can be #defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform */ +//void lwip_itoa(char* result, size_t bufsize, int number); +#define lwip_itoa itoa +#endif +#ifndef lwip_stricmp +/* This can be #defined to stricmp() or strcasecmp() depending on your platform */ +//int lwip_stricmp(const char* str1, const char* str2); +#define lwip_stricmp _stricmp +#endif +#ifndef lwip_strnstr +/* This can be #defined to strnstr() depending on your platform */ +//char* lwip_strnstr(const char* buffer, const char* token, size_t n); +#define lwip_strnstr strnstr +#endif + +//<----add pvvx---> +#define LWIP_IPV4 1 +#if LWIP_IPV4 && LWIP_IPV6 +/** @ingroup ipaddr */ +#define IP_ANY_TYPE (&ip_addr_any_type) +#else +#define IP_ANY_TYPE IP_ADDR_ANY +#define IP4_ADDR_ANY (&ip_addr_any) +typedef uint32_t ip4_addr_t; +#endif +/* DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_ANY 255 /* any class */ +/* DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_SRV 33 /* service location */ +#define DNS_RRTYPE_ANY 255 /* any type */ + +#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF) + +enum lwip_ip_addr_type { + /** IPv4 */ + IPADDR_TYPE_V4 = 0U, + /** IPv6 */ + IPADDR_TYPE_V6 = 6U, + /** IPv4+IPv6 ("dual-stack") */ + IPADDR_TYPE_ANY = 46U +}; + +/** @ingroup netif_ip4 */ +#define netif_ip4_addr(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr))) +/** @ingroup netif_ip4 */ +#define netif_ip4_netmask(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->netmask))) +/** @ingroup netif_ip4 */ +#define netif_ip4_gw(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->gw))) +/** @ingroup netif_ip4 */ +#define netif_ip_addr4(netif) ((const ip_addr_t*)&((netif)->ip_addr)) +/** @ingroup netif_ip4 */ +#define netif_ip_netmask4(netif) ((const ip_addr_t*)&((netif)->netmask)) +/** @ingroup netif_ip4 */ +#define netif_ip_gw4(netif) ((const ip_addr_t*)&((netif)->gw)) + +#define ip_2_ip4(ipaddr) (&((ipaddr)->addr)) +#define netif_ip4_addr(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr))) + +#define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff)) +#define IPADDR4_INIT(u32val) { u32val } +#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d))) +/* IPv4 group for multicast DNS queries: 224.0.0.251 */ +#ifndef DNS_MQUERY_IPV4_GROUP_INIT +#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251) +#endif +#define ip4_addr_isany_val(addr1) ((addr1) == IPADDR_ANY) +#define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1))) +//<---------------> + +#include + +#if LWIP_MDNS_RESPONDER + +#if (LWIP_IPV4 && !LWIP_IGMP) + #error "If you want to use MDNS with IPv4, you have to define LWIP_IGMP=1 in your lwipopts.h" +#endif +#if (LWIP_IPV6 && !LWIP_IPV6_MLD) +#error "If you want to use MDNS with IPv6, you have to define LWIP_IPV6_MLD=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP) + #error "If you want to use MDNS, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif + +#if LWIP_IPV4 +#include "lwip/igmp.h" +/* IPv4 multicast group 224.0.0.251 */ +static const ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT; +#endif + +#if LWIP_IPV6 +#include "lwip/mld6.h" +/* IPv6 multicast group FF02::FB */ +static const ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT; +#endif + +#define MDNS_PORT 5353 +#define MDNS_TTL 255 + +/* Stored offsets to beginning of domain names + * Used for compression. + */ +#define NUM_DOMAIN_OFFSETS 10 +#define DOMAIN_JUMP_SIZE 2 +#define DOMAIN_JUMP 0xc000 + +static u8_t mdns_netif_client_id; +static struct udp_pcb *mdns_pcb; + +#define NETIF_TO_HOST(netif) (struct mdns_host*)(netif_get_client_data(netif, mdns_netif_client_id)) + +#define TOPDOMAIN_LOCAL "local" + +#define REVERSE_PTR_TOPDOMAIN "arpa" +#define REVERSE_PTR_V4_DOMAIN "in-addr" +#define REVERSE_PTR_V6_DOMAIN "ip6" + +#define SRV_PRIORITY 0 +#define SRV_WEIGHT 0 + +/* Payload size allocated for each outgoing UDP packet */ +#define OUTPACKET_SIZE 500 + +/* Lookup from hostname -> IPv4 */ +#define REPLY_HOST_A 0x01 +/* Lookup from IPv4/v6 -> hostname */ +#define REPLY_HOST_PTR_V4 0x02 +/* Lookup from hostname -> IPv6 */ +#define REPLY_HOST_AAAA 0x04 +/* Lookup from hostname -> IPv6 */ +#define REPLY_HOST_PTR_V6 0x08 + +/* Lookup for service types */ +#define REPLY_SERVICE_TYPE_PTR 0x10 +/* Lookup for instances of service */ +#define REPLY_SERVICE_NAME_PTR 0x20 +/* Lookup for location of service instance */ +#define REPLY_SERVICE_SRV 0x40 +/* Lookup for text info on service instance */ +#define REPLY_SERVICE_TXT 0x80 + +static const char *dnssd_protos[] = { + "_udp", /* DNSSD_PROTO_UDP */ + "_tcp", /* DNSSD_PROTO_TCP */ +}; + +/** Description of a service */ +struct mdns_service { + /** TXT record to answer with */ + struct mdns_domain txtdata; + /** Name of service, like 'myweb' */ + char name[MDNS_LABEL_MAXLEN + 1]; + /** Type of service, like '_http' */ + char service[MDNS_LABEL_MAXLEN + 1]; + /** Callback function and userdata + * to update txtdata buffer */ + service_get_txt_fn_t txt_fn; + void *txt_userdata; + /** TTL in seconds of SRV/TXT replies */ + u32_t dns_ttl; + /** Protocol, TCP or UDP */ + u16_t proto; + /** Port of the service */ + u16_t port; +}; + +/** Description of a host/netif */ +struct mdns_host { + /** Hostname */ + char name[MDNS_LABEL_MAXLEN + 1]; + /** Pointer to services */ + struct mdns_service *services[MDNS_MAX_SERVICES]; + /** TTL in seconds of A/AAAA/PTR replies */ + u32_t dns_ttl; +}; + +/** Information about received packet */ +struct mdns_packet { + /** Sender IP/port */ + ip_addr_t source_addr; + u16_t source_port; + /** If packet was received unicast */ + u16_t recv_unicast; + /** Netif that received the packet */ + struct netif *netif; + /** Packet data */ + struct pbuf *pbuf; + /** Current parsing offset in packet */ + u16_t parse_offset; + /** Identifier. Used in legacy queries */ + u16_t tx_id; + /** Number of questions in packet, + * read from packet header */ + u16_t questions; + /** Number of unparsed questions */ + u16_t questions_left; + /** Number of answers in packet, + * (sum of normal, authorative and additional answers) + * read from packet header */ + u16_t answers; + /** Number of unparsed answers */ + u16_t answers_left; +}; + +/** Information about outgoing packet */ +struct mdns_outpacket { + /** Netif to send the packet on */ + struct netif *netif; + /** Packet data */ + struct pbuf *pbuf; + /** Current write offset in packet */ + u16_t write_offset; + /** Identifier. Used in legacy queries */ + u16_t tx_id; + /** Destination IP/port if sent unicast */ + ip_addr_t dest_addr; + u16_t dest_port; + /** Number of questions written */ + u16_t questions; + /** Number of normal answers written */ + u16_t answers; + /** Number of additional answers written */ + u16_t additional; + /** Offsets for written domain names in packet. + * Used for compression */ + u16_t domain_offsets[NUM_DOMAIN_OFFSETS]; + /** If all answers in packet should set cache_flush bit */ + u8_t cache_flush; + /** If reply should be sent unicast */ + u8_t unicast_reply; + /** If legacy query. (tx_id needed, and write + * question again in reply before answer) */ + u8_t legacy_query; + /* Reply bitmask for host information */ + u8_t host_replies; + /* Bitmask for which reverse IPv6 hosts to answer */ + u8_t host_reverse_v6_replies; + /* Reply bitmask per service */ + u8_t serv_replies[MDNS_MAX_SERVICES]; +}; + +/** Domain, type and class. + * Shared between questions and answers */ +struct mdns_rr_info { + struct mdns_domain domain; + u16_t type; + u16_t klass; +}; + +struct mdns_question { + struct mdns_rr_info info; + /** unicast reply requested */ + u16_t unicast; +}; + +struct mdns_answer { + struct mdns_rr_info info; + /** cache flush command bit */ + u16_t cache_flush; + /* Validity time in seconds */ + u32_t ttl; + /** Length of variable answer */ + u16_t rd_length; + /** Offset of start of variable answer in packet */ + u16_t rd_offset; +}; + +#ifndef lwip_strnicmp +/** + * @ingroup sys_nonstandard + * lwIP default implementation for strnicmp() non-standard function. + * This can be \#defined to strnicmp() depending on your platform port. + */ +int +lwip_strnicmp(const char* str1, const char* str2, size_t len) +{ + char c1, c2; + + do { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) { + char c1_upc = c1 | 0x20; + if ((c1_upc >= 'a') && (c1_upc <= 'z')) { + /* characters are not equal an one is in the alphabet range: + downcase both chars and check again */ + char c2_upc = c2 | 0x20; + if (c1_upc != c2_upc) { + /* still not equal */ + /* don't care for < or > */ + return 1; + } + } else { + /* characters are not equal but none is in the alphabet range */ + return 1; + } + } + } while (len-- && c1 != 0); + return 0; +} +#endif + +/* Actual implementation of pbuf_skip() but returning const pointer... */ +static const struct pbuf* +pbuf_skip_const(const struct pbuf* in, u16_t in_offset, u16_t* out_offset) +{ + u16_t offset_left = in_offset; + const struct pbuf* q = in; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= offset_left)) { + offset_left -= q->len; + q = q->next; + } + if (out_offset != NULL) { + *out_offset = offset_left; + } + return q; +} + +/** + * @ingroup pbuf + * Skip a number of bytes at the start of a pbuf + * + * @param in input pbuf + * @param in_offset offset to skip + * @param out_offset resulting offset in the returned pbuf + * @return the pbuf in the queue where the offset is + */ +#ifndef LWIP_CONST_CAST +#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val)) +#endif + +struct pbuf* pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset) +{ + const struct pbuf* out = pbuf_skip_const(in, in_offset, out_offset); + return LWIP_CONST_CAST(struct pbuf*, out); +} + +err_t +pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset) +{ + u16_t target_offset; + struct pbuf* q = pbuf_skip(buf, offset, &target_offset); + + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->tot_len >= target_offset + len)) { + u16_t remaining_len = len; + const u8_t* src_ptr = (const u8_t*)dataptr; + /* copy the part that goes into the first pbuf */ + u16_t first_copy_len = LWIP_MIN(q->len - target_offset, len); + MEMCPY(((u8_t*)q->payload) + target_offset, dataptr, first_copy_len); + remaining_len -= first_copy_len; + src_ptr += first_copy_len; + if (remaining_len > 0) { + return pbuf_take(q->next, src_ptr, remaining_len); + } + return ERR_OK; + } + return ERR_MEM; +} + + +/** + * Add a label part to a domain + * @param domain The domain to add a label to + * @param label The label to add, like <hostname>, 'local', 'com' or '' + * @param len The length of the label + * @return ERR_OK on success, an err_t otherwise if label too long + */ +err_t +mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len) +{ + if (len > MDNS_LABEL_MAXLEN) { + return ERR_VAL; + } + if (len > 0 && (1 + len + domain->length >= MDNS_DOMAIN_MAXLEN)) { + return ERR_VAL; + } + /* Allow only zero marker on last byte */ + if (len == 0 && (1 + domain->length > MDNS_DOMAIN_MAXLEN)) { + return ERR_VAL; + } + domain->name[domain->length] = len; + domain->length++; + if (len) { + MEMCPY(&domain->name[domain->length], label, len); + domain->length += len; + } + return ERR_OK; +} + +/** + * Internal readname function with max 6 levels of recursion following jumps + * while decompressing name + */ +static u16_t +mdns_readname_loop(struct pbuf *p, u16_t offset, struct mdns_domain *domain, unsigned depth) +{ + u8_t c; + + do { + if (depth > 5) { + /* Too many jumps */ + return MDNS_READNAME_ERROR; + } + + c = pbuf_get_at(p, offset); + offset++; + + /* is this a compressed label? */ + if((c & 0xc0) == 0xc0) { + u16_t jumpaddr; + if (offset >= p->tot_len) { + /* Make sure both jump bytes fit in the packet */ + return MDNS_READNAME_ERROR; + } + jumpaddr = (((c & 0x3f) << 8) | (pbuf_get_at(p, offset) & 0xff)); + offset++; + if (jumpaddr >= SIZEOF_DNS_HDR && jumpaddr < p->tot_len) { + u16_t res; + /* Recursive call, maximum depth will be checked */ + res = mdns_readname_loop(p, jumpaddr, domain, depth + 1); + /* Dont return offset since new bytes were not read (jumped to somewhere in packet) */ + if (res == MDNS_READNAME_ERROR) { + return res; + } + } else { + return MDNS_READNAME_ERROR; + } + break; + } + + /* normal label */ + if (c <= MDNS_LABEL_MAXLEN) { + u8_t label[MDNS_LABEL_MAXLEN]; + err_t res; + + if (c + domain->length >= MDNS_DOMAIN_MAXLEN) { + return MDNS_READNAME_ERROR; + } + if (c != 0) { + if (pbuf_copy_partial(p, label, c, offset) != c) { + return MDNS_READNAME_ERROR; + } + offset += c; + } + res = mdns_domain_add_label(domain, (char *) label, c); + if (res != ERR_OK) { + return MDNS_READNAME_ERROR; + } + } else { + /* bad length byte */ + return MDNS_READNAME_ERROR; + } + } while (c != 0); + + return offset; +} + +/** + * Read possibly compressed domain name from packet buffer + * @param p The packet + * @param offset start position of domain name in packet + * @param domain The domain name destination + * @return The new offset after the domain, or MDNS_READNAME_ERROR + * if reading failed + */ +u16_t +mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain) +{ + memset(domain, 0, sizeof(struct mdns_domain)); + return mdns_readname_loop(p, offset, domain, 0); +} + +/** + * Print domain name to debug output + * @param domain The domain name + */ +static void +mdns_domain_debug_print(struct mdns_domain *domain) +{ + u8_t *src = domain->name; + u8_t i; + + while (*src) { + u8_t label_len = *src; + src++; + for (i = 0; i < label_len; i++) { + LWIP_DEBUGF(MDNS_DEBUG, ("%c", src[i])); + } + src += label_len; + LWIP_DEBUGF(MDNS_DEBUG, (".")); + } +} + +/** + * Return 1 if contents of domains match (case-insensitive) + * @param a Domain name to compare 1 + * @param b Domain name to compare 2 + * @return 1 if domains are equal ignoring case, 0 otherwise + */ +int +mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b) +{ + u8_t *ptra, *ptrb; + u8_t len; + int res; + + if (a->length != b->length) { + return 0; + } + + ptra = a->name; + ptrb = b->name; + while (*ptra && *ptrb && ptra < &a->name[a->length]) { + if (*ptra != *ptrb) { + return 0; + } + len = *ptra; + ptra++; + ptrb++; + res = lwip_strnicmp((char *) ptra, (char *) ptrb, len); + if (res != 0) { + return 0; + } + ptra += len; + ptrb += len; + } + if (*ptra != *ptrb && ptra < &a->name[a->length]) { + return 0; + } + return 1; +} + +/** + * Call user supplied function to setup TXT data + * @param service The service to build TXT record for + */ +static void +mdns_prepare_txtdata(struct mdns_service *service) +{ + memset(&service->txtdata, 0, sizeof(struct mdns_domain)); + if (service->txt_fn) { + service->txt_fn(service, service->txt_userdata); + } +} + +#if LWIP_IPV4 +/** + * Build domain for reverse lookup of IPv4 address + * like 12.0.168.192.in-addr.arpa. for 192.168.0.12 + * @param domain Where to write the domain name + * @param addr Pointer to an IPv4 address to encode + * @return ERR_OK if domain was written, an err_t otherwise + */ +static err_t +mdns_build_reverse_v4_domain(struct mdns_domain *domain, const ip4_addr_t *addr) +{ + int i; + err_t res; + const u8_t *ptr; + if (!domain || !addr) { + return ERR_ARG; + } + memset(domain, 0, sizeof(struct mdns_domain)); + ptr = (const u8_t *) addr; + for (i = sizeof(ip4_addr_t) - 1; i >= 0; i--) { + char buf[4]; + u8_t val = ptr[i]; + + lwip_itoa(buf, sizeof(buf), val); + res = mdns_domain_add_label(domain, buf, (u8_t)strlen(buf)); + LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); + } + res = mdns_domain_add_label(domain, REVERSE_PTR_V4_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V4_DOMAIN)-1)); + LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN)-1)); + LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, NULL, 0); + LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); + + return ERR_OK; +} +#endif + +#if LWIP_IPV6 +/** + * Build domain for reverse lookup of IP address + * like b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. for 2001:db8::567:89ab + * @param domain Where to write the domain name + * @param addr Pointer to an IPv6 address to encode + * @return ERR_OK if domain was written, an err_t otherwise + */ +static err_t +mdns_build_reverse_v6_domain(struct mdns_domain *domain, const ip6_addr_t *addr) +{ + int i; + err_t res; + const u8_t *ptr; + if (!domain || !addr) { + return ERR_ARG; + } + memset(domain, 0, sizeof(struct mdns_domain)); + ptr = (const u8_t *) addr; + for (i = sizeof(ip6_addr_t) - 1; i >= 0; i--) { + char buf; + u8_t byte = ptr[i]; + int j; + for (j = 0; j < 2; j++) { + if ((byte & 0x0F) < 0xA) { + buf = '0' + (byte & 0x0F); + } else { + buf = 'a' + (byte & 0x0F) - 0xA; + } + res = mdns_domain_add_label(domain, &buf, sizeof(buf)); + LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); + byte >>= 4; + } + } + res = mdns_domain_add_label(domain, REVERSE_PTR_V6_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V6_DOMAIN)-1)); + LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN)-1)); + LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, NULL, 0); + LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); + + return ERR_OK; +} +#endif + +/* Add .local. to domain */ +static err_t +mdns_add_dotlocal(struct mdns_domain *domain) +{ + err_t res = mdns_domain_add_label(domain, TOPDOMAIN_LOCAL, (u8_t)(sizeof(TOPDOMAIN_LOCAL)-1)); + LWIP_ERROR("mdns_add_dotlocal: Failed to add label", (res == ERR_OK), return res); + return mdns_domain_add_label(domain, NULL, 0); +} + +/** + * Build the .local. domain name + * @param domain Where to write the domain name + * @param mdns TMDNS netif descriptor. + * @return ERR_OK if domain .local. was written, an err_t otherwise + */ +static err_t +mdns_build_host_domain(struct mdns_domain *domain, struct mdns_host *mdns) +{ + err_t res; + memset(domain, 0, sizeof(struct mdns_domain)); + LWIP_ERROR("mdns_build_host_domain: mdns != NULL", (mdns != NULL), return ERR_VAL); + res = mdns_domain_add_label(domain, mdns->name, (u8_t)strlen(mdns->name)); + LWIP_ERROR("mdns_build_host_domain: Failed to add label", (res == ERR_OK), return res); + return mdns_add_dotlocal(domain); +} + +/** + * Build the lookup-all-services special DNS-SD domain name + * @param domain Where to write the domain name + * @return ERR_OK if domain _services._dns-sd._udp.local. was written, an err_t otherwise + */ +static err_t +mdns_build_dnssd_domain(struct mdns_domain *domain) +{ + err_t res; + memset(domain, 0, sizeof(struct mdns_domain)); + res = mdns_domain_add_label(domain, "_services", (u8_t)(sizeof("_services")-1)); + LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, "_dns-sd", (u8_t)(sizeof("_dns-sd")-1)); + LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, dnssd_protos[DNSSD_PROTO_UDP], (u8_t)strlen(dnssd_protos[DNSSD_PROTO_UDP])); + LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); + return mdns_add_dotlocal(domain); +} + +/** + * Build domain name for a service + * @param domain Where to write the domain name + * @param service The service struct, containing service name, type and protocol + * @param include_name Whether to include the service name in the domain + * @return ERR_OK if domain was written. If service name is included, + * ...local. will be written, otherwise ..local. + * An err_t is returned on error. + */ +static err_t +mdns_build_service_domain(struct mdns_domain *domain, struct mdns_service *service, int include_name) +{ + err_t res; + memset(domain, 0, sizeof(struct mdns_domain)); + if (include_name) { + res = mdns_domain_add_label(domain, service->name, (u8_t)strlen(service->name)); + LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); + } + res = mdns_domain_add_label(domain, service->service, (u8_t)strlen(service->service)); + LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); + res = mdns_domain_add_label(domain, dnssd_protos[service->proto], (u8_t)strlen(dnssd_protos[service->proto])); + LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); + return mdns_add_dotlocal(domain); +} + +/** + * Check which replies we should send for a host/netif based on question + * @param netif The network interface that received the question + * @param rr Domain/type/class from a question + * @param reverse_v6_reply Bitmask of which IPv6 addresses to send reverse PTRs for + * if reply bit has REPLY_HOST_PTR_V6 set + * @return Bitmask of which replies to send + */ +static int +check_host(struct netif *netif, struct mdns_rr_info *rr, u8_t *reverse_v6_reply) +{ + err_t res; + int replies = 0; + struct mdns_domain mydomain; + + LWIP_UNUSED_ARG(reverse_v6_reply); /* if ipv6 is disabled */ + + if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { + /* Invalid class */ + return replies; + } + + /* Handle PTR for our addresses */ + if (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY) { +#if LWIP_IPV6 + int i; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { + res = mdns_build_reverse_v6_domain(&mydomain, netif_ip6_addr(netif, i)); + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { + replies |= REPLY_HOST_PTR_V6; + /* Mark which addresses where requested */ + if (reverse_v6_reply) { + *reverse_v6_reply |= (1 << i); + } + } + } + } +#endif +#if LWIP_IPV4 + if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { + res = mdns_build_reverse_v4_domain(&mydomain, netif_ip4_addr(netif)); + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { + replies |= REPLY_HOST_PTR_V4; + } + } +#endif + } + res = mdns_build_host_domain(&mydomain, NETIF_TO_HOST(netif)); + /* Handle requests for our hostname */ + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { + /* TODO return NSEC if unsupported protocol requested */ +#if LWIP_IPV4 + if (!ip4_addr_isany_val(*netif_ip4_addr(netif)) + && (rr->type == DNS_RRTYPE_A || rr->type == DNS_RRTYPE_ANY)) { + replies |= REPLY_HOST_A; + } +#endif +#if LWIP_IPV6 + if (rr->type == DNS_RRTYPE_AAAA || rr->type == DNS_RRTYPE_ANY) { + replies |= REPLY_HOST_AAAA; + } +#endif + } + + return replies; +} + +/** + * Check which replies we should send for a service based on question + * @param service A registered MDNS service + * @param rr Domain/type/class from a question + * @return Bitmask of which replies to send + */ +static int +check_service(struct mdns_service *service, struct mdns_rr_info *rr) +{ + err_t res; + int replies = 0; + struct mdns_domain mydomain; + + if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { + /* Invalid class */ + return 0; + } + + res = mdns_build_dnssd_domain(&mydomain); + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && + (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { + /* Request for all service types */ + replies |= REPLY_SERVICE_TYPE_PTR; + } + + res = mdns_build_service_domain(&mydomain, service, 0); + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && + (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { + /* Request for the instance of my service */ + replies |= REPLY_SERVICE_NAME_PTR; + } + + res = mdns_build_service_domain(&mydomain, service, 1); + if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { + /* Request for info about my service */ + if (rr->type == DNS_RRTYPE_SRV || rr->type == DNS_RRTYPE_ANY) { + replies |= REPLY_SERVICE_SRV; + } + if (rr->type == DNS_RRTYPE_TXT || rr->type == DNS_RRTYPE_ANY) { + replies |= REPLY_SERVICE_TXT; + } + } + + return replies; +} + +/** + * Return bytes needed to write before jump for best result of compressing supplied domain + * against domain in outpacket starting at specified offset. + * If a match is found, offset is updated to where to jump to + * @param pbuf Pointer to pbuf with the partially constructed DNS packet + * @param offset Start position of a domain written earlier. If this location is suitable + * for compression, the pointer is updated to where in the domain to jump to. + * @param domain The domain to write + * @return Number of bytes to write of the new domain before writing a jump to the offset. + * If compression can not be done against this previous domain name, the full new + * domain length is returned. + */ +u16_t +mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain) +{ + struct mdns_domain target; + u16_t target_end; + u8_t target_len; + u8_t writelen = 0; + u8_t *ptr; + if (pbuf == NULL) { + return domain->length; + } + target_end = mdns_readname(pbuf, *offset, &target); + if (target_end == MDNS_READNAME_ERROR) { + return domain->length; + } + target_len = (u8_t)(target_end - *offset); + ptr = domain->name; + while (writelen < domain->length) { + u8_t domainlen = (u8_t)(domain->length - writelen); + u8_t labellen; + if (domainlen <= target.length && domainlen > DOMAIN_JUMP_SIZE) { + /* Compare domains if target is long enough, and we have enough left of the domain */ + u8_t targetpos = (u8_t)(target.length - domainlen); + if ((targetpos + DOMAIN_JUMP_SIZE) >= target_len) { + /* We are checking at or beyond a jump in the original, stop looking */ + break; + } + if (target.length >= domainlen && + memcmp(&domain->name[writelen], &target.name[targetpos], domainlen) == 0) { + *offset += targetpos; + return writelen; + } + } + /* Skip to next label in domain */ + labellen = *ptr; + writelen += 1 + labellen; + ptr += 1 + labellen; + } + /* Nothing found */ + return domain->length; +} + +/** + * Write domain to outpacket. Compression will be attempted, + * unless domain->skip_compression is set. + * @param outpkt The outpacket to write to + * @param domain The domain name to write + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain) +{ + int i; + err_t res; + u16_t writelen = domain->length; + u16_t jump_offset = 0; + u16_t jump; + + if (!domain->skip_compression) { + for (i = 0; i < NUM_DOMAIN_OFFSETS; ++i) { + u16_t offset = outpkt->domain_offsets[i]; + if (offset) { + u16_t len = mdns_compress_domain(outpkt->pbuf, &offset, domain); + if (len < writelen) { + writelen = len; + jump_offset = offset; + } + } + } + } + + if (writelen) { + /* Write uncompressed part of name */ + res = pbuf_take_at(outpkt->pbuf, domain->name, writelen, outpkt->write_offset); + if (res != ERR_OK) { + return res; + } + + /* Store offset of this new domain */ + for (i = 0; i < NUM_DOMAIN_OFFSETS; ++i) { + if (outpkt->domain_offsets[i] == 0) { + outpkt->domain_offsets[i] = outpkt->write_offset; + break; + } + } + + outpkt->write_offset += writelen; + } + if (jump_offset) { + /* Write jump */ + jump = lwip_htons(DOMAIN_JUMP | jump_offset); + res = pbuf_take_at(outpkt->pbuf, &jump, DOMAIN_JUMP_SIZE, outpkt->write_offset); + if (res != ERR_OK) { + return res; + } + outpkt->write_offset += DOMAIN_JUMP_SIZE; + } + return ERR_OK; +} + +/** + * Write a question to an outpacket + * A question contains domain, type and class. Since an answer also starts with these fields this function is also + * called from mdns_add_answer(). + * @param outpkt The outpacket to write to + * @param domain The domain name the answer is for + * @param type The DNS type of the answer (like 'AAAA', 'SRV') + * @param klass The DNS type of the answer (like 'IN') + * @param unicast If highest bit in class should be set, to instruct the responder to + * reply with a unicast packet + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_add_question(struct mdns_outpacket *outpkt, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t unicast) +{ + u16_t question_len; + u16_t field16; + err_t res; + + if (!outpkt->pbuf) { + /* If no pbuf is active, allocate one */ + outpkt->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM); + if (!outpkt->pbuf) { + return ERR_MEM; + } + outpkt->write_offset = SIZEOF_DNS_HDR; + } + + /* Worst case calculation. Domain string might be compressed */ + question_len = domain->length + sizeof(type) + sizeof(klass); + if (outpkt->write_offset + question_len > outpkt->pbuf->tot_len) { + /* No space */ + return ERR_MEM; + } + + /* Write name */ + res = mdns_write_domain(outpkt, domain); + if (res != ERR_OK) { + return res; + } + + /* Write type */ + field16 = lwip_htons(type); + res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset); + if (res != ERR_OK) { + return res; + } + outpkt->write_offset += sizeof(field16); + + /* Write class */ + if (unicast) { + klass |= 0x8000; + } + field16 = lwip_htons(klass); + res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset); + if (res != ERR_OK) { + return res; + } + outpkt->write_offset += sizeof(field16); + + return ERR_OK; +} + +/** + * Write answer to reply packet. + * buf or answer_domain can be null. The rd_length written will be buf_length + + * size of (compressed) domain. Most uses will need either buf or answer_domain, + * special case is SRV that starts with 3 u16 and then a domain name. + * @param reply The outpacket to write to + * @param domain The domain name the answer is for + * @param type The DNS type of the answer (like 'AAAA', 'SRV') + * @param klass The DNS type of the answer (like 'IN') + * @param cache_flush If highest bit in class should be set, to instruct receiver that + * this reply replaces any earlier answer for this domain/type/class + * @param ttl Validity time in seconds to send out for IP address data in DNS replies + * @param buf Pointer to buffer of answer data + * @param buf_length Length of variable data + * @param answer_domain A domain to write after any buffer data as answer + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_add_answer(struct mdns_outpacket *reply, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t cache_flush, + u32_t ttl, const u8_t *buf, size_t buf_length, struct mdns_domain *answer_domain) +{ + u16_t answer_len; + u16_t field16; + u16_t rdlen_offset; + u16_t answer_offset; + u32_t field32; + err_t res; + + if (!reply->pbuf) { + /* If no pbuf is active, allocate one */ + reply->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM); + if (!reply->pbuf) { + return ERR_MEM; + } + reply->write_offset = SIZEOF_DNS_HDR; + } + + /* Worst case calculation. Domain strings might be compressed */ + answer_len = domain->length + sizeof(type) + sizeof(klass) + sizeof(ttl) + sizeof(field16)/*rd_length*/; + if (buf) { + answer_len += (u16_t)buf_length; + } + if (answer_domain) { + answer_len += answer_domain->length; + } + if (reply->write_offset + answer_len > reply->pbuf->tot_len) { + /* No space */ + return ERR_MEM; + } + + /* Answer starts with same data as question, then more fields */ + mdns_add_question(reply, domain, type, klass, cache_flush); + + /* Write TTL */ + field32 = lwip_htonl(ttl); + res = pbuf_take_at(reply->pbuf, &field32, sizeof(field32), reply->write_offset); + if (res != ERR_OK) { + return res; + } + reply->write_offset += sizeof(field32); + + /* Store offsets and skip forward to the data */ + rdlen_offset = reply->write_offset; + reply->write_offset += sizeof(field16); + answer_offset = reply->write_offset; + + if (buf) { + /* Write static data */ + res = pbuf_take_at(reply->pbuf, buf, (u16_t)buf_length, reply->write_offset); + if (res != ERR_OK) { + return res; + } + reply->write_offset += (u16_t)buf_length; + } + + if (answer_domain) { + /* Write name answer (compressed if possible) */ + res = mdns_write_domain(reply, answer_domain); + if (res != ERR_OK) { + return res; + } + } + + /* Write rd_length after when we know the answer size */ + field16 = lwip_htons(reply->write_offset - answer_offset); + res = pbuf_take_at(reply->pbuf, &field16, sizeof(field16), rdlen_offset); + + return res; +} + +/** + * Helper function for mdns_read_question/mdns_read_answer + * Reads a domain, type and class from the packet + * @param pkt The MDNS packet to read from. The parse_offset field will be + * incremented to point to the next unparsed byte. + * @param info The struct to fill with domain, type and class + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_read_rr_info(struct mdns_packet *pkt, struct mdns_rr_info *info) +{ + u16_t field16, copied; + pkt->parse_offset = mdns_readname(pkt->pbuf, pkt->parse_offset, &info->domain); + if (pkt->parse_offset == MDNS_READNAME_ERROR) { + return ERR_VAL; + } + + copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); + if (copied != sizeof(field16)) { + return ERR_VAL; + } + pkt->parse_offset += copied; + info->type = lwip_ntohs(field16); + + copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); + if (copied != sizeof(field16)) { + return ERR_VAL; + } + pkt->parse_offset += copied; + info->klass = lwip_ntohs(field16); + + return ERR_OK; +} + +/** + * Read a question from the packet. + * All questions have to be read before the answers. + * @param pkt The MDNS packet to read from. The questions_left field will be decremented + * and the parse_offset will be updated. + * @param question The struct to fill with question data + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_read_question(struct mdns_packet *pkt, struct mdns_question *question) +{ + /* Safety check */ + if (pkt->pbuf->tot_len < pkt->parse_offset) { + return ERR_VAL; + } + + if (pkt->questions_left) { + err_t res; + pkt->questions_left--; + + memset(question, 0, sizeof(struct mdns_question)); + res = mdns_read_rr_info(pkt, &question->info); + if (res != ERR_OK) { + return res; + } + + /* Extract unicast flag from class field */ + question->unicast = question->info.klass & 0x8000; + question->info.klass &= 0x7FFF; + + return ERR_OK; + } + return ERR_VAL; +} + +/** + * Read an answer from the packet + * The variable length reply is not copied, its pbuf offset and length is stored instead. + * @param pkt The MDNS packet to read. The answers_left field will be decremented and + * the parse_offset will be updated. + * @param answer The struct to fill with answer data + * @return ERR_OK on success, an err_t otherwise + */ +static err_t +mdns_read_answer(struct mdns_packet *pkt, struct mdns_answer *answer) +{ + /* Read questions first */ + if (pkt->questions_left) { + return ERR_VAL; + } + + /* Safety check */ + if (pkt->pbuf->tot_len < pkt->parse_offset) { + return ERR_VAL; + } + + if (pkt->answers_left) { + u16_t copied, field16; + u32_t ttl; + err_t res; + pkt->answers_left--; + + memset(answer, 0, sizeof(struct mdns_answer)); + res = mdns_read_rr_info(pkt, &answer->info); + if (res != ERR_OK) { + return res; + } + + /* Extract cache_flush flag from class field */ + answer->cache_flush = answer->info.klass & 0x8000; + answer->info.klass &= 0x7FFF; + + copied = pbuf_copy_partial(pkt->pbuf, &ttl, sizeof(ttl), pkt->parse_offset); + if (copied != sizeof(ttl)) { + return ERR_VAL; + } + pkt->parse_offset += copied; + answer->ttl = lwip_ntohl(ttl); + + copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); + if (copied != sizeof(field16)) { + return ERR_VAL; + } + pkt->parse_offset += copied; + answer->rd_length = lwip_ntohs(field16); + + answer->rd_offset = pkt->parse_offset; + pkt->parse_offset += answer->rd_length; + + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_IPV4 +/** Write an IPv4 address (A) RR to outpacket */ +static err_t +mdns_add_a_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif) +{ + struct mdns_domain host; + mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with A record\n")); + return mdns_add_answer(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip4_addr(netif), sizeof(ip4_addr_t), NULL); +} + +/** Write a 4.3.2.1.in-addr.arpa -> hostname.local PTR RR to outpacket */ +static err_t +mdns_add_hostv4_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif) +{ + struct mdns_domain host, revhost; + mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); + mdns_build_reverse_v4_domain(&revhost, netif_ip4_addr(netif)); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v4 PTR record\n")); + return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host); +} +#endif + +#if LWIP_IPV6 +/** Write an IPv6 address (AAAA) RR to outpacket */ +static err_t +mdns_add_aaaa_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex) +{ + struct mdns_domain host; + mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with AAAA record\n")); + return mdns_add_answer(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip6_addr(netif, addrindex), sizeof(ip6_addr_t), NULL); +} + +/** Write a x.y.z.ip6.arpa -> hostname.local PTR RR to outpacket */ +static err_t +mdns_add_hostv6_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex) +{ + struct mdns_domain host, revhost; + mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); + mdns_build_reverse_v6_domain(&revhost, netif_ip6_addr(netif, addrindex)); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v6 PTR record\n")); + return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host); +} +#endif + +/** Write an all-services -> servicetype PTR RR to outpacket */ +static err_t +mdns_add_servicetype_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service) +{ + struct mdns_domain service_type, service_dnssd; + mdns_build_service_domain(&service_type, service, 0); + mdns_build_dnssd_domain(&service_dnssd); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n")); + return mdns_add_answer(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_type); +} + +/** Write a servicetype -> servicename PTR RR to outpacket */ +static err_t +mdns_add_servicename_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service) +{ + struct mdns_domain service_type, service_instance; + mdns_build_service_domain(&service_type, service, 0); + mdns_build_service_domain(&service_instance, service, 1); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service name PTR record\n")); + return mdns_add_answer(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_instance); +} + +/** Write a SRV RR to outpacket */ +static err_t +mdns_add_srv_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_host *mdns, struct mdns_service *service) +{ + struct mdns_domain service_instance, srvhost; + u16_t srvdata[3]; + mdns_build_service_domain(&service_instance, service, 1); + mdns_build_host_domain(&srvhost, mdns); + if (reply->legacy_query) { + /* RFC 6762 section 18.14: + * In legacy unicast responses generated to answer legacy queries, + * name compression MUST NOT be performed on SRV records. + */ + srvhost.skip_compression = 1; + } + srvdata[0] = lwip_htons(SRV_PRIORITY); + srvdata[1] = lwip_htons(SRV_WEIGHT); + srvdata[2] = lwip_htons(service->port); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with SRV record\n")); + return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN, cache_flush, service->dns_ttl, + (const u8_t *) &srvdata, sizeof(srvdata), &srvhost); +} + +/** Write a TXT RR to outpacket */ +static err_t +mdns_add_txt_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_service *service) +{ + struct mdns_domain service_instance; + mdns_build_service_domain(&service_instance, service, 1); + mdns_prepare_txtdata(service); + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n")); + return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN, cache_flush, service->dns_ttl, + (u8_t *) &service->txtdata.name, service->txtdata.length, NULL); +} + +/** + * Setup outpacket as a reply to the incoming packet + */ +static void +mdns_init_outpacket(struct mdns_outpacket *out, struct mdns_packet *in) +{ + memset(out, 0, sizeof(struct mdns_outpacket)); + out->cache_flush = 1; + out->netif = in->netif; + + /* Copy source IP/port to use when responding unicast, or to choose + * which pcb to use for multicast (IPv4/IPv6) + */ + SMEMCPY(&out->dest_addr, &in->source_addr, sizeof(ip_addr_t)); + out->dest_port = in->source_port; + + if (in->source_port != MDNS_PORT) { + out->unicast_reply = 1; + out->cache_flush = 0; + if (in->questions == 1) { + out->legacy_query = 1; + out->tx_id = in->tx_id; + } + } + + if (in->recv_unicast) { + out->unicast_reply = 1; + } +} + +/** + * Send chosen answers as a reply + * + * Add all selected answers (first write will allocate pbuf) + * Add additional answers based on the selected answers + * Send the packet + */ +static void +mdns_send_outpacket(struct mdns_outpacket *outpkt) +{ + struct mdns_service *service; + err_t res; + int i; + struct mdns_host* mdns = NETIF_TO_HOST(outpkt->netif); + + /* Write answers to host questions */ +#if LWIP_IPV4 + if (outpkt->host_replies & REPLY_HOST_A) { + res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + if (outpkt->host_replies & REPLY_HOST_PTR_V4) { + res = mdns_add_hostv4_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } +#endif +#if LWIP_IPV6 + if (outpkt->host_replies & REPLY_HOST_AAAA) { + int addrindex; + for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; ++addrindex) { + if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) { + res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + } + } + if (outpkt->host_replies & REPLY_HOST_PTR_V6) { + u8_t rev_addrs = outpkt->host_reverse_v6_replies; + int addrindex = 0; + while (rev_addrs) { + if (rev_addrs & 1) { + res = mdns_add_hostv6_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + addrindex++; + rev_addrs >>= 1; + } + } +#endif + + /* Write answers to service questions */ + for (i = 0; i < MDNS_MAX_SERVICES; ++i) { + service = mdns->services[i]; + if (!service) { + continue; + } + + if (outpkt->serv_replies[i] & REPLY_SERVICE_TYPE_PTR) { + res = mdns_add_servicetype_ptr_answer(outpkt, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + + if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) { + res = mdns_add_servicename_ptr_answer(outpkt, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + + if (outpkt->serv_replies[i] & REPLY_SERVICE_SRV) { + res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + + if (outpkt->serv_replies[i] & REPLY_SERVICE_TXT) { + res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->answers++; + } + } + + /* All answers written, add additional RRs */ + for (i = 0; i < MDNS_MAX_SERVICES; ++i) { + service = mdns->services[i]; + if (!service) { + continue; + } + + if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) { + /* Our service instance requested, include SRV & TXT + * if they are already not requested. */ + if (!(outpkt->serv_replies[i] & REPLY_SERVICE_SRV)) { + res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->additional++; + } + + if (!(outpkt->serv_replies[i] & REPLY_SERVICE_TXT)) { + res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->additional++; + } + } + + /* If service instance, SRV, record or an IP address is requested, + * supply all addresses for the host + */ + if ((outpkt->serv_replies[i] & (REPLY_SERVICE_NAME_PTR | REPLY_SERVICE_SRV)) || + (outpkt->host_replies & (REPLY_HOST_A | REPLY_HOST_AAAA))) { +#if LWIP_IPV6 + if (!(outpkt->host_replies & REPLY_HOST_AAAA)) { + int addrindex; + for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; ++addrindex) { + if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) { + res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->additional++; + } + } + } +#endif +#if LWIP_IPV4 + if (!(outpkt->host_replies & REPLY_HOST_A)) { + res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif); + if (res != ERR_OK) { + goto cleanup; + } + outpkt->additional++; + } +#endif + } + } + + if (outpkt->pbuf) { + const ip_addr_t *mcast_destaddr; + struct dns_hdr hdr; + + /* Write header */ + memset(&hdr, 0, sizeof(hdr)); + hdr.flags1 = DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE; + hdr.numanswers = lwip_htons(outpkt->answers); + hdr.numextrarr = lwip_htons(outpkt->additional); + if (outpkt->legacy_query) { + hdr.numquestions = lwip_htons(1); + hdr.id = lwip_htons(outpkt->tx_id); + } + pbuf_take(outpkt->pbuf, &hdr, sizeof(hdr)); + + /* Shrink packet */ + pbuf_realloc(outpkt->pbuf, outpkt->write_offset); + + if (IP_IS_V6_VAL(outpkt->dest_addr)) { +#if LWIP_IPV6 + mcast_destaddr = &v6group; +#endif + } else { +#if LWIP_IPV4 + mcast_destaddr = &v4group; +#endif + } + /* Send created packet */ + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Sending packet, len=%d, unicast=%d\n", outpkt->write_offset, outpkt->unicast_reply)); + if (outpkt->unicast_reply) { + udp_sendto_if(mdns_pcb, outpkt->pbuf, &outpkt->dest_addr, outpkt->dest_port, outpkt->netif); + } else { + udp_sendto_if(mdns_pcb, outpkt->pbuf, mcast_destaddr, MDNS_PORT, outpkt->netif); + } + } + +cleanup: + if (outpkt->pbuf) { + pbuf_free(outpkt->pbuf); + outpkt->pbuf = NULL; + } +} + +/** + * Send unsolicited answer containing all our known data + * @param netif The network interface to send on + * @param destination The target address to send to (usually multicast address) + */ +static void +mdns_announce(struct netif *netif, const ip_addr_t *destination) +{ + struct mdns_outpacket announce; + int i; + struct mdns_host* mdns = NETIF_TO_HOST(netif); + + memset(&announce, 0, sizeof(announce)); + announce.netif = netif; + announce.cache_flush = 1; +#if LWIP_IPV4 + if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) + announce.host_replies = REPLY_HOST_A | REPLY_HOST_PTR_V4; +#endif +#if LWIP_IPV6 + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { + announce.host_replies |= REPLY_HOST_AAAA | REPLY_HOST_PTR_V6; + announce.host_reverse_v6_replies |= (1 << i); + } + } +#endif + + for (i = 0; i < MDNS_MAX_SERVICES; i++) { + struct mdns_service *serv = mdns->services[i]; + if (serv) { + announce.serv_replies[i] = REPLY_SERVICE_TYPE_PTR | REPLY_SERVICE_NAME_PTR | + REPLY_SERVICE_SRV | REPLY_SERVICE_TXT; + } + } + + announce.dest_port = MDNS_PORT; + SMEMCPY(&announce.dest_addr, destination, sizeof(announce.dest_addr)); + mdns_send_outpacket(&announce); +} + +/** + * Handle question MDNS packet + * 1. Parse all questions and set bits what answers to send + * 2. Clear pending answers if known answers are supplied + * 3. Put chosen answers in new packet and send as reply + */ +static void +mdns_handle_question(struct mdns_packet *pkt) +{ + struct mdns_service *service; + struct mdns_outpacket reply; + int replies = 0; + int i; + err_t res; + struct mdns_host* mdns = NETIF_TO_HOST(pkt->netif); + + mdns_init_outpacket(&reply, pkt); + + while (pkt->questions_left) { + struct mdns_question q; + + res = mdns_read_question(pkt, &q); + if (res != ERR_OK) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping query packet\n")); + return; + } + + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Query for domain ")); + mdns_domain_debug_print(&q.info.domain); + LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", q.info.type, q.info.klass)); + + if (q.unicast) { + /* Reply unicast if any question is unicast */ + reply.unicast_reply = 1; + } + + reply.host_replies |= check_host(pkt->netif, &q.info, &reply.host_reverse_v6_replies); + replies |= reply.host_replies; + + for (i = 0; i < MDNS_MAX_SERVICES; ++i) { + service = mdns->services[i]; + if (!service) { + continue; + } + reply.serv_replies[i] |= check_service(service, &q.info); + replies |= reply.serv_replies[i]; + } + + if (replies && reply.legacy_query) { + /* Add question to reply packet (legacy packet only has 1 question) */ + res = mdns_add_question(&reply, &q.info.domain, q.info.type, q.info.klass, 0); + if (res != ERR_OK) { + goto cleanup; + } + } + } + + /* Handle known answers */ + while (pkt->answers_left) { + struct mdns_answer ans; + u8_t rev_v6; + int match; + + res = mdns_read_answer(pkt, &ans); + if (res != ERR_OK) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping query packet\n")); + goto cleanup; + } + + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Known answer for domain ")); + mdns_domain_debug_print(&ans.info.domain); + LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass)); + + + if (ans.info.type == DNS_RRTYPE_ANY || ans.info.klass == DNS_RRCLASS_ANY) { + /* Skip known answers for ANY type & class */ + continue; + } + + rev_v6 = 0; + match = reply.host_replies & check_host(pkt->netif, &ans.info, &rev_v6); + if (match && (ans.ttl > (mdns->dns_ttl / 2))) { + /* The RR in the known answer matches an RR we are planning to send, + * and the TTL is less than half gone. + * If the payload matches we should not send that answer. + */ + if (ans.info.type == DNS_RRTYPE_PTR) { + /* Read domain and compare */ + struct mdns_domain known_ans, my_ans; + u16_t len; + len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); + res = mdns_build_host_domain(&my_ans, mdns); + if (len != MDNS_READNAME_ERROR && res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { +#if LWIP_IPV4 + if (match & REPLY_HOST_PTR_V4) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v4 PTR\n")); + reply.host_replies &= ~REPLY_HOST_PTR_V4; + } +#endif +#if LWIP_IPV6 + if (match & REPLY_HOST_PTR_V6) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v6 PTR\n")); + reply.host_reverse_v6_replies &= ~rev_v6; + if (reply.host_reverse_v6_replies == 0) { + reply.host_replies &= ~REPLY_HOST_PTR_V6; + } + } +#endif + } + } else if (match & REPLY_HOST_A) { +#if LWIP_IPV4 + if (ans.rd_length == sizeof(ip4_addr_t) && + pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip4_addr(pkt->netif), ans.rd_length) == 0) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: A\n")); + reply.host_replies &= ~REPLY_HOST_A; + } +#endif + } else if (match & REPLY_HOST_AAAA) { +#if LWIP_IPV6 + if (ans.rd_length == sizeof(ip6_addr_t) && + /* TODO this clears all AAAA responses if first addr is set as known */ + pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip6_addr(pkt->netif, 0), ans.rd_length) == 0) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: AAAA\n")); + reply.host_replies &= ~REPLY_HOST_AAAA; + } +#endif + } + } + + for (i = 0; i < MDNS_MAX_SERVICES; ++i) { + service = mdns->services[i]; + if (!service) { + continue; + } + match = reply.serv_replies[i] & check_service(service, &ans.info); + if (match && (ans.ttl > (service->dns_ttl / 2))) { + /* The RR in the known answer matches an RR we are planning to send, + * and the TTL is less than half gone. + * If the payload matches we should not send that answer. + */ + if (ans.info.type == DNS_RRTYPE_PTR) { + /* Read domain and compare */ + struct mdns_domain known_ans, my_ans; + u16_t len; + len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); + if (len != MDNS_READNAME_ERROR) { + if (match & REPLY_SERVICE_TYPE_PTR) { + res = mdns_build_service_domain(&my_ans, service, 0); + if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service type PTR\n")); + reply.serv_replies[i] &= ~REPLY_SERVICE_TYPE_PTR; + } + } + if (match & REPLY_SERVICE_NAME_PTR) { + res = mdns_build_service_domain(&my_ans, service, 1); + if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service name PTR\n")); + reply.serv_replies[i] &= ~REPLY_SERVICE_NAME_PTR; + } + } + } + } else if (match & REPLY_SERVICE_SRV) { + /* Read and compare to my SRV record */ + u16_t field16, len, read_pos; + struct mdns_domain known_ans, my_ans; + read_pos = ans.rd_offset; + do { + /* Check priority field */ + len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); + if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_PRIORITY) { + break; + } + read_pos += len; + /* Check weight field */ + len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); + if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_WEIGHT) { + break; + } + read_pos += len; + /* Check port field */ + len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); + if (len != sizeof(field16) || lwip_ntohs(field16) != service->port) { + break; + } + read_pos += len; + /* Check host field */ + len = mdns_readname(pkt->pbuf, read_pos, &known_ans); + mdns_build_host_domain(&my_ans, mdns); + if (len == MDNS_READNAME_ERROR || !mdns_domain_eq(&known_ans, &my_ans)) { + break; + } + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: SRV\n")); + reply.serv_replies[i] &= ~REPLY_SERVICE_SRV; + } while (0); + } else if (match & REPLY_SERVICE_TXT) { + mdns_prepare_txtdata(service); + if (service->txtdata.length == ans.rd_length && + pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n")); + reply.serv_replies[i] &= ~REPLY_SERVICE_TXT; + } + } + } + } + } + + mdns_send_outpacket(&reply); + +cleanup: + if (reply.pbuf) { + /* This should only happen if we fail to alloc/write question for legacy query */ + pbuf_free(reply.pbuf); + reply.pbuf = NULL; + } +} + +/** + * Handle response MDNS packet + * Only prints debug for now. Will need more code to do conflict resolution. + */ +static void +mdns_handle_response(struct mdns_packet *pkt) +{ + /* Ignore all questions */ + while (pkt->questions_left) { + struct mdns_question q; + err_t res; + + res = mdns_read_question(pkt, &q); + if (res != ERR_OK) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping response packet\n")); + return; + } + } + + while (pkt->answers_left) { + struct mdns_answer ans; + err_t res; + + res = mdns_read_answer(pkt, &ans); + if (res != ERR_OK) { + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping response packet\n")); + return; + } + + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Answer for domain ")); + mdns_domain_debug_print(&ans.info.domain); + LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass)); + } +} + +/** + * Receive input function for MDNS packets. + * Handles both IPv4 and IPv6 UDP pcbs. + */ +static void +mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + struct dns_hdr hdr; + struct mdns_packet packet; + struct netif *recv_netif = ip_current_input_netif(); + u16_t offset = 0; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + + LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Received IPv%d MDNS packet, len %d\n", IP_IS_V6(addr)? 6 : 4, p->tot_len)); + + if (NETIF_TO_HOST(recv_netif) == NULL) { + /* From netif not configured for MDNS */ + goto dealloc; + } + + if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, offset) < SIZEOF_DNS_HDR) { + /* Too small */ + goto dealloc; + } + offset += SIZEOF_DNS_HDR; + + if (DNS_HDR_GET_OPCODE(&hdr)) { + /* Ignore non-standard queries in multicast packets (RFC 6762, section 18.3) */ + goto dealloc; + } + + memset(&packet, 0, sizeof(packet)); + SMEMCPY(&packet.source_addr, addr, sizeof(packet.source_addr)); + packet.source_port = port; + packet.netif = recv_netif; + packet.pbuf = p; + packet.parse_offset = offset; + packet.tx_id = lwip_ntohs(hdr.id); + packet.questions = packet.questions_left = lwip_ntohs(hdr.numquestions); + packet.answers = packet.answers_left = lwip_ntohs(hdr.numanswers) + lwip_ntohs(hdr.numauthrr) + lwip_ntohs(hdr.numextrarr); + +#if LWIP_IPV6 + if (IP_IS_V6(ip_current_dest_addr())) { + if (!ip_addr_cmp(ip_current_dest_addr(), &v6group)) { + packet.recv_unicast = 1; + } + } +#endif +#if LWIP_IPV4 + if (!IP_IS_V6(ip_current_dest_addr())) { + if (!ip_addr_cmp(ip_current_dest_addr(), &v4group)) { + packet.recv_unicast = 1; + } + } +#endif + + if (hdr.flags1 & DNS_FLAG1_RESPONSE) { + mdns_handle_response(&packet); + } else { + mdns_handle_question(&packet); + } + +dealloc: + pbuf_free(p); +} + +/** + * @ingroup mdns + * Initiate MDNS responder. Will open UDP sockets on port 5353 + */ +void +mdns_resp_init(void) +{ + err_t res; + + mdns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + LWIP_ASSERT("Failed to allocate pcb", mdns_pcb != NULL); +#if LWIP_MULTICAST_TX_OPTIONS + udp_set_multicast_ttl(mdns_pcb, MDNS_TTL); +#else + mdns_pcb->ttl = MDNS_TTL; +#endif + res = udp_bind(mdns_pcb, IP_ANY_TYPE, MDNS_PORT); + LWIP_UNUSED_ARG(res); /* in case of LWIP_NOASSERT */ + LWIP_ASSERT("Failed to bind pcb", res == ERR_OK); + udp_recv(mdns_pcb, mdns_recv, NULL); + + mdns_netif_client_id = netif_alloc_client_data_id(); +} + +/** + * @ingroup mdns + * Announce IP settings have changed on netif. + * Call this in your callback registered by netif_set_status_callback(). + * This function may go away in the future when netif supports registering + * multiple callback functions. + * @param netif The network interface where settings have changed. + */ +void +mdns_resp_netif_settings_changed(struct netif *netif) +{ + LWIP_ERROR("mdns_resp_netif_ip_changed: netif != NULL", (netif != NULL), return); + + if (NETIF_TO_HOST(netif) == NULL) { + return; + } + + /* Announce on IPv6 and IPv4 */ +#if LWIP_IPV6 + mdns_announce(netif, IP6_ADDR_ANY); +#endif +#if LWIP_IPV4 + mdns_announce(netif, IP4_ADDR_ANY); +#endif +} + +/** + * @ingroup mdns + * Activate MDNS responder for a network interface and send announce packets. + * @param netif The network interface to activate. + * @param hostname Name to use. Queries for <hostname>.local will be answered + * with the IP addresses of the netif. The hostname will be copied, the + * given pointer can be on the stack. + * @param dns_ttl Validity time in seconds to send out for IP address data in DNS replies + * @return ERR_OK if netif was added, an err_t otherwise + */ +err_t +mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl) +{ + err_t res; + struct mdns_host* mdns; + + LWIP_ERROR("mdns_resp_add_netif: netif != NULL", (netif != NULL), return ERR_VAL); + LWIP_ERROR("mdns_resp_add_netif: Hostname too long", (strlen(hostname) <= MDNS_LABEL_MAXLEN), return ERR_VAL); + + LWIP_ASSERT("mdns_resp_add_netif: Double add", NETIF_TO_HOST(netif) == NULL); + mdns = (struct mdns_host *) mem_malloc(sizeof(struct mdns_host)); + LWIP_ERROR("mdns_resp_add_netif: Alloc failed", (mdns != NULL), return ERR_MEM); + + netif_set_client_data(netif, mdns_netif_client_id, mdns); + + memset(mdns, 0, sizeof(struct mdns_host)); + MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname))); + mdns->dns_ttl = dns_ttl; + + /* Join multicast groups */ +#if LWIP_IPV4 + res = igmp_joingroup_netif(netif, ip_2_ip4(&v4group)); + if (res != ERR_OK) { + goto cleanup; + } +#endif +#if LWIP_IPV6 + res = mld6_joingroup_netif(netif, ip_2_ip6(&v6group)); + if (res != ERR_OK) { + goto cleanup; + } +#endif + + mdns_resp_netif_settings_changed(netif); + return ERR_OK; + +cleanup: + mem_free(mdns); + netif_set_client_data(netif, mdns_netif_client_id, NULL); + return res; +} + +/** + * @ingroup mdns + * Stop responding to MDNS queries on this interface, leave multicast groups, + * and free the helper structure and any of its services. + * @param netif The network interface to remove. + * @return ERR_OK if netif was removed, an err_t otherwise + */ +err_t +mdns_resp_remove_netif(struct netif *netif) +{ + int i; + struct mdns_host* mdns; + + LWIP_ASSERT("mdns_resp_remove_netif: Null pointer", netif); + mdns = NETIF_TO_HOST(netif); + LWIP_ERROR("mdns_resp_remove_netif: Not an active netif", (mdns != NULL), return ERR_VAL); + + for (i = 0; i < MDNS_MAX_SERVICES; i++) { + struct mdns_service *service = mdns->services[i]; + if (service) { + mem_free(service); + } + } + + /* Leave multicast groups */ +#if LWIP_IPV4 + igmp_leavegroup_netif(netif, ip_2_ip4(&v4group)); +#endif +#if LWIP_IPV6 + mld6_leavegroup_netif(netif, ip_2_ip6(&v6group)); +#endif + + mem_free(mdns); + netif_set_client_data(netif, mdns_netif_client_id, NULL); + return ERR_OK; +} + +/** + * @ingroup mdns + * Add a service to the selected network interface. + * @param netif The network interface to publish this service on + * @param name The name of the service + * @param service The service type, like "_http" + * @param proto The service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP + * for others ("_udp") + * @param port The port the service listens to + * @param dns_ttl Validity time in seconds to send out for service data in DNS replies + * @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to + * allow dynamic replies. + * @param txt_data Userdata pointer for txt_fn + * @return ERR_OK if the service was added to the netif, an err_t otherwise + */ +err_t +mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_data) +{ + int i; + int slot = -1; + struct mdns_service *srv; + struct mdns_host* mdns; + + LWIP_ASSERT("mdns_resp_add_service: netif != NULL", netif); + mdns = NETIF_TO_HOST(netif); + LWIP_ERROR("mdns_resp_add_service: Not an mdns netif", (mdns != NULL), return ERR_VAL); + + LWIP_ERROR("mdns_resp_add_service: Name too long", (strlen(name) <= MDNS_LABEL_MAXLEN), return ERR_VAL); + LWIP_ERROR("mdns_resp_add_service: Service too long", (strlen(service) <= MDNS_LABEL_MAXLEN), return ERR_VAL); + LWIP_ERROR("mdns_resp_add_service: Bad proto (need TCP or UDP)", (proto == DNSSD_PROTO_TCP || proto == DNSSD_PROTO_UDP), return ERR_VAL); + + for (i = 0; i < MDNS_MAX_SERVICES; i++) { + if (mdns->services[i] == NULL) { + slot = i; + break; + } + } + LWIP_ERROR("mdns_resp_add_service: Service list full (increase MDNS_MAX_SERVICES)", (slot >= 0), return ERR_MEM); + + srv = (struct mdns_service*)mem_malloc(sizeof(struct mdns_service)); + LWIP_ERROR("mdns_resp_add_service: Alloc failed", (srv != NULL), return ERR_MEM); + + memset(srv, 0, sizeof(struct mdns_service)); + + MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name))); + MEMCPY(&srv->service, service, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(service))); + srv->txt_fn = txt_fn; + srv->txt_userdata = txt_data; + srv->proto = (u16_t)proto; + srv->port = port; + srv->dns_ttl = dns_ttl; + + mdns->services[slot] = srv; + + /* Announce on IPv6 and IPv4 */ +#if LWIP_IPV6 + mdns_announce(netif, IP6_ADDR_ANY); +#endif +#if LWIP_IPV4 + mdns_announce(netif, IP4_ADDR_ANY); +#endif + + return ERR_OK; +} + +/** + * @ingroup mdns + * Call this function from inside the service_get_txt_fn_t callback to add text data. + * Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte. + * @param service The service provided to the get_txt callback + * @param txt String to add to the TXT field. + * @param txt_len Length of string + * @return ERR_OK if the string was added to the reply, an err_t otherwise + */ +err_t +mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len) +{ + LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service); + + /* Use a mdns_domain struct to store txt chunks since it is the same encoding */ + return mdns_domain_add_label(&service->txtdata, txt, txt_len); +} + +#endif /* LWIP_MDNS_RESPONDER */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mqtt/mqtt.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mqtt/mqtt.c new file mode 100644 index 0000000..3d37ec7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/mqtt/mqtt.c @@ -0,0 +1,1337 @@ +/** + * @file + * MQTT client + * + * @defgroup mqtt MQTT client + * @ingroup apps + * @verbinclude mqtt_client.txt + */ + +/* + * Copyright (c) 2016 Erik Andersson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack + * + * Author: Erik Andersson + * + * + * @todo: + * - Handle large outgoing payloads for PUBLISH messages + * - Fix restriction of a single topic in each (UN)SUBSCRIBE message (protocol has support for multiple topics) + * - Add support for legacy MQTT protocol version + * + * Please coordinate changes and requests with Erik Andersson + * Erik Andersson + * + */ +#include +#include "lwip/timeouts.h" +#include "lwip/ip_addr.h" +#include "lwip/mem.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/tcp.h" +#include "lwip/apps/mqtt.h" + +/** + * MQTT_DEBUG: Default is off. + */ +#if !defined MQTT_DEBUG || defined __DOXYGEN__ +#define MQTT_DEBUG LWIP_DBG_OFF +#endif + +#define MQTT_DEBUG_TRACE (MQTT_DEBUG | LWIP_DBG_TRACE) +#define MQTT_DEBUG_STATE (MQTT_DEBUG | LWIP_DBG_STATE) +#define MQTT_DEBUG_WARN (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define MQTT_DEBUG_WARN_STATE (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) +#define MQTT_DEBUG_SERIOUS (MQTT_DEBUG | LWIP_DBG_LEVEL_SERIOUS) + +static void mqtt_cyclic_timer(void *arg); + +/** + * MQTT client connection states + */ +enum { + TCP_DISCONNECTED, + TCP_CONNECTING, + MQTT_CONNECTING, + MQTT_CONNECTED +}; + +/** + * MQTT control message types + */ +enum mqtt_message_type { + MQTT_MSG_TYPE_CONNECT = 1, + MQTT_MSG_TYPE_CONNACK = 2, + MQTT_MSG_TYPE_PUBLISH = 3, + MQTT_MSG_TYPE_PUBACK = 4, + MQTT_MSG_TYPE_PUBREC = 5, + MQTT_MSG_TYPE_PUBREL = 6, + MQTT_MSG_TYPE_PUBCOMP = 7, + MQTT_MSG_TYPE_SUBSCRIBE = 8, + MQTT_MSG_TYPE_SUBACK = 9, + MQTT_MSG_TYPE_UNSUBSCRIBE = 10, + MQTT_MSG_TYPE_UNSUBACK = 11, + MQTT_MSG_TYPE_PINGREQ = 12, + MQTT_MSG_TYPE_PINGRESP = 13, + MQTT_MSG_TYPE_DISCONNECT = 14 +}; + +/** Helpers to extract control packet type and qos from first byte in fixed header */ +#define MQTT_CTL_PACKET_TYPE(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0xf0) >> 4) +#define MQTT_CTL_PACKET_QOS(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0x6) >> 1) + +/** + * MQTT connect flags, only used in CONNECT message + */ +enum mqtt_connect_flag { + MQTT_CONNECT_FLAG_USERNAME = 1 << 7, + MQTT_CONNECT_FLAG_PASSWORD = 1 << 6, + MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5, + MQTT_CONNECT_FLAG_WILL = 1 << 2, + MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1 +}; + + +#if defined(LWIP_DEBUG) +static const char * const mqtt_message_type_str[15] = +{ + "UNDEFINED", + "CONNECT", + "CONNACK", + "PUBLISH", + "PUBACK", + "PUBREC", + "PUBREL", + "PUBCOMP", + "SUBSCRIBE", + "SUBACK", + "UNSUBSCRIBE", + "UNSUBACK", + "PINGREQ", + "PINGRESP", + "DISCONNECT" +}; + +/** + * Message type value to string + * @param msg_type see enum mqtt_message_type + * + * @return Control message type text string + */ +static const char * +mqtt_msg_type_to_str(u8_t msg_type) +{ + if (msg_type >= LWIP_ARRAYSIZE(mqtt_message_type_str)) { + msg_type = 0; + } + return mqtt_message_type_str[msg_type]; +} + +#endif + + +/** + * Generate MQTT packet identifier + * @param client MQTT client + * @return New packet identifier, range 1 to 65535 + */ +static u16_t +msg_generate_packet_id(mqtt_client_t *client) +{ + client->pkt_id_seq++; + if (client->pkt_id_seq == 0) { + client->pkt_id_seq++; + } + return client->pkt_id_seq; +} + +/*--------------------------------------------------------------------------------------------------------------------- */ +/* Output ring buffer */ + + +#define MQTT_RINGBUF_IDX_MASK ((MQTT_OUTPUT_RINGBUF_SIZE) - 1) + +/** Add single item to ring buffer */ +#define mqtt_ringbuf_put(rb, item) ((rb)->buf)[(rb)->put++ & MQTT_RINGBUF_IDX_MASK] = (item) + +/** Return number of bytes in ring buffer */ +#define mqtt_ringbuf_len(rb) ((u16_t)((rb)->put - (rb)->get)) + +/** Return number of bytes free in ring buffer */ +#define mqtt_ringbuf_free(rb) (MQTT_OUTPUT_RINGBUF_SIZE - mqtt_ringbuf_len(rb)) + +/** Return number of bytes possible to read without wrapping around */ +#define mqtt_ringbuf_linear_read_length(rb) LWIP_MIN(mqtt_ringbuf_len(rb), (MQTT_OUTPUT_RINGBUF_SIZE - ((rb)->get & MQTT_RINGBUF_IDX_MASK))) + +/** Return pointer to ring buffer get position */ +#define mqtt_ringbuf_get_ptr(rb) (&(rb)->buf[(rb)->get & MQTT_RINGBUF_IDX_MASK]) + +#define mqtt_ringbuf_advance_get_idx(rb, len) ((rb)->get += (len)) + + +/** + * Try send as many bytes as possible from output ring buffer + * @param rb Output ring buffer + * @param tpcb TCP connection handle + */ +static void +mqtt_output_send(struct mqtt_ringbuf_t *rb, struct tcp_pcb *tpcb) +{ + err_t err; + u8_t wrap = 0; + u16_t ringbuf_lin_len = mqtt_ringbuf_linear_read_length(rb); + u16_t send_len = tcp_sndbuf(tpcb); + LWIP_ASSERT("mqtt_output_send: tpcb != NULL", tpcb != NULL); + + if (send_len == 0 || ringbuf_lin_len == 0) { + return; + } + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_output_send: tcp_sndbuf: %d bytes, ringbuf_linear_available: %d, get %d, put %d\n", + send_len, ringbuf_lin_len, ((rb)->get & MQTT_RINGBUF_IDX_MASK), ((rb)->put & MQTT_RINGBUF_IDX_MASK))); + + if (send_len > ringbuf_lin_len) { + /* Space in TCP output buffer is larger than available in ring buffer linear portion */ + send_len = ringbuf_lin_len; + /* Wrap around if more data in ring buffer after linear portion */ + wrap = (mqtt_ringbuf_len(rb) > ringbuf_lin_len); + } + err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0)); + if ((err == ERR_OK) && wrap) { + mqtt_ringbuf_advance_get_idx(rb, send_len); + /* Use the lesser one of ring buffer linear length and TCP send buffer size */ + send_len = LWIP_MIN(tcp_sndbuf(tpcb), mqtt_ringbuf_linear_read_length(rb)); + err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY); + } + + if (err == ERR_OK) { + mqtt_ringbuf_advance_get_idx(rb, send_len); + /* Flush */ + tcp_output(tpcb); + } else { + LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_output_send: Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); + } +} + + + +/*--------------------------------------------------------------------------------------------------------------------- */ +/* Request queue */ + +/** + * Create request item + * @param r_objs Pointer to request objects + * @param pkt_id Packet identifier of request + * @param cb Packet callback to call when requests lifetime ends + * @param arg Parameter following callback + * @return Request or NULL if failed to create + */ +static struct mqtt_request_t * +mqtt_create_request(struct mqtt_request_t *r_objs, u16_t pkt_id, mqtt_request_cb_t cb, void *arg) +{ + struct mqtt_request_t *r = NULL; + u8_t n; + LWIP_ASSERT("mqtt_create_request: r_objs != NULL", r_objs != NULL); + for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) { + /* Item point to itself if not in use */ + if (r_objs[n].next == &r_objs[n]) { + r = &r_objs[n]; + r->next = NULL; + r->cb = cb; + r->arg = arg; + r->pkt_id = pkt_id; + break; + } + } + return r; +} + + +/** + * Append request to pending request queue + * @param tail Pointer to request queue tail pointer + * @param r Request to append + */ +static void +mqtt_append_request(struct mqtt_request_t **tail, struct mqtt_request_t *r) +{ + struct mqtt_request_t *head = NULL; + s16_t time_before = 0; + struct mqtt_request_t *iter; + + LWIP_ASSERT("mqtt_append_request: tail != NULL", tail != NULL); + + /* Iterate trough queue to find head, and count total timeout time */ + for (iter = *tail; iter != NULL; iter = iter->next) { + time_before += iter->timeout_diff; + head = iter; + } + + LWIP_ASSERT("mqtt_append_request: time_before <= MQTT_REQ_TIMEOUT", time_before <= MQTT_REQ_TIMEOUT); + r->timeout_diff = MQTT_REQ_TIMEOUT - time_before; + if (head == NULL) { + *tail = r; + } else { + head->next = r; + } +} + + +/** + * Delete request item + * @param r Request item to delete + */ +static void +mqtt_delete_request(struct mqtt_request_t *r) +{ + if (r != NULL) { + r->next = r; + } +} + +/** + * Remove a request item with a specific packet identifier from request queue + * @param tail Pointer to request queue tail pointer + * @param pkt_id Packet identifier of request to take + * @return Request item if found, NULL if not + */ +static struct mqtt_request_t * +mqtt_take_request(struct mqtt_request_t **tail, u16_t pkt_id) +{ + struct mqtt_request_t *iter = NULL, *prev = NULL; + LWIP_ASSERT("mqtt_take_request: tail != NULL", tail != NULL); + /* Search all request for pkt_id */ + for (iter = *tail; iter != NULL; iter = iter->next) { + if (iter->pkt_id == pkt_id) { + break; + } + prev = iter; + } + + /* If request was found */ + if (iter != NULL) { + /* unchain */ + if (prev == NULL) { + *tail= iter->next; + } else { + prev->next = iter->next; + } + /* If exists, add remaining timeout time for the request to next */ + if (iter->next != NULL) { + iter->next->timeout_diff += iter->timeout_diff; + } + iter->next = NULL; + } + return iter; +} + +/** + * Handle requests timeout + * @param tail Pointer to request queue tail pointer + * @param t Time since last call in seconds + */ +static void +mqtt_request_time_elapsed(struct mqtt_request_t **tail, u8_t t) +{ + struct mqtt_request_t *r = *tail; + LWIP_ASSERT("mqtt_request_time_elapsed: tail != NULL", tail != NULL); + while (t > 0 && r != NULL) { + if (t >= r->timeout_diff) { + t -= (u8_t)r->timeout_diff; + /* Unchain */ + *tail = r->next; + /* Notify upper layer about timeout */ + if (r->cb != NULL) { + r->cb(r->arg, ERR_TIMEOUT); + } + mqtt_delete_request(r); + /* Tail might be be modified in callback, so re-read it in every iteration */ + r = *(struct mqtt_request_t * const volatile *)tail; + } else { + r->timeout_diff -= t; + t = 0; + } + } +} + +/** + * Free all request items + * @param tail Pointer to request queue tail pointer + */ +static void +mqtt_clear_requests(struct mqtt_request_t **tail) +{ + struct mqtt_request_t *iter, *next; + LWIP_ASSERT("mqtt_clear_requests: tail != NULL", tail != NULL); + for (iter = *tail; iter != NULL; iter = next) { + next = iter->next; + mqtt_delete_request(iter); + } + *tail = NULL; +} +/** + * Initialize all request items + * @param r_objs Pointer to request objects + */ +static void +mqtt_init_requests(struct mqtt_request_t *r_objs) +{ + u8_t n; + LWIP_ASSERT("mqtt_init_requests: r_objs != NULL", r_objs != NULL); + for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) { + /* Item pointing to itself indicates unused */ + r_objs[n].next = &r_objs[n]; + } +} + +/*--------------------------------------------------------------------------------------------------------------------- */ +/* Output message build helpers */ + + +static void +mqtt_output_append_u8(struct mqtt_ringbuf_t *rb, u8_t value) +{ + mqtt_ringbuf_put(rb, value); +} + +static +void mqtt_output_append_u16(struct mqtt_ringbuf_t *rb, u16_t value) +{ + mqtt_ringbuf_put(rb, value >> 8); + mqtt_ringbuf_put(rb, value & 0xff); +} + +static void +mqtt_output_append_buf(struct mqtt_ringbuf_t *rb, const void *data, u16_t length) +{ + u16_t n; + for (n = 0; n < length; n++) { + mqtt_ringbuf_put(rb, ((const u8_t *)data)[n]); + } +} + +static void +mqtt_output_append_string(struct mqtt_ringbuf_t *rb, const char *str, u16_t length) +{ + u16_t n; + mqtt_ringbuf_put(rb, length >> 8); + mqtt_ringbuf_put(rb, length & 0xff); + for (n = 0; n < length; n++) { + mqtt_ringbuf_put(rb, str[n]); + } +} + +/** + * Append fixed header + * @param rb Output ring buffer + * @param msg_type see enum mqtt_message_type + * @param dup MQTT DUP flag + * @param qos MQTT QoS field + * @param retain MQTT retain flag + * @param r_length Remaining length after fixed header + */ + +static void +mqtt_output_append_fixed_header(struct mqtt_ringbuf_t *rb, u8_t msg_type, u8_t dup, + u8_t qos, u8_t retain, u16_t r_length) +{ + /* Start with control byte */ + mqtt_output_append_u8(rb, (((msg_type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1))); + /* Encode remaining length field */ + do { + mqtt_output_append_u8(rb, (r_length & 0x7f) | (r_length >= 128 ? 0x80 : 0)); + r_length >>= 7; + } while (r_length > 0); +} + + +/** + * Check output buffer space + * @param rb Output ring buffer + * @param r_length Remaining length after fixed header + * @return 1 if message will fit, 0 if not enough buffer space + */ +static u8_t +mqtt_output_check_space(struct mqtt_ringbuf_t *rb, u16_t r_length) +{ + /* Start with length of type byte + remaining length */ + u16_t total_len = 1 + r_length; + + LWIP_ASSERT("mqtt_output_check_space: rb != NULL", rb != NULL); + + /* Calculate number of required bytes to contain the remaining bytes field and add to total*/ + do { + total_len++; + r_length >>= 7; + } while (r_length > 0); + + return (total_len <= mqtt_ringbuf_free(rb)); +} + + +/** + * Close connection to server + * @param client MQTT client + * @param reason Reason for disconnection + */ +static void +mqtt_close(mqtt_client_t *client, mqtt_connection_status_t reason) +{ + LWIP_ASSERT("mqtt_close: client != NULL", client != NULL); + + /* Bring down TCP connection if not already done */ + if (client->conn != NULL) { + err_t res; + tcp_recv(client->conn, NULL); + tcp_err(client->conn, NULL); + tcp_sent(client->conn, NULL); + res = tcp_close(client->conn); + if (res != ERR_OK) { + tcp_abort(client->conn); + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_close: Close err=%s\n", lwip_strerr(res))); + } + client->conn = NULL; + } + + /* Remove all pending requests */ + mqtt_clear_requests(&client->pend_req_queue); + /* Stop cyclic timer */ + sys_untimeout(mqtt_cyclic_timer, client); + + /* Notify upper layer of disconnection if changed state */ + if (client->conn_state != TCP_DISCONNECTED) { + + client->conn_state = TCP_DISCONNECTED; + if (client->connect_cb != NULL) { + client->connect_cb(client, client->connect_arg, reason); + } + } +} + + +/** + * Interval timer, called every MQTT_CYCLIC_TIMER_INTERVAL seconds in MQTT_CONNECTING and MQTT_CONNECTED states + * @param arg MQTT client + */ +static void +mqtt_cyclic_timer(void *arg) +{ + u8_t restart_timer = 1; + mqtt_client_t *client = (mqtt_client_t *)arg; + LWIP_ASSERT("mqtt_cyclic_timer: client != NULL", client != NULL); + + if (client->conn_state == MQTT_CONNECTING) { + client->cyclic_tick++; + if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= MQTT_CONNECT_TIMOUT) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_cyclic_timer: CONNECT attempt to server timed out\n")); + /* Disconnect TCP */ + mqtt_close(client, MQTT_CONNECT_TIMEOUT); + restart_timer = 0; + } + } else if (client->conn_state == MQTT_CONNECTED) { + /* Handle timeout for pending requests */ + mqtt_request_time_elapsed(&client->pend_req_queue, MQTT_CYCLIC_TIMER_INTERVAL); + + /* keep_alive > 0 means keep alive functionality shall be used */ + if (client->keep_alive > 0) { + + client->server_watchdog++; + /* If reception from server has been idle for 1.5*keep_alive time, server is considered unresponsive */ + if ((client->server_watchdog * MQTT_CYCLIC_TIMER_INTERVAL) > (client->keep_alive + client->keep_alive/2)) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_cyclic_timer: Server incoming keep-alive timeout\n")); + mqtt_close(client, MQTT_CONNECT_TIMEOUT); + restart_timer = 0; + } + + /* If time for a keep alive message to be sent, transmission has been idle for keep_alive time */ + if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= client->keep_alive) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_cyclic_timer: Sending keep-alive message to server\n")); + if (mqtt_output_check_space(&client->output, 0) != 0) { + mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0, 0); + client->cyclic_tick = 0; + } + } else { + client->cyclic_tick++; + } + } + } else { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_cyclic_timer: Timer should not be running in state %d\n", client->conn_state)); + restart_timer = 0; + } + if (restart_timer) { + sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL*1000, mqtt_cyclic_timer, arg); + } +} + + +/** + * Send PUBACK, PUBREC or PUBREL response message + * @param client MQTT client + * @param msg PUBACK, PUBREC or PUBREL + * @param pkt_id Packet identifier + * @param qos QoS value + * @return ERR_OK if successful, ERR_MEM if out of memory + */ +static err_t +pub_ack_rec_rel_response(mqtt_client_t *client, u8_t msg, u16_t pkt_id, u8_t qos) +{ + err_t err = ERR_OK; + if (mqtt_output_check_space(&client->output, 2)) { + mqtt_output_append_fixed_header(&client->output, msg, 0, qos, 0, 2); + mqtt_output_append_u16(&client->output, pkt_id); + mqtt_output_send(&client->output, client->conn); + } else { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("pub_ack_rec_rel_response: OOM creating response: %s with pkt_id: %d\n", + mqtt_msg_type_to_str(msg), pkt_id)); + err = ERR_MEM; + } + return err; +} + +/** + * Subscribe response from server + * @param r Matching request + * @param result Result code from server + */ +static void +mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result) +{ + if (r->cb != NULL) { + r->cb(r->arg, result < 3 ? ERR_OK : ERR_ABRT); + } +} + + +/** + * Complete MQTT message received or buffer full + * @param client MQTT client + * @param fixed_hdr_idx header index + * @param length length received part + * @param remaining_length Remaining length of complete message + */ +static mqtt_connection_status_t + mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length) +{ + mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED; + + u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_idx; + + /* Control packet type */ + u8_t pkt_type = MQTT_CTL_PACKET_TYPE(client->rx_buffer[0]); + u16_t pkt_id = 0; + + if (pkt_type == MQTT_MSG_TYPE_CONNACK) { + if (client->conn_state == MQTT_CONNECTING) { + /* Get result code from CONNACK */ + res = (mqtt_connection_status_t)var_hdr_payload[1]; + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: Connect response code %d\n", res)); + if (res == MQTT_CONNECT_ACCEPTED) { + /* Reset cyclic_tick when changing to connected state */ + client->cyclic_tick = 0; + client->conn_state = MQTT_CONNECTED; + /* Notify upper layer */ + if (client->connect_cb != 0) { + client->connect_cb(client, client->connect_arg, res); + } + } + } else { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Received CONNACK in connected state\n")); + } + } else if (pkt_type == MQTT_MSG_TYPE_PINGRESP) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,( "mqtt_message_received: Received PINGRESP from server\n")); + + } else if (pkt_type == MQTT_MSG_TYPE_PUBLISH) { + u16_t payload_offset = 0; + u16_t payload_length = length; + u8_t qos = MQTT_CTL_PACKET_QOS(client->rx_buffer[0]); + + if (client->msg_idx <= MQTT_VAR_HEADER_BUFFER_LEN) { + /* Should have topic and pkt id*/ + uint8_t *topic; + uint16_t after_topic; + u8_t bkp; + u16_t topic_len = var_hdr_payload[0]; + topic_len = (topic_len << 8) + (u16_t)(var_hdr_payload[1]); + + topic = var_hdr_payload + 2; + after_topic = 2 + topic_len; + /* Check length, add one byte even for QoS 0 so that zero termination will fit */ + if ((after_topic + (qos? 2 : 1)) > length) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Receive buffer can not fit topic + pkt_id\n")); + goto out_disconnect; + } + + /* id for QoS 1 and 2 */ + if (qos > 0) { + client->inpub_pkt_id = ((u16_t)var_hdr_payload[after_topic] << 8) + (u16_t)var_hdr_payload[after_topic + 1]; + after_topic += 2; + } else { + client->inpub_pkt_id = 0; + } + /* Take backup of byte after topic */ + bkp = topic[topic_len]; + /* Zero terminate string */ + topic[topic_len] = 0; + /* Payload data remaining in receive buffer */ + payload_length = length - after_topic; + payload_offset = after_topic; + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_incomming_publish: Received message with QoS %d at topic: %s, payload length %d\n", + qos, topic, remaining_length + payload_length)); + if (client->pub_cb != NULL) { + client->pub_cb(client->inpub_arg, (const char *)topic, remaining_length + payload_length); + } + /* Restore byte after topic */ + topic[topic_len] = bkp; + } + if (payload_length > 0 || remaining_length == 0) { + client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0); + /* Reply if QoS > 0 */ + if (remaining_length == 0 && qos > 0) { + /* Send PUBACK for QoS 1 or PUBREC for QoS 2 */ + u8_t resp_msg = (qos == 1) ? MQTT_MSG_TYPE_PUBACK : MQTT_MSG_TYPE_PUBREC; + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_incomming_publish: Sending publish response: %s with pkt_id: %d\n", + mqtt_msg_type_to_str(resp_msg), client->inpub_pkt_id)); + pub_ack_rec_rel_response(client, resp_msg, client->inpub_pkt_id, 0); + } + } + } else { + /* Get packet identifier */ + pkt_id = (u16_t)var_hdr_payload[0] << 8; + pkt_id |= (u16_t)var_hdr_payload[1]; + if (pkt_id == 0) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Got message with illegal packet identifier: 0\n")); + goto out_disconnect; + } + if (pkt_type == MQTT_MSG_TYPE_PUBREC) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: PUBREC, sending PUBREL with pkt_id: %d\n",pkt_id)); + pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBREL, pkt_id, 1); + + } else if (pkt_type == MQTT_MSG_TYPE_PUBREL) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: PUBREL, sending PUBCOMP response with pkt_id: %d\n",pkt_id)); + pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBCOMP, pkt_id, 0); + + } else if (pkt_type == MQTT_MSG_TYPE_SUBACK || pkt_type == MQTT_MSG_TYPE_UNSUBACK || + pkt_type == MQTT_MSG_TYPE_PUBCOMP || pkt_type == MQTT_MSG_TYPE_PUBACK) { + struct mqtt_request_t *r = mqtt_take_request(&client->pend_req_queue, pkt_id); + if (r != NULL) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: %s response with id %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id)); + if (pkt_type == MQTT_MSG_TYPE_SUBACK) { + if (length < 3) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: To small SUBACK packet\n")); + goto out_disconnect; + } else { + mqtt_incomming_suback(r, var_hdr_payload[2]); + } + } else if (r->cb != NULL) { + r->cb(r->arg, ERR_OK); + } + mqtt_delete_request(r); + } else { + LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received %s reply, with wrong pkt_id: %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id)); + } + } else { + LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received unknown message type: %d\n", pkt_type)); + goto out_disconnect; + } + } + return res; +out_disconnect: + return MQTT_CONNECT_DISCONNECTED; +} + + +/** + * MQTT incoming message parser + * @param client MQTT client + * @param p PBUF chain of received data + * @return Connection status + */ +static mqtt_connection_status_t +mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p) +{ + u16_t in_offset = 0; + u32_t msg_rem_len = 0; + u8_t fixed_hdr_idx = 0; + u8_t b = 0; + + while (p->tot_len > in_offset) { + if ((fixed_hdr_idx < 2) || ((b & 0x80) != 0)) { + + if (fixed_hdr_idx < client->msg_idx) { + b = client->rx_buffer[fixed_hdr_idx]; + } else { + b = pbuf_get_at(p, in_offset++); + client->rx_buffer[client->msg_idx++] = b; + } + fixed_hdr_idx++; + + if (fixed_hdr_idx >= 2) { + msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_idx - 2) * 7); + if ((b & 0x80) == 0) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_parse_incoming: Remaining length after fixed header: %d\n", msg_rem_len)); + if (msg_rem_len == 0) { + /* Complete message with no extra headers of payload received */ + mqtt_message_received(client, fixed_hdr_idx, 0, 0); + client->msg_idx = 0; + fixed_hdr_idx = 0; + } else { + /* Bytes remaining in message */ + msg_rem_len = (msg_rem_len + fixed_hdr_idx) - client->msg_idx; + } + } + } + } else { + u16_t cpy_len, cpy_start, buffer_space; + + cpy_start = (client->msg_idx - fixed_hdr_idx) % (MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_idx) + fixed_hdr_idx; + + /* Allow to copy the lesser one of available length in input data or bytes remaining in message */ + cpy_len = (u16_t)LWIP_MIN((u16_t)(p->tot_len - in_offset), msg_rem_len); + + /* Limit to available space in buffer */ + buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - cpy_start; + if (cpy_len > buffer_space) { + cpy_len = buffer_space; + } + pbuf_copy_partial(p, client->rx_buffer+cpy_start, cpy_len, in_offset); + + /* Advance get and put indexes */ + client->msg_idx += cpy_len; + in_offset += cpy_len; + msg_rem_len -= cpy_len; + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_parse_incoming: msg_idx: %d, cpy_len: %d, remaining %d\n", client->msg_idx, cpy_len, msg_rem_len)); + if (msg_rem_len == 0 || cpy_len == buffer_space) { + /* Whole message received or buffer is full */ + mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_idx, (cpy_start + cpy_len) - fixed_hdr_idx, msg_rem_len); + if (res != MQTT_CONNECT_ACCEPTED) { + return res; + } + if (msg_rem_len == 0) { + /* Reset parser state */ + client->msg_idx = 0; + /* msg_tot_len = 0; */ + fixed_hdr_idx = 0; + } + } + } + } + return MQTT_CONNECT_ACCEPTED; +} + + +/** + * TCP received callback function. @see tcp_recv_fn + * @param arg MQTT client + * @param p PBUF chain of received data + * @param err Passed as return value if not ERR_OK + * @return ERR_OK or err passed into callback + */ +static err_t +mqtt_tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + mqtt_client_t *client = (mqtt_client_t *)arg; + LWIP_ASSERT("mqtt_tcp_recv_cb: client != NULL", client != NULL); + LWIP_ASSERT("mqtt_tcp_recv_cb: client->conn == pcb", client->conn == pcb); + + if (p == NULL) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_recv_cb: Recv pbuf=NULL, remote has closed connection\n")); + mqtt_close(client, MQTT_CONNECT_DISCONNECTED); + } else { + mqtt_connection_status_t res; + if (err != ERR_OK) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_tcp_recv_cb: Recv err=%d\n", err)); + pbuf_free(p); + return err; + } + + /* Tell remote that data has been received */ + tcp_recved(pcb, p->tot_len); + res = mqtt_parse_incoming(client, p); + pbuf_free(p); + + if (res != MQTT_CONNECT_ACCEPTED) { + mqtt_close(client, res); + } + /* If keep alive functionality is used */ + if (client->keep_alive != 0) { + /* Reset server alive watchdog */ + client->server_watchdog = 0; + } + + } + return ERR_OK; +} + + +/** + * TCP data sent callback function. @see tcp_sent_fn + * @param arg MQTT client + * @param tpcb TCP connection handle + * @param len Number of bytes sent + * @return ERR_OK + */ +static err_t +mqtt_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + mqtt_client_t *client = (mqtt_client_t *)arg; + + LWIP_UNUSED_ARG(tpcb); + LWIP_UNUSED_ARG(len); + + if (client->conn_state == MQTT_CONNECTED) { + struct mqtt_request_t *r; + + /* Reset keep-alive send timer and server watchdog */ + client->cyclic_tick = 0; + client->server_watchdog = 0; + /* QoS 0 publish has no response from server, so call its callbacks here */ + while ((r = mqtt_take_request(&client->pend_req_queue, 0)) != NULL) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_sent_cb: Calling QoS 0 publish complete callback\n")); + if (r->cb != NULL) { + r->cb(r->arg, ERR_OK); + } + mqtt_delete_request(r); + } + /* Try send any remaining buffers from output queue */ + mqtt_output_send(&client->output, client->conn); + } + return ERR_OK; +} + +/** + * TCP error callback function. @see tcp_err_fn + * @param arg MQTT client + * @param err Error encountered + */ +static void +mqtt_tcp_err_cb(void *arg, err_t err) +{ + mqtt_client_t *client = (mqtt_client_t *)arg; + LWIP_UNUSED_ARG(err); /* only used for debug output */ + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_err_cb: TCP error callback: error %d, arg: %p\n", err, arg)); + LWIP_ASSERT("mqtt_tcp_err_cb: client != NULL", client != NULL); + /* Set conn to null before calling close as pcb is already deallocated*/ + client->conn = 0; + mqtt_close(client, MQTT_CONNECT_DISCONNECTED); +} + +/** + * TCP poll callback function. @see tcp_poll_fn + * @param arg MQTT client + * @param tpcb TCP connection handle + * @return err ERR_OK + */ +static err_t +mqtt_tcp_poll_cb(void *arg, struct tcp_pcb *tpcb) +{ + mqtt_client_t *client = (mqtt_client_t *)arg; + if (client->conn_state == MQTT_CONNECTED) { + /* Try send any remaining buffers from output queue */ + mqtt_output_send(&client->output, tpcb); + } + return ERR_OK; +} + +/** + * TCP connect callback function. @see tcp_connected_fn + * @param arg MQTT client + * @param err Always ERR_OK, mqtt_tcp_err_cb is called in case of error + * @return ERR_OK + */ +static err_t +mqtt_tcp_connect_cb(void *arg, struct tcp_pcb *tpcb, err_t err) +{ + mqtt_client_t* client = (mqtt_client_t *)arg; + + if (err != ERR_OK) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_tcp_connect_cb: TCP connect error %d\n", err)); + return err; + } + + /* Initiate receiver state */ + client->msg_idx = 0; + + /* Setup TCP callbacks */ + tcp_recv(tpcb, mqtt_tcp_recv_cb); + tcp_sent(tpcb, mqtt_tcp_sent_cb); + tcp_poll(tpcb, mqtt_tcp_poll_cb, 2); + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_connect_cb: TCP connection established to server\n")); + /* Enter MQTT connect state */ + client->conn_state = MQTT_CONNECTING; + + /* Start cyclic timer */ + sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL*1000, mqtt_cyclic_timer, client); + client->cyclic_tick = 0; + + /* Start transmission from output queue, connect message is the first one out*/ + mqtt_output_send(&client->output, client->conn); + + return ERR_OK; +} + + + +/*---------------------------------------------------------------------------------------------------- */ +/* Public API */ + + +/** + * @ingroup mqtt + * MQTT publish function. + * @param client MQTT client + * @param topic Publish topic string + * @param payload Data to publish (NULL is allowed) + * @param payload_length: Length of payload (0 is allowed) + * @param qos Quality of service, 0 1 or 2 + * @param retain MQTT retain flag + * @param cb Callback to call when publish is complete or has timed out + * @param arg User supplied argument to publish callback + * @return ERR_OK if successful + * ERR_CONN if client is disconnected + * ERR_MEM if short on memory + */ +err_t +mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain, + mqtt_request_cb_t cb, void *arg) +{ + struct mqtt_request_t *r; + u16_t pkt_id; + size_t topic_strlen; + size_t total_len; + u16_t topic_len; + u16_t remaining_length; + + LWIP_ASSERT("mqtt_publish: client != NULL", client); + LWIP_ASSERT("mqtt_publish: topic != NULL", topic); + LWIP_ERROR("mqtt_publish: TCP disconnected", (client->conn_state != TCP_DISCONNECTED), return ERR_CONN); + + topic_strlen = strlen(topic); + LWIP_ERROR("mqtt_publish: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG); + topic_len = (u16_t)topic_strlen; + total_len = 2 + topic_len + payload_length; + LWIP_ERROR("mqtt_publish: total length overflow", (total_len <= 0xFFFF), return ERR_ARG); + remaining_length = (u16_t)total_len; + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_publish: Publish with payload length %d to topic \"%s\"\n", payload_length, topic)); + + if (qos > 0) { + remaining_length += 2; + /* Generate pkt_id id for QoS1 and 2 */ + pkt_id = msg_generate_packet_id(client); + } else { + /* Use reserved value pkt_id 0 for QoS 0 in request handle */ + pkt_id = 0; + } + + r = mqtt_create_request(client->req_list, pkt_id, cb, arg); + if (r == NULL) { + return ERR_MEM; + } + + if (mqtt_output_check_space(&client->output, remaining_length) == 0) { + mqtt_delete_request(r); + return ERR_MEM; + } + /* Append fixed header */ + mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain, remaining_length); + + /* Append Topic */ + mqtt_output_append_string(&client->output, topic, topic_len); + + /* Append packet if for QoS 1 and 2*/ + if (qos > 0) { + mqtt_output_append_u16(&client->output, pkt_id); + } + + /* Append optional publish payload */ + if ((payload != NULL) && (payload_length > 0)) { + mqtt_output_append_buf(&client->output, payload, payload_length); + } + + mqtt_append_request(&client->pend_req_queue, r); + mqtt_output_send(&client->output, client->conn); + return ERR_OK; +} + + +/** + * @ingroup mqtt + * MQTT subscribe/unsubscribe function. + * @param client MQTT client + * @param topic topic to subscribe to + * @param qos Quality of service, 0 1 or 2 (only used for subscribe) + * @param cb Callback to call when subscribe/unsubscribe reponse is received + * @param arg User supplied argument to publish callback + * @param sub 1 for subscribe, 0 for unsubscribe + * @return ERR_OK if successful, @see err_t enum for other results + */ +err_t +mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub) +{ + size_t topic_strlen; + size_t total_len; + u16_t topic_len; + u16_t remaining_length; + u16_t pkt_id; + struct mqtt_request_t *r; + + LWIP_ASSERT("mqtt_sub_unsub: client != NULL", client); + LWIP_ASSERT("mqtt_sub_unsub: topic != NULL", topic); + + topic_strlen = strlen(topic); + LWIP_ERROR("mqtt_sub_unsub: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG); + topic_len = (u16_t)topic_strlen; + /* Topic string, pkt_id, qos for subscribe */ + total_len = topic_len + 2 + 2 + (sub != 0); + LWIP_ERROR("mqtt_sub_unsub: total length overflow", (total_len <= 0xFFFF), return ERR_ARG); + remaining_length = (u16_t)total_len; + + LWIP_ASSERT("mqtt_sub_unsub: qos < 3", qos < 3); + if (client->conn_state == TCP_DISCONNECTED) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_sub_unsub: Can not (un)subscribe in disconnected state\n")); + return ERR_CONN; + } + + pkt_id = msg_generate_packet_id(client); + r = mqtt_create_request(client->req_list, pkt_id, cb, arg); + if (r == NULL) { + return ERR_MEM; + } + + if (mqtt_output_check_space(&client->output, remaining_length) == 0) { + mqtt_delete_request(r); + return ERR_MEM; + } + + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_sub_unsub: Client (un)subscribe to topic \"%s\", id: %d\n", topic, pkt_id)); + + mqtt_output_append_fixed_header(&client->output, sub ? MQTT_MSG_TYPE_SUBSCRIBE : MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0, remaining_length); + /* Packet id */ + mqtt_output_append_u16(&client->output, pkt_id); + /* Topic */ + mqtt_output_append_string(&client->output, topic, topic_len); + /* QoS */ + if (sub != 0) { + mqtt_output_append_u8(&client->output, LWIP_MIN(qos, 2)); + } + + mqtt_append_request(&client->pend_req_queue, r); + mqtt_output_send(&client->output, client->conn); + return ERR_OK; +} + + +/** + * @ingroup mqtt + * Set callback to handle incoming publish requests from server + * @param client MQTT client + * @param pub_cb Callback invoked when publish starts, contain topic and total length of payload + * @param data_cb Callback for each fragment of payload that arrives + * @param arg User supplied argument to both callbacks + */ +void +mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t pub_cb, + mqtt_incoming_data_cb_t data_cb, void *arg) +{ + LWIP_ASSERT("mqtt_set_inpub_callback: client != NULL", client != NULL); + client->data_cb = data_cb; + client->pub_cb = pub_cb; + client->inpub_arg = arg; +} + +/** + * @ingroup mqtt + * Create a new MQTT client instance + * @return Pointer to instance on success, NULL otherwise + */ +mqtt_client_t * +mqtt_client_new(void) +{ + mqtt_client_t *client = (mqtt_client_t *)mem_malloc(sizeof(mqtt_client_t)); + if (client != NULL) { + memset(client, 0, sizeof(mqtt_client_t)); + } + return client; +} + + +/** + * @ingroup mqtt + * Connect to MQTT server + * @param client MQTT client + * @param ip_addr Server IP + * @param port Server port + * @param cb Connection state change callback + * @param arg User supplied argument to connection callback + * @param client_info Client identification and connection options + * @return ERR_OK if successful, @see err_t enum for other results + */ +err_t +mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg, + const struct mqtt_connect_client_info_t *client_info) +{ + err_t err; + size_t len; + u16_t client_id_length; + /* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */ + u16_t remaining_length = 2 + 4 + 1 + 1 + 2; + u8_t flags = 0, will_topic_len = 0, will_msg_len = 0; + + LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL); + LWIP_ASSERT("mqtt_client_connect: ip_addr != NULL", ip_addr != NULL); + LWIP_ASSERT("mqtt_client_connect: client_info != NULL", client_info != NULL); + LWIP_ASSERT("mqtt_client_connect: client_info->client_id != NULL", client_info->client_id != NULL); + + if (client->conn_state != TCP_DISCONNECTED) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Already connected\n")); + return ERR_ISCONN; + } + + /* Wipe clean */ + memset(client, 0, sizeof(mqtt_client_t)); + client->connect_arg = arg; + client->connect_cb = cb; + client->keep_alive = client_info->keep_alive; + mqtt_init_requests(client->req_list); + + /* Build connect message */ + if (client_info->will_topic != NULL && client_info->will_msg != NULL) { + flags |= MQTT_CONNECT_FLAG_WILL; + flags |= (client_info->will_qos & 3) << 3; + if (client_info->will_retain) { + flags |= MQTT_CONNECT_FLAG_WILL_RETAIN; + } + len = strlen(client_info->will_topic); + LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL); + LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL); + will_topic_len = (u8_t)len; + len = strlen(client_info->will_msg); + LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL); + will_msg_len = (u8_t)len; + len = remaining_length + 2 + will_topic_len + 2 + will_msg_len; + LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL); + remaining_length = (u16_t)len; + } + + /* Don't complicate things, always connect using clean session */ + flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION; + + len = strlen(client_info->client_id); + LWIP_ERROR("mqtt_client_connect: client_info->client_id length overflow", len <= 0xFFFF, return ERR_VAL); + client_id_length = (u16_t)len; + len = remaining_length + 2 + client_id_length; + LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL); + remaining_length = (u16_t)len; + + if (mqtt_output_check_space(&client->output, remaining_length) == 0) { + return ERR_MEM; + } + + client->conn = tcp_new(); + if (client->conn == NULL) { + return ERR_MEM; + } + + /* Set arg pointer for callbacks */ + tcp_arg(client->conn, client); + /* Any local address, pick random local port number */ + err = tcp_bind(client->conn, IP_ADDR_ANY, 0); + if (err != ERR_OK) { + LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Error binding to local ip/port, %d\n", err)); + goto tcp_fail; + } + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Connecting to host: %s at port:%"U16_F"\n", ipaddr_ntoa(ip_addr), port)); + + /* Connect to server */ + err = tcp_connect(client->conn, ip_addr, port, mqtt_tcp_connect_cb); + if (err != ERR_OK) { + LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Error connecting to remote ip/port, %d\n", err)); + goto tcp_fail; + } + /* Set error callback */ + tcp_err(client->conn, mqtt_tcp_err_cb); + client->conn_state = TCP_CONNECTING; + + /* Append fixed header */ + mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_CONNECT, 0, 0, 0, remaining_length); + /* Append Protocol string */ + mqtt_output_append_string(&client->output, "MQTT", 4); + /* Append Protocol level */ + mqtt_output_append_u8(&client->output, 4); + /* Append connect flags */ + mqtt_output_append_u8(&client->output, flags); + /* Append keep-alive */ + mqtt_output_append_u16(&client->output, client_info->keep_alive); + /* Append client id */ + mqtt_output_append_string(&client->output, client_info->client_id, client_id_length); + /* Append will message if used */ + if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) { + mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len); + mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len); + } + return ERR_OK; + +tcp_fail: + tcp_abort(client->conn); + client->conn = NULL; + return err; +} + + +/** + * @ingroup mqtt + * Disconnect from MQTT server + * @param client MQTT client + */ +void +mqtt_disconnect(mqtt_client_t *client) +{ + LWIP_ASSERT("mqtt_disconnect: client != NULL", client); + /* If connection in not already closed */ + if (client->conn_state != TCP_DISCONNECTED) { + /* Set conn_state before calling mqtt_close to prevent callback from being called */ + client->conn_state = TCP_DISCONNECTED; + mqtt_close(client, (mqtt_connection_status_t)0); + } +} + +/** + * @ingroup mqtt + * Check connection with server + * @param client MQTT client + * @return 1 if connected to server, 0 otherwise + */ +u8_t +mqtt_client_is_connected(mqtt_client_t *client) +{ + LWIP_ASSERT("mqtt_client_is_connected: client != NULL", client); + return client->conn_state == MQTT_CONNECTED; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/netbiosns/netbiosns.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/netbiosns/netbiosns.c new file mode 100644 index 0000000..2dfbe65 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/netbiosns/netbiosns.c @@ -0,0 +1,367 @@ +/** + * @file + * NetBIOS name service responder + */ + +/** + * @defgroup netbiosns NETBIOS responder + * @ingroup apps + * + * This is an example implementation of a NetBIOS name server. + * It responds to name queries for a configurable name. + * Name resolving is not supported. + * + * Note that the device doesn't broadcast it's own name so can't + * detect duplicate names! + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/apps/netbiosns.h" + +#if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/udp.h" +#include "lwip/netif.h" + +#include + +/** default port number for "NetBIOS Name service */ +#define NETBIOS_PORT 137 + +/** size of a NetBIOS name */ +#define NETBIOS_NAME_LEN 16 + +/** The Time-To-Live for NetBIOS name responds (in seconds) + * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ +#define NETBIOS_NAME_TTL 300000u + +/** NetBIOS header flags */ +#define NETB_HFLAG_RESPONSE 0x8000U +#define NETB_HFLAG_OPCODE 0x7800U +#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U +#define NETB_HFLAG_AUTHORATIVE 0x0400U +#define NETB_HFLAG_TRUNCATED 0x0200U +#define NETB_HFLAG_RECURS_DESIRED 0x0100U +#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U +#define NETB_HFLAG_BROADCAST 0x0010U +#define NETB_HFLAG_REPLYCODE 0x0008U +#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U + +/** NetBIOS name flags */ +#define NETB_NFLAG_UNIQUE 0x8000U +#define NETB_NFLAG_NODETYPE 0x6000U +#define NETB_NFLAG_NODETYPE_HNODE 0x6000U +#define NETB_NFLAG_NODETYPE_MNODE 0x4000U +#define NETB_NFLAG_NODETYPE_PNODE 0x2000U +#define NETB_NFLAG_NODETYPE_BNODE 0x0000U + +/** NetBIOS message header */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_hdr { + PACK_STRUCT_FIELD(u16_t trans_id); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(u16_t questions); + PACK_STRUCT_FIELD(u16_t answerRRs); + PACK_STRUCT_FIELD(u16_t authorityRRs); + PACK_STRUCT_FIELD(u16_t additionalRRs); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message name part */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_name_hdr { + PACK_STRUCT_FLD_8(u8_t nametype); + PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN*2)+1]); + PACK_STRUCT_FIELD(u16_t type); + PACK_STRUCT_FIELD(u16_t cls); + PACK_STRUCT_FIELD(u32_t ttl); + PACK_STRUCT_FIELD(u16_t datalen); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FLD_S(ip4_addr_p_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_resp +{ + struct netbios_hdr resp_hdr; + struct netbios_name_hdr resp_name; +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef NETBIOS_LWIP_NAME +#define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME +#else +static char netbiosns_local_name[NETBIOS_NAME_LEN]; +#define NETBIOS_LOCAL_NAME netbiosns_local_name +#endif + +struct udp_pcb *netbiosns_pcb; + +/** Decode a NetBIOS name (from packet to string) */ +static int +netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len) +{ + char *pname; + char cname; + char cnbname; + int idx = 0; + + LWIP_UNUSED_ARG(name_dec_len); + + /* Start decoding netbios name. */ + pname = name_enc; + for (;;) { + /* Every two characters of the first level-encoded name + * turn into one character in the decoded name. */ + cname = *pname; + if (cname == '\0') + break; /* no more characters */ + if (cname == '.') + break; /* scope ID follows */ + if (cname < 'A' || cname > 'Z') { + /* Not legal. */ + return -1; + } + cname -= 'A'; + cnbname = cname << 4; + pname++; + + cname = *pname; + if (cname == '\0' || cname == '.') { + /* No more characters in the name - but we're in + * the middle of a pair. Not legal. */ + return -1; + } + if (cname < 'A' || cname > 'Z') { + /* Not legal. */ + return -1; + } + cname -= 'A'; + cnbname |= cname; + pname++; + + /* Do we have room to store the character? */ + if (idx < NETBIOS_NAME_LEN) { + /* Yes - store the character. */ + name_dec[idx++] = (cnbname!=' '?cnbname:'\0'); + } + } + + return 0; +} + +#if 0 /* function currently unused */ +/** Encode a NetBIOS name (from string to packet) - currently unused because + we don't ask for names. */ +static int +netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len) +{ + char *pname; + char cname; + unsigned char ucname; + int idx = 0; + + /* Start encoding netbios name. */ + pname = name_enc; + + for (;;) { + /* Every two characters of the first level-encoded name + * turn into one character in the decoded name. */ + cname = *pname; + if (cname == '\0') + break; /* no more characters */ + if (cname == '.') + break; /* scope ID follows */ + if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) { + /* Not legal. */ + return -1; + } + + /* Do we have room to store the character? */ + if (idx >= name_dec_len) { + return -1; + } + + /* Yes - store the character. */ + ucname = cname; + name_dec[idx++] = ('A'+((ucname>>4) & 0x0F)); + name_dec[idx++] = ('A'+( ucname & 0x0F)); + pname++; + } + + /* Fill with "space" coding */ + for (;idx < name_dec_len - 1;) { + name_dec[idx++] = 'C'; + name_dec[idx++] = 'A'; + } + + /* Terminate string */ + name_dec[idx] = '\0'; + + return 0; +} +#endif /* 0 */ + +/** NetBIOS Name service recv callback */ +static void +netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + LWIP_UNUSED_ARG(arg); + + /* if packet is valid */ + if (p != NULL) { + char netbios_name[NETBIOS_NAME_LEN+1]; + struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload; + struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1); + + /* we only answer if we got a default interface */ + if (netif_default != NULL) { + /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ + /* if the packet is a NetBIOS name query question */ + if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && + ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && + (netbios_hdr->questions == PP_NTOHS(1))) { + /* decode the NetBIOS name */ + netbiosns_name_decode((char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name)); + /* if the packet is for us */ + if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) { + struct pbuf *q; + struct netbios_resp *resp; + + q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); + if (q != NULL) { + resp = (struct netbios_resp*)q->payload; + + /* prepare NetBIOS header response */ + resp->resp_hdr.trans_id = netbios_hdr->trans_id; + resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | + NETB_HFLAG_OPCODE_NAME_QUERY | + NETB_HFLAG_AUTHORATIVE | + NETB_HFLAG_RECURS_DESIRED); + resp->resp_hdr.questions = 0; + resp->resp_hdr.answerRRs = PP_HTONS(1); + resp->resp_hdr.authorityRRs = 0; + resp->resp_hdr.additionalRRs = 0; + + /* prepare NetBIOS header datas */ + MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname)); + resp->resp_name.nametype = netbios_name_hdr->nametype; + resp->resp_name.type = netbios_name_hdr->type; + resp->resp_name.cls = netbios_name_hdr->cls; + resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); + resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); + resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); + ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default)); + + /* send the NetBIOS response */ + udp_sendto(upcb, q, addr, port); + + /* free the "reference" pbuf */ + pbuf_free(q); + } + } + } + } + /* free the pbuf */ + pbuf_free(p); + } +} + +/** + * @ingroup netbiosns + * Init netbios responder + */ +void +netbiosns_init(void) +{ +#ifdef NETBIOS_LWIP_NAME + LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); +#endif + + netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (netbiosns_pcb != NULL) { + /* we have to be allowed to send broadcast packets! */ + ip_set_option(netbiosns_pcb, SOF_BROADCAST); + udp_bind(netbiosns_pcb, IP_ANY_TYPE, NETBIOS_PORT); + udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb); + } +} + +#ifndef NETBIOS_LWIP_NAME +/** + * @ingroup netbiosns + * Set netbios name. ATTENTION: the hostname must be less than 15 characters! + */ +void +netbiosns_set_name(const char* hostname) +{ + size_t copy_len = strlen(hostname); + LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN); + if (copy_len >= NETBIOS_NAME_LEN) { + copy_len = NETBIOS_NAME_LEN - 1; + } + MEMCPY(netbiosns_local_name, hostname, copy_len + 1); +} +#endif + +/** + * @ingroup netbiosns + * Stop netbios responder + */ +void +netbiosns_stop(void) +{ + if (netbiosns_pcb != NULL) { + udp_remove(netbiosns_pcb); + netbiosns_pcb = NULL; + } +} + +#endif /* LWIP_IPV4 && LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.c new file mode 100644 index 0000000..d4f094e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.c @@ -0,0 +1,749 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) encoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "snmp_asn1.h" + +#define PBUF_OP_EXEC(code) \ + if ((code) != ERR_OK) { \ + return ERR_BUF; \ + } + +/** + * Encodes a TLV into a pbuf stream. + * + * @param pbuf_stream points to a pbuf stream + * @param tlv TLV to encode + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv) +{ + u8_t data; + u8_t length_bytes_required; + + /* write type */ + if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) { + /* extended format is not used by SNMP so we do not accept those values */ + return ERR_ARG; + } + if (tlv->type_len != 0) { + /* any other value as auto is not accepted for type (we always use one byte because extended syntax is prohibited) */ + return ERR_ARG; + } + + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, tlv->type)); + tlv->type_len = 1; + + /* write length */ + if (tlv->value_len <= 127) { + length_bytes_required = 1; + } else if (tlv->value_len <= 255) { + length_bytes_required = 2; + } else { + length_bytes_required = 3; + } + + /* check for forced min length */ + if (tlv->length_len > 0) { + if (tlv->length_len < length_bytes_required) { + /* unable to code requested length in requested number of bytes */ + return ERR_ARG; + } + + length_bytes_required = tlv->length_len; + } else { + tlv->length_len = length_bytes_required; + } + + if (length_bytes_required > 1) { + /* multi byte representation required */ + length_bytes_required--; + data = 0x80 | length_bytes_required; /* extended length definition, 1 length byte follows */ + + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); + + while (length_bytes_required > 1) { + if (length_bytes_required == 2) { + /* append high byte */ + data = (u8_t)(tlv->value_len >> 8); + } else { + /* append leading 0x00 */ + data = 0x00; + } + + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); + length_bytes_required--; + } + } + + /* append low byte */ + data = (u8_t)(tlv->value_len & 0xFF); + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); + + return ERR_OK; +} + +/** + * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. + * + * @param pbuf_stream points to a pbuf stream + * @param raw_len raw data length + * @param raw points raw data + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len) +{ + PBUF_OP_EXEC(snmp_pbuf_stream_writebuf(pbuf_stream, raw, raw_len)); + + return ERR_OK; +} + +/** + * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. + * + * @param pbuf_stream points to a pbuf stream + * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) + * @param value is the host order u32_t value to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_u32t_cnt() + */ +err_t +snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value) +{ + if (octets_needed > 5) { + return ERR_ARG; + } + if (octets_needed == 5) { + /* not enough bits in 'value' add leading 0x00 */ + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00)); + octets_needed--; + } + + while (octets_needed > 1) { + octets_needed--; + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3)))); + } + + /* (only) one least significant octet */ + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value)); + + return ERR_OK; +} + +/** + * Encodes u64_t (counter64) into a pbuf chained ASN1 msg. + * + * @param pbuf_stream points to a pbuf stream + * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) + * @param value is the host order u32_t value to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_u64t_cnt() + */ +err_t +snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value) +{ + if (octets_needed > 9) { + return ERR_ARG; + } + if (octets_needed == 9) { + /* not enough bits in 'value' add leading 0x00 */ + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00)); + octets_needed--; + } + + while (octets_needed > 4) { + octets_needed--; + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> ((octets_needed-4) << 3)))); + } + + /* skip to low u32 */ + value++; + + while (octets_needed > 1) { + octets_needed--; + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> (octets_needed << 3)))); + } + + /* always write at least one octet (also in case of value == 0) */ + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value))); + + return ERR_OK; +} + +/** + * Encodes s32_t integer into a pbuf chained ASN1 msg. + * + * @param pbuf_stream points to a pbuf stream + * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) + * @param value is the host order s32_t value to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_s32t_cnt() + */ +err_t +snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value) +{ + while (octets_needed > 1) { + octets_needed--; + + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3)))); + } + + /* (only) one least significant octet */ + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value)); + + return ERR_OK; +} + +/** + * Encodes object identifier into a pbuf chained ASN1 msg. + * + * @param pbuf_stream points to a pbuf stream + * @param oid points to object identifier array + * @param oid_len object identifier array length + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len) +{ + if (oid_len > 1) { + /* write compressed first two sub id's */ + u32_t compressed_byte = ((oid[0] * 40) + oid[1]); + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)compressed_byte)); + oid_len -= 2; + oid += 2; + } else { + /* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ + /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ + return ERR_ARG; + } + + while (oid_len > 0) { + u32_t sub_id; + u8_t shift, tail; + + oid_len--; + sub_id = *oid; + tail = 0; + shift = 28; + while (shift > 0) { + u8_t code; + + code = (u8_t)(sub_id >> shift); + if ((code != 0) || (tail != 0)) { + tail = 1; + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, code | 0x80)); + } + shift -= 7; + } + PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)sub_id & 0x7F)); + + /* proceed to next sub-identifier */ + oid++; + } + return ERR_OK; +} + +/** + * Returns octet count for length. + * + * @param length parameter length + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) +{ + if (length < 0x80U) { + *octets_needed = 1; + } else if (length < 0x100U) { + *octets_needed = 2; + } else { + *octets_needed = 3; + } +} + +/** + * Returns octet count for an u32_t. + * + * @param value value to be encoded + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets! + */ +void +snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) +{ + if (value < 0x80UL) { + *octets_needed = 1; + } else if (value < 0x8000UL) { + *octets_needed = 2; + } else if (value < 0x800000UL) { + *octets_needed = 3; + } else if (value < 0x80000000UL) { + *octets_needed = 4; + } else { + *octets_needed = 5; + } +} + +/** + * Returns octet count for an u64_t. + * + * @param value value to be encoded + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets! + */ +void +snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed) +{ + /* check if high u32 is 0 */ + if (*value == 0x00) { + /* only low u32 is important */ + value++; + snmp_asn1_enc_u32t_cnt(*value, octets_needed); + } else { + /* low u32 does not matter for length determination */ + snmp_asn1_enc_u32t_cnt(*value, octets_needed); + *octets_needed = *octets_needed + 4; /* add the 4 bytes of low u32 */ + } +} + +/** + * Returns octet count for an s32_t. + * + * @param value value to be encoded + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. + */ +void +snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) +{ + if (value < 0) { + value = ~value; + } + if (value < 0x80L) { + *octets_needed = 1; + } else if (value < 0x8000L) { + *octets_needed = 2; + } else if (value < 0x800000L) { + *octets_needed = 3; + } else { + *octets_needed = 4; + } +} + +/** + * Returns octet count for an object identifier. + * + * @param oid points to object identifier array + * @param oid_len object identifier array length + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed) +{ + u32_t sub_id; + + *octets_needed = 0; + if (oid_len > 1) { + /* compressed prefix in one octet */ + (*octets_needed)++; + oid_len -= 2; + oid += 2; + } + while (oid_len > 0) { + oid_len--; + sub_id = *oid; + + sub_id >>= 7; + (*octets_needed)++; + while (sub_id > 0) { + sub_id >>= 7; + (*octets_needed)++; + } + oid++; + } +} + +/** + * Decodes a TLV from a pbuf stream. + * + * @param pbuf_stream points to a pbuf stream + * @param tlv returns decoded TLV + * @return ERR_OK if successful, ERR_VAL if we can't decode + */ +err_t +snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv) +{ + u8_t data; + + /* decode type first */ + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + tlv->type = data; + + if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) { + /* extended format is not used by SNMP so we do not accept those values */ + return ERR_VAL; + } + tlv->type_len = 1; + + /* now, decode length */ + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + + if (data < 0x80) { /* short form */ + tlv->length_len = 1; + tlv->value_len = data; + } else if (data > 0x80) { /* long form */ + u8_t length_bytes = data - 0x80; + tlv->length_len = length_bytes + 1; /* this byte + defined number of length bytes following */ + tlv->value_len = 0; + + while (length_bytes > 0) { + /* we only support up to u16.maxvalue-1 (2 bytes) but have to accept leading zero bytes */ + if (tlv->value_len > 0xFF) { + return ERR_VAL; + } + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + tlv->value_len <<= 8; + tlv->value_len |= data; + + /* take care for special value used for indefinite length */ + if (tlv->value_len == 0xFFFF) { + return ERR_VAL; + } + + length_bytes--; + } + } else { /* data == 0x80 indefinite length form */ + /* (not allowed for SNMP; RFC 1157, 3.2.2) */ + return ERR_VAL; + } + + return ERR_OK; +} + +/** + * Decodes positive integer (counter, gauge, timeticks) into u32_t. + * + * @param pbuf_stream points to a pbuf stream + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets! + */ +err_t +snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value) +{ + u8_t data; + + if ((len > 0) && (len <= 5)) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + + /* expecting sign bit to be zero, only unsigned please! */ + if (((len == 5) && (data == 0x00)) || ((len < 5) && ((data & 0x80) == 0))) { + *value = data; + len--; + + while (len > 0) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + + *value <<= 8; + *value |= data; + } + + return ERR_OK; + } + } + + return ERR_VAL; +} + +/** + * Decodes large positive integer (counter64) into 2x u32_t. + * + * @param pbuf_stream points to a pbuf stream + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets! + */ +err_t +snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value) +{ + u8_t data; + + if (len <= 4) { + /* high u32 is 0 */ + *value = 0; + /* directly skip to low u32 */ + value++; + } + + if ((len > 0) && (len <= 9)) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + + /* expecting sign bit to be zero, only unsigned please! */ + if (((len == 9) && (data == 0x00)) || ((len < 9) && ((data & 0x80) == 0))) { + *value = data; + len--; + + while (len > 0) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + + if (len == 4) { + /* skip to low u32 */ + value++; + *value = 0; + } else { + *value <<= 8; + } + + *value |= data; + len--; + } + + return ERR_OK; + } + } + + return ERR_VAL; +} + +/** + * Decodes integer into s32_t. + * + * @param pbuf_stream points to a pbuf stream + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed! + */ +err_t +snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value) +{ +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t *lsb_ptr = (u8_t*)value; +#endif +#if BYTE_ORDER == BIG_ENDIAN + u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; +#endif + u8_t sign; + u8_t data; + + if ((len > 0) && (len < 5)) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + + if (data & 0x80) { + /* negative, start from -1 */ + *value = -1; + sign = 1; + *lsb_ptr &= data; + } else { + /* positive, start from 0 */ + *value = 0; + sign = 0; + *lsb_ptr |= data; + } + + /* OR/AND octets with value */ + while (len > 0) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + +#if BYTE_ORDER == LITTLE_ENDIAN + *value <<= 8; +#endif +#if BYTE_ORDER == BIG_ENDIAN + *value >>= 8; +#endif + + if (sign) { + *lsb_ptr |= 255; + *lsb_ptr &= data; + } else { + *lsb_ptr |= data; + } + } + + return ERR_OK; + } + + return ERR_VAL; +} + +/** + * Decodes object identifier from incoming message into array of u32_t. + * + * @param pbuf_stream points to a pbuf stream + * @param len length of the coded object identifier + * @param oid return decoded object identifier + * @param oid_len return decoded object identifier length + * @param oid_max_len size of oid buffer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len) +{ + u32_t *oid_ptr; + u8_t data; + + *oid_len = 0; + oid_ptr = oid; + if (len > 0) { + if (oid_max_len < 2) { + return ERR_MEM; + } + + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + + /* first compressed octet */ + if (data == 0x2B) { + /* (most) common case 1.3 (iso.org) */ + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = 3; + oid_ptr++; + } else if (data < 40) { + *oid_ptr = 0; + oid_ptr++; + *oid_ptr = data; + oid_ptr++; + } else if (data < 80) { + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = data - 40; + oid_ptr++; + } else { + *oid_ptr = 2; + oid_ptr++; + *oid_ptr = data - 80; + oid_ptr++; + } + *oid_len = 2; + } else { + /* accepting zero length identifiers e.g. for getnext operation. uncommon but valid */ + return ERR_OK; + } + + while ((len > 0) && (*oid_len < oid_max_len)) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + + if ((data & 0x80) == 0x00) { + /* sub-identifier uses single octet */ + *oid_ptr = data; + } else { + /* sub-identifier uses multiple octets */ + u32_t sub_id = (data & ~0x80); + while ((len > 0) && ((data & 0x80) != 0)) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); + len--; + + sub_id = (sub_id << 7) + (data & ~0x80); + } + + if ((data & 0x80) != 0) { + /* "more bytes following" bit still set at end of len */ + return ERR_VAL; + } + *oid_ptr = sub_id; + } + oid_ptr++; + (*oid_len)++; + } + + if (len > 0) { + /* OID to long to fit in our buffer */ + return ERR_MEM; + } + + return ERR_OK; +} + +/** + * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) + * from incoming message into array. + * + * @param pbuf_stream points to a pbuf stream + * @param len length of the coded raw data (zero is valid, e.g. empty string!) + * @param buf return raw bytes + * @param buf_len returns length of the raw return value + * @param buf_max_len buffer size + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len) +{ + if (len > buf_max_len) { + /* not enough dst space */ + return ERR_MEM; + } + *buf_len = len; + + while (len > 0) { + PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, buf)); + buf++; + len--; + } + + return ERR_OK; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.h new file mode 100644 index 0000000..ec50d8c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_asn1.h @@ -0,0 +1,108 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel + * Elias Oenal + */ + +#ifndef LWIP_HDR_APPS_SNMP_ASN1_H +#define LWIP_HDR_APPS_SNMP_ASN1_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP + +#include "lwip/err.h" +#include "lwip/apps/snmp_core.h" +#include "snmp_pbuf_stream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_TLV_INDEFINITE_LENGTH 0x80 + +#define SNMP_ASN1_CLASS_MASK 0xC0 +#define SNMP_ASN1_CONTENTTYPE_MASK 0x20 +#define SNMP_ASN1_DATATYPE_MASK 0x1F +#define SNMP_ASN1_DATATYPE_EXTENDED 0x1F /* DataType indicating that datatype is encoded in following bytes */ + +/* context specific (SNMP) tags (from SNMP spec. RFC1157) */ +#define SNMP_ASN1_CONTEXT_PDU_GET_REQ 0 +#define SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_CONTEXT_PDU_GET_RESP 2 +#define SNMP_ASN1_CONTEXT_PDU_SET_REQ 3 +#define SNMP_ASN1_CONTEXT_PDU_TRAP 4 +#define SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ 5 + +#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT 0 +#define SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW 2 + +struct snmp_asn1_tlv +{ + u8_t type; /* only U8 because extended types are not specified by SNMP */ + u8_t type_len; /* encoded length of 'type' field (normally 1) */ + u8_t length_len; /* indicates how many bytes are required to encode the 'value_len' field */ + u16_t value_len; /* encoded length of the value */ +}; +#define SNMP_ASN1_TLV_HDR_LENGTH(tlv) ((tlv).type_len + (tlv).length_len) +#define SNMP_ASN1_TLV_LENGTH(tlv) ((tlv).type_len + (tlv).length_len + (tlv).value_len) +#define SNMP_ASN1_SET_TLV_PARAMS(tlv, type_, length_len_, value_len_) do { (tlv).type = (type_); (tlv).type_len = 0; (tlv).length_len = (length_len_); (tlv).value_len = (value_len_); } while (0); + +err_t snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv); +err_t snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value); +err_t snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len); +err_t snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len); + +err_t snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed); +err_t snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len); +err_t snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value); +err_t snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value); +err_t snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value); +err_t snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_APPS_SNMP_ASN1_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core.c new file mode 100644 index 0000000..c041833 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core.c @@ -0,0 +1,1349 @@ +/** + * @file + * MIB tree access/construction functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel +*/ + +/** + * @defgroup snmp SNMPv2c agent + * @ingroup apps + * SNMPv2c compatible agent\n + * There is also a MIB compiler and a MIB viewer in lwIP contrib repository + * (lwip-contrib/apps/LwipMibCompiler).\n + * The agent implements the most important MIB2 MIBs including IPv6 support + * (interfaces, UDP, TCP, SNMP, ICMP, SYSTEM). IP MIB is an older version + * whithout IPv6 statistics (TODO).\n + * Rewritten by Martin Hentschel and + * Dirk Ziegelmeier \n + * Work on SNMPv3 has started, but is not finished.\n + * + * 0 Agent Capabilities + * ==================== + * + * Features: + * --------- + * - SNMPv2c support. + * - Low RAM usage - no memory pools, stack only. + * - MIB2 implementation is separated from SNMP stack. + * - Support for multiple MIBs (snmp_set_mibs() call) - e.g. for private MIB. + * - Simple and generic API for MIB implementation. + * - Comfortable node types and helper functions for scalar arrays and tables. + * - Counter64, bit and truthvalue datatype support. + * - Callbacks for SNMP writes e.g. to implement persistency. + * - Runs on two APIs: RAW and netconn. + * - Async API is gone - the stack now supports netconn API instead, + * so blocking operations can be done in MIB calls. + * SNMP runs in a worker thread when netconn API is used. + * - Simplified thread sync support for MIBs - useful when MIBs + * need to access variables shared with other threads where no locking is + * possible. Used in MIB2 to access lwIP stats from lwIP thread. + * + * MIB compiler (code generator): + * ------------------------------ + * - Provided in lwIP contrib repository. + * - Written in C#. MIB viewer used Windows Forms. + * - Developed on Windows with Visual Studio 2010. + * - Can be compiled and used on all platforms with http://www.monodevelop.com/. + * - Based on a heavily modified version of of SharpSnmpLib (a4bd05c6afb4) + * (https://sharpsnmplib.codeplex.com/SourceControl/network/forks/Nemo157/MIBParserUpdate). + * - MIB parser, C file generation framework and LWIP code generation are cleanly + * separated, which means the code may be useful as a base for code generation + * of other SNMP agents. + * + * Notes: + * ------ + * - Stack and MIB compiler were used to implement a Profinet device. + * Compiled/implemented MIBs: LLDP-MIB, LLDP-EXT-DOT3-MIB, LLDP-EXT-PNO-MIB. + * + * SNMPv1 per RFC1157 and SNMPv2c per RFC 3416 + * ------------------------------------------- + * Note the S in SNMP stands for "Simple". Note that "Simple" is + * relative. SNMP is simple compared to the complex ISO network + * management protocols CMIP (Common Management Information Protocol) + * and CMOT (CMip Over Tcp). + * + * MIB II + * ------ + * The standard lwIP stack management information base. + * This is a required MIB, so this is always enabled. + * The groups EGP, CMOT and transmission are disabled by default. + * + * Most mib-2 objects are not writable except: + * sysName, sysLocation, sysContact, snmpEnableAuthenTraps. + * Writing to or changing the ARP and IP address and route + * tables is not possible. + * + * Note lwIP has a very limited notion of IP routing. It currently + * doen't have a route table and doesn't have a notion of the U,G,H flags. + * Instead lwIP uses the interface list with only one default interface + * acting as a single gateway interface (G) for the default route. + * + * The agent returns a "virtual table" with the default route 0.0.0.0 + * for the default interface and network routes (no H) for each + * network interface in the netif_list. + * All routes are considered to be up (U). + * + * Loading additional MIBs + * ----------------------- + * MIBs can only be added in compile-time, not in run-time. + * + * + * 1 Building the Agent + * ==================== + * First of all you'll need to add the following define + * to your local lwipopts.h: + * \#define LWIP_SNMP 1 + * + * and add the source files your makefile. + * + * Note you'll might need to adapt you network driver to update + * the mib2 variables for your interface. + * + * 2 Running the Agent + * =================== + * The following function calls must be made in your program to + * actually get the SNMP agent running. + * + * Before starting the agent you should supply pointers + * for sysContact, sysLocation, and snmpEnableAuthenTraps. + * You can do this by calling + * + * - snmp_mib2_set_syscontact() + * - snmp_mib2_set_syslocation() + * - snmp_set_auth_traps_enabled() + * + * You can register a callback which is called on successful write access: + * snmp_set_write_callback(). + * + * Additionally you may want to set + * + * - snmp_mib2_set_sysdescr() + * - snmp_set_device_enterprise_oid() + * - snmp_mib2_set_sysname() + * + * Also before starting the agent you need to setup + * one or more trap destinations using these calls: + * + * - snmp_trap_dst_enable() + * - snmp_trap_dst_ip_set() + * + * If you need more than MIB2, set the MIBs you want to use + * by snmp_set_mibs(). + * + * Finally, enable the agent by calling snmp_init() + * + * @defgroup snmp_core Core + * @ingroup snmp + * + * @defgroup snmp_traps Traps + * @ingroup snmp + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "snmp_core_priv.h" +#include "lwip/netif.h" +#include + + +#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) + #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif + +struct snmp_statistics snmp_stats; +static const struct snmp_obj_id snmp_device_enterprise_oid_default = {SNMP_DEVICE_ENTERPRISE_OID_LEN, SNMP_DEVICE_ENTERPRISE_OID}; +static const struct snmp_obj_id* snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default; + +const u32_t snmp_zero_dot_zero_values[] = { 0, 0 }; +const struct snmp_obj_id_const_ref snmp_zero_dot_zero = { LWIP_ARRAYSIZE(snmp_zero_dot_zero_values), snmp_zero_dot_zero_values }; + + +#if SNMP_LWIP_MIB2 +#include "lwip/apps/snmp_mib2.h" +static const struct snmp_mib* const default_mibs[] = { &mib2 }; +static u8_t snmp_num_mibs = 1; +#else +static const struct snmp_mib* const default_mibs[] = { NULL }; +static u8_t snmp_num_mibs = 0; +#endif + +/* List of known mibs */ +static struct snmp_mib const * const *snmp_mibs = default_mibs; + +/** + * @ingroup snmp_core + * Sets the MIBs to use. + * Example: call snmp_set_mibs() as follows: + * static const struct snmp_mib *my_snmp_mibs[] = { + * &mib2, + * &private_mib + * }; + * snmp_set_mibs(my_snmp_mibs, LWIP_ARRAYSIZE(my_snmp_mibs)); + */ +void +snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs) +{ + LWIP_ASSERT("mibs pointer must be != NULL", (mibs != NULL)); + LWIP_ASSERT("num_mibs pointer must be != 0", (num_mibs != 0)); + snmp_mibs = mibs; + snmp_num_mibs = num_mibs; +} + +/** + * @ingroup snmp_core + * 'device enterprise oid' is used for 'device OID' field in trap PDU's (for identification of generating device) + * as well as for value returned by MIB-2 'sysObjectID' field (if internal MIB2 implementation is used). + * The 'device enterprise oid' shall point to an OID located under 'private-enterprises' branch (1.3.6.1.4.1.XXX). If a vendor + * wants to provide a custom object there, he has to get its own enterprise oid from IANA (http://www.iana.org). It + * is not allowed to use LWIP enterprise ID! + * In order to identify a specific device it is recommended to create a dedicated OID for each device type under its own + * enterprise oid. + * e.g. + * device a > 1.3.6.1.4.1.XXX(ent-oid).1(devices).1(device a) + * device b > 1.3.6.1.4.1.XXX(ent-oid).1(devices).2(device b) + * for more details see description of 'sysObjectID' field in RFC1213-MIB + */ +void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid) +{ + if (device_enterprise_oid == NULL) { + snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default; + } else { + snmp_device_enterprise_oid = device_enterprise_oid; + } +} + +/** + * @ingroup snmp_core + * Get 'device enterprise oid' + */ +const struct snmp_obj_id* snmp_get_device_enterprise_oid(void) +{ + return snmp_device_enterprise_oid; +} + +#if LWIP_IPV4 +/** + * Conversion from InetAddressIPv4 oid to lwIP ip4_addr + * @param oid points to u32_t ident[4] input + * @param ip points to output struct + */ +u8_t +snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip) +{ + if ((oid[0] > 0xFF) || + (oid[1] > 0xFF) || + (oid[2] > 0xFF) || + (oid[3] > 0xFF)) { + ip4_addr_copy(*ip, *IP4_ADDR_ANY4); + return 0; + } + + IP4_ADDR(ip, oid[0], oid[1], oid[2], oid[3]); + return 1; +} + +/** + * Convert ip4_addr to InetAddressIPv4 (no InetAddressType) + * @param ip points to input struct + * @param oid points to u32_t ident[4] output + */ +void +snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid) +{ + oid[0] = ip4_addr1(ip); + oid[1] = ip4_addr2(ip); + oid[2] = ip4_addr3(ip); + oid[3] = ip4_addr4(ip); +} +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 +/** + * Conversion from InetAddressIPv6 oid to lwIP ip6_addr + * @param oid points to u32_t oid[16] input + * @param ip points to output struct + */ +u8_t +snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip) +{ + if ((oid[0] > 0xFF) || + (oid[1] > 0xFF) || + (oid[2] > 0xFF) || + (oid[3] > 0xFF) || + (oid[4] > 0xFF) || + (oid[5] > 0xFF) || + (oid[6] > 0xFF) || + (oid[7] > 0xFF) || + (oid[8] > 0xFF) || + (oid[9] > 0xFF) || + (oid[10] > 0xFF) || + (oid[11] > 0xFF) || + (oid[12] > 0xFF) || + (oid[13] > 0xFF) || + (oid[14] > 0xFF) || + (oid[15] > 0xFF)) { + ip6_addr_set_any(ip); + return 0; + } + + ip->addr[0] = (oid[0] << 24) | (oid[1] << 16) | (oid[2] << 8) | (oid[3] << 0); + ip->addr[1] = (oid[4] << 24) | (oid[5] << 16) | (oid[6] << 8) | (oid[7] << 0); + ip->addr[2] = (oid[8] << 24) | (oid[9] << 16) | (oid[10] << 8) | (oid[11] << 0); + ip->addr[3] = (oid[12] << 24) | (oid[13] << 16) | (oid[14] << 8) | (oid[15] << 0); + return 1; +} + +/** + * Convert ip6_addr to InetAddressIPv6 (no InetAddressType) + * @param ip points to input struct + * @param oid points to u32_t ident[16] output + */ +void +snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid) +{ + oid[0] = (ip->addr[0] & 0xFF000000) >> 24; + oid[1] = (ip->addr[0] & 0x00FF0000) >> 16; + oid[2] = (ip->addr[0] & 0x0000FF00) >> 8; + oid[3] = (ip->addr[0] & 0x000000FF) >> 0; + oid[4] = (ip->addr[1] & 0xFF000000) >> 24; + oid[5] = (ip->addr[1] & 0x00FF0000) >> 16; + oid[6] = (ip->addr[1] & 0x0000FF00) >> 8; + oid[7] = (ip->addr[1] & 0x000000FF) >> 0; + oid[8] = (ip->addr[2] & 0xFF000000) >> 24; + oid[9] = (ip->addr[2] & 0x00FF0000) >> 16; + oid[10] = (ip->addr[2] & 0x0000FF00) >> 8; + oid[11] = (ip->addr[2] & 0x000000FF) >> 0; + oid[12] = (ip->addr[3] & 0xFF000000) >> 24; + oid[13] = (ip->addr[3] & 0x00FF0000) >> 16; + oid[14] = (ip->addr[3] & 0x0000FF00) >> 8; + oid[15] = (ip->addr[3] & 0x000000FF) >> 0; +} +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV4 || LWIP_IPV6 +/** + * Convert to InetAddressType+InetAddress+InetPortNumber + * @param ip IP address + * @param port Port + * @param oid OID + * @return OID length + */ +u8_t +snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid) +{ + u8_t idx; + + idx = snmp_ip_to_oid(ip, oid); + oid[idx] = port; + idx++; + + return idx; +} + +/** + * Convert to InetAddressType+InetAddress + * @param ip IP address + * @param oid OID + * @return OID length + */ +u8_t +snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid) +{ + if (IP_IS_ANY_TYPE_VAL(*ip)) { + oid[0] = 0; /* any */ + oid[1] = 0; /* no IP OIDs follow */ + return 2; + } else if (IP_IS_V6(ip)) { +#if LWIP_IPV6 + oid[0] = 2; /* ipv6 */ + oid[1] = 16; /* 16 InetAddressIPv6 OIDs follow */ + snmp_ip6_to_oid(ip_2_ip6(ip), &oid[2]); + return 18; +#else /* LWIP_IPV6 */ + return 0; +#endif /* LWIP_IPV6 */ + } else { +#if LWIP_IPV4 + oid[0] = 1; /* ipv4 */ + oid[1] = 4; /* 4 InetAddressIPv4 OIDs follow */ + snmp_ip4_to_oid(ip_2_ip4(ip), &oid[2]); + return 6; +#else /* LWIP_IPV4 */ + return 0; +#endif /* LWIP_IPV4 */ + } +} + +/** + * Convert from InetAddressType+InetAddress to ip_addr_t + * @param oid OID + * @param oid_len OID length + * @param ip IP address + * @return Parsed OID length + */ +u8_t +snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip) +{ + /* InetAddressType */ + if (oid_len < 1) { + return 0; + } + + if (oid[0] == 0) { /* any */ + /* 1x InetAddressType, 1x OID len */ + if (oid_len < 2) { + return 0; + } + if (oid[1] != 0) { + return 0; + } + + memset(ip, 0, sizeof(*ip)); + IP_SET_TYPE(ip, IPADDR_TYPE_ANY); + + return 2; + } else if (oid[0] == 1) { /* ipv4 */ +#if LWIP_IPV4 + /* 1x InetAddressType, 1x OID len, 4x InetAddressIPv4 */ + if (oid_len < 6) { + return 0; + } + + /* 4x ipv4 OID */ + if (oid[1] != 4) { + return 0; + } + + IP_SET_TYPE(ip, IPADDR_TYPE_V4); + if (!snmp_oid_to_ip4(&oid[2], ip_2_ip4(ip))) { + return 0; + } + + return 6; +#else /* LWIP_IPV4 */ + return 0; +#endif /* LWIP_IPV4 */ + } else if (oid[0] == 2) { /* ipv6 */ +#if LWIP_IPV6 + /* 1x InetAddressType, 1x OID len, 16x InetAddressIPv6 */ + if (oid_len < 18) { + return 0; + } + + /* 16x ipv6 OID */ + if (oid[1] != 16) { + return 0; + } + + IP_SET_TYPE(ip, IPADDR_TYPE_V6); + if (!snmp_oid_to_ip6(&oid[2], ip_2_ip6(ip))) { + return 0; + } + + return 18; +#else /* LWIP_IPV6 */ + return 0; +#endif /* LWIP_IPV6 */ + } else { /* unsupported InetAddressType */ + return 0; + } +} + +/** + * Convert from InetAddressType+InetAddress+InetPortNumber to ip_addr_t and u16_t + * @param oid OID + * @param oid_len OID length + * @param ip IP address + * @param port Port + * @return Parsed OID length + */ +u8_t +snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port) +{ + u8_t idx = 0; + + /* InetAddressType + InetAddress */ + idx += snmp_oid_to_ip(&oid[idx], oid_len-idx, ip); + if (idx == 0) { + return 0; + } + + /* InetPortNumber */ + if (oid_len < (idx+1)) { + return 0; + } + if (oid[idx] > 0xffff) { + return 0; + } + *port = (u16_t)oid[idx]; + idx++; + + return idx; +} + +#endif /* LWIP_IPV4 || LWIP_IPV6 */ + +/** + * Assign an OID to struct snmp_obj_id + * @param target Assignment target + * @param oid OID + * @param oid_len OID length + */ +void +snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) +{ + LWIP_ASSERT("oid_len <= LWIP_SNMP_OBJ_ID_LEN", oid_len <= SNMP_MAX_OBJ_ID_LEN); + + target->len = oid_len; + + if (oid_len > 0) { + MEMCPY(target->id, oid, oid_len * sizeof(u32_t)); + } +} + +/** + * Prefix an OID to OID in struct snmp_obj_id + * @param target Assignment target to prefix + * @param oid OID + * @param oid_len OID length + */ +void +snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) +{ + LWIP_ASSERT("target->len + oid_len <= LWIP_SNMP_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN); + + if (oid_len > 0) { + /* move existing OID to make room at the beginning for OID to insert */ + int i; + for (i = target->len-1; i>=0; i--) { + target->id[i + oid_len] = target->id[i]; + } + + /* paste oid at the beginning */ + MEMCPY(target->id, oid, oid_len * sizeof(u32_t)); + } +} + +/** + * Combine two OIDs into struct snmp_obj_id + * @param target Assignmet target + * @param oid1 OID 1 + * @param oid1_len OID 1 length + * @param oid2 OID 2 + * @param oid2_len OID 2 length + */ +void +snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) +{ + snmp_oid_assign(target, oid1, oid1_len); + snmp_oid_append(target, oid2, oid2_len); +} + +/** + * Append OIDs to struct snmp_obj_id + * @param target Assignment target to append to + * @param oid OID + * @param oid_len OID length + */ +void +snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) +{ + LWIP_ASSERT("offset + oid_len <= LWIP_SNMP_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN); + + if (oid_len > 0) { + MEMCPY(&target->id[target->len], oid, oid_len * sizeof(u32_t)); + target->len += oid_len; + } +} + +/** + * Compare two OIDs + * @param oid1 OID 1 + * @param oid1_len OID 1 length + * @param oid2 OID 2 + * @param oid2_len OID 2 length + * @return -1: OID1<OID2 1: OID1 >OID2 0: equal + */ +s8_t +snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) +{ + u8_t level = 0; + LWIP_ASSERT("'oid1' param must not be NULL or 'oid1_len' param be 0!", (oid1 != NULL) || (oid1_len == 0)); + LWIP_ASSERT("'oid2' param must not be NULL or 'oid2_len' param be 0!", (oid2 != NULL) || (oid2_len == 0)); + + while ((level < oid1_len) && (level < oid2_len)) { + if (*oid1 < *oid2) { + return -1; + } + if (*oid1 > *oid2) { + return 1; + } + + level++; + oid1++; + oid2++; + } + + /* common part of both OID's is equal, compare length */ + if (oid1_len < oid2_len) { + return -1; + } + if (oid1_len > oid2_len) { + return 1; + } + + /* they are equal */ + return 0; +} + + +/** + * Check of two OIDs are equal + * @param oid1 OID 1 + * @param oid1_len OID 1 length + * @param oid2 OID 2 + * @param oid2_len OID 2 length + * @return 1: equal 0: non-equal + */ +u8_t +snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) +{ + return (snmp_oid_compare(oid1, oid1_len, oid2, oid2_len) == 0)? 1 : 0; +} + +/** + * Convert netif to interface index + * @param netif netif + * @return index + */ +u8_t +netif_to_num(const struct netif *netif) +{ + u8_t result = 0; + struct netif *netif_iterator = netif_list; + + while (netif_iterator != NULL) { + result++; + + if (netif_iterator == netif) { + return result; + } + + netif_iterator = netif_iterator->next; + } + + LWIP_ASSERT("netif not found in netif_list", 0); + return 0; +} + +static const struct snmp_mib* +snmp_get_mib_from_oid(const u32_t *oid, u8_t oid_len) +{ + const u32_t* list_oid; + const u32_t* searched_oid; + u8_t i, l; + + u8_t max_match_len = 0; + const struct snmp_mib* matched_mib = NULL; + + LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL)); + + if (oid_len == 0) { + return NULL; + } + + for (i = 0; i < snmp_num_mibs; i++) { + LWIP_ASSERT("MIB array not initialized correctly", (snmp_mibs[i] != NULL)); + LWIP_ASSERT("MIB array not initialized correctly - base OID is NULL", (snmp_mibs[i]->base_oid != NULL)); + + if (oid_len >= snmp_mibs[i]->base_oid_len) { + l = snmp_mibs[i]->base_oid_len; + list_oid = snmp_mibs[i]->base_oid; + searched_oid = oid; + + while (l > 0) { + if (*list_oid != *searched_oid) { + break; + } + + l--; + list_oid++; + searched_oid++; + } + + if ((l == 0) && (snmp_mibs[i]->base_oid_len > max_match_len)) { + max_match_len = snmp_mibs[i]->base_oid_len; + matched_mib = snmp_mibs[i]; + } + } + } + + return matched_mib; +} + +static const struct snmp_mib* +snmp_get_next_mib(const u32_t *oid, u8_t oid_len) +{ + u8_t i; + const struct snmp_mib* next_mib = NULL; + + LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL)); + + if (oid_len == 0) { + return NULL; + } + + for (i = 0; i < snmp_num_mibs; i++) { + if (snmp_mibs[i]->base_oid != NULL) { + /* check if mib is located behind starting point */ + if (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len, oid, oid_len) > 0) { + if ((next_mib == NULL) || + (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len, + next_mib->base_oid, next_mib->base_oid_len) < 0)) { + next_mib = snmp_mibs[i]; + } + } + } + } + + return next_mib; +} + +static const struct snmp_mib* +snmp_get_mib_between(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) +{ + const struct snmp_mib* next_mib = snmp_get_next_mib(oid1, oid1_len); + + LWIP_ASSERT("'oid2' param must not be NULL!", (oid2 != NULL)); + LWIP_ASSERT("'oid2_len' param must be greater than 0!", (oid2_len > 0)); + + if (next_mib != NULL) { + if (snmp_oid_compare(next_mib->base_oid, next_mib->base_oid_len, oid2, oid2_len) < 0) { + return next_mib; + } + } + + return NULL; +} + +u8_t +snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance* node_instance) +{ + u8_t result = SNMP_ERR_NOSUCHOBJECT; + const struct snmp_mib *mib; + const struct snmp_node *mn = NULL; + + mib = snmp_get_mib_from_oid(oid, oid_len); + if (mib != NULL) { + u8_t oid_instance_len; + + mn = snmp_mib_tree_resolve_exact(mib, oid, oid_len, &oid_instance_len); + if ((mn != NULL) && (mn->node_type != SNMP_NODE_TREE)) { + /* get instance */ + const struct snmp_leaf_node* leaf_node = (const struct snmp_leaf_node*)(const void*)mn; + + node_instance->node = mn; + snmp_oid_assign(&node_instance->instance_oid, oid + (oid_len - oid_instance_len), oid_instance_len); + + result = leaf_node->get_instance( + oid, + oid_len - oid_instance_len, + node_instance); + +#ifdef LWIP_DEBUG + if (result == SNMP_ERR_NOERROR) { + if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) { + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n")); + } + if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) { + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value and/or set_test function is specified\n")); + } + } +#endif + } + } + + return result; +} + +u8_t +snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void* validate_node_instance_arg, struct snmp_obj_id* node_oid, struct snmp_node_instance* node_instance) +{ + const struct snmp_mib *mib; + const struct snmp_node *mn = NULL; + const u32_t* start_oid = NULL; + u8_t start_oid_len = 0; + + /* resolve target MIB from passed OID */ + mib = snmp_get_mib_from_oid(oid, oid_len); + if (mib == NULL) { + /* passed OID does not reference any known MIB, start at the next closest MIB */ + mib = snmp_get_next_mib(oid, oid_len); + + if (mib != NULL) { + start_oid = mib->base_oid; + start_oid_len = mib->base_oid_len; + } + } else { + start_oid = oid; + start_oid_len = oid_len; + } + + /* resolve target node from MIB, skip to next MIB if no suitable node is found in current MIB */ + while ((mib != NULL) && (mn == NULL)) { + u8_t oid_instance_len; + + /* check if OID directly references a node inside current MIB, in this case we have to ask this node for the next instance */ + mn = snmp_mib_tree_resolve_exact(mib, start_oid, start_oid_len, &oid_instance_len); + if (mn != NULL) { + snmp_oid_assign(node_oid, start_oid, start_oid_len - oid_instance_len); /* set oid to node */ + snmp_oid_assign(&node_instance->instance_oid, start_oid + (start_oid_len - oid_instance_len), oid_instance_len); /* set (relative) instance oid */ + } else { + /* OID does not reference a node, search for the next closest node inside MIB; set instance_oid.len to zero because we want the first instance of this node */ + mn = snmp_mib_tree_resolve_next(mib, start_oid, start_oid_len, node_oid); + node_instance->instance_oid.len = 0; + } + + /* validate the node; if the node has no further instance or the returned instance is invalid, search for the next in MIB and validate again */ + node_instance->node = mn; + while (mn != NULL) { + u8_t result; + + /* clear fields which may have values from previous loops */ + node_instance->asn1_type = 0; + node_instance->access = SNMP_NODE_INSTANCE_NOT_ACCESSIBLE; + node_instance->get_value = NULL; + node_instance->set_test = NULL; + node_instance->set_value = NULL; + node_instance->release_instance = NULL; + node_instance->reference.ptr = NULL; + node_instance->reference_len = 0; + + result = ((const struct snmp_leaf_node*)(const void*)mn)->get_next_instance( + node_oid->id, + node_oid->len, + node_instance); + + if (result == SNMP_ERR_NOERROR) { +#ifdef LWIP_DEBUG + if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) { + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n")); + } + if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) { + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value function is specified\n")); + } +#endif + + /* validate node because the node may be not accessible for example (but let the caller decide what is valid */ + if ((validate_node_instance_method == NULL) || + (validate_node_instance_method(node_instance, validate_node_instance_arg) == SNMP_ERR_NOERROR)) { + /* node_oid "returns" the full result OID (including the instance part) */ + snmp_oid_append(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len); + break; + } + + if (node_instance->release_instance != NULL) { + node_instance->release_instance(node_instance); + } + /* + the instance itself is not valid, ask for next instance from same node. + we don't have to change any variables because node_instance->instance_oid is used as input (starting point) + as well as output (resulting next OID), so we have to simply call get_next_instance method again + */ + } else { + if (node_instance->release_instance != NULL) { + node_instance->release_instance(node_instance); + } + + /* the node has no further instance, skip to next node */ + mn = snmp_mib_tree_resolve_next(mib, node_oid->id, node_oid->len, &node_instance->instance_oid); /* misuse node_instance->instance_oid as tmp buffer */ + if (mn != NULL) { + /* prepare for next loop */ + snmp_oid_assign(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len); + node_instance->instance_oid.len = 0; + node_instance->node = mn; + } + } + } + + if (mn != NULL) { + /* + we found a suitable next node, + now we have to check if a inner MIB is located between the searched OID and the resulting OID. + this is possible because MIB's may be located anywhere in the global tree, that means also in + the subtree of another MIB (e.g. if searched OID is .2 and resulting OID is .4, then another + MIB having .3 as root node may exist) + */ + const struct snmp_mib *intermediate_mib; + intermediate_mib = snmp_get_mib_between(start_oid, start_oid_len, node_oid->id, node_oid->len); + + if (intermediate_mib != NULL) { + /* search for first node inside intermediate mib in next loop */ + if (node_instance->release_instance != NULL) { + node_instance->release_instance(node_instance); + } + + mn = NULL; + mib = intermediate_mib; + start_oid = mib->base_oid; + start_oid_len = mib->base_oid_len; + } + /* else { we found out target node } */ + } else { + /* + there is no further (suitable) node inside this MIB, search for the next MIB with following priority + 1. search for inner MIB's (whose root is located inside tree of current MIB) + 2. search for surrouding MIB's (where the current MIB is the inner MIB) and continue there if any + 3. take the next closest MIB (not being related to the current MIB) + */ + const struct snmp_mib *next_mib; + next_mib = snmp_get_next_mib(start_oid, start_oid_len); /* returns MIB's related to point 1 and 3 */ + + /* is the found MIB an inner MIB? (point 1) */ + if ((next_mib != NULL) && (next_mib->base_oid_len > mib->base_oid_len) && + (snmp_oid_compare(next_mib->base_oid, mib->base_oid_len, mib->base_oid, mib->base_oid_len) == 0)) { + /* yes it is -> continue at inner MIB */ + mib = next_mib; + start_oid = mib->base_oid; + start_oid_len = mib->base_oid_len; + } else { + /* check if there is a surrounding mib where to continue (point 2) (only possible if OID length > 1) */ + if (mib->base_oid_len > 1) { + mib = snmp_get_mib_from_oid(mib->base_oid, mib->base_oid_len - 1); + + if (mib == NULL) { + /* no surrounding mib, use next mib encountered above (point 3) */ + mib = next_mib; + + if (mib != NULL) { + start_oid = mib->base_oid; + start_oid_len = mib->base_oid_len; + } + } + /* else { start_oid stays the same because we want to continue from current offset in surrounding mib (point 2) } */ + } + } + } + } + + if (mib == NULL) { + /* loop is only left when mib == null (error) or mib_node != NULL (success) */ + return SNMP_ERR_ENDOFMIBVIEW; + } + + return SNMP_ERR_NOERROR; +} + +/** + * Searches tree for the supplied object identifier. + * + */ +const struct snmp_node * +snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t* oid_instance_len) +{ + const struct snmp_node* const* node = &mib->root_node; + u8_t oid_offset = mib->base_oid_len; + + while ((oid_offset < oid_len) && ((*node)->node_type == SNMP_NODE_TREE)) { + /* search for matching sub node */ + u32_t subnode_oid = *(oid + oid_offset); + + u32_t i = (*(const struct snmp_tree_node* const*)node)->subnode_count; + node = (*(const struct snmp_tree_node* const*)node)->subnodes; + while ((i > 0) && ((*node)->oid != subnode_oid)) { + node++; + i--; + } + + if (i == 0) { + /* no matching subnode found */ + return NULL; + } + + oid_offset++; + } + + if ((*node)->node_type != SNMP_NODE_TREE) { + /* we found a leaf node */ + *oid_instance_len = oid_len - oid_offset; + return (*node); + } + + return NULL; +} + +const struct snmp_node* +snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id* oidret) +{ + u8_t oid_offset = mib->base_oid_len; + const struct snmp_node* const* node; + const struct snmp_tree_node* node_stack[SNMP_MAX_OBJ_ID_LEN]; + s32_t nsi = 0; /* NodeStackIndex */ + u32_t subnode_oid; + + if (mib->root_node->node_type != SNMP_NODE_TREE) { + /* a next operation on a mib with only a leaf node will always return NULL because there is no other node */ + return NULL; + } + + /* first build node stack related to passed oid (as far as possible), then go backwards to determine the next node */ + node_stack[nsi] = (const struct snmp_tree_node*)(const void*)mib->root_node; + while (oid_offset < oid_len) { + /* search for matching sub node */ + u32_t i = node_stack[nsi]->subnode_count; + node = node_stack[nsi]->subnodes; + + subnode_oid = *(oid + oid_offset); + + while ((i > 0) && ((*node)->oid != subnode_oid)) { + node++; + i--; + } + + if ((i == 0) || ((*node)->node_type != SNMP_NODE_TREE)) { + /* no (matching) tree-subnode found */ + break; + } + nsi++; + node_stack[nsi] = (const struct snmp_tree_node*)(const void*)(*node); + + oid_offset++; + } + + + if (oid_offset >= oid_len) { + /* passed oid references a tree node -> return first useable sub node of it */ + subnode_oid = 0; + } else { + subnode_oid = *(oid + oid_offset) + 1; + } + + while (nsi >= 0) { + const struct snmp_node* subnode = NULL; + + /* find next node on current level */ + s32_t i = node_stack[nsi]->subnode_count; + node = node_stack[nsi]->subnodes; + while (i > 0) { + if ((*node)->oid == subnode_oid) { + subnode = *node; + break; + } else if (((*node)->oid > subnode_oid) && ((subnode == NULL) || ((*node)->oid < subnode->oid))) { + subnode = *node; + } + + node++; + i--; + } + + if (subnode == NULL) { + /* no further node found on this level, go one level up and start searching with index of current node*/ + subnode_oid = node_stack[nsi]->node.oid + 1; + nsi--; + } else { + if (subnode->node_type == SNMP_NODE_TREE) { + /* next is a tree node, go into it and start searching */ + nsi++; + node_stack[nsi] = (const struct snmp_tree_node*)(const void*)subnode; + subnode_oid = 0; + } else { + /* we found a leaf node -> fill oidret and return it */ + snmp_oid_assign(oidret, mib->base_oid, mib->base_oid_len); + i = 1; + while (i <= nsi) { + oidret->id[oidret->len] = node_stack[i]->node.oid; + oidret->len++; + i++; + } + + oidret->id[oidret->len] = subnode->oid; + oidret->len++; + + return subnode; + } + } + } + + return NULL; +} + +/** initialize struct next_oid_state using this function before passing it to next_oid_check */ +void +snmp_next_oid_init(struct snmp_next_oid_state *state, + const u32_t *start_oid, u8_t start_oid_len, + u32_t *next_oid_buf, u8_t next_oid_max_len) +{ + state->start_oid = start_oid; + state->start_oid_len = start_oid_len; + state->next_oid = next_oid_buf; + state->next_oid_len = 0; + state->next_oid_max_len = next_oid_max_len; + state->status = SNMP_NEXT_OID_STATUS_NO_MATCH; +} + +/** checks if the passed incomplete OID may be a possible candidate for snmp_next_oid_check(); +this methid is intended if the complete OID is not yet known but it is very expensive to build it up, +so it is possible to test the starting part before building up the complete oid and pass it to snmp_next_oid_check()*/ +u8_t +snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len) +{ + if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) { + u8_t start_oid_len = (oid_len < state->start_oid_len) ? oid_len : state->start_oid_len; + + /* check passed OID is located behind start offset */ + if (snmp_oid_compare(oid, oid_len, state->start_oid, start_oid_len) >= 0) { + /* check if new oid is located closer to start oid than current closest oid */ + if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) || + (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) { + return 1; + } + } + } + + return 0; +} + +/** checks the passed OID if it is a candidate to be the next one (get_next); returns !=0 if passed oid is currently closest, otherwise 0 */ +u8_t +snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference) +{ + /* do not overwrite a fail result */ + if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) { + /* check passed OID is located behind start offset */ + if (snmp_oid_compare(oid, oid_len, state->start_oid, state->start_oid_len) > 0) { + /* check if new oid is located closer to start oid than current closest oid */ + if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) || + (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) { + if (oid_len <= state->next_oid_max_len) { + MEMCPY(state->next_oid, oid, oid_len * sizeof(u32_t)); + state->next_oid_len = oid_len; + state->status = SNMP_NEXT_OID_STATUS_SUCCESS; + state->reference = reference; + return 1; + } else { + state->status = SNMP_NEXT_OID_STATUS_BUF_TO_SMALL; + } + } + } + } + + return 0; +} + +u8_t +snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len) +{ + u8_t i; + + if (oid_len != oid_ranges_len) { + return 0; + } + + for (i = 0; i < oid_ranges_len; i++) { + if ((oid_in[i] < oid_ranges[i].min) || (oid_in[i] > oid_ranges[i].max)) { + return 0; + } + } + + return 1; +} + +snmp_err_t +snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value) +{ + LWIP_UNUSED_ARG(instance); + LWIP_UNUSED_ARG(value_len); + LWIP_UNUSED_ARG(value); + + return SNMP_ERR_NOERROR; +} + +/** + * Decodes BITS pseudotype value from ASN.1 OctetString. + * + * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly + * be encoded/decoded by the agent. Instead call this function as required from + * get/test/set methods. + * + * @param buf points to a buffer holding the ASN1 octet string + * @param buf_len length of octet string + * @param bit_value decoded Bit value with Bit0 == LSB + * @return ERR_OK if successful, ERR_ARG if bit value contains more than 32 bit + */ +err_t +snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value) +{ + u8_t b; + u8_t bits_processed = 0; + *bit_value = 0; + + while (buf_len > 0) { + /* any bit set in this byte? */ + if (*buf != 0x00) { + if (bits_processed >= 32) { + /* accept more than 4 bytes, but only when no bits are set */ + return ERR_VAL; + } + + b = *buf; + do { + if (b & 0x80) { + *bit_value |= (1 << bits_processed); + } + bits_processed++; + b <<= 1; + } + while ((bits_processed & 0x07) != 0); /* &0x07 -> % 8 */ + } else { + bits_processed += 8; + } + + buf_len--; + buf++; + } + + return ERR_OK; +} + +err_t +snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value) +{ + /* defined by RFC1443: + TruthValue ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "Represents a boolean value." + SYNTAX INTEGER { true(1), false(2) } + */ + + if ((asn1_value == NULL) || (bool_value == NULL)) { + return ERR_ARG; + } + + if (*asn1_value == 1) { + *bool_value = 1; + } else if (*asn1_value == 2) { + *bool_value = 0; + } else { + return ERR_VAL; + } + + return ERR_OK; +} + +/** + * Encodes BITS pseudotype value into ASN.1 OctetString. + * + * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly + * be encoded/decoded by the agent. Instead call this function as required from + * get/test/set methods. + * + * @param buf points to a buffer where the resulting ASN1 octet string is stored to + * @param buf_len max length of the bufffer + * @param bit_value Bit value to encode with Bit0 == LSB + * @param bit_count Number of possible bits for the bit value (according to rfc we have to send all bits independant from their truth value) + * @return number of bytes used from buffer to store the resulting OctetString + */ +u8_t +snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count) +{ + u8_t len = 0; + u8_t min_bytes = (bit_count + 7) >> 3; /* >>3 -> / 8 */ + + while ((buf_len > 0) && (bit_value != 0x00)) { + s8_t i = 7; + *buf = 0x00; + while (i >= 0) { + if (bit_value & 0x01) { + *buf |= 0x01; + } + + if (i > 0) { + *buf <<= 1; + } + + bit_value >>= 1; + i--; + } + + buf++; + buf_len--; + len++; + } + + if (len < min_bytes) { + buf += len; + buf_len -= len; + + while ((len < min_bytes) && (buf_len > 0)) { + *buf = 0x00; + buf++; + buf_len--; + len++; + } + } + + return len; +} + +u8_t +snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value) +{ + /* defined by RFC1443: + TruthValue ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "Represents a boolean value." + SYNTAX INTEGER { true(1), false(2) } + */ + + if (asn1_value == NULL) { + return 0; + } + + if (bool_value) { + *asn1_value = 1; /* defined by RFC1443 */ + } else { + *asn1_value = 2; /* defined by RFC1443 */ + } + + return sizeof(s32_t); +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core_priv.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core_priv.h new file mode 100644 index 0000000..5552177 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_core_priv.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#ifndef LWIP_HDR_APPS_SNMP_CORE_PRIV_H +#define LWIP_HDR_APPS_SNMP_CORE_PRIV_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp_core.h" +#include "snmp_asn1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* (outdated) SNMPv1 error codes + * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request + */ +#define SNMP_ERR_NOSUCHNAME 2 +#define SNMP_ERR_BADVALUE 3 +#define SNMP_ERR_READONLY 4 +/* error codes which are internal and shall not be used by MIBS + * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request + */ +#define SNMP_ERR_TOOBIG 1 +#define SNMP_ERR_AUTHORIZATIONERROR 16 +#define SNMP_ERR_NOSUCHOBJECT SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT +#define SNMP_ERR_ENDOFMIBVIEW SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW + + +const struct snmp_node* snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t* oid_instance_len); +const struct snmp_node* snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id* oidret); + +typedef u8_t (*snmp_validate_node_instance_method)(struct snmp_node_instance*, void*); + +u8_t snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance* node_instance); +u8_t snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void* validate_node_instance_arg, struct snmp_obj_id* node_oid, struct snmp_node_instance* node_instance); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_APPS_SNMP_CORE_PRIV_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2.c new file mode 100644 index 0000000..9d8c43c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2.c @@ -0,0 +1,116 @@ +/** + * @file + * Management Information Base II (RFC1213) objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +/** + * @defgroup snmp_mib2 MIB2 + * @ingroup snmp + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP && SNMP_LWIP_MIB2 /* don't build if not configured for use in lwipopts.h */ + +#if !LWIP_STATS +#error LWIP_SNMP MIB2 needs LWIP_STATS (for MIB2) +#endif +#if !MIB2_STATS +#error LWIP_SNMP MIB2 needs MIB2_STATS (for MIB2) +#endif + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_scalar.h" + +#if SNMP_USE_NETCONN +#include "lwip/tcpip.h" +#include "lwip/priv/tcpip_priv.h" +void +snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg) +{ +#if LWIP_TCPIP_CORE_LOCKING + LOCK_TCPIP_CORE(); + fn(arg); + UNLOCK_TCPIP_CORE(); +#else + tcpip_callback(fn, arg); +#endif +} + +struct snmp_threadsync_instance snmp_mib2_lwip_locks; +#endif + +/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ +/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ +/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ + +/* --- mib-2 .1.3.6.1.2.1 ----------------------------------------------------- */ +extern const struct snmp_scalar_array_node snmp_mib2_snmp_root; +extern const struct snmp_tree_node snmp_mib2_udp_root; +extern const struct snmp_tree_node snmp_mib2_tcp_root; +extern const struct snmp_scalar_array_node snmp_mib2_icmp_root; +extern const struct snmp_tree_node snmp_mib2_interface_root; +extern const struct snmp_scalar_array_node snmp_mib2_system_node; +extern const struct snmp_tree_node snmp_mib2_at_root; +extern const struct snmp_tree_node snmp_mib2_ip_root; + +static const struct snmp_node* const mib2_nodes[] = { + &snmp_mib2_system_node.node.node, + &snmp_mib2_interface_root.node, +#if LWIP_ARP && LWIP_IPV4 + &snmp_mib2_at_root.node, +#endif /* LWIP_ARP && LWIP_IPV4 */ +#if LWIP_IPV4 + &snmp_mib2_ip_root.node, +#endif /* LWIP_IPV4 */ +#if LWIP_ICMP + &snmp_mib2_icmp_root.node.node, +#endif /* LWIP_ICMP */ +#if LWIP_TCP + &snmp_mib2_tcp_root.node, +#endif /* LWIP_TCP */ +#if LWIP_UDP + &snmp_mib2_udp_root.node, +#endif /* LWIP_UDP */ + &snmp_mib2_snmp_root.node.node +}; + +static const struct snmp_tree_node mib2_root = SNMP_CREATE_TREE_NODE(1, mib2_nodes); + +static const u32_t mib2_base_oid_arr[] = { 1,3,6,1,2,1 }; +const struct snmp_mib mib2 = SNMP_MIB_CREATE(mib2_base_oid_arr, &mib2_root.node); + +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_icmp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_icmp.c new file mode 100644 index 0000000..995bd32 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_icmp.c @@ -0,0 +1,182 @@ +/** + * @file + * Management Information Base II (RFC1213) ICMP objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/icmp.h" +#include "lwip/stats.h" + +#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +/* --- icmp .1.3.6.1.2.1.5 ----------------------------------------------------- */ + +static s16_t +icmp_get_value(const struct snmp_scalar_array_node_def *node, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + + switch (node->oid) { + case 1: /* icmpInMsgs */ + *uint_ptr = STATS_GET(mib2.icmpinmsgs); + return sizeof(*uint_ptr); + case 2: /* icmpInErrors */ + *uint_ptr = STATS_GET(mib2.icmpinerrors); + return sizeof(*uint_ptr); + case 3: /* icmpInDestUnreachs */ + *uint_ptr = STATS_GET(mib2.icmpindestunreachs); + return sizeof(*uint_ptr); + case 4: /* icmpInTimeExcds */ + *uint_ptr = STATS_GET(mib2.icmpintimeexcds); + return sizeof(*uint_ptr); + case 5: /* icmpInParmProbs */ + *uint_ptr = STATS_GET(mib2.icmpinparmprobs); + return sizeof(*uint_ptr); + case 6: /* icmpInSrcQuenchs */ + *uint_ptr = STATS_GET(mib2.icmpinsrcquenchs); + return sizeof(*uint_ptr); + case 7: /* icmpInRedirects */ + *uint_ptr = STATS_GET(mib2.icmpinredirects); + return sizeof(*uint_ptr); + case 8: /* icmpInEchos */ + *uint_ptr = STATS_GET(mib2.icmpinechos); + return sizeof(*uint_ptr); + case 9: /* icmpInEchoReps */ + *uint_ptr = STATS_GET(mib2.icmpinechoreps); + return sizeof(*uint_ptr); + case 10: /* icmpInTimestamps */ + *uint_ptr = STATS_GET(mib2.icmpintimestamps); + return sizeof(*uint_ptr); + case 11: /* icmpInTimestampReps */ + *uint_ptr = STATS_GET(mib2.icmpintimestampreps); + return sizeof(*uint_ptr); + case 12: /* icmpInAddrMasks */ + *uint_ptr = STATS_GET(mib2.icmpinaddrmasks); + return sizeof(*uint_ptr); + case 13: /* icmpInAddrMaskReps */ + *uint_ptr = STATS_GET(mib2.icmpinaddrmaskreps); + return sizeof(*uint_ptr); + case 14: /* icmpOutMsgs */ + *uint_ptr = STATS_GET(mib2.icmpoutmsgs); + return sizeof(*uint_ptr); + case 15: /* icmpOutErrors */ + *uint_ptr = STATS_GET(mib2.icmpouterrors); + return sizeof(*uint_ptr); + case 16: /* icmpOutDestUnreachs */ + *uint_ptr = STATS_GET(mib2.icmpoutdestunreachs); + return sizeof(*uint_ptr); + case 17: /* icmpOutTimeExcds */ + *uint_ptr = STATS_GET(mib2.icmpouttimeexcds); + return sizeof(*uint_ptr); + case 18: /* icmpOutParmProbs: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 19: /* icmpOutSrcQuenchs: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 20: /* icmpOutRedirects: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 21: /* icmpOutEchos */ + *uint_ptr = STATS_GET(mib2.icmpoutechos); + return sizeof(*uint_ptr); + case 22: /* icmpOutEchoReps */ + *uint_ptr = STATS_GET(mib2.icmpoutechoreps); + return sizeof(*uint_ptr); + case 23: /* icmpOutTimestamps: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 24: /* icmpOutTimestampReps: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 25: /* icmpOutAddrMasks: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + case 26: /* icmpOutAddrMaskReps: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_value(): unknown id: %"S32_F"\n", node->oid)); + break; + } + + return 0; +} + + +static const struct snmp_scalar_array_node_def icmp_nodes[] = { + { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 7, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {23, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, + {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY} +}; + +const struct snmp_scalar_array_node snmp_mib2_icmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(5, icmp_nodes, icmp_get_value, NULL, NULL); + +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_interfaces.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_interfaces.c new file mode 100644 index 0000000..979b507 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_interfaces.c @@ -0,0 +1,375 @@ +/** + * @file + * Management Information Base II (RFC1213) INTERFACES objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/netif.h" +#include "lwip/stats.h" + +#include + +#if LWIP_SNMP && SNMP_LWIP_MIB2 + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + + +/* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */ + +static s16_t +interfaces_get_value(struct snmp_node_instance* instance, void* value) +{ + if (instance->node->oid == 1) { + s32_t *sint_ptr = (s32_t*)value; + s32_t num_netifs = 0; + + struct netif *netif = netif_list; + while (netif != NULL) { + num_netifs++; + netif = netif->next; + } + + *sint_ptr = num_netifs; + return sizeof(*sint_ptr); + } + + return 0; +} + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range interfaces_Table_oid_ranges[] = { + { 1, 0xff } /* netif->num is u8_t */ +}; + +static const u8_t iftable_ifOutQLen = 0; + +static const u8_t iftable_ifOperStatus_up = 1; +static const u8_t iftable_ifOperStatus_down = 2; + +static const u8_t iftable_ifAdminStatus_up = 1; +static const u8_t iftable_ifAdminStatus_lowerLayerDown = 7; +static const u8_t iftable_ifAdminStatus_down = 2; + +static snmp_err_t +interfaces_Table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance) +{ + u32_t ifIndex; + struct netif *netif; + + LWIP_UNUSED_ARG(column); + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get netif index from incoming OID */ + ifIndex = row_oid[0]; + + /* find netif with index */ + netif = netif_list; + while (netif != NULL) { + if (netif_to_num(netif) == ifIndex) { + /* store netif pointer for subsequent operations (get/test/set) */ + cell_instance->reference.ptr = netif; + return SNMP_ERR_NOERROR; + } + netif = netif->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +interfaces_Table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance) +{ + struct netif *netif; + struct snmp_next_oid_state state; + u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; + + LWIP_UNUSED_ARG(column); + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)); + + /* iterate over all possible OIDs to find the next one */ + netif = netif_list; + while (netif != NULL) { + u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; + test_oid[0] = netif_to_num(netif); + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif); + + netif = netif->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* store netif pointer for subsequent operations (get/test/set) */ + cell_instance->reference.ptr = /* (struct netif*) */state.reference; + return SNMP_ERR_NOERROR; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static s16_t +interfaces_Table_get_value(struct snmp_node_instance* instance, void* value) +{ + struct netif *netif = (struct netif*)instance->reference.ptr; + u32_t* value_u32 = (u32_t*)value; + s32_t* value_s32 = (s32_t*)value; + u16_t value_len; + + switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id)) + { + case 1: /* ifIndex */ + *value_s32 = netif_to_num(netif); + value_len = sizeof(*value_s32); + break; + case 2: /* ifDescr */ + value_len = sizeof(netif->name); + MEMCPY(value, netif->name, value_len); + break; + case 3: /* ifType */ + *value_s32 = netif->link_type; + value_len = sizeof(*value_s32); + break; + case 4: /* ifMtu */ + *value_s32 = netif->mtu; + value_len = sizeof(*value_s32); + break; + case 5: /* ifSpeed */ + *value_u32 = netif->link_speed; + value_len = sizeof(*value_u32); + break; + case 6: /* ifPhysAddress */ + value_len = sizeof(netif->hwaddr); + MEMCPY(value, &netif->hwaddr, value_len); + break; + case 7: /* ifAdminStatus */ + if (netif_is_up(netif)) { + *value_s32 = iftable_ifOperStatus_up; + } else { + *value_s32 = iftable_ifOperStatus_down; + } + value_len = sizeof(*value_s32); + break; + case 8: /* ifOperStatus */ + if (netif_is_up(netif)) { + if (netif_is_link_up(netif)) { + *value_s32 = iftable_ifAdminStatus_up; + } else { + *value_s32 = iftable_ifAdminStatus_lowerLayerDown; + } + } else { + *value_s32 = iftable_ifAdminStatus_down; + } + value_len = sizeof(*value_s32); + break; + case 9: /* ifLastChange */ + *value_u32 = netif->ts; + value_len = sizeof(*value_u32); + break; + case 10: /* ifInOctets */ + *value_u32 = netif->mib2_counters.ifinoctets; + value_len = sizeof(*value_u32); + break; + case 11: /* ifInUcastPkts */ + *value_u32 = netif->mib2_counters.ifinucastpkts; + value_len = sizeof(*value_u32); + break; + case 12: /* ifInNUcastPkts */ + *value_u32 = netif->mib2_counters.ifinnucastpkts; + value_len = sizeof(*value_u32); + break; + case 13: /* ifInDiscards */ + *value_u32 = netif->mib2_counters.ifindiscards; + value_len = sizeof(*value_u32); + break; + case 14: /* ifInErrors */ + *value_u32 = netif->mib2_counters.ifinerrors; + value_len = sizeof(*value_u32); + break; + case 15: /* ifInUnkownProtos */ + *value_u32 = netif->mib2_counters.ifinunknownprotos; + value_len = sizeof(*value_u32); + break; + case 16: /* ifOutOctets */ + *value_u32 = netif->mib2_counters.ifoutoctets; + value_len = sizeof(*value_u32); + break; + case 17: /* ifOutUcastPkts */ + *value_u32 = netif->mib2_counters.ifoutucastpkts; + value_len = sizeof(*value_u32); + break; + case 18: /* ifOutNUcastPkts */ + *value_u32 = netif->mib2_counters.ifoutnucastpkts; + value_len = sizeof(*value_u32); + break; + case 19: /* ifOutDiscarts */ + *value_u32 = netif->mib2_counters.ifoutdiscards; + value_len = sizeof(*value_u32); + break; + case 20: /* ifOutErrors */ + *value_u32 = netif->mib2_counters.ifouterrors; + value_len = sizeof(*value_u32); + break; + case 21: /* ifOutQLen */ + *value_u32 = iftable_ifOutQLen; + value_len = sizeof(*value_u32); + break; + /** @note returning zeroDotZero (0.0) no media specific MIB support */ + case 22: /* ifSpecific */ + value_len = snmp_zero_dot_zero.len * sizeof(u32_t); + MEMCPY(value, snmp_zero_dot_zero.id, value_len); + break; + default: + return 0; + } + + return value_len; +} + +#if !SNMP_SAFE_REQUESTS + +static snmp_err_t +interfaces_Table_set_test(struct snmp_node_instance* instance, u16_t len, void *value) +{ + s32_t *sint_ptr = (s32_t*)value; + + /* stack should never call this method for another column, + because all other columns are set to readonly */ + LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); + LWIP_UNUSED_ARG(len); + + if (*sint_ptr == 1 || *sint_ptr == 2) { + return SNMP_ERR_NOERROR; + } + + return SNMP_ERR_WRONGVALUE; +} + +static snmp_err_t +interfaces_Table_set_value(struct snmp_node_instance* instance, u16_t len, void *value) +{ + struct netif *netif = (struct netif*)instance->reference.ptr; + s32_t *sint_ptr = (s32_t*)value; + + /* stack should never call this method for another column, + because all other columns are set to readonly */ + LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); + LWIP_UNUSED_ARG(len); + + if (*sint_ptr == 1) { + netif_set_up(netif); + } else if (*sint_ptr == 2) { + netif_set_down(netif); + } + + return SNMP_ERR_NOERROR; +} + +#endif /* SNMP_SAFE_REQUESTS */ + +static const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value); + +static const struct snmp_table_col_def interfaces_Table_columns[] = { + { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */ + { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */ + { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */ + { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */ + { 5, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */ + { 6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */ +#if !SNMP_SAFE_REQUESTS + { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */ +#else + { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */ +#endif + { 8, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */ + { 9, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */ + { 10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */ + { 11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */ + { 12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */ + { 13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */ + { 14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */ + { 15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */ + { 16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */ + { 17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */ + { 18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */ + { 19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */ + { 20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */ + { 21, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */ + { 22, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY } /* ifSpecific */ +}; + +#if !SNMP_SAFE_REQUESTS +static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( + 2, interfaces_Table_columns, + interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, + interfaces_Table_get_value, interfaces_Table_set_test, interfaces_Table_set_value); +#else +static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( + 2, interfaces_Table_columns, + interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, + interfaces_Table_get_value, NULL, NULL); +#endif + +/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ +CREATE_LWIP_SYNC_NODE(1, interfaces_Number) +CREATE_LWIP_SYNC_NODE(2, interfaces_Table) + +static const struct snmp_node* const interface_nodes[] = { + &SYNC_NODE_NAME(interfaces_Number).node.node, + &SYNC_NODE_NAME(interfaces_Table).node.node +}; + +const struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes); + +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_ip.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_ip.c new file mode 100644 index 0000000..4f05180 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_ip.c @@ -0,0 +1,743 @@ +/** + * @file + * Management Information Base II (RFC1213) IP objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/stats.h" +#include "lwip/netif.h" +#include "lwip/ip.h" +#include "lwip/etharp.h" + +#if LWIP_SNMP && SNMP_LWIP_MIB2 + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +#if LWIP_IPV4 +/* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */ + +static s16_t +ip_get_value(struct snmp_node_instance* instance, void* value) +{ + s32_t* sint_ptr = (s32_t*)value; + u32_t* uint_ptr = (u32_t*)value; + + switch (instance->node->oid) { + case 1: /* ipForwarding */ +#if IP_FORWARD + /* forwarding */ + *sint_ptr = 1; +#else + /* not-forwarding */ + *sint_ptr = 2; +#endif + return sizeof(*sint_ptr); + case 2: /* ipDefaultTTL */ + *sint_ptr = IP_DEFAULT_TTL; + return sizeof(*sint_ptr); + case 3: /* ipInReceives */ + *uint_ptr = STATS_GET(mib2.ipinreceives); + return sizeof(*uint_ptr); + case 4: /* ipInHdrErrors */ + *uint_ptr = STATS_GET(mib2.ipinhdrerrors); + return sizeof(*uint_ptr); + case 5: /* ipInAddrErrors */ + *uint_ptr = STATS_GET(mib2.ipinaddrerrors); + return sizeof(*uint_ptr); + case 6: /* ipForwDatagrams */ + *uint_ptr = STATS_GET(mib2.ipforwdatagrams); + return sizeof(*uint_ptr); + case 7: /* ipInUnknownProtos */ + *uint_ptr = STATS_GET(mib2.ipinunknownprotos); + return sizeof(*uint_ptr); + case 8: /* ipInDiscards */ + *uint_ptr = STATS_GET(mib2.ipindiscards); + return sizeof(*uint_ptr); + case 9: /* ipInDelivers */ + *uint_ptr = STATS_GET(mib2.ipindelivers); + return sizeof(*uint_ptr); + case 10: /* ipOutRequests */ + *uint_ptr = STATS_GET(mib2.ipoutrequests); + return sizeof(*uint_ptr); + case 11: /* ipOutDiscards */ + *uint_ptr = STATS_GET(mib2.ipoutdiscards); + return sizeof(*uint_ptr); + case 12: /* ipOutNoRoutes */ + *uint_ptr = STATS_GET(mib2.ipoutnoroutes); + return sizeof(*uint_ptr); + case 13: /* ipReasmTimeout */ +#if IP_REASSEMBLY + *sint_ptr = IP_REASS_MAXAGE; +#else + *sint_ptr = 0; +#endif + return sizeof(*sint_ptr); + case 14: /* ipReasmReqds */ + *uint_ptr = STATS_GET(mib2.ipreasmreqds); + return sizeof(*uint_ptr); + case 15: /* ipReasmOKs */ + *uint_ptr = STATS_GET(mib2.ipreasmoks); + return sizeof(*uint_ptr); + case 16: /* ipReasmFails */ + *uint_ptr = STATS_GET(mib2.ipreasmfails); + return sizeof(*uint_ptr); + case 17: /* ipFragOKs */ + *uint_ptr = STATS_GET(mib2.ipfragoks); + return sizeof(*uint_ptr); + case 18: /* ipFragFails */ + *uint_ptr = STATS_GET(mib2.ipfragfails); + return sizeof(*uint_ptr); + case 19: /* ipFragCreates */ + *uint_ptr = STATS_GET(mib2.ipfragcreates); + return sizeof(*uint_ptr); + case 23: /* ipRoutingDiscards: not supported -> always 0 */ + *uint_ptr = 0; + return sizeof(*uint_ptr); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); + break; + } + + return 0; +} + +/** + * Test ip object value before setting. + * + * @param instance node instance + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + * + * @note we allow set if the value matches the hardwired value, + * otherwise return badvalue. + */ +static snmp_err_t +ip_set_test(struct snmp_node_instance* instance, u16_t len, void *value) +{ + snmp_err_t ret = SNMP_ERR_WRONGVALUE; + s32_t *sint_ptr = (s32_t*)value; + + LWIP_UNUSED_ARG(len); + switch (instance->node->oid) { + case 1: /* ipForwarding */ +#if IP_FORWARD + /* forwarding */ + if (*sint_ptr == 1) +#else + /* not-forwarding */ + if (*sint_ptr == 2) +#endif + { + ret = SNMP_ERR_NOERROR; + } + break; + case 2: /* ipDefaultTTL */ + if (*sint_ptr == IP_DEFAULT_TTL) { + ret = SNMP_ERR_NOERROR; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_set_test(): unknown id: %"S32_F"\n", instance->node->oid)); + break; + } + + return ret; +} + +static snmp_err_t +ip_set_value(struct snmp_node_instance* instance, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(instance); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* nothing to do here because in set_test we only accept values being the same as our own stored value -> no need to store anything */ + return SNMP_ERR_NOERROR; +} + +/* --- ipAddrTable --- */ + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range ip_AddrTable_oid_ranges[] = { + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff } /* IP D */ +}; + +static snmp_err_t +ip_AddrTable_get_cell_value_core(struct netif *netif, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) +{ + LWIP_UNUSED_ARG(value_len); + + switch (*column) { + case 1: /* ipAdEntAddr */ + value->u32 = netif_ip4_addr(netif)->addr; + break; + case 2: /* ipAdEntIfIndex */ + value->u32 = netif_to_num(netif); + break; + case 3: /* ipAdEntNetMask */ + value->u32 = netif_ip4_netmask(netif)->addr; + break; + case 4: /* ipAdEntBcastAddr */ + /* lwIP oddity, there's no broadcast + address in the netif we can rely on */ + value->u32 = IPADDR_BROADCAST & 1; + break; + case 5: /* ipAdEntReasmMaxSize */ +#if IP_REASSEMBLY + /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, + * but only if receiving one fragmented packet at a time. + * The current solution is to calculate for 2 simultaneous packets... + */ + value->u32 = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * + (PBUF_POOL_BUFSIZE - PBUF_LINK_ENCAPSULATION_HLEN - PBUF_LINK_HLEN - IP_HLEN))); +#else + /** @todo returning MTU would be a bad thing and + returning a wild guess like '576' isn't good either */ + value->u32 = 0; +#endif + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +ip_AddrTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip4_addr_t ip; + struct netif *netif; + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, ip_AddrTable_oid_ranges, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get IP from incoming OID */ + snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ + + /* find netif with requested ip */ + netif = netif_list; + while (netif != NULL) { + if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) { + /* fill in object properties */ + return ip_AddrTable_get_cell_value_core(netif, column, value, value_len); + } + + netif = netif->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +ip_AddrTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct netif *netif; + struct snmp_next_oid_state state; + u32_t result_temp[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)); + + /* iterate over all possible OIDs to find the next one */ + netif = netif_list; + while (netif != NULL) { + u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; + snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]); + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif); + + netif = netif->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return ip_AddrTable_get_cell_value_core((struct netif*)state.reference, column, value, value_len); + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +/* --- ipRouteTable --- */ + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range ip_RouteTable_oid_ranges[] = { + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff }, /* IP D */ +}; + +static snmp_err_t +ip_RouteTable_get_cell_value_core(struct netif *netif, u8_t default_route, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) +{ + switch (*column) { + case 1: /* ipRouteDest */ + if (default_route) { + /* default rte has 0.0.0.0 dest */ + value->u32 = IP4_ADDR_ANY4->addr; + } else { + /* netifs have netaddress dest */ + ip4_addr_t tmp; + ip4_addr_get_network(&tmp, netif_ip4_addr(netif), netif_ip4_netmask(netif)); + value->u32 = tmp.addr; + } + break; + case 2: /* ipRouteIfIndex */ + value->u32 = netif_to_num(netif); + break; + case 3: /* ipRouteMetric1 */ + if (default_route) { + value->s32 = 1; /* default */ + } else { + value->s32 = 0; /* normal */ + } + break; + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + value->s32 = -1; /* none */ + break; + case 7: /* ipRouteNextHop */ + if (default_route) { + /* default rte: gateway */ + value->u32 = netif_ip4_gw(netif)->addr; + } else { + /* other rtes: netif ip_addr */ + value->u32 = netif_ip4_addr(netif)->addr; + } + break; + case 8: /* ipRouteType */ + if (default_route) { + /* default rte is indirect */ + value->u32 = 4; /* indirect */ + } else { + /* other rtes are direct */ + value->u32 = 3; /* direct */ + } + break; + case 9: /* ipRouteProto */ + /* locally defined routes */ + value->u32 = 2; /* local */ + break; + case 10: /* ipRouteAge */ + /* @todo (sysuptime - timestamp last change) / 100 */ + value->u32 = 0; + break; + case 11: /* ipRouteMask */ + if (default_route) { + /* default rte use 0.0.0.0 mask */ + value->u32 = IP4_ADDR_ANY4->addr; + } else { + /* other rtes use netmask */ + value->u32 = netif_ip4_netmask(netif)->addr; + } + break; + case 12: /* ipRouteMetric5 */ + value->s32 = -1; /* none */ + break; + case 13: /* ipRouteInfo */ + value->const_ptr = snmp_zero_dot_zero.id; + *value_len = snmp_zero_dot_zero.len * sizeof(u32_t); + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +ip_RouteTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip4_addr_t test_ip; + struct netif *netif; + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, ip_RouteTable_oid_ranges, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get IP and port from incoming OID */ + snmp_oid_to_ip4(&row_oid[0], &test_ip); /* we know it succeeds because of oid_in_range check above */ + + /* default route is on default netif */ + if (ip4_addr_isany_val(test_ip) && (netif_default != NULL)) { + /* fill in object properties */ + return ip_RouteTable_get_cell_value_core(netif_default, 1, column, value, value_len); + } + + /* find netif with requested route */ + netif = netif_list; + while (netif != NULL) { + ip4_addr_t dst; + ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); + + if (ip4_addr_cmp(&dst, &test_ip)) { + /* fill in object properties */ + return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len); + } + + netif = netif->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +ip_RouteTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct netif *netif; + struct snmp_next_oid_state state; + u32_t result_temp[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; + u32_t test_oid[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)); + + /* check default route */ + if (netif_default != NULL) { + snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[0]); + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif_default); + } + + /* iterate over all possible OIDs to find the next one */ + netif = netif_list; + while (netif != NULL) { + ip4_addr_t dst; + ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); + + /* check generated OID: is it a candidate for the next one? */ + if (!ip4_addr_isany_val(dst)) { + snmp_ip4_to_oid(&dst, &test_oid[0]); + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif); + } + + netif = netif->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + ip4_addr_t dst; + snmp_oid_to_ip4(&result_temp[0], &dst); + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return ip_RouteTable_get_cell_value_core((struct netif*)state.reference, ip4_addr_isany_val(dst), column, value, value_len); + } else { + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; + } +} + +#if LWIP_ARP && LWIP_IPV4 +/* --- ipNetToMediaTable --- */ + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range ip_NetToMediaTable_oid_ranges[] = { + { 1, 0xff }, /* IfIndex */ + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff } /* IP D */ +}; + +static snmp_err_t +ip_NetToMediaTable_get_cell_value_core(u8_t arp_table_index, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) +{ + ip4_addr_t *ip; + struct netif *netif; + struct eth_addr *ethaddr; + + etharp_get_entry(arp_table_index, &ip, &netif, ðaddr); + + /* value */ + switch (*column) { + case 1: /* atIfIndex / ipNetToMediaIfIndex */ + value->u32 = netif_to_num(netif); + break; + case 2: /* atPhysAddress / ipNetToMediaPhysAddress */ + value->ptr = ethaddr; + *value_len = sizeof(*ethaddr); + break; + case 3: /* atNetAddress / ipNetToMediaNetAddress */ + value->u32 = ip->addr; + break; + case 4: /* ipNetToMediaType */ + value->u32 = 3; /* dynamic*/ + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +ip_NetToMediaTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip4_addr_t ip_in; + u8_t netif_index; + u8_t i; + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, ip_NetToMediaTable_oid_ranges, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get IP from incoming OID */ + netif_index = (u8_t)row_oid[0]; + snmp_oid_to_ip4(&row_oid[1], &ip_in); /* we know it succeeds because of oid_in_range check above */ + + /* find requested entry */ + for (i=0; iid, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)); + + /* iterate over all possible OIDs to find the next one */ + for (i=0; i + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_scalar.h" + +#if LWIP_SNMP && SNMP_LWIP_MIB2 + +#define MIB2_AUTH_TRAPS_ENABLED 1 +#define MIB2_AUTH_TRAPS_DISABLED 2 + +/* --- snmp .1.3.6.1.2.1.11 ----------------------------------------------------- */ +static s16_t +snmp_get_value(const struct snmp_scalar_array_node_def *node, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + switch (node->oid) { + case 1: /* snmpInPkts */ + *uint_ptr = snmp_stats.inpkts; + break; + case 2: /* snmpOutPkts */ + *uint_ptr = snmp_stats.outpkts; + break; + case 3: /* snmpInBadVersions */ + *uint_ptr = snmp_stats.inbadversions; + break; + case 4: /* snmpInBadCommunityNames */ + *uint_ptr = snmp_stats.inbadcommunitynames; + break; + case 5: /* snmpInBadCommunityUses */ + *uint_ptr = snmp_stats.inbadcommunityuses; + break; + case 6: /* snmpInASNParseErrs */ + *uint_ptr = snmp_stats.inasnparseerrs; + break; + case 8: /* snmpInTooBigs */ + *uint_ptr = snmp_stats.intoobigs; + break; + case 9: /* snmpInNoSuchNames */ + *uint_ptr = snmp_stats.innosuchnames; + break; + case 10: /* snmpInBadValues */ + *uint_ptr = snmp_stats.inbadvalues; + break; + case 11: /* snmpInReadOnlys */ + *uint_ptr = snmp_stats.inreadonlys; + break; + case 12: /* snmpInGenErrs */ + *uint_ptr = snmp_stats.ingenerrs; + break; + case 13: /* snmpInTotalReqVars */ + *uint_ptr = snmp_stats.intotalreqvars; + break; + case 14: /* snmpInTotalSetVars */ + *uint_ptr = snmp_stats.intotalsetvars; + break; + case 15: /* snmpInGetRequests */ + *uint_ptr = snmp_stats.ingetrequests; + break; + case 16: /* snmpInGetNexts */ + *uint_ptr = snmp_stats.ingetnexts; + break; + case 17: /* snmpInSetRequests */ + *uint_ptr = snmp_stats.insetrequests; + break; + case 18: /* snmpInGetResponses */ + *uint_ptr = snmp_stats.ingetresponses; + break; + case 19: /* snmpInTraps */ + *uint_ptr = snmp_stats.intraps; + break; + case 20: /* snmpOutTooBigs */ + *uint_ptr = snmp_stats.outtoobigs; + break; + case 21: /* snmpOutNoSuchNames */ + *uint_ptr = snmp_stats.outnosuchnames; + break; + case 22: /* snmpOutBadValues */ + *uint_ptr = snmp_stats.outbadvalues; + break; + case 24: /* snmpOutGenErrs */ + *uint_ptr = snmp_stats.outgenerrs; + break; + case 25: /* snmpOutGetRequests */ + *uint_ptr = snmp_stats.outgetrequests; + break; + case 26: /* snmpOutGetNexts */ + *uint_ptr = snmp_stats.outgetnexts; + break; + case 27: /* snmpOutSetRequests */ + *uint_ptr = snmp_stats.outsetrequests; + break; + case 28: /* snmpOutGetResponses */ + *uint_ptr = snmp_stats.outgetresponses; + break; + case 29: /* snmpOutTraps */ + *uint_ptr = snmp_stats.outtraps; + break; + case 30: /* snmpEnableAuthenTraps */ + if (snmp_get_auth_traps_enabled() == SNMP_AUTH_TRAPS_DISABLED) { + *uint_ptr = MIB2_AUTH_TRAPS_DISABLED; + } else { + *uint_ptr = MIB2_AUTH_TRAPS_ENABLED; + } + break; + case 31: /* snmpSilentDrops */ + *uint_ptr = 0; /* not supported */ + break; + case 32: /* snmpProxyDrops */ + *uint_ptr = 0; /* not supported */ + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_value(): unknown id: %"S32_F"\n", node->oid)); + return 0; + } + + return sizeof(*uint_ptr); +} + +static snmp_err_t +snmp_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + snmp_err_t ret = SNMP_ERR_WRONGVALUE; + LWIP_UNUSED_ARG(len); + + if (node->oid == 30) { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = (s32_t*)value; + + /* we should have writable non-volatile mem here */ + if ((*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) || (*sint_ptr == MIB2_AUTH_TRAPS_ENABLED)) { + ret = SNMP_ERR_NOERROR; + } + } + return ret; +} + +static snmp_err_t +snmp_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(len); + + if (node->oid == 30) { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = (s32_t*)value; + if (*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) { + snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_DISABLED); + } else { + snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_ENABLED); + } + } + + return SNMP_ERR_NOERROR; +} + +/* the following nodes access variables in SNMP stack (snmp_stats) from SNMP worker thread -> OK, no sync needed */ +static const struct snmp_scalar_array_node_def snmp_nodes[] = { + { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInPkts */ + { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutPkts */ + { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadVersions */ + { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityNames */ + { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityUses */ + { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInASNParseErrs */ + { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTooBigs */ + { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInNoSuchNames */ + {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadValues */ + {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInReadOnlys */ + {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGenErrs */ + {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalReqVars */ + {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalSetVars */ + {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetRequests */ + {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetNexts */ + {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInSetRequests */ + {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetResponses */ + {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTraps */ + {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTooBigs */ + {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutNoSuchNames */ + {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutBadValues */ + {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGenErrs */ + {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetRequests */ + {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetNexts */ + {27, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutSetRequests */ + {28, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetResponses */ + {29, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTraps */ + {30, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE}, /* snmpEnableAuthenTraps */ + {31, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpSilentDrops */ + {32, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY} /* snmpProxyDrops */ +}; + +const struct snmp_scalar_array_node snmp_mib2_snmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(11, snmp_nodes, snmp_get_value, snmp_set_test, snmp_set_value); + +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_system.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_system.c new file mode 100644 index 0000000..90e5780 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_system.c @@ -0,0 +1,377 @@ +/** + * @file + * Management Information Base II (RFC1213) SYSTEM objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/sys.h" + +#include + +#if LWIP_SNMP && SNMP_LWIP_MIB2 + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */ + +/** mib-2.system.sysDescr */ +static const u8_t sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC; +static const u8_t* sysdescr = sysdescr_default; +static const u16_t* sysdescr_len = NULL; /* use strlen for determining len */ + +/** mib-2.system.sysContact */ +static const u8_t syscontact_default[] = SNMP_LWIP_MIB2_SYSCONTACT; +static const u8_t* syscontact = syscontact_default; +static const u16_t* syscontact_len = NULL; /* use strlen for determining len */ +static u8_t* syscontact_wr = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */ +static u16_t* syscontact_wr_len = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */ +static u16_t syscontact_bufsize = 0; /* 0=not writable */ + +/** mib-2.system.sysName */ +static const u8_t sysname_default[] = SNMP_LWIP_MIB2_SYSNAME; +static const u8_t* sysname = sysname_default; +static const u16_t* sysname_len = NULL; /* use strlen for determining len */ +static u8_t* sysname_wr = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */ +static u16_t* sysname_wr_len = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */ +static u16_t sysname_bufsize = 0; /* 0=not writable */ + +/** mib-2.system.sysLocation */ +static const u8_t syslocation_default[] = SNMP_LWIP_MIB2_SYSLOCATION; +static const u8_t* syslocation = syslocation_default; +static const u16_t* syslocation_len = NULL; /* use strlen for determining len */ +static u8_t* syslocation_wr = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */ +static u16_t* syslocation_wr_len = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */ +static u16_t syslocation_bufsize = 0; /* 0=not writable */ + +/** + * @ingroup snmp_mib2 + * Initializes sysDescr pointers. + * + * @param str if non-NULL then copy str pointer + * @param len points to string length, excluding zero terminator + */ +void +snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len) +{ + if (str != NULL) { + sysdescr = str; + sysdescr_len = len; + } +} + +/** + * @ingroup snmp_mib2 + * Initializes sysContact pointers + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + syscontact = ocstr; + syscontact_wr = ocstr; + syscontact_len = ocstrlen; + syscontact_wr_len = ocstrlen; + syscontact_bufsize = bufsize; + } +} + +/** + * @ingroup snmp_mib2 + * see \ref snmp_mib2_set_syscontact but set pointer to readonly memory + */ +void +snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + syscontact = ocstr; + syscontact_len = ocstrlen; + syscontact_wr = NULL; + syscontact_wr_len = NULL; + syscontact_bufsize = 0; + } +} + + +/** + * @ingroup snmp_mib2 + * Initializes sysName pointers + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + sysname = ocstr; + sysname_wr = ocstr; + sysname_len = ocstrlen; + sysname_wr_len = ocstrlen; + sysname_bufsize = bufsize; + } +} + +/** + * @ingroup snmp_mib2 + * see \ref snmp_mib2_set_sysname but set pointer to readonly memory + */ +void +snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + sysname = ocstr; + sysname_len = ocstrlen; + sysname_wr = NULL; + sysname_wr_len = NULL; + sysname_bufsize = 0; + } +} + +/** + * @ingroup snmp_mib2 + * Initializes sysLocation pointers + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + syslocation = ocstr; + syslocation_wr = ocstr; + syslocation_len = ocstrlen; + syslocation_wr_len = ocstrlen; + syslocation_bufsize = bufsize; + } +} + +/** + * @ingroup snmp_mib2 + * see \ref snmp_mib2_set_syslocation but set pointer to readonly memory + */ +void +snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + syslocation = ocstr; + syslocation_len = ocstrlen; + syslocation_wr = NULL; + syslocation_wr_len = NULL; + syslocation_bufsize = 0; + } +} + + +static s16_t +system_get_value(const struct snmp_scalar_array_node_def *node, void *value) +{ + const u8_t* var = NULL; + const s16_t* var_len; + u16_t result; + + switch (node->oid) { + case 1: /* sysDescr */ + var = sysdescr; + var_len = (const s16_t*)sysdescr_len; + break; + case 2: /* sysObjectID */ + { + const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid(); + MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t)); + return dev_enterprise_oid->len * sizeof(u32_t); + } + case 3: /* sysUpTime */ + MIB2_COPY_SYSUPTIME_TO((u32_t*)value); + return sizeof(u32_t); + case 4: /* sysContact */ + var = syscontact; + var_len = (const s16_t*)syscontact_len; + break; + case 5: /* sysName */ + var = sysname; + var_len = (const s16_t*)sysname_len; + break; + case 6: /* sysLocation */ + var = syslocation; + var_len = (const s16_t*)syslocation_len; + break; + case 7: /* sysServices */ + *(s32_t*)value = SNMP_SYSSERVICES; + return sizeof(s32_t); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid)); + return 0; + } + + /* handle string values (OID 1,4,5 and 6) */ + LWIP_ASSERT("", (value != NULL)); + if (var_len == NULL) { + result = (s16_t)strlen((const char*)var); + } else { + result = *var_len; + } + MEMCPY(value, var, result); + return result; +} + +static snmp_err_t +system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + snmp_err_t ret = SNMP_ERR_WRONGVALUE; + const u16_t* var_bufsize = NULL; + const u16_t* var_wr_len; + + LWIP_UNUSED_ARG(value); + + switch (node->oid) { + case 4: /* sysContact */ + var_bufsize = &syscontact_bufsize; + var_wr_len = syscontact_wr_len; + break; + case 5: /* sysName */ + var_bufsize = &sysname_bufsize; + var_wr_len = sysname_wr_len; + break; + case 6: /* sysLocation */ + var_bufsize = &syslocation_bufsize; + var_wr_len = syslocation_wr_len; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid)); + return ret; + } + + /* check if value is writable at all */ + if (*var_bufsize > 0) { + if (var_wr_len == NULL) { + /* we have to take the terminating 0 into account */ + if (len < *var_bufsize) { + ret = SNMP_ERR_NOERROR; + } + } else { + if (len <= *var_bufsize) { + ret = SNMP_ERR_NOERROR; + } + } + } else { + ret = SNMP_ERR_NOTWRITABLE; + } + + return ret; +} + +static snmp_err_t +system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + u8_t* var_wr = NULL; + u16_t* var_wr_len; + + switch (node->oid) { + case 4: /* sysContact */ + var_wr = syscontact_wr; + var_wr_len = syscontact_wr_len; + break; + case 5: /* sysName */ + var_wr = sysname_wr; + var_wr_len = sysname_wr_len; + break; + case 6: /* sysLocation */ + var_wr = syslocation_wr; + var_wr_len = syslocation_wr_len; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid)); + return SNMP_ERR_GENERROR; + } + + /* no need to check size of target buffer, this was already done in set_test method */ + LWIP_ASSERT("", var_wr != NULL); + MEMCPY(var_wr, value, len); + + if (var_wr_len == NULL) { + /* add terminating 0 */ + var_wr[len] = 0; + } else { + *var_wr_len = len; + } + + return SNMP_ERR_NOERROR; +} + +static const struct snmp_scalar_array_node_def system_nodes[] = { + {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysDescr */ + {2, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysObjectID */ + {3, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysUpTime */ + {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */ + {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */ + {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */ + {7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY} /* sysServices */ +}; + +const struct snmp_scalar_array_node snmp_mib2_system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value); + +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_tcp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_tcp.c new file mode 100644 index 0000000..21f6965 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_tcp.c @@ -0,0 +1,594 @@ +/** + * @file + * Management Information Base II (RFC1213) TCP objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/tcp.h" +#include "lwip/priv/tcp_priv.h" +#include "lwip/stats.h" + +#include + +#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +/* --- tcp .1.3.6.1.2.1.6 ----------------------------------------------------- */ + +static s16_t +tcp_get_value(struct snmp_node_instance* instance, void* value) +{ + u32_t *uint_ptr = (u32_t*)value; + s32_t *sint_ptr = (s32_t*)value; + + switch (instance->node->oid) { + case 1: /* tcpRtoAlgorithm, vanj(4) */ + *sint_ptr = 4; + return sizeof(*sint_ptr); + case 2: /* tcpRtoMin */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 1000; + return sizeof(*sint_ptr); + case 3: /* tcpRtoMax */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 60000; + return sizeof(*sint_ptr); + case 4: /* tcpMaxConn */ + *sint_ptr = MEMP_NUM_TCP_PCB; + return sizeof(*sint_ptr); + case 5: /* tcpActiveOpens */ + *uint_ptr = STATS_GET(mib2.tcpactiveopens); + return sizeof(*uint_ptr); + case 6: /* tcpPassiveOpens */ + *uint_ptr = STATS_GET(mib2.tcppassiveopens); + return sizeof(*uint_ptr); + case 7: /* tcpAttemptFails */ + *uint_ptr = STATS_GET(mib2.tcpattemptfails); + return sizeof(*uint_ptr); + case 8: /* tcpEstabResets */ + *uint_ptr = STATS_GET(mib2.tcpestabresets); + return sizeof(*uint_ptr); + case 9: /* tcpCurrEstab */ + { + u16_t tcpcurrestab = 0; + struct tcp_pcb *pcb = tcp_active_pcbs; + while (pcb != NULL) { + if ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT)) { + tcpcurrestab++; + } + pcb = pcb->next; + } + *uint_ptr = tcpcurrestab; + } + return sizeof(*uint_ptr); + case 10: /* tcpInSegs */ + *uint_ptr = STATS_GET(mib2.tcpinsegs); + return sizeof(*uint_ptr); + case 11: /* tcpOutSegs */ + *uint_ptr = STATS_GET(mib2.tcpoutsegs); + return sizeof(*uint_ptr); + case 12: /* tcpRetransSegs */ + *uint_ptr = STATS_GET(mib2.tcpretranssegs); + return sizeof(*uint_ptr); + case 14: /* tcpInErrs */ + *uint_ptr = STATS_GET(mib2.tcpinerrs); + return sizeof(*uint_ptr); + case 15: /* tcpOutRsts */ + *uint_ptr = STATS_GET(mib2.tcpoutrsts); + return sizeof(*uint_ptr); + case 17: /* tcpHCInSegs */ + memset(value, 0, 2*sizeof(u32_t)); /* not supported */ + return 2*sizeof(u32_t); + case 18: /* tcpHCOutSegs */ + memset(value, 0, 2*sizeof(u32_t)); /* not supported */ + return 2*sizeof(u32_t); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); + break; + } + + return 0; +} + +/* --- tcpConnTable --- */ + +#if LWIP_IPV4 + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range tcp_ConnTable_oid_ranges[] = { + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff }, /* IP D */ + { 0, 0xffff }, /* Port */ + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff }, /* IP D */ + { 0, 0xffff } /* Port */ +}; + +static snmp_err_t +tcp_ConnTable_get_cell_value_core(struct tcp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) +{ + LWIP_UNUSED_ARG(value_len); + + /* value */ + switch (*column) { + case 1: /* tcpConnState */ + value->u32 = pcb->state + 1; + break; + case 2: /* tcpConnLocalAddress */ + value->u32 = ip_2_ip4(&pcb->local_ip)->addr; + break; + case 3: /* tcpConnLocalPort */ + value->u32 = pcb->local_port; + break; + case 4: /* tcpConnRemAddress */ + if (pcb->state == LISTEN) { + value->u32 = IP4_ADDR_ANY4->addr; + } else { + value->u32 = ip_2_ip4(&pcb->remote_ip)->addr; + } + break; + case 5: /* tcpConnRemPort */ + if (pcb->state == LISTEN) { + value->u32 = 0; + } else { + value->u32 = pcb->remote_port; + } + break; + default: + LWIP_ASSERT("invalid id", 0); + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +tcp_ConnTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + u8_t i; + ip4_addr_t local_ip; + ip4_addr_t remote_ip; + u16_t local_port; + u16_t remote_port; + struct tcp_pcb *pcb; + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, tcp_ConnTable_oid_ranges, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get IPs and ports from incoming OID */ + snmp_oid_to_ip4(&row_oid[0], &local_ip); /* we know it succeeds because of oid_in_range check above */ + local_port = (u16_t)row_oid[4]; + snmp_oid_to_ip4(&row_oid[5], &remote_ip); /* we know it succeeds because of oid_in_range check above */ + remote_port = (u16_t)row_oid[9]; + + /* find tcp_pcb with requested ips and ports */ + for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { + pcb = *tcp_pcb_lists[i]; + + while (pcb != NULL) { + /* do local IP and local port match? */ + if (IP_IS_V4_VAL(pcb->local_ip) && + ip4_addr_cmp(&local_ip, ip_2_ip4(&pcb->local_ip)) && (local_port == pcb->local_port)) { + + /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */ + if (pcb->state == LISTEN) { + if (ip4_addr_cmp(&remote_ip, IP4_ADDR_ANY4) && (remote_port == 0)) { + /* fill in object properties */ + return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len); + } + } else { + if (IP_IS_V4_VAL(pcb->remote_ip) && + ip4_addr_cmp(&remote_ip, ip_2_ip4(&pcb->remote_ip)) && (remote_port == pcb->remote_port)) { + /* fill in object properties */ + return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len); + } + } + } + + pcb = pcb->next; + } + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +tcp_ConnTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + u8_t i; + struct tcp_pcb *pcb; + struct snmp_next_oid_state state; + u32_t result_temp[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)]; + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)); + + /* iterate over all possible OIDs to find the next one */ + for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { + pcb = *tcp_pcb_lists[i]; + while (pcb != NULL) { + u32_t test_oid[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)]; + + if (IP_IS_V4_VAL(pcb->local_ip)) { + snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]); + test_oid[4] = pcb->local_port; + + /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */ + if (pcb->state == LISTEN) { + snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[5]); + test_oid[9] = 0; + } else { + if (IP_IS_V6_VAL(pcb->remote_ip)) { /* should never happen */ + continue; + } + snmp_ip4_to_oid(ip_2_ip4(&pcb->remote_ip), &test_oid[5]); + test_oid[9] = pcb->remote_port; + } + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges), pcb); + } + + pcb = pcb->next; + } + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return tcp_ConnTable_get_cell_value_core((struct tcp_pcb*)state.reference, column, value, value_len); + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +#endif /* LWIP_IPV4 */ + +/* --- tcpConnectionTable --- */ + +static snmp_err_t +tcp_ConnectionTable_get_cell_value_core(const u32_t* column, struct tcp_pcb *pcb, union snmp_variant_value* value) +{ + /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */ + switch (*column) { + case 7: /* tcpConnectionState */ + value->u32 = pcb->state + 1; + break; + case 8: /* tcpConnectionProcess */ + value->u32 = 0; /* not supported */ + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +tcp_ConnectionTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip_addr_t local_ip, remote_ip; + u16_t local_port, remote_port; + struct tcp_pcb *pcb; + u8_t idx = 0; + u8_t i; + struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; + + LWIP_UNUSED_ARG(value_len); + + /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */ + idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); + if (idx == 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */ + idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port); + if (idx == 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* find tcp_pcb with requested ip and port*/ + for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) { + pcb = *tcp_pcb_nonlisten_lists[i]; + + while (pcb != NULL) { + if (ip_addr_cmp(&local_ip, &pcb->local_ip) && + (local_port == pcb->local_port) && + ip_addr_cmp(&remote_ip, &pcb->remote_ip) && + (remote_port == pcb->remote_port)) { + /* fill in object properties */ + return tcp_ConnectionTable_get_cell_value_core(column, pcb, value); + } + pcb = pcb->next; + } + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +tcp_ConnectionTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct tcp_pcb *pcb; + struct snmp_next_oid_state state; + /* 1x tcpConnectionLocalAddressType + 1x OID len + 16x tcpConnectionLocalAddress + 1x tcpConnectionLocalPort + * 1x tcpConnectionRemAddressType + 1x OID len + 16x tcpConnectionRemAddress + 1x tcpConnectionRemPort */ + u32_t result_temp[38]; + u8_t i; + struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; + + LWIP_UNUSED_ARG(value_len); + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); + + /* iterate over all possible OIDs to find the next one */ + for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) { + pcb = *tcp_pcb_nonlisten_lists[i]; + + while (pcb != NULL) { + u8_t idx = 0; + u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; + + /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */ + idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); + + /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */ + idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]); + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, idx, pcb); + + pcb = pcb->next; + } + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return tcp_ConnectionTable_get_cell_value_core(column, (struct tcp_pcb*)state.reference, value); + } else { + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; + } +} + +/* --- tcpListenerTable --- */ + +static snmp_err_t +tcp_ListenerTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value) +{ + /* all items except tcpListenerProcess are declared as not-accessible */ + switch (*column) { + case 4: /* tcpListenerProcess */ + value->u32 = 0; /* not supported */ + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +tcp_ListenerTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip_addr_t local_ip; + u16_t local_port; + struct tcp_pcb_listen *pcb; + u8_t idx = 0; + + LWIP_UNUSED_ARG(value_len); + + /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */ + idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); + if (idx == 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* find tcp_pcb with requested ip and port*/ + pcb = tcp_listen_pcbs.listen_pcbs; + while (pcb != NULL) { + if (ip_addr_cmp(&local_ip, &pcb->local_ip) && + (local_port == pcb->local_port)) { + /* fill in object properties */ + return tcp_ListenerTable_get_cell_value_core(column, value); + } + pcb = pcb->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +tcp_ListenerTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct tcp_pcb_listen *pcb; + struct snmp_next_oid_state state; + /* 1x tcpListenerLocalAddressType + 1x OID len + 16x tcpListenerLocalAddress + 1x tcpListenerLocalPort */ + u32_t result_temp[19]; + + LWIP_UNUSED_ARG(value_len); + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); + + /* iterate over all possible OIDs to find the next one */ + pcb = tcp_listen_pcbs.listen_pcbs; + while (pcb != NULL) { + u8_t idx = 0; + u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; + + /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */ + idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, idx, NULL); + + pcb = pcb->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return tcp_ListenerTable_get_cell_value_core(column, value); + } else { + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; + } +} + +static const struct snmp_scalar_node tcp_RtoAlgorithm = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); +static const struct snmp_scalar_node tcp_RtoMin = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); +static const struct snmp_scalar_node tcp_RtoMax = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); +static const struct snmp_scalar_node tcp_MaxConn = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); +static const struct snmp_scalar_node tcp_ActiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_PassiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_AttemptFails = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_EstabResets = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_CurrEstab = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_GAUGE, tcp_get_value); +static const struct snmp_scalar_node tcp_InSegs = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_OutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_RetransSegs = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_InErrs = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_OutRsts = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); +static const struct snmp_scalar_node tcp_HCInSegs = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value); +static const struct snmp_scalar_node tcp_HCOutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value); + +#if LWIP_IPV4 +static const struct snmp_table_simple_col_def tcp_ConnTable_columns[] = { + { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnState */ + { 2, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalAddress */ + { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalPort */ + { 4, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnRemAddress */ + { 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnRemPort */ +}; + +static const struct snmp_table_simple_node tcp_ConnTable = SNMP_TABLE_CREATE_SIMPLE(13, tcp_ConnTable_columns, tcp_ConnTable_get_cell_value, tcp_ConnTable_get_next_cell_instance_and_value); +#endif /* LWIP_IPV4 */ + +static const struct snmp_table_simple_col_def tcp_ConnectionTable_columns[] = { + /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */ + { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnectionState */ + { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnectionProcess */ +}; + +static const struct snmp_table_simple_node tcp_ConnectionTable = SNMP_TABLE_CREATE_SIMPLE(19, tcp_ConnectionTable_columns, tcp_ConnectionTable_get_cell_value, tcp_ConnectionTable_get_next_cell_instance_and_value); + + +static const struct snmp_table_simple_col_def tcp_ListenerTable_columns[] = { + /* all items except tcpListenerProcess are declared as not-accessible */ + { 4, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpListenerProcess */ +}; + +static const struct snmp_table_simple_node tcp_ListenerTable = SNMP_TABLE_CREATE_SIMPLE(20, tcp_ListenerTable_columns, tcp_ListenerTable_get_cell_value, tcp_ListenerTable_get_next_cell_instance_and_value); + +/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ +CREATE_LWIP_SYNC_NODE( 1, tcp_RtoAlgorithm) +CREATE_LWIP_SYNC_NODE( 2, tcp_RtoMin) +CREATE_LWIP_SYNC_NODE( 3, tcp_RtoMax) +CREATE_LWIP_SYNC_NODE( 4, tcp_MaxConn) +CREATE_LWIP_SYNC_NODE( 5, tcp_ActiveOpens) +CREATE_LWIP_SYNC_NODE( 6, tcp_PassiveOpens) +CREATE_LWIP_SYNC_NODE( 7, tcp_AttemptFails) +CREATE_LWIP_SYNC_NODE( 8, tcp_EstabResets) +CREATE_LWIP_SYNC_NODE( 9, tcp_CurrEstab) +CREATE_LWIP_SYNC_NODE(10, tcp_InSegs) +CREATE_LWIP_SYNC_NODE(11, tcp_OutSegs) +CREATE_LWIP_SYNC_NODE(12, tcp_RetransSegs) +#if LWIP_IPV4 +CREATE_LWIP_SYNC_NODE(13, tcp_ConnTable) +#endif /* LWIP_IPV4 */ +CREATE_LWIP_SYNC_NODE(14, tcp_InErrs) +CREATE_LWIP_SYNC_NODE(15, tcp_OutRsts) +CREATE_LWIP_SYNC_NODE(17, tcp_HCInSegs) +CREATE_LWIP_SYNC_NODE(18, tcp_HCOutSegs) +CREATE_LWIP_SYNC_NODE(19, tcp_ConnectionTable) +CREATE_LWIP_SYNC_NODE(20, tcp_ListenerTable) + +static const struct snmp_node* const tcp_nodes[] = { + &SYNC_NODE_NAME(tcp_RtoAlgorithm).node.node, + &SYNC_NODE_NAME(tcp_RtoMin).node.node, + &SYNC_NODE_NAME(tcp_RtoMax).node.node, + &SYNC_NODE_NAME(tcp_MaxConn).node.node, + &SYNC_NODE_NAME(tcp_ActiveOpens).node.node, + &SYNC_NODE_NAME(tcp_PassiveOpens).node.node, + &SYNC_NODE_NAME(tcp_AttemptFails).node.node, + &SYNC_NODE_NAME(tcp_EstabResets).node.node, + &SYNC_NODE_NAME(tcp_CurrEstab).node.node, + &SYNC_NODE_NAME(tcp_InSegs).node.node, + &SYNC_NODE_NAME(tcp_OutSegs).node.node, + &SYNC_NODE_NAME(tcp_RetransSegs).node.node, +#if LWIP_IPV4 + &SYNC_NODE_NAME(tcp_ConnTable).node.node, +#endif /* LWIP_IPV4 */ + &SYNC_NODE_NAME(tcp_InErrs).node.node, + &SYNC_NODE_NAME(tcp_OutRsts).node.node, + &SYNC_NODE_NAME(tcp_HCInSegs).node.node, + &SYNC_NODE_NAME(tcp_HCOutSegs).node.node, + &SYNC_NODE_NAME(tcp_ConnectionTable).node.node, + &SYNC_NODE_NAME(tcp_ListenerTable).node.node +}; + +const struct snmp_tree_node snmp_mib2_tcp_root = SNMP_CREATE_TREE_NODE(6, tcp_nodes); +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_udp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_udp.c new file mode 100644 index 0000000..6a983df --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_mib2_udp.c @@ -0,0 +1,357 @@ +/** + * @file + * Management Information Base II (RFC1213) UDP objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" +#include "lwip/udp.h" +#include "lwip/stats.h" + +#include + +#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +/* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */ + +static s16_t +udp_get_value(struct snmp_node_instance* instance, void* value) +{ + u32_t *uint_ptr = (u32_t*)value; + + switch (instance->node->oid) { + case 1: /* udpInDatagrams */ + *uint_ptr = STATS_GET(mib2.udpindatagrams); + return sizeof(*uint_ptr); + case 2: /* udpNoPorts */ + *uint_ptr = STATS_GET(mib2.udpnoports); + return sizeof(*uint_ptr); + case 3: /* udpInErrors */ + *uint_ptr = STATS_GET(mib2.udpinerrors); + return sizeof(*uint_ptr); + case 4: /* udpOutDatagrams */ + *uint_ptr = STATS_GET(mib2.udpoutdatagrams); + return sizeof(*uint_ptr); + case 8: /* udpHCInDatagrams */ + memset(value, 0, 2*sizeof(u32_t)); /* not supported */ + return 2*sizeof(u32_t); + case 9: /* udpHCOutDatagrams */ + memset(value, 0, 2*sizeof(u32_t)); /* not supported */ + return 2*sizeof(u32_t); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); + break; + } + + return 0; +} + +/* --- udpEndpointTable --- */ + +static snmp_err_t +udp_endpointTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value) +{ + /* all items except udpEndpointProcess are declared as not-accessible */ + switch (*column) { + case 8: /* udpEndpointProcess */ + value->u32 = 0; /* not supported */ + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +udp_endpointTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip_addr_t local_ip, remote_ip; + u16_t local_port, remote_port; + struct udp_pcb *pcb; + u8_t idx = 0; + + LWIP_UNUSED_ARG(value_len); + + /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ + idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); + if (idx == 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ + idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port); + if (idx == 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* udpEndpointInstance */ + if (row_oid_len < (idx+1)) { + return SNMP_ERR_NOSUCHINSTANCE; + } + if (row_oid[idx] != 0) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* find udp_pcb with requested ip and port*/ + pcb = udp_pcbs; + while (pcb != NULL) { + if (ip_addr_cmp(&local_ip, &pcb->local_ip) && + (local_port == pcb->local_port) && + ip_addr_cmp(&remote_ip, &pcb->remote_ip) && + (remote_port == pcb->remote_port)) { + /* fill in object properties */ + return udp_endpointTable_get_cell_value_core(column, value); + } + pcb = pcb->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +udp_endpointTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct udp_pcb *pcb; + struct snmp_next_oid_state state; + /* 1x udpEndpointLocalAddressType + 1x OID len + 16x udpEndpointLocalAddress + 1x udpEndpointLocalPort + + * 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort + + * 1x udpEndpointInstance = 39 + */ + u32_t result_temp[39]; + + LWIP_UNUSED_ARG(value_len); + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); + + /* iterate over all possible OIDs to find the next one */ + pcb = udp_pcbs; + while (pcb != NULL) { + u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; + u8_t idx = 0; + + /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ + idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); + + /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ + idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]); + + test_oid[idx] = 0; /* udpEndpointInstance */ + idx++; + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, idx, NULL); + + pcb = pcb->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return udp_endpointTable_get_cell_value_core(column, value); + } else { + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; + } +} + +/* --- udpTable --- */ + +#if LWIP_IPV4 + +/* list of allowed value ranges for incoming OID */ +static const struct snmp_oid_range udp_Table_oid_ranges[] = { + { 0, 0xff }, /* IP A */ + { 0, 0xff }, /* IP B */ + { 0, 0xff }, /* IP C */ + { 0, 0xff }, /* IP D */ + { 1, 0xffff } /* Port */ +}; + +static snmp_err_t +udp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) +{ + LWIP_UNUSED_ARG(value_len); + + switch (*column) { + case 1: /* udpLocalAddress */ + /* set reference to PCB local IP and return a generic node that copies IP4 addresses */ + value->u32 = ip_2_ip4(&pcb->local_ip)->addr; + break; + case 2: /* udpLocalPort */ + /* set reference to PCB local port and return a generic node that copies u16_t values */ + value->u32 = pcb->local_port; + break; + default: + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static snmp_err_t +udp_Table_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) +{ + ip4_addr_t ip; + u16_t port; + struct udp_pcb *pcb; + + /* check if incoming OID length and if values are in plausible range */ + if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + /* get IP and port from incoming OID */ + snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ + port = (u16_t)row_oid[4]; + + /* find udp_pcb with requested ip and port*/ + pcb = udp_pcbs; + while (pcb != NULL) { + if (IP_IS_V4_VAL(pcb->local_ip)) { + if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) { + /* fill in object properties */ + return udp_Table_get_cell_value_core(pcb, column, value, value_len); + } + } + pcb = pcb->next; + } + + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; +} + +static snmp_err_t +udp_Table_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) +{ + struct udp_pcb *pcb; + struct snmp_next_oid_state state; + u32_t result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; + + /* init struct to search next oid */ + snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges)); + + /* iterate over all possible OIDs to find the next one */ + pcb = udp_pcbs; + while (pcb != NULL) { + u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; + + if (IP_IS_V4_VAL(pcb->local_ip)) { + snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]); + test_oid[4] = pcb->local_port; + + /* check generated OID: is it a candidate for the next one? */ + snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb); + } + + pcb = pcb->next; + } + + /* did we find a next one? */ + if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { + snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); + /* fill in object properties */ + return udp_Table_get_cell_value_core((struct udp_pcb*)state.reference, column, value, value_len); + } else { + /* not found */ + return SNMP_ERR_NOSUCHINSTANCE; + } +} + +#endif /* LWIP_IPV4 */ + +static const struct snmp_scalar_node udp_inDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER, udp_get_value); +static const struct snmp_scalar_node udp_noPorts = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER, udp_get_value); +static const struct snmp_scalar_node udp_inErrors = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, udp_get_value); +static const struct snmp_scalar_node udp_outDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, udp_get_value); +static const struct snmp_scalar_node udp_HCInDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); +static const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); + +#if LWIP_IPV4 +static const struct snmp_table_simple_col_def udp_Table_columns[] = { + { 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */ + { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpLocalPort */ +}; +static const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value); +#endif /* LWIP_IPV4 */ + +static const struct snmp_table_simple_col_def udp_endpointTable_columns[] = { + /* all items except udpEndpointProcess are declared as not-accessible */ + { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpEndpointProcess */ +}; + +static const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value); + +/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ +CREATE_LWIP_SYNC_NODE(1, udp_inDatagrams) +CREATE_LWIP_SYNC_NODE(2, udp_noPorts) +CREATE_LWIP_SYNC_NODE(3, udp_inErrors) +CREATE_LWIP_SYNC_NODE(4, udp_outDatagrams) +#if LWIP_IPV4 +CREATE_LWIP_SYNC_NODE(5, udp_Table) +#endif /* LWIP_IPV4 */ +CREATE_LWIP_SYNC_NODE(7, udp_endpointTable) +CREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams) +CREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams) + +static const struct snmp_node* const udp_nodes[] = { + &SYNC_NODE_NAME(udp_inDatagrams).node.node, + &SYNC_NODE_NAME(udp_noPorts).node.node, + &SYNC_NODE_NAME(udp_inErrors).node.node, + &SYNC_NODE_NAME(udp_outDatagrams).node.node, +#if LWIP_IPV4 + &SYNC_NODE_NAME(udp_Table).node.node, +#endif /* LWIP_IPV4 */ + &SYNC_NODE_NAME(udp_endpointTable).node.node, + &SYNC_NODE_NAME(udp_HCInDatagrams).node.node, + &SYNC_NODE_NAME(udp_HCOutDatagrams).node.node +}; + +const struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes); +#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.c new file mode 100644 index 0000000..0cb7ca9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.c @@ -0,0 +1,1668 @@ +/** + * @file + * SNMP message processing (RFC1157). + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel + * Elias Oenal + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "snmp_msg.h" +#include "snmp_asn1.h" +#include "snmp_core_priv.h" +#include "lwip/ip_addr.h" +#include "lwip/stats.h" + +#if LWIP_SNMP_V3 +#include "lwip/apps/snmpv3.h" +#include "snmpv3_priv.h" +#ifdef LWIP_SNMPV3_INCLUDE_ENGINE +#include LWIP_SNMPV3_INCLUDE_ENGINE +#endif +#endif + +#include + +/* public (non-static) constants */ +/** SNMP community string */ +const char *snmp_community = SNMP_COMMUNITY; +/** SNMP community string for write access */ +const char *snmp_community_write = SNMP_COMMUNITY_WRITE; +/** SNMP community string for sending traps */ +const char *snmp_community_trap = SNMP_COMMUNITY_TRAP; + +snmp_write_callback_fct snmp_write_callback = NULL; +void* snmp_write_callback_arg = NULL; + +/** + * @ingroup snmp_core + * Returns current SNMP community string. + * @return current SNMP community string + */ +const char * +snmp_get_community(void) +{ + return snmp_community; +} + +/** + * @ingroup snmp_core + * Sets SNMP community string. + * The string itself (its storage) must be valid throughout the whole life of + * program (or until it is changed to sth else). + * + * @param community is a pointer to new community string + */ +void +snmp_set_community(const char * const community) +{ + LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); + snmp_community = community; +} + +/** + * @ingroup snmp_core + * Returns current SNMP write-access community string. + * @return current SNMP write-access community string + */ +const char * +snmp_get_community_write(void) +{ + return snmp_community_write; +} + +/** + * @ingroup snmp_traps + * Returns current SNMP community string used for sending traps. + * @return current SNMP community string used for sending traps + */ +const char * +snmp_get_community_trap(void) +{ + return snmp_community_trap; +} + +/** + * @ingroup snmp_core + * Sets SNMP community string for write-access. + * The string itself (its storage) must be valid throughout the whole life of + * program (or until it is changed to sth else). + * + * @param community is a pointer to new write-access community string + */ +void +snmp_set_community_write(const char * const community) +{ + LWIP_ASSERT("community string must not be NULL", community != NULL); + LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); + snmp_community_write = community; +} + +/** + * @ingroup snmp_traps + * Sets SNMP community string used for sending traps. + * The string itself (its storage) must be valid throughout the whole life of + * program (or until it is changed to sth else). + * + * @param community is a pointer to new trap community string + */ +void +snmp_set_community_trap(const char * const community) +{ + LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); + snmp_community_trap = community; +} + +/** + * @ingroup snmp_core + * Callback fired on every successful write access + */ +void +snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg) +{ + snmp_write_callback = write_callback; + snmp_write_callback_arg = callback_arg; +} + +/* ----------------------------------------------------------------------- */ +/* forward declarations */ +/* ----------------------------------------------------------------------- */ + +static err_t snmp_process_get_request(struct snmp_request *request); +static err_t snmp_process_getnext_request(struct snmp_request *request); +static err_t snmp_process_getbulk_request(struct snmp_request *request); +static err_t snmp_process_set_request(struct snmp_request *request); + +static err_t snmp_parse_inbound_frame(struct snmp_request *request); +static err_t snmp_prepare_outbound_frame(struct snmp_request *request); +static err_t snmp_complete_outbound_frame(struct snmp_request *request); +static void snmp_execute_write_callbacks(struct snmp_request *request); + + +/* ----------------------------------------------------------------------- */ +/* implementation */ +/* ----------------------------------------------------------------------- */ + +void +snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port) +{ + err_t err; + struct snmp_request request; + + memset(&request, 0, sizeof(request)); + request.handle = handle; + request.source_ip = source_ip; + request.source_port = port; + request.inbound_pbuf = p; + + snmp_stats.inpkts++; + + err = snmp_parse_inbound_frame(&request); + if (err == ERR_OK) { + err = snmp_prepare_outbound_frame(&request); + if (err == ERR_OK) { + + if (request.error_status == SNMP_ERR_NOERROR) { + /* only process frame if we do not already have an error to return (e.g. all readonly) */ + if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_REQ) { + err = snmp_process_get_request(&request); + } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ) { + err = snmp_process_getnext_request(&request); + } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { + err = snmp_process_getbulk_request(&request); + } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { + err = snmp_process_set_request(&request); + } + } + + if (err == ERR_OK) { + err = snmp_complete_outbound_frame(&request); + + if (err == ERR_OK) { + err = snmp_sendto(request.handle, request.outbound_pbuf, request.source_ip, request.source_port); + + if ((request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) + && (request.error_status == SNMP_ERR_NOERROR) + && (snmp_write_callback != NULL)) { + /* raise write notification for all written objects */ + snmp_execute_write_callbacks(&request); + } + } + } + } + + if (request.outbound_pbuf != NULL) { + pbuf_free(request.outbound_pbuf); + } + } +} + +static u8_t +snmp_msg_getnext_validate_node_inst(struct snmp_node_instance* node_instance, void* validate_arg) +{ + if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != SNMP_NODE_INSTANCE_ACCESS_READ) || (node_instance->get_value == NULL)) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + if ((node_instance->asn1_type == SNMP_ASN1_TYPE_COUNTER64) && (((struct snmp_request*)validate_arg)->version == SNMP_VERSION_1)) { + /* according to RFC 2089 skip Counter64 objects in GetNext requests from v1 clients */ + return SNMP_ERR_NOSUCHINSTANCE; + } + + return SNMP_ERR_NOERROR; +} + +static void +snmp_process_varbind(struct snmp_request *request, struct snmp_varbind *vb, u8_t get_next) +{ + err_t err; + struct snmp_node_instance node_instance; + memset(&node_instance, 0, sizeof(node_instance)); + + if (get_next) { + struct snmp_obj_id result_oid; + request->error_status = snmp_get_next_node_instance_from_oid(vb->oid.id, vb->oid.len, snmp_msg_getnext_validate_node_inst, request, &result_oid, &node_instance); + + if (request->error_status == SNMP_ERR_NOERROR) { + snmp_oid_assign(&vb->oid, result_oid.id, result_oid.len); + } + } else { + request->error_status = snmp_get_node_instance_from_oid(vb->oid.id, vb->oid.len, &node_instance); + + if (request->error_status == SNMP_ERR_NOERROR) { + /* use 'getnext_validate' method for validation to avoid code duplication (some checks have to be executed here) */ + request->error_status = snmp_msg_getnext_validate_node_inst(&node_instance, request); + + if (request->error_status != SNMP_ERR_NOERROR) { + if (node_instance.release_instance != NULL) { + node_instance.release_instance(&node_instance); + } + } + } + } + + if (request->error_status != SNMP_ERR_NOERROR) { + if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) { + if ((request->version == SNMP_VERSION_2c) || request->version == SNMP_VERSION_3) { + /* in SNMP v2c a varbind related exception is stored in varbind and not in frame header */ + vb->type = (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | (request->error_status & SNMP_VARBIND_EXCEPTION_MASK)); + vb->value_len = 0; + + err = snmp_append_outbound_varbind(&(request->outbound_pbuf_stream), vb); + if (err == ERR_OK) { + /* we stored the exception in varbind -> go on */ + request->error_status = SNMP_ERR_NOERROR; + } else if (err == ERR_BUF) { + request->error_status = SNMP_ERR_TOOBIG; + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } + } else { + /* according to RFC 1157/1905, all other errors only return genError */ + request->error_status = SNMP_ERR_GENERROR; + } + } else { + s16_t len = node_instance.get_value(&node_instance, vb->value); + vb->type = node_instance.asn1_type; + + if(len >= 0) { + vb->value_len = (u16_t)len; /* cast is OK because we checked >= 0 above */ + + LWIP_ASSERT("SNMP_MAX_VALUE_SIZE is configured too low", (vb->value_len & ~SNMP_GET_VALUE_RAW_DATA) <= SNMP_MAX_VALUE_SIZE); + err = snmp_append_outbound_varbind(&request->outbound_pbuf_stream, vb); + + if (err == ERR_BUF) { + request->error_status = SNMP_ERR_TOOBIG; + } else if (err != ERR_OK) { + request->error_status = SNMP_ERR_GENERROR; + } + } else { + request->error_status = SNMP_ERR_GENERROR; + } + + if (node_instance.release_instance != NULL) { + node_instance.release_instance(&node_instance); + } + } +} + + +/** + * Service an internal or external event for SNMP GET. + * + * @param request points to the associated message process state + */ +static err_t +snmp_process_get_request(struct snmp_request *request) +{ + snmp_vb_enumerator_err_t err; + struct snmp_varbind vb; + vb.value = request->value_buffer; + + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get request\n")); + + while (request->error_status == SNMP_ERR_NOERROR) { + err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_OK) { + if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) { + snmp_process_varbind(request, &vb, 0); + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { + /* malformed ASN.1, don't answer */ + return ERR_ARG; + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } + + return ERR_OK; +} + +/** + * Service an internal or external event for SNMP GET. + * + * @param request points to the associated message process state + */ +static err_t +snmp_process_getnext_request(struct snmp_request *request) +{ + snmp_vb_enumerator_err_t err; + struct snmp_varbind vb; + vb.value = request->value_buffer; + + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-next request\n")); + + while (request->error_status == SNMP_ERR_NOERROR) { + err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_OK) { + if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) { + snmp_process_varbind(request, &vb, 1); + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { + /* malformed ASN.1, don't answer */ + return ERR_ARG; + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } + + return ERR_OK; +} + +/** + * Service an internal or external event for SNMP GETBULKT. + * + * @param request points to the associated message process state + */ +static err_t +snmp_process_getbulk_request(struct snmp_request *request) +{ + snmp_vb_enumerator_err_t err; + s32_t non_repeaters = request->non_repeaters; + s32_t repetitions; + u16_t repetition_offset = 0; + struct snmp_varbind_enumerator repetition_varbind_enumerator; + struct snmp_varbind vb; + vb.value = request->value_buffer; + + if (SNMP_LWIP_GETBULK_MAX_REPETITIONS > 0) { + repetitions = LWIP_MIN(request->max_repetitions, SNMP_LWIP_GETBULK_MAX_REPETITIONS); + } else { + repetitions = request->max_repetitions; + } + + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-bulk request\n")); + + /* process non repeaters and first repetition */ + while (request->error_status == SNMP_ERR_NOERROR) { + if (non_repeaters == 0) { + repetition_offset = request->outbound_pbuf_stream.offset; + + if (repetitions == 0) { + /* do not resolve repeaters when repetitions is set to 0 */ + break; + } + repetitions--; + } + + err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { + /* malformed ASN.1, don't answer */ + return ERR_ARG; + } else if ((err != SNMP_VB_ENUMERATOR_ERR_OK) || (vb.type != SNMP_ASN1_TYPE_NULL) || (vb.value_len != 0)) { + request->error_status = SNMP_ERR_GENERROR; + } else { + snmp_process_varbind(request, &vb, 1); + non_repeaters--; + } + } + + /* process repetitions > 1 */ + while ((request->error_status == SNMP_ERR_NOERROR) && (repetitions > 0) && (request->outbound_pbuf_stream.offset != repetition_offset)) { + + u8_t all_endofmibview = 1; + + snmp_vb_enumerator_init(&repetition_varbind_enumerator, request->outbound_pbuf, repetition_offset, request->outbound_pbuf_stream.offset - repetition_offset); + repetition_offset = request->outbound_pbuf_stream.offset; /* for next loop */ + + while (request->error_status == SNMP_ERR_NOERROR) { + vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned) */ + err = snmp_vb_enumerator_get_next(&repetition_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_OK) { + vb.value = request->value_buffer; + snmp_process_varbind(request, &vb, 1); + + if (request->error_status != SNMP_ERR_NOERROR) { + /* already set correct error-index (here it cannot be taken from inbound varbind enumerator) */ + request->error_index = request->non_repeaters + repetition_varbind_enumerator.varbind_count; + } else if (vb.type != (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW)) { + all_endofmibview = 0; + } + } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else { + LWIP_DEBUGF(SNMP_DEBUG, ("Very strange, we cannot parse the varbind output that we created just before!")); + request->error_status = SNMP_ERR_GENERROR; + request->error_index = request->non_repeaters + repetition_varbind_enumerator.varbind_count; + } + } + + if ((request->error_status == SNMP_ERR_NOERROR) && all_endofmibview) { + /* stop when all varbinds in a loop return EndOfMibView */ + break; + } + + repetitions--; + } + + if (request->error_status == SNMP_ERR_TOOBIG) { + /* for GetBulk it is ok, if not all requested variables fit into the response -> just return the varbinds added so far */ + request->error_status = SNMP_ERR_NOERROR; + } + + return ERR_OK; +} + +/** + * Service an internal or external event for SNMP SET. + * + * @param request points to the associated message process state + */ +static err_t +snmp_process_set_request(struct snmp_request *request) +{ + snmp_vb_enumerator_err_t err; + struct snmp_varbind vb; + vb.value = request->value_buffer; + + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP set request\n")); + + /* perform set test on all objects */ + while (request->error_status == SNMP_ERR_NOERROR) { + err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_OK) { + struct snmp_node_instance node_instance; + memset(&node_instance, 0, sizeof(node_instance)); + + request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance); + if (request->error_status == SNMP_ERR_NOERROR) { + if (node_instance.asn1_type != vb.type) { + request->error_status = SNMP_ERR_WRONGTYPE; + } else if (((node_instance.access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != SNMP_NODE_INSTANCE_ACCESS_WRITE) || (node_instance.set_value == NULL)) { + request->error_status = SNMP_ERR_NOTWRITABLE; + } else { + if (node_instance.set_test != NULL) { + request->error_status = node_instance.set_test(&node_instance, vb.value_len, vb.value); + } + } + + if (node_instance.release_instance != NULL) { + node_instance.release_instance(&node_instance); + } + } + } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else if (err == SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH) { + request->error_status = SNMP_ERR_WRONGLENGTH; + } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { + /* malformed ASN.1, don't answer */ + return ERR_ARG; + } else { + request->error_status = SNMP_ERR_GENERROR; + } + } + + /* perform real set operation on all objects */ + if (request->error_status == SNMP_ERR_NOERROR) { + snmp_vb_enumerator_init(&request->inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); + while (request->error_status == SNMP_ERR_NOERROR) { + err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); + if (err == SNMP_VB_ENUMERATOR_ERR_OK) { + struct snmp_node_instance node_instance; + memset(&node_instance, 0, sizeof(node_instance)); + request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance); + if (request->error_status == SNMP_ERR_NOERROR) { + if (node_instance.set_value(&node_instance, vb.value_len, vb.value) != SNMP_ERR_NOERROR) { + if (request->inbound_varbind_enumerator.varbind_count == 1) { + request->error_status = SNMP_ERR_COMMITFAILED; + } else { + /* we cannot undo the set operations done so far */ + request->error_status = SNMP_ERR_UNDOFAILED; + } + } + + if (node_instance.release_instance != NULL) { + node_instance.release_instance(&node_instance); + } + } + } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { + /* no more varbinds in request */ + break; + } else { + /* first time enumerating varbinds work but second time not, although nothing should have changed in between ??? */ + request->error_status = SNMP_ERR_GENERROR; + } + } + } + + return ERR_OK; +} + +#define PARSE_EXEC(code, retValue) \ + if ((code) != ERR_OK) { \ + LWIP_DEBUGF(SNMP_DEBUG, ("Malformed ASN.1 detected.\n")); \ + snmp_stats.inasnparseerrs++; \ + return retValue; \ + } + +#define PARSE_ASSERT(cond, retValue) \ + if (!(cond)) { \ + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP parse assertion failed!: " # cond)); \ + snmp_stats.inasnparseerrs++; \ + return retValue; \ + } + +#define BUILD_EXEC(code, retValue) \ + if ((code) != ERR_OK) { \ + LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound frame!: " # code)); \ + return retValue; \ + } + +#define IF_PARSE_EXEC(code) PARSE_EXEC(code, ERR_ARG) +#define IF_PARSE_ASSERT(code) PARSE_ASSERT(code, ERR_ARG) + +/** + * Checks and decodes incoming SNMP message header, logs header errors. + * + * @param request points to the current message request state return + * @return + * - ERR_OK SNMP header is sane and accepted + * - ERR_VAL SNMP header is either malformed or rejected + */ +static err_t +snmp_parse_inbound_frame(struct snmp_request *request) +{ + struct snmp_pbuf_stream pbuf_stream; + struct snmp_asn1_tlv tlv; + s32_t parent_tlv_value_len; + s32_t s32_value; + err_t err; + + IF_PARSE_EXEC(snmp_pbuf_stream_init(&pbuf_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); + + /* decode main container consisting of version, community and PDU */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len == pbuf_stream.length)); + parent_tlv_value_len = tlv.value_len; + + /* decode version */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + if ((s32_value != SNMP_VERSION_1) && + (s32_value != SNMP_VERSION_2c) +#if LWIP_SNMP_V3 + && (s32_value != SNMP_VERSION_3) +#endif + ) + { + /* unsupported SNMP version */ + snmp_stats.inbadversions++; + return ERR_ARG; + } + request->version = (u8_t)s32_value; + +#if LWIP_SNMP_V3 + if (request->version == SNMP_VERSION_3) { + u16_t u16_value; + u16_t inbound_msgAuthenticationParameters_offset; + + /* SNMPv3 doesn't use communities */ + /* @todo: Differentiate read/write access */ + strcpy((char*)request->community, snmp_community); + request->community_strlen = (u16_t)strlen(snmp_community); + + /* RFC3414 globalData */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); + parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + /* decode msgID */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + request->msg_id = s32_value; + + /* decode msgMaxSize */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + request->msg_max_size = s32_value; + + /* decode msgFlags */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + request->msg_flags = (u8_t)s32_value; + + /* decode msgSecurityModel */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + request->msg_security_model = s32_value; + + /* RFC3414 msgSecurityParameters + * The User-based Security Model defines the contents of the OCTET + * STRING as a SEQUENCE. + * + * We skip the protective dummy OCTET STRING header + * to access the SEQUENCE header. + */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + /* msgSecurityParameters SEQUENCE header */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); + parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + /* decode msgAuthoritativeEngineID */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authoritative_engine_id, + &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); + request->msg_authoritative_engine_id_len = (u8_t)u16_value; + + /* msgAuthoritativeEngineBoots */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_boots)); + + /* msgAuthoritativeEngineTime */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_time)); + /* @todo: Implement time window checking */ + + /* msgUserName */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_user_name, + &u16_value, SNMP_V3_MAX_USER_LENGTH)); + request->msg_user_name_len = (u8_t)u16_value; + /* @todo: Implement unknown user error response */ + IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, NULL, NULL)); + + /* msgAuthenticationParameters */ + memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH); + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + /* Remember position */ + inbound_msgAuthenticationParameters_offset = pbuf_stream.offset; + LWIP_UNUSED_ARG(inbound_msgAuthenticationParameters_offset); + /* Read auth parameters */ + IF_PARSE_ASSERT(tlv.value_len <= SNMP_V3_MAX_AUTH_PARAM_LENGTH); + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authentication_parameters, + &u16_value, tlv.value_len)); + +#if LWIP_SNMP_V3_CRYPTO + if (request->msg_flags & SNMP_V3_AUTH_FLAG) { + const u8_t zero_arr[SNMP_V3_MAX_AUTH_PARAM_LENGTH] = { 0 }; + u8_t key[20]; + u8_t algo; + u8_t hmac[LWIP_MAX(SNMP_V3_SHA_LEN, SNMP_V3_MD5_LEN)]; + struct snmp_pbuf_stream auth_stream; + + /* Rewind stream */ + IF_PARSE_EXEC(snmp_pbuf_stream_init(&pbuf_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); + IF_PARSE_EXEC(snmp_pbuf_stream_seek_abs(&pbuf_stream, inbound_msgAuthenticationParameters_offset)); + /* Set auth parameters to zero for verification */ + IF_PARSE_EXEC(snmp_asn1_enc_raw(&pbuf_stream, zero_arr, tlv.value_len)); + + /* Verify authentication */ + IF_PARSE_EXEC(snmp_pbuf_stream_init(&auth_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); + + IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, &algo, key, NULL, NULL)); + IF_PARSE_EXEC(snmpv3_auth(&auth_stream, request->inbound_pbuf->tot_len, key, algo, hmac)); + /* @todo: Implement error response */ + IF_PARSE_EXEC(memcmp(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); + } +#else + /* Ungraceful exit if we encounter cryptography and don't support it. + * @todo: Implement error response + */ + IF_PARSE_ASSERT(!(request->msg_flags & (SNMP_V3_AUTH_FLAG | SNMP_V3_PRIV_FLAG))); +#endif + + /* msgPrivacyParameters */ + memset(request->msg_privacy_parameters, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH); + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_privacy_parameters, + &u16_value, SNMP_V3_MAX_PRIV_PARAM_LENGTH)); + +#if LWIP_SNMP_V3_CRYPTO + /* Decrypt message */ + if (request->msg_flags & SNMP_V3_PRIV_FLAG) { + u8_t key[20]; + u8_t algo; + + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, &algo, key)); + IF_PARSE_EXEC(snmpv3_crypt(&pbuf_stream, tlv.value_len, key, + request->msg_privacy_parameters, request->msg_authoritative_engine_boots, + request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_DECRYPT)); + } +#endif + + /* Scoped PDU + * Encryption context + */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); + parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + /* contextEngineID */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_engine_id, + &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); + request->context_engine_id_len = (u8_t)u16_value; + + /* contextName */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_name, + &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); + request->context_name_len = (u8_t)u16_value; + } else +#endif + { + /* decode community */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + err = snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->community, &request->community_strlen, SNMP_MAX_COMMUNITY_STR_LEN); + if (err == ERR_MEM) { + /* community string does not fit in our buffer -> its too long -> its invalid */ + request->community_strlen = 0; + snmp_pbuf_stream_seek(&pbuf_stream, tlv.value_len); + } else { + IF_PARSE_ASSERT(err == ERR_OK); + } + /* add zero terminator */ + request->community[request->community_strlen] = 0; + } + + /* decode PDU type (next container level) */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.value_len <= pbuf_stream.length); + request->inbound_padding_len = pbuf_stream.length - tlv.value_len; + parent_tlv_value_len = tlv.value_len; + + /* validate PDU type */ + switch(tlv.type) { + case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_REQ): + /* GetRequest PDU */ + snmp_stats.ingetrequests++; + break; + case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ): + /* GetNextRequest PDU */ + snmp_stats.ingetnexts++; + break; + case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ): + /* GetBulkRequest PDU */ + if (request->version < SNMP_VERSION_2c) { + /* RFC2089: invalid, drop packet */ + return ERR_ARG; + } + break; + case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_SET_REQ): + /* SetRequest PDU */ + snmp_stats.insetrequests++; + break; + default: + /* unsupported input PDU for this agent (no parse error) */ + LWIP_DEBUGF(SNMP_DEBUG, ("Unknown/Invalid SNMP PDU type received: %d", tlv.type)); \ + return ERR_ARG; + break; + } + request->request_type = tlv.type & SNMP_ASN1_DATATYPE_MASK; + + /* validate community (do this after decoding PDU type because we don't want to increase 'inbadcommunitynames' for wrong frame types */ + if (request->community_strlen == 0) { + /* community string was too long or really empty*/ + snmp_stats.inbadcommunitynames++; + snmp_authfail_trap(); + return ERR_ARG; + } else if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { + if (snmp_community_write[0] == 0) { + /* our write community is empty, that means all our objects are readonly */ + request->error_status = SNMP_ERR_NOTWRITABLE; + request->error_index = 1; + } else if (strncmp(snmp_community_write, (const char*)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) { + /* community name does not match */ + snmp_stats.inbadcommunitynames++; + snmp_authfail_trap(); + return ERR_ARG; + } + } else { + if (strncmp(snmp_community, (const char*)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) { + /* community name does not match */ + snmp_stats.inbadcommunitynames++; + snmp_authfail_trap(); + return ERR_ARG; + } + } + + /* decode request ID */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->request_id)); + + /* decode error status / non-repeaters */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->non_repeaters)); + if (request->non_repeaters < 0) { + /* RFC 1905, 4.2.3 */ + request->non_repeaters = 0; + } + } else { + /* only check valid value, don't touch 'request->error_status', maybe a response error status was already set to above; */ + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); + IF_PARSE_ASSERT(s32_value == SNMP_ERR_NOERROR); + } + + /* decode error index / max-repetitions */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); + parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); + IF_PARSE_ASSERT(parent_tlv_value_len > 0); + + if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->max_repetitions)); + if (request->max_repetitions < 0) { + /* RFC 1905, 4.2.3 */ + request->max_repetitions = 0; + } + } else { + IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->error_index)); + IF_PARSE_ASSERT(s32_value == 0); + } + + /* decode varbind-list type (next container level) */ + IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); + IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= pbuf_stream.length)); + + request->inbound_varbind_offset = pbuf_stream.offset; + request->inbound_varbind_len = pbuf_stream.length - request->inbound_padding_len; + snmp_vb_enumerator_init(&(request->inbound_varbind_enumerator), request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); + + return ERR_OK; +} + +#define OF_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG) + +static err_t +snmp_prepare_outbound_frame(struct snmp_request *request) +{ + struct snmp_asn1_tlv tlv; + struct snmp_pbuf_stream* pbuf_stream = &(request->outbound_pbuf_stream); + + /* try allocating pbuf(s) for maximum response size */ + request->outbound_pbuf = pbuf_alloc(PBUF_TRANSPORT, 1472, PBUF_RAM); + if (request->outbound_pbuf == NULL) { + return ERR_MEM; + } + + snmp_pbuf_stream_init(pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len); + + /* 'Message' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + + /* version */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(request->version, &tlv.value_len); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->version) ); + +#if LWIP_SNMP_V3 + if (request->version < SNMP_VERSION_3) { +#endif + /* community */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->community_strlen); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + OF_BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, request->community, request->community_strlen) ); +#if LWIP_SNMP_V3 + } else { + const char* id; + + /* globalData */ + request->outbound_msg_global_data_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + /* msgID */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); + snmp_asn1_enc_s32t_cnt(request->msg_id, &tlv.value_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_id)); + + /* msgMaxSize */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); + snmp_asn1_enc_s32t_cnt(request->msg_max_size, &tlv.value_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_max_size)); + + /* msgFlags */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 1); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, &request->msg_flags, 1)); + + /* msgSecurityModel */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); + snmp_asn1_enc_s32t_cnt(request->msg_security_model, &tlv.value_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_security_model)); + + /* end of msgGlobalData */ + request->outbound_msg_global_data_end = pbuf_stream->offset; + + /* msgSecurityParameters */ + request->outbound_msg_security_parameters_str_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + request->outbound_msg_security_parameters_seq_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + /* msgAuthoritativeEngineID */ + snmpv3_get_engine_id(&id, &request->msg_authoritative_engine_id_len); + MEMCPY(request->msg_authoritative_engine_id, id, request->msg_authoritative_engine_id_len); + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_authoritative_engine_id_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authoritative_engine_id, request->msg_authoritative_engine_id_len)); + + request->msg_authoritative_engine_time = snmpv3_get_engine_time(); + request->msg_authoritative_engine_boots = snmpv3_get_engine_boots(); + + /* msgAuthoritativeEngineBoots */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_boots, &tlv.value_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_boots)); + + /* msgAuthoritativeEngineTime */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_time, &tlv.value_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_time)); + + /* msgUserName */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_user_name_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_user_name, request->msg_user_name_len)); + +#if LWIP_SNMP_V3_CRYPTO + /* msgAuthenticationParameters */ + if (request->msg_flags & SNMP_V3_AUTH_FLAG) { + memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH); + request->outbound_msg_authentication_parameters_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); + } else +#endif + { + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + } + +#if LWIP_SNMP_V3_CRYPTO + /* msgPrivacyParameters */ + if (request->msg_flags & SNMP_V3_PRIV_FLAG) { + snmpv3_build_priv_param(request->msg_privacy_parameters); + + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_privacy_parameters, SNMP_V3_MAX_PRIV_PARAM_LENGTH)); + } else +#endif + { + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + } + + /* End of msgSecurityParameters, so we can calculate the length of this sequence later */ + request->outbound_msg_security_parameters_end = pbuf_stream->offset; + +#if LWIP_SNMP_V3_CRYPTO + /* For encryption we have to encapsulate the payload in an octet string */ + if (request->msg_flags & SNMP_V3_PRIV_FLAG) { + request->outbound_scoped_pdu_string_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + } +#endif + /* Scoped PDU + * Encryption context + */ + request->outbound_scoped_pdu_seq_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + /* contextEngineID */ + snmpv3_get_engine_id(&id, &request->context_engine_id_len); + MEMCPY(request->context_engine_id, id, request->context_engine_id_len); + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_engine_id_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_engine_id, request->context_engine_id_len)); + + /* contextName */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_name_len); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_name, request->context_name_len)); + } +#endif + + /* 'PDU' sequence */ + request->outbound_pdu_offset = pbuf_stream->offset; + SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_RESP), 3, 0); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + + /* request ID */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(request->request_id, &tlv.value_len); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->request_id) ); + + /* error status */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + request->outbound_error_status_offset = pbuf_stream->offset; + OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) ); + + /* error index */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + request->outbound_error_index_offset = pbuf_stream->offset; + OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) ); + + /* 'VarBindList' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); + + request->outbound_varbind_offset = pbuf_stream->offset; + + return ERR_OK; +} + +/** Calculate the length of a varbind list */ +err_t +snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len) +{ + /* calculate required lengths */ + snmp_asn1_enc_oid_cnt(varbind->oid.id, varbind->oid.len, &len->oid_value_len); + snmp_asn1_enc_length_cnt(len->oid_value_len, &len->oid_len_len); + + if (varbind->value_len == 0) { + len->value_value_len = 0; + } else if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) { + len->value_value_len = varbind->value_len & (~SNMP_GET_VALUE_RAW_DATA); + } else { + switch (varbind->type) { + case SNMP_ASN1_TYPE_INTEGER: + if (varbind->value_len != sizeof (s32_t)) { + return ERR_VAL; + } + snmp_asn1_enc_s32t_cnt(*((s32_t*) varbind->value), &len->value_value_len); + break; + case SNMP_ASN1_TYPE_COUNTER: + case SNMP_ASN1_TYPE_GAUGE: + case SNMP_ASN1_TYPE_TIMETICKS: + if (varbind->value_len != sizeof (u32_t)) { + return ERR_VAL; + } + snmp_asn1_enc_u32t_cnt(*((u32_t*) varbind->value), &len->value_value_len); + break; + case SNMP_ASN1_TYPE_OCTET_STRING: + case SNMP_ASN1_TYPE_IPADDR: + case SNMP_ASN1_TYPE_OPAQUE: + len->value_value_len = varbind->value_len; + break; + case SNMP_ASN1_TYPE_NULL: + if (varbind->value_len != 0) { + return ERR_VAL; + } + len->value_value_len = 0; + break; + case SNMP_ASN1_TYPE_OBJECT_ID: + if ((varbind->value_len & 0x03) != 0) { + return ERR_VAL; + } + snmp_asn1_enc_oid_cnt((u32_t*) varbind->value, varbind->value_len >> 2, &len->value_value_len); + break; + case SNMP_ASN1_TYPE_COUNTER64: + if (varbind->value_len != (2 * sizeof (u32_t))) { + return ERR_VAL; + } + snmp_asn1_enc_u64t_cnt((u32_t*) varbind->value, &len->value_value_len); + break; + default: + /* unsupported type */ + return ERR_VAL; + } + } + snmp_asn1_enc_length_cnt(len->value_value_len, &len->value_len_len); + + len->vb_value_len = 1 + len->oid_len_len + len->oid_value_len + 1 + len->value_len_len + len->value_value_len; + snmp_asn1_enc_length_cnt(len->vb_value_len, &len->vb_len_len); + + return ERR_OK; +} + +#define OVB_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG) + +err_t +snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind* varbind) +{ + struct snmp_asn1_tlv tlv; + struct snmp_varbind_len len; + err_t err; + + err = snmp_varbind_length(varbind, &len); + + if (err != ERR_OK) { + return err; + } + + /* check length already before adding first data because in case of GetBulk, + * data added so far is returned and therefore no partial data shall be added + */ + if ((1 + len.vb_len_len + len.vb_value_len) > pbuf_stream->length) { + return ERR_BUF; + } + + /* 'VarBind' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, len.vb_len_len, len.vb_value_len); + OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + /* VarBind OID */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, len.oid_len_len, len.oid_value_len); + OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, varbind->oid.id, varbind->oid.len)); + + /* VarBind value */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, varbind->type, len.value_len_len, len.value_value_len); + OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); + + if (len.value_value_len > 0) { + if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) { + OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t*) varbind->value, len.value_value_len)); + } else { + switch (varbind->type) { + case SNMP_ASN1_TYPE_INTEGER: + OVB_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, len.value_value_len, *((s32_t*) varbind->value))); + break; + case SNMP_ASN1_TYPE_COUNTER: + case SNMP_ASN1_TYPE_GAUGE: + case SNMP_ASN1_TYPE_TIMETICKS: + OVB_BUILD_EXEC(snmp_asn1_enc_u32t(pbuf_stream, len.value_value_len, *((u32_t*) varbind->value))); + break; + case SNMP_ASN1_TYPE_OCTET_STRING: + case SNMP_ASN1_TYPE_IPADDR: + case SNMP_ASN1_TYPE_OPAQUE: + OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t*) varbind->value, len.value_value_len)); + len.value_value_len = varbind->value_len; + break; + case SNMP_ASN1_TYPE_OBJECT_ID: + OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, (u32_t*) varbind->value, varbind->value_len / sizeof (u32_t))); + break; + case SNMP_ASN1_TYPE_COUNTER64: + OVB_BUILD_EXEC(snmp_asn1_enc_u64t(pbuf_stream, len.value_value_len, (u32_t*) varbind->value)); + break; + default: + LWIP_ASSERT("Unknown variable type", 0); + break; + } + } + } + + return ERR_OK; +} + +static err_t +snmp_complete_outbound_frame(struct snmp_request *request) +{ + struct snmp_asn1_tlv tlv; + u16_t frame_size; + u8_t outbound_padding = 0; + + if (request->version == SNMP_VERSION_1) { + if (request->error_status != SNMP_ERR_NOERROR) { + /* map v2c error codes to v1 compliant error code (according to RFC 2089) */ + switch (request->error_status) { + /* mapping of implementation specific "virtual" error codes + * (during processing of frame we already stored them in error_status field, + * so no need to check all varbinds here for those exceptions as suggested by RFC) */ + case SNMP_ERR_NOSUCHINSTANCE: + case SNMP_ERR_NOSUCHOBJECT: + case SNMP_ERR_ENDOFMIBVIEW: + request->error_status = SNMP_ERR_NOSUCHNAME; + break; + /* mapping according to RFC */ + case SNMP_ERR_WRONGVALUE: + case SNMP_ERR_WRONGENCODING: + case SNMP_ERR_WRONGTYPE: + case SNMP_ERR_WRONGLENGTH: + case SNMP_ERR_INCONSISTENTVALUE: + request->error_status = SNMP_ERR_BADVALUE; + break; + case SNMP_ERR_NOACCESS: + case SNMP_ERR_NOTWRITABLE: + case SNMP_ERR_NOCREATION: + case SNMP_ERR_INCONSISTENTNAME: + case SNMP_ERR_AUTHORIZATIONERROR: + request->error_status = SNMP_ERR_NOSUCHNAME; + break; + case SNMP_ERR_RESOURCEUNAVAILABLE: + case SNMP_ERR_COMMITFAILED: + case SNMP_ERR_UNDOFAILED: + default: + request->error_status = SNMP_ERR_GENERROR; + break; + } + } + } else { + if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { + /* map error codes to according to RFC 1905 (4.2.5. The SetRequest-PDU) return 'NotWritable' for unknown OIDs) */ + switch (request->error_status) { + case SNMP_ERR_NOSUCHINSTANCE: + case SNMP_ERR_NOSUCHOBJECT: + case SNMP_ERR_ENDOFMIBVIEW: + request->error_status = SNMP_ERR_NOTWRITABLE; + break; + default: + break; + } + } + + if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) { + /* should never occur because v2 frames store exceptions directly inside varbinds and not as frame error_status */ + LWIP_DEBUGF(SNMP_DEBUG, ("snmp_complete_outbound_frame() > Found v2 request with varbind exception code stored as error status!\n")); + return ERR_ARG; + } + } + + if ((request->error_status != SNMP_ERR_NOERROR) || (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ)) { + /* all inbound vars are returned in response without any modification for error responses and successful set requests*/ + struct snmp_pbuf_stream inbound_stream; + OF_BUILD_EXEC( snmp_pbuf_stream_init(&inbound_stream, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len) ); + OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, request->outbound_varbind_offset, request->outbound_pbuf->tot_len - request->outbound_varbind_offset) ); + snmp_pbuf_stream_writeto(&inbound_stream, &(request->outbound_pbuf_stream), 0); + } + + frame_size = request->outbound_pbuf_stream.offset; + +#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO + /* Calculate padding for encryption */ + if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) { + u8_t i; + outbound_padding = (8 - (u8_t)((frame_size - request->outbound_scoped_pdu_seq_offset) & 0x07)) & 0x07; + for (i = 0; i < outbound_padding; i++) { + snmp_pbuf_stream_write(&request->outbound_pbuf_stream, 0); + } + } +#endif + + /* complete missing length in 'Message' sequence ; 'Message' tlv is located at the beginning (offset 0) */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size + outbound_padding - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ + OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, 0, request->outbound_pbuf->tot_len) ); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); + +#if LWIP_SNMP_V3 + if (request->version == SNMP_VERSION_3) { + /* complete missing length in 'globalData' sequence */ + /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_global_data_end + - request->outbound_msg_global_data_offset - 1 - 1); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_global_data_offset)); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); + + /* complete missing length in 'msgSecurityParameters' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, request->outbound_msg_security_parameters_end + - request->outbound_msg_security_parameters_str_offset - 1 - 1); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_str_offset)); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); + + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_security_parameters_end + - request->outbound_msg_security_parameters_seq_offset - 1 - 1); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_seq_offset)); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); + + /* complete missing length in scoped PDU sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_scoped_pdu_seq_offset - 1 - 3); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_seq_offset)); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); + } +#endif + + /* complete missing length in 'PDU' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_RESP), 3, + frame_size - request->outbound_pdu_offset - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ + OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_pdu_offset) ); + OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); + + /* process and encode final error status */ + if (request->error_status != 0) { + u16_t len; + snmp_asn1_enc_s32t_cnt(request->error_status, &len); + if (len != 1) { + /* error, we only reserved one byte for it */ + return ERR_ARG; + } + OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_status_offset) ); + OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_status) ); + + /* for compatibility to v1, log statistics; in v2 (RFC 1907) these statistics are obsoleted */ + switch (request->error_status) { + case SNMP_ERR_TOOBIG: + snmp_stats.outtoobigs++; + break; + case SNMP_ERR_NOSUCHNAME: + snmp_stats.outnosuchnames++; + break; + case SNMP_ERR_BADVALUE: + snmp_stats.outbadvalues++; + break; + case SNMP_ERR_GENERROR: + default: + snmp_stats.outgenerrs++; + break; + } + + if (request->error_status == SNMP_ERR_TOOBIG) { + request->error_index = 0; /* defined by RFC 1157 */ + } else if (request->error_index == 0) { + /* set index to varbind where error occured (if not already set before, e.g. during GetBulk processing) */ + request->error_index = request->inbound_varbind_enumerator.varbind_count; + } + } else { + if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { + snmp_stats.intotalsetvars += request->inbound_varbind_enumerator.varbind_count; + } else { + snmp_stats.intotalreqvars += request->inbound_varbind_enumerator.varbind_count; + } + } + + /* encode final error index*/ + if (request->error_index != 0) { + u16_t len; + snmp_asn1_enc_s32t_cnt(request->error_index, &len); + if (len != 1) { + /* error, we only reserved one byte for it */ + return ERR_VAL; + } + OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_index_offset) ); + OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_index) ); + } + + /* complete missing length in 'VarBindList' sequence ; 'VarBindList' tlv is located directly before varbind offset */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_varbind_offset); + OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_varbind_offset - 1 - 3) ); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ + OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); + + /* Authenticate response */ +#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO + /* Encrypt response */ + if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) { + u8_t key[20]; + u8_t algo; + + /* complete missing length in PDU sequence */ + OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_string_offset)); + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, frame_size + outbound_padding + - request->outbound_scoped_pdu_string_offset - 1 - 3); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); + + OF_BUILD_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, &algo, key)); + + OF_BUILD_EXEC(snmpv3_crypt(&request->outbound_pbuf_stream, tlv.value_len, key, + request->msg_privacy_parameters, request->msg_authoritative_engine_boots, + request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_ENCRYPT)); + } + + if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_AUTH_FLAG)) { + u8_t key[20]; + u8_t algo; + u8_t hmac[20]; + + OF_BUILD_EXEC(snmpv3_get_user((char*)request->msg_user_name, &algo, key, NULL, NULL)); + OF_BUILD_EXEC(snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), + request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); + OF_BUILD_EXEC(snmpv3_auth(&request->outbound_pbuf_stream, frame_size + outbound_padding, key, algo, hmac)); + + MEMCPY(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH); + OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, + request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); + OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&request->outbound_pbuf_stream, + request->outbound_msg_authentication_parameters_offset)); + + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH); + OF_BUILD_EXEC(snmp_ans1_enc_tlv(&request->outbound_pbuf_stream, &tlv)); + OF_BUILD_EXEC(snmp_asn1_enc_raw(&request->outbound_pbuf_stream, + request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); + } +#endif + + pbuf_realloc(request->outbound_pbuf, frame_size + outbound_padding); + + snmp_stats.outgetresponses++; + snmp_stats.outpkts++; + + return ERR_OK; +} + +static void +snmp_execute_write_callbacks(struct snmp_request *request) +{ + struct snmp_varbind_enumerator inbound_varbind_enumerator; + struct snmp_varbind vb; + + snmp_vb_enumerator_init(&inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); + vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned, which we don't need here) */ + + while (snmp_vb_enumerator_get_next(&inbound_varbind_enumerator, &vb) == SNMP_VB_ENUMERATOR_ERR_OK) { + snmp_write_callback(vb.oid.id, vb.oid.len, snmp_write_callback_arg); + } +} + + +/* ----------------------------------------------------------------------- */ +/* VarBind enumerator methods */ +/* ----------------------------------------------------------------------- */ + +void +snmp_vb_enumerator_init(struct snmp_varbind_enumerator* enumerator, struct pbuf* p, u16_t offset, u16_t length) +{ + snmp_pbuf_stream_init(&(enumerator->pbuf_stream), p, offset, length); + enumerator->varbind_count = 0; +} + +#define VB_PARSE_EXEC(code) PARSE_EXEC(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) +#define VB_PARSE_ASSERT(code) PARSE_ASSERT(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) + +snmp_vb_enumerator_err_t +snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator* enumerator, struct snmp_varbind* varbind) +{ + struct snmp_asn1_tlv tlv; + u16_t varbind_len; + err_t err; + + if (enumerator->pbuf_stream.length == 0) + { + return SNMP_VB_ENUMERATOR_ERR_EOVB; + } + enumerator->varbind_count++; + + /* decode varbind itself (parent container of a varbind) */ + VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); + VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= enumerator->pbuf_stream.length)); + varbind_len = tlv.value_len; + + /* decode varbind name (object id) */ + VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); + VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_OBJECT_ID) && (SNMP_ASN1_TLV_LENGTH(tlv) < varbind_len) && (tlv.value_len < enumerator->pbuf_stream.length)); + + VB_PARSE_EXEC(snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, varbind->oid.id, &(varbind->oid.len), SNMP_MAX_OBJ_ID_LEN)); + varbind_len -= SNMP_ASN1_TLV_LENGTH(tlv); + + /* decode varbind value (object id) */ + VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); + VB_PARSE_ASSERT((SNMP_ASN1_TLV_LENGTH(tlv) == varbind_len) && (tlv.value_len <= enumerator->pbuf_stream.length)); + varbind->type = tlv.type; + + /* shall the value be decoded ? */ + if (varbind->value != NULL) { + switch (varbind->type) { + case SNMP_ASN1_TYPE_INTEGER: + VB_PARSE_EXEC(snmp_asn1_dec_s32t(&(enumerator->pbuf_stream), tlv.value_len, (s32_t*)varbind->value)); + varbind->value_len = sizeof(s32_t*); + break; + case SNMP_ASN1_TYPE_COUNTER: + case SNMP_ASN1_TYPE_GAUGE: + case SNMP_ASN1_TYPE_TIMETICKS: + VB_PARSE_EXEC(snmp_asn1_dec_u32t(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value)); + varbind->value_len = sizeof(u32_t*); + break; + case SNMP_ASN1_TYPE_OCTET_STRING: + case SNMP_ASN1_TYPE_OPAQUE: + err = snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t*)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE); + if (err == ERR_MEM) { + return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH; + } + VB_PARSE_ASSERT(err == ERR_OK); + break; + case SNMP_ASN1_TYPE_NULL: + varbind->value_len = 0; + break; + case SNMP_ASN1_TYPE_OBJECT_ID: + /* misuse tlv.length_len as OID_length transporter */ + err = snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value, &tlv.length_len, SNMP_MAX_OBJ_ID_LEN); + if (err == ERR_MEM) { + return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH; + } + VB_PARSE_ASSERT(err == ERR_OK); + varbind->value_len = tlv.length_len * sizeof(u32_t); + break; + case SNMP_ASN1_TYPE_IPADDR: + if (tlv.value_len == 4) { + /* must be exactly 4 octets! */ + VB_PARSE_EXEC(snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t*)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE)); + } else { + VB_PARSE_ASSERT(0); + } + break; + case SNMP_ASN1_TYPE_COUNTER64: + VB_PARSE_EXEC(snmp_asn1_dec_u64t(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value)); + varbind->value_len = 2 * sizeof(u32_t*); + break; + default: + VB_PARSE_ASSERT(0); + break; + } + } else { + snmp_pbuf_stream_seek(&(enumerator->pbuf_stream), tlv.value_len); + varbind->value_len = tlv.value_len; + } + + return SNMP_VB_ENUMERATOR_ERR_OK; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.h new file mode 100644 index 0000000..2d01ef3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_msg.h @@ -0,0 +1,194 @@ +/** + * @file + * SNMP Agent message handling structures (internal API, do not use in client code). + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel + * Elias Oenal + */ + +#ifndef LWIP_HDR_APPS_SNMP_MSG_H +#define LWIP_HDR_APPS_SNMP_MSG_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP + +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "snmp_pbuf_stream.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#if LWIP_SNMP_V3 +#include "snmpv3_priv.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +/* version defines used in PDU */ +#define SNMP_VERSION_1 0 +#define SNMP_VERSION_2c 1 +#define SNMP_VERSION_3 3 + +struct snmp_varbind_enumerator +{ + struct snmp_pbuf_stream pbuf_stream; + u16_t varbind_count; +}; + +typedef enum { + SNMP_VB_ENUMERATOR_ERR_OK = 0, + SNMP_VB_ENUMERATOR_ERR_EOVB = 1, + SNMP_VB_ENUMERATOR_ERR_ASN1ERROR = 2, + SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH = 3 +} snmp_vb_enumerator_err_t; + +void snmp_vb_enumerator_init(struct snmp_varbind_enumerator* enumerator, struct pbuf* p, u16_t offset, u16_t length); +snmp_vb_enumerator_err_t snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator* enumerator, struct snmp_varbind* varbind); + +struct snmp_request +{ + /* Communication handle */ + void *handle; + /* source IP address */ + const ip_addr_t *source_ip; + /* source UDP port */ + u16_t source_port; + /* incoming snmp version */ + u8_t version; + /* community name (zero terminated) */ + u8_t community[SNMP_MAX_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u16_t community_strlen; + /* request type */ + u8_t request_type; + /* request ID */ + s32_t request_id; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* non-repeaters (getBulkRequest (SNMPv2c)) */ + s32_t non_repeaters; + /* max-repetitions (getBulkRequest (SNMPv2c)) */ + s32_t max_repetitions; + +#if LWIP_SNMP_V3 + s32_t msg_id; + s32_t msg_max_size; + u8_t msg_flags; + s32_t msg_security_model; + u8_t msg_authoritative_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH]; + u8_t msg_authoritative_engine_id_len; + s32_t msg_authoritative_engine_boots; + s32_t msg_authoritative_engine_time; + u8_t msg_user_name[SNMP_V3_MAX_USER_LENGTH]; + u8_t msg_user_name_len; + u8_t msg_authentication_parameters[SNMP_V3_MAX_AUTH_PARAM_LENGTH]; + u8_t msg_privacy_parameters[SNMP_V3_MAX_PRIV_PARAM_LENGTH]; + u8_t context_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH]; + u8_t context_engine_id_len; + u8_t context_name[SNMP_V3_MAX_ENGINE_ID_LENGTH]; + u8_t context_name_len; +#endif + + struct pbuf *inbound_pbuf; + struct snmp_varbind_enumerator inbound_varbind_enumerator; + u16_t inbound_varbind_offset; + u16_t inbound_varbind_len; + u16_t inbound_padding_len; + + struct pbuf *outbound_pbuf; + struct snmp_pbuf_stream outbound_pbuf_stream; + u16_t outbound_pdu_offset; + u16_t outbound_error_status_offset; + u16_t outbound_error_index_offset; + u16_t outbound_varbind_offset; +#if LWIP_SNMP_V3 + u16_t outbound_msg_global_data_offset; + u16_t outbound_msg_global_data_end; + u16_t outbound_msg_security_parameters_str_offset; + u16_t outbound_msg_security_parameters_seq_offset; + u16_t outbound_msg_security_parameters_end; + u16_t outbound_msg_authentication_parameters_offset; + u16_t outbound_scoped_pdu_seq_offset; + u16_t outbound_scoped_pdu_string_offset; +#endif + + u8_t value_buffer[SNMP_MAX_VALUE_SIZE]; +}; + +/** A helper struct keeping length information about varbinds */ +struct snmp_varbind_len +{ + u8_t vb_len_len; + u16_t vb_value_len; + u8_t oid_len_len; + u16_t oid_value_len; + u8_t value_len_len; + u16_t value_value_len; +}; + +/** Agent community string */ +extern const char *snmp_community; +/** Agent community string for write access */ +extern const char *snmp_community_write; +/** handle for sending traps */ +extern void* snmp_traps_handle; + +void snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port); +err_t snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port); +u8_t snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result); +err_t snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len); +err_t snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind* varbind); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_APPS_SNMP_MSG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_netconn.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_netconn.c new file mode 100644 index 0000000..24c3e26 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_netconn.c @@ -0,0 +1,121 @@ +/** + * @file + * SNMP netconn frontend. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP && SNMP_USE_NETCONN + +#include +#include "lwip/api.h" +#include "lwip/ip.h" +#include "lwip/udp.h" +#include "snmp_msg.h" +#include "lwip/sys.h" + +/** SNMP netconn API worker thread */ +static void +snmp_netconn_thread(void *arg) +{ + struct netconn *conn; + struct netbuf *buf; + err_t err; + LWIP_UNUSED_ARG(arg); + + /* Bind to SNMP port with default IP address */ +#if LWIP_IPV6 + conn = netconn_new(NETCONN_UDP_IPV6); + netconn_bind(conn, IP6_ADDR_ANY, SNMP_IN_PORT); +#else /* LWIP_IPV6 */ + conn = netconn_new(NETCONN_UDP); + netconn_bind(conn, IP4_ADDR_ANY, SNMP_IN_PORT); +#endif /* LWIP_IPV6 */ + LWIP_ERROR("snmp_netconn: invalid conn", (conn != NULL), return;); + + snmp_traps_handle = conn; + + do { + err = netconn_recv(conn, &buf); + + if (err == ERR_OK) { + snmp_receive(conn, buf->p, &buf->addr, buf->port); + } + + if (buf != NULL) { + netbuf_delete(buf); + } + } while(1); +} + +err_t +snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port) +{ + err_t result; + struct netbuf buf; + + memset(&buf, 0, sizeof(buf)); + buf.p = p; + result = netconn_sendto((struct netconn*)handle, &buf, dst, port); + + return result; +} + +u8_t +snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result) +{ + struct netconn* conn = (struct netconn*)handle; + struct netif *dst_if; + const ip_addr_t* dst_ip; + + LWIP_UNUSED_ARG(conn); /* unused in case of IPV4 only configuration */ + + ip_route_get_local_ip(&conn->pcb.udp->local_ip, dst, dst_if, dst_ip); + + if ((dst_if != NULL) && (dst_ip != NULL)) { + ip_addr_copy(*result, *dst_ip); + return 1; + } else { + return 0; + } +} + +/** + * Starts SNMP Agent. + */ +void +snmp_init(void) +{ + sys_thread_new("snmp_netconn", snmp_netconn_thread, NULL, SNMP_STACK_SIZE, SNMP_THREAD_PRIO); +} + +#endif /* LWIP_SNMP && SNMP_USE_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.c new file mode 100644 index 0000000..3c1217d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.c @@ -0,0 +1,156 @@ +/** + * @file + * SNMP pbuf stream wrapper implementation (internal API, do not use in client code). + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "snmp_pbuf_stream.h" +#include "lwip/def.h" +#include + +err_t +snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length) +{ + pbuf_stream->offset = offset; + pbuf_stream->length = length; + pbuf_stream->pbuf = p; + + return ERR_OK; +} + +err_t +snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data) +{ + if (pbuf_stream->length == 0) { + return ERR_BUF; + } + + if (pbuf_copy_partial(pbuf_stream->pbuf, data, 1, pbuf_stream->offset) == 0) { + return ERR_BUF; + } + + pbuf_stream->offset++; + pbuf_stream->length--; + + return ERR_OK; +} + +err_t +snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data) +{ + return snmp_pbuf_stream_writebuf(pbuf_stream, &data, 1); +} + +err_t +snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len) +{ + if (pbuf_stream->length < buf_len) { + return ERR_BUF; + } + + if (pbuf_take_at(pbuf_stream->pbuf, buf, buf_len, pbuf_stream->offset) != ERR_OK) { + return ERR_BUF; + } + + pbuf_stream->offset += buf_len; + pbuf_stream->length -= buf_len; + + return ERR_OK; +} + +err_t +snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len) +{ + + if ((pbuf_stream == NULL) || (target_pbuf_stream == NULL)) { + return ERR_ARG; + } + if ((len > pbuf_stream->length) || (len > target_pbuf_stream->length)) { + return ERR_ARG; + } + + if (len == 0) { + len = LWIP_MIN(pbuf_stream->length, target_pbuf_stream->length); + } + + while (len > 0) { + u16_t chunk_len; + err_t err; + u16_t target_offset; + struct pbuf* pbuf = pbuf_skip(pbuf_stream->pbuf, pbuf_stream->offset, &target_offset); + + if ((pbuf == NULL) || (pbuf->len == 0)) { + return ERR_BUF; + } + + chunk_len = LWIP_MIN(len, pbuf->len); + err = snmp_pbuf_stream_writebuf(target_pbuf_stream, &((u8_t*)pbuf->payload)[target_offset], chunk_len); + if (err != ERR_OK) { + return err; + } + + pbuf_stream->offset += chunk_len; + pbuf_stream->length -= chunk_len; + len -= chunk_len; + } + + return ERR_OK; +} + +err_t +snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset) +{ + if ((offset < 0) || (offset > pbuf_stream->length)) { + /* we cannot seek backwards or forward behind stream end */ + return ERR_ARG; + } + + pbuf_stream->offset += (u16_t)offset; + pbuf_stream->length -= (u16_t)offset; + + return ERR_OK; +} + +err_t +snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset) +{ + s32_t rel_offset = offset - pbuf_stream->offset; + return snmp_pbuf_stream_seek(pbuf_stream, rel_offset); +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.h new file mode 100644 index 0000000..9778de7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_pbuf_stream.h @@ -0,0 +1,73 @@ +/** + * @file + * SNMP pbuf stream wrapper (internal API, do not use in client code). + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#ifndef LWIP_HDR_APPS_SNMP_PBUF_STREAM_H +#define LWIP_HDR_APPS_SNMP_PBUF_STREAM_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP + +#include "lwip/err.h" +#include "lwip/pbuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct snmp_pbuf_stream +{ + struct pbuf* pbuf; + u16_t offset; + u16_t length; +}; + +err_t snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length); +err_t snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data); +err_t snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data); +err_t snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len); +err_t snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len); +err_t snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset); +err_t snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_APPS_SNMP_PBUF_STREAM_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_raw.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_raw.c new file mode 100644 index 0000000..4a40864 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_raw.c @@ -0,0 +1,100 @@ +/** + * @file + * SNMP RAW API frontend. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + */ + +#include "lwip/apps/snmp_opts.h" +#include "lwip/ip_addr.h" + +#if LWIP_SNMP && SNMP_USE_RAW + +#include "lwip/udp.h" +#include "lwip/ip.h" +#include "snmp_msg.h" + +/* lwIP UDP receive callback function */ +static void +snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + LWIP_UNUSED_ARG(arg); + + snmp_receive(pcb, p, addr, port); + + pbuf_free(p); +} + +err_t +snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port) +{ + return udp_sendto((struct udp_pcb*)handle, p, dst, port); +} + +u8_t +snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result) +{ + struct udp_pcb* udp_pcb = (struct udp_pcb*)handle; + struct netif *dst_if; + const ip_addr_t* dst_ip; + + LWIP_UNUSED_ARG(udp_pcb); /* unused in case of IPV4 only configuration */ + + ip_route_get_local_ip(&udp_pcb->local_ip, dst, dst_if, dst_ip); + + if ((dst_if != NULL) && (dst_ip != NULL)) { + ip_addr_copy(*result, *dst_ip); + return 1; + } else { + return 0; + } +} + +/** + * @ingroup snmp_core + * Starts SNMP Agent. + * Allocates UDP pcb and binds it to IP_ANY_TYPE port 161. + */ +void +snmp_init(void) +{ + err_t err; + + struct udp_pcb *snmp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + LWIP_ERROR("snmp_raw: no PCB", (snmp_pcb != NULL), return;); + + snmp_traps_handle = snmp_pcb; + + udp_recv(snmp_pcb, snmp_recv, (void *)SNMP_IN_PORT); + err = udp_bind(snmp_pcb, IP_ANY_TYPE, SNMP_IN_PORT); + LWIP_ERROR("snmp_raw: Unable to bind PCB", (err == ERR_OK), return;); +} + +#endif /* LWIP_SNMP && SNMP_USE_RAW */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_scalar.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_scalar.c new file mode 100644 index 0000000..136c9ec --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_scalar.c @@ -0,0 +1,220 @@ +/** + * @file + * SNMP scalar node support implementation. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp_scalar.h" +#include "lwip/apps/snmp_core.h" + +static s16_t snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value); +static snmp_err_t snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value); +static snmp_err_t snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value); + +snmp_err_t +snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + const struct snmp_scalar_node* scalar_node = (const struct snmp_scalar_node*)(const void*)instance->node; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + /* scalar only has one dedicated instance: .0 */ + if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) { + return SNMP_ERR_NOSUCHINSTANCE; + } + + instance->access = scalar_node->access; + instance->asn1_type = scalar_node->asn1_type; + instance->get_value = scalar_node->get_value; + instance->set_test = scalar_node->set_test; + instance->set_value = scalar_node->set_value; + return SNMP_ERR_NOERROR; +} + +snmp_err_t +snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + /* because our only instance is .0 we can only return a next instance if no instance oid is passed */ + if (instance->instance_oid.len == 0) { + instance->instance_oid.len = 1; + instance->instance_oid.id[0] = 0; + + return snmp_scalar_get_instance(root_oid, root_oid_len, instance); + } + + return SNMP_ERR_NOSUCHINSTANCE; +} + + +snmp_err_t +snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) { + const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; + const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes; + u32_t i = 0; + + while (i < array_node->array_node_count) { + if (array_node_def->oid == instance->instance_oid.id[0]) { + break; + } + + array_node_def++; + i++; + } + + if (i < array_node->array_node_count) { + instance->access = array_node_def->access; + instance->asn1_type = array_node_def->asn1_type; + instance->get_value = snmp_scalar_array_get_value; + instance->set_test = snmp_scalar_array_set_test; + instance->set_value = snmp_scalar_array_set_value; + instance->reference.const_ptr = array_node_def; + + return SNMP_ERR_NOERROR; + } + } + + return SNMP_ERR_NOSUCHINSTANCE; +} + +snmp_err_t +snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; + const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes; + const struct snmp_scalar_array_node_def* result = NULL; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) { + /* return node with lowest OID */ + u16_t i = 0; + + result = array_node_def; + array_node_def++; + + for (i = 1; i < array_node->array_node_count; i++) { + if (array_node_def->oid < result->oid) { + result = array_node_def; + } + array_node_def++; + } + } else if (instance->instance_oid.len >= 1) { + if (instance->instance_oid.len == 1) { + /* if we have the requested OID we return its instance, otherwise we search for the next available */ + u16_t i = 0; + while (i < array_node->array_node_count) { + if (array_node_def->oid == instance->instance_oid.id[0]) { + result = array_node_def; + break; + } + + array_node_def++; + i++; + } + } + if (result == NULL) { + u32_t oid_dist = 0xFFFFFFFFUL; + u16_t i = 0; + array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */ + while (i < array_node->array_node_count) { + if ((array_node_def->oid > instance->instance_oid.id[0]) && + ((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) { + result = array_node_def; + oid_dist = array_node_def->oid - instance->instance_oid.id[0]; + } + + array_node_def++; + i++; + } + } + } + + if (result == NULL) { + /* nothing to return */ + return SNMP_ERR_NOSUCHINSTANCE; + } + + instance->instance_oid.len = 2; + instance->instance_oid.id[0] = result->oid; + instance->instance_oid.id[1] = 0; + + instance->access = result->access; + instance->asn1_type = result->asn1_type; + instance->get_value = snmp_scalar_array_get_value; + instance->set_test = snmp_scalar_array_set_test; + instance->set_value = snmp_scalar_array_set_value; + instance->reference.const_ptr = result; + + return SNMP_ERR_NOERROR; +} + +static s16_t +snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value) +{ + const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; + const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; + + return array_node->get_value(array_node_def, value); +} + +static snmp_err_t +snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value) +{ + const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; + const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; + + return array_node->set_test(array_node_def, value_len, value); +} + +static snmp_err_t +snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value) +{ + const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; + const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; + + return array_node->set_value(array_node_def, value_len, value); +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_table.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_table.c new file mode 100644 index 0000000..63ca595 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_table.c @@ -0,0 +1,343 @@ +/** + * @file + * SNMP table support implementation. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_table.h" +#include + +snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE; + const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */ + /* fixed row entry always has oid 1 */ + if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) { + /* search column */ + const struct snmp_table_col_def* col_def = table_node->columns; + u16_t i = table_node->column_count; + while (i > 0) { + if (col_def->index == instance->instance_oid.id[1]) { + break; + } + + col_def++; + i--; + } + + if (i > 0) { + /* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */ + instance->asn1_type = col_def->asn1_type; + instance->access = col_def->access; + instance->get_value = table_node->get_value; + instance->set_test = table_node->set_test; + instance->set_value = table_node->set_value; + + ret = table_node->get_cell_instance( + &(instance->instance_oid.id[1]), + &(instance->instance_oid.id[2]), + instance->instance_oid.len-2, + instance); + } + } + + return ret; +} + +snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node; + const struct snmp_table_col_def* col_def; + struct snmp_obj_id row_oid; + u32_t column = 0; + snmp_err_t result; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + /* check that first part of id is 0 or 1, referencing fixed row entry */ + if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) { + return SNMP_ERR_NOSUCHINSTANCE; + } + if (instance->instance_oid.len > 1) { + column = instance->instance_oid.id[1]; + } + if (instance->instance_oid.len > 2) { + snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2); + } else { + row_oid.len = 0; + } + + instance->get_value = table_node->get_value; + instance->set_test = table_node->set_test; + instance->set_value = table_node->set_value; + + /* resolve column and value */ + do { + u16_t i; + const struct snmp_table_col_def* next_col_def = NULL; + col_def = table_node->columns; + + for (i = 0; i < table_node->column_count; i++) { + if (col_def->index == column) { + next_col_def = col_def; + break; + } else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) { + next_col_def = col_def; + } + col_def++; + } + + if (next_col_def == NULL) { + /* no further column found */ + return SNMP_ERR_NOSUCHINSTANCE; + } + + instance->asn1_type = next_col_def->asn1_type; + instance->access = next_col_def->access; + + result = table_node->get_next_cell_instance( + &next_col_def->index, + &row_oid, + instance); + + if (result == SNMP_ERR_NOERROR) { + col_def = next_col_def; + break; + } + + row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */ + column = next_col_def->index + 1; + } while (1); + + /* build resulting oid */ + instance->instance_oid.len = 2; + instance->instance_oid.id[0] = 1; + instance->instance_oid.id[1] = col_def->index; + snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len); + + return SNMP_ERR_NOERROR; +} + + +snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE; + const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */ + /* fixed row entry always has oid 1 */ + if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) { + ret = table_node->get_cell_value( + &(instance->instance_oid.id[1]), + &(instance->instance_oid.id[2]), + instance->instance_oid.len-2, + &instance->reference, + &instance->reference_len); + + if (ret == SNMP_ERR_NOERROR) { + /* search column */ + const struct snmp_table_simple_col_def* col_def = table_node->columns; + u32_t i = table_node->column_count; + while (i > 0) { + if (col_def->index == instance->instance_oid.id[1]) { + break; + } + + col_def++; + i--; + } + + if (i > 0) { + instance->asn1_type = col_def->asn1_type; + instance->access = SNMP_NODE_INSTANCE_READ_ONLY; + instance->set_test = NULL; + instance->set_value = NULL; + + switch (col_def->data_type) { + case SNMP_VARIANT_VALUE_TYPE_U32: + instance->get_value = snmp_table_extract_value_from_u32ref; + break; + case SNMP_VARIANT_VALUE_TYPE_S32: + instance->get_value = snmp_table_extract_value_from_s32ref; + break; + case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */ + case SNMP_VARIANT_VALUE_TYPE_CONST_PTR: + instance->get_value = snmp_table_extract_value_from_refconstptr; + break; + default: + LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type)); + return SNMP_ERR_GENERROR; + } + + ret = SNMP_ERR_NOERROR; + } else { + ret = SNMP_ERR_NOSUCHINSTANCE; + } + } + } + + return ret; +} + +snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node; + const struct snmp_table_simple_col_def* col_def; + struct snmp_obj_id row_oid; + u32_t column = 0; + snmp_err_t result; + + LWIP_UNUSED_ARG(root_oid); + LWIP_UNUSED_ARG(root_oid_len); + + /* check that first part of id is 0 or 1, referencing fixed row entry */ + if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) { + return SNMP_ERR_NOSUCHINSTANCE; + } + if (instance->instance_oid.len > 1) { + column = instance->instance_oid.id[1]; + } + if (instance->instance_oid.len > 2) { + snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2); + } else { + row_oid.len = 0; + } + + /* resolve column and value */ + do { + u32_t i; + const struct snmp_table_simple_col_def* next_col_def = NULL; + col_def = table_node->columns; + + for (i = 0; i < table_node->column_count; i++) { + if (col_def->index == column) { + next_col_def = col_def; + break; + } else if ((col_def->index > column) && ((next_col_def == NULL) || + (col_def->index < next_col_def->index))) { + next_col_def = col_def; + } + col_def++; + } + + if (next_col_def == NULL) { + /* no further column found */ + return SNMP_ERR_NOSUCHINSTANCE; + } + + result = table_node->get_next_cell_instance_and_value( + &next_col_def->index, + &row_oid, + &instance->reference, + &instance->reference_len); + + if (result == SNMP_ERR_NOERROR) { + col_def = next_col_def; + break; + } + + row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */ + column = next_col_def->index + 1; + } + while (1); + + instance->asn1_type = col_def->asn1_type; + instance->access = SNMP_NODE_INSTANCE_READ_ONLY; + instance->set_test = NULL; + instance->set_value = NULL; + + switch (col_def->data_type) { + case SNMP_VARIANT_VALUE_TYPE_U32: + instance->get_value = snmp_table_extract_value_from_u32ref; + break; + case SNMP_VARIANT_VALUE_TYPE_S32: + instance->get_value = snmp_table_extract_value_from_s32ref; + break; + case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */ + case SNMP_VARIANT_VALUE_TYPE_CONST_PTR: + instance->get_value = snmp_table_extract_value_from_refconstptr; + break; + default: + LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type)); + return SNMP_ERR_GENERROR; + } + + /* build resulting oid */ + instance->instance_oid.len = 2; + instance->instance_oid.id[0] = 1; + instance->instance_oid.id[1] = col_def->index; + snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len); + + return SNMP_ERR_NOERROR; +} + + +s16_t +snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value) +{ + s32_t *dst = (s32_t*)value; + *dst = instance->reference.s32; + return sizeof(*dst); +} + +s16_t +snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value) +{ + u32_t *dst = (u32_t*)value; + *dst = instance->reference.u32; + return sizeof(*dst); +} + +s16_t +snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value) +{ + MEMCPY(value, instance->reference.const_ptr, instance->reference_len); + return (u16_t)instance->reference_len; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_threadsync.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_threadsync.c new file mode 100644 index 0000000..204f265 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_threadsync.c @@ -0,0 +1,219 @@ +/** + * @file + * SNMP thread synchronization implementation. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp_threadsync.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/sys.h" +#include + +static void +call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn) +{ + sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex); + call_data->threadsync_node->instance->sync_fn(fn, call_data); + sys_sem_wait(&call_data->threadsync_node->instance->sem); + sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex); +} + +static void +threadsync_get_value_synced(void *ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + + call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static s16_t +threadsync_get_value(struct snmp_node_instance* instance, void* value) +{ + struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; + + call_data->arg1.value = value; + call_synced_function(call_data, threadsync_get_value_synced); + + return call_data->retval.s16; +} + +static void +threadsync_set_test_synced(void *ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + + call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static snmp_err_t +threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value) +{ + struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; + + call_data->arg1.value = value; + call_data->arg2.len = len; + call_synced_function(call_data, threadsync_set_test_synced); + + return call_data->retval.err; +} + +static void +threadsync_set_value_synced(void *ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + + call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static snmp_err_t +threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value) +{ + struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; + + call_data->arg1.value = value; + call_data->arg2.len = len; + call_synced_function(call_data, threadsync_set_value_synced); + + return call_data->retval.err; +} + +static void +threadsync_release_instance_synced(void* ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + + call_data->proxy_instance.release_instance(&call_data->proxy_instance); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static void +threadsync_release_instance(struct snmp_node_instance *instance) +{ + struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; + + if (call_data->proxy_instance.release_instance != NULL) { + call_synced_function(call_data, threadsync_release_instance_synced); + } +} + +static void +get_instance_synced(void* ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; + + call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static void +get_next_instance_synced(void* ctx) +{ + struct threadsync_data *call_data = (struct threadsync_data*)ctx; + const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; + + call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); + + sys_sem_signal(&call_data->threadsync_node->instance->sem); +} + +static snmp_err_t +do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn) +{ + const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)(const void*)instance->node; + struct threadsync_data *call_data = &threadsync_node->instance->data; + + if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) { + LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID")); + return SNMP_ERR_NOSUCHINSTANCE; + } + + memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance)); + + instance->reference.ptr = call_data; + snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len); + + call_data->proxy_instance.node = &threadsync_node->target->node; + call_data->threadsync_node = threadsync_node; + + call_data->arg1.root_oid = root_oid; + call_data->arg2.root_oid_len = root_oid_len; + call_synced_function(call_data, fn); + + if (call_data->retval.err == SNMP_ERR_NOERROR) { + instance->access = call_data->proxy_instance.access; + instance->asn1_type = call_data->proxy_instance.asn1_type; + instance->release_instance = threadsync_release_instance; + instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL; + instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL; + instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL; + snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len); + } + + return call_data->retval.err; +} + +snmp_err_t +snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + return do_sync(root_oid, root_oid_len, instance, get_instance_synced); +} + +snmp_err_t +snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) +{ + return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced); +} + +/** Initializes thread synchronization instance */ +void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn) +{ + err_t err = sys_mutex_new(&instance->sem_usage_mutex); + LWIP_ASSERT("Failed to set up mutex", err == ERR_OK); + err = sys_sem_new(&instance->sem, 0); + LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ + LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK); + instance->sync_fn = sync_fn; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_traps.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_traps.c new file mode 100644 index 0000000..0d2df64 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmp_traps.c @@ -0,0 +1,445 @@ +/** + * @file + * SNMPv1 traps implementation. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * Christiaan Simons + * + */ + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include + +#include "lwip/snmp.h" +#include "lwip/sys.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "snmp_msg.h" +#include "snmp_asn1.h" +#include "snmp_core_priv.h" + +struct snmp_msg_trap +{ + /* source enterprise ID (sysObjectID) */ + const struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + ip_addr_t sip; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* snmp_version */ + u32_t snmp_version; + + /* output trap lengths used in ASN encoding */ + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding sequence length */ + u16_t seqlen; + /* encoding varbinds sequence length */ + u16_t vbseqlen; +}; + +static u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds); +static u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len); +static void snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream); +static void snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds); + +/** Agent community string for sending traps */ +extern const char *snmp_community_trap; + +void* snmp_traps_handle; + +struct snmp_trap_dst +{ + /* destination IP address in network order */ + ip_addr_t dip; + /* set to 0 when disabled, >0 when enabled */ + u8_t enable; +}; +static struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; + +static u8_t snmp_auth_traps_enabled = 0; + +/** + * @ingroup snmp_traps + * Sets enable switch for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param enable switch if 0 destination is disabled >0 enabled. + */ +void +snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) { + trap_dst[dst_idx].enable = enable; + } +} + +/** + * @ingroup snmp_traps + * Sets IPv4 address for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param dst IPv4 address in host order. + */ +void +snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) { + ip_addr_set(&trap_dst[dst_idx].dip, dst); + } +} + +/** + * @ingroup snmp_traps + * Enable/disable authentication traps + */ +void +snmp_set_auth_traps_enabled(u8_t enable) +{ + snmp_auth_traps_enabled = enable; +} + +/** + * @ingroup snmp_traps + * Get authentication traps enabled state + */ +u8_t +snmp_get_auth_traps_enabled(void) +{ + return snmp_auth_traps_enabled; +} + + +/** + * @ingroup snmp_traps + * Sends a generic or enterprise specific trap message. + * + * @param eoid points to enterprise object identifier + * @param generic_trap is the trap code + * @param specific_trap used for enterprise traps when generic_trap == 6 + * @param varbinds linked list of varbinds to be sent + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the use of the enterprise identifier field + * is per RFC1215. + * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps + * and .iso.org.dod.internet.private.enterprises.yourenterprise + * (sysObjectID) for specific traps. + */ +err_t +snmp_send_trap(const struct snmp_obj_id* eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds) +{ + struct snmp_msg_trap trap_msg; + struct snmp_trap_dst *td; + struct pbuf *p; + u16_t i, tot_len; + err_t err = ERR_OK; + + trap_msg.snmp_version = 0; + + for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) { + if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { + /* lookup current source address for this dst */ + if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg.sip)) { + if (eoid == NULL) { + trap_msg.enterprise = snmp_get_device_enterprise_oid(); + } else { + trap_msg.enterprise = eoid; + } + + trap_msg.gen_trap = generic_trap; + if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) { + trap_msg.spc_trap = specific_trap; + } else { + trap_msg.spc_trap = 0; + } + + MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts); + + /* pass 0, calculate length fields */ + tot_len = snmp_trap_varbind_sum(&trap_msg, varbinds); + tot_len = snmp_trap_header_sum(&trap_msg, tot_len); + + /* allocate pbuf(s) */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM); + if (p != NULL) { + struct snmp_pbuf_stream pbuf_stream; + snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len); + + /* pass 1, encode packet ino the pbuf(s) */ + snmp_trap_header_enc(&trap_msg, &pbuf_stream); + snmp_trap_varbind_enc(&trap_msg, &pbuf_stream, varbinds); + + snmp_stats.outtraps++; + snmp_stats.outpkts++; + + /** send to the TRAP destination */ + snmp_sendto(snmp_traps_handle, p, &td->dip, SNMP_TRAP_PORT); + pbuf_free(p); + } else { + err = ERR_MEM; + } + } else { + /* routing error */ + err = ERR_RTE; + } + } + } + return err; +} + +/** + * @ingroup snmp_traps + * Send generic SNMP trap + */ +err_t +snmp_send_trap_generic(s32_t generic_trap) +{ + static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } }; + return snmp_send_trap(&oid, generic_trap, 0, NULL); +} + +/** + * @ingroup snmp_traps + * Send specific SNMP trap with variable bindings + */ +err_t +snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds) +{ + return snmp_send_trap(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds); +} + +/** + * @ingroup snmp_traps + * Send coldstart trap + */ +void +snmp_coldstart_trap(void) +{ + snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART); +} + +/** + * @ingroup snmp_traps + * Send authentication failure trap (used internally by agent) + */ +void +snmp_authfail_trap(void) +{ + if (snmp_auth_traps_enabled != 0) { + snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE); + } +} + +static u16_t +snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds) +{ + struct snmp_varbind *varbind; + u16_t tot_len; + u8_t tot_len_len; + + tot_len = 0; + varbind = varbinds; + while (varbind != NULL) { + struct snmp_varbind_len len; + + if (snmp_varbind_length(varbind, &len) == ERR_OK) { + tot_len += 1 + len.vb_len_len + len.vb_value_len; + } + + varbind = varbind->next; + } + + trap->vbseqlen = tot_len; + snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len); + tot_len += 1 + tot_len_len; + + return tot_len; +} + +/** + * Sums trap header field lengths from tail to head and + * returns trap_header_lengths for second encoding pass. + * + * @param trap Trap message + * @param vb_len varbind-list length + * @return the required length for encoding the trap header + */ +static u16_t +snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len) +{ + u16_t tot_len; + u16_t len; + u8_t lenlen; + + tot_len = vb_len; + + snmp_asn1_enc_u32t_cnt(trap->ts, &len); + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len); + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len); + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + if (IP_IS_V6_VAL(trap->sip)) { +#if LWIP_IPV6 + len = sizeof(ip_2_ip6(&trap->sip)->addr); +#endif + } else { +#if LWIP_IPV4 + len = sizeof(ip_2_ip4(&trap->sip)->addr); +#endif + } + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len); + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + trap->pdulen = tot_len; + snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen); + tot_len += 1 + lenlen; + + trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF); + snmp_asn1_enc_length_cnt(trap->comlen, &lenlen); + tot_len += 1 + lenlen + trap->comlen; + + snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len); + snmp_asn1_enc_length_cnt(len, &lenlen); + tot_len += 1 + len + lenlen; + + trap->seqlen = tot_len; + snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen); + tot_len += 1 + lenlen; + + return tot_len; +} + +static void +snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds) +{ + struct snmp_asn1_tlv tlv; + struct snmp_varbind *varbind; + + varbind = varbinds; + + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + + while (varbind != NULL) { + snmp_append_outbound_varbind(pbuf_stream, varbind); + + varbind = varbind->next; + } +} + +/** + * Encodes trap header from head to tail. + */ +static void +snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream) +{ + struct snmp_asn1_tlv tlv; + + /* 'Message' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + + /* version */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version); + + /* community */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)snmp_community_trap, trap->comlen); + + /* 'PDU' sequence */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + + /* object ID */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0); + snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len); + + /* IP addr */ + if (IP_IS_V6_VAL(trap->sip)) { +#if LWIP_IPV6 + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr)); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr)); +#endif + } else { +#if LWIP_IPV4 + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr)); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr)); +#endif + } + + /* trap length */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap); + + /* specific trap */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); + snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap); + + /* timestamp */ + SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0); + snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len); + snmp_ans1_enc_tlv(pbuf_stream, &tlv); + snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts); +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3.c new file mode 100644 index 0000000..69fb3a0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3.c @@ -0,0 +1,136 @@ +/** + * @file + * Additional SNMPv3 functionality RFC3414 and RFC3826. + */ + +/* + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Elias Oenal + */ + +#include "snmpv3_priv.h" +#include "lwip/apps/snmpv3.h" +#include "lwip/sys.h" +#include + +#if LWIP_SNMP && LWIP_SNMP_V3 + +#ifdef LWIP_SNMPV3_INCLUDE_ENGINE +#include LWIP_SNMPV3_INCLUDE_ENGINE +#endif + +#define SNMP_MAX_TIME_BOOT 2147483647UL + +/** Call this if engine has been changed. Has to reset boots, see below */ +void +snmpv3_engine_id_changed(void) +{ + snmpv3_set_engine_boots(0); +} + +/** According to RFC3414 2.2.2. + * + * The number of times that the SNMP engine has + * (re-)initialized itself since snmpEngineID + * was last configured. + */ +u32_t +snmpv3_get_engine_boots_internal(void) +{ + if (snmpv3_get_engine_boots() == 0 || + snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT) { + return snmpv3_get_engine_boots(); + } + + snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT); + return snmpv3_get_engine_boots(); +} + +/** RFC3414 2.2.2. + * + * Once the timer reaches 2147483647 it gets reset to zero and the + * engine boot ups get incremented. + */ +u32_t +snmpv3_get_engine_time_internal(void) +{ + if (snmpv3_get_engine_time() >= SNMP_MAX_TIME_BOOT) { + snmpv3_reset_engine_time(); + + if (snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT - 1) { + snmpv3_set_engine_boots(snmpv3_get_engine_boots() + 1); + } else { + snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT); + } + } + + return snmpv3_get_engine_time(); +} + +#if LWIP_SNMP_V3_CRYPTO + +/* This function ignores the byte order suggestion in RFC3414 + * since it simply doesn't influence the effectiveness of an IV. + * + * Implementing RFC3826 priv param algorithm if LWIP_RAND is available. + * + * @todo: This is a potential thread safety issue. + */ +err_t +snmpv3_build_priv_param(u8_t* priv_param) +{ +#ifdef LWIP_RAND /* Based on RFC3826 */ + static u8_t init; + static u32_t priv1, priv2; + + /* Lazy initialisation */ + if (init == 0) { + init = 1; + priv1 = LWIP_RAND(); + priv2 = LWIP_RAND(); + } + + SMEMCPY(&priv_param[0], &priv1, sizeof(priv1)); + SMEMCPY(&priv_param[4], &priv2, sizeof(priv2)); + + /* Emulate 64bit increment */ + priv1++; + if (!priv1) { /* Overflow */ + priv2++; + } +#else /* Based on RFC3414 */ + static u32_t ctr; + u32_t boots = LWIP_SNMPV3_GET_ENGINE_BOOTS(); + SMEMCPY(&priv_param[0], &boots, 4); + SMEMCPY(&priv_param[4], &ctr, 4); + ctr++; +#endif + return ERR_OK; +} +#endif /* LWIP_SNMP_V3_CRYPTO */ + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_dummy.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_dummy.c new file mode 100644 index 0000000..bdfe844 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_dummy.c @@ -0,0 +1,145 @@ +/** + * @file + * Dummy SNMPv3 functions. + */ + +/* + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Elias Oenal + * Dirk Ziegelmeier + */ + +#include "lwip/apps/snmpv3.h" +#include "snmpv3_priv.h" +#include +#include "lwip/err.h" + +#if LWIP_SNMP && LWIP_SNMP_V3 + +/** + * @param username is a pointer to a string. + * @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found. + * @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found. + * @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found. + * @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found. + */ +err_t +snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key) +{ + const char* engine_id; + u8_t engine_id_len; + + if(strlen(username) == 0) { + return ERR_OK; + } + + if(memcmp(username, "lwip", 4) != 0) { + return ERR_VAL; + } + + snmpv3_get_engine_id(&engine_id, &engine_id_len); + + if(auth_key != NULL) { + snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10, + (const u8_t*)engine_id, engine_id_len, + auth_key); + *auth_algo = SNMP_V3_AUTH_ALGO_SHA; + } + if(priv_key != NULL) { + snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10, + (const u8_t*)engine_id, engine_id_len, + priv_key); + *priv_algo = SNMP_V3_PRIV_ALGO_DES; + } + return ERR_OK; +} + +/** + * Get engine ID from persistence + * @param id + * @param len + */ +void +snmpv3_get_engine_id(const char **id, u8_t *len) +{ + *id = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"; + *len = 12; +} + +/** + * Store engine ID in persistence + * @param id + * @param len + */ +err_t +snmpv3_set_engine_id(const char *id, u8_t len) +{ + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(len); + return ERR_OK; +} + +/** + * Get engine boots from persistence. Must be increased on each boot. + * @return + */ +u32_t +snmpv3_get_engine_boots(void) +{ + return 0; +} + +/** + * Store engine boots in persistence + * @param boots + */ +void +snmpv3_set_engine_boots(u32_t boots) +{ + LWIP_UNUSED_ARG(boots); +} + +/** + * RFC3414 2.2.2. + * Once the timer reaches 2147483647 it gets reset to zero and the + * engine boot ups get incremented. + */ +u32_t +snmpv3_get_engine_time(void) +{ + return 0; +} + +/** + * Reset current engine time to 0 + */ +void +snmpv3_reset_engine_time(void) +{ +} + +#endif /* LWIP_SNMP && LWIP_SNMP_V3 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_mbedtls.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_mbedtls.c new file mode 100644 index 0000000..0b1eefb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_mbedtls.c @@ -0,0 +1,331 @@ +/** + * @file + * SNMPv3 crypto/auth functions implemented for ARM mbedtls. + */ + +/* + * Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Elias Oenal + * Dirk Ziegelmeier + */ + +#include "lwip/apps/snmpv3.h" +#include "snmpv3_priv.h" +#include "lwip/arch.h" +#include "snmp_msg.h" +#include "lwip/sys.h" +#include + +#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS + +#include "mbedtls/md.h" +#include "mbedtls/cipher.h" + +#include "mbedtls/md5.h" +#include "mbedtls/sha1.h" + +err_t +snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length, + const u8_t* key, u8_t algo, u8_t* hmac_out) +{ + u32_t i; + u8_t key_len; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t ctx; + struct snmp_pbuf_stream read_stream; + snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); + + if (algo == SNMP_V3_AUTH_ALGO_MD5) { + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); + key_len = SNMP_V3_MD5_LEN; + } else if (algo == SNMP_V3_AUTH_ALGO_SHA) { + md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); + key_len = SNMP_V3_SHA_LEN; + } else { + return ERR_ARG; + } + + mbedtls_md_init(&ctx); + if(mbedtls_md_setup(&ctx, md_info, 1) != 0) { + return ERR_ARG; + } + + if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) { + goto free_md; + } + + for (i = 0; i < length; i++) { + u8_t byte; + + if (snmp_pbuf_stream_read(&read_stream, &byte)) { + goto free_md; + } + + if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) { + goto free_md; + } + } + + if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) { + goto free_md; + } + + mbedtls_md_free(&ctx); + return ERR_OK; + +free_md: + mbedtls_md_free(&ctx); + return ERR_ARG; +} + +#if LWIP_SNMP_V3_CRYPTO + +err_t +snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length, + const u8_t* key, const u8_t* priv_param, const u32_t engine_boots, + const u32_t engine_time, u8_t algo, u8_t mode) +{ + size_t i; + mbedtls_cipher_context_t ctx; + const mbedtls_cipher_info_t *cipher_info; + + struct snmp_pbuf_stream read_stream; + struct snmp_pbuf_stream write_stream; + snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); + snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length); + mbedtls_cipher_init(&ctx); + + if (algo == SNMP_V3_PRIV_ALGO_DES) { + u8_t iv_local[8]; + u8_t out_bytes[8]; + size_t out_len; + + /* RFC 3414 mandates padding for DES */ + if ((length & 0x07) != 0) { + return ERR_ARG; + } + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC); + if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) { + return ERR_ARG; + } + if(mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) { + return ERR_ARG; + } + if(mbedtls_cipher_setkey(&ctx, key, 8*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { + goto error; + } + + /* Prepare IV */ + for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) { + iv_local[i] = priv_param[i] ^ key[i + 8]; + } + if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { + goto error; + } + + for (i = 0; i < length; i += 8) { + size_t j; + u8_t in_bytes[8]; + out_len = LWIP_ARRAYSIZE(out_bytes) ; + + for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) { + snmp_pbuf_stream_read(&read_stream, &in_bytes[j]); + } + + if(mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) { + goto error; + } + + snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len); + } + + out_len = LWIP_ARRAYSIZE(out_bytes); + if(mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) { + goto error; + } + snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len); + } else if (algo == SNMP_V3_PRIV_ALGO_AES) { + u8_t iv_local[16]; + + cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128); + if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) { + return ERR_ARG; + } + if(mbedtls_cipher_setkey(&ctx, key, 16*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { + goto error; + } + + /* + * IV is the big endian concatenation of boots, + * uptime and priv param - see RFC3826. + */ + iv_local[0 + 0] = (engine_boots >> 24) & 0xFF; + iv_local[0 + 1] = (engine_boots >> 16) & 0xFF; + iv_local[0 + 2] = (engine_boots >> 8) & 0xFF; + iv_local[0 + 3] = (engine_boots >> 0) & 0xFF; + iv_local[4 + 0] = (engine_time >> 24) & 0xFF; + iv_local[4 + 1] = (engine_time >> 16) & 0xFF; + iv_local[4 + 2] = (engine_time >> 8) & 0xFF; + iv_local[4 + 3] = (engine_time >> 0) & 0xFF; + SMEMCPY(iv_local + 8, priv_param, 8); + if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { + goto error; + } + + for (i = 0; i < length; i++) { + u8_t in_byte; + u8_t out_byte; + size_t out_len = sizeof(out_byte); + + snmp_pbuf_stream_read(&read_stream, &in_byte); + if(mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) { + goto error; + } + snmp_pbuf_stream_write(&write_stream, out_byte); + } + } else { + return ERR_ARG; + } + + mbedtls_cipher_free(&ctx); + return ERR_OK; + +error: + mbedtls_cipher_free(&ctx); + return ERR_OK; +} + +#endif /* LWIP_SNMP_V3_CRYPTO */ + +/* A.2.1. Password to Key Sample Code for MD5 */ +void +snmpv3_password_to_key_md5( + const u8_t *password, /* IN */ + u8_t passwordlen, /* IN */ + const u8_t *engineID, /* IN - pointer to snmpEngineID */ + u8_t engineLength,/* IN - length of snmpEngineID */ + u8_t *key) /* OUT - pointer to caller 16-octet buffer */ +{ + mbedtls_md5_context MD; + u8_t *cp, password_buf[64]; + u32_t password_index = 0; + u8_t i; + u32_t count = 0; + + mbedtls_md5_init(&MD); /* initialize MD5 */ + mbedtls_md5_starts(&MD); + + /**********************************************/ + /* Use while loop until we've done 1 Megabyte */ + /**********************************************/ + while (count < 1048576) { + cp = password_buf; + for (i = 0; i < 64; i++) { + /*************************************************/ + /* Take the next octet of the password, wrapping */ + /* to the beginning of the password as necessary.*/ + /*************************************************/ + *cp++ = password[password_index++ % passwordlen]; + } + mbedtls_md5_update(&MD, password_buf, 64); + count += 64; + } + mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */ + + /*****************************************************/ + /* Now localize the key with the engineID and pass */ + /* through MD5 to produce final key */ + /* May want to ensure that engineLength <= 32, */ + /* otherwise need to use a buffer larger than 64 */ + /*****************************************************/ + SMEMCPY(password_buf, key, 16); + MEMCPY(password_buf + 16, engineID, engineLength); + SMEMCPY(password_buf + 16 + engineLength, key, 16); + + mbedtls_md5_starts(&MD); + mbedtls_md5_update(&MD, password_buf, 32 + engineLength); + mbedtls_md5_finish(&MD, key); + + mbedtls_md5_free(&MD); + return; +} + +/* A.2.2. Password to Key Sample Code for SHA */ +void +snmpv3_password_to_key_sha( + const u8_t *password, /* IN */ + u8_t passwordlen, /* IN */ + const u8_t *engineID, /* IN - pointer to snmpEngineID */ + u8_t engineLength,/* IN - length of snmpEngineID */ + u8_t *key) /* OUT - pointer to caller 20-octet buffer */ +{ + mbedtls_sha1_context SH; + u8_t *cp, password_buf[72]; + u32_t password_index = 0; + u8_t i; + u32_t count = 0; + + mbedtls_sha1_init(&SH); /* initialize SHA */ + mbedtls_sha1_starts(&SH); + + /**********************************************/ + /* Use while loop until we've done 1 Megabyte */ + /**********************************************/ + while (count < 1048576) { + cp = password_buf; + for (i = 0; i < 64; i++) { + /*************************************************/ + /* Take the next octet of the password, wrapping */ + /* to the beginning of the password as necessary.*/ + /*************************************************/ + *cp++ = password[password_index++ % passwordlen]; + } + mbedtls_sha1_update(&SH, password_buf, 64); + count += 64; + } + mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */ + + /*****************************************************/ + /* Now localize the key with the engineID and pass */ + /* through SHA to produce final key */ + /* May want to ensure that engineLength <= 32, */ + /* otherwise need to use a buffer larger than 72 */ + /*****************************************************/ + SMEMCPY(password_buf, key, 20); + MEMCPY(password_buf + 20, engineID, engineLength); + SMEMCPY(password_buf + 20 + engineLength, key, 20); + + mbedtls_sha1_starts(&SH); + mbedtls_sha1_update(&SH, password_buf, 40 + engineLength); + mbedtls_sha1_finish(&SH, key); + + mbedtls_sha1_free(&SH); + return; +} + +#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_priv.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_priv.h new file mode 100644 index 0000000..b87666d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/snmp/snmpv3_priv.h @@ -0,0 +1,66 @@ +/** + * @file + * Additional SNMPv3 functionality RFC3414 and RFC3826 (internal API, do not use in client code). + */ + +/* + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Elias Oenal + */ + +#ifndef LWIP_HDR_APPS_SNMP_V3_PRIV_H +#define LWIP_HDR_APPS_SNMP_V3_PRIV_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP && LWIP_SNMP_V3 + +#include "snmp_pbuf_stream.h" + +/* According to RFC 3411 */ +#define SNMP_V3_MAX_ENGINE_ID_LENGTH 32 +#define SNMP_V3_MAX_USER_LENGTH 32 + +#define SNMP_V3_MAX_AUTH_PARAM_LENGTH 12 +#define SNMP_V3_MAX_PRIV_PARAM_LENGTH 8 + +#define SNMP_V3_AUTH_FLAG 0x01 +#define SNMP_V3_PRIV_FLAG 0x02 + +#define SNMP_V3_MD5_LEN 16 +#define SNMP_V3_SHA_LEN 20 + +u32_t snmpv3_get_engine_boots_internal(void); +u32_t snmpv3_get_engine_time_internal(void); +err_t snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key, u8_t algo, u8_t* hmac_out); +err_t snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key, + const u8_t* priv_param, const u32_t engine_boots, const u32_t engine_time, u8_t algo, u8_t mode); +err_t snmpv3_build_priv_param(u8_t* priv_param); + +#endif + +#endif /* LWIP_HDR_APPS_SNMP_V3_PRIV_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/tftp/tftp_server.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/tftp/tftp_server.c new file mode 100644 index 0000000..243b092 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/apps/tftp/tftp_server.c @@ -0,0 +1,417 @@ +/****************************************************************//** + * + * @file tftp_server.c + * + * @author Logan Gunthorpe + * Dirk Ziegelmeier + * + * @brief Trivial File Transfer Protocol (RFC 1350) + * + * Copyright (c) Deltatee Enterprises Ltd. 2013 + * All rights reserved. + * + ********************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification,are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Logan Gunthorpe + * Dirk Ziegelmeier + * + */ + +/** + * @defgroup tftp TFTP server + * @ingroup apps + * + * This is simple TFTP server for the lwIP raw API. + */ + +#include "lwip/apps/tftp_server.h" + +#if LWIP_UDP + +#include "lwip/udp.h" +#include "lwip/timeouts.h" +#include "lwip/debug.h" + +#define TFTP_MAX_PAYLOAD_SIZE 512 +#define TFTP_HEADER_LENGTH 4 + +#define TFTP_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 + +enum tftp_error { + TFTP_ERROR_FILE_NOT_FOUND = 1, + TFTP_ERROR_ACCESS_VIOLATION = 2, + TFTP_ERROR_DISK_FULL = 3, + TFTP_ERROR_ILLEGAL_OPERATION = 4, + TFTP_ERROR_UNKNOWN_TRFR_ID = 5, + TFTP_ERROR_FILE_EXISTS = 6, + TFTP_ERROR_NO_SUCH_USER = 7 +}; + +#include + +struct tftp_state { + const struct tftp_context *ctx; + void *handle; + struct pbuf *last_data; + struct udp_pcb *upcb; + ip_addr_t addr; + u16_t port; + int timer; + int last_pkt; + u16_t blknum; + u8_t retries; + u8_t mode_write; +}; + +static struct tftp_state tftp_state; + +static void tftp_tmr(void* arg); + +static void +close_handle(void) +{ + tftp_state.port = 0; + ip_addr_set_any(0, &tftp_state.addr); + + if(tftp_state.last_data != NULL) { + pbuf_free(tftp_state.last_data); + tftp_state.last_data = NULL; + } + + sys_untimeout(tftp_tmr, NULL); + + if (tftp_state.handle) { + tftp_state.ctx->close(tftp_state.handle); + tftp_state.handle = NULL; + LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n")); + } +} + +static void +send_error(const ip_addr_t *addr, u16_t port, enum tftp_error code, const char *str) +{ + int str_length = strlen(str); + struct pbuf* p; + u16_t* payload; + + p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(TFTP_HEADER_LENGTH + str_length + 1), PBUF_RAM); + if(p == NULL) { + return; + } + + payload = (u16_t*) p->payload; + payload[0] = PP_HTONS(TFTP_ERROR); + payload[1] = lwip_htons(code); + MEMCPY(&payload[2], str, str_length + 1); + + udp_sendto(tftp_state.upcb, p, addr, port); + pbuf_free(p); +} + +static void +send_ack(u16_t blknum) +{ + struct pbuf* p; + u16_t* payload; + + p = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH, PBUF_RAM); + if(p == NULL) { + return; + } + payload = (u16_t*) p->payload; + + payload[0] = PP_HTONS(TFTP_ACK); + payload[1] = lwip_htons(blknum); + udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port); + pbuf_free(p); +} + +static void +resend_data(void) +{ + struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, tftp_state.last_data->len, PBUF_RAM); + if(p == NULL) { + return; + } + + if(pbuf_copy(p, tftp_state.last_data) != ERR_OK) { + pbuf_free(p); + return; + } + + udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port); + pbuf_free(p); +} + +static void +send_data(void) +{ + u16_t *payload; + int ret; + + if(tftp_state.last_data != NULL) { + pbuf_free(tftp_state.last_data); + } + + tftp_state.last_data = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH + TFTP_MAX_PAYLOAD_SIZE, PBUF_RAM); + if(tftp_state.last_data == NULL) { + return; + } + + payload = (u16_t *) tftp_state.last_data->payload; + payload[0] = PP_HTONS(TFTP_DATA); + payload[1] = lwip_htons(tftp_state.blknum); + + ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE); + if (ret < 0) { + send_error(&tftp_state.addr, tftp_state.port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file."); + close_handle(); + return; + } + + pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret)); + resend_data(); +} + +static void +recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + u16_t *sbuf = (u16_t *) p->payload; + int opcode; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(upcb); + + if (((tftp_state.port != 0) && (port != tftp_state.port)) || + (!ip_addr_isany_val(tftp_state.addr) && !ip_addr_cmp(&tftp_state.addr, addr))) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); + pbuf_free(p); + return; + } + + opcode = sbuf[0]; + + tftp_state.last_pkt = tftp_state.timer; + tftp_state.retries = 0; + + switch (opcode) { + case PP_HTONS(TFTP_RRQ): /* fall through */ + case PP_HTONS(TFTP_WRQ): + { + const char tftp_null = 0; + char filename[TFTP_MAX_FILENAME_LEN]; + char mode[TFTP_MAX_MODE_LEN]; + u16_t filename_end_offset; + u16_t mode_end_offset; + + if(tftp_state.handle != NULL) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); + break; + } + + sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); + + /* find \0 in pbuf -> end of filename string */ + filename_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), 2); + if((u16_t)(filename_end_offset-2) > sizeof(filename)) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Filename too long/not NULL terminated"); + break; + } + pbuf_copy_partial(p, filename, filename_end_offset-2, 2); + + /* find \0 in pbuf -> end of mode string */ + mode_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), filename_end_offset+1); + if((u16_t)(mode_end_offset-filename_end_offset) > sizeof(mode)) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Mode too long/not NULL terminated"); + break; + } + pbuf_copy_partial(p, mode, mode_end_offset-filename_end_offset, filename_end_offset+1); + + tftp_state.handle = tftp_state.ctx->open(filename, mode, opcode == PP_HTONS(TFTP_WRQ)); + tftp_state.blknum = 1; + + if (!tftp_state.handle) { + send_error(addr, port, TFTP_ERROR_FILE_NOT_FOUND, "Unable to open requested file."); + break; + } + + LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: %s request from ", (opcode == PP_HTONS(TFTP_WRQ)) ? "write" : "read")); + ip_addr_debug_print(TFTP_DEBUG | LWIP_DBG_STATE, addr); + LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, (" for '%s' mode '%s'\n", filename, mode)); + + ip_addr_copy(tftp_state.addr, *addr); + tftp_state.port = port; + + if (opcode == PP_HTONS(TFTP_WRQ)) { + tftp_state.mode_write = 1; + send_ack(0); + } else { + tftp_state.mode_write = 0; + send_data(); + } + + break; + } + + case PP_HTONS(TFTP_DATA): + { + int ret; + u16_t blknum; + + if (tftp_state.handle == NULL) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); + break; + } + + if (tftp_state.mode_write != 1) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a write connection"); + break; + } + + blknum = lwip_ntohs(sbuf[1]); + pbuf_header(p, -TFTP_HEADER_LENGTH); + + ret = tftp_state.ctx->write(tftp_state.handle, p); + if (ret < 0) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "error writing file"); + close_handle(); + } else { + send_ack(blknum); + } + + if (p->tot_len < TFTP_MAX_PAYLOAD_SIZE) { + close_handle(); + } + break; + } + + case PP_HTONS(TFTP_ACK): + { + u16_t blknum; + int lastpkt; + + if (tftp_state.handle == NULL) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); + break; + } + + if (tftp_state.mode_write != 0) { + send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a read connection"); + break; + } + + blknum = lwip_ntohs(sbuf[1]); + if (blknum != tftp_state.blknum) { + send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number"); + break; + } + + lastpkt = 0; + + if (tftp_state.last_data != NULL) { + lastpkt = tftp_state.last_data->tot_len != (TFTP_MAX_PAYLOAD_SIZE + TFTP_HEADER_LENGTH); + } + + if (!lastpkt) { + tftp_state.blknum++; + send_data(); + } else { + close_handle(); + } + + break; + } + + default: + send_error(addr, port, TFTP_ERROR_ILLEGAL_OPERATION, "Unknown operation"); + break; + } + + pbuf_free(p); +} + +static void +tftp_tmr(void* arg) +{ + LWIP_UNUSED_ARG(arg); + + tftp_state.timer++; + + if (tftp_state.handle == NULL) { + return; + } + + sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); + + if ((tftp_state.timer - tftp_state.last_pkt) > (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS)) { + if ((tftp_state.last_data != NULL) && (tftp_state.retries < TFTP_MAX_RETRIES)) { + LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout, retrying\n")); + resend_data(); + tftp_state.retries++; + } else { + LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout\n")); + close_handle(); + } + } +} + +/** @ingroup tftp + * Initialize TFTP server. + * @param ctx TFTP callback struct + */ +err_t +tftp_init(const struct tftp_context *ctx) +{ + err_t ret; + + struct udp_pcb *pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (pcb == NULL) { + return ERR_MEM; + } + + ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT); + if (ret != ERR_OK) { + udp_remove(pcb); + return ret; + } + + tftp_state.handle = NULL; + tftp_state.port = 0; + tftp_state.ctx = ctx; + tftp_state.timer = 0; + tftp_state.last_data = NULL; + tftp_state.upcb = pcb; + + udp_recv(pcb, recv, NULL); + + return ERR_OK; +} + +#endif /* LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/def.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/def.c new file mode 100644 index 0000000..352b552 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/def.c @@ -0,0 +1,108 @@ +/** + * @file + * Common functions used throughout the stack. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/opt.h" +#include "lwip/def.h" + +/** + * These are reference implementations of the byte swapping functions. + * Again with the aim of being simple, correct and fully portable. + * Byte swapping is the second thing you would want to optimize. You will + * need to port it to your architecture and in your cc.h: + * + * #define LWIP_PLATFORM_BYTESWAP 1 + * #define LWIP_PLATFORM_HTONS(x) + * #define LWIP_PLATFORM_HTONL(x) + * + * Note ntohs() and ntohl() are merely references to the htonx counterparts. + */ + +#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) + +/** + * Convert an u16_t from host- to network byte order. + * + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +lwip_htons(u16_t n) +{ + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); +} + +/** + * Convert an u16_t from network- to host byte order. + * + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +lwip_ntohs(u16_t n) +{ + return lwip_htons(n); +} + +/** + * Convert an u32_t from host- to network byte order. + * + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +lwip_htonl(u32_t n) +{ + return ((n & 0xff) << 24) | + ((n & 0xff00) << 8) | + ((n & 0xff0000UL) >> 8) | + ((n & 0xff000000UL) >> 24); +} + +/** + * Convert an u32_t from network- to host byte order. + * + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +lwip_ntohl(u32_t n) +{ + return lwip_htonl(n); +} + +#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dhcp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dhcp.c new file mode 100644 index 0000000..fcecff1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dhcp.c @@ -0,0 +1,1851 @@ +/** + * @file + * Dynamic Host Configuration Protocol client + * + */ + +/* + * + * Copyright (c) 2001-2004 Leon Woestenberg + * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. + * + * Author: Leon Woestenberg + * + * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform + * with RFC 2131 and RFC 2132. + * + * TODO: + * - Support for interfaces other than Ethernet (SLIP, PPP, ...) + * + * Please coordinate changes and requests with Leon Woestenberg + * + * + * Integration with your code: + * + * In lwip/dhcp.h + * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) + * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) + * + * Then have your application call dhcp_coarse_tmr() and + * dhcp_fine_tmr() on the defined intervals. + * + * dhcp_start(struct netif *netif); + * starts a DHCP client instance which configures the interface by + * obtaining an IP address lease and maintaining it. + * + * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif) + * to remove the DHCP client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/dns.h" +#include "netif/etharp.h" + +#include + +/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using + * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) + */ +#ifndef DHCP_CREATE_RAND_XID +#define DHCP_CREATE_RAND_XID 1 +#endif + +/** Default for DHCP_GLOBAL_XID is 0xABCD0000 + * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. + * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" + * #define DHCP_GLOBAL_XID rand() + */ +#ifdef DHCP_GLOBAL_XID_HEADER +#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ +#endif + +/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU + * MTU is checked to be big enough in dhcp_start */ +#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) +#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 +/** Minimum length for reply before packet is parsed */ +#define DHCP_MIN_REPLY_LEN 44 + +#define REBOOT_TRIES 2 + +/** Option handling: options are parsed in dhcp_parse_reply + * and saved in an array where other functions can load them from. + * This might be moved into the struct dhcp (not necessarily since + * lwIP is single-threaded and the array is only used while in recv + * callback). */ +#define DHCP_OPTION_IDX_OVERLOAD 0 +#define DHCP_OPTION_IDX_MSG_TYPE 1 +#define DHCP_OPTION_IDX_SERVER_ID 2 +#define DHCP_OPTION_IDX_LEASE_TIME 3 +#define DHCP_OPTION_IDX_T1 4 +#define DHCP_OPTION_IDX_T2 5 +#define DHCP_OPTION_IDX_SUBNET_MASK 6 +#define DHCP_OPTION_IDX_ROUTER 7 +#define DHCP_OPTION_IDX_DNS_SERVER 8 +#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS) + +/** Holds the decoded option values, only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; +/** Holds a flag which option was received and is contained in dhcp_rx_options_val, + only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; + +#ifdef DHCP_GLOBAL_XID +static u32_t xid; +static u8_t xid_initialised; +#endif /* DHCP_GLOBAL_XID */ + +#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) +#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) +#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) +#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) +#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) +#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) + + +/* DHCP client state machine functions */ +static err_t dhcp_discover(struct netif *netif); +static err_t dhcp_select(struct netif *netif); +static void dhcp_bind(struct netif *netif); +#if DHCP_DOES_ARP_CHECK +static err_t dhcp_decline(struct netif *netif); +#endif /* DHCP_DOES_ARP_CHECK */ +static err_t dhcp_rebind(struct netif *netif); +static err_t dhcp_reboot(struct netif *netif); +static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); + +/* receive, unfold, parse and free incoming messages */ +static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); + +/* set the DHCP timers */ +static void dhcp_timeout(struct netif *netif); +static void dhcp_t1_timeout(struct netif *netif); +static void dhcp_t2_timeout(struct netif *netif); + +/* build outgoing messages */ +/* create a DHCP message, fill in common headers */ +static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type); +/* free a DHCP request */ +static void dhcp_delete_msg(struct dhcp *dhcp); +/* add a DHCP option (type, then length in bytes) */ +static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); +/* add option values */ +static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); +static void dhcp_option_short(struct dhcp *dhcp, u16_t value); +static void dhcp_option_long(struct dhcp *dhcp, u32_t value); +#if LWIP_NETIF_HOSTNAME +static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); +#endif /* LWIP_NETIF_HOSTNAME */ +/* always add the DHCP options trailer to end and pad */ +static void dhcp_option_trailer(struct dhcp *dhcp); + +/** + * Back-off the DHCP client (because of a received NAK response). + * + * Back-off the DHCP client because of a received NAK. Receiving a + * NAK means the client asked for something non-sensible, for + * example when it tries to renew a lease obtained on another network. + * + * We clear any existing set IP address and restart DHCP negotiation + * afresh (as per RFC2131 3.2.3). + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_nak(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Set the interface down since the address must no longer be used, as per RFC2131 */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + /* Change to a defined state */ + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* We can immediately restart discovery */ + dhcp_discover(netif); +} + +#if DHCP_DOES_ARP_CHECK +/** + * Checks if the offered IP address is already in use. + * + * It does so by sending an ARP request for the offered address and + * entering CHECKING state. If no ARP reply is received within a small + * interval, the address is assumed to be free for use by us. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_check(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], + (s16_t)netif->name[1])); + dhcp_set_state(dhcp, DHCP_CHECKING); + /* create an ARP query for the offered IP address, expecting that no host + responds, as the IP address should not be in use. */ + result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); + if (result != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); + } + dhcp->tries++; + msecs = 500; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); +} +#endif /* DHCP_DOES_ARP_CHECK */ + +/** + * Remember the configuration offered by a DHCP server. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_offer(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* obtain the server address */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { + ip4_addr_set_u32(&dhcp->server_ip_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->server_ip_addr))); + /* remember offered address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif)); + } +} + +/** + * Select a DHCP server offer out of all offers. + * + * Simply select the first offer received. + * + * @param netif the netif under DHCP control + * @return lwIP specific error (see error.h) + */ +static err_t +dhcp_select(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + dhcp_set_state(dhcp, DHCP_REQUESTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + /* MUST request the offered IP address */ + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + dhcp_option_trailer(dhcp); + /* shrink the pbuf to the actual content length */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* send broadcast to any DHCP server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * The DHCP timer that checks for lease renewal/rebind timeouts. + */ +void +dhcp_coarse_tmr() +{ + struct netif *netif = netif_list; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); + /* iterate through all network interfaces */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and triggers (zeroes) now? */ + if (++netif->dhcp->lease_used == netif->dhcp->t0_timeout) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); + /* this clients' lease time has expired */ + dhcp_release(netif); + dhcp_discover(netif); + }else if (netif->dhcp->t2_rebind_time-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); + /* this clients' rebind timeout triggered */ + dhcp_t2_timeout(netif); + /* timer is active (non zero), and triggers (zeroes) now */ + } else if (netif->dhcp->t1_renew_time-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); + /* this clients' renewal timeout triggered */ + dhcp_t1_timeout(netif); + } + } + /* proceed to next netif */ + netif = netif->next; + } +} + +/** + * DHCP transaction timeout handling + * + * A DHCP server is expected to respond within a short period of time. + * This timer checks whether an outstanding DHCP request is timed out. + */ +void +dhcp_fine_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and is about to trigger now */ + if (netif->dhcp->request_timeout > 1) { + netif->dhcp->request_timeout--; + } + else if (netif->dhcp->request_timeout == 1) { + netif->dhcp->request_timeout--; + /* { netif->dhcp->request_timeout == 0 } */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); + /* this client's request timeout triggered */ + dhcp_timeout(netif); + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * A DHCP negotiation transaction, or ARP request, has timed out. + * + * The timer that was started with the DHCP or ARP request has + * timed out, indicating no response was received in time. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); + /* back-off period has passed, or server selection timed out */ + if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); + dhcp_discover(netif); + /* receiving the requested lease timed out */ + } else if (dhcp->state == DHCP_REQUESTING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); + if (dhcp->tries <= 5) { + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); + dhcp_release(netif); + dhcp_discover(netif); + } +#if DHCP_DOES_ARP_CHECK + /* received no ARP reply for the offered address (which is good) */ + } else if (dhcp->state == DHCP_CHECKING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); + if (dhcp->tries <= 1) { + dhcp_check(netif); + /* no ARP replies on the offered address, + looks like the IP address is indeed free */ + } else { + /* bind the interface to the offered address */ + dhcp_bind(netif); + } +#endif /* DHCP_DOES_ARP_CHECK */ + } + /* did not get response to renew request? */ + else if (dhcp->state == DHCP_RENEWING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); + /* just retry renewal */ + /* note that the rebind timer will eventually time-out if renew does not work */ + dhcp_renew(netif); + /* did not get response to rebind request? */ + } else if (dhcp->state == DHCP_REBINDING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); + if (dhcp->tries <= 8) { + dhcp_rebind(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); + dhcp_release(netif); + dhcp_discover(netif); + } + } else if (dhcp->state == DHCP_REBOOTING) { + if (dhcp->tries < REBOOT_TRIES) { + dhcp_reboot(netif); + } else { + dhcp_discover(netif); + } + } +} + +/** + * The renewal period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t1_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING)) { + /* just retry to renew - note that the rebind timer (t2) will + * eventually time-out if renew tries fail. */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t1_timeout(): must renew\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_RENEWING, not DHCP_BOUND */ + dhcp_renew(netif); + } +} + +/** + * The rebind period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t2_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING) || (dhcp->state == DHCP_REBINDING)) { + /* just retry to rebind */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t2_timeout(): must rebind\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_REBINDING, not DHCP_BOUND */ + dhcp_rebind(netif); + /* Calculate next timeout */ + if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) + { + netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2); + } + } +} + +/** + * Handle a DHCP ACK packet + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_ack(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; +#if LWIP_DNS + u8_t n; +#endif /* LWIP_DNS */ + + /* clear options we might not get from the ACK */ + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* lease time given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { + /* remember offered lease time */ + dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); + } + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { + /* remember given renewal period */ + dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); + } else { + /* calculate safe periods for renewal */ + dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; + } + + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { + /* remember given rebind period */ + dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); + } else { + /* calculate safe periods for rebinding */ + dhcp->offered_t2_rebind = dhcp->offered_t0_lease/2 + dhcp->offered_t0_lease /4 + dhcp->offered_t0_lease/8; // (u32_t)(dhcp->offered_t0_lease * 0.875); + } + + /* (y)our internet address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + +#if LWIP_DHCP_BOOTP_FILE + /* copy boot server address, + boot file name copied in dhcp_parse_reply if not overloaded */ + ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* subnet mask given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { + /* remember given subnet mask */ + ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); + dhcp->subnet_mask_given = 1; + } else { + dhcp->subnet_mask_given = 0; + } + + /* gateway router */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { + ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); + } + +#if LWIP_DNS + /* DNS servers */ + n = 0; + while(dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n) && (n < DNS_MAX_SERVERS)) { + ip_addr_t dns_addr; + ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); + dns_setserver(n, &dns_addr); + n++; + } +#endif /* LWIP_DNS */ +} + +/** Set a statically allocated struct dhcp to work with. + * Using this prevents dhcp_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct dhcp + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("dhcp != NULL", dhcp != NULL); + LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL); + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + netif->dhcp = dhcp; +} + +/** Removes a struct dhcp from a netif. + * + * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the + * struct dhcp since the memory is passed back to the heap. + * + * @param netif the netif from which to remove the struct dhcp + */ +void dhcp_cleanup(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + + if (netif->dhcp != NULL) { + mem_free(netif->dhcp); + netif->dhcp = NULL; + } +} + +/** + * Start DHCP negotiation for a network interface. + * + * If no DHCP client instance was attached to this interface, + * a new client is created first. If a DHCP client instance + * was already present, it restarts negotiation. + * + * @param netif The lwIP network interface + * @return lwIP error code + * - ERR_OK - No error + * - ERR_MEM - Out of memory + */ +err_t +dhcp_start(struct netif *netif) +{ + struct dhcp *dhcp; + err_t result = ERR_OK; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); + dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Remove the flag that says this netif is handled by DHCP, + it is set when we succeeded starting. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + /* check hwtype of the netif */ + if ((netif->flags & NETIF_FLAG_ETHARP) == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n")); + return ERR_ARG; + } + + /* check MTU of the netif */ + if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); + return ERR_MEM; + } + + /* no DHCP client attached yet? */ + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); + dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); + return ERR_MEM; + } + /* store this dhcp client in the netif */ + netif->dhcp = dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); + /* already has DHCP client attached */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + } + LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); + } + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + /* allocate UDP PCB */ + dhcp->pcb = udp_new(); + if (dhcp->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); + return ERR_MEM; + } + ip_set_option(dhcp->pcb, SOF_BROADCAST); + /* set up local and remote port for the pcb */ + udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + /* set up the recv callback and argument */ + udp_recv(dhcp->pcb, dhcp_recv, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); + /* (re)start the DHCP negotiation */ + result = dhcp_discover(netif); + if (result != ERR_OK) { + /* free resources allocated above */ + dhcp_stop(netif); + return ERR_MEM; + } + /* Set the flag that says this netif is handled by DHCP. */ + netif->flags |= NETIF_FLAG_DHCP; + return result; +} + +/** + * Inform a DHCP server of our manual configuration. + * + * This informs DHCP servers of our fixed IP address configuration + * by sending an INFORM message. It does not involve DHCP address + * configuration, it is just here to be nice to the network. + * + * @param netif The lwIP network interface + */ +void +dhcp_inform(struct netif *netif) +{ + struct dhcp dhcp; + err_t result = ERR_OK; + struct udp_pcb *pcb; + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + memset(&dhcp, 0, sizeof(struct dhcp)); + dhcp_set_state(&dhcp, DHCP_INFORM); + + if ((netif->dhcp != NULL) && (netif->dhcp->pcb != NULL)) { + /* re-use existing pcb */ + pcb = netif->dhcp->pcb; + } else { + pcb = udp_new(); + if (pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); + return; + } + dhcp.pcb = pcb; + ip_set_option(dhcp.pcb, SOF_BROADCAST); + udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); + } + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM); + if (result == ERR_OK) { + dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option_trailer(&dhcp); + + pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); + udp_sendto_if(pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(&dhcp); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); + } + + if (dhcp.pcb != NULL) { + /* otherwise, the existing pcb was used */ + udp_remove(dhcp.pcb); + } +} + +/** Handle a possible change in the network configuration. + * + * This enters the REBOOTING state to verify that the currently bound + * address is still valid. + */ +void +dhcp_network_changed(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + if (!dhcp) + return; + switch (dhcp->state) { + case DHCP_REBINDING: + case DHCP_RENEWING: + case DHCP_BOUND: + case DHCP_REBOOTING: + netif_set_down(netif); + dhcp->tries = 0; + dhcp_reboot(netif); + break; + case DHCP_OFF: + /* stay off */ + break; + default: + dhcp->tries = 0; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + dhcp_discover(netif); + break; + } +} + +#if DHCP_DOES_ARP_CHECK +/** + * Match an ARP reply with the offered IP address. + * + * @param netif the network interface on which the reply was received + * @param addr The IP address we received a reply from + */ +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr) +{ + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); + /* is a DHCP client doing an ARP check? */ + if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", + ip4_addr_get_u32(addr))); + /* did a host respond with the address we + were offered by the DHCP server? */ + if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { + /* we will not accept the offered address */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); + dhcp_decline(netif); + } + } +} + +/** + * Decline an offered lease. + * + * Tell the DHCP server we do not accept the offered address. + * One reason to decline the lease is when we find out the address + * is already in use by another host (through ARP). + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_decline(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + /* resize pbuf to reflect true size of options */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* per section 4.4.4, broadcast DECLINE messages */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_decline: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = 10*1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} +#endif /* DHCP_DOES_ARP_CHECK */ + + +/** + * Start the DHCP process, discover a DHCP server. + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_discover(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); + ip_addr_set_any(&dhcp->offered_ip_addr); + dhcp_set_state(dhcp, DHCP_SELECTING); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER); + if (result == ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + + dhcp_option_trailer(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); + } + dhcp->tries++; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; + autoip_start(netif); + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Bind the interface to the offered IP address. + * + * @param netif network interface to bind to the offered address + */ +static void +dhcp_bind(struct netif *netif) +{ + u32_t timeout; + struct dhcp *dhcp; + ip_addr_t sn_mask, gw_addr; + LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + + /* reset time used of lease */ + dhcp->lease_used = 0; + + if( dhcp->offered_t0_lease != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); + timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t0_timeout = (u16_t)timeout; + if (dhcp->t0_timeout == 0) { + dhcp->t0_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease*1000)); + } + /* temporary DHCP lease? */ + if (dhcp->offered_t1_renew != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); + timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t1_timeout = (u16_t)timeout; + if (dhcp->t1_timeout == 0) { + dhcp->t1_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); + dhcp->t1_renew_time = dhcp->t1_timeout; + } + /* set renewal period timer */ + if (dhcp->offered_t2_rebind != 0xffffffffUL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); + timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t2_timeout = (u16_t)timeout; + if (dhcp->t2_timeout == 0) { + dhcp->t2_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); + dhcp->t2_rebind_time = dhcp->t2_timeout; + } + + if (dhcp->subnet_mask_given) { + /* copy offered network mask */ + ip_addr_copy(sn_mask, dhcp->offered_sn_mask); + } else { + /* subnet mask not given, choose a safe subnet mask given the network class */ + u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); + if (first_octet <= 127) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); + } else if (first_octet >= 192) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); + } else { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); + } + } + + ip_addr_copy(gw_addr, dhcp->offered_gw_addr); + /* gateway address not given? */ + if (ip_addr_isany(&gw_addr)) { + /* copy network address */ + ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); + /* use first host address on network as gateway */ + ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); + } + +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + netif_set_ipaddr(netif, &dhcp->offered_ip_addr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", + ip4_addr_get_u32(&sn_mask))); + netif_set_netmask(netif, &sn_mask); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", + ip4_addr_get_u32(&gw_addr))); + netif_set_gw(netif, &gw_addr); + /* bring the interface up */ + netif_set_up(netif); + /* netif is now bound to DHCP leased address */ + dhcp_set_state(dhcp, DHCP_BOUND); +} + +/** + * Renew an existing DHCP lease at the involved DHCP server. + * + * @param netif network interface which must renew its lease + */ +err_t +dhcp_renew(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); + dhcp_set_state(dhcp, DHCP_RENEWING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); +#endif + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + /* append DHCP message trailer */ + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); + } + dhcp->tries++; + /* back-off on retries, but to a maximum of 20 seconds */ + msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Rebind with a DHCP server for an existing DHCP lease. + * + * @param netif network interface which must rebind with a DHCP server + */ +static err_t +dhcp_rebind(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); + dhcp_set_state(dhcp, DHCP_REBINDING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Enter REBOOTING state to verify an existing lease + * + * @param netif network interface which must reboot + */ +static err_t +dhcp_reboot(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); + dhcp_set_state(dhcp, DHCP_REBOOTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, 576); + + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_OFF); + /* clean old DHCP offer */ + ip_addr_set_zero(&dhcp->server_ip_addr); + ip_addr_set_zero(&dhcp->offered_ip_addr); + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); + if (result == ERR_OK) { + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release_unicast(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_RELEASING); + /* clean old DHCP offer *//* + dhcp->server_ip_addr.addr = 0; + dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0; + dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0; + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + dhcp->dns_count = 0;*/ + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif,netif->dhcp,DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_RELEASE); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(netif->dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Remove the DHCP client from the interface. + * + * @param netif The network interface to stop DHCP on + */ +void +dhcp_stop(struct netif *netif) +{ + struct dhcp *dhcp; + LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + /* Remove the flag that says this netif is handled by DHCP. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); + /* netif is DHCP configured? */ + if (dhcp != NULL) { +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + dhcp->pcb = NULL; + } + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + dhcp_set_state(dhcp, DHCP_OFF); + } +} + +/* + * Set the DHCP state of a DHCP client. + * + * If the state changed, reset the number of tries. + */ +static void +dhcp_set_state(struct dhcp *dhcp, u8_t new_state) +{ + if (new_state != dhcp->state) { + dhcp->state = new_state; + dhcp->tries = 0; + dhcp->request_timeout = 0; + } +} + +/* + * Concatenate an option type and length field to the outgoing + * DHCP message. + * + */ +static void +dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) +{ + LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = option_type; + dhcp->msg_out->options[dhcp->options_out_len++] = option_len; +} +/* + * Concatenate a single byte to the outgoing DHCP message. + * + */ +static void +dhcp_option_byte(struct dhcp *dhcp, u8_t value) +{ + LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = value; +} + +static void +dhcp_option_short(struct dhcp *dhcp, u16_t value) +{ + LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); +} + +static void +dhcp_option_long(struct dhcp *dhcp, u32_t value) +{ + LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); +} + +#if LWIP_NETIF_HOSTNAME +static void +dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) +{ + if (netif->hostname != NULL) { + size_t namelen = strlen(netif->hostname); + if (namelen > 0) { + u8_t len; + const char *p = netif->hostname; + /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME + and 1 byte for trailer) */ + size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; + LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); + len = LWIP_MIN(namelen, available); + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len); + while (len--) { + dhcp_option_byte(dhcp, *p++); + } + } + } +} +#endif /* LWIP_NETIF_HOSTNAME */ + +/** + * Extract the DHCP message and the DHCP options. + * + * Extract the DHCP message and the DHCP options, each into a contiguous + * piece of memory. As a DHCP message is variable sized by its options, + * and also allows overriding some fields for options, the easy approach + * is to first unfold the options into a conitguous piece of memory, and + * use that further on. + * + */ +static err_t +dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) +{ + u8_t *options; + u16_t offset; + u16_t offset_max; + u16_t options_idx; + u16_t options_idx_max; + struct pbuf *q; + int parse_file_as_options = 0; + int parse_sname_as_options = 0; + + /* clear received options */ + dhcp_clear_all_options(dhcp); + /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ + if (p->len < DHCP_SNAME_OFS) { + return ERR_BUF; + } + dhcp->msg_in = (struct dhcp_msg *)p->payload; +#if LWIP_DHCP_BOOTP_FILE + /* clear boot file name */ + dhcp->boot_file_name[0] = 0; +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* parse options */ + + /* start with options field */ + options_idx = DHCP_OPTIONS_OFS; + /* parse options to the end of the received packet */ + options_idx_max = p->tot_len; +again: + q = p; + while((q != NULL) && (options_idx >= q->len)) { + options_idx -= q->len; + options_idx_max -= q->len; + q = q->next; + } + if (q == NULL) { + return ERR_BUF; + } + offset = options_idx; + offset_max = options_idx_max; + options = (u8_t*)q->payload; + /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ + while((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) { + u8_t op = options[offset]; + u8_t len; + u8_t decode_len = 0; + int decode_idx = -1; + u16_t val_offset = offset + 2; + /* len byte might be in the next pbuf */ + if (offset + 1 < q->len) { + len = options[offset + 1]; + } else { + len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0); + } + /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ + decode_len = len; + switch(op) { + /* case(DHCP_OPTION_END): handled above */ + case(DHCP_OPTION_PAD): + /* special option: no len encoded */ + decode_len = len = 0; + /* will be increased below */ + offset--; + break; + case(DHCP_OPTION_SUBNET_MASK): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; + break; + case(DHCP_OPTION_ROUTER): + decode_len = 4; /* only copy the first given router */ + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_ROUTER; + break; + case(DHCP_OPTION_DNS_SERVER): + /* special case: there might be more than one server */ + LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;); + /* limit number of DNS servers */ + decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_DNS_SERVER; + break; + case(DHCP_OPTION_LEASE_TIME): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_LEASE_TIME; + break; + case(DHCP_OPTION_OVERLOAD): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_OVERLOAD; + break; + case(DHCP_OPTION_MESSAGE_TYPE): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_MSG_TYPE; + break; + case(DHCP_OPTION_SERVER_ID): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SERVER_ID; + break; + case(DHCP_OPTION_T1): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T1; + break; + case(DHCP_OPTION_T2): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T2; + break; + default: + decode_len = 0; + LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op)); + break; + } + offset += len + 2; + if (decode_len > 0) { + u32_t value = 0; + u16_t copy_len; +decode_next: + LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); + if (!dhcp_option_given(dhcp, decode_idx)) { + copy_len = LWIP_MIN(decode_len, 4); + pbuf_copy_partial(q, &value, copy_len, val_offset); + if (decode_len > 4) { + /* decode more than one u32_t */ + LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, htonl(value)); + decode_len -= 4; + val_offset += 4; + decode_idx++; + goto decode_next; + } else if (decode_len == 4) { + value = ntohl(value); + } else { + LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); + value = ((u8_t*)&value)[0]; + } + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, value); + } + } + if (offset >= q->len) { + offset -= q->len; + offset_max -= q->len; + if ((offset < offset_max) && offset_max) { + q = q->next; + LWIP_ASSERT("next pbuf was null", q); + options = (u8_t*)q->payload; + } else { + // We've run out of bytes, probably no end marker. Don't proceed. + break; + } + } + } + /* is this an overloaded message? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { + u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); + dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); + if (overload == DHCP_OVERLOAD_FILE) { + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME) { + parse_sname_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { + parse_sname_as_options = 1; + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); + } +#if LWIP_DHCP_BOOTP_FILE + if (!parse_file_as_options) { + /* only do this for ACK messages */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && + (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) + /* copy bootp file name, don't care for sname (server hostname) */ + pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS); + /* make sure the string is really NULL-terminated */ + dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; + } +#endif /* LWIP_DHCP_BOOTP_FILE */ + } + if (parse_file_as_options) { + /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ + parse_file_as_options = 0; + options_idx = DHCP_FILE_OFS; + options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; + goto again; + } else if (parse_sname_as_options) { + parse_sname_as_options = 0; + options_idx = DHCP_SNAME_OFS; + options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; + goto again; + } + return ERR_OK; +} + +/** + * If an incoming DHCP message is in response to us, then trigger the state machine + */ +static void +dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + struct netif *netif = (struct netif *)arg; + struct dhcp *dhcp = netif->dhcp; + struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; + u8_t msg_type; + u8_t i; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, + ip4_addr1_16(addr), ip4_addr2_16(addr), ip4_addr3_16(addr), ip4_addr4_16(addr), port)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); + /* prevent warnings about unused arguments */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + + if (p->len < DHCP_MIN_REPLY_LEN) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); + goto free_pbuf_and_return; + } + + if (reply_msg->op != DHCP_BOOTREPLY) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); + goto free_pbuf_and_return; + } + /* iterate through hardware address and match against DHCP message */ + for (i = 0; i < netif->hwaddr_len; i++) { + if (netif->hwaddr[i] != reply_msg->chaddr[i]) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", + (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); + goto free_pbuf_and_return; + } + } + /* match transaction ID against what we expected */ + if (ntohl(reply_msg->xid) != dhcp->xid) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid)); + goto free_pbuf_and_return; + } + /* option fields could be unfold? */ + if (dhcp_parse_reply(dhcp, p) != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("problem unfolding DHCP message - too short on memory?\n")); + goto free_pbuf_and_return; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); + /* obtain pointer to DHCP message type */ + if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); + goto free_pbuf_and_return; + } + + /* read DHCP message type */ + msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); + /* message type is DHCP ACK? */ + if (msg_type == DHCP_ACK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); + /* in requesting state? */ + if (dhcp->state == DHCP_REQUESTING) { + dhcp_handle_ack(netif); +#if DHCP_DOES_ARP_CHECK + /* check if the acknowledged lease address is already in use */ + dhcp_check(netif); +#else + /* bind interface to the acknowledged lease address */ + dhcp_bind(netif); +#endif + } + /* already bound to the given lease address? */ + else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { + dhcp_bind(netif); + } + } + /* received a DHCP_NAK in appropriate state? */ + else if ((msg_type == DHCP_NAK) && + ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || + (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); + dhcp_handle_nak(netif); + } + /* received a DHCP_OFFER in DHCP_SELECTING state? */ + else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n")); + dhcp->request_timeout = 0; + /* remember offered lease */ + dhcp_handle_offer(netif); + } +free_pbuf_and_return: + dhcp->msg_in = NULL; + pbuf_free(p); +} + +/** + * Create a DHCP request, fill in common headers + * + * @param netif the netif under DHCP control + * @param dhcp dhcp control struct + * @param message_type message type of the request + */ +static err_t +dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) +{ + u16_t i; +#ifndef DHCP_GLOBAL_XID + /** default global transaction identifier starting value (easy to match + * with a packet analyser). We simply increment for each new request. + * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one + * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + static u32_t xid; +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + static u32_t xid = 0xABCD0000; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ +#else + if (!xid_initialised) { + xid = DHCP_GLOBAL_XID; + xid_initialised = !xid_initialised; + } +#endif + LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;); + LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); + LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL); + LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL); + dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); + if (dhcp->p_out == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_create_msg(): could not allocate pbuf\n")); + return ERR_MEM; + } + LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", + (dhcp->p_out->len >= sizeof(struct dhcp_msg))); + + /* reuse transaction identifier in retransmissions */ + if (dhcp->tries == 0) { +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + xid = LWIP_RAND(); +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + xid++; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + } + dhcp->xid = xid; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("transaction id xid(%"X32_F")\n", xid)); + + dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; + + dhcp->msg_out->op = DHCP_BOOTREQUEST; + /* TODO: make link layer independent */ + dhcp->msg_out->htype = DHCP_HTYPE_ETH; + dhcp->msg_out->hlen = netif->hwaddr_len; + dhcp->msg_out->hops = 0; + dhcp->msg_out->xid = htonl(dhcp->xid); + dhcp->msg_out->secs = 0; + /* we don't need the broadcast flag since we can receive unicast traffic + before being fully configured! */ + dhcp->msg_out->flags = 0; + ip_addr_set_zero(&dhcp->msg_out->ciaddr); + /* set ciaddr to netif->ip_addr based on message_type and state */ + if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || + ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */ + ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING))) { + ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr); + } + ip_addr_set_zero(&dhcp->msg_out->yiaddr); + ip_addr_set_zero(&dhcp->msg_out->siaddr); + ip_addr_set_zero(&dhcp->msg_out->giaddr); + for (i = 0; i < DHCP_CHADDR_LEN; i++) { + /* copy netif hardware address, pad with zeroes */ + dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len) ? netif->hwaddr[i] : 0/* pad byte*/; + } + for (i = 0; i < DHCP_SNAME_LEN; i++) { + dhcp->msg_out->sname[i] = 0; + } + for (i = 0; i < DHCP_FILE_LEN; i++) { + dhcp->msg_out->file[i] = 0; + } + dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); + dhcp->options_out_len = 0; + /* fill options field with an incrementing array (for debugging purposes) */ + for (i = 0; i < DHCP_OPTIONS_LEN; i++) { + dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ + } + /* Add option MESSAGE_TYPE */ + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, message_type); + return ERR_OK; +} + +/** + * Free previously allocated memory used to send a DHCP request. + * + * @param dhcp the dhcp struct to free the request from + */ +static void +dhcp_delete_msg(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL); + LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL); + if (dhcp->p_out != NULL) { + pbuf_free(dhcp->p_out); + } + dhcp->p_out = NULL; + dhcp->msg_out = NULL; +} + +/** + * Add a DHCP message trailer + * + * Adds the END option to the DHCP message, and if + * necessary, up to three padding bytes. + * + * @param dhcp DHCP state structure + */ +static void +dhcp_option_trailer(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); + LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; + /* packet is too small, or not 4 byte aligned? */ + while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && + (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { + /* add a fill/padding byte */ + dhcp->msg_out->options[dhcp->options_out_len++] = 0; + } +} + +#endif /* LWIP_DHCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dns.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dns.c new file mode 100644 index 0000000..d31ff8c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/dns.c @@ -0,0 +1,931 @@ +/** + * @file + * DNS - host name to IP address resolver. + * + */ + +/** + + * This file implements a DNS host name to IP address resolver. + + * Port to lwIP from uIP + * by Jim Pettinato April 2007 + + * uIP version Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * DNS.C + * + * The lwIP DNS resolver functions are used to lookup a host name and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the dns_lookup() function. + * New hostnames can be resolved using the dns_query() function. + * + * The lwIP version of the resolver also adds a non-blocking version of + * gethostbyname() that will work with a raw API application. This function + * checks for an IP address string first and converts it if it is valid. + * gethostbyname() then does a dns_lookup() to see if the name is + * already in the table. If so, the IP is returned. If not, a query is + * issued and the function returns with a ERR_INPROGRESS status. The app + * using the dns client must then go into a waiting state. + * + * Once a hostname has been resolved (or found to be non-existent), + * the resolver code calls a specified callback function (which + * must be implemented by the module that uses the resolver). + */ + +/*----------------------------------------------------------------------------- + * RFC 1035 - Domain names - implementation and specification + * RFC 2181 - Clarifications to the DNS Specification + *----------------------------------------------------------------------------*/ + +/** @todo: define good default values (rfc compliance) */ +/** @todo: improve answer parsing, more checkings... */ +/** @todo: check RFC1035 - 7.3. Processing responses */ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/dns.h" + +#include + +/** DNS server IP address */ +#ifndef DNS_SERVER_ADDRESS +#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */ +#endif + +/** DNS server port address */ +#ifndef DNS_SERVER_PORT +#define DNS_SERVER_PORT 53 +#endif + +/** DNS maximum number of retries when asking for a name, before "timeout". */ +#ifndef DNS_MAX_RETRIES +#define DNS_MAX_RETRIES 4 +#endif + +/** DNS resource record max. TTL (one week as default) */ +#ifndef DNS_MAX_TTL +#define DNS_MAX_TTL 604800 +#endif + +/** DNS query message structure. + No packing needed: only used locally on the stack. */ +struct dns_query { + /* DNS query record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; +}; +#define SIZEOF_DNS_QUERY 4 + +/** DNS answer message structure. + No packing needed: only used locally on the stack. */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; + u32_t ttl; + u16_t len; +}; +#define SIZEOF_DNS_ANSWER 10 + +/** DNS table entry */ +struct dns_table_entry { + u8_t state; + u8_t numdns; + u8_t tmr; + u8_t retries; + u8_t seqno; + u8_t err; + u32_t ttl; + char name[DNS_MAX_NAME_LENGTH]; + ip_addr_t ipaddr; + /* pointer to callback on DNS query done */ + dns_found_callback found; + void *arg; +}; + +#if DNS_LOCAL_HOSTLIST + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Local host-list. For hostnames in this list, no + * external name resolution is performed */ +static struct local_hostlist_entry *local_hostlist_dynamic; +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE +#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST +#define DNS_LOCAL_HOSTLIST_STORAGE_POST +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ +DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] + DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; + +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +static void dns_init_local(); +#endif /* DNS_LOCAL_HOSTLIST */ + + +/* forward declarations */ +static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); +static void dns_check_entries(void); + +/*----------------------------------------------------------------------------- + * Globales + *----------------------------------------------------------------------------*/ + +/* DNS variables */ +static struct udp_pcb *dns_pcb; +static u8_t dns_seqno; +static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; +static ip_addr_t dns_servers[DNS_MAX_SERVERS]; +/** Contiguous buffer for processing responses */ +static u8_t dns_payload_buffer[LWIP_MEM_ALIGN_BUFFER(DNS_MSG_SIZE)]; +static u8_t* dns_payload; + +/** + * Initialize the resolver: set up the UDP pcb and configure the default server + * (DNS_SERVER_ADDRESS). + */ +void +dns_init() +{ + ip_addr_t dnsserver; + + dns_payload = (u8_t *)LWIP_MEM_ALIGN(dns_payload_buffer); + + /* initialize default DNS server address */ + DNS_SERVER_ADDRESS(&dnsserver); + + LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); + + /* if dns client not yet initialized... */ + if (dns_pcb == NULL) { + dns_pcb = udp_new(); + + if (dns_pcb != NULL) { + /* initialize DNS table not needed (initialized to zero since it is a + * global variable) */ + LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", + DNS_STATE_UNUSED == 0); + + /* initialize DNS client */ + udp_bind(dns_pcb, IP_ADDR_ANY, 0); + udp_recv(dns_pcb, dns_recv, NULL); + + /* initialize default DNS primary server */ + dns_setserver(0, &dnsserver); + } + } +#if DNS_LOCAL_HOSTLIST + dns_init_local(); +#endif +} + +/** + * Initialize one of the DNS servers. + * + * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS + * @param dnsserver IP address of the DNS server to set + */ +void +dns_setserver(u8_t numdns, ip_addr_t *dnsserver) +{ + if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) && + (dnsserver != NULL) && !ip_addr_isany(dnsserver)) { + dns_servers[numdns] = (*dnsserver); + } +} + +/** + * Obtain one of the currently configured DNS server. + * + * @param numdns the index of the DNS server + * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS + * server has not been configured. + */ +ip_addr_t +dns_getserver(u8_t numdns) +{ + if (numdns < DNS_MAX_SERVERS) { + return dns_servers[numdns]; + } else { + return *IP_ADDR_ANY; + } +} + +/** + * The DNS resolver client timer - handle retries and timeouts and should + * be called every DNS_TMR_INTERVAL milliseconds (every second by default). + */ +void +dns_tmr(void) +{ + if (dns_pcb != NULL) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); + dns_check_entries(); + } +} + +#if DNS_LOCAL_HOSTLIST +static void +dns_init_local() +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) + int i; + struct local_hostlist_entry *entry; + /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ + struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; + size_t namelen; + for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { + struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; + LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); + namelen = strlen(init_entry->name); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); + if (entry != NULL) { + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, init_entry->name, namelen); + ((char*)entry->name)[namelen] = 0; + entry->addr = init_entry->addr; + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ +} + +/** + * Scans the local host-list for a hostname. + * + * @param hostname Hostname to look for in the local host-list + * @return The first IP address for the hostname in the local host-list or + * IPADDR_NONE if not found. + */ +static u32_t +dns_lookup_local(const char *hostname) +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC + struct local_hostlist_entry *entry = local_hostlist_dynamic; + while(entry != NULL) { + if(strcmp(entry->name, hostname) == 0) { + return ip4_addr_get_u32(&entry->addr); + } + entry = entry->next; + } +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + int i; + for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { + if(strcmp(local_hostlist_static[i].name, hostname) == 0) { + return ip4_addr_get_u32(&local_hostlist_static[i].addr); + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + return IPADDR_NONE; +} + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Remove all entries from the local host-list for a specific hostname + * and/or IP addess + * + * @param hostname hostname for which entries shall be removed from the local + * host-list + * @param addr address for which entries shall be removed from the local host-list + * @return the number of removed entries + */ +int +dns_local_removehost(const char *hostname, const ip_addr_t *addr) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist_dynamic; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (((hostname == NULL) || !strcmp(entry->name, hostname)) && + ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { + struct local_hostlist_entry *free_entry; + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist_dynamic = entry->next; + } + free_entry = entry; + entry = entry->next; + memp_free(MEMP_LOCALHOSTLIST, free_entry); + removed++; + } else { + last_entry = entry; + entry = entry->next; + } + } + return removed; +} + +/** + * Add a hostname/IP address pair to the local host-list. + * Duplicates are not checked. + * + * @param hostname hostname of the new entry + * @param addr IP address of the new entry + * @return ERR_OK if succeeded or ERR_MEM on memory error + */ +err_t +dns_local_addhost(const char *hostname, const ip_addr_t *addr) +{ + struct local_hostlist_entry *entry; + size_t namelen; + LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); + namelen = strlen(hostname); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + if (entry == NULL) { + return ERR_MEM; + } + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, hostname, namelen); + ((char*)entry->name)[namelen] = 0; + ip_addr_copy(entry->addr, *addr); + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + return ERR_OK; +} +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** + * Look up a hostname in the array of known hostnames. + * + * @note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function dns_enqueue() can be used to send a query + * for a hostname. + * + * @param name the hostname to look up + * @return the hostname's IP address, as u32_t (instead of ip_addr_t to + * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname + * was not found in the cached dns_table. + */ +static u32_t +dns_lookup(const char *name) +{ + u8_t i; +#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) + u32_t addr; +#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ +#if DNS_LOCAL_HOSTLIST + if ((addr = dns_lookup_local(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOCAL_HOSTLIST */ +#ifdef DNS_LOOKUP_LOCAL_EXTERN + if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOOKUP_LOCAL_EXTERN */ + + /* Walk through name list, return entry if found. If not, return NULL. */ + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + if ((dns_table[i].state == DNS_STATE_DONE) && + (strcmp(name, dns_table[i].name) == 0)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); + ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + return ip4_addr_get_u32(&dns_table[i].ipaddr); + } + } + + return IPADDR_NONE; +} + +#if DNS_DOES_NAME_CHECK +/** + * Compare the "dotted" name "query" with the encoded name "response" + * to make sure an answer from the DNS server matches the current dns_table + * entry (otherwise, answers might arrive late for hostname not on the list + * any more). + * + * @param query hostname (not encoded) from the dns_table + * @param response encoded hostname in the DNS response + * @return 0: names equal; 1: names differ + */ +static u8_t +dns_compare_name(unsigned char *query, unsigned char *response) +{ + unsigned char n; + + do { + n = *response++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + if ((*query) != (*response)) { + return 1; + } + ++response; + ++query; + --n; + }; + ++query; + } + } while (*response != 0); + + return 0; +} +#endif /* DNS_DOES_NAME_CHECK */ + +/** + * Walk through a compact encoded DNS name and return the end of the name. + * + * @param query encoded DNS name in the DNS server response + * @return end of the name + */ +static unsigned char * +dns_parse_name(unsigned char *query) +{ + unsigned char n; + + do { + n = *query++; + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + ++query; + --n; + }; + } + } while (*query != 0); + + return query + 1; +} + +/** + * Send a DNS query packet. + * + * @param numdns index of the DNS server in the dns_servers table + * @param name hostname to query + * @param id index of the hostname in dns_table, used as transaction ID in the + * DNS query packet + * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise + */ +static err_t +dns_send(u8_t numdns, const char* name, u8_t id) +{ + err_t err; + struct dns_hdr *hdr; + struct dns_query qry; + struct pbuf *p; + char *query, *nptr; + const char *pHostname; + u8_t n; + + LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", + (u16_t)(numdns), name)); + LWIP_ASSERT("dns server out of array", numdns < DNS_MAX_SERVERS); + LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[numdns])); + + /* if here, we have either a new query or a retry on a previous query to process */ + p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + DNS_MAX_NAME_LENGTH + + SIZEOF_DNS_QUERY, PBUF_RAM); + if (p != NULL) { + LWIP_ASSERT("pbuf must be in one piece", p->next == NULL); + /* fill dns header */ + hdr = (struct dns_hdr*)p->payload; + memset(hdr, 0, SIZEOF_DNS_HDR); + hdr->id = htons(id); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = PP_HTONS(1); + query = (char*)hdr + SIZEOF_DNS_HDR; + pHostname = name; + --pHostname; + + /* convert hostname into suitable query format. */ + do { + ++pHostname; + nptr = query; + ++query; + for(n = 0; *pHostname != '.' && *pHostname != 0; ++pHostname) { + *query = *pHostname; + ++query; + ++n; + } + *nptr = n; + } while(*pHostname != 0); + *query++='\0'; + + /* fill dns query */ + qry.type = PP_HTONS(DNS_RRTYPE_A); + qry.cls = PP_HTONS(DNS_RRCLASS_IN); + SMEMCPY(query, &qry, SIZEOF_DNS_QUERY); + + /* resize pbuf to the exact dns query */ + pbuf_realloc(p, (u16_t)((query + SIZEOF_DNS_QUERY) - ((char*)(p->payload)))); + + /* connect to the server for faster receiving */ + udp_connect(dns_pcb, &dns_servers[numdns], DNS_SERVER_PORT); + /* send dns packet */ + err = udp_sendto(dns_pcb, p, &dns_servers[numdns], DNS_SERVER_PORT); + + /* free pbuf */ + pbuf_free(p); + } else { + err = ERR_MEM; + } + + return err; +} + +/** + * dns_check_entry() - see if pEntry has not yet been queried and, if so, sends out a query. + * Check an entry in the dns_table: + * - send out query for new entries + * - retry old pending entries on timeout (also with different servers) + * - remove completed entries from the table if their TTL has expired + * + * @param i index of the dns_table entry to check + */ +static void +dns_check_entry(u8_t i) +{ + err_t err; + struct dns_table_entry *pEntry = &dns_table[i]; + + LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); + + switch(pEntry->state) { + + case DNS_STATE_NEW: { + /* initialize new entry */ + pEntry->state = DNS_STATE_ASKING; + pEntry->numdns = 0; + pEntry->tmr = 1; + pEntry->retries = 0; + + /* send DNS packet for this entry */ + err = dns_send(pEntry->numdns, pEntry->name, i); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + break; + } + + case DNS_STATE_ASKING: { + if (--pEntry->tmr == 0) { + if (++pEntry->retries == DNS_MAX_RETRIES) { + if ((pEntry->numdns+1numdns+1])) { + /* change of server */ + pEntry->numdns++; + pEntry->tmr = 1; + pEntry->retries = 0; + break; + } else { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name)); + /* call specified callback function if provided */ + if (pEntry->found) + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + break; + } + } + + /* wait longer for the next retry */ + pEntry->tmr = pEntry->retries; + + /* send DNS packet for this entry */ + err = dns_send(pEntry->numdns, pEntry->name, i); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + } + break; + } + + case DNS_STATE_DONE: { + /* if the time to live is nul */ + if (--pEntry->ttl == 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", pEntry->name)); + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + } + break; + } + case DNS_STATE_UNUSED: + /* nothing to do */ + break; + default: + LWIP_ASSERT("unknown dns_table entry state:", 0); + break; + } +} + +/** + * Call dns_check_entry for each entry in dns_table - check all entries. + */ +static void +dns_check_entries(void) +{ + u8_t i; + + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + dns_check_entry(i); + } +} + +/** + * Receive input function for DNS response packets arriving for the dns UDP pcb. + * + * @params see udp.h + */ +static void +dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + u16_t i; + char *pHostname; + struct dns_hdr *hdr; + struct dns_answer ans; + struct dns_table_entry *pEntry; + u16_t nquestions, nanswers; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + /* is the dns message too big ? */ + if (p->tot_len > DNS_MSG_SIZE) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); + /* free pbuf and return */ + goto memerr; + } + + /* is the dns message big enough ? */ + if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); + /* free pbuf and return */ + goto memerr; + } + + /* copy dns payload inside static buffer for processing */ + if (pbuf_copy_partial(p, dns_payload, p->tot_len, 0) == p->tot_len) { + /* The ID in the DNS header should be our entry into the name table. */ + hdr = (struct dns_hdr*)dns_payload; + i = htons(hdr->id); + if (i < DNS_TABLE_SIZE) { + pEntry = &dns_table[i]; + if(pEntry->state == DNS_STATE_ASKING) { + /* This entry is now completed. */ + pEntry->state = DNS_STATE_DONE; + pEntry->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Check for error. If so, call callback to inform. */ + if (((hdr->flags1 & DNS_FLAG1_RESPONSE) == 0) || (pEntry->err != 0) || (nquestions != 1)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + +#if DNS_DOES_NAME_CHECK + /* Check if the name in the "question" part match with the name in the entry. */ + if (dns_compare_name((unsigned char *)(pEntry->name), (unsigned char *)dns_payload + SIZEOF_DNS_HDR) != 0) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } +#endif /* DNS_DOES_NAME_CHECK */ + + /* Skip the name in the "question" part */ + pHostname = (char *) dns_parse_name((unsigned char *)dns_payload + SIZEOF_DNS_HDR) + SIZEOF_DNS_QUERY; + + while (nanswers > 0) { + /* skip answer resource record's host name */ + pHostname = (char *) dns_parse_name((unsigned char *)pHostname); + + /* Check for IP address type and Internet class. Others are discarded. */ + SMEMCPY(&ans, pHostname, SIZEOF_DNS_ANSWER); + if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && + (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) { + /* read the answer resource record's TTL, and maximize it if needed */ + pEntry->ttl = ntohl(ans.ttl); + if (pEntry->ttl > DNS_MAX_TTL) { + pEntry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + SMEMCPY(&(pEntry->ipaddr), (pHostname+SIZEOF_DNS_ANSWER), sizeof(ip_addr_t)); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", pEntry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(pEntry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + /* call specified callback function if provided */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, &pEntry->ipaddr, pEntry->arg); + } + /* deallocate memory and return */ + goto memerr; + } else { + pHostname = pHostname + SIZEOF_DNS_ANSWER + htons(ans.len); + } + --nanswers; + } + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", pEntry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + } + } + + /* deallocate memory and return */ + goto memerr; + +responseerr: + /* ERROR: call specified callback function with NULL as name to indicate an error */ + if (pEntry->found) { + (*pEntry->found)(pEntry->name, NULL, pEntry->arg); + } + /* flush this entry */ + pEntry->state = DNS_STATE_UNUSED; + pEntry->found = NULL; + +memerr: + /* free pbuf */ + pbuf_free(p); + return; +} + +/** + * Queues a new hostname to resolve and sends out a DNS query for that hostname + * + * @param name the hostname that is to be queried + * @param found a callback founction to be called on success, failure or timeout + * @param callback_arg argument to pass to the callback function + * @return @return a err_t return code. + */ +static err_t +dns_enqueue(const char *name, dns_found_callback found, void *callback_arg) +{ + u8_t i; + u8_t lseq, lseqi; + struct dns_table_entry *pEntry = NULL; + size_t namelen; + + /* search an unused entry, or the oldest one */ + lseq = lseqi = 0; + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + pEntry = &dns_table[i]; + /* is it an unused entry ? */ + if (pEntry->state == DNS_STATE_UNUSED) + break; + + /* check if this is the oldest completed entry */ + if (pEntry->state == DNS_STATE_DONE) { + if ((dns_seqno - pEntry->seqno) > lseq) { + lseq = dns_seqno - pEntry->seqno; + lseqi = i; + } + } + } + + /* if we don't have found an unused entry, use the oldest completed one */ + if (i == DNS_TABLE_SIZE) { + if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { + /* no entry can't be used now, table is full */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); + return ERR_MEM; + } else { + /* use the oldest completed one */ + i = lseqi; + pEntry = &dns_table[i]; + } + } + + /* use this entry */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); + + /* fill the entry */ + pEntry->state = DNS_STATE_NEW; + pEntry->seqno = dns_seqno++; + pEntry->found = found; + pEntry->arg = callback_arg; + namelen = LWIP_MIN(strlen(name), DNS_MAX_NAME_LENGTH-1); + MEMCPY(pEntry->name, name, namelen); + pEntry->name[namelen] = 0; + + /* force to send query without waiting timer */ + dns_check_entry(i); + + /* dns query is enqueued */ + return ERR_INPROGRESS; +} + +/** + * Resolve a hostname (string) into an IP address. + * NON-BLOCKING callback version for use with raw API! + * + * Returns immediately with one of err_t return codes: + * - ERR_OK if hostname is a valid IP address string or the host + * name is already in the local names table. + * - ERR_INPROGRESS enqueue a request to be sent to the DNS server + * for resolution if no errors are present. + * - ERR_ARG: dns client not initialized or invalid hostname + * + * @param hostname the hostname that is to be queried + * @param addr pointer to a ip_addr_t where to store the address if it is already + * cached in the dns_table (only valid if ERR_OK is returned!) + * @param found a callback function to be called on success, failure or timeout (only if + * ERR_INPROGRESS is returned!) + * @param callback_arg argument to pass to the callback function + * @return a err_t return code. + */ +err_t +dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, + void *callback_arg) +{ + u32_t ipaddr; + /* not initialized or no valid server yet, or invalid addr pointer + * or invalid hostname or invalid hostname length */ + if ((dns_pcb == NULL) || (addr == NULL) || + (!hostname) || (!hostname[0]) || + (strlen(hostname) >= DNS_MAX_NAME_LENGTH)) { + return ERR_ARG; + } + +#if LWIP_HAVE_LOOPIF + if (strcmp(hostname, "localhost")==0) { + ip_addr_set_loopback(addr); + return ERR_OK; + } +#endif /* LWIP_HAVE_LOOPIF */ + + /* host name already in octet notation? set ip addr and return ERR_OK */ + ipaddr = ipaddr_addr(hostname); + if (ipaddr == IPADDR_NONE) { + /* already have this address cached? */ + ipaddr = dns_lookup(hostname); + } + if (ipaddr != IPADDR_NONE) { + ip4_addr_set_u32(addr, ipaddr); + return ERR_OK; + } + + /* queue query with specified callback */ + return dns_enqueue(hostname, found, callback_arg); +} + +#endif /* LWIP_DNS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/init.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/init.c new file mode 100644 index 0000000..8aea49d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/init.c @@ -0,0 +1,332 @@ +/** + * @file + * Modules initialization + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/init.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/sockets.h" +#include "lwip/ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp_msg.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "lwip/api.h" + +/* Compile-time sanity checks for configuration errors. + * These can be done independently of LWIP_DEBUG, without penalty. + */ +#ifndef BYTE_ORDER + #error "BYTE_ORDER is not defined, you have to define it in your cc.h" +#endif +#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) + #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_UDPLITE) + #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DHCP) + #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_IGMP) + #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DNS) + #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ +#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) + #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" +#endif +#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) + #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) + #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) + #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) + #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" +#endif +#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) + #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" +#endif +/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ +#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT)) + #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" +#endif +#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) + #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" +#endif +#endif /* !MEMP_MEM_MALLOC */ +#if (LWIP_TCP && (TCP_WND > 0xffff)) + #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) + #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) + #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" +#endif +#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) + #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" +#endif +#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) + #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" +#endif +#if (LWIP_NETIF_API && (NO_SYS==1)) + #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) + #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if (!LWIP_NETCONN && LWIP_SOCKET) + #error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) + #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) + #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" +#endif +#if (!LWIP_ARP && LWIP_AUTOIP) + #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) + #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) + #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) + #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" +#endif +#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) + #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" +#endif +#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) + #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" +#endif +#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) + #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" +#endif +#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) + #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" +#endif +#if PPP_SUPPORT && !PPPOS_SUPPORT & !PPPOE_SUPPORT + #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on" +#endif +#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) + #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" +#endif +#if LWIP_IGMP && !defined(LWIP_RAND) + #error "When using IGMP, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value" +#endif +#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING + #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" +#endif +#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE + #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" +#endif +#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF + #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues" +#endif +#if LWIP_NETCONN && LWIP_TCP +#if NETCONN_COPY != TCP_WRITE_FLAG_COPY + #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" +#endif +#if NETCONN_MORE != TCP_WRITE_FLAG_MORE + #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" +#endif +#endif /* LWIP_NETCONN && LWIP_TCP */ +#if LWIP_SOCKET +/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ +#if SO_ACCEPTCONN != SOF_ACCEPTCONN + #error "SO_ACCEPTCONN != SOF_ACCEPTCONN" +#endif +#if SO_REUSEADDR != SOF_REUSEADDR + #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" +#endif +#if SO_KEEPALIVE != SOF_KEEPALIVE + #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" +#endif +#if SO_BROADCAST != SOF_BROADCAST + #error "WARNING: SO_BROADCAST != SOF_BROADCAST" +#endif +#if SO_LINGER != SOF_LINGER + #error "WARNING: SO_LINGER != SOF_LINGER" +#endif +#endif /* LWIP_SOCKET */ + + +/* Compile-time checks for deprecated options. + */ +#ifdef MEMP_NUM_TCPIP_MSG + #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef MEMP_NUM_API_MSG + #error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef TCP_REXMIT_DEBUG + #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef RAW_STATS + #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_QUEUE_FIRST + #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_ALWAYS_INSERT + #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." +#endif + +#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS +#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 +#endif +#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 +#endif + +/* MEMP sanity checks */ +#if !LWIP_DISABLE_MEMP_SANITY_CHECKS +#if LWIP_NETCONN +#if MEMP_MEM_MALLOC +#if !MEMP_NUM_NETCONN && LWIP_SOCKET +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" +#endif +#else /* MEMP_MEM_MALLOC */ +#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* MEMP_MEM_MALLOC */ +#endif /* LWIP_NETCONN */ +#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ + +/* TCP sanity checks */ +#if !LWIP_DISABLE_TCP_SANITY_CHECKS +#if LWIP_TCP +#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) + #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_BUF < (2 * TCP_MSS) + #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) + #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDLOWAT >= TCP_SND_BUF + #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN + #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) + #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_WND < TCP_MSS + #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* LWIP_TCP */ +#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ + +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + /* Modules initialization */ + stats_init(); +#if !NO_SYS + sys_init(); +#endif /* !NO_SYS */ + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); +#if LWIP_SOCKET + lwip_socket_init(); +#endif /* LWIP_SOCKET */ + ip_init(); +#if LWIP_ARP + etharp_init(); +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); +#endif /* LWIP_TCP */ +#if LWIP_SNMP + snmp_init(); +#endif /* LWIP_SNMP */ +#if LWIP_AUTOIP + autoip_init(); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + igmp_init(); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ + +#if LWIP_TIMERS + sys_timeouts_init(); +#endif /* LWIP_TIMERS */ +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/autoip.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/autoip.c new file mode 100644 index 0000000..b122da2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/autoip.c @@ -0,0 +1,528 @@ +/** + * @file + * AutoIP Automatic LinkLocal IP Configuration + * + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +/******************************************************************************* + * USAGE: + * + * define LWIP_AUTOIP 1 in your lwipopts.h + * + * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): + * - First, call autoip_init(). + * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, + * that should be defined in autoip.h. + * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. + * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * + * Without DHCP: + * - Call autoip_start() after netif_add(). + * + * With DHCP: + * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. + * - Configure your DHCP Client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#include +#include + +/* 169.254.0.0 */ +#define AUTOIP_NET 0xA9FE0000 +/* 169.254.1.0 */ +#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) +/* 169.254.254.255 */ +#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) + + +/** Pseudo random macro based on netif informations. + * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ +#ifndef LWIP_AUTOIP_RAND +#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ + ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ + ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ + ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ + (netif->autoip?netif->autoip->tried_llipaddr:0)) +#endif /* LWIP_AUTOIP_RAND */ + +/** + * Macro that generates the initial IP address to be tried by AUTOIP. + * If you want to override this, define it to something else in lwipopts.h. + */ +#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR +#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ + htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ + ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) +#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ + +/* static functions */ +static void autoip_handle_arp_conflict(struct netif *netif); + +/* creates a pseudo random LL IP-Address for a network interface */ +static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr); + +/* sends an ARP probe */ +static err_t autoip_arp_probe(struct netif *netif); + +/* sends an ARP announce */ +static err_t autoip_arp_announce(struct netif *netif); + +/* configure interface for use with current LL IP-Address */ +static err_t autoip_bind(struct netif *netif); + +/* start sending probes for llipaddr */ +static void autoip_start_probing(struct netif *netif); + + +/** Set a statically allocated struct autoip to work with. + * Using this prevents autoip_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct autoip + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +autoip_set_struct(struct netif *netif, struct autoip *autoip) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("autoip != NULL", autoip != NULL); + LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL); + + /* clear data structure */ + memset(autoip, 0, sizeof(struct autoip)); + /* autoip->state = AUTOIP_STATE_OFF; */ + netif->autoip = autoip; +} + +/** Restart AutoIP client and check the next address (conflict detected) + * + * @param netif The netif under AutoIP control + */ +static void +autoip_restart(struct netif *netif) +{ + netif->autoip->tried_llipaddr++; + autoip_start(netif); +} + +/** + * Handle a IP address conflict after an ARP conflict detection + */ +static void +autoip_handle_arp_conflict(struct netif *netif) +{ + /* Somehow detect if we are defending or retreating */ + unsigned char defend = 1; /* tbd */ + + if (defend) { + if (netif->autoip->lastconflict > 0) { + /* retreat, there was a conflicting ARP in the last + * DEFEND_INTERVAL seconds + */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); + + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); + autoip_arp_announce(netif); + netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } +} + +/** + * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * + * @param netif network interface on which create the IP-Address + * @param ipaddr ip address to initialize + */ +static void +autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * compliant to RFC 3927 Section 2.1 + * We have 254 * 256 possibilities */ + + u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); + addr += netif->autoip->tried_llipaddr; + addr = AUTOIP_NET | (addr & 0xffff); + /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ + + if (addr < AUTOIP_RANGE_START) { + addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + if (addr > AUTOIP_RANGE_END) { + addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && + (addr <= AUTOIP_RANGE_END)); + ip4_addr_set_u32(ipaddr, htonl(addr)); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), + ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); +} + +/** + * Sends an ARP probe from a network interface + * + * @param netif network interface used to send the probe + */ +static err_t +autoip_arp_probe(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Sends an ARP announce from a network interface + * + * @param netif network interface used to send the announce + */ +static err_t +autoip_arp_announce(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Configure interface for use with current LL IP-Address + * + * @param netif network interface to configure with current LL IP-Address + */ +static err_t +autoip_bind(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + ip_addr_t sn_mask, gw_addr; + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, + ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), + ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); + + IP4_ADDR(&sn_mask, 255, 255, 0, 0); + IP4_ADDR(&gw_addr, 0, 0, 0, 0); + + netif_set_ipaddr(netif, &autoip->llipaddr); + netif_set_netmask(netif, &sn_mask); + netif_set_gw(netif, &gw_addr); + + /* bring the interface up */ + netif_set_up(netif); + + return ERR_OK; +} + +/** + * Start AutoIP client + * + * @param netif network interface on which start the AutoIP client + */ +err_t +autoip_start(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + err_t result = ERR_OK; + + if (netif_is_up(netif)) { + netif_set_down(netif); + } + + /* Set IP-Address, Netmask and Gateway to 0 to make sure that + * ARP Packets are formed correctly + */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], + netif->name[1], (u16_t)netif->num)); + if (autoip == NULL) { + /* no AutoIP client attached yet? */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): starting new AUTOIP client\n")); + autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); + if (autoip == NULL) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): could not allocate autoip\n")); + return ERR_MEM; + } + memset(autoip, 0, sizeof(struct autoip)); + /* store this AutoIP client in the netif */ + netif->autoip = autoip; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); + } else { + autoip->state = AUTOIP_STATE_OFF; + autoip->ttw = 0; + autoip->sent_num = 0; + ip_addr_set_zero(&autoip->llipaddr); + autoip->lastconflict = 0; + } + + autoip_create_addr(netif, &(autoip->llipaddr)); + autoip_start_probing(netif); + + return result; +} + +static void +autoip_start_probing(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + + autoip->state = AUTOIP_STATE_PROBING; + autoip->sent_num = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + + /* time to wait to first probe, this is randomly + * choosen out of 0 to PROBE_WAIT seconds. + * compliant to RFC 3927 Section 2.2.1 + */ + autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); + + /* + * if we tried more then MAX_CONFLICTS we must limit our rate for + * accquiring and probing address + * compliant to RFC 3927 Section 2.2.1 + */ + if (autoip->tried_llipaddr > MAX_CONFLICTS) { + autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } +} + +/** + * Handle a possible change in the network configuration. + * + * If there is an AutoIP address configured, take the interface down + * and begin probing with the same address. + */ +void +autoip_network_changed(struct netif *netif) +{ + if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) { + netif_set_down(netif); + autoip_start_probing(netif); + } +} + +/** + * Stop AutoIP client + * + * @param netif network interface on which stop the AutoIP client + */ +err_t +autoip_stop(struct netif *netif) +{ + netif->autoip->state = AUTOIP_STATE_OFF; + netif_set_down(netif); + return ERR_OK; +} + +/** + * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds + */ +void +autoip_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on AutoIP configured interfaces */ + if (netif->autoip != NULL) { + if (netif->autoip->lastconflict > 0) { + netif->autoip->lastconflict--; + } + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", + (u16_t)(netif->autoip->state), netif->autoip->ttw)); + + switch(netif->autoip->state) { + case AUTOIP_STATE_PROBING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num >= PROBE_NUM) { + netif->autoip->state = AUTOIP_STATE_ANNOUNCING; + netif->autoip->sent_num = 0; + netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } else { + autoip_arp_probe(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() PROBING Sent Probe\n")); + netif->autoip->sent_num++; + /* calculate time to wait to next probe */ + netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % + ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + + PROBE_MIN * AUTOIP_TICKS_PER_SECOND); + } + } + break; + + case AUTOIP_STATE_ANNOUNCING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num == 0) { + /* We are here the first time, so we waited ANNOUNCE_WAIT seconds + * Now we can bind to an IP address and use it. + * + * autoip_bind calls netif_set_up. This triggers a gratuitous ARP + * which counts as an announcement. + */ + autoip_bind(netif); + } else { + autoip_arp_announce(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() ANNOUNCING Sent Announce\n")); + } + netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; + netif->autoip->sent_num++; + + if (netif->autoip->sent_num >= ANNOUNCE_NUM) { + netif->autoip->state = AUTOIP_STATE_BOUND; + netif->autoip->sent_num = 0; + netif->autoip->ttw = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } + } + break; + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * Handles every incoming ARP Packet, called by etharp_arp_input. + * + * @param netif network interface to use for autoip processing + * @param hdr Incoming ARP packet + */ +void +autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) +{ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); + if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) { + /* when ip.src == llipaddr && hw.src != netif->hwaddr + * + * when probing ip.dst == llipaddr && hw.src != netif->hwaddr + * we have a conflict and must solve it + */ + ip_addr_t sipaddr, dipaddr; + struct eth_addr netifaddr; + ETHADDR16_COPY(netifaddr.addr, netif->hwaddr); + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). + */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + if ((netif->autoip->state == AUTOIP_STATE_PROBING) || + ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && + (netif->autoip->sent_num == 0))) { + /* RFC 3927 Section 2.2.1: + * from beginning to after ANNOUNCE_WAIT + * seconds we have a conflict if + * ip.src == llipaddr OR + * ip.dst == llipaddr && hw.src != own hwaddr + */ + if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) || + (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Probe Conflict detected\n")); + autoip_restart(netif); + } + } else { + /* RFC 3927 Section 2.5: + * in any state we have a conflict if + * ip.src == llipaddr && hw.src != own hwaddr + */ + if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); + autoip_handle_arp_conflict(netif); + } + } + } +} + +#endif /* LWIP_AUTOIP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/icmp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/icmp.c new file mode 100644 index 0000000..47ba857 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/icmp.c @@ -0,0 +1,339 @@ +/** + * @file + * ICMP - Internet Control Message Protocol + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" + +#include + +/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be + * used to modify and send a response packet (and to 1 if this is not the case, + * e.g. when link header is stripped of when receiving) */ +#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + +/* The amount of data from the original packet to return in a dest-unreachable */ +#define ICMP_DEST_UNREACH_DATASIZE 8 + +static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); + +/** + * Processes ICMP input packets, called from ip_input(). + * + * Currently only processes icmp echo requests and sends + * out the echo response. + * + * @param p the icmp echo request packet, p->payload pointing to the ip header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; +#ifdef LWIP_DEBUG + u8_t code; +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + snmp_inc_icmpinmsgs(); + + + iphdr = (struct ip_hdr *)p->payload; + hlen = IPH_HL(iphdr) * 4; + if (pbuf_header(p, -hlen) || (p->tot_len < sizeof(u16_t)*2)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + case ICMP_ER: + /* This is OK, echo reply might have been parsed by a raw PCB + (as obviously, an echo request has been sent, too). */ + break; + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + accepted = 0; + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp)) { + accepted = 0; + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not acceptd? */ + if (!accepted) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + pbuf_free(p); + return; + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + ICMP_STATS_INC(icmp.chkerr); + snmp_inc_icmpinerrors(); + return; + } +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* switch p->payload to ip header */ + if (pbuf_header(p, hlen)) { + LWIP_ASSERT("icmp_input: moving p->payload to ip header failed\n", 0); + goto memerr; + } + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the whole packet including ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + iphdr = (struct ip_hdr *)r->payload; + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + /* we now have an identical copy of p that has room for link headers */ + p = r; + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = (struct icmp_echo_hdr *)p->payload; + ip_addr_copy(iphdr->src, *ip_current_dest_addr()); + ip_addr_copy(iphdr->dest, *ip_current_src_addr()); + ICMPH_TYPE_SET(iecho, ICMP_ER); +#if CHECKSUM_GEN_ICMP + /* adjust the checksum */ + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; + } else { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8); + } +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + /* send an ICMP packet, src addr is the dest addr of the curren packet */ + ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + pbuf_free(p); + return; +lenerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + snmp_inc_icmpinerrors(); + return; +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.err); + snmp_inc_icmpinerrors(); + return; +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + +/** + * Send an icmp 'destination unreachable' packet, called from ip_input() if + * the transport layer protocol is unknown and from udp_input() if the local + * port is not bound. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + icmp_send_response(p, ICMP_DUR, t); +} + +#if IP_FORWARD || IP_REASSEMBLY +/** + * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. + * + * @param p the input packet for which the 'time exceeded' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + icmp_send_response(p, ICMP_TE, t); +} + +#endif /* IP_FORWARD || IP_REASSEMBLY */ + +/** + * Send an icmp packet in response to an incoming packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + ip_addr_t iphdr_src; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + PBUF_RAM); + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = (struct ip_hdr *)p->payload; + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = (struct icmp_echo_hdr *)q->payload; + icmphdr->type = type; + icmphdr->code = code; + icmphdr->id = 0; + icmphdr->seqno = 0; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; + icmphdr->chksum = inet_chksum(icmphdr, q->len); + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_addr_copy(iphdr_src, iphdr->src); + ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/igmp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/igmp.c new file mode 100644 index 0000000..45bb5d9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/igmp.c @@ -0,0 +1,805 @@ +/** + * @file + * IGMP - Internet Group Management Protocol + * + */ + +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +/*------------------------------------------------------------- +Note 1) +Although the rfc requires V1 AND V2 capability +we will only support v2 since now V1 is very old (August 1989) +V1 can be added if required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 2) +A query for a specific group address (as opposed to ALLHOSTS) +has now been implemented as I am unsure if it is required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 3) +The router alert rfc 2113 is implemented in outgoing packets +but not checked rigorously incoming +------------------------------------------------------------- +Steve Reynolds +------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * RFC 988 - Host extensions for IP multicasting - V0 + * RFC 1054 - Host extensions for IP multicasting - + * RFC 1112 - Host extensions for IP multicasting - V1 + * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) + * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 + * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ + * RFC 2113 - IP Router Alert Option - + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/igmp.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/stats.h" + +#include "string.h" + +/* + * IGMP constants + */ +#define IGMP_TTL 1 +#define IGMP_MINLEN 8 +#define ROUTER_ALERT 0x9404U +#define ROUTER_ALERTLEN 4 + +/* + * IGMP message types, including version number. + */ +#define IGMP_MEMB_QUERY 0x11 /* Membership query */ +#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ + +/* Group membership states */ +#define IGMP_GROUP_NON_MEMBER 0 +#define IGMP_GROUP_DELAYING_MEMBER 1 +#define IGMP_GROUP_IDLE_MEMBER 2 + +/** + * IGMP packet format. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct igmp_msg { + PACK_STRUCT_FIELD(u8_t igmp_msgtype); + PACK_STRUCT_FIELD(u8_t igmp_maxresp); + PACK_STRUCT_FIELD(u16_t igmp_checksum); + PACK_STRUCT_FIELD(ip_addr_p_t igmp_group_address); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr); +static err_t igmp_remove_group(struct igmp_group *group); +static void igmp_timeout( struct igmp_group *group); +static void igmp_start_timer(struct igmp_group *group, u8_t max_time); +static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); +static err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif); +static void igmp_send(struct igmp_group *group, u8_t type); + + +static struct igmp_group* igmp_group_list; +static ip_addr_t allsystems; +static ip_addr_t allrouters; + + +/** + * Initialize the IGMP module + */ +void +igmp_init(void) +{ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); + + IP4_ADDR(&allsystems, 224, 0, 0, 1); + IP4_ADDR(&allrouters, 224, 0, 0, 2); +} + +#ifdef LWIP_DEBUG +/** + * Dump global IGMP groups list + */ +void +igmp_dump_group_list() +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state))); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + group = group->next; + } + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); +} +#else +#define igmp_dump_group_list() +#endif /* LWIP_DEBUG */ + +/** + * Start IGMP processing on interface + * + * @param netif network interface on which start IGMP processing + */ +err_t +igmp_start(struct netif *netif) +{ + struct igmp_group* group; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif)); + + group = igmp_lookup_group(netif, &allsystems); + + if (group != NULL) { + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->use++; + + /* Allow the igmp messages at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, &allsystems); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER); + } + + return ERR_OK; + } + + return ERR_MEM; +} + +/** + * Stop IGMP processing on interface + * + * @param netif network interface on which stop IGMP processing + */ +err_t +igmp_stop(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + struct igmp_group *prev = NULL; + struct igmp_group *next; + + /* look for groups joined on this interface further down the list */ + while (group != NULL) { + next = group->next; + /* is it a group joined on this interface? */ + if (group->netif == netif) { + /* is it the first group of the list? */ + if (group == igmp_group_list) { + igmp_group_list = next; + } + /* is there a "previous" group defined? */ + if (prev != NULL) { + prev->next = next; + } + /* disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER); + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + } else { + /* change the "previous" */ + prev = group; + } + /* move to "next" */ + group = next; + } + return ERR_OK; +} + +/** + * Report IGMP memberships for this interface + * + * @param netif network interface on which report IGMP memberships + */ +void +igmp_report_groups(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); + + while (group != NULL) { + if (group->netif == netif) { + igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + } + group = group->next; + } +} + +/** + * Search for a group in the global igmp_group_list + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search for + * @return a struct igmp_group* if the group has been found, + * NULL if the group wasn't found. + */ +struct igmp_group * +igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if ((group->netif == ifp) && (ip_addr_cmp(&(group->group_address), addr))) { + return group; + } + group = group->next; + } + + /* to be clearer, we return NULL here instead of + * 'group' (which is also NULL at this point). + */ + return NULL; +} + +/** + * Search for a specific igmp group and create a new one if not found- + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search + * @return a struct igmp_group*, + * NULL on memory error. + */ +struct igmp_group * +igmp_lookup_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + /* Search if the group already exists */ + group = igmp_lookfor_group(ifp, addr); + if (group != NULL) { + /* Group already exists. */ + return group; + } + + /* Group doesn't exist yet, create a new one */ + group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); + if (group != NULL) { + group->netif = ifp; + ip_addr_set(&(group->group_address), addr); + group->timer = 0; /* Not running */ + group->group_state = IGMP_GROUP_NON_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; + group->next = igmp_group_list; + + igmp_group_list = group; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); + ip_addr_debug_print(IGMP_DEBUG, addr); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp)); + + return group; +} + +/** + * Remove a group in the global igmp_group_list + * + * @param group the group to remove from the global igmp_group_list + * @return ERR_OK if group was removed from the list, an err_t otherwise + */ +static err_t +igmp_remove_group(struct igmp_group *group) +{ + err_t err = ERR_OK; + + /* Is it the first group? */ + if (igmp_group_list == group) { + igmp_group_list = group->next; + } else { + /* look for group further down the list */ + struct igmp_group *tmpGroup; + for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { + if (tmpGroup->next == group) { + tmpGroup->next = group->next; + break; + } + } + /* Group not found in the global igmp_group_list */ + if (tmpGroup == NULL) + err = ERR_ARG; + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + + return err; +} + +/** + * Called from ip_input() if a new IGMP packet is received. + * + * @param p received igmp packet, p->payload pointing to the ip header + * @param inp network interface on which the packet was received + * @param dest destination ip address of the igmp packet + */ +void +igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest) +{ + struct ip_hdr * iphdr; + struct igmp_msg* igmp; + struct igmp_group* group; + struct igmp_group* groupref; + + IGMP_STATS_INC(igmp.recv); + + /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ + iphdr = (struct ip_hdr *)p->payload; + if (pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4)) || (p->len < IGMP_MINLEN)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.lenerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); + return; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); + ip_addr_debug_print(IGMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp)); + + /* Now calculate and check the checksum */ + igmp = (struct igmp_msg *)p->payload; + if (inet_chksum(igmp, p->len)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.chkerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); + return; + } + + /* Packet is ok so find an existing group */ + group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ + + /* If group can be found or create... */ + if (!group) { + pbuf_free(p); + IGMP_STATS_INC(igmp.drop); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); + return; + } + + /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ + switch (igmp->igmp_msgtype) { + case IGMP_MEMB_QUERY: { + /* IGMP_MEMB_QUERY to the "all systems" address ? */ + if ((ip_addr_cmp(dest, &allsystems)) && ip_addr_isany(&igmp->igmp_group_address)) { + /* THIS IS THE GENERAL QUERY */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + + if (igmp->igmp_maxresp == 0) { + IGMP_STATS_INC(igmp.rx_v1); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); + igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; + } else { + IGMP_STATS_INC(igmp.rx_general); + } + + groupref = igmp_group_list; + while (groupref) { + /* Do not send messages on the all systems group address! */ + if ((groupref->netif == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) { + igmp_delaying_member(groupref, igmp->igmp_maxresp); + } + groupref = groupref->next; + } + } else { + /* IGMP_MEMB_QUERY to a specific group ? */ + if (!ip_addr_isany(&igmp->igmp_group_address)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); + ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address); + if (ip_addr_cmp(dest, &allsystems)) { + ip_addr_t groupaddr; + LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + /* we first need to re-look for the group since we used dest last time */ + ip_addr_copy(groupaddr, igmp->igmp_group_address); + group = igmp_lookfor_group(inp, &groupaddr); + } else { + LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + } + + if (group != NULL) { + IGMP_STATS_INC(igmp.rx_group); + igmp_delaying_member(group, igmp->igmp_maxresp); + } else { + IGMP_STATS_INC(igmp.drop); + } + } else { + IGMP_STATS_INC(igmp.proterr); + } + } + break; + } + case IGMP_V2_MEMB_REPORT: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); + IGMP_STATS_INC(igmp.rx_report); + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + /* This is on a specific group we have already looked up */ + group->timer = 0; /* stopped */ + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + } + break; + } + default: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", + igmp->igmp_msgtype, group->group_state, &group, group->netif)); + IGMP_STATS_INC(igmp.proterr); + break; + } + } + + pbuf_free(p); + return; +} + +/** + * Join a group on one network interface. + * + * @param ifaddr ip address of the network interface which should join a new group + * @param groupaddr the ip address of the group which to join + * @return ERR_OK if group was joined on the netif(s), an err_t otherwise + */ +err_t +igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we join this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group or create a new one if not found */ + group = igmp_lookup_group(netif, groupaddr); + + if (group != NULL) { + /* This should create a new group, check the state to make sure */ + if (group->group_state != IGMP_GROUP_NON_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n")); + } else { + /* OK - it was new group */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If first use of the group, allow the group at the MAC level */ + if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER); + } + + IGMP_STATS_INC(igmp.tx_join); + igmp_send(group, IGMP_V2_MEMB_REPORT); + + igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } + /* Increment group use */ + group->use++; + /* Join on this interface */ + err = ERR_OK; + } else { + /* Return an error even if some network interfaces are joined */ + /** @todo undo any other netif already joined */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n")); + return ERR_MEM; + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * Leave a group on one network interface. + * + * @param ifaddr ip address of the network interface which should leave a group + * @param groupaddr the ip address of the group which to leave + * @return ERR_OK if group was left on the netif(s), an err_t otherwise + */ +err_t +igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we leave this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group */ + group = igmp_lookfor_group(netif, groupaddr); + + if (group != NULL) { + /* Only send a leave if the flag is set according to the state diagram */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If there is no other use of the group */ + if (group->use <= 1) { + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n")); + IGMP_STATS_INC(igmp.tx_leave); + igmp_send(group, IGMP_LEAVE_GROUP); + } + + /* Disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER); + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* Free the group */ + igmp_remove_group(group); + } else { + /* Decrement group use */ + group->use--; + } + /* Leave on this interface */ + err = ERR_OK; + } else { + /* It's not a fatal error on "leavegroup" */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n")); + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * The igmp timer function (both for NO_SYS=1 and =0) + * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). + */ +void +igmp_tmr(void) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if (group->timer > 0) { + group->timer--; + if (group->timer == 0) { + igmp_timeout(group); + } + } + group = group->next; + } +} + +/** + * Called if a timeout for one group is reached. + * Sends a report for this group. + * + * @param group an igmp_group for which a timeout is reached + */ +static void +igmp_timeout(struct igmp_group *group) +{ + /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */ + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); + ip_addr_debug_print(IGMP_DEBUG, &(group->group_address)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + + IGMP_STATS_INC(igmp.tx_report); + igmp_send(group, IGMP_V2_MEMB_REPORT); + } +} + +/** + * Start a timer for an igmp group + * + * @param group the igmp_group for which to start a timer + * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with + * every call to igmp_tmr()) + */ +static void +igmp_start_timer(struct igmp_group *group, u8_t max_time) +{ + /* ensure the input value is > 0 */ + if (max_time == 0) { + max_time = 1; + } + /* ensure the random value is > 0 */ + group->timer = (LWIP_RAND() % (max_time - 1)) + 1; +} + +/** + * Delaying membership report for a group if necessary + * + * @param group the igmp_group for which "delaying" membership report + * @param maxresp query delay + */ +static void +igmp_delaying_member(struct igmp_group *group, u8_t maxresp) +{ + if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || + ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && + ((group->timer == 0) || (maxresp < group->timer)))) { + igmp_start_timer(group, maxresp); + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } +} + + +/** + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + */ +static err_t +igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif) +{ + /* This is the "router alert" option */ + u16_t ra[2]; + ra[0] = PP_HTONS(ROUTER_ALERT); + ra[1] = 0x0000; /* Router shall examine packet */ + IGMP_STATS_INC(igmp.xmit); + return ip_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); +} + +/** + * Send an igmp packet to a specific group. + * + * @param group the group to which to send the packet + * @param type the type of igmp packet to send + */ +static void +igmp_send(struct igmp_group *group, u8_t type) +{ + struct pbuf* p = NULL; + struct igmp_msg* igmp = NULL; + ip_addr_t src = *IP_ADDR_ANY; + ip_addr_t* dest = NULL; + + /* IP header + "router alert" option + IGMP header */ + p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); + + if (p) { + igmp = (struct igmp_msg *)p->payload; + LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", + (p->len >= sizeof(struct igmp_msg))); + ip_addr_copy(src, group->netif->ip_addr); + + if (type == IGMP_V2_MEMB_REPORT) { + dest = &(group->group_address); + ip_addr_copy(igmp->igmp_group_address, group->group_address); + group->last_reporter_flag = 1; /* Remember we were the last to report */ + } else { + if (type == IGMP_LEAVE_GROUP) { + dest = &allrouters; + ip_addr_copy(igmp->igmp_group_address, group->group_address); + } + } + + if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { + igmp->igmp_msgtype = type; + igmp->igmp_maxresp = 0; + igmp->igmp_checksum = 0; + igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); + + igmp_ip_output_if(p, &src, dest, group->netif); + } + + pbuf_free(p); + } else { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); + IGMP_STATS_INC(igmp.memerr); + } +} + +#endif /* LWIP_IGMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet.c new file mode 100644 index 0000000..e283a57 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet.c @@ -0,0 +1,42 @@ +/** + * @file + * Functions common to all TCP/IPv4 modules, such as the byte order functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet.h" + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet_chksum.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet_chksum.c new file mode 100644 index 0000000..960252f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/inet_chksum.c @@ -0,0 +1,450 @@ +/** + * @file + * Incluse internet checksum functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet_chksum.h" +#include "lwip/def.h" + +#include +#include + +/* These are some reference implementations of the checksum algorithm, with the + * aim of being simple, correct and fully portable. Checksumming is the + * first thing you would want to optimize for your platform. If you create + * your own version, link it in and in your cc.h put: + * + * #define LWIP_CHKSUM + * + * Or you can select from the implementations below by defining + * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. + */ + +#ifndef LWIP_CHKSUM +# define LWIP_CHKSUM lwip_standard_chksum +# ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 2 +# endif +#endif +/* If none set: */ +#ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 0 +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ +/** + * lwip checksum + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * @note accumulator size limits summable length to 64k + * @note host endianess is irrelevant (p3 RFC1071) + */ +static u16_t +lwip_standard_chksum(void *dataptr, u16_t len) +{ + u32_t acc; + u16_t src; + u8_t *octetptr; + + acc = 0; + /* dataptr may be at odd or even addresses */ + octetptr = (u8_t*)dataptr; + while (len > 1) { + /* declare first octet as most significant + thus assume network order, ignoring host order */ + src = (*octetptr) << 8; + octetptr++; + /* declare second octet as least significant */ + src |= (*octetptr); + octetptr++; + acc += src; + len -= 2; + } + if (len > 0) { + /* accumulate remaining octet */ + src = (*octetptr) << 8; + acc += src; + } + /* add deferred carry bits */ + acc = (acc >> 16) + (acc & 0x0000ffffUL); + if ((acc & 0xffff0000UL) != 0) { + acc = (acc >> 16) + (acc & 0x0000ffffUL); + } + /* This maybe a little confusing: reorder sum using htons() + instead of ntohs() since it has a little less call overhead. + The caller must invert bits for Internet sum ! */ + return htons((u16_t)acc); +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ +/* + * Curt McDowell + * Broadcom Corp. + * csm@broadcom.com + * + * IP checksum two bytes at a time with support for + * unaligned buffer. + * Works for len up to and including 0x20000. + * by Curt McDowell, Broadcom Corp. 12/08/2005 + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t sum = 0; + int odd = ((mem_ptr_t)pb & 1); + + /* Get aligned to u16_t */ + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + /* Add the bulk of the data */ + ps = (u16_t *)(void *)pb; + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* Consume left-over byte, if any */ + if (len > 0) { + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + /* Add end bytes */ + sum += t; + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + /* Swap if alignment was odd */ + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ +/** + * An optimized checksum routine. Basically, it uses loop-unrolling on + * the checksum loop, treating the head and tail bytes specially, whereas + * the inner loop acts on 8 bytes at a time. + * + * @arg start of buffer to be checksummed. May be an odd byte address. + * @len number of bytes in the buffer to be checksummed. + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * by Curt McDowell, Broadcom Corp. December 8th, 2005 + */ + +static u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t *pl; + u32_t sum = 0, tmp; + /* starts at odd byte address? */ + int odd = ((mem_ptr_t)pb & 1); + + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + ps = (u16_t *)pb; + + if (((mem_ptr_t)ps & 3) && len > 1) { + sum += *ps++; + len -= 2; + } + + pl = (u32_t *)ps; + + while (len > 7) { + tmp = sum + *pl++; /* ping */ + if (tmp < sum) { + tmp++; /* add back carry */ + } + + sum = tmp + *pl++; /* pong */ + if (sum < tmp) { + sum++; /* add back carry */ + } + + len -= 8; + } + + /* make room in upper bits */ + sum = FOLD_U32T(sum); + + ps = (u16_t *)pl; + + /* 16-bit aligned word remaining? */ + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* dangling tail byte remaining? */ + if (len > 0) { /* include odd byte */ + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + sum += t; /* add end bytes */ + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len) +{ + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + addr = ip4_addr_get_u32(src); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo_partial(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len) +{ + u32_t acc; + u32_t addr; + struct pbuf *q; + u8_t swapped; + u16_t chklen; + + acc = 0; + swapped = 0; + /* iterate through all pbuf in chain */ + for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + chklen = q->len; + if (chklen > chksum_len) { + chklen = chksum_len; + } + acc += LWIP_CHKSUM(q->payload, chklen); + chksum_len -= chklen; + LWIP_ASSERT("delete me", chksum_len < 0x7fff); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* fold the upper bit down */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + addr = ip4_addr_get_u32(src); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is propably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarily for IP + * and ICMP. + * + * @param dataptr start of the buffer to calculate the checksum (no alignment needed) + * @param len length of the buffer to calculate the checksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + return ~LWIP_CHKSUM(dataptr, len); +} + +/** + * Calculate a checksum over a chain of pbufs (without pseudo-header, much like + * inet_chksum only pbufs are used). + * + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += LWIP_CHKSUM(q->payload, q->len); + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + return (u16_t)~(acc & 0xffffUL); +} + +/* These are some implementations for LWIP_CHKSUM_COPY, which copies data + * like MEMCPY but generates a checksum at the same time. Since this is a + * performance-sensitive function, you might want to create your own version + * in assembly targeted at your hardware by defining it in lwipopts.h: + * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) + */ + +#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ +/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. + * For architectures with big caches, data might still be in cache when + * generating the checksum after copying. + */ +u16_t +lwip_chksum_copy(void *dst, const void *src, u16_t len) +{ + MEMCPY(dst, src, len); + return LWIP_CHKSUM(dst, len); +} +#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip.c new file mode 100644 index 0000000..b529e27 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip.c @@ -0,0 +1,957 @@ +/** + * @file + * This is the IPv4 layer implementation for incoming and outgoing IP traffic. + * + * @see ip_frag.c + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip_frag.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/igmp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/stats.h" +#include "arch/perf.h" +#include "platform_opts.h" + +#include + +/** Set this to 0 in the rare case of wanting to call an extra function to + * generate the IP checksum (in contrast to calculating it on-the-fly). */ +#ifndef LWIP_INLINE_IP_CHKSUM +#define LWIP_INLINE_IP_CHKSUM 1 +#endif +#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP_INLINE 1 +#else +#define CHECKSUM_GEN_IP_INLINE 0 +#endif + +#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 + +/** Some defines for DHCP to let link-layer-addressed packets through while the + * netif is down. + * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT + * to return 1 if the port is accepted and 0 if the port is not accepted. + */ +#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) +/* accept DHCP client port and custom port */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ + || (LWIP_IP_ACCEPT_UDP_PORT(port))) +#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept custom port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) +#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept DHCP client port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) +#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ + +#else /* LWIP_DHCP */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 +#endif /* LWIP_DHCP */ + +/** + * The interface that provided the packet for the current callback + * invocation. + */ +struct netif *current_netif; + +/** + * Header of the input packet currently being processed. + */ +const struct ip_hdr *current_header; +/** Source IP address of current_header */ +ip_addr_t current_iphdr_src; +/** Destination IP address of current_header */ +ip_addr_t current_iphdr_dest; + +/** The IP header ID of the next outgoing IP packet */ +static u16_t ip_id; + +/** The flag indicating whether the ethernet/mii is the default interface */ +extern int ethernet_if_default; + +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(ip_addr_t *dest) +{ + struct netif *netif; + struct netif *last_netif = NULL; + +#ifdef LWIP_HOOK_IP4_ROUTE + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif + + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* network mask matches? */ + if (netif_is_up(netif)) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + /* return netif on which to forward IP packet */ +#if CONFIG_ETHERNET + if(ethernet_if_default == 1) + last_netif = netif; + else + return netif; +#else + return netif; +#endif + } + } + } + +#if CONFIG_ETHERNET + if(ethernet_if_default == 1 && last_netif != NULL) + return last_netif; +#endif + + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + snmp_inc_ipoutnoroutes(); + return NULL; + } + /* no matching netif found, use default netif */ + return netif_default; +} + +#if IP_FORWARD +/** + * Determine whether an IP address is in a reserved set of addresses + * that may not be forwarded, or whether datagrams to that destination + * may be forwarded. + * @param p the packet to forward + * @param dest the destination IP address + * @return 1: can forward 0: discard + */ +static int +ip_canforward(struct pbuf *p) +{ + u32_t addr = ip4_addr_get_u32(ip_current_dest_addr()); + + if (p->flags & PBUF_FLAG_LLBCAST) { + /* don't route link-layer broadcasts */ + return 0; + } + if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { + /* don't route link-layer multicasts unless the destination address is an IP + multicast address */ + return 0; + } + if (IP_EXPERIMENTAL(addr)) { + return 0; + } + if (IP_CLASSA(addr)) { + u32_t net = addr & IP_CLASSA_NET; + if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { + /* don't route loopback packets */ + return 0; + } + } + return 1; +} + +/** + * Forwards an IP packet. It finds an appropriate route for the + * packet, decrements the TTL value of the packet, adjusts the + * checksum and outputs the packet on the appropriate interface. + * + * @param p the packet to forward (p->payload points to IP header) + * @param iphdr the IP header of the input packet + * @param inp the netif on which this packet was received + */ +static void +ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) +{ + struct netif *netif; + + PERF_START; + + if (!ip_canforward(p)) { + goto return_noroute; + } + + /* RFC3927 2.7: do not forward link-local addresses */ + if (ip_addr_islinklocal(¤t_iphdr_dest)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + goto return_noroute; + } + + /* Find network interface where to forward this IP packet to. */ + netif = ip_route(¤t_iphdr_dest); + if (netif == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + /* @todo: send ICMP_DUR_NET? */ + goto return_noroute; + } +#ifdef CONFIG_DONT_CARE_TP + /* Do not forward packets onto the same network interface on which + * they arrived. */ + if((netif->flags & NETIF_FLAG_IPSWITCH) == 0) + { +#endif +#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF + if (netif == inp) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); + goto return_noroute; + } +#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ +#ifdef CONFIG_DONT_CARE_TP + } +#endif + /* decrement TTL */ + IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); + /* send ICMP if TTL == 0 */ + if (IPH_TTL(iphdr) == 0) { + snmp_inc_ipinhdrerrors(); +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + return; + } + + /* Incrementally update the IP checksum. */ + if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); + } else { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); + } + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(¤t_iphdr_dest), ip4_addr2_16(¤t_iphdr_dest), + ip4_addr3_16(¤t_iphdr_dest), ip4_addr4_16(¤t_iphdr_dest))); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + snmp_inc_ipforwdatagrams(); + + PERF_STOP("ip_forward"); + /* don't fragment if interface has mtu set to 0 [loopif] */ +#ifdef CONFIG_DONT_CARE_TP + if ((netif->flags & NETIF_FLAG_IPSWITCH) &&(netif->mtu && (p->tot_len > netif->mtu)) ){ +#else + if (netif->mtu && (p->tot_len > netif->mtu)) { +#endif + if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { +#if IP_FRAG + ip_frag(p, netif, ip_current_dest_addr()); +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } else { + /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; + } + /* transmit pbuf on chosen interface */ + netif->output(netif, p, ¤t_iphdr_dest); + return; +return_noroute: + snmp_inc_ipoutnoroutes(); +} +#endif /* IP_FORWARD */ + +/** + * This function is called by the network interface device driver when + * an IP packet is received. The function does the basic checks of the + * IP header such as packet size being at least larger than the header + * size etc. If the packet was not destined for us, the packet is + * forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + * + * @param p the received IP packet (p->payload points to IP header) + * @param inp the netif on which this packet was received + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + int check_ip_src=1; +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + IP_STATS_INC(ip.recv); + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = (struct ip_hdr *)p->payload; + if (IPH_V(iphdr) != 4) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } + +#ifdef LWIP_HOOK_IP4_INPUT + if (LWIP_HOOK_IP4_INPUT(p, inp)) { + /* the packet has been eaten */ + return ERR_OK; + } +#endif + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + if (iphdr_hlen > p->len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_hlen, p->len)); + } + if (iphdr_len > p->tot_len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.lenerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipindiscards(); + return ERR_OK; + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.chkerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + + /* copy IP addresses to aligned ip_addr_t */ + ip_addr_copy(current_iphdr_dest, iphdr->dest); + ip_addr_copy(current_iphdr_src, iphdr->src); + + /* match packet against an interface, i.e. is this packet for us? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(¤t_iphdr_dest)) { + if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ¤t_iphdr_dest))) { + netif = inp; + } else { + netif = NULL; + } + } else +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + netif = inp; + do { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", + ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr), + ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + /* unicast to this interface address? */ + if (ip_addr_cmp(¤t_iphdr_dest, &(netif->ip_addr)) || + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(¤t_iphdr_dest, netif)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#if LWIP_AUTOIP + /* connections to link-local addresses must persist after changing + the netif's address (RFC3927 ch. 1.9) */ + if ((netif->autoip != NULL) && + ip_addr_cmp(¤t_iphdr_dest, &(netif->autoip->llipaddr))) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#endif /* LWIP_AUTOIP */ + } + if (first) { + first = 0; + netif = netif_list; + } else { + netif = netif->next; + } + if (netif == inp) { + netif = netif->next; + } + } while(netif != NULL); + } + +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed + * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. + * According to RFC 1542 section 3.1.1, referred by RFC 2131). + * + * If you want to accept private broadcast communication while a netif is down, + * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: + * + * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) + */ + if (netif == NULL) { + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(udphdr->dest))); + if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + check_ip_src = 0; + } + } + } +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + if (check_ip_src && !ip_addr_isany(¤t_iphdr_src)) +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + { if ((ip_addr_isbroadcast(¤t_iphdr_src, inp)) || + (ip_addr_ismulticast(¤t_iphdr_src))) { + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.drop); + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + } + } + + /* packet not for us? */ + if (netif == NULL) { + /* packet not for us, route or discard */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); +#if IP_FORWARD + /* non-broadcast packet? */ +#ifdef CONFIG_DONT_CARE_TP + if(inp->flags & NETIF_FLAG_IPSWITCH) +#else + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp)) +#endif +{ + /* try to forward IP packet on (other) interfaces */ + ip_forward(p, iphdr, inp); + } else +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + return ERR_OK; + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + /* packet not fully reassembled yet? */ + if (p == NULL) { + return ERR_OK; + } + iphdr = (struct ip_hdr *)p->payload; +#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", + ntohs(IPH_OFFSET(iphdr)))); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; +#endif /* IP_REASSEMBLY */ + } + +#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ + +#if LWIP_IGMP + /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ + if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { +#else + if (iphdr_hlen > IP_HLEN) { +#endif /* LWIP_IGMP */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); + pbuf_free(p); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; + } +#endif /* IP_OPTIONS_ALLOWED == 0 */ + + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + current_netif = inp; + current_header = iphdr; + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) +#endif /* LWIP_RAW */ + { + switch (IPH_PROTO(iphdr)) { +#if LWIP_UDP + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + break; +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ +#if LWIP_IGMP + case IP_PROTO_IGMP: + igmp_input(p, inp, ¤t_iphdr_dest); + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(¤t_iphdr_dest, inp) && + !ip_addr_ismulticast(¤t_iphdr_dest)) { + p->payload = iphdr; + icmp_dest_unreach(p, ICMP_DUR_PROTO); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinunknownprotos(); + } + } + + current_netif = NULL; + current_header = NULL; + ip_addr_set_any(¤t_iphdr_src); + ip_addr_set_any(¤t_iphdr_dest); + + return ERR_OK; +} + +/** + * Sends an IP packet on a network interface. This function constructs + * the IP header and calculates the IP header checksum. If the source + * IP address is NULL, the IP address of the outgoing network + * interface is filled in as source address. + * If the destination IP address is IP_HDRINCL, p is assumed to already + * include an IP header and p->payload points to it instead of the data. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + * + * @note ip_id: RFC791 "some host may be able to simply use + * unique identifiers independent of destination" + */ +err_t +ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ +#if IP_OPTIONS_SEND + return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); +} + +/** + * Same as ip_output_if() but with the possibility to include IP options: + * + * @ param ip_options pointer to the IP options, copied into the IP header + * @ param optlen length of ip_options + */ +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen) +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + ip_addr_t dest_addr; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + u16_t ip_hlen = IP_HLEN; +#if IP_OPTIONS_SEND + u16_t optlen_aligned = 0; + if (optlen != 0) { +#if CHECKSUM_GEN_IP_INLINE + int i; +#endif /* CHECKSUM_GEN_IP_INLINE */ + /* round up to a multiple of 4 */ + optlen_aligned = ((optlen + 3) & ~3); + ip_hlen += optlen_aligned; + /* First write in the IP options */ + if (pbuf_header(p, optlen_aligned)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + MEMCPY(p->payload, ip_options, optlen); + if (optlen < optlen_aligned) { + /* zero the remaining bytes */ + memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); + } +#if CHECKSUM_GEN_IP_INLINE + for (i = 0; i < optlen_aligned/2; i++) { + chk_sum += ((u16_t*)p->payload)[i]; + } +#endif /* CHECKSUM_GEN_IP_INLINE */ + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + + iphdr = (struct ip_hdr *)p->payload; + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + IPH_PROTO_SET(iphdr, proto); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(proto, ttl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip_addr_copy(iphdr->dest, *dest); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + IPH_TOS_SET(iphdr, tos); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, htons(p->tot_len)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + IPH_ID_SET(iphdr, htons(ip_id)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; +#endif /* CHECKSUM_GEN_IP_INLINE */ + ++ip_id; + + if (ip_addr_isany(src)) { + ip_addr_copy(iphdr->src, netif->ip_addr); + } else { + /* src cannot be NULL here */ + ip_addr_copy(iphdr->src, *src); + } + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + chk_sum = (chk_sum >> 16) + chk_sum; + chk_sum = ~chk_sum; + iphdr->_chksum = chk_sum; /* network order */ +#else /* CHECKSUM_GEN_IP_INLINE */ + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif +#endif /* CHECKSUM_GEN_IP_INLINE */ + } else { + /* IP header already included in p */ + iphdr = (struct ip_hdr *)p->payload; + ip_addr_copy(dest_addr, iphdr->dest); + dest = &dest_addr; + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); + ip_debug_print(p); + +#if ENABLE_LOOPBACK + if (ip_addr_cmp(dest, &netif->ip_addr)) { + /* Packet to self, enqueue it for loopback */ + LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); + return netif_loop_output(netif, p, dest); + } +#if LWIP_IGMP + if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { + netif_loop_output(netif, p, dest); + } +#endif /* LWIP_IGMP */ +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip_frag(p, netif, dest); + } +#endif /* IP_FRAG */ + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); +} + +/** + * Simple interface to ip_output_if. It finds the outgoing network + * interface and calls upon ip_output_if to do the actual work. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + struct netif *netif; + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint + * before calling ip_output_if. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param addr_hint address hint pointer set to netif->addr_hint before + * calling ip_output_if() + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + /* pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ + LWIP_ASSERT("p->ref == 1", p->ref == 1); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + NETIF_SET_HWADDRHINT(netif, addr_hint); + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +/* Print an IP header by using LWIP_DEBUGF + * @param p an IP packet, p->payload pointing to the IP header + */ +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", + IPH_V(iphdr), + IPH_HL(iphdr), + IPH_TOS(iphdr), + ntohs(IPH_LEN(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", + ntohs(IPH_ID(iphdr)), + ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, + ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", + IPH_TTL(iphdr), + IPH_PROTO(iphdr), + ntohs(IPH_CHKSUM(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", + ip4_addr1_16(&iphdr->src), + ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), + ip4_addr4_16(&iphdr->src))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", + ip4_addr1_16(&iphdr->dest), + ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), + ip4_addr4_16(&iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_addr.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_addr.c new file mode 100644 index 0000000..8f633ff --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_addr.c @@ -0,0 +1,312 @@ +/** + * @file + * This is the IPv4 address tools implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ +const ip_addr_t ip_addr_any = { IPADDR_ANY }; +const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; + +/** + * Determine if an address is a broadcast address on a network interface + * + * @param addr address to be checked + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +{ + ip_addr_t ipaddr; + ip4_addr_set_u32(&ipaddr, addr); + + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr == IPADDR_ANY) || + (addr == IPADDR_ANY)) { + return 1; + /* no broadcast support on this network interface? */ + } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + /* address matches network interface address exactly? => no broadcast */ + } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { + return 0; + /* on the same (sub) network... */ + } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) + /* ...and host identifier bits are all ones? =>... */ + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { + /* => network broadcast address */ + return 1; + } else { + return 0; + } +} + +/** Checks if a netmask is valid (starting with ones, then only zeros) + * + * @param netmask the IPv4 netmask to check (in network byte order!) + * @return 1 if the netmask is valid, 0 if it is not + */ +u8_t +ip4_addr_netmask_valid(u32_t netmask) +{ + u32_t mask; + u32_t nm_hostorder = lwip_htonl(netmask); + + /* first, check for the first zero */ + for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) == 0) { + break; + } + } + /* then check that there is no one */ + for (; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) != 0) { + /* there is a one after the first zero -> invalid */ + return 0; + } + } + /* no one after the first zero -> valid */ + return 1; +} + +/* Here for now until needed in other places in lwIP */ +#ifndef isprint +#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#endif + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @return ip address in network order + */ +u32_t +ipaddr_addr(const char *cp) +{ + ip_addr_t val; + + if (ipaddr_aton(cp, &val)) { + return ip4_addr_get_u32(&val); + } + return (IPADDR_NONE); +} + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + * + * @param cp IP address in ascii represenation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +ipaddr_aton(const char *cp, ip_addr_t *addr) +{ + u32_t val; + u8_t base; + char c; + u32_t parts[4]; + u32_t *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; + base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') { + base = 16; + c = *++cp; + } else + base = 8; + } + for (;;) { + if (isdigit(c)) { + val = (val * base) + (int)(c - '0'); + c = *++cp; + } else if (base == 16 && isxdigit(c)) { + val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) { + return (0); + } + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) { + return (0); + } + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) { + return (0); + } + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + default: + LWIP_ASSERT("unhandled", 0); + break; + } + if (addr) { + ip4_addr_set_u32(addr, htonl(val)); + } + return (1); +} + +/** + * Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * represenation of addr + */ +char * +ipaddr_ntoa(const ip_addr_t *addr) +{ + static char str[16]; + return ipaddr_ntoa_r(addr, str, 16); +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) +{ + u32_t s_addr; + char inv[3]; + char *rp; + u8_t *ap; + u8_t rem; + u8_t n; + u8_t i; + int len = 0; + + s_addr = ip4_addr_get_u32(addr); + + rp = buf; + ap = (u8_t *)&s_addr; + for(n = 0; n < 4; n++) { + i = 0; + do { + rem = *ap % (u8_t)10; + *ap /= (u8_t)10; + inv[i++] = '0' + rem; + } while(*ap); + while(i--) { + if (len++ >= buflen) { + return NULL; + } + *rp++ = inv[i]; + } + if (len++ >= buflen) { + return NULL; + } + *rp++ = '.'; + ap++; + } + *--rp = 0; + return buf; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_frag.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_frag.c new file mode 100644 index 0000000..8d18434 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/ipv4/ip_frag.c @@ -0,0 +1,863 @@ +/** + * @file + * This is the IPv4 packet segmentation and reassembly implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * Simon Goldschmidt + * original reassembly code by Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_frag.h" +#include "lwip/def.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/stats.h" +#include "lwip/icmp.h" + +#include + +#if IP_REASSEMBLY +/** + * The IP reassembly code currently has the following limitations: + * - IP header options are not supported + * - fragments must not overlap (e.g. due to different routes), + * currently, overlapping or duplicate fragments are thrown away + * if IP_REASS_CHECK_OVERLAP=1 (the default)! + * + * @todo: work with IP header options + */ + +/** Setting this to 0, you can turn off checking the fragments for overlapping + * regions. The code gets a little smaller. Only use this if you know that + * overlapping won't occur on your network! */ +#ifndef IP_REASS_CHECK_OVERLAP +#define IP_REASS_CHECK_OVERLAP 1 +#endif /* IP_REASS_CHECK_OVERLAP */ + +/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is + * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. + * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA + * is set to 1, so one datagram can be reassembled at a time, only. */ +#ifndef IP_REASS_FREE_OLDEST +#define IP_REASS_FREE_OLDEST 1 +#endif /* IP_REASS_FREE_OLDEST */ + +#define IP_REASS_FLAG_LASTFRAG 0x01 + +/** This is a helper struct which holds the starting + * offset and the ending offset of this fragment to + * easily chain the fragments. + * It has the same packing requirements as the IP header, since it replaces + * the IP header in memory in incoming fragments (after copying it) to keep + * track of the various fragments. (-> If the IP header doesn't need packing, + * this struct doesn't need packing, too.) + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_reass_helper { + PACK_STRUCT_FIELD(struct pbuf *next_pbuf); + PACK_STRUCT_FIELD(u16_t start); + PACK_STRUCT_FIELD(u16_t end); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ + (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ + ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ + IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 + +/* global variables */ +static struct ip_reassdata *reassdatagrams; +static u16_t ip_reass_pbufcount; + +/* function prototypes */ +static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); +static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); + +/** + * Reassembly timer base function + * for both NO_SYS == 0 and 1 (!). + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + struct ip_reassdata *r, *prev = NULL; + + r = reassdatagrams; + while (r != NULL) { + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + r->timer--; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + r = r->next; + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + /* get the next pointer before freeing */ + r = r->next; + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + } + } +} + +/** + * Free a datagram (struct ip_reassdata) and all its pbufs. + * Updates the total count of enqueued pbufs (ip_reass_pbufcount), + * SNMP counters and sends an ICMP time exceeded packet. + * + * @param ipr datagram to free + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + u16_t pbufs_freed = 0; + u8_t clen; + struct pbuf *p; + struct ip_reass_helper *iprh; + + LWIP_ASSERT("prev != ipr", prev != ipr); + if (prev != NULL) { + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + icmp_time_exceeded(p, ICMP_TE_FRAG); + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(p); + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + while (p != NULL) { + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + pcur = p; + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + clen = pbuf_clen(pcur); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(pcur); + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + + return pbufs_freed; +} + +#if IP_REASS_FREE_OLDEST +/** + * Free the oldest datagram to make room for enqueueing new fragments. + * The datagram 'fraghdr' belongs to is not freed! + * + * @param fraghdr IP header of the current fragment + * @param pbufs_needed number of pbufs needed to enqueue + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + prev = NULL; + other_datagrams = 0; + r = reassdatagrams; + while (r != NULL) { + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + /* Not the same datagram as fraghdr */ + other_datagrams++; + if (oldest == NULL) { + oldest = r; + } else if (r->timer <= oldest->timer) { + /* older than the previous oldest */ + oldest = r; + } + } + if (r->next != NULL) { + prev = r; + } + r = r->next; + } + if (oldest != NULL) { + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + pbufs_freed += pbufs_freed_current; + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + return pbufs_freed; +} +#endif /* IP_REASS_FREE_OLDEST */ + +/** + * Enqueues a new fragment into the fragment queue + * @param fraghdr points to the new fragments IP hdr + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + if (ipr == NULL) { +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + } + if (ipr == NULL) +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + ipr->timer = IP_REASS_MAXAGE; + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + reassdatagrams = ipr; + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + return ipr; +} + +/** + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + /* it was the first in the list */ + reassdatagrams = ipr->next; + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); +} + +/** + * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list + * will grow over time as new pbufs are rx. + * Also checks that the datagram passes basic continuity checks (if the last + * fragment was received at least once). + * @param root_p points to the 'root' pbuf for the current datagram being assembled. + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + iprh->next_pbuf = NULL; + iprh->start = offset; + iprh->end = offset + len; + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + iprh_tmp = (struct ip_reass_helper*)q->payload; + if (iprh->start < iprh_tmp->start) { + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + if (iprh_prev != NULL) { + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + } else if(iprh->start == iprh_tmp->start) { + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + if (iprh_prev->end != iprh_tmp->start) { + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + } + } + } + q = iprh_tmp->next_pbuf; + iprh_prev = iprh_tmp; + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + if (iprh_prev != NULL) { + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + if (iprh_prev->end != iprh->start) { + valid = 0; + } + } else { +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + /* and had no wholes so far */ + if (valid) { + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if (((struct ip_reass_helper*)ipr->p->payload)->start != 0) { + valid = 0; + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + q = iprh->next_pbuf; + while (q != NULL) { + iprh = (struct ip_reass_helper*)q->payload; + if (iprh_prev->end != iprh->start) { + valid = 0; + break; + } + iprh_prev = iprh; + q = iprh->next_pbuf; + } + /* if still valid, all fragments are received + * (because to the MF==0 already arrived */ + if (valid) { + LWIP_ASSERT("sanity check", ipr->p != NULL); + LWIP_ASSERT("sanity check", + ((struct ip_reass_helper*)ipr->p->payload) != iprh); + LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", + iprh->next_pbuf == NULL); + LWIP_ASSERT("validate_datagram:datagram end!=datagram len", + iprh->end == ipr->datagram_len); + } + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ +#if IP_REASS_CHECK_OVERLAP +freepbuf: + ip_reass_pbufcount -= pbuf_clen(new_p); + pbuf_free(new_p); + return 0; +#endif /* IP_REASS_CHECK_OVERLAP */ +} + +/** + * Reassembles incoming IP fragments into an IP datagram. + * + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + struct pbuf *r; + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + struct ip_reassdata *ipr_prev = NULL; + + IPFRAG_STATS_INC(ip_frag.recv); + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + goto nullreturn; + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + break; + } + ipr_prev = ipr; + } + + if (ipr == NULL) { + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + /* Bail if unable to enqueue */ + if(ipr == NULL) { + goto nullreturn; + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + ipr->datagram_len = offset + len; + LWIP_DEBUGF(IP_REASS_DEBUG, + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + IPH_OFFSET_SET(fraghdr, 0); + IPH_CHKSUM_SET(fraghdr, 0); + /* @todo: do we need to set calculate the correct checksum? */ + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); + + p = ipr->p; + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + iprh = (struct ip_reass_helper*)r->payload; + + /* hide the ip header for every succeding fragment */ + pbuf_header(r, -IP_HLEN); + pbuf_cat(p, r); + r = iprh->next_pbuf; + } + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + + /* Return the pbuf chain */ + return p; + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + pbuf_free(p); + return NULL; +} +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if IP_FRAG_USES_STATIC_BUF +static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)]; +#else /* IP_FRAG_USES_STATIC_BUF */ + +#if !LWIP_NETIF_TX_SINGLE_PBUF +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip_frag_alloc_pbuf_custom_ref(void) +{ + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); +} + +/** Free a struct pbuf_custom_ref */ +static void +ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); +} + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ipfrag_free_pbuf_custom(struct pbuf *p) +{ + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + pbuf_free(pcr->original); + } + ip_frag_free_pbuf_custom_ref(pcr); +} +#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + +/** + * Fragment an IP datagram if too large for the netif. + * + * Chop the datagram in MTU sized chunks and send them in order + * by using a fixed size static memory buffer (PBUF_REF) or + * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF). + * + * @param p ip packet to send + * @param netif the netif on which to send + * @param dest destination ip address to which to send + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) +{ + struct pbuf *rambuf; +#if IP_FRAG_USES_STATIC_BUF + struct pbuf *header; +#else +#if !LWIP_NETIF_TX_SINGLE_PBUF + struct pbuf *newpbuf; +#endif + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF + u16_t newpbuflen = 0; + u16_t left_to_copy; +#endif + + /* Get a RAM based MTU sized pbuf */ +#if IP_FRAG_USES_STATIC_BUF + /* When using a static buffer, we use a PBUF_REF, which we will + * use to reference the packet (without link header). + * Layer and length is irrelevant. + */ + rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF); + if (rambuf == NULL) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n")); + return ERR_MEM; + } + rambuf->tot_len = rambuf->len = mtu; + rambuf->payload = LWIP_MEM_ALIGN((void *)buf); + + /* Copy the IP header in it */ + iphdr = (struct ip_hdr *)rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = (struct ip_hdr *)p->payload; + iphdr = original_iphdr; +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + ofo = tmp & IP_OFFMASK; + omf = tmp & IP_MF; + + left = p->tot_len - IP_HLEN; + + nfb = (mtu - IP_HLEN) / 8; + + while (left) { + last = (left <= mtu - IP_HLEN); + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + if (!last) { + tmp = tmp | IP_MF; + } + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + +#if IP_FRAG_USES_STATIC_BUF + poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); +#else /* IP_FRAG_USES_STATIC_BUF */ +#if LWIP_NETIF_TX_SINGLE_PBUF + rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); + poff += pbuf_copy_partial(p, rambuf->payload, cop, poff); + /* make room for the IP header */ + if(pbuf_header(rambuf, IP_HLEN)) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* fill in the IP header */ + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = rambuf->payload; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = (struct ip_hdr *)rambuf->payload; + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + p->len -= poff; + + left_to_copy = cop; + while (left_to_copy) { + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + /* Is this pbuf already empty? */ + if (!newpbuflen) { + p = p->next; + continue; + } + pcr = ip_frag_alloc_pbuf_custom_ref(); + if (pcr == NULL) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + if (newpbuf == NULL) { + ip_frag_free_pbuf_custom_ref(pcr); + pbuf_free(rambuf); + return ERR_MEM; + } + pbuf_ref(p); + pcr->original = p; + pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + left_to_copy -= newpbuflen; + if (left_to_copy) { + p = p->next; + } + } + poff = newpbuflen; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + IPH_CHKSUM_SET(iphdr, 0); + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); + +#if IP_FRAG_USES_STATIC_BUF + if (last) { + pbuf_realloc(rambuf, left + IP_HLEN); + } + + /* This part is ugly: we alloc a RAM based pbuf for + * the link level header for each chunk and then + * free it.A PBUF_ROM style pbuf for which pbuf_header + * worked would make things simpler. + */ + header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); + if (header != NULL) { + pbuf_chain(header, rambuf); + netif->output(netif, header, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + snmp_inc_ipfragcreates(); + pbuf_free(header); + } else { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n")); + pbuf_free(rambuf); + return ERR_MEM; + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + + /* Unfortunately we can't reuse rambuf - the hardware may still be + * using the buffer. Instead we free it (and the ensuing chain) and + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + ofo += nfb; + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; +} +#endif /* IP_FRAG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/lwip_timers.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/lwip_timers.c new file mode 100644 index 0000000..cf7cb03 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/lwip_timers.c @@ -0,0 +1,487 @@ +/** + * @file + * Stack-internal timers implementation. + * This file includes timer callbacks for stack-internal timers as well as + * functions to set up or stop timers and check for expired timers. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#include "lwip/lwip_timers.h" +#include "lwip/tcp_impl.h" + +#if LWIP_TIMERS + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/tcpip.h" + +#include "lwip/ip_frag.h" +#include "netif/etharp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/sys.h" +#include "lwip/pbuf.h" + + +/** The one and only timeout list */ +static struct sys_timeo *next_timeout; +#if NO_SYS +static u32_t timeouts_last_time; +#endif /* NO_SYS */ + +#if LWIP_TCP +/** global variable that shows if the tcp timer is currently scheduled or not */ +static int tcpip_tcp_timer_active; + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +/** + * Called from TCP_REG when registering a new PCB: + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +/** + * Timer callback function that calls ip_reass_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +} +#endif /* IP_REASSEMBLY */ + +#if LWIP_ARP +/** + * Timer callback function that calls etharp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} +#endif /* LWIP_ARP */ + +#if LWIP_DHCP +/** + * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_coarse(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); + dhcp_coarse_tmr(); + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); +} + +/** + * Timer callback function that calls dhcp_fine_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_fine(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n")); + dhcp_fine_tmr(); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +} +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP +/** + * Timer callback function that calls autoip_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +autoip_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n")); + autoip_tmr(); + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +} +#endif /* LWIP_AUTOIP */ + +#if LWIP_IGMP +/** + * Timer callback function that calls igmp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +igmp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n")); + igmp_tmr(); + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Timer callback function that calls dns_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dns_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n")); + dns_tmr(); + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +} +#endif /* LWIP_DNS */ + +/** Initialize this module */ +void sys_timeouts_init(void) +{ +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +#endif /* LWIP_ARP */ +#if LWIP_DHCP + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ + +#if NO_SYS + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); +#endif +} + +/** + * Create a one-shot timer (aka timeout). Timeouts are processed in the + * following cases: + * - while waiting for a message using sys_timeouts_mbox_fetch() + * - by calling sys_check_timeouts() (NO_SYS==1 only) + * + * @param msecs time in milliseconds after that the timer should expire + * @param handler callback function to call when msecs have elapsed + * @param arg argument to pass to the callback function + */ +#if LWIP_DEBUG_TIMERNAMES +void +sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + struct sys_timeo *timeout, *t; + + timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); + if (timeout == NULL) { + LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); + return; + } + timeout->next = NULL; + timeout->h = handler; + timeout->arg = arg; + timeout->time = msecs; +#if LWIP_DEBUG_TIMERNAMES + timeout->handler_name = handler_name; + LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", + (void *)timeout, msecs, handler_name, (void *)arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) { + next_timeout = timeout; + return; + } + + if (next_timeout->time > msecs) { + next_timeout->time -= msecs; + timeout->next = next_timeout; + next_timeout = timeout; + } else { + for(t = next_timeout; t != NULL; t = t->next) { + timeout->time -= t->time; + if (t->next == NULL || t->next->time > timeout->time) { + if (t->next != NULL) { + t->next->time -= timeout->time; + } + timeout->next = t->next; + t->next = timeout; + break; + } + } + } +} + +/** + * Go through timeout list (for this task only) and remove the first matching + * entry, even though the timeout has not triggered yet. + * + * @note This function only works as expected if there is only one timeout + * calling 'handler' in the list of timeouts. + * + * @param handler callback function that would be called by the timeout + * @param arg callback argument that would be passed to handler +*/ +void +sys_untimeout(sys_timeout_handler handler, void *arg) +{ + struct sys_timeo *prev_t, *t; + + if (next_timeout == NULL) { + return; + } + + for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { + if ((t->h == handler) && (t->arg == arg)) { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) { + next_timeout = t->next; + } else { + prev_t->next = t->next; + } + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) { + t->next->time += t->time; + } + memp_free(MEMP_SYS_TIMEOUT, t); + return; + } + } + return; +} + +#if NO_SYS + +/** Handle timeouts for NO_SYS==1 (i.e. without using + * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout + * handler functions when timeouts expire. + * + * Must be called periodically from your main loop. + */ +void +sys_check_timeouts(void) +{ + if (next_timeout) { + struct sys_timeo *tmptimeout; + u32_t diff; + sys_timeout_handler handler; + void *arg; + u8_t had_one; + u32_t now; + + now = sys_now(); + /* this cares for wraparounds */ + diff = now - timeouts_last_time; + do + { +#if PBUF_POOL_FREE_OOSEQ + PBUF_CHECK_FREE_OOSEQ(); +#endif /* PBUF_POOL_FREE_OOSEQ */ + had_one = 0; + tmptimeout = next_timeout; + if (tmptimeout && (tmptimeout->time <= diff)) { + /* timeout has expired */ + had_one = 1; + timeouts_last_time = now; + diff -= tmptimeout->time; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + handler(arg); + } + } + /* repeat until all expired timers have been called */ + }while(had_one); + } +} + +/** Set back the timestamp of the last call to sys_check_timeouts() + * This is necessary if sys_check_timeouts() hasn't been called for a long + * time (e.g. while saving energy) to prevent all timer functions of that + * period being called. + */ +void +sys_restart_timeouts(void) +{ + timeouts_last_time = sys_now(); +} + +#else /* NO_SYS */ + +/** + * Wait (forever) for a message to arrive in an mbox. + * While waiting, timeouts are processed. + * + * @param mbox the mbox to fetch the message from + * @param msg the place to store the message + */ +void +sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) +{ + u32_t time_needed; + struct sys_timeo *tmptimeout; + sys_timeout_handler handler; + void *arg; + + again: + if (!next_timeout) { + time_needed = sys_arch_mbox_fetch(mbox, msg, 0); + } else { + if (next_timeout->time > 0) { + time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occured before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = next_timeout; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the + timeout handler function. */ + LOCK_TCPIP_CORE(); + handler(arg); + UNLOCK_TCPIP_CORE(); + } + LWIP_TCPIP_THREAD_ALIVE(); + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < next_timeout->time) { + next_timeout->time -= time_needed; + } else { + next_timeout->time = 0; + } + } + } +} + +#endif /* NO_SYS */ + +#else /* LWIP_TIMERS */ +/* Satisfy the TCP code which calls this function */ +void +tcp_timer_needed(void) +{ +} +#endif /* LWIP_TIMERS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/mem.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/mem.c new file mode 100644 index 0000000..568407c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/mem.c @@ -0,0 +1,662 @@ +/** + * @file + * Dynamic memory manager + * + * This is a lightweight replacement for the standard C library malloc(). + * + * If you want to use the standard C library malloc() instead, define + * MEM_LIBC_MALLOC to 1 in your lwipopts.h + * + * To let mem_malloc() use pools (prevents fragmentation and is much faster than + * a heap but might waste some memory), define MEM_USE_POOLS to 1, define + * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list + * of pools like this (more pools can be added between _START and _END): + * + * Define three pools with sizes 256, 512, and 1512 bytes + * LWIP_MALLOC_MEMPOOL_START + * LWIP_MALLOC_MEMPOOL(20, 256) + * LWIP_MALLOC_MEMPOOL(10, 512) + * LWIP_MALLOC_MEMPOOL(5, 1512) + * LWIP_MALLOC_MEMPOOL_END + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "lwip/err.h" + +#include + +#if MEM_USE_POOLS +/* lwIP head implemented with different sized pools */ + +/** + * Allocate memory: determine the smallest pool that is big enough + * to contain an element of 'size' and get an element from that pool. + * + * @param size the size in bytes of the memory needed + * @return a pointer to the allocated memory or NULL if the pool is empty + */ +void * +mem_malloc(mem_size_t size) +{ + void *ret; + struct memp_malloc_helper *element; + memp_t poolnr; + mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + + for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { +#if MEM_USE_POOLS_TRY_BIGGER_POOL +again: +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + /* is this pool big enough to hold an element of the required size + plus a struct memp_malloc_helper that saves the pool this element came from? */ + if (required_size <= memp_sizes[poolnr]) { + break; + } + } + if (poolnr > MEMP_POOL_LAST) { + LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); + return NULL; + } + element = (struct memp_malloc_helper*)memp_malloc(poolnr); + if (element == NULL) { + /* No need to DEBUGF or ASSERT: This error is already + taken care of in memp.c */ +#if MEM_USE_POOLS_TRY_BIGGER_POOL + /** Try a bigger pool if this one is empty! */ + if (poolnr < MEMP_POOL_LAST) { + poolnr++; + goto again; + } +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + return NULL; + } + + /* save the pool number this element came from */ + element->poolnr = poolnr; + /* and return a pointer to the memory directly after the struct memp_malloc_helper */ + ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + + return ret; +} + +/** + * Free memory previously allocated by mem_malloc. Loads the pool number + * and calls memp_free with that pool number to put the element back into + * its pool + * + * @param rmem the memory element to free + */ +void +mem_free(void *rmem) +{ + struct memp_malloc_helper *hmem; + + LWIP_ASSERT("rmem != NULL", (rmem != NULL)); + LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); + + /* get the original struct memp_malloc_helper */ + hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); + + LWIP_ASSERT("hmem != NULL", (hmem != NULL)); + LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); + LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); + + /* and put it in the pool we saved earlier */ + memp_free(hmem->poolnr, hmem); +} + +#else /* MEM_USE_POOLS */ +/* lwIP replacement for your libc malloc() */ + +/** + * The heap is made up as a list of structs of this type. + * This does not have to be aligned since for getting its size, + * we only use the macro SIZEOF_STRUCT_MEM, which automatically alignes. + */ +struct mem { + /** index (-> ram[next]) of the next struct */ + mem_size_t next; + /** index (-> ram[prev]) of the previous struct */ + mem_size_t prev; + /** 1: this area is used; 0: this area is unused */ + u8_t used; +}; + +/** All allocated blocks will be MIN_SIZE bytes big, at least! + * MIN_SIZE can be overridden to suit your needs. Smaller values save space, + * larger values could prevent too small blocks to fragment the RAM too much. */ +#ifndef MIN_SIZE +#define MIN_SIZE 12 +#endif /* MIN_SIZE */ +/* some alignment macros: we define them here for better source code layout */ +#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) +#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) +#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) + +/** If you want to relocate the heap to external memory, simply define + * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. + * If so, make sure the memory at that location is big enough (see below on + * how that space is calculated). */ +#ifndef LWIP_RAM_HEAP_POINTER +/** the heap. we need one struct mem at the end and some room for alignment */ +u8_t ram_heap[MEM_SIZE_ALIGNED + (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]; +#define LWIP_RAM_HEAP_POINTER ram_heap +#endif /* LWIP_RAM_HEAP_POINTER */ + +/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ +static u8_t *ram; +/** the last entry, always unused! */ +static struct mem *ram_end; +/** pointer to the lowest free block, this is used for faster search */ +static struct mem *lfree; + +/** concurrent access protection */ +#if !NO_SYS +static sys_mutex_t mem_mutex; +#endif + +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + +static volatile u8_t mem_free_count; + +/* Allow mem_free from other (e.g. interrupt) context */ +#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) +#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) +#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) +#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) + +#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + +/* Protect the heap only by using a semaphore */ +#define LWIP_MEM_FREE_DECL_PROTECT() +#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) +#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) +/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ +#define LWIP_MEM_ALLOC_DECL_PROTECT() +#define LWIP_MEM_ALLOC_PROTECT() +#define LWIP_MEM_ALLOC_UNPROTECT() + +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + +/** + * "Plug holes" by combining adjacent empty struct mems. + * After this function is through, there should not exist + * one empty struct mem pointing to another empty struct mem. + * + * @param mem this points to a struct mem which just has been freed + * @internal this function is only called by mem_free() and mem_trim() + * + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + struct mem *nmem; + struct mem *pmem; + + LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); + LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)(void *)&ram[mem->next]; + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + lfree = mem; + } + mem->next = nmem->next; + ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); + } + + /* plug hole backward */ + pmem = (struct mem *)(void *)&ram[mem->prev]; + if (pmem != mem && pmem->used == 0) { + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + lfree = pmem; + } + pmem->next = mem->next; + ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); + } +} + +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + struct mem *mem; + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); + /* initialize the start of the heap */ + mem = (struct mem *)(void *)ram; + mem->next = MEM_SIZE_ALIGNED; + mem->prev = 0; + mem->used = 0; + /* initialize the end of the heap */ + ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; + ram_end->used = 1; + ram_end->next = MEM_SIZE_ALIGNED; + ram_end->prev = MEM_SIZE_ALIGNED; + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)(void *)ram; + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); + + if(sys_mutex_new(&mem_mutex) != ERR_OK) { + LWIP_ASSERT("failed to create mem_mutex", 0); + } +} + +/** + * Put a struct mem back on the heap + * + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); + return; + } + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ +#if MEM_STATS + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); +#endif + return; + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + + if (mem < lfree) { + /* the newly freed struct is now the lowest */ + lfree = mem; + } + + MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); + + /* finally, see if prev or next are free also */ + plug_holes(mem); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + +/** + * Shrink memory returned by mem_malloc(). + * + * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked + * @param newsize required size after shrinking (needs to be smaller than or + * equal to the previous size) + * @return for compatibility reasons: is always == rmem, at the moment + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_trim(void *rmem, mem_size_t newsize) +{ + mem_size_t size; + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + + if(newsize < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + } + + if (newsize > MEM_SIZE_ALIGNED) { + return NULL; + } + + LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); + /* protect mem stats from concurrent access */ +#if MEM_STATS + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); +#endif + return rmem; + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... and its offset pointer */ + ptr = (mem_size_t)((u8_t *)mem - ram); + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); + if (newsize > size) { + /* not supported */ + return NULL; + } + if (newsize == size) { + /* No change in size, simply return */ + return rmem; + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + mem2 = (struct mem *)(void *)&ram[mem->next]; + if(mem2->used == 0) { + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + if (lfree == mem2) { + lfree = (struct mem *)(void *)&ram[ptr2]; + } + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + /* restore the next pointer */ + mem2->next = next; + /* link it back to mem */ + mem2->prev = ptr; + /* link mem to it */ + mem->next = ptr2; + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + /* Next struct is used but there's room for another struct mem with + * at least MIN_SIZE_ALIGNED of data. + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + mem2 = (struct mem *)(void *)&ram[ptr2]; + if (mem2 < lfree) { + lfree = mem2; + } + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* the original mem->next is used, so no need to plug holes! */ + } + /* else { + next struct mem is used but size between mem and mem2 is not big enough + to create another struct mem + -> don't do anyhting. + -> the remaining space stays unused since it is too small + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; +} + +/** + * Adam's mem_malloc() plus solution for bug #17922 + * Allocate a block of memory with a minimum of 'size' bytes. + * + * @param size is the minimum size of the requested block in bytes. + * @return pointer to allocated memory or NULL if no free memory was found. + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + return NULL; + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + + if(size < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + } + + if (size > MEM_SIZE_ALIGNED) { + return NULL; + } + + /* protect the heap from concurrent access */ + sys_mutex_lock(&mem_mutex); + LWIP_MEM_ALLOC_PROTECT(); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* run as long as a mem_free disturbed mem_malloc or mem_trim */ + do { + local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + mem = (struct mem *)(void *)&ram[ptr]; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* allow mem_free or mem_trim to run */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem. */ + local_mem_free_count = 1; + break; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing + * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') + * -> split large block, create empty remainder, + * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if + * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + /* create mem2 struct */ + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + /* and insert it between mem and mem->next */ + mem->next = ptr2; + mem->used = 1; + + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + } else { + /* (a mem2 struct does no fit into the user data space of mem and mem->next will always + * be used at this point: if not we have 2 unused structs in a row, plug_holes should have + * take care of this). + * -> near fit or excact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + if (mem == lfree) { + struct mem *cur = lfree; + /* Find next free block after mem and update lowest free pointer */ + while (cur->used && cur != ram_end) { +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* prevent high interrupt latency... */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; + } + lfree = cur; + LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); + } + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", + (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + } + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + return NULL; +} + +#endif /* MEM_USE_POOLS */ +/** + * Contiguously allocates enough space for count objects that are size bytes + * of memory each and returns a pointer to the allocated memory. + * + * The allocated memory is filled with bytes of value zero. + * + * @param count number of objects to allocate + * @param size size of the objects to allocate + * @return pointer to allocated memory / NULL pointer if there is an error + */ +void *mem_calloc(mem_size_t count, mem_size_t size) +{ + void *p; + + /* allocate 'count' objects of size 'size' */ + p = mem_malloc(count * size); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } + return p; +} + +#endif /* !MEM_LIBC_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/memp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/memp.c new file mode 100644 index 0000000..24a12b1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/memp.c @@ -0,0 +1,470 @@ +/** + * @file + * Dynamic pool memory manager + * + * lwIP has dedicated pools for many structures (netconn, protocol control blocks, + * packet buffers, ...). All these pools are managed here. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/udp.h" +#include "lwip/raw.h" +#include "lwip/tcp_impl.h" +#include "lwip/igmp.h" +#include "lwip/api.h" +#include "lwip/api_msg.h" +#include "lwip/tcpip.h" +#include "lwip/sys.h" +#include "lwip/lwip_timers.h" +#include "lwip/stats.h" +#include "netif/etharp.h" +#include "lwip/ip_frag.h" +#include "lwip/snmp_structs.h" +#include "lwip/snmp_msg.h" +#include "lwip/dns.h" +#include "netif/ppp_oe.h" + +#include + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +struct memp { + struct memp *next; +#if MEMP_OVERFLOW_CHECK + const char *file; + int line; +#endif /* MEMP_OVERFLOW_CHECK */ +}; + +#if MEMP_OVERFLOW_CHECK +/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning + * and at the end of each element, initialize them as 0xcd and check + * them later. */ +/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, + * every single element in each pool is checked! + * This is VERY SLOW but also very helpful. */ +/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in + * lwipopts.h to change the amount reserved for checking. */ +#ifndef MEMP_SANITY_REGION_BEFORE +#define MEMP_SANITY_REGION_BEFORE 16 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#if MEMP_SANITY_REGION_BEFORE > 0 +#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) +#else +#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#ifndef MEMP_SANITY_REGION_AFTER +#define MEMP_SANITY_REGION_AFTER 16 +#endif /* MEMP_SANITY_REGION_AFTER*/ +#if MEMP_SANITY_REGION_AFTER > 0 +#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) +#else +#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_AFTER*/ + +/* MEMP_SIZE: save space for struct memp and for sanity check */ +#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) + +#else /* MEMP_OVERFLOW_CHECK */ + +/* No sanity checks + * We don't need to preserve the struct memp while not allocated, so we + * can save a little space and set MEMP_SIZE to 0. + */ +#define MEMP_SIZE 0 +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_OVERFLOW_CHECK */ + +/** This array holds the first free element of each pool. + * Elements form a linked list. */ +static struct memp *memp_tab[MEMP_MAX]; + +#else /* MEMP_MEM_MALLOC */ + +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_MEM_MALLOC */ + +/** This array holds the element sizes of each pool. */ +#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC +static +#endif +const u16_t memp_sizes[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), +#include "lwip/memp_std.h" +}; + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +/** This array holds the number of elements in each pool. */ +static const u16_t memp_num[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (num), +#include "lwip/memp_std.h" +}; + +/** This array holds a textual description of each pool. */ +#ifdef LWIP_DEBUG +static const char *memp_desc[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (desc), +#include "lwip/memp_std.h" +}; +#endif /* LWIP_DEBUG */ + +#if MEMP_SEPARATE_POOLS + +/** This creates each memory pool. These are named memp_memory_XXX_base (where + * XXX is the name of the pool defined in memp_std.h). + * To relocate a pool, declare it as extern in cc.h. Example for GCC: + * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[]; + */ +#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \ + [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; +#include "lwip/memp_std.h" + +/** This array holds the base of each memory pool. */ +static u8_t *const memp_bases[] = { +#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base, +#include "lwip/memp_std.h" +}; + +#else /* MEMP_SEPARATE_POOLS */ + +/** This is the actual memory used by the pools (all pools in one big block). */ +static u8_t memp_memory[MEM_ALIGNMENT - 1 +#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) +#include "lwip/memp_std.h" +]; + +#endif /* MEMP_SEPARATE_POOLS */ + +#if MEMP_SANITY_CHECK +/** + * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". + */ +static int +memp_sanity(void) +{ + s16_t i; + struct memp *t, *h; + + for (i = 0; i < MEMP_MAX; i++) { + t = memp_tab[i]; + if(t != NULL) { + for (h = t->next; (t != NULL) && (h != NULL); t = t->next, + h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) { + if (t == h) { + return 0; + } + } + } + } + return 1; +} +#endif /* MEMP_SANITY_CHECK*/ +#if MEMP_OVERFLOW_CHECK +#if defined(LWIP_DEBUG) && MEMP_STATS +static const char * memp_overflow_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) "/"desc, +#include "lwip/memp_std.h" + }; +#endif + +/** + * Check if a memp element was victim of an overflow + * (e.g. the restricted area after it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type]; + for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp overflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Check if a memp element was victim of an underflow + * (e.g. the restricted area before it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp underflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Do an overflow check for all elements in every pool. + * + * @see memp_overflow_check_element for a description of the check + */ +static void +memp_overflow_check_all(void) +{ + u16_t i, j; + struct memp *p; + + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_overflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_underflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} + +/** + * Initialize the restricted areas of all memp elements in every pool. + */ +static void +memp_overflow_init(void) +{ + u16_t i, j; + struct memp *p; + u8_t *m; + + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); + for (i = 0; i < MEMP_MAX; ++i) { + p = p; + for (j = 0; j < memp_num[i]; ++j) { +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; + memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); +#endif + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} +#endif /* MEMP_OVERFLOW_CHECK */ + +/** + * Initialize this module. + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + MEMP_STATS_AVAIL(used, i, 0); + MEMP_STATS_AVAIL(max, i, 0); + MEMP_STATS_AVAIL(err, i, 0); + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + } + +#if !MEMP_SEPARATE_POOLS + memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + memp_tab[i] = NULL; +#if MEMP_SEPARATE_POOLS + memp = (struct memp*)memp_bases[i]; +#endif /* MEMP_SEPARATE_POOLS */ + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + memp->next = memp_tab[i]; + memp_tab[i] = memp; + memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] +#if MEMP_OVERFLOW_CHECK + + MEMP_SANITY_REGION_AFTER_ALIGNED +#endif + ); + } + } +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + +/** + * Get an element from a specific pool. + * + * @param type the pool to get an element from + * + * the debug version has two more parameters: + * @param file file name calling this function + * @param line number of line where this function is called + * + * @return a pointer to the allocated memory or a NULL pointer on error + */ +void * +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + + if (memp != NULL) { + memp_tab[type] = memp->next; +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; +} + +/** + * Put an element back into its pool. + * + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#else + memp_overflow_check_element_overflow(memp, type); + memp_overflow_check_element_underflow(memp, type); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + + memp->next = memp_tab[type]; + memp_tab[type] = memp; + +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + +#endif /* MEMP_MEM_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/netif.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/netif.c new file mode 100644 index 0000000..4a02e77 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/netif.c @@ -0,0 +1,774 @@ +/** + * @file + * lwIP network interface abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/igmp.h" +#include "netif/etharp.h" +#include "lwip/stats.h" +#if ENABLE_LOOPBACK +#include "lwip/sys.h" +#if LWIP_NETIF_LOOPBACK_MULTITHREADING +#include "lwip/tcpip.h" +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_AUTOIP +#include "lwip/autoip.h" +#endif /* LWIP_AUTOIP */ +#if LWIP_DHCP +#include "lwip/dhcp.h" +#endif /* LWIP_DHCP */ + +#if LWIP_NETIF_STATUS_CALLBACK +#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) +#else +#define NETIF_STATUS_CALLBACK(n) +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) +#else +#define NETIF_LINK_CALLBACK(n) +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +struct netif *netif_list; +struct netif *netif_default; + +static u8_t netif_num; + +#if LWIP_HAVE_LOOPIF +static struct netif loop_netif; + +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ +static err_t +netif_loopif_init(struct netif *netif) +{ + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); + + netif->name[0] = 'l'; + netif->name[1] = 'o'; + netif->output = netif_loop_output; + return ERR_OK; +} +#endif /* LWIP_HAVE_LOOPIF */ + +void +netif_init(void) +{ +#if LWIP_HAVE_LOOPIF + ip_addr_t loop_ipaddr, loop_netmask, loop_gw; + IP4_ADDR(&loop_gw, 127,0,0,1); + IP4_ADDR(&loop_ipaddr, 127,0,0,1); + IP4_ADDR(&loop_netmask, 255,0,0,0); + +#if NO_SYS + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input); +#else /* NO_SYS */ + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); +#endif /* NO_SYS */ + netif_set_up(&loop_netif); + +#endif /* LWIP_HAVE_LOOPIF */ +} + +/** + * Add a network interface to the list of lwIP netifs. + * + * @param netif a pre-allocated netif structure + * @param ipaddr IP address for the new netif + * @param netmask network mask for the new netif + * @param gw default gateway IP address for the new netif + * @param state opaque data passed to the new netif + * @param init callback function that initializes the interface + * @param input callback function that is called to pass + * ingress packets up in the protocol layer stack. + * + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) +{ + + LWIP_ASSERT("No init function given", init != NULL); + + /* reset new interface configuration state */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); + netif->flags = 0; +#if LWIP_DHCP + /* netif not under DHCP control by default */ + netif->dhcp = NULL; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /* netif not under AutoIP control by default */ + netif->autoip = NULL; +#endif /* LWIP_AUTOIP */ +#if LWIP_NETIF_STATUS_CALLBACK + netif->status_callback = NULL; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + netif->link_callback = NULL; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_IGMP + netif->igmp_mac_filter = NULL; +#endif /* LWIP_IGMP */ +#if ENABLE_LOOPBACK + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + netif->num = netif_num++; + netif->input = input; + NETIF_SET_HWADDRHINT(netif, NULL); +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + return NULL; + } + + /* add this netif to the list */ + netif->next = netif_list; + netif_list = netif; + snmp_inc_iflist(); + +#if LWIP_IGMP + /* start IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_start(netif); + } +#endif /* LWIP_IGMP */ + + LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", + netif->name[0], netif->name[1])); + ip_addr_debug_print(NETIF_DEBUG, ipaddr); + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; +} + +/** + * Change IP address configuration for a network interface (including netmask + * and default gateway). + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * @param netmask the new netmask + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw) +{ + netif_set_ipaddr(netif, ipaddr); + netif_set_netmask(netif, netmask); + netif_set_gw(netif, gw); +} + +/** + * Remove a network interface from the list of lwIP netifs. + * + * @param netif the network interface to remove + */ +void +netif_remove(struct netif *netif) +{ + if (netif == NULL) { + return; + } + +#if LWIP_IGMP + /* stop IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_stop(netif); + } +#endif /* LWIP_IGMP */ + if (netif_is_up(netif)) { + /* set netif down before removing (call callback function) */ + netif_set_down(netif); + } + + snmp_delete_ipaddridx_tree(netif); + + /* is it the first netif? */ + if (netif_list == netif) { + netif_list = netif->next; + } else { + /* look for netif further down the list */ + struct netif * tmpNetif; + for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { + if (tmpNetif->next == netif) { + tmpNetif->next = netif->next; + break; + } + } + if (tmpNetif == NULL) + return; /* we didn't find any netif today */ + } + snmp_dec_iflist(); + /* this netif is default? */ + if (netif_default == netif) { + /* reset default netif */ + netif_set_default(NULL); + } +#if LWIP_NETIF_REMOVE_CALLBACK + if (netif->remove_callback) { + netif->remove_callback(netif); + } +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); +} + +/** + * Find a network interface by searching for its name + * + * @param name the name of the netif (like netif->name) plus concatenated number + * in ascii representation (e.g. 'en0') + */ +struct netif * +netif_find(char *name) +{ + struct netif *netif; + u8_t num; + + if (name == NULL) { + return NULL; + } + + num = name[2] - '0'; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (num == netif->num && + name[0] == netif->name[0] && + name[1] == netif->name[1]) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); + return netif; + } + } + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); + return NULL; +} + +/** + * Change the IP address of a network interface + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* TODO: Handling of obsolete pcbs */ + /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + while (pcb != NULL) { + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr)) +#if LWIP_AUTOIP + /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ + && !ip_addr_islinklocal(&(pcb->local_ip)) +#endif /* LWIP_AUTOIP */ + ) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + pcb = next; + } else { + pcb = pcb->next; + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(&(lpcb->local_ip)))) && + (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr)))) { + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(&(lpcb->local_ip), ipaddr); + } + } + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + snmp_insert_ipaddridx_tree(netif); + snmp_insert_iprteidx_tree(0,netif); + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->ip_addr), + ip4_addr2_16(&netif->ip_addr), + ip4_addr3_16(&netif->ip_addr), + ip4_addr4_16(&netif->ip_addr))); +} + +/** + * Change the default gateway for a network interface + * + * @param netif the network interface to change + * @param gw the new default gateway + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, ip_addr_t *gw) +{ + ip_addr_set(&(netif->gw), gw); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->gw), + ip4_addr2_16(&netif->gw), + ip4_addr3_16(&netif->gw), + ip4_addr4_16(&netif->gw))); +} + +/** + * Change the netmask of a network interface + * + * @param netif the network interface to change + * @param netmask the new netmask + * + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, ip_addr_t *netmask) +{ + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + snmp_insert_iprteidx_tree(0, netif); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->netmask), + ip4_addr2_16(&netif->netmask), + ip4_addr3_16(&netif->netmask), + ip4_addr4_16(&netif->netmask))); +} + +/** + * Set a network interface as the default network interface + * (used to output all packets for which no specific route is found) + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + if (netif == NULL) { + /* remove default route */ + snmp_delete_iprteidx_tree(1, netif); + } else { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + +/** + * Bring an interface up, available for processing + * traffic. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_up(struct netif *netif) +{ + if (!(netif->flags & NETIF_FLAG_UP)) { + netif->flags |= NETIF_FLAG_UP; + +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif /* LWIP_SNMP */ + + NETIF_STATUS_CALLBACK(netif); + + if (netif->flags & NETIF_FLAG_LINK_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & (NETIF_FLAG_ETHARP)) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } + } +} + +/** + * Bring an interface down, disabling any traffic processing. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_down(struct netif *netif) +{ + if (netif->flags & NETIF_FLAG_UP) { + netif->flags &= ~NETIF_FLAG_UP; +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif + +#if LWIP_ARP + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_ARP */ + NETIF_STATUS_CALLBACK(netif); + } +} + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Set callback to be called when interface is brought up/down + */ +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) +{ + if (netif) { + netif->status_callback = status_callback; + } +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_REMOVE_CALLBACK +/** + * Set callback to be called when the interface has been removed + */ +void +netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) +{ + if (netif) { + netif->remove_callback = remove_callback; + } +} +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +/** + * Called by a driver when its link goes up + */ +void netif_set_link_up(struct netif *netif ) +{ + if (!(netif->flags & NETIF_FLAG_LINK_UP)) { + netif->flags |= NETIF_FLAG_LINK_UP; + +#if LWIP_DHCP + if (netif->dhcp) { + dhcp_network_changed(netif); + } +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP + if (netif->autoip) { + autoip_network_changed(netif); + } +#endif /* LWIP_AUTOIP */ + + if (netif->flags & NETIF_FLAG_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ + } + NETIF_LINK_CALLBACK(netif); + } +} + +/** + * Called by a driver when its link goes down + */ +void netif_set_link_down(struct netif *netif ) +{ + if (netif->flags & NETIF_FLAG_LINK_UP) { + netif->flags &= ~NETIF_FLAG_LINK_UP; + NETIF_LINK_CALLBACK(netif); + } +} + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) +{ + if (netif) { + netif->link_callback = link_callback; + } +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if ENABLE_LOOPBACK +/** + * Send an IP packet to be received on the same netif (loopif-like). + * The pbuf is simply copied and handed back to netif->input. + * In multithreaded mode, this is done directly since netif->input must put + * the packet on a queue. + * In callback mode, the packet is put on an internal queue and is fed to + * netif->input by netif_poll(). + * + * @param netif the lwip network interface structure + * @param p the (IP) packet to 'send' + * @param ipaddr the ip address to send the packet to (not used) + * @return ERR_OK if the packet has been sent + * ERR_MEM if the pbuf used to copy the packet couldn't be allocated + */ +err_t +netif_loop_output(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr) +{ + struct pbuf *r; + err_t err; + struct pbuf *last; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = 0; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + LWIP_UNUSED_ARG(ipaddr); + + /* Allocate a new pbuf */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } +#if LWIP_LOOPBACK_MAX_PBUFS + clen = pbuf_clen(r); + /* check for overflow or too many pbuf on queue */ + if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || + ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } + netif->loop_cnt_current += clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + + /* Copy the whole pbuf queue p into the single pbuf r */ + if ((err = pbuf_copy(r, p)) != ERR_OK) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return err; + } + + /* Put the packet on a linked list which gets emptied through calling + netif_poll(). */ + + /* let last point to the last pbuf in chain r */ + for (last = r; last->next != NULL; last = last->next); + + SYS_ARCH_PROTECT(lev); + if(netif->loop_first != NULL) { + LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); + netif->loop_last->next = r; + netif->loop_last = last; + } else { + netif->loop_first = r; + netif->loop_last = last; + } + SYS_ARCH_UNPROTECT(lev); + + LINK_STATS_INC(link.xmit); + snmp_add_ifoutoctets(stats_if, p->tot_len); + snmp_inc_ifoutucastpkts(stats_if); + +#if LWIP_NETIF_LOOPBACK_MULTITHREADING + /* For multithreading environment, schedule a call to netif_poll */ + tcpip_callback((tcpip_callback_fn)netif_poll, netif); +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ + + return ERR_OK; +} + +/** + * Call netif_poll() in the main loop of your application. This is to prevent + * reentering non-reentrant functions like tcp_input(). Packets passed to + * netif_loop_output() are put on a list that is passed to netif->input() by + * netif_poll(). + */ +void +netif_poll(struct netif *netif) +{ + struct pbuf *in; + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + + do { + /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ + SYS_ARCH_PROTECT(lev); + in = netif->loop_first; + if (in != NULL) { + struct pbuf *in_end = in; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = pbuf_clen(in); + /* adjust the number of pbufs on queue */ + LWIP_ASSERT("netif->loop_cnt_current underflow", + ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); + netif->loop_cnt_current -= clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + while (in_end->len != in_end->tot_len) { + LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); + in_end = in_end->next; + } + /* 'in_end' now points to the last pbuf from 'in' */ + if (in_end == netif->loop_last) { + /* this was the last pbuf in the list */ + netif->loop_first = netif->loop_last = NULL; + } else { + /* pop the pbuf off the list */ + netif->loop_first = in_end->next; + LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); + } + /* De-queue the pbuf from its successors on the 'loop_' list. */ + in_end->next = NULL; + } + SYS_ARCH_UNPROTECT(lev); + + if (in != NULL) { + LINK_STATS_INC(link.recv); + snmp_add_ifinoctets(stats_if, in->tot_len); + snmp_inc_ifinucastpkts(stats_if); + /* loopback packets are always IP packets! */ + if (ip_input(in, netif) != ERR_OK) { + pbuf_free(in); + } + /* Don't reference the packet any more! */ + in = NULL; + } + /* go on while there is a packet on the list */ + } while (netif->loop_first != NULL); +} + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +/** + * Calls netif_poll() for every netif on the netif_list. + */ +void +netif_poll_all(void) +{ + struct netif *netif = netif_list; + /* loop through netifs */ + while (netif != NULL) { + netif_poll(netif); + /* proceed to next network interface */ + netif = netif->next; + } +} +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/pbuf.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/pbuf.c new file mode 100644 index 0000000..88cff4f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/pbuf.c @@ -0,0 +1,1179 @@ +/** + * @file + * Packet buffer management + * + * Packets are built from the pbuf data structure. It supports dynamic + * memory allocation for packet contents or can reference externally + * managed packet contents both in RAM and ROM. Quick allocation for + * incoming packets is provided through pools with fixed sized pbufs. + * + * A packet may span over multiple pbufs, chained as a singly linked + * list. This is called a "pbuf chain". + * + * Multiple packets may be queued, also using this singly linked list. + * This is called a "packet queue". + * + * So, a packet queue consists of one or more pbuf chains, each of + * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE + * NOT SUPPORTED! Use helper structs to queue multiple packets. + * + * The differences between a pbuf chain and a packet queue are very + * precise but subtle. + * + * The last pbuf of a packet has a ->tot_len field that equals the + * ->len field. It can be found by traversing the list. If the last + * pbuf of a packet has a ->next field other than NULL, more packets + * are on the queue. + * + * Therefore, looping through a pbuf of a single packet, has an + * loop end condition (tot_len == p->len), NOT (next == NULL). + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/stats.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "arch/perf.h" +#if LWIP_TCP && TCP_QUEUE_OOSEQ +#include "lwip/tcp_impl.h" +#endif +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) +/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically + aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ +#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) + +#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_IS_EMPTY() +#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +#if !NO_SYS +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL +#include "lwip/tcpip.h" +#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ + if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ + SYS_ARCH_PROTECT(old_level); \ + pbuf_free_ooseq_pending = 0; \ + SYS_ARCH_UNPROTECT(old_level); \ + } } while(0) +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +#endif /* !NO_SYS */ + +volatile u8_t pbuf_free_ooseq_pending; +#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() + +/** + * Attempt to reclaim some memory from queued out-of-sequence TCP segments + * if we run out of pool pbufs. It's better to give priority to new packets + * if we're running out. + * + * This must be done in the correct thread context therefore this function + * can only be used with NO_SYS=0 and through tcpip_callback. + */ +#if !NO_SYS +static +#endif /* !NO_SYS */ +void +pbuf_free_ooseq(void) +{ + struct tcp_pcb* pcb; + SYS_ARCH_DECL_PROTECT(old_level); + + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 0; + SYS_ARCH_UNPROTECT(old_level); + + for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { + if (NULL != pcb->ooseq) { + /** Free the ooseq pbufs of one PCB only */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + return; + } + } +} + +#if !NO_SYS +/** + * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq(). + */ +static void +pbuf_free_ooseq_callback(void *arg) +{ + LWIP_UNUSED_ARG(arg); + pbuf_free_ooseq(); +} +#endif /* !NO_SYS */ + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); +#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ + u8_t queued; + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + queued = pbuf_free_ooseq_pending; + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); + + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); + } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +} +#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +/** + * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). + * + * The actual memory allocated for the pbuf is determined by the + * layer at which the pbuf is allocated and the requested size + * (from the size parameter). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type this parameter decides how and where the pbuf + * should be allocated as follows: + * + * - PBUF_RAM: buffer memory for pbuf is allocated as one large + * chunk. This includes protocol headers as well. + * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for + * protocol headers. Additional headers must be prepended + * by allocating another pbuf and chain in to the front of + * the ROM pbuf. It is assumed that the memory used is really + * similar to ROM in that it is immutable and will not be + * changed. Memory which is dynamic should generally not + * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. + * - PBUF_REF: no buffer memory is allocated for the pbuf, even for + * protocol headers. It is assumed that the pbuf is only + * being used in a single thread. If the pbuf gets queued, + * then pbuf_take should be called to copy the buffer. + * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from + * the pbuf pool that is allocated during pbuf_init(). + * + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + struct pbuf *p, *q, *r; + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (layer) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + } + + switch (type) { + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + PBUF_POOL_IS_EMPTY(); + return NULL; + } + p->type = type; + p->next = NULL; + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + /* remaining length to be allocated */ + rem_len = length - p->len; + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + if (q == NULL) { + PBUF_POOL_IS_EMPTY(); + /* free chain so far allocated */ + pbuf_free(p); + /* bail out unsuccesfully */ + return NULL; + } + q->type = type; + q->flags = 0; + q->next = NULL; + /* make previous pbuf point to this pbuf */ + r->next = q; + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + /* calculate remaining length to be allocated */ + rem_len -= q->len; + /* remember this pbuf for linkage in next iteration */ + r = q; + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + if (p == NULL) { + return NULL; + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF); + if (p == NULL) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + break; + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + } + /* set reference count */ + p->ref = 1; + /* set flags */ + p->flags = 0; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; +} + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Initialize a custom pbuf (already allocated). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type type of the pbuf (only used to treat the pbuf accordingly, as + * this function allocates no memory) + * @param p pointer to the custom pbuf to initialize (already allocated) + * @param payload_mem pointer to the buffer that is used for payload and headers, + * must be at least big enough to hold 'length' plus the header size, + * may be NULL if set later. + * ATTENTION: The caller is responsible for correct alignment of this buffer! + * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least + * big enough to hold 'length' plus the header size + */ +struct pbuf* +pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, + void *payload_mem, u16_t payload_mem_len) +{ + u16_t offset; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (l) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); + return NULL; + } + + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); + return NULL; + } + + p->pbuf.next = NULL; + if (payload_mem != NULL) { + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); + } else { + p->pbuf.payload = NULL; + } + p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; + p->pbuf.len = p->pbuf.tot_len = length; + p->pbuf.type = type; + p->pbuf.ref = 1; + return &p->pbuf; +} +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +/** + * Shrink a pbuf chain to a desired length. + * + * @param p pbuf to shrink. + * @param new_len desired new length of pbuf chain + * + * Depending on the desired length, the first few pbufs in a chain might + * be skipped and left unchanged. The new last pbuf in the chain will be + * resized, and any remaining pbufs will be freed. + * + * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. + * @note May not be called on a packet queue. + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + /* enlarging not yet supported */ + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + q = p; + /* should this pbuf be kept? */ + while (rem_len > q->len) { + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + /* proceed to next pbuf in chain */ + q = q->next; + LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); + } + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + /* reallocate and adjust the length of the pbuf that will be split */ + q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); + LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + q->tot_len = q->len; + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + /* free remaining pbufs in chain */ + pbuf_free(q->next); + } + /* q is last packet in chain */ + q->next = NULL; + +} + +/** + * Adjusts the payload pointer to hide or reveal headers in the payload. + * + * Adjusts the ->payload pointer so that space for a header + * (dis)appears in the pbuf payload. + * + * The ->payload, ->tot_len and ->len fields are adjusted. + * + * @param p pbuf to change the header size. + * @param header_size_increment Number of bytes to increment header size which + * increases the size of the pbuf. New space is on the front. + * (Using a negative value decreases the header size.) + * If hdr_size_inc is 0, this function does nothing and returns succesful. + * + * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so + * the call will fail. A check is made that the increase in header size does + * not move the payload pointer in front of the start of the buffer. + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) { + return 0; + } + + if (header_size_increment < 0){ + increment_magnitude = -header_size_increment; + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + } else { + increment_magnitude = header_size_increment; +#if 0 + /* Can't assert these as some callers speculatively call + pbuf_header() to see if it's OK. Will return 1 below instead. */ + /* Check that we've got the correct type of pbuf to work with */ + LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", + p->type == PBUF_RAM || p->type == PBUF_POOL); + /* Check that we aren't going to move off the beginning of the pbuf */ + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + /* remember current payload pointer */ + payload = p->payload; + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + /* bail out unsuccesfully */ + return 1; + } + /* pbuf types refering to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccesfully */ + return 1; + } + } else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + } + /* modify pbuf length fields */ + p->len += header_size_increment; + p->tot_len += header_size_increment; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; +} + +/** + * Dereference a pbuf chain or queue and deallocate any no-longer-used + * pbufs at the head of this chain or queue. + * + * Decrements the pbuf reference count. If it reaches zero, the pbuf is + * deallocated. + * + * For a pbuf chain, this is repeated for each pbuf in the chain, + * up to the first pbuf which has a non-zero reference count after + * decrementing. So, when all reference counts are one, the whole + * chain is free'd. + * + * @param p The pbuf (chain) to be dereferenced. + * + * @return the number of pbufs that were de-allocated + * from the head of the chain. + * + * @note MUST NOT be called on a packet queue (Not verified to work yet). + * @note the reference counter of a pbuf equals the number of pointers + * that refer to the pbuf (or into the pbuf). + * + * @internal examples: + * + * Assuming existing chains a->b->c with the following reference + * counts, calling pbuf_free(a) results in: + * + * 1->2->3 becomes ...1->3 + * 3->3->3 becomes 2->3->3 + * 1->1->2 becomes ......1 + * 2->1->1 becomes 1->1->1 + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + u16_t ref; + SYS_ARCH_DECL_PROTECT(old_level); + /* Since decrementing ref cannot be guaranteed to be a single machine operation + * we must protect it. We put the new ref into a local variable to prevent + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + /* remember next pbuf in chain for next iteration */ + q = p->next; + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; +#if LWIP_SUPPORT_CUSTOM_PBUF + /* is this a custom pbuf? */ + if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { + struct pbuf_custom *pc = (struct pbuf_custom*)p; + LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); + pc->custom_free_function(p); + } else +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + { + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + memp_free(MEMP_PBUF_POOL, p); + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + memp_free(MEMP_PBUF, p); + /* type == PBUF_RAM */ + } else { + mem_free(p); + } + } + count++; + /* proceed to next pbuf */ + p = q; + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; +} + +/** + * Count number of pbufs in a chain + * + * @param p first pbuf of chain + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + u8_t len; + + len = 0; + while (p != NULL) { + ++len; + p = p->next; + } + return len; +} + +/** + * Increment the reference count of the pbuf. + * + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Concatenate two pbufs (each may be a pbuf chain) and take over + * the caller's reference of the tail pbuf. + * + * @note The caller MAY NOT reference the tail pbuf afterwards. + * Use pbuf_chain() for that purpose. + * + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +/** + * Chain two pbufs (or pbuf chains) together. + * + * The caller MUST call pbuf_free(t) once it has stopped + * using it. Use pbuf_cat() instead if you no longer use t. + * + * @param h head pbuf (chain) + * @param t tail pbuf (chain) + * @note The pbufs MUST belong to the same packet. + * @note MAY NOT be called on a packet queue. + * + * The ->tot_len fields of all pbufs of the head chain are adjusted. + * The ->next field of the last pbuf of the head chain is adjusted. + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + pbuf_cat(h, t); + /* t is now referenced by h */ + pbuf_ref(t); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + +/** + * Dechains the first pbuf from its succeeding pbufs in the chain. + * + * Makes p->tot_len field equal to p->len. + * @param p pbuf to dechain + * @return remainder of the pbuf chain, or NULL if it was de-allocated. + * @note May not be called on a packet queue. + */ +struct pbuf * +pbuf_dechain(struct pbuf *p) +{ + struct pbuf *q; + u8_t tail_gone = 1; + /* tail */ + q = p->next; + /* pbuf has successor in chain? */ + if (q != NULL) { + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); + /* enforce invariant if assertion is disabled */ + q->tot_len = p->tot_len - p->len; + /* decouple pbuf from remainder */ + p->next = NULL; + /* total length of pbuf p is its own length only */ + p->tot_len = p->len; + /* q is no longer referenced by p, free it */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); + tail_gone = pbuf_free(q); + if (tail_gone > 0) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, + ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); + } + /* return remaining tail or NULL if deallocated */ + } + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); + return ((tail_gone > 0) ? NULL : q); +} + +/** + * + * Create PBUF_RAM copies of pbufs. + * + * Used to queue packets on behalf of the lwIP stack, such as + * ARP based queueing. + * + * @note You MUST explicitly use p = pbuf_take(p); + * + * @note Only one packet is copied, no packet queue! + * + * @param p_to pbuf destination of the copy + * @param p_from pbuf source of the copy + * + * @return ERR_OK if pbuf was copied + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + u16_t offset_to=0, offset_from=0, len; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); + + /* iterate through pbuf chain */ + do + { + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + offset_to += len; + offset_from += len; + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + /* on to next p_from (if any) */ + offset_from = 0; + p_from = p_from->next; + } + if (offset_to == p_to->len) { + /* on to next p_to (if any) */ + offset_to = 0; + p_to = p_to->next; + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!\n", + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; +} + +/** + * Copy (part of) the contents of a packet buffer + * to an application supplied buffer. + * + * @param buf the pbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough). No more + * than buf->tot_len will be copied, irrespective of len + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + + left = 0; + + if((buf == NULL) || (dataptr == NULL)) { + return 0; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + if ((offset != 0) && (offset >= p->len)) { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + if (buf_copy_len > len) + buf_copy_len = len; + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + copied_total += buf_copy_len; + left += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + return copied_total; +} + +/** + * Copy application supplied data into a pbuf. + * This function can only be used to copy the equivalent of buf->tot_len data. + * + * @param buf pbuf to fill with data + * @param dataptr application supplied data buffer + * @param len length of the application supplied data buffer + * + * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough + */ +err_t +pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) +{ + struct pbuf *p; + u16_t buf_copy_len; + u16_t total_copy_len = len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;); + + if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { + return ERR_ARG; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; total_copy_len != 0; p = p->next) { + LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); + buf_copy_len = total_copy_len; + if (buf_copy_len > p->len) { + /* this pbuf cannot hold all remaining data */ + buf_copy_len = p->len; + } + /* copy the necessary parts of the buffer */ + MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len); + total_copy_len -= buf_copy_len; + copied_total += buf_copy_len; + } + LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); + return ERR_OK; +} + +/** + * Creates a single pbuf out of a queue of pbufs. + * + * @remark: Either the source pbuf 'p' is freed by this function or the original + * pbuf 'p' is returned, therefore the caller has to check the result! + * + * @param p the source pbuf + * @param layer pbuf_layer of the new pbuf + * + * @return a new, single pbuf (p->next is NULL) + * or the old pbuf if allocation fails + */ +struct pbuf* +pbuf_coalesce(struct pbuf *p, pbuf_layer layer) +{ + struct pbuf *q; + err_t err; + if (p->next == NULL) { + return p; + } + q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); + if (q == NULL) { + /* @todo: what do we do now? */ + return p; + } + err = pbuf_copy(q, p); + LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); + pbuf_free(p); + return q; +} + +#if LWIP_CHECKSUM_ON_COPY +/** + * Copies data into a single pbuf (*not* into a pbuf queue!) and updates + * the checksum while copying + * + * @param p the pbuf to copy data into + * @param start_offset offset of p->payload where to copy the data to + * @param dataptr data to copy into the pbuf + * @param len length of data to copy into the pbuf + * @param chksum pointer to the checksum which is updated + * @return ERR_OK if successful, another error if the data does not fit + * within the (first) pbuf (no pbuf queues!) + */ +err_t +pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum) +{ + u32_t acc; + u16_t copy_chksum; + char *dst_ptr; + LWIP_ASSERT("p != NULL", p != NULL); + LWIP_ASSERT("dataptr != NULL", dataptr != NULL); + LWIP_ASSERT("chksum != NULL", chksum != NULL); + LWIP_ASSERT("len != 0", len != 0); + + if ((start_offset >= p->len) || (start_offset + len > p->len)) { + return ERR_ARG; + } + + dst_ptr = ((char*)p->payload) + start_offset; + copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); + if ((start_offset & 1) != 0) { + copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); + } + acc = *chksum; + acc += copy_chksum; + *chksum = FOLD_U32T(acc); + return ERR_OK; +} +#endif /* LWIP_CHECKSUM_ON_COPY */ + + /** Get one byte from the specified position in a pbuf + * WARNING: returns zero for offset >= p->tot_len + * + * @param p pbuf to parse + * @param offset offset into p of the byte to return + * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len + */ +u8_t +pbuf_get_at(struct pbuf* p, u16_t offset) +{ + u16_t copy_from = offset; + struct pbuf* q = p; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= copy_from)) { + copy_from -= q->len; + q = q->next; + } + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > copy_from)) { + return ((u8_t*)q->payload)[copy_from]; + } + return 0; +} + +/** Compare pbuf contents at specified offset with memory s2, both of length n + * + * @param p pbuf to compare + * @param offset offset into p at wich to start comparing + * @param s2 buffer to compare + * @param n length of buffer to compare + * @return zero if equal, nonzero otherwise + * (0xffff if p is too short, diffoffset+1 otherwise) + */ +u16_t +pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n) +{ + u16_t start = offset; + struct pbuf* q = p; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= start)) { + start -= q->len; + q = q->next; + } + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > start)) { + u16_t i; + for(i = 0; i < n; i++) { + u8_t a = pbuf_get_at(q, start + i); + u8_t b = ((u8_t*)s2)[i]; + if (a != b) { + return i+1; + } + } + return 0; + } + return 0xffff; +} + +/** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset + * start_offset. + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param mem search for the contents of this buffer + * @param mem_len length of 'mem' + * @param start_offset offset into p at which to start searching + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset) +{ + u16_t i; + u16_t max = p->tot_len - mem_len; + if (p->tot_len >= mem_len + start_offset) { + for(i = start_offset; i <= max; ) { + u16_t plus = pbuf_memcmp(p, i, mem, mem_len); + if (plus == 0) { + return i; + } else { + i += plus; + } + } + } + return 0xFFFF; +} + +/** Find occurrence of substr with length substr_len in pbuf p, start at offset + * start_offset + * WARNING: in contrast to strstr(), this one does not stop at the first \0 in + * the pbuf/source string! + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param substr string to search for in p, maximum length is 0xFFFE + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_strstr(struct pbuf* p, const char* substr) +{ + size_t substr_len; + if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { + return 0xFFFF; + } + substr_len = strlen(substr); + if (substr_len >= 0xFFFF) { + return 0xFFFF; + } + return pbuf_memfind(p, substr, (u16_t)substr_len, 0); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/raw.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/raw.c new file mode 100644 index 0000000..7160c0f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/raw.c @@ -0,0 +1,350 @@ +/** + * @file + * Implementation of raw protocol PCBs for low-level handling of + * different types of protocols besides (or overriding) those + * already available in lwIP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/raw.h" +#include "lwip/stats.h" +#include "arch/perf.h" + +#include + +/** The list of RAW PCBs */ +static struct raw_pcb *raw_pcbs; + +/** + * Determine if in incoming IP packet is covered by a RAW PCB + * and if so, pass it to a user-provided receive callback function. + * + * Given an incoming IP datagram (as a chain of pbufs) this function + * finds a corresponding RAW PCB and calls the corresponding receive + * callback function. + * + * @param p pbuf to be demultiplexed to a RAW PCB. + * @param inp network interface on which the datagram was received. + * @return - 1 if the packet has been eaten by a RAW PCB receive + * callback function. The caller MAY NOT not reference the + * packet any longer, and MAY NOT call pbuf_free(). + * @return - 0 if packet is not eaten (pbuf is still referenced by the + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + + LWIP_UNUSED_ARG(inp); + + iphdr = (struct ip_hdr *)p->payload; + proto = IPH_PROTO(iphdr); + + prev = NULL; + pcb = raw_pcbs; + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + if ((pcb->protocol == proto) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))) { +#if IP_SOF_BROADCAST_RECV + /* broadcast filter? */ + if (ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(¤t_iphdr_dest, inp)) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv != NULL) { + /* the receive callback function did not eat the packet? */ + if (pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()) != 0) { + /* receive function ate the packet */ + p = NULL; + eaten = 1; + if (prev != NULL) { + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + } + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + pcb = pcb->next; + } + return eaten; +} + +/** + * Bind a RAW PCB. + * + * @param pcb RAW PCB to be bound with a local address ipaddr. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified IP address is already bound to by + * another RAW PCB. + * + * @see raw_disconnect() + */ +err_t +raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ip_addr_set(&pcb->local_ip, ipaddr); + return ERR_OK; +} + +/** + * Connect an RAW PCB. This function is required by upper layers + * of lwip. Using the raw api you could use raw_sendto() instead + * + * This will associate the RAW PCB with the remote address. + * + * @param pcb RAW PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * + * @return lwIP error code + * + * @see raw_disconnect() and raw_sendto() + */ +err_t +raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ip_addr_set(&pcb->remote_ip, ipaddr); + return ERR_OK; +} + + +/** + * Set the callback function for received packets that match the + * raw PCB's protocol and binding. + * + * The callback function MUST either + * - eat the packet by calling pbuf_free() and returning non-zero. The + * packet will not be passed to other raw PCBs or other protocol layers. + * - not free the packet, and return zero. The packet will be matched + * against further PCBs and/or forwarded to another protocol layers. + * + * @return non-zero if the packet was free()d, zero if the packet remains + * available for others. + */ +void +raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Send the raw IP packet to the given address. Note that actually you cannot + * modify the IP headers (this is inconsistent with the receive callback where + * you actually get the IP headers), you can only specify the IP payload here. + * It requires some more changes in lwIP. (there will be a raw_send() function + * then.) + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * @param ipaddr the destination address of the IP packet + * + */ +err_t +raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) +{ + err_t err; + struct netif *netif; + ip_addr_t *src_ip; + struct pbuf *q; /* q will be sent down the stack */ + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); + + /* not enough space to add an IP header to first pbuf in given p chain? */ + if (pbuf_header(p, IP_HLEN)) { + /* allocate header in new pbuf */ + q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p */ + pbuf_chain(q, p); + } + /* { first pbuf q points to header pbuf } */ + LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* first pbuf q equals given pbuf */ + q = p; + if(pbuf_header(q, -IP_HLEN)) { + LWIP_ASSERT("Can't restore header we just removed!", 0); + return ERR_MEM; + } + } + + if ((netif = ip_route(ipaddr)) == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_RTE; + } + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* use RAW PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + /* did we chain a header earlier? */ + if (q != p) { + /* free the header */ + pbuf_free(q); + } + return err; +} + +/** + * Send the raw IP packet to the address given by raw_connect() + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * + */ +err_t +raw_send(struct raw_pcb *pcb, struct pbuf *p) +{ + return raw_sendto(pcb, p, &pcb->remote_ip); +} + +/** + * Remove an RAW PCB. + * + * @param pcb RAW PCB to be removed. The PCB is removed from the list of + * RAW PCB's and the data structure is freed from memory. + * + * @see raw_new() + */ +void +raw_remove(struct raw_pcb *pcb) +{ + struct raw_pcb *pcb2; + /* pcb to be removed is first in list? */ + if (raw_pcbs == pcb) { + /* make list start at 2nd pcb */ + raw_pcbs = raw_pcbs->next; + /* pcb not 1st in list */ + } else { + for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in raw_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_RAW_PCB, pcb); +} + +/** + * Create a RAW PCB. + * + * @return The RAW PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) + * + * @see raw_remove() + */ +struct raw_pcb * +raw_new(u8_t proto) +{ + struct raw_pcb *pcb; + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); + + pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); + /* could allocate RAW PCB? */ + if (pcb != NULL) { + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct raw_pcb)); + pcb->protocol = proto; + pcb->ttl = RAW_TTL; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + return pcb; +} + +#endif /* LWIP_RAW */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/stats.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/stats.c new file mode 100644 index 0000000..8ea8249 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/stats.c @@ -0,0 +1,176 @@ +/** + * @file + * Statistics module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/mem.h" + +#include + +struct stats_ lwip_stats; + +void stats_init(void) +{ +#ifdef LWIP_DEBUG +#if MEMP_STATS + const char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + int i; + for (i = 0; i < MEMP_MAX; i++) { + lwip_stats.memp[i].name = memp_names[i]; + } +#endif /* MEMP_STATS */ +#if MEM_STATS + lwip_stats.mem.name = "MEM"; +#endif /* MEM_STATS */ +#endif /* LWIP_DEBUG */ +} + +#if LWIP_STATS_DISPLAY +void +stats_display_proto(struct stats_proto *proto, const char *name) +{ + LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); + LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); + LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); + LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); + LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); + LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); +} + +#if IGMP_STATS +void +stats_display_igmp(struct stats_igmp *igmp) +{ + LWIP_PLATFORM_DIAG(("\nIGMP\n\t")); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); + LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); + LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n", igmp->rx_group)); + LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n", igmp->rx_general)); + LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); + LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); + LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); + LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); +} +#endif /* IGMP_STATS */ + +#if MEM_STATS || MEMP_STATS +void +stats_display_mem(struct stats_mem *mem, const char *name) +{ + LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); + LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); + LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); + LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); + LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); +} + +#if MEMP_STATS +void +stats_display_memp(struct stats_mem *mem, int index) +{ + char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + if(index < MEMP_MAX) { + stats_display_mem(mem, memp_names[index]); + } +} +#endif /* MEMP_STATS */ +#endif /* MEM_STATS || MEMP_STATS */ + +#if SYS_STATS +void +stats_display_sys(struct stats_sys *sys) +{ + LWIP_PLATFORM_DIAG(("\nSYS\n\t")); + LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); + LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); + LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); + LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); + LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max)); + LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err)); + LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); + LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); + LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err)); +} +#endif /* SYS_STATS */ + +void +stats_display(void) +{ + s16_t i; + + LINK_STATS_DISPLAY(); + ETHARP_STATS_DISPLAY(); + IPFRAG_STATS_DISPLAY(); + IP_STATS_DISPLAY(); + IGMP_STATS_DISPLAY(); + ICMP_STATS_DISPLAY(); + UDP_STATS_DISPLAY(); + TCP_STATS_DISPLAY(); + MEM_STATS_DISPLAY(); + for (i = 0; i < MEMP_MAX; i++) { + MEMP_STATS_DISPLAY(i); + } + SYS_STATS_DISPLAY(); +} +#endif /* LWIP_STATS_DISPLAY */ + +#endif /* LWIP_STATS */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/sys.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/sys.c new file mode 100644 index 0000000..f177737 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/sys.c @@ -0,0 +1,68 @@ +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/sys.h" + +/* Most of the functions defined in sys.h must be implemented in the + * architecture-dependent file sys_arch.c */ + +#if !NO_SYS + +#ifndef sys_msleep +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + if (ms > 0) { + sys_sem_t delaysem; + err_t err = sys_sem_new(&delaysem, 0); + if (err == ERR_OK) { + sys_arch_sem_wait(&delaysem, ms); + sys_sem_free(&delaysem); + } + } +} +#endif /* sys_msleep */ + +#endif /* !NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp.c new file mode 100644 index 0000000..8687693 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp.c @@ -0,0 +1,1741 @@ +/** + * @file + * Transmission Control Protocol for IP + * + * This file contains common functions for the TCP implementation, such as functinos + * for manipulating the data structures and the TCP timer functions. TCP functions + * related to input and output is found in tcp_in.c and tcp_out.c respectively. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/snmp.h" +#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" +#include "lwip/debug.h" +#include "lwip/stats.h" + +#include + +#ifndef TCP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define TCP_LOCAL_PORT_RANGE_START 0xc000 +#define TCP_LOCAL_PORT_RANGE_END 0xffff +#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) +#endif + +#if LWIP_TCP_KEEPALIVE +#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) +#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) +#else /* LWIP_TCP_KEEPALIVE */ +#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE +#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT +#endif /* LWIP_TCP_KEEPALIVE */ + +const char * const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; + +/* last local TCP port */ +static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; + +/* Incremented every coarse grained timer shot (typically every 500 ms). */ +u32_t tcp_ticks; +const u8_t tcp_backoff[13] = + { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; + /* Times per slowtmr hits */ +const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; + +/* The TCP PCB lists. */ + +/** List of all TCP PCBs bound but not yet (connected || listening) */ +struct tcp_pcb *tcp_bound_pcbs; +/** List of all TCP PCBs in LISTEN state */ +union tcp_listen_pcbs_t tcp_listen_pcbs; +/** List of all TCP PCBs that are in a state in which + * they accept or send data. */ +struct tcp_pcb *tcp_active_pcbs; +/** List of all TCP PCBs in TIME-WAIT state */ +struct tcp_pcb *tcp_tw_pcbs; + +#define NUM_TCP_PCB_LISTS 4 +#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 +/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ +struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, + &tcp_active_pcbs, &tcp_tw_pcbs}; + +/** Only used for temporary storage. */ +struct tcp_pcb *tcp_tmp_pcb; + +u8_t tcp_active_pcbs_changed; + +/** Timer counter to handle calling slow-timer from tcp_tmr() */ +static u8_t tcp_timer; +static u8_t tcp_timer_ctr; +static u16_t tcp_new_port(void); + +/** + * Initialize this module. + */ +void +tcp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Called periodically to dispatch TCP timers. + */ +void +tcp_tmr(void) +{ + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + + if (++tcp_timer & 1) { + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + } +} + +/** + * Closes the TX side of a connection held by the PCB. + * For tcp_close(), a RST is sent if the application didn't receive all data + * (tcp_recved() not called for all data passed to recv callback). + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it. + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +static err_t +tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) +{ + err_t err; + + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { + if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { + /* Not all data received by application, send RST to tell the remote + side about this. */ + LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); + + /* don't call tcp_abort here: we must not deallocate the pcb since + that might not be expected when calling tcp_close */ + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + if (pcb->state == ESTABLISHED) { + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + } + return ERR_OK; + } + } + + switch (pcb->state) { + case CLOSED: + /* Closing a pcb in the CLOSED state might seem erroneous, + * however, it is in this state once allocated and as yet unused + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + break; + case LISTEN: + err = ERR_OK; + tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + pcb = NULL; + break; + case SYN_SENT: + err = ERR_OK; + TCP_PCB_REMOVE_ACTIVE(pcb); + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + snmp_inc_tcpattemptfails(); + break; + case SYN_RCVD: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + } + break; + case ESTABLISHED: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + } + break; + case CLOSE_WAIT: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + } + break; + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + pcb = NULL; + break; + } + + if (pcb != NULL && err == ERR_OK) { + /* To ensure all data has been sent when tcp_close returns, we have + to make sure tcp_output doesn't fail. + Since we don't really have to ensure all data has been sent when tcp_close + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + /* @todo: When implementing SO_LINGER, this must be changed somehow: + If SOF_LINGER is set, the data should be sent and acked before close returns. + This can only be valid for sequential APIs, not for the raw API. */ + tcp_output(pcb); + } + return err; +} + +/** + * Closes the connection held by the PCB. + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it (unless an error is returned). + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + if (pcb->state != LISTEN) { + /* Set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + } + /* ... and close */ + return tcp_close_shutdown(pcb, 1); +} + +/** + * Causes all or part of a full-duplex connection of this PCB to be shut down. + * This doesn't deallocate the PCB unless shutting down both sides! + * Shutting down both sides is the same as calling tcp_close, so if it succeds, + * the PCB should not be referenced any more. + * + * @param pcb PCB to shutdown + * @param shut_rx shut down receive side if this is != 0 + * @param shut_tx shut down send side if this is != 0 + * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) + * another err_t on error. + */ +err_t +tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) +{ + if (pcb->state == LISTEN) { + return ERR_CONN; + } + if (shut_rx) { + /* shut down the receive side: set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + if (shut_tx) { + /* shutting down the tx AND rx side is the same as closing for the raw API */ + return tcp_close_shutdown(pcb, 1); + } + /* ... and free buffered data */ + if (pcb->refused_data != NULL) { + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + } + if (shut_tx) { + /* This can't happen twice since if it succeeds, the pcb's state is changed. + Only close in these states as the others directly deallocate the PCB */ + switch (pcb->state) { + case SYN_RCVD: + case ESTABLISHED: + case CLOSE_WAIT: + return tcp_close_shutdown(pcb, shut_rx); + default: + /* Not (yet?) connected, cannot shutdown the TX side as that would bring us + into CLOSED state, where the PCB is deallocated. */ + return ERR_CONN; + } + } + return ERR_OK; +} + +/** + * Abandons a connection and optionally sends a RST to the remote + * host. Deletes the local protocol control block. This is done when + * a connection is killed because of shortage of memory. + * + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + u32_t seqno, ackno; +#if LWIP_CALLBACK_API + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + void *errf_arg; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", + pcb->state != LISTEN); + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + seqno = pcb->snd_nxt; + ackno = pcb->rcv_nxt; +#if LWIP_CALLBACK_API + errf = pcb->errf; +#endif /* LWIP_CALLBACK_API */ + errf_arg = pcb->callback_arg; + TCP_PCB_REMOVE_ACTIVE(pcb); + if (pcb->unacked != NULL) { + tcp_segs_free(pcb->unacked); + } + if (pcb->unsent != NULL) { + tcp_segs_free(pcb->unsent); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + tcp_segs_free(pcb->ooseq); + } +#endif /* TCP_QUEUE_OOSEQ */ + if (reset) { + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port); + } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + } +} + +/** + * Aborts the connection by sending a RST (reset) segment to the remote + * host. The pcb is deallocated. This function never fails. + * + * ATTENTION: When calling this from one of the TCP callbacks, make + * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + * or you will risk accessing deallocated memory or memory leaks! + * + * @param pcb the tcp pcb to abort + */ +void +tcp_abort(struct tcp_pcb *pcb) +{ + tcp_abandon(pcb, 1); +} + +/** + * Binds the connection to a local portnumber and IP address. If the + * IP address is not given (i.e., ipaddr == NULL), the IP address of + * the outgoing network interface is used instead. + * + * @param pcb the tcp_pcb to bind (no check is done whether this pcb is + * already bound!) + * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind + * to any local address + * @param port the local port to bind to + * @return ERR_USE if the port is already in use + * ERR_VAL if bind failed because the PCB is not in a valid state + * ERR_OK if bound + */ +err_t +tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + int i; + int max_pcb_list = NUM_TCP_PCB_LISTS; + struct tcp_pcb *cpcb; + + LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); + +#if SO_REUSE + /* Unless the REUSEADDR flag is set, + we have to check the pcbs in TIME-WAIT state, also. + We do not dump TIME_WAIT pcb's; they can still be matched by incoming + packets using both local and remote IP addresses and ports to distinguish. + */ + if (ip_get_option(pcb, SOF_REUSEADDR)) { + max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; + } +#endif /* SO_REUSE */ + + if (port == 0) { + port = tcp_new_port(); + if (port == 0) { + return ERR_BUF; + } + } + + /* Check if the address already is in use (on all lists) */ + for (i = 0; i < max_pcb_list; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { +#if SO_REUSE + /* Omit checking for the same port if both pcbs have REUSEADDR set. + For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in + tcp_connect. */ + if (!ip_get_option(pcb, SOF_REUSEADDR) || + !ip_get_option(cpcb, SOF_REUSEADDR)) +#endif /* SO_REUSE */ + { + if (ip_addr_isany(&(cpcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(cpcb->local_ip), ipaddr)) { + return ERR_USE; + } + } + } + } + } + + if (!ip_addr_isany(ipaddr)) { + pcb->local_ip = *ipaddr; + } + pcb->local_port = port; + TCP_REG(&tcp_bound_pcbs, pcb); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); + return ERR_OK; +} +#if LWIP_CALLBACK_API +/** + * Default accept callback if no accept callback is specified by the user. + */ +static err_t +tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(err); + + return ERR_ABRT; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Set the state of the connection to be LISTEN, which means that it + * is able to accept incoming connections. The protocol control block + * is reallocated in order to consume less memory. Setting the + * connection to LISTEN is an irreversible process. + * + * @param pcb the original tcp_pcb + * @param backlog the incoming connections queue limit + * @return tcp_pcb used for listening, consumes less memory. + * + * @note The original tcp_pcb is freed. This function therefore has to be + * called like this: + * tpcb = tcp_listen(tpcb); + */ +struct tcp_pcb * +tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb_listen *lpcb; + + LWIP_UNUSED_ARG(backlog); + LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); + + /* already listening? */ + if (pcb->state == LISTEN) { + return pcb; + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage + is declared (listen-/connection-pcb), we have to make sure now that + this port is only used once for every local IP. */ + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if (lpcb->local_port == pcb->local_port) { + if (ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) { + /* this address/port is already used */ + return NULL; + } + } + } + } +#endif /* SO_REUSE */ + lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); + if (lpcb == NULL) { + return NULL; + } + lpcb->callback_arg = pcb->callback_arg; + lpcb->local_port = pcb->local_port; + lpcb->state = LISTEN; + lpcb->prio = pcb->prio; + lpcb->so_options = pcb->so_options; + ip_set_option(lpcb, SOF_ACCEPTCONN); + lpcb->ttl = pcb->ttl; + lpcb->tos = pcb->tos; + ip_addr_copy(lpcb->local_ip, pcb->local_ip); + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); +#if LWIP_CALLBACK_API + lpcb->accept = tcp_accept_null; +#endif /* LWIP_CALLBACK_API */ +#if TCP_LISTEN_BACKLOG + lpcb->accepts_pending = 0; + lpcb->backlog = (backlog ? backlog : 1); +#endif /* TCP_LISTEN_BACKLOG */ + TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); + return (struct tcp_pcb *)lpcb; +} + +/** + * Update the state that tracks the available window space to advertise. + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + return new_right_edge - pcb->rcv_ann_right_edge; + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + } else { + /* keep the right edge of window constant */ + u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; + LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); + pcb->rcv_ann_wnd = (u16_t)new_rcv_ann_wnd; + } + return 0; + } +} + +/** + * This function should be called by the application when it has + * processed the data. The purpose is to advertise a larger window + * when the data has been processed. + * + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + int wnd_inflation; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); + LWIP_ASSERT("tcp_recved: len would wrap rcv_wnd\n", + len <= 0xffff - pcb->rcv_wnd ); + + pcb->rcv_wnd += len; + if (pcb->rcv_wnd > TCP_WND) { + pcb->rcv_wnd = TCP_WND; + } + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/4), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + tcp_ack_now(pcb); + tcp_output(pcb); + } + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: recveived %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + +/** + * Allocate a new local TCP port. + * + * @return a new (free) local TCP port number + */ +static u16_t +tcp_new_port(void) +{ + u8_t i; + u16_t n = 0; + struct tcp_pcb *pcb; + +again: + if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { + tcp_port = TCP_LOCAL_PORT_RANGE_START; + } + /* Check all PCB lists. */ + for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { + for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == tcp_port) { + if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + } + return tcp_port; +} + +/** + * Connects to another host. The function given as the "connected" + * argument will be called when the connection has been established. + * + * @param pcb the tcp_pcb used to establish the connection + * @param ipaddr the remote ip address to connect to + * @param port the remote tcp port to connect to + * @param connected callback function to call when connected (or on error) + * @return ERR_VAL if invalid arguments are given + * ERR_OK if connect request has been sent + * other err_t values if connect request couldn't be sent + */ +err_t +tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, + tcp_connected_fn connected) +{ + err_t ret; + u32_t iss; + u16_t old_local_port; + + LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); + if (ipaddr != NULL) { + pcb->remote_ip = *ipaddr; + } else { + return ERR_VAL; + } + pcb->remote_port = port; + + /* check if we have a route to the remote host */ + if (ip_addr_isany(&(pcb->local_ip))) { + /* no local IP address set, yet. */ + struct netif *netif = ip_route(&(pcb->remote_ip)); + if (netif == NULL) { + /* Don't even try to send a SYN packet if we have no route + since that will fail. */ + return ERR_RTE; + } + /* Use the netif's IP address as local address. */ + ip_addr_copy(pcb->local_ip, netif->ip_addr); + } + + old_local_port = pcb->local_port; + if (pcb->local_port == 0) { + pcb->local_port = tcp_new_port(); + if (pcb->local_port == 0) { + return ERR_BUF; + } + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure + now that the 5-tuple is unique. */ + struct tcp_pcb *cpcb; + int i; + /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ + for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if ((cpcb->local_port == pcb->local_port) && + (cpcb->remote_port == port) && + ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) && + ip_addr_cmp(&cpcb->remote_ip, ipaddr)) { + /* linux returns EISCONN here, but ERR_USE should be OK for us */ + return ERR_USE; + } + } + } + } +#endif /* SO_REUSE */ + iss = tcp_next_iss(); + pcb->rcv_nxt = 0; + pcb->snd_nxt = iss; + pcb->lastack = iss - 1; + pcb->snd_lbb = iss - 1; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->snd_wnd = TCP_WND; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, ipaddr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + pcb->cwnd = 1; + pcb->ssthresh = pcb->mss * 10; +#if LWIP_CALLBACK_API + pcb->connected = connected; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(connected); +#endif /* LWIP_CALLBACK_API */ + + /* Send a SYN together with the MSS option. */ + ret = tcp_enqueue_flags(pcb, TCP_SYN); + if (ret == ERR_OK) { + /* SYN segment was enqueued, changed the pcbs state now */ + pcb->state = SYN_SENT; + if (old_local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + TCP_REG_ACTIVE(pcb); + snmp_inc_tcpactiveopens(); + + tcp_output(pcb); + } + return ret; +} + +/** + * Called every 500 ms and implements the retransmission timer and the timer that + * removes PCBs that have been in TIME-WAIT for enough time. It also increments + * various timers such as the inactivity timer in each PCB. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + struct tcp_pcb *pcb, *prev; + u16_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + + ++tcp_ticks; + ++tcp_timer_ctr; + +tcp_slowtmr_start: + /* Steps through all of the active PCBs. */ + prev = NULL; + pcb = tcp_active_pcbs; + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + continue; + } + pcb->last_timer = tcp_timer_ctr; + + pcb_remove = 0; + pcb_reset = 0; + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + pcb->persist_cnt = 0; + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + pcb->persist_backoff++; + } + tcp_zero_window_probe(pcb); + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) { + ++pcb->rtime; + } + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + /* Time for a retransmission. */ + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + pcb->ssthresh = eff_wnd >> 1; + if (pcb->ssthresh < (pcb->mss << 1)) { + pcb->ssthresh = (pcb->mss << 1); + } + pcb->cwnd = pcb->mss; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"U16_F + " ssthresh %"U16_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + } + } + } + + /* Check if KEEPALIVE should be sent */ + if(ip_get_option(pcb, SOF_KEEPALIVE) && + ((pcb->state == ESTABLISHED) || + (pcb->state == FIN_WAIT_1) || //modified by realtek + (pcb->state == CLOSE_WAIT))) { + if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to %"U16_F".%"U16_F".%"U16_F".%"U16_F".\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + ++pcb_remove; + ++pcb_reset; + } + else if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) + / TCP_SLOW_INTERVAL) + { + tcp_keepalive(pcb); + pcb->keep_cnt_sent++; + } + } + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + } + + if (pcb_reset) { + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port); + } + + err_fn = pcb->errf; + err_arg = pcb->callback_arg; + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + + tcp_active_pcbs_changed = 0; + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + } else { + /* get the 'next' element now and work with 'prev' below (in case of abort) */ + prev = pcb; + pcb = pcb->next; + + /* We check if we should poll the connection. */ + ++prev->polltmr; + if (prev->polltmr >= prev->pollinterval) { + prev->polltmr = 0; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; + TCP_EVENT_POLL(prev, err); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + /* if err == ERR_ABRT, 'prev' is already deallocated */ + if (err == ERR_OK) { + tcp_output(prev); + } + } + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + pcb = tcp_tw_pcbs; + while (pcb != NULL) { + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + } + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + } else { + prev = pcb; + pcb = pcb->next; + } + } +} + +/** + * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously + * "refused" by upper layer (application) and sends delayed ACKs. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; + + while(pcb != NULL) { + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + tcp_output(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + next = pcb->next; + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + tcp_active_pcbs_changed = 0; + tcp_process_refused_data(pcb); + if (tcp_active_pcbs_changed) { + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + } + } + pcb = next; + } + } +} + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; + pcb->refused_data = NULL; + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + if (err == ERR_OK) { + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN) { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + } + } else if (err == ERR_ABRT) { + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ + pcb->refused_data = refused_data; + } + return ERR_OK; +} + +/** + * Deallocates a list of TCP segments (tcp_seg structures). + * + * @param seg tcp_seg list of TCP segments to free + */ +void +tcp_segs_free(struct tcp_seg *seg) +{ + while (seg != NULL) { + struct tcp_seg *next = seg->next; + tcp_seg_free(seg); + seg = next; + } +} + +/** + * Frees a TCP segment (tcp_seg structure). + * + * @param seg single tcp_seg to free + */ +void +tcp_seg_free(struct tcp_seg *seg) +{ + if (seg != NULL) { + if (seg->p != NULL) { + pbuf_free(seg->p); +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + } +} + +/** + * Sets the priority of a connection. + * + * @param pcb the tcp_pcb to manipulate + * @param prio new priority + */ +void +tcp_setprio(struct tcp_pcb *pcb, u8_t prio) +{ + pcb->prio = prio; +} + +#if TCP_QUEUE_OOSEQ +/** + * Returns a copy of the given TCP segment. + * The pbuf and data are not copied, only the pointers + * + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + struct tcp_seg *cseg; + + cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); + if (cseg == NULL) { + return NULL; + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + pbuf_ref(cseg->p); + return cseg; +} +#endif /* TCP_QUEUE_OOSEQ */ + +#if LWIP_CALLBACK_API +/** + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } else if (err == ERR_OK) { + return tcp_close(pcb); + } + return ERR_OK; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Kills the oldest active connection that has the same or lower priority than + * 'prio'. + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + u8_t mprio; + + + mprio = TCP_PRIO_MAX; + + /* We kill the oldest active connection that has lower priority than prio. */ + inactivity = 0; + inactive = NULL; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->prio <= prio && + pcb->prio <= mprio && + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + mprio = pcb->prio; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + inactive = NULL; + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Allocate a new tcp_pcb structure. + * + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + struct tcp_pcb *pcb; + u32_t iss; + + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb != NULL) { + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + memset(pcb, 0, sizeof(struct tcp_pcb)); + pcb->prio = prio; + pcb->snd_buf = TCP_SND_BUF; + pcb->snd_queuelen = 0; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->tos = 0; + pcb->ttl = TCP_TTL; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + pcb->sa = 0; + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + pcb->rtime = -1; + pcb->cwnd = 1; + iss = tcp_next_iss(); + pcb->snd_wl2 = iss; + pcb->snd_nxt = iss; + pcb->lastack = iss; + pcb->snd_lbb = iss; + pcb->tmr = tcp_ticks; + pcb->last_timer = tcp_timer_ctr; + + pcb->polltmr = 0; + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + } + return pcb; +} + +/** + * Creates a new TCP protocol control block but doesn't place it on + * any of the TCP PCB lists. + * The pcb is not put on any list until binding using tcp_bind(). + * + * @internal: Maybe there should be a idle TCP PCB list where these + * PCBs are put on. Port reservation using tcp_bind() is implemented but + * allocated pcbs that are not bound can't be killed automatically if wanting + * to allocate a pcb with higher prio (@see tcp_kill_prio()) + * + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_new(void) +{ + return tcp_alloc(TCP_PRIO_NORMAL); +} + +/** + * Used to specify the argument that should be passed callback + * functions. + * + * @param pcb tcp_pcb to set the callback argument + * @param arg void pointer argument to pass to callback functions + */ +void +tcp_arg(struct tcp_pcb *pcb, void *arg) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->callback_arg = arg; +} +#if LWIP_CALLBACK_API + +/** + * Used to specify the function that should be called when a TCP + * connection receives data. + * + * @param pcb tcp_pcb to set the recv callback + * @param recv callback function to call for this pcb when data is received + */ +void +tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) +{ + LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); + pcb->recv = recv; +} + +/** + * Used to specify the function that should be called when TCP data + * has been successfully delivered to the remote host. + * + * @param pcb tcp_pcb to set the sent callback + * @param sent callback function to call for this pcb when data is successfully sent + */ +void +tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) +{ + LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); + pcb->sent = sent; +} + +/** + * Used to specify the function that should be called when a fatal error + * has occured on the connection. + * + * @param pcb tcp_pcb to set the err callback + * @param err callback function to call for this pcb when a fatal error + * has occured on the connection + */ +void +tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) +{ + LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); + pcb->errf = err; +} + +/** + * Used for specifying the function that should be called when a + * LISTENing connection has been connected to another host. + * + * @param pcb tcp_pcb to set the accept callback + * @param accept callback function to call for this pcb when LISTENing + * connection has been connected to another host + */ +void +tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->accept = accept; +} +#endif /* LWIP_CALLBACK_API */ + + +/** + * Used to specify the function that should be called periodically + * from TCP. The interval is specified in terms of the TCP coarse + * timer interval, which is called twice a second. + * + */ +void +tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) +{ + LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); +#if LWIP_CALLBACK_API + pcb->poll = poll; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(poll); +#endif /* LWIP_CALLBACK_API */ + pcb->pollinterval = interval; +} + +/** + * Purges a TCP PCB. Removes any buffered data and frees the buffer memory + * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + if (pcb->state != CLOSED && + pcb->state != TIME_WAIT && + pcb->state != LISTEN) { + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); + +#if TCP_LISTEN_BACKLOG + if (pcb->state == SYN_RCVD) { + /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ + struct tcp_pcb_listen *lpcb; + LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", + tcp_listen_pcbs.listen_pcbs != NULL); + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((lpcb->local_port == pcb->local_port) && + (ip_addr_isany(&lpcb->local_ip) || + ip_addr_cmp(&pcb->local_ip, &lpcb->local_ip))) { + /* port and address of the listen pcb match the timed-out pcb */ + LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", + lpcb->accepts_pending > 0); + lpcb->accepts_pending--; + break; + } + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + if (pcb->unsent != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); + } + if (pcb->unacked != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; +#endif /* TCP_QUEUE_OOSEQ */ + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + + tcp_segs_free(pcb->unsent); + tcp_segs_free(pcb->unacked); + pcb->unacked = pcb->unsent = NULL; +#if TCP_OVERSIZE + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + } +} + +/** + * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. + * + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + pcb->state != LISTEN && + pcb->flags & TF_ACK_DELAY) { + pcb->flags |= TF_ACK_NOW; + tcp_output(pcb); + } + + if (pcb->state != LISTEN) { + LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); + LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + +/** + * Calculates a new initial sequence number for new connections. + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + return iss; +} + +#if TCP_CALCULATE_EFF_SEND_MSS +/** + * Calcluates the effective send mss that can be used for a specific IP address + * by using ip_route to determin the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr) +{ + u16_t mss_s; + struct netif *outif; + + outif = ip_route(addr); + if ((outif != NULL) && (outif->mtu != 0)) { + mss_s = outif->mtu - IP_HLEN - TCP_HLEN; + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_write(), and don't support IP options. + */ + sendmss = LWIP_MIN(sendmss, mss_s); + } + return sendmss; +} +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +const char* +tcp_debug_state_str(enum tcp_state s) +{ + return tcp_state_str[s]; +} + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +/** + * Print a tcp header for debugging purposes. + * + * @param tcphdr pointer to a struct tcp_hdr + */ +void +tcp_debug_print(struct tcp_hdr *tcphdr) +{ + LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(tcphdr->src), ntohs(tcphdr->dest))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", + ntohl(tcphdr->seqno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", + ntohl(tcphdr->ackno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", + TCPH_HDRLEN(tcphdr), + TCPH_FLAGS(tcphdr) >> 5 & 1, + TCPH_FLAGS(tcphdr) >> 4 & 1, + TCPH_FLAGS(tcphdr) >> 3 & 1, + TCPH_FLAGS(tcphdr) >> 2 & 1, + TCPH_FLAGS(tcphdr) >> 1 & 1, + TCPH_FLAGS(tcphdr) & 1, + ntohs(tcphdr->wnd))); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", + ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); +} + +/** + * Print a tcp state for debugging purposes. + * + * @param s enum tcp_state to print + */ +void +tcp_debug_print_state(enum tcp_state s) +{ + LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); +} + +/** + * Print tcp flags for debugging purposes. + * + * @param flags tcp flags, all active flags are printed + */ +void +tcp_debug_print_flags(u8_t flags) +{ + if (flags & TCP_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); + } + if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); + } + if (flags & TCP_RST) { + LWIP_DEBUGF(TCP_DEBUG, ("RST ")); + } + if (flags & TCP_PSH) { + LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); + } + if (flags & TCP_ACK) { + LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); + } + if (flags & TCP_URG) { + LWIP_DEBUGF(TCP_DEBUG, ("URG ")); + } + if (flags & TCP_ECE) { + LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); + } + if (flags & TCP_CWR) { + LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); + } + LWIP_DEBUGF(TCP_DEBUG, ("\n")); +} + +/** + * Print all tcp_pcbs in every list for debugging purposes. + */ +void +tcp_debug_print_pcbs(void) +{ + struct tcp_pcb *pcb; + LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } +} + +/** + * Check state consistency of the tcp_pcb lists. + */ +s16_t +tcp_pcbs_sane(void) +{ + struct tcp_pcb *pcb; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + } + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + } + return 1; +} +#endif /* TCP_DEBUG */ + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_in.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_in.c new file mode 100644 index 0000000..4ec971a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_in.c @@ -0,0 +1,1619 @@ +/** + * @file + * Transmission Control Protocol, incoming traffic + * + * The input processing functions of the TCP layer. + * + * These functions are generally called in the order (ip_input() ->) + * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" + +/* These variables are global to all functions involved in the input + processing of TCP segments. They are set by the tcp_input() + function. */ +static struct tcp_seg inseg; +static struct tcp_hdr *tcphdr; +static struct ip_hdr *iphdr; +static u32_t seqno, ackno; +static u8_t flags; +static u16_t tcplen; + +static u8_t recv_flags; +static struct pbuf *recv_data; + +struct tcp_pcb *tcp_input_pcb; + +/* Forward declarations. */ +static err_t tcp_process(struct tcp_pcb *pcb); +static void tcp_receive(struct tcp_pcb *pcb); +static void tcp_parseopt(struct tcp_pcb *pcb); + +static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); +static err_t tcp_timewait_input(struct tcp_pcb *pcb); + +/** + * The initial input processing of TCP. It verifies the TCP header, demultiplexes + * the segment between the PCBs and passes it on to tcp_process(), which implements + * the TCP finite state machine. This function is called by the IP layer (in + * ip_input()). + * + * @param p received TCP segment to process (p->payload pointing to the IP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + struct tcp_pcb *pcb, *prev; + struct tcp_pcb_listen *lpcb; +#if SO_REUSE + struct tcp_pcb *lpcb_prev = NULL; + struct tcp_pcb_listen *lpcb_any = NULL; +#endif /* SO_REUSE */ + u8_t hdrlen; + err_t err; + + PERF_START; + + TCP_STATS_INC(tcp.recv); + snmp_inc_tcpinsegs(); + + iphdr = (struct ip_hdr *)p->payload; + tcphdr = (struct tcp_hdr *)((u8_t *)p->payload + IPH_HL(iphdr) * 4); + +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* remove header from payload */ + if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) { + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + + /* Don't even process incoming broadcasts/multicasts. */ + if (ip_addr_isbroadcast(¤t_iphdr_dest, inp) || + ip_addr_ismulticast(¤t_iphdr_dest)) { + TCP_STATS_INC(tcp.proterr); + goto dropped; + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len) != 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", + inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_TCP, p->tot_len))); +#if TCP_DEBUG + tcp_debug_print(tcphdr); +#endif /* TCP_DEBUG */ + TCP_STATS_INC(tcp.chkerr); + goto dropped; + } +#endif + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + if(pbuf_header(p, -(hdrlen * 4))){ + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + tcphdr->dest = ntohs(tcphdr->dest); + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + tcphdr->wnd = ntohs(tcphdr->wnd); + + flags = TCPH_FLAGS(tcphdr); + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + prev->next = pcb->next; + pcb->next = tcp_active_pcbs; + tcp_active_pcbs = pcb; + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + } + prev = pcb; + } + + if (pcb == NULL) { + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) && + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) { + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + pbuf_free(p); + return; + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if (lpcb->local_port == tcphdr->dest) { +#if SO_REUSE + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) { + /* found an exact match */ + break; + } else if(ip_addr_isany(&(lpcb->local_ip))) { + /* found an ANY-match */ + lpcb_any = lpcb; + lpcb_prev = prev; + } +#else /* SO_REUSE */ + if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) || + ip_addr_isany(&(lpcb->local_ip))) { + /* found a match */ + break; + } +#endif /* SO_REUSE */ + } + prev = (struct tcp_pcb *)lpcb; + } +#if SO_REUSE + /* first try specific local IP */ + if (lpcb == NULL) { + /* only pass to ANY if no specific local IP has been found */ + lpcb = lpcb_any; + prev = lpcb_prev; + } +#endif /* SO_REUSE */ + if (lpcb != NULL) { + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + pbuf_free(p); + return; + } + } + +#if TCP_INPUT_DEBUG + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + /* The incoming segment belongs to a connection. */ +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + inseg.len = p->tot_len; + inseg.p = p; + inseg.tcphdr = tcphdr; + + recv_data = NULL; + recv_flags = 0; + + if (flags & TCP_PSH) { + p->flags |= PBUF_FLAG_PUSH; + } + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + ((pcb->refused_data != NULL) && (tcplen > 0))) { + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + goto aborted; + } + } + tcp_input_pcb = pcb; + err = tcp_process(pcb); + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + if (recv_flags & TF_RESET) { + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else if (recv_flags & TF_CLOSED) { + /* The connection has been closed and we will deallocate the + PCB. */ + if (!(pcb->flags & TF_RXCLOSED)) { + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); + } + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + err = ERR_OK; + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + TCP_EVENT_SENT(pcb, pcb->acked, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + + if (recv_data != NULL) { + LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); + if (pcb->flags & TF_RXCLOSED) { + /* received data although already closed -> abort (send RST) to + notify the remote host that not all data has been processed */ + pbuf_free(recv_data); + tcp_abort(pcb); + goto aborted; + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + if (err == ERR_ABRT) { + goto aborted; + } + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { + pcb->refused_data = recv_data; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + if (pcb->refused_data != NULL) { + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + } + + tcp_input_pcb = NULL; + /* Try to send something out. */ + tcp_output(pcb); +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + } + } + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ +aborted: + tcp_input_pcb = NULL; + recv_data = NULL; + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + { + pbuf_free(inseg.p); + inseg.p = NULL; + } + } else { + + /* If no matching PCB was found, send a TCP RST (reset) to the + sender. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); + tcp_rst(ackno, seqno + tcplen, + ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); + return; +dropped: + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); +} + +/** + * Called by tcp_input() when a segment arrives for a listening + * connection (from tcp_input()). + * + * @param pcb the tcp_pcb_listen for which a segment arrived + * @return ERR_OK if the segment was processed + * another err_t on error + * + * @note the return value is not (yet?) used in tcp_input() + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + struct tcp_pcb *npcb; + err_t rc; + + if (flags & TCP_RST) { + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + } + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), + ip_current_src_addr(), tcphdr->dest, tcphdr->src); + } else if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); +#if TCP_LISTEN_BACKLOG + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ + ip_addr_copy(npcb->local_ip, current_iphdr_dest); + npcb->local_port = pcb->local_port; + ip_addr_copy(npcb->remote_ip, current_iphdr_src); + npcb->remote_port = tcphdr->src; + npcb->state = SYN_RCVD; + npcb->rcv_nxt = seqno + 1; + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + npcb->snd_wnd = tcphdr->wnd; + npcb->snd_wnd_max = tcphdr->wnd; + npcb->ssthresh = npcb->snd_wnd; + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + npcb->callback_arg = pcb->callback_arg; +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & SOF_INHERITED; + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG_ACTIVE(npcb); + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &(npcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); + if (rc != ERR_OK) { + tcp_abandon(npcb, 0); + return rc; + } + return tcp_output(npcb); + } + return ERR_OK; +} + +/** + * Called by tcp_input() when a segment arrives for a connection in + * TIME_WAIT. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + return ERR_OK; + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + return ERR_OK; + } + } else if (flags & TCP_FIN) { + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + } + + if ((tcplen > 0)) { + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + return tcp_output(pcb); + } + return ERR_OK; +} + +/** + * Implements the TCP state machine. Called by tcp_input. In some + * states tcp_receive() is called to receive data. The tcp_seg + * argument will be freed by the caller (tcp_input()) unless the + * recv_data pointer in the pcb is set. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + struct tcp_seg *rseg; + u8_t acceptable = 0; + err_t err; + + err = ERR_OK; + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + if (ackno == pcb->snd_nxt) { + acceptable = 1; + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + } + } + + if (acceptable) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + pcb->flags &= ~TF_ACK_DELAY; + return ERR_RST; + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + return ERR_OK; + } + + if ((pcb->flags & TF_RXCLOSED) == 0) { + /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ + pcb->tmr = tcp_ticks; + } + pcb->keep_cnt_sent = 0; + + tcp_parseopt(pcb); + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + pcb->snd_buf++; + pcb->rcv_nxt = seqno + 1; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->lastack = ackno; + pcb->snd_wnd = tcphdr->wnd; + pcb->snd_wnd_max = tcphdr->wnd; + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + pcb->state = ESTABLISHED; + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + + pcb->cwnd = ((pcb->cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + pcb->unacked = rseg->next; + tcp_seg_free(rseg); + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else { + pcb->rtime = 0; + pcb->nrtx = 0; + } + + /* Call the user specified function to call when sucessfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + tcp_ack_now(pcb); + } + /* received ACK? possibly a half-open connection */ + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + break; + case SYN_RCVD: + if (flags & TCP_ACK) { + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + u16_t old_cwnd; + pcb->state = ESTABLISHED; + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + if (err != ERR_OK) { + /* If the accept function returns with an error, we abort + * the connection. */ + /* Already aborted? */ + if (err != ERR_ABRT) { + tcp_abort(pcb); + } + return ERR_ABRT; + } + old_cwnd = pcb->cwnd; + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + pcb->acked--; + } + + pcb->cwnd = ((old_cwnd == 1) ? (pcb->mss * 2) : pcb->mss); + + if (recv_flags & TF_GOT_FIN) { + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + } else { + /* incorrect ACK number, send RST */ + tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), ip_current_src_addr(), + tcphdr->dest, tcphdr->src); + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { /* passive close */ + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + break; + case FIN_WAIT_1: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + tcp_ack_now(pcb); + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + case FIN_WAIT_2: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case CLOSING: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case LAST_ACK: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + } + break; + default: + break; + } + return ERR_OK; +} + +#if TCP_QUEUE_OOSEQ +/** + * Insert segment into the list (segments covered with new one will be deleted) + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + /* received segment overlaps all following segments */ + tcp_segs_free(next); + next = NULL; + } + else { + /* delete some following segments + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); + } + old_seg = next; + next = next->next; + tcp_seg_free(old_seg); + } + if (next && + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + pbuf_realloc(cseg->p, cseg->len); + } + } + cseg->next = next; +} +#endif /* TCP_QUEUE_OOSEQ */ + +/** + * Called by tcp_process. Checks if the given segment is an ACK for outstanding + * data, and if so frees the memory of the buffered data. Next, is places the + * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment + * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until + * it has been removed from the buffer. + * + * If the incoming segment constitutes an ACK for a segment that was used for RTT + * estimation, the RTT is estimated here as well. + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + struct tcp_seg *next; +#if TCP_QUEUE_OOSEQ + struct tcp_seg *prev, *cseg; +#endif /* TCP_QUEUE_OOSEQ */ + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + u32_t ooseq_blen; + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); + + if (flags & TCP_ACK) { + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + pcb->snd_wnd = tcphdr->wnd; + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < tcphdr->wnd) { + pcb->snd_wnd_max = tcphdr->wnd; + } + pcb->snd_wl1 = seqno; + pcb->snd_wl2 = ackno; + if (pcb->snd_wnd == 0) { + if (pcb->persist_backoff == 0) { + /* start persist timer */ + pcb->persist_cnt = 0; + pcb->persist_backoff = 1; + } + } else if (pcb->persist_backoff > 0) { + /* stop persist timer */ + pcb->persist_backoff = 0; + } + LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); +#if TCP_WND_DEBUG + } else { + if (pcb->snd_wnd != tcphdr->wnd) { + LWIP_DEBUGF(TCP_WND_DEBUG, + ("tcp_receive: no window update lastack %"U32_F" ackno %" + U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", + pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); + } +#endif /* TCP_WND_DEBUG */ + } + + /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a + * duplicate ack if: + * 1) It doesn't ACK new data + * 2) length of received packet is zero (i.e. no payload) + * 3) the advertised window hasn't changed + * 4) There is outstanding unacknowledged data (retransmission timer running) + * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) + * + * If it passes all five, should process as a dupack: + * a) dupacks < 3: do nothing + * b) dupacks == 3: fast retransmit + * c) dupacks > 3: increase cwnd + * + * If it only passes 1-3, should reset dupack counter (and add to + * stats, which we don't do in lwIP) + * + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + pcb->acked = 0; + /* Clause 2 */ + if (tcplen == 0) { + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + /* Clause 4 */ + if (pcb->rtime >= 0) { + /* Clause 5 */ + if (pcb->lastack == ackno) { + found_dupack = 1; + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { + ++pcb->dupacks; + } + if (pcb->dupacks > 3) { + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + } else if (pcb->dupacks == 3) { + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + } + } + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + pcb->dupacks = 0; + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + pcb->flags &= ~TF_INFR; + pcb->cwnd = pcb->ssthresh; + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + /* Update the send buffer space. Diff between the two can never exceed 64K? */ + pcb->acked = (u16_t)(ackno - pcb->lastack); + + pcb->snd_buf += pcb->acked; + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + pcb->lastack = ackno; + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + if (pcb->cwnd < pcb->ssthresh) { + if ((u16_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"U16_F"\n", pcb->cwnd)); + } else { + u16_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + if (new_cwnd > pcb->cwnd) { + pcb->cwnd = new_cwnd; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"U16_F"\n", pcb->cwnd)); + } + } + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", + ackno, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno): 0, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowlegdes them. */ + while (pcb->unacked != NULL && + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked), ackno)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + pcb->unacked = pcb->unacked->next; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unacked)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else + pcb->rtime = 0; + + pcb->polltmr = 0; + } else { + /* Fix bug bug #21582: out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + } + + /* We go through the ->unsent list to see if any of the segments + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + pcb->unsent = pcb->unsent->next; +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"U16_F" ... ", (u16_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"U16_F" (after freeing unsent)\n", (u16_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + } + /* End of ACK for new data processing. */ + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + pcb->sa += m; + if (m < 0) { + m = -m; + } + m = m - (pcb->sv >> 2); + pcb->sv += m; + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + } + } + + /* If the incoming segment contains data, we must process it + further unless the pcb already received a FIN. + (RFC 793, chapeter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { + /* This code basically does three things: + + +) If the incoming segment contains data that is the next + in-sequence data, this data is passed to the application. This + might involve trimming the first edge of the data. The rcv_nxt + variable and the advertised window are adjusted. + + +) If the incoming segment has data that is above the next + sequence number expected (->rcv_nxt), the segment is placed on + the ->ooseq queue. This is done by finding the appropriate + place in the ->ooseq queue (which is ordered by sequence + number) and trim the segment in both ends if needed. An + immediate ACK is sent to indicate that we received an + out-of-sequence segment. + + +) Finally, we check if the first segment on the ->ooseq queue + now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If + rcv_nxt > ooseq->seqno, we must trim the first edge of the + segment on ->ooseq before we adjust rcv_nxt. The data in the + segments that are now on sequence are chained onto the + incoming segment so that we only need to call the application + once. + */ + + /* First, we check if we must trim the first edge. We have to do + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + /* Trimming the first edge is done by pushing the payload + pointer in the pbuf downwards. This is somewhat tricky since + we do not want to discard the full contents of the pbuf up to + the new starting point of the data since we have to keep the + TCP header which is present in the first pbuf in the chain. + + What is done is really quite a nasty hack: the first pbuf in + the pbuf chain is pointed to by inseg.p. Since we need to be + able to deallocate the whole pbuf, we cannot change this + inseg.p pointer to point to any of the later pbufs in the + chain. Instead, we point the ->payload pointer in the first + pbuf to data in one of the later pbufs. We also set the + inseg.data pointer to point to the right place. This way, the + ->p pointer will still point to the first pbuf, but the + ->p->payload pointer will point to data in another pbuf. + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + p = inseg.p; + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + while (p->len < off) { + off -= p->len; + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + p->len = 0; + p = p->next; + } + if(pbuf_header(p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + } + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + + if (tcplen > pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } +#if TCP_QUEUE_OOSEQ + /* Received in-sequence data, adjust ooseq data if: + - FIN has been received or + - inseq overlaps with ooseq */ + if (pcb->ooseq != NULL) { + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue */ + while (pcb->ooseq != NULL) { + struct tcp_seg *old_ooseq = pcb->ooseq; + pcb->ooseq = pcb->ooseq->next; + tcp_seg_free(old_ooseq); + } + } else { + next = pcb->ooseq; + /* Remove all segments on ooseq that are covered by inseg already. + * FIN is copied from ooseq to inseg if present. */ + while (next && + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg cannot have FIN here (already processed above) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); + tcplen = TCP_TCPLEN(&inseg); + } + prev = next; + next = next->next; + tcp_seg_free(prev); + } + /* Now trim right side of inseg if it overlaps with the first + * segment on ooseq */ + if (next && + TCP_SEQ_GT(seqno + tcplen, + next->tcphdr->seqno)) { + /* inseg cannot have FIN here (already processed above) */ + inseg.len = (u16_t)(next->tcphdr->seqno - seqno); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == next->tcphdr->seqno); + } + pcb->ooseq = next; + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + + tcp_update_rcv_ann_wnd(pcb); + + /* If there is data in the segment, we make preparations to + pass this up to the application. The ->recv_data variable + is used for holding the pbuf that goes to the + application. The code for reassembling out-of-sequence data + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + recv_data = inseg.p; + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + are now in sequence. */ + while (pcb->ooseq != NULL && + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + seqno = pcb->ooseq->tcphdr->seqno; + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + + tcp_update_rcv_ann_wnd(pcb); + + if (cseg->p->tot_len > 0) { + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + if (recv_data) { + pbuf_cat(recv_data, cseg->p); + } else { + recv_data = cseg->p; + } + cseg->p = NULL; + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + pcb->state = CLOSE_WAIT; + } + } + + pcb->ooseq = cseg->next; + tcp_seg_free(cseg); + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + pcb->ooseq = tcp_seg_copy(&inseg); + } else { + /* If the queue is not empty, we walk through the queue and + try to find a place where the sequence number of the + incoming segment is between the sequence numbers of the + previous and the next segment on the ->ooseq queue. That is + the place where we put the incoming segment. If needed, we + trim the second edges of the previous and the incoming + segment so that it will fit into the sequence. + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + for(next = pcb->ooseq; next != NULL; next = next->next) { + if (seqno == next->tcphdr->seqno) { + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (prev != NULL) { + prev->next = cseg; + } else { + pcb->ooseq = cseg; + } + tcp_oos_insert_segment(cseg, next); + } + break; + } else { + /* Either the lenghts are the same or the incoming + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + pcb->ooseq = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + pbuf_realloc(prev->p, prev->len); + } + prev->next = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + if (next->next != NULL) { + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + pbuf_realloc(next->p, next->len); + } + /* check if the remote side overruns our receive window */ + if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; + pbuf_realloc(next->next->p, next->next->len); + tcplen = TCP_TCPLEN(next->next); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } + } + break; + } + } + prev = next; + } + } +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + /* Check that the data on ooseq doesn't exceed one of the limits + and throw away everything above that limit. */ + ooseq_blen = 0; + ooseq_qlen = 0; + prev = NULL; + for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) { + struct pbuf *p = next->p; + ooseq_blen += p->tot_len; + ooseq_qlen += pbuf_clen(p); + if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || + (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { + /* too much ooseq data, dump this and everything after it */ + tcp_segs_free(next); + if (prev == NULL) { + /* first ooseq segment is too much, dump the whole queue */ + pcb->ooseq = NULL; + } else { + /* just dump 'next' and everything after it */ + prev->next = NULL; + } + break; + } + } +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ +#endif /* TCP_QUEUE_OOSEQ */ + } + } else { + /* The incoming segment is not withing the window. */ + tcp_send_empty_ack(pcb); + } + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + tcp_ack_now(pcb); + } + } +} + +/** + * Parses the options contained in the incoming segment. + * + * Called from tcp_listen_input() and tcp_process(). + * Currently, only the MSS option is supported! + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + u16_t c, max_c; + u16_t mss; + u8_t *opts, opt; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + opts = (u8_t *)tcphdr + TCP_HLEN; + + /* Parse the TCP MSS option, if present. */ + if(TCPH_HDRLEN(tcphdr) > 0x5) { + max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + for (c = 0; c < max_c; ) { + opt = opts[c]; + switch (opt) { + case 0x00: + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case 0x01: + /* NOP option. */ + ++c; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + case 0x02: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (opts[c + 1] != 0x04 || c + 0x04 > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (opts[c + 2] << 8) | opts[c + 3]; + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + /* Advance to next option */ + c += 0x04; + break; +#if LWIP_TCP_TIMESTAMPS + case 0x08: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); + if (opts[c + 1] != 0x0A || c + 0x0A > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* TCP timestamp option with valid length */ + tsval = (opts[c+2]) | (opts[c+3] << 8) | + (opts[c+4] << 16) | (opts[c+5] << 24); + if (flags & TCP_SYN) { + pcb->ts_recent = ntohl(tsval); + pcb->flags |= TF_TIMESTAMP; + } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { + pcb->ts_recent = ntohl(tsval); + } + /* Advance to next option */ + c += 0x0A; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + if (opts[c + 1] == 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + /* If the length field is zero, the options are malformed + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + c += opts[c + 1]; + } + } + } +} + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_out.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_out.c new file mode 100644 index 0000000..59db81c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/tcp_out.c @@ -0,0 +1,1489 @@ +/** + * @file + * Transmission Control Protocol, outgoing traffic + * + * The output functions of TCP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#if LWIP_TCP_TIMESTAMPS +#include "lwip/sys.h" +#endif + +#include + +/* Define some copy-macros for checksum-on-copy so that the code looks + nicer by preventing too many ifdef's. */ +#if TCP_CHECKSUM_ON_COPY +#define TCP_DATA_COPY(dst, src, len, seg) do { \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ + len, &seg->chksum, &seg->chksum_swapped); \ + seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); +#else /* TCP_CHECKSUM_ON_COPY*/ +#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) +#endif /* TCP_CHECKSUM_ON_COPY*/ + +/** Define this to 1 for an extra check that the output checksum is valid + * (usefule when the checksum is generated by the application, not the stack) */ +#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 +#endif + +/* Forward declarations.*/ +static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); + +/** Allocate a pbuf and create a tcphdr at p->payload, used for output + * functions other than the default tcp_output -> tcp_output_segment + * (e.g. tcp_send_empty_ack, etc.) + * + * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) + * @param optlen length of header-options + * @param datalen length of tcp data to reserve in pbuf + * @param seqno_be seqno in network byte order (big-endian) + * @return pbuf with p->payload being the tcp_hdr + */ +static struct pbuf * +tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, + u32_t seqno_be /* already in network byte order */) +{ + struct tcp_hdr *tcphdr; + struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + if (p == NULL) { + p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_POOL); + } + + if (p != NULL) { + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= TCP_HLEN + optlen)); + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(pcb->local_port); + tcphdr->dest = htons(pcb->remote_port); + tcphdr->seqno = seqno_be; + tcphdr->ackno = htonl(pcb->rcv_nxt); + TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); + tcphdr->wnd = htons(pcb->rcv_ann_wnd); + tcphdr->chksum = 0; + tcphdr->urgp = 0; + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + } + return p; +} + +/** + * Called by tcp_close() to send a segment including FIN flag but not data. + * + * @param pcb the tcp_pcb over which to send a segment + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_fin(struct tcp_pcb *pcb) +{ + /* first, try to add the fin to the last unsent segment */ + if (pcb->unsent != NULL) { + struct tcp_seg *last_unsent; + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ + TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); + pcb->flags |= TF_FIN; + return ERR_OK; + } + } + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue_flags(pcb, TCP_FIN); +} + +/** + * Create a TCP segment with prefilled header. + * + * Called by tcp_write and tcp_enqueue_flags. + * + * @param pcb Protocol control block for the TCP connection. + * @param p pbuf that is used to hold the TCP header. + * @param flags TCP flags for header. + * @param seqno TCP sequence number of this packet + * @param optflags options to include in TCP header + * @return a new tcp_seg pointing to p, or NULL. + * The TCP header is filled in except ackno and wnd. + * p is freed on failure. + */ +static struct tcp_seg * +tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) +{ + struct tcp_seg *seg; + u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); + + if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); + pbuf_free(p); + return NULL; + } + seg->flags = optflags; + seg->next = NULL; + seg->p = p; + seg->len = p->tot_len - optlen; +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = 0; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = 0; + seg->chksum_swapped = 0; + /* check optflags */ + LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", + (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* build TCP header */ + if (pbuf_header(p, TCP_HLEN)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + tcp_seg_free(seg); + return NULL; + } + seg->tcphdr = (struct tcp_hdr *)seg->p->payload; + seg->tcphdr->src = htons(pcb->local_port); + seg->tcphdr->dest = htons(pcb->remote_port); + seg->tcphdr->seqno = htonl(seqno); + /* ackno is set in tcp_output */ + TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); + /* wnd and chksum are set in tcp_output */ + seg->tcphdr->urgp = 0; + return seg; +} + +/** + * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. + * + * This function is like pbuf_alloc(layer, length, PBUF_RAM) except + * there may be extra bytes available at the end. + * + * @param layer flag to define header size. + * @param length size of the pbuf's payload. + * @param max_length maximum usable size of payload+oversize. + * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. + * @param pcb The TCP connection that willo enqueue the pbuf. + * @param apiflags API flags given to tcp_write. + * @param first_seg true when this pbuf will be used in the first enqueued segment. + * @param + */ +#if TCP_OVERSIZE +static struct pbuf * +tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, + u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, + u8_t first_seg) +{ + struct pbuf *p; + u16_t alloc = length; + +#if LWIP_NETIF_TX_SINGLE_PBUF + LWIP_UNUSED_ARG(max_length); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(apiflags); + LWIP_UNUSED_ARG(first_seg); + /* always create MSS-sized pbufs */ + alloc = max_length; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (length < max_length) { + /* Should we allocate an oversized pbuf, or just the minimum + * length required? If tcp_write is going to be called again + * before this segment is transmitted, we want the oversized + * buffer. If the segment will be transmitted immediately, we can + * save memory by allocating only length. We use a simple + * heuristic based on the following information: + * + * Did the user set TCP_WRITE_FLAG_MORE? + * + * Will the Nagle algorithm defer transmission of this segment? + */ + if ((apiflags & TCP_WRITE_FLAG_MORE) || + (!(pcb->flags & TF_NODELAY) && + (!first_seg || + pcb->unsent != NULL || + pcb->unacked != NULL))) { + alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(length + TCP_OVERSIZE)); + } + } +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(layer, alloc, PBUF_RAM); + if (p == NULL) { + return NULL; + } + LWIP_ASSERT("need unchained pbuf", p->next == NULL); + *oversize = p->len - length; + /* trim p->len to the currently used size */ + p->len = p->tot_len = length; + return p; +} +#else /* TCP_OVERSIZE */ +#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) +#endif /* TCP_OVERSIZE */ + +#if TCP_CHECKSUM_ON_COPY +/** Add a checksum of newly added data to the segment */ +static void +tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, + u8_t *seg_chksum_swapped) +{ + u32_t helper; + /* add chksum to old chksum and fold to u16_t */ + helper = chksum + *seg_chksum; + chksum = FOLD_U32T(helper); + if ((len & 1) != 0) { + *seg_chksum_swapped = 1 - *seg_chksum_swapped; + chksum = SWAP_BYTES_IN_WORD(chksum); + } + *seg_chksum = chksum; +} +#endif /* TCP_CHECKSUM_ON_COPY */ + +/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). + * + * @param pcb the tcp pcb to check for + * @param len length of data to send (checked agains snd_buf) + * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise + */ +static err_t +tcp_write_checks(struct tcp_pcb *pcb, u16_t len) +{ + /* connection is in invalid state for data transmission? */ + if ((pcb->state != ESTABLISHED) && + (pcb->state != CLOSE_WAIT) && + (pcb->state != SYN_SENT) && + (pcb->state != SYN_RCVD)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); + return ERR_CONN; + } else if (len == 0) { + return ERR_OK; + } + + /* fail on too much data */ + if (len > pcb->snd_buf) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", + len, pcb->snd_buf)); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + /* If total number of pbufs on the unsent/unacked queues exceeds the + * configured maximum, return an error */ + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", + pcb->unacked != NULL || pcb->unsent != NULL); + } else { + LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", + pcb->unacked == NULL && pcb->unsent == NULL); + } + return ERR_OK; +} + +/** + * Write data for sending (but does not send it immediately). + * + * It waits in the expectation of more data being sent soon (as + * it can send them more efficiently by combining them together). + * To prompt the system to send data now, call tcp_output() after + * calling tcp_write(). + * + * @param pcb Protocol control block for the TCP connection to enqueue data for. + * @param arg Pointer to the data to be enqueued for sending. + * @param len Data length in bytes + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, + * @return ERR_OK if enqueued, another err_t on error + */ +err_t +tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +{ + struct pbuf *concat_p = NULL; + struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; + u16_t pos = 0; /* position in 'arg' data */ + u16_t queuelen; + u8_t optlen = 0; + u8_t optflags = 0; +#if TCP_OVERSIZE + u16_t oversize = 0; + u16_t oversize_used = 0; +#endif /* TCP_OVERSIZE */ +#if TCP_CHECKSUM_ON_COPY + u16_t concat_chksum = 0; + u8_t concat_chksum_swapped = 0; + u16_t concat_chksummed = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + err_t err; + /* don't allocate segments bigger than half the maximum window we ever received */ + u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2); + +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Always copy to try to create single pbufs for TX */ + apiflags |= TCP_WRITE_FLAG_COPY; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", + (void *)pcb, arg, len, (u16_t)apiflags)); + LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", + arg != NULL, return ERR_ARG;); + + err = tcp_write_checks(pcb, len); + if (err != ERR_OK) { + return err; + } + queuelen = pcb->snd_queuelen; + +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags = TF_SEG_OPTS_TS; + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif /* LWIP_TCP_TIMESTAMPS */ + + + /* + * TCP segmentation is done in three phases with increasing complexity: + * + * 1. Copy data directly into an oversized pbuf. + * 2. Chain a new pbuf to the end of pcb->unsent. + * 3. Create new segments. + * + * We may run out of memory at any point. In that case we must + * return ERR_MEM and not change anything in pcb. Therefore, all + * changes are recorded in local variables and committed at the end + * of the function. Some pcb fields are maintained in local copies: + * + * queuelen = pcb->snd_queuelen + * oversize = pcb->unsent_oversize + * + * These variables are set consistently by the phases: + * + * seg points to the last segment tampered with. + * + * pos records progress as data is segmented. + */ + + /* Find the tail of the unsent queue. */ + if (pcb->unsent != NULL) { + u16_t space; + u16_t unsent_optlen; + + /* @todo: this could be sped up by keeping last_unsent in the pcb */ + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + /* Usable space at the end of the last unsent segment */ + unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); + space = mss_local - (last_unsent->len + unsent_optlen); + + /* + * Phase 1: Copy data directly into an oversized pbuf. + * + * The number of bytes copied is recorded in the oversize_used + * variable. The actual copying is done at the bottom of the + * function. + */ +#if TCP_OVERSIZE +#if TCP_OVERSIZE_DBGCHECK + /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */ + LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", + pcb->unsent_oversize == last_unsent->oversize_left); +#endif /* TCP_OVERSIZE_DBGCHECK */ + oversize = pcb->unsent_oversize; + if (oversize > 0) { + LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space); + seg = last_unsent; + oversize_used = oversize < len ? oversize : len; + pos += oversize_used; + oversize -= oversize_used; + space -= oversize_used; + } + /* now we are either finished or oversize is zero */ + LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len)); +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: Chain a new pbuf to the end of pcb->unsent. + * + * We don't extend segments containing SYN/FIN flags or options + * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at + * the end. + */ + if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { + u16_t seglen = space < len - pos ? space : len - pos; + seg = last_unsent; + + /* Create a pbuf with a copy or reference to seglen bytes. We + * can use PBUF_RAW here since the data appears in the middle of + * a segment. A header will never be prepended. */ + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* Data is copied */ + if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", + seglen)); + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + last_unsent->oversize_left += oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ + TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); +#if TCP_CHECKSUM_ON_COPY + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + } else { + /* Data is not copied */ + if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen, + &concat_chksum, &concat_chksum_swapped); + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + concat_p->payload = (u8_t*)arg + pos; + } + + pos += seglen; + queuelen += pbuf_clen(concat_p); + } + } else { +#if TCP_OVERSIZE + LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", + pcb->unsent_oversize == 0); +#endif /* TCP_OVERSIZE */ + } + + /* + * Phase 3: Create new segments. + * + * The new segments are chained together in the local 'queue' + * variable, ready to be appended to pcb->unsent. + */ + while (pos < len) { + struct pbuf *p; + u16_t left = len - pos; + u16_t max_len = mss_local - optlen; + u16_t seglen = left > max_len ? max_len : left; +#if TCP_CHECKSUM_ON_COPY + u16_t chksum = 0; + u8_t chksum_swapped = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* If copy is set, memory should be allocated and data copied + * into pbuf */ + if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); + goto memerr; + } + LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", + (p->len >= seglen)); + TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped); + } else { + /* Copy is not set: First allocate a pbuf for holding the data. + * Since the referenced data is available at least until it is + * sent out on the link (as it has to be ACKed by the remote + * party) we can safely use PBUF_ROM instead of PBUF_REF here. + */ + struct pbuf *p2; +#if TCP_OVERSIZE + LWIP_ASSERT("oversize == 0", oversize == 0); +#endif /* TCP_OVERSIZE */ + if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + chksum = ~inet_chksum((u8_t*)arg + pos, seglen); +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + p2->payload = (u8_t*)arg + pos; + + /* Second, allocate a pbuf for the headers. */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + /* If allocation fails, we have to deallocate the data pbuf as + * well. */ + pbuf_free(p2); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n")); + goto memerr; + } + /* Concatenate the headers and data pbufs together. */ + pbuf_cat(p/*header*/, p2/*data*/); + } + + queuelen += pbuf_clen(p); + + /* Now that there are more segments queued, we check again if the + * length of the queue exceeds the configured maximum or + * overflows. */ + if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"U16_F" (%"U16_F")\n", queuelen, TCP_SND_QUEUELEN)); + pbuf_free(p); + goto memerr; + } + + if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = chksum; + seg->chksum_swapped = chksum_swapped; + seg->flags |= TF_SEG_DATA_CHECKSUMMED; +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* first segment of to-be-queued data? */ + if (queue == NULL) { + queue = seg; + } else { + /* Attach the segment to the end of the queued segments */ + LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); + prev_seg->next = seg; + } + /* remember last segment of to-be-queued data for next iteration */ + prev_seg = seg; + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); + + pos += seglen; + } + + /* + * All three segmentation phases were successful. We can commit the + * transaction. + */ + + /* + * Phase 1: If data has been added to the preallocated tail of + * last_unsent, we update the length fields of the pbuf chain. + */ +#if TCP_OVERSIZE + if (oversize_used > 0) { + struct pbuf *p; + /* Bump tot_len of whole chain, len of tail */ + for (p = last_unsent->p; p; p = p->next) { + p->tot_len += oversize_used; + if (p->next == NULL) { + TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); + p->len += oversize_used; + } + } + last_unsent->len += oversize_used; +#if TCP_OVERSIZE_DBGCHECK + LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", + last_unsent->oversize_left >= oversize_used); + last_unsent->oversize_left -= oversize_used; +#endif /* TCP_OVERSIZE_DBGCHECK */ + } + pcb->unsent_oversize = oversize; +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: concat_p can be concatenated onto last_unsent->p + */ + if (concat_p != NULL) { + LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", + (last_unsent != NULL)); + pbuf_cat(last_unsent->p, concat_p); + last_unsent->len += concat_p->tot_len; +#if TCP_CHECKSUM_ON_COPY + if (concat_chksummed) { + tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, + &last_unsent->chksum_swapped); + last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; + } +#endif /* TCP_CHECKSUM_ON_COPY */ + } + + /* + * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that + * is harmless + */ + if (last_unsent == NULL) { + pcb->unsent = queue; + } else { + last_unsent->next = queue; + } + + /* + * Finally update the pcb state. + */ + pcb->snd_lbb += len; + pcb->snd_buf -= len; + pcb->snd_queuelen = queuelen; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", + pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + /* Set the PSH flag in the last segment that we enqueued. */ + if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { + TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); + } + + return ERR_OK; +memerr: + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + + if (concat_p != NULL) { + pbuf_free(concat_p); + } + if (queue != NULL) { + tcp_segs_free(queue); + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); + return ERR_MEM; +} + +/** + * Enqueue TCP options for transmission. + * + * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl(). + * + * @param pcb Protocol control block for the TCP connection. + * @param flags TCP header flags to set in the outgoing segment. + * @param optdata pointer to TCP options, or NULL. + * @param optlen length of TCP options in bytes. + */ +err_t +tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +{ + struct pbuf *p; + struct tcp_seg *seg; + u8_t optflags = 0; + u8_t optlen = 0; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", + (flags & (TCP_SYN | TCP_FIN)) != 0); + + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + if (flags & TCP_SYN) { + optflags = TF_SEG_OPTS_MSS; + } +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + optflags |= TF_SEG_OPTS_TS; + } +#endif /* LWIP_TCP_TIMESTAMPS */ + optlen = LWIP_TCP_OPT_LENGTH(optflags); + + /* tcp_enqueue_flags is always called with either SYN or FIN in flags. + * We need one available snd_buf byte to do that. + * This means we can't send FIN while snd_buf==0. A better fix would be to + * not include SYN and FIN sequence numbers in the snd_buf count. */ + if (pcb->snd_buf == 0) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + + /* Allocate pbuf with room for TCP header + options */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", + (p->len >= optlen)); + + /* Allocate memory for tcp_seg, and fill in fields. */ + if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, + ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + /* Now append seg to pcb->unsent queue */ + if (pcb->unsent == NULL) { + pcb->unsent = seg; + } else { + struct tcp_seg *useg; + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + useg->next = seg; + } +#if TCP_OVERSIZE + /* The new unsent tail has no space */ + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + + /* SYN and FIN bump the sequence number */ + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + pcb->snd_lbb++; + /* optlen does not influence snd_buf */ + pcb->snd_buf--; + } + if (flags & TCP_FIN) { + pcb->flags |= TF_FIN; + } + + /* update number of segments on the queues */ + pcb->snd_queuelen += pbuf_clen(seg->p); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + return ERR_OK; +} + +#if LWIP_TCP_TIMESTAMPS +/* Build a timestamp option (12 bytes long) at the specified options pointer) + * + * @param pcb tcp_pcb + * @param opts option pointer where to store the timestamp option + */ +static void +tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) +{ + /* Pad with two NOP options to make everything nicely aligned */ + opts[0] = PP_HTONL(0x0101080A); + opts[1] = htonl(sys_now()); + opts[2] = htonl(pcb->ts_recent); +} +#endif + +/** Send an ACK without data. + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + u8_t optlen = 0; + +#if LWIP_TCP_TIMESTAMPS + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + + p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); + if (p == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + } + tcphdr = (struct tcp_hdr *)p->payload; + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + + /* NB. MSS option is only sent on SYNs, so ignore it here */ +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (pcb->flags & TF_TIMESTAMP) { + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip), + IP_PROTO_TCP, p->tot_len); +#endif +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + + return ERR_OK; +} + +/** + * Find out what we can send and send it + * + * @param pcb Protocol control block for the TCP connection to send data + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg, *useg; + u32_t wnd, snd_nxt; +#if TCP_CWND_DEBUG + s16_t i = 0; +#endif /* TCP_CWND_DEBUG */ + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_output for listen-pcbs", + pcb->state != LISTEN); + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + return ERR_OK; + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + + seg = pcb->unsent; + + /* If the TF_ACK_NOW flag is set and no data will be sent (either + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + return tcp_send_empty_ack(pcb); + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + if (useg != NULL) { + for (; useg->next != NULL; useg = useg->next); + } + +#if TCP_OUTPUT_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", + (void*)pcb->unsent)); + } +#endif /* TCP_OUTPUT_DEBUG */ +#if TCP_CWND_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F + ", cwnd %"U16_F", wnd %"U32_F + ", seg == NULL, ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); + } else { + LWIP_DEBUGF(TCP_CWND_DEBUG, + ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F + ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); + /* Stop sending if the nagle algorithm would prevent it + * Don't stop: + * - if tcp_write had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_write/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + break; + } +#if TCP_CWND_DEBUG + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"U16_F", cwnd %"U16_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) + seg->len - + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + + if (pcb->state != SYN_SENT) { + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + tcp_output_segment(seg, pcb); + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + pcb->snd_nxt = snd_nxt; + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + seg->next = NULL; + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + pcb->unacked = seg; + useg = seg; + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = (*cur_seg); + (*cur_seg) = seg; + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + useg = useg->next; + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + } + seg = pcb->unsent; + } +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + /* last unsent has been removed, reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + pcb->flags &= ~TF_NAGLEMEMERR; + return ERR_OK; +} + +/** + * Called by tcp_output() to actually send a TCP segment over IP. + * + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + u16_t len; + struct netif *netif; + u32_t *opts; + + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + + /* advertise our receive window size in this TCP segment */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(void *)(seg->tcphdr + 1); + if (seg->flags & TF_SEG_OPTS_MSS) { + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->remote_ip); +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); + opts += 1; + } +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (seg->flags & TF_SEG_OPTS_TS) { + tcp_build_timestamp_option(pcb, opts); + opts += 3; + } +#endif + + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + pcb->rtime = 0; + } + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ip_addr_isany(&(pcb->local_ip))) { + netif = ip_route(&(pcb->remote_ip)); + if (netif == NULL) { + return; + } + ip_addr_copy(pcb->local_ip, netif->ip_addr); + } + + if (pcb->rttest == 0) { + pcb->rttest = tcp_ticks; + pcb->rtseq = ntohl(seg->tcphdr->seqno); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + + seg->p->len -= len; + seg->p->tot_len -= len; + + seg->p->payload = seg->tcphdr; + + seg->tcphdr->chksum = 0; +#if CHECKSUM_GEN_TCP +#if TCP_CHECKSUM_ON_COPY + { + u32_t acc; +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + u16_t chksum_slow = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { + LWIP_ASSERT("data included but not checksummed", + seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4)); + } + + /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ + acc = inet_chksum_pseudo_partial(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4); + /* add payload checksum */ + if (seg->chksum_swapped) { + seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); + seg->chksum_swapped = 0; + } + acc += (u16_t)~(seg->chksum); + seg->tcphdr->chksum = FOLD_U32T(acc); +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + if (chksum_slow != seg->tcphdr->chksum) { + LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", + seg->tcphdr->chksum, chksum_slow)); + seg->tcphdr->chksum = chksum_slow; + } +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + } +#else /* TCP_CHECKSUM_ON_COPY */ + seg->tcphdr->chksum = inet_chksum_pseudo(seg->p, &(pcb->local_ip), + &(pcb->remote_ip), + IP_PROTO_TCP, seg->p->tot_len); +#endif /* TCP_CHECKSUM_ON_COPY */ +#endif /* CHECKSUM_GEN_TCP */ + TCP_STATS_INC(tcp.xmit); + +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP, &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(seg->p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + +/** + * Send a TCP RESET packet (empty segment with RST flag set) either to + * abort a connection or to show that there is no matching local connection + * for a received segment. + * + * Called by tcp_abort() (to abort a local connection), tcp_input() (if no + * matching local pcb was found), tcp_listen_input() (if incoming segment + * has ACK flag set) and tcp_process() (received segment in the wrong state) + * + * Since a RST segment is in most cases not sent for an active connection, + * tcp_rst() has a number of arguments that are taken from a tcp_pcb for + * most other segment output functions. + * + * @param seqno the sequence number to use for the outgoing segment + * @param ackno the acknowledge number to use for the outgoing segment + * @param local_ip the local IP address to send the segment from + * @param remote_ip the remote IP address to send the segment to + * @param local_port the local TCP port to send the segment from + * @param remote_port the remote TCP port to send the segment to + */ +void +tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + if (p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(local_port); + tcphdr->dest = htons(remote_port); + tcphdr->seqno = htonl(seqno); + tcphdr->ackno = htonl(ackno); + TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); + tcphdr->wnd = PP_HTONS(TCP_WND); + tcphdr->chksum = 0; + tcphdr->urgp = 0; + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, local_ip, remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + snmp_inc_tcpoutrsts(); + /* Send output with hardcoded TTL since we have no access to the pcb */ + ip_output(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + pbuf_free(p); + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + +/** + * Requeue all unacked segments for retransmission + * + * Called by tcp_slowtmr() for slow retransmission. + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + /* unacked queue is now empty */ + pcb->unacked = NULL; + /* last unsent hasn't changed, no need to reset unsent_oversize */ + + /* increment number of retransmissions */ + ++pcb->nrtx; + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission */ + tcp_output(pcb); +} + +/** + * Requeue the first unacked segment for retransmission + * + * Called by tcp_receive() for fast retramsmit. + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + pcb->unacked = seg->next; + + cur_seg = &(pcb->unsent); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = *cur_seg; + *cur_seg = seg; +#if TCP_OVERSIZE + if (seg->next == NULL) { + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + ++pcb->nrtx; + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + + +/** + * Handle retransmission after three dupacks received + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + /* This is fast retransmit. Retransmit the first unacked segment. */ + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) { + pcb->ssthresh = pcb->snd_wnd / 2; + } else { + pcb->ssthresh = pcb->cwnd / 2; + } + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < 2*pcb->mss) { + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + pcb->flags |= TF_INFR; + } +} + + +/** + * Send keepalive packets to keep a connection active although + * no data is sent over it. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + + +/** + * Send persist timer zero-window probes to keep a connection active + * when a window update is lost. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + struct tcp_seg *seg; + u16_t len; + u8_t is_fin; + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: sending ZERO WINDOW probe to %" + U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip))); + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + + if(seg == NULL) { + seg = pcb->unsent; + } + if(seg == NULL) { + return; + } + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + /* we want to send one seqno: either FIN or data (no options) */ + len = is_fin ? 0 : 1; + + p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + + if (is_fin) { + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + char *d = ((char *)p->payload + TCP_HLEN); + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = inet_chksum_pseudo(p, &pcb->local_ip, &pcb->remote_ip, + IP_PROTO_TCP, p->tot_len); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ip_output_hinted(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, + &(pcb->addr_hint)); +#else /* LWIP_NETIF_HWADDRHINT*/ + ip_output(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/udp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/udp.c new file mode 100644 index 0000000..32c7d38 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/core/udp.c @@ -0,0 +1,1013 @@ +/** + * @file + * User Datagram Protocol module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +/* udp.c + * + * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). + * + */ + +/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! + */ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" +#include "lwip/dhcp.h" + +#include + +#ifndef UDP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define UDP_LOCAL_PORT_RANGE_START 0xc000 +#define UDP_LOCAL_PORT_RANGE_END 0xffff +#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START) +#endif + +/* last local UDP port */ +static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; + +/* The list of UDP PCBs */ +/* exported in udp.h (was static) */ +struct udp_pcb *udp_pcbs; + +/** + * Initialize this module. + */ +void +udp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Allocate a new local UDP port. + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + u16_t n = 0; + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + udp_port = UDP_LOCAL_PORT_RANGE_START; + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == udp_port) { + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + return udp_port; +#if 0 + struct udp_pcb *ipcb = udp_pcbs; + while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { + if (ipcb->local_port == udp_port) { + /* port is already used by another udp_pcb */ + udp_port++; + /* restart scanning all udp pcbs */ + ipcb = udp_pcbs; + } else { + /* go on with next udp pcb */ + ipcb = ipcb->next; + } + } + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + +/** + * Process an incoming UDP datagram. + * + * Given an incoming UDP datagram (as a chain of pbufs) this function + * finds a corresponding UDP PCB and hands over the pbuf to the pcbs + * recv function. If no pcb is found or the datagram is incorrect, the + * pbuf is freed. + * + * @param p pbuf to be demultiplexed to a UDP PCB. + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + struct udp_hdr *udphdr; + struct udp_pcb *pcb, *prev; + struct udp_pcb *uncon_pcb; + struct ip_hdr *iphdr; + u16_t src, dest; + u8_t local_match; + u8_t broadcast; + + PERF_START; + + UDP_STATS_INC(udp.recv); + + iphdr = (struct ip_hdr *)p->payload; + + /* Check minimum length (IP header + UDP header) + * and move payload pointer to UDP header */ + if (p->tot_len < (IPH_HL(iphdr) * 4 + UDP_HLEN) || pbuf_header(p, -(s16_t)(IPH_HL(iphdr) * 4))) { + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + + udphdr = (struct udp_hdr *)p->payload; + + /* is broadcast packet ? */ + broadcast = ip_addr_isbroadcast(¤t_iphdr_dest, inp); + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + dest = ntohs(udphdr->dest); + + udp_debug_print(udphdr); + + /* print the UDP source and destination */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") <-- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1_16(&iphdr->dest), ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), ip4_addr4_16(&iphdr->dest), ntohs(udphdr->dest), + ip4_addr1_16(&iphdr->src), ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), ip4_addr4_16(&iphdr->src), ntohs(udphdr->src))); + +#if LWIP_DHCP + pcb = NULL; + /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by + the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */ + if (dest == DHCP_CLIENT_PORT) { + /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */ + if (src == DHCP_SERVER_PORT) { + if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { + /* accept the packe if + (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! + - inp->dhcp->pcb->remote == ANY or iphdr->src */ + if ((ip_addr_isany(&inp->dhcp->pcb->remote_ip) || + ip_addr_cmp(&(inp->dhcp->pcb->remote_ip), ¤t_iphdr_src))) { + pcb = inp->dhcp->pcb; + } + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + local_match = 0; + uncon_pcb = NULL; + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + local_match = 0; + /* print the PCB local and remote address */ + LWIP_DEBUGF(UDP_DEBUG, + ("pcb (%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F") --- " + "(%"U16_F".%"U16_F".%"U16_F".%"U16_F", %"U16_F")\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), pcb->local_port, + ip4_addr1_16(&pcb->remote_ip), ip4_addr2_16(&pcb->remote_ip), + ip4_addr3_16(&pcb->remote_ip), ip4_addr4_16(&pcb->remote_ip), pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if (pcb->local_port == dest) { + if ( + (!broadcast && ip_addr_isany(&pcb->local_ip)) || + ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest) || +#if LWIP_IGMP + ip_addr_ismulticast(¤t_iphdr_dest) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ip_addr_isany(&pcb->local_ip) || + ip_addr_netcmp(&pcb->local_ip, ip_current_dest_addr(), &inp->netmask)))) { +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + if ((uncon_pcb == NULL) && + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + } + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + (pcb->remote_port == src) && + (ip_addr_isany(&pcb->remote_ip) || + ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src))) { + /* the first fully matching PCB */ + if (prev != NULL) { + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + } + prev = pcb; + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + pcb = uncon_pcb; + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL || ip_addr_cmp(&inp->ip_addr, ¤t_iphdr_dest)) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); +#if LWIP_UDPLITE + if (IPH_PROTO(iphdr) == IP_PROTO_UDPLITE) { + /* Do the UDP Lite checksum */ +#if CHECKSUM_CHECK_UDP + u16_t chklen = ntohs(udphdr->len); + if (chklen < sizeof(struct udp_hdr)) { + if (chklen == 0) { + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet (See RFC 3828 chap. 3.1) */ + chklen = p->tot_len; + } else { + /* At least the UDP-Lite header must be covered by the + checksum! (Again, see RFC 3828 chap. 3.1) */ + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } + if (inet_chksum_pseudo_partial(p, ¤t_iphdr_src, ¤t_iphdr_dest, + IP_PROTO_UDPLITE, p->tot_len, chklen) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP Lite datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } +#endif /* CHECKSUM_CHECK_UDP */ + } else +#endif /* LWIP_UDPLITE */ + { +#if CHECKSUM_CHECK_UDP + if (udphdr->chksum != 0) { + if (inet_chksum_pseudo(p, ip_current_src_addr(), ip_current_dest_addr(), + IP_PROTO_UDP, p->tot_len) != 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + } +#endif /* CHECKSUM_CHECK_UDP */ + } + if(pbuf_header(p, -UDP_HLEN)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + if (pcb != NULL) { + snmp_inc_udpindatagrams(); +#if SO_REUSE && SO_REUSE_RXTOALL + if ((broadcast || ip_addr_ismulticast(¤t_iphdr_dest)) && + ip_get_option(pcb, SOF_REUSEADDR)) { + /* pass broadcast- or multicast packets to all multicast pcbs + if SOF_REUSEADDR is set on the first match */ + struct udp_pcb *mpcb; + u8_t p_header_changed = 0; + for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { + if (mpcb != pcb) { + /* compare PCB local addr+port to UDP destination addr+port */ + if ((mpcb->local_port == dest) && + ((!broadcast && ip_addr_isany(&mpcb->local_ip)) || + ip_addr_cmp(&(mpcb->local_ip), ¤t_iphdr_dest) || +#if LWIP_IGMP + ip_addr_ismulticast(¤t_iphdr_dest) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast))) { +#endif /* IP_SOF_BROADCAST_RECV */ + /* pass a copy of the packet to all local matches */ + if (mpcb->recv != NULL) { + struct pbuf *q; + /* for that, move payload to IP header again */ + if (p_header_changed == 0) { + pbuf_header(p, (s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + p_header_changed = 1; + } + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if (q != NULL) { + err_t err = pbuf_copy(q, p); + if (err == ERR_OK) { + /* move payload to UDP data */ + pbuf_header(q, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); + } + } + } + } + } + } + if (p_header_changed) { + /* and move payload to UDP data again */ + pbuf_header(p, -(s16_t)((IPH_HL(iphdr) * 4) + UDP_HLEN)); + } + } +#endif /* SO_REUSE && SO_REUSE_RXTOALL */ + /* callback */ + if (pcb->recv != NULL) { + /* now the recv function is responsible for freeing p */ + pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + goto end; + } + } else { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && + !ip_addr_ismulticast(¤t_iphdr_dest)) { + /* move payload pointer back to ip header */ + pbuf_header(p, (IPH_HL(iphdr) * 4) + UDP_HLEN); + LWIP_ASSERT("p->payload == iphdr", (p->payload == iphdr)); + icmp_dest_unreach(p, ICMP_DUR_PORT); + } +#endif /* LWIP_ICMP */ + UDP_STATS_INC(udp.proterr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpnoports(); + pbuf_free(p); + } + } else { + pbuf_free(p); + } +end: + PERF_STOP("udp_input"); +} + +/** + * Send data using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * + * The datagram will be sent to the current remote_ip & remote_port + * stored in pcb. If the pcb is not bound to a port, it will + * automatically be bound to a random port. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_MEM. Out of memory. + * - ERR_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. + * + * @see udp_disconnect() udp_sendto() + */ +err_t +udp_send(struct udp_pcb *pcb, struct pbuf *p) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); +} + +#if LWIP_CHECKSUM_ON_COPY +/** Same as udp_send() but with checksum + */ +err_t +udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port, + have_chksum, chksum); +} +#endif /* LWIP_CHECKSUM_ON_COPY */ + +/** + * Send data to a specified address using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * If the PCB already has a remote address association, it will + * be restored after the data is sent. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port) +{ +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); +} + +/** Same as udp_sendto(), but with checksum */ +err_t +udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, u8_t have_chksum, u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY */ + struct netif *netif; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); + + /* find the outgoing network interface for this packet */ +#if LWIP_IGMP + netif = ip_route((ip_addr_ismulticast(dst_ip))?(&(pcb->multicast_ip)):(dst_ip)); +#else + netif = ip_route(dst_ip); +#endif /* LWIP_IGMP */ + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dst_ip), ip4_addr2_16(dst_ip), ip4_addr3_16(dst_ip), ip4_addr4_16(dst_ip))); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); +#else /* LWIP_CHECKSUM_ON_COPY */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); +#endif /* LWIP_CHECKSUM_ON_COPY */ +} + +/** + * Send data to a specified address using UDP. + * The netif used for sending can be specified. + * + * This function exists mainly for DHCP, to be able to send UDP packets + * on a netif that is still down. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * @param netif the netif used for sending. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) +{ +#if LWIP_CHECKSUM_ON_COPY + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); +} + +/** Same as udp_sendto_if(), but with checksum */ +err_t +udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, struct netif *netif, u8_t have_chksum, + u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY */ + struct udp_hdr *udphdr; + ip_addr_t *src_ip; + err_t err; + struct pbuf *q; /* q will be sent down the stack */ + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p (only if p contains data) */ + pbuf_chain(q, p); + } + /* first pbuf q points to header pbuf */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = (struct udp_hdr *)q->payload; + udphdr->src = htons(pcb->local_port); + udphdr->dest = htons(dst_port); + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + + /* Multicast Loop? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(dst_ip) && ((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0)) { + q->flags |= PBUF_FLAG_MCASTLOOP; + } +#endif /* LWIP_IGMP */ + + + /* PCB local address is IP_ANY_ADDR? */ + if (ip_addr_isany(&pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) { + /* local_ip doesn't match, drop the packet */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + return ERR_VAL; + } + /* use UDP PCB local IP address as source address */ + src_ip = &(pcb->local_ip); + } + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); + +#if LWIP_UDPLITE + /* UDP Lite protocol? */ + if (pcb->flags & UDP_FLAGS_UDPLITE) { + u16_t chklen, chklen_hdr; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); + /* set UDP message length in UDP header */ + chklen_hdr = chklen = pcb->chksum_len_tx; + if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { + if (chklen != 0) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); + } + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet. (See RFC 3828 chap. 3.1) + At least the UDP-Lite header must be covered by the + checksum, therefore, if chksum_len has an illegal + value, we generate the checksum over the complete + packet to be safe. */ + chklen_hdr = 0; + chklen = q->tot_len; + } + udphdr->len = htons(chklen_hdr); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + udphdr->chksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, + IP_PROTO_UDPLITE, q->tot_len, +#if !LWIP_CHECKSUM_ON_COPY + chklen); +#else /* !LWIP_CHECKSUM_ON_COPY */ + (have_chksum ? UDP_HLEN : chklen)); + if (have_chksum) { + u32_t acc; + acc = udphdr->chksum + (u16_t)~(chksum); + udphdr->chksum = FOLD_U32T(acc); + } +#endif /* !LWIP_CHECKSUM_ON_COPY */ + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) { + udphdr->chksum = 0xffff; + } +#endif /* CHECKSUM_GEN_UDP */ + /* output to IP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n")); + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + if ((pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + u16_t udpchksum; +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + u32_t acc; + udpchksum = inet_chksum_pseudo_partial(q, src_ip, dst_ip, IP_PROTO_UDP, + q->tot_len, UDP_HLEN); + acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + udpchksum = inet_chksum_pseudo(q, src_ip, dst_ip, IP_PROTO_UDP, q->tot_len); + } + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udpchksum == 0x0000) { + udpchksum = 0xffff; + } + udphdr->chksum = udpchksum; + } +#endif /* CHECKSUM_GEN_UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n")); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ip_output_if(q, src_ip, dst_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + } + /* TODO: must this be increased even if error occured? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + return err; +} + +/** + * Bind an UDP PCB. + * + * @param pcb UDP PCB to be bound with a local address ipaddr and port. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * @param port local UDP port to bind with. Use 0 to automatically bind + * to a random port between UDP_LOCAL_PORT_RANGE_START and + * UDP_LOCAL_PORT_RANGE_END. + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occured. + * - ERR_USE. The specified ipaddr and port are already bound to by + * another UDP PCB. + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + u8_t rebind; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ip_addr_debug_print(UDP_DEBUG, ipaddr); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + } + + /* By default, we don't allow to bind to a port that any other udp + PCB is alread bound to, unless *all* PCBs with that port have tha + REUSEADDR flag set. */ +#if SO_REUSE + else if (!ip_get_option(pcb, SOF_REUSEADDR) && + !ip_get_option(ipcb, SOF_REUSEADDR)) { +#else /* SO_REUSE */ + /* port matches that of PCB in list and REUSEADDR not set -> reject */ + else { +#endif /* SO_REUSE */ + if ((ipcb->local_port == port) && + /* IP address matches, or one is IP_ADDR_ANY? */ + (ip_addr_isany(&(ipcb->local_ip)) || + ip_addr_isany(ipaddr) || + ip_addr_cmp(&(ipcb->local_ip), ipaddr))) { + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + } + } + } + + ip_addr_set(&pcb->local_ip, ipaddr); + + /* no port specified? */ + if (port == 0) { + port = udp_new_port(); + if (port == 0) { + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + } + } + pcb->local_port = port; + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_bind: bound to %"U16_F".%"U16_F".%"U16_F".%"U16_F", port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + return ERR_OK; +} +/** + * Connect an UDP PCB. + * + * This will associate the UDP PCB with the remote address. + * + * @param pcb UDP PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * @param port remote UDP port to connect with. + * + * @return lwIP error code + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * The udp pcb is bound to a random local port if not already bound. + * + * @see udp_disconnect() + */ +err_t +udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + + if (pcb->local_port == 0) { + err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); + if (err != ERR_OK) { + return err; + } + } + + ip_addr_set(&pcb->remote_ip, ipaddr); + pcb->remote_port = port; + pcb->flags |= UDP_FLAGS_CONNECTED; +/** TODO: this functionality belongs in upper layers */ +#ifdef LWIP_UDP_TODO + /* Nail down local IP for netconn_addr()/getsockname() */ + if (ip_addr_isany(&pcb->local_ip) && !ip_addr_isany(&pcb->remote_ip)) { + struct netif *netif; + + if ((netif = ip_route(&(pcb->remote_ip))) == NULL) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", pcb->remote_ip.addr)); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } + /** TODO: this will bind the udp pcb locally, to the interface which + is used to route output packets to the remote address. However, we + might want to accept incoming packets on any interface! */ + pcb->local_ip = netif->ip_addr; + } else if (ip_addr_isany(&pcb->remote_ip)) { + pcb->local_ip.addr = 0; + } +#endif + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("udp_connect: connected to %"U16_F".%"U16_F".%"U16_F".%"U16_F",port %"U16_F"\n", + ip4_addr1_16(&pcb->local_ip), ip4_addr2_16(&pcb->local_ip), + ip4_addr3_16(&pcb->local_ip), ip4_addr4_16(&pcb->local_ip), + pcb->local_port)); + + /* Insert UDP PCB into the list of active UDP PCBs. */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + if (pcb == ipcb) { + /* already on the list, just return */ + return ERR_OK; + } + } + /* PCB not yet on the list, add PCB now */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + return ERR_OK; +} + +/** + * Disconnect a UDP PCB + * + * @param pcb the udp pcb to disconnect. + */ +void +udp_disconnect(struct udp_pcb *pcb) +{ + /* reset remote address association */ + ip_addr_set_any(&pcb->remote_ip); + pcb->remote_port = 0; + /* mark PCB as unconnected */ + pcb->flags &= ~UDP_FLAGS_CONNECTED; +} + +/** + * Set a receive callback for a UDP PCB + * + * This callback will be called when receiving a datagram for the pcb. + * + * @param pcb the pcb for wich to set the recv callback + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Remove an UDP PCB. + * + * @param pcb UDP PCB to be removed. The PCB is removed from the list of + * UDP PCB's and the data structure is freed from memory. + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + /* pcb not 1st in list */ + } else { + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_UDP_PCB, pcb); +} + +/** + * Create a UDP PCB. + * + * @return The UDP PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + struct udp_pcb *pcb; + pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); + /* could allocate UDP PCB? */ + if (pcb != NULL) { + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + pcb->ttl = UDP_TTL; + } + return pcb; +} + +#if UDP_DEBUG +/** + * Print UDP header information for debug purposes. + * + * @param udphdr pointer to the udp header in memory. + */ +void +udp_debug_print(struct udp_hdr *udphdr) +{ + LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(udphdr->src), ntohs(udphdr->dest))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", + ntohs(udphdr->len), ntohs(udphdr->chksum))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* UDP_DEBUG */ + +#endif /* LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/autoip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/autoip.h new file mode 100644 index 0000000..e62b72e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/autoip.h @@ -0,0 +1,118 @@ +/** + * @file + * + * AutoIP Automatic LinkLocal IP Configuration + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +#ifndef __LWIP_AUTOIP_H__ +#define __LWIP_AUTOIP_H__ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* AutoIP Timing */ +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 + +struct autoip +{ + ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ + u8_t state; /* current AutoIP state machine state */ + u8_t sent_num; /* sent number of probes or announces, dependent on state */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ + u8_t lastconflict; /* ticks until a conflict can be solved by defending */ + u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ +}; + + +#define autoip_init() /* Compatibility define, no init needed. */ + +/** Set a struct autoip allocated by the application to work with */ +void autoip_set_struct(struct netif *netif, struct autoip *autoip); + +/** Start AutoIP client */ +err_t autoip_start(struct netif *netif); + +/** Stop AutoIP client */ +err_t autoip_stop(struct netif *netif); + +/** Handles every incoming ARP Packet, called by etharp_arp_input */ +void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); + +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); + +/** Handle a possible change in the network configuration */ +void autoip_network_changed(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_AUTOIP */ + +#endif /* __LWIP_AUTOIP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/icmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/icmp.h new file mode 100644 index 0000000..d47a7d8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/icmp.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is splitted to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FIELD(u8_t type); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) + +/** Combines type and code to an u16_t */ +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +void icmp_input(struct pbuf *p, struct netif *inp); +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +#endif /* LWIP_ICMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ICMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/igmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/igmp.h new file mode 100644 index 0000000..8aabac2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/igmp.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +#ifndef __LWIP_IGMP_H__ +#define __LWIP_IGMP_H__ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* IGMP timer */ +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + +/* MAC Filter Actions, these are passed to a netif's + * igmp_mac_filter callback function. */ +#define IGMP_DEL_MAC_FILTER 0 +#define IGMP_ADD_MAC_FILTER 1 + + +/** + * igmp group structure - there is + * a list of groups for each interface + * these should really be linked from the interface, but + * if we keep them separate we will not affect the lwip original code + * too much + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ +struct igmp_group { + /** next link */ + struct igmp_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting, negative is OFF */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/* Prototypes */ +void igmp_init(void); +err_t igmp_start(struct netif *netif); +err_t igmp_stop(struct netif *netif); +void igmp_report_groups(struct netif *netif); +struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); +void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); +err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +void igmp_tmr(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IGMP */ + +#endif /* __LWIP_IGMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet.h new file mode 100644 index 0000000..7bff49b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** For compatibility with BSD code */ +struct in_addr { + u32_t s_addr; +}; + +/** 255.255.255.255 */ +#define INADDR_NONE IPADDR_NONE +/** 127.0.0.1 */ +#define INADDR_LOOPBACK IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define INADDR_ANY IPADDR_ANY +/** 255.255.255.255 */ +#define INADDR_BROADCAST IPADDR_BROADCAST + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IN_CLASSA(a) IP_CLASSA(a) +#define IN_CLASSA_NET IP_CLASSA_NET +#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT +#define IN_CLASSA_HOST IP_CLASSA_HOST +#define IN_CLASSA_MAX IP_CLASSA_MAX + +#define IN_CLASSB(b) IP_CLASSB(b) +#define IN_CLASSB_NET IP_CLASSB_NET +#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT +#define IN_CLASSB_HOST IP_CLASSB_HOST +#define IN_CLASSB_MAX IP_CLASSB_MAX + +#define IN_CLASSC(c) IP_CLASSC(c) +#define IN_CLASSC_NET IP_CLASSC_NET +#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT +#define IN_CLASSC_HOST IP_CLASSC_HOST +#define IN_CLASSC_MAX IP_CLASSC_MAX + +#define IN_CLASSD(d) IP_CLASSD(d) +#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ +#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ +#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ +#define IN_CLASSD_MAX IP_CLASSD_MAX + +#define IN_MULTICAST(a) IP_MULTICAST(a) + +#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) +#define IN_BADCLASS(a) IP_BADCLASS(a) + +#define IN_LOOPBACKNET IP_LOOPBACKNET + +#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) +#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ +#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) ipaddr_addr(cp) +#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) +#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) +#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet_chksum.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet_chksum.h new file mode 100644 index 0000000..79a2d90 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/inet_chksum.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_CHKSUM_H__ +#define __LWIP_INET_CHKSUM_H__ + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +/** Swap the bytes in an u16_t: much like htons() for little-endian */ +#ifndef SWAP_BYTES_IN_WORD +#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) +/* little endian and PLATFORM_BYTESWAP defined */ +#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) +#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ +/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ +#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) +#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ +#endif /* SWAP_BYTES_IN_WORD */ + +/** Split an u32_t in two u16_ts and add them up */ +#ifndef FOLD_U32T +#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) +#endif + +#if LWIP_CHECKSUM_ON_COPY +/** Function-like macro: same as MEMCPY but returns the checksum of copied data + as u16_t */ +#ifndef LWIP_CHKSUM_COPY +#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) +#ifndef LWIP_CHKSUM_COPY_ALGORITHM +#define LWIP_CHKSUM_COPY_ALGORITHM 1 +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ +#endif /* LWIP_CHKSUM_COPY */ +#else /* LWIP_CHECKSUM_ON_COPY */ +#define LWIP_CHKSUM_COPY_ALGORITHM 0 +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *dataptr, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len); +u16_t inet_chksum_pseudo_partial(struct pbuf *p, + ip_addr_t *src, ip_addr_t *dest, + u8_t proto, u16_t proto_len, u16_t chksum_len); +#if LWIP_CHKSUM_COPY_ALGORITHM +u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip.h new file mode 100644 index 0000000..00c83a0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip.h @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the function ip_output_if_opt() is only used with IGMP */ +#define IP_OPTIONS_SEND LWIP_IGMP + +#define IP_HLEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_IGMP 2 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + /* ip addresses in network byte order */ \ + ip_addr_t local_ip; \ + ip_addr_t remote_ip; \ + /* Socket options */ \ + u8_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX. + */ +/*#define SOF_DEBUG 0x01U Unimplemented: turn on debugging info recording */ +#define SOF_ACCEPTCONN 0x02U /* socket has had listen() */ +#define SOF_REUSEADDR 0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE 0x08U /* keep connections alive */ +/*#define SOF_DONTROUTE 0x10U Unimplemented: just use interface addresses */ +#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +/*#define SOF_USELOOPBACK 0x40U Unimplemented: bypass hardware when possible */ +#define SOF_LINGER 0x80U /* linger on close if data present */ +/*#define SOF_OOBINLINE 0x0100U Unimplemented: leave received OOB data in line */ +/*#define SOF_REUSEPORT 0x0200U Unimplemented: allow local address & port reuse */ + +/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ +#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/) + + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_hdr { + /* version / header length */ + PACK_STRUCT_FIELD(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FIELD(u8_t _tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* dont fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ + /* time to live */ + PACK_STRUCT_FIELD(u8_t _ttl); + /* protocol*/ + PACK_STRUCT_FIELD(u8_t _proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FIELD(ip_addr_p_t src); + PACK_STRUCT_FIELD(ip_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) ((hdr)->_ttl) +#define IPH_PROTO(hdr) ((hdr)->_proto) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + +/** The interface that provided the packet for the current callback invocation. */ +extern struct netif *current_netif; +/** Header of the input packet currently being processed. */ +extern const struct ip_hdr *current_header; +/** Source IP address of current_header */ +extern ip_addr_t current_iphdr_src; +/** Destination IP address of current_header */ +extern ip_addr_t current_iphdr_dest; + +#define ip_init() /* Compatibility define, not init needed. */ +struct netif *ip_route(ip_addr_t *dest); +err_t ip_input(struct pbuf *p, struct netif *inp); +err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, + struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if IP_OPTIONS_SEND +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +#endif /* IP_OPTIONS_SEND */ +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (current_netif) +/** Get the IP header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_header() (current_header) +/** Source IP address of current_header */ +#define ip_current_src_addr() (¤t_iphdr_src) +/** Destination IP address of current_header */ +#define ip_current_dest_addr() (¤t_iphdr_dest) + +/** Gets an IP pcb option (SOF_* flags) */ +#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) +/** Sets an IP pcb option (SOF_* flags) */ +#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) +/** Resets an IP pcb option (SOF_* flags) */ +#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#else +#define ip_debug_print(p) +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_addr.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_addr.h new file mode 100644 index 0000000..77f84e0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_addr.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +struct ip_addr { + u32_t addr; +}; + +/* This is the packed version of ip_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr_packed { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip_addr_t as well as on ip_addr_p_t. */ +typedef struct ip_addr ip_addr_t; +typedef struct ip_addr_packed ip_addr_p_t; + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Forward declaration to not include netif.h */ +struct netif; + +extern const ip_addr_t ip_addr_any; +extern const ip_addr_t ip_addr_broadcast; + +/** IP_ADDR_ can be used as a fixed IP address + * for the wildcard and the broadcast address + */ +#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) +#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) + +/** 255.255.255.255 */ +#define IPADDR_NONE ((u32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define IPADDR_ANY ((u32_t)0x00000000UL) +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) +#define IP_CLASSA_NET 0xff000000 +#define IP_CLASSA_NSHIFT 24 +#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) +#define IP_CLASSA_MAX 128 + +#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) +#define IP_CLASSB_NET 0xffff0000 +#define IP_CLASSB_NSHIFT 16 +#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) +#define IP_CLASSB_MAX 65536 + +#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) +#define IP_CLASSC_NET 0xffffff00 +#define IP_CLASSC_NSHIFT 8 +#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) + +#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) +#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IP_MULTICAST(a) IP_CLASSD(a) + +#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) +#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) + +#define IP_LOOPBACKNET 127 /* official! */ + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IP address given by the four byte-parts */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IP address given by the four byte-parts. + Little-endian version that prevents the use of htonl. */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** MEMCPY-like copying of IP addresses where addresses are known to be + * 16-bit-aligned if the port is correctly configured (so a port could define + * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ +#ifndef IPADDR2_COPY +#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) +#endif + +/** Copy IP address - faster than ip_addr_set: no NULL check */ +#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) +/** Safely copy one IP address to another (src may be NULL) */ +#define ip_addr_set(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + (src)->addr)) +/** Set complete address to zero */ +#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) +/** Set address to IPADDR_ANY (no need for htonl()) */ +#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) +/** Set address to loopback address */ +#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) +/** Safely copy one IP address to another and change byte order + * from host- to network-order. */ +#define ip_addr_set_hton(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0:\ + htonl((src)->addr))) +/** IPv4 only: set the IP address given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) +/** IPv4 only: get the IP address as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +/** Get the network address by combining host address with netmask */ +#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) + +/** + * Determine if two address are on the same network. + * + * @arg addr1 IP address 1 + * @arg addr2 IP address 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) +#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) + +#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) + +#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) +u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); + +#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) +u8_t ip4_addr_netmask_valid(u32_t netmask); + +#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) + +#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \ + ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) + +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +/** For backwards compatibility */ +#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) + +u32_t ipaddr_addr(const char *cp); +int ipaddr_aton(const char *cp, ip_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ipaddr_ntoa(const ip_addr_t *addr); +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_frag.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_frag.h new file mode 100644 index 0000000..77b5eb1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv4/lwip/ip_frag.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * + */ + +#ifndef __LWIP_IP_FRAG_H__ +#define __LWIP_IP_FRAG_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_REASSEMBLY +/* The IP reassembly timer interval in milliseconds. */ +#define IP_TMR_INTERVAL 1000 + +/* IP reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip_reassdata { + struct ip_reassdata *next; + struct pbuf *p; + struct ip_hdr iphdr; + u16_t datagram_len; + u8_t flags; + u8_t timer; +}; + +void ip_reass_init(void); +void ip_reass_tmr(void); +struct pbuf * ip_reass(struct pbuf *p); +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); +#endif /* IP_FRAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_FRAG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/icmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/icmp.h new file mode 100644 index 0000000..87e9ffd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/icmp.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ICMP_H__ +#define __LWIP_ICMP_H__ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP6_DUR 1 +#define ICMP6_TE 3 +#define ICMP6_ECHO 128 /* echo */ +#define ICMP6_ER 129 /* echo reply */ + + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +void icmp_input(struct pbuf *p, struct netif *inp); + +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +struct icmp_echo_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u16_t id; + u16_t seqno; +}; + +struct icmp_dur_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +struct icmp_te_hdr { + u8_t type; + u8_t icode; + u16_t chksum; + u32_t unused; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ICMP */ + +#endif /* __LWIP_ICMP_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/inet.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/inet.h new file mode 100644 index 0000000..de1a0b6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/inet.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INET_H__ +#define __LWIP_INET_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *data, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, + struct ip_addr *src, struct ip_addr *dest, + u8_t proto, u32_t proto_len); + +u32_t inet_addr(const char *cp); +s8_t inet_aton(const char *cp, struct in_addr *addr); + +#ifndef _MACHINE_ENDIAN_H_ +#ifndef _NETINET_IN_H +#ifndef _LINUX_BYTEORDER_GENERIC_H +u16_t htons(u16_t n); +u16_t ntohs(u16_t n); +u32_t htonl(u32_t n); +u32_t ntohl(u32_t n); +#endif /* _LINUX_BYTEORDER_GENERIC_H */ +#endif /* _NETINET_IN_H */ +#endif /* _MACHINE_ENDIAN_H_ */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INET_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip.h new file mode 100644 index 0000000..a01cfc6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_H__ +#define __LWIP_IP_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_HLEN 40 + +#define IP_PROTO_ICMP 58 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB struct ip_addr local_ip; \ + struct ip_addr remote_ip; \ + /* Socket options */ \ + u16_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl; \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + + +/* The IPv6 header. */ +struct ip_hdr { +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t tclass1:4, v:4; + u8_t flow1:4, tclass2:4; +#else + u8_t v:4, tclass1:4; + u8_t tclass2:8, flow1:4; +#endif + u16_t flow2; + u16_t len; /* payload length */ + u8_t nexthdr; /* next header */ + u8_t hoplim; /* hop limit (TTL) */ + struct ip_addr src, dest; /* source and destination IP addresses */ +}; + +#define IPH_PROTO(hdr) (iphdr->nexthdr) + +void ip_init(void); + +#include "lwip/netif.h" + +struct netif *ip_route(struct ip_addr *dest); + +void ip_input(struct pbuf *p, struct netif *inp); + +/* source and destination addresses in network byte order, please */ +err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto); + +err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, + u8_t ttl, u8_t proto, + struct netif *netif); + +#define ip_current_netif() NULL +#define ip_current_header() NULL + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_H__ */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip_addr.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip_addr.h new file mode 100644 index 0000000..b2d8ae5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/ipv6/lwip/ip_addr.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_IP_ADDR_H__ +#define __LWIP_IP_ADDR_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP_ADDR_ANY 0 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN + struct ip_addr { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \ + (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \ + (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \ + (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0) + +u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2, + struct ip_addr *mask); +u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2); +void ip_addr_set(struct ip_addr *dest, struct ip_addr *src); +u8_t ip_addr_isany(struct ip_addr *addr); + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \ + (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[0]) & 0xffff, \ + (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[1]) & 0xffff, \ + (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[2]) & 0xffff, \ + (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \ + ntohl(ipaddr->addr[3]) & 0xffff)); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_IP_ADDR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api.h new file mode 100644 index 0000000..2ba65a1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_H__ +#define __LWIP_API_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/netbuf.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define port_netconn_recv(conn , buf, ret) do{ret = netconn_recv(conn, &buf);}while(0); +#define port_netconn_accept(conn , newconn, ret) do{ret = netconn_accept(conn, &newconn);}while(0); + +/* Throughout this file, IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for netconn_write (u8_t) */ +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY 0x01 +#define NETCONN_MORE 0x02 +#define NETCONN_DONTBLOCK 0x04 + +/* Flags for struct netconn.flags (u8_t) */ +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define NETCONN_FLAG_WRITE_DELAYED 0x01 +/** Should this netconn avoid blocking? */ +#define NETCONN_FLAG_NON_BLOCKING 0x02 +/** Was the last connect action a non-blocking one? */ +#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 + + +/* Helpers to process several netconn_types by the same code */ +#define NETCONNTYPE_GROUP(t) (t&0xF0) +#define NETCONNTYPE_DATAGRAM(t) (t&0xE0) + +/** Protocol family and type of the netconn */ +enum netconn_type { + NETCONN_INVALID = 0, + /* NETCONN_TCP Group */ + NETCONN_TCP = 0x10, + /* NETCONN_UDP Group */ + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM= 0x22, + /* NETCONN_RAW Group */ + NETCONN_RAW = 0x40 +}; + +/** Current state of the netconn. Non-TCP netconns are always + * in state NETCONN_NONE! */ +enum netconn_state { + NETCONN_NONE, + NETCONN_WRITE, + NETCONN_LISTEN, + NETCONN_CONNECT, + NETCONN_CLOSE +}; + +/** Use to inform the callback function about changes */ +enum netconn_evt { + NETCONN_EVT_RCVPLUS, + NETCONN_EVT_RCVMINUS, + NETCONN_EVT_SENDPLUS, + NETCONN_EVT_SENDMINUS, + NETCONN_EVT_ERROR +}; + +#if LWIP_IGMP +/** Used for netconn_join_leave_group() */ +enum netconn_igmp { + NETCONN_JOIN, + NETCONN_LEAVE +}; +#endif /* LWIP_IGMP */ + +/* forward-declare some structs to avoid to include their headers */ +struct ip_pcb; +struct tcp_pcb; +struct udp_pcb; +struct raw_pcb; +struct netconn; +struct api_msg_msg; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); + +/** A netconn descriptor */ +struct netconn { + /** type of the netconn (TCP, UDP or RAW) */ + enum netconn_type type; + /** current state of the netconn */ + enum netconn_state state; + /** the lwIP internal protocol control block */ + union { + struct ip_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + /** the last error this netconn had */ + err_t last_err; + /** sem that is used to synchroneously execute functions in the core context */ + sys_sem_t op_completed; + /** mbox where received packets are stored until they are fetched + by the netconn application thread (can grow quite big) */ + sys_mbox_t recvmbox; +#if LWIP_TCP + /** mbox where new connections are stored until processed + by the application thread */ + sys_mbox_t acceptmbox; +#endif /* LWIP_TCP */ + /** only used for socket layer */ +#if LWIP_SOCKET + int socket; +#endif /* LWIP_SOCKET */ +#if LWIP_SO_SNDTIMEO + /** timeout to wait for sending data (which means enqueueing data for sending + in internal buffers) */ + s32_t send_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVTIMEO + /** timeout to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + /** maximum amount of bytes queued in recvmbox + not used for TCP: adjust TCP_WND instead! */ + int recv_bufsize; + /** number of bytes currently in recvmbox to be received, + tested against recv_bufsize to limit bytes on recvmbox + for UDP and RAW, used for FIONREAD */ + s16_t recv_avail; +#endif /* LWIP_SO_RCVBUF */ + /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ + u8_t flags; +#if LWIP_TCP + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores how much is already sent. */ + size_t write_offset; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. + Also used during connect and close. */ + struct api_msg_msg *current_msg; +#endif /* LWIP_TCP */ + /** A callback function that is informed about events for this netconn */ + netconn_callback callback; +}; + +/** Register an Network connection event */ +#define API_EVENT(c,e,l) if (c->callback) { \ + (*c->callback)(c, e, l); \ + } + +/** Set conn->last_err to err but don't overwrite fatal errors */ +#define NETCONN_SET_SAFE_ERR(conn, err) do { \ + SYS_ARCH_DECL_PROTECT(lev); \ + SYS_ARCH_PROTECT(lev); \ + if (!ERR_IS_FATAL((conn)->last_err)) { \ + (conn)->last_err = err; \ + } \ + SYS_ARCH_UNPROTECT(lev); \ +} while(0); + + +/* Network connection functions: */ +#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) +#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) +struct +netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, + netconn_callback callback); +err_t netconn_delete(struct netconn *conn); +/** Get the type of a netconn (as enum netconn_type). */ +#define netconn_type(conn) (conn->type) + +err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, + u16_t *port, u8_t local); +#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) +#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) + +err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); +err_t netconn_disconnect (struct netconn *conn); +err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); +#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) +err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); +err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); +void netconn_recved(struct netconn *conn, u32_t length); +err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, + ip_addr_t *addr, u16_t port); +err_t netconn_send(struct netconn *conn, struct netbuf *buf); +err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written); +#define netconn_write(conn, dataptr, size, apiflags) \ + netconn_write_partly(conn, dataptr, size, apiflags, NULL) +err_t netconn_close(struct netconn *conn); +err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); + +err_t netconn_abort(struct netconn *conn);//Realtek add + +#if LWIP_IGMP +err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, + ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); +#endif /* LWIP_IGMP */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); +#endif /* LWIP_DNS */ + +#define netconn_err(conn) ((conn)->last_err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) + +/** Set the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_set_nonblocking(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) +/** Get the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) + +/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_set_noautorecved(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) +/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) + +#if LWIP_SO_SNDTIMEO +/** Set the send timeout in milliseconds */ +#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) +/** Get the send timeout in milliseconds */ +#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO +/** Set the receive timeout in milliseconds */ +#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) +/** Get the receive timeout in milliseconds */ +#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF +/** Set the receive buffer in bytes */ +#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) +/** Get the receive buffer in bytes */ +#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) +#endif /* LWIP_SO_RCVBUF*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api_msg.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api_msg.h new file mode 100644 index 0000000..f9e1c7d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/api_msg.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_API_MSG_H__ +#define __LWIP_API_MSG_H__ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* For the netconn API, these values are use as a bitmask! */ +#define NETCONN_SHUT_RD 1 +#define NETCONN_SHUT_WR 2 +#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) + +/* IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ +/** This struct includes everything that is necessary to execute a function + for a netconn in another thread context (mainly used to process netconns + in the tcpip_thread context to be thread safe). */ +struct api_msg_msg { + /** The netconn which to process - always needed: it includes the semaphore + which is used to block the application thread until the function finished. */ + struct netconn *conn; + /** The return value of the function executed in tcpip_thread. */ + err_t err; + /** Depending on the executed function, one of these union members is used */ + union { + /** used for do_send */ + struct netbuf *b; + /** used for do_newconn */ + struct { + u8_t proto; + } n; + /** used for do_bind and do_connect */ + struct { + ip_addr_t *ipaddr; + u16_t port; + } bc; + /** used for do_getaddr */ + struct { + ip_addr_t *ipaddr; + u16_t *port; + u8_t local; + } ad; + /** used for do_write */ + struct { + const void *dataptr; + size_t len; + u8_t apiflags; +#if LWIP_SO_SNDTIMEO + u32_t time_started; +#endif /* LWIP_SO_SNDTIMEO */ + } w; + /** used for do_recv */ + struct { + u32_t len; + } r; + /** used for do_close (/shutdown) */ + struct { + u8_t shut; + } sd; +#if LWIP_IGMP + /** used for do_join_leave_group */ + struct { + ip_addr_t *multiaddr; + ip_addr_t *netif_addr; + enum netconn_igmp join_or_leave; + } jl; +#endif /* LWIP_IGMP */ +#if TCP_LISTEN_BACKLOG + struct { + u8_t backlog; + } lb; +#endif /* TCP_LISTEN_BACKLOG */ + } msg; +}; + +/** This struct contains a function to execute in another thread context and + a struct api_msg_msg that serves as an argument for this function. + This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ +struct api_msg { + /** function to execute in tcpip_thread context */ + void (* function)(struct api_msg_msg *msg); + /** arguments for this function */ + struct api_msg_msg msg; +}; + +#if LWIP_DNS +/** As do_gethostbyname requires more arguments but doesn't require a netconn, + it has its own struct (to avoid struct api_msg getting bigger than necessary). + do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg + (see netconn_gethostbyname). */ +struct dns_api_msg { + /** Hostname to query or dotted IP address string */ + const char *name; + /** Rhe resolved address is stored here */ + ip_addr_t *addr; + /** This semaphore is posted when the name is resolved, the application thread + should wait on it. */ + sys_sem_t *sem; + /** Errors are given back here */ + err_t *err; +}; +#endif /* LWIP_DNS */ + +void do_newconn ( struct api_msg_msg *msg); +void do_delconn ( struct api_msg_msg *msg); +void do_bind ( struct api_msg_msg *msg); +void do_connect ( struct api_msg_msg *msg); +void do_disconnect ( struct api_msg_msg *msg); +void do_listen ( struct api_msg_msg *msg); +void do_send ( struct api_msg_msg *msg); +void do_recv ( struct api_msg_msg *msg); +void do_write ( struct api_msg_msg *msg); +void do_getaddr ( struct api_msg_msg *msg); +void do_close ( struct api_msg_msg *msg); +void do_shutdown ( struct api_msg_msg *msg); +#if LWIP_IGMP +void do_join_leave_group( struct api_msg_msg *msg); +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +void do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + +struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); +void netconn_free(struct netconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN */ + +#endif /* __LWIP_API_MSG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/FILES b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/FILES new file mode 100644 index 0000000..adfc0f3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/FILES @@ -0,0 +1,2 @@ +This directory contains application headers. +Every application shall provide one api file APP.h and optionally one options file APP_opts.h diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/fs.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/fs.h new file mode 100644 index 0000000..c635127 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/fs.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_APPS_FS_H +#define LWIP_HDR_APPS_FS_H + +#include "httpd_opts.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FS_READ_EOF -1 +#define FS_READ_DELAYED -2 + +#if HTTPD_PRECALCULATED_CHECKSUM +struct fsdata_chksum { + u32_t offset; + u16_t chksum; + u16_t len; +}; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ + +#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01 +#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02 + +struct fs_file { + const char *data; + int len; + int index; + void *pextension; +#if HTTPD_PRECALCULATED_CHECKSUM + const struct fsdata_chksum *chksum; + u16_t chksum_count; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ + u8_t flags; +#if LWIP_HTTPD_CUSTOM_FILES + u8_t is_custom_file; +#endif /* LWIP_HTTPD_CUSTOM_FILES */ +#if LWIP_HTTPD_FILE_STATE + void *state; +#endif /* LWIP_HTTPD_FILE_STATE */ +}; + +#if LWIP_HTTPD_FS_ASYNC_READ +typedef void (*fs_wait_cb)(void *arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ + +err_t fs_open(struct fs_file *file, const char *name); +void fs_close(struct fs_file *file); +#if LWIP_HTTPD_DYNAMIC_FILE_READ +#if LWIP_HTTPD_FS_ASYNC_READ +int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg); +#else /* LWIP_HTTPD_FS_ASYNC_READ */ +int fs_read(struct fs_file *file, char *buffer, int count); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ +#if LWIP_HTTPD_FS_ASYNC_READ +int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); +#endif /* LWIP_HTTPD_FS_ASYNC_READ */ +int fs_bytes_left(struct fs_file *file); + +#if LWIP_HTTPD_FILE_STATE +/** This user-defined function is called when a file is opened. */ +void *fs_state_init(struct fs_file *file, const char *name); +/** This user-defined function is called when a file is closed. */ +void fs_state_free(struct fs_file *file, void *state); +#endif /* #if LWIP_HTTPD_FILE_STATE */ + +struct fsdata_file { + const struct fsdata_file *next; + const unsigned char *name; + const unsigned char *data; + int len; + u8_t flags; +#if HTTPD_PRECALCULATED_CHECKSUM + u16_t chksum_count; + const struct fsdata_chksum *chksum; +#endif /* HTTPD_PRECALCULATED_CHECKSUM */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_FS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd.h new file mode 100644 index 0000000..40f1811 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd.h @@ -0,0 +1,236 @@ +/** + * @file + * HTTP server + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * This version of the file has been modified by Texas Instruments to offer + * simple server-side-include (SSI) and Common Gateway Interface (CGI) + * capability. + */ + +#ifndef LWIP_HDR_APPS_HTTPD_H +#define LWIP_HDR_APPS_HTTPD_H + +#include "httpd_opts.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_HTTPD_CGI + +/* + * Function pointer for a CGI script handler. + * + * This function is called each time the HTTPD server is asked for a file + * whose name was previously registered as a CGI function using a call to + * http_set_cgi_handler. The iIndex parameter provides the index of the + * CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters + * pcParam and pcValue provide access to the parameters provided along with + * the URI. iNumParams provides a count of the entries in the pcParam and + * pcValue arrays. Each entry in the pcParam array contains the name of a + * parameter with the corresponding entry in the pcValue array containing the + * value for that parameter. Note that pcParam may contain multiple elements + * with the same name if, for example, a multi-selection list control is used + * in the form generating the data. + * + * The function should return a pointer to a character string which is the + * path and filename of the response that is to be sent to the connected + * browser, for example "/thanks.htm" or "/response/error.ssi". + * + * The maximum number of parameters that will be passed to this function via + * iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming + * HTTP request above this number will be discarded. + * + * Requests intended for use by this CGI mechanism must be sent using the GET + * method (which encodes all parameters within the URI rather than in a block + * later in the request). Attempts to use the POST method will result in the + * request being ignored. + * + */ +typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[], + char *pcValue[]); + +/* + * Structure defining the base filename (URL) of a CGI and the associated + * function which is to be called when that URL is requested. + */ +typedef struct +{ + const char *pcCGIName; + tCGIHandler pfnCGIHandler; +} tCGI; + +void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers); + +#endif /* LWIP_HTTPD_CGI */ + +#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI + +#if LWIP_HTTPD_CGI_SSI +/** Define this generic CGI handler in your application. + * It is called once for every URI with parameters. + * The parameters can be stored to + */ +extern void httpd_cgi_handler(const char* uri, int iNumParams, char **pcParam, char **pcValue +#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE + , void *connection_state +#endif /* LWIP_HTTPD_FILE_STATE */ + ); +#endif /* LWIP_HTTPD_CGI_SSI */ + +#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */ + +#if LWIP_HTTPD_SSI + +/* + * Function pointer for the SSI tag handler callback. + * + * This function will be called each time the HTTPD server detects a tag of the + * form in a .shtml, .ssi or .shtm file where "name" appears as + * one of the tags supplied to http_set_ssi_handler in the ppcTags array. The + * returned insert string, which will be appended after the the string + * "" in file sent back to the client,should be written to pointer + * pcInsert. iInsertLen contains the size of the buffer pointed to by + * pcInsert. The iIndex parameter provides the zero-based index of the tag as + * found in the ppcTags array and identifies the tag that is to be processed. + * + * The handler returns the number of characters written to pcInsert excluding + * any terminating NULL or a negative number to indicate a failure (tag not + * recognized, for example). + * + * Note that the behavior of this SSI mechanism is somewhat different from the + * "normal" SSI processing as found in, for example, the Apache web server. In + * this case, the inserted text is appended following the SSI tag rather than + * replacing the tag entirely. This allows for an implementation that does not + * require significant additional buffering of output data yet which will still + * offer usable SSI functionality. One downside to this approach is when + * attempting to use SSI within JavaScript. The SSI tag is structured to + * resemble an HTML comment but this syntax does not constitute a comment + * within JavaScript and, hence, leaving the tag in place will result in + * problems in these cases. To work around this, any SSI tag which needs to + * output JavaScript code must do so in an encapsulated way, sending the whole + * HTML section as a single include. + */ +typedef u16_t (*tSSIHandler)( +#if LWIP_HTTPD_SSI_RAW + const char* ssi_tag_name, +#else /* LWIP_HTTPD_SSI_RAW */ + int iIndex, +#endif /* LWIP_HTTPD_SSI_RAW */ + char *pcInsert, int iInsertLen +#if LWIP_HTTPD_SSI_MULTIPART + , u16_t current_tag_part, u16_t *next_tag_part +#endif /* LWIP_HTTPD_SSI_MULTIPART */ +#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE + , void *connection_state +#endif /* LWIP_HTTPD_FILE_STATE */ + ); + +/** Set the SSI handler function + * (if LWIP_HTTPD_SSI_RAW==1, only the first argument is used) + */ +void http_set_ssi_handler(tSSIHandler pfnSSIHandler, + const char **ppcTags, int iNumTags); + +/** For LWIP_HTTPD_SSI_RAW==1, return this to indicate the tag is unknown. + * In this case, the webserver writes a warning into the page. + * You can also just return 0 to write nothing for unknown tags. + */ +#define HTTPD_SSI_TAG_UNKNOWN 0xFFFF + +#endif /* LWIP_HTTPD_SSI */ + +#if LWIP_HTTPD_SUPPORT_POST + +/* These functions must be implemented by the application */ + +/** Called when a POST request has been received. The application can decide + * whether to accept it or not. + * + * @param connection Unique connection identifier, valid until httpd_post_end + * is called. + * @param uri The HTTP header URI receiving the POST request. + * @param http_request The raw HTTP request (the first packet, normally). + * @param http_request_len Size of 'http_request'. + * @param content_len Content-Length from HTTP header. + * @param response_uri Filename of response file, to be filled when denying the + * request + * @param response_uri_len Size of the 'response_uri' buffer. + * @param post_auto_wnd Set this to 0 to let the callback code handle window + * updates by calling 'httpd_post_data_recved' (to throttle rx speed) + * default is 1 (httpd handles window updates automatically) + * @return ERR_OK: Accept the POST request, data may be passed in + * another err_t: Deny the POST request, send back 'bad request'. + */ +err_t httpd_post_begin(void *connection, const char *uri, const char *http_request, + u16_t http_request_len, int content_len, char *response_uri, + u16_t response_uri_len, u8_t *post_auto_wnd); + +/** Called for each pbuf of data that has been received for a POST. + * ATTENTION: The application is responsible for freeing the pbufs passed in! + * + * @param connection Unique connection identifier. + * @param p Received data. + * @return ERR_OK: Data accepted. + * another err_t: Data denied, http_post_get_response_uri will be called. + */ +err_t httpd_post_receive_data(void *connection, struct pbuf *p); + +/** Called when all data is received or when the connection is closed. + * The application must return the filename/URI of a file to send in response + * to this POST request. If the response_uri buffer is untouched, a 404 + * response is returned. + * + * @param connection Unique connection identifier. + * @param response_uri Filename of response file, to be filled when denying the request + * @param response_uri_len Size of the 'response_uri' buffer. + */ +void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len); + +#if LWIP_HTTPD_POST_MANUAL_WND +void httpd_post_data_recved(void *connection, u16_t recved_len); +#endif /* LWIP_HTTPD_POST_MANUAL_WND */ + +#endif /* LWIP_HTTPD_SUPPORT_POST */ + +void httpd_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HTTPD_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd_opts.h new file mode 100644 index 0000000..e94aba8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/httpd_opts.h @@ -0,0 +1,327 @@ +/** + * @file + * HTTP server options list + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * This version of the file has been modified by Texas Instruments to offer + * simple server-side-include (SSI) and Common Gateway Interface (CGI) + * capability. + */ + +#ifndef LWIP_HDR_APPS_HTTPD_OPTS_H +#define LWIP_HDR_APPS_HTTPD_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup httpd_opts Options + * @ingroup httpd + * @{ + */ + +/** Set this to 1 to support CGI (old style) */ +#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__ +#define LWIP_HTTPD_CGI 0 +#endif + +/** Set this to 1 to support CGI (new style) */ +#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__ +#define LWIP_HTTPD_CGI_SSI 0 +#endif + +/** Set this to 1 to support SSI (Server-Side-Includes) */ +#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__ +#define LWIP_HTTPD_SSI 0 +#endif + +/** Set this to 1 to implement an SSI tag handler callback that gets a const char* + * to the tag (instead of an index into a pre-registered array of known tags) */ +#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__ +#define LWIP_HTTPD_SSI_RAW 0 +#endif + +/** Set this to 1 to support HTTP POST */ +#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__ +#define LWIP_HTTPD_SUPPORT_POST 0 +#endif + +/* The maximum number of parameters that the CGI handler can be sent. */ +#if !defined LWIP_HTTPD_MAX_CGI_PARAMETERS || defined __DOXYGEN__ +#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16 +#endif + +/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more + * arguments indicating a counter for insert string that are too long to be + * inserted at once: the SSI handler function must then set 'next_tag_part' + * which will be passed back to it in the next call. */ +#if !defined LWIP_HTTPD_SSI_MULTIPART || defined __DOXYGEN__ +#define LWIP_HTTPD_SSI_MULTIPART 0 +#endif + +/* The maximum length of the string comprising the tag name */ +#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__ +#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8 +#endif + +/* The maximum length of string that can be returned to replace any given tag */ +#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__ +#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192 +#endif + +#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__ +#define LWIP_HTTPD_POST_MANUAL_WND 0 +#endif + +/** This string is passed in the HTTP header as "Server: " */ +#if !defined HTTPD_SERVER_AGENT || defined __DOXYGEN__ +#define HTTPD_SERVER_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)" +#endif + +/** Set this to 1 if you want to include code that creates HTTP headers + * at runtime. Default is off: HTTP headers are then created statically + * by the makefsdata tool. Static headers mean smaller code size, but + * the (readonly) fsdata will grow a bit as every file includes the HTTP + * header. */ +#if !defined LWIP_HTTPD_DYNAMIC_HEADERS || defined __DOXYGEN__ +#define LWIP_HTTPD_DYNAMIC_HEADERS 0 +#endif + +#if !defined HTTPD_DEBUG || defined __DOXYGEN__ +#define HTTPD_DEBUG LWIP_DBG_OFF +#endif + +/** Set this to 1 to use a memp pool for allocating + * struct http_state instead of the heap. + */ +#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__ +#define HTTPD_USE_MEM_POOL 0 +#endif + +/** The server port for HTTPD to use */ +#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__ +#define HTTPD_SERVER_PORT 80 +#endif + +/** Maximum retries before the connection is aborted/closed. + * - number of times pcb->poll is called -> default is 4*500ms = 2s; + * - reset when pcb->sent is called + */ +#if !defined HTTPD_MAX_RETRIES || defined __DOXYGEN__ +#define HTTPD_MAX_RETRIES 4 +#endif + +/** The poll delay is X*500ms */ +#if !defined HTTPD_POLL_INTERVAL || defined __DOXYGEN__ +#define HTTPD_POLL_INTERVAL 4 +#endif + +/** Priority for tcp pcbs created by HTTPD (very low by default). + * Lower priorities get killed first when running out of memory. + */ +#if !defined HTTPD_TCP_PRIO || defined __DOXYGEN__ +#define HTTPD_TCP_PRIO TCP_PRIO_MIN +#endif + +/** Set this to 1 to enable timing each file sent */ +#if !defined LWIP_HTTPD_TIMING || defined __DOXYGEN__ +#define LWIP_HTTPD_TIMING 0 +#endif +/** Set this to 1 to enable timing each file sent */ +#if !defined HTTPD_DEBUG_TIMING || defined __DOXYGEN__ +#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF +#endif + +/** Set this to one to show error pages when parsing a request fails instead + of simply closing the connection. */ +#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__ +#define LWIP_HTTPD_SUPPORT_EXTSTATUS 0 +#endif + +/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */ +#if !defined LWIP_HTTPD_SUPPORT_V09 || defined __DOXYGEN__ +#define LWIP_HTTPD_SUPPORT_V09 1 +#endif + +/** Set this to 1 to enable HTTP/1.1 persistent connections. + * ATTENTION: If the generated file system includes HTTP headers, these must + * include the "Connection: keep-alive" header (pass argument "-11" to makefsdata). + */ +#if !defined LWIP_HTTPD_SUPPORT_11_KEEPALIVE || defined __DOXYGEN__ +#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE 0 +#endif + +/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */ +#if !defined LWIP_HTTPD_SUPPORT_REQUESTLIST || defined __DOXYGEN__ +#define LWIP_HTTPD_SUPPORT_REQUESTLIST 1 +#endif + +#if LWIP_HTTPD_SUPPORT_REQUESTLIST +/** Number of rx pbufs to enqueue to parse an incoming request (up to the first + newline) */ +#if !defined LWIP_HTTPD_REQ_QUEUELEN || defined __DOXYGEN__ +#define LWIP_HTTPD_REQ_QUEUELEN 5 +#endif + +/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming + request (up to the first double-newline) */ +#if !defined LWIP_HTTPD_REQ_BUFSIZE || defined __DOXYGEN__ +#define LWIP_HTTPD_REQ_BUFSIZE LWIP_HTTPD_MAX_REQ_LENGTH +#endif + +/** Defines the maximum length of a HTTP request line (up to the first CRLF, + copied from pbuf into this a global buffer when pbuf- or packet-queues + are received - otherwise the input pbuf is used directly) */ +#if !defined LWIP_HTTPD_MAX_REQ_LENGTH || defined __DOXYGEN__ +#define LWIP_HTTPD_MAX_REQ_LENGTH LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE)) +#endif +#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ + +/** This is the size of a static buffer used when URIs end with '/'. + * In this buffer, the directory requested is concatenated with all the + * configured default file names. + * Set to 0 to disable checking default filenames on non-root directories. + */ +#if !defined LWIP_HTTPD_MAX_REQUEST_URI_LEN || defined __DOXYGEN__ +#define LWIP_HTTPD_MAX_REQUEST_URI_LEN 63 +#endif + +/** Maximum length of the filename to send as response to a POST request, + * filled in by the application when a POST is finished. + */ +#if !defined LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN || defined __DOXYGEN__ +#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63 +#endif + +/** Set this to 0 to not send the SSI tag (default is on, so the tag will + * be sent in the HTML page */ +#if !defined LWIP_HTTPD_SSI_INCLUDE_TAG || defined __DOXYGEN__ +#define LWIP_HTTPD_SSI_INCLUDE_TAG 1 +#endif + +/** Set this to 1 to call tcp_abort when tcp_close fails with memory error. + * This can be used to prevent consuming all memory in situations where the + * HTTP server has low priority compared to other communication. */ +#if !defined LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR || defined __DOXYGEN__ +#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR 0 +#endif + +/** Set this to 1 to kill the oldest connection when running out of + * memory for 'struct http_state' or 'struct http_ssi_state'. + * ATTENTION: This puts all connections on a linked list, so may be kind of slow. + */ +#if !defined LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED || defined __DOXYGEN__ +#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0 +#endif + +/** Set this to 1 to send URIs without extension without headers + * (who uses this at all??) */ +#if !defined LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI || defined __DOXYGEN__ +#define LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI 0 +#endif + +/** Default: Tags are sent from struct http_state and are therefore volatile */ +#if !defined HTTP_IS_TAG_VOLATILE || defined __DOXYGEN__ +#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY +#endif + +/* By default, the httpd is limited to send 2*pcb->mss to keep resource usage low + when http is not an important protocol in the device. */ +#if !defined HTTPD_LIMIT_SENDING_TO_2MSS || defined __DOXYGEN__ +#define HTTPD_LIMIT_SENDING_TO_2MSS 1 +#endif + +/* Define this to a function that returns the maximum amount of data to enqueue. + The function have this signature: u16_t fn(struct tcp_pcb* pcb); */ +#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__ +#if HTTPD_LIMIT_SENDING_TO_2MSS +#define HTTPD_MAX_WRITE_LEN(pcb) (2 * tcp_mss(pcb)) +#endif +#endif + +/*------------------- FS OPTIONS -------------------*/ + +/** Set this to 1 and provide the functions: + * - "int fs_open_custom(struct fs_file *file, const char *name)" + * Called first for every opened file to allow opening files + * that are not included in fsdata(_custom).c + * - "void fs_close_custom(struct fs_file *file)" + * Called to free resources allocated by fs_open_custom(). + */ +#if !defined LWIP_HTTPD_CUSTOM_FILES || defined __DOXYGEN__ +#define LWIP_HTTPD_CUSTOM_FILES 0 +#endif + +/** Set this to 1 to support fs_read() to dynamically read file data. + * Without this (default=off), only one-block files are supported, + * and the contents must be ready after fs_open(). + */ +#if !defined LWIP_HTTPD_DYNAMIC_FILE_READ || defined __DOXYGEN__ +#define LWIP_HTTPD_DYNAMIC_FILE_READ 0 +#endif + +/** Set this to 1 to include an application state argument per file + * that is opened. This allows to keep a state per connection/file. + */ +#if !defined LWIP_HTTPD_FILE_STATE || defined __DOXYGEN__ +#define LWIP_HTTPD_FILE_STATE 0 +#endif + +/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for + * predefined (MSS-sized) chunks of the files to prevent having to calculate + * the checksums at runtime. */ +#if !defined HTTPD_PRECALCULATED_CHECKSUM || defined __DOXYGEN__ +#define HTTPD_PRECALCULATED_CHECKSUM 0 +#endif + +/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations + * (fs_read_async returns FS_READ_DELAYED and calls a callback when finished). + */ +#if !defined LWIP_HTTPD_FS_ASYNC_READ || defined __DOXYGEN__ +#define LWIP_HTTPD_FS_ASYNC_READ 0 +#endif + +/** Filename (including path) to use as FS data file */ +#if !defined HTTPD_FSDATA_FILE || defined __DOXYGEN__ +/* HTTPD_USE_CUSTOM_FSDATA: Compatibility with deprecated lwIP option */ +#if defined(HTTPD_USE_CUSTOM_FSDATA) && (HTTPD_USE_CUSTOM_FSDATA != 0) +#define HTTPD_FSDATA_FILE "fsdata_custom.c" +#else +#define HTTPD_FSDATA_FILE "fsdata.c" +#endif +#endif + +/** + * @} + */ + +#endif /* LWIP_HDR_APPS_HTTPD_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/lwiperf.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/lwiperf.h new file mode 100644 index 0000000..7dbebb0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/lwiperf.h @@ -0,0 +1,84 @@ +/** + * @file + * lwIP iPerf server implementation + */ + +/* + * Copyright (c) 2014 Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_APPS_LWIPERF_H +#define LWIP_HDR_APPS_LWIPERF_H + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIPERF_TCP_PORT_DEFAULT 5001 + +/** lwIPerf test results */ +enum lwiperf_report_type +{ + /** The server side test is done */ + LWIPERF_TCP_DONE_SERVER, + /** The client side test is done */ + LWIPERF_TCP_DONE_CLIENT, + /** Local error lead to test abort */ + LWIPERF_TCP_ABORTED_LOCAL, + /** Data check error lead to test abort */ + LWIPERF_TCP_ABORTED_LOCAL_DATAERROR, + /** Transmit error lead to test abort */ + LWIPERF_TCP_ABORTED_LOCAL_TXERROR, + /** Remote side aborted the test */ + LWIPERF_TCP_ABORTED_REMOTE +}; + +/** Prototype of a report function that is called when a session is finished. + This report function can show the test results. + @param report_type contains the test result */ +typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_type, + const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port, + u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec); + + +void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port, + lwiperf_report_fn report_fn, void* report_arg); +void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg); +void lwiperf_abort(void* lwiperf_session); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_LWIPERF_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns.h new file mode 100644 index 0000000..d036816 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns.h @@ -0,0 +1,69 @@ +/** + * @file + * MDNS responder + */ + + /* + * Copyright (c) 2015 Verisure Innovation AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Ekman + * + */ +#ifndef LWIP_HDR_MDNS_H +#define LWIP_HDR_MDNS_H + +#include "lwip/apps/mdns_opts.h" +#include "lwip/netif.h" + +#if LWIP_MDNS_RESPONDER + +enum mdns_sd_proto { + DNSSD_PROTO_UDP = 0, + DNSSD_PROTO_TCP = 1 +}; + +#define MDNS_LABEL_MAXLEN 63 + +struct mdns_host; +struct mdns_service; + +/** Callback function to add text to a reply, called when generating the reply */ +typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata); + +void mdns_resp_init(void); + +err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl); +err_t mdns_resp_remove_netif(struct netif *netif); + +err_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata); +err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len); +void mdns_resp_netif_settings_changed(struct netif *netif); + +#endif /* LWIP_MDNS_RESPONDER */ + +#endif /* LWIP_HDR_MDNS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_opts.h new file mode 100644 index 0000000..d8058e4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_opts.h @@ -0,0 +1,74 @@ +/** + * @file + * MDNS responder + */ + + /* + * Copyright (c) 2015 Verisure Innovation AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Ekman + * + */ + +#ifndef LWIP_HDR_APPS_MDNS_OPTS_H +#define LWIP_HDR_APPS_MDNS_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup mdns_opts Options + * @ingroup mdns + * @{ + */ + +/** + * LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS + * transport. IGMP is needed for IPv4 multicast. + */ +#ifndef LWIP_MDNS_RESPONDER +#define LWIP_MDNS_RESPONDER 1 +#endif /* LWIP_MDNS_RESPONDER */ + +/** The maximum number of services per netif */ +#ifndef MDNS_MAX_SERVICES +#define MDNS_MAX_SERVICES 1 +#endif + +/** + * MDNS_DEBUG: Enable debugging for multicast DNS. + */ +#ifndef MDNS_DEBUG +#define MDNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * @} + */ + +#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_priv.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_priv.h new file mode 100644 index 0000000..8ee6db8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mdns_priv.h @@ -0,0 +1,66 @@ +/** + * @file + * MDNS responder private definitions + */ + + /* + * Copyright (c) 2015 Verisure Innovation AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Ekman + * + */ +#ifndef LWIP_HDR_MDNS_PRIV_H +#define LWIP_HDR_MDNS_PRIV_H + +#include "lwip/apps/mdns_opts.h" +#include "lwip/pbuf.h" + +#if LWIP_MDNS_RESPONDER + +/* Domain struct and methods - visible for unit tests */ + +#define MDNS_DOMAIN_MAXLEN 256 +#define MDNS_READNAME_ERROR 0xFFFF + +struct mdns_domain { + /* Encoded domain name */ + u8_t name[MDNS_DOMAIN_MAXLEN]; + /* Total length of domain name, including zero */ + u16_t length; + /* Set if compression of this domain is not allowed */ + u8_t skip_compression; +}; + +err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len); +u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain); +int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b); +u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain); + +#endif /* LWIP_MDNS_RESPONDER */ + +#endif /* LWIP_HDR_MDNS_PRIV_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt.h new file mode 100644 index 0000000..ee88040 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt.h @@ -0,0 +1,243 @@ +/** + * @file + * MQTT client + */ + +/* + * Copyright (c) 2016 Erik Andersson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Andersson + * + */ +#ifndef LWIP_HDR_APPS_MQTT_CLIENT_H +#define LWIP_HDR_APPS_MQTT_CLIENT_H + +#include "lwip/apps/mqtt_opts.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mqtt_client_t mqtt_client_t; + +/** @ingroup mqtt + * Default MQTT port */ +#define MQTT_PORT 1883 + +/*---------------------------------------------------------------------------------------------- */ +/* Connection with server */ + +/** + * @ingroup mqtt + * Client information and connection parameters */ +struct mqtt_connect_client_info_t { + /** Client identifier, must be set by caller */ + const char *client_id; + /** User name and password, set to NULL if not used */ + const char* client_user; + const char* client_pass; + /** keep alive time in seconds, 0 to disable keep alive functionality*/ + u16_t keep_alive; + /** will topic, set to NULL if will is not to be used, + will_msg, will_qos and will retain are then ignored */ + const char* will_topic; + const char* will_msg; + u8_t will_qos; + u8_t will_retain; +}; + +/** + * @ingroup mqtt + * Connection status codes */ +typedef enum +{ + MQTT_CONNECT_ACCEPTED = 0, + MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1, + MQTT_CONNECT_REFUSED_IDENTIFIER = 2, + MQTT_CONNECT_REFUSED_SERVER = 3, + MQTT_CONNECT_REFUSED_USERNAME_PASS = 4, + MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5, + MQTT_CONNECT_DISCONNECTED = 256, + MQTT_CONNECT_TIMEOUT = 257 +} mqtt_connection_status_t; + +/** + * @ingroup mqtt + * Function prototype for mqtt connection status callback. Called when + * client has connected to the server after initiating a mqtt connection attempt by + * calling mqtt_connect() or when connection is closed by server or an error + * + * @param client MQTT client itself + * @param arg Additional argument to pass to the callback function + * @param status Connect result code or disconnection notification @see mqtt_connection_status_t + * + */ +typedef void (*mqtt_connection_cb_t)(mqtt_client_t *client, void *arg, mqtt_connection_status_t status); + + +/** + * @ingroup mqtt + * Data callback flags */ +enum { + /** Flag set when last fragment of data arrives in data callback */ + MQTT_DATA_FLAG_LAST = 1 +}; + +/** + * @ingroup mqtt + * Function prototype for MQTT incoming publish data callback function. Called when data + * arrives to a subscribed topic @see mqtt_subscribe + * + * @param arg Additional argument to pass to the callback function + * @param data User data, pointed object, data may not be referenced after callback return, + NULL is passed when all publish data are delivered + * @param len Length of publish data fragment + * @param flags MQTT_DATA_FLAG_LAST set when this call contains the last part of data from publish message + * + */ +typedef void (*mqtt_incoming_data_cb_t)(void *arg, const u8_t *data, u16_t len, u8_t flags); + + +/** + * @ingroup mqtt + * Function prototype for MQTT incoming publish function. Called when an incoming publish + * arrives to a subscribed topic @see mqtt_subscribe + * + * @param arg Additional argument to pass to the callback function + * @param topic Zero terminated Topic text string, topic may not be referenced after callback return + * @param tot_len Total length of publish data, if set to 0 (no publish payload) data callback will not be invoked + */ +typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t tot_len); + + +/** + * @ingroup mqtt + * Function prototype for mqtt request callback. Called when a subscribe, unsubscribe + * or publish request has completed + * @param arg Pointer to user data supplied when invoking request + * @param err ERR_OK on success + * ERR_TIMEOUT if no response was received within timeout, + * ERR_ABRT if (un)subscribe was denied + */ +typedef void (*mqtt_request_cb_t)(void *arg, err_t err); + + +/** + * Pending request item, binds application callback to pending server requests + */ +struct mqtt_request_t +{ + /** Next item in list, NULL means this is the last in chain, + next pointing at itself means request is unallocated */ + struct mqtt_request_t *next; + /** Callback to upper layer */ + mqtt_request_cb_t cb; + void *arg; + /** MQTT packet identifier */ + u16_t pkt_id; + /** Expire time relative to element before this */ + u16_t timeout_diff; +}; + +/** Ring buffer */ +struct mqtt_ringbuf_t { + u16_t put; + u16_t get; + u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE]; +}; + +/** MQTT client */ +struct mqtt_client_t +{ + /** Timers and timeouts */ + u16_t cyclic_tick; + u16_t keep_alive; + u16_t server_watchdog; + /** Packet identifier generator*/ + u16_t pkt_id_seq; + /** Packet identifier of pending incoming publish */ + u16_t inpub_pkt_id; + /** Connection state */ + u8_t conn_state; + struct tcp_pcb *conn; + /** Connection callback */ + void *connect_arg; + mqtt_connection_cb_t connect_cb; + /** Pending requests to server */ + struct mqtt_request_t *pend_req_queue; + struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT]; + void *inpub_arg; + /** Incoming data callback */ + mqtt_incoming_data_cb_t data_cb; + mqtt_incoming_publish_cb_t pub_cb; + /** Input */ + u32_t msg_idx; + u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN]; + /** Output ring-buffer */ + struct mqtt_ringbuf_t output; +}; + + +/** Connect to server */ +err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg, + const struct mqtt_connect_client_info_t *client_info); + +/** Disconnect from server */ +void mqtt_disconnect(mqtt_client_t *client); + +/** Create new client */ +mqtt_client_t *mqtt_client_new(void); + +/** Check connection status */ +u8_t mqtt_client_is_connected(mqtt_client_t *client); + +/** Set callback to call for incoming publish */ +void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t, + mqtt_incoming_data_cb_t data_cb, void *arg); + +/** Common function for subscribe and unsubscribe */ +err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub); + +/** @ingroup mqtt + *Subscribe to topic */ +#define mqtt_subscribe(client, topic, qos, cb, arg) mqtt_sub_unsub(client, topic, qos, cb, arg, 1) +/** @ingroup mqtt + * Unsubscribe to topic */ +#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0) + + +/** Publish data to topic */ +err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain, + mqtt_request_cb_t cb, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_MQTT_CLIENT_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt_opts.h new file mode 100644 index 0000000..ffefacd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/mqtt_opts.h @@ -0,0 +1,103 @@ +/** + * @file + * MQTT client options + */ + +/* + * Copyright (c) 2016 Erik Andersson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Erik Andersson + * + */ +#ifndef LWIP_HDR_APPS_MQTT_OPTS_H +#define LWIP_HDR_APPS_MQTT_OPTS_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup mqtt_opts Options + * @ingroup mqtt + * @{ + */ + +/** + * Output ring-buffer size, must be able to fit largest outgoing publish message topic+payloads + */ +#ifndef MQTT_OUTPUT_RINGBUF_SIZE +#define MQTT_OUTPUT_RINGBUF_SIZE 256 +#endif + +/** + * Number of bytes in receive buffer, must be at least the size of the longest incoming topic + 8 + * If one wants to avoid fragmented incoming publish, set length to max incoming topic length + max payload length + 8 + */ +#ifndef MQTT_VAR_HEADER_BUFFER_LEN +#define MQTT_VAR_HEADER_BUFFER_LEN 128 +#endif + +/** + * Maximum number of pending subscribe, unsubscribe and publish requests to server . + */ +#ifndef MQTT_REQ_MAX_IN_FLIGHT +#define MQTT_REQ_MAX_IN_FLIGHT 4 +#endif + +/** + * Seconds between each cyclic timer call. + */ +#ifndef MQTT_CYCLIC_TIMER_INTERVAL +#define MQTT_CYCLIC_TIMER_INTERVAL 5 +#endif + +/** + * Publish, subscribe and unsubscribe request timeout in seconds. + */ +#ifndef MQTT_REQ_TIMEOUT +#define MQTT_REQ_TIMEOUT 30 +#endif + +/** + * Seconds for MQTT connect response timeout after sending connect request + */ +#ifndef MQTT_CONNECT_TIMOUT +#define MQTT_CONNECT_TIMOUT 100 +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_MQTT_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns.h new file mode 100644 index 0000000..c9f68d8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns.h @@ -0,0 +1,43 @@ +/** + * @file + * NETBIOS name service responder + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ +#ifndef LWIP_HDR_APPS_NETBIOS_H +#define LWIP_HDR_APPS_NETBIOS_H + +#include "lwip/apps/netbiosns_opts.h" + +void netbiosns_init(void); +#ifndef NETBIOS_LWIP_NAME +void netbiosns_set_name(const char* hostname); +#endif +void netbiosns_stop(void); + +#endif /* LWIP_HDR_APPS_NETBIOS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns_opts.h new file mode 100644 index 0000000..0909ef7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/netbiosns_opts.h @@ -0,0 +1,59 @@ +/** + * @file + * NETBIOS name service responder options + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ +#ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H +#define LWIP_HDR_APPS_NETBIOS_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup netbiosns_opts Options + * @ingroup netbiosns + * @{ + */ + +/** NetBIOS name of lwip device + * This must be uppercase until NETBIOS_STRCMP() is defined to a string + * comparision function that is case insensitive. + * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): + * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") + * + * If this is not defined, netbiosns_set_name() can be called at runtime to change the name. + */ +#ifdef __DOXYGEN__ +#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV" +#endif + +/** + * @} + */ + +#endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp.h new file mode 100644 index 0000000..10e8ff4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp.h @@ -0,0 +1,128 @@ +/** + * @file + * SNMP server main API - start and basic configuration + */ + +/* + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * Martin Hentschel + * + */ +#ifndef LWIP_HDR_APPS_SNMP_H +#define LWIP_HDR_APPS_SNMP_H + +#include "lwip/apps/snmp_opts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/err.h" +#include "lwip/apps/snmp_core.h" + +/** SNMP variable binding descriptor (publically needed for traps) */ +struct snmp_varbind +{ + /** pointer to next varbind, NULL for last in list */ + struct snmp_varbind *next; + /** pointer to previous varbind, NULL for first in list */ + struct snmp_varbind *prev; + + /** object identifier */ + struct snmp_obj_id oid; + + /** value ASN1 type */ + u8_t type; + /** object value length */ + u16_t value_len; + /** object value */ + void *value; +}; + +/** + * @ingroup snmp_core + * Agent setup, start listening to port 161. + */ +void snmp_init(void); +void snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs); + +void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid); +const struct snmp_obj_id* snmp_get_device_enterprise_oid(void); + +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst); + +/** Generic trap: cold start */ +#define SNMP_GENTRAP_COLDSTART 0 +/** Generic trap: warm start */ +#define SNMP_GENTRAP_WARMSTART 1 +/** Generic trap: link down */ +#define SNMP_GENTRAP_LINKDOWN 2 +/** Generic trap: link up */ +#define SNMP_GENTRAP_LINKUP 3 +/** Generic trap: authentication failure */ +#define SNMP_GENTRAP_AUTH_FAILURE 4 +/** Generic trap: EGP neighbor lost */ +#define SNMP_GENTRAP_EGP_NEIGHBOR_LOSS 5 +/** Generic trap: enterprise specific */ +#define SNMP_GENTRAP_ENTERPRISE_SPECIFIC 6 + +err_t snmp_send_trap_generic(s32_t generic_trap); +err_t snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds); +err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds); + +#define SNMP_AUTH_TRAPS_DISABLED 0 +#define SNMP_AUTH_TRAPS_ENABLED 1 +void snmp_set_auth_traps_enabled(u8_t enable); +u8_t snmp_get_auth_traps_enabled(void); + +const char * snmp_get_community(void); +const char * snmp_get_community_write(void); +const char * snmp_get_community_trap(void); +void snmp_set_community(const char * const community); +void snmp_set_community_write(const char * const community); +void snmp_set_community_trap(const char * const community); + +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +typedef void (*snmp_write_callback_fct)(const u32_t* oid, u8_t oid_len, void* callback_arg); +void snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg); + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_core.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_core.h new file mode 100644 index 0000000..e781c53 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_core.h @@ -0,0 +1,364 @@ +/** + * @file + * SNMP core API for implementing MIBs + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + * Martin Hentschel + */ + +#ifndef LWIP_HDR_APPS_SNMP_CORE_H +#define LWIP_HDR_APPS_SNMP_CORE_H + +#include "lwip/apps/snmp_opts.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* basic ASN1 defines */ +#define SNMP_ASN1_CLASS_UNIVERSAL 0x00 +#define SNMP_ASN1_CLASS_APPLICATION 0x40 +#define SNMP_ASN1_CLASS_CONTEXT 0x80 +#define SNMP_ASN1_CLASS_PRIVATE 0xC0 + +#define SNMP_ASN1_CONTENTTYPE_PRIMITIVE 0x00 +#define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20 + +/* universal tags (from ASN.1 spec.) */ +#define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT 0 +#define SNMP_ASN1_UNIVERSAL_INTEGER 2 +#define SNMP_ASN1_UNIVERSAL_OCTET_STRING 4 +#define SNMP_ASN1_UNIVERSAL_NULL 5 +#define SNMP_ASN1_UNIVERSAL_OBJECT_ID 6 +#define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF 16 + +/* application specific (SNMP) tags (from SNMPv2-SMI) */ +#define SNMP_ASN1_APPLICATION_IPADDR 0 /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */ +#define SNMP_ASN1_APPLICATION_COUNTER 1 /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */ +#define SNMP_ASN1_APPLICATION_GAUGE 2 /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */ +#define SNMP_ASN1_APPLICATION_TIMETICKS 3 /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */ +#define SNMP_ASN1_APPLICATION_OPAQUE 4 /* [APPLICATION 4] IMPLICIT OCTET STRING */ +#define SNMP_ASN1_APPLICATION_COUNTER64 6 /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */ + +/* context specific (SNMP) tags (from RFC 1905) */ +#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1 + +/* full ASN1 type defines */ +#define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT) +#define SNMP_ASN1_TYPE_INTEGER (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER) +#define SNMP_ASN1_TYPE_OCTET_STRING (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING) +#define SNMP_ASN1_TYPE_NULL (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL) +#define SNMP_ASN1_TYPE_OBJECT_ID (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID) +#define SNMP_ASN1_TYPE_SEQUENCE (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF) +#define SNMP_ASN1_TYPE_IPADDR (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR) +#define SNMP_ASN1_TYPE_IPADDRESS SNMP_ASN1_TYPE_IPADDR +#define SNMP_ASN1_TYPE_COUNTER (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER) +#define SNMP_ASN1_TYPE_COUNTER32 SNMP_ASN1_TYPE_COUNTER +#define SNMP_ASN1_TYPE_GAUGE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE) +#define SNMP_ASN1_TYPE_GAUGE32 SNMP_ASN1_TYPE_GAUGE +#define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE +#define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS) +#define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE) +#define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64) + +#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0 +#define SNMP_VARBIND_EXCEPTION_MASK 0x0F + +/** error codes predefined by SNMP prot. */ +typedef enum { + SNMP_ERR_NOERROR = 0, +/* +outdated v1 error codes. do not use anmore! +#define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead +#define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead +#define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead +*/ + SNMP_ERR_GENERROR = 5, + SNMP_ERR_NOACCESS = 6, + SNMP_ERR_WRONGTYPE = 7, + SNMP_ERR_WRONGLENGTH = 8, + SNMP_ERR_WRONGENCODING = 9, + SNMP_ERR_WRONGVALUE = 10, + SNMP_ERR_NOCREATION = 11, + SNMP_ERR_INCONSISTENTVALUE = 12, + SNMP_ERR_RESOURCEUNAVAILABLE = 13, + SNMP_ERR_COMMITFAILED = 14, + SNMP_ERR_UNDOFAILED = 15, + SNMP_ERR_NOTWRITABLE = 17, + SNMP_ERR_INCONSISTENTNAME = 18, + + SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE +} snmp_err_t; + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + u32_t id[SNMP_MAX_OBJ_ID_LEN]; +}; + +struct snmp_obj_id_const_ref +{ + u8_t len; + const u32_t* id; +}; + +extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */ + +/** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */ +union snmp_variant_value +{ + void* ptr; + const void* const_ptr; + u32_t u32; + s32_t s32; +}; + + +/** +SNMP MIB node types + tree node is the only node the stack can process in order to walk the tree, + all other nodes are assumed to be leaf nodes. + This cannot be an enum because users may want to define their own node types. +*/ +#define SNMP_NODE_TREE 0x00 +/* predefined leaf node types */ +#define SNMP_NODE_SCALAR 0x01 +#define SNMP_NODE_SCALAR_ARRAY 0x02 +#define SNMP_NODE_TABLE 0x03 +#define SNMP_NODE_THREADSYNC 0x04 + +/** node "base class" layout, the mandatory fields for a node */ +struct snmp_node +{ + /** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */ + u8_t node_type; + /** the number assigned to this node which used as part of the full OID */ + u32_t oid; +}; + +/** SNMP node instance access types */ +typedef enum { + SNMP_NODE_INSTANCE_ACCESS_READ = 1, + SNMP_NODE_INSTANCE_ACCESS_WRITE = 2, + SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ, + SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE), + SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE, + SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0 +} snmp_access_t; + +struct snmp_node_instance; + +typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*); +typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*); +typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*); +typedef void (*node_instance_release_method)(struct snmp_node_instance*); + +#define SNMP_GET_VALUE_RAW_DATA 0x8000 + +/** SNMP node instance */ +struct snmp_node_instance +{ + /** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */ + const struct snmp_node* node; + /** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */ + struct snmp_obj_id instance_oid; + + /** ASN type for this object (see snmp_asn1.h for definitions) */ + u8_t asn1_type; + /** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */ + snmp_access_t access; + + /** returns object value for the given object identifier. Return values <0 to indicate an error */ + node_instance_get_value_method get_value; + /** tests length and/or range BEFORE setting */ + node_instance_set_test_method set_test; + /** sets object value, only called when set_test() was successful */ + node_instance_set_value_method set_value; + /** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */ + node_instance_release_method release_instance; + + /** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */ + union snmp_variant_value reference; + /** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */ + u32_t reference_len; +}; + + +/** SNMP tree node */ +struct snmp_tree_node +{ + /** inherited "base class" members */ + struct snmp_node node; + u16_t subnode_count; + const struct snmp_node* const *subnodes; +}; + +#define SNMP_CREATE_TREE_NODE(oid, subnodes) \ + {{ SNMP_NODE_TREE, (oid) }, \ + (u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) } + +#define SNMP_CREATE_EMPTY_TREE_NODE(oid) \ + {{ SNMP_NODE_TREE, (oid) }, \ + 0, NULL } + +/** SNMP leaf node */ +struct snmp_leaf_node +{ + /** inherited "base class" members */ + struct snmp_node node; + snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +}; + +/** represents a single mib with its base oid and root node */ +struct snmp_mib +{ + const u32_t *base_oid; + u8_t base_oid_len; + const struct snmp_node *root_node; +}; + +#define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node } + +/** OID range structure */ +struct snmp_oid_range +{ + u32_t min; + u32_t max; +}; + +/** checks if incoming OID length and values are in allowed ranges */ +u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len); + +typedef enum { + SNMP_NEXT_OID_STATUS_SUCCESS, + SNMP_NEXT_OID_STATUS_NO_MATCH, + SNMP_NEXT_OID_STATUS_BUF_TO_SMALL +} snmp_next_oid_status_t; + +/** state for next_oid_init / next_oid_check functions */ +struct snmp_next_oid_state +{ + const u32_t* start_oid; + u8_t start_oid_len; + + u32_t* next_oid; + u8_t next_oid_len; + u8_t next_oid_max_len; + + snmp_next_oid_status_t status; + void* reference; +}; + +void snmp_next_oid_init(struct snmp_next_oid_state *state, + const u32_t *start_oid, u8_t start_oid_len, + u32_t *next_oid_buf, u8_t next_oid_max_len); +u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len); +u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference); + +void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); +void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); +void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); +void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); +u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); +s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); + +#if LWIP_IPV4 +u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip); +void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid); +#endif /* LWIP_IPV4 */ +#if LWIP_IPV6 +u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip); +void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid); +#endif /* LWIP_IPV6 */ +#if LWIP_IPV4 || LWIP_IPV6 +u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid); +u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid); + +u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip); +u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port); +#endif /* LWIP_IPV4 || LWIP_IPV6 */ + +struct netif; +u8_t netif_to_num(const struct netif *netif); + +snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */ + +err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value); +err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value); +u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count); +u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value); + +struct snmp_statistics +{ + u32_t inpkts; + u32_t outpkts; + u32_t inbadversions; + u32_t inbadcommunitynames; + u32_t inbadcommunityuses; + u32_t inasnparseerrs; + u32_t intoobigs; + u32_t innosuchnames; + u32_t inbadvalues; + u32_t inreadonlys; + u32_t ingenerrs; + u32_t intotalreqvars; + u32_t intotalsetvars; + u32_t ingetrequests; + u32_t ingetnexts; + u32_t insetrequests; + u32_t ingetresponses; + u32_t intraps; + u32_t outtoobigs; + u32_t outnosuchnames; + u32_t outbadvalues; + u32_t outgenerrs; + u32_t outgetrequests; + u32_t outgetnexts; + u32_t outsetrequests; + u32_t outgetresponses; + u32_t outtraps; +}; + +extern struct snmp_statistics snmp_stats; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_APPS_SNMP_CORE_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_mib2.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_mib2.h new file mode 100644 index 0000000..2f4a689 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_mib2.h @@ -0,0 +1,78 @@ +/** + * @file + * SNMP MIB2 API + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Dirk Ziegelmeier + * + */ +#ifndef LWIP_HDR_APPS_SNMP_MIB2_H +#define LWIP_HDR_APPS_SNMP_MIB2_H + +#include "lwip/apps/snmp_opts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ +#if SNMP_LWIP_MIB2 + +#include "lwip/apps/snmp_core.h" + +extern const struct snmp_mib mib2; + +#if SNMP_USE_NETCONN +#include "lwip/apps/snmp_threadsync.h" +void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg); +extern struct snmp_threadsync_instance snmp_mib2_lwip_locks; +#endif + +#ifndef SNMP_SYSSERVICES +#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) +#endif + +void snmp_mib2_set_sysdescr(const u8_t* str, const u16_t* len); /* read-only be defintion */ +void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); +void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen); +void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); +void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen); +void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); +void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen); + +#endif /* SNMP_LWIP_MIB2 */ +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNMP_MIB2_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_opts.h new file mode 100644 index 0000000..6c9ba7b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_opts.h @@ -0,0 +1,293 @@ +/** + * @file + * SNMP server options list + */ + +/* + * Copyright (c) 2015 Dirk Ziegelmeier + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Dirk Ziegelmeier + * + */ +#ifndef LWIP_HDR_SNMP_OPTS_H +#define LWIP_HDR_SNMP_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup snmp_opts Options + * @ingroup snmp + * @{ + */ + +/** + * LWIP_SNMP==1: This enables the lwIP SNMP agent. UDP must be available + * for SNMP transport. + * If you want to use your own SNMP agent, leave this disabled. + * To integrate MIB2 of an external agent, you need to enable + * LWIP_MIB2_CALLBACKS and MIB2_STATS. This will give you the callbacks + * and statistics counters you need to get MIB2 working. + */ +#if !defined LWIP_SNMP || defined __DOXYGEN__ +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_USE_NETCONN: Use netconn API instead of raw API. + * Makes SNMP agent run in a worker thread, so blocking operations + * can be done in MIB calls. + */ +#if !defined SNMP_USE_NETCONN || defined __DOXYGEN__ +#define SNMP_USE_NETCONN 0 +#endif + +/** + * SNMP_USE_RAW: Use raw API. + * SNMP agent does not run in a worker thread, so blocking operations + * should not be done in MIB calls. + */ +#if !defined SNMP_USE_RAW || defined __DOXYGEN__ +#define SNMP_USE_RAW 1 +#endif + +#if SNMP_USE_NETCONN && SNMP_USE_RAW +#error SNMP stack can use only one of the APIs {raw, netconn} +#endif + +#if LWIP_SNMP && !SNMP_USE_NETCONN && !SNMP_USE_RAW +#error SNMP stack needs a receive API and UDP {raw, netconn} +#endif + +#if SNMP_USE_NETCONN +/** + * SNMP_STACK_SIZE: Stack size of SNMP netconn worker thread + */ +#if !defined SNMP_STACK_SIZE || defined __DOXYGEN__ +#define SNMP_STACK_SIZE DEFAULT_THREAD_STACKSIZE +#endif + +/** + * SNMP_THREAD_PRIO: SNMP netconn worker thread priority + */ +#if !defined SNMP_THREAD_PRIO || defined __DOXYGEN__ +#define SNMP_THREAD_PRIO DEFAULT_THREAD_PRIO +#endif +#endif /* SNMP_USE_NETCONN */ + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#if !defined SNMP_TRAP_DESTINATIONS || defined __DOXYGEN__ +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#if !defined SNMP_SAFE_REQUESTS || defined __DOXYGEN__ +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. + */ +#if !defined SNMP_MAX_OCTET_STRING_LEN || defined __DOXYGEN__ +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum number of Sub ID's inside an object identifier. + * Indirectly this also limits the maximum depth of SNMP tree. + */ +#if !defined SNMP_MAX_OBJ_ID_LEN || defined __DOXYGEN__ +#define SNMP_MAX_OBJ_ID_LEN 50 +#endif + +#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__ +/** + * The maximum size of a value. + */ +#define SNMP_MIN_VALUE_SIZE (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */ +/** + * The minimum size of a value. + */ +#define SNMP_MAX_VALUE_SIZE LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE) +#endif + +/** + * The snmp read-access community. Used for write-access and traps, too + * unless SNMP_COMMUNITY_WRITE or SNMP_COMMUNITY_TRAP are enabled, respectively. + */ +#if !defined SNMP_COMMUNITY || defined __DOXYGEN__ +#define SNMP_COMMUNITY "public" +#endif + +/** + * The snmp write-access community. + * Set this community to "" in order to disallow any write access. + */ +#if !defined SNMP_COMMUNITY_WRITE || defined __DOXYGEN__ +#define SNMP_COMMUNITY_WRITE "private" +#endif + +/** + * The snmp community used for sending traps. + */ +#if !defined SNMP_COMMUNITY_TRAP || defined __DOXYGEN__ +#define SNMP_COMMUNITY_TRAP "public" +#endif + +/** + * The maximum length of community string. + * If community names shall be adjusted at runtime via snmp_set_community() calls, + * enter here the possible maximum length (+1 for terminating null character). + */ +#if !defined SNMP_MAX_COMMUNITY_STR_LEN || defined __DOXYGEN__ +#define SNMP_MAX_COMMUNITY_STR_LEN LWIP_MAX(LWIP_MAX(sizeof(SNMP_COMMUNITY), sizeof(SNMP_COMMUNITY_WRITE)), sizeof(SNMP_COMMUNITY_TRAP)) +#endif + +/** + * The OID identifiying the device. This may be the enterprise OID itself or any OID located below it in tree. + */ +#if !defined SNMP_DEVICE_ENTERPRISE_OID || defined __DOXYGEN__ +#define SNMP_LWIP_ENTERPRISE_OID 26381 +/** + * IANA assigned enterprise ID for lwIP is 26381 + * @see http://www.iana.org/assignments/enterprise-numbers + * + * @note this enterprise ID is assigned to the lwIP project, + * all object identifiers living under this ID are assigned + * by the lwIP maintainers! + * @note don't change this define, use snmp_set_device_enterprise_oid() + * + * If you need to create your own private MIB you'll need + * to apply for your own enterprise ID with IANA: + * http://www.iana.org/numbers.html + */ +#define SNMP_DEVICE_ENTERPRISE_OID {1, 3, 6, 1, 4, 1, SNMP_LWIP_ENTERPRISE_OID} +/** + * Length of SNMP_DEVICE_ENTERPRISE_OID + */ +#define SNMP_DEVICE_ENTERPRISE_OID_LEN 7 +#endif + +/** + * SNMP_DEBUG: Enable debugging for SNMP messages. + */ +#if !defined SNMP_DEBUG || defined __DOXYGEN__ +#define SNMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#if !defined SNMP_MIB_DEBUG || defined __DOXYGEN__ +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * Indicates if the MIB2 implementation of LWIP SNMP stack is used. + */ +#if !defined SNMP_LWIP_MIB2 || defined __DOXYGEN__ +#define SNMP_LWIP_MIB2 LWIP_SNMP +#endif + +/** + * Value return for sysDesc field of MIB2. + */ +#if !defined SNMP_LWIP_MIB2_SYSDESC || defined __DOXYGEN__ +#define SNMP_LWIP_MIB2_SYSDESC "lwIP" +#endif + +/** + * Value return for sysName field of MIB2. + * To make sysName field settable, call snmp_mib2_set_sysname() to provide the necessary buffers. + */ +#if !defined SNMP_LWIP_MIB2_SYSNAME || defined __DOXYGEN__ +#define SNMP_LWIP_MIB2_SYSNAME "FQDN-unk" +#endif + +/** + * Value return for sysContact field of MIB2. + * To make sysContact field settable, call snmp_mib2_set_syscontact() to provide the necessary buffers. + */ +#if !defined SNMP_LWIP_MIB2_SYSCONTACT || defined __DOXYGEN__ +#define SNMP_LWIP_MIB2_SYSCONTACT "" +#endif + +/** + * Value return for sysLocation field of MIB2. + * To make sysLocation field settable, call snmp_mib2_set_syslocation() to provide the necessary buffers. + */ +#if !defined SNMP_LWIP_MIB2_SYSLOCATION || defined __DOXYGEN__ +#define SNMP_LWIP_MIB2_SYSLOCATION "" +#endif + +/** + * This value is used to limit the repetitions processed in GetBulk requests (value == 0 means no limitation). + * This may be useful to limit the load for a single request. + * According to SNMP RFC 1905 it is allowed to not return all requested variables from a GetBulk request if system load would be too high. + * so the effect is that the client will do more requests to gather all data. + * For the stack this could be useful in case that SNMP processing is done in TCP/IP thread. In this situation a request with many + * repetitions could block the thread for a longer time. Setting limit here will keep the stack more responsive. + */ +#if !defined SNMP_LWIP_GETBULK_MAX_REPETITIONS || defined __DOXYGEN__ +#define SNMP_LWIP_GETBULK_MAX_REPETITIONS 0 +#endif + +/** + * @} + */ + +/* + ------------------------------------ + ---------- SNMPv3 options ---------- + ------------------------------------ +*/ + +/** + * LWIP_SNMP_V3==1: This enables EXPERIMENTAL SNMPv3 support. LWIP_SNMP must + * also be enabled. + * THIS IS UNDER DEVELOPMENT AND SHOULD NOT BE ENABLED IN PRODUCTS. + */ +#ifndef LWIP_SNMP_V3 +#define LWIP_SNMP_V3 0 +#endif + +#ifndef LWIP_SNMP_V3_CRYPTO +#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3 +#endif + +#ifndef LWIP_SNMP_V3_MBEDTLS +#define LWIP_SNMP_V3_MBEDTLS LWIP_SNMP_V3 +#endif + +#endif /* LWIP_HDR_SNMP_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_scalar.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_scalar.h new file mode 100644 index 0000000..40a060c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_scalar.h @@ -0,0 +1,113 @@ +/** + * @file + * SNMP server MIB API to implement scalar nodes + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#ifndef LWIP_HDR_APPS_SNMP_SCALAR_H +#define LWIP_HDR_APPS_SNMP_SCALAR_H + +#include "lwip/apps/snmp_opts.h" +#include "lwip/apps/snmp_core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** basic scalar node */ +struct snmp_scalar_node +{ + /** inherited "base class" members */ + struct snmp_leaf_node node; + u8_t asn1_type; + snmp_access_t access; + node_instance_get_value_method get_value; + node_instance_set_test_method set_test; + node_instance_set_value_method set_value; +}; + + +snmp_err_t snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +snmp_err_t snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + +#define SNMP_SCALAR_CREATE_NODE(oid, access, asn1_type, get_value_method, set_test_method, set_value_method) \ + {{{ SNMP_NODE_SCALAR, (oid) }, \ + snmp_scalar_get_instance, \ + snmp_scalar_get_next_instance }, \ + (asn1_type), (access), (get_value_method), (set_test_method), (set_value_method) } + +#define SNMP_SCALAR_CREATE_NODE_READONLY(oid, asn1_type, get_value_method) SNMP_SCALAR_CREATE_NODE(oid, SNMP_NODE_INSTANCE_READ_ONLY, asn1_type, get_value_method, NULL, NULL) + +/** scalar array node - a tree node which contains scalars only as children */ +struct snmp_scalar_array_node_def +{ + u32_t oid; + u8_t asn1_type; + snmp_access_t access; +}; + +typedef s16_t (*snmp_scalar_array_get_value_method)(const struct snmp_scalar_array_node_def*, void*); +typedef snmp_err_t (*snmp_scalar_array_set_test_method)(const struct snmp_scalar_array_node_def*, u16_t, void*); +typedef snmp_err_t (*snmp_scalar_array_set_value_method)(const struct snmp_scalar_array_node_def*, u16_t, void*); + +/** basic scalar array node */ +struct snmp_scalar_array_node +{ + /** inherited "base class" members */ + struct snmp_leaf_node node; + u16_t array_node_count; + const struct snmp_scalar_array_node_def* array_nodes; + snmp_scalar_array_get_value_method get_value; + snmp_scalar_array_set_test_method set_test; + snmp_scalar_array_set_value_method set_value; +}; + +snmp_err_t snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +snmp_err_t snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + +#define SNMP_SCALAR_CREATE_ARRAY_NODE(oid, array_nodes, get_value_method, set_test_method, set_value_method) \ + {{{ SNMP_NODE_SCALAR_ARRAY, (oid) }, \ + snmp_scalar_array_get_instance, \ + snmp_scalar_array_get_next_instance }, \ + (u16_t)LWIP_ARRAYSIZE(array_nodes), (array_nodes), (get_value_method), (set_test_method), (set_value_method) } + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNMP_SCALAR_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_table.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_table.h new file mode 100644 index 0000000..4988b51 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_table.h @@ -0,0 +1,134 @@ +/** + * @file + * SNMP server MIB API to implement table nodes + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Martin Hentschel + * + */ + +#ifndef LWIP_HDR_APPS_SNMP_TABLE_H +#define LWIP_HDR_APPS_SNMP_TABLE_H + +#include "lwip/apps/snmp_opts.h" +#include "lwip/apps/snmp_core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** default (customizable) read/write table */ +struct snmp_table_col_def +{ + u32_t index; + u8_t asn1_type; + snmp_access_t access; +}; + +/** table node */ +struct snmp_table_node +{ + /** inherited "base class" members */ + struct snmp_leaf_node node; + u16_t column_count; + const struct snmp_table_col_def* columns; + snmp_err_t (*get_cell_instance)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance); + snmp_err_t (*get_next_cell_instance)(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance); + /** returns object value for the given object identifier */ + node_instance_get_value_method get_value; + /** tests length and/or range BEFORE setting */ + node_instance_set_test_method set_test; + /** sets object value, only called when set_test() was successful */ + node_instance_set_value_method set_value; +}; + +snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + +#define SNMP_TABLE_CREATE(oid, columns, get_cell_instance_method, get_next_cell_instance_method, get_value_method, set_test_method, set_value_method) \ + {{{ SNMP_NODE_TABLE, (oid) }, \ + snmp_table_get_instance, \ + snmp_table_get_next_instance }, \ + (u16_t)LWIP_ARRAYSIZE(columns), (columns), \ + (get_cell_instance_method), (get_next_cell_instance_method), \ + (get_value_method), (set_test_method), (set_value_method)} + +#define SNMP_TABLE_GET_COLUMN_FROM_OID(oid) ((oid)[1]) /* first array value is (fixed) row entry (fixed to 1) and 2nd value is column, follow3ed by instance */ + + +/** simple read-only table */ +typedef enum { + SNMP_VARIANT_VALUE_TYPE_U32, + SNMP_VARIANT_VALUE_TYPE_S32, + SNMP_VARIANT_VALUE_TYPE_PTR, + SNMP_VARIANT_VALUE_TYPE_CONST_PTR +} snmp_table_column_data_type_t; + +struct snmp_table_simple_col_def +{ + u32_t index; + u8_t asn1_type; + snmp_table_column_data_type_t data_type; /* depending of what union member is used to store the value*/ +}; + +/** simple read-only table node */ +struct snmp_table_simple_node +{ + /* inherited "base class" members */ + struct snmp_leaf_node node; + u16_t column_count; + const struct snmp_table_simple_col_def* columns; + snmp_err_t (*get_cell_value)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len); + snmp_err_t (*get_next_cell_instance_and_value)(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len); +}; + +snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + +#define SNMP_TABLE_CREATE_SIMPLE(oid, columns, get_cell_value_method, get_next_cell_instance_and_value_method) \ + {{{ SNMP_NODE_TABLE, (oid) }, \ + snmp_table_simple_get_instance, \ + snmp_table_simple_get_next_instance }, \ + (u16_t)LWIP_ARRAYSIZE(columns), (columns), (get_cell_value_method), (get_next_cell_instance_and_value_method) } + +s16_t snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value); +s16_t snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value); +s16_t snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value); + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNMP_TABLE_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_threadsync.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_threadsync.h new file mode 100644 index 0000000..a25dbf2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmp_threadsync.h @@ -0,0 +1,114 @@ +/** + * @file + * SNMP server MIB API to implement thread synchronization + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Dirk Ziegelmeier + * + */ + +#ifndef LWIP_HDR_APPS_SNMP_THREADSYNC_H +#define LWIP_HDR_APPS_SNMP_THREADSYNC_H + +#include "lwip/apps/snmp_opts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/apps/snmp_core.h" +#include "lwip/sys.h" + +typedef void (*snmp_threadsync_called_fn)(void* arg); +typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg); + + +/** Thread sync runtime data. For internal usage only. */ +struct threadsync_data +{ + union { + snmp_err_t err; + s16_t s16; + } retval; + union { + const u32_t *root_oid; + void *value; + } arg1; + union { + u8_t root_oid_len; + u16_t len; + } arg2; + const struct snmp_threadsync_node *threadsync_node; + struct snmp_node_instance proxy_instance; +}; + +/** Thread sync instance. Needed EXCATLY once for every thread to be synced into. */ +struct snmp_threadsync_instance +{ + sys_sem_t sem; + sys_mutex_t sem_usage_mutex; + snmp_threadsync_synchronizer_fn sync_fn; + struct threadsync_data data; +}; + +/** SNMP thread sync proxy leaf node */ +struct snmp_threadsync_node +{ + /* inherited "base class" members */ + struct snmp_leaf_node node; + + const struct snmp_leaf_node *target; + struct snmp_threadsync_instance *instance; +}; + +snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); +snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); + +/** Create thread sync proxy node */ +#define SNMP_CREATE_THREAD_SYNC_NODE(oid, target_leaf_node, threadsync_instance) \ + {{{ SNMP_NODE_THREADSYNC, (oid) }, \ + snmp_threadsync_get_instance, \ + snmp_threadsync_get_next_instance }, \ + (target_leaf_node), \ + (threadsync_instance) } + +/** Create thread sync instance data */ +void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn); + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNMP_THREADSYNC_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmpv3.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmpv3.h new file mode 100644 index 0000000..c99fed4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/snmpv3.h @@ -0,0 +1,90 @@ +/** + * @file + * Additional SNMPv3 functionality RFC3414 and RFC3826. + */ + +/* + * Copyright (c) 2016 Elias Oenal. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Elias Oenal + */ + +#ifndef LWIP_HDR_APPS_SNMP_V3_H +#define LWIP_HDR_APPS_SNMP_V3_H + +#include "lwip/apps/snmp_opts.h" +#include "lwip/err.h" + +#if LWIP_SNMP && LWIP_SNMP_V3 + +#define SNMP_V3_AUTH_ALGO_INVAL 0 +#define SNMP_V3_AUTH_ALGO_MD5 1 +#define SNMP_V3_AUTH_ALGO_SHA 2 + +#define SNMP_V3_PRIV_ALGO_INVAL 0 +#define SNMP_V3_PRIV_ALGO_DES 1 +#define SNMP_V3_PRIV_ALGO_AES 2 + +#define SNMP_V3_PRIV_MODE_DECRYPT 0 +#define SNMP_V3_PRIV_MODE_ENCRYPT 1 + +/* + * The following callback functions must be implemented by the application. + * There is a dummy implementation in snmpv3_dummy.c. + */ + +void snmpv3_get_engine_id(const char **id, u8_t *len); +err_t snmpv3_set_engine_id(const char* id, u8_t len); + +u32_t snmpv3_get_engine_boots(void); +void snmpv3_set_engine_boots(u32_t boots); + +u32_t snmpv3_get_engine_time(void); +void snmpv3_reset_engine_time(void); + +err_t snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key); + +/* The following functions are provided by the SNMPv3 agent */ + +void snmpv3_engine_id_changed(void); + +void snmpv3_password_to_key_md5( + const u8_t *password, /* IN */ + u8_t passwordlen, /* IN */ + const u8_t *engineID, /* IN - pointer to snmpEngineID */ + u8_t engineLength, /* IN - length of snmpEngineID */ + u8_t *key); /* OUT - pointer to caller 16-octet buffer */ + +void snmpv3_password_to_key_sha( + const u8_t *password, /* IN */ + u8_t passwordlen, /* IN */ + const u8_t *engineID, /* IN - pointer to snmpEngineID */ + u8_t engineLength, /* IN - length of snmpEngineID */ + u8_t *key); /* OUT - pointer to caller 20-octet buffer */ + +#endif + +#endif /* LWIP_HDR_APPS_SNMP_V3_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp.h new file mode 100644 index 0000000..40df9cc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp.h @@ -0,0 +1,76 @@ +/** + * @file + * SNTP client API + */ + +/* + * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Frédéric Bernon, Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_APPS_SNTP_H +#define LWIP_HDR_APPS_SNTP_H + +#include "lwip/apps/sntp_opts.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* SNTP operating modes: default is to poll using unicast. + The mode has to be set before calling sntp_init(). */ +#define SNTP_OPMODE_POLL 0 +#define SNTP_OPMODE_LISTENONLY 1 +void sntp_setoperatingmode(u8_t operating_mode); +u8_t sntp_getoperatingmode(void); + +void sntp_init(void); +void sntp_stop(void); +u8_t sntp_enabled(void); + +void sntp_setserver(u8_t idx, const ip_addr_t *addr); +const ip_addr_t* sntp_getserver(u8_t idx); + +#if SNTP_SERVER_DNS +void sntp_setservername(u8_t idx, char *server); +char *sntp_getservername(u8_t idx); +#endif /* SNTP_SERVER_DNS */ + +#if SNTP_GET_SERVERS_FROM_DHCP +void sntp_servermode_dhcp(int set_servers_from_dhcp); +#else /* SNTP_GET_SERVERS_FROM_DHCP */ +#define sntp_servermode_dhcp(x) +#endif /* SNTP_GET_SERVERS_FROM_DHCP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_SNTP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp_opts.h new file mode 100644 index 0000000..f3651f9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/sntp_opts.h @@ -0,0 +1,173 @@ +/** + * @file + * SNTP client options list + */ + +/* + * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Frédéric Bernon, Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_APPS_SNTP_OPTS_H +#define LWIP_HDR_APPS_SNTP_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup sntp_opts Options + * @ingroup sntp + * @{ + */ + +/** SNTP macro to change system time in seconds + * Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds instead of this one + * if you need the additional precision. + */ +#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__ +#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec) +#endif + +/** The maximum number of SNTP servers that can be set */ +#if !defined SNTP_MAX_SERVERS || defined __DOXYGEN__ +#define SNTP_MAX_SERVERS LWIP_DHCP_MAX_NTP_SERVERS +#endif + +/** Set this to 1 to implement the callback function called by dhcp when + * NTP servers are received. */ +#if !defined SNTP_GET_SERVERS_FROM_DHCP || defined __DOXYGEN__ +#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV +#endif + +/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers + * One server address/name can be defined as default if SNTP_SERVER_DNS == 1: + * \#define SNTP_SERVER_ADDRESS "pool.ntp.org" + */ +#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__ +#define SNTP_SERVER_DNS 0 +#endif + +/** + * SNTP_DEBUG: Enable debugging for SNTP. + */ +#if !defined SNTP_DEBUG || defined __DOXYGEN__ +#define SNTP_DEBUG LWIP_DBG_OFF +#endif + +/** SNTP server port */ +#if !defined SNTP_PORT || defined __DOXYGEN__ +#define SNTP_PORT 123 +#endif + +/** Set this to 1 to allow config of SNTP server(s) by DNS name */ +#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__ +#define SNTP_SERVER_DNS 0 +#endif + +/** Sanity check: + * Define this to + * - 0 to turn off sanity checks (default; smaller code) + * - >= 1 to check address and port of the response packet to ensure the + * response comes from the server we sent the request to. + * - >= 2 to check returned Originate Timestamp against Transmit Timestamp + * sent to the server (to ensure response to older request). + * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp + * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast). + * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each + * greater than or equal to 0 and less than infinity, where infinity is + * currently a cozy number like one second. This check avoids using a + * server whose synchronization source has expired for a very long time. + */ +#if !defined SNTP_CHECK_RESPONSE || defined __DOXYGEN__ +#define SNTP_CHECK_RESPONSE 0 +#endif + +/** According to the RFC, this shall be a random delay + * between 1 and 5 minutes (in milliseconds) to prevent load peaks. + * This can be defined to a random generation function, + * which must return the delay in milliseconds as u32_t. + * Turned off by default. + */ +#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__ +#define SNTP_STARTUP_DELAY 0 +#endif + +/** If you want the startup delay to be a function, define this + * to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1. + */ +#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__ +#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY +#endif + +/** SNTP receive timeout - in milliseconds + * Also used as retry timeout - this shouldn't be too low. + * Default is 3 seconds. + */ +#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__ +#define SNTP_RECV_TIMEOUT 3000 +#endif + +/** SNTP update delay - in milliseconds + * Default is 1 hour. Must not be beolw 15 seconds by specification (i.e. 15000) + */ +#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__ +#define SNTP_UPDATE_DELAY 3600000 +#endif + +/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2 + * to send in request and compare in response. + */ +#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__ +#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0) +#endif + +/** Default retry timeout (in milliseconds) if the response + * received is invalid. + * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached. + */ +#if !defined SNTP_RETRY_TIMEOUT || defined __DOXYGEN__ +#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT +#endif + +/** Maximum retry timeout (in milliseconds). */ +#if !defined SNTP_RETRY_TIMEOUT_MAX || defined __DOXYGEN__ +#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10) +#endif + +/** Increase retry timeout with every retry sent + * Default is on to conform to RFC. + */ +#if !defined SNTP_RETRY_TIMEOUT_EXP || defined __DOXYGEN__ +#define SNTP_RETRY_TIMEOUT_EXP 1 +#endif + +/** + * @} + */ + +#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_opts.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_opts.h new file mode 100644 index 0000000..6968a80 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_opts.h @@ -0,0 +1,105 @@ +/****************************************************************//** + * + * @file tftp_opts.h + * + * @author Logan Gunthorpe + * + * @brief Trivial File Transfer Protocol (RFC 1350) implementation options + * + * Copyright (c) Deltatee Enterprises Ltd. 2013 + * All rights reserved. + * + ********************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification,are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Logan Gunthorpe + * + */ + +#ifndef LWIP_HDR_APPS_TFTP_OPTS_H +#define LWIP_HDR_APPS_TFTP_OPTS_H + +#include "lwip/opt.h" + +/** + * @defgroup tftp_opts Options + * @ingroup tftp + * @{ + */ + +/** + * Enable TFTP debug messages + */ +#if !defined TFTP_DEBUG || defined __DOXYGEN__ +#define TFTP_DEBUG LWIP_DBG_ON +#endif + +/** + * TFTP server port + */ +#if !defined TFTP_PORT || defined __DOXYGEN__ +#define TFTP_PORT 69 +#endif + +/** + * TFTP timeout + */ +#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__ +#define TFTP_TIMEOUT_MSECS 10000 +#endif + +/** + * Max. number of retries when a file is read from server + */ +#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__ +#define TFTP_MAX_RETRIES 5 +#endif + +/** + * TFTP timer cyclic interval + */ +#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__ +#define TFTP_TIMER_MSECS 50 +#endif + +/** + * Max. length of TFTP filename + */ +#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__ +#define TFTP_MAX_FILENAME_LEN 20 +#endif + +/** + * Max. length of TFTP mode + */ +#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__ +#define TFTP_MAX_MODE_LEN 7 +#endif + +/** + * @} + */ + +#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_server.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_server.h new file mode 100644 index 0000000..3fbe701 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/apps/tftp_server.h @@ -0,0 +1,94 @@ +/****************************************************************//** + * + * @file tftp_server.h + * + * @author Logan Gunthorpe + * + * @brief Trivial File Transfer Protocol (RFC 1350) + * + * Copyright (c) Deltatee Enterprises Ltd. 2013 + * All rights reserved. + * + ********************************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification,are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Author: Logan Gunthorpe + * + */ + +#ifndef LWIP_HDR_APPS_TFTP_SERVER_H +#define LWIP_HDR_APPS_TFTP_SERVER_H + +#include "lwip/apps/tftp_opts.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @ingroup tftp + * TFTP context containing callback functions for TFTP transfers + */ +struct tftp_context { + /** + * Open file for read/write. + * @param fname Filename + * @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail) + * @param write Flag indicating read (0) or write (!= 0) access + * @returns File handle supplied to other functions + */ + void* (*open)(const char* fname, const char* mode, u8_t write); + /** + * Close file handle + * @param handle File handle returned by open() + */ + void (*close)(void* handle); + /** + * Read from file + * @param handle File handle returned by open() + * @param buf Target buffer to copy read data to + * @param bytes Number of bytes to copy to buf + * @returns >= 0: Success; < 0: Error + */ + int (*read)(void* handle, void* buf, int bytes); + /** + * Write to file + * @param handle File handle returned by open() + * @param pbuf PBUF adjusted such that payload pointer points + * to the beginning of write data. In other words, + * TFTP headers are stripped off. + * @returns >= 0: Success; < 0: Error + */ + int (*write)(void* handle, struct pbuf* p); +}; + +err_t tftp_init(const struct tftp_context* ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/arch.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/arch.h new file mode 100644 index 0000000..4d6df77 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/arch.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ARCH_H__ +#define __LWIP_ARCH_H__ + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#include "arch/cc.h" + +/** Temporary: define format string for size_t if not defined in cc.h */ +#ifndef SZT_F +#define SZT_F U32_F +#endif /* SZT_F */ +/** Temporary upgrade helper: define format string for u8_t as hex if not + defined in cc.h */ +#ifndef X8_F +#define X8_F "02x" +#endif /* X8_F */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PACK_STRUCT_BEGIN +#define PACK_STRUCT_BEGIN +#endif /* PACK_STRUCT_BEGIN */ + +#ifndef PACK_STRUCT_END +#define PACK_STRUCT_END +#endif /* PACK_STRUCT_END */ + +#ifndef PACK_STRUCT_FIELD +#define PACK_STRUCT_FIELD(x) x +#endif /* PACK_STRUCT_FIELD */ + + +#ifndef LWIP_UNUSED_ARG +#define LWIP_UNUSED_ARG(x) (void)x +#endif /* LWIP_UNUSED_ARG */ + + +#ifdef LWIP_PROVIDE_ERRNO + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#ifndef errno +extern int errno; +#endif + +#endif /* LWIP_PROVIDE_ERRNO */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ARCH_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/debug.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/debug.h new file mode 100644 index 0000000..346e0f0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/debug.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEBUG_H__ +#define __LWIP_DEBUG_H__ + +#include "lwip/arch.h" +#include "lwip/opt.h" +#include //Realtek add +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + +#ifndef LWIP_NOASSERT +#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ + LWIP_PLATFORM_ASSERT(message); } while(0) +#else /* LWIP_NOASSERT */ +#define LWIP_ASSERT(message, assertion) +#endif /* LWIP_NOASSERT */ + +/** if "expression" isn't true, then print "message" and execute "handler" expression */ +#ifndef LWIP_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + LWIP_PLATFORM_ASSERT(message); handler;}} while(0) +#endif /* LWIP_ERROR */ + +#if LWIP_DEBUG +//#ifdef LWIP_DEBUG +/** print debug message only if debug message type is enabled... + * AND is of correct type AND is at least LWIP_DBG_LEVEL + */ + + +#define LWIP_PLATFORM_DIAG printf //Realtek add +#define LWIP_DEBUGF(debug, message) do { \ + if ( \ + ((debug) & LWIP_DBG_ON) && \ + ((debug) & LWIP_DBG_TYPES_ON) && \ + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + LWIP_PLATFORM_DIAG message; \ + if ((debug) & LWIP_DBG_HALT) { \ + while(1); \ + } \ + } \ + } while(0) + +#else /* LWIP_DEBUG */ +#define LWIP_DEBUGF(debug, message) +#endif /* LWIP_DEBUG */ + +#endif /* __LWIP_DEBUG_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/def.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/def.h new file mode 100644 index 0000000..73a1b56 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/def.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_DEF_H__ +#define __LWIP_DEF_H__ + +/* arch.h might define NULL already */ +#include "lwip/arch.h" +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) +#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define LWIP_MAKE_U16(a, b) ((a << 8) | b) +#else +#define LWIP_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#ifndef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ + +#ifdef htons +#undef htons +#endif /* htons */ +#ifdef htonl +#undef htonl +#endif /* htonl */ +#ifdef ntohs +#undef ntohs +#endif /* ntohs */ +#ifdef ntohl +#undef ntohl +#endif /* ntohl */ + +#define htons(x) lwip_htons(x) +#define ntohs(x) lwip_ntohs(x) +#define htonl(x) lwip_htonl(x) +#define ntohl(x) lwip_ntohl(x) +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ + +#if BYTE_ORDER == BIG_ENDIAN +#define lwip_htons(x) (x) +#define lwip_ntohs(x) (x) +#define lwip_htonl(x) (x) +#define lwip_ntohl(x) (x) +#define PP_HTONS(x) (x) +#define PP_NTOHS(x) (x) +#define PP_HTONL(x) (x) +#define PP_NTOHL(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#if LWIP_PLATFORM_BYTESWAP +#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) +#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) +#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) +#else /* LWIP_PLATFORM_BYTESWAP */ +u16_t lwip_htons(u16_t x); +u16_t lwip_ntohs(u16_t x); +u32_t lwip_htonl(u32_t x); +u32_t lwip_ntohl(u32_t x); +#endif /* LWIP_PLATFORM_BYTESWAP */ + +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define PP_NTOHL(x) PP_HTONL(x) + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_DEF_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dhcp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dhcp.h new file mode 100644 index 0000000..c8a8761 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dhcp.h @@ -0,0 +1,249 @@ +/** @file + */ + +#ifndef __LWIP_DHCP_H__ +#define __LWIP_DHCP_H__ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** period (in seconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_SECS 60 +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +#define DHCP_FINE_TIMER_MSECS 500 + +#define DHCP_CHADDR_LEN 16U +#define DHCP_SNAME_LEN 64U +#define DHCP_FILE_LEN 128U + +struct dhcp +{ + /** transaction identifier of last sent request */ + u32_t xid; + /** our connection to the DHCP server */ + struct udp_pcb *pcb; + /** incoming msg */ + struct dhcp_msg *msg_in; + /** current DHCP state machine state */ + u8_t state; + /** retries of current request */ + u8_t tries; +#if LWIP_DHCP_AUTOIP_COOP + u8_t autoip_coop_state; +#endif + u8_t subnet_mask_given; + + struct pbuf *p_out; /* pbuf of outcoming msg */ + struct dhcp_msg *msg_out; /* outgoing msg */ + u16_t options_out_len; /* outgoing msg options length */ + u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ + u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ + u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ + u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ + ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ + ip_addr_t offered_ip_addr; + ip_addr_t offered_sn_mask; + ip_addr_t offered_gw_addr; + ip_addr_t offered_bc_addr; + + u32_t offered_t0_lease; /* lease period (in seconds) */ + u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5% of lease period) */ + /* @todo: LWIP_DHCP_BOOTP_FILE configuration option? + integrate with possible TFTP-client for booting? */ +#if LWIP_DHCP_BOOTP_FILE + ip_addr_t offered_si_addr; + char boot_file_name[DHCP_FILE_LEN]; +#endif /* LWIP_DHCP_BOOTPFILE */ +}; + +/* MUST be compiled with "pack structs" or equivalent! */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FIELD(u8_t op); + PACK_STRUCT_FIELD(u8_t htype); + PACK_STRUCT_FIELD(u8_t hlen); + PACK_STRUCT_FIELD(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(ip_addr_p_t ciaddr); + PACK_STRUCT_FIELD(ip_addr_p_t yiaddr); + PACK_STRUCT_FIELD(ip_addr_p_t siaddr); + PACK_STRUCT_FIELD(ip_addr_p_t giaddr); + PACK_STRUCT_FIELD(u8_t chaddr[DHCP_CHADDR_LEN]); + PACK_STRUCT_FIELD(u8_t sname[DHCP_SNAME_LEN]); + PACK_STRUCT_FIELD(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FIELD(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); +/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ +#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) +void dhcp_cleanup(struct netif *netif); +/** start DHCP configuration */ +err_t dhcp_start(struct netif *netif); +/** enforce early lease renewal (not needed normally)*/ +err_t dhcp_renew(struct netif *netif); +/** release the DHCP lease, usually called before dhcp_stop()*/ +err_t dhcp_release(struct netif *netif); +/** stop DHCP configuration */ +void dhcp_stop(struct netif *netif); +/** inform server of our manual IP address */ +void dhcp_inform(struct netif *netif); +/** Handle a possible change in the network configuration */ +void dhcp_network_changed(struct netif *netif); + +/** if enabled, check whether the offered IP address is not in use, using ARP */ +#if DHCP_DOES_ARP_CHECK +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); +#endif + +/** to be called every minute */ +void dhcp_coarse_tmr(void); +/** to be called every half second */ +void dhcp_fine_tmr(void); + +err_t dhcp_release_unicast(struct netif *netif); + +/** DHCP message item offsets and length */ +#define DHCP_OP_OFS 0 +#define DHCP_HTYPE_OFS 1 +#define DHCP_HLEN_OFS 2 +#define DHCP_HOPS_OFS 3 +#define DHCP_XID_OFS 4 +#define DHCP_SECS_OFS 8 +#define DHCP_FLAGS_OFS 10 +#define DHCP_CIADDR_OFS 12 +#define DHCP_YIADDR_OFS 16 +#define DHCP_SIADDR_OFS 20 +#define DHCP_GIADDR_OFS 24 +#define DHCP_CHADDR_OFS 28 +#define DHCP_SNAME_OFS 44 +#define DHCP_FILE_OFS 108 +#define DHCP_MSG_LEN 236 + +#define DHCP_COOKIE_OFS DHCP_MSG_LEN +#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +/** DHCP client states */ +#define DHCP_OFF 0 +#define DHCP_REQUESTING 1 +#define DHCP_INIT 2 +#define DHCP_REBOOTING 3 +#define DHCP_REBINDING 4 +#define DHCP_RENEWING 5 +#define DHCP_SELECTING 6 +#define DHCP_INFORMING 7 +#define DHCP_CHECKING 8 +#define DHCP_PERMANENT 9 +#define DHCP_BOUND 10 +#define DHCP_RELEASING 11 //Realtek modified +#define DHCP_BACKING_OFF 12 + +/** AUTOIP cooperatation flags */ +#define DHCP_AUTOIP_COOP_STATE_OFF 0 +#define DHCP_AUTOIP_COOP_STATE_ON 1 + +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/** DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/** DHCP hardware type, currently only ethernet is supported */ +#define DHCP_HTYPE_ETH 1 + +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ + +/** BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_END 255 + +/** DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/** possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DHCP */ + +#endif /*__LWIP_DHCP_H__*/ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dns.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dns.h new file mode 100644 index 0000000..23646ed --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/dns.h @@ -0,0 +1,163 @@ +/** + * lwip DNS resolver header file. + + * Author: Jim Pettinato + * April 2007 + + * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LWIP_DNS_H__ +#define __LWIP_DNS_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** DNS timer period */ +#define DNS_TMR_INTERVAL 1000 + +/** DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ + +/** DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +/* DNS protocol flags */ +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + +/* DNS protocol states */ +#define DNS_STATE_UNUSED 0 +#define DNS_STATE_NEW 1 +#define DNS_STATE_ASKING 2 +#define DNS_STATE_DONE 3 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS message header */ +struct dns_hdr { + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u8_t flags1); + PACK_STRUCT_FIELD(u8_t flags2); + PACK_STRUCT_FIELD(u16_t numquestions); + PACK_STRUCT_FIELD(u16_t numanswers); + PACK_STRUCT_FIELD(u16_t numauthrr); + PACK_STRUCT_FIELD(u16_t numextrarr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_HDR 12 + +/* The size used for the next line is rather a hack, but it prevents including socket.h in all files + that include memp.h, and that would possibly break portability (since socket.h defines some types + and constants possibly already define by the OS). + Calculation rule: + sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1 byte zero-termination */ +#define NETDB_ELEM_SIZE (32 + 16 + DNS_MAX_NAME_LENGTH + 1) + +#if DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + ip_addr_t addr; + struct local_hostlist_entry *next; +}; +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN +#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH +#endif +#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** Callback which is invoked when a hostname is found. + * A function of this type must be implemented by the application using the DNS resolver. + * @param name pointer to the name that was looked up. + * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, + * or NULL if the name could not be found (or on any other error). + * @param callback_arg a user-specified callback argument passed to dns_gethostbyname +*/ +typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +void dns_init(void); +void dns_tmr(void); +void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); +ip_addr_t dns_getserver(u8_t numdns); +err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, + dns_found_callback found, void *callback_arg); + +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehost(const char *hostname, const ip_addr_t *addr); +err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS */ + +#endif /* __LWIP_DNS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/err.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/err.h new file mode 100644 index 0000000..ac90772 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/err.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_ERR_H__ +#define __LWIP_ERR_H__ + +#include "lwip/opt.h" +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define LWIP_ERR_T in cc.h if you want to use + * a different type for your platform (must be signed). */ +#ifdef LWIP_ERR_T +typedef LWIP_ERR_T err_t; +#else /* LWIP_ERR_T */ +typedef s8_t err_t; +#endif /* LWIP_ERR_T*/ + +/* Definitions for error constants. */ + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ +#define ERR_INPROGRESS -5 /* Operation in progress */ +#define ERR_VAL -6 /* Illegal value. */ +#define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ +#define ERR_ISCONN -9 /* Already connected. */ + +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_ABRT -10 /* Connection aborted. */ +#define ERR_RST -11 /* Connection reset. */ +#define ERR_CLSD -12 /* Connection closed. */ +#define ERR_CONN -13 /* Not connected. */ + +#define ERR_ARG -14 /* Illegal argument. */ + +#define ERR_IF -15 /* Low-level netif error */ + + +#ifdef LWIP_DEBUG +extern const char *lwip_strerr(err_t err); +#else +#define lwip_strerr(x) "" +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_ERR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/init.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/init.h new file mode 100644 index 0000000..3238534 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/init.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_INIT_H__ +#define __LWIP_INIT_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** X.x.x: Major version of the stack */ +#define LWIP_VERSION_MAJOR 1U +/** x.X.x: Minor version of the stack */ +#define LWIP_VERSION_MINOR 4U +/** x.x.X: Revision of the stack */ +#define LWIP_VERSION_REVISION 1U +/** For release candidates, this is set to 1..254 + * For official releases, this is set to 255 (LWIP_RC_RELEASE) + * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ +#define LWIP_VERSION_RC 255U + +/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ +#define LWIP_RC_RELEASE 255U +/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ +#define LWIP_RC_DEVELOPMENT 0U + +#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) +#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) +#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) + +/** Provides the version of the stack */ +#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ + LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) + +/* Modules initialization */ +void lwip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_INIT_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/lwip_timers.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/lwip_timers.h new file mode 100644 index 0000000..dbb9dbc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/lwip_timers.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ +#ifndef __LWIP_TIMERS_H__ +#define __LWIP_TIMERS_H__ + +#include "lwip/opt.h" + +/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ +#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) + +#if LWIP_TIMERS + +#include "lwip/err.h" +#if !NO_SYS +#include "lwip/sys.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LWIP_DEBUG_TIMERNAMES +#ifdef LWIP_DEBUG +#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG +#else /* LWIP_DEBUG */ +#define LWIP_DEBUG_TIMERNAMES 0 +#endif /* LWIP_DEBUG*/ +#endif + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ +typedef void (* sys_timeout_handler)(void *arg); + +struct sys_timeo { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +#if LWIP_DEBUG_TIMERNAMES + const char* handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ +}; + +void sys_timeouts_init(void); + +//Realtek add +struct sys_timeouts { + struct sys_timeo *next; +}; + +struct sys_timeouts *sys_arch_timeouts(void); +//Realtek add end + +#if LWIP_DEBUG_TIMERNAMES +void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); +#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) +#else /* LWIP_DEBUG_TIMERNAMES */ +void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); +#endif /* LWIP_DEBUG_TIMERNAMES */ + +void sys_untimeout(sys_timeout_handler handler, void *arg); +#if NO_SYS +void sys_check_timeouts(void); +void sys_restart_timeouts(void); +#else /* NO_SYS */ +void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); +#endif /* NO_SYS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TIMERS */ +#endif /* __LWIP_TIMERS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/mem.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/mem.h new file mode 100644 index 0000000..5bb906b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/mem.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_MEM_H__ +#define __LWIP_MEM_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MEM_LIBC_MALLOC + +#include /* for size_t */ + +typedef size_t mem_size_t; +#define MEM_SIZE_F SZT_F + +/* aliases for C library malloc() */ +#define mem_init() +/* in case C library malloc() needs extra protection, + * allow these defines to be overridden. + */ +#ifndef mem_free +#define mem_free free +#endif +#ifndef mem_malloc +#define mem_malloc malloc +#endif +#ifndef mem_calloc +#define mem_calloc calloc +#endif +/* Since there is no C library allocation function to shrink memory without + moving it, define this to nothing. */ +#ifndef mem_trim +#define mem_trim(mem, size) (mem) +#endif +#else /* MEM_LIBC_MALLOC */ + +/* MEM_SIZE would have to be aligned, but using 64000 here instead of + * 65535 leaves some room for alignment... + */ +#if MEM_SIZE > 64000L +typedef u32_t mem_size_t; +#define MEM_SIZE_F U32_F +#else +typedef u16_t mem_size_t; +#define MEM_SIZE_F U16_F +#endif /* MEM_SIZE > 64000 */ + +#if MEM_USE_POOLS +/** mem_init is not used when using pools instead of a heap */ +#define mem_init() +/** mem_trim is not used when using pools instead of a heap: + we can't free part of a pool element and don't want to copy the rest */ +#define mem_trim(mem, size) (mem) +#else /* MEM_USE_POOLS */ +/* lwIP alternative malloc */ +void mem_init(void); +void *mem_trim(void *mem, mem_size_t size); +#endif /* MEM_USE_POOLS */ +void *mem_malloc(mem_size_t size); +void *mem_calloc(mem_size_t count, mem_size_t size); +void mem_free(void *mem); +#endif /* MEM_LIBC_MALLOC */ + +/** Calculate memory size for an aligned buffer - returns the next highest + * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and + * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). + */ +#ifndef LWIP_MEM_ALIGN_SIZE +#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)) +#endif + +/** Calculate safe memory size for an aligned buffer when using an unaligned + * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the + * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) + */ +#ifndef LWIP_MEM_ALIGN_BUFFER +#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1)) +#endif + +/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT + * so that ADDR % MEM_ALIGNMENT == 0 + */ +#ifndef LWIP_MEM_ALIGN +#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEM_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp.h new file mode 100644 index 0000000..f0d0739 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_MEMP_H__ +#define __LWIP_MEMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ +typedef enum { +#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, +#include "lwip/memp_std.h" + MEMP_MAX +} memp_t; + +#if MEM_USE_POOLS +/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ +typedef enum { + /* Get the first (via: + MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ + MEMP_POOL_HELPER_FIRST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START 1 +#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 +#define LWIP_MALLOC_MEMPOOL_END +#include "lwip/memp_std.h" + ) , + /* Get the last (via: + MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ + MEMP_POOL_HELPER_LAST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * +#define LWIP_MALLOC_MEMPOOL_END 1 +#include "lwip/memp_std.h" + ) +} memp_pool_helper_t; + +/* The actual start and stop values are here (cast them over) + We use this helper type and these defines so we can avoid using const memp_t values */ +#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) +#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) +#endif /* MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC || MEM_USE_POOLS +extern const u16_t memp_sizes[MEMP_MAX]; +#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC + +#include "mem.h" + +#define memp_init() +#define memp_malloc(type) mem_malloc(memp_sizes[type]) +#define memp_free(type, mem) mem_free(mem) + +#else /* MEMP_MEM_MALLOC */ + +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +}; +#endif /* MEM_USE_POOLS */ + +void memp_init(void); + +#if MEMP_OVERFLOW_CHECK +void *memp_malloc_fn(memp_t type, const char* file, const int line); +#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) +#else +void *memp_malloc(memp_t type); +#endif +void memp_free(memp_t type, void *mem); + +#endif /* MEMP_MEM_MALLOC */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_MEMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp_std.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp_std.h new file mode 100644 index 0000000..461ed1a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/memp_std.h @@ -0,0 +1,122 @@ +/* + * SETUP: Make sure we define everything we will need. + * + * We have create three types of pools: + * 1) MEMPOOL - standard pools + * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c + * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct + * + * If the include'r doesn't require any special treatment of each of the types + * above, then will declare #2 & #3 to be just standard mempools. + */ +#ifndef LWIP_MALLOC_MEMPOOL +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + sizeof(struct memp_malloc_helper)), "MALLOC_"#size) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL_END +#endif /* LWIP_MALLOC_MEMPOOL */ + +#ifndef LWIP_PBUF_MEMPOOL +/* This treats "pbuf pools" just like any other pool. + * Allocates buffers for a pbuf struct AND a payload size */ +#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) +#endif /* LWIP_PBUF_MEMPOOL */ + + +/* + * A list of internal pools used by LWIP. + * + * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + */ +#if LWIP_RAW +LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") +#endif /* LWIP_RAW */ + +#if LWIP_UDP +LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") +#endif /* LWIP_UDP */ + +#if LWIP_TCP +LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") +LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") +LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") +#endif /* IP_REASSEMBLY */ +#if IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") +#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +#if LWIP_NETCONN +LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") +LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") +#endif /* LWIP_NETCONN */ + +#if NO_SYS==0 +LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +#if !LWIP_TCPIP_CORE_LOCKING_INPUT +LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") +#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ +#endif /* NO_SYS==0 */ + +#if LWIP_ARP && ARP_QUEUEING +LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") +#endif /* LWIP_ARP && ARP_QUEUEING */ + +#if LWIP_IGMP +LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") +#endif /* LWIP_IGMP */ + +#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ +LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") +#endif /* LWIP_TIMERS */ + +#if LWIP_SNMP +LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") +LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") +LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") +LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") +#endif /* LWIP_SNMP */ +#if LWIP_DNS && LWIP_SOCKET +LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") +#endif /* LWIP_DNS && LWIP_SOCKET */ +#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") +#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#if PPP_SUPPORT && PPPOE_SUPPORT +LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ + +/* + * A list of pools of pbuf's used by LWIP. + * + * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + * This allocates enough space for the pbuf struct and a payload. + * (Example: pbuf_payload_size=0 allocates only size for the struct) + */ +LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") +LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") + + +/* + * Allow for user-defined pools; this must be explicitly set in lwipopts.h + * since the default is to NOT look for lwippools.h + */ +#if MEMP_USE_CUSTOM_POOLS +#include "lwippools.h" +#endif /* MEMP_USE_CUSTOM_POOLS */ + +/* + * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later + * (#undef is ignored for something that is not defined) + */ +#undef LWIP_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL_START +#undef LWIP_MALLOC_MEMPOOL_END +#undef LWIP_PBUF_MEMPOOL diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netbuf.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netbuf.h new file mode 100644 index 0000000..7d247d7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netbuf.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETBUF_H__ +#define __LWIP_NETBUF_H__ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 +/** This netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + +struct netbuf { + struct pbuf *p, *ptr; + ip_addr_t addr; + u16_t port; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + u8_t flags; +#endif /* LWIP_CHECKSUM_ON_COPY */ + u16_t toport_chksum; +#if LWIP_NETBUF_RECVINFO + ip_addr_t toaddr; +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ +}; + +/* Network buffer functions: */ +struct netbuf * netbuf_new (void); +void netbuf_delete (struct netbuf *buf); +void * netbuf_alloc (struct netbuf *buf, u16_t size); +void netbuf_free (struct netbuf *buf); +err_t netbuf_ref (struct netbuf *buf, + const void *dataptr, u16_t size); +void netbuf_chain (struct netbuf *head, + struct netbuf *tail); + +err_t netbuf_data (struct netbuf *buf, + void **dataptr, u16_t *len); +s8_t netbuf_next (struct netbuf *buf); +void netbuf_first (struct netbuf *buf); + + +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) +#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) +#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) +#define netbuf_len(buf) ((buf)->p->tot_len) +#define netbuf_fromaddr(buf) (&((buf)->addr)) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set((&(buf)->addr), fromaddr) +#define netbuf_fromport(buf) ((buf)->port) +#if LWIP_NETBUF_RECVINFO +#define netbuf_destaddr(buf) (&((buf)->toaddr)) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set((&(buf)->addr), destaddr) +#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) +#endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_CHECKSUM_ON_COPY +#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ + (buf)->toport_chksum = chksum; } while(0) +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETBUF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netdb.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netdb.h new file mode 100644 index 0000000..7587e2f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netdb.h @@ -0,0 +1,124 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIP_NETDB_H__ +#define __LWIP_NETDB_H__ + +#include "lwip/opt.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include /* for size_t */ + +#include "lwip/inet.h" +#include "lwip/sockets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* some rarely used options */ +#ifndef LWIP_DNS_API_DECLARE_H_ERRNO +#define LWIP_DNS_API_DECLARE_H_ERRNO 1 +#endif + +#ifndef LWIP_DNS_API_DEFINE_ERRORS +#define LWIP_DNS_API_DEFINE_ERRORS 1 +#endif + +#ifndef LWIP_DNS_API_DECLARE_STRUCTS +#define LWIP_DNS_API_DECLARE_STRUCTS 1 +#endif + +#if LWIP_DNS_API_DEFINE_ERRORS +/** Errors used by the DNS API functions, h_errno can be one of them */ +#define EAI_NONAME 200 +#define EAI_SERVICE 201 +#define EAI_FAIL 202 +#define EAI_MEMORY 203 + +#define HOST_NOT_FOUND 210 +#define NO_DATA 211 +#define NO_RECOVERY 212 +#define TRY_AGAIN 213 +#endif /* LWIP_DNS_API_DEFINE_ERRORS */ + +#if LWIP_DNS_API_DECLARE_STRUCTS +struct hostent { + char *h_name; /* Official name of the host. */ + char **h_aliases; /* A pointer to an array of pointers to alternative host names, + terminated by a null pointer. */ + int h_addrtype; /* Address type. */ + int h_length; /* The length, in bytes, of the address. */ + char **h_addr_list; /* A pointer to an array of pointers to network addresses (in + network byte order) for the host, terminated by a null pointer. */ +#define h_addr h_addr_list[0] /* for backward compatibility */ +}; + +struct addrinfo { + int ai_flags; /* Input flags. */ + int ai_family; /* Address family of socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol of socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address of socket. */ + char *ai_canonname; /* Canonical name of service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ + +#if LWIP_DNS_API_DECLARE_H_ERRNO +/* application accessable error code set by the DNS API functions */ +extern int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ + +struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); +void lwip_freeaddrinfo(struct addrinfo *ai); +int lwip_getaddrinfo(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + +#if LWIP_COMPAT_SOCKETS +#define gethostbyname(name) lwip_gethostbyname(name) +#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ + lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) +#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) +#define getaddrinfo(nodname, servname, hints, res) \ + lwip_getaddrinfo(nodname, servname, hints, res) +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS && LWIP_SOCKET */ + +#endif /* __LWIP_NETDB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netif.h new file mode 100644 index 0000000..fd44ec0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netif.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_NETIF_H__ +#define __LWIP_NETIF_H__ + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** must be the maximum of all used hardware address lengths + across all types of interfaces in use */ +#define NETIF_MAX_HWADDR_LEN 6U + +/** Whether the network interface is 'up'. This is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + * It is set by the startup code (for static IP configuration) or + * by dhcp/autoip when an address has been assigned. + */ +#define NETIF_FLAG_UP 0x01U +/** If set, the netif has broadcast capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_BROADCAST 0x02U +/** If set, the netif is one end of a point-to-point connection. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** If set, the interface is configured using DHCP. + * Set by the DHCP code when starting or stopping DHCP. */ +#define NETIF_FLAG_DHCP 0x08U +/** If set, the interface has an active link + * (set by the network interface driver). + * Either set by the netif driver in its init function (if the link + * is up at that time) or at a later point once the link comes up + * (if link detection is supported by the hardware). */ +#define NETIF_FLAG_LINK_UP 0x10U +/** If set, the netif is an ethernet device using ARP. + * Set by the netif driver in its init function. + * Used to check input packet types and use of DHCP. */ +#define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U +/** If set, the netif has IGMP capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_IGMP 0x80U + +#ifdef CONFIG_DONT_CARE_TP +#define NETIF_FLAG_IPSWITCH 0x100U +#endif +/** Function prototype for netif init functions. Set up flags and output/linkoutput + * callback functions in this function. + * + * @param netif The netif to initialize + */ +typedef err_t (*netif_init_fn)(struct netif *netif); +/** Function prototype for netif->input functions. This function is saved as 'input' + * callback function in the netif struct. Call it when a packet has been received. + * + * @param p The received packet, copied into a pbuf + * @param inp The netif which received the packet + */ +typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); +/** Function prototype for netif->output functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'etharp_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IP address to which the packet shall be sent + */ +typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr); +/** Function prototype for netif->linkoutput functions. Only used for ethernet + * netifs. This function is called by ARP when a packet shall be sent. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (raw ethernet packet) + */ +typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); +/** Function prototype for netif status- or link-callback functions. */ +typedef void (*netif_status_callback_fn)(struct netif *netif); +/** Function prototype for netif igmp_mac_filter functions */ +typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, + ip_addr_t *group, u8_t action); + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. */ + netif_input_fn input; + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_fn output; + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. */ + netif_linkoutput_fn linkoutput; +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + netif_status_callback_fn status_callback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + netif_status_callback_fn link_callback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK + /** This function is called when the netif has been removed */ + netif_status_callback_fn remove_callback; +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. */ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) */ + u16_t mtu; + /** number of bytes used in hwaddr */ + u8_t hwaddr_len; + /** link level hardware address of this interface */ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) */ + u8_t flags; + /** descriptive abbreviation */ + char name[2]; + /** number of this interface */ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /** This function could be called to add or delete a entry in the multicast + filter table of the ethernet MAC.*/ + netif_igmp_mac_filter_fn igmp_mac_filter; +#endif /* LWIP_IGMP */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + (netif)->link_type = (type); \ + /* your link speed here (units: bits per second) */ \ + (netif)->link_speed = (speed); \ + (netif)->ts = 0; \ + (netif)->ifinoctets = 0; \ + (netif)->ifinucastpkts = 0; \ + (netif)->ifinnucastpkts = 0; \ + (netif)->ifindiscards = 0; \ + (netif)->ifoutoctets = 0; \ + (netif)->ifoutucastpkts = 0; \ + (netif)->ifoutnucastpkts = 0; \ + (netif)->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +void netif_init(void); + +struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); + +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw); +void netif_remove(struct netif * netif); + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name); + +void netif_set_default(struct netif *netif); + +void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); +void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); +void netif_set_gw(struct netif *netif, ip_addr_t *gw); + +void netif_set_up(struct netif *netif); +void netif_set_down(struct netif *netif); +/** Ask if an interface is up */ +#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_STATUS_CALLBACK +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +void netif_set_link_up(struct netif *netif); +void netif_set_link_down(struct netif *netif); +/** Ask if a link is up */ +#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_HOSTNAME +#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) +#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IGMP +#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) +#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) +#endif /* LWIP_IGMP */ + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p, ip_addr_t *dest_ip); +void netif_poll(struct netif *netif); +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void); +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_NETIF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netifapi.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netifapi.h new file mode 100644 index 0000000..33318ef --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/netifapi.h @@ -0,0 +1,108 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_NETIFAPI_H__ +#define __LWIP_NETIFAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*netifapi_void_fn)(struct netif *netif); +typedef err_t (*netifapi_errt_fn)(struct netif *netif); + +struct netifapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + err_t err; + struct netif *netif; + union { + struct { + ip_addr_t *ipaddr; + ip_addr_t *netmask; + ip_addr_t *gw; + void *state; + netif_init_fn init; + netif_input_fn input; + } add; + struct { + netifapi_void_fn voidfunc; + netifapi_errt_fn errtfunc; + } common; + } msg; +}; + +struct netifapi_msg { + void (* function)(struct netifapi_msg_msg *msg); + struct netifapi_msg_msg msg; +}; + + +/* API for application */ +err_t netifapi_netif_add ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input); + +err_t netifapi_netif_set_addr ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw ); + +err_t netifapi_netif_common ( struct netif *netif, + netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc); + +#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) +#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) +#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) +#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) +#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) +#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) +#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) +#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETIF_API */ + +#endif /* __LWIP_NETIFAPI_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/opt.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/opt.h new file mode 100644 index 0000000..e644178 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/opt.h @@ -0,0 +1,2134 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_OPT_H__ +#define __LWIP_OPT_H__ + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 0 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 0 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * inlude path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simulateously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members et the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT) +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 50 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 30 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 2 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 3 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 16 +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 0 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 0 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving ethernet packets with VLAN header. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 0 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 1 //Realtek modified (0->1) +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + * Does not have to be changed unless external MIBs answer request asynchronously + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + * When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabeling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS message max. size. Default value is RFC compliant. */ +#ifndef DNS_MSG_SIZE +#define DNS_MSG_SIZE 512 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 0 +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE TCP_MSS +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. + */ +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accomodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquistion) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#ifndef LWIP_NETIF_REMOVE_CALLBACK +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) and loopif.c + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "TCP_IP" //Realtek modified ("tcpip_thread"->"TCP_IP") +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * PPP_THREAD_NAME: The name assigned to the pppInputThread. + */ +#ifndef PPP_THREAD_NAME +#define PPP_THREAD_NAME "pppInputThread" +#endif + +/** + * PPP_THREAD_STACKSIZE: The stack size used by the pppInputThread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_STACKSIZE +#define PPP_THREAD_STACKSIZE 0 +#endif + +/** + * PPP_THREAD_PRIO: The priority assigned to the pppInputThread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef PPP_THREAD_PRIO +#define PPP_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 1 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout tod create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 1 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#ifndef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 1 //Realtek modified(0->1) +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 1 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +#else + +#define LINK_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define ETHARP_STATS 0 //Realtek add + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +#if PPP_SUPPORT + +/** + * NUM_PPP: Max PPP sessions. + */ +#ifndef NUM_PPP +#define NUM_PPP 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 0 +#endif + +/** + * MD5_SUPPORT==1: Support MD5 (see also CHAP). + */ +#ifndef MD5_SUPPORT +#define MD5_SUPPORT 0 +#endif + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#ifndef CHECKSUM_GEN_ICMP +#define CHECKSUM_GEN_ICMP 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* Hooks are undefined by default, define them to a function if you need them. */ + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +#endif /* __LWIP_OPT_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/pbuf.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/pbuf.h new file mode 100644 index 0000000..99d5443 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/pbuf.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __LWIP_PBUF_H__ +#define __LWIP_PBUF_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the pbuf_custom code is only needed for one specific configuration + * of IP_FRAG */ +#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) + +#define PBUF_TRANSPORT_HLEN 20 +#define PBUF_IP_HLEN 20 + +typedef enum { + PBUF_TRANSPORT, + PBUF_IP, + PBUF_LINK, + PBUF_RAW +} pbuf_layer; + +typedef enum { + PBUF_RAM, /* pbuf data is stored in RAM */ + PBUF_ROM, /* pbuf data is stored in ROM */ + PBUF_REF, /* pbuf comes from the pbuf pool */ + PBUF_POOL /* pbuf payload refers to RAM */ +} pbuf_type; + + +/** indicates this packet's data should be immediately passed to the application */ +#define PBUF_FLAG_PUSH 0x01U +/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a + a pbuf differently */ +#define PBUF_FLAG_IS_CUSTOM 0x02U +/** indicates this pbuf is UDP multicast to be looped back */ +#define PBUF_FLAG_MCASTLOOP 0x04U +/** indicates this pbuf was received as link-level broadcast */ +#define PBUF_FLAG_LLBCAST 0x08U +/** indicates this pbuf was received as link-level multicast */ +#define PBUF_FLAG_LLMCAST 0x10U +/** indicates this pbuf includes a TCP FIN flag */ +#define PBUF_FLAG_TCP_FIN 0x20U + +struct pbuf { + /** next pbuf in singly linked pbuf chain */ + struct pbuf *next; + + /** pointer to the actual data in the buffer */ + void *payload; + + /** + * total length of this buffer and all next buffers in chain + * belonging to the same packet. + * + * For non-queue packet chains this is the invariant: + * p->tot_len == p->len + (p->next? p->next->tot_len: 0) + */ + u16_t tot_len; + + /** length of this buffer */ + u16_t len; + + /** pbuf_type as u8_t instead of enum to save space */ + u8_t /*pbuf_type*/ type; + + /** misc flags */ + u8_t flags; + + /** + * the reference count always equals the number of pointers + * that refer to this pbuf. This can be pointers from an application, + * the stack itself, or pbuf->next pointers from a chain. + */ + u16_t ref; +}; + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Prototype for a function to free a custom pbuf */ +typedef void (*pbuf_free_custom_fn)(struct pbuf *p); + +/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ +struct pbuf_custom { + /** The actual pbuf */ + struct pbuf pbuf; + /** This function is called when pbuf_free deallocates this pbuf(_custom) */ + pbuf_free_custom_fn custom_free_function; +}; +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +#if LWIP_TCP && TCP_QUEUE_OOSEQ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ +#if NO_SYS && PBUF_POOL_FREE_OOSEQ +extern volatile u8_t pbuf_free_ooseq_pending; +void pbuf_free_ooseq(); +/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level to check if ooseq pbufs need to be + freed! */ +#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ + /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ + ooseq queued pbufs now */ \ + pbuf_free_ooseq(); }}while(0) +#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ + +/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ +#define pbuf_init() + +struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); +#if LWIP_SUPPORT_CUSTOM_PBUF +struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, + struct pbuf_custom *p, void *payload_mem, + u16_t payload_mem_len); +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ +void pbuf_realloc(struct pbuf *p, u16_t size); +u8_t pbuf_header(struct pbuf *p, s16_t header_size); +void pbuf_ref(struct pbuf *p); +u8_t pbuf_free(struct pbuf *p); +u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *head, struct pbuf *tail); +void pbuf_chain(struct pbuf *head, struct pbuf *tail); +struct pbuf *pbuf_dechain(struct pbuf *p); +err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); +err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); +struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); +#if LWIP_CHECKSUM_ON_COPY +err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ + +u8_t pbuf_get_at(struct pbuf* p, u16_t offset); +u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); +u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); +u16_t pbuf_strstr(struct pbuf* p, const char* substr); + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_PBUF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/autoip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/autoip.h new file mode 100644 index 0000000..fd3af8a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/autoip.h @@ -0,0 +1,78 @@ +/** + * @file + * AutoIP protocol definitions + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + */ + +#ifndef LWIP_HDR_PROT_AUTOIP_H +#define LWIP_HDR_PROT_AUTOIP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* 169.254.0.0 */ +#define AUTOIP_NET 0xA9FE0000 +/* 169.254.1.0 */ +#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) +/* 169.254.254.255 */ +#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +typedef enum { + AUTOIP_STATE_OFF = 0, + AUTOIP_STATE_PROBING = 1, + AUTOIP_STATE_ANNOUNCING = 2, + AUTOIP_STATE_BOUND = 3 +} autoip_state_enum_t; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_AUTOIP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dhcp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dhcp.h new file mode 100644 index 0000000..112953c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dhcp.h @@ -0,0 +1,183 @@ +/** + * @file + * DHCP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Leon Woestenberg + * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + */ +#ifndef LWIP_HDR_PROT_DHCP_H +#define LWIP_HDR_PROT_DHCP_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + + + /* DHCP message item offsets and length */ +#define DHCP_CHADDR_LEN 16U +#define DHCP_SNAME_OFS 44U +#define DHCP_SNAME_LEN 64U +#define DHCP_FILE_OFS 108U +#define DHCP_FILE_LEN 128U +#define DHCP_MSG_LEN 236U +#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4U) /* 4 byte: cookie */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FLD_8(u8_t op); + PACK_STRUCT_FLD_8(u8_t htype); + PACK_STRUCT_FLD_8(u8_t hlen); + PACK_STRUCT_FLD_8(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr); + PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr); + PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr); + PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr); + PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]); + PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]); + PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +/* DHCP client states */ +typedef enum { + DHCP_STATE_OFF = 0, + DHCP_STATE_REQUESTING = 1, + DHCP_STATE_INIT = 2, + DHCP_STATE_REBOOTING = 3, + DHCP_STATE_REBINDING = 4, + DHCP_STATE_RENEWING = 5, + DHCP_STATE_SELECTING = 6, + DHCP_STATE_INFORMING = 7, + DHCP_STATE_CHECKING = 8, + DHCP_STATE_PERMANENT = 9, /* not yet implemented */ + DHCP_STATE_BOUND = 10, + DHCP_STATE_RELEASING = 11, /* not yet implemented */ + DHCP_STATE_BACKING_OFF = 12 +} dhcp_state_enum_t; + +/* DHCP op codes */ +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/* DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/** DHCP hardware type, currently only ethernet is supported */ +#define DHCP_HTYPE_ETH 1 + +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ + +/* BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_NTP 42 +#define DHCP_OPTION_END 255 + +/* DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/* possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + + +#ifdef __cplusplus +} +#endif + +#endif /*LWIP_HDR_PROT_DHCP_H*/ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dns.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dns.h new file mode 100644 index 0000000..94782d6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/dns.h @@ -0,0 +1,140 @@ +/** + * @file + * DNS - host name to IP address resolver. + */ + +/* + * Port to lwIP from uIP + * by Jim Pettinato April 2007 + * + * security fixes and more by Simon Goldschmidt + * + * uIP version Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LWIP_HDR_PROT_DNS_H +#define LWIP_HDR_PROT_DNS_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** DNS server port address */ +#ifndef DNS_SERVER_PORT +#define DNS_SERVER_PORT 53 +#endif + +/* DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ +#define DNS_RRTYPE_AAAA 28 /* IPv6 address */ +#define DNS_RRTYPE_SRV 33 /* service location */ +#define DNS_RRTYPE_ANY 255 /* any type */ + +/* DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_ANY 255 /* any class */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +/* DNS protocol flags */ +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + +#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF) + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS message header */ +struct dns_hdr { + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FLD_8(u8_t flags1); + PACK_STRUCT_FLD_8(u8_t flags2); + PACK_STRUCT_FIELD(u16_t numquestions); + PACK_STRUCT_FIELD(u16_t numanswers); + PACK_STRUCT_FIELD(u16_t numauthrr); + PACK_STRUCT_FIELD(u16_t numextrarr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_HDR 12 + + +/* Multicast DNS definitions */ + +/** UDP port for multicast DNS queries */ +#ifndef DNS_MQUERY_PORT +#define DNS_MQUERY_PORT 5353 +#endif + +/* IPv4 group for multicast DNS queries: 224.0.0.251 */ +#ifndef DNS_MQUERY_IPV4_GROUP_INIT +#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251) +#endif + +/* IPv6 group for multicast DNS queries: FF02::FB */ +#ifndef DNS_MQUERY_IPV6_GROUP_INIT +#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_DNS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/etharp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/etharp.h new file mode 100644 index 0000000..ec78305 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/etharp.h @@ -0,0 +1,91 @@ +/** + * @file + * ARP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_ETHARP_H +#define LWIP_HDR_PROT_ETHARP_H + +#include "lwip/arch.h" +#include "lwip/prot/ethernet.h" +#include "lwip/ip4_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN ETH_HWADDR_LEN +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message, see RFC 826 ("Packet format") */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FLD_8(u8_t hwlen); + PACK_STRUCT_FLD_8(u8_t protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FLD_S(struct eth_addr shwaddr); + PACK_STRUCT_FLD_S(struct ip4_addr2 sipaddr); + PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); + PACK_STRUCT_FLD_S(struct ip4_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 + +/* ARP hwtype values */ +enum etharp_hwtype { + HWTYPE_ETHERNET = 1 + /* others not used */ +}; + +/* ARP message types (opcodes) */ +enum etharp_opcode { + ARP_REQUEST = 1, + ARP_REPLY = 2 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_ETHARP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ethernet.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ethernet.h new file mode 100644 index 0000000..b7a967f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ethernet.h @@ -0,0 +1,164 @@ +/** + * @file + * Ethernet protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_ETHERNET_H +#define LWIP_HDR_PROT_ETHERNET_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETH_HWADDR_LEN +#ifdef ETHARP_HWADDR_LEN +#define ETH_HWADDR_LEN ETHARP_HWADDR_LEN /* compatibility mode */ +#else +#define ETH_HWADDR_LEN 6 +#endif +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** Ethernet header */ +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FLD_S(struct eth_addr dest); + PACK_STRUCT_FLD_S(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** VLAN header inserted between ethernet header and payload + * if 'type' in ethernet header is ETHTYPE_VLAN. + * See IEEE802.Q */ +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF) + +/** + * @ingroup ethernet + * A list of often ethtypes (although lwIP does not use all of them): */ +enum eth_type { + /** Internet protocol v4 */ + ETHTYPE_IP = 0x0800U, + /** Address resolution protocol */ + ETHTYPE_ARP = 0x0806U, + /** Wake on lan */ + ETHTYPE_WOL = 0x0842U, + /** RARP */ + ETHTYPE_RARP = 0x8035U, + /** Virtual local area network */ + ETHTYPE_VLAN = 0x8100U, + /** Internet protocol v6 */ + ETHTYPE_IPV6 = 0x86DDU, + /** PPP Over Ethernet Discovery Stage */ + ETHTYPE_PPPOEDISC = 0x8863U, + /** PPP Over Ethernet Session Stage */ + ETHTYPE_PPPOE = 0x8864U, + /** Jumbo Frames */ + ETHTYPE_JUMBO = 0x8870U, + /** Process field network */ + ETHTYPE_PROFINET = 0x8892U, + /** Ethernet for control automation technology */ + ETHTYPE_ETHERCAT = 0x88A4U, + /** Link layer discovery protocol */ + ETHTYPE_LLDP = 0x88CCU, + /** Serial real-time communication system */ + ETHTYPE_SERCOS = 0x88CDU, + /** Media redundancy protocol */ + ETHTYPE_MRP = 0x88E3U, + /** Precision time protocol */ + ETHTYPE_PTP = 0x88F7U, + /** Q-in-Q, 802.1ad */ + ETHTYPE_QINQ = 0x9100U +}; + +/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */ +#define LL_IP4_MULTICAST_ADDR_0 0x01 +#define LL_IP4_MULTICAST_ADDR_1 0x00 +#define LL_IP4_MULTICAST_ADDR_2 0x5e + +/** IPv6 multicast uses this prefix */ +#define LL_IP6_MULTICAST_ADDR_0 0x33 +#define LL_IP6_MULTICAST_ADDR_1 0x33 + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local + * variables and known to be 16-bit aligned within the protocol header. */ +#ifndef ETHADDR16_COPY +#define ETHADDR16_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN) +#endif + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_ETHERNET_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp.h new file mode 100644 index 0000000..7d19385 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp.h @@ -0,0 +1,91 @@ +/** + * @file + * ICMP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_ICMP_H +#define LWIP_HDR_PROT_ICMP_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ +#define ICMP_AM 17 /* address mask request */ +#define ICMP_AMR 18 /* address mask reply */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is split to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Compatibility defines, old versions used to combine type and code to an u16_t */ +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_ICMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp6.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp6.h new file mode 100644 index 0000000..3461120 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/icmp6.h @@ -0,0 +1,170 @@ +/** + * @file + * ICMP6 protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_ICMP6_H +#define LWIP_HDR_PROT_ICMP6_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** ICMP type */ +enum icmp6_type { + /** Destination unreachable */ + ICMP6_TYPE_DUR = 1, + /** Packet too big */ + ICMP6_TYPE_PTB = 2, + /** Time exceeded */ + ICMP6_TYPE_TE = 3, + /** Parameter problem */ + ICMP6_TYPE_PP = 4, + /** Private experimentation */ + ICMP6_TYPE_PE1 = 100, + /** Private experimentation */ + ICMP6_TYPE_PE2 = 101, + /** Reserved for expansion of error messages */ + ICMP6_TYPE_RSV_ERR = 127, + + /** Echo request */ + ICMP6_TYPE_EREQ = 128, + /** Echo reply */ + ICMP6_TYPE_EREP = 129, + /** Multicast listener query */ + ICMP6_TYPE_MLQ = 130, + /** Multicast listener report */ + ICMP6_TYPE_MLR = 131, + /** Multicast listener done */ + ICMP6_TYPE_MLD = 132, + /** Router solicitation */ + ICMP6_TYPE_RS = 133, + /** Router advertisement */ + ICMP6_TYPE_RA = 134, + /** Neighbor solicitation */ + ICMP6_TYPE_NS = 135, + /** Neighbor advertisement */ + ICMP6_TYPE_NA = 136, + /** Redirect */ + ICMP6_TYPE_RD = 137, + /** Multicast router advertisement */ + ICMP6_TYPE_MRA = 151, + /** Multicast router solicitation */ + ICMP6_TYPE_MRS = 152, + /** Multicast router termination */ + ICMP6_TYPE_MRT = 153, + /** Private experimentation */ + ICMP6_TYPE_PE3 = 200, + /** Private experimentation */ + ICMP6_TYPE_PE4 = 201, + /** Reserved for expansion of informational messages */ + ICMP6_TYPE_RSV_INF = 255 +}; + +/** ICMP destination unreachable codes */ +enum icmp6_dur_code { + /** No route to destination */ + ICMP6_DUR_NO_ROUTE = 0, + /** Communication with destination administratively prohibited */ + ICMP6_DUR_PROHIBITED = 1, + /** Beyond scope of source address */ + ICMP6_DUR_SCOPE = 2, + /** Address unreachable */ + ICMP6_DUR_ADDRESS = 3, + /** Port unreachable */ + ICMP6_DUR_PORT = 4, + /** Source address failed ingress/egress policy */ + ICMP6_DUR_POLICY = 5, + /** Reject route to destination */ + ICMP6_DUR_REJECT_ROUTE = 6 +}; + +/** ICMP time exceeded codes */ +enum icmp6_te_code { + /** Hop limit exceeded in transit */ + ICMP6_TE_HL = 0, + /** Fragment reassembly time exceeded */ + ICMP6_TE_FRAG = 1 +}; + +/** ICMP parameter code */ +enum icmp6_pp_code { + /** Erroneous header field encountered */ + ICMP6_PP_FIELD = 0, + /** Unrecognized next header type encountered */ + ICMP6_PP_HEADER = 1, + /** Unrecognized IPv6 option encountered */ + ICMP6_PP_OPTION = 2 +}; + +/** This is the standard ICMP6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t data); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** This is the ICMP6 header adapted for echo req/resp. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_echo_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_ICMP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/igmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/igmp.h new file mode 100644 index 0000000..d60cb31 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/igmp.h @@ -0,0 +1,90 @@ +/** + * @file + * IGMP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_IGMP_H +#define LWIP_HDR_PROT_IGMP_H + +#include "lwip/arch.h" +#include "lwip/ip4_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * IGMP constants + */ +#define IGMP_TTL 1 +#define IGMP_MINLEN 8 +#define ROUTER_ALERT 0x9404U +#define ROUTER_ALERTLEN 4 + +/* + * IGMP message types, including version number. + */ +#define IGMP_MEMB_QUERY 0x11 /* Membership query */ +#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ + +/* Group membership states */ +#define IGMP_GROUP_NON_MEMBER 0 +#define IGMP_GROUP_DELAYING_MEMBER 1 +#define IGMP_GROUP_IDLE_MEMBER 2 + +/** + * IGMP packet format. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct igmp_msg { + PACK_STRUCT_FLD_8(u8_t igmp_msgtype); + PACK_STRUCT_FLD_8(u8_t igmp_maxresp); + PACK_STRUCT_FIELD(u16_t igmp_checksum); + PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_IGMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip.h new file mode 100644 index 0000000..bbfae36 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip.h @@ -0,0 +1,51 @@ +/** + * @file + * IP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_IP_H +#define LWIP_HDR_PROT_IP_H + +#include "lwip/arch.h" + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_IGMP 2 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + +/** This operates on a void* by loading the first byte */ +#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4) + +#endif /* LWIP_HDR_PROT_IP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip4.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip4.h new file mode 100644 index 0000000..bd442c6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip4.h @@ -0,0 +1,127 @@ +/** + * @file + * IPv4 protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_IP4_H +#define LWIP_HDR_PROT_IP4_H + +#include "lwip/arch.h" +#include "lwip/ip4_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This is the packed version of ip4_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip4_addr_packed { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +typedef struct ip4_addr_packed ip4_addr_p_t; + +/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */ +#define IP_HLEN 20 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/* The IPv4 header */ +struct ip_hdr { + /* version / header length */ + PACK_STRUCT_FLD_8(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FLD_8(u8_t _tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* don't fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ + /* time to live */ + PACK_STRUCT_FLD_8(u8_t _ttl); + /* protocol*/ + PACK_STRUCT_FLD_8(u8_t _proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FLD_S(ip4_addr_p_t src); + PACK_STRUCT_FLD_S(ip4_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Macros to get struct ip_hdr fields: */ +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) ((hdr)->_ttl) +#define IPH_PROTO(hdr) ((hdr)->_proto) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +/* Macros to set struct ip_hdr fields: */ +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl))) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_IP4_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip6.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip6.h new file mode 100644 index 0000000..6e1e263 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/ip6.h @@ -0,0 +1,169 @@ +/** + * @file + * IPv6 protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_IP6_H +#define LWIP_HDR_PROT_IP6_H + +#include "lwip/arch.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This is the packed version of ip6_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_addr_packed { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +typedef struct ip6_addr_packed ip6_addr_p_t; + +#define IP6_HLEN 40 + +#define IP6_NEXTH_HOPBYHOP 0 +#define IP6_NEXTH_TCP 6 +#define IP6_NEXTH_UDP 17 +#define IP6_NEXTH_ENCAPS 41 +#define IP6_NEXTH_ROUTING 43 +#define IP6_NEXTH_FRAGMENT 44 +#define IP6_NEXTH_ICMP6 58 +#define IP6_NEXTH_NONE 59 +#define IP6_NEXTH_DESTOPTS 60 +#define IP6_NEXTH_UDPLITE 136 + +/** The IPv6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hdr { + /** version / traffic class / flow label */ + PACK_STRUCT_FIELD(u32_t _v_tc_fl); + /** payload length */ + PACK_STRUCT_FIELD(u16_t _plen); + /** next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /** hop limit */ + PACK_STRUCT_FLD_8(u8_t _hoplim); + /** source and destination IP addresses */ + PACK_STRUCT_FLD_S(ip6_addr_p_t src); + PACK_STRUCT_FLD_S(ip6_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Hop-by-hop router alert option. */ +#define IP6_HBH_HLEN 8 +#define IP6_PAD1_OPTION 0 +#define IP6_PADN_ALERT_OPTION 1 +#define IP6_ROUTER_ALERT_OPTION 5 +#define IP6_ROUTER_ALERT_VALUE_MLD 0 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hbh_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* header length */ + PACK_STRUCT_FLD_8(u8_t _hlen); + /* router alert option type */ + PACK_STRUCT_FLD_8(u8_t _ra_opt_type); + /* router alert option data len */ + PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen); + /* router alert option data */ + PACK_STRUCT_FIELD(u16_t _ra_opt_data); + /* PadN option type */ + PACK_STRUCT_FLD_8(u8_t _padn_opt_type); + /* PadN option data len */ + PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Fragment header. */ +#define IP6_FRAG_HLEN 8 +#define IP6_FRAG_OFFSET_MASK 0xfff8 +#define IP6_FRAG_MORE_FLAG 0x0001 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_frag_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* reserved */ + PACK_STRUCT_FLD_8(u8_t reserved); + /* fragment offset */ + PACK_STRUCT_FIELD(u16_t _fragment_offset); + /* fragmented packet identification */ + PACK_STRUCT_FIELD(u32_t _identification); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) +#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) +#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff) +#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen)) +#define IP6H_NEXTH(hdr) ((hdr)->_nexth) +#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) +#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) + +#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) +#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen) +#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) +#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_IP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/mld6.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/mld6.h new file mode 100644 index 0000000..be3a006 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/mld6.h @@ -0,0 +1,70 @@ +/** + * @file + * MLD6 protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_MLD6_H +#define LWIP_HDR_PROT_MLD6_H + +#include "lwip/arch.h" +#include "lwip/prot/ip6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Multicast listener report/query/done message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mld_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t max_resp_delay); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_MLD6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/nd6.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/nd6.h new file mode 100644 index 0000000..2d4903d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/nd6.h @@ -0,0 +1,277 @@ +/** + * @file + * ND6 protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_ND6_H +#define LWIP_HDR_PROT_ND6_H + +#include "lwip/arch.h" +#include "lwip/ip6_addr.h" +#include "lwip/prot/ip6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Neighbor solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ns_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Neighbor advertisement message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct na_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FLD_8(u8_t reserved[3]); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define ND6_FLAG_ROUTER (0x80) +#define ND6_FLAG_SOLICITED (0x40) +#define ND6_FLAG_OVERRIDE (0x20) + +/** Router solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct rs_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Router advertisement message header. */ +#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) +#define ND6_RA_FLAG_OTHER_CONFIG (0x40) +#define ND6_RA_FLAG_HOME_AGENT (0x20) +#define ND6_RA_PREFERENCE_MASK (0x18) +#define ND6_RA_PREFERENCE_HIGH (0x08) +#define ND6_RA_PREFERENCE_MEDIUM (0x00) +#define ND6_RA_PREFERENCE_LOW (0x18) +#define ND6_RA_PREFERENCE_DISABLED (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ra_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FLD_8(u8_t current_hop_limit); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FIELD(u16_t router_lifetime); + PACK_STRUCT_FIELD(u32_t reachable_time); + PACK_STRUCT_FIELD(u32_t retrans_timer); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirect message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirect_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Link-layer address option. */ +#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) +#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct lladdr_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Prefix information option. */ +#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) +#define ND6_PREFIX_FLAG_ON_LINK (0x80) +#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) +#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) +#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct prefix_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t prefix_length); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FIELD(u32_t valid_lifetime); + PACK_STRUCT_FIELD(u32_t preferred_lifetime); + PACK_STRUCT_FLD_8(u8_t reserved2[3]); + PACK_STRUCT_FLD_8(u8_t site_prefix_length); + PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirected header option. */ +#define ND6_OPTION_TYPE_REDIR_HDR (0x04) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirected_header_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t reserved[6]); + /* Portion of redirected packet follows. */ + /* PACK_STRUCT_FLD_8(u8_t redirected[8]); */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** MTU option. */ +#define ND6_OPTION_TYPE_MTU (0x05) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mtu_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FIELD(u32_t mtu); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Route information option. */ +#define ND6_OPTION_TYPE_ROUTE_INFO (24) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct route_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t prefix_length); + PACK_STRUCT_FLD_8(u8_t preference); + PACK_STRUCT_FIELD(u32_t route_lifetime); + PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Recursive DNS Server Option. */ +#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS +#define LWIP_RDNSS_OPTION_MAX_SERVERS LWIP_ND6_RDNSS_MAX_DNS_SERVERS +#else +#define LWIP_RDNSS_OPTION_MAX_SERVERS 1 +#endif +#define ND6_OPTION_TYPE_RDNSS (25) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct rdnss_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FIELD(u32_t lifetime); + PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[LWIP_RDNSS_OPTION_MAX_SERVERS]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_ND6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/tcp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/tcp.h new file mode 100644 index 0000000..67fe7b9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/tcp.h @@ -0,0 +1,97 @@ +/** + * @file + * TCP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_TCP_H +#define LWIP_HDR_PROT_TCP_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* TCP header flags bits */ +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U +/* Valid TCP header flags */ +#define TCP_FLAGS 0x3fU + +#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)) +#define TCPH_FLAGS(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)) + +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags)) +#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = (u16_t)(lwip_htons((u16_t)((len) << 12) | (flags))) + +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | lwip_htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags & ~lwip_htons(flags)) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_TCP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/udp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/udp.h new file mode 100644 index 0000000..664f19a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/prot/udp.h @@ -0,0 +1,68 @@ +/** + * @file + * UDP protocol definitions + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_PROT_UDP_H +#define LWIP_HDR_PROT_UDP_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PROT_UDP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/raw.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/raw.h new file mode 100644 index 0000000..17d0a1c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/raw.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_RAW_H__ +#define __LWIP_RAW_H__ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct raw_pcb; + +/** Function prototype for raw pcb receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr); + +struct raw_pcb { + /* Common members of all PCB types */ + IP_PCB; + + struct raw_pcb *next; + + u8_t protocol; + + /** receive callback function */ + raw_recv_fn recv; + /* user-supplied argument for the recv callback */ + void *recv_arg; +}; + +/* The following functions is the application layer interface to the + RAW code. */ +struct raw_pcb * raw_new (u8_t proto); +void raw_remove (struct raw_pcb *pcb); +err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); +err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); + +void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); +err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); +err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); + +/* The following functions are the lower layer interface to RAW. */ +u8_t raw_input (struct pbuf *p, struct netif *inp); +#define raw_init() /* Compatibility define, not init needed. */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_RAW */ + +#endif /* __LWIP_RAW_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sio.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sio.h new file mode 100644 index 0000000..28ae2f2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sio.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ + +#ifndef __SIO_H__ +#define __SIO_H__ + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If you want to define sio_fd_t elsewhere or differently, + define this in your cc.h file. */ +#ifndef __sio_fd_t_defined +typedef void * sio_fd_t; +#endif + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +#ifndef sio_open +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum); +#endif + +#ifndef sio_send +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd); +#endif + +#ifndef sio_recv +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd); +#endif + +#ifndef sio_read +/** + * Reads from the serial device. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * + * @note This function will block until data can be received. The blocking + * can be cancelled by calling sio_read_abort(). + */ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_tryread +/** + * Tries to read from the serial device. Same as sio_read but returns + * immediately if no data is available and never blocks. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received + */ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_write +/** + * Writes to the serial device. + * + * @param fd serial device handle + * @param data pointer to data to send + * @param len length (in bytes) of data to send + * @return number of bytes actually sent + * + * @note This function will block until all data can be sent. + */ +u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_read_abort +/** + * Aborts a blocking sio_read() call. + * + * @param fd serial device handle + */ +void sio_read_abort(sio_fd_t fd); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __SIO_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp.h new file mode 100644 index 0000000..2ed043d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + */ +#ifndef __LWIP_SNMP_H__ +#define __LWIP_SNMP_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip/ip_addr.h" + +struct udp_pcb; +struct netif; + +/** + * @see RFC1213, "MIB-II, 6. Definitions" + */ +enum snmp_ifType { + snmp_ifType_other=1, /* none of the following */ + snmp_ifType_regular1822, + snmp_ifType_hdh1822, + snmp_ifType_ddn_x25, + snmp_ifType_rfc877_x25, + snmp_ifType_ethernet_csmacd, + snmp_ifType_iso88023_csmacd, + snmp_ifType_iso88024_tokenBus, + snmp_ifType_iso88025_tokenRing, + snmp_ifType_iso88026_man, + snmp_ifType_starLan, + snmp_ifType_proteon_10Mbit, + snmp_ifType_proteon_80Mbit, + snmp_ifType_hyperchannel, + snmp_ifType_fddi, + snmp_ifType_lapb, + snmp_ifType_sdlc, + snmp_ifType_ds1, /* T-1 */ + snmp_ifType_e1, /* european equiv. of T-1 */ + snmp_ifType_basicISDN, + snmp_ifType_primaryISDN, /* proprietary serial */ + snmp_ifType_propPointToPointSerial, + snmp_ifType_ppp, + snmp_ifType_softwareLoopback, + snmp_ifType_eon, /* CLNP over IP [11] */ + snmp_ifType_ethernet_3Mbit, + snmp_ifType_nsip, /* XNS over IP */ + snmp_ifType_slip, /* generic SLIP */ + snmp_ifType_ultra, /* ULTRA technologies */ + snmp_ifType_ds3, /* T-3 */ + snmp_ifType_sip, /* SMDS */ + snmp_ifType_frame_relay +}; + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** SNMP "sysuptime" Interval */ +#define SNMP_SYSUPTIME_INTERVAL 10 + +/** fixed maximum length for object identifier type */ +#define LWIP_SNMP_OBJ_ID_LEN 32 + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + s32_t id[LWIP_SNMP_OBJ_ID_LEN]; +}; + +/* system */ +void snmp_set_sysdesr(u8_t* str, u8_t* len); +void snmp_set_sysobjid(struct snmp_obj_id *oid); +void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid); +void snmp_inc_sysuptime(void); +void snmp_add_sysuptime(u32_t value); +void snmp_get_sysuptime(u32_t *value); +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); + +/* network interface */ +void snmp_add_ifinoctets(struct netif *ni, u32_t value); +void snmp_inc_ifinucastpkts(struct netif *ni); +void snmp_inc_ifinnucastpkts(struct netif *ni); +void snmp_inc_ifindiscards(struct netif *ni); +void snmp_add_ifoutoctets(struct netif *ni, u32_t value); +void snmp_inc_ifoutucastpkts(struct netif *ni); +void snmp_inc_ifoutnucastpkts(struct netif *ni); +void snmp_inc_ifoutdiscards(struct netif *ni); +void snmp_inc_iflist(void); +void snmp_dec_iflist(void); + +/* ARP (for atTable and ipNetToMediaTable) */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); + +/* IP */ +void snmp_inc_ipinreceives(void); +void snmp_inc_ipinhdrerrors(void); +void snmp_inc_ipinaddrerrors(void); +void snmp_inc_ipforwdatagrams(void); +void snmp_inc_ipinunknownprotos(void); +void snmp_inc_ipindiscards(void); +void snmp_inc_ipindelivers(void); +void snmp_inc_ipoutrequests(void); +void snmp_inc_ipoutdiscards(void); +void snmp_inc_ipoutnoroutes(void); +void snmp_inc_ipreasmreqds(void); +void snmp_inc_ipreasmoks(void); +void snmp_inc_ipreasmfails(void); +void snmp_inc_ipfragoks(void); +void snmp_inc_ipfragfails(void); +void snmp_inc_ipfragcreates(void); +void snmp_inc_iproutingdiscards(void); +void snmp_insert_ipaddridx_tree(struct netif *ni); +void snmp_delete_ipaddridx_tree(struct netif *ni); +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); + +/* ICMP */ +void snmp_inc_icmpinmsgs(void); +void snmp_inc_icmpinerrors(void); +void snmp_inc_icmpindestunreachs(void); +void snmp_inc_icmpintimeexcds(void); +void snmp_inc_icmpinparmprobs(void); +void snmp_inc_icmpinsrcquenchs(void); +void snmp_inc_icmpinredirects(void); +void snmp_inc_icmpinechos(void); +void snmp_inc_icmpinechoreps(void); +void snmp_inc_icmpintimestamps(void); +void snmp_inc_icmpintimestampreps(void); +void snmp_inc_icmpinaddrmasks(void); +void snmp_inc_icmpinaddrmaskreps(void); +void snmp_inc_icmpoutmsgs(void); +void snmp_inc_icmpouterrors(void); +void snmp_inc_icmpoutdestunreachs(void); +void snmp_inc_icmpouttimeexcds(void); +void snmp_inc_icmpoutparmprobs(void); +void snmp_inc_icmpoutsrcquenchs(void); +void snmp_inc_icmpoutredirects(void); +void snmp_inc_icmpoutechos(void); +void snmp_inc_icmpoutechoreps(void); +void snmp_inc_icmpouttimestamps(void); +void snmp_inc_icmpouttimestampreps(void); +void snmp_inc_icmpoutaddrmasks(void); +void snmp_inc_icmpoutaddrmaskreps(void); + +/* TCP */ +void snmp_inc_tcpactiveopens(void); +void snmp_inc_tcppassiveopens(void); +void snmp_inc_tcpattemptfails(void); +void snmp_inc_tcpestabresets(void); +void snmp_inc_tcpinsegs(void); +void snmp_inc_tcpoutsegs(void); +void snmp_inc_tcpretranssegs(void); +void snmp_inc_tcpinerrs(void); +void snmp_inc_tcpoutrsts(void); + +/* UDP */ +void snmp_inc_udpindatagrams(void); +void snmp_inc_udpnoports(void); +void snmp_inc_udpinerrors(void); +void snmp_inc_udpoutdatagrams(void); +void snmp_insert_udpidx_tree(struct udp_pcb *pcb); +void snmp_delete_udpidx_tree(struct udp_pcb *pcb); + +/* SNMP */ +void snmp_inc_snmpinpkts(void); +void snmp_inc_snmpoutpkts(void); +void snmp_inc_snmpinbadversions(void); +void snmp_inc_snmpinbadcommunitynames(void); +void snmp_inc_snmpinbadcommunityuses(void); +void snmp_inc_snmpinasnparseerrs(void); +void snmp_inc_snmpintoobigs(void); +void snmp_inc_snmpinnosuchnames(void); +void snmp_inc_snmpinbadvalues(void); +void snmp_inc_snmpinreadonlys(void); +void snmp_inc_snmpingenerrs(void); +void snmp_add_snmpintotalreqvars(u8_t value); +void snmp_add_snmpintotalsetvars(u8_t value); +void snmp_inc_snmpingetrequests(void); +void snmp_inc_snmpingetnexts(void); +void snmp_inc_snmpinsetrequests(void); +void snmp_inc_snmpingetresponses(void); +void snmp_inc_snmpintraps(void); +void snmp_inc_snmpouttoobigs(void); +void snmp_inc_snmpoutnosuchnames(void); +void snmp_inc_snmpoutbadvalues(void); +void snmp_inc_snmpoutgenerrs(void); +void snmp_inc_snmpoutgetrequests(void); +void snmp_inc_snmpoutgetnexts(void); +void snmp_inc_snmpoutsetrequests(void); +void snmp_inc_snmpoutgetresponses(void); +void snmp_inc_snmpouttraps(void); +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); +void snmp_set_snmpenableauthentraps(u8_t *value); +void snmp_get_snmpenableauthentraps(u8_t *value); + +/* LWIP_SNMP support not available */ +/* define everything to be empty */ +#else + +/* system */ +#define snmp_set_sysdesr(str, len) +#define snmp_set_sysobjid(oid); +#define snmp_get_sysobjid_ptr(oid) +#define snmp_inc_sysuptime() +#define snmp_add_sysuptime(value) +#define snmp_get_sysuptime(value) +#define snmp_set_syscontact(ocstr, ocstrlen); +#define snmp_set_sysname(ocstr, ocstrlen); +#define snmp_set_syslocation(ocstr, ocstrlen); + +/* network interface */ +#define snmp_add_ifinoctets(ni,value) +#define snmp_inc_ifinucastpkts(ni) +#define snmp_inc_ifinnucastpkts(ni) +#define snmp_inc_ifindiscards(ni) +#define snmp_add_ifoutoctets(ni,value) +#define snmp_inc_ifoutucastpkts(ni) +#define snmp_inc_ifoutnucastpkts(ni) +#define snmp_inc_ifoutdiscards(ni) +#define snmp_inc_iflist() +#define snmp_dec_iflist() + +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) + +/* IP */ +#define snmp_inc_ipinreceives() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() +#define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#define snmp_inc_ipoutdiscards() +#define snmp_inc_ipoutnoroutes() +#define snmp_inc_ipreasmreqds() +#define snmp_inc_ipreasmoks() +#define snmp_inc_ipreasmfails() +#define snmp_inc_ipfragoks() +#define snmp_inc_ipfragfails() +#define snmp_inc_ipfragcreates() +#define snmp_inc_iproutingdiscards() +#define snmp_insert_ipaddridx_tree(ni) +#define snmp_delete_ipaddridx_tree(ni) +#define snmp_insert_iprteidx_tree(dflt, ni) +#define snmp_delete_iprteidx_tree(dflt, ni) + +/* ICMP */ +#define snmp_inc_icmpinmsgs() +#define snmp_inc_icmpinerrors() +#define snmp_inc_icmpindestunreachs() +#define snmp_inc_icmpintimeexcds() +#define snmp_inc_icmpinparmprobs() +#define snmp_inc_icmpinsrcquenchs() +#define snmp_inc_icmpinredirects() +#define snmp_inc_icmpinechos() +#define snmp_inc_icmpinechoreps() +#define snmp_inc_icmpintimestamps() +#define snmp_inc_icmpintimestampreps() +#define snmp_inc_icmpinaddrmasks() +#define snmp_inc_icmpinaddrmaskreps() +#define snmp_inc_icmpoutmsgs() +#define snmp_inc_icmpouterrors() +#define snmp_inc_icmpoutdestunreachs() +#define snmp_inc_icmpouttimeexcds() +#define snmp_inc_icmpoutparmprobs() +#define snmp_inc_icmpoutsrcquenchs() +#define snmp_inc_icmpoutredirects() +#define snmp_inc_icmpoutechos() +#define snmp_inc_icmpoutechoreps() +#define snmp_inc_icmpouttimestamps() +#define snmp_inc_icmpouttimestampreps() +#define snmp_inc_icmpoutaddrmasks() +#define snmp_inc_icmpoutaddrmaskreps() +/* TCP */ +#define snmp_inc_tcpactiveopens() +#define snmp_inc_tcppassiveopens() +#define snmp_inc_tcpattemptfails() +#define snmp_inc_tcpestabresets() +#define snmp_inc_tcpinsegs() +#define snmp_inc_tcpoutsegs() +#define snmp_inc_tcpretranssegs() +#define snmp_inc_tcpinerrs() +#define snmp_inc_tcpoutrsts() + +/* UDP */ +#define snmp_inc_udpindatagrams() +#define snmp_inc_udpnoports() +#define snmp_inc_udpinerrors() +#define snmp_inc_udpoutdatagrams() +#define snmp_insert_udpidx_tree(pcb) +#define snmp_delete_udpidx_tree(pcb) + +/* SNMP */ +#define snmp_inc_snmpinpkts() +#define snmp_inc_snmpoutpkts() +#define snmp_inc_snmpinbadversions() +#define snmp_inc_snmpinbadcommunitynames() +#define snmp_inc_snmpinbadcommunityuses() +#define snmp_inc_snmpinasnparseerrs() +#define snmp_inc_snmpintoobigs() +#define snmp_inc_snmpinnosuchnames() +#define snmp_inc_snmpinbadvalues() +#define snmp_inc_snmpinreadonlys() +#define snmp_inc_snmpingenerrs() +#define snmp_add_snmpintotalreqvars(value) +#define snmp_add_snmpintotalsetvars(value) +#define snmp_inc_snmpingetrequests() +#define snmp_inc_snmpingetnexts() +#define snmp_inc_snmpinsetrequests() +#define snmp_inc_snmpingetresponses() +#define snmp_inc_snmpintraps() +#define snmp_inc_snmpouttoobigs() +#define snmp_inc_snmpoutnosuchnames() +#define snmp_inc_snmpoutbadvalues() +#define snmp_inc_snmpoutgenerrs() +#define snmp_inc_snmpoutgetrequests() +#define snmp_inc_snmpoutgetnexts() +#define snmp_inc_snmpoutsetrequests() +#define snmp_inc_snmpoutgetresponses() +#define snmp_inc_snmpouttraps() +#define snmp_get_snmpgrpid_ptr(oid) +#define snmp_set_snmpenableauthentraps(value) +#define snmp_get_snmpenableauthentraps(value) + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SNMP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_asn1.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_asn1.h new file mode 100644 index 0000000..605fa3f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_asn1.h @@ -0,0 +1,101 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_ASN1_H__ +#define __LWIP_SNMP_ASN1_H__ + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/snmp.h" + +#if LWIP_SNMP + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ +#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ +#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ + +#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ +#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ + +/* universal tags */ +#define SNMP_ASN1_INTEG 2 +#define SNMP_ASN1_OC_STR 4 +#define SNMP_ASN1_NUL 5 +#define SNMP_ASN1_OBJ_ID 6 +#define SNMP_ASN1_SEQ 16 + +/* application specific (SNMP) tags */ +#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ +#define SNMP_ASN1_COUNTER 1 /* u32_t */ +#define SNMP_ASN1_GAUGE 2 /* u32_t */ +#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ +#define SNMP_ASN1_OPAQUE 4 /* octet string */ + +/* context specific (SNMP) tags */ +#define SNMP_ASN1_PDU_GET_REQ 0 +#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_PDU_GET_RESP 2 +#define SNMP_ASN1_PDU_SET_REQ 3 +#define SNMP_ASN1_PDU_TRAP 4 + +err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); +err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); +err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); +err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); +err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); +err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); +err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); +err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); +err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); +err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_ASN1_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_msg.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_msg.h new file mode 100644 index 0000000..1183e3a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_msg.h @@ -0,0 +1,315 @@ +/** + * @file + * SNMP Agent message handling structures. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_MSG_H__ +#define __LWIP_SNMP_MSG_H__ + +#include "lwip/opt.h" +#include "lwip/snmp.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#if LWIP_SNMP + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +#define SNMP_ES_NOERROR 0 +#define SNMP_ES_TOOBIG 1 +#define SNMP_ES_NOSUCHNAME 2 +#define SNMP_ES_BADVALUE 3 +#define SNMP_ES_READONLY 4 +#define SNMP_ES_GENERROR 5 + +#define SNMP_GENTRAP_COLDSTART 0 +#define SNMP_GENTRAP_WARMSTART 1 +#define SNMP_GENTRAP_AUTHFAIL 4 +#define SNMP_GENTRAP_ENTERPRISESPC 6 + +struct snmp_varbind +{ + /* next pointer, NULL for last in list */ + struct snmp_varbind *next; + /* previous pointer, NULL for first in list */ + struct snmp_varbind *prev; + + /* object identifier length (in s32_t) */ + u8_t ident_len; + /* object identifier array */ + s32_t *ident; + + /* object value ASN1 type */ + u8_t value_type; + /* object value length (in u8_t) */ + u8_t value_len; + /* object value */ + void *value; + + /* encoding varbind seq length length */ + u8_t seqlenlen; + /* encoding object identifier length length */ + u8_t olenlen; + /* encoding object value length length */ + u8_t vlenlen; + /* encoding varbind seq length */ + u16_t seqlen; + /* encoding object identifier length */ + u16_t olen; + /* encoding object value length */ + u16_t vlen; +}; + +struct snmp_varbind_root +{ + struct snmp_varbind *head; + struct snmp_varbind *tail; + /* number of variable bindings in list */ + u8_t count; + /* encoding varbind-list seq length length */ + u8_t seqlenlen; + /* encoding varbind-list seq length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_resp_header_lengths +{ + /* encoding error-index length length */ + u8_t erridxlenlen; + /* encoding error-status length length */ + u8_t errstatlenlen; + /* encoding request id length length */ + u8_t ridlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding error-index length */ + u16_t erridxlen; + /* encoding error-status length */ + u16_t errstatlen; + /* encoding request id length */ + u16_t ridlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_trap_header_lengths +{ + /* encoding timestamp length length */ + u8_t tslenlen; + /* encoding specific-trap length length */ + u8_t strplenlen; + /* encoding generic-trap length length */ + u8_t gtrplenlen; + /* encoding agent-addr length length */ + u8_t aaddrlenlen; + /* encoding enterprise-id length length */ + u8_t eidlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding timestamp length */ + u16_t tslen; + /* encoding specific-trap length */ + u16_t strplen; + /* encoding generic-trap length */ + u16_t gtrplen; + /* encoding agent-addr length */ + u16_t aaddrlen; + /* encoding enterprise-id length */ + u16_t eidlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/* Accepting new SNMP messages. */ +#define SNMP_MSG_EMPTY 0 +/* Search for matching object for variable binding. */ +#define SNMP_MSG_SEARCH_OBJ 1 +/* Perform SNMP operation on in-memory object. + Pass-through states, for symmetry only. */ +#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 +#define SNMP_MSG_INTERNAL_GET_VALUE 3 +#define SNMP_MSG_INTERNAL_SET_TEST 4 +#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 +#define SNMP_MSG_INTERNAL_SET_VALUE 6 +/* Perform SNMP operation on object located externally. + In theory this could be used for building a proxy agent. + Practical use is for an enterprise spc. app. gateway. */ +#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 +#define SNMP_MSG_EXTERNAL_GET_VALUE 8 +#define SNMP_MSG_EXTERNAL_SET_TEST 9 +#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 +#define SNMP_MSG_EXTERNAL_SET_VALUE 11 + +#define SNMP_COMMUNITY_STR_LEN 64 +struct snmp_msg_pstat +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* source IP address */ + ip_addr_t sip; + /* source UDP port */ + u16_t sp; + /* request type */ + u8_t rt; + /* request ID */ + s32_t rid; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* community name (zero terminated) */ + u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u8_t com_strlen; + /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ + u8_t state; + /* saved arguments for MSG_EXTERNAL_x */ + struct mib_external_node *ext_mib_node; + struct snmp_name_ptr ext_name_ptr; + struct obj_def ext_object_def; + struct snmp_obj_id ext_oid; + /* index into input variable binding list */ + u8_t vb_idx; + /* ptr into input variable binding list */ + struct snmp_varbind *vb_ptr; + /* list of variable bindings from input */ + struct snmp_varbind_root invb; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output response lengths used in ASN encoding */ + struct snmp_resp_header_lengths rhl; +}; + +struct snmp_msg_trap +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* destination IP address in network order */ + ip_addr_t dip; + + /* source enterprise ID (sysObjectID) */ + struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + u8_t sip_raw[4]; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output trap lengths used in ASN encoding */ + struct snmp_trap_header_lengths thl; +}; + +/** Agent Version constant, 0 = v1 oddity */ +extern const s32_t snmp_version; +/** Agent default "public" community string */ +extern const char snmp_publiccommunity[7]; + +extern struct snmp_msg_trap trap_msg; + +/** Agent setup, start listening to port 161. */ +void snmp_init(void); +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); + +/** Varbind-list functions. */ +struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); +void snmp_varbind_free(struct snmp_varbind *vb); +void snmp_varbind_list_free(struct snmp_varbind_root *root); +void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); +struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); + +/** Handle an internal (recv) or external (private response) event. */ +void snmp_msg_event(u8_t request_id); +err_t snmp_send_response(struct snmp_msg_pstat *m_stat); +err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_MSG_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_structs.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_structs.h new file mode 100644 index 0000000..0d3b46a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/snmp_structs.h @@ -0,0 +1,268 @@ +/** + * @file + * Generic MIB tree structures. + * + * @todo namespace prefixes + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef __LWIP_SNMP_STRUCTS_H__ +#define __LWIP_SNMP_STRUCTS_H__ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MIB object instance */ +#define MIB_OBJECT_NONE 0 +#define MIB_OBJECT_SCALAR 1 +#define MIB_OBJECT_TAB 2 + +/* MIB access types */ +#define MIB_ACCESS_READ 1 +#define MIB_ACCESS_WRITE 2 + +/* MIB object access */ +#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ +#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) +#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE +#define MIB_OBJECT_NOT_ACCESSIBLE 0 + +/** object definition returned by (get_object_def)() */ +struct obj_def +{ + /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ + u8_t instance; + /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ + u8_t access; + /* ASN type for this object */ + u8_t asn_type; + /* value length (host length) */ + u16_t v_len; + /* length of instance part of supplied object identifier */ + u8_t id_inst_len; + /* instance part of supplied object identifier */ + s32_t *id_inst_ptr; +}; + +struct snmp_name_ptr +{ + u8_t ident_len; + s32_t *ident; +}; + +/** MIB const scalar (.0) node */ +#define MIB_NODE_SC 0x01 +/** MIB const array node */ +#define MIB_NODE_AR 0x02 +/** MIB array node (mem_malloced from RAM) */ +#define MIB_NODE_RA 0x03 +/** MIB list root node (mem_malloced from RAM) */ +#define MIB_NODE_LR 0x04 +/** MIB node for external objects */ +#define MIB_NODE_EX 0x05 + +/** node "base class" layout, the mandatory fields for a node */ +struct mib_node +{ + /** returns struct obj_def for the given object identifier */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + /** returns object value for the given object identifier, + @note the caller must allocate at least len bytes for the value */ + void (*get_value)(struct obj_def *od, u16_t len, void *value); + /** tests length and/or range BEFORE setting */ + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + /** sets object value, only to be called when set_test() */ + void (*set_value)(struct obj_def *od, u16_t len, void *value); + /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ + u8_t node_type; + /* array or max list length */ + u16_t maxlength; +}; + +/** derived node for scalars .0 index */ +typedef struct mib_node mib_scalar_node; + +/** derived node, points to a fixed size const array + of sub-identifiers plus a 'child' pointer */ +struct mib_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + const s32_t *objid; + struct mib_node* const *nptr; +}; + +/** derived node, points to a fixed size mem_malloced array + of sub-identifiers plus a 'child' pointer */ +struct mib_ram_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + s32_t *objid; + struct mib_node **nptr; +}; + +struct mib_list_node +{ + struct mib_list_node *prev; + struct mib_list_node *next; + s32_t objid; + struct mib_node *nptr; +}; + +/** derived node, points to a doubly linked list + of sub-identifiers plus a 'child' pointer */ +struct mib_list_rootnode +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + struct mib_list_node *head; + struct mib_list_node *tail; + /* counts list nodes in list */ + u16_t count; +}; + +/** derived node, has access functions for mib object in external memory or device + using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ +struct mib_external_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + /** points to an external (in memory) record of some sort of addressing + information, passed to and interpreted by the funtions below */ + void* addr_inf; + /** tree levels under this node */ + u8_t tree_levels; + /** number of objects at this level */ + u16_t (*level_length)(void* addr_inf, u8_t level); + /** compares object sub identifier with external id + return zero when equal, nonzero when unequal */ + s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); + void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + + /** async Questions */ + void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_q)(u8_t rid, struct obj_def *od); + void (*set_test_q)(u8_t rid, struct obj_def *od); + void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Answers */ + void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Panic Close (agent returns error reply, + e.g. used for external transaction cleanup) */ + void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_pc)(u8_t rid, struct obj_def *od); + void (*set_test_pc)(u8_t rid, struct obj_def *od); + void (*set_value_pc)(u8_t rid, struct obj_def *od); +}; + +/** export MIB tree from mib2.c */ +extern const struct mib_array_node internet; + +/** dummy function pointers for non-leaf MIB nodes from mib2.c */ +void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); +void noleafs_set_value(struct obj_def *od, u16_t len, void *value); + +void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); +void snmp_iptooid(ip_addr_t *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct mib_list_node* snmp_mib_ln_alloc(s32_t id); +void snmp_mib_ln_free(struct mib_list_node *ln); +struct mib_list_rootnode* snmp_mib_lrn_alloc(void); +void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); + +s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); +s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); +struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); + +struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); +struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); +u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); +u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* __LWIP_SNMP_STRUCTS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sockets.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sockets.h new file mode 100644 index 0000000..167ec1c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sockets.h @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#ifndef __LWIP_SOCKETS_H__ +#define __LWIP_SOCKETS_H__ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/inet.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* members are in network byte order */ +struct sockaddr_in { + u8_t sin_len; + u8_t sin_family; + u16_t sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +struct sockaddr { + u8_t sa_len; + u8_t sa_family; + char sa_data[14]; +}; + +/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef u32_t socklen_t; +#endif + +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 + +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ + +#define SO_DONTLINGER ((int)(~SO_LINGER)) + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ + + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ + + +#define AF_UNSPEC 0 +#define AF_INET 2 +#define PF_INET AF_INET +#define PF_UNSPEC AF_UNSPEC + +#define IPPROTO_IP 0 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#define IPPROTO_UDPLITE 136 + +/* Flags we can use with send and recv. */ +#define MSG_PEEK 0x01 /* Peeks at an incoming message */ +#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ +#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ +#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ + + +/* + * Options for level IPPROTO_IP + */ +#define IP_TOS 1 +#define IP_TTL 2 + +#if LWIP_TCP +/* + * Options for level IPPROTO_TCP + */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ +#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ +#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ +#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#endif /* LWIP_TCP */ + +#if LWIP_UDP && LWIP_UDPLITE +/* + * Options for level IPPROTO_UDPLITE + */ +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif /* LWIP_UDP && LWIP_UDPLITE*/ + + +#if LWIP_IGMP +/* + * Options and types for UDP multicast traffic handling + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +} ip_mreq; +#endif /* LWIP_IGMP */ + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWCOST 0x02 +#define IPTOS_MINCOST IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * lwip_ioctl only supports FIONREAD and FIONBIO, for now + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#if !defined(FIONREAD) || !defined(FIONBIO) +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#endif + +/* Socket I/O Controls: unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#endif + +/* commands for fnctl */ +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 1 /* nonblocking I/O */ +#endif +#ifndef O_NDELAY +#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ +#endif + +#ifndef SHUT_RD + #define SHUT_RD 0 + #define SHUT_WR 1 + #define SHUT_RDWR 2 +#endif + +/* FD_SET used for lwip_select */ +#ifndef FD_SET + #undef FD_SETSIZE + /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ + #define FD_SETSIZE MEMP_NUM_NETCONN + #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) + #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) + #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) + #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) + + typedef struct fd_set { + unsigned char fd_bits [(FD_SETSIZE+7)/8]; + } fd_set; + +#endif /* FD_SET */ + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 1 +#endif + +#if LWIP_TIMEVAL_PRIVATE +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif /* LWIP_TIMEVAL_PRIVATE */ + +void lwip_socket_init(void); + +int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_shutdown(int s, int how); +int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); +int lwip_close(int s); +int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_listen(int s, int backlog); +int lwip_recv(int s, void *mem, size_t len, int flags); +int lwip_read(int s, void *mem, size_t len); +int lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); +int lwip_send(int s, const void *dataptr, size_t size, int flags); +int lwip_sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +int lwip_socket(int domain, int type, int protocol); +int lwip_write(int s, const void *dataptr, size_t size); +int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +int lwip_ioctl(int s, long cmd, void *argp); +int lwip_fcntl(int s, int cmd, int val); + +int lwip_last_err_socket(int s); // errno + +#if LWIP_COMPAT_SOCKETS +#define accept(a,b,c) lwip_accept(a,b,c) +#define bind(a,b,c) lwip_bind(a,b,c) +#define shutdown(a,b) lwip_shutdown(a,b) +#define closesocket(s) lwip_close(s) +#define connect(a,b,c) lwip_connect(a,b,c) +#define getsockname(a,b,c) lwip_getsockname(a,b,c) +#define getpeername(a,b,c) lwip_getpeername(a,b,c) +#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) +#define listen(a,b) lwip_listen(a,b) +#define recv(a,b,c,d) lwip_recv(a,b,c,d) +#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) +#define send(a,b,c,d) lwip_send(a,b,c,d) +#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) +#define socket(a,b,c) lwip_socket(a,b,c) +#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) +#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) + + +#if LWIP_POSIX_SOCKETS_IO_NAMES +#define read(a,b,c) lwip_read(a,b,c) +#define write(a,b,c) lwip_write(a,b,c) +#define close(s) lwip_close(s) +#define fcntl(a,b,c) lwip_fcntl(a,b,c) +#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ + +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SOCKET */ + +#endif /* __LWIP_SOCKETS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/stats.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/stats.h new file mode 100644 index 0000000..1f5152a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/stats.h @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_STATS_H__ +#define __LWIP_STATS_H__ + +#include "lwip/opt.h" + +#include "lwip/mem.h" +#include "lwip/memp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_STATS + +#ifndef LWIP_STATS_LARGE +#define LWIP_STATS_LARGE 0 +#endif + +#if LWIP_STATS_LARGE +#define STAT_COUNTER u32_t +#define STAT_COUNTER_F U32_F +#else +#define STAT_COUNTER u16_t +#define STAT_COUNTER_F U16_F +#endif + +struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER cachehit; +}; + +struct stats_igmp { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER rx_v1; /* Received v1 frames. */ + STAT_COUNTER rx_group; /* Received group-specific queries. */ + STAT_COUNTER rx_general; /* Received general queries. */ + STAT_COUNTER rx_report; /* Received reports. */ + STAT_COUNTER tx_join; /* Sent joins. */ + STAT_COUNTER tx_leave; /* Sent leaves. */ + STAT_COUNTER tx_report; /* Sent reports. */ +}; + +struct stats_mem { +#ifdef LWIP_DEBUG + const char *name; +#endif /* LWIP_DEBUG */ + mem_size_t avail; + mem_size_t used; + mem_size_t max; + STAT_COUNTER err; + STAT_COUNTER illegal; +}; + +struct stats_syselem { + STAT_COUNTER used; + STAT_COUNTER max; + STAT_COUNTER err; +}; + +struct stats_sys { + struct stats_syselem sem; + struct stats_syselem mutex; + struct stats_syselem mbox; +}; + +struct stats_ { +#if LINK_STATS + struct stats_proto link; +#endif +#if ETHARP_STATS + struct stats_proto etharp; +#endif +#if IPFRAG_STATS + struct stats_proto ip_frag; +#endif +#if IP_STATS + struct stats_proto ip; +#endif +#if ICMP_STATS + struct stats_proto icmp; +#endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif +#if UDP_STATS + struct stats_proto udp; +#endif +#if TCP_STATS + struct stats_proto tcp; +#endif +#if MEM_STATS + struct stats_mem mem; +#endif +#if MEMP_STATS + struct stats_mem memp[MEMP_MAX]; +#endif +#if SYS_STATS + struct stats_sys sys; +#endif +}; + +extern struct stats_ lwip_stats; + +void stats_init(void); + +#define STATS_INC(x) ++lwip_stats.x +#define STATS_DEC(x) --lwip_stats.x +#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ + if (lwip_stats.x.max < lwip_stats.x.used) { \ + lwip_stats.x.max = lwip_stats.x.used; \ + } \ + } while(0) +#else /* LWIP_STATS */ +#define stats_init() +#define STATS_INC(x) +#define STATS_DEC(x) +#define STATS_INC_USED(x) +#endif /* LWIP_STATS */ + +#if TCP_STATS +#define TCP_STATS_INC(x) STATS_INC(x) +#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") +#else +#define TCP_STATS_INC(x) +#define TCP_STATS_DISPLAY() +#endif + +#if UDP_STATS +#define UDP_STATS_INC(x) STATS_INC(x) +#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") +#else +#define UDP_STATS_INC(x) +#define UDP_STATS_DISPLAY() +#endif + +#if ICMP_STATS +#define ICMP_STATS_INC(x) STATS_INC(x) +#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") +#else +#define ICMP_STATS_INC(x) +#define ICMP_STATS_DISPLAY() +#endif + +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp) +#else +#define IGMP_STATS_INC(x) +#define IGMP_STATS_DISPLAY() +#endif + +#if IP_STATS +#define IP_STATS_INC(x) STATS_INC(x) +#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") +#else +#define IP_STATS_INC(x) +#define IP_STATS_DISPLAY() +#endif + +#if IPFRAG_STATS +#define IPFRAG_STATS_INC(x) STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") +#else +#define IPFRAG_STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() +#endif + +#if ETHARP_STATS +#define ETHARP_STATS_INC(x) STATS_INC(x) +#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") +#else +#define ETHARP_STATS_INC(x) +#define ETHARP_STATS_DISPLAY() +#endif + +#if LINK_STATS +#define LINK_STATS_INC(x) STATS_INC(x) +#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") +#else +#define LINK_STATS_INC(x) +#define LINK_STATS_DISPLAY() +#endif + +#if MEM_STATS +#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y +#define MEM_STATS_INC(x) STATS_INC(mem.x) +#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) +#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y +#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") +#else +#define MEM_STATS_AVAIL(x, y) +#define MEM_STATS_INC(x) +#define MEM_STATS_INC_USED(x, y) +#define MEM_STATS_DEC_USED(x, y) +#define MEM_STATS_DISPLAY() +#endif + +#if MEMP_STATS +#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y +#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) +#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) +#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) +#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) +#else +#define MEMP_STATS_AVAIL(x, i, y) +#define MEMP_STATS_INC(x, i) +#define MEMP_STATS_DEC(x, i) +#define MEMP_STATS_INC_USED(x, i) +#define MEMP_STATS_DISPLAY(i) +#endif + +#if SYS_STATS +#define SYS_STATS_INC(x) STATS_INC(sys.x) +#define SYS_STATS_DEC(x) STATS_DEC(sys.x) +#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) +#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) +#else +#define SYS_STATS_INC(x) +#define SYS_STATS_DEC(x) +#define SYS_STATS_INC_USED(x) +#define SYS_STATS_DISPLAY() +#endif + +/* Display of statistics */ +#if LWIP_STATS_DISPLAY +void stats_display(void); +void stats_display_proto(struct stats_proto *proto, const char *name); +void stats_display_igmp(struct stats_igmp *igmp); +void stats_display_mem(struct stats_mem *mem, const char *name); +void stats_display_memp(struct stats_mem *mem, int index); +void stats_display_sys(struct stats_sys *sys); +#else /* LWIP_STATS_DISPLAY */ +#define stats_display() +#define stats_display_proto(proto, name) +#define stats_display_igmp(igmp) +#define stats_display_mem(mem, name) +#define stats_display_memp(mem, index) +#define stats_display_sys(sys) +#endif /* LWIP_STATS_DISPLAY */ + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_STATS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sys.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sys.h new file mode 100644 index 0000000..9deadba --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/sys.h @@ -0,0 +1,338 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_SYS_H__ +#define __LWIP_SYS_H__ + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ +typedef u8_t sys_sem_t; +typedef u8_t sys_mutex_t; +typedef u8_t sys_mbox_t; + +#define sys_sem_new(s, c) ERR_OK +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_set_invalid(s) +#define sys_mutex_new(mu) ERR_OK +#define sys_mutex_lock(mu) +#define sys_mutex_unlock(mu) +#define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) +#define sys_mbox_new(m, s) ERR_OK +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_set_invalid(m) + +#define sys_thread_new(n,t,a,s,p) + +#define sys_msleep(t) + +#else /* NO_SYS */ + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +/** Function prototype for thread functions */ +typedef void (*lwip_thread_fn)(void *arg); + +/* Function prototypes for functions to be implemented by platform ports + (in sys_arch.c) */ + +/* Mutex functions: */ + +/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#if LWIP_COMPAT_MUTEX +/* for old ports that don't have mutexes: define them to binary semaphores */ +#define sys_mutex_t sys_sem_t +#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) +#define sys_mutex_lock(mutex) sys_sem_wait(mutex) +#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) +#define sys_mutex_free(mutex) sys_sem_free(mutex) +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +#else /* LWIP_COMPAT_MUTEX */ + +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ +err_t sys_mutex_new(sys_mutex_t *mutex); +/** Lock a mutex + * @param mutex the mutex to lock */ +void sys_mutex_lock(sys_mutex_t *mutex); +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void sys_mutex_unlock(sys_mutex_t *mutex); +/** Delete a semaphore + * @param mutex the mutex to delete */ +void sys_mutex_free(sys_mutex_t *mutex); +#ifndef sys_mutex_valid +/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mutex_valid(sys_mutex_t *mutex); +#endif +#ifndef sys_mutex_set_invalid +/** Set a mutex invalid so that sys_mutex_valid returns 0 */ +void sys_mutex_set_invalid(sys_mutex_t *mutex); +#endif +#endif /* LWIP_COMPAT_MUTEX */ + +/* Semaphore functions: */ + +/** Create a new semaphore + * @param sem pointer to the semaphore to create + * @param count initial count of the semaphore + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count); +/** Signals a semaphore + * @param sem the semaphore to signal */ +void sys_sem_signal(sys_sem_t *sem); +/** Wait for a semaphore for the specified timeout + * @param sem the semaphore to wait for + * @param timeout timeout in milliseconds to wait (0 = wait forever) + * @return time (in milliseconds) waited for the semaphore + * or SYS_ARCH_TIMEOUT on timeout */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); +/** Delete a semaphore + * @param sem semaphore to delete */ +void sys_sem_free(sys_sem_t *sem); +/** Wait for a semaphore - forever/no timeout */ +#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) +#ifndef sys_sem_valid +/** Check if a sempahore is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_sem_valid(sys_sem_t *sem); +#endif +#ifndef sys_sem_set_invalid +/** Set a semaphore invalid so that sys_sem_valid returns 0 */ +void sys_sem_set_invalid(sys_sem_t *sem); +#endif + +/* Time functions. */ +#ifndef sys_msleep +void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ +#endif + +/* Mailbox functions. */ + +/** Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (miminum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size); +/** Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg); +/** Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); +/* Allow port to override with a macro, e.g. special timout for sys_arch_mbox_fetch() */ +#ifndef sys_arch_mbox_tryfetch +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); +#endif +/** For now, we map straight to sys_arch implementation. */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +/** Delete an mbox + * @param mbox mbox to delete */ +void sys_mbox_free(sys_mbox_t *mbox); +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) +#ifndef sys_mbox_valid +/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mbox_valid(sys_mbox_t *mbox); +#endif +#ifndef sys_mbox_set_invalid +/** Set an mbox invalid so that sys_mbox_valid returns 0 */ +void sys_mbox_set_invalid(sys_mbox_t *mbox); +#endif + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); +//sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio); + +#endif /* NO_SYS */ + +/* sys_init() must be called before anthing else. */ +void sys_init(void); + +#ifndef sys_jiffies +/** Ticks/jiffies since power up. */ +u32_t sys_jiffies(void); +#endif + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +u32_t sys_now(void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __LWIP_SYS_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp.h new file mode 100644 index 0000000..f729575 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp.h @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_H__ +#define __LWIP_TCP_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct tcp_pcb; + +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +/** Function prototype for tcp accept callback functions. Called when a new + * connection can be accepted on a listening pcb. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param newpcb The new connection pcb + * @param err An error code if there has been an error accepting. + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); + +/** Function prototype for tcp receive callback functions. Called when data has + * been received. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which received data + * @param p The received data (or NULL when the connection has been closed!) + * @param err An error code if there has been an error receiving + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err); + +/** Function prototype for tcp sent callback functions. Called when sent data has + * been acknowledged by the remote side. Use it to free corresponding resources. + * This also means that the pcb has now space available to send new data. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb for which data has been acknowledged + * @param len The amount of bytes acknowledged + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, + u16_t len); + +/** Function prototype for tcp poll callback functions. Called periodically as + * specified by @see tcp_poll. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb tcp pcb + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); + +/** Function prototype for tcp error callback functions. Called when the pcb + * receives a RST or is unexpectedly closed for any other reason. + * + * @note The corresponding pcb is already freed when this callback is called! + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param err Error code to indicate why the pcb has been closed + * ERR_ABRT: aborted through tcp_abort or by a TCP timer + * ERR_RST: the connection was reset by the remote host + */ +typedef void (*tcp_err_fn)(void *arg, err_t err); + +/** Function prototype for tcp connected callback functions. Called when a pcb + * is connected to the remote side after initiating a connection attempt by + * calling tcp_connect(). + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which is connected + * @param err An unused error code, always ERR_OK currently ;-) TODO! + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + * + * @note When a connection attempt fails, the error callback is currently called! + */ +typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); + +enum tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + +#if LWIP_CALLBACK_API + /* Function to call when a listener has been connected. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb a new tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: accept the new connection, + * any other err_t abortsthe new connection + */ +#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; +#else /* LWIP_CALLBACK_API */ +#define DEF_ACCEPT_CALLBACK +#endif /* LWIP_CALLBACK_API */ + +/** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +#define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ + void *callback_arg; \ + /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ + DEF_ACCEPT_CALLBACK \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + /* ports are in host byte order */ \ + u16_t local_port + + +/* the TCP protocol control block */ +struct tcp_pcb { +/** common PCB members */ + IP_PCB; +/** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); + + /* ports are in host byte order */ + u16_t remote_port; + + u8_t flags; +#define TF_ACK_DELAY ((u8_t)0x01U) /* Delayed ACK. */ +#define TF_ACK_NOW ((u8_t)0x02U) /* Immediate ACK. */ +#define TF_INFR ((u8_t)0x04U) /* In fast recovery. */ +#define TF_TIMESTAMP ((u8_t)0x08U) /* Timestamp option enabled */ +#define TF_RXCLOSED ((u8_t)0x10U) /* rx closed by tcp_shutdown */ +#define TF_FIN ((u8_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((u8_t)0x40U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((u8_t)0x80U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ + + /* the rest of the fields are in host byte order + as we have to do some math with them */ + + /* Timers */ + u8_t polltmr, pollinterval; + u8_t last_timer; + u32_t tmr; + + /* receiver variables */ + u32_t rcv_nxt; /* next seqno expected */ + u16_t rcv_wnd; /* receiver window available */ + u16_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ + + /* Retransmission timer. */ + s16_t rtime; + + u16_t mss; /* maximum segment size */ + + /* RTT (round trip time) estimation variables */ + u32_t rttest; /* RTT estimate in 500ms ticks */ + u32_t rtseq; /* sequence number being timed */ + s16_t sa, sv; /* @todo document this */ + + s16_t rto; /* retransmission time-out */ + u8_t nrtx; /* number of retransmissions */ + + /* fast retransmit/recovery */ + u8_t dupacks; + u32_t lastack; /* Highest acknowledged seqno. */ + + /* congestion avoidance/control variables */ + u16_t cwnd; + u16_t ssthresh; + + /* sender variables */ + u32_t snd_nxt; /* next new seqno to be sent */ + u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last + window update. */ + u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + u16_t snd_wnd; /* sender window */ + u16_t snd_wnd_max; /* the maximum sender window announced by the remote host */ + + u16_t acked; + + u16_t snd_buf; /* Available buffer space for sending (in bytes). */ +#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) + u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */ + +#if TCP_OVERSIZE + /* Extra bytes available at the end of the last pbuf in unsent. */ + u16_t unsent_oversize; +#endif /* TCP_OVERSIZE */ + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +#if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ +#endif /* TCP_QUEUE_OOSEQ */ + + struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ + +#if LWIP_CALLBACK_API + /* Function to be called when more send buffer space is available. */ + tcp_sent_fn sent; + /* Function to be called when (in-sequence) data has arrived. */ + tcp_recv_fn recv; + /* Function to be called when a connection has been set up. */ + tcp_connected_fn connected; + /* Function which is called periodically. */ + tcp_poll_fn poll; + /* Function to be called whenever a fatal error occurs. */ + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + +#if LWIP_TCP_TIMESTAMPS + u32_t ts_lastacksent; + u32_t ts_recent; +#endif /* LWIP_TCP_TIMESTAMPS */ + + /* idle time before KEEPALIVE is sent */ + u32_t keep_idle; +#if LWIP_TCP_KEEPALIVE + u32_t keep_intvl; + u32_t keep_cnt; +#endif /* LWIP_TCP_KEEPALIVE */ + + /* Persist timer counter */ + u8_t persist_cnt; + /* Persist timer back-off */ + u8_t persist_backoff; + + /* KEEPALIVE counter */ + u8_t keep_cnt_sent; +}; + +struct tcp_pcb_listen { +/* Common members of all PCB types */ + IP_PCB; +/* Protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb_listen); + +#if TCP_LISTEN_BACKLOG + u8_t backlog; + u8_t accepts_pending; +#endif /* TCP_LISTEN_BACKLOG */ +}; + +#if LWIP_EVENT_API + +enum lwip_event { + LWIP_EVENT_ACCEPT, + LWIP_EVENT_SENT, + LWIP_EVENT_RECV, + LWIP_EVENT_CONNECTED, + LWIP_EVENT_POLL, + LWIP_EVENT_ERR +}; + +err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, + enum lwip_event, + struct pbuf *p, + u16_t size, + err_t err); + +#endif /* LWIP_EVENT_API */ + +/* Application program's interface: */ +struct tcp_pcb * tcp_new (void); + +void tcp_arg (struct tcp_pcb *pcb, void *arg); +void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); +void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); +void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); +void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); +void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); + +#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) +#define tcp_sndbuf(pcb) ((pcb)->snd_buf) +#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) +#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) +#define tcp_nagle_enable(pcb) ((pcb)->flags &= ~TF_NODELAY) +#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) + +#if TCP_LISTEN_BACKLOG +#define tcp_accepted(pcb) do { \ + LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ + (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) +#else /* TCP_LISTEN_BACKLOG */ +#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ + (pcb)->state == LISTEN) +#endif /* TCP_LISTEN_BACKLOG */ + +void tcp_recved (struct tcp_pcb *pcb, u16_t len); +err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, tcp_connected_fn connected); + +struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +void tcp_abort (struct tcp_pcb *pcb); +err_t tcp_close (struct tcp_pcb *pcb); +err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); + +/* Flags for "apiflags" parameter in tcp_write */ +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + +err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); + +void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); + +#define TCP_PRIO_MIN 1 +#define TCP_PRIO_NORMAL 64 +#define TCP_PRIO_MAX 127 + +err_t tcp_output (struct tcp_pcb *pcb); + + +const char* tcp_debug_state_str(enum tcp_state s); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp_impl.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp_impl.h new file mode 100644 index 0000000..173de44 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcp_impl.h @@ -0,0 +1,486 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCP_IMPL_H__ +#define __LWIP_TCP_IMPL_H__ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions for interfacing with TCP: */ + +/* Lower layer interface to TCP: */ +void tcp_init (void); /* Initialize this module. */ +void tcp_tmr (void); /* Must be called every + TCP_TMR_INTERVAL + ms. (Typically 250 ms). */ +/* It is also possible to call these two functions at the right + intervals (instead of calling tcp_tmr()). */ +void tcp_slowtmr (void); +void tcp_fasttmr (void); + + +/* Only used by IP to pass a TCP segment to TCP: */ +void tcp_input (struct pbuf *p, struct netif *inp); +/* Used within the TCP code only: */ +struct tcp_pcb * tcp_alloc (u8_t prio); +void tcp_abandon (struct tcp_pcb *pcb, int reset); +err_t tcp_send_empty_ack(struct tcp_pcb *pcb); +void tcp_rexmit (struct tcp_pcb *pcb); +void tcp_rexmit_rto (struct tcp_pcb *pcb); +void tcp_rexmit_fast (struct tcp_pcb *pcb); +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); +err_t tcp_process_refused_data(struct tcp_pcb *pcb); + +/** + * This is the Nagle algorithm: try to combine user data to send as few TCP + * segments as possible. Only send if + * - no previously transmitted data on the connection remains unacknowledged or + * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or + * - the only unsent segment is at least pcb->mss bytes long (or there is more + * than one unsent segment - with lwIP, this can happen although unsent->len < mss) + * - or if we are in fast-retransmit (TF_INFR) + */ +#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ + ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ + (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ + ((tpcb)->unsent->len >= (tpcb)->mss))) || \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ + ) ? 1 : 0) +#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) + + +#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) +/* is b<=a<=c? */ +#if 0 /* see bug #10548 */ +#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) +#endif +#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U + +#define TCP_FLAGS 0x3fU + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +#ifndef TCP_TMR_INTERVAL +#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ +#endif /* TCP_TMR_INTERVAL */ + +#ifndef TCP_FAST_INTERVAL +#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ +#endif /* TCP_FAST_INTERVAL */ + +#ifndef TCP_SLOW_INTERVAL +#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ +#endif /* TCP_SLOW_INTERVAL */ + +#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ +#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ + +#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ + +#ifndef TCP_MSL +#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ +#endif + +/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ +#ifndef TCP_KEEPIDLE_DEFAULT +#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ +#endif + +#ifndef TCP_KEEPINTVL_DEFAULT +#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ +#endif + +#ifndef TCP_KEEPCNT_DEFAULT +#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ +#endif + +#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) +#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) + +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) +#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) + +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) + +#define TCP_TCPLEN(seg) ((seg)->len + ((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0)) + +/** Flags used on input processing, not on pcb->flags +*/ +#define TF_RESET (u8_t)0x08U /* Connection was reset. */ +#define TF_CLOSED (u8_t)0x10U /* Connection was sucessfully closed. */ +#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ + + +#if LWIP_EVENT_API + +#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_ACCEPT, NULL, 0, err) +#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_SENT, NULL, space, ERR_OK) +#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, (p), 0, (err)) +#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, NULL, 0, ERR_OK) +#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_CONNECTED, NULL, 0, (err)) +#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_POLL, NULL, 0, ERR_OK) +#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ + LWIP_EVENT_ERR, NULL, 0, (err)) + +#else /* LWIP_EVENT_API */ + +#define TCP_EVENT_ACCEPT(pcb,err,ret) \ + do { \ + if((pcb)->accept != NULL) \ + (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_ARG; \ + } while (0) + +#define TCP_EVENT_SENT(pcb,space,ret) \ + do { \ + if((pcb)->sent != NULL) \ + (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_RECV(pcb,p,err,ret) \ + do { \ + if((pcb)->recv != NULL) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ + } else { \ + (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ + } \ + } while (0) + +#define TCP_EVENT_CLOSED(pcb,ret) \ + do { \ + if(((pcb)->recv != NULL)) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ + } else { \ + (ret) = ERR_OK; \ + } \ + } while (0) + +#define TCP_EVENT_CONNECTED(pcb,err,ret) \ + do { \ + if((pcb)->connected != NULL) \ + (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_POLL(pcb,ret) \ + do { \ + if((pcb)->poll != NULL) \ + (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_ERR(errf,arg,err) \ + do { \ + if((errf) != NULL) \ + (errf)((arg),(err)); \ + } while (0) + +#endif /* LWIP_EVENT_API */ + +/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ +#if TCP_OVERSIZE && defined(LWIP_DEBUG) +#define TCP_OVERSIZE_DBGCHECK 1 +#else +#define TCP_OVERSIZE_DBGCHECK 0 +#endif + +/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ +#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) + +/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ +struct tcp_seg { + struct tcp_seg *next; /* used when putting segements on a queue */ + struct pbuf *p; /* buffer containing data + TCP header */ + u16_t len; /* the TCP length of this segment */ +#if TCP_OVERSIZE_DBGCHECK + u16_t oversize_left; /* Extra bytes available at the end of the last + pbuf in unsent (used for asserting vs. + tcp_pcb.unsent_oversized only) */ +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + u16_t chksum; + u8_t chksum_swapped; +#endif /* TCP_CHECKSUM_ON_COPY */ + u8_t flags; +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ +#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is + checksummed into 'chksum' */ + struct tcp_hdr *tcphdr; /* the TCP header */ +}; + +#define LWIP_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \ + (flags & TF_SEG_OPTS_TS ? 12 : 0) + +/** This returns a TCP header option for MSS in an u32_t */ +#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) + +/* Global variables: */ +extern struct tcp_pcb *tcp_input_pcb; +extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; + +/* The TCP PCB lists. */ +union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ + struct tcp_pcb_listen *listen_pcbs; + struct tcp_pcb *pcbs; +}; +extern struct tcp_pcb *tcp_bound_pcbs; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ + +/* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. + 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. + 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. +*/ +/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB + with a PCB list or removes a PCB from a list, respectively. */ +#ifndef TCP_DEBUG_PCB_LISTS +#define TCP_DEBUG_PCB_LISTS 0 +#endif +#if TCP_DEBUG_PCB_LISTS +#define TCP_REG(pcbs, npcb) do {\ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ + for(tcp_tmp_pcb = *(pcbs); \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ + } \ + LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ + (npcb)->next = *(pcbs); \ + LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ + *(pcbs) = (npcb); \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + tcp_timer_needed(); \ + } while(0) +#define TCP_RMV(pcbs, npcb) do { \ + LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ + if(*(pcbs) == (npcb)) { \ + *(pcbs) = (*pcbs)->next; \ + } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + (npcb)->next = NULL; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ + } while(0) + +#else /* LWIP_DEBUG */ + +#define TCP_REG(pcbs, npcb) \ + do { \ + (npcb)->next = *pcbs; \ + *(pcbs) = (npcb); \ + tcp_timer_needed(); \ + } while (0) + +#define TCP_RMV(pcbs, npcb) \ + do { \ + if(*(pcbs) == (npcb)) { \ + (*(pcbs)) = (*pcbs)->next; \ + } \ + else { \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + } \ + (npcb)->next = NULL; \ + } while(0) + +#endif /* LWIP_DEBUG */ + +#define TCP_REG_ACTIVE(npcb) \ + do { \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_RMV_ACTIVE(npcb) \ + do { \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_PCB_REMOVE_ACTIVE(pcb) \ + do { \ + tcp_pcb_remove(&tcp_active_pcbs, pcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + + +/* Internal functions: */ +struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); +void tcp_pcb_purge(struct tcp_pcb *pcb); +void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); + +void tcp_segs_free(struct tcp_seg *seg); +void tcp_seg_free(struct tcp_seg *seg); +struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); + +#define tcp_ack(pcb) \ + do { \ + if((pcb)->flags & TF_ACK_DELAY) { \ + (pcb)->flags &= ~TF_ACK_DELAY; \ + (pcb)->flags |= TF_ACK_NOW; \ + } \ + else { \ + (pcb)->flags |= TF_ACK_DELAY; \ + } \ + } while (0) + +#define tcp_ack_now(pcb) \ + do { \ + (pcb)->flags |= TF_ACK_NOW; \ + } while (0) + +err_t tcp_send_fin(struct tcp_pcb *pcb); +err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); + +void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); + +void tcp_rst(u32_t seqno, u32_t ackno, + ip_addr_t *local_ip, ip_addr_t *remote_ip, + u16_t local_port, u16_t remote_port); + +u32_t tcp_next_iss(void); + +void tcp_keepalive(struct tcp_pcb *pcb); +void tcp_zero_window_probe(struct tcp_pcb *pcb); + +#if TCP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss(u16_t sendmss, ip_addr_t *addr); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +#if LWIP_CALLBACK_API +err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +#endif /* LWIP_CALLBACK_API */ + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +void tcp_debug_print(struct tcp_hdr *tcphdr); +void tcp_debug_print_flags(u8_t flags); +void tcp_debug_print_state(enum tcp_state s); +void tcp_debug_print_pcbs(void); +s16_t tcp_pcbs_sane(void); +#else +# define tcp_debug_print(tcphdr) +# define tcp_debug_print_flags(flags) +# define tcp_debug_print_state(s) +# define tcp_debug_print_pcbs() +# define tcp_pcbs_sane() 1 +#endif /* TCP_DEBUG */ + +/** External function (implemented in timers.c), called when TCP detects + * that a timer is needed (i.e. active- or time-wait-pcb found). */ +void tcp_timer_needed(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* __LWIP_TCP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcpip.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcpip.h new file mode 100644 index 0000000..08aa67a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/tcpip.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_TCPIP_H__ +#define __LWIP_TCPIP_H__ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" +#include "lwip/netifapi.h" +#include "lwip/pbuf.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/lwip_timers.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define this to something that triggers a watchdog. This is called from + * tcpip_thread after processing a message. */ +#ifndef LWIP_TCPIP_THREAD_ALIVE +#define LWIP_TCPIP_THREAD_ALIVE() +#endif + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_mutex_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) +#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m) +#define TCPIP_APIMSG_ACK(m) +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) +#else /* LWIP_TCPIP_CORE_LOCKING */ +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG(m) tcpip_apimsg(m) +#define TCPIP_APIMSG_ACK(m) sys_sem_signal(&m->conn->op_completed) +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** Function prototype for the init_done function passed to tcpip_init */ +typedef void (*tcpip_init_done_fn)(void *arg); +/** Function prototype for functions passed to tcpip_callback() */ +typedef void (*tcpip_callback_fn)(void *ctx); + +/* Forward declarations */ +struct tcpip_callback_msg; + +void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); + +#if LWIP_NETCONN +err_t tcpip_apimsg(struct api_msg *apimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_apimsg_lock(struct api_msg *apimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETCONN */ + +err_t tcpip_input(struct pbuf *p, struct netif *inp); + +#if LWIP_NETIF_API +err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); +#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) + +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + +/* free pbufs or heap memory from another context without blocking */ +err_t pbuf_free_callback(struct pbuf *p); +err_t mem_free_callback(void *m); + +#if LWIP_TCPIP_TIMEOUT +err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +err_t tcpip_untimeout(sys_timeout_handler h, void *arg); +#endif /* LWIP_TCPIP_TIMEOUT */ + +enum tcpip_msg_type { +#if LWIP_NETCONN + TCPIP_MSG_API, +#endif /* LWIP_NETCONN */ + TCPIP_MSG_INPKT, +#if LWIP_NETIF_API + TCPIP_MSG_NETIFAPI, +#endif /* LWIP_NETIF_API */ +#if LWIP_TCPIP_TIMEOUT + TCPIP_MSG_TIMEOUT, + TCPIP_MSG_UNTIMEOUT, +#endif /* LWIP_TCPIP_TIMEOUT */ + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC +}; + +struct tcpip_msg { + enum tcpip_msg_type type; + sys_sem_t *sem; + union { +#if LWIP_NETCONN + struct api_msg *apimsg; +#endif /* LWIP_NETCONN */ +#if LWIP_NETIF_API + struct netifapi_msg *netifapimsg; +#endif /* LWIP_NETIF_API */ + struct { + struct pbuf *p; + struct netif *netif; + } inp; + struct { + tcpip_callback_fn function; + void *ctx; + } cb; +#if LWIP_TCPIP_TIMEOUT + struct { + u32_t msecs; + sys_timeout_handler h; + void *arg; + } tmo; +#endif /* LWIP_TCPIP_TIMEOUT */ + } msg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !NO_SYS */ + +#endif /* __LWIP_TCPIP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/udp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/udp.h new file mode 100644 index 0000000..f1e6d3f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/lwip/udp.h @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIP_UDP_H__ +#define __LWIP_UDP_H__ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define UDP_FLAGS_NOCHKSUM 0x01U +#define UDP_FLAGS_UDPLITE 0x02U +#define UDP_FLAGS_CONNECTED 0x04U +#define UDP_FLAGS_MULTICAST_LOOP 0x08U + +struct udp_pcb; + +/** Function prototype for udp pcb receive callback functions + * addr and port are in same byte order as in the pcb + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf + * makes 'addr' invalid, too. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port); + + +struct udp_pcb { +/* Common members of all PCB types */ + IP_PCB; + +/* Protocol specific PCB members */ + + struct udp_pcb *next; + + u8_t flags; + /** ports are in host byte order */ + u16_t local_port, remote_port; + +#if LWIP_IGMP + /** outgoing network interface for multicast packets */ + ip_addr_t multicast_ip; +#endif /* LWIP_IGMP */ + +#if LWIP_UDPLITE + /** used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +#endif /* LWIP_UDPLITE */ + + /** receive callback function */ + udp_recv_fn recv; + /** user-supplied argument for the recv callback */ + void *recv_arg; +}; +/* udp_pcbs export for exernal reference (e.g. SNMP agent) */ +extern struct udp_pcb *udp_pcbs; + +/* The following functions is the application layer interface to the + UDP code. */ +struct udp_pcb * udp_new (void); +void udp_remove (struct udp_pcb *pcb); +err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +void udp_disconnect (struct udp_pcb *pcb); +void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, + void *recv_arg); +err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif); +err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port); +err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); + +#if LWIP_CHECKSUM_ON_COPY +err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif, u8_t have_chksum, + u16_t chksum); +err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + u8_t have_chksum, u16_t chksum); +err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#define udp_flags(pcb) ((pcb)->flags) +#define udp_setflags(pcb, f) ((pcb)->flags = (f)) + +/* The following functions are the lower layer interface to UDP. */ +void udp_input (struct pbuf *p, struct netif *inp); + +void udp_init (void); + +#if UDP_DEBUG +void udp_debug_print(struct udp_hdr *udphdr); +#else +#define udp_debug_print(udphdr) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_UDP */ + +#endif /* __LWIP_UDP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/etharp.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/etharp.h new file mode 100644 index 0000000..859608d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/etharp.h @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef __NETIF_ETHARP_H__ +#define __NETIF_ETHARP_H__ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN 6 +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FIELD(u8_t addr[ETHARP_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** Ethernet header */ +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FIELD(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FIELD(struct eth_addr dest); + PACK_STRUCT_FIELD(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#if ETHARP_SUPPORT_VLAN + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** VLAN header inserted between ethernet header and payload + * if 'type' in ethernet header is ETHTYPE_VLAN. + * See IEEE802.Q */ +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) + +#endif /* ETHARP_SUPPORT_VLAN */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message, see RFC 826 ("Packet format") */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FIELD(u8_t hwlen); + PACK_STRUCT_FIELD(u8_t protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FIELD(struct eth_addr shwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 sipaddr); + PACK_STRUCT_FIELD(struct eth_addr dhwaddr); + PACK_STRUCT_FIELD(struct ip_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 +#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) + +/** 5 seconds period */ +#define ARP_TMR_INTERVAL 5000 + +#define ETHTYPE_ARP 0x0806U +#define ETHTYPE_IP 0x0800U +#define ETHTYPE_VLAN 0x8100U +#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables + * or known to be 32-bit aligned within the protocol header. */ +#ifndef ETHADDR32_COPY +#define ETHADDR32_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local + * variables and known to be 16-bit aligned within the protocol header. */ +#ifndef ETHADDR16_COPY +#define ETHADDR16_COPY(src, dst) SMEMCPY(src, dst, ETHARP_HWADDR_LEN) +#endif + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** ARP message types (opcodes) */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) + * to a filter function that returns the correct netif when using multiple + * netifs on one hardware interface where the netif's low-level receive + * routine cannot decide for the correct netif (e.g. when mapping multiple + * IP addresses to one hardware interface). + */ +#ifndef LWIP_ARP_FILTER_NETIF +#define LWIP_ARP_FILTER_NETIF 0 +#endif + +#if ARP_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct etharp_q_entry { + struct etharp_q_entry *next; + struct pbuf *p; +}; +#endif /* ARP_QUEUEING */ + +#define etharp_init() /* Compatibility define, not init needed. */ +void etharp_tmr(void); +s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret); +err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); +err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); +/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; + * this is an ARP packet sent by a node in order to spontaneously cause other + * nodes to update an entry in their ARP cache. + * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ +#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) +void etharp_cleanup_netif(struct netif *netif); + +#if ETHARP_SUPPORT_STATIC_ENTRIES +err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); +err_t etharp_remove_static_entry(ip_addr_t *ipaddr); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_AUTOIP +err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode); +#endif /* LWIP_AUTOIP */ + +#endif /* LWIP_ARP */ + +err_t ethernet_input(struct pbuf *p, struct netif *netif); + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) + +extern const struct eth_addr ethbroadcast, ethzero; + +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +#ifdef __cplusplus +} +#endif + +#endif /* __NETIF_ARP_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/loopif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/loopif.h new file mode 100644 index 0000000..e69de29 diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/ppp_oe.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/ppp_oe.h new file mode 100644 index 0000000..e1cdfa5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/ppp_oe.h @@ -0,0 +1,190 @@ +/***************************************************************************** +* ppp_oe.h - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef PPP_OE_H +#define PPP_OE_H + +#include "lwip/opt.h" + +#if PPPOE_SUPPORT > 0 + +#include "netif/etharp.h" + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoehdr { + PACK_STRUCT_FIELD(u8_t vertype); + PACK_STRUCT_FIELD(u8_t code); + PACK_STRUCT_FIELD(u16_t session); + PACK_STRUCT_FIELD(u16_t plen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoetag { + PACK_STRUCT_FIELD(u16_t tag); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#define PPPOE_STATE_INITIAL 0 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +#define PPPOE_STATE_CLOSING 4 +/* passive */ +#define PPPOE_STATE_PADO_SENT 1 + +#define PPPOE_HEADERLEN sizeof(struct pppoehdr) +#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ + +#define PPPOE_TAG_EOL 0x0000 /* end of list */ +#define PPPOE_TAG_SNAME 0x0101 /* service name */ +#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ +#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ +#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ +#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ +#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ +#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ +#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ +#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ + +#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ +#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ +#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ +#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ +#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ + +#ifndef ETHERMTU +#define ETHERMTU 1500 +#endif + +/* two byte PPP protocol discriminator, then IP data */ +#define PPPOE_MAXMTU (ETHERMTU-PPPOE_HEADERLEN-2) + +#ifndef PPPOE_MAX_AC_COOKIE_LEN +#define PPPOE_MAX_AC_COOKIE_LEN 64 +#endif + +struct pppoe_softc { + struct pppoe_softc *next; + struct netif *sc_ethif; /* ethernet interface we are using */ + int sc_pd; /* ppp unit number */ + void (*sc_linkStatusCB)(int pd, int up); + + int sc_state; /* discovery phase or session connected */ + struct eth_addr sc_dest; /* hardware address of concentrator */ + u16_t sc_session; /* PPPoE session id */ + +#ifdef PPPOE_TODO + char *sc_service_name; /* if != NULL: requested name of service */ + char *sc_concentrator_name; /* if != NULL: requested concentrator id */ +#endif /* PPPOE_TODO */ + u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ + size_t sc_ac_cookie_len; /* length of cookie data */ +#ifdef PPPOE_SERVER + u8_t *sc_hunique; /* content of host unique we must echo back */ + size_t sc_hunique_len; /* length of host unique */ +#endif + int sc_padi_retried; /* number of PADI retries already done */ + int sc_padr_retried; /* number of PADR retries already done */ +}; + + +#define pppoe_init() /* compatibility define, no initialization needed */ + +err_t pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr); +err_t pppoe_destroy(struct netif *ifp); + +int pppoe_connect(struct pppoe_softc *sc); +void pppoe_disconnect(struct pppoe_softc *sc); + +void pppoe_disc_input(struct netif *netif, struct pbuf *p); +void pppoe_data_input(struct netif *netif, struct pbuf *p); + +err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); + +/** used in ppp.c */ +#define PPPOE_HDRLEN (sizeof(struct eth_hdr) + PPPOE_HEADERLEN) + +#endif /* PPPOE_SUPPORT */ + +#endif /* PPP_OE_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/slipif.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/slipif.h new file mode 100644 index 0000000..7b6ce5e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/netif/slipif.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __NETIF_SLIPIF_H__ +#define __NETIF_SLIPIF_H__ + +#include "lwip/opt.h" +#include "lwip/netif.h" + +/** Set this to 1 to start a thread that blocks reading on the serial line + * (using sio_read()). + */ +#ifndef SLIP_USE_RX_THREAD +#define SLIP_USE_RX_THREAD !NO_SYS +#endif + +/** Set this to 1 to enable functions to pass in RX bytes from ISR context. + * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled + * packets on a queue, which is fed into lwIP from slipif_poll(). + * If disabled, slipif_poll() polls the serila line (using sio_tryread()). + */ +#ifndef SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 0 +#endif + +/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets + * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. + * If disabled, packets will be dropped if more than one packet is received. + */ +#ifndef SLIP_RX_QUEUE +#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +err_t slipif_init(struct netif * netif); +void slipif_poll(struct netif *netif); +#if SLIP_RX_FROM_ISR +void slipif_process_rxqueue(struct netif *netif); +void slipif_received_byte(struct netif *netif, u8_t data); +void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); +#endif /* SLIP_RX_FROM_ISR */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/netdb.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/netdb.h new file mode 100644 index 0000000..7134032 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/netdb.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/netdb.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/netdb.h" diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/sys/socket.h b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/sys/socket.h new file mode 100644 index 0000000..f7c7066 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/include/posix/sys/socket.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/sockets.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/sockets.h" diff --git a/USDK/component/common/network/lwip/lwip_v1.4.1/src/netif/etharp.c b/USDK/component/common/network/lwip/lwip_v1.4.1/src/netif/etharp.c new file mode 100644 index 0000000..a0d3d8e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.4.1/src/netif/etharp.c @@ -0,0 +1,1408 @@ +/** + * @file + * Address Resolution Protocol module for IP over Ethernet + * + * Functionally, ARP is divided into two parts. The first maps an IP address + * to a physical address when sending a packet, and the second part answers + * requests from other machines for our physical address. + * + * This implementation complies with RFC 826 (Ethernet ARP). It supports + * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 + * if an interface calls etharp_gratuitous(our_netif) upon address change. + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET + +#include "lwip/ip_addr.h" +#include "lwip/def.h" +#include "lwip/ip.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#if PPPOE_SUPPORT +#include "netif/ppp_oe.h" +#endif /* PPPOE_SUPPORT */ + +#include + +const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; +const struct eth_addr ethzero = {{0,0,0,0,0,0}}; + +/** The 24-bit IANA multicast OUI is 01-00-5e: */ +#define LL_MULTICAST_ADDR_0 0x01 +#define LL_MULTICAST_ADDR_1 0x00 +#define LL_MULTICAST_ADDR_2 0x5e + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** the time an ARP entry stays valid after its last update, + * for ARP_TMR_INTERVAL = 5000, this is + * (240 * 5) seconds = 20 minutes. + */ +#define ARP_MAXAGE 240 +/** Re-request a used ARP entry 1 minute before it would expire to prevent + * breaking a steadily used connection because the ARP entry timed out. */ +#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 12) + +/** the time an ARP entry stays pending after first request, + * for ARP_TMR_INTERVAL = 5000, this is + * (2 * 5) seconds = 10 seconds. + * + * @internal Keep this number at least 2, otherwise it might + * run out instantly if the timeout occurs directly after a request. + */ +#define ARP_MAXPENDING 2 + +#define HWTYPE_ETHERNET 1 + +enum etharp_state { + ETHARP_STATE_EMPTY = 0, + ETHARP_STATE_PENDING, + ETHARP_STATE_STABLE, + ETHARP_STATE_STABLE_REREQUESTING +#if ETHARP_SUPPORT_STATIC_ENTRIES + ,ETHARP_STATE_STATIC +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ +}; + +struct etharp_entry { +#if ARP_QUEUEING + /** Pointer to queue of pending outgoing packets on this ARP entry. */ + struct etharp_q_entry *q; +#else /* ARP_QUEUEING */ + /** Pointer to a single pending outgoing packet on this ARP entry. */ + struct pbuf *q; +#endif /* ARP_QUEUEING */ + ip_addr_t ipaddr; + struct netif *netif; + struct eth_addr ethaddr; + u8_t state; + u8_t ctime; +}; + +static struct etharp_entry arp_table[ARP_TABLE_SIZE]; + +#if !LWIP_NETIF_HWADDRHINT +static u8_t etharp_cached_entry; +#endif /* !LWIP_NETIF_HWADDRHINT */ + +/** Try hard to create a new entry - we want the IP address to appear in + the cache (even if this means removing an active entry or so). */ +#define ETHARP_FLAG_TRY_HARD 1 +#define ETHARP_FLAG_FIND_ONLY 2 +#if ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_FLAG_STATIC_ENTRY 4 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_NETIF_HWADDRHINT +#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ + *((netif)->addr_hint) = (hint); +#else /* LWIP_NETIF_HWADDRHINT */ +#define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) +#endif /* LWIP_NETIF_HWADDRHINT */ + + +/* Some checks, instead of etharp_init(): */ +#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) + #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" +#endif + + +#if ARP_QUEUEING +/** + * Free a complete queue of etharp entries + * + * @param q a qeueue of etharp_q_entry's to free + */ +static void +free_etharp_q(struct etharp_q_entry *q) +{ + struct etharp_q_entry *r; + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("q->p != NULL", q->p != NULL); + while (q) { + r = q; + q = q->next; + LWIP_ASSERT("r->p != NULL", (r->p != NULL)); + pbuf_free(r->p); + memp_free(MEMP_ARP_QUEUE, r); + } +} +#else /* ARP_QUEUEING */ + +/** Compatibility define: free the queued pbuf */ +#define free_etharp_q(q) pbuf_free(q) + +#endif /* ARP_QUEUEING */ + +/** Clean up ARP table entries */ +static void +etharp_free_entry(int i) +{ + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + arp_table[i].q = NULL; + } + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; +#ifdef LWIP_DEBUG + /* for debugging, clean out the complete entry */ + arp_table[i].ctime = 0; + arp_table[i].netif = NULL; + ip_addr_set_zero(&arp_table[i].ipaddr); + arp_table[i].ethaddr = ethzero; +#endif /* LWIP_DEBUG */ +} + +/** + * Clears expired entries in the ARP table. + * + * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if (state != ETHARP_STATE_EMPTY +#if ETHARP_SUPPORT_STATIC_ENTRIES + && (state != ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) { + arp_table[i].ctime++; + if ((arp_table[i].ctime >= ARP_MAXAGE) || + ((arp_table[i].state == ETHARP_STATE_PENDING) && + (arp_table[i].ctime >= ARP_MAXPENDING))) { + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + etharp_free_entry(i); + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; + } +#if ARP_QUEUEING + /* still pending entry? (not expired) */ + if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* resend an ARP query here? */ + } +#endif /* ARP_QUEUEING */ + } + } +} + +/** + * Search the ARP table for a matching or new entry. + * + * If an IP address is given, return a pending or stable ARP entry that matches + * the address. If no match is found, create a new entry with this address set, + * but in state ETHARP_EMPTY. The caller must check and possibly change the + * state of the returned entry. + * + * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. + * + * In all cases, attempt to create new entries from an empty entry. If no + * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle + * old entries. Heuristic choose the least important entry for recycling. + * + * @param ipaddr IP address to find in ARP cache, or to add if not found. + * @param flags @see definition of ETHARP_FLAG_* + * @param netif netif related to this address (used for NETIF_HWADDRHINT) + * + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) +{ + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + s8_t empty = ARP_TABLE_SIZE; + u8_t i = 0, age_pending = 0, age_stable = 0; + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + /* its age */ + u8_t age_queue = 0; + + /** + * a) do a search through the cache, remember candidates + * b) select candidate entry + * c) create new entry + */ + + /* a) in a single search sweep, do all of this + * 1) remember the first empty entry (if any) + * 2) remember the oldest stable entry (if any) + * 3) remember the oldest pending entry without queued packets (if any) + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + } else if (state != ETHARP_STATE_EMPTY) { + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ + return i; + } + /* pending entry? */ + if (state == ETHARP_STATE_PENDING) { + /* pending with queued packets? */ + if (arp_table[i].q != NULL) { + if (arp_table[i].ctime >= age_queue) { + old_queue = i; + age_queue = arp_table[i].ctime; + } + } else + /* pending without queued packets? */ + { + if (arp_table[i].ctime >= age_pending) { + old_pending = i; + age_pending = arp_table[i].ctime; + } + } + /* stable entry? */ + } else if (state >= ETHARP_STATE_STABLE) { +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* don't record old_stable for static entries since they never expire */ + if (state < ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + if (arp_table[i].ctime >= age_stable) { + old_stable = i; + age_stable = arp_table[i].ctime; + } + } + } + } + } + /* { we have no match } => try to create a new entry */ + + /* don't create new entry, only search? */ + if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || + /* or no empty entry found and not allowed to recycle? */ + ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + } + + /* b) choose the least destructive entry to recycle: + * 1) empty entry + * 2) oldest stable entry + * 3) oldest pending entry without queued packets + * 4) oldest pending entry with queued packets + * + * { ETHARP_FLAG_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + i = empty; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } else { + /* 2) found recyclable stable entry? */ + if (old_stable < ARP_TABLE_SIZE) { + /* recycle oldest stable*/ + i = old_stable; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + /* recycle oldest pending */ + i = old_pending; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ + i = old_queue; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + /* no empty or recyclable entries found */ + } else { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); + return (s8_t)ERR_MEM; + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + etharp_free_entry(i); + } + + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", + arp_table[i].state == ETHARP_STATE_EMPTY); + + /* IP address given? */ + if (ipaddr != NULL) { + /* set IP address */ + ip_addr_copy(arp_table[i].ipaddr, *ipaddr); + } + arp_table[i].ctime = 0; + return (err_t)i; +} + +/** + * Send an IP packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); + ETHADDR32_COPY(ðhdr->dest, dst); + ETHADDR16_COPY(ðhdr->src, src); + ethhdr->type = PP_HTONS(ETHTYPE_IP); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} + +/** + * Update (or insert) a IP/MAC address pair in the ARP cache. + * + * If a pending entry is resolved, any queued packets will be sent + * at this point. + * + * @param netif netif related to this entry (used for NETIF_ADDRHINT) + * @param ipaddr IP address of the inserted ARP entry. + * @param ethaddr Ethernet address of the inserted ARP entry. + * @param flags @see definition of ETHARP_FLAG_* + * + * @return + * - ERR_OK Succesfully updated ARP cache. + * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + * @see pbuf_free() + */ +static err_t +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + s8_t i; + LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, flags); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + +#if ETHARP_SUPPORT_STATIC_ENTRIES + if (flags & ETHARP_FLAG_STATIC_ENTRY) { + /* record static type */ + arp_table[i].state = ETHARP_STATE_STATIC; + } else +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + } + + /* record network interface */ + arp_table[i].netif = netif; + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); + /* reset time stamp */ + arp_table[i].ctime = 0; + /* this is where we will send out queued packets! */ +#if ARP_QUEUEING + while (arp_table[i].q != NULL) { + struct pbuf *p; + /* remember remainder of queue */ + struct etharp_q_entry *q = arp_table[i].q; + /* pop first item off the queue */ + arp_table[i].q = q->next; + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); +#else /* ARP_QUEUEING */ + if (arp_table[i].q != NULL) { + struct pbuf *p = arp_table[i].q; + arp_table[i].q = NULL; +#endif /* ARP_QUEUEING */ + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + /* free the queued IP packet */ + pbuf_free(p); + } + return ERR_OK; +} + +#if ETHARP_SUPPORT_STATIC_ENTRIES +/** Add a new static entry to the ARP table. If an entry exists for the + * specified IP address, this entry is overwritten. + * If packets are queued for the specified IP address, they are sent out. + * + * @param ipaddr IP address for the new static entry + * @param ethaddr ethernet address for the new static entry + * @return @see return values of etharp_add_static_entry + */ +err_t +etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) +{ + struct netif *netif; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + + netif = ip_route(ipaddr); + if (netif == NULL) { + return ERR_RTE; + } + + return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); +} + +/** Remove a static entry from the ARP table previously added with a call to + * etharp_add_static_entry. + * + * @param ipaddr IP address of the static entry to remove + * @return ERR_OK: entry removed + * ERR_MEM: entry wasn't found + * ERR_ARG: entry wasn't a static entry but a dynamic one + */ +err_t +etharp_remove_static_entry(ip_addr_t *ipaddr) +{ + s8_t i; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + + if (arp_table[i].state != ETHARP_STATE_STATIC) { + /* entry wasn't a static entry, cannot remove it */ + return ERR_ARG; + } + /* entry found, free it */ + etharp_free_entry(i); + return ERR_OK; +} +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +/** + * Remove all ARP table entries of the specified netif. + * + * @param netif points to a network interface + */ +void etharp_cleanup_netif(struct netif *netif) +{ + u8_t i; + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { + etharp_free_entry(i); + } + } +} + +/** + * Finds (stable) ethernet/IP address pair from ARP table + * using interface and IP address index. + * @note the addresses in the ARP table are in network order! + * + * @param netif points to interface index + * @param ipaddr points to the (network order) IP address index + * @param eth_ret points to return pointer + * @param ip_ret points to return pointer + * @return table index if found, -1 otherwise + */ +s8_t +etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret) +{ + s8_t i; + + LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", + eth_ret != NULL && ip_ret != NULL); + + LWIP_UNUSED_ARG(netif); + + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { + *eth_ret = &arp_table[i].ethaddr; + *ip_ret = &arp_table[i].ipaddr; + return i; + } + return -1; +} + +#if ETHARP_TRUST_IP_MAC +/** + * Updates the ARP table using the given IP packet. + * + * Uses the incoming IP packet's source address to update the + * ARP cache for the local network. The function does not alter + * or free the packet. This function must be called before the + * packet p is passed to the IP layer. + * + * @param netif The lwIP network interface on which the IP packet pbuf arrived. + * @param p The IP packet that arrived on netif. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_ip_input(struct netif *netif, struct pbuf *p) +{ + struct eth_hdr *ethhdr; + struct ip_hdr *iphdr; + ip_addr_t iphdr_src; + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* Only insert an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + ethhdr = (struct eth_hdr *)p->payload; + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + ip_addr_copy(iphdr_src, iphdr->src); + + /* source is not on the local network? */ + if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) { + /* do nothing */ + return; + } + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); + /* update the source IP address in the cache, if present */ + /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk + * back soon (for example, if the destination IP address is ours. */ + etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); +} +#endif /* ETHARP_TRUST_IP_MAC */ + +/** + * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache + * send out queued IP packets. Updates cache with snooped address pairs. + * + * Should be called for incoming ARP packets. The pbuf in the argument + * is freed by this function. + * + * @param netif The lwIP network interface on which the ARP packet pbuf arrived. + * @param ethaddr Ethernet address of netif. + * @param p The ARP packet that arrived on netif. Is freed by this function. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + struct etharp_hdr *hdr; + struct eth_hdr *ethhdr; + /* these are aligned properly, whereas the ARP header fields might not be */ + ip_addr_t sipaddr, dipaddr; + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + + ethhdr = (struct eth_hdr *)p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + (hdr->hwlen != ETHARP_HWADDR_LEN) || + (hdr->protolen != sizeof(ip_addr_t)) || + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + ETHARP_STATS_INC(etharp.recv); + +#if LWIP_AUTOIP + /* We have to check if a host already has configured our random + * created link local address and continously check if there is + * a host with this IP-address so we can detect collisions */ + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + /* this interface is not configured? */ + if (ip_addr_isany(&netif->ip_addr)) { + for_us = 0; + } else { + /* ARP packet directed to us? */ + for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + } + + /* ARP message directed to us? + -> add IP address in ARP cache; assume requester wants to talk to us, + can result in directly sending the queued packets for this host. + ARP message not directed to us? + -> update the source IP address in the cache, if present */ + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); + + /* now act on the message itself */ + switch (hdr->opcode) { + /* ARP request? */ + case PP_HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + * reply. In any case, we time-stamp any existing ARP entry, + * and possiby send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + + IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); + IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(&hdr->shwaddr, ethaddr); + ETHADDR16_COPY(ðhdr->src, ethaddr); + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + /* we are not configured? */ + } else if (ip_addr_isany(&netif->ip_addr)) { + /* { for_us == 0 and netif->ip_addr.addr == 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); + /* request was not directed to us */ + } else { + #ifdef CONFIG_DONT_CARE_TP + if(netif->flags & NETIF_FLAG_IPSWITCH) + netif->linkoutput(netif, p); + else +#endif + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + case PP_HTONS(ARP_REPLY): + /* ARP reply. We already updated the ARP cache earlier. */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); +#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) + /* DHCP wants to know about ARP replies from any host with an + * IP address also offered to us by the DHCP server. We do not + * want to take a duplicate IP address on a single network. + * @todo How should we handle redundant (fail-over) interfaces? */ + dhcp_arp_reply(netif, &sipaddr); +#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ +#ifdef CONFIG_DONT_CARE_TP + if(netif->flags & NETIF_FLAG_IPSWITCH) + netif->linkoutput(netif, p); +#endif + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + break; + } + /* free ARP packet */ + pbuf_free(p); +} + +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + &arp_table[arp_idx].ethaddr); +} + +/** + * Resolve and fill-in Ethernet address header for outgoing IP packet. + * + * For IP multicast and broadcast, corresponding Ethernet addresses + * are selected and the packet is transmitted on the link. + * + * For unicast addresses, the packet is submitted to etharp_query(). In + * case the IP address is outside the local network, the IP address of + * the gateway is used. + * + * @param netif The lwIP network interface which the IP packet will be sent on. + * @param q The pbuf(s) containing the IP packet to be sent. + * @param ipaddr The IP address of the packet destination. + * + * @return + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + mcastaddr.addr[4] = ip4_addr3(ipaddr); + mcastaddr.addr[5] = ip4_addr4(ipaddr); + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + /* unicast destination IP address? */ + } else { + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + !ip_addr_islinklocal(ipaddr)) { +#if LWIP_AUTOIP + struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload + + sizeof(struct eth_hdr)); + /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with + a link-local source address must always be "directly to its destination + on the same physical link. The host MUST NOT send the packet to any + router for forwarding". */ + if (!ip_addr_islinklocal(&iphdr->src)) +#endif /* LWIP_AUTOIP */ + { + /* interface has default gateway? */ + if (!ip_addr_isany(&netif->gw)) { + /* send to hardware address of default gateway IP address */ + dst_addr = &(netif->gw); + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + } + } + } +#if LWIP_NETIF_HWADDRHINT + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t etharp_cached_entry = *(netif->addr_hint); + if (etharp_cached_entry < ARP_TABLE_SIZE) { +#endif /* LWIP_NETIF_HWADDRHINT */ + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { + /* the per-pcb-cached entry is stable and the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); + } +#if LWIP_NETIF_HWADDRHINT + } + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + return etharp_output_to_arp_index(netif, q, i); + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); +} + +/** + * Send an ARP request for the given IP address and/or queue a packet. + * + * If the IP address was not yet in the cache, a pending ARP cache entry + * is added and an ARP request is sent for the given address. The packet + * is queued on this entry. + * + * If the IP address was already pending in the cache, a new ARP request + * is sent for the given address. The packet is queued on this entry. + * + * If the IP address was already stable in the cache, and a packet is + * given, it is directly sent and no ARP request is sent out. + * + * If the IP address was already stable in the cache, and no packet is + * given, an ARP request is sent out. + * + * @param netif The lwIP network interface on which ipaddr + * must be queried for. + * @param ipaddr The IP address to be resolved. + * @param q If non-NULL, a pbuf that must be delivered to the IP address. + * q is not freed by this function. + * + * @note q must only be ONE packet, not a packet queue! + * + * @return + * - ERR_BUF Could not make room for Ethernet header. + * - ERR_MEM Hardware address unknown, and no more ARP entries available + * to query for address or queue the packet. + * - ERR_MEM Could not queue packet due to memory shortage. + * - ERR_RTE No route to destination (no gateway to external networks). + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) +{ + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + err_t result = ERR_MEM; + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr) || + ip_addr_isany(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + + /* could not find or create entry? */ + if (i < 0) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + } + return (err_t)i; + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + arp_table[i].state = ETHARP_STATE_PENDING; + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state >= ETHARP_STATE_STABLE))); + + /* do we have a pending entry? or an implicit query request? */ + if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) { + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + if (result != ERR_OK) { + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + if (q == NULL) { + return result; + } + } + + /* packet given? */ + LWIP_ASSERT("q != NULL", q != NULL); + /* stable entry? */ + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + /* we have a valid IP->Ethernet address mapping */ + ETHARP_SET_HINT(netif, i); + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* entry is still pending, queue the given packet 'q' */ + struct pbuf *p; + int copy_needed = 0; + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + while (p) { + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + copy_needed = 1; + break; + } + p = p->next; + } + if(copy_needed) { + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(p != NULL) { + if (pbuf_copy(p, q) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + pbuf_ref(p); + } + /* packet could be taken over? */ + if (p != NULL) { + /* queue packet ... */ +#if ARP_QUEUEING + struct etharp_q_entry *new_entry; + /* allocate a new arp queue entry */ + new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); + if (new_entry != NULL) { + new_entry->next = 0; + new_entry->p = p; + if(arp_table[i].q != NULL) { + /* queue was already existent, append the new entry to the end */ + struct etharp_q_entry *r; + r = arp_table[i].q; + while (r->next != NULL) { + r = r->next; + } + r->next = new_entry; + } else { + /* queue did not exist, first item in queue */ + arp_table[i].q = new_entry; + } + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + result = ERR_OK; + } else { + /* the pool MEMP_ARP_QUEUE is empty */ + pbuf_free(p); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } +#else /* ARP_QUEUEING */ + /* always queue one packet per ARP request only, freeing a previously queued packet */ + if (arp_table[i].q != NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + pbuf_free(arp_table[i].q); + } + arp_table[i].q = p; + result = ERR_OK; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); +#endif /* ARP_QUEUEING */ + } else { + ETHARP_STATS_INC(etharp.memerr); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } + } + return result; +} + +/** + * Send a raw ARP packet (opcode and all addresses can be modified) + * + * @param netif the lwip network interface on which to send the ARP packet + * @param ethsrc_addr the source MAC address for the ethernet header + * @param ethdst_addr the destination MAC address for the ethernet header + * @param hwsrc_addr the source MAC address for the ARP protocol header + * @param ipsrc_addr the source IP address for the ARP protocol header + * @param hwdst_addr the destination MAC address for the ARP protocol header + * @param ipdst_addr the destination IP address for the ARP protocol header + * @param opcode the type of the ARP packet + * @return ERR_OK if the ARP packet has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +#if !LWIP_AUTOIP +static +#endif /* LWIP_AUTOIP */ +err_t +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode) +{ + struct pbuf *p; + err_t result = ERR_OK; + struct eth_hdr *ethhdr; + struct etharp_hdr *hdr; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ASSERT("netif != NULL", netif != NULL); + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET, PBUF_RAM); + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET)); + + ethhdr = (struct eth_hdr *)p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write the ARP MAC-Addresses */ + ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); + ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, ethdst_addr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->src, ethsrc_addr); + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing. */ + IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); + IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); + + hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); + hdr->proto = PP_HTONS(ETHTYPE_IP); + /* set hwlen and protolen */ + hdr->hwlen = ETHARP_HWADDR_LEN; + hdr->protolen = sizeof(ip_addr_t); + + ethhdr->type = PP_HTONS(ETHTYPE_ARP); + /* send ARP query */ + result = netif->linkoutput(netif, p); + ETHARP_STATS_INC(etharp.xmit); + /* free ARP query packet */ + pbuf_free(p); + p = NULL; + /* could not allocate pbuf for ARP request */ + + return result; +} + +/** + * Send an ARP request packet asking for ipaddr. + * + * @param netif the lwip network interface on which to send the request + * @param ipaddr the IP address for which to ask + * @return ERR_OK if the request has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, ip_addr_t *ipaddr) +{ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + ipaddr, ARP_REQUEST); +} +#endif /* LWIP_ARP */ + +/** + * Process received ethernet frames. Using this function instead of directly + * calling ip_input and passing ARP frames through etharp in ethernetif_input, + * the ARP cache is protected from concurrent access. + * + * @param p the recevied packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + struct eth_hdr* ethhdr; + u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ + + if (p->len <= SIZEOF_ETH_HDR) { + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = (struct eth_hdr *)p->payload; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, + ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", + (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = ethhdr->type; +#if ETHARP_SUPPORT_VLAN + if (type == PP_HTONS(ETHTYPE_VLAN)) { + struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); + if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { + /* a packet with only an ethernet/vlan header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } +#if defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ +#ifdef ETHARP_VLAN_CHECK_FN + if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { +#elif defined(ETHARP_VLAN_CHECK) + if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { +#endif + /* silently ignore this packet: not for our VLAN */ + pbuf_free(p); + return ERR_OK; + } +#endif /* defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ + type = vlan->tpid; + ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; + } +#endif /* ETHARP_SUPPORT_VLAN */ + +#if LWIP_ARP_FILTER_NETIF + netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); +#endif /* LWIP_ARP_FILTER_NETIF*/ + + if (ethhdr->dest.addr[0] & 1) { + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + } + } + + switch (type) { +#if LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, -ip_hdr_offset)) { + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IP layer */ + ip_input(p, netif); + } + break; + + case PP_HTONS(ETHTYPE_ARP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + break; +#endif /* LWIP_ARP */ +#if PPPOE_SUPPORT + case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ + pppoe_disc_input(netif, p); + break; + + case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + + default: + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; + +free_and_return: + pbuf_free(p); + return ERR_OK; +} +#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/CHANGELOG b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/CHANGELOG new file mode 100644 index 0000000..1d757d3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/CHANGELOG @@ -0,0 +1,3733 @@ +HISTORY + +(git master) + + * [Enter new changes just after this line - do not remove this line] + + ++ New features: + + 2015-01-02: Simon Goldschmidt + * tcp.c: tcp_kill_prio(): prefer nearly-closed connections (waiting for the + last ACK only) over established connections when out of tcp pcbs + + 2015-01-17: Simon Goldschmidt + * api: allow enabling socket API without (public) netconn API - netconn API is + still used by sockets, but keeping it private (static) should allow better + compiler optimizations + + 2015-01-16: Simon Goldschmidt + * tcp_in.c: fixed bug #20506 "Initial congestion window is very small" again + by implementing the calculation formula from RFC3390 + + 2014-12-10: Simon Goldschmidt + * api: added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread + instead of using one per netconn and per select call + + 2014-12-08: Simon Goldschmidt + * ip6.h: fixed bug #43778: IPv6 header version not set on 16-bit platform + (macro IP6H_VTCFL_SET()) + + 2014-12-08: Simon Goldschmidt + * icmp.c, ip4.c, pbuf.c, udp.c, pbuf.h: task #11472 Support PBUF_REF for RX + (IPv6 and IPv4/v6 reassembly might not work yet) + + 2014-11-06: Simon Goldschmidt + * sockets.c/.h, init.c: lwip_socket_init() is not needed any more + -> compatibility define + + 2014-09-16: Simon Goldschmidt + * dns.c, opt.h: reduced ram usage by parsing DNS responses in place + + 2014-09-16: Simon Goldschmidt + * pbuf.h/.c: added pbuf_take_at() and pbuf_put_at() + + 2014-09-15: Simon Goldschmidt + * dns.c: added source port randomization to make the DNS client more robust + (see bug #43144) + + 2013-09-02: Simon Goldschmidt + * arch.h and many other files: added optional macros PACK_STRUCT_FLD_8() and + PACK_STRUCT_FLD_S() to prevent gcc 4 from warning about struct members that + do not need packing + + 2013-08-19: Simon Goldschmidt + * netif.h: bug #42998: made NETIF_MAX_HWADDR_LEN overridable for some special + networks + + 2013-03-17: Simon Goldschmidt (patch by Ghobad Emadi) + * opt.h, etharp.c: Added LWIP_HOOK_ETHARP_GET_GW to implement IPv4 routing with + multiple gateways + + 2013-04-20: Fatih Asici + * opt.h, etharp.h/.c: patch #7993: Added support for transmitting packets + with VLAN headers via hook function LWIP_HOOK_VLAN_SET and to check them + via hook function LWIP_HOOK_VLAN_CHECK + + 2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko) + * patch #7885: modification of api modules to support FreeRTOS-MPU + (don't pass stack-pointers to other threads) + + 2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab") + * patch #6537/#7858: TCP window scaling support + + 2014-01-17: Jiri Engelthaler + * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and + IPv6 ICMP's + + 2012-08-22: Sylvain Rochet + * New PPP stack for lwIP, developed in ppp-new branch. + Based from pppd 2.4.5, released 2009-11-17, with huge changes to match + code size and memory requirements for embedded devices, including: + - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which + is more or less what pppd sys-* files are, so that we get something working + using the unix port. + - Merged some patchs from lwIP Git repository which add interesting features + or fix bugs. + - Merged some patchs from Debian pppd package which add interesting features + or fix bugs. + - Ported PPP timeout handling to the lwIP timers system + - Disabled all the PPP code using filesystem access, replaced in necessary cases + to configuration variables. + - Disabled all the PPP code forking processes. + - Removed IPX support, lwIP does not support IPX. + - Ported and improved random module from the previous PPP port. + - Removed samba TDB (file-driven database) usage, because it needs a filesystem. + - MS-CHAP required a DES implementation, we added the latest PolarSSL DES + implementation which is under a BSD-ish license. + - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be + used in embedded devices with reduced memory footprint. + - Removed PPP configuration file parsing support. + - Added macro definition EAP_SUPPORT to make EAP support optional. + - Added macro definition CHAP_SUPPORT to make CHAP support optional. + - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional. + - Added macro definition PAP_SUPPORT to make PAP support optional. + - Cleared all Linux syscall calls. + - Disabled demand support using a macro, so that it can be ported later. + - Disabled ECP support using a macro, so that it can be ported later. + - Disabled CCP support using a macro, so that it can be ported later. + - Disabled CBCP support using a macro, so that it can be ported later. + - Disabled LQR support using a macro, so that it can be ported later. + - Print packet debug feature optional, through PRINTPKT_SUPPORT + - Removed POSIX signal usage. + - Fully ported PPPoS code from the previous port. + - Fully ported PPPoE code from the previous port. + - Fully ported VJ compression protocol code from the previous port. + - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF. + - Disabled PPP server support using a macro, so that it can be ported later. + - Switched all PPP debug to lwIP debug system. + - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere, + removed all global variables everywhere, did everything necessary for + the PPP stack to support more than one PPP session (pppd only support + one session per process). + - Removed the statically allocated output buffer, now using PBUF. + - Improved structure size of all PPP modules, deep analyze of code to reduce + variables size to the bare minimum. Switched all boolean type (char type in + most architecture) to compiler generated bitfields. + - Added PPP IPv6 support, glued lwIP IPv6 support to PPP. + - Now using a persistent netif interface which can then be used in lwIP + functions requiring a netif. + - Now initializing PPP in lwip_init() function. + - Reworked completely the PPP state machine, so that we don't end up in + anymore in inconsistent state, especially with PPPoE. + - Improved the way we handle PPP reconnection after disconnect, cleaning + everything required so that we start the PPP connection again from a + clean state. + - Added PPP holdoff support, allow the lwIP user to wait a little bit before + reconnecting, prevents connection flood, especially when using PPPoL2TP. + - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client + feature to lwIP, L2TP being a widely used tunnel protocol. + - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...) + - Added PPP API "sequential" thread-safe API, based from NETIFAPI. + + 2011-07-21: Simon Goldschmidt + * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes + ioctl/FIONREAD return the size of the next pending datagram. + + 2011-05-25: Simon Goldschmidt + * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, + combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 + and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP + code so that the code is more readable. + + 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) + * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to + Ivan! (this is work in progress: we're just post release anyway :-) + + + ++ Bugfixes: + + 2014-01-27: Simon Goldschmidt + * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR, + fixed return value of lwip_netconn_do_close on unconnected netconns + + 2015-01-17: Simon Goldschmidt + * sockets.c: fixed bug #43361 select() crashes with stale FDs + + 2015-01-17: Simon Goldschmidt + * sockets.c/.h, memp_std.h: fixed bug #40788 "lwip_setsockopt_internal() crashes" + by rewriting set/getsockopt functions to combine checks with the actual code + and add more NULL checks; this also fixes that CORE_LOCKING used message + passing for set/getsockopt. + + 2014-12-19: Simon Goldschmidt + * opt.h, dhcp.h/.c: prevent dhcp from starting when netif link is down (only + when LWIP_DHCP_CHECK_LINK_UP==1, which is disabled by default for + compatibility reasons) + + 2014-12-17: Simon Goldschmidt + * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for + no-copy data with odd length + + 2014-12-10: Simon Goldschmidt + * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO + take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can + be used to revert to the old 'winsock' style behaviour) + Fixed implementation of SO_ACCEPTCONN to just look at the pcb state + + 2014-12-09: Simon Goldschmidt + * ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded + + 2014-10-21: Simon Goldschmidt (patch by Joel Cunningham and Albert Huitsing) + * sockts.c: fixed bugs #41495 Possible threading issue in select() and #43278 + event_callback() handle context switch when calling sys_sem_signal() + + 2014-10-21: Simon Goldschmidt + * api_msg.c: fixed bug #38219 Assert on TCP netconn_write with sndtimeout set + + 2014-09-16: Kevin Cernekee + * dns.c: patch #8480 Fix handling of dns_seqno wraparound + + 2014-09-16: Simon Goldschmidt + * tcp_out.c: fixed bug #43192 tcp_enqueue_flags() should not check TCP_SND_QUEUELEN + when sending FIN + + 2014-09-03: Simon Goldschmidt + * msg_in.c: fixed bug #39355 SNMP Memory Leak in case of error + + 2014-09-02: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before + listen() will cause a error + + 2014-09-02: Simon Goldschmidt + * sockets.c: fixed bug #42117 lwip_fcntl does not set errno + + 2014-09-02: Simon Goldschmidt + * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list + + 2014-08-20: Simon Goldschmidt + * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to + non-randomized TXIDs + + 2014-06-03: Simon Goldschmidt + * tcp_impl.h, tcp_in.c: fixed bug #37969 SYN packet dropped as short packet in + tcp_input function + + 2014-05-20: Simon Goldschmidt + * tcp_out.c: fixed bug #37184 tcp_write problem for pcbs in the SYN_SENT state + + 2014-05-19: Simon Goldschmidt + * *.h: Fixed bug #35874 reserved identifier violation (removed leading underscores + from header include guards) + + 2014-04-08: Simon Goldschmidt + * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window) + + 2014-04-06: Simon Goldschmidt + * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received + unacceptable ACK + + 2014-04-06: Simon Goldschmidt + * dhcp.c, ip4.c/.h, ip6.c/.h, udp.c/.h, ip.h: Fixed bug #41787 DHCP Discovery + is invalid when an IP is set to thet netif. + + 2014-03-14: Simon Goldschmidt + * tcp_out.c: Fixed bug #36153 TCP Cheksum error if LWIP_CHECKSUM_ON_COPY=1 + + 2014-03-11: Simon Goldschmidt (patch by Mason) + * opt.h, sockets.c: fixed bug #35928 BSD sockets functions must set errno for + POSIX-compliance + + 2014-02-27: Simon Goldschmidt + * dhcp.c: fixed bug #40303 DHCP xid renewed when sending a DHCPREQUEST + + 2014-02-27: Simon Goldschmidt + * raw.c: fixed bug #41680 raw socket can not receive IPv6 packet when + IP_SOF_BROADCAST_RECV==1 + + 2014-02-27: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #38404 getpeeraddr returns success on + unconnected/listening TCP sockets + + 2014-02-27: Simon Goldschmidt + * sockets.c: fixed bug #41729 Some socket functions return Exyz instead of -1 + + 2014-02-25: Simon Goldschmidt + * ip4.c: fixed bug #39514 ip_route() may return an IPv6-only interface + + 2014-02-25: Simon Goldschmidt, patch by Fatih Asici + * pbuf.c: fixed bug #39356 Wrong increment in pbuf_memfind() + + 2014-02-25: Simon Goldschmidt + * netif.c/.h, udp.c: fixed bug #39225 udp.c uses netif_matches_ip6_addr() incorrectly; + renamed function netif_matches_ip6_addr() to netif_get_ip6_addr_match() + + 2014-02-25: Simon Goldschmidt + * igmp.c: fixed bug #39145 IGMP membership report for 224.0.0.1 + + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) + * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) + + 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) + * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry + + 2014-02-20: Simon Goldschmidt + * tcp_out.c: fixed bug #39683 Assertion "seg->tcphdr not aligned" failed with + MEM_ALIGNMENT = 8 + + 2014-02-20: Simon Goldschmidt + * sockets.c: fixed bug #39882 No function shall set errno to 0 + + 2014-02-20: Simon Goldschmidt + * mib_structs.c: fixed bug #40050 SNMP problem with MIB arrays > 255 + + 2014-02-20: Simon Goldschmidt + * api.h, sockets.c: fixed bug #41499 netconn::recv_avail can overflow + + 2014-01-08: Stathis Voukelatos + * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool + creation macro + + 2014-01-18: Brian Fahs + * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize + when necessary + + 2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt + * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback + + 2014-01-16: Stathis Voukelatos + * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0 + + 2014-01-14: "Freddie Chopin" + * snmp.h, mib2.c: fixed constness and spelling of sysdescr + + 2014-01-14: Simon Goldschmidt (patch by Thomas Faber) + * tcpip.c: patch #8241: Fix implicit declaration of ip_input with + LWIP_TCPIP_CORE_LOCKING_INPUT disabled + + 2014-01-14: chrysn + * timers.c: patch #8244 make timeouts usable reliably from outside of the + timeout routine + + 2014-01-10: Simon Goldschmidt + * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly + + 2014-01-10: Simon Goldschmidt + * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1 + + 2014-01-10: Simon Goldschmidt + * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop + + 2013-06-29: Simon Goldschmidt + * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs) + + 2013-06-29: Simon Goldschmidt + * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec + + 2013-04-24: patch by Liam + * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert + + 2013-04-24: Simon Goldschmidt + * igmp.c: fixed possible division by zero + + 2013-04-24: Simon Goldschmidt + * ip6.h, some ipv6 C files: fixed bug #38526 Coverity: Recursive Header Inclusion in ip6.h + + 2013-04-24: Simon Goldschmidt (patch by Emil Ljungdahl): + * netif.c: fixed bug #38586 netif_loop_output() "deadlocks" + + 2013-01-15: Simon Goldschmidt + * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order + + 2013-01-15: Simon Goldschmidt + * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning + + 2013-01-14: Simon Goldschmidt + * dns.c: fixed bug #37705 Possible memory corruption in DNS query + + 2013-01-11: Simon Goldschmidt + * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-08-13: Simon Goldschmidt + * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start + dereferences NULL + + 2012-08-13: Simon Goldschmidt + * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps + configured but no interfaces available + + 2012-08-13: Simon Goldschmidt + * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time + + 2012-05-11: Simon Goldschmidt (patch by Marty) + * memp.c: fixed bug #36412: memp.c does not compile when + MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 + + 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) + * ppp.c: fixed bug #36283 (PPP struct used on header size computation and + not packed) + + 2012-05-03: Simon Goldschmidt (patch by David Empson) + * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with + zero length) + + 2012-03-25: Simon Goldschmidt + * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed + for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 + + 2012-03-25: Simon Goldschmidt + * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space + pollution in api_msg.c and netifapi.c + + 2011-08-24: Simon Goldschmidt + * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard + + + +(STABLE-1.4.1) + + ++ New features: + + 2012-03-25: Simon Goldschmidt (idea by Mason) + * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h + which are a simple wrapper to the correct lwIP include files. + + 2012-01-16: Simon Goldschmidt + * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP + + 2011-12-17: Simon Goldschmidt + * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) + (fixes bug #35061) + + 2011-09-27: Simon Goldschmidt + * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) + (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) + + 2011-09-21: Simon Goldschmidt + * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on + send (TCP only, bug #33820) + + 2011-09-21: Simon Goldschmidt + * init.c: Converted runtime-sanity-checks into compile-time checks that can + be disabled (since runtime checks can often not be seen on embedded targets) + + 2011-09-11: Simon Goldschmidt + * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file + to get a clear separation of which functions an application or port may use + (task #11281) + + 2011-09-11: Simon Goldschmidt + * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize + initial local TCP/UDP ports (so that different port ranges are used after + a reboot; bug #33818; this one added tcp_init/udp_init functions again) + + 2011-09-03: Simon Goldschmidt + * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) + + 2011-08-24: Simon Goldschmidt + * opt.h, netif.h/.c: added netif remove callback (bug #32397) + + 2011-07-26: Simon Goldschmidt + * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter + function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) + + 2011-07-21: Simon Goldschmidt (patch by hanhui) + * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: + Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. + Also added code to allow ip_forward() to forward non-broadcast packets to + the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). + + 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) + * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that + pcb->state != LISTEN + + 2011-05-14: Simon Goldschmidt (patch by Stphane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + + + ++ Bugfixes: + + 2012-09-26: Simon Goldschmidt + * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7843 Fix corner case with dhcp timeouts + + 2012-09-26: patch by Henrik Persson + * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet + + 2012-08-22: Simon Goldschmidt + * memp.c: fixed bug #37166: memp_sanity check loops itself + + 2012-05-08: Simon Goldschmidt + * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was + a debug-check issue only) + + 2012-03-27: Simon Goldschmidt + * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c + + 2012-03-27: Simon Goldschmidt (patch by Mason) + * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the + send MSS + + 2012-03-22: Simon Goldschmidt + * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward + + 2012-03-20: Simon Goldschmidt (patch by Mason) + * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list + + 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) + * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, + possible bug on little endian system + + 2012-02-23: Simon Goldschmidt + * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt + * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() + (bug #35541: PPP Memory Leak) + + 2012-02-16: Simon Goldschmidt + * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway + (introduced when fixing bug# 33551) + + 2012-02-16: Simon Goldschmidt (patch by Stphane Lesage) + * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed + + 2012-02-15: Simon Goldschmidt + * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with + MEMP_MEM_MALLOC==1 + + 2012-02-12: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on + MSS > pcb->snd_wnd (by not creating segments bigger than half the window) + + 2012-02-11: Simon Goldschmidt + * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait + queue while closing + + 2012-01-22: Simon Goldschmidt + * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) + + 2012-01-21: Simon Goldschmidt + * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb + + 2012-01-20: Simon Goldschmidt + * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths + + 2012-01-20: Simon Goldschmidt + * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy + + 2011-11-25: Simon Goldschmidt + * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt + tcp_active_pcbs in some cases + + 2011-11-23: Simon Goldschmidt + * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with + '#ifndef sys_msleep' + + 2011-11-22: Simon Goldschmidt + * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when + netif is brought down + + 2011-10-28: Simon Goldschmidt + * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks + + 2011-10-23: Simon Goldschmidt + * mem.c: fixed bug #34429: possible memory corruption with + LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 + + 2011-10-18: Simon Goldschmidt + * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard + error value + + 2011-10-18: Simon Goldschmidt + * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small + windows (bug #34176 select after non-blocking send times out) + + 2011-10-18: Simon Goldschmidt + * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't + consider netif->mtu, causes slow network + + 2011-10-18: Simon Goldschmidt + * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code + + 2011-10-18: Simon Goldschmidt + * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS + + 2011-10-17: Simon Goldschmidt + * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api + + 2011-10-13: Simon Goldschmidt + * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no + zero window is received) by starting the persist timer when a zero window is + received, not when we have more data queued for sending than fits into the + window + + 2011-10-13: Simon Goldschmidt + * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex + + 2011-10-13: Simon Goldschmidt + * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is + used and not all protocols are enabled + + 2011-10-12: Simon Goldschmidt + * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 + + 2011-10-09: Simon Goldschmidt + * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect + byte value when pcb->unacked != NULL + + 2011-10-09: Simon Goldschmidt + * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong + + 2011-09-27: Simon Goldschmidt + * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... + + 2011-09-27: Simon Goldschmidt + * tcp_in.c: fixed bug #28288: Data after FIN in oos queue + + 2011-09-27: Simon Goldschmidt + * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf + + 2011-09-24: Simon Goldschmidt + * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 + + 2011-09-23: Simon Goldschmidt + * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for + the last packet including FIN can lose data + + 2011-09-22: Simon Goldschmidt + * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into + account + + 2011-09-21: Simon Goldschmidt + * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks + in init.c + + 2011-09-20: Simon Goldschmidt + * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) + + 2011-09-11: Simon Goldschmidt + * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs + (bug #34019) + + 2011-09-09: Simon Goldschmidt + * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if + udp port matches + + 2011-09-03: Simon Goldschmidt + * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet + is aggregated and sent to application + + 2011-09-01: Simon Goldschmidt + * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared + to other options + + 2011-09-01: Simon Goldschmidt + * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno + + 2011-08-24: Simon Goldschmidt + * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling + accept() on UDP connections + + 2011-08-24: Simon Goldschmidt + * sockets.h: fixed bug #34057 socklen_t should be a typedef + + 2011-08-24: Simon Goldschmidt + * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) + + 2011-08-24: Simon Goldschmidt + * dhcp.c: fixed bug #34122 dhcp: hostname can overflow + + 2011-08-24: Simon Goldschmidt + * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr + + 2011-08-22: Simon Goldschmidt + * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This + merely prevents nagle from not transmitting fast after closing.) + + 2011-07-22: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns + always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now + lwip_send() sends as much as possible for non-blocking sockets + + 2011-07-22: Simon Goldschmidt + * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented + for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level. + + 2011-07-21: Simon Goldschmidt + * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by + sending an ARP request when an ARP entry is used in the last minute before + it would time out. + + 2011-07-04: Simon Goldschmidt + * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. + + 2011-06-26: Simon Goldschmidt + * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by + updating its documentation only. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an + unaligned pointer. + + 2011-06-26: Simon Goldschmidt + * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" + + 2011-05-25: Simon Goldschmidt + * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) + + + +(STABLE-1.4.0) + + ++ New features: + + 2011-03-27: Simon Goldschmidt + * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and + calculate it in tcp_zero_window_probe (the only place where it was used). + + 2010-11-21: Simon Goldschmidt + * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif + (fixes bug #31525). + + 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) + * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for + IP_MULTICAST_LOOP at socket- and raw-API level. + + 2010-06-16: Simon Goldschmidt + * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow + link-layer-addressed UDP traffic to be received while a netif is down (just + like DHCP during configuration) + + 2010-05-22: Simon Goldschmidt + * many many files: bug #27352: removed packing from ip_addr_t, the packed + version is now only used in protocol headers. Added global storage for + current src/dest IP address while in input functions. + + 2010-05-16: Simon Goldschmidt + * def.h: task #10391: Add preprocessor-macros for compile-time htonl + calculation (and use them throughout the stack where applicable) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool + instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) + + 2010-05-16: Simon Goldschmidt + * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own + MEMP pool instead of the heap + + 2010-05-13: Simon Goldschmidt + * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added + new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast + packets to more than one pcb. + + 2010-05-02: Simon Goldschmidt + * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending + UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-04-30: Simon Goldschmidt + * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that + take a precalculated checksum, added pbuf_fill_chksum() to copy data + into a pbuf and at the same time calculating the checksum for that data + + 2010-04-29: Simon Goldschmidt + * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying + 2-byte-aligned IP addresses and MAC addresses + + 2010-04-28: Patch by Bill Auerbach + * ip.c: Inline generating IP checksum to save a function call + + 2010-04-14: Simon Goldschmidt + * tcpip.h/.c, timers.c: Added an overridable define to get informed when the + tcpip_thread processes messages or timeouts to implement a watchdog. + + 2010-03-28: Simon Goldschmidt + * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing + fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 + + 2010-03-27: Simon Goldschmidt + * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ + etharp_query to prevent unnecessary function calls (inspired by + patch #7135). + + 2010-03-20: Simon Goldschmidt + * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code + since the linker cannot do this automatically to save space. + + 2010-03-20: Simon Goldschmidt + * opt.h, etharp.c/.h: Added support for static ARP table entries + + 2010-03-14: Simon Goldschmidt + * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum + when creating TCP segments, not when (re-)transmitting them. + + 2010-03-07: Simon Goldschmidt + * sockets.c: bug #28775 (select/event_callback: only check select_cb_list + on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. + This should speed up receiving data on sockets as the select code in + event_callback is only executed when select is waiting. + + 2010-03-06: Simon Goldschmidt + * tcp_out.c: task #7013 (Create option to have all packets delivered to + netif->output in one piece): Always copy to try to create single pbufs + in tcp_write. + + 2010-03-06: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv + by not allocating a netbuf): added function netconn_recv_tcp_pbuf() + for tcp netconns to receive pbufs, not netbufs; use that function + for tcp sockets. + + 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt + * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: + Work on tcp_enqueue: Don't waste memory when chaining segments, + added option TCP_OVERSIZE to prevent creating many small pbufs when + calling tcp_write with many small blocks of data. Instead, pbufs are + allocated larger than needed and the space is used for later calls to + tcp_write. + + 2010-02-21: Simon Goldschmidt + * stats.c/.h: Added const char* name to mem- and memp-stats for easier + debugging. + + 2010-02-21: Simon Goldschmidt + * tcp.h (and usages), added tcp_impl.h: Splitted API and internal + implementation of tcp to make API usage cleare to application programmers + + 2010-02-14: Simon Goldschmidt/Stephane Lesage + * ip_addr.h: Improved some defines working on ip addresses, added faster + macro to copy addresses that cannot be NULL + + 2010-02-13: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- + blocking send operation) + + 2010-02-12: Simon Goldschmidt + * sockets.c/.h: Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + 2010-02-12: Simon Goldschmidt + * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated + memory): added autoip_set_struct() and dhcp_set_struct() to let autoip + and dhcp work with user-allocated structs instead of callin mem_malloc + + 2010-02-12: Simon Goldschmidt/Jeff Barber + * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has + SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT + + 2010-02-12: Simon Goldschmidt + * sys layer: task #10139 (Prefer statically allocated memory): converted + mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; + converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX + to let sys.h use binary semaphores instead of mutexes - as before) + + 2010-02-09: Simon Goldschmidt (Simon Kallweit) + * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 + (Restart system timeout handling) + + 2010-02-09: Simon Goldschmidt + * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into + netif.c) - loopif does not have to be created by the port any more, + just define LWIP_HAVE_LOOPIF to 1. + + 2010-02-08: Simon Goldschmidt + * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa + inet_ntoa_r/ipaddr_ntoa_r + + 2010-02-08: Simon Goldschmidt + * netif.h: Added netif_s/get_igmp_mac_filter() macros + + 2010-02-05: Simon Goldschmidt + * netif.h: Added function-like macros to get/set the hostname on a netif + + 2010-02-04: Simon Goldschmidt + * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to + make changing the actual implementation behind the typedef easier. + + 2010-02-01: Simon Goldschmidt + * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool + for allocating memory when getaddrinfo() is called. + + 2010-01-31: Simon Goldschmidt + * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse + them once instead of parsing for every option. This also removes + the need for mem_malloc from dhcp_recv and makes it possible to + correctly retrieve the BOOTP file. + + 2010-01-30: simon Goldschmidt + * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect + the sockets array. + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, api_msg.c, sockets.c: Added except set support in select + (patch #6860) + + 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) + * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: + Add non-blocking support for connect (partly from patch #6860), + plus many cleanups in socket & netconn API. + + 2010-01-27: Simon Goldschmidt + * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding + to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 + + 2010-01-26: Simon Goldschmidt + * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. + + 2010-01-14: Simon Goldschmidt + * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback + by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() + + 2010-01-13: Simon Goldschmidt + * mem.c: The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + (patch #6966 and bug #26133) + + 2010-01-10: Simon Goldschmidt (Bill Auerbach) + * opt.h, memp.c: patch #6822 (Add option to place memory pools in + separate arrays) + + 2010-01-10: Simon Goldschmidt + * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define + LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) + + 2009-12-31: Simon Goldschmidt + * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h + added timers.c/.h: Separated timer implementation from semaphore/mbox + implementation, moved timer implementation to timers.c/.h, timers are + now only called from tcpip_thread or by explicitly checking them. + (TASK#7235) + + 2009-12-27: Simon Goldschmidt + * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option + LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) + + + ++ Bugfixes: + + 2011-04-20: Simon Goldschmidt + * sys_arch.txt: sys_arch_timeouts() is not needed any more. + + 2011-04-13: Simon Goldschmidt + * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by + using ports in the IANA private/dynamic range (49152 through 65535). + + 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: + * etharp.h/.c: Fixed broken VLAN support. + + 2011-03-27: Simon Goldschmidt + * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp + pcbs) by checking if the pcb was bound (local_port != 0). + + 2011-03-27: Simon Goldschmidt + * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) + + 2011-03-27: Simon Goldschmidt + * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and + raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. + + 2011-03-27: Simon Goldschmidt + * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route + is present never times out) by starting retransmission timer before checking + route. + + 2011-03-22: Simon Goldschmidt + * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only + calling sio_read_abort() if the file descriptor is valid. + + 2011-03-14: Simon Goldschmidt + * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect + more than once can render a socket useless) since it mainly involves changing + "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. + + 2011-03-13: Simon Goldschmidt + * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing + err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: + use EALRADY instead of -1 + + 2011-03-13: Simon Goldschmidt + * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the + connection has been aborted by err_tcp (since this is not a normal closing + procedure). + + 2011-03-13: Simon Goldschmidt + * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind + with pcb->state != CLOSED + + 2011-02-17: Simon Goldschmidt + * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in + documentation + + 2011-02-17: Simon Goldschmidt + * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. + + 2011-01-24: Simon Goldschmidt + * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems + + 2010-12-02: Simon Goldschmidt + * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. + + 2010-11-23: Simon Goldschmidt + * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for + LWIP_SO_RCVBUF and ioctl/FIONREAD. + + 2010-11-23: Simon Goldschmidt + * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at + least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. + + 2010-11-23: Simon Goldschmidt + * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after + refusing 'refused_data' again. + + 2010-11-22: Simon Goldschmidt + * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS + after a successful nonblocking connection. + + 2010-11-22: Simon Goldschmidt + * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr + must be sent link-local + + 2010-11-22: Simon Goldschmidt + * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for + LWIP_TIMERS==0 + + 2010-11-20: Simon Goldschmidt + * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number + + 2010-11-20: Simon Goldschmidt + * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to + resemble other stacks. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else + no-copy TCP writes will never succeed. + + 2010-11-20: Simon Goldschmidt + * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does + not match documentation: return ERR_ARG instead of ERR_VAL if not + initialized or wrong argument. + + 2010-10-20: Simon Goldschmidt + * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 + + 2010-10-05: Simon Goldschmidt + * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when + replugging the network cable after an AutoIP address was assigned. + + 2010-08-10: Simon Goldschmidt + * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs + + 2010-08-03: Simon Goldschmidt + * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) + + 2010-08-01: Simon Goldschmidt (patch by Greg Renda) + * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big + endian architectures) + + 2010-07-28: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP + disabled. + + 2010-07-27: Simon Goldschmidt + * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no + harm but never did anything + + 2010-07-21: Simon Goldschmidt + * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not + add IP options) + + 2010-07-16: Kieran Mansley + * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator + + 2010-07-10: Simon Goldschmidt + * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options + + 2010-06-30: Simon Goldschmidt + * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in + netconn_delete) + + 2010-06-28: Kieran Mansley + * timers.c remove unportable printing of C function pointers + + 2010-06-24: Simon Goldschmidt + * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag + NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading + + 2010-06-24: Simon Goldschmidt + * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly + implemented shutdown at socket level. + + 2010-06-21: Simon Goldschmidt + * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has + problems with zero-copy DMA MACs) by adding custom pbufs and implementing + custom pbufs that reference other (original) pbufs. Additionally set + IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. + + 2010-06-15: Simon Goldschmidt + * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses + + 2010-06-14: Simon Goldschmidt + * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses + + 2010-06-12: Simon Goldschmidt + * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop + state + + 2010-05-17: Simon Goldschmidt + * netdb.c: Correctly NULL-terminate h_addr_list + + 2010-05-16: Simon Goldschmidt + * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent + "symbol already defined" i.e. when linking to winsock + + 2010-05-05: Simon Goldschmidt + * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may + overflow) + + 2010-04-21: Simon Goldschmidt + * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening + connection) + + 2010-03-28: Luca Ceresoli + * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers + + 2010-03-27: Luca Ceresoli + * mib2.c: patch #7130: remove meaningless const qualifiers + + 2010-03-26: Simon Goldschmidt + * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too + + 2010-03-26: Simon Goldschmidt + * various files: Fixed compiling with different options disabled (TCP/UDP), + triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled + + 2010-03-25: Simon Goldschmidt + * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly + + 2010-03-25: Simon Goldschmidt + * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side + overrunning our rcv_wnd in ooseq case. + + 2010-03-22: Simon Goldschmidt + * tcp.c: tcp_listen() did not copy the pcb's prio. + + 2010-03-19: Simon Goldschmidt + * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set + + 2010-03-14: Simon Goldschmidt + * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports + where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h + and basing PBUF_LINK_HLEN on it. + + 2010-03-08: Simon Goldschmidt + * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections + when assiging routable address): when checking incoming packets and + aborting existing connection on address change, filter out link-local + addresses. + + 2010-03-06: Simon Goldschmidt + * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING + + 2010-03-06: Simon Goldschmidt + * ipv4/ip.c: Don't try to forward link-local addresses + + 2010-03-06: Simon Goldschmidt + * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- + addresses to gw + + 2010-03-05: Simon Goldschmidt + * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type + and state. + + 2010-03-05: Simon Goldschmidt + * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split + into multiple calls to tcp_write. + + 2010-02-21: Simon Goldschmidt + * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep + the implementation of DNS_USES_STATIC_BUF==1) + + 2010-02-20: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement + close() vs. shutdown(). Now the application does not get any more + recv callbacks after calling tcp_close(). Added tcp_shutdown(). + + 2010-02-19: Simon Goldschmidt + * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent + confusion with realloc() + + 2010-02-15: Simon Goldschmidt/Stephane Lesage + * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK + (fixes bug #28899) + + 2010-02-14: Simon Goldschmidt + * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with + LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and + admin-status of a netif are up + + 2010-02-14: Simon Goldschmidt + * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet + reception and is not really necessary + + 2010-02-14: Simon Goldschmidt + * etharp.c/.h: Fixed ARP input processing: only add a new entry if a + request was directed as us (RFC 826, Packet Reception), otherwise + only update existing entries; internalized some functions + + 2010-02-14: Simon Goldschmidt + * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be + disabled on netif used for PPPoE) by adding a new netif flag + (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet + device but prevents usage of ARP (so that ethernet_input can be used + for PPPoE). + + 2010-02-12: Simon Goldschmidt + * netif.c: netif_set_link_up/down: only do something if the link state + actually changes + + 2010-02-12: Simon Goldschmidt/Stephane Lesage + * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking + connect) + + 2010-02-12: Simon Goldschmidt + * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) + + 2010-02-09: Simon Goldschmidt + * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 + (recv() makes receive window update for data that wasn't received by + application) + + 2010-02-09: Simon Goldschmidt/Stephane Lesage + * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out + or any netconn_recv() error) + + 2010-02-09: Simon Goldschmidt + * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) + + 2010-02-09: Simon Goldschmidt + * netif.c: For loopback packets, adjust the stats- and snmp-counters + for the loopback netif. + + 2010-02-08: Simon Goldschmidt + * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity + since they are not used anywhere else. + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats + (patch from bug #28798) + + 2010-02-08: Simon Goldschmidt (Stphane Lesage) + * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and + another bug when LWIP_RAND() returns zero. + + 2010-02-04: Simon Goldschmidt + * nearly every file: Use macros defined in ip_addr.h (some of them new) + to work with IP addresses (preparation for bug #27352 - Change ip_addr + from struct to typedef (u32_t) - and better code). + + 2010-01-31: Simon Goldschmidt + * netif.c: Don't call the link-callback from netif_set_up/down() since + this invalidly retriggers DHCP. + + 2010-01-29: Simon Goldschmidt + * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the + portability file inet.h and its contents from the stack: moved htonX- + functions to def.h (and the new def.c - they are not ipv4 dependent), + let inet.h depend on ip_addr.h and not the other way round. + This fixes bug #28732. + + 2010-01-28: Kieran Mansley + * tcp.c: Ensure ssthresh >= 2*MSS + + 2010-01-27: Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv + callback can lead to accessing unallocated memory. As a consequence, + ERR_ABRT means the application has called tcp_abort()! + + 2010-01-25: Simon Goldschmidt + * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY + not implemented in SNMP): write-only or not-accessible are still + returned by getnext (though not by get) + + 2010-01-24: Simon Goldschmidt + * snmp: Renamed the private mib node from 'private' to 'mib_private' to + not use reserved C/C++ keywords + + 2010-01-23: Simon Goldschmidt + * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less + than 1 ms + + 2010-01-21: Simon Goldschmidt + * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called + if tcp_enqueue fails) both in raw- and netconn-API + + 2010-01-19: Simon Goldschmidt + * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp + + 2010-01-18: Iordan Neshev/Simon Goldschmidt + * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some + bugfix backports from 2.4.x. + + 2010-01-18: Simon Goldschmidt + * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong + + 2010-01-17: Simon Goldschmidt + * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): + task #10102: "netconn: clean up conn->err threading issues" by adding + error return value to struct api_msg_msg + + 2010-01-17: Simon Goldschmidt + * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() + to return err_t (bugs #27709 and #28087) + + 2010-01-14: Simon Goldschmidt + * ...: Use typedef for function prototypes throughout the stack. + + 2010-01-13: Simon Goldschmidt + * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive + window = 0) by correctly draining recvmbox/acceptmbox + + 2010-01-11: Simon Goldschmidt + * pap.c: Fixed bug #13315 (PPP PAP authentication can result in + erroneous callbacks) by copying the code from recent pppd + + 2010-01-10: Simon Goldschmidt + * raw.c: Fixed bug #28506 (raw_bind should filter received packets) + + 2010-01-10: Simon Goldschmidt + * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) + + 2010-01-08: Simon Goldschmidt + * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) + + 2010-01-08: Simon Goldschmidt + * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string + passed to dns_local_addhost() might be volatile + + 2010-01-07: Simon Goldschmidt + * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too + + 2010-01-06: Simon Goldschmidt + * netdb.h: Fixed bug #28496: missing include guards in netdb.h + + 2009-12-31: Simon Goldschmidt + * many ppp files: Reorganised PPP source code from ucip structure to pppd + structure to easily compare our code against the pppd code (around v2.3.1) + + 2009-12-27: Simon Goldschmidt + * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted + unit test + + +(STABLE-1.3.2) + + ++ New features: + + 2009-10-27 Simon Goldschmidt/Stephan Lesage + * netifapi.c/.h: Added netifapi_netif_set_addr() + + 2009-10-07 Simon Goldschmidt/Fabian Koch + * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to + support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) + + 2009-08-26 Simon Goldschmidt/Simon Kallweit + * slipif.c/.h: bug #26397: SLIP polling support + + 2009-08-25 Simon Goldschmidt + * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), + New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. + + 2009-08-25 Simon Goldschmidt + * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) + + 2009-08-24 Jakob Stoklund Olesen + * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond + to netif_set_link_up(). + + 2009-08-23 Simon Goldschmidt + * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state + to a human-readable string. + + ++ Bugfixes: + + 2009-12-24: Kieran Mansley + * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing + (BUG#28241) + + 2009-12-06: Simon Goldschmidt + * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can + be statically allocated (like in ucip) + + 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) + * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT + + 2009-12-03: Simon Goldschmidt + * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit + could have non-zero length + + 2009-12-02: Simon Goldschmidt + * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting + tcp_input_pcb until after calling the pcb's callbacks + + 2009-11-29: Simon Goldschmidt + * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- + sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code + + 2009-11-29: Simon Goldschmidt + * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by + queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty + + 2009-11-26: Simon Goldschmidt + * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending + segment + + 2009-11-26: Simon Goldschmidt + * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle + algorithm at PCB level + + 2009-11-22: Simon Goldschmidt + * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent + + 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) + * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when + reusing time-wait pcb + + 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) + * sockets.c: Fixed bug #28062: Data received directly after accepting + does not wake up select + + 2009-11-11: Simon Goldschmidt + * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) + + 2009-10-30: Simon Goldschmidt + * opt.h: Increased default value for TCP_MSS to 536, updated default + value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. + + 2009-10-28: Kieran Mansley + * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code + to follow algorithm from TCP/IP Illustrated + + 2009-10-27: Kieran Mansley + * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK + + 2009-10-25: Simon Goldschmidt + * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if + pcb->recv is NULL to keep rcv_wnd correct) + + 2009-10-25: Simon Goldschmidt + * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state + + 2009-10-23: Simon Goldschmidt (David Empson) + * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes + + 2009-10-21: Simon Goldschmidt + * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and + trailing 1 byte len (SYN/FIN) + + 2009-10-21: Simon Goldschmidt + * tcp_out.c: Fixed bug #27315: zero window probe and FIN + + 2009-10-19: Simon Goldschmidt + * dhcp.c/.h: Minor code simplification (don't store received pbuf, change + conditional code to assert where applicable), check pbuf length before + testing for valid reply + + 2009-10-19: Simon Goldschmidt + * dhcp.c: Removed most calls to udp_connect since they aren't necessary + when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. + + 2009-10-16: Simon Goldschmidt + * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop + valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is + enabled + + 2009-10-15: Simon Goldschmidt (Oleg Tyshev) + * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit + + 2009-10-15: Simon Goldschmidt + * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() + timeout + + 2009-10-15: Simon Goldschmidt + * autoip.c: Fixed bug #27704: autoip starts with wrong address + LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead + of network byte order + + 2009-10-11 Simon Goldschmidt (Jrg Kesten) + * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments + which are not consecutive when retransmitting unacked segments + + 2009-10-09 Simon Goldschmidt + * opt.h: Fixed default values of some stats to only be enabled if used + Fixes bug #27338: sys_stats is defined when NO_SYS = 1 + + 2009-08-30 Simon Goldschmidt + * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK + function" by checking for loopback before calling ip_frag + + 2009-08-25 Simon Goldschmidt + * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27078: Possible memory leak in pppInit() + + 2009-08-23 Simon Goldschmidt + * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result + is error. + + 2009-08-23 Simon Goldschmidt + * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF + Fixed wrong parenthesis, added check in init.c + + 2009-08-23 Simon Goldschmidt + * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms + + 2009-08-23 Simon Goldschmidt + * many ppp files: bug #27267: Added include to string.h where needed + + 2009-08-23 Simon Goldschmidt + * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) + + +(STABLE-1.3.1) + + ++ New features: + + 2009-05-10 Simon Goldschmidt + * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option + LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only + one pbuf to help MACs that don't support scatter-gather DMA. + + 2009-05-09 Simon Goldschmidt + * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming + ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + + 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen + * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive + extended info about the currently received packet. + + 2009-04-27 Simon Goldschmidt + * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 + + 2009-04-25 Simon Goldschmidt + * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next + bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). + + 2009-04-21 Simon Goldschmidt + * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static + hosts table. New configuration options DNS_LOCAL_HOSTLIST and + DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined + as an external function for lookup. + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for + TCP timestamp options, off by default. Rework tcp_enqueue() to + take option flags rather than specified option data + + 2009-02-18 Simon Goldschmidt + * cc.h: Added printf formatter for size_t: SZT_F + + 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) + * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast + pings + + 2009-02-12 Simon Goldschmidt + * init.h: Added LWIP_VERSION to get the current version of the stack + + 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) + * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead + of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc + is otherwise used) + + 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) + * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() + is only used by UDPLITE at present, so conditionalise it. + + 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) + * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP + "seed" address. This should reduce AUTOIP conflicts if + LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. + + 2008-10-02 Jonathan Larmour and Rishi Khan + * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking + socket. + + 2008-06-30 Simon Goldschmidt + * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from + interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows + mem_free to run between mem_malloc iterations. Added illegal counter for + mem stats. + + 2008-06-27 Simon Goldschmidt + * stats.h/.c, some other files: patch #6483: stats module improvement: + Added defines to display each module's statistic individually, added stats + defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. + + 2008-06-17 Simon Goldschmidt + * err.h: patch #6459: Made err_t overridable to use a more efficient type + (define LWIP_ERR_T in cc.h) + + 2008-06-17 Simon Goldschmidt + * slipif.c: patch #6480: Added a configuration option for slipif for symmetry + to loopif + + 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) + * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly + modified version of patch # 6370: Moved loopif code to netif.c so that + loopback traffic is supported on all netifs (all local IPs). + Added option to limit loopback packets for each netifs. + + + ++ Bugfixes: + 2009-08-12 Kieran Mansley + * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when + out of window or out of order properly + + 2009-08-12 Kieran Mansley + * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 + + 2009-07-28 Simon Goldschmidt + * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s + + 2009-07-27 Kieran Mansley + * api.h api_msg.h netdb.h sockets.h: add missing #include directives + + 2009-07-09 Kieran Mansley + * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for + recv_avail and don't increment counters until message successfully + sent to mbox + + 2009-06-25 Kieran Mansley + * api_msg.c api.h: BUG26722: initialise netconn write variables + in netconn_alloc + + 2009-06-25 Kieran Mansley + * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set + + 2009-06-25 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct + simultaneous close behaviour, and make snd_nxt have the same meaning + as in the RFCs. + + 2009-05-12 Simon Goldschmidt + * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on + arp_table / uses etharp_query" by adding etharp_gratuitous() + + 2009-05-12 Simon Goldschmidt + * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options + to the IP header (used by igmp_ip_output_if) + + 2009-05-06 Simon Goldschmidt + * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if + defined) for SWAP_BYTES_IN_WORD to speed up checksumming. + + 2009-05-05 Simon Goldschmidt + * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() + to crash + + 2009-05-04 Simon Goldschmidt + * init.c: snmp was not initialized in lwip_init() + + 2009-05-04 Frdric Bernon + * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. + + 2009-05-03 Simon Goldschmidt + * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full + (and unsent->next == NULL) + + 2009-05-02 Simon Goldschmidt + * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after + 1.3.0 in CVS only) - fixes compilation of ppp_oe.c + + 2009-05-02 Simon Goldschmidt + * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields + + 2009-05-01 Simon Goldschmidt + * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets + + 2009-05-01 Simon Goldschmidt + * ppp.c: bug #24228: Memory corruption with PPP and DHCP + + 2009-04-29 Frdric Bernon + * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the + SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception + of broadcast packets even when this option wasn't set. Port maintainers + which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. + If you want this option also filter broadcast on recv operations, you also + have to set IP_SOF_BROADCAST_RECV=1 in opt.h. + + 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen + * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and + DHCP/AUTOIP cooperation + + 2009-04-25 Simon Goldschmidt, Oleg Tyshev + * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd + Fixed by sorting the unsent and unacked queues (segments are inserted at the + right place in tcp_output and tcp_rexmit). + + 2009-04-25 Simon Goldschmidt + * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation + when debugging": memp_sizes contained the wrong sizes (including sanity + regions); memp pools for MEM_USE_POOLS were too small + + 2009-04-24 Simon Goldschmidt, Frdric Bernon + * inet.c: patch #6765: Fix a small problem with the last changes (incorrect + behavior, with with ip address string not ended by a '\0', a space or a + end of line) + + 2009-04-19 Simon Goldschmidt + * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, + pcb->err is called, not pcb->connected (with an error code). + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with + no-copy-tcpwrite": deallocate option data, only concat segments with same flags + + 2009-04-19 Simon Goldschmidt + * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated + in the header pbuf, not the data pbuf) + + 2009-04-18 Simon Goldschmidt + * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() + + 2009-04-15 Simon Goldschmidt + * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp + + 2009-04-15 Simon Goldschmidt + * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in + + 2009-04-15 Simon Goldschmidt + * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function + ip_hinted_output() (for smaller code mainly) + + 2009-04-15 Simon Goldschmidt + * inet.c: patch #6765: Supporting new line characters in inet_aton() + + 2009-04-15 Simon Goldschmidt + * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; + Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu + is big enough in dhcp_start + + 2009-04-15 Simon Goldschmidt + * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak + + 2009-04-15 Simon Goldschmidt + * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY + + 2009-04-15 Simon Goldschmidt + * sockets.c: bug #26121: set_errno can be overridden + + 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) + * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when + LWIP_TCP==0 + + 2009-04-09 Kieran Mansley (patch from Roy Lee ) + * tcp.h: Patch#6802 Add do-while-clauses to those function like + macros in tcp.h + + 2009-03-31 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window + updates are calculated and sent (BUG20515) + + * tcp_in.c: cope with SYN packets received during established states, + and retransmission of initial SYN. + + * tcp_out.c: set push bit correctly when tcp segments are merged + + 2009-03-27 Kieran Mansley + * tcp_out.c set window correctly on probes (correcting change made + yesterday) + + 2009-03-26 Kieran Mansley + * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping + connections where no reset required (bug #25622) + + * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes + (bug #20779) + + 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) + * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be + too small depending on MEM_ALIGNMENT + + 2009-02-16 Simon Goldschmidt + * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; + converted size argument of netconn_write to 'size_t' + + 2009-02-16 Simon Goldschmidt + * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host + by moving accept callback function pointer to TCP_PCB_COMMON + + 2009-02-12 Simon Goldschmidt + * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" + option) + + 2009-02-11 Simon Goldschmidt + * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) + + 2009-02-11 Simon Goldschmidt + * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: + RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) + + 2009-02-10 Simon Goldschmidt + * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: + Accepts_pending is decrease on a corresponding listen pcb when a connection + in state SYN_RCVD is close. + + 2009-01-28 Jonathan Larmour + * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run + out of pool pbufs. + + 2008-12-19 Simon Goldschmidt + * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 + + 2008-12-10 Tamas Somogyi, Frdric Bernon + * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and + port uses deleted netbuf. + + 2008-10-18 Simon Goldschmidt + * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length + in tcp_parseopt + + 2008-10-15 Simon Goldschmidt + * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers + by packing the struct ip_reass_helper. + + 2008-10-03 David Woodhouse, Jonathan Larmour + * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. + + 2008-10-02 Jonathan Larmour + * dns.c: Hard-code structure sizes, to avoid issues on some compilers where + padding is included. + + 2008-09-30 Jonathan Larmour + * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an + assertion check that addrlen isn't NULL. + + 2008-09-30 Jonathan Larmour + * tcp.c: Fix bug #24227, wrong error message in tcp_bind. + + 2008-08-26 Simon Goldschmidt + * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and + inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h + + 2008-08-14 Simon Goldschmidt + * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when + tcp_close returns != ERR_OK) + + 2008-07-08 Frdric Bernon + * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters + in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). + + 2008-06-24 Jonathan Larmour + * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused + if tcp_seg_copy fails. + + 2008-06-17 Simon Goldschmidt + * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) + and created defines for swapping bytes and folding u32 to u16. + + 2008-05-30 Kieran Mansley + * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd + rather than rcv_ann_wnd when deciding if packets are in-window. + Contributed by + + 2008-05-30 Kieran Mansley + * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow + passing as function pointers when MEM_LIBC_MALLOC is defined. + + 2008-05-09 Jonathan Larmour + * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to + stop it being treated as a fatal error. + + 2008-04-15 Simon Goldschmidt + * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP + (flag now cleared) + + 2008-03-27 Simon Goldschmidt + * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free + from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 + in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs + or heap memory from interrupt context + + 2008-03-26 Simon Goldschmidt + * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote + host sent a zero mss as TCP option. + + +(STABLE-1.3.0) + + ++ New features: + + 2008-03-10 Jonathan Larmour + * inet_chksum.c: Allow choice of one of the sample algorithms to be + made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. + + 2008-01-22 Frdric Bernon + * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in + TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. + + 2008-01-14 Frdric Bernon + * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable + to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the + tcp_recv callback (see rawapi.txt). + + 2008-01-14 Frdric Bernon, Marc Chaland + * ip.c: Integrate patch #6369" ip_input : checking before realloc". + + 2008-01-12 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::sem per netconn::op_completed like suggested for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-12 Frdric Bernon + * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, + DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues + sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 + "Add return value to sys_mbox_post". tcpip_callback is always defined as + "blocking" ("block" parameter = 1). + + 2008-01-10 Frdric Bernon + * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field + netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 + "Add return value to sys_mbox_post". + + 2008-01-05 Frdric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + + 2008-01-04 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, + tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the + "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add + documentation in the rawapi.txt file. + + 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer + + 2007-12-31 Frdric Bernon, Luca Ceresoli + * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets + in autoip". The change in etharp_raw could be removed, since all calls to + etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be + wrong in the future. + + 2007-12-30 Frdric Bernon, Tom Evans + * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address + Filtering" reported by Tom Evans. + + 2007-12-21 Frdric Bernon, Simon Goldschmidt, Jonathan Larmour + * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, + sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API + applications have to call 'tcp_accepted(pcb)' in their accept callback to + keep accepting new connections. + + 2007-12-13 Frdric Bernon + * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" + by err_t type. Add a new err_t code "ERR_INPROGRESS". + + 2007-12-12 Frdric Bernon + * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles + are the one which have ram usage. + + 2007-12-05 Frdric Bernon + * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static + set of variables (=0) or a local one (=1). In this last case, your port should + provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" + which have to do a copy of "h" and return a pointer ont the "per-thread" copy. + + 2007-12-03 Simon Goldschmidt + * ip.c: ip_input: check if a packet is for inp first before checking all other + netifs on netif_list (speeds up packet receiving in most cases) + + 2007-11-30 Simon Goldschmidt + * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access + UDP: move a (connected) pcb selected for input to the front of the list of + pcbs so that it is found faster next time. Same for RAW pcbs that have eaten + a packet. + + 2007-11-28 Simon Goldschmidt + * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS + + 2007-11-25 Simon Goldschmidt + * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy + algorithm. + + 2007-11-24 Simon Goldschmidt + * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c + to the new file netdb.c; included lwip_getaddrinfo. + + 2007-11-21 Simon Goldschmidt + * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss + based on the MTU of the netif used to send. Enabled by default. Disable by + setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. + + 2007-11-19 Frdric Bernon + * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name + received match the name query), implement DNS_USES_STATIC_BUF (the place where + copy dns payload to parse the response), return an error if there is no place + for a new query, and fix some minor problems. + + 2007-11-16 Simon Goldschmidt + * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c + removed files: core/inet.c, core/inet6.c + Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into + inet and chksum part; changed includes in all lwIP files as appropriate + + 2007-11-16 Simon Goldschmidt + * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential + dns resolver function for netconn api (netconn_gethostbyname) and socket api + (gethostbyname/gethostbyname_r). + + 2007-11-15 Jim Pettinato, Frdric Bernon + * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name + requests with RAW api interface. Initialization is done in lwip_init() with + build time options. DNS timer is added in tcpip_thread context. DHCP can set + DNS server ip addresses when options are received. You need to set LWIP_DNS=1 + in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get + some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" + list with points to improve. + + 2007-11-06 Simon Goldschmidt + * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly + enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status + for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. + + 2007-11-06 Simon Goldschmidt + * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include + core header files in api.h (ip/tcp/udp/raw.h) to hide the internal + implementation from netconn api applications. + + 2007-11-03 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & + RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled + by default). Netconn API users can use the netconn_recv_bufsize macro to access + it. This is a first release which have to be improve for TCP. Note it used the + netconn::recv_avail which need to be more "thread-safe" (note there is already + the problem for FIONREAD with lwip_ioctl/ioctlsocket). + + 2007-11-01 Frdric Bernon, Marc Chaland + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: + Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api + layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api + layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. + Note that previous "copy" parameter for "write" APIs is now called "apiflags". + + 2007-10-24 Frdric Bernon + * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than + TCP_EVENT_xxx macros to get a code more readable. It could also help to remove + some code (like we have talk in "patch #5919 : Create compile switch to remove + select code"), but it could be done later. + + 2007-10-08 Simon Goldschmidt + * many files: Changed initialization: many init functions are not needed any + more since we now rely on the compiler initializing global and static + variables to zero! + + 2007-10-06 Simon Goldschmidt + * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY + to enqueue the received pbufs so that multiple packets can be reassembled + simultaneously and no static reassembly buffer is needed. + + 2007-10-05 Simon Goldschmidt + * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so + all netifs (or ports) can use it. + + 2007-10-05 Frdric Bernon + * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the + common function to reduce a little bit the footprint (for all functions using + only the "netif" parameter). + + 2007-10-03 Frdric Bernon + * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, + netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce + a little bit the footprint (for all functions using only the "netif" parameter). + + 2007-09-15 Frdric Bernon + * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF + option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for + netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for + IP_MULTICAST_TTL and IP_MULTICAST_IF. + + 2007-09-10 Frdric Bernon + * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles + even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() + each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can + decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but + call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() + or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. + This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside + snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only + when it's queried (any direct call to "sysuptime" is changed by a call to + snmp_get_sysuptime). + + 2007-09-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, + and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags + if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). + igmp_report_groups() is now called inside netif_set_link_up() (need to have + LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait + the next query message to receive the matching multicast streams). + + 2007-09-08 Frdric Bernon + * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains + IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). + Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). + Enable to access to these fields with LWIP_TCP=0. + + 2007-09-05 Frdric Bernon + * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, + ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option + LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). + Be careful, disabling ICMP make your product non-compliant to RFC1122, but + help to reduce footprint, and to reduce "visibility" on the Internet. + + 2007-09-05 Frdric Bernon, Bill Florac + * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list + for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new + parameters have to be provided: a task name, and a task stack size. For this + one, since it's platform dependant, you could define the best one for you in + your lwipopts.h. For port maintainers, you can just add these new parameters + in your sys_arch.c file, and but it's not mandatory, use them in your OS + specific functions. + + 2007-09-05 Frdric Bernon + * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings + inside init.c for task #7142 "Sanity check user-configurable values". + + 2007-09-04 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by + memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the + value). It will avoid potential fragmentation problems, use a counter to know + how many times a group is used on an netif, and free it when all applications + leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity + check if LWIP_IGMP!=0). + + 2007-09-03 Frdric Bernon + * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". + Initialize igmp_mac_filter to NULL in netif_add (this field should be set in + the netif's "init" function). Use the "imr_interface" field (for socket layer) + and/or the "interface" field (for netconn layer), for join/leave operations. + The igmp_join/leavegroup first parameter change from a netif to an ipaddr. + This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). + + 2007-08-30 Frdric Bernon + * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions + from api/api_lib". Now netbuf API is independant of netconn, and can be used + with other API (application based on raw API, or future "socket2" API). Ports + maintainers just have to add src/api/netbuf.c in their makefile/projects. + + 2007-08-30 Frdric Bernon, Jonathan Larmour + * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check + user-configurable values". + + 2007-08-29 Frdric Bernon + * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. + igmp_start is call inside netif_add. Now, igmp initialization is in the same + spirit than the others modules. Modify some IGMP debug traces. + + 2007-08-29 Frdric Bernon + * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" + Add lwip_init function to regroup all modules initializations, and to provide + a place to add code for task #7142 "Sanity check user-configurable values". + Ports maintainers should remove direct initializations calls from their code, + and add init.c in their makefiles. Note that lwip_init() function is called + inside tcpip_init, but can also be used by raw api users since all calls are + disabled when matching options are disabled. Also note that their is new options + in opt.h, you should configure in your lwipopts.h (they are enabled per default). + + 2007-08-26 Marc Boucher + * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL + since they can under certain circumstances be called with an invalid conn + pointer after the connection has been closed (and conn has been freed). + + 2007-08-25 Frdric Bernon (Artem Migaev's Patch) + * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". + Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. + + 2007-08-22 Frdric Bernon + * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK + to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. + + 2007-08-22 Frdric Bernon + * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & + ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the + name is tcpip_input (we keep the name of 1.2.0 function). + + 2007-08-17 Jared Grubb + * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool + settings into new memp_std.h and optional user file lwippools.h. This adds + more dynamic mempools, and allows the user to create an arbitrary number of + mempools for mem_malloc. + + 2007-08-16 Marc Boucher + * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; + otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely + close the connection. + + 2007-08-16 Marc Boucher + * sockets.c: lwip_accept(): check netconn_peer() error return. + + 2007-08-16 Marc Boucher + * mem.c, mem.h: Added mem_calloc(). + + 2007-08-16 Marc Boucher + * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) + for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG + and starving other message types. + Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API + + 2007-08-16 Marc Boucher + * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf + type and flgs (later renamed to flags). + Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. + Improved lwip_recvfrom(). TCP push now propagated. + + 2007-08-16 Marc Boucher + * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global + provided by etharp. + + 2007-08-16 Marc Boucher + * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, + etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: + Added PPPoE support and various PPP improvements. + + 2007-07-25 Simon Goldschmidt + * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, + making netbuf_copy_partial use this function. + + 2007-07-25 Simon Goldschmidt + * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with + 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and + other stacks. + + 2007-07-13 Jared Grubb (integrated by Frdric Bernon) + * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add + a link callback in the netif struct, and functions to handle it. Be carefull + for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) + if you want to be sure to be compatible with future changes... + + 2007-06-30 Frdric Bernon + * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. + + 2007-06-21 Simon Goldschmidt + * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both + LWIP_AUTOIP =0 and =1 to remove redundant code. + + 2007-06-21 Simon Goldschmidt + * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option + MEM_USE_POOLS to use 4 pools with different sized elements instead of a + heap. This both prevents memory fragmentation and gives a higher speed + at the cost of more memory consumption. Turned off by default. + + 2007-06-21 Simon Goldschmidt + * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of + netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into + int to be able to send a bigger buffer than 64K with one time (mainly + used from lwip_send). + + 2007-06-21 Simon Goldschmidt + * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write + into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. + + 2007-06-21 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in + netconn_write from api_lib.c to api_msg.c to also prevent multiple context- + changes on low memory or empty send-buffer. + + 2007-06-18 Simon Goldschmidt + * etharp.c, etharp.h: Changed etharp to use a defined hardware address length + of 6 to avoid loading netif->hwaddr_len every time (since this file is only + used for ethernet and struct eth_addr already had a defined length of 6). + + 2007-06-17 Simon Goldschmidt + * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets + to disable UDP checksum generation on transmit. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid + pointers or parameters, and let the possibility to redefined it in cc.h. Use + this macro to check "conn" parameter in api_msg.c functions. + + 2007-06-11 Simon Goldschmidt + * sockets.c, sockets.h: Added UDP lite support for sockets + + 2007-06-10 Simon Goldschmidt + * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled + by default) to switch off UDP-Lite support if not needed (reduces udp.c code + size) + + 2007-06-09 Dominik Spies (integrated by Frdric Bernon) + * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: + AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and + LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt + (see TODO mark in the source code). + + 2007-06-09 Simon Goldschmidt + * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for + etharp_output() to match netif->output so etharp_output() can be used + directly as netif->output to save one function call. + + 2007-06-08 Simon Goldschmidt + * netif.h, ethernetif.c, slipif.c, loopif.c: Added define + NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, + added initialization of those to ethernetif, slipif and loopif. + + 2007-05-18 Simon Goldschmidt + * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF + (defaulting to off for now) that can be set to 0 to send fragmented + packets by passing PBUF_REFs down the stack. + + 2007-05-23 Frdric Bernon + * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP + connections, such present in patch #5959. + + 2007-05-23 Frdric Bernon + * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx + code in only one part... + + 2007-05-18 Simon Goldschmidt + * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp + elements to overflow. This is achieved by adding some bytes before and after + each pool element (increasing their size, of course), filling them with a + prominent value and checking them on freeing the element. + Set it to 2 to also check every element in every pool each time memp_malloc() + or memp_free() is called (slower but more helpful). + + 2007-05-10 Simon Goldschmidt + * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for + PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce + code size. + + 2007-05-11 Frdric Bernon + * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: + Include a function pointer instead of a table index in the message to reduce + footprint. Disable some part of lwip_send and lwip_sendto if some options are + not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). + + 2007-05-10 Simon Goldschmidt + * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus + \ extern "C" {' in all header files. Now you can write your application using + the lwIP stack in C++ and simply #include the core files. Note I have left + out the netif/ppp/*h header files for now, since I don't know which files are + included by applications and which are for internal use only. + + 2007-05-09 Simon Goldschmidt + * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library + memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for + situations where some compilers might inline the copy and save a function + call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). + + 2007-05-08 Simon Goldschmidt + * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) + to be overriden in case the C-library malloc implementation is not protected + against concurrent access. + + 2007-05-04 Simon Goldschmidt (Atte Kojo) + * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending + multiple packets to the same host. + + 2007-05-04 Frdric Bernon, Jonathan Larmour + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible + to corrupt remote addr/port connection state". Reduce problems "not enought memory" with + netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between + sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. + Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, + these fields are now renamed "addr" & "port". + + 2007-04-11 Jonathan Larmour + * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new + sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return + with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro + by the port in sys_arch.h if desired. + + 2007-04-06 Frdric Bernon, Simon Goldschmidt + * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API + allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp + clients, using new functions from netifapi.h. Disable as default (no port change to do). + + 2007-04-05 Frdric Bernon + * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. + + 2007-04-04 Simon Goldschmidt + * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) + use this for and architecture-independent form to tell the compiler you intentionally + are not using this variable. Can be overriden in cc.h. + + 2007-03-28 Frdric Bernon + * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to + define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded + string, point on one of your's ethernetif field, or alloc a string you will free yourself). + It will be used by DHCP to register a client hostname, but can also be use when you call + snmp_set_sysname. + + 2007-03-28 Frdric Bernon + * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to + initialize a network interface's flag with. It tell this interface is an ethernet + device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility + Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). + + 2007-03-26 Frdric Bernon, Jonathan Larmour + * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build + time if you only use PPP or SLIP. The default is enable. Note we don't have to call + etharp_init in your port's initilization sequence if you use tcpip.c, because this call + is done in tcpip_init function. + + 2007-03-22 Frdric Bernon + * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the + new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in + your lwipopts.h. More, unused counters are not defined in the stats structs, and not + display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined + but never used. Fix msg_in.c with the correct #if test for a stat display. + + 2007-03-21 Kieran Mansley + * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). + Provides callback on netif up/down state change. + + 2007-03-11 Frdric Bernon, Mace Gael, Steve Reynolds + * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, + ip.c, netif.h, tcpip.c, opt.h: + New configuration option LWIP_IGMP to enable IGMP processing. Based on only one + filter per all network interfaces. Declare a new function in netif to enable to + control the MAC filter (to reduce lwIP traffic processing). + + 2007-03-11 Frdric Bernon + * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can + be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this + unless you know what you're doing (default are RFC1122 compliant). Note + that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. + + 2007-03-08 Frdric Bernon + * tcp.h: Keepalive values can be configured at compile time, but don't change + this unless you know what you're doing (default are RFC1122 compliant). + + 2007-03-08 Frdric Bernon + * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: + Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO + on UDP sockets/netconn. + + 2007-03-08 Simon Goldschmidt + * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. + + 2007-03-06 Frdric Bernon + * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: + Implement SO_RCVTIMEO on UDP sockets/netconn. + + 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) + * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated + on the stack and remove the API msg type from memp + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * sockets.h, sockets.c: Move socket initialization to new + lwip_socket_init() function. + NOTE: this changes the API with ports. Ports will have to be + updated to call lwip_socket_init() now. + + 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) + * api_lib.c: Use memcpy in netbuf_copy_partial. + + + ++ Bug fixes: + + 2008-03-17 Frdric Bernon, Ed Kerekes + * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have + some problems to fill the IP header on some targets, use now the + ip.h macros to do it). + + 2008-03-13 Frdric Bernon + * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using + (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a + TCP connection caused a crash. Note that using (lwip_)recvfrom + like this is a bit slow and that using (lwip)getpeername is the + good lwip way to do it (so, using recv is faster on tcp sockets). + + 2008-03-12 Frdric Bernon, Jonathan Larmour + * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's + recv_raw() does not consume data", and the ping sample (with + LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom + returned the IP payload, without the IP header). + + 2008-03-04 Jonathan Larmour + * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors + and/or warnings on some systems where mem_size_t and size_t differ. + * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. + + 2008-03-04 Kieran Mansley (contributions by others) + * Numerous small compiler error/warning fixes from contributions to + mailing list after 1.3.0 release candidate made. + + 2008-01-25 Cui hengbin (integrated by Frdric Bernon) + * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. + + 2008-01-15 Kieran Mansley + * tcp_out.c: BUG20511. Modify persist timer to start when we are + prevented from sending by a small send window, not just a zero + send window. + + 2008-01-09 Jonathan Larmour + * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid + conflict with Linux system headers. + + 2008-01-06 Jonathan Larmour + * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP + address entirely on receiving a DHCPNAK, and restarting discovery. + + 2007-12-21 Simon Goldschmidt + * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail + is not protected" by using new macros for interlocked access to modify/test + netconn->recv_avail. + + 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) + * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) + + 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling + of silly window avoidance and prevent lwIP from shrinking the window) + + 2007-12-04 Simon Goldschmidt + * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last + data packet was lost): add assert that all segment lists are empty in + tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED + state from LAST_ACK in tcp_process + + 2007-12-02 Simon Goldschmidt + * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET + If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now + has to be set to 0 in lwipopts.h + + 2007-12-02 Simon Goldschmidt + * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always + allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen + netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. + This is a fix for thread-safety and allocates all items needed for a netconn + when the netconn is created. + + 2007-11-30 Simon Goldschmidt + * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple + netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed + to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same + port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) + + 2007-11-27 Simon Goldschmidt + * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by + letting ip_route only use netifs that are up. + + 2007-11-27 Simon Goldschmidt + * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF + and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and + sockets block most operations once they have seen a fatal error. + + 2007-11-27 Simon Goldschmidt + * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the + netif to send as an argument (to be able to send on netifs that are down). + + 2007-11-26 Simon Goldschmidt + * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs + arrive out-of-order + + 2007-11-21 Simon Goldschmidt + * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early + Fixed the nagle algorithm; nagle now also works for all raw API applications + and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' + + 2007-11-12 Frdric Bernon + * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most + of the netconn_peer and netconn_addr processing is done inside tcpip_thread + context in do_getaddr. + + 2007-11-10 Simon Goldschmidt + * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can + happen any time). Now the packet simply isn't enqueued when out of memory. + + 2007-11-01 Simon Goldschmidt + * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or + TCP_MSS if that is smaller) as long as no MSS option is received from the + remote host. + + 2007-11-01 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) + is now based on TCP_MSS instead of pcb->mss (on passive open now effectively + sending our configured TCP_MSS instead of the one received). + + 2007-11-01 Simon Goldschmidt + * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was + calculated based on the configured TCP_MSS, not on the MSS option received + with SYN+ACK. + + 2007-10-09 Simon Goldschmidt + * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too + short and also was generated wrong if checksum coverage != tot_len; + receive: checksum was calculated wrong if checksum coverage != tot_len + + 2007-10-08 Simon Goldschmidt + * mem.c: lfree was not updated in mem_realloc! + + 2007-10-07 Frdric Bernon + * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential + crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: + this change cause an API breakage for netconn_addr, since a parameter + type change. Any compiler should cause an error without any changes in + yours netconn_peer calls (so, it can't be a "silent change"). It also + reduce a little bit the footprint for socket layer (lwip_getpeername & + lwip_getsockname use now a common lwip_getaddrname function since + netconn_peer & netconn_addr have the same parameters). + + 2007-09-20 Simon Goldschmidt + * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) + by checking tcp_tw_pcbs also + + 2007-09-19 Simon Goldschmidt + * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) + + 2007-09-15 Mike Kleshov + * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) + + 2007-09-06 Frdric Bernon + * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove + it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which + already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" + if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. + + 2007-08-30 Frdric Bernon + * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, + and fix some coding style. + + 2007-08-28 Frdric Bernon + * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any + kind of packets. These packets are considered like Ethernet packets (payload + pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets + are considered like IP packets (payload pointing to iphdr). + + 2007-08-27 Frdric Bernon + * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error + problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state + and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). + + 2007-08-24 Kieran Mansley + * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy + compiler (Paradigm C++) + + 2007-08-09 Frdric Bernon, Bill Florac + * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. + Introduce IGMP_STATS to centralize statistics management. + + 2007-08-09 Frdric Bernon, Bill Florac + * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast + packet on a udp pcb binded on an netif's IP address, and not on "any". + + 2007-08-09 Frdric Bernon, Bill Florac + * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. + This is mainly on using lookup/lookfor, and some coding styles... + + 2007-07-26 Frdric Bernon (and "thedoctor") + * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. + + 2007-07-25 Simon Goldschmidt + * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if + tcp_output fails in tcp_close, the code in do_close_internal gets simpler + (tcp_output is called again later from tcp timers). + + 2007-07-25 Simon Goldschmidt + * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old + copy_from_pbuf, which illegally modified the given pbuf. + + 2007-07-25 Simon Goldschmidt + * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: + changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). + + 2007-07-24 Simon Goldschmidt + * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the + correct state (must be CLOSED). + + 2007-07-13 Thomas Taranowski (commited by Jared Grubb) + * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed + allocation. It now returns NULL. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in + all error cases. + + 2007-07-13 Frdric Bernon + * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, + because current code doesn't follow rawapi.txt documentation. + + 2007-07-13 Kieran Mansley + * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in + out of sequence processing of received packets + + 2007-07-03 Simon Goldschmidt + * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an + assumption is made that this pbuf is in one piece (i.e. not chained). These + assumptions clash with the possibility of converting to fully pool-based + pbuf implementations, where PBUF_RAM pbufs might be chained. + + 2007-07-03 Simon Goldschmidt + * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems + when closing tcp netconns: removed conn->sem, less context switches when + closing, both netconn_close and netconn_delete should safely close tcp + connections. + + 2007-07-02 Simon Goldschmidt + * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, + tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) + to cache ARP table indices with each pcb instead of single-entry cache for + the complete stack. + + 2007-07-02 Simon Goldschmidt + * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent + warnings when assigning to smaller types. + + 2007-06-28 Simon Goldschmidt + * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. + + 2007-06-28 Simon Goldschmidt + * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if + a segment contained chained pbufs) + + 2007-06-28 Frdric Bernon + * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute + a "pseudo-random" value based on netif's MAC and some autoip fields. It's always + possible to define this macro in your own lwipopts.h to always use C library's + rand(). Note that autoip_create_rand_addr doesn't use this macro. + + 2007-06-28 Frdric Bernon + * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option + LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications + in api_lib/api_msg (use pointers and not type with table, etc...) + + 2007-06-26 Simon Goldschmidt + * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload + for udp packets with no matching pcb. + + 2007-06-25 Simon Goldschmidt + * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match + could get udp input packets if the remote side matched. + + 2007-06-13 Simon Goldschmidt + * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get + changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. + + 2007-06-13 Simon Goldschmidt + * api_msg.c: pcb_new sets conn->err if protocol is not implemented + -> netconn_new_..() does not allocate a new connection for unsupported + protocols. + + 2007-06-13 Frdric Bernon, Simon Goldschmidt + * api_lib.c: change return expression in netconn_addr and netconn_peer, because + conn->err was reset to ERR_OK without any reasons (and error was lost)... + + 2007-06-13 Frdric Bernon, Matthias Weisser + * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename + MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid + some macro names collision with some OS macros. + + 2007-06-11 Simon Goldschmidt + * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, + create checksum over the complete packet. On RX, if it's < 8 (and not 0), + discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both + UDP & UDP Lite. + + 2007-06-11 Srinivas Gollakota & Oleg Tyshev + * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" + where TCP flags wasn't initialized in tcp_keepalive. + + 2007-06-03 Simon Goldschmidt + * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function + registered, p->payload was modified without modifying p->len if sending + icmp_dest_unreach() (had no negative effect but was definitively wrong). + + 2007-06-03 Simon Goldschmidt + * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp + re-used the input pbuf even if that didn't have enough space to include the + link headers. Now the space is tested and a new pbuf is allocated for the + echo response packet if the echo request pbuf isn't big enough. + + 2007-06-01 Simon Goldschmidt + * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. + + 2007-05-23 Frdric Bernon + * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only + allocated by do_listen if success) and netconn_accept errors handling. In + most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" + by ASSERT, except for netconn_delete. + + 2007-05-23 Frdric Bernon + * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return + an error code if it's impossible to fetch a pbuf on a TCP connection (and not + directly close the recvmbox). + + 2007-05-22 Simon Goldschmidt + * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of + bound but unconnected (and non-listening) tcp_pcbs. + + 2007-05-22 Frdric Bernon + * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only + used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of + sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features + like "sys_timeout" in their application threads. + + 2007-05-22 Frdric Bernon + * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see + which parameters are used by which do_xxx function, and to avoid "misusing" + parameters (patch #5938). + + 2007-05-22 Simon Goldschmidt + * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: + changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto + is only 8 bits wide. This affects the api, as there, the protocol was + u16_t, too. + + 2007-05-18 Simon Goldschmidt + * memp.c: addition to patch #5913: smaller pointer was returned but + memp_memory was the same size -> did not save memory. + + 2007-05-16 Simon Goldschmidt + * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns + != ERR_OK. + + 2007-05-16 Simon Goldschmidt + * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same + as the one of the netif used for sending to prevent sending from old + addresses after a netif address gets changed (partly fixes bug #3168). + + 2007-05-16 Frdric Bernon + * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work + with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in + tcpip_init) because we have to be sure that network interfaces are already + added (mac filter is updated only in igmp_init for the moment). + + 2007-05-16 Simon Goldschmidt + * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls + into sys_arch_sem_wait calls to prevent timers from running while waiting + for the heap. This fixes bug #19167. + + 2007-05-13 Simon Goldschmidt + * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines + for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from + tcp.h to sockets.h. + + 2007-05-07 Simon Goldschmidt + * mem.c: Another attempt to fix bug #17922. + + 2007-05-04 Simon Goldschmidt + * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() + implementation so that it can be reused (don't allocate the target + pbuf inside pbuf_copy()). + + 2007-05-04 Simon Goldschmidt + * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem + to save a little RAM (next pointer of memp is not used while not in pool). + + 2007-05-03 "maq" + * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. + (patch #3574). + + 2007-04-23 Simon Goldschmidt + * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results + in NULL reference for incoming TCP packets". Loopif has to be configured + (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() + (multithreading environments, e.g. netif->input() = tcpip_input()) or + putting packets on a list that is fed to the stack by calling loopif_poll() + (single-thread / NO_SYS / polling environment where e.g. + netif->input() = ip_input). + + 2007-04-17 Jonathan Larmour + * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold + the difference between two u16_t's. + * sockets.h: FD_SETSIZE needs to match number of sockets, which is + MEMP_NUM_NETCONN in sockets.c right now. + + 2007-04-12 Jonathan Larmour + * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). + + 2007-04-12 Kieran Mansley + * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission + timer is reset to fix bug#19434, with help from Oleg Tyshev. + + 2007-04-11 Simon Goldschmidt + * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than + previously thought need to be copied (everything but PBUF_ROM!). Cleaned up + pbuf.c: removed functions no needed any more (by etharp). + + 2007-04-11 Kieran Mansley + * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix + "Constant is long" warnings with 16bit compilers. Contributed by + avatar@mmlab.cse.yzu.edu.tw + + 2007-04-05 Frdric Bernon, Jonathan Larmour + * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on + the mailbox is active". Now, the post is only done during a connect, and do_send, + do_write and do_join_leave_group don't do anything if a previous error was signaled. + + 2007-04-03 Frdric Bernon + * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output + packets. See patch #5834. + + 2007-03-30 Frdric Bernon + * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add + missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. + + 2007-03-30 Frdric Bernon + * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with + others environment defines (these were too "generic"). + + 2007-03-28 Frdric Bernon + * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call + result and can cause a crash. lwip_send now check netbuf_ref result. + + 2007-03-28 Simon Goldschmidt + * sockets.c Remove "#include " from sockets.c to avoid multiple + definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is + defined. This is the way it should have been already (looking at + doc/sys_arch.txt) + + 2007-03-28 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + + IP and TCP headers *and* physical link headers + + 2007-03-26 Frdric Bernon (based on patch from Dmitry Potapov) + * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause + to send some garbage. It is not a definitive solution, but the patch does solve + the problem for most cases. + + 2007-03-22 Frdric Bernon + * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). + + 2007-03-22 Frdric Bernon + * api_lib.c: somes resources couldn't be freed if there was errors during + netconn_new_with_proto_and_callback. + + 2007-03-22 Frdric Bernon + * ethernetif.c: update netif->input calls to check return value. In older ports, + it's a good idea to upgrade them, even if before, there could be another problem + (access to an uninitialized mailbox). + + 2007-03-21 Simon Goldschmidt + * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed + by casting to unsigned). + + 2007-03-21 Frdric Bernon + * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from + api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a + dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. + Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a + faster and more reliable communication between api_lib and tcpip. + + 2007-03-21 Frdric Bernon + * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. + + 2007-03-21 Frdric Bernon + * api_msg.c, igmp.c, igmp.h: Fix C++ style comments + + 2007-03-21 Kieran Mansley + * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + + IP and TCP headers + + 2007-03-21 Kieran Mansley + * Fix all uses of pbuf_header to check the return value. In some + cases just assert if it fails as I'm not sure how to fix them, but + this is no worse than before when they would carry on regardless + of the failure. + + 2007-03-21 Kieran Mansley + * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and + comment out missing header include in icmp.c + + 2007-03-20 Frdric Bernon + * memp.h, stats.c: Fix stats_display function where memp_names table wasn't + synchronized with memp.h. + + 2007-03-20 Frdric Bernon + * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, + tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with + network interfaces. Also fix a compiler warning. + + 2007-03-20 Kieran Mansley + * udp.c: Only try and use pbuf_header() to make space for headers if + not a ROM or REF pbuf. + + 2007-03-19 Frdric Bernon + * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() + and api_msg_post(). + + 2007-03-19 Frdric Bernon + * Remove unimplemented "memp_realloc" function from memp.h. + + 2007-03-11 Simon Goldschmidt + * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused + memory corruption. + + 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) + * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 + (missing `const' qualifier in socket functions), to get more compatible to + standard POSIX sockets. + + 2007-03-11 Frdric Bernon (based on patch from Dmitry Potapov) + * sockets.c: Add asserts inside bind, connect and sendto to check input + parameters. Remove excessive set_errno() calls after get_socket(), because + errno is set inside of get_socket(). Move last sock_set_errno() inside + lwip_close. + + 2007-03-09 Simon Goldschmidt + * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory + was allocated too small. + + 2007-03-06 Simon Goldschmidt + * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect + the stack from concurrent access. + + 2007-03-06 Frdric Bernon, Dmitry Potapov + * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy + call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). + + 2007-03-06 Simon Goldschmidt + * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files + if IP_FRAG == 0 and IP_REASSEMBLY == 0 + + 2007-03-06 Frdric Bernon, Simon Goldschmidt + * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration + option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. + Allow to do ARP processing for incoming packets inside tcpip_thread + (protecting ARP layer against concurrent access). You can also disable + old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. + Older ports have to use tcpip_ethinput. + + 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) + * err.h, err.c: fixed compiler warning "initialization dircards qualifiers + from pointer target type" + + 2007-03-05 Frdric Bernon + * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, + ETHARP_TRUST_IP_MAC, review SO_REUSE) + + 2007-03-04 Frdric Bernon + * api_msg.c: Remove some compiler warnings : parameter "pcb" was never + referenced. + + 2007-03-04 Frdric Bernon + * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from + Dmitry Potapov). + The api_msg struct stay on the stack (not moved to netconn struct). + + 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) + * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if + SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) + Also fixed cast warning in pbuf_alloc() + + 2007-03-04 Simon Goldschmidt + * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt + existing pbuf chain when enqueuing multiple pbufs to a pending ARP request + + 2007-03-03 Frdric Bernon + * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" + It is static, and never used in udp.c except udp_init(). + + 2007-03-02 Simon Goldschmidt + * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from + tcpip_thread() to tcpip_init(). This way, raw API connections can be + initialized before tcpip_thread is running (e.g. before OS is started) + + 2007-03-02 Frdric Bernon + * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call + interval. + + 2007-02-28 Kieran Mansley + * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved + outside the region of the pbuf by pbuf_header() + + 2007-02-28 Kieran Mansley + * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero + when supplied timeout is also non-zero + +(STABLE-1.2.0) + + 2006-12-05 Leon Woestenberg + * CHANGELOG: Mention STABLE-1.2.0 release. + + ++ New features: + + 2006-12-01 Christiaan Simons + * mem.h, opt.h: Added MEM_LIBC_MALLOC option. + Note this is a workaround. Currently I have no other options left. + + 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) + * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define + to include/lwip/opt.h. + * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. + Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. + * opt.h: Add above new options. + + 2006-08-18 Christiaan Simons + * tcp_{in,out}.c: added SNMP counters. + * ipv4/ip.c: added SNMP counters. + * ipv4/ip_frag.c: added SNMP counters. + + 2006-08-08 Christiaan Simons + * etharp.{c,h}: added etharp_find_addr() to read + (stable) ethernet/IP address pair from ARP table + + 2006-07-14 Christiaan Simons + * mib_structs.c: added + * include/lwip/snmp_structs.h: added + * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct + + 2006-07-06 Christiaan Simons + * snmp/asn1_{enc,dec}.c added + * snmp/mib2.c added + * snmp/msg_{in,out}.c added + * include/lwip/snmp_asn1.h added + * include/lwip/snmp_msg.h added + * doc/snmp_agent.txt added + + 2006-03-29 Christiaan Simons + * inet.c, inet.h: Added platform byteswap support. + Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and + optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. + + ++ Bug fixes: + + 2006-11-30 Christiaan Simons + * dhcp.c: Fixed false triggers of request_timeout. + + 2006-11-28 Christiaan Simons + * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. + + 2006-10-11 Christiaan Simons + * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: + Partially accepted patch #5449 for ANSI C compatibility / build fixes. + * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol + identifier from 170 to 136 (bug #17574). + + 2006-10-10 Christiaan Simons + * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. + + 2006-08-17 Christiaan Simons + * udp.c: Fixed bug #17200, added check for broadcast + destinations for PCBs bound to a unicast address. + + 2006-08-07 Christiaan Simons + * api_msg.c: Flushing TCP output in do_close() (bug #15926). + + 2006-06-27 Christiaan Simons + * api_msg.c: Applied patch for cold case (bug #11135). + In accept_function() ensure newconn->callback is always initialized. + + 2006-06-15 Christiaan Simons + * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), + facilitate printing of mem_size_t and u16_t statistics. + + 2006-06-14 Christiaan Simons + * api_msg.c: Applied patch #5146 to handle allocation failures + in accept() by Kevin Lawson. + + 2006-05-26 Christiaan Simons + * api_lib.c: Removed conn->sem creation and destruction + from netconn_write() and added sys_sem_new to netconn_new_*. + +(STABLE-1_1_1) + + 2006-03-03 Christiaan Simons + * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap + access and added pbuf_alloc() return value checks. + + 2006-01-01 Leon Woestenberg + * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is + now handled by the checksum routine properly. + + 2006-02-27 Leon Woestenberg + * pbuf.c: Fix alignment; pbuf_init() would not work unless + pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) + + 2005-12-20 Leon Woestenberg + * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch + submitted by Mitrani Hiroshi. + + 2005-12-15 Christiaan Simons + * inet.c: Disabled the added summing routine to preserve code space. + + 2005-12-14 Leon Woestenberg + * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. + Added Curt McDowell's optimized checksumming routine for future + inclusion. Need to create test case for unaliged, aligned, odd, + even length combination of cases on various endianess machines. + + 2005-12-09 Christiaan Simons + * inet.c: Rewrote standard checksum routine in proper portable C. + + 2005-11-25 Christiaan Simons + * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. + * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, + u32_t, s32_t typedefs. This solves most debug word-length assumes. + + 2005-07-17 Leon Woestenberg + * inet.c: Fixed unaligned 16-bit access in the standard checksum + routine by Peter Jolasson. + * slipif.c: Fixed implementation assumption of single-pbuf datagrams. + + 2005-02-04 Leon Woestenberg + * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. + * tcp_{out|in}.c: Applied patch fixing unaligned access. + + 2005-01-04 Leon Woestenberg + * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. + + 2005-01-03 Leon Woestenberg + * udp.c: UDP pcb->recv() was called even when it was NULL. + +(STABLE-1_1_0) + + 2004-12-28 Leon Woestenberg + * etharp.*: Disabled multiple packets on the ARP queue. + This clashes with TCP queueing. + + 2004-11-28 Leon Woestenberg + * etharp.*: Fixed race condition from ARP request to ARP timeout. + Halved the ARP period, doubled the period counts. + ETHARP_MAX_PENDING now should be at least 2. This prevents + the counter from reaching 0 right away (which would allow + too little time for ARP responses to be received). + + 2004-11-25 Leon Woestenberg + * dhcp.c: Decline messages were not multicast but unicast. + * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. + Do not try hard to insert arbitrary packet's source address, + etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. + etharp_query() now always DOES call ETHARP_TRY_HARD so that users + querying an address will see it appear in the cache (DHCP could + suffer from this when a server invalidly gave an in-use address.) + * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are + comparing network addresses (identifiers), not the network masks + themselves. + * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given + IP address actually belongs to the network of the given interface. + + 2004-11-24 Kieran Mansley + * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. + +(STABLE-1_1_0-RC1) + + 2004-10-16 Kieran Mansley + * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, + even if one is already pending, if the rcv_wnd is above a threshold + (currently TCP_WND/2). This avoids waiting for a timer to expire to send a + delayed ACK in order to open the window if the stack is only receiving data. + + 2004-09-12 Kieran Mansley + * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. + + 2004-08-20 Tony Mountifield + * etharp.c: Make sure the first pbuf queued on an ARP entry + is properly ref counted. + + 2004-07-27 Tony Mountifield + * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler + warnings about comparison. + * pbuf.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. Closed an unclosed comment. + * tcp.c: Stopped compiler complaining of empty if statement + when LWIP_DEBUGF() empty. + * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). + * inet.c: Added a couple of casts to quiet the compiler. + No need to test isascii(c) before isdigit(c) or isxdigit(c). + + 2004-07-22 Tony Mountifield + * inet.c: Made data types consistent in inet_ntoa(). + Added casts for return values of checksum routines, to pacify compiler. + * ip_frag.c, tcp_out.c, sockets.c, pbuf.c + Small corrections to some debugging statements, to pacify compiler. + + 2004-07-21 Tony Mountifield + * etharp.c: Removed spurious semicolon and added missing end-of-comment. + * ethernetif.c Updated low_level_output() to match prototype for + netif->linkoutput and changed low_level_input() similarly for consistency. + * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype + of raw_recv() in raw.h and so avoid compiler error. + * sockets.c: Added trivial (int) cast to keep compiler happier. + * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. + +(STABLE-1_0_0) + + ++ Changes: + + 2004-07-05 Leon Woestenberg + * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure + your cc.h file defines this either 1 or 0. If non-defined, + defaults to 1. + * .c: Added and includes where used. + * etharp.c: Made some array indices unsigned. + + 2004-06-27 Leon Woestenberg + * netif.*: Added netif_set_up()/down(). + * dhcp.c: Changes to restart program flow. + + 2004-05-07 Leon Woestenberg + * etharp.c: In find_entry(), instead of a list traversal per candidate, do a + single-pass lookup for different candidates. Should exploit locality. + + 2004-04-29 Leon Woestenberg + * tcp*.c: Cleaned up source comment documentation for Doxygen processing. + * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. + * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by + the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. + + ++ Bug fixes: + + 2004-04-27 Leon Woestenberg + * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution + suggested by Timmy Brolin. Fix for 32-bit processors that cannot access + non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix + is to prefix the 14-bit Ethernet headers with two padding bytes. + + 2004-04-23 Leon Woestenberg + * ip_addr.c: Fix in the ip_addr_isbroadcast() check. + * etharp.c: Fixed the case where the packet that initiates the ARP request + is not queued, and gets lost. Fixed the case where the packets destination + address is already known; we now always queue the packet and perform an ARP + request. + +(STABLE-0_7_0) + + ++ Bug fixes: + + * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. + * Fixed TCP bug in dequeueing of FIN from out of order segment queue. + * Fixed two possible NULL references in rare cases. + +(STABLE-0_6_6) + + ++ Bug fixes: + + * Fixed DHCP which did not include the IP address in DECLINE messages. + + ++ Changes: + + * etharp.c has been hauled over a bit. + +(STABLE-0_6_5) + + ++ Bug fixes: + + * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. + * Packets sent from ARP queue had invalid source hardware address. + + ++ Changes: + + * Pass-by ARP requests do now update the cache. + + ++ New features: + + * No longer dependent on ctype.h. + * New socket options. + * Raw IP pcb support. + +(STABLE-0_6_4) + + ++ Bug fixes: + + * Some debug formatters and casts fixed. + * Numereous fixes in PPP. + + ++ Changes: + + * DEBUGF now is LWIP_DEBUGF + * pbuf_dechain() has been re-enabled. + * Mentioned the changed use of CVS branches in README. + +(STABLE-0_6_3) + + ++ Bug fixes: + + * Fixed pool pbuf memory leak in pbuf_alloc(). + Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. + Reported by Savin Zlobec. + + * PBUF_POOL chains had their tot_len field not set for non-first + pbufs. Fixed in pbuf_alloc(). + + ++ New features: + + * Added PPP stack contributed by Marc Boucher + + ++ Changes: + + * Now drops short packets for ICMP/UDP/TCP protocols. More robust. + + * ARP queueuing now queues the latest packet instead of the first. + This is the RFC recommended behaviour, but can be overridden in + lwipopts.h. + +(0.6.2) + + ++ Bugfixes: + + * TCP has been fixed to deal with the new use of the pbuf->ref + counter. + + * DHCP dhcp_inform() crash bug fixed. + + ++ Changes: + + * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed + pbuf_refresh(). This has sped up pbuf pool operations considerably. + Implemented by David Haas. + +(0.6.1) + + ++ New features: + + * The packet buffer implementation has been enhanced to support + zero-copy and copy-on-demand for packet buffers which have their + payloads in application-managed memory. + Implemented by David Haas. + + Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy + if an outgoing packet can be directly sent on the link, or perform + a copy-on-demand when necessary. + + The application can safely assume the packet is sent, and the RAM + is available to the application directly after calling udp_send() + or similar function. + + ++ Bugfixes: + + * ARP_QUEUEING should now correctly work for all cases, including + PBUF_REF. + Implemented by Leon Woestenberg. + + ++ Changes: + + * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer + to a '0.0.0.0' IP address. + + * The packet buffer implementation is changed. The pbuf->ref counter + meaning has changed, and several pbuf functions have been + adapted accordingly. + + * netif drivers have to be changed to set the hardware address length field + that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). + See the contrib/ports/c16x cs8900 driver as a driver example. + + * netif's have a dhcp field that must be initialized to NULL by the driver. + See the contrib/ports/c16x cs8900 driver as a driver example. + +(0.5.x) This file has been unmaintained up to 0.6.1. All changes are + logged in CVS but have not been explained here. + +(0.5.3) Changes since version 0.5.2 + + ++ Bugfixes: + + * memp_malloc(MEMP_API_MSG) could fail with multiple application + threads because it wasn't protected by semaphores. + + ++ Other changes: + + * struct ip_addr now packed. + + * The name of the time variable in arp.c has been changed to ctime + to avoid conflicts with the time() function. + +(0.5.2) Changes since version 0.5.1 + + ++ New features: + + * A new TCP function, tcp_tmr(), now handles both TCP timers. + + ++ Bugfixes: + + * A bug in tcp_parseopt() could cause the stack to hang because of a + malformed TCP option. + + * The address of new connections in the accept() function in the BSD + socket library was not handled correctly. + + * pbuf_dechain() did not update the ->tot_len field of the tail. + + * Aborted TCP connections were not handled correctly in all + situations. + + ++ Other changes: + + * All protocol header structs are now packed. + + * The ->len field in the tcp_seg structure now counts the actual + amount of data, and does not add one for SYN and FIN segments. + +(0.5.1) Changes since version 0.5.0 + + ++ New features: + + * Possible to run as a user process under Linux. + + * Preliminary support for cross platform packed structs. + + * ARP timer now implemented. + + ++ Bugfixes: + + * TCP output queue length was badly initialized when opening + connections. + + * TCP delayed ACKs were not sent correctly. + + * Explicit initialization of BSS segment variables. + + * read() in BSD socket library could drop data. + + * Problems with memory alignment. + + * Situations when all TCP buffers were used could lead to + starvation. + + * TCP MSS option wasn't parsed correctly. + + * Problems with UDP checksum calculation. + + * IP multicast address tests had endianess problems. + + * ARP requests had wrong destination hardware address. + + ++ Other changes: + + * struct eth_addr changed from u16_t[3] array to u8_t[6]. + + * A ->linkoutput() member was added to struct netif. + + * TCP and UDP ->dest_* struct members where changed to ->remote_*. + + * ntoh* macros are now null definitions for big endian CPUs. + +(0.5.0) Changes since version 0.4.2 + + ++ New features: + + * Redesigned operating system emulation layer to make porting easier. + + * Better control over TCP output buffers. + + * Documenation added. + + ++ Bugfixes: + + * Locking issues in buffer management. + + * Bugfixes in the sequential API. + + * IP forwarding could cause memory leakage. This has been fixed. + + ++ Other changes: + + * Directory structure somewhat changed; the core/ tree has been + collapsed. + +(0.4.2) Changes since version 0.4.1 + + ++ New features: + + * Experimental ARP implementation added. + + * Skeleton Ethernet driver added. + + * Experimental BSD socket API library added. + + ++ Bugfixes: + + * In very intense situations, memory leakage could occur. This has + been fixed. + + ++ Other changes: + + * Variables named "data" and "code" have been renamed in order to + avoid name conflicts in certain compilers. + + * Variable++ have in appliciable cases been translated to ++variable + since some compilers generate better code in the latter case. + +(0.4.1) Changes since version 0.4 + + ++ New features: + + * TCP: Connection attempts time out earlier than data + transmissions. Nagle algorithm implemented. Push flag set on the + last segment in a burst. + + * UDP: experimental support for UDP-Lite extensions. + + ++ Bugfixes: + + * TCP: out of order segments were in some cases handled incorrectly, + and this has now been fixed. Delayed acknowledgements was broken + in 0.4, has now been fixed. Binding to an address that is in use + now results in an error. Reset connections sometimes hung an + application; this has been fixed. + + * Checksum calculation sometimes failed for chained pbufs with odd + lengths. This has been fixed. + + * API: a lot of bug fixes in the API. The UDP API has been improved + and tested. Error reporting and handling has been + improved. Logical flaws and race conditions for incoming TCP + connections has been found and removed. + + * Memory manager: alignment issues. Reallocating memory sometimes + failed, this has been fixed. + + * Generic library: bcopy was flawed and has been fixed. + + ++ Other changes: + + * API: all datatypes has been changed from generic ones such as + ints, to specified ones such as u16_t. Functions that return + errors now have the correct type (err_t). + + * General: A lot of code cleaned up and debugging code removed. Many + portability issues have been fixed. + + * The license was changed; the advertising clause was removed. + + * C64 port added. + + * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri + Kosunen, Mikael Caleres, and Frits Wilmink for reporting and + fixing bugs! + +(0.4) Changes since version 0.3.1 + + * Memory management has been radically changed; instead of + allocating memory from a shared heap, memory for objects that are + rapidly allocated and deallocated is now kept in pools. Allocation + and deallocation from those memory pools is very fast. The shared + heap is still present but is used less frequently. + + * The memory, memory pool, and packet buffer subsystems now support + 4-, 2-, or 1-byte alignment. + + * "Out of memory" situations are handled in a more robust way. + + * Stack usage has been reduced. + + * Easier configuration of lwIP parameters such as memory usage, + TTLs, statistics gathering, etc. All configuration parameters are + now kept in a single header file "lwipopts.h". + + * The directory structure has been changed slightly so that all + architecture specific files are kept under the src/arch + hierarchy. + + * Error propagation has been improved, both in the protocol modules + and in the API. + + * The code for the RTXC architecture has been implemented, tested + and put to use. + + * Bugs have been found and corrected in the TCP, UDP, IP, API, and + the Internet checksum modules. + + * Bugs related to porting between a 32-bit and a 16-bit architecture + have been found and corrected. + + * The license has been changed slightly to conform more with the + original BSD license, including the advertisement clause. + +(0.3.1) Changes since version 0.3 + + * Fix of a fatal bug in the buffer management. Pbufs with allocated + RAM never returned the RAM when the pbuf was deallocated. + + * TCP congestion control, window updates and retransmissions did not + work correctly. This has now been fixed. + + * Bugfixes in the API. + +(0.3) Changes since version 0.2 + + * New and improved directory structure. All include files are now + kept in a dedicated include/ directory. + + * The API now has proper error handling. A new function, + netconn_err(), now returns an error code for the connection in + case of errors. + + * Improvements in the memory management subsystem. The system now + keeps a pointer to the lowest free memory block. A new function, + mem_malloc2() tries to allocate memory once, and if it fails tries + to free some memory and retry the allocation. + + * Much testing has been done with limited memory + configurations. lwIP now does a better job when overloaded. + + * Some bugfixes and improvements to the buffer (pbuf) subsystem. + + * Many bugfixes in the TCP code: + + - Fixed a bug in tcp_close(). + + - The TCP receive window was incorrectly closed when out of + sequence segments was received. This has been fixed. + + - Connections are now timed-out of the FIN-WAIT-2 state. + + - The initial congestion window could in some cases be too + large. This has been fixed. + + - The retransmission queue could in some cases be screwed up. This + has been fixed. + + - TCP RST flag now handled correctly. + + - Out of sequence data was in some cases never delivered to the + application. This has been fixed. + + - Retransmitted segments now contain the correct acknowledgment + number and advertised window. + + - TCP retransmission timeout backoffs are not correctly computed + (ala BSD). After a number of retransmissions, TCP now gives up + the connection. + + * TCP connections now are kept on three lists, one for active + connections, one for listening connections, and one for + connections that are in TIME-WAIT. This greatly speeds up the fast + timeout processing for sending delayed ACKs. + + * TCP now provides proper feedback to the application when a + connection has been successfully set up. + + * More comments have been added to the code. The code has also been + somewhat cleaned up. + +(0.2) Initial public release. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/COPYING b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/COPYING new file mode 100644 index 0000000..e23898b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/COPYING @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/FILES b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/FILES new file mode 100644 index 0000000..6625319 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/FILES @@ -0,0 +1,4 @@ +src/ - The source code for the lwIP TCP/IP stack. +doc/ - The documentation for lwIP. + +See also the FILES file in each subdirectory. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/README b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/README new file mode 100644 index 0000000..a62cc4f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/README @@ -0,0 +1,89 @@ +INTRODUCTION + +lwIP is a small independent implementation of the TCP/IP protocol +suite that has been developed by Adam Dunkels at the Computer and +Networks Architectures (CNA) lab at the Swedish Institute of Computer +Science (SICS). + +The focus of the lwIP TCP/IP implementation is to reduce the RAM usage +while still having a full scale TCP. This making lwIP suitable for use +in embedded systems with tens of kilobytes of free RAM and room for +around 40 kilobytes of code ROM. + +FEATURES + + * IP (Internet Protocol) including packet forwarding over multiple network + interfaces + * ICMP (Internet Control Message Protocol) for network maintenance and debugging + * IGMP (Internet Group Management Protocol) for multicast traffic management + * UDP (User Datagram Protocol) including experimental UDP-lite extensions + * TCP (Transmission Control Protocol) with congestion control, RTT estimation + and fast recovery/fast retransmit + * Specialized raw/native API for enhanced performance + * Optional Berkeley-like socket API + * DNS (Domain names resolver) + * SNMP (Simple Network Management Protocol) + * DHCP (Dynamic Host Configuration Protocol) + * AUTOIP (for IPv4, conform with RFC 3927) + * PPP (Point-to-Point Protocol) + * ARP (Address Resolution Protocol) for Ethernet + +LICENSE + +lwIP is freely available under a BSD license. + +DEVELOPMENT + +lwIP has grown into an excellent TCP/IP stack for embedded devices, +and developers using the stack often submit bug fixes, improvements, +and additions to the stack to further increase its usefulness. + +Development of lwIP is hosted on Savannah, a central point for +software development, maintenance and distribution. Everyone can +help improve lwIP by use of Savannah's interface, CVS and the +mailing list. A core team of developers will commit changes to the +CVS source tree. + +The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and +contributions (such as platform ports) are in the 'contrib' module. + +See doc/savannah.txt for details on CVS server access for users and +developers. + +Last night's CVS tar ball can be downloaded from: + http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING] + +The current CVS trees are web-browsable: + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/ + http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/ + +Submit patches and bugs via the lwIP project page: + http://savannah.nongnu.org/projects/lwip/ + + +DOCUMENTATION + +The original out-dated homepage of lwIP and Adam Dunkels' papers on +lwIP are at the official lwIP home page: + http://www.sics.se/~adam/lwip/ + +Self documentation of the source code is regularly extracted from the +current CVS sources and is available from this web page: + http://www.nongnu.org/lwip/ + +There is now a constantly growin wiki about lwIP at + http://lwip.wikia.com/wiki/LwIP_Wiki + +Also, there are mailing lists you can subscribe at + http://savannah.nongnu.org/mail/?group=lwip +plus searchable archives: + http://lists.nongnu.org/archive/html/lwip-users/ + http://lists.nongnu.org/archive/html/lwip-devel/ + +Reading Adam's papers, the files in docs/, browsing the source code +documentation and browsing the mailing list archives is a good way to +become familiar with the design of lwIP. + +Adam Dunkels +Leon Woestenberg + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/UPGRADING b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/UPGRADING new file mode 100644 index 0000000..6501107 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/UPGRADING @@ -0,0 +1,144 @@ +This file lists major changes between release versions that require +ports or applications to be changed. Use it to update a port or an +application written for an older version of lwIP to correctly work +with newer versions. + + +(CVS HEAD) + + * [Enter new changes just after this line - do not remove this line] + + ++ Application changes: + + * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for + compatibility to old applications, but will be removed in the future). + + * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() + + +++ Raw API: + * Changed the semantics of tcp_close() (since it was rather a + shutdown before): Now the application does *NOT* get any calls to the recv + callback (aside from NULL/closed) after calling tcp_close() + + * When calling tcp_abort() from a raw API TCP callback function, + make sure you return ERR_ABRT to prevent accessing unallocated memory. + (ERR_ABRT now means the applicaiton has called tcp_abort!) + + +++ Netconn API: + * Changed netconn_receive() and netconn_accept() to return + err_t, not a pointer to new data/netconn. + + +++ Socket API: + * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they + now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. + + * Added a minimal version of posix fctl() to have a + standardised way to set O_NONBLOCK for nonblocking sockets. + + +++ all APIs: + * correctly implemented SO(F)_REUSEADDR + + ++ Port changes + + +++ new files: + + * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: + + * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains + the actual application programmer's API + + * Separated timer implementation from sys.h/.c, moved to timers.h/.c; + Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you + still want to use your own timer implementation for NO_SYS==0 (as before). + + +++ sys layer: + + * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ + sys_sem_t; + + * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; + + * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use + binary semaphores instead of mutexes - as before) + + +++ new options: + + * Don't waste memory when chaining segments, added option TCP_OVERSIZE to + prevent creating many small pbufs when calling tcp_write with many small + blocks of data. Instead, pbufs are allocated larger than needed and the + space is used for later calls to tcp_write. + + * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs + in tcp_write/udp_send. + + * Added an additional option LWIP_ETHERNET to support ethernet without ARP + (necessary for pure PPPoE) + + * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may + be used to place these pools into user-defined memory by using external + declaration. + + * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT + + +++ new pools: + + * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, + so MEMP_NUM_NETDB has to be set accordingly. + + * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so + MEMP_NUM_LOCALHOSTLIST has to be set accordingly. + + * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have + to be set accordingly. + + * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES + has to be set accordingly + + * Integrated loopif into netif.c - loopif does not have to be created by the + port any more, just define LWIP_HAVE_LOOPIF to 1. + + * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined + in cc.h, e.g. used by igmp) + + * Added printf-formatter X8_F to printf u8_t as hex + + * The heap now may be moved to user-defined memory by defining + LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address + + * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work + with user-allocated structs instead of calling mem_malloc + + * Added const char* name to mem- and memp-stats for easier debugging. + + * Calculate the TCP/UDP checksum while copying to only fetch data once: + Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum + + * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to + more than one pcb. + + * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned + off any more, if this is set to 0, only one packet (the most recent one) is + queued (like demanded by RFC 1122). + + + ++ Major bugfixes/improvements + + * Implemented tcp_shutdown() to only shut down one end of a connection + * Implemented shutdown() at socket- and netconn-level + * Added errorset support to select() + improved select speed overhead + * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) + * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 + * Use macros defined in ip_addr.h to work with IP addresses + * Implemented many nonblocking socket/netconn functions + * Fixed ARP input processing: only add a new entry if a request was directed as us + * mem_realloc() to mem_trim() to prevent confusion with realloc() + * Some improvements for AutoIP (don't route/forward link-local addresses, don't break + existing connections when assigning a routable address) + * Correctly handle remote side overrunning our rcv_wnd in ooseq case + * Removed packing from ip_addr_t, the packed version is now only used in protocol headers + * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 + * Added support for static ARP table entries + +(STABLE-1.3.2) + + * initial version of this file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/FILES b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/FILES new file mode 100644 index 0000000..05d356f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/FILES @@ -0,0 +1,6 @@ +savannah.txt - How to obtain the current development source code. +contrib.txt - How to contribute to lwIP as a developer. +rawapi.txt - The documentation for the core API of lwIP. + Also provides an overview about the other APIs and multithreading. +snmp_agent.txt - The documentation for the lwIP SNMP agent. +sys_arch.txt - The documentation for a system abstraction layer of lwIP. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/contrib.txt b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/contrib.txt new file mode 100644 index 0000000..b986020 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/contrib.txt @@ -0,0 +1,59 @@ +1 Introduction + +This document describes some guidelines for people participating +in lwIP development. + +2 How to contribute to lwIP + +Here is a short list of suggestions to anybody working with lwIP and +trying to contribute bug reports, fixes, enhancements, platform ports etc. +First of all as you may already know lwIP is a volunteer project so feedback +to fixes or questions might often come late. Hopefully the bug and patch tracking +features of Savannah help us not lose users' input. + +2.1 Source code style: + +1. do not use tabs. +2. indentation is two spaces per level (i.e. per tab). +3. end debug messages with a trailing newline (\n). +4. one space between keyword and opening bracket. +5. no space between function and opening bracket. +6. one space and no newline before opening curly braces of a block. +7. closing curly brace on a single line. +8. spaces surrounding assignment and comparisons. +9. don't initialize static and/or global variables to zero, the compiler takes care of that. +10. use current source code style as further reference. + +2.2 Source code documentation style: + +1. JavaDoc compliant and Doxygen compatible. +2. Function documentation above functions in .c files, not .h files. + (This forces you to synchronize documentation and implementation.) +3. Use current documentation style as further reference. + +2.3 Bug reports and patches: + +1. Make sure you are reporting bugs or send patches against the latest + sources. (From the latest release and/or the current CVS sources.) +2. If you think you found a bug make sure it's not already filed in the + bugtracker at Savannah. +3. If you have a fix put the patch on Savannah. If it is a patch that affects + both core and arch specific stuff please separate them so that the core can + be applied separately while leaving the other patch 'open'. The prefered way + is to NOT touch archs you can't test and let maintainers take care of them. + This is a good way to see if they are used at all - the same goes for unix + netifs except tapif. +4. Do not file a bug and post a fix to it to the patch area. Either a bug report + or a patch will be enough. + If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. +5. Patches should be specific to a single change or to related changes.Do not mix bugfixes with spelling and other + trivial fixes unless the bugfix is trivial too.Do not reorganize code and rename identifiers in the same patch you + change behaviour if not necessary.A patch is easier to read and understand if it's to the point and short than + if it's not to the point and long :) so the chances for it to be applied are greater. + +2.4 Platform porters: + +1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and + you think it could benefit others[1] you might want discuss this on the mailing list. You + can also ask for CVS access to submit and maintain your port in the contrib CVS module. + \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/rawapi.txt b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/rawapi.txt new file mode 100644 index 0000000..8c19030 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/rawapi.txt @@ -0,0 +1,511 @@ +Raw TCP/IP interface for lwIP + +Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons + +lwIP provides three Application Program's Interfaces (APIs) for programs +to use for communication with the TCP/IP code: +* low-level "core" / "callback" or "raw" API. +* higher-level "sequential" API. +* BSD-style socket API. + +The sequential API provides a way for ordinary, sequential, programs +to use the lwIP stack. It is quite similar to the BSD socket API. The +model of execution is based on the blocking open-read-write-close +paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP +code and the application program must reside in different execution +contexts (threads). + +The socket API is a compatibility API for existing applications, +currently it is built on top of the sequential API. It is meant to +provide all functions needed to run socket API applications running +on other platforms (e.g. unix / windows etc.). However, due to limitations +in the specification of this API, there might be incompatibilities +that require small modifications of existing programs. + +** Threading + +lwIP started targeting single-threaded environments. When adding multi- +threading support, instead of making the core thread-safe, another +approach was chosen: there is one main thread running the lwIP core +(also known as the "tcpip_thread"). The raw API may only be used from +this thread! Application threads using the sequential- or socket API +communicate with this main thread through message passing. + + As such, the list of functions that may be called from + other threads or an ISR is very limited! Only functions + from these API header files are thread-safe: + - api.h + - netbuf.h + - netdb.h + - netifapi.h + - sockets.h + - sys.h + + Additionaly, memory (de-)allocation functions may be + called from multiple threads (not ISR!) with NO_SYS=0 + since they are protected by SYS_LIGHTWEIGHT_PROT and/or + semaphores. + + Only since 1.3.0, if SYS_LIGHTWEIGHT_PROT is set to 1 + and LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, + pbuf_free() may also be called from another thread or + an ISR (since only then, mem_free - for PBUF_RAM - may + be called from an ISR: otherwise, the HEAP is only + protected by semaphores). + + +** The remainder of this document discusses the "raw" API. ** + +The raw TCP/IP interface allows the application program to integrate +better with the TCP/IP code. Program execution is event based by +having callback functions being called from within the TCP/IP +code. The TCP/IP code and the application program both run in the same +thread. The sequential API has a much higher overhead and is not very +well suited for small systems since it forces a multithreaded paradigm +on the application. + +The raw TCP/IP interface is not only faster in terms of code execution +time but is also less memory intensive. The drawback is that program +development is somewhat harder and application programs written for +the raw TCP/IP interface are more difficult to understand. Still, this +is the preferred way of writing applications that should be small in +code size and memory usage. + +Both APIs can be used simultaneously by different application +programs. In fact, the sequential API is implemented as an application +program using the raw TCP/IP interface. + +--- Callbacks + +Program execution is driven by callbacks. Each callback is an ordinary +C function that is called from within the TCP/IP code. Every callback +function is passed the current TCP or UDP connection state as an +argument. Also, in order to be able to keep program specific state, +the callback functions are called with a program specified argument +that is independent of the TCP/IP state. + +The function for setting the application connection state is: + +- void tcp_arg(struct tcp_pcb *pcb, void *arg) + + Specifies the program specific state that should be passed to all + other callback functions. The "pcb" argument is the current TCP + connection control block, and the "arg" argument is the argument + that will be passed to the callbacks. + + +--- TCP connection setup + +The functions used for setting up connections is similar to that of +the sequential API and of the BSD socket API. A new TCP connection +identifier (i.e., a protocol control block - PCB) is created with the +tcp_new() function. This PCB can then be either set to listen for new +incoming connections or be explicitly connected to another host. + +- struct tcp_pcb *tcp_new(void) + + Creates a new connection identifier (PCB). If memory is not + available for creating the new pcb, NULL is returned. + +- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local IP address and port number. The IP address + can be specified as IP_ADDR_ANY in order to bind the connection to + all local IP addresses. + + If another connection is bound to the same port, the function will + return ERR_USE, otherwise ERR_OK is returned. + +- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) + + Commands a pcb to start listening for incoming connections. When an + incoming connection is accepted, the function specified with the + tcp_accept() function will be called. The pcb will have to be bound + to a local port with the tcp_bind() function. + + The tcp_listen() function returns a new connection identifier, and + the one passed as an argument to the function will be + deallocated. The reason for this behavior is that less memory is + needed for a connection that is listening, so tcp_listen() will + reclaim the memory needed for the original connection and allocate a + new smaller memory block for the listening connection. + + tcp_listen() may return NULL if no memory was available for the + listening connection. If so, the memory associated with the pcb + passed as an argument to tcp_listen() will not be deallocated. + +- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) + + Same as tcp_listen, but limits the number of outstanding connections + in the listen queue to the value specified by the backlog argument. + To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. + +- void tcp_accepted(struct tcp_pcb *pcb) + + Inform lwIP that an incoming connection has been accepted. This would + usually be called from the accept callback. This allows lwIP to perform + housekeeping tasks, such as allowing further incoming connections to be + queued in the listen backlog. + ATTENTION: the PCB passed in must be the listening pcb, not the pcb passed + into the accept callback! + +- void tcp_accept(struct tcp_pcb *pcb, + err_t (* accept)(void *arg, struct tcp_pcb *newpcb, + err_t err)) + + Specified the callback function that should be called when a new + connection arrives on a listening connection. + +- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, err_t (* connected)(void *arg, + struct tcp_pcb *tpcb, + err_t err)); + + Sets up the pcb to connect to the remote host and sends the + initial SYN segment which opens the connection. + + The tcp_connect() function returns immediately; it does not wait for + the connection to be properly setup. Instead, it will call the + function specified as the fourth argument (the "connected" argument) + when the connection is established. If the connection could not be + properly established, either because the other host refused the + connection or because the other host didn't answer, the "err" + callback function of this pcb (registered with tcp_err, see below) + will be called. + + The tcp_connect() function can return ERR_MEM if no memory is + available for enqueueing the SYN segment. If the SYN indeed was + enqueued successfully, the tcp_connect() function returns ERR_OK. + + +--- Sending TCP data + +TCP data is sent by enqueueing the data with a call to +tcp_write(). When the data is successfully transmitted to the remote +host, the application will be notified with a call to a specified +callback function. + +- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags) + + Enqueues the data pointed to by the argument dataptr. The length of + the data is passed as the len parameter. The apiflags can be one or more of: + - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated + for the data to be copied into. If this flag is not given, no new memory + should be allocated and the data should only be referenced by pointer. This + also means that the memory behind dataptr must not change until the data is + ACKed by the remote host + - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is given, + the PSH flag is set in the last segment created by this call to tcp_write. + If this flag is given, the PSH flag is not set. + + The tcp_write() function will fail and return ERR_MEM if the length + of the data exceeds the current send buffer size or if the length of + the queue of outgoing segment is larger than the upper limit defined + in lwipopts.h. The number of bytes available in the output queue can + be retrieved with the tcp_sndbuf() function. + + The proper way to use this function is to call the function with at + most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, + the application should wait until some of the currently enqueued + data has been successfully received by the other host and try again. + +- void tcp_sent(struct tcp_pcb *pcb, + err_t (* sent)(void *arg, struct tcp_pcb *tpcb, + u16_t len)) + + Specifies the callback function that should be called when data has + successfully been received (i.e., acknowledged) by the remote + host. The len argument passed to the callback function gives the + amount bytes that was acknowledged by the last acknowledgment. + + +--- Receiving TCP data + +TCP data reception is callback based - an application specified +callback function is called when new data arrives. When the +application has taken the data, it has to call the tcp_recved() +function to indicate that TCP can advertise increase the receive +window. + +- void tcp_recv(struct tcp_pcb *pcb, + err_t (* recv)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err)) + + Sets the callback function that will be called when new data + arrives. The callback function will be passed a NULL pbuf to + indicate that the remote host has closed the connection. If + there are no errors and the callback function is to return + ERR_OK, then it must free the pbuf. Otherwise, it must not + free the pbuf so that lwIP core code can store it. + +- void tcp_recved(struct tcp_pcb *pcb, u16_t len) + + Must be called when the application has received the data. The len + argument indicates the length of the received data. + + +--- Application polling + +When a connection is idle (i.e., no data is either transmitted or +received), lwIP will repeatedly poll the application by calling a +specified callback function. This can be used either as a watchdog +timer for killing connections that have stayed idle for too long, or +as a method of waiting for memory to become available. For instance, +if a call to tcp_write() has failed because memory wasn't available, +the application may use the polling functionality to call tcp_write() +again when the connection has been idle for a while. + +- void tcp_poll(struct tcp_pcb *pcb, + err_t (* poll)(void *arg, struct tcp_pcb *tpcb), + u8_t interval) + + Specifies the polling interval and the callback function that should + be called to poll the application. The interval is specified in + number of TCP coarse grained timer shots, which typically occurs + twice a second. An interval of 10 means that the application would + be polled every 5 seconds. + + +--- Closing and aborting connections + +- err_t tcp_close(struct tcp_pcb *pcb) + + Closes the connection. The function may return ERR_MEM if no memory + was available for closing the connection. If so, the application + should wait and try again either by using the acknowledgment + callback or the polling functionality. If the close succeeds, the + function returns ERR_OK. + + The pcb is deallocated by the TCP code after a call to tcp_close(). + +- void tcp_abort(struct tcp_pcb *pcb) + + Aborts the connection by sending a RST (reset) segment to the remote + host. The pcb is deallocated. This function never fails. + + ATTENTION: When calling this from one of the TCP callbacks, make + sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + or you will risk accessing deallocated memory or memory leaks! + + +If a connection is aborted because of an error, the application is +alerted of this event by the err callback. Errors that might abort a +connection are when there is a shortage of memory. The callback +function to be called is set using the tcp_err() function. + +- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, + err_t err)) + + The error callback function does not get the pcb passed to it as a + parameter since the pcb may already have been deallocated. + + +--- Lower layer TCP interface + +TCP provides a simple interface to the lower layers of the +system. During system initialization, the function tcp_init() has +to be called before any other TCP function is called. When the system +is running, the two timer functions tcp_fasttmr() and tcp_slowtmr() +must be called with regular intervals. The tcp_fasttmr() should be +called every TCP_FAST_INTERVAL milliseconds (defined in tcp.h) and +tcp_slowtmr() should be called every TCP_SLOW_INTERVAL milliseconds. + + +--- UDP interface + +The UDP interface is similar to that of TCP, but due to the lower +level of complexity of UDP, the interface is significantly simpler. + +- struct udp_pcb *udp_new(void) + + Creates a new UDP pcb which can be used for UDP communication. The + pcb is not active until it has either been bound to a local address + or connected to a remote address. + +- void udp_remove(struct udp_pcb *pcb) + + Removes and deallocates the pcb. + +- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Binds the pcb to a local address. The IP-address argument "ipaddr" + can be IP_ADDR_ANY to indicate that it should listen to any local IP + address. The function currently always return ERR_OK. + +- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port) + + Sets the remote end of the pcb. This function does not generate any + network traffic, but only set the remote address of the pcb. + +- err_t udp_disconnect(struct udp_pcb *pcb) + + Remove the remote end of the pcb. This function does not generate + any network traffic, but only removes the remote address of the pcb. + +- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) + + Sends the pbuf p. The pbuf is not deallocated. + +- void udp_recv(struct udp_pcb *pcb, + void (* recv)(void *arg, struct udp_pcb *upcb, + struct pbuf *p, + ip_addr_t *addr, + u16_t port), + void *recv_arg) + + Specifies a callback function that should be called when a UDP + datagram is received. + + +--- System initalization + +A truly complete and generic sequence for initializing the lwip stack +cannot be given because it depends on the build configuration (lwipopts.h) +and additional initializations for your runtime environment (e.g. timers). + +We can give you some idea on how to proceed when using the raw API. +We assume a configuration using a single Ethernet netif and the +UDP and TCP transport layers, IPv4 and the DHCP client. + +Call these functions in the order of appearance: + +- stats_init() + + Clears the structure where runtime statistics are gathered. + +- sys_init() + + Not of much use since we set the NO_SYS 1 option in lwipopts.h, + to be called for easy configuration changes. + +- mem_init() + + Initializes the dynamic memory heap defined by MEM_SIZE. + +- memp_init() + + Initializes the memory pools defined by MEMP_NUM_x. + +- pbuf_init() + + Initializes the pbuf memory pool defined by PBUF_POOL_SIZE. + +- etharp_init() + + Initializes the ARP table and queue. + Note: you must call etharp_tmr at a ARP_TMR_INTERVAL (5 seconds) regular interval + after this initialization. + +- ip_init() + + Doesn't do much, it should be called to handle future changes. + +- udp_init() + + Clears the UDP PCB list. + +- tcp_init() + + Clears the TCP PCB list and clears some internal TCP timers. + Note: you must call tcp_fasttmr() and tcp_slowtmr() at the + predefined regular intervals after this initialization. + +- netif_add(struct netif *netif, ip_addr_t *ipaddr, + ip_addr_t *netmask, ip_addr_t *gw, + void *state, err_t (* init)(struct netif *netif), + err_t (* input)(struct pbuf *p, struct netif *netif)) + + Adds your network interface to the netif_list. Allocate a struct + netif and pass a pointer to this structure as the first argument. + Give pointers to cleared ip_addr structures when using DHCP, + or fill them with sane numbers otherwise. The state pointer may be NULL. + + The init function pointer must point to a initialization function for + your ethernet netif interface. The following code illustrates it's use. + + err_t netif_if_init(struct netif *netif) + { + u8_t i; + + for(i = 0; i < ETHARP_HWADDR_LEN; i++) netif->hwaddr[i] = some_eth_addr[i]; + init_my_eth_device(); + return ERR_OK; + } + + For ethernet drivers, the input function pointer must point to the lwip + function ethernet_input() declared in "netif/etharp.h". Other drivers + must use ip_input() declared in "lwip/ip.h". + +- netif_set_default(struct netif *netif) + + Registers the default network interface. + +- netif_set_up(struct netif *netif) + + When the netif is fully configured this function must be called. + +- dhcp_start(struct netif *netif) + + Creates a new DHCP client for this interface on the first call. + Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at + the predefined regular intervals after starting the client. + + You can peek in the netif->dhcp struct for the actual DHCP status. + + +--- Optimalization hints + +The first thing you want to optimize is the lwip_standard_checksum() +routine from src/core/inet.c. You can override this standard +function with the #define LWIP_CHKSUM . + +There are C examples given in inet.c or you might want to +craft an assembly function for this. RFC1071 is a good +introduction to this subject. + +Other significant improvements can be made by supplying +assembly or inline replacements for htons() and htonl() +if you're using a little-endian architecture. +#define LWIP_PLATFORM_BYTESWAP 1 +#define LWIP_PLATFORM_HTONS(x) +#define LWIP_PLATFORM_HTONL(x) + +Check your network interface driver if it reads at +a higher speed than the maximum wire-speed. If the +hardware isn't serviced frequently and fast enough +buffer overflows are likely to occur. + +E.g. when using the cs8900 driver, call cs8900if_service(ethif) +as frequently as possible. When using an RTOS let the cs8900 interrupt +wake a high priority task that services your driver using a binary +semaphore or event flag. Some drivers might allow additional tuning +to match your application and network. + +For a production release it is recommended to set LWIP_STATS to 0. +Note that speed performance isn't influenced much by simply setting +high values to the memory options. + +For more optimization hints take a look at the lwIP wiki. + +--- Zero-copy MACs + +To achieve zero-copy on transmit, the data passed to the raw API must +remain unchanged until sent. Because the send- (or write-)functions return +when the packets have been enqueued for sending, data must be kept stable +after that, too. + +This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions +must *not* be reused by the application unless their ref-count is 1. + +For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too, +but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while +PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change). + +Also, data passed to tcp_write without the copy-flag must not be changed! + +Therefore, be careful which type of PBUF you use and if you copy TCP data +or not! diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/savannah.txt b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/savannah.txt new file mode 100644 index 0000000..409905b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/savannah.txt @@ -0,0 +1,135 @@ +Daily Use Guide for using Savannah for lwIP + +Table of Contents: + +1 - Obtaining lwIP from the CVS repository +2 - Committers/developers CVS access using SSH (to be written) +3 - Merging from DEVEL branch to main trunk (stable branch) +4 - How to release lwIP + + + +1 Obtaining lwIP from the CVS repository +---------------------------------------- + +To perform an anonymous CVS checkout of the main trunk (this is where +bug fixes and incremental enhancements occur), do this: + +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout lwip + +Or, obtain a stable branch (updated with bug fixes only) as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7 -d lwip-0.7 lwip + +Or, obtain a specific (fixed) release as follows: +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_7_0 -d lwip-0.7.0 lwip + +3 Committers/developers CVS access using SSH +-------------------------------------------- + +The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. +As such, CVS commits to the server occur through a SSH tunnel for project members. +To create a SSH2 key pair in UNIX-like environments, do this: + +ssh-keygen -t dsa + +Under Windows, a recommended SSH client is "PuTTY", freely available with good +documentation and a graphic user interface. Use its key generator. + +Now paste the id_dsa.pub contents into your Savannah account public key list. Wait +a while so that Savannah can update its configuration (This can take minutes). + +Try to login using SSH: + +ssh -v your_login@cvs.sv.gnu.org + +If it tells you: + +Authenticating with public key "your_key_name"... +Server refused to allocate pty + +then you could login; Savannah refuses to give you a shell - which is OK, as we +are allowed to use SSH for CVS only. Now, you should be able to do this: + +export CVS_RSH=ssh +cvs -z3 -d:ext:your_login@cvs.sv.gnu.org:/sources/lwip co lwip + +after which you can edit your local files with bug fixes or new features and +commit them. Make sure you know what you are doing when using CVS to make +changes on the repository. If in doubt, ask on the lwip-members mailing list. + +(If SSH asks about authenticity of the host, you can check the key + fingerprint against http://savannah.nongnu.org/cvs/?group=lwip) + + +3 Merging from DEVEL branch to main trunk (stable) +-------------------------------------------------- + +Merging is a delicate process in CVS and requires the +following disciplined steps in order to prevent conflicts +in the future. Conflicts can be hard to solve! + +Merging from branch A to branch B requires that the A branch +has a tag indicating the previous merger. This tag is called +'merged_from_A_to_B'. After merging, the tag is moved in the +A branch to remember this merger for future merge actions. + +IMPORTANT: AFTER COMMITTING A SUCCESFUL MERGE IN THE +REPOSITORY, THE TAG MUST BE SET ON THE SOURCE BRANCH OF THE +MERGE ACTION (REPLACING EXISTING TAGS WITH THE SAME NAME). + +Merge all changes in DEVEL since our last merge to main: + +In the working copy of the main trunk: +cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL + +(This will apply the changes between 'merged_from_DEVEL_to_main' +and 'DEVEL' to your work set of files) + +We can now commit the merge result. +cvs commit -R -m "Merged from DEVEL to main." + +If this worked out OK, we now move the tag in the DEVEL branch +to this merge point, so we can use this point for future merges: + +cvs rtag -F -r DEVEL merged_from_DEVEL_to_main lwip + +4 How to release lwIP +--------------------- + +First, checkout a clean copy of the branch to be released. Tag this set with +tag name "STABLE-0_6_3". (I use release number 0.6.3 throughout this example). + +Login CVS using pserver authentication, then export a clean copy of the +tagged tree. Export is similar to a checkout, except that the CVS metadata +is not created locally. + +export CVS_RSH=ssh +cvs -z3 -d:pserver:anonymous@cvs.sv.gnu.org:/sources/lwip checkout \ + -r STABLE-0_6_3 -d lwip-0.6.3 lwip + +Archive this directory using tar, gzip'd, bzip2'd and zip'd. + +tar czvf lwip-0.6.3.tar.gz lwip-0.6.3 +tar cjvf lwip-0.6.3.tar.bz2 lwip-0.6.3 +zip -r lwip-0.6.3.zip lwip-0.6.3 + +Now, sign the archives with a detached GPG binary signature as follows: + +gpg -b lwip-0.6.3.tar.gz +gpg -b lwip-0.6.3.tar.bz2 +gpg -b lwip-0.6.3.zip + +Upload these files using anonymous FTP: +ncftp ftp://savannah.gnu.org/incoming/savannah/lwip + +ncftp>mput *0.6.3.* + +Additionally, you may post a news item on Savannah, like this: + +A new 0.6.3 release is now available here: +http://savannah.nongnu.org/files/?group=lwip&highlight=0.6.3 + +You will have to submit this via the user News interface, then approve +this via the Administrator News interface. \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/snmp_agent.txt b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/snmp_agent.txt new file mode 100644 index 0000000..2653230 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/snmp_agent.txt @@ -0,0 +1,181 @@ +SNMPv1 agent for lwIP + +Author: Christiaan Simons + +This is a brief introduction how to use and configure the SNMP agent. +Note the agent uses the raw-API UDP interface so you may also want to +read rawapi.txt to gain a better understanding of the SNMP message handling. + +0 Agent Capabilities +==================== + +SNMPv1 per RFC1157 + This is an old(er) standard but is still widely supported. + For SNMPv2c and v3 have a greater complexity and need many + more lines of code. IMHO this breaks the idea of "lightweight IP". + + Note the S in SNMP stands for "Simple". Note that "Simple" is + relative. SNMP is simple compared to the complex ISO network + management protocols CMIP (Common Management Information Protocol) + and CMOT (CMip Over Tcp). + +MIB II per RFC1213 + The standard lwIP stack management information base. + This is a required MIB, so this is always enabled. + When builing lwIP without TCP, the mib-2.tcp group is omitted. + The groups EGP, CMOT and transmission are disabled by default. + + Most mib-2 objects are not writable except: + sysName, sysLocation, sysContact, snmpEnableAuthenTraps. + Writing to or changing the ARP and IP address and route + tables is not possible. + + Note lwIP has a very limited notion of IP routing. It currently + doen't have a route table and doesn't have a notion of the U,G,H flags. + Instead lwIP uses the interface list with only one default interface + acting as a single gateway interface (G) for the default route. + + The agent returns a "virtual table" with the default route 0.0.0.0 + for the default interface and network routes (no H) for each + network interface in the netif_list. + All routes are considered to be up (U). + +Loading additional MIBs + MIBs can only be added in compile-time, not in run-time. + There is no MIB compiler thus additional MIBs must be hand coded. + +Large SNMP message support + The packet decoding and encoding routines are designed + to use pbuf-chains. Larger payloads than the minimum + SNMP requirement of 484 octets are supported if the + PBUF_POOL_SIZE and IP_REASS_BUFSIZE are set to match your + local requirement. + +1 Building the Agent +==================== + +First of all you'll need to add the following define +to your local lwipopts.h: + +#define LWIP_SNMP 1 + +and add the source files in lwip/src/core/snmp +and some snmp headers in lwip/src/include/lwip to your makefile. + +Note you'll might need to adapt you network driver to update +the mib2 variables for your interface. + +2 Running the Agent +=================== + +The following function calls must be made in your program to +actually get the SNMP agent running. + +Before starting the agent you should supply pointers +to non-volatile memory for sysContact, sysLocation, +and snmpEnableAuthenTraps. You can do this by calling + +snmp_set_syscontact() +snmp_set_syslocation() +snmp_set_snmpenableauthentraps() + +Additionally you may want to set + +snmp_set_sysdescr() +snmp_set_sysobjid() (if you have a private MIB) +snmp_set_sysname() + +Also before starting the agent you need to setup +one or more trap destinations using these calls: + +snmp_trap_dst_enable(); +snmp_trap_dst_ip_set(); + +In the lwIP initialisation sequence call snmp_init() just after +the call to udp_init(). + +Exactly every 10 msec the SNMP uptime timestamp must be updated with +snmp_inc_sysuptime(). You should call this from a timer interrupt +or a timer signal handler depending on your runtime environment. + +An alternative way to update the SNMP uptime timestamp is to do a call like +snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but call to +a lower frequency). Another one is to not call snmp_inc_sysuptime() or +snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. +This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside +snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only +when it's queried (any function which need "sysuptime" have to call +snmp_get_sysuptime). + + +3 Private MIBs +============== + +If want to extend the agent with your own private MIB you'll need to +add the following define to your local lwipopts.h: + +#define SNMP_PRIVATE_MIB 1 + +You must provide the private_mib.h and associated files yourself. +Note we don't have a "MIB compiler" that generates C source from a MIB, +so you're required to do some serious coding if you enable this! + +Note the lwIP enterprise ID (26381) is assigned to the lwIP project, +ALL OBJECT IDENTIFIERS LIVING UNDER THIS ID ARE ASSIGNED BY THE lwIP +MAINTAINERS! + +If you need to create your own private MIB you'll need +to apply for your own enterprise ID with IANA: http://www.iana.org/numbers.html + +You can set it by passing a struct snmp_obj_id to the agent +using snmp_set_sysobjid(&my_object_id), just before snmp_init(). + +Note the object identifiers for thes MIB-2 and your private MIB +tree must be kept in sorted ascending (lexicographical) order. +This to ensure correct getnext operation. + +An example for a private MIB is part of the "minimal Unix" project: +contrib/ports/unix/proj/minimal/lwip_prvmib.c + +The next chapter gives a more detailed description of the +MIB-2 tree and the optional private MIB. + +4 The Gory Details +================== + +4.0 Object identifiers and the MIB tree. + +We have three distinct parts for all object identifiers: + +The prefix + .iso.org.dod.internet + +the middle part + .mgmt.mib-2.ip.ipNetToMediaTable.ipNetToMediaEntry.ipNetToMediaPhysAddress + +and the index part + .1.192.168.0.1 + +Objects located above the .internet hierarchy aren't supported. +Currently only the .mgmt sub-tree is available and +when the SNMP_PRIVATE_MIB is enabled the .private tree +becomes available too. + +Object identifiers from incoming requests are checked +for a matching prefix, middle part and index part +or are expanded(*) for GetNext requests with short +or inexisting names in the request. +(* we call this "expansion" but this also +resembles the "auto-completion" operation) + +The middle part is usually located in ROM (const) +to preserve precious RAM on small microcontrollers. +However RAM location is possible for a dynamically +changing private tree. + +The index part is handled by functions which in +turn use dynamically allocated index trees from RAM. +These trees are updated by e.g. the etharp code +when new entries are made or removed form the ARP cache. + +/** @todo more gory details */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/sys_arch.txt b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/sys_arch.txt new file mode 100644 index 0000000..847cd77 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/doc/sys_arch.txt @@ -0,0 +1,267 @@ +sys_arch interface for lwIP 0.6++ + +Author: Adam Dunkels + +The operating system emulation layer provides a common interface +between the lwIP code and the underlying operating system kernel. The +general idea is that porting lwIP to new architectures requires only +small changes to a few header files and a new sys_arch +implementation. It is also possible to do a sys_arch implementation +that does not rely on any underlying operating system. + +The sys_arch provides semaphores and mailboxes to lwIP. For the full +lwIP functionality, multiple threads support can be implemented in the +sys_arch, but this is not required for the basic lwIP +functionality. Previous versions of lwIP required the sys_arch to +implement timer scheduling as well but as of lwIP 0.5 this is +implemented in a higher layer. + +In addition to the source file providing the functionality of sys_arch, +the OS emulation layer must provide several header files defining +macros used throughout lwip. The files required and the macros they +must define are listed below the sys_arch description. + +Semaphores can be either counting or binary - lwIP works with both +kinds. Mailboxes are used for message passing and can be implemented +either as a queue which allows multiple messages to be posted to a +mailbox, or as a rendez-vous point where only one message can be +posted at a time. lwIP works with both kinds, but the former type will +be more efficient. A message in a mailbox is just a pointer, nothing +more. + +Semaphores are represented by the type "sys_sem_t" which is typedef'd +in the sys_arch.h file. Mailboxes are equivalently represented by the +type "sys_mbox_t". lwIP does not place any restrictions on how +sys_sem_t or sys_mbox_t are represented internally. + +Since lwIP 1.4.0, semaphore and mailbox functions are prototyped in a way that +allows both using pointers or actual OS structures to be used. This way, memory +required for such types can be either allocated in place (globally or on the +stack) or on the heap (allocated internally in the "*_new()" functions). + +The following functions must be implemented by the sys_arch: + +- void sys_init(void) + + Is called to initialize the sys_arch layer. + +- err_t sys_sem_new(sys_sem_t *sem, u8_t count) + + Creates a new semaphore. The semaphore is allocated to the memory that 'sem' + points to (which can be both a pointer or the actual OS structure). + The "count" argument specifies the initial state of the semaphore (which is + either 0 or 1). + If the semaphore has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_sem_free(sys_sem_t *sem) + + Deallocates a semaphore. + +- void sys_sem_signal(sys_sem_t *sem) + + Signals a semaphore. + +- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) + + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). If the "timeout" argument is zero, the thread should be + blocked until the semaphore is signalled. + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. + +- int sys_sem_valid(sys_sem_t *sem) + + Returns 1 if the semaphore is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_sem_set_invalid(sys_sem_t *sem) + + Invalidate a semaphore so that sys_sem_valid() returns 0. + ATTENTION: This does NOT mean that the semaphore shall be deallocated: + sys_sem_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +- err_t sys_mbox_new(sys_mbox_t *mbox, int size) + + Creates an empty mailbox for maximum "size" elements. Elements stored + in mailboxes are pointers. You have to define macros "_MBOX_SIZE" + in your lwipopts.h, or ignore this parameter in your implementation + and use a default size. + If the mailbox has been created, ERR_OK should be returned. Returning any + other error will provide a hint what went wrong, but except for assertions, + no real error handling is implemented. + +- void sys_mbox_free(sys_mbox_t *mbox) + + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. + +- void sys_mbox_post(sys_mbox_t *mbox, void *msg) + + Posts the "msg" to the mailbox. This function have to block until + the "msg" is really posted. + +- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one + is full, else, ERR_OK if the "msg" is posted. + +- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) + + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). If "timeout" is 0, the thread should + be blocked until a message arrives. The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. + +- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) + + This is similar to sys_arch_mbox_fetch, however if a message is not + present in the mailbox, it immediately returns with the code + SYS_MBOX_EMPTY. On success 0 is returned. + + To allow for efficient implementations, this can be defined as a + function-like macro in sys_arch.h instead of a normal function. For + example, a naive implementation could be: + #define sys_arch_mbox_tryfetch(mbox,msg) \ + sys_arch_mbox_fetch(mbox,msg,1) + although this would introduce unnecessary delays. + +- int sys_mbox_valid(sys_mbox_t *mbox) + + Returns 1 if the mailbox is valid, 0 if it is not valid. + When using pointers, a simple way is to check the pointer for != NULL. + When directly using OS structures, implementing this may be more complex. + This may also be a define, in which case the function is not prototyped. + +- void sys_mbox_set_invalid(sys_mbox_t *mbox) + + Invalidate a mailbox so that sys_mbox_valid() returns 0. + ATTENTION: This does NOT mean that the mailbox shall be deallocated: + sys_mbox_free() is always called before calling this function! + This may also be a define, in which case the function is not prototyped. + +If threads are supported by the underlying operating system and if +such functionality is needed in lwIP, the following function will have +to be implemented as well: + +- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) + + Starts a new thread named "name" with priority "prio" that will begin its + execution in the function "thread()". The "arg" argument will be passed as an + argument to the thread() function. The stack size to used for this thread is + the "stacksize" parameter. The id of the new thread is returned. Both the id + and the priority are system dependent. + +- sys_prot_t sys_arch_protect(void) + + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. + +- void sys_arch_unprotect(sys_prot_t pval) + + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. + +For some configurations, you also need: + +- u32_t sys_now(void) + + This optional function returns the current time in milliseconds (don't care + for wraparound, this is only used for time diffs). + Not implementing this function means you cannot use some modules (e.g. TCP + timestamps, internal timeouts for NO_SYS==1). + + +Note: + +Be carefull with using mem_malloc() in sys_arch. When malloc() refers to +mem_malloc() you can run into a circular function call problem. In mem.c +mem_init() tries to allcate a semaphore using mem_malloc, which of course +can't be performed when sys_arch uses mem_malloc. + +------------------------------------------------------------------------------- +Additional files required for the "OS support" emulation layer: +------------------------------------------------------------------------------- + +cc.h - Architecture environment, some compiler specific, some + environment specific (probably should move env stuff + to sys_arch.h.) + + Typedefs for the types used by lwip - + u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + + Compiler hints for packing lwip's structures - + PACK_STRUCT_FIELD(x) + PACK_STRUCT_STRUCT + PACK_STRUCT_BEGIN + PACK_STRUCT_END + + Platform specific diagnostic output - + LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + Portability defines for printf formatters: + U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + + "lightweight" synchronization mechanisms - + SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. + SYS_ARCH_PROTECT(x) - enter protection mode. + SYS_ARCH_UNPROTECT(x) - leave protection mode. + + If the compiler does not provide memset() this file must include a + definition of it, or include a file which defines it. + + This file must either include a system-local which defines + the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO + to make lwip/arch.h define the codes which are used throughout. + + +perf.h - Architecture specific performance measurement. + Measurement calls made throughout lwip, these can be defined to nothing. + PERF_START - start measuring something. + PERF_STOP(x) - stop measuring something, and record the result. + +sys_arch.h - Tied to sys_arch.c + + Arch dependent types for the following objects: + sys_sem_t, sys_mbox_t, sys_thread_t, + And, optionally: + sys_prot_t + + Defines to set vars of sys_mbox_t and sys_sem_t to NULL. + SYS_MBOX_NULL NULL + SYS_SEM_NULL NULL diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cc.h new file mode 100644 index 0000000..85636ef --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cc.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned int u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + +#define U16_F "d" +#define S16_F "d" +#define X16_F "x" +#define U32_F "d" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cpu.h new file mode 100644 index 0000000..a02f86d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/sys_arch.h new file mode 100644 index 0000000..2e841bd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/arch/sys_arch.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xSemaphoreHandle sys_mutex_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.c new file mode 100644 index 0000000..3f0d6b5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.c @@ -0,0 +1,280 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" + +#include "lwip/ethip6.h" //Add for ipv6 +#include +#include + +#define netifMTU (1500) +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) + + +#ifdef CONFIG_CONCURRENT_MODE +#define IF2NAME0 'r' +#define IF2NAME1 '2' +#endif + +static void arp_timer(void *arg); + + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ + +static void low_level_init(struct netif *netif) +{ + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set netif maximum transfer unit */ + netif->mtu = 1500; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + /* Wlan interface is initialized later */ +} + + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + + + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; + + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + if (sg_len) + rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len); + + return ERR_OK; +} + + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +//static struct pbuf * low_level_input(struct netif *netif){} + + +/** + * This function is the ethernetif_input task, it is processed when a packet + * is ready to be read from the interface. It uses the function low_level_input() + * that should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +//void ethernetif_input( void * pvParameters ) + + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); + +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = "lwip0"; + else if(netif->name[1] == '1') + netif->hostname = "lwip1"; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->output = etharp_output; +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + + return ERR_OK; +} + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.h new file mode 100644 index 0000000..93139d1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/ethernetif.h @@ -0,0 +1,13 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.c new file mode 100644 index 0000000..ce265a9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "lwip/lwip_timers.h" +#include "autoconf.h" +#include "tcm_heap.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + (void ) size; + + *mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + if (*mbox == NULL) + return ERR_MEM; + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t *mbox) +{ + if( uxQueueMessagesWaiting( *mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( *mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t *mbox, void *data) +{ + while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} +/*----------------------------------------------------------------------------------*/ +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (*mbox == SYS_MBOX_NULL) + return 0; + else + return 1; +} +/*-----------------------------------------------------------------------------------*/ +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = SYS_MBOX_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Creates a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + vSemaphoreCreateBinary(*sem ); + if(*sem == NULL) + { + +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(*sem,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t *sem) +{ + xSemaphoreGive(*sem); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t *sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete(*sem); +} +/*-----------------------------------------------------------------------------------*/ +int sys_sem_valid(sys_sem_t *sem) +{ + if (*sem == SYS_SEM_NULL) + return 0; + else + return 1; +} + +/*-----------------------------------------------------------------------------------*/ +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = SYS_SEM_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts *sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} +/*-----------------------------------------------------------------------------------*/ + /* Mutexes*/ +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_COMPAT_MUTEX == 0 +/* Create a new mutex*/ +err_t sys_mutex_new(sys_mutex_t *mutex) { + + *mutex = xSemaphoreCreateMutex(); + if(*mutex == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.mutex.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + +#if SYS_STATS + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } +#endif /* SYS_STATS */ + return ERR_OK; +} +/*-----------------------------------------------------------------------------------*/ +/* Deallocate a mutex*/ +void sys_mutex_free(sys_mutex_t *mutex) +{ +#if SYS_STATS + --lwip_stats.sys.mutex.used; +#endif /* SYS_STATS */ + + vQueueDelete(*mutex); +} +/*-----------------------------------------------------------------------------------*/ +/* Lock a mutex*/ +void sys_mutex_lock(sys_mutex_t *mutex) +{ + sys_arch_sem_wait(*mutex, 0); +} + +/*-----------------------------------------------------------------------------------*/ +/* Unlock a mutex*/ +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + xSemaphoreGive(*mutex); +} +#endif /*LWIP_COMPAT_MUTEX*/ +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +#if 0 +sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); +#if CONFIG_USE_TCM_HEAP + { + void *stack_addr = tcm_heap_malloc(stacksize * sizeof(int)); + + if(stack_addr == NULL){ + } + + result = xTaskGenericCreate( + thread, + ( signed portCHAR * ) name, + stacksize, + arg, + prio, + &CreatedTask, + stack_addr, + NULL); + } +#else + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); +#endif + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} +#endif +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} + +u32_t sys_now(void) +{ + return xTaskGetTickCount(); +} \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/realtek/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/bpstruct.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/bpstruct.h new file mode 100644 index 0000000..177758c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/bpstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack(1) +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cc.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cc.h new file mode 100644 index 0000000..356ec3c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cc.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "cpu.h" + +typedef unsigned char u8_t; +typedef signed char s8_t; +typedef unsigned short u16_t; +typedef signed short s16_t; +typedef unsigned long u32_t; +typedef signed long s32_t; +typedef u32_t mem_ptr_t; +typedef int sys_prot_t; + + +#define U16_F "hu" +#define S16_F "d" +#define X16_F "hx" +#define U32_F "u" +#define S32_F "d" +#define X32_F "x" +#define SZT_F "uz" + +//Add for ipv6 & IGMP +#define LWIP_RAND 1 +#ifdef LWIP_RAND +#define u32_t_random() (u32_t)(rand() % 0xFFFFFFFF) +#endif + +/* define compiler specific symbols */ +#if defined (__ICCARM__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x +#define PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define PACK_STRUCT_BEGIN __packed +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__GNUC__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#elif defined (__TASKING__) + +#define PACK_STRUCT_BEGIN +#define PACK_STRUCT_STRUCT +#define PACK_STRUCT_END +#define PACK_STRUCT_FIELD(x) x + +#endif + +#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0) + +#endif /* __CC_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cpu.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cpu.h new file mode 100644 index 0000000..a02f86d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/cpu.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __CPU_H__ +#define __CPU_H__ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* __CPU_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/epstruct.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/epstruct.h new file mode 100644 index 0000000..1e1a049 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/epstruct.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#if defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#endif + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/init.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/init.h new file mode 100644 index 0000000..e622c73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/init.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __ARCH_INIT_H__ +#define __ARCH_INIT_H__ + +#define TCPIP_INIT_DONE(arg) tcpip_init_done(arg) + +void tcpip_init_done(void *); +int wait_for_tcpip_init(void); + +#endif /* __ARCH_INIT_H__ */ + + + + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/lib.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/lib.h new file mode 100644 index 0000000..378f25b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/lib.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LIB_H__ +#define __LIB_H__ + +#include + + +#endif /* __LIB_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/perf.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/perf.h new file mode 100644 index 0000000..334d42a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/perf.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START /* null definition */ +#define PERF_STOP(x) /* null definition */ + +#endif /* __PERF_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/sys_arch.h new file mode 100644 index 0000000..2e841bd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/arch/sys_arch.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xSemaphoreHandle sys_mutex_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/MFC6A0B.tmp b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/MFC6A0B.tmp new file mode 100644 index 0000000..5097f29 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/MFC6A0B.tmp @@ -0,0 +1,489 @@ +/** +* @file +* Ethernet Interface Skeleton +* +*/ + +/* +* Copyright (c) 2001-2004 Swedish Institute of Computer Science. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. The name of the author may not be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +* +* This file is part of the lwIP TCP/IP stack. +* +* Author: Adam Dunkels +* +*/ + +/* +* This file is a skeleton for developing Ethernet network interface +* drivers for lwIP. Add code to the low_level functions and do a +* search-and-replace for the word "ethernetif" to replace it with +* something that better describes your network interface. +*/ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +//#include "lwip/sys.h" +//#include "lwip/tcpip.h" +//#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +//#include "queue.h" + +#include "main.h" // for the definition of CONFIG_WLAN + +#if !CONFIG_WLAN +#include "stm32f2x7_eth.h" +#else +#include +#endif +#include + +#include + + +#define netifMTU (1500) +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) + +#if !CONFIG_WLAN +/* Define those to better describe your network interface. */ +#define IFNAME0 's' +#define IFNAME1 't' + +static struct netif *s_pxNetIf = NULL; +xSemaphoreHandle s_xSemaphore = NULL; + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + + +static void ethernetif_input( void * pvParameters ); +#endif + +static void arp_timer(void *arg); + + +/** +* In this function, the hardware should be initialized. +* Called from ethernetif_init(). +* +* @param netif the already initialized lwip network interface structure +* for this ethernetif +*/ +static void low_level_init(struct netif *netif) +{ + uint32_t i; + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + +#if !CONFIG_WLAN + /* set netif MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; +#endif + + /* set netif maximum transfer unit */ + netif->mtu = 1500; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if !CONFIG_WLAN + s_pxNetIf =netif; + + /* create binary semaphore used for informing ethernetif of frame reception */ + if (s_xSemaphore == NULL) + { + vSemaphoreCreateBinary(s_xSemaphore); + xSemaphoreTake( s_xSemaphore, 0); + } + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable Ethernet Rx interrrupt */ + { + for(i=0; iBuffer1Addr); + bufferoffset = 0; + + for(q = p; q != NULL; q = q->next) + { + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + goto error; + } + + /* Get bytes in current lwIP buffer */ + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) + { + /* Copy data to Tx buffer*/ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); + + /* Point to next descriptor */ + DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); + + /* Check if the buffer is available */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + goto error; + } + + buffer = (u8 *)(DmaTxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); + framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy the remaining bytes */ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy ); + bufferoffset = bufferoffset + byteslefttocopy; + framelength = framelength + byteslefttocopy; + } + + /* Prepare transmit descriptors to give to DMA*/ + ETH_Prepare_Transmit_Descriptors(framelength); + + /* Give semaphore and exit */ + error: + + xSemaphoreGive(xTxSemaphore); + } +#endif // #if !CONFIG_WLAN + + return ERR_OK; +} + + +#if !CONFIG_WLAN +/** +* Should allocate a pbuf and transfer the bytes of the incoming +* packet from the interface into the pbuf. +* +* @param netif the lwip network interface structure for this ethernetif +* @return a pbuf filled with the received packet (including MAC header) +* NULL on memory error +*/ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p= NULL, *q; + u32_t len; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxDesc; + uint32_t bufferoffset = 0; + uint32_t payloadoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t i=0; + + /* get received frame */ + frame = ETH_Get_Received_Frame_interrupt(); + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + if (len > 0) + { + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + } + + if (p != NULL) + { + DMARxDesc = frame.descriptor; + bufferoffset = 0; + for(q = p; q != NULL; q = q->next) + { + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) + { + /* Copy data to pbuf*/ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); + + /* Point to next descriptor */ + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + buffer = (unsigned char *)(DMARxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy remaining data in pbuf */ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy); + bufferoffset = bufferoffset + byteslefttocopy; + } + + /* Release descriptors to DMA */ + DMARxDesc =frame.descriptor; + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxDesc->Status = ETH_DMARxDesc_OWN; + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + /* added for test*/ + } + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + + +/** +* This function is the ethernetif_input task, it is processed when a packet +* is ready to be read from the interface. It uses the function low_level_input() +* that should handle the actual reception of bytes from the network +* interface. Then the type of the received packet is determined and +* the appropriate input function is called. +* +* @param netif the lwip network interface structure for this ethernetif +*/ +void ethernetif_input( void * pvParameters ) +{ + struct pbuf *p; + + for( ;; ) + { + if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE) + { +TRY_GET_NEXT_FRAME: + p = low_level_input( s_pxNetIf ); + if (p != NULL) + { + if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) + { + pbuf_free(p); + } + else + { + goto TRY_GET_NEXT_FRAME; + } + } + + } + } +} +#endif +/** +* Should be called at the beginning of the program to set up the +* network interface. It calls the function low_level_init() to do the +* actual setup of the hardware. +* +* This function should be passed as a parameter to netif_add(). +* +* @param netif the lwip network interface structure for this ethernetif +* @return ERR_OK if the loopif is initialized +* ERR_MEM if private data couldn't be allocated +* any other err_t on error +*/ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if !CONFIG_WLAN + /* ethernet */ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#else + /* wlan interface*/ +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ +#endif // WLAN + + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + + return ERR_OK; +} + + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + +/* +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} +*/ +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.c new file mode 100644 index 0000000..cee7c33 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.c @@ -0,0 +1,656 @@ +/** +* @file +* Ethernet Interface Skeleton +* +*/ + +/* +* Copyright (c) 2001-2004 Swedish Institute of Computer Science. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* 3. The name of the author may not be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +* OF SUCH DAMAGE. +* +* This file is part of the lwIP TCP/IP stack. +* +* Author: Adam Dunkels +* +*/ + +/* +* This file is a skeleton for developing Ethernet network interface +* drivers for lwIP. Add code to the low_level functions and do a +* search-and-replace for the word "ethernetif" to replace it with +* something that better describes your network interface. +*/ + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/icmp.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "err.h" +#include "ethernetif.h" +#include "queue.h" + +#include "lwip/ethip6.h" //Add for ipv6 + +#include "main.h" // for the definition of CONFIG_WLAN + + +#if !CONFIG_WLAN +#include "stm32f2x7_eth.h" +#else +#include +#endif +#include + +#include + +#ifdef CONFIG_DONT_CARE_TP +#define netifMTU (576) +#else +#define netifMTU (1500) +#endif +#define netifINTERFACE_TASK_STACK_SIZE ( 350 ) +#define netifINTERFACE_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define netifGUARD_BLOCK_TIME ( 250 ) +/* The time to block waiting for input. */ +#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 ) +#define FAKE_PING_REPLY 0 + +#if !CONFIG_WLAN +/* Define those to better describe your network interface. */ +#define IFNAME0 's' +#define IFNAME1 't' + +static struct netif *s_pxNetIf = NULL; +xSemaphoreHandle s_xSemaphore = NULL; + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + +static void ethernetif_input( void * pvParameters ); +#endif + +static void arp_timer(void *arg); + + +/** +* In this function, the hardware should be initialized. +* Called from ethernetif_init(). +* +* @param netif the already initialized lwip network interface structure +* for this ethernetif +*/ +static void low_level_init(struct netif *netif) +{ + uint32_t i; + + /* set netif MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + +#if !CONFIG_WLAN + /* set netif MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; +#endif + + /* set netif maximum transfer unit */ + netif->mtu = netifMTU; + + /* Accept broadcast address and ARP traffic */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + +#if !CONFIG_WLAN + s_pxNetIf =netif; + + /* create binary semaphore used for informing ethernetif of frame reception */ + if (s_xSemaphore == NULL) + { + s_xSemaphore= xSemaphoreCreateCounting(20,0); + } + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable Ethernet Rx interrrupt */ + { + for(i=0; itot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_arp = (struct etharp_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_arp = (struct etharp_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = fake_src_mac; + q_arp->opcode = htons(ARP_REPLY); + q_arp->shwaddr = fake_src_mac; + q_arp->sipaddr = p_arp->dipaddr; + q_arp->dhwaddr = p_eth->src; + q_arp->dipaddr = p_arp->sipaddr; + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_arp_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake arp reply \n\r"); +} + +void fake_echo_reply(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q, *tq, *tp; + int q_len, p_len; + struct eth_hdr *p_eth, *q_eth; + struct ip_hdr *p_ip, *q_ip; + struct icmp_echo_hdr *p_echo, *q_echo; + + // Allocate buffer to store received packet + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + for (tq = q, tp = p, q_len = tq->len; tp != NULL ; tp = tp->next) + { + p_len = tp->len; + while(p_len) + { + if(q_len > p_len) { + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), p_len); + q_len -= p_len; + p_len = 0; + }else{ + memcpy((char*)tq->payload + (tq->len - q_len), (char*)tp->payload + (tp->len - p_len), q_len); + p_len -= q_len; + tq = tq->next; + q_len = tq->len; + } + } + } + p_eth = (struct eth_hdr *)p->payload; + q_eth = (struct eth_hdr *)q->payload; + p_ip = (struct ip_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr)); + q_ip = (struct ip_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr)); + p_echo = (struct icmp_echo_hdr *)((char*)(p->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + q_echo = (struct icmp_echo_hdr *)((char*)(q->payload) + sizeof(struct eth_hdr) + sizeof(struct ip_hdr)); + + q_eth->dest = p_eth->src; + q_eth->src = p_eth->dest; + q_ip->src.addr = p_ip->dest.addr; + q_ip->dest.addr = p_ip->src.addr; + q_ip->_chksum = 0; + q_ip->_chksum = inet_chksum(q_ip, sizeof(struct ip_hdr)); + q_echo->type = ICMP_ER; + q_echo->code = 0; + q_echo->chksum = 0; + q_echo->chksum = inet_chksum(q_echo, q->tot_len - sizeof(struct eth_hdr) - sizeof(struct ip_hdr)); + + if(0){ + int i; + char *buf = q->payload; + printf("\n\r"); + for(i=0;itot_len;i++) + printf("0x%02x, ", buf[i]); + printf("\n\r"); + } + if (ERR_OK != netif->input(q, netif)){ + printf("\n\rfake_echo_reply input error"); + pbuf_free(q); + }else + printf("\n\rfake echo reply \n\r"); +} +#endif // #if FAKE_PING_REPLY + +/** +* This function should do the actual transmission of the packet. The packet is +* contained in the pbuf that is passed to the function. This pbuf +* might be chained. +* +* @param netif the lwip network interface structure for this ethernetif +* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) +* @return ERR_OK if the packet could be sent +* an err_t value if the packet couldn't be sent +* +* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to +* strange results. You might consider waiting for space in the DMA queue +* to become availale since the stack doesn't retry to send a packet +* dropped because of memory failure (except for the TCP timers). +*/ + +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ +#if !CONFIG_WLAN + static xSemaphoreHandle xTxSemaphore = NULL; + struct pbuf *q; + uint32_t l = 0; + u8 *buffer ; + + if (xTxSemaphore == NULL) + { + vSemaphoreCreateBinary (xTxSemaphore); + } + + if (xSemaphoreTake(xTxSemaphore, netifGUARD_BLOCK_TIME)) + { + buffer = (u8 *)(DMATxDescToSet->Buffer1Addr); + for(q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)&buffer[l], q->payload, q->len); + l = l + q->len; + } + ETH_Prepare_Transmit_Descriptors(l); + xSemaphoreGive(xTxSemaphore); + } +#else + /* Refer to eCos lwip eth_drv_send() */ + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + int sg_len = 0; + struct pbuf *q; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return ERR_IF; + + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + +#if FAKE_PING_REPLY + { + char *header = p->payload; + if(header[12] == 0x08 && header[13] == 0x06) + { // arp packet + if(header[21] == 0x01) + { // arp request packet + printf("\n\rfake_ping: arp request packet."); + if(0) + { + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_arp_reply(netif, p); + return ERR_OK; + } + }else if(header[12] == 0x08 && header[13] == 0x00) + { // ip packet + if(header[15] == 0x00 && header[23] == 0x01) + { // icmp packet + printf("\n\rfake_ping: icmp packet."); + if(0){ + int i; + printf("\n\r"); + for (q = p; q != NULL; q = q->next) + { + char *buf = q->payload; + for(i=0;ilen;i++) + printf("0x%02x, ", buf[i]); + } + printf("\n\r"); + } + fake_echo_reply(netif, p); + return ERR_OK; + } + } + } +#endif // #if FAKE_PING_REPLY + if (sg_len) + rltk_wlan_send(netif_get_idx(netif), sg_list, sg_len, p->tot_len); +#endif // #if !CONFIG_WLAN + + return ERR_OK; +} + + +#if !CONFIG_WLAN +/** +* Should allocate a pbuf and transfer the bytes of the incoming +* packet from the interface into the pbuf. +* +* @param netif the lwip network interface structure for this ethernetif +* @return a pbuf filled with the received packet (including MAC header) +* NULL on memory error +*/ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + u16_t len; + uint32_t l=0,i =0; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxNextDesc; + + p = NULL; + + /* Get received frame */ + frame = ETH_Get_Received_Frame_interrupt(); + + /* check that frame has no error */ + if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) + { + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + /* Copy received frame from ethernet driver buffer to stack buffer */ + if (p != NULL) + { + for (q = p; q != NULL; q = q->next) + { + memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len); + l = l + q->len; + } + } + } + + /* Release descriptors to DMA */ + /* Check if received frame with multiple DMA buffer segments */ + if (DMA_RX_FRAME_infos->Seg_Count > 1) + { + DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc; + } + else + { + DMARxNextDesc = frame.descriptor; + } + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxNextDesc->Status = ETH_DMARxDesc_OWN; + DMARxNextDesc = (ETH_DMADESCTypeDef *)(DMARxNextDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + + +/** +* This function is the ethernetif_input task, it is processed when a packet +* is ready to be read from the interface. It uses the function low_level_input() +* that should handle the actual reception of bytes from the network +* interface. Then the type of the received packet is determined and +* the appropriate input function is called. +* +* @param netif the lwip network interface structure for this ethernetif +*/ +void ethernetif_input( void * pvParameters ) +{ + struct pbuf *p; + + for( ;; ) + { + if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE) + { + p = low_level_input( s_pxNetIf ); + if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf)) + { + pbuf_free(p); + p=NULL; + } + } + } +} +#endif + +/* Refer to eCos eth_drv_recv to do similarly in ethernetif_input */ +void ethernetif_recv(struct netif *netif, int total_len) +{ +#if CONFIG_WLAN + struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; + struct pbuf *p, *q; + int sg_len = 0; + + if(!rltk_wlan_running(netif_get_idx(netif))) + return; + + if ((total_len > MAX_ETH_MSG) || (total_len < 0)) + total_len = MAX_ETH_MSG; + + // Allocate buffer to store received packet + p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL); + if (p == NULL) { + printf("\n\rCannot allocate pbuf to receive packet"); + return; + } + + // Create scatter list + for (q = p; q != NULL && sg_len < MAX_ETH_DRV_SG; q = q->next) { + sg_list[sg_len].buf = (unsigned int) q->payload; + sg_list[sg_len++].len = q->len; + } + + // Copy received packet to scatter list from wrapper rx skb + //printf("\n\rwlan:%c: Recv sg_len: %d, tot_len:%d", netif->name[1],sg_len, total_len); + rltk_wlan_recv(netif_get_idx(netif), sg_list, sg_len); + + // Pass received packet to the interface + if (ERR_OK != netif->input(p, netif)) + pbuf_free(p); +#endif +} + +/** +* Should be called at the beginning of the program to set up the +* network interface. It calls the function low_level_init() to do the +* actual setup of the hardware. +* +* This function should be passed as a parameter to netif_add(). +* +* @param netif the lwip network interface structure for this ethernetif +* @return ERR_OK if the loopif is initialized +* ERR_MEM if private data couldn't be allocated +* any other err_t on error +*/ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if !CONFIG_WLAN + /* ethernet */ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; +#else + /* wlan interface*/ +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + if(netif->name[1] == '0') + netif->hostname = "lwip0"; + else if(netif->name[1] == '1') + netif->hostname = "lwip1"; +#endif /* LWIP_NETIF_HOSTNAME */ + +#endif // WLAN + + netif->output = etharp_output; + netif->output_ip6 = ethip6_output ;//Add for ipv6 + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + etharp_init(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + + return ERR_OK; +} + + +static void arp_timer(void *arg) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} + +/* + * For FreeRTOS tickless + */ +int lwip_tickless_used = 0; + + +int arp_timeout_exist(void) +{ + struct sys_timeouts *timeouts; + struct sys_timeo *t; + + timeouts = sys_arch_timeouts(); + + for(t = timeouts->next; t != NULL;t = t->next) + if(t->h == arp_timer) + return 1; + + return 0; +} + +//Called by rltk_wlan_PRE_SLEEP_PROCESSING() +void lwip_PRE_SLEEP_PROCESSING(void) +{ + if(arp_timeout_exist()) { + tcpip_untimeout(arp_timer, NULL); + } + lwip_tickless_used = 1; +} + +//Called in ips_leave() path, support tickless when wifi power wakeup due to ioctl or deinit +void lwip_POST_SLEEP_PROCESSING(void) +{ + if(lwip_tickless_used) { + tcpip_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); + } +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.h new file mode 100644 index 0000000..93139d1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/ethernetif.h @@ -0,0 +1,13 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); +void lwip_PRE_SLEEP_PROCESSING(void); +void lwip_POST_SLEEP_PROCESSING(void); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.c new file mode 100644 index 0000000..3d111c6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.c @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "lwip/lwip_timers.h" + +xTaskHandle xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +struct timeoutlist +{ + struct sys_timeouts timeouts; + xTaskHandle pid; +}; + +/* This is the number of threads that can be started with sys_thread_new() */ +#define SYS_THREAD_MAX 6 + +static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX]; +static u16_t s_nextthread = 0; + + +/*-----------------------------------------------------------------------------------*/ +// Creates an empty mailbox. +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + (void ) size; + + *mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) ); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + if (*mbox == NULL) + return ERR_MEM; + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t *mbox) +{ + if( uxQueueMessagesWaiting( *mbox ) ) + { + /* Line for breakpoint. Should never break here! */ + portNOP(); +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + // TODO notify the user of failure. + } + + vQueueDelete( *mbox ); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t *mbox, void *data) +{ + while ( xQueueSendToBack(*mbox, &data, portMAX_DELAY ) != pdTRUE ){} +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ +err_t result; + + if ( xQueueSend( *mbox, &msg, 0 ) == pdPASS ) + { + result = ERR_OK; + } + else { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ +void *dummyptr; +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), timeout / portTICK_RATE_MS ) ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + while( pdTRUE != xQueueReceive( *mbox, &(*msg), portMAX_DELAY ) ){} // time is arbitrary + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( pdTRUE == xQueueReceive( *mbox, &(*msg), 0 ) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} +/*----------------------------------------------------------------------------------*/ +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (*mbox == SYS_MBOX_NULL) + return 0; + else + return 1; +} +/*-----------------------------------------------------------------------------------*/ +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = SYS_MBOX_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Creates a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + vSemaphoreCreateBinary(*sem ); + if(*sem == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.sem.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + + if(count == 0) // Means it can't be taken + { + xSemaphoreTake(*sem,1); + } + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ +portTickType StartTime, EndTime, Elapsed; + + StartTime = xTaskGetTickCount(); + + if( timeout != 0) + { + if( xSemaphoreTake( *sem, timeout / portTICK_RATE_MS ) == pdTRUE ) + { + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + while( xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE){} + EndTime = xTaskGetTickCount(); + Elapsed = (EndTime - StartTime) * portTICK_RATE_MS; + + return ( Elapsed ); // return time blocked + + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t *sem) +{ + xSemaphoreGive(*sem); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t *sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + vQueueDelete(*sem); +} +/*-----------------------------------------------------------------------------------*/ +int sys_sem_valid(sys_sem_t *sem) +{ + if (*sem == SYS_SEM_NULL) + return 0; + else + return 1; +} + +/*-----------------------------------------------------------------------------------*/ +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = SYS_SEM_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ + int i; + + // Initialize the the per-thread sys_timeouts structures + // make sure there are no valid pids in the list + for(i = 0; i < SYS_THREAD_MAX; i++) + { + s_timeoutlist[i].pid = 0; + s_timeoutlist[i].timeouts.next = NULL; + } + + // keep track of how many threads have been created + s_nextthread = 0; +} + +/* + Returns a pointer to the per-thread sys_timeouts structure. In lwIP, + each thread has a list of timeouts which is represented as a linked + list of sys_timeout structures. The sys_timeouts structure holds a + pointer to a linked list of timeouts. This function is called by + the lwIP timeout scheduler and must not return a NULL value. + + In a single threaded sys_arch implementation, this function will + simply return a pointer to a global sys_timeouts variable stored in + the sys_arch module. +*/ +struct sys_timeouts* sys_arch_timeouts(void) +{ +int i; +xTaskHandle pid; +struct timeoutlist *tl; + + pid = xTaskGetCurrentTaskHandle(); + + for(i = 0; i < s_nextthread; i++) + { + tl = &(s_timeoutlist[i]); + if(tl->pid == pid) + { + return &(tl->timeouts); + } + } + // Error + return NULL; +} +/*-----------------------------------------------------------------------------------*/ + /* Mutexes*/ +/*-----------------------------------------------------------------------------------*/ +/*-----------------------------------------------------------------------------------*/ +#if LWIP_COMPAT_MUTEX == 0 +/* Create a new mutex*/ +err_t sys_mutex_new(sys_mutex_t *mutex) { + + *mutex = xSemaphoreCreateMutex(); + if(*mutex == NULL) + { +#if SYS_STATS + ++lwip_stats.sys.mutex.err; +#endif /* SYS_STATS */ + return ERR_MEM; + } + +#if SYS_STATS + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } +#endif /* SYS_STATS */ + return ERR_OK; +} +/*-----------------------------------------------------------------------------------*/ +/* Deallocate a mutex*/ +void sys_mutex_free(sys_mutex_t *mutex) +{ +#if SYS_STATS + --lwip_stats.sys.mutex.used; +#endif /* SYS_STATS */ + + vQueueDelete(*mutex); +} +/*-----------------------------------------------------------------------------------*/ +/* Lock a mutex*/ +void sys_mutex_lock(sys_mutex_t *mutex) +{ + sys_arch_sem_wait(*mutex, 0); +} + +/*-----------------------------------------------------------------------------------*/ +/* Unlock a mutex*/ +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + xSemaphoreGive(*mutex); +} +#endif /*LWIP_COMPAT_MUTEX*/ +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ +xTaskHandle CreatedTask; +int result; + + if ( s_nextthread < SYS_THREAD_MAX ) + { + vPortEnterCritical(); + result = xTaskCreate( thread, ( signed portCHAR * ) name, stacksize, arg, prio, &CreatedTask ); + + // For each task created, store the task handle (pid) in the timers array. + // This scheme doesn't allow for threads to be deleted + s_timeoutlist[s_nextthread++].pid = CreatedTask; + vPortExitCritical(); + + if(result == pdPASS) + { + return CreatedTask; + } + else + { + return NULL; + } + } + else + { + return NULL; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ + vPortEnterCritical(); + return 1; +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ + ( void ) pval; + vPortExitCritical(); +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + ( void ) msg; + /*FSL:only needed for debugging + printf(msg); + printf("\n\r"); + */ + vPortEnterCritical( ); + for(;;) + ; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.h new file mode 100644 index 0000000..83d0c08 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/freertos/sys_arch.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +#define SYS_MBOX_NULL (xQueueHandle)0 +#define SYS_SEM_NULL (xSemaphoreHandle)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE + +typedef xSemaphoreHandle sys_sem_t; +typedef xQueueHandle sys_mbox_t; +typedef xTaskHandle sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[configMAX_TASK_NAME_LEN]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + + + +//extern sys_arch_state_t s_sys_arch_state; + +//void sys_set_default_state(); +//void sys_set_state(signed char *pTaskName, unsigned short nStackSize); + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 6 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.c new file mode 100644 index 0000000..f3b74ee --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.c @@ -0,0 +1,366 @@ +/** + * @file + * Ethernet Interface for standalone applications (without RTOS) - works only for + * ethernet polling mode (polling for ethernet frame reception) + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/mem.h" +#include "netif/etharp.h" +#include "ethernetif.h" +#include "stm32f2x7_eth.h" +#include "main.h" +#include + +/* Network interface name */ +#define IFNAME0 's' +#define IFNAME1 't' + + +/* Ethernet Rx & Tx DMA Descriptors */ +extern ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; + +/* Ethernet Driver Receive buffers */ +extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]; + +/* Ethernet Driver Transmit buffers */ +extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]; + +/* Global pointers to track current transmit and receive descriptors */ +extern ETH_DMADESCTypeDef *DMATxDescToSet; +extern ETH_DMADESCTypeDef *DMARxDescToGet; + +/* Global pointer for last received frame infos */ +extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos; + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void low_level_init(struct netif *netif) +{ +#ifdef CHECKSUM_BY_HARDWARE + int i; +#endif + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = MAC_ADDR0; + netif->hwaddr[1] = MAC_ADDR1; + netif->hwaddr[2] = MAC_ADDR2; + netif->hwaddr[3] = MAC_ADDR3; + netif->hwaddr[4] = MAC_ADDR4; + netif->hwaddr[5] = MAC_ADDR5; + + /* initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(ETH_MAC_Address0, netif->hwaddr); + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + +#ifdef CHECKSUM_BY_HARDWARE + /* Enable the TCP, UDP and ICMP checksum insertion for the Tx frames */ + for(i=0; iBuffer1Addr); + __IO ETH_DMADESCTypeDef *DmaTxDesc; + uint16_t framelength = 0; + uint32_t bufferoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t payloadoffset = 0; + + DmaTxDesc = DMATxDescToSet; + bufferoffset = 0; + + /* copy frame from pbufs to driver buffers */ + for(q = p; q != NULL; q = q->next) + { + /* Is this buffer available? If not, goto error */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + errval = ERR_BUF; + goto error; + } + + /* Get bytes in current lwIP buffer */ + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) + { + /* Copy data to Tx buffer*/ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); + + /* Point to next descriptor */ + DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); + + /* Check if the buffer is available */ + if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) + { + errval = ERR_USE; + goto error; + } + + buffer = (u8 *)(DmaTxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); + framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy the remaining bytes */ + memcpy( (u8_t*)((u8_t*)buffer + bufferoffset), (u8_t*)((u8_t*)q->payload + payloadoffset), byteslefttocopy ); + bufferoffset = bufferoffset + byteslefttocopy; + framelength = framelength + byteslefttocopy; + } + + /* Note: padding and CRC for transmitted frame + are automatically inserted by DMA */ + + /* Prepare transmit descriptors to give to DMA*/ + ETH_Prepare_Transmit_Descriptors(framelength); + + errval = ERR_OK; + +error: + + /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ + if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET) + { + /* Clear TUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_TUS; + + /* Resume DMA transmission*/ + ETH->DMATPDR = 0; + } + return errval; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * low_level_input(struct netif *netif) +{ + struct pbuf *p, *q; + uint32_t len; + FrameTypeDef frame; + u8 *buffer; + __IO ETH_DMADESCTypeDef *DMARxDesc; + uint32_t bufferoffset = 0; + uint32_t payloadoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t i=0; + + /* get received frame */ + frame = ETH_Get_Received_Frame(); + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = frame.length; + buffer = (u8 *)frame.buffer; + + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) + { + DMARxDesc = frame.descriptor; + bufferoffset = 0; + for(q = p; q != NULL; q = q->next) + { + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) + { + /* Copy data to pbuf*/ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); + + /* Point to next descriptor */ + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + buffer = (unsigned char *)(DMARxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + /* Copy remaining data in pbuf */ + memcpy( (u8_t*)((u8_t*)q->payload + payloadoffset), (u8_t*)((u8_t*)buffer + bufferoffset), byteslefttocopy); + bufferoffset = bufferoffset + byteslefttocopy; + } + } + + /* Release descriptors to DMA */ + DMARxDesc =frame.descriptor; + + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; iSeg_Count; i++) + { + DMARxDesc->Status = ETH_DMARxDesc_OWN; + DMARxDesc = (ETH_DMADESCTypeDef *)(DMARxDesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + DMA_RX_FRAME_infos->Seg_Count =0; + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + ETH->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + ETH->DMARPDR = 0; + } + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +err_t ethernetif_input(struct netif *netif) +{ + err_t err; + struct pbuf *p; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + + /* no packet could be read, silently ignore this */ + if (p == NULL) return ERR_MEM; + + /* entry point to the LwIP stack */ + err = netif->input(p, netif); + + if (err != ERR_OK) + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + } + return err; +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.h new file mode 100644 index 0000000..9ff1408 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/port/stm32f2x7/standalone/ethernetif.h @@ -0,0 +1,11 @@ +#ifndef __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + +err_t ethernetif_init(struct netif *netif); +err_t ethernetif_input(struct netif *netif); + +#endif diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/FILES b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/FILES new file mode 100644 index 0000000..952aeab --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/FILES @@ -0,0 +1,13 @@ +api/ - The code for the high-level wrapper API. Not needed if + you use the lowel-level call-back/raw API. + +core/ - The core of the TPC/IP stack; protocol implementations, + memory and buffer management, and the low-level raw API. + +include/ - lwIP include files. + +netif/ - Generic network interface device drivers are kept here, + as well as the ARP module. + +For more information on the various subdirectories, check the FILES +file in each directory. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_lib.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_lib.c new file mode 100644 index 0000000..7791b56 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_lib.c @@ -0,0 +1,903 @@ +/** + * @file + * Sequential API External module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* This is the part of the API that is linked with + the application */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" + +#include "lwip/lwip_ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" + +#include + +#define API_MSG_VAR_REF(name) API_VAR_REF(name) +#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) +#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name) +#define API_MSG_VAR_ALLOC_DONTFAIL(name) API_VAR_ALLOC_DONTFAIL(struct api_msg, MEMP_API_MSG, name) +#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name) + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is also created. + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) +{ + struct netconn *conn; + API_MSG_VAR_DECLARE(msg); + + conn = netconn_alloc(t, callback); + if (conn != NULL) { + err_t err; + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.msg.n.proto = proto; + API_MSG_VAR_REF(msg).msg.conn = conn; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_newconn, err); + API_MSG_VAR_FREE(msg); + if (err != ERR_OK) { + LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); + LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ +#if !LWIP_NETCONN_SEM_PER_THREAD + LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); + sys_sem_free(&conn->op_completed); +#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ + sys_mbox_free(&conn->recvmbox); + memp_free(MEMP_NETCONN, conn); + return NULL; + } + } + return conn; +} + +/** + * Close a netconn 'connection' and free its resources. + * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate + * after this returns. + * + * @param conn the netconn to delete + * @return ERR_OK if the connection was deleted + */ +err_t +netconn_delete(struct netconn *conn) +{ + err_t err; + API_MSG_VAR_DECLARE(msg); + + /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ + if (conn == NULL) { + return ERR_OK; + } + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).function = lwip_netconn_do_delconn; + API_MSG_VAR_REF(msg).msg.conn = conn; + err = tcpip_apimsg(&API_MSG_VAR_REF(msg)); + API_MSG_VAR_FREE(msg); + + if (err != ERR_OK) { + return err; + } + + netconn_free(conn); + + return ERR_OK; +} + +/** + * Get the local or remote IP address and port of a netconn. + * For RAW netconns, this returns the protocol instead of a port! + * + * @param conn the netconn to query + * @param addr a pointer to which to save the IP address + * @param port a pointer to which to save the port (or protocol for RAW) + * @param local 1 to get the local IP address, 0 to get the remote one + * @return ERR_CONN for invalid connections + * ERR_OK if the information was retrieved + */ +err_t +netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.ad.local = local; +#if LWIP_MPU_COMPATIBLE + TCPIP_APIMSG(msg, lwip_netconn_do_getaddr, err); + *addr = *ipX_2_ip(&(msg->msg.msg.ad.ipaddr)); + *port = msg->msg.msg.ad.port; +#else /* LWIP_MPU_COMPATIBLE */ + msg.msg.msg.ad.ipaddr = ip_2_ipX(addr); + msg.msg.msg.ad.port = port; + TCPIP_APIMSG(&msg, lwip_netconn_do_getaddr, err); +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Bind a netconn to a specific local IP address and port. + * Binding one netconn twice might not always be checked correctly! + * + * @param conn the netconn to bind + * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY + * to bind to all addresses) + * @param port the local port to bind the netconn to (not used for RAW) + * @return ERR_OK if bound, any other err_t on failure + */ +err_t +netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (addr == NULL) { + addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr); + API_MSG_VAR_REF(msg).msg.msg.bc.port = port; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_bind, err); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Connect a netconn to a specific remote IP address and port. + * + * @param conn the netconn to connect + * @param addr the remote IP address to connect to + * @param port the remote port to connect to (no used for RAW) + * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise + */ +err_t +netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (addr == NULL) { + addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr); + API_MSG_VAR_REF(msg).msg.msg.bc.port = port; +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + /* The TCP version waits for the connect to succeed, + so always needs to use message passing. */ + API_MSG_VAR_REF(msg).function = lwip_netconn_do_connect; + err = tcpip_apimsg(&API_MSG_VAR_REF(msg)); + } +#endif /* LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) && LWIP_TCP + else +#endif /* (LWIP_UDP || LWIP_RAW) && LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) + { + /* UDP and RAW only set flags, so we can use core-locking. */ + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_connect, err); + } +#endif /* (LWIP_UDP || LWIP_RAW) */ + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Disconnect a netconn from its current peer (only valid for UDP netconns). + * + * @param conn the netconn to disconnect + * @return TODO: return value is not set here... + */ +err_t +netconn_disconnect(struct netconn *conn) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_disconnect, err); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Set a TCP netconn into listen mode + * + * @param conn the tcp netconn to set to listen mode + * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 + * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns + * don't return any error (yet?)) + */ +err_t +netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) +{ +#if LWIP_TCP + API_MSG_VAR_DECLARE(msg); + err_t err; + + /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ + LWIP_UNUSED_ARG(backlog); + + LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; +#if TCP_LISTEN_BACKLOG + API_MSG_VAR_REF(msg).msg.msg.lb.backlog = backlog; +#endif /* TCP_LISTEN_BACKLOG */ + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_listen, err); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(backlog); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Accept a new connection on a TCP listening netconn. + * + * @param conn the TCP listen netconn + * @param new_conn pointer where the new connection is stored + * @return ERR_OK if a new connection has been received or an error + * code otherwise + */ +err_t +netconn_accept(struct netconn *conn, struct netconn **new_conn) +{ +#if LWIP_TCP + struct netconn *newconn; + err_t err; +#if TCP_LISTEN_BACKLOG + API_MSG_VAR_DECLARE(msg); +#endif /* TCP_LISTEN_BACKLOG */ + + LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); + *new_conn = NULL; + LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on acceptmbox forever! */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + + if (newconn == NULL) { + /* connection has been aborted */ + NETCONN_SET_SAFE_ERR(conn, ERR_ABRT); + return ERR_ABRT; + } +#if TCP_LISTEN_BACKLOG + /* Let the stack know that we have accepted the connection. */ + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + /* don't care for the return value of lwip_netconn_do_recv */ + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); +#endif /* TCP_LISTEN_BACKLOG */ + + *new_conn = newconn; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(new_conn); + return ERR_ARG; +#endif /* LWIP_TCP */ +} + +/** + * Receive data: actual implementation that doesn't care whether pbuf or netbuf + * is received + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf/netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +static err_t +netconn_recv_data(struct netconn *conn, void **new_buf) +{ + void *buf = NULL; + u16_t len; + err_t err; +#if LWIP_TCP + API_MSG_VAR_DECLARE(msg); +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + + err = conn->last_err; + if (ERR_IS_FATAL(err)) { + /* don't recv on fatal errors: this might block the application task + waiting on recvmbox forever! */ + /* @todo: this does not allow us to fetch data that has been put into recvmbox + before the fatal error occurred - is that a problem? */ + return err; + } + +#if LWIP_SO_RCVTIMEO + if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { + NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT); + return ERR_TIMEOUT; + } +#else + sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); +#endif /* LWIP_SO_RCVTIMEO*/ + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + if (!netconn_get_noautorecved(conn) || (buf == NULL)) { + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + if (buf != NULL) { + API_MSG_VAR_REF(msg).msg.msg.r.len = ((struct pbuf *)buf)->tot_len; + } else { + API_MSG_VAR_REF(msg).msg.msg.r.len = 1; + } + /* don't care for the return value of lwip_netconn_do_recv */ + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); + } + + /* If we are closed, we indicate that we no longer wish to use the socket */ + if (buf == NULL) { + API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); + /* Avoid to lose any previous error code */ + NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); + return ERR_CLSD; + } + len = ((struct pbuf *)buf)->tot_len; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ +#if (LWIP_UDP || LWIP_RAW) + { + LWIP_ASSERT("buf != NULL", buf != NULL); + len = netbuf_len((struct netbuf *)buf); + } +#endif /* (LWIP_UDP || LWIP_RAW) */ + +#if LWIP_SO_RCVBUF + SYS_ARCH_DEC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); + + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; +} + +/** + * Receive data (in form of a pbuf) from a TCP netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new pbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + * ERR_ARG if conn is not a TCP netconn + */ +err_t +netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) +{ + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) && + NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); + + return netconn_recv_data(conn, (void **)new_buf); +} + +/** + * Receive data (in form of a netbuf containing a packet buffer) from a netconn + * + * @param conn the netconn from which to receive data + * @param new_buf pointer where a new netbuf is stored when received data + * @return ERR_OK if data has been received, an error code otherwise (timeout, + * memory error or another error) + */ +err_t +netconn_recv(struct netconn *conn, struct netbuf **new_buf) +{ +#if LWIP_TCP + struct netbuf *buf = NULL; + err_t err; +#endif /* LWIP_TCP */ + + LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); + *new_buf = NULL; + LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); + +#if LWIP_TCP +#if (LWIP_UDP || LWIP_RAW) + if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) +#endif /* (LWIP_UDP || LWIP_RAW) */ + { + struct pbuf *p = NULL; + /* This is not a listening netconn, since recvmbox is set */ + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + NETCONN_SET_SAFE_ERR(conn, ERR_MEM); + return ERR_MEM; + } + + err = netconn_recv_data(conn, (void **)&p); + if (err != ERR_OK) { + memp_free(MEMP_NETBUF, buf); + return err; + } + LWIP_ASSERT("p != NULL", p != NULL); + + buf->p = p; + buf->ptr = p; + buf->port = 0; + ipX_addr_set_any(LWIP_IPV6, &buf->addr); + *new_buf = buf; + /* don't set conn->last_err: it's only ERR_OK, anyway */ + return ERR_OK; + } +#endif /* LWIP_TCP */ +#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) + else +#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ + { +#if (LWIP_UDP || LWIP_RAW) + return netconn_recv_data(conn, (void **)new_buf); +#endif /* (LWIP_UDP || LWIP_RAW) */ + } +} + +/** + * TCP: update the receive window: by calling this, the application + * tells the stack that it has processed data and is able to accept + * new data. + * ATTENTION: use with care, this is mainly used for sockets! + * Can only be used when calling netconn_set_noautorecved(conn, 1) before. + * + * @param conn the netconn for which to update the receive window + * @param length amount of data processed (ATTENTION: this must be accurate!) + */ +void +netconn_recved(struct netconn *conn, u32_t length) +{ +#if LWIP_TCP + if ((conn != NULL) && (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && + (netconn_get_noautorecved(conn))) { + API_MSG_VAR_DECLARE(msg); + /* Let the stack know that we have taken the data. */ + /* TODO: Speedup: Don't block and wait for the answer here + (to prevent multiple thread-switches). */ + API_MSG_VAR_ALLOC_DONTFAIL(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.r.len = length; + /* don't care for the return value of lwip_netconn_do_recv */ + TCPIP_APIMSG_NOERR(&API_MSG_VAR_REF(msg), lwip_netconn_do_recv); + API_MSG_VAR_FREE(msg); + } +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(conn); + LWIP_UNUSED_ARG(length); +#endif /* LWIP_TCP */ +} + +/** + * Send data (in form of a netbuf) to a specific remote IP address and port. + * Only to be used for UDP and RAW netconns (not TCP). + * + * @param conn the netconn over which to send data + * @param buf a netbuf containing the data to send + * @param addr the remote IP address to which to send the data + * @param port the remote port to which to send the data + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port) +{ + if (buf != NULL) { + ipX_addr_set_ipaddr(PCB_ISIPV6(conn->pcb.ip), &buf->addr, addr); + buf->port = port; + return netconn_send(conn, buf); + } + return ERR_VAL; +} + +/** + * Send data over a UDP or RAW netconn (that is already connected). + * + * @param conn the UDP or RAW netconn over which to send data + * @param buf a netbuf containing the data to send + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_send(struct netconn *conn, struct netbuf *buf) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); + + LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.b = buf; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_send, err); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Send data over a TCP netconn. + * + * @param conn the TCP netconn over which to send data + * @param dataptr pointer to the application buffer that contains the data to send + * @param size size of the application data to send + * @param apiflags combination of following flags : + * - NETCONN_COPY: data will be copied into memory belonging to the stack + * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent + * - NETCONN_DONTBLOCK: only write the data if all data can be written at once + * @param bytes_written pointer to a location that receives the number of written bytes + * @return ERR_OK if data was sent, any other err_t on error + */ +err_t +netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + u8_t dontblock; + + LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type)== NETCONN_TCP), return ERR_VAL;); + if (size == 0) { + return ERR_OK; + } + dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); + if (dontblock && !bytes_written) { + /* This implies netconn_write() cannot be used for non-blocking send, since + it has no way to return the number of bytes written. */ + return ERR_VAL; + } + + API_MSG_VAR_ALLOC(msg); + /* non-blocking write sends as much */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.w.dataptr = dataptr; + API_MSG_VAR_REF(msg).msg.msg.w.apiflags = apiflags; + API_MSG_VAR_REF(msg).msg.msg.w.len = size; +#if LWIP_SO_SNDTIMEO + if (conn->send_timeout != 0) { + /* get the time we started, which is later compared to + sys_now() + conn->send_timeout */ + API_MSG_VAR_REF(msg).msg.msg.w.time_started = sys_now(); + } else { + API_MSG_VAR_REF(msg).msg.msg.w.time_started = 0; + } +#endif /* LWIP_SO_SNDTIMEO */ + + /* For locking the core: this _can_ be delayed on low memory/low send buffer, + but if it is, this is done inside api_msg.c:do_write(), so we can use the + non-blocking version here. */ + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_write, err); + if ((err == ERR_OK) && (bytes_written != NULL)) { + if (dontblock +#if LWIP_SO_SNDTIMEO + || (conn->send_timeout != 0) +#endif /* LWIP_SO_SNDTIMEO */ + ) { + /* nonblocking write: maybe the data has been sent partly */ + *bytes_written = API_MSG_VAR_REF(msg).msg.msg.w.len; + } else { + /* blocking call succeeded: all data has been sent if it */ + *bytes_written = size; + } + } + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close or shutdown a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close or shutdown + * @param how fully close or only shutdown one side? + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +static err_t +netconn_close_shutdown(struct netconn *conn, u8_t how) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); + API_MSG_VAR_REF(msg).function = lwip_netconn_do_close; + API_MSG_VAR_REF(msg).msg.conn = conn; + /* shutting down both ends is the same as closing */ + API_MSG_VAR_REF(msg).msg.msg.sd.shut = how; + /* because of the LWIP_TCPIP_CORE_LOCKING implementation of lwip_netconn_do_close, + don't use TCPIP_APIMSG here */ + err = tcpip_apimsg(&API_MSG_VAR_REF(msg)); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} + +/** + * Close a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to close + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_close(struct netconn *conn) +{ + /* shutting down both ends is the same as closing */ + return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); +} + +/** + * Shut down one or both sides of a TCP netconn (doesn't delete it). + * + * @param conn the TCP netconn to shut down + * @return ERR_OK if the netconn was closed, any other err_t on error + */ +err_t +netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) +{ + return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)); +} + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +/** + * Join multicast groups for UDP netconns. + * + * @param conn the UDP netconn for which to change multicast addresses + * @param multiaddr IP address of the multicast group to join or leave + * @param netif_addr the IP address of the network interface on which to send + * the igmp message + * @param join_or_leave flag whether to send a join- or leave-message + * @return ERR_OK if the action was taken, any err_t on error + */ +err_t +netconn_join_leave_group(struct netconn *conn, + ip_addr_t *multiaddr, + ip_addr_t *netif_addr, + enum netconn_igmp join_or_leave) +{ + API_MSG_VAR_DECLARE(msg); + err_t err; + + LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); + + API_MSG_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (multiaddr == NULL) { + multiaddr = IP_ADDR_ANY; + } + if (netif_addr == NULL) { + netif_addr = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + API_MSG_VAR_REF(msg).msg.conn = conn; + API_MSG_VAR_REF(msg).msg.msg.jl.multiaddr = API_MSG_VAR_REF(ip_2_ipX(multiaddr)); + API_MSG_VAR_REF(msg).msg.msg.jl.netif_addr = API_MSG_VAR_REF(ip_2_ipX(netif_addr)); + API_MSG_VAR_REF(msg).msg.msg.jl.join_or_leave = join_or_leave; + TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_join_leave_group, err); + API_MSG_VAR_FREE(msg); + + NETCONN_SET_SAFE_ERR(conn, err); + return err; +} +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +#if LWIP_DNS +/** + * Execute a DNS query, only one IP address is returned + * + * @param name a string representation of the DNS host name to query + * @param addr a preallocated ip_addr_t where to store the resolved IP address + * @return ERR_OK: resolving succeeded + * ERR_MEM: memory error, try again later + * ERR_ARG: dns client not initialized or invalid hostname + * ERR_VAL: dns server response was invalid + */ +err_t +netconn_gethostbyname(const char *name, ip_addr_t *addr) +{ + API_VAR_DECLARE(struct dns_api_msg, msg); +#if !LWIP_MPU_COMPATIBLE + sys_sem_t sem; +#endif /* LWIP_MPU_COMPATIBLE */ + err_t err; + + LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); + LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); +#if LWIP_MPU_COMPATIBLE + if (strlen(name) >= DNS_MAX_NAME_LENGTH) { + return ERR_ARG; + } +#endif + + API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg); +#if LWIP_MPU_COMPATIBLE + strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH-1); + API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH-1] = 0; +#else /* LWIP_MPU_COMPATIBLE */ + msg.err = &err; + msg.sem = &sem; + API_VAR_REF(msg).addr = API_VAR_REF(addr); + API_VAR_REF(msg).name = name; +#endif /* LWIP_MPU_COMPATIBLE */ + err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0); + if (err != ERR_OK) { + API_VAR_FREE(MEMP_DNS_API_MSG, msg); + return err; + } + + tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg)); + sys_sem_wait(API_EXPR_REF(API_VAR_REF(msg).sem)); + sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); + +#if LWIP_MPU_COMPATIBLE + *addr = msg->addr; + err = msg->err; +#endif /* LWIP_MPU_COMPATIBLE */ + + API_VAR_FREE(MEMP_DNS_API_MSG, msg); + return err; +} +#endif /* LWIP_DNS*/ + +#if LWIP_NETCONN_SEM_PER_THREAD +void netconn_thread_init(void) +{ + sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); + if (sem == SYS_SEM_NULL) { + /* call alloc only once */ + LWIP_NETCONN_THREAD_SEM_ALLOC(); + LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", LWIP_NETCONN_THREAD_SEM_GET() != SYS_SEM_NULL); + } +} + +void netconn_thread_cleanup(void) +{ + sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); + if (sem == SYS_SEM_NULL) { + /* call free only once */ + LWIP_NETCONN_THREAD_SEM_FREE(); + } +} +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +//Realtek add +err_t netconn_abort(struct netconn *conn) +{ + if (conn->acceptmbox != SYS_MBOX_NULL) { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + sys_mbox_post(conn->acceptmbox, NULL); + } + return ERR_OK; +} +//Realtek add end + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_msg.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_msg.c new file mode 100644 index 0000000..42a4f8e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/api_msg.c @@ -0,0 +1,1657 @@ +/** + * @file + * Sequential API Internal module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" + +#include "lwip/lwip_ip.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" + +#include "lwip/memp.h" +#include "lwip/tcpip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/mld6.h" + +#include + +#define SET_NONBLOCKING_CONNECT(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) +#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) + +/* forward declarations */ +#if LWIP_TCP +static err_t lwip_netconn_do_writemore(struct netconn *conn); +static void lwip_netconn_do_close_internal(struct netconn *conn); +#endif + +#if LWIP_RAW +/** + * Receive callback function for RAW netconns. + * Doesn't 'eat' the packet, only copies it and sends it to + * conn->recvmbox + * + * @see raw.h (struct raw_pcb.recv) for parameters and return value + */ +static u8_t +recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr) +{ + struct pbuf *q; + struct netbuf *buf; + struct netconn *conn; + + LWIP_UNUSED_ARG(addr); + conn = (struct netconn *)arg; + + if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) { +#if LWIP_SO_RCVBUF + int recv_avail; + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { + return 0; + } +#endif /* LWIP_SO_RCVBUF */ + /* copy the whole packet into new pbufs */ + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(q != NULL) { + if (pbuf_copy(q, p) != ERR_OK) { + pbuf_free(q); + q = NULL; + } + } + + if (q != NULL) { + u16_t len; + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(q); + return 0; + } + + buf->p = q; + buf->ptr = q; + ipX_addr_copy(PCB_ISIPV6(pcb), buf->addr, *ipX_current_src_addr()); + buf->port = pcb->protocol; + + len = q->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return 0; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + } + } + + return 0; /* do not eat the packet */ +} +#endif /* LWIP_RAW*/ + +#if LWIP_UDP +/** + * Receive callback function for UDP netconns. + * Posts the packet to conn->recvmbox or deletes it on memory error. + * + * @see udp.h (struct udp_pcb.recv) for parameters + */ +static void +recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port) +{ + struct netbuf *buf; + struct netconn *conn; + u16_t len; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ + LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_udp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); + +#if LWIP_SO_RCVBUF + SYS_ARCH_GET(conn->recv_avail, recv_avail); + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) || + ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { +#else /* LWIP_SO_RCVBUF */ + if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox)) { +#endif /* LWIP_SO_RCVBUF */ + pbuf_free(p); + return; + } + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf == NULL) { + pbuf_free(p); + return; + } else { + buf->p = p; + buf->ptr = p; + ipX_addr_set_ipaddr(ip_current_is_v6(), &buf->addr, addr); + buf->port = port; +#if LWIP_NETBUF_RECVINFO + { + /* get the UDP header - always in the first pbuf, ensured by udp_input */ + const struct udp_hdr* udphdr = ipX_next_header_ptr(); +#if LWIP_CHECKSUM_ON_COPY + buf->flags = NETBUF_FLAG_DESTADDR; +#endif /* LWIP_CHECKSUM_ON_COPY */ + ipX_addr_set(ip_current_is_v6(), &buf->toaddr, ipX_current_dest_addr()); + buf->toport_chksum = udphdr->dest; + } +#endif /* LWIP_NETBUF_RECVINFO */ + } + + len = p->tot_len; + if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } +} +#endif /* LWIP_UDP */ + +#if LWIP_TCP +/** + * Receive callback function for TCP netconns. + * Posts the packet to conn->recvmbox, but doesn't delete it on errors. + * + * @see tcp.h (struct tcp_pcb.recv) for parameters and return value + */ +static err_t +recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + struct netconn *conn; + u16_t len; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); + LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); + + if (!sys_mbox_valid(&conn->recvmbox)) { + /* recvmbox already deleted */ + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } + return ERR_OK; + } + /* Unlike for UDP or RAW pcbs, don't check for available space + using recv_avail since that could break the connection + (data is already ACKed) */ + + /* don't overwrite fatal errors! */ + NETCONN_SET_SAFE_ERR(conn, err); + + if (p != NULL) { + len = p->tot_len; + } else { + len = 0; + } + + if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { + /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ + return ERR_MEM; + } else { +#if LWIP_SO_RCVBUF + SYS_ARCH_INC(conn->recv_avail, len); +#endif /* LWIP_SO_RCVBUF */ + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); + } + + return ERR_OK; +} + +/** + * Poll callback function for TCP netconns. + * Wakes up an application thread that waits for a connection to close + * or data to be sent. The application thread then takes the + * appropriate action to go on. + * + * Signals the conn->sem. + * netconn_close waits for conn->sem if closing failed. + * + * @see tcp.h (struct tcp_pcb.poll) for parameters and return value + */ +static err_t +poll_tcp(void *arg, struct tcp_pcb *pcb) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + lwip_netconn_do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + lwip_netconn_do_close_internal(conn); + } + /* @todo: implement connect timeout here? */ + + /* Did a nonblocking write fail before? Then check available write-space. */ + if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + } + + return ERR_OK; +} + +/** + * Sent callback function for TCP netconns. + * Signals the conn->sem and calls API_EVENT. + * netconn_write waits for conn->sem if send buffer is low. + * + * @see tcp.h (struct tcp_pcb.sent) for parameters and return value + */ +static err_t +sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) +{ + struct netconn *conn = (struct netconn *)arg; + + LWIP_UNUSED_ARG(pcb); + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + if (conn->state == NETCONN_WRITE) { + lwip_netconn_do_writemore(conn); + } else if (conn->state == NETCONN_CLOSE) { + lwip_netconn_do_close_internal(conn); + } + + if (conn) { + /* If the queued byte- or pbuf-count drops below the configured low-water limit, + let select mark this pcb as writable again. */ + if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && + (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { + conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; + API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); + } + } + + return ERR_OK; +} + +/** + * Error callback function for TCP netconns. + * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. + * The application thread has then to decide what to do. + * + * @see tcp.h (struct tcp_pcb.err) for parameters + */ +static void +err_tcp(void *arg, err_t err) +{ + struct netconn *conn; + enum netconn_state old_state; + SYS_ARCH_DECL_PROTECT(lev); + + conn = (struct netconn *)arg; + LWIP_ASSERT("conn != NULL", (conn != NULL)); + + conn->pcb.tcp = NULL; + + /* no check since this is always fatal! */ + SYS_ARCH_PROTECT(lev); + conn->last_err = err; + SYS_ARCH_UNPROTECT(lev); + + /* reset conn->state now before waking up other threads */ + old_state = conn->state; + conn->state = NETCONN_NONE; + + /* @todo: the type of NETCONN_EVT created should depend on 'old_state' */ + + /* Notify the user layer about a connection error. Used to signal select. */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + /* Try to release selects pending on 'read' or 'write', too. + They will get an error if they actually try to read or write. */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + /* pass NULL-message to recvmbox to wake up pending recv */ + if (sys_mbox_valid(&conn->recvmbox)) { + /* use trypost to prevent deadlock */ + sys_mbox_trypost(&conn->recvmbox, NULL); + } + /* pass NULL-message to acceptmbox to wake up pending accept */ + if (sys_mbox_valid(&conn->acceptmbox)) { + /* use trypost to preven deadlock */ + sys_mbox_trypost(&conn->acceptmbox, NULL); + } + + if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || + (old_state == NETCONN_CONNECT)) { + /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary + since the pcb has already been deleted! */ + int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + + if (!was_nonblocking_connect) { + sys_sem_t* op_completed_sem; + /* set error return code */ + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + conn->current_msg->err = err; + op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + LWIP_ASSERT("inavlid op_completed_sem", op_completed_sem != SYS_SEM_NULL); + conn->current_msg = NULL; + /* wake up the waiting task */ + sys_sem_signal(op_completed_sem); + } + } else { + LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); + } +} + +/** + * Setup a tcp_pcb with the correct callback function pointers + * and their arguments. + * + * @param conn the TCP netconn to setup + */ +static void +setup_tcp(struct netconn *conn) +{ + struct tcp_pcb *pcb; + + pcb = conn->pcb.tcp; + tcp_arg(pcb, conn); + tcp_recv(pcb, recv_tcp); + tcp_sent(pcb, sent_tcp); + tcp_poll(pcb, poll_tcp, 4); + tcp_err(pcb, err_tcp); +} + +/** + * Accept callback function for TCP netconns. + * Allocates a new netconn and posts that to conn->acceptmbox. + * + * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value + */ +static err_t +accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + struct netconn *newconn; + struct netconn *conn = (struct netconn *)arg; + + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); + + if (!sys_mbox_valid(&conn->acceptmbox)) { + LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); + return ERR_VAL; + } + + /* We have to set the callback here even though + * the new socket is unknown. conn->socket is marked as -1. */ + newconn = netconn_alloc(conn->type, conn->callback); + if (newconn == NULL) { + return ERR_MEM; + } + newconn->pcb.tcp = newpcb; + setup_tcp(newconn); + /* no protection: when creating the pcb, the netconn is not yet known + to the application thread */ + newconn->last_err = err; + + if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { + /* When returning != ERR_OK, the pcb is aborted in tcp_process(), + so do nothing here! */ + /* remove all references to this netconn from the pcb */ + struct tcp_pcb* pcb = newconn->pcb.tcp; + tcp_arg(pcb, NULL); + tcp_recv(pcb, NULL); + tcp_sent(pcb, NULL); + tcp_poll(pcb, NULL, 4); + tcp_err(pcb, NULL); + /* remove reference from to the pcb from this netconn */ + newconn->pcb.tcp = NULL; + /* no need to drain since we know the recvmbox is empty. */ + sys_mbox_free(&newconn->recvmbox); + sys_mbox_set_invalid(&newconn->recvmbox); + netconn_free(newconn); + return ERR_MEM; + } else { + /* Register event with callback */ + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Create a new pcb of a specific type. + * Called from lwip_netconn_do_newconn(). + * + * @param msg the api_msg_msg describing the connection type + * @return msg->conn->err, but the return value is currently ignored + */ +static void +pcb_new(struct api_msg_msg *msg) +{ + LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); + + /* Allocate a PCB for this connection */ + switch(NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->conn->pcb.raw = raw_new(msg->msg.n.proto); + if(msg->conn->pcb.raw != NULL) { + raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); + } + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp = udp_new(); + if(msg->conn->pcb.udp != NULL) { +#if LWIP_UDPLITE + if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); + } +#endif /* LWIP_UDPLITE */ + if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { + udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); + } + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->conn->pcb.tcp = tcp_new(); + if(msg->conn->pcb.tcp != NULL) { + setup_tcp(msg->conn); + } + break; +#endif /* LWIP_TCP */ + default: + /* Unsupported netconn type, e.g. protocol disabled */ + msg->err = ERR_VAL; + return; + } + if (msg->conn->pcb.ip == NULL) { + msg->err = ERR_MEM; + } +#if LWIP_IPV6 + else { + if (NETCONNTYPE_ISIPV6(msg->conn->type)) { + ip_set_v6(msg->conn->pcb.ip, 1); + } + } +#endif /* LWIP_IPV6 */ +} + +/** + * Create a new pcb of a specific type inside a netconn. + * Called from netconn_new_with_proto_and_callback. + * + * @param msg the api_msg_msg describing the connection type + */ +void +lwip_netconn_do_newconn(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if (msg->conn->pcb.tcp == NULL) { + pcb_new(msg); + } + /* Else? This "new" connection already has a PCB allocated. */ + /* Is this an error condition? Should it be deleted? */ + /* We currently just are happy and return. */ + + TCPIP_APIMSG_ACK(msg); +} + +/** + * Create a new netconn (of a specific type) that has a callback function. + * The corresponding pcb is NOT created! + * + * @param t the type of 'connection' to create (@see enum netconn_type) + * @param proto the IP protocol for RAW IP pcbs + * @param callback a function to call on status changes (RX available, TX'ed) + * @return a newly allocated struct netconn or + * NULL on memory error + */ +struct netconn* +netconn_alloc(enum netconn_type t, netconn_callback callback) +{ + struct netconn *conn; + int size; + + conn = (struct netconn *)memp_malloc(MEMP_NETCONN); + if (conn == NULL) { + return NULL; + } + + conn->last_err = ERR_OK; + conn->type = t; + conn->pcb.tcp = NULL; + + /* If all sizes are the same, every compiler should optimize this switch to nothing */ + switch(NETCONNTYPE_GROUP(t)) { +#if LWIP_RAW + case NETCONN_RAW: + size = DEFAULT_RAW_RECVMBOX_SIZE; + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + size = DEFAULT_UDP_RECVMBOX_SIZE; + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + size = DEFAULT_TCP_RECVMBOX_SIZE; + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); + goto free_and_return; + } + + if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { + goto free_and_return; + } +#if !LWIP_NETCONN_SEM_PER_THREAD + if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { + sys_mbox_free(&conn->recvmbox); + goto free_and_return; + } +#endif + +#if LWIP_TCP + sys_mbox_set_invalid(&conn->acceptmbox); +#endif + conn->state = NETCONN_NONE; +#if LWIP_SOCKET + /* initialize socket to -1 since 0 is a valid socket */ + conn->socket = -1; +#endif /* LWIP_SOCKET */ + conn->callback = callback; +#if LWIP_TCP + conn->current_msg = NULL; + conn->write_offset = 0; +#endif /* LWIP_TCP */ +#if LWIP_SO_SNDTIMEO + conn->send_timeout = 0; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + conn->recv_timeout = 0; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; + conn->recv_avail = 0; +#endif /* LWIP_SO_RCVBUF */ + conn->flags = 0; + return conn; +free_and_return: + memp_free(MEMP_NETCONN, conn); + return NULL; +} + +/** + * Delete a netconn and all its resources. + * The pcb is NOT freed (since we might not be in the right thread context do this). + * + * @param conn the netconn to free + */ +void +netconn_free(struct netconn *conn) +{ + LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); + LWIP_ASSERT("recvmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->recvmbox)); +#if LWIP_TCP + LWIP_ASSERT("acceptmbox must be deallocated before calling this function", + !sys_mbox_valid(&conn->acceptmbox)); +#endif /* LWIP_TCP */ + +#if !LWIP_NETCONN_SEM_PER_THREAD + sys_sem_free(&conn->op_completed); + sys_sem_set_invalid(&conn->op_completed); +#endif + + memp_free(MEMP_NETCONN, conn); +} + +/** + * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in + * these mboxes + * + * @param conn the netconn to free + * @bytes_drained bytes drained from recvmbox + * @accepts_drained pending connections drained from acceptmbox + */ +static void +netconn_drain(struct netconn *conn) +{ + void *mem; +#if LWIP_TCP + struct pbuf *p; +#endif /* LWIP_TCP */ + + /* This runs in tcpip_thread, so we don't need to lock against rx packets */ + + /* Delete and drain the recvmbox. */ + if (sys_mbox_valid(&conn->recvmbox)) { + while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { +#if LWIP_TCP + if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { + if(mem != NULL) { + p = (struct pbuf*)mem; + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_recved(conn->pcb.tcp, p->tot_len); + } + pbuf_free(p); + } + } else +#endif /* LWIP_TCP */ + { + netbuf_delete((struct netbuf *)mem); + } + } + sys_mbox_free(&conn->recvmbox); + sys_mbox_set_invalid(&conn->recvmbox); + } + + /* Delete and drain the acceptmbox. */ +#if LWIP_TCP + if (sys_mbox_valid(&conn->acceptmbox)) { + while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { + struct netconn *newconn = (struct netconn *)mem; + /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ + /* pcb might be set to NULL already by err_tcp() */ + if (conn->pcb.tcp != NULL) { + tcp_accepted(conn->pcb.tcp); + } + /* drain recvmbox */ + netconn_drain(newconn); + if (newconn->pcb.tcp != NULL) { + tcp_abort(newconn->pcb.tcp); + newconn->pcb.tcp = NULL; + } + netconn_free(newconn); + } + sys_mbox_free(&conn->acceptmbox); + sys_mbox_set_invalid(&conn->acceptmbox); + } +#endif /* LWIP_TCP */ +} + +#if LWIP_TCP +/** + * Internal helper function to close a TCP netconn: since this sometimes + * doesn't work at the first attempt, this function is called from multiple + * places. + * + * @param conn the TCP netconn to close + */ +static void +lwip_netconn_do_close_internal(struct netconn *conn) +{ + err_t err; + u8_t shut, shut_rx, shut_tx, close; + struct tcp_pcb* tpcb = conn->pcb.tcp; + + LWIP_ASSERT("invalid conn", (conn != NULL)); + LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); + LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); + LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + + shut = conn->current_msg->msg.sd.shut; + shut_rx = shut & NETCONN_SHUT_RD; + shut_tx = shut & NETCONN_SHUT_WR; + /* shutting down both ends is the same as closing + (also if RD or WR side was shut down before already) */ + if (shut == NETCONN_SHUT_RDWR) { + close = 1; + } else if (shut_rx && + ((tpcb->state == FIN_WAIT_1) || + (tpcb->state == FIN_WAIT_2) || + (tpcb->state == CLOSING))) { + close = 1; + } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) { + close = 1; + } else { + close = 0; + } + + /* Set back some callback pointers */ + if (close) { + tcp_arg(tpcb, NULL); + } + if (tpcb->state == LISTEN) { + tcp_accept(tpcb, NULL); + } else { + /* some callbacks have to be reset if tcp_close is not successful */ + if (shut_rx) { + tcp_recv(tpcb, NULL); + tcp_accept(tpcb, NULL); + } + if (shut_tx) { + tcp_sent(tpcb, NULL); + } + if (close) { + tcp_poll(tpcb, NULL, 4); + tcp_err(tpcb, NULL); + } + } + /* Try to close the connection */ + if (close) { + err = tcp_close(tpcb); + } else { + err = tcp_shutdown(tpcb, shut_rx, shut_tx); + } + if (err == ERR_OK) { + /* Closing succeeded */ + sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + conn->current_msg->err = ERR_OK; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (close) { + /* Set back some callback pointers as conn is going away */ + conn->pcb.tcp = NULL; + /* Trigger select() in socket layer. Make sure everybody notices activity + on the connection, error first! */ + API_EVENT(conn, NETCONN_EVT_ERROR, 0); + } + if (shut_rx) { + API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); + } + if (shut_tx) { + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + } + /* wake up the application task */ + sys_sem_signal(op_completed_sem); + } else { + /* Closing failed, restore some of the callbacks */ + /* Closing of listen pcb will never fail! */ + LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); + tcp_sent(conn->pcb.tcp, sent_tcp); + tcp_poll(conn->pcb.tcp, poll_tcp, 4); + tcp_err(conn->pcb.tcp, err_tcp); + tcp_arg(conn->pcb.tcp, conn); + /* don't restore recv callback: we don't want to receive any more data */ + } + /* If closing didn't succeed, we get called again either + from poll_tcp or from sent_tcp */ +} +#endif /* LWIP_TCP */ + +/** + * Delete the pcb inside a netconn. + * Called from netconn_delete. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_delconn(struct api_msg_msg *msg) +{ + /* @todo TCP: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && + (msg->conn->state != NETCONN_LISTEN) && + (msg->conn->state != NETCONN_CONNECT)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", + NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else { + LWIP_ASSERT("blocking connect in progress", + (msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); + msg->err = ERR_OK; + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + + if (msg->conn->pcb.tcp != NULL) { + + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + raw_remove(msg->conn->pcb.raw); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->conn->pcb.udp->recv_arg = NULL; + udp_remove(msg->conn->pcb.udp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->msg.sd.shut = NETCONN_SHUT_RDWR; + msg->conn->current_msg = msg; + lwip_netconn_do_close_internal(msg->conn); + /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing + the application thread, so we can return at this point! */ + return; +#endif /* LWIP_TCP */ + default: + break; + } + msg->conn->pcb.tcp = NULL; + } + /* tcp netconns don't come here! */ + + /* @todo: this lets select make the socket readable and writable, + which is wrong! errfd instead? */ + API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); + API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); + } + if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) { + sys_sem_signal(LWIP_API_MSG_SEM(msg)); + } +} + +/** + * Bind a pcb contained in a netconn + * Called from netconn_bind. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to bind to + */ +void +lwip_netconn_do_bind(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_VAL; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; +#endif /* LWIP_TCP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * TCP callback function if a connection (opened by tcp_connect/lwip_netconn_do_connect) has + * been established (or reset by the remote host). + * + * @see tcp.h (struct tcp_pcb.connected) for parameters and return values + */ +static err_t +lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) +{ + struct netconn *conn; + int was_blocking; + sys_sem_t* op_completed_sem = NULL; + + LWIP_UNUSED_ARG(pcb); + + conn = (struct netconn *)arg; + + if (conn == NULL) { + return ERR_VAL; + } + + LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); + LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", + (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); + + if (conn->current_msg != NULL) { + conn->current_msg->err = err; + op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + } + if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) { + setup_tcp(conn); + } + was_blocking = !IN_NONBLOCKING_CONNECT(conn); + SET_NONBLOCKING_CONNECT(conn, 0); + LWIP_ASSERT("blocking connect state error", + (was_blocking && op_completed_sem != NULL) || + (!was_blocking && op_completed_sem == NULL)); + conn->current_msg = NULL; + conn->state = NETCONN_NONE; + if (!was_blocking) { + NETCONN_SET_SAFE_ERR(conn, ERR_OK); + } + API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); + + if (was_blocking) { + sys_sem_signal(op_completed_sem); + } + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Connect a pcb contained inside a netconn + * Called from netconn_connect. + * + * @param msg the api_msg_msg pointing to the connection and containing + * the IP address and port to connect to + */ +void +lwip_netconn_do_connect(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.tcp == NULL) { + /* This may happen when calling netconn_connect() a second time */ + msg->err = ERR_CLSD; + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { + /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ + sys_sem_signal(LWIP_API_MSG_SEM(msg)); + return; + } + } else { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + /* Prevent connect while doing any other action. */ + if (msg->conn->state != NETCONN_NONE) { + msg->err = ERR_ISCONN; + } else { + setup_tcp(msg->conn); + msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), + msg->msg.bc.port, lwip_netconn_do_connected); + if (msg->err == ERR_OK) { + u8_t non_blocking = netconn_is_nonblocking(msg->conn); + msg->conn->state = NETCONN_CONNECT; + SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); + if (non_blocking) { + msg->err = ERR_INPROGRESS; + } else { + msg->conn->current_msg = msg; + /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), + * when the connection is established! */ + return; + } + } + } + /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ + sys_sem_signal(LWIP_API_MSG_SEM(msg)); + return; +#endif /* LWIP_TCP */ + default: + LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); + break; + } + } + /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), + so use TCPIP_APIMSG_ACK() here. */ + TCPIP_APIMSG_ACK(msg); +} + +/** + * Connect a pcb contained inside a netconn + * Only used for UDP netconns. + * Called from netconn_disconnect. + * + * @param msg the api_msg_msg pointing to the connection to disconnect + */ +void +lwip_netconn_do_disconnect(struct api_msg_msg *msg) +{ +#if LWIP_UDP + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { + udp_disconnect(msg->conn->pcb.udp); + msg->err = ERR_OK; + } else +#endif /* LWIP_UDP */ + { + msg->err = ERR_VAL; + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Set a TCP pcb contained in a netconn into listen mode + * Called from netconn_listen. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_listen(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL_LISTENCONNECT(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { + if (msg->conn->state == NETCONN_NONE) { + struct tcp_pcb* lpcb; + if (msg->conn->pcb.tcp->state != CLOSED) { + /* connection is not closed, cannot listen */ + msg->err = ERR_VAL; + } else { +#if LWIP_IPV6 + if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { +#if TCP_LISTEN_BACKLOG + lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + lpcb = tcp_listen_dual(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + } else +#endif /* LWIP_IPV6 */ + { +#if TCP_LISTEN_BACKLOG + lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); +#else /* TCP_LISTEN_BACKLOG */ + lpcb = tcp_listen(msg->conn->pcb.tcp); +#endif /* TCP_LISTEN_BACKLOG */ + } + if (lpcb == NULL) { + /* in this case, the old pcb is still allocated */ + msg->err = ERR_MEM; + } else { + /* delete the recvmbox and allocate the acceptmbox */ + if (sys_mbox_valid(&msg->conn->recvmbox)) { + /** @todo: should we drain the recvmbox here? */ + sys_mbox_free(&msg->conn->recvmbox); + sys_mbox_set_invalid(&msg->conn->recvmbox); + } + msg->err = ERR_OK; + if (!sys_mbox_valid(&msg->conn->acceptmbox)) { + msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); + } + if (msg->err == ERR_OK) { + msg->conn->state = NETCONN_LISTEN; + msg->conn->pcb.tcp = lpcb; + tcp_arg(msg->conn->pcb.tcp, msg->conn); + tcp_accept(msg->conn->pcb.tcp, accept_function); + } else { + /* since the old pcb is already deallocated, free lpcb now */ + tcp_close(lpcb); + msg->conn->pcb.tcp = NULL; + } + } + } + } + } else { + msg->err = ERR_ARG; + } + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a RAW or UDP pcb contained in a netconn + * Called from netconn_send + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_send(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + msg->err = ERR_CONN; + if (msg->conn->pcb.tcp != NULL) { + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { + msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); + } else { + msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr)); + } + break; +#endif +#if LWIP_UDP + case NETCONN_UDP: +#if LWIP_CHECKSUM_ON_COPY + if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { + msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } else { + msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, + ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port, + msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); + } +#else /* LWIP_CHECKSUM_ON_COPY */ + if (ipX_addr_isany(PCB_ISIPV6(msg->conn->pcb.ip), &msg->msg.b->addr)) { + msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); + } else { + msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, ipX_2_ip(&msg->msg.b->addr), msg->msg.b->port); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + break; +#endif /* LWIP_UDP */ + default: + break; + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +#if LWIP_TCP +/** + * Indicate data has been received from a TCP pcb contained in a netconn + * Called from netconn_recv + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_recv(struct api_msg_msg *msg) +{ + msg->err = ERR_OK; + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { +#if TCP_LISTEN_BACKLOG + if (msg->conn->pcb.tcp->state == LISTEN) { + tcp_accepted(msg->conn->pcb.tcp); + } else +#endif /* TCP_LISTEN_BACKLOG */ + { + u32_t remaining = msg->msg.r.len; + do { + u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; + tcp_recved(msg->conn->pcb.tcp, recved); + remaining -= recved; + }while(remaining != 0); + } + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * See if more data needs to be written from a previous call to netconn_write. + * Called initially from lwip_netconn_do_write. If the first call can't send all data + * (because of low memory or empty send-buffer), this function is called again + * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the + * blocking application thread (waiting in netconn_write) is released. + * + * @param conn netconn (that is currently in state NETCONN_WRITE) to process + * @return ERR_OK + * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished + */ +static err_t +lwip_netconn_do_writemore(struct netconn *conn) +{ + err_t err; + void *dataptr; + u16_t len, available; + u8_t write_finished = 0; + size_t diff; + u8_t dontblock; + u8_t apiflags; + + LWIP_ASSERT("conn != NULL", conn != NULL); + LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); + LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); + LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); + LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", + conn->write_offset < conn->current_msg->msg.w.len); + + dontblock = netconn_is_nonblocking(conn) || + (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK); + apiflags = conn->current_msg->msg.w.apiflags; + +#if LWIP_SO_SNDTIMEO + if ((conn->send_timeout != 0) && + ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { + write_finished = 1; + if (conn->write_offset == 0) { + /* nothing has been written */ + err = ERR_WOULDBLOCK; + conn->current_msg->msg.w.len = 0; + } else { + /* partial write */ + err = ERR_OK; + conn->current_msg->msg.w.len = conn->write_offset; + conn->write_offset = 0; + } + } else +#endif /* LWIP_SO_SNDTIMEO */ + { + dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; + diff = conn->current_msg->msg.w.len - conn->write_offset; + if (diff > 0xffffUL) { /* max_u16_t */ + len = 0xffff; +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } else { + len = (u16_t)diff; + } + available = tcp_sndbuf(conn->pcb.tcp); + if (available < len) { + /* don't try to write more than sendbuf */ + len = available; + if (dontblock) { + if (!len) { + err = ERR_WOULDBLOCK; + goto err_mem; + } + } else { +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + apiflags |= TCP_WRITE_FLAG_MORE; + } + } + LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); + err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); + /* if OK or memory error, check available space */ + if ((err == ERR_OK) || (err == ERR_MEM)) { +err_mem: + if (dontblock && (len < conn->current_msg->msg.w.len)) { + /* non-blocking write did not write everything: mark the pcb non-writable + and let poll_tcp check writable space to mark the pcb writable again */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; + } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || + (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { + /* The queued byte- or pbuf-count exceeds the configured low-water limit, + let select mark this pcb as non-writable. */ + API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); + } + } + + if (err == ERR_OK) { + conn->write_offset += len; + if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { + /* return sent length */ + conn->current_msg->msg.w.len = conn->write_offset; + /* everything was written */ + write_finished = 1; + conn->write_offset = 0; + } + tcp_output(conn->pcb.tcp); + } else if ((err == ERR_MEM) && !dontblock) { + /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called + we do NOT return to the application thread, since ERR_MEM is + only a temporary error! */ + + /* tcp_write returned ERR_MEM, try tcp_output anyway */ + tcp_output(conn->pcb.tcp); + +#if LWIP_TCPIP_CORE_LOCKING + conn->flags |= NETCONN_FLAG_WRITE_DELAYED; +#endif + } else { + /* On errors != ERR_MEM, we don't try writing any more but return + the error to the application thread. */ + write_finished = 1; + conn->current_msg->msg.w.len = 0; + } + } + if (write_finished) { + /* everything was written: set back connection state + and back to application task */ + sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); + conn->current_msg->err = err; + conn->current_msg = NULL; + conn->state = NETCONN_NONE; +#if LWIP_TCPIP_CORE_LOCKING + if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0) +#endif + { + sys_sem_signal(op_completed_sem); + } + } +#if LWIP_TCPIP_CORE_LOCKING + else { + return ERR_MEM; + } +#endif + return ERR_OK; +} +#endif /* LWIP_TCP */ + +/** + * Send some data on a TCP pcb contained in a netconn + * Called from netconn_write + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_write(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { +#if LWIP_TCP + if (msg->conn->state != NETCONN_NONE) { + /* netconn is connecting, closing or in blocking write */ + msg->err = ERR_INPROGRESS; + } else if (msg->conn->pcb.tcp != NULL) { + msg->conn->state = NETCONN_WRITE; + /* set all the variables used by lwip_netconn_do_writemore */ + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); + msg->conn->current_msg = msg; + msg->conn->write_offset = 0; +#if LWIP_TCPIP_CORE_LOCKING + msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; + if (lwip_netconn_do_writemore(msg->conn) != ERR_OK) { + LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); + UNLOCK_TCPIP_CORE(); + sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); + LOCK_TCPIP_CORE(); + LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + lwip_netconn_do_writemore(msg->conn); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG + since lwip_netconn_do_writemore ACKs it! */ + return; + } else { + msg->err = ERR_CONN; + } +#else /* LWIP_TCP */ + msg->err = ERR_VAL; +#endif /* LWIP_TCP */ +#if (LWIP_UDP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Return a connection's local or remote address + * Called from netconn_getaddr + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_getaddr(struct api_msg_msg *msg) +{ + if (msg->conn->pcb.ip != NULL) { + if (msg->msg.ad.local) { + ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->local_ip); + } else { + ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), + msg->conn->pcb.ip->remote_ip); + } + msg->err = ERR_OK; + switch (NETCONNTYPE_GROUP(msg->conn->type)) { +#if LWIP_RAW + case NETCONN_RAW: + if (msg->msg.ad.local) { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; + } else { + /* return an error as connecting is only a helper for upper layers */ + msg->err = ERR_CONN; + } + break; +#endif /* LWIP_RAW */ +#if LWIP_UDP + case NETCONN_UDP: + if (msg->msg.ad.local) { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; + } else { + if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { + msg->err = ERR_CONN; + } else { + API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; + } + } + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case NETCONN_TCP: + if ((msg->msg.ad.local == 0) && + ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) { + /* pcb is not connected and remote name is requested */ + msg->err = ERR_CONN; + } else { + API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); + } + break; +#endif /* LWIP_TCP */ + default: + LWIP_ASSERT("invalid netconn_type", 0); + break; + } + } else { + msg->err = ERR_CONN; + } + TCPIP_APIMSG_ACK(msg); +} + +/** + * Close or half-shutdown a TCP pcb contained in a netconn + * Called from netconn_close + * In contrast to closing sockets, the netconn is not deallocated. + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_close(struct api_msg_msg *msg) +{ +#if LWIP_TCP + /* @todo: abort running write/connect? */ + if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) { + /* this only happens for TCP netconns */ + LWIP_ASSERT("NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP", + NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP); + msg->err = ERR_INPROGRESS; + } else if ((msg->conn->pcb.tcp != NULL) && (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)) { + if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) { + /* LISTEN doesn't support half shutdown */ + msg->err = ERR_CONN; + } else { + if (msg->msg.sd.shut & NETCONN_SHUT_RD) { + /* Drain and delete mboxes */ + netconn_drain(msg->conn); + } + LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && + msg->conn->write_offset == 0); + msg->conn->state = NETCONN_CLOSE; + msg->conn->current_msg = msg; + lwip_netconn_do_close_internal(msg->conn); + /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ + return; + } + } else +#endif /* LWIP_TCP */ + { + msg->err = ERR_CONN; + } + sys_sem_signal(LWIP_API_MSG_SEM(msg)); +} + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +/** + * Join multicast groups for UDP netconns. + * Called from netconn_join_leave_group + * + * @param msg the api_msg_msg pointing to the connection + */ +void +lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) +{ + if (ERR_IS_FATAL(msg->conn->last_err)) { + msg->err = msg->conn->last_err; + } else { + if (msg->conn->pcb.tcp != NULL) { + if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { +#if LWIP_UDP +#if LWIP_IPV6 && LWIP_IPV6_MLD + if (PCB_ISIPV6(msg->conn->pcb.udp)) { + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); + } + } + else +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + { +#if LWIP_IGMP + if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { + msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); + } else { + msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), + ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); + } +#endif /* LWIP_IGMP */ + } +#endif /* LWIP_UDP */ +#if (LWIP_TCP || LWIP_RAW) + } else { + msg->err = ERR_VAL; +#endif /* (LWIP_TCP || LWIP_RAW) */ + } + } else { + msg->err = ERR_CONN; + } + } + TCPIP_APIMSG_ACK(msg); +} +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +#if LWIP_DNS +/** + * Callback function that is called when DNS name is resolved + * (or on timeout). A waiting application thread is waked up by + * signaling the semaphore. + */ +static void +lwip_netconn_do_dns_found(const char *name, ip_addr_t *ipaddr, void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + /* we trust the internal implementation to be correct :-) */ + LWIP_UNUSED_ARG(name); + + if (ipaddr == NULL) { + /* timeout or memory error */ + API_EXPR_DEREF(msg->err) = ERR_VAL; + } else { + /* address was resolved */ + API_EXPR_DEREF(msg->err) = ERR_OK; + API_EXPR_DEREF(msg->addr) = *ipaddr; + } + /* wake up the application task waiting in netconn_gethostbyname */ + sys_sem_signal(API_EXPR_REF(msg->sem)); +} + +/** + * Execute a DNS query + * Called from netconn_gethostbyname + * + * @param arg the dns_api_msg pointing to the query + */ +void +lwip_netconn_do_gethostbyname(void *arg) +{ + struct dns_api_msg *msg = (struct dns_api_msg*)arg; + + API_EXPR_DEREF(msg->err) = dns_gethostbyname(msg->name, API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg); + if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { + /* on error or immediate success, wake up the application + * task waiting in netconn_gethostbyname */ + sys_sem_signal(API_EXPR_REF(msg->sem)); + } +} +#endif /* LWIP_DNS */ + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/err.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/err.c new file mode 100644 index 0000000..e970101 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/err.c @@ -0,0 +1,75 @@ +/** + * @file + * Error Management module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/err.h" + +#ifdef LWIP_DEBUG + +static const char *err_strerr[] = { + "Ok.", /* ERR_OK 0 */ + "Out of memory error.", /* ERR_MEM -1 */ + "Buffer error.", /* ERR_BUF -2 */ + "Timeout.", /* ERR_TIMEOUT -3 */ + "Routing problem.", /* ERR_RTE -4 */ + "Operation in progress.", /* ERR_INPROGRESS -5 */ + "Illegal value.", /* ERR_VAL -6 */ + "Operation would block.", /* ERR_WOULDBLOCK -7 */ + "Address in use.", /* ERR_USE -8 */ + "Already connected.", /* ERR_ISCONN -9 */ + "Not connected.", /* ERR_CONN -10 */ + "Connection aborted.", /* ERR_ABRT -11 */ + "Connection reset.", /* ERR_RST -12 */ + "Connection closed.", /* ERR_CLSD -13 */ + "Illegal argument.", /* ERR_ARG -14 */ + "Low-level netif error.", /* ERR_IF -15 */ +}; + +/** + * Convert an lwip internal error to a string representation. + * + * @param err an lwip internal err_t + * @return a string representation for err + */ +const char * +lwip_strerr(err_t err) +{ + return err_strerr[-err]; + +} + +#endif /* LWIP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netbuf.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netbuf.c new file mode 100644 index 0000000..4a417b0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netbuf.c @@ -0,0 +1,245 @@ +/** + * @file + * Network buffer management + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netbuf.h" +#include "lwip/memp.h" + +#include + +/** + * Create (allocate) and initialize a new netbuf. + * The netbuf doesn't yet contain a packet buffer! + * + * @return a pointer to a new netbuf + * NULL on lack of memory + */ +struct +netbuf *netbuf_new(void) +{ + struct netbuf *buf; + + buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); + if (buf != NULL) { + buf->p = NULL; + buf->ptr = NULL; + ipX_addr_set_any(LWIP_IPV6, &buf->addr); + buf->port = 0; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + buf->flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + buf->toport_chksum = 0; +#if LWIP_NETBUF_RECVINFO + ipX_addr_set_any(LWIP_IPV6, &buf->toaddr); +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ + return buf; + } else { + return NULL; + } +} + +/** + * Deallocate a netbuf allocated by netbuf_new(). + * + * @param buf pointer to a netbuf allocated by netbuf_new() + */ +void +netbuf_delete(struct netbuf *buf) +{ + if (buf != NULL) { + if (buf->p != NULL) { + pbuf_free(buf->p); + buf->p = buf->ptr = NULL; + } + memp_free(MEMP_NETBUF, buf); + } +} + +/** + * Allocate memory for a packet buffer for a given netbuf. + * + * @param buf the netbuf for which to allocate a packet buffer + * @param size the size of the packet buffer to allocate + * @return pointer to the allocated memory + * NULL if no memory could be allocated + */ +void * +netbuf_alloc(struct netbuf *buf, u16_t size) +{ + LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); + + /* Deallocate any previously allocated memory. */ + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); + if (buf->p == NULL) { + return NULL; + } + LWIP_ASSERT("check that first pbuf can hold size", + (buf->p->len >= size)); + buf->ptr = buf->p; + return buf->p->payload; +} + +/** + * Free the packet buffer included in a netbuf + * + * @param buf pointer to the netbuf which contains the packet buffer to free + */ +void +netbuf_free(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = buf->ptr = NULL; +} + +/** + * Let a netbuf reference existing (non-volatile) data. + * + * @param buf netbuf which should reference the data + * @param dataptr pointer to the data to reference + * @param size size of the data + * @return ERR_OK if data is referenced + * ERR_MEM if data couldn't be referenced due to lack of memory + */ +err_t +netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) +{ + LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); + if (buf->p != NULL) { + pbuf_free(buf->p); + } + buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (buf->p == NULL) { + buf->ptr = NULL; + return ERR_MEM; + } + buf->p->payload = (void*)dataptr; + buf->p->len = buf->p->tot_len = size; + buf->ptr = buf->p; + return ERR_OK; +} + +/** + * Chain one netbuf to another (@see pbuf_chain) + * + * @param head the first netbuf + * @param tail netbuf to chain after head, freed by this function, may not be reference after returning + */ +void +netbuf_chain(struct netbuf *head, struct netbuf *tail) +{ + LWIP_ERROR("netbuf_ref: invalid head", (head != NULL), return;); + LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); + pbuf_cat(head->p, tail->p); + head->ptr = head->p; + memp_free(MEMP_NETBUF, tail); +} + +/** + * Get the data pointer and length of the data inside a netbuf. + * + * @param buf netbuf to get the data from + * @param dataptr pointer to a void pointer where to store the data pointer + * @param len pointer to an u16_t where the length of the data is stored + * @return ERR_OK if the information was retrieved, + * ERR_BUF on error. + */ +err_t +netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) +{ + LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); + LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); + + if (buf->ptr == NULL) { + return ERR_BUF; + } + *dataptr = buf->ptr->payload; + *len = buf->ptr->len; + return ERR_OK; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the next part. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + * @return -1 if there is no next part + * 1 if moved to the next part but now there is no next part + * 0 if moved to the next part and there are still more parts + */ +s8_t +netbuf_next(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return -1;); + if (buf->ptr->next == NULL) { + return -1; + } + buf->ptr = buf->ptr->next; + if (buf->ptr->next == NULL) { + return 1; + } + return 0; +} + +/** + * Move the current data pointer of a packet buffer contained in a netbuf + * to the beginning of the packet. + * The packet buffer itself is not modified. + * + * @param buf the netbuf to modify + */ +void +netbuf_first(struct netbuf *buf) +{ + LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); + buf->ptr = buf->p; +} + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netdb.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netdb.c new file mode 100644 index 0000000..ad93944 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netdb.c @@ -0,0 +1,349 @@ +/** + * @file + * API functions for name resolving + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/netdb.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include "lwip/err.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/api.h" +#include "lwip/dns.h" + +#include +#include + +/** helper struct for gethostbyname_r to access the char* buffer */ +struct gethostbyname_r_helper { + ip_addr_t *addr_list[2]; + ip_addr_t addr; + char *aliases; +}; + +/** h_errno is exported in netdb.h for access by applications. */ +#if LWIP_DNS_API_DECLARE_H_ERRNO +int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ + +/** define "hostent" variables storage: 0 if we use a static (but unprotected) + * set of variables for lwip_gethostbyname, 1 if we use a local storage */ +#ifndef LWIP_DNS_API_HOSTENT_STORAGE +#define LWIP_DNS_API_HOSTENT_STORAGE 0 +#endif + +/** define "hostent" variables storage */ +#if LWIP_DNS_API_HOSTENT_STORAGE +#define HOSTENT_STORAGE +#else +#define HOSTENT_STORAGE static +#endif /* LWIP_DNS_API_STATIC_HOSTENT */ + +/** + * Returns an entry containing addresses of address family AF_INET + * for the host with name name. + * Due to dns_gethostbyname limitations, only one address is returned. + * + * @param name the hostname to resolve + * @return an entry containing addresses of address family AF_INET + * for the host with name name + */ +struct hostent* +lwip_gethostbyname(const char *name) +{ + err_t err; + ip_addr_t addr; + + /* buffer variables for lwip_gethostbyname() */ + HOSTENT_STORAGE struct hostent s_hostent; + HOSTENT_STORAGE char *s_aliases; + HOSTENT_STORAGE ip_addr_t s_hostent_addr; + HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; + + /* query host IP address */ + err = netconn_gethostbyname(name, &addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + h_errno = HOST_NOT_FOUND; + return NULL; + } + + /* fill hostent */ + s_hostent_addr = addr; + s_phostent_addr[0] = &s_hostent_addr; + s_phostent_addr[1] = NULL; + s_hostent.h_name = (char*)name; + s_aliases = NULL; + s_hostent.h_aliases = &s_aliases; + s_hostent.h_addrtype = AF_INET; + s_hostent.h_length = sizeof(ip_addr_t); + s_hostent.h_addr_list = (char**)&s_phostent_addr; + +#if DNS_DEBUG + /* dump hostent */ + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", s_hostent.h_aliases)); + /* h_aliases are always empty */ + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", s_hostent.h_addr_list)); + if (s_hostent.h_addr_list != NULL) { + u8_t idx; + for ( idx=0; s_hostent.h_addr_list[idx]; idx++) { + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); + LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ip_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx]))); + } + } +#endif /* DNS_DEBUG */ + +#if LWIP_DNS_API_HOSTENT_STORAGE + /* this function should return the "per-thread" hostent after copy from s_hostent */ + return sys_thread_hostent(&s_hostent); +#else + return &s_hostent; +#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ +} + +/** + * Thread-safe variant of lwip_gethostbyname: instead of using a static + * buffer, this function takes buffer and errno pointers as arguments + * and uses these for the result. + * + * @param name the hostname to resolve + * @param ret pre-allocated struct where to store the result + * @param buf pre-allocated buffer where to store additional data + * @param buflen the size of buf + * @param result pointer to a hostent pointer that is set to ret on success + * and set to zero on error + * @param h_errnop pointer to an int where to store errors (instead of modifying + * the global h_errno) + * @return 0 on success, non-zero on error, additional error information + * is stored in *h_errnop instead of h_errno to be thread-safe + */ +int +lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop) +{ + err_t err; + struct gethostbyname_r_helper *h; + char *hostname; + size_t namelen; + int lh_errno; + + if (h_errnop == NULL) { + /* ensure h_errnop is never NULL */ + h_errnop = &lh_errno; + } + + if (result == NULL) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + /* first thing to do: set *result to nothing */ + *result = NULL; + if ((name == NULL) || (ret == NULL) || (buf == NULL)) { + /* not all arguments given */ + *h_errnop = EINVAL; + return -1; + } + + namelen = strlen(name); + if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { + /* buf can't hold the data needed + a copy of name */ + *h_errnop = ERANGE; + return -1; + } + + h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); + hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); + + /* query host IP address */ + err = netconn_gethostbyname(name, &h->addr); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); + *h_errnop = HOST_NOT_FOUND; + return -1; + } + + /* copy the hostname into buf */ + MEMCPY(hostname, name, namelen); + hostname[namelen] = 0; + + /* fill hostent */ + h->addr_list[0] = &h->addr; + h->addr_list[1] = NULL; + h->aliases = NULL; + ret->h_name = hostname; + ret->h_aliases = &h->aliases; + ret->h_addrtype = AF_INET; + ret->h_length = sizeof(ip_addr_t); + ret->h_addr_list = (char**)&h->addr_list; + + /* set result != NULL */ + *result = ret; + + /* return success */ + return 0; +} + +/** + * Frees one or more addrinfo structures returned by getaddrinfo(), along with + * any additional storage associated with those structures. If the ai_next field + * of the structure is not null, the entire list of structures is freed. + * + * @param ai struct addrinfo to free + */ +void +lwip_freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + while (ai != NULL) { + next = ai->ai_next; + memp_free(MEMP_NETDB, ai); + ai = next; + } +} + +/** + * Translates the name of a service location (for example, a host name) and/or + * a service name and returns a set of socket addresses and associated + * information to be used in creating a socket with which to address the + * specified service. + * Memory for the result is allocated internally and must be freed by calling + * lwip_freeaddrinfo()! + * + * Due to a limitation in dns_gethostbyname, only the first address of a + * host is returned. + * Also, service names are not supported (only port numbers)! + * + * @param nodename descriptive name or address string of the host + * (may be NULL -> local address) + * @param servname port number as string of NULL + * @param hints structure containing input values that set socktype and protocol + * @param res pointer to a pointer where to store the result (set to NULL on failure) + * @return 0 on success, non-zero on failure + */ +int +lwip_getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + err_t err; + ip_addr_t addr; + struct addrinfo *ai; + struct sockaddr_in *sa = NULL; + int port_nr = 0; + size_t total_size; + size_t namelen = 0; + + if (res == NULL) { + return EAI_FAIL; + } + *res = NULL; + if ((nodename == NULL) && (servname == NULL)) { + return EAI_NONAME; + } + + if (hints != NULL) { + if ((hints->ai_family != AF_UNSPEC) && (hints->ai_family != AF_INET)) { + return EAI_FAMILY; + } + } + + if (servname != NULL) { + /* service name specified: convert to port number + * @todo?: currently, only ASCII integers (port numbers) are supported! */ + port_nr = atoi(servname); + if ((port_nr <= 0) || (port_nr > 0xffff)) { + return EAI_SERVICE; + } + } + + if (nodename != NULL) { + /* service location specified, try to resolve */ + err = netconn_gethostbyname(nodename, &addr); + if (err != ERR_OK) { + return EAI_FAIL; + } + } else { + /* service location specified, use loopback address */ + ip_addr_set_loopback(&addr); + } + + total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_in); + if (nodename != NULL) { + namelen = strlen(nodename); + LWIP_ASSERT("namelen is too long", (namelen + 1) <= (mem_size_t)-1); + total_size += namelen + 1; + } + /* If this fails, please report to lwip-devel! :-) */ + LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", + total_size <= NETDB_ELEM_SIZE); + ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); + if (ai == NULL) { + return EAI_MEMORY; + } + memset(ai, 0, total_size); + sa = (struct sockaddr_in*)((u8_t*)ai + sizeof(struct addrinfo)); + /* set up sockaddr */ + inet_addr_from_ipaddr(&sa->sin_addr, &addr); + sa->sin_family = AF_INET; + sa->sin_len = sizeof(struct sockaddr_in); + sa->sin_port = htons((u16_t)port_nr); + + /* set up addrinfo */ + ai->ai_family = AF_INET; + if (hints != NULL) { + /* copy socktype & protocol from hints if specified */ + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + if (nodename != NULL) { + /* copy nodename to canonname if specified */ + ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + MEMCPY(ai->ai_canonname, nodename, namelen); + ai->ai_canonname[namelen] = 0; + } + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr = (struct sockaddr*)sa; + + *res = ai; + + return 0; +} + +#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netifapi.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netifapi.c new file mode 100644 index 0000000..715d515 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/netifapi.c @@ -0,0 +1,204 @@ +/** + * @file + * Network Interface Sequential API module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netifapi.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" + +#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) +#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) +#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name) +#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) + +/** + * Call netif_add() inside the tcpip_thread context. + */ +static void +netifapi_do_netif_add(struct netifapi_msg_msg *msg) +{ + if (!netif_add( msg->netif, + API_EXPR_REF(msg->msg.add.ipaddr), + API_EXPR_REF(msg->msg.add.netmask), + API_EXPR_REF(msg->msg.add.gw), + msg->msg.add.state, + msg->msg.add.init, + msg->msg.add.input)) { + msg->err = ERR_IF; + } else { + msg->err = ERR_OK; + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_set_addr() inside the tcpip_thread context. + */ +static void +netifapi_do_netif_set_addr(struct netifapi_msg_msg *msg) +{ + netif_set_addr( msg->netif, + API_EXPR_REF(msg->msg.add.ipaddr), + API_EXPR_REF(msg->msg.add.netmask), + API_EXPR_REF(msg->msg.add.gw)); + msg->err = ERR_OK; + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the + * tcpip_thread context. + */ +static void +netifapi_do_netif_common(struct netifapi_msg_msg *msg) +{ + if (msg->msg.common.errtfunc != NULL) { + msg->err = msg->msg.common.errtfunc(msg->netif); + } else { + msg->err = ERR_OK; + msg->msg.common.voidfunc(msg->netif); + } + TCPIP_NETIFAPI_ACK(msg); +} + +/** + * Call netif_add() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_add() + */ +err_t +netifapi_netif_add(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (ipaddr == NULL) { + ipaddr = IP_ADDR_ANY; + } + if (netmask == NULL) { + netmask = IP_ADDR_ANY; + } + if (gw == NULL) { + gw = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_add; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); + NETIFAPI_VAR_REF(msg).msg.msg.add.netmask = NETIFAPI_VAR_REF(netmask); + NETIFAPI_VAR_REF(msg).msg.msg.add.gw = NETIFAPI_VAR_REF(gw); + NETIFAPI_VAR_REF(msg).msg.msg.add.state = state; + NETIFAPI_VAR_REF(msg).msg.msg.add.init = init; + NETIFAPI_VAR_REF(msg).msg.msg.add.input = input; + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; +} + +/** + * Call netif_set_addr() in a thread-safe way by running that function inside the + * tcpip_thread context. + * + * @note for params @see netif_set_addr() + */ +err_t +netifapi_netif_set_addr(struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); +#if LWIP_MPU_COMPATIBLE + if (ipaddr == NULL) { + ipaddr = IP_ADDR_ANY; + } + if (netmask == NULL) { + netmask = IP_ADDR_ANY; + } + if (gw == NULL) { + gw = IP_ADDR_ANY; + } +#endif /* LWIP_MPU_COMPATIBLE */ + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_set_addr; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); + NETIFAPI_VAR_REF(msg).msg.msg.add.netmask = NETIFAPI_VAR_REF(netmask); + NETIFAPI_VAR_REF(msg).msg.msg.add.gw = NETIFAPI_VAR_REF(gw); + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; +} + +/** + * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe + * way by running that function inside the tcpip_thread context. + * + * @note use only for functions where there is only "netif" parameter. + */ +err_t +netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc) +{ + err_t err; + NETIFAPI_VAR_DECLARE(msg); + NETIFAPI_VAR_ALLOC(msg); + + NETIFAPI_VAR_REF(msg).function = netifapi_do_netif_common; + NETIFAPI_VAR_REF(msg).msg.netif = netif; + NETIFAPI_VAR_REF(msg).msg.msg.common.voidfunc = voidfunc; + NETIFAPI_VAR_REF(msg).msg.msg.common.errtfunc = errtfunc; + TCPIP_NETIFAPI(&API_VAR_REF(msg)); + + err = NETIFAPI_VAR_REF(msg).msg.err; + NETIFAPI_VAR_FREE(msg); + return err; +} + +#endif /* LWIP_NETIF_API */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/pppapi.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/pppapi.c new file mode 100644 index 0000000..10e4b82 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/pppapi.c @@ -0,0 +1,439 @@ +/** + * @file + * Point To Point Protocol Sequential API module + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pppapi.h" +#include "lwip/tcpip.h" + +/** + * Call ppp_new() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_new(struct pppapi_msg_msg *msg) +{ + msg->ppp = ppp_new(); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_new() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +ppp_pcb* +pppapi_new(void) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_new; + TCPIP_PPPAPI(&msg); + return msg.msg.ppp; +} + + +/** + * Call ppp_set_default() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_set_default(struct pppapi_msg_msg *msg) +{ + ppp_set_default(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_default() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_set_default(ppp_pcb *pcb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_default; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); +} + + +/** + * Call ppp_set_auth() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_set_auth(struct pppapi_msg_msg *msg) +{ + ppp_set_auth(msg->ppp, msg->msg.setauth.authtype, + msg->msg.setauth.user, msg->msg.setauth.passwd); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_auth() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_auth; + msg.msg.ppp = pcb; + msg.msg.msg.setauth.authtype = authtype; + msg.msg.msg.setauth.user = user; + msg.msg.msg.setauth.passwd = passwd; + TCPIP_PPPAPI(&msg); +} + + +#if PPP_NOTIFY_PHASE +/** + * Call ppp_set_notify_phase_callback() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_set_notify_phase_callback(struct pppapi_msg_msg *msg) +{ + ppp_set_notify_phase_callback(msg->ppp, msg->msg.setnotifyphasecb.notify_phase_cb); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_notify_phase_callback; + msg.msg.ppp = pcb; + msg.msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb; + TCPIP_PPPAPI(&msg); +} +#endif /* PPP_NOTIFY_PHASE */ + + +#if PPPOS_SUPPORT +/** + * Call ppp_over_serial_create() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_over_serial_create(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_over_serial_create(msg->ppp, msg->msg.serialcreate.fd, + msg->msg.serialcreate.link_status_cb, msg->msg.serialcreate.ctx_cb); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_serial_create() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, + void *ctx_cb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_serial_create; + msg.msg.ppp = pcb; + msg.msg.msg.serialcreate.fd = fd; + msg.msg.msg.serialcreate.link_status_cb = link_status_cb; + msg.msg.msg.serialcreate.ctx_cb = ctx_cb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOS_SUPPORT */ + + +#if PPPOE_SUPPORT +/** + * Call ppp_over_ethernet_create() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_over_ethernet_create(struct pppapi_msg_msg *msg) +{ + + msg->err = ppp_over_ethernet_create(msg->ppp, msg->msg.ethernetcreate.ethif, + msg->msg.ethernetcreate.service_name, msg->msg.ethernetcreate.concentrator_name, + msg->msg.ethernetcreate.link_status_cb, msg->msg.ethernetcreate.ctx_cb); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_ethernet_create() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, + const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, + void *ctx_cb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_ethernet_create; + msg.msg.ppp = pcb; + msg.msg.msg.ethernetcreate.ethif = ethif; + msg.msg.msg.ethernetcreate.service_name = service_name; + msg.msg.msg.ethernetcreate.concentrator_name = concentrator_name; + msg.msg.msg.ethernetcreate.link_status_cb = link_status_cb; + msg.msg.msg.ethernetcreate.ctx_cb = ctx_cb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOE_SUPPORT */ + + +#if PPPOL2TP_SUPPORT +/** + * Call ppp_over_l2tp_create() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_over_l2tp_create(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_over_l2tp_create(msg->ppp, + msg->msg.l2tpcreate.netif, msg->msg.l2tpcreate.ipaddr, msg->msg.l2tpcreate.port, +#if PPPOL2TP_AUTH_SUPPORT + msg->msg.l2tpcreate.secret, + msg->msg.l2tpcreate.secret_len, +#else /* PPPOL2TP_AUTH_SUPPORT */ + NULL, +#endif /* PPPOL2TP_AUTH_SUPPORT */ + msg->msg.l2tpcreate.link_status_cb, msg->msg.l2tpcreate.ctx_cb); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_over_l2tp_create() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_over_l2tp_create; + msg.msg.ppp = pcb; + msg.msg.msg.l2tpcreate.netif = netif; + msg.msg.msg.l2tpcreate.ipaddr = ipaddr; + msg.msg.msg.l2tpcreate.port = port; +#if PPPOL2TP_AUTH_SUPPORT + msg.msg.msg.l2tpcreate.secret = secret; + msg.msg.msg.l2tpcreate.secret_len = secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + msg.msg.msg.l2tpcreate.link_status_cb = link_status_cb; + msg.msg.msg.l2tpcreate.ctx_cb = ctx_cb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} +#endif /* PPPOL2TP_SUPPORT */ + + +/** + * Call ppp_open() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_open(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_open(msg->ppp, msg->msg.open.holdoff); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_open() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_open(ppp_pcb *pcb, u16_t holdoff) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_open; + msg.msg.ppp = pcb; + msg.msg.msg.open.holdoff = holdoff; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +/** + * Call ppp_close() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_close(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_close(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_close() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_close(ppp_pcb *pcb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_close; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +/** + * Call ppp_sighup() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_sighup(struct pppapi_msg_msg *msg) +{ + ppp_sighup(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_sighup() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_sighup(ppp_pcb *pcb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_sighup; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); +} + + +/** + * Call ppp_delete() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_delete(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_delete(msg->ppp); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_delete() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_delete(ppp_pcb *pcb) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_delete; + msg.msg.ppp = pcb; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +/** + * Call ppp_ioctl() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_ioctl(struct pppapi_msg_msg *msg) +{ + msg->err = ppp_ioctl(msg->ppp, msg->msg.ioctl.cmd, msg->msg.ioctl.arg); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_ioctl() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +int +pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_ioctl; + msg.msg.ppp = pcb; + msg.msg.msg.ioctl.cmd = cmd; + msg.msg.msg.ioctl.arg = arg; + TCPIP_PPPAPI(&msg); + return msg.msg.err; +} + + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Call ppp_set_netif_statuscallback() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_set_netif_statuscallback(struct pppapi_msg_msg *msg) +{ + ppp_set_netif_statuscallback(msg->ppp, msg->msg.netifstatuscallback.status_callback); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_netif_statuscallback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_netif_statuscallback; + msg.msg.ppp = pcb; + msg.msg.msg.netifstatuscallback.status_callback = status_callback; + TCPIP_PPPAPI(&msg); +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Call ppp_set_netif_linkcallback() inside the tcpip_thread context. + */ +static void +pppapi_do_ppp_set_netif_linkcallback(struct pppapi_msg_msg *msg) +{ + ppp_set_netif_linkcallback(msg->ppp, msg->msg.netiflinkcallback.link_callback); + TCPIP_PPPAPI_ACK(msg); +} + +/** + * Call ppp_set_netif_linkcallback() in a thread-safe way by running that function inside the + * tcpip_thread context. + */ +void +pppapi_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) +{ + struct pppapi_msg msg; + msg.function = pppapi_do_ppp_set_netif_linkcallback; + msg.msg.ppp = pcb; + msg.msg.msg.netiflinkcallback.link_callback = link_callback; + TCPIP_PPPAPI(&msg); +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#endif /* LWIP_PPP_API */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/sockets.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/sockets.c new file mode 100644 index 0000000..84520b1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/sockets.c @@ -0,0 +1,2551 @@ +/** + * @file + * Sockets BSD-Like API module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ +#include "lwip/arch.h" +#include "lwip/sockets.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcpip.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +/* If the netconn API is not required publicly, then we include the necessary + files here to get the implementation */ +#if !LWIP_NETCONN +#undef LWIP_NETCONN +#define LWIP_NETCONN 1 +#include "api_msg.c" +#include "api_lib.c" +#include "netbuf.c" +#undef LWIP_NETCONN +#define LWIP_NETCONN 0 +#endif + +#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipXaddr, port) do { \ + (sin)->sin_len = sizeof(struct sockaddr_in); \ + (sin)->sin_family = AF_INET; \ + (sin)->sin_port = htons((port)); \ + inet_addr_from_ipaddr(&(sin)->sin_addr, ipX_2_ip(ipXaddr)); \ + memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) +#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipXaddr, port) do { \ + inet_addr_to_ipaddr(ipX_2_ip(ipXaddr), &((sin)->sin_addr)); \ + (port) = ntohs((sin)->sin_port); }while(0) + +#if LWIP_IPV6 +#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ + ((namelen) == sizeof(struct sockaddr_in6))) +#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ + ((name)->sa_family == AF_INET6)) +#define SOCK_ADDR_TYPE_MATCH(name, sock) \ + ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ + (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) +#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipXaddr, port) do { \ + (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ + (sin6)->sin6_family = AF_INET6; \ + (sin6)->sin6_port = htons((port)); \ + (sin6)->sin6_flowinfo = 0; \ + inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipX_2_ip6(ipXaddr)); }while(0) +#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) do { \ + if (isipv6) { \ + IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ipXaddr, port); \ + } else { \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port); \ + } } while(0) +#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipXaddr, port) do { \ + inet6_addr_to_ip6addr(ipX_2_ip6(ipXaddr), &((sin6)->sin6_addr)); \ + (port) = ntohs((sin6)->sin6_port); }while(0) +#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) do { \ + if (isipv6) { \ + SOCKADDR6_TO_IP6ADDR_PORT((struct sockaddr_in6*)(void*)(sockaddr), ipXaddr, port); \ + } else { \ + SOCKADDR4_TO_IP4ADDR_PORT((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port); \ + } } while(0) +#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ + (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) +#else /* LWIP_IPV6 */ +#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) +#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) +#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 +#define IPXADDR_PORT_TO_SOCKADDR(isipv6, sockaddr, ipXaddr, port) \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port) +#define SOCKADDR_TO_IPXADDR_PORT(isipv6, sockaddr, ipXaddr, port) \ + SOCKADDR4_TO_IP4ADDR_PORT((struct sockaddr_in*)(void*)(sockaddr), ipXaddr, port) +#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) +#endif /* LWIP_IPV6 */ + +#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ + IS_SOCK_ADDR_TYPE_VALID(name)) +#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ + SOCK_ADDR_TYPE_MATCH(name, sock)) +#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) + + +#define LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype) do { if((optlen) < sizeof(opttype)) { return EINVAL; }}while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ + if ((sock)->conn == NULL) { return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ + if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ + if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { return ENOPROTOOPT; } }while(0) + + +#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) +#if LWIP_MPU_COMPATIBLE +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ + name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ + if (name == NULL) { \ + sock_set_errno(sock, ENOMEM); \ + return -1; \ + } }while(0) +#else /* LWIP_MPU_COMPATIBLE */ +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) +#endif /* LWIP_MPU_COMPATIBLE */ + +#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD +#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int +#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((s32_t)*(int*)(optval)) +#else +#define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval +#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ + s32_t loc = (val); \ + ((struct timeval *)(optval))->tv_sec = (loc) / 1000U; \ + ((struct timeval *)(optval))->tv_sec = ((loc) % 1000U) * 1000U; }while(0) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((struct timeval *)(optval))->tv_sec * 1000U) + (((struct timeval *)(optval))->tv_usec / 1000U)) +#endif + +#define NUM_SOCKETS MEMP_NUM_NETCONN + +/** This is overridable for the rare case where more than 255 threads + * select on the same socket... + */ +#ifndef SELWAIT_T +#define SELWAIT_T u8_t +#endif + +/** Contains all internal pointers and states used for a socket */ +struct lwip_sock { + /** sockets currently are built on netconns, each socket has one netconn */ + struct netconn *conn; + /** data that was left from the previous read */ + void *lastdata; + /** offset in the data that was left from the previous read */ + u16_t lastoffset; + /** number of times data was received, set by event_callback(), + tested by the receive and select functions */ + s16_t rcvevent; + /** number of times data was ACKed (free send buffer), set by event_callback(), + tested by select */ + u16_t sendevent; + /** error happened for this socket, set by event_callback(), tested by select */ + u16_t errevent; + /** last error that occurred on this socket (in fact, all our errnos fit into an u8_t) */ + u8_t err; + /** counter of how many threads are waiting for this socket using select */ + SELWAIT_T select_waiting; +}; + +#if LWIP_NETCONN_SEM_PER_THREAD +#define SELECT_SEM_T sys_sem_t* +#define SELECT_SEM_PTR(sem) (sem) +#else /* LWIP_NETCONN_SEM_PER_THREAD */ +#define SELECT_SEM_T sys_sem_t +#define SELECT_SEM_PTR(sem) (&(sem)) +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +/** Description for a task waiting in select */ +struct lwip_select_cb { + /** Pointer to the next waiting task */ + struct lwip_select_cb *next; + /** Pointer to the previous waiting task */ + struct lwip_select_cb *prev; + /** readset passed to select */ + fd_set *readset; + /** writeset passed to select */ + fd_set *writeset; + /** unimplemented: exceptset passed to select */ + fd_set *exceptset; + /** don't signal the same semaphore twice: set to 1 when signalled */ + int sem_signalled; + /** semaphore to wake up a task waiting for select */ + SELECT_SEM_T sem; +}; + +/** A struct sockaddr replacement that has the same alignment as sockaddr_in/ + * sockaddr_in6 if instantiated. + */ +union sockaddr_aligned { + struct sockaddr sa; +#if LWIP_IPV6 + struct sockaddr_in6 sin6; +#endif /* LWIP_IPV6 */ + struct sockaddr_in sin; +}; + + +/** The global array of available sockets */ +static struct lwip_sock sockets[NUM_SOCKETS]; +/** The global list of tasks waiting for select */ +static struct lwip_select_cb *select_cb_list; +/** This counter is increased from lwip_select when the list is chagned + and checked in event_callback to see if it has changed. */ +static volatile int select_cb_ctr; + +/** Table to quickly map an lwIP error (err_t) to a socket error + * by using -err as an index */ +static const int err_to_errno_table[] = { + 0, /* ERR_OK 0 No error, everything OK. */ + ENOMEM, /* ERR_MEM -1 Out of memory error. */ + ENOBUFS, /* ERR_BUF -2 Buffer error. */ + EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ + EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ + EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ + EINVAL, /* ERR_VAL -6 Illegal value. */ + EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ + EADDRINUSE, /* ERR_USE -8 Address in use. */ + EALREADY, /* ERR_ISCONN -9 Already connected. */ + ENOTCONN, /* ERR_CONN -10 Not connected. */ + ECONNABORTED, /* ERR_ABRT -11 Connection aborted. */ + ECONNRESET, /* ERR_RST -12 Connection reset. */ + ENOTCONN, /* ERR_CLSD -13 Connection closed. */ + EIO, /* ERR_ARG -14 Illegal argument. */ + -1, /* ERR_IF -15 Low-level netif error */ +}; + +#define ERR_TO_ERRNO_TABLE_SIZE \ + (sizeof(err_to_errno_table)/sizeof(err_to_errno_table[0])) + +#define err_to_errno(err) \ + ((unsigned)(-(err)) < ERR_TO_ERRNO_TABLE_SIZE ? \ + err_to_errno_table[-(err)] : EIO) + +#if LWIP_SOCKET_SET_ERRNO +#ifndef set_errno +#define set_errno(err) do { if (err) { errno = (err); } } while(0) +#endif +#else /* LWIP_SOCKET_SET_ERRNO */ +#define set_errno(err) +#endif /* LWIP_SOCKET_SET_ERRNO */ + +#define sock_set_errno(sk, e) do { \ + sk->err = (e); \ + set_errno(sk->err); \ +} while (0) + +/* Forward declaration of some functions */ +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); +#if !LWIP_TCPIP_CORE_LOCKING +static void lwip_getsockopt_callback(void *arg); +static void lwip_setsockopt_callback(void *arg); +#endif +static u8_t lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen); +static u8_t lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen); + +/** + * Map a externally used socket index to the internal socket representation. + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +get_socket(int s) +{ + struct lwip_sock *sock; + + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s)); + set_errno(EBADF); + return NULL; + } + + sock = &sockets[s]; + + if (!sock->conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s)); + set_errno(EBADF); + return NULL; + } + + return sock; +} + +/** + * Same as get_socket but doesn't set errno + * + * @param s externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +tryget_socket(int s) +{ + if ((s < 0) || (s >= NUM_SOCKETS)) { + return NULL; + } + if (!sockets[s].conn) { + return NULL; + } + return &sockets[s]; +} + +/** + * Allocate a new socket for a given netconn. + * + * @param newconn the netconn for which to allocate a socket + * @param accepted 1 if socket has been created by accept(), + * 0 if socket has been created by socket() + * @return the index of the new socket; -1 on error + */ +static int +alloc_socket(struct netconn *newconn, int accepted) +{ + int i; + SYS_ARCH_DECL_PROTECT(lev); + + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + if (!sockets[i].conn) { + sockets[i].conn = newconn; + /* The socket is not yet known to anyone, so no need to protect + after having marked it as used. */ + SYS_ARCH_UNPROTECT(lev); + sockets[i].lastdata = NULL; + sockets[i].lastoffset = 0; + sockets[i].rcvevent = 0; + /* TCP sendbuf is empty, but the socket is not yet writable until connected + * (unless it has been created by accept()). */ + sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); + sockets[i].errevent = 0; + sockets[i].err = 0; + sockets[i].select_waiting = 0; + return i; + } + SYS_ARCH_UNPROTECT(lev); + } + return -1; +} + +/** Free a socket. The socket's netconn must have been + * delete before! + * + * @param sock the socket to free + * @param is_tcp != 0 for TCP sockets, used to free lastdata + */ +static void +free_socket(struct lwip_sock *sock, int is_tcp) +{ + void *lastdata; + SYS_ARCH_DECL_PROTECT(lev); + + lastdata = sock->lastdata; + sock->lastdata = NULL; + sock->lastoffset = 0; + sock->err = 0; + + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + sock->conn = NULL; + SYS_ARCH_UNPROTECT(lev); + /* don't use 'sock' after this line, as another task might have allocated it */ + + if (lastdata != NULL) { + if (is_tcp) { + pbuf_free((struct pbuf *)lastdata); + } else { + netbuf_delete((struct netbuf *)lastdata); + } + } +} + +/* Below this, the well-known socket functions are implemented. + * Use google.com or opengroup.org to get a good description :-) + * + * Exceptions are documented! + */ + +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct lwip_sock *sock, *nsock; + struct netconn *newconn; + ipX_addr_t naddr; + u16_t port = 0; + int newsock; + err_t err; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return EOPNOTSUPP; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + LWIP_ASSERT("newconn != NULL", newconn != NULL); + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(newconn, 1); + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if (addr != NULL) { + union sockaddr_aligned tempaddr; + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, ipX_2_ip(&naddr), &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + netconn_delete(newconn); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); + + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(newconn->type), &tempaddr, &naddr, port); + if (*addrlen > tempaddr.sa.sa_len) { + *addrlen = tempaddr.sa.sa_len; + } + MEMCPY(addr, &tempaddr, *addrlen); + } + + newsock = alloc_socket(newconn, 1); + if (newsock == -1) { + netconn_delete(newconn); + sock_set_errno(sock, ENFILE); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= 0) && (newsock < NUM_SOCKETS)); + LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); + nsock = &sockets[newsock]; + + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + SYS_ARCH_PROTECT(lev); + nsock->rcvevent += (s16_t)(-1 - newconn->socket); + newconn->socket = newsock; + SYS_ARCH_UNPROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); + if (addr != NULL) { + LWIP_DEBUGF(SOCKETS_DEBUG, (" addr=")); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(newconn->type), SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + } + + sock_set_errno(sock, 0); + return newsock; +} + +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + ipX_addr_t local_addr; + u16_t local_port; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + LWIP_UNUSED_ARG(namelen); + + SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &local_addr, local_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); + + err = netconn_bind(sock->conn, ipX_2_ip(&local_addr), local_port); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_close(int s) +{ + struct lwip_sock *sock; + int is_tcp = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if(sock->conn != NULL) { + is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; + } else { + LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); + } + + netconn_delete(sock->conn); + + free_socket(sock, is_tcp); + set_errno(0); + return 0; +} + +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + + LWIP_UNUSED_ARG(namelen); + if (name->sa_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + ipX_addr_t remote_addr; + u16_t remote_port; + + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + + SOCKADDR_TO_IPXADDR_PORT((name->sa_family == AF_INET6), name, &remote_addr, remote_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ipX_addr_debug_print(name->sa_family == AF_INET6, SOCKETS_DEBUG, &remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); + + err = netconn_connect(sock->conn, ipX_2_ip(&remote_addr), remote_port); + } + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + return 0; +} + +/** + * Set a socket into listen mode. + * The socket may not have been used for another connection previously. + * + * @param s the socket to set to listening mode + * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) + * @return 0 on success, non-zero on failure + */ +int +lwip_listen(int s, int backlog) +{ + struct lwip_sock *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* limit the "backlog" parameter to fit in an u8_t */ + backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); + + err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return -1; + } + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ + struct lwip_sock *sock; + void *buf = NULL; + struct pbuf *p; + u16_t buflen, copylen; + int off = 0; + u8_t done = 0; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + do { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata) { + buf = sock->lastdata; + } else { + /* If this is non-blocking call, then check first */ + if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && + (sock->rcvevent <= 0)) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); + sock_set_errno(sock, EWOULDBLOCK); + return -1; + } + + /* No data was left from the previous operation, so we try to get + some from the network. */ + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); + } else { + err = netconn_recv(sock->conn, (struct netbuf **)&buf); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", + err, buf)); + + if (err != ERR_OK) { + if (off > 0) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + /* already received data, return that */ + sock_set_errno(sock, 0); + return off; + } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + if (err == ERR_CLSD) { + return 0; + } else { + return -1; + } + } + LWIP_ASSERT("buf != NULL", buf != NULL); + sock->lastdata = buf; + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + p = (struct pbuf *)buf; + } else { + p = ((struct netbuf *)buf)->p; + } + buflen = p->tot_len; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", + buflen, len, off, sock->lastoffset)); + + buflen -= sock->lastoffset; + + if (len > buflen) { + copylen = buflen; + } else { + copylen = (u16_t)len; + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); + + off += copylen; + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); + len -= copylen; + if ( (len <= 0) || + (p->flags & PBUF_FLAG_PUSH) || + (sock->rcvevent <= 0) || + ((flags & MSG_PEEK)!=0)) { + done = 1; + } + } else { + done = 1; + } + + /* Check to see from where the data was.*/ + if (done) { +#if !SOCKETS_DEBUG + if (from && fromlen) +#endif /* !SOCKETS_DEBUG */ + { + u16_t port; + ipX_addr_t tmpaddr; + ipX_addr_t *fromaddr; + union sockaddr_aligned saddr; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + fromaddr = &tmpaddr; + /* @todo: this does not work for IPv6, yet */ + netconn_getaddr(sock->conn, ipX_2_ip(fromaddr), &port, 0); + } else { + port = netbuf_fromport((struct netbuf *)buf); + fromaddr = netbuf_fromaddr_ipX((struct netbuf *)buf); + } + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + &saddr, fromaddr, port); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + SOCKETS_DEBUG, fromaddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); +#if SOCKETS_DEBUG + if (from && fromlen) +#endif /* SOCKETS_DEBUG */ + { + if (*fromlen > saddr.sa.sa_len) { + *fromlen = saddr.sa.sa_len; + } + MEMCPY(from, &saddr, *fromlen); + } + } + } + + /* If we don't peek the incoming message... */ + if ((flags & MSG_PEEK) == 0) { + /* If this is a TCP socket, check if there is data left in the + buffer. If so, it should be saved in the sock structure for next + time around. */ + if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) && (buflen - copylen > 0)) { + sock->lastdata = buf; + sock->lastoffset += copylen; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); + } else { + sock->lastdata = NULL; + sock->lastoffset = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + pbuf_free((struct pbuf *)buf); + } else { + netbuf_delete((struct netbuf *)buf); + } + } + } + } while (!done); + + if ((off > 0) && (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP)) { + /* update receive window */ + netconn_recved(sock->conn, (u32_t)off); + } + sock_set_errno(sock, 0); + return off; +} + +int +lwip_read(int s, void *mem, size_t len) +{ + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); +} + +int +lwip_recv(int s, void *mem, size_t len, int flags) +{ + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); +} + +int +lwip_send(int s, const void *data, size_t size, int flags) +{ + struct lwip_sock *sock; + err_t err; + u8_t write_flags; + size_t written; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + return lwip_sendto(s, data, size, flags, NULL, 0); +#else /* (LWIP_UDP || LWIP_RAW) */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + write_flags = NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? (int)written : -1); +} + +int +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ + struct lwip_sock *sock; + err_t err; + u16_t short_size; + u16_t remote_port; +#if !LWIP_TCPIP_CORE_LOCKING + struct netbuf buf; +#endif + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCP + return lwip_send(s, data, size, flags); +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(flags); + sock_set_errno(sock, err_to_errno(ERR_ARG)); + return -1; +#endif /* LWIP_TCP */ + } + + if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + return -1; + } + + /* @todo: split into multiple sendto's? */ + LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + (IS_SOCK_ADDR_LEN_VALID(tolen) && + IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))), + sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); + LWIP_UNUSED_ARG(tolen); + +#if LWIP_TCPIP_CORE_LOCKING + /* Special speedup for fast UDP/RAW sending: call the raw API directly + instead of using the netconn functions. */ + { + struct pbuf* p; + ipX_addr_t *remote_addr; + ipX_addr_t remote_addr_tmp; + +#if LWIP_NETIF_TX_SINGLE_PBUF + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM); + if (p != NULL) { +#if LWIP_CHECKSUM_ON_COPY + u16_t chksum = 0; + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { + chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + MEMCPY(p->payload, data, size); +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF); + if (p != NULL) { + p->payload = (void*)data; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + if (to != NULL) { + SOCKADDR_TO_IPXADDR_PORT(to->sa_family == AF_INET6, + to, &remote_addr_tmp, remote_port); + remote_addr = &remote_addr_tmp; + } else { + remote_addr = &sock->conn->pcb.ip->remote_ip; +#if LWIP_UDP + if (NETCONNTYPE_GROUP(sock->conn->type) == NETCONN_UDP) { + remote_port = sock->conn->pcb.udp->remote_port; + } else +#endif /* LWIP_UDP */ + { + remote_port = 0; + } + } + + LOCK_TCPIP_CORE(); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { +#if LWIP_RAW + err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, ipX_2_ip(remote_addr)); +#else /* LWIP_RAW */ + err = ERR_ARG; +#endif /* LWIP_RAW */ + } +#if LWIP_UDP && LWIP_RAW + else +#endif /* LWIP_UDP && LWIP_RAW */ + { +#if LWIP_UDP +#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF + err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p, + ipX_2_ip(remote_addr), remote_port, 1, chksum); +#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ + err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p, + ipX_2_ip(remote_addr), remote_port); +#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */ +#else /* LWIP_UDP */ + err = ERR_ARG; +#endif /* LWIP_UDP */ + } + UNLOCK_TCPIP_CORE(); + + pbuf_free(p); + } else { + err = ERR_MEM; + } + } +#else /* LWIP_TCPIP_CORE_LOCKING */ + /* initialize a buffer */ + buf.p = buf.ptr = NULL; +#if LWIP_CHECKSUM_ON_COPY + buf.flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + if (to) { + SOCKADDR_TO_IPXADDR_PORT((to->sa_family) == AF_INET6, to, &buf.addr, remote_port); + } else { + remote_port = 0; + ipX_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); + } + netbuf_fromport(&buf) = remote_port; + + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + SOCKETS_DEBUG, &buf.addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + + /* make the buffer point to the data that should be sent */ +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { +#if LWIP_CHECKSUM_ON_COPY + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + err = ERR_OK; + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + err = netbuf_take(&buf, data, short_size); + } + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { + /* send the data */ + err = netconn_send(sock->conn, &buf); + } + + /* deallocated the buffer */ + netbuf_free(&buf); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? short_size : -1); +} + +int +lwip_socket(int domain, int type, int protocol) +{ + struct netconn *conn; + int i; + +#if !LWIP_IPV6 + LWIP_UNUSED_ARG(domain); /* @todo: check this */ +#endif /* LWIP_IPV6 */ + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), + (u8_t)protocol, event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, + ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) , + event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + if (conn != NULL) { + /* Prevent automatic window updates, we do this on our own! */ + netconn_set_noautorecved(conn, 1); + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } + + i = alloc_socket(conn, 0); + + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->socket = i; + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; +} + +int +lwip_write(int s, const void *data, size_t size) +{ + return lwip_send(s, data, size, 0); +} + +/** + * Go through the readset and writeset lists and see which socket of the sockets + * set in the sets has events. On return, readset, writeset and exceptset have + * the sockets enabled that had events. + * + * exceptset is not used for now!!! + * + * @param maxfdp1 the highest socket index in the sets + * @param readset_in: set of sockets to check for read events + * @param writeset_in: set of sockets to check for write events + * @param exceptset_in: set of sockets to check for error events + * @param readset_out: set of sockets that had read events + * @param writeset_out: set of sockets that had write events + * @param exceptset_out: set os sockets that had error events + * @return number of sockets that had events (read/write/exception) (>= 0) + */ +static int +lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, + fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) +{ + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for(i = 0; i < maxfdp1; i++) { + void* lastdata = NULL; + s16_t rcvevent = 0; + u16_t sendevent = 0; + u16_t errevent = 0; + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket(i); + if (sock != NULL) { + lastdata = sock->lastdata; + rcvevent = sock->rcvevent; + sendevent = sock->sendevent; + errevent = sock->errevent; + } + SYS_ARCH_UNPROTECT(lev); + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + /* See if netconn of this socket is ready for write */ + if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + /* See if netconn of this socket had an error */ + if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { + FD_SET(i, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); + nready++; + } + } + /* copy local sets to the ones provided as arguments */ + *readset_out = lreadset; + *writeset_out = lwriteset; + *exceptset_out = lexceptset; + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; +} + +/** + * Processing exceptset is not yet implemented. + */ +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) +{ + u32_t waitres = 0; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + struct lwip_select_cb select_cb; + int i; + int maxfdp2; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, + timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); + + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables. */ + + select_cb.next = NULL; + select_cb.prev = NULL; + select_cb.readset = readset; + select_cb.writeset = writeset; + select_cb.exceptset = exceptset; + select_cb.sem_signalled = 0; +#if LWIP_NETCONN_SEM_PER_THREAD + select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + if (sys_sem_new(&select_cb.sem, 0) != ERR_OK) { + /* failed to create semaphore */ + set_errno(ENOMEM); + return -1; + } +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + + /* Protect the select_cb_list */ + SYS_ARCH_PROTECT(lev); + + /* Put this select_cb on top of list */ + select_cb.next = select_cb_list; + if (select_cb_list != NULL) { + select_cb_list->prev = &select_cb; + } + select_cb_list = &select_cb; + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + + /* Now we can safely unprotect */ + SYS_ARCH_UNPROTECT(lev); + + /* Increase select_waiting for each socket we are interested in */ + maxfdp2 = maxfdp1; + for (i = 0; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket(i); + if (sock != NULL) { + sock->select_waiting++; + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + } else { + /* Not a valid socket */ + nready = -1; + maxfdp2 = i; + SYS_ARCH_UNPROTECT(lev); + break; + } + SYS_ARCH_UNPROTECT(lev); + } + } + + if (nready >= 0) { + /* Call lwip_selscan again: there could have been events between + the last scan (without us on the list) and putting us on the list! */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout == 0) { + /* Wait forever */ + msectimeout = 0; + } else { + msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); + if (msectimeout == 0) { + /* Wait 1ms at least (0 means wait forever) */ + msectimeout = 1; + } + } + + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem), msectimeout); + } + } + + /* Decrease select_waiting for each socket we are interested in */ + for (i = 0; i < maxfdp2; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket(i); + if (sock != NULL) { + /* @todo: what if this is a new socket (reallocated?) in this case, + select_waiting-- would be wrong (a global 'sockalloc' counter, + stored per socket could help) */ + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + if (sock->select_waiting > 0) { + sock->select_waiting--; + } + } else { + /* Not a valid socket */ + nready = -1; + } + SYS_ARCH_UNPROTECT(lev); + } + } + /* Take us off the list */ + SYS_ARCH_PROTECT(lev); + if (select_cb.next != NULL) { + select_cb.next->prev = select_cb.prev; + } + if (select_cb_list == &select_cb) { + LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); + select_cb_list = select_cb.next; + } else { + LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); + select_cb.prev->next = select_cb.next; + } + /* Increasing this counter tells even_callback that the list has changed. */ + select_cb_ctr++; + SYS_ARCH_UNPROTECT(lev); + +#if !LWIP_NETCONN_SEM_PER_THREAD + sys_sem_free(&select_cb.sem); +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + + if (nready < 0) { + /* This happens when a socket got closed while waiting */ + set_errno(EBADF); + return -1; + } + + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + goto return_copy_fdsets; + } + + /* See what's set */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); +return_copy_fdsets: + set_errno(0); + if (readset) { + *readset = lreadset; + } + if (writeset) { + *writeset = lwriteset; + } + if (exceptset) { + *exceptset = lexceptset; + } + return nready; +} + +/** + * Callback registered in the netconn layer for each socket-netconn. + * Processes recvevent (data available) and wakes up tasks waiting for select. + */ +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s; + struct lwip_sock *sock; + struct lwip_select_cb *scb; + int last_select_cb_ctr; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + conn->socket--; + } + SYS_ARCH_UNPROTECT(lev); + return; + } + s = conn->socket; + SYS_ARCH_UNPROTECT(lev); + } + + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + break; + case NETCONN_EVT_SENDPLUS: + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + + if (sock->select_waiting == 0) { + /* noone is waiting for this socket, no need to check select_cb_list */ + SYS_ARCH_UNPROTECT(lev); + return; + } + + /* Now decide if anyone is waiting for this socket */ + /* NOTE: This code goes through the select_cb_list list multiple times + ONLY IF a select was actually waiting. We go through the list the number + of waiting select calls + 1. This list is expected to be small. */ + + /* At this point, SYS_ARCH is still protected! */ +again: + for (scb = select_cb_list; scb != NULL; scb = scb->next) { + /* remember the state of select_cb_list to detect changes */ + last_select_cb_ctr = select_cb_ctr; + if (scb->sem_signalled == 0) { + /* semaphore not signalled yet */ + int do_signal = 0; + /* Test this select call for our socket */ + if (sock->rcvevent > 0) { + if (scb->readset && FD_ISSET(s, scb->readset)) { + do_signal = 1; + } + } + if (sock->sendevent != 0) { + if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { + do_signal = 1; + } + } + if (sock->errevent != 0) { + if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { + do_signal = 1; + } + } + if (do_signal) { + scb->sem_signalled = 1; + /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might + lead to the select thread taking itself off the list, invalidating the semaphore. */ + sys_sem_signal(SELECT_SEM_PTR(scb->sem)); + } + } + /* unlock interrupts with each step */ + SYS_ARCH_UNPROTECT(lev); + /* this makes sure interrupt protection time is short */ + SYS_ARCH_PROTECT(lev); + if (last_select_cb_ctr != select_cb_ctr) { + /* someone has changed select_cb_list, restart at the beginning */ + goto again; + } + } + SYS_ARCH_UNPROTECT(lev); +} + +/** + * Unimplemented: Close one end of a full-duplex connection. + * Currently, the full connection is closed. + */ +int +lwip_shutdown(int s, int how) +{ + struct lwip_sock *sock; + err_t err; + u8_t shut_rx = 0, shut_tx = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn != NULL) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + return -1; + } + } else { + sock_set_errno(sock, ENOTCONN); + return -1; + } + + if (how == SHUT_RD) { + shut_rx = 1; + } else if (how == SHUT_WR) { + shut_tx = 1; + } else if(how == SHUT_RDWR) { + shut_rx = 1; + shut_tx = 1; + } else { + sock_set_errno(sock, EINVAL); + return -1; + } + err = netconn_shutdown(sock->conn, shut_rx, shut_tx); + + sock_set_errno(sock, err_to_errno(err)); + return (err == ERR_OK ? 0 : -1); +} + +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +{ + struct lwip_sock *sock; + union sockaddr_aligned saddr; + ipX_addr_t naddr; + u16_t port; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* get the IP address and port */ + /* @todo: this does not work for IPv6, yet */ + err = netconn_getaddr(sock->conn, ipX_2_ip(&naddr), &port, local); + if (err != ERR_OK) { + sock_set_errno(sock, err_to_errno(err)); + return -1; + } + IPXADDR_PORT_TO_SOCKADDR(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + &saddr, &naddr, port); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ipX_addr_debug_print(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), + SOCKETS_DEBUG, &naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); + + if (*namelen > saddr.sa.sa_len) { + *namelen = saddr.sa.sa_len; + } + MEMCPY(name, &saddr, *namelen); + + sock_set_errno(sock, 0); + return 0; +} + +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 0); +} + +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 1); +} + +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + u8_t err; + struct lwip_sock *sock = get_socket(s); +#if !LWIP_TCPIP_CORE_LOCKING + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + + if (!sock) { + return -1; + } + + if ((NULL == optval) || (NULL == optlen)) { + sock_set_errno(sock, EFAULT); + return -1; + } + +#if LWIP_TCPIP_CORE_LOCKING + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_getsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); + +#else /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_MPU_COMPATIBLE + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + sock_set_errno(sock, ENOBUFS); + return -1; + } +#endif /* LWIP_MPU_COMPATIBLE */ + + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; +#if !LWIP_MPU_COMPATIBLE + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval = optval; +#endif /* !LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; +#if LWIP_NETCONN_SEM_PER_THREAD + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; +#endif + tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + + /* write back optlen and optval */ + *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; +#if LWIP_MPU_COMPATIBLE + memcpy(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); +#endif /* LWIP_MPU_COMPATIBLE */ + + /* maybe lwip_getsockopt_internal has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +#if !LWIP_TCPIP_CORE_LOCKING +/** lwip_getsockopt_callback: only used without CORE_LOCKING + * to get into the tcpip_thread + */ +static void +lwip_getsockopt_callback(void *arg) +{ + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data*)arg; + + data->err = lwip_getsockopt_impl(data->s, data->level, data->optname, data->optval, + &data->optlen); + + sys_sem_signal((sys_sem_t*)(data->completed_sem)); +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** lwip_getsockopt_impl: the actual implementation of getsockopt: + * same argument as lwip_getsockopt, either called directly or through callback + */ +static u8_t +lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + u8_t err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + case SO_ACCEPTCONN: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { + return ENOPROTOOPT; + } + if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) { + *(int*)optval = 1; + } else { + *(int*)optval = 0; + } + break; + + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: +#if SO_REUSE + case SO_REUSEADDR: +#endif /* SO_REUSE */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; + + case SO_TYPE: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { + case NETCONN_RAW: + *(int*)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int*)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int*)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int*)optval = netconn_type(sock->conn); + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (netconn_type(sock->conn)) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + LWIP_SOCKOPT_CHECK_OPTLEN(*optlen, int); + /* only overwrite ERR_OK or temporary errors */ + if (((sock->err == 0) || (sock->err == EINPROGRESS)) && (sock->conn != NULL)) { + sock_set_errno(sock, err_to_errno(sock->conn->last_err)); + } + *(int *)optval = sock->err; + sock->err = 0; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + *(int *)optval = netconn_get_recvbufsize(sock->conn); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); +#if LWIP_UDPLITE + if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) { + /* this flag is only available for UDP, not for UDP lite */ + return EAFNOSUPPORT; + } +#endif /* LWIP_UDPLITE */ + *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; +#endif /* LWIP_UDP*/ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int*)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + return ENOPROTOOPT; + } + *(u8_t*)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + return ENOPROTOOPT; + } + inet_addr_from_ipaddr((struct in_addr*)optval, &sock->conn->pcb.udp->multicast_ip); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t*)optval = 1; + } else { + *(u8_t*)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); + switch (optname) { + case TCP_NODELAY: + *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int*)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ + +#if LWIP_IPV6 +/* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + /* @todo: this does not work for datagram sockets, yet */ + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + return ENOPROTOOPT; + } + *(int*)optval = ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", + s, *(int *)optval)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { +#if LWIP_IPV6 + case IPV6_CHECKSUM: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); + if (sock->conn->pcb.raw->chksum_reqd == 0) { + *(int *)optval = -1; + } else { + *(int *)optval = sock->conn->pcb.raw->chksum_offset; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", + s, (*(int*)optval)) ); + break; +#endif /* LWIP_IPV6 */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + return err; +} + +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + u8_t err = 0; + struct lwip_sock *sock = get_socket(s); +#if !LWIP_TCPIP_CORE_LOCKING + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + + if (!sock) { + return -1; + } + + if (NULL == optval) { + sock_set_errno(sock, EFAULT); + return -1; + } + +#if LWIP_TCPIP_CORE_LOCKING + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_setsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); + +#else /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_MPU_COMPATIBLE + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + sock_set_errno(sock, ENOBUFS); + return -1; + } +#endif /* LWIP_MPU_COMPATIBLE */ + + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; +#if LWIP_MPU_COMPATIBLE + memcpy(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); +#else /* LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval = (void*)optval; +#endif /* LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; +#if LWIP_NETCONN_SEM_PER_THREAD + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; +#endif + tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + + /* maybe lwip_getsockopt_internal has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sock_set_errno(sock, err); + return err ? -1 : 0; +} + +#if !LWIP_TCPIP_CORE_LOCKING +/** lwip_setsockopt_callback: only used without CORE_LOCKING + * to get into the tcpip_thread + */ +static void +lwip_setsockopt_callback(void *arg) +{ + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data*)arg; + + data->err = lwip_setsockopt_impl(data->s, data->level, data->optname, data->optval, + data->optlen); + + sys_sem_signal((sys_sem_t*)(data->completed_sem)); +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** lwip_setsockopt_impl: the actual implementation of setsockopt: + * same argument as lwip_setsockopt, either called directly or through callback + */ +static u8_t +lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + u8_t err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } + + switch (level) { + +/* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* SO_ACCEPTCONN is get-only */ + + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: +#if SO_REUSE + case SO_REUSEADDR: +#endif /* SO_REUSE */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + if (*(int*)optval) { + ip_set_option(sock->conn->pcb.ip, optname); + } else { + ip_reset_option(sock->conn->pcb.ip, optname); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(int*)optval?"on":"off"))); + break; + + /* SO_TYPE is get-only */ + /* SO_ERROR is get-only */ + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + netconn_set_sendtimeout(sock->conn, LWIP_SO_SNDRCVTIMEO_GET_MS(optval)); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + netconn_set_recvtimeout(sock->conn, (int)LWIP_SO_SNDRCVTIMEO_GET_MS(optval)); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); + netconn_set_recvbufsize(sock->conn, *(int*)optval); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_UDP + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); +#if LWIP_UDPLITE + if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) { + /* this flag is only available for UDP, not for UDP lite */ + return EAFNOSUPPORT; + } +#endif /* LWIP_UDPLITE */ + if (*(int*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); + } + break; +#endif /* LWIP_UDP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +/* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->ttl = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->tos = (u8_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; +#if LWIP_IGMP + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + sock->conn->pcb.udp->ttl = (u8_t)(*(u8_t*)optval); + break; + case IP_MULTICAST_IF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); + inet_addr_to_ipaddr(&sock->conn->pcb.udp->multicast_ip, (struct in_addr*)optval); + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + if (*(u8_t*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); + } + break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + { + /* If this is a TCP or a RAW socket, ignore these options. */ + /* @todo: assign membership to this socket so that it is dropped when closing the socket */ + err_t igmp_err; + struct ip_mreq *imr = (struct ip_mreq *)optval; + ip_addr_t if_addr; + ip_addr_t multi_addr; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); + inet_addr_to_ipaddr(&if_addr, &imr->imr_interface); + inet_addr_to_ipaddr(&multi_addr, &imr->imr_multiaddr); + if(optname == IP_ADD_MEMBERSHIP){ + igmp_err = igmp_joingroup(&if_addr, &multi_addr); + } else { + igmp_err = igmp_leavegroup(&if_addr, &multi_addr); + } + if (igmp_err != ERR_OK) { + err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP +/* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); + switch (optname) { + case TCP_NODELAY: + if (*(int*)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(int *)optval)?"on":"off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(int*)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP*/ + +#if LWIP_IPV6 +/* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + /* @todo: this does not work for datagram sockets, yet */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); + if (*(int*)optval) { + sock->conn->flags |= NETCONN_FLAG_IPV6_V6ONLY; + } else { + sock->conn->flags &= ~NETCONN_FLAG_IPV6_V6ONLY; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", + s, ((sock->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) ? 1 : 0))); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(int*)optval != 0) && ((*(int*)optval < 8) || (*(int*)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(int*)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(int*)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { +#if LWIP_IPV6 + case IPV6_CHECKSUM: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); + if (*(int *)optval < 0) { + sock->conn->pcb.raw->chksum_reqd = 0; + } else if (*(int *)optval & 1) { + /* Per RFC3542, odd offsets are not allowed */ + return EINVAL; + } else { + sock->conn->pcb.raw->chksum_reqd = 1; + sock->conn->pcb.raw->chksum_offset = *(int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", + s, sock->conn->pcb.raw->chksum_reqd)); + break; +#endif /* LWIP_IPV6 */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + return err; +} + +int +lwip_ioctl(int s, long cmd, void *argp) +{ + struct lwip_sock *sock = get_socket(s); + u8_t val; +#if LWIP_SO_RCVBUF + u16_t buflen = 0; + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + if (!sock) { + return -1; + } + + switch (cmd) { +#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE + case FIONREAD: + if (!argp) { + sock_set_errno(sock, EINVAL); + return -1; + } +#if LWIP_FIONREAD_LINUXMODE + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + struct pbuf *p; + if (sock->lastdata) { + p = ((struct netbuf *)sock->lastdata)->p; + } else { + struct netbuf *rxbuf; + err_t err; + if (sock->rcvevent <= 0) { + *((u16_t*)argp) = 0; + } else { + err = netconn_recv(sock->conn, &rxbuf); + if (err != ERR_OK) { + *((u16_t*)argp) = 0; + } else { + sock->lastdata = rxbuf; + *((u16_t*)argp) = rxbuf->p->tot_len; + } + } + } + return 0; + } +#endif /* LWIP_FIONREAD_LINUXMODE */ + +#if LWIP_SO_RCVBUF + /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) { + recv_avail = 0; + } + *((int*)argp) = recv_avail; + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata) { + struct pbuf *p = (struct pbuf *)sock->lastdata; + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + p = ((struct netbuf *)p)->p; + } + buflen = p->tot_len; + buflen -= sock->lastoffset; + + *((int*)argp) += buflen; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); + sock_set_errno(sock, 0); + return 0; +#else /* LWIP_SO_RCVBUF */ + break; +#endif /* LWIP_SO_RCVBUF */ +#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ + + case (long)FIONBIO: + val = 0; + if (argp && *(u32_t*)argp) { + val = 1; + } + netconn_set_nonblocking(sock->conn, val); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); + sock_set_errno(sock, 0); + return 0; + + default: + break; + } /* switch (cmd) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + return -1; +} + +/** A minimal implementation of fcntl. + * Currently only the commands F_GETFL and F_SETFL are implemented. + * Only the flag O_NONBLOCK is implemented. + */ +int +lwip_fcntl(int s, int cmd, int val) +{ + struct lwip_sock *sock = get_socket(s); + int ret = -1; + + if (!sock) { + return -1; + } + + switch (cmd) { + case F_GETFL: + ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; + sock_set_errno(sock, 0); + break; + case F_SETFL: + if ((val & ~O_NONBLOCK) == 0) { + /* only O_NONBLOCK, all other bits are zero */ + netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); + ret = 0; + sock_set_errno(sock, 0); + } else { + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + break; + } + return ret; +} + +/************************************************************** +* Added by Realtek Begin * +**************************************************************/ +int lwip_allocsocketsd() +{ + struct netconn *conn; + int i; + + /*new a netconn due to avoid some socket->conn check*/ + conn = netconn_new_with_proto_and_callback(NETCONN_RAW, 0, NULL); + if (!conn) { + printf("\r\n could not create netconn"); + return -1; + } + + /*alloc a socket*/ + i = alloc_socket(conn, 1); + if (i == -1) { + netconn_delete(conn); + printf("\r\n alloc socket fail!"); + return -1; + } + + conn->socket = i; + return i; +} +void lwip_setsockrcvevent(int fd, int rcvevent) +{ + struct lwip_sock *sock = get_socket(fd); + + if(sock){ + if(rcvevent) + sock->rcvevent = 1; + else + sock->rcvevent = 0; + } +} +void lwip_selectevindicate(int fd) +{ + struct lwip_select_cb *scb; + struct lwip_sock *sock; + + sock = get_socket(fd); + SYS_ARCH_DECL_PROTECT(lev); + while (1) { + SYS_ARCH_PROTECT(lev); + for (scb = select_cb_list; scb; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* Test this select call for our socket */ + if (scb->readset && FD_ISSET(fd, scb->readset)) + if (sock->rcvevent > 0) + break; + if (scb->writeset && FD_ISSET(fd, scb->writeset)) + if (sock->sendevent) + break; + } + } + if (scb) { + scb->sem_signalled = 1; + sys_sem_signal(&scb->sem); + SYS_ARCH_UNPROTECT(lev); + } else { + SYS_ARCH_UNPROTECT(lev); + break; + } + } +} +/************************************************************** +* Added by Realtek end * +**************************************************************/ + +#endif /* LWIP_SOCKET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/tcpip.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/tcpip.c new file mode 100644 index 0000000..7db7135 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/api/tcpip.c @@ -0,0 +1,581 @@ +/** + * @file + * Sequential API Main thread module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/memp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/tcpip.h" +#include "lwip/init.h" +#include "lwip/lwip_ip.h" +#include "netif/etharp.h" +#include "netif/ppp/pppoe.h" + +#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) +#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) +#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name) +#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) + +/* global variables */ +static tcpip_init_done_fn tcpip_init_done; +static void *tcpip_init_done_arg; +static sys_mbox_t mbox; + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +sys_mutex_t lock_tcpip_core; +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + +/** + * The main lwIP thread. This thread has exclusive access to lwIP core functions + * (unless access to them is not locked). Other threads communicate with this + * thread using message boxes. + * + * It also starts all the timers to make sure they are running in the right + * thread context. + * + * @param arg unused argument + */ +static void +tcpip_thread(void *arg) +{ + struct tcpip_msg *msg; + LWIP_UNUSED_ARG(arg); + + if (tcpip_init_done != NULL) { + tcpip_init_done(tcpip_init_done_arg); + } + + LOCK_TCPIP_CORE(); + while (1) { /* MAIN Loop */ + UNLOCK_TCPIP_CORE(); + LWIP_TCPIP_THREAD_ALIVE(); + /* wait for a message, timeouts are processed while waiting */ + sys_timeouts_mbox_fetch(&mbox, (void **)&msg); + LOCK_TCPIP_CORE(); + if (msg == NULL) { + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n")); + LWIP_ASSERT("tcpip_thread: invalid message", 0); + continue; + } + switch (msg->type) { +#if LWIP_NETCONN || LWIP_SOCKET + case TCPIP_MSG_API: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); + msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); + break; +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#if !LWIP_TCPIP_CORE_LOCKING_INPUT + case TCPIP_MSG_INPKT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); +#if LWIP_ETHERNET + if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); + } else +#endif /* LWIP_ETHERNET */ +#if LWIP_IPV6 + if ((*((unsigned char *)(msg->msg.inp.p->payload)) & 0xf0) == 0x60) { + ip6_input(msg->msg.inp.p, msg->msg.inp.netif); + } else +#endif /* LWIP_IPV6 */ + { + ip_input(msg->msg.inp.p, msg->msg.inp.netif); + } + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + break; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + +#if LWIP_NETIF_API + case TCPIP_MSG_NETIFAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); + msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); + break; +#endif /* LWIP_NETIF_API */ + +#if LWIP_PPP_API + case TCPIP_MSG_PPPAPI: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PPP API message %p\n", (void *)msg)); + msg->msg.pppapimsg->function(&(msg->msg.pppapimsg->msg)); + break; +#endif /* LWIP_PPP_API */ + +#if LWIP_TCPIP_TIMEOUT + case TCPIP_MSG_TIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); + sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + case TCPIP_MSG_UNTIMEOUT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); + sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; +#endif /* LWIP_TCPIP_TIMEOUT */ + + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_CALLBACK_STATIC: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + break; + + default: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); + LWIP_ASSERT("tcpip_thread: invalid message", 0); + break; + } + } +} + +/** + * Pass a received packet to tcpip_thread for input processing + * + * @param p the received packet, p->payload pointing to the Ethernet header or + * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or + * NETIF_FLAG_ETHERNET flags) + * @param inp the network interface on which the packet was received + */ +err_t +tcpip_input(struct pbuf *p, struct netif *inp) +{ +#if LWIP_TCPIP_CORE_LOCKING_INPUT + err_t ret; + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); + LOCK_TCPIP_CORE(); +#if LWIP_ETHERNET + if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { + ret = ethernet_input(p, inp); + } else +#endif /* LWIP_ETHERNET */ + { + ret = ip_input(p, inp); + } + UNLOCK_TCPIP_CORE(); + return ret; +#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ + struct tcpip_msg *msg; + + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_INPKT; + msg->msg.inp.p = p; + msg->msg.inp.netif = inp; + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } + return ERR_OK; +#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ +} + +/** + * Call a specific function in the thread context of + * tcpip_thread for easy access synchronization. + * A function called in that way may access lwIP core code + * without fearing concurrent access. + * + * @param f the function to call + * @param ctx parameter passed to f + * @param block 1 to block until the request is posted, 0 to non-blocking mode + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + if (block) { + sys_mbox_post(&mbox, msg); + } else { + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_API, msg); + return ERR_MEM; + } + } + return ERR_OK; + } + return ERR_VAL; +} + +#if LWIP_TCPIP_TIMEOUT +/** + * call sys_timeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_TIMEOUT; + msg->msg.tmo.msecs = msecs; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} + +/** + * call sys_untimeout in tcpip_thread + * + * @param msec time in milliseconds for timeout + * @param h function to be called on timeout + * @param arg argument to pass to timeout function h + * @return ERR_MEM on memory error, ERR_OK otherwise + */ +err_t +tcpip_untimeout(sys_timeout_handler h, void *arg) +{ + struct tcpip_msg *msg; + + if (sys_mbox_valid(&mbox)) { + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_UNTIMEOUT; + msg->msg.tmo.h = h; + msg->msg.tmo.arg = arg; + sys_mbox_post(&mbox, msg); + return ERR_OK; + } + return ERR_VAL; +} +#endif /* LWIP_TCPIP_TIMEOUT */ + +#if LWIP_NETCONN || LWIP_SOCKET +/** + * Call the lower part of a netconn_* function + * This function is then running in the thread context + * of tcpip_thread and has exclusive access to lwIP core code. + * + * @param apimsg a struct containing the function to call and its parameters + * @return ERR_OK if the function was called, another err_t if not + */ +err_t +tcpip_apimsg(struct api_msg *apimsg) +{ + TCPIP_MSG_VAR_DECLARE(msg); +#ifdef LWIP_DEBUG + /* catch functions that don't set err */ + apimsg->msg.err = ERR_VAL; +#endif + + if (sys_mbox_valid(&mbox)) { +/* raise priority temporary if not support LWIP_NETCONN_SEM_PER_THREAD */ +#if !LWIP_NETCONN_SEM_PER_THREAD + UBaseType_t prio = uxTaskPriorityGet(NULL); // add to prevent switch to tcpip thread between mbox post and sem wait + if((TCPIP_THREAD_PRIO + 1) > prio) + vTaskPrioritySet(NULL, TCPIP_THREAD_PRIO + 1); // set priority higher than tcpip thread +#endif + TCPIP_MSG_VAR_ALLOC(msg); + TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; + TCPIP_MSG_VAR_REF(msg).msg.apimsg = apimsg; +#if LWIP_NETCONN_SEM_PER_THREAD + apimsg->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); + LWIP_ASSERT("netconn semaphore not initialized", + apimsg->msg.op_completed_sem != SYS_SEM_NULL); +#endif + sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); + sys_arch_sem_wait(LWIP_API_MSG_SEM(&apimsg->msg), 0); + TCPIP_MSG_VAR_FREE(msg); +#if !LWIP_NETCONN_SEM_PER_THREAD + vTaskPrioritySet(NULL, prio); // restore to original priority +#endif + return apimsg->msg.err; + } + return ERR_VAL; +} + +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#if LWIP_NETIF_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a netifapi_* + * function. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_netifapi(struct netifapi_msg* netifapimsg) +{ + TCPIP_MSG_VAR_DECLARE(msg); + + if (sys_mbox_valid(&mbox)) { + err_t err; + TCPIP_MSG_VAR_ALLOC(msg); + + err = sys_sem_new(&netifapimsg->msg.sem, 0); + if (err != ERR_OK) { + netifapimsg->msg.err = err; + return err; + } + + TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_NETIFAPI; + TCPIP_MSG_VAR_REF(msg).msg.netifapimsg = netifapimsg; + sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); + sys_sem_wait(&netifapimsg->msg.sem); + sys_sem_free(&netifapimsg->msg.sem); + TCPIP_MSG_VAR_FREE(msg); + return netifapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a netifapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param netifapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_netifapi()) + */ +err_t +tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) +{ + LOCK_TCPIP_CORE(); + netifapimsg->function(&(netifapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return netifapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +#if LWIP_PPP_API +#if !LWIP_TCPIP_CORE_LOCKING +/** + * Much like tcpip_apimsg, but calls the lower part of a pppapi_* + * function. + * + * @param pppapimsg a struct containing the function to call and its parameters + * @return error code given back by the function that was called + */ +err_t +tcpip_pppapi(struct pppapi_msg* pppapimsg) +{ + struct tcpip_msg msg; + + if (sys_mbox_valid(&mbox)) { + err_t err = sys_sem_new(&pppapimsg->msg.sem, 0); + if (err != ERR_OK) { + pppapimsg->msg.err = err; + return err; + } + + msg.type = TCPIP_MSG_PPPAPI; + msg.msg.pppapimsg = pppapimsg; + sys_mbox_post(&mbox, &msg); + sys_sem_wait(&pppapimsg->msg.sem); + sys_sem_free(&pppapimsg->msg.sem); + return pppapimsg->msg.err; + } + return ERR_VAL; +} +#else /* !LWIP_TCPIP_CORE_LOCKING */ +/** + * Call the lower part of a pppapi_* function + * This function has exclusive access to lwIP core code by locking it + * before the function is called. + * + * @param pppapimsg a struct containing the function to call and its parameters + * @return ERR_OK (only for compatibility fo tcpip_pppapi()) + */ +err_t +tcpip_pppapi_lock(struct pppapi_msg* pppapimsg) +{ + LOCK_TCPIP_CORE(); + pppapimsg->function(&(pppapimsg->msg)); + UNLOCK_TCPIP_CORE(); + return pppapimsg->msg.err; +} +#endif /* !LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_PPP_API */ + +/** + * Allocate a structure for a static callback message and initialize it. + * This is intended to be used to send "static" messages from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to function + * @return a struct pointer to pass to tcpip_trycallback(). + */ +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +{ + struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return NULL; + } + msg->type = TCPIP_MSG_CALLBACK_STATIC; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + return (struct tcpip_callback_msg*)msg; +} + +/** + * Free a callback message allocated by tcpip_callbackmsg_new(). + * + * @param msg the message to free + */ +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) +{ + memp_free(MEMP_TCPIP_MSG_API, msg); +} + +/** + * Try to post a callback-message to the tcpip_thread mbox + * This is intended to be used to send "static" messages from interrupt context. + * + * @param msg pointer to the message to post + * @return sys_mbox_trypost() return code + */ +err_t +tcpip_trycallback(struct tcpip_callback_msg* msg) +{ + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + return sys_mbox_trypost(&mbox, msg); +} + +/** + * Initialize this module: + * - initialize all sub modules + * - start the tcpip_thread + * + * @param initfunc a function to call when tcpip_thread is running and finished initializing + * @param arg argument to pass to initfunc + */ +void +tcpip_init(tcpip_init_done_fn initfunc, void *arg) +{ + lwip_init(); + + tcpip_init_done = initfunc; + tcpip_init_done_arg = arg; + if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { + LWIP_ASSERT("failed to create tcpip_thread mbox", 0); + } +#if LWIP_TCPIP_CORE_LOCKING + if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) { + LWIP_ASSERT("failed to create lock_tcpip_core", 0); + } +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +// sys_thread_new_tcm(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); + sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); +} + +/** + * Simple callback function used with tcpip_callback to free a pbuf + * (pbuf_free has a wrong signature for tcpip_callback) + * + * @param p The pbuf (chain) to be dereferenced. + */ +static void +pbuf_free_int(void *p) +{ + struct pbuf *q = (struct pbuf *)p; + pbuf_free(q); +} + +/** + * A simple wrapper function that allows you to free a pbuf from interrupt context. + * + * @param p The pbuf (chain) to be dereferenced. + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +pbuf_free_callback(struct pbuf *p) +{ + return tcpip_callback_with_block(pbuf_free_int, p, 0); +} + +/** + * A simple wrapper function that allows you to free heap memory from + * interrupt context. + * + * @param m the heap memory to free + * @return ERR_OK if callback could be enqueued, an err_t if not + */ +err_t +mem_free_callback(void *m) +{ + return tcpip_callback_with_block(mem_free, m, 0); +} + +#endif /* !NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/def.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/def.c new file mode 100644 index 0000000..352b552 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/def.c @@ -0,0 +1,108 @@ +/** + * @file + * Common functions used throughout the stack. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ + +#include "lwip/opt.h" +#include "lwip/def.h" + +/** + * These are reference implementations of the byte swapping functions. + * Again with the aim of being simple, correct and fully portable. + * Byte swapping is the second thing you would want to optimize. You will + * need to port it to your architecture and in your cc.h: + * + * #define LWIP_PLATFORM_BYTESWAP 1 + * #define LWIP_PLATFORM_HTONS(x) + * #define LWIP_PLATFORM_HTONL(x) + * + * Note ntohs() and ntohl() are merely references to the htonx counterparts. + */ + +#if (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) + +/** + * Convert an u16_t from host- to network byte order. + * + * @param n u16_t in host byte order + * @return n in network byte order + */ +u16_t +lwip_htons(u16_t n) +{ + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); +} + +/** + * Convert an u16_t from network- to host byte order. + * + * @param n u16_t in network byte order + * @return n in host byte order + */ +u16_t +lwip_ntohs(u16_t n) +{ + return lwip_htons(n); +} + +/** + * Convert an u32_t from host- to network byte order. + * + * @param n u32_t in host byte order + * @return n in network byte order + */ +u32_t +lwip_htonl(u32_t n) +{ + return ((n & 0xff) << 24) | + ((n & 0xff00) << 8) | + ((n & 0xff0000UL) >> 8) | + ((n & 0xff000000UL) >> 24); +} + +/** + * Convert an u32_t from network- to host byte order. + * + * @param n u32_t in network byte order + * @return n in host byte order + */ +u32_t +lwip_ntohl(u32_t n) +{ + return lwip_htonl(n); +} + +#endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dhcp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dhcp.c new file mode 100644 index 0000000..22321f3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dhcp.c @@ -0,0 +1,1844 @@ +/** + * @file + * Dynamic Host Configuration Protocol client + * + */ + +/* + * + * Copyright (c) 2001-2004 Leon Woestenberg + * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. + * + * Author: Leon Woestenberg + * + * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform + * with RFC 2131 and RFC 2132. + * + * TODO: + * - Support for interfaces other than Ethernet (SLIP, PPP, ...) + * + * Please coordinate changes and requests with Leon Woestenberg + * + * + * Integration with your code: + * + * In lwip/dhcp.h + * #define DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) + * #define DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) + * + * Then have your application call dhcp_coarse_tmr() and + * dhcp_fine_tmr() on the defined intervals. + * + * dhcp_start(struct netif *netif); + * starts a DHCP client instance which configures the interface by + * obtaining an IP address lease and maintaining it. + * + * Use dhcp_release(netif) to end the lease and use dhcp_stop(netif) + * to remove the DHCP client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/dns.h" +#include "netif/etharp.h" + +#include + +/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using + * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) + */ +#ifndef DHCP_CREATE_RAND_XID +#define DHCP_CREATE_RAND_XID 1 +#endif + +/** Default for DHCP_GLOBAL_XID is 0xABCD0000 + * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. + * #define DHCP_GLOBAL_XID_HEADER "stdlib.h" + * #define DHCP_GLOBAL_XID rand() + */ +#ifdef DHCP_GLOBAL_XID_HEADER +#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ +#endif + +/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU + * MTU is checked to be big enough in dhcp_start */ +#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) +#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 +/** Minimum length for reply before packet is parsed */ +#define DHCP_MIN_REPLY_LEN 44 + +#define REBOOT_TRIES 2 + +/** Option handling: options are parsed in dhcp_parse_reply + * and saved in an array where other functions can load them from. + * This might be moved into the struct dhcp (not necessarily since + * lwIP is single-threaded and the array is only used while in recv + * callback). */ +#define DHCP_OPTION_IDX_OVERLOAD 0 +#define DHCP_OPTION_IDX_MSG_TYPE 1 +#define DHCP_OPTION_IDX_SERVER_ID 2 +#define DHCP_OPTION_IDX_LEASE_TIME 3 +#define DHCP_OPTION_IDX_T1 4 +#define DHCP_OPTION_IDX_T2 5 +#define DHCP_OPTION_IDX_SUBNET_MASK 6 +#define DHCP_OPTION_IDX_ROUTER 7 +#define DHCP_OPTION_IDX_DNS_SERVER 8 +#define DHCP_OPTION_IDX_MAX (DHCP_OPTION_IDX_DNS_SERVER + DNS_MAX_SERVERS) + +/** Holds the decoded option values, only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; +/** Holds a flag which option was received and is contained in dhcp_rx_options_val, + only valid while in dhcp_recv. + @todo: move this into struct dhcp? */ +u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; + +#ifdef DHCP_GLOBAL_XID +static u32_t xid; +static u8_t xid_initialised; +#endif /* DHCP_GLOBAL_XID */ + +#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) +#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) +#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) +#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) +#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) +#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) + + +/* DHCP client state machine functions */ +static err_t dhcp_discover(struct netif *netif); +static err_t dhcp_select(struct netif *netif); +static void dhcp_bind(struct netif *netif); +#if DHCP_DOES_ARP_CHECK +static err_t dhcp_decline(struct netif *netif); +#endif /* DHCP_DOES_ARP_CHECK */ +static err_t dhcp_rebind(struct netif *netif); +static err_t dhcp_reboot(struct netif *netif); +static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); + +/* receive, unfold, parse and free incoming messages */ +static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); + +/* set the DHCP timers */ +static void dhcp_timeout(struct netif *netif); +static void dhcp_t1_timeout(struct netif *netif); +static void dhcp_t2_timeout(struct netif *netif); + +/* build outgoing messages */ +/* create a DHCP message, fill in common headers */ +static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type); +/* free a DHCP request */ +static void dhcp_delete_msg(struct dhcp *dhcp); +/* add a DHCP option (type, then length in bytes) */ +static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); +/* add option values */ +static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); +static void dhcp_option_short(struct dhcp *dhcp, u16_t value); +static void dhcp_option_long(struct dhcp *dhcp, u32_t value); +#if LWIP_NETIF_HOSTNAME +static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); +#endif /* LWIP_NETIF_HOSTNAME */ +/* always add the DHCP options trailer to end and pad */ +static void dhcp_option_trailer(struct dhcp *dhcp); + +/** + * Back-off the DHCP client (because of a received NAK response). + * + * Back-off the DHCP client because of a received NAK. Receiving a + * NAK means the client asked for something non-sensible, for + * example when it tries to renew a lease obtained on another network. + * + * We clear any existing set IP address and restart DHCP negotiation + * afresh (as per RFC2131 3.2.3). + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_nak(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* Set the interface down since the address must no longer be used, as per RFC2131 */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + /* Change to a defined state */ + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* We can immediately restart discovery */ + dhcp_discover(netif); +} + +#if DHCP_DOES_ARP_CHECK +/** + * Checks if the offered IP address is already in use. + * + * It does so by sending an ARP request for the offered address and + * entering CHECKING state. If no ARP reply is received within a small + * interval, the address is assumed to be free for use by us. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_check(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], + (s16_t)netif->name[1])); + dhcp_set_state(dhcp, DHCP_CHECKING); + /* create an ARP query for the offered IP address, expecting that no host + responds, as the IP address should not be in use. */ + result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); + if (result != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); + } + dhcp->tries++; + msecs = 500; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); +} +#endif /* DHCP_DOES_ARP_CHECK */ + +/** + * Remember the configuration offered by a DHCP server. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_offer(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + /* obtain the server address */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { + ip4_addr_set_u32(&dhcp->server_ip_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->server_ip_addr))); + /* remember offered address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif)); + } +} + +/** + * Select a DHCP server offer out of all offers. + * + * Simply select the first offer received. + * + * @param netif the netif under DHCP control + * @return lwIP specific error (see error.h) + */ +static err_t +dhcp_select(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + dhcp_set_state(dhcp, DHCP_REQUESTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + /* MUST request the offered IP address */ + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr))); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + dhcp_option_trailer(dhcp); + /* shrink the pbuf to the actual content length */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* send broadcast to any DHCP server */ + udp_sendto_if_src(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP_ADDR_ANY); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * The DHCP timer that checks for lease renewal/rebind timeouts. + */ +void +dhcp_coarse_tmr() +{ + struct netif *netif = netif_list; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); + /* iterate through all network interfaces */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and triggers (zeroes) now? */ + if (netif->dhcp->t2_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); + /* this clients' rebind timeout triggered */ + dhcp_t2_timeout(netif); + /* timer is active (non zero), and triggers (zeroes) now */ + } else if (netif->dhcp->t1_timeout-- == 1) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); + /* this clients' renewal timeout triggered */ + dhcp_t1_timeout(netif); + } + } + /* proceed to next netif */ + netif = netif->next; + } +} + +/** + * DHCP transaction timeout handling + * + * A DHCP server is expected to respond within a short period of time. + * This timer checks whether an outstanding DHCP request is timed out. + */ +void +dhcp_fine_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on DHCP configured interfaces */ + if (netif->dhcp != NULL) { + /* timer is active (non zero), and is about to trigger now */ + if (netif->dhcp->request_timeout > 1) { + netif->dhcp->request_timeout--; + } + else if (netif->dhcp->request_timeout == 1) { + netif->dhcp->request_timeout--; + /* { netif->dhcp->request_timeout == 0 } */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); + /* this client's request timeout triggered */ + dhcp_timeout(netif); + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * A DHCP negotiation transaction, or ARP request, has timed out. + * + * The timer that was started with the DHCP or ARP request has + * timed out, indicating no response was received in time. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); + /* back-off period has passed, or server selection timed out */ + if ((dhcp->state == DHCP_BACKING_OFF) || (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); + dhcp_discover(netif); + /* receiving the requested lease timed out */ + } else if (dhcp->state == DHCP_REQUESTING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); + if (dhcp->tries <= 5) { + dhcp_select(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); + dhcp_release(netif); + dhcp_discover(netif); + } +#if DHCP_DOES_ARP_CHECK + /* received no ARP reply for the offered address (which is good) */ + } else if (dhcp->state == DHCP_CHECKING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); + if (dhcp->tries <= 1) { + dhcp_check(netif); + /* no ARP replies on the offered address, + looks like the IP address is indeed free */ + } else { + /* bind the interface to the offered address */ + dhcp_bind(netif); + } +#endif /* DHCP_DOES_ARP_CHECK */ + } + /* did not get response to renew request? */ + else if (dhcp->state == DHCP_RENEWING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RENEWING, DHCP request timed out\n")); + /* just retry renewal */ + /* note that the rebind timer will eventually time-out if renew does not work */ + dhcp_renew(netif); + /* did not get response to rebind request? */ + } else if (dhcp->state == DHCP_REBINDING) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REBINDING, DHCP request timed out\n")); + if (dhcp->tries <= 8) { + dhcp_rebind(netif); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): RELEASING, DISCOVERING\n")); + dhcp_release(netif); + dhcp_discover(netif); + } + } else if (dhcp->state == DHCP_REBOOTING) { + if (dhcp->tries < REBOOT_TRIES) { + dhcp_reboot(netif); + } else { + dhcp_discover(netif); + } + } +} + +/** + * The renewal period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t1_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING)) { + /* just retry to renew - note that the rebind timer (t2) will + * eventually time-out if renew tries fail. */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t1_timeout(): must renew\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_RENEWING, not DHCP_BOUND */ + dhcp_renew(netif); + } +} + +/** + * The rebind period has timed out. + * + * @param netif the netif under DHCP control + */ +static void +dhcp_t2_timeout(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); + if ((dhcp->state == DHCP_REQUESTING) || (dhcp->state == DHCP_BOUND) || + (dhcp->state == DHCP_RENEWING)) { + /* just retry to rebind */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("dhcp_t2_timeout(): must rebind\n")); + /* This slightly different to RFC2131: DHCPREQUEST will be sent from state + DHCP_REBINDING, not DHCP_BOUND */ + dhcp_rebind(netif); + } +} + +/** + * Handle a DHCP ACK packet + * + * @param netif the netif under DHCP control + */ +static void +dhcp_handle_ack(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; +#if LWIP_DNS + u8_t n; +#endif /* LWIP_DNS */ + + /* clear options we might not get from the ACK */ + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* lease time given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { + /* remember offered lease time */ + dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); + } + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { + /* remember given renewal period */ + dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); + } else { + /* calculate safe periods for renewal */ + dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; + } + + /* renewal period given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { + /* remember given rebind period */ + dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); + } else { + /* calculate safe periods for rebinding */ + dhcp->offered_t2_rebind = dhcp->offered_t0_lease; + } + + /* (y)our internet address */ + ip_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); + +#if LWIP_DHCP_BOOTP_FILE + /* copy boot server address, + boot file name copied in dhcp_parse_reply if not overloaded */ + ip_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* subnet mask given? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { + /* remember given subnet mask */ + ip4_addr_set_u32(&dhcp->offered_sn_mask, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); + dhcp->subnet_mask_given = 1; + } else { + dhcp->subnet_mask_given = 0; + } + + /* gateway router */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { + ip4_addr_set_u32(&dhcp->offered_gw_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); + } + +#if LWIP_DNS + /* DNS servers */ + for(n = 0; (n < DNS_MAX_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { + ip_addr_t dns_addr; + ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); + dns_setserver(n, &dns_addr); + } +#endif /* LWIP_DNS */ +} + +/** Set a statically allocated struct dhcp to work with. + * Using this prevents dhcp_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct dhcp + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("dhcp != NULL", dhcp != NULL); + LWIP_ASSERT("netif already has a struct dhcp set", netif->dhcp == NULL); + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + netif->dhcp = dhcp; +} + +/** Removes a struct dhcp from a netif. + * + * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the + * struct dhcp since the memory is passed back to the heap. + * + * @param netif the netif from which to remove the struct dhcp + */ +void dhcp_cleanup(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + + if (netif->dhcp != NULL) { + mem_free(netif->dhcp); + netif->dhcp = NULL; + } +} + +/** + * Start DHCP negotiation for a network interface. + * + * If no DHCP client instance was attached to this interface, + * a new client is created first. If a DHCP client instance + * was already present, it restarts negotiation. + * + * @param netif The lwIP network interface + * @return lwIP error code + * - ERR_OK - No error + * - ERR_MEM - Out of memory + */ +err_t +dhcp_start(struct netif *netif) +{ + struct dhcp *dhcp; + err_t result; + + LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); + dhcp = netif->dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + + /* check hwtype of the netif */ + if ((netif->flags & NETIF_FLAG_ETHARP) == 0) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): No ETHARP netif\n")); + return ERR_ARG; + } + + /* check MTU of the netif */ + if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); + return ERR_MEM; + } + + /* Remove the flag that says this netif is handled by DHCP, + it is set when we succeeded starting. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + /* no DHCP client attached yet? */ + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting new DHCP client\n")); + dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); + if (dhcp == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); + return ERR_MEM; + } + /* store this dhcp client in the netif */ + netif->dhcp = dhcp; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); + /* already has DHCP client attached */ + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + } + LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); + } + + /* clear data structure */ + memset(dhcp, 0, sizeof(struct dhcp)); + /* dhcp_set_state(&dhcp, DHCP_OFF); */ + /* allocate UDP PCB */ + dhcp->pcb = udp_new(); + if (dhcp->pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not obtain pcb\n")); + return ERR_MEM; + } + ip_set_option(dhcp->pcb, SOF_BROADCAST); + /* set up local and remote port for the pcb */ + udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT); + /* set up the recv callback and argument */ + udp_recv(dhcp->pcb, dhcp_recv, netif); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); + +#if LWIP_DHCP_CHECK_LINK_UP + if (!netif_is_link_up(netif)) { + /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */ + dhcp_set_state(dhcp, DHCP_INIT); + netif->flags |= NETIF_FLAG_DHCP; + return ERR_OK; + } +#endif /* LWIP_DHCP_CHECK_LINK_UP */ + + /* (re)start the DHCP negotiation */ + result = dhcp_discover(netif); + if (result != ERR_OK) { + /* free resources allocated above */ + dhcp_stop(netif); + return ERR_MEM; + } + /* Set the flag that says this netif is handled by DHCP. */ + netif->flags |= NETIF_FLAG_DHCP; + return result; +} + +/** + * Inform a DHCP server of our manual configuration. + * + * This informs DHCP servers of our fixed IP address configuration + * by sending an INFORM message. It does not involve DHCP address + * configuration, it is just here to be nice to the network. + * + * @param netif The lwIP network interface + */ +void +dhcp_inform(struct netif *netif) +{ + struct dhcp dhcp; + err_t result = ERR_OK; + struct udp_pcb *pcb; + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + memset(&dhcp, 0, sizeof(struct dhcp)); + dhcp_set_state(&dhcp, DHCP_INFORM); + + if ((netif->dhcp != NULL) && (netif->dhcp->pcb != NULL)) { + /* re-use existing pcb */ + pcb = netif->dhcp->pcb; + } else { + pcb = udp_new(); + if (pcb == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform(): could not obtain pcb")); + return; + } + dhcp.pcb = pcb; + ip_set_option(dhcp.pcb, SOF_BROADCAST); + udp_bind(dhcp.pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_inform(): created new udp pcb\n")); + } + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM); + if (result == ERR_OK) { + dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option_trailer(&dhcp); + + pbuf_realloc(dhcp.p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp.options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); + udp_sendto_if(pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(&dhcp); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); + } + + if (dhcp.pcb != NULL) { + /* otherwise, the existing pcb was used */ + udp_remove(dhcp.pcb); + } +} + +/** Handle a possible change in the network configuration. + * + * This enters the REBOOTING state to verify that the currently bound + * address is still valid. + */ +void +dhcp_network_changed(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + if (!dhcp) + return; + switch (dhcp->state) { + case DHCP_REBINDING: + case DHCP_RENEWING: + case DHCP_BOUND: + case DHCP_REBOOTING: + netif_set_down(netif); + dhcp->tries = 0; + dhcp_reboot(netif); + break; + case DHCP_OFF: + /* stay off */ + break; + default: + /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the + state changes, SELECTING: continue with current 'rid' as we stay in the + same state */ +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + dhcp_discover(netif); + break; + } +} + +#if DHCP_DOES_ARP_CHECK +/** + * Match an ARP reply with the offered IP address. + * + * @param netif the network interface on which the reply was received + * @param addr The IP address we received a reply from + */ +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr) +{ + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); + /* is a DHCP client doing an ARP check? */ + if ((netif->dhcp != NULL) && (netif->dhcp->state == DHCP_CHECKING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", + ip4_addr_get_u32(addr))); + /* did a host respond with the address we + were offered by the DHCP server? */ + if (ip_addr_cmp(addr, &netif->dhcp->offered_ip_addr)) { + /* we will not accept the offered address */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); + dhcp_decline(netif); + } + } +} + +/** + * Decline an offered lease. + * + * Tell the DHCP server we do not accept the offered address. + * One reason to decline the lease is when we find out the address + * is already in use by another host (through ARP). + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_decline(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); + dhcp_set_state(dhcp, DHCP_BACKING_OFF); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + /* resize pbuf to reflect true size of options */ + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* per section 4.4.4, broadcast DECLINE messages */ + udp_sendto_if_src(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP_ADDR_ANY); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_decline: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = 10*1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} +#endif /* DHCP_DOES_ARP_CHECK */ + + +/** + * Start the DHCP process, discover a DHCP server. + * + * @param netif the netif under DHCP control + */ +static err_t +dhcp_discover(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result = ERR_OK; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); + ip_addr_set_any(&dhcp->offered_ip_addr); + dhcp_set_state(dhcp, DHCP_SELECTING); + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER); + if (result == ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); + + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + + dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, 4/*num options*/); + dhcp_option_byte(dhcp, DHCP_OPTION_SUBNET_MASK); + dhcp_option_byte(dhcp, DHCP_OPTION_ROUTER); + dhcp_option_byte(dhcp, DHCP_OPTION_BROADCAST); + dhcp_option_byte(dhcp, DHCP_OPTION_DNS_SERVER); + + dhcp_option_trailer(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: realloc()ing\n")); + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); + udp_sendto_if_src(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP_ADDR_ANY); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); + } + dhcp->tries++; +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; + autoip_start(netif); + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Bind the interface to the offered IP address. + * + * @param netif network interface to bind to the offered address + */ +static void +dhcp_bind(struct netif *netif) +{ + u32_t timeout; + struct dhcp *dhcp; + ip_addr_t sn_mask, gw_addr; + LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); + + /* temporary DHCP lease? */ + if (dhcp->offered_t1_renew != 0xffffffffUL) { + /* set renewal period timer */ + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); + timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t1_timeout = (u16_t)timeout; + if (dhcp->t1_timeout == 0) { + dhcp->t1_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); + } + /* set renewal period timer */ + if (dhcp->offered_t2_rebind != 0xffffffffUL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); + timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; + if(timeout > 0xffff) { + timeout = 0xffff; + } + dhcp->t2_timeout = (u16_t)timeout; + if (dhcp->t2_timeout == 0) { + dhcp->t2_timeout = 1; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); + } + + /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ + if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { + dhcp->t1_timeout = 0; + } + + if (dhcp->subnet_mask_given) { + /* copy offered network mask */ + ip_addr_copy(sn_mask, dhcp->offered_sn_mask); + } else { + /* subnet mask not given, choose a safe subnet mask given the network class */ + u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); + if (first_octet <= 127) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); + } else if (first_octet >= 192) { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); + } else { + ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); + } + } + + ip_addr_copy(gw_addr, dhcp->offered_gw_addr); + /* gateway address not given? */ + if (ip_addr_isany(&gw_addr)) { + /* copy network address */ + ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); + /* use first host address on network as gateway */ + ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); + } + +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F"\n", + ip4_addr_get_u32(&dhcp->offered_ip_addr))); + netif_set_ipaddr(netif, &dhcp->offered_ip_addr); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): SN: 0x%08"X32_F"\n", + ip4_addr_get_u32(&sn_mask))); + netif_set_netmask(netif, &sn_mask); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): GW: 0x%08"X32_F"\n", + ip4_addr_get_u32(&gw_addr))); + netif_set_gw(netif, &gw_addr); + /* bring the interface up */ + netif_set_up(netif); + /* netif is now bound to DHCP leased address */ + dhcp_set_state(dhcp, DHCP_BOUND); +} + +/** + * Renew an existing DHCP lease at the involved DHCP server. + * + * @param netif network interface which must renew its lease + */ +err_t +dhcp_renew(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); + dhcp_set_state(dhcp, DHCP_RENEWING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); +#endif + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + + /* append DHCP message trailer */ + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); + } + dhcp->tries++; + /* back-off on retries, but to a maximum of 20 seconds */ + msecs = dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Rebind with a DHCP server for an existing DHCP lease. + * + * @param netif network interface which must rebind with a DHCP server + */ +static err_t +dhcp_rebind(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); + dhcp_set_state(dhcp, DHCP_REBINDING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); + +#if LWIP_NETIF_HOSTNAME + dhcp_option_hostname(dhcp, netif); +#endif /* LWIP_NETIF_HOSTNAME */ + +#if 0 + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr)); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); +#endif + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + +/** + * Enter REBOOTING state to verify an existing lease + * + * @param netif network interface which must reboot + */ +static err_t +dhcp_reboot(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); + dhcp_set_state(dhcp, DHCP_REBOOTING); + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); + dhcp_option_short(dhcp, 576); + + dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); + dhcp_option_long(dhcp, ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + /* broadcast to server */ + udp_sendto_if(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); + return result; +} + + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + if (dhcp == NULL) { + return ERR_ARG; + } + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_OFF); + /* clean old DHCP offer */ + ip_addr_set_zero(&dhcp->server_ip_addr); + ip_addr_set_zero(&dhcp->offered_ip_addr); + ip_addr_set_zero(&dhcp->offered_sn_mask); + ip_addr_set_zero(&dhcp->offered_gw_addr); +#if LWIP_DHCP_BOOTP_FILE + ip_addr_set_zero(&dhcp->offered_si_addr); +#endif /* LWIP_DHCP_BOOTP_FILE */ + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); + if (result == ERR_OK) { + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Release a DHCP lease. + * + * @param netif network interface which must release its lease + */ +err_t +dhcp_release_unicast(struct netif *netif) +{ + struct dhcp *dhcp = netif->dhcp; + err_t result; + u16_t msecs; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); + + /* idle DHCP client */ + dhcp_set_state(dhcp, DHCP_RELEASING); + /* clean old DHCP offer *//* + dhcp->server_ip_addr.addr = 0; + dhcp->offered_ip_addr.addr = dhcp->offered_sn_mask.addr = 0; + dhcp->offered_gw_addr.addr = dhcp->offered_bc_addr.addr = 0; + dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; + dhcp->dns_count = 0;*/ + + /* create and initialize the DHCP message header */ + result = dhcp_create_msg(netif,netif->dhcp,DHCP_REQUEST); + if (result == ERR_OK) { + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, DHCP_RELEASE); + + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, ntohl(dhcp->server_ip_addr.addr)); + + dhcp_option_trailer(dhcp); + + pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len); + + udp_sendto_if(dhcp->pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); + dhcp_delete_msg(netif->dhcp); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_OFF\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); + } + dhcp->tries++; + msecs = dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000; + dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release(): set request timeout %"U16_F" msecs\n", msecs)); + /* bring the interface down */ + netif_set_down(netif); + /* remove IP address from interface */ + netif_set_ipaddr(netif, IP_ADDR_ANY); + netif_set_gw(netif, IP_ADDR_ANY); + netif_set_netmask(netif, IP_ADDR_ANY); + + /* TODO: netif_down(netif); */ + return result; +} + +/** + * Remove the DHCP client from the interface. + * + * @param netif The network interface to stop DHCP on + */ +void +dhcp_stop(struct netif *netif) +{ + struct dhcp *dhcp; + LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); + dhcp = netif->dhcp; + /* Remove the flag that says this netif is handled by DHCP. */ + netif->flags &= ~NETIF_FLAG_DHCP; + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); + /* netif is DHCP configured? */ + if (dhcp != NULL) { +#if LWIP_DHCP_AUTOIP_COOP + if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { + autoip_stop(netif); + dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; + } +#endif /* LWIP_DHCP_AUTOIP_COOP */ + + if (dhcp->pcb != NULL) { + udp_remove(dhcp->pcb); + dhcp->pcb = NULL; + } + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + dhcp_set_state(dhcp, DHCP_OFF); + } +} + +/* + * Set the DHCP state of a DHCP client. + * + * If the state changed, reset the number of tries. + */ +static void +dhcp_set_state(struct dhcp *dhcp, u8_t new_state) +{ + if (new_state != dhcp->state) { + dhcp->state = new_state; + dhcp->tries = 0; + dhcp->request_timeout = 0; + } +} + +/* + * Concatenate an option type and length field to the outgoing + * DHCP message. + * + */ +static void +dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) +{ + LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = option_type; + dhcp->msg_out->options[dhcp->options_out_len++] = option_len; +} +/* + * Concatenate a single byte to the outgoing DHCP message. + * + */ +static void +dhcp_option_byte(struct dhcp *dhcp, u8_t value) +{ + LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = value; +} + +static void +dhcp_option_short(struct dhcp *dhcp, u16_t value) +{ + LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); +} + +static void +dhcp_option_long(struct dhcp *dhcp, u32_t value) +{ + LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); + dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); +} + +#if LWIP_NETIF_HOSTNAME +static void +dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) +{ + if (netif->hostname != NULL) { + size_t namelen = strlen(netif->hostname); + if (namelen > 0) { + u8_t len; + const char *p = netif->hostname; + /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME + and 1 byte for trailer) */ + size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; + LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); + len = LWIP_MIN(namelen, available); + dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, len); + while (len--) { + dhcp_option_byte(dhcp, *p++); + } + } + } +} +#endif /* LWIP_NETIF_HOSTNAME */ + +/** + * Extract the DHCP message and the DHCP options. + * + * Extract the DHCP message and the DHCP options, each into a contiguous + * piece of memory. As a DHCP message is variable sized by its options, + * and also allows overriding some fields for options, the easy approach + * is to first unfold the options into a contiguous piece of memory, and + * use that further on. + * + */ +static err_t +dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) +{ + u8_t *options; + u16_t offset; + u16_t offset_max; + u16_t options_idx; + u16_t options_idx_max; + struct pbuf *q; + int parse_file_as_options = 0; + int parse_sname_as_options = 0; + + /* clear received options */ + dhcp_clear_all_options(dhcp); + /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ + if (p->len < DHCP_SNAME_OFS) { + return ERR_BUF; + } + dhcp->msg_in = (struct dhcp_msg *)p->payload; +#if LWIP_DHCP_BOOTP_FILE + /* clear boot file name */ + dhcp->boot_file_name[0] = 0; +#endif /* LWIP_DHCP_BOOTP_FILE */ + + /* parse options */ + + /* start with options field */ + options_idx = DHCP_OPTIONS_OFS; + /* parse options to the end of the received packet */ + options_idx_max = p->tot_len; +again: + q = p; + while((q != NULL) && (options_idx >= q->len)) { + options_idx -= q->len; + options_idx_max -= q->len; + q = q->next; + } + if (q == NULL) { + return ERR_BUF; + } + offset = options_idx; + offset_max = options_idx_max; + options = (u8_t*)q->payload; + /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ + while((q != NULL) && (options[offset] != DHCP_OPTION_END) && (offset < offset_max)) { + u8_t op = options[offset]; + u8_t len; + u8_t decode_len = 0; + int decode_idx = -1; + u16_t val_offset = offset + 2; + /* len byte might be in the next pbuf */ + if (offset + 1 < q->len) { + len = options[offset + 1]; + } else { + len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0); + } + /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ + decode_len = len; + switch(op) { + /* case(DHCP_OPTION_END): handled above */ + case(DHCP_OPTION_PAD): + /* special option: no len encoded */ + decode_len = len = 0; + /* will be increased below */ + offset--; + break; + case(DHCP_OPTION_SUBNET_MASK): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; + break; + case(DHCP_OPTION_ROUTER): + decode_len = 4; /* only copy the first given router */ + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_ROUTER; + break; + case(DHCP_OPTION_DNS_SERVER): + /* special case: there might be more than one server */ + LWIP_ERROR("len % 4 == 0", len % 4 == 0, return ERR_VAL;); + /* limit number of DNS servers */ + decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); + LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_DNS_SERVER; + break; + case(DHCP_OPTION_LEASE_TIME): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_LEASE_TIME; + break; + case(DHCP_OPTION_OVERLOAD): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_OVERLOAD; + break; + case(DHCP_OPTION_MESSAGE_TYPE): + LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_MSG_TYPE; + break; + case(DHCP_OPTION_SERVER_ID): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_SERVER_ID; + break; + case(DHCP_OPTION_T1): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T1; + break; + case(DHCP_OPTION_T2): + LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); + decode_idx = DHCP_OPTION_IDX_T2; + break; + default: + decode_len = 0; + LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", op)); + break; + } + offset += len + 2; + if (decode_len > 0) { + u32_t value = 0; + u16_t copy_len; +decode_next: + LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); + if (!dhcp_option_given(dhcp, decode_idx)) { + copy_len = LWIP_MIN(decode_len, 4); + pbuf_copy_partial(q, &value, copy_len, val_offset); + if (decode_len > 4) { + /* decode more than one u32_t */ + LWIP_ERROR("decode_len % 4 == 0", decode_len % 4 == 0, return ERR_VAL;); + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, htonl(value)); + decode_len -= 4; + val_offset += 4; + decode_idx++; + goto decode_next; + } else if (decode_len == 4) { + value = ntohl(value); + } else { + LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); + value = ((u8_t*)&value)[0]; + } + dhcp_got_option(dhcp, decode_idx); + dhcp_set_option_value(dhcp, decode_idx, value); + } + } + if (offset >= q->len) { + offset -= q->len; + offset_max -= q->len; + if ((offset < offset_max) && offset_max) { + q = q->next; + LWIP_ASSERT("next pbuf was null", q); + options = (u8_t*)q->payload; + } else { + /* We've run out of bytes, probably no end marker. Don't proceed. */ + break; + } + } + } + /* is this an overloaded message? */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { + u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); + dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); + if (overload == DHCP_OVERLOAD_FILE) { + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME) { + parse_sname_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); + } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { + parse_sname_as_options = 1; + parse_file_as_options = 1; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); + } else { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); + } +#if LWIP_DHCP_BOOTP_FILE + if (!parse_file_as_options) { + /* only do this for ACK messages */ + if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && + (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) + /* copy bootp file name, don't care for sname (server hostname) */ + pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS); + /* make sure the string is really NULL-terminated */ + dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; + } +#endif /* LWIP_DHCP_BOOTP_FILE */ + } + if (parse_file_as_options) { + /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ + parse_file_as_options = 0; + options_idx = DHCP_FILE_OFS; + options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; + goto again; + } else if (parse_sname_as_options) { + parse_sname_as_options = 0; + options_idx = DHCP_SNAME_OFS; + options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; + goto again; + } + return ERR_OK; +} + +/** + * If an incoming DHCP message is in response to us, then trigger the state machine + */ +static void +dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + struct netif *netif = (struct netif *)arg; + struct dhcp *dhcp = netif->dhcp; + struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; + u8_t msg_type; + u8_t i; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, + ip4_addr1_16(addr), ip4_addr2_16(addr), ip4_addr3_16(addr), ip4_addr4_16(addr), port)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); + /* prevent warnings about unused arguments */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); + + LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); + + if (p->len < DHCP_MIN_REPLY_LEN) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); + goto free_pbuf_and_return; + } + + if (reply_msg->op != DHCP_BOOTREPLY) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); + goto free_pbuf_and_return; + } + /* iterate through hardware address and match against DHCP message */ + for (i = 0; i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN && i < DHCP_CHADDR_LEN; i++) { + if (netif->hwaddr[i] != reply_msg->chaddr[i]) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", + (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); + goto free_pbuf_and_return; + } + } + /* match transaction ID against what we expected */ + if (ntohl(reply_msg->xid) != dhcp->xid) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",ntohl(reply_msg->xid),dhcp->xid)); + goto free_pbuf_and_return; + } + /* option fields could be unfold? */ + if (dhcp_parse_reply(dhcp, p) != ERR_OK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("problem unfolding DHCP message - too short on memory?\n")); + goto free_pbuf_and_return; + } + + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); + /* obtain pointer to DHCP message type */ + if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); + goto free_pbuf_and_return; + } + + /* read DHCP message type */ + msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); + /* message type is DHCP ACK? */ + if (msg_type == DHCP_ACK) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); + /* in requesting state? */ + if (dhcp->state == DHCP_REQUESTING) { + dhcp_handle_ack(netif); +#if DHCP_DOES_ARP_CHECK + /* check if the acknowledged lease address is already in use */ + dhcp_check(netif); +#else + /* bind interface to the acknowledged lease address */ + dhcp_bind(netif); +#endif + } + /* already bound to the given lease address? */ + else if ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING)) { + dhcp_bind(netif); + } + } + /* received a DHCP_NAK in appropriate state? */ + else if ((msg_type == DHCP_NAK) && + ((dhcp->state == DHCP_REBOOTING) || (dhcp->state == DHCP_REQUESTING) || + (dhcp->state == DHCP_REBINDING) || (dhcp->state == DHCP_RENEWING ))) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); + dhcp_handle_nak(netif); + } + /* received a DHCP_OFFER in DHCP_SELECTING state? */ + else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_SELECTING)) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_SELECTING state\n")); + dhcp->request_timeout = 0; + /* remember offered lease */ + dhcp_handle_offer(netif); + } +free_pbuf_and_return: + dhcp->msg_in = NULL; + pbuf_free(p); +} + +/** + * Create a DHCP request, fill in common headers + * + * @param netif the netif under DHCP control + * @param dhcp dhcp control struct + * @param message_type message type of the request + */ +static err_t +dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) +{ + u16_t i; +#ifndef DHCP_GLOBAL_XID + /** default global transaction identifier starting value (easy to match + * with a packet analyser). We simply increment for each new request. + * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one + * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + static u32_t xid; +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + static u32_t xid = 0xABCD0000; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ +#else + if (!xid_initialised) { + xid = DHCP_GLOBAL_XID; + xid_initialised = !xid_initialised; + } +#endif + LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;); + LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); + LWIP_ASSERT("dhcp_create_msg: dhcp->p_out == NULL", dhcp->p_out == NULL); + LWIP_ASSERT("dhcp_create_msg: dhcp->msg_out == NULL", dhcp->msg_out == NULL); + dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); + if (dhcp->p_out == NULL) { + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("dhcp_create_msg(): could not allocate pbuf\n")); + return ERR_MEM; + } + LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", + (dhcp->p_out->len >= sizeof(struct dhcp_msg))); + + /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */ + if (message_type != DHCP_REQUEST) { + /* reuse transaction identifier in retransmissions */ + if (dhcp->tries == 0) { +#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) + xid = LWIP_RAND(); +#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + xid++; +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ + } + dhcp->xid = xid; + } + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, + ("transaction id xid(%"X32_F")\n", xid)); + + dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; + + dhcp->msg_out->op = DHCP_BOOTREQUEST; + /* TODO: make link layer independent */ + dhcp->msg_out->htype = DHCP_HTYPE_ETH; + dhcp->msg_out->hlen = netif->hwaddr_len; + dhcp->msg_out->hops = 0; + dhcp->msg_out->xid = htonl(dhcp->xid); + dhcp->msg_out->secs = 0; + /* we don't need the broadcast flag since we can receive unicast traffic + before being fully configured! */ + dhcp->msg_out->flags = 0; + ip_addr_set_zero(&dhcp->msg_out->ciaddr); + /* set ciaddr to netif->ip_addr based on message_type and state */ + if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || + ((message_type == DHCP_REQUEST) && /* DHCP_BOUND not used for sending! */ + ((dhcp->state==DHCP_RENEWING) || dhcp->state==DHCP_REBINDING || dhcp->state == DHCP_RELEASING))) { + ip_addr_copy(dhcp->msg_out->ciaddr, netif->ip_addr); + } + ip_addr_set_zero(&dhcp->msg_out->yiaddr); + ip_addr_set_zero(&dhcp->msg_out->siaddr); + ip_addr_set_zero(&dhcp->msg_out->giaddr); + for (i = 0; i < DHCP_CHADDR_LEN; i++) { + /* copy netif hardware address, pad with zeroes */ + dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN) ? netif->hwaddr[i] : 0/* pad byte*/; + } + for (i = 0; i < DHCP_SNAME_LEN; i++) { + dhcp->msg_out->sname[i] = 0; + } + for (i = 0; i < DHCP_FILE_LEN; i++) { + dhcp->msg_out->file[i] = 0; + } + dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); + dhcp->options_out_len = 0; + /* fill options field with an incrementing array (for debugging purposes) */ + for (i = 0; i < DHCP_OPTIONS_LEN; i++) { + dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ + } + /* Add option MESSAGE_TYPE */ + dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); + dhcp_option_byte(dhcp, message_type); + return ERR_OK; +} + +/** + * Free previously allocated memory used to send a DHCP request. + * + * @param dhcp the dhcp struct to free the request from + */ +static void +dhcp_delete_msg(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL); + LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL); + if (dhcp->p_out != NULL) { + pbuf_free(dhcp->p_out); + } + dhcp->p_out = NULL; + dhcp->msg_out = NULL; +} + +/** + * Add a DHCP message trailer + * + * Adds the END option to the DHCP message, and if + * necessary, up to three padding bytes. + * + * @param dhcp DHCP state structure + */ +static void +dhcp_option_trailer(struct dhcp *dhcp) +{ + LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); + LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); + LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); + dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; + /* packet is too small, or not 4 byte aligned? */ + while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && + (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { + /* add a fill/padding byte */ + dhcp->msg_out->options[dhcp->options_out_len++] = 0; + } +} + +#endif /* LWIP_DHCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dns.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dns.c new file mode 100644 index 0000000..45b416b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/dns.c @@ -0,0 +1,1302 @@ +/** + * @file + * DNS - host name to IP address resolver. + * + */ + +/** + + * This file implements a DNS host name to IP address resolver. + + * Port to lwIP from uIP + * by Jim Pettinato April 2007 + + * security fixes and more by Simon Goldschmidt + + * uIP version Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + * DNS.C + * + * The lwIP DNS resolver functions are used to lookup a host name and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the dns_lookup() function. + * New hostnames can be resolved using the dns_query() function. + * + * The lwIP version of the resolver also adds a non-blocking version of + * gethostbyname() that will work with a raw API application. This function + * checks for an IP address string first and converts it if it is valid. + * gethostbyname() then does a dns_lookup() to see if the name is + * already in the table. If so, the IP is returned. If not, a query is + * issued and the function returns with a ERR_INPROGRESS status. The app + * using the dns client must then go into a waiting state. + * + * Once a hostname has been resolved (or found to be non-existent), + * the resolver code calls a specified callback function (which + * must be implemented by the module that uses the resolver). + */ + +/*----------------------------------------------------------------------------- + * RFC 1035 - Domain names - implementation and specification + * RFC 2181 - Clarifications to the DNS Specification + *----------------------------------------------------------------------------*/ + +/** @todo: define good default values (rfc compliance) */ +/** @todo: improve answer parsing, more checkings... */ +/** @todo: check RFC1035 - 7.3. Processing responses */ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/dns.h" + +#include + +/* A list of DNS security features follows */ +#define LWIP_DNS_SECURE_RAND_XID 1 +#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2 +#define LWIP_DNS_SECURE_RAND_SRC_PORT 4 +/** Use all DNS security features by default. + * This is overridable but should only be needed by very small targets + * or when using against non standard DNS servers. */ +#ifndef LWIP_DNS_SECURE +#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) +#endif + +/** Random generator function to create random TXIDs and source ports for queries */ +#ifndef DNS_RAND_TXID +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0) +#define DNS_RAND_TXID LWIP_RAND +#else +static u16_t dns_txid; +#define DNS_RAND_TXID() (++dns_txid) +#endif +#endif + +/** Limits the source port to be >= 1024 by default */ +#ifndef DNS_PORT_ALLOWED +#define DNS_PORT_ALLOWED(port) ((port) >= 1024) +#endif + +/** DNS server IP address */ +#ifndef DNS_SERVER_ADDRESS +#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */ +#endif + +/** DNS server port address */ +#ifndef DNS_SERVER_PORT +#define DNS_SERVER_PORT 53 +#endif + +/** DNS maximum number of retries when asking for a name, before "timeout". */ +#ifndef DNS_MAX_RETRIES +#define DNS_MAX_RETRIES 4 +#endif + +/** DNS resource record max. TTL (one week as default) */ +#ifndef DNS_MAX_TTL +#define DNS_MAX_TTL 604800 +#endif + +/* The number of parallel requests (i.e. calls to dns_gethostbyname + * that cannot be answered from the DNS table. + * This is set to the table size by default. + */ +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) +#ifndef DNS_MAX_REQUESTS +#define DNS_MAX_REQUESTS DNS_TABLE_SIZE +#endif +#else +/* In this configuration, both arrays have to have the same size and are used + * like one entry (used/free) */ +#define DNS_MAX_REQUESTS DNS_TABLE_SIZE +#endif + +/* The number of UDP source ports used in parallel */ +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) +#ifndef DNS_MAX_SOURCE_PORTS +#define DNS_MAX_SOURCE_PORTS DNS_MAX_REQUESTS +#endif +#else +#ifdef DNS_MAX_SOURCE_PORTS +#undef DNS_MAX_SOURCE_PORTS +#endif +#define DNS_MAX_SOURCE_PORTS 1 +#endif + + +/* DNS protocol flags */ +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + +/* DNS protocol states */ +#define DNS_STATE_UNUSED 0 +#define DNS_STATE_NEW 1 +#define DNS_STATE_ASKING 2 +#define DNS_STATE_DONE 3 + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** DNS message header */ +struct dns_hdr { + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FLD_8(u8_t flags1); + PACK_STRUCT_FLD_8(u8_t flags2); + PACK_STRUCT_FIELD(u16_t numquestions); + PACK_STRUCT_FIELD(u16_t numanswers); + PACK_STRUCT_FIELD(u16_t numauthrr); + PACK_STRUCT_FIELD(u16_t numextrarr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define SIZEOF_DNS_HDR 12 + +/** DNS query message structure. + No packing needed: only used locally on the stack. */ +struct dns_query { + /* DNS query record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; +}; +#define SIZEOF_DNS_QUERY 4 + +/** DNS answer message structure. + No packing needed: only used locally on the stack. */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t cls; + u32_t ttl; + u16_t len; +}; +#define SIZEOF_DNS_ANSWER 10 +/* maximum allowed size for the struct due to non-packed */ +#define SIZEOF_DNS_ANSWER_ASSERT 12 + +/** DNS table entry */ +struct dns_table_entry { + u32_t ttl; + ip_addr_t ipaddr; + u16_t txid; + u8_t state; + u8_t server_idx; + u8_t tmr; + u8_t retries; + u8_t seqno; +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) + u8_t pcb_idx; +#endif + char name[DNS_MAX_NAME_LENGTH]; +}; + +/** DNS request table entry: used when dns_gehostbyname cannot answer the + * request from the DNS table */ +struct dns_req_entry { + /* pointer to callback on DNS query done */ + dns_found_callback found; + /* argument passed to the callback function */ + void *arg; +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) + u8_t dns_table_idx; +#endif +}; + +#if DNS_LOCAL_HOSTLIST + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Local host-list. For hostnames in this list, no + * external name resolution is performed */ +static struct local_hostlist_entry *local_hostlist_dynamic; +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE +#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ +/** Defining this allows the local_hostlist_static to be placed in a different + * linker section (e.g. FLASH) */ +#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST +#define DNS_LOCAL_HOSTLIST_STORAGE_POST +#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ +DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] + DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; + +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +static void dns_init_local(); +#endif /* DNS_LOCAL_HOSTLIST */ + + +/* forward declarations */ +static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); +static void dns_check_entries(void); + +/*----------------------------------------------------------------------------- + * Globals + *----------------------------------------------------------------------------*/ + +/* DNS variables */ +static struct udp_pcb *dns_pcbs[DNS_MAX_SOURCE_PORTS]; +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) +static u8_t dns_last_pcb_idx; +#endif +static u8_t dns_seqno; +static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; +static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS]; +static ip_addr_t dns_servers[DNS_MAX_SERVERS]; + +#ifndef LWIP_DNS_STRICMP +#define LWIP_DNS_STRICMP(str1, str2) dns_stricmp(str1, str2) +/** + * A small but sufficient implementation for case insensitive strcmp. + * This can be defined to e.g. stricmp for windows or strcasecmp for linux. */ +static int +dns_stricmp(const char* str1, const char* str2) +{ + char c1, c2; + + do { + c1 = *str1++; + c2 = *str2++; + if (c1 != c2) { + char c1_upc = c1 | 0x20; + if ((c1_upc >= 'a') && (c1_upc <= 'z')) { + /* characters are not equal an one is in the alphabet range: + downcase both chars and check again */ + char c2_upc = c2 | 0x20; + if (c1_upc != c2_upc) { + /* still not equal */ + /* don't care for < or > */ + return 1; + } + } else { + /* characters are not equal but none is in the alphabet range */ + return 1; + } + } + } while (c1 != 0); + return 0; +} +#endif /* LWIP_DNS_STRICMP */ + +/** + * Initialize the resolver: set up the UDP pcb and configure the default server + * (DNS_SERVER_ADDRESS). + */ +void +dns_init() +{ + ip_addr_t dnsserver; + + LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY", + sizeof(struct dns_query) == SIZEOF_DNS_QUERY); + LWIP_ASSERT("sanity check SIZEOF_DNS_ANSWER", + sizeof(struct dns_answer) <= SIZEOF_DNS_ANSWER_ASSERT); + + /* initialize default DNS server address */ + DNS_SERVER_ADDRESS(&dnsserver); + + LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); + + /* if dns client not yet initialized... */ +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) + if (dns_pcbs[0] == NULL) { + dns_pcbs[0] = udp_new(); + LWIP_ASSERT("dns_pcbs[0] != NULL", dns_pcbs[0] != NULL); + + /* initialize DNS table not needed (initialized to zero since it is a + * global variable) */ + LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", + DNS_STATE_UNUSED == 0); + + /* initialize DNS client */ + udp_bind(dns_pcbs[0], IP_ADDR_ANY, 0); + udp_recv(dns_pcbs[0], dns_recv, NULL); + } +#endif + /* initialize default DNS primary server */ + dns_setserver(0, &dnsserver); +#if DNS_LOCAL_HOSTLIST + dns_init_local(); +#endif +} + +/** + * Initialize one of the DNS servers. + * + * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS + * @param dnsserver IP address of the DNS server to set + */ +void +dns_setserver(u8_t numdns, ip_addr_t *dnsserver) +{ + if (numdns < DNS_MAX_SERVERS) { + if (dnsserver != NULL) { + dns_servers[numdns] = (*dnsserver); + } else { + dns_servers[numdns] = *IP_ADDR_ANY; + } + } +} + +/** + * Obtain one of the currently configured DNS server. + * + * @param numdns the index of the DNS server + * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS + * server has not been configured. + */ +ip_addr_t +dns_getserver(u8_t numdns) +{ + if (numdns < DNS_MAX_SERVERS) { + return dns_servers[numdns]; + } else { + return *IP_ADDR_ANY; + } +} + +/** + * The DNS resolver client timer - handle retries and timeouts and should + * be called every DNS_TMR_INTERVAL milliseconds (every second by default). + */ +void +dns_tmr(void) +{ + LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); + dns_check_entries(); +} + +#if DNS_LOCAL_HOSTLIST +static void +dns_init_local() +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) + int i; + struct local_hostlist_entry *entry; + /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ + struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; + size_t namelen; + for (i = 0; i < sizeof(local_hostlist_init) / sizeof(struct local_hostlist_entry); i++) { + struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; + LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); + namelen = strlen(init_entry->name); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); + if (entry != NULL) { + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, init_entry->name, namelen); + ((char*)entry->name)[namelen] = 0; + entry->addr = init_entry->addr; + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ +} + +/** + * Scans the local host-list for a hostname. + * + * @param hostname Hostname to look for in the local host-list + * @return The first IP address for the hostname in the local host-list or + * IPADDR_NONE if not found. + */ +static u32_t +dns_lookup_local(const char *hostname) +{ +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC + struct local_hostlist_entry *entry = local_hostlist_dynamic; + while(entry != NULL) { + if (LWIP_DNS_STRICMP(entry->name, hostname) == 0) { + return ip4_addr_get_u32(&entry->addr); + } + entry = entry->next; + } +#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + int i; + for (i = 0; i < sizeof(local_hostlist_static) / sizeof(struct local_hostlist_entry); i++) { + if (LWIP_DNS_STRICMP(local_hostlist_static[i].name, hostname) == 0) { + return ip4_addr_get_u32(&local_hostlist_static[i].addr); + } + } +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + return IPADDR_NONE; +} + +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +/** Remove all entries from the local host-list for a specific hostname + * and/or IP address + * + * @param hostname hostname for which entries shall be removed from the local + * host-list + * @param addr address for which entries shall be removed from the local host-list + * @return the number of removed entries + */ +int +dns_local_removehost(const char *hostname, const ip_addr_t *addr) +{ + int removed = 0; + struct local_hostlist_entry *entry = local_hostlist_dynamic; + struct local_hostlist_entry *last_entry = NULL; + while (entry != NULL) { + if (((hostname == NULL) || !LWIP_DNS_STRICMP(entry->name, hostname)) && + ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { + struct local_hostlist_entry *free_entry; + if (last_entry != NULL) { + last_entry->next = entry->next; + } else { + local_hostlist_dynamic = entry->next; + } + free_entry = entry; + entry = entry->next; + memp_free(MEMP_LOCALHOSTLIST, free_entry); + removed++; + } else { + last_entry = entry; + entry = entry->next; + } + } + return removed; +} + +/** + * Add a hostname/IP address pair to the local host-list. + * Duplicates are not checked. + * + * @param hostname hostname of the new entry + * @param addr IP address of the new entry + * @return ERR_OK if succeeded or ERR_MEM on memory error + */ +err_t +dns_local_addhost(const char *hostname, const ip_addr_t *addr) +{ + struct local_hostlist_entry *entry; + size_t namelen; + LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); + namelen = strlen(hostname); + LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); + entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); + if (entry == NULL) { + return ERR_MEM; + } + entry->name = (char*)entry + sizeof(struct local_hostlist_entry); + MEMCPY((char*)entry->name, hostname, namelen); + ((char*)entry->name)[namelen] = 0; + ip_addr_copy(entry->addr, *addr); + entry->next = local_hostlist_dynamic; + local_hostlist_dynamic = entry; + return ERR_OK; +} +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** + * Look up a hostname in the array of known hostnames. + * + * @note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function dns_enqueue() can be used to send a query + * for a hostname. + * + * @param name the hostname to look up + * @return the hostname's IP address, as u32_t (instead of ip_addr_t to + * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname + * was not found in the cached dns_table. + */ +static u32_t +dns_lookup(const char *name) +{ + u8_t i; +#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) + u32_t addr; +#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ +#if DNS_LOCAL_HOSTLIST + if ((addr = dns_lookup_local(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOCAL_HOSTLIST */ +#ifdef DNS_LOOKUP_LOCAL_EXTERN + if((addr = DNS_LOOKUP_LOCAL_EXTERN(name)) != IPADDR_NONE) { + return addr; + } +#endif /* DNS_LOOKUP_LOCAL_EXTERN */ + + /* Walk through name list, return entry if found. If not, return NULL. */ + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + if ((dns_table[i].state == DNS_STATE_DONE) && + (LWIP_DNS_STRICMP(name, dns_table[i].name) == 0)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); + ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + return ip4_addr_get_u32(&dns_table[i].ipaddr); + } + } + + return IPADDR_NONE; +} + +/** + * Compare the "dotted" name "query" with the encoded name "response" + * to make sure an answer from the DNS server matches the current dns_table + * entry (otherwise, answers might arrive late for hostname not on the list + * any more). + * + * @param query hostname (not encoded) from the dns_table + * @param p pbuf containing the encoded hostname in the DNS response + * @param start_offset offset into p where the name starts + * @return 0xFFFF: names differ, other: names equal -> offset behind name + */ +static u16_t +dns_compare_name(char *query, struct pbuf* p, u16_t start_offset) +{ + unsigned char n; + u16_t response_offset = start_offset; + + do { + n = pbuf_get_at(p, response_offset++); + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name: cannot be equal since we don't send them */ + return 0xFFFF; + } else { + /* Not compressed name */ + while (n > 0) { + if ((*query) != pbuf_get_at(p, response_offset)) { + return 0xFFFF; + } + ++response_offset; + ++query; + --n; + }; + ++query; + } + } while (pbuf_get_at(p, response_offset) != 0); + + return response_offset + 1; +} + +/** + * Walk through a compact encoded DNS name and return the end of the name. + * + * @param p pbuf containing the name + * @param query_idx start index into p pointing to encoded DNS name in the DNS server response + * @return index to end of the name + */ +static u16_t +dns_parse_name(struct pbuf* p, u16_t query_idx) +{ + unsigned char n; + + do { + n = pbuf_get_at(p, query_idx++); + /** @see RFC 1035 - 4.1.4. Message compression */ + if ((n & 0xc0) == 0xc0) { + /* Compressed name */ + break; + } else { + /* Not compressed name */ + while (n > 0) { + ++query_idx; + --n; + }; + } + } while (pbuf_get_at(p, query_idx) != 0); + + return query_idx + 1; +} + +/** + * Send a DNS query packet. + * + * @param entry the DNS table entry for which to send a request + * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise + */ +static err_t +dns_send(struct dns_table_entry* entry) +{ + err_t err; + struct dns_hdr hdr; + struct dns_query qry; + struct pbuf *p; + u16_t query_idx, copy_len; + const char *hostname, *hostname_part; + u8_t n; + u8_t pcb_idx; + + LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", + (u16_t)(entry->server_idx), entry->name)); + LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS); + LWIP_ASSERT("dns server has no IP address set", !ip_addr_isany(&dns_servers[entry->server_idx])); + + /* if here, we have either a new query or a retry on a previous query to process */ + p = pbuf_alloc(PBUF_TRANSPORT, SIZEOF_DNS_HDR + strlen(entry->name) + 2 + + SIZEOF_DNS_QUERY, PBUF_RAM); + if (p != NULL) { + /* fill dns header */ + memset(&hdr, 0, SIZEOF_DNS_HDR); + hdr.id = htons(entry->txid); + hdr.flags1 = DNS_FLAG1_RD; + hdr.numquestions = PP_HTONS(1); + pbuf_take(p, &hdr, SIZEOF_DNS_HDR); + hostname = entry->name; + --hostname; + + /* convert hostname into suitable query format. */ + query_idx = SIZEOF_DNS_HDR; + do { + ++hostname; + hostname_part = hostname; + for(n = 0; *hostname != '.' && *hostname != 0; ++hostname) { + ++n; + } + copy_len = hostname - hostname_part; + pbuf_put_at(p, query_idx, n); + pbuf_take_at(p, hostname_part, copy_len, query_idx + 1); + query_idx += n + 1; + } while(*hostname != 0); + pbuf_put_at(p, query_idx, 0); + query_idx++; + + /* fill dns query */ + qry.type = PP_HTONS(DNS_RRTYPE_A); + qry.cls = PP_HTONS(DNS_RRCLASS_IN); + pbuf_take_at(p, &qry, SIZEOF_DNS_QUERY, query_idx); + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) + pcb_idx = entry->pcb_idx; +#else + pcb_idx = 0; +#endif + /* send dns packet */ + LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n", + entry->txid, entry->name, entry->server_idx)); + err = udp_sendto(dns_pcbs[pcb_idx], p, &dns_servers[entry->server_idx], DNS_SERVER_PORT); + + /* free pbuf */ + pbuf_free(p); + } else { + err = ERR_MEM; + } + + return err; +} + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) +static struct udp_pcb* +dns_alloc_random_port(void) +{ + err_t err; + struct udp_pcb* ret; + + ret = udp_new(); + if (ret == NULL) { + /* out of memory, have to reuse an existing pcb */ + return NULL; + } + do { + u16_t port = DNS_RAND_TXID(); + if (!DNS_PORT_ALLOWED(port)) { + /* this port is not allowed, try again */ + err = ERR_USE; + continue; + } + err = udp_bind(ret, IP_ADDR_ANY, port); + } while(err == ERR_USE); + if ((err != ERR_OK) && (err != ERR_USE)) { + udp_remove(ret); + return NULL; + } + udp_recv(ret, dns_recv, NULL); + return ret; +} + +/** + * dns_alloc_pcb() - allocates a new pcb (or reuses an existing one) to be used + * for sending a request + * + * @return an index into dns_pcbs + */ +static u8_t +dns_alloc_pcb(void) +{ + u8_t i; + u8_t idx; + + for (i = 0; i < DNS_MAX_SOURCE_PORTS; i++) { + if (dns_pcbs[i] == NULL) { + break; + } + } + if (i < DNS_MAX_SOURCE_PORTS) { + dns_pcbs[i] = dns_alloc_random_port(); + if (dns_pcbs[i] != NULL) { + /* succeeded */ + dns_last_pcb_idx = i; + return i; + } + } + /* if we come here, creating a new UDP pcb failed, so we have to use + an already existing one */ + idx = dns_last_pcb_idx + 1; + for (i = 0; i < DNS_MAX_SOURCE_PORTS; i++) { + if (idx >= DNS_MAX_SOURCE_PORTS) { + idx = 0; + } + if (dns_pcbs[idx] != NULL) { + dns_last_pcb_idx = idx; + return idx; + } + } + return DNS_MAX_SOURCE_PORTS; +} +#endif /* ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) */ + +/** + * dns_call_found() - call the found callback and check if there are duplicate + * entries for the given hostname. If there are any, their found callback will + * be called and they will be removed. + * + * @param idx dns table index of the entry that is resolved or removed + * @param addr IP address for the hostname (or NULL on error or memory shortage) + */ +static void +dns_call_found(u8_t idx, ip_addr_t* addr) +{ + u8_t i; + LWIP_UNUSED_ARG(i); + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) + for (i = 0; i < DNS_MAX_REQUESTS; i++) { + if (dns_requests[i].found && (dns_requests[i].dns_table_idx == idx)) { + (*dns_requests[i].found)(dns_table[idx].name, addr, dns_requests[i].arg); + /* flush this entry */ + dns_requests[i].found = NULL; + } + } +#else + if (dns_requests[idx].found) { + (*dns_requests[idx].found)(dns_table[idx].name, addr, dns_requests[idx].arg); + } + dns_requests[idx].found = NULL; +#endif +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) + /* close the pcb used unless other request are using it */ + for (i = 0; i < DNS_MAX_REQUESTS; i++) { + if (i == idx) { + continue; /* only check other requests */ + } + if (dns_table[i].state == DNS_STATE_ASKING) { + if (dns_table[i].pcb_idx == dns_table[idx].pcb_idx) { + /* another request is still using the same pcb */ + dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; + break; + } + } + } + if (dns_table[idx].pcb_idx < DNS_MAX_SOURCE_PORTS) { + /* if we come here, the pcb is not used any more and can be removed */ + udp_remove(dns_pcbs[dns_table[idx].pcb_idx]); + dns_pcbs[dns_table[idx].pcb_idx] = NULL; + dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; + } +#endif +} + +/* Create a query transmission ID that is unique for all outstanding queries */ +static u16_t +dns_create_txid(void) +{ + u16_t txid; + u8_t i; + +again: + txid = DNS_RAND_TXID(); + + /* check whether the ID is unique */ + for (i = 0; i < DNS_TABLE_SIZE; i++) { + if ((dns_table[i].state == DNS_STATE_ASKING) && + (dns_table[i].txid == txid)) { + /* ID already used by another pending query */ + goto again; + } + } + + return txid; +} + +/** + * dns_check_entry() - see if entry has not yet been queried and, if so, sends out a query. + * Check an entry in the dns_table: + * - send out query for new entries + * - retry old pending entries on timeout (also with different servers) + * - remove completed entries from the table if their TTL has expired + * + * @param i index of the dns_table entry to check + */ +static void +dns_check_entry(u8_t i) +{ + err_t err; + struct dns_table_entry *entry = &dns_table[i]; + + LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); + + switch (entry->state) { + + case DNS_STATE_NEW: { + u16_t txid; + /* initialize new entry */ + txid = dns_create_txid(); + entry->txid = txid; + entry->state = DNS_STATE_ASKING; + entry->server_idx = 0; + entry->tmr = 1; + entry->retries = 0; + + /* send DNS packet for this entry */ + err = dns_send(entry); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + break; + } + + case DNS_STATE_ASKING: + if (--entry->tmr == 0) { + if (++entry->retries == DNS_MAX_RETRIES) { + if ((entry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany(&dns_servers[entry->server_idx + 1])) { + /* change of server */ + entry->server_idx++; + entry->tmr = 1; + entry->retries = 0; + break; + } else { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", entry->name)); + /* call specified callback function if provided */ + dns_call_found(i, NULL); + /* flush this entry */ + entry->state = DNS_STATE_UNUSED; + break; + } + } + + /* wait longer for the next retry */ + entry->tmr = entry->retries; + + /* send DNS packet for this entry */ + err = dns_send(entry); + if (err != ERR_OK) { + LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, + ("dns_send returned error: %s\n", lwip_strerr(err))); + } + } + break; + case DNS_STATE_DONE: + /* if the time to live is nul */ + if ((entry->ttl == 0) || (--entry->ttl == 0)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", entry->name)); + /* flush this entry, there cannot be any related pending entries in this state */ + entry->state = DNS_STATE_UNUSED; + } + break; + case DNS_STATE_UNUSED: + /* nothing to do */ + break; + default: + LWIP_ASSERT("unknown dns_table entry state:", 0); + break; + } +} + +/** + * Call dns_check_entry for each entry in dns_table - check all entries. + */ +static void +dns_check_entries(void) +{ + u8_t i; + + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + dns_check_entry(i); + } +} + +/** + * Receive input function for DNS response packets arriving for the dns UDP pcb. + * + * @params see udp.h + */ +static void +dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + u8_t i, entry_idx = DNS_TABLE_SIZE; + u16_t txid; + u16_t res_idx; + struct dns_hdr hdr; + struct dns_answer ans; + struct dns_query qry; + u16_t nquestions, nanswers; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(port); + + /* is the dns message big enough ? */ + if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); + /* free pbuf and return */ + goto memerr; + } + + /* copy dns payload inside static buffer for processing */ + if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, 0) == SIZEOF_DNS_HDR) { + /* Match the ID in the DNS header with the name table. */ + txid = htons(hdr.id); + for (i = 0; i < DNS_TABLE_SIZE; i++) { + struct dns_table_entry *entry = &dns_table[i]; + entry_idx = i; + if ((entry->state == DNS_STATE_ASKING) && + (entry->txid == txid)) { + u8_t dns_err; + /* This entry is now completed. */ + entry->state = DNS_STATE_DONE; + dns_err = hdr.flags2 & DNS_FLAG2_ERR_MASK; + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr.numquestions); + nanswers = htons(hdr.numanswers); + + /* Check for error. If so, call callback to inform. */ + if (((hdr.flags1 & DNS_FLAG1_RESPONSE) == 0) || (dns_err != 0) || (nquestions != 1)) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + + /* Check whether response comes from the same network address to which the + question was sent. (RFC 5452) */ + if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) { + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + + /* Check if the name in the "question" part match with the name in the entry and + skip it if equal. */ + res_idx = dns_compare_name(entry->name, p, SIZEOF_DNS_HDR); + if (res_idx == 0xFFFF) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + + /* check if "question" part matches the request */ + pbuf_copy_partial(p, &qry, SIZEOF_DNS_QUERY, res_idx); + if((qry.type != PP_HTONS(DNS_RRTYPE_A)) || (qry.cls != PP_HTONS(DNS_RRCLASS_IN))) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + /* skip the rest of the "question" part */ + res_idx += SIZEOF_DNS_QUERY; + + while (nanswers > 0) { + /* skip answer resource record's host name */ + res_idx = dns_parse_name(p, res_idx); + + /* Check for IP address type and Internet class. Others are discarded. */ + pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx); + if((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) && + (ans.len == PP_HTONS(sizeof(ip_addr_t))) ) { + res_idx += SIZEOF_DNS_ANSWER; + /* read the answer resource record's TTL, and maximize it if needed */ + entry->ttl = ntohl(ans.ttl); + if (entry->ttl > DNS_MAX_TTL) { + entry->ttl = DNS_MAX_TTL; + } + /* read the IP address after answer resource record's header */ + pbuf_copy_partial(p, &(entry->ipaddr), sizeof(entry->ipaddr), res_idx); + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); + ip_addr_debug_print(DNS_DEBUG, (&(entry->ipaddr))); + LWIP_DEBUGF(DNS_DEBUG, ("\n")); + /* call specified callback function if provided */ + dns_call_found(entry_idx, &entry->ipaddr); + if (entry->ttl == 0) { + /* RFC 883, page 29: "Zero values are + interpreted to mean that the RR can only be used for the + transaction in progress, and should not be cached." + -> flush this entry now */ + goto flushentry; + } + /* deallocate memory and return */ + goto memerr; + } else { + res_idx += SIZEOF_DNS_ANSWER + htons(ans.len); + } + --nanswers; + } + LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", entry->name)); + /* call callback to indicate error, clean up memory and return */ + goto responseerr; + } + } + } + + /* deallocate memory and return */ + goto memerr; + +responseerr: + /* ERROR: call specified callback function with NULL as name to indicate an error */ + dns_call_found(entry_idx, NULL); +flushentry: + /* flush this entry */ + dns_table[entry_idx].state = DNS_STATE_UNUSED; + +memerr: + /* free pbuf */ + pbuf_free(p); + return; +} + +/** + * Queues a new hostname to resolve and sends out a DNS query for that hostname + * + * @param name the hostname that is to be queried + * @param hostnamelen length of the hostname + * @param found a callback function to be called on success, failure or timeout + * @param callback_arg argument to pass to the callback function + * @return @return a err_t return code. + */ +static err_t +dns_enqueue(const char *name, size_t hostnamelen, dns_found_callback found, + void *callback_arg) +{ + u8_t i; + u8_t lseq, lseqi; + struct dns_table_entry *entry = NULL; + size_t namelen; + struct dns_req_entry* req; + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) + u8_t r; + /* check for duplicate entries */ + for (i = 0; i < DNS_TABLE_SIZE; i++) { + if ((dns_table[i].state == DNS_STATE_ASKING) && + (LWIP_DNS_STRICMP(name, dns_table[i].name) == 0)) { + /* this is a duplicate entry, find a free request entry */ + for (r = 0; r < DNS_MAX_REQUESTS; r++) { + if (dns_requests[r].found == 0) { + dns_requests[r].found = found; + dns_requests[r].arg = callback_arg; + dns_requests[r].dns_table_idx = i; + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": duplicate request\n", name)); + return ERR_INPROGRESS; + } + } + } + } + /* no duplicate entries found */ +#endif + + /* search an unused entry, or the oldest one */ + lseq = 0; + lseqi = DNS_TABLE_SIZE; + for (i = 0; i < DNS_TABLE_SIZE; ++i) { + entry = &dns_table[i]; + /* is it an unused entry ? */ + if (entry->state == DNS_STATE_UNUSED) { + break; + } + /* check if this is the oldest completed entry */ + if (entry->state == DNS_STATE_DONE) { + if ((u8_t)(dns_seqno - entry->seqno) > lseq) { + lseq = dns_seqno - entry->seqno; + lseqi = i; + } + } + } + + /* if we don't have found an unused entry, use the oldest completed one */ + if (i == DNS_TABLE_SIZE) { + if ((lseqi >= DNS_TABLE_SIZE) || (dns_table[lseqi].state != DNS_STATE_DONE)) { + /* no entry can be used now, table is full */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); + return ERR_MEM; + } else { + /* use the oldest completed one */ + i = lseqi; + entry = &dns_table[i]; + } + } + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) + /* find a free request entry */ + req = NULL; + for (r = 0; r < DNS_MAX_REQUESTS; r++) { + if (dns_requests[r].found == NULL) { + req = &dns_requests[r]; + break; + } + } + if (req == NULL) { + /* no request entry can be used now, table is full */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS request entries table is full\n", name)); + return ERR_MEM; + } + req->dns_table_idx = i; +#else + /* in this configuration, the entry index is the same as the request index */ + req = &dns_requests[i]; +#endif + + /* use this entry */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); + + /* fill the entry */ + entry->state = DNS_STATE_NEW; + entry->seqno = dns_seqno; + req->found = found; + req->arg = callback_arg; + namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH-1); + MEMCPY(entry->name, name, namelen); + entry->name[namelen] = 0; + +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) + entry->pcb_idx = dns_alloc_pcb(); + if (entry->pcb_idx >= DNS_MAX_SOURCE_PORTS) { + /* failed to get a UDP pcb */ + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": failed to allocate a pcb\n", name)); + entry->state = DNS_STATE_UNUSED; + req->found = NULL; + return ERR_MEM; + } + LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx))); +#endif + + dns_seqno++; + + /* force to send query without waiting timer */ + dns_check_entry(i); + + /* dns query is enqueued */ + return ERR_INPROGRESS; +} + +/** + * Resolve a hostname (string) into an IP address. + * NON-BLOCKING callback version for use with raw API!!! + * + * Returns immediately with one of err_t return codes: + * - ERR_OK if hostname is a valid IP address string or the host + * name is already in the local names table. + * - ERR_INPROGRESS enqueue a request to be sent to the DNS server + * for resolution if no errors are present. + * - ERR_ARG: dns client not initialized or invalid hostname + * + * @param hostname the hostname that is to be queried + * @param addr pointer to a ip_addr_t where to store the address if it is already + * cached in the dns_table (only valid if ERR_OK is returned!) + * @param found a callback function to be called on success, failure or timeout (only if + * ERR_INPROGRESS is returned!) + * @param callback_arg argument to pass to the callback function + * @return a err_t return code. + */ +err_t +dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, + void *callback_arg) +{ + u32_t ipaddr; + size_t hostnamelen; + /* not initialized or no valid server yet, or invalid addr pointer + * or invalid hostname or invalid hostname length */ + if ((addr == NULL) || + (!hostname) || (!hostname[0])) { + return ERR_ARG; + } +#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) + if (dns_pcbs[0] == NULL) { + return ERR_ARG; + } +#endif + hostnamelen = strlen(hostname); + if (hostnamelen >= DNS_MAX_NAME_LENGTH) { + LWIP_DEBUGF(DNS_DEBUG, ("dns_gethostbyname: name too long to resolve")); + return ERR_ARG; + } + + +#if LWIP_HAVE_LOOPIF + if (strcmp(hostname, "localhost") == 0) { + ip_addr_set_loopback(addr); + return ERR_OK; + } +#endif /* LWIP_HAVE_LOOPIF */ + + /* host name already in octet notation? set ip addr and return ERR_OK */ + ipaddr = ipaddr_addr(hostname); + if (ipaddr == IPADDR_NONE) { + /* already have this address cached? */ + ipaddr = dns_lookup(hostname); + } + if (ipaddr != IPADDR_NONE) { + ip4_addr_set_u32(addr, ipaddr); + return ERR_OK; + } + + /* queue query with specified callback */ + return dns_enqueue(hostname, hostnamelen, found, callback_arg); +} + +#endif /* LWIP_DNS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/inet_chksum.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/inet_chksum.c new file mode 100644 index 0000000..01a8fa9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/inet_chksum.c @@ -0,0 +1,545 @@ +/** + * @file + * Incluse internet checksum functions. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/inet_chksum.h" +#include "lwip/def.h" + +#include +#include + +/* These are some reference implementations of the checksum algorithm, with the + * aim of being simple, correct and fully portable. Checksumming is the + * first thing you would want to optimize for your platform. If you create + * your own version, link it in and in your cc.h put: + * + * #define LWIP_CHKSUM + * + * Or you can select from the implementations below by defining + * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. + */ + +#ifndef LWIP_CHKSUM +# define LWIP_CHKSUM lwip_standard_chksum +# ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 2 +# endif +u16_t lwip_standard_chksum(void *dataptr, int len); +#endif +/* If none set: */ +#ifndef LWIP_CHKSUM_ALGORITHM +# define LWIP_CHKSUM_ALGORITHM 0 +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ +/** + * lwip checksum + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * @note accumulator size limits summable length to 64k + * @note host endianess is irrelevant (p3 RFC1071) + */ +u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u32_t acc; + u16_t src; + u8_t *octetptr; + + acc = 0; + /* dataptr may be at odd or even addresses */ + octetptr = (u8_t*)dataptr; + while (len > 1) { + /* declare first octet as most significant + thus assume network order, ignoring host order */ + src = (*octetptr) << 8; + octetptr++; + /* declare second octet as least significant */ + src |= (*octetptr); + octetptr++; + acc += src; + len -= 2; + } + if (len > 0) { + /* accumulate remaining octet */ + src = (*octetptr) << 8; + acc += src; + } + /* add deferred carry bits */ + acc = (acc >> 16) + (acc & 0x0000ffffUL); + if ((acc & 0xffff0000UL) != 0) { + acc = (acc >> 16) + (acc & 0x0000ffffUL); + } + /* This maybe a little confusing: reorder sum using htons() + instead of ntohs() since it has a little less call overhead. + The caller must invert bits for Internet sum ! */ + return htons((u16_t)acc); +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ +/* + * Curt McDowell + * Broadcom Corp. + * csm@broadcom.com + * + * IP checksum two bytes at a time with support for + * unaligned buffer. + * Works for len up to and including 0x20000. + * by Curt McDowell, Broadcom Corp. 12/08/2005 + * + * @param dataptr points to start of data to be summed at any boundary + * @param len length of data to be summed + * @return host order (!) lwip checksum (non-inverted Internet sum) + */ + +u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t sum = 0; + int odd = ((mem_ptr_t)pb & 1); + + /* Get aligned to u16_t */ + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + /* Add the bulk of the data */ + ps = (u16_t *)(void *)pb; + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* Consume left-over byte, if any */ + if (len > 0) { + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + /* Add end bytes */ + sum += t; + + /* Fold 32-bit sum to 16 bits + calling this twice is probably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + /* Swap if alignment was odd */ + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ +/** + * An optimized checksum routine. Basically, it uses loop-unrolling on + * the checksum loop, treating the head and tail bytes specially, whereas + * the inner loop acts on 8 bytes at a time. + * + * @arg start of buffer to be checksummed. May be an odd byte address. + * @len number of bytes in the buffer to be checksummed. + * @return host order (!) lwip checksum (non-inverted Internet sum) + * + * by Curt McDowell, Broadcom Corp. December 8th, 2005 + */ + +u16_t +lwip_standard_chksum(void *dataptr, int len) +{ + u8_t *pb = (u8_t *)dataptr; + u16_t *ps, t = 0; + u32_t *pl; + u32_t sum = 0, tmp; + /* starts at odd byte address? */ + int odd = ((mem_ptr_t)pb & 1); + + if (odd && len > 0) { + ((u8_t *)&t)[1] = *pb++; + len--; + } + + ps = (u16_t *)pb; + + if (((mem_ptr_t)ps & 3) && len > 1) { + sum += *ps++; + len -= 2; + } + + pl = (u32_t *)ps; + + while (len > 7) { + tmp = sum + *pl++; /* ping */ + if (tmp < sum) { + tmp++; /* add back carry */ + } + + sum = tmp + *pl++; /* pong */ + if (sum < tmp) { + sum++; /* add back carry */ + } + + len -= 8; + } + + /* make room in upper bits */ + sum = FOLD_U32T(sum); + + ps = (u16_t *)pl; + + /* 16-bit aligned word remaining? */ + while (len > 1) { + sum += *ps++; + len -= 2; + } + + /* dangling tail byte remaining? */ + if (len > 0) { /* include odd byte */ + ((u8_t *)&t)[0] = *(u8_t *)ps; + } + + sum += t; /* add end bytes */ + + /* Fold 32-bit sum to 16 bits + calling this twice is probably faster than if statements... */ + sum = FOLD_U32T(sum); + sum = FOLD_U32T(sum); + + if (odd) { + sum = SWAP_BYTES_IN_WORD(sum); + } + + return (u16_t)sum; +} +#endif + +/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ +static u16_t +inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc) +{ + struct pbuf *q; + u8_t swapped = 0; + + /* iterate through all pbuf in chain */ + for(q = p; q != NULL; q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + acc += LWIP_CHKSUM(q->payload, q->len); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* just executing this next line is probably faster that the if statement needed + to check whether we really need to execute it, and does no harm */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is probably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum_pseudo: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip_addr_t *src, ip_addr_t *dest) +{ + u32_t acc; + u32_t addr; + + addr = ip4_addr_get_u32(src); + acc = (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + /* fold down to 16 bits */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + + return inet_cksum_pseudo_base(p, proto, proto_len, acc); +} +#if LWIP_IPV6 +/** + * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. + * IPv6 addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ipv6 address (used for checksum of pseudo header) + * @param dst destination ipv6 address (used for checksum of pseudo header) + * @param proto ipv6 protocol/next header (used for checksum of pseudo header) + * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip6_addr_t *src, ip6_addr_t *dest) +{ + u32_t acc = 0; + u32_t addr; + u8_t addr_part; + + for (addr_part = 0; addr_part < 4; addr_part++) { + addr = src->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = dest->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + } + /* fold down to 16 bits */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + + return inet_cksum_pseudo_base(p, proto, proto_len, acc); +} +#endif /* LWIP_IPV6 */ + +/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ +static u16_t +inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, u32_t acc) +{ + struct pbuf *q; + u8_t swapped = 0; + u16_t chklen; + + /* iterate through all pbuf in chain */ + for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) { + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", + (void *)q, (void *)q->next)); + chklen = q->len; + if (chklen > chksum_len) { + chklen = chksum_len; + } + acc += LWIP_CHKSUM(q->payload, chklen); + chksum_len -= chklen; + LWIP_ASSERT("delete me", chksum_len < 0x7fff); + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ + /* fold the upper bit down */ + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + + acc += (u32_t)htons((u16_t)proto); + acc += (u32_t)htons(proto_len); + + /* Fold 32-bit sum to 16 bits + calling this twice is probably faster than if statements... */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); + return (u16_t)~(acc & 0xffffUL); +} + +/* inet_chksum_pseudo_partial: + * + * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain. + * IP addresses are expected to be in network byte order. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ip address (used for checksum of pseudo header) + * @param dst destination ip address (used for checksum of pseudo header) + * @param proto ip protocol (used for checksum of pseudo header) + * @param proto_len length of the ip data part (used for checksum of pseudo header) + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest) +{ + u32_t acc; + u32_t addr; + + addr = ip4_addr_get_u32(src); + acc = (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = ip4_addr_get_u32(dest); + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + /* fold down to 16 bits */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + + return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); +} + +#if LWIP_IPV6 +/** + * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. + * IPv6 addresses are expected to be in network byte order. Will only compute for a + * portion of the payload. + * + * @param p chain of pbufs over that a checksum should be calculated (ip data part) + * @param src source ipv6 address (used for checksum of pseudo header) + * @param dst destination ipv6 address (used for checksum of pseudo header) + * @param proto ipv6 protocol/next header (used for checksum of pseudo header) + * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) + * @param chksum_len number of payload bytes used to compute chksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest) +{ + u32_t acc = 0; + u32_t addr; + u8_t addr_part; + + for (addr_part = 0; addr_part < 4; addr_part++) { + addr = src->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + addr = dest->addr[addr_part]; + acc += (addr & 0xffffUL); + acc += ((addr >> 16) & 0xffffUL); + } + /* fold down to 16 bits */ + acc = FOLD_U32T(acc); + acc = FOLD_U32T(acc); + + return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); +} +#endif /* LWIP_IPV6 */ + +/* inet_chksum: + * + * Calculates the Internet checksum over a portion of memory. Used primarily for IP + * and ICMP. + * + * @param dataptr start of the buffer to calculate the checksum (no alignment needed) + * @param len length of the buffer to calculate the checksum + * @return checksum (as u16_t) to be saved directly in the protocol header + */ + +u16_t +inet_chksum(void *dataptr, u16_t len) +{ + return ~LWIP_CHKSUM(dataptr, len); +} + +/** + * Calculate a checksum over a chain of pbufs (without pseudo-header, much like + * inet_chksum only pbufs are used). + * + * @param p pbuf chain over that the checksum should be calculated + * @return checksum (as u16_t) to be saved directly in the protocol header + */ +u16_t +inet_chksum_pbuf(struct pbuf *p) +{ + u32_t acc; + struct pbuf *q; + u8_t swapped; + + acc = 0; + swapped = 0; + for(q = p; q != NULL; q = q->next) { + acc += LWIP_CHKSUM(q->payload, q->len); + acc = FOLD_U32T(acc); + if (q->len % 2 != 0) { + swapped = 1 - swapped; + acc = SWAP_BYTES_IN_WORD(acc); + } + } + + if (swapped) { + acc = SWAP_BYTES_IN_WORD(acc); + } + return (u16_t)~(acc & 0xffffUL); +} + +/* These are some implementations for LWIP_CHKSUM_COPY, which copies data + * like MEMCPY but generates a checksum at the same time. Since this is a + * performance-sensitive function, you might want to create your own version + * in assembly targeted at your hardware by defining it in lwipopts.h: + * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) + */ + +#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ +/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. + * For architectures with big caches, data might still be in cache when + * generating the checksum after copying. + */ +u16_t +lwip_chksum_copy(void *dst, const void *src, u16_t len) +{ + MEMCPY(dst, src, len); + return LWIP_CHKSUM(dst, len); +} +#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/init.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/init.c new file mode 100644 index 0000000..98a8d62 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/init.c @@ -0,0 +1,349 @@ +/** + * @file + * Modules initialization + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/init.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/sockets.h" +#include "lwip/lwip_ip.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp_msg.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/lwip_timers.h" +#include "netif/etharp.h" +#include "lwip/ip6.h" +#include "lwip/nd6.h" +#include "lwip/mld6.h" +#include "lwip/api.h" +#include "netif/ppp/ppp_impl.h" + +/* Compile-time sanity checks for configuration errors. + * These can be done independently of LWIP_DEBUG, without penalty. + */ +#ifndef BYTE_ORDER + #error "BYTE_ORDER is not defined, you have to define it in your cc.h" +#endif +#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) + #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_UDPLITE) + #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DHCP) + #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_IGMP) + #error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_SNMP) + #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if (!LWIP_UDP && LWIP_DNS) + #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" +#endif +#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ +#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) + #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" +#endif +#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) + #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) + #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) + #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" +#endif +#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) + #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" +#endif +#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) + #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" +#endif +/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ +#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0))) + #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" +#endif +#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) + #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" +#endif +#endif /* !MEMP_MEM_MALLOC */ +#if LWIP_WND_SCALE +#if (LWIP_TCP && (TCP_WND > 0xffffffff)) + #error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && LWIP_WND_SCALE > 14) + #error "The maximum valid window scale value is 14!" +#endif +#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE))) + #error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!" +#endif +#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0)) + #error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!" +#endif +#else /* LWIP_WND_SCALE */ +#if (LWIP_TCP && (TCP_WND > 0xffff)) + #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" +#endif +#endif /* LWIP_WND_SCALE */ +#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) + #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" +#endif +#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) + #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" +#endif +#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) + #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" +#endif +#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))) + #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" +#endif +#if (LWIP_NETIF_API && (NO_SYS==1)) + #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) + #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if (LWIP_PPP_API && (NO_SYS==1)) + #error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) + #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" +#endif +#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) + #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" +#endif +#if (!LWIP_ARP && LWIP_AUTOIP) + #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) + #error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" +#endif +#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) + #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" +#endif +#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) + #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" +#endif +#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) + #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" +#endif +#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) + #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" +#endif +#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) + #error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" +#endif +#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) + #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" +#endif +#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT + #error "PPP_SUPPORT needs either PPPOS_SUPPORT or PPPOE_SUPPORT turned on" +#endif +#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) + #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" +#endif +#if (LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) + #error "When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value" +#endif +#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING + #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" +#endif +#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE + #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" +#endif +#if IP_FRAG && IP_FRAG_USES_STATIC_BUF && LWIP_NETIF_TX_SINGLE_PBUF + #error "LWIP_NETIF_TX_SINGLE_PBUF does not work with IP_FRAG_USES_STATIC_BUF==1 as that creates pbuf queues" +#endif +#if LWIP_NETCONN && LWIP_TCP +#if NETCONN_COPY != TCP_WRITE_FLAG_COPY + #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" +#endif +#if NETCONN_MORE != TCP_WRITE_FLAG_MORE + #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" +#endif +#endif /* LWIP_NETCONN && LWIP_TCP */ +#if LWIP_SOCKET +/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ +#if SO_REUSEADDR != SOF_REUSEADDR + #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" +#endif +#if SO_KEEPALIVE != SOF_KEEPALIVE + #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" +#endif +#if SO_BROADCAST != SOF_BROADCAST + #error "WARNING: SO_BROADCAST != SOF_BROADCAST" +#endif +#endif /* LWIP_SOCKET */ + + +/* Compile-time checks for deprecated options. + */ +#ifdef MEMP_NUM_TCPIP_MSG + #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef TCP_REXMIT_DEBUG + #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef RAW_STATS + #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_QUEUE_FIRST + #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." +#endif +#ifdef ETHARP_ALWAYS_INSERT + #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." +#endif + +#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS +#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 +#endif +#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS +#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 +#endif + +/* MEMP sanity checks */ +#if !LWIP_DISABLE_MEMP_SANITY_CHECKS +#if LWIP_NETCONN +#if MEMP_MEM_MALLOC +#if !MEMP_NUM_NETCONN && LWIP_SOCKET +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" +#endif +#else /* MEMP_MEM_MALLOC */ +#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) +#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* MEMP_MEM_MALLOC */ +#endif /* LWIP_NETCONN */ +#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ + +/* TCP sanity checks */ +#if !LWIP_DISABLE_TCP_SANITY_CHECKS +#if LWIP_TCP +#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) + #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_BUF < (2 * TCP_MSS) + #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) + #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDLOWAT >= TCP_SND_BUF + #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN + #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if !MEMP_MEM_MALLOC && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) + #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if !MEMP_MEM_MALLOC && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) + #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#if TCP_WND < TCP_MSS + #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." +#endif +#endif /* LWIP_TCP */ +#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ + +/** + * Perform Sanity check of user-configurable values, and initialize all modules. + */ +void +lwip_init(void) +{ + /* Modules initialization */ + stats_init(); +#if !NO_SYS + sys_init(); +#endif /* !NO_SYS */ + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); + ip_init(); +#if LWIP_ARP + etharp_init(); +#endif /* LWIP_ARP */ +#if LWIP_RAW + raw_init(); +#endif /* LWIP_RAW */ +#if LWIP_UDP + udp_init(); +#endif /* LWIP_UDP */ +#if LWIP_TCP + tcp_init(); +#endif /* LWIP_TCP */ +#if LWIP_SNMP + snmp_init(); +#endif /* LWIP_SNMP */ +#if LWIP_AUTOIP + autoip_init(); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + igmp_init(); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + dns_init(); +#endif /* LWIP_DNS */ +#if LWIP_IPV6 + ip6_init(); + nd6_init(); +#if LWIP_IPV6_MLD + mld6_init(); +#endif /* LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6 */ +#if PPP_SUPPORT + ppp_init(); +#endif + +#if LWIP_TIMERS + sys_timeouts_init(); +#endif /* LWIP_TIMERS */ +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/autoip.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/autoip.c new file mode 100644 index 0000000..3052f6b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/autoip.c @@ -0,0 +1,528 @@ +/** + * @file + * AutoIP Automatic LinkLocal IP Configuration + * + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +/******************************************************************************* + * USAGE: + * + * define LWIP_AUTOIP 1 in your lwipopts.h + * + * If you don't use tcpip.c (so, don't call, you don't call tcpip_init): + * - First, call autoip_init(). + * - call autoip_tmr() all AUTOIP_TMR_INTERVAL msces, + * that should be defined in autoip.h. + * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. + * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... + * + * Without DHCP: + * - Call autoip_start() after netif_add(). + * + * With DHCP: + * - define LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. + * - Configure your DHCP Client. + * + */ + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mem.h" +#include "lwip/udp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" + +#include +#include + +/* 169.254.0.0 */ +#define AUTOIP_NET 0xA9FE0000 +/* 169.254.1.0 */ +#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) +/* 169.254.254.255 */ +#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) + + +/** Pseudo random macro based on netif informations. + * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ +#ifndef LWIP_AUTOIP_RAND +#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ + ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ + ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ + ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ + (netif->autoip?netif->autoip->tried_llipaddr:0)) +#endif /* LWIP_AUTOIP_RAND */ + +/** + * Macro that generates the initial IP address to be tried by AUTOIP. + * If you want to override this, define it to something else in lwipopts.h. + */ +#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR +#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ + htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ + ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) +#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ + +/* static functions */ +static void autoip_handle_arp_conflict(struct netif *netif); + +/* creates a pseudo random LL IP-Address for a network interface */ +static void autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr); + +/* sends an ARP probe */ +static err_t autoip_arp_probe(struct netif *netif); + +/* sends an ARP announce */ +static err_t autoip_arp_announce(struct netif *netif); + +/* configure interface for use with current LL IP-Address */ +static err_t autoip_bind(struct netif *netif); + +/* start sending probes for llipaddr */ +static void autoip_start_probing(struct netif *netif); + + +/** Set a statically allocated struct autoip to work with. + * Using this prevents autoip_start to allocate it using mem_malloc. + * + * @param netif the netif for which to set the struct autoip + * @param dhcp (uninitialised) dhcp struct allocated by the application + */ +void +autoip_set_struct(struct netif *netif, struct autoip *autoip) +{ + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("autoip != NULL", autoip != NULL); + LWIP_ASSERT("netif already has a struct autoip set", netif->autoip == NULL); + + /* clear data structure */ + memset(autoip, 0, sizeof(struct autoip)); + /* autoip->state = AUTOIP_STATE_OFF; */ + netif->autoip = autoip; +} + +/** Restart AutoIP client and check the next address (conflict detected) + * + * @param netif The netif under AutoIP control + */ +static void +autoip_restart(struct netif *netif) +{ + netif->autoip->tried_llipaddr++; + autoip_start(netif); +} + +/** + * Handle a IP address conflict after an ARP conflict detection + */ +static void +autoip_handle_arp_conflict(struct netif *netif) +{ + /* Somehow detect if we are defending or retreating */ + unsigned char defend = 1; /* tbd */ + + if (defend) { + if (netif->autoip->lastconflict > 0) { + /* retreat, there was a conflicting ARP in the last + * DEFEND_INTERVAL seconds + */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); + + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); + autoip_arp_announce(netif); + netif->autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } + } else { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_handle_arp_conflict(): we do not defend, retreating\n")); + /* TODO: close all TCP sessions */ + autoip_restart(netif); + } +} + +/** + * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * + * @param netif network interface on which create the IP-Address + * @param ipaddr ip address to initialize + */ +static void +autoip_create_addr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 + * compliant to RFC 3927 Section 2.1 + * We have 254 * 256 possibilities */ + + u32_t addr = ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); + addr += netif->autoip->tried_llipaddr; + addr = AUTOIP_NET | (addr & 0xffff); + /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ + + if (addr < AUTOIP_RANGE_START) { + addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + if (addr > AUTOIP_RANGE_END) { + addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; + } + LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && + (addr <= AUTOIP_RANGE_END)); + ip4_addr_set_u32(ipaddr, htonl(addr)); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (u16_t)(netif->autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), + ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); +} + +/** + * Sends an ARP probe from a network interface + * + * @param netif network interface used to send the probe + */ +static err_t +autoip_arp_probe(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, IP_ADDR_ANY, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Sends an ARP announce from a network interface + * + * @param netif network interface used to send the announce + */ +static err_t +autoip_arp_announce(struct netif *netif) +{ + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->autoip->llipaddr, ðzero, + &netif->autoip->llipaddr, ARP_REQUEST); +} + +/** + * Configure interface for use with current LL IP-Address + * + * @param netif network interface to configure with current LL IP-Address + */ +static err_t +autoip_bind(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + ip_addr_t sn_mask, gw_addr; + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, + ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), + ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); + + IP4_ADDR(&sn_mask, 255, 255, 0, 0); + IP4_ADDR(&gw_addr, 0, 0, 0, 0); + + netif_set_ipaddr(netif, &autoip->llipaddr); + netif_set_netmask(netif, &sn_mask); + netif_set_gw(netif, &gw_addr); + + /* bring the interface up */ + netif_set_up(netif); + + return ERR_OK; +} + +/** + * Start AutoIP client + * + * @param netif network interface on which start the AutoIP client + */ +err_t +autoip_start(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + err_t result = ERR_OK; + + if (netif_is_up(netif)) { + netif_set_down(netif); + } + + /* Set IP-Address, Netmask and Gateway to 0 to make sure that + * ARP Packets are formed correctly + */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], + netif->name[1], (u16_t)netif->num)); + if (autoip == NULL) { + /* no AutoIP client attached yet? */ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): starting new AUTOIP client\n")); + autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); + if (autoip == NULL) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_start(): could not allocate autoip\n")); + return ERR_MEM; + } + memset(autoip, 0, sizeof(struct autoip)); + /* store this AutoIP client in the netif */ + netif->autoip = autoip; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); + } else { + autoip->state = AUTOIP_STATE_OFF; + autoip->ttw = 0; + autoip->sent_num = 0; + ip_addr_set_zero(&autoip->llipaddr); + autoip->lastconflict = 0; + } + + autoip_create_addr(netif, &(autoip->llipaddr)); + autoip_start_probing(netif); + + return result; +} + +static void +autoip_start_probing(struct netif *netif) +{ + struct autoip *autoip = netif->autoip; + + autoip->state = AUTOIP_STATE_PROBING; + autoip->sent_num = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + + /* time to wait to first probe, this is randomly + * chosen out of 0 to PROBE_WAIT seconds. + * compliant to RFC 3927 Section 2.2.1 + */ + autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); + + /* + * if we tried more then MAX_CONFLICTS we must limit our rate for + * acquiring and probing address + * compliant to RFC 3927 Section 2.2.1 + */ + if (autoip->tried_llipaddr >= MAX_CONFLICTS) { + autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; + } +} + +/** + * Handle a possible change in the network configuration. + * + * If there is an AutoIP address configured, take the interface down + * and begin probing with the same address. + */ +void +autoip_network_changed(struct netif *netif) +{ + if (netif->autoip && netif->autoip->state != AUTOIP_STATE_OFF) { + netif_set_down(netif); + autoip_start_probing(netif); + } +} + +/** + * Stop AutoIP client + * + * @param netif network interface on which stop the AutoIP client + */ +err_t +autoip_stop(struct netif *netif) +{ + netif->autoip->state = AUTOIP_STATE_OFF; + netif_set_down(netif); + return ERR_OK; +} + +/** + * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds + */ +void +autoip_tmr() +{ + struct netif *netif = netif_list; + /* loop through netif's */ + while (netif != NULL) { + /* only act on AutoIP configured interfaces */ + if (netif->autoip != NULL) { + if (netif->autoip->lastconflict > 0) { + netif->autoip->lastconflict--; + } + + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", + (u16_t)(netif->autoip->state), netif->autoip->ttw)); + + switch(netif->autoip->state) { + case AUTOIP_STATE_PROBING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num >= PROBE_NUM) { + netif->autoip->state = AUTOIP_STATE_ANNOUNCING; + netif->autoip->sent_num = 0; + netif->autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } else { + autoip_arp_probe(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() PROBING Sent Probe\n")); + netif->autoip->sent_num++; + /* calculate time to wait to next probe */ + netif->autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % + ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + + PROBE_MIN * AUTOIP_TICKS_PER_SECOND); + } + } + break; + + case AUTOIP_STATE_ANNOUNCING: + if (netif->autoip->ttw > 0) { + netif->autoip->ttw--; + } else { + if (netif->autoip->sent_num == 0) { + /* We are here the first time, so we waited ANNOUNCE_WAIT seconds + * Now we can bind to an IP address and use it. + * + * autoip_bind calls netif_set_up. This triggers a gratuitous ARP + * which counts as an announcement. + */ + autoip_bind(netif); + } else { + autoip_arp_announce(netif); + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, + ("autoip_tmr() ANNOUNCING Sent Announce\n")); + } + netif->autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; + netif->autoip->sent_num++; + + if (netif->autoip->sent_num >= ANNOUNCE_NUM) { + netif->autoip->state = AUTOIP_STATE_BOUND; + netif->autoip->sent_num = 0; + netif->autoip->ttw = 0; + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(&netif->autoip->llipaddr), ip4_addr2_16(&netif->autoip->llipaddr), + ip4_addr3_16(&netif->autoip->llipaddr), ip4_addr4_16(&netif->autoip->llipaddr))); + } + } + break; + } + } + /* proceed to next network interface */ + netif = netif->next; + } +} + +/** + * Handles every incoming ARP Packet, called by etharp_arp_input. + * + * @param netif network interface to use for autoip processing + * @param hdr Incoming ARP packet + */ +void +autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) +{ + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); + if ((netif->autoip != NULL) && (netif->autoip->state != AUTOIP_STATE_OFF)) { + /* when ip.src == llipaddr && hw.src != netif->hwaddr + * + * when probing ip.dst == llipaddr && hw.src != netif->hwaddr + * we have a conflict and must solve it + */ + ip_addr_t sipaddr, dipaddr; + struct eth_addr netifaddr; + ETHADDR16_COPY(netifaddr.addr, netif->hwaddr); + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). + */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + if ((netif->autoip->state == AUTOIP_STATE_PROBING) || + ((netif->autoip->state == AUTOIP_STATE_ANNOUNCING) && + (netif->autoip->sent_num == 0))) { + /* RFC 3927 Section 2.2.1: + * from beginning to after ANNOUNCE_WAIT + * seconds we have a conflict if + * ip.src == llipaddr OR + * ip.dst == llipaddr && hw.src != own hwaddr + */ + if ((ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr)) || + (ip_addr_cmp(&dipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Probe Conflict detected\n")); + autoip_restart(netif); + } + } else { + /* RFC 3927 Section 2.5: + * in any state we have a conflict if + * ip.src == llipaddr && hw.src != own hwaddr + */ + if (ip_addr_cmp(&sipaddr, &netif->autoip->llipaddr) && + !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { + LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, + ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); + autoip_handle_arp_conflict(netif); + } + } + } +} + +#endif /* LWIP_AUTOIP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/icmp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/icmp.c new file mode 100644 index 0000000..cd8f652 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/icmp.c @@ -0,0 +1,339 @@ +/** + * @file + * ICMP - Internet Control Message Protocol + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* Some ICMP messages should be passed to the transport protocols. This + is not implemented. */ + +#include "lwip/opt.h" + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/lwip_ip.h" +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" + +#include + +/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be + * used to modify and send a response packet (and to 1 if this is not the case, + * e.g. when link header is stripped of when receiving) */ +#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + +/* The amount of data from the original packet to return in a dest-unreachable */ +#define ICMP_DEST_UNREACH_DATASIZE 8 + +static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); + +/** + * Processes ICMP input packets, called from ip_input(). + * + * Currently only processes icmp echo requests and sends + * out the echo response. + * + * @param p the icmp echo request packet, p->payload pointing to the icmp header + * @param inp the netif on which this packet was received + */ +void +icmp_input(struct pbuf *p, struct netif *inp) +{ + u8_t type; +#ifdef LWIP_DEBUG + u8_t code; +#endif /* LWIP_DEBUG */ + struct icmp_echo_hdr *iecho; + struct ip_hdr *iphdr; + s16_t hlen; + + ICMP_STATS_INC(icmp.recv); + snmp_inc_icmpinmsgs(); + + iphdr = (struct ip_hdr *)ip_current_header(); + hlen = IPH_HL(iphdr) * 4; + if (p->len < sizeof(u16_t)*2) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); + goto lenerr; + } + + type = *((u8_t *)p->payload); +#ifdef LWIP_DEBUG + code = *(((u8_t *)p->payload)+1); +#endif /* LWIP_DEBUG */ + switch (type) { + case ICMP_ER: + /* This is OK, echo reply might have been parsed by a raw PCB + (as obviously, an echo request has been sent, too). */ + break; + case ICMP_ECHO: +#if !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING + { + int accepted = 1; +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip_addr_ismulticast(ip_current_dest_addr())) { + accepted = 0; + } +#endif /* LWIP_MULTICAST_PING */ +#if !LWIP_BROADCAST_PING + /* broadcast destination address? */ + if (ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { + accepted = 0; + } +#endif /* LWIP_BROADCAST_PING */ + /* broadcast or multicast destination address not accepted? */ + if (!accepted) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast or broadcast pings\n")); + ICMP_STATS_INC(icmp.err); + pbuf_free(p); + return; + } + } +#endif /* !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); + if (p->tot_len < sizeof(struct icmp_echo_hdr)) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); + goto lenerr; + } +#if CHECKSUM_CHECK_ICMP + if (inet_chksum_pbuf(p) != 0) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); + pbuf_free(p); + ICMP_STATS_INC(icmp.chkerr); + snmp_inc_icmpinerrors(); + return; + } +#endif +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN + if (pbuf_header(p, (PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + /* p is not big enough to contain link headers + * allocate a new one and copy p into it + */ + struct pbuf *r; + /* allocate new packet buffer with space for link headers */ + r = pbuf_alloc(PBUF_LINK, p->tot_len + hlen, PBUF_RAM); + if (r == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); + goto memerr; + } + LWIP_ASSERT("check that first pbuf can hold struct the ICMP header", + (r->len >= hlen + sizeof(struct icmp_echo_hdr))); + /* copy the ip header */ + MEMCPY(r->payload, iphdr, hlen); + iphdr = (struct ip_hdr *)r->payload; + /* switch r->payload back to icmp header */ + if (pbuf_header(r, -hlen)) { + LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0); + goto memerr; + } + /* copy the rest of the packet without ip header */ + if (pbuf_copy(r, p) != ERR_OK) { + LWIP_ASSERT("icmp_input: copying to new pbuf failed\n", 0); + goto memerr; + } + /* free the original p */ + pbuf_free(p); + /* we now have an identical copy of p that has room for link headers */ + p = r; + } else { + /* restore p->payload to point to icmp header */ + if (pbuf_header(p, -(s16_t)(PBUF_IP_HLEN + PBUF_LINK_HLEN))) { + LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); + goto memerr; + } + } +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ + /* At this point, all checks are OK. */ + /* We generate an answer by switching the dest and src ip addresses, + * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ + iecho = (struct icmp_echo_hdr *)p->payload; + ip_addr_copy(iphdr->src, *ip_current_dest_addr()); + ip_addr_copy(iphdr->dest, *ip_current_src_addr()); + ICMPH_TYPE_SET(iecho, ICMP_ER); +#if CHECKSUM_GEN_ICMP + /* adjust the checksum */ + if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; + } else { + iecho->chksum += PP_HTONS(ICMP_ECHO << 8); + } +#else /* CHECKSUM_GEN_ICMP */ + iecho->chksum = 0; +#endif /* CHECKSUM_GEN_ICMP */ + + /* Set the correct TTL and recalculate the header checksum. */ + IPH_TTL_SET(iphdr, ICMP_TTL); + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of echo replies attempted to send */ + snmp_inc_icmpoutechoreps(); + + if(pbuf_header(p, hlen)) { + LWIP_ASSERT("Can't move over header in packet", 0); + } else { + err_t ret; + /* send an ICMP packet, src addr is the dest addr of the current packet */ + ret = ip_output_if(p, ip_current_dest_addr(), IP_HDRINCL, + ICMP_TTL, 0, IP_PROTO_ICMP, inp); + if (ret != ERR_OK) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %c.\n", ret)); + } + } + break; + default: + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", + (s16_t)type, (s16_t)code)); + ICMP_STATS_INC(icmp.proterr); + ICMP_STATS_INC(icmp.drop); + } + pbuf_free(p); + return; +lenerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.lenerr); + snmp_inc_icmpinerrors(); + return; +#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN +memerr: + pbuf_free(p); + ICMP_STATS_INC(icmp.err); + snmp_inc_icmpinerrors(); + return; +#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ +} + +/** + * Send an icmp 'destination unreachable' packet, called from ip_input() if + * the transport layer protocol is unknown and from udp_input() if the local + * port is not bound. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'unreachable' packet + */ +void +icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) +{ + icmp_send_response(p, ICMP_DUR, t); +} + +#if IP_FORWARD || IP_REASSEMBLY +/** + * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. + * + * @param p the input packet for which the 'time exceeded' should be sent, + * p->payload pointing to the IP header + * @param t type of the 'time exceeded' packet + */ +void +icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) +{ + icmp_send_response(p, ICMP_TE, t); +} + +#endif /* IP_FORWARD || IP_REASSEMBLY */ + +/** + * Send an icmp packet in response to an incoming packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IP header + * @param type Type of the ICMP header + * @param code Code of the ICMP header + */ +static void +icmp_send_response(struct pbuf *p, u8_t type, u8_t code) +{ + struct pbuf *q; + struct ip_hdr *iphdr; + /* we can use the echo header here */ + struct icmp_echo_hdr *icmphdr; + ip_addr_t iphdr_src; + + /* ICMP header + IP header + 8 bytes of data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, + PBUF_RAM); + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp message", + (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); + + iphdr = (struct ip_hdr *)p->payload; + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->src)); + LWIP_DEBUGF(ICMP_DEBUG, (" to ")); + ip_addr_debug_print(ICMP_DEBUG, &(iphdr->dest)); + LWIP_DEBUGF(ICMP_DEBUG, ("\n")); + + icmphdr = (struct icmp_echo_hdr *)q->payload; + icmphdr->type = type; + icmphdr->code = code; + icmphdr->id = 0; + icmphdr->seqno = 0; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); + + /* calculate checksum */ + icmphdr->chksum = 0; +#if CHECKSUM_GEN_ICMP + icmphdr->chksum = inet_chksum(icmphdr, q->len); +#endif + ICMP_STATS_INC(icmp.xmit); + /* increase number of messages attempted to send */ + snmp_inc_icmpoutmsgs(); + /* increase number of destination unreachable messages attempted to send */ + snmp_inc_icmpouttimeexcds(); + ip_addr_copy(iphdr_src, iphdr->src); + ip_output(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP); + pbuf_free(q); +} + +#endif /* LWIP_ICMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/igmp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/igmp.c new file mode 100644 index 0000000..0d09a8c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/igmp.c @@ -0,0 +1,816 @@ +/** + * @file + * IGMP - Internet Group Management Protocol + * + */ + +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +/*------------------------------------------------------------- +Note 1) +Although the rfc requires V1 AND V2 capability +we will only support v2 since now V1 is very old (August 1989) +V1 can be added if required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 2) +A query for a specific group address (as opposed to ALLHOSTS) +has now been implemented as I am unsure if it is required + +a debug print and statistic have been implemented to +show this up. +------------------------------------------------------------- +------------------------------------------------------------- +Note 3) +The router alert rfc 2113 is implemented in outgoing packets +but not checked rigorously incoming +------------------------------------------------------------- +Steve Reynolds +------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * RFC 988 - Host extensions for IP multicasting - V0 + * RFC 1054 - Host extensions for IP multicasting - + * RFC 1112 - Host extensions for IP multicasting - V1 + * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) + * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 + * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ + * RFC 2113 - IP Router Alert Option - + *----------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Includes + *----------------------------------------------------------------------------*/ + +#include "lwip/opt.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/igmp.h" +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/lwip_ip.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/stats.h" + +#include "string.h" + +/* + * IGMP constants + */ +#define IGMP_TTL 1 +#define IGMP_MINLEN 8 +#define ROUTER_ALERT 0x9404U +#define ROUTER_ALERTLEN 4 + +/* + * IGMP message types, including version number. + */ +#define IGMP_MEMB_QUERY 0x11 /* Membership query */ +#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ +#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ +#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ + +/* Group membership states */ +#define IGMP_GROUP_NON_MEMBER 0 +#define IGMP_GROUP_DELAYING_MEMBER 1 +#define IGMP_GROUP_IDLE_MEMBER 2 + +/** + * IGMP packet format. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct igmp_msg { + PACK_STRUCT_FLD_8(u8_t igmp_msgtype); + PACK_STRUCT_FLD_8(u8_t igmp_maxresp); + PACK_STRUCT_FIELD(u16_t igmp_checksum); + PACK_STRUCT_FLD_S(ip_addr_p_t igmp_group_address); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +static struct igmp_group *igmp_lookup_group(struct netif *ifp, ip_addr_t *addr); +static err_t igmp_remove_group(struct igmp_group *group); +static void igmp_timeout( struct igmp_group *group); +static void igmp_start_timer(struct igmp_group *group, u8_t max_time); +static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); +static err_t igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif); +static void igmp_send(struct igmp_group *group, u8_t type); + + +static struct igmp_group* igmp_group_list; +static ip_addr_t allsystems; +static ip_addr_t allrouters; + + +/** + * Initialize the IGMP module + */ +void +igmp_init(void) +{ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); + + IP4_ADDR(&allsystems, 224, 0, 0, 1); + IP4_ADDR(&allrouters, 224, 0, 0, 2); +} + +#ifdef LWIP_DEBUG +/** + * Dump global IGMP groups list + */ +void +igmp_dump_group_list() +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state))); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + group = group->next; + } + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); +} +#else +#define igmp_dump_group_list() +#endif /* LWIP_DEBUG */ + +/** + * Start IGMP processing on interface + * + * @param netif network interface on which start IGMP processing + */ +err_t +igmp_start(struct netif *netif) +{ + struct igmp_group* group; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", netif)); + + group = igmp_lookup_group(netif, &allsystems); + + if (group != NULL) { + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->use++; + + /* Allow the igmp messages at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, &allsystems); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &allsystems, IGMP_ADD_MAC_FILTER); + } + + return ERR_OK; + } + + return ERR_MEM; +} + +/** + * Stop IGMP processing on interface + * + * @param netif network interface on which stop IGMP processing + */ +err_t +igmp_stop(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + struct igmp_group *prev = NULL; + struct igmp_group *next; + + /* look for groups joined on this interface further down the list */ + while (group != NULL) { + next = group->next; + /* is it a group joined on this interface? */ + if (group->netif == netif) { + /* is it the first group of the list? */ + if (group == igmp_group_list) { + igmp_group_list = next; + } + /* is there a "previous" group defined? */ + if (prev != NULL) { + prev->next = next; + } + /* disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, &group->group_address); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER); + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + } else { + /* change the "previous" */ + prev = group; + } + /* move to "next" */ + group = next; + } + return ERR_OK; +} + +/** + * Report IGMP memberships for this interface + * + * @param netif network interface on which report IGMP memberships + */ +void +igmp_report_groups(struct netif *netif) +{ + struct igmp_group *group = igmp_group_list; + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", netif)); + + while (group != NULL) { + if ((group->netif == netif) && (!(ip_addr_cmp(&(group->group_address), &allsystems)))) { + igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + } + group = group->next; + } +} + +/** + * Search for a group in the global igmp_group_list + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search for + * @return a struct igmp_group* if the group has been found, + * NULL if the group wasn't found. + */ +struct igmp_group * +igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if ((group->netif == ifp) && (ip_addr_cmp(&(group->group_address), addr))) { + return group; + } + group = group->next; + } + + /* to be clearer, we return NULL here instead of + * 'group' (which is also NULL at this point). + */ + return NULL; +} + +/** + * Search for a specific igmp group and create a new one if not found- + * + * @param ifp the network interface for which to look + * @param addr the group ip address to search + * @return a struct igmp_group*, + * NULL on memory error. + */ +struct igmp_group * +igmp_lookup_group(struct netif *ifp, ip_addr_t *addr) +{ + struct igmp_group *group = igmp_group_list; + + /* Search if the group already exists */ + group = igmp_lookfor_group(ifp, addr); + if (group != NULL) { + /* Group already exists. */ + return group; + } + + /* Group doesn't exist yet, create a new one */ + group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); + if (group != NULL) { + group->netif = ifp; + ip_addr_set(&(group->group_address), addr); + group->timer = 0; /* Not running */ + group->group_state = IGMP_GROUP_NON_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; + group->next = igmp_group_list; + + igmp_group_list = group; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); + ip_addr_debug_print(IGMP_DEBUG, addr); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", ifp)); + + return group; +} + +/** + * Remove a group in the global igmp_group_list + * + * @param group the group to remove from the global igmp_group_list + * @return ERR_OK if group was removed from the list, an err_t otherwise + */ +static err_t +igmp_remove_group(struct igmp_group *group) +{ + err_t err = ERR_OK; + + /* Is it the first group? */ + if (igmp_group_list == group) { + igmp_group_list = group->next; + } else { + /* look for group further down the list */ + struct igmp_group *tmpGroup; + for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { + if (tmpGroup->next == group) { + tmpGroup->next = group->next; + break; + } + } + /* Group not found in the global igmp_group_list */ + if (tmpGroup == NULL) + err = ERR_ARG; + } + /* free group */ + memp_free(MEMP_IGMP_GROUP, group); + + return err; +} + +/** + * Called from ip_input() if a new IGMP packet is received. + * + * @param p received igmp packet, p->payload pointing to the igmp header + * @param inp network interface on which the packet was received + * @param dest destination ip address of the igmp packet + */ +void +igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest) +{ + struct igmp_msg* igmp; + struct igmp_group* group; + struct igmp_group* groupref; + + IGMP_STATS_INC(igmp.recv); + + /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ + if (p->len < IGMP_MINLEN) { + pbuf_free(p); + IGMP_STATS_INC(igmp.lenerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); + return; + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); + ip_addr_debug_print(IGMP_DEBUG, &(ip_current_header()->src)); + LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); + ip_addr_debug_print(IGMP_DEBUG, &(ip_current_header()->dest)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", inp)); + + /* Now calculate and check the checksum */ + igmp = (struct igmp_msg *)p->payload; + if (inet_chksum(igmp, p->len)) { + pbuf_free(p); + IGMP_STATS_INC(igmp.chkerr); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); + return; + } + + /* Packet is ok so find an existing group */ + group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ + + /* If group can be found or create... */ + if (!group) { + pbuf_free(p); + IGMP_STATS_INC(igmp.drop); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); + return; + } + + /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ + switch (igmp->igmp_msgtype) { + case IGMP_MEMB_QUERY: { + /* IGMP_MEMB_QUERY to the "all systems" address ? */ + if ((ip_addr_cmp(dest, &allsystems)) && ip_addr_isany(&igmp->igmp_group_address)) { + /* THIS IS THE GENERAL QUERY */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + + if (igmp->igmp_maxresp == 0) { + IGMP_STATS_INC(igmp.rx_v1); + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); + igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; + } else { + IGMP_STATS_INC(igmp.rx_general); + } + + groupref = igmp_group_list; + while (groupref) { + /* Do not send messages on the all systems group address! */ + if ((groupref->netif == inp) && (!(ip_addr_cmp(&(groupref->group_address), &allsystems)))) { + igmp_delaying_member(groupref, igmp->igmp_maxresp); + } + groupref = groupref->next; + } + } else { + /* IGMP_MEMB_QUERY to a specific group ? */ + if (!ip_addr_isany(&igmp->igmp_group_address)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); + ip_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address); + if (ip_addr_cmp(dest, &allsystems)) { + ip_addr_t groupaddr; + LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + /* we first need to re-look for the group since we used dest last time */ + ip_addr_copy(groupaddr, igmp->igmp_group_address); + group = igmp_lookfor_group(inp, &groupaddr); + } else { + LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); + } + + if (group != NULL) { + IGMP_STATS_INC(igmp.rx_group); + igmp_delaying_member(group, igmp->igmp_maxresp); + } else { + IGMP_STATS_INC(igmp.drop); + } + } else { + IGMP_STATS_INC(igmp.proterr); + } + } + break; + } + case IGMP_V2_MEMB_REPORT: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); + IGMP_STATS_INC(igmp.rx_report); + if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { + /* This is on a specific group we have already looked up */ + group->timer = 0; /* stopped */ + group->group_state = IGMP_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + } + break; + } + default: { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", + igmp->igmp_msgtype, group->group_state, &group, group->netif)); + IGMP_STATS_INC(igmp.proterr); + break; + } + } + + pbuf_free(p); + return; +} + +/** + * Join a group on one network interface. + * + * @param ifaddr ip address of the network interface which should join a new group + * @param groupaddr the ip address of the group which to join + * @return ERR_OK if group was joined on the netif(s), an err_t otherwise + */ +err_t +igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we join this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group or create a new one if not found */ + group = igmp_lookup_group(netif, groupaddr); + + if (group != NULL) { + /* This should create a new group, check the state to make sure */ + if (group->group_state != IGMP_GROUP_NON_MEMBER) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_NON_MEMBER\n")); + } else { + /* OK - it was new group */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If first use of the group, allow the group at the MAC level */ + if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER); + } + + IGMP_STATS_INC(igmp.tx_join); + igmp_send(group, IGMP_V2_MEMB_REPORT); + + igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } + /* Increment group use */ + group->use++; + /* Join on this interface */ + err = ERR_OK; + } else { + /* Return an error even if some network interfaces are joined */ + /** @todo undo any other netif already joined */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enough memory to join to group\n")); + return ERR_MEM; + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * Leave a group on one network interface. + * + * @param ifaddr ip address of the network interface which should leave a group + * @param groupaddr the ip address of the group which to leave + * @return ERR_OK if group was left on the netif(s), an err_t otherwise + */ +err_t +igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct igmp_group *group; + struct netif *netif; + + /* make sure it is multicast address */ + LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;); + LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we leave this interface ? */ + if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) { + /* find group */ + group = igmp_lookfor_group(netif, groupaddr); + + if (group != NULL) { + /* Only send a leave if the flag is set according to the state diagram */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* If there is no other use of the group */ + if (group->use <= 1) { + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n")); + IGMP_STATS_INC(igmp.tx_leave); + igmp_send(group, IGMP_LEAVE_GROUP); + } + + /* Disable the group at the MAC level */ + if (netif->igmp_mac_filter != NULL) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", netif)); + netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER); + } + + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: ")); + ip_addr_debug_print(IGMP_DEBUG, groupaddr); + LWIP_DEBUGF(IGMP_DEBUG, ("\n")); + + /* Free the group */ + igmp_remove_group(group); + } else { + /* Decrement group use */ + group->use--; + } + /* Leave on this interface */ + err = ERR_OK; + } else { + /* It's not a fatal error on "leavegroup" */ + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n")); + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * The igmp timer function (both for NO_SYS=1 and =0) + * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). + */ +void +igmp_tmr(void) +{ + struct igmp_group *group = igmp_group_list; + + while (group != NULL) { + if (group->timer > 0) { + group->timer--; + if (group->timer == 0) { + igmp_timeout(group); + } + } + group = group->next; + } +} + +/** + * Called if a timeout for one group is reached. + * Sends a report for this group. + * + * @param group an igmp_group for which a timeout is reached + */ +static void +igmp_timeout(struct igmp_group *group) +{ + /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group + (unless it is the allsystems group) */ + if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && + (!(ip_addr_cmp(&(group->group_address), &allsystems)))) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); + ip_addr_debug_print(IGMP_DEBUG, &(group->group_address)); + LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", group->netif)); + + IGMP_STATS_INC(igmp.tx_report); + igmp_send(group, IGMP_V2_MEMB_REPORT); + } +} + +/** + * Start a timer for an igmp group + * + * @param group the igmp_group for which to start a timer + * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with + * every call to igmp_tmr()) + */ +static void +igmp_start_timer(struct igmp_group *group, u8_t max_time) +{ + /* ensure the input value is > 0 */ +#ifdef LWIP_RAND + if (max_time == 0) { + max_time = 1; + } + /* ensure the random value is > 0 */ + group->timer = (LWIP_RAND() % max_time); + if (group->timer == 0) { + group->timer = 1; + } +#else /* LWIP_RAND */ + /* ATTENTION: use this only if absolutely necessary! */ + group->timer = max_time / 2; + if (group->timer == 0) { + group->timer = 1; + } +#endif /* LWIP_RAND */ +} + +/** + * Delaying membership report for a group if necessary + * + * @param group the igmp_group for which "delaying" membership report + * @param maxresp query delay + */ +static void +igmp_delaying_member(struct igmp_group *group, u8_t maxresp) +{ + if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || + ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && + ((group->timer == 0) || (maxresp < group->timer)))) { + igmp_start_timer(group, maxresp); + group->group_state = IGMP_GROUP_DELAYING_MEMBER; + } +} + + +/** + * Sends an IP packet on a network interface. This function constructs the IP header + * and calculates the IP header checksum. If the source IP address is NULL, + * the IP address of the outgoing network interface is filled in as source address. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + */ +static err_t +igmp_ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, struct netif *netif) +{ + /* This is the "router alert" option */ + u16_t ra[2]; + ra[0] = PP_HTONS(ROUTER_ALERT); + ra[1] = 0x0000; /* Router shall examine packet */ + IGMP_STATS_INC(igmp.xmit); + return ip_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); +} + +/** + * Send an igmp packet to a specific group. + * + * @param group the group to which to send the packet + * @param type the type of igmp packet to send + */ +static void +igmp_send(struct igmp_group *group, u8_t type) +{ + struct pbuf* p = NULL; + struct igmp_msg* igmp = NULL; + ip_addr_t src = *IP_ADDR_ANY; + ip_addr_t* dest = NULL; + + /* IP header + "router alert" option + IGMP header */ + p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); + + if (p) { + igmp = (struct igmp_msg *)p->payload; + LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", + (p->len >= sizeof(struct igmp_msg))); + ip_addr_copy(src, group->netif->ip_addr); + + if (type == IGMP_V2_MEMB_REPORT) { + dest = &(group->group_address); + ip_addr_copy(igmp->igmp_group_address, group->group_address); + group->last_reporter_flag = 1; /* Remember we were the last to report */ + } else { + if (type == IGMP_LEAVE_GROUP) { + dest = &allrouters; + ip_addr_copy(igmp->igmp_group_address, group->group_address); + } + } + + if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { + igmp->igmp_msgtype = type; + igmp->igmp_maxresp = 0; + igmp->igmp_checksum = 0; + igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); + + igmp_ip_output_if(p, &src, dest, group->netif); + } + + pbuf_free(p); + } else { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); + IGMP_STATS_INC(igmp.memerr); + } +} + +#endif /* LWIP_IGMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4.c new file mode 100644 index 0000000..b2dbdad --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4.c @@ -0,0 +1,965 @@ +/** + * @file + * This is the IPv4 layer implementation for incoming and outgoing IP traffic. + * + * @see ip_frag.c + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/lwip_ip.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/ip_frag.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/igmp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/stats.h" +#include "arch/perf.h" + +#include + +/** Set this to 0 in the rare case of wanting to call an extra function to + * generate the IP checksum (in contrast to calculating it on-the-fly). */ +#ifndef LWIP_INLINE_IP_CHKSUM +#define LWIP_INLINE_IP_CHKSUM 1 +#endif +#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP_INLINE 1 +#else +#define CHECKSUM_GEN_IP_INLINE 0 +#endif + +#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 + +/** Some defines for DHCP to let link-layer-addressed packets through while the + * netif is down. + * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT + * to return 1 if the port is accepted and 0 if the port is not accepted. + */ +#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) +/* accept DHCP client port and custom port */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ + || (LWIP_IP_ACCEPT_UDP_PORT(port))) +#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept custom port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) +#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ +/* accept DHCP client port only */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) +#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ + +#else /* LWIP_DHCP */ +#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 +#endif /* LWIP_DHCP */ + +/** Global data for both IPv4 and IPv6 */ +struct ip_globals ip_data; + +/** The IP header ID of the next outgoing IP packet */ +static u16_t ip_id; + +/** + * Finds the appropriate network interface for a given IP address. It + * searches the list of network interfaces linearly. A match is found + * if the masked IP address of the network interface equals the masked + * IP address given to the function. + * + * @param dest the destination IP address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip_route(ip_addr_t *dest) +{ + struct netif *netif; + +#ifdef LWIP_HOOK_IP4_ROUTE + netif = LWIP_HOOK_IP4_ROUTE(dest); + if (netif != NULL) { + return netif; + } +#endif + + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* network mask matches? */ + if ((netif_is_up(netif)) +#if LWIP_IPV6 + /* prevent using IPv6-only interfaces */ + && (!ip_addr_isany(&(netif->ip_addr))) +#endif /* LWIP_IPV6 */ + ) { + if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + if ((netif_default == NULL) || (!netif_is_up(netif_default))) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + snmp_inc_ipoutnoroutes(); + return NULL; + } + /* no matching netif found, use default netif */ + return netif_default; +} + +#if IP_FORWARD +/** + * Determine whether an IP address is in a reserved set of addresses + * that may not be forwarded, or whether datagrams to that destination + * may be forwarded. + * @param p the packet to forward + * @param dest the destination IP address + * @return 1: can forward 0: discard + */ +static int +ip_canforward(struct pbuf *p) +{ + u32_t addr = htonl(ip4_addr_get_u32(ip_current_dest_addr())); + + if (p->flags & PBUF_FLAG_LLBCAST) { + /* don't route link-layer broadcasts */ + return 0; + } + if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { + /* don't route link-layer multicasts unless the destination address is an IP + multicast address */ + return 0; + } + if (IP_EXPERIMENTAL(addr)) { + return 0; + } + if (IP_CLASSA(addr)) { + u32_t net = addr & IP_CLASSA_NET; + if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { + /* don't route loopback packets */ + return 0; + } + } + return 1; +} + +/** + * Forwards an IP packet. It finds an appropriate route for the + * packet, decrements the TTL value of the packet, adjusts the + * checksum and outputs the packet on the appropriate interface. + * + * @param p the packet to forward (p->payload points to IP header) + * @param iphdr the IP header of the input packet + * @param inp the netif on which this packet was received + */ +static void +ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) +{ + struct netif *netif; + + PERF_START; + + if (!ip_canforward(p)) { + goto return_noroute; + } + + /* RFC3927 2.7: do not forward link-local addresses */ + if (ip_addr_islinklocal(ip_current_dest_addr())) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); + goto return_noroute; + } + + /* Find network interface where to forward this IP packet to. */ + netif = ip_route(ip_current_dest_addr()); + if (netif == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); + /* @todo: send ICMP_DUR_NET? */ + goto return_noroute; + } +#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF + /* Do not forward packets onto the same network interface on which + * they arrived. */ + if (netif == inp) { + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n")); + goto return_noroute; + } +#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ + + /* decrement TTL */ + IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); + /* send ICMP if TTL == 0 */ + if (IPH_TTL(iphdr) == 0) { + snmp_inc_ipinhdrerrors(); +#if LWIP_ICMP + /* Don't send ICMP messages in response to ICMP messages */ + if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { + icmp_time_exceeded(p, ICMP_TE_TTL); + } +#endif /* LWIP_ICMP */ + return; + } + + /* Incrementally update the IP checksum. */ + if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); + } else { + IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); + } + + LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ip_current_dest_addr()), ip4_addr2_16(ip_current_dest_addr()), + ip4_addr3_16(ip_current_dest_addr()), ip4_addr4_16(ip_current_dest_addr()))); + + IP_STATS_INC(ip.fw); + IP_STATS_INC(ip.xmit); + snmp_inc_ipforwdatagrams(); + + PERF_STOP("ip_forward"); + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { +#if IP_FRAG + ip_frag(p, netif, ip_current_dest_addr()); +#else /* IP_FRAG */ + /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */ +#endif /* IP_FRAG */ + } else { + /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */ + icmp_dest_unreach(p, ICMP_DUR_FRAG); + } + return; + } + /* transmit pbuf on chosen interface */ + netif->output(netif, p, ip_current_dest_addr()); + return; +return_noroute: + snmp_inc_ipoutnoroutes(); +} +#endif /* IP_FORWARD */ + +/** + * This function is called by the network interface device driver when + * an IP packet is received. The function does the basic checks of the + * IP header such as packet size being at least larger than the header + * size etc. If the packet was not destined for us, the packet is + * forwarded (using ip_forward). The IP checksum is always checked. + * + * Finally, the packet is sent to the upper layer protocol input function. + * + * @param p the received IP packet (p->payload points to IP header) + * @param inp the netif on which this packet was received + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip_input(struct pbuf *p, struct netif *inp) +{ + struct ip_hdr *iphdr; + struct netif *netif; + u16_t iphdr_hlen; + u16_t iphdr_len; +#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP + int check_ip_src = 1; +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */ + + IP_STATS_INC(ip.recv); + snmp_inc_ipinreceives(); + + /* identify the IP header */ + iphdr = (struct ip_hdr *)p->payload; + if (IPH_V(iphdr) != 4) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.err); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } + +#ifdef LWIP_HOOK_IP4_INPUT + if (LWIP_HOOK_IP4_INPUT(p, inp)) { + /* the packet has been eaten */ + return ERR_OK; + } +#endif + + /* obtain IP header length in number of 32-bit words */ + iphdr_hlen = IPH_HL(iphdr); + /* calculate IP header length in bytes */ + iphdr_hlen *= 4; + /* obtain ip length in bytes */ + iphdr_len = ntohs(IPH_LEN(iphdr)); + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { + if (iphdr_hlen > p->len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_hlen, p->len)); + } + if (iphdr_len > p->tot_len) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + iphdr_len, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.lenerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipindiscards(); + return ERR_OK; + } + + /* verify checksum */ +#if CHECKSUM_CHECK_IP + if (inet_chksum(iphdr, iphdr_hlen) != 0) { + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); + ip_debug_print(p); + pbuf_free(p); + IP_STATS_INC(ip.chkerr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinhdrerrors(); + return ERR_OK; + } +#endif + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, iphdr_len); + + /* copy IP addresses to aligned ip_addr_t */ + ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_dest), iphdr->dest); + ip_addr_copy(*ipX_2_ip(&ip_data.current_iphdr_src), iphdr->src); + + /* match packet against an interface, i.e. is this packet for us? */ +#if LWIP_IGMP + if (ip_addr_ismulticast(ip_current_dest_addr())) { + if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip_current_dest_addr()))) { + /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */ + ip_addr_t allsystems; + IP4_ADDR(&allsystems, 224, 0, 0, 1); + if (ip_addr_cmp(ip_current_dest_addr(), &allsystems) && + ip_addr_isany(ip_current_src_addr())) { + check_ip_src = 0; + } + netif = inp; + } else { + netif = NULL; + } + } else +#endif /* LWIP_IGMP */ + { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + netif = inp; + do { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", + ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr), + ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask), + ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { + /* unicast to this interface address? */ + if (ip_addr_cmp(ip_current_dest_addr(), &(netif->ip_addr)) || + /* or broadcast on this interface network address? */ + ip_addr_isbroadcast(ip_current_dest_addr(), netif)) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#if LWIP_AUTOIP + /* connections to link-local addresses must persist after changing + the netif's address (RFC3927 ch. 1.9) */ + if ((netif->autoip != NULL) && + ip_addr_cmp(ip_current_dest_addr(), &(netif->autoip->llipaddr))) { + LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* break out of for loop */ + break; + } +#endif /* LWIP_AUTOIP */ + } + if (first) { + first = 0; + netif = netif_list; + } else { + netif = netif->next; + } + if (netif == inp) { + netif = netif->next; + } + } while(netif != NULL); + } + +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed + * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. + * According to RFC 1542 section 3.1.1, referred by RFC 2131). + * + * If you want to accept private broadcast communication while a netif is down, + * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: + * + * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) + */ + if (netif == NULL) { + /* remote port is DHCP server? */ + if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { + struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n", + ntohs(udphdr->dest))); + if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n")); + netif = inp; + check_ip_src = 0; + } + } + } +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ +#if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING + if (check_ip_src +#if IP_ACCEPT_LINK_LAYER_ADDRESSING + /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ + && !ip_addr_isany(ip_current_src_addr()) +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + ) +#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */ + { if ((ip_addr_isbroadcast(ip_current_src_addr(), inp)) || + (ip_addr_ismulticast(ip_current_src_addr()))) { + /* packet source is not valid */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n")); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP_STATS_INC(ip.drop); + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + return ERR_OK; + } + } + + /* packet not for us? */ + if (netif == NULL) { + /* packet not for us, route or discard */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n")); +#if IP_FORWARD + /* non-broadcast packet? */ + if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp)) { + /* try to forward IP packet on (other) interfaces */ + ip_forward(p, iphdr, inp); + } else +#endif /* IP_FORWARD */ + { + snmp_inc_ipinaddrerrors(); + snmp_inc_ipindiscards(); + } + pbuf_free(p); + return ERR_OK; + } + /* packet consists of multiple fragments? */ + if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { +#if IP_REASSEMBLY /* packet fragment reassembly code present? */ + LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n", + ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)); + /* reassemble the packet*/ + p = ip_reass(p); + /* packet not fully reassembled yet? */ + if (p == NULL) { + return ERR_OK; + } + iphdr = (struct ip_hdr *)p->payload; +#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ + pbuf_free(p); + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", + ntohs(IPH_OFFSET(iphdr)))); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; +#endif /* IP_REASSEMBLY */ + } + +#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ + +#if LWIP_IGMP + /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ + if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { +#else + if (iphdr_hlen > IP_HLEN) { +#endif /* LWIP_IGMP */ + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); + pbuf_free(p); + IP_STATS_INC(ip.opterr); + IP_STATS_INC(ip.drop); + /* unsupported protocol feature */ + snmp_inc_ipinunknownprotos(); + return ERR_OK; + } +#endif /* IP_OPTIONS_ALLOWED == 0 */ + + /* send to upper layers */ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); + ip_debug_print(p); + LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + + ip_data.current_netif = inp; + ip_data.current_ip4_header = iphdr; + ip_data.current_ip_header_tot_len = IPH_HL(iphdr) * 4; + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) +#endif /* LWIP_RAW */ + { + pbuf_header(p, -(s16_t)iphdr_hlen); /* Move to payload, no check necessary. */ + + switch (IPH_PROTO(iphdr)) { +#if LWIP_UDP + case IP_PROTO_UDP: +#if LWIP_UDPLITE + case IP_PROTO_UDPLITE: +#endif /* LWIP_UDPLITE */ + snmp_inc_ipindelivers(); + udp_input(p, inp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP_PROTO_TCP: + snmp_inc_ipindelivers(); + tcp_input(p, inp); + break; +#endif /* LWIP_TCP */ +#if LWIP_ICMP + case IP_PROTO_ICMP: + snmp_inc_ipindelivers(); + icmp_input(p, inp); + break; +#endif /* LWIP_ICMP */ +#if LWIP_IGMP + case IP_PROTO_IGMP: + igmp_input(p, inp, ip_current_dest_addr()); + break; +#endif /* LWIP_IGMP */ + default: +#if LWIP_ICMP + /* send ICMP destination protocol unreachable unless is was a broadcast */ + if (!ip_addr_isbroadcast(ip_current_dest_addr(), inp) && + !ip_addr_ismulticast(ip_current_dest_addr())) { + pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */ + p->payload = iphdr; + icmp_dest_unreach(p, ICMP_DUR_PROTO); + } +#endif /* LWIP_ICMP */ + pbuf_free(p); + + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr))); + + IP_STATS_INC(ip.proterr); + IP_STATS_INC(ip.drop); + snmp_inc_ipinunknownprotos(); + } + } + + /* @todo: this is not really necessary... */ + ip_data.current_netif = NULL; + ip_data.current_ip4_header = NULL; + ip_data.current_ip_header_tot_len = 0; + ip_addr_set_any(ip_current_src_addr()); + ip_addr_set_any(ip_current_dest_addr()); + + return ERR_OK; +} + +/** + * Sends an IP packet on a network interface. This function constructs + * the IP header and calculates the IP header checksum. If the source + * IP address is NULL, the IP address of the outgoing network + * interface is filled in as source address. + * If the destination IP address is IP_HDRINCL, p is assumed to already + * include an IP header and p->payload points to it instead of the data. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IP/LINK headers + * returns errors returned by netif->output + * + * @note ip_id: RFC791 "some host may be able to simply use + * unique identifiers independent of destination" + */ +err_t +ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ +#if IP_OPTIONS_SEND + return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); +} + +/** + * Same as ip_output_if() but with the possibility to include IP options: + * + * @ param ip_options pointer to the IP options, copied into the IP header + * @ param optlen length of ip_options + */ +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen) +{ +#endif /* IP_OPTIONS_SEND */ + ip_addr_t *src_used = src; + if (dest != IP_HDRINCL) { + if (ip_addr_isany(src)) { + src_used = &netif->ip_addr; + } + } + +#if IP_OPTIONS_SEND + return ip_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, + ip_options, optlen); +#else /* IP_OPTIONS_SEND */ + return ip_output_if_src(p, src_used, dest, ttl, tos, proto, netif); +#endif /* IP_OPTIONS_SEND */ +} + +/** + * Same as ip_output_if() but 'src' address is not replaced by netif address + * when it is 'any'. + */ +err_t +ip_output_if_src(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, + u8_t proto, struct netif *netif) +{ +#if IP_OPTIONS_SEND + return ip_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0); +} + +/** + * Same as ip_output_if_opt() but 'src' address is not replaced by netif address + * when it is 'any'. + */ +err_t ip_output_if_opt_src(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen) +{ +#endif /* IP_OPTIONS_SEND */ + struct ip_hdr *iphdr; + ip_addr_t dest_addr; +#if CHECKSUM_GEN_IP_INLINE + u32_t chk_sum = 0; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + snmp_inc_ipoutrequests(); + + /* Should the IP header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + u16_t ip_hlen = IP_HLEN; +#if IP_OPTIONS_SEND + u16_t optlen_aligned = 0; + if (optlen != 0) { +#if CHECKSUM_GEN_IP_INLINE + int i; +#endif /* CHECKSUM_GEN_IP_INLINE */ + /* round up to a multiple of 4 */ + optlen_aligned = ((optlen + 3) & ~3); + ip_hlen += optlen_aligned; + /* First write in the IP options */ + if (pbuf_header(p, optlen_aligned)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n")); + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + MEMCPY(p->payload, ip_options, optlen); + if (optlen < optlen_aligned) { + /* zero the remaining bytes */ + memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); + } +#if CHECKSUM_GEN_IP_INLINE + for (i = 0; i < optlen_aligned/2; i++) { + chk_sum += ((u16_t*)p->payload)[i]; + } +#endif /* CHECKSUM_GEN_IP_INLINE */ + } +#endif /* IP_OPTIONS_SEND */ + /* generate IP header */ + if (pbuf_header(p, IP_HLEN)) { + LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n")); + + IP_STATS_INC(ip.err); + snmp_inc_ipoutdiscards(); + return ERR_BUF; + } + + iphdr = (struct ip_hdr *)p->payload; + LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", + (p->len >= sizeof(struct ip_hdr))); + + IPH_TTL_SET(iphdr, ttl); + IPH_PROTO_SET(iphdr, proto); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(proto, ttl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + + /* dest cannot be NULL here */ + ip_addr_copy(iphdr->dest, *dest); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; +#endif /* CHECKSUM_GEN_IP_INLINE */ + + IPH_VHL_SET(iphdr, 4, ip_hlen / 4); + IPH_TOS_SET(iphdr, tos); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl); +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_LEN_SET(iphdr, htons(p->tot_len)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_len; +#endif /* CHECKSUM_GEN_IP_INLINE */ + IPH_OFFSET_SET(iphdr, 0); + IPH_ID_SET(iphdr, htons(ip_id)); +#if CHECKSUM_GEN_IP_INLINE + chk_sum += iphdr->_id; +#endif /* CHECKSUM_GEN_IP_INLINE */ + ++ip_id; + + if (src == NULL) { + ip_addr_copy(iphdr->src, ip_addr_any); + } else { + /* src cannot be NULL here */ + ip_addr_copy(iphdr->src, *src); + } + +#if CHECKSUM_GEN_IP_INLINE + chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; + chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; + chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); + chk_sum = (chk_sum >> 16) + chk_sum; + chk_sum = ~chk_sum; + iphdr->_chksum = chk_sum; /* network order */ +#else /* CHECKSUM_GEN_IP_INLINE */ + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); +#endif +#endif /* CHECKSUM_GEN_IP_INLINE */ + } else { + /* IP header already included in p */ + iphdr = (struct ip_hdr *)p->payload; + ip_addr_copy(dest_addr, iphdr->dest); + dest = &dest_addr; + } + + IP_STATS_INC(ip.xmit); + + LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); + ip_debug_print(p); + +#if ENABLE_LOOPBACK + if (ip_addr_cmp(dest, &netif->ip_addr)) { + /* Packet to self, enqueue it for loopback */ + LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); + return netif_loop_output(netif, p); + } +#if LWIP_IGMP + if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { + netif_loop_output(netif, p); + } +#endif /* LWIP_IGMP */ +#endif /* ENABLE_LOOPBACK */ +#if IP_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > netif->mtu)) { + return ip_frag(p, netif, dest); + } +#endif /* IP_FRAG */ + + LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); + return netif->output(netif, p, dest); +} + +/** + * Simple interface to ip_output_if. It finds the outgoing network + * interface and calls upon ip_output_if to do the actual work. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto) +{ + struct netif *netif; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + return ip_output_if(p, src, dest, ttl, tos, proto, netif); +} + +#if LWIP_NETIF_HWADDRHINT +/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint + * before calling ip_output_if. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an IP + header and p->payload points to that IP header) + * @param src the source IP address to send from (if src == IP_ADDR_ANY, the + * IP address of the netif used to send is used as source address) + * @param dest the destination IP address to send the packet to + * @param ttl the TTL value to be set in the IP header + * @param tos the TOS value to be set in the IP header + * @param proto the PROTOCOL to be set in the IP header + * @param addr_hint address hint pointer set to netif->addr_hint before + * calling ip_output_if() + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) +{ + struct netif *netif; + err_t err; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + if ((netif = ip_route(dest)) == NULL) { + LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); + IP_STATS_INC(ip.rterr); + return ERR_RTE; + } + + NETIF_SET_HWADDRHINT(netif, addr_hint); + err = ip_output_if(p, src, dest, ttl, tos, proto, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if IP_DEBUG +/* Print an IP header by using LWIP_DEBUGF + * @param p an IP packet, p->payload pointing to the IP header + */ +void +ip_debug_print(struct pbuf *p) +{ + struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; + + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", + IPH_V(iphdr), + IPH_HL(iphdr), + IPH_TOS(iphdr), + ntohs(IPH_LEN(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", + ntohs(IPH_ID(iphdr)), + ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, + ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, + ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", + IPH_TTL(iphdr), + IPH_PROTO(iphdr), + ntohs(IPH_CHKSUM(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", + ip4_addr1_16(&iphdr->src), + ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), + ip4_addr4_16(&iphdr->src))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", + ip4_addr1_16(&iphdr->dest), + ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), + ip4_addr4_16(&iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP_DEBUG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4_addr.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4_addr.c new file mode 100644 index 0000000..3836f27 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip4_addr.c @@ -0,0 +1,312 @@ +/** + * @file + * This is the IPv4 address tools implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ +const ip_addr_t ip_addr_any = { IPADDR_ANY }; +const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST }; + +/** + * Determine if an address is a broadcast address on a network interface + * + * @param addr address to be checked + * @param netif the network interface against which the address is checked + * @return returns non-zero if the address is a broadcast address + */ +u8_t +ip4_addr_isbroadcast(u32_t addr, const struct netif *netif) +{ + ip_addr_t ipaddr; + ip4_addr_set_u32(&ipaddr, addr); + + /* all ones (broadcast) or all zeroes (old skool broadcast) */ + if ((~addr == IPADDR_ANY) || + (addr == IPADDR_ANY)) { + return 1; + /* no broadcast support on this network interface? */ + } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { + /* the given address cannot be a broadcast address + * nor can we check against any broadcast addresses */ + return 0; + /* address matches network interface address exactly? => no broadcast */ + } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) { + return 0; + /* on the same (sub) network... */ + } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask)) + /* ...and host identifier bits are all ones? =>... */ + && ((addr & ~ip4_addr_get_u32(&netif->netmask)) == + (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) { + /* => network broadcast address */ + return 1; + } else { + return 0; + } +} + +/** Checks if a netmask is valid (starting with ones, then only zeros) + * + * @param netmask the IPv4 netmask to check (in network byte order!) + * @return 1 if the netmask is valid, 0 if it is not + */ +u8_t +ip4_addr_netmask_valid(u32_t netmask) +{ + u32_t mask; + u32_t nm_hostorder = lwip_htonl(netmask); + + /* first, check for the first zero */ + for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) == 0) { + break; + } + } + /* then check that there is no one */ + for (; mask != 0; mask >>= 1) { + if ((nm_hostorder & mask) != 0) { + /* there is a one after the first zero -> invalid */ + return 0; + } + } + /* no one after the first zero -> valid */ + return 1; +} + +/* Here for now until needed in other places in lwIP */ +#ifndef isprint +#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#endif + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IP address in ascii representation (e.g. "127.0.0.1") + * @return ip address in network order + */ +u32_t +ipaddr_addr(const char *cp) +{ + ip_addr_t val; + + if (ipaddr_aton(cp, &val)) { + return ip4_addr_get_u32(&val); + } + return (IPADDR_NONE); +} + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + * + * @param cp IP address in ascii representation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +ipaddr_aton(const char *cp, ip_addr_t *addr) +{ + u32_t val; + u8_t base; + char c; + u32_t parts[4]; + u32_t *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; + base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') { + base = 16; + c = *++cp; + } else + base = 8; + } + for (;;) { + if (isdigit(c)) { + val = (val * base) + (int)(c - '0'); + c = *++cp; + } else if (base == 16 && isxdigit(c)) { + val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) { + return (0); + } + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) { + return (0); + } + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) { + return (0); + } + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) { + return (0); + } + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + default: + LWIP_ASSERT("unhandled", 0); + break; + } + if (addr) { + ip4_addr_set_u32(addr, htonl(val)); + } + return (1); +} + +/** + * Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * representation of addr + */ +char * +ipaddr_ntoa(const ip_addr_t *addr) +{ + static char str[16]; + return ipaddr_ntoa_r(addr, str, 16); +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen) +{ + u32_t s_addr; + char inv[3]; + char *rp; + u8_t *ap; + u8_t rem; + u8_t n; + u8_t i; + int len = 0; + + s_addr = ip4_addr_get_u32(addr); + + rp = buf; + ap = (u8_t *)&s_addr; + for(n = 0; n < 4; n++) { + i = 0; + do { + rem = *ap % (u8_t)10; + *ap /= (u8_t)10; + inv[i++] = '0' + rem; + } while(*ap); + while(i--) { + if (len++ >= buflen) { + return NULL; + } + *rp++ = inv[i]; + } + if (len++ >= buflen) { + return NULL; + } + *rp++ = '.'; + ap++; + } + *--rp = 0; + return buf; +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip_frag.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip_frag.c new file mode 100644 index 0000000..3450927 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv4/ip_frag.c @@ -0,0 +1,878 @@ +/** + * @file + * This is the IPv4 packet segmentation and reassembly implementation. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * Simon Goldschmidt + * original reassembly code by Adam Dunkels + * + */ + +#include "lwip/opt.h" +#include "lwip/ip_frag.h" +#include "lwip/def.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/stats.h" +#include "lwip/icmp.h" + +#include + +#if IP_REASSEMBLY +/** + * The IP reassembly code currently has the following limitations: + * - IP header options are not supported + * - fragments must not overlap (e.g. due to different routes), + * currently, overlapping or duplicate fragments are thrown away + * if IP_REASS_CHECK_OVERLAP=1 (the default)! + * + * @todo: work with IP header options + */ + +/** Setting this to 0, you can turn off checking the fragments for overlapping + * regions. The code gets a little smaller. Only use this if you know that + * overlapping won't occur on your network! */ +#ifndef IP_REASS_CHECK_OVERLAP +#define IP_REASS_CHECK_OVERLAP 1 +#endif /* IP_REASS_CHECK_OVERLAP */ + +/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is + * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. + * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA + * is set to 1, so one datagram can be reassembled at a time, only. */ +#ifndef IP_REASS_FREE_OLDEST +#define IP_REASS_FREE_OLDEST 1 +#endif /* IP_REASS_FREE_OLDEST */ + +#define IP_REASS_FLAG_LASTFRAG 0x01 + +/** This is a helper struct which holds the starting + * offset and the ending offset of this fragment to + * easily chain the fragments. + * It has the same packing requirements as the IP header, since it replaces + * the IP header in memory in incoming fragments (after copying it) to keep + * track of the various fragments. (-> If the IP header doesn't need packing, + * this struct doesn't need packing, too.) + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_reass_helper { + PACK_STRUCT_FIELD(struct pbuf *next_pbuf); + PACK_STRUCT_FIELD(u16_t start); + PACK_STRUCT_FIELD(u16_t end); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ + (ip_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ + ip_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ + IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 + +/* global variables */ +static struct ip_reassdata *reassdatagrams; +static u16_t ip_reass_pbufcount; + +/* function prototypes */ +static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); +static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); + +/** + * Reassembly timer base function + * for both NO_SYS == 0 and 1 (!). + * + * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). + */ +void +ip_reass_tmr(void) +{ + struct ip_reassdata *r, *prev = NULL; + + r = reassdatagrams; + while (r != NULL) { + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + r->timer--; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); + prev = r; + r = r->next; + } else { + /* reassembly timed out */ + struct ip_reassdata *tmp; + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); + tmp = r; + /* get the next pointer before freeing */ + r = r->next; + /* free the helper struct and all enqueued pbufs */ + ip_reass_free_complete_datagram(tmp, prev); + } + } +} + +/** + * Free a datagram (struct ip_reassdata) and all its pbufs. + * Updates the total count of enqueued pbufs (ip_reass_pbufcount), + * SNMP counters and sends an ICMP time exceeded packet. + * + * @param ipr datagram to free + * @param prev the previous datagram in the linked list + * @return the number of pbufs freed + */ +static int +ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + u16_t pbufs_freed = 0; + u8_t clen; + struct pbuf *p; + struct ip_reass_helper *iprh; + + LWIP_ASSERT("prev != ipr", prev != ipr); + if (prev != NULL) { + LWIP_ASSERT("prev->next == ipr", prev->next == ipr); + } + + snmp_inc_ipreasmfails(); +#if LWIP_ICMP + iprh = (struct ip_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, copy the original header into it. */ + SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); + icmp_time_exceeded(p, ICMP_TE_FRAG); + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(p); + } +#endif /* LWIP_ICMP */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + while (p != NULL) { + struct pbuf *pcur; + iprh = (struct ip_reass_helper *)p->payload; + pcur = p; + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + clen = pbuf_clen(pcur); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(pcur); + } + /* Then, unchain the struct ip_reassdata from the list and free it. */ + ip_reass_dequeue_datagram(ipr, prev); + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); + ip_reass_pbufcount -= pbufs_freed; + + return pbufs_freed; +} + +#if IP_REASS_FREE_OLDEST +/** + * Free the oldest datagram to make room for enqueueing new fragments. + * The datagram 'fraghdr' belongs to is not freed! + * + * @param fraghdr IP header of the current fragment + * @param pbufs_needed number of pbufs needed to enqueue + * (used for freeing other datagrams if not enough space) + * @return the number of pbufs freed + */ +static int +ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) +{ + /* @todo Can't we simply remove the last datagram in the + * linked list behind reassdatagrams? + */ + struct ip_reassdata *r, *oldest, *prev; + int pbufs_freed = 0, pbufs_freed_current; + int other_datagrams; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the datagram that 'fraghdr' belongs to! */ + do { + oldest = NULL; + prev = NULL; + other_datagrams = 0; + r = reassdatagrams; + while (r != NULL) { + if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { + /* Not the same datagram as fraghdr */ + other_datagrams++; + if (oldest == NULL) { + oldest = r; + } else if (r->timer <= oldest->timer) { + /* older than the previous oldest */ + oldest = r; + } + } + if (r->next != NULL) { + prev = r; + } + r = r->next; + } + if (oldest != NULL) { + pbufs_freed_current = ip_reass_free_complete_datagram(oldest, prev); + pbufs_freed += pbufs_freed_current; + } + } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); + return pbufs_freed; +} +#endif /* IP_REASS_FREE_OLDEST */ + +/** + * Enqueues a new fragment into the fragment queue + * @param fraghdr points to the new fragments IP hdr + * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) + * @return A pointer to the queue location into which the fragment was enqueued + */ +static struct ip_reassdata* +ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) +{ + struct ip_reassdata* ipr; + /* No matching previous fragment found, allocate a new reassdata struct */ + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + if (ipr == NULL) { +#if IP_REASS_FREE_OLDEST + if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { + ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); + } + if (ipr == NULL) +#endif /* IP_REASS_FREE_OLDEST */ + { + IPFRAG_STATS_INC(ip_frag.memerr); + LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); + return NULL; + } + } + memset(ipr, 0, sizeof(struct ip_reassdata)); + ipr->timer = IP_REASS_MAXAGE; + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + reassdatagrams = ipr; + /* copy the ip header for later tests and input */ + /* @todo: no ip options supported? */ + SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); + return ipr; +} + +/** + * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. + * @param ipr points to the queue entry to dequeue + */ +static void +ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) +{ + + /* dequeue the reass struct */ + if (reassdatagrams == ipr) { + /* it was the first in the list */ + reassdatagrams = ipr->next; + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", prev != NULL); + prev->next = ipr->next; + } + + /* now we can free the ip_reass struct */ + memp_free(MEMP_REASSDATA, ipr); +} + +/** + * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list + * will grow over time as new pbufs are rx. + * Also checks that the datagram passes basic continuity checks (if the last + * fragment was received at least once). + * @param root_p points to the 'root' pbuf for the current datagram being assembled. + * @param new_p points to the pbuf for the current fragment + * @return 0 if invalid, >0 otherwise + */ +static int +ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p) +{ + struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + struct pbuf *q; + u16_t offset,len; + struct ip_hdr *fraghdr; + int valid = 1; + + /* Extract length and fragment offset from current fragment */ + fraghdr = (struct ip_hdr*)new_p->payload; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + + /* overwrite the fragment's ip header from the pbuf with our helper struct, + * and setup the embedded helper structure. */ + /* make sure the struct ip_reass_helper fits into the IP header */ + LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", + sizeof(struct ip_reass_helper) <= IP_HLEN); + iprh = (struct ip_reass_helper*)new_p->payload; + iprh->next_pbuf = NULL; + iprh->start = offset; + iprh->end = offset + len; + + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + iprh_tmp = (struct ip_reass_helper*)q->payload; + if (iprh->start < iprh_tmp->start) { + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + if (iprh_prev != NULL) { + /* not the fragment with the lowest offset */ +#if IP_REASS_CHECK_OVERLAP + if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { + /* fragment overlaps with previous or following, throw away */ + goto freepbuf; + } +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + } else { + /* fragment with the lowest offset */ + ipr->p = new_p; + } + break; + } else if(iprh->start == iprh_tmp->start) { + /* received the same datagram twice: no need to keep the datagram */ + goto freepbuf; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + /* overlap: no need to keep the new datagram */ + goto freepbuf; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no wholes. */ + if (iprh_prev != NULL) { + if (iprh_prev->end != iprh_tmp->start) { + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + } + } + } + q = iprh_tmp->next_pbuf; + iprh_prev = iprh_tmp; + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + if (iprh_prev != NULL) { + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = new_p; + if (iprh_prev->end != iprh->start) { + valid = 0; + } + } else { +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = new_p; + } + } + + /* At this point, the validation part begins: */ + /* If we already received the last fragment */ + if ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0) { + /* and had no wholes so far */ + if (valid) { + /* then check if the rest of the fragments is here */ + /* Check if the queue starts with the first datagram */ + if ((ipr->p == NULL) || (((struct ip_reass_helper*)ipr->p->payload)->start != 0)) { + valid = 0; + } else { + /* and check that there are no wholes after this datagram */ + iprh_prev = iprh; + q = iprh->next_pbuf; + while (q != NULL) { + iprh = (struct ip_reass_helper*)q->payload; + if (iprh_prev->end != iprh->start) { + valid = 0; + break; + } + iprh_prev = iprh; + q = iprh->next_pbuf; + } + /* if still valid, all fragments are received + * (because to the MF==0 already arrived */ + if (valid) { + LWIP_ASSERT("sanity check", ipr->p != NULL); + LWIP_ASSERT("sanity check", + ((struct ip_reass_helper*)ipr->p->payload) != iprh); + LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", + iprh->next_pbuf == NULL); + LWIP_ASSERT("validate_datagram:datagram end!=datagram len", + iprh->end == ipr->datagram_len); + } + } + } + /* If valid is 0 here, there are some fragments missing in the middle + * (since MF == 0 has already arrived). Such datagrams simply time out if + * no more fragments are received... */ + return valid; + } + /* If we come here, not all fragments were received, yet! */ + return 0; /* not yet valid! */ +#if IP_REASS_CHECK_OVERLAP +freepbuf: + ip_reass_pbufcount -= pbuf_clen(new_p); + pbuf_free(new_p); + return 0; +#endif /* IP_REASS_CHECK_OVERLAP */ +} + +/** + * Reassembles incoming IP fragments into an IP datagram. + * + * @param p points to a pbuf chain of the fragment + * @return NULL if reassembly is incomplete, ? otherwise + */ +struct pbuf * +ip_reass(struct pbuf *p) +{ + struct pbuf *r; + struct ip_hdr *fraghdr; + struct ip_reassdata *ipr; + struct ip_reass_helper *iprh; + u16_t offset, len; + u8_t clen; + + IPFRAG_STATS_INC(ip_frag.recv); + snmp_inc_ipreasmreqds(); + + fraghdr = (struct ip_hdr*)p->payload; + + if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: IP options currently not supported!\n")); + IPFRAG_STATS_INC(ip_frag.err); + goto nullreturn; + } + + offset = (ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; + len = ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; + + /* Check if we are allowed to enqueue more datagrams. */ + clen = pbuf_clen(p); + if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { +#if IP_REASS_FREE_OLDEST + if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || + ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) +#endif /* IP_REASS_FREE_OLDEST */ + { + /* No datagram could be freed and still too many pbufs enqueued */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", + ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); + IPFRAG_STATS_INC(ip_frag.memerr); + /* @todo: send ICMP time exceeded here? */ + /* drop this pbuf */ + goto nullreturn; + } + } + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass: matching previous fragment ID=%"X16_F"\n", + ntohs(IPH_ID(fraghdr)))); + IPFRAG_STATS_INC(ip_frag.cachehit); + break; + } + } + + if (ipr == NULL) { + /* Enqueue a new datagram into the datagram queue */ + ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); + /* Bail if unable to enqueue */ + if(ipr == NULL) { + goto nullreturn; + } + } else { + if (((ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && + ((ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { + /* ipr->iphdr is not the header from the first fragment, but fraghdr is + * -> copy fraghdr into ipr->iphdr since we want to have the header + * of the first fragment (for ICMP time exceeded and later, for copying + * all options, if supported)*/ + SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); + } + } + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip_reass_pbufcount += clen; + + /* At this point, we have either created a new entry or pointing + * to an existing one */ + + /* check for 'no more fragments', and update queue entry*/ + if ((IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0) { + ipr->flags |= IP_REASS_FLAG_LASTFRAG; + ipr->datagram_len = offset + len; + LWIP_DEBUGF(IP_REASS_DEBUG, + ("ip_reass: last fragment seen, total len %"S16_F"\n", + ipr->datagram_len)); + } + /* find the right place to insert this pbuf */ + /* @todo: trim pbufs if fragments are overlapping */ + if (ip_reass_chain_frag_into_datagram_and_validate(ipr, p)) { + struct ip_reassdata *ipr_prev; + /* the totally last fragment (flag more fragments = 0) was received at least + * once AND all fragments are received */ + ipr->datagram_len += IP_HLEN; + + /* save the second pbuf before copying the header over the pointer */ + r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; + + /* copy the original ip header back to the first pbuf */ + fraghdr = (struct ip_hdr*)(ipr->p->payload); + SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); + IPH_LEN_SET(fraghdr, htons(ipr->datagram_len)); + IPH_OFFSET_SET(fraghdr, 0); + IPH_CHKSUM_SET(fraghdr, 0); + /* @todo: do we need to set calculate the correct checksum? */ +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + + p = ipr->p; + + /* chain together the pbufs contained within the reass_data list. */ + while(r != NULL) { + iprh = (struct ip_reass_helper*)r->payload; + + /* hide the ip header for every succeeding fragment */ + pbuf_header(r, -IP_HLEN); + pbuf_cat(p, r); + r = iprh->next_pbuf; + } + + /* find the previous entry in the linked list */ + if (ipr == reassdatagrams) { + ipr_prev = NULL; + } else { + for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { + if (ipr_prev->next == ipr) { + break; + } + } + } + + /* release the sources allocate for the fragment queue entry */ + ip_reass_dequeue_datagram(ipr, ipr_prev); + + /* and adjust the number of pbufs currently queued for reassembly. */ + ip_reass_pbufcount -= pbuf_clen(p); + + /* Return the pbuf chain */ + return p; + } + /* the datagram is not (yet?) reassembled completely */ + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); + return NULL; + +nullreturn: + LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass: nullreturn\n")); + IPFRAG_STATS_INC(ip_frag.drop); + pbuf_free(p); + return NULL; +} +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if IP_FRAG_USES_STATIC_BUF +static u8_t buf[LWIP_MEM_ALIGN_SIZE(IP_FRAG_MAX_MTU + MEM_ALIGNMENT - 1)]; +#else /* IP_FRAG_USES_STATIC_BUF */ + +#if !LWIP_NETIF_TX_SINGLE_PBUF +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip_frag_alloc_pbuf_custom_ref(void) +{ + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); +} + +/** Free a struct pbuf_custom_ref */ +static void +ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); +} + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ipfrag_free_pbuf_custom(struct pbuf *p) +{ + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + pbuf_free(pcr->original); + } + ip_frag_free_pbuf_custom_ref(pcr); +} +#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + +/** + * Fragment an IP datagram if too large for the netif. + * + * Chop the datagram in MTU sized chunks and send them in order + * by using a fixed size static memory buffer (PBUF_REF) or + * point PBUF_REFs into p (depending on IP_FRAG_USES_STATIC_BUF). + * + * @param p ip packet to send + * @param netif the netif on which to send + * @param dest destination ip address to which to send + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest) +{ + struct pbuf *rambuf; +#if IP_FRAG_USES_STATIC_BUF + struct pbuf *header; +#else +#if !LWIP_NETIF_TX_SINGLE_PBUF + struct pbuf *newpbuf; +#endif + struct ip_hdr *original_iphdr; +#endif + struct ip_hdr *iphdr; + u16_t nfb; + u16_t left, cop; + u16_t mtu = netif->mtu; + u16_t ofo, omf; + u16_t last; + u16_t poff = IP_HLEN; + u16_t tmp; +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF + u16_t newpbuflen = 0; + u16_t left_to_copy; +#endif + + /* Get a RAM based MTU sized pbuf */ +#if IP_FRAG_USES_STATIC_BUF + /* When using a static buffer, we use a PBUF_REF, which we will + * use to reference the packet (without link header). + * Layer and length is irrelevant. + */ + rambuf = pbuf_alloc(PBUF_LINK, 0, PBUF_REF); + if (rambuf == NULL) { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc(PBUF_LINK, 0, PBUF_REF) failed\n")); + return ERR_MEM; + } + rambuf->tot_len = rambuf->len = mtu; + rambuf->payload = LWIP_MEM_ALIGN((void *)buf); + + /* Copy the IP header in it */ + iphdr = (struct ip_hdr *)rambuf->payload; + SMEMCPY(iphdr, p->payload, IP_HLEN); +#else /* IP_FRAG_USES_STATIC_BUF */ + original_iphdr = (struct ip_hdr *)p->payload; + iphdr = original_iphdr; +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Save original offset */ + tmp = ntohs(IPH_OFFSET(iphdr)); + ofo = tmp & IP_OFFMASK; + omf = tmp & IP_MF; + + left = p->tot_len - IP_HLEN; + + nfb = (mtu - IP_HLEN) / 8; + + while (left) { + last = (left <= mtu - IP_HLEN); + + /* Set new offset and MF flag */ + tmp = omf | (IP_OFFMASK & (ofo)); + if (!last) { + tmp = tmp | IP_MF; + } + + /* Fill this fragment */ + cop = last ? left : nfb * 8; + +#if IP_FRAG_USES_STATIC_BUF + poff += pbuf_copy_partial(p, (u8_t*)iphdr + IP_HLEN, cop, poff); +#else /* IP_FRAG_USES_STATIC_BUF */ +#if LWIP_NETIF_TX_SINGLE_PBUF + rambuf = pbuf_alloc(PBUF_IP, cop, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); + poff += pbuf_copy_partial(p, rambuf->payload, cop, poff); + /* make room for the IP header */ + if(pbuf_header(rambuf, IP_HLEN)) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* fill in the IP header */ + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = rambuf->payload; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link and IP header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); + if (rambuf == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP_HLEN))); + SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); + iphdr = (struct ip_hdr *)rambuf->payload; + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + p->len -= poff; + + left_to_copy = cop; + while (left_to_copy) { + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + /* Is this pbuf already empty? */ + if (!newpbuflen) { + p = p->next; + continue; + } + pcr = ip_frag_alloc_pbuf_custom_ref(); + if (pcr == NULL) { + pbuf_free(rambuf); + return ERR_MEM; + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + if (newpbuf == NULL) { + ip_frag_free_pbuf_custom_ref(pcr); + pbuf_free(rambuf); + return ERR_MEM; + } + pbuf_ref(p); + pcr->original = p; + pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + left_to_copy -= newpbuflen; + if (left_to_copy) { + p = p->next; + } + } + poff = newpbuflen; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ +#endif /* IP_FRAG_USES_STATIC_BUF */ + + /* Correct header */ + IPH_OFFSET_SET(iphdr, htons(tmp)); + IPH_LEN_SET(iphdr, htons(cop + IP_HLEN)); + IPH_CHKSUM_SET(iphdr, 0); +#if CHECKSUM_GEN_IP + IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); +#endif /* CHECKSUM_GEN_IP */ + +#if IP_FRAG_USES_STATIC_BUF + if (last) { + pbuf_realloc(rambuf, left + IP_HLEN); + } + + /* This part is ugly: we alloc a RAM based pbuf for + * the link level header for each chunk and then + * free it.A PBUF_ROM style pbuf for which pbuf_header + * worked would make things simpler. + */ + header = pbuf_alloc(PBUF_LINK, 0, PBUF_RAM); + if (header != NULL) { + pbuf_chain(header, rambuf); + netif->output(netif, header, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + snmp_inc_ipfragcreates(); + pbuf_free(header); + } else { + LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_frag: pbuf_alloc() for header failed\n")); + pbuf_free(rambuf); + return ERR_MEM; + } +#else /* IP_FRAG_USES_STATIC_BUF */ + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + netif->output(netif, rambuf, dest); + IPFRAG_STATS_INC(ip_frag.xmit); + + /* Unfortunately we can't reuse rambuf - the hardware may still be + * using the buffer. Instead we free it (and the ensuing chain) and + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + left -= cop; + ofo += nfb; + } +#if IP_FRAG_USES_STATIC_BUF + pbuf_free(rambuf); +#endif /* IP_FRAG_USES_STATIC_BUF */ + snmp_inc_ipfragoks(); + return ERR_OK; +} +#endif /* IP_FRAG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/README b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/README new file mode 100644 index 0000000..3620004 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/README @@ -0,0 +1 @@ +IPv6 support in lwIP is very experimental. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/dhcp6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/dhcp6.c new file mode 100644 index 0000000..9656c3b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/dhcp6.c @@ -0,0 +1,50 @@ +/** + * @file + * + * DHCPv6. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" + + +#endif /* LWIP_IPV6_DHCP6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ethip6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ethip6.c new file mode 100644 index 0000000..d9ac30f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ethip6.c @@ -0,0 +1,193 @@ +/** + * @file + * + * Ethernet output for IPv6. Uses ND tables for link-layer addressing. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_ETHERNET + +#include "lwip/ethip6.h" +#include "lwip/nd6.h" +#include "lwip/pbuf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp6.h" + +#include + +#define ETHTYPE_IPV6 0x86DD + +/** The ethernet address */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FLD_8(u8_t addr[6]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Ethernet header */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FLD_S(struct eth_addr dest); + PACK_STRUCT_FLD_S(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +/** + * Send an IPv6 packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +ethip6_send(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; + + LWIP_ASSERT("netif->hwaddr_len must be 6 for ethip6!", + (netif->hwaddr_len == 6)); + SMEMCPY(ðhdr->dest, dst, 6); + SMEMCPY(ðhdr->src, src, 6); + ethhdr->type = PP_HTONS(ETHTYPE_IPV6); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("ethip6_send: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} + +/** + * Resolve and fill-in Ethernet address header for outgoing IPv6 packet. + * + * For IPv6 multicast, corresponding Ethernet addresses + * are selected and the packet is transmitted on the link. + * + * For unicast addresses, ... + * + * @TODO anycast addresses + * + * @param netif The lwIP network interface which the IP packet will be sent on. + * @param q The pbuf(s) containing the IP packet to be sent. + * @param ip6addr The IP address of the packet destination. + * + * @return + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr) +{ + struct eth_addr dest; + s8_t i; + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + return ERR_BUF; + } + + /* multicast destination IP address? */ + if (ip6_addr_ismulticast(ip6addr)) { + /* Hash IP multicast address to MAC address.*/ + dest.addr[0] = 0x33; + dest.addr[1] = 0x33; + dest.addr[2] = ((u8_t *)(&(ip6addr->addr[3])))[0]; + dest.addr[3] = ((u8_t *)(&(ip6addr->addr[3])))[1]; + dest.addr[4] = ((u8_t *)(&(ip6addr->addr[3])))[2]; + dest.addr[5] = ((u8_t *)(&(ip6addr->addr[3])))[3]; + + /* Send out. */ + return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest); + } + + /* We have a unicast destination IP address */ + /* TODO anycast? */ + /* Get next hop record. */ + i = nd6_get_next_hop_entry(ip6addr, netif); + if (i < 0) { + /* failed to get a next hop neighbor record. */ + return ERR_MEM; + } + + /* Now that we have a destination record, send or queue the packet. */ + if (neighbor_cache[i].state == ND6_STALE) { + /* Switch to delay state. */ + neighbor_cache[i].state = ND6_DELAY; + neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; + } + /* TODO should we send or queue if PROBE? send for now, to let unicast NS pass. */ + if ((neighbor_cache[i].state == ND6_REACHABLE) || + (neighbor_cache[i].state == ND6_DELAY) || + (neighbor_cache[i].state == ND6_PROBE)) { + + /* Send out. */ + SMEMCPY(dest.addr, neighbor_cache[i].lladdr, 6); + return ethip6_send(netif, q, (struct eth_addr*)(netif->hwaddr), &dest); + } + + /* We should queue packet on this interface. */ + pbuf_header(q, -(s16_t)SIZEOF_ETH_HDR); + return nd6_queue_packet(i, q); +} + +#endif /* LWIP_IPV6 && LWIP_ETHERNET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/icmp6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/icmp6.c new file mode 100644 index 0000000..5cd1bbb --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/icmp6.c @@ -0,0 +1,342 @@ +/** + * @file + * + * IPv6 version of ICMP, as per RFC 4443. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/icmp6.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/nd6.h" +#include "lwip/mld6.h" +#include "lwip/lwip_ip.h" +#include "lwip/stats.h" + +#include + +#ifndef LWIP_ICMP6_DATASIZE +#define LWIP_ICMP6_DATASIZE 8 +#endif +#if LWIP_ICMP6_DATASIZE == 0 +#define LWIP_ICMP6_DATASIZE 8 +#endif + +/* Forward declarations */ +static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); + + +/** + * Process an input ICMPv6 message. Called by ip6_input. + * + * Will generate a reply for echo requests. Other messages are forwarded + * to nd6_input, or mld6_input. + * + * @param p the mld packet, p->payload pointing to the icmpv6 header + * @param inp the netif on which this packet was received + */ +void +icmp6_input(struct pbuf *p, struct netif *inp) +{ + struct icmp6_hdr *icmp6hdr; + struct pbuf * r; + ip6_addr_t * reply_src; + + ICMP6_STATS_INC(icmp6.recv); + + /* Check that ICMPv6 header fits in payload */ + if (p->len < sizeof(struct icmp6_hdr)) { + /* drop short packets */ + pbuf_free(p); + ICMP6_STATS_INC(icmp6.lenerr); + ICMP6_STATS_INC(icmp6.drop); + return; + } + + icmp6hdr = (struct icmp6_hdr *)p->payload; + +#if CHECKSUM_CHECK_ICMP6 + if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), + ip6_current_dest_addr()) != 0) { + /* Checksum failed */ + pbuf_free(p); + ICMP6_STATS_INC(icmp6.chkerr); + ICMP6_STATS_INC(icmp6.drop); + return; + } +#endif /* CHECKSUM_CHECK_ICMP6 */ + + switch (icmp6hdr->type) { + case ICMP6_TYPE_NA: /* Neighbor advertisement */ + case ICMP6_TYPE_NS: /* Neighbor solicitation */ + case ICMP6_TYPE_RA: /* Router advertisement */ + case ICMP6_TYPE_RD: /* Redirect */ + case ICMP6_TYPE_PTB: /* Packet too big */ + nd6_input(p, inp); + return; + break; + case ICMP6_TYPE_RS: +#if LWIP_IPV6_FORWARD + /* TODO implement router functionality */ +#endif + break; +#if LWIP_IPV6_MLD + case ICMP6_TYPE_MLQ: + case ICMP6_TYPE_MLR: + case ICMP6_TYPE_MLD: + mld6_input(p, inp); + return; + break; +#endif + case ICMP6_TYPE_EREQ: +#if !LWIP_MULTICAST_PING + /* multicast destination address? */ + if (ip6_addr_ismulticast(ip6_current_dest_addr())) { + /* drop */ + pbuf_free(p); + ICMP6_STATS_INC(icmp6.drop); + return; + } +#endif /* LWIP_MULTICAST_PING */ + + /* Allocate reply. */ + r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM); + if (r == NULL) { + /* drop */ + pbuf_free(p); + ICMP6_STATS_INC(icmp6.memerr); + return; + } + + /* Copy echo request. */ + if (pbuf_copy(r, p) != ERR_OK) { + /* drop */ + pbuf_free(p); + pbuf_free(r); + ICMP6_STATS_INC(icmp6.err); + return; + } + + /* Determine reply source IPv6 address. */ +#if LWIP_MULTICAST_PING + if (ip6_addr_ismulticast(ip6_current_dest_addr())) { + reply_src = ip6_select_source_address(inp, ip6_current_src_addr()); + if (reply_src == NULL) { + /* drop */ + pbuf_free(p); + pbuf_free(r); + ICMP6_STATS_INC(icmp6.rterr); + return; + } + } + else +#endif /* LWIP_MULTICAST_PING */ + { + reply_src = ip6_current_dest_addr(); + } + + /* Set fields in reply. */ + ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; + ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; +#if CHECKSUM_GEN_ICMP6 + ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, + IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); +#endif /* CHECKSUM_GEN_ICMP6 */ + + /* Send reply. */ + ICMP6_STATS_INC(icmp6.xmit); + ip6_output_if(r, reply_src, ip6_current_src_addr(), + LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp); + pbuf_free(r); + + break; + default: + ICMP6_STATS_INC(icmp6.proterr); + ICMP6_STATS_INC(icmp6.drop); + break; + } + + pbuf_free(p); +} + + +/** + * Send an icmpv6 'destination unreachable' packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IPv6 header + * @param c ICMPv6 code for the unreachable type + */ +void +icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) +{ + icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR); +} + +/** + * Send an icmpv6 'packet too big' packet. + * + * @param p the input packet for which the 'packet too big' should be sent, + * p->payload pointing to the IPv6 header + * @param mtu the maximum mtu that we can accept + */ +void +icmp6_packet_too_big(struct pbuf *p, u32_t mtu) +{ + icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB); +} + +/** + * Send an icmpv6 'time exceeded' packet. + * + * @param p the input packet for which the 'unreachable' should be sent, + * p->payload pointing to the IPv6 header + * @param c ICMPv6 code for the time exceeded type + */ +void +icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) +{ + icmp6_send_response(p, c, 0, ICMP6_TYPE_TE); +} + +/** + * Send an icmpv6 'parameter problem' packet. + * + * @param p the input packet for which the 'param problem' should be sent, + * p->payload pointing to the IP header + * @param c ICMPv6 code for the param problem type + * @param pointer the pointer to the byte where the parameter is found + */ +void +icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) +{ + icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP); +} + +/** + * Send an ICMPv6 packet in response to an incoming packet. + * + * @param p the input packet for which the response should be sent, + * p->payload pointing to the IPv6 header + * @param code Code of the ICMPv6 header + * @param data Additional 32-bit parameter in the ICMPv6 header + * @param type Type of the ICMPv6 header + */ +static void +icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) +{ + struct pbuf *q; + struct icmp6_hdr *icmp6hdr; + ip6_addr_t *reply_src, *reply_dest; + ip6_addr_t reply_src_local, reply_dest_local; + struct ip6_hdr *ip6hdr; + struct netif *netif; + + /* ICMPv6 header + IPv6 header + data */ + q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, + PBUF_RAM); + if (q == NULL) { + LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n")); + ICMP6_STATS_INC(icmp6.memerr); + return; + } + LWIP_ASSERT("check that first pbuf can hold icmp 6message", + (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE))); + + icmp6hdr = (struct icmp6_hdr *)q->payload; + icmp6hdr->type = type; + icmp6hdr->code = code; + icmp6hdr->data = data; + + /* copy fields from original packet */ + SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, + IP6_HLEN + LWIP_ICMP6_DATASIZE); + + /* Get the destination address and netif for this ICMP message. */ + if ((ip_current_netif() == NULL) || + ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) { + /* Special case, as ip6_current_xxx is either NULL, or points + * to a different packet than the one that expired. + * We must use the addresses that are stored in the expired packet. */ + ip6hdr = (struct ip6_hdr *)p->payload; + /* copy from packed address to aligned address */ + ip6_addr_copy(reply_dest_local, ip6hdr->src); + ip6_addr_copy(reply_src_local, ip6hdr->dest); + reply_dest = &reply_dest_local; + reply_src = &reply_src_local; + netif = ip6_route(reply_src, reply_dest); + if (netif == NULL) { + /* drop */ + pbuf_free(q); + ICMP6_STATS_INC(icmp6.rterr); + return; + } + } + else { + netif = ip_current_netif(); + reply_dest = ip6_current_src_addr(); + + /* Select an address to use as source. */ + reply_src = ip6_select_source_address(netif, reply_dest); + if (reply_src == NULL) { + /* drop */ + pbuf_free(q); + ICMP6_STATS_INC(icmp6.rterr); + return; + } + } + + /* calculate checksum */ + icmp6hdr->chksum = 0; +#if CHECKSUM_GEN_ICMP6 + icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, + reply_src, reply_dest); +#endif /* CHECKSUM_GEN_ICMP6 */ + + ICMP6_STATS_INC(icmp6.xmit); + ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); + pbuf_free(q); +} + +#endif /* LWIP_ICMP6 && LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/inet6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/inet6.c new file mode 100644 index 0000000..bdf4ff4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/inet6.c @@ -0,0 +1,51 @@ +/** + * @file + * + * INET v6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/inet6.h" + +/** @see ip6_addr.c for implementation of functions. */ + +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6.c new file mode 100644 index 0000000..854d746 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6.c @@ -0,0 +1,1045 @@ +/** + * @file + * + * IPv6 layer. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/ip6_frag.h" +#include "lwip/icmp6.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/tcp_impl.h" +#include "lwip/dhcp6.h" +#include "lwip/nd6.h" +#include "lwip/mld6.h" +#include "lwip/debug.h" +#include "lwip/stats.h" + + +/** + * Finds the appropriate network interface for a given IPv6 address. It tries to select + * a netif following a sequence of heuristics: + * 1) if there is only 1 netif, return it + * 2) if the destination is a link-local address, try to match the src address to a netif. + * this is a tricky case because with multiple netifs, link-local addresses only have + * meaning within a particular subnet/link. + * 3) tries to match the destination subnet to a configured address + * 4) tries to find a router + * 5) tries to match the source address to the netif + * 6) returns the default netif, if configured + * + * @param src the source IPv6 address, if known + * @param dest the destination IPv6 address for which to find the route + * @return the netif on which to send to reach dest + */ +struct netif * +ip6_route(struct ip6_addr *src, struct ip6_addr *dest) +{ + struct netif *netif; + s8_t i; + + /* If single netif configuration, fast return. */ + if ((netif_list != NULL) && (netif_list->next == NULL)) { + return netif_list; + } + + /* Special processing for link-local addresses. */ + if (ip6_addr_islinklocal(dest)) { + if (ip6_addr_isany(src)) { + /* Use default netif. */ + return netif_default; + } + + /* Try to find the netif for the source address. */ + for(netif = netif_list; netif != NULL; netif = netif->next) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { + return netif; + } + } + } + + /* netif not found, use default netif */ + return netif_default; + } + + /* See if the destination subnet matches a configured address. */ + for(netif = netif_list; netif != NULL; netif = netif->next) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { + return netif; + } + } + } + + /* Get the netif for a suitable router. */ + i = nd6_select_router(dest, NULL); + if (i >= 0) { + if (default_router_list[i].neighbor_entry != NULL) { + if (default_router_list[i].neighbor_entry->netif != NULL) { + return default_router_list[i].neighbor_entry->netif; + } + } + } + + /* try with the netif that matches the source address. */ + if (!ip6_addr_isany(src)) { + for(netif = netif_list; netif != NULL; netif = netif->next) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { + return netif; + } + } + } + } + + /* no matching netif found, use default netif */ + return netif_default; +} + +/** + * Select the best IPv6 source address for a given destination + * IPv6 address. Loosely follows RFC 3484. "Strong host" behavior + * is assumed. + * + * @param netif the netif on which to send a packet + * @param dest the destination we are trying to reach + * @return the most suitable source address to use, or NULL if no suitable + * source address is found + */ +ip6_addr_t * +ip6_select_source_address(struct netif *netif, ip6_addr_t * dest) +{ + ip6_addr_t * src = NULL; + u8_t i; + + /* If dest is link-local, choose a link-local source. */ + if (ip6_addr_islinklocal(dest) || ip6_addr_ismulticast_linklocal(dest) || ip6_addr_ismulticast_iflocal(dest)) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_islinklocal(netif_ip6_addr(netif, i))) { + return netif_ip6_addr(netif, i); + } + } + } + + /* Choose a site-local with matching prefix. */ + if (ip6_addr_issitelocal(dest) || ip6_addr_ismulticast_sitelocal(dest)) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_issitelocal(netif_ip6_addr(netif, i)) && + ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { + return netif_ip6_addr(netif, i); + } + } + } + + /* Choose a unique-local with matching prefix. */ + if (ip6_addr_isuniquelocal(dest) || ip6_addr_ismulticast_orglocal(dest)) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_isuniquelocal(netif_ip6_addr(netif, i)) && + ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { + return netif_ip6_addr(netif, i); + } + } + } + + /* Choose a global with best matching prefix. */ + if (ip6_addr_isglobal(dest) || ip6_addr_ismulticast_global(dest)) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_isglobal(netif_ip6_addr(netif, i))) { + if (src == NULL) { + src = netif_ip6_addr(netif, i); + } + else { + /* Replace src only if we find a prefix match. */ + /* TODO find longest matching prefix. */ + if ((!(ip6_addr_netcmp(src, dest))) && + ip6_addr_netcmp(netif_ip6_addr(netif, i), dest)) { + src = netif_ip6_addr(netif, i); + } + } + } + } + if (src != NULL) { + return src; + } + } + + /* Last resort: see if arbitrary prefix matches. */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_netcmp(dest, netif_ip6_addr(netif, i))) { + return netif_ip6_addr(netif, i); + } + } + + return NULL; +} + +#if LWIP_IPV6_FORWARD +/** + * Forwards an IPv6 packet. It finds an appropriate route for the + * packet, decrements the HL value of the packet, and outputs + * the packet on the appropriate interface. + * + * @param p the packet to forward (p->payload points to IP header) + * @param iphdr the IPv6 header of the input packet + * @param inp the netif on which this packet was received + */ +static void +ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) +{ + struct netif *netif; + + /* do not forward link-local addresses */ + if (ip6_addr_islinklocal(ip6_current_dest_addr())) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); + IP6_STATS_INC(ip6.rterr); + IP6_STATS_INC(ip6.drop); + return; + } + + /* Find network interface where to forward this IP packet to. */ + netif = ip6_route(IP6_ADDR_ANY, ip6_current_dest_addr()); + if (netif == NULL) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", + IP6_ADDR_BLOCK1(ip6_current_dest_addr()), + IP6_ADDR_BLOCK2(ip6_current_dest_addr()), + IP6_ADDR_BLOCK3(ip6_current_dest_addr()), + IP6_ADDR_BLOCK4(ip6_current_dest_addr()), + IP6_ADDR_BLOCK5(ip6_current_dest_addr()), + IP6_ADDR_BLOCK6(ip6_current_dest_addr()), + IP6_ADDR_BLOCK7(ip6_current_dest_addr()), + IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); +#if LWIP_ICMP6 + /* Don't send ICMP messages in response to ICMP messages */ + if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { + icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE); + } +#endif /* LWIP_ICMP6 */ + IP6_STATS_INC(ip6.rterr); + IP6_STATS_INC(ip6.drop); + return; + } + /* Do not forward packets onto the same network interface on which + * they arrived. */ + if (netif == inp) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n")); + IP6_STATS_INC(ip6.rterr); + IP6_STATS_INC(ip6.drop); + return; + } + + /* decrement HL */ + IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1); + /* send ICMP6 if HL == 0 */ + if (IP6H_HOPLIM(iphdr) == 0) { +#if LWIP_ICMP6 + /* Don't send ICMP messages in response to ICMP messages */ + if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { + icmp6_time_exceeded(p, ICMP6_TE_HL); + } +#endif /* LWIP_ICMP6 */ + IP6_STATS_INC(ip6.drop); + return; + } + + if (netif->mtu && (p->tot_len > netif->mtu)) { +#if LWIP_ICMP6 + /* Don't send ICMP messages in response to ICMP messages */ + if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { + icmp6_packet_too_big(p, netif->mtu); + } +#endif /* LWIP_ICMP6 */ + IP6_STATS_INC(ip6.drop); + return; + } + + LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", + IP6_ADDR_BLOCK1(ip6_current_dest_addr()), + IP6_ADDR_BLOCK2(ip6_current_dest_addr()), + IP6_ADDR_BLOCK3(ip6_current_dest_addr()), + IP6_ADDR_BLOCK4(ip6_current_dest_addr()), + IP6_ADDR_BLOCK5(ip6_current_dest_addr()), + IP6_ADDR_BLOCK6(ip6_current_dest_addr()), + IP6_ADDR_BLOCK7(ip6_current_dest_addr()), + IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); + + /* transmit pbuf on chosen interface */ + netif->output_ip6(netif, p, ip6_current_dest_addr()); + IP6_STATS_INC(ip6.fw); + IP6_STATS_INC(ip6.xmit); + return; +} +#endif /* LWIP_IPV6_FORWARD */ + + +/** + * This function is called by the network interface device driver when + * an IPv6 packet is received. The function does the basic checks of the + * IP header such as packet size being at least larger than the header + * size etc. If the packet was not destined for us, the packet is + * forwarded (using ip6_forward). + * + * Finally, the packet is sent to the upper layer protocol input function. + * + * @param p the received IPv6 packet (p->payload points to IPv6 header) + * @param inp the netif on which this packet was received + * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't + * processed, but currently always returns ERR_OK) + */ +err_t +ip6_input(struct pbuf *p, struct netif *inp) +{ + struct ip6_hdr *ip6hdr; + struct netif *netif; + u8_t nexth; + u16_t hlen; /* the current header length */ + u8_t i; +#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ + @todo + int check_ip_src=1; +#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ + + IP6_STATS_INC(ip6.recv); + + /* identify the IP header */ + ip6hdr = (struct ip6_hdr *)p->payload; + if (IP6H_V(ip6hdr) != 6) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", + IP6H_V(ip6hdr))); + pbuf_free(p); + IP6_STATS_INC(ip6.err); + IP6_STATS_INC(ip6.drop); + return ERR_OK; + } + + /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ + if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) { + if (IP6_HLEN > p->len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", + IP6_HLEN, p->len)); + } + if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", + IP6H_PLEN(ip6hdr) + IP6_HLEN, p->tot_len)); + } + /* free (drop) packet pbufs */ + pbuf_free(p); + IP6_STATS_INC(ip6.lenerr); + IP6_STATS_INC(ip6.drop); + return ERR_OK; + } + + /* Trim pbuf. This should have been done at the netif layer, + * but we'll do it anyway just to be sure that its done. */ + pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr)); + + /* copy IP addresses to aligned ip6_addr_t */ + ip6_addr_copy(ip_data.current_iphdr_dest.ip6, ip6hdr->dest); + ip6_addr_copy(ip_data.current_iphdr_src.ip6, ip6hdr->src); + + /* current header pointer. */ + ip_data.current_ip6_header = ip6hdr; + + /* In netif, used in case we need to send ICMPv6 packets back. */ + ip_data.current_netif = inp; + + /* match packet against an interface, i.e. is this packet for us? */ + if (ip6_addr_ismulticast(ip6_current_dest_addr())) { + /* Always joined to multicast if-local and link-local all-nodes group. */ + if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) || + ip6_addr_isallnodes_linklocal(ip6_current_dest_addr())) { + netif = inp; + } +#if LWIP_IPV6_MLD + else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) { + netif = inp; + } +#else /* LWIP_IPV6_MLD */ + else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { + /* Filter solicited node packets when MLD is not enabled + * (for Neighbor discovery). */ + netif = NULL; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && + ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { + netif = inp; + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + break; + } + } + } +#endif /* LWIP_IPV6_MLD */ + else { + netif = NULL; + } + } + else { + /* start trying with inp. if that's not acceptable, start walking the + list of configured netifs. + 'first' is used as a boolean to mark whether we started walking the list */ + int first = 1; + netif = inp; + do { + /* interface is up? */ + if (netif_is_up(netif)) { + /* unicast to this interface address? address configured? */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) { + /* exit outer loop */ + goto netif_found; + } + } + } + if (ip6_addr_islinklocal(ip6_current_dest_addr())) { + /* Do not match link-local addresses to other netifs. */ + netif = NULL; + break; + } + if (first) { + first = 0; + netif = netif_list; + } else { + netif = netif->next; + } + if (netif == inp) { + netif = netif->next; + } + } while(netif != NULL); +netif_found: + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", + netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); + } + + /* "::" packet source address? (used in duplicate address detection) */ + if (ip6_addr_isany(ip6_current_src_addr()) && + (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) { + /* packet source is not valid */ + /* free (drop) packet pbufs */ + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); + pbuf_free(p); + IP6_STATS_INC(ip6.drop); + goto ip6_input_cleanup; + } + + /* packet not for us? */ + if (netif == NULL) { + /* packet not for us, route or discard */ + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n")); +#if LWIP_IPV6_FORWARD + /* non-multicast packet? */ + if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { + /* try to forward IP packet on (other) interfaces */ + ip6_forward(p, ip6hdr, inp); + } +#endif /* LWIP_IPV6_FORWARD */ + pbuf_free(p); + goto ip6_input_cleanup; + } + + /* current netif pointer. */ + ip_data.current_netif = netif; + + /* Save next header type. */ + nexth = IP6H_NEXTH(ip6hdr); + + /* Init header length. */ + hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; + + /* Move to payload. */ + pbuf_header(p, -IP6_HLEN); + + /* Process known option extension headers, if present. */ + while (nexth != IP6_NEXTH_NONE) + { + switch (nexth) { + case IP6_NEXTH_HOPBYHOP: + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); + /* Get next header type. */ + nexth = *((u8_t *)p->payload); + + /* Get the header length. */ + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); + ip_data.current_ip_header_tot_len += hlen; + + /* Skip over this header. */ + if (hlen > p->len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", + hlen, p->len)); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP6_STATS_INC(ip6.lenerr); + IP6_STATS_INC(ip6.drop); + goto ip6_input_cleanup; + } + + pbuf_header(p, -hlen); + break; + case IP6_NEXTH_DESTOPTS: + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n")); + /* Get next header type. */ + nexth = *((u8_t *)p->payload); + + /* Get the header length. */ + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); + ip_data.current_ip_header_tot_len += hlen; + + /* Skip over this header. */ + if (hlen > p->len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", + hlen, p->len)); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP6_STATS_INC(ip6.lenerr); + IP6_STATS_INC(ip6.drop); + goto ip6_input_cleanup; + } + + pbuf_header(p, -hlen); + break; + case IP6_NEXTH_ROUTING: + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); + /* Get next header type. */ + nexth = *((u8_t *)p->payload); + + /* Get the header length. */ + hlen = 8 * (1 + *((u8_t *)p->payload + 1)); + ip_data.current_ip_header_tot_len += hlen; + + /* Skip over this header. */ + if (hlen > p->len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", + hlen, p->len)); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP6_STATS_INC(ip6.lenerr); + IP6_STATS_INC(ip6.drop); + goto ip6_input_cleanup; + } + + pbuf_header(p, -hlen); + break; + + case IP6_NEXTH_FRAGMENT: + { + struct ip6_frag_hdr * frag_hdr; + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); + + frag_hdr = (struct ip6_frag_hdr *)p->payload; + + /* Get next header type. */ + nexth = frag_hdr->_nexth; + + /* Fragment Header length. */ + hlen = 8; + ip_data.current_ip_header_tot_len += hlen; + + /* Make sure this header fits in current pbuf. */ + if (hlen > p->len) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", + hlen, p->len)); + /* free (drop) packet pbufs */ + pbuf_free(p); + IP6_FRAG_STATS_INC(ip6_frag.lenerr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto ip6_input_cleanup; + } + + /* Offset == 0 and more_fragments == 0? */ + if (((frag_hdr->_fragment_offset & IP6_FRAG_OFFSET_MASK) == 0) && + ((frag_hdr->_fragment_offset & IP6_FRAG_MORE_FLAG) == 0)) { + + /* This is a 1-fragment packet, usually a packet that we have + * already reassembled. Skip this header anc continue. */ + pbuf_header(p, -hlen); + } + else { +#if LWIP_IPV6_REASS + + /* reassemble the packet */ + p = ip6_reass(p); + /* packet not fully reassembled yet? */ + if (p == NULL) { + goto ip6_input_cleanup; + } + + /* Returned p point to IPv6 header. + * Update all our variables and pointers and continue. */ + ip6hdr = (struct ip6_hdr *)p->payload; + nexth = IP6H_NEXTH(ip6hdr); + hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; + pbuf_header(p, -IP6_HLEN); + +#else /* LWIP_IPV6_REASS */ + /* free (drop) packet pbufs */ + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n")); + pbuf_free(p); + IP6_STATS_INC(ip6.opterr); + IP6_STATS_INC(ip6.drop); + goto ip6_input_cleanup; +#endif /* LWIP_IPV6_REASS */ + } + break; + } + default: + goto options_done; + break; + } + } +options_done: + + /* p points to IPv6 header again. */ + /* @todo: this does not work for PBUF_REF pbufs */ + pbuf_header(p, ip_data.current_ip_header_tot_len); + + /* send to upper layers */ + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); + ip6_debug_print(p); + LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); + +#if LWIP_RAW + /* raw input did not eat the packet? */ + if (raw_input(p, inp) == 0) +#endif /* LWIP_RAW */ + { + switch (nexth) { + case IP6_NEXTH_NONE: + pbuf_free(p); + break; +#if LWIP_UDP + case IP6_NEXTH_UDP: +#if LWIP_UDPLITE + case IP6_NEXTH_UDPLITE: +#endif /* LWIP_UDPLITE */ + /* Point to payload. */ + pbuf_header(p, -ip_data.current_ip_header_tot_len); + udp_input(p, inp); + break; +#endif /* LWIP_UDP */ +#if LWIP_TCP + case IP6_NEXTH_TCP: + /* Point to payload. */ + pbuf_header(p, -ip_data.current_ip_header_tot_len); + tcp_input(p, inp); + break; +#endif /* LWIP_TCP */ +#if LWIP_ICMP6 + case IP6_NEXTH_ICMP6: + /* Point to payload. */ + pbuf_header(p, -ip_data.current_ip_header_tot_len); + icmp6_input(p, inp); + break; +#endif /* LWIP_ICMP */ + default: +#if LWIP_ICMP6 + /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ + if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && + (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { + icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen); + } +#endif /* LWIP_ICMP */ + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", IP6H_NEXTH(ip6hdr))); + pbuf_free(p); + IP6_STATS_INC(ip6.proterr); + IP6_STATS_INC(ip6.drop); + break; + } + } + +ip6_input_cleanup: + ip_data.current_netif = NULL; + ip_data.current_ip6_header = NULL; + ip_data.current_ip_header_tot_len = 0; + ip6_addr_set_any(&ip_data.current_iphdr_src.ip6); + ip6_addr_set_any(&ip_data.current_iphdr_dest.ip6); + + return ERR_OK; +} + + +/** + * Sends an IPv6 packet on a network interface. This function constructs + * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is + * used as source (usually during network startup). If the source IPv6 address it + * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network + * interface is filled in as source address. If the destination IPv6 address is + * IP_HDRINCL, p is assumed to already include an IPv6 header and p->payload points + * to it instead of the data. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an + IPv6 header and p->payload points to that IPv6 header) + * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an + * IP address of the netif is selected and used as source address. + * if src == NULL, IP6_ADDR_ANY is used as source) + * @param dest the destination IPv6 address to send the packet to + * @param hl the Hop Limit value to be set in the IPv6 header + * @param tc the Traffic Class value to be set in the IPv6 header + * @param nexth the Next Header to be set in the IPv6 header + * @param netif the netif on which to send this packet + * @return ERR_OK if the packet was sent OK + * ERR_BUF if p doesn't have enough space for IPv6/LINK headers + * returns errors returned by netif->output + */ +err_t +ip6_output_if(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, + u8_t nexth, struct netif *netif) +{ + ip6_addr_t *src_used = src; + if (dest != IP_HDRINCL) { + if (src != NULL && ip6_addr_isany(src)) { + src = ip6_select_source_address(netif, dest); + if ((src == NULL) || ip6_addr_isany(src)) { + /* No appropriate source address was found for this packet. */ + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n")); + IP6_STATS_INC(ip6.rterr); + return ERR_RTE; + } + } + } + return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif); +} + +/** + * Same as ip6_output_if() but 'src' address is not replaced by netif address + * when it is 'any'. + */ +err_t +ip6_output_if_src(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, + u8_t nexth, struct netif *netif) +{ + struct ip6_hdr *ip6hdr; + ip6_addr_t dest_addr; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + /* Should the IPv6 header be generated or is it already included in p? */ + if (dest != IP_HDRINCL) { + /* generate IPv6 header */ + if (pbuf_header(p, IP6_HLEN)) { + LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); + IP6_STATS_INC(ip6.err); + return ERR_BUF; + } + + ip6hdr = (struct ip6_hdr *)p->payload; + LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", + (p->len >= sizeof(struct ip6_hdr))); + + IP6H_HOPLIM_SET(ip6hdr, hl); + IP6H_NEXTH_SET(ip6hdr, nexth); + + /* dest cannot be NULL here */ + ip6_addr_copy(ip6hdr->dest, *dest); + + IP6H_VTCFL_SET(ip6hdr, 6, tc, 0); + IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN); + + if (src == NULL) { + src = IP6_ADDR_ANY; + } + /* src cannot be NULL here */ + ip6_addr_copy(ip6hdr->src, *src); + + } else { + /* IP header already included in p */ + ip6hdr = (struct ip6_hdr *)p->payload; + ip6_addr_copy(dest_addr, ip6hdr->dest); + dest = &dest_addr; + } + + IP6_STATS_INC(ip6.xmit); + + LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num)); + ip6_debug_print(p); + +#if ENABLE_LOOPBACK + { + int i; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) { + /* Packet to self, enqueue it for loopback */ + LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n")); + return netif_loop_output(netif, p); + } + } + } +#endif /* ENABLE_LOOPBACK */ +#if LWIP_IPV6_FRAG + /* don't fragment if interface has mtu set to 0 [loopif] */ + if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { + return ip6_frag(p, netif, dest); + } +#endif /* LWIP_IPV6_FRAG */ + + LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n")); + return netif->output_ip6(netif, p, dest); +} + +/** + * Simple interface to ip6_output_if. It finds the outgoing network + * interface and calls upon ip6_output_if to do the actual work. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an + IPv6 header and p->payload points to that IPv6 header) + * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an + * IP address of the netif is selected and used as source address. + * if src == NULL, IP6_ADDR_ANY is used as source) + * @param dest the destination IPv6 address to send the packet to + * @param hl the Hop Limit value to be set in the IPv6 header + * @param tc the Traffic Class value to be set in the IPv6 header + * @param nexth the Next Header to be set in the IPv6 header + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip6_output(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, u8_t nexth) +{ + struct netif *netif; + struct ip6_hdr *ip6hdr; + ip6_addr_t src_addr, dest_addr; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + if (dest != IP_HDRINCL) { + netif = ip6_route(src, dest); + } else { + /* IP header included in p, read addresses. */ + ip6hdr = (struct ip6_hdr *)p->payload; + ip6_addr_copy(src_addr, ip6hdr->src); + ip6_addr_copy(dest_addr, ip6hdr->dest); + netif = ip6_route(&src_addr, &dest_addr); + } + + if (netif == NULL) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", + IP6_ADDR_BLOCK1(dest), + IP6_ADDR_BLOCK2(dest), + IP6_ADDR_BLOCK3(dest), + IP6_ADDR_BLOCK4(dest), + IP6_ADDR_BLOCK5(dest), + IP6_ADDR_BLOCK6(dest), + IP6_ADDR_BLOCK7(dest), + IP6_ADDR_BLOCK8(dest))); + IP6_STATS_INC(ip6.rterr); + return ERR_RTE; + } + + return ip6_output_if(p, src, dest, hl, tc, nexth, netif); +} + + +#if LWIP_NETIF_HWADDRHINT +/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint + * before calling ip6_output_if. + * + * @param p the packet to send (p->payload points to the data, e.g. next + protocol header; if dest == IP_HDRINCL, p already includes an + IPv6 header and p->payload points to that IPv6 header) + * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an + * IP address of the netif is selected and used as source address. + * if src == NULL, IP6_ADDR_ANY is used as source) + * @param dest the destination IPv6 address to send the packet to + * @param hl the Hop Limit value to be set in the IPv6 header + * @param tc the Traffic Class value to be set in the IPv6 header + * @param nexth the Next Header to be set in the IPv6 header + * @param addr_hint address hint pointer set to netif->addr_hint before + * calling ip_output_if() + * + * @return ERR_RTE if no route is found + * see ip_output_if() for more return values + */ +err_t +ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) +{ + struct netif *netif; + struct ip6_hdr *ip6hdr; + ip6_addr_t src_addr, dest_addr; + err_t err; + + LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); + + if (dest != IP_HDRINCL) { + netif = ip6_route(src, dest); + } else { + /* IP header included in p, read addresses. */ + ip6hdr = (struct ip6_hdr *)p->payload; + ip6_addr_copy(src_addr, ip6hdr->src); + ip6_addr_copy(dest_addr, ip6hdr->dest); + netif = ip6_route(&src_addr, &dest_addr); + } + + if (netif == NULL) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", + IP6_ADDR_BLOCK1(dest), + IP6_ADDR_BLOCK2(dest), + IP6_ADDR_BLOCK3(dest), + IP6_ADDR_BLOCK4(dest), + IP6_ADDR_BLOCK5(dest), + IP6_ADDR_BLOCK6(dest), + IP6_ADDR_BLOCK7(dest), + IP6_ADDR_BLOCK8(dest))); + IP6_STATS_INC(ip6.rterr); + return ERR_RTE; + } + + NETIF_SET_HWADDRHINT(netif, addr_hint); + err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + return err; +} +#endif /* LWIP_NETIF_HWADDRHINT*/ + +#if LWIP_IPV6_MLD +/** + * Add a hop-by-hop options header with a router alert option and padding. + * + * Used by MLD when sending a Multicast listener report/done message. + * + * @param p the packet to which we will prepend the options header + * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6) + * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD) + * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise + */ +err_t +ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value) +{ + struct ip6_hbh_hdr * hbh_hdr; + + /* Move pointer to make room for hop-by-hop options header. */ + if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) { + LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); + IP6_STATS_INC(ip6.err); + return ERR_BUF; + } + + hbh_hdr = (struct ip6_hbh_hdr *)p->payload; + + /* Set fields. */ + hbh_hdr->_nexth = nexth; + hbh_hdr->_hlen = 0; + hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION; + hbh_hdr->_ra_opt_dlen = 2; + hbh_hdr->_ra_opt_data = value; + hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION; + hbh_hdr->_padn_opt_dlen = 0; + + return ERR_OK; +} +#endif /* LWIP_IPV6_MLD */ + +#if IP6_DEBUG +/* Print an IPv6 header by using LWIP_DEBUGF + * @param p an IPv6 packet, p->payload pointing to the IPv6 header + */ +void +ip6_debug_print(struct pbuf *p) +{ + struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; + + LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); + LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", + IP6H_V(ip6hdr), + IP6H_TC(ip6hdr), + IP6H_FL(ip6hdr))); + LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", + IP6H_PLEN(ip6hdr), + IP6H_NEXTH(ip6hdr), + IP6H_HOPLIM(ip6hdr))); + LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", + IP6_ADDR_BLOCK1(&(ip6hdr->src)), + IP6_ADDR_BLOCK2(&(ip6hdr->src)), + IP6_ADDR_BLOCK3(&(ip6hdr->src)), + IP6_ADDR_BLOCK4(&(ip6hdr->src)))); + LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", + IP6_ADDR_BLOCK5(&(ip6hdr->src)), + IP6_ADDR_BLOCK6(&(ip6hdr->src)), + IP6_ADDR_BLOCK7(&(ip6hdr->src)), + IP6_ADDR_BLOCK8(&(ip6hdr->src)))); + LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", + IP6_ADDR_BLOCK1(&(ip6hdr->dest)), + IP6_ADDR_BLOCK2(&(ip6hdr->dest)), + IP6_ADDR_BLOCK3(&(ip6hdr->dest)), + IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); + LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", + IP6_ADDR_BLOCK5(&(ip6hdr->dest)), + IP6_ADDR_BLOCK6(&(ip6hdr->dest)), + IP6_ADDR_BLOCK7(&(ip6hdr->dest)), + IP6_ADDR_BLOCK8(&(ip6hdr->dest)))); + LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); +} +#endif /* IP6_DEBUG */ + +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_addr.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_addr.c new file mode 100644 index 0000000..66c1e0c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_addr.c @@ -0,0 +1,251 @@ +/** + * @file + * + * IPv6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * Functions for handling IPv6 addresses. + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" + +/* used by IP6_ADDR_ANY in ip6_addr.h */ +const ip6_addr_t ip6_addr_any = { { 0ul, 0ul, 0ul, 0ul } }; + +#ifndef isprint +#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10) +#endif + +/** + * Check whether "cp" is a valid ascii representation + * of an IPv6 address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * + * @param cp IPv6 address in ascii representation (e.g. "FF01::1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +ip6addr_aton(const char *cp, ip6_addr_t *addr) +{ + u32_t addr_index, zero_blocks, current_block_index, current_block_value; + const char * s; + + /* Count the number of colons, to count the number of blocks in a "::" sequence + zero_blocks may be 1 even if there are no :: sequences */ + zero_blocks = 8; + for (s = cp; *s != 0; s++) { + if (*s == ':') + zero_blocks--; + else if (!isxdigit(*s)) + break; + } + + /* parse each block */ + addr_index = 0; + current_block_index = 0; + current_block_value = 0; + for (s = cp; *s != 0; s++) { + if (*s == ':') { + if (addr) { + if (current_block_index & 0x1) { + addr->addr[addr_index++] |= current_block_value; + } + else { + addr->addr[addr_index] = current_block_value << 16; + } + } + current_block_index++; + current_block_value = 0; + if (current_block_index > 7) { + /* address too long! */ + return 0; + } if (s[1] == ':') { + s++; + /* "::" found, set zeros */ + while (zero_blocks-- > 0) { + if (current_block_index & 0x1) { + addr_index++; + } + else { + if (addr) { + addr->addr[addr_index] = 0; + } + } + current_block_index++; + } + } + } else if (isxdigit(*s)) { + /* add current digit */ + current_block_value = (current_block_value << 4) + + (isdigit(*s) ? *s - '0' : + 10 + (islower(*s) ? *s - 'a' : *s - 'A')); + } else { + /* unexpected digit, space? CRLF? */ + break; + } + } + + if (addr) { + if (current_block_index & 0x1) { + addr->addr[addr_index++] |= current_block_value; + } + else { + addr->addr[addr_index] = current_block_value << 16; + } + } + + /* convert to network byte order. */ + if (addr) { + for (addr_index = 0; addr_index < 4; addr_index++) { + addr->addr[addr_index] = htonl(addr->addr[addr_index]); + } + } + + if (current_block_index != 7) { + return 0; + } + + return 1; +} + +/** + * Convert numeric IPv6 address into ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip6 address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * representation of addr + */ +char * +ip6addr_ntoa(const ip6_addr_t *addr) +{ + static char str[40]; + return ip6addr_ntoa_r(addr, str, 40); +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip6 address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char * +ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen) +{ + u32_t current_block_index, current_block_value; + s32_t zero_flag, i; + + i = 0; + zero_flag = 0; /* used to indicate a zero chain for "::' */ + + for (current_block_index = 0; current_block_index < 8; current_block_index++) { + /* get the current 16-bit block */ + current_block_value = htonl(addr->addr[current_block_index >> 1]); + if ((current_block_index & 0x1) == 0) { + current_block_value = current_block_value >> 16; + } + current_block_value &= 0xffff; + + if (current_block_value == 0) { + /* generate empty block "::" */ + if (!zero_flag) { + if (current_block_index > 0) { + zero_flag = 1; + buf[i++] = ':'; + if (i >= buflen) return NULL; + } + } + } + else { + if (current_block_index > 0) { + buf[i++] = ':'; + if (i >= buflen) return NULL; + } + + if ((current_block_value & 0xf000) == 0) { + zero_flag = 1; + } + else { + buf[i++] = xchar(((current_block_value & 0xf000) >> 12)); + zero_flag = 0; + if (i >= buflen) return NULL; + } + + if (((current_block_value & 0xf00) == 0) && (zero_flag)) { + /* do nothing */ + } + else { + buf[i++] = xchar(((current_block_value & 0xf00) >> 8)); + zero_flag = 0; + if (i >= buflen) return NULL; + } + + if (((current_block_value & 0xf0) == 0) && (zero_flag)) { + /* do nothing */ + } + else { + buf[i++] = xchar(((current_block_value & 0xf0) >> 4)); + zero_flag = 0; + if (i >= buflen) return NULL; + } + + buf[i++] = xchar((current_block_value & 0xf)); + if (i >= buflen) return NULL; + + zero_flag = 0; + } + } + + buf[i] = 0; + + return buf; +} +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_frag.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_frag.c new file mode 100644 index 0000000..4829ac3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/ip6_frag.c @@ -0,0 +1,716 @@ +/** + * @file + * + * IPv6 fragmentation and reassembly. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" +#include "lwip/ip6_frag.h" +#include "lwip/ip6.h" +#include "lwip/icmp6.h" +#include "lwip/nd6.h" +#include "lwip/lwip_ip.h" + +#include "lwip/pbuf.h" +#include "lwip/memp.h" +#include "lwip/stats.h" + +#include + +#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ + + +/** Setting this to 0, you can turn off checking the fragments for overlapping + * regions. The code gets a little smaller. Only use this if you know that + * overlapping won't occur on your network! */ +#ifndef IP_REASS_CHECK_OVERLAP +#define IP_REASS_CHECK_OVERLAP 1 +#endif /* IP_REASS_CHECK_OVERLAP */ + +/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is + * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. + * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA + * is set to 1, so one datagram can be reassembled at a time, only. */ +#ifndef IP_REASS_FREE_OLDEST +#define IP_REASS_FREE_OLDEST 1 +#endif /* IP_REASS_FREE_OLDEST */ + +#define IP_REASS_FLAG_LASTFRAG 0x01 + +/** This is a helper struct which holds the starting + * offset and the ending offset of this fragment to + * easily chain the fragments. + * It has the same packing requirements as the IPv6 header, since it replaces + * the Fragment Header in memory in incoming fragments to keep + * track of the various fragments. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_reass_helper { + PACK_STRUCT_FIELD(struct pbuf *next_pbuf); + PACK_STRUCT_FIELD(u16_t start); + PACK_STRUCT_FIELD(u16_t end); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* static variables */ +static struct ip6_reassdata *reassdatagrams; +static u16_t ip6_reass_pbufcount; + +/* Forward declarations. */ +static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr); +#if IP_REASS_FREE_OLDEST +static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed); +#endif /* IP_REASS_FREE_OLDEST */ + +void +ip6_reass_tmr(void) +{ + struct ip6_reassdata *r, *tmp; + + r = reassdatagrams; + while (r != NULL) { + /* Decrement the timer. Once it reaches 0, + * clean up the incomplete fragment assembly */ + if (r->timer > 0) { + r->timer--; + r = r->next; + } else { + /* reassembly timed out */ + tmp = r; + /* get the next pointer before freeing */ + r = r->next; + /* free the helper struct and all enqueued pbufs */ + ip6_reass_free_complete_datagram(tmp); + } + } +} + +/** + * Free a datagram (struct ip6_reassdata) and all its pbufs. + * Updates the total count of enqueued pbufs (ip6_reass_pbufcount), + * sends an ICMP time exceeded packet. + * + * @param ipr datagram to free + */ +static void +ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) +{ + struct ip6_reassdata *prev; + u16_t pbufs_freed = 0; + u8_t clen; + struct pbuf *p; + struct ip6_reass_helper *iprh; + +#if LWIP_ICMP6 + iprh = (struct ip6_reass_helper *)ipr->p->payload; + if (iprh->start == 0) { + /* The first fragment was received, send ICMP time exceeded. */ + /* First, de-queue the first pbuf from r->p. */ + p = ipr->p; + ipr->p = iprh->next_pbuf; + /* Then, move back to the original header (we are now pointing to Fragment header). */ + if (pbuf_header(p, (u8_t*)p->payload - (u8_t*)ipr->iphdr)) { + LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); + } + else { + icmp6_time_exceeded(p, ICMP6_TE_FRAG); + } + clen = pbuf_clen(p); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(p); + } +#endif /* LWIP_ICMP6 */ + + /* First, free all received pbufs. The individual pbufs need to be released + separately as they have not yet been chained */ + p = ipr->p; + while (p != NULL) { + struct pbuf *pcur; + iprh = (struct ip6_reass_helper *)p->payload; + pcur = p; + /* get the next pointer before freeing */ + p = iprh->next_pbuf; + clen = pbuf_clen(pcur); + LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); + pbufs_freed += clen; + pbuf_free(pcur); + } + + /* Then, unchain the struct ip6_reassdata from the list and free it. */ + if (ipr == reassdatagrams) { + reassdatagrams = ipr->next; + } else { + prev = reassdatagrams; + while (prev != NULL) { + if (prev->next == ipr) { + break; + } + prev = prev->next; + } + if (prev != NULL) { + prev->next = ipr->next; + } + } + memp_free(MEMP_IP6_REASSDATA, ipr); + + /* Finally, update number of pbufs in reassembly queue */ + LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed); + ip6_reass_pbufcount -= pbufs_freed; +} + +#if IP_REASS_FREE_OLDEST +/** + * Free the oldest datagram to make room for enqueueing new fragments. + * The datagram ipr is not freed! + * + * @param ipr ip6_reassdata for the current fragment + * @param pbufs_needed number of pbufs needed to enqueue + * (used for freeing other datagrams if not enough space) + */ +static void +ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed) +{ + struct ip6_reassdata *r, *oldest; + + /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, + * but don't free the current datagram! */ + do { + r = oldest = reassdatagrams; + while (r != NULL) { + if (r != ipr) { + if (r->timer <= oldest->timer) { + /* older than the previous oldest */ + oldest = r; + } + } + r = r->next; + } + if (oldest != NULL) { + ip6_reass_free_complete_datagram(oldest); + } + } while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL)); +} +#endif /* IP_REASS_FREE_OLDEST */ + +/** + * Reassembles incoming IPv6 fragments into an IPv6 datagram. + * + * @param p points to the IPv6 Fragment Header + * @param len the length of the payload (after Fragment Header) + * @return NULL if reassembly is incomplete, pbuf pointing to + * IPv6 Header if reassembly is complete + */ +struct pbuf * +ip6_reass(struct pbuf *p) +{ + struct ip6_reassdata *ipr, *ipr_prev; + struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; + struct ip6_frag_hdr * frag_hdr; + u16_t offset, len; + u8_t clen, valid = 1; + struct pbuf *q; + + IP6_FRAG_STATS_INC(ip6_frag.recv); + + frag_hdr = (struct ip6_frag_hdr *) p->payload; + + clen = pbuf_clen(p); + + offset = ntohs(frag_hdr->_fragment_offset); + + /* Calculate fragment length from IPv6 payload length. + * Adjust for headers before Fragment Header. + * And finally adjust by Fragment Header length. */ + len = ntohs(ip6_current_header()->_plen); + len -= ((u8_t*)p->payload - (u8_t*)ip6_current_header()) - IP6_HLEN; + len -= IP6_FRAG_HLEN; + + /* Look for the datagram the fragment belongs to in the current datagram queue, + * remembering the previous in the queue for later dequeueing. */ + for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) { + /* Check if the incoming fragment matches the one currently present + in the reassembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if ((frag_hdr->_identification == ipr->identification) && + ip6_addr_cmp(ip6_current_src_addr(), &(ipr->iphdr->src)) && + ip6_addr_cmp(ip6_current_dest_addr(), &(ipr->iphdr->dest))) { + IP6_FRAG_STATS_INC(ip6_frag.cachehit); + break; + } + ipr_prev = ipr; + } + + if (ipr == NULL) { + /* Enqueue a new datagram into the datagram queue */ + ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); + if (ipr == NULL) { +#if IP_REASS_FREE_OLDEST + /* Make room and try again. */ + ip6_reass_remove_oldest_datagram(ipr, clen); + ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); + if (ipr != NULL) { + /* re-search ipr_prev since it might have been removed */ + for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { + if (ipr_prev->next == ipr) { + break; + } + } + } else +#endif /* IP_REASS_FREE_OLDEST */ + { + IP6_FRAG_STATS_INC(ip6_frag.memerr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; + } + } + + memset(ipr, 0, sizeof(struct ip6_reassdata)); + ipr->timer = IP_REASS_MAXAGE; + + /* enqueue the new structure to the front of the list */ + ipr->next = reassdatagrams; + reassdatagrams = ipr; + + /* Use the current IPv6 header for src/dest address reference. + * Eventually, we will replace it when we get the first fragment + * (it might be this one, in any case, it is done later). */ + ipr->iphdr = (struct ip6_hdr *)ip6_current_header(); + + /* copy the fragmented packet id. */ + ipr->identification = frag_hdr->_identification; + + /* copy the nexth field */ + ipr->nexth = frag_hdr->_nexth; + } + + /* Check if we are allowed to enqueue more datagrams. */ + if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { +#if IP_REASS_FREE_OLDEST + ip6_reass_remove_oldest_datagram(ipr, clen); + if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) { + /* re-search ipr_prev since it might have been removed */ + for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { + if (ipr_prev->next == ipr) { + break; + } + } + } else +#endif /* IP_REASS_FREE_OLDEST */ + { + /* @todo: send ICMPv6 time exceeded here? */ + /* drop this pbuf */ + IP6_FRAG_STATS_INC(ip6_frag.memerr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; + } + } + + /* Overwrite Fragment Header with our own helper struct. */ + iprh = (struct ip6_reass_helper *)p->payload; + LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN", + sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); + iprh->next_pbuf = NULL; + iprh->start = (offset & IP6_FRAG_OFFSET_MASK); + iprh->end = (offset & IP6_FRAG_OFFSET_MASK) + len; + + /* find the right place to insert this pbuf */ + /* Iterate through until we either get to the end of the list (append), + * or we find on with a larger offset (insert). */ + for (q = ipr->p; q != NULL;) { + iprh_tmp = (struct ip6_reass_helper*)q->payload; + if (iprh->start < iprh_tmp->start) { +#if IP_REASS_CHECK_OVERLAP + if (iprh->end > iprh_tmp->start) { + /* fragment overlaps with following, throw away */ + IP6_FRAG_STATS_INC(ip6_frag.proterr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; + } + if (iprh_prev != NULL) { + if (iprh->start < iprh_prev->end) { + /* fragment overlaps with previous, throw away */ + IP6_FRAG_STATS_INC(ip6_frag.proterr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; + } + } +#endif /* IP_REASS_CHECK_OVERLAP */ + /* the new pbuf should be inserted before this */ + iprh->next_pbuf = q; + if (iprh_prev != NULL) { + /* not the fragment with the lowest offset */ + iprh_prev->next_pbuf = p; + } else { + /* fragment with the lowest offset */ + ipr->p = p; + } + break; + } else if(iprh->start == iprh_tmp->start) { + /* received the same datagram twice: no need to keep the datagram */ + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; +#if IP_REASS_CHECK_OVERLAP + } else if(iprh->start < iprh_tmp->end) { + /* overlap: no need to keep the new datagram */ + IP6_FRAG_STATS_INC(ip6_frag.proterr); + IP6_FRAG_STATS_INC(ip6_frag.drop); + goto nullreturn; +#endif /* IP_REASS_CHECK_OVERLAP */ + } else { + /* Check if the fragments received so far have no gaps. */ + if (iprh_prev != NULL) { + if (iprh_prev->end != iprh_tmp->start) { + /* There is a fragment missing between the current + * and the previous fragment */ + valid = 0; + } + } + } + q = iprh_tmp->next_pbuf; + iprh_prev = iprh_tmp; + } + + /* If q is NULL, then we made it to the end of the list. Determine what to do now */ + if (q == NULL) { + if (iprh_prev != NULL) { + /* this is (for now), the fragment with the highest offset: + * chain it to the last fragment */ +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); +#endif /* IP_REASS_CHECK_OVERLAP */ + iprh_prev->next_pbuf = p; + if (iprh_prev->end != iprh->start) { + valid = 0; + } + } else { +#if IP_REASS_CHECK_OVERLAP + LWIP_ASSERT("no previous fragment, this must be the first fragment!", + ipr->p == NULL); +#endif /* IP_REASS_CHECK_OVERLAP */ + /* this is the first fragment we ever received for this ip datagram */ + ipr->p = p; + } + } + + /* Track the current number of pbufs current 'in-flight', in order to limit + the number of fragments that may be enqueued at any one time */ + ip6_reass_pbufcount += clen; + + /* Remember IPv6 header if this is the first fragment. */ + if (iprh->start == 0) { + ipr->iphdr = (struct ip6_hdr *)ip6_current_header(); + } + + /* If this is the last fragment, calculate total packet length. */ + if ((offset & IP6_FRAG_MORE_FLAG) == 0) { + ipr->datagram_len = iprh->end; + } + + /* Additional validity tests: we have received first and last fragment. */ + iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload; + if (iprh_tmp->start != 0) { + valid = 0; + } + if (ipr->datagram_len == 0) { + valid = 0; + } + + /* Final validity test: no gaps between current and last fragment. */ + iprh_prev = iprh; + q = iprh->next_pbuf; + while ((q != NULL) && valid) { + iprh = (struct ip6_reass_helper*)q->payload; + if (iprh_prev->end != iprh->start) { + valid = 0; + break; + } + iprh_prev = iprh; + q = iprh->next_pbuf; + } + + if (valid) { + /* All fragments have been received */ + u8_t* iphdr_ptr; + + /* chain together the pbufs contained within the ip6_reassdata list. */ + iprh = (struct ip6_reass_helper*) ipr->p->payload; + while(iprh != NULL) { + + if (iprh->next_pbuf != NULL) { + /* Save next helper struct (will be hidden in next step). */ + iprh_tmp = (struct ip6_reass_helper*) iprh->next_pbuf->payload; + + /* hide the fragment header for every succeeding fragment */ + pbuf_header(iprh->next_pbuf, -IP6_FRAG_HLEN); + pbuf_cat(ipr->p, iprh->next_pbuf); + } + else { + iprh_tmp = NULL; + } + + iprh = iprh_tmp; + } + + /* Adjust datagram length by adding header lengths. */ + ipr->datagram_len += ((u8_t*)ipr->p->payload - (u8_t*)ipr->iphdr) + + IP6_FRAG_HLEN + - IP6_HLEN ; + + /* Set payload length in ip header. */ + ipr->iphdr->_plen = htons(ipr->datagram_len); + + /* Get the first pbuf. */ + p = ipr->p; + + /* Restore Fragment Header in first pbuf. Mark as "single fragment" + * packet. Restore nexth. */ + frag_hdr = (struct ip6_frag_hdr *) p->payload; + frag_hdr->_nexth = ipr->nexth; + frag_hdr->reserved = 0; + frag_hdr->_fragment_offset = 0; + frag_hdr->_identification = 0; + + /* release the sources allocate for the fragment queue entry */ + if (reassdatagrams == ipr) { + /* it was the first in the list */ + reassdatagrams = ipr->next; + } else { + /* it wasn't the first, so it must have a valid 'prev' */ + LWIP_ASSERT("sanity check linked list", ipr_prev != NULL); + ipr_prev->next = ipr->next; + } + iphdr_ptr = (u8_t*)ipr->iphdr; + memp_free(MEMP_IP6_REASSDATA, ipr); + + /* adjust the number of pbufs currently queued for reassembly. */ + ip6_reass_pbufcount -= pbuf_clen(p); + + /* Move pbuf back to IPv6 header. */ + if (pbuf_header(p, (u8_t*)p->payload - iphdr_ptr)) { + LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); + pbuf_free(p); + return NULL; + } + + /* Return the pbuf chain */ + return p; + } + /* the datagram is not (yet?) reassembled completely */ + return NULL; + +nullreturn: + pbuf_free(p); + return NULL; +} + +#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ + +#if LWIP_IPV6 && LWIP_IPV6_FRAG + +/** Allocate a new struct pbuf_custom_ref */ +static struct pbuf_custom_ref* +ip6_frag_alloc_pbuf_custom_ref(void) +{ + return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); +} + +/** Free a struct pbuf_custom_ref */ +static void +ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) +{ + LWIP_ASSERT("p != NULL", p != NULL); + memp_free(MEMP_FRAG_PBUF, p); +} + +/** Free-callback function to free a 'struct pbuf_custom_ref', called by + * pbuf_free. */ +static void +ip6_frag_free_pbuf_custom(struct pbuf *p) +{ + struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; + LWIP_ASSERT("pcr != NULL", pcr != NULL); + LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); + if (pcr->original != NULL) { + pbuf_free(pcr->original); + } + ip6_frag_free_pbuf_custom_ref(pcr); +} + +/** + * Fragment an IPv6 datagram if too large for the netif or path MTU. + * + * Chop the datagram in MTU sized chunks and send them in order + * by pointing PBUF_REFs into p + * + * @param p ipv6 packet to send + * @param netif the netif on which to send + * @param dest destination ipv6 address to which to send + * + * @return ERR_OK if sent successfully, err_t otherwise + */ +err_t +ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest) +{ + struct ip6_hdr *original_ip6hdr; + struct ip6_hdr *ip6hdr; + struct ip6_frag_hdr * frag_hdr; + struct pbuf *rambuf; + struct pbuf *newpbuf; + static u32_t identification; + u16_t nfb; + u16_t left, cop; + u16_t mtu; + u16_t fragment_offset = 0; + u16_t last; + u16_t poff = IP6_HLEN; + u16_t newpbuflen = 0; + u16_t left_to_copy; + + identification++; + + original_ip6hdr = (struct ip6_hdr *)p->payload; + + mtu = nd6_get_destination_mtu(dest, netif); + + /* TODO we assume there are no options in the unfragmentable part (IPv6 header). */ + left = p->tot_len - IP6_HLEN; + + nfb = (mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK; + + while (left) { + last = (left <= nfb); + + /* Fill this fragment */ + cop = last ? left : nfb; + + /* When not using a static buffer, create a chain of pbufs. + * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. + * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, + * but limited to the size of an mtu. + */ + rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM); + if (rambuf == NULL) { + IP6_FRAG_STATS_INC(ip6_frag.memerr); + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (p->len >= (IP6_HLEN + IP6_FRAG_HLEN))); + SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); + ip6hdr = (struct ip6_hdr *)rambuf->payload; + frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); + + /* Can just adjust p directly for needed offset. */ + p->payload = (u8_t *)p->payload + poff; + p->len -= poff; + p->tot_len -= poff; + + left_to_copy = cop; + while (left_to_copy) { + struct pbuf_custom_ref *pcr; + newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; + /* Is this pbuf already empty? */ + if (!newpbuflen) { + p = p->next; + continue; + } + pcr = ip6_frag_alloc_pbuf_custom_ref(); + if (pcr == NULL) { + pbuf_free(rambuf); + IP6_FRAG_STATS_INC(ip6_frag.memerr); + return ERR_MEM; + } + /* Mirror this pbuf, although we might not need all of it. */ + newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); + if (newpbuf == NULL) { + ip6_frag_free_pbuf_custom_ref(pcr); + pbuf_free(rambuf); + IP6_FRAG_STATS_INC(ip6_frag.memerr); + return ERR_MEM; + } + pbuf_ref(p); + pcr->original = p; + pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom; + + /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain + * so that it is removed when pbuf_dechain is later called on rambuf. + */ + pbuf_cat(rambuf, newpbuf); + left_to_copy -= newpbuflen; + if (left_to_copy) { + p = p->next; + } + } + poff = newpbuflen; + + /* Set headers */ + frag_hdr->_nexth = original_ip6hdr->_nexth; + frag_hdr->reserved = 0; + frag_hdr->_fragment_offset = htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)); + frag_hdr->_identification = htonl(identification); + + IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); + IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN); + + /* No need for separate header pbuf - we allowed room for it in rambuf + * when allocated. + */ + IP6_FRAG_STATS_INC(ip6_frag.xmit); + netif->output_ip6(netif, rambuf, dest); + + /* Unfortunately we can't reuse rambuf - the hardware may still be + * using the buffer. Instead we free it (and the ensuing chain) and + * recreate it next time round the loop. If we're lucky the hardware + * will have already sent the packet, the free will really free, and + * there will be zero memory penalty. + */ + + pbuf_free(rambuf); + left -= cop; + fragment_offset += cop; + } + return ERR_OK; +} + +#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/mld6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/mld6.c new file mode 100644 index 0000000..a884a39 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/mld6.c @@ -0,0 +1,586 @@ +/** + * @file + * + * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. + * No support for MLDv2. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +/* Based on igmp.c implementation of igmp v2 protocol */ + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_IPV6_MLD /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/mld6.h" +#include "lwip/icmp6.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/lwip_ip.h" +#include "lwip/inet_chksum.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/memp.h" +#include "lwip/stats.h" + +#include + + +/* + * MLD constants + */ +#define MLD6_HL 1 +#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500) + +#define MLD6_GROUP_NON_MEMBER 0 +#define MLD6_GROUP_DELAYING_MEMBER 1 +#define MLD6_GROUP_IDLE_MEMBER 2 + + +/* The list of joined groups. */ +static struct mld_group* mld_group_list; + + +/* Forward declarations. */ +static struct mld_group * mld6_new_group(struct netif *ifp, ip6_addr_t *addr); +static err_t mld6_free_group(struct mld_group *group); +static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); +static void mld6_send(struct mld_group *group, u8_t type); + + +/** + * Stop MLD processing on interface + * + * @param netif network interface on which stop MLD processing + */ +err_t +mld6_stop(struct netif *netif) +{ + struct mld_group *group = mld_group_list; + struct mld_group *prev = NULL; + struct mld_group *next; + + /* look for groups joined on this interface further down the list */ + while (group != NULL) { + next = group->next; + /* is it a group joined on this interface? */ + if (group->netif == netif) { + /* is it the first group of the list? */ + if (group == mld_group_list) { + mld_group_list = next; + } + /* is there a "previous" group defined? */ + if (prev != NULL) { + prev->next = next; + } + /* disable the group at the MAC level */ + if (netif->mld_mac_filter != NULL) { + netif->mld_mac_filter(netif, &(group->group_address), MLD6_DEL_MAC_FILTER); + } + /* free group */ + memp_free(MEMP_MLD6_GROUP, group); + } else { + /* change the "previous" */ + prev = group; + } + /* move to "next" */ + group = next; + } + return ERR_OK; +} + +/** + * Report MLD memberships for this interface + * + * @param netif network interface on which report MLD memberships + */ +void +mld6_report_groups(struct netif *netif) +{ + struct mld_group *group = mld_group_list; + + while (group != NULL) { + if (group->netif == netif) { + mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); + } + group = group->next; + } +} + +/** + * Search for a group that is joined on a netif + * + * @param ifp the network interface for which to look + * @param addr the group ipv6 address to search for + * @return a struct mld_group* if the group has been found, + * NULL if the group wasn't found. + */ +struct mld_group * +mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr) +{ + struct mld_group *group = mld_group_list; + + while (group != NULL) { + if ((group->netif == ifp) && (ip6_addr_cmp(&(group->group_address), addr))) { + return group; + } + group = group->next; + } + + return NULL; +} + + +/** + * create a new group + * + * @param ifp the network interface for which to create + * @param addr the new group ipv6 + * @return a struct mld_group*, + * NULL on memory error. + */ +static struct mld_group * +mld6_new_group(struct netif *ifp, ip6_addr_t *addr) +{ + struct mld_group *group; + + group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP); + if (group != NULL) { + group->netif = ifp; + ip6_addr_set(&(group->group_address), addr); + group->timer = 0; /* Not running */ + group->group_state = MLD6_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + group->use = 0; + group->next = mld_group_list; + + mld_group_list = group; + } + + return group; +} + +/** + * Remove a group in the mld_group_list and free + * + * @param group the group to remove + * @return ERR_OK if group was removed from the list, an err_t otherwise + */ +static err_t +mld6_free_group(struct mld_group *group) +{ + err_t err = ERR_OK; + + /* Is it the first group? */ + if (mld_group_list == group) { + mld_group_list = group->next; + } else { + /* look for group further down the list */ + struct mld_group *tmpGroup; + for (tmpGroup = mld_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) { + if (tmpGroup->next == group) { + tmpGroup->next = group->next; + break; + } + } + /* Group not find group */ + if (tmpGroup == NULL) + err = ERR_ARG; + } + /* free group */ + memp_free(MEMP_MLD6_GROUP, group); + + return err; +} + + +/** + * Process an input MLD message. Called by icmp6_input. + * + * @param p the mld packet, p->payload pointing to the icmpv6 header + * @param inp the netif on which this packet was received + */ +void +mld6_input(struct pbuf *p, struct netif *inp) +{ + struct mld_header * mld_hdr; + struct mld_group* group; + + MLD6_STATS_INC(mld6.recv); + + /* Check that mld header fits in packet. */ + if (p->len < sizeof(struct mld_header)) { + /* TODO debug message */ + pbuf_free(p); + MLD6_STATS_INC(mld6.lenerr); + MLD6_STATS_INC(mld6.drop); + return; + } + + mld_hdr = (struct mld_header *)p->payload; + + switch (mld_hdr->type) { + case ICMP6_TYPE_MLQ: /* Multicast listener query. */ + { + /* Is it a general query? */ + if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && + ip6_addr_isany(&(mld_hdr->multicast_address))) { + MLD6_STATS_INC(mld6.rx_general); + /* Report all groups, except all nodes group, and if-local groups. */ + group = mld_group_list; + while (group != NULL) { + if ((group->netif == inp) && + (!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && + (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { + mld6_delayed_report(group, mld_hdr->max_resp_delay); + } + group = group->next; + } + } + else { + /* Have we joined this group? + * We use IP6 destination address to have a memory aligned copy. + * mld_hdr->multicast_address should be the same. */ + MLD6_STATS_INC(mld6.rx_group); + group = mld6_lookfor_group(inp, ip6_current_dest_addr()); + if (group != NULL) { + /* Schedule a report. */ + mld6_delayed_report(group, mld_hdr->max_resp_delay); + } + } + break; /* ICMP6_TYPE_MLQ */ + } + case ICMP6_TYPE_MLR: /* Multicast listener report. */ + { + /* Have we joined this group? + * We use IP6 destination address to have a memory aligned copy. + * mld_hdr->multicast_address should be the same. */ + MLD6_STATS_INC(mld6.rx_report); + group = mld6_lookfor_group(inp, ip6_current_dest_addr()); + if (group != NULL) { + /* If we are waiting to report, cancel it. */ + if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { + group->timer = 0; /* stopped */ + group->group_state = MLD6_GROUP_IDLE_MEMBER; + group->last_reporter_flag = 0; + } + } + break; /* ICMP6_TYPE_MLR */ + } + case ICMP6_TYPE_MLD: /* Multicast listener done. */ + { + /* Do nothing, router will query us. */ + break; /* ICMP6_TYPE_MLD */ + } + default: + MLD6_STATS_INC(mld6.proterr); + MLD6_STATS_INC(mld6.drop); + break; + } + + pbuf_free(p); +} + +/** + * Join a group on a network interface. + * + * @param srcaddr ipv6 address of the network interface which should + * join a new group. If IP6_ADDR_ANY, join on all netifs + * @param groupaddr the ipv6 address of the group to join + * @return ERR_OK if group was joined on the netif(s), an err_t otherwise + */ +err_t +mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct mld_group *group; + struct netif *netif; + u8_t match; + u8_t i; + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we join this interface ? */ + match = 0; + if (ip6_addr_isany(srcaddr)) { + match = 1; + } + else { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_cmp(srcaddr, netif_ip6_addr(netif, i))) { + match = 1; + break; + } + } + } + if (match) { + /* find group or create a new one if not found */ + group = mld6_lookfor_group(netif, groupaddr); + + if (group == NULL) { + /* Joining a new group. Create a new group entry. */ + group = mld6_new_group(netif, groupaddr); + if (group == NULL) { + return ERR_MEM; + } + + /* Activate this address on the MAC layer. */ + if (netif->mld_mac_filter != NULL) { + netif->mld_mac_filter(netif, groupaddr, MLD6_ADD_MAC_FILTER); + } + + /* Report our membership. */ + MLD6_STATS_INC(mld6.tx_report); + mld6_send(group, ICMP6_TYPE_MLR); + mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); + } + + /* Increment group use */ + group->use++; + err = ERR_OK; + } + + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + +/** + * Leave a group on a network interface. + * + * @param srcaddr ipv6 address of the network interface which should + * leave the group. If IP6_ISANY, leave on all netifs + * @param groupaddr the ipv6 address of the group to leave + * @return ERR_OK if group was left on the netif(s), an err_t otherwise + */ +err_t +mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr) +{ + err_t err = ERR_VAL; /* no matching interface */ + struct mld_group *group; + struct netif *netif; + u8_t match; + u8_t i; + + /* loop through netif's */ + netif = netif_list; + while (netif != NULL) { + /* Should we leave this interface ? */ + match = 0; + if (ip6_addr_isany(srcaddr)) { + match = 1; + } + else { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_cmp(srcaddr, netif_ip6_addr(netif, i))) { + match = 1; + break; + } + } + } + if (match) { + /* find group */ + group = mld6_lookfor_group(netif, groupaddr); + + if (group != NULL) { + /* Leave if there is no other use of the group */ + if (group->use <= 1) { + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + MLD6_STATS_INC(mld6.tx_leave); + mld6_send(group, ICMP6_TYPE_MLD); + } + + /* Disable the group at the MAC level */ + if (netif->mld_mac_filter != NULL) { + netif->mld_mac_filter(netif, groupaddr, MLD6_DEL_MAC_FILTER); + } + + /* Free the group */ + mld6_free_group(group); + } else { + /* Decrement group use */ + group->use--; + } + /* Leave on this interface */ + err = ERR_OK; + } + } + /* proceed to next network interface */ + netif = netif->next; + } + + return err; +} + + +/** + * Periodic timer for mld processing. Must be called every + * MLD6_TMR_INTERVAL milliseconds (100). + * + * When a delaying member expires, a membership report is sent. + */ +void +mld6_tmr(void) +{ + struct mld_group *group = mld_group_list; + + while (group != NULL) { + if (group->timer > 0) { + group->timer--; + if (group->timer == 0) { + /* If the state is MLD6_GROUP_DELAYING_MEMBER then we send a report for this group */ + if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { + MLD6_STATS_INC(mld6.tx_report); + mld6_send(group, ICMP6_TYPE_MLR); + group->group_state = MLD6_GROUP_IDLE_MEMBER; + } + } + } + group = group->next; + } +} + +/** + * Schedule a delayed membership report for a group + * + * @param group the mld_group for which "delaying" membership report + * should be sent + * @param maxresp the max resp delay provided in the query + */ +static void +mld6_delayed_report(struct mld_group *group, u16_t maxresp) +{ + /* Convert maxresp from milliseconds to tmr ticks */ + maxresp = maxresp / MLD6_TMR_INTERVAL; + if (maxresp == 0) { + maxresp = 1; + } + +#ifdef LWIP_RAND + /* Randomize maxresp. (if LWIP_RAND is supported) */ + maxresp = LWIP_RAND() % maxresp; + if (maxresp == 0) { + maxresp = 1; + } +#endif /* LWIP_RAND */ + + /* Apply timer value if no report has been scheduled already. */ + if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) || + ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && + ((group->timer == 0) || (maxresp < group->timer)))) { + group->timer = maxresp; + group->group_state = MLD6_GROUP_DELAYING_MEMBER; + } +} + +/** + * Send a MLD message (report or done). + * + * An IPv6 hop-by-hop options header with a router alert option + * is prepended. + * + * @param group the group to report or quit + * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done) + */ +static void +mld6_send(struct mld_group *group, u8_t type) +{ + struct mld_header * mld_hdr; + struct pbuf * p; + ip6_addr_t * src_addr; + + /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */ + p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr), PBUF_RAM); + if ((p == NULL) || (p->len < (sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr)))) { + /* We couldn't allocate a suitable pbuf. drop it. */ + if (p != NULL) { + pbuf_free(p); + } + MLD6_STATS_INC(mld6.memerr); + return; + } + + /* Move to make room for Hop-by-hop options header. */ + if (pbuf_header(p, -IP6_HBH_HLEN)) { + pbuf_free(p); + MLD6_STATS_INC(mld6.lenerr); + return; + } + + /* Select our source address. */ + if (!ip6_addr_isvalid(netif_ip6_addr_state(group->netif, 0))) { + /* This is a special case, when we are performing duplicate address detection. + * We must join the multicast group, but we don't have a valid address yet. */ + src_addr = IP6_ADDR_ANY; + } else { + /* Use link-local address as source address. */ + src_addr = netif_ip6_addr(group->netif, 0); + } + + /* MLD message header pointer. */ + mld_hdr = (struct mld_header *)p->payload; + + /* Set fields. */ + mld_hdr->type = type; + mld_hdr->code = 0; + mld_hdr->chksum = 0; + mld_hdr->max_resp_delay = 0; + mld_hdr->reserved = 0; + ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address)); + +#if CHECKSUM_GEN_ICMP6 + mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, + src_addr, &(group->group_address)); +#endif /* CHECKSUM_GEN_ICMP6 */ + + /* Add hop-by-hop headers options: router alert with MLD value. */ + ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD); + + /* Send the packet out. */ + MLD6_STATS_INC(mld6.xmit); + ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), + MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, group->netif); + pbuf_free(p); +} + + + +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/nd6.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/nd6.c new file mode 100644 index 0000000..2a46045 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/ipv6/nd6.c @@ -0,0 +1,1793 @@ +/** + * @file + * + * Neighbor discovery and stateless address autoconfiguration for IPv6. + * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 + * (Address autoconfiguration). + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/nd6.h" +#include "lwip/pbuf.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp6.h" +#include "lwip/mld6.h" +#include "lwip/lwip_ip.h" +#include "lwip/stats.h" + +#include + + +/* Router tables. */ +struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; +struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; +struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES]; +struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS]; + +/* Default values, can be updated by a RA message. */ +u32_t reachable_time = LWIP_ND6_REACHABLE_TIME; +u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* TODO implement this value in timer */ + +/* Index for cache entries. */ +static u8_t nd6_cached_neighbor_index; +static u8_t nd6_cached_destination_index; + +/* Multicast address holder. */ +static ip6_addr_t multicast_address; + +/* Static buffer to parse RA packet options (size of a prefix option, biggest option) */ +static u8_t nd6_ra_buffer[sizeof(struct prefix_option)]; + +/* Forward declarations. */ +static s8_t nd6_find_neighbor_cache_entry(ip6_addr_t * ip6addr); +static s8_t nd6_new_neighbor_cache_entry(void); +static void nd6_free_neighbor_cache_entry(s8_t i); +static s8_t nd6_find_destination_cache_entry(ip6_addr_t * ip6addr); +static s8_t nd6_new_destination_cache_entry(void); +static s8_t nd6_is_prefix_in_netif(ip6_addr_t * ip6addr, struct netif * netif); +static s8_t nd6_get_router(ip6_addr_t * router_addr, struct netif * netif); +static s8_t nd6_new_router(ip6_addr_t * router_addr, struct netif * netif); +static s8_t nd6_get_onlink_prefix(ip6_addr_t * prefix, struct netif * netif); +static s8_t nd6_new_onlink_prefix(ip6_addr_t * prefix, struct netif * netif); + +#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 +#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 +static void nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags); +static void nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags); +#if LWIP_IPV6_SEND_ROUTER_SOLICIT +static void nd6_send_rs(struct netif * netif); +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ + +#if LWIP_ND6_QUEUEING +static void nd6_free_q(struct nd6_q_entry *q); +#else /* LWIP_ND6_QUEUEING */ +#define nd6_free_q(q) pbuf_free(q) +#endif /* LWIP_ND6_QUEUEING */ +static void nd6_send_q(s8_t i); + + +/** + * Process an incoming neighbor discovery message + * + * @param p the nd packet, p->payload pointing to the icmpv6 header + * @param inp the netif on which this packet was received + */ +void +nd6_input(struct pbuf *p, struct netif *inp) +{ + u8_t msg_type; + s8_t i; + + ND6_STATS_INC(nd6.recv); + + msg_type = *((u8_t *)p->payload); + switch (msg_type) { + case ICMP6_TYPE_NA: /* Neighbor Advertisement. */ + { + struct na_header * na_hdr; + struct lladdr_option * lladdr_opt; + + /* Check that na header fits in packet. */ + if (p->len < (sizeof(struct na_header))) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + na_hdr = (struct na_header *)p->payload; + + /* Unsolicited NA?*/ + if (ip6_addr_ismulticast(ip6_current_dest_addr())) { + /* This is an unsolicited NA. + * link-layer changed? + * part of DAD mechanism? */ + + /* Check that link-layer address option also fits in packet. */ + if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); + + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ + ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); + +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS + /* If the target address matches this netif, it is a DAD response. */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { + /* We are using a duplicate address. */ + netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID); + +#if LWIP_IPV6_MLD + /* Leave solicited node multicast group. */ + ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(inp, i)->addr[3]); + mld6_leavegroup(netif_ip6_addr(inp, i), &multicast_address); +#endif /* LWIP_IPV6_MLD */ + + + + +#if LWIP_IPV6_AUTOCONFIG + /* Check to see if this address was autoconfigured. */ + if (!ip6_addr_islinklocal(ip6_current_dest_addr())) { + i = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp); + if (i >= 0) { + /* Mark this prefix as duplicate, so that we don't use it + * to generate this address again. */ + prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE; + } + } +#endif /* LWIP_IPV6_AUTOCONFIG */ + + pbuf_free(p); + return; + } + } +#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ + + /* This is an unsolicited NA, most likely there was a LLADDR change. */ + i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr()); + if (i >= 0) { + if (na_hdr->flags & ND6_FLAG_OVERRIDE) { + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + } + } + } + else { + /* This is a solicited NA. + * neighbor address resolution response? + * neighbor unreachability detection response? */ + + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ + ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); + + /* Find the cache entry corresponding to this na. */ + i = nd6_find_neighbor_cache_entry(ip6_current_dest_addr()); + if (i < 0) { + /* We no longer care about this target address. drop it. */ + pbuf_free(p); + return; + } + + /* Update cache entry. */ + neighbor_cache[i].netif = inp; + neighbor_cache[i].counter.reachable_time = reachable_time; + if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || + (neighbor_cache[i].state == ND6_INCOMPLETE)) { + /* Check that link-layer address option also fits in packet. */ + if (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option))) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); + + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + } + neighbor_cache[i].state = ND6_REACHABLE; + + /* Send queued packets, if any. */ + if (neighbor_cache[i].q != NULL) { + nd6_send_q(i); + } + } + + break; /* ICMP6_TYPE_NA */ + } + case ICMP6_TYPE_NS: /* Neighbor solicitation. */ + { + struct ns_header * ns_hdr; + struct lladdr_option * lladdr_opt; + u8_t accepted; + + /* Check that ns header fits in packet. */ + if (p->len < sizeof(struct ns_header)) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + ns_hdr = (struct ns_header *)p->payload; + + /* Check if there is a link-layer address provided. Only point to it if in this buffer. */ + lladdr_opt = NULL; + if (p->len >= (sizeof(struct ns_header) + sizeof(struct lladdr_option))) { + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); + } + + /* Check if the target address is configured on the receiving netif. */ + accepted = 0; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { + if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || + (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && + ip6_addr_isany(ip6_current_src_addr()))) && + ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { + accepted = 1; + break; + } + } + + /* NS not for us? */ + if (!accepted) { + pbuf_free(p); + return; + } + + /* Check for ANY address in src (DAD algorithm). */ + if (ip6_addr_isany(ip6_current_src_addr())) { + /* Sender is validating this address. */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { + if (ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { + /* Send a NA back so that the sender does not use this address. */ + nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST); + if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) { + /* We shouldn't use this address either. */ + netif_ip6_addr_set_state(inp, i, IP6_ADDR_INVALID); + } + } + } + } + else { + /* Sender is trying to resolve our address. */ + /* Verify that they included their own link-layer address. */ + if (lladdr_opt == NULL) { + /* Not a valid message. */ + pbuf_free(p); + ND6_STATS_INC(nd6.proterr); + ND6_STATS_INC(nd6.drop); + return; + } + + i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); + if ( i>= 0) { + /* We already have a record for the solicitor. */ + if (neighbor_cache[i].state == ND6_INCOMPLETE) { + neighbor_cache[i].netif = inp; + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + + /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */ + neighbor_cache[i].state = ND6_DELAY; + neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; + } + } + else + { + /* Add their IPv6 address and link-layer address to neighbor cache. + * We will need it at least to send a unicast NA message, but most + * likely we will also be communicating with this node soon. */ + i = nd6_new_neighbor_cache_entry(); + if (i < 0) { + /* We couldn't assign a cache entry for this neighbor. + * we won't be able to reply. drop it. */ + pbuf_free(p); + ND6_STATS_INC(nd6.memerr); + return; + } + neighbor_cache[i].netif = inp; + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); + + /* Receiving a message does not prove reachability: only in one direction. + * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ + neighbor_cache[i].state = ND6_DELAY; + neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; + } + + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ + ip6_addr_set(ip6_current_dest_addr(), &(ns_hdr->target_address)); + + /* Send back a NA for us. Allocate the reply pbuf. */ + nd6_send_na(inp, ip6_current_dest_addr(), ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE); + } + + break; /* ICMP6_TYPE_NS */ + } + case ICMP6_TYPE_RA: /* Router Advertisement. */ + { + struct ra_header * ra_hdr; + u8_t * buffer; /* Used to copy options. */ + u16_t offset; + + /* Check that RA header fits in packet. */ + if (p->len < sizeof(struct ra_header)) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + ra_hdr = (struct ra_header *)p->payload; + + /* If we are sending RS messages, stop. */ +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + inp->rs_count = 0; +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ + + /* Get the matching default router entry. */ + i = nd6_get_router(ip6_current_src_addr(), inp); + if (i < 0) { + /* Create a new router entry. */ + i = nd6_new_router(ip6_current_src_addr(), inp); + } + + if (i < 0) { + /* Could not create a new router entry. */ + pbuf_free(p); + ND6_STATS_INC(nd6.memerr); + return; + } + + /* Re-set invalidation timer. */ + default_router_list[i].invalidation_timer = ra_hdr->router_lifetime; + + /* Re-set default timer values. */ +#if LWIP_ND6_ALLOW_RA_UPDATES + if (ra_hdr->retrans_timer > 0) { + retrans_timer = ra_hdr->retrans_timer; + } + if (ra_hdr->reachable_time > 0) { + reachable_time = ra_hdr->reachable_time; + } +#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ + + /* TODO set default hop limit... */ + /* ra_hdr->current_hop_limit;*/ + + /* Update flags in local entry (incl. preference). */ + default_router_list[i].flags = ra_hdr->flags; + + /* Offset to options. */ + offset = sizeof(struct ra_header); + + /* Process each option. */ + while ((p->tot_len - offset) > 0) { + if (p->len == p->tot_len) { + /* no need to copy from contiguous pbuf */ + buffer = &((u8_t*)p->payload)[offset]; + } else { + buffer = nd6_ra_buffer; + pbuf_copy_partial(p, buffer, sizeof(struct prefix_option), offset); + } + switch (buffer[0]) { + case ND6_OPTION_TYPE_SOURCE_LLADDR: + { + struct lladdr_option * lladdr_opt; + lladdr_opt = (struct lladdr_option *)buffer; + if ((default_router_list[i].neighbor_entry != NULL) && + (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) { + SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len); + default_router_list[i].neighbor_entry->state = ND6_REACHABLE; + default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time; + } + break; + } + case ND6_OPTION_TYPE_MTU: + { + struct mtu_option * mtu_opt; + mtu_opt = (struct mtu_option *)buffer; + if (mtu_opt->mtu >= 1280) { +#if LWIP_ND6_ALLOW_RA_UPDATES + inp->mtu = mtu_opt->mtu; +#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ + } + break; + } + case ND6_OPTION_TYPE_PREFIX_INFO: + { + struct prefix_option * prefix_opt; + prefix_opt = (struct prefix_option *)buffer; + + if (prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) { + /* Add to on-link prefix list. */ + s8_t prefix; + + /* Get a memory-aligned copy of the prefix. */ + ip6_addr_set(ip6_current_dest_addr(), &(prefix_opt->prefix)); + + /* find cache entry for this prefix. */ + prefix = nd6_get_onlink_prefix(ip6_current_dest_addr(), inp); + if (prefix < 0) { + /* Create a new cache entry. */ + prefix = nd6_new_onlink_prefix(ip6_current_dest_addr(), inp); + } + if (prefix >= 0) { + prefix_list[prefix].invalidation_timer = prefix_opt->valid_lifetime; + +#if LWIP_IPV6_AUTOCONFIG + if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) { + /* Mark prefix as autonomous, so that address autoconfiguration can take place. + * Only OR flag, so that we don't over-write other flags (such as ADDRESS_DUPLICATE)*/ + prefix_list[prefix].flags |= ND6_PREFIX_AUTOCONFIG_AUTONOMOUS; + } +#endif /* LWIP_IPV6_AUTOCONFIG */ + } + } + + break; + } + case ND6_OPTION_TYPE_ROUTE_INFO: + { + /* TODO implement preferred routes. + struct route_option * route_opt; + route_opt = (struct route_option *)buffer;*/ + + break; + } + default: + /* Unrecognized option, abort. */ + ND6_STATS_INC(nd6.proterr); + break; + } + offset += 8 * ((u16_t)buffer[1]); + } + + break; /* ICMP6_TYPE_RA */ + } + case ICMP6_TYPE_RD: /* Redirect */ + { + struct redirect_header * redir_hdr; + struct lladdr_option * lladdr_opt; + + /* Check that Redir header fits in packet. */ + if (p->len < sizeof(struct redirect_header)) { + /* TODO debug message */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + redir_hdr = (struct redirect_header *)p->payload; + + lladdr_opt = NULL; + if (p->len >= (sizeof(struct redirect_header) + sizeof(struct lladdr_option))) { + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header)); + } + + /* Copy original destination address to current source address, to have an aligned copy. */ + ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->destination_address)); + + /* Find dest address in cache */ + i = nd6_find_destination_cache_entry(ip6_current_src_addr()); + if (i < 0) { + /* Destination not in cache, drop packet. */ + pbuf_free(p); + return; + } + + /* Set the new target address. */ + ip6_addr_set(&(destination_cache[i].next_hop_addr), &(redir_hdr->target_address)); + + /* If Link-layer address of other router is given, try to add to neighbor cache. */ + if (lladdr_opt != NULL) { + if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) { + /* Copy target address to current source address, to have an aligned copy. */ + ip6_addr_set(ip6_current_src_addr(), &(redir_hdr->target_address)); + + i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); + if (i < 0) { + i = nd6_new_neighbor_cache_entry(); + if (i >= 0) { + neighbor_cache[i].netif = inp; + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); + + /* Receiving a message does not prove reachability: only in one direction. + * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ + neighbor_cache[i].state = ND6_DELAY; + neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; + } + } + if (i >= 0) { + if (neighbor_cache[i].state == ND6_INCOMPLETE) { + MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); + /* Receiving a message does not prove reachability: only in one direction. + * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ + neighbor_cache[i].state = ND6_DELAY; + neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME; + } + } + } + } + break; /* ICMP6_TYPE_RD */ + } + case ICMP6_TYPE_PTB: /* Packet too big */ + { + struct icmp6_hdr *icmp6hdr; /* Packet too big message */ + struct ip6_hdr * ip6hdr; /* IPv6 header of the packet which caused the error */ + + /* Check that ICMPv6 header + IPv6 header fit in payload */ + if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) { + /* drop short packets */ + pbuf_free(p); + ND6_STATS_INC(nd6.lenerr); + ND6_STATS_INC(nd6.drop); + return; + } + + icmp6hdr = (struct icmp6_hdr *)p->payload; + ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr)); + + /* Copy original destination address to current source address, to have an aligned copy. */ + ip6_addr_set(ip6_current_src_addr(), &(ip6hdr->dest)); + + /* Look for entry in destination cache. */ + i = nd6_find_destination_cache_entry(ip6_current_src_addr()); + if (i < 0) { + /* Destination not in cache, drop packet. */ + pbuf_free(p); + return; + } + + /* Change the Path MTU. */ + destination_cache[i].pmtu = icmp6hdr->data; + + break; /* ICMP6_TYPE_PTB */ + } + + default: + ND6_STATS_INC(nd6.proterr); + ND6_STATS_INC(nd6.drop); + break; /* default */ + } + + pbuf_free(p); +} + + +/** + * Periodic timer for Neighbor discovery functions: + * + * - Update neighbor reachability states + * - Update destination cache entries age + * - Update invalidation timers of default routers and on-link prefixes + * - Perform duplicate address detection (DAD) for our addresses + * - Send router solicitations + */ +void +nd6_tmr(void) +{ + s8_t i, j; + struct netif * netif; + + /* Process neighbor entries. */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + switch (neighbor_cache[i].state) { + case ND6_INCOMPLETE: + if (neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) { + /* Retries exceeded. */ + nd6_free_neighbor_cache_entry(i); + } + else { + /* Send a NS for this entry. */ + neighbor_cache[i].counter.probes_sent++; + nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), ND6_SEND_FLAG_MULTICAST_DEST); + } + break; + case ND6_REACHABLE: + /* Send queued packets, if any are left. Should have been sent already. */ + if (neighbor_cache[i].q != NULL) { + nd6_send_q(i); + } + if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) { + /* Change to stale state. */ + neighbor_cache[i].state = ND6_STALE; + neighbor_cache[i].counter.stale_time = 0; + } + else { + neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL; + } + break; + case ND6_STALE: + neighbor_cache[i].counter.stale_time += ND6_TMR_INTERVAL; + break; + case ND6_DELAY: + if (neighbor_cache[i].counter.delay_time <= ND6_TMR_INTERVAL) { + /* Change to PROBE state. */ + neighbor_cache[i].state = ND6_PROBE; + neighbor_cache[i].counter.probes_sent = 0; + } + else { + neighbor_cache[i].counter.delay_time -= ND6_TMR_INTERVAL; + } + break; + case ND6_PROBE: + if (neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) { + /* Retries exceeded. */ + nd6_free_neighbor_cache_entry(i); + } + else { + /* Send a NS for this entry. */ + neighbor_cache[i].counter.probes_sent++; + nd6_send_ns(neighbor_cache[i].netif, &(neighbor_cache[i].next_hop_address), 0); + } + break; + case ND6_NO_ENTRY: + default: + /* Do nothing. */ + break; + } + } + + /* Process destination entries. */ + for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { + destination_cache[i].age++; + } + + /* Process router entries. */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if (default_router_list[i].neighbor_entry != NULL) { + /* Active entry. */ + if (default_router_list[i].invalidation_timer > 0) { + default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; + } + if (default_router_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) { + /* Less than 1 second remaining. Clear this entry. */ + default_router_list[i].neighbor_entry->isrouter = 0; + default_router_list[i].neighbor_entry = NULL; + default_router_list[i].invalidation_timer = 0; + default_router_list[i].flags = 0; + } + } + } + + /* Process prefix entries. */ + for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { + if (prefix_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) { + prefix_list[i].invalidation_timer = 0; + } + if ((prefix_list[i].invalidation_timer > 0) && + (prefix_list[i].netif != NULL)) { + prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; + +#if LWIP_IPV6_AUTOCONFIG + /* Initiate address autoconfiguration for this prefix, if conditions are met. */ + if (prefix_list[i].netif->ip6_autoconfig_enabled && + (prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_AUTONOMOUS) && + !(prefix_list[i].flags & ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED)) { + /* Try to get an address on this netif that is invalid. + * Skip 0 index (link-local address) */ + for (j = 1; j < LWIP_IPV6_NUM_ADDRESSES; j++) { + if (netif_ip6_addr_state(prefix_list[i].netif, j) == IP6_ADDR_INVALID) { + /* Generate an address using this prefix and interface ID from link-local address. */ + prefix_list[i].netif->ip6_addr[j].addr[0] = prefix_list[i].prefix.addr[0]; + prefix_list[i].netif->ip6_addr[j].addr[1] = prefix_list[i].prefix.addr[1]; + prefix_list[i].netif->ip6_addr[j].addr[2] = prefix_list[i].netif->ip6_addr[0].addr[2]; + prefix_list[i].netif->ip6_addr[j].addr[3] = prefix_list[i].netif->ip6_addr[0].addr[3]; + + /* Mark it as tentative (DAD will be performed if configured). */ + netif_ip6_addr_set_state(prefix_list[i].netif, j, IP6_ADDR_TENTATIVE); + + /* Mark this prefix with ADDRESS_GENERATED, so that we don't try again. */ + prefix_list[i].flags |= ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED; + + /* Exit loop. */ + break; + } + } + } +#endif /* LWIP_IPV6_AUTOCONFIG */ + } + } + + + /* Process our own addresses, if DAD configured. */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { + if (ip6_addr_istentative(netif->ip6_addr_state[i])) { + if ((netif->ip6_addr_state[i] & 0x07) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { + /* No NA received in response. Mark address as valid. */ + netif->ip6_addr_state[i] = IP6_ADDR_PREFERRED; + /* TODO implement preferred and valid lifetimes. */ + } + else if (netif->flags & NETIF_FLAG_UP) { +#if LWIP_IPV6_MLD + if ((netif->ip6_addr_state[i] & 0x07) == 0) { + /* Join solicited node multicast group. */ + ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, i)->addr[3]); + mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address); + } +#endif /* LWIP_IPV6_MLD */ + /* Send a NS for this address. */ + nd6_send_ns(netif, netif_ip6_addr(netif, i), ND6_SEND_FLAG_MULTICAST_DEST); + (netif->ip6_addr_state[i])++; + /* TODO send max 1 NS per tmr call? enable return*/ + /*return;*/ + } + } + } + } + +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + /* Send router solicitation messages, if necessary. */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + if ((netif->rs_count > 0) && (netif->flags & NETIF_FLAG_UP)) { + nd6_send_rs(netif); + netif->rs_count--; + } + } +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ + +} + +/** + * Send a neighbor solicitation message + * + * @param netif the netif on which to send the message + * @param target_addr the IPv6 target address for the ND message + * @param flags one of ND6_SEND_FLAG_* + */ +static void +nd6_send_ns(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) +{ + struct ns_header * ns_hdr; + struct lladdr_option * lladdr_opt; + struct pbuf * p; + ip6_addr_t * src_addr; + + if (ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) { + /* Use link-local address as source address. */ + src_addr = netif_ip6_addr(netif, 0); + } else { + src_addr = IP6_ADDR_ANY; + } + + /* Allocate a packet. */ + p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + sizeof(struct lladdr_option), PBUF_RAM); + if ((p == NULL) || (p->len < (sizeof(struct ns_header) + sizeof(struct lladdr_option)))) { + /* We couldn't allocate a suitable pbuf for the ns. drop it. */ + if (p != NULL) { + pbuf_free(p); + } + ND6_STATS_INC(nd6.memerr); + return; + } + + /* Set fields. */ + ns_hdr = (struct ns_header *)p->payload; + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); + + ns_hdr->type = ICMP6_TYPE_NS; + ns_hdr->code = 0; + ns_hdr->chksum = 0; + ns_hdr->reserved = 0; + ip6_addr_set(&(ns_hdr->target_address), target_addr); + + lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; + lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); + SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); + + /* Generate the solicited node address for the target address. */ + if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { + ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); + target_addr = &multicast_address; + } + +#if CHECKSUM_GEN_ICMP6 + ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + target_addr); +#endif /* CHECKSUM_GEN_ICMP6 */ + + /* Send the packet out. */ + ND6_STATS_INC(nd6.xmit); + ip6_output_if(p, (src_addr == IP6_ADDR_ANY) ? NULL : src_addr, target_addr, + LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); + pbuf_free(p); +} + +/** + * Send a neighbor advertisement message + * + * @param netif the netif on which to send the message + * @param target_addr the IPv6 target address for the ND message + * @param flags one of ND6_SEND_FLAG_* + */ +static void +nd6_send_na(struct netif * netif, ip6_addr_t * target_addr, u8_t flags) +{ + struct na_header * na_hdr; + struct lladdr_option * lladdr_opt; + struct pbuf * p; + ip6_addr_t * src_addr; + ip6_addr_t * dest_addr; + + /* Use link-local address as source address. */ + /* src_addr = &(netif->ip6_addr[0]); */ + /* Use target address as source address. */ + src_addr = target_addr; + + /* Allocate a packet. */ + p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + sizeof(struct lladdr_option), PBUF_RAM); + if ((p == NULL) || (p->len < (sizeof(struct na_header) + sizeof(struct lladdr_option)))) { + /* We couldn't allocate a suitable pbuf for the ns. drop it. */ + if (p != NULL) { + pbuf_free(p); + } + ND6_STATS_INC(nd6.memerr); + return; + } + + /* Set fields. */ + na_hdr = (struct na_header *)p->payload; + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); + + na_hdr->type = ICMP6_TYPE_NA; + na_hdr->code = 0; + na_hdr->chksum = 0; + na_hdr->flags = flags & 0xf0; + na_hdr->reserved[0] = 0; + na_hdr->reserved[1] = 0; + na_hdr->reserved[2] = 0; + ip6_addr_set(&(na_hdr->target_address), target_addr); + + lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR; + lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); + SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); + + /* Generate the solicited node address for the target address. */ + if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { + ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); + dest_addr = &multicast_address; + } + else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) { + ip6_addr_set_allnodes_linklocal(&multicast_address); + dest_addr = &multicast_address; + } + else { + dest_addr = ip6_current_src_addr(); + } + +#if CHECKSUM_GEN_ICMP6 + na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + dest_addr); +#endif /* CHECKSUM_GEN_ICMP6 */ + + /* Send the packet out. */ + ND6_STATS_INC(nd6.xmit); + ip6_output_if(p, src_addr, dest_addr, + LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); + pbuf_free(p); +} + +#if LWIP_IPV6_SEND_ROUTER_SOLICIT +/** + * Send a router solicitation message + * + * @param netif the netif on which to send the message + */ +static void +nd6_send_rs(struct netif * netif) +{ + struct rs_header * rs_hdr; + struct lladdr_option * lladdr_opt; + struct pbuf * p; + ip6_addr_t * src_addr; + u16_t packet_len; + + /* Link-local source address, or unspecified address? */ + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { + src_addr = netif_ip6_addr(netif, 0); + } + else { + src_addr = IP6_ADDR_ANY; + } + + /* Generate the all routers target address. */ + ip6_addr_set_allrouters_linklocal(&multicast_address); + + /* Allocate a packet. */ + packet_len = sizeof(struct rs_header); + if (src_addr != IP6_ADDR_ANY) { + packet_len += sizeof(struct lladdr_option); + } + p = pbuf_alloc(PBUF_IP, packet_len, PBUF_RAM); + if ((p == NULL) || (p->len < packet_len)) { + /* We couldn't allocate a suitable pbuf for the ns. drop it. */ + if (p != NULL) { + pbuf_free(p); + } + ND6_STATS_INC(nd6.memerr); + return; + } + + /* Set fields. */ + rs_hdr = (struct rs_header *)p->payload; + + rs_hdr->type = ICMP6_TYPE_RS; + rs_hdr->code = 0; + rs_hdr->chksum = 0; + rs_hdr->reserved = 0; + + if (src_addr != IP6_ADDR_ANY) { + /* Include our hw address. */ + lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header)); + lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; + lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); + SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); + } + +#if CHECKSUM_GEN_ICMP6 + rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, + &multicast_address); +#endif /* CHECKSUM_GEN_ICMP6 */ + + /* Send the packet out. */ + ND6_STATS_INC(nd6.xmit); + ip6_output_if(p, src_addr, &multicast_address, + LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); + pbuf_free(p); +} +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ + +/** + * Search for a neighbor cache entry + * + * @param ip6addr the IPv6 address of the neighbor + * @return The neighbor cache entry index that matched, -1 if no + * entry is found + */ +static s8_t +nd6_find_neighbor_cache_entry(ip6_addr_t * ip6addr) +{ + s8_t i; + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) { + return i; + } + } + return -1; +} + +/** + * Create a new neighbor cache entry. + * + * If no unused entry is found, will try to recycle an old entry + * according to ad-hoc "age" heuristic. + * + * @return The neighbor cache entry index that was created, -1 if no + * entry could be created + */ +static s8_t +nd6_new_neighbor_cache_entry(void) +{ + s8_t i; + s8_t j; + u32_t time; + + + /* First, try to find an empty entry. */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if (neighbor_cache[i].state == ND6_NO_ENTRY) { + return i; + } + } + + /* We need to recycle an entry. in general, do not recycle if it is a router. */ + + /* Next, try to find a Stale entry. */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ((neighbor_cache[i].state == ND6_STALE) && + (!neighbor_cache[i].isrouter)) { + nd6_free_neighbor_cache_entry(i); + return i; + } + } + + /* Next, try to find a Probe entry. */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ((neighbor_cache[i].state == ND6_PROBE) && + (!neighbor_cache[i].isrouter)) { + nd6_free_neighbor_cache_entry(i); + return i; + } + } + + /* Next, try to find a Delayed entry. */ + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ((neighbor_cache[i].state == ND6_DELAY) && + (!neighbor_cache[i].isrouter)) { + nd6_free_neighbor_cache_entry(i); + return i; + } + } + + /* Next, try to find the oldest reachable entry. */ + time = 0xfffffffful; + j = -1; + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ((neighbor_cache[i].state == ND6_REACHABLE) && + (!neighbor_cache[i].isrouter)) { + if (neighbor_cache[i].counter.reachable_time < time) { + j = i; + time = neighbor_cache[i].counter.reachable_time; + } + } + } + if (j >= 0) { + nd6_free_neighbor_cache_entry(j); + return j; + } + + /* Next, find oldest incomplete entry without queued packets. */ + time = 0; + j = -1; + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ( + (neighbor_cache[i].q == NULL) && + (neighbor_cache[i].state == ND6_INCOMPLETE) && + (!neighbor_cache[i].isrouter)) { + if (neighbor_cache[i].counter.probes_sent >= time) { + j = i; + time = neighbor_cache[i].counter.probes_sent; + } + } + } + if (j >= 0) { + nd6_free_neighbor_cache_entry(j); + return j; + } + + /* Next, find oldest incomplete entry with queued packets. */ + time = 0; + j = -1; + for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { + if ((neighbor_cache[i].state == ND6_INCOMPLETE) && + (!neighbor_cache[i].isrouter)) { + if (neighbor_cache[i].counter.probes_sent >= time) { + j = i; + time = neighbor_cache[i].counter.probes_sent; + } + } + } + if (j >= 0) { + nd6_free_neighbor_cache_entry(j); + return j; + } + + /* No more entries to try. */ + return -1; +} + +/** + * Will free any resources associated with a neighbor cache + * entry, and will mark it as unused. + * + * @param i the neighbor cache entry index to free + */ +static void +nd6_free_neighbor_cache_entry(s8_t i) +{ + if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { + return; + } + + /* Free any queued packets. */ + if (neighbor_cache[i].q != NULL) { + nd6_free_q(neighbor_cache[i].q); + neighbor_cache[i].q = NULL; + } + + neighbor_cache[i].state = ND6_NO_ENTRY; + neighbor_cache[i].isrouter = 0; + neighbor_cache[i].netif = NULL; + neighbor_cache[i].counter.reachable_time = 0; + ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address)); +} + +/** + * Search for a destination cache entry + * + * @param ip6addr the IPv6 address of the destination + * @return The destination cache entry index that matched, -1 if no + * entry is found + */ +static s8_t +nd6_find_destination_cache_entry(ip6_addr_t * ip6addr) +{ + s8_t i; + for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { + if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) { + return i; + } + } + return -1; +} + +/** + * Create a new destination cache entry. If no unused entry is found, + * will recycle oldest entry. + * + * @return The destination cache entry index that was created, -1 if no + * entry was created + */ +static s8_t +nd6_new_destination_cache_entry(void) +{ + s8_t i, j; + u32_t age; + + /* Find an empty entry. */ + for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { + if (ip6_addr_isany(&(destination_cache[i].destination_addr))) { + return i; + } + } + + /* Find oldest entry. */ + age = 0; + j = LWIP_ND6_NUM_DESTINATIONS - 1; + for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { + if (destination_cache[i].age > age) { + j = i; + } + } + + return j; +} + +/** + * Determine whether an address matches an on-link prefix. + * + * @param ip6addr the IPv6 address to match + * @return 1 if the address is on-link, 0 otherwise + */ +static s8_t +nd6_is_prefix_in_netif(ip6_addr_t * ip6addr, struct netif * netif) +{ + s8_t i; + for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { + if ((prefix_list[i].netif == netif) && + (prefix_list[i].invalidation_timer > 0) && + ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { + return 1; + } + } + /* Check to see if address prefix matches a (manually?) configured address. */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { + return 1; + } + } + return 0; +} + +/** + * Select a default router for a destination. + * + * @param ip6addr the destination address + * @param netif the netif for the outgoing packet, if known + * @return the default router entry index, or -1 if no suitable + * router is found + */ +s8_t +nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif) +{ + s8_t i; + /* last_router is used for round-robin router selection (as recommended + * in RFC). This is more robust in case one router is not reachable, + * we are not stuck trying to resolve it. */ + static s8_t last_router; + (void)ip6addr; /* TODO match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */ + + /* TODO: implement default router preference */ + + /* Look for reachable routers. */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if (++last_router >= LWIP_ND6_NUM_ROUTERS) { + last_router = 0; + } + if ((default_router_list[i].neighbor_entry != NULL) && + (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) && + (default_router_list[i].invalidation_timer > 0) && + (default_router_list[i].neighbor_entry->state == ND6_REACHABLE)) { + return i; + } + } + + /* Look for router in other reachability states, but still valid according to timer. */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if (++last_router >= LWIP_ND6_NUM_ROUTERS) { + last_router = 0; + } + if ((default_router_list[i].neighbor_entry != NULL) && + (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1) && + (default_router_list[i].invalidation_timer > 0)) { + return i; + } + } + + /* Look for any router for which we have any information at all. */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if (++last_router >= LWIP_ND6_NUM_ROUTERS) { + last_router = 0; + } + if (default_router_list[i].neighbor_entry != NULL && + (netif != NULL ? netif == default_router_list[i].neighbor_entry->netif : 1)) { + return i; + } + } + + /* no suitable router found. */ + return -1; +} + +/** + * Find an entry for a default router. + * + * @param router_addr the IPv6 address of the router + * @param netif the netif on which the router is found, if known + * @return the index of the router entry, or -1 if not found + */ +static s8_t +nd6_get_router(ip6_addr_t * router_addr, struct netif * netif) +{ + s8_t i; + + /* Look for router. */ + for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { + if ((default_router_list[i].neighbor_entry != NULL) && + ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) && + ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) { + return i; + } + } + + /* router not found. */ + return -1; +} + +/** + * Create a new entry for a default router. + * + * @param router_addr the IPv6 address of the router + * @param netif the netif on which the router is connected, if known + * @return the index on the router table, or -1 if could not be created + */ +static s8_t +nd6_new_router(ip6_addr_t * router_addr, struct netif * netif) +{ + s8_t router_index; + s8_t neighbor_index; + + /* Do we have a neighbor entry for this router? */ + neighbor_index = nd6_find_neighbor_cache_entry(router_addr); + if (neighbor_index < 0) { + /* Create a neighbor entry for this router. */ + neighbor_index = nd6_new_neighbor_cache_entry(); + if (neighbor_index < 0) { + /* Could not create neighbor entry for this router. */ + return -1; + } + ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr); + neighbor_cache[neighbor_index].netif = netif; + neighbor_cache[neighbor_index].q = NULL; + neighbor_cache[neighbor_index].state = ND6_INCOMPLETE; + neighbor_cache[neighbor_index].counter.probes_sent = 0; + } + + /* Mark neighbor as router. */ + neighbor_cache[neighbor_index].isrouter = 1; + + /* Look for empty entry. */ + for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) { + if (default_router_list[router_index].neighbor_entry == NULL) { + default_router_list[router_index].neighbor_entry = &(neighbor_cache[neighbor_index]); + return router_index; + } + } + + /* Could not create a router entry. */ + + /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */ + neighbor_cache[neighbor_index].isrouter = 0; + + /* router not found. */ + return -1; +} + +/** + * Find the cached entry for an on-link prefix. + * + * @param prefix the IPv6 prefix that is on-link + * @param netif the netif on which the prefix is on-link + * @return the index on the prefix table, or -1 if not found + */ +static s8_t +nd6_get_onlink_prefix(ip6_addr_t * prefix, struct netif * netif) +{ + s8_t i; + + /* Look for prefix in list. */ + for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { + if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && + (prefix_list[i].netif == netif)) { + return i; + } + } + + /* Entry not available. */ + return -1; +} + +/** + * Creates a new entry for an on-link prefix. + * + * @param prefix the IPv6 prefix that is on-link + * @param netif the netif on which the prefix is on-link + * @return the index on the prefix table, or -1 if not created + */ +static s8_t +nd6_new_onlink_prefix(ip6_addr_t * prefix, struct netif * netif) +{ + s8_t i; + + /* Create new entry. */ + for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { + if ((prefix_list[i].netif == NULL) || + (prefix_list[i].invalidation_timer == 0)) { + /* Found empty prefix entry. */ + prefix_list[i].netif = netif; + ip6_addr_set(&(prefix_list[i].prefix), prefix); + prefix_list[i].flags = 0; + return i; + } + } + + /* Entry not available. */ + return -1; +} + +/** + * Determine the next hop for a destination. Will determine if the + * destination is on-link, else a suitable on-link router is selected. + * + * The last entry index is cached for fast entry search. + * + * @param ip6addr the destination address + * @param netif the netif on which the packet will be sent + * @return the neighbor cache entry for the next hop, ERR_RTE if no + * suitable next hop was found, ERR_MEM if no cache entry + * could be created + */ +s8_t +nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif) +{ + s8_t i; + +#if LWIP_NETIF_HWADDRHINT + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t addr_hint = *(netif->addr_hint); + if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { + nd6_cached_destination_index = addr_hint; + } + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* Look for ip6addr in destination cache. */ + if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { + /* the cached entry index is the right one! */ + /* do nothing. */ + ND6_STATS_INC(nd6.cachehit); + } else { + /* Search destination cache. */ + i = nd6_find_destination_cache_entry(ip6addr); + if (i >= 0) { + /* found destination entry. make it our new cached index. */ + nd6_cached_destination_index = i; + } + else { + /* Not found. Create a new destination entry. */ + i = nd6_new_destination_cache_entry(); + if (i >= 0) { + /* got new destination entry. make it our new cached index. */ + nd6_cached_destination_index = i; + } else { + /* Could not create a destination cache entry. */ + return ERR_MEM; + } + + /* Copy dest address to destination cache. */ + ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); + + /* Now find the next hop. is it a neighbor? */ + if (ip6_addr_islinklocal(ip6addr) || + nd6_is_prefix_in_netif(ip6addr, netif)) { + /* Destination in local link. */ + destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; + ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); + } + else { + /* We need to select a router. */ + i = nd6_select_router(ip6addr, netif); + if (i < 0) { + /* No router found. */ + ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); + return ERR_RTE; + } + destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; /* Start with netif mtu, correct through ICMPv6 if necessary */ + ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); + } + } + } + +#if LWIP_NETIF_HWADDRHINT + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + *(netif->addr_hint) = nd6_cached_destination_index; + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* Look in neighbor cache for the next-hop address. */ + if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr), + &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { + /* Cache hit. */ + /* Do nothing. */ + ND6_STATS_INC(nd6.cachehit); + } else { + i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr)); + if (i >= 0) { + /* Found a matching record, make it new cached entry. */ + nd6_cached_neighbor_index = i; + } + else { + /* Neighbor not in cache. Make a new entry. */ + i = nd6_new_neighbor_cache_entry(); + if (i >= 0) { + /* got new neighbor entry. make it our new cached index. */ + nd6_cached_neighbor_index = i; + } else { + /* Could not create a neighbor cache entry. */ + return ERR_MEM; + } + + /* Initialize fields. */ + ip6_addr_copy(neighbor_cache[i].next_hop_address, + destination_cache[nd6_cached_destination_index].next_hop_addr); + neighbor_cache[i].isrouter = 0; + neighbor_cache[i].netif = netif; + neighbor_cache[i].state = ND6_INCOMPLETE; + neighbor_cache[i].counter.probes_sent = 0; + } + } + + /* Reset this destination's age. */ + destination_cache[nd6_cached_destination_index].age = 0; + + return nd6_cached_neighbor_index; +} + +/** + * Queue a packet for a neighbor. + * + * @param neighbor_index the index in the neighbor cache table + * @param q packet to be queued + * @return ERR_OK if succeeded, ERR_MEM if out of memory + */ +err_t +nd6_queue_packet(s8_t neighbor_index, struct pbuf * q) +{ + err_t result = ERR_MEM; + struct pbuf *p; + int copy_needed = 0; +#if LWIP_ND6_QUEUEING + struct nd6_q_entry *new_entry, *r; +#endif /* LWIP_ND6_QUEUEING */ + + if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { + return ERR_ARG; + } + + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + while (p) { + if(p->type != PBUF_ROM) { + copy_needed = 1; + break; + } + p = p->next; + } + if(copy_needed) { + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); + while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { + /* Free oldest packet (as per RFC recommendation) */ +#if LWIP_ND6_QUEUEING + r = neighbor_cache[neighbor_index].q; + neighbor_cache[neighbor_index].q = r->next; + r->next = NULL; + nd6_free_q(r); +#else /* LWIP_ND6_QUEUEING */ + pbuf_free(neighbor_cache[neighbor_index].q); + neighbor_cache[neighbor_index].q = NULL; +#endif /* LWIP_ND6_QUEUEING */ + p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); + } + if(p != NULL) { + if (pbuf_copy(p, q) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + pbuf_ref(p); + } + /* packet was copied/ref'd? */ + if (p != NULL) { + /* queue packet ... */ +#if LWIP_ND6_QUEUEING + /* allocate a new nd6 queue entry */ + new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); + if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { + /* Free oldest packet (as per RFC recommendation) */ + r = neighbor_cache[neighbor_index].q; + neighbor_cache[neighbor_index].q = r->next; + r->next = NULL; + nd6_free_q(r); + new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); + } + if (new_entry != NULL) { + new_entry->next = NULL; + new_entry->p = p; + if(neighbor_cache[neighbor_index].q != NULL) { + /* queue was already existent, append the new entry to the end */ + r = neighbor_cache[neighbor_index].q; + while (r->next != NULL) { + r = r->next; + } + r->next = new_entry; + } else { + /* queue did not exist, first item in queue */ + neighbor_cache[neighbor_index].q = new_entry; + } + LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); + result = ERR_OK; + } else { + /* the pool MEMP_ND6_QUEUE is empty */ + pbuf_free(p); + LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p)); + /* { result == ERR_MEM } through initialization */ + } +#else /* LWIP_ND6_QUEUEING */ + /* Queue a single packet. If an older packet is already queued, free it as per RFC. */ + if (neighbor_cache[neighbor_index].q != NULL) { + pbuf_free(neighbor_cache[neighbor_index].q); + } + neighbor_cache[neighbor_index].q = p; + LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); + result = ERR_OK; +#endif /* LWIP_ND6_QUEUEING */ + } else { + LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q)); + /* { result == ERR_MEM } through initialization */ + } + + return result; +} + +#if LWIP_ND6_QUEUEING +/** + * Free a complete queue of nd6 q entries + * + * @param q a queue of nd6_q_entry to free + */ +static void +nd6_free_q(struct nd6_q_entry *q) +{ + struct nd6_q_entry *r; + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("q->p != NULL", q->p != NULL); + while (q) { + r = q; + q = q->next; + LWIP_ASSERT("r->p != NULL", (r->p != NULL)); + pbuf_free(r->p); + memp_free(MEMP_ND6_QUEUE, r); + } +} +#endif /* LWIP_ND6_QUEUEING */ + +/** + * Send queued packets for a neighbor + * + * @param i the neighbor to send packets to + */ +static void +nd6_send_q(s8_t i) +{ + struct ip6_hdr *ip6hdr; +#if LWIP_ND6_QUEUEING + struct nd6_q_entry *q; +#endif /* LWIP_ND6_QUEUEING */ + + if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { + return; + } + +#if LWIP_ND6_QUEUEING + while (neighbor_cache[i].q != NULL) { + /* remember first in queue */ + q = neighbor_cache[i].q; + /* pop first item off the queue */ + neighbor_cache[i].q = q->next; + /* Get ipv6 header. */ + ip6hdr = (struct ip6_hdr *)(q->p->payload); + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ + ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest)); + /* send the queued IPv6 packet */ + (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, ip6_current_dest_addr()); + /* free the queued IP packet */ + pbuf_free(q->p); + /* now queue entry can be freed */ + memp_free(MEMP_ND6_QUEUE, q); + } +#else /* LWIP_ND6_QUEUEING */ + if (neighbor_cache[i].q != NULL) { + /* Get ipv6 header. */ + ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload); + /* Override ip6_current_dest_addr() so that we have an aligned copy. */ + ip6_addr_set(ip6_current_dest_addr(), &(ip6hdr->dest)); + /* send the queued IPv6 packet */ + (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, ip6_current_dest_addr()); + /* free the queued IP packet */ + pbuf_free(neighbor_cache[i].q); + neighbor_cache[i].q = NULL; + } +#endif /* LWIP_ND6_QUEUEING */ +} + + +/** + * Get the Path MTU for a destination. + * + * @param ip6addr the destination address + * @param netif the netif on which the packet will be sent + * @return the Path MTU, if known, or the netif default MTU + */ +u16_t +nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif) +{ + s8_t i; + + i = nd6_find_destination_cache_entry(ip6addr); + if (i >= 0) { + if (destination_cache[i].pmtu > 0) { + return destination_cache[i].pmtu; + } + } + + if (netif != NULL) { + return netif->mtu; + } + + return 1280; /* Minimum MTU */ +} + + +#if LWIP_ND6_TCP_REACHABILITY_HINTS +/** + * Provide the Neighbor discovery process with a hint that a + * destination is reachable. Called by tcp_receive when ACKs are + * received or sent (as per RFC). This is useful to avoid sending + * NS messages every 30 seconds. + * + * @param ip6addr the destination address which is know to be reachable + * by an upper layer protocol (TCP) + */ +void +nd6_reachability_hint(ip6_addr_t * ip6addr) +{ + s8_t i; + + /* Find destination in cache. */ + if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { + i = nd6_cached_destination_index; + ND6_STATS_INC(nd6.cachehit); + } + else { + i = nd6_find_destination_cache_entry(ip6addr); + } + if (i < 0) { + return; + } + + /* Find next hop neighbor in cache. */ + if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { + i = nd6_cached_neighbor_index; + ND6_STATS_INC(nd6.cachehit); + } + else { + i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr)); + } + if (i < 0) { + return; + } + + /* Set reachability state. */ + neighbor_cache[i].state = ND6_REACHABLE; + neighbor_cache[i].counter.reachable_time = reachable_time; +} +#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ + +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/lwip_timers.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/lwip_timers.c new file mode 100644 index 0000000..b18e528 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/lwip_timers.c @@ -0,0 +1,562 @@ +/** + * @file + * Stack-internal timers implementation. + * This file includes timer callbacks for stack-internal timers as well as + * functions to set up or stop timers and check for expired timers. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#include "lwip/lwip_timers.h" +#include "lwip/tcp_impl.h" + +#if LWIP_TIMERS + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/tcpip.h" + +#include "lwip/ip_frag.h" +#include "netif/etharp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "lwip/igmp.h" +#include "lwip/dns.h" +#include "lwip/nd6.h" +#include "lwip/ip6_frag.h" +#include "lwip/mld6.h" +#include "lwip/sys.h" +#include "lwip/pbuf.h" + +/** The one and only timeout list */ +static struct sys_timeo *next_timeout; +#if NO_SYS +static u32_t timeouts_last_time; +#endif /* NO_SYS */ + +#if LWIP_TCP +/** global variable that shows if the tcp timer is currently scheduled or not */ +static int tcpip_tcp_timer_active; + +/** + * Timer callback function that calls tcp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +tcpip_tcp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + + /* call TCP timer handler */ + tcp_tmr(); + /* timer still needed? */ + if (tcp_active_pcbs || tcp_tw_pcbs) { + /* restart timer */ + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } else { + /* disable timer */ + tcpip_tcp_timer_active = 0; + } +} + +/** + * Called from TCP_REG when registering a new PCB: + * the reason is to have the TCP timer only running when + * there are active (or time-wait) PCBs. + */ +void +tcp_timer_needed(void) +{ + /* timer is off but needed again? */ + if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { + /* enable and start timer */ + tcpip_tcp_timer_active = 1; + sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); + } +} +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +/** + * Timer callback function that calls ip_reass_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +ip_reass_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip_reass_tmr()\n")); + ip_reass_tmr(); + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +} +#endif /* IP_REASSEMBLY */ + +#if LWIP_ARP +/** + * Timer callback function that calls etharp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +arp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: etharp_tmr()\n")); + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +} +#endif /* LWIP_ARP */ + +#if LWIP_DHCP +/** + * Timer callback function that calls dhcp_coarse_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_coarse(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_coarse_tmr()\n")); + dhcp_coarse_tmr(); + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); +} + +/** + * Timer callback function that calls dhcp_fine_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dhcp_timer_fine(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dhcp_fine_tmr()\n")); + dhcp_fine_tmr(); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +} +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP +/** + * Timer callback function that calls autoip_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +autoip_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: autoip_tmr()\n")); + autoip_tmr(); + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +} +#endif /* LWIP_AUTOIP */ + +#if LWIP_IGMP +/** + * Timer callback function that calls igmp_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +igmp_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: igmp_tmr()\n")); + igmp_tmr(); + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +} +#endif /* LWIP_IGMP */ + +#if LWIP_DNS +/** + * Timer callback function that calls dns_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +dns_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: dns_tmr()\n")); + dns_tmr(); + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +} +#endif /* LWIP_DNS */ + +#if LWIP_IPV6 +/** + * Timer callback function that calls nd6_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +nd6_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: nd6_tmr()\n")); + nd6_tmr(); + sys_timeout(ND6_TMR_INTERVAL, nd6_timer, NULL); +} + +#if LWIP_IPV6_REASS +/** + * Timer callback function that calls ip6_reass_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +ip6_reass_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: ip6_reass_tmr()\n")); + ip6_reass_tmr(); + sys_timeout(IP6_REASS_TMR_INTERVAL, ip6_reass_timer, NULL); +} +#endif /* LWIP_IPV6_REASS */ + +#if LWIP_IPV6_MLD +/** + * Timer callback function that calls mld6_tmr() and reschedules itself. + * + * @param arg unused argument + */ +static void +mld6_timer(void *arg) +{ + LWIP_UNUSED_ARG(arg); + LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: mld6_tmr()\n")); + mld6_tmr(); + sys_timeout(MLD6_TMR_INTERVAL, mld6_timer, NULL); +} +#endif /* LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6 */ + +/** Initialize this module */ +void sys_timeouts_init(void) +{ +#if IP_REASSEMBLY + sys_timeout(IP_TMR_INTERVAL, ip_reass_timer, NULL); +#endif /* IP_REASSEMBLY */ +#if LWIP_ARP + sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL); +#endif /* LWIP_ARP */ +#if LWIP_DHCP + sys_timeout(DHCP_COARSE_TIMER_MSECS, dhcp_timer_coarse, NULL); + sys_timeout(DHCP_FINE_TIMER_MSECS, dhcp_timer_fine, NULL); +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + sys_timeout(AUTOIP_TMR_INTERVAL, autoip_timer, NULL); +#endif /* LWIP_AUTOIP */ +#if LWIP_IGMP + sys_timeout(IGMP_TMR_INTERVAL, igmp_timer, NULL); +#endif /* LWIP_IGMP */ +#if LWIP_DNS + sys_timeout(DNS_TMR_INTERVAL, dns_timer, NULL); +#endif /* LWIP_DNS */ +#if LWIP_IPV6 + sys_timeout(ND6_TMR_INTERVAL, nd6_timer, NULL); +#if LWIP_IPV6_REASS + sys_timeout(IP6_REASS_TMR_INTERVAL, ip6_reass_timer, NULL); +#endif /* LWIP_IPV6_REASS */ +#if LWIP_IPV6_MLD + sys_timeout(MLD6_TMR_INTERVAL, mld6_timer, NULL); +#endif /* LWIP_IPV6_MLD */ +#endif /* LWIP_IPV6 */ + +#if NO_SYS + /* Initialise timestamp for sys_check_timeouts */ + timeouts_last_time = sys_now(); +#endif +} + +/** + * Create a one-shot timer (aka timeout). Timeouts are processed in the + * following cases: + * - while waiting for a message using sys_timeouts_mbox_fetch() + * - by calling sys_check_timeouts() (NO_SYS==1 only) + * + * @param msecs time in milliseconds after that the timer should expire + * @param handler callback function to call when msecs have elapsed + * @param arg argument to pass to the callback function + */ +#if LWIP_DEBUG_TIMERNAMES +void +sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) +#else /* LWIP_DEBUG_TIMERNAMES */ +void +sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) +#endif /* LWIP_DEBUG_TIMERNAMES */ +{ + struct sys_timeo *timeout, *t; +#if NO_SYS + u32_t now, diff; +#endif + + timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); + if (timeout == NULL) { + LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); + return; + } + +#if NO_SYS + now = sys_now(); + if (next_timeout == NULL) { + diff = 0; + timeouts_last_time = now; + } else { + diff = now - timeouts_last_time; + } +#endif + + timeout->next = NULL; + timeout->h = handler; + timeout->arg = arg; +#if NO_SYS + timeout->time = msecs + diff; +#else + timeout->time = msecs; +#endif +#if LWIP_DEBUG_TIMERNAMES + timeout->handler_name = handler_name; + LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", + (void *)timeout, msecs, handler_name, (void *)arg)); +#endif /* LWIP_DEBUG_TIMERNAMES */ + + if (next_timeout == NULL) { + next_timeout = timeout; + return; + } + + if (next_timeout->time > msecs) { + next_timeout->time -= msecs; + timeout->next = next_timeout; + next_timeout = timeout; + } else { + for(t = next_timeout; t != NULL; t = t->next) { + timeout->time -= t->time; + if (t->next == NULL || t->next->time > timeout->time) { + if (t->next != NULL) { + t->next->time -= timeout->time; + } + timeout->next = t->next; + t->next = timeout; + break; + } + } + } +} + +/** + * Go through timeout list (for this task only) and remove the first matching + * entry (subsequent entries remain untouched), even though the timeout has not + * triggered yet. + * + * @param handler callback function that would be called by the timeout + * @param arg callback argument that would be passed to handler +*/ +void +sys_untimeout(sys_timeout_handler handler, void *arg) +{ + struct sys_timeo *prev_t, *t; + + if (next_timeout == NULL) { + return; + } + + for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { + if ((t->h == handler) && (t->arg == arg)) { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) { + next_timeout = t->next; + } else { + prev_t->next = t->next; + } + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) { + t->next->time += t->time; + } + memp_free(MEMP_SYS_TIMEOUT, t); + return; + } + } + return; +} + +#if NO_SYS + +/** Handle timeouts for NO_SYS==1 (i.e. without using + * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout + * handler functions when timeouts expire. + * + * Must be called periodically from your main loop. + */ +void +sys_check_timeouts(void) +{ + if (next_timeout) { + struct sys_timeo *tmptimeout; + u32_t diff; + sys_timeout_handler handler; + void *arg; + u8_t had_one; + u32_t now; + + now = sys_now(); + /* this cares for wraparounds */ + diff = now - timeouts_last_time; + do + { +#if PBUF_POOL_FREE_OOSEQ + PBUF_CHECK_FREE_OOSEQ(); +#endif /* PBUF_POOL_FREE_OOSEQ */ + had_one = 0; + tmptimeout = next_timeout; + if (tmptimeout && (tmptimeout->time <= diff)) { + /* timeout has expired */ + had_one = 1; + timeouts_last_time += tmptimeout->time; + diff -= tmptimeout->time; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + handler(arg); + } + } + /* repeat until all expired timers have been called */ + }while(had_one); + } +} + +/** Set back the timestamp of the last call to sys_check_timeouts() + * This is necessary if sys_check_timeouts() hasn't been called for a long + * time (e.g. while saving energy) to prevent all timer functions of that + * period being called. + */ +void +sys_restart_timeouts(void) +{ + timeouts_last_time = sys_now(); +} + +#else /* NO_SYS */ + +/** + * Wait (forever) for a message to arrive in an mbox. + * While waiting, timeouts are processed. + * + * @param mbox the mbox to fetch the message from + * @param msg the place to store the message + */ +void +sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) +{ + u32_t time_needed; + struct sys_timeo *tmptimeout; + sys_timeout_handler handler; + void *arg; + + again: + if (!next_timeout) { + time_needed = sys_arch_mbox_fetch(mbox, msg, 0); + } else { + if (next_timeout->time > 0) { + time_needed = sys_arch_mbox_fetch(mbox, msg, next_timeout->time); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occurred before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = next_timeout; + next_timeout = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; +#if LWIP_DEBUG_TIMERNAMES + if (handler != NULL) { + LWIP_DEBUGF(TIMERS_DEBUG, ("stmf calling h=%s arg=%p\n", + tmptimeout->handler_name, arg)); + } +#endif /* LWIP_DEBUG_TIMERNAMES */ + memp_free(MEMP_SYS_TIMEOUT, tmptimeout); + if (handler != NULL) { + /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the + timeout handler function. */ + LOCK_TCPIP_CORE(); + handler(arg); + UNLOCK_TCPIP_CORE(); + } + LWIP_TCPIP_THREAD_ALIVE(); + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < next_timeout->time) { + next_timeout->time -= time_needed; + } else { + next_timeout->time = 0; + } + } + } +} + +#endif /* NO_SYS */ + +#else /* LWIP_TIMERS */ +/* Satisfy the TCP code which calls this function */ +void +tcp_timer_needed(void) +{ +} +#endif /* LWIP_TIMERS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/mem.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/mem.c new file mode 100644 index 0000000..634e760 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/mem.c @@ -0,0 +1,677 @@ +/** + * @file + * Dynamic memory manager + * + * This is a lightweight replacement for the standard C library malloc(). + * + * If you want to use the standard C library malloc() instead, define + * MEM_LIBC_MALLOC to 1 in your lwipopts.h + * + * To let mem_malloc() use pools (prevents fragmentation and is much faster than + * a heap but might waste some memory), define MEM_USE_POOLS to 1, define + * MEM_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list + * of pools like this (more pools can be added between _START and _END): + * + * Define three pools with sizes 256, 512, and 1512 bytes + * LWIP_MALLOC_MEMPOOL_START + * LWIP_MALLOC_MEMPOOL(20, 256) + * LWIP_MALLOC_MEMPOOL(10, 512) + * LWIP_MALLOC_MEMPOOL(5, 1512) + * LWIP_MALLOC_MEMPOOL_END + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ + +#include "lwip/opt.h" + +#if !MEM_LIBC_MALLOC /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" +#include "lwip/err.h" + +#include + +#if MEM_USE_POOLS +/* lwIP head implemented with different sized pools */ + +/** + * Allocate memory: determine the smallest pool that is big enough + * to contain an element of 'size' and get an element from that pool. + * + * @param size the size in bytes of the memory needed + * @return a pointer to the allocated memory or NULL if the pool is empty + */ +void * +mem_malloc(mem_size_t size) +{ + void *ret; + struct memp_malloc_helper *element; + memp_t poolnr; + mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + + for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { +#if MEM_USE_POOLS_TRY_BIGGER_POOL +again: +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + /* is this pool big enough to hold an element of the required size + plus a struct memp_malloc_helper that saves the pool this element came from? */ + if (required_size <= memp_sizes[poolnr]) { + break; + } + } + if (poolnr > MEMP_POOL_LAST) { + LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); + return NULL; + } + element = (struct memp_malloc_helper*)memp_malloc(poolnr); + if (element == NULL) { + /* No need to DEBUGF or ASSERT: This error is already + taken care of in memp.c */ +#if MEM_USE_POOLS_TRY_BIGGER_POOL + /** Try a bigger pool if this one is empty! */ + if (poolnr < MEMP_POOL_LAST) { + poolnr++; + goto again; + } +#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ + return NULL; + } + + /* save the pool number this element came from */ + element->poolnr = poolnr; + /* and return a pointer to the memory directly after the struct memp_malloc_helper */ + ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); + +#if MEMP_OVERFLOW_CHECK + /* initialize unused memory */ + element->size = size; + memset((u8_t*)ret + size, 0xcd, memp_sizes[poolnr] - size); +#endif /* MEMP_OVERFLOW_CHECK */ + return ret; +} + +/** + * Free memory previously allocated by mem_malloc. Loads the pool number + * and calls memp_free with that pool number to put the element back into + * its pool + * + * @param rmem the memory element to free + */ +void +mem_free(void *rmem) +{ + struct memp_malloc_helper *hmem; + + LWIP_ASSERT("rmem != NULL", (rmem != NULL)); + LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); + + /* get the original struct memp_malloc_helper */ + hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); + + LWIP_ASSERT("hmem != NULL", (hmem != NULL)); + LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); + LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); + +#if MEMP_OVERFLOW_CHECK + { + u16_t i; + LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size", + hmem->size <= memp_sizes[hmem->poolnr]); + /* check that unused memory remained untouched */ + for (i = hmem->size; i < memp_sizes[hmem->poolnr]; i++) { + u8_t data = *((u8_t*)rmem + i); + LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd); + } + } +#endif /* MEMP_OVERFLOW_CHECK */ + + /* and put it in the pool we saved earlier */ + memp_free(hmem->poolnr, hmem); +} + +#else /* MEM_USE_POOLS */ +/* lwIP replacement for your libc malloc() */ + +/** + * The heap is made up as a list of structs of this type. + * This does not have to be aligned since for getting its size, + * we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns. + */ +struct mem { + /** index (-> ram[next]) of the next struct */ + mem_size_t next; + /** index (-> ram[prev]) of the previous struct */ + mem_size_t prev; + /** 1: this area is used; 0: this area is unused */ + u8_t used; +}; + +/** All allocated blocks will be MIN_SIZE bytes big, at least! + * MIN_SIZE can be overridden to suit your needs. Smaller values save space, + * larger values could prevent too small blocks to fragment the RAM too much. */ +#ifndef MIN_SIZE +#define MIN_SIZE 12 +#endif /* MIN_SIZE */ +/* some alignment macros: we define them here for better source code layout */ +#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) +#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) +#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) + +/** If you want to relocate the heap to external memory, simply define + * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. + * If so, make sure the memory at that location is big enough (see below on + * how that space is calculated). */ +#ifndef LWIP_RAM_HEAP_POINTER +/** the heap. we need one struct mem at the end and some room for alignment */ +u8_t ram_heap[MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT]; +#define LWIP_RAM_HEAP_POINTER ram_heap +#endif /* LWIP_RAM_HEAP_POINTER */ + +/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ +static u8_t *ram; +/** the last entry, always unused! */ +static struct mem *ram_end; +/** pointer to the lowest free block, this is used for faster search */ +static struct mem *lfree; + +/** concurrent access protection */ +#if !NO_SYS +static sys_mutex_t mem_mutex; +#endif + +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + +static volatile u8_t mem_free_count; + +/* Allow mem_free from other (e.g. interrupt) context */ +#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) +#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) +#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) +#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) +#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) + +#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + +/* Protect the heap only by using a semaphore */ +#define LWIP_MEM_FREE_DECL_PROTECT() +#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) +#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) +/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ +#define LWIP_MEM_ALLOC_DECL_PROTECT() +#define LWIP_MEM_ALLOC_PROTECT() +#define LWIP_MEM_ALLOC_UNPROTECT() + +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + +/** + * "Plug holes" by combining adjacent empty struct mems. + * After this function is through, there should not exist + * one empty struct mem pointing to another empty struct mem. + * + * @param mem this points to a struct mem which just has been freed + * @internal this function is only called by mem_free() and mem_trim() + * + * This assumes access to the heap is protected by the calling function + * already. + */ +static void +plug_holes(struct mem *mem) +{ + struct mem *nmem; + struct mem *pmem; + + LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); + LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); + LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); + + /* plug hole forward */ + LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); + + nmem = (struct mem *)(void *)&ram[mem->next]; + if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { + /* if mem->next is unused and not end of ram, combine mem and mem->next */ + if (lfree == nmem) { + lfree = mem; + } + mem->next = nmem->next; + ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); + } + + /* plug hole backward */ + pmem = (struct mem *)(void *)&ram[mem->prev]; + if (pmem != mem && pmem->used == 0) { + /* if mem->prev is unused, combine mem and mem->prev */ + if (lfree == mem) { + lfree = pmem; + } + pmem->next = mem->next; + ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); + } +} + +/** + * Zero the heap and initialize start, end and lowest-free + */ +void +mem_init(void) +{ + struct mem *mem; + + LWIP_ASSERT("Sanity check alignment", + (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); + + /* align the heap */ + ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); + /* initialize the start of the heap */ + mem = (struct mem *)(void *)ram; + mem->next = MEM_SIZE_ALIGNED; + mem->prev = 0; + mem->used = 0; + /* initialize the end of the heap */ + ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; + ram_end->used = 1; + ram_end->next = MEM_SIZE_ALIGNED; + ram_end->prev = MEM_SIZE_ALIGNED; + + /* initialize the lowest-free pointer to the start of the heap */ + lfree = (struct mem *)(void *)ram; + + MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); + + if(sys_mutex_new(&mem_mutex) != ERR_OK) { + LWIP_ASSERT("failed to create mem_mutex", 0); + } +} + +/** + * Put a struct mem back on the heap + * + * @param rmem is the data portion of a struct mem as returned by a previous + * call to mem_malloc() + */ +void +mem_free(void *rmem) +{ + struct mem *mem; + LWIP_MEM_FREE_DECL_PROTECT(); + + if (rmem == NULL) { + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); + return; + } + LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); + + LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return; + } + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... which has to be in a used state ... */ + LWIP_ASSERT("mem_free: mem->used", mem->used); + /* ... and is now unused. */ + mem->used = 0; + + if (mem < lfree) { + /* the newly freed struct is now the lowest */ + lfree = mem; + } + + MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); + + /* finally, see if prev or next are free also */ + plug_holes(mem); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); +} + +/** + * Shrink memory returned by mem_malloc(). + * + * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked + * @param newsize required size after shrinking (needs to be smaller than or + * equal to the previous size) + * @return for compatibility reasons: is always == rmem, at the moment + * or NULL if newsize is > old size, in which case rmem is NOT touched + * or freed! + */ +void * +mem_trim(void *rmem, mem_size_t newsize) +{ + mem_size_t size; + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; + /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ + LWIP_MEM_FREE_DECL_PROTECT(); + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + newsize = LWIP_MEM_ALIGN_SIZE(newsize); + + if(newsize < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + newsize = MIN_SIZE_ALIGNED; + } + + if (newsize > MEM_SIZE_ALIGNED) { + return NULL; + } + + LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && + (u8_t *)rmem < (u8_t *)ram_end); + + if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { + SYS_ARCH_DECL_PROTECT(lev); + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); + /* protect mem stats from concurrent access */ + SYS_ARCH_PROTECT(lev); + MEM_STATS_INC(illegal); + SYS_ARCH_UNPROTECT(lev); + return rmem; + } + /* Get the corresponding struct mem ... */ + mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); + /* ... and its offset pointer */ + ptr = (mem_size_t)((u8_t *)mem - ram); + + size = mem->next - ptr - SIZEOF_STRUCT_MEM; + LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); + if (newsize > size) { + /* not supported */ + return NULL; + } + if (newsize == size) { + /* No change in size, simply return */ + return rmem; + } + + /* protect the heap from concurrent access */ + LWIP_MEM_FREE_PROTECT(); + + mem2 = (struct mem *)(void *)&ram[mem->next]; + if(mem2->used == 0) { + /* The next struct is unused, we can simply move it at little */ + mem_size_t next; + /* remember the old next pointer */ + next = mem2->next; + /* create new struct mem which is moved directly after the shrinked mem */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + if (lfree == mem2) { + lfree = (struct mem *)(void *)&ram[ptr2]; + } + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + /* restore the next pointer */ + mem2->next = next; + /* link it back to mem */ + mem2->prev = ptr; + /* link mem to it */ + mem->next = ptr2; + /* last thing to restore linked list: as we have moved mem2, + * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not + * the end of the heap */ + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* no need to plug holes, we've already done that */ + } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { + /* Next struct is used but there's room for another struct mem with + * at least MIN_SIZE_ALIGNED of data. + * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem + * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; + mem2 = (struct mem *)(void *)&ram[ptr2]; + if (mem2 < lfree) { + lfree = mem2; + } + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + mem->next = ptr2; + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_DEC_USED(used, (size - newsize)); + /* the original mem->next is used, so no need to plug holes! */ + } + /* else { + next struct mem is used but size between mem and mem2 is not big enough + to create another struct mem + -> don't do anyhting. + -> the remaining space stays unused since it is too small + } */ +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 1; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_FREE_UNPROTECT(); + return rmem; +} + +/** + * Adam's mem_malloc() plus solution for bug #17922 + * Allocate a block of memory with a minimum of 'size' bytes. + * + * @param size is the minimum size of the requested block in bytes. + * @return pointer to allocated memory or NULL if no free memory was found. + * + * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). + */ +void * +mem_malloc(mem_size_t size) +{ + mem_size_t ptr, ptr2; + struct mem *mem, *mem2; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + u8_t local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_MEM_ALLOC_DECL_PROTECT(); + + if (size == 0) { + return NULL; + } + + /* Expand the size of the allocated memory region so that we can + adjust for alignment. */ + size = LWIP_MEM_ALIGN_SIZE(size); + + if(size < MIN_SIZE_ALIGNED) { + /* every data block must be at least MIN_SIZE_ALIGNED long */ + size = MIN_SIZE_ALIGNED; + } + + if (size > MEM_SIZE_ALIGNED) { + return NULL; + } + + /* protect the heap from concurrent access */ + sys_mutex_lock(&mem_mutex); + LWIP_MEM_ALLOC_PROTECT(); +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* run as long as a mem_free disturbed mem_malloc or mem_trim */ + do { + local_mem_free_count = 0; +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + /* Scan through the heap searching for a free block that is big enough, + * beginning with the lowest free block. + */ + for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; + ptr = ((struct mem *)(void *)&ram[ptr])->next) { + mem = (struct mem *)(void *)&ram[ptr]; +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* allow mem_free or mem_trim to run */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem. */ + local_mem_free_count = 1; + break; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + + if ((!mem->used) && + (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { + /* mem is not used and at least perfect fit is possible: + * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ + + if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { + /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing + * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') + * -> split large block, create empty remainder, + * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if + * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, + * struct mem would fit in but no data between mem2 and mem2->next + * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty + * region that couldn't hold data, but when mem->next gets freed, + * the 2 regions would be combined, resulting in more free memory + */ + ptr2 = ptr + SIZEOF_STRUCT_MEM + size; + /* create mem2 struct */ + mem2 = (struct mem *)(void *)&ram[ptr2]; + mem2->used = 0; + mem2->next = mem->next; + mem2->prev = ptr; + /* and insert it between mem and mem->next */ + mem->next = ptr2; + mem->used = 1; + + if (mem2->next != MEM_SIZE_ALIGNED) { + ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; + } + MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); + } else { + /* (a mem2 struct does no fit into the user data space of mem and mem->next will always + * be used at this point: if not we have 2 unused structs in a row, plug_holes should have + * take care of this). + * -> near fit or exact fit: do not split, no mem2 creation + * also can't move mem->next directly behind mem, since mem->next + * will always be used at this point! + */ + mem->used = 1; + MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +mem_malloc_adjust_lfree: +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + if (mem == lfree) { + struct mem *cur = lfree; + /* Find next free block after mem and update lowest free pointer */ + while (cur->used && cur != ram_end) { +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + mem_free_count = 0; + LWIP_MEM_ALLOC_UNPROTECT(); + /* prevent high interrupt latency... */ + LWIP_MEM_ALLOC_PROTECT(); + if (mem_free_count != 0) { + /* If mem_free or mem_trim have run, we have to restart since they + could have altered our current struct mem or lfree. */ + goto mem_malloc_adjust_lfree; + } +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + cur = (struct mem *)(void *)&ram[cur->next]; + } + lfree = cur; + LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); + } + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", + (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); + LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", + ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); + LWIP_ASSERT("mem_malloc: sanity check alignment", + (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); + + return (u8_t *)mem + SIZEOF_STRUCT_MEM; + } + } +#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT + /* if we got interrupted by a mem_free, try again */ + } while(local_mem_free_count != 0); +#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ + LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); + MEM_STATS_INC(err); + LWIP_MEM_ALLOC_UNPROTECT(); + sys_mutex_unlock(&mem_mutex); + return NULL; +} + +#endif /* MEM_USE_POOLS */ +/** + * Contiguously allocates enough space for count objects that are size bytes + * of memory each and returns a pointer to the allocated memory. + * + * The allocated memory is filled with bytes of value zero. + * + * @param count number of objects to allocate + * @param size size of the objects to allocate + * @return pointer to allocated memory / NULL pointer if there is an error + */ +void *mem_calloc(mem_size_t count, mem_size_t size) +{ + void *p; + + /* allocate 'count' objects of size 'size' */ + p = mem_malloc(count * size); + if (p) { + /* zero the memory */ + memset(p, 0, count * size); + } + return p; +} + +#endif /* !MEM_LIBC_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/memp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/memp.c new file mode 100644 index 0000000..b70909d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/memp.c @@ -0,0 +1,489 @@ +/** + * @file + * Dynamic pool memory manager + * + * lwIP has dedicated pools for many structures (netconn, protocol control blocks, + * packet buffers, ...). All these pools are managed here. + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/udp.h" +#include "lwip/raw.h" +#include "lwip/tcp_impl.h" +#include "lwip/igmp.h" +#include "lwip/api.h" +#include "lwip/api_msg.h" +#include "lwip/sockets.h" +#include "lwip/tcpip.h" +#include "lwip/sys.h" +#include "lwip/lwip_timers.h" +#include "lwip/stats.h" +#include "netif/etharp.h" +#include "lwip/ip_frag.h" +#include "lwip/snmp_structs.h" +#include "lwip/snmp_msg.h" +#include "lwip/dns.h" +#include "lwip/netdb.h" +#include "netif/ppp/ppp.h" +#include "netif/ppp/pppoe.h" +#include "netif/ppp/pppol2tp.h" +#include "lwip/nd6.h" +#include "lwip/ip6_frag.h" +#include "lwip/mld6.h" + +#include + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +struct memp { + struct memp *next; +#if MEMP_OVERFLOW_CHECK + const char *file; + int line; +#endif /* MEMP_OVERFLOW_CHECK */ +}; + +#if MEMP_OVERFLOW_CHECK +/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning + * and at the end of each element, initialize them as 0xcd and check + * them later. */ +/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, + * every single element in each pool is checked! + * This is VERY SLOW but also very helpful. */ +/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in + * lwipopts.h to change the amount reserved for checking. */ +#ifndef MEMP_SANITY_REGION_BEFORE +#define MEMP_SANITY_REGION_BEFORE 16 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#if MEMP_SANITY_REGION_BEFORE > 0 +#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) +#else +#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_BEFORE*/ +#ifndef MEMP_SANITY_REGION_AFTER +#define MEMP_SANITY_REGION_AFTER 16 +#endif /* MEMP_SANITY_REGION_AFTER*/ +#if MEMP_SANITY_REGION_AFTER > 0 +#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) +#else +#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 +#endif /* MEMP_SANITY_REGION_AFTER*/ + +/* MEMP_SIZE: save space for struct memp and for sanity check */ +#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) + +#else /* MEMP_OVERFLOW_CHECK */ + +/* No sanity checks + * We don't need to preserve the struct memp while not allocated, so we + * can save a little space and set MEMP_SIZE to 0. + */ +#define MEMP_SIZE 0 +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_OVERFLOW_CHECK */ + +/** This array holds the first free element of each pool. + * Elements form a linked list. */ +static struct memp *memp_tab[MEMP_MAX]; + +#else /* MEMP_MEM_MALLOC */ + +#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) + +#endif /* MEMP_MEM_MALLOC */ + +/** This array holds the element sizes of each pool. */ +#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC +static +#endif +const u16_t memp_sizes[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), +#include "lwip/memp_std.h" +}; + +#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ + +/** This array holds the number of elements in each pool. */ +static const u16_t memp_num[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (num), +#include "lwip/memp_std.h" +}; + +/** This array holds a textual description of each pool. */ +#ifdef LWIP_DEBUG +static const char *memp_desc[MEMP_MAX] = { +#define LWIP_MEMPOOL(name,num,size,desc) (desc), +#include "lwip/memp_std.h" +}; +#endif /* LWIP_DEBUG */ + +#if MEMP_SEPARATE_POOLS + +/** This creates each memory pool. These are named memp_memory_XXX_base (where + * XXX is the name of the pool defined in memp_std.h). + * To relocate a pool, declare it as extern in cc.h. Example for GCC: + * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_UDP_PCB_base[]; + */ +#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \ + [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))]; +#include "lwip/memp_std.h" + +/** This array holds the base of each memory pool. */ +static u8_t *const memp_bases[] = { +#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base, +#include "lwip/memp_std.h" +}; + +#else /* MEMP_SEPARATE_POOLS */ + +/** This is the actual memory used by the pools (all pools in one big block). */ +static u8_t memp_memory[MEM_ALIGNMENT - 1 +#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) ) +#include "lwip/memp_std.h" +]; + +#endif /* MEMP_SEPARATE_POOLS */ + +#if MEMP_SANITY_CHECK +/** + * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". + */ +static int +memp_sanity(void) +{ + s16_t i; + struct memp *t, *h; + + for (i = 0; i < MEMP_MAX; i++) { + t = memp_tab[i]; + if(t != NULL) { + for (h = t->next; (t != NULL) && (h != NULL); t = t->next, + h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) { + if (t == h) { + return 0; + } + } + } + } + return 1; +} +#endif /* MEMP_SANITY_CHECK*/ +#if MEMP_OVERFLOW_CHECK +#if defined(LWIP_DEBUG) && MEMP_STATS +static const char * memp_overflow_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) "/"desc, +#include "lwip/memp_std.h" + }; +#endif + +/** + * Check if a memp element was victim of an overflow + * (e.g. the restricted area after it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type]; + for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp overflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Check if a memp element was victim of an underflow + * (e.g. the restricted area before it has been altered) + * + * @param p the memp element to check + * @param memp_type the pool p comes from + */ +static void +memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type) +{ + u16_t k; + u8_t *m; +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { + if (m[k] != 0xcd) { + char errstr[128] = "detected memp underflow in pool "; + char digit[] = "0"; + if(memp_type >= 10) { + digit[0] = '0' + (memp_type/10); + strcat(errstr, digit); + } + digit[0] = '0' + (memp_type%10); + strcat(errstr, digit); +#if defined(LWIP_DEBUG) && MEMP_STATS + strcat(errstr, memp_overflow_names[memp_type]); +#endif + LWIP_ASSERT(errstr, 0); + } + } +#endif +} + +/** + * Do an overflow check for all elements in every pool. + * + * @see memp_overflow_check_element for a description of the check + */ +static void +memp_overflow_check_all(void) +{ + u16_t i, j; + struct memp *p; + +#if !MEMP_SEPARATE_POOLS + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + for (i = 0; i < MEMP_MAX; ++i) { +#if MEMP_SEPARATE_POOLS + p = (struct memp *)(memp_bases[i]); +#endif /* MEMP_SEPARATE_POOLS */ + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_overflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +#if !MEMP_SEPARATE_POOLS + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + for (i = 0; i < MEMP_MAX; ++i) { +#if MEMP_SEPARATE_POOLS + p = (struct memp *)(memp_bases[i]); +#endif /* MEMP_SEPARATE_POOLS */ + for (j = 0; j < memp_num[i]; ++j) { + memp_overflow_check_element_underflow(p, i); + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} + +/** + * Initialize the restricted areas of all memp elements in every pool. + */ +static void +memp_overflow_init(void) +{ + u16_t i, j; + struct memp *p; + u8_t *m; + +#if !MEMP_SEPARATE_POOLS + p = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + for (i = 0; i < MEMP_MAX; ++i) { +#if MEMP_SEPARATE_POOLS + p = (struct memp *)(memp_bases[i]); +#endif /* MEMP_SEPARATE_POOLS */ + for (j = 0; j < memp_num[i]; ++j) { +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + memp_sizes[i]; + memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); +#endif + p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED); + } + } +} +#endif /* MEMP_OVERFLOW_CHECK */ + +/** + * Initialize this module. + * + * Carves out memp_memory into linked lists for each pool-type. + */ +void +memp_init(void) +{ + struct memp *memp; + u16_t i, j; + + for (i = 0; i < MEMP_MAX; ++i) { + MEMP_STATS_AVAIL(used, i, 0); + MEMP_STATS_AVAIL(max, i, 0); + MEMP_STATS_AVAIL(err, i, 0); + MEMP_STATS_AVAIL(avail, i, memp_num[i]); + } + +#if !MEMP_SEPARATE_POOLS + memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory); +#endif /* !MEMP_SEPARATE_POOLS */ + /* for every pool: */ + for (i = 0; i < MEMP_MAX; ++i) { + memp_tab[i] = NULL; +#if MEMP_SEPARATE_POOLS + memp = (struct memp*)LWIP_MEM_ALIGN(memp_bases[i]); +#endif /* MEMP_SEPARATE_POOLS */ + /* create a linked list of memp elements */ + for (j = 0; j < memp_num[i]; ++j) { + memp->next = memp_tab[i]; + memp_tab[i] = memp; + memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i] +#if MEMP_OVERFLOW_CHECK + + MEMP_SANITY_REGION_AFTER_ALIGNED +#endif + ); + } + } +#if MEMP_OVERFLOW_CHECK + memp_overflow_init(); + /* check everything a first time to see if it worked */ + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK */ +} + +/** + * Get an element from a specific pool. + * + * @param type the pool to get an element from + * + * the debug version has two more parameters: + * @param file file name calling this function + * @param line number of line where this function is called + * + * @return a pointer to the allocated memory or a NULL pointer on error + */ +void * +#if !MEMP_OVERFLOW_CHECK +memp_malloc(memp_t type) +#else +memp_malloc_fn(memp_t type, const char* file, const int line) +#endif +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ + + memp = memp_tab[type]; + + if (memp != NULL) { + memp_tab[type] = memp->next; +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; + memp->file = file; + memp->line = line; +#endif /* MEMP_OVERFLOW_CHECK */ + MEMP_STATS_INC_USED(used, type); + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); + memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type])); + MEMP_STATS_INC(err, type); + } + + SYS_ARCH_UNPROTECT(old_level); + + return memp; +} + +/** + * Put an element back into its pool. + * + * @param type the pool where to put mem + * @param mem the memp element to free + */ +void +memp_free(memp_t type, void *mem) +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + + if (mem == NULL) { + return; + } + LWIP_ASSERT("memp_free: mem properly aligned", + ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); + + memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); + + SYS_ARCH_PROTECT(old_level); +#if MEMP_OVERFLOW_CHECK +#if MEMP_OVERFLOW_CHECK >= 2 + memp_overflow_check_all(); +#else + memp_overflow_check_element_overflow(memp, type); + memp_overflow_check_element_underflow(memp, type); +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#endif /* MEMP_OVERFLOW_CHECK */ + + MEMP_STATS_DEC(used, type); + + memp->next = memp_tab[type]; + memp_tab[type] = memp; + +#if MEMP_SANITY_CHECK + LWIP_ASSERT("memp sanity", memp_sanity()); +#endif /* MEMP_SANITY_CHECK */ + + SYS_ARCH_UNPROTECT(old_level); +} + +#endif /* MEMP_MEM_MALLOC */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/netif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/netif.c new file mode 100644 index 0000000..36e801b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/netif.c @@ -0,0 +1,940 @@ +/** + * @file + * lwIP network interface abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" +#include "lwip/tcp_impl.h" +#include "lwip/snmp.h" +#include "lwip/igmp.h" +#include "netif/etharp.h" +#include "lwip/stats.h" +#if ENABLE_LOOPBACK +#include "lwip/sys.h" +#if LWIP_NETIF_LOOPBACK_MULTITHREADING +#include "lwip/tcpip.h" +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_AUTOIP +#include "lwip/autoip.h" +#endif /* LWIP_AUTOIP */ +#if LWIP_DHCP +#include "lwip/dhcp.h" +#endif /* LWIP_DHCP */ +#if LWIP_IPV6_DHCP6 +#include "lwip/dhcp6.h" +#endif /* LWIP_IPV6_DHCP6 */ +#if LWIP_IPV6_MLD +#include "lwip/mld6.h" +#endif /* LWIP_IPV6_MLD */ + +#if LWIP_NETIF_STATUS_CALLBACK +#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) +#else +#define NETIF_STATUS_CALLBACK(n) +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) +#else +#define NETIF_LINK_CALLBACK(n) +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +struct netif *netif_list; +struct netif *netif_default; + +static u8_t netif_num; + +#if LWIP_IPV6 +static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr); +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV6 +#define ipX_input(in, netif) (IP6H_V((const struct ip6_hdr *)in->payload) == 6) ? ip6_input(in, netif) : ip_input(in, netif) +#else +#define ipX_input(in, netif) ip_input(in, netif) +#endif + +#if LWIP_HAVE_LOOPIF +static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr); +#if LWIP_IPV6 +static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr); +#endif + + +static struct netif loop_netif; + +/** + * Initialize a lwip network interface structure for a loopback interface + * + * @param netif the lwip network interface structure for this loopif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + */ +static err_t +netif_loopif_init(struct netif *netif) +{ + /* initialize the snmp variables and counters inside the struct netif + * ifSpeed: no assumption can be made! + */ + NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0); + + netif->name[0] = 'l'; + netif->name[1] = 'o'; + netif->output = netif_loop_output_ipv4; +#if LWIP_IPV6 + netif->output_ip6 = netif_loop_output_ipv6; +#endif + return ERR_OK; +} +#endif /* LWIP_HAVE_LOOPIF */ + +void +netif_init(void) +{ +#if LWIP_HAVE_LOOPIF + ip_addr_t loop_ipaddr, loop_netmask, loop_gw; + IP4_ADDR(&loop_gw, 127,0,0,1); + IP4_ADDR(&loop_ipaddr, 127,0,0,1); + IP4_ADDR(&loop_netmask, 255,0,0,0); + +#if NO_SYS + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, ip_input); +#else /* NO_SYS */ + netif_add(&loop_netif, &loop_ipaddr, &loop_netmask, &loop_gw, NULL, netif_loopif_init, tcpip_input); +#endif /* NO_SYS */ + +#if LWIP_IPV6 + loop_netif.ip6_addr[0].addr[0] = 0; + loop_netif.ip6_addr[0].addr[1] = 0; + loop_netif.ip6_addr[0].addr[2] = 0; + loop_netif.ip6_addr[0].addr[3] = PP_HTONL(0x00000001UL); + loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID; +#endif /* LWIP_IPV6 */ + + netif_set_up(&loop_netif); + +#endif /* LWIP_HAVE_LOOPIF */ +} + +/** + * Add a network interface to the list of lwIP netifs. + * + * @param netif a pre-allocated netif structure + * @param ipaddr IP address for the new netif + * @param netmask network mask for the new netif + * @param gw default gateway IP address for the new netif + * @param state opaque data passed to the new netif + * @param init callback function that initializes the interface + * @param input callback function that is called to pass + * ingress packets up in the protocol layer stack. + * + * @return netif, or NULL if failed. + */ +struct netif * +netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) +{ +#if LWIP_IPV6 + u32_t i; +#endif + + LWIP_ASSERT("No init function given", init != NULL); + + /* reset new interface configuration state */ + ip_addr_set_zero(&netif->ip_addr); + ip_addr_set_zero(&netif->netmask); + ip_addr_set_zero(&netif->gw); +#if LWIP_IPV6 + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + ip6_addr_set_zero(&netif->ip6_addr[i]); + netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); + } + netif->output_ip6 = netif_null_output_ip6; +#endif /* LWIP_IPV6 */ + netif->flags = 0; +#if LWIP_DHCP + /* netif not under DHCP control by default */ + netif->dhcp = NULL; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /* netif not under AutoIP control by default */ + netif->autoip = NULL; +#endif /* LWIP_AUTOIP */ +#if LWIP_IPV6_AUTOCONFIG + /* IPv6 address autoconfiguration not enabled by default */ + netif->ip6_autoconfig_enabled = 0; +#endif /* LWIP_IPV6_AUTOCONFIG */ +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ +#if LWIP_IPV6_DHCP6 + /* netif not under DHCPv6 control by default */ + netif->dhcp6 = NULL; +#endif /* LWIP_IPV6_DHCP6 */ +#if LWIP_NETIF_STATUS_CALLBACK + netif->status_callback = NULL; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + netif->link_callback = NULL; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_IGMP + netif->igmp_mac_filter = NULL; +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + netif->mld_mac_filter = NULL; +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +#if ENABLE_LOOPBACK + netif->loop_first = NULL; + netif->loop_last = NULL; +#endif /* ENABLE_LOOPBACK */ + + /* remember netif specific state information data */ + netif->state = state; + netif->num = netif_num++; + netif->input = input; + NETIF_SET_HWADDRHINT(netif, NULL); +#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS + netif->loop_cnt_current = 0; +#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ + + netif_set_addr(netif, ipaddr, netmask, gw); + + /* call user specified initialization function for netif */ + if (init(netif) != ERR_OK) { + return NULL; + } + + /* add this netif to the list */ + netif->next = netif_list; + netif_list = netif; + snmp_inc_iflist(); + +#if LWIP_IGMP + /* start IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_start(netif); + } +#endif /* LWIP_IGMP */ + + LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ", + netif->name[0], netif->name[1])); + ip_addr_debug_print(NETIF_DEBUG, ipaddr); + LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); + ip_addr_debug_print(NETIF_DEBUG, netmask); + LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); + ip_addr_debug_print(NETIF_DEBUG, gw); + LWIP_DEBUGF(NETIF_DEBUG, ("\n")); + return netif; +} + +/** + * Change IP address configuration for a network interface (including netmask + * and default gateway). + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * @param netmask the new netmask + * @param gw the new default gateway + */ +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw) +{ + netif_set_ipaddr(netif, ipaddr); + netif_set_netmask(netif, netmask); + netif_set_gw(netif, gw); +} + +/** + * Remove a network interface from the list of lwIP netifs. + * + * @param netif the network interface to remove + */ +void +netif_remove(struct netif *netif) +{ + if (netif == NULL) { + return; + } + +#if LWIP_IGMP + /* stop IGMP processing */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_stop(netif); + } +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + /* stop MLD processing */ + mld6_stop(netif); +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + if (netif_is_up(netif)) { + /* set netif down before removing (call callback function) */ + netif_set_down(netif); + } + + snmp_delete_ipaddridx_tree(netif); + + /* is it the first netif? */ + if (netif_list == netif) { + netif_list = netif->next; + } else { + /* look for netif further down the list */ + struct netif * tmpNetif; + for (tmpNetif = netif_list; tmpNetif != NULL; tmpNetif = tmpNetif->next) { + if (tmpNetif->next == netif) { + tmpNetif->next = netif->next; + break; + } + } + if (tmpNetif == NULL) + return; /* we didn't find any netif today */ + } + snmp_dec_iflist(); + /* this netif is default? */ + if (netif_default == netif) { + /* reset default netif */ + netif_set_default(NULL); + } +#if LWIP_NETIF_REMOVE_CALLBACK + if (netif->remove_callback) { + netif->remove_callback(netif); + } +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); +} + +/** + * Find a network interface by searching for its name + * + * @param name the name of the netif (like netif->name) plus concatenated number + * in ascii representation (e.g. 'en0') + */ +struct netif * +netif_find(char *name) +{ + struct netif *netif; + u8_t num; + + if (name == NULL) { + return NULL; + } + + num = name[2] - '0'; + + for(netif = netif_list; netif != NULL; netif = netif->next) { + if (num == netif->num && + name[0] == netif->name[0] && + name[1] == netif->name[1]) { + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); + return netif; + } + } + LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); + return NULL; +} + +/** + * Change the IP address of a network interface + * + * @param netif the network interface to change + * @param ipaddr the new IP address + * + * @note call netif_set_addr() if you also want to change netmask and + * default gateway + */ +void +netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr) +{ + /* TODO: Handling of obsolete pcbs */ + /* See: http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */ +#if LWIP_TCP + struct tcp_pcb *pcb; + struct tcp_pcb_listen *lpcb; + + /* address is actually being changed? */ + if (ipaddr && (ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0) { + /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */ + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); + pcb = tcp_active_pcbs; + while (pcb != NULL) { + /* PCB bound to current local interface address? */ + if (ip_addr_cmp(ipX_2_ip(&pcb->local_ip), &(netif->ip_addr)) +#if LWIP_AUTOIP + /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ + && !ip_addr_islinklocal(ipX_2_ip(&pcb->local_ip)) +#endif /* LWIP_AUTOIP */ + ) { + /* this connection must be aborted */ + struct tcp_pcb *next = pcb->next; + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); + tcp_abort(pcb); + pcb = next; + } else { + pcb = pcb->next; + } + } + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + /* PCB bound to current local interface address? */ + if ((!(ip_addr_isany(ipX_2_ip(&lpcb->local_ip)))) && + (ip_addr_cmp(ipX_2_ip(&lpcb->local_ip), &(netif->ip_addr)))) { + /* The PCB is listening to the old ipaddr and + * is set to listen to the new one instead */ + ip_addr_set(ipX_2_ip(&lpcb->local_ip), ipaddr); + } + } + } +#endif + snmp_delete_ipaddridx_tree(netif); + snmp_delete_iprteidx_tree(0,netif); + /* set new IP address to netif */ + ip_addr_set(&(netif->ip_addr), ipaddr); + snmp_insert_ipaddridx_tree(netif); + snmp_insert_iprteidx_tree(0,netif); + + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->ip_addr), + ip4_addr2_16(&netif->ip_addr), + ip4_addr3_16(&netif->ip_addr), + ip4_addr4_16(&netif->ip_addr))); +} + +/** + * Change the default gateway for a network interface + * + * @param netif the network interface to change + * @param gw the new default gateway + * + * @note call netif_set_addr() if you also want to change ip address and netmask + */ +void +netif_set_gw(struct netif *netif, ip_addr_t *gw) +{ + ip_addr_set(&(netif->gw), gw); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->gw), + ip4_addr2_16(&netif->gw), + ip4_addr3_16(&netif->gw), + ip4_addr4_16(&netif->gw))); +} + +/** + * Change the netmask of a network interface + * + * @param netif the network interface to change + * @param netmask the new netmask + * + * @note call netif_set_addr() if you also want to change ip address and + * default gateway + */ +void +netif_set_netmask(struct netif *netif, ip_addr_t *netmask) +{ + snmp_delete_iprteidx_tree(0, netif); + /* set new netmask to netif */ + ip_addr_set(&(netif->netmask), netmask); + snmp_insert_iprteidx_tree(0, netif); + LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + netif->name[0], netif->name[1], + ip4_addr1_16(&netif->netmask), + ip4_addr2_16(&netif->netmask), + ip4_addr3_16(&netif->netmask), + ip4_addr4_16(&netif->netmask))); +} + +/** + * Set a network interface as the default network interface + * (used to output all packets for which no specific route is found) + * + * @param netif the default network interface + */ +void +netif_set_default(struct netif *netif) +{ + if (netif == NULL) { + /* remove default route */ + snmp_delete_iprteidx_tree(1, netif); + } else { + /* install default route */ + snmp_insert_iprteidx_tree(1, netif); + } + netif_default = netif; + LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", + netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); +} + +/** + * Bring an interface up, available for processing + * traffic. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_up(struct netif *netif) +{ + if (!(netif->flags & NETIF_FLAG_UP)) { + netif->flags |= NETIF_FLAG_UP; + +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif /* LWIP_SNMP */ + + NETIF_STATUS_CALLBACK(netif); + + if (netif->flags & NETIF_FLAG_LINK_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & (NETIF_FLAG_ETHARP)) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + /* send mld memberships */ + mld6_report_groups( netif); +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + /* Send Router Solicitation messages. */ + netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ + + } + } +} + +/** + * Bring an interface down, disabling any traffic processing. + * + * @note: Enabling DHCP on a down interface will make it come + * up once configured. + * + * @see dhcp_start() + */ +void netif_set_down(struct netif *netif) +{ + if (netif->flags & NETIF_FLAG_UP) { + netif->flags &= ~NETIF_FLAG_UP; +#if LWIP_SNMP + snmp_get_sysuptime(&netif->ts); +#endif + +#if LWIP_ARP + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_cleanup_netif(netif); + } +#endif /* LWIP_ARP */ + NETIF_STATUS_CALLBACK(netif); + } +} + +#if LWIP_NETIF_STATUS_CALLBACK +/** + * Set callback to be called when interface is brought up/down + */ +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) +{ + if (netif) { + netif->status_callback = status_callback; + } +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_REMOVE_CALLBACK +/** + * Set callback to be called when the interface has been removed + */ +void +netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) +{ + if (netif) { + netif->remove_callback = remove_callback; + } +} +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +/** + * Called by a driver when its link goes up + */ +void netif_set_link_up(struct netif *netif ) +{ + if (!(netif->flags & NETIF_FLAG_LINK_UP)) { + netif->flags |= NETIF_FLAG_LINK_UP; + +#if LWIP_DHCP + if (netif->dhcp) { + dhcp_network_changed(netif); + } +#endif /* LWIP_DHCP */ + +#if LWIP_AUTOIP + if (netif->autoip) { + autoip_network_changed(netif); + } +#endif /* LWIP_AUTOIP */ + + if (netif->flags & NETIF_FLAG_UP) { +#if LWIP_ARP + /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ + if (netif->flags & NETIF_FLAG_ETHARP) { + etharp_gratuitous(netif); + } +#endif /* LWIP_ARP */ + +#if LWIP_IGMP + /* resend IGMP memberships */ + if (netif->flags & NETIF_FLAG_IGMP) { + igmp_report_groups( netif); + } +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + /* send mld memberships */ + mld6_report_groups( netif); +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + } + NETIF_LINK_CALLBACK(netif); + } +} + +/** + * Called by a driver when its link goes down + */ +void netif_set_link_down(struct netif *netif ) +{ + if (netif->flags & NETIF_FLAG_LINK_UP) { + netif->flags &= ~NETIF_FLAG_LINK_UP; + NETIF_LINK_CALLBACK(netif); + } +} + +#if LWIP_NETIF_LINK_CALLBACK +/** + * Set callback to be called when link is brought up/down + */ +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) +{ + if (netif) { + netif->link_callback = link_callback; + } +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if ENABLE_LOOPBACK +/** + * Send an IP packet to be received on the same netif (loopif-like). + * The pbuf is simply copied and handed back to netif->input. + * In multithreaded mode, this is done directly since netif->input must put + * the packet on a queue. + * In callback mode, the packet is put on an internal queue and is fed to + * netif->input by netif_poll(). + * + * @param netif the lwip network interface structure + * @param p the (IP) packet to 'send' + * @return ERR_OK if the packet has been sent + * ERR_MEM if the pbuf used to copy the packet couldn't be allocated + */ +err_t +netif_loop_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *r; + err_t err; + struct pbuf *last; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = 0; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + + /* Allocate a new pbuf */ + r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); + if (r == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } +#if LWIP_LOOPBACK_MAX_PBUFS + clen = pbuf_clen(r); + /* check for overflow or too many pbuf on queue */ + if(((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || + ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return ERR_MEM; + } + netif->loop_cnt_current += clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + + /* Copy the whole pbuf queue p into the single pbuf r */ + if ((err = pbuf_copy(r, p)) != ERR_OK) { + pbuf_free(r); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(stats_if); + return err; + } + + /* Put the packet on a linked list which gets emptied through calling + netif_poll(). */ + + /* let last point to the last pbuf in chain r */ + for (last = r; last->next != NULL; last = last->next); + + SYS_ARCH_PROTECT(lev); + if (netif->loop_first != NULL) { + LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); + netif->loop_last->next = r; + netif->loop_last = last; + } else { + netif->loop_first = r; + netif->loop_last = last; + } + SYS_ARCH_UNPROTECT(lev); + + LINK_STATS_INC(link.xmit); + snmp_add_ifoutoctets(stats_if, p->tot_len); + snmp_inc_ifoutucastpkts(stats_if); + +#if LWIP_NETIF_LOOPBACK_MULTITHREADING + /* For multithreading environment, schedule a call to netif_poll */ + tcpip_callback_with_block((tcpip_callback_fn)netif_poll, netif, 0); +#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ + + return ERR_OK; +} + +static err_t +netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, ip_addr_t* addr) +{ + LWIP_UNUSED_ARG(addr); + return netif_loop_output(netif, p); +} + +#if LWIP_IPV6 +static err_t +netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, ip6_addr_t* addr) +{ + LWIP_UNUSED_ARG(addr); + return netif_loop_output(netif, p); +} +#endif + + +/** + * Call netif_poll() in the main loop of your application. This is to prevent + * reentering non-reentrant functions like tcp_input(). Packets passed to + * netif_loop_output() are put on a list that is passed to netif->input() by + * netif_poll(). + */ +void +netif_poll(struct netif *netif) +{ + struct pbuf *in; + /* If we have a loopif, SNMP counters are adjusted for it, + * if not they are adjusted for 'netif'. */ +#if LWIP_SNMP +#if LWIP_HAVE_LOOPIF + struct netif *stats_if = &loop_netif; +#else /* LWIP_HAVE_LOOPIF */ + struct netif *stats_if = netif; +#endif /* LWIP_HAVE_LOOPIF */ +#endif /* LWIP_SNMP */ + SYS_ARCH_DECL_PROTECT(lev); + + do { + /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ + SYS_ARCH_PROTECT(lev); + in = netif->loop_first; + if (in != NULL) { + struct pbuf *in_end = in; +#if LWIP_LOOPBACK_MAX_PBUFS + u8_t clen = 1; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + while (in_end->len != in_end->tot_len) { + LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); + in_end = in_end->next; +#if LWIP_LOOPBACK_MAX_PBUFS + clen++; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + } +#if LWIP_LOOPBACK_MAX_PBUFS + /* adjust the number of pbufs on queue */ + LWIP_ASSERT("netif->loop_cnt_current underflow", + ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); + netif->loop_cnt_current -= clen; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ + + /* 'in_end' now points to the last pbuf from 'in' */ + if (in_end == netif->loop_last) { + /* this was the last pbuf in the list */ + netif->loop_first = netif->loop_last = NULL; + } else { + /* pop the pbuf off the list */ + netif->loop_first = in_end->next; + LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); + } + /* De-queue the pbuf from its successors on the 'loop_' list. */ + in_end->next = NULL; + } + SYS_ARCH_UNPROTECT(lev); + + if (in != NULL) { + LINK_STATS_INC(link.recv); + snmp_add_ifinoctets(stats_if, in->tot_len); + snmp_inc_ifinucastpkts(stats_if); + /* loopback packets are always IP packets! */ + if (ipX_input(in, netif) != ERR_OK) { + pbuf_free(in); + } + /* Don't reference the packet any more! */ + in = NULL; + } + /* go on while there is a packet on the list */ + } while (netif->loop_first != NULL); +} + +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +/** + * Calls netif_poll() for every netif on the netif_list. + */ +void +netif_poll_all(void) +{ + struct netif *netif = netif_list; + /* loop through netifs */ + while (netif != NULL) { + netif_poll(netif); + /* proceed to next network interface */ + netif = netif->next; + } +} +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_IPV6 +s8_t +netif_get_ip6_addr_match(struct netif * netif, ip6_addr_t * ip6addr) +{ + s8_t i; + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_cmp(netif_ip6_addr(netif, i), ip6addr)) { + return i; + } + } + return -1; +} + +void +netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit) +{ + u8_t i, addr_index; + + /* Link-local prefix. */ + netif->ip6_addr[0].addr[0] = PP_HTONL(0xfe800000ul); + netif->ip6_addr[0].addr[1] = 0; + + /* Generate interface ID. */ + if (from_mac_48bit) { + /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ + netif->ip6_addr[0].addr[2] = htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | + ((u32_t)(netif->hwaddr[1]) << 16) | + ((u32_t)(netif->hwaddr[2]) << 8) | + (0xff)); + netif->ip6_addr[0].addr[3] = htonl((0xfeul << 24) | + ((u32_t)(netif->hwaddr[3]) << 16) | + ((u32_t)(netif->hwaddr[4]) << 8) | + (netif->hwaddr[5])); + } + else { + /* Use hwaddr directly as interface ID. */ + netif->ip6_addr[0].addr[2] = 0; + netif->ip6_addr[0].addr[3] = 0; + + addr_index = 3; + for (i = 0; i < 8; i++) { + if (i == 4) { + addr_index--; + } + netif->ip6_addr[0].addr[addr_index] |= ((u32_t)(netif->hwaddr[netif->hwaddr_len - i - 1])) << (8 * (i & 0x03)); + } + } + + /* Set address state. */ +#if LWIP_IPV6_DUP_DETECT_ATTEMPTS + /* Will perform duplicate address detection (DAD). */ + netif->ip6_addr_state[0] = IP6_ADDR_TENTATIVE; +#else + /* Consider address valid. */ + netif->ip6_addr_state[0] = IP6_ADDR_PREFERRED; +#endif /* LWIP_IPV6_AUTOCONFIG */ +} + +static err_t +netif_null_output_ip6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr) +{ + (void)netif; + (void)p; + (void)ipaddr; + + return ERR_IF; +} +#endif /* LWIP_IPV6 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/pbuf.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/pbuf.c new file mode 100644 index 0000000..1a91d75 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/pbuf.c @@ -0,0 +1,1329 @@ +/** + * @file + * Packet buffer management + * + * Packets are built from the pbuf data structure. It supports dynamic + * memory allocation for packet contents or can reference externally + * managed packet contents both in RAM and ROM. Quick allocation for + * incoming packets is provided through pools with fixed sized pbufs. + * + * A packet may span over multiple pbufs, chained as a singly linked + * list. This is called a "pbuf chain". + * + * Multiple packets may be queued, also using this singly linked list. + * This is called a "packet queue". + * + * So, a packet queue consists of one or more pbuf chains, each of + * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE + * NOT SUPPORTED!!! Use helper structs to queue multiple packets. + * + * The differences between a pbuf chain and a packet queue are very + * precise but subtle. + * + * The last pbuf of a packet has a ->tot_len field that equals the + * ->len field. It can be found by traversing the list. If the last + * pbuf of a packet has a ->next field other than NULL, more packets + * are on the queue. + * + * Therefore, looping through a pbuf of a single packet, has an + * loop end condition (tot_len == p->len), NOT (next == NULL). + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/stats.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include "arch/perf.h" +#if LWIP_TCP && TCP_QUEUE_OOSEQ +#include "lwip/tcp_impl.h" +#endif +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#include + +#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) +/* Since the pool is created in memp, PBUF_POOL_BUFSIZE will be automatically + aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */ +#define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) + +#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_IS_EMPTY() +#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +#if !NO_SYS +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL +#include "lwip/tcpip.h" +#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ + if(tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ + SYS_ARCH_PROTECT(old_level); \ + pbuf_free_ooseq_pending = 0; \ + SYS_ARCH_UNPROTECT(old_level); \ + } } while(0) +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +#endif /* !NO_SYS */ + +volatile u8_t pbuf_free_ooseq_pending; +#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() + +/** + * Attempt to reclaim some memory from queued out-of-sequence TCP segments + * if we run out of pool pbufs. It's better to give priority to new packets + * if we're running out. + * + * This must be done in the correct thread context therefore this function + * can only be used with NO_SYS=0 and through tcpip_callback. + */ +#if !NO_SYS +static +#endif /* !NO_SYS */ +void +pbuf_free_ooseq(void) +{ + struct tcp_pcb* pcb; + SYS_ARCH_DECL_PROTECT(old_level); + + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 0; + SYS_ARCH_UNPROTECT(old_level); + + for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { + if (NULL != pcb->ooseq) { + /** Free the ooseq pbufs of one PCB only */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + return; + } + } +} + +#if !NO_SYS +/** + * Just a callback function for tcpip_timeout() that calls pbuf_free_ooseq(). + */ +static void +pbuf_free_ooseq_callback(void *arg) +{ + LWIP_UNUSED_ARG(arg); + pbuf_free_ooseq(); +} +#endif /* !NO_SYS */ + +/** Queue a call to pbuf_free_ooseq if not already queued. */ +static void +pbuf_pool_is_empty(void) +{ +#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); +#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ + u8_t queued; + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); + queued = pbuf_free_ooseq_pending; + pbuf_free_ooseq_pending = 1; + SYS_ARCH_UNPROTECT(old_level); + + if(!queued) { + /* queue a call to pbuf_free_ooseq if not already queued */ + PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); + } +#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ +} +#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ + +/** + * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). + * + * The actual memory allocated for the pbuf is determined by the + * layer at which the pbuf is allocated and the requested size + * (from the size parameter). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type this parameter decides how and where the pbuf + * should be allocated as follows: + * + * - PBUF_RAM: buffer memory for pbuf is allocated as one large + * chunk. This includes protocol headers as well. + * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for + * protocol headers. Additional headers must be prepended + * by allocating another pbuf and chain in to the front of + * the ROM pbuf. It is assumed that the memory used is really + * similar to ROM in that it is immutable and will not be + * changed. Memory which is dynamic should generally not + * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. + * - PBUF_REF: no buffer memory is allocated for the pbuf, even for + * protocol headers. It is assumed that the pbuf is only + * being used in a single thread. If the pbuf gets queued, + * then pbuf_take should be called to copy the buffer. + * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from + * the pbuf pool that is allocated during pbuf_init(). + * + * @return the allocated pbuf. If multiple pbufs where allocated, this + * is the first pbuf of a pbuf chain. + */ +struct pbuf * +pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) +{ + struct pbuf *p, *q, *r; + u16_t offset; + s32_t rem_len; /* remaining length */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (layer) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); + return NULL; + } + + switch (type) { + case PBUF_POOL: + /* allocate head of pbuf chain into p */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p\n", (void *)p)); + if (p == NULL) { + PBUF_POOL_IS_EMPTY(); + return NULL; + } + p->type = type; + p->next = NULL; + + /* make the payload pointer point 'offset' bytes into pbuf data memory */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); + LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + /* the total length of the pbuf chain is the requested size */ + p->tot_len = length; + /* set the length of the first pbuf in the chain */ + p->len = LWIP_MIN(length, PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", + (PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); + /* set reference count (needed here in case we fail) */ + p->ref = 1; + + /* now allocate the tail of the pbuf chain */ + + /* remember first pbuf for linkage in next iteration */ + r = p; + /* remaining length to be allocated */ + rem_len = length - p->len; + /* any remaining pbufs to be allocated? */ + while (rem_len > 0) { + q = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); + if (q == NULL) { + PBUF_POOL_IS_EMPTY(); + /* free chain so far allocated */ + pbuf_free(p); + /* bail out unsuccessfully */ + return NULL; + } + q->type = type; + q->flags = 0; + q->next = NULL; + /* make previous pbuf point to this pbuf */ + r->next = q; + /* set total length of this pbuf and next in chain */ + LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); + q->tot_len = (u16_t)rem_len; + /* this pbuf length is pool size, unless smaller sized tail */ + q->len = LWIP_MIN((u16_t)rem_len, PBUF_POOL_BUFSIZE_ALIGNED); + q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); + LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", + ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); + LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", + ((u8_t*)p->payload + p->len <= + (u8_t*)p + SIZEOF_STRUCT_PBUF + PBUF_POOL_BUFSIZE_ALIGNED)); + q->ref = 1; + /* calculate remaining length to be allocated */ + rem_len -= q->len; + /* remember this pbuf for linkage in next iteration */ + r = q; + } + /* end of chain */ + /*r->next = NULL;*/ + + break; + case PBUF_RAM: + /* If pbuf is to be allocated in RAM, allocate memory for it. */ + p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length)); + if (p == NULL) { + return NULL; + } + /* Set up internal structure of the pbuf. */ + p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + + LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", + ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); + break; + /* pbuf references existing (non-volatile static constant) ROM payload? */ + case PBUF_ROM: + /* pbuf references existing (externally allocated) RAM payload? */ + case PBUF_REF: + /* only allocate memory for the pbuf structure */ + p = (struct pbuf *)memp_malloc(MEMP_PBUF); + if (p == NULL) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", + (type == PBUF_ROM) ? "ROM" : "REF")); + return NULL; + } + /* caller must set this field properly, afterwards */ + p->payload = NULL; + p->len = p->tot_len = length; + p->next = NULL; + p->type = type; + break; + default: + LWIP_ASSERT("pbuf_alloc: erroneous type", 0); + return NULL; + } + /* set reference count */ + p->ref = 1; + /* set flags */ + p->flags = 0; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); + return p; +} + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Initialize a custom pbuf (already allocated). + * + * @param layer flag to define header size + * @param length size of the pbuf's payload + * @param type type of the pbuf (only used to treat the pbuf accordingly, as + * this function allocates no memory) + * @param p pointer to the custom pbuf to initialize (already allocated) + * @param payload_mem pointer to the buffer that is used for payload and headers, + * must be at least big enough to hold 'length' plus the header size, + * may be NULL if set later. + * ATTENTION: The caller is responsible for correct alignment of this buffer!! + * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least + * big enough to hold 'length' plus the header size + */ +struct pbuf* +pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, + void *payload_mem, u16_t payload_mem_len) +{ + u16_t offset; + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); + + /* determine header offset */ + switch (l) { + case PBUF_TRANSPORT: + /* add room for transport (often TCP) layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; + break; + case PBUF_IP: + /* add room for IP layer header */ + offset = PBUF_LINK_HLEN + PBUF_IP_HLEN; + break; + case PBUF_LINK: + /* add room for link layer header */ + offset = PBUF_LINK_HLEN; + break; + case PBUF_RAW: + offset = 0; + break; + default: + LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); + return NULL; + } + + if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); + return NULL; + } + + p->pbuf.next = NULL; + if (payload_mem != NULL) { + p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); + } else { + p->pbuf.payload = NULL; + } + p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; + p->pbuf.len = p->pbuf.tot_len = length; + p->pbuf.type = type; + p->pbuf.ref = 1; + return &p->pbuf; +} +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +/** + * Shrink a pbuf chain to a desired length. + * + * @param p pbuf to shrink. + * @param new_len desired new length of pbuf chain + * + * Depending on the desired length, the first few pbufs in a chain might + * be skipped and left unchanged. The new last pbuf in the chain will be + * resized, and any remaining pbufs will be freed. + * + * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. + * @note May not be called on a packet queue. + * + * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). + */ +void +pbuf_realloc(struct pbuf *p, u16_t new_len) +{ + struct pbuf *q; + u16_t rem_len; /* remaining length */ + s32_t grow; + + LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); + LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || + p->type == PBUF_ROM || + p->type == PBUF_RAM || + p->type == PBUF_REF); + + /* desired length larger than current length? */ + if (new_len >= p->tot_len) { + /* enlarging not yet supported */ + return; + } + + /* the pbuf chain grows by (new_len - p->tot_len) bytes + * (which may be negative in case of shrinking) */ + grow = new_len - p->tot_len; + + /* first, step over any pbufs that should remain in the chain */ + rem_len = new_len; + q = p; + /* should this pbuf be kept? */ + while (rem_len > q->len) { + /* decrease remaining length by pbuf length */ + rem_len -= q->len; + /* decrease total length indicator */ + LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); + q->tot_len += (u16_t)grow; + /* proceed to next pbuf in chain */ + q = q->next; + LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); + } + /* we have now reached the new last pbuf (in q) */ + /* rem_len == desired length for pbuf q */ + + /* shrink allocated memory for PBUF_RAM */ + /* (other types merely adjust their length fields */ + if ((q->type == PBUF_RAM) && (rem_len != q->len)) { + /* reallocate and adjust the length of the pbuf that will be split */ + q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); + LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); + } + /* adjust length fields for new last pbuf */ + q->len = rem_len; + q->tot_len = q->len; + + /* any remaining pbufs in chain? */ + if (q->next != NULL) { + /* free remaining pbufs in chain */ + pbuf_free(q->next); + } + /* q is last packet in chain */ + q->next = NULL; + +} + +/** + * Adjusts the payload pointer to hide or reveal headers in the payload. + * @see pbuf_header. + * + * @param p pbuf to change the header size. + * @param header_size_increment Number of bytes to increment header size. + * @param force Allow 'header_size_increment > 0' for PBUF_REF/PBUF_ROM types + * + * @return non-zero on failure, zero on success. + * + */ +static u8_t +pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force) +{ + u16_t type; + void *payload; + u16_t increment_magnitude; + + LWIP_ASSERT("p != NULL", p != NULL); + if ((header_size_increment == 0) || (p == NULL)) { + return 0; + } + + if (header_size_increment < 0){ + increment_magnitude = -header_size_increment; + /* Check that we aren't going to move off the end of the pbuf */ + LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); + } else { + increment_magnitude = header_size_increment; +#if 0 + /* Can't assert these as some callers speculatively call + pbuf_header() to see if it's OK. Will return 1 below instead. */ + /* Check that we've got the correct type of pbuf to work with */ + LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", + p->type == PBUF_RAM || p->type == PBUF_POOL); + /* Check that we aren't going to move off the beginning of the pbuf */ + LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", + (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); +#endif + } + + type = p->type; + /* remember current payload pointer */ + payload = p->payload; + + /* pbuf types containing payloads? */ + if (type == PBUF_RAM || type == PBUF_POOL) { + /* set new payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + /* boundary check fails? */ + if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", + (void *)p->payload, (void *)(p + 1))); + /* restore old payload pointer */ + p->payload = payload; + /* bail out unsuccessfully */ + return 1; + } + /* pbuf types referring to external payloads? */ + } else if (type == PBUF_REF || type == PBUF_ROM) { + /* hide a header in the payload? */ + if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { + /* increase payload pointer */ + p->payload = (u8_t *)p->payload - header_size_increment; + } else if ((header_size_increment > 0) && force) { + p->payload = (u8_t *)p->payload - header_size_increment; + } else { + /* cannot expand payload to front (yet!) + * bail out unsuccessfully */ + return 1; + } + } else { + /* Unknown type */ + LWIP_ASSERT("bad pbuf type", 0); + return 1; + } + /* modify pbuf length fields */ + p->len += header_size_increment; + p->tot_len += header_size_increment; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", + (void *)payload, (void *)p->payload, header_size_increment)); + + return 0; +} + +/** + * Adjusts the payload pointer to hide or reveal headers in the payload. + * + * Adjusts the ->payload pointer so that space for a header + * (dis)appears in the pbuf payload. + * + * The ->payload, ->tot_len and ->len fields are adjusted. + * + * @param p pbuf to change the header size. + * @param header_size_increment Number of bytes to increment header size which + * increases the size of the pbuf. New space is on the front. + * (Using a negative value decreases the header size.) + * If hdr_size_inc is 0, this function does nothing and returns successful. + * + * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so + * the call will fail. A check is made that the increase in header size does + * not move the payload pointer in front of the start of the buffer. + * @return non-zero on failure, zero on success. + * + */ +u8_t +pbuf_header(struct pbuf *p, s16_t header_size_increment) +{ + return pbuf_header_impl(p, header_size_increment, 0); +} + +/** + * Same as pbuf_header but does not check if 'header_size > 0' is allowed. + * This is used internally only, to allow PBUF_REF for RX. + */ +u8_t +pbuf_header_force(struct pbuf *p, s16_t header_size_increment) +{ + return pbuf_header_impl(p, header_size_increment, 1); +} + +/** + * Dereference a pbuf chain or queue and deallocate any no-longer-used + * pbufs at the head of this chain or queue. + * + * Decrements the pbuf reference count. If it reaches zero, the pbuf is + * deallocated. + * + * For a pbuf chain, this is repeated for each pbuf in the chain, + * up to the first pbuf which has a non-zero reference count after + * decrementing. So, when all reference counts are one, the whole + * chain is free'd. + * + * @param p The pbuf (chain) to be dereferenced. + * + * @return the number of pbufs that were de-allocated + * from the head of the chain. + * + * @note MUST NOT be called on a packet queue (Not verified to work yet). + * @note the reference counter of a pbuf equals the number of pointers + * that refer to the pbuf (or into the pbuf). + * + * @internal examples: + * + * Assuming existing chains a->b->c with the following reference + * counts, calling pbuf_free(a) results in: + * + * 1->2->3 becomes ...1->3 + * 3->3->3 becomes 2->3->3 + * 1->1->2 becomes ......1 + * 2->1->1 becomes 1->1->1 + * 1->1->1 becomes ....... + * + */ +u8_t +pbuf_free(struct pbuf *p) +{ + u16_t type; + struct pbuf *q; + u8_t count; + + if (p == NULL) { + LWIP_ASSERT("p != NULL", p != NULL); + /* if assertions are disabled, proceed with debug output */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("pbuf_free(p == NULL) was called.\n")); + return 0; + } + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); + + PERF_START; + + LWIP_ASSERT("pbuf_free: sane type", + p->type == PBUF_RAM || p->type == PBUF_ROM || + p->type == PBUF_REF || p->type == PBUF_POOL); + + count = 0; + /* de-allocate all consecutive pbufs from the head of the chain that + * obtain a zero reference count after decrementing*/ + while (p != NULL) { + u16_t ref; + SYS_ARCH_DECL_PROTECT(old_level); + /* Since decrementing ref cannot be guaranteed to be a single machine operation + * we must protect it. We put the new ref into a local variable to prevent + * further protection. */ + SYS_ARCH_PROTECT(old_level); + /* all pbufs in a chain are referenced at least once */ + LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); + /* decrease reference count (number of pointers to pbuf) */ + ref = --(p->ref); + SYS_ARCH_UNPROTECT(old_level); + /* this pbuf is no longer referenced to? */ + if (ref == 0) { + /* remember next pbuf in chain for next iteration */ + q = p->next; + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); + type = p->type; +#if LWIP_SUPPORT_CUSTOM_PBUF + /* is this a custom pbuf? */ + if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { + struct pbuf_custom *pc = (struct pbuf_custom*)p; + LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); + pc->custom_free_function(p); + } else +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + { + /* is this a pbuf from the pool? */ + if (type == PBUF_POOL) { + memp_free(MEMP_PBUF_POOL, p); + /* is this a ROM or RAM referencing pbuf? */ + } else if (type == PBUF_ROM || type == PBUF_REF) { + memp_free(MEMP_PBUF, p); + /* type == PBUF_RAM */ + } else { + mem_free(p); + } + } + count++; + /* proceed to next pbuf */ + p = q; + /* p->ref > 0, this pbuf is still referenced to */ + /* (and so the remaining pbufs in chain as well) */ + } else { + LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); + /* stop walking through the chain */ + p = NULL; + } + } + PERF_STOP("pbuf_free"); + /* return number of de-allocated pbufs */ + return count; +} + +/** + * Count number of pbufs in a chain + * + * @param p first pbuf of chain + * @return the number of pbufs in a chain + */ + +u8_t +pbuf_clen(struct pbuf *p) +{ + u8_t len; + + len = 0; + while (p != NULL) { + ++len; + p = p->next; + } + return len; +} + +/** + * Increment the reference count of the pbuf. + * + * @param p pbuf to increase reference counter of + * + */ +void +pbuf_ref(struct pbuf *p) +{ + SYS_ARCH_DECL_PROTECT(old_level); + /* pbuf given? */ + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + ++(p->ref); + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Concatenate two pbufs (each may be a pbuf chain) and take over + * the caller's reference of the tail pbuf. + * + * @note The caller MAY NOT reference the tail pbuf afterwards. + * Use pbuf_chain() for that purpose. + * + * @see pbuf_chain() + */ + +void +pbuf_cat(struct pbuf *h, struct pbuf *t) +{ + struct pbuf *p; + + LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", + ((h != NULL) && (t != NULL)), return;); + + /* proceed to last pbuf of chain */ + for (p = h; p->next != NULL; p = p->next) { + /* add total length of second chain to all totals of first chain */ + p->tot_len += t->tot_len; + } + /* { p is last pbuf of first h chain, p->next == NULL } */ + LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); + LWIP_ASSERT("p->next == NULL", p->next == NULL); + /* add total length of second chain to last pbuf total of first chain */ + p->tot_len += t->tot_len; + /* chain last pbuf of head (p) with first of tail (t) */ + p->next = t; + /* p->next now references t, but the caller will drop its reference to t, + * so netto there is no change to the reference count of t. + */ +} + +/** + * Chain two pbufs (or pbuf chains) together. + * + * The caller MUST call pbuf_free(t) once it has stopped + * using it. Use pbuf_cat() instead if you no longer use t. + * + * @param h head pbuf (chain) + * @param t tail pbuf (chain) + * @note The pbufs MUST belong to the same packet. + * @note MAY NOT be called on a packet queue. + * + * The ->tot_len fields of all pbufs of the head chain are adjusted. + * The ->next field of the last pbuf of the head chain is adjusted. + * The ->ref field of the first pbuf of the tail chain is adjusted. + * + */ +void +pbuf_chain(struct pbuf *h, struct pbuf *t) +{ + pbuf_cat(h, t); + /* t is now referenced by h */ + pbuf_ref(t); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); +} + +/** + * Dechains the first pbuf from its succeeding pbufs in the chain. + * + * Makes p->tot_len field equal to p->len. + * @param p pbuf to dechain + * @return remainder of the pbuf chain, or NULL if it was de-allocated. + * @note May not be called on a packet queue. + */ +struct pbuf * +pbuf_dechain(struct pbuf *p) +{ + struct pbuf *q; + u8_t tail_gone = 1; + /* tail */ + q = p->next; + /* pbuf has successor in chain? */ + if (q != NULL) { + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); + /* enforce invariant if assertion is disabled */ + q->tot_len = p->tot_len - p->len; + /* decouple pbuf from remainder */ + p->next = NULL; + /* total length of pbuf p is its own length only */ + p->tot_len = p->len; + /* q is no longer referenced by p, free it */ + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); + tail_gone = pbuf_free(q); + if (tail_gone > 0) { + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, + ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); + } + /* return remaining tail or NULL if deallocated */ + } + /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ + LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); + return ((tail_gone > 0) ? NULL : q); +} + +/** + * + * Create PBUF_RAM copies of pbufs. + * + * Used to queue packets on behalf of the lwIP stack, such as + * ARP based queueing. + * + * @note You MUST explicitly use p = pbuf_take(p); + * + * @note Only one packet is copied, no packet queue! + * + * @param p_to pbuf destination of the copy + * @param p_from pbuf source of the copy + * + * @return ERR_OK if pbuf was copied + * ERR_ARG if one of the pbufs is NULL or p_to is not big + * enough to hold p_from + */ +err_t +pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) +{ + u16_t offset_to=0, offset_from=0, len; + + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", + (void*)p_to, (void*)p_from)); + + /* is the target big enough to hold the source? */ + LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && + (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); + + /* iterate through pbuf chain */ + do + { + /* copy one part of the original chain */ + if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { + /* complete current p_from fits into current p_to */ + len = p_from->len - offset_from; + } else { + /* current p_from does not fit into current p_to */ + len = p_to->len - offset_to; + } + MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); + offset_to += len; + offset_from += len; + LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); + LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); + if (offset_from >= p_from->len) { + /* on to next p_from (if any) */ + offset_from = 0; + p_from = p_from->next; + } + if (offset_to == p_to->len) { + /* on to next p_to (if any) */ + offset_to = 0; + p_to = p_to->next; + LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); + } + + if((p_from != NULL) && (p_from->len == p_from->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!", + (p_from->next == NULL), return ERR_VAL;); + } + if((p_to != NULL) && (p_to->len == p_to->tot_len)) { + /* don't copy more than one packet! */ + LWIP_ERROR("pbuf_copy() does not allow packet queues!", + (p_to->next == NULL), return ERR_VAL;); + } + } while (p_from); + LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); + return ERR_OK; +} + +/** + * Copy (part of) the contents of a packet buffer + * to an application supplied buffer. + * + * @param buf the pbuf from which to copy data + * @param dataptr the application supplied buffer + * @param len length of data to copy (dataptr must be big enough). No more + * than buf->tot_len will be copied, irrespective of len + * @param offset offset into the packet buffer from where to begin copying len bytes + * @return the number of bytes copied, or 0 on failure + */ +u16_t +pbuf_copy_partial(struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) +{ + struct pbuf *p; + u16_t left; + u16_t buf_copy_len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); + + left = 0; + + if((buf == NULL) || (dataptr == NULL)) { + return 0; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; len != 0 && p != NULL; p = p->next) { + if ((offset != 0) && (offset >= p->len)) { + /* don't copy from this buffer -> on to the next */ + offset -= p->len; + } else { + /* copy from this buffer. maybe only partially. */ + buf_copy_len = p->len - offset; + if (buf_copy_len > len) + buf_copy_len = len; + /* copy the necessary parts of the buffer */ + MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); + copied_total += buf_copy_len; + left += buf_copy_len; + len -= buf_copy_len; + offset = 0; + } + } + return copied_total; +} + +#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE +/** + * This method modifies a 'pbuf chain', so that its total length is + * smaller than 64K. The remainder of the original pbuf chain is stored + * in *rest. + * This function never creates new pbufs, but splits an existing chain + * in two parts. The tot_len of the modified packet queue will likely be + * smaller than 64K. + * 'packet queues' are not supported by this function. + * + * @param p the pbuf queue to be split + * @param rest pointer to store the remainder (after the first 64K) + */ +void pbuf_split_64k(struct pbuf *p, struct pbuf **rest) +{ + *rest = NULL; + if ((p != NULL) && (p->next != NULL)) { + u16_t tot_len_front = p->len; + struct pbuf *i = p; + struct pbuf *r = p->next; + + /* continue until the total length (summed up as u16_t) overflows */ + while ((r != NULL) && ((u16_t)(tot_len_front + r->len) > tot_len_front)) { + tot_len_front += r->len; + i = r; + r = r->next; + } + /* i now points to last packet of the first segment. Set next + pointer to NULL */ + i->next = NULL; + + if (r != NULL) { + /* Update the tot_len field in the first part */ + for (i = p; i != NULL; i = i->next) { + i->tot_len -= r->tot_len; + LWIP_ASSERT("tot_len/len mismatch in last pbuf", + (i->next != NULL) || (i->tot_len == i->len)); + } + if (p->flags & PBUF_FLAG_TCP_FIN) { + r->flags |= PBUF_FLAG_TCP_FIN; + } + + /* tot_len field in rest does not need modifications */ + /* reference counters do not need modifications */ + *rest = r; + } + } +} +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + +/** + * Skip a number of bytes at the start of a pbuf + * + * @param in input pbuf + * @param in_offset offset to skip + * @param out_offset resulting offset in the returned pbuf + * @return the pbuf in the queue where the offset is + */ +static struct pbuf* +pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset) +{ + u16_t offset_left = in_offset; + struct pbuf* q = in; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= offset_left)) { + offset_left -= q->len; + q = q->next; + } + if (out_offset != NULL) { + *out_offset = offset_left; + } + return q; +} + +/** + * Copy application supplied data into a pbuf. + * This function can only be used to copy the equivalent of buf->tot_len data. + * + * @param buf pbuf to fill with data + * @param dataptr application supplied data buffer + * @param len length of the application supplied data buffer + * + * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough + */ +err_t +pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) +{ + struct pbuf *p; + u16_t buf_copy_len; + u16_t total_copy_len = len; + u16_t copied_total = 0; + + LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return 0;); + LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return 0;); + + if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { + return ERR_ARG; + } + + /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ + for(p = buf; total_copy_len != 0; p = p->next) { + LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); + buf_copy_len = total_copy_len; + if (buf_copy_len > p->len) { + /* this pbuf cannot hold all remaining data */ + buf_copy_len = p->len; + } + /* copy the necessary parts of the buffer */ + MEMCPY(p->payload, &((char*)dataptr)[copied_total], buf_copy_len); + total_copy_len -= buf_copy_len; + copied_total += buf_copy_len; + } + LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); + return ERR_OK; +} + +/** + * Same as pbuf_take() but puts data at an offset + * + * @param buf pbuf to fill with data + * @param dataptr application supplied data buffer + * @param len length of the application supplied data buffer + * + * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough + */ +err_t +pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset) +{ + u16_t target_offset; + struct pbuf* q = pbuf_skip(buf, offset, &target_offset); + + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->tot_len >= target_offset + len)) { + u16_t remaining_len = len; + u8_t* src_ptr = (u8_t*)dataptr; + if (target_offset > 0) { + /* copy the part that goes into the first pbuf */ + u16_t first_copy_len = LWIP_MIN(q->len - target_offset, len); + MEMCPY(((u8_t*)q->payload) + target_offset, dataptr, first_copy_len); + remaining_len -= first_copy_len; + src_ptr += first_copy_len; + } + if (remaining_len > 0) { + return pbuf_take(q->next, src_ptr, remaining_len); + } + return ERR_OK; + } + return ERR_MEM; +} + +/** + * Creates a single pbuf out of a queue of pbufs. + * + * @remark: Either the source pbuf 'p' is freed by this function or the original + * pbuf 'p' is returned, therefore the caller has to check the result! + * + * @param p the source pbuf + * @param layer pbuf_layer of the new pbuf + * + * @return a new, single pbuf (p->next is NULL) + * or the old pbuf if allocation fails + */ +struct pbuf* +pbuf_coalesce(struct pbuf *p, pbuf_layer layer) +{ + struct pbuf *q; + err_t err; + if (p->next == NULL) { + return p; + } + q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); + if (q == NULL) { + /* @todo: what do we do now? */ + return p; + } + err = pbuf_copy(q, p); + LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); + pbuf_free(p); + return q; +} + +#if LWIP_CHECKSUM_ON_COPY +/** + * Copies data into a single pbuf (*not* into a pbuf queue!) and updates + * the checksum while copying + * + * @param p the pbuf to copy data into + * @param start_offset offset of p->payload where to copy the data to + * @param dataptr data to copy into the pbuf + * @param len length of data to copy into the pbuf + * @param chksum pointer to the checksum which is updated + * @return ERR_OK if successful, another error if the data does not fit + * within the (first) pbuf (no pbuf queues!) + */ +err_t +pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum) +{ + u32_t acc; + u16_t copy_chksum; + char *dst_ptr; + LWIP_ASSERT("p != NULL", p != NULL); + LWIP_ASSERT("dataptr != NULL", dataptr != NULL); + LWIP_ASSERT("chksum != NULL", chksum != NULL); + LWIP_ASSERT("len != 0", len != 0); + + if ((start_offset >= p->len) || (start_offset + len > p->len)) { + return ERR_ARG; + } + + dst_ptr = ((char*)p->payload) + start_offset; + copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); + if ((start_offset & 1) != 0) { + copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); + } + acc = *chksum; + acc += copy_chksum; + *chksum = FOLD_U32T(acc); + return ERR_OK; +} +#endif /* LWIP_CHECKSUM_ON_COPY */ + + /** Get one byte from the specified position in a pbuf + * WARNING: returns zero for offset >= p->tot_len + * + * @param p pbuf to parse + * @param offset offset into p of the byte to return + * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len + */ +u8_t +pbuf_get_at(struct pbuf* p, u16_t offset) +{ + u16_t q_idx; + struct pbuf* q = pbuf_skip(p, offset, &q_idx); + + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > q_idx)) { + return ((u8_t*)q->payload)[q_idx]; + } + return 0; +} + + /** Put one byte to the specified position in a pbuf + * WARNING: silently ignores offset >= p->tot_len + * + * @param p pbuf to fill + * @param offset offset into p of the byte to write + * @param data byte to write at an offset into p + */ +void +pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data) +{ + u16_t q_idx; + struct pbuf* q = pbuf_skip(p, offset, &q_idx); + + /* write requested data if pbuf is OK */ + if ((q != NULL) && (q->len > q_idx)) { + ((u8_t*)q->payload)[q_idx] = data; + } +} + +/** Compare pbuf contents at specified offset with memory s2, both of length n + * + * @param p pbuf to compare + * @param offset offset into p at which to start comparing + * @param s2 buffer to compare + * @param n length of buffer to compare + * @return zero if equal, nonzero otherwise + * (0xffff if p is too short, diffoffset+1 otherwise) + */ +u16_t +pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n) +{ + u16_t start = offset; + struct pbuf* q = p; + + /* get the correct pbuf */ + while ((q != NULL) && (q->len <= start)) { + start -= q->len; + q = q->next; + } + /* return requested data if pbuf is OK */ + if ((q != NULL) && (q->len > start)) { + u16_t i; + for(i = 0; i < n; i++) { + u8_t a = pbuf_get_at(q, start + i); + u8_t b = ((u8_t*)s2)[i]; + if (a != b) { + return i+1; + } + } + return 0; + } + return 0xffff; +} + +/** Find occurrence of mem (with length mem_len) in pbuf p, starting at offset + * start_offset. + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param mem search for the contents of this buffer + * @param mem_len length of 'mem' + * @param start_offset offset into p at which to start searching + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset) +{ + u16_t i; + u16_t max = p->tot_len - mem_len; + if (p->tot_len >= mem_len + start_offset) { + for(i = start_offset; i <= max; i++) { + u16_t plus = pbuf_memcmp(p, i, mem, mem_len); + if (plus == 0) { + return i; + } + } + } + return 0xFFFF; +} + +/** Find occurrence of substr with length substr_len in pbuf p, start at offset + * start_offset + * WARNING: in contrast to strstr(), this one does not stop at the first \0 in + * the pbuf/source string! + * + * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as + * return value 'not found' + * @param substr string to search for in p, maximum length is 0xFFFE + * @return 0xFFFF if substr was not found in p or the index where it was found + */ +u16_t +pbuf_strstr(struct pbuf* p, const char* substr) +{ + size_t substr_len; + if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { + return 0xFFFF; + } + substr_len = strlen(substr); + if (substr_len >= 0xFFFF) { + return 0xFFFF; + } + return pbuf_memfind(p, substr, (u16_t)substr_len, 0); +} diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/raw.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/raw.c new file mode 100644 index 0000000..243dd66 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/raw.c @@ -0,0 +1,436 @@ +/** + * @file + * Implementation of raw protocol PCBs for low-level handling of + * different types of protocols besides (or overriding) those + * already available in lwIP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/raw.h" +#include "lwip/stats.h" +#include "arch/perf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" + +#include + +/** The list of RAW PCBs */ +static struct raw_pcb *raw_pcbs; + +/** + * Determine if in incoming IP packet is covered by a RAW PCB + * and if so, pass it to a user-provided receive callback function. + * + * Given an incoming IP datagram (as a chain of pbufs) this function + * finds a corresponding RAW PCB and calls the corresponding receive + * callback function. + * + * @param p pbuf to be demultiplexed to a RAW PCB. + * @param inp network interface on which the datagram was received. + * @return - 1 if the packet has been eaten by a RAW PCB receive + * callback function. The caller MAY NOT not reference the + * packet any longer, and MAY NOT call pbuf_free(). + * @return - 0 if packet is not eaten (pbuf is still referenced by the + * caller). + * + */ +u8_t +raw_input(struct pbuf *p, struct netif *inp) +{ + struct raw_pcb *pcb, *prev; + struct ip_hdr *iphdr; + s16_t proto; + u8_t eaten = 0; + + LWIP_UNUSED_ARG(inp); + + iphdr = (struct ip_hdr *)p->payload; +#if LWIP_IPV6 + if (IPH_V(iphdr) == 6) { + struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; + proto = IP6H_NEXTH(ip6hdr); + iphdr = NULL; + } + else +#endif /* LWIP_IPV6 */ + { + proto = IPH_PROTO(iphdr); + } + + prev = NULL; + pcb = raw_pcbs; + /* loop through all raw pcbs until the packet is eaten by one */ + /* this allows multiple pcbs to match against the packet by design */ + while ((eaten == 0) && (pcb != NULL)) { + if ((pcb->protocol == proto) && IP_PCB_IPVER_INPUT_MATCH(pcb) && + (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip) || + ipX_addr_cmp(PCB_ISIPV6(pcb), &(pcb->local_ip), ipX_current_dest_addr()))) { +#if IP_SOF_BROADCAST_RECV + /* broadcast filter? */ + if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) +#if LWIP_IPV6 + || PCB_ISIPV6(pcb) +#endif /* LWIP_IPV6 */ + ) +#endif /* IP_SOF_BROADCAST_RECV */ + { + /* receive callback function available? */ + if (pcb->recv.ip4 != NULL) { +#ifndef LWIP_NOASSERT + void* old_payload = p->payload; +#endif + /* the receive callback function did not eat the packet? */ +#if LWIP_IPV6 + if (PCB_ISIPV6(pcb)) { + eaten = pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr()); + } else +#endif /* LWIP_IPV6 */ + { + eaten = pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr()); + } + if (eaten != 0) { + /* receive function ate the packet */ + p = NULL; + eaten = 1; + if (prev != NULL) { + /* move the pcb to the front of raw_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + } else { + /* sanity-check that the receive callback did not alter the pbuf */ + LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet", + p->payload == old_payload); + } + } + /* no receive callback function was set for this raw PCB */ + } + /* drop the packet */ + } + prev = pcb; + pcb = pcb->next; + } + return eaten; +} + +/** + * Bind a RAW PCB. + * + * @param pcb RAW PCB to be bound with a local address ipaddr. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified IP address is already bound to by + * another RAW PCB. + * + * @see raw_disconnect() + */ +err_t +raw_bind(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->local_ip, ipaddr); + return ERR_OK; +} + +/** + * Connect an RAW PCB. This function is required by upper layers + * of lwip. Using the raw api you could use raw_sendto() instead + * + * This will associate the RAW PCB with the remote address. + * + * @param pcb RAW PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * + * @return lwIP error code + * + * @see raw_disconnect() and raw_sendto() + */ +err_t +raw_connect(struct raw_pcb *pcb, ip_addr_t *ipaddr) +{ + ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->remote_ip, ipaddr); + return ERR_OK; +} + + +/** + * Set the callback function for received packets that match the + * raw PCB's protocol and binding. + * + * The callback function MUST either + * - eat the packet by calling pbuf_free() and returning non-zero. The + * packet will not be passed to other raw PCBs or other protocol layers. + * - not free the packet, and return zero. The packet will be matched + * against further PCBs and/or forwarded to another protocol layers. + * + * @return non-zero if the packet was free()d, zero if the packet remains + * available for others. + */ +void +raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv.ip4 = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Send the raw IP packet to the given address. Note that actually you cannot + * modify the IP headers (this is inconsistent with the receive callback where + * you actually get the IP headers), you can only specify the IP payload here. + * It requires some more changes in lwIP. (there will be a raw_send() function + * then.) + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * @param ipaddr the destination address of the IP packet + * + */ +err_t +raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr) +{ + err_t err; + struct netif *netif; + ipX_addr_t *src_ip; + struct pbuf *q; /* q will be sent down the stack */ + s16_t header_size; + ipX_addr_t *dst_ip = ip_2_ipX(ipaddr); + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); + + header_size = ( +#if LWIP_IPV6 + PCB_ISIPV6(pcb) ? IP6_HLEN : +#endif /* LWIP_IPV6 */ + IP_HLEN); + + /* not enough space to add an IP header to first pbuf in given p chain? */ + if (pbuf_header(p, header_size)) { + /* allocate header in new pbuf */ + q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p */ + pbuf_chain(q, p); + } + /* { first pbuf q points to header pbuf } */ + LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* first pbuf q equals given pbuf */ + q = p; + if(pbuf_header(q, -header_size)) { + LWIP_ASSERT("Can't restore header we just removed!", 0); + return ERR_MEM; + } + } + + netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip); + if (netif == NULL) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_RTE; + } + +#if IP_SOF_BROADCAST +#if LWIP_IPV6 + if (!PCB_ISIPV6(pcb)) +#endif /* LWIP_IPV6 */ + { + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) { + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + /* free any temporary header pbuf allocated by pbuf_header() */ + if (q != p) { + pbuf_free(q); + } + return ERR_VAL; + } + } +#endif /* IP_SOF_BROADCAST */ + + if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { + /* use outgoing network interface IP address as source address */ + src_ip = ipX_netif_get_local_ipX(PCB_ISIPV6(pcb), netif, dst_ip); +#if LWIP_IPV6 + if (src_ip == NULL) { + if (q != p) { + pbuf_free(q); + } + return ERR_RTE; + } +#endif /* LWIP_IPV6 */ + } else { + /* use RAW PCB local IP address as source address */ + src_ip = &pcb->local_ip; + } + +#if LWIP_IPV6 + /* If requested, based on the IPV6_CHECKSUM socket option per RFC3542, + compute the checksum and update the checksum in the payload. */ + if (PCB_ISIPV6(pcb) && pcb->chksum_reqd) { + u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ipX_2_ip6(src_ip), ipX_2_ip6(dst_ip)); + LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2)); + SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t)); + } +#endif + + NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint); + err = ipX_output_if(PCB_ISIPV6(pcb), q, ipX_2_ip(src_ip), ipX_2_ip(dst_ip), pcb->ttl, pcb->tos, pcb->protocol, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + /* did we chain a header earlier? */ + if (q != p) { + /* free the header */ + pbuf_free(q); + } + return err; +} + +/** + * Send the raw IP packet to the address given by raw_connect() + * + * @param pcb the raw pcb which to send + * @param p the IP payload to send + * + */ +err_t +raw_send(struct raw_pcb *pcb, struct pbuf *p) +{ + return raw_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip)); +} + +/** + * Remove an RAW PCB. + * + * @param pcb RAW PCB to be removed. The PCB is removed from the list of + * RAW PCB's and the data structure is freed from memory. + * + * @see raw_new() + */ +void +raw_remove(struct raw_pcb *pcb) +{ + struct raw_pcb *pcb2; + /* pcb to be removed is first in list? */ + if (raw_pcbs == pcb) { + /* make list start at 2nd pcb */ + raw_pcbs = raw_pcbs->next; + /* pcb not 1st in list */ + } else { + for(pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in raw_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_RAW_PCB, pcb); +} + +/** + * Create a RAW PCB. + * + * @return The RAW PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) + * + * @see raw_remove() + */ +struct raw_pcb * +raw_new(u8_t proto) +{ + struct raw_pcb *pcb; + + LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); + + pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); + /* could allocate RAW PCB? */ + if (pcb != NULL) { + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct raw_pcb)); + pcb->protocol = proto; + pcb->ttl = RAW_TTL; + pcb->next = raw_pcbs; + raw_pcbs = pcb; + } + return pcb; +} + +#if LWIP_IPV6 +/** + * Create a RAW PCB for IPv6. + * + * @return The RAW PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @param proto the protocol number (next header) of the IPv6 packet payload + * (e.g. IP6_NEXTH_ICMP6) + * + * @see raw_remove() + */ +struct raw_pcb * +raw_new_ip6(u8_t proto) +{ + struct raw_pcb *pcb; + pcb = raw_new(proto); + ip_set_v6(pcb, 1); + return pcb; +} +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_RAW */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_dec.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_dec.c new file mode 100644 index 0000000..39b70bc --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_dec.c @@ -0,0 +1,657 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) decoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Retrieves type field from incoming pbuf chain. + * + * @param p points to a pbuf holding an ASN1 coded type field + * @param ofs points to the offset within the pbuf chain of the ASN1 coded type field + * @param type return ASN1 type + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + *type = *msg_ptr; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes length field from incoming pbuf chain into host length. + * + * @param p points to a pbuf holding an ASN1 coded length + * @param ofs points to the offset within the pbuf chain of the ASN1 coded length + * @param octets_used returns number of octets used by the length code + * @param length return host order length, up to 64k + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (*msg_ptr < 0x80) + { + /* primitive definite length format */ + *octets_used = 1; + *length = *msg_ptr; + return ERR_OK; + } + else if (*msg_ptr == 0x80) + { + /* constructed indefinite length format, termination with two zero octets */ + u8_t zeros; + u8_t i; + + *length = 0; + zeros = 0; + while (zeros != 2) + { + i = 2; + while (i > 0) + { + i--; + (*length) += 1; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (*msg_ptr == 0) + { + zeros++; + if (zeros == 2) + { + /* stop while (i > 0) */ + i = 0; + } + } + else + { + zeros = 0; + } + } + } + *octets_used = 1; + return ERR_OK; + } + else if (*msg_ptr == 0x81) + { + /* constructed definite length format, one octet */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *length = *msg_ptr; + *octets_used = 2; + return ERR_OK; + } + else if (*msg_ptr == 0x82) + { + u8_t i; + + /* constructed definite length format, two octets */ + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *length |= *msg_ptr; + } + else + { + /* most significant length octet */ + *length = (*msg_ptr) << 8; + } + } + *octets_used = 3; + return ERR_OK; + } + else + { + /* constructed definite length format 3..127 octets, this is too big (>64k) */ + /** @todo: do we need to accept inefficient codings with many leading zero's? */ + *octets_used = 1 + ((*msg_ptr) & 0x7f); + return ERR_ARG; + } + } + p = p->next; + } + + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes positive integer (counter, gauge, timeticks) into u32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +err_t +snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 6)) + { + /* start from zero */ + *value = 0; + if (*msg_ptr & 0x80) + { + /* negative, expecting zero sign bit! */ + return ERR_ARG; + } + else + { + /* positive */ + if ((len > 1) && (*msg_ptr == 0)) + { + /* skip leading "sign byte" octet 0x00 */ + len--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + } + /* OR octets with value */ + while (len > 1) + { + len--; + *value |= *msg_ptr; + *value <<= 8; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + *value |= *msg_ptr; + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes integer into s32_t. + * + * @param p points to a pbuf holding an ASN1 coded integer + * @param ofs points to the offset within the pbuf chain of the ASN1 coded integer + * @param len length of the coded integer field + * @param value return host order integer + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + * + * @note ASN coded integers are _always_ signed! + */ +err_t +snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value) +{ + u16_t plen, base; + u8_t *msg_ptr; +#if BYTE_ORDER == LITTLE_ENDIAN + u8_t *lsb_ptr = (u8_t*)value; +#endif +#if BYTE_ORDER == BIG_ENDIAN + u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; +#endif + u8_t sign; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if ((len > 0) && (len < 5)) + { + if (*msg_ptr & 0x80) + { + /* negative, start from -1 */ + *value = -1; + sign = 1; + } + else + { + /* positive, start from 0 */ + *value = 0; + sign = 0; + } + /* OR/AND octets with value */ + while (len > 1) + { + len--; + if (sign) + { + *lsb_ptr &= *msg_ptr; + *value <<= 8; + *lsb_ptr |= 255; + } + else + { + *lsb_ptr |= *msg_ptr; + *value <<= 8; + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (sign) + { + *lsb_ptr &= *msg_ptr; + } + else + { + *lsb_ptr |= *msg_ptr; + } + return ERR_OK; + } + else + { + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes object identifier from incoming message into array of s32_t. + * + * @param p points to a pbuf holding an ASN1 coded object identifier + * @param ofs points to the offset within the pbuf chain of the ASN1 coded object identifier + * @param len length of the coded object identifier + * @param oid return object identifier struct + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid) +{ + u16_t plen, base; + u8_t *msg_ptr; + s32_t *oid_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + oid->len = 0; + oid_ptr = &oid->id[0]; + if (len > 0) + { + /* first compressed octet */ + if (*msg_ptr == 0x2B) + { + /* (most) common case 1.3 (iso.org) */ + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = 3; + oid_ptr++; + } + else if (*msg_ptr < 40) + { + *oid_ptr = 0; + oid_ptr++; + *oid_ptr = *msg_ptr; + oid_ptr++; + } + else if (*msg_ptr < 80) + { + *oid_ptr = 1; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 40; + oid_ptr++; + } + else + { + *oid_ptr = 2; + oid_ptr++; + *oid_ptr = (*msg_ptr) - 80; + oid_ptr++; + } + oid->len = 2; + } + else + { + /* accepting zero length identifiers e.g. for + getnext operation. uncommon but valid */ + return ERR_OK; + } + len--; + if (len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while ((len > 0) && (oid->len < LWIP_SNMP_OBJ_ID_LEN)) + { + /* sub-identifier uses multiple octets */ + if (*msg_ptr & 0x80) + { + s32_t sub_id = 0; + + while ((*msg_ptr & 0x80) && (len > 1)) + { + len--; + sub_id = (sub_id << 7) + (*msg_ptr & ~0x80); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (!(*msg_ptr & 0x80) && (len > 0)) + { + /* last octet sub-identifier */ + len--; + sub_id = (sub_id << 7) + *msg_ptr; + *oid_ptr = sub_id; + } + } + else + { + /* !(*msg_ptr & 0x80) sub-identifier uses single octet */ + len--; + *oid_ptr = *msg_ptr; + } + if (len > 0) + { + /* remaining oid bytes available ... */ + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + oid_ptr++; + oid->len++; + } + if (len == 0) + { + /* len == 0, end of oid */ + return ERR_OK; + } + else + { + /* len > 0, oid->len == LWIP_SNMP_OBJ_ID_LEN or malformed encoding */ + return ERR_ARG; + } + + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) + * from incoming message into array. + * + * @param p points to a pbuf holding an ASN1 coded raw data + * @param ofs points to the offset within the pbuf chain of the ASN1 coded raw data + * @param len length of the coded raw data (zero is valid, e.g. empty string!) + * @param raw_len length of the raw return value + * @param raw return raw bytes + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode + */ +err_t +snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + if (len > 0) + { + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + if (raw_len >= len) + { + while (len > 1) + { + /* copy len - 1 octets */ + len--; + *raw = *msg_ptr; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* copy last octet */ + *raw = *msg_ptr; + return ERR_OK; + } + else + { + /* raw_len < len, not enough dst space */ + return ERR_ARG; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; + } + else + { + /* len == 0, empty string */ + return ERR_OK; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_enc.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_enc.c new file mode 100644 index 0000000..d24a5c4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/asn1_enc.c @@ -0,0 +1,611 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) encoding + * + * @todo not optimised (yet), favor correctness over speed, favor speed over size + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_asn1.h" + +/** + * Returns octet count for length. + * + * @param length + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) +{ + if (length < 0x80U) + { + *octets_needed = 1; + } + else if (length < 0x100U) + { + *octets_needed = 2; + } + else + { + *octets_needed = 3; + } +} + +/** + * Returns octet count for an u32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded + * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value + * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! + */ +void +snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) +{ + if (value < 0x80UL) + { + *octets_needed = 1; + } + else if (value < 0x8000UL) + { + *octets_needed = 2; + } + else if (value < 0x800000UL) + { + *octets_needed = 3; + } + else if (value < 0x80000000UL) + { + *octets_needed = 4; + } + else + { + *octets_needed = 5; + } +} + +/** + * Returns octet count for an s32_t. + * + * @param value + * @param octets_needed points to the return value + * + * @note ASN coded integers are _always_ signed. + */ +void +snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) +{ + if (value < 0) + { + value = ~value; + } + if (value < 0x80L) + { + *octets_needed = 1; + } + else if (value < 0x8000L) + { + *octets_needed = 2; + } + else if (value < 0x800000L) + { + *octets_needed = 3; + } + else + { + *octets_needed = 4; + } +} + +/** + * Returns octet count for an object identifier. + * + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @param octets_needed points to the return value + */ +void +snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed) +{ + s32_t sub_id; + u8_t cnt; + + cnt = 0; + if (ident_len > 1) + { + /* compressed prefix in one octet */ + cnt++; + ident_len -= 2; + ident += 2; + } + while(ident_len > 0) + { + ident_len--; + sub_id = *ident; + + sub_id >>= 7; + cnt++; + while(sub_id > 0) + { + sub_id >>= 7; + cnt++; + } + ident++; + } + *octets_needed = cnt; +} + +/** + * Encodes ASN type field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param type input ASN1 type + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + *msg_ptr = type; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes host order length field into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode length into + * @param ofs points to the offset within the pbuf chain + * @param length is the host order length to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (length < 0x80) + { + *msg_ptr = (u8_t)length; + return ERR_OK; + } + else if (length < 0x100) + { + *msg_ptr = 0x81; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + *msg_ptr = (u8_t)length; + return ERR_OK; + } + else + { + u8_t i; + + /* length >= 0x100 && length <= 0xFFFF */ + *msg_ptr = 0x82; + i = 2; + while (i > 0) + { + i--; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + if (i == 0) + { + /* least significant length octet */ + *msg_ptr = (u8_t)length; + } + else + { + /* most significant length octet */ + *msg_ptr = (u8_t)(length >> 8); + } + } + return ERR_OK; + } + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) + * @param value is the host order u32_t value to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_u32t_cnt() + */ +err_t +snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (octets_needed == 5) + { + /* not enough bits in 'value' add leading 0x00 */ + octets_needed--; + *msg_ptr = 0x00; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = (u8_t)(value >> (octets_needed << 3)); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = (u8_t)value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes s32_t integer into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode value into + * @param ofs points to the offset within the pbuf chain + * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) + * @param value is the host order s32_t value to be encoded + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + * + * @see snmp_asn1_enc_s32t_cnt() + */ +err_t +snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + while (octets_needed > 1) + { + octets_needed--; + *msg_ptr = (u8_t)(value >> (octets_needed << 3)); + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* (only) one least significant octet */ + *msg_ptr = (u8_t)value; + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes object identifier into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode oid into + * @param ofs points to the offset within the pbuf chain + * @param ident_len object identifier array length + * @param ident points to object identifier array + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + if (ident_len > 1) + { + if ((ident[0] == 1) && (ident[1] == 3)) + { + /* compressed (most common) prefix .iso.org */ + *msg_ptr = 0x2b; + } + else + { + /* calculate prefix */ + *msg_ptr = (u8_t)((ident[0] * 40) + ident[1]); + } + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + ident_len -= 2; + ident += 2; + } + else + { +/* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ + /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ + return ERR_ARG; + } + while (ident_len > 0) + { + s32_t sub_id; + u8_t shift, tail; + + ident_len--; + sub_id = *ident; + tail = 0; + shift = 28; + while(shift > 0) + { + u8_t code; + + code = (u8_t)(sub_id >> shift); + if ((code != 0) || (tail != 0)) + { + tail = 1; + *msg_ptr = code | 0x80; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + shift -= 7; + } + *msg_ptr = (u8_t)sub_id & 0x7F; + if (ident_len > 0) + { + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + /* proceed to next sub-identifier */ + ident++; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +/** + * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. + * + * @param p points to output pbuf to encode raw data into + * @param ofs points to the offset within the pbuf chain + * @param raw_len raw data length + * @param raw points raw data + * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode + */ +err_t +snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw) +{ + u16_t plen, base; + u8_t *msg_ptr; + + plen = 0; + while (p != NULL) + { + base = plen; + plen += p->len; + if (ofs < plen) + { + msg_ptr = (u8_t*)p->payload; + msg_ptr += ofs - base; + + while (raw_len > 1) + { + /* copy raw_len - 1 octets */ + raw_len--; + *msg_ptr = *raw; + raw++; + ofs += 1; + if (ofs >= plen) + { + /* next octet in next pbuf */ + p = p->next; + if (p == NULL) { return ERR_ARG; } + msg_ptr = (u8_t*)p->payload; + plen += p->len; + } + else + { + /* next octet in same pbuf */ + msg_ptr++; + } + } + if (raw_len > 0) + { + /* copy last or single octet */ + *msg_ptr = *raw; + } + return ERR_OK; + } + p = p->next; + } + /* p == NULL, ofs >= plen */ + return ERR_ARG; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib2.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib2.c new file mode 100644 index 0000000..553b4de --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib2.c @@ -0,0 +1,4160 @@ +/** + * @file + * Management Information Base II (RFC1213) objects and functions. + * + * @note the object identifiers for this MIB-2 and private MIB tree + * must be kept in sorted ascending order. This to ensure correct getnext operation. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" +#include "lwip/netif.h" +#include "lwip/ip.h" +#include "lwip/ip_frag.h" +#include "lwip/mem.h" +#include "lwip/tcp_impl.h" +#include "lwip/udp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_structs.h" +#include "lwip/sys.h" +#include "netif/etharp.h" + +#include + +/** + * IANA assigned enterprise ID for lwIP is 26381 + * @see http://www.iana.org/assignments/enterprise-numbers + * + * @note this enterprise ID is assigned to the lwIP project, + * all object identifiers living under this ID are assigned + * by the lwIP maintainers (contact Christiaan Simons)! + * @note don't change this define, use snmp_set_sysobjid() + * + * If you need to create your own private MIB you'll need + * to apply for your own enterprise ID with IANA: + * http://www.iana.org/numbers.html + */ +#define SNMP_ENTERPRISE_ID 26381 +#define SNMP_SYSOBJID_LEN 7 +#define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID} + +#ifndef SNMP_SYSSERVICES +#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) +#endif + +#ifndef SNMP_GET_SYSUPTIME +#define SNMP_GET_SYSUPTIME(sysuptime) (sysuptime = (sys_now() / 10)) +#endif + +static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void system_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t system_set_test(struct obj_def *od, u16_t len, void *value); +static void system_set_value(struct obj_def *od, u16_t len, void *value); +static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void interfaces_get_value(struct obj_def *od, u16_t len, void *value); +static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ifentry_get_value(struct obj_def *od, u16_t len, void *value); +#if !SNMP_SAFE_REQUESTS +static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value); +static void ifentry_set_value (struct obj_def *od, u16_t len, void *value); +#endif /* SNMP_SAFE_REQUESTS */ +static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void atentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value); +static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value); +static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value); +static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void icmp_get_value(struct obj_def *od, u16_t len, void *value); +#if LWIP_TCP +static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcp_get_value(struct obj_def *od, u16_t len, void *value); +#ifdef THIS_SEEMS_UNUSED +static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value); +#endif +#endif +static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udp_get_value(struct obj_def *od, u16_t len, void *value); +static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void udpentry_get_value(struct obj_def *od, u16_t len, void *value); +static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +static void snmp_get_value(struct obj_def *od, u16_t len, void *value); +static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value); +static void snmp_set_value(struct obj_def *od, u16_t len, void *value); + + +/* snmp .1.3.6.1.2.1.11 */ +const mib_scalar_node snmp_scalar = { + &snmp_get_object_def, + &snmp_get_value, + &snmp_set_test, + &snmp_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t snmp_ids[28] = { + 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30 +}; +struct mib_node* const snmp_nodes[28] = { + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar, + (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar +}; +const struct mib_array_node snmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 28, + snmp_ids, + snmp_nodes +}; + +/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ +/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ +/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ + +/* udp .1.3.6.1.2.1.7 */ +/** index root node for udpTable */ +struct mib_list_rootnode udp_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t udpentry_ids[2] = { 1, 2 }; +struct mib_node* const udpentry_nodes[2] = { + (struct mib_node*)&udp_root, (struct mib_node*)&udp_root, +}; +const struct mib_array_node udpentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + udpentry_ids, + udpentry_nodes +}; + +s32_t udptable_id = 1; +struct mib_node* udptable_node = (struct mib_node*)&udpentry; +struct mib_ram_array_node udptable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &udptable_id, + &udptable_node +}; + +const mib_scalar_node udp_scalar = { + &udp_get_object_def, + &udp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const udp_nodes[5] = { + (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, + (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar, + (struct mib_node*)&udptable +}; +const struct mib_array_node udp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + udp_ids, + udp_nodes +}; + +/* tcp .1.3.6.1.2.1.6 */ +#if LWIP_TCP +/* only if the TCP protocol is available may implement this group */ +/** index root node for tcpConnTable */ +struct mib_list_rootnode tcpconntree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const tcpconnentry_nodes[5] = { + (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, + (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root, + (struct mib_node*)&tcpconntree_root +}; +const struct mib_array_node tcpconnentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + tcpconnentry_ids, + tcpconnentry_nodes +}; + +s32_t tcpconntable_id = 1; +struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry; +struct mib_ram_array_node tcpconntable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, +/** @todo update maxlength when inserting / deleting from table + 0 when table is empty, 1 when more than one entry */ + 0, + &tcpconntable_id, + &tcpconntable_node +}; + +const mib_scalar_node tcp_scalar = { + &tcp_get_object_def, + &tcp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +struct mib_node* const tcp_nodes[15] = { + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar, + (struct mib_node*)&tcp_scalar +}; +const struct mib_array_node tcp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 15, + tcp_ids, + tcp_nodes +}; +#endif + +/* icmp .1.3.6.1.2.1.5 */ +const mib_scalar_node icmp_scalar = { + &icmp_get_object_def, + &icmp_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; +struct mib_node* const icmp_nodes[26] = { + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar, + (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar +}; +const struct mib_array_node icmp = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 26, + icmp_ids, + icmp_nodes +}; + +/** index root node for ipNetToMediaTable */ +struct mib_list_rootnode ipntomtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 }; +struct mib_node* const ipntomentry_nodes[4] = { + (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root, + (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root +}; +const struct mib_array_node ipntomentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 4, + ipntomentry_ids, + ipntomentry_nodes +}; + +s32_t ipntomtable_id = 1; +struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry; +struct mib_ram_array_node ipntomtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipntomtable_id, + &ipntomtable_node +}; + +/** index root node for ipRouteTable */ +struct mib_list_rootnode iprtetree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; +struct mib_node* const iprteentry_nodes[13] = { + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root, + (struct mib_node*)&iprtetree_root +}; +const struct mib_array_node iprteentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 13, + iprteentry_ids, + iprteentry_nodes +}; + +s32_t iprtetable_id = 1; +struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry; +struct mib_ram_array_node iprtetable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iprtetable_id, + &iprtetable_node +}; + +/** index root node for ipAddrTable */ +struct mib_list_rootnode ipaddrtree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 }; +struct mib_node* const ipaddrentry_nodes[5] = { + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root, + (struct mib_node*)&ipaddrtree_root +}; +const struct mib_array_node ipaddrentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 5, + ipaddrentry_ids, + ipaddrentry_nodes +}; + +s32_t ipaddrtable_id = 1; +struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry; +struct mib_ram_array_node ipaddrtable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &ipaddrtable_id, + &ipaddrtable_node +}; + +/* ip .1.3.6.1.2.1.4 */ +const mib_scalar_node ip_scalar = { + &ip_get_object_def, + &ip_get_value, + &ip_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; +struct mib_node* const ip_nodes[23] = { + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar, + (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable, + (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable, + (struct mib_node*)&ip_scalar +}; +const struct mib_array_node mib2_ip = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 23, + ip_ids, + ip_nodes +}; + +/** index root node for atTable */ +struct mib_list_rootnode arptree_root = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t atentry_ids[3] = { 1, 2, 3 }; +struct mib_node* const atentry_nodes[3] = { + (struct mib_node*)&arptree_root, + (struct mib_node*)&arptree_root, + (struct mib_node*)&arptree_root +}; +const struct mib_array_node atentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 3, + atentry_ids, + atentry_nodes +}; + +const s32_t attable_id = 1; +struct mib_node* const attable_node = (struct mib_node*)&atentry; +const struct mib_array_node attable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + &attable_id, + &attable_node +}; + +/* at .1.3.6.1.2.1.3 */ +s32_t at_id = 1; +struct mib_node* mib2_at_node = (struct mib_node*)&attable; +struct mib_ram_array_node at = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &at_id, + &mib2_at_node +}; + +/** index root node for ifTable */ +struct mib_list_rootnode iflist_root = { + &ifentry_get_object_def, + &ifentry_get_value, +#if SNMP_SAFE_REQUESTS + &noleafs_set_test, + &noleafs_set_value, +#else /* SNMP_SAFE_REQUESTS */ + &ifentry_set_test, + &ifentry_set_value, +#endif /* SNMP_SAFE_REQUESTS */ + MIB_NODE_LR, + 0, + NULL, + NULL, + 0 +}; +const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 }; +struct mib_node* const ifentry_nodes[22] = { + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root, + (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root +}; +const struct mib_array_node ifentry = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 22, + ifentry_ids, + ifentry_nodes +}; + +s32_t iftable_id = 1; +struct mib_node* iftable_node = (struct mib_node*)&ifentry; +struct mib_ram_array_node iftable = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_RA, + 0, + &iftable_id, + &iftable_node +}; + +/* interfaces .1.3.6.1.2.1.2 */ +const mib_scalar_node interfaces_scalar = { + &interfaces_get_object_def, + &interfaces_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t interfaces_ids[2] = { 1, 2 }; +struct mib_node* const interfaces_nodes[2] = { + (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable +}; +const struct mib_array_node interfaces = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + interfaces_ids, + interfaces_nodes +}; + + +/* 0 1 2 3 4 5 6 */ +/* system .1.3.6.1.2.1.1 */ +const mib_scalar_node sys_tem_scalar = { + &system_get_object_def, + &system_get_value, + &system_set_test, + &system_set_value, + MIB_NODE_SC, + 0 +}; +const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 }; +struct mib_node* const sys_tem_nodes[7] = { + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar, + (struct mib_node*)&sys_tem_scalar +}; +/* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */ +const struct mib_array_node sys_tem = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 7, + sys_tem_ids, + sys_tem_nodes +}; + +/* mib-2 .1.3.6.1.2.1 */ +#if LWIP_TCP +#define MIB2_GROUPS 8 +#else +#define MIB2_GROUPS 7 +#endif +const s32_t mib2_ids[MIB2_GROUPS] = +{ + 1, + 2, + 3, + 4, + 5, +#if LWIP_TCP + 6, +#endif + 7, + 11 +}; +struct mib_node* const mib2_nodes[MIB2_GROUPS] = { + (struct mib_node*)&sys_tem, + (struct mib_node*)&interfaces, + (struct mib_node*)&at, + (struct mib_node*)&mib2_ip, + (struct mib_node*)&icmp, +#if LWIP_TCP + (struct mib_node*)&tcp, +#endif + (struct mib_node*)&udp, + (struct mib_node*)&snmp +}; + +const struct mib_array_node mib2 = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + MIB2_GROUPS, + mib2_ids, + mib2_nodes +}; + +/* mgmt .1.3.6.1.2 */ +const s32_t mgmt_ids[1] = { 1 }; +struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 }; +const struct mib_array_node mgmt = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + mgmt_ids, + mgmt_nodes +}; + +/* internet .1.3.6.1 */ +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +s32_t internet_ids[2] = { 2, 4 }; +struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 2, + internet_ids, + internet_nodes +}; +#else +const s32_t internet_ids[1] = { 2 }; +struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt }; +const struct mib_array_node internet = { + &noleafs_get_object_def, + &noleafs_get_value, + &noleafs_set_test, + &noleafs_set_value, + MIB_NODE_AR, + 1, + internet_ids, + internet_nodes +}; +#endif + +/** mib-2.system.sysObjectID */ +static const struct snmp_obj_id sysobjid_default = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID}; +static const struct snmp_obj_id* sysobjid_ptr = &sysobjid_default; +/** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */ +static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}}; +/** mib-2.system.sysServices */ +static const s32_t sysservices = SNMP_SYSSERVICES; + +/** mib-2.system.sysDescr */ +static const u8_t sysdescr_len_default = 4; +static const u8_t sysdescr_default[] = "lwIP"; +static const u8_t* sysdescr_len_ptr = &sysdescr_len_default; +static const u8_t* sysdescr_ptr = &sysdescr_default[0]; +/** mib-2.system.sysContact */ +static const u8_t syscontact_len_default = 0; +static const u8_t syscontact_default[] = ""; +static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default; +static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0]; +/** mib-2.system.sysName */ +static const u8_t sysname_len_default = 8; +static const u8_t sysname_default[] = "FQDN-unk"; +static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default; +static u8_t* sysname_ptr = (u8_t*)&sysname_default[0]; +/** mib-2.system.sysLocation */ +static const u8_t syslocation_len_default = 0; +static const u8_t syslocation_default[] = ""; +static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default; +static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0]; +/** mib-2.snmp.snmpEnableAuthenTraps */ +static const u8_t snmpenableauthentraps_default = 2; /* disabled */ +static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default; + +/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */ +static const struct snmp_obj_id ifspecific = {2, {0, 0}}; +/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */ +static const struct snmp_obj_id iprouteinfo = {2, {0, 0}}; + + + +/* mib-2.system counter(s) */ +static u32_t sysuptime = 0; + +/* mib-2.ip counter(s) */ +static u32_t ipinreceives = 0, + ipinhdrerrors = 0, + ipinaddrerrors = 0, + ipforwdatagrams = 0, + ipinunknownprotos = 0, + ipindiscards = 0, + ipindelivers = 0, + ipoutrequests = 0, + ipoutdiscards = 0, + ipoutnoroutes = 0, + ipreasmreqds = 0, + ipreasmoks = 0, + ipreasmfails = 0, + ipfragoks = 0, + ipfragfails = 0, + ipfragcreates = 0, + iproutingdiscards = 0; +/* mib-2.icmp counter(s) */ +static u32_t icmpinmsgs = 0, + icmpinerrors = 0, + icmpindestunreachs = 0, + icmpintimeexcds = 0, + icmpinparmprobs = 0, + icmpinsrcquenchs = 0, + icmpinredirects = 0, + icmpinechos = 0, + icmpinechoreps = 0, + icmpintimestamps = 0, + icmpintimestampreps = 0, + icmpinaddrmasks = 0, + icmpinaddrmaskreps = 0, + icmpoutmsgs = 0, + icmpouterrors = 0, + icmpoutdestunreachs = 0, + icmpouttimeexcds = 0, + icmpoutparmprobs = 0, + icmpoutsrcquenchs = 0, + icmpoutredirects = 0, + icmpoutechos = 0, + icmpoutechoreps = 0, + icmpouttimestamps = 0, + icmpouttimestampreps = 0, + icmpoutaddrmasks = 0, + icmpoutaddrmaskreps = 0; +/* mib-2.tcp counter(s) */ +static u32_t tcpactiveopens = 0, + tcppassiveopens = 0, + tcpattemptfails = 0, + tcpestabresets = 0, + tcpinsegs = 0, + tcpoutsegs = 0, + tcpretranssegs = 0, + tcpinerrs = 0, + tcpoutrsts = 0; +/* mib-2.udp counter(s) */ +static u32_t udpindatagrams = 0, + udpnoports = 0, + udpinerrors = 0, + udpoutdatagrams = 0; +/* mib-2.snmp counter(s) */ +static u32_t snmpinpkts = 0, + snmpoutpkts = 0, + snmpinbadversions = 0, + snmpinbadcommunitynames = 0, + snmpinbadcommunityuses = 0, + snmpinasnparseerrs = 0, + snmpintoobigs = 0, + snmpinnosuchnames = 0, + snmpinbadvalues = 0, + snmpinreadonlys = 0, + snmpingenerrs = 0, + snmpintotalreqvars = 0, + snmpintotalsetvars = 0, + snmpingetrequests = 0, + snmpingetnexts = 0, + snmpinsetrequests = 0, + snmpingetresponses = 0, + snmpintraps = 0, + snmpouttoobigs = 0, + snmpoutnosuchnames = 0, + snmpoutbadvalues = 0, + snmpoutgenerrs = 0, + snmpoutgetrequests = 0, + snmpoutgetnexts = 0, + snmpoutsetrequests = 0, + snmpoutgetresponses = 0, + snmpouttraps = 0; + + +/** + * Initializes sysDescr pointers. + * + * @param str if non-NULL then copy str pointer + * @param len points to string length, excluding zero terminator + */ +void snmp_set_sysdescr(const u8_t *str, const u8_t *len) +{ + if (str != NULL) + { + sysdescr_ptr = str; + sysdescr_len_ptr = len; + } +} + +void snmp_get_sysobjid_ptr(const struct snmp_obj_id **oid) +{ + *oid = sysobjid_ptr; +} + +/** + * Initializes sysObjectID value. + * + * @param oid points to stuct snmp_obj_id to copy + */ +void snmp_set_sysobjid(const struct snmp_obj_id *oid) +{ + sysobjid_ptr = oid; +} + +/** + * Must be called at regular 10 msec interval from a timer interrupt + * or signal handler depending on your runtime environment. + */ +void snmp_inc_sysuptime(void) +{ + sysuptime++; +} + +void snmp_add_sysuptime(u32_t value) +{ + sysuptime+=value; +} + +void snmp_get_sysuptime(u32_t *value) +{ + SNMP_GET_SYSUPTIME(sysuptime); + *value = sysuptime; +} + +/** + * Initializes sysContact pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syscontact_ptr = ocstr; + syscontact_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysName pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + sysname_ptr = ocstr; + sysname_len_ptr = ocstrlen; + } +} + +/** + * Initializes sysLocation pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator + */ +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen) +{ + if (ocstr != NULL) + { + syslocation_ptr = ocstr; + syslocation_len_ptr = ocstrlen; + } +} + + +void snmp_add_ifinoctets(struct netif *ni, u32_t value) +{ + ni->ifinoctets += value; +} + +void snmp_inc_ifinucastpkts(struct netif *ni) +{ + (ni->ifinucastpkts)++; +} + +void snmp_inc_ifinnucastpkts(struct netif *ni) +{ + (ni->ifinnucastpkts)++; +} + +void snmp_inc_ifindiscards(struct netif *ni) +{ + (ni->ifindiscards)++; +} + +void snmp_add_ifoutoctets(struct netif *ni, u32_t value) +{ + ni->ifoutoctets += value; +} + +void snmp_inc_ifoutucastpkts(struct netif *ni) +{ + (ni->ifoutucastpkts)++; +} + +void snmp_inc_ifoutnucastpkts(struct netif *ni) +{ + (ni->ifoutnucastpkts)++; +} + +void snmp_inc_ifoutdiscards(struct netif *ni) +{ + (ni->ifoutdiscards)++; +} + +void snmp_inc_iflist(void) +{ + struct mib_list_node *if_node = NULL; + + snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node); + /* enable getnext traversal on filled table */ + iftable.maxlength = 1; +} + +void snmp_dec_iflist(void) +{ + snmp_mib_node_delete(&iflist_root, iflist_root.tail); + /* disable getnext traversal on empty table */ + if(iflist_root.count == 0) iftable.maxlength = 0; +} + +/** + * Inserts ARP table indexes (.xIfIndex.xNetAddress) + * into arp table index trees (both atTable and ipNetToMediaTable). + */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip) +{ + struct mib_list_rootnode *at_rn; + struct mib_list_node *at_node; + s32_t arpidx[5]; + u8_t level, tree; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_netiftoifindex(ni, &arpidx[0]); + snmp_iptooid(ip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + for (level = 0; level < 5; level++) + { + at_node = NULL; + snmp_mib_node_insert(at_rn, arpidx[level], &at_node); + if ((level != 4) && (at_node != NULL)) + { + if (at_node->nptr == NULL) + { + at_rn = snmp_mib_lrn_alloc(); + at_node->nptr = (struct mib_node*)at_rn; + if (at_rn != NULL) + { + if (level == 3) + { + if (tree == 0) + { + at_rn->get_object_def = atentry_get_object_def; + at_rn->get_value = atentry_get_value; + } + else + { + at_rn->get_object_def = ip_ntomentry_get_object_def; + at_rn->get_value = ip_ntomentry_get_value; + } + at_rn->set_test = noleafs_set_test; + at_rn->set_value = noleafs_set_value; + } + } + else + { + /* at_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full")); + break; + } + } + else + { + at_rn = (struct mib_list_rootnode*)at_node->nptr; + } + } + } + } + /* enable getnext traversal on filled tables */ + at.maxlength = 1; + ipntomtable.maxlength = 1; +} + +/** + * Removes ARP table indexes (.xIfIndex.xNetAddress) + * from arp table index trees. + */ +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip) +{ + struct mib_list_rootnode *at_rn, *next, *del_rn[5]; + struct mib_list_node *at_n, *del_n[5]; + s32_t arpidx[5]; + u8_t fc, tree, level, del_cnt; + + snmp_netiftoifindex(ni, &arpidx[0]); + snmp_iptooid(ip, &arpidx[1]); + + for (tree = 0; tree < 2; tree++) + { + /* mark nodes for deletion */ + if (tree == 0) + { + at_rn = &arptree_root; + } + else + { + at_rn = &ipntomtree_root; + } + level = 0; + del_cnt = 0; + while ((level < 5) && (at_rn != NULL)) + { + fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n); + if (fc == 0) + { + /* arpidx[level] does not exist */ + del_cnt = 0; + at_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = at_rn; + del_n[del_cnt] = at_n; + del_cnt++; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + at_rn = (struct mib_list_rootnode*)(at_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + at_rn = del_rn[del_cnt]; + at_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(at_rn, at_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty tables */ + if(arptree_root.count == 0) at.maxlength = 0; + if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0; +} + +void snmp_inc_ipinreceives(void) +{ + ipinreceives++; +} + +void snmp_inc_ipinhdrerrors(void) +{ + ipinhdrerrors++; +} + +void snmp_inc_ipinaddrerrors(void) +{ + ipinaddrerrors++; +} + +void snmp_inc_ipforwdatagrams(void) +{ + ipforwdatagrams++; +} + +void snmp_inc_ipinunknownprotos(void) +{ + ipinunknownprotos++; +} + +void snmp_inc_ipindiscards(void) +{ + ipindiscards++; +} + +void snmp_inc_ipindelivers(void) +{ + ipindelivers++; +} + +void snmp_inc_ipoutrequests(void) +{ + ipoutrequests++; +} + +void snmp_inc_ipoutdiscards(void) +{ + ipoutdiscards++; +} + +void snmp_inc_ipoutnoroutes(void) +{ + ipoutnoroutes++; +} + +void snmp_inc_ipreasmreqds(void) +{ + ipreasmreqds++; +} + +void snmp_inc_ipreasmoks(void) +{ + ipreasmoks++; +} + +void snmp_inc_ipreasmfails(void) +{ + ipreasmfails++; +} + +void snmp_inc_ipfragoks(void) +{ + ipfragoks++; +} + +void snmp_inc_ipfragfails(void) +{ + ipfragfails++; +} + +void snmp_inc_ipfragcreates(void) +{ + ipfragcreates++; +} + +void snmp_inc_iproutingdiscards(void) +{ + iproutingdiscards++; +} + +/** + * Inserts ipAddrTable indexes (.ipAdEntAddr) + * into index tree. + */ +void snmp_insert_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn; + struct mib_list_node *ipa_node; + s32_t ipaddridx[4]; + u8_t level; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); + + level = 0; + ipa_rn = &ipaddrtree_root; + while (level < 4) + { + ipa_node = NULL; + snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node); + if ((level != 3) && (ipa_node != NULL)) + { + if (ipa_node->nptr == NULL) + { + ipa_rn = snmp_mib_lrn_alloc(); + ipa_node->nptr = (struct mib_node*)ipa_rn; + if (ipa_rn != NULL) + { + if (level == 2) + { + ipa_rn->get_object_def = ip_addrentry_get_object_def; + ipa_rn->get_value = ip_addrentry_get_value; + ipa_rn->set_test = noleafs_set_test; + ipa_rn->set_value = noleafs_set_value; + } + } + else + { + /* ipa_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full")); + break; + } + } + else + { + ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr; + } + } + level++; + } + /* enable getnext traversal on filled table */ + ipaddrtable.maxlength = 1; +} + +/** + * Removes ipAddrTable indexes (.ipAdEntAddr) + * from index tree. + */ +void snmp_delete_ipaddridx_tree(struct netif *ni) +{ + struct mib_list_rootnode *ipa_rn, *next, *del_rn[4]; + struct mib_list_node *ipa_n, *del_n[4]; + s32_t ipaddridx[4]; + u8_t fc, level, del_cnt; + + LWIP_ASSERT("ni != NULL", ni != NULL); + snmp_iptooid(&ni->ip_addr, &ipaddridx[0]); + + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + ipa_rn = &ipaddrtree_root; + while ((level < 4) && (ipa_rn != NULL)) + { + fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n); + if (fc == 0) + { + /* ipaddridx[level] does not exist */ + del_cnt = 0; + ipa_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = ipa_rn; + del_n[del_cnt] = ipa_n; + del_cnt++; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + ipa_rn = del_rn[del_cnt]; + ipa_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(ipa_rn, ipa_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + /* disable getnext traversal on empty table */ + if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0; +} + +/** + * Inserts ipRouteTable indexes (.ipRouteDest) + * into index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte + * + * @todo record sysuptime for _this_ route when it is installed + * (needed for ipRouteAge) in the netif. + */ +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t insert = 0; + ip_addr_t dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + ip_addr_set_any(&dst); + insert = 1; + } + else + { + /* route to the network address */ + ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (!ip_addr_isany(&dst)) { + insert = 1; + } + } + if (insert) + { + struct mib_list_rootnode *iprte_rn; + struct mib_list_node *iprte_node; + s32_t iprteidx[4]; + u8_t level; + + snmp_iptooid(&dst, &iprteidx[0]); + level = 0; + iprte_rn = &iprtetree_root; + while (level < 4) + { + iprte_node = NULL; + snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node); + if ((level != 3) && (iprte_node != NULL)) + { + if (iprte_node->nptr == NULL) + { + iprte_rn = snmp_mib_lrn_alloc(); + iprte_node->nptr = (struct mib_node*)iprte_rn; + if (iprte_rn != NULL) + { + if (level == 2) + { + iprte_rn->get_object_def = ip_rteentry_get_object_def; + iprte_rn->get_value = ip_rteentry_get_value; + iprte_rn->set_test = noleafs_set_test; + iprte_rn->set_value = noleafs_set_value; + } + } + else + { + /* iprte_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full")); + break; + } + } + else + { + iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr; + } + } + level++; + } + } + /* enable getnext traversal on filled table */ + iprtetable.maxlength = 1; +} + +/** + * Removes ipRouteTable indexes (.ipRouteDest) + * from index tree. + * + * @param dflt non-zero for the default rte, zero for network rte + * @param ni points to network interface for this rte or NULL + * for default route to be removed. + */ +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni) +{ + u8_t del = 0; + ip_addr_t dst; + + if (dflt != 0) + { + /* the default route 0.0.0.0 */ + ip_addr_set_any(&dst); + del = 1; + } + else + { + /* route to the network address */ + ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask); + /* exclude 0.0.0.0 network (reserved for default rte) */ + if (!ip_addr_isany(&dst)) { + del = 1; + } + } + if (del) + { + struct mib_list_rootnode *iprte_rn, *next, *del_rn[4]; + struct mib_list_node *iprte_n, *del_n[4]; + s32_t iprteidx[4]; + u8_t fc, level, del_cnt; + + snmp_iptooid(&dst, &iprteidx[0]); + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + iprte_rn = &iprtetree_root; + while ((level < 4) && (iprte_rn != NULL)) + { + fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n); + if (fc == 0) + { + /* iprteidx[level] does not exist */ + del_cnt = 0; + iprte_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = iprte_rn; + del_n[del_cnt] = iprte_n; + del_cnt++; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + iprte_rn = del_rn[del_cnt]; + iprte_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(iprte_rn, iprte_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (iprtetree_root.count == 0) iprtetable.maxlength = 0; +} + + +void snmp_inc_icmpinmsgs(void) +{ + icmpinmsgs++; +} + +void snmp_inc_icmpinerrors(void) +{ + icmpinerrors++; +} + +void snmp_inc_icmpindestunreachs(void) +{ + icmpindestunreachs++; +} + +void snmp_inc_icmpintimeexcds(void) +{ + icmpintimeexcds++; +} + +void snmp_inc_icmpinparmprobs(void) +{ + icmpinparmprobs++; +} + +void snmp_inc_icmpinsrcquenchs(void) +{ + icmpinsrcquenchs++; +} + +void snmp_inc_icmpinredirects(void) +{ + icmpinredirects++; +} + +void snmp_inc_icmpinechos(void) +{ + icmpinechos++; +} + +void snmp_inc_icmpinechoreps(void) +{ + icmpinechoreps++; +} + +void snmp_inc_icmpintimestamps(void) +{ + icmpintimestamps++; +} + +void snmp_inc_icmpintimestampreps(void) +{ + icmpintimestampreps++; +} + +void snmp_inc_icmpinaddrmasks(void) +{ + icmpinaddrmasks++; +} + +void snmp_inc_icmpinaddrmaskreps(void) +{ + icmpinaddrmaskreps++; +} + +void snmp_inc_icmpoutmsgs(void) +{ + icmpoutmsgs++; +} + +void snmp_inc_icmpouterrors(void) +{ + icmpouterrors++; +} + +void snmp_inc_icmpoutdestunreachs(void) +{ + icmpoutdestunreachs++; +} + +void snmp_inc_icmpouttimeexcds(void) +{ + icmpouttimeexcds++; +} + +void snmp_inc_icmpoutparmprobs(void) +{ + icmpoutparmprobs++; +} + +void snmp_inc_icmpoutsrcquenchs(void) +{ + icmpoutsrcquenchs++; +} + +void snmp_inc_icmpoutredirects(void) +{ + icmpoutredirects++; +} + +void snmp_inc_icmpoutechos(void) +{ + icmpoutechos++; +} + +void snmp_inc_icmpoutechoreps(void) +{ + icmpoutechoreps++; +} + +void snmp_inc_icmpouttimestamps(void) +{ + icmpouttimestamps++; +} + +void snmp_inc_icmpouttimestampreps(void) +{ + icmpouttimestampreps++; +} + +void snmp_inc_icmpoutaddrmasks(void) +{ + icmpoutaddrmasks++; +} + +void snmp_inc_icmpoutaddrmaskreps(void) +{ + icmpoutaddrmaskreps++; +} + +void snmp_inc_tcpactiveopens(void) +{ + tcpactiveopens++; +} + +void snmp_inc_tcppassiveopens(void) +{ + tcppassiveopens++; +} + +void snmp_inc_tcpattemptfails(void) +{ + tcpattemptfails++; +} + +void snmp_inc_tcpestabresets(void) +{ + tcpestabresets++; +} + +void snmp_inc_tcpinsegs(void) +{ + tcpinsegs++; +} + +void snmp_inc_tcpoutsegs(void) +{ + tcpoutsegs++; +} + +void snmp_inc_tcpretranssegs(void) +{ + tcpretranssegs++; +} + +void snmp_inc_tcpinerrs(void) +{ + tcpinerrs++; +} + +void snmp_inc_tcpoutrsts(void) +{ + tcpoutrsts++; +} + +void snmp_inc_udpindatagrams(void) +{ + udpindatagrams++; +} + +void snmp_inc_udpnoports(void) +{ + udpnoports++; +} + +void snmp_inc_udpinerrors(void) +{ + udpinerrors++; +} + +void snmp_inc_udpoutdatagrams(void) +{ + udpoutdatagrams++; +} + +/** + * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort) + * into index tree. + */ +void snmp_insert_udpidx_tree(struct udp_pcb *pcb) +{ + struct mib_list_rootnode *udp_rn; + struct mib_list_node *udp_node; + s32_t udpidx[5]; + u8_t level; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); + udpidx[4] = pcb->local_port; + + udp_rn = &udp_root; + for (level = 0; level < 5; level++) + { + udp_node = NULL; + snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node); + if ((level != 4) && (udp_node != NULL)) + { + if (udp_node->nptr == NULL) + { + udp_rn = snmp_mib_lrn_alloc(); + udp_node->nptr = (struct mib_node*)udp_rn; + if (udp_rn != NULL) + { + if (level == 3) + { + udp_rn->get_object_def = udpentry_get_object_def; + udp_rn->get_value = udpentry_get_value; + udp_rn->set_test = noleafs_set_test; + udp_rn->set_value = noleafs_set_value; + } + } + else + { + /* udp_rn == NULL, malloc failure */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full")); + break; + } + } + else + { + udp_rn = (struct mib_list_rootnode*)udp_node->nptr; + } + } + } + udptable.maxlength = 1; +} + +/** + * Removes udpTable indexes (.udpLocalAddress.udpLocalPort) + * from index tree. + */ +void snmp_delete_udpidx_tree(struct udp_pcb *pcb) +{ + struct udp_pcb *npcb; + struct mib_list_rootnode *udp_rn, *next, *del_rn[5]; + struct mib_list_node *udp_n, *del_n[5]; + s32_t udpidx[5]; + u8_t bindings, fc, level, del_cnt; + + LWIP_ASSERT("pcb != NULL", pcb != NULL); + snmp_iptooid(ipX_2_ip(&pcb->local_ip), &udpidx[0]); + udpidx[4] = pcb->local_port; + + /* count PCBs for a given binding + (e.g. when reusing ports or for temp output PCBs) */ + bindings = 0; + npcb = udp_pcbs; + while ((npcb != NULL)) + { + if (ipX_addr_cmp(0, &npcb->local_ip, &pcb->local_ip) && + (npcb->local_port == udpidx[4])) + { + bindings++; + } + npcb = npcb->next; + } + if (bindings == 1) + { + /* selectively remove */ + /* mark nodes for deletion */ + level = 0; + del_cnt = 0; + udp_rn = &udp_root; + while ((level < 5) && (udp_rn != NULL)) + { + fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n); + if (fc == 0) + { + /* udpidx[level] does not exist */ + del_cnt = 0; + udp_rn = NULL; + } + else if (fc == 1) + { + del_rn[del_cnt] = udp_rn; + del_n[del_cnt] = udp_n; + del_cnt++; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + else if (fc == 2) + { + /* reset delete (2 or more childs) */ + del_cnt = 0; + udp_rn = (struct mib_list_rootnode*)(udp_n->nptr); + } + level++; + } + /* delete marked index nodes */ + while (del_cnt > 0) + { + del_cnt--; + + udp_rn = del_rn[del_cnt]; + udp_n = del_n[del_cnt]; + + next = snmp_mib_node_delete(udp_rn, udp_n); + if (next != NULL) + { + LWIP_ASSERT("next_count == 0",next->count == 0); + snmp_mib_lrn_free(next); + } + } + } + /* disable getnext traversal on empty table */ + if (udp_root.count == 0) udptable.maxlength = 0; +} + + +void snmp_inc_snmpinpkts(void) +{ + snmpinpkts++; +} + +void snmp_inc_snmpoutpkts(void) +{ + snmpoutpkts++; +} + +void snmp_inc_snmpinbadversions(void) +{ + snmpinbadversions++; +} + +void snmp_inc_snmpinbadcommunitynames(void) +{ + snmpinbadcommunitynames++; +} + +void snmp_inc_snmpinbadcommunityuses(void) +{ + snmpinbadcommunityuses++; +} + +void snmp_inc_snmpinasnparseerrs(void) +{ + snmpinasnparseerrs++; +} + +void snmp_inc_snmpintoobigs(void) +{ + snmpintoobigs++; +} + +void snmp_inc_snmpinnosuchnames(void) +{ + snmpinnosuchnames++; +} + +void snmp_inc_snmpinbadvalues(void) +{ + snmpinbadvalues++; +} + +void snmp_inc_snmpinreadonlys(void) +{ + snmpinreadonlys++; +} + +void snmp_inc_snmpingenerrs(void) +{ + snmpingenerrs++; +} + +void snmp_add_snmpintotalreqvars(u8_t value) +{ + snmpintotalreqvars += value; +} + +void snmp_add_snmpintotalsetvars(u8_t value) +{ + snmpintotalsetvars += value; +} + +void snmp_inc_snmpingetrequests(void) +{ + snmpingetrequests++; +} + +void snmp_inc_snmpingetnexts(void) +{ + snmpingetnexts++; +} + +void snmp_inc_snmpinsetrequests(void) +{ + snmpinsetrequests++; +} + +void snmp_inc_snmpingetresponses(void) +{ + snmpingetresponses++; +} + +void snmp_inc_snmpintraps(void) +{ + snmpintraps++; +} + +void snmp_inc_snmpouttoobigs(void) +{ + snmpouttoobigs++; +} + +void snmp_inc_snmpoutnosuchnames(void) +{ + snmpoutnosuchnames++; +} + +void snmp_inc_snmpoutbadvalues(void) +{ + snmpoutbadvalues++; +} + +void snmp_inc_snmpoutgenerrs(void) +{ + snmpoutgenerrs++; +} + +void snmp_inc_snmpoutgetrequests(void) +{ + snmpoutgetrequests++; +} + +void snmp_inc_snmpoutgetnexts(void) +{ + snmpoutgetnexts++; +} + +void snmp_inc_snmpoutsetrequests(void) +{ + snmpoutsetrequests++; +} + +void snmp_inc_snmpoutgetresponses(void) +{ + snmpoutgetresponses++; +} + +void snmp_inc_snmpouttraps(void) +{ + snmpouttraps++; +} + +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid) +{ + *oid = &snmpgrp_id; +} + +void snmp_set_snmpenableauthentraps(u8_t *value) +{ + if (value != NULL) + { + snmpenableauthentraps_ptr = value; + } +} + +void snmp_get_snmpenableauthentraps(u8_t *value) +{ + *value = *snmpenableauthentraps_ptr; +} + +void +noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + LWIP_UNUSED_ARG(ident_len); + LWIP_UNUSED_ARG(ident); + od->instance = MIB_OBJECT_NONE; +} + +void +noleafs_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + +u8_t +noleafs_set_test(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); + /* can't set */ + return 0; +} + +void +noleafs_set_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(od); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value); +} + + +/** + * Returns systems object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param od points to object definition. + */ +static void +system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* sysDescr */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysdescr_len_ptr; + break; + case 2: /* sysObjectID */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = sysobjid_ptr->len * sizeof(s32_t); + break; + case 3: /* sysUpTime */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 4: /* sysContact */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syscontact_len_ptr; + break; + case 5: /* sysName */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *sysname_len_ptr; + break; + case 6: /* sysLocation */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = *syslocation_len_ptr; + break; + case 7: /* sysServices */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns system object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +system_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* sysDescr */ + MEMCPY(value, sysdescr_ptr, len); + break; + case 2: /* sysObjectID */ + MEMCPY(value, sysobjid_ptr->id, len); + break; + case 3: /* sysUpTime */ + { + snmp_get_sysuptime((u32_t*)value); + } + break; + case 4: /* sysContact */ + MEMCPY(value, syscontact_ptr, len); + break; + case 5: /* sysName */ + MEMCPY(value, sysname_ptr, len); + break; + case 6: /* sysLocation */ + MEMCPY(value, syslocation_ptr, len); + break; + case 7: /* sysServices */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = sysservices; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %d\n", id)); + break; + }; +} + +static u8_t +system_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(value); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + if ((syscontact_ptr != syscontact_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 5: /* sysName */ + if ((sysname_ptr != sysname_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + case 6: /* sysLocation */ + if ((syslocation_ptr != syslocation_default) && + (len <= 255)) + { + set_ok = 1; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %d\n", id)); + break; + }; + return set_ok; +} + +static void +system_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_ASSERT("invalid len", len <= 0xff); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 4: /* sysContact */ + MEMCPY(syscontact_ptr, value, len); + *syscontact_len_ptr = (u8_t)len; + break; + case 5: /* sysName */ + MEMCPY(sysname_ptr, value, len); + *sysname_len_ptr = (u8_t)len; + break; + case 6: /* sysLocation */ + MEMCPY(syslocation_ptr, value, len); + *syslocation_len_ptr = (u8_t)len; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %d\n", id)); + break; + }; +} + +/** + * Returns interfaces.ifnumber object definition. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns interfaces.ifnumber object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +interfaces_get_value(struct obj_def *od, u16_t len, void *value) +{ + LWIP_UNUSED_ARG(len); + if (od->id_inst_ptr[0] == 1) + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = iflist_root.count; + } +} + +/** + * Returns ifentry object definitions. + * + * @param ident_len the address length (2) + * @param ident points to objectname.index + * @param od points to object definition. + */ +static void +ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id)); + switch (id) + { + case 1: /* ifIndex */ + case 3: /* ifType */ + case 4: /* ifMtu */ + case 8: /* ifOperStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ifDescr */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + /** @todo this should be some sort of sizeof(struct netif.name) */ + od->v_len = 2; + break; + case 5: /* ifSpeed */ + case 21: /* ifOutQLen */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + case 6: /* ifPhysAddress */ + { + struct netif *netif; + + snmp_ifindextonetif(ident[1], &netif); + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = netif->hwaddr_len; + } + break; + case 7: /* ifAdminStatus */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ifLastChange */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS); + od->v_len = sizeof(u32_t); + break; + case 10: /* ifInOctets */ + case 11: /* ifInUcastPkts */ + case 12: /* ifInNUcastPkts */ + case 13: /* ifInDiscarts */ + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + case 16: /* ifOutOctets */ + case 17: /* ifOutUcastPkts */ + case 18: /* ifOutNUcastPkts */ + case 19: /* ifOutDiscarts */ + case 20: /* ifOutErrors */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 22: /* ifSpecific */ + /** @note returning zeroDotZero (0.0) no media specific MIB support */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = ifspecific.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +/** + * Returns ifentry object value. + * + * @param ident_len the address length (2) + * @param ident points to objectname.0 (object id trailer) + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value into. + */ +static void +ifentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ifIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ifDescr */ + MEMCPY(value, netif->name, len); + break; + case 3: /* ifType */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = netif->link_type; + } + break; + case 4: /* ifMtu */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = netif->mtu; + } + break; + case 5: /* ifSpeed */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->link_speed; + } + break; + case 6: /* ifPhysAddress */ + MEMCPY(value, netif->hwaddr, len); + break; + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (netif_is_up(netif)) + { + if (netif_is_link_up(netif)) + { + *sint_ptr = 1; /* up */ + } + else + { + *sint_ptr = 7; /* lowerLayerDown */ + } + } + else + { + *sint_ptr = 2; /* down */ + } + } + break; + case 8: /* ifOperStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (netif_is_up(netif)) + { + *sint_ptr = 1; + } + else + { + *sint_ptr = 2; + } + } + break; + case 9: /* ifLastChange */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ts; + } + break; + case 10: /* ifInOctets */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinoctets; + } + break; + case 11: /* ifInUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinucastpkts; + } + break; + case 12: /* ifInNUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifinnucastpkts; + } + break; + case 13: /* ifInDiscarts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifindiscards; + } + break; + case 14: /* ifInErrors */ + case 15: /* ifInUnkownProtos */ + /** @todo add these counters! */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 16: /* ifOutOctets */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutoctets; + } + break; + case 17: /* ifOutUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutucastpkts; + } + break; + case 18: /* ifOutNUcastPkts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutnucastpkts; + } + break; + case 19: /* ifOutDiscarts */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = netif->ifoutdiscards; + } + break; + case 20: /* ifOutErrors */ + /** @todo add this counter! */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 21: /* ifOutQLen */ + /** @todo figure out if this must be 0 (no queue) or 1? */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = 0; + } + break; + case 22: /* ifSpecific */ + MEMCPY(value, ifspecific.id, len); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_value(): unknown id: %d\n", id)); + break; + }; +} + +#if !SNMP_SAFE_REQUESTS +static u8_t +ifentry_set_test(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id, set_ok; + LWIP_UNUSED_ARG(len); + + set_ok = 0; + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (*sint_ptr == 1 || *sint_ptr == 2) + set_ok = 1; + } + break; + } + return set_ok; +} + +static void +ifentry_set_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + u8_t id; + LWIP_UNUSED_ARG(len); + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 7: /* ifAdminStatus */ + { + s32_t *sint_ptr = (s32_t*)value; + if (*sint_ptr == 1) + { + netif_set_up(netif); + } + else if (*sint_ptr == 2) + { + netif_set_down(netif); + } + } + break; + } +} +#endif /* SNMP_SAFE_REQUESTS */ + +/** + * Returns atentry object definitions. + * + * @param ident_len the address length (6) + * @param ident points to objectname.atifindex.atnetaddress + * @param od points to object definition. + */ +static void +atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* atIfIndex */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* atPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* atNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +atentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + ip_addr_t* ipaddr_ret; +#endif /* LWIP_ARP */ + ip_addr_t ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* atIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* atPhysAddress */ + { + struct eth_addr *dst = (struct eth_addr*)value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* atNetAddress */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + *dst = *ipaddr_ret; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_value(): unknown id: %d\n", id)); + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id)); + switch (id) + { + case 1: /* ipForwarding */ + case 2: /* ipDefaultTTL */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 3: /* ipInReceives */ + case 4: /* ipInHdrErrors */ + case 5: /* ipInAddrErrors */ + case 6: /* ipForwDatagrams */ + case 7: /* ipInUnknownProtos */ + case 8: /* ipInDiscards */ + case 9: /* ipInDelivers */ + case 10: /* ipOutRequests */ + case 11: /* ipOutDiscards */ + case 12: /* ipOutNoRoutes */ + case 14: /* ipReasmReqds */ + case 15: /* ipReasmOKs */ + case 16: /* ipReasmFails */ + case 17: /* ipFragOKs */ + case 18: /* ipFragFails */ + case 19: /* ipFragCreates */ + case 23: /* ipRoutingDiscards */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 13: /* ipReasmTimeout */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_FORWARD + /* forwarding */ + *sint_ptr = 1; +#else + /* not-forwarding */ + *sint_ptr = 2; +#endif + } + break; + case 2: /* ipDefaultTTL */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = IP_DEFAULT_TTL; + } + break; + case 3: /* ipInReceives */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinreceives; + } + break; + case 4: /* ipInHdrErrors */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinhdrerrors; + } + break; + case 5: /* ipInAddrErrors */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinaddrerrors; + } + break; + case 6: /* ipForwDatagrams */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipforwdatagrams; + } + break; + case 7: /* ipInUnknownProtos */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipinunknownprotos; + } + break; + case 8: /* ipInDiscards */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipindiscards; + } + break; + case 9: /* ipInDelivers */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipindelivers; + } + break; + case 10: /* ipOutRequests */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutrequests; + } + break; + case 11: /* ipOutDiscards */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutdiscards; + } + break; + case 12: /* ipOutNoRoutes */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipoutnoroutes; + } + break; + case 13: /* ipReasmTimeout */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_REASSEMBLY + *sint_ptr = IP_REASS_MAXAGE; +#else + *sint_ptr = 0; +#endif + } + break; + case 14: /* ipReasmReqds */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmreqds; + } + break; + case 15: /* ipReasmOKs */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmoks; + } + break; + case 16: /* ipReasmFails */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipreasmfails; + } + break; + case 17: /* ipFragOKs */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragoks; + } + break; + case 18: /* ipFragFails */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragfails; + } + break; + case 19: /* ipFragCreates */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = ipfragcreates; + } + break; + case 23: /* ipRoutingDiscards */ + /** @todo can lwIP discard routes at all?? hardwire this to 0?? */ + { + u32_t *uint_ptr = (u32_t*)value; + *uint_ptr = iproutingdiscards; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_value(): unknown id: %d\n", id)); + break; + }; +} + +/** + * Test ip object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + * + * @note we allow set if the value matches the hardwired value, + * otherwise return badvalue. + */ +static u8_t +ip_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + s32_t *sint_ptr = (s32_t*)value; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipForwarding */ +#if IP_FORWARD + /* forwarding */ + if (*sint_ptr == 1) +#else + /* not-forwarding */ + if (*sint_ptr == 2) +#endif + { + set_ok = 1; + } + break; + case 2: /* ipDefaultTTL */ + if (*sint_ptr == IP_DEFAULT_TTL) + { + set_ok = 1; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_set_test(): unknown id: %d\n", id)); + break; + }; + return set_ok; +} + +static void +ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + case 3: /* ipAdEntNetMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipAdEntIfIndex */ + case 4: /* ipAdEntBcastAddr */ + case 5: /* ipAdEntReasmMaxSize */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + u16_t ifidx; + ip_addr_t ip; + struct netif *netif = netif_list; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], &ip); + ifidx = 0; + while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr)) + { + netif = netif->next; + ifidx++; + } + + if (netif != NULL) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipAdEntAddr */ + { + ip_addr_t *dst = (ip_addr_t*)value; + *dst = netif->ip_addr; + } + break; + case 2: /* ipAdEntIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = ifidx + 1; + } + break; + case 3: /* ipAdEntNetMask */ + { + ip_addr_t *dst = (ip_addr_t*)value; + *dst = netif->netmask; + } + break; + case 4: /* ipAdEntBcastAddr */ + { + s32_t *sint_ptr = (s32_t*)value; + + /* lwIP oddity, there's no broadcast + address in the netif we can rely on */ + *sint_ptr = IPADDR_BROADCAST & 1; + } + break; + case 5: /* ipAdEntReasmMaxSize */ + { + s32_t *sint_ptr = (s32_t*)value; +#if IP_REASSEMBLY + /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, + * but only if receiving one fragmented packet at a time. + * The current solution is to calculate for 2 simultaneous packets... + */ + *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * + (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN))); +#else + /** @todo returning MTU would be a bad thing and + returning a wild guess like '576' isn't good either */ + *sint_ptr = 0; +#endif + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_value(): unknown id: %d\n", id)); + break; + } + } +} + +/** + * @note + * lwIP IP routing is currently using the network addresses in netif_list. + * if no suitable network IP is found in netif_list, the default_netif is used. + */ +static void +ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (4) */ + ident_len += 4; + ident -= 4; + + if (ident_len == 5) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + case 7: /* ipRouteNextHop */ + case 11: /* ipRouteMask */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* ipRouteIfIndex */ + case 3: /* ipRouteMetric1 */ + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 8: /* ipRouteType */ + case 10: /* ipRouteAge */ + case 12: /* ipRouteMetric5 */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 9: /* ipRouteProto */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 13: /* ipRouteInfo */ + /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID); + od->v_len = iprouteinfo.len * sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + struct netif *netif; + ip_addr_t dest; + s32_t *ident; + u8_t id; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &dest); + + if (ip_addr_isany(&dest)) + { + /* ip_route() uses default netif for default route */ + netif = netif_default; + } + else + { + /* not using ip_route(), need exact match! */ + netif = netif_list; + while ((netif != NULL) && + !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) ) + { + netif = netif->next; + } + } + if (netif != NULL) + { + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipRouteDest */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte has 0.0.0.0 dest */ + ip_addr_set_zero(dst); + } + else + { + /* netifs have netaddress dest */ + ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask); + } + } + break; + case 2: /* ipRouteIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + + snmp_netiftoifindex(netif, sint_ptr); + } + break; + case 3: /* ipRouteMetric1 */ + { + s32_t *sint_ptr = (s32_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte has metric 1 */ + *sint_ptr = 1; + } + else + { + /* other rtes have metric 0 */ + *sint_ptr = 0; + } + } + break; + case 4: /* ipRouteMetric2 */ + case 5: /* ipRouteMetric3 */ + case 6: /* ipRouteMetric4 */ + case 12: /* ipRouteMetric5 */ + { + s32_t *sint_ptr = (s32_t*)value; + /* not used */ + *sint_ptr = -1; + } + break; + case 7: /* ipRouteNextHop */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte: gateway */ + *dst = netif->gw; + } + else + { + /* other rtes: netif ip_addr */ + *dst = netif->ip_addr; + } + } + break; + case 8: /* ipRouteType */ + { + s32_t *sint_ptr = (s32_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte is indirect */ + *sint_ptr = 4; + } + else + { + /* other rtes are direct */ + *sint_ptr = 3; + } + } + break; + case 9: /* ipRouteProto */ + { + s32_t *sint_ptr = (s32_t*)value; + /* locally defined routes */ + *sint_ptr = 2; + } + break; + case 10: /* ipRouteAge */ + { + s32_t *sint_ptr = (s32_t*)value; + /** @todo (sysuptime - timestamp last change) / 100 + @see snmp_insert_iprteidx_tree() */ + *sint_ptr = 0; + } + break; + case 11: /* ipRouteMask */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + if (ip_addr_isany(&dest)) + { + /* default rte use 0.0.0.0 mask */ + ip_addr_set_zero(dst); + } + else + { + /* other rtes use netmask */ + *dst = netif->netmask; + } + } + break; + case 13: /* ipRouteInfo */ + MEMCPY(value, iprouteinfo.id, len); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_value(): unknown id: %d\n", id)); + break; + } + } +} + +static void +ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + case 4: /* ipNetToMediaType */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* ipNetToMediaPhysAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR); + od->v_len = 6; /** @todo try to use netif::hwaddr_len */ + break; + case 3: /* ipNetToMediaNetAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value) +{ +#if LWIP_ARP + u8_t id; + struct eth_addr* ethaddr_ret; + ip_addr_t* ipaddr_ret; +#endif /* LWIP_ARP */ + ip_addr_t ip; + struct netif *netif; + + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */ + + snmp_ifindextonetif(od->id_inst_ptr[1], &netif); + snmp_oidtoip(&od->id_inst_ptr[2], &ip); + +#if LWIP_ARP /** @todo implement a netif_find_addr */ + if (etharp_find_addr(netif, &ip, ðaddr_ret, &ipaddr_ret) > -1) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* ipNetToMediaIfIndex */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = od->id_inst_ptr[1]; + } + break; + case 2: /* ipNetToMediaPhysAddress */ + { + struct eth_addr *dst = (struct eth_addr*)value; + + *dst = *ethaddr_ret; + } + break; + case 3: /* ipNetToMediaNetAddress */ + { + ip_addr_t *dst = (ip_addr_t*)value; + + *dst = *ipaddr_ret; + } + break; + case 4: /* ipNetToMediaType */ + { + s32_t *sint_ptr = (s32_t*)value; + /* dynamic (?) */ + *sint_ptr = 3; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_value(): unknown id: %d\n", id)); + break; + } + } +#endif /* LWIP_ARP */ +} + +static void +icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 27)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +icmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* icmpInMsgs */ + *uint_ptr = icmpinmsgs; + break; + case 2: /* icmpInErrors */ + *uint_ptr = icmpinerrors; + break; + case 3: /* icmpInDestUnreachs */ + *uint_ptr = icmpindestunreachs; + break; + case 4: /* icmpInTimeExcds */ + *uint_ptr = icmpintimeexcds; + break; + case 5: /* icmpInParmProbs */ + *uint_ptr = icmpinparmprobs; + break; + case 6: /* icmpInSrcQuenchs */ + *uint_ptr = icmpinsrcquenchs; + break; + case 7: /* icmpInRedirects */ + *uint_ptr = icmpinredirects; + break; + case 8: /* icmpInEchos */ + *uint_ptr = icmpinechos; + break; + case 9: /* icmpInEchoReps */ + *uint_ptr = icmpinechoreps; + break; + case 10: /* icmpInTimestamps */ + *uint_ptr = icmpintimestamps; + break; + case 11: /* icmpInTimestampReps */ + *uint_ptr = icmpintimestampreps; + break; + case 12: /* icmpInAddrMasks */ + *uint_ptr = icmpinaddrmasks; + break; + case 13: /* icmpInAddrMaskReps */ + *uint_ptr = icmpinaddrmaskreps; + break; + case 14: /* icmpOutMsgs */ + *uint_ptr = icmpoutmsgs; + break; + case 15: /* icmpOutErrors */ + *uint_ptr = icmpouterrors; + break; + case 16: /* icmpOutDestUnreachs */ + *uint_ptr = icmpoutdestunreachs; + break; + case 17: /* icmpOutTimeExcds */ + *uint_ptr = icmpouttimeexcds; + break; + case 18: /* icmpOutParmProbs */ + *uint_ptr = icmpoutparmprobs; + break; + case 19: /* icmpOutSrcQuenchs */ + *uint_ptr = icmpoutsrcquenchs; + break; + case 20: /* icmpOutRedirects */ + *uint_ptr = icmpoutredirects; + break; + case 21: /* icmpOutEchos */ + *uint_ptr = icmpoutechos; + break; + case 22: /* icmpOutEchoReps */ + *uint_ptr = icmpoutechoreps; + break; + case 23: /* icmpOutTimestamps */ + *uint_ptr = icmpouttimestamps; + break; + case 24: /* icmpOutTimestampReps */ + *uint_ptr = icmpouttimestampreps; + break; + case 25: /* icmpOutAddrMasks */ + *uint_ptr = icmpoutaddrmasks; + break; + case 26: /* icmpOutAddrMaskReps */ + *uint_ptr = icmpoutaddrmaskreps; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_value(): unknown id: %d\n", id)); + break; + } +} + +#if LWIP_TCP +/** @todo tcp grp */ +static void +tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + u8_t id; + + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpRtoAlgorithm */ + case 2: /* tcpRtoMin */ + case 3: /* tcpRtoMax */ + case 4: /* tcpMaxConn */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 5: /* tcpActiveOpens */ + case 6: /* tcpPassiveOpens */ + case 7: /* tcpAttemptFails */ + case 8: /* tcpEstabResets */ + case 10: /* tcpInSegs */ + case 11: /* tcpOutSegs */ + case 12: /* tcpRetransSegs */ + case 14: /* tcpInErrs */ + case 15: /* tcpOutRsts */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 9: /* tcpCurrEstab */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE); + od->v_len = sizeof(u32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + s32_t *sint_ptr = (s32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* tcpRtoAlgorithm, vanj(4) */ + *sint_ptr = 4; + break; + case 2: /* tcpRtoMin */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 1000; + break; + case 3: /* tcpRtoMax */ + /* @todo not the actual value, a guess, + needs to be calculated */ + *sint_ptr = 60000; + break; + case 4: /* tcpMaxConn */ + *sint_ptr = MEMP_NUM_TCP_PCB; + break; + case 5: /* tcpActiveOpens */ + *uint_ptr = tcpactiveopens; + break; + case 6: /* tcpPassiveOpens */ + *uint_ptr = tcppassiveopens; + break; + case 7: /* tcpAttemptFails */ + *uint_ptr = tcpattemptfails; + break; + case 8: /* tcpEstabResets */ + *uint_ptr = tcpestabresets; + break; + case 9: /* tcpCurrEstab */ + { + u16_t tcpcurrestab = 0; + struct tcp_pcb *pcb = tcp_active_pcbs; + while (pcb != NULL) + { + if ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT)) + { + tcpcurrestab++; + } + pcb = pcb->next; + } + *uint_ptr = tcpcurrestab; + } + break; + case 10: /* tcpInSegs */ + *uint_ptr = tcpinsegs; + break; + case 11: /* tcpOutSegs */ + *uint_ptr = tcpoutsegs; + break; + case 12: /* tcpRetransSegs */ + *uint_ptr = tcpretranssegs; + break; + case 14: /* tcpInErrs */ + *uint_ptr = tcpinerrs; + break; + case 15: /* tcpOutRsts */ + *uint_ptr = tcpoutrsts; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_value(): unknown id: %d\n", id)); + break; + } +} +#ifdef THIS_SEEMS_UNUSED +static void +tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (10) */ + ident_len += 10; + ident -= 10; + + if (ident_len == 11) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + id = ident[0]; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id)); + + switch (id) + { + case 1: /* tcpConnState */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + case 2: /* tcpConnLocalAddress */ + case 4: /* tcpConnRemAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 3: /* tcpConnLocalPort */ + case 5: /* tcpConnRemPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + ip_addr_t lip, rip; + u16_t lport, rport; + s32_t *ident; + + ident = od->id_inst_ptr; + snmp_oidtoip(&ident[1], &lip); + lport = ident[5]; + snmp_oidtoip(&ident[6], &rip); + rport = ident[10]; + + /** @todo find matching PCB */ +} +#endif /* if 0 */ +#endif + +static void +udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if ((ident_len == 2) && + (ident[0] > 0) && (ident[0] < 6)) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpInDatagrams */ + *uint_ptr = udpindatagrams; + break; + case 2: /* udpNoPorts */ + *uint_ptr = udpnoports; + break; + case 3: /* udpInErrors */ + *uint_ptr = udpinerrors; + break; + case 4: /* udpOutDatagrams */ + *uint_ptr = udpoutdatagrams; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_value(): unknown id: %d\n", id)); + break; + } +} + +static void +udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (5) */ + ident_len += 5; + ident -= 5; + + if (ident_len == 6) + { + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + switch (ident[0]) + { + case 1: /* udpLocalAddress */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR); + od->v_len = 4; + break; + case 2: /* udpLocalPort */ + od->instance = MIB_OBJECT_TAB; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + } + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +udpentry_get_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + struct udp_pcb *pcb; + ipX_addr_t ip; + u16_t port; + + LWIP_UNUSED_ARG(len); + snmp_oidtoip(&od->id_inst_ptr[1], (ip_addr_t*)&ip); + LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff)); + port = (u16_t)od->id_inst_ptr[5]; + + pcb = udp_pcbs; + while ((pcb != NULL) && + !(ipX_addr_cmp(0, &pcb->local_ip, &ip) && + (pcb->local_port == port))) + { + pcb = pcb->next; + } + + if (pcb != NULL) + { + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* udpLocalAddress */ + { + ipX_addr_t *dst = (ipX_addr_t*)value; + ipX_addr_copy(0, *dst, pcb->local_ip); + } + break; + case 2: /* udpLocalPort */ + { + s32_t *sint_ptr = (s32_t*)value; + *sint_ptr = pcb->local_port; + } + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_value(): unknown id: %d\n", id)); + break; + } + } +} + +static void +snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od) +{ + /* return to object name, adding index depth (1) */ + ident_len += 1; + ident -= 1; + if (ident_len == 2) + { + u8_t id; + + od->id_inst_len = ident_len; + od->id_inst_ptr = ident; + + LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff)); + id = (u8_t)ident[0]; + switch (id) + { + case 1: /* snmpInPkts */ + case 2: /* snmpOutPkts */ + case 3: /* snmpInBadVersions */ + case 4: /* snmpInBadCommunityNames */ + case 5: /* snmpInBadCommunityUses */ + case 6: /* snmpInASNParseErrs */ + case 8: /* snmpInTooBigs */ + case 9: /* snmpInNoSuchNames */ + case 10: /* snmpInBadValues */ + case 11: /* snmpInReadOnlys */ + case 12: /* snmpInGenErrs */ + case 13: /* snmpInTotalReqVars */ + case 14: /* snmpInTotalSetVars */ + case 15: /* snmpInGetRequests */ + case 16: /* snmpInGetNexts */ + case 17: /* snmpInSetRequests */ + case 18: /* snmpInGetResponses */ + case 19: /* snmpInTraps */ + case 20: /* snmpOutTooBigs */ + case 21: /* snmpOutNoSuchNames */ + case 22: /* snmpOutBadValues */ + case 24: /* snmpOutGenErrs */ + case 25: /* snmpOutGetRequests */ + case 26: /* snmpOutGetNexts */ + case 27: /* snmpOutSetRequests */ + case 28: /* snmpOutGetResponses */ + case 29: /* snmpOutTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_ONLY; + od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER); + od->v_len = sizeof(u32_t); + break; + case 30: /* snmpEnableAuthenTraps */ + od->instance = MIB_OBJECT_SCALAR; + od->access = MIB_OBJECT_READ_WRITE; + od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG); + od->v_len = sizeof(s32_t); + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n")); + od->instance = MIB_OBJECT_NONE; + break; + }; + } + else + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n")); + od->instance = MIB_OBJECT_NONE; + } +} + +static void +snmp_get_value(struct obj_def *od, u16_t len, void *value) +{ + u32_t *uint_ptr = (u32_t*)value; + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + switch (id) + { + case 1: /* snmpInPkts */ + *uint_ptr = snmpinpkts; + break; + case 2: /* snmpOutPkts */ + *uint_ptr = snmpoutpkts; + break; + case 3: /* snmpInBadVersions */ + *uint_ptr = snmpinbadversions; + break; + case 4: /* snmpInBadCommunityNames */ + *uint_ptr = snmpinbadcommunitynames; + break; + case 5: /* snmpInBadCommunityUses */ + *uint_ptr = snmpinbadcommunityuses; + break; + case 6: /* snmpInASNParseErrs */ + *uint_ptr = snmpinasnparseerrs; + break; + case 8: /* snmpInTooBigs */ + *uint_ptr = snmpintoobigs; + break; + case 9: /* snmpInNoSuchNames */ + *uint_ptr = snmpinnosuchnames; + break; + case 10: /* snmpInBadValues */ + *uint_ptr = snmpinbadvalues; + break; + case 11: /* snmpInReadOnlys */ + *uint_ptr = snmpinreadonlys; + break; + case 12: /* snmpInGenErrs */ + *uint_ptr = snmpingenerrs; + break; + case 13: /* snmpInTotalReqVars */ + *uint_ptr = snmpintotalreqvars; + break; + case 14: /* snmpInTotalSetVars */ + *uint_ptr = snmpintotalsetvars; + break; + case 15: /* snmpInGetRequests */ + *uint_ptr = snmpingetrequests; + break; + case 16: /* snmpInGetNexts */ + *uint_ptr = snmpingetnexts; + break; + case 17: /* snmpInSetRequests */ + *uint_ptr = snmpinsetrequests; + break; + case 18: /* snmpInGetResponses */ + *uint_ptr = snmpingetresponses; + break; + case 19: /* snmpInTraps */ + *uint_ptr = snmpintraps; + break; + case 20: /* snmpOutTooBigs */ + *uint_ptr = snmpouttoobigs; + break; + case 21: /* snmpOutNoSuchNames */ + *uint_ptr = snmpoutnosuchnames; + break; + case 22: /* snmpOutBadValues */ + *uint_ptr = snmpoutbadvalues; + break; + case 24: /* snmpOutGenErrs */ + *uint_ptr = snmpoutgenerrs; + break; + case 25: /* snmpOutGetRequests */ + *uint_ptr = snmpoutgetrequests; + break; + case 26: /* snmpOutGetNexts */ + *uint_ptr = snmpoutgetnexts; + break; + case 27: /* snmpOutSetRequests */ + *uint_ptr = snmpoutsetrequests; + break; + case 28: /* snmpOutGetResponses */ + *uint_ptr = snmpoutgetresponses; + break; + case 29: /* snmpOutTraps */ + *uint_ptr = snmpouttraps; + break; + case 30: /* snmpEnableAuthenTraps */ + *uint_ptr = *snmpenableauthentraps_ptr; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_value(): unknown id: %d\n", id)); + break; + }; +} + +/** + * Test snmp object value before setting. + * + * @param od is the object definition + * @param len return value space (in bytes) + * @param value points to (varbind) space to copy value from. + */ +static u8_t +snmp_set_test(struct obj_def *od, u16_t len, void *value) +{ + u8_t id, set_ok; + + LWIP_UNUSED_ARG(len); + set_ok = 0; + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + s32_t *sint_ptr = (s32_t*)value; + + if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default) + { + /* we should have writable non-volatile mem here */ + if ((*sint_ptr == 1) || (*sint_ptr == 2)) + { + set_ok = 1; + } + } + else + { + /* const or hardwired value */ + if (*sint_ptr == snmpenableauthentraps_default) + { + set_ok = 1; + } + } + } + return set_ok; +} + +static void +snmp_set_value(struct obj_def *od, u16_t len, void *value) +{ + u8_t id; + + LWIP_UNUSED_ARG(len); + LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff)); + id = (u8_t)od->id_inst_ptr[0]; + if (id == 30) + { + /* snmpEnableAuthenTraps */ + /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */ + u8_t *ptr = (u8_t*)value; + *snmpenableauthentraps_ptr = *ptr; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib_structs.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib_structs.c new file mode 100644 index 0000000..fa796c5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/mib_structs.c @@ -0,0 +1,1175 @@ +/** + * @file + * MIB tree access/construction functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp_structs.h" +#include "lwip/memp.h" +#include "lwip/netif.h" + +/** .iso.org.dod.internet address prefix, @see snmp_iso_*() */ +const s32_t prefix[4] = {1, 3, 6, 1}; + +#define NODE_STACK_SIZE (LWIP_SNMP_OBJ_ID_LEN) +/** node stack entry (old news?) */ +struct nse +{ + /** right child */ + struct mib_node* r_ptr; + /** right child identifier */ + s32_t r_id; + /** right child next level */ + u8_t r_nl; +}; +static u8_t node_stack_cnt; +static struct nse node_stack[NODE_STACK_SIZE]; +const struct nse node_null = {NULL, 0, 0}; + +/** + * Pushes nse struct onto stack. + */ +static void +push_node(const struct nse* node) +{ + LWIP_ASSERT("node_stack_cnt < NODE_STACK_SIZE",node_stack_cnt < NODE_STACK_SIZE); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("push_node() node=%p id=%"S32_F"\n",(void*)(node->r_ptr),node->r_id)); + if (node_stack_cnt < NODE_STACK_SIZE) + { + node_stack[node_stack_cnt] = *node; + node_stack_cnt++; + } +} + +/** + * Pops nse struct from stack. + */ +static void +pop_node(struct nse* node) +{ + if (node_stack_cnt > 0) + { + node_stack_cnt--; + *node = node_stack[node_stack_cnt]; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("pop_node() node=%p id=%"S32_F"\n",(void *)(node->r_ptr),node->r_id)); +} + +/** + * Conversion from ifIndex to lwIP netif + * @param ifindex is a s32_t object sub-identifier + * @param netif points to returned netif struct pointer + */ +void +snmp_ifindextonetif(s32_t ifindex, struct netif **netif) +{ + struct netif *nif = netif_list; + s32_t i, ifidx; + + ifidx = ifindex - 1; + i = 0; + while ((nif != NULL) && (i < ifidx)) + { + nif = nif->next; + i++; + } + *netif = nif; +} + +/** + * Conversion from lwIP netif to ifIndex + * @param netif points to a netif struct + * @param ifidx points to s32_t object sub-identifier + */ +void +snmp_netiftoifindex(struct netif *netif, s32_t *ifidx) +{ + struct netif *nif = netif_list; + u16_t i; + + i = 0; + while ((nif != NULL) && (nif != netif)) + { + nif = nif->next; + i++; + } + *ifidx = i+1; +} + +/** + * Conversion from oid to lwIP ip_addr + * @param ident points to s32_t ident[4] input + * @param ip points to output struct + */ +void +snmp_oidtoip(s32_t *ident, ip_addr_t *ip) +{ + IP4_ADDR(ip, ident[0], ident[1], ident[2], ident[3]); +} + +/** + * Conversion from lwIP ip_addr to oid + * @param ip points to input struct + * @param ident points to s32_t ident[4] output + */ +void +snmp_iptooid(ip_addr_t *ip, s32_t *ident) +{ + ident[0] = ip4_addr1(ip); + ident[1] = ip4_addr2(ip); + ident[2] = ip4_addr3(ip); + ident[3] = ip4_addr4(ip); +} + +struct mib_list_node * +snmp_mib_ln_alloc(s32_t id) +{ + struct mib_list_node *ln; + + ln = (struct mib_list_node *)memp_malloc(MEMP_SNMP_NODE); + if (ln != NULL) + { + ln->prev = NULL; + ln->next = NULL; + ln->objid = id; + ln->nptr = NULL; + } + return ln; +} + +void +snmp_mib_ln_free(struct mib_list_node *ln) +{ + memp_free(MEMP_SNMP_NODE, ln); +} + +struct mib_list_rootnode * +snmp_mib_lrn_alloc(void) +{ + struct mib_list_rootnode *lrn; + + lrn = (struct mib_list_rootnode*)memp_malloc(MEMP_SNMP_ROOTNODE); + if (lrn != NULL) + { + lrn->get_object_def = noleafs_get_object_def; + lrn->get_value = noleafs_get_value; + lrn->set_test = noleafs_set_test; + lrn->set_value = noleafs_set_value; + lrn->node_type = MIB_NODE_LR; + lrn->maxlength = 0; + lrn->head = NULL; + lrn->tail = NULL; + lrn->count = 0; + } + return lrn; +} + +void +snmp_mib_lrn_free(struct mib_list_rootnode *lrn) +{ + memp_free(MEMP_SNMP_ROOTNODE, lrn); +} + +/** + * Inserts node in idx list in a sorted + * (ascending order) fashion and + * allocates the node if needed. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param insn points to a pointer to the inserted node + * used for constructing the tree. + * @return -1 if failed, 1 if inserted, 2 if present. + */ +s8_t +snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn) +{ + struct mib_list_node *nn; + s8_t insert; + + LWIP_ASSERT("rn != NULL",rn != NULL); + + /* -1 = malloc failure, 0 = not inserted, 1 = inserted, 2 = was present */ + insert = 0; + if (rn->head == NULL) + { + /* empty list, add first node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc empty list objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + rn->head = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + insert = -1; + } + } + else + { + struct mib_list_node *n; + /* at least one node is present */ + n = rn->head; + while ((n != NULL) && (insert == 0)) + { + if (n->objid == objid) + { + /* node is already there */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node already there objid==%"S32_F"\n",objid)); + *insn = n; + insert = 2; + } + else if (n->objid < objid) + { + if (n->next == NULL) + { + /* alloc and insert at the tail */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins tail objid==%"S32_F"\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + nn->next = NULL; + nn->prev = n; + n->next = nn; + rn->tail = nn; + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + else + { + /* there's more to explore: traverse list */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("traverse list\n")); + n = n->next; + } + } + else + { + /* n->objid > objid */ + /* alloc and insert between n->prev and n */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("alloc ins n->prev, objid==%"S32_F", n\n",objid)); + nn = snmp_mib_ln_alloc(objid); + if (nn != NULL) + { + if (n->prev == NULL) + { + /* insert at the head */ + nn->next = n; + nn->prev = NULL; + rn->head = nn; + n->prev = nn; + } + else + { + /* insert in the middle */ + nn->next = n; + nn->prev = n->prev; + n->prev->next = nn; + n->prev = nn; + } + *insn = nn; + insert = 1; + } + else + { + /* insertion failure */ + insert = -1; + } + } + } + } + if (insert == 1) + { + rn->count += 1; + } + LWIP_ASSERT("insert != 0",insert != 0); + return insert; +} + +/** + * Finds node in idx list and returns deletion mark. + * + * @param rn points to the root node + * @param objid is the object sub identifier + * @param fn returns pointer to found node + * @return 0 if not found, 1 if deletable, + * 2 can't delete (2 or more children), 3 not a list_node + */ +s8_t +snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn) +{ + s8_t fc; + struct mib_list_node *n; + + LWIP_ASSERT("rn != NULL",rn != NULL); + n = rn->head; + while ((n != NULL) && (n->objid != objid)) + { + n = n->next; + } + if (n == NULL) + { + fc = 0; + } + else if (n->nptr == NULL) + { + /* leaf, can delete node */ + fc = 1; + } + else + { + struct mib_list_rootnode *r; + + if (n->nptr->node_type == MIB_NODE_LR) + { + r = (struct mib_list_rootnode *)n->nptr; + if (r->count > 1) + { + /* can't delete node */ + fc = 2; + } + else + { + /* count <= 1, can delete node */ + fc = 1; + } + } + else + { + /* other node type */ + fc = 3; + } + } + *fn = n; + return fc; +} + +/** + * Removes node from idx list + * if it has a single child left. + * + * @param rn points to the root node + * @param n points to the node to delete + * @return the nptr to be freed by caller + */ +struct mib_list_rootnode * +snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n) +{ + struct mib_list_rootnode *next; + + LWIP_ASSERT("rn != NULL",rn != NULL); + LWIP_ASSERT("n != NULL",n != NULL); + + /* caller must remove this sub-tree */ + next = (struct mib_list_rootnode*)(n->nptr); + rn->count -= 1; + + if (n == rn->head) + { + rn->head = n->next; + if (n->next != NULL) + { + /* not last node, new list begin */ + n->next->prev = NULL; + } + } + else if (n == rn->tail) + { + rn->tail = n->prev; + if (n->prev != NULL) + { + /* not last node, new list end */ + n->prev->next = NULL; + } + } + else + { + /* node must be in the middle */ + n->prev->next = n->next; + n->next->prev = n->prev; + } + LWIP_DEBUGF(SNMP_MIB_DEBUG,("free list objid==%"S32_F"\n",n->objid)); + snmp_mib_ln_free(n); + if (rn->count == 0) + { + rn->head = NULL; + rn->tail = NULL; + } + return next; +} + + + +/** + * Searches tree for the supplied (scalar?) object identifier. + * + * @param node points to the root of the tree ('.internet') + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param np points to the found object instance (return) + * @return pointer to the requested parent (!) node if success, NULL otherwise + */ +struct mib_node * +snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np) +{ + u8_t node_type, ext_level; + + ext_level = 0; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("node==%p *ident==%"S32_F"\n",(void*)node,*ident)); + while (node != NULL) + { + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + if (ident_len > 0) + { + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + i = 0; + while ((i < an->maxlength) && (an->objid[i] != *ident)) + { + i++; + } + if (i < an->maxlength) + { + /* found it, if available proceed to child, otherwise inspect leaf */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + if (an->nptr[i] == NULL) + { + /* a scalar leaf OR table, + inspect remaining instance number / table index */ + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)an; + } + else + { + /* follow next child pointer */ + ident++; + ident_len--; + node = an->nptr[i]; + } + } + else + { + /* search failed, identifier mismatch (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + if (ident_len > 0) + { + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid != *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + /* found it, proceed to child */; + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + if (ln->nptr == NULL) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)lrn; + } + else + { + /* follow next child pointer */ + ident_len--; + ident++; + node = ln->nptr; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln search failed, short object identifier\n")); + return NULL; + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + u16_t i, len; + + if (ident_len > 0) + { + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) != 0)) + { + i++; + } + if (i < len) + { + s32_t debug_id; + + en->get_objid(en->addr_inf,ext_level,i,&debug_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid==%"S32_F" *ident==%"S32_F"\n",debug_id,*ident)); + if ((ext_level + 1) == en->tree_levels) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)en; + } + else + { + /* found it, proceed to child */ + ident_len--; + ident++; + ext_level++; + } + } + else + { + /* search failed */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed *ident==%"S32_F"\n",*ident)); + return NULL; + } + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en search failed, short object identifier\n")); + return NULL; + } + } + else if (node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + sn = (mib_scalar_node *)node; + if ((ident_len == 1) && (*ident == 0)) + { + np->ident_len = ident_len; + np->ident = ident; + return (struct mib_node*)sn; + } + else + { + /* search failed, short object identifier (nosuchname) */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed, invalid object identifier length\n")); + return NULL; + } + } + else + { + /* unknown node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("search failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test table for presence of at least one table entry. + */ +static u8_t +empty_table(struct mib_node *node) +{ + u8_t node_type; + u8_t empty = 0; + + if (node != NULL) + { + node_type = node->node_type; + if (node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + lrn = (struct mib_list_rootnode *)node; + if ((lrn->count == 0) || (lrn->head == NULL)) + { + empty = 1; + } + } + else if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + an = (struct mib_array_node *)node; + if ((an->maxlength == 0) || (an->nptr == NULL)) + { + empty = 1; + } + } + else if (node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + en = (struct mib_external_node *)node; + if (en->tree_levels == 0) + { + empty = 1; + } + } + } + return empty; +} + +/** + * Tree expansion. + */ +struct mib_node * +snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + u8_t node_type, ext_level, climb_tree; + + ext_level = 0; + /* reset node stack */ + node_stack_cnt = 0; + while (node != NULL) + { + climb_tree = 0; + node_type = node->node_type; + if ((node_type == MIB_NODE_AR) || (node_type == MIB_NODE_RA)) + { + struct mib_array_node *an; + u16_t i; + + /* array node (internal ROM or RAM, fixed length) */ + an = (struct mib_array_node *)node; + if (ident_len > 0) + { + i = 0; + while ((i < an->maxlength) && (an->objid[i] < *ident)) + { + i++; + } + if (i < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("an->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,an->objid[i],*ident)); + /* add identifier to oidret */ + oidret->id[oidret->len] = an->objid[i]; + (oidret->len)++; + + if (an->nptr[i] == NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node (e.g. in a fixed size table) */ + if (an->objid[i] > *ident) + { + return (struct mib_node*)an; + } + else if ((i + 1) < an->maxlength) + { + /* an->objid[i] == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = an->objid[i + 1]; + (oidret->len)++; + return (struct mib_node*)an; + } + else + { + /* (i + 1) == an->maxlength */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u16_t j; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + LWIP_ASSERT("i < 0xff", i < 0xff); + j = i + 1; + while ((j < an->maxlength) && (empty_table(an->nptr[j]))) + { + j++; + } + if (j < an->maxlength) + { + struct nse cur_node; + cur_node.r_ptr = an->nptr[j]; + cur_node.r_id = an->objid[j]; + cur_node.r_nl = 0; + push_node(&cur_node); + } + else + { + push_node(&node_null); + } + if (an->objid[i] == *ident) + { + ident_len--; + ident++; + } + else + { + /* an->objid[i] < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = an->nptr[i]; + } + } + else + { + /* i == an->maxlength */ + climb_tree = 1; + } + } + else + { + u16_t j; + /* ident_len == 0, complete with leftmost '.thing' */ + j = 0; + while ((j < an->maxlength) && empty_table(an->nptr[j])) + { + j++; + } + if (j < an->maxlength) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left an->objid[j]==%"S32_F"\n",an->objid[j])); + oidret->id[oidret->len] = an->objid[j]; + (oidret->len)++; + if (an->nptr[j] == NULL) + { + /* leaf node */ + return (struct mib_node*)an; + } + else + { + /* no leaf, continue */ + node = an->nptr[j]; + } + } + else + { + /* j == an->maxlength */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_LR) + { + struct mib_list_rootnode *lrn; + struct mib_list_node *ln; + + /* list root node (internal 'RAM', variable length) */ + lrn = (struct mib_list_rootnode *)node; + if (ident_len > 0) + { + ln = lrn->head; + /* iterate over list, head to tail */ + while ((ln != NULL) && (ln->objid < *ident)) + { + ln = ln->next; + } + if (ln != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("ln->objid==%"S32_F" *ident==%"S32_F"\n",ln->objid,*ident)); + oidret->id[oidret->len] = ln->objid; + (oidret->len)++; + if (ln->nptr == NULL) + { + /* leaf node */ + if (ln->objid > *ident) + { + return (struct mib_node*)lrn; + } + else if (ln->next != NULL) + { + /* ln->objid == *ident */ + (oidret->len)--; + oidret->id[oidret->len] = ln->next->objid; + (oidret->len)++; + return (struct mib_node*)lrn; + } + else + { + /* ln->next == NULL */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + + /* non-leaf, store right child ptr and id */ + jn = ln->next; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + struct nse cur_node; + cur_node.r_ptr = jn->nptr; + cur_node.r_id = jn->objid; + cur_node.r_nl = 0; + push_node(&cur_node); + } + else + { + push_node(&node_null); + } + if (ln->objid == *ident) + { + ident_len--; + ident++; + } + else + { + /* ln->objid < *ident */ + ident_len = 0; + } + /* follow next child pointer */ + node = ln->nptr; + } + + } + else + { + /* ln == NULL */ + climb_tree = 1; + } + } + else + { + struct mib_list_node *jn; + /* ident_len == 0, complete with leftmost '.thing' */ + jn = lrn->head; + while ((jn != NULL) && empty_table(jn->nptr)) + { + jn = jn->next; + } + if (jn != NULL) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left jn->objid==%"S32_F"\n",jn->objid)); + oidret->id[oidret->len] = jn->objid; + (oidret->len)++; + if (jn->nptr == NULL) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("jn->nptr == NULL\n")); + return (struct mib_node*)lrn; + } + else + { + /* no leaf, continue */ + node = jn->nptr; + } + } + else + { + /* jn == NULL */ + climb_tree = 1; + } + } + } + else if(node_type == MIB_NODE_EX) + { + struct mib_external_node *en; + s32_t ex_id; + + /* external node (addressing and access via functions) */ + en = (struct mib_external_node *)node; + if (ident_len > 0) + { + u16_t i, len; + + i = 0; + len = en->level_length(en->addr_inf,ext_level); + while ((i < len) && (en->ident_cmp(en->addr_inf,ext_level,i,*ident) < 0)) + { + i++; + } + if (i < len) + { + /* add identifier to oidret */ + en->get_objid(en->addr_inf,ext_level,i,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("en->objid[%"U16_F"]==%"S32_F" *ident==%"S32_F"\n",i,ex_id,*ident)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + + if ((ext_level + 1) == en->tree_levels) + { + LWIP_DEBUGF(SNMP_MIB_DEBUG,("leaf node\n")); + /* leaf node */ + if (ex_id > *ident) + { + return (struct mib_node*)en; + } + else if ((i + 1) < len) + { + /* ex_id == *ident */ + en->get_objid(en->addr_inf,ext_level,i + 1,&ex_id); + (oidret->len)--; + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + return (struct mib_node*)en; + } + else + { + /* (i + 1) == len */ + (oidret->len)--; + climb_tree = 1; + } + } + else + { + u16_t j; + + LWIP_DEBUGF(SNMP_MIB_DEBUG,("non-leaf node\n")); + /* non-leaf, store right child ptr and id */ + LWIP_ASSERT("i < 0xff", i < 0xff); + j = i + 1; + if (j < len) + { + struct nse cur_node; + /* right node is the current external node */ + cur_node.r_ptr = node; + en->get_objid(en->addr_inf,ext_level,j,&cur_node.r_id); + cur_node.r_nl = ext_level + 1; + push_node(&cur_node); + } + else + { + push_node(&node_null); + } + if (en->ident_cmp(en->addr_inf,ext_level,i,*ident) == 0) + { + ident_len--; + ident++; + } + else + { + /* external id < *ident */ + ident_len = 0; + } + /* proceed to child */ + ext_level++; + } + } + else + { + /* i == len (en->level_len()) */ + climb_tree = 1; + } + } + else + { + /* ident_len == 0, complete with leftmost '.thing' */ + en->get_objid(en->addr_inf,ext_level,0,&ex_id); + LWIP_DEBUGF(SNMP_MIB_DEBUG,("left en->objid==%"S32_F"\n",ex_id)); + oidret->id[oidret->len] = ex_id; + (oidret->len)++; + if ((ext_level + 1) == en->tree_levels) + { + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("(ext_level + 1) == en->tree_levels\n")); + return (struct mib_node*)en; + } + else + { + /* no leaf, proceed to child */ + ext_level++; + } + } + } + else if(node_type == MIB_NODE_SC) + { + mib_scalar_node *sn; + + /* scalar node */ + sn = (mib_scalar_node *)node; + if (ident_len > 0) + { + /* at .0 */ + climb_tree = 1; + } + else + { + /* ident_len == 0, complete object identifier */ + oidret->id[oidret->len] = 0; + (oidret->len)++; + /* leaf node */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("completed scalar leaf\n")); + return (struct mib_node*)sn; + } + } + else + { + /* unknown/unhandled node_type */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node_type %"U16_F" unkown\n",(u16_t)node_type)); + return NULL; + } + + if (climb_tree) + { + struct nse child; + + /* find right child ptr */ + child.r_ptr = NULL; + child.r_id = 0; + child.r_nl = 0; + while ((node_stack_cnt > 0) && (child.r_ptr == NULL)) + { + pop_node(&child); + /* trim returned oid */ + (oidret->len)--; + } + if (child.r_ptr != NULL) + { + /* incoming ident is useless beyond this point */ + ident_len = 0; + oidret->id[oidret->len] = child.r_id; + oidret->len++; + node = child.r_ptr; + ext_level = child.r_nl; + } + else + { + /* tree ends here ... */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed, tree ends here\n")); + return NULL; + } + } + } + /* done, found nothing */ + LWIP_DEBUGF(SNMP_MIB_DEBUG,("expand failed node==%p\n",(void*)node)); + return NULL; +} + +/** + * Test object identifier for the iso.org.dod.internet prefix. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @return 1 if it matches, 0 otherwise + */ +u8_t +snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident) +{ + if ((ident_len > 3) && + (ident[0] == 1) && (ident[1] == 3) && + (ident[2] == 6) && (ident[3] == 1)) + { + return 1; + } + else + { + return 0; + } +} + +/** + * Expands object identifier to the iso.org.dod.internet + * prefix for use in getnext operation. + * + * @param ident_len the length of the supplied object identifier + * @param ident points to the array of sub identifiers + * @param oidret points to returned expanded object identifier + * @return 1 if it matches, 0 otherwise + * + * @note ident_len 0 is allowed, expanding to the first known object id!! + */ +u8_t +snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret) +{ + const s32_t *prefix_ptr; + s32_t *ret_ptr; + u8_t i; + + i = 0; + prefix_ptr = &prefix[0]; + ret_ptr = &oidret->id[0]; + ident_len = ((ident_len < 4)?ident_len:4); + while ((i < ident_len) && ((*ident) <= (*prefix_ptr))) + { + *ret_ptr++ = *prefix_ptr++; + ident++; + i++; + } + if (i == ident_len) + { + /* match, complete missing bits */ + while (i < 4) + { + *ret_ptr++ = *prefix_ptr++; + i++; + } + oidret->len = i; + return 1; + } + else + { + /* i != ident_len */ + return 0; + } +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_in.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_in.c new file mode 100644 index 0000000..da9b78c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_in.c @@ -0,0 +1,1463 @@ +/** + * @file + * SNMP input message processing (RFC1157). + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/memp.h" +#include "lwip/udp.h" +#include "lwip/stats.h" + +#include + +/* public (non-static) constants */ +/** SNMP v1 == 0 */ +const s32_t snmp_version = 0; +/** default SNMP community string */ +const char snmp_publiccommunity[7] = "public"; + +/* statically allocated buffers for SNMP_CONCURRENT_REQUESTS */ +struct snmp_msg_pstat msg_input_list[SNMP_CONCURRENT_REQUESTS]; +/* UDP Protocol Control Block */ +struct udp_pcb *snmp1_pcb; + +static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port); +static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); +static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat); + + +/** + * Starts SNMP Agent. + * Allocates UDP pcb and binds it to IP_ADDR_ANY port 161. + */ +void +snmp_init(void) +{ + struct snmp_msg_pstat *msg_ps; + u8_t i; + + snmp1_pcb = udp_new(); + if (snmp1_pcb != NULL) + { + udp_recv(snmp1_pcb, snmp_recv, (void *)SNMP_IN_PORT); + udp_bind(snmp1_pcb, IP_ADDR_ANY, SNMP_IN_PORT); + } + msg_ps = &msg_input_list[0]; + for (i=0; istate = SNMP_MSG_EMPTY; + msg_ps->error_index = 0; + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps++; + } + trap_msg.pcb = snmp1_pcb; + +#ifdef SNMP_PRIVATE_MIB_INIT + /* If defined, this must be a function-like define to initialize the + * private MIB after the stack has been initialized. + * The private MIB can also be initialized in tcpip_callback (or after + * the stack is initialized), this define is only for convenience. */ + SNMP_PRIVATE_MIB_INIT(); +#endif /* SNMP_PRIVATE_MIB_INIT */ + + /* The coldstart trap will only be output + if our outgoing interface is up & configured */ + snmp_coldstart_trap(); +} + +static void +snmp_error_response(struct snmp_msg_pstat *msg_ps, u8_t error) +{ + /* move names back from outvb to invb */ + int v; + struct snmp_varbind *vbi = msg_ps->invb.head; + struct snmp_varbind *vbo = msg_ps->outvb.head; + for (v=0; vvb_idx; v++) { + if (vbi->ident != NULL) { + /* free previously allocated value before overwriting the pointer */ + memp_free(MEMP_SNMP_VALUE, vbi->ident); + } + vbi->ident_len = vbo->ident_len; + vbo->ident_len = 0; + vbi->ident = vbo->ident; + vbo->ident = NULL; + vbi = vbi->next; + vbo = vbo->next; + } + /* free outvb */ + snmp_varbind_list_free(&msg_ps->outvb); + /* we send invb back */ + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + msg_ps->error_status = error; + /* error index must be 0 for error too big */ + msg_ps->error_index = (error != SNMP_ES_TOOBIG) ? (1 + msg_ps->vb_idx) : 0; + snmp_send_response(msg_ps); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +static void +snmp_ok_response(struct snmp_msg_pstat *msg_ps) +{ + err_t err_ret; + + err_ret = snmp_send_response(msg_ps); + if (err_ret == ERR_MEM) + { + /* serious memory problem, can't return tooBig */ + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event = %"S32_F"\n",msg_ps->error_status)); + } + /* free varbinds (if available) */ + snmp_varbind_list_free(&msg_ps->invb); + snmp_varbind_list_free(&msg_ps->outvb); + msg_ps->state = SNMP_MSG_EMPTY; +} + +/** + * Service an internal or external event for SNMP GET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the associated message process state + */ +static void +snmp_msg_get_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_get_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if ((msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) && + (msg_ps->ext_object_def.access & MIB_ACCESS_READ)) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + /* allocate output varbind */ + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is referenced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = msg_ps->ext_object_def.asn_type; + LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); + vb->value_len = (u8_t)msg_ps->ext_object_def.v_len; + if (vb->value_len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + memp_free(MEMP_SNMP_VARBIND, vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + en->get_value_a(request_id, &msg_ps->ext_object_def, 0, NULL); + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + /* search again (if vb_idx < msg_ps->invb.count) */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: no outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if ((object_def.instance != MIB_OBJECT_NONE) && + (object_def.access & MIB_ACCESS_READ)) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + /* allocate output varbind */ + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + vb->next = NULL; + vb->prev = NULL; + + /* move name from invb to outvb */ + vb->ident = msg_ps->vb_ptr->ident; + vb->ident_len = msg_ps->vb_ptr->ident_len; + /* ensure this memory is referenced once only */ + msg_ps->vb_ptr->ident = NULL; + msg_ps->vb_ptr->ident_len = 0; + + vb->value_type = object_def.asn_type; + LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); + vb->value_len = (u8_t)object_def.v_len; + if (vb->value_len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", + vb->value_len <= SNMP_MAX_VALUE_SIZE); + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value != NULL) + { + mn->get_value(&object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate variable space\n")); + msg_ps->vb_ptr->ident = vb->ident; + msg_ps->vb_ptr->ident_len = vb->ident_len; + vb->ident = NULL; + vb->ident_len = 0; + memp_free(MEMP_SNMP_VARBIND, vb); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + else + { + /* vb->value_len == 0, empty value (e.g. empty string) */ + vb->value = NULL; + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP GETNEXT. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the associated message process state + */ +static void +snmp_msg_getnext_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1], &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_GET_VALUE; + en->get_value_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, 1, &msg_ps->ext_oid.id[msg_ps->ext_oid.len - 1]); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_VALUE) + { + struct mib_external_node *en; + struct snmp_varbind *vb; + + /* get_value() answer */ + en = msg_ps->ext_mib_node; + + LWIP_ASSERT("invalid length", msg_ps->ext_object_def.v_len <= 0xff); + vb = snmp_varbind_alloc(&msg_ps->ext_oid, + msg_ps->ext_object_def.asn_type, + (u8_t)msg_ps->ext_object_def.v_len); + if (vb != NULL) + { + en->get_value_a(request_id, &msg_ps->ext_object_def, vb->value_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->get_value_pc(request_id, &msg_ps->ext_object_def); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_getnext_event: couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_obj_id oid; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + if (snmp_iso_prefix_expand(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident, &oid)) + { + if (msg_ps->vb_ptr->ident_len > 3) + { + /* can offset ident_len and ident */ + mn = snmp_expand_tree((struct mib_node*)&internet, + msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &oid); + } + else + { + /* can't offset ident_len -4, ident + 4 */ + mn = snmp_expand_tree((struct mib_node*)&internet, 0, NULL, &oid); + } + } + else + { + mn = NULL; + } + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_oid = oid; + + en->get_object_def_q(en->addr_inf, request_id, 1, &oid.id[oid.len - 1]); + } + else + { + /* internal object */ + struct obj_def object_def; + struct snmp_varbind *vb; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(1, &oid.id[oid.len - 1], &object_def); + + LWIP_ASSERT("invalid length", object_def.v_len <= 0xff); + vb = snmp_varbind_alloc(&oid, object_def.asn_type, (u8_t)object_def.v_len); + if (vb != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_GET_VALUE; + mn->get_value(&object_def, object_def.v_len, vb->value); + snmp_varbind_tail_add(&msg_ps->outvb, vb); + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv couldn't allocate outvb space\n")); + snmp_error_response(msg_ps,SNMP_ES_TOOBIG); + } + } + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + snmp_ok_response(msg_ps); + } +} + +/** + * Service an internal or external event for SNMP SET. + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + * @param msg_ps points to the associated message process state + */ +static void +snmp_msg_set_event(u8_t request_id, struct snmp_msg_pstat *msg_ps) +{ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_msg_set_event: msg_ps->state==%"U16_F"\n",(u16_t)msg_ps->state)); + + if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_TEST; + en->set_test_q(request_id, &msg_ps->ext_object_def); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* search failed, object id points to unknown object (nosuchname) */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_TEST) + { + struct mib_external_node *en; + + /* set_test() answer*/ + en = msg_ps->ext_mib_node; + + if (msg_ps->ext_object_def.access & MIB_ACCESS_WRITE) + { + if ((msg_ps->ext_object_def.asn_type == msg_ps->vb_ptr->value_type) && + (en->set_test_a(request_id,&msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + en->set_test_pc(request_id,&msg_ps->ext_object_def); + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_GET_OBJDEF_S) + { + struct mib_external_node *en; + struct snmp_name_ptr np; + + /* get_object_def() answer*/ + en = msg_ps->ext_mib_node; + np = msg_ps->ext_name_ptr; + + /* translate answer into a known lifeform */ + en->get_object_def_a(request_id, np.ident_len, np.ident, &msg_ps->ext_object_def); + if (msg_ps->ext_object_def.instance != MIB_OBJECT_NONE) + { + msg_ps->state = SNMP_MSG_EXTERNAL_SET_VALUE; + en->set_value_q(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + } + else + { + en->get_object_def_pc(request_id, np.ident_len, np.ident); + /* set_value failed, object has disappeared for some odd reason?? */ + snmp_error_response(msg_ps,SNMP_ES_GENERROR); + } + } + else if (msg_ps->state == SNMP_MSG_EXTERNAL_SET_VALUE) + { + struct mib_external_node *en; + + /** set_value_a() */ + en = msg_ps->ext_mib_node; + en->set_value_a(request_id, &msg_ps->ext_object_def, + msg_ps->vb_ptr->value_len, msg_ps->vb_ptr->value); + + /** @todo use set_value_pc() if toobig */ + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + msg_ps->vb_idx += 1; + } + + /* test all values before setting */ + while ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /** test object identifier for .iso.org.dod.internet prefix */ + if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len, msg_ps->vb_ptr->ident)) + { + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF; + mn->get_object_def(np.ident_len, np.ident, &object_def); + if (object_def.instance != MIB_OBJECT_NONE) + { + mn = mn; + } + else + { + /* search failed, object id points to unknown object (nosuchname) */ + mn = NULL; + } + if (mn != NULL) + { + msg_ps->state = SNMP_MSG_INTERNAL_SET_TEST; + + if (object_def.access & MIB_ACCESS_WRITE) + { + if ((object_def.asn_type == msg_ps->vb_ptr->value_type) && + (mn->set_test(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value) != 0)) + { + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + msg_ps->vb_idx += 1; + } + else + { + /* bad value */ + snmp_error_response(msg_ps,SNMP_ES_BADVALUE); + } + } + else + { + /* object not available for set */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + } + } + } + else + { + mn = NULL; + } + if (mn == NULL) + { + /* mn == NULL, noSuchName */ + snmp_error_response(msg_ps,SNMP_ES_NOSUCHNAME); + } + } + + if ((msg_ps->state == SNMP_MSG_SEARCH_OBJ) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + msg_ps->vb_idx = 0; + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + } + + /* set all values "atomically" (be as "atomic" as possible) */ + while ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx < msg_ps->invb.count)) + { + struct mib_node *mn; + struct snmp_name_ptr np; + + if (msg_ps->vb_idx == 0) + { + msg_ps->vb_ptr = msg_ps->invb.head; + } + else + { + msg_ps->vb_ptr = msg_ps->vb_ptr->next; + } + /* skip iso prefix test, was done previously while settesting() */ + mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4, + msg_ps->vb_ptr->ident + 4, &np); + /* check if object is still available + (e.g. external hot-plug thingy present?) */ + if (mn != NULL) + { + if (mn->node_type == MIB_NODE_EX) + { + /* external object */ + struct mib_external_node *en = (struct mib_external_node*)mn; + + msg_ps->state = SNMP_MSG_EXTERNAL_GET_OBJDEF_S; + /* save en && args in msg_ps!! */ + msg_ps->ext_mib_node = en; + msg_ps->ext_name_ptr = np; + + en->get_object_def_q(en->addr_inf, request_id, np.ident_len, np.ident); + } + else + { + /* internal object */ + struct obj_def object_def; + + msg_ps->state = SNMP_MSG_INTERNAL_GET_OBJDEF_S; + mn->get_object_def(np.ident_len, np.ident, &object_def); + msg_ps->state = SNMP_MSG_INTERNAL_SET_VALUE; + mn->set_value(&object_def,msg_ps->vb_ptr->value_len,msg_ps->vb_ptr->value); + msg_ps->vb_idx += 1; + } + } + } + if ((msg_ps->state == SNMP_MSG_INTERNAL_SET_VALUE) && + (msg_ps->vb_idx == msg_ps->invb.count)) + { + /* simply echo the input if we can set it + @todo do we need to return the actual value? + e.g. if value is silently modified or behaves sticky? */ + msg_ps->outvb = msg_ps->invb; + msg_ps->invb.head = NULL; + msg_ps->invb.tail = NULL; + msg_ps->invb.count = 0; + snmp_ok_response(msg_ps); + } +} + + +/** + * Handle one internal or external event. + * Called for one async event. (recv external/private answer) + * + * @param request_id identifies requests from 0 to (SNMP_CONCURRENT_REQUESTS-1) + */ +void +snmp_msg_event(u8_t request_id) +{ + struct snmp_msg_pstat *msg_ps; + + if (request_id < SNMP_CONCURRENT_REQUESTS) + { + msg_ps = &msg_input_list[request_id]; + if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ) + { + snmp_msg_getnext_event(request_id, msg_ps); + } + else if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ) + { + snmp_msg_get_event(request_id, msg_ps); + } + else if(msg_ps->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_msg_set_event(request_id, msg_ps); + } + } +} + + +/* lwIP UDP receive callback function */ +static void +snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + struct snmp_msg_pstat *msg_ps; + u8_t req_idx; + err_t err_ret; + u16_t payload_len = p->tot_len; + u16_t payload_ofs = 0; + u16_t varbind_ofs = 0; + + /* suppress unused argument warning */ + LWIP_UNUSED_ARG(arg); + + /* traverse input message process list, look for SNMP_MSG_EMPTY */ + msg_ps = &msg_input_list[0]; + req_idx = 0; + while ((req_idx < SNMP_CONCURRENT_REQUESTS) && (msg_ps->state != SNMP_MSG_EMPTY)) + { + req_idx++; + msg_ps++; + } + if (req_idx == SNMP_CONCURRENT_REQUESTS) + { + /* exceeding number of concurrent requests */ + pbuf_free(p); + return; + } + + /* accepting request */ + snmp_inc_snmpinpkts(); + /* record used 'protocol control block' */ + msg_ps->pcb = pcb; + /* source address (network order) */ + msg_ps->sip = *addr; + /* source port (host order (lwIP oddity)) */ + msg_ps->sp = port; + + /* check total length, version, community, pdu type */ + err_ret = snmp_pdu_header_check(p, payload_ofs, payload_len, &varbind_ofs, msg_ps); + /* Only accept requests and requests without error (be robust) */ + /* Reject response and trap headers or error requests as input! */ + if ((err_ret != ERR_OK) || + ((msg_ps->rt != SNMP_ASN1_PDU_GET_REQ) && + (msg_ps->rt != SNMP_ASN1_PDU_GET_NEXT_REQ) && + (msg_ps->rt != SNMP_ASN1_PDU_SET_REQ)) || + ((msg_ps->error_status != SNMP_ES_NOERROR) || + (msg_ps->error_index != 0)) ) + { + /* header check failed drop request silently, do not return error! */ + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check() failed\n")); + return; + } + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv ok, community %s\n", msg_ps->community)); + + /* Builds a list of variable bindings. Copy the varbinds from the pbuf + chain to glue them when these are divided over two or more pbuf's. */ + err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps); + /* we've decoded the incoming message, release input msg now */ + pbuf_free(p); + if ((err_ret != ERR_OK) || (msg_ps->invb.count == 0)) + { + /* varbind-list decode failed, or varbind list empty. + drop request silently, do not return error! + (errors are only returned for a specific varbind failure) */ + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed\n")); + return; + } + + msg_ps->error_status = SNMP_ES_NOERROR; + msg_ps->error_index = 0; + /* find object for each variable binding */ + msg_ps->state = SNMP_MSG_SEARCH_OBJ; + /* first variable binding from list to inspect */ + msg_ps->vb_idx = 0; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv varbind cnt=%"U16_F"\n",(u16_t)msg_ps->invb.count)); + + /* handle input event and as much objects as possible in one go */ + snmp_msg_event(req_idx); +} + +/** + * Checks and decodes incoming SNMP message header, logs header errors. + * + * @param p points to pbuf chain of SNMP message (UDP payload) + * @param ofs points to first octet of SNMP message + * @param pdu_len the length of the UDP payload + * @param ofs_ret returns the ofset of the variable bindings + * @param m_stat points to the current message request state return + * @return + * - ERR_OK SNMP header is sane and accepted + * - ERR_ARG SNMP header is either malformed or rejected + */ +static err_t +snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, ofs_base; + u8_t len_octets; + u8_t type; + s32_t version; + + ofs_base = ofs; + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (pdu_len != (1 + len_octets + len)) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (version) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &version); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + if (version != 0) + { + /* not version 1 */ + snmp_inc_snmpinbadversions(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR))) + { + /* can't decode or no octet string (community) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, SNMP_COMMUNITY_STR_LEN, m_stat->community); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* add zero terminator */ + len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN)); + m_stat->community[len] = 0; + m_stat->com_strlen = (u8_t)len; + if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0) + { + /** @todo: move this if we need to check more names */ + snmp_inc_snmpinbadcommunitynames(); + snmp_authfail_trap(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch(type) + { + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_REQ): + /* GetRequest PDU */ + snmp_inc_snmpingetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_NEXT_REQ): + /* GetNextRequest PDU */ + snmp_inc_snmpingetnexts(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP): + /* GetResponse PDU */ + snmp_inc_snmpingetresponses(); + derr = ERR_ARG; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_SET_REQ): + /* SetRequest PDU */ + snmp_inc_snmpinsetrequests(); + derr = ERR_OK; + break; + case (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP): + /* Trap PDU */ + snmp_inc_snmpintraps(); + derr = ERR_ARG; + break; + default: + snmp_inc_snmpinasnparseerrs(); + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + /* unsupported input PDU for this agent (no parse error) */ + return ERR_ARG; + } + m_stat->rt = type & 0x1F; + ofs += (1 + len_octets); + if (len != (pdu_len - (ofs - ofs_base))) + { + /* decoded PDU length does not equal actual payload length */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (request ID) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->rid); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-status) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be noError (0) for incoming requests. + log errors for mib-2 completeness and for debug purposes */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_status); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + switch (m_stat->error_status) + { + case SNMP_ES_NOERROR: + /* nothing to do */ + break; + case SNMP_ES_TOOBIG: + snmp_inc_snmpintoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpinnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpinbadvalues(); + break; + case SNMP_ES_READONLY: + snmp_inc_snmpinreadonlys(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpingenerrs(); + break; + default: + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_header_check(): unknown error_status: %d\n", (int)m_stat->error_status)); + break; + } + ofs += (1 + len_octets + len); + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG))) + { + /* can't decode or no integer (error-index) */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + /* must be 0 for incoming requests. + decode anyway to catch bad integers (and dirty tricks) */ + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, &m_stat->error_index); + if (derr != ERR_OK) + { + /* can't decode */ + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + *ofs_ret = ofs; + return ERR_OK; +} + +static err_t +snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat) +{ + err_t derr; + u16_t len, vb_len; + u8_t len_octets; + u8_t type; + + /* variable binding list */ + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &vb_len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ))) + { + snmp_inc_snmpinasnparseerrs(); + return ERR_ARG; + } + ofs += (1 + len_octets); + + /* start with empty list */ + m_stat->invb.count = 0; + m_stat->invb.head = NULL; + m_stat->invb.tail = NULL; + + while (vb_len > 0) + { + struct snmp_obj_id oid, oid_value; + struct snmp_varbind *vb; + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || + (type != (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)) || + (len == 0) || (len > vb_len)) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets); + vb_len -= (1 + len_octets); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID))) + { + /* can't decode object name length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid); + if (derr != ERR_OK) + { + /* can't decode object name */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + + snmp_asn1_dec_type(p, ofs, &type); + derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len); + if (derr != ERR_OK) + { + /* can't decode object value length */ + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + + switch (type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + vb = snmp_varbind_alloc(&oid, type, sizeof(s32_t)); + if (vb != NULL) + { + s32_t *vptr = (s32_t*)vb->value; + + derr = snmp_asn1_dec_s32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + vb = snmp_varbind_alloc(&oid, type, sizeof(u32_t)); + if (vb != NULL) + { + u32_t *vptr = (u32_t*)vb->value; + + derr = snmp_asn1_dec_u32t(p, ofs + 1 + len_octets, len, vptr); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + LWIP_ASSERT("invalid length", len <= 0xff); + vb = snmp_varbind_alloc(&oid, type, (u8_t)len); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + vb = snmp_varbind_alloc(&oid, type, 0); + if (vb != NULL) + { + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + derr = snmp_asn1_dec_oid(p, ofs + 1 + len_octets, len, &oid_value); + if (derr == ERR_OK) + { + vb = snmp_varbind_alloc(&oid, type, oid_value.len * sizeof(s32_t)); + if (vb != NULL) + { + u8_t i = oid_value.len; + s32_t *vptr = (s32_t*)vb->value; + + while(i > 0) + { + i--; + vptr[i] = oid_value.id[i]; + } + snmp_varbind_tail_add(&m_stat->invb, vb); + derr = ERR_OK; + } + else + { + derr = ERR_ARG; + } + } + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + if (len == 4) + { + /* must be exactly 4 octets! */ + vb = snmp_varbind_alloc(&oid, type, 4); + if (vb != NULL) + { + derr = snmp_asn1_dec_raw(p, ofs + 1 + len_octets, len, vb->value_len, (u8_t*)vb->value); + snmp_varbind_tail_add(&m_stat->invb, vb); + } + else + { + derr = ERR_ARG; + } + } + else + { + derr = ERR_ARG; + } + break; + default: + derr = ERR_ARG; + break; + } + if (derr != ERR_OK) + { + snmp_inc_snmpinasnparseerrs(); + /* free varbinds (if available) */ + snmp_varbind_list_free(&m_stat->invb); + return ERR_ARG; + } + ofs += (1 + len_octets + len); + vb_len -= (1 + len_octets + len); + } + + if (m_stat->rt == SNMP_ASN1_PDU_SET_REQ) + { + snmp_add_snmpintotalsetvars(m_stat->invb.count); + } + else + { + snmp_add_snmpintotalreqvars(m_stat->invb.count); + } + + *ofs_ret = ofs; + return ERR_OK; +} + +struct snmp_varbind* +snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len) +{ + struct snmp_varbind *vb; + + vb = (struct snmp_varbind *)memp_malloc(MEMP_SNMP_VARBIND); + if (vb != NULL) + { + u8_t i; + + vb->next = NULL; + vb->prev = NULL; + i = oid->len; + vb->ident_len = i; + if (i > 0) + { + LWIP_ASSERT("SNMP_MAX_TREE_DEPTH is configured too low", i <= SNMP_MAX_TREE_DEPTH); + /* allocate array of s32_t for our object identifier */ + vb->ident = (s32_t*)memp_malloc(MEMP_SNMP_VALUE); + if (vb->ident == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate ident value space\n")); + memp_free(MEMP_SNMP_VARBIND, vb); + return NULL; + } + while(i > 0) + { + i--; + vb->ident[i] = oid->id[i]; + } + } + else + { + /* i == 0, pass zero length object identifier */ + vb->ident = NULL; + } + vb->value_type = type; + vb->value_len = len; + if (len > 0) + { + LWIP_ASSERT("SNMP_MAX_OCTET_STRING_LEN is configured too low", vb->value_len <= SNMP_MAX_VALUE_SIZE); + /* allocate raw bytes for our object value */ + vb->value = memp_malloc(MEMP_SNMP_VALUE); + if (vb->value == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate value space\n")); + if (vb->ident != NULL) + { + memp_free(MEMP_SNMP_VALUE, vb->ident); + } + memp_free(MEMP_SNMP_VARBIND, vb); + return NULL; + } + } + else + { + /* ASN1_NUL type, or zero length ASN1_OC_STR */ + vb->value = NULL; + } + } + else + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_varbind_alloc: couldn't allocate varbind space\n")); + } + return vb; +} + +void +snmp_varbind_free(struct snmp_varbind *vb) +{ + if (vb->value != NULL ) + { + memp_free(MEMP_SNMP_VALUE, vb->value); + } + if (vb->ident != NULL ) + { + memp_free(MEMP_SNMP_VALUE, vb->ident); + } + memp_free(MEMP_SNMP_VARBIND, vb); +} + +void +snmp_varbind_list_free(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb, *prev; + + vb = root->tail; + while ( vb != NULL ) + { + prev = vb->prev; + snmp_varbind_free(vb); + vb = prev; + } + root->count = 0; + root->head = NULL; + root->tail = NULL; +} + +void +snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb) +{ + if (root->count == 0) + { + /* add first varbind to list */ + root->head = vb; + root->tail = vb; + } + else + { + /* add nth varbind to list tail */ + root->tail->next = vb; + vb->prev = root->tail; + root->tail = vb; + } + root->count += 1; +} + +struct snmp_varbind* +snmp_varbind_tail_remove(struct snmp_varbind_root *root) +{ + struct snmp_varbind* vb; + + if (root->count > 0) + { + /* remove tail varbind */ + vb = root->tail; + root->tail = vb->prev; + vb->prev->next = NULL; + root->count -= 1; + } + else + { + /* nothing to remove */ + vb = NULL; + } + return vb; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_out.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_out.c new file mode 100644 index 0000000..ecc524c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/snmp/msg_out.c @@ -0,0 +1,684 @@ +/** + * @file + * SNMP output message processing (RFC1157). + * + * Output responses and traps are build in two passes: + * + * Pass 0: iterate over the output message backwards to determine encoding lengths + * Pass 1: the actual forward encoding of internal form into ASN1 + * + * The single-pass encoding method described by Comer & Stevens + * requires extra buffer space and copying for reversal of the packet. + * The buffer requirement can be prohibitively large for big payloads + * (>= 484) therefore we use the two encoding passes. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/netif.h" +#include "lwip/snmp.h" +#include "lwip/snmp_asn1.h" +#include "lwip/snmp_msg.h" + +struct snmp_trap_dst +{ + /* destination IP address in network order */ + ip_addr_t dip; + /* set to 0 when disabled, >0 when enabled */ + u8_t enable; +}; +struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; + +/** TRAP message structure */ +struct snmp_msg_trap trap_msg; + +static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len); +static u16_t snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len); +static u16_t snmp_varbind_list_sum(struct snmp_varbind_root *root); + +static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p); +static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p); +static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs); + +/** + * Sets enable switch for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param enable switch if 0 destination is disabled >0 enabled. + */ +void +snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + trap_dst[dst_idx].enable = enable; + } +} + +/** + * Sets IPv4 address for this trap destination. + * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 + * @param dst IPv4 address in host order. + */ +void +snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst) +{ + if (dst_idx < SNMP_TRAP_DESTINATIONS) + { + ip_addr_set(&trap_dst[dst_idx].dip, dst); + } +} + +/** + * Sends a 'getresponse' message to the request originator. + * + * @param m_stat points to the current message request state source + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the m_stat + * and provide error-status and index (except for tooBig errors) ... + */ +err_t +snmp_send_response(struct snmp_msg_pstat *m_stat) +{ + struct snmp_varbind_root emptyvb = {NULL, NULL, 0, 0, 0}; + struct pbuf *p; + u16_t tot_len; + err_t err; + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&m_stat->outvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + + /* try allocating pbuf(s) for complete response */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p == NULL) + { + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() tooBig\n")); + + /* can't construct reply, return error-status tooBig */ + m_stat->error_status = SNMP_ES_TOOBIG; + m_stat->error_index = 0; + /* pass 0, recalculate lengths, for empty varbind-list */ + tot_len = snmp_varbind_list_sum(&emptyvb); + tot_len = snmp_resp_header_sum(m_stat, tot_len); + /* retry allocation once for header and empty varbind-list */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + } + if (p != NULL) + { + /* first pbuf alloc try or retry alloc success */ + u16_t ofs; + + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() p != NULL\n")); + + /* pass 1, size error, encode packet ino the pbuf(s) */ + ofs = snmp_resp_header_enc(m_stat, p); + snmp_varbind_list_enc(&m_stat->outvb, p, ofs); + + switch (m_stat->error_status) + { + case SNMP_ES_NOERROR: + /* nothing to do */ + break; + case SNMP_ES_TOOBIG: + snmp_inc_snmpouttoobigs(); + break; + case SNMP_ES_NOSUCHNAME: + snmp_inc_snmpoutnosuchnames(); + break; + case SNMP_ES_BADVALUE: + snmp_inc_snmpoutbadvalues(); + break; + case SNMP_ES_GENERROR: + snmp_inc_snmpoutgenerrs(); + break; + default: + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_send_response(): unknown error_status: %d\n", (int)m_stat->error_status)); + break; + } + snmp_inc_snmpoutgetresponses(); + snmp_inc_snmpoutpkts(); + + /** @todo do we need separate rx and tx pcbs for threaded case? */ + /** connect to the originating source */ + udp_connect(m_stat->pcb, &m_stat->sip, m_stat->sp); + err = udp_send(m_stat->pcb, p); + if (err == ERR_MEM) + { + /** @todo release some memory, retry and return tooBig? tooMuchHassle? */ + err = ERR_MEM; + } + else + { + err = ERR_OK; + } + /** disassociate remote address and port with this pcb */ + udp_disconnect(m_stat->pcb); + + pbuf_free(p); + LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_snd_response() done\n")); + return err; + } + else + { + /* first pbuf alloc try or retry alloc failed + very low on memory, couldn't return tooBig */ + return ERR_MEM; + } +} + + +/** + * Sends an generic or enterprise specific trap message. + * + * @param generic_trap is the trap code + * @param eoid points to enterprise object identifier + * @param specific_trap used for enterprise traps when generic_trap == 6 + * @return ERR_OK when success, ERR_MEM if we're out of memory + * + * @note the caller is responsible for filling in outvb in the trap_msg + * @note the use of the enterprise identifier field + * is per RFC1215. + * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps + * and .iso.org.dod.internet.private.enterprises.yourenterprise + * (sysObjectID) for specific traps. + */ +err_t +snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap) +{ + struct snmp_trap_dst *td; + struct netif *dst_if; + ip_addr_t dst_ip; + struct pbuf *p; + u16_t i,tot_len; + err_t err = ERR_OK; + + for (i=0, td = &trap_dst[0]; ienable != 0) && !ip_addr_isany(&td->dip)) + { + /* network order trap destination */ + ip_addr_copy(trap_msg.dip, td->dip); + /* lookup current source address for this dst */ + dst_if = ip_route(&td->dip); + if (dst_if != NULL) { + ip_addr_copy(dst_ip, dst_if->ip_addr); + /* @todo: what about IPv6? */ + trap_msg.sip_raw[0] = ip4_addr1(&dst_ip); + trap_msg.sip_raw[1] = ip4_addr2(&dst_ip); + trap_msg.sip_raw[2] = ip4_addr3(&dst_ip); + trap_msg.sip_raw[3] = ip4_addr4(&dst_ip); + trap_msg.gen_trap = generic_trap; + trap_msg.spc_trap = specific_trap; + if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC) + { + /* enterprise-Specific trap */ + trap_msg.enterprise = eoid; + } + else + { + /* generic (MIB-II) trap */ + snmp_get_snmpgrpid_ptr(&trap_msg.enterprise); + } + snmp_get_sysuptime(&trap_msg.ts); + + /* pass 0, calculate length fields */ + tot_len = snmp_varbind_list_sum(&trap_msg.outvb); + tot_len = snmp_trap_header_sum(&trap_msg, tot_len); + + /* allocate pbuf(s) */ + p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL); + if (p != NULL) + { + u16_t ofs; + + /* pass 1, encode packet ino the pbuf(s) */ + ofs = snmp_trap_header_enc(&trap_msg, p); + snmp_varbind_list_enc(&trap_msg.outvb, p, ofs); + + snmp_inc_snmpouttraps(); + snmp_inc_snmpoutpkts(); + + /** send to the TRAP destination */ + udp_sendto(trap_msg.pcb, p, &trap_msg.dip, SNMP_TRAP_PORT); + + pbuf_free(p); + } else { + err = ERR_MEM; + } + } else { + /* routing error */ + err = ERR_RTE; + } + } + } + return err; +} + +void +snmp_coldstart_trap(void) +{ + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_COLDSTART, NULL, 0); +} + +void +snmp_authfail_trap(void) +{ + u8_t enable; + snmp_get_snmpenableauthentraps(&enable); + if (enable == 1) + { + trap_msg.outvb.head = NULL; + trap_msg.outvb.tail = NULL; + trap_msg.outvb.count = 0; + snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, NULL, 0); + } +} + +/** + * Sums response header field lengths from tail to head and + * returns resp_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param rhl points to returned header lengths + * @return the required length for encoding the response header + */ +static u16_t +snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_resp_header_lengths *rhl; + + rhl = &m_stat->rhl; + tot_len = vb_len; + snmp_asn1_enc_s32t_cnt(m_stat->error_index, &rhl->erridxlen); + snmp_asn1_enc_length_cnt(rhl->erridxlen, &rhl->erridxlenlen); + tot_len += 1 + rhl->erridxlenlen + rhl->erridxlen; + + snmp_asn1_enc_s32t_cnt(m_stat->error_status, &rhl->errstatlen); + snmp_asn1_enc_length_cnt(rhl->errstatlen, &rhl->errstatlenlen); + tot_len += 1 + rhl->errstatlenlen + rhl->errstatlen; + + snmp_asn1_enc_s32t_cnt(m_stat->rid, &rhl->ridlen); + snmp_asn1_enc_length_cnt(rhl->ridlen, &rhl->ridlenlen); + tot_len += 1 + rhl->ridlenlen + rhl->ridlen; + + rhl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(rhl->pdulen, &rhl->pdulenlen); + tot_len += 1 + rhl->pdulenlen; + + rhl->comlen = m_stat->com_strlen; + snmp_asn1_enc_length_cnt(rhl->comlen, &rhl->comlenlen); + tot_len += 1 + rhl->comlenlen + rhl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &rhl->verlen); + snmp_asn1_enc_length_cnt(rhl->verlen, &rhl->verlenlen); + tot_len += 1 + rhl->verlen + rhl->verlenlen; + + rhl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(rhl->seqlen, &rhl->seqlenlen); + tot_len += 1 + rhl->seqlenlen; + + return tot_len; +} + +/** + * Sums trap header field lengths from tail to head and + * returns trap_header_lengths for second encoding pass. + * + * @param vb_len varbind-list length + * @param thl points to returned header lengths + * @return the required length for encoding the trap header + */ +static u16_t +snmp_trap_header_sum(struct snmp_msg_trap *m_trap, u16_t vb_len) +{ + u16_t tot_len; + struct snmp_trap_header_lengths *thl; + + thl = &m_trap->thl; + tot_len = vb_len; + + snmp_asn1_enc_u32t_cnt(m_trap->ts, &thl->tslen); + snmp_asn1_enc_length_cnt(thl->tslen, &thl->tslenlen); + tot_len += 1 + thl->tslen + thl->tslenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->spc_trap, &thl->strplen); + snmp_asn1_enc_length_cnt(thl->strplen, &thl->strplenlen); + tot_len += 1 + thl->strplen + thl->strplenlen; + + snmp_asn1_enc_s32t_cnt(m_trap->gen_trap, &thl->gtrplen); + snmp_asn1_enc_length_cnt(thl->gtrplen, &thl->gtrplenlen); + tot_len += 1 + thl->gtrplen + thl->gtrplenlen; + + thl->aaddrlen = 4; + snmp_asn1_enc_length_cnt(thl->aaddrlen, &thl->aaddrlenlen); + tot_len += 1 + thl->aaddrlen + thl->aaddrlenlen; + + snmp_asn1_enc_oid_cnt(m_trap->enterprise->len, &m_trap->enterprise->id[0], &thl->eidlen); + snmp_asn1_enc_length_cnt(thl->eidlen, &thl->eidlenlen); + tot_len += 1 + thl->eidlen + thl->eidlenlen; + + thl->pdulen = tot_len; + snmp_asn1_enc_length_cnt(thl->pdulen, &thl->pdulenlen); + tot_len += 1 + thl->pdulenlen; + + thl->comlen = sizeof(snmp_publiccommunity) - 1; + snmp_asn1_enc_length_cnt(thl->comlen, &thl->comlenlen); + tot_len += 1 + thl->comlenlen + thl->comlen; + + snmp_asn1_enc_s32t_cnt(snmp_version, &thl->verlen); + snmp_asn1_enc_length_cnt(thl->verlen, &thl->verlenlen); + tot_len += 1 + thl->verlen + thl->verlenlen; + + thl->seqlen = tot_len; + snmp_asn1_enc_length_cnt(thl->seqlen, &thl->seqlenlen); + tot_len += 1 + thl->seqlenlen; + + return tot_len; +} + +/** + * Sums varbind lengths from tail to head and + * annotates lengths in varbind for second encoding pass. + * + * @param root points to the root of the variable binding list + * @return the required length for encoding the variable bindings + */ +static u16_t +snmp_varbind_list_sum(struct snmp_varbind_root *root) +{ + struct snmp_varbind *vb; + u32_t *uint_ptr; + s32_t *sint_ptr; + u16_t tot_len; + + tot_len = 0; + vb = root->tail; + while ( vb != NULL ) + { + /* encoded value lenght depends on type */ + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_s32t_cnt(*sint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = (u32_t*)vb->value; + snmp_asn1_enc_u32t_cnt(*uint_ptr, &vb->vlen); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + vb->vlen = vb->value_len; + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_oid_cnt(vb->value_len / sizeof(s32_t), sint_ptr, &vb->vlen); + break; + default: + /* unsupported type */ + vb->vlen = 0; + break; + }; + /* encoding length of value length field */ + snmp_asn1_enc_length_cnt(vb->vlen, &vb->vlenlen); + snmp_asn1_enc_oid_cnt(vb->ident_len, vb->ident, &vb->olen); + snmp_asn1_enc_length_cnt(vb->olen, &vb->olenlen); + + vb->seqlen = 1 + vb->vlenlen + vb->vlen; + vb->seqlen += 1 + vb->olenlen + vb->olen; + snmp_asn1_enc_length_cnt(vb->seqlen, &vb->seqlenlen); + + /* varbind seq */ + tot_len += 1 + vb->seqlenlen + vb->seqlen; + + vb = vb->prev; + } + + /* varbind-list seq */ + root->seqlen = tot_len; + snmp_asn1_enc_length_cnt(root->seqlen, &root->seqlenlen); + tot_len += 1 + root->seqlenlen; + + return tot_len; +} + +/** + * Encodes response header from head to tail. + */ +static u16_t +snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.seqlen); + ofs += m_stat->rhl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.verlen); + ofs += m_stat->rhl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.verlen, snmp_version); + ofs += m_stat->rhl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.comlen); + ofs += m_stat->rhl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_stat->rhl.comlen, m_stat->community); + ofs += m_stat->rhl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_GET_RESP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.pdulen); + ofs += m_stat->rhl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.ridlen); + ofs += m_stat->rhl.ridlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.ridlen, m_stat->rid); + ofs += m_stat->rhl.ridlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.errstatlen); + ofs += m_stat->rhl.errstatlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.errstatlen, m_stat->error_status); + ofs += m_stat->rhl.errstatlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_stat->rhl.erridxlen); + ofs += m_stat->rhl.erridxlenlen; + snmp_asn1_enc_s32t(p, ofs, m_stat->rhl.erridxlen, m_stat->error_index); + ofs += m_stat->rhl.erridxlen; + + return ofs; +} + +/** + * Encodes trap header from head to tail. + */ +static u16_t +snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p) +{ + u16_t ofs; + + ofs = 0; + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.seqlen); + ofs += m_trap->thl.seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.verlen); + ofs += m_trap->thl.verlenlen; + snmp_asn1_enc_s32t(p, ofs, m_trap->thl.verlen, snmp_version); + ofs += m_trap->thl.verlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.comlen); + ofs += m_trap->thl.comlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.comlen, (u8_t *)&snmp_publiccommunity[0]); + ofs += m_trap->thl.comlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_CONTXT | SNMP_ASN1_CONSTR | SNMP_ASN1_PDU_TRAP)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.pdulen); + ofs += m_trap->thl.pdulenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.eidlen); + ofs += m_trap->thl.eidlenlen; + snmp_asn1_enc_oid(p, ofs, m_trap->enterprise->len, &m_trap->enterprise->id[0]); + ofs += m_trap->thl.eidlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.aaddrlen); + ofs += m_trap->thl.aaddrlenlen; + snmp_asn1_enc_raw(p, ofs, m_trap->thl.aaddrlen, &m_trap->sip_raw[0]); + ofs += m_trap->thl.aaddrlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.gtrplen); + ofs += m_trap->thl.gtrplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.gtrplen, m_trap->gen_trap); + ofs += m_trap->thl.gtrplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.strplen); + ofs += m_trap->thl.strplenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.strplen, m_trap->spc_trap); + ofs += m_trap->thl.strplen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, m_trap->thl.tslen); + ofs += m_trap->thl.tslenlen; + snmp_asn1_enc_u32t(p, ofs, m_trap->thl.tslen, m_trap->ts); + ofs += m_trap->thl.tslen; + + return ofs; +} + +/** + * Encodes varbind list from head to tail. + */ +static u16_t +snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs) +{ + struct snmp_varbind *vb; + s32_t *sint_ptr; + u32_t *uint_ptr; + u8_t *raw_ptr; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, root->seqlen); + ofs += root->seqlenlen; + + vb = root->head; + while ( vb != NULL ) + { + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_CONSTR | SNMP_ASN1_SEQ)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->seqlen); + ofs += vb->seqlenlen; + + snmp_asn1_enc_type(p, ofs, (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID)); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->olen); + ofs += vb->olenlen; + snmp_asn1_enc_oid(p, ofs, vb->ident_len, &vb->ident[0]); + ofs += vb->olen; + + snmp_asn1_enc_type(p, ofs, vb->value_type); + ofs += 1; + snmp_asn1_enc_length(p, ofs, vb->vlen); + ofs += vb->vlenlen; + + switch (vb->value_type) + { + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_s32t(p, ofs, vb->vlen, *sint_ptr); + break; + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS): + uint_ptr = (u32_t*)vb->value; + snmp_asn1_enc_u32t(p, ofs, vb->vlen, *uint_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR): + case (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_OPAQUE): + raw_ptr = (u8_t*)vb->value; + snmp_asn1_enc_raw(p, ofs, vb->vlen, raw_ptr); + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_NUL): + break; + case (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID): + sint_ptr = (s32_t*)vb->value; + snmp_asn1_enc_oid(p, ofs, vb->value_len / sizeof(s32_t), sint_ptr); + break; + default: + /* unsupported type */ + break; + }; + ofs += vb->vlen; + vb = vb->next; + } + return ofs; +} + +#endif /* LWIP_SNMP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/stats.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/stats.c new file mode 100644 index 0000000..ff97853 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/stats.c @@ -0,0 +1,181 @@ +/** + * @file + * Statistics module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/mem.h" + +#include + +struct stats_ lwip_stats; + +void stats_init(void) +{ +#ifdef LWIP_DEBUG +#if MEMP_STATS + const char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + int i; + for (i = 0; i < MEMP_MAX; i++) { + lwip_stats.memp[i].name = memp_names[i]; + } +#endif /* MEMP_STATS */ +#if MEM_STATS + lwip_stats.mem.name = "MEM"; +#endif /* MEM_STATS */ +#endif /* LWIP_DEBUG */ +} + +#if LWIP_STATS_DISPLAY +void +stats_display_proto(struct stats_proto *proto, const char *name) +{ + LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); + LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); + LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); + LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); + LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); + LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); +} + +#if IGMP_STATS || MLD6_STATS +void +stats_display_igmp(struct stats_igmp *igmp, const char *name) +{ + LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); + LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); + LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); + LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); + LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); + LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); + LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); + LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); + LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); + LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group)); + LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general)); + LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); + LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); + LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); + LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n\t", igmp->tx_report)); +} +#endif /* IGMP_STATS || MLD6_STATS */ + +#if MEM_STATS || MEMP_STATS +void +stats_display_mem(struct stats_mem *mem, const char *name) +{ + LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); + LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); + LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); + LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); + LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); +} + +#if MEMP_STATS +void +stats_display_memp(struct stats_mem *mem, int index) +{ + char * memp_names[] = { +#define LWIP_MEMPOOL(name,num,size,desc) desc, +#include "lwip/memp_std.h" + }; + if(index < MEMP_MAX) { + stats_display_mem(mem, memp_names[index]); + } +} +#endif /* MEMP_STATS */ +#endif /* MEM_STATS || MEMP_STATS */ + +#if SYS_STATS +void +stats_display_sys(struct stats_sys *sys) +{ + LWIP_PLATFORM_DIAG(("\nSYS\n\t")); + LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); + LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); + LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); + LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); + LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max)); + LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err)); + LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); + LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); + LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n\t", (u32_t)sys->mbox.err)); +} +#endif /* SYS_STATS */ + +void +stats_display(void) +{ + s16_t i; + + LINK_STATS_DISPLAY(); + ETHARP_STATS_DISPLAY(); + IPFRAG_STATS_DISPLAY(); + IP6_FRAG_STATS_DISPLAY(); + IP_STATS_DISPLAY(); + ND6_STATS_DISPLAY(); + IP6_STATS_DISPLAY(); + IGMP_STATS_DISPLAY(); + MLD6_STATS_DISPLAY(); + ICMP_STATS_DISPLAY(); + ICMP6_STATS_DISPLAY(); + UDP_STATS_DISPLAY(); + TCP_STATS_DISPLAY(); + MEM_STATS_DISPLAY(); + for (i = 0; i < MEMP_MAX; i++) { + MEMP_STATS_DISPLAY(i); + } + SYS_STATS_DISPLAY(); +} +#endif /* LWIP_STATS_DISPLAY */ + +#endif /* LWIP_STATS */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/sys.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/sys.c new file mode 100644 index 0000000..f177737 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/sys.c @@ -0,0 +1,68 @@ +/** + * @file + * lwIP Operating System abstraction + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#include "lwip/sys.h" + +/* Most of the functions defined in sys.h must be implemented in the + * architecture-dependent file sys_arch.c */ + +#if !NO_SYS + +#ifndef sys_msleep +/** + * Sleep for some ms. Timeouts are NOT processed while sleeping. + * + * @param ms number of milliseconds to sleep + */ +void +sys_msleep(u32_t ms) +{ + if (ms > 0) { + sys_sem_t delaysem; + err_t err = sys_sem_new(&delaysem, 0); + if (err == ERR_OK) { + sys_arch_sem_wait(&delaysem, ms); + sys_sem_free(&delaysem); + } + } +} +#endif /* sys_msleep */ + +#endif /* !NO_SYS */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp.c new file mode 100644 index 0000000..5edc73c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp.c @@ -0,0 +1,1880 @@ +/** + * @file + * Transmission Control Protocol for IP + * + * This file contains common functions for the TCP implementation, such as functinos + * for manipulating the data structures and the TCP timer functions. TCP functions + * related to input and output is found in tcp_in.c and tcp_out.c respectively. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/snmp.h" +#include "lwip/tcp.h" +#include "lwip/tcp_impl.h" +#include "lwip/debug.h" +#include "lwip/stats.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/nd6.h" + +#include + +#ifndef TCP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define TCP_LOCAL_PORT_RANGE_START 0xc000 +#define TCP_LOCAL_PORT_RANGE_END 0xffff +#define TCP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START) +#endif + +#if LWIP_TCP_KEEPALIVE +#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) +#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) +#else /* LWIP_TCP_KEEPALIVE */ +#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE +#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT +#endif /* LWIP_TCP_KEEPALIVE */ + +const char * const tcp_state_str[] = { + "CLOSED", + "LISTEN", + "SYN_SENT", + "SYN_RCVD", + "ESTABLISHED", + "FIN_WAIT_1", + "FIN_WAIT_2", + "CLOSE_WAIT", + "CLOSING", + "LAST_ACK", + "TIME_WAIT" +}; + +/* last local TCP port */ +static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; + +/* Incremented every coarse grained timer shot (typically every 500 ms). */ +u32_t tcp_ticks; +const u8_t tcp_backoff[13] = + { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; + /* Times per slowtmr hits */ +const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; + +/* The TCP PCB lists. */ + +/** List of all TCP PCBs bound but not yet (connected || listening) */ +struct tcp_pcb *tcp_bound_pcbs; +/** List of all TCP PCBs in LISTEN state */ +union tcp_listen_pcbs_t tcp_listen_pcbs; +/** List of all TCP PCBs that are in a state in which + * they accept or send data. */ +struct tcp_pcb *tcp_active_pcbs; +/** List of all TCP PCBs in TIME-WAIT state */ +struct tcp_pcb *tcp_tw_pcbs; + +#define NUM_TCP_PCB_LISTS 4 +#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 +/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ +struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, + &tcp_active_pcbs, &tcp_tw_pcbs}; + +/** Only used for temporary storage. */ +struct tcp_pcb *tcp_tmp_pcb; + +u8_t tcp_active_pcbs_changed; + +/** Timer counter to handle calling slow-timer from tcp_tmr() */ +static u8_t tcp_timer; +static u8_t tcp_timer_ctr; +static u16_t tcp_new_port(void); + +/** + * Initialize this module. + */ +void +tcp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Called periodically to dispatch TCP timers. + */ +void +tcp_tmr(void) +{ + /* Call tcp_fasttmr() every 250 ms */ + tcp_fasttmr(); + + if (++tcp_timer & 1) { + /* Call tcp_tmr() every 500 ms, i.e., every other timer + tcp_tmr() is called. */ + tcp_slowtmr(); + } +} + +/** + * Closes the TX side of a connection held by the PCB. + * For tcp_close(), a RST is sent if the application didn't receive all data + * (tcp_recved() not called for all data passed to recv callback). + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it. + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +static err_t +tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) +{ + err_t err; + + if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { + if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) { + /* Not all data received by application, send RST to tell the remote + side about this. */ + LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); + + /* don't call tcp_abort here: we must not deallocate the pcb since + that might not be expected when calling tcp_close */ + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + if (pcb->state == ESTABLISHED) { + /* move to TIME_WAIT since we close actively */ + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ + memp_free(MEMP_TCP_PCB, pcb); + } + return ERR_OK; + } + } + + switch (pcb->state) { + case CLOSED: + /* Closing a pcb in the CLOSED state might seem erroneous, + * however, it is in this state once allocated and as yet unused + * and the user needs some way to free it should the need arise. + * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) + * or for a pcb that has been used and then entered the CLOSED state + * is erroneous, but this should never happen as the pcb has in those cases + * been freed, and so any remaining handles are bogus. */ + err = ERR_OK; + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + break; + case LISTEN: + err = ERR_OK; + tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); + memp_free(MEMP_TCP_PCB_LISTEN, pcb); + pcb = NULL; + break; + case SYN_SENT: + err = ERR_OK; + TCP_PCB_REMOVE_ACTIVE(pcb); + memp_free(MEMP_TCP_PCB, pcb); + pcb = NULL; + snmp_inc_tcpattemptfails(); + break; + case SYN_RCVD: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpattemptfails(); + pcb->state = FIN_WAIT_1; + } + break; + case ESTABLISHED: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = FIN_WAIT_1; + } + break; + case CLOSE_WAIT: + err = tcp_send_fin(pcb); + if (err == ERR_OK) { + snmp_inc_tcpestabresets(); + pcb->state = LAST_ACK; + } + break; + default: + /* Has already been closed, do nothing. */ + err = ERR_OK; + pcb = NULL; + break; + } + + if (pcb != NULL && err == ERR_OK) { + /* To ensure all data has been sent when tcp_close returns, we have + to make sure tcp_output doesn't fail. + Since we don't really have to ensure all data has been sent when tcp_close + returns (unsent data is sent from tcp timer functions, also), we don't care + for the return value of tcp_output for now. */ + tcp_output(pcb); + } + return err; +} + +/** + * Closes the connection held by the PCB. + * + * Listening pcbs are freed and may not be referenced any more. + * Connection pcbs are freed if not yet connected and may not be referenced + * any more. If a connection is established (at least SYN received or in + * a closing state), the connection is closed, and put in a closing state. + * The pcb is then automatically freed in tcp_slowtmr(). It is therefore + * unsafe to reference it (unless an error is returned). + * + * @param pcb the tcp_pcb to close + * @return ERR_OK if connection has been closed + * another err_t if closing failed and pcb is not freed + */ +err_t +tcp_close(struct tcp_pcb *pcb) +{ +#if TCP_DEBUG + LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ + + if (pcb->state != LISTEN) { + /* Set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + } + /* ... and close */ + return tcp_close_shutdown(pcb, 1); +} + +/** + * Causes all or part of a full-duplex connection of this PCB to be shut down. + * This doesn't deallocate the PCB unless shutting down both sides! + * Shutting down both sides is the same as calling tcp_close, so if it succeds, + * the PCB should not be referenced any more. + * + * @param pcb PCB to shutdown + * @param shut_rx shut down receive side if this is != 0 + * @param shut_tx shut down send side if this is != 0 + * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) + * another err_t on error. + */ +err_t +tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) +{ + if (pcb->state == LISTEN) { + return ERR_CONN; + } + if (shut_rx) { + /* shut down the receive side: set a flag not to receive any more data... */ + pcb->flags |= TF_RXCLOSED; + if (shut_tx) { + /* shutting down the tx AND rx side is the same as closing for the raw API */ + return tcp_close_shutdown(pcb, 1); + } + /* ... and free buffered data */ + if (pcb->refused_data != NULL) { + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + } + if (shut_tx) { + /* This can't happen twice since if it succeeds, the pcb's state is changed. + Only close in these states as the others directly deallocate the PCB */ + switch (pcb->state) { + case SYN_RCVD: + case ESTABLISHED: + case CLOSE_WAIT: + return tcp_close_shutdown(pcb, shut_rx); + default: + /* Not (yet?) connected, cannot shutdown the TX side as that would bring us + into CLOSED state, where the PCB is deallocated. */ + return ERR_CONN; + } + } + return ERR_OK; +} + +/** + * Abandons a connection and optionally sends a RST to the remote + * host. Deletes the local protocol control block. This is done when + * a connection is killed because of shortage of memory. + * + * @param pcb the tcp_pcb to abort + * @param reset boolean to indicate whether a reset should be sent + */ +void +tcp_abandon(struct tcp_pcb *pcb, int reset) +{ + u32_t seqno, ackno; +#if LWIP_CALLBACK_API + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + void *errf_arg; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", + pcb->state != LISTEN); + /* Figure out on which TCP PCB list we are, and remove us. If we + are in an active state, call the receive function associated with + the PCB with a NULL argument, and send an RST to the remote end. */ + if (pcb->state == TIME_WAIT) { + tcp_pcb_remove(&tcp_tw_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + int send_rst = reset && (pcb->state != CLOSED); + seqno = pcb->snd_nxt; + ackno = pcb->rcv_nxt; +#if LWIP_CALLBACK_API + errf = pcb->errf; +#endif /* LWIP_CALLBACK_API */ + errf_arg = pcb->callback_arg; + if ((pcb->state == CLOSED) && (pcb->local_port != 0)) { + /* bound, not yet opened */ + TCP_RMV(&tcp_bound_pcbs, pcb); + } else { + TCP_PCB_REMOVE_ACTIVE(pcb); + } + if (pcb->unacked != NULL) { + tcp_segs_free(pcb->unacked); + } + if (pcb->unsent != NULL) { + tcp_segs_free(pcb->unsent); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + tcp_segs_free(pcb->ooseq); + } +#endif /* TCP_QUEUE_OOSEQ */ + if (send_rst) { + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); + tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + } + memp_free(MEMP_TCP_PCB, pcb); + TCP_EVENT_ERR(errf, errf_arg, ERR_ABRT); + } +} + +/** + * Aborts the connection by sending a RST (reset) segment to the remote + * host. The pcb is deallocated. This function never fails. + * + * ATTENTION: When calling this from one of the TCP callbacks, make + * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise + * or you will risk accessing deallocated memory or memory leaks! + * + * @param pcb the tcp pcb to abort + */ +void +tcp_abort(struct tcp_pcb *pcb) +{ + tcp_abandon(pcb, 1); +} + +/** + * Binds the connection to a local port number and IP address. If the + * IP address is not given (i.e., ipaddr == NULL), the IP address of + * the outgoing network interface is used instead. + * + * @param pcb the tcp_pcb to bind (no check is done whether this pcb is + * already bound!) + * @param ipaddr the local ip address to bind to (use IP_ADDR_ANY to bind + * to any local address + * @param port the local port to bind to + * @return ERR_USE if the port is already in use + * ERR_VAL if bind failed because the PCB is not in a valid state + * ERR_OK if bound + */ +err_t +tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + int i; + int max_pcb_list = NUM_TCP_PCB_LISTS; + struct tcp_pcb *cpcb; + + LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); + +#if SO_REUSE + /* Unless the REUSEADDR flag is set, + we have to check the pcbs in TIME-WAIT state, also. + We do not dump TIME_WAIT pcb's; they can still be matched by incoming + packets using both local and remote IP addresses and ports to distinguish. + */ + if (ip_get_option(pcb, SOF_REUSEADDR)) { + max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; + } +#endif /* SO_REUSE */ + + if (port == 0) { + port = tcp_new_port(); + if (port == 0) { + return ERR_BUF; + } + } + + /* Check if the address already is in use (on all lists) */ + for (i = 0; i < max_pcb_list; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if (cpcb->local_port == port) { +#if SO_REUSE + /* Omit checking for the same port if both pcbs have REUSEADDR set. + For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in + tcp_connect. */ + if (!ip_get_option(pcb, SOF_REUSEADDR) || + !ip_get_option(cpcb, SOF_REUSEADDR)) +#endif /* SO_REUSE */ + { + /* @todo: check accept_any_ip_version */ + if (IP_PCB_IPVER_EQ(pcb, cpcb) && + (ipX_addr_isany(PCB_ISIPV6(pcb), &cpcb->local_ip) || + ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr)) || + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, ip_2_ipX(ipaddr)))) { + return ERR_USE; + } + } + } + } + } + + if (!ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr))) { + ipX_addr_set(PCB_ISIPV6(pcb), &pcb->local_ip, ip_2_ipX(ipaddr)); + } + pcb->local_port = port; + TCP_REG(&tcp_bound_pcbs, pcb); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); + return ERR_OK; +} +#if LWIP_CALLBACK_API +/** + * Default accept callback if no accept callback is specified by the user. + */ +static err_t +tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(err); + + return ERR_ABRT; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Set the state of the connection to be LISTEN, which means that it + * is able to accept incoming connections. The protocol control block + * is reallocated in order to consume less memory. Setting the + * connection to LISTEN is an irreversible process. + * + * @param pcb the original tcp_pcb + * @param backlog the incoming connections queue limit + * @return tcp_pcb used for listening, consumes less memory. + * + * @note The original tcp_pcb is freed. This function therefore has to be + * called like this: + * tpcb = tcp_listen(tpcb); + */ +struct tcp_pcb * +tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb_listen *lpcb; + + LWIP_UNUSED_ARG(backlog); + LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL); + + /* already listening? */ + if (pcb->state == LISTEN) { + return pcb; + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage + is declared (listen-/connection-pcb), we have to make sure now that + this port is only used once for every local IP. */ + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((lpcb->local_port == pcb->local_port) && + IP_PCB_IPVER_EQ(pcb, lpcb)) { + if (ipX_addr_cmp(PCB_ISIPV6(pcb), &lpcb->local_ip, &pcb->local_ip)) { + /* this address/port is already used */ + return NULL; + } + } + } + } +#endif /* SO_REUSE */ + lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); + if (lpcb == NULL) { + return NULL; + } + lpcb->callback_arg = pcb->callback_arg; + lpcb->local_port = pcb->local_port; + lpcb->state = LISTEN; + lpcb->prio = pcb->prio; + lpcb->so_options = pcb->so_options; + lpcb->ttl = pcb->ttl; + lpcb->tos = pcb->tos; +#if LWIP_IPV6 + PCB_ISIPV6(lpcb) = PCB_ISIPV6(pcb); + lpcb->accept_any_ip_version = 0; +#endif /* LWIP_IPV6 */ + ipX_addr_copy(PCB_ISIPV6(pcb), lpcb->local_ip, pcb->local_ip); + if (pcb->local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + memp_free(MEMP_TCP_PCB, pcb); +#if LWIP_CALLBACK_API + lpcb->accept = tcp_accept_null; +#endif /* LWIP_CALLBACK_API */ +#if TCP_LISTEN_BACKLOG + lpcb->accepts_pending = 0; + lpcb->backlog = (backlog ? backlog : 1); +#endif /* TCP_LISTEN_BACKLOG */ + TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); + return (struct tcp_pcb *)lpcb; +} + +#if LWIP_IPV6 +/** + * Same as tcp_listen_with_backlog, but allows to accept IPv4 and IPv6 + * connections, if the pcb's local address is set to ANY. + */ +struct tcp_pcb * +tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog) +{ + struct tcp_pcb *lpcb; + + lpcb = tcp_listen_with_backlog(pcb, backlog); + if ((lpcb != NULL) && + ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { + /* The default behavior is to accept connections on either + * IPv4 or IPv6, if not bound. */ + /* @see NETCONN_FLAG_IPV6_V6ONLY for changing this behavior */ + ((struct tcp_pcb_listen*)lpcb)->accept_any_ip_version = 1; + } + return lpcb; +} +#endif /* LWIP_IPV6 */ + +/** + * Update the state that tracks the available window space to advertise. + * + * Returns how much extra window would be advertised if we sent an + * update now. + */ +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) +{ + u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; + + if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { + /* we can advertise more window */ + pcb->rcv_ann_wnd = pcb->rcv_wnd; + return new_right_edge - pcb->rcv_ann_right_edge; + } else { + if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { + /* Can happen due to other end sending out of advertised window, + * but within actual available (but not yet advertised) window */ + pcb->rcv_ann_wnd = 0; + } else { + /* keep the right edge of window constant */ + u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; +#if !LWIP_WND_SCALE + LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); +#endif + pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd; + } + return 0; + } +} + +/** + * This function should be called by the application when it has + * processed the data. The purpose is to advertise a larger window + * when the data has been processed. + * + * @param pcb the tcp_pcb for which data is read + * @param len the amount of bytes that have been read by the application + */ +void +tcp_recved(struct tcp_pcb *pcb, u16_t len) +{ + int wnd_inflation; + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_recved for listen-pcbs", + pcb->state != LISTEN); + + pcb->rcv_wnd += len; + if (pcb->rcv_wnd > TCP_WND) { + pcb->rcv_wnd = TCP_WND; + } else if(pcb->rcv_wnd == 0) { + /* rcv_wnd overflowed */ + if ((pcb->state == CLOSE_WAIT) || (pcb->state == LAST_ACK)) { + /* In passive close, we allow this, since the FIN bit is added to rcv_wnd + by the stack itself, since it is not mandatory for an application + to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */ + pcb->rcv_wnd = TCP_WND; + } else { + LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0); + } + } + + wnd_inflation = tcp_update_rcv_ann_wnd(pcb); + + /* If the change in the right edge of window is significant (default + * watermark is TCP_WND/4), then send an explicit update now. + * Otherwise wait for a packet to be sent in the normal course of + * events (or more window to be available later) */ + if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { + tcp_ack_now(pcb); + tcp_output(pcb); + } + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: received %"U16_F" bytes, wnd %"U16_F" (%"U16_F").\n", + len, pcb->rcv_wnd, TCP_WND - pcb->rcv_wnd)); +} + +/** + * Allocate a new local TCP port. + * + * @return a new (free) local TCP port number + */ +static u16_t +tcp_new_port(void) +{ + u8_t i; + u16_t n = 0; + struct tcp_pcb *pcb; + +again: + if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { + tcp_port = TCP_LOCAL_PORT_RANGE_START; + } + /* Check all PCB lists. */ + for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { + for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == tcp_port) { + if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + } + return tcp_port; +} + +/** + * Connects to another host. The function given as the "connected" + * argument will be called when the connection has been established. + * + * @param pcb the tcp_pcb used to establish the connection + * @param ipaddr the remote ip address to connect to + * @param port the remote tcp port to connect to + * @param connected callback function to call when connected (on error, + the err calback will be called) + * @return ERR_VAL if invalid arguments are given + * ERR_OK if connect request has been sent + * other err_t values if connect request couldn't be sent + */ +err_t +tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, + tcp_connected_fn connected) +{ + err_t ret; + u32_t iss; + u16_t old_local_port; + + LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); + if (ipaddr != NULL) { + ipX_addr_set(PCB_ISIPV6(pcb), &pcb->remote_ip, ip_2_ipX(ipaddr)); + } else { + return ERR_VAL; + } + pcb->remote_port = port; + + /* check if we have a route to the remote host */ + if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { + /* no local IP address set, yet. */ + struct netif *netif; + ipX_addr_t *local_ip; + ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip); + if ((netif == NULL) || (local_ip == NULL)) { + /* Don't even try to send a SYN packet if we have no route + since that will fail. */ + return ERR_RTE; + } + /* Use the address as local address of the pcb. */ + ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip); + } + + old_local_port = pcb->local_port; + if (pcb->local_port == 0) { + pcb->local_port = tcp_new_port(); + if (pcb->local_port == 0) { + return ERR_BUF; + } + } +#if SO_REUSE + if (ip_get_option(pcb, SOF_REUSEADDR)) { + /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure + now that the 5-tuple is unique. */ + struct tcp_pcb *cpcb; + int i; + /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ + for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { + for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { + if ((cpcb->local_port == pcb->local_port) && + (cpcb->remote_port == port) && + IP_PCB_IPVER_EQ(cpcb, pcb) && + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->local_ip, &pcb->local_ip) && + ipX_addr_cmp(PCB_ISIPV6(pcb), &cpcb->remote_ip, ip_2_ipX(ipaddr))) { + /* linux returns EISCONN here, but ERR_USE should be OK for us */ + return ERR_USE; + } + } + } + } +#endif /* SO_REUSE */ + iss = tcp_next_iss(); + pcb->rcv_nxt = 0; + pcb->snd_nxt = iss; + pcb->lastack = iss - 1; + pcb->snd_lbb = iss - 1; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->snd_wnd = TCP_WND; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + pcb->cwnd = 1; + pcb->ssthresh = pcb->mss * 10; +#if LWIP_CALLBACK_API + pcb->connected = connected; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(connected); +#endif /* LWIP_CALLBACK_API */ + + /* Send a SYN together with the MSS option. */ + ret = tcp_enqueue_flags(pcb, TCP_SYN); + if (ret == ERR_OK) { + /* SYN segment was enqueued, changed the pcbs state now */ + pcb->state = SYN_SENT; + if (old_local_port != 0) { + TCP_RMV(&tcp_bound_pcbs, pcb); + } + TCP_REG_ACTIVE(pcb); + snmp_inc_tcpactiveopens(); + + tcp_output(pcb); + } + return ret; +} + +/** + * Called every 500 ms and implements the retransmission timer and the timer that + * removes PCBs that have been in TIME-WAIT for enough time. It also increments + * various timers such as the inactivity timer in each PCB. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_slowtmr(void) +{ + struct tcp_pcb *pcb, *prev; + tcpwnd_size_t eff_wnd; + u8_t pcb_remove; /* flag if a PCB should be removed */ + u8_t pcb_reset; /* flag if a RST should be sent when removing */ + err_t err; + + err = ERR_OK; + + ++tcp_ticks; + ++tcp_timer_ctr; + +tcp_slowtmr_start: + /* Steps through all of the active PCBs. */ + prev = NULL; + pcb = tcp_active_pcbs; + if (pcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); + } + while (pcb != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); + LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); + if (pcb->last_timer == tcp_timer_ctr) { + /* skip this pcb, we have already processed it */ + pcb = pcb->next; + continue; + } + pcb->last_timer = tcp_timer_ctr; + + pcb_remove = 0; + pcb_reset = 0; + + if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); + } + else if (pcb->nrtx == TCP_MAXRTX) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); + } else { + if (pcb->persist_backoff > 0) { + /* If snd_wnd is zero, use persist timer to send 1 byte probes + * instead of using the standard retransmission mechanism. */ + pcb->persist_cnt++; + if (pcb->persist_cnt >= tcp_persist_backoff[pcb->persist_backoff-1]) { + pcb->persist_cnt = 0; + if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { + pcb->persist_backoff++; + } + tcp_zero_window_probe(pcb); + } + } else { + /* Increase the retransmission timer if it is running */ + if(pcb->rtime >= 0) { + ++pcb->rtime; + } + + if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { + /* Time for a retransmission. */ + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F + " pcb->rto %"S16_F"\n", + pcb->rtime, pcb->rto)); + + /* Double retransmission time-out unless we are trying to + * connect to somebody (i.e., we are in SYN_SENT). */ + if (pcb->state != SYN_SENT) { + pcb->rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[pcb->nrtx]; + } + + /* Reset the retransmission timer. */ + pcb->rtime = 0; + + /* Reduce congestion window and ssthresh. */ + eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); + pcb->ssthresh = eff_wnd >> 1; + if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) { + pcb->ssthresh = (pcb->mss << 1); + } + pcb->cwnd = pcb->mss; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"TCPWNDSIZE_F + " ssthresh %"TCPWNDSIZE_F"\n", + pcb->cwnd, pcb->ssthresh)); + + /* The following needs to be called AFTER cwnd is set to one + mss - STJ */ + tcp_rexmit_rto(pcb); + } + } + } + /* Check if this PCB has stayed too long in FIN-WAIT-2 */ + if (pcb->state == FIN_WAIT_2) { + /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ + if (pcb->flags & TF_RXCLOSED) { + /* PCB was fully closed (either through close() or SHUT_RDWR): + normal FIN-WAIT timeout handling. */ + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); + } + } + } + + /* Check if KEEPALIVE should be sent */ + if(ip_get_option(pcb, SOF_KEEPALIVE) && + ((pcb->state == ESTABLISHED) || + (pcb->state == CLOSE_WAIT))) { + if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) + { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); + LWIP_DEBUGF(TCP_DEBUG, ("\n")); + + ++pcb_remove; + ++pcb_reset; + } + else if((u32_t)(tcp_ticks - pcb->tmr) > + (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) + / TCP_SLOW_INTERVAL) + { + tcp_keepalive(pcb); + pcb->keep_cnt_sent++; + } + } + + /* If this PCB has queued out of sequence data, but has been + inactive for too long, will drop the data (it will eventually + be retransmitted). */ +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL && + (u32_t)tcp_ticks - pcb->tmr >= pcb->rto * TCP_OOSEQ_TIMEOUT) { + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); + } +#endif /* TCP_QUEUE_OOSEQ */ + + /* Check if this PCB has stayed too long in SYN-RCVD */ + if (pcb->state == SYN_RCVD) { + if ((u32_t)(tcp_ticks - pcb->tmr) > + TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); + } + } + + /* Check if this PCB has stayed too long in LAST-ACK */ + if (pcb->state == LAST_ACK) { + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); + } + } + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_err_fn err_fn; + void *err_arg; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_active_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); + tcp_active_pcbs = pcb->next; + } + + if (pcb_reset) { + tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, + pcb->local_port, pcb->remote_port, PCB_ISIPV6(pcb)); + } + + err_fn = pcb->errf; + err_arg = pcb->callback_arg; + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + + tcp_active_pcbs_changed = 0; + TCP_EVENT_ERR(err_fn, err_arg, ERR_ABRT); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + } else { + /* get the 'next' element now and work with 'prev' below (in case of abort) */ + prev = pcb; + pcb = pcb->next; + + /* We check if we should poll the connection. */ + ++prev->polltmr; + if (prev->polltmr >= prev->pollinterval) { + prev->polltmr = 0; + LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); + tcp_active_pcbs_changed = 0; + TCP_EVENT_POLL(prev, err); + if (tcp_active_pcbs_changed) { + goto tcp_slowtmr_start; + } + /* if err == ERR_ABRT, 'prev' is already deallocated */ + if (err == ERR_OK) { + tcp_output(prev); + } + } + } + } + + + /* Steps through all of the TIME-WAIT PCBs. */ + prev = NULL; + pcb = tcp_tw_pcbs; + while (pcb != NULL) { + LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + pcb_remove = 0; + + /* Check if this PCB has stayed long enough in TIME-WAIT */ + if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { + ++pcb_remove; + } + + + + /* If the PCB should be removed, do it. */ + if (pcb_remove) { + struct tcp_pcb *pcb2; + tcp_pcb_purge(pcb); + /* Remove PCB from tcp_tw_pcbs list. */ + if (prev != NULL) { + LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); + prev->next = pcb->next; + } else { + /* This PCB was the first. */ + LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); + tcp_tw_pcbs = pcb->next; + } + pcb2 = pcb; + pcb = pcb->next; + memp_free(MEMP_TCP_PCB, pcb2); + } else { + prev = pcb; + pcb = pcb->next; + } + } +} + +/** + * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously + * "refused" by upper layer (application) and sends delayed ACKs. + * + * Automatically called from tcp_tmr(). + */ +void +tcp_fasttmr(void) +{ + struct tcp_pcb *pcb; + + ++tcp_timer_ctr; + +tcp_fasttmr_start: + pcb = tcp_active_pcbs; + + while(pcb != NULL) { + if (pcb->last_timer != tcp_timer_ctr) { + struct tcp_pcb *next; + pcb->last_timer = tcp_timer_ctr; + /* send delayed ACKs */ + if (pcb->flags & TF_ACK_DELAY) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); + tcp_ack_now(pcb); + tcp_output(pcb); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + + next = pcb->next; + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + tcp_active_pcbs_changed = 0; + tcp_process_refused_data(pcb); + if (tcp_active_pcbs_changed) { + /* application callback has changed the pcb list: restart the loop */ + goto tcp_fasttmr_start; + } + } + pcb = next; + } else { + pcb = pcb->next; + } + } +} + +/** Pass pcb->refused_data to the recv callback */ +err_t +tcp_process_refused_data(struct tcp_pcb *pcb) +{ +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + struct pbuf *rest; + while (pcb->refused_data != NULL) +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + { + err_t err; + u8_t refused_flags = pcb->refused_data->flags; + /* set pcb->refused_data to NULL in case the callback frees it and then + closes the pcb */ + struct pbuf *refused_data = pcb->refused_data; +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + pbuf_split_64k(refused_data, &rest); + pcb->refused_data = rest; +#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + pcb->refused_data = NULL; +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + /* Notify again application with data previously received. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); + TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); + if (err == ERR_OK) { + /* did refused_data include a FIN? */ + if (refused_flags & PBUF_FLAG_TCP_FIN +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + && (rest == NULL) +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + ) { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + } + } else if (err == ERR_ABRT) { + /* if err == ERR_ABRT, 'pcb' is already deallocated */ + /* Drop incoming packets because pcb is "full" (only if the incoming + segment contains data). */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); + return ERR_ABRT; + } else { + /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + if (rest != NULL) { + pbuf_cat(refused_data, rest); + } +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + pcb->refused_data = refused_data; + return ERR_INPROGRESS; + } + } + return ERR_OK; +} + +/** + * Deallocates a list of TCP segments (tcp_seg structures). + * + * @param seg tcp_seg list of TCP segments to free + */ +void +tcp_segs_free(struct tcp_seg *seg) +{ + while (seg != NULL) { + struct tcp_seg *next = seg->next; + tcp_seg_free(seg); + seg = next; + } +} + +/** + * Frees a TCP segment (tcp_seg structure). + * + * @param seg single tcp_seg to free + */ +void +tcp_seg_free(struct tcp_seg *seg) +{ + if (seg != NULL) { + if (seg->p != NULL) { + pbuf_free(seg->p); +#if TCP_DEBUG + seg->p = NULL; +#endif /* TCP_DEBUG */ + } + memp_free(MEMP_TCP_SEG, seg); + } +} + +/** + * Sets the priority of a connection. + * + * @param pcb the tcp_pcb to manipulate + * @param prio new priority + */ +void +tcp_setprio(struct tcp_pcb *pcb, u8_t prio) +{ + pcb->prio = prio; +} + +#if TCP_QUEUE_OOSEQ +/** + * Returns a copy of the given TCP segment. + * The pbuf and data are not copied, only the pointers + * + * @param seg the old tcp_seg + * @return a copy of seg + */ +struct tcp_seg * +tcp_seg_copy(struct tcp_seg *seg) +{ + struct tcp_seg *cseg; + + cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); + if (cseg == NULL) { + return NULL; + } + SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); + pbuf_ref(cseg->p); + return cseg; +} +#endif /* TCP_QUEUE_OOSEQ */ + +#if LWIP_CALLBACK_API +/** + * Default receive callback that is called if the user didn't register + * a recv callback for the pcb. + */ +err_t +tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) +{ + LWIP_UNUSED_ARG(arg); + if (p != NULL) { + tcp_recved(pcb, p->tot_len); + pbuf_free(p); + } else if (err == ERR_OK) { + return tcp_close(pcb); + } + return ERR_OK; +} +#endif /* LWIP_CALLBACK_API */ + +/** + * Kills the oldest active connection that has the same or lower priority than + * 'prio'. + * + * @param prio minimum priority + */ +static void +tcp_kill_prio(u8_t prio) +{ + struct tcp_pcb *pcb, *inactive, *lastack; + u32_t inactivity, inactivity_lastack; + u8_t minprio, minprio_lastack; + + minprio = prio; + minprio_lastack = prio; + + /* We kill the oldest active connection that has lower priority than prio. + However, already closed connections waiting for the last ack are closed first + since they don't lose data. */ + inactivity = 0; + inactive = NULL; + inactivity_lastack = 0; + lastack = NULL; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + if ((lastack != NULL) || (pcb->state == LAST_ACK) || (pcb->state == CLOSING)) { + /* found at least one pcb in last ack phase */ + if ((pcb->prio < minprio_lastack) || + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity_lastack) { + inactivity_lastack = tcp_ticks - pcb->tmr; + lastack = pcb; + minprio_lastack = pcb->prio; + } + } else if (pcb->prio <= minprio) { + if ((pcb->prio < minprio) || + (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + minprio = pcb->prio; + } + } + } + if (lastack != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB in LAST_ACK or CLOSING %p (%"S32_F")\n", + (void *)lastack, inactivity_lastack)); + tcp_abort(lastack); + } else if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Kills the oldest connection that is in TIME_WAIT state. + * Called from tcp_alloc() if no more connections are available. + */ +static void +tcp_kill_timewait(void) +{ + struct tcp_pcb *pcb, *inactive; + u32_t inactivity; + + inactivity = 0; + inactive = NULL; + /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { + inactivity = tcp_ticks - pcb->tmr; + inactive = pcb; + } + } + if (inactive != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", + (void *)inactive, inactivity)); + tcp_abort(inactive); + } +} + +/** + * Allocate a new tcp_pcb structure. + * + * @param prio priority for the new pcb + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_alloc(u8_t prio) +{ + struct tcp_pcb *pcb; + u32_t iss; + + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing oldest connection in TIME-WAIT. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); + tcp_kill_timewait(); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb == NULL) { + /* Try killing active connections with lower priority than the new one. */ + LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); + tcp_kill_prio(prio); + /* Try to allocate a tcp_pcb again. */ + pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); + if (pcb != NULL) { + /* adjust err stats: memp_malloc failed twice before */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + /* adjust err stats: timewait PCB was freed above */ + MEMP_STATS_DEC(err, MEMP_TCP_PCB); + } + } + if (pcb != NULL) { + memset(pcb, 0, sizeof(struct tcp_pcb)); + pcb->prio = prio; + pcb->snd_buf = TCP_SND_BUF; + pcb->snd_queuelen = 0; + pcb->rcv_wnd = TCP_WND; + pcb->rcv_ann_wnd = TCP_WND; +#if LWIP_WND_SCALE + /* snd_scale and rcv_scale are zero unless both sides agree to use scaling */ + pcb->snd_scale = 0; + pcb->rcv_scale = 0; +#endif + pcb->tos = 0; + pcb->ttl = TCP_TTL; + /* As initial send MSS, we use TCP_MSS but limit it to 536. + The send MSS is updated when an MSS option is received. */ + pcb->mss = (TCP_MSS > 536) ? 536 : TCP_MSS; + pcb->rto = 3000 / TCP_SLOW_INTERVAL; + pcb->sa = 0; + pcb->sv = 3000 / TCP_SLOW_INTERVAL; + pcb->rtime = -1; + pcb->cwnd = 1; + iss = tcp_next_iss(); + pcb->snd_wl2 = iss; + pcb->snd_nxt = iss; + pcb->lastack = iss; + pcb->snd_lbb = iss; + pcb->tmr = tcp_ticks; + pcb->last_timer = tcp_timer_ctr; + + pcb->polltmr = 0; + +#if LWIP_CALLBACK_API + pcb->recv = tcp_recv_null; +#endif /* LWIP_CALLBACK_API */ + + /* Init KEEPALIVE timer */ + pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; + +#if LWIP_TCP_KEEPALIVE + pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; + pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; +#endif /* LWIP_TCP_KEEPALIVE */ + + pcb->keep_cnt_sent = 0; + } + return pcb; +} + +/** + * Creates a new TCP protocol control block but doesn't place it on + * any of the TCP PCB lists. + * The pcb is not put on any list until binding using tcp_bind(). + * + * @internal: Maybe there should be a idle TCP PCB list where these + * PCBs are put on. Port reservation using tcp_bind() is implemented but + * allocated pcbs that are not bound can't be killed automatically if wanting + * to allocate a pcb with higher prio (@see tcp_kill_prio()) + * + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_new(void) +{ + return tcp_alloc(TCP_PRIO_NORMAL); +} + +#if LWIP_IPV6 +/** + * Creates a new TCP-over-IPv6 protocol control block but doesn't + * place it on any of the TCP PCB lists. + * The pcb is not put on any list until binding using tcp_bind(). + * + * @return a new tcp_pcb that initially is in state CLOSED + */ +struct tcp_pcb * +tcp_new_ip6(void) +{ + struct tcp_pcb * pcb; + pcb = tcp_alloc(TCP_PRIO_NORMAL); + ip_set_v6(pcb, 1); + return pcb; +} +#endif /* LWIP_IPV6 */ + +/** + * Used to specify the argument that should be passed callback + * functions. + * + * @param pcb tcp_pcb to set the callback argument + * @param arg void pointer argument to pass to callback functions + */ +void +tcp_arg(struct tcp_pcb *pcb, void *arg) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->callback_arg = arg; +} +#if LWIP_CALLBACK_API + +/** + * Used to specify the function that should be called when a TCP + * connection receives data. + * + * @param pcb tcp_pcb to set the recv callback + * @param recv callback function to call for this pcb when data is received + */ +void +tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) +{ + LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); + pcb->recv = recv; +} + +/** + * Used to specify the function that should be called when TCP data + * has been successfully delivered to the remote host. + * + * @param pcb tcp_pcb to set the sent callback + * @param sent callback function to call for this pcb when data is successfully sent + */ +void +tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) +{ + LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); + pcb->sent = sent; +} + +/** + * Used to specify the function that should be called when a fatal error + * has occurred on the connection. + * + * @param pcb tcp_pcb to set the err callback + * @param err callback function to call for this pcb when a fatal error + * has occurred on the connection + */ +void +tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) +{ + LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); + pcb->errf = err; +} + +/** + * Used for specifying the function that should be called when a + * LISTENing connection has been connected to another host. + * + * @param pcb tcp_pcb to set the accept callback + * @param accept callback function to call for this pcb when LISTENing + * connection has been connected to another host + */ +void +tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) +{ + /* This function is allowed to be called for both listen pcbs and + connection pcbs. */ + pcb->accept = accept; +} +#endif /* LWIP_CALLBACK_API */ + + +/** + * Used to specify the function that should be called periodically + * from TCP. The interval is specified in terms of the TCP coarse + * timer interval, which is called twice a second. + * + */ +void +tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) +{ + LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); +#if LWIP_CALLBACK_API + pcb->poll = poll; +#else /* LWIP_CALLBACK_API */ + LWIP_UNUSED_ARG(poll); +#endif /* LWIP_CALLBACK_API */ + pcb->pollinterval = interval; +} + +/** + * Purges a TCP PCB. Removes any buffered data and frees the buffer memory + * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). + * + * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! + */ +void +tcp_pcb_purge(struct tcp_pcb *pcb) +{ + if (pcb->state != CLOSED && + pcb->state != TIME_WAIT && + pcb->state != LISTEN) { + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); + +#if TCP_LISTEN_BACKLOG + if (pcb->state == SYN_RCVD) { + /* Need to find the corresponding listen_pcb and decrease its accepts_pending */ + struct tcp_pcb_listen *lpcb; + LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", + tcp_listen_pcbs.listen_pcbs != NULL); + for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if ((lpcb->local_port == pcb->local_port) && + IP_PCB_IPVER_EQ(pcb, lpcb) && + (ipX_addr_isany(PCB_ISIPV6(lpcb), &lpcb->local_ip) || + ipX_addr_cmp(PCB_ISIPV6(lpcb), &pcb->local_ip, &lpcb->local_ip))) { + /* port and address of the listen pcb match the timed-out pcb */ + LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", + lpcb->accepts_pending > 0); + lpcb->accepts_pending--; + break; + } + } + } +#endif /* TCP_LISTEN_BACKLOG */ + + + if (pcb->refused_data != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); + pbuf_free(pcb->refused_data); + pcb->refused_data = NULL; + } + if (pcb->unsent != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); + } + if (pcb->unacked != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); + } +#if TCP_QUEUE_OOSEQ + if (pcb->ooseq != NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); + } + tcp_segs_free(pcb->ooseq); + pcb->ooseq = NULL; +#endif /* TCP_QUEUE_OOSEQ */ + + /* Stop the retransmission timer as it will expect data on unacked + queue if it fires */ + pcb->rtime = -1; + + tcp_segs_free(pcb->unsent); + tcp_segs_free(pcb->unacked); + pcb->unacked = pcb->unsent = NULL; +#if TCP_OVERSIZE + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + } +} + +/** + * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. + * + * @param pcblist PCB list to purge. + * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! + */ +void +tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) +{ + TCP_RMV(pcblist, pcb); + + tcp_pcb_purge(pcb); + + /* if there is an outstanding delayed ACKs, send it */ + if (pcb->state != TIME_WAIT && + pcb->state != LISTEN && + pcb->flags & TF_ACK_DELAY) { + pcb->flags |= TF_ACK_NOW; + tcp_output(pcb); + } + + if (pcb->state != LISTEN) { + LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); + LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); +#if TCP_QUEUE_OOSEQ + LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); +#endif /* TCP_QUEUE_OOSEQ */ + } + + pcb->state = CLOSED; + /* reset the local port to prevent the pcb from being 'bound' */ + pcb->local_port = 0; + + LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); +} + +/** + * Calculates a new initial sequence number for new connections. + * + * @return u32_t pseudo random sequence number + */ +u32_t +tcp_next_iss(void) +{ + static u32_t iss = 6510; + + iss += tcp_ticks; /* XXX */ + return iss; +} + +#if TCP_CALCULATE_EFF_SEND_MSS +/** + * Calculates the effective send mss that can be used for a specific IP address + * by using ip_route to determine the netif used to send to the address and + * calculating the minimum of TCP_MSS and that netif's mtu (if set). + */ +u16_t +tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest +#if LWIP_IPV6 + , ipX_addr_t *src, u8_t isipv6 +#endif /* LWIP_IPV6 */ + ) +{ + u16_t mss_s; + struct netif *outif; + s16_t mtu; + + outif = ipX_route(isipv6, src, dest); +#if LWIP_IPV6 + if (isipv6) { + /* First look in destination cache, to see if there is a Path MTU. */ + mtu = nd6_get_destination_mtu(ipX_2_ip6(dest), outif); + } else +#endif /* LWIP_IPV6 */ + { + if (outif == NULL) { + return sendmss; + } + mtu = outif->mtu; + } + + if (mtu != 0) { + mss_s = mtu - IP_HLEN - TCP_HLEN; +#if LWIP_IPV6 + if (isipv6) { + /* for IPv6, subtract the difference in header size */ + mss_s -= (IP6_HLEN - IP_HLEN); + } +#endif /* LWIP_IPV6 */ + /* RFC 1122, chap 4.2.2.6: + * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize + * We correct for TCP options in tcp_write(), and don't support IP options. + */ + sendmss = LWIP_MIN(sendmss, mss_s); + } + return sendmss; +} +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +const char* +tcp_debug_state_str(enum tcp_state s) +{ + return tcp_state_str[s]; +} + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +/** + * Print a tcp header for debugging purposes. + * + * @param tcphdr pointer to a struct tcp_hdr + */ +void +tcp_debug_print(struct tcp_hdr *tcphdr) +{ + LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(tcphdr->src), ntohs(tcphdr->dest))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", + ntohl(tcphdr->seqno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", + ntohl(tcphdr->ackno))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", + TCPH_HDRLEN(tcphdr), + TCPH_FLAGS(tcphdr) >> 5 & 1, + TCPH_FLAGS(tcphdr) >> 4 & 1, + TCPH_FLAGS(tcphdr) >> 3 & 1, + TCPH_FLAGS(tcphdr) >> 2 & 1, + TCPH_FLAGS(tcphdr) >> 1 & 1, + TCPH_FLAGS(tcphdr) & 1, + ntohs(tcphdr->wnd))); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", + ntohs(tcphdr->chksum), ntohs(tcphdr->urgp))); + LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); +} + +/** + * Print a tcp state for debugging purposes. + * + * @param s enum tcp_state to print + */ +void +tcp_debug_print_state(enum tcp_state s) +{ + LWIP_DEBUGF(TCP_DEBUG, ("State: %s\n", tcp_state_str[s])); +} + +/** + * Print tcp flags for debugging purposes. + * + * @param flags tcp flags, all active flags are printed + */ +void +tcp_debug_print_flags(u8_t flags) +{ + if (flags & TCP_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); + } + if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); + } + if (flags & TCP_RST) { + LWIP_DEBUGF(TCP_DEBUG, ("RST ")); + } + if (flags & TCP_PSH) { + LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); + } + if (flags & TCP_ACK) { + LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); + } + if (flags & TCP_URG) { + LWIP_DEBUGF(TCP_DEBUG, ("URG ")); + } + if (flags & TCP_ECE) { + LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); + } + if (flags & TCP_CWR) { + LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); + } + LWIP_DEBUGF(TCP_DEBUG, ("\n")); +} + +/** + * Print all tcp_pcbs in every list for debugging purposes. + */ +void +tcp_debug_print_pcbs(void) +{ + struct tcp_pcb *pcb; + LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); + for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } + LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", + pcb->local_port, pcb->remote_port, + pcb->snd_nxt, pcb->rcv_nxt)); + tcp_debug_print_state(pcb->state); + } +} + +/** + * Check state consistency of the tcp_pcb lists. + */ +s16_t +tcp_pcbs_sane(void) +{ + struct tcp_pcb *pcb; + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); + LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + } + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + } + return 1; +} +#endif /* TCP_DEBUG */ + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_in.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_in.c new file mode 100644 index 0000000..9eedfc2 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_in.c @@ -0,0 +1,1770 @@ +/** + * @file + * Transmission Control Protocol, incoming traffic + * + * The input processing functions of the TCP layer. + * + * These functions are generally called in the order (ip_input() ->) + * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#if LWIP_ND6_TCP_REACHABILITY_HINTS +#include "lwip/nd6.h" +#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ + +#define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)); + +/* These variables are global to all functions involved in the input + processing of TCP segments. They are set by the tcp_input() + function. */ +static struct tcp_seg inseg; +static struct tcp_hdr *tcphdr; +static u16_t tcphdr_opt1len; +static u8_t* tcphdr_opt2; +static u16_t tcp_optidx; +static u32_t seqno, ackno; +static u8_t flags; +static u16_t tcplen; + +static u8_t recv_flags; +static struct pbuf *recv_data; + +struct tcp_pcb *tcp_input_pcb; + +/* Forward declarations. */ +static err_t tcp_process(struct tcp_pcb *pcb); +static void tcp_receive(struct tcp_pcb *pcb); +static void tcp_parseopt(struct tcp_pcb *pcb); + +static err_t tcp_listen_input(struct tcp_pcb_listen *pcb); +static err_t tcp_timewait_input(struct tcp_pcb *pcb); + +/** + * The initial input processing of TCP. It verifies the TCP header, demultiplexes + * the segment between the PCBs and passes it on to tcp_process(), which implements + * the TCP finite state machine. This function is called by the IP layer (in + * ip_input()). + * + * @param p received TCP segment to process (p->payload pointing to the TCP header) + * @param inp network interface on which this segment was received + */ +void +tcp_input(struct pbuf *p, struct netif *inp) +{ + struct tcp_pcb *pcb, *prev; + struct tcp_pcb_listen *lpcb; +#if SO_REUSE + struct tcp_pcb *lpcb_prev = NULL; + struct tcp_pcb_listen *lpcb_any = NULL; +#endif /* SO_REUSE */ + u8_t hdrlen; + err_t err; +#if CHECKSUM_CHECK_TCP + u16_t chksum; +#endif /* CHECKSUM_CHECK_TCP */ + + PERF_START; + + TCP_STATS_INC(tcp.recv); + snmp_inc_tcpinsegs(); + + tcphdr = (struct tcp_hdr *)p->payload; + +#if TCP_INPUT_DEBUG + tcp_debug_print(tcphdr); +#endif + + /* Check that TCP header fits in payload */ + if (p->len < sizeof(struct tcp_hdr)) { + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + + /* Don't even process incoming broadcasts/multicasts. */ + if ((!ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp)) || + ipX_addr_ismulticast(ip_current_is_v6(), ipX_current_dest_addr())) { + TCP_STATS_INC(tcp.proterr); + goto dropped; + } + +#if CHECKSUM_CHECK_TCP + /* Verify TCP checksum. */ + chksum = ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_TCP, p->tot_len, + ipX_current_src_addr(), ipX_current_dest_addr()); + if (chksum != 0) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", + chksum)); + tcp_debug_print(tcphdr); + TCP_STATS_INC(tcp.chkerr); + goto dropped; + } +#endif /* CHECKSUM_CHECK_TCP */ + + /* Move the payload pointer in the pbuf so that it points to the + TCP data instead of the TCP header. */ + hdrlen = TCPH_HDRLEN(tcphdr); + tcphdr_opt1len = (hdrlen * 4) - TCP_HLEN; + tcphdr_opt2 = NULL; + if (p->len < hdrlen * 4) { + if (p->len >= TCP_HLEN) { + /* TCP header fits into first pbuf, options don't - data is in the next pbuf */ + u16_t optlen = tcphdr_opt1len; + pbuf_header(p, -TCP_HLEN); /* cannot fail */ + LWIP_ASSERT("tcphdr_opt1len >= p->len", tcphdr_opt1len >= p->len); + LWIP_ASSERT("p->next != NULL", p->next != NULL); + tcphdr_opt1len = p->len; + if (optlen > tcphdr_opt1len) { + s16_t opt2len; + /* options continue in the next pbuf: set p to zero length and hide the + options in the next pbuf (adjusting p->tot_len) */ + u8_t phret = pbuf_header(p, -(s16_t)tcphdr_opt1len); + LWIP_ASSERT("phret == 0", phret == 0); + tcphdr_opt2 = (u8_t*)p->next->payload; + opt2len = optlen - tcphdr_opt1len; + phret = pbuf_header(p->next, -opt2len); + LWIP_ASSERT("phret == 0", phret == 0); + /* p->next->payload now points to the TCP data */ + /* manually adjust p->tot_len to changed p->next->tot_len change */ + p->tot_len -= opt2len; + } + LWIP_ASSERT("p->len == 0", p->len == 0); + } else { + /* drop short packets */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet\n")); + TCP_STATS_INC(tcp.lenerr); + goto dropped; + } + } else { + pbuf_header(p, -(hdrlen * 4)); /* cannot fail */ + } + + /* Convert fields in TCP header to host byte order. */ + tcphdr->src = ntohs(tcphdr->src); + tcphdr->dest = ntohs(tcphdr->dest); + seqno = tcphdr->seqno = ntohl(tcphdr->seqno); + ackno = tcphdr->ackno = ntohl(tcphdr->ackno); + tcphdr->wnd = ntohs(tcphdr->wnd); + + flags = TCPH_FLAGS(tcphdr); + tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); + + /* Demultiplex an incoming segment. First, we check if it is destined + for an active connection. */ + prev = NULL; + + + for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); + LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); + LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + IP_PCB_IPVER_INPUT_MATCH(pcb) && + ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && + ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); + if (prev != NULL) { + prev->next = pcb->next; + pcb->next = tcp_active_pcbs; + tcp_active_pcbs = pcb; + } + LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); + break; + } + prev = pcb; + } + + if (pcb == NULL) { + /* If it did not go to an active connection, we check the connections + in the TIME-WAIT state. */ + for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { + LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); + if (pcb->remote_port == tcphdr->src && + pcb->local_port == tcphdr->dest && + IP_PCB_IPVER_INPUT_MATCH(pcb) && + ipX_addr_cmp(ip_current_is_v6(), &pcb->remote_ip, ipX_current_src_addr()) && + ipX_addr_cmp(ip_current_is_v6(),&pcb->local_ip, ipX_current_dest_addr())) { + /* We don't really care enough to move this PCB to the front + of the list since we are not very likely to receive that + many segments for connections in TIME-WAIT. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); + tcp_timewait_input(pcb); + pbuf_free(p); + return; + } + } + + /* Finally, if we still did not get a match, we check all PCBs that + are LISTENing for incoming connections. */ + prev = NULL; + for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { + if (lpcb->local_port == tcphdr->dest) { +#if LWIP_IPV6 + if (lpcb->accept_any_ip_version) { + /* found an ANY-match */ +#if SO_REUSE + lpcb_any = lpcb; + lpcb_prev = prev; +#else /* SO_REUSE */ + break; +#endif /* SO_REUSE */ + } else +#endif /* LWIP_IPV6 */ + if (IP_PCB_IPVER_INPUT_MATCH(lpcb)) { + if (ipX_addr_cmp(ip_current_is_v6(), &lpcb->local_ip, ipX_current_dest_addr())) { + /* found an exact match */ + break; + } else if (ipX_addr_isany(ip_current_is_v6(), &lpcb->local_ip)) { + /* found an ANY-match */ +#if SO_REUSE + lpcb_any = lpcb; + lpcb_prev = prev; +#else /* SO_REUSE */ + break; + #endif /* SO_REUSE */ + } + } + } + prev = (struct tcp_pcb *)lpcb; + } +#if SO_REUSE + /* first try specific local IP */ + if (lpcb == NULL) { + /* only pass to ANY if no specific local IP has been found */ + lpcb = lpcb_any; + prev = lpcb_prev; + } +#endif /* SO_REUSE */ + if (lpcb != NULL) { + /* Move this PCB to the front of the list so that subsequent + lookups will be faster (we exploit locality in TCP segment + arrivals). */ + if (prev != NULL) { + ((struct tcp_pcb_listen *)prev)->next = lpcb->next; + /* our successor is the remainder of the listening list */ + lpcb->next = tcp_listen_pcbs.listen_pcbs; + /* put this listening pcb at the head of the listening list */ + tcp_listen_pcbs.listen_pcbs = lpcb; + } + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); + tcp_listen_input(lpcb); + pbuf_free(p); + return; + } + } + +#if TCP_INPUT_DEBUG + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("+-+-+-+-+-+-+-+-+-+-+-+-+-+- tcp_input: flags ")); + tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n")); +#endif /* TCP_INPUT_DEBUG */ + + + if (pcb != NULL) { + /* The incoming segment belongs to a connection. */ +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + + /* Set up a tcp_seg structure. */ + inseg.next = NULL; + inseg.len = p->tot_len; + inseg.p = p; + inseg.tcphdr = tcphdr; + + recv_data = NULL; + recv_flags = 0; + + if (flags & TCP_PSH) { + p->flags |= PBUF_FLAG_PUSH; + } + + /* If there is data which was previously "refused" by upper layer */ + if (pcb->refused_data != NULL) { + if ((tcp_process_refused_data(pcb) == ERR_ABRT) || + ((pcb->refused_data != NULL) && (tcplen > 0))) { + /* pcb has been aborted or refused data is still refused and the new + segment contains data */ + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + goto aborted; + } + } + tcp_input_pcb = pcb; + err = tcp_process(pcb); + /* A return value of ERR_ABRT means that tcp_abort() was called + and that the pcb has been freed. If so, we don't do anything. */ + if (err != ERR_ABRT) { + if (recv_flags & TF_RESET) { + /* TF_RESET means that the connection was reset by the other + end. We then call the error callback to inform the + application that the connection is dead before we + deallocate the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST); + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else if (recv_flags & TF_CLOSED) { + /* The connection has been closed and we will deallocate the + PCB. */ + if (!(pcb->flags & TF_RXCLOSED)) { + /* Connection closed although the application has only shut down the + tx side: call the PCB's err callback and indicate the closure to + ensure the application doesn't continue using the PCB. */ + TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_CLSD); + } + tcp_pcb_remove(&tcp_active_pcbs, pcb); + memp_free(MEMP_TCP_PCB, pcb); + } else { + err = ERR_OK; + /* If the application has registered a "sent" function to be + called when new send buffer space is available, we call it + now. */ + if (pcb->acked > 0) { + u16_t acked; +#if LWIP_WND_SCALE + /* pcb->acked is u32_t but the sent callback only takes a u16_t, + so we might have to call it multiple times. */ + u32_t pcb_acked = pcb->acked; + while(pcb_acked > 0) { + acked = (u16_t)LWIP_MIN(pcb_acked, 0xffffu); + pcb_acked -= acked; +#else + { + acked = pcb->acked; +#endif + TCP_EVENT_SENT(pcb, (u16_t)acked, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + } + +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + while (recv_data != NULL) { + struct pbuf *rest = NULL; + pbuf_split_64k(recv_data, &rest); +#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + if (recv_data != NULL) { +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + + LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); + if (pcb->flags & TF_RXCLOSED) { + /* received data although already closed -> abort (send RST) to + notify the remote host that not all data has been processed */ + pbuf_free(recv_data); +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + if (rest != NULL) { + pbuf_free(rest); + } +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + tcp_abort(pcb); + goto aborted; + } + + /* Notify application that data has been received. */ + TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); + if (err == ERR_ABRT) { +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + if (rest != NULL) { + pbuf_free(rest); + } +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + goto aborted; + } + + /* If the upper layer can't receive this data, store it */ + if (err != ERR_OK) { +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + if (rest != NULL) { + pbuf_cat(recv_data, rest); + } +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + pcb->refused_data = recv_data; + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); +#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE + break; + } else { + /* Upper layer received the data, go on with the rest if > 64K */ + recv_data = rest; +#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + } + } + + /* If a FIN segment was received, we call the callback + function with a NULL buffer to indicate EOF. */ + if (recv_flags & TF_GOT_FIN) { + if (pcb->refused_data != NULL) { + /* Delay this if we have refused data. */ + pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; + } else { + /* correct rcv_wnd as the application won't call tcp_recved() + for the FIN's seqno */ + if (pcb->rcv_wnd != TCP_WND) { + pcb->rcv_wnd++; + } + TCP_EVENT_CLOSED(pcb, err); + if (err == ERR_ABRT) { + goto aborted; + } + } + } + + tcp_input_pcb = NULL; + /* Try to send something out. */ + tcp_output(pcb); +#if TCP_INPUT_DEBUG +#if TCP_DEBUG + tcp_debug_print_state(pcb->state); +#endif /* TCP_DEBUG */ +#endif /* TCP_INPUT_DEBUG */ + } + } + /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). + Below this line, 'pcb' may not be dereferenced! */ +aborted: + tcp_input_pcb = NULL; + recv_data = NULL; + + /* give up our reference to inseg.p */ + if (inseg.p != NULL) + { + pbuf_free(inseg.p); + inseg.p = NULL; + } + } else { + + /* If no matching PCB was found, send a TCP RST (reset) to the + sender. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); + if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { + TCP_STATS_INC(tcp.proterr); + TCP_STATS_INC(tcp.drop); + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + } + pbuf_free(p); + } + + LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); + PERF_STOP("tcp_input"); + return; +dropped: + TCP_STATS_INC(tcp.drop); + snmp_inc_tcpinerrs(); + pbuf_free(p); +} + +/** + * Called by tcp_input() when a segment arrives for a listening + * connection (from tcp_input()). + * + * @param pcb the tcp_pcb_listen for which a segment arrived + * @return ERR_OK if the segment was processed + * another err_t on error + * + * @note the return value is not (yet?) used in tcp_input() + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_listen_input(struct tcp_pcb_listen *pcb) +{ + struct tcp_pcb *npcb; + err_t rc; + + if (flags & TCP_RST) { + /* An incoming RST should be ignored. Return. */ + return ERR_OK; + } + + /* In the LISTEN state, we check for incoming SYN segments, + creates a new PCB, and responds with a SYN|ACK. */ + if (flags & TCP_ACK) { + /* For incoming segments with the ACK flag set, respond with a + RST. */ + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + } else if (flags & TCP_SYN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); +#if TCP_LISTEN_BACKLOG + if (pcb->accepts_pending >= pcb->backlog) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); + return ERR_ABRT; + } +#endif /* TCP_LISTEN_BACKLOG */ + npcb = tcp_alloc(pcb->prio); + /* If a new PCB could not be created (probably due to lack of memory), + we don't do anything, but rely on the sender will retransmit the + SYN at a time when we have more memory available. */ + if (npcb == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } +#if TCP_LISTEN_BACKLOG + pcb->accepts_pending++; +#endif /* TCP_LISTEN_BACKLOG */ + /* Set up the new PCB. */ +#if LWIP_IPV6 + PCB_ISIPV6(npcb) = ip_current_is_v6(); +#endif /* LWIP_IPV6 */ + ipX_addr_copy(ip_current_is_v6(), npcb->local_ip, *ipX_current_dest_addr()); + ipX_addr_copy(ip_current_is_v6(), npcb->remote_ip, *ipX_current_src_addr()); + npcb->local_port = pcb->local_port; + npcb->remote_port = tcphdr->src; + npcb->state = SYN_RCVD; + npcb->rcv_nxt = seqno + 1; + npcb->rcv_ann_right_edge = npcb->rcv_nxt; + npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ + npcb->callback_arg = pcb->callback_arg; +#if LWIP_CALLBACK_API + npcb->accept = pcb->accept; +#endif /* LWIP_CALLBACK_API */ + /* inherit socket options */ + npcb->so_options = pcb->so_options & SOF_INHERITED; + /* Register the new PCB so that we can begin receiving segments + for it. */ + TCP_REG_ACTIVE(npcb); + + /* Parse any options in the SYN. */ + tcp_parseopt(npcb); + npcb->snd_wnd = SND_WND_SCALE(npcb, tcphdr->wnd); + npcb->snd_wnd_max = npcb->snd_wnd; + npcb->ssthresh = npcb->snd_wnd; + +#if TCP_CALCULATE_EFF_SEND_MSS + npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, + &npcb->remote_ip, PCB_ISIPV6(npcb)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + snmp_inc_tcppassiveopens(); + + /* Send a SYN|ACK together with the MSS option. */ + rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); + if (rc != ERR_OK) { + tcp_abandon(npcb, 0); + return rc; + } + return tcp_output(npcb); + } + return ERR_OK; +} + +/** + * Called by tcp_input() when a segment arrives for a connection in + * TIME_WAIT. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_timewait_input(struct tcp_pcb *pcb) +{ + /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ + /* RFC 793 3.9 Event Processing - Segment Arrives: + * - first check sequence number - we skip that one in TIME_WAIT (always + * acceptable since we only send ACKs) + * - second check the RST bit (... return) */ + if (flags & TCP_RST) { + return ERR_OK; + } + /* - fourth, check the SYN bit, */ + if (flags & TCP_SYN) { + /* If an incoming segment is not acceptable, an acknowledgment + should be sent in reply */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt+pcb->rcv_wnd)) { + /* If the SYN is in the window it is an error, send a reset */ + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + return ERR_OK; + } + } else if (flags & TCP_FIN) { + /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. + Restart the 2 MSL time-wait timeout.*/ + pcb->tmr = tcp_ticks; + } + + if ((tcplen > 0)) { + /* Acknowledge data, FIN or out-of-window SYN */ + pcb->flags |= TF_ACK_NOW; + return tcp_output(pcb); + } + return ERR_OK; +} + +/** + * Implements the TCP state machine. Called by tcp_input. In some + * states tcp_receive() is called to receive data. The tcp_seg + * argument will be freed by the caller (tcp_input()) unless the + * recv_data pointer in the pcb is set. + * + * @param pcb the tcp_pcb for which a segment arrived + * + * @note the segment which arrived is saved in global variables, therefore only the pcb + * involved is passed as a parameter to this function + */ +static err_t +tcp_process(struct tcp_pcb *pcb) +{ + struct tcp_seg *rseg; + u8_t acceptable = 0; + err_t err; + + err = ERR_OK; + + /* Process incoming RST segments. */ + if (flags & TCP_RST) { + /* First, determine if the reset is acceptable. */ + if (pcb->state == SYN_SENT) { + if (ackno == pcb->snd_nxt) { + acceptable = 1; + } + } else { + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt+pcb->rcv_wnd)) { + acceptable = 1; + } + } + + if (acceptable) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); + LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); + recv_flags |= TF_RESET; + pcb->flags &= ~TF_ACK_DELAY; + return ERR_RST; + } else { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", + seqno, pcb->rcv_nxt)); + return ERR_OK; + } + } + + if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { + /* Cope with new connection attempt after remote end crashed */ + tcp_ack_now(pcb); + return ERR_OK; + } + + if ((pcb->flags & TF_RXCLOSED) == 0) { + /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ + pcb->tmr = tcp_ticks; + } + pcb->keep_cnt_sent = 0; + + tcp_parseopt(pcb); + + /* Do different things depending on the TCP state. */ + switch (pcb->state) { + case SYN_SENT: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, + pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno))); + /* received SYN ACK with expected sequence number? */ + if ((flags & TCP_ACK) && (flags & TCP_SYN) + && ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) { + pcb->snd_buf++; + pcb->rcv_nxt = seqno + 1; + pcb->rcv_ann_right_edge = pcb->rcv_nxt; + pcb->lastack = ackno; + pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); + pcb->snd_wnd_max = pcb->snd_wnd; + pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ + pcb->state = ESTABLISHED; + +#if TCP_CALCULATE_EFF_SEND_MSS + pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip, + PCB_ISIPV6(pcb)); +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + + /* Set ssthresh again after changing pcb->mss (already set in tcp_connect + * but for the default value of pcb->mss) */ + pcb->ssthresh = pcb->mss * 10; + + pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F + " ssthresh %"TCPWNDSIZE_F"\n", + pcb->cwnd, pcb->ssthresh)); + LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); + --pcb->snd_queuelen; + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); + rseg = pcb->unacked; + pcb->unacked = rseg->next; + tcp_seg_free(rseg); + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if(pcb->unacked == NULL) + pcb->rtime = -1; + else { + pcb->rtime = 0; + pcb->nrtx = 0; + } + + /* Call the user specified function to call when successfully + * connected. */ + TCP_EVENT_CONNECTED(pcb, ERR_OK, err); + if (err == ERR_ABRT) { + return ERR_ABRT; + } + tcp_ack_now(pcb); + } + /* received ACK? possibly a half-open connection */ + else if (flags & TCP_ACK) { + /* send a RST to bring the other side in a non-synchronized state. */ + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + } + break; + case SYN_RCVD: + if (flags & TCP_ACK) { + /* expected ACK number? */ + if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { + pcb->state = ESTABLISHED; + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); +#if LWIP_CALLBACK_API + LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL); +#endif + /* Call the accept function. */ + TCP_EVENT_ACCEPT(pcb, ERR_OK, err); + if (err != ERR_OK) { + /* If the accept function returns with an error, we abort + * the connection. */ + /* Already aborted? */ + if (err != ERR_ABRT) { + tcp_abort(pcb); + } + return ERR_ABRT; + } + /* If there was any data contained within this ACK, + * we'd better pass it on to the application as well. */ + tcp_receive(pcb); + + /* Prevent ACK for SYN to generate a sent event */ + if (pcb->acked != 0) { + pcb->acked--; + } + + pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F + " ssthresh %"TCPWNDSIZE_F"\n", + pcb->cwnd, pcb->ssthresh)); + + if (recv_flags & TF_GOT_FIN) { + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + } else { + /* incorrect ACK number, send RST */ + tcp_rst(ackno, seqno + tcplen, ipX_current_dest_addr(), + ipX_current_src_addr(), tcphdr->dest, tcphdr->src, ip_current_is_v6()); + } + } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { + /* Looks like another copy of the SYN - retransmit our SYN-ACK */ + tcp_rexmit(pcb); + } + break; + case CLOSE_WAIT: + /* FALLTHROUGH */ + case ESTABLISHED: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { /* passive close */ + tcp_ack_now(pcb); + pcb->state = CLOSE_WAIT; + } + break; + case FIN_WAIT_1: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_DEBUG, + ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } else { + tcp_ack_now(pcb); + pcb->state = CLOSING; + } + } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt)) { + pcb->state = FIN_WAIT_2; + } + break; + case FIN_WAIT_2: + tcp_receive(pcb); + if (recv_flags & TF_GOT_FIN) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_ack_now(pcb); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case CLOSING: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + tcp_pcb_purge(pcb); + TCP_RMV_ACTIVE(pcb); + pcb->state = TIME_WAIT; + TCP_REG(&tcp_tw_pcbs, pcb); + } + break; + case LAST_ACK: + tcp_receive(pcb); + if (flags & TCP_ACK && ackno == pcb->snd_nxt) { + LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); + /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ + recv_flags |= TF_CLOSED; + } + break; + default: + break; + } + return ERR_OK; +} + +#if TCP_QUEUE_OOSEQ +/** + * Insert segment into the list (segments covered with new one will be deleted) + * + * Called from tcp_receive() + */ +static void +tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) +{ + struct tcp_seg *old_seg; + + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + /* received segment overlaps all following segments */ + tcp_segs_free(next); + next = NULL; + } + else { + /* delete some following segments + oos queue may have segments with FIN flag */ + while (next && + TCP_SEQ_GEQ((seqno + cseg->len), + (next->tcphdr->seqno + next->len))) { + /* cseg with FIN already processed */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); + } + old_seg = next; + next = next->next; + tcp_seg_free(old_seg); + } + if (next && + TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { + /* We need to trim the incoming segment. */ + cseg->len = (u16_t)(next->tcphdr->seqno - seqno); + pbuf_realloc(cseg->p, cseg->len); + } + } + cseg->next = next; +} +#endif /* TCP_QUEUE_OOSEQ */ + +/** + * Called by tcp_process. Checks if the given segment is an ACK for outstanding + * data, and if so frees the memory of the buffered data. Next, is places the + * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment + * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until + * it has been removed from the buffer. + * + * If the incoming segment constitutes an ACK for a segment that was used for RTT + * estimation, the RTT is estimated here as well. + * + * Called from tcp_process(). + */ +static void +tcp_receive(struct tcp_pcb *pcb) +{ + struct tcp_seg *next; +#if TCP_QUEUE_OOSEQ + struct tcp_seg *prev, *cseg; +#endif /* TCP_QUEUE_OOSEQ */ + struct pbuf *p; + s32_t off; + s16_t m; + u32_t right_wnd_edge; + u16_t new_tot_len; + int found_dupack = 0; +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + u32_t ooseq_blen; + u16_t ooseq_qlen; +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ + + LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); + + if (flags & TCP_ACK) { + right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; + + /* Update window. */ + if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || + (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || + (pcb->snd_wl2 == ackno && tcphdr->wnd > pcb->snd_wnd)) { + pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); + /* keep track of the biggest window announced by the remote host to calculate + the maximum segment size */ + if (pcb->snd_wnd_max < pcb->snd_wnd) { + pcb->snd_wnd_max = pcb->snd_wnd; + } + pcb->snd_wl1 = seqno; + pcb->snd_wl2 = ackno; + if (pcb->snd_wnd == 0) { + if (pcb->persist_backoff == 0) { + /* start persist timer */ + pcb->persist_cnt = 0; + pcb->persist_backoff = 1; + } + } else if (pcb->persist_backoff > 0) { + /* stop persist timer */ + pcb->persist_backoff = 0; + } + LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"U16_F"\n", pcb->snd_wnd)); +#if TCP_WND_DEBUG + } else { + if (pcb->snd_wnd != tcphdr->wnd) { + LWIP_DEBUGF(TCP_WND_DEBUG, + ("tcp_receive: no window update lastack %"U32_F" ackno %" + U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", + pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); + } +#endif /* TCP_WND_DEBUG */ + } + + /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a + * duplicate ack if: + * 1) It doesn't ACK new data + * 2) length of received packet is zero (i.e. no payload) + * 3) the advertised window hasn't changed + * 4) There is outstanding unacknowledged data (retransmission timer running) + * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) + * + * If it passes all five, should process as a dupack: + * a) dupacks < 3: do nothing + * b) dupacks == 3: fast retransmit + * c) dupacks > 3: increase cwnd + * + * If it only passes 1-3, should reset dupack counter (and add to + * stats, which we don't do in lwIP) + * + * If it only passes 1, should reset dupack counter + * + */ + + /* Clause 1 */ + if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { + pcb->acked = 0; + /* Clause 2 */ + if (tcplen == 0) { + /* Clause 3 */ + if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge){ + /* Clause 4 */ + if (pcb->rtime >= 0) { + /* Clause 5 */ + if (pcb->lastack == ackno) { + found_dupack = 1; + if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { + ++pcb->dupacks; + } + if (pcb->dupacks > 3) { + /* Inflate the congestion window, but not if it means that + the value overflows. */ + if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + } else if (pcb->dupacks == 3) { + /* Do fast retransmit */ + tcp_rexmit_fast(pcb); + } + } + } + } + } + /* If Clause (1) or more is true, but not a duplicate ack, reset + * count of consecutive duplicate acks */ + if (!found_dupack) { + pcb->dupacks = 0; + } + } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)){ + /* We come here when the ACK acknowledges new data. */ + + /* Reset the "IN Fast Retransmit" flag, since we are no longer + in fast retransmit. Also reset the congestion window to the + slow start threshold. */ + if (pcb->flags & TF_INFR) { + pcb->flags &= ~TF_INFR; + pcb->cwnd = pcb->ssthresh; + } + + /* Reset the number of retransmissions. */ + pcb->nrtx = 0; + + /* Reset the retransmission time-out. */ + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + /* Update the send buffer space. Diff between the two can never exceed 64K + unless window scaling is used. */ + pcb->acked = (tcpwnd_size_t)(ackno - pcb->lastack); + + pcb->snd_buf += pcb->acked; + + /* Reset the fast retransmit variables. */ + pcb->dupacks = 0; + pcb->lastack = ackno; + + /* Update the congestion control variables (cwnd and + ssthresh). */ + if (pcb->state >= ESTABLISHED) { + if (pcb->cwnd < pcb->ssthresh) { + if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { + pcb->cwnd += pcb->mss; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); + } else { + tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); + if (new_cwnd > pcb->cwnd) { + pcb->cwnd = new_cwnd; + } + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); + } + } + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", + ackno, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno): 0, + pcb->unacked != NULL? + ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); + + /* Remove segment from the unacknowledged list if the incoming + ACK acknowledges them. */ + while (pcb->unacked != NULL && + TCP_SEQ_LEQ(ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked), ackno)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", + ntohl(pcb->unacked->tcphdr->seqno), + ntohl(pcb->unacked->tcphdr->seqno) + + TCP_TCPLEN(pcb->unacked))); + + next = pcb->unacked; + pcb->unacked = pcb->unacked->next; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + } + + /* If there's nothing left to acknowledge, stop the retransmit + timer, otherwise reset it to start again */ + if (pcb->unacked == NULL) { + pcb->rtime = -1; + } else { + pcb->rtime = 0; + } + + pcb->polltmr = 0; + +#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS + if (PCB_ISIPV6(pcb)) { + /* Inform neighbor reachability of forward progress. */ + nd6_reachability_hint(ip6_current_src_addr()); + } +#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ + } else { + /* Out of sequence ACK, didn't really ack anything */ + pcb->acked = 0; + tcp_send_empty_ack(pcb); + } + + /* We go through the ->unsent list to see if any of the segments + on the list are acknowledged by the ACK. This may seem + strange since an "unsent" segment shouldn't be acked. The + rationale is that lwIP puts all outstanding segments on the + ->unsent list after a retransmission, so these segments may + in fact have been sent once. */ + while (pcb->unsent != NULL && + TCP_SEQ_BETWEEN(ackno, ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", + ntohl(pcb->unsent->tcphdr->seqno), ntohl(pcb->unsent->tcphdr->seqno) + + TCP_TCPLEN(pcb->unsent))); + + next = pcb->unsent; + pcb->unsent = pcb->unsent->next; +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); + LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); + /* Prevent ACK for FIN to generate a sent event */ + if ((pcb->acked != 0) && ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0)) { + pcb->acked--; + } + pcb->snd_queuelen -= pbuf_clen(next->p); + tcp_seg_free(next); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_receive: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + } + /* End of ACK for new data processing. */ + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", + pcb->rttest, pcb->rtseq, ackno)); + + /* RTT estimation calculations. This is done by checking if the + incoming segment acknowledges the segment we use to take a + round-trip time measurement. */ + if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { + /* diff between this shouldn't exceed 32K since this are tcp timer ticks + and a round-trip shouldn't be that long... */ + m = (s16_t)(tcp_ticks - pcb->rttest); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", + m, m * TCP_SLOW_INTERVAL)); + + /* This is taken directly from VJs original code in his paper */ + m = m - (pcb->sa >> 3); + pcb->sa += m; + if (m < 0) { + m = -m; + } + m = m - (pcb->sv >> 2); + pcb->sv += m; + pcb->rto = (pcb->sa >> 3) + pcb->sv; + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", + pcb->rto, pcb->rto * TCP_SLOW_INTERVAL)); + + pcb->rttest = 0; + } + } + + /* If the incoming segment contains data, we must process it + further unless the pcb already received a FIN. + (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, + LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ + if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { + /* This code basically does three things: + + +) If the incoming segment contains data that is the next + in-sequence data, this data is passed to the application. This + might involve trimming the first edge of the data. The rcv_nxt + variable and the advertised window are adjusted. + + +) If the incoming segment has data that is above the next + sequence number expected (->rcv_nxt), the segment is placed on + the ->ooseq queue. This is done by finding the appropriate + place in the ->ooseq queue (which is ordered by sequence + number) and trim the segment in both ends if needed. An + immediate ACK is sent to indicate that we received an + out-of-sequence segment. + + +) Finally, we check if the first segment on the ->ooseq queue + now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If + rcv_nxt > ooseq->seqno, we must trim the first edge of the + segment on ->ooseq before we adjust rcv_nxt. The data in the + segments that are now on sequence are chained onto the + incoming segment so that we only need to call the application + once. + */ + + /* First, we check if we must trim the first edge. We have to do + this if the sequence number of the incoming segment is less + than rcv_nxt, and the sequence number plus the length of the + segment is larger than rcv_nxt. */ + /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ + if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)){ + /* Trimming the first edge is done by pushing the payload + pointer in the pbuf downwards. This is somewhat tricky since + we do not want to discard the full contents of the pbuf up to + the new starting point of the data since we have to keep the + TCP header which is present in the first pbuf in the chain. + + What is done is really quite a nasty hack: the first pbuf in + the pbuf chain is pointed to by inseg.p. Since we need to be + able to deallocate the whole pbuf, we cannot change this + inseg.p pointer to point to any of the later pbufs in the + chain. Instead, we point the ->payload pointer in the first + pbuf to data in one of the later pbufs. We also set the + inseg.data pointer to point to the right place. This way, the + ->p pointer will still point to the first pbuf, but the + ->p->payload pointer will point to data in another pbuf. + + After we are done with adjusting the pbuf pointers we must + adjust the ->data pointer in the seg and the segment + length.*/ + + off = pcb->rcv_nxt - seqno; + p = inseg.p; + LWIP_ASSERT("inseg.p != NULL", inseg.p); + LWIP_ASSERT("insane offset!", (off < 0x7fff)); + if (inseg.p->len < off) { + LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); + new_tot_len = (u16_t)(inseg.p->tot_len - off); + while (p->len < off) { + off -= p->len; + /* KJM following line changed (with addition of new_tot_len var) + to fix bug #9076 + inseg.p->tot_len -= p->len; */ + p->tot_len = new_tot_len; + p->len = 0; + p = p->next; + } + if(pbuf_header(p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } else { + if(pbuf_header(inseg.p, (s16_t)-off)) { + /* Do we need to cope with this failing? Assert for now */ + LWIP_ASSERT("pbuf_header failed", 0); + } + } + inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); + inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; + } + else { + if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)){ + /* the whole segment is < rcv_nxt */ + /* must be a duplicate of a packet that has already been correctly handled */ + + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); + tcp_ack_now(pcb); + } + } + + /* The sequence number must be within the window (above rcv_nxt + and below rcv_nxt + rcv_wnd) in order to be further + processed. */ + if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, + pcb->rcv_nxt + pcb->rcv_wnd - 1)){ + if (pcb->rcv_nxt == seqno) { + /* The incoming segment is the next in sequence. We check if + we have to trim the end of the segment and update rcv_nxt + and pass the data to the application. */ + tcplen = TCP_TCPLEN(&inseg); + + if (tcplen > pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + inseg.len = pcb->rcv_wnd; + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } +#if TCP_QUEUE_OOSEQ + /* Received in-sequence data, adjust ooseq data if: + - FIN has been received or + - inseq overlaps with ooseq */ + if (pcb->ooseq != NULL) { + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: received in-order FIN, binning ooseq queue\n")); + /* Received in-order FIN means anything that was received + * out of order must now have been received in-order, so + * bin the ooseq queue */ + while (pcb->ooseq != NULL) { + struct tcp_seg *old_ooseq = pcb->ooseq; + pcb->ooseq = pcb->ooseq->next; + tcp_seg_free(old_ooseq); + } + } else { + next = pcb->ooseq; + /* Remove all segments on ooseq that are covered by inseg already. + * FIN is copied from ooseq to inseg if present. */ + while (next && + TCP_SEQ_GEQ(seqno + tcplen, + next->tcphdr->seqno + next->len)) { + /* inseg cannot have FIN here (already processed above) */ + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN && + (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { + TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); + tcplen = TCP_TCPLEN(&inseg); + } + prev = next; + next = next->next; + tcp_seg_free(prev); + } + /* Now trim right side of inseg if it overlaps with the first + * segment on ooseq */ + if (next && + TCP_SEQ_GT(seqno + tcplen, + next->tcphdr->seqno)) { + /* inseg cannot have FIN here (already processed above) */ + inseg.len = (u16_t)(next->tcphdr->seqno - seqno); + if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { + inseg.len -= 1; + } + pbuf_realloc(inseg.p, inseg.len); + tcplen = TCP_TCPLEN(&inseg); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", + (seqno + tcplen) == next->tcphdr->seqno); + } + pcb->ooseq = next; + } + } +#endif /* TCP_QUEUE_OOSEQ */ + + pcb->rcv_nxt = seqno + tcplen; + + /* Update the receiver's (our) window. */ + LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); + pcb->rcv_wnd -= tcplen; + + tcp_update_rcv_ann_wnd(pcb); + + /* If there is data in the segment, we make preparations to + pass this up to the application. The ->recv_data variable + is used for holding the pbuf that goes to the + application. The code for reassembling out-of-sequence data + chains its data on this pbuf as well. + + If the segment was a FIN, we set the TF_GOT_FIN flag that will + be used to indicate to the application that the remote side has + closed its end of the connection. */ + if (inseg.p->tot_len > 0) { + recv_data = inseg.p; + /* Since this pbuf now is the responsibility of the + application, we delete our reference to it so that we won't + (mistakingly) deallocate it. */ + inseg.p = NULL; + } + if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); + recv_flags |= TF_GOT_FIN; + } + +#if TCP_QUEUE_OOSEQ + /* We now check if we have segments on the ->ooseq queue that + are now in sequence. */ + while (pcb->ooseq != NULL && + pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { + + cseg = pcb->ooseq; + seqno = pcb->ooseq->tcphdr->seqno; + + pcb->rcv_nxt += TCP_TCPLEN(cseg); + LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", + pcb->rcv_wnd >= TCP_TCPLEN(cseg)); + pcb->rcv_wnd -= TCP_TCPLEN(cseg); + + tcp_update_rcv_ann_wnd(pcb); + + if (cseg->p->tot_len > 0) { + /* Chain this pbuf onto the pbuf that we will pass to + the application. */ + /* With window scaling, this can overflow recv_data->tot_len, but + that's not a problem since we explicitly fix that before passing + recv_data to the application. */ + if (recv_data) { + pbuf_cat(recv_data, cseg->p); + } else { + recv_data = cseg->p; + } + cseg->p = NULL; + } + if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); + recv_flags |= TF_GOT_FIN; + if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ + pcb->state = CLOSE_WAIT; + } + } + + pcb->ooseq = cseg->next; + tcp_seg_free(cseg); + } +#endif /* TCP_QUEUE_OOSEQ */ + + + /* Acknowledge the segment(s). */ + tcp_ack(pcb); + +#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS + if (PCB_ISIPV6(pcb)) { + /* Inform neighbor reachability of forward progress. */ + nd6_reachability_hint(ip6_current_src_addr()); + } +#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ + + } else { + /* We get here if the incoming segment is out-of-sequence. */ + tcp_send_empty_ack(pcb); +#if TCP_QUEUE_OOSEQ + /* We queue the segment on the ->ooseq queue. */ + if (pcb->ooseq == NULL) { + pcb->ooseq = tcp_seg_copy(&inseg); + } else { + /* If the queue is not empty, we walk through the queue and + try to find a place where the sequence number of the + incoming segment is between the sequence numbers of the + previous and the next segment on the ->ooseq queue. That is + the place where we put the incoming segment. If needed, we + trim the second edges of the previous and the incoming + segment so that it will fit into the sequence. + + If the incoming segment has the same sequence number as a + segment on the ->ooseq queue, we discard the segment that + contains less data. */ + + prev = NULL; + for(next = pcb->ooseq; next != NULL; next = next->next) { + if (seqno == next->tcphdr->seqno) { + /* The sequence number of the incoming segment is the + same as the sequence number of the segment on + ->ooseq. We check the lengths to see which one to + discard. */ + if (inseg.len > next->len) { + /* The incoming segment is larger than the old + segment. We replace some segments with the new + one. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (prev != NULL) { + prev->next = cseg; + } else { + pcb->ooseq = cseg; + } + tcp_oos_insert_segment(cseg, next); + } + break; + } else { + /* Either the lengths are the same or the incoming + segment was smaller than the old one; in either + case, we ditch the incoming segment. */ + break; + } + } else { + if (prev == NULL) { + if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { + /* The sequence number of the incoming segment is lower + than the sequence number of the first segment on the + queue. We put the incoming segment first on the + queue. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + pcb->ooseq = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } else { + /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && + TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ + if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { + /* The sequence number of the incoming segment is in + between the sequence numbers of the previous and + the next segment on ->ooseq. We trim trim the previous + segment, delete next segments that included in received segment + and trim received, if needed. */ + cseg = tcp_seg_copy(&inseg); + if (cseg != NULL) { + if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { + /* We need to trim the prev segment. */ + prev->len = (u16_t)(seqno - prev->tcphdr->seqno); + pbuf_realloc(prev->p, prev->len); + } + prev->next = cseg; + tcp_oos_insert_segment(cseg, next); + } + break; + } + } + /* If the "next" segment is the last segment on the + ooseq queue, we add the incoming segment to the end + of the list. */ + if (next->next == NULL && + TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { + if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { + /* segment "next" already contains all data */ + break; + } + next->next = tcp_seg_copy(&inseg); + if (next->next != NULL) { + if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { + /* We need to trim the last segment. */ + next->len = (u16_t)(seqno - next->tcphdr->seqno); + pbuf_realloc(next->p, next->len); + } + /* check if the remote side overruns our receive window */ + if ((u32_t)tcplen + seqno > pcb->rcv_nxt + (u32_t)pcb->rcv_wnd) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, + ("tcp_receive: other end overran receive window" + "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", + seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); + if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { + /* Must remove the FIN from the header as we're trimming + * that byte of sequence-space from the packet */ + TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) &~ TCP_FIN); + } + /* Adjust length of segment to fit in the window. */ + next->next->len = pcb->rcv_nxt + pcb->rcv_wnd - seqno; + pbuf_realloc(next->next->p, next->next->len); + tcplen = TCP_TCPLEN(next->next); + LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", + (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); + } + } + break; + } + } + prev = next; + } + } +#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS + /* Check that the data on ooseq doesn't exceed one of the limits + and throw away everything above that limit. */ + ooseq_blen = 0; + ooseq_qlen = 0; + prev = NULL; + for(next = pcb->ooseq; next != NULL; prev = next, next = next->next) { + struct pbuf *p = next->p; + ooseq_blen += p->tot_len; + ooseq_qlen += pbuf_clen(p); + if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || + (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { + /* too much ooseq data, dump this and everything after it */ + tcp_segs_free(next); + if (prev == NULL) { + /* first ooseq segment is too much, dump the whole queue */ + pcb->ooseq = NULL; + } else { + /* just dump 'next' and everything after it */ + prev->next = NULL; + } + break; + } + } +#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ +#endif /* TCP_QUEUE_OOSEQ */ + } + } else { + /* The incoming segment is not within the window. */ + tcp_send_empty_ack(pcb); + } + } else { + /* Segments with length 0 is taken care of here. Segments that + fall out of the window are ACKed. */ + /*if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) || + TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {*/ + if(!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd-1)){ + tcp_ack_now(pcb); + } + } +} + +static u8_t tcp_getoptbyte(void) +{ + if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) { + u8_t* opts = (u8_t *)tcphdr + TCP_HLEN; + return opts[tcp_optidx++]; + } else { + u8_t idx = tcp_optidx++ - tcphdr_opt1len; + return tcphdr_opt2[idx]; + } +} + +/** + * Parses the options contained in the incoming segment. + * + * Called from tcp_listen_input() and tcp_process(). + * Currently, only the MSS option is supported! + * + * @param pcb the tcp_pcb for which a segment arrived + */ +static void +tcp_parseopt(struct tcp_pcb *pcb) +{ + u8_t data; + u16_t mss; +#if LWIP_TCP_TIMESTAMPS + u32_t tsval; +#endif + + /* Parse the TCP MSS option, if present. */ + if (TCPH_HDRLEN(tcphdr) > 0x5) { + u16_t max_c = (TCPH_HDRLEN(tcphdr) - 5) << 2; + for (tcp_optidx = 0; tcp_optidx < max_c; ) { + u8_t opt = tcp_getoptbyte(); + switch (opt) { + case LWIP_TCP_OPT_EOL: + /* End of options. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); + return; + case LWIP_TCP_OPT_NOP: + /* NOP option. */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); + break; + case LWIP_TCP_OPT_MSS: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); + if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* An MSS option with the right option length. */ + mss = (tcp_getoptbyte() << 8); + mss |= tcp_getoptbyte(); + /* Limit the mss to the configured TCP_MSS and prevent division by zero */ + pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; + break; +#if LWIP_WND_SCALE + case LWIP_TCP_OPT_WS: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n")); + if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* If syn was received with wnd scale option, + activate wnd scale opt */ + data = tcp_getoptbyte(); + if (flags & TCP_SYN) { + /* An WND_SCALE option with the right option length. */ + pcb->snd_scale = data; + if (pcb->snd_scale > 14U) { + pcb->snd_scale = 14U; + } + pcb->rcv_scale = TCP_RCV_SCALE; + pcb->flags |= TF_WND_SCALE; + } + break; +#endif +#if LWIP_TCP_TIMESTAMPS + case LWIP_TCP_OPT_TS: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); + if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > max_c) { + /* Bad length */ + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + return; + } + /* TCP timestamp option with valid length */ + tsval = tcp_getoptbyte(); + tsval |= (tcp_getoptbyte() << 8); + tsval |= (tcp_getoptbyte() << 16); + tsval |= (tcp_getoptbyte() << 24); + if (flags & TCP_SYN) { + pcb->ts_recent = ntohl(tsval); + /* Enable sending timestamps in every segment now that we know + the remote host supports it. */ + pcb->flags |= TF_TIMESTAMP; + } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { + pcb->ts_recent = ntohl(tsval); + } + /* Advance to next option (6 bytes already read) */ + tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; + break; +#endif + default: + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); + data = tcp_getoptbyte(); + if (data < 2) { + LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); + /* If the length field is zero, the options are malformed + and we don't process them further. */ + return; + } + /* All other options have a length field, so that we easily + can skip past them. */ + tcp_optidx += data - 2; + } + } + } +} + +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_out.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_out.c new file mode 100644 index 0000000..2aecbba --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/tcp_out.c @@ -0,0 +1,1578 @@ +/** + * @file + * Transmission Control Protocol, outgoing traffic + * + * The output functions of TCP. + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp_impl.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/memp.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/inet_chksum.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#if LWIP_TCP_TIMESTAMPS +#include "lwip/sys.h" +#endif + +#include + +/* Define some copy-macros for checksum-on-copy so that the code looks + nicer by preventing too many ifdef's. */ +#if TCP_CHECKSUM_ON_COPY +#define TCP_DATA_COPY(dst, src, len, seg) do { \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ + len, &seg->chksum, &seg->chksum_swapped); \ + seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ + tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); +#else /* TCP_CHECKSUM_ON_COPY*/ +#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) +#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) +#endif /* TCP_CHECKSUM_ON_COPY*/ + +/** Define this to 1 for an extra check that the output checksum is valid + * (usefule when the checksum is generated by the application, not the stack) */ +#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 +#endif +/* Allow to override the failure of sanity check from warning to e.g. hard failure */ +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK +#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL +#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg) +#endif +#endif + +#if TCP_OVERSIZE +/** The size of segment pbufs created when TCP_OVERSIZE is enabled */ +#ifndef TCP_OVERSIZE_CALC_LENGTH +#define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE) +#endif +#endif + +/* Forward declarations.*/ +static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb); + +/** Allocate a pbuf and create a tcphdr at p->payload, used for output + * functions other than the default tcp_output -> tcp_output_segment + * (e.g. tcp_send_empty_ack, etc.) + * + * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) + * @param optlen length of header-options + * @param datalen length of tcp data to reserve in pbuf + * @param seqno_be seqno in network byte order (big-endian) + * @return pbuf with p->payload being the tcp_hdr + */ +static struct pbuf * +tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, + u32_t seqno_be /* already in network byte order */) +{ + struct tcp_hdr *tcphdr; + struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); + if (p == NULL) { + p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_POOL); + } + + if (p != NULL) { + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= TCP_HLEN + optlen)); + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(pcb->local_port); + tcphdr->dest = htons(pcb->remote_port); + tcphdr->seqno = seqno_be; + tcphdr->ackno = htonl(pcb->rcv_nxt); + TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); + tcphdr->wnd = htons(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)); + tcphdr->chksum = 0; + tcphdr->urgp = 0; + + /* If we're sending a packet, update the announced right window edge */ + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + } + return p; +} + +/** + * Called by tcp_close() to send a segment including FIN flag but not data. + * + * @param pcb the tcp_pcb over which to send a segment + * @return ERR_OK if sent, another err_t otherwise + */ +err_t +tcp_send_fin(struct tcp_pcb *pcb) +{ + /* first, try to add the fin to the last unsent segment */ + if (pcb->unsent != NULL) { + struct tcp_seg *last_unsent; + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { + /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ + TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); + pcb->flags |= TF_FIN; + return ERR_OK; + } + } + /* no data, no length, flags, copy=1, no optdata */ + return tcp_enqueue_flags(pcb, TCP_FIN); +} + +/** + * Create a TCP segment with prefilled header. + * + * Called by tcp_write and tcp_enqueue_flags. + * + * @param pcb Protocol control block for the TCP connection. + * @param p pbuf that is used to hold the TCP header. + * @param flags TCP flags for header. + * @param seqno TCP sequence number of this packet + * @param optflags options to include in TCP header + * @return a new tcp_seg pointing to p, or NULL. + * The TCP header is filled in except ackno and wnd. + * p is freed on failure. + */ +static struct tcp_seg * +tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) +{ + struct tcp_seg *seg; + u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); + + if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no memory.\n")); + pbuf_free(p); + return NULL; + } + seg->flags = optflags; + seg->next = NULL; + seg->p = p; + LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen); + seg->len = p->tot_len - optlen; +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = 0; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = 0; + seg->chksum_swapped = 0; + /* check optflags */ + LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", + (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* build TCP header */ + if (pbuf_header(p, TCP_HLEN)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_create_segment: no room for TCP header in pbuf.\n")); + TCP_STATS_INC(tcp.err); + tcp_seg_free(seg); + return NULL; + } + seg->tcphdr = (struct tcp_hdr *)seg->p->payload; + seg->tcphdr->src = htons(pcb->local_port); + seg->tcphdr->dest = htons(pcb->remote_port); + seg->tcphdr->seqno = htonl(seqno); + /* ackno is set in tcp_output */ + TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); + /* wnd and chksum are set in tcp_output */ + seg->tcphdr->urgp = 0; + return seg; +} + +/** + * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. + * + * This function is like pbuf_alloc(layer, length, PBUF_RAM) except + * there may be extra bytes available at the end. + * + * @param layer flag to define header size. + * @param length size of the pbuf's payload. + * @param max_length maximum usable size of payload+oversize. + * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. + * @param pcb The TCP connection that willo enqueue the pbuf. + * @param apiflags API flags given to tcp_write. + * @param first_seg true when this pbuf will be used in the first enqueued segment. + * @param + */ +#if TCP_OVERSIZE +static struct pbuf * +tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, + u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, + u8_t first_seg) +{ + struct pbuf *p; + u16_t alloc = length; + +#if LWIP_NETIF_TX_SINGLE_PBUF + LWIP_UNUSED_ARG(max_length); + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(apiflags); + LWIP_UNUSED_ARG(first_seg); + /* always create MSS-sized pbufs */ + alloc = max_length; +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (length < max_length) { + /* Should we allocate an oversized pbuf, or just the minimum + * length required? If tcp_write is going to be called again + * before this segment is transmitted, we want the oversized + * buffer. If the segment will be transmitted immediately, we can + * save memory by allocating only length. We use a simple + * heuristic based on the following information: + * + * Did the user set TCP_WRITE_FLAG_MORE? + * + * Will the Nagle algorithm defer transmission of this segment? + */ + if ((apiflags & TCP_WRITE_FLAG_MORE) || + (!(pcb->flags & TF_NODELAY) && + (!first_seg || + pcb->unsent != NULL || + pcb->unacked != NULL))) { + alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length))); + } + } +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + p = pbuf_alloc(layer, alloc, PBUF_RAM); + if (p == NULL) { + return NULL; + } + LWIP_ASSERT("need unchained pbuf", p->next == NULL); + *oversize = p->len - length; + /* trim p->len to the currently used size */ + p->len = p->tot_len = length; + return p; +} +#else /* TCP_OVERSIZE */ +#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) +#endif /* TCP_OVERSIZE */ + +#if TCP_CHECKSUM_ON_COPY +/** Add a checksum of newly added data to the segment */ +static void +tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, + u8_t *seg_chksum_swapped) +{ + u32_t helper; + /* add chksum to old chksum and fold to u16_t */ + helper = chksum + *seg_chksum; + chksum = FOLD_U32T(helper); + if ((len & 1) != 0) { + *seg_chksum_swapped = 1 - *seg_chksum_swapped; + chksum = SWAP_BYTES_IN_WORD(chksum); + } + *seg_chksum = chksum; +} +#endif /* TCP_CHECKSUM_ON_COPY */ + +/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). + * + * @param pcb the tcp pcb to check for + * @param len length of data to send (checked agains snd_buf) + * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise + */ +static err_t +tcp_write_checks(struct tcp_pcb *pcb, u16_t len) +{ + /* connection is in invalid state for data transmission? */ + if ((pcb->state != ESTABLISHED) && + (pcb->state != CLOSE_WAIT) && + (pcb->state != SYN_SENT) && + (pcb->state != SYN_RCVD)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); + return ERR_CONN; + } else if (len == 0) { + return ERR_OK; + } + + /* fail on too much data */ + if (len > pcb->snd_buf) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"U16_F")\n", + len, pcb->snd_buf)); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); + + /* If total number of pbufs on the unsent/unacked queues exceeds the + * configured maximum, return an error */ + /* check for configured max queuelen and possible overflow */ + if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_write: too long queue %"TCPWNDSIZE_F" (max %"TCPWNDSIZE_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", + pcb->unacked != NULL || pcb->unsent != NULL); + } else { + LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", + pcb->unacked == NULL && pcb->unsent == NULL); + } + return ERR_OK; +} + +/** + * Write data for sending (but does not send it immediately). + * + * It waits in the expectation of more data being sent soon (as + * it can send them more efficiently by combining them together). + * To prompt the system to send data now, call tcp_output() after + * calling tcp_write(). + * + * @param pcb Protocol control block for the TCP connection to enqueue data for. + * @param arg Pointer to the data to be enqueued for sending. + * @param len Data length in bytes + * @param apiflags combination of following flags : + * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack + * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will be set on last segment sent, + * @return ERR_OK if enqueued, another err_t on error + */ +err_t +tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) +{ + struct pbuf *concat_p = NULL; + struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; + u16_t pos = 0; /* position in 'arg' data */ + u16_t queuelen; + u8_t optlen = 0; + u8_t optflags = 0; +#if TCP_OVERSIZE + u16_t oversize = 0; + u16_t oversize_used = 0; +#endif /* TCP_OVERSIZE */ +#if TCP_CHECKSUM_ON_COPY + u16_t concat_chksum = 0; + u8_t concat_chksum_swapped = 0; + u16_t concat_chksummed = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + err_t err; + /* don't allocate segments bigger than half the maximum window we ever received */ + u16_t mss_local = LWIP_MIN(pcb->mss, pcb->snd_wnd_max/2); + mss_local = mss_local ? mss_local : pcb->mss; + +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Always copy to try to create single pbufs for TX */ + apiflags |= TCP_WRITE_FLAG_COPY; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", + (void *)pcb, arg, len, (u16_t)apiflags)); + LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", + arg != NULL, return ERR_ARG;); + + err = tcp_write_checks(pcb, len); + if (err != ERR_OK) { + return err; + } + queuelen = pcb->snd_queuelen; + +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + /* Make sure the timestamp option is only included in data segments if we + agreed about it with the remote host. */ + optflags = TF_SEG_OPTS_TS; + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + /* ensure that segments can hold at least one data byte... */ + mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1); + } +#endif /* LWIP_TCP_TIMESTAMPS */ + + + /* + * TCP segmentation is done in three phases with increasing complexity: + * + * 1. Copy data directly into an oversized pbuf. + * 2. Chain a new pbuf to the end of pcb->unsent. + * 3. Create new segments. + * + * We may run out of memory at any point. In that case we must + * return ERR_MEM and not change anything in pcb. Therefore, all + * changes are recorded in local variables and committed at the end + * of the function. Some pcb fields are maintained in local copies: + * + * queuelen = pcb->snd_queuelen + * oversize = pcb->unsent_oversize + * + * These variables are set consistently by the phases: + * + * seg points to the last segment tampered with. + * + * pos records progress as data is segmented. + */ + + /* Find the tail of the unsent queue. */ + if (pcb->unsent != NULL) { + u16_t space; + u16_t unsent_optlen; + + /* @todo: this could be sped up by keeping last_unsent in the pcb */ + for (last_unsent = pcb->unsent; last_unsent->next != NULL; + last_unsent = last_unsent->next); + + /* Usable space at the end of the last unsent segment */ + unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); + LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen); + space = mss_local - (last_unsent->len + unsent_optlen); + + /* + * Phase 1: Copy data directly into an oversized pbuf. + * + * The number of bytes copied is recorded in the oversize_used + * variable. The actual copying is done at the bottom of the + * function. + */ +#if TCP_OVERSIZE +#if TCP_OVERSIZE_DBGCHECK + /* check that pcb->unsent_oversize matches last_unsent->unsent_oversize */ + LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", + pcb->unsent_oversize == last_unsent->oversize_left); +#endif /* TCP_OVERSIZE_DBGCHECK */ + oversize = pcb->unsent_oversize; + if (oversize > 0) { + LWIP_ASSERT("inconsistent oversize vs. space", oversize_used <= space); + seg = last_unsent; + oversize_used = oversize < len ? oversize : len; + pos += oversize_used; + oversize -= oversize_used; + space -= oversize_used; + } + /* now we are either finished or oversize is zero */ + LWIP_ASSERT("inconsistend oversize vs. len", (oversize == 0) || (pos == len)); +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: Chain a new pbuf to the end of pcb->unsent. + * + * We don't extend segments containing SYN/FIN flags or options + * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at + * the end. + */ + if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { + u16_t seglen = space < len - pos ? space : len - pos; + seg = last_unsent; + + /* Create a pbuf with a copy or reference to seglen bytes. We + * can use PBUF_RAW here since the data appears in the middle of + * a segment. A header will never be prepended. */ + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* Data is copied */ + if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", + seglen)); + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + last_unsent->oversize_left += oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ + TCP_DATA_COPY2(concat_p->payload, (u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); +#if TCP_CHECKSUM_ON_COPY + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + } else { + /* Data is not copied */ + if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, + ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + tcp_seg_add_chksum(~inet_chksum((u8_t*)arg + pos, seglen), seglen, + &concat_chksum, &concat_chksum_swapped); + concat_chksummed += seglen; +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + concat_p->payload = (u8_t*)arg + pos; + } + + pos += seglen; + queuelen += pbuf_clen(concat_p); + } + } else { +#if TCP_OVERSIZE + LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", + pcb->unsent_oversize == 0); +#endif /* TCP_OVERSIZE */ + } + + /* + * Phase 3: Create new segments. + * + * The new segments are chained together in the local 'queue' + * variable, ready to be appended to pcb->unsent. + */ + while (pos < len) { + struct pbuf *p; + u16_t left = len - pos; + u16_t max_len = mss_local - optlen; + u16_t seglen = left > max_len ? max_len : left; +#if TCP_CHECKSUM_ON_COPY + u16_t chksum = 0; + u8_t chksum_swapped = 0; +#endif /* TCP_CHECKSUM_ON_COPY */ + + if (apiflags & TCP_WRITE_FLAG_COPY) { + /* If copy is set, memory should be allocated and data copied + * into pbuf */ + if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); + goto memerr; + } + LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", + (p->len >= seglen)); + TCP_DATA_COPY2((char *)p->payload + optlen, (u8_t*)arg + pos, seglen, &chksum, &chksum_swapped); + } else { + /* Copy is not set: First allocate a pbuf for holding the data. + * Since the referenced data is available at least until it is + * sent out on the link (as it has to be ACKed by the remote + * party) we can safely use PBUF_ROM instead of PBUF_REF here. + */ + struct pbuf *p2; +#if TCP_OVERSIZE + LWIP_ASSERT("oversize == 0", oversize == 0); +#endif /* TCP_OVERSIZE */ + if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); + goto memerr; + } +#if TCP_CHECKSUM_ON_COPY + /* calculate the checksum of nocopy-data */ + chksum = ~inet_chksum((u8_t*)arg + pos, seglen); + if (seglen & 1) { + chksum_swapped = 1; + chksum = SWAP_BYTES_IN_WORD(chksum); + } +#endif /* TCP_CHECKSUM_ON_COPY */ + /* reference the non-volatile payload data */ + p2->payload = (u8_t*)arg + pos; + + /* Second, allocate a pbuf for the headers. */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + /* If allocation fails, we have to deallocate the data pbuf as + * well. */ + pbuf_free(p2); + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: could not allocate memory for header pbuf\n")); + goto memerr; + } + /* Concatenate the headers and data pbufs together. */ + pbuf_cat(p/*header*/, p2/*data*/); + } + + queuelen += pbuf_clen(p); + + /* Now that there are more segments queued, we check again if the + * length of the queue exceeds the configured maximum or + * overflows. */ + if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 2, ("tcp_write: queue too long %"TCPWNDSIZE_F" (%"TCPWNDSIZE_F")\n", queuelen, TCP_SND_QUEUELEN)); + pbuf_free(p); + goto memerr; + } + + if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { + goto memerr; + } +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = oversize; +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + seg->chksum = chksum; + seg->chksum_swapped = chksum_swapped; + seg->flags |= TF_SEG_DATA_CHECKSUMMED; +#endif /* TCP_CHECKSUM_ON_COPY */ + + /* first segment of to-be-queued data? */ + if (queue == NULL) { + queue = seg; + } else { + /* Attach the segment to the end of the queued segments */ + LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); + prev_seg->next = seg; + } + /* remember last segment of to-be-queued data for next iteration */ + prev_seg = seg; + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); + + pos += seglen; + } + + /* + * All three segmentation phases were successful. We can commit the + * transaction. + */ + + /* + * Phase 1: If data has been added to the preallocated tail of + * last_unsent, we update the length fields of the pbuf chain. + */ +#if TCP_OVERSIZE + if (oversize_used > 0) { + struct pbuf *p; + /* Bump tot_len of whole chain, len of tail */ + for (p = last_unsent->p; p; p = p->next) { + p->tot_len += oversize_used; + if (p->next == NULL) { + TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); + p->len += oversize_used; + } + } + last_unsent->len += oversize_used; +#if TCP_OVERSIZE_DBGCHECK + LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", + last_unsent->oversize_left >= oversize_used); + last_unsent->oversize_left -= oversize_used; +#endif /* TCP_OVERSIZE_DBGCHECK */ + } + pcb->unsent_oversize = oversize; +#endif /* TCP_OVERSIZE */ + + /* + * Phase 2: concat_p can be concatenated onto last_unsent->p + */ + if (concat_p != NULL) { + LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", + (last_unsent != NULL)); + pbuf_cat(last_unsent->p, concat_p); + last_unsent->len += concat_p->tot_len; +#if TCP_CHECKSUM_ON_COPY + if (concat_chksummed) { + /*if concat checksumm swapped - swap it back */ + if (concat_chksum_swapped){ + concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum); + } + tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, + &last_unsent->chksum_swapped); + last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; + } +#endif /* TCP_CHECKSUM_ON_COPY */ + } + + /* + * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that + * is harmless + */ + if (last_unsent == NULL) { + pcb->unsent = queue; + } else { + last_unsent->next = queue; + } + + /* + * Finally update the pcb state. + */ + pcb->snd_lbb += len; + pcb->snd_buf -= len; + pcb->snd_queuelen = queuelen; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", + pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + /* Set the PSH flag in the last segment that we enqueued. */ + if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { + TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); + } + + return ERR_OK; +memerr: + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + + if (concat_p != NULL) { + pbuf_free(concat_p); + } + if (queue != NULL) { + tcp_segs_free(queue); + } + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || + pcb->unsent != NULL); + } + LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); + return ERR_MEM; +} + +/** + * Enqueue TCP options for transmission. + * + * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl(). + * + * @param pcb Protocol control block for the TCP connection. + * @param flags TCP header flags to set in the outgoing segment. + * @param optdata pointer to TCP options, or NULL. + * @param optlen length of TCP options in bytes. + */ +err_t +tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) +{ + struct pbuf *p; + struct tcp_seg *seg; + u8_t optflags = 0; + u8_t optlen = 0; + + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); + + LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", + (flags & (TCP_SYN | TCP_FIN)) != 0); + + /* check for configured max queuelen and possible overflow (FIN flag should always come through!) */ + if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) && + ((flags & TCP_FIN) == 0)) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", + pcb->snd_queuelen, TCP_SND_QUEUELEN)); + TCP_STATS_INC(tcp.memerr); + pcb->flags |= TF_NAGLEMEMERR; + return ERR_MEM; + } + + if (flags & TCP_SYN) { + optflags = TF_SEG_OPTS_MSS; +#if LWIP_WND_SCALE + if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) { + /* In a (sent in state SYN_RCVD), the window scale option may only + be sent if we received a window scale option from the remote host. */ + optflags |= TF_SEG_OPTS_WND_SCALE; + } +#endif /* LWIP_WND_SCALE */ + } +#if LWIP_TCP_TIMESTAMPS + if ((pcb->flags & TF_TIMESTAMP)) { + /* Make sure the timestamp option is only included in data segments if we + agreed about it with the remote host. */ + optflags |= TF_SEG_OPTS_TS; + } +#endif /* LWIP_TCP_TIMESTAMPS */ + optlen = LWIP_TCP_OPT_LENGTH(optflags); + + /* tcp_enqueue_flags is always called with either SYN or FIN in flags. + * We need one available snd_buf byte to do that. + * This means we can't send FIN while snd_buf==0. A better fix would be to + * not include SYN and FIN sequence numbers in the snd_buf count. */ + if (pcb->snd_buf == 0) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | 3, ("tcp_enqueue_flags: no send buffer available\n")); + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + + /* Allocate pbuf with room for TCP header + options */ + if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", + (p->len >= optlen)); + + /* Allocate memory for tcp_seg, and fill in fields. */ + if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { + pcb->flags |= TF_NAGLEMEMERR; + TCP_STATS_INC(tcp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % 4) == 0); + LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); + + LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, + ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", + ntohl(seg->tcphdr->seqno), + ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), + (u16_t)flags)); + + /* Now append seg to pcb->unsent queue */ + if (pcb->unsent == NULL) { + pcb->unsent = seg; + } else { + struct tcp_seg *useg; + for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); + useg->next = seg; + } +#if TCP_OVERSIZE + /* The new unsent tail has no space */ + pcb->unsent_oversize = 0; +#endif /* TCP_OVERSIZE */ + + /* SYN and FIN bump the sequence number */ + if ((flags & TCP_SYN) || (flags & TCP_FIN)) { + pcb->snd_lbb++; + /* optlen does not influence snd_buf */ + pcb->snd_buf--; + } + if (flags & TCP_FIN) { + pcb->flags |= TF_FIN; + } + + /* update number of segments on the queues */ + pcb->snd_queuelen += pbuf_clen(seg->p); + LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); + if (pcb->snd_queuelen != 0) { + LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", + pcb->unacked != NULL || pcb->unsent != NULL); + } + + return ERR_OK; +} + +#if LWIP_TCP_TIMESTAMPS +/* Build a timestamp option (12 bytes long) at the specified options pointer) + * + * @param pcb tcp_pcb + * @param opts option pointer where to store the timestamp option + */ +static void +tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) +{ + /* Pad with two NOP options to make everything nicely aligned */ + opts[0] = PP_HTONL(0x0101080A); + opts[1] = htonl(sys_now()); + opts[2] = htonl(pcb->ts_recent); +} +#endif + +#if LWIP_WND_SCALE +/** Build a window scale option (3 bytes long) at the specified options pointer) + * + * @param opts option pointer where to store the window scale option + */ +static void +tcp_build_wnd_scale_option(u32_t *opts) +{ + /* Pad with one NOP option to make everything nicely aligned */ + opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE); +} +#endif + +/** Send an ACK without data. + * + * @param pcb Protocol control block for the TCP connection to send the ACK + */ +err_t +tcp_send_empty_ack(struct tcp_pcb *pcb) +{ + struct pbuf *p; + u8_t optlen = 0; +#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP + struct tcp_hdr *tcphdr; +#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ + +#if LWIP_TCP_TIMESTAMPS + if (pcb->flags & TF_TIMESTAMP) { + optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); + } +#endif + + p = tcp_output_alloc_header(pcb, optlen, 0, htonl(pcb->snd_nxt)); + if (p == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); + return ERR_BUF; + } +#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP + tcphdr = (struct tcp_hdr *)p->payload; +#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, + ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); + /* remove ACK flags from the PCB, as we send an empty ACK now */ + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + + /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */ +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (pcb->flags & TF_TIMESTAMP) { + tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); + } +#endif + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); +#endif +#if LWIP_NETIF_HWADDRHINT + ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, + IP_PROTO_TCP, &pcb->addr_hint); +#else /* LWIP_NETIF_HWADDRHINT*/ + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, + IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + pbuf_free(p); + + return ERR_OK; +} + +/** + * Find out what we can send and send it + * + * @param pcb Protocol control block for the TCP connection to send data + * @return ERR_OK if data has been sent or nothing to send + * another err_t on error + */ +err_t +tcp_output(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg, *useg; + u32_t wnd, snd_nxt; +#if TCP_CWND_DEBUG + s16_t i = 0; +#endif /* TCP_CWND_DEBUG */ + + /* pcb->state LISTEN not allowed here */ + LWIP_ASSERT("don't call tcp_output for listen-pcbs", + pcb->state != LISTEN); + + /* First, check if we are invoked by the TCP input processing + code. If so, we do not output anything. Instead, we rely on the + input processing code to call us when input processing is done + with. */ + if (tcp_input_pcb == pcb) { + return ERR_OK; + } + + wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); + + seg = pcb->unsent; + + /* If the TF_ACK_NOW flag is set and no data will be sent (either + * because the ->unsent queue is empty or because the window does + * not allow it), construct an empty ACK segment and send it. + * + * If data is to be sent, we will just piggyback the ACK (see below). + */ + if (pcb->flags & TF_ACK_NOW && + (seg == NULL || + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { + return tcp_send_empty_ack(pcb); + } + + /* useg should point to last segment on unacked queue */ + useg = pcb->unacked; + if (useg != NULL) { + for (; useg->next != NULL; useg = useg->next); + } + +#if TCP_OUTPUT_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", + (void*)pcb->unsent)); + } +#endif /* TCP_OUTPUT_DEBUG */ +#if TCP_CWND_DEBUG + if (seg == NULL) { + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F + ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F + ", seg == NULL, ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); + } else { + LWIP_DEBUGF(TCP_CWND_DEBUG, + ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F + ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, + ntohl(seg->tcphdr->seqno), pcb->lastack)); + } +#endif /* TCP_CWND_DEBUG */ + /* data available and window allows it to be sent? */ + while (seg != NULL && + ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { + LWIP_ASSERT("RST not expected here!", + (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); + /* Stop sending if the nagle algorithm would prevent it + * Don't stop: + * - if tcp_write had a memory error before (prevent delayed ACK timeout) or + * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - + * either seg->next != NULL or pcb->unacked == NULL; + * RST is no sent using tcp_write/tcp_output. + */ + if((tcp_do_output_nagle(pcb) == 0) && + ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)){ + break; + } +#if TCP_CWND_DEBUG + LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", + pcb->snd_wnd, pcb->cwnd, wnd, + ntohl(seg->tcphdr->seqno) + seg->len - + pcb->lastack, + ntohl(seg->tcphdr->seqno), pcb->lastack, i)); + ++i; +#endif /* TCP_CWND_DEBUG */ + + pcb->unsent = seg->next; + + if (pcb->state != SYN_SENT) { + TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); + pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); + } + +#if TCP_OVERSIZE_DBGCHECK + seg->oversize_left = 0; +#endif /* TCP_OVERSIZE_DBGCHECK */ + tcp_output_segment(seg, pcb); + snd_nxt = ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); + if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { + pcb->snd_nxt = snd_nxt; + } + /* put segment on unacknowledged list if length > 0 */ + if (TCP_TCPLEN(seg) > 0) { + seg->next = NULL; + /* unacked list is empty? */ + if (pcb->unacked == NULL) { + pcb->unacked = seg; + useg = seg; + /* unacked list is not empty? */ + } else { + /* In the case of fast retransmit, the packet should not go to the tail + * of the unacked queue, but rather somewhere before it. We need to check for + * this case. -STJ Jul 27, 2004 */ + if (TCP_SEQ_LT(ntohl(seg->tcphdr->seqno), ntohl(useg->tcphdr->seqno))) { + /* add segment to before tail of unacked list, keeping the list sorted */ + struct tcp_seg **cur_seg = &(pcb->unacked); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = (*cur_seg); + (*cur_seg) = seg; + } else { + /* add segment to tail of unacked list */ + useg->next = seg; + useg = useg->next; + } + } + /* do not queue empty segments on the unacked list */ + } else { + tcp_seg_free(seg); + } + seg = pcb->unsent; + } +#if TCP_OVERSIZE + if (pcb->unsent == NULL) { + /* last unsent has been removed, reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + pcb->flags &= ~TF_NAGLEMEMERR; + return ERR_OK; +} + +/** + * Called by tcp_output() to actually send a TCP segment over IP. + * + * @param seg the tcp_seg to send + * @param pcb the tcp_pcb for the TCP connection used to send the segment + */ +static void +tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb) +{ + u16_t len; + u32_t *opts; + + /** @bug Exclude retransmitted segments from this count. */ + snmp_inc_tcpoutsegs(); + + /* The TCP header has already been constructed, but the ackno and + wnd fields remain. */ + seg->tcphdr->ackno = htonl(pcb->rcv_nxt); + + /* advertise our receive window size in this TCP segment */ +#if LWIP_WND_SCALE + if (seg->flags & TF_SEG_OPTS_WND_SCALE) { + /* The Window field in a SYN segment itself (the only type where we send + the window scale option) is never scaled. */ + seg->tcphdr->wnd = htons(pcb->rcv_ann_wnd); + } else +#endif /* LWIP_WND_SCALE */ + { + seg->tcphdr->wnd = htons(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd)); + } + + pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; + + /* Add any requested options. NB MSS option is only set on SYN + packets, so ignore it here */ + opts = (u32_t *)(void *)(seg->tcphdr + 1); + if (seg->flags & TF_SEG_OPTS_MSS) { + u16_t mss; +#if TCP_CALCULATE_EFF_SEND_MSS + mss = tcp_eff_send_mss(TCP_MSS, &pcb->local_ip, &pcb->remote_ip, PCB_ISIPV6(pcb)); +#else /* TCP_CALCULATE_EFF_SEND_MSS */ + mss = TCP_MSS; +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + *opts = TCP_BUILD_MSS_OPTION(mss); + opts += 1; + } +#if LWIP_TCP_TIMESTAMPS + pcb->ts_lastacksent = pcb->rcv_nxt; + + if (seg->flags & TF_SEG_OPTS_TS) { + tcp_build_timestamp_option(pcb, opts); + opts += 3; + } +#endif +#if LWIP_WND_SCALE + if (seg->flags & TF_SEG_OPTS_WND_SCALE) { + tcp_build_wnd_scale_option(opts); + opts += 1; + } +#endif + + /* Set retransmission timer running if it is not currently enabled + This must be set before checking the route. */ + if (pcb->rtime == -1) { + pcb->rtime = 0; + } + + /* If we don't have a local IP address, we get one by + calling ip_route(). */ + if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) { + struct netif *netif; + ipX_addr_t *local_ip; + ipX_route_get_local_ipX(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip, netif, local_ip); + if ((netif == NULL) || (local_ip == NULL)) { + return; + } + ipX_addr_copy(PCB_ISIPV6(pcb), pcb->local_ip, *local_ip); + } + + if (pcb->rttest == 0) { + pcb->rttest = tcp_ticks; + pcb->rtseq = ntohl(seg->tcphdr->seqno); + + LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); + } + LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", + htonl(seg->tcphdr->seqno), htonl(seg->tcphdr->seqno) + + seg->len)); + + len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); + + seg->p->len -= len; + seg->p->tot_len -= len; + + seg->p->payload = seg->tcphdr; + + seg->tcphdr->chksum = 0; +#if TCP_CHECKSUM_ON_COPY + { + u32_t acc; +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + u16_t chksum_slow = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { + LWIP_ASSERT("data included but not checksummed", + seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4)); + } + + /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ + acc = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip); + /* add payload checksum */ + if (seg->chksum_swapped) { + seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); + seg->chksum_swapped = 0; + } + acc += (u16_t)~(seg->chksum); + seg->tcphdr->chksum = FOLD_U32T(acc); +#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK + if (chksum_slow != seg->tcphdr->chksum) { + TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL( + ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", + seg->tcphdr->chksum, chksum_slow)); + seg->tcphdr->chksum = chksum_slow; + } +#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ + } +#else /* TCP_CHECKSUM_ON_COPY */ +#if CHECKSUM_GEN_TCP + seg->tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), seg->p, IP_PROTO_TCP, + seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); +#endif /* CHECKSUM_GEN_TCP */ +#endif /* TCP_CHECKSUM_ON_COPY */ + TCP_STATS_INC(tcp.xmit); + +#if LWIP_NETIF_HWADDRHINT + ipX_output_hinted(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, + pcb->ttl, pcb->tos, IP_PROTO_TCP, &pcb->addr_hint); +#else /* LWIP_NETIF_HWADDRHINT*/ + ipX_output(PCB_ISIPV6(pcb), seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + pcb->tos, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ +} + +/** + * Send a TCP RESET packet (empty segment with RST flag set) either to + * abort a connection or to show that there is no matching local connection + * for a received segment. + * + * Called by tcp_abort() (to abort a local connection), tcp_input() (if no + * matching local pcb was found), tcp_listen_input() (if incoming segment + * has ACK flag set) and tcp_process() (received segment in the wrong state) + * + * Since a RST segment is in most cases not sent for an active connection, + * tcp_rst() has a number of arguments that are taken from a tcp_pcb for + * most other segment output functions. + * + * @param seqno the sequence number to use for the outgoing segment + * @param ackno the acknowledge number to use for the outgoing segment + * @param local_ip the local IP address to send the segment from + * @param remote_ip the remote IP address to send the segment to + * @param local_port the local TCP port to send the segment from + * @param remote_port the remote TCP port to send the segment to + */ +void +tcp_rst_impl(u32_t seqno, u32_t ackno, + ipX_addr_t *local_ip, ipX_addr_t *remote_ip, + u16_t local_port, u16_t remote_port +#if LWIP_IPV6 + , u8_t isipv6 +#endif /* LWIP_IPV6 */ + ) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); + if (p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); + return; + } + LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", + (p->len >= sizeof(struct tcp_hdr))); + + tcphdr = (struct tcp_hdr *)p->payload; + tcphdr->src = htons(local_port); + tcphdr->dest = htons(remote_port); + tcphdr->seqno = htonl(seqno); + tcphdr->ackno = htonl(ackno); + TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); +#if LWIP_WND_SCALE + tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); +#else + tcphdr->wnd = PP_HTONS(TCP_WND); +#endif + tcphdr->chksum = 0; + tcphdr->urgp = 0; + + TCP_STATS_INC(tcp.xmit); + snmp_inc_tcpoutrsts(); + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = ipX_chksum_pseudo(isipv6, p, IP_PROTO_TCP, p->tot_len, + local_ip, remote_ip); +#endif + /* Send output with hardcoded TTL/HL since we have no access to the pcb */ + ipX_output(isipv6, p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP); + pbuf_free(p); + LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); +} + +/** + * Requeue all unacked segments for retransmission + * + * Called by tcp_slowtmr() for slow retransmission. + * + * @param pcb the tcp_pcb for which to re-enqueue all unacked segments + */ +void +tcp_rexmit_rto(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move all unacked segments to the head of the unsent queue */ + for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); + /* concatenate unsent queue after unacked queue */ + seg->next = pcb->unsent; +#if TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK + /* if last unsent changed, we need to update unsent_oversize */ + if (pcb->unsent == NULL) { + pcb->unsent_oversize = seg->oversize_left; + } +#endif /* TCP_OVERSIZE && TCP_OVERSIZE_DBGCHECK*/ + /* unsent queue is the concatenated queue (of unacked, unsent) */ + pcb->unsent = pcb->unacked; + /* unacked queue is now empty */ + pcb->unacked = NULL; + + /* increment number of retransmissions */ + ++pcb->nrtx; + + /* Don't take any RTT measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission */ + tcp_output(pcb); +} + +/** + * Requeue the first unacked segment for retransmission + * + * Called by tcp_receive() for fast retramsmit. + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit(struct tcp_pcb *pcb) +{ + struct tcp_seg *seg; + struct tcp_seg **cur_seg; + + if (pcb->unacked == NULL) { + return; + } + + /* Move the first unacked segment to the unsent queue */ + /* Keep the unsent queue sorted. */ + seg = pcb->unacked; + pcb->unacked = seg->next; + + cur_seg = &(pcb->unsent); + while (*cur_seg && + TCP_SEQ_LT(ntohl((*cur_seg)->tcphdr->seqno), ntohl(seg->tcphdr->seqno))) { + cur_seg = &((*cur_seg)->next ); + } + seg->next = *cur_seg; + *cur_seg = seg; +#if TCP_OVERSIZE + if (seg->next == NULL) { + /* the retransmitted segment is last in unsent, so reset unsent_oversize */ + pcb->unsent_oversize = 0; + } +#endif /* TCP_OVERSIZE */ + + ++pcb->nrtx; + + /* Don't take any rtt measurements after retransmitting. */ + pcb->rttest = 0; + + /* Do the actual retransmission. */ + snmp_inc_tcpretranssegs(); + /* No need to call tcp_output: we are always called from tcp_input() + and thus tcp_output directly returns. */ +} + + +/** + * Handle retransmission after three dupacks received + * + * @param pcb the tcp_pcb for which to retransmit the first unacked segment + */ +void +tcp_rexmit_fast(struct tcp_pcb *pcb) +{ + if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { + /* This is fast retransmit. Retransmit the first unacked segment. */ + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: dupacks %"U16_F" (%"U32_F + "), fast retransmit %"U32_F"\n", + (u16_t)pcb->dupacks, pcb->lastack, + ntohl(pcb->unacked->tcphdr->seqno))); + tcp_rexmit(pcb); + + /* Set ssthresh to half of the minimum of the current + * cwnd and the advertised window */ + if (pcb->cwnd > pcb->snd_wnd) { + pcb->ssthresh = pcb->snd_wnd / 2; + } else { + pcb->ssthresh = pcb->cwnd / 2; + } + + /* The minimum value for ssthresh should be 2 MSS */ + if (pcb->ssthresh < (2U * pcb->mss)) { + LWIP_DEBUGF(TCP_FR_DEBUG, + ("tcp_receive: The minimum value for ssthresh %"U16_F + " should be min 2 mss %"U16_F"...\n", + pcb->ssthresh, 2*pcb->mss)); + pcb->ssthresh = 2*pcb->mss; + } + + pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; + pcb->flags |= TF_INFR; + } +} + + +/** + * Send keepalive packets to keep a connection active although + * no data is sent over it. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a keepalive packet + */ +void +tcp_keepalive(struct tcp_pcb *pcb) +{ + struct pbuf *p; +#if CHECKSUM_GEN_TCP + struct tcp_hdr *tcphdr; +#endif /* CHECKSUM_GEN_TCP */ + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); + LWIP_DEBUGF(TCP_DEBUG, ("\n")); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + p = tcp_output_alloc_header(pcb, 0, 0, htonl(pcb->snd_nxt - 1)); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_keepalive: could not allocate memory for pbuf\n")); + return; + } +#if CHECKSUM_GEN_TCP + tcphdr = (struct tcp_hdr *)p->payload; + + tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); +#endif /* CHECKSUM_GEN_TCP */ + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, + pcb->ttl, 0, IP_PROTO_TCP, &pcb->addr_hint); +#else /* LWIP_NETIF_HWADDRHINT*/ + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} + + +/** + * Send persist timer zero-window probes to keep a connection active + * when a window update is lost. + * + * Called by tcp_slowtmr() + * + * @param pcb the tcp_pcb for which to send a zero-window probe packet + */ +void +tcp_zero_window_probe(struct tcp_pcb *pcb) +{ + struct pbuf *p; + struct tcp_hdr *tcphdr; + struct tcp_seg *seg; + u16_t len; + u8_t is_fin; + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), TCP_DEBUG, &pcb->remote_ip); + LWIP_DEBUGF(TCP_DEBUG, ("\n")); + + LWIP_DEBUGF(TCP_DEBUG, + ("tcp_zero_window_probe: tcp_ticks %"U32_F + " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", + tcp_ticks, pcb->tmr, pcb->keep_cnt_sent)); + + seg = pcb->unacked; + + if(seg == NULL) { + seg = pcb->unsent; + } + if(seg == NULL) { + return; + } + + is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); + /* we want to send one seqno: either FIN or data (no options) */ + len = is_fin ? 0 : 1; + + p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); + if(p == NULL) { + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); + return; + } + tcphdr = (struct tcp_hdr *)p->payload; + + if (is_fin) { + /* FIN segment, no data */ + TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); + } else { + /* Data segment, copy in one byte from the head of the unacked queue */ + char *d = ((char *)p->payload + TCP_HLEN); + /* Depending on whether the segment has already been sent (unacked) or not + (unsent), seg->p->payload points to the IP header or TCP header. + Ensure we copy the first TCP data byte: */ + pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); + } + +#if CHECKSUM_GEN_TCP + tcphdr->chksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), p, IP_PROTO_TCP, p->tot_len, + &pcb->local_ip, &pcb->remote_ip); +#endif + TCP_STATS_INC(tcp.xmit); + + /* Send output to IP */ +#if LWIP_NETIF_HWADDRHINT + ipX_output_hinted(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, + 0, IP_PROTO_TCP, &pcb->addr_hint); +#else /* LWIP_NETIF_HWADDRHINT*/ + ipX_output(PCB_ISIPV6(pcb), p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP); +#endif /* LWIP_NETIF_HWADDRHINT*/ + + pbuf_free(p); + + LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F + " ackno %"U32_F".\n", + pcb->snd_nxt - 1, pcb->rcv_nxt)); +} +#endif /* LWIP_TCP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/udp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/udp.c new file mode 100644 index 0000000..39a07e3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/core/udp.c @@ -0,0 +1,1164 @@ +/** + * @file + * User Datagram Protocol module + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +/* udp.c + * + * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828). + * + */ + +/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! + */ + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/udp.h" +#include "lwip/def.h" +#include "lwip/memp.h" +#include "lwip/inet_chksum.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/inet_chksum.h" +#include "lwip/netif.h" +#include "lwip/icmp.h" +#include "lwip/icmp6.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "arch/perf.h" +#include "lwip/dhcp.h" + +#include + +#ifndef UDP_LOCAL_PORT_RANGE_START +/* From http://www.iana.org/assignments/port-numbers: + "The Dynamic and/or Private Ports are those from 49152 through 65535" */ +#define UDP_LOCAL_PORT_RANGE_START 0xc000 +#define UDP_LOCAL_PORT_RANGE_END 0xffff +#define UDP_ENSURE_LOCAL_PORT_RANGE(port) (((port) & ~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START) +#endif + +/* last local UDP port */ +static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; + +/* The list of UDP PCBs */ +/* exported in udp.h (was static) */ +struct udp_pcb *udp_pcbs; + +/** + * Initialize this module. + */ +void +udp_init(void) +{ +#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) + udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); +#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ +} + +/** + * Allocate a new local UDP port. + * + * @return a new (free) local UDP port number + */ +static u16_t +udp_new_port(void) +{ + u16_t n = 0; + struct udp_pcb *pcb; + +again: + if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { + udp_port = UDP_LOCAL_PORT_RANGE_START; + } + /* Check all PCBs. */ + for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == udp_port) { + if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { + return 0; + } + goto again; + } + } + return udp_port; +#if 0 + struct udp_pcb *ipcb = udp_pcbs; + while ((ipcb != NULL) && (udp_port != UDP_LOCAL_PORT_RANGE_END)) { + if (ipcb->local_port == udp_port) { + /* port is already used by another udp_pcb */ + udp_port++; + /* restart scanning all udp pcbs */ + ipcb = udp_pcbs; + } else { + /* go on with next udp pcb */ + ipcb = ipcb->next; + } + } + if (ipcb != NULL) { + return 0; + } + return udp_port; +#endif +} + +/** + * Process an incoming UDP datagram. + * + * Given an incoming UDP datagram (as a chain of pbufs) this function + * finds a corresponding UDP PCB and hands over the pbuf to the pcbs + * recv function. If no pcb is found or the datagram is incorrect, the + * pbuf is freed. + * + * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header) + * @param inp network interface on which the datagram was received. + * + */ +void +udp_input(struct pbuf *p, struct netif *inp) +{ + struct udp_hdr *udphdr; + struct udp_pcb *pcb, *prev; + struct udp_pcb *uncon_pcb; + u16_t src, dest; + u8_t local_match; + u8_t broadcast; + u8_t for_us; + + PERF_START; + + UDP_STATS_INC(udp.recv); + + /* Check minimum length (UDP header) */ + if (p->len < UDP_HLEN) { + /* drop short packets */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); + UDP_STATS_INC(udp.lenerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + + udphdr = (struct udp_hdr *)p->payload; + + /* is broadcast packet ? */ +#if LWIP_IPV6 + broadcast = !ip_current_is_v6() && ip_addr_isbroadcast(ip_current_dest_addr(), inp); +#else /* LWIP_IPV6 */ + broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), inp); +#endif /* LWIP_IPV6 */ + + LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); + + /* convert src and dest ports to host byte order */ + src = ntohs(udphdr->src); + dest = ntohs(udphdr->dest); + + udp_debug_print(udphdr); + + /* print the UDP source and destination */ + LWIP_DEBUGF(UDP_DEBUG, ("udp (")); + ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_dest_addr()); + LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", ntohs(udphdr->dest))); + ipX_addr_debug_print(ip_current_is_v6(), UDP_DEBUG, ipX_current_src_addr()); + LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", ntohs(udphdr->src))); + +#if LWIP_DHCP + pcb = NULL; + /* when LWIP_DHCP is active, packets to DHCP_CLIENT_PORT may only be processed by + the dhcp module, no other UDP pcb may use the local UDP port DHCP_CLIENT_PORT */ + if (dest == DHCP_CLIENT_PORT) { + /* all packets for DHCP_CLIENT_PORT not coming from DHCP_SERVER_PORT are dropped! */ + if (src == DHCP_SERVER_PORT) { + if ((inp->dhcp != NULL) && (inp->dhcp->pcb != NULL)) { + /* accept the packet if + (- broadcast or directed to us) -> DHCP is link-layer-addressed, local ip is always ANY! + - inp->dhcp->pcb->remote == ANY or iphdr->src + (no need to check for IPv6 since the dhcp struct always uses IPv4) */ + if (ipX_addr_isany(0, &inp->dhcp->pcb->remote_ip) || + ip_addr_cmp(ipX_2_ip(&(inp->dhcp->pcb->remote_ip)), ip_current_src_addr())) { + pcb = inp->dhcp->pcb; + } + } + } + } else +#endif /* LWIP_DHCP */ + { + prev = NULL; + local_match = 0; + uncon_pcb = NULL; + /* Iterate through the UDP pcb list for a matching pcb. + * 'Perfect match' pcbs (connected to the remote port & ip address) are + * preferred. If no perfect match is found, the first unconnected pcb that + * matches the local port and ip address gets the datagram. */ + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + local_match = 0; + /* print the PCB local and remote address */ + LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->local_ip); + LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG, &pcb->remote_ip); + LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); + + /* compare PCB local addr+port to UDP destination addr+port */ + if (pcb->local_port == dest) { + if ( +#if LWIP_IPV6 + ((PCB_ISIPV6(pcb) && (ip_current_is_v6()) && + (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip)) || +#if LWIP_IPV6_MLD + ip6_addr_ismulticast(ip6_current_dest_addr()) || +#endif /* LWIP_IPV6_MLD */ + ip6_addr_cmp(ipX_2_ip6(&pcb->local_ip), ip6_current_dest_addr()))) || + (!PCB_ISIPV6(pcb) && + (ip_current_header() != NULL) && +#else /* LWIP_IPV6 */ + (( +#endif /* LWIP_IPV6 */ + ((!broadcast && ipX_addr_isany(0, &pcb->local_ip)) || + ip_addr_cmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr()) || +#if LWIP_IGMP + ip_addr_ismulticast(ip_current_dest_addr()) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(pcb, SOF_BROADCAST) && + (ipX_addr_isany(0, &pcb->local_ip) || + ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast && + (ipX_addr_isany(0, &pcb->local_ip) || + ip_addr_netcmp(ipX_2_ip(&pcb->local_ip), ip_current_dest_addr(), &inp->netmask))))))) { +#endif /* IP_SOF_BROADCAST_RECV */ + local_match = 1; + if ((uncon_pcb == NULL) && + ((pcb->flags & UDP_FLAGS_CONNECTED) == 0)) { + /* the first unconnected matching PCB */ + uncon_pcb = pcb; + } + } + } + /* compare PCB remote addr+port to UDP source addr+port */ + if ((local_match != 0) && + (pcb->remote_port == src) && IP_PCB_IPVER_INPUT_MATCH(pcb) && + (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->remote_ip) || + ipX_addr_cmp(PCB_ISIPV6(pcb), &pcb->remote_ip, ipX_current_src_addr()))) { + /* the first fully matching PCB */ + if (prev != NULL) { + /* move the pcb to the front of udp_pcbs so that is + found faster next time */ + prev->next = pcb->next; + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } else { + UDP_STATS_INC(udp.cachehit); + } + break; + } +/* This part of code has been modified by ST's MCD Application Team */ +/* To use the UPnP responder for device discovery */ +#if LWIP_UPNP + if((local_match != 0) && (dest == 1900)) { + break; + } +#endif /* LWIP_UPNP */ + prev = pcb; + } + /* no fully matching pcb found? then look for an unconnected pcb */ + if (pcb == NULL) { + pcb = uncon_pcb; + } + } + + /* Check checksum if this is a match or if it was directed at us. */ + if (pcb != NULL) { + for_us = 1; + } else { +#if LWIP_IPV6 + if (ip_current_is_v6()) { + for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0; + } else +#endif /* LWIP_IPV6 */ + { + for_us = ip_addr_cmp(&inp->ip_addr, ip_current_dest_addr()); + } + } + if (for_us) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); +#if CHECKSUM_CHECK_UDP +#if LWIP_UDPLITE + if (ip_current_header_proto() == IP_PROTO_UDPLITE) { + /* Do the UDP Lite checksum */ + u16_t chklen = ntohs(udphdr->len); + if (chklen < sizeof(struct udp_hdr)) { + if (chklen == 0) { + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet (See RFC 3828 chap. 3.1) */ + chklen = p->tot_len; + } else { + /* At least the UDP-Lite header must be covered by the + checksum! (Again, see RFC 3828 chap. 3.1) */ + goto chkerr; + } + } + if (ipX_chksum_pseudo_partial(ip_current_is_v6(), p, IP_PROTO_UDPLITE, + p->tot_len, chklen, + ipX_current_src_addr(), ipX_current_dest_addr()) != 0) { + goto chkerr; + } + } else +#endif /* LWIP_UDPLITE */ + { + if (udphdr->chksum != 0) { + if (ipX_chksum_pseudo(ip_current_is_v6(), p, IP_PROTO_UDP, p->tot_len, + ipX_current_src_addr(), + ipX_current_dest_addr()) != 0) { + goto chkerr; + } + } + } +#endif /* CHECKSUM_CHECK_UDP */ + if(pbuf_header(p, -UDP_HLEN)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + goto end; + } + if (pcb != NULL) { + snmp_inc_udpindatagrams(); +#if SO_REUSE && SO_REUSE_RXTOALL + if ((broadcast || +#if LWIP_IPV6 + ip6_addr_ismulticast(ip6_current_dest_addr()) || +#endif /* LWIP_IPV6 */ + ip_addr_ismulticast(ip_current_dest_addr())) && + ip_get_option(pcb, SOF_REUSEADDR)) { + /* pass broadcast- or multicast packets to all multicast pcbs + if SOF_REUSEADDR is set on the first match */ + struct udp_pcb *mpcb; + u8_t p_header_changed = 0; + s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN); + for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { + if (mpcb != pcb) { + /* compare PCB local addr+port to UDP destination addr+port */ + if ((mpcb->local_port == dest) && +#if LWIP_IPV6 + ((PCB_ISIPV6(mpcb) && + (ip6_addr_ismulticast(ip6_current_dest_addr()) || + ip6_addr_cmp(ipX_2_ip6(&mpcb->local_ip), ip6_current_dest_addr()))) || + (!PCB_ISIPV6(mpcb) && +#else /* LWIP_IPV6 */ + (( +#endif /* LWIP_IPV6 */ + ((!broadcast && ipX_addr_isany(0, &mpcb->local_ip)) || + ip_addr_cmp(ipX_2_ip(&mpcb->local_ip), ip_current_dest_addr()) || +#if LWIP_IGMP + ip_addr_ismulticast(ip_current_dest_addr()) || +#endif /* LWIP_IGMP */ +#if IP_SOF_BROADCAST_RECV + (broadcast && ip_get_option(mpcb, SOF_BROADCAST)))))) { +#else /* IP_SOF_BROADCAST_RECV */ + (broadcast))))) { +#endif /* IP_SOF_BROADCAST_RECV */ + /* pass a copy of the packet to all local matches */ + if (mpcb->recv.ip4 != NULL) { + struct pbuf *q; + /* for that, move payload to IP header again */ + if (p_header_changed == 0) { + pbuf_header_force(p, hdrs_len); + p_header_changed = 1; + } + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if (q != NULL) { + err_t err = pbuf_copy(q, p); + if (err == ERR_OK) { + /* move payload to UDP data */ + pbuf_header(q, -hdrs_len); +#if LWIP_IPV6 + if (PCB_ISIPV6(mpcb)) { + mpcb->recv.ip6(mpcb->recv_arg, mpcb, q, ip6_current_src_addr(), src); + } + else +#endif /* LWIP_IPV6 */ + { + mpcb->recv.ip4(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); + } + } + } + } + } + } + } + if (p_header_changed) { + /* and move payload to UDP data again */ + pbuf_header(p, -hdrs_len); + } + } +#endif /* SO_REUSE && SO_REUSE_RXTOALL */ + /* callback */ + if (pcb->recv.ip4 != NULL) { + /* now the recv function is responsible for freeing p */ +#if LWIP_IPV6 + if (PCB_ISIPV6(pcb)) { + pcb->recv.ip6(pcb->recv_arg, pcb, p, ip6_current_src_addr(), src); + } + else +#endif /* LWIP_IPV6 */ + { + pcb->recv.ip4(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); + } + } else { + /* no recv function registered? then we have to free the pbuf! */ + pbuf_free(p); + goto end; + } + } else { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); + +#if LWIP_ICMP || LWIP_ICMP6 + /* No match was found, send ICMP destination port unreachable unless + destination address was broadcast/multicast. */ + if (!broadcast && +#if LWIP_IPV6 + !ip6_addr_ismulticast(ip6_current_dest_addr()) && +#endif /* LWIP_IPV6 */ + !ip_addr_ismulticast(ip_current_dest_addr())) { + /* move payload pointer back to ip header */ + pbuf_header_force(p, ip_current_header_tot_len() + UDP_HLEN); + icmp_port_unreach(ip_current_is_v6(), p); + } +#endif /* LWIP_ICMP || LWIP_ICMP6 */ + UDP_STATS_INC(udp.proterr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpnoports(); + pbuf_free(p); + } + } else { + pbuf_free(p); + } +end: + PERF_STOP("udp_input"); + return; +#if CHECKSUM_CHECK_UDP +chkerr: + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); + UDP_STATS_INC(udp.chkerr); + UDP_STATS_INC(udp.drop); + snmp_inc_udpinerrors(); + pbuf_free(p); + PERF_STOP("udp_input"); +#endif /* CHECKSUM_CHECK_UDP */ +} + +/** + * Send data using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * + * The datagram will be sent to the current remote_ip & remote_port + * stored in pcb. If the pcb is not bound to a port, it will + * automatically be bound to a random port. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_MEM. Out of memory. + * - ERR_RTE. Could not find route to destination address. + * - More errors could be returned by lower protocol layers. + * + * @see udp_disconnect() udp_sendto() + */ +err_t +udp_send(struct udp_pcb *pcb, struct pbuf *p) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port); +} + +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP +/** Same as udp_send() but with checksum + */ +err_t +udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum) +{ + /* send to the packet using remote ip and port stored in the pcb */ + return udp_sendto_chksum(pcb, p, ipX_2_ip(&pcb->remote_ip), pcb->remote_port, + have_chksum, chksum); +} +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + +/** + * Send data to a specified address using UDP. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * If the PCB already has a remote address association, it will + * be restored after the data is sent. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port) +{ +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); +} + +/** Same as udp_sendto(), but with checksum */ +err_t +udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, u8_t have_chksum, u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + struct netif *netif; + ipX_addr_t *dst_ip_route = ip_2_ipX(dst_ip); + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); + +#if LWIP_IPV6 || LWIP_IGMP + if (ipX_addr_ismulticast(PCB_ISIPV6(pcb), dst_ip_route)) { + /* For multicast, find a netif based on source address. */ +#if LWIP_IPV6 + if (PCB_ISIPV6(pcb)) { + dst_ip_route = &pcb->local_ip; + } else +#endif /* LWIP_IPV6 */ + { +#if LWIP_IGMP + dst_ip_route = ip_2_ipX(&pcb->multicast_ip); +#endif /* LWIP_IGMP */ + } + } +#endif /* LWIP_IPV6 || LWIP_IGMP */ + + /* find the outgoing network interface for this packet */ + netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip_route); + + /* no outgoing network interface could be found? */ + if (netif == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ip_2_ipX(dst_ip)); + LWIP_DEBUGF(UDP_DEBUG, ("\n")); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); +#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ +} + +/** + * Send data to a specified address using UDP. + * The netif used for sending can be specified. + * + * This function exists mainly for DHCP, to be able to send UDP packets + * on a netif that is still down. + * + * @param pcb UDP PCB used to send the data. + * @param p chain of pbuf's to be sent. + * @param dst_ip Destination IP address. + * @param dst_port Destination UDP port. + * @param netif the netif used for sending. + * + * dst_ip & dst_port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code (@see udp_send for possible error codes) + * + * @see udp_disconnect() udp_send() + */ +err_t +udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) +{ +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); +} + +/** Same as udp_sendto_if(), but with checksum */ +err_t +udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, struct netif *netif, u8_t have_chksum, + u16_t chksum) +{ +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + ip_addr_t *src_ip; + + /* PCB local address is IP_ANY_ADDR? */ +#if LWIP_IPV6 + if (PCB_ISIPV6(pcb)) { + if (ip6_addr_isany(ipX_2_ip6(&pcb->local_ip))) { + src_ip = ip6_2_ip(ip6_select_source_address(netif, ip_2_ip6(dst_ip))); + if (src_ip == NULL) { + /* No suitable source address was found. */ + return ERR_RTE; + } + } else { + /* use UDP PCB local IPv6 address as source address, if still valid. */ + if (netif_get_ip6_addr_match(netif, ipX_2_ip6(&pcb->local_ip)) < 0) { + /* Address isn't valid anymore. */ + return ERR_RTE; + } + src_ip = ipX_2_ip(&pcb->local_ip); + } + } + else +#endif /* LWIP_IPV6 */ + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip))) { + /* use outgoing network interface IP address as source address */ + src_ip = &(netif->ip_addr); + } else { + /* check if UDP PCB local IP address is correct + * this could be an old address if netif->ip_addr has changed */ + if (!ip_addr_cmp(ipX_2_ip(&(pcb->local_ip)), &(netif->ip_addr))) { + /* local_ip doesn't match, drop the packet */ + return ERR_VAL; + } + /* use UDP PCB local IP address as source address */ + src_ip = ipX_2_ip(&(pcb->local_ip)); + } +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip); +#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip); +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ +} + +/** Same as udp_sendto_if(), but with source address */ +err_t +udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, ip_addr_t *src_ip) +{ +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP + return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0, src_ip); +} + +/** Same as udp_sendto_if_src(), but with checksum */ +err_t +udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip, + u16_t dst_port, struct netif *netif, u8_t have_chksum, + u16_t chksum, ip_addr_t *src_ip) +{ +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + struct udp_hdr *udphdr; + err_t err; + struct pbuf *q; /* q will be sent down the stack */ + u8_t ip_proto; + +#if IP_SOF_BROADCAST + /* broadcast filter? */ + if (!ip_get_option(pcb, SOF_BROADCAST) && +#if LWIP_IPV6 + !PCB_ISIPV6(pcb) && +#endif /* LWIP_IPV6 */ + ip_addr_isbroadcast(dst_ip, netif) ) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, + ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); + return ERR_VAL; + } +#endif /* IP_SOF_BROADCAST */ + + /* if the PCB is not yet bound to a port, bind it here */ + if (pcb->local_port == 0) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); + err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); + if (err != ERR_OK) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); + return err; + } + } + + /* not enough space to add an UDP header to first pbuf in given p chain? */ + if (pbuf_header(p, UDP_HLEN)) { + /* allocate header in a separate new pbuf */ + q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); + /* new header pbuf could not be allocated? */ + if (q == NULL) { + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); + return ERR_MEM; + } + if (p->tot_len != 0) { + /* chain header q in front of given pbuf p (only if p contains data) */ + pbuf_chain(q, p); + } + /* first pbuf q points to header pbuf */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); + } else { + /* adding space for header within p succeeded */ + /* first pbuf q equals given pbuf */ + q = p; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); + } + LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", + (q->len >= sizeof(struct udp_hdr))); + /* q now represents the packet to be sent */ + udphdr = (struct udp_hdr *)q->payload; + udphdr->src = htons(pcb->local_port); + udphdr->dest = htons(dst_port); + /* in UDP, 0 checksum means 'no checksum' */ + udphdr->chksum = 0x0000; + + /* Multicast Loop? */ +#if LWIP_IGMP + if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && +#if LWIP_IPV6 + ( +#if LWIP_IPV6_MLD + (PCB_ISIPV6(pcb) && + ip6_addr_ismulticast(ip_2_ip6(dst_ip))) || +#endif /* LWIP_IPV6_MLD */ + (!PCB_ISIPV6(pcb) && +#else /* LWIP_IPV6 */ + (( +#endif /* LWIP_IPV6 */ + ip_addr_ismulticast(dst_ip)))) { + q->flags |= PBUF_FLAG_MCASTLOOP; + } +#endif /* LWIP_IGMP */ + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); + +#if LWIP_UDPLITE + /* UDP Lite protocol? */ + if (pcb->flags & UDP_FLAGS_UDPLITE) { + u16_t chklen, chklen_hdr; + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); + /* set UDP message length in UDP header */ + chklen_hdr = chklen = pcb->chksum_len_tx; + if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { + if (chklen != 0) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); + } + /* For UDP-Lite, checksum length of 0 means checksum + over the complete packet. (See RFC 3828 chap. 3.1) + At least the UDP-Lite header must be covered by the + checksum, therefore, if chksum_len has an illegal + value, we generate the checksum over the complete + packet to be safe. */ + chklen_hdr = 0; + chklen = q->tot_len; + } + udphdr->len = htons(chklen_hdr); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + chklen = UDP_HLEN; + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + udphdr->chksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDPLITE, + q->tot_len, chklen, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + u32_t acc; + acc = udphdr->chksum + (u16_t)~(chksum); + udphdr->chksum = FOLD_U32T(acc); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udphdr->chksum == 0x0000) { + udphdr->chksum = 0xffff; + } +#endif /* CHECKSUM_GEN_UDP */ + + ip_proto = IP_PROTO_UDPLITE; + } else +#endif /* LWIP_UDPLITE */ + { /* UDP */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); + udphdr->len = htons(q->tot_len); + /* calculate checksum */ +#if CHECKSUM_GEN_UDP + /* Checksum is mandatory over IPv6. */ + if (PCB_ISIPV6(pcb) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { + u16_t udpchksum; +#if LWIP_CHECKSUM_ON_COPY + if (have_chksum) { + u32_t acc; + udpchksum = ipX_chksum_pseudo_partial(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, + q->tot_len, UDP_HLEN, ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); + acc = udpchksum + (u16_t)~(chksum); + udpchksum = FOLD_U32T(acc); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + udpchksum = ipX_chksum_pseudo(PCB_ISIPV6(pcb), q, IP_PROTO_UDP, q->tot_len, + ip_2_ipX(src_ip), ip_2_ipX(dst_ip)); + } + + /* chksum zero must become 0xffff, as zero means 'no checksum' */ + if (udpchksum == 0x0000) { + udpchksum = 0xffff; + } + udphdr->chksum = udpchksum; + } +#endif /* CHECKSUM_GEN_UDP */ + ip_proto = IP_PROTO_UDP; + } + + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", udphdr->chksum)); + LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); + /* output to IP */ + NETIF_SET_HWADDRHINT(netif, &(pcb->addr_hint)); + err = ipX_output_if_src(PCB_ISIPV6(pcb), q, src_ip, dst_ip, pcb->ttl, pcb->tos, ip_proto, netif); + NETIF_SET_HWADDRHINT(netif, NULL); + + /* TODO: must this be increased even if error occurred? */ + snmp_inc_udpoutdatagrams(); + + /* did we chain a separate header pbuf earlier? */ + if (q != p) { + /* free the header pbuf */ + pbuf_free(q); + q = NULL; + /* p is still referenced by the caller, and will live on */ + } + + UDP_STATS_INC(udp.xmit); + return err; +} + +/** + * Bind an UDP PCB. + * + * @param pcb UDP PCB to be bound with a local address ipaddr and port. + * @param ipaddr local IP address to bind with. Use IP_ADDR_ANY to + * bind to all local interfaces. + * @param port local UDP port to bind with. Use 0 to automatically bind + * to a random port between UDP_LOCAL_PORT_RANGE_START and + * UDP_LOCAL_PORT_RANGE_END. + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified ipaddr and port are already bound to by + * another UDP PCB. + * + * @see udp_disconnect() + */ +err_t +udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + u8_t rebind; + + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE, ip_2_ipX(ipaddr)); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); + + rebind = 0; + /* Check for double bind and rebind of the same pcb */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + /* is this UDP PCB already on active list? */ + if (pcb == ipcb) { + /* pcb may occur at most once in active list */ + LWIP_ASSERT("rebind == 0", rebind == 0); + /* pcb already in list, just rebind */ + rebind = 1; + } + + /* By default, we don't allow to bind to a port that any other udp + PCB is already bound to, unless *all* PCBs with that port have tha + REUSEADDR flag set. */ +#if SO_REUSE + else if (!ip_get_option(pcb, SOF_REUSEADDR) && + !ip_get_option(ipcb, SOF_REUSEADDR)) { +#else /* SO_REUSE */ + /* port matches that of PCB in list and REUSEADDR not set -> reject */ + else { +#endif /* SO_REUSE */ + if ((ipcb->local_port == port) && IP_PCB_IPVER_EQ(pcb, ipcb) && + /* IP address matches, or one is IP_ADDR_ANY? */ + (ipX_addr_isany(PCB_ISIPV6(ipcb), &(ipcb->local_ip)) || + ipX_addr_isany(PCB_ISIPV6(ipcb), ip_2_ipX(ipaddr)) || + ipX_addr_cmp(PCB_ISIPV6(ipcb), &(ipcb->local_ip), ip_2_ipX(ipaddr)))) { + /* other PCB already binds to this local IP and port */ + LWIP_DEBUGF(UDP_DEBUG, + ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); + return ERR_USE; + } + } + } + + ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->local_ip, ipaddr); + + /* no port specified? */ + if (port == 0) { + port = udp_new_port(); + if (port == 0) { + /* no more ports available in local range */ + LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); + return ERR_USE; + } + } + pcb->local_port = port; + snmp_insert_udpidx_tree(pcb); + /* pcb not active yet? */ + if (rebind == 0) { + /* place the PCB on the active list if not already there */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + } + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); + return ERR_OK; +} + +/** + * Connect an UDP PCB. + * + * This will associate the UDP PCB with the remote address. + * + * @param pcb UDP PCB to be connected with remote address ipaddr and port. + * @param ipaddr remote IP address to connect with. + * @param port remote UDP port to connect with. + * + * @return lwIP error code + * + * ipaddr & port are expected to be in the same byte order as in the pcb. + * + * The udp pcb is bound to a random local port if not already bound. + * + * @see udp_disconnect() + */ +err_t +udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) +{ + struct udp_pcb *ipcb; + + if (pcb->local_port == 0) { + err_t err = udp_bind(pcb, ipX_2_ip(&pcb->local_ip), pcb->local_port); + if (err != ERR_OK) { + return err; + } + } + + ipX_addr_set_ipaddr(PCB_ISIPV6(pcb), &pcb->remote_ip, ipaddr); + pcb->remote_port = port; + pcb->flags |= UDP_FLAGS_CONNECTED; +/** TODO: this functionality belongs in upper layers */ +#ifdef LWIP_UDP_TODO +#if LWIP_IPV6 + if (!PCB_ISIPV6(pcb)) +#endif /* LWIP_IPV6 */ + { + /* Nail down local IP for netconn_addr()/getsockname() */ + if (ip_addr_isany(ipX_2_ip(&pcb->local_ip)) && !ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { + struct netif *netif; + + if ((netif = ip_route(ipX_2_ip(&pcb->remote_ip))) == NULL) { + LWIP_DEBUGF(UDP_DEBUG, ("udp_connect: No route to 0x%lx\n", + ip4_addr_get_u32(ipX_2_ip(&pcb->remote_ip)))); + UDP_STATS_INC(udp.rterr); + return ERR_RTE; + } + /** TODO: this will bind the udp pcb locally, to the interface which + is used to route output packets to the remote address. However, we + might want to accept incoming packets on any interface! */ + ipX_addr_copy(0, pcb->local_ip, netif->ip_addr); + } else if (ip_addr_isany(ipX_2_ip(&pcb->remote_ip))) { + ipX_addr_set_any(0, &pcb->local_ip); + } + } +#endif + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); + ipX_addr_debug_print(PCB_ISIPV6(pcb), UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, + &pcb->remote_ip); + LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); + + /* Insert UDP PCB into the list of active UDP PCBs. */ + for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { + if (pcb == ipcb) { + /* already on the list, just return */ + return ERR_OK; + } + } + /* PCB not yet on the list, add PCB now */ + pcb->next = udp_pcbs; + udp_pcbs = pcb; + return ERR_OK; +} + +/** + * Disconnect a UDP PCB + * + * @param pcb the udp pcb to disconnect. + */ +void +udp_disconnect(struct udp_pcb *pcb) +{ + /* reset remote address association */ + ipX_addr_set_any(PCB_ISIPV6(pcb), &pcb->remote_ip); + pcb->remote_port = 0; + /* mark PCB as unconnected */ + pcb->flags &= ~UDP_FLAGS_CONNECTED; +} + +/** + * Set a receive callback for a UDP PCB + * + * This callback will be called when receiving a datagram for the pcb. + * + * @param pcb the pcb for which to set the recv callback + * @param recv function pointer of the callback function + * @param recv_arg additional argument to pass to the callback function + */ +void +udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) +{ + /* remember recv() callback and user data */ + pcb->recv.ip4 = recv; + pcb->recv_arg = recv_arg; +} + +/** + * Remove an UDP PCB. + * + * @param pcb UDP PCB to be removed. The PCB is removed from the list of + * UDP PCB's and the data structure is freed from memory. + * + * @see udp_new() + */ +void +udp_remove(struct udp_pcb *pcb) +{ + struct udp_pcb *pcb2; + + snmp_delete_udpidx_tree(pcb); + /* pcb to be removed is first in list? */ + if (udp_pcbs == pcb) { + /* make list start at 2nd pcb */ + udp_pcbs = udp_pcbs->next; + /* pcb not 1st in list */ + } else { + for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { + /* find pcb in udp_pcbs list */ + if (pcb2->next != NULL && pcb2->next == pcb) { + /* remove pcb from list */ + pcb2->next = pcb->next; + } + } + } + memp_free(MEMP_UDP_PCB, pcb); +} + +/** + * Create a UDP PCB. + * + * @return The UDP PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new(void) +{ + struct udp_pcb *pcb; + pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); + /* could allocate UDP PCB? */ + if (pcb != NULL) { + /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 + * which means checksum is generated over the whole datagram per default + * (recommended as default by RFC 3828). */ + /* initialize PCB to all zeroes */ + memset(pcb, 0, sizeof(struct udp_pcb)); + pcb->ttl = UDP_TTL; + } + return pcb; +} + +#if LWIP_IPV6 +/** + * Create a UDP PCB for IPv6. + * + * @return The UDP PCB which was created. NULL if the PCB data structure + * could not be allocated. + * + * @see udp_remove() + */ +struct udp_pcb * +udp_new_ip6(void) +{ + struct udp_pcb *pcb; + pcb = udp_new(); + ip_set_v6(pcb, 1); + return pcb; +} +#endif /* LWIP_IPV6 */ + +#if UDP_DEBUG +/** + * Print UDP header information for debug purposes. + * + * @param udphdr pointer to the udp header in memory. + */ +void +udp_debug_print(struct udp_hdr *udphdr) +{ + LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", + ntohs(udphdr->src), ntohs(udphdr->dest))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", + ntohs(udphdr->len), ntohs(udphdr->chksum))); + LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); +} +#endif /* UDP_DEBUG */ + +#endif /* LWIP_UDP */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/compat/lwip/ip.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/compat/lwip/ip.h new file mode 100644 index 0000000..ea0899b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/compat/lwip/ip.h @@ -0,0 +1 @@ +#include "lwip/lwip_ip.h" diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api.h new file mode 100644 index 0000000..c31a0e3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api.h @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_API_H +#define LWIP_HDR_API_H + +#include "lwip/opt.h" + +#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +/* don't export the netconn functions when socket API is enabled but netconn API is disabled */ +#if LWIP_NETCONN +#define LWIP_NETCONN_SCOPE +#else /* LWIP_NETCONN */ +#define LWIP_NETCONN_SCOPE static +#endif /* LWIP_NETCONN */ + +#include /* for size_t */ + +#include "lwip/netbuf.h" +#include "lwip/sys.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define port_netconn_recv(conn , buf, ret) do{ret = netconn_recv(conn, &buf);}while(0); +#define port_netconn_accept(conn , newconn, ret) do{ret = netconn_accept(conn, &newconn);}while(0); + +/* Throughout this file, IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ + +/* Flags for netconn_write (u8_t) */ +#define NETCONN_NOFLAG 0x00 +#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ +#define NETCONN_COPY 0x01 +#define NETCONN_MORE 0x02 +#define NETCONN_DONTBLOCK 0x04 + +/* Flags for struct netconn.flags (u8_t) */ +/** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores whether to wake up the original application task + if data couldn't be sent in the first try. */ +#define NETCONN_FLAG_WRITE_DELAYED 0x01 +/** Should this netconn avoid blocking? */ +#define NETCONN_FLAG_NON_BLOCKING 0x02 +/** Was the last connect action a non-blocking one? */ +#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 +/** If this is set, a TCP netconn must call netconn_recved() to update + the TCP receive window (done automatically if not set). */ +#define NETCONN_FLAG_NO_AUTO_RECVED 0x08 +/** If a nonblocking write has been rejected before, poll_tcp needs to + check if the netconn is writable again */ +#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 +#if LWIP_IPV6 +/** If this flag is set then only IPv6 communication is allowed on the + netconn. As per RFC#3493 this features defaults to OFF allowing + dual-stack usage by default. */ +#define NETCONN_FLAG_IPV6_V6ONLY 0x20 +#endif /* LWIP_IPV6 */ + + +/* Helpers to process several netconn_types by the same code */ +#define NETCONNTYPE_GROUP(t) ((t)&0xF0) +#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) +#if LWIP_IPV6 +#define NETCONN_TYPE_IPV6 0x08 +#define NETCONNTYPE_ISIPV6(t) ((t)&0x08) +#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF7) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF7) == NETCONN_UDPNOCHKSUM) +#else /* LWIP_IPV6 */ +#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) +#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) +#endif /* LWIP_IPV6 */ + +/** Protocol family and type of the netconn */ +enum netconn_type { + NETCONN_INVALID = 0, + /* NETCONN_TCP Group */ + NETCONN_TCP = 0x10, +#if LWIP_IPV6 + NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, +#endif /* LWIP_IPV6 */ + /* NETCONN_UDP Group */ + NETCONN_UDP = 0x20, + NETCONN_UDPLITE = 0x21, + NETCONN_UDPNOCHKSUM = 0x22, +#if LWIP_IPV6 + NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, + NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, + NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, +#endif /* LWIP_IPV6 */ + /* NETCONN_RAW Group */ + NETCONN_RAW = 0x40 +#if LWIP_IPV6 + , + NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ +#endif /* LWIP_IPV6 */ +}; + +/** Current state of the netconn. Non-TCP netconns are always + * in state NETCONN_NONE! */ +enum netconn_state { + NETCONN_NONE, + NETCONN_WRITE, + NETCONN_LISTEN, + NETCONN_CONNECT, + NETCONN_CLOSE +}; + +/** Use to inform the callback function about changes */ +enum netconn_evt { + NETCONN_EVT_RCVPLUS, + NETCONN_EVT_RCVMINUS, + NETCONN_EVT_SENDPLUS, + NETCONN_EVT_SENDMINUS, + NETCONN_EVT_ERROR +}; + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +/** Used for netconn_join_leave_group() */ +enum netconn_igmp { + NETCONN_JOIN, + NETCONN_LEAVE +}; +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +/* forward-declare some structs to avoid to include their headers */ +struct ip_pcb; +struct tcp_pcb; +struct udp_pcb; +struct raw_pcb; +struct netconn; +struct api_msg_msg; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); + +/** A netconn descriptor */ +struct netconn { + /** type of the netconn (TCP, UDP or RAW) */ + enum netconn_type type; + /** current state of the netconn */ + enum netconn_state state; + /** the lwIP internal protocol control block */ + union { + struct ip_pcb *ip; + struct tcp_pcb *tcp; + struct udp_pcb *udp; + struct raw_pcb *raw; + } pcb; + /** the last error this netconn had */ + err_t last_err; +#if !LWIP_NETCONN_SEM_PER_THREAD + /** sem that is used to synchronously execute functions in the core context */ + sys_sem_t op_completed; +#endif + /** mbox where received packets are stored until they are fetched + by the netconn application thread (can grow quite big) */ + sys_mbox_t recvmbox; +#if LWIP_TCP + /** mbox where new connections are stored until processed + by the application thread */ + sys_mbox_t acceptmbox; +#endif /* LWIP_TCP */ + /** only used for socket layer */ +#if LWIP_SOCKET + int socket; +#endif /* LWIP_SOCKET */ +#if LWIP_SO_SNDTIMEO + /** timeout to wait for sending data (which means enqueueing data for sending + in internal buffers) in milliseconds */ + s32_t send_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVTIMEO + /** timeout in milliseconds to wait for new data to be received + (or connections to arrive for listening netconns) */ + int recv_timeout; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + /** maximum amount of bytes queued in recvmbox + not used for TCP: adjust TCP_WND instead! */ + int recv_bufsize; + /** number of bytes currently in recvmbox to be received, + tested against recv_bufsize to limit bytes on recvmbox + for UDP and RAW, used for FIONREAD */ + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ + u8_t flags; +#if LWIP_TCP + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores how much is already sent. */ + size_t write_offset; + /** TCP: when data passed to netconn_write doesn't fit into the send buffer, + this temporarily stores the message. + Also used during connect and close. */ + struct api_msg_msg *current_msg; +#endif /* LWIP_TCP */ + /** A callback function that is informed about events for this netconn */ + netconn_callback callback; +}; + +/** Register an Network connection event */ +#define API_EVENT(c,e,l) if (c->callback) { \ + (*c->callback)(c, e, l); \ + } + +/** Set conn->last_err to err but don't overwrite fatal errors */ +#define NETCONN_SET_SAFE_ERR(conn, err) do { \ + SYS_ARCH_DECL_PROTECT(lev); \ + SYS_ARCH_PROTECT(lev); \ + if (!ERR_IS_FATAL((conn)->last_err)) { \ + (conn)->last_err = err; \ + } \ + SYS_ARCH_UNPROTECT(lev); \ +} while(0); + +// Realtek add +err_t netconn_abort(struct netconn *conn); +// Realtek add end + +/* Network connection functions: */ +#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) +#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) +LWIP_NETCONN_SCOPE struct +netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, + netconn_callback callback); +LWIP_NETCONN_SCOPE err_t netconn_delete(struct netconn *conn); +/** Get the type of a netconn (as enum netconn_type). */ +#define netconn_type(conn) (conn->type) + +LWIP_NETCONN_SCOPE err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, + u16_t *port, u8_t local); +#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) +#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) + +LWIP_NETCONN_SCOPE err_t netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port); +LWIP_NETCONN_SCOPE err_t netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port); +LWIP_NETCONN_SCOPE err_t netconn_disconnect (struct netconn *conn); +LWIP_NETCONN_SCOPE err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); +#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) +LWIP_NETCONN_SCOPE err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); +LWIP_NETCONN_SCOPE err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); +LWIP_NETCONN_SCOPE err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); +LWIP_NETCONN_SCOPE void netconn_recved(struct netconn *conn, u32_t length); +LWIP_NETCONN_SCOPE err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, + ip_addr_t *addr, u16_t port); +LWIP_NETCONN_SCOPE err_t netconn_send(struct netconn *conn, struct netbuf *buf); +LWIP_NETCONN_SCOPE err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, + u8_t apiflags, size_t *bytes_written); +#define netconn_write(conn, dataptr, size, apiflags) \ + netconn_write_partly(conn, dataptr, size, apiflags, NULL) +LWIP_NETCONN_SCOPE err_t netconn_close(struct netconn *conn); +LWIP_NETCONN_SCOPE err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); + +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +LWIP_NETCONN_SCOPE err_t netconn_join_leave_group(struct netconn *conn, ip_addr_t *multiaddr, + ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ +#if LWIP_DNS +err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); +#endif /* LWIP_DNS */ +#if LWIP_IPV6 + +#define netconn_bind_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_bind(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_connect_ip6(conn, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_connect(conn, ip6_2_ip(ip6addr), port) : ERR_VAL) +#define netconn_sendto_ip6(conn, buf, ip6addr, port) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_sendto(conn, buf, ip6_2_ip(ip6addr), port) : ERR_VAL) +#if LWIP_IPV6_MLD +#define netconn_join_leave_group_ip6(conn, multiaddr, srcaddr, join_or_leave) (NETCONNTYPE_ISIPV6((conn)->type) ? \ + netconn_join_leave_group(conn, ip6_2_ip(multiaddr), ip6_2_ip(srcaddr), join_or_leave) :\ + ERR_VAL) +#endif /* LWIP_IPV6_MLD*/ +#endif /* LWIP_IPV6 */ + +#define netconn_err(conn) ((conn)->last_err) +#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) + +/** Set the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_set_nonblocking(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) +/** Get the blocking status of netconn calls (@todo: write/send is missing) */ +#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) + +/** TCP: Set the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_set_noautorecved(conn, val) do { if(val) { \ + (conn)->flags |= NETCONN_FLAG_NO_AUTO_RECVED; \ +} else { \ + (conn)->flags &= ~ NETCONN_FLAG_NO_AUTO_RECVED; }} while(0) +/** TCP: Get the no-auto-recved status of netconn calls (see NETCONN_FLAG_NO_AUTO_RECVED) */ +#define netconn_get_noautorecved(conn) (((conn)->flags & NETCONN_FLAG_NO_AUTO_RECVED) != 0) + +#if LWIP_SO_SNDTIMEO +/** Set the send timeout in milliseconds */ +#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) +/** Get the send timeout in milliseconds */ +#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO +/** Set the receive timeout in milliseconds */ +#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) +/** Get the receive timeout in milliseconds */ +#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF +/** Set the receive buffer in bytes */ +#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) +/** Get the receive buffer in bytes */ +#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) +#endif /* LWIP_SO_RCVBUF*/ + +#if LWIP_NETCONN_SEM_PER_THREAD +void netconn_thread_init(void); +void netconn_thread_cleanup(void); +#else /* LWIP_NETCONN_SEM_PER_THREAD */ +#define netconn_thread_init() +#define netconn_thread_cleanup() +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#endif /* LWIP_HDR_API_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api_msg.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api_msg.h new file mode 100644 index 0000000..3505bf3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/api_msg.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_API_MSG_H +#define LWIP_HDR_API_MSG_H + +#include "lwip/opt.h" + +#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +/* don't export the netconn functions when socket API is enabled but netconn API is disabled */ +#if LWIP_NETCONN +#define LWIP_NETCONN_SCOPE +#else /* LWIP_NETCONN */ +#define LWIP_NETCONN_SCOPE static +#endif /* LWIP_NETCONN */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/sys.h" +#include "lwip/igmp.h" +#include "lwip/api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_MPU_COMPATIBLE +#define API_MSG_M_DEF(m) m +#else /* LWIP_MPU_COMPATIBLE */ +#define API_MSG_M_DEF(m) *m +#endif /* LWIP_MPU_COMPATIBLE */ + +/* For the netconn API, these values are use as a bitmask! */ +#define NETCONN_SHUT_RD 1 +#define NETCONN_SHUT_WR 2 +#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) + +/* IP addresses and port numbers are expected to be in + * the same byte order as in the corresponding pcb. + */ +/** This struct includes everything that is necessary to execute a function + for a netconn in another thread context (mainly used to process netconns + in the tcpip_thread context to be thread safe). */ +struct api_msg_msg { + /** The netconn which to process - always needed: it includes the semaphore + which is used to block the application thread until the function finished. */ + struct netconn *conn; + /** The return value of the function executed in tcpip_thread. */ + err_t err; + /** Depending on the executed function, one of these union members is used */ + union { + /** used for lwip_netconn_do_send */ + struct netbuf *b; + /** used for lwip_netconn_do_newconn */ + struct { + u8_t proto; + } n; + /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ + struct { + ip_addr_t API_MSG_M_DEF(ipaddr); + u16_t port; + } bc; + /** used for lwip_netconn_do_getaddr */ + struct { + ipX_addr_t API_MSG_M_DEF(ipaddr); + u16_t API_MSG_M_DEF(port); + u8_t local; + } ad; + /** used for lwip_netconn_do_write */ + struct { + const void *dataptr; + size_t len; + u8_t apiflags; +#if LWIP_SO_SNDTIMEO + u32_t time_started; +#endif /* LWIP_SO_SNDTIMEO */ + } w; + /** used for lwip_netconn_do_recv */ + struct { + u32_t len; + } r; + /** used for lwip_netconn_do_close (/shutdown) */ + struct { + u8_t shut; + } sd; +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) + /** used for lwip_netconn_do_join_leave_group */ + struct { + ipX_addr_t API_MSG_M_DEF(multiaddr); + ipX_addr_t API_MSG_M_DEF(netif_addr); + enum netconn_igmp join_or_leave; + } jl; +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ +#if TCP_LISTEN_BACKLOG + struct { + u8_t backlog; + } lb; +#endif /* TCP_LISTEN_BACKLOG */ + } msg; +#if LWIP_NETCONN_SEM_PER_THREAD + sys_sem_t* op_completed_sem; +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ +}; + +#if LWIP_NETCONN_SEM_PER_THREAD +#define LWIP_API_MSG_SEM(msg) ((msg)->op_completed_sem) +#else /* LWIP_NETCONN_SEM_PER_THREAD */ +#define LWIP_API_MSG_SEM(msg) (&(msg)->conn->op_completed) +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + + +/** This struct contains a function to execute in another thread context and + a struct api_msg_msg that serves as an argument for this function. + This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */ +struct api_msg { + /** function to execute in tcpip_thread context */ + void (* function)(struct api_msg_msg *msg); + /** arguments for this function */ + struct api_msg_msg msg; +}; + +#if LWIP_DNS +/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, + it has its own struct (to avoid struct api_msg getting bigger than necessary). + lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg + (see netconn_gethostbyname). */ +struct dns_api_msg { + /** Hostname to query or dotted IP address string */ +#if LWIP_MPU_COMPATIBLE + char name[DNS_MAX_NAME_LENGTH]; +#else /* LWIP_MPU_COMPATIBLE */ + const char *name; +#endif /* LWIP_MPU_COMPATIBLE */ + /** Rhe resolved address is stored here */ + ip_addr_t API_MSG_M_DEF(addr); + /** This semaphore is posted when the name is resolved, the application thread + should wait on it. */ + sys_sem_t API_MSG_M_DEF(sem); + /** Errors are given back here */ + err_t API_MSG_M_DEF(err); +}; +#endif /* LWIP_DNS */ + +LWIP_NETCONN_SCOPE void lwip_netconn_do_newconn ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_delconn ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_bind ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_connect ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_disconnect ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_listen ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_send ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_recv ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_write ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_getaddr ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_close ( struct api_msg_msg *msg); +LWIP_NETCONN_SCOPE void lwip_netconn_do_shutdown ( struct api_msg_msg *msg); +#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) +LWIP_NETCONN_SCOPE void lwip_netconn_do_join_leave_group( struct api_msg_msg *msg); +#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ + +#if LWIP_DNS +LWIP_NETCONN_SCOPE void lwip_netconn_do_gethostbyname(void *arg); +#endif /* LWIP_DNS */ + +LWIP_NETCONN_SCOPE struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); +LWIP_NETCONN_SCOPE void netconn_free(struct netconn *conn); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#endif /* LWIP_HDR_API_MSG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/arch.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/arch.h new file mode 100644 index 0000000..4cdb764 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/arch.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_ARCH_H +#define LWIP_HDR_ARCH_H + +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +#include "arch/cc.h" + +/** Temporary: define format string for size_t if not defined in cc.h */ +#ifndef SZT_F +#define SZT_F U32_F +#endif /* SZT_F */ +/** Temporary upgrade helper: define format string for u8_t as hex if not + defined in cc.h */ +#ifndef X8_F +#define X8_F "02x" +#endif /* X8_F */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PACK_STRUCT_BEGIN +#define PACK_STRUCT_BEGIN +#endif /* PACK_STRUCT_BEGIN */ + +#ifndef PACK_STRUCT_END +#define PACK_STRUCT_END +#endif /* PACK_STRUCT_END */ + +#ifndef PACK_STRUCT_STRUCT +#define PACK_STRUCT_STRUCT +#endif /* PACK_STRUCT_STRUCT */ + +#ifndef PACK_STRUCT_FIELD +#define PACK_STRUCT_FIELD(x) x +#endif /* PACK_STRUCT_FIELD */ + +/* Used for struct fields of u8_t, + * where some compilers warn that packing is not necessary */ +#ifndef PACK_STRUCT_FLD_8 +#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x) +#endif /* PACK_STRUCT_FLD_8 */ + +/* Used for struct fields of that are packed structs themself, + * where some compilers warn that packing is not necessary */ +#ifndef PACK_STRUCT_FLD_S +#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x) +#endif /* PACK_STRUCT_FLD_S */ + + +#ifndef LWIP_UNUSED_ARG +#define LWIP_UNUSED_ARG(x) (void)x +#endif /* LWIP_UNUSED_ARG */ + + +#ifdef LWIP_PROVIDE_ERRNO + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ + +#ifndef errno +extern int errno; +#endif + +#endif /* LWIP_PROVIDE_ERRNO */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_ARCH_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/autoip.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/autoip.h new file mode 100644 index 0000000..9a062c6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/autoip.h @@ -0,0 +1,121 @@ +/** + * @file + * + * AutoIP Automatic LinkLocal IP Configuration + */ + +/* + * + * Copyright (c) 2007 Dominik Spies + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dominik Spies + * + * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform + * with RFC 3927. + * + * + * Please coordinate changes and requests with Dominik Spies + * + */ + +#ifndef LWIP_HDR_AUTOIP_H +#define LWIP_HDR_AUTOIP_H + +#include "lwip/opt.h" + +#if LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" +#include "netif/etharp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* AutoIP Timing */ +#define AUTOIP_TMR_INTERVAL 100 +#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) + +/* RFC 3927 Constants */ +#define PROBE_WAIT 1 /* second (initial random delay) */ +#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ +#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ +#define PROBE_NUM 3 /* (number of probe packets) */ +#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ +#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ +#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ +#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ +#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ +#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ + +/* AutoIP client states */ +#define AUTOIP_STATE_OFF 0 +#define AUTOIP_STATE_PROBING 1 +#define AUTOIP_STATE_ANNOUNCING 2 +#define AUTOIP_STATE_BOUND 3 + +struct autoip +{ + ip_addr_t llipaddr; /* the currently selected, probed, announced or used LL IP-Address */ + u8_t state; /* current AutoIP state machine state */ + u8_t sent_num; /* sent number of probes or announces, dependent on state */ + u16_t ttw; /* ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ + u8_t lastconflict; /* ticks until a conflict can be solved by defending */ + u8_t tried_llipaddr; /* total number of probed/used Link Local IP-Addresses */ +}; + + +#define autoip_init() /* Compatibility define, no init needed. */ + +/** Set a struct autoip allocated by the application to work with */ +void autoip_set_struct(struct netif *netif, struct autoip *autoip); + +/** Remove a struct autoip previously set to the netif using autoip_set_struct() */ +#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0) + +/** Start AutoIP client */ +err_t autoip_start(struct netif *netif); + +/** Stop AutoIP client */ +err_t autoip_stop(struct netif *netif); + +/** Handles every incoming ARP Packet, called by etharp_arp_input */ +void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); + +/** Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds */ +void autoip_tmr(void); + +/** Handle a possible change in the network configuration */ +void autoip_network_changed(struct netif *netif); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_AUTOIP */ + +#endif /* LWIP_HDR_AUTOIP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/debug.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/debug.h new file mode 100644 index 0000000..8844e73 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/debug.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_DEBUG_H +#define LWIP_HDR_DEBUG_H + +#include "lwip/arch.h" +#include "lwip/opt.h" +#include //Realtek add +/** lower two bits indicate debug level + * - 0 all + * - 1 warning + * - 2 serious + * - 3 severe + */ +#define LWIP_DBG_LEVEL_ALL 0x00 +#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL /* compatibility define only */ +#define LWIP_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */ +#define LWIP_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */ +#define LWIP_DBG_LEVEL_SEVERE 0x03 +#define LWIP_DBG_MASK_LEVEL 0x03 + +/** flag for LWIP_DEBUGF to enable that debug message */ +#define LWIP_DBG_ON 0x80U +/** flag for LWIP_DEBUGF to disable that debug message */ +#define LWIP_DBG_OFF 0x00U + +/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ +#define LWIP_DBG_TRACE 0x40U +/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ +#define LWIP_DBG_STATE 0x20U +/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ +#define LWIP_DBG_FRESH 0x10U +/** flag for LWIP_DEBUGF to halt after printing this debug message */ +#define LWIP_DBG_HALT 0x08U + +#ifndef LWIP_NOASSERT +#define LWIP_ASSERT(message, assertion) do { if(!(assertion)) \ + LWIP_PLATFORM_ASSERT(message); } while(0) +#else /* LWIP_NOASSERT */ +#define LWIP_ASSERT(message, assertion) +#endif /* LWIP_NOASSERT */ + +/** if "expression" isn't true, then print "message" and execute "handler" expression */ +#ifndef LWIP_ERROR +#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ + LWIP_PLATFORM_ASSERT(message); handler;}} while(0) +#endif /* LWIP_ERROR */ + +#ifdef LWIP_DEBUG +/** print debug message only if debug message type is enabled... + * AND is of correct type AND is at least LWIP_DBG_LEVEL + */ + + +#define LWIP_PLATFORM_DIAG printf //Realtek add +#define LWIP_DEBUGF(debug, message) do { \ + if ( \ + ((debug) & LWIP_DBG_ON) && \ + ((debug) & LWIP_DBG_TYPES_ON) && \ + ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ + LWIP_PLATFORM_DIAG message; \ + if ((debug) & LWIP_DBG_HALT) { \ + while(1); \ + } \ + } \ + } while(0) + +#else /* LWIP_DEBUG */ +#define LWIP_DEBUGF(debug, message) +#endif /* LWIP_DEBUG */ + +#endif /* LWIP_HDR_DEBUG_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/def.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/def.h new file mode 100644 index 0000000..c985a87 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/def.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_DEF_H +#define LWIP_HDR_DEF_H + +/* arch.h might define NULL already */ +#include "lwip/arch.h" +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) +#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) + +#ifndef NULL +#define NULL ((void *)0) +#endif + +/* Endianess-optimized shifting of two u8_t to create one u16_t */ +#if BYTE_ORDER == LITTLE_ENDIAN +#define LWIP_MAKE_U16(a, b) ((a << 8) | b) +#else +#define LWIP_MAKE_U16(a, b) ((b << 8) | a) +#endif + +#ifndef LWIP_PLATFORM_BYTESWAP +#define LWIP_PLATFORM_BYTESWAP 0 +#endif + +#ifndef LWIP_PREFIX_BYTEORDER_FUNCS +/* workaround for naming collisions on some platforms */ + +#ifdef htons +#undef htons +#endif /* htons */ +#ifdef htonl +#undef htonl +#endif /* htonl */ +#ifdef ntohs +#undef ntohs +#endif /* ntohs */ +#ifdef ntohl +#undef ntohl +#endif /* ntohl */ + +#define htons(x) lwip_htons(x) +#define ntohs(x) lwip_ntohs(x) +#define htonl(x) lwip_htonl(x) +#define ntohl(x) lwip_ntohl(x) +#endif /* LWIP_PREFIX_BYTEORDER_FUNCS */ + +#if BYTE_ORDER == BIG_ENDIAN +#define lwip_htons(x) (x) +#define lwip_ntohs(x) (x) +#define lwip_htonl(x) (x) +#define lwip_ntohl(x) (x) +#define PP_HTONS(x) (x) +#define PP_NTOHS(x) (x) +#define PP_HTONL(x) (x) +#define PP_NTOHL(x) (x) +#else /* BYTE_ORDER != BIG_ENDIAN */ +#if LWIP_PLATFORM_BYTESWAP +#define lwip_htons(x) LWIP_PLATFORM_HTONS(x) +#define lwip_ntohs(x) LWIP_PLATFORM_HTONS(x) +#define lwip_htonl(x) LWIP_PLATFORM_HTONL(x) +#define lwip_ntohl(x) LWIP_PLATFORM_HTONL(x) +#else /* LWIP_PLATFORM_BYTESWAP */ +u16_t lwip_htons(u16_t x); +u16_t lwip_ntohs(u16_t x); +u32_t lwip_htonl(u32_t x); +u32_t lwip_ntohl(u32_t x); +#endif /* LWIP_PLATFORM_BYTESWAP */ + +/* These macros should be calculated by the preprocessor and are used + with compile-time constants only (so that there is no little-endian + overhead at runtime). */ +#define PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8)) +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_HTONL(x) ((((x) & 0xff) << 24) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff0000UL) >> 8) | \ + (((x) & 0xff000000UL) >> 24)) +#define PP_NTOHL(x) PP_HTONL(x) + +#endif /* BYTE_ORDER == BIG_ENDIAN */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_DEF_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp.h new file mode 100644 index 0000000..52f63e7 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp.h @@ -0,0 +1,242 @@ +/** @file + */ + +#ifndef LWIP_HDR_DHCP_H +#define LWIP_HDR_DHCP_H + +#include "lwip/opt.h" + +#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/netif.h" +#include "lwip/udp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** period (in seconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_SECS 60 +/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ +#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) +/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ +#define DHCP_FINE_TIMER_MSECS 500 + +#define DHCP_CHADDR_LEN 16U +#define DHCP_SNAME_LEN 64U +#define DHCP_FILE_LEN 128U + +struct dhcp +{ + /** transaction identifier of last sent request */ + u32_t xid; + /** our connection to the DHCP server */ + struct udp_pcb *pcb; + /** incoming msg */ + struct dhcp_msg *msg_in; + /** current DHCP state machine state */ + u8_t state; + /** retries of current request */ + u8_t tries; +#if LWIP_DHCP_AUTOIP_COOP + u8_t autoip_coop_state; +#endif + u8_t subnet_mask_given; + + struct pbuf *p_out; /* pbuf of outcoming msg */ + struct dhcp_msg *msg_out; /* outgoing msg */ + u16_t options_out_len; /* outgoing msg options length */ + u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ + u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ + u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ + ip_addr_t server_ip_addr; /* dhcp server address that offered this lease */ + ip_addr_t offered_ip_addr; + ip_addr_t offered_sn_mask; + ip_addr_t offered_gw_addr; + ip_addr_t offered_bc_addr; + + u32_t offered_t0_lease; /* lease period (in seconds) */ + u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ + u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */ +#if LWIP_DHCP_BOOTP_FILE + ip_addr_t offered_si_addr; + char boot_file_name[DHCP_FILE_LEN]; +#endif /* LWIP_DHCP_BOOTPFILE */ +}; + +/* MUST be compiled with "pack structs" or equivalent! */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** minimum set of fields of any DHCP message */ +struct dhcp_msg +{ + PACK_STRUCT_FLD_8(u8_t op); + PACK_STRUCT_FLD_8(u8_t htype); + PACK_STRUCT_FLD_8(u8_t hlen); + PACK_STRUCT_FLD_8(u8_t hops); + PACK_STRUCT_FIELD(u32_t xid); + PACK_STRUCT_FIELD(u16_t secs); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FLD_S(ip_addr_p_t ciaddr); + PACK_STRUCT_FLD_S(ip_addr_p_t yiaddr); + PACK_STRUCT_FLD_S(ip_addr_p_t siaddr); + PACK_STRUCT_FLD_S(ip_addr_p_t giaddr); + PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]); + PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]); + PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]); + PACK_STRUCT_FIELD(u32_t cookie); +#define DHCP_MIN_OPTIONS_LEN 68U +/** make sure user does not configure this too small */ +#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) +# undef DHCP_OPTIONS_LEN +#endif +/** allow this to be configured in lwipopts.h, but not too small */ +#if (!defined(DHCP_OPTIONS_LEN)) +/** set this to be sufficient for your options in outgoing DHCP msgs */ +# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN +#endif + PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); +/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ +#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0) +void dhcp_cleanup(struct netif *netif); +/** start DHCP configuration */ +err_t dhcp_start(struct netif *netif); +/** enforce early lease renewal (not needed normally)*/ +err_t dhcp_renew(struct netif *netif); +/** release the DHCP lease, usually called before dhcp_stop()*/ +err_t dhcp_release(struct netif *netif); +err_t dhcp_release_unicast(struct netif *netif); //Realtek add +/** stop DHCP configuration */ +void dhcp_stop(struct netif *netif); +/** inform server of our manual IP address */ +void dhcp_inform(struct netif *netif); +/** Handle a possible change in the network configuration */ +void dhcp_network_changed(struct netif *netif); + +/** if enabled, check whether the offered IP address is not in use, using ARP */ +#if DHCP_DOES_ARP_CHECK +void dhcp_arp_reply(struct netif *netif, ip_addr_t *addr); +#endif + +/** to be called every minute */ +void dhcp_coarse_tmr(void); +/** to be called every half second */ +void dhcp_fine_tmr(void); + +/** DHCP message item offsets and length */ +#define DHCP_OP_OFS 0 +#define DHCP_HTYPE_OFS 1 +#define DHCP_HLEN_OFS 2 +#define DHCP_HOPS_OFS 3 +#define DHCP_XID_OFS 4 +#define DHCP_SECS_OFS 8 +#define DHCP_FLAGS_OFS 10 +#define DHCP_CIADDR_OFS 12 +#define DHCP_YIADDR_OFS 16 +#define DHCP_SIADDR_OFS 20 +#define DHCP_GIADDR_OFS 24 +#define DHCP_CHADDR_OFS 28 +#define DHCP_SNAME_OFS 44 +#define DHCP_FILE_OFS 108 +#define DHCP_MSG_LEN 236 + +#define DHCP_COOKIE_OFS DHCP_MSG_LEN +#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4) + +#define DHCP_CLIENT_PORT 68 +#define DHCP_SERVER_PORT 67 + +/** DHCP client states */ +#define DHCP_OFF 0 +#define DHCP_REQUESTING 1 +#define DHCP_INIT 2 +#define DHCP_REBOOTING 3 +#define DHCP_REBINDING 4 +#define DHCP_RENEWING 5 +#define DHCP_SELECTING 6 +/* not yet implemented #define DHCP_INFORMING 7*/ +#define DHCP_CHECKING 8 +/* not yet implemented #define DHCP_PERMANENT 9*/ +#define DHCP_BOUND 10 +#define DHCP_RELEASING 11 //Realtek modified +#define DHCP_BACKING_OFF 12 + +/** AUTOIP cooperation flags */ +#define DHCP_AUTOIP_COOP_STATE_OFF 0 +#define DHCP_AUTOIP_COOP_STATE_ON 1 + +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + +/** DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/** DHCP hardware type, currently only ethernet is supported */ +#define DHCP_HTYPE_ETH 1 + +#define DHCP_MAGIC_COOKIE 0x63825363UL + +/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ + +/** BootP options */ +#define DHCP_OPTION_PAD 0 +#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_HOSTNAME 12 +#define DHCP_OPTION_IP_TTL 23 +#define DHCP_OPTION_MTU 26 +#define DHCP_OPTION_BROADCAST 28 +#define DHCP_OPTION_TCP_TTL 37 +#define DHCP_OPTION_END 255 + +/** DHCP options */ +#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ +#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ +#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ + +#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ +#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 + +#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ +#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ + +#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ +#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 + +#define DHCP_OPTION_T1 58 /* T1 renewal time */ +#define DHCP_OPTION_T2 59 /* T2 rebinding time */ +#define DHCP_OPTION_US 60 +#define DHCP_OPTION_CLIENT_ID 61 +#define DHCP_OPTION_TFTP_SERVERNAME 66 +#define DHCP_OPTION_BOOTFILE 67 + +/** possible combinations of overloading the file and sname fields with options */ +#define DHCP_OVERLOAD_NONE 0 +#define DHCP_OVERLOAD_FILE 1 +#define DHCP_OVERLOAD_SNAME 2 +#define DHCP_OVERLOAD_SNAME_FILE 3 + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DHCP */ + +#endif /*LWIP_HDR_DHCP_H*/ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp6.h new file mode 100644 index 0000000..345bcf0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dhcp6.h @@ -0,0 +1,58 @@ +/** + * @file + * + * IPv6 address autoconfiguration as per RFC 4862. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * IPv6 address autoconfiguration as per RFC 4862. + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef LWIP_HDR_IP6_DHCP6_H +#define LWIP_HDR_IP6_DHCP6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ + + +struct dhcp6 +{ + /*TODO: implement DHCP6*/ +}; + +#endif /* LWIP_IPV6_DHCP6 */ + +#endif /* LWIP_HDR_IP6_DHCP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dns.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dns.h new file mode 100644 index 0000000..eb81c90 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/dns.h @@ -0,0 +1,117 @@ +/** + * lwip DNS resolver header file. + + * Author: Jim Pettinato + * April 2007 + + * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LWIP_HDR_DNS_H +#define LWIP_HDR_DNS_H + +#include "lwip/opt.h" + +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** DNS timer period */ +#define DNS_TMR_INTERVAL 1000 + +/** DNS field TYPE used for "Resource Records" */ +#define DNS_RRTYPE_A 1 /* a host address */ +#define DNS_RRTYPE_NS 2 /* an authoritative name server */ +#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ +#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ +#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ +#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ +#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ +#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ +#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ +#define DNS_RRTYPE_WKS 11 /* a well known service description */ +#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ +#define DNS_RRTYPE_HINFO 13 /* host information */ +#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ +#define DNS_RRTYPE_MX 15 /* mail exchange */ +#define DNS_RRTYPE_TXT 16 /* text strings */ + +/** DNS field CLASS used for "Resource Records" */ +#define DNS_RRCLASS_IN 1 /* the Internet */ +#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ +#define DNS_RRCLASS_CH 3 /* the CHAOS class */ +#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ +#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ + +#if DNS_LOCAL_HOSTLIST +/** struct used for local host-list */ +struct local_hostlist_entry { + /** static hostname */ + const char *name; + /** static host address in network byteorder */ + ip_addr_t addr; + struct local_hostlist_entry *next; +}; +#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN +#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH +#endif +#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ +#endif /* DNS_LOCAL_HOSTLIST */ + +/** Callback which is invoked when a hostname is found. + * A function of this type must be implemented by the application using the DNS resolver. + * @param name pointer to the name that was looked up. + * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, + * or NULL if the name could not be found (or on any other error). + * @param callback_arg a user-specified callback argument passed to dns_gethostbyname +*/ +typedef void (*dns_found_callback)(const char *name, ip_addr_t *ipaddr, void *callback_arg); + +void dns_init(void); +void dns_tmr(void); +void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); +ip_addr_t dns_getserver(u8_t numdns); +err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, + dns_found_callback found, void *callback_arg); + +#if DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +int dns_local_removehost(const char *hostname, const ip_addr_t *addr); +err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); +#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS */ + +#endif /* LWIP_HDR_DNS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/err.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/err.h new file mode 100644 index 0000000..a48430d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/err.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_ERR_H +#define LWIP_HDR_ERR_H + +#include "lwip/opt.h" +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define LWIP_ERR_T in cc.h if you want to use + * a different type for your platform (must be signed). */ +#ifdef LWIP_ERR_T +typedef LWIP_ERR_T err_t; +#else /* LWIP_ERR_T */ +typedef s8_t err_t; +#endif /* LWIP_ERR_T*/ + +/* Definitions for error constants. */ + +#define ERR_OK 0 /* No error, everything OK. */ +#define ERR_MEM -1 /* Out of memory error. */ +#define ERR_BUF -2 /* Buffer error. */ +#define ERR_TIMEOUT -3 /* Timeout. */ +#define ERR_RTE -4 /* Routing problem. */ +#define ERR_INPROGRESS -5 /* Operation in progress */ +#define ERR_VAL -6 /* Illegal value. */ +#define ERR_WOULDBLOCK -7 /* Operation would block. */ +#define ERR_USE -8 /* Address in use. */ +#define ERR_ISCONN -9 /* Already connected. */ + +#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN) + +#define ERR_CONN -10 /* Not connected. */ +#define ERR_IS_FATAL_LISTENCONNECT(e) ((e) < ERR_CONN) + +#define ERR_ABRT -11 /* Connection aborted. */ +#define ERR_RST -12 /* Connection reset. */ +#define ERR_CLSD -13 /* Connection closed. */ + +#define ERR_ARG -14 /* Illegal argument. */ + +#define ERR_IF -15 /* Low-level netif error */ + + +#ifdef LWIP_DEBUG +extern const char *lwip_strerr(err_t err); +#else +#define lwip_strerr(x) "" +#endif /* LWIP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_ERR_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ethip6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ethip6.h new file mode 100644 index 0000000..31fed18 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ethip6.h @@ -0,0 +1,68 @@ +/** + * @file + * + * Ethernet output for IPv6. Uses ND tables for link-layer addressing. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef LWIP_HDR_ETHIP6_H +#define LWIP_HDR_ETHIP6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +err_t ethip6_output(struct netif *netif, struct pbuf *q, ip6_addr_t *ip6addr); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 && LWIP_ETHERNET */ + +#endif /* LWIP_HDR_ETHIP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp.h new file mode 100644 index 0000000..0ca6522 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_ICMP_H +#define LWIP_HDR_ICMP_H + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" + +#if LWIP_IPV6 && LWIP_ICMP6 +#include "lwip/icmp6.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define ICMP_ER 0 /* echo reply */ +#define ICMP_DUR 3 /* destination unreachable */ +#define ICMP_SQ 4 /* source quench */ +#define ICMP_RD 5 /* redirect */ +#define ICMP_ECHO 8 /* echo */ +#define ICMP_TE 11 /* time exceeded */ +#define ICMP_PP 12 /* parameter problem */ +#define ICMP_TS 13 /* timestamp */ +#define ICMP_TSR 14 /* timestamp reply */ +#define ICMP_IRQ 15 /* information request */ +#define ICMP_IR 16 /* information reply */ + +enum icmp_dur_type { + ICMP_DUR_NET = 0, /* net unreachable */ + ICMP_DUR_HOST = 1, /* host unreachable */ + ICMP_DUR_PROTO = 2, /* protocol unreachable */ + ICMP_DUR_PORT = 3, /* port unreachable */ + ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */ + ICMP_DUR_SR = 5 /* source route failed */ +}; + +enum icmp_te_type { + ICMP_TE_TTL = 0, /* time to live exceeded in transit */ + ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */ +}; + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +/** This is the standard ICMP header only that the u32_t data + * is split to two u16_t like ICMP echo needs it. + * This header is also used for other ICMP types that do not + * use the data part. + */ +PACK_STRUCT_BEGIN +struct icmp_echo_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define ICMPH_TYPE(hdr) ((hdr)->type) +#define ICMPH_CODE(hdr) ((hdr)->code) + +/** Combines type and code to an u16_t */ +#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) +#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) + + +#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ + +void icmp_input(struct pbuf *p, struct netif *inp); +void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); +void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); + +#endif /* LWIP_ICMP */ + +#if (LWIP_IPV6 && LWIP_ICMP6) +#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ + icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ + icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) +#elif LWIP_ICMP +#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) +#else /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ +#define icmp_port_unreach(isipv6, pbuf) +#endif /* (LWIP_IPV6 && LWIP_ICMP6) || LWIP_ICMP*/ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_ICMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp6.h new file mode 100644 index 0000000..9d57103 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/icmp6.h @@ -0,0 +1,152 @@ +/** + * @file + * + * IPv6 version of ICMP, as per RFC 4443. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef LWIP_HDR_ICMP6_H +#define LWIP_HDR_ICMP6_H + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +enum icmp6_type { + ICMP6_TYPE_DUR = 1, /* Destination unreachable */ + ICMP6_TYPE_PTB = 2, /* Packet too big */ + ICMP6_TYPE_TE = 3, /* Time exceeded */ + ICMP6_TYPE_PP = 4, /* Parameter problem */ + ICMP6_TYPE_PE1 = 100, /* Private experimentation */ + ICMP6_TYPE_PE2 = 101, /* Private experimentation */ + ICMP6_TYPE_RSV_ERR = 127, /* Reserved for expansion of error messages */ + + ICMP6_TYPE_EREQ = 128, /* Echo request */ + ICMP6_TYPE_EREP = 129, /* Echo reply */ + ICMP6_TYPE_MLQ = 130, /* Multicast listener query */ + ICMP6_TYPE_MLR = 131, /* Multicast listener report */ + ICMP6_TYPE_MLD = 132, /* Multicast listener done */ + ICMP6_TYPE_RS = 133, /* Router solicitation */ + ICMP6_TYPE_RA = 134, /* Router advertisement */ + ICMP6_TYPE_NS = 135, /* Neighbor solicitation */ + ICMP6_TYPE_NA = 136, /* Neighbor advertisement */ + ICMP6_TYPE_RD = 137, /* Redirect */ + ICMP6_TYPE_MRA = 151, /* Multicast router advertisement */ + ICMP6_TYPE_MRS = 152, /* Multicast router solicitation */ + ICMP6_TYPE_MRT = 153, /* Multicast router termination */ + ICMP6_TYPE_PE3 = 200, /* Private experimentation */ + ICMP6_TYPE_PE4 = 201, /* Private experimentation */ + ICMP6_TYPE_RSV_INF = 255 /* Reserved for expansion of informational messages */ +}; + +enum icmp6_dur_code { + ICMP6_DUR_NO_ROUTE = 0, /* No route to destination */ + ICMP6_DUR_PROHIBITED = 1, /* Communication with destination administratively prohibited */ + ICMP6_DUR_SCOPE = 2, /* Beyond scope of source address */ + ICMP6_DUR_ADDRESS = 3, /* Address unreachable */ + ICMP6_DUR_PORT = 4, /* Port unreachable */ + ICMP6_DUR_POLICY = 5, /* Source address failed ingress/egress policy */ + ICMP6_DUR_REJECT_ROUTE = 6 /* Reject route to destination */ +}; + +enum icmp6_te_code { + ICMP6_TE_HL = 0, /* Hop limit exceeded in transit */ + ICMP6_TE_FRAG = 1 /* Fragment reassembly time exceeded */ +}; + +enum icmp6_pp_code { + ICMP6_PP_FIELD = 0, /* Erroneous header field encountered */ + ICMP6_PP_HEADER = 1, /* Unrecognized next header type encountered */ + ICMP6_PP_OPTION = 2 /* Unrecognized IPv6 option encountered */ +}; + +/** This is the standard ICMP6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t data); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** This is the ICMP6 header adapted for echo req/resp. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct icmp6_echo_hdr { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t id); + PACK_STRUCT_FIELD(u16_t seqno); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +void icmp6_input(struct pbuf *p, struct netif *inp); +void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); +void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); +void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); +void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); + +#endif /* LWIP_ICMP6 && LWIP_IPV6 */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* LWIP_HDR_ICMP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/igmp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/igmp.h new file mode 100644 index 0000000..4687b1f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/igmp.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2002 CITEL Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is a contribution to the lwIP TCP/IP stack. + * The Swedish Institute of Computer Science and Adam Dunkels + * are specifically granted permission to redistribute this + * source code. +*/ + +#ifndef LWIP_HDR_IGMP_H +#define LWIP_HDR_IGMP_H + +#include "lwip/opt.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" + +#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* IGMP timer */ +#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ +#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) +#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) + +/* MAC Filter Actions, these are passed to a netif's + * igmp_mac_filter callback function. */ +#define IGMP_DEL_MAC_FILTER 0 +#define IGMP_ADD_MAC_FILTER 1 + + +/** + * igmp group structure - there is + * a list of groups for each interface + * these should really be linked from the interface, but + * if we keep them separate we will not affect the lwip original code + * too much + * + * There will be a group for the all systems group address but this + * will not run the state machine as it is used to kick off reports + * from all the other groups + */ +struct igmp_group { + /** next link */ + struct igmp_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting, negative is OFF */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/* Prototypes */ +void igmp_init(void); +err_t igmp_start(struct netif *netif); +err_t igmp_stop(struct netif *netif); +void igmp_report_groups(struct netif *netif); +struct igmp_group *igmp_lookfor_group(struct netif *ifp, ip_addr_t *addr); +void igmp_input(struct pbuf *p, struct netif *inp, ip_addr_t *dest); +err_t igmp_joingroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +err_t igmp_leavegroup(ip_addr_t *ifaddr, ip_addr_t *groupaddr); +void igmp_tmr(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IGMP */ + +#endif /* LWIP_HDR_IGMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet.h new file mode 100644 index 0000000..2895d61 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_INET_H +#define LWIP_HDR_INET_H + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/ip_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) +typedef u32_t in_addr_t; +#endif +/** For compatibility with BSD code */ +struct in_addr { + in_addr_t s_addr; +}; + +/** 255.255.255.255 */ +#define INADDR_NONE IPADDR_NONE +/** 127.0.0.1 */ +#define INADDR_LOOPBACK IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define INADDR_ANY IPADDR_ANY +/** 255.255.255.255 */ +#define INADDR_BROADCAST IPADDR_BROADCAST + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IN_CLASSA(a) IP_CLASSA(a) +#define IN_CLASSA_NET IP_CLASSA_NET +#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT +#define IN_CLASSA_HOST IP_CLASSA_HOST +#define IN_CLASSA_MAX IP_CLASSA_MAX + +#define IN_CLASSB(b) IP_CLASSB(b) +#define IN_CLASSB_NET IP_CLASSB_NET +#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT +#define IN_CLASSB_HOST IP_CLASSB_HOST +#define IN_CLASSB_MAX IP_CLASSB_MAX + +#define IN_CLASSC(c) IP_CLASSC(c) +#define IN_CLASSC_NET IP_CLASSC_NET +#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT +#define IN_CLASSC_HOST IP_CLASSC_HOST +#define IN_CLASSC_MAX IP_CLASSC_MAX + +#define IN_CLASSD(d) IP_CLASSD(d) +#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ +#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ +#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ +#define IN_CLASSD_MAX IP_CLASSD_MAX + +#define IN_MULTICAST(a) IP_MULTICAST(a) + +#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) +#define IN_BADCLASS(a) IP_BADCLASS(a) + +#define IN_LOOPBACKNET IP_LOOPBACKNET + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX +#endif +#if LWIP_IPV6 +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX +#endif +#endif + +#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) +#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) +/* ATTENTION: the next define only works because both s_addr and ip_addr_t are an u32_t effectively! */ +#define inet_addr_to_ipaddr_p(target_ipaddr_p, source_inaddr) ((target_ipaddr_p) = (ip_addr_t*)&((source_inaddr)->s_addr)) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) ipaddr_addr(cp) +#define inet_aton(cp, addr) ipaddr_aton(cp, (ip_addr_t*)addr) +#define inet_ntoa(addr) ipaddr_ntoa((ip_addr_t*)&(addr)) +#define inet_ntoa_r(addr, buf, buflen) ipaddr_ntoa_r((ip_addr_t*)&(addr), buf, buflen) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_INET_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet6.h new file mode 100644 index 0000000..afaa923 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet6.h @@ -0,0 +1,92 @@ +/** + * @file + * + * INET v6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef LWIP_HDR_INET6_H +#define LWIP_HDR_INET6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** For compatibility with BSD code */ +struct in6_addr { + union { + u8_t u8_addr[16]; + u32_t u32_addr[4]; + } un; +#define s6_addr un.u8_addr +}; + +#define IN6ADDR_ANY_INIT {0,0,0,0} +#define IN6ADDR_LOOPBACK_INIT {0,0,0,PP_HTONL(1)} + + +#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ + (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ + (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ + (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} +#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ + (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ + (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ + (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];} +/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */ +#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr)) + +/* directly map this to the lwip internal functions */ +#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) +#define inet6_ntoa(addr) ip6addr_ntoa((ip6_addr_t*)&(addr)) +#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((ip6_addr_t*)&(addr), buf, buflen) + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_HDR_INET6_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet_chksum.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet_chksum.h new file mode 100644 index 0000000..4171d0a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/inet_chksum.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_INET_CHKSUM_H +#define LWIP_HDR_INET_CHKSUM_H + +#include "lwip/opt.h" + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" + +/** Swap the bytes in an u16_t: much like htons() for little-endian */ +#ifndef SWAP_BYTES_IN_WORD +#if LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) +/* little endian and PLATFORM_BYTESWAP defined */ +#define SWAP_BYTES_IN_WORD(w) LWIP_PLATFORM_HTONS(w) +#else /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN) */ +/* can't use htons on big endian (or PLATFORM_BYTESWAP not defined)... */ +#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) +#endif /* LWIP_PLATFORM_BYTESWAP && (BYTE_ORDER == LITTLE_ENDIAN)*/ +#endif /* SWAP_BYTES_IN_WORD */ + +/** Split an u32_t in two u16_ts and add them up */ +#ifndef FOLD_U32T +#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) +#endif + +#if LWIP_CHECKSUM_ON_COPY +/** Function-like macro: same as MEMCPY but returns the checksum of copied data + as u16_t */ +#ifndef LWIP_CHKSUM_COPY +#define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) +#ifndef LWIP_CHKSUM_COPY_ALGORITHM +#define LWIP_CHKSUM_COPY_ALGORITHM 1 +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ +#endif /* LWIP_CHKSUM_COPY */ +#else /* LWIP_CHECKSUM_ON_COPY */ +#define LWIP_CHKSUM_COPY_ALGORITHM 0 +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#ifdef __cplusplus +extern "C" { +#endif + +u16_t inet_chksum(void *dataptr, u16_t len); +u16_t inet_chksum_pbuf(struct pbuf *p); +u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip_addr_t *src, ip_addr_t *dest); +u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, + u16_t proto_len, u16_t chksum_len, ip_addr_t *src, ip_addr_t *dest); +#if LWIP_CHKSUM_COPY_ALGORITHM +u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); +#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ + +#if LWIP_IPV6 +u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, + ip6_addr_t *src, ip6_addr_t *dest); +u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, + u16_t chksum_len, ip6_addr_t *src, ip6_addr_t *dest); + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo(p, proto, proto_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo(p, proto, proto_len, ipX_2_ip(src), ipX_2_ip(dest))) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + ((isipv6) ? \ + ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip6(src), ipX_2_ip6(dest)) :\ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ipX_2_ip(src), ipX_2_ip(dest))) + +#else /* LWIP_IPV6 */ + +#define ipX_chksum_pseudo(isipv6, p, proto, proto_len, src, dest) \ + inet_chksum_pseudo(p, proto, proto_len, src, dest) +#define ipX_chksum_pseudo_partial(isipv6, p, proto, proto_len, chksum_len, src, dest) \ + inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, src, dest) + +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_INET_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/init.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/init.h new file mode 100644 index 0000000..0a35993 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/init.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_INIT_H +#define LWIP_HDR_INIT_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** X.x.x: Major version of the stack */ +#define LWIP_VERSION_MAJOR 1U +/** x.X.x: Minor version of the stack */ +#define LWIP_VERSION_MINOR 4U +/** x.x.X: Revision of the stack */ +#define LWIP_VERSION_REVISION 1U +/** For release candidates, this is set to 1..254 + * For official releases, this is set to 255 (LWIP_RC_RELEASE) + * For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */ +#define LWIP_VERSION_RC 0U + +/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ +#define LWIP_RC_RELEASE 255U +/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for CVS versions */ +#define LWIP_RC_DEVELOPMENT 0U + +#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) +#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) +#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) + +/** Provides the version of the stack */ +#define LWIP_VERSION (LWIP_VERSION_MAJOR << 24 | LWIP_VERSION_MINOR << 16 | \ + LWIP_VERSION_REVISION << 8 | LWIP_VERSION_RC) + +/* Modules initialization */ +void lwip_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_INIT_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4.h new file mode 100644 index 0000000..c49a771 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_IP4_H +#define LWIP_HDR_IP4_H + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the function ip_output_if_opt() is only used with IGMP */ +#define IP_OPTIONS_SEND LWIP_IGMP + +#define IP_HLEN 20 + +#define IP_PROTO_ICMP 1 +#define IP_PROTO_IGMP 2 +#define IP_PROTO_UDP 17 +#define IP_PROTO_UDPLITE 136 +#define IP_PROTO_TCP 6 + + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_hdr { + /* version / header length */ + PACK_STRUCT_FLD_8(u8_t _v_hl); + /* type of service */ + PACK_STRUCT_FLD_8(u8_t _tos); + /* total length */ + PACK_STRUCT_FIELD(u16_t _len); + /* identification */ + PACK_STRUCT_FIELD(u16_t _id); + /* fragment offset field */ + PACK_STRUCT_FIELD(u16_t _offset); +#define IP_RF 0x8000U /* reserved fragment flag */ +#define IP_DF 0x4000U /* don't fragment flag */ +#define IP_MF 0x2000U /* more fragments flag */ +#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ + /* time to live */ + PACK_STRUCT_FLD_8(u8_t _ttl); + /* protocol*/ + PACK_STRUCT_FLD_8(u8_t _proto); + /* checksum */ + PACK_STRUCT_FIELD(u16_t _chksum); + /* source and destination IP addresses */ + PACK_STRUCT_FLD_S(ip_addr_p_t src); + PACK_STRUCT_FLD_S(ip_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IPH_V(hdr) ((hdr)->_v_hl >> 4) +#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) +#define IPH_TOS(hdr) ((hdr)->_tos) +#define IPH_LEN(hdr) ((hdr)->_len) +#define IPH_ID(hdr) ((hdr)->_id) +#define IPH_OFFSET(hdr) ((hdr)->_offset) +#define IPH_TTL(hdr) ((hdr)->_ttl) +#define IPH_PROTO(hdr) ((hdr)->_proto) +#define IPH_CHKSUM(hdr) ((hdr)->_chksum) + +#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (((v) << 4) | (hl)) +#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) +#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) +#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) +#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) +#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) +#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) +#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) + + +#define ip_init() /* Compatibility define, no init needed. */ +struct netif *ip_route(ip_addr_t *dest); +err_t ip_input(struct pbuf *p, struct netif *inp); +err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto); +err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); +err_t ip_output_if_src(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if IP_OPTIONS_SEND +err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +err_t ip_output_if_opt_src(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, + u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, + u16_t optlen); +#endif /* IP_OPTIONS_SEND */ + +#define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) + +#if IP_DEBUG +void ip_debug_print(struct pbuf *p); +#else +#define ip_debug_print(p) +#endif /* IP_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP_H */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4_addr.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4_addr.h new file mode 100644 index 0000000..6f6318b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip4_addr.h @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_IP4_ADDR_H +#define LWIP_HDR_IP4_ADDR_H + +#include "lwip/opt.h" +#include "lwip/def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the aligned version of ip_addr_t, + used as local variable, on the stack, etc. */ +struct ip_addr { + u32_t addr; +}; + +/* This is the packed version of ip_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr_packed { + PACK_STRUCT_FIELD(u32_t addr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip_addr_t as well as on ip_addr_p_t. */ +typedef struct ip_addr ip_addr_t; +typedef struct ip_addr_packed ip_addr_p_t; + +/* + * struct ipaddr2 is used in the definition of the ARP packet format in + * order to support compilers that don't have structure packing. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip_addr2 { + PACK_STRUCT_FIELD(u16_t addrw[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Forward declaration to not include netif.h */ +struct netif; + +extern const ip_addr_t ip_addr_any; +extern const ip_addr_t ip_addr_broadcast; + +/** IP_ADDR_ can be used as a fixed IP address + * for the wildcard and the broadcast address + */ +#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any) +#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast) + +/** 255.255.255.255 */ +#define IPADDR_NONE ((u32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define IPADDR_ANY ((u32_t)0x00000000UL) +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) + +/* Definitions of the bits in an Internet address integer. + + On subnets, host and network parts are found according to + the subnet mask, not these masks. */ +#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) +#define IP_CLASSA_NET 0xff000000 +#define IP_CLASSA_NSHIFT 24 +#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) +#define IP_CLASSA_MAX 128 + +#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) +#define IP_CLASSB_NET 0xffff0000 +#define IP_CLASSB_NSHIFT 16 +#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) +#define IP_CLASSB_MAX 65536 + +#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) +#define IP_CLASSC_NET 0xffffff00 +#define IP_CLASSC_NSHIFT 8 +#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) + +#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) +#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ +#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ +#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ +#define IP_MULTICAST(a) IP_CLASSD(a) + +#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) +#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) + +#define IP_LOOPBACKNET 127 /* official! */ + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IP address given by the four byte-parts */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IP address given by the four byte-parts. + Little-endian version that prevents the use of htonl. */ +#define IP4_ADDR(ipaddr, a,b,c,d) \ + (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** MEMCPY-like copying of IP addresses where addresses are known to be + * 16-bit-aligned if the port is correctly configured (so a port could define + * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ +#ifndef IPADDR2_COPY +#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t)) +#endif + +/** Copy IP address - faster than ip_addr_set: no NULL check */ +#define ip_addr_copy(dest, src) ((dest).addr = (src).addr) +/** Safely copy one IP address to another (src may be NULL) */ +#define ip_addr_set(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0 : \ + (src)->addr)) +/** Set complete address to zero */ +#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) +/** Set address to IPADDR_ANY (no need for htonl()) */ +#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) +/** Set address to loopback address */ +#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) +/** Safely copy one IP address to another and change byte order + * from host- to network-order. */ +#define ip_addr_set_hton(dest, src) ((dest)->addr = \ + ((src) == NULL ? 0:\ + htonl((src)->addr))) +/** IPv4 only: set the IP address given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) +/** IPv4 only: get the IP address as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +/** Get the network address by combining host address with netmask */ +#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr)) + +/** + * Determine if two address are on the same network. + * + * @arg addr1 IP address 1 + * @arg addr2 IP address 2 + * @arg mask network identifier mask + * @return !0 if the network identifiers of both address match + */ +#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ + (mask)->addr) == \ + ((addr2)->addr & \ + (mask)->addr)) +#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) + +#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY) + +#define ip_addr_isbroadcast(ipaddr, netif) ip4_addr_isbroadcast((ipaddr)->addr, (netif)) +u8_t ip4_addr_isbroadcast(u32_t addr, const struct netif *netif); + +#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) +u8_t ip4_addr_netmask_valid(u32_t netmask); + +#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) + +#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) + +#define ip_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, \ + ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \ + ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0)) + +/* Get one byte from the 4-byte address */ +#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) +#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) +#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) +#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) +/* These are cast to u16_t, with the intent that they are often arguments + * to printf using the U16_F format from cc.h. */ +#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) +#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) +#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) +#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) + +#define IP4ADDR_STRLEN_MAX 16 +#define IPADDR_STRLEN_MAX IP4ADDR_STRLEN_MAX + +/** For backwards compatibility */ +#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) + +u32_t ipaddr_addr(const char *cp); +int ipaddr_aton(const char *cp, ip_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ipaddr_ntoa(const ip_addr_t *addr); +char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP_ADDR_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6.h new file mode 100644 index 0000000..a7b264f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6.h @@ -0,0 +1,198 @@ +/** + * @file + * + * IPv6 layer. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef LWIP_HDR_IP6_H +#define LWIP_HDR_IP6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/ip6_addr.h" +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" + +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define IP6_HLEN 40 + +#define IP6_NEXTH_HOPBYHOP 0 +#define IP6_NEXTH_TCP 6 +#define IP6_NEXTH_UDP 17 +#define IP6_NEXTH_ENCAPS 41 +#define IP6_NEXTH_ROUTING 43 +#define IP6_NEXTH_FRAGMENT 44 +#define IP6_NEXTH_ICMP6 58 +#define IP6_NEXTH_NONE 59 +#define IP6_NEXTH_DESTOPTS 60 +#define IP6_NEXTH_UDPLITE 136 + + +/* The IPv6 header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hdr { + /* version / traffic class / flow label */ + PACK_STRUCT_FIELD(u32_t _v_tc_fl); + /* payload length */ + PACK_STRUCT_FIELD(u16_t _plen); + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* hop limit */ + PACK_STRUCT_FLD_8(u8_t _hoplim); + /* source and destination IP addresses */ + PACK_STRUCT_FLD_S(ip6_addr_p_t src); + PACK_STRUCT_FLD_S(ip6_addr_p_t dest); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Hop-by-hop router alert option. */ +#define IP6_HBH_HLEN 8 +#define IP6_PAD1_OPTION 0 +#define IP6_PADN_ALERT_OPTION 1 +#define IP6_ROUTER_ALERT_OPTION 5 +#define IP6_ROUTER_ALERT_VALUE_MLD 0 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_hbh_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* header length */ + PACK_STRUCT_FLD_8(u8_t _hlen); + /* router alert option type */ + PACK_STRUCT_FLD_8(u8_t _ra_opt_type); + /* router alert option data len */ + PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen); + /* router alert option data */ + PACK_STRUCT_FIELD(u16_t _ra_opt_data); + /* PadN option type */ + PACK_STRUCT_FLD_8(u8_t _padn_opt_type); + /* PadN option data len */ + PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* Fragment header. */ +#define IP6_FRAG_HLEN 8 +#define IP6_FRAG_OFFSET_MASK 0xfff8 +#define IP6_FRAG_MORE_FLAG 0x0001 +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_frag_hdr { + /* next header */ + PACK_STRUCT_FLD_8(u8_t _nexth); + /* reserved */ + PACK_STRUCT_FLD_8(u8_t reserved); + /* fragment offset */ + PACK_STRUCT_FIELD(u16_t _fragment_offset); + /* fragmented packet identification */ + PACK_STRUCT_FIELD(u32_t _identification); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define IP6H_V(hdr) ((ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) +#define IP6H_TC(hdr) ((ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) +#define IP6H_FL(hdr) (ntohl((hdr)->_v_tc_fl) & 0x000fffff) +#define IP6H_PLEN(hdr) (ntohs((hdr)->_plen)) +#define IP6H_NEXTH(hdr) ((hdr)->_nexth) +#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) +#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) + +#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) +#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = htons(plen) +#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) +#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) + + +#define ip6_init() /* TODO should we init current addresses and header pointer? */ +struct netif *ip6_route(struct ip6_addr *src, struct ip6_addr *dest); +ip6_addr_t *ip6_select_source_address(struct netif *netif, ip6_addr_t * dest); +err_t ip6_input(struct pbuf *p, struct netif *inp); +err_t ip6_output(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, + u8_t hl, u8_t tc, u8_t nexth); +err_t ip6_output_if(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, + u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); +err_t ip6_output_if_src(struct pbuf *p, struct ip6_addr *src, struct ip6_addr *dest, + u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); +#if LWIP_NETIF_HWADDRHINT +err_t ip6_output_hinted(struct pbuf *p, ip6_addr_t *src, ip6_addr_t *dest, + u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); +#endif /* LWIP_NETIF_HWADDRHINT */ +#if LWIP_IPV6_MLD +err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); +#endif /* LWIP_IPV6_MLD */ + +#define ip6_netif_get_local_ipX(netif, dest) (((netif) != NULL) ? \ + ip6_2_ipX(ip6_select_source_address(netif, dest)) : NULL) + +#if IP6_DEBUG +void ip6_debug_print(struct pbuf *p); +#else +#define ip6_debug_print(p) +#endif /* IP6_DEBUG */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_HDR_IP6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_addr.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_addr.h new file mode 100644 index 0000000..ace219c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_addr.h @@ -0,0 +1,289 @@ +/** + * @file + * + * IPv6 addresses. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * Structs and macros for handling IPv6 addresses. + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef LWIP_HDR_IP6_ADDR_H +#define LWIP_HDR_IP6_ADDR_H + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is the aligned version of ip6_addr_t, + used as local variable, on the stack, etc. */ +struct ip6_addr { + u32_t addr[4]; +}; + +/* This is the packed version of ip6_addr_t, + used in network headers that are itself packed */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ip6_addr_packed { + PACK_STRUCT_FIELD(u32_t addr[4]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** ip6_addr_t uses a struct for convenience only, so that the same defines can + * operate both on ip6_addr_t as well as on ip6_addr_p_t. */ +typedef struct ip6_addr ip6_addr_t; +typedef struct ip6_addr_packed ip6_addr_p_t; + + +/** IP6_ADDR_ANY can be used as a fixed IPv6 address + * for the wildcard + */ +extern const ip6_addr_t ip6_addr_any; +#define IP6_ADDR_ANY ((ip6_addr_t *)&ip6_addr_any) + + +#if BYTE_ORDER == BIG_ENDIAN +/** Set an IPv6 partial address given by byte-parts. */ +#define IP6_ADDR(ip6addr, index, a,b,c,d) \ + (ip6addr)->addr[index] = ((u32_t)((a) & 0xff) << 24) | \ + ((u32_t)((b) & 0xff) << 16) | \ + ((u32_t)((c) & 0xff) << 8) | \ + (u32_t)((d) & 0xff) +#else +/** Set an IPv6 partial address given by byte-parts. +Little-endian version, stored in network order (no htonl). */ +#define IP6_ADDR(ip6addr, index, a,b,c,d) \ + (ip6addr)->addr[index] = ((u32_t)((d) & 0xff) << 24) | \ + ((u32_t)((c) & 0xff) << 16) | \ + ((u32_t)((b) & 0xff) << 8) | \ + (u32_t)((a) & 0xff) +#endif + +/** Access address in 16-bit block */ +#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)(htonl((ip6addr)->addr[0])) & 0xffff) +#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)(htonl((ip6addr)->addr[1])) & 0xffff) +#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)(htonl((ip6addr)->addr[2])) & 0xffff) +#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3]) >> 16) & 0xffff) +#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)(htonl((ip6addr)->addr[3])) & 0xffff) + +/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ +#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ + (dest).addr[1] = (src).addr[1]; \ + (dest).addr[2] = (src).addr[2]; \ + (dest).addr[3] = (src).addr[3];}while(0) +/** Safely copy one IPv6 address to another (src may be NULL) */ +#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ + (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ + (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ + (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) + +/** Set complete address to zero */ +#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = 0;}while(0) + +/** Set address to ipv6 'any' (no need for htonl()) */ +#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) +/** Set address to ipv6 loopback address */ +#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) +/** Safely copy one IPv6 address to another and change byte order + * from host- to network-order. */ +#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : htonl((src)->addr[0]); \ + (dest)->addr[1] = (src) == NULL ? 0 : htonl((src)->addr[1]); \ + (dest)->addr[2] = (src) == NULL ? 0 : htonl((src)->addr[2]); \ + (dest)->addr[3] = (src) == NULL ? 0 : htonl((src)->addr[3]);}while(0) + + +/** + * Determine if two IPv6 address are on the same network. + * + * @arg addr1 IPv6 address 1 + * @arg addr2 IPv6 address 2 + * @return !0 if the network identifiers of both address match + */ +#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1])) + +#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1]) && \ + ((addr1)->addr[2] == (addr2)->addr[2]) && \ + ((addr1)->addr[3] == (addr2)->addr[3])) + +#define ip6_get_subnet_id(ip6addr) (htonl((ip6addr)->addr[2]) & 0x0000ffffUL) + +#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || \ + (((ip6addr)->addr[0] == 0) && \ + ((ip6addr)->addr[1] == 0) && \ + ((ip6addr)->addr[2] == 0) && \ + ((ip6addr)->addr[3] == 0))) + +#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) + +#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) + +#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) + +#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) + +#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) + +#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) +#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) +#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) +#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) +#define ip6_addr_multicast_scope(ip6addr) ((htonl((ip6addr)->addr[0]) >> 16) & 0xf) +#define IP6_MULTICAST_SCOPE_RESERVED 0x0 +#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 +#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 +#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 +#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 +#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 +#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 +#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 +#define IP6_MULTICAST_SCOPE_GLOBAL 0xe +#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf +#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff010000UL)) +#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff020000UL)) +#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff040000UL)) +#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff050000UL)) +#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff080000UL)) +#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xff0e0000UL)) + +/* TODO define get/set for well-know multicast addresses, e.g. ff02::1 */ +#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) + +#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) +#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) + +#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0UL) && \ + ((ip6addr)->addr[2] == 0UL) && \ + ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) +#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) + +#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ + (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) + +#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ + (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id));}while(0) + +#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ + ((ip6addr)->addr[1] == 0) && \ + ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ + ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3]))) + +/* IPv6 address states. */ +#define IP6_ADDR_INVALID 0x00 +#define IP6_ADDR_TENTATIVE 0x08 +#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ +#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ +#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ +#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ +#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ +#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ +#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ +#define IP6_ADDR_VALID 0x10 +#define IP6_ADDR_PREFERRED 0x30 +#define IP6_ADDR_DEPRECATED 0x50 + +#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) +#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) +#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ +#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) +#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) + +#define ip6_addr_debug_print(debug, ipaddr) \ + LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \ + ipaddr != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0, \ + ipaddr != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) + +#define IP6ADDR_STRLEN_MAX 46 + +int ip6addr_aton(const char *cp, ip6_addr_t *addr); +/** returns ptr to static buffer; not reentrant! */ +char *ip6addr_ntoa(const ip6_addr_t *addr); +char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); + + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_HDR_IP6_ADDR_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_frag.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_frag.h new file mode 100644 index 0000000..9987914 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip6_frag.h @@ -0,0 +1,102 @@ +/** + * @file + * + * IPv6 fragmentation and reassembly. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ +#ifndef LWIP_HDR_IP6_FRAG_H +#define LWIP_HDR_IP6_FRAG_H + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ + +/* The IPv6 reassembly timer interval in milliseconds. */ +#define IP6_REASS_TMR_INTERVAL 1000 + +/* IPv6 reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip6_reassdata { + struct ip6_reassdata *next; + struct pbuf *p; + struct ip6_hdr * iphdr; + u32_t identification; + u16_t datagram_len; + u8_t nexth; + u8_t timer; +}; + +#define ip6_reass_init() /* Compatibility define */ +void ip6_reass_tmr(void); +struct pbuf * ip6_reass(struct pbuf *p); + +#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ + +#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ + +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED +#define LWIP_PBUF_CUSTOM_REF_DEFINED +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ + +err_t ip6_frag(struct pbuf *p, struct netif *netif, ip6_addr_t *dest); + +#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP6_FRAG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_addr.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_addr.h new file mode 100644 index 0000000..1ded93f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_addr.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_IP_ADDR_H__ +#define LWIP_HDR_IP_ADDR_H__ + +#include "lwip/opt.h" +#include "lwip/def.h" + +#include "lwip/ip4_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_IPV6 +/* A union struct for both IP version's addresses. */ +typedef union { + ip_addr_t ip4; + ip6_addr_t ip6; +} ipX_addr_t; + +/** These functions only exist for type-safe conversion from ip_addr_t to + ip6_addr_t and back */ +#ifdef LWIP_ALLOW_STATIC_FN_IN_HEADER +static ip6_addr_t* ip_2_ip6(ip_addr_t *ipaddr) +{ return (ip6_addr_t*)ipaddr;} +static ip_addr_t* ip6_2_ip(ip6_addr_t *ip6addr) +{ return (ip_addr_t*)ip6addr; } +static ipX_addr_t* ip_2_ipX(ip_addr_t *ipaddr) +{ return (ipX_addr_t*)ipaddr; } +static ipX_addr_t* ip6_2_ipX(ip6_addr_t *ip6addr) +{ return (ipX_addr_t*)ip6addr; } +#else /* LWIP_ALLOW_STATIC_FN_IN_HEADER */ +#define ip_2_ip6(ipaddr) ((ip6_addr_t*)(ipaddr)) +#define ip6_2_ip(ip6addr) ((ip_addr_t*)(ip6addr)) +#define ip_2_ipX(ipaddr) ((ipX_addr_t*)ipaddr) +#define ip6_2_ipX(ip6addr) ((ipX_addr_t*)ip6addr) +#endif /* LWIP_ALLOW_STATIC_FN_IN_HEADER*/ +#define ipX_2_ip6(ip6addr) (&((ip6addr)->ip6)) +#define ipX_2_ip(ipaddr) (&((ipaddr)->ip4)) + +#define ipX_addr_copy(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_copy((dest).ip6, (src).ip6); }else{ \ + ip_addr_copy((dest).ip4, (src).ip4); }}while(0) +#define ipX_addr_set(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ipX_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), ipX_2_ip(src)); }}while(0) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set(ipX_2_ip6(dest), ip_2_ip6(src)); }else{ \ + ip_addr_set(ipX_2_ip(dest), src); }}while(0) +#define ipX_addr_set_zero(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_zero(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_zero(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_any(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_any(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ + ip6_addr_set_loopback(ipX_2_ip6(ipaddr)); }else{ \ + ip_addr_set_loopback(ipX_2_ip(ipaddr)); }}while(0) +#define ipX_addr_set_hton(is_ipv6, dest, src) do{if(is_ipv6){ \ + ip6_addr_set_hton(ipX_2_ip6(ipaddr), (src)) ;}else{ \ + ip_addr_set_hton(ipX_2_ip(ipaddr), (src));}}while(0) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ((is_ipv6) ? \ + ip6_addr_cmp(ipX_2_ip6(addr1), ipX_2_ip6(addr2)) : \ + ip_addr_cmp(ipX_2_ip(addr1), ipX_2_ip(addr2))) +#define ipX_addr_isany(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_isany(ipX_2_ip6(ipaddr)) : \ + ip_addr_isany(ipX_2_ip(ipaddr))) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ((is_ipv6) ? \ + ip6_addr_ismulticast(ipX_2_ip6(ipaddr)) : \ + ip_addr_ismulticast(ipX_2_ip(ipaddr))) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) do { if(is_ipv6) { \ + ip6_addr_debug_print(debug, ipX_2_ip6(ipaddr)); } else { \ + ip_addr_debug_print(debug, ipX_2_ip(ipaddr)); }}while(0) + +#else /* LWIP_IPV6 */ + +typedef ip_addr_t ipX_addr_t; +#define ipX_2_ip(ipaddr) (ipaddr) +#define ip_2_ipX(ipaddr) (ipaddr) + +#define ipX_addr_copy(is_ipv6, dest, src) ip_addr_copy(dest, src) +#define ipX_addr_set(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_ipaddr(is_ipv6, dest, src) ip_addr_set(dest, src) +#define ipX_addr_set_zero(is_ipv6, ipaddr) ip_addr_set_zero(ipaddr) +#define ipX_addr_set_any(is_ipv6, ipaddr) ip_addr_set_any(ipaddr) +#define ipX_addr_set_loopback(is_ipv6, ipaddr) ip_addr_set_loopback(ipaddr) +#define ipX_addr_set_hton(is_ipv6, dest, src) ip_addr_set_hton(dest, src) +#define ipX_addr_cmp(is_ipv6, addr1, addr2) ip_addr_cmp(addr1, addr2) +#define ipX_addr_isany(is_ipv6, ipaddr) ip_addr_isany(ipaddr) +#define ipX_addr_ismulticast(is_ipv6, ipaddr) ip_addr_ismulticast(ipaddr) +#define ipX_addr_debug_print(is_ipv6, debug, ipaddr) ip_addr_debug_print(debug, ipaddr) + +#endif /* LWIP_IPV6 */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP_ADDR_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_frag.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_frag.h new file mode 100644 index 0000000..143b1e5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/ip_frag.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Jani Monoses + * + */ + +#ifndef LWIP_HDR_IP_FRAG_H +#define LWIP_HDR_IP_FRAG_H + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/lwip_ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if IP_REASSEMBLY +/* The IP reassembly timer interval in milliseconds. */ +#define IP_TMR_INTERVAL 1000 + +/* IP reassembly helper struct. + * This is exported because memp needs to know the size. + */ +struct ip_reassdata { + struct ip_reassdata *next; + struct pbuf *p; + struct ip_hdr iphdr; + u16_t datagram_len; + u8_t flags; + u8_t timer; +}; + +void ip_reass_init(void); +void ip_reass_tmr(void); +struct pbuf * ip_reass(struct pbuf *p); +#endif /* IP_REASSEMBLY */ + +#if IP_FRAG +#if !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF +/** A custom pbuf that holds a reference to another pbuf, which is freed + * when this custom pbuf is freed. This is used to create a custom PBUF_REF + * that points into the original pbuf. */ +#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED +#define LWIP_PBUF_CUSTOM_REF_DEFINED +struct pbuf_custom_ref { + /** 'base class' */ + struct pbuf_custom pc; + /** pointer to the original pbuf that is referenced */ + struct pbuf *original; +}; +#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ +#endif /* !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +err_t ip_frag(struct pbuf *p, struct netif *netif, ip_addr_t *dest); +#endif /* IP_FRAG */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP_FRAG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_ip.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_ip.h new file mode 100644 index 0000000..522e98d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_ip.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_IP_H__ +#define LWIP_HDR_IP_H__ + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/netif.h" +#include "lwip/ip4.h" +#include "lwip/ip6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This is passed as the destination address to ip_output_if (not + to ip_output), meaning that an IP header already is constructed + in the pbuf. This is used when TCP retransmits. */ +#ifdef IP_HDRINCL +#undef IP_HDRINCL +#endif /* IP_HDRINCL */ +#define IP_HDRINCL NULL + +/** pbufs passed to IP must have a ref-count of 1 as their payload pointer + gets altered as the packet is passed down the stack */ +#ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX +#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1) +#endif + +#if LWIP_NETIF_HWADDRHINT +#define IP_PCB_ADDRHINT ;u8_t addr_hint +#else +#define IP_PCB_ADDRHINT +#endif /* LWIP_NETIF_HWADDRHINT */ + +#if LWIP_IPV6 +#define IP_PCB_ISIPV6_MEMBER u8_t isipv6; +#define IP_PCB_IPVER_EQ(pcb1, pcb2) ((pcb1)->isipv6 == (pcb2)->isipv6) +#define IP_PCB_IPVER_INPUT_MATCH(pcb) (ip_current_is_v6() ? \ + ((pcb)->isipv6 != 0) : \ + ((pcb)->isipv6 == 0)) +#define PCB_ISIPV6(pcb) ((pcb)->isipv6) +#else +#define IP_PCB_ISIPV6_MEMBER +#define IP_PCB_IPVER_EQ(pcb1, pcb2) 1 +#define IP_PCB_IPVER_INPUT_MATCH(pcb) 1 +#define PCB_ISIPV6(pcb) 0 +#endif /* LWIP_IPV6 */ + +/* This is the common part of all PCB types. It needs to be at the + beginning of a PCB type definition. It is located here so that + changes to this common part are made in one location instead of + having to change all PCB structs. */ +#define IP_PCB \ + IP_PCB_ISIPV6_MEMBER \ + /* ip addresses in network byte order */ \ + ipX_addr_t local_ip; \ + ipX_addr_t remote_ip; \ + /* Socket options */ \ + u8_t so_options; \ + /* Type Of Service */ \ + u8_t tos; \ + /* Time To Live */ \ + u8_t ttl \ + /* link layer address resolution hint */ \ + IP_PCB_ADDRHINT + +struct ip_pcb { +/* Common members of all PCB types */ + IP_PCB; +}; + +/* + * Option flags per-socket. These are the same like SO_XXX in sockets.h + */ +#define SOF_REUSEADDR 0x04U /* allow local address reuse */ +#define SOF_KEEPALIVE 0x08U /* keep connections alive */ +#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ + +/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ +#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) + +/* Global variables of this module, kept in a struct for efficient access using base+index. */ +struct ip_globals +{ + /** The interface that provided the packet for the current callback invocation. */ + struct netif *current_netif; + /** Header of the input packet currently being processed. */ + const struct ip_hdr *current_ip4_header; +#if LWIP_IPV6 + /** Header of the input IPv6 packet currently being processed. */ + const struct ip6_hdr *current_ip6_header; +#endif /* LWIP_IPV6 */ + /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ + u16_t current_ip_header_tot_len; + /** Source IP address of current_header */ + ipX_addr_t current_iphdr_src; + /** Destination IP address of current_header */ + ipX_addr_t current_iphdr_dest; +}; +extern struct ip_globals ip_data; + + +/** Get the interface that received the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_netif() (ip_data.current_netif) +/** Get the IP header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip_current_header() (ip_data.current_ip4_header) +/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ +#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) +/** Source IP address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +#if LWIP_IPV6 +/** Get the IPv6 header of the current packet. + * This function must only be called from a receive callback (udp_recv, + * raw_recv, tcp_accept). It will return NULL otherwise. */ +#define ip6_current_header() (ip_data.current_ip6_header) +/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ +#define ip_current_is_v6() (ip6_current_header() != NULL) +/** Source IPv6 address of current_header */ +#define ip6_current_src_addr() (ipX_2_ip6(&ip_data.current_iphdr_src)) +/** Destination IPv6 address of current_header */ +#define ip6_current_dest_addr() (ipX_2_ip6(&ip_data.current_iphdr_dest)) +/** Get the transport layer protocol */ +#define ip_current_header_proto() (ip_current_is_v6() ? \ + IP6H_NEXTH(ip6_current_header()) :\ + IPH_PROTO(ip_current_header())) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((ip_current_is_v6() ? \ + (u8_t*)ip6_current_header() : (u8_t*)ip_current_header()) + ip_current_header_tot_len())) + +/** Set an IP_PCB to IPv6 (IPv4 is the default) */ +#define ip_set_v6(pcb, val) do{if(pcb != NULL) { pcb->isipv6 = val; }}while(0) + +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (ipX_2_ip(&ip_data.current_iphdr_src)) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (ipX_2_ip(&ip_data.current_iphdr_dest)) + +#else /* LWIP_IPV6 */ + +/** Always returns FALSE when only supporting IPv4 */ +#define ip_current_is_v6() 0 +/** Get the transport layer protocol */ +#define ip_current_header_proto() IPH_PROTO(ip_current_header()) +/** Get the transport layer header */ +#define ipX_next_header_ptr() ((void*)((u8_t*)ip_current_header() + ip_current_header_tot_len())) +/** Source IP4 address of current_header */ +#define ip_current_src_addr() (&ip_data.current_iphdr_src) +/** Destination IP4 address of current_header */ +#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) + +#endif /* LWIP_IPV6 */ + +/** Union source address of current_header */ +#define ipX_current_src_addr() (&ip_data.current_iphdr_src) +/** Union destination address of current_header */ +#define ipX_current_dest_addr() (&ip_data.current_iphdr_dest) + +/** Gets an IP pcb option (SOF_* flags) */ +#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) +/** Sets an IP pcb option (SOF_* flags) */ +#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) +/** Resets an IP pcb option (SOF_* flags) */ +#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) + +#if LWIP_IPV6 +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ((isipv6) ? \ + ip6_output(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto) : \ + ip_output(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto)) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ((isipv6) ? \ + ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ + ip_output_if(p, (src), (dest), ttl, tos, proto, netif)) +#define ipX_output_if_src(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ((isipv6) ? \ + ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ + ip_output_if_src(p, (src), (dest), ttl, tos, proto, netif)) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ((isipv6) ? \ + ip6_output_hinted(p, ipX_2_ip6(src), ipX_2_ip6(dest), ttl, tos, proto, addr_hint) : \ + ip_output_hinted(p, ipX_2_ip(src), ipX_2_ip(dest), ttl, tos, proto, addr_hint)) +#define ipX_route(isipv6, src, dest) \ + ((isipv6) ? \ + ip6_route(ipX_2_ip6(src), ipX_2_ip6(dest)) : \ + ip_route(ipX_2_ip(dest))) +#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ + ((isipv6) ? \ + ip6_netif_get_local_ipX(netif, ipX_2_ip6(dest)) : \ + ip_netif_get_local_ipX(netif)) +#define ipX_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip_debug_print(p)) +#else /* LWIP_IPV6 */ +#define ipX_output(isipv6, p, src, dest, ttl, tos, proto) \ + ip_output(p, src, dest, ttl, tos, proto) +#define ipX_output_if(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ip_output_if(p, src, dest, ttl, tos, proto, netif) +#define ipX_output_if_src(isipv6, p, src, dest, ttl, tos, proto, netif) \ + ip_output_if_src(p, src, dest, ttl, tos, proto, netif) +#define ipX_output_hinted(isipv6, p, src, dest, ttl, tos, proto, addr_hint) \ + ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) +#define ipX_route(isipv6, src, dest) \ + ip_route(ipX_2_ip(dest)) +#define ipX_netif_get_local_ipX(isipv6, netif, dest) \ + ip_netif_get_local_ipX(netif) +#define ipX_debug_print(is_ipv6, p) ip_debug_print(p) +#endif /* LWIP_IPV6 */ + +#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \ + (netif) = ipX_route(isipv6, src, dest); \ + (ipXaddr) = ipX_netif_get_local_ipX(isipv6, netif, dest); \ +}while(0) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_IP_H__ */ + + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_timers.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_timers.h new file mode 100644 index 0000000..e125777 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/lwip_timers.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_TIMERS_H +#define LWIP_HDR_TIMERS_H + +#include "lwip/opt.h" + +/* Timers are not supported when NO_SYS==1 and NO_SYS_NO_TIMERS==1 */ +#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) + +#if LWIP_TIMERS + +#include "lwip/err.h" +#if !NO_SYS +#include "lwip/sys.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LWIP_DEBUG_TIMERNAMES +#ifdef LWIP_DEBUG +#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG +#else /* LWIP_DEBUG */ +#define LWIP_DEBUG_TIMERNAMES 0 +#endif /* LWIP_DEBUG*/ +#endif + +/** Function prototype for a timeout callback function. Register such a function + * using sys_timeout(). + * + * @param arg Additional argument to pass to the function - set up by sys_timeout() + */ +typedef void (* sys_timeout_handler)(void *arg); + +struct sys_timeo { + struct sys_timeo *next; + u32_t time; + sys_timeout_handler h; + void *arg; +#if LWIP_DEBUG_TIMERNAMES + const char* handler_name; +#endif /* LWIP_DEBUG_TIMERNAMES */ +}; + +void sys_timeouts_init(void); + +//Realtek add +struct sys_timeouts { + struct sys_timeo *next; +}; + +struct sys_timeouts *sys_arch_timeouts(void); +//Realtek add end + +#if LWIP_DEBUG_TIMERNAMES +void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); +#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) +#else /* LWIP_DEBUG_TIMERNAMES */ +void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); +#endif /* LWIP_DEBUG_TIMERNAMES */ + +void sys_untimeout(sys_timeout_handler handler, void *arg); +#if NO_SYS +void sys_check_timeouts(void); +void sys_restart_timeouts(void); +#else /* NO_SYS */ +void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); +#endif /* NO_SYS */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TIMERS */ +#endif /* LWIP_HDR_TIMERS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mem.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mem.h new file mode 100644 index 0000000..7fea25a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mem.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_MEM_H +#define LWIP_HDR_MEM_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if MEM_LIBC_MALLOC + +#include /* for size_t */ + +typedef size_t mem_size_t; +#define MEM_SIZE_F SZT_F + +/* aliases for C library malloc() */ +#define mem_init() +/* in case C library malloc() needs extra protection, + * allow these defines to be overridden. + */ +#ifndef mem_free +#define mem_free free +#endif +#ifndef mem_malloc +#define mem_malloc malloc +#endif +#ifndef mem_calloc +#define mem_calloc calloc +#endif +/* Since there is no C library allocation function to shrink memory without + moving it, define this to nothing. */ +#ifndef mem_trim +#define mem_trim(mem, size) (mem) +#endif +#else /* MEM_LIBC_MALLOC */ + +/* MEM_SIZE would have to be aligned, but using 64000 here instead of + * 65535 leaves some room for alignment... + */ +#if MEM_SIZE > 64000L +typedef u32_t mem_size_t; +#define MEM_SIZE_F U32_F +#else +typedef u16_t mem_size_t; +#define MEM_SIZE_F U16_F +#endif /* MEM_SIZE > 64000 */ + +#if MEM_USE_POOLS +/** mem_init is not used when using pools instead of a heap */ +#define mem_init() +/** mem_trim is not used when using pools instead of a heap: + we can't free part of a pool element and don't want to copy the rest */ +#define mem_trim(mem, size) (mem) +#else /* MEM_USE_POOLS */ +/* lwIP alternative malloc */ +void mem_init(void); +void *mem_trim(void *mem, mem_size_t size); +#endif /* MEM_USE_POOLS */ +void *mem_malloc(mem_size_t size); +void *mem_calloc(mem_size_t count, mem_size_t size); +void mem_free(void *mem); +#endif /* MEM_LIBC_MALLOC */ + +/** Calculate memory size for an aligned buffer - returns the next highest + * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and + * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). + */ +#ifndef LWIP_MEM_ALIGN_SIZE +#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U)) +#endif + +/** Calculate safe memory size for an aligned buffer when using an unaligned + * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the + * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) + */ +#ifndef LWIP_MEM_ALIGN_BUFFER +#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U)) +#endif + +/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT + * so that ADDR % MEM_ALIGNMENT == 0 + */ +#ifndef LWIP_MEM_ALIGN +#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_MEM_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp.h new file mode 100644 index 0000000..8bcc43a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef LWIP_HDR_MEMP_H +#define LWIP_HDR_MEMP_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ +typedef enum { +#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, +#include "lwip/memp_std.h" + MEMP_MAX +} memp_t; + +#if MEM_USE_POOLS +/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ +typedef enum { + /* Get the first (via: + MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ + MEMP_POOL_HELPER_FIRST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START 1 +#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 +#define LWIP_MALLOC_MEMPOOL_END +#include "lwip/memp_std.h" + ) , + /* Get the last (via: + MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ + MEMP_POOL_HELPER_LAST = ((u8_t) +#define LWIP_MEMPOOL(name,num,size,desc) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * +#define LWIP_MALLOC_MEMPOOL_END 1 +#include "lwip/memp_std.h" + ) +} memp_pool_helper_t; + +/* The actual start and stop values are here (cast them over) + We use this helper type and these defines so we can avoid using const memp_t values */ +#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) +#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) +#endif /* MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC || MEM_USE_POOLS +extern const u16_t memp_sizes[MEMP_MAX]; +#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ + +#if MEMP_MEM_MALLOC + +#include "mem.h" + +#define memp_init() +#define memp_malloc(type) mem_malloc(memp_sizes[type]) +#define memp_free(type, mem) mem_free(mem) + +#else /* MEMP_MEM_MALLOC */ + +#if MEM_USE_POOLS +/** This structure is used to save the pool one element came from. */ +struct memp_malloc_helper +{ + memp_t poolnr; +#if MEMP_OVERFLOW_CHECK + u16_t size; +#endif /* MEMP_OVERFLOW_CHECK */ +}; +#endif /* MEM_USE_POOLS */ + +void memp_init(void); + +#if MEMP_OVERFLOW_CHECK +void *memp_malloc_fn(memp_t type, const char* file, const int line); +#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) +#else +void *memp_malloc(memp_t type); +#endif +void memp_free(memp_t type, void *mem); + +#endif /* MEMP_MEM_MALLOC */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_MEMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp_std.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp_std.h new file mode 100644 index 0000000..ce303da --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/memp_std.h @@ -0,0 +1,154 @@ +/* + * SETUP: Make sure we define everything we will need. + * + * We have create three types of pools: + * 1) MEMPOOL - standard pools + * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c + * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct + * + * If the include'r doesn't require any special treatment of each of the types + * above, then will declare #2 & #3 to be just standard mempools. + */ +#ifndef LWIP_MALLOC_MEMPOOL +/* This treats "malloc pools" just like any other pool. + The pools are a little bigger to provide 'size' as the amount of user data. */ +#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))), "MALLOC_"#size) +#define LWIP_MALLOC_MEMPOOL_START +#define LWIP_MALLOC_MEMPOOL_END +#endif /* LWIP_MALLOC_MEMPOOL */ + +#ifndef LWIP_PBUF_MEMPOOL +/* This treats "pbuf pools" just like any other pool. + * Allocates buffers for a pbuf struct AND a payload size */ +#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) +#endif /* LWIP_PBUF_MEMPOOL */ + + +/* + * A list of internal pools used by LWIP. + * + * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + */ +#if LWIP_RAW +LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") +#endif /* LWIP_RAW */ + +#if LWIP_UDP +LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") +#endif /* LWIP_UDP */ + +#if LWIP_TCP +LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") +LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") +LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") +#endif /* LWIP_TCP */ + +#if IP_REASSEMBLY +LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") +#endif /* IP_REASSEMBLY */ +#if (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) || LWIP_IPV6_FRAG +LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") +#endif /* IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF */ + +#if LWIP_NETCONN || LWIP_SOCKET +LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") +LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#if NO_SYS==0 +LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") +#if LWIP_MPU_COMPATIBLE +LWIP_MEMPOOL(API_MSG, MEMP_NUM_API_MSG, sizeof(struct api_msg), "API_MSG") +#if LWIP_DNS +LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg), "DNS_API_MSG") +#endif +#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING +LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA") +#endif +#if LWIP_NETIF_API +LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG") +#endif +#endif /* LWIP_MPU_COMPATIBLE */ +#if !LWIP_TCPIP_CORE_LOCKING_INPUT +LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") +#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ +#endif /* NO_SYS==0 */ + +#if LWIP_ARP && ARP_QUEUEING +LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") +#endif /* LWIP_ARP && ARP_QUEUEING */ + +#if LWIP_IGMP +LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") +#endif /* LWIP_IGMP */ + +#if (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) /* LWIP_TIMERS */ +LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") +#endif /* LWIP_TIMERS */ + +#if LWIP_SNMP +LWIP_MEMPOOL(SNMP_ROOTNODE, MEMP_NUM_SNMP_ROOTNODE, sizeof(struct mib_list_rootnode), "SNMP_ROOTNODE") +LWIP_MEMPOOL(SNMP_NODE, MEMP_NUM_SNMP_NODE, sizeof(struct mib_list_node), "SNMP_NODE") +LWIP_MEMPOOL(SNMP_VARBIND, MEMP_NUM_SNMP_VARBIND, sizeof(struct snmp_varbind), "SNMP_VARBIND") +LWIP_MEMPOOL(SNMP_VALUE, MEMP_NUM_SNMP_VALUE, SNMP_MAX_VALUE_SIZE, "SNMP_VALUE") +#endif /* LWIP_SNMP */ +#if LWIP_DNS && LWIP_SOCKET +LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") +#endif /* LWIP_DNS && LWIP_SOCKET */ +#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC +LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") +#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +#if PPP_SUPPORT +LWIP_MEMPOOL(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") +#if PPPOE_SUPPORT +LWIP_MEMPOOL(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +LWIP_MEMPOOL(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB") +#endif /* PPPOL2TP_SUPPORT */ +#endif /* PPP_SUPPORT */ + +#if LWIP_IPV6 && LWIP_ND6_QUEUEING +LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") +#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ + +#if LWIP_IPV6 && LWIP_IPV6_REASS +LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") +#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ + +#if LWIP_IPV6 && LWIP_IPV6_MLD +LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + + +/* + * A list of pools of pbuf's used by LWIP. + * + * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) + * creates a pool name MEMP_pool_name. description is used in stats.c + * This allocates enough space for the pbuf struct and a payload. + * (Example: pbuf_payload_size=0 allocates only size for the struct) + */ +LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") +LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") + + +/* + * Allow for user-defined pools; this must be explicitly set in lwipopts.h + * since the default is to NOT look for lwippools.h + */ +#if MEMP_USE_CUSTOM_POOLS +#include "lwippools.h" +#endif /* MEMP_USE_CUSTOM_POOLS */ + +/* + * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later + * (#undef is ignored for something that is not defined) + */ +#undef LWIP_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL +#undef LWIP_MALLOC_MEMPOOL_START +#undef LWIP_MALLOC_MEMPOOL_END +#undef LWIP_PBUF_MEMPOOL diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mld6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mld6.h new file mode 100644 index 0000000..f629c3d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/mld6.h @@ -0,0 +1,118 @@ +/** + * @file + * + * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. + * No support for MLDv2. + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef LWIP_HDR_MLD6_H +#define LWIP_HDR_MLD6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6_MLD && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct mld_group { + /** next link */ + struct mld_group *next; + /** interface on which the group is active */ + struct netif *netif; + /** multicast address */ + ip6_addr_t group_address; + /** signifies we were the last person to report */ + u8_t last_reporter_flag; + /** current state of the group */ + u8_t group_state; + /** timer for reporting */ + u16_t timer; + /** counter of simultaneous uses */ + u8_t use; +}; + +/** Multicast listener report/query/done message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mld_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t max_resp_delay); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ + +/* MAC Filter Actions, these are passed to a netif's + * mld_mac_filter callback function. */ +#define MLD6_DEL_MAC_FILTER 0 +#define MLD6_ADD_MAC_FILTER 1 + + +#define mld6_init() /* TODO should we init tables? */ +err_t mld6_stop(struct netif *netif); +void mld6_report_groups(struct netif *netif); +void mld6_tmr(void); +struct mld_group *mld6_lookfor_group(struct netif *ifp, ip6_addr_t *addr); +void mld6_input(struct pbuf *p, struct netif *inp); +err_t mld6_joingroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); +err_t mld6_leavegroup(ip6_addr_t *srcaddr, ip6_addr_t *groupaddr); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6_MLD && LWIP_IPV6 */ + +#endif /* LWIP_HDR_MLD6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/nd6.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/nd6.h new file mode 100644 index 0000000..2a8401f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/nd6.h @@ -0,0 +1,362 @@ +/** + * @file + * + * Neighbor discovery and stateless address autoconfiguration for IPv6. + * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 + * (Address autoconfiguration). + */ + +/* + * Copyright (c) 2010 Inico Technologies Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Ivan Delamer + * + * + * Please coordinate changes and requests with Ivan Delamer + * + */ + +#ifndef LWIP_HDR_ND6_H +#define LWIP_HDR_ND6_H + +#include "lwip/opt.h" + +#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" +#include "lwip/netif.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct for tables. */ +struct nd6_neighbor_cache_entry { + ip6_addr_t next_hop_address; + struct netif * netif; + u8_t lladdr[NETIF_MAX_HWADDR_LEN]; + /*u32_t pmtu;*/ +#if LWIP_ND6_QUEUEING + /** Pointer to queue of pending outgoing packets on this entry. */ + struct nd6_q_entry *q; +#else /* LWIP_ND6_QUEUEING */ + /** Pointer to a single pending outgoing packet on this entry. */ + struct pbuf *q; +#endif /* LWIP_ND6_QUEUEING */ + u8_t state; + u8_t isrouter; + union { + u32_t reachable_time; + u32_t delay_time; + u32_t probes_sent; + u32_t stale_time; + } counter; +}; + +struct nd6_destination_cache_entry { + ip6_addr_t destination_addr; + ip6_addr_t next_hop_addr; + u32_t pmtu; + u32_t age; +}; + +struct nd6_prefix_list_entry { + ip6_addr_t prefix; + struct netif * netif; + u32_t invalidation_timer; +#if LWIP_IPV6_AUTOCONFIG + u8_t flags; +#define ND6_PREFIX_AUTOCONFIG_AUTONOMOUS 0x01 +#define ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED 0x02 +#define ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE 0x04 +#endif /* LWIP_IPV6_AUTOCONFIG */ +}; + +struct nd6_router_list_entry { + struct nd6_neighbor_cache_entry * neighbor_entry; + u32_t invalidation_timer; + u8_t flags; +}; + + +enum nd6_neighbor_cache_entry_state { + ND6_NO_ENTRY = 0, + ND6_INCOMPLETE, + ND6_REACHABLE, + ND6_STALE, + ND6_DELAY, + ND6_PROBE +}; + +#if LWIP_ND6_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct nd6_q_entry { + struct nd6_q_entry *next; + struct pbuf *p; +}; +#endif /* LWIP_ND6_QUEUEING */ + +/** Neighbor solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ns_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Neighbor advertisement message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct na_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FLD_8(u8_t reserved[3]); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#define ND6_FLAG_ROUTER (0x80) +#define ND6_FLAG_SOLICITED (0x40) +#define ND6_FLAG_OVERRIDE (0x20) + +/** Router solicitation message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct rs_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Router advertisement message header. */ +#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) +#define ND6_RA_FLAG_OTHER_STATEFUL_CONFIG (0x40) +#define ND6_RA_FLAG_HOME_AGENT (0x20) +#define ND6_RA_PREFERENCE_MASK (0x18) +#define ND6_RA_PREFERENCE_HIGH (0x08) +#define ND6_RA_PREFERENCE_MEDIUM (0x00) +#define ND6_RA_PREFERENCE_LOW (0x18) +#define ND6_RA_PREFERENCE_DISABLED (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct ra_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FLD_8(u8_t current_hop_limit); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FIELD(u16_t router_lifetime); + PACK_STRUCT_FIELD(u32_t reachable_time); + PACK_STRUCT_FIELD(u32_t retrans_timer); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirect message header. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirect_header { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u32_t reserved); + PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); + PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address); + /* Options follow. */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Link-layer address option. */ +#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) +#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct lladdr_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Prefix information option. */ +#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) +#define ND6_PREFIX_FLAG_ON_LINK (0x80) +#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) +#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) +#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct prefix_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t prefix_length); + PACK_STRUCT_FLD_8(u8_t flags); + PACK_STRUCT_FIELD(u32_t valid_lifetime); + PACK_STRUCT_FIELD(u32_t preferred_lifetime); + PACK_STRUCT_FLD_8(u8_t reserved2[3]); + PACK_STRUCT_FLD_8(u8_t site_prefix_length); + PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Redirected header option. */ +#define ND6_OPTION_TYPE_REDIR_HDR (0x04) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct redirected_header_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t reserved[6]); + /* Portion of redirected packet follows. */ + /* PACK_STRUCT_FLD_8(u8_t redirected[8]); */ +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** MTU option. */ +#define ND6_OPTION_TYPE_MTU (0x05) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct mtu_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FIELD(u16_t reserved); + PACK_STRUCT_FIELD(u32_t mtu); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** Route information option. */ +#define ND6_OPTION_TYPE_ROUTE_INFO (24) +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct route_option { + PACK_STRUCT_FLD_8(u8_t type); + PACK_STRUCT_FLD_8(u8_t length); + PACK_STRUCT_FLD_8(u8_t prefix_length); + PACK_STRUCT_FLD_8(u8_t preference); + PACK_STRUCT_FIELD(u32_t route_lifetime); + PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** 1 second period */ +#define ND6_TMR_INTERVAL 1000 + +/* Router tables. */ +/* TODO make these static? and entries accessible through API? */ +extern struct nd6_neighbor_cache_entry neighbor_cache[]; +extern struct nd6_destination_cache_entry destination_cache[]; +extern struct nd6_prefix_list_entry prefix_list[]; +extern struct nd6_router_list_entry default_router_list[]; + +/* Default values, can be updated by a RA message. */ +extern u32_t reachable_time; +extern u32_t retrans_timer; + +#define nd6_init() /* TODO should we init tables? */ +void nd6_tmr(void); +void nd6_input(struct pbuf *p, struct netif *inp); +s8_t nd6_get_next_hop_entry(ip6_addr_t * ip6addr, struct netif * netif); +s8_t nd6_select_router(ip6_addr_t * ip6addr, struct netif * netif); +u16_t nd6_get_destination_mtu(ip6_addr_t * ip6addr, struct netif * netif); +err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf * p); +#if LWIP_ND6_TCP_REACHABILITY_HINTS +void nd6_reachability_hint(ip6_addr_t * ip6addr); +#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_HDR_ND6_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netbuf.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netbuf.h new file mode 100644 index 0000000..54ef1e6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netbuf.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_NETBUF_H +#define LWIP_HDR_NETBUF_H + +#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +/* don't export the netbuf functions when socket API is enabled but netconn API is disabled */ +#if LWIP_NETCONN +#define LWIP_NETCONN_SCOPE +#else /* LWIP_NETCONN */ +#define LWIP_NETCONN_SCOPE static +#endif /* LWIP_NETCONN */ + +#include "lwip/opt.h" +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** This netbuf has dest-addr/port set */ +#define NETBUF_FLAG_DESTADDR 0x01 +/** This netbuf includes a checksum */ +#define NETBUF_FLAG_CHKSUM 0x02 + +struct netbuf { + struct pbuf *p, *ptr; + ipX_addr_t addr; + u16_t port; +#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY +#if LWIP_CHECKSUM_ON_COPY + u8_t flags; +#endif /* LWIP_CHECKSUM_ON_COPY */ + u16_t toport_chksum; +#if LWIP_NETBUF_RECVINFO + ipX_addr_t toaddr; +#endif /* LWIP_NETBUF_RECVINFO */ +#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ +}; + +/* Network buffer functions: */ +LWIP_NETCONN_SCOPE struct netbuf * netbuf_new (void); +LWIP_NETCONN_SCOPE void netbuf_delete (struct netbuf *buf); +LWIP_NETCONN_SCOPE void * netbuf_alloc (struct netbuf *buf, u16_t size); +LWIP_NETCONN_SCOPE void netbuf_free (struct netbuf *buf); +LWIP_NETCONN_SCOPE err_t netbuf_ref (struct netbuf *buf, + const void *dataptr, u16_t size); +LWIP_NETCONN_SCOPE void netbuf_chain (struct netbuf *head, + struct netbuf *tail); + +LWIP_NETCONN_SCOPE err_t netbuf_data (struct netbuf *buf, + void **dataptr, u16_t *len); +LWIP_NETCONN_SCOPE s8_t netbuf_next (struct netbuf *buf); +LWIP_NETCONN_SCOPE void netbuf_first (struct netbuf *buf); + + +#define netbuf_copy_partial(buf, dataptr, len, offset) \ + pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) +#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) +#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) +#define netbuf_len(buf) ((buf)->p->tot_len) +#define netbuf_fromaddr(buf) (ipX_2_ip(&((buf)->addr))) +#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(ipX_2_ip(&((buf)->addr)), fromaddr) +#define netbuf_fromport(buf) ((buf)->port) +#if LWIP_NETBUF_RECVINFO +#define netbuf_destaddr(buf) (ipX_2_ip(&((buf)->toaddr))) +#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(ipX_2_ip(&((buf)->toaddr)), destaddr) +#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) +#endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_CHECKSUM_ON_COPY +#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ + (buf)->toport_chksum = chksum; } while(0) +#endif /* LWIP_CHECKSUM_ON_COPY */ + +#if LWIP_IPV6 +#define netbuf_fromaddr_ip6(buf) (ipX_2_ip6(&((buf)->addr))) +#define netbuf_set_fromaddr_ip6(buf, fromaddr) ip6_addr_set(ipX_2_ip6(&((buf)->addr)), fromaddr) +#define netbuf_destaddr_ip6(buf) (ipX_2_ip6(&((buf)->toaddr))) +#define netbuf_set_destaddr_ip6(buf, destaddr) ip6_addr_set(ipX_2_ip6(&((buf)->toaddr)), destaddr) +#endif /* LWIP_IPV6 */ + +#define netbuf_fromaddr_ipX(buf) (&((buf)->addr)) +#define netbuf_destaddr_ipX(buf) (&((buf)->toaddr)) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +#endif /* LWIP_HDR_NETBUF_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netdb.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netdb.h new file mode 100644 index 0000000..d7acdc9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netdb.h @@ -0,0 +1,127 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef LWIP_HDR_NETDB_H +#define LWIP_HDR_NETDB_H + +#include "lwip/opt.h" + +#if LWIP_DNS && LWIP_SOCKET + +#include /* for size_t */ + +#include "lwip/inet.h" +#include "lwip/sockets.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* some rarely used options */ +#ifndef LWIP_DNS_API_DECLARE_H_ERRNO +#define LWIP_DNS_API_DECLARE_H_ERRNO 1 +#endif + +#ifndef LWIP_DNS_API_DEFINE_ERRORS +#define LWIP_DNS_API_DEFINE_ERRORS 1 +#endif + +#ifndef LWIP_DNS_API_DECLARE_STRUCTS +#define LWIP_DNS_API_DECLARE_STRUCTS 1 +#endif + +#if LWIP_DNS_API_DEFINE_ERRORS +/** Errors used by the DNS API functions, h_errno can be one of them */ +#define EAI_NONAME 200 +#define EAI_SERVICE 201 +#define EAI_FAIL 202 +#define EAI_MEMORY 203 +#define EAI_FAMILY 204 + +#define HOST_NOT_FOUND 210 +#define NO_DATA 211 +#define NO_RECOVERY 212 +#define TRY_AGAIN 213 +#endif /* LWIP_DNS_API_DEFINE_ERRORS */ + +#if LWIP_DNS_API_DECLARE_STRUCTS +struct hostent { + char *h_name; /* Official name of the host. */ + char **h_aliases; /* A pointer to an array of pointers to alternative host names, + terminated by a null pointer. */ + int h_addrtype; /* Address type. */ + int h_length; /* The length, in bytes, of the address. */ + char **h_addr_list; /* A pointer to an array of pointers to network addresses (in + network byte order) for the host, terminated by a null pointer. */ +#define h_addr h_addr_list[0] /* for backward compatibility */ +}; + +struct addrinfo { + int ai_flags; /* Input flags. */ + int ai_family; /* Address family of socket. */ + int ai_socktype; /* Socket type. */ + int ai_protocol; /* Protocol of socket. */ + socklen_t ai_addrlen; /* Length of socket address. */ + struct sockaddr *ai_addr; /* Socket address of socket. */ + char *ai_canonname; /* Canonical name of service location. */ + struct addrinfo *ai_next; /* Pointer to next in list. */ +}; +#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ + +#define NETDB_ELEM_SIZE (sizeof(struct addrinfo) + sizeof(struct sockaddr_in) + DNS_MAX_NAME_LENGTH + 1) + +#if LWIP_DNS_API_DECLARE_H_ERRNO +/* application accessible error code set by the DNS API functions */ +extern int h_errno; +#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ + +struct hostent *lwip_gethostbyname(const char *name); +int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, + size_t buflen, struct hostent **result, int *h_errnop); +void lwip_freeaddrinfo(struct addrinfo *ai); +int lwip_getaddrinfo(const char *nodename, + const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + +#if LWIP_COMPAT_SOCKETS +#define gethostbyname(name) lwip_gethostbyname(name) +#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ + lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) +#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) +#define getaddrinfo(nodname, servname, hints, res) \ + lwip_getaddrinfo(nodname, servname, hints, res) +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_DNS && LWIP_SOCKET */ + +#endif /* LWIP_HDR_NETDB_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netif.h new file mode 100644 index 0000000..fd2939d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netif.h @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_NETIF_H +#define LWIP_HDR_NETIF_H + +#include "lwip/opt.h" + +#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) + +#include "lwip/err.h" + +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#if LWIP_DHCP +struct dhcp; +#endif +#if LWIP_AUTOIP +struct autoip; +#endif +#if LWIP_IPV6_DHCP6 +#include "lwip/dhcp6.h" +#endif /* LWIP_IPV6_DHCP6 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Throughout this file, IP addresses are expected to be in + * the same byte order as in IP_PCB. */ + +/** Must be the maximum of all used hardware address lengths + across all types of interfaces in use. + This does not have to be changed, normally. */ +#ifndef NETIF_MAX_HWADDR_LEN +#define NETIF_MAX_HWADDR_LEN 6U +#endif + +/** Whether the network interface is 'up'. This is + * a software flag used to control whether this network + * interface is enabled and processes traffic. + * It is set by the startup code (for static IP configuration) or + * by dhcp/autoip when an address has been assigned. + */ +#define NETIF_FLAG_UP 0x01U +/** If set, the netif has broadcast capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_BROADCAST 0x02U +/** If set, the netif is one end of a point-to-point connection. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_POINTTOPOINT 0x04U +/** If set, the interface is configured using DHCP. + * Set by the DHCP code when starting or stopping DHCP. */ +#define NETIF_FLAG_DHCP 0x08U +/** If set, the interface has an active link + * (set by the network interface driver). + * Either set by the netif driver in its init function (if the link + * is up at that time) or at a later point once the link comes up + * (if link detection is supported by the hardware). */ +#define NETIF_FLAG_LINK_UP 0x10U +/** If set, the netif is an ethernet device using ARP. + * Set by the netif driver in its init function. + * Used to check input packet types and use of DHCP. */ +#define NETIF_FLAG_ETHARP 0x20U +/** If set, the netif is an ethernet device. It might not use + * ARP or TCP/IP if it is used for PPPoE only. + */ +#define NETIF_FLAG_ETHERNET 0x40U +/** If set, the netif has IGMP capability. + * Set by the netif driver in its init function. */ +#define NETIF_FLAG_IGMP 0x80U + +/* Realtek Modified Start */ +/** if set, the netif has IP layer switch capability */ +#ifdef CONFIG_DONT_CARE_TP +#define NETIF_FLAG_IPSWITCH 0x100U +#endif +/* Realtek Modified End */ + +/** Function prototype for netif init functions. Set up flags and output/linkoutput + * callback functions in this function. + * + * @param netif The netif to initialize + */ +typedef err_t (*netif_init_fn)(struct netif *netif); +/** Function prototype for netif->input functions. This function is saved as 'input' + * callback function in the netif struct. Call it when a packet has been received. + * + * @param p The received packet, copied into a pbuf + * @param inp The netif which received the packet + */ +typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); +/** Function prototype for netif->output functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'etharp_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IP address to which the packet shall be sent + */ +typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, + ip_addr_t *ipaddr); +#if LWIP_IPV6 +/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet + * shall be sent. For ethernet netif, set this to 'ethip6_output' and set + * 'linkoutput'. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (p->payload points to IP header) + * @param ipaddr The IPv6 address to which the packet shall be sent + */ +typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, + ip6_addr_t *ipaddr); +#endif /* LWIP_IPV6 */ +/** Function prototype for netif->linkoutput functions. Only used for ethernet + * netifs. This function is called by ARP when a packet shall be sent. + * + * @param netif The netif which shall send a packet + * @param p The packet to send (raw ethernet packet) + */ +typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); +/** Function prototype for netif status- or link-callback functions. */ +typedef void (*netif_status_callback_fn)(struct netif *netif); +/** Function prototype for netif igmp_mac_filter functions */ +typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, + ip_addr_t *group, u8_t action); +#if LWIP_IPV6 && LWIP_IPV6_MLD +/** Function prototype for netif mld_mac_filter functions */ +typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, + ip6_addr_t *group, u8_t action); +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + +/** Generic data structure used for all lwIP network interfaces. + * The following fields should be filled in by the initialization + * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ +struct netif { + /** pointer to next in linked list */ + struct netif *next; + + /** IP address configuration in network byte order */ + ip_addr_t ip_addr; + ip_addr_t netmask; + ip_addr_t gw; + +#if LWIP_IPV6 + /** Array of IPv6 addresses for this netif. */ + ip6_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; + /** The state of each IPv6 address (Tentative, Preferred, etc). + * @see ip6_addr.h */ + u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; +#endif /* LWIP_IPV6 */ + /** This function is called by the network device driver + * to pass a packet up the TCP/IP stack. */ + netif_input_fn input; + /** This function is called by the IP module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_fn output; + /** This function is called by the ARP module when it wants + * to send a packet on the interface. This function outputs + * the pbuf as-is on the link medium. */ + netif_linkoutput_fn linkoutput; +#if LWIP_IPV6 + /** This function is called by the IPv6 module when it wants + * to send a packet on the interface. This function typically + * first resolves the hardware address, then sends the packet. */ + netif_output_ip6_fn output_ip6; +#endif /* LWIP_IPV6 */ +#if LWIP_NETIF_STATUS_CALLBACK + /** This function is called when the netif state is set to up or down + */ + netif_status_callback_fn status_callback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + /** This function is called when the netif link is set to up or down + */ + netif_status_callback_fn link_callback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK + /** This function is called when the netif has been removed */ + netif_status_callback_fn remove_callback; +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + /** This field can be set by the device driver and could point + * to state information for the device. */ + void *state; +#if LWIP_DHCP + /** the DHCP client state information for this netif */ + struct dhcp *dhcp; +#endif /* LWIP_DHCP */ +#if LWIP_AUTOIP + /** the AutoIP client state information for this netif */ + struct autoip *autoip; +#endif +#if LWIP_IPV6_AUTOCONFIG + /** is this netif enabled for IPv6 autoconfiguration */ + u8_t ip6_autoconfig_enabled; +#endif /* LWIP_IPV6_AUTOCONFIG */ +#if LWIP_IPV6_SEND_ROUTER_SOLICIT + /** Number of Router Solicitation messages that remain to be sent. */ + u8_t rs_count; +#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ +#if LWIP_IPV6_DHCP6 + /** the DHCPv6 client state information for this netif */ + struct dhcp6 *dhcp6; +#endif /* LWIP_IPV6_DHCP6 */ +#if LWIP_NETIF_HOSTNAME + /* the hostname for this netif, NULL is a valid value */ + char* hostname; +#endif /* LWIP_NETIF_HOSTNAME */ + /** maximum transfer unit (in bytes) */ + u16_t mtu; + /** number of bytes used in hwaddr */ + u8_t hwaddr_len; + /** link level hardware address of this interface */ + u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; + /** flags (see NETIF_FLAG_ above) */ + //Realtek modified u8_t to u16_t for NETIF_FLAG_IPSWITCH extend flag + //u8_t flags; + u16_t flags; + //Realtek modified end + + /** descriptive abbreviation */ + char name[2]; + /** number of this interface */ + u8_t num; +#if LWIP_SNMP + /** link type (from "snmp_ifType" enum from snmp.h) */ + u8_t link_type; + /** (estimate) link speed */ + u32_t link_speed; + /** timestamp at last change made (up/down) */ + u32_t ts; + /** counters */ + u32_t ifinoctets; + u32_t ifinucastpkts; + u32_t ifinnucastpkts; + u32_t ifindiscards; + u32_t ifoutoctets; + u32_t ifoutucastpkts; + u32_t ifoutnucastpkts; + u32_t ifoutdiscards; +#endif /* LWIP_SNMP */ +#if LWIP_IGMP + /** This function could be called to add or delete an entry in the multicast + filter table of the ethernet MAC.*/ + netif_igmp_mac_filter_fn igmp_mac_filter; +#endif /* LWIP_IGMP */ +#if LWIP_IPV6 && LWIP_IPV6_MLD + /** This function could be called to add or delete an entry in the IPv6 multicast + filter table of the ethernet MAC. */ + netif_mld_mac_filter_fn mld_mac_filter; +#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +#if LWIP_NETIF_HWADDRHINT + u8_t *addr_hint; +#endif /* LWIP_NETIF_HWADDRHINT */ +#if ENABLE_LOOPBACK + /* List of packets to be queued for ourselves. */ + struct pbuf *loop_first; + struct pbuf *loop_last; +#if LWIP_LOOPBACK_MAX_PBUFS + u16_t loop_cnt_current; +#endif /* LWIP_LOOPBACK_MAX_PBUFS */ +#endif /* ENABLE_LOOPBACK */ +}; + +#if LWIP_SNMP +#define NETIF_INIT_SNMP(netif, type, speed) \ + /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \ + (netif)->link_type = (type); \ + /* your link speed here (units: bits per second) */ \ + (netif)->link_speed = (speed); \ + (netif)->ts = 0; \ + (netif)->ifinoctets = 0; \ + (netif)->ifinucastpkts = 0; \ + (netif)->ifinnucastpkts = 0; \ + (netif)->ifindiscards = 0; \ + (netif)->ifoutoctets = 0; \ + (netif)->ifoutucastpkts = 0; \ + (netif)->ifoutnucastpkts = 0; \ + (netif)->ifoutdiscards = 0 +#else /* LWIP_SNMP */ +#define NETIF_INIT_SNMP(netif, type, speed) +#endif /* LWIP_SNMP */ + + +/** The list of network interfaces. */ +extern struct netif *netif_list; +/** The default network interface. */ +extern struct netif *netif_default; + +void netif_init(void); + +struct netif *netif_add(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input); + +void +netif_set_addr(struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, + ip_addr_t *gw); +void netif_remove(struct netif * netif); + +/* Returns a network interface given its name. The name is of the form + "et0", where the first two letters are the "name" field in the + netif structure, and the digit is in the num field in the same + structure. */ +struct netif *netif_find(char *name); + +void netif_set_default(struct netif *netif); + +void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); +void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); +void netif_set_gw(struct netif *netif, ip_addr_t *gw); + +void netif_set_up(struct netif *netif); +void netif_set_down(struct netif *netif); +/** Ask if an interface is up */ +#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_STATUS_CALLBACK +void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_REMOVE_CALLBACK +void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); +#endif /* LWIP_NETIF_REMOVE_CALLBACK */ + +void netif_set_link_up(struct netif *netif); +void netif_set_link_down(struct netif *netif); +/** Ask if a link is up */ +#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) + +#if LWIP_NETIF_LINK_CALLBACK +void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#if LWIP_NETIF_HOSTNAME +#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) +#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) +#endif /* LWIP_NETIF_HOSTNAME */ + +#if LWIP_IGMP +#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) +#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) +#endif /* LWIP_IGMP */ + +#if ENABLE_LOOPBACK +err_t netif_loop_output(struct netif *netif, struct pbuf *p); +void netif_poll(struct netif *netif); +#if !LWIP_NETIF_LOOPBACK_MULTITHREADING +void netif_poll_all(void); +#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ +#endif /* ENABLE_LOOPBACK */ + +#if LWIP_IPV6 +#define netif_ip6_addr(netif, i) (&((netif)->ip6_addr[(i)])) +#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[(i)]) +#define netif_ip6_addr_set_state(netif, i, state) ((netif)->ip6_addr_state[(i)] = (state)) +s8_t netif_get_ip6_addr_match(struct netif * netif, ip6_addr_t * ip6addr); +void netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit); +#endif /* LWIP_IPV6 */ + +#if LWIP_NETIF_HWADDRHINT +#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) +#else /* LWIP_NETIF_HWADDRHINT */ +#define NETIF_SET_HWADDRHINT(netif, hint) +#endif /* LWIP_NETIF_HWADDRHINT */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_NETIF_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netifapi.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netifapi.h new file mode 100644 index 0000000..5d7738a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/netifapi.h @@ -0,0 +1,117 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef LWIP_HDR_NETIFAPI_H +#define LWIP_HDR_NETIFAPI_H + +#include "lwip/opt.h" + +#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_MPU_COMPATIBLE +#define NETIFAPI_IPADDR_DEF(m) m +#else /* LWIP_MPU_COMPATIBLE */ +#define NETIFAPI_IPADDR_DEF(m) *m +#endif /* LWIP_MPU_COMPATIBLE */ + +typedef void (*netifapi_void_fn)(struct netif *netif); +typedef err_t (*netifapi_errt_fn)(struct netif *netif); + +struct netifapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + err_t err; + struct netif *netif; + union { + struct { + ip_addr_t NETIFAPI_IPADDR_DEF(ipaddr); + ip_addr_t NETIFAPI_IPADDR_DEF(netmask); + ip_addr_t NETIFAPI_IPADDR_DEF(gw); + void *state; + netif_init_fn init; + netif_input_fn input; + } add; + struct { + netifapi_void_fn voidfunc; + netifapi_errt_fn errtfunc; + } common; + } msg; +}; + +struct netifapi_msg { + void (* function)(struct netifapi_msg_msg *msg); + struct netifapi_msg_msg msg; +}; + + +/* API for application */ +err_t netifapi_netif_add ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw, + void *state, + netif_init_fn init, + netif_input_fn input); + +err_t netifapi_netif_set_addr ( struct netif *netif, + ip_addr_t *ipaddr, + ip_addr_t *netmask, + ip_addr_t *gw ); + +err_t netifapi_netif_common ( struct netif *netif, + netifapi_void_fn voidfunc, + netifapi_errt_fn errtfunc); + +#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) +#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) +#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) +#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) +#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) +#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) +#define netifapi_dhcp_inform(n) netifapi_netif_common(n, dhcp_inform, NULL) +#define netifapi_dhcp_renew(n) netifapi_netif_common(n, NULL, dhcp_renew) +#define netifapi_dhcp_release(n) netifapi_netif_common(n, NULL, dhcp_release) +#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) +#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_NETIF_API */ + +#endif /* LWIP_HDR_NETIFAPI_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/opt.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/opt.h new file mode 100644 index 0000000..7e8511d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/opt.h @@ -0,0 +1,2773 @@ +/** + * @file + * + * lwIP Options Configuration + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_OPT_H +#define LWIP_HDR_OPT_H + +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you don't like! + */ +#include "lwipopts.h" +#include "lwip/debug.h" + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ + +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#ifndef SYS_LIGHTWEIGHT_PROT +#define SYS_LIGHTWEIGHT_PROT 0 +#endif + +/** + * NO_SYS==1: Provides VERY minimal functionality. Otherwise, + * use lwIP facilities. + */ +#ifndef NO_SYS +#define NO_SYS 0 +#endif + +/** + * NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1 + * Mainly for compatibility to old versions. + */ +#ifndef NO_SYS_NO_TIMERS +#define NO_SYS_NO_TIMERS 0 +#endif + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#ifndef MEMCPY +#define MEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#ifndef SMEMCPY +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) +#endif + +/** + * LWIP_MPU_COMPATIBLE: enables special memory management mechanism + * which makes lwip able to work on MPU (Memory Protection Unit) system + * by not passing stack-pointers to other threads + * (this decreases performance) + */ +#ifndef LWIP_MPU_COMPATIBLE +#define LWIP_MPU_COMPATIBLE 0 +#endif + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#ifndef MEM_LIBC_MALLOC +#define MEM_LIBC_MALLOC 0 +#endif + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#ifndef MEMP_MEM_MALLOC +#define MEMP_MEM_MALLOC 0 +#endif + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#ifndef MEM_ALIGNMENT +#define MEM_ALIGNMENT 1 +#endif + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#ifndef MEM_SIZE +#define MEM_SIZE 1600 +#endif + +/** + * MEMP_SEPARATE_POOLS: if defined to 1, each pool is placed in its own array. + * This can be used to individually change the location of each pool. + * Default is one big array for all pools + */ +#ifndef MEMP_SEPARATE_POOLS +#define MEMP_SEPARATE_POOLS 0 +#endif + +/** + * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable + * amount of bytes before and after each memp element in every pool and fills + * it with a prominent default value. + * MEMP_OVERFLOW_CHECK == 0 no checking + * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed + * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time + * memp_malloc() or memp_free() is called (useful but slow!) + */ +#ifndef MEMP_OVERFLOW_CHECK +#define MEMP_OVERFLOW_CHECK 0 +#endif + +/** + * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make + * sure that there are no cycles in the linked lists. + */ +#ifndef MEMP_SANITY_CHECK +#define MEMP_SANITY_CHECK 0 +#endif + +/** + * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set + * of memory pools of various sizes. When mem_malloc is called, an element of + * the smallest pool that can provide the length needed is returned. + * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. + */ +#ifndef MEM_USE_POOLS +#define MEM_USE_POOLS 0 +#endif + +/** + * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next + * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more + * reliable. */ +#ifndef MEM_USE_POOLS_TRY_BIGGER_POOL +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +#endif + +/** + * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h + * that defines additional pools beyond the "standard" ones required + * by lwIP. If you set this to 1, you must have lwippools.h in your + * include path somewhere. + */ +#ifndef MEMP_USE_CUSTOM_POOLS +#define MEMP_USE_CUSTOM_POOLS 0 +#endif + +/** + * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from + * interrupt context (or another context that doesn't allow waiting for a + * semaphore). + * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, + * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs + * with each loop so that mem_free can run. + * + * ATTENTION: As you can see from the above description, this leads to dis-/ + * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc + * can need longer. + * + * If you don't want that, at least for NO_SYS=0, you can still use the following + * functions to enqueue a deallocation call which then runs in the tcpip_thread + * context: + * - pbuf_free_callback(p); + * - mem_free_callback(m); + */ +#ifndef LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT +#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 +#endif + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#ifndef MEMP_NUM_PBUF +#define MEMP_NUM_PBUF 16 +#endif + +/** + * MEMP_NUM_RAW_PCB: Number of raw connection PCBs + * (requires the LWIP_RAW option) + */ +#ifndef MEMP_NUM_RAW_PCB +#define MEMP_NUM_RAW_PCB 4 +#endif + +/** + * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One + * per active UDP "connection". + * (requires the LWIP_UDP option) + */ +#ifndef MEMP_NUM_UDP_PCB +#define MEMP_NUM_UDP_PCB 4 +#endif + +/** + * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB +#define MEMP_NUM_TCP_PCB 5 +#endif + +/** + * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_PCB_LISTEN +#define MEMP_NUM_TCP_PCB_LISTEN 8 +#endif + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#ifndef MEMP_NUM_TCP_SEG +#define MEMP_NUM_TCP_SEG 16 +#endif + +/** + * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for + * reassembly (whole packets, not fragments!) + */ +#ifndef MEMP_NUM_REASSDATA +#define MEMP_NUM_REASSDATA 5 +#endif + +/** + * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent + * (fragments, not whole packets!). + * This is only used with IP_FRAG_USES_STATIC_BUF==0 and + * LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 with DMA-enabled MACs + * where the packet is not yet sent when netif->output returns. + */ +#ifndef MEMP_NUM_FRAG_PBUF +#define MEMP_NUM_FRAG_PBUF 15 +#endif + +/** + * MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing + * packets (pbufs) that are waiting for an ARP request (to resolve + * their destination address) to finish. + * (requires the ARP_QUEUEING option) + */ +#ifndef MEMP_NUM_ARP_QUEUE +#define MEMP_NUM_ARP_QUEUE 30 +#endif + +/** + * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces + * can be members at the same time (one per netif - allsystems group -, plus one + * per netif membership). + * (requires the LWIP_IGMP option) + */ +#ifndef MEMP_NUM_IGMP_GROUP +#define MEMP_NUM_IGMP_GROUP 8 +#endif + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts. + * The default number of timeouts is calculated here for all enabled modules. + * The formula expects settings to be either '0' or '1'. + */ +#ifndef MEMP_NUM_SYS_TIMEOUT +#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) +#endif + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETBUF +#define MEMP_NUM_NETBUF 2 +#endif + +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + */ +#ifndef MEMP_NUM_NETCONN +#define MEMP_NUM_NETCONN 4 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used + * for callback/timeout API communication. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_API +#define MEMP_NUM_TCPIP_MSG_API 8 +#endif + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ +#ifndef MEMP_NUM_TCPIP_MSG_INPKT +#define MEMP_NUM_TCPIP_MSG_INPKT 8 +#endif + +/** + * MEMP_NUM_SNMP_NODE: the number of leafs in the SNMP tree. + */ +#ifndef MEMP_NUM_SNMP_NODE +#define MEMP_NUM_SNMP_NODE 50 +#endif + +/** + * MEMP_NUM_SNMP_ROOTNODE: the number of branches in the SNMP tree. + * Every branch has one leaf (MEMP_NUM_SNMP_NODE) at least! + */ +#ifndef MEMP_NUM_SNMP_ROOTNODE +#define MEMP_NUM_SNMP_ROOTNODE 30 +#endif + +/** + * MEMP_NUM_SNMP_VARBIND: the number of concurrent requests (does not have to + * be changed normally) - 2 of these are used per request (1 for input, + * 1 for output) + */ +#ifndef MEMP_NUM_SNMP_VARBIND +#define MEMP_NUM_SNMP_VARBIND 2 +#endif + +/** + * MEMP_NUM_SNMP_VALUE: the number of OID or values concurrently used + * (does not have to be changed normally) - 3 of these are used per request + * (1 for the value read and 2 for OIDs - input and output) + */ +#ifndef MEMP_NUM_SNMP_VALUE +#define MEMP_NUM_SNMP_VALUE 3 +#endif + +/** + * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls + * (before freeing the corresponding memory using lwip_freeaddrinfo()). + */ +#ifndef MEMP_NUM_NETDB +#define MEMP_NUM_NETDB 1 +#endif + +/** + * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list + * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. + */ +#ifndef MEMP_NUM_LOCALHOSTLIST +#define MEMP_NUM_LOCALHOSTLIST 1 +#endif + +/** + * MEMP_NUM_PPP_PCB: the number of simultaneously active PPP + * connections (requires the PPP_SUPPORT option) + */ +#ifndef MEMP_NUM_PPP_PCB +#define MEMP_NUM_PPP_PCB 1 +#endif + +/** + * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE + * interfaces (only used with PPPOE_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOE_INTERFACES +#define MEMP_NUM_PPPOE_INTERFACES 1 +#endif + +/** + * MEMP_NUM_PPPOL2TP_INTERFACES: the number of concurrently active PPPoL2TP + * interfaces (only used with PPPOL2TP_SUPPORT==1) + */ +#ifndef MEMP_NUM_PPPOL2TP_INTERFACES +#define MEMP_NUM_PPPOL2TP_INTERFACES 1 +#endif + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#ifndef PBUF_POOL_SIZE +#define PBUF_POOL_SIZE 16 +#endif + +/** MEMP_NUM_API_MSG: the number of concurrently active calls to various + * socket, netconn, and tcpip functions + */ +#ifndef MEMP_NUM_API_MSG +#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname + */ +#ifndef MEMP_NUM_DNS_API_MSG +#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls + * to getsockopt/setsockopt + */ +#ifndef MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA +#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API +#endif + +/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the + * netifapi functions + */ +#ifndef MEMP_NUM_NETIFAPI_MSG +#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API +#endif + +/* + --------------------------------- + ---------- ARP options ---------- + --------------------------------- +*/ +/** + * LWIP_ARP==1: Enable ARP functionality. + */ +#ifndef LWIP_ARP +#define LWIP_ARP 1 +#endif + +/** + * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. + */ +#ifndef ARP_TABLE_SIZE +#define ARP_TABLE_SIZE 10 +#endif + +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#ifndef ARP_QUEUEING +#define ARP_QUEUEING 1 //Realtek changed 0 -> 1 +#endif + +/** The maximum number of packets which may be queued for each + * unresolved address by other network layers. Defaults to 3, 0 means disabled. + * Old packets are dropped, new packets are queued. + */ +#ifndef ARP_QUEUE_LEN +#define ARP_QUEUE_LEN 0 //Realtek changed 3 -> 0 +#endif + +/** + * ETHARP_TRUST_IP_MAC==1: Incoming IP packets cause the ARP table to be + * updated with the source MAC and IP addresses supplied in the packet. + * You may want to disable this if you do not trust LAN peers to have the + * correct addresses, or as a limited approach to attempt to handle + * spoofing. If disabled, lwIP will need to make a new ARP request if + * the peer is not already in the ARP table, adding a little latency. + * The peer *is* in the ARP table if it requested our address before. + * Also notice that this slows down input processing of every IP packet! + */ +#ifndef ETHARP_TRUST_IP_MAC +#define ETHARP_TRUST_IP_MAC 1 //Realtek changed 0 -> 1 +#endif + +/** + * ETHARP_SUPPORT_VLAN==1: support receiving and sending ethernet packets with + * VLAN header. See the description of LWIP_HOOK_VLAN_CHECK and + * LWIP_HOOK_VLAN_SET hooks to check/set VLAN headers. + * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. + * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. + * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. + * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) + * that returns 1 to accept a packet or 0 to drop a packet. + */ +#ifndef ETHARP_SUPPORT_VLAN +#define ETHARP_SUPPORT_VLAN 0 +#endif + +/** LWIP_ETHERNET==1: enable ethernet support for PPPoE even though ARP + * might be disabled + */ +#ifndef LWIP_ETHERNET +#define LWIP_ETHERNET (LWIP_ARP || PPPOE_SUPPORT) +#endif + +/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure + * alignment of payload after that header. Since the header is 14 bytes long, + * without this padding e.g. addresses in the IP header will not be aligned + * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. + */ +#ifndef ETH_PAD_SIZE +#define ETH_PAD_SIZE 0 +#endif + +/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table + * entries (using etharp_add_static_entry/etharp_remove_static_entry). + */ +#ifndef ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_SUPPORT_STATIC_ENTRIES 0 +#endif + + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_FORWARD==1: Enables the ability to forward IP packets across network + * interfaces. If you are going to run lwIP on a device with only one network + * interface, define this to 0. + */ +#ifndef IP_FORWARD +#define IP_FORWARD 0 +#endif + +/** + * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. + * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. + * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). + */ +#ifndef IP_OPTIONS_ALLOWED +#define IP_OPTIONS_ALLOWED 1 +#endif + +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#ifndef IP_REASSEMBLY +#define IP_REASSEMBLY 1 +#endif + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#ifndef IP_FRAG +#define IP_FRAG 1 +#endif + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#ifndef IP_REASS_MAXAGE +#define IP_REASS_MAXAGE 3 +#endif + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#ifndef IP_REASS_MAX_PBUFS +#define IP_REASS_MAX_PBUFS 10 +#endif + +/** + * IP_FRAG_USES_STATIC_BUF==1: Use a static MTU-sized buffer for IP + * fragmentation. Otherwise pbufs are allocated and reference the original + * packet data to be fragmented (or with LWIP_NETIF_TX_SINGLE_PBUF==1, + * new PBUF_RAM pbufs are used for fragments). + * ATTENTION: IP_FRAG_USES_STATIC_BUF==1 may not be used for DMA-enabled MACs! + */ +#ifndef IP_FRAG_USES_STATIC_BUF +#define IP_FRAG_USES_STATIC_BUF 0 +#endif + +/** + * IP_FRAG_MAX_MTU: Assumed max MTU on any interface for IP frag buffer + * (requires IP_FRAG_USES_STATIC_BUF==1) + */ +#if IP_FRAG_USES_STATIC_BUF && !defined(IP_FRAG_MAX_MTU) +#define IP_FRAG_MAX_MTU 1500 +#endif + +/** + * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. + */ +#ifndef IP_DEFAULT_TTL +#define IP_DEFAULT_TTL 255 +#endif + +/** + * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast + * filter per pcb on udp and raw send operations. To enable broadcast filter + * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. + */ +#ifndef IP_SOF_BROADCAST +#define IP_SOF_BROADCAST 0 +#endif + +/** + * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast + * filter on recv operations. + */ +#ifndef IP_SOF_BROADCAST_RECV +#define IP_SOF_BROADCAST_RECV 0 +#endif + +/** + * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back + * out on the netif where it was received. This should only be used for + * wireless networks. + * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming + * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! + */ +#ifndef IP_FORWARD_ALLOW_TX_ON_RX_NETIF +#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 +#endif + +/** + * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first + * local TCP/UDP pcb (default==0). This can prevent creating predictable port + * numbers after booting a device. + */ +#ifndef LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS +#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 +#endif + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_ICMP==1: Enable ICMP module inside the IP stack. + * Be careful, disable that make your product non-compliant to RFC1122 + */ +#ifndef LWIP_ICMP +#define LWIP_ICMP 1 +#endif + +/** + * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. + */ +#ifndef ICMP_TTL +#define ICMP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) + */ +#ifndef LWIP_BROADCAST_PING +#define LWIP_BROADCAST_PING 0 +#endif + +/** + * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) + */ +#ifndef LWIP_MULTICAST_PING +#define LWIP_MULTICAST_PING 0 +#endif + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef LWIP_RAW +#define LWIP_RAW 1 +#endif + +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#ifndef RAW_TTL +#define RAW_TTL (IP_DEFAULT_TTL) +#endif + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#ifndef LWIP_DHCP +#define LWIP_DHCP 0 +#endif + +/** + * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. + */ +#ifndef DHCP_DOES_ARP_CHECK +#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) +#endif + +/** + * LWIP_DHCP_CHECK_LINK_UP==1: dhcp_start() only really starts if the netif has + * NETIF_FLAG_LINK_UP set in its flags. As this is only an optimization and + * netif drivers might not set this flag, the default is off. If enabled, + * netif_set_link_up() must be called to continue dhcp starting. + */ +#ifndef LWIP_DHCP_CHECK_LINK_UP +#define LWIP_DHCP_CHECK_LINK_UP 0 +#endif + +/** + * LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name. + */ +#ifndef LWIP_DHCP_BOOTP_FILE +#define LWIP_DHCP_BOOTP_FILE 0 +#endif + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/** + * LWIP_AUTOIP==1: Enable AUTOIP module. + */ +#ifndef LWIP_AUTOIP +#define LWIP_AUTOIP 1 //Realtek modified (0->1) +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on + * the same interface at the same time. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP +#define LWIP_DHCP_AUTOIP_COOP 0 +#endif + +/** + * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes + * that should be sent before falling back on AUTOIP. This can be set + * as low as 1 to get an AutoIP address very quickly, but you should + * be prepared to handle a changing IP address when DHCP overrides + * AutoIP. + */ +#ifndef LWIP_DHCP_AUTOIP_COOP_TRIES +#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 +#endif + +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_SNMP==1: Turn on SNMP module. UDP must be available for SNMP + * transport. + */ +#ifndef LWIP_SNMP +#define LWIP_SNMP 0 +#endif + +/** + * SNMP_CONCURRENT_REQUESTS: Number of concurrent requests the module will + * allow. At least one request buffer is required. + * Does not have to be changed unless external MIBs answer request asynchronously + */ +#ifndef SNMP_CONCURRENT_REQUESTS +#define SNMP_CONCURRENT_REQUESTS 1 +#endif + +/** + * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap + * destination is required + */ +#ifndef SNMP_TRAP_DESTINATIONS +#define SNMP_TRAP_DESTINATIONS 1 +#endif + +/** + * SNMP_PRIVATE_MIB: + * When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. + */ +#ifndef SNMP_PRIVATE_MIB +#define SNMP_PRIVATE_MIB 0 +#endif + +/** + * Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not + * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). + * Unsafe requests are disabled by default! + */ +#ifndef SNMP_SAFE_REQUESTS +#define SNMP_SAFE_REQUESTS 1 +#endif + +/** + * The maximum length of strings used. This affects the size of + * MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_OCTET_STRING_LEN +#define SNMP_MAX_OCTET_STRING_LEN 127 +#endif + +/** + * The maximum depth of the SNMP tree. + * With private MIBs enabled, this depends on your MIB! + * This affects the size of MEMP_SNMP_VALUE elements. + */ +#ifndef SNMP_MAX_TREE_DEPTH +#define SNMP_MAX_TREE_DEPTH 15 +#endif + +/** + * The size of the MEMP_SNMP_VALUE elements, normally calculated from + * SNMP_MAX_OCTET_STRING_LEN and SNMP_MAX_TREE_DEPTH. + */ +#ifndef SNMP_MAX_VALUE_SIZE +#define SNMP_MAX_VALUE_SIZE LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN)+1, sizeof(s32_t)*(SNMP_MAX_TREE_DEPTH)) +#endif + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#ifndef LWIP_IGMP +#define LWIP_IGMP 0 +#endif + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#ifndef LWIP_DNS +#define LWIP_DNS 0 +#endif + +/** DNS maximum number of entries to maintain locally. */ +#ifndef DNS_TABLE_SIZE +#define DNS_TABLE_SIZE 4 +#endif + +/** DNS maximum host name length supported in the name table. */ +#ifndef DNS_MAX_NAME_LENGTH +#define DNS_MAX_NAME_LENGTH 256 +#endif + +/** The maximum of DNS servers */ +#ifndef DNS_MAX_SERVERS +#define DNS_MAX_SERVERS 2 +#endif + +/** DNS do a name checking between the query and the response. */ +#ifndef DNS_DOES_NAME_CHECK +#define DNS_DOES_NAME_CHECK 1 +#endif + +/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, + * you have to define + * #define DNS_LOCAL_HOSTLIST_INIT {{"host1", 0x123}, {"host2", 0x234}} + * (an array of structs name/address, where address is an u32_t in network + * byte order). + * + * Instead, you can also use an external function: + * #define DNS_LOOKUP_LOCAL_EXTERN(x) extern u32_t my_lookup_function(const char *name) + * that returns the IP address or INADDR_NONE if not found. + */ +#ifndef DNS_LOCAL_HOSTLIST +#define DNS_LOCAL_HOSTLIST 0 +#endif /* DNS_LOCAL_HOSTLIST */ + +/** If this is turned on, the local host-list can be dynamically changed + * at runtime. */ +#ifndef DNS_LOCAL_HOSTLIST_IS_DYNAMIC +#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 +#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/** + * LWIP_UDP==1: Turn on UDP. + */ +#ifndef LWIP_UDP +#define LWIP_UDP 1 +#endif + +/** + * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) + */ +#ifndef LWIP_UDPLITE +#define LWIP_UDPLITE 0 +#endif + +/** + * UDP_TTL: Default Time-To-Live value. + */ +#ifndef UDP_TTL +#define UDP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. + */ +#ifndef LWIP_NETBUF_RECVINFO +#define LWIP_NETBUF_RECVINFO 0 +#endif + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * LWIP_TCP==1: Turn on TCP. + */ +#ifndef LWIP_TCP +#define LWIP_TCP 1 +#endif + +/** + * TCP_TTL: Default Time-To-Live value. + */ +#ifndef TCP_TTL +#define TCP_TTL (IP_DEFAULT_TTL) +#endif + +/** + * TCP_WND: The size of a TCP window. This must be at least + * (2 * TCP_MSS) for things to work well + */ +#ifndef TCP_WND +#define TCP_WND (4 * TCP_MSS) +#endif + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#ifndef TCP_MAXRTX +#define TCP_MAXRTX 12 +#endif + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#ifndef TCP_SYNMAXRTX +#define TCP_SYNMAXRTX 6 +#endif + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#ifndef TCP_QUEUE_OOSEQ +#define TCP_QUEUE_OOSEQ (LWIP_TCP) +#endif + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#ifndef TCP_MSS +#define TCP_MSS 536 +#endif + +/** + * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really + * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which + * reflects the available reassembly buffer size at the remote host) and the + * largest size permitted by the IP layer" (RFC 1122) + * Setting this to 1 enables code that checks TCP_MSS against the MTU of the + * netif used for a connection and limits the MSS if it would be too big otherwise. + */ +#ifndef TCP_CALCULATE_EFF_SEND_MSS +#define TCP_CALCULATE_EFF_SEND_MSS 1 +#endif + + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#ifndef TCP_SND_BUF +#define TCP_SND_BUF (2 * TCP_MSS) +#endif + +/** + * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least + * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. + */ +#ifndef TCP_SND_QUEUELEN +#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) +#endif + +/** + * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than + * TCP_SND_BUF. It is the amount of space which must be available in the + * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). + */ +#ifndef TCP_SNDLOWAT +#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) +#endif + +/** + * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less + * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below + * this number, select returns writable (combined with TCP_SNDLOWAT). + */ +#ifndef TCP_SNDQUEUELOWAT +#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) +#endif + +/** + * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_BYTES +#define TCP_OOSEQ_MAX_BYTES 0 +#endif + +/** + * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. + * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==0. + */ +#ifndef TCP_OOSEQ_MAX_PBUFS +#define TCP_OOSEQ_MAX_PBUFS 0 +#endif + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#ifndef TCP_LISTEN_BACKLOG +#define TCP_LISTEN_BACKLOG 0 +#endif + +/** + * The maximum allowed backlog for TCP listen netconns. + * This backlog is used unless another is explicitly specified. + * 0xff is the maximum (u8_t). + */ +#ifndef TCP_DEFAULT_LISTEN_BACKLOG +#define TCP_DEFAULT_LISTEN_BACKLOG 0xff +#endif + +/** + * TCP_OVERSIZE: The maximum number of bytes that tcp_write may + * allocate ahead of time in an attempt to create shorter pbuf chains + * for transmission. The meaningful range is 0 to TCP_MSS. Some + * suggested values are: + * + * 0: Disable oversized allocation. Each tcp_write() allocates a new + pbuf (old behaviour). + * 1: Allocate size-aligned pbufs with minimal excess. Use this if your + * scatter-gather DMA requires aligned fragments. + * 128: Limit the pbuf/memory overhead to 20%. + * TCP_MSS: Try to create unfragmented TCP packets. + * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. + */ +#ifndef TCP_OVERSIZE +#define TCP_OVERSIZE 0 //Realtek changed TCP_MSS -> 0 +#endif + +/** + * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. + * The timestamp option is currently only used to help remote hosts, it is not + * really used locally. Therefore, it is only enabled when a TS option is + * received in the initial SYN packet from a remote host. + */ +#ifndef LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_TIMESTAMPS 0 +#endif + +/** + * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an + * explicit window update + */ +#ifndef TCP_WND_UPDATE_THRESHOLD +#define TCP_WND_UPDATE_THRESHOLD (TCP_WND / 4) +#endif + +/** + * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. + */ +#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) +#define LWIP_EVENT_API 0 +#define LWIP_CALLBACK_API 1 +#endif + +/** + * LWIP_WND_SCALE and TCP_RCV_SCALE: + * Set LWIP_WND_SCALE to 1 to enable window scaling. + * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the + * range of [0..14]). + * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large + * send window while having a small receive window only. + */ +#ifndef LWIP_WND_SCALE +#define LWIP_WND_SCALE 0 +#define TCP_RCV_SCALE 0 +#endif + + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ +/** + * PBUF_LINK_HLEN: the number of bytes that should be allocated for a + * link level header. The default is 14, the standard value for + * Ethernet. + */ +#ifndef PBUF_LINK_HLEN +#ifdef LWIP_HOOK_VLAN_SET +#define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) +#else /* LWIP_HOOK_VLAN_SET */ +#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) +#endif /* LWIP_HOOK_VLAN_SET */ +#endif + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accommodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#ifndef PBUF_POOL_BUFSIZE +#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_HLEN) +#endif + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#ifndef LWIP_NETIF_HOSTNAME +#define LWIP_NETIF_HOSTNAME 0 +#endif + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#ifndef LWIP_NETIF_API +#define LWIP_NETIF_API 0 +#endif + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquisition) + */ +#ifndef LWIP_NETIF_STATUS_CALLBACK +#define LWIP_NETIF_STATUS_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#ifndef LWIP_NETIF_LINK_CALLBACK +#define LWIP_NETIF_LINK_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called + * when a netif has been removed + */ +#ifndef LWIP_NETIF_REMOVE_CALLBACK +#define LWIP_NETIF_REMOVE_CALLBACK 0 +#endif + +/** + * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table + * indices) in struct netif. TCP and UDP can make use of this to prevent + * scanning the ARP table for every sent packet. While this is faster for big + * ARP tables or many concurrent connections, it might be counterproductive + * if you have a tiny ARP table or if there never are concurrent connections. + */ +#ifndef LWIP_NETIF_HWADDRHINT +#define LWIP_NETIF_HWADDRHINT 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP + * address equal to the netif IP address, looping them back up the stack. + */ +#ifndef LWIP_NETIF_LOOPBACK +#define LWIP_NETIF_LOOPBACK 0 +#endif + +/** + * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback + * sending for each netif (0 = disabled) + */ +#ifndef LWIP_LOOPBACK_MAX_PBUFS +#define LWIP_LOOPBACK_MAX_PBUFS 0 +#endif + +/** + * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in + * the system, as netifs must change how they behave depending on this setting + * for the LWIP_NETIF_LOOPBACK option to work. + * Setting this is needed to avoid reentering non-reentrant functions like + * tcp_input(). + * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a + * multithreaded environment like tcpip.c. In this case, netif->input() + * is called directly. + * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. + * The packets are put on a list and netif_poll() must be called in + * the main application loop. + */ +#ifndef LWIP_NETIF_LOOPBACK_MULTITHREADING +#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) +#endif + +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#ifndef LWIP_NETIF_TX_SINGLE_PBUF +#define LWIP_NETIF_TX_SINGLE_PBUF 0 +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) + */ +#ifndef LWIP_HAVE_LOOPIF +#define LWIP_HAVE_LOOPIF 0 +#endif + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ +/** + * LWIP_HAVE_SLIPIF==1: Support slip interface and slipif.c + */ +#ifndef LWIP_HAVE_SLIPIF +#define LWIP_HAVE_SLIPIF 0 +#endif + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. + */ +#ifndef TCPIP_THREAD_NAME +#define TCPIP_THREAD_NAME "TCP_IP" // Realtek modified ("tcpip_thread" -> "TCP_IP") +#endif + +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_STACKSIZE +#define TCPIP_THREAD_STACKSIZE 0 +#endif + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef TCPIP_THREAD_PRIO +#define TCPIP_THREAD_PRIO 1 +#endif + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + +/** + * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. + */ +#ifndef SLIPIF_THREAD_NAME +#define SLIPIF_THREAD_NAME "slipif_loop" +#endif + +/** + * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_STACKSIZE +#define SLIPIF_THREAD_STACKSIZE 0 +#endif + +/** + * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef SLIPIF_THREAD_PRIO +#define SLIPIF_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. + */ +#ifndef DEFAULT_THREAD_NAME +#define DEFAULT_THREAD_NAME "lwIP" +#endif + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_STACKSIZE +#define DEFAULT_THREAD_STACKSIZE 0 +#endif + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#ifndef DEFAULT_THREAD_PRIO +#define DEFAULT_THREAD_PRIO 1 +#endif + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RAW_RECVMBOX_SIZE +#define DEFAULT_RAW_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_UDP_RECVMBOX_SIZE +#define DEFAULT_UDP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_TCP_RECVMBOX_SIZE +#define DEFAULT_TCP_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** + * LWIP_TCPIP_CORE_LOCKING: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif + +/** + * LWIP_TCPIP_CORE_LOCKING_INPUT: (EXPERIMENTAL!) + * Don't use it if you're not an active lwIP project member + */ +#ifndef LWIP_TCPIP_CORE_LOCKING_INPUT +#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 +#endif + +/** + * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) + */ +#ifndef LWIP_NETCONN +#define LWIP_NETCONN 1 +#endif + +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create + * timers running in tcpip_thread from another thread. + */ +#ifndef LWIP_TCPIP_TIMEOUT +#define LWIP_TCPIP_TIMEOUT 1 +#endif + +/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per + * thread calling socket/netconn functions instead of allocating one + * semaphore per netconn (and per select etc.) + * ATTENTION: a thread-local semaphore for API calls is needed: + * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t* + * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore + * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore + * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). + * Ports may call these for threads created with sys_thread_new(). + */ +#ifndef LWIP_NETCONN_SEM_PER_THREAD +#define LWIP_NETCONN_SEM_PER_THREAD 0 +#endif + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#ifndef LWIP_SOCKET +#define LWIP_SOCKET 1 +#endif + +/* LWIP_SOCKET_SET_ERRNO==1: Set errno when socket functions cannot complete + * successfully, as required by POSIX. Default is POSIX-compliant. + */ +#ifndef LWIP_SOCKET_SET_ERRNO +#define LWIP_SOCKET_SET_ERRNO 0 +#endif + +/** + * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names. + * (only used if you use sockets.c) + */ +#ifndef LWIP_COMPAT_SOCKETS +#define LWIP_COMPAT_SOCKETS 1 +#endif + +/** + * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. + * Disable this option if you use a POSIX operating system that uses the same + * names (read, write & close). (only used if you use sockets.c) + */ +#ifndef LWIP_POSIX_SOCKETS_IO_NAMES +#define LWIP_POSIX_SOCKETS_IO_NAMES 1 +#endif + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#ifndef LWIP_TCP_KEEPALIVE +#define LWIP_TCP_KEEPALIVE 0 +#endif + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#ifndef LWIP_SO_SNDTIMEO +#define LWIP_SO_SNDTIMEO 0 +#endif + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#ifndef LWIP_SO_RCVTIMEO +#define LWIP_SO_RCVTIMEO 1 //Realtek modified(0->1) +#endif + +/** + * LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int + * (milliseconds, much like winsock does) instead of a struct timeval (default). + */ +#ifndef LWIP_SO_SNDRCVTIMEO_NONSTANDARD +#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 +#endif + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#ifndef LWIP_SO_RCVBUF +#define LWIP_SO_RCVBUF 0 +#endif + +/** + * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. + */ +#ifndef RECV_BUFSIZE_DEFAULT +#define RECV_BUFSIZE_DEFAULT INT_MAX +#endif + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#ifndef SO_REUSE +#define SO_REUSE 0 +#endif + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#ifndef SO_REUSE_RXTOALL +#define SO_REUSE_RXTOALL 0 +#endif + +/** + * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of + * pending data in the network buffer. This is the way windows does it. It's + * the default for lwIP since it is smaller. + * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next + * pending datagram in bytes. This is the way linux does it. This code is only + * here for compatibility. + */ +#ifndef LWIP_FIONREAD_LINUXMODE +#define LWIP_FIONREAD_LINUXMODE 0 +#endif + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#ifndef LWIP_STATS +#define LWIP_STATS 1 +#endif + +#if LWIP_STATS + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#ifndef LWIP_STATS_DISPLAY +#define LWIP_STATS_DISPLAY 0 +#endif + +/** + * LINK_STATS==1: Enable link stats. + */ +#ifndef LINK_STATS +#define LINK_STATS 1 +#endif + +/** + * ETHARP_STATS==1: Enable etharp stats. + */ +#ifndef ETHARP_STATS +#define ETHARP_STATS (LWIP_ARP) +#endif + +/** + * IP_STATS==1: Enable IP stats. + */ +#ifndef IP_STATS +#define IP_STATS 1 +#endif + +/** + * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is + * on if using either frag or reass. + */ +#ifndef IPFRAG_STATS +#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) +#endif + +/** + * ICMP_STATS==1: Enable ICMP stats. + */ +#ifndef ICMP_STATS +#define ICMP_STATS 1 +#endif + +/** + * IGMP_STATS==1: Enable IGMP stats. + */ +#ifndef IGMP_STATS +#define IGMP_STATS (LWIP_IGMP) +#endif + +/** + * UDP_STATS==1: Enable UDP stats. Default is on if + * UDP enabled, otherwise off. + */ +#ifndef UDP_STATS +#define UDP_STATS (LWIP_UDP) +#endif + +/** + * TCP_STATS==1: Enable TCP stats. Default is on if TCP + * enabled, otherwise off. + */ +#ifndef TCP_STATS +#define TCP_STATS (LWIP_TCP) +#endif + +/** + * MEM_STATS==1: Enable mem.c stats. + */ +#ifndef MEM_STATS +#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) +#endif + +/** + * MEMP_STATS==1: Enable memp.c pool stats. + */ +#ifndef MEMP_STATS +#define MEMP_STATS (MEMP_MEM_MALLOC == 0) +#endif + +/** + * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). + */ +#ifndef SYS_STATS +#define SYS_STATS (NO_SYS == 0) +#endif + +/** + * IP6_STATS==1: Enable IPv6 stats. + */ +#ifndef IP6_STATS +#define IP6_STATS (LWIP_IPV6) +#endif + +/** + * ICMP6_STATS==1: Enable ICMP for IPv6 stats. + */ +#ifndef ICMP6_STATS +#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) +#endif + +/** + * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. + */ +#ifndef IP6_FRAG_STATS +#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) +#endif + +/** + * MLD6_STATS==1: Enable MLD for IPv6 stats. + */ +#ifndef MLD6_STATS +#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) +#endif + +/** + * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. + */ +#ifndef ND6_STATS +#define ND6_STATS (LWIP_IPV6) +#endif + +#else + +#define LINK_STATS 0 +#define ETHARP_STATS 0 +#define IP_STATS 0 +#define IPFRAG_STATS 0 +#define ICMP_STATS 0 +#define IGMP_STATS 0 +#define UDP_STATS 0 +#define TCP_STATS 0 +#define MEM_STATS 0 +#define MEMP_STATS 0 +#define SYS_STATS 0 +#define LWIP_STATS_DISPLAY 0 +#define IP6_STATS 0 +#define ICMP6_STATS 0 +#define IP6_FRAG_STATS 0 +#define MLD6_STATS 0 +#define ND6_STATS 0 + +#endif /* LWIP_STATS */ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ +/** + * PPP_SUPPORT==1: Enable PPP. + */ +#ifndef PPP_SUPPORT +#define PPP_SUPPORT 0 +#endif + +/** + * PPPOE_SUPPORT==1: Enable PPP Over Ethernet + */ +#ifndef PPPOE_SUPPORT +#define PPPOE_SUPPORT 0 +#endif + +/** + * PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP + */ +#ifndef PPPOL2TP_SUPPORT +#define PPPOL2TP_SUPPORT 0 +#endif + +/** + * PPPOL2TP_AUTH_SUPPORT==1: Enable PPP Over L2TP Auth (enable MD5 support) + */ +#ifndef PPPOL2TP_AUTH_SUPPORT +#define PPPOL2TP_AUTH_SUPPORT PPPOL2TP_SUPPORT +#endif + +/** + * PPPOS_SUPPORT==1: Enable PPP Over Serial + */ +#ifndef PPPOS_SUPPORT +#define PPPOS_SUPPORT PPP_SUPPORT +#endif + +/** + * LWIP_PPP_API==1: Enable PPP API (in pppapi.c) + */ +#ifndef LWIP_PPP_API +#define LWIP_PPP_API 0 +#endif + +#if PPP_SUPPORT + +/** + * PPP_INPROC_MULTITHREADED==1 call ppp_input() using tcpip_callback(). + * Set this to 0 if pppos_input() is called inside tcpip_thread or with NO_SYS==1. + * Default is 1 for NO_SYS==0 (multithreaded) and 0 for NO_SYS==1 (single-threaded). + */ +#ifndef PPP_INPROC_MULTITHREADED +#define PPP_INPROC_MULTITHREADED (NO_SYS==0) +#endif + +/** + * PRINTPKT_SUPPORT==1: Enable PPP print packet support + * + * Mandatory for debugging, it displays exchanged packet content in debug trace. + */ +#ifndef PRINTPKT_SUPPORT +#define PRINTPKT_SUPPORT 0 +#endif + +/** + * PPP_IPV6_SUPPORT==1: Enable PPP IPv6 support + */ +#ifndef PPP_IPV6_SUPPORT +#define PPP_IPV6_SUPPORT 0 +#endif + +/** + * PPP_NOTIFY_PHASE==1: Support PPP notify phase support + * + * PPP notify phase support allows you to set a callback which is + * called on change of the internal PPP state machine. + * + * This can be used for example to set a LED pattern depending on the + * current phase of the PPP session. + */ +#ifndef PPP_NOTIFY_PHASE +#define PPP_NOTIFY_PHASE 0 +#endif + +/** + * pbuf_type PPP is using for LCP, PAP, CHAP, EAP, IPCP and IP6CP packets. + * + * Memory allocated must be single buffered for PPP to works, it requires pbuf + * that are not going to be chained when allocated. This requires setting + * PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems. + * + * Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous + * buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE. + */ +#ifndef PPP_USE_PBUF_RAM +#define PPP_USE_PBUF_RAM 0 +#endif + +/** + * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation + */ +#ifndef PPP_FCS_TABLE +#define PPP_FCS_TABLE 1 +#endif + +/** + * PAP_SUPPORT==1: Support PAP. + */ +#ifndef PAP_SUPPORT +#define PAP_SUPPORT 0 +#endif + +/** + * CHAP_SUPPORT==1: Support CHAP. + */ +#ifndef CHAP_SUPPORT +#define CHAP_SUPPORT 0 +#endif + +/** + * MSCHAP_SUPPORT==1: Support MSCHAP. + */ +#ifndef MSCHAP_SUPPORT +#define MSCHAP_SUPPORT 0 +#endif +#if MSCHAP_SUPPORT +#undef CHAP_SUPPORT +#define CHAP_SUPPORT 1 /* MSCHAP requires CHAP support */ +#endif /* MSCHAP_SUPPORT */ + +/** + * EAP_SUPPORT==1: Support EAP. + */ +#ifndef EAP_SUPPORT +#define EAP_SUPPORT 0 +#endif + +/** + * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CBCP_SUPPORT +#define CBCP_SUPPORT 0 +#endif + +/** + * CCP_SUPPORT==1: Support CCP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef CCP_SUPPORT +#define CCP_SUPPORT 0 +#endif + +/** + * ECP_SUPPORT==1: Support ECP. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef ECP_SUPPORT +#define ECP_SUPPORT 0 +#endif + +/** + * DEMAND_SUPPORT==1: Support dial on demand. CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef DEMAND_SUPPORT +#define DEMAND_SUPPORT 0 +#endif + +/** + * LQR_SUPPORT==1: Support Link Quality Report. Do nothing except exchanging some LCP packets. + */ +#ifndef LQR_SUPPORT +#define LQR_SUPPORT 0 +#endif + +/** + * PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session). CURRENTLY NOT SUPPORTED! DO NOT SET! + */ +#ifndef PPP_SERVER +#define PPP_SERVER 0 +#endif + +/** + * VJ_SUPPORT==1: Support VJ header compression. + */ +#ifndef VJ_SUPPORT +#define VJ_SUPPORT 1 +#endif +#if !PPPOS_SUPPORT +#undef VJ_SUPPORT +#define VJ_SUPPORT 0 /* Only PPPoS may need VJ compression */ +#endif /* !PPPOS_SUPPORT */ + +/** + * PPP_MD5_RANDM==1: Use MD5 for better randomness. Automatically enabled if CHAP or L2TP AUTH support is enabled. + */ +#ifndef PPP_MD5_RANDM +#define PPP_MD5_RANDM 0 +#endif +#if CHAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT +#undef PPP_MD5_RANDM +#define PPP_MD5_RANDM 1 /* MD5 Random is required for CHAP and L2TP AUTH */ +#endif /* CHAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT */ + +/** + * PolarSSL library, used if necessary and not previously disabled + * + * + * lwIP contains some files fetched from the latest BSD release of + * the PolarSSL project for ciphers and encryption methods we need for lwIP + * PPP support. + * + * The PolarSSL files were cleaned to contain only the necessary struct + * fields and functions needed for lwIP. + * + * The PolarSSL API was not changed at all, so if you are already using + * PolarSSL you can choose to skip the compilation of the included PolarSSL + * library into lwIP: + * + * The following defines are available for flexibility: + * + * LWIP_INCLUDED_POLARSSL_MD4 ; Use lwIP internal PolarSSL for MD4 + * LWIP_INCLUDED_POLARSSL_MD5 ; Use lwIP internal PolarSSL for MD5 + * LWIP_INCLUDED_POLARSSL_SHA1 ; Use lwIP internal PolarSSL for SHA1 + * LWIP_INCLUDED_POLARSSL_DES ; Use lwIP internal PolarSSL for DES + * + * If set (=1), the default if required by another enabled PPP feature unless + * explicitly set to 0, using included lwIP PolarSSL. + * + * If clear (=0), using external PolarSSL. + * + * Undefined if not needed. + * + * Beware of the stack requirements which can be a lot larger if you are not + * using our cleaned PolarSSL library. + */ + +#if CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM +#ifndef LWIP_INCLUDED_POLARSSL_MD5 +#define LWIP_INCLUDED_POLARSSL_MD5 1 /* CHAP, EAP, L2TP AUTH and MD5 Random require MD5 support */ +#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ +#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM */ + +#if MSCHAP_SUPPORT +#ifndef LWIP_INCLUDED_POLARSSL_MD4 +#define LWIP_INCLUDED_POLARSSL_MD4 1 /* MSCHAP require MD4 support */ +#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ +#ifndef LWIP_INCLUDED_POLARSSL_SHA1 +#define LWIP_INCLUDED_POLARSSL_SHA1 1 /* MSCHAP require SHA1 support */ +#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ +#ifndef LWIP_INCLUDED_POLARSSL_DES +#define LWIP_INCLUDED_POLARSSL_DES 1 /* MSCHAP require DES support */ +#endif /* LWIP_INCLUDED_POLARSSL_DES */ +#endif /* MSCHAP_SUPPORT */ + +/* + * Timeouts + */ +#ifndef FSM_DEFTIMEOUT +#define FSM_DEFTIMEOUT 6 /* Timeout time in seconds */ +#endif + +#ifndef FSM_DEFMAXTERMREQS +#define FSM_DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXCONFREQS +#define FSM_DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#endif + +#ifndef FSM_DEFMAXNAKLOOPS +#define FSM_DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif + +#ifndef UPAP_DEFTIMEOUT +#define UPAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef UPAP_DEFTRANSMITS +#define UPAP_DEFTRANSMITS 10 /* Maximum number of auth-reqs to send */ +#endif + +#if PPP_SERVER +#ifndef UPAP_DEFREQTIME +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif +#endif /* PPP_SERVER */ + +#ifndef CHAP_DEFTIMEOUT +#define CHAP_DEFTIMEOUT 6 /* Timeout (seconds) for retransmitting req */ +#endif + +#ifndef CHAP_DEFTRANSMITS +#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */ +#endif + +#if PPP_SERVER +#ifndef CHAP_DEFREQTIME +#define CHAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif +#endif /* PPP_SERVER */ + +#ifndef EAP_DEFREQTIME +#define EAP_DEFREQTIME 6 /* Time to wait for peer request */ +#endif + +#ifndef EAP_DEFALLOWREQ +#define EAP_DEFALLOWREQ 10 /* max # times to accept requests */ +#endif + +#if PPP_SERVER +#ifndef EAP_DEFTIMEOUT +#define EAP_DEFTIMEOUT 6 /* Timeout (seconds) for rexmit */ +#endif + +#ifndef EAP_DEFTRANSMITS +#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ +#endif +#endif /* PPP_SERVER */ + +/* Default number of times we receive our magic number from the peer + before deciding the link is looped-back. */ +#ifndef LCP_DEFLOOPBACKFAIL +#define LCP_DEFLOOPBACKFAIL 10 +#endif + +/* Interval in seconds between keepalive echo requests, 0 to disable. */ +#ifndef LCP_ECHOINTERVAL +#define LCP_ECHOINTERVAL 0 +#endif + +/* Number of unanswered echo requests before failure. */ +#ifndef LCP_MAXECHOFAILS +#define LCP_MAXECHOFAILS 3 +#endif + +/* Max Xmit idle time (in jiffies) before resend flag char. */ +#ifndef PPP_MAXIDLEFLAG +#define PPP_MAXIDLEFLAG 100 +#endif + +/* + * Packet sizes + * + * Note - lcp shouldn't be allowed to negotiate stuff outside these + * limits. See lcp.h in the pppd directory. + * (XXX - these constants should simply be shared by lcp.c instead + * of living in lcp.h) + */ +#define PPP_MTU 1500 /* Default MTU (size of Info field) */ +#ifndef PPP_MAXMTU +/* #define PPP_MAXMTU 65535 - (PPP_HDRLEN + PPP_FCSLEN) */ +#define PPP_MAXMTU 1500 /* Largest MTU we allow */ +#endif +#define PPP_MINMTU 64 +#define PPP_MRU 1500 /* default MRU = max length of info field */ +#define PPP_MAXMRU 1500 /* Largest MRU we allow */ +#ifndef PPP_DEFMRU +#define PPP_DEFMRU 296 /* Try for this */ +#endif +#define PPP_MINMRU 128 /* No MRUs below this */ + +#ifndef MAXNAMELEN +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#endif +#ifndef MAXSECRETLEN +#define MAXSECRETLEN 256 /* max length of password or secret */ +#endif + +#endif /* PPP_SUPPORT */ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ +/** + * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. + */ +#ifndef CHECKSUM_GEN_IP +#define CHECKSUM_GEN_IP 1 +#endif + +/** + * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. + */ +#ifndef CHECKSUM_GEN_UDP +#define CHECKSUM_GEN_UDP 1 +#endif + +/** + * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. + */ +#ifndef CHECKSUM_GEN_TCP +#define CHECKSUM_GEN_TCP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. + */ +#ifndef CHECKSUM_GEN_ICMP +#define CHECKSUM_GEN_ICMP 1 +#endif + +/** + * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets. + */ +#ifndef CHECKSUM_GEN_ICMP6 +#define CHECKSUM_GEN_ICMP6 1 +#endif + +/** + * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. + */ +#ifndef CHECKSUM_CHECK_IP +#define CHECKSUM_CHECK_IP 1 +#endif + +/** + * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. + */ +#ifndef CHECKSUM_CHECK_UDP +#define CHECKSUM_CHECK_UDP 1 +#endif + +/** + * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. + */ +#ifndef CHECKSUM_CHECK_TCP +#define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets. + */ +#ifndef CHECKSUM_CHECK_ICMP +#define CHECKSUM_CHECK_ICMP 1 +#endif + +/** + * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets + */ +#ifndef CHECKSUM_CHECK_ICMP6 +#define CHECKSUM_CHECK_ICMP6 1 +#endif + +/** + * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from + * application buffers to pbufs. + */ +#ifndef LWIP_CHECKSUM_ON_COPY +#define LWIP_CHECKSUM_ON_COPY 0 +#endif + +/* + --------------------------------------- + ---------- IPv6 options --------------- + --------------------------------------- +*/ +/** + * LWIP_IPV6==1: Enable IPv6 + */ +#ifndef LWIP_IPV6 +#define LWIP_IPV6 0 +#endif + +/** + * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. + */ +#ifndef LWIP_IPV6_NUM_ADDRESSES +#define LWIP_IPV6_NUM_ADDRESSES 3 +#endif + +/** + * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs + */ +#ifndef LWIP_IPV6_FORWARD +#define LWIP_IPV6_FORWARD 0 +#endif + +/** + * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) + */ +#ifndef LWIP_ICMP6 +#define LWIP_ICMP6 (LWIP_IPV6) +#endif + +/** + * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in + * ICMPv6 error messages. + */ +#ifndef LWIP_ICMP6_DATASIZE +#define LWIP_ICMP6_DATASIZE 8 +#endif + +/** + * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages + */ +#ifndef LWIP_ICMP6_HL +#define LWIP_ICMP6_HL 255 +#endif + +/** + * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. + */ +#ifndef LWIP_IPV6_MLD +#define LWIP_IPV6_MLD (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast that can be joined. + */ +#ifndef MEMP_NUM_MLD6_GROUP +#define MEMP_NUM_MLD6_GROUP 4 +#endif + +/** + * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. + */ +#ifndef LWIP_IPV6_FRAG +#define LWIP_IPV6_FRAG 0 +#endif + +/** + * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented + */ +#ifndef LWIP_IPV6_REASS +#define LWIP_IPV6_REASS (LWIP_IPV6) +#endif + +/** + * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address + * is being resolved. + */ +#ifndef LWIP_ND6_QUEUEING +#define LWIP_ND6_QUEUEING (LWIP_IPV6) +#endif + +/** + * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. + */ +#ifndef MEMP_NUM_ND6_QUEUE +#define MEMP_NUM_ND6_QUEUE 20 +#endif + +/** + * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache + */ +#ifndef LWIP_ND6_NUM_NEIGHBORS +#define LWIP_ND6_NUM_NEIGHBORS 10 +#endif + +/** + * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache + */ +#ifndef LWIP_ND6_NUM_DESTINATIONS +#define LWIP_ND6_NUM_DESTINATIONS 10 +#endif + +/** + * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache + */ +#ifndef LWIP_ND6_NUM_PREFIXES +#define LWIP_ND6_NUM_PREFIXES 5 +#endif + +/** + * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache + */ +#ifndef LWIP_ND6_NUM_ROUTERS +#define LWIP_ND6_NUM_ROUTERS 3 +#endif + +/** + * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send + * (neighbor solicit and router solicit) + */ +#ifndef LWIP_ND6_MAX_MULTICAST_SOLICIT +#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 +#endif + +/** + * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages + * to send during neighbor reachability detection. + */ +#ifndef LWIP_ND6_MAX_UNICAST_SOLICIT +#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 +#endif + +/** + * Unused: See ND RFC (time in milliseconds). + */ +#ifndef LWIP_ND6_MAX_ANYCAST_DELAY_TIME +#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 +#endif + +/** + * Unused: See ND RFC + */ +#ifndef LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT +#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 +#endif + +/** + * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). + * May be updated by router advertisement messages. + */ +#ifndef LWIP_ND6_REACHABLE_TIME +#define LWIP_ND6_REACHABLE_TIME 30000 +#endif + +/** + * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages + */ +#ifndef LWIP_ND6_RETRANS_TIMER +#define LWIP_ND6_RETRANS_TIMER 1000 +#endif + +/** + * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation + * message is sent, during neighbor reachability detection. + */ +#ifndef LWIP_ND6_DELAY_FIRST_PROBE_TIME +#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 +#endif + +/** + * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update + * Reachable time and retransmission timers, and netif MTU. + */ +#ifndef LWIP_ND6_ALLOW_RA_UPDATES +#define LWIP_ND6_ALLOW_RA_UPDATES 1 +#endif + +/** + * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during + * network startup. + */ +#ifndef LWIP_IPV6_SEND_ROUTER_SOLICIT +#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 +#endif + +/** + * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery + * with reachability hints for connected destinations. This helps avoid sending + * unicast neighbor solicitation messages. + */ +#ifndef LWIP_ND6_TCP_REACHABILITY_HINTS +#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 +#endif + +/** + * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. + */ +#ifndef LWIP_IPV6_AUTOCONFIG +#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) +#endif + +/** + * LWIP_IPV6_DUP_DETECT_ATTEMPTS: Number of duplicate address detection attempts. + */ +#ifndef LWIP_IPV6_DUP_DETECT_ATTEMPTS +#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 +#endif + +/** + * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. + */ +#ifndef LWIP_IPV6_DHCP6 +#define LWIP_IPV6_DHCP6 0 +#endif + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* Hooks are undefined by default, define them to a function if you need them. */ + +/** + * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): + * - called from ip_input() (IPv4) + * - pbuf: received struct pbuf passed to ip_input() + * - input_netif: struct netif on which the packet has been received + * Return values: + * - 0: Hook has not consumed the packet, packet is processed as normal + * - != 0: Hook has consumed the packet. + * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook + * (i.e. free it when done). + */ + +/** + * LWIP_HOOK_IP4_ROUTE(dest): + * - called from ip_route() (IPv4) + * - dest: destination IPv4 address + * Returns the destination netif or NULL if no destination netif is found. In + * that case, ip_route() continues as normal. + */ + +/** + * LWIP_HOOK_ETHARP_GET_GW(netif, dest): + * - called from etharp_output() (IPv4) + * - netif: the netif used for sending + * - dest: the destination IPv4 address + * Returns the IPv4 address of the gateway to handle the specified destination + * IPv4 address. If NULL is returned, the netif's default gateway is used. + * The returned address MUST be reachable on the specified netif! + * This function is meant to implement advanced IPv4 routing together with + * LWIP_HOOK_IP4_ROUTE(). The actual routing/gateway table implementation is + * not part of lwIP but can e.g. be hidden in the netif's state argument. +*/ + +/** + * LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr): + * - called from ethernet_input() if VLAN support is enabled + * - netif: struct netif on which the packet has been received + * - eth_hdr: struct eth_hdr of the packet + * - vlan_hdr: struct eth_vlan_hdr of the packet + * Return values: + * - 0: Packet must be dropped. + * - != 0: Packet must be accepted. + */ + +/** + * LWIP_HOOK_VLAN_SET(netif, eth_hdr, vlan_hdr): + * - called from etharp_raw() and etharp_send_ip() if VLAN support is enabled + * - netif: struct netif that the packet will be sent through + * - eth_hdr: struct eth_hdr of the packet + * - vlan_hdr: struct eth_vlan_hdr of the packet + * Return values: + * - 0: Packet shall not contain VLAN header. + * - != 0: Packet shall contain VLAN header. + * Hook can be used to set prio_vid field of vlan_hdr. + */ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is + * compared against this value. If it is smaller, then debugging + * messages are written. + */ +#ifndef LWIP_DBG_MIN_LEVEL +#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL +#endif + +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + */ +#ifndef LWIP_DBG_TYPES_ON +#define LWIP_DBG_TYPES_ON LWIP_DBG_ON +#endif + +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#ifndef ETHARP_DEBUG +#define ETHARP_DEBUG LWIP_DBG_OFF +#endif + +/** + * NETIF_DEBUG: Enable debugging in netif.c. + */ +#ifndef NETIF_DEBUG +#define NETIF_DEBUG LWIP_DBG_OFF +#endif + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#ifndef PBUF_DEBUG +#define PBUF_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#ifndef API_LIB_DEBUG +#define API_LIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * API_MSG_DEBUG: Enable debugging in api_msg.c. + */ +#ifndef API_MSG_DEBUG +#define API_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#ifndef SOCKETS_DEBUG +#define SOCKETS_DEBUG LWIP_DBG_OFF +#endif + +/** + * ICMP_DEBUG: Enable debugging in icmp.c. + */ +#ifndef ICMP_DEBUG +#define ICMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IGMP_DEBUG: Enable debugging in igmp.c. + */ +#ifndef IGMP_DEBUG +#define IGMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * INET_DEBUG: Enable debugging in inet.c. + */ +#ifndef INET_DEBUG +#define INET_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#ifndef IP_DEBUG +#define IP_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. + */ +#ifndef IP_REASS_DEBUG +#define IP_REASS_DEBUG LWIP_DBG_OFF +#endif + +/** + * RAW_DEBUG: Enable debugging in raw.c. + */ +#ifndef RAW_DEBUG +#define RAW_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEM_DEBUG: Enable debugging in mem.c. + */ +#ifndef MEM_DEBUG +#define MEM_DEBUG LWIP_DBG_OFF +#endif + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#ifndef MEMP_DEBUG +#define MEMP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SYS_DEBUG: Enable debugging in sys.c. + */ +#ifndef SYS_DEBUG +#define SYS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TIMERS_DEBUG: Enable debugging in timers.c. + */ +#ifndef TIMERS_DEBUG +#define TIMERS_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_DEBUG: Enable debugging for TCP. + */ +#ifndef TCP_DEBUG +#define TCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#ifndef TCP_INPUT_DEBUG +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. + */ +#ifndef TCP_FR_DEBUG +#define TCP_FR_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit + * timeout. + */ +#ifndef TCP_RTO_DEBUG +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. + */ +#ifndef TCP_CWND_DEBUG +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. + */ +#ifndef TCP_WND_DEBUG +#define TCP_WND_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#ifndef TCP_OUTPUT_DEBUG +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. + */ +#ifndef TCP_RST_DEBUG +#define TCP_RST_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. + */ +#ifndef TCP_QLEN_DEBUG +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#endif + +/** + * UDP_DEBUG: Enable debugging in UDP. + */ +#ifndef UDP_DEBUG +#define UDP_DEBUG LWIP_DBG_OFF +#endif + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#ifndef TCPIP_DEBUG +#define TCPIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * PPP_DEBUG: Enable debugging for PPP. + */ +#ifndef PPP_DEBUG +#define PPP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SLIP_DEBUG: Enable debugging in slipif.c. + */ +#ifndef SLIP_DEBUG +#define SLIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#ifndef DHCP_DEBUG +#define DHCP_DEBUG LWIP_DBG_OFF +#endif + +/** + * AUTOIP_DEBUG: Enable debugging in autoip.c. + */ +#ifndef AUTOIP_DEBUG +#define AUTOIP_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MSG_DEBUG: Enable debugging for SNMP messages. + */ +#ifndef SNMP_MSG_DEBUG +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#endif + +/** + * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. + */ +#ifndef SNMP_MIB_DEBUG +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#endif + +/** + * DNS_DEBUG: Enable debugging for DNS. + */ +#ifndef DNS_DEBUG +#define DNS_DEBUG LWIP_DBG_OFF +#endif + +/** + * IP6_DEBUG: Enable debugging for IPv6. + */ +#ifndef IP6_DEBUG +#define IP6_DEBUG LWIP_DBG_OFF +#endif + +#endif /* LWIP_HDR_OPT_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pbuf.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pbuf.h new file mode 100644 index 0000000..6bd6b30 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pbuf.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef LWIP_HDR_PBUF_H +#define LWIP_HDR_PBUF_H + +#include "lwip/opt.h" +#include "lwip/err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Currently, the pbuf_custom code is only needed for one specific configuration + * of IP_FRAG */ +#ifndef LWIP_SUPPORT_CUSTOM_PBUF +#define LWIP_SUPPORT_CUSTOM_PBUF (IP_FRAG && !IP_FRAG_USES_STATIC_BUF && !LWIP_NETIF_TX_SINGLE_PBUF) +#endif + +/* @todo: We need a mechanism to prevent wasting memory in every pbuf + (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ + +#define PBUF_TRANSPORT_HLEN 20 +#if LWIP_IPV6 +#define PBUF_IP_HLEN 40 +#else +#define PBUF_IP_HLEN 20 +#endif + +typedef enum { + PBUF_TRANSPORT, + PBUF_IP, + PBUF_LINK, + PBUF_RAW +} pbuf_layer; + +typedef enum { + PBUF_RAM, /* pbuf data is stored in RAM */ + PBUF_ROM, /* pbuf data is stored in ROM */ + PBUF_REF, /* pbuf comes from the pbuf pool */ + PBUF_POOL /* pbuf payload refers to RAM */ +} pbuf_type; + + +/** indicates this packet's data should be immediately passed to the application */ +#define PBUF_FLAG_PUSH 0x01U +/** indicates this is a custom pbuf: pbuf_free and pbuf_header handle such a + a pbuf differently */ +#define PBUF_FLAG_IS_CUSTOM 0x02U +/** indicates this pbuf is UDP multicast to be looped back */ +#define PBUF_FLAG_MCASTLOOP 0x04U +/** indicates this pbuf was received as link-level broadcast */ +#define PBUF_FLAG_LLBCAST 0x08U +/** indicates this pbuf was received as link-level multicast */ +#define PBUF_FLAG_LLMCAST 0x10U +/** indicates this pbuf includes a TCP FIN flag */ +#define PBUF_FLAG_TCP_FIN 0x20U + +struct pbuf { + /** next pbuf in singly linked pbuf chain */ + struct pbuf *next; + + /** pointer to the actual data in the buffer */ + void *payload; + + /** + * total length of this buffer and all next buffers in chain + * belonging to the same packet. + * + * For non-queue packet chains this is the invariant: + * p->tot_len == p->len + (p->next? p->next->tot_len: 0) + */ + u16_t tot_len; + + /** length of this buffer */ + u16_t len; + + /** pbuf_type as u8_t instead of enum to save space */ + u8_t /*pbuf_type*/ type; + + /** misc flags */ + u8_t flags; + + /** + * the reference count always equals the number of pointers + * that refer to this pbuf. This can be pointers from an application, + * the stack itself, or pbuf->next pointers from a chain. + */ + u16_t ref; +}; + +#if LWIP_SUPPORT_CUSTOM_PBUF +/** Prototype for a function to free a custom pbuf */ +typedef void (*pbuf_free_custom_fn)(struct pbuf *p); + +/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ +struct pbuf_custom { + /** The actual pbuf */ + struct pbuf pbuf; + /** This function is called when pbuf_free deallocates this pbuf(_custom) */ + pbuf_free_custom_fn custom_free_function; +}; +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ + +#if LWIP_TCP && TCP_QUEUE_OOSEQ +/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ +#ifndef PBUF_POOL_FREE_OOSEQ +#define PBUF_POOL_FREE_OOSEQ 1 +#endif /* PBUF_POOL_FREE_OOSEQ */ +#if NO_SYS && PBUF_POOL_FREE_OOSEQ +extern volatile u8_t pbuf_free_ooseq_pending; +void pbuf_free_ooseq(void); +/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() + at regular intervals from main level to check if ooseq pbufs need to be + freed! */ +#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ + /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ + ooseq queued pbufs now */ \ + pbuf_free_ooseq(); }}while(0) +#endif /* NO_SYS && PBUF_POOL_FREE_OOSEQ*/ +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ */ + +/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ +#define pbuf_init() + +struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); +#if LWIP_SUPPORT_CUSTOM_PBUF +struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, + struct pbuf_custom *p, void *payload_mem, + u16_t payload_mem_len); +#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ +void pbuf_realloc(struct pbuf *p, u16_t size); +u8_t pbuf_header(struct pbuf *p, s16_t header_size); +u8_t pbuf_header_force(struct pbuf *p, s16_t header_size); +void pbuf_ref(struct pbuf *p); +u8_t pbuf_free(struct pbuf *p); +u8_t pbuf_clen(struct pbuf *p); +void pbuf_cat(struct pbuf *head, struct pbuf *tail); +void pbuf_chain(struct pbuf *head, struct pbuf *tail); +struct pbuf *pbuf_dechain(struct pbuf *p); +err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from); +u16_t pbuf_copy_partial(struct pbuf *p, void *dataptr, u16_t len, u16_t offset); +err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); +err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset); +struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); +#if LWIP_CHECKSUM_ON_COPY +err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, + u16_t len, u16_t *chksum); +#endif /* LWIP_CHECKSUM_ON_COPY */ +#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE +void pbuf_split_64k(struct pbuf *p, struct pbuf **rest); +#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ + +u8_t pbuf_get_at(struct pbuf* p, u16_t offset); +void pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data); +u16_t pbuf_memcmp(struct pbuf* p, u16_t offset, const void* s2, u16_t n); +u16_t pbuf_memfind(struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); +u16_t pbuf_strstr(struct pbuf* p, const char* substr); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_PBUF_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pppapi.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pppapi.h new file mode 100644 index 0000000..dd24af5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/pppapi.h @@ -0,0 +1,151 @@ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#ifndef __LWIP_PPPAPI_H__ +#define __LWIP_PPPAPI_H__ + +#include "lwip/opt.h" + +#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/sys.h" +#include "netif/ppp/ppp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pppapi_msg_msg { +#if !LWIP_TCPIP_CORE_LOCKING + sys_sem_t sem; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + int err; + ppp_pcb *ppp; + union { + struct { + u8_t authtype; + const char *user; + const char *passwd; + } setauth; +#if PPP_NOTIFY_PHASE + struct { + ppp_notify_phase_cb_fn notify_phase_cb; + } setnotifyphasecb; +#endif /* PPP_NOTIFY_PHASE */ +#if PPPOS_SUPPORT + struct { + sio_fd_t fd; + ppp_link_status_cb_fn link_status_cb; + void *ctx_cb; + } serialcreate; +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT + struct { + struct netif *ethif; + const char *service_name; + const char *concentrator_name; + ppp_link_status_cb_fn link_status_cb; + void *ctx_cb; + } ethernetcreate; +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + struct { + struct netif *netif; + ip_addr_t *ipaddr; + u16_t port; +#if PPPOL2TP_AUTH_SUPPORT + u8_t *secret; + u8_t secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + ppp_link_status_cb_fn link_status_cb; + void *ctx_cb; + } l2tpcreate; +#endif /* PPPOL2TP_SUPPORT */ + struct { + u16_t holdoff; + } open; + struct { + int cmd; + void *arg; + } ioctl; +#if LWIP_NETIF_STATUS_CALLBACK + struct { + netif_status_callback_fn status_callback; + } netifstatuscallback; +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK + struct { + netif_status_callback_fn link_callback; + } netiflinkcallback; +#endif /* LWIP_NETIF_LINK_CALLBACK */ + } msg; +}; + +struct pppapi_msg { + void (* function)(struct pppapi_msg_msg *msg); + struct pppapi_msg_msg msg; +}; + +/* API for application */ +ppp_pcb *pppapi_new(void); +void pppapi_set_default(ppp_pcb *pcb); +void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); +#if PPP_NOTIFY_PHASE +void pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); +#endif /* PPP_NOTIFY_PHASE */ +#if PPPOS_SUPPORT +int pppapi_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT +int pppapi_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, + const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, + void *ctx_cb); +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +int pppapi_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); +#endif /* PPPOL2TP_SUPPORT */ +int pppapi_open(ppp_pcb *pcb, u16_t holdoff); +int pppapi_close(ppp_pcb *pcb); +void pppapi_sighup(ppp_pcb *pcb); +int pppapi_delete(ppp_pcb *pcb); +int pppapi_ioctl(ppp_pcb *pcb, int cmd, void *arg); +#if LWIP_NETIF_STATUS_CALLBACK +void pppapi_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK +void pppapi_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_PPP_API */ + +#endif /* __LWIP_PPPAPI_H__ */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/raw.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/raw.h new file mode 100644 index 0000000..52964f5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/raw.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_RAW_H +#define LWIP_HDR_RAW_H + +#include "lwip/opt.h" + +#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/def.h" +#include "lwip/lwip_ip.h" +#include "lwip/ip_addr.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct raw_pcb; + +/** Function prototype for raw pcb receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip_addr_t *addr); + +#if LWIP_IPV6 +/** Function prototype for raw pcb IPv6 receive callback functions. + * @param arg user supplied argument (raw_pcb.recv_arg) + * @param pcb the raw_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IPv6 address from which the packet was received + * @return 1 if the packet was 'eaten' (aka. deleted), + * 0 if the packet lives on + * If returning 1, the callback is responsible for freeing the pbuf + * if it's not used any more. + */ +typedef u8_t (*raw_recv_ip6_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, + ip6_addr_t *addr); +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV6 +#define RAW_PCB_RECV_IP6 raw_recv_ip6_fn ip6; +#else +#define RAW_PCB_RECV_IP6 +#endif /* LWIP_IPV6 */ + +struct raw_pcb { + /* Common members of all PCB types */ + IP_PCB; + + struct raw_pcb *next; + + u8_t protocol; + + /** receive callback function */ + union { + raw_recv_fn ip4; + RAW_PCB_RECV_IP6 + } recv; + /* user-supplied argument for the recv callback */ + void *recv_arg; +#if LWIP_IPV6 + /* fields for handling checksum computations as per RFC3542. */ + u16_t chksum_offset; + u8_t chksum_reqd; +#endif +}; + +/* The following functions is the application layer interface to the + RAW code. */ +struct raw_pcb * raw_new (u8_t proto); +void raw_remove (struct raw_pcb *pcb); +err_t raw_bind (struct raw_pcb *pcb, ip_addr_t *ipaddr); +err_t raw_connect (struct raw_pcb *pcb, ip_addr_t *ipaddr); + +void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); +err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr); +err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); + +#if LWIP_IPV6 +struct raw_pcb * raw_new_ip6 (u8_t proto); +#define raw_bind_ip6(pcb, ip6addr) raw_bind(pcb, ip6_2_ip(ip6addr)) +#define raw_connect_ip6(pcb, ip6addr) raw_connect(pcb, ip6_2_ip(ip6addr)) +#define raw_recv_ip6(pcb, recv_ip6_fn, recv_arg) raw_recv(pcb, (raw_recv_fn)recv_ip6_fn, recv_arg) +#define raw_sendto_ip6(pcb, pbuf, ip6addr) raw_sendto(pcb, pbuf, ip6_2_ip(ip6addr)) +#endif /* LWIP_IPV6 */ + +/* The following functions are the lower layer interface to RAW. */ +u8_t raw_input (struct pbuf *p, struct netif *inp); +#define raw_init() /* Compatibility define, no init needed. */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_RAW */ + +#endif /* LWIP_HDR_RAW_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sio.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sio.h new file mode 100644 index 0000000..23d116b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sio.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + */ + +/* + * This is the interface to the platform specific serial IO module + * It needs to be implemented by those platforms which need SLIP or PPP + */ + +#ifndef SIO_H +#define SIO_H + +#include "lwip/arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If you want to define sio_fd_t elsewhere or differently, + define this in your cc.h file. */ +#ifndef __sio_fd_t_defined +typedef void * sio_fd_t; +#endif + +/* The following functions can be defined to something else in your cc.h file + or be implemented in your custom sio.c file. */ + +#ifndef sio_open +/** + * Opens a serial device for communication. + * + * @param devnum device number + * @return handle to serial device if successful, NULL otherwise + */ +sio_fd_t sio_open(u8_t devnum); +#endif + +#ifndef sio_send +/** + * Sends a single character to the serial device. + * + * @param c character to send + * @param fd serial device handle + * + * @note This function will block until the character can be sent. + */ +void sio_send(u8_t c, sio_fd_t fd); +#endif + +#ifndef sio_recv +/** + * Receives a single character from the serial device. + * + * @param fd serial device handle + * + * @note This function will block until a character is received. + */ +u8_t sio_recv(sio_fd_t fd); +#endif + +#ifndef sio_read +/** + * Reads from the serial device. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * + * @note This function will block until data can be received. The blocking + * can be cancelled by calling sio_read_abort(). + */ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_tryread +/** + * Tries to read from the serial device. Same as sio_read but returns + * immediately if no data is available and never blocks. + * + * @param fd serial device handle + * @param data pointer to data buffer for receiving + * @param len maximum length (in bytes) of data to receive + * @return number of bytes actually received + */ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_write +/** + * Writes to the serial device. + * + * @param fd serial device handle + * @param data pointer to data to send + * @param len length (in bytes) of data to send + * @return number of bytes actually sent + * + * @note This function will block until all data can be sent. + */ +u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); +#endif + +#ifndef sio_read_abort +/** + * Aborts a blocking sio_read() call. + * + * @param fd serial device handle + */ +void sio_read_abort(sio_fd_t fd); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SIO_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp.h new file mode 100644 index 0000000..101bb66 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp.h @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2001, 2002 Leon Woestenberg + * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Leon Woestenberg + * + */ +#ifndef LWIP_HDR_SNMP_H +#define LWIP_HDR_SNMP_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip/ip_addr.h" + +struct udp_pcb; +struct netif; + +/** + * @see RFC1213, "MIB-II, 6. Definitions" + */ +enum snmp_ifType { + snmp_ifType_other=1, /* none of the following */ + snmp_ifType_regular1822, + snmp_ifType_hdh1822, + snmp_ifType_ddn_x25, + snmp_ifType_rfc877_x25, + snmp_ifType_ethernet_csmacd, + snmp_ifType_iso88023_csmacd, + snmp_ifType_iso88024_tokenBus, + snmp_ifType_iso88025_tokenRing, + snmp_ifType_iso88026_man, + snmp_ifType_starLan, + snmp_ifType_proteon_10Mbit, + snmp_ifType_proteon_80Mbit, + snmp_ifType_hyperchannel, + snmp_ifType_fddi, + snmp_ifType_lapb, + snmp_ifType_sdlc, + snmp_ifType_ds1, /* T-1 */ + snmp_ifType_e1, /* european equiv. of T-1 */ + snmp_ifType_basicISDN, + snmp_ifType_primaryISDN, /* proprietary serial */ + snmp_ifType_propPointToPointSerial, + snmp_ifType_ppp, + snmp_ifType_softwareLoopback, + snmp_ifType_eon, /* CLNP over IP [11] */ + snmp_ifType_ethernet_3Mbit, + snmp_ifType_nsip, /* XNS over IP */ + snmp_ifType_slip, /* generic SLIP */ + snmp_ifType_ultra, /* ULTRA technologies */ + snmp_ifType_ds3, /* T-3 */ + snmp_ifType_sip, /* SMDS */ + snmp_ifType_frame_relay +}; + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +/** SNMP "sysuptime" Interval */ +#define SNMP_SYSUPTIME_INTERVAL 10 + +/** fixed maximum length for object identifier type */ +#define LWIP_SNMP_OBJ_ID_LEN 32 + +/** internal object identifier representation */ +struct snmp_obj_id +{ + u8_t len; + s32_t id[LWIP_SNMP_OBJ_ID_LEN]; +}; + +/* system */ +void snmp_set_sysdescr(const u8_t* str, const u8_t* len); +void snmp_set_sysobjid(const struct snmp_obj_id *oid); +void snmp_get_sysobjid_ptr(const struct snmp_obj_id **oid); +void snmp_inc_sysuptime(void); +void snmp_add_sysuptime(u32_t value); +void snmp_get_sysuptime(u32_t *value); +void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen); +void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen); + +/* network interface */ +void snmp_add_ifinoctets(struct netif *ni, u32_t value); +void snmp_inc_ifinucastpkts(struct netif *ni); +void snmp_inc_ifinnucastpkts(struct netif *ni); +void snmp_inc_ifindiscards(struct netif *ni); +void snmp_add_ifoutoctets(struct netif *ni, u32_t value); +void snmp_inc_ifoutucastpkts(struct netif *ni); +void snmp_inc_ifoutnucastpkts(struct netif *ni); +void snmp_inc_ifoutdiscards(struct netif *ni); +void snmp_inc_iflist(void); +void snmp_dec_iflist(void); + +/* ARP (for atTable and ipNetToMediaTable) */ +void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip); +void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip); + +/* IP */ +void snmp_inc_ipinreceives(void); +void snmp_inc_ipinhdrerrors(void); +void snmp_inc_ipinaddrerrors(void); +void snmp_inc_ipforwdatagrams(void); +void snmp_inc_ipinunknownprotos(void); +void snmp_inc_ipindiscards(void); +void snmp_inc_ipindelivers(void); +void snmp_inc_ipoutrequests(void); +void snmp_inc_ipoutdiscards(void); +void snmp_inc_ipoutnoroutes(void); +void snmp_inc_ipreasmreqds(void); +void snmp_inc_ipreasmoks(void); +void snmp_inc_ipreasmfails(void); +void snmp_inc_ipfragoks(void); +void snmp_inc_ipfragfails(void); +void snmp_inc_ipfragcreates(void); +void snmp_inc_iproutingdiscards(void); +void snmp_insert_ipaddridx_tree(struct netif *ni); +void snmp_delete_ipaddridx_tree(struct netif *ni); +void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni); +void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni); + +/* ICMP */ +void snmp_inc_icmpinmsgs(void); +void snmp_inc_icmpinerrors(void); +void snmp_inc_icmpindestunreachs(void); +void snmp_inc_icmpintimeexcds(void); +void snmp_inc_icmpinparmprobs(void); +void snmp_inc_icmpinsrcquenchs(void); +void snmp_inc_icmpinredirects(void); +void snmp_inc_icmpinechos(void); +void snmp_inc_icmpinechoreps(void); +void snmp_inc_icmpintimestamps(void); +void snmp_inc_icmpintimestampreps(void); +void snmp_inc_icmpinaddrmasks(void); +void snmp_inc_icmpinaddrmaskreps(void); +void snmp_inc_icmpoutmsgs(void); +void snmp_inc_icmpouterrors(void); +void snmp_inc_icmpoutdestunreachs(void); +void snmp_inc_icmpouttimeexcds(void); +void snmp_inc_icmpoutparmprobs(void); +void snmp_inc_icmpoutsrcquenchs(void); +void snmp_inc_icmpoutredirects(void); +void snmp_inc_icmpoutechos(void); +void snmp_inc_icmpoutechoreps(void); +void snmp_inc_icmpouttimestamps(void); +void snmp_inc_icmpouttimestampreps(void); +void snmp_inc_icmpoutaddrmasks(void); +void snmp_inc_icmpoutaddrmaskreps(void); + +/* TCP */ +void snmp_inc_tcpactiveopens(void); +void snmp_inc_tcppassiveopens(void); +void snmp_inc_tcpattemptfails(void); +void snmp_inc_tcpestabresets(void); +void snmp_inc_tcpinsegs(void); +void snmp_inc_tcpoutsegs(void); +void snmp_inc_tcpretranssegs(void); +void snmp_inc_tcpinerrs(void); +void snmp_inc_tcpoutrsts(void); + +/* UDP */ +void snmp_inc_udpindatagrams(void); +void snmp_inc_udpnoports(void); +void snmp_inc_udpinerrors(void); +void snmp_inc_udpoutdatagrams(void); +void snmp_insert_udpidx_tree(struct udp_pcb *pcb); +void snmp_delete_udpidx_tree(struct udp_pcb *pcb); + +/* SNMP */ +void snmp_inc_snmpinpkts(void); +void snmp_inc_snmpoutpkts(void); +void snmp_inc_snmpinbadversions(void); +void snmp_inc_snmpinbadcommunitynames(void); +void snmp_inc_snmpinbadcommunityuses(void); +void snmp_inc_snmpinasnparseerrs(void); +void snmp_inc_snmpintoobigs(void); +void snmp_inc_snmpinnosuchnames(void); +void snmp_inc_snmpinbadvalues(void); +void snmp_inc_snmpinreadonlys(void); +void snmp_inc_snmpingenerrs(void); +void snmp_add_snmpintotalreqvars(u8_t value); +void snmp_add_snmpintotalsetvars(u8_t value); +void snmp_inc_snmpingetrequests(void); +void snmp_inc_snmpingetnexts(void); +void snmp_inc_snmpinsetrequests(void); +void snmp_inc_snmpingetresponses(void); +void snmp_inc_snmpintraps(void); +void snmp_inc_snmpouttoobigs(void); +void snmp_inc_snmpoutnosuchnames(void); +void snmp_inc_snmpoutbadvalues(void); +void snmp_inc_snmpoutgenerrs(void); +void snmp_inc_snmpoutgetrequests(void); +void snmp_inc_snmpoutgetnexts(void); +void snmp_inc_snmpoutsetrequests(void); +void snmp_inc_snmpoutgetresponses(void); +void snmp_inc_snmpouttraps(void); +void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid); +void snmp_set_snmpenableauthentraps(u8_t *value); +void snmp_get_snmpenableauthentraps(u8_t *value); + +/* LWIP_SNMP support not available */ +/* define everything to be empty */ +#else + +/* system */ +#define snmp_set_sysdescr(str, len) +#define snmp_set_sysobjid(oid); +#define snmp_get_sysobjid_ptr(oid) +#define snmp_inc_sysuptime() +#define snmp_add_sysuptime(value) +#define snmp_get_sysuptime(value) +#define snmp_set_syscontact(ocstr, ocstrlen); +#define snmp_set_sysname(ocstr, ocstrlen); +#define snmp_set_syslocation(ocstr, ocstrlen); + +/* network interface */ +#define snmp_add_ifinoctets(ni,value) +#define snmp_inc_ifinucastpkts(ni) +#define snmp_inc_ifinnucastpkts(ni) +#define snmp_inc_ifindiscards(ni) +#define snmp_add_ifoutoctets(ni,value) +#define snmp_inc_ifoutucastpkts(ni) +#define snmp_inc_ifoutnucastpkts(ni) +#define snmp_inc_ifoutdiscards(ni) +#define snmp_inc_iflist() +#define snmp_dec_iflist() + +/* ARP */ +#define snmp_insert_arpidx_tree(ni,ip) +#define snmp_delete_arpidx_tree(ni,ip) + +/* IP */ +#define snmp_inc_ipinreceives() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() +#define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#define snmp_inc_ipoutdiscards() +#define snmp_inc_ipoutnoroutes() +#define snmp_inc_ipreasmreqds() +#define snmp_inc_ipreasmoks() +#define snmp_inc_ipreasmfails() +#define snmp_inc_ipfragoks() +#define snmp_inc_ipfragfails() +#define snmp_inc_ipfragcreates() +#define snmp_inc_iproutingdiscards() +#define snmp_insert_ipaddridx_tree(ni) +#define snmp_delete_ipaddridx_tree(ni) +#define snmp_insert_iprteidx_tree(dflt, ni) +#define snmp_delete_iprteidx_tree(dflt, ni) + +/* ICMP */ +#define snmp_inc_icmpinmsgs() +#define snmp_inc_icmpinerrors() +#define snmp_inc_icmpindestunreachs() +#define snmp_inc_icmpintimeexcds() +#define snmp_inc_icmpinparmprobs() +#define snmp_inc_icmpinsrcquenchs() +#define snmp_inc_icmpinredirects() +#define snmp_inc_icmpinechos() +#define snmp_inc_icmpinechoreps() +#define snmp_inc_icmpintimestamps() +#define snmp_inc_icmpintimestampreps() +#define snmp_inc_icmpinaddrmasks() +#define snmp_inc_icmpinaddrmaskreps() +#define snmp_inc_icmpoutmsgs() +#define snmp_inc_icmpouterrors() +#define snmp_inc_icmpoutdestunreachs() +#define snmp_inc_icmpouttimeexcds() +#define snmp_inc_icmpoutparmprobs() +#define snmp_inc_icmpoutsrcquenchs() +#define snmp_inc_icmpoutredirects() +#define snmp_inc_icmpoutechos() +#define snmp_inc_icmpoutechoreps() +#define snmp_inc_icmpouttimestamps() +#define snmp_inc_icmpouttimestampreps() +#define snmp_inc_icmpoutaddrmasks() +#define snmp_inc_icmpoutaddrmaskreps() +/* TCP */ +#define snmp_inc_tcpactiveopens() +#define snmp_inc_tcppassiveopens() +#define snmp_inc_tcpattemptfails() +#define snmp_inc_tcpestabresets() +#define snmp_inc_tcpinsegs() +#define snmp_inc_tcpoutsegs() +#define snmp_inc_tcpretranssegs() +#define snmp_inc_tcpinerrs() +#define snmp_inc_tcpoutrsts() + +/* UDP */ +#define snmp_inc_udpindatagrams() +#define snmp_inc_udpnoports() +#define snmp_inc_udpinerrors() +#define snmp_inc_udpoutdatagrams() +#define snmp_insert_udpidx_tree(pcb) +#define snmp_delete_udpidx_tree(pcb) + +/* SNMP */ +#define snmp_inc_snmpinpkts() +#define snmp_inc_snmpoutpkts() +#define snmp_inc_snmpinbadversions() +#define snmp_inc_snmpinbadcommunitynames() +#define snmp_inc_snmpinbadcommunityuses() +#define snmp_inc_snmpinasnparseerrs() +#define snmp_inc_snmpintoobigs() +#define snmp_inc_snmpinnosuchnames() +#define snmp_inc_snmpinbadvalues() +#define snmp_inc_snmpinreadonlys() +#define snmp_inc_snmpingenerrs() +#define snmp_add_snmpintotalreqvars(value) +#define snmp_add_snmpintotalsetvars(value) +#define snmp_inc_snmpingetrequests() +#define snmp_inc_snmpingetnexts() +#define snmp_inc_snmpinsetrequests() +#define snmp_inc_snmpingetresponses() +#define snmp_inc_snmpintraps() +#define snmp_inc_snmpouttoobigs() +#define snmp_inc_snmpoutnosuchnames() +#define snmp_inc_snmpoutbadvalues() +#define snmp_inc_snmpoutgenerrs() +#define snmp_inc_snmpoutgetrequests() +#define snmp_inc_snmpoutgetnexts() +#define snmp_inc_snmpoutsetrequests() +#define snmp_inc_snmpoutgetresponses() +#define snmp_inc_snmpouttraps() +#define snmp_get_snmpgrpid_ptr(oid) +#define snmp_set_snmpenableauthentraps(value) +#define snmp_get_snmpenableauthentraps(value) + +#endif /* LWIP_SNMP */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_SNMP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_asn1.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_asn1.h new file mode 100644 index 0000000..9ef9228 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_asn1.h @@ -0,0 +1,101 @@ +/** + * @file + * Abstract Syntax Notation One (ISO 8824, 8825) codec. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef LWIP_HDR_SNMP_ASN1_H +#define LWIP_HDR_SNMP_ASN1_H + +#include "lwip/opt.h" +#include "lwip/err.h" +#include "lwip/pbuf.h" +#include "lwip/snmp.h" + +#if LWIP_SNMP + +#ifdef __cplusplus +extern "C" { +#endif + +#define SNMP_ASN1_UNIV (0) /* (!0x80 | !0x40) */ +#define SNMP_ASN1_APPLIC (0x40) /* (!0x80 | 0x40) */ +#define SNMP_ASN1_CONTXT (0x80) /* ( 0x80 | !0x40) */ + +#define SNMP_ASN1_CONSTR (0x20) /* ( 0x20) */ +#define SNMP_ASN1_PRIMIT (0) /* (!0x20) */ + +/* universal tags */ +#define SNMP_ASN1_INTEG 2 +#define SNMP_ASN1_OC_STR 4 +#define SNMP_ASN1_NUL 5 +#define SNMP_ASN1_OBJ_ID 6 +#define SNMP_ASN1_SEQ 16 + +/* application specific (SNMP) tags */ +#define SNMP_ASN1_IPADDR 0 /* octet string size(4) */ +#define SNMP_ASN1_COUNTER 1 /* u32_t */ +#define SNMP_ASN1_GAUGE 2 /* u32_t */ +#define SNMP_ASN1_TIMETICKS 3 /* u32_t */ +#define SNMP_ASN1_OPAQUE 4 /* octet string */ + +/* context specific (SNMP) tags */ +#define SNMP_ASN1_PDU_GET_REQ 0 +#define SNMP_ASN1_PDU_GET_NEXT_REQ 1 +#define SNMP_ASN1_PDU_GET_RESP 2 +#define SNMP_ASN1_PDU_SET_REQ 3 +#define SNMP_ASN1_PDU_TRAP 4 + +err_t snmp_asn1_dec_type(struct pbuf *p, u16_t ofs, u8_t *type); +err_t snmp_asn1_dec_length(struct pbuf *p, u16_t ofs, u8_t *octets_used, u16_t *length); +err_t snmp_asn1_dec_u32t(struct pbuf *p, u16_t ofs, u16_t len, u32_t *value); +err_t snmp_asn1_dec_s32t(struct pbuf *p, u16_t ofs, u16_t len, s32_t *value); +err_t snmp_asn1_dec_oid(struct pbuf *p, u16_t ofs, u16_t len, struct snmp_obj_id *oid); +err_t snmp_asn1_dec_raw(struct pbuf *p, u16_t ofs, u16_t len, u16_t raw_len, u8_t *raw); + +void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); +void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); +void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); +void snmp_asn1_enc_oid_cnt(u8_t ident_len, s32_t *ident, u16_t *octets_needed); +err_t snmp_asn1_enc_type(struct pbuf *p, u16_t ofs, u8_t type); +err_t snmp_asn1_enc_length(struct pbuf *p, u16_t ofs, u16_t length); +err_t snmp_asn1_enc_u32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, u32_t value); +err_t snmp_asn1_enc_s32t(struct pbuf *p, u16_t ofs, u16_t octets_needed, s32_t value); +err_t snmp_asn1_enc_oid(struct pbuf *p, u16_t ofs, u8_t ident_len, s32_t *ident); +err_t snmp_asn1_enc_raw(struct pbuf *p, u16_t ofs, u16_t raw_len, u8_t *raw); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_SNMP_ASN1_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_msg.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_msg.h new file mode 100644 index 0000000..3f65395 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_msg.h @@ -0,0 +1,315 @@ +/** + * @file + * SNMP Agent message handling structures. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef LWIP_HDR_SNMP_MSG_H +#define LWIP_HDR_SNMP_MSG_H + +#include "lwip/opt.h" +#include "lwip/snmp.h" +#include "lwip/snmp_structs.h" +#include "lwip/ip_addr.h" +#include "lwip/err.h" + +#if LWIP_SNMP + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* The listen port of the SNMP agent. Clients have to make their requests to + this port. Most standard clients won't work if you change this! */ +#ifndef SNMP_IN_PORT +#define SNMP_IN_PORT 161 +#endif +/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't + work if you change this! */ +#ifndef SNMP_TRAP_PORT +#define SNMP_TRAP_PORT 162 +#endif + +#define SNMP_ES_NOERROR 0 +#define SNMP_ES_TOOBIG 1 +#define SNMP_ES_NOSUCHNAME 2 +#define SNMP_ES_BADVALUE 3 +#define SNMP_ES_READONLY 4 +#define SNMP_ES_GENERROR 5 + +#define SNMP_GENTRAP_COLDSTART 0 +#define SNMP_GENTRAP_WARMSTART 1 +#define SNMP_GENTRAP_AUTHFAIL 4 +#define SNMP_GENTRAP_ENTERPRISESPC 6 + +struct snmp_varbind +{ + /* next pointer, NULL for last in list */ + struct snmp_varbind *next; + /* previous pointer, NULL for first in list */ + struct snmp_varbind *prev; + + /* object identifier length (in s32_t) */ + u8_t ident_len; + /* object identifier array */ + s32_t *ident; + + /* object value ASN1 type */ + u8_t value_type; + /* object value length (in u8_t) */ + u8_t value_len; + /* object value */ + void *value; + + /* encoding varbind seq length length */ + u8_t seqlenlen; + /* encoding object identifier length length */ + u8_t olenlen; + /* encoding object value length length */ + u8_t vlenlen; + /* encoding varbind seq length */ + u16_t seqlen; + /* encoding object identifier length */ + u16_t olen; + /* encoding object value length */ + u16_t vlen; +}; + +struct snmp_varbind_root +{ + struct snmp_varbind *head; + struct snmp_varbind *tail; + /* number of variable bindings in list */ + u8_t count; + /* encoding varbind-list seq length length */ + u8_t seqlenlen; + /* encoding varbind-list seq length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_resp_header_lengths +{ + /* encoding error-index length length */ + u8_t erridxlenlen; + /* encoding error-status length length */ + u8_t errstatlenlen; + /* encoding request id length length */ + u8_t ridlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding error-index length */ + u16_t erridxlen; + /* encoding error-status length */ + u16_t errstatlen; + /* encoding request id length */ + u16_t ridlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/** output response message header length fields */ +struct snmp_trap_header_lengths +{ + /* encoding timestamp length length */ + u8_t tslenlen; + /* encoding specific-trap length length */ + u8_t strplenlen; + /* encoding generic-trap length length */ + u8_t gtrplenlen; + /* encoding agent-addr length length */ + u8_t aaddrlenlen; + /* encoding enterprise-id length length */ + u8_t eidlenlen; + /* encoding pdu length length */ + u8_t pdulenlen; + /* encoding community length length */ + u8_t comlenlen; + /* encoding version length length */ + u8_t verlenlen; + /* encoding sequence length length */ + u8_t seqlenlen; + + /* encoding timestamp length */ + u16_t tslen; + /* encoding specific-trap length */ + u16_t strplen; + /* encoding generic-trap length */ + u16_t gtrplen; + /* encoding agent-addr length */ + u16_t aaddrlen; + /* encoding enterprise-id length */ + u16_t eidlen; + /* encoding pdu length */ + u16_t pdulen; + /* encoding community length */ + u16_t comlen; + /* encoding version length */ + u16_t verlen; + /* encoding sequence length */ + u16_t seqlen; +}; + +/* Accepting new SNMP messages. */ +#define SNMP_MSG_EMPTY 0 +/* Search for matching object for variable binding. */ +#define SNMP_MSG_SEARCH_OBJ 1 +/* Perform SNMP operation on in-memory object. + Pass-through states, for symmetry only. */ +#define SNMP_MSG_INTERNAL_GET_OBJDEF 2 +#define SNMP_MSG_INTERNAL_GET_VALUE 3 +#define SNMP_MSG_INTERNAL_SET_TEST 4 +#define SNMP_MSG_INTERNAL_GET_OBJDEF_S 5 +#define SNMP_MSG_INTERNAL_SET_VALUE 6 +/* Perform SNMP operation on object located externally. + In theory this could be used for building a proxy agent. + Practical use is for an enterprise spc. app. gateway. */ +#define SNMP_MSG_EXTERNAL_GET_OBJDEF 7 +#define SNMP_MSG_EXTERNAL_GET_VALUE 8 +#define SNMP_MSG_EXTERNAL_SET_TEST 9 +#define SNMP_MSG_EXTERNAL_GET_OBJDEF_S 10 +#define SNMP_MSG_EXTERNAL_SET_VALUE 11 + +#define SNMP_COMMUNITY_STR_LEN 64 +struct snmp_msg_pstat +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* source IP address */ + ip_addr_t sip; + /* source UDP port */ + u16_t sp; + /* request type */ + u8_t rt; + /* request ID */ + s32_t rid; + /* error status */ + s32_t error_status; + /* error index */ + s32_t error_index; + /* community name (zero terminated) */ + u8_t community[SNMP_COMMUNITY_STR_LEN + 1]; + /* community string length (exclusive zero term) */ + u8_t com_strlen; + /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL_x */ + u8_t state; + /* saved arguments for MSG_EXTERNAL_x */ + struct mib_external_node *ext_mib_node; + struct snmp_name_ptr ext_name_ptr; + struct obj_def ext_object_def; + struct snmp_obj_id ext_oid; + /* index into input variable binding list */ + u8_t vb_idx; + /* ptr into input variable binding list */ + struct snmp_varbind *vb_ptr; + /* list of variable bindings from input */ + struct snmp_varbind_root invb; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output response lengths used in ASN encoding */ + struct snmp_resp_header_lengths rhl; +}; + +struct snmp_msg_trap +{ + /* lwIP local port (161) binding */ + struct udp_pcb *pcb; + /* destination IP address in network order */ + ip_addr_t dip; + + /* source enterprise ID (sysObjectID) */ + struct snmp_obj_id *enterprise; + /* source IP address, raw network order format */ + u8_t sip_raw[4]; + /* generic trap code */ + u32_t gen_trap; + /* specific trap code */ + u32_t spc_trap; + /* timestamp */ + u32_t ts; + /* list of variable bindings to output */ + struct snmp_varbind_root outvb; + /* output trap lengths used in ASN encoding */ + struct snmp_trap_header_lengths thl; +}; + +/** Agent Version constant, 0 = v1 oddity */ +extern const s32_t snmp_version; +/** Agent default "public" community string */ +extern const char snmp_publiccommunity[7]; + +extern struct snmp_msg_trap trap_msg; + +/** Agent setup, start listening to port 161. */ +void snmp_init(void); +void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); +void snmp_trap_dst_ip_set(u8_t dst_idx, ip_addr_t *dst); + +/** Varbind-list functions. */ +struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len); +void snmp_varbind_free(struct snmp_varbind *vb); +void snmp_varbind_list_free(struct snmp_varbind_root *root); +void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb); +struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root); + +/** Handle an internal (recv) or external (private response) event. */ +void snmp_msg_event(u8_t request_id); +err_t snmp_send_response(struct snmp_msg_pstat *m_stat); +err_t snmp_send_trap(s8_t generic_trap, struct snmp_obj_id *eoid, s32_t specific_trap); +void snmp_coldstart_trap(void); +void snmp_authfail_trap(void); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_SNMP_MSG_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_structs.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_structs.h new file mode 100644 index 0000000..b69160c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/snmp_structs.h @@ -0,0 +1,268 @@ +/** + * @file + * Generic MIB tree structures. + * + * @todo namespace prefixes + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Christiaan Simons + */ + +#ifndef LWIP_HDR_SNMP_STRUCTS_H +#define LWIP_HDR_SNMP_STRUCTS_H + +#include "lwip/opt.h" + +#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/snmp.h" + +#if SNMP_PRIVATE_MIB +/* When using a private MIB, you have to create a file 'private_mib.h' that contains + * a 'struct mib_array_node mib_private' which contains your MIB. */ +#include "private_mib.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MIB object instance */ +#define MIB_OBJECT_NONE 0 +#define MIB_OBJECT_SCALAR 1 +#define MIB_OBJECT_TAB 2 + +/* MIB access types */ +#define MIB_ACCESS_READ 1 +#define MIB_ACCESS_WRITE 2 + +/* MIB object access */ +#define MIB_OBJECT_READ_ONLY MIB_ACCESS_READ +#define MIB_OBJECT_READ_WRITE (MIB_ACCESS_READ | MIB_ACCESS_WRITE) +#define MIB_OBJECT_WRITE_ONLY MIB_ACCESS_WRITE +#define MIB_OBJECT_NOT_ACCESSIBLE 0 + +/** object definition returned by (get_object_def)() */ +struct obj_def +{ + /* MIB_OBJECT_NONE (0), MIB_OBJECT_SCALAR (1), MIB_OBJECT_TAB (2) */ + u8_t instance; + /* 0 read-only, 1 read-write, 2 write-only, 3 not-accessible */ + u8_t access; + /* ASN type for this object */ + u8_t asn_type; + /* value length (host length) */ + u16_t v_len; + /* length of instance part of supplied object identifier */ + u8_t id_inst_len; + /* instance part of supplied object identifier */ + s32_t *id_inst_ptr; +}; + +struct snmp_name_ptr +{ + u8_t ident_len; + s32_t *ident; +}; + +/** MIB const scalar (.0) node */ +#define MIB_NODE_SC 0x01 +/** MIB const array node */ +#define MIB_NODE_AR 0x02 +/** MIB array node (mem_malloced from RAM) */ +#define MIB_NODE_RA 0x03 +/** MIB list root node (mem_malloced from RAM) */ +#define MIB_NODE_LR 0x04 +/** MIB node for external objects */ +#define MIB_NODE_EX 0x05 + +/** node "base class" layout, the mandatory fields for a node */ +struct mib_node +{ + /** returns struct obj_def for the given object identifier */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + /** returns object value for the given object identifier, + @note the caller must allocate at least len bytes for the value */ + void (*get_value)(struct obj_def *od, u16_t len, void *value); + /** tests length and/or range BEFORE setting */ + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + /** sets object value, only to be called when set_test() */ + void (*set_value)(struct obj_def *od, u16_t len, void *value); + /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */ + u8_t node_type; + /* array or max list length */ + u16_t maxlength; +}; + +/** derived node for scalars .0 index */ +typedef struct mib_node mib_scalar_node; + +/** derived node, points to a fixed size const array + of sub-identifiers plus a 'child' pointer */ +struct mib_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + const s32_t *objid; + struct mib_node* const *nptr; +}; + +/** derived node, points to a fixed size mem_malloced array + of sub-identifiers plus a 'child' pointer */ +struct mib_ram_array_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* aditional struct members */ + s32_t *objid; + struct mib_node **nptr; +}; + +struct mib_list_node +{ + struct mib_list_node *prev; + struct mib_list_node *next; + s32_t objid; + struct mib_node *nptr; +}; + +/** derived node, points to a doubly linked list + of sub-identifiers plus a 'child' pointer */ +struct mib_list_rootnode +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + struct mib_list_node *head; + struct mib_list_node *tail; + /* counts list nodes in list */ + u16_t count; +}; + +/** derived node, has access functions for mib object in external memory or device + using 'tree_level' and 'idx', with a range 0 .. (level_length() - 1) */ +struct mib_external_node +{ + /* inherited "base class" members */ + void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value)(struct obj_def *od, u16_t len, void *value); + u8_t (*set_test)(struct obj_def *od, u16_t len, void *value); + void (*set_value)(struct obj_def *od, u16_t len, void *value); + + u8_t node_type; + u16_t maxlength; + + /* additional struct members */ + /** points to an external (in memory) record of some sort of addressing + information, passed to and interpreted by the functions below */ + void* addr_inf; + /** tree levels under this node */ + u8_t tree_levels; + /** number of objects at this level */ + u16_t (*level_length)(void* addr_inf, u8_t level); + /** compares object sub identifier with external id + return zero when equal, nonzero when unequal */ + s32_t (*ident_cmp)(void* addr_inf, u8_t level, u16_t idx, s32_t sub_id); + void (*get_objid)(void* addr_inf, u8_t level, u16_t idx, s32_t *sub_id); + + /** async Questions */ + void (*get_object_def_q)(void* addr_inf, u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_q)(u8_t rid, struct obj_def *od); + void (*set_test_q)(u8_t rid, struct obj_def *od); + void (*set_value_q)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Answers */ + void (*get_object_def_a)(u8_t rid, u8_t ident_len, s32_t *ident, struct obj_def *od); + void (*get_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + u8_t (*set_test_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + void (*set_value_a)(u8_t rid, struct obj_def *od, u16_t len, void *value); + /** async Panic Close (agent returns error reply, + e.g. used for external transaction cleanup) */ + void (*get_object_def_pc)(u8_t rid, u8_t ident_len, s32_t *ident); + void (*get_value_pc)(u8_t rid, struct obj_def *od); + void (*set_test_pc)(u8_t rid, struct obj_def *od); + void (*set_value_pc)(u8_t rid, struct obj_def *od); +}; + +/** export MIB tree from mib2.c */ +extern const struct mib_array_node internet; + +/** dummy function pointers for non-leaf MIB nodes from mib2.c */ +void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od); +void noleafs_get_value(struct obj_def *od, u16_t len, void *value); +u8_t noleafs_set_test(struct obj_def *od, u16_t len, void *value); +void noleafs_set_value(struct obj_def *od, u16_t len, void *value); + +void snmp_oidtoip(s32_t *ident, ip_addr_t *ip); +void snmp_iptooid(ip_addr_t *ip, s32_t *ident); +void snmp_ifindextonetif(s32_t ifindex, struct netif **netif); +void snmp_netiftoifindex(struct netif *netif, s32_t *ifidx); + +struct mib_list_node* snmp_mib_ln_alloc(s32_t id); +void snmp_mib_ln_free(struct mib_list_node *ln); +struct mib_list_rootnode* snmp_mib_lrn_alloc(void); +void snmp_mib_lrn_free(struct mib_list_rootnode *lrn); + +s8_t snmp_mib_node_insert(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **insn); +s8_t snmp_mib_node_find(struct mib_list_rootnode *rn, s32_t objid, struct mib_list_node **fn); +struct mib_list_rootnode *snmp_mib_node_delete(struct mib_list_rootnode *rn, struct mib_list_node *n); + +struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_name_ptr *np); +struct mib_node* snmp_expand_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); +u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident); +u8_t snmp_iso_prefix_expand(u8_t ident_len, s32_t *ident, struct snmp_obj_id *oidret); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SNMP */ + +#endif /* LWIP_HDR_SNMP_STRUCTS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sockets.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sockets.h new file mode 100644 index 0000000..97897c8 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sockets.h @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#ifndef LWIP_HDR_SOCKETS_H +#define LWIP_HDR_SOCKETS_H + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ + +#include /* for size_t */ + +#include "lwip/ip_addr.h" +#include "lwip/err.h" +#include "lwip/inet.h" +#include "lwip/inet6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) +typedef u8_t sa_family_t; +#endif +/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) +typedef u16_t in_port_t; +#endif + +/* members are in network byte order */ +struct sockaddr_in { + u8_t sin_len; + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; +#define SIN_ZERO_LEN 8 + char sin_zero[SIN_ZERO_LEN]; +}; + +#if LWIP_IPV6 +struct sockaddr_in6 { + u8_t sin6_len; /* length of this structure */ + sa_family_t sin6_family; /* AF_INET6 */ + in_port_t sin6_port; /* Transport layer port # */ + u32_t sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ +}; +#endif /* LWIP_IPV6 */ + +struct sockaddr { + u8_t sa_len; + sa_family_t sa_family; +#if LWIP_IPV6 + char sa_data[22]; +#else /* LWIP_IPV6 */ + char sa_data[14]; +#endif /* LWIP_IPV6 */ +}; + +struct sockaddr_storage { + u8_t s2_len; + sa_family_t ss_family; + char s2_data1[2]; + u32_t s2_data2[3]; +#if LWIP_IPV6 + u32_t s2_data3[2]; +#endif /* LWIP_IPV6 */ +}; + +/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) +typedef u32_t socklen_t; +#endif + +struct lwip_sock; + +#if !LWIP_TCPIP_CORE_LOCKING +/** Maximum optlen used by setsockopt/getsockopt */ +#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16 + +/** This struct is used to pass data to the set/getsockopt_internal + * functions running in tcpip_thread context (only a void* is allowed) */ +struct lwip_setgetsockopt_data { + /** socket index for which to change options */ + int s; + /** level of the option to process */ + int level; + /** name of the option to process */ + int optname; + /** set: value to set the option to + * get: value of the option is stored here */ +#if LWIP_MPU_COMPATIBLE + u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN]; +#else + void* optval; +#endif + /** size of *optval */ + socklen_t optlen; + /** if an error occurs, it is temporarily stored here */ + err_t err; + /** semaphore to wake up the calling task */ + void* completed_sem; +}; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + +/* Socket protocol types (TCP/UDP/RAW) */ +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 + +/* + * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) + */ +#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ + + +/* + * Additional options, not kept in so_options. + */ +#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ +#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_DONTLINGER ((int)(~SO_LINGER)) +#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ +#define SO_REUSEPORT 0x0200 /* allow local address & port reuse */ +#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* Unimplemented: send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ +#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ +#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ + + +/* + * Structure used for manipulating linger option. + */ +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xfff /* options for socket level */ + + +#define AF_UNSPEC 0 +#define AF_INET 2 +#if LWIP_IPV6 +#define AF_INET6 10 +#else /* LWIP_IPV6 */ +#define AF_INET6 AF_UNSPEC +#endif /* LWIP_IPV6 */ +#define PF_INET AF_INET +#define PF_INET6 AF_INET6 +#define PF_UNSPEC AF_UNSPEC + +#define IPPROTO_IP 0 +#define IPPROTO_ICMP 1 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#if LWIP_IPV6 +#define IPPROTO_IPV6 41 +#define IPPROTO_ICMPV6 58 +#endif /* LWIP_IPV6 */ +#define IPPROTO_UDPLITE 136 +#define IPPROTO_RAW 255 + +/* Flags we can use with send and recv. */ +#define MSG_PEEK 0x01 /* Peeks at an incoming message */ +#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ +#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ +#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ +#define MSG_MORE 0x10 /* Sender will send more */ + + +/* + * Options for level IPPROTO_IP + */ +#define IP_TOS 1 +#define IP_TTL 2 + +#if LWIP_TCP +/* + * Options for level IPPROTO_TCP + */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ +#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ +#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ +#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ +#endif /* LWIP_TCP */ + +#if LWIP_IPV6 +/* + * Options for level IPPROTO_IPV6 + */ +#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ +#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE +/* + * Options for level IPPROTO_UDPLITE + */ +#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ +#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ +#endif /* LWIP_UDP && LWIP_UDPLITE*/ + + +#if LWIP_IGMP +/* + * Options and types for UDP multicast traffic handling + */ +#define IP_ADD_MEMBERSHIP 3 +#define IP_DROP_MEMBERSHIP 4 +#define IP_MULTICAST_TTL 5 +#define IP_MULTICAST_IF 6 +#define IP_MULTICAST_LOOP 7 + +typedef struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +} ip_mreq; +#endif /* LWIP_IGMP */ + +/* + * The Type of Service provides an indication of the abstract + * parameters of the quality of service desired. These parameters are + * to be used to guide the selection of the actual service parameters + * when transmitting a datagram through a particular network. Several + * networks offer service precedence, which somehow treats high + * precedence traffic as more important than other traffic (generally + * by accepting only traffic above a certain precedence at time of high + * load). The major choice is a three way tradeoff between low-delay, + * high-reliability, and high-throughput. + * The use of the Delay, Throughput, and Reliability indications may + * increase the cost (in some sense) of the service. In many networks + * better performance for one of these parameters is coupled with worse + * performance on another. Except for very unusual cases at most two + * of these three indications should be set. + */ +#define IPTOS_TOS_MASK 0x1E +#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWCOST 0x02 +#define IPTOS_MINCOST IPTOS_LOWCOST + +/* + * The Network Control precedence designation is intended to be used + * within a network only. The actual use and control of that + * designation is up to each network. The Internetwork Control + * designation is intended for use by gateway control originators only. + * If the actual use of these precedence designations is of concern to + * a particular network, it is the responsibility of that network to + * control the access to, and use of, those precedence designations. + */ +#define IPTOS_PREC_MASK 0xe0 +#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * lwip_ioctl only supports FIONREAD and FIONBIO, for now + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#if !defined(FIONREAD) || !defined(FIONBIO) +#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000UL /* no parameters */ +#define IOC_OUT 0x40000000UL /* copy out parameters */ +#define IOC_IN 0x80000000UL /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) +#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ + +#ifndef FIONREAD +#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ +#endif +#ifndef FIONBIO +#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ +#endif + +/* Socket I/O Controls: unimplemented */ +#ifndef SIOCSHIWAT +#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ +#endif + +/* commands for fnctl */ +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + +/* File status flags and file access modes for fnctl, + these are bits in an int. */ +#ifndef O_NONBLOCK +#define O_NONBLOCK 1 /* nonblocking I/O */ +#endif +#ifndef O_NDELAY +#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ +#endif + +#ifndef SHUT_RD + #define SHUT_RD 0 + #define SHUT_WR 1 + #define SHUT_RDWR 2 +#endif + +/* FD_SET used for lwip_select */ +#ifndef FD_SET + #undef FD_SETSIZE + /* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ + #define FD_SETSIZE MEMP_NUM_NETCONN + #define FD_SET(n, p) ((p)->fd_bits[(n)/8] |= (1 << ((n) & 7))) + #define FD_CLR(n, p) ((p)->fd_bits[(n)/8] &= ~(1 << ((n) & 7))) + #define FD_ISSET(n,p) ((p)->fd_bits[(n)/8] & (1 << ((n) & 7))) + #define FD_ZERO(p) memset((void*)(p),0,sizeof(*(p))) + + typedef struct fd_set { + unsigned char fd_bits [(FD_SETSIZE+7)/8]; + } fd_set; + +#endif /* FD_SET */ + +/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided + * by your system, set this to 0 and include in cc.h */ +#ifndef LWIP_TIMEVAL_PRIVATE +#define LWIP_TIMEVAL_PRIVATE 1 +#endif + +#if LWIP_TIMEVAL_PRIVATE +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; +#endif /* LWIP_TIMEVAL_PRIVATE */ + +#define lwip_socket_init() /* Compatibility define, no init needed. */ + +int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_shutdown(int s, int how); +int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); +int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); +int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); +int lwip_close(int s); +int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); +int lwip_listen(int s, int backlog); +int lwip_recv(int s, void *mem, size_t len, int flags); +int lwip_read(int s, void *mem, size_t len); +int lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen); +int lwip_send(int s, const void *dataptr, size_t size, int flags); +int lwip_sendto(int s, const void *dataptr, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen); +int lwip_socket(int domain, int type, int protocol); +int lwip_write(int s, const void *dataptr, size_t size); +int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout); +int lwip_ioctl(int s, long cmd, void *argp); +int lwip_fcntl(int s, int cmd, int val); + +#if LWIP_COMPAT_SOCKETS +#define accept(a,b,c) lwip_accept(a,b,c) +#define bind(a,b,c) lwip_bind(a,b,c) +#define shutdown(a,b) lwip_shutdown(a,b) +#define closesocket(s) lwip_close(s) +#define connect(a,b,c) lwip_connect(a,b,c) +#define getsockname(a,b,c) lwip_getsockname(a,b,c) +#define getpeername(a,b,c) lwip_getpeername(a,b,c) +#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e) +#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e) +#define listen(a,b) lwip_listen(a,b) +#define recv(a,b,c,d) lwip_recv(a,b,c,d) +#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f) +#define send(a,b,c,d) lwip_send(a,b,c,d) +#define sendto(a,b,c,d,e,f) lwip_sendto(a,b,c,d,e,f) +#define socket(a,b,c) lwip_socket(a,b,c) +#define select(a,b,c,d,e) lwip_select(a,b,c,d,e) +#define ioctlsocket(a,b,c) lwip_ioctl(a,b,c) + +#if LWIP_POSIX_SOCKETS_IO_NAMES +#define read(a,b,c) lwip_read(a,b,c) +#define write(a,b,c) lwip_write(a,b,c) +#define close(s) lwip_close(s) +#define fcntl(a,b,c) lwip_fcntl(a,b,c) +#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ + +#if LWIP_IPV6 +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET6) ? ip6addr_ntoa_r((src),(dst),(size)) \ + : (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL)) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET6) ? inet6_aton((src),(dst)) \ + : (((af) == AF_INET) ? inet_aton((src),(dst)) : 0)) +#else /* LWIP_IPV6 */ +#define inet_ntop(af,src,dst,size) \ + (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL) +#define inet_pton(af,src,dst) \ + (((af) == AF_INET) ? inet_aton((src),(dst)) : 0) +#endif /* LWIP_IPV6 */ + +#endif /* LWIP_COMPAT_SOCKETS */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_SOCKET */ + +#endif /* LWIP_HDR_SOCKETS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/stats.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/stats.h new file mode 100644 index 0000000..6385318 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/stats.h @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_STATS_H +#define LWIP_HDR_STATS_H + +#include "lwip/opt.h" + +#include "lwip/mem.h" +#include "lwip/memp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if LWIP_STATS + +#ifndef LWIP_STATS_LARGE +#define LWIP_STATS_LARGE 0 +#endif + +#if LWIP_STATS_LARGE +#define STAT_COUNTER u32_t +#define STAT_COUNTER_F U32_F +#else +#define STAT_COUNTER u16_t +#define STAT_COUNTER_F U16_F +#endif + +struct stats_proto { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER fw; /* Forwarded packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER rterr; /* Routing error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER opterr; /* Error in options. */ + STAT_COUNTER err; /* Misc error. */ + STAT_COUNTER cachehit; +}; + +struct stats_igmp { + STAT_COUNTER xmit; /* Transmitted packets. */ + STAT_COUNTER recv; /* Received packets. */ + STAT_COUNTER drop; /* Dropped packets. */ + STAT_COUNTER chkerr; /* Checksum error. */ + STAT_COUNTER lenerr; /* Invalid length error. */ + STAT_COUNTER memerr; /* Out of memory error. */ + STAT_COUNTER proterr; /* Protocol error. */ + STAT_COUNTER rx_v1; /* Received v1 frames. */ + STAT_COUNTER rx_group; /* Received group-specific queries. */ + STAT_COUNTER rx_general; /* Received general queries. */ + STAT_COUNTER rx_report; /* Received reports. */ + STAT_COUNTER tx_join; /* Sent joins. */ + STAT_COUNTER tx_leave; /* Sent leaves. */ + STAT_COUNTER tx_report; /* Sent reports. */ +}; + +struct stats_mem { +#ifdef LWIP_DEBUG + const char *name; +#endif /* LWIP_DEBUG */ + STAT_COUNTER err; + mem_size_t avail; + mem_size_t used; + mem_size_t max; + STAT_COUNTER illegal; +}; + +struct stats_syselem { + STAT_COUNTER used; + STAT_COUNTER max; + STAT_COUNTER err; +}; + +struct stats_sys { + struct stats_syselem sem; + struct stats_syselem mutex; + struct stats_syselem mbox; +}; + +struct stats_ { +#if LINK_STATS + struct stats_proto link; +#endif +#if ETHARP_STATS + struct stats_proto etharp; +#endif +#if IPFRAG_STATS + struct stats_proto ip_frag; +#endif +#if IP_STATS + struct stats_proto ip; +#endif +#if ICMP_STATS + struct stats_proto icmp; +#endif +#if IGMP_STATS + struct stats_igmp igmp; +#endif +#if UDP_STATS + struct stats_proto udp; +#endif +#if TCP_STATS + struct stats_proto tcp; +#endif +#if MEM_STATS + struct stats_mem mem; +#endif +#if MEMP_STATS + struct stats_mem memp[MEMP_MAX]; +#endif +#if SYS_STATS + struct stats_sys sys; +#endif +#if IP6_STATS + struct stats_proto ip6; +#endif +#if ICMP6_STATS + struct stats_proto icmp6; +#endif +#if IP6_FRAG_STATS + struct stats_proto ip6_frag; +#endif +#if MLD6_STATS + struct stats_igmp mld6; +#endif +#if ND6_STATS + struct stats_proto nd6; +#endif +}; + +extern struct stats_ lwip_stats; + +void stats_init(void); + +#define STATS_INC(x) ++lwip_stats.x +#define STATS_DEC(x) --lwip_stats.x +#define STATS_INC_USED(x, y) do { lwip_stats.x.used += y; \ + if (lwip_stats.x.max < lwip_stats.x.used) { \ + lwip_stats.x.max = lwip_stats.x.used; \ + } \ + } while(0) +#else /* LWIP_STATS */ +#define stats_init() +#define STATS_INC(x) +#define STATS_DEC(x) +#define STATS_INC_USED(x) +#endif /* LWIP_STATS */ + +#if TCP_STATS +#define TCP_STATS_INC(x) STATS_INC(x) +#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") +#else +#define TCP_STATS_INC(x) +#define TCP_STATS_DISPLAY() +#endif + +#if UDP_STATS +#define UDP_STATS_INC(x) STATS_INC(x) +#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") +#else +#define UDP_STATS_INC(x) +#define UDP_STATS_DISPLAY() +#endif + +#if ICMP_STATS +#define ICMP_STATS_INC(x) STATS_INC(x) +#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") +#else +#define ICMP_STATS_INC(x) +#define ICMP_STATS_DISPLAY() +#endif + +#if IGMP_STATS +#define IGMP_STATS_INC(x) STATS_INC(x) +#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") +#else +#define IGMP_STATS_INC(x) +#define IGMP_STATS_DISPLAY() +#endif + +#if IP_STATS +#define IP_STATS_INC(x) STATS_INC(x) +#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") +#else +#define IP_STATS_INC(x) +#define IP_STATS_DISPLAY() +#endif + +#if IPFRAG_STATS +#define IPFRAG_STATS_INC(x) STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") +#else +#define IPFRAG_STATS_INC(x) +#define IPFRAG_STATS_DISPLAY() +#endif + +#if ETHARP_STATS +#define ETHARP_STATS_INC(x) STATS_INC(x) +#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") +#else +#define ETHARP_STATS_INC(x) +#define ETHARP_STATS_DISPLAY() +#endif + +#if LINK_STATS +#define LINK_STATS_INC(x) STATS_INC(x) +#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") +#else +#define LINK_STATS_INC(x) +#define LINK_STATS_DISPLAY() +#endif + +#if MEM_STATS +#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y +#define MEM_STATS_INC(x) STATS_INC(mem.x) +#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y) +#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x -= y +#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") +#else +#define MEM_STATS_AVAIL(x, y) +#define MEM_STATS_INC(x) +#define MEM_STATS_INC_USED(x, y) +#define MEM_STATS_DEC_USED(x, y) +#define MEM_STATS_DISPLAY() +#endif + +#if MEMP_STATS +#define MEMP_STATS_AVAIL(x, i, y) lwip_stats.memp[i].x = y +#define MEMP_STATS_INC(x, i) STATS_INC(memp[i].x) +#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i].x) +#define MEMP_STATS_INC_USED(x, i) STATS_INC_USED(memp[i], 1) +#define MEMP_STATS_DISPLAY(i) stats_display_memp(&lwip_stats.memp[i], i) +#else +#define MEMP_STATS_AVAIL(x, i, y) +#define MEMP_STATS_INC(x, i) +#define MEMP_STATS_DEC(x, i) +#define MEMP_STATS_INC_USED(x, i) +#define MEMP_STATS_DISPLAY(i) +#endif + +#if SYS_STATS +#define SYS_STATS_INC(x) STATS_INC(sys.x) +#define SYS_STATS_DEC(x) STATS_DEC(sys.x) +#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1) +#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) +#else +#define SYS_STATS_INC(x) +#define SYS_STATS_DEC(x) +#define SYS_STATS_INC_USED(x) +#define SYS_STATS_DISPLAY() +#endif + +#if IP6_STATS +#define IP6_STATS_INC(x) STATS_INC(x) +#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") +#else +#define IP6_STATS_INC(x) +#define IP6_STATS_DISPLAY() +#endif + +#if ICMP6_STATS +#define ICMP6_STATS_INC(x) STATS_INC(x) +#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") +#else +#define ICMP6_STATS_INC(x) +#define ICMP6_STATS_DISPLAY() +#endif + +#if IP6_FRAG_STATS +#define IP6_FRAG_STATS_INC(x) STATS_INC(x) +#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") +#else +#define IP6_FRAG_STATS_INC(x) +#define IP6_FRAG_STATS_DISPLAY() +#endif + +#if MLD6_STATS +#define MLD6_STATS_INC(x) STATS_INC(x) +#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") +#else +#define MLD6_STATS_INC(x) +#define MLD6_STATS_DISPLAY() +#endif + +#if ND6_STATS +#define ND6_STATS_INC(x) STATS_INC(x) +#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") +#else +#define ND6_STATS_INC(x) +#define ND6_STATS_DISPLAY() +#endif + +/* Display of statistics */ +#if LWIP_STATS_DISPLAY +void stats_display(void); +void stats_display_proto(struct stats_proto *proto, const char *name); +void stats_display_igmp(struct stats_igmp *igmp, const char *name); +void stats_display_mem(struct stats_mem *mem, const char *name); +void stats_display_memp(struct stats_mem *mem, int index); +void stats_display_sys(struct stats_sys *sys); +#else /* LWIP_STATS_DISPLAY */ +#define stats_display() +#define stats_display_proto(proto, name) +#define stats_display_igmp(igmp, name) +#define stats_display_mem(mem, name) +#define stats_display_memp(mem, index) +#define stats_display_sys(sys) +#endif /* LWIP_STATS_DISPLAY */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_STATS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sys.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sys.h new file mode 100644 index 0000000..82db118 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/sys.h @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_SYS_H +#define LWIP_HDR_SYS_H + +#include "lwip/opt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if NO_SYS + +/* For a totally minimal and standalone system, we provide null + definitions of the sys_ functions. */ +typedef u8_t sys_sem_t; +typedef u8_t sys_mutex_t; +typedef u8_t sys_mbox_t; + +#define sys_sem_new(s, c) ERR_OK +#define sys_sem_signal(s) +#define sys_sem_wait(s) +#define sys_arch_sem_wait(s,t) +#define sys_sem_free(s) +#define sys_sem_valid(s) 0 +#define sys_sem_set_invalid(s) +#define sys_mutex_new(mu) ERR_OK +#define sys_mutex_lock(mu) +#define sys_mutex_unlock(mu) +#define sys_mutex_free(mu) +#define sys_mutex_valid(mu) 0 +#define sys_mutex_set_invalid(mu) +#define sys_mbox_new(m, s) ERR_OK +#define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) +#define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) +#define sys_mbox_free(m) +#define sys_mbox_valid(m) +#define sys_mbox_set_invalid(m) + +#define sys_thread_new(n,t,a,s,p) + +#define sys_msleep(t) + +#else /* NO_SYS */ + +/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ +#define SYS_ARCH_TIMEOUT 0xffffffffUL + +/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. + * For now we use the same magic value, but we allow this to change in future. + */ +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +#include "lwip/err.h" +#include "arch/sys_arch.h" + +/** Function prototype for thread functions */ +typedef void (*lwip_thread_fn)(void *arg); + +/* Function prototypes for functions to be implemented by platform ports + (in sys_arch.c) */ + +/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores + should be used instead */ +#if LWIP_COMPAT_MUTEX +/* for old ports that don't have mutexes: define them to binary semaphores */ +#define sys_mutex_t sys_sem_t +#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) +#define sys_mutex_lock(mutex) sys_sem_wait(mutex) +#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) +#define sys_mutex_free(mutex) sys_sem_free(mutex) +#define sys_mutex_valid(mutex) sys_sem_valid(mutex) +#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) + +#else /* LWIP_COMPAT_MUTEX */ + +/** Create a new mutex + * @param mutex pointer to the mutex to create + * @return a new mutex */ +err_t sys_mutex_new(sys_mutex_t *mutex); +/** Lock a mutex + * @param mutex the mutex to lock */ +void sys_mutex_lock(sys_mutex_t *mutex); +/** Unlock a mutex + * @param mutex the mutex to unlock */ +void sys_mutex_unlock(sys_mutex_t *mutex); +/** Delete a semaphore + * @param mutex the mutex to delete */ +void sys_mutex_free(sys_mutex_t *mutex); +#ifndef sys_mutex_valid +/** Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mutex_valid(sys_mutex_t *mutex); +#endif +#ifndef sys_mutex_set_invalid +/** Set a mutex invalid so that sys_mutex_valid returns 0 */ +void sys_mutex_set_invalid(sys_mutex_t *mutex); +#endif +#endif /* LWIP_COMPAT_MUTEX */ + +/* Semaphore functions: */ + +/** Create a new semaphore + * @param sem pointer to the semaphore to create + * @param count initial count of the semaphore + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_sem_new(sys_sem_t *sem, u8_t count); +/** Signals a semaphore + * @param sem the semaphore to signal */ +void sys_sem_signal(sys_sem_t *sem); +/** Wait for a semaphore for the specified timeout + * @param sem the semaphore to wait for + * @param timeout timeout in milliseconds to wait (0 = wait forever) + * @return time (in milliseconds) waited for the semaphore + * or SYS_ARCH_TIMEOUT on timeout */ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); +/** Delete a semaphore + * @param sem semaphore to delete */ +void sys_sem_free(sys_sem_t *sem); +/** Wait for a semaphore - forever/no timeout */ +#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) +#ifndef sys_sem_valid +/** Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_sem_valid(sys_sem_t *sem); +#endif +#ifndef sys_sem_set_invalid +/** Set a semaphore invalid so that sys_sem_valid returns 0 */ +void sys_sem_set_invalid(sys_sem_t *sem); +#endif + +/* Time functions. */ +#ifndef sys_msleep +void sys_msleep(u32_t ms); /* only has a (close to) 1 jiffy resolution. */ +#endif + +/* Mailbox functions. */ + +/** Create a new mbox of specified size + * @param mbox pointer to the mbox to create + * @param size (minimum) number of messages in this mbox + * @return ERR_OK if successful, another err_t otherwise */ +err_t sys_mbox_new(sys_mbox_t *mbox, int size); +/** Post a message to an mbox - may not fail + * -> blocks if full, only used from tasks not from ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +void sys_mbox_post(sys_mbox_t *mbox, void *msg); +/** Try to post a message to an mbox - may fail if full or ISR + * @param mbox mbox to posts the message + * @param msg message to post (ATTENTION: can be NULL) */ +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) + * @return time (in milliseconds) waited for a message, may be 0 if not waited + or SYS_ARCH_TIMEOUT on timeout + * The returned time has to be accurate to prevent timer jitter! */ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); +/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ +#ifndef sys_arch_mbox_tryfetch +/** Wait for a new message to arrive in the mbox + * @param mbox mbox to get a message from + * @param msg pointer where the message is stored + * @return 0 (milliseconds) if a message has been received + * or SYS_MBOX_EMPTY if the mailbox is empty */ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); +#endif +/** For now, we map straight to sys_arch implementation. */ +#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) +/** Delete an mbox + * @param mbox mbox to delete */ +void sys_mbox_free(sys_mbox_t *mbox); +#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) +#ifndef sys_mbox_valid +/** Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid */ +int sys_mbox_valid(sys_mbox_t *mbox); +#endif +#ifndef sys_mbox_set_invalid +/** Set an mbox invalid so that sys_mbox_valid returns 0 */ +void sys_mbox_set_invalid(sys_mbox_t *mbox); +#endif + +/** The only thread function: + * Creates a new thread + * @param name human-readable name for the thread (used for debugging purposes) + * @param thread thread-function + * @param arg parameter passed to 'thread' + * @param stacksize stack size in bytes for the new thread (may be ignored by ports) + * @param prio priority of the new thread (may be ignored by ports) */ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); +//sys_thread_t sys_thread_new_tcm(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio); +#endif /* NO_SYS */ + +/* sys_init() must be called before anything else. */ +void sys_init(void); + +#ifndef sys_jiffies +/** Ticks/jiffies since power up. */ +u32_t sys_jiffies(void); +#endif + +/** Returns the current time in milliseconds, + * may be the same as sys_jiffies or at least based on it. */ +u32_t sys_now(void); + +/* Critical Region Protection */ +/* These functions must be implemented in the sys_arch.c file. + In some implementations they can provide a more light-weight protection + mechanism than using semaphores. Otherwise semaphores can be used for + implementation */ +#ifndef SYS_ARCH_PROTECT +/** SYS_LIGHTWEIGHT_PROT + * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection + * for certain critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#if SYS_LIGHTWEIGHT_PROT + +/** SYS_ARCH_DECL_PROTECT + * declare a protection variable. This macro will default to defining a variable of + * type sys_prot_t. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h. + */ +#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev +/** SYS_ARCH_PROTECT + * Perform a "fast" protect. This could be implemented by + * disabling interrupts for an embedded system or by using a semaphore or + * mutex. The implementation should allow calling SYS_ARCH_PROTECT when + * already protected. The old protection level is returned in the variable + * "lev". This macro will default to calling the sys_arch_protect() function + * which should be implemented in sys_arch.c. If a particular port needs a + * different implementation, then this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() +/** SYS_ARCH_UNPROTECT + * Perform a "fast" set of the protection level to "lev". This could be + * implemented by setting the interrupt level to "lev" within the MACRO or by + * using a semaphore or mutex. This macro will default to calling the + * sys_arch_unprotect() function which should be implemented in + * sys_arch.c. If a particular port needs a different implementation, then + * this macro may be defined in sys_arch.h + */ +#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) +sys_prot_t sys_arch_protect(void); +void sys_arch_unprotect(sys_prot_t pval); + +#else + +#define SYS_ARCH_DECL_PROTECT(lev) +#define SYS_ARCH_PROTECT(lev) +#define SYS_ARCH_UNPROTECT(lev) + +#endif /* SYS_LIGHTWEIGHT_PROT */ + +#endif /* SYS_ARCH_PROTECT */ + +/* + * Macros to set/get and increase/decrease variables in a thread-safe way. + * Use these for accessing variable that are used from more than one thread. + */ + +#ifndef SYS_ARCH_INC +#define SYS_ARCH_INC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var += val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_INC */ + +#ifndef SYS_ARCH_DEC +#define SYS_ARCH_DEC(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var -= val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_DEC */ + +#ifndef SYS_ARCH_GET +#define SYS_ARCH_GET(var, ret) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + ret = var; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_GET */ + +#ifndef SYS_ARCH_SET +#define SYS_ARCH_SET(var, val) do { \ + SYS_ARCH_DECL_PROTECT(old_level); \ + SYS_ARCH_PROTECT(old_level); \ + var = val; \ + SYS_ARCH_UNPROTECT(old_level); \ + } while(0) +#endif /* SYS_ARCH_SET */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_SYS_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp.h new file mode 100644 index 0000000..4a9bb30 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp.h @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_TCP_H +#define LWIP_HDR_TCP_H + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/lwip_ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct tcp_pcb; + +//Realtek add +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ +//Realtek add end + +/** Function prototype for tcp accept callback functions. Called when a new + * connection can be accepted on a listening pcb. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param newpcb The new connection pcb + * @param err An error code if there has been an error accepting. + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); + +/** Function prototype for tcp receive callback functions. Called when data has + * been received. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which received data + * @param p The received data (or NULL when the connection has been closed!) + * @param err An error code if there has been an error receiving + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, + struct pbuf *p, err_t err); + +/** Function prototype for tcp sent callback functions. Called when sent data has + * been acknowledged by the remote side. Use it to free corresponding resources. + * This also means that the pcb has now space available to send new data. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb for which data has been acknowledged + * @param len The amount of bytes acknowledged + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, + u16_t len); + +/** Function prototype for tcp poll callback functions. Called periodically as + * specified by @see tcp_poll. + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb tcp pcb + * @return ERR_OK: try to send some data by calling tcp_output + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + */ +typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); + +/** Function prototype for tcp error callback functions. Called when the pcb + * receives a RST or is unexpectedly closed for any other reason. + * + * @note The corresponding pcb is already freed when this callback is called! + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param err Error code to indicate why the pcb has been closed + * ERR_ABRT: aborted through tcp_abort or by a TCP timer + * ERR_RST: the connection was reset by the remote host + */ +typedef void (*tcp_err_fn)(void *arg, err_t err); + +/** Function prototype for tcp connected callback functions. Called when a pcb + * is connected to the remote side after initiating a connection attempt by + * calling tcp_connect(). + * + * @param arg Additional argument to pass to the callback function (@see tcp_arg()) + * @param tpcb The connection pcb which is connected + * @param err An unused error code, always ERR_OK currently ;-) TODO! + * Only return ERR_ABRT if you have called tcp_abort from within the + * callback function! + * + * @note When a connection attempt fails, the error callback is currently called! + */ +typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); + +#if LWIP_WND_SCALE +#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) +#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) +typedef u32_t tcpwnd_size_t; +typedef u16_t tcpflags_t; +#else +#define RCV_WND_SCALE(pcb, wnd) (wnd) +#define SND_WND_SCALE(pcb, wnd) (wnd) +typedef u16_t tcpwnd_size_t; +typedef u8_t tcpflags_t; +#endif + +enum tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + +#if LWIP_CALLBACK_API + /* Function to call when a listener has been connected. + * @param arg user-supplied argument (tcp_pcb.callback_arg) + * @param pcb a new tcp_pcb that now is connected + * @param err an error argument (TODO: that is current always ERR_OK?) + * @return ERR_OK: accept the new connection, + * any other err_t aborts the new connection + */ +#define DEF_ACCEPT_CALLBACK tcp_accept_fn accept; +#else /* LWIP_CALLBACK_API */ +#define DEF_ACCEPT_CALLBACK +#endif /* LWIP_CALLBACK_API */ + +/** + * members common to struct tcp_pcb and struct tcp_listen_pcb + */ +#define TCP_PCB_COMMON(type) \ + type *next; /* for the linked list */ \ + void *callback_arg; \ + /* the accept callback for listen- and normal pcbs, if LWIP_CALLBACK_API */ \ + DEF_ACCEPT_CALLBACK \ + enum tcp_state state; /* TCP state */ \ + u8_t prio; \ + /* ports are in host byte order */ \ + u16_t local_port + + +/* the TCP protocol control block */ +struct tcp_pcb { +/** common PCB members */ + IP_PCB; +/** protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb); + + /* ports are in host byte order */ + u16_t remote_port; + + tcpflags_t flags; +#define TF_ACK_DELAY ((tcpflags_t)0x0001U) /* Delayed ACK. */ +#define TF_ACK_NOW ((tcpflags_t)0x0002U) /* Immediate ACK. */ +#define TF_INFR ((tcpflags_t)0x0004U) /* In fast recovery. */ +#define TF_TIMESTAMP ((tcpflags_t)0x0008U) /* Timestamp option enabled */ +#define TF_RXCLOSED ((tcpflags_t)0x0010U) /* rx closed by tcp_shutdown */ +#define TF_FIN ((tcpflags_t)0x0020U) /* Connection was closed locally (FIN segment enqueued). */ +#define TF_NODELAY ((tcpflags_t)0x0040U) /* Disable Nagle algorithm */ +#define TF_NAGLEMEMERR ((tcpflags_t)0x0080U) /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ +#if LWIP_WND_SCALE +#define TF_WND_SCALE ((tcpflags_t)0x0100U) /* Window Scale option enabled */ +#endif + + /* the rest of the fields are in host byte order + as we have to do some math with them */ + + /* Timers */ + u8_t polltmr, pollinterval; + u8_t last_timer; + u32_t tmr; + + /* receiver variables */ + u32_t rcv_nxt; /* next seqno expected */ + tcpwnd_size_t rcv_wnd; /* receiver window available */ + tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ + u32_t rcv_ann_right_edge; /* announced right edge of window */ + + /* Retransmission timer. */ + s16_t rtime; + + u16_t mss; /* maximum segment size */ + + /* RTT (round trip time) estimation variables */ + u32_t rttest; /* RTT estimate in 500ms ticks */ + u32_t rtseq; /* sequence number being timed */ + s16_t sa, sv; /* @todo document this */ + + s16_t rto; /* retransmission time-out */ + u8_t nrtx; /* number of retransmissions */ + + /* fast retransmit/recovery */ + u8_t dupacks; + u32_t lastack; /* Highest acknowledged seqno. */ + + /* congestion avoidance/control variables */ + tcpwnd_size_t cwnd; + tcpwnd_size_t ssthresh; + + /* sender variables */ + u32_t snd_nxt; /* next new seqno to be sent */ + u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last + window update. */ + u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ + tcpwnd_size_t snd_wnd; /* sender window */ + tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ + + tcpwnd_size_t acked; + + tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ +#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) + u16_t snd_queuelen; /* Available buffer space for sending (in pbufs). */ + +#if TCP_OVERSIZE + /* Extra bytes available at the end of the last pbuf in unsent. */ + u16_t unsent_oversize; +#endif /* TCP_OVERSIZE */ + + /* These are ordered by sequence number: */ + struct tcp_seg *unsent; /* Unsent (queued) segments. */ + struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ +#if TCP_QUEUE_OOSEQ + struct tcp_seg *ooseq; /* Received out of sequence segments. */ +#endif /* TCP_QUEUE_OOSEQ */ + + struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ + +#if LWIP_CALLBACK_API + /* Function to be called when more send buffer space is available. */ + tcp_sent_fn sent; + /* Function to be called when (in-sequence) data has arrived. */ + tcp_recv_fn recv; + /* Function to be called when a connection has been set up. */ + tcp_connected_fn connected; + /* Function which is called periodically. */ + tcp_poll_fn poll; + /* Function to be called whenever a fatal error occurs. */ + tcp_err_fn errf; +#endif /* LWIP_CALLBACK_API */ + +#if LWIP_TCP_TIMESTAMPS + u32_t ts_lastacksent; + u32_t ts_recent; +#endif /* LWIP_TCP_TIMESTAMPS */ + + /* idle time before KEEPALIVE is sent */ + u32_t keep_idle; +#if LWIP_TCP_KEEPALIVE + u32_t keep_intvl; + u32_t keep_cnt; +#endif /* LWIP_TCP_KEEPALIVE */ + + /* Persist timer counter */ + u8_t persist_cnt; + /* Persist timer back-off */ + u8_t persist_backoff; + + /* KEEPALIVE counter */ + u8_t keep_cnt_sent; + +#if LWIP_WND_SCALE + u8_t snd_scale; + u8_t rcv_scale; +#endif +}; + +struct tcp_pcb_listen { +/* Common members of all PCB types */ + IP_PCB; +/* Protocol specific PCB members */ + TCP_PCB_COMMON(struct tcp_pcb_listen); + +#if TCP_LISTEN_BACKLOG + u8_t backlog; + u8_t accepts_pending; +#endif /* TCP_LISTEN_BACKLOG */ +#if LWIP_IPV6 + u8_t accept_any_ip_version; +#endif /* LWIP_IPV6 */ +}; + +#if LWIP_EVENT_API + +enum lwip_event { + LWIP_EVENT_ACCEPT, + LWIP_EVENT_SENT, + LWIP_EVENT_RECV, + LWIP_EVENT_CONNECTED, + LWIP_EVENT_POLL, + LWIP_EVENT_ERR +}; + +err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, + enum lwip_event, + struct pbuf *p, + u16_t size, + err_t err); + +#endif /* LWIP_EVENT_API */ + +/* Application program's interface: */ +struct tcp_pcb * tcp_new (void); + +void tcp_arg (struct tcp_pcb *pcb, void *arg); +void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); +void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); +void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); +void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); +void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); + +#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) +#define tcp_sndbuf(pcb) ((pcb)->snd_buf) +#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) +#define tcp_nagle_disable(pcb) ((pcb)->flags |= TF_NODELAY) +#define tcp_nagle_enable(pcb) ((pcb)->flags &= (tcpflags_t)~TF_NODELAY) +#define tcp_nagle_disabled(pcb) (((pcb)->flags & TF_NODELAY) != 0) + +#if TCP_LISTEN_BACKLOG +#define tcp_accepted(pcb) do { \ + LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", pcb->state == LISTEN); \ + (((struct tcp_pcb_listen *)(pcb))->accepts_pending--); } while(0) +#else /* TCP_LISTEN_BACKLOG */ +#define tcp_accepted(pcb) LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", \ + (pcb)->state == LISTEN) +#endif /* TCP_LISTEN_BACKLOG */ + +void tcp_recved (struct tcp_pcb *pcb, u16_t len); +err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port, tcp_connected_fn connected); + +struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) + +void tcp_abort (struct tcp_pcb *pcb); +err_t tcp_close (struct tcp_pcb *pcb); +err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); + +/* Flags for "apiflags" parameter in tcp_write */ +#define TCP_WRITE_FLAG_COPY 0x01 +#define TCP_WRITE_FLAG_MORE 0x02 + +err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, + u8_t apiflags); + +void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); + +#define TCP_PRIO_MIN 1 +#define TCP_PRIO_NORMAL 64 +#define TCP_PRIO_MAX 127 + +err_t tcp_output (struct tcp_pcb *pcb); + + +const char* tcp_debug_state_str(enum tcp_state s); + +#if LWIP_IPV6 +struct tcp_pcb * tcp_new_ip6 (void); +#define tcp_bind_ip6(pcb, ip6addr, port) \ + tcp_bind(pcb, ip6_2_ip(ip6addr), port) +#define tcp_connect_ip6(pcb, ip6addr, port, connected) \ + tcp_connect(pcb, ip6_2_ip(ip6addr), port, connected) +struct tcp_pcb * tcp_listen_dual_with_backlog(struct tcp_pcb *pcb, u8_t backlog); +#define tcp_listen_dual(pcb) tcp_listen_dual_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) +#else /* LWIP_IPV6 */ +#define tcp_listen_dual_with_backlog(pcb, backlog) tcp_listen_with_backlog(pcb, backlog) +#define tcp_listen_dual(pcb) tcp_listen(pcb) +#endif /* LWIP_IPV6 */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* LWIP_HDR_TCP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp_impl.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp_impl.h new file mode 100644 index 0000000..ac1a716 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcp_impl.h @@ -0,0 +1,538 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_TCP_IMPL_H +#define LWIP_HDR_TCP_IMPL_H + +#include "lwip/opt.h" + +#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/tcp.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/lwip_ip.h" +#include "lwip/icmp.h" +#include "lwip/err.h" +#include "lwip/ip6.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Functions for interfacing with TCP: */ + +/* Lower layer interface to TCP: */ +void tcp_init (void); /* Initialize this module. */ +void tcp_tmr (void); /* Must be called every + TCP_TMR_INTERVAL + ms. (Typically 250 ms). */ +/* It is also possible to call these two functions at the right + intervals (instead of calling tcp_tmr()). */ +void tcp_slowtmr (void); +void tcp_fasttmr (void); + + +/* Only used by IP to pass a TCP segment to TCP: */ +void tcp_input (struct pbuf *p, struct netif *inp); +/* Used within the TCP code only: */ +struct tcp_pcb * tcp_alloc (u8_t prio); +void tcp_abandon (struct tcp_pcb *pcb, int reset); +err_t tcp_send_empty_ack(struct tcp_pcb *pcb); +void tcp_rexmit (struct tcp_pcb *pcb); +void tcp_rexmit_rto (struct tcp_pcb *pcb); +void tcp_rexmit_fast (struct tcp_pcb *pcb); +u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); +err_t tcp_process_refused_data(struct tcp_pcb *pcb); + +/** + * This is the Nagle algorithm: try to combine user data to send as few TCP + * segments as possible. Only send if + * - no previously transmitted data on the connection remains unacknowledged or + * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or + * - the only unsent segment is at least pcb->mss bytes long (or there is more + * than one unsent segment - with lwIP, this can happen although unsent->len < mss) + * - or if we are in fast-retransmit (TF_INFR) + */ +#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ + ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ + (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ + ((tpcb)->unsent->len >= (tpcb)->mss))) || \ + ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ + ) ? 1 : 0) +#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) + + +#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) +#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) +#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) +#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) +/* is b<=a<=c? */ +#if 0 /* see bug #10548 */ +#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) +#endif +#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) +#define TCP_FIN 0x01U +#define TCP_SYN 0x02U +#define TCP_RST 0x04U +#define TCP_PSH 0x08U +#define TCP_ACK 0x10U +#define TCP_URG 0x20U +#define TCP_ECE 0x40U +#define TCP_CWR 0x80U + +#define TCP_FLAGS 0x3fU + +/* Length of the TCP header, excluding options. */ +#define TCP_HLEN 20 + +#ifndef TCP_TMR_INTERVAL +#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ +#endif /* TCP_TMR_INTERVAL */ + +#ifndef TCP_FAST_INTERVAL +#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ +#endif /* TCP_FAST_INTERVAL */ + +#ifndef TCP_SLOW_INTERVAL +#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ +#endif /* TCP_SLOW_INTERVAL */ + +#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ +#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ + +#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ + +#ifndef TCP_MSL +#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ +#endif + +/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ +#ifndef TCP_KEEPIDLE_DEFAULT +#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ +#endif + +#ifndef TCP_KEEPINTVL_DEFAULT +#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ +#endif + +#ifndef TCP_KEEPCNT_DEFAULT +#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ +#endif + +#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ + +/* Fields are (of course) in network byte order. + * Some fields are converted to host byte order in tcp_input(). + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct tcp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); + PACK_STRUCT_FIELD(u32_t seqno); + PACK_STRUCT_FIELD(u32_t ackno); + PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); + PACK_STRUCT_FIELD(u16_t wnd); + PACK_STRUCT_FIELD(u16_t chksum); + PACK_STRUCT_FIELD(u16_t urgp); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define TCPH_HDRLEN(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) >> 12) +#define TCPH_FLAGS(phdr) (ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS) + +#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | TCPH_FLAGS(phdr)) +#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS((u16_t)(~(u16_t)(TCP_FLAGS)))) | htons(flags)) +#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = htons(((len) << 12) | (flags)) + +#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | htons(flags)) +#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = htons(ntohs((phdr)->_hdrlen_rsvd_flags) | (TCPH_FLAGS(phdr) & ~(flags)) ) + +#define TCP_TCPLEN(seg) ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U)) + +/** Flags used on input processing, not on pcb->flags +*/ +#define TF_RESET (u8_t)0x08U /* Connection was reset. */ +#define TF_CLOSED (u8_t)0x10U /* Connection was successfully closed. */ +#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ + + +#if LWIP_EVENT_API + +#define TCP_EVENT_ACCEPT(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_ACCEPT, NULL, 0, err) +#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_SENT, NULL, space, ERR_OK) +#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, (p), 0, (err)) +#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_RECV, NULL, 0, ERR_OK) +#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_CONNECTED, NULL, 0, (err)) +#define TCP_EVENT_POLL(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ + LWIP_EVENT_POLL, NULL, 0, ERR_OK) +#define TCP_EVENT_ERR(errf,arg,err) lwip_tcp_event((arg), NULL, \ + LWIP_EVENT_ERR, NULL, 0, (err)) + +#else /* LWIP_EVENT_API */ + +#define TCP_EVENT_ACCEPT(pcb,err,ret) \ + do { \ + if((pcb)->accept != NULL) \ + (ret) = (pcb)->accept((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_ARG; \ + } while (0) + +#define TCP_EVENT_SENT(pcb,space,ret) \ + do { \ + if((pcb)->sent != NULL) \ + (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_RECV(pcb,p,err,ret) \ + do { \ + if((pcb)->recv != NULL) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ + } else { \ + (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ + } \ + } while (0) + +#define TCP_EVENT_CLOSED(pcb,ret) \ + do { \ + if(((pcb)->recv != NULL)) { \ + (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ + } else { \ + (ret) = ERR_OK; \ + } \ + } while (0) + +#define TCP_EVENT_CONNECTED(pcb,err,ret) \ + do { \ + if((pcb)->connected != NULL) \ + (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_POLL(pcb,ret) \ + do { \ + if((pcb)->poll != NULL) \ + (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ + else (ret) = ERR_OK; \ + } while (0) + +#define TCP_EVENT_ERR(errf,arg,err) \ + do { \ + if((errf) != NULL) \ + (errf)((arg),(err)); \ + } while (0) + +#endif /* LWIP_EVENT_API */ + +/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ +#if TCP_OVERSIZE && defined(LWIP_DEBUG) +#define TCP_OVERSIZE_DBGCHECK 1 +#else +#define TCP_OVERSIZE_DBGCHECK 0 +#endif + +/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ +#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) + +/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ +struct tcp_seg { + struct tcp_seg *next; /* used when putting segments on a queue */ + struct pbuf *p; /* buffer containing data + TCP header */ + u16_t len; /* the TCP length of this segment */ +#if TCP_OVERSIZE_DBGCHECK + u16_t oversize_left; /* Extra bytes available at the end of the last + pbuf in unsent (used for asserting vs. + tcp_pcb.unsent_oversized only) */ +#endif /* TCP_OVERSIZE_DBGCHECK */ +#if TCP_CHECKSUM_ON_COPY + u16_t chksum; + u8_t chksum_swapped; +#endif /* TCP_CHECKSUM_ON_COPY */ + u8_t flags; +#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ +#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ +#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is + checksummed into 'chksum' */ +#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option */ + struct tcp_hdr *tcphdr; /* the TCP header */ +}; + +#define LWIP_TCP_OPT_EOL 0 +#define LWIP_TCP_OPT_NOP 1 +#define LWIP_TCP_OPT_MSS 2 +#define LWIP_TCP_OPT_WS 3 +#define LWIP_TCP_OPT_TS 8 + +#define LWIP_TCP_OPT_LEN_MSS 4 +#if LWIP_TCP_TIMESTAMPS +#define LWIP_TCP_OPT_LEN_TS 10 +#define LWIP_TCP_OPT_LEN_TS_OUT 12 /* aligned for output (includes NOP padding) */ +#else +#define LWIP_TCP_OPT_LEN_TS_OUT 0 +#endif +#if LWIP_WND_SCALE +#define LWIP_TCP_OPT_LEN_WS 3 +#define LWIP_TCP_OPT_LEN_WS_OUT 4 /* aligned for output (includes NOP padding) */ +#else +#define LWIP_TCP_OPT_LEN_WS_OUT 0 +#endif + +#define LWIP_TCP_OPT_LENGTH(flags) \ + (flags & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \ + (flags & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \ + (flags & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) + +/** This returns a TCP header option for MSS in an u32_t */ +#define TCP_BUILD_MSS_OPTION(mss) htonl(0x02040000 | ((mss) & 0xFFFF)) + +#if LWIP_WND_SCALE +#define TCPWNDSIZE_F U32_F +#define TCPWND_MAX 0xFFFFFFFFU +#else /* LWIP_WND_SCALE */ +#define TCPWNDSIZE_F U16_F +#define TCPWND_MAX 0xFFFFU +#endif /* LWIP_WND_SCALE */ + +/* Global variables: */ +extern struct tcp_pcb *tcp_input_pcb; +extern u32_t tcp_ticks; +extern u8_t tcp_active_pcbs_changed; + +/* The TCP PCB lists. */ +union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ + struct tcp_pcb_listen *listen_pcbs; + struct tcp_pcb *pcbs; +}; +extern struct tcp_pcb *tcp_bound_pcbs; +extern union tcp_listen_pcbs_t tcp_listen_pcbs; +extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a + state in which they accept or send + data. */ +extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ + +extern struct tcp_pcb *tcp_tmp_pcb; /* Only used for temporary storage. */ + +/* Axioms about the above lists: + 1) Every TCP PCB that is not CLOSED is in one of the lists. + 2) A PCB is only in one of the lists. + 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. + 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. +*/ +/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB + with a PCB list or removes a PCB from a list, respectively. */ +#ifndef TCP_DEBUG_PCB_LISTS +#define TCP_DEBUG_PCB_LISTS 0 +#endif +#if TCP_DEBUG_PCB_LISTS +#define TCP_REG(pcbs, npcb) do {\ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ + for(tcp_tmp_pcb = *(pcbs); \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ + } \ + LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ + (npcb)->next = *(pcbs); \ + LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ + *(pcbs) = (npcb); \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + tcp_timer_needed(); \ + } while(0) +#define TCP_RMV(pcbs, npcb) do { \ + LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ + if(*(pcbs) == (npcb)) { \ + *(pcbs) = (*pcbs)->next; \ + } else for(tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + (npcb)->next = NULL; \ + LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ + LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ + } while(0) + +#else /* LWIP_DEBUG */ + +#define TCP_REG(pcbs, npcb) \ + do { \ + (npcb)->next = *pcbs; \ + *(pcbs) = (npcb); \ + tcp_timer_needed(); \ + } while (0) + +#define TCP_RMV(pcbs, npcb) \ + do { \ + if(*(pcbs) == (npcb)) { \ + (*(pcbs)) = (*pcbs)->next; \ + } \ + else { \ + for(tcp_tmp_pcb = *pcbs; \ + tcp_tmp_pcb != NULL; \ + tcp_tmp_pcb = tcp_tmp_pcb->next) { \ + if(tcp_tmp_pcb->next == (npcb)) { \ + tcp_tmp_pcb->next = (npcb)->next; \ + break; \ + } \ + } \ + } \ + (npcb)->next = NULL; \ + } while(0) + +#endif /* LWIP_DEBUG */ + +#define TCP_REG_ACTIVE(npcb) \ + do { \ + TCP_REG(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_RMV_ACTIVE(npcb) \ + do { \ + TCP_RMV(&tcp_active_pcbs, npcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + +#define TCP_PCB_REMOVE_ACTIVE(pcb) \ + do { \ + tcp_pcb_remove(&tcp_active_pcbs, pcb); \ + tcp_active_pcbs_changed = 1; \ + } while (0) + + +/* Internal functions: */ +struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); +void tcp_pcb_purge(struct tcp_pcb *pcb); +void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); + +void tcp_segs_free(struct tcp_seg *seg); +void tcp_seg_free(struct tcp_seg *seg); +struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); + +#define tcp_ack(pcb) \ + do { \ + if((pcb)->flags & TF_ACK_DELAY) { \ + (pcb)->flags &= ~TF_ACK_DELAY; \ + (pcb)->flags |= TF_ACK_NOW; \ + } \ + else { \ + (pcb)->flags |= TF_ACK_DELAY; \ + } \ + } while (0) + +#define tcp_ack_now(pcb) \ + do { \ + (pcb)->flags |= TF_ACK_NOW; \ + } while (0) + +err_t tcp_send_fin(struct tcp_pcb *pcb); +err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); + +void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); + +void tcp_rst_impl(u32_t seqno, u32_t ackno, + ipX_addr_t *local_ip, ipX_addr_t *remote_ip, + u16_t local_port, u16_t remote_port +#if LWIP_IPV6 + , u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_rst(seqno, ackno, local_ip, remote_ip, local_port, remote_port, isipv6) \ + tcp_rst_impl(seqno, ackno, local_ip, remote_ip, local_port, remote_port) +#endif /* LWIP_IPV6 */ + +u32_t tcp_next_iss(void); + +void tcp_keepalive(struct tcp_pcb *pcb); +void tcp_zero_window_probe(struct tcp_pcb *pcb); + +#if TCP_CALCULATE_EFF_SEND_MSS +u16_t tcp_eff_send_mss_impl(u16_t sendmss, ipX_addr_t *dest +#if LWIP_IPV6 + , ipX_addr_t *src, u8_t isipv6 +#endif /* LWIP_IPV6 */ + ); +#if LWIP_IPV6 +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest, src, isipv6) +#else /* LWIP_IPV6 */ +#define tcp_eff_send_mss(sendmss, src, dest, isipv6) tcp_eff_send_mss_impl(sendmss, dest) +#endif /* LWIP_IPV6 */ +#endif /* TCP_CALCULATE_EFF_SEND_MSS */ + +#if LWIP_CALLBACK_API +err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); +#endif /* LWIP_CALLBACK_API */ + +#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG +void tcp_debug_print(struct tcp_hdr *tcphdr); +void tcp_debug_print_flags(u8_t flags); +void tcp_debug_print_state(enum tcp_state s); +void tcp_debug_print_pcbs(void); +s16_t tcp_pcbs_sane(void); +#else +# define tcp_debug_print(tcphdr) +# define tcp_debug_print_flags(flags) +# define tcp_debug_print_state(s) +# define tcp_debug_print_pcbs() +# define tcp_pcbs_sane() 1 +#endif /* TCP_DEBUG */ + +/** External function (implemented in timers.c), called when TCP detects + * that a timer is needed (i.e. active- or time-wait-pcb found). */ +void tcp_timer_needed(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_TCP */ + +#endif /* LWIP_HDR_TCP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcpip.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcpip.h new file mode 100644 index 0000000..3635e81 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/tcpip.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_TCPIP_H +#define LWIP_HDR_TCPIP_H + +#include "lwip/opt.h" + +#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/api_msg.h" +#include "lwip/netifapi.h" +#include "lwip/pppapi.h" +#include "lwip/pbuf.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/lwip_timers.h" +#include "lwip/netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Define this to something that triggers a watchdog. This is called from + * tcpip_thread after processing a message. */ +#ifndef LWIP_TCPIP_THREAD_ALIVE +#define LWIP_TCPIP_THREAD_ALIVE() +#endif + +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_mutex_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) +#ifdef LWIP_DEBUG +#define TCIP_APIMSG_SET_ERR(m, e) (m)->msg.err = e /* catch functions that don't set err */ +#else +#define TCIP_APIMSG_SET_ERR(m, e) +#endif +#if LWIP_NETCONN_SEM_PER_THREAD +#define TCPIP_APIMSG_SET_SEM(m) ((m)->msg.op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET()) +#else +#define TCPIP_APIMSG_SET_SEM(m) +#endif +#define TCPIP_APIMSG_NOERR(m,f) do { \ + TCIP_APIMSG_SET_ERR(m, ERR_VAL); \ + TCPIP_APIMSG_SET_SEM(m); \ + LOCK_TCPIP_CORE(); \ + f(&((m)->msg)); \ + UNLOCK_TCPIP_CORE(); \ +} while(0) +#define TCPIP_APIMSG(m,f,e) do { \ + TCPIP_APIMSG_NOERR(m,f); \ + (e) = (m)->msg.err; \ +} while(0) +#define TCPIP_APIMSG_ACK(m) +#define TCPIP_NETIFAPI(m) tcpip_netifapi_lock(m) +#define TCPIP_NETIFAPI_ACK(m) +#define TCPIP_PPPAPI(m) tcpip_pppapi_lock(m) +#define TCPIP_PPPAPI_ACK(m) +#else /* LWIP_TCPIP_CORE_LOCKING */ +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG_NOERR(m,f) do { (m)->function = f; tcpip_apimsg(m); } while(0) +#define TCPIP_APIMSG(m,f,e) do { (m)->function = f; (e) = tcpip_apimsg(m); } while(0) +#define TCPIP_APIMSG_ACK(m) sys_sem_signal(LWIP_API_MSG_SEM(m)) +#define TCPIP_NETIFAPI(m) tcpip_netifapi(m) +#define TCPIP_NETIFAPI_ACK(m) sys_sem_signal(&m->sem) +#define TCPIP_PPPAPI(m) tcpip_pppapi(m) +#define TCPIP_PPPAPI_ACK(m) sys_sem_signal(&m->sem) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + +#if LWIP_MPU_COMPATIBLE +#define API_VAR_REF(name) (*(name)) +#define API_VAR_DECLARE(type, name) type * name +#define API_VAR_ALLOC(type, pool, name) do { \ + name = (type *)memp_malloc(pool); \ + if (name == NULL) { \ + return ERR_MEM; \ + } \ + } while(0) +#define API_VAR_ALLOC_DONTFAIL(type, pool, name) do { \ + name = (type *)memp_malloc(pool); \ + LWIP_ASSERT("pool empty", name != NULL); \ + } while(0) +#define API_VAR_FREE(pool, name) memp_free(pool, name) +#define API_EXPR_REF(expr) &(expr) +#define API_EXPR_DEREF(expr) expr +#else /* LWIP_MPU_COMPATIBLE */ +#define API_VAR_REF(name) name +#define API_VAR_DECLARE(type, name) type name +#define API_VAR_ALLOC(type, pool, name) +#define API_VAR_ALLOC_DONTFAIL(type, pool, name) +#define API_VAR_FREE(pool, name) +#define API_EXPR_REF(expr) expr +#define API_EXPR_DEREF(expr) *(expr) +#endif /* LWIP_MPU_COMPATIBLE */ + + + +/** Function prototype for the init_done function passed to tcpip_init */ +typedef void (*tcpip_init_done_fn)(void *arg); +/** Function prototype for functions passed to tcpip_callback() */ +typedef void (*tcpip_callback_fn)(void *ctx); + +/* Forward declarations */ +struct tcpip_callback_msg; + +void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); + +#if LWIP_NETCONN || LWIP_SOCKET +err_t tcpip_apimsg(struct api_msg *apimsg); +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + +err_t tcpip_input(struct pbuf *p, struct netif *inp); + +#if LWIP_NETIF_API +err_t tcpip_netifapi(struct netifapi_msg *netifapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_NETIF_API */ + +#if LWIP_PPP_API +err_t tcpip_pppapi(struct pppapi_msg *pppapimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_pppapi_lock(struct pppapi_msg *pppapimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ +#endif /* LWIP_PPP_API */ + +err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); +#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) + +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + +/* free pbufs or heap memory from another context without blocking */ +err_t pbuf_free_callback(struct pbuf *p); +err_t mem_free_callback(void *m); + +#if LWIP_TCPIP_TIMEOUT +err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); +err_t tcpip_untimeout(sys_timeout_handler h, void *arg); +#endif /* LWIP_TCPIP_TIMEOUT */ + +enum tcpip_msg_type { +#if LWIP_NETCONN || LWIP_SOCKET + TCPIP_MSG_API, +#endif /* LWIP_NETCONN || LWIP_SOCKET */ + TCPIP_MSG_INPKT, +#if LWIP_NETIF_API + TCPIP_MSG_NETIFAPI, +#endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API + TCPIP_MSG_PPPAPI, +#endif /* LWIP_PPP_API */ +#if LWIP_TCPIP_TIMEOUT + TCPIP_MSG_TIMEOUT, + TCPIP_MSG_UNTIMEOUT, +#endif /* LWIP_TCPIP_TIMEOUT */ + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC +}; + +struct tcpip_msg { + enum tcpip_msg_type type; + sys_sem_t *sem; + union { +#if LWIP_NETCONN || LWIP_SOCKET + struct api_msg *apimsg; +#endif /* LWIP_NETCONN || LWIP_SOCKET */ +#if LWIP_NETIF_API + struct netifapi_msg *netifapimsg; +#endif /* LWIP_NETIF_API */ +#if LWIP_PPP_API + struct pppapi_msg *pppapimsg; +#endif /* LWIP_PPP_API */ + struct { + struct pbuf *p; + struct netif *netif; + } inp; + struct { + tcpip_callback_fn function; + void *ctx; + } cb; +#if LWIP_TCPIP_TIMEOUT + struct { + u32_t msecs; + sys_timeout_handler h; + void *arg; + } tmo; +#endif /* LWIP_TCPIP_TIMEOUT */ + } msg; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* !NO_SYS */ + +#endif /* LWIP_HDR_TCPIP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/udp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/udp.h new file mode 100644 index 0000000..7593ca1 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/lwip/udp.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_UDP_H +#define LWIP_HDR_UDP_H + +#include "lwip/opt.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/ip_addr.h" +#include "lwip/lwip_ip.h" +#include "lwip/ip6_addr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define UDP_HLEN 8 + +/* Fields are (of course) in network byte order. */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct udp_hdr { + PACK_STRUCT_FIELD(u16_t src); + PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ + PACK_STRUCT_FIELD(u16_t len); + PACK_STRUCT_FIELD(u16_t chksum); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define UDP_FLAGS_NOCHKSUM 0x01U +#define UDP_FLAGS_UDPLITE 0x02U +#define UDP_FLAGS_CONNECTED 0x04U +#define UDP_FLAGS_MULTICAST_LOOP 0x08U + +struct udp_pcb; + +/** Function prototype for udp pcb receive callback functions + * addr and port are in same byte order as in the pcb + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * ATTENTION: Be aware that 'addr' points into the pbuf 'p' so freeing this pbuf + * makes 'addr' invalid, too. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IP address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *addr, u16_t port); + +#if LWIP_IPV6 +/** Function prototype for udp pcb IPv6 receive callback functions + * The callback is responsible for freeing the pbuf + * if it's not used any more. + * + * @param arg user supplied argument (udp_pcb.recv_arg) + * @param pcb the udp_pcb which received data + * @param p the packet buffer that was received + * @param addr the remote IPv6 address from which the packet was received + * @param port the remote port from which the packet was received + */ +typedef void (*udp_recv_ip6_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, + ip6_addr_t *addr, u16_t port); +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV6 +#define UDP_PCB_RECV_IP6 udp_recv_ip6_fn ip6; +#else +#define UDP_PCB_RECV_IP6 +#endif /* LWIP_IPV6 */ + +struct udp_pcb { +/* Common members of all PCB types */ + IP_PCB; + +/* Protocol specific PCB members */ + + struct udp_pcb *next; + + u8_t flags; + /** ports are in host byte order */ + u16_t local_port, remote_port; + +#if LWIP_IGMP + /** outgoing network interface for multicast packets */ + ip_addr_t multicast_ip; +#endif /* LWIP_IGMP */ + +#if LWIP_UDPLITE + /** used for UDP_LITE only */ + u16_t chksum_len_rx, chksum_len_tx; +#endif /* LWIP_UDPLITE */ + + /** receive callback function */ + union { + udp_recv_fn ip4; + UDP_PCB_RECV_IP6 + }recv; + /** user-supplied argument for the recv callback */ + void *recv_arg; +}; +/* udp_pcbs export for external reference (e.g. SNMP agent) */ +extern struct udp_pcb *udp_pcbs; + +/* The following functions is the application layer interface to the + UDP code. */ +struct udp_pcb * udp_new (void); +void udp_remove (struct udp_pcb *pcb); +err_t udp_bind (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +err_t udp_connect (struct udp_pcb *pcb, ip_addr_t *ipaddr, + u16_t port); +void udp_disconnect (struct udp_pcb *pcb); +void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, + void *recv_arg); +err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif); +err_t udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif, ip_addr_t *src_ip); +err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port); +err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); + +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP +err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + struct netif *netif, u8_t have_chksum, + u16_t chksum); +err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, + u8_t have_chksum, u16_t chksum); +err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, + u8_t have_chksum, u16_t chksum); +err_t udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, + ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, + u8_t have_chksum, u16_t chksum, ip_addr_t *src_ip); +#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ + +#define udp_flags(pcb) ((pcb)->flags) +#define udp_setflags(pcb, f) ((pcb)->flags = (f)) + +/* The following functions are the lower layer interface to UDP. */ +void udp_input (struct pbuf *p, struct netif *inp); + +void udp_init (void); + +#if LWIP_IPV6 +struct udp_pcb * udp_new_ip6(void); +#define udp_bind_ip6(pcb, ip6addr, port) \ + udp_bind(pcb, ip6_2_ip(ip6addr), port) +#define udp_connect_ip6(pcb, ip6addr, port) \ + udp_connect(pcb, ip6_2_ip(ip6addr), port) +#define udp_recv_ip6(pcb, recv_ip6_fn, recv_arg) \ + udp_recv(pcb, (udp_recv_fn)recv_ip6_fn, recv_arg) +#define udp_sendto_ip6(pcb, pbuf, ip6addr, port) \ + udp_sendto(pcb, pbuf, ip6_2_ip(ip6addr), port) +#define udp_sendto_if_ip6(pcb, pbuf, ip6addr, port, netif) \ + udp_sendto_if(pcb, pbuf, ip6_2_ip(ip6addr), port, netif) +#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP +#define udp_sendto_chksum_ip6(pcb, pbuf, ip6addr, port, have_chk, chksum) \ + udp_sendto_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, have_chk, chksum) +#define udp_sendto_if_chksum_ip6(pcb, pbuf, ip6addr, port, netif, have_chk, chksum) \ + udp_sendto_if_chksum(pcb, pbuf, ip6_2_ip(ip6addr), port, netif, have_chk, chksum) +#endif /*LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ +#endif /* LWIP_IPV6 */ + +#if UDP_DEBUG +void udp_debug_print(struct udp_hdr *udphdr); +#else +#define udp_debug_print(udphdr) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_UDP */ + +#endif /* LWIP_HDR_UDP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/etharp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/etharp.h new file mode 100644 index 0000000..39f148a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/etharp.h @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +#ifndef LWIP_HDR_NETIF_ETHARP_H +#define LWIP_HDR_NETIF_ETHARP_H + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/ip_addr.h" +#include "lwip/netif.h" +#include "lwip/lwip_ip.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ETHARP_HWADDR_LEN +#define ETHARP_HWADDR_LEN 6 +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct eth_addr { + PACK_STRUCT_FLD_8(u8_t addr[ETHARP_HWADDR_LEN]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** Ethernet header */ +struct eth_hdr { +#if ETH_PAD_SIZE + PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]); +#endif + PACK_STRUCT_FLD_S(struct eth_addr dest); + PACK_STRUCT_FLD_S(struct eth_addr src); + PACK_STRUCT_FIELD(u16_t type); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) + +#if ETHARP_SUPPORT_VLAN + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** VLAN header inserted between ethernet header and payload + * if 'type' in ethernet header is ETHTYPE_VLAN. + * See IEEE802.Q */ +struct eth_vlan_hdr { + PACK_STRUCT_FIELD(u16_t prio_vid); + PACK_STRUCT_FIELD(u16_t tpid); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_VLAN_HDR 4 +#define VLAN_ID(vlan_hdr) (htons((vlan_hdr)->prio_vid) & 0xFFF) + +#endif /* ETHARP_SUPPORT_VLAN */ + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +/** the ARP message, see RFC 826 ("Packet format") */ +struct etharp_hdr { + PACK_STRUCT_FIELD(u16_t hwtype); + PACK_STRUCT_FIELD(u16_t proto); + PACK_STRUCT_FLD_8(u8_t hwlen); + PACK_STRUCT_FLD_8(u8_t protolen); + PACK_STRUCT_FIELD(u16_t opcode); + PACK_STRUCT_FLD_S(struct eth_addr shwaddr); + PACK_STRUCT_FLD_S(struct ip_addr2 sipaddr); + PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); + PACK_STRUCT_FLD_S(struct ip_addr2 dipaddr); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#define SIZEOF_ETHARP_HDR 28 + +#define SIZEOF_ETHARP_PACKET (SIZEOF_ETH_HDR + SIZEOF_ETHARP_HDR) +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) +#define SIZEOF_ETHARP_PACKET_TX (SIZEOF_ETHARP_PACKET + SIZEOF_VLAN_HDR) +#else /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ +#define SIZEOF_ETHARP_PACKET_TX SIZEOF_ETHARP_PACKET +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + +/** 1 seconds period */ +#define ARP_TMR_INTERVAL 1000 + +#define ETHTYPE_ARP 0x0806U +#define ETHTYPE_IP 0x0800U +#define ETHTYPE_VLAN 0x8100U +#define ETHTYPE_IPV6 0x86DDU +#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */ +#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */ + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables + * or known to be 32-bit aligned within the protocol header. */ +#ifndef ETHADDR32_COPY +#define ETHADDR32_COPY(dst, src) SMEMCPY(dst, src, ETHARP_HWADDR_LEN) +#endif + +/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local + * variables and known to be 16-bit aligned within the protocol header. */ +#ifndef ETHADDR16_COPY +#define ETHADDR16_COPY(dst, src) SMEMCPY(dst, src, ETHARP_HWADDR_LEN) +#endif + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** ARP message types (opcodes) */ +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) + * to a filter function that returns the correct netif when using multiple + * netifs on one hardware interface where the netif's low-level receive + * routine cannot decide for the correct netif (e.g. when mapping multiple + * IP addresses to one hardware interface). + */ +#ifndef LWIP_ARP_FILTER_NETIF +#define LWIP_ARP_FILTER_NETIF 0 +#endif + +#if ARP_QUEUEING +/** struct for queueing outgoing packets for unknown address + * defined here to be accessed by memp.h + */ +struct etharp_q_entry { + struct etharp_q_entry *next; + struct pbuf *p; +}; +#endif /* ARP_QUEUEING */ + +#define etharp_init() /* Compatibility define, no init needed. */ +void etharp_tmr(void); +s8_t etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret); +err_t etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr); +err_t etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q); +err_t etharp_request(struct netif *netif, ip_addr_t *ipaddr); +/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; + * this is an ARP packet sent by a node in order to spontaneously cause other + * nodes to update an entry in their ARP cache. + * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ +#define etharp_gratuitous(netif) etharp_request((netif), &(netif)->ip_addr) +void etharp_cleanup_netif(struct netif *netif); + +#if ETHARP_SUPPORT_STATIC_ENTRIES +err_t etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr); +err_t etharp_remove_static_entry(ip_addr_t *ipaddr); +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_AUTOIP +err_t etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode); +#endif /* LWIP_AUTOIP */ + +#endif /* LWIP_ARP */ + +err_t ethernet_input(struct pbuf *p, struct netif *netif); + +#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETHARP_HWADDR_LEN) == 0) + +extern const struct eth_addr ethbroadcast, ethzero; + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_ARP || LWIP_ETHERNET */ + +#endif /* LWIP_HDR_NETIF_ARP_H */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/loopif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/loopif.h new file mode 100644 index 0000000..e69de29 diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ccp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ccp.h new file mode 100644 index 0000000..f106cb5 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ccp.h @@ -0,0 +1,57 @@ +/* + * ccp.h - Definitions for PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +typedef struct ccp_options { + bool bsd_compress; /* do BSD Compress? */ + bool deflate; /* do Deflate? */ + bool predictor_1; /* do Predictor-1? */ + bool predictor_2; /* do Predictor-2? */ + bool deflate_correct; /* use correct code for deflate? */ + bool deflate_draft; /* use draft RFC code for deflate? */ + bool mppe; /* do MPPE? */ + u_short bsd_bits; /* # bits/code for BSD Compress */ + u_short deflate_size; /* lg(window size) for Deflate */ + short method; /* code for chosen compression method */ +} ccp_options; + +extern fsm ccp_fsm[]; +extern ccp_options ccp_wantoptions[]; +extern ccp_options ccp_gotoptions[]; +extern ccp_options ccp_allowoptions[]; +extern ccp_options ccp_hisoptions[]; + +extern const struct protent ccp_protent; + +#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-md5.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-md5.h new file mode 100644 index 0000000..a05a157 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-md5.h @@ -0,0 +1,36 @@ +/* + * chap-md5.h - New CHAP/MD5 implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +extern const struct chap_digest_type md5_digest; + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-new.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-new.h new file mode 100644 index 0000000..5753fb6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap-new.h @@ -0,0 +1,193 @@ +/* + * chap-new.c - New CHAP implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef CHAP_H +#define CHAP_H + +#include "ppp.h" + +/* + * CHAP packets begin with a standard header with code, id, len (2 bytes). + */ +#define CHAP_HDRLEN 4 + +/* + * Values for the code field. + */ +#define CHAP_CHALLENGE 1 +#define CHAP_RESPONSE 2 +#define CHAP_SUCCESS 3 +#define CHAP_FAILURE 4 + +/* + * CHAP digest codes. + */ +#define CHAP_MD5 5 +#if MSCHAP_SUPPORT +#define CHAP_MICROSOFT 0x80 +#define CHAP_MICROSOFT_V2 0x81 +#endif /* MSCHAP_SUPPORT */ + +/* + * Semi-arbitrary limits on challenge and response fields. + */ +#define MAX_CHALLENGE_LEN 64 +#define MAX_RESPONSE_LEN 64 + +/* + * These limits apply to challenge and response packets we send. + * The +4 is the +1 that we actually need rounded up. + */ +#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) +#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) + +/* bitmask of supported algorithms */ +#if MSCHAP_SUPPORT +#define MDTYPE_MICROSOFT_V2 0x1 +#define MDTYPE_MICROSOFT 0x2 +#endif /* MSCHAP_SUPPORT */ +#define MDTYPE_MD5 0x4 +#define MDTYPE_NONE 0 + +#if MSCHAP_SUPPORT +/* Return the digest alg. ID for the most preferred digest type. */ +#define CHAP_DIGEST(mdtype) \ + ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ + ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ + ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ + 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_DIGEST(mdtype) \ + ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ + +/* Return the bit flag (lsb set) for our most preferred digest type. */ +#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) + +/* Return the bit flag for a given digest algorithm ID. */ +#if MSCHAP_SUPPORT +#define CHAP_MDTYPE_D(digest) \ + ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ + ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ + ((digest) == CHAP_MD5)? MDTYPE_MD5: \ + 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_MDTYPE_D(digest) \ + ((digest) == CHAP_MD5)? MDTYPE_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ + +/* Can we do the requested digest? */ +#if MSCHAP_SUPPORT +#define CHAP_CANDIGEST(mdtype, digest) \ + ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ + ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ + ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ + 0 +#else /* !MSCHAP_SUPPORT */ +#define CHAP_CANDIGEST(mdtype, digest) \ + ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ + 0 +#endif /* MSCHAP_SUPPORT */ + +/* + * The code for each digest type has to supply one of these. + */ +struct chap_digest_type { + int code; + +#if PPP_SERVER + /* + * Note: challenge and response arguments below are formatted as + * a length byte followed by the actual challenge/response data. + */ + void (*generate_challenge)(unsigned char *challenge); + int (*verify_response)(int id, const char *name, + const unsigned char *secret, int secret_len, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space); +#endif /* PPP_SERVER */ + void (*make_response)(unsigned char *response, int id, const char *our_name, + const unsigned char *challenge, const char *secret, int secret_len, + const unsigned char *priv); + int (*check_success)(unsigned char *pkt, int len, unsigned char *priv); + void (*handle_failure)(unsigned char *pkt, int len); +}; + +/* + * Each interface is described by chap structure. + */ +#if CHAP_SUPPORT +typedef struct chap_client_state { + u8_t flags; + const char *name; + const struct chap_digest_type *digest; + unsigned char priv[64]; /* private area for digest's use */ +} chap_client_state; + +#if PPP_SERVER +typedef struct chap_server_state { + u8_t flags; + int id; + const char *name; + const struct chap_digest_type *digest; + int challenge_xmits; + int challenge_pktlen; + unsigned char challenge[CHAL_MAX_PKTLEN]; + char message[256]; +} chap_server_state; +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPORT */ + +#if 0 /* UNUSED */ +/* Hook for a plugin to validate CHAP challenge */ +extern int (*chap_verify_hook)(char *name, char *ourname, int id, + const struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space); +#endif /* UNUSED */ + +#if PPP_SERVER +/* Called by authentication code to start authenticating the peer. */ +extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code); +#endif /* PPP_SERVER */ + +/* Called by auth. code to start authenticating us to the peer. */ +extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code); + +/* Represents the CHAP protocol to the main pppd code */ +extern const struct protent chap_protent; + +#endif /* CHAP_H */ +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap_ms.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap_ms.h new file mode 100644 index 0000000..a366e47 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/chap_ms.h @@ -0,0 +1,115 @@ +/* + * chap_ms.h - Challenge Handshake Authentication Protocol definitions. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef __CHAPMS_INCLUDE__ + +#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ +#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ + +#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ +#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ +#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ + /* as ASCII */ + +/* Error codes for MS-CHAP failure messages. */ +#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 +#define MS_CHAP_ERROR_ACCT_DISABLED 647 +#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 +#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 +#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 +#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 + +/* + * Offsets within the response field for MS-CHAP + */ +#define MS_CHAP_LANMANRESP 0 +#define MS_CHAP_LANMANRESP_LEN 24 +#define MS_CHAP_NTRESP 24 +#define MS_CHAP_NTRESP_LEN 24 +#define MS_CHAP_USENT 48 + +/* + * Offsets within the response field for MS-CHAP2 + */ +#define MS_CHAP2_PEER_CHALLENGE 0 +#define MS_CHAP2_PEER_CHAL_LEN 16 +#define MS_CHAP2_RESERVED_LEN 8 +#define MS_CHAP2_NTRESP 24 +#define MS_CHAP2_NTRESP_LEN 24 +#define MS_CHAP2_FLAGS 48 + +#ifdef MPPE +#include "mppe.h" /* MPPE_MAX_KEY_LEN */ +extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +extern int mppe_keys_set; + +/* These values are the RADIUS attribute values--see RFC 2548. */ +#define MPPE_ENC_POL_ENC_ALLOWED 1 +#define MPPE_ENC_POL_ENC_REQUIRED 2 +#define MPPE_ENC_TYPES_RC4_40 2 +#define MPPE_ENC_TYPES_RC4_128 4 + +/* used by plugins (using above values) */ +extern void set_mppe_enc_types(int, int); +#endif + +/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ +#define MS_CHAP2_AUTHENTICATEE 0 +#define MS_CHAP2_AUTHENTICATOR 1 + +void ChapMS (u_char *, char *, int, u_char *); +void ChapMS2 (u_char *, u_char *, char *, char *, int, + u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); +#ifdef MPPE +void mppe_set_keys (u_char *, u_char[MD4_SIGNATURE_SIZE]); +void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer); +#endif + +void ChallengeHash (u_char[16], u_char *, char *, u_char[8]); + +void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); + +extern const struct chap_digest_type chapms_digest; +extern const struct chap_digest_type chapms2_digest; + +#define __CHAPMS_INCLUDE__ +#endif /* __CHAPMS_INCLUDE__ */ + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eap.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eap.h new file mode 100644 index 0000000..cab6901 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eap.h @@ -0,0 +1,168 @@ +/* + * eap.h - Extensible Authentication Protocol for PPP (RFC 2284) + * + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + * + * Non-exclusive rights to redistribute, modify, translate, and use + * this software in source and binary forms, in whole or in part, is + * hereby granted, provided that the above copyright notice is + * duplicated in any source form, and that neither the name of the + * copyright holder nor the author is used to endorse or promote + * products derived from this software. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Original version by James Carlson + * + * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPP_EAP_H +#define PPP_EAP_H + +#include "ppp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Packet header = Code, id, length. + */ +#define EAP_HEADERLEN 4 + + +/* EAP message codes. */ +#define EAP_REQUEST 1 +#define EAP_RESPONSE 2 +#define EAP_SUCCESS 3 +#define EAP_FAILURE 4 + +/* EAP types */ +#define EAPT_IDENTITY 1 +#define EAPT_NOTIFICATION 2 +#define EAPT_NAK 3 /* (response only) */ +#define EAPT_MD5CHAP 4 +#define EAPT_OTP 5 /* One-Time Password; RFC 1938 */ +#define EAPT_TOKEN 6 /* Generic Token Card */ +/* 7 and 8 are unassigned. */ +#define EAPT_RSA 9 /* RSA Public Key Authentication */ +#define EAPT_DSS 10 /* DSS Unilateral */ +#define EAPT_KEA 11 /* KEA */ +#define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */ +#define EAPT_TLS 13 /* EAP-TLS */ +#define EAPT_DEFENDER 14 /* Defender Token (AXENT) */ +#define EAPT_W2K 15 /* Windows 2000 EAP */ +#define EAPT_ARCOT 16 /* Arcot Systems */ +#define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */ +#define EAPT_NOKIACARD 18 /* Nokia IP smart card */ +#define EAPT_SRP 19 /* Secure Remote Password */ +/* 20 is deprecated */ + +/* EAP SRP-SHA1 Subtypes */ +#define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ +#define EAPSRP_CKEY 1 /* Response 1 - Client Key */ +#define EAPSRP_SKEY 2 /* Request 2 - Server Key */ +#define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */ +#define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */ +#define EAPSRP_ACK 3 /* Response 3 - final ack */ +#define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */ + +#define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */ + +#define SRP_PSEUDO_ID "pseudo_" +#define SRP_PSEUDO_LEN 7 + +#define MD5_SIGNATURE_SIZE 16 +#define EAP_MIN_CHALLENGE_LENGTH 16 +#define EAP_MAX_CHALLENGE_LENGTH 24 + +#define EAP_STATES \ + "Initial", "Pending", "Closed", "Listen", "Identify", \ + "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" + +#define eap_client_active(pcb) ((pcb)->eap.es_client.ea_state == eapListen) +#if PPP_SERVER +#define eap_server_active(pcb) \ + ((pcb)->eap.es_server.ea_state >= eapIdentify && \ + (pcb)->eap.es_server.ea_state <= eapMD5Chall) +#endif /* PPP_SERVER */ + +/* + * Complete EAP state for one PPP session. + */ +enum eap_state_code { + eapInitial = 0, /* No EAP authentication yet requested */ + eapPending, /* Waiting for LCP (no timer) */ + eapClosed, /* Authentication not in use */ + eapListen, /* Client ready (and timer running) */ + eapIdentify, /* EAP Identify sent */ + eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ + eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ + eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ + eapMD5Chall, /* Sent MD5-Challenge */ + eapOpen, /* Completed authentication */ + eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ + eapBadAuth /* Failed authentication */ +}; + +struct eap_auth { + const char *ea_name; /* Our name */ + char *ea_peer; /* Peer's name */ + void *ea_session; /* Authentication library linkage */ + u_char *ea_skey; /* Shared encryption key */ + u_short ea_namelen; /* Length of our name */ + u_short ea_peerlen; /* Length of peer's name */ + enum eap_state_code ea_state; + u_char ea_id; /* Current id */ + u_char ea_requests; /* Number of Requests sent/received */ + u_char ea_responses; /* Number of Responses */ + u_char ea_type; /* One of EAPT_* */ + u32_t ea_keyflags; /* SRP shared key usage flags */ +}; + +#ifndef EAP_MAX_CHALLENGE_LENGTH +#define EAP_MAX_CHALLENGE_LENGTH 24 +#endif +typedef struct eap_state { + struct eap_auth es_client; /* Client (authenticatee) data */ +#if PPP_SERVER + struct eap_auth es_server; /* Server (authenticator) data */ +#endif /* PPP_SERVER */ + int es_savedtime; /* Saved timeout */ + int es_rechallenge; /* EAP rechallenge interval */ + int es_lwrechallenge; /* SRP lightweight rechallenge inter */ + u8_t es_usepseudo; /* Use SRP Pseudonym if offered one */ + int es_usedpseudo; /* Set if we already sent PN */ + int es_challen; /* Length of challenge string */ + u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; +} eap_state; + +/* + * Timeouts. + */ +#if 0 /* moved to opt.h */ +#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ +#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ +#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ +#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ +#endif /* moved to opt.h */ + +void eap_authwithpeer(ppp_pcb *pcb, const char *localname); +void eap_authpeer(ppp_pcb *pcb, const char *localname); + +extern const struct protent eap_protent; + +#ifdef __cplusplus +} +#endif + +#endif /* PPP_EAP_H */ + +#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ecp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ecp.h new file mode 100644 index 0000000..cba6678 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ecp.h @@ -0,0 +1,50 @@ +/* + * ecp.h - Definitions for PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +typedef struct ecp_options { + bool required; /* Is ECP required? */ + unsigned enctype; /* Encryption type */ +} ecp_options; + +extern fsm ecp_fsm[]; +extern ecp_options ecp_wantoptions[]; +extern ecp_options ecp_gotoptions[]; +extern ecp_options ecp_allowoptions[]; +extern ecp_options ecp_hisoptions[]; + +extern const struct protent ecp_protent; + +#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eui64.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eui64.h new file mode 100644 index 0000000..dffb5e4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/eui64.h @@ -0,0 +1,94 @@ +/* + * eui64.h - EUI64 routines for IPv6CP. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ +*/ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef __EUI64_H__ +#define __EUI64_H__ + +/* + * TODO: + * + * Maybe this should be done by processing struct in6_addr directly... + */ +typedef union +{ + u8_t e8[8]; + u16_t e16[4]; + u32_t e32[2]; +} eui64_t; + +#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) +#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ + ((e).e32[1] == (o).e32[1])) +#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; + +#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) + +#define eui64_magic(e) do { \ + (e).e32[0] = magic(); \ + (e).e32[1] = magic(); \ + (e).e8[0] &= ~2; \ + } while (0) +#define eui64_magic_nz(x) do { \ + eui64_magic(x); \ + } while (eui64_iszero(x)) +#define eui64_magic_ne(x, y) do { \ + eui64_magic(x); \ + } while (eui64_equals(x, y)) + +#define eui64_get(ll, cp) do { \ + eui64_copy((*cp), (ll)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_put(ll, cp) do { \ + eui64_copy((ll), (*cp)); \ + (cp) += sizeof(eui64_t); \ + } while (0) + +#define eui64_set32(e, l) do { \ + (e).e32[0] = 0; \ + (e).e32[1] = htonl(l); \ + } while (0) +#define eui64_setlo32(e, l) eui64_set32(e, l) + +char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ + +#endif /* __EUI64_H__ */ +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/fsm.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/fsm.h new file mode 100644 index 0000000..fda2d6e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/fsm.h @@ -0,0 +1,175 @@ +/* + * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef FSM_H +#define FSM_H + +#include "ppp.h" + +/* + * Packet header = Code, id, length. + */ +#define HEADERLEN 4 + + +/* + * CP (LCP, IPCP, etc.) codes. + */ +#define CONFREQ 1 /* Configuration Request */ +#define CONFACK 2 /* Configuration Ack */ +#define CONFNAK 3 /* Configuration Nak */ +#define CONFREJ 4 /* Configuration Reject */ +#define TERMREQ 5 /* Termination Request */ +#define TERMACK 6 /* Termination Ack */ +#define CODEREJ 7 /* Code Reject */ + + +/* + * Each FSM is described by an fsm structure and fsm callbacks. + */ +typedef struct fsm { + ppp_pcb *pcb; /* PPP Interface */ + const struct fsm_callbacks *callbacks; /* Callback routines */ + const char *term_reason; /* Reason for closing protocol */ + u8_t seen_ack; /* Have received valid Ack/Nak/Rej to Req */ + /* -- This is our only flag, we might use u_int :1 if we have more flags */ + u16_t protocol; /* Data Link Layer Protocol field value */ + u8_t state; /* State */ + u8_t flags; /* Contains option bits */ + u8_t id; /* Current id */ + u8_t reqid; /* Current request id */ + u8_t retransmits; /* Number of retransmissions left */ + u8_t nakloops; /* Number of nak loops since last ack */ + u8_t rnakloops; /* Number of naks received */ + u8_t maxnakloops; /* Maximum number of nak loops tolerated + (necessary because IPCP require a custom large max nak loops value) */ + u8_t term_reason_len; /* Length of term_reason */ +} fsm; + + +typedef struct fsm_callbacks { + void (*resetci) /* Reset our Configuration Information */ + (fsm *); + int (*cilen) /* Length of our Configuration Information */ + (fsm *); + void (*addci) /* Add our Configuration Information */ + (fsm *, u_char *, int *); + int (*ackci) /* ACK our Configuration Information */ + (fsm *, u_char *, int); + int (*nakci) /* NAK our Configuration Information */ + (fsm *, u_char *, int, int); + int (*rejci) /* Reject our Configuration Information */ + (fsm *, u_char *, int); + int (*reqci) /* Request peer's Configuration Information */ + (fsm *, u_char *, int *, int); + void (*up) /* Called when fsm reaches PPP_FSM_OPENED state */ + (fsm *); + void (*down) /* Called when fsm leaves PPP_FSM_OPENED state */ + (fsm *); + void (*starting) /* Called when we want the lower layer */ + (fsm *); + void (*finished) /* Called when we don't want the lower layer */ + (fsm *); + void (*protreject) /* Called when Protocol-Reject received */ + (int); + void (*retransmit) /* Retransmission is necessary */ + (fsm *); + int (*extcode) /* Called when unknown code received */ + (fsm *, int, int, u_char *, int); + const char *proto_name; /* String name for protocol (for messages) */ +} fsm_callbacks; + + +/* + * Link states. + */ +#define PPP_FSM_INITIAL 0 /* Down, hasn't been opened */ +#define PPP_FSM_STARTING 1 /* Down, been opened */ +#define PPP_FSM_CLOSED 2 /* Up, hasn't been opened */ +#define PPP_FSM_STOPPED 3 /* Open, waiting for down event */ +#define PPP_FSM_CLOSING 4 /* Terminating the connection, not open */ +#define PPP_FSM_STOPPING 5 /* Terminating, but open */ +#define PPP_FSM_REQSENT 6 /* We've sent a Config Request */ +#define PPP_FSM_ACKRCVD 7 /* We've received a Config Ack */ +#define PPP_FSM_ACKSENT 8 /* We've sent a Config Ack */ +#define PPP_FSM_OPENED 9 /* Connection available */ + + +/* + * Flags - indicate options controlling FSM operation + */ +#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ +#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ +#define OPT_SILENT 4 /* Wait for peer to speak first */ + + +/* + * Timeouts. + */ +#if 0 /* moved to opt.h */ +#define DEFTIMEOUT 3 /* Timeout time in seconds */ +#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ +#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ +#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ +#endif /* moved to opt.h */ + + +/* + * Prototypes + */ +void fsm_init(fsm *f); +void fsm_lowerup(fsm *f); +void fsm_lowerdown(fsm *f); +void fsm_open(fsm *f); +void fsm_close(fsm *f, const char *reason); +void fsm_input(fsm *f, u_char *inpacket, int l); +void fsm_protreject(fsm *f); +void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen); + + +#endif /* FSM_H */ +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipcp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipcp.h new file mode 100644 index 0000000..b5f2334 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipcp.h @@ -0,0 +1,107 @@ +/* + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef IPCP_H +#define IPCP_H + +/* + * Options. + */ +#define CI_ADDRS 1 /* IP Addresses */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ +#define CI_ADDR 3 + +#define CI_MS_DNS1 129 /* Primary DNS value */ +#define CI_MS_WINS1 130 /* Primary WINS value */ +#define CI_MS_DNS2 131 /* Secondary DNS value */ +#define CI_MS_WINS2 132 /* Secondary WINS value */ + +#define MAX_STATES 16 /* from slcompress.h */ + +#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ +#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ +#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ + /* maxslot and slot number compression) */ + +#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ +#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ + /* compression option*/ + +typedef struct ipcp_options { + unsigned int neg_addr :1; /* Negotiate IP Address? */ + unsigned int old_addrs :1; /* Use old (IP-Addresses) option? */ + unsigned int req_addr :1; /* Ask peer to send IP address? */ +#if 0 /* UNUSED */ + unsigned int default_route :1; /* Assign default route through interface? */ + unsigned int replace_default_route :1; /* Replace default route through interface? */ +#endif /* UNUSED */ + unsigned int proxy_arp :1; /* Make proxy ARP entry for peer? */ + unsigned int neg_vj :1; /* Van Jacobson Compression? */ + unsigned int old_vj :1; /* use old (short) form of VJ option? */ + unsigned int accept_local :1; /* accept peer's value for ouraddr */ + unsigned int accept_remote :1; /* accept peer's value for hisaddr */ + unsigned int req_dns1 :1; /* Ask peer to send primary DNS address? */ + unsigned int req_dns2 :1; /* Ask peer to send secondary DNS address? */ + unsigned int cflag :1; + unsigned int :5; /* 3 bits of padding to round out to 16 bits */ + + u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ + u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ + u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ + + u16_t vj_protocol; /* protocol value to use in VJ option */ + u8_t maxslotindex; /* values for RFC1332 VJ compression neg. */ +} ipcp_options; + +#if 0 /* UNUSED, already defined by lwIP */ +char *ip_ntoa (u32_t); +#endif /* UNUSED, already defined by lwIP */ + +extern const struct protent ipcp_protent; + +#endif /* IPCP_H */ +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipv6cp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipv6cp.h new file mode 100644 index 0000000..e6afddf --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ipv6cp.h @@ -0,0 +1,177 @@ +/* + * ipv6cp.h - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a t fait au sein du GIE DYADE (Groupement d'Intrt + conomique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est--dire qu'il peut + tre utilis, copi, modifi, distribu l'unique + condition que ce texte soit conserv afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant particip l'laboration de ce logiciel ne peut + tre utilis sans son accord pralable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilit d'aucune sorte. + Ce logiciel est driv de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Mathmatiques Appliques de Grenoble (IMAG) + est une fdration d'units mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Universit Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Systmes, Rseaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.h - IP Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef IPV6CP_H +#define IPV6CP_H + +#include "eui64.h" + +/* + * Options. + */ +#define CI_IFACEID 1 /* Interface Identifier */ +#define CI_COMPRESSTYPE 2 /* Compression Type */ + +/* No compression types yet defined. + *#define IPV6CP_COMP 0x004f + */ +typedef struct ipv6cp_options { + unsigned int neg_ifaceid :1; /* Negotiate interface identifier? */ + unsigned int req_ifaceid :1; /* Ask peer to send interface identifier? */ + unsigned int accept_local :1; /* accept peer's value for iface id? */ + unsigned int opt_local :1; /* ourtoken set by option */ + unsigned int opt_remote :1; /* histoken set by option */ + unsigned int use_ip :1; /* use IP as interface identifier */ +#if 0 + unsigned int use_persistent :1; /* use uniquely persistent value for address */ +#endif + unsigned int neg_vj :1; /* Van Jacobson Compression? */ + unsigned int :1; /* 1 bit of padding to round out to 8 bits */ + u_short vj_protocol; /* protocol value to use in VJ option */ + eui64_t ourid, hisid; /* Interface identifiers */ +} ipv6cp_options; + +extern const struct protent ipv6cp_protent; + +#endif /* IPV6CP_H */ +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/lcp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/lcp.h new file mode 100644 index 0000000..d7fa7c4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/lcp.h @@ -0,0 +1,176 @@ +/* + * lcp.h - Link Control Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef LCP_H +#define LCP_H + +#include "ppp.h" + +/* + * Options. + */ +#define CI_VENDOR 0 /* Vendor Specific */ +#define CI_MRU 1 /* Maximum Receive Unit */ +#define CI_ASYNCMAP 2 /* Async Control Character Map */ +#define CI_AUTHTYPE 3 /* Authentication Type */ +#define CI_QUALITY 4 /* Quality Protocol */ +#define CI_MAGICNUMBER 5 /* Magic Number */ +#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ +#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ +#define CI_FCSALTERN 9 /* FCS-Alternatives */ +#define CI_SDP 10 /* Self-Describing-Pad */ +#define CI_NUMBERED 11 /* Numbered-Mode */ +#define CI_CALLBACK 13 /* callback */ +#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ +#define CI_SSNHF 18 /* short sequence numbers for multilink */ +#define CI_EPDISC 19 /* endpoint discriminator */ +#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ +#define CI_LDISC 23 /* Link-Discriminator */ +#define CI_LCPAUTH 24 /* LCP Authentication */ +#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ +#define CI_PREFELIS 26 /* Prefix Elision */ +#define CI_MPHDRFMT 27 /* MP Header Format */ +#define CI_I18N 28 /* Internationalization */ +#define CI_SDL 29 /* Simple Data Link */ + +/* + * LCP-specific packet types (code numbers). + */ +#define PROTREJ 8 /* Protocol Reject */ +#define ECHOREQ 9 /* Echo Request */ +#define ECHOREP 10 /* Echo Reply */ +#define DISCREQ 11 /* Discard Request */ +#define IDENTIF 12 /* Identification */ +#define TIMEREM 13 /* Time Remaining */ + +/* Value used as data for CI_CALLBACK option */ +#define CBCP_OPT 6 /* Use callback control protocol */ + +#define DEFMRU 1500 /* Try for this */ +#define MINMRU 128 /* No MRUs below this */ +#define MAXMRU 16384 /* Normally limit MRU to this */ + +/* An endpoint discriminator, used with multilink. */ +#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ +struct epdisc { + unsigned char class_; /* -- The word "class" is reserved in C++. */ + unsigned char length; + unsigned char value[MAX_ENDP_LEN]; +}; + +/* + * The state of options is described by an lcp_options structure. + */ +typedef struct lcp_options { + unsigned int passive :1; /* Don't die if we don't get a response */ + unsigned int silent :1; /* Wait for the other end to start first */ + unsigned int restart :1; /* Restart vs. exit after close */ + unsigned int neg_mru :1; /* Negotiate the MRU? */ + unsigned int neg_asyncmap :1; /* Negotiate the async map? */ +#if PAP_SUPPORT + unsigned int neg_upap :1; /* Ask for UPAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + unsigned int neg_chap :1; /* Ask for CHAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + unsigned int neg_eap :1; /* Ask for EAP authentication? */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* EAP_SUPPORT */ + unsigned int neg_magicnumber :1; /* Ask for magic number? */ + unsigned int neg_pcompression :1; /* HDLC Protocol Field Compression? */ + unsigned int neg_accompression :1; /* HDLC Address/Control Field Compression? */ +#if LQR_SUPPORT + unsigned int neg_lqr :1; /* Negotiate use of Link Quality Reports */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* LQR_SUPPORT */ + unsigned int neg_cbcp :1; /* Negotiate use of CBCP */ +#ifdef HAVE_MULTILINK + unsigned int neg_mrru :1; /* negotiate multilink MRRU */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* HAVE_MULTILINK */ + unsigned int neg_ssnhf :1; /* negotiate short sequence numbers */ + unsigned int neg_endpoint :1; /* negotiate endpoint discriminator */ + u16_t mru; /* Value of MRU */ +#ifdef HAVE_MULTILINK + u16_t mrru; /* Value of MRRU, and multilink enable */ +#endif /* MULTILINK */ +#if CHAP_SUPPORT + u8_t chap_mdtype; /* which MD types (hashing algorithm) */ +#endif /* CHAP_SUPPORT */ + u32_t asyncmap; /* Value of async map */ + u32_t magicnumber; + u8_t numloops; /* Number of loops during magic number neg. */ +#if LQR_SUPPORT + u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ +#endif /* LQR_SUPPORT */ + struct epdisc endpoint; /* endpoint discriminator */ +} lcp_options; + +void lcp_open(ppp_pcb *pcb); +void lcp_close(ppp_pcb *pcb, const char *reason); +void lcp_lowerup(ppp_pcb *pcb); +void lcp_lowerdown(ppp_pcb *pcb); +void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject */ + +extern const struct protent lcp_protent; + +#if 0 /* moved to opt.h */ +/* Default number of times we receive our magic number from the peer + before deciding the link is looped-back. */ +#define DEFLOOPBACKFAIL 10 +#endif /* moved to opt.h */ + +#endif /* LCP_H */ +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/magic.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/magic.h new file mode 100644 index 0000000..4661dea --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/magic.h @@ -0,0 +1,119 @@ +/* + * magic.h - PPP Magic Number definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ + */ +/***************************************************************************** +* randm.h - Random number generator header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-05-29 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef MAGIC_H +#define MAGIC_H + +/*********************** +*** PUBLIC FUNCTIONS *** +***********************/ + +/* + * Initialize the random number generator. + */ +void magic_init(void); + +/* + * Randomize our random seed value. To be called for truely random events + * such as user operations and network traffic. + */ +void magic_randomize(void); + +/* + * Return a new random number. + */ +u32_t magic(void); /* Returns the next magic number */ + +#if PPP_MD5_RANDM +/* + * Fill buffer with random bytes + * + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using magic_churnrand(). + * Thus it's important to make sure that the results of this are not + * published directly because one could predict the next result to at + * least some degree. Also, it's important to get a good seed before + * the first use. + */ +void random_bytes(unsigned char *buf, u32_t len); +#endif /* PPP_MD5_RANDM */ + +#endif /* MAGIC_H */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/des.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/des.h new file mode 100644 index 0000000..86417cd --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/des.h @@ -0,0 +1,92 @@ +/** + * \file des.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_DES + +#ifndef LWIP_INCLUDED_POLARSSL_DES_H +#define LWIP_INCLUDED_POLARSSL_DES_H + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +/** + * \brief DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + unsigned long sk[32]; /*!< DES subkeys */ +} +des_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + */ +void des_setkey_enc( des_context *ctx, unsigned char key[8] ); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + */ +void des_setkey_dec( des_context *ctx, unsigned char key[8] ); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + */ +void des_crypt_ecb( des_context *ctx, + unsigned char input[8], + unsigned char output[8] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_DES */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md4.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md4.h new file mode 100644 index 0000000..46ebf5c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md4.h @@ -0,0 +1,97 @@ +/** + * \file md4.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_MD4 + +#ifndef LWIP_INCLUDED_POLARSSL_MD4_H +#define LWIP_INCLUDED_POLARSSL_MD4_H + +/** + * \brief MD4 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md4_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD4 context setup + * + * \param ctx context to be initialized + */ +void md4_starts( md4_context *ctx ); + +/** + * \brief MD4 process buffer + * + * \param ctx MD4 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_update( md4_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD4 final digest + * + * \param ctx MD4 context + * \param output MD4 checksum result + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD4( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD4 checksum result + */ +void md4( unsigned char *input, int ilen, unsigned char output[16] ); + + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md5.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md5.h new file mode 100644 index 0000000..3587b4c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/md5.h @@ -0,0 +1,96 @@ +/** + * \file md5.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_MD5 + +#ifndef LWIP_INCLUDED_POLARSSL_MD5_H +#define LWIP_INCLUDED_POLARSSL_MD5_H + +/** + * \brief MD5 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +md5_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + */ +void md5_starts( md5_context *ctx ); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_update( md5_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + */ +void md5( unsigned char *input, int ilen, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/sha1.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/sha1.h new file mode 100644 index 0000000..9d33163 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/polarssl/sha1.h @@ -0,0 +1,96 @@ +/** + * \file sha1.h + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" +#if LWIP_INCLUDED_POLARSSL_SHA1 + +#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H +#define LWIP_INCLUDED_POLARSSL_SHA1_H + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ +} +sha1_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( unsigned char *input, int ilen, unsigned char output[20] ); + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ + +#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp.h new file mode 100644 index 0000000..ed60536 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp.h @@ -0,0 +1,644 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPP_H +#define PPP_H + +#include "lwip/def.h" +#include "lwip/stats.h" +#include "lwip/mem.h" +#include "lwip/netif.h" +#include "lwip/sys.h" +#include "lwip/sio.h" +#include "lwip/timers.h" +#if PPP_IPV6_SUPPORT +#include "lwip/ip6_addr.h" +#endif /* PPP_IPV6_SUPPORT */ + +/* Disable non-working or rarely used PPP feature, so rarely that we don't want to bloat opt.h with them */ +#ifndef PPP_OPTIONS +#define PPP_OPTIONS 0 +#endif + +#ifndef PPP_NOTIFY +#define PPP_NOTIFY 0 +#endif + +#ifndef PPP_REMOTENAME +#define PPP_REMOTENAME 0 +#endif + +#ifndef PPP_IDLETIMELIMIT +#define PPP_IDLETIMELIMIT 0 +#endif + +#ifndef PPP_LCP_ADAPTIVE +#define PPP_LCP_ADAPTIVE 0 +#endif + +#ifndef PPP_MAXCONNECT +#define PPP_MAXCONNECT 0 +#endif + +#ifndef PPP_ALLOWED_ADDRS +#define PPP_ALLOWED_ADDRS 0 +#endif + +#ifndef PPP_PROTOCOLNAME +#define PPP_PROTOCOLNAME 0 +#endif + +#ifndef PPP_STATS_SUPPORT +#define PPP_STATS_SUPPORT 0 +#endif + + +/************************* +*** PUBLIC DEFINITIONS *** +*************************/ + +/* + * The basic PPP frame. + */ +#define PPP_HDRLEN 4 /* octets for standard ppp header */ +#define PPP_FCSLEN 2 /* octets for FCS */ + +/* + * Values for phase. + */ +#define PPP_PHASE_DEAD 0 +#define PPP_PHASE_INITIALIZE 1 +#define PPP_PHASE_SERIALCONN 2 +#define PPP_PHASE_DORMANT 3 +#define PPP_PHASE_ESTABLISH 4 +#define PPP_PHASE_AUTHENTICATE 5 +#define PPP_PHASE_CALLBACK 6 +#define PPP_PHASE_NETWORK 7 +#define PPP_PHASE_RUNNING 8 +#define PPP_PHASE_TERMINATE 9 +#define PPP_PHASE_DISCONNECT 10 +#define PPP_PHASE_HOLDOFF 11 +#define PPP_PHASE_MASTER 12 + +/* Error codes. */ +#define PPPERR_NONE 0 /* No error. */ +#define PPPERR_PARAM 1 /* Invalid parameter. */ +#define PPPERR_OPEN 2 /* Unable to open PPP session. */ +#define PPPERR_DEVICE 3 /* Invalid I/O device for PPP. */ +#define PPPERR_ALLOC 4 /* Unable to allocate resources. */ +#define PPPERR_USER 5 /* User interrupt. */ +#define PPPERR_CONNECT 6 /* Connection lost. */ +#define PPPERR_AUTHFAIL 7 /* Failed authentication challenge. */ +#define PPPERR_PROTOCOL 8 /* Failed to meet protocol. */ +#define PPPERR_PEERDEAD 9 /* Connection timeout */ +#define PPPERR_IDLETIMEOUT 10 /* Idle Timeout */ +#define PPPERR_CONNECTTIME 11 /* Max connect time reached */ +#define PPPERR_LOOPBACK 12 /* Loopback detected */ + +/* + * PPP IOCTL commands. + */ +/* + * Get the up status - 0 for down, non-zero for up. The argument must + * point to an int. + */ +#define PPPCTLG_UPSTATUS 100 /* Get the up status - 0 down else up */ +#define PPPCTLS_ERRCODE 101 /* Set the error code */ +#define PPPCTLG_ERRCODE 102 /* Get the error code */ +#define PPPCTLG_FD 103 /* Get the fd associated with the ppp */ + +/************************ +*** PUBLIC DATA TYPES *** +************************/ + +/* + * Other headers require ppp_pcb definition for prototypes, but ppp_pcb + * require some structure definition from other headers as well, we are + * fixing the dependency loop here by declaring the ppp_pcb type then + * by including headers containing necessary struct definition for ppp_pcb + */ +typedef struct ppp_pcb_s ppp_pcb; + +/* Type definitions for BSD code. */ +#ifndef __u_char_defined +typedef unsigned long u_long; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; +#endif + +#include "fsm.h" +#include "lcp.h" +#include "ipcp.h" +#if PPP_IPV6_SUPPORT +#include "ipv6cp.h" +#endif /* PPP_IPV6_SUPPORT */ +#if PAP_SUPPORT +#include "upap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "chap-new.h" +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#include "eap.h" +#endif /* EAP_SUPPORT */ +#if VJ_SUPPORT +#include "vj.h" +#endif /* VJ_SUPPORT */ + +#if PPPOE_SUPPORT +#include "netif/ppp/pppoe.h" +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +#include "netif/ppp/pppol2tp.h" +#endif /* PPPOL2TP_SUPPORT */ + +/* + * PPP configuration. + */ +typedef struct ppp_settings_s { + +#if PPP_SERVER + unsigned int auth_required : 1; /* Peer is required to authenticate */ + unsigned int null_login : 1; /* Username of "" and a password of "" are acceptable */ +#else + unsigned int :2; /* 2 bits of padding */ +#endif /* PPP_SERVER */ +#if PPP_REMOTENAME + unsigned int explicit_remote : 1; /* remote_name specified with remotename opt */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PPP_REMOTENAME */ +#if PAP_SUPPORT + unsigned int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + unsigned int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* CHAP_SUPPORT */ +#if MSCHAP_SUPPORT + unsigned int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */ + unsigned int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#else + unsigned int :2; /* 2 bits of padding */ +#endif /* MSCHAP_SUPPORT */ +#if EAP_SUPPORT + unsigned int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* EAP_SUPPORT */ + unsigned int usepeerdns : 1; /* Ask peer for DNS adds */ + unsigned int persist : 1; /* Persist mode, always try to reopen the connection */ +#if PRINTPKT_SUPPORT + unsigned int hide_password : 1; /* Hide password in dumped packets */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PRINTPKT_SUPPORT */ + unsigned int noremoteip : 1; /* Let him have no IP address */ + unsigned int lax_recv : 1; /* accept control chars in asyncmap */ + unsigned int noendpoint : 1; /* don't send/accept endpoint discriminator */ +#if PPP_LCP_ADAPTIVE + unsigned int lcp_echo_adaptive : 1; /* request echo only if the link was idle */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif + unsigned int :1; /* 1 bit of padding to round out to 16 bits */ + + u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ + +#if PPP_IDLETIMELIMIT + u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT + u32_t maxconnect; /* Maximum connect time (seconds) */ +#endif /* PPP_MAXCONNECT */ + + /* auth data */ + const char *user; /* Username for PAP */ + const char *passwd; /* Password for PAP, secret for CHAP */ +#if PPP_SERVER + char our_name [MAXNAMELEN + 1]; /* Our name for authentication purposes */ +#endif /* PPP_SERVER */ +#if PPP_REMOTENAME + char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ +#endif /* PPP_REMOTENAME */ + +#if PAP_SUPPORT + u8_t pap_timeout_time; /* Timeout (seconds) for auth-req retrans. */ + u8_t pap_max_transmits; /* Number of auth-reqs sent */ +#if PPP_SERVER + u8_t pap_req_timeout; /* Time to wait for auth-req from peer */ +#endif /* PPP_SERVER */ +#endif /* PAP_SUPPPORT */ + +#if CHAP_SUPPORT + u8_t chap_timeout_time; /* Timeout (seconds) for retransmitting req */ + u8_t chap_max_transmits; /* max # times to send challenge */ +#if PPP_SERVER + u8_t chap_rechallenge_time; /* Time to wait for auth-req from peer */ +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPPORT */ + +#if EAP_SUPPORT + u8_t eap_req_time; /* Time to wait (for retransmit/fail) */ + u8_t eap_allow_req; /* Max Requests allowed */ +#if PPP_SERVER + u8_t eap_timeout_time; /* Time to wait (for retransmit/fail) */ + u8_t eap_max_transmits; /* Max Requests allowed */ +#endif /* PPP_SERVER */ +#endif /* EAP_SUPPORT */ + + u8_t fsm_timeout_time; /* Timeout time in seconds */ + u8_t fsm_max_conf_req_transmits; /* Maximum Configure-Request transmissions */ + u8_t fsm_max_term_transmits; /* Maximum Terminate-Request transmissions */ + u8_t fsm_max_nak_loops; /* Maximum number of nak loops tolerated */ + + u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer + before deciding the link is looped-back. */ + u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ + u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ + +} ppp_settings; + +struct ppp_addrs { + ip_addr_t our_ipaddr, his_ipaddr, netmask; + ip_addr_t dns1, dns2; +#if PPP_IPV6_SUPPORT + ip6_addr_t our6_ipaddr, his6_ipaddr; +#endif /* PPP_IPV6_SUPPORT */ +}; + +/* FIXME: find a way to move ppp_dev_states and ppp_pcb_rx_s to ppp_impl.h */ +#if PPPOS_SUPPORT +/* + * Extended asyncmap - allows any character to be escaped. + */ +typedef u_char ext_accm[32]; + +/* PPP packet parser states. Current state indicates operation yet to be + * completed. */ +typedef enum { + PDIDLE = 0, /* Idle state - waiting. */ + PDSTART, /* Process start flag. */ + PDADDRESS, /* Process address field. */ + PDCONTROL, /* Process control field. */ + PDPROTOCOL1, /* Process protocol field 1. */ + PDPROTOCOL2, /* Process protocol field 2. */ + PDDATA /* Process data byte. */ +} ppp_dev_states; + +/* + * PPP interface RX control block. + */ +typedef struct ppp_pcb_rx_s { + /** ppp descriptor */ + ppp_pcb *pcb; + /** the rx file descriptor */ + sio_fd_t fd; + + /* The input packet. */ + struct pbuf *in_head, *in_tail; + + u16_t in_protocol; /* The input protocol code. */ + u16_t in_fcs; /* Input Frame Check Sequence value. */ + ppp_dev_states in_state; /* The input process state. */ + char in_escaped; /* Escape next character. */ + ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ +} ppp_pcb_rx; +#endif /* PPPOS_SUPPORT */ + +/* + * PPP interface control block. + */ +struct ppp_pcb_s { + /* -- below are data that will NOT be cleared between two sessions */ +#if PPP_DEBUG + u8_t num; /* Interface number - only useful for debugging */ +#endif /* PPP_DEBUG */ + ppp_settings settings; +#if PPPOS_SUPPORT + sio_fd_t fd; /* File device ID of port. */ +#endif /* PPPOS_SUPPORT */ +#if PPPOE_SUPPORT + struct pppoe_softc *pppoe_sc; +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + pppol2tp_pcb *l2tp_pcb; +#endif /* PPPOL2TP_SUPPORT */ + void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ +#if PPP_NOTIFY_PHASE + void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx); /* Notify phase callback */ +#endif /* PPP_NOTIFY_PHASE */ + void *ctx_cb; /* Callbacks optional pointer */ + struct netif netif; /* PPP interface */ + + /* -- below are data that will be cleared between two sessions */ + + /* + * phase must be the first member of cleared members, because it is used to know + * which part must not be cleared. + */ + u8_t phase; /* where the link is at */ + u8_t err_code; /* Code indicating why interface is down. */ + + /* flags */ + unsigned int if_up :1; /* True when the interface is up. */ +#if PPP_IPV6_SUPPORT + unsigned int if6_up :1; /* True when the IPv6 interface is up. */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PPP_IPV6_SUPPORT */ + unsigned int pcomp :1; /* Does peer accept protocol compression? */ + unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ + unsigned int proxy_arp_set :1; /* Have created proxy arp entry */ + unsigned int ipcp_is_open :1; /* haven't called np_finished() */ + unsigned int ipcp_is_up :1; /* have called ipcp_up() */ +#if PPP_IPV6_SUPPORT + unsigned int ipv6cp_is_up :1; /* have called ip6cp_up() */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PPP_IPV6_SUPPORT */ + unsigned int ask_for_local :1; /* request our address from peer */ + unsigned int lcp_echo_timer_running :1; /* set if a timer is running */ +#if PPPOS_SUPPORT && VJ_SUPPORT + unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */ +#else + unsigned int :1; /* 1 bit of padding */ +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + unsigned int :5; /* 5 bits of padding to round out to 16 bits */ + +#if PPPOS_SUPPORT +/* FIXME: there is probably one superfluous */ + ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ + ext_accm xmit_accm; /* extended transmit ACCM */ + ppp_pcb_rx rx; +#if VJ_SUPPORT + struct vjcompress vj_comp; /* Van Jacobson compression header. */ +#endif /* VJ_SUPPORT */ +#endif /* PPPOS_SUPPORT */ + + u32_t last_xmit; /* Time of last transmission. */ + + struct ppp_addrs addrs; /* PPP addresses */ + + /* auth data */ +#if PPP_SERVER + char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */ +#endif /* PPP_SERVER */ + u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ + u16_t auth_done; /* Records which authentication operations have been completed. */ + u8_t num_np_open; /* Number of network protocols which we have opened. */ + u8_t num_np_up; /* Number of network protocols which have come up. */ + +#if PAP_SUPPORT + upap_state upap; /* PAP data */ +#endif /* PAP_SUPPORT */ + +#if CHAP_SUPPORT + chap_client_state chap_client; /* CHAP client data */ +#if PPP_SERVER + chap_server_state chap_server; /* CHAP server data */ +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPORT */ + +#if EAP_SUPPORT + eap_state eap; /* EAP data */ +#endif /* EAP_SUPPORT */ + + fsm lcp_fsm; /* LCP fsm structure */ + lcp_options lcp_wantoptions; /* Options that we want to request */ + lcp_options lcp_gotoptions; /* Options that peer ack'd */ + lcp_options lcp_allowoptions; /* Options we allow peer to request */ + lcp_options lcp_hisoptions; /* Options that we ack'd */ + u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ + u8_t lcp_echo_number; /* ID number of next echo frame */ + u16_t peer_mru; /* currently negotiated peer MRU */ + + fsm ipcp_fsm; /* IPCP fsm structure */ + ipcp_options ipcp_wantoptions; /* Options that we want to request */ + ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ + ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ + ipcp_options ipcp_hisoptions; /* Options that we ack'd */ + +#if PPP_IPV6_SUPPORT + fsm ipv6cp_fsm; /* IPV6CP fsm structure */ + ipv6cp_options ipv6cp_wantoptions; /* Options that we want to request */ + ipv6cp_options ipv6cp_gotoptions; /* Options that peer ack'd */ + ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */ + ipv6cp_options ipv6cp_hisoptions; /* Options that we ack'd */ +#endif /* PPP_IPV6_SUPPORT */ +}; + +/************************ + *** PUBLIC FUNCTIONS *** + ************************/ + +/* + * Create a new PPP session. + * + * This initializes the PPP control block but does not + * attempt to negotiate the LCP session. + * + * Return a new PPP connection control block pointer + * on success or a null pointer on failure. + */ +ppp_pcb *ppp_new(void); + +/* + * Set a PPP interface as the default network interface + * (used to output all packets for which no specific route is found). + */ +void ppp_set_default(ppp_pcb *pcb); + +/* + * Set auth helper, optional, you can either fill ppp_pcb->settings. + * + * Warning: Using PPPAUTHTYPE_ANY might have security consequences. + * RFC 1994 says: + * + * In practice, within or associated with each PPP server, there is a + * database which associates "user" names with authentication + * information ("secrets"). It is not anticipated that a particular + * named user would be authenticated by multiple methods. This would + * make the user vulnerable to attacks which negotiate the least secure + * method from among a set (such as PAP rather than CHAP). If the same + * secret was used, PAP would reveal the secret to be used later with + * CHAP. + * + * Instead, for each user name there should be an indication of exactly + * one method used to authenticate that user name. If a user needs to + * make use of different authentication methods under different + * circumstances, then distinct user names SHOULD be employed, each of + * which identifies exactly one authentication method. + * + */ +#define PPPAUTHTYPE_NONE 0x00 +#define PPPAUTHTYPE_PAP 0x01 +#define PPPAUTHTYPE_CHAP 0x02 +#define PPPAUTHTYPE_MSCHAP 0x04 +#define PPPAUTHTYPE_EAP 0x08 +#define PPPAUTHTYPE_ANY 0xff + +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); + +#if PPP_NOTIFY_PHASE +/* + * Set a PPP notify phase callback. + * + * This can be used for example to set a LED pattern depending on the + * current phase of the PPP session. + */ +typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx); +void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); +#endif /* PPP_NOTIFY_PHASE */ + +/* Link status callback function prototype */ +typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); + +#if PPPOS_SUPPORT +/* + * Create a new PPP connection using the given serial I/O device. + * + * If this port connects to a modem, the modem connection must be + * established before calling this. + * + * Return 0 on success, an error code on failure. + */ +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +/* + * Create a new PPP Over Ethernet (PPPoE) connection. + * + * Return 0 on success, an error code on failure. + */ +int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT +/* + * Create a new PPP Over L2TP (PPPoL2TP) connection. + */ +int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb); +#endif /* PPPOL2TP_SUPPORT */ + +/* + * Open a PPP connection. + * + * This can only be called if PPP is in the dead phase. + * + * Holdoff is the time to wait (in seconds) before initiating + * the connection. + */ +int ppp_open(ppp_pcb *pcb, u16_t holdoff); + +/* + * Initiate the end of a PPP connection. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. + */ +int ppp_close(ppp_pcb *pcb); + +/* + * Indicate to the PPP stack that the line has disconnected. + */ +void ppp_sighup(ppp_pcb *pcb); + +/* + * Free the control block, clean everything except the PPP PCB itself + * and the netif, it allows you to change the underlying PPP protocol + * (eg. from PPPoE to PPPoS to switch from DSL to GPRS) without losing + * your PPP and netif handlers. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_free(ppp_pcb *pcb); + +/* + * Release the control block. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_delete(ppp_pcb *pcb); + +/* + * Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. + */ +int ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg); + +#if PPPOS_SUPPORT +/* + * PPP over Serial: this is the input function to be called for received data. + */ +void pppos_input(ppp_pcb *pcb, u_char* data, int len); +#endif /* PPPOS_SUPPORT */ + +/* Get the PPP netif interface */ +#define ppp_netif(ppp) (&(ppp)->netif) + +/* Get the PPP addresses */ +#define ppp_addrs(ppp) (&(ppp)->addrs) + +#if LWIP_NETIF_STATUS_CALLBACK +/* Set an lwIP-style status-callback for the selected PPP device */ +void ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback); +#endif /* LWIP_NETIF_STATUS_CALLBACK */ +#if LWIP_NETIF_LINK_CALLBACK +/* Set an lwIP-style link-callback for the selected PPP device */ +void ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback); +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +#endif /* PPP_H */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp_impl.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp_impl.h new file mode 100644 index 0000000..9584871 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/ppp_impl.h @@ -0,0 +1,581 @@ +/***************************************************************************** +* ppp.h - Network Point to Point Protocol header file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original derived from BSD codes. +*****************************************************************************/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPP_IMP_H_ +#define PPP_IMP_H_ + +#include /* formats */ +#include +#include +#include /* strtol() */ + +#include "lwip/netif.h" +#include "lwip/def.h" +#include "lwip/timers.h" + +#include "ppp.h" +#include "pppdebug.h" + +/* + * Memory used for control packets. + * + * PPP_CTRL_PBUF_MAX_SIZE is the amount of memory we allocate when we + * cannot figure out how much we are going to use before filling the buffer. + */ +#if PPP_USE_PBUF_RAM +#define PPP_CTRL_PBUF_TYPE PBUF_RAM +#define PPP_CTRL_PBUF_MAX_SIZE 512 +#else /* PPP_USE_PBUF_RAM */ +#define PPP_CTRL_PBUF_TYPE PBUF_POOL +#define PPP_CTRL_PBUF_MAX_SIZE PBUF_POOL_BUFSIZE +#endif /* PPP_USE_PBUF_RAM */ + +/* + * Limits. + */ +#define MAXWORDLEN 1024 /* max length of word in file (incl null) */ +#define MAXARGS 1 /* max # args to a command */ +#define MAXNAMELEN 256 /* max length of hostname or name for auth */ +#define MAXSECRETLEN 256 /* max length of password or secret */ + +/* + * The basic PPP frame. + */ +#define PPP_ADDRESS(p) (((u_char *)(p))[0]) +#define PPP_CONTROL(p) (((u_char *)(p))[1]) +#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) + +/* + * Significant octet values. + */ +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_FLAG 0x7e /* Flag Sequence */ +#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ +#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ + +/* + * Protocol field values. + */ +#define PPP_IP 0x21 /* Internet Protocol */ +#if 0 /* UNUSED */ +#define PPP_AT 0x29 /* AppleTalk Protocol */ +#define PPP_IPX 0x2b /* IPX protocol */ +#endif /* UNUSED */ +#if VJ_SUPPORT +#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ +#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ +#endif /* VJ_SUPPORT */ +#if PPP_IPV6_SUPPORT +#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ +#endif /* PPP_IPV6_SUPPORT */ +#if CCP_SUPPORT +#define PPP_COMP 0xfd /* compressed packet */ +#endif /* CCP_SUPPORT */ +#define PPP_IPCP 0x8021 /* IP Control Protocol */ +#if 0 /* UNUSED */ +#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ +#define PPP_IPXCP 0x802b /* IPX Control Protocol */ +#endif /* UNUSED */ +#if PPP_IPV6_SUPPORT +#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ +#endif /* PPP_IPV6_SUPPORT */ +#if CCP_SUPPORT +#define PPP_CCP 0x80fd /* Compression Control Protocol */ +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT +#define PPP_ECP 0x8053 /* Encryption Control Protocol */ +#endif /* ECP_SUPPORT */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#if PAP_SUPPORT +#define PPP_PAP 0xc023 /* Password Authentication Protocol */ +#endif /* PAP_SUPPORT */ +#if LQR_SUPPORT +#define PPP_LQR 0xc025 /* Link Quality Report protocol */ +#endif /* LQR_SUPPORT */ +#if CHAP_SUPPORT +#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT +#define PPP_CBCP 0xc029 /* Callback Control Protocol */ +#endif /* CBCP_SUPPORT */ +#if EAP_SUPPORT +#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ +#endif /* EAP_SUPPORT */ + +/* + * Values for FCS calculations. + */ +#define PPP_INITFCS 0xffff /* Initial FCS value */ +#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ +#if PPP_FCS_TABLE + #define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) +#else +u16_t ppp_get_fcs(u8_t byte); +#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) +#endif + + +/* + * What to do with network protocol (NP) packets. + */ +enum NPmode { + NPMODE_PASS, /* pass the packet through */ + NPMODE_DROP, /* silently drop the packet */ + NPMODE_ERROR, /* return an error */ + NPMODE_QUEUE /* save it up for later. */ +}; + +/* + * Statistics. + */ +#if PPP_STATS_SUPPORT +struct pppstat { + unsigned int ppp_ibytes; /* bytes received */ + unsigned int ppp_ipackets; /* packets received */ + unsigned int ppp_ierrors; /* receive errors */ + unsigned int ppp_obytes; /* bytes sent */ + unsigned int ppp_opackets; /* packets sent */ + unsigned int ppp_oerrors; /* transmit errors */ +}; + +#if VJ_SUPPORT +struct vjstat { + unsigned int vjs_packets; /* outbound packets */ + unsigned int vjs_compressed; /* outbound compressed packets */ + unsigned int vjs_searches; /* searches for connection state */ + unsigned int vjs_misses; /* times couldn't find conn. state */ + unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned int vjs_compressedin; /* inbound compressed packets */ + unsigned int vjs_errorin; /* inbound unknown type packets */ + unsigned int vjs_tossed; /* inbound packets tossed because of error */ +}; +#endif /* VJ_SUPPORT */ + +struct ppp_stats { + struct pppstat p; /* basic PPP statistics */ +#if VJ_SUPPORT + struct vjstat vj; /* VJ header compression statistics */ +#endif /* VJ_SUPPORT */ +}; + +#if CCP_SUPPORT +struct compstat { + unsigned int unc_bytes; /* total uncompressed bytes */ + unsigned int unc_packets; /* total uncompressed packets */ + unsigned int comp_bytes; /* compressed bytes */ + unsigned int comp_packets; /* compressed packets */ + unsigned int inc_bytes; /* incompressible bytes */ + unsigned int inc_packets; /* incompressible packets */ + unsigned int ratio; /* recent compression ratio << 8 */ +}; + +struct ppp_comp_stats { + struct compstat c; /* packet compression statistics */ + struct compstat d; /* packet decompression statistics */ +}; +#endif /* CCP_SUPPORT */ + +#endif /* PPP_STATS_SUPPORT */ + +#if PPP_IDLETIMELIMIT +/* + * The following structure records the time in seconds since + * the last NP packet was sent or received. + */ +struct ppp_idle { + time_t xmit_idle; /* time since last NP packet sent */ + time_t recv_idle; /* time since last NP packet received */ +}; +#endif /* PPP_IDLETIMELIMIT */ + +/* values for epdisc.class */ +#define EPD_NULL 0 /* null discriminator, no data */ +#define EPD_LOCAL 1 +#define EPD_IP 2 +#define EPD_MAC 3 +#define EPD_MAGIC 4 +#define EPD_PHONENUM 5 + +/* + * Global variables. + */ +#ifdef HAVE_MULTILINK +extern u8_t multilink; /* enable multilink operation */ +extern u8_t doing_multilink; +extern u8_t multilink_master; +extern u8_t bundle_eof; +extern u8_t bundle_terminating; +#endif + +#ifdef MAXOCTETS +extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ +extern int maxoctets_dir; /* Direction : + 0 - in+out (default) + 1 - in + 2 - out + 3 - max(in,out) */ +extern int maxoctets_timeout; /* Timeout for check of octets limit */ +#define PPP_OCTETS_DIRECTION_SUM 0 +#define PPP_OCTETS_DIRECTION_IN 1 +#define PPP_OCTETS_DIRECTION_OUT 2 +#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 +/* same as previos, but little different on RADIUS side */ +#define PPP_OCTETS_DIRECTION_MAXSESSION 4 +#endif + +/* + * The following struct gives the addresses of procedures to call + * for a particular protocol. + */ +struct protent { + u_short protocol; /* PPP protocol number */ + /* Initialization procedure */ + void (*init) (ppp_pcb *pcb); + /* Process a received packet */ + void (*input) (ppp_pcb *pcb, u_char *pkt, int len); + /* Process a received protocol-reject */ + void (*protrej) (ppp_pcb *pcb); + /* Lower layer has come up */ + void (*lowerup) (ppp_pcb *pcb); + /* Lower layer has gone down */ + void (*lowerdown) (ppp_pcb *pcb); + /* Open the protocol */ + void (*open) (ppp_pcb *pcb); + /* Close the protocol */ + void (*close) (ppp_pcb *pcb, const char *reason); +#if PRINTPKT_SUPPORT + /* Print a packet in readable form */ + int (*printpkt) (u_char *pkt, int len, + void (*printer) (void *, const char *, ...), + void *arg); +#endif /* PRINTPKT_SUPPORT */ + /* FIXME: data input is only used by CCP, which is not supported at this time, + * should we remove this entry and save some flash ? + */ + /* Process a received data packet */ + void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len); + u8_t enabled_flag; /* 0 if protocol is disabled */ +#if PRINTPKT_SUPPORT + const char *name; /* Text name of protocol */ + const char *data_name; /* Text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + option_t *options; /* List of command-line options */ + /* Check requested options, assign defaults */ + void (*check_options) (void); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + /* Configure interface for demand-dial */ + int (*demand_conf) (int unit); + /* Say whether to bring up link for this pkt */ + int (*active_pkt) (u_char *pkt, int len); +#endif /* DEMAND_SUPPORT */ +}; + +/* Table of pointers to supported protocols */ +extern const struct protent* const protocols[]; + + +/* Values for auth_pending, auth_done */ +#if PAP_SUPPORT +#define PAP_WITHPEER 0x1 +#define PAP_PEER 0x2 +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#define CHAP_WITHPEER 0x4 +#define CHAP_PEER 0x8 +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#define EAP_WITHPEER 0x10 +#define EAP_PEER 0x20 +#endif /* EAP_SUPPORT */ + +/* Values for auth_done only */ +#if CHAP_SUPPORT +#define CHAP_MD5_WITHPEER 0x40 +#define CHAP_MD5_PEER 0x80 +#if MSCHAP_SUPPORT +#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ +#define CHAP_MS_WITHPEER 0x100 +#define CHAP_MS_PEER 0x200 +#define CHAP_MS2_WITHPEER 0x400 +#define CHAP_MS2_PEER 0x800 +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ + +/* Supported CHAP protocols */ +#if CHAP_SUPPORT +#include "chap-new.h" +#if MSCHAP_SUPPORT +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) +#else +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5) +#endif +#else +#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE) +#endif + +#if PPP_STATS_SUPPORT +/* + * PPP statistics structure + */ +struct pppd_stats { + unsigned int bytes_in; + unsigned int bytes_out; + unsigned int pkts_in; + unsigned int pkts_out; +}; +#endif /* PPP_STATS_SUPPORT */ + + +/* PPP flow functions + */ +/* initialize the PPP subsystem */ +int ppp_init(void); + +/* function called by pppoe.c */ +void ppp_input(ppp_pcb *pcb, struct pbuf *pb); + +/* function called by all PPP subsystems to send packets */ +int ppp_write(ppp_pcb *pcb, struct pbuf *p); + +/* functions called by auth.c link_terminated() */ +void ppp_link_down(ppp_pcb *pcb); +void ppp_link_terminated(ppp_pcb *pcb); + +/* merge a pbuf chain into one pbuf */ +struct pbuf * ppp_singlebuf(struct pbuf *p); + + +/* Functions called by various PPP subsystems to configure + * the PPP interface or change the PPP phase. + */ +void new_phase(ppp_pcb *pcb, int p); + +#if PPPOS_SUPPORT +void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm); +#endif /* PPPOS_SUPPORT */ +int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp); +int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp); + +int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t net_mask); +int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr); + +#if PPP_IPV6_SUPPORT +int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); +int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); +#endif /* PPP_IPV6_SUPPORT */ + +int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); +int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); + +int sifup(ppp_pcb *pcb); +int sifdown (ppp_pcb *pcb); + +#if PPP_IPV6_SUPPORT +int sif6up(ppp_pcb *pcb); +int sif6down (ppp_pcb *pcb); +#endif /* PPP_IPV6_SUPPORT */ + +int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); + +void netif_set_mtu(ppp_pcb *pcb, int mtu); +int netif_get_mtu(ppp_pcb *pcb); + +int sifproxyarp(ppp_pcb *pcb, u32_t his_adr); +int cifproxyarp(ppp_pcb *pcb, u32_t his_adr); + +int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); + +#if PPP_IDLETIMELIMIT +int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); +#endif /* PPP_IDLETIMELIMIT */ + +int get_loop_output(void); + +u32_t get_mask (u32_t addr); + + +/* Optional protocol names list, to make our messages a little more informative. */ +#if PPP_PROTOCOLNAME +const char * protocol_name(int proto); +#endif /* PPP_PROTOCOLNAME */ + + +/* Optional stats support, to get some statistics on the PPP interface */ +#if PPP_STATS_SUPPORT +void print_link_stats(void); /* Print stats, if available */ +void reset_link_stats(int u); /* Reset (init) stats when link goes up */ +void update_link_stats(int u); /* Get stats at link termination */ +#endif /* PPP_STATS_SUPPORT */ + + + +/* + * Inline versions of get/put char/short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETCHAR(c, cp) { \ + (c) = *(cp)++; \ +} +#define PUTCHAR(c, cp) { \ + *(cp)++ = (u_char) (c); \ +} + + +#define GETSHORT(s, cp) { \ + (s) = *(cp)++ << 8; \ + (s) |= *(cp)++; \ +} +#define PUTSHORT(s, cp) { \ + *(cp)++ = (u_char) ((s) >> 8); \ + *(cp)++ = (u_char) (s); \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp)++ << 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; \ +} +#define PUTLONG(l, cp) { \ + *(cp)++ = (u_char) ((l) >> 24); \ + *(cp)++ = (u_char) ((l) >> 16); \ + *(cp)++ = (u_char) ((l) >> 8); \ + *(cp)++ = (u_char) (l); \ +} + +#define INCPTR(n, cp) ((cp) += (n)) +#define DECPTR(n, cp) ((cp) -= (n)) + +/* + * System dependent definitions for user-level 4.3BSD UNIX implementation. + */ +#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) +#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) +#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) + +#define BZERO(s, n) memset(s, 0, n) +#define BCMP(s1, s2, l) memcmp(s1, s2, l) + +#define PRINTMSG(m, l) { ppp_info("Remote message: %0.*v", l, m); } + +/* + * MAKEHEADER - Add Header fields to a packet. + */ +#define MAKEHEADER(p, t) { \ + PUTCHAR(PPP_ALLSTATIONS, p); \ + PUTCHAR(PPP_UI, p); \ + PUTSHORT(t, p); } + +/* Procedures exported from auth.c */ +void link_required(ppp_pcb *pcb); /* we are starting to use the link */ +void link_terminated(ppp_pcb *pcb); /* we are finished with the link */ +void link_down(ppp_pcb *pcb); /* the LCP layer has left the Opened state */ +void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */ +void link_established(ppp_pcb *pcb); /* the link is up; authenticate now */ +void start_networks(ppp_pcb *pcb); /* start all the network control protos */ +void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */ +#if PPP_SERVER +void auth_peer_fail(ppp_pcb *pcb, int protocol); + /* peer failed to authenticate itself */ +void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen); + /* peer successfully authenticated itself */ +#endif /* PPP_SERVER */ +void auth_withpeer_fail(ppp_pcb *pcb, int protocol); + /* we failed to authenticate ourselves */ +void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor); + /* we successfully authenticated ourselves */ +void np_up(ppp_pcb *pcb, int proto); /* a network protocol has come up */ +void np_down(ppp_pcb *pcb, int proto); /* a network protocol has gone down */ +void np_finished(ppp_pcb *pcb, int proto); /* a network protocol no longer needs link */ +void auth_reset(ppp_pcb *pcb); /* check what secrets we have */ +int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server); + /* get "secret" for chap */ + +/* Procedures exported from ipcp.c */ +/* int parse_dotted_ip (char *, u32_t *); */ + +/* Procedures exported from demand.c */ +#if DEMAND_SUPPORT +void demand_conf (void); /* config interface(s) for demand-dial */ +void demand_block (void); /* set all NPs to queue up packets */ +void demand_unblock (void); /* set all NPs to pass packets */ +void demand_discard (void); /* set all NPs to discard packets */ +void demand_rexmit (int, u32_t); /* retransmit saved frames for an NP*/ +int loop_chars (unsigned char *, int); /* process chars from loopback */ +int loop_frame (unsigned char *, int); /* should we bring link up? */ +#endif /* DEMAND_SUPPORT */ + +/* Procedures exported from multilink.c */ +#ifdef HAVE_MULTILINK +void mp_check_options (void); /* Check multilink-related options */ +int mp_join_bundle (void); /* join our link to an appropriate bundle */ +void mp_exit_bundle (void); /* have disconnected our link from bundle */ +void mp_bundle_terminated (void); +char *epdisc_to_str (struct epdisc *); /* string from endpoint discrim. */ +int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ +#else +#define mp_bundle_terminated() /* nothing */ +#define mp_exit_bundle() /* nothing */ +#define doing_multilink 0 +#define multilink_master 0 +#endif + +/* Procedures exported from utils.c. */ +void ppp_print_string(char *p, int len, void (*printer) (void *, const char *, ...), void *arg); /* Format a string for output */ +int ppp_slprintf(char *buf, int buflen, const char *fmt, ...); /* sprintf++ */ +int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args); /* vsprintf++ */ +size_t ppp_strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ +size_t ppp_strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ +void ppp_dbglog(const char *fmt, ...); /* log a debug message */ +void ppp_info(const char *fmt, ...); /* log an informational message */ +void ppp_notice(const char *fmt, ...); /* log a notice-level message */ +void ppp_warn(const char *fmt, ...); /* log a warning message */ +void ppp_error(const char *fmt, ...); /* log an error message */ +void ppp_fatal(const char *fmt, ...); /* log an error message and die(1) */ +#if PRINTPKT_SUPPORT +void ppp_dump_packet(const char *tag, unsigned char *p, int len); + /* dump packet to debug log if interesting */ +#endif /* PRINTPKT_SUPPORT */ + + +#endif /* PPP_IMP_H_ */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppcrypt.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppcrypt.h new file mode 100644 index 0000000..ef2e87d --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppcrypt.h @@ -0,0 +1,43 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPPCRYPT_H +#define PPPCRYPT_H + +void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); + +#endif /* PPPCRYPT_H */ + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppdebug.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppdebug.h new file mode 100644 index 0000000..e35c8e0 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppdebug.h @@ -0,0 +1,80 @@ +/***************************************************************************** +* pppdebug.h - System debugging utilities. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1998 Global Election Systems Inc. +* portions Copyright (c) 2001 by Cognizant Pty Ltd. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY (please don't use tabs!) +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-07-29 Guy Lancaster , Global Election Systems Inc. +* Original. +* +***************************************************************************** +*/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPPDEBUG_H +#define PPPDEBUG_H + +/* Trace levels. */ +#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) +#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) +#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define LOG_INFO (PPP_DEBUG) +#define LOG_DETAIL (PPP_DEBUG) +#define LOG_DEBUG (PPP_DEBUG) + +#if PPP_DEBUG + +#define MAINDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define SYSDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define FSMDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define LCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define IPCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define IPV6CPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define UPAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define CHAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) +#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) + +#else /* PPP_DEBUG */ + +#define MAINDEBUG(a) +#define SYSDEBUG(a) +#define FSMDEBUG(a) +#define LCPDEBUG(a) +#define IPCPDEBUG(a) +#define IPV6CPDEBUG(a) +#define UPAPDEBUG(a) +#define CHAPDEBUG(a) +#define PPPDEBUG(a, b) + +#endif /* PPP_DEBUG */ + +#endif /* PPPDEBUG_H */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppoe.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppoe.h new file mode 100644 index 0000000..eae032c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppoe.h @@ -0,0 +1,183 @@ +/***************************************************************************** +* pppoe.h - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPP_OE_H +#define PPP_OE_H + +#include "ppp.h" +#include "netif/etharp.h" + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoehdr { + PACK_STRUCT_FLD_8(u8_t vertype); + PACK_STRUCT_FLD_8(u8_t code); + PACK_STRUCT_FIELD(u16_t session); + PACK_STRUCT_FIELD(u16_t plen); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppoetag { + PACK_STRUCT_FIELD(u16_t tag); + PACK_STRUCT_FIELD(u16_t len); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + + +#define PPPOE_STATE_INITIAL 0 +#define PPPOE_STATE_PADI_SENT 1 +#define PPPOE_STATE_PADR_SENT 2 +#define PPPOE_STATE_SESSION 3 +/* passive */ +#define PPPOE_STATE_PADO_SENT 1 + +#define PPPOE_CB_STATE_UP 0 /* PPPoE link is UP */ +#define PPPOE_CB_STATE_DOWN 1 /* PPPoE link is DOWN - normal condition */ +#define PPPOE_CB_STATE_FAILED 2 /* Failed to setup PPPoE link */ + +#define PPPOE_HEADERLEN sizeof(struct pppoehdr) +#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ + +#define PPPOE_TAG_EOL 0x0000 /* end of list */ +#define PPPOE_TAG_SNAME 0x0101 /* service name */ +#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ +#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ +#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ +#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ +#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ +#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ +#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ +#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ + +#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ +#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ +#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ +#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ +#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ + +#ifndef PPPOE_MAX_AC_COOKIE_LEN +#define PPPOE_MAX_AC_COOKIE_LEN 64 +#endif + +struct pppoe_softc { + struct pppoe_softc *next; + struct netif *sc_ethif; /* ethernet interface we are using */ + ppp_pcb *pcb; /* PPP PCB */ + void (*sc_link_status_cb)(ppp_pcb *pcb, int up); + + struct eth_addr sc_dest; /* hardware address of concentrator */ + u16_t sc_session; /* PPPoE session id */ + u8_t sc_state; /* discovery phase or session connected */ + +#ifdef PPPOE_TODO + u8_t *sc_service_name; /* if != NULL: requested name of service */ + u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */ +#endif /* PPPOE_TODO */ + u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ + u8_t sc_ac_cookie_len; /* length of cookie data */ +#ifdef PPPOE_SERVER + u8_t *sc_hunique; /* content of host unique we must echo back */ + u8_t sc_hunique_len; /* length of host unique */ +#endif + u8_t sc_padi_retried; /* number of PADI retries already done */ + u8_t sc_padr_retried; /* number of PADR retries already done */ +}; + + +#define pppoe_init() /* compatibility define, no initialization needed */ + +err_t pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr); +err_t pppoe_destroy(struct pppoe_softc *sc); + +int pppoe_connect(struct pppoe_softc *sc); +void pppoe_disconnect(struct pppoe_softc *sc); + +void pppoe_disc_input(struct netif *netif, struct pbuf *p); +void pppoe_data_input(struct netif *netif, struct pbuf *p); + +err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); + +#endif /* PPP_OE_H */ + +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppol2tp.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppol2tp.h new file mode 100644 index 0000000..5b869ae --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/pppol2tp.h @@ -0,0 +1,217 @@ +/** + * @file + * Network Point to Point Protocol over Layer 2 Tunneling Protocol header file. + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef PPPOL2TP_H_ +#define PPPOL2TP_H_ + +#include "ppp.h" + +/* Timeout */ +#define PPPOL2TP_CONTROL_TIMEOUT (5*1000) /* base for quick timeout calculation */ +#define PPPOL2TP_SLOW_RETRY (60*1000) /* persistent retry interval */ + +#define PPPOL2TP_MAXSCCRQ 4 /* retry SCCRQ four times (quickly) */ +#define PPPOL2TP_MAXICRQ 4 /* retry IRCQ four times */ +#define PPPOL2TP_MAXICCN 4 /* retry ICCN four times */ + +/* L2TP header flags */ +#define PPPOL2TP_HEADERFLAG_CONTROL 0x8000 +#define PPPOL2TP_HEADERFLAG_LENGTH 0x4000 +#define PPPOL2TP_HEADERFLAG_SEQUENCE 0x0800 +#define PPPOL2TP_HEADERFLAG_OFFSET 0x0200 +#define PPPOL2TP_HEADERFLAG_PRIORITY 0x0100 +#define PPPOL2TP_HEADERFLAG_VERSION 0x0002 + +/* Mandatory bits for control: Control, Length, Sequence, Version 2 */ +#define PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY (PPPOL2TP_HEADERFLAG_CONTROL|PPPOL2TP_HEADERFLAG_LENGTH|PPPOL2TP_HEADERFLAG_SEQUENCE|PPPOL2TP_HEADERFLAG_VERSION) +/* Forbidden bits for control: Offset, Priority */ +#define PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN (PPPOL2TP_HEADERFLAG_OFFSET|PPPOL2TP_HEADERFLAG_PRIORITY) + +/* Mandatory bits for data: Version 2 */ +#define PPPOL2TP_HEADERFLAG_DATA_MANDATORY (PPPOL2TP_HEADERFLAG_VERSION) + +/* AVP (Attribute Value Pair) header */ +#define PPPOL2TP_AVPHEADERFLAG_MANDATORY 0x8000 +#define PPPOL2TP_AVPHEADERFLAG_HIDDEN 0x4000 +#define PPPOL2TP_AVPHEADERFLAG_LENGTHMASK 0x03ff + +/* -- AVP - Message type */ +#define PPPOL2TP_AVPTYPE_MESSAGE 0 /* Message type */ + +/* Control Connection Management */ +#define PPPOL2TP_MESSAGETYPE_SCCRQ 1 /* Start Control Connection Request */ +#define PPPOL2TP_MESSAGETYPE_SCCRP 2 /* Start Control Connection Reply */ +#define PPPOL2TP_MESSAGETYPE_SCCCN 3 /* Start Control Connection Connected */ +#define PPPOL2TP_MESSAGETYPE_STOPCCN 4 /* Stop Control Connection Notification */ +#define PPPOL2TP_MESSAGETYPE_HELLO 6 /* Hello */ +/* Call Management */ +#define PPPOL2TP_MESSAGETYPE_OCRQ 7 /* Outgoing Call Request */ +#define PPPOL2TP_MESSAGETYPE_OCRP 8 /* Outgoing Call Reply */ +#define PPPOL2TP_MESSAGETYPE_OCCN 9 /* Outgoing Call Connected */ +#define PPPOL2TP_MESSAGETYPE_ICRQ 10 /* Incoming Call Request */ +#define PPPOL2TP_MESSAGETYPE_ICRP 11 /* Incoming Call Reply */ +#define PPPOL2TP_MESSAGETYPE_ICCN 12 /* Incoming Call Connected */ +#define PPPOL2TP_MESSAGETYPE_CDN 14 /* Call Disconnect Notify */ +/* Error reporting */ +#define PPPOL2TP_MESSAGETYPE_WEN 15 /* WAN Error Notify */ +/* PPP Session Control */ +#define PPPOL2TP_MESSAGETYPE_SLI 16 /* Set Link Info */ + +/* -- AVP - Result code */ +#define PPPOL2TP_AVPTYPE_RESULTCODE 1 /* Result code */ +#define PPPOL2TP_RESULTCODE 1 /* General request to clear control connection */ + +/* -- AVP - Protocol version (!= L2TP Header version) */ +#define PPPOL2TP_AVPTYPE_VERSION 2 +#define PPPOL2TP_VERSION 0x0100 /* L2TP Protocol version 1, revision 0 */ + +/* -- AVP - Framing capabilities */ +#define PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES 3 /* Bearer capabilities */ +#define PPPOL2TP_FRAMINGCAPABILITIES 0x00000003 /* Async + Sync framing */ + +/* -- AVP - Bearer capabilities */ +#define PPPOL2TP_AVPTYPE_BEARERCAPABILITIES 4 /* Bearer capabilities */ +#define PPPOL2TP_BEARERCAPABILITIES 0x00000003 /* Analog + Digital Access */ + +/* -- AVP - Tie breaker */ +#define PPPOL2TP_AVPTYPE_TIEBREAKER 5 + +/* -- AVP - Host name */ +#define PPPOL2TP_AVPTYPE_HOSTNAME 7 /* Host name */ +#define PPPOL2TP_HOSTNAME "lwIP" /* FIXME: make it configurable */ + +/* -- AVP - Vendor name */ +#define PPPOL2TP_AVPTYPE_VENDORNAME 8 /* Vendor name */ +#define PPPOL2TP_VENDORNAME "lwIP" /* FIXME: make it configurable */ + +/* -- AVP - Assign tunnel ID */ +#define PPPOL2TP_AVPTYPE_TUNNELID 9 /* Assign Tunnel ID */ + +/* -- AVP - Receive window size */ +#define PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE 10 /* Receive window size */ +#define PPPOL2TP_RECEIVEWINDOWSIZE 8 /* FIXME: make it configurable */ + +/* -- AVP - Challenge */ +#define PPPOL2TP_AVPTYPE_CHALLENGE 11 /* Challenge */ + +/* -- AVP - Cause code */ +#define PPPOL2TP_AVPTYPE_CAUSECODE 12 /* Cause code*/ + +/* -- AVP - Challenge response */ +#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE 13 /* Challenge response */ +#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE 16 + +/* -- AVP - Assign session ID */ +#define PPPOL2TP_AVPTYPE_SESSIONID 14 /* Assign Session ID */ + +/* -- AVP - Call serial number */ +#define PPPOL2TP_AVPTYPE_CALLSERIALNUMBER 15 /* Call Serial Number */ + +/* -- AVP - Framing type */ +#define PPPOL2TP_AVPTYPE_FRAMINGTYPE 19 /* Framing Type */ +#define PPPOL2TP_FRAMINGTYPE 0x00000001 /* Sync framing */ + +/* -- AVP - TX Connect Speed */ +#define PPPOL2TP_AVPTYPE_TXCONNECTSPEED 24 /* TX Connect Speed */ +#define PPPOL2TP_TXCONNECTSPEED 100000000 /* Connect speed: 100 Mbits/s */ + +/* L2TP Session state */ +#define PPPOL2TP_STATE_INITIAL 0 +#define PPPOL2TP_STATE_SCCRQ_SENT 1 +#define PPPOL2TP_STATE_ICRQ_SENT 2 +#define PPPOL2TP_STATE_ICCN_SENT 3 +#define PPPOL2TP_STATE_DATA 4 + +#define PPPOL2TP_CB_STATE_UP 0 /* PPPoL2TP link is UP */ +#define PPPOL2TP_CB_STATE_DOWN 1 /* PPPo2TP link is DOWN - normal condition */ +#define PPPOL2TP_CB_STATE_FAILED 2 /* Failed to setup PPPo2TP link */ + +#define PPPOL2TP_OUTPUT_DATA_HEADER_LEN 6 /* Our data header len */ + +/* + * PPPoL2TP interface control block. + */ +typedef struct pppol2tp_pcb_s pppol2tp_pcb; +struct pppol2tp_pcb_s { + ppp_pcb *ppp; /* PPP PCB */ + u8_t phase; /* L2TP phase */ + void (*link_status_cb)(ppp_pcb *pcb, int status); + struct udp_pcb *udp; /* UDP L2TP Socket */ + struct netif *netif; /* Output interface, used as a default route */ + ip_addr_t remote_ip; /* LNS IP Address */ + u16_t remote_port; /* LNS port */ +#if PPPOL2TP_AUTH_SUPPORT + u8_t *secret; /* Secret string */ + u8_t secret_len; /* Secret string length */ + u8_t secret_rv[16]; /* Random vector */ + u8_t challenge_hash[16]; /* Challenge response */ + u8_t send_challenge; /* Boolean whether the next sent packet should contains a challenge response */ +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + u16_t tunnel_port; /* Tunnel port */ + u16_t our_ns; /* NS to peer */ + u16_t peer_nr; /* NR from peer */ + u16_t peer_ns; /* NS from peer */ + u16_t source_tunnel_id; /* Tunnel ID assigned by peer */ + u16_t remote_tunnel_id; /* Tunnel ID assigned to peer */ + u16_t source_session_id; /* Session ID assigned by peer */ + u16_t remote_session_id; /* Session ID assigned to peer */ + + u8_t sccrq_retried; /* number of SCCRQ retries already done */ + u8_t icrq_retried; /* number of ICRQ retries already done */ + u8_t iccn_retried; /* number of ICCN retries already done */ +}; + + +/* Create a new L2TP session. */ +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), pppol2tp_pcb **l2tpptr, + struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len); + +/* Destroy a L2TP control block */ +err_t pppol2tp_destroy(pppol2tp_pcb *l2tp); + +/* Be a LAC, connect to a LNS. */ +err_t pppol2tp_connect(pppol2tp_pcb *l2tp); + +/* Disconnect */ +void pppol2tp_disconnect(pppol2tp_pcb *l2tp); + +/* Data packet from PPP to L2TP */ +err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); + +#endif /* PPPOL2TP_H_ */ +#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/upap.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/upap.h new file mode 100644 index 0000000..bb9309b --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/upap.h @@ -0,0 +1,123 @@ +/* + * upap.h - User/Password Authentication Protocol definitions. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef UPAP_H +#define UPAP_H + +#include "ppp.h" + +/* + * Packet header = Code, id, length. + */ +#define UPAP_HEADERLEN 4 + + +/* + * UPAP codes. + */ +#define UPAP_AUTHREQ 1 /* Authenticate-Request */ +#define UPAP_AUTHACK 2 /* Authenticate-Ack */ +#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ + + +/* + * Client states. + */ +#define UPAPCS_INITIAL 0 /* Connection down */ +#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ +#define UPAPCS_OPEN 4 /* We've received an Ack */ +#define UPAPCS_BADAUTH 5 /* We've received a Nak */ + +/* + * Server states. + */ +#define UPAPSS_INITIAL 0 /* Connection down */ +#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ +#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ +#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ +#define UPAPSS_OPEN 4 /* We've sent an Ack */ +#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ + + +/* + * Timeouts. + */ +#if 0 /* moved to opt.h */ +#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ +#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ +#endif /* moved to opt.h */ + +/* + * Each interface is described by upap structure. + */ +#if PAP_SUPPORT +typedef struct upap_state { + const char *us_user; /* User */ + u8_t us_userlen; /* User length */ + const char *us_passwd; /* Password */ + u8_t us_passwdlen; /* Password length */ + u8_t us_clientstate; /* Client state */ +#if PPP_SERVER + u8_t us_serverstate; /* Server state */ +#endif /* PPP_SERVER */ + u8_t us_id; /* Current id */ + u8_t us_transmits; /* Number of auth-reqs sent */ +} upap_state; +#endif /* PAP_SUPPORT */ + + +void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password); +#if PPP_SERVER +void upap_authpeer(ppp_pcb *pcb); +#endif /* PPP_SERVER */ + +extern const struct protent pap_protent; + +#endif /* UPAP_H */ +#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/vj.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/vj.h new file mode 100644 index 0000000..3780667 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/ppp/vj.h @@ -0,0 +1,161 @@ +/* + * Definitions for tcp compression routines. + * + * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * - Initial distribution. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#ifndef VJ_H +#define VJ_H + +#include "lwip/ip.h" +#include "lwip/tcp_impl.h" + +#define MAX_SLOTS 16 /* must be > 2 and < 256 */ +#define MAX_HDR 128 + +/* + * Compressed packet format: + * + * The first octet contains the packet type (top 3 bits), TCP + * 'push' bit, and flags that indicate which of the 4 TCP sequence + * numbers have changed (bottom 5 bits). The next octet is a + * conversation number that associates a saved IP/TCP header with + * the compressed packet. The next two octets are the TCP checksum + * from the original datagram. The next 0 to 15 octets are + * sequence number changes, one change per bit set in the header + * (there may be no changes and there are two special cases where + * the receiver implicitly knows what changed -- see below). + * + * There are 5 numbers which can change (they are always inserted + * in the following order): TCP urgent pointer, window, + * acknowlegement, sequence number and IP ID. (The urgent pointer + * is different from the others in that its value is sent, not the + * change in value.) Since typical use of SLIP links is biased + * toward small packets (see comments on MTU/MSS below), changes + * use a variable length coding with one octet for numbers in the + * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the + * range 256 - 65535 or 0. (If the change in sequence number or + * ack is more than 65535, an uncompressed packet is sent.) + */ + +/* + * Packet types (must not conflict with IP protocol version) + * + * The top nibble of the first octet is the packet type. There are + * three possible types: IP (not proto TCP or tcp with one of the + * control flags set); uncompressed TCP (a normal IP/TCP packet but + * with the 8-bit protocol field replaced by an 8-bit connection id -- + * this type of packet syncs the sender & receiver); and compressed + * TCP (described above). + * + * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and + * is logically part of the 4-bit "changes" field that follows. Top + * three bits are actual packet type. For backward compatibility + * and in the interest of conserving bits, numbers are chosen so the + * IP protocol version number (4) which normally appears in this nibble + * means "IP packet". + */ + +/* packet types */ +#define TYPE_IP 0x40 +#define TYPE_UNCOMPRESSED_TCP 0x70 +#define TYPE_COMPRESSED_TCP 0x80 +#define TYPE_ERROR 0x00 + +/* Bits in first octet of compressed packet */ +#define NEW_C 0x40 /* flag bits for what changed in a packet */ +#define NEW_I 0x20 +#define NEW_S 0x08 +#define NEW_A 0x04 +#define NEW_W 0x02 +#define NEW_U 0x01 + +/* reserved, special-case values of above */ +#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ +#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ +#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) + +#define TCP_PUSH_BIT 0x10 + + +/* + * "state" data for each active tcp conversation on the wire. This is + * basically a copy of the entire IP/TCP header from the last packet + * we saw from the conversation together with a small identifier + * the transmit & receive ends of the line use to locate saved header. + */ +struct cstate { + struct cstate *cs_next; /* next most recently used state (xmit only) */ + u_short cs_hlen; /* size of hdr (receive only) */ + u_char cs_id; /* connection # associated with this state */ + u_char cs_filler; + union { + char csu_hdr[MAX_HDR]; + struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ + } vjcs_u; +}; +#define cs_ip vjcs_u.csu_ip +#define cs_hdr vjcs_u.csu_hdr + + +struct vjstat { + unsigned long vjs_packets; /* outbound packets */ + unsigned long vjs_compressed; /* outbound compressed packets */ + unsigned long vjs_searches; /* searches for connection state */ + unsigned long vjs_misses; /* times couldn't find conn. state */ + unsigned long vjs_uncompressedin; /* inbound uncompressed packets */ + unsigned long vjs_compressedin; /* inbound compressed packets */ + unsigned long vjs_errorin; /* inbound unknown type packets */ + unsigned long vjs_tossed; /* inbound packets tossed because of error */ +}; + +/* + * all the state data for one serial line (we need one of these per line). + */ +struct vjcompress { + struct cstate *last_cs; /* most recently used tstate */ + u_char last_recv; /* last rcvd conn. id */ + u_char last_xmit; /* last sent conn. id */ + u_short flags; + u_char maxSlotIndex; + u_char compressSlot; /* Flag indicating OK to compress slot ID. */ +#if LINK_STATS + struct vjstat stats; +#endif + struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ + struct cstate rstate[MAX_SLOTS]; /* receive connection states */ +}; + +/* flag values */ +#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ + +extern void vj_compress_init (struct vjcompress *comp); +extern u_int vj_compress_tcp (struct vjcompress *comp, struct pbuf *pb); +extern void vj_uncompress_err (struct vjcompress *comp); +extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); +extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); + +#endif /* VJ_H */ + +#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/slipif.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/slipif.h new file mode 100644 index 0000000..dc40d30 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/netif/slipif.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef LWIP_HDR_NETIF_SLIPIF_H +#define LWIP_HDR_NETIF_SLIPIF_H + +#include "lwip/opt.h" +#include "lwip/netif.h" + +/** Set this to 1 to start a thread that blocks reading on the serial line + * (using sio_read()). + */ +#ifndef SLIP_USE_RX_THREAD +#define SLIP_USE_RX_THREAD !NO_SYS +#endif + +/** Set this to 1 to enable functions to pass in RX bytes from ISR context. + * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled + * packets on a queue, which is fed into lwIP from slipif_poll(). + * If disabled, slipif_poll() polls the serial line (using sio_tryread()). + */ +#ifndef SLIP_RX_FROM_ISR +#define SLIP_RX_FROM_ISR 0 +#endif + +/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets + * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. + * If disabled, packets will be dropped if more than one packet is received. + */ +#ifndef SLIP_RX_QUEUE +#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +err_t slipif_init(struct netif * netif); +void slipif_poll(struct netif *netif); +#if SLIP_RX_FROM_ISR +void slipif_process_rxqueue(struct netif *netif); +void slipif_received_byte(struct netif *netif, u8_t data); +void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); +#endif /* SLIP_RX_FROM_ISR */ + +#ifdef __cplusplus +} +#endif + +#endif /* LWIP_HDR_NETIF_SLIPIF_H */ + diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/netdb.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/netdb.h new file mode 100644 index 0000000..7134032 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/netdb.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/netdb.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/netdb.h" diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/sys/socket.h b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/sys/socket.h new file mode 100644 index 0000000..f7c7066 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/include/posix/sys/socket.h @@ -0,0 +1,33 @@ +/** + * @file + * This file is a posix wrapper for lwip/sockets.h. + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/sockets.h" diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/FILES b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/FILES new file mode 100644 index 0000000..099dbf3 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/FILES @@ -0,0 +1,29 @@ +This directory contains generic network interface device drivers that +do not contain any hardware or architecture specific code. The files +are: + +etharp.c + Implements the ARP (Address Resolution Protocol) over + Ethernet. The code in this file should be used together with + Ethernet device drivers. Note that this module has been + largely made Ethernet independent so you should be able to + adapt this for other link layers (such as Firewire). + +ethernetif.c + An example of how an Ethernet device driver could look. This + file can be used as a "skeleton" for developing new Ethernet + network device drivers. It uses the etharp.c ARP code. + +loopif.c + A "loopback" network interface driver. It requires configuration + through the define LWIP_LOOPIF_MULTITHREADING (see opt.h). + +slipif.c + A generic implementation of the SLIP (Serial Line IP) + protocol. It requires a sio (serial I/O) module to work. + +ppp/ Point-to-Point Protocol stack + The PPP stack has been ported from ucip (http://ucip.sourceforge.net). + It matches quite well to pppd 2.3.1 (http://ppp.samba.org), although + compared to that, it has some modifications for embedded systems and + the source code has been reordered a bit. \ No newline at end of file diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/etharp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/etharp.c new file mode 100644 index 0000000..b00cd80 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/etharp.c @@ -0,0 +1,1484 @@ +/** + * @file + * Address Resolution Protocol module for IP over Ethernet + * + * Functionally, ARP is divided into two parts. The first maps an IP address + * to a physical address when sending a packet, and the second part answers + * requests from other machines for our physical address. + * + * This implementation complies with RFC 826 (Ethernet ARP). It supports + * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 + * if an interface calls etharp_gratuitous(our_netif) upon address change. + */ + +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * Copyright (c) 2003-2004 Leon Woestenberg + * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +#include "lwip/opt.h" + +#if LWIP_ARP || LWIP_ETHERNET + +#include "lwip/ip_addr.h" +#include "lwip/def.h" +#include "lwip/lwip_ip.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/dhcp.h" +#include "lwip/autoip.h" +#include "netif/etharp.h" +#include "lwip/ip6.h" + +#if PPPOE_SUPPORT +#include "netif/ppp/pppoe.h" +#endif /* PPPOE_SUPPORT */ + +#include + +const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; +const struct eth_addr ethzero = {{0,0,0,0,0,0}}; + +/** The 24-bit IANA multicast OUI is 01-00-5e: */ +#define LL_MULTICAST_ADDR_0 0x01 +#define LL_MULTICAST_ADDR_1 0x00 +#define LL_MULTICAST_ADDR_2 0x5e + +#if LWIP_ARP /* don't build if not configured for use in lwipopts.h */ + +/** the time an ARP entry stays valid after its last update, + * for ARP_TMR_INTERVAL = 1000, this is + * (60 * 20) seconds = 20 minutes. + */ +#define ARP_MAXAGE 1200 +/** Re-request a used ARP entry 1 minute before it would expire to prevent + * breaking a steadily used connection because the ARP entry timed out. */ +#define ARP_AGE_REREQUEST_USED (ARP_MAXAGE - 60) + +/** the time an ARP entry stays pending after first request, + * for ARP_TMR_INTERVAL = 1000, this is + * 10 seconds. + * + * @internal Keep this number at least 2, otherwise it might + * run out instantly if the timeout occurs directly after a request. + */ +#define ARP_MAXPENDING 5 + +#define HWTYPE_ETHERNET 1 + +enum etharp_state { + ETHARP_STATE_EMPTY = 0, + ETHARP_STATE_PENDING, + ETHARP_STATE_STABLE, + ETHARP_STATE_STABLE_REREQUESTING +#if ETHARP_SUPPORT_STATIC_ENTRIES + ,ETHARP_STATE_STATIC +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ +}; + +struct etharp_entry { +#if ARP_QUEUEING + /** Pointer to queue of pending outgoing packets on this ARP entry. */ + struct etharp_q_entry *q; +#else /* ARP_QUEUEING */ + /** Pointer to a single pending outgoing packet on this ARP entry. */ + struct pbuf *q; +#endif /* ARP_QUEUEING */ + ip_addr_t ipaddr; + struct netif *netif; + struct eth_addr ethaddr; + u16_t ctime; + u8_t state; +}; + +static struct etharp_entry arp_table[ARP_TABLE_SIZE]; + +#if !LWIP_NETIF_HWADDRHINT +static u8_t etharp_cached_entry; +#endif /* !LWIP_NETIF_HWADDRHINT */ + +/** Try hard to create a new entry - we want the IP address to appear in + the cache (even if this means removing an active entry or so). */ +#define ETHARP_FLAG_TRY_HARD 1 +#define ETHARP_FLAG_FIND_ONLY 2 +#if ETHARP_SUPPORT_STATIC_ENTRIES +#define ETHARP_FLAG_STATIC_ENTRY 4 +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +#if LWIP_NETIF_HWADDRHINT +#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ + *((netif)->addr_hint) = (hint); +#else /* LWIP_NETIF_HWADDRHINT */ +#define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) +#endif /* LWIP_NETIF_HWADDRHINT */ + + +/* Some checks, instead of etharp_init(): */ +#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) + #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" +#endif + + +#if ARP_QUEUEING +/** + * Free a complete queue of etharp entries + * + * @param q a qeueue of etharp_q_entry's to free + */ +static void +free_etharp_q(struct etharp_q_entry *q) +{ + struct etharp_q_entry *r; + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("q->p != NULL", q->p != NULL); + while (q) { + r = q; + q = q->next; + LWIP_ASSERT("r->p != NULL", (r->p != NULL)); + pbuf_free(r->p); + memp_free(MEMP_ARP_QUEUE, r); + } +} +#else /* ARP_QUEUEING */ + +/** Compatibility define: free the queued pbuf */ +#define free_etharp_q(q) pbuf_free(q) + +#endif /* ARP_QUEUEING */ + +/** Clean up ARP table entries */ +static void +etharp_free_entry(int i) +{ + /* remove from SNMP ARP index tree */ + snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr); + /* and empty packet queue */ + if (arp_table[i].q != NULL) { + /* remove all queued packets */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); + free_etharp_q(arp_table[i].q); + arp_table[i].q = NULL; + } + /* recycle entry for re-use */ + arp_table[i].state = ETHARP_STATE_EMPTY; +#ifdef LWIP_DEBUG + /* for debugging, clean out the complete entry */ + arp_table[i].ctime = 0; + arp_table[i].netif = NULL; + ip_addr_set_zero(&arp_table[i].ipaddr); + arp_table[i].ethaddr = ethzero; +#endif /* LWIP_DEBUG */ +} + +/** + * Clears expired entries in the ARP table. + * + * This function should be called every ETHARP_TMR_INTERVAL milliseconds (5 seconds), + * in order to expire entries in the ARP table. + */ +void +etharp_tmr(void) +{ + u8_t i; + + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); + /* remove expired entries from the ARP table */ + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if (state != ETHARP_STATE_EMPTY +#if ETHARP_SUPPORT_STATIC_ENTRIES + && (state != ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + ) { + arp_table[i].ctime++; + if ((arp_table[i].ctime >= ARP_MAXAGE) || + ((arp_table[i].state == ETHARP_STATE_PENDING) && + (arp_table[i].ctime >= ARP_MAXPENDING))) { + /* pending or stable entry has become old! */ + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", + arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); + /* clean up entries that have just been expired */ + etharp_free_entry(i); + } + else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING) { + /* Reset state to stable, so that the next transmitted packet will + re-send an ARP request. */ + arp_table[i].state = ETHARP_STATE_STABLE; + } + /* still pending entry? (not expired) */ + else if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* resend an ARP query here? */ + if (etharp_request(arp_table[i].netif, &arp_table[i].ipaddr) != ERR_OK) { + } + } + } + } +} + +/** + * Search the ARP table for a matching or new entry. + * + * If an IP address is given, return a pending or stable ARP entry that matches + * the address. If no match is found, create a new entry with this address set, + * but in state ETHARP_EMPTY. The caller must check and possibly change the + * state of the returned entry. + * + * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. + * + * In all cases, attempt to create new entries from an empty entry. If no + * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle + * old entries. Heuristic choose the least important entry for recycling. + * + * @param ipaddr IP address to find in ARP cache, or to add if not found. + * @param flags @see definition of ETHARP_FLAG_* + * @param netif netif related to this address (used for NETIF_HWADDRHINT) + * + * @return The ARP entry index that matched or is created, ERR_MEM if no + * entry is found or could be recycled. + */ +static s8_t +etharp_find_entry(ip_addr_t *ipaddr, u8_t flags) +{ + s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; + s8_t empty = ARP_TABLE_SIZE; + u8_t i = 0; + /* oldest entry with packets on queue */ + s8_t old_queue = ARP_TABLE_SIZE; + /* its age */ + u16_t age_queue = 0, age_pending = 0, age_stable = 0; + + /** + * a) do a search through the cache, remember candidates + * b) select candidate entry + * c) create new entry + */ + + /* a) in a single search sweep, do all of this + * 1) remember the first empty entry (if any) + * 2) remember the oldest stable entry (if any) + * 3) remember the oldest pending entry without queued packets (if any) + * 4) remember the oldest pending entry with queued packets (if any) + * 5) search for a matching IP entry, either pending or stable + * until 5 matches, or all entries are searched for. + */ + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + /* no empty entry found yet and now we do find one? */ + if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { + LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); + /* remember first empty entry */ + empty = i; + } else if (state != ETHARP_STATE_EMPTY) { + LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", + state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); + /* if given, does IP address match IP address in ARP entry? */ + if (ipaddr && ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); + /* found exact IP address match, simply bail out */ + return i; + } + /* pending entry? */ + if (state == ETHARP_STATE_PENDING) { + /* pending with queued packets? */ + if (arp_table[i].q != NULL) { + if (arp_table[i].ctime >= age_queue) { + old_queue = i; + age_queue = arp_table[i].ctime; + } + } else + /* pending without queued packets? */ + { + if (arp_table[i].ctime >= age_pending) { + old_pending = i; + age_pending = arp_table[i].ctime; + } + } + /* stable entry? */ + } else if (state >= ETHARP_STATE_STABLE) { +#if ETHARP_SUPPORT_STATIC_ENTRIES + /* don't record old_stable for static entries since they never expire */ + if (state < ETHARP_STATE_STATIC) +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* remember entry with oldest stable entry in oldest, its age in maxtime */ + if (arp_table[i].ctime >= age_stable) { + old_stable = i; + age_stable = arp_table[i].ctime; + } + } + } + } + } + /* { we have no match } => try to create a new entry */ + + /* don't create new entry, only search? */ + if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || + /* or no empty entry found and not allowed to recycle? */ + ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); + return (s8_t)ERR_MEM; + } + + /* b) choose the least destructive entry to recycle: + * 1) empty entry + * 2) oldest stable entry + * 3) oldest pending entry without queued packets + * 4) oldest pending entry with queued packets + * + * { ETHARP_FLAG_TRY_HARD is set at this point } + */ + + /* 1) empty entry available? */ + if (empty < ARP_TABLE_SIZE) { + i = empty; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); + } else { + /* 2) found recyclable stable entry? */ + if (old_stable < ARP_TABLE_SIZE) { + /* recycle oldest stable*/ + i = old_stable; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); + /* no queued packets should exist on stable entries */ + LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); + /* 3) found recyclable pending entry without queued packets? */ + } else if (old_pending < ARP_TABLE_SIZE) { + /* recycle oldest pending */ + i = old_pending; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); + /* 4) found recyclable pending entry with queued packets? */ + } else if (old_queue < ARP_TABLE_SIZE) { + /* recycle oldest pending (queued packets are free in etharp_free_entry) */ + i = old_queue; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); + /* no empty or recyclable entries found */ + } else { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); + return (s8_t)ERR_MEM; + } + + /* { empty or recyclable entry found } */ + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + etharp_free_entry(i); + } + + LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); + LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", + arp_table[i].state == ETHARP_STATE_EMPTY); + + /* IP address given? */ + if (ipaddr != NULL) { + /* set IP address */ + ip_addr_copy(arp_table[i].ipaddr, *ipaddr); + } + arp_table[i].ctime = 0; + return (err_t)i; +} + +/** + * Send an IP packet on the network using netif->linkoutput + * The ethernet header is filled in before sending. + * + * @params netif the lwIP network interface on which to send the packet + * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header + * @params src the source MAC address to be copied into the ethernet header + * @params dst the destination MAC address to be copied into the ethernet header + * @return ERR_OK if the packet was sent, any other err_t on failure + */ +static err_t +etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst) +{ + struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload; +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + struct eth_vlan_hdr *vlanhdr; +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + ethhdr->type = PP_HTONS(ETHTYPE_VLAN); + vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR); + vlanhdr->prio_vid = 0; + vlanhdr->tpid = PP_HTONS(ETHTYPE_IP); + if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) { + /* packet shall not contain VLAN header, so hide it and set correct ethertype */ + pbuf_header(p, -SIZEOF_VLAN_HDR); + ethhdr = (struct eth_hdr *)p->payload; +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + ethhdr->type = PP_HTONS(ETHTYPE_IP); +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + } +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + ETHADDR32_COPY(ðhdr->dest, dst); + ETHADDR16_COPY(ðhdr->src, src); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p)); + /* send the packet */ + return netif->linkoutput(netif, p); +} + +/** + * Update (or insert) a IP/MAC address pair in the ARP cache. + * + * If a pending entry is resolved, any queued packets will be sent + * at this point. + * + * @param netif netif related to this entry (used for NETIF_ADDRHINT) + * @param ipaddr IP address of the inserted ARP entry. + * @param ethaddr Ethernet address of the inserted ARP entry. + * @param flags @see definition of ETHARP_FLAG_* + * + * @return + * - ERR_OK Successfully updated ARP cache. + * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + * @see pbuf_free() + */ +static err_t +etharp_update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) +{ + s8_t i; + LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + /* non-unicast address? */ + if (ip_addr_isany(ipaddr) || + ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, flags); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + +#if ETHARP_SUPPORT_STATIC_ENTRIES + if (flags & ETHARP_FLAG_STATIC_ENTRY) { + /* record static type */ + arp_table[i].state = ETHARP_STATE_STATIC; + } else +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + { + /* mark it stable */ + arp_table[i].state = ETHARP_STATE_STABLE; + } + + /* record network interface */ + arp_table[i].netif = netif; + /* insert in SNMP ARP index tree */ + snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr); + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); + /* update address */ + ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); + /* reset time stamp */ + arp_table[i].ctime = 0; + /* this is where we will send out queued packets! */ +#if ARP_QUEUEING + while (arp_table[i].q != NULL) { + struct pbuf *p; + /* remember remainder of queue */ + struct etharp_q_entry *q = arp_table[i].q; + /* pop first item off the queue */ + arp_table[i].q = q->next; + /* get the packet pointer */ + p = q->p; + /* now queue entry can be freed */ + memp_free(MEMP_ARP_QUEUE, q); +#else /* ARP_QUEUEING */ + if (arp_table[i].q != NULL) { + struct pbuf *p = arp_table[i].q; + arp_table[i].q = NULL; +#endif /* ARP_QUEUEING */ + /* send the queued IP packet */ + etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr); + /* free the queued IP packet */ + pbuf_free(p); + } + return ERR_OK; +} + +#if ETHARP_SUPPORT_STATIC_ENTRIES +/** Add a new static entry to the ARP table. If an entry exists for the + * specified IP address, this entry is overwritten. + * If packets are queued for the specified IP address, they are sent out. + * + * @param ipaddr IP address for the new static entry + * @param ethaddr ethernet address for the new static entry + * @return @see return values of etharp_add_static_entry + */ +err_t +etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr) +{ + struct netif *netif; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), + ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2], + ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5])); + + netif = ip_route(ipaddr); + if (netif == NULL) { + return ERR_RTE; + } + + return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); +} + +/** Remove a static entry from the ARP table previously added with a call to + * etharp_add_static_entry. + * + * @param ipaddr IP address of the static entry to remove + * @return ERR_OK: entry removed + * ERR_MEM: entry wasn't found + * ERR_ARG: entry wasn't a static entry but a dynamic one + */ +err_t +etharp_remove_static_entry(ip_addr_t *ipaddr) +{ + s8_t i; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", + ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); + + /* find or create ARP entry */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + /* bail out if no entry could be found */ + if (i < 0) { + return (err_t)i; + } + + if (arp_table[i].state != ETHARP_STATE_STATIC) { + /* entry wasn't a static entry, cannot remove it */ + return ERR_ARG; + } + /* entry found, free it */ + etharp_free_entry(i); + return ERR_OK; +} +#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ + +/** + * Remove all ARP table entries of the specified netif. + * + * @param netif points to a network interface + */ +void etharp_cleanup_netif(struct netif *netif) +{ + u8_t i; + + for (i = 0; i < ARP_TABLE_SIZE; ++i) { + u8_t state = arp_table[i].state; + if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { + etharp_free_entry(i); + } + } +} + +/** + * Finds (stable) ethernet/IP address pair from ARP table + * using interface and IP address index. + * @note the addresses in the ARP table are in network order! + * + * @param netif points to interface index + * @param ipaddr points to the (network order) IP address index + * @param eth_ret points to return pointer + * @param ip_ret points to return pointer + * @return table index if found, -1 otherwise + */ +s8_t +etharp_find_addr(struct netif *netif, ip_addr_t *ipaddr, + struct eth_addr **eth_ret, ip_addr_t **ip_ret) +{ + s8_t i; + + LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", + eth_ret != NULL && ip_ret != NULL); + + LWIP_UNUSED_ARG(netif); + + i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY); + if((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { + *eth_ret = &arp_table[i].ethaddr; + *ip_ret = &arp_table[i].ipaddr; + return i; + } + return -1; +} + +#if ETHARP_TRUST_IP_MAC +/** + * Updates the ARP table using the given IP packet. + * + * Uses the incoming IP packet's source address to update the + * ARP cache for the local network. The function does not alter + * or free the packet. This function must be called before the + * packet p is passed to the IP layer. + * + * @param netif The lwIP network interface on which the IP packet pbuf arrived. + * @param p The IP packet that arrived on netif. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_ip_input(struct netif *netif, struct pbuf *p) +{ + struct eth_hdr *ethhdr; + struct ip_hdr *iphdr; + ip_addr_t iphdr_src; + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* Only insert an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + ethhdr = (struct eth_hdr *)p->payload; + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + ip_addr_copy(iphdr_src, iphdr->src); + + /* source is not on the local network? */ + if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) { + /* do nothing */ + return; + } + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n")); + /* update the source IP address in the cache, if present */ + /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk + * back soon (for example, if the destination IP address is ours. */ + etharp_update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY); +} +#endif /* ETHARP_TRUST_IP_MAC */ + +/** + * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache + * send out queued IP packets. Updates cache with snooped address pairs. + * + * Should be called for incoming ARP packets. The pbuf in the argument + * is freed by this function. + * + * @param netif The lwIP network interface on which the ARP packet pbuf arrived. + * @param ethaddr Ethernet address of netif. + * @param p The ARP packet that arrived on netif. Is freed by this function. + * + * @return NULL + * + * @see pbuf_free() + */ +static void +etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p) +{ + struct etharp_hdr *hdr; + struct eth_hdr *ethhdr; + /* these are aligned properly, whereas the ARP header fields might not be */ + ip_addr_t sipaddr, dipaddr; + u8_t for_us; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ERROR("netif != NULL", (netif != NULL), return;); + + /* drop short ARP packets: we have to check for p->len instead of p->tot_len here + since a struct etharp_hdr is pointed to p->payload, so it musn't be chained! */ + if (p->len < SIZEOF_ETHARP_PACKET) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, + (s16_t)SIZEOF_ETHARP_PACKET)); + ETHARP_STATS_INC(etharp.lenerr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + + ethhdr = (struct eth_hdr *)p->payload; + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#if ETHARP_SUPPORT_VLAN + if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) { + hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); + } +#endif /* ETHARP_SUPPORT_VLAN */ + + /* RFC 826 "Packet Reception": */ + if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || + (hdr->hwlen != ETHARP_HWADDR_LEN) || + (hdr->protolen != sizeof(ip_addr_t)) || + (hdr->proto != PP_HTONS(ETHTYPE_IP))) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, + ("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", + hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen)); + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + pbuf_free(p); + return; + } + ETHARP_STATS_INC(etharp.recv); + +#if LWIP_AUTOIP + /* We have to check if a host already has configured our random + * created link local address and continuously check if there is + * a host with this IP-address so we can detect collisions */ + autoip_arp_reply(netif, hdr); +#endif /* LWIP_AUTOIP */ + + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing (not using structure copy which breaks strict-aliasing rules). */ + IPADDR2_COPY(&sipaddr, &hdr->sipaddr); + IPADDR2_COPY(&dipaddr, &hdr->dipaddr); + + /* this interface is not configured? */ + if (ip_addr_isany(&netif->ip_addr)) { + for_us = 0; + } else { + /* ARP packet directed to us? */ + for_us = (u8_t)ip_addr_cmp(&dipaddr, &(netif->ip_addr)); + } + + /* ARP message directed to us? + -> add IP address in ARP cache; assume requester wants to talk to us, + can result in directly sending the queued packets for this host. + ARP message not directed to us? + -> update the source IP address in the cache, if present */ + etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), + for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); + + /* now act on the message itself */ + switch (hdr->opcode) { + /* ARP request? */ + case PP_HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + * reply. In any case, we time-stamp any existing ARP entry, + * and possibly send out an IP packet that was queued on it. */ + + LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP request\n")); + /* ARP request for our address? */ + if (for_us) { + + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n")); + /* Re-use pbuf to send ARP reply. + Since we are re-using an existing pbuf, we can't call etharp_raw since + that would allocate a new pbuf. */ + hdr->opcode = htons(ARP_REPLY); + + IPADDR2_COPY(&hdr->dipaddr, &hdr->sipaddr); + IPADDR2_COPY(&hdr->sipaddr, &netif->ip_addr); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(&netif->ip_addr) ? (u8_t*)(ethbroadcast.addr) : hdr->shwaddr.addr; +#endif /* LWIP_AUTOIP */ + + ETHADDR16_COPY(&hdr->dhwaddr, &hdr->shwaddr); +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, &hdr->shwaddr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(&hdr->shwaddr, ethaddr); + ETHADDR16_COPY(ðhdr->src, ethaddr); + + /* hwtype, hwaddr_len, proto, protolen and the type in the ethernet header + are already correct, we tested that before */ + + /* return ARP reply */ + netif->linkoutput(netif, p); + /* we are not configured? */ + } else if (ip_addr_isany(&netif->ip_addr)) { + /* { for_us == 0 and netif->ip_addr.addr == 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n")); + /* request was not directed to us */ + } else { + /* { for_us == 0 and netif->ip_addr.addr != 0 } */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n")); + } + break; + case PP_HTONS(ARP_REPLY): + /* ARP reply. We already updated the ARP cache earlier. */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n")); +#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) + /* DHCP wants to know about ARP replies from any host with an + * IP address also offered to us by the DHCP server. We do not + * want to take a duplicate IP address on a single network. + * @todo How should we handle redundant (fail-over) interfaces? */ + dhcp_arp_reply(netif, &sipaddr); +#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ + break; + default: + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode))); + ETHARP_STATS_INC(etharp.err); + break; + } + /* free ARP packet */ + pbuf_free(p); +} + +/** Just a small helper function that sends a pbuf to an ethernet address + * in the arp_table specified by the index 'arp_idx'. + */ +static err_t +etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) +{ + LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", + arp_table[arp_idx].state >= ETHARP_STATE_STABLE); + /* if arp table entry is about to expire: re-request it, + but only if its state is ETHARP_STATE_STABLE to prevent flooding the + network with ARP requests if this address is used frequently. */ + if ((arp_table[arp_idx].state == ETHARP_STATE_STABLE) && + (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED)) { + if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { + arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING; + } + } + + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), + &arp_table[arp_idx].ethaddr); +} + +/** + * Resolve and fill-in Ethernet address header for outgoing IP packet. + * + * For IP multicast and broadcast, corresponding Ethernet addresses + * are selected and the packet is transmitted on the link. + * + * For unicast addresses, the packet is submitted to etharp_query(). In + * case the IP address is outside the local network, the IP address of + * the gateway is used. + * + * @param netif The lwIP network interface which the IP packet will be sent on. + * @param q The pbuf(s) containing the IP packet to be sent. + * @param ipaddr The IP address of the packet destination. + * + * @return + * - ERR_RTE No route to destination (no gateway to external networks), + * or the return type of either etharp_query() or etharp_send_ip(). + */ +err_t +etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) +{ + struct eth_addr *dest; + struct eth_addr mcastaddr; + ip_addr_t *dst_addr = ipaddr; + + LWIP_ASSERT("netif != NULL", netif != NULL); + LWIP_ASSERT("q != NULL", q != NULL); + LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); + + /* make room for Ethernet header - should not fail */ +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + if (pbuf_header(q, sizeof(struct eth_hdr) + SIZEOF_VLAN_HDR) != 0) { +#else /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) { +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + /* bail out */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_output: could not allocate room for header.\n")); + LINK_STATS_INC(link.lenerr); + return ERR_BUF; + } + + /* Determine on destination hardware address. Broadcasts and multicasts + * are special, other IP addresses are looked up in the ARP table. */ + + /* broadcast destination IP address? */ + if (ip_addr_isbroadcast(ipaddr, netif)) { + /* broadcast on Ethernet also */ + dest = (struct eth_addr *)ðbroadcast; + /* multicast destination IP address? */ + } else if (ip_addr_ismulticast(ipaddr)) { + /* Hash IP multicast address to MAC address.*/ + mcastaddr.addr[0] = LL_MULTICAST_ADDR_0; + mcastaddr.addr[1] = LL_MULTICAST_ADDR_1; + mcastaddr.addr[2] = LL_MULTICAST_ADDR_2; + mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; + mcastaddr.addr[4] = ip4_addr3(ipaddr); + mcastaddr.addr[5] = ip4_addr4(ipaddr); + /* destination Ethernet address is multicast */ + dest = &mcastaddr; + /* unicast destination IP address? */ + } else { + s8_t i; + /* outside local network? if so, this can neither be a global broadcast nor + a subnet broadcast. */ + if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) && + !ip_addr_islinklocal(ipaddr)) { +#if LWIP_AUTOIP + struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload + +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + SIZEOF_VLAN_HDR + +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + sizeof(struct eth_hdr)); + /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with + a link-local source address must always be "directly to its destination + on the same physical link. The host MUST NOT send the packet to any + router for forwarding". */ + if (!ip_addr_islinklocal(&iphdr->src)) +#endif /* LWIP_AUTOIP */ + { +#ifdef LWIP_HOOK_ETHARP_GET_GW + /* For advanced routing, a single default gateway might not be enough, so get + the IP address of the gateway to handle the current destination address. */ + dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr); + if(dst_addr == NULL) +#endif /* LWIP_HOOK_ETHARP_GET_GW */ + { + /* interface has default gateway? */ + if (!ip_addr_isany(&netif->gw)) { + /* send to hardware address of default gateway IP address */ + dst_addr = &(netif->gw); + /* no default gateway available */ + } else { + /* no route to destination error (default gateway missing) */ + return ERR_RTE; + } + } + } + } +#if LWIP_NETIF_HWADDRHINT + if (netif->addr_hint != NULL) { + /* per-pcb cached entry was given */ + u8_t etharp_cached_entry = *(netif->addr_hint); + if (etharp_cached_entry < ARP_TABLE_SIZE) { +#endif /* LWIP_NETIF_HWADDRHINT */ + if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { + /* the per-pcb-cached entry is stable and the right one! */ + ETHARP_STATS_INC(etharp.cachehit); + return etharp_output_to_arp_index(netif, q, etharp_cached_entry); + } +#if LWIP_NETIF_HWADDRHINT + } + } +#endif /* LWIP_NETIF_HWADDRHINT */ + + /* find stable entry: do this here since this is a critical path for + throughput and etharp_find_entry() is kind of slow */ + for (i = 0; i < ARP_TABLE_SIZE; i++) { + if ((arp_table[i].state >= ETHARP_STATE_STABLE) && + (ip_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { + /* found an existing, stable entry */ + ETHARP_SET_HINT(netif, i); + return etharp_output_to_arp_index(netif, q, i); + } + } + /* no stable entry found, use the (slower) query function: + queue on destination Ethernet address belonging to ipaddr */ + return etharp_query(netif, dst_addr, q); + } + + /* continuation for multicast/broadcast destinations */ + /* obtain source Ethernet address of the given interface */ + /* send packet directly on the link */ + return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest); +} + +/** + * Send an ARP request for the given IP address and/or queue a packet. + * + * If the IP address was not yet in the cache, a pending ARP cache entry + * is added and an ARP request is sent for the given address. The packet + * is queued on this entry. + * + * If the IP address was already pending in the cache, a new ARP request + * is sent for the given address. The packet is queued on this entry. + * + * If the IP address was already stable in the cache, and a packet is + * given, it is directly sent and no ARP request is sent out. + * + * If the IP address was already stable in the cache, and no packet is + * given, an ARP request is sent out. + * + * @param netif The lwIP network interface on which ipaddr + * must be queried for. + * @param ipaddr The IP address to be resolved. + * @param q If non-NULL, a pbuf that must be delivered to the IP address. + * q is not freed by this function. + * + * @note q must only be ONE packet, not a packet queue! + * + * @return + * - ERR_BUF Could not make room for Ethernet header. + * - ERR_MEM Hardware address unknown, and no more ARP entries available + * to query for address or queue the packet. + * - ERR_MEM Could not queue packet due to memory shortage. + * - ERR_RTE No route to destination (no gateway to external networks). + * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. + * + */ +err_t +etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q) +{ + struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; + err_t result = ERR_MEM; + int is_new_entry = 0; + s8_t i; /* ARP entry index */ + + /* non-unicast address? */ + if (ip_addr_isbroadcast(ipaddr, netif) || + ip_addr_ismulticast(ipaddr) || + ip_addr_isany(ipaddr)) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); + return ERR_ARG; + } + + /* find entry in ARP cache, ask to create entry if queueing packet */ + i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD); + + /* could not find or create entry? */ + if (i < 0) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); + if (q) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); + ETHARP_STATS_INC(etharp.memerr); + } + return (err_t)i; + } + + /* mark a fresh entry as pending (we just sent a request) */ + if (arp_table[i].state == ETHARP_STATE_EMPTY) { + is_new_entry = 1; + arp_table[i].state = ETHARP_STATE_PENDING; + /* record network interface for re-sending arp request in etharp_tmr */ + arp_table[i].netif = netif; + } + + /* { i is either a STABLE or (new or existing) PENDING entry } */ + LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", + ((arp_table[i].state == ETHARP_STATE_PENDING) || + (arp_table[i].state >= ETHARP_STATE_STABLE))); + + /* do we have a new entry? or an implicit query request? */ + if (is_new_entry || (q == NULL)) { + /* try to resolve it; send out ARP request */ + result = etharp_request(netif, ipaddr); + if (result != ERR_OK) { + /* ARP request couldn't be sent */ + /* We don't re-send arp request in etharp_tmr, but we still queue packets, + since this failure could be temporary, and the next packet calling + etharp_query again could lead to sending the queued packets. */ + } + if (q == NULL) { + return result; + } + } + + /* packet given? */ + LWIP_ASSERT("q != NULL", q != NULL); + /* stable entry? */ + if (arp_table[i].state >= ETHARP_STATE_STABLE) { + /* we have a valid IP->Ethernet address mapping */ + ETHARP_SET_HINT(netif, i); + /* send the packet */ + result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr)); + /* pending entry? (either just created or already pending */ + } else if (arp_table[i].state == ETHARP_STATE_PENDING) { + /* entry is still pending, queue the given packet 'q' */ + struct pbuf *p; + int copy_needed = 0; + /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but + * to copy the whole queue into a new PBUF_RAM (see bug #11400) + * PBUF_ROMs can be left as they are, since ROM must not get changed. */ + p = q; + while (p) { + LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); + if(p->type != PBUF_ROM) { + copy_needed = 1; + break; + } + p = p->next; + } + if(copy_needed) { + /* copy the whole packet into new pbufs */ + p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(p != NULL) { + if (pbuf_copy(p, q) != ERR_OK) { + pbuf_free(p); + p = NULL; + } + } + } else { + /* referencing the old pbuf is enough */ + p = q; + pbuf_ref(p); + } + /* packet could be taken over? */ + if (p != NULL) { + /* queue packet ... */ +#if ARP_QUEUEING + struct etharp_q_entry *new_entry; + /* allocate a new arp queue entry */ + new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); + if (new_entry != NULL) { + unsigned int qlen = 0; + new_entry->next = 0; + new_entry->p = p; + if(arp_table[i].q != NULL) { + /* queue was already existent, append the new entry to the end */ + struct etharp_q_entry *r; + r = arp_table[i].q; + qlen++; + while (r->next != NULL) { + r = r->next; + qlen++; + } + r->next = new_entry; + } else { + /* queue did not exist, first item in queue */ + arp_table[i].q = new_entry; + } +#if ARP_QUEUE_LEN + if (qlen >= ARP_QUEUE_LEN) { + struct etharp_q_entry *old; + old = arp_table[i].q; + arp_table[i].q = arp_table[i].q->next; + pbuf_free(old->p); + memp_free(MEMP_ARP_QUEUE, old); + } +#endif + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + result = ERR_OK; + } else { + /* the pool MEMP_ARP_QUEUE is empty */ + pbuf_free(p); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } +#else /* ARP_QUEUEING */ + /* always queue one packet per ARP request only, freeing a previously queued packet */ + if (arp_table[i].q != NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); + pbuf_free(arp_table[i].q); + } + arp_table[i].q = p; + result = ERR_OK; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); +#endif /* ARP_QUEUEING */ + } else { + ETHARP_STATS_INC(etharp.memerr); + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); + result = ERR_MEM; + } + } + return result; +} + +/** + * Send a raw ARP packet (opcode and all addresses can be modified) + * + * @param netif the lwip network interface on which to send the ARP packet + * @param ethsrc_addr the source MAC address for the ethernet header + * @param ethdst_addr the destination MAC address for the ethernet header + * @param hwsrc_addr the source MAC address for the ARP protocol header + * @param ipsrc_addr the source IP address for the ARP protocol header + * @param hwdst_addr the destination MAC address for the ARP protocol header + * @param ipdst_addr the destination IP address for the ARP protocol header + * @param opcode the type of the ARP packet + * @return ERR_OK if the ARP packet has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +#if !LWIP_AUTOIP +static +#endif /* LWIP_AUTOIP */ +err_t +etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, + const struct eth_addr *ethdst_addr, + const struct eth_addr *hwsrc_addr, const ip_addr_t *ipsrc_addr, + const struct eth_addr *hwdst_addr, const ip_addr_t *ipdst_addr, + const u16_t opcode) +{ + struct pbuf *p; + err_t result = ERR_OK; + struct eth_hdr *ethhdr; +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + struct eth_vlan_hdr *vlanhdr; +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + struct etharp_hdr *hdr; +#if LWIP_AUTOIP + const u8_t * ethdst_hwaddr; +#endif /* LWIP_AUTOIP */ + + LWIP_ASSERT("netif != NULL", netif != NULL); + + /* allocate a pbuf for the outgoing ARP request packet */ + p = pbuf_alloc(PBUF_RAW, SIZEOF_ETHARP_PACKET_TX, PBUF_RAM); + /* could allocate a pbuf for an ARP request? */ + if (p == NULL) { + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, + ("etharp_raw: could not allocate pbuf for ARP request.\n")); + ETHARP_STATS_INC(etharp.memerr); + return ERR_MEM; + } + LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", + (p->len >= SIZEOF_ETHARP_PACKET_TX)); + + ethhdr = (struct eth_hdr *)p->payload; +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR); + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR); +#else /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR); +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); + hdr->opcode = htons(opcode); + + LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!", + (netif->hwaddr_len == ETHARP_HWADDR_LEN)); +#if LWIP_AUTOIP + /* If we are using Link-Local, all ARP packets that contain a Link-Local + * 'sender IP address' MUST be sent using link-layer broadcast instead of + * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ + ethdst_hwaddr = ip_addr_islinklocal(ipsrc_addr) ? (u8_t*)(ethbroadcast.addr) : ethdst_addr->addr; +#endif /* LWIP_AUTOIP */ + /* Write the ARP MAC-Addresses */ + ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); + ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); + /* Copy struct ip_addr2 to aligned ip_addr, to support compilers without + * structure packing. */ + IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); + IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); + + hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); + hdr->proto = PP_HTONS(ETHTYPE_IP); + /* set hwlen and protolen */ + hdr->hwlen = ETHARP_HWADDR_LEN; + hdr->protolen = sizeof(ip_addr_t); + +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + ethhdr->type = PP_HTONS(ETHTYPE_VLAN); + vlanhdr->tpid = PP_HTONS(ETHTYPE_ARP); + vlanhdr->prio_vid = 0; + if (!LWIP_HOOK_VLAN_SET(netif, ethhdr, vlanhdr)) { + /* packet shall not contain VLAN header, so hide it and set correct ethertype */ + pbuf_header(p, -SIZEOF_VLAN_HDR); + ethhdr = (struct eth_hdr *)p->payload; +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + ethhdr->type = PP_HTONS(ETHTYPE_ARP); +#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) + } +#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ + + /* Write the Ethernet MAC-Addresses */ +#if LWIP_AUTOIP + ETHADDR16_COPY(ðhdr->dest, ethdst_hwaddr); +#else /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->dest, ethdst_addr); +#endif /* LWIP_AUTOIP */ + ETHADDR16_COPY(ðhdr->src, ethsrc_addr); + + /* send ARP query */ + result = netif->linkoutput(netif, p); + ETHARP_STATS_INC(etharp.xmit); + /* free ARP query packet */ + pbuf_free(p); + p = NULL; + /* could not allocate pbuf for ARP request */ + + return result; +} + +/** + * Send an ARP request packet asking for ipaddr. + * + * @param netif the lwip network interface on which to send the request + * @param ipaddr the IP address for which to ask + * @return ERR_OK if the request has been sent + * ERR_MEM if the ARP packet couldn't be allocated + * any other err_t on failure + */ +err_t +etharp_request(struct netif *netif, ip_addr_t *ipaddr) +{ + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); + return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, ðbroadcast, + (struct eth_addr *)netif->hwaddr, &netif->ip_addr, ðzero, + ipaddr, ARP_REQUEST); +} +#endif /* LWIP_ARP */ + +/** + * Process received ethernet frames. Using this function instead of directly + * calling ip_input and passing ARP frames through etharp in ethernetif_input, + * the ARP cache is protected from concurrent access. + * + * @param p the received packet, p->payload pointing to the ethernet header + * @param netif the network interface on which the packet was received + */ +err_t +ethernet_input(struct pbuf *p, struct netif *netif) +{ + struct eth_hdr* ethhdr; + u16_t type; +#if LWIP_ARP || ETHARP_SUPPORT_VLAN + s16_t ip_hdr_offset = SIZEOF_ETH_HDR; +#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ + + if (p->len <= SIZEOF_ETH_HDR) { + /* a packet with only an ethernet header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = (struct eth_hdr *)p->payload; + LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, + ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", + (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], + (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], + (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], + (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], + (unsigned)htons(ethhdr->type))); + + type = ethhdr->type; +#if ETHARP_SUPPORT_VLAN + if (type == PP_HTONS(ETHTYPE_VLAN)) { + struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); + if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { + /* a packet with only an ethernet/vlan header (or less) is not valid for us */ + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } +#if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ +#ifdef LWIP_HOOK_VLAN_CHECK + if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) { +#elif defined(ETHARP_VLAN_CHECK_FN) + if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { +#elif defined(ETHARP_VLAN_CHECK) + if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { +#endif + /* silently ignore this packet: not for our VLAN */ + pbuf_free(p); + return ERR_OK; + } +#endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ + type = vlan->tpid; + ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; + } +#endif /* ETHARP_SUPPORT_VLAN */ + +#if LWIP_ARP_FILTER_NETIF + netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, htons(type)); +#endif /* LWIP_ARP_FILTER_NETIF*/ + + if (ethhdr->dest.addr[0] & 1) { + /* this might be a multicast or broadcast packet */ + if (ethhdr->dest.addr[0] == LL_MULTICAST_ADDR_0) { + if ((ethhdr->dest.addr[1] == LL_MULTICAST_ADDR_1) && + (ethhdr->dest.addr[2] == LL_MULTICAST_ADDR_2)) { + /* mark the pbuf as link-layer multicast */ + p->flags |= PBUF_FLAG_LLMCAST; + } + } else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { + /* mark the pbuf as link-layer broadcast */ + p->flags |= PBUF_FLAG_LLBCAST; + } + } + + switch (type) { +#if LWIP_ARP + /* IP packet? */ + case PP_HTONS(ETHTYPE_IP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } +#if ETHARP_TRUST_IP_MAC + /* update ARP table */ + etharp_ip_input(netif, p); +#endif /* ETHARP_TRUST_IP_MAC */ + /* skip Ethernet header */ + if(pbuf_header(p, (s16_t)-ip_hdr_offset)) { + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IP layer */ + ip_input(p, netif); + } + break; + + case PP_HTONS(ETHTYPE_ARP): + if (!(netif->flags & NETIF_FLAG_ETHARP)) { + goto free_and_return; + } + /* pass p to ARP module */ + etharp_arp_input(netif, (struct eth_addr*)(netif->hwaddr), p); + break; +#endif /* LWIP_ARP */ +#if PPPOE_SUPPORT + case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ + pppoe_disc_input(netif, p); + break; + + case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ + pppoe_data_input(netif, p); + break; +#endif /* PPPOE_SUPPORT */ + +#if LWIP_IPV6 + case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */ + /* skip Ethernet header */ + if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) { + LWIP_ASSERT("Can't move over header in packet", 0); + goto free_and_return; + } else { + /* pass to IPv6 layer */ + ip6_input(p, netif); + } + break; +#endif /* LWIP_IPV6 */ + + default: + ETHARP_STATS_INC(etharp.proterr); + ETHARP_STATS_INC(etharp.drop); + goto free_and_return; + } + + /* This means the pbuf is freed or consumed, + so the caller doesn't have to free it again */ + return ERR_OK; + +free_and_return: + pbuf_free(p); + return ERR_OK; +} +#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ethernetif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ethernetif.c new file mode 100644 index 0000000..b9276b6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ethernetif.c @@ -0,0 +1,322 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "lwip/opt.h" + +#if 0 /* don't build, this is only a skeleton, see previous comment */ + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/ethip6.h" +#include "netif/etharp.h" +#include "netif/ppp/pppoe.h" + +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +/** + * Helper struct to hold private data used to operate your ethernet interface. + * Keeping the ethernet address of the MAC in this struct is not necessary + * as it is already kept in the struct netif. + * But this is only an example, anyway... + */ +struct ethernetif { + struct eth_addr *ethaddr; + /* Add whatever per-interface state that is needed here. */ +}; + +/* Forward declarations. */ +static void ethernetif_input(struct netif *netif); + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ +static void +low_level_init(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* set MAC hardware address */ + netif->hwaddr[0] = ; + ... + netif->hwaddr[5] = ; + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Do whatever else is needed to initialize interface. */ +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ + +static err_t +low_level_output(struct netif *netif, struct pbuf *p) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *q; + + initiate transfer(); + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + for(q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + send data from(q->payload, q->len); + } + + signal that packet should be sent(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +/** + * Should allocate a pbuf and transfer the bytes of the incoming + * packet from the interface into the pbuf. + * + * @param netif the lwip network interface structure for this ethernetif + * @return a pbuf filled with the received packet (including MAC header) + * NULL on memory error + */ +static struct pbuf * +low_level_input(struct netif *netif) +{ + struct ethernetif *ethernetif = netif->state; + struct pbuf *p, *q; + u16_t len; + + /* Obtain the size of the packet and put it into the "len" + variable. */ + len = ; + +#if ETH_PAD_SIZE + len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ +#endif + + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + + if (p != NULL) { + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* We iterate over the pbuf chain until we have read the entire + * packet into the pbuf. */ + for(q = p; q != NULL; q = q->next) { + /* Read enough bytes to fill this pbuf in the chain. The + * available data in the pbuf is given by the q->len + * variable. + * This does not necessarily have to be a memcpy, you can also preallocate + * pbufs for a DMA-enabled MAC and after receiving truncate it to the + * actually received size. In this case, ensure the tot_len member of the + * pbuf is the sum of the chained pbuf len members. + */ + read data into(q->payload, q->len); + } + acknowledge that packet has been read(); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } else { + drop packet(); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + + return p; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +static void +ethernetif_input(struct netif *netif) +{ + struct ethernetif *ethernetif; + struct eth_hdr *ethhdr; + struct pbuf *p; + + ethernetif = netif->state; + + /* move received packet into a new pbuf */ + p = low_level_input(netif); + /* no packet could be read, silently ignore this */ + if (p == NULL) return; + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_IPV6: + case ETHTYPE_ARP: +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif)!=ERR_OK) + { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); + p = NULL; + } + break; + + default: + pbuf_free(p); + p = NULL; + break; + } +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init(struct netif *netif) +{ + struct ethernetif *ethernetif; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + ethernetif = mem_malloc(sizeof(struct ethernetif)); + if (ethernetif == NULL) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); + return ERR_MEM; + } + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); + + netif->state = ethernetif; + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; +#if LWIP_IPV6 + netif->output_ip6 = ethip6_output; +#endif /* LWIP_IPV6 */ + netif->linkoutput = low_level_output; + + ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +#endif /* 0 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/PPPD_FOLLOWUP b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/PPPD_FOLLOWUP new file mode 100644 index 0000000..4a82915 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/PPPD_FOLLOWUP @@ -0,0 +1,382 @@ +The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with +huge changes to match code size and memory requirements for embedded devices. + +Anyway, pppd has a mature codebase for years and the average commit count +is getting low on their Git repositories, meaning that we can follow what +is happening on their side and merge what is relevant for lwIP. + +So, here is the pppd follow up, so that we don't get away too far from pppd. + + +== Patch fetched from from pppd Debian packages == + +This has nothing to do with pppd, but we merged some good patch from +Debian and this is a good place to be. + +- LCP adaptive echo, so that we don't send LCP echo request if we + are receiving data from peer, can be enabled by setting PPP_LCP_ADAPTIVE + to true. + +- IPCP no/replace default route option, were added in the early stage of + the ppp port, but it wasn't really helpful and was disabled when adding + the new API ppp_set_default() call, which gives the lwIP user control over + which one is the default interface, it was actually a requirement if you + are doing PPP over PPP (i.e. PPPoL2TP, VPN link, over PPPoE, ADSL link). + +- using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting + for PADO due to no modem attached, bug reported to pppd bug tracker, fixed + in Debian but not in the latest (at the time when the port were started) + pppd release. + + +== Commits on pppd == + +2010-03-06 - Document +ipv6 and ipv6cp-accept-local + e7537958aee79b3f653c601e903cb31d78fb7dcc + +Don't care. + + +2010-03-06 - Install pppol2tp plugins with sane permissions + 406215672cfadc03017341fe03802d1c7294b903 + +Don't care. + + +2010-03-07 - pppd: Terminate correctly if lcp_lowerup delayed calling + fsm_lowerup + 3eb9e810cfa515543655659b72dde30c54fea0a5 + +Merged 2012-05-17. + + +2010-03-07 - rp_pppoe: Copy acName and pppd_pppoe_service after option parsing + cab58617fd9d328029fffabc788020264b4fa91f + +Don't care, is a patch for pppd/plugins/rp-pppoe/plugin.c which is not part +of the port. + + +2010-08-23 - set and reset options to control environment variables + for scripts. + 2b6310fd24dba8e0fca8999916a162f0a1842a84 + +We can't fork processes in embedded, therefore all the pppd process run +feature is disabled in the port, so we don't care about the new +"environment variables" pppd feature. + + +2010-08-23 - Nit: use _exit when exec fails and restrict values to 0-255 + per POSIX. + 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 + +Again, we are not running as a heavy process, so all exit() or _exit() calls +were removed. + + +2010-08-23 - Fix quote handling in configuration files to be more like shell + quoting. + 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca + +We are not parsing config file, all the filesystem I/O stuff were disabled +in our port. + + +2010-08-24 - rp-pppoe: allow MTU to be increased up to 1500 + fd1dcdf758418f040da3ed801ab001b5e46854e7 + +Only concern changes on RP-PPPoE plugin, which we don't use. + + +2010-09-11 - chat: Allow TIMEOUT value to come from environment variable + ae80bf833e48a6202f44a935a68083ae52ad3824 + +See 2b6310fd24dba8e0fca8999916a162f0a1842a84. + + +2011-03-05 - pppdump: Fix printfs with insufficient arguments + 7b8db569642c83ba3283745034f2e2c95e459423 + +pppdump is a ppp tool outside pppd source tree. + + +2012-05-06 - pppd: Don't unconditionally disable VJ compression under Linux + d8a66adf98a0e525cf38031b42098d539da6eeb6 + +Patch for sys-linux.c, which we don't use. + + +2012-05-20 - Remove old version of Linux if_pppol2tp.h + c41092dd4c49267f232f6cba3d31c6c68bfdf68d + +Not in the port. + + +2012-05-20 - pppd: Make MSCHAP-v2 cope better with packet loss + 08ef47ca532294eb428238c831616748940e24a2 + +This is an interesting patch. However it consumes much more memory for +MSCHAP and I am not sure if the benefit worth it. The PPP client can +always start the authentication again if it failed for whatever reason. + + +2012-05-20 - scripts: Make poff ignore extra arguments to pppd + 18f515f32c9f5723a9c2c912601e04335106534b + +Again, we are not running scripts. + + +2012-05-20 - rp-pppoe plugin: Print leading zeros in MAC address + f5dda0cfc220c4b52e26144096d729e27b30f0f7 + +Again, we are not using the RP-PPPoE plugin. + + +2012-05-20 - pppd: Notify IPv6 up/down as we do for IPv4 + 845cda8fa18939cf56e60b073f63a7efa65336fc + +This is just a patch that adds plugins hooks for IPv6, the plugin interface +was disabled because we don't have .so plugins in embedded. + + +2012-05-20 - pppd: Enable IPV6 by default and fix some warnings + 0b6118239615e98959f7e0b4e746bdd197533248 + +Change on Makefile for IPv6, warnings were already cleared during port. + + +2012-05-20 - contrib: Fix pppgetpass.gtk compilation + 80a8e2ce257ca12cce723519a0f20ea1d663b14a + +Change on Makefile, don't care. + + +2012-05-20 - pppd: Don't crash if crypt() returns NULL + 04c4348108d847e034dd91066cc6843f60d71731 + +We are using the PolarSSL DES implementation that does not return NULL. + + +2012-05-20 - pppd: Eliminate some warnings + c44ae5e6a7338c96eb463881fe709b2dfaffe568 + +Again, we are handling compilation warnings on our own. + + +2012-05-20 - rp-pppoe plugin: Import some fixes from rp-pppoe-3.10 + 1817d83e51a411044e730ba89ebdb0480e1c8cd4 + +Once more, we are not using the RP-PPPoE plugin. + + +2013-01-23 - pppd: Clarify circumstances where DNS1/DNS2 environment variables are set + cf2f5c9538b9400ade23446a194729b0a4113b3a + +Documentation only. + + +2013-02-03 - ppp: ignore unrecognised radiusclient configuration directives + 7f736dde0da3c19855997d9e67370e351e15e923 + +Radius plugin, not in the port. + + +2013-02-03 - pppd: Take out unused %r conversion completely + 356d8d558d844412119aa18c8e5a113bc6459c7b + +Merged 2014-04-15. + + +2013-02-03 - pppd: Arrange to use logwtmp from libutil on Linux + 9617a7eb137f4fee62799a677a9ecf8d834db3f5 + +Patch for sys-linux.c, which we don't use. + + +2013-02-03 - pppdump: Eliminate some compiler warnings + 3e3acf1ba2b3046c072a42c19164788a9e419bd1 + +pppdump is a ppp tool outside pppd source tree. + + +2013-02-03 - chat: Correct spelling errors in the man page + 8dea1b969d266ccbf6f3a8c5474eb6dcd8838e3b + +Documentation only. + + +2013-02-03 - pppd: Fix spelling errors in man page + 9e05a25d76b3f83096c661678010320df673df6b + +Documentation only. + + +2013-02-03 - plugins/passprompt: Fix potential out-of-bounds array reference + 8edb889b753056a691a3e4b217a110a35f9fdedb + +Plugin patch, we do not have plugins. + + +2013-02-03 - chat: Fix *roff errors in the man page + a7c3489eeaf44e83ce592143c7c8a5b5c29f4c48 + +Documentation only. + + +2013-03-02 - pppd: Fix man page description of case when remote IP address isn't known + 224841f4799f4f1e2e71bc490c54448d66740f4f + +Documentation only. + + +2013-03-02 - pppd: Add master_detach option + 398ed2585640d198c53e736ee5bbd67f7ce8168e + +Option for multilink support, we do not support multilink and this option +is about detaching from the terminal, which is out of the embedded scope. + + +2013-03-11 - pppd: Default exit status to EXIT_CONNECT_FAILED during connection phase + 225361d64ae737afdc8cb57579a2f33525461bc9 + +Commented out in our port, and already fixed by a previously applied Debian patch. + + +2013-03-11 - pppstats: Fix undefined macro in man page + d16a3985eade5280b8e171f5dd0670a91cba0d39 + +Documentation only. + + +2013-05-11 - plugins/radius: Handle bindaddr keyword in radiusclient.conf + d883b2dbafeed3ebd9d7a56ab1469373bd001a3b + +Radius plugin, not in the port. + + +2013-06-09 - pppoatm: Remove explicit loading of pppoatm kernel module + 52cd43a84bea524033b918b603698104f221bbb7 + +PPPoATM plugin, not in the port. + + +2013-06-09 - pppd: Fix segfault in update_db_entry() + 37476164f15a45015310b9d4b197c2d7db1f7f8f + +We do not use the samba db. + + +2013-06-09 - chat: Fix some text that was intended to be literal + cd9683676618adcee8add2c3cfa3382341b5a1f6 + +Documentation only. + + +2013-06-09 - README.pppoe: Minor semantic fix + b5b8898af6fd3d44e873cfc66810ace5f1f47e17 + +Documentation only. + + +2013-06-10 - radius: Handle additional attributes + 2f581cd986a56f2ec4a95abad4f8297a1b10d7e2 + +Radius plugin, not in the port. + + +2013-06-10 - chat, pppd: Use \e instead of \\ in man pages + 8d6942415d22f6ca4377340ca26e345c3f5fa5db + +Documentation only. + + +2014-01-02 - pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v + 906814431bddeb2061825fa1ebad1a967b6d87a9 + +Merged 2014-04-15. + + +2014-01-02 - pppd: Accept IPCP ConfAck packets containing MS-WINS options + a243f217f1c6ac1aa7793806bc88590d077f490a + +Merged 2014-04-15. + + +2014-01-02 - config: Update Solaris compiler options and enable CHAPMS and IPV6 + 99c46caaed01b7edba87962aa52b77fad61bfd7b + +Solaris port, don't care. + + +2014-01-02 - Update README and patchlevel for 2.4.6 release + 4043750fca36e7e0eb90d702e048ad1da4929418 + +Just release stuff. + + +2014-02-18 - pppd: Add option "stop-bits" to set number of serial port stop bits. + ad993a20ee485f0d0e2ac4105221641b200da6e2 + +Low level serial port, not in the port. + + +2014-03-09 - pppd: Separate IPv6 handling for sifup/sifdown + b04d2dc6df5c6b5650fea44250d58757ee3dac4a + +Reimplemented. + + +2014-03-09 - pppol2tp: Connect up/down events to notifiers and add IPv6 ones + fafbe50251efc7d6b4a8be652d085316e112b34f + +Not in the port. + + +2014-03-09 - pppd: Add declarations to eliminate compile warnings + 50967962addebe15c7a7e63116ff46a0441dc464 + +We are handling compilation warnings on our own + + +2014-03-09 - pppd: Eliminate some unnecessary ifdefs + de8da14d845ee6db9236ccfddabf1d8ebf045ddb + +We mostly did that previously. Anyway, merged 2014-12-24. + + +2014-08-01 - radius: Fix realms-config-file option + 880a81be7c8e0fe8567227bc17a1bff3ea035943 + +Radius plugin, not in the port. + + +2014-08-01 - pppd: Eliminate potential integer overflow in option parsing + 7658e8257183f062dc01f87969c140707c7e52cb + +pppd config file parser, not in the port. + + +2014-08-01 - pppd: Eliminate memory leak with multiple instances of a string option + b94b7fbbaa0589aa6ec5fdc733aeb9ff294d2656 + +pppd config file parser, not in the port. + + +2014-08-01 - pppd: Fix a stack variable overflow in MSCHAP-v2 + 36733a891fb56594fcee580f667b33a64b990981 + +This fixes a bug introduced in 08ef47ca ("pppd: Make MSCHAP-v2 cope better with packet loss"). + +We didn't merge 08ef47ca ;-) + + +2014-08-01 - winbind plugin: Add -DMPPE=1 to eliminate compiler warnings + 2b05e22c62095e97dd0a97e4b5588402c2185071 + +Linux plugin, not in the port. + + +2014-08-09 - Update README and patchlevel for 2.4.7 release + 6e8eaa7a78b31cdab2edf140a9c8afdb02ffaca5 + +Just release stuff. diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/auth.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/auth.c new file mode 100644 index 0000000..b98691e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/auth.c @@ -0,0 +1,2563 @@ +/* + * auth.c - PPP authentication and phase control. + * + * Copyright (c) 1993-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from main.c, which is: + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(_PATH_LASTLOG) && defined(__linux__) +#include +#endif + +#include +#include +#include + +#ifdef HAS_SHADOW +#include +#ifndef PW_PPP +#define PW_PPP PW_LOGIN +#endif +#endif + +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#if CCP_SUPPORT +#include "netif/ppp/ccp.h" +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT +#include "netif/ppp/ecp.h" +#endif /* ECP_SUPPORT */ +#include "netif/ppp/ipcp.h" +#if PAP_SUPPORT +#include "netif/ppp/upap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "netif/ppp/chap-new.h" +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#include "netif/ppp/eap.h" +#endif /* EAP_SUPPORT */ +#if CBCP_SUPPORT +#include "netif/ppp/cbcp.h" +#endif + +#if 0 /* UNUSED */ +#include "session.h" +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +/* Bits in scan_authfile return value */ +#define NONWILD_SERVER 1 +#define NONWILD_CLIENT 2 + +#define ISWILD(word) (word[0] == '*' && word[1] == 0) +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +/* List of addresses which the peer may use. */ +static struct permitted_ip *addresses[NUM_PPP]; + +/* Wordlist giving addresses which the peer may use + without authenticating itself. */ +static struct wordlist *noauth_addrs; + +/* Remote telephone number, if available */ +char remote_number[MAXNAMELEN]; + +/* Wordlist giving remote telephone numbers which may connect. */ +static struct wordlist *permitted_numbers; + +/* Extra options to apply, from the secrets file entry for the peer. */ +static struct wordlist *extra_options; +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +/* Set if we require authentication only because we have a default route. */ +static bool default_auth; + +/* Hook to enable a plugin to control the idle time limit */ +int (*idle_time_hook) (struct ppp_idle *) = NULL; + +/* Hook for a plugin to say whether we can possibly authenticate any peer */ +int (*pap_check_hook) (void) = NULL; + +/* Hook for a plugin to check the PAP user and password */ +int (*pap_auth_hook) (char *user, char *passwd, char **msgp, + struct wordlist **paddrs, + struct wordlist **popts) = NULL; + +/* Hook for a plugin to know about the PAP user logout */ +void (*pap_logout_hook) (void) = NULL; + +/* Hook for a plugin to get the PAP password for authenticating us */ +int (*pap_passwd_hook) (char *user, char *passwd) = NULL; + +/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ +int (*chap_check_hook) (void) = NULL; + +/* Hook for a plugin to get the CHAP password for authenticating us */ +int (*chap_passwd_hook) (char *user, char *passwd) = NULL; + +/* Hook for a plugin to say whether it is OK if the peer + refuses to authenticate. */ +int (*null_auth_hook) (struct wordlist **paddrs, + struct wordlist **popts) = NULL; + +int (*allowed_address_hook) (u32_t addr) = NULL; +#endif /* UNUSED */ + +#ifdef HAVE_MULTILINK +/* Hook for plugin to hear when an interface joins a multilink bundle */ +void (*multilink_join_hook) (void) = NULL; +#endif + +#if PPP_NOTIFY +/* A notifier for when the peer has authenticated itself, + and we are proceeding to the network phase. */ +struct notifier *auth_up_notifier = NULL; + +/* A notifier for when the link goes down. */ +struct notifier *link_down_notifier = NULL; +#endif /* PPP_NOTIFY */ + +/* + * Option variables. + */ +#if 0 /* MOVED TO ppp_settings */ +bool uselogin = 0; /* Use /etc/passwd for checking PAP */ +bool session_mgmt = 0; /* Do session management (login records) */ +bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ +bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ +bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ +bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ +#if MSCHAP_SUPPORT +bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#else /* MSCHAP_SUPPORT */ +bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ +bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ +#endif /* MSCHAP_SUPPORT */ +bool usehostname = 0; /* Use hostname for our_name */ +bool auth_required = 0; /* Always require authentication from peer */ +bool allow_any_ip = 0; /* Allow peer to use any IP address */ +bool explicit_remote = 0; /* User specified explicit remote name */ +bool explicit_user = 0; /* Set if "user" option supplied */ +bool explicit_passwd = 0; /* Set if "password" option supplied */ +char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ +static char *uafname; /* name of most recent +ua file */ + +extern char *crypt (const char *, const char *); +#endif /* UNUSED */ +/* Prototypes for procedures local to this file. */ + +static void network_phase(ppp_pcb *pcb); +#if PPP_IDLETIMELIMIT +static void check_idle(void *arg); +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT +static void connect_time_expired(void *arg); +#endif /* PPP_MAXCONNECT */ +#if 0 /* UNUSED */ +static int null_login (int); +/* static int get_pap_passwd (char *); */ +static int have_pap_secret (int *); +static int have_chap_secret (char *, char *, int, int *); +static int have_srp_secret (char *client, char *server, int need_ip, + int *lacks_ipp); +static int ip_addr_check (u32_t, struct permitted_ip *); +static int scan_authfile (FILE *, char *, char *, char *, + struct wordlist **, struct wordlist **, + char *, int); +static void free_wordlist (struct wordlist *); +static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); +static int some_ip_ok (struct wordlist *); +static int setupapfile (char **); +static int privgroup (char **); +static int set_noauth_addr (char **); +static int set_permitted_number (char **); +static void check_access (FILE *, char *); +static int wordlist_count (struct wordlist *); +#endif /* UNUSED */ + +#ifdef MAXOCTETS +static void check_maxoctets (void *); +#endif + +#if PPP_OPTIONS +/* + * Authentication-related options. + */ +option_t auth_options[] = { + { "auth", o_bool, &auth_required, + "Require authentication from peer", OPT_PRIO | 1 }, + { "noauth", o_bool, &auth_required, + "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, + &allow_any_ip }, + { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, + "Require PAP authentication from peer", + OPT_PRIOSUB | 1, &auth_required }, + { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, + "Require PAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, + { "require-chap", o_bool, &auth_required, + "Require CHAP authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, + { "+chap", o_bool, &auth_required, + "Require CHAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, + &lcp_wantoptions[0].chap_mdtype }, +#if MSCHAP_SUPPORT + { "require-mschap", o_bool, &auth_required, + "Require MS-CHAP authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap", o_bool, &auth_required, + "Require MS-CHAP authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, + &lcp_wantoptions[0].chap_mdtype }, + { "require-mschap-v2", o_bool, &auth_required, + "Require MS-CHAPv2 authentication from peer", + OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, + { "+mschap-v2", o_bool, &auth_required, + "Require MS-CHAPv2 authentication from peer", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, + &lcp_wantoptions[0].chap_mdtype }, +#endif /* MSCHAP_SUPPORT */ +#if 0 + { "refuse-pap", o_bool, &refuse_pap, + "Don't agree to auth to peer with PAP", 1 }, + { "-pap", o_bool, &refuse_pap, + "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, + { "refuse-chap", o_bool, &refuse_chap, + "Don't agree to auth to peer with CHAP", + OPT_A2CLRB | MDTYPE_MD5, + &lcp_allowoptions[0].chap_mdtype }, + { "-chap", o_bool, &refuse_chap, + "Don't allow CHAP authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, + &lcp_allowoptions[0].chap_mdtype }, +#endif +#if MSCHAP_SUPPORT +#if 0 + { "refuse-mschap", o_bool, &refuse_mschap, + "Don't agree to auth to peer with MS-CHAP", + OPT_A2CLRB | MDTYPE_MICROSOFT, + &lcp_allowoptions[0].chap_mdtype }, + { "-mschap", o_bool, &refuse_mschap, + "Don't allow MS-CHAP authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, + &lcp_allowoptions[0].chap_mdtype }, + { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, + "Don't agree to auth to peer with MS-CHAPv2", + OPT_A2CLRB | MDTYPE_MICROSOFT_V2, + &lcp_allowoptions[0].chap_mdtype }, + { "-mschap-v2", o_bool, &refuse_mschap_v2, + "Don't allow MS-CHAPv2 authentication with peer", + OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, + &lcp_allowoptions[0].chap_mdtype }, +#endif +#endif /* MSCHAP_SUPPORT*/ +#if EAP_SUPPORT + { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, + "Require EAP authentication from peer", OPT_PRIOSUB | 1, + &auth_required }, +#if 0 + { "refuse-eap", o_bool, &refuse_eap, + "Don't agree to authenticate to peer with EAP", 1 }, +#endif +#endif /* EAP_SUPPORT */ + { "name", o_string, our_name, + "Set local name for authentication", + OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, + + { "+ua", o_special, (void *)setupapfile, + "Get PAP user and password from file", + OPT_PRIO | OPT_A2STRVAL, &uafname }, + +#if 0 + { "user", o_string, user, + "Set name for auth with peer", OPT_PRIO | OPT_STATIC, + &explicit_user, MAXNAMELEN }, + + { "password", o_string, passwd, + "Password for authenticating us to the peer", + OPT_PRIO | OPT_STATIC | OPT_HIDE, + &explicit_passwd, MAXSECRETLEN }, +#endif + + { "usehostname", o_bool, &usehostname, + "Must use hostname for authentication", 1 }, + + { "remotename", o_string, remote_name, + "Set remote name for authentication", OPT_PRIO | OPT_STATIC, + &explicit_remote, MAXNAMELEN }, + + { "login", o_bool, &uselogin, + "Use system password database for PAP", OPT_A2COPY | 1 , + &session_mgmt }, + { "enable-session", o_bool, &session_mgmt, + "Enable session accounting for remote peers", OPT_PRIV | 1 }, + + { "papcrypt", o_bool, &cryptpap, + "PAP passwords are encrypted", 1 }, + + { "privgroup", o_special, (void *)privgroup, + "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, + + { "allow-ip", o_special, (void *)set_noauth_addr, + "Set IP address(es) which can be used without authentication", + OPT_PRIV | OPT_A2LIST }, + + { "remotenumber", o_string, remote_number, + "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, + NULL, MAXNAMELEN }, + + { "allow-number", o_special, (void *)set_permitted_number, + "Set telephone number(s) which are allowed to connect", + OPT_PRIV | OPT_A2LIST }, + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +#if 0 /* UNUSED */ +/* + * setupapfile - specifies UPAP info for authenticating with peer. + */ +static int +setupapfile(argv) + char **argv; +{ + FILE *ufile; + int l; + uid_t euid; + char u[MAXNAMELEN], p[MAXSECRETLEN]; + char *fname; + + lcp_allowoptions[0].neg_upap = 1; + + /* open user info file */ + fname = strdup(*argv); + if (fname == NULL) + novm("+ua file name"); + euid = geteuid(); + if (seteuid(getuid()) == -1) { + option_error("unable to reset uid before opening %s: %m", fname); + return 0; + } + ufile = fopen(fname, "r"); + if (seteuid(euid) == -1) + fatal("unable to regain privileges: %m"); + if (ufile == NULL) { + option_error("unable to open user login data file %s", fname); + return 0; + } + check_access(ufile, fname); + uafname = fname; + + /* get username */ + if (fgets(u, MAXNAMELEN - 1, ufile) == NULL + || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { + fclose(ufile); + option_error("unable to read user login data file %s", fname); + return 0; + } + fclose(ufile); + + /* get rid of newlines */ + l = strlen(u); + if (l > 0 && u[l-1] == '\n') + u[l-1] = 0; + l = strlen(p); + if (l > 0 && p[l-1] == '\n') + p[l-1] = 0; + + if (override_value("user", option_priority, fname)) { + strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user)); + explicit_user = 1; + } + if (override_value("passwd", option_priority, fname)) { + strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd)); + explicit_passwd = 1; + } + + return (1); +} + +/* + * privgroup - allow members of the group to have privileged access. + */ +static int +privgroup(argv) + char **argv; +{ + struct group *g; + int i; + + g = getgrnam(*argv); + if (g == 0) { + option_error("group %s is unknown", *argv); + return 0; + } + for (i = 0; i < ngroups; ++i) { + if (groups[i] == g->gr_gid) { + privileged = 1; + break; + } + } + return 1; +} + + +/* + * set_noauth_addr - set address(es) that can be used without authentication. + * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. + */ +static int +set_noauth_addr(argv) + char **argv; +{ + char *addr = *argv; + int l = strlen(addr) + 1; + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); + if (wp == NULL) + novm("allow-ip argument"); + wp->word = (char *) (wp + 1); + wp->next = noauth_addrs; + MEMCPY(wp->word, addr, l); + noauth_addrs = wp; + return 1; +} + + +/* + * set_permitted_number - set remote telephone number(s) that may connect. + */ +static int +set_permitted_number(argv) + char **argv; +{ + char *number = *argv; + int l = strlen(number) + 1; + struct wordlist *wp; + + wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); + if (wp == NULL) + novm("allow-number argument"); + wp->word = (char *) (wp + 1); + wp->next = permitted_numbers; + MEMCPY(wp->word, number, l); + permitted_numbers = wp; + return 1; +} +#endif + +/* + * An Open on LCP has requested a change from Dead to Establish phase. + */ +void link_required(ppp_pcb *pcb) { + LWIP_UNUSED_ARG(pcb); +} + +#if 0 +/* + * Bring the link up to the point of being able to do ppp. + */ +void start_link(unit) + int unit; +{ + ppp_pcb *pcb = &ppp_pcb_list[unit]; + char *msg; + + status = EXIT_NEGOTIATION_FAILED; + new_phase(pcb, PPP_PHASE_SERIALCONN); + + hungup = 0; + devfd = the_channel->connect(); + msg = "Connect script failed"; + if (devfd < 0) + goto fail; + + /* set up the serial device as a ppp interface */ + /* + * N.B. we used to do tdb_writelock/tdb_writeunlock around this + * (from establish_ppp to set_ifunit). However, we won't be + * doing the set_ifunit in multilink mode, which is the only time + * we need the atomicity that the tdb_writelock/tdb_writeunlock + * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. + */ + fd_ppp = the_channel->establish_ppp(devfd); + msg = "ppp establishment failed"; + if (fd_ppp < 0) { + status = EXIT_FATAL_ERROR; + goto disconnect; + } + + if (!demand && ifunit >= 0) + set_ifunit(1); + + /* + * Start opening the connection and wait for + * incoming events (reply, timeout, etc.). + */ + if (ifunit >= 0) + ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam); + else + ppp_notice("Starting negotiation on %s", ppp_devnam); + add_fd(fd_ppp); + + new_phase(pcb, PPP_PHASE_ESTABLISH); + + lcp_lowerup(pcb); + return; + + disconnect: + new_phase(pcb, PPP_PHASE_DISCONNECT); + if (the_channel->disconnect) + the_channel->disconnect(); + + fail: + new_phase(pcb, PPP_PHASE_DEAD); + if (the_channel->cleanup) + (*the_channel->cleanup)(); +} +#endif + +/* + * LCP has terminated the link; go to the Dead phase and take the + * physical layer down. + */ +void link_terminated(ppp_pcb *pcb) { + if (pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_MASTER) + return; + new_phase(pcb, PPP_PHASE_DISCONNECT); + +#if 0 /* UNUSED */ + if (pap_logout_hook) { + pap_logout_hook(); + } + session_end(devnam); +#endif /* UNUSED */ + + if (!doing_multilink) { + ppp_notice("Connection terminated."); +#if PPP_STATS_SUPPORT + print_link_stats(); +#endif /* PPP_STATS_SUPPORT */ + } else + ppp_notice("Link terminated."); + + lcp_lowerdown(pcb); + + new_phase(pcb, PPP_PHASE_DEAD); + ppp_link_terminated(pcb); +#if 0 + /* + * Delete pid files before disestablishing ppp. Otherwise it + * can happen that another pppd gets the same unit and then + * we delete its pid file. + */ + if (!doing_multilink && !demand) + remove_pidfiles(); + + /* + * If we may want to bring the link up again, transfer + * the ppp unit back to the loopback. Set the + * real serial device back to its normal mode of operation. + */ + if (fd_ppp >= 0) { + remove_fd(fd_ppp); + clean_check(); + the_channel->disestablish_ppp(devfd); + if (doing_multilink) + mp_exit_bundle(); + fd_ppp = -1; + } + if (!hungup) + lcp_lowerdown(pcb); + if (!doing_multilink && !demand) + script_unsetenv("IFNAME"); + + /* + * Run disconnector script, if requested. + * XXX we may not be able to do this if the line has hung up! + */ + if (devfd >= 0 && the_channel->disconnect) { + the_channel->disconnect(); + devfd = -1; + } + if (the_channel->cleanup) + (*the_channel->cleanup)(); + + if (doing_multilink && multilink_master) { + if (!bundle_terminating) + new_phase(pcb, PPP_PHASE_MASTER); + else + mp_bundle_terminated(); + } else + new_phase(pcb, PPP_PHASE_DEAD); +#endif +} + +/* + * LCP has gone down; it will either die or try to re-establish. + */ +void link_down(ppp_pcb *pcb) { +#if PPP_NOTIFY + notify(link_down_notifier, 0); +#endif /* PPP_NOTIFY */ + + if (!doing_multilink) { + upper_layers_down(pcb); + if (pcb->phase != PPP_PHASE_DEAD && pcb->phase != PPP_PHASE_MASTER) + new_phase(pcb, PPP_PHASE_ESTABLISH); + } + /* XXX if doing_multilink, should do something to stop + network-layer traffic on the link */ + + ppp_link_down(pcb); +} + +void upper_layers_down(ppp_pcb *pcb) { + int i; + const struct protent *protp; + + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (!protp->enabled_flag) + continue; + if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) + (*protp->lowerdown)(pcb); + if (protp->protocol < 0xC000 && protp->close != NULL) + (*protp->close)(pcb, "LCP down"); + } + pcb->num_np_open = 0; + pcb->num_np_up = 0; +} + +/* + * The link is established. + * Proceed to the Dead, Authenticate or Network phase as appropriate. + */ +void link_established(ppp_pcb *pcb) { + int auth; +#if PPP_SERVER + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *go = &pcb->lcp_gotoptions; +#endif /* PPP_SERVER */ + lcp_options *ho = &pcb->lcp_hisoptions; + int i; + const struct protent *protp; +#if PPP_SERVER + int errcode; +#endif /* PPP_SERVER */ + + /* + * Tell higher-level protocols that LCP is up. + */ + if (!doing_multilink) { + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol != PPP_LCP && protp->enabled_flag + && protp->lowerup != NULL) + (*protp->lowerup)(pcb); + } + +#if PPP_SERVER +#if PPP_ALLOWED_ADDRS + if (!auth_required && noauth_addrs != NULL) + set_allowed_addrs(unit, NULL, NULL); +#endif /* PPP_ALLOWED_ADDRS */ + + if (pcb->settings.auth_required && !(0 +#if PAP_SUPPORT + || go->neg_upap +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + )) { + +#if PPP_ALLOWED_ADDRS + /* + * We wanted the peer to authenticate itself, and it refused: + * if we have some address(es) it can use without auth, fine, + * otherwise treat it as though it authenticated with PAP using + * a username of "" and a password of "". If that's not OK, + * boot it out. + */ + if (noauth_addrs != NULL) { + set_allowed_addrs(unit, NULL, NULL); + } else +#endif /* PPP_ALLOWED_ADDRS */ + if (!wo->neg_upap || !pcb->settings.null_login) { + ppp_warn("peer refused to authenticate: terminating link"); +#if 0 /* UNUSED */ + status = EXIT_PEER_AUTH_FAILED; +#endif /* UNUSED */ + errcode = PPPERR_AUTHFAIL; + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "peer refused to authenticate"); + return; + } + } +#endif /* PPP_SERVER */ + + new_phase(pcb, PPP_PHASE_AUTHENTICATE); + auth = 0; +#if PPP_SERVER +#if EAP_SUPPORT + if (go->neg_eap) { + eap_authpeer(pcb, pcb->settings.our_name); + auth |= EAP_PEER; + } else +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT + if (go->neg_chap) { + chap_auth_peer(pcb, pcb->settings.our_name, CHAP_DIGEST(go->chap_mdtype)); + auth |= CHAP_PEER; + } else +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + if (go->neg_upap) { + upap_authpeer(pcb); + auth |= PAP_PEER; + } else +#endif /* PAP_SUPPORT */ + {} +#endif /* PPP_SERVER */ + +#if EAP_SUPPORT + if (ho->neg_eap) { + eap_authwithpeer(pcb, pcb->settings.user); + auth |= EAP_WITHPEER; + } else +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT + if (ho->neg_chap) { + chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); + auth |= CHAP_WITHPEER; + } else +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + if (ho->neg_upap) { + upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); + auth |= PAP_WITHPEER; + } else +#endif /* PAP_SUPPORT */ + {} + + pcb->auth_pending = auth; + pcb->auth_done = 0; + + if (!auth) + + network_phase(pcb); +} + +/* + * Proceed to the network phase. + */ +static void network_phase(ppp_pcb *pcb) { +#if CBCP_SUPPORT + ppp_pcb *pcb = &ppp_pcb_list[unit]; +#endif +#if 0 /* UNUSED */ + lcp_options *go = &lcp_gotoptions[unit]; +#endif /* UNUSED */ + +#if 0 /* UNUSED */ + /* Log calling number. */ + if (*remote_number) + ppp_notice("peer from calling number %q authorized", remote_number); +#endif /* UNUSED */ + +#if PPP_NOTIFY + /* + * If the peer had to authenticate, notify it now. + */ + if (0 +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + || go->neg_upap +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + ) { + notify(auth_up_notifier, 0); + } +#endif /* PPP_NOTIFY */ + +#if CBCP_SUPPORT + /* + * If we negotiated callback, do it now. + */ + if (go->neg_cbcp) { + new_phase(pcb, PPP_PHASE_CALLBACK); + (*cbcp_protent.open)(pcb); + return; + } +#endif + +#if PPP_OPTIONS + /* + * Process extra options from the secrets file + */ + if (extra_options) { + options_from_list(extra_options, 1); + free_wordlist(extra_options); + extra_options = 0; + } +#endif /* PPP_OPTIONS */ + start_networks(pcb); +} + +void start_networks(ppp_pcb *pcb) { +#if CCP_SUPPORT || ECP_SUPPORT + int i; + const struct protent *protp; +#endif /* CCP_SUPPORT || ECP_SUPPORT */ +#if ECP_SUPPORT + int ecp_required; +#endif /* ECP_SUPPORT */ +#ifdef MPPE + int mppe_required; +#endif /* MPPE */ + + new_phase(pcb, PPP_PHASE_NETWORK); + +#ifdef HAVE_MULTILINK + if (multilink) { + if (mp_join_bundle()) { + if (multilink_join_hook) + (*multilink_join_hook)(); + if (updetach && !nodetach) + detach(); + return; + } + } +#endif /* HAVE_MULTILINK */ + +#ifdef PPP_FILTER + if (!demand) + set_filters(&pass_filter, &active_filter); +#endif +#if CCP_SUPPORT || ECP_SUPPORT + /* Start CCP and ECP */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if ( + (0 +#if ECP_SUPPORT + || protp->protocol == PPP_ECP +#endif /* ECP_SUPPORT */ +#if CCP_SUPPORT + || protp->protocol == PPP_CCP +#endif /* CCP_SUPPORT */ + ) + && protp->enabled_flag && protp->open != NULL) + (*protp->open)(pcb); +#endif /* CCP_SUPPORT || ECP_SUPPORT */ + + /* + * Bring up other network protocols iff encryption is not required. + */ +#if ECP_SUPPORT + ecp_required = ecp_gotoptions[unit].required; +#endif /* ECP_SUPPORT */ +#ifdef MPPE + mppe_required = ccp_gotoptions[unit].mppe; +#endif /* MPPE */ + + if (1 +#if ECP_SUPPORT + && !ecp_required +#endif /* ECP_SUPPORT */ +#ifdef MPPE + && !mppe_required +#endif /* MPPE */ + ) + continue_networks(pcb); +} + +void continue_networks(ppp_pcb *pcb) { + int i; + const struct protent *protp; + + /* + * Start the "real" network protocols. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol < 0xC000 +#if CCP_SUPPORT + && protp->protocol != PPP_CCP +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT + && protp->protocol != PPP_ECP +#endif /* ECP_SUPPORT */ + && protp->enabled_flag && protp->open != NULL) { + (*protp->open)(pcb); + ++pcb->num_np_open; + } + + if (pcb->num_np_open == 0) + /* nothing to do */ + lcp_close(pcb, "No network protocols running"); +} + +#if PPP_SERVER +/* + * The peer has failed to authenticate himself using `protocol'. + */ +void auth_peer_fail(ppp_pcb *pcb, int protocol) { + int errcode = PPPERR_AUTHFAIL; + LWIP_UNUSED_ARG(protocol); + /* + * Authentication failure: take the link down + */ +#if 0 /* UNUSED */ + status = EXIT_PEER_AUTH_FAILED; +#endif /* UNUSED */ + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "Authentication failed"); +} + +/* + * The peer has been successfully authenticated using `protocol'. + */ +void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) { + int bit; + + switch (protocol) { +#if CHAP_SUPPORT + case PPP_CHAP: + bit = CHAP_PEER; + switch (prot_flavor) { + case CHAP_MD5: + bit |= CHAP_MD5_PEER; + break; +#if MSCHAP_SUPPORT + case CHAP_MICROSOFT: + bit |= CHAP_MS_PEER; + break; + case CHAP_MICROSOFT_V2: + bit |= CHAP_MS2_PEER; + break; +#endif /* MSCHAP_SUPPORT */ + default: + break; + } + break; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + case PPP_PAP: + bit = PAP_PEER; + break; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + case PPP_EAP: + bit = EAP_PEER; + break; +#endif /* EAP_SUPPORT */ + default: + ppp_warn("auth_peer_success: unknown protocol %x", protocol); + return; + } + + /* + * Save the authenticated name of the peer for later. + */ + /* FIXME: do we need that ? */ + if (namelen > (int)sizeof(pcb->peer_authname) - 1) + namelen = (int)sizeof(pcb->peer_authname) - 1; + MEMCPY(pcb->peer_authname, name, namelen); + pcb->peer_authname[namelen] = 0; +#if 0 /* UNUSED */ + script_setenv("PEERNAME", , 0); +#endif /* UNUSED */ + + /* Save the authentication method for later. */ + pcb->auth_done |= bit; + + /* + * If there is no more authentication still to be done, + * proceed to the network (or callback) phase. + */ + if ((pcb->auth_pending &= ~bit) == 0) + network_phase(pcb); +} +#endif /* PPP_SERVER */ + +/* + * We have failed to authenticate ourselves to the peer using `protocol'. + */ +void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { + int errcode = PPPERR_AUTHFAIL; + LWIP_UNUSED_ARG(protocol); + /* + * We've failed to authenticate ourselves to our peer. + * + * Some servers keep sending CHAP challenges, but there + * is no point in persisting without any way to get updated + * authentication secrets. + * + * He'll probably take the link down, and there's not much + * we can do except wait for that. + */ + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "Failed to authenticate ourselves to peer"); +} + +/* + * We have successfully authenticated ourselves with the peer using `protocol'. + */ +void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { + int bit; + const char *prot = ""; + + switch (protocol) { +#if CHAP_SUPPORT + case PPP_CHAP: + bit = CHAP_WITHPEER; + prot = "CHAP"; + switch (prot_flavor) { + case CHAP_MD5: + bit |= CHAP_MD5_WITHPEER; + break; +#if MSCHAP_SUPPORT + case CHAP_MICROSOFT: + bit |= CHAP_MS_WITHPEER; + break; + case CHAP_MICROSOFT_V2: + bit |= CHAP_MS2_WITHPEER; + break; +#endif /* MSCHAP_SUPPORT */ + default: + break; + } + break; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + case PPP_PAP: + bit = PAP_WITHPEER; + prot = "PAP"; + break; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + case PPP_EAP: + bit = EAP_WITHPEER; + prot = "EAP"; + break; +#endif /* EAP_SUPPORT */ + default: + ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); + bit = 0; + /* no break */ + } + + ppp_notice("%s authentication succeeded", prot); + + /* Save the authentication method for later. */ + pcb->auth_done |= bit; + + /* + * If there is no more authentication still being done, + * proceed to the network (or callback) phase. + */ + if ((pcb->auth_pending &= ~bit) == 0) + network_phase(pcb); +} + + +/* + * np_up - a network protocol has come up. + */ +void np_up(ppp_pcb *pcb, int proto) { +#if PPP_IDLETIMELIMIT + int tlim; +#endif /* PPP_IDLETIMELIMIT */ + LWIP_UNUSED_ARG(proto); + + if (pcb->num_np_up == 0) { + /* + * At this point we consider that the link has come up successfully. + */ + new_phase(pcb, PPP_PHASE_RUNNING); + +#if PPP_IDLETIMELIMIT +#if 0 /* UNUSED */ + if (idle_time_hook != 0) + tlim = (*idle_time_hook)(NULL); + else +#endif /* UNUSED */ + tlim = pcb->settings.idle_time_limit; + if (tlim > 0) + TIMEOUT(check_idle, (void*)pcb, tlim); +#endif /* PPP_IDLETIMELIMIT */ + +#if PPP_MAXCONNECT + /* + * Set a timeout to close the connection once the maximum + * connect time has expired. + */ + if (pcb->settings.maxconnect > 0) + TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); +#endif /* PPP_MAXCONNECT */ + +#ifdef MAXOCTETS + if (maxoctets > 0) + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); +#endif + +#if 0 /* Unused */ + /* + * Detach now, if the updetach option was given. + */ + if (updetach && !nodetach) + detach(); +#endif /* Unused */ + } + ++pcb->num_np_up; +} + +/* + * np_down - a network protocol has gone down. + */ +void np_down(ppp_pcb *pcb, int proto) { + LWIP_UNUSED_ARG(proto); + if (--pcb->num_np_up == 0) { +#if PPP_IDLETIMELIMIT + UNTIMEOUT(check_idle, (void*)pcb); +#endif /* PPP_IDLETIMELIMIT */ +#if PPP_MAXCONNECT + UNTIMEOUT(connect_time_expired, NULL); +#endif /* PPP_MAXCONNECT */ +#ifdef MAXOCTETS + UNTIMEOUT(check_maxoctets, NULL); +#endif + new_phase(pcb, PPP_PHASE_NETWORK); + } +} + +/* + * np_finished - a network protocol has finished using the link. + */ +void np_finished(ppp_pcb *pcb, int proto) { + LWIP_UNUSED_ARG(proto); + if (--pcb->num_np_open <= 0) { + /* no further use for the link: shut up shop. */ + lcp_close(pcb, "No network protocols running"); + } +} + +#ifdef MAXOCTETS +static void +check_maxoctets(arg) + void *arg; +{ +#if PPP_STATS_SUPPORT + unsigned int used; + + update_link_stats(ifunit); + link_stats_valid=0; + + switch(maxoctets_dir) { + case PPP_OCTETS_DIRECTION_IN: + used = link_stats.bytes_in; + break; + case PPP_OCTETS_DIRECTION_OUT: + used = link_stats.bytes_out; + break; + case PPP_OCTETS_DIRECTION_MAXOVERAL: + case PPP_OCTETS_DIRECTION_MAXSESSION: + used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; + break; + default: + used = link_stats.bytes_in+link_stats.bytes_out; + break; + } + if (used > maxoctets) { + ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); + status = EXIT_TRAFFIC_LIMIT; + lcp_close(pcb, "Traffic limit"); +#if 0 /* UNUSED */ + need_holdoff = 0; +#endif /* UNUSED */ + } else { + TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); + } +#endif /* PPP_STATS_SUPPORT */ +} +#endif /* MAXOCTETS */ + +#if PPP_IDLETIMELIMIT +/* + * check_idle - check whether the link has been idle for long + * enough that we can shut it down. + */ +static void check_idle(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + struct ppp_idle idle; + time_t itime; + int tlim; + + if (!get_idle_time(pcb, &idle)) + return; +#if 0 /* UNUSED */ + if (idle_time_hook != 0) { + tlim = idle_time_hook(&idle); + } else { +#endif /* UNUSED */ + itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); + tlim = pcb->settings.idle_time_limit - itime; +#if 0 /* UNUSED */ + } +#endif /* UNUSED */ + if (tlim <= 0) { + int errcode = PPPERR_IDLETIMEOUT; + /* link is idle: shut it down. */ + ppp_notice("Terminating connection due to lack of activity."); + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "Link inactive"); +#if 0 /* UNUSED */ + need_holdoff = 0; +#endif /* UNUSED */ + } else { + TIMEOUT(check_idle, (void*)pcb, tlim); + } +} +#endif /* PPP_IDLETIMELIMIT */ + +#if PPP_MAXCONNECT +/* + * connect_time_expired - log a message and close the connection. + */ +static void connect_time_expired(void *arg) { + int errcode = PPPERR_CONNECTTIME; + ppp_pcb *pcb = (ppp_pcb*)arg; + ppp_info("Connect time expired"); + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "Connect time expired"); /* Close connection */ +} +#endif /* PPP_MAXCONNECT */ + +#if PPP_OPTIONS +/* + * auth_check_options - called to check authentication options. + */ +void +auth_check_options() +{ + lcp_options *wo = &lcp_wantoptions[0]; + int can_auth; + int lacks_ip; + + /* Default our_name to hostname, and user to our_name */ + if (our_name[0] == 0 || usehostname) + strlcpy(our_name, hostname, sizeof(our_name)); + /* If a blank username was explicitly given as an option, trust + the user and don't use our_name */ + if (ppp_settings.user[0] == 0 && !explicit_user) + strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); + + /* + * If we have a default route, require the peer to authenticate + * unless the noauth option was given or the real user is root. + */ + if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { + auth_required = 1; + default_auth = 1; + } + +#if CHAP_SUPPORT + /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ + if (wo->chap_mdtype) + wo->neg_chap = 1; +#endif /* CHAP_SUPPORT */ + + /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ + if (auth_required) { + allow_any_ip = 0; + if (1 +#if CHAP_SUPPORT + && !wo->neg_chap +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + && !wo->neg_upap +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + && !wo->neg_eap +#endif /* EAP_SUPPORT */ + ) { +#if CHAP_SUPPORT + wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; + wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + wo->neg_upap = 1; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + wo->neg_eap = 1; +#endif /* EAP_SUPPORT */ + } + } else { +#if CHAP_SUPPORT + wo->neg_chap = 0; + wo->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + wo->neg_upap = 0; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + wo->neg_eap = 0; +#endif /* EAP_SUPPORT */ + } + + /* + * Check whether we have appropriate secrets to use + * to authenticate the peer. Note that EAP can authenticate by way + * of a CHAP-like exchanges as well as SRP. + */ + lacks_ip = 0; +#if PAP_SUPPORT + can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); +#else + can_auth = 0; +#endif /* PAP_SUPPORT */ + if (!can_auth && (0 +#if CHAP_SUPPORT + || wo->neg_chap +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || wo->neg_eap +#endif /* EAP_SUPPORT */ + )) { +#if CHAP_SUPPORT + can_auth = have_chap_secret((explicit_remote? remote_name: NULL), + our_name, 1, &lacks_ip); +#else + can_auth = 0; +#endif + } + if (!can_auth +#if EAP_SUPPORT + && wo->neg_eap +#endif /* EAP_SUPPORT */ + ) { + can_auth = have_srp_secret((explicit_remote? remote_name: NULL), + our_name, 1, &lacks_ip); + } + + if (auth_required && !can_auth && noauth_addrs == NULL) { + if (default_auth) { + option_error( +"By default the remote system is required to authenticate itself"); + option_error( +"(because this system has a default route to the internet)"); + } else if (explicit_remote) + option_error( +"The remote system (%s) is required to authenticate itself", + remote_name); + else + option_error( +"The remote system is required to authenticate itself"); + option_error( +"but I couldn't find any suitable secret (password) for it to use to do so."); + if (lacks_ip) + option_error( +"(None of the available passwords would let it use an IP address.)"); + + exit(1); + } + + /* + * Early check for remote number authorization. + */ + if (!auth_number()) { + ppp_warn("calling number %q is not authorized", remote_number); + exit(EXIT_CNID_AUTH_FAILED); + } +} +#endif /* PPP_OPTIONS */ + +/* + * auth_reset - called when LCP is starting negotiations to recheck + * authentication options, i.e. whether we have appropriate secrets + * to use for authenticating ourselves and/or the peer. + */ +void auth_reset(ppp_pcb *pcb) { + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + if(pcb->settings.passwd) { + +#if PAP_SUPPORT + ao->neg_upap = !pcb->settings.refuse_pap; +#endif /* PAP_SUPPORT */ + +#if EAP_SUPPORT + ao->neg_eap = !pcb->settings.refuse_eap; +#endif /* EAP_SUPPORT */ + +#if CHAP_SUPPORT + ao->chap_mdtype = MDTYPE_NONE; + if(!pcb->settings.refuse_chap) + ao->chap_mdtype |= MDTYPE_MD5; +#if MSCHAP_SUPPORT + if(!pcb->settings.refuse_mschap) + ao->chap_mdtype |= MDTYPE_MICROSOFT; + if(!pcb->settings.refuse_mschap_v2) + ao->chap_mdtype |= MDTYPE_MICROSOFT_V2; +#endif /* MSCHAP_SUPPORT */ + + ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); +#endif /* CHAP_SUPPORT */ + + } else { +#if PAP_SUPPORT + ao->neg_upap = 0; +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + ao->neg_chap = 0; + ao->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + ao->neg_eap = 0; +#endif /* EAP_SUPPORT */ + } + +#if PAP_SUPPORT + PPPDEBUG(LOG_DEBUG, ("neg_upap: %d\n", ao->neg_upap) ); +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + PPPDEBUG(LOG_DEBUG, ("neg_chap: %d\n", ao->neg_chap) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5)) ); +#if MSCHAP_SUPPORT + PPPDEBUG(LOG_DEBUG, ("neg_chap_ms: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT)) ); + PPPDEBUG(LOG_DEBUG, ("neg_chap_ms2: %d\n", !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2)) ); +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + PPPDEBUG(LOG_DEBUG, ("neg_eap: %d\n", ao->neg_eap) ); +#endif /* EAP_SUPPORT */ + +#if 0 /* OLD CODE */ + ao->neg_upap = !ppp_settings.refuse_pap && (ppp_settings.passwd[0] != 0 || get_pap_passwd(NULL)); + + /* + ao->neg_chap = (!ppp_settings.refuse_chap || !refuse_mschap || !refuse_mschap_v2) + && (passwd[0] != 0 || + (hadchap = have_chap_secret(user, (explicit_remote? remote_name: + NULL), 0, NULL))); */ + /* + ao->neg_eap = !refuse_eap && ( + passwd[0] != 0 || + (hadchap == 1 || (hadchap == -1 && have_chap_secret(ppp_settings.user, + (explicit_remote? remote_name: NULL), 0, NULL))) || + have_srp_secret(ppp_settings.user, (explicit_remote? remote_name: NULL), 0, NULL)); */ +#endif /* OLD CODE */ + +#if PAP_SUPPORT + go->neg_upap = 0; +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + go->neg_chap = 0; + go->chap_mdtype = MDTYPE_NONE; +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + go->neg_eap = 0; +#endif /* EAP_SUPPORT */ + return; +#if 0 + /* FIXME: find what the below stuff do */ + int hadchap; + hadchap = -1; + + hadchap = -1; + if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) + go->neg_upap = 0; + + if (go->neg_chap) { + if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), + our_name, 1, NULL))) + go->neg_chap = 0; + } + + if (go->neg_eap && + (hadchap == 0 || (hadchap == -1 && + !have_chap_secret((explicit_remote? remote_name: NULL), our_name, + 1, NULL))) && + !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, + NULL)) + go->neg_eap = 0; +#endif +} + +#if 0 /* UNUSED */ +/* + * check_passwd - Check the user name and passwd against the PAP secrets + * file. If requested, also check against the system password database, + * and login the user if OK. + * + * returns: + * UPAP_AUTHNAK: Authentication failed. + * UPAP_AUTHACK: Authentication succeeded. + * In either case, msg points to an appropriate message. + */ +int +check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) + int unit; + char *auser; + int userlen; + char *apasswd; + int passwdlen; + char **msg; +{ + return UPAP_AUTHNAK; + int ret; + char *filename; + FILE *f; + struct wordlist *addrs = NULL, *opts = NULL; + char passwd[256], user[256]; + char secret[MAXWORDLEN]; + static int attempts = 0; + + /* + * Make copies of apasswd and auser, then null-terminate them. + * If there are unprintable characters in the password, make + * them visible. + */ + slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); + slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); + *msg = ""; + + /* + * Check if a plugin wants to handle this. + */ + if (pap_auth_hook) { + ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); + if (ret >= 0) { + /* note: set_allowed_addrs() saves opts (but not addrs): + don't free it! */ + if (ret) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); + return ret? UPAP_AUTHACK: UPAP_AUTHNAK; + } + } + + /* + * Open the file of pap secrets and scan for a suitable secret + * for authenticating this user. + */ + filename = _PATH_UPAPFILE; + addrs = opts = NULL; + ret = UPAP_AUTHNAK; + f = fopen(filename, "r"); + if (f == NULL) { + ppp_error("Can't open PAP password file %s: %m", filename); + + } else { + check_access(f, filename); + if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { + ppp_warn("no PAP secret found for %s", user); + } else { + /* + * If the secret is "@login", it means to check + * the password against the login database. + */ + int login_secret = strcmp(secret, "@login") == 0; + ret = UPAP_AUTHACK; + if (uselogin || login_secret) { + /* login option or secret is @login */ + if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { + ret = UPAP_AUTHNAK; + } + } else if (session_mgmt) { + if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { + ppp_warn("Peer %q failed PAP Session verification", user); + ret = UPAP_AUTHNAK; + } + } + if (secret[0] != 0 && !login_secret) { + /* password given in pap-secrets - must match */ + if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) + && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) + ret = UPAP_AUTHNAK; + } + } + fclose(f); + } + + if (ret == UPAP_AUTHNAK) { + if (**msg == 0) + *msg = "Login incorrect"; + /* + * XXX can we ever get here more than once?? + * Frustrate passwd stealer programs. + * Allow 10 tries, but start backing off after 3 (stolen from login). + * On 10'th, drop the connection. + */ + if (attempts++ >= 10) { + ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); + lcp_close(pcb, "login failed"); + } + if (attempts > 3) + sleep((u_int) (attempts - 3) * 5); + if (opts != NULL) + free_wordlist(opts); + + } else { + attempts = 0; /* Reset count */ + if (**msg == 0) + *msg = "Login ok"; + set_allowed_addrs(unit, addrs, opts); + } + + if (addrs != NULL) + free_wordlist(addrs); + BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); + BZERO(secret, sizeof(secret)); + + return ret; +} + +/* + * null_login - Check if a username of "" and a password of "" are + * acceptable, and iff so, set the list of acceptable IP addresses + * and return 1. + */ +static int +null_login(unit) + int unit; +{ + char *filename; + FILE *f; + int i, ret; + struct wordlist *addrs, *opts; + char secret[MAXWORDLEN]; + + /* + * Check if a plugin wants to handle this. + */ + ret = -1; + if (null_auth_hook) + ret = (*null_auth_hook)(&addrs, &opts); + + /* + * Open the file of pap secrets and scan for a suitable secret. + */ + if (ret <= 0) { + filename = _PATH_UPAPFILE; + addrs = NULL; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + check_access(f, filename); + + i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); + ret = i >= 0 && secret[0] == 0; + BZERO(secret, sizeof(secret)); + fclose(f); + } + + if (ret) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + + return ret; +} + +/* + * get_pap_passwd - get a password for authenticating ourselves with + * our peer using PAP. Returns 1 on success, 0 if no suitable password + * could be found. + * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). + */ +static int +get_pap_passwd(passwd) + char *passwd; +{ + char *filename; + FILE *f; + int ret; + char secret[MAXWORDLEN]; + + /* + * Check whether a plugin wants to supply this. + */ + if (pap_passwd_hook) { + ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); + if (ret >= 0) + return ret; + } + + filename = _PATH_UPAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + check_access(f, filename); + ret = scan_authfile(f, user, + (remote_name[0]? remote_name: NULL), + secret, NULL, NULL, filename, 0); + fclose(f); + if (ret < 0) + return 0; + if (passwd != NULL) + strlcpy(passwd, secret, MAXSECRETLEN); + BZERO(secret, sizeof(secret)); + return 1; +} + +/* + * have_pap_secret - check whether we have a PAP file with any + * secrets that we could possibly use for authenticating the peer. + */ +static int +have_pap_secret(lacks_ipp) + int *lacks_ipp; +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + + /* let the plugin decide, if there is one */ + if (pap_check_hook) { + ret = (*pap_check_hook)(); + if (ret >= 0) + return ret; + } + + filename = _PATH_UPAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, + NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} + +/* + * have_chap_secret - check whether we have a CHAP file with a + * secret that we could possibly use for authenticating `client' + * on `server'. Either can be the null string, meaning we don't + * know the identity yet. + */ +static int +have_chap_secret(client, server, need_ip, lacks_ipp) + char *client; + char *server; + int need_ip; + int *lacks_ipp; +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + + if (chap_check_hook) { + ret = (*chap_check_hook)(); + if (ret >= 0) { + return ret; + } + } + + filename = _PATH_CHAPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} + +/* + * have_srp_secret - check whether we have a SRP file with a + * secret that we could possibly use for authenticating `client' + * on `server'. Either can be the null string, meaning we don't + * know the identity yet. + */ +static int +have_srp_secret(client, server, need_ip, lacks_ipp) + char *client; + char *server; + int need_ip; + int *lacks_ipp; +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + + filename = _PATH_SRPFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); + fclose(f); + if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} +#endif /* UNUSED */ + +/* + * get_secret - open the CHAP secret file and return the secret + * for authenticating the given client on the given server. + * (We could be either client or server). + */ +int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) { + int len; + + LWIP_UNUSED_ARG(server); + LWIP_UNUSED_ARG(am_server); + + if(!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { + return 0; + } + + len = (int)strlen(pcb->settings.passwd); + if (len > MAXSECRETLEN) { + ppp_error("Secret for %s on %s is too long", client, server); + len = MAXSECRETLEN; + } + + MEMCPY(secret, pcb->settings.passwd, len); + *secret_len = len; + + return 1; + +/* FIXME: clean that */ +#if 0 + strlcpy(rname, ppp_settings.user, sizeof(rname)); + + +/* + strlcpy(rname, ppp_settings.user, sizeof(rname)); + strlcpy(secret, ppp_settings.passwd, sizeof(secret)); + secret_len = strlen(secret); +*/ + + FILE *f; + int ret, len; + char *filename; + struct wordlist *addrs, *opts; + char secbuf[MAXWORDLEN]; + struct wordlist *addrs; + addrs = NULL; + + if (!am_server && ppp_settings.passwd[0] != 0) { + strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); + } else if (!am_server && chap_passwd_hook) { + if ( (*chap_passwd_hook)(client, secbuf) < 0) { + ppp_error("Unable to obtain CHAP password for %s on %s from plugin", + client, server); + return 0; + } + } else { + filename = _PATH_CHAPFILE; + addrs = NULL; + secbuf[0] = 0; + + f = fopen(filename, "r"); + if (f == NULL) { + ppp_error("Can't open chap secret file %s: %m", filename); + return 0; + } + check_access(f, filename); + + ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); + fclose(f); + if (ret < 0) + return 0; + + if (am_server) + set_allowed_addrs(unit, addrs, opts); + else if (opts != 0) + free_wordlist(opts); + if (addrs != 0) + free_wordlist(addrs); + } + + len = strlen(secbuf); + if (len > MAXSECRETLEN) { + ppp_error("Secret for %s on %s is too long", client, server); + len = MAXSECRETLEN; + } + MEMCPY(secret, secbuf, len); + BZERO(secbuf, sizeof(secbuf)); + *secret_len = len; + + return 1; +#endif +} + + +#if 0 /* UNUSED */ +/* + * get_srp_secret - open the SRP secret file and return the secret + * for authenticating the given client on the given server. + * (We could be either client or server). + */ +int +get_srp_secret(unit, client, server, secret, am_server) + int unit; + char *client; + char *server; + char *secret; + int am_server; +{ + FILE *fp; + int ret; + char *filename; + struct wordlist *addrs, *opts; + + if (!am_server && ppp_settings.passwd[0] != '\0') { + strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); + } else { + filename = _PATH_SRPFILE; + addrs = NULL; + + fp = fopen(filename, "r"); + if (fp == NULL) { + ppp_error("Can't open srp secret file %s: %m", filename); + return 0; + } + check_access(fp, filename); + + secret[0] = '\0'; + ret = scan_authfile(fp, client, server, secret, &addrs, &opts, + filename, am_server); + fclose(fp); + if (ret < 0) + return 0; + + if (am_server) + set_allowed_addrs(unit, addrs, opts); + else if (opts != NULL) + free_wordlist(opts); + if (addrs != NULL) + free_wordlist(addrs); + } + + return 1; +} + +/* + * set_allowed_addrs() - set the list of allowed addresses. + * Also looks for `--' indicating options to apply for this peer + * and leaves the following words in extra_options. + */ +static void +set_allowed_addrs(unit, addrs, opts) + int unit; + struct wordlist *addrs; + struct wordlist *opts; +{ + int n; + struct wordlist *ap, **plink; + struct permitted_ip *ip; + char *ptr_word, *ptr_mask; + struct hostent *hp; + struct netent *np; + u32_t a, mask, ah, offset; + struct ipcp_options *wo = &ipcp_wantoptions[unit]; + u32_t suggested_ip = 0; + + if (addresses[unit] != NULL) + free(addresses[unit]); + addresses[unit] = NULL; + if (extra_options != NULL) + free_wordlist(extra_options); + extra_options = opts; + + /* + * Count the number of IP addresses given. + */ + n = wordlist_count(addrs) + wordlist_count(noauth_addrs); + if (n == 0) + return; + ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); + if (ip == 0) + return; + + /* temporarily append the noauth_addrs list to addrs */ + for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) + ; + *plink = noauth_addrs; + + n = 0; + for (ap = addrs; ap != NULL; ap = ap->next) { + /* "-" means no addresses authorized, "*" means any address allowed */ + ptr_word = ap->word; + if (strcmp(ptr_word, "-") == 0) + break; + if (strcmp(ptr_word, "*") == 0) { + ip[n].permit = 1; + ip[n].base = ip[n].mask = 0; + ++n; + break; + } + + ip[n].permit = 1; + if (*ptr_word == '!') { + ip[n].permit = 0; + ++ptr_word; + } + + mask = ~ (u32_t) 0; + offset = 0; + ptr_mask = strchr (ptr_word, '/'); + if (ptr_mask != NULL) { + int bit_count; + char *endp; + + bit_count = (int) strtol (ptr_mask+1, &endp, 10); + if (bit_count <= 0 || bit_count > 32) { + ppp_warn("invalid address length %v in auth. address list", + ptr_mask+1); + continue; + } + bit_count = 32 - bit_count; /* # bits in host part */ + if (*endp == '+') { + offset = ifunit + 1; + ++endp; + } + if (*endp != 0) { + ppp_warn("invalid address length syntax: %v", ptr_mask+1); + continue; + } + *ptr_mask = '\0'; + mask <<= bit_count; + } + + hp = gethostbyname(ptr_word); + if (hp != NULL && hp->h_addrtype == AF_INET) { + a = *(u32_t *)hp->h_addr; + } else { + np = getnetbyname (ptr_word); + if (np != NULL && np->n_addrtype == AF_INET) { + a = htonl ((u32_t)np->n_net); + if (ptr_mask == NULL) { + /* calculate appropriate mask for net */ + ah = ntohl(a); + if (IN_CLASSA(ah)) + mask = IN_CLASSA_NET; + else if (IN_CLASSB(ah)) + mask = IN_CLASSB_NET; + else if (IN_CLASSC(ah)) + mask = IN_CLASSC_NET; + } + } else { + a = inet_addr (ptr_word); + } + } + + if (ptr_mask != NULL) + *ptr_mask = '/'; + + if (a == (u32_t)-1L) { + ppp_warn("unknown host %s in auth. address list", ap->word); + continue; + } + if (offset != 0) { + if (offset >= ~mask) { + ppp_warn("interface unit %d too large for subnet %v", + ifunit, ptr_word); + continue; + } + a = htonl((ntohl(a) & mask) + offset); + mask = ~(u32_t)0; + } + ip[n].mask = htonl(mask); + ip[n].base = a & ip[n].mask; + ++n; + if (~mask == 0 && suggested_ip == 0) + suggested_ip = a; + } + *plink = NULL; + + ip[n].permit = 0; /* make the last entry forbid all addresses */ + ip[n].base = 0; /* to terminate the list */ + ip[n].mask = 0; + + addresses[unit] = ip; + + /* + * If the address given for the peer isn't authorized, or if + * the user hasn't given one, AND there is an authorized address + * which is a single host, then use that if we find one. + */ + if (suggested_ip != 0 + && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { + wo->hisaddr = suggested_ip; + /* + * Do we insist on this address? No, if there are other + * addresses authorized than the suggested one. + */ + if (n > 1) + wo->accept_remote = 1; + } +} + +/* + * auth_ip_addr - check whether the peer is authorized to use + * a given IP address. Returns 1 if authorized, 0 otherwise. + */ +int +auth_ip_addr(unit, addr) + int unit; + u32_t addr; +{ + int ok; + + /* don't allow loopback or multicast address */ + if (bad_ip_adrs(addr)) + return 0; + + if (allowed_address_hook) { + ok = allowed_address_hook(addr); + if (ok >= 0) return ok; + } + + if (addresses[unit] != NULL) { + ok = ip_addr_check(addr, addresses[unit]); + if (ok >= 0) + return ok; + } + + if (auth_required) + return 0; /* no addresses authorized */ + return allow_any_ip || privileged || !have_route_to(addr); +} + +static int +ip_addr_check(addr, addrs) + u32_t addr; + struct permitted_ip *addrs; +{ + for (; ; ++addrs) + if ((addr & addrs->mask) == addrs->base) + return addrs->permit; +} + +/* + * bad_ip_adrs - return 1 if the IP address is one we don't want + * to use, such as an address in the loopback net or a multicast address. + * addr is in network byte order. + */ +int +bad_ip_adrs(addr) + u32_t addr; +{ + addr = ntohl(addr); + return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET + || IN_MULTICAST(addr) || IN_BADCLASS(addr); +} + +/* + * some_ip_ok - check a wordlist to see if it authorizes any + * IP address(es). + */ +static int +some_ip_ok(addrs) + struct wordlist *addrs; +{ + for (; addrs != 0; addrs = addrs->next) { + if (addrs->word[0] == '-') + break; + if (addrs->word[0] != '!') + return 1; /* some IP address is allowed */ + } + return 0; +} + +/* + * auth_number - check whether the remote number is allowed to connect. + * Returns 1 if authorized, 0 otherwise. + */ +int +auth_number() +{ + struct wordlist *wp = permitted_numbers; + int l; + + /* Allow all if no authorization list. */ + if (!wp) + return 1; + + /* Allow if we have a match in the authorization list. */ + while (wp) { + /* trailing '*' wildcard */ + l = strlen(wp->word); + if ((wp->word)[l - 1] == '*') + l--; + if (!strncasecmp(wp->word, remote_number, l)) + return 1; + wp = wp->next; + } + + return 0; +} + +/* + * check_access - complain if a secret file has too-liberal permissions. + */ +static void +check_access(f, filename) + FILE *f; + char *filename; +{ + struct stat sbuf; + + if (fstat(fileno(f), &sbuf) < 0) { + ppp_warn("cannot stat secret file %s: %m", filename); + } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { + ppp_warn("Warning - secret file %s has world and/or group access", + filename); + } +} + +/* + * scan_authfile - Scan an authorization file for a secret suitable + * for authenticating `client' on `server'. The return value is -1 + * if no secret is found, otherwise >= 0. The return value has + * NONWILD_CLIENT set if the secret didn't have "*" for the client, and + * NONWILD_SERVER set if the secret didn't have "*" for the server. + * Any following words on the line up to a "--" (i.e. address authorization + * info) are placed in a wordlist and returned in *addrs. Any + * following words (extra options) are placed in a wordlist and + * returned in *opts. + * We assume secret is NULL or points to MAXWORDLEN bytes of space. + * Flags are non-zero if we need two colons in the secret in order to + * match. + */ +static int +scan_authfile(f, client, server, secret, addrs, opts, filename, flags) + FILE *f; + char *client; + char *server; + char *secret; + struct wordlist **addrs; + struct wordlist **opts; + char *filename; + int flags; +{ + int newline, xxx; + int got_flag, best_flag; + FILE *sf; + struct wordlist *ap, *addr_list, *alist, **app; + char word[MAXWORDLEN]; + char atfile[MAXWORDLEN]; + char lsecret[MAXWORDLEN]; + char *cp; + + if (addrs != NULL) + *addrs = NULL; + if (opts != NULL) + *opts = NULL; + addr_list = NULL; + if (!getword(f, word, &newline, filename)) + return -1; /* file is empty??? */ + newline = 1; + best_flag = -1; + for (;;) { + /* + * Skip until we find a word at the start of a line. + */ + while (!newline && getword(f, word, &newline, filename)) + ; + if (!newline) + break; /* got to end of file */ + + /* + * Got a client - check if it's a match or a wildcard. + */ + got_flag = 0; + if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { + newline = 0; + continue; + } + if (!ISWILD(word)) + got_flag = NONWILD_CLIENT; + + /* + * Now get a server and check if it matches. + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + if (!ISWILD(word)) { + if (server != NULL && strcmp(word, server) != 0) + continue; + got_flag |= NONWILD_SERVER; + } + + /* + * Got some sort of a match - see if it's better than what + * we have already. + */ + if (got_flag <= best_flag) + continue; + + /* + * Get the secret. + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + + /* + * SRP-SHA1 authenticator should never be reading secrets from + * a file. (Authenticatee may, though.) + */ + if (flags && ((cp = strchr(word, ':')) == NULL || + strchr(cp + 1, ':') == NULL)) + continue; + + if (secret != NULL) { + /* + * Special syntax: @/pathname means read secret from file. + */ + if (word[0] == '@' && word[1] == '/') { + strlcpy(atfile, word+1, sizeof(atfile)); + if ((sf = fopen(atfile, "r")) == NULL) { + ppp_warn("can't open indirect secret file %s", atfile); + continue; + } + check_access(sf, atfile); + if (!getword(sf, word, &xxx, atfile)) { + ppp_warn("no secret in indirect secret file %s", atfile); + fclose(sf); + continue; + } + fclose(sf); + } + strlcpy(lsecret, word, sizeof(lsecret)); + } + + /* + * Now read address authorization info and make a wordlist. + */ + app = &alist; + for (;;) { + if (!getword(f, word, &newline, filename) || newline) + break; + ap = (struct wordlist *) + malloc(sizeof(struct wordlist) + strlen(word) + 1); + if (ap == NULL) + novm("authorized addresses"); + ap->word = (char *) (ap + 1); + strcpy(ap->word, word); + *app = ap; + app = &ap->next; + } + *app = NULL; + + /* + * This is the best so far; remember it. + */ + best_flag = got_flag; + if (addr_list) + free_wordlist(addr_list); + addr_list = alist; + if (secret != NULL) + strlcpy(secret, lsecret, MAXWORDLEN); + + if (!newline) + break; + } + + /* scan for a -- word indicating the start of options */ + for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) + if (strcmp(ap->word, "--") == 0) + break; + /* ap = start of options */ + if (ap != NULL) { + ap = ap->next; /* first option */ + free(*app); /* free the "--" word */ + *app = NULL; /* terminate addr list */ + } + if (opts != NULL) + *opts = ap; + else if (ap != NULL) + free_wordlist(ap); + if (addrs != NULL) + *addrs = addr_list; + else if (addr_list != NULL) + free_wordlist(addr_list); + + return best_flag; +} + +/* + * wordlist_count - return the number of items in a wordlist + */ +static int +wordlist_count(wp) + struct wordlist *wp; +{ + int n; + + for (n = 0; wp != NULL; wp = wp->next) + ++n; + return n; +} + +/* + * free_wordlist - release memory allocated for a wordlist. + */ +static void +free_wordlist(wp) + struct wordlist *wp; +{ + struct wordlist *next; + + while (wp != NULL) { + next = wp->next; + free(wp); + wp = next; + } +} +#endif /* UNUSED */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ccp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ccp.c new file mode 100644 index 0000000..0af3548 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ccp.c @@ -0,0 +1,1694 @@ +/* + * ccp.c - PPP Compression Control Protocol. + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include +#include + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/ccp.h" +#include + +#ifdef MPPE +#include "netif/ppp/chap_ms.h" /* mppe_xxxx_key, mppe_keys_set */ +#include "netif/ppp/lcp.h" /* lcp_close(), lcp_fsm */ +#endif + +/* + * Unfortunately there is a bug in zlib which means that using a + * size of 8 (window size = 256) for Deflate compression will cause + * buffer overruns and kernel crashes in the deflate module. + * Until this is fixed we only accept sizes in the range 9 .. 15. + * Thanks to James Carlson for pointing this out. + */ +#define DEFLATE_MIN_WORKS 9 + +/* + * Command-line options. + */ +static int setbsdcomp (char **); +static int setdeflate (char **); +static char bsd_value[8]; +static char deflate_value[8]; + +/* + * Option variables. + */ +#ifdef MPPE +bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ +#endif + +#if PPP_OPTIONS +static option_t ccp_option_list[] = { + { "noccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation" }, + { "-ccp", o_bool, &ccp_protent.enabled_flag, + "Disable CCP negotiation", OPT_ALIAS }, + + { "bsdcomp", o_special, (void *)setbsdcomp, + "Request BSD-Compress packet compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, + { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, + "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].bsd_compress }, + + { "deflate", o_special, (void *)setdeflate, + "request Deflate compression", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, + { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + { "-deflate", o_bool, &ccp_wantoptions[0].deflate, + "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].deflate }, + + { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, + "don't use draft deflate #", OPT_A2COPY, + &ccp_allowoptions[0].deflate_draft }, + + { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "request Predictor-1", OPT_PRIO | 1 }, + { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, + "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, + &ccp_allowoptions[0].predictor_1 }, + +#ifdef MPPE + /* MPPE options are symmetrical ... we only set wantoptions here */ + { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "+mppe", o_bool, &ccp_wantoptions[0].mppe, + "require MPPE encryption", + OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, + { "nomppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_PRIO }, + { "-mppe", o_bool, &ccp_wantoptions[0].mppe, + "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, + + /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ + { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, + { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 40-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, + &ccp_wantoptions[0].mppe }, + + { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "require MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, + { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, + "don't allow MPPE 128-bit encryption", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, + &ccp_wantoptions[0].mppe }, + + /* strange one; we always request stateless, but will we allow stateful? */ + { "mppe-stateful", o_bool, &refuse_mppe_stateful, + "allow MPPE stateful mode", OPT_PRIO }, + { "nomppe-stateful", o_bool, &refuse_mppe_stateful, + "disallow MPPE stateful mode", OPT_PRIO | 1 }, +#endif /* MPPE */ + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points from main code. + */ +static void ccp_init (int unit); +static void ccp_open (int unit); +static void ccp_close (int unit, const char *); +static void ccp_lowerup (int unit); +static void ccp_lowerdown (int); +static void ccp_input (int unit, u_char *pkt, int len); +static void ccp_protrej (int unit); +#if PRINTPKT_SUPPORT +static int ccp_printpkt (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); +#endif /* PRINTPKT_SUPPORT */ +static void ccp_datainput (int unit, u_char *pkt, int len); + +const struct protent ccp_protent = { + PPP_CCP, + ccp_init, + ccp_input, + ccp_protrej, + ccp_lowerup, + ccp_lowerdown, + ccp_open, + ccp_close, +#if PRINTPKT_SUPPORT + ccp_printpkt, +#endif /* PRINTPKT_SUPPORT */ + ccp_datainput, + 1, +#if PRINTPKT_SUPPORT + "CCP", + "Compressed", +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + ccp_option_list, + NULL, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, + NULL +#endif /* DEMAND_SUPPORT */ +}; + +fsm ccp_fsm[NUM_PPP]; +ccp_options ccp_wantoptions[NUM_PPP]; /* what to request the peer to use */ +ccp_options ccp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ +ccp_options ccp_allowoptions[NUM_PPP]; /* what we'll agree to do */ +ccp_options ccp_hisoptions[NUM_PPP]; /* what we agreed to do */ + +/* + * Callbacks for fsm code. + */ +static void ccp_resetci (fsm *); +static int ccp_cilen (fsm *); +static void ccp_addci (fsm *, u_char *, int *); +static int ccp_ackci (fsm *, u_char *, int); +static int ccp_nakci (fsm *, u_char *, int, int); +static int ccp_rejci (fsm *, u_char *, int); +static int ccp_reqci (fsm *, u_char *, int *, int); +static void ccp_up (fsm *); +static void ccp_down (fsm *); +static int ccp_extcode (fsm *, int, int, u_char *, int); +static void ccp_rack_timeout (void *); +static char *method_name (ccp_options *, ccp_options *); + +static const fsm_callbacks ccp_callbacks = { + ccp_resetci, + ccp_cilen, + ccp_addci, + ccp_ackci, + ccp_nakci, + ccp_rejci, + ccp_reqci, + ccp_up, + ccp_down, + NULL, + NULL, + NULL, + NULL, + ccp_extcode, + "CCP" +}; + +/* + * Do we want / did we get any compression? + */ +#define ANY_COMPRESS(opt) ((opt).deflate || (opt).bsd_compress \ + || (opt).predictor_1 || (opt).predictor_2 \ + || (opt).mppe) + +/* + * Local state (mainly for handling reset-reqs and reset-acks). + */ +static int ccp_localstate[NUM_PPP]; +#define RACK_PENDING 1 /* waiting for reset-ack */ +#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ + +#define RACKTIMEOUT 1 /* second */ + +static int all_rejected[NUM_PPP]; /* we rejected all peer's options */ + +/* + * Option parsing + */ +static int +setbsdcomp(argv) + char **argv; +{ + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + option_error("invalid parameter '%s' for bsdcomp option", *argv); + return 0; + } + if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) + || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { + option_error("bsdcomp option values must be 0 or %d .. %d", + BSD_MIN_BITS, BSD_MAX_BITS); + return 0; + } + if (rbits > 0) { + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = rbits; + } else + ccp_wantoptions[0].bsd_compress = 0; + if (abits > 0) { + ccp_allowoptions[0].bsd_compress = 1; + ccp_allowoptions[0].bsd_bits = abits; + } else + ccp_allowoptions[0].bsd_compress = 0; + slprintf(bsd_value, sizeof(bsd_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +static int +setdeflate(argv) + char **argv; +{ + int rbits, abits; + char *str, *endp; + + str = *argv; + abits = rbits = strtol(str, &endp, 0); + if (endp != str && *endp == ',') { + str = endp + 1; + abits = strtol(str, &endp, 0); + } + if (*endp != 0 || endp == str) { + option_error("invalid parameter '%s' for deflate option", *argv); + return 0; + } + if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) + || (abits != 0 && (abits < DEFLATE_MIN_SIZE + || abits > DEFLATE_MAX_SIZE))) { + option_error("deflate option values must be 0 or %d .. %d", + DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); + return 0; + } + if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { + if (rbits == DEFLATE_MIN_SIZE) + rbits = DEFLATE_MIN_WORKS; + if (abits == DEFLATE_MIN_SIZE) + abits = DEFLATE_MIN_WORKS; + warn("deflate option value of %d changed to %d to avoid zlib bug", + DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); + } + if (rbits > 0) { + ccp_wantoptions[0].deflate = 1; + ccp_wantoptions[0].deflate_size = rbits; + } else + ccp_wantoptions[0].deflate = 0; + if (abits > 0) { + ccp_allowoptions[0].deflate = 1; + ccp_allowoptions[0].deflate_size = abits; + } else + ccp_allowoptions[0].deflate = 0; + slprintf(deflate_value, sizeof(deflate_value), + rbits == abits? "%d": "%d,%d", rbits, abits); + + return 1; +} + +/* + * ccp_init - initialize CCP. + */ +static void +ccp_init(unit) + int unit; +{ + fsm *f = &ccp_fsm[unit]; + + f->unit = unit; + f->protocol = PPP_CCP; + f->callbacks = &ccp_callbacks; + fsm_init(f); + + memset(&ccp_wantoptions[unit], 0, sizeof(ccp_options)); + memset(&ccp_gotoptions[unit], 0, sizeof(ccp_options)); + memset(&ccp_allowoptions[unit], 0, sizeof(ccp_options)); + memset(&ccp_hisoptions[unit], 0, sizeof(ccp_options)); + + ccp_wantoptions[0].deflate = 1; + ccp_wantoptions[0].deflate_size = DEFLATE_MAX_SIZE; + ccp_wantoptions[0].deflate_correct = 1; + ccp_wantoptions[0].deflate_draft = 1; + ccp_allowoptions[0].deflate = 1; + ccp_allowoptions[0].deflate_size = DEFLATE_MAX_SIZE; + ccp_allowoptions[0].deflate_correct = 1; + ccp_allowoptions[0].deflate_draft = 1; + + ccp_wantoptions[0].bsd_compress = 1; + ccp_wantoptions[0].bsd_bits = BSD_MAX_BITS; + ccp_allowoptions[0].bsd_compress = 1; + ccp_allowoptions[0].bsd_bits = BSD_MAX_BITS; + + ccp_allowoptions[0].predictor_1 = 1; +} + +/* + * ccp_open - CCP is allowed to come up. + */ +static void +ccp_open(unit) + int unit; +{ + fsm *f = &ccp_fsm[unit]; + + if (f->state != OPENED) + ccp_flags_set(unit, 1, 0); + + /* + * Find out which compressors the kernel supports before + * deciding whether to open in silent mode. + */ + ccp_resetci(f); + if (!ANY_COMPRESS(ccp_gotoptions[unit])) + f->flags |= OPT_SILENT; + + fsm_open(f); +} + +/* + * ccp_close - Terminate CCP. + */ +static void +ccp_close(unit, reason) + int unit; + const char *reason; +{ + ccp_flags_set(unit, 0, 0); + fsm_close(&ccp_fsm[unit], reason); +} + +/* + * ccp_lowerup - we may now transmit CCP packets. + */ +static void +ccp_lowerup(unit) + int unit; +{ + fsm_lowerup(&ccp_fsm[unit]); +} + +/* + * ccp_lowerdown - we may not transmit CCP packets. + */ +static void +ccp_lowerdown(unit) + int unit; +{ + fsm_lowerdown(&ccp_fsm[unit]); +} + +/* + * ccp_input - process a received CCP packet. + */ +static void +ccp_input(unit, p, len) + int unit; + u_char *p; + int len; +{ + fsm *f = &ccp_fsm[unit]; + int oldstate; + + /* + * Check for a terminate-request so we can print a message. + */ + oldstate = f->state; + fsm_input(f, p, len); + if (oldstate == OPENED && p[0] == TERMREQ && f->state != OPENED) { + notice("Compression disabled by peer."); +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE disabled, closing LCP"); + lcp_close(unit, "MPPE disabled by peer"); + } +#endif + } + + /* + * If we get a terminate-ack and we're not asking for compression, + * close CCP. + */ + if (oldstate == REQSENT && p[0] == TERMACK + && !ANY_COMPRESS(ccp_gotoptions[unit])) + ccp_close(unit, "No compression negotiated"); +} + +/* + * Handle a CCP-specific code. + */ +static int +ccp_extcode(f, code, id, p, len) + fsm *f; + int code, id; + u_char *p; + int len; +{ + switch (code) { + case CCP_RESETREQ: + if (f->state != OPENED) + break; + /* send a reset-ack, which the transmitter will see and + reset its compression state. */ + fsm_sdata(f, CCP_RESETACK, id, NULL, 0); + break; + + case CCP_RESETACK: + if (ccp_localstate[f->unit] & RACK_PENDING && id == f->reqid) { + ccp_localstate[f->unit] &= ~(RACK_PENDING | RREQ_REPEAT); + UNTIMEOUT(ccp_rack_timeout, f); + } + break; + + default: + return 0; + } + + return 1; +} + +/* + * ccp_protrej - peer doesn't talk CCP. + */ +static void +ccp_protrej(unit) + int unit; +{ + ccp_flags_set(unit, 0, 0); + fsm_lowerdown(&ccp_fsm[unit]); + +#ifdef MPPE + if (ccp_gotoptions[unit].mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(unit, "MPPE required but peer negotiation failed"); + } +#endif + +} + +/* + * ccp_resetci - initialize at start of negotiation. + */ +static void +ccp_resetci(f) + fsm *f; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char opt_buf[CCP_MAX_OPTION_LENGTH]; + + *go = ccp_wantoptions[f->unit]; + all_rejected[f->unit] = 0; + +#ifdef MPPE + if (go->mppe) { + ccp_options *ao = &ccp_allowoptions[f->unit]; + int auth_mschap_bits = auth_done[f->unit]; + int numbits; + + /* + * Start with a basic sanity check: mschap[v2] auth must be in + * exactly one direction. RFC 3079 says that the keys are + * 'derived from the credentials of the peer that initiated the call', + * however the PPP protocol doesn't have such a concept, and pppd + * cannot get this info externally. Instead we do the best we can. + * NB: If MPPE is required, all other compression opts are invalid. + * So, we return right away if we can't do it. + */ + + /* Leave only the mschap auth bits set */ + auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | + CHAP_MS2_WITHPEER | CHAP_MS2_PEER); + /* Count the mschap auths */ + auth_mschap_bits >>= CHAP_MS_SHIFT; + numbits = 0; + do { + numbits += auth_mschap_bits & 1; + auth_mschap_bits >>= 1; + } while (auth_mschap_bits); + if (numbits > 1) { + error("MPPE required, but auth done in both directions."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + if (!numbits) { + error("MPPE required, but MS-CHAP[v2] auth not performed."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* A plugin (eg radius) may not have obtained key material. */ + if (!mppe_keys_set) { + error("MPPE required, but keys are not available. " + "Possible plugin problem?"); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* LM auth not supported for MPPE */ + if (auth_done[f->unit] & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { + /* This might be noise */ + if (go->mppe & MPPE_OPT_40) { + notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); + go->mppe &= ~MPPE_OPT_40; + ccp_wantoptions[f->unit].mppe &= ~MPPE_OPT_40; + } + } + + /* Last check: can we actually negotiate something? */ + if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { + /* Could be misconfig, could be 40-bit disabled above. */ + error("MPPE required, but both 40-bit and 128-bit disabled."); + lcp_close(f->unit, "MPPE required but not available"); + return; + } + + /* sync options */ + ao->mppe = go->mppe; + /* MPPE is not compatible with other compression types */ + ao->bsd_compress = go->bsd_compress = 0; + ao->predictor_1 = go->predictor_1 = 0; + ao->predictor_2 = go->predictor_2 = 0; + ao->deflate = go->deflate = 0; + } +#endif /* MPPE */ + + /* + * Check whether the kernel knows about the various + * compression methods we might request. + */ +#ifdef MPPE + if (go->mppe) { + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + /* Key material unimportant here. */ + if (ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0) <= 0) { + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + } + } +#endif + if (go->bsd_compress) { + opt_buf[0] = CI_BSD_COMPRESS; + opt_buf[1] = CILEN_BSD_COMPRESS; + opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, BSD_MIN_BITS); + if (ccp_test(f->unit, opt_buf, CILEN_BSD_COMPRESS, 0) <= 0) + go->bsd_compress = 0; + } + if (go->deflate) { + if (go->deflate_correct) { + opt_buf[0] = CI_DEFLATE; + opt_buf[1] = CILEN_DEFLATE; + opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); + opt_buf[3] = DEFLATE_CHK_SEQUENCE; + if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) + go->deflate_correct = 0; + } + if (go->deflate_draft) { + opt_buf[0] = CI_DEFLATE_DRAFT; + opt_buf[1] = CILEN_DEFLATE; + opt_buf[2] = DEFLATE_MAKE_OPT(DEFLATE_MIN_WORKS); + opt_buf[3] = DEFLATE_CHK_SEQUENCE; + if (ccp_test(f->unit, opt_buf, CILEN_DEFLATE, 0) <= 0) + go->deflate_draft = 0; + } + if (!go->deflate_correct && !go->deflate_draft) + go->deflate = 0; + } + if (go->predictor_1) { + opt_buf[0] = CI_PREDICTOR_1; + opt_buf[1] = CILEN_PREDICTOR_1; + if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) + go->predictor_1 = 0; + } + if (go->predictor_2) { + opt_buf[0] = CI_PREDICTOR_2; + opt_buf[1] = CILEN_PREDICTOR_2; + if (ccp_test(f->unit, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) + go->predictor_2 = 0; + } +} + +/* + * ccp_cilen - Return total length of our configuration info. + */ +static int +ccp_cilen(f) + fsm *f; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + + return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) + + (go->deflate? CILEN_DEFLATE: 0) + + (go->predictor_1? CILEN_PREDICTOR_1: 0) + + (go->predictor_2? CILEN_PREDICTOR_2: 0) + + (go->mppe? CILEN_MPPE: 0); +} + +/* + * ccp_addci - put our requests in a packet. + */ +static void +ccp_addci(f, p, lenp) + fsm *f; + u_char *p; + int *lenp; +{ + int res; + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char *p0 = p; + + /* + * Add the compression types that we can receive, in decreasing + * preference order. Get the kernel to allocate the first one + * in case it gets Acked. + */ +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + + p[0] = opt_buf[0] = CI_MPPE; + p[1] = opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &p[2]); + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + MEMCPY(&opt_buf[CILEN_MPPE], mppe_recv_key, MPPE_MAX_KEY_LEN); + res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0); + if (res > 0) + p += CILEN_MPPE; + else + /* This shouldn't happen, we've already tested it! */ + lcp_close(f->unit, "MPPE required but not available in kernel"); + } +#endif + if (go->deflate) { + p[0] = go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT; + p[1] = CILEN_DEFLATE; + p[2] = DEFLATE_MAKE_OPT(go->deflate_size); + p[3] = DEFLATE_CHK_SEQUENCE; + if (p != p0) { + p += CILEN_DEFLATE; + } else { + for (;;) { + if (go->deflate_size < DEFLATE_MIN_WORKS) { + go->deflate = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_DEFLATE, 0); + if (res > 0) { + p += CILEN_DEFLATE; + break; + } else if (res < 0) { + go->deflate = 0; + break; + } + --go->deflate_size; + p[2] = DEFLATE_MAKE_OPT(go->deflate_size); + } + } + if (p != p0 && go->deflate_correct && go->deflate_draft) { + p[0] = CI_DEFLATE_DRAFT; + p[1] = CILEN_DEFLATE; + p[2] = p[2 - CILEN_DEFLATE]; + p[3] = DEFLATE_CHK_SEQUENCE; + p += CILEN_DEFLATE; + } + } + if (go->bsd_compress) { + p[0] = CI_BSD_COMPRESS; + p[1] = CILEN_BSD_COMPRESS; + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); + if (p != p0) { + p += CILEN_BSD_COMPRESS; /* not the first option */ + } else { + for (;;) { + if (go->bsd_bits < BSD_MIN_BITS) { + go->bsd_compress = 0; + break; + } + res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 0); + if (res > 0) { + p += CILEN_BSD_COMPRESS; + break; + } else if (res < 0) { + go->bsd_compress = 0; + break; + } + --go->bsd_bits; + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); + } + } + } + /* XXX Should Predictor 2 be preferable to Predictor 1? */ + if (go->predictor_1) { + p[0] = CI_PREDICTOR_1; + p[1] = CILEN_PREDICTOR_1; + if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 0) <= 0) { + go->predictor_1 = 0; + } else { + p += CILEN_PREDICTOR_1; + } + } + if (go->predictor_2) { + p[0] = CI_PREDICTOR_2; + p[1] = CILEN_PREDICTOR_2; + if (p == p0 && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 0) <= 0) { + go->predictor_2 = 0; + } else { + p += CILEN_PREDICTOR_2; + } + } + + go->method = (p > p0)? p0[0]: -1; + + *lenp = p - p0; +} + +/* + * ccp_ackci - process a received configure-ack, and return + * 1 iff the packet was OK. + */ +static int +ccp_ackci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + u_char *p0 = p; + +#ifdef MPPE + if (go->mppe) { + u_char opt_buf[CILEN_MPPE]; + + opt_buf[0] = CI_MPPE; + opt_buf[1] = CILEN_MPPE; + MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); + if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) + return 0; + p += CILEN_MPPE; + len -= CILEN_MPPE; + /* XXX Cope with first/fast ack */ + if (len == 0) + return 1; + } +#endif + if (go->deflate) { + if (len < CILEN_DEFLATE + || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) + || p[1] != CILEN_DEFLATE + || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + /* XXX Cope with first/fast ack */ + if (len == 0) + return 1; + if (go->deflate_correct && go->deflate_draft) { + if (len < CILEN_DEFLATE + || p[0] != CI_DEFLATE_DRAFT + || p[1] != CILEN_DEFLATE + || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + } + if (go->bsd_compress) { + if (len < CILEN_BSD_COMPRESS + || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS + || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) + return 0; + p += CILEN_BSD_COMPRESS; + len -= CILEN_BSD_COMPRESS; + /* XXX Cope with first/fast ack */ + if (p == p0 && len == 0) + return 1; + } + if (go->predictor_1) { + if (len < CILEN_PREDICTOR_1 + || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) + return 0; + p += CILEN_PREDICTOR_1; + len -= CILEN_PREDICTOR_1; + /* XXX Cope with first/fast ack */ + if (p == p0 && len == 0) + return 1; + } + if (go->predictor_2) { + if (len < CILEN_PREDICTOR_2 + || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) + return 0; + p += CILEN_PREDICTOR_2; + len -= CILEN_PREDICTOR_2; + /* XXX Cope with first/fast ack */ + if (p == p0 && len == 0) + return 1; + } + + if (len != 0) + return 0; + return 1; +} + +/* + * ccp_nakci - process received configure-nak. + * Returns 1 iff the nak was OK. + */ +static int +ccp_nakci(f, p, len, treat_as_reject) + fsm *f; + u_char *p; + int len; + int treat_as_reject; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + ccp_options no; /* options we've seen already */ + ccp_options try; /* options to ask for next time */ + + memset(&no, 0, sizeof(no)); + try = *go; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + no.mppe = 1; + /* + * Peer wants us to use a different strength or other setting. + * Fail if we aren't willing to use his suggestion. + */ + MPPE_CI_TO_OPTS(&p[2], try.mppe); + if ((try.mppe & MPPE_OPT_STATEFUL) && refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + try.mppe = 0; + } else if (((go->mppe | MPPE_OPT_STATEFUL) & try.mppe) != try.mppe) { + /* Peer must have set options we didn't request (suggest) */ + try.mppe = 0; + } + + if (!try.mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } + } +#endif /* MPPE */ + if (go->deflate && len >= CILEN_DEFLATE + && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) + && p[1] == CILEN_DEFLATE) { + no.deflate = 1; + /* + * Peer wants us to use a different code size or something. + * Stop asking for Deflate if we don't understand his suggestion. + */ + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL + || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS + || p[3] != DEFLATE_CHK_SEQUENCE) + try.deflate = 0; + else if (DEFLATE_SIZE(p[2]) < go->deflate_size) + try.deflate_size = DEFLATE_SIZE(p[2]); + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + if (go->deflate_correct && go->deflate_draft + && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT + && p[1] == CILEN_DEFLATE) { + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + } + + if (go->bsd_compress && len >= CILEN_BSD_COMPRESS + && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { + no.bsd_compress = 1; + /* + * Peer wants us to use a different number of bits + * or a different version. + */ + if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) + try.bsd_compress = 0; + else if (BSD_NBITS(p[2]) < go->bsd_bits) + try.bsd_bits = BSD_NBITS(p[2]); + p += CILEN_BSD_COMPRESS; + len -= CILEN_BSD_COMPRESS; + } + + /* + * Predictor-1 and 2 have no options, so they can't be Naked. + * + * There may be remaining options but we ignore them. + */ + + if (f->state != OPENED) + *go = try; + return 1; +} + +/* + * ccp_rejci - reject some of our suggested compression methods. + */ +static int +ccp_rejci(f, p, len) + fsm *f; + u_char *p; + int len; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + ccp_options try; /* options to request next time */ + + try = *go; + + /* + * Cope with empty configure-rejects by ceasing to send + * configure-requests. + */ + if (len == 0 && all_rejected[f->unit]) + return -1; + +#ifdef MPPE + if (go->mppe && len >= CILEN_MPPE + && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { + error("MPPE required but peer refused"); + lcp_close(f->unit, "MPPE required but peer refused"); + p += CILEN_MPPE; + len -= CILEN_MPPE; + } +#endif + if (go->deflate_correct && len >= CILEN_DEFLATE + && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { + if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; /* Rej is bad */ + try.deflate_correct = 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + if (go->deflate_draft && len >= CILEN_DEFLATE + && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { + if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) + || p[3] != DEFLATE_CHK_SEQUENCE) + return 0; /* Rej is bad */ + try.deflate_draft = 0; + p += CILEN_DEFLATE; + len -= CILEN_DEFLATE; + } + if (!try.deflate_correct && !try.deflate_draft) + try.deflate = 0; + if (go->bsd_compress && len >= CILEN_BSD_COMPRESS + && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { + if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) + return 0; + try.bsd_compress = 0; + p += CILEN_BSD_COMPRESS; + len -= CILEN_BSD_COMPRESS; + } + if (go->predictor_1 && len >= CILEN_PREDICTOR_1 + && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { + try.predictor_1 = 0; + p += CILEN_PREDICTOR_1; + len -= CILEN_PREDICTOR_1; + } + if (go->predictor_2 && len >= CILEN_PREDICTOR_2 + && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { + try.predictor_2 = 0; + p += CILEN_PREDICTOR_2; + len -= CILEN_PREDICTOR_2; + } + + if (len != 0) + return 0; + + if (f->state != OPENED) + *go = try; + + return 1; +} + +/* + * ccp_reqci - processed a received configure-request. + * Returns CONFACK, CONFNAK or CONFREJ and the packet modified + * appropriately. + */ +static int +ccp_reqci(f, p, lenp, dont_nak) + fsm *f; + u_char *p; + int *lenp; + int dont_nak; +{ + ppp_pcb *pcb = &ppp_pcb_list[f->unit]; + int ret, newret, res; + u_char *p0, *retp; + int len, clen, type, nb; + ccp_options *ho = &ccp_hisoptions[f->unit]; + ccp_options *ao = &ccp_allowoptions[f->unit]; +#ifdef MPPE + bool rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ + /* CI_MPPE, or due to other options? */ +#endif + + ret = CONFACK; + retp = p0 = p; + len = *lenp; + + memset(ho, 0, sizeof(ccp_options)); + ho->method = (len > 0)? p[0]: -1; + + while (len > 0) { + newret = CONFACK; + if (len < 2 || p[1] < 2 || p[1] > len) { + /* length is bad */ + clen = len; + newret = CONFREJ; + + } else { + type = p[0]; + clen = p[1]; + + switch (type) { +#ifdef MPPE + case CI_MPPE: + if (!ao->mppe || clen != CILEN_MPPE) { + newret = CONFREJ; + break; + } + MPPE_CI_TO_OPTS(&p[2], ho->mppe); + + /* Nak if anything unsupported or unknown are set. */ + if (ho->mppe & MPPE_OPT_UNSUPPORTED) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNSUPPORTED; + } + if (ho->mppe & MPPE_OPT_UNKNOWN) { + newret = CONFNAK; + ho->mppe &= ~MPPE_OPT_UNKNOWN; + } + + /* Check state opt */ + if (ho->mppe & MPPE_OPT_STATEFUL) { + /* + * We can Nak and request stateless, but it's a + * lot easier to just assume the peer will request + * it if he can do it; stateful mode is bad over + * the Internet -- which is where we expect MPPE. + */ + if (refuse_mppe_stateful) { + error("Refusing MPPE stateful mode offered by peer"); + newret = CONFREJ; + break; + } + } + + /* Find out which of {S,L} are set. */ + if ((ho->mppe & MPPE_OPT_128) + && (ho->mppe & MPPE_OPT_40)) { + /* Both are set, negotiate the strongest. */ + newret = CONFNAK; + if (ao->mppe & MPPE_OPT_128) + ho->mppe &= ~MPPE_OPT_40; + else if (ao->mppe & MPPE_OPT_40) + ho->mppe &= ~MPPE_OPT_128; + else { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_128) { + if (!(ao->mppe & MPPE_OPT_128)) { + newret = CONFREJ; + break; + } + } else if (ho->mppe & MPPE_OPT_40) { + if (!(ao->mppe & MPPE_OPT_40)) { + newret = CONFREJ; + break; + } + } else { + /* Neither are set. */ + /* We cannot accept this. */ + newret = CONFNAK; + /* Give the peer our idea of what can be used, + so it can choose and confirm */ + ho->mppe = ao->mppe; + } + + /* rebuild the opts */ + MPPE_OPTS_TO_CI(ho->mppe, &p[2]); + if (newret == CONFACK) { + u_char opt_buf[CILEN_MPPE + MPPE_MAX_KEY_LEN]; + int mtu; + + MEMCPY(opt_buf, p, CILEN_MPPE); + MEMCPY(&opt_buf[CILEN_MPPE], mppe_send_key, + MPPE_MAX_KEY_LEN); + if (ccp_test(f->unit, opt_buf, + CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) { + /* This shouldn't happen, we've already tested it! */ + error("MPPE required, but kernel has no support."); + lcp_close(f->unit, "MPPE required but not available"); + newret = CONFREJ; + break; + } + /* + * We need to decrease the interface MTU by MPPE_PAD + * because MPPE frames **grow**. The kernel [must] + * allocate MPPE_PAD extra bytes in xmit buffers. + */ + mtu = netif_get_mtu(pcb); + if (mtu) + netif_set_mtu(pcb, mtu - MPPE_PAD); + else + newret = CONFREJ; + } + + /* + * We have accepted MPPE or are willing to negotiate + * MPPE parameters. A CONFREJ is due to subsequent + * (non-MPPE) processing. + */ + rej_for_ci_mppe = 0; + break; +#endif /* MPPE */ + case CI_DEFLATE: + case CI_DEFLATE_DRAFT: + if (!ao->deflate || clen != CILEN_DEFLATE + || (!ao->deflate_correct && type == CI_DEFLATE) + || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { + newret = CONFREJ; + break; + } + + ho->deflate = 1; + ho->deflate_size = nb = DEFLATE_SIZE(p[2]); + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL + || p[3] != DEFLATE_CHK_SEQUENCE + || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { + newret = CONFNAK; + if (!dont_nak) { + p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); + p[3] = DEFLATE_CHK_SEQUENCE; + /* fall through to test this #bits below */ + } else + break; + } + + /* + * Check whether we can do Deflate with the window + * size they want. If the window is too big, reduce + * it until the kernel can cope and nak with that. + * We only check this for the first option. + */ + if (p == p0) { + for (;;) { + res = ccp_test(f->unit, p, CILEN_DEFLATE, 1); + if (res > 0) + break; /* it's OK now */ + if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { + newret = CONFREJ; + p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); + break; + } + newret = CONFNAK; + --nb; + p[2] = DEFLATE_MAKE_OPT(nb); + } + } + break; + + case CI_BSD_COMPRESS: + if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { + newret = CONFREJ; + break; + } + + ho->bsd_compress = 1; + ho->bsd_bits = nb = BSD_NBITS(p[2]); + if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION + || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { + newret = CONFNAK; + if (!dont_nak) { + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); + /* fall through to test this #bits below */ + } else + break; + } + + /* + * Check whether we can do BSD-Compress with the code + * size they want. If the code size is too big, reduce + * it until the kernel can cope and nak with that. + * We only check this for the first option. + */ + if (p == p0) { + for (;;) { + res = ccp_test(f->unit, p, CILEN_BSD_COMPRESS, 1); + if (res > 0) + break; + if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { + newret = CONFREJ; + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, + ho->bsd_bits); + break; + } + newret = CONFNAK; + --nb; + p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); + } + } + break; + + case CI_PREDICTOR_1: + if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { + newret = CONFREJ; + break; + } + + ho->predictor_1 = 1; + if (p == p0 + && ccp_test(f->unit, p, CILEN_PREDICTOR_1, 1) <= 0) { + newret = CONFREJ; + } + break; + + case CI_PREDICTOR_2: + if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { + newret = CONFREJ; + break; + } + + ho->predictor_2 = 1; + if (p == p0 + && ccp_test(f->unit, p, CILEN_PREDICTOR_2, 1) <= 0) { + newret = CONFREJ; + } + break; + + default: + newret = CONFREJ; + } + } + + if (newret == CONFNAK && dont_nak) + newret = CONFREJ; + if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { + /* we're returning this option */ + if (newret == CONFREJ && ret == CONFNAK) + retp = p0; + ret = newret; + if (p != retp) + MEMCPY(retp, p, clen); + retp += clen; + } + + p += clen; + len -= clen; + } + + if (ret != CONFACK) { + if (ret == CONFREJ && *lenp == retp - p0) + all_rejected[f->unit] = 1; + else + *lenp = retp - p0; + } +#ifdef MPPE + if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { + error("MPPE required but peer negotiation failed"); + lcp_close(f->unit, "MPPE required but peer negotiation failed"); + } +#endif + return ret; +} + +/* + * Make a string name for a compression method (or 2). + */ +static char * +method_name(opt, opt2) + ccp_options *opt, *opt2; +{ + static char result[64]; + + if (!ANY_COMPRESS(*opt)) + return "(none)"; + switch (opt->method) { +#ifdef MPPE + case CI_MPPE: + { + char *p = result; + char *q = result + sizeof(result); /* 1 past result */ + + slprintf(p, q - p, "MPPE "); + p += 5; + if (opt->mppe & MPPE_OPT_128) { + slprintf(p, q - p, "128-bit "); + p += 8; + } + if (opt->mppe & MPPE_OPT_40) { + slprintf(p, q - p, "40-bit "); + p += 7; + } + if (opt->mppe & MPPE_OPT_STATEFUL) + slprintf(p, q - p, "stateful"); + else + slprintf(p, q - p, "stateless"); + + break; + } +#endif + case CI_DEFLATE: + case CI_DEFLATE_DRAFT: + if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) + slprintf(result, sizeof(result), "Deflate%s (%d/%d)", + (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), + opt->deflate_size, opt2->deflate_size); + else + slprintf(result, sizeof(result), "Deflate%s (%d)", + (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), + opt->deflate_size); + break; + case CI_BSD_COMPRESS: + if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) + slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", + opt->bsd_bits, opt2->bsd_bits); + else + slprintf(result, sizeof(result), "BSD-Compress (%d)", + opt->bsd_bits); + break; + case CI_PREDICTOR_1: + return "Predictor 1"; + case CI_PREDICTOR_2: + return "Predictor 2"; + default: + slprintf(result, sizeof(result), "Method %d", opt->method); + } + return result; +} + +/* + * CCP has come up - inform the kernel driver and log a message. + */ +static void +ccp_up(f) + fsm *f; +{ + ccp_options *go = &ccp_gotoptions[f->unit]; + ccp_options *ho = &ccp_hisoptions[f->unit]; + char method1[64]; + + ccp_flags_set(f->unit, 1, 1); + if (ANY_COMPRESS(*go)) { + if (ANY_COMPRESS(*ho)) { + if (go->method == ho->method) { + notice("%s compression enabled", method_name(go, ho)); + } else { + strlcpy(method1, method_name(go, NULL), sizeof(method1)); + notice("%s / %s compression enabled", + method1, method_name(ho, NULL)); + } + } else + notice("%s receive compression enabled", method_name(go, NULL)); + } else if (ANY_COMPRESS(*ho)) + notice("%s transmit compression enabled", method_name(ho, NULL)); +#ifdef MPPE + if (go->mppe) { + BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN); + BZERO(mppe_send_key, MPPE_MAX_KEY_LEN); + continue_networks(f->unit); /* Bring up IP et al */ + } +#endif +} + +/* + * CCP has gone down - inform the kernel driver. + */ +static void +ccp_down(f) + fsm *f; +{ + if (ccp_localstate[f->unit] & RACK_PENDING) + UNTIMEOUT(ccp_rack_timeout, f); + ccp_localstate[f->unit] = 0; + ccp_flags_set(f->unit, 1, 0); +#ifdef MPPE + if (ccp_gotoptions[f->unit].mppe) { + ccp_gotoptions[f->unit].mppe = 0; + if (lcp_fsm[f->unit].state == OPENED) { + /* If LCP is not already going down, make sure it does. */ + error("MPPE disabled"); + lcp_close(f->unit, "MPPE disabled"); + } + } +#endif +} + +#if PRINTPKT_SUPPORT +/* + * Print the contents of a CCP packet. + */ +static char *ccp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej", + NULL, NULL, NULL, NULL, NULL, NULL, + "ResetReq", "ResetAck", +}; + +static int +ccp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) (void *, char *, ...); + void *arg; +{ + u_char *p0, *optend; + int code, id, len; + int optlen; + + p0 = p; + if (plen < HEADERLEN) + return 0; + code = p[0]; + id = p[1]; + len = (p[2] << 8) + p[3]; + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= sizeof(ccp_codenames) / sizeof(char *) + && ccp_codenames[code-1] != NULL) + printer(arg, " %s", ccp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + p += HEADERLEN; + + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print list of possible compression methods */ + while (len >= 2) { + code = p[0]; + optlen = p[1]; + if (optlen < 2 || optlen > len) + break; + printer(arg, " <"); + len -= optlen; + optend = p + optlen; + switch (code) { +#ifdef MPPE + case CI_MPPE: + if (optlen >= CILEN_MPPE) { + u_char mppe_opts; + + MPPE_CI_TO_OPTS(&p[2], mppe_opts); + printer(arg, "mppe %s %s %s %s %s %s%s", + (p[2] & MPPE_H_BIT)? "+H": "-H", + (p[5] & MPPE_M_BIT)? "+M": "-M", + (p[5] & MPPE_S_BIT)? "+S": "-S", + (p[5] & MPPE_L_BIT)? "+L": "-L", + (p[5] & MPPE_D_BIT)? "+D": "-D", + (p[5] & MPPE_C_BIT)? "+C": "-C", + (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); + if (mppe_opts & MPPE_OPT_UNKNOWN) + printer(arg, " (%.2x %.2x %.2x %.2x)", + p[2], p[3], p[4], p[5]); + p += CILEN_MPPE; + } + break; +#endif + case CI_DEFLATE: + case CI_DEFLATE_DRAFT: + if (optlen >= CILEN_DEFLATE) { + printer(arg, "deflate%s %d", + (code == CI_DEFLATE_DRAFT? "(old#)": ""), + DEFLATE_SIZE(p[2])); + if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) + printer(arg, " method %d", DEFLATE_METHOD(p[2])); + if (p[3] != DEFLATE_CHK_SEQUENCE) + printer(arg, " check %d", p[3]); + p += CILEN_DEFLATE; + } + break; + case CI_BSD_COMPRESS: + if (optlen >= CILEN_BSD_COMPRESS) { + printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), + BSD_NBITS(p[2])); + p += CILEN_BSD_COMPRESS; + } + break; + case CI_PREDICTOR_1: + if (optlen >= CILEN_PREDICTOR_1) { + printer(arg, "predictor 1"); + p += CILEN_PREDICTOR_1; + } + break; + case CI_PREDICTOR_2: + if (optlen >= CILEN_PREDICTOR_2) { + printer(arg, "predictor 2"); + p += CILEN_PREDICTOR_2; + } + break; + } + while (p < optend) + printer(arg, " %.2x", *p++); + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + } + + /* dump out the rest of the packet in hex */ + while (--len >= 0) + printer(arg, " %.2x", *p++); + + return p - p0; +} +#endif /* PRINTPKT_SUPPORT */ + +/* + * We have received a packet that the decompressor failed to + * decompress. Here we would expect to issue a reset-request, but + * Motorola has a patent on resetting the compressor as a result of + * detecting an error in the decompressed data after decompression. + * (See US patent 5,130,993; international patent publication number + * WO 91/10289; Australian patent 73296/91.) + * + * So we ask the kernel whether the error was detected after + * decompression; if it was, we take CCP down, thus disabling + * compression :-(, otherwise we issue the reset-request. + */ +static void +ccp_datainput(unit, pkt, len) + int unit; + u_char *pkt; + int len; +{ + fsm *f; + + f = &ccp_fsm[unit]; + if (f->state == OPENED) { + if (ccp_fatal_error(unit)) { + /* + * Disable compression by taking CCP down. + */ + error("Lost compression sync: disabling compression"); + ccp_close(unit, "Lost compression sync"); +#ifdef MPPE + /* + * If we were doing MPPE, we must also take the link down. + */ + if (ccp_gotoptions[unit].mppe) { + error("Too many MPPE errors, closing LCP"); + lcp_close(unit, "Too many MPPE errors"); + } +#endif + } else { + /* + * Send a reset-request to reset the peer's compressor. + * We don't do that if we are still waiting for an + * acknowledgement to a previous reset-request. + */ + if (!(ccp_localstate[f->unit] & RACK_PENDING)) { + fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); + TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); + ccp_localstate[f->unit] |= RACK_PENDING; + } else + ccp_localstate[f->unit] |= RREQ_REPEAT; + } + } +} + +/* + * Timeout waiting for reset-ack. + */ +static void +ccp_rack_timeout(arg) + void *arg; +{ + fsm *f = arg; + + if (f->state == OPENED && ccp_localstate[f->unit] & RREQ_REPEAT) { + fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); + TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); + ccp_localstate[f->unit] &= ~RREQ_REPEAT; + } else + ccp_localstate[f->unit] &= ~RACK_PENDING; +} + +#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-md5.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-md5.c new file mode 100644 index 0000000..70b879a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-md5.c @@ -0,0 +1,124 @@ +/* + * chap-md5.c - New CHAP/MD5 implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap-md5.h" +#include "netif/ppp/magic.h" + +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "netif/ppp/polarssl/md5.h" +#else +#include "polarssl/md5.h" +#endif + +#define MD5_HASH_SIZE 16 +#define MD5_MIN_CHALLENGE 16 +#define MD5_MAX_CHALLENGE 24 + +#if PPP_SERVER +static void chap_md5_generate_challenge(unsigned char *cp) { + int clen; + + clen = (int)(drand48() * (MD5_MAX_CHALLENGE - MD5_MIN_CHALLENGE)) + + MD5_MIN_CHALLENGE; + *cp++ = clen; + random_bytes(cp, clen); +} + +static int chap_md5_verify_response(int id, const char *name, + const unsigned char *secret, int secret_len, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space) { + md5_context ctx; + unsigned char idbyte = id; + unsigned char hash[MD5_HASH_SIZE]; + int challenge_len, response_len; + LWIP_UNUSED_ARG(name); + + challenge_len = *challenge++; + response_len = *response++; + if (response_len == MD5_HASH_SIZE) { + /* Generate hash of ID, secret, challenge */ + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, (unsigned char*)secret, secret_len); + md5_update(&ctx, (unsigned char*)challenge, challenge_len); + md5_finish(&ctx, hash); + + /* Test if our hash matches the peer's response */ + if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { + ppp_slprintf(message, message_space, "Access granted"); + return 1; + } + } + ppp_slprintf(message, message_space, "Access denied"); + return 0; +} +#endif /* PPP_SERVER */ + +static void chap_md5_make_response(unsigned char *response, int id, const char *our_name, + const unsigned char *challenge, const char *secret, int secret_len, + const unsigned char *private_) { + md5_context ctx; + unsigned char idbyte = id; + int challenge_len = *challenge++; + LWIP_UNUSED_ARG(our_name); + LWIP_UNUSED_ARG(private_); + + md5_starts(&ctx); + md5_update(&ctx, &idbyte, 1); + md5_update(&ctx, (u_char *)secret, secret_len); + md5_update(&ctx, (unsigned char *)challenge, challenge_len); + md5_finish(&ctx, &response[1]); + response[0] = MD5_HASH_SIZE; +} + +const struct chap_digest_type md5_digest = { + CHAP_MD5, /* code */ +#if PPP_SERVER + chap_md5_generate_challenge, + chap_md5_verify_response, +#endif /* PPP_SERVER */ + chap_md5_make_response, + NULL, /* check_success */ + NULL, /* handle_failure */ +}; + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-new.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-new.c new file mode 100644 index 0000000..8432dac --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap-new.c @@ -0,0 +1,670 @@ +/* + * chap-new.c - New CHAP implementation. + * + * Copyright (c) 2003 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#if 0 /* UNUSED */ +#include "session.h" +#endif /* UNUSED */ + +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap-md5.h" +#if MSCHAP_SUPPORT +#include "netif/ppp/chap_ms.h" +#endif + +/* Hook for a plugin to validate CHAP challenge */ +int (*chap_verify_hook)(const char *name, const char *ourname, int id, + const struct chap_digest_type *digest, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space) = NULL; + +#if PPP_OPTIONS +/* + * Command-line options. + */ +static option_t chap_option_list[] = { + { "chap-restart", o_int, &chap_timeout_time, + "Set timeout for CHAP", OPT_PRIO }, + { "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits, + "Set max #xmits for challenge", OPT_PRIO }, + { "chap-interval", o_int, &pcb->settings.chap_rechallenge_time, + "Set interval for rechallenge", OPT_PRIO }, + { NULL } +}; +#endif /* PPP_OPTIONS */ + + +/* Values for flags in chap_client_state and chap_server_state */ +#define LOWERUP 1 +#define AUTH_STARTED 2 +#define AUTH_DONE 4 +#define AUTH_FAILED 8 +#define TIMEOUT_PENDING 0x10 +#define CHALLENGE_VALID 0x20 + +/* + * Prototypes. + */ +static void chap_init(ppp_pcb *pcb); +static void chap_lowerup(ppp_pcb *pcb); +static void chap_lowerdown(ppp_pcb *pcb); +#if PPP_SERVER +static void chap_timeout(void *arg); +static void chap_generate_challenge(ppp_pcb *pcb); +static void chap_handle_response(ppp_pcb *pcb, int code, + unsigned char *pkt, int len); +static int chap_verify_response(const char *name, const char *ourname, int id, + const struct chap_digest_type *digest, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space); +#endif /* PPP_SERVER */ +static void chap_respond(ppp_pcb *pcb, int id, + unsigned char *pkt, int len); +static void chap_handle_status(ppp_pcb *pcb, int code, int id, + unsigned char *pkt, int len); +static void chap_protrej(ppp_pcb *pcb); +static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen); +#if PRINTPKT_SUPPORT +static int chap_print_pkt(unsigned char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ + +/* List of digest types that we know about */ +static const struct chap_digest_type* const chap_digests[] = { + &md5_digest, +#if MSCHAP_SUPPORT + &chapms_digest, + &chapms2_digest, +#endif /* MSCHAP_SUPPORT */ + NULL +}; + +/* + * chap_init - reset to initial state. + */ +static void chap_init(ppp_pcb *pcb) { + + memset(&pcb->chap_client, 0, sizeof(chap_client_state)); +#if PPP_SERVER + memset(&pcb->chap_server, 0, sizeof(chap_server_state)); +#endif /* PPP_SERVER */ +} + +/* + * chap_lowerup - we can start doing stuff now. + */ +static void chap_lowerup(ppp_pcb *pcb) { + + pcb->chap_client.flags |= LOWERUP; +#if PPP_SERVER + pcb->chap_server.flags |= LOWERUP; + if (pcb->chap_server.flags & AUTH_STARTED) + chap_timeout(pcb); +#endif /* PPP_SERVER */ +} + +static void chap_lowerdown(ppp_pcb *pcb) { + + pcb->chap_client.flags = 0; +#if PPP_SERVER + if (pcb->chap_server.flags & TIMEOUT_PENDING) + UNTIMEOUT(chap_timeout, pcb); + pcb->chap_server.flags = 0; +#endif /* PPP_SERVER */ +} + +#if PPP_SERVER +/* + * chap_auth_peer - Start authenticating the peer. + * If the lower layer is already up, we start sending challenges, + * otherwise we wait for the lower layer to come up. + */ +void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { + struct chap_server_state *ss = &pcb->chap_server; + const struct chap_digest_type *dp; + int i; + + if (pcb->chap_server.flags & AUTH_STARTED) { + ppp_error("CHAP: peer authentication already started!"); + return; + } + for (i = 0; (dp = chap_digests[i]) != NULL; ++i) + if (dp->code == digest_code) + break; + if (dp == NULL) + ppp_fatal("CHAP digest 0x%x requested but not available", + digest_code); + + pcb->chap_server.digest = dp; + pcb->chap_server.name = our_name; + /* Start with a random ID value */ + pcb->chap_server.id = (unsigned char)(drand48() * 256); + pcb->chap_server.flags |= AUTH_STARTED; + if (pcb->chap_server.flags & LOWERUP) + chap_timeout(ss); +} +#endif /* PPP_SERVER */ + +/* + * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. + * There isn't much to do until we receive a challenge. + */ +void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { + const struct chap_digest_type *dp; + int i; + + if(NULL == our_name) + return; + + if (pcb->chap_client.flags & AUTH_STARTED) { + ppp_error("CHAP: authentication with peer already started!"); + return; + } + for (i = 0; (dp = chap_digests[i]) != NULL; ++i) + if (dp->code == digest_code) + break; + + if (dp == NULL) + ppp_fatal("CHAP digest 0x%x requested but not available", + digest_code); + + pcb->chap_client.digest = dp; + pcb->chap_client.name = our_name; + pcb->chap_client.flags |= AUTH_STARTED; +} + +#if PPP_SERVER +/* + * chap_timeout - It's time to send another challenge to the peer. + * This could be either a retransmission of a previous challenge, + * or a new challenge to start re-authentication. + */ +static void chap_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + struct pbuf *p; + + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { + pcb->chap_server.challenge_xmits = 0; + chap_generate_challenge(pcb); + pcb->chap_server.flags |= CHALLENGE_VALID; + } else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) { + pcb->chap_server.flags &= ~CHALLENGE_VALID; + pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; + auth_peer_fail(pcb, PPP_CHAP); + return; + } + + p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); + ppp_write(pcb, p); + ++pcb->chap_server.challenge_xmits; + pcb->chap_server.flags |= TIMEOUT_PENDING; + TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); +} + +/* + * chap_generate_challenge - generate a challenge string and format + * the challenge packet in pcb->chap_server.challenge_pkt. + */ +static void chap_generate_challenge(ppp_pcb *pcb) { + int clen = 1, nlen, len; + unsigned char *p; + + p = pcb->chap_server.challenge; + MAKEHEADER(p, PPP_CHAP); + p += CHAP_HDRLEN; + pcb->chap_server.digest->generate_challenge(p); + clen = *p; + nlen = strlen(pcb->chap_server.name); + memcpy(p + 1 + clen, pcb->chap_server.name, nlen); + + len = CHAP_HDRLEN + 1 + clen + nlen; + pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len; + + p = pcb->chap_server.challenge + PPP_HDRLEN; + p[0] = CHAP_CHALLENGE; + p[1] = ++pcb->chap_server.id; + p[2] = len >> 8; + p[3] = len; +} + +/* + * chap_handle_response - check the response to our challenge. + */ +static void chap_handle_response(ppp_pcb *pcb, int id, + unsigned char *pkt, int len) { + int response_len, ok, mlen; + const unsigned char *response; + unsigned char *outp; + struct pbuf *p; + const char *name = NULL; /* initialized to shut gcc up */ + int (*verifier)(const char *, const char *, int, const struct chap_digest_type *, + const unsigned char *, const unsigned char *, char *, int); + char rname[MAXNAMELEN+1]; + + if ((pcb->chap_server.flags & LOWERUP) == 0) + return; + if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2) + return; + if (pcb->chap_server.flags & CHALLENGE_VALID) { + response = pkt; + GETCHAR(response_len, pkt); + len -= response_len + 1; /* length of name */ + name = (char *)pkt + response_len; + if (len < 0) + return; + + if (pcb->chap_server.flags & TIMEOUT_PENDING) { + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, pcb); + } +#if PPP_REMOTENAME + if (pcb->settings.explicit_remote) { + name = pcb->remote_name; + } else +#endif /* PPP_REMOTENAME */ + { + /* Null terminate and clean remote name. */ + ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); + name = rname; + } + + if (chap_verify_hook) + verifier = chap_verify_hook; + else + verifier = chap_verify_response; + ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest, + pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, + response, pcb->chap_server.message, sizeof(pcb->chap_server.message)); +#if 0 /* UNUSED */ + if (!ok || !auth_number()) { +#endif /* UNUSED */ + if (!ok) { + pcb->chap_server.flags |= AUTH_FAILED; + ppp_warn("Peer %q failed CHAP authentication", name); + } + } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) + return; + + /* send the response */ + mlen = strlen(pcb->chap_server.message); + len = CHAP_HDRLEN + mlen; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (unsigned char *)p->payload; + MAKEHEADER(outp, PPP_CHAP); + + outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; + outp[1] = id; + outp[2] = len >> 8; + outp[3] = len; + if (mlen > 0) + memcpy(outp + CHAP_HDRLEN, pcb->chap_server.message, mlen); + ppp_write(pcb, p); + + if (pcb->chap_server.flags & CHALLENGE_VALID) { + pcb->chap_server.flags &= ~CHALLENGE_VALID; + if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) { + +#if 0 /* UNUSED */ + /* + * Auth is OK, so now we need to check session restrictions + * to ensure everything is OK, but only if we used a + * plugin, and only if we're configured to check. This + * allows us to do PAM checks on PPP servers that + * authenticate against ActiveDirectory, and use AD for + * account info (like when using Winbind integrated with + * PAM). + */ + if (session_mgmt && + session_check(name, NULL, devnam, NULL) == 0) { + pcb->chap_server.flags |= AUTH_FAILED; + ppp_warn("Peer %q failed CHAP Session verification", name); + } +#endif /* UNUSED */ + + } + if (pcb->chap_server.flags & AUTH_FAILED) { + auth_peer_fail(pcb, PPP_CHAP); + } else { + if ((pcb->chap_server.flags & AUTH_DONE) == 0) + auth_peer_success(pcb, PPP_CHAP, + pcb->chap_server.digest->code, + name, strlen(name)); + if (pcb->settings.chap_rechallenge_time) { + pcb->chap_server.flags |= TIMEOUT_PENDING; + TIMEOUT(chap_timeout, pcb, + pcb->settings.chap_rechallenge_time); + } + } + pcb->chap_server.flags |= AUTH_DONE; + } +} + +/* + * chap_verify_response - check whether the peer's response matches + * what we think it should be. Returns 1 if it does (authentication + * succeeded), or 0 if it doesn't. + */ +static int chap_verify_response(const char *name, const char *ourname, int id, + const struct chap_digest_type *digest, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space) { + int ok; + unsigned char secret[MAXSECRETLEN]; + int secret_len; + +/* FIXME: we need a way to check peer secret */ +#if 0 + /* Get the secret that the peer is supposed to know */ + if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { + ppp_error("No CHAP secret found for authenticating %q", name); + return 0; + } +#else + /* only here to clean compiler warnings */ + LWIP_UNUSED_ARG(ourname); + secret_len = 0; +#endif /* 0 */ + ok = digest->verify_response(id, name, secret, secret_len, challenge, + response, message, message_space); + memset(secret, 0, sizeof(secret)); + + return ok; +} +#endif /* PPP_SERVER */ + +/* + * chap_respond - Generate and send a response to a challenge. + */ +static void chap_respond(ppp_pcb *pcb, int id, + unsigned char *pkt, int len) { + int clen, nlen; + int secret_len; + struct pbuf *p; + u_char *outp; + char rname[MAXNAMELEN+1]; + char secret[MAXSECRETLEN+1]; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) + return; /* not ready */ + if (len < 2 || len < pkt[0] + 1) + return; /* too short */ + clen = pkt[0]; + nlen = len - (clen + 1); + + /* Null terminate and clean remote name. */ + ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); + +#if PPP_REMOTENAME + /* Microsoft doesn't send their name back in the PPP packet */ + if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) + strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); +#endif /* PPP_REMOTENAME */ + + /* get secret for authenticating ourselves with the specified host */ + if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { + secret_len = 0; /* assume null secret if can't find one */ + ppp_warn("No CHAP secret found for authenticating us to %q", rname); + } + + outp = (u_char*)p->payload; + MAKEHEADER(outp, PPP_CHAP); + outp += CHAP_HDRLEN; + + pcb->chap_client.digest->make_response(outp, id, pcb->chap_client.name, pkt, + secret, secret_len, pcb->chap_client.priv); + memset(secret, 0, secret_len); + + clen = *outp; + nlen = strlen(pcb->chap_client.name); + memcpy(outp + clen + 1, pcb->chap_client.name, nlen); + + outp = (u_char*)p->payload + PPP_HDRLEN; + len = CHAP_HDRLEN + clen + 1 + nlen; + outp[0] = CHAP_RESPONSE; + outp[1] = id; + outp[2] = len >> 8; + outp[3] = len; + + pbuf_realloc(p, PPP_HDRLEN + len); + ppp_write(pcb, p); +} + +static void chap_handle_status(ppp_pcb *pcb, int code, int id, + unsigned char *pkt, int len) { + const char *msg = NULL; + LWIP_UNUSED_ARG(id); + + if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) + != (AUTH_STARTED|LOWERUP)) + return; + pcb->chap_client.flags |= AUTH_DONE; + + if (code == CHAP_SUCCESS) { + /* used for MS-CHAP v2 mutual auth, yuck */ + if (pcb->chap_client.digest->check_success != NULL) { + if (!(*pcb->chap_client.digest->check_success)(pkt, len, pcb->chap_client.priv)) + code = CHAP_FAILURE; + } else + msg = "CHAP authentication succeeded"; + } else { + if (pcb->chap_client.digest->handle_failure != NULL) + (*pcb->chap_client.digest->handle_failure)(pkt, len); + else + msg = "CHAP authentication failed"; + } + if (msg) { + if (len > 0) + ppp_info("%s: %.*v", msg, len, pkt); + else + ppp_info("%s", msg); + } + if (code == CHAP_SUCCESS) + auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); + else { + pcb->chap_client.flags |= AUTH_FAILED; + ppp_error("CHAP authentication failed"); + auth_withpeer_fail(pcb, PPP_CHAP); + } +} + +static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) { + unsigned char code, id; + int len; + + if (pktlen < CHAP_HDRLEN) + return; + GETCHAR(code, pkt); + GETCHAR(id, pkt); + GETSHORT(len, pkt); + if (len < CHAP_HDRLEN || len > pktlen) + return; + len -= CHAP_HDRLEN; + + switch (code) { + case CHAP_CHALLENGE: + chap_respond(pcb, id, pkt, len); + break; +#if PPP_SERVER + case CHAP_RESPONSE: + chap_handle_response(pcb, id, pkt, len); + break; +#endif /* PPP_SERVER */ + case CHAP_FAILURE: + case CHAP_SUCCESS: + chap_handle_status(pcb, code, id, pkt, len); + break; + default: + break; + } +} + +static void chap_protrej(ppp_pcb *pcb) { + +#if PPP_SERVER + if (pcb->chap_server.flags & TIMEOUT_PENDING) { + pcb->chap_server.flags &= ~TIMEOUT_PENDING; + UNTIMEOUT(chap_timeout, pcb); + } + if (pcb->chap_server.flags & AUTH_STARTED) { + pcb->chap_server.flags = 0; + auth_peer_fail(pcb, PPP_CHAP); + } +#endif /* PPP_SERVER */ + if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { + pcb->chap_client.flags &= ~AUTH_STARTED; + ppp_error("CHAP authentication failed due to protocol-reject"); + auth_withpeer_fail(pcb, PPP_CHAP); + } +} + +#if PRINTPKT_SUPPORT +/* + * chap_print_pkt - print the contents of a CHAP packet. + */ +static const char *chap_code_names[] = { + "Challenge", "Response", "Success", "Failure" +}; + +static int chap_print_pkt(unsigned char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg) { + int code, id, len; + int clen, nlen; + unsigned char x; + + if (plen < CHAP_HDRLEN) + return 0; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < CHAP_HDRLEN || len > plen) + return 0; + + if (code >= 1 && code <= (int)sizeof(chap_code_names) / (int)sizeof(char *)) + printer(arg, " %s", chap_code_names[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= CHAP_HDRLEN; + switch (code) { + case CHAP_CHALLENGE: + case CHAP_RESPONSE: + if (len < 1) + break; + clen = p[0]; + if (len < clen + 1) + break; + ++p; + nlen = len - clen - 1; + printer(arg, " <"); + for (; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, "%.2x", x); + } + printer(arg, ">, name = "); + ppp_print_string((char *)p, nlen, printer, arg); + break; + case CHAP_FAILURE: + case CHAP_SUCCESS: + printer(arg, " "); + ppp_print_string((char *)p, len, printer, arg); + break; + default: + for (clen = len; clen > 0; --clen) { + GETCHAR(x, p); + printer(arg, " %.2x", x); + } + /* no break */ + } + + return len + CHAP_HDRLEN; +} +#endif /* PRINTPKT_SUPPORT */ + +const struct protent chap_protent = { + PPP_CHAP, + chap_init, + chap_input, + chap_protrej, + chap_lowerup, + chap_lowerdown, + NULL, /* open */ + NULL, /* close */ +#if PRINTPKT_SUPPORT + chap_print_pkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, /* datainput */ + 1, /* enabled_flag */ +#if PRINTPKT_SUPPORT + "CHAP", /* name */ + NULL, /* data_name */ +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + chap_option_list, + NULL, /* check_options */ +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, + NULL +#endif /* DEMAND_SUPPORT */ +}; + +#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap_ms.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap_ms.c new file mode 100644 index 0000000..e0b67d4 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/chap_ms.c @@ -0,0 +1,913 @@ +/* + * chap_ms.c - Microsoft MS-CHAP compatible implementation. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 + * + * Implemented LANManager type password response to MS-CHAP challenges. + * Now pppd provides both NT style and LANMan style blocks, and the + * prefered is set by option "ms-lanman". Default is to use NT. + * The hash text (StdText) was taken from Win95 RASAPI32.DLL. + * + * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 + */ + +/* + * Modifications by Frank Cusack, frank@google.com, March 2002. + * + * Implemented MS-CHAPv2 functionality, heavily based on sample + * implementation in RFC 2759. Implemented MPPE functionality, + * heavily based on sample implementation in RFC 3079. + * + * Copyright (c) 2002 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#include +#include +#include +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/chap-new.h" +#include "netif/ppp/chap_ms.h" +#include "netif/ppp/pppcrypt.h" +#include "netif/ppp/magic.h" + +#if LWIP_INCLUDED_POLARSSL_MD4 +#include "netif/ppp/polarssl/md4.h" +#else +#include "polarssl/md4.h" +#endif + +#if LWIP_INCLUDED_POLARSSL_SHA1 +#include "netif/ppp/polarssl/sha1.h" +#else +#include "polarssl/sha1.h" +#endif + +#if LWIP_INCLUDED_POLARSSL_DES +#include "netif/ppp/polarssl/des.h" +#else +#include "polarssl/des.h" +#endif + +#define SHA1_SIGNATURE_SIZE 20 + +static void ascii2unicode (char[], int, u_char[]); +static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]); +static void ChallengeResponse (u_char *, u_char *, u_char[24]); +static void ChapMS_NT (u_char *, char *, int, u_char[24]); +static void ChapMS2_NT (u_char *, u_char[16], char *, char *, int, + u_char[24]); +static void GenerateAuthenticatorResponsePlain + (char*, int, u_char[24], u_char[16], u_char *, + char *, u_char[41]); +#ifdef MSLANMAN +static void ChapMS_LANMan (u_char *, char *, int, u_char *); +#endif + +#ifdef MPPE +static void Set_Start_Key (u_char *, char *, int); +static void SetMasterKeys (char *, int, u_char[24], int); +#endif + +#ifdef MSLANMAN +bool ms_lanman = 0; /* Use LanMan password instead of NT */ + /* Has meaning only with MS-CHAP challenges */ +#endif + +#ifdef MPPE +u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +int mppe_keys_set = 0; /* Have the MPPE keys been set? */ + +#ifdef DEBUGMPPEKEY +/* For MPPE debug */ +/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ +static char *mschap_challenge = NULL; +/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ +static char *mschap2_peer_challenge = NULL; +#endif + +#include "netif/ppp/fsm.h" /* Need to poke MPPE options */ +#include "netif/ppp/ccp.h" +#include +#endif + +#if PPP_OPTIONS +/* + * Command-line options. + */ +static option_t chapms_option_list[] = { +#ifdef MSLANMAN + { "ms-lanman", o_bool, &ms_lanman, + "Use LanMan passwd when using MS-CHAP", 1 }, +#endif +#ifdef DEBUGMPPEKEY + { "mschap-challenge", o_string, &mschap_challenge, + "specify CHAP challenge" }, + { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, + "specify CHAP peer challenge" }, +#endif + { NULL } +}; +#endif /* PPP_OPTIONS */ + +#if PPP_SERVER +/* + * chapms_generate_challenge - generate a challenge for MS-CHAP. + * For MS-CHAP the challenge length is fixed at 8 bytes. + * The length goes in challenge[0] and the actual challenge starts + * at challenge[1]. + */ +static void chapms_generate_challenge(unsigned char *challenge) { + *challenge++ = 8; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 8) + memcpy(challenge, mschap_challenge, 8); + else +#endif + random_bytes(challenge, 8); +} + +static void chapms2_generate_challenge(unsigned char *challenge) { + *challenge++ = 16; +#ifdef DEBUGMPPEKEY + if (mschap_challenge && strlen(mschap_challenge) == 16) + memcpy(challenge, mschap_challenge, 16); + else +#endif + random_bytes(challenge, 16); +} + +static int chapms_verify_response(int id, const char *name, + const unsigned char *secret, int secret_len, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space) { + unsigned char md[MS_CHAP_RESPONSE_LEN]; + int diff; + int challenge_len, response_len; + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(name); + + challenge_len = *challenge++; /* skip length, is 8 */ + response_len = *response++; + if (response_len != MS_CHAP_RESPONSE_LEN) + goto bad; + +#ifndef MSLANMAN + if (!response[MS_CHAP_USENT]) { + /* Should really propagate this into the error packet. */ + ppp_notice("Peer request for LANMAN auth not supported"); + goto bad; + } +#endif + + /* Generate the expected response. */ + ChapMS((u_char *)challenge, (char *)secret, secret_len, md); + +#ifdef MSLANMAN + /* Determine which part of response to verify against */ + if (!response[MS_CHAP_USENT]) + diff = memcmp(&response[MS_CHAP_LANMANRESP], + &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); + else +#endif + diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], + MS_CHAP_NTRESP_LEN); + + if (diff == 0) { + ppp_slprintf(message, message_space, "Access granted"); + return 1; + } + + bad: + /* See comments below for MS-CHAP V2 */ + ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", + challenge_len, challenge); + return 0; +} + +static int chapms2_verify_response(int id, const char *name, + const unsigned char *secret, int secret_len, + const unsigned char *challenge, const unsigned char *response, + char *message, int message_space) { + unsigned char md[MS_CHAP2_RESPONSE_LEN]; + char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; + int challenge_len, response_len; + LWIP_UNUSED_ARG(id); + + challenge_len = *challenge++; /* skip length, is 16 */ + response_len = *response++; + if (response_len != MS_CHAP2_RESPONSE_LEN) + goto bad; /* not even the right length */ + + /* Generate the expected response and our mutual auth. */ + ChapMS2((u_char*)challenge, (u_char*)&response[MS_CHAP2_PEER_CHALLENGE], (char*)name, + (char *)secret, secret_len, md, + (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); + + /* compare MDs and send the appropriate status */ + /* + * Per RFC 2759, success message must be formatted as + * "S= M=" + * where + * is the Authenticator Response (mutual auth) + * is a text message + * + * However, some versions of Windows (win98 tested) do not know + * about the M= part (required per RFC 2759) and flag + * it as an error (reported incorrectly as an encryption error + * to the user). Since the RFC requires it, and it can be + * useful information, we supply it if the peer is a conforming + * system. Luckily (?), win98 sets the Flags field to 0x04 + * (contrary to RFC requirements) so we can use that to + * distinguish between conforming and non-conforming systems. + * + * Special thanks to Alex Swiridov for + * help debugging this. + */ + if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], + MS_CHAP2_NTRESP_LEN) == 0) { + if (response[MS_CHAP2_FLAGS]) + ppp_slprintf(message, message_space, "S=%s", saresponse); + else + ppp_slprintf(message, message_space, "S=%s M=%s", + saresponse, "Access granted"); + return 1; + } + + bad: + /* + * Failure message must be formatted as + * "E=e R=r C=c V=v M=m" + * where + * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) + * r = retry (we use 1, ok to retry) + * c = challenge to use for next response, we reuse previous + * v = Change Password version supported, we use 0 + * m = text message + * + * The M=m part is only for MS-CHAPv2. Neither win2k nor + * win98 (others untested) display the message to the user anyway. + * They also both ignore the E=e code. + * + * Note that it's safe to reuse the same challenge as we don't + * actually accept another response based on the error message + * (and no clients try to resend a response anyway). + * + * Basically, this whole bit is useless code, even the small + * implementation here is only because of overspecification. + */ + ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", + challenge_len, challenge, "Access denied"); + return 0; +} +#endif /* PPP_SERVER */ + +static void chapms_make_response(unsigned char *response, int id, const char *our_name, + const unsigned char *challenge, const char *secret, int secret_len, + const unsigned char *private_) { + LWIP_UNUSED_ARG(id); + LWIP_UNUSED_ARG(our_name); + LWIP_UNUSED_ARG(private_); + challenge++; /* skip length, should be 8 */ + *response++ = MS_CHAP_RESPONSE_LEN; + ChapMS((u_char*)challenge, (char*)secret, secret_len, response); +} + +static void chapms2_make_response(unsigned char *response, int id, const char *our_name, + const unsigned char *challenge, const char *secret, int secret_len, + const unsigned char *private_) { + LWIP_UNUSED_ARG(id); + challenge++; /* skip length, should be 16 */ + *response++ = MS_CHAP2_RESPONSE_LEN; + ChapMS2((u_char*)challenge, +#ifdef DEBUGMPPEKEY + mschap2_peer_challenge, +#else + NULL, +#endif + (char*)our_name, (char*)secret, secret_len, response, (u_char*)private_, + MS_CHAP2_AUTHENTICATEE); +} + +static int chapms2_check_success(unsigned char *msg, int len, unsigned char *private_) { + if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || + strncmp((char *)msg, "S=", 2) != 0) { + /* Packet does not start with "S=" */ + ppp_error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + msg += 2; + len -= 2; + if (len < MS_AUTH_RESPONSE_LENGTH + || memcmp(msg, private_, MS_AUTH_RESPONSE_LENGTH)) { + /* Authenticator Response did not match expected. */ + ppp_error("MS-CHAPv2 mutual authentication failed."); + return 0; + } + /* Authenticator Response matches. */ + msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ + len -= MS_AUTH_RESPONSE_LENGTH; + if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { + msg += 3; /* Eat the delimiter */ + } else if (len) { + /* Packet has extra text which does not begin " M=" */ + ppp_error("MS-CHAPv2 Success packet is badly formed."); + return 0; + } + return 1; +} + +static void chapms_handle_failure(unsigned char *inp, int len) { + int err; + const char *p; + char msg[64]; + + /* We want a null-terminated string for strxxx(). */ + len = LWIP_MIN(len, 63); + MEMCPY(msg, inp, len); + msg[len] = 0; + p = msg; + + /* + * Deal with MS-CHAP formatted failure messages; just print the + * M= part (if any). For MS-CHAP we're not really supposed + * to use M=, but it shouldn't hurt. See + * chapms[2]_verify_response. + */ + if (!strncmp(p, "E=", 2)) + err = strtol(p+2, NULL, 10); /* Remember the error code. */ + else + goto print_msg; /* Message is badly formatted. */ + + if (len && ((p = strstr(p, " M=")) != NULL)) { + /* M= field found. */ + p += 3; + } else { + /* No M=; use the error code. */ + switch (err) { + case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: + p = "E=646 Restricted logon hours"; + break; + + case MS_CHAP_ERROR_ACCT_DISABLED: + p = "E=647 Account disabled"; + break; + + case MS_CHAP_ERROR_PASSWD_EXPIRED: + p = "E=648 Password expired"; + break; + + case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: + p = "E=649 No dialin permission"; + break; + + case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: + p = "E=691 Authentication failure"; + break; + + case MS_CHAP_ERROR_CHANGING_PASSWORD: + /* Should never see this, we don't support Change Password. */ + p = "E=709 Error changing password"; + break; + + default: + ppp_error("Unknown MS-CHAP authentication failure: %.*v", + len, inp); + return; + } + } +print_msg: + if (p != NULL) + ppp_error("MS-CHAP authentication failed: %v", p); +} + +static void ChallengeResponse(u_char *challenge, + u_char PasswordHash[MD4_SIGNATURE_SIZE], + u_char response[24]) { + u_char ZPasswordHash[21]; + des_context des; + u_char des_key[8]; + + BZERO(ZPasswordHash, sizeof(ZPasswordHash)); + MEMCPY(ZPasswordHash, PasswordHash, MD4_SIGNATURE_SIZE); + +#if 0 + dbglog("ChallengeResponse - ZPasswordHash %.*B", + sizeof(ZPasswordHash), ZPasswordHash); +#endif + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +0); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +8); + + pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, challenge, response +16); + +#if 0 + dbglog("ChallengeResponse - response %.24B", response); +#endif +} + +void ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge, + char *username, u_char Challenge[8]) { + sha1_context sha1Context; + u_char sha1Hash[SHA1_SIGNATURE_SIZE]; + char *user; + + /* remove domain from "domain\username" */ + if ((user = strrchr(username, '\\')) != NULL) + ++user; + else + user = username; + + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PeerChallenge, 16); + sha1_update(&sha1Context, rchallenge, 16); + sha1_update(&sha1Context, (unsigned char *)user, strlen(user)); + sha1_finish(&sha1Context, sha1Hash); + + MEMCPY(Challenge, sha1Hash, 8); +} + +/* + * Convert the ASCII version of the password to Unicode. + * This implicitly supports 8-bit ISO8859/1 characters. + * This gives us the little-endian representation, which + * is assumed by all M$ CHAP RFCs. (Unicode byte ordering + * is machine-dependent.) + */ +static void ascii2unicode(char ascii[], int ascii_len, u_char unicode[]) { + int i; + + BZERO(unicode, ascii_len * 2); + for (i = 0; i < ascii_len; i++) + unicode[i * 2] = (u_char) ascii[i]; +} + +static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { + md4_context md4Context; + + md4_starts(&md4Context); + md4_update(&md4Context, secret, secret_len); + md4_finish(&md4Context, hash); +} + +static void ChapMS_NT(u_char *rchallenge, char *secret, int secret_len, + u_char NTResponse[24]) { + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(rchallenge, PasswordHash, NTResponse); +} + +static void ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username, + char *secret, int secret_len, u_char NTResponse[24]) { + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char Challenge[8]; + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + /* Hash the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + + ChallengeResponse(Challenge, PasswordHash, NTResponse); +} + +#ifdef MSLANMAN +static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ + +static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) { + int i; + u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + des_context des; + u_char des_key[8]; + + /* LANMan password is case insensitive */ + BZERO(UcasePassword, sizeof(UcasePassword)); + for (i = 0; i < secret_len; i++) + UcasePassword[i] = (u_char)toupper(secret[i]); + + pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +0); + + pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); + des_setkey_enc(&des, des_key); + des_crypt_ecb(&des, StdText, PasswordHash +8); + + ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); +} +#endif + + +void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { + /* + * "Magic" constants used in response generation, from RFC 2759. + */ + u_char Magic1[39] = /* "Magic server to client signing constant" */ + { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, + 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, + 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; + u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ + { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, + 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, + 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, + 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, + 0x6E }; + + int i; + sha1_context sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; + u_char Challenge[8]; + + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, Digest); + + ChallengeHash(PeerChallenge, rchallenge, username, Challenge); + + sha1_starts(&sha1Context); + sha1_update(&sha1Context, Digest, sizeof(Digest)); + sha1_update(&sha1Context, Challenge, sizeof(Challenge)); + sha1_update(&sha1Context, Magic2, sizeof(Magic2)); + sha1_finish(&sha1Context, Digest); + + /* Convert to ASCII hex string. */ + for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), (int)sizeof(Digest)); i++) + sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); +} + + +static void GenerateAuthenticatorResponsePlain + (char *secret, int secret_len, + u_char NTResponse[24], u_char PeerChallenge[16], + u_char *rchallenge, char *username, + u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), + PasswordHashHash); + + GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, + rchallenge, username, authResponse); +} + + +#ifdef MPPE +/* + * Set mppe_xxxx_key from the NTPasswordHashHash. + * RFC 2548 (RADIUS support) requires us to export this function (ugh). + */ +void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { + sha1_context sha1Context; + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, rchallenge, 8); + sha1_finish(&sha1Context, Digest); + + /* Same key in both directions. */ + MEMCPY(mppe_send_key, Digest, sizeof(mppe_send_key)); + MEMCPY(mppe_recv_key, Digest, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) + */ +static void Set_Start_Key(u_char *rchallenge, char *secret, int secret_len) { + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + + mppe_set_keys(rchallenge, PasswordHashHash); +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + * + * This helper function used in the Winbind module, which gets the + * NTHashHash from the server. + */ +void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], + u_char NTResponse[24], int IsServer) { + sha1_context sha1Context; + u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ + + u_char SHApad1[40] = + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + u_char SHApad2[40] = + { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, + 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 }; + + /* "This is the MPPE Master Key" */ + u_char Magic1[27] = + { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, + 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; + /* "On the client side, this is the send key; " + "on the server side, it is the receive key." */ + u_char Magic2[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, + 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + /* "On the client side, this is the receive key; " + "on the server side, it is the send key." */ + u_char Magic3[84] = + { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, + 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, + 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, + 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, + 0x6b, 0x65, 0x79, 0x2e }; + u_char *s; + + sha1_starts(&sha1Context); + sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); + sha1_update(&sha1Context, NTResponse, 24); + sha1_update(&sha1Context, Magic1, sizeof(Magic1)); + sha1_finish(&sha1Context, MasterKey); + + /* + * generate send key + */ + if (IsServer) + s = Magic3; + else + s = Magic2; + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); + + MEMCPY(mppe_send_key, Digest, sizeof(mppe_send_key)); + + /* + * generate recv key + */ + if (IsServer) + s = Magic2; + else + s = Magic3; + sha1_starts(&sha1Context); + sha1_update(&sha1Context, MasterKey, 16); + sha1_update(&sha1Context, SHApad1, sizeof(SHApad1)); + sha1_update(&sha1Context, s, 84); + sha1_update(&sha1Context, SHApad2, sizeof(SHApad2)); + sha1_finish(&sha1Context, Digest); + + MEMCPY(mppe_recv_key, Digest, sizeof(mppe_recv_key)); + + mppe_keys_set = 1; +} + +/* + * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) + */ +static void SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer) { + u_char unicodePassword[MAX_NT_PASSWORD * 2]; + u_char PasswordHash[MD4_SIGNATURE_SIZE]; + u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; + /* Hash (x2) the Unicode version of the secret (== password). */ + ascii2unicode(secret, secret_len, unicodePassword); + NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); + NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); + mppe_set_keys2(PasswordHashHash, NTResponse, IsServer); +} + +#endif /* MPPE */ + + +void ChapMS(u_char *rchallenge, char *secret, int secret_len, + unsigned char *response) { + BZERO(response, MS_CHAP_RESPONSE_LEN); + + ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); + +#ifdef MSLANMAN + ChapMS_LANMan(rchallenge, secret, secret_len, + &response[MS_CHAP_LANMANRESP]); + + /* preferred method is set by option */ + response[MS_CHAP_USENT] = !ms_lanman; +#else + response[MS_CHAP_USENT] = 1; +#endif + +#ifdef MPPE + Set_Start_Key(rchallenge, secret, secret_len); +#endif +} + + +/* + * If PeerChallenge is NULL, one is generated and the PeerChallenge + * field of response is filled in. Call this way when generating a response. + * If PeerChallenge is supplied, it is copied into the PeerChallenge field. + * Call this way when verifying a response (or debugging). + * Do not call with PeerChallenge = response. + * + * The PeerChallenge field of response is then used for calculation of the + * Authenticator Response. + */ +void ChapMS2(u_char *rchallenge, u_char *PeerChallenge, + char *user, char *secret, int secret_len, unsigned char *response, + u_char authResponse[], int authenticator) { + /* ARGSUSED */ + u_char *p = &response[MS_CHAP2_PEER_CHALLENGE]; + int i; + LWIP_UNUSED_ARG(authenticator); + + BZERO(response, MS_CHAP2_RESPONSE_LEN); + + /* Generate the Peer-Challenge if requested, or copy it if supplied. */ + if (!PeerChallenge) + for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++) + *p++ = (u_char) (drand48() * 0xff); + else + MEMCPY(&response[MS_CHAP2_PEER_CHALLENGE], PeerChallenge, + MS_CHAP2_PEER_CHAL_LEN); + + /* Generate the NT-Response */ + ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, + secret, secret_len, &response[MS_CHAP2_NTRESP]); + + /* Generate the Authenticator Response. */ + GenerateAuthenticatorResponsePlain(secret, secret_len, + &response[MS_CHAP2_NTRESP], + &response[MS_CHAP2_PEER_CHALLENGE], + rchallenge, user, authResponse); + +#ifdef MPPE + SetMasterKeys(secret, secret_len, + &response[MS_CHAP2_NTRESP], authenticator); +#endif +} + +#ifdef MPPE +/* + * Set MPPE options from plugins. + */ +void set_mppe_enc_types(int policy, int types) { + /* Early exit for unknown policies. */ + if (policy != MPPE_ENC_POL_ENC_ALLOWED || + policy != MPPE_ENC_POL_ENC_REQUIRED) + return; + + /* Don't modify MPPE if it's optional and wasn't already configured. */ + if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) + return; + + /* + * Disable undesirable encryption types. Note that we don't ENABLE + * any encryption types, to avoid overriding manual configuration. + */ + switch(types) { + case MPPE_ENC_TYPES_RC4_40: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ + break; + case MPPE_ENC_TYPES_RC4_128: + ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ + break; + default: + break; + } +} +#endif /* MPPE */ + +const struct chap_digest_type chapms_digest = { + CHAP_MICROSOFT, /* code */ +#if PPP_SERVER + chapms_generate_challenge, + chapms_verify_response, +#endif /* PPP_SERVER */ + chapms_make_response, + NULL, /* check_success */ + chapms_handle_failure, +}; + +const struct chap_digest_type chapms2_digest = { + CHAP_MICROSOFT_V2, /* code */ +#if PPP_SERVER + chapms2_generate_challenge, + chapms2_verify_response, +#endif /* PPP_SERVER */ + chapms2_make_response, + chapms2_check_success, + chapms_handle_failure, +}; + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/demand.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/demand.c new file mode 100644 index 0000000..f31a124 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/demand.c @@ -0,0 +1,467 @@ +/* + * demand.c - Support routines for demand-dialling. + * + * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && DEMAND_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef PPP_FILTER +#include +#endif + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/lcp.h" + +char *frame; +int framelen; +int framemax; +int escape_flag; +int flush_flag; +int fcs; + +struct packet { + int length; + struct packet *next; + unsigned char data[1]; +}; + +struct packet *pend_q; +struct packet *pend_qtail; + +static int active_packet (unsigned char *, int); + +/* + * demand_conf - configure the interface for doing dial-on-demand. + */ +void +demand_conf() +{ + int i; + const struct protent *protp; + +/* framemax = lcp_allowoptions[0].mru; + if (framemax < PPP_MRU) */ + framemax = PPP_MRU; + framemax += PPP_HDRLEN + PPP_FCSLEN; + frame = malloc(framemax); + if (frame == NULL) + novm("demand frame"); + framelen = 0; + pend_q = NULL; + escape_flag = 0; + flush_flag = 0; + fcs = PPP_INITFCS; + + netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); + if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0 + || ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0) + fatal("Couldn't set up demand-dialled PPP interface: %m"); + +#ifdef PPP_FILTER + set_filters(&pass_filter, &active_filter); +#endif + + /* + * Call the demand_conf procedure for each protocol that's got one. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->enabled_flag && protp->demand_conf != NULL) + ((*protp->demand_conf)(pcb)); +/* FIXME: find a way to die() here */ +#if 0 + if (!((*protp->demand_conf)(pcb))) + die(1); +#endif +} + + +/* + * demand_block - set each network protocol to block further packets. + */ +void +demand_block() +{ + int i; + const struct protent *protp; + + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->enabled_flag && protp->demand_conf != NULL) + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_QUEUE); + get_loop_output(); +} + +/* + * demand_discard - set each network protocol to discard packets + * with an error. + */ +void +demand_discard() +{ + struct packet *pkt, *nextpkt; + int i; + const struct protent *protp; + + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->enabled_flag && protp->demand_conf != NULL) + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_ERROR); + get_loop_output(); + + /* discard all saved packets */ + for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { + nextpkt = pkt->next; + free(pkt); + } + pend_q = NULL; + framelen = 0; + flush_flag = 0; + escape_flag = 0; + fcs = PPP_INITFCS; +} + +/* + * demand_unblock - set each enabled network protocol to pass packets. + */ +void +demand_unblock() +{ + int i; + const struct protent *protp; + + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->enabled_flag && protp->demand_conf != NULL) + sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_PASS); +} + +/* + * FCS lookup table as calculated by genfcstab. + */ +static u_short fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/* + * loop_chars - process characters received from the loopback. + * Calls loop_frame when a complete frame has been accumulated. + * Return value is 1 if we need to bring up the link, 0 otherwise. + */ +int +loop_chars(p, n) + unsigned char *p; + int n; +{ + int c, rv; + + rv = 0; + +/* check for synchronous connection... */ + + if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { + rv = loop_frame(p,n); + return rv; + } + + for (; n > 0; --n) { + c = *p++; + if (c == PPP_FLAG) { + if (!escape_flag && !flush_flag + && framelen > 2 && fcs == PPP_GOODFCS) { + framelen -= 2; + if (loop_frame((unsigned char *)frame, framelen)) + rv = 1; + } + framelen = 0; + flush_flag = 0; + escape_flag = 0; + fcs = PPP_INITFCS; + continue; + } + if (flush_flag) + continue; + if (escape_flag) { + c ^= PPP_TRANS; + escape_flag = 0; + } else if (c == PPP_ESCAPE) { + escape_flag = 1; + continue; + } + if (framelen >= framemax) { + flush_flag = 1; + continue; + } + frame[framelen++] = c; + fcs = PPP_FCS(fcs, c); + } + return rv; +} + +/* + * loop_frame - given a frame obtained from the loopback, + * decide whether to bring up the link or not, and, if we want + * to transmit this frame later, put it on the pending queue. + * Return value is 1 if we need to bring up the link, 0 otherwise. + * We assume that the kernel driver has already applied the + * pass_filter, so we won't get packets it rejected. + * We apply the active_filter to see if we want this packet to + * bring up the link. + */ +int +loop_frame(frame, len) + unsigned char *frame; + int len; +{ + struct packet *pkt; + + /* dbglog("from loop: %P", frame, len); */ + if (len < PPP_HDRLEN) + return 0; + if ((PPP_PROTOCOL(frame) & 0x8000) != 0) + return 0; /* shouldn't get any of these anyway */ + if (!active_packet(frame, len)) + return 0; + + pkt = (struct packet *) malloc(sizeof(struct packet) + len); + if (pkt != NULL) { + pkt->length = len; + pkt->next = NULL; + memcpy(pkt->data, frame, len); + if (pend_q == NULL) + pend_q = pkt; + else + pend_qtail->next = pkt; + pend_qtail = pkt; + } + return 1; +} + +/* + * demand_rexmit - Resend all those frames which we got via the + * loopback, now that the real serial link is up. + */ +void +demand_rexmit(proto, newip) + int proto; + u32_t newip; +{ + struct packet *pkt, *prev, *nextpkt; + unsigned short checksum; + unsigned short pkt_checksum = 0; + unsigned iphdr; + struct timeval tv; + char cv = 0; + char ipstr[16]; + + prev = NULL; + pkt = pend_q; + pend_q = NULL; + tv.tv_sec = 1; + tv.tv_usec = 0; + select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ + for (; pkt != NULL; pkt = nextpkt) { + nextpkt = pkt->next; + if (PPP_PROTOCOL(pkt->data) == proto) { + if ( (proto == PPP_IP) && newip ) { + /* Get old checksum */ + + iphdr = (pkt->data[4] & 15) << 2; + checksum = *((unsigned short *) (pkt->data+14)); + if (checksum == 0xFFFF) { + checksum = 0; + } + + + if (pkt->data[13] == 17) { + pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); + if (pkt_checksum) { + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + else { + cv = 0; + } + } + + if (pkt->data[13] == 6) { + pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); + cv = 1; + if (pkt_checksum == 0xFFFF) { + pkt_checksum = 0; + } + } + + /* Delete old Source-IP-Address */ + checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Change Source-IP-Address */ + * ((u32_t *) (pkt->data + 16)) = newip; + + /* Add new Source-IP-Address */ + checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; + pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; + + /* Write new checksum */ + if (!checksum) { + checksum = 0xFFFF; + } + *((unsigned short *) (pkt->data+14)) = checksum; + if (pkt->data[13] == 6) { + *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; + } + if (cv && (pkt->data[13] == 17) ) { + *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; + } + + /* Log Packet */ + strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); + if (pkt->data[13] == 1) { + syslog(LOG_INFO,"Open ICMP %s -> %s\n", + ipstr, + inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); + } else { + syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", + pkt->data[13] == 6 ? "TCP" : "UDP", + ipstr, + ntohs(*( (short *) (pkt->data+iphdr+4))), + inet_ntoa(*( (struct in_addr *) (pkt->data+20))), + ntohs(*( (short *) (pkt->data+iphdr+6)))); + } + } + output(pcb, pkt->data, pkt->length); + free(pkt); + } else { + if (prev == NULL) + pend_q = pkt; + else + prev->next = pkt; + prev = pkt; + } + } + pend_qtail = prev; + if (prev != NULL) + prev->next = NULL; +} + +/* + * Scan a packet to decide whether it is an "active" packet, + * that is, whether it is worth bringing up the link for. + */ +static int +active_packet(p, len) + unsigned char *p; + int len; +{ + int proto, i; + const struct protent *protp; + + if (len < PPP_HDRLEN) + return 0; + proto = PPP_PROTOCOL(p); +#ifdef PPP_FILTER + p[0] = 1; /* outbound packet indicator */ + if ((pass_filter.bf_len != 0 + && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) + || (active_filter.bf_len != 0 + && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) { + p[0] = 0xff; + return 0; + } + p[0] = 0xff; +#endif + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { + if (!protp->enabled_flag) + return 0; + if (protp->active_pkt == NULL) + return 1; + return (*protp->active_pkt)(p, len); + } + } + return 0; /* not a supported protocol !!?? */ +} + +#endif /* PPP_SUPPORT && DEMAND_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eap.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eap.c new file mode 100644 index 0000000..5016eac --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eap.c @@ -0,0 +1,2455 @@ +/* + * eap.c - Extensible Authentication Protocol for PPP (RFC 2284) + * + * Copyright (c) 2001 by Sun Microsystems, Inc. + * All rights reserved. + * + * Non-exclusive rights to redistribute, modify, translate, and use + * this software in source and binary forms, in whole or in part, is + * hereby granted, provided that the above copyright notice is + * duplicated in any source form, and that neither the name of the + * copyright holder nor the author is used to endorse or promote + * products derived from this software. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Original version by James Carlson + * + * This implementation of EAP supports MD5-Challenge and SRP-SHA1 + * authentication styles. Note that support of MD5-Challenge is a + * requirement of RFC 2284, and that it's essentially just a + * reimplementation of regular RFC 1994 CHAP using EAP messages. + * + * As an authenticator ("server"), there are multiple phases for each + * style. In the first phase of each style, the unauthenticated peer + * name is queried using the EAP Identity request type. If the + * "remotename" option is used, then this phase is skipped, because + * the peer's name is presumed to be known. + * + * For MD5-Challenge, there are two phases, and the second phase + * consists of sending the challenge itself and handling the + * associated response. + * + * For SRP-SHA1, there are four phases. The second sends 's', 'N', + * and 'g'. The reply contains 'A'. The third sends 'B', and the + * reply contains 'M1'. The forth sends the 'M2' value. + * + * As an authenticatee ("client"), there's just a single phase -- + * responding to the queries generated by the peer. EAP is an + * authenticator-driven protocol. + * + * Based on draft-ietf-pppext-eap-srp-03.txt. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "netif/ppp/ppp_impl.h" + +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "netif/ppp/polarssl/md5.h" +#else +#include "polarssl/md5.h" +#endif + +#include "netif/ppp/eap.h" + +#ifdef USE_SRP +#include +#include +#include +#include "netif/ppp/pppcrypt.h" +#endif /* USE_SRP */ + +#ifndef SHA_DIGESTSIZE +#define SHA_DIGESTSIZE 20 +#endif + +#ifdef USE_SRP +static char *pn_secret = NULL; /* Pseudonym generating secret */ +#endif + +#if PPP_OPTIONS +/* + * Command-line options. + */ +static option_t eap_option_list[] = { + { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, + "Set retransmit timeout for EAP Requests (server)" }, + { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, + "Set max number of EAP Requests sent (server)" }, + { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, + "Set time limit for peer EAP authentication" }, + { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, + "Set max number of EAP Requests allows (client)" }, + { "eap-interval", o_int, &eap_states[0].es_rechallenge, + "Set interval for EAP rechallenge" }, +#ifdef USE_SRP + { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, + "Set interval for SRP lightweight rechallenge" }, + { "srp-pn-secret", o_string, &pn_secret, + "Long term pseudonym generation secret" }, + { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, + "Use pseudonym if offered one by server", 1 }, +#endif + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points. + */ +static void eap_init(ppp_pcb *pcb); +static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen); +static void eap_protrej(ppp_pcb *pcb); +static void eap_lowerup(ppp_pcb *pcb); +static void eap_lowerdown(ppp_pcb *pcb); +#if PRINTPKT_SUPPORT +static int eap_printpkt(u_char *inp, int inlen, + void (*)(void *arg, const char *fmt, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ + +const struct protent eap_protent = { + PPP_EAP, /* protocol number */ + eap_init, /* initialization procedure */ + eap_input, /* process a received packet */ + eap_protrej, /* process a received protocol-reject */ + eap_lowerup, /* lower layer has gone up */ + eap_lowerdown, /* lower layer has gone down */ + NULL, /* open the protocol */ + NULL, /* close the protocol */ +#if PRINTPKT_SUPPORT + eap_printpkt, /* print a packet in readable form */ +#endif /* PRINTPKT_SUPPORT */ + NULL, /* process a received data packet */ + 1, /* protocol enabled */ +#if PRINTPKT_SUPPORT + "EAP", /* text name of protocol */ + NULL, /* text name of corresponding data protocol */ +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + eap_option_list, /* list of command-line options */ + NULL, /* check requested options; assign defaults */ +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, /* configure interface for demand-dial */ + NULL /* say whether to bring up link for this pkt */ +#endif /* DEMAND_SUPPORT */ +}; + +#ifdef USE_SRP +/* + * A well-known 2048 bit modulus. + */ +static const u_char wkmodulus[] = { + 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, + 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, + 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, + 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, + 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, + 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, + 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, + 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, + 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, + 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, + 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, + 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, + 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, + 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, + 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, + 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, + 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, + 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, + 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, + 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, + 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, + 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, + 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, + 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, + 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, + 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, + 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, + 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, + 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, + 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, + 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, + 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 +}; +#endif + +#if PPP_SERVER +/* Local forward declarations. */ +static void eap_server_timeout(void *arg); +#endif /* PPP_SERVER */ + +/* + * Convert EAP state code to printable string for debug. + */ +static const char * eap_state_name(enum eap_state_code esc) +{ + static const char *state_names[] = { EAP_STATES }; + + return (state_names[(int)esc]); +} + +/* + * eap_init - Initialize state for an EAP user. This is currently + * called once by main() during start-up. + */ +static void eap_init(ppp_pcb *pcb) { + + BZERO(&pcb->eap, sizeof(eap_state)); +#if PPP_SERVER + pcb->eap.es_server.ea_id = (u_char)(drand48() * 0x100); /* FIXME: use magic.c random function */ +#endif /* PPP_SERVER */ +} + +/* + * eap_client_timeout - Give up waiting for the peer to send any + * Request messages. + */ +static void eap_client_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (!eap_client_active(pcb)) + return; + + ppp_error("EAP: timeout waiting for Request from peer"); + auth_withpeer_fail(pcb, PPP_EAP); + pcb->eap.es_client.ea_state = eapBadAuth; +} + +/* + * eap_authwithpeer - Authenticate to our peer (behave as client). + * + * Start client state and wait for requests. This is called only + * after eap_lowerup. + */ +void eap_authwithpeer(ppp_pcb *pcb, const char *localname) { + + if(NULL == localname) + return; + + /* Save the peer name we're given */ + pcb->eap.es_client.ea_name = localname; + pcb->eap.es_client.ea_namelen = strlen(localname); + + pcb->eap.es_client.ea_state = eapListen; + + /* + * Start a timer so that if the other end just goes + * silent, we don't sit here waiting forever. + */ + if (pcb->settings.eap_req_time > 0) + TIMEOUT(eap_client_timeout, pcb, + pcb->settings.eap_req_time); +} + +#if PPP_SERVER +/* + * Format a standard EAP Failure message and send it to the peer. + * (Server operation) + */ +static void eap_send_failure(ppp_pcb *pcb) { + struct pbuf *p; + u_char *outp; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_FAILURE, outp); + pcb->eap.es_server.ea_id++; + PUTCHAR(pcb->eap.es_server.ea_id, outp); + PUTSHORT(EAP_HEADERLEN, outp); + + ppp_write(pcb, p); + + pcb->eap.es_server.ea_state = eapBadAuth; + auth_peer_fail(pcb, PPP_EAP); +} + +/* + * Format a standard EAP Success message and send it to the peer. + * (Server operation) + */ +static void eap_send_success(ppp_pcb *pcb) { + struct pbuf *p; + u_char *outp; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_SUCCESS, outp); + pcb->eap.es_server.ea_id++; + PUTCHAR(pcb->eap.es_server.ea_id, outp); + PUTSHORT(EAP_HEADERLEN, outp); + + ppp_write(pcb, p); + + auth_peer_success(pcb, PPP_EAP, 0, + pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); +} +#endif /* PPP_SERVER */ + +#ifdef USE_SRP +/* + * Set DES key according to pseudonym-generating secret and current + * date. + */ +static bool +pncrypt_setkey(int timeoffs) +{ + struct tm *tp; + char tbuf[9]; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + time_t reftime; + + if (pn_secret == NULL) + return (0); + reftime = time(NULL) + timeoffs; + tp = localtime(&reftime); + SHA1Init(&ctxt); + SHA1Update(&ctxt, pn_secret, strlen(pn_secret)); + strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); + SHA1Update(&ctxt, tbuf, strlen(tbuf)); + SHA1Final(dig, &ctxt); + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + return (DesSetkey(dig)); +} + +static char base64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +struct b64state { + u32_t bs_bits; + int bs_offs; +}; + +static int +b64enc(bs, inp, inlen, outp) +struct b64state *bs; +u_char *inp; +int inlen; +u_char *outp; +{ + int outlen = 0; + + while (inlen > 0) { + bs->bs_bits = (bs->bs_bits << 8) | *inp++; + inlen--; + bs->bs_offs += 8; + if (bs->bs_offs >= 24) { + *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; + *outp++ = base64[bs->bs_bits & 0x3F]; + outlen += 4; + bs->bs_offs = 0; + bs->bs_bits = 0; + } + } + return (outlen); +} + +static int +b64flush(bs, outp) +struct b64state *bs; +u_char *outp; +{ + int outlen = 0; + + if (bs->bs_offs == 8) { + *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; + *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; + outlen = 2; + } else if (bs->bs_offs == 16) { + *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; + *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; + *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; + outlen = 3; + } + bs->bs_offs = 0; + bs->bs_bits = 0; + return (outlen); +} + +static int +b64dec(bs, inp, inlen, outp) +struct b64state *bs; +u_char *inp; +int inlen; +u_char *outp; +{ + int outlen = 0; + char *cp; + + while (inlen > 0) { + if ((cp = strchr(base64, *inp++)) == NULL) + break; + bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); + inlen--; + bs->bs_offs += 6; + if (bs->bs_offs >= 8) { + *outp++ = bs->bs_bits >> (bs->bs_offs - 8); + outlen++; + bs->bs_offs -= 8; + } + } + return (outlen); +} +#endif /* USE_SRP */ + +#if PPP_SERVER +/* + * Assume that current waiting server state is complete and figure + * next state to use based on available authentication data. 'status' + * indicates if there was an error in handling the last query. It is + * 0 for success and non-zero for failure. + */ +static void eap_figure_next_state(ppp_pcb *pcb, int status) { +#ifdef USE_SRP + unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; + struct t_pw tpw; + struct t_confent *tce, mytce; + char *cp, *cp2; + struct t_server *ts; + int id, i, plen, toffs; + u_char vals[2]; + struct b64state bs; +#endif /* USE_SRP */ + + pcb->settings.eap_timeout_time = pcb->eap.es_savedtime; + switch (pcb->eap.es_server.ea_state) { + case eapBadAuth: + return; + + case eapIdentify: +#ifdef USE_SRP + /* Discard any previous session. */ + ts = (struct t_server *)pcb->eap.es_server.ea_session; + if (ts != NULL) { + t_serverclose(ts); + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0) { + pcb->eap.es_server.ea_state = eapBadAuth; + break; + } +#ifdef USE_SRP + /* If we've got a pseudonym, try to decode to real name. */ + if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN && + strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID, + SRP_PSEUDO_LEN) == 0 && + (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < + sizeof (secbuf)) { + BZERO(&bs, sizeof (bs)); + plen = b64dec(&bs, + pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN, + pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN, + secbuf); + toffs = 0; + for (i = 0; i < 5; i++) { + pncrypt_setkey(toffs); + toffs -= 86400; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + if (!DesDecrypt(secbuf, clear)) { + ppp_dbglog("no DES here; cannot decode " + "pseudonym"); + return; + } + id = *(unsigned char *)clear; + if (id + 1 <= plen && id + 9 > plen) + break; + } + if (plen % 8 == 0 && i < 5) { + /* + * Note that this is always shorter than the + * original stored string, so there's no need + * to realloc. + */ + if ((i = plen = *(unsigned char *)clear) > 7) + i = 7; + pcb->eap.es_server.ea_peerlen = plen; + dp = (unsigned char *)pcb->eap.es_server.ea_peer; + MEMCPY(dp, clear + 1, i); + plen -= i; + dp += i; + sp = secbuf + 8; + while (plen > 0) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + (void) DesDecrypt(sp, dp); + sp += 8; + dp += 8; + plen -= 8; + } + pcb->eap.es_server.ea_peer[ + pcb->eap.es_server.ea_peerlen] = '\0'; + ppp_dbglog("decoded pseudonym to \"%.*q\"", + pcb->eap.es_server.ea_peerlen, + pcb->eap.es_server.ea_peer); + } else { + ppp_dbglog("failed to decode real name"); + /* Stay in eapIdentfy state; requery */ + break; + } + } + /* Look up user in secrets database. */ + if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) { + /* Set up default in case SRP entry is bad */ + pcb->eap.es_server.ea_state = eapMD5Chall; + /* Get t_confent based on index in srp-secrets */ + id = strtol((char *)secbuf, &cp, 10); + if (*cp++ != ':' || id < 0) + break; + if (id == 0) { + mytce.index = 0; + mytce.modulus.data = (u_char *)wkmodulus; + mytce.modulus.len = sizeof (wkmodulus); + mytce.generator.data = (u_char *)"\002"; + mytce.generator.len = 1; + tce = &mytce; + } else if ((tce = gettcid(id)) != NULL) { + /* + * Client will have to verify this modulus/ + * generator combination, and that will take + * a while. Lengthen the timeout here. + */ + if (pcb->settings.eap_timeout_time > 0 && + pcb->settings.eap_timeout_time < 30) + pcb->settings.eap_timeout_time = 30; + } else { + break; + } + if ((cp2 = strchr(cp, ':')) == NULL) + break; + *cp2++ = '\0'; + tpw.pebuf.name = pcb->eap.es_server.ea_peer; + tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, + cp); + tpw.pebuf.password.data = tpw.pwbuf; + tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, + cp2); + tpw.pebuf.salt.data = tpw.saltbuf; + if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) + break; + pcb->eap.es_server.ea_session = (void *)ts; + pcb->eap.es_server.ea_state = eapSRP1; + vals[0] = pcb->eap.es_server.ea_id + 1; + vals[1] = EAPT_SRP; + t_serveraddexdata(ts, vals, 2); + /* Generate B; must call before t_servergetkey() */ + t_servergenexp(ts); + break; + } +#endif /* USE_SRP */ + pcb->eap.es_server.ea_state = eapMD5Chall; + break; + + case eapSRP1: +#ifdef USE_SRP + ts = (struct t_server *)pcb->eap.es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status == 1) { + pcb->eap.es_server.ea_state = eapMD5Chall; + } else if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; + } else { + pcb->eap.es_server.ea_state = eapSRP2; + } + break; + + case eapSRP2: +#ifdef USE_SRP + ts = (struct t_server *)pcb->eap.es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; + } else { + pcb->eap.es_server.ea_state = eapSRP3; + } + break; + + case eapSRP3: + case eapSRP4: +#ifdef USE_SRP + ts = (struct t_server *)pcb->eap.es_server.ea_session; + if (ts != NULL && status != 0) { + t_serverclose(ts); + pcb->eap.es_server.ea_session = NULL; + pcb->eap.es_server.ea_skey = NULL; + } +#endif /* USE_SRP */ + if (status != 0 || pcb->eap.es_server.ea_session == NULL) { + pcb->eap.es_server.ea_state = eapBadAuth; + } else { + pcb->eap.es_server.ea_state = eapOpen; + } + break; + + case eapMD5Chall: + if (status != 0) { + pcb->eap.es_server.ea_state = eapBadAuth; + } else { + pcb->eap.es_server.ea_state = eapOpen; + } + break; + + default: + pcb->eap.es_server.ea_state = eapBadAuth; + break; + } + if (pcb->eap.es_server.ea_state == eapBadAuth) + eap_send_failure(pcb); +} + +/* + * Format an EAP Request message and send it to the peer. Message + * type depends on current state. (Server operation) + */ +static void eap_send_request(ppp_pcb *pcb) { + struct pbuf *p; + u_char *outp; + u_char *lenloc; + u_char *ptr; + int outlen; + int challen; + const char *str; +#ifdef USE_SRP + struct t_server *ts; + u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; + int i, j; + struct b64state b64; + SHA1_CTX ctxt; +#endif /* USE_SRP */ + + /* Handle both initial auth and restart */ + if (pcb->eap.es_server.ea_state < eapIdentify && + pcb->eap.es_server.ea_state != eapInitial) { + pcb->eap.es_server.ea_state = eapIdentify; +#if PPP_REMOTENAME + if (pcb->settings.explicit_remote) { + /* + * If we already know the peer's + * unauthenticated name, then there's no + * reason to ask. Go to next state instead. + */ + pcb->eap.es_server.ea_peer = pcb->remote_name; + pcb->eap.es_server.ea_peerlen = strlen(pcb->remote_name); + eap_figure_next_state(pcb, 0); + } +#endif /* PPP_REMOTENAME */ + } + + if (pcb->settings.eap_max_transmits > 0 && + pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) { + if (pcb->eap.es_server.ea_responses > 0) + ppp_error("EAP: too many Requests sent"); + else + ppp_error("EAP: no response to Requests"); + eap_send_failure(pcb); + return; + } + + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_REQUEST, outp); + PUTCHAR(pcb->eap.es_server.ea_id, outp); + lenloc = outp; + INCPTR(2, outp); + + switch (pcb->eap.es_server.ea_state) { + case eapIdentify: + PUTCHAR(EAPT_IDENTITY, outp); + str = "Name"; + challen = strlen(str); + MEMCPY(outp, str, challen); + INCPTR(challen, outp); + break; + + case eapMD5Chall: + PUTCHAR(EAPT_MD5CHAP, outp); + /* + * pick a random challenge length between + * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH + */ + challen = (drand48() * + (EAP_MAX_CHALLENGE_LENGTH - EAP_MIN_CHALLENGE_LENGTH)) + + EAP_MIN_CHALLENGE_LENGTH; + PUTCHAR(challen, outp); + pcb->eap.es_challen = challen; + ptr = pcb->eap.es_challenge; + while (--challen >= 0) + *ptr++ = (u_char) (drand48() * 0x100); + MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); + INCPTR(pcb->eap.es_challen, outp); + MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); + INCPTR(pcb->eap.es_server.ea_namelen, outp); + break; + +#ifdef USE_SRP + case eapSRP1: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_CHALLENGE, outp); + + PUTCHAR(pcb->eap.es_server.ea_namelen, outp); + MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); + INCPTR(pcb->eap.es_server.ea_namelen, outp); + + ts = (struct t_server *)pcb->eap.es_server.ea_session; + assert(ts != NULL); + PUTCHAR(ts->s.len, outp); + MEMCPY(outp, ts->s.data, ts->s.len); + INCPTR(ts->s.len, outp); + + if (ts->g.len == 1 && ts->g.data[0] == 2) { + PUTCHAR(0, outp); + } else { + PUTCHAR(ts->g.len, outp); + MEMCPY(outp, ts->g.data, ts->g.len); + INCPTR(ts->g.len, outp); + } + + if (ts->n.len != sizeof (wkmodulus) || + BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { + MEMCPY(outp, ts->n.data, ts->n.len); + INCPTR(ts->n.len, outp); + } + break; + + case eapSRP2: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_SKEY, outp); + + ts = (struct t_server *)pcb->eap.es_server.ea_session; + assert(ts != NULL); + MEMCPY(outp, ts->B.data, ts->B.len); + INCPTR(ts->B.len, outp); + break; + + case eapSRP3: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_SVALIDATOR, outp); + PUTLONG(SRPVAL_EBIT, outp); + ts = (struct t_server *)pcb->eap.es_server.ea_session; + assert(ts != NULL); + MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE); + INCPTR(SHA_DIGESTSIZE, outp); + + if (pncrypt_setkey(0)) { + /* Generate pseudonym */ + optr = outp; + cp = (unsigned char *)pcb->eap.es_server.ea_peer; + if ((j = i = pcb->eap.es_server.ea_peerlen) > 7) + j = 7; + clear[0] = i; + MEMCPY(clear + 1, cp, j); + i -= j; + cp += j; + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + if (!DesEncrypt(clear, cipher)) { + ppp_dbglog("no DES here; not generating pseudonym"); + break; + } + BZERO(&b64, sizeof (b64)); + outp++; /* space for pseudonym length */ + outp += b64enc(&b64, cipher, 8, outp); + while (i >= 8) { + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + (void) DesEncrypt(cp, cipher); + outp += b64enc(&b64, cipher, 8, outp); + cp += 8; + i -= 8; + } + if (i > 0) { + MEMCPY(clear, cp, i); + cp += i; + while (i < 8) { + *cp++ = drand48() * 0x100; + i++; + } + /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ + (void) DesEncrypt(clear, cipher); + outp += b64enc(&b64, cipher, 8, outp); + } + outp += b64flush(&b64, outp); + + /* Set length and pad out to next 20 octet boundary */ + i = outp - optr - 1; + *optr = i; + i %= SHA_DIGESTSIZE; + if (i != 0) { + while (i < SHA_DIGESTSIZE) { + *outp++ = drand48() * 0x100; + i++; + } + } + + /* Obscure the pseudonym with SHA1 hash */ + SHA1Init(&ctxt); + SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_peerlen); + while (optr < outp) { + SHA1Final(dig, &ctxt); + cp = dig; + while (cp < dig + SHA_DIGESTSIZE) + *optr++ ^= *cp++; + SHA1Init(&ctxt); + SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, + SHA_DIGESTSIZE); + } + } + break; + + case eapSRP4: + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_LWRECHALLENGE, outp); + challen = EAP_MIN_CHALLENGE_LENGTH + + ((EAP_MAX_CHALLENGE_LENGTH - EAP_MIN_CHALLENGE_LENGTH) * drand48()); + pcb->eap.es_challen = challen; + ptr = pcb->eap.es_challenge; + while (--challen >= 0) + *ptr++ = drand48() * 0x100; + MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); + INCPTR(pcb->eap.es_challen, outp); + break; +#endif /* USE_SRP */ + + default: + return; + } + + outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN; + PUTSHORT(outlen, lenloc); + + pbuf_realloc(p, outlen + PPP_HDRLEN); + ppp_write(pcb, p); + + pcb->eap.es_server.ea_requests++; + + if (pcb->settings.eap_timeout_time > 0) + TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time); +} + +/* + * eap_authpeer - Authenticate our peer (behave as server). + * + * Start server state and send first request. This is called only + * after eap_lowerup. + */ +void eap_authpeer(ppp_pcb *pcb, const char *localname) { + + /* Save the name we're given. */ + pcb->eap.es_server.ea_name = localname; + pcb->eap.es_server.ea_namelen = strlen(localname); + + pcb->eap.es_savedtime = pcb->settings.eap_timeout_time; + + /* Lower layer up yet? */ + if (pcb->eap.es_server.ea_state == eapInitial || + pcb->eap.es_server.ea_state == eapPending) { + pcb->eap.es_server.ea_state = eapPending; + return; + } + + pcb->eap.es_server.ea_state = eapPending; + + /* ID number not updated here intentionally; hashed into M1 */ + eap_send_request(pcb); +} + +/* + * eap_server_timeout - Retransmission timer for sending Requests + * expired. + */ +static void eap_server_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (!eap_server_active(pcb)) + return; + + /* EAP ID number must not change on timeout. */ + eap_send_request(pcb); +} + +/* + * When it's time to send rechallenge the peer, this timeout is + * called. Once the rechallenge is successful, the response handler + * will restart the timer. If it fails, then the link is dropped. + */ +static void eap_rechallenge(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (pcb->eap.es_server.ea_state != eapOpen && + pcb->eap.es_server.ea_state != eapSRP4) + return; + + pcb->eap.es_server.ea_requests = 0; + pcb->eap.es_server.ea_state = eapIdentify; + eap_figure_next_state(pcb, 0); + pcb->eap.es_server.ea_id++; + eap_send_request(pcb); +} + +static void srp_lwrechallenge(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (pcb->eap.es_server.ea_state != eapOpen || + pcb->eap.es_server.ea_type != EAPT_SRP) + return; + + pcb->eap.es_server.ea_requests = 0; + pcb->eap.es_server.ea_state = eapSRP4; + pcb->eap.es_server.ea_id++; + eap_send_request(pcb); +} +#endif /* PPP_SERVER */ + +/* + * eap_lowerup - The lower layer is now up. + * + * This is called before either eap_authpeer or eap_authwithpeer. See + * link_established() in auth.c. All that's necessary here is to + * return to closed state so that those two routines will do the right + * thing. + */ +static void eap_lowerup(ppp_pcb *pcb) { + + /* Discard any (possibly authenticated) peer name. */ +#if PPP_SERVER + if (pcb->eap.es_server.ea_peer != NULL +#if PPP_REMOTENAME + && pcb->eap.es_server.ea_peer != pcb->remote_name +#endif /* PPP_REMOTENAME */ + ) + free(pcb->eap.es_server.ea_peer); + pcb->eap.es_server.ea_peer = NULL; +#endif /* PPP_SERVER */ + if (pcb->eap.es_client.ea_peer != NULL) + free(pcb->eap.es_client.ea_peer); + pcb->eap.es_client.ea_peer = NULL; + + pcb->eap.es_client.ea_state = eapClosed; +#if PPP_SERVER + pcb->eap.es_server.ea_state = eapClosed; +#endif /* PPP_SERVER */ +} + +/* + * eap_lowerdown - The lower layer is now down. + * + * Cancel all timeouts and return to initial state. + */ +static void eap_lowerdown(ppp_pcb *pcb) { + + if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + } +#if PPP_SERVER + if (eap_server_active(pcb)) { + if (pcb->settings.eap_timeout_time > 0) { + UNTIMEOUT(eap_server_timeout, pcb); + } + } else { + if ((pcb->eap.es_server.ea_state == eapOpen || + pcb->eap.es_server.ea_state == eapSRP4) && + pcb->eap.es_rechallenge > 0) { + UNTIMEOUT(eap_rechallenge, (void *)pcb); + } + if (pcb->eap.es_server.ea_state == eapOpen && + pcb->eap.es_lwrechallenge > 0) { + UNTIMEOUT(srp_lwrechallenge, (void *)pcb); + } + } + + pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial; + pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0; +#endif /* PPP_SERVER */ +} + +/* + * eap_protrej - Peer doesn't speak this protocol. + * + * This shouldn't happen. If it does, it represents authentication + * failure. + */ +static void eap_protrej(ppp_pcb *pcb) { + + if (eap_client_active(pcb)) { + ppp_error("EAP authentication failed due to Protocol-Reject"); + auth_withpeer_fail(pcb, PPP_EAP); + } +#if PPP_SERVER + if (eap_server_active(pcb)) { + ppp_error("EAP authentication of peer failed on Protocol-Reject"); + auth_peer_fail(pcb, PPP_EAP); + } +#endif /* PPP_SERVER */ + eap_lowerdown(pcb); +} + +/* + * Format and send a regular EAP Response message. + */ +static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, u_char *str, int lenstr) { + struct pbuf *p; + u_char *outp; + int msglen; + + msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + pcb->eap.es_client.ea_id = id; + PUTSHORT(msglen, outp); + PUTCHAR(typenum, outp); + if (lenstr > 0) { + MEMCPY(outp, str, lenstr); + } + + ppp_write(pcb, p); +} + +/* + * Format and send an MD5-Challenge EAP Response message. + */ +static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, const char *name, int namelen) { + struct pbuf *p; + u_char *outp; + int msglen; + + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + + namelen; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + pcb->eap.es_client.ea_id = id; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_MD5CHAP, outp); + PUTCHAR(MD5_SIGNATURE_SIZE, outp); + MEMCPY(outp, hash, MD5_SIGNATURE_SIZE); + INCPTR(MD5_SIGNATURE_SIZE, outp); + if (namelen > 0) { + MEMCPY(outp, name, namelen); + } + + ppp_write(pcb, p); +} + +#ifdef USE_SRP +/* + * Format and send a SRP EAP Response message. + */ +static void +eap_srp_response(esp, id, subtypenum, str, lenstr) +eap_state *esp; +u_char id; +u_char subtypenum; +u_char *str; +int lenstr; +{ + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; + u_char *outp; + int msglen; + + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + pcb->eap.es_client.ea_id = id; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(subtypenum, outp); + if (lenstr > 0) { + MEMCPY(outp, str, lenstr); + } + + ppp_write(pcb, p); +} + +/* + * Format and send a SRP EAP Client Validator Response message. + */ +static void +eap_srpval_response(esp, id, flags, str) +eap_state *esp; +u_char id; +u32_t flags; +u_char *str; +{ + ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; + struct pbuf *p; + u_char *outp; + int msglen; + + msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + + SHA_DIGESTSIZE; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + pcb->eap.es_client.ea_id = id; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_SRP, outp); + PUTCHAR(EAPSRP_CVALIDATOR, outp); + PUTLONG(flags, outp); + MEMCPY(outp, str, SHA_DIGESTSIZE); + + ppp_write(pcb, p); +} +#endif /* USE_SRP */ + +static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { + struct pbuf *p; + u_char *outp; + int msglen; + + msglen = EAP_HEADERLEN + 2 * sizeof (u_char); + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + pcb->eap.es_client.ea_id = id; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_NAK, outp); + PUTCHAR(type, outp); + + ppp_write(pcb, p); +} + +#ifdef USE_SRP +static char * +name_of_pn_file() +{ + char *user, *path, *file; + struct passwd *pw; + size_t pl; + static bool pnlogged = 0; + + pw = getpwuid(getuid()); + if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { + errno = EINVAL; + return (NULL); + } + file = _PATH_PSEUDONYM; + pl = strlen(user) + strlen(file) + 2; + path = malloc(pl); + if (path == NULL) + return (NULL); + (void) slprintf(path, pl, "%s/%s", user, file); + if (!pnlogged) { + ppp_dbglog("pseudonym file: %s", path); + pnlogged = 1; + } + return (path); +} + +static int +open_pn_file(modebits) +mode_t modebits; +{ + char *path; + int fd, err; + + if ((path = name_of_pn_file()) == NULL) + return (-1); + fd = open(path, modebits, S_IRUSR | S_IWUSR); + err = errno; + free(path); + errno = err; + return (fd); +} + +static void +remove_pn_file() +{ + char *path; + + if ((path = name_of_pn_file()) != NULL) { + (void) unlink(path); + (void) free(path); + } +} + +static void +write_pseudonym(esp, inp, len, id) +eap_state *esp; +u_char *inp; +int len, id; +{ + u_char val; + u_char *datp, *digp; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + int dsize, fd, olen = len; + + /* + * Do the decoding by working backwards. This eliminates the need + * to save the decoded output in a separate buffer. + */ + val = id; + while (len > 0) { + if ((dsize = len % SHA_DIGESTSIZE) == 0) + dsize = SHA_DIGESTSIZE; + len -= dsize; + datp = inp + len; + SHA1Init(&ctxt); + SHA1Update(&ctxt, &val, 1); + SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN); + if (len > 0) { + SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); + } else { + SHA1Update(&ctxt, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); + } + SHA1Final(dig, &ctxt); + for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) + *datp++ ^= *digp; + } + + /* Now check that the result is sane */ + if (olen <= 0 || *inp + 1 > olen) { + ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); + return; + } + + /* Save it away */ + fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) { + ppp_dbglog("EAP: error saving pseudonym: %m"); + return; + } + len = write(fd, inp + 1, *inp); + if (close(fd) != -1 && len == *inp) { + ppp_dbglog("EAP: saved pseudonym"); + pcb->eap.es_usedpseudo = 0; + } else { + ppp_dbglog("EAP: failed to save pseudonym"); + remove_pn_file(); + } +} +#endif /* USE_SRP */ + +/* + * eap_request - Receive EAP Request message (client mode). + */ +static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { + u_char typenum; + u_char vallen; + int secret_len; + char secret[MAXWORDLEN]; + char rhostname[256]; + md5_context mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; +#ifdef USE_SRP + struct t_client *tc; + struct t_num sval, gval, Nval, *Ap, Bval; + u_char vals[2]; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; + int fd; +#endif /* USE_SRP */ + + /* + * Note: we update es_client.ea_id *only if* a Response + * message is being generated. Otherwise, we leave it the + * same for duplicate detection purposes. + */ + + pcb->eap.es_client.ea_requests++; + if (pcb->settings.eap_allow_req != 0 && + pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) { + ppp_info("EAP: received too many Request messages"); + if (pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + } + auth_withpeer_fail(pcb, PPP_EAP); + return; + } + + if (len <= 0) { + ppp_error("EAP: empty Request message discarded"); + return; + } + + GETCHAR(typenum, inp); + len--; + + switch (typenum) { + case EAPT_IDENTITY: + if (len > 0) + ppp_info("EAP: Identity prompt \"%.*q\"", len, inp); +#ifdef USE_SRP + if (pcb->eap.es_usepseudo && + (pcb->eap.es_usedpseudo == 0 || + (pcb->eap.es_usedpseudo == 1 && + id == pcb->eap.es_client.ea_id))) { + pcb->eap.es_usedpseudo = 1; + /* Try to get a pseudonym */ + if ((fd = open_pn_file(O_RDONLY)) >= 0) { + strcpy(rhostname, SRP_PSEUDO_ID); + len = read(fd, rhostname + SRP_PSEUDO_LEN, + sizeof (rhostname) - SRP_PSEUDO_LEN); + /* XXX NAI unsupported */ + if (len > 0) { + eap_send_response(pcb, id, typenum, + rhostname, len + SRP_PSEUDO_LEN); + } + (void) close(fd); + if (len > 0) + break; + } + } + /* Stop using pseudonym now. */ + if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) { + remove_pn_file(); + pcb->eap.es_usedpseudo = 2; + } +#endif /* USE_SRP */ + eap_send_response(pcb, id, typenum, (u_char*)pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); + break; + + case EAPT_NOTIFICATION: + if (len > 0) + ppp_info("EAP: Notification \"%.*q\"", len, inp); + eap_send_response(pcb, id, typenum, NULL, 0); + break; + + case EAPT_NAK: + /* + * Avoid the temptation to send Response Nak in reply + * to Request Nak here. It can only lead to trouble. + */ + ppp_warn("EAP: unexpected Nak in Request; ignored"); + /* Return because we're waiting for something real. */ + return; + + case EAPT_MD5CHAP: + if (len < 1) { + ppp_error("EAP: received MD5-Challenge with no data"); + /* Bogus request; wait for something real. */ + return; + } + GETCHAR(vallen, inp); + len--; + if (vallen < 8 || vallen > len) { + ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)", + vallen, len); + /* Try something better. */ + eap_send_nak(pcb, id, EAPT_SRP); + break; + } + + /* Not so likely to happen. */ + if (vallen >= len + sizeof (rhostname)) { + ppp_dbglog("EAP: trimming really long peer name down"); + MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); + rhostname[sizeof (rhostname) - 1] = '\0'; + } else { + MEMCPY(rhostname, inp + vallen, len - vallen); + rhostname[len - vallen] = '\0'; + } + +#if PPP_REMOTENAME + /* In case the remote doesn't give us his name. */ + if (pcb->settings.explicit_remote || + (pcb->settings.remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname)); +#endif /* PPP_REMOTENAME */ + + /* + * Get the secret for authenticating ourselves with + * the specified host. + */ + if (!get_secret(pcb, pcb->eap.es_client.ea_name, + rhostname, secret, &secret_len, 0)) { + ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname); + eap_send_nak(pcb, id, EAPT_SRP); + break; + } + md5_starts(&mdContext); + typenum = id; + md5_update(&mdContext, &typenum, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); + BZERO(secret, sizeof (secret)); + md5_update(&mdContext, inp, vallen); + md5_finish(&mdContext, hash); + eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); + break; + +#ifdef USE_SRP + case EAPT_SRP: + if (len < 1) { + ppp_error("EAP: received empty SRP Request"); + /* Bogus request; wait for something real. */ + return; + } + + /* Get subtype */ + GETCHAR(vallen, inp); + len--; + switch (vallen) { + case EAPSRP_CHALLENGE: + tc = NULL; + if (pcb->eap.es_client.ea_session != NULL) { + tc = (struct t_client *)pcb->eap.es_client. + ea_session; + /* + * If this is a new challenge, then start + * over with a new client session context. + * Otherwise, just resend last response. + */ + if (id != pcb->eap.es_client.ea_id) { + t_clientclose(tc); + pcb->eap.es_client.ea_session = NULL; + tc = NULL; + } + } + /* No session key just yet */ + pcb->eap.es_client.ea_skey = NULL; + if (tc == NULL) { + GETCHAR(vallen, inp); + len--; + if (vallen >= len) { + ppp_error("EAP: badly-formed SRP Challenge" + " (name)"); + /* Ignore badly-formed messages */ + return; + } + MEMCPY(rhostname, inp, vallen); + rhostname[vallen] = '\0'; + INCPTR(vallen, inp); + len -= vallen; + + /* + * In case the remote doesn't give us his name, + * use configured name. + */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == 0)) { + strlcpy(rhostname, remote_name, + sizeof (rhostname)); + } + + if (pcb->eap.es_client.ea_peer != NULL) + free(pcb->eap.es_client.ea_peer); + pcb->eap.es_client.ea_peer = strdup(rhostname); + pcb->eap.es_client.ea_peerlen = strlen(rhostname); + + GETCHAR(vallen, inp); + len--; + if (vallen >= len) { + ppp_error("EAP: badly-formed SRP Challenge" + " (s)"); + /* Ignore badly-formed messages */ + return; + } + sval.data = inp; + sval.len = vallen; + INCPTR(vallen, inp); + len -= vallen; + + GETCHAR(vallen, inp); + len--; + if (vallen > len) { + ppp_error("EAP: badly-formed SRP Challenge" + " (g)"); + /* Ignore badly-formed messages */ + return; + } + /* If no generator present, then use value 2 */ + if (vallen == 0) { + gval.data = (u_char *)"\002"; + gval.len = 1; + } else { + gval.data = inp; + gval.len = vallen; + } + INCPTR(vallen, inp); + len -= vallen; + + /* + * If no modulus present, then use well-known + * value. + */ + if (len == 0) { + Nval.data = (u_char *)wkmodulus; + Nval.len = sizeof (wkmodulus); + } else { + Nval.data = inp; + Nval.len = len; + } + tc = t_clientopen(pcb->eap.es_client.ea_name, + &Nval, &gval, &sval); + if (tc == NULL) { + eap_send_nak(pcb, id, EAPT_MD5CHAP); + break; + } + pcb->eap.es_client.ea_session = (void *)tc; + + /* Add Challenge ID & type to verifier */ + vals[0] = id; + vals[1] = EAPT_SRP; + t_clientaddexdata(tc, vals, 2); + } + Ap = t_clientgenexp(tc); + eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, + Ap->len); + break; + + case EAPSRP_SKEY: + tc = (struct t_client *)pcb->eap.es_client.ea_session; + if (tc == NULL) { + ppp_warn("EAP: peer sent Subtype 2 without 1"); + eap_send_nak(pcb, id, EAPT_MD5CHAP); + break; + } + if (pcb->eap.es_client.ea_skey != NULL) { + /* + * ID number should not change here. Warn + * if it does (but otherwise ignore). + */ + if (id != pcb->eap.es_client.ea_id) { + ppp_warn("EAP: ID changed from %d to %d " + "in SRP Subtype 2 rexmit", + pcb->eap.es_client.ea_id, id); + } + } else { + if (get_srp_secret(pcb->eap.es_unit, + pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_peer, secret, 0) == 0) { + /* + * Can't work with this peer because + * the secret is missing. Just give + * up. + */ + eap_send_nak(pcb, id, EAPT_MD5CHAP); + break; + } + Bval.data = inp; + Bval.len = len; + t_clientpasswd(tc, secret); + BZERO(secret, sizeof (secret)); + pcb->eap.es_client.ea_skey = + t_clientgetkey(tc, &Bval); + if (pcb->eap.es_client.ea_skey == NULL) { + /* Server is rogue; stop now */ + ppp_error("EAP: SRP server is rogue"); + goto client_failure; + } + } + eap_srpval_response(esp, id, SRPVAL_EBIT, + t_clientresponse(tc)); + break; + + case EAPSRP_SVALIDATOR: + tc = (struct t_client *)pcb->eap.es_client.ea_session; + if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) { + ppp_warn("EAP: peer sent Subtype 3 without 1/2"); + eap_send_nak(pcb, id, EAPT_MD5CHAP); + break; + } + /* + * If we're already open, then this ought to be a + * duplicate. Otherwise, check that the server is + * who we think it is. + */ + if (pcb->eap.es_client.ea_state == eapOpen) { + if (id != pcb->eap.es_client.ea_id) { + ppp_warn("EAP: ID changed from %d to %d " + "in SRP Subtype 3 rexmit", + pcb->eap.es_client.ea_id, id); + } + } else { + len -= sizeof (u32_t) + SHA_DIGESTSIZE; + if (len < 0 || t_clientverify(tc, inp + + sizeof (u32_t)) != 0) { + ppp_error("EAP: SRP server verification " + "failed"); + goto client_failure; + } + GETLONG(pcb->eap.es_client.ea_keyflags, inp); + /* Save pseudonym if user wants it. */ + if (len > 0 && pcb->eap.es_usepseudo) { + INCPTR(SHA_DIGESTSIZE, inp); + write_pseudonym(esp, inp, len, id); + } + } + /* + * We've verified our peer. We're now mostly done, + * except for waiting on the regular EAP Success + * message. + */ + eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); + break; + + case EAPSRP_LWRECHALLENGE: + if (len < 4) { + ppp_warn("EAP: malformed Lightweight rechallenge"); + return; + } + SHA1Init(&ctxt); + vals[0] = id; + SHA1Update(&ctxt, vals, 1); + SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, inp, len); + SHA1Update(&ctxt, pcb->eap.es_client.ea_name, + pcb->eap.es_client.ea_namelen); + SHA1Final(dig, &ctxt); + eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, + SHA_DIGESTSIZE); + break; + + default: + ppp_error("EAP: unknown SRP Subtype %d", vallen); + eap_send_nak(pcb, id, EAPT_MD5CHAP); + break; + } + break; +#endif /* USE_SRP */ + + default: + ppp_info("EAP: unknown authentication type %d; Naking", typenum); + eap_send_nak(pcb, id, EAPT_SRP); + break; + } + + if (pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + TIMEOUT(eap_client_timeout, pcb, + pcb->settings.eap_req_time); + } + return; + +#ifdef USE_SRP +client_failure: + pcb->eap.es_client.ea_state = eapBadAuth; + if (pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } + pcb->eap.es_client.ea_session = NULL; + t_clientclose(tc); + auth_withpeer_fail(pcb, PPP_EAP); +#endif /* USE_SRP */ +} + +#if PPP_SERVER +/* FIXME: remove malloc() and free() */ +/* + * eap_response - Receive EAP Response message (server mode). + */ +static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { + u_char typenum; + u_char vallen; + int secret_len; + char secret[MAXSECRETLEN]; + char rhostname[256]; + md5_context mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; +#ifdef USE_SRP + struct t_server *ts; + struct t_num A; + SHA1_CTX ctxt; + u_char dig[SHA_DIGESTSIZE]; +#endif /* USE_SRP */ + + if (pcb->eap.es_server.ea_id != id) { + ppp_dbglog("EAP: discarding Response %d; expected ID %d", id, + pcb->eap.es_server.ea_id); + return; + } + + pcb->eap.es_server.ea_responses++; + + if (len <= 0) { + ppp_error("EAP: empty Response message discarded"); + return; + } + + GETCHAR(typenum, inp); + len--; + + switch (typenum) { + case EAPT_IDENTITY: + if (pcb->eap.es_server.ea_state != eapIdentify) { + ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len, + inp); + break; + } + ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); + if (pcb->eap.es_server.ea_peer != NULL +#if PPP_REMOTENAME + && pcb->eap.es_server.ea_peer != pcb->remote_name +#endif /* PPP_REMOTENAME */ + ) + free(pcb->eap.es_server.ea_peer); + pcb->eap.es_server.ea_peer = (char*)malloc(len + 1); + if (pcb->eap.es_server.ea_peer == NULL) { + pcb->eap.es_server.ea_peerlen = 0; + eap_figure_next_state(pcb, 1); + break; + } + MEMCPY(pcb->eap.es_server.ea_peer, inp, len); + pcb->eap.es_server.ea_peer[len] = '\0'; + pcb->eap.es_server.ea_peerlen = len; + eap_figure_next_state(pcb, 0); + break; + + case EAPT_NOTIFICATION: + ppp_dbglog("EAP unexpected Notification; response discarded"); + break; + + case EAPT_NAK: + if (len < 1) { + ppp_info("EAP: Nak Response with no suggested protocol"); + eap_figure_next_state(pcb, 1); + break; + } + + GETCHAR(vallen, inp); + len--; + + if ( +#if PPP_REMOTENAME + !pcb->explicit_remote && +#endif /* PPP_REMOTENAME */ + pcb->eap.es_server.ea_state == eapIdentify){ + /* Peer cannot Nak Identify Request */ + eap_figure_next_state(pcb, 1); + break; + } + + switch (vallen) { + case EAPT_SRP: + /* Run through SRP validator selection again. */ + pcb->eap.es_server.ea_state = eapIdentify; + eap_figure_next_state(pcb, 0); + break; + + case EAPT_MD5CHAP: + pcb->eap.es_server.ea_state = eapMD5Chall; + break; + + default: + ppp_dbglog("EAP: peer requesting unknown Type %d", vallen); + switch (pcb->eap.es_server.ea_state) { + case eapSRP1: + case eapSRP2: + case eapSRP3: + pcb->eap.es_server.ea_state = eapMD5Chall; + break; + case eapMD5Chall: + case eapSRP4: + pcb->eap.es_server.ea_state = eapIdentify; + eap_figure_next_state(pcb, 0); + break; + default: + break; + } + break; + } + break; + + case EAPT_MD5CHAP: + if (pcb->eap.es_server.ea_state != eapMD5Chall) { + ppp_error("EAP: unexpected MD5-Response"); + eap_figure_next_state(pcb, 1); + break; + } + if (len < 1) { + ppp_error("EAP: received MD5-Response with no data"); + eap_figure_next_state(pcb, 1); + break; + } + GETCHAR(vallen, inp); + len--; + if (vallen != 16 || vallen > len) { + ppp_error("EAP: MD5-Response with bad length %d", vallen); + eap_figure_next_state(pcb, 1); + break; + } + + /* Not so likely to happen. */ + if (vallen >= len + sizeof (rhostname)) { + ppp_dbglog("EAP: trimming really long peer name down"); + MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); + rhostname[sizeof (rhostname) - 1] = '\0'; + } else { + MEMCPY(rhostname, inp + vallen, len - vallen); + rhostname[len - vallen] = '\0'; + } + +#if PPP_REMOTENAME + /* In case the remote doesn't give us his name. */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, remote_name, sizeof (rhostname)); +#endif /* PPP_REMOTENAME */ + + /* + * Get the secret for authenticating the specified + * host. + */ + if (!get_secret(pcb, rhostname, + pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { + ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); + eap_send_failure(pcb); + break; + } + md5_starts(&mdContext); + md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1); + md5_update(&mdContext, (u_char *)secret, secret_len); + BZERO(secret, sizeof (secret)); + md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); + md5_finish(&mdContext, hash); + if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { + eap_send_failure(pcb); + break; + } + pcb->eap.es_server.ea_type = EAPT_MD5CHAP; + eap_send_success(pcb); + eap_figure_next_state(pcb, 0); + if (pcb->eap.es_rechallenge != 0) + TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge); + break; + +#ifdef USE_SRP + case EAPT_SRP: + if (len < 1) { + ppp_error("EAP: empty SRP Response"); + eap_figure_next_state(pcb, 1); + break; + } + GETCHAR(typenum, inp); + len--; + switch (typenum) { + case EAPSRP_CKEY: + if (pcb->eap.es_server.ea_state != eapSRP1) { + ppp_error("EAP: unexpected SRP Subtype 1 Response"); + eap_figure_next_state(pcb, 1); + break; + } + A.data = inp; + A.len = len; + ts = (struct t_server *)pcb->eap.es_server.ea_session; + assert(ts != NULL); + pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A); + if (pcb->eap.es_server.ea_skey == NULL) { + /* Client's A value is bogus; terminate now */ + ppp_error("EAP: bogus A value from client"); + eap_send_failure(pcb); + } else { + eap_figure_next_state(pcb, 0); + } + break; + + case EAPSRP_CVALIDATOR: + if (pcb->eap.es_server.ea_state != eapSRP2) { + ppp_error("EAP: unexpected SRP Subtype 2 Response"); + eap_figure_next_state(pcb, 1); + break; + } + if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { + ppp_error("EAP: M1 length %d < %d", len, + sizeof (u32_t) + SHA_DIGESTSIZE); + eap_figure_next_state(pcb, 1); + break; + } + GETLONG(pcb->eap.es_server.ea_keyflags, inp); + ts = (struct t_server *)pcb->eap.es_server.ea_session; + assert(ts != NULL); + if (t_serververify(ts, inp)) { + ppp_info("EAP: unable to validate client identity"); + eap_send_failure(pcb); + break; + } + eap_figure_next_state(pcb, 0); + break; + + case EAPSRP_ACK: + if (pcb->eap.es_server.ea_state != eapSRP3) { + ppp_error("EAP: unexpected SRP Subtype 3 Response"); + eap_send_failure(esp); + break; + } + pcb->eap.es_server.ea_type = EAPT_SRP; + eap_send_success(pcb, esp); + eap_figure_next_state(pcb, 0); + if (pcb->eap.es_rechallenge != 0) + TIMEOUT(eap_rechallenge, pcb, + pcb->eap.es_rechallenge); + if (pcb->eap.es_lwrechallenge != 0) + TIMEOUT(srp_lwrechallenge, pcb, + pcb->eap.es_lwrechallenge); + break; + + case EAPSRP_LWRECHALLENGE: + if (pcb->eap.es_server.ea_state != eapSRP4) { + ppp_info("EAP: unexpected SRP Subtype 4 Response"); + return; + } + if (len != SHA_DIGESTSIZE) { + ppp_error("EAP: bad Lightweight rechallenge " + "response"); + return; + } + SHA1Init(&ctxt); + vallen = id; + SHA1Update(&ctxt, &vallen, 1); + SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, + SESSION_KEY_LEN); + SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen); + SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, + pcb->eap.es_server.ea_peerlen); + SHA1Final(dig, &ctxt); + if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { + ppp_error("EAP: failed Lightweight rechallenge"); + eap_send_failure(pcb); + break; + } + pcb->eap.es_server.ea_state = eapOpen; + if (pcb->eap.es_lwrechallenge != 0) + TIMEOUT(srp_lwrechallenge, esp, + pcb->eap.es_lwrechallenge); + break; + } + break; +#endif /* USE_SRP */ + + default: + /* This can't happen. */ + ppp_error("EAP: unknown Response type %d; ignored", typenum); + return; + } + + if (pcb->settings.eap_timeout_time > 0) { + UNTIMEOUT(eap_server_timeout, pcb); + } + + if (pcb->eap.es_server.ea_state != eapBadAuth && + pcb->eap.es_server.ea_state != eapOpen) { + pcb->eap.es_server.ea_id++; + eap_send_request(pcb); + } +} +#endif /* PPP_SERVER */ + +/* + * eap_success - Receive EAP Success message (client mode). + */ +static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { + LWIP_UNUSED_ARG(id); + + if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) { + ppp_dbglog("EAP unexpected success message in state %s (%d)", + eap_state_name(pcb->eap.es_client.ea_state), + pcb->eap.es_client.ea_state); + return; + } + + if (pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + } + + if (len > 0) { + /* This is odd. The spec doesn't allow for this. */ + PRINTMSG(inp, len); + } + + pcb->eap.es_client.ea_state = eapOpen; + auth_withpeer_success(pcb, PPP_EAP, 0); +} + +/* + * eap_failure - Receive EAP Failure message (client mode). + */ +static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { + LWIP_UNUSED_ARG(id); + + if (!eap_client_active(pcb)) { + ppp_dbglog("EAP unexpected failure message in state %s (%d)", + eap_state_name(pcb->eap.es_client.ea_state), + pcb->eap.es_client.ea_state); + } + + if (pcb->settings.eap_req_time > 0) { + UNTIMEOUT(eap_client_timeout, pcb); + } + + if (len > 0) { + /* This is odd. The spec doesn't allow for this. */ + PRINTMSG(inp, len); + } + + pcb->eap.es_client.ea_state = eapBadAuth; + + ppp_error("EAP: peer reports authentication failure"); + auth_withpeer_fail(pcb, PPP_EAP); +} + +/* + * eap_input - Handle received EAP message. + */ +static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { + u_char code, id; + int len; + + /* + * Parse header (code, id and length). If packet too short, + * drop it. + */ + if (inlen < EAP_HEADERLEN) { + ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < EAP_HEADERLEN || len > inlen) { + ppp_error("EAP: packet has illegal length field %d (%d..%d)", len, + EAP_HEADERLEN, inlen); + return; + } + len -= EAP_HEADERLEN; + + /* Dispatch based on message code */ + switch (code) { + case EAP_REQUEST: + eap_request(pcb, inp, id, len); + break; + +#if PPP_SERVER + case EAP_RESPONSE: + eap_response(pcb, inp, id, len); + break; +#endif /* PPP_SERVER */ + + case EAP_SUCCESS: + eap_success(pcb, inp, id, len); + break; + + case EAP_FAILURE: + eap_failure(pcb, inp, id, len); + break; + + default: /* XXX Need code reject */ + /* Note: it's not legal to send EAP Nak here. */ + ppp_warn("EAP: unknown code %d received", code); + break; + } +} + +#if PRINTPKT_SUPPORT +/* + * eap_printpkt - print the contents of an EAP packet. + */ +static const char *eap_codenames[] = { + "Request", "Response", "Success", "Failure" +}; + +static const char *eap_typenames[] = { + "Identity", "Notification", "Nak", "MD5-Challenge", + "OTP", "Generic-Token", NULL, NULL, + "RSA", "DSS", "KEA", "KEA-Validate", + "TLS", "Defender", "Windows 2000", "Arcot", + "Cisco", "Nokia", "SRP" +}; + +static int eap_printpkt(u_char *inp, int inlen, void (*printer) (void *, const char *, ...), void *arg) { + int code, id, len, rtype, vallen; + u_char *pstart; + u32_t uval; + + if (inlen < EAP_HEADERLEN) + return (0); + pstart = inp; + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < EAP_HEADERLEN || len > inlen) + return (0); + + if (code >= 1 && code <= (int)sizeof(eap_codenames) / (int)sizeof(char *)) + printer(arg, " %s", eap_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= EAP_HEADERLEN; + switch (code) { + case EAP_REQUEST: + if (len < 1) { + printer(arg, " "); + break; + } + GETCHAR(rtype, inp); + len--; + if (rtype >= 1 && + rtype <= (int)sizeof (eap_typenames) / (int)sizeof (char *)) + printer(arg, " %s", eap_typenames[rtype-1]); + else + printer(arg, " type=0x%x", rtype); + switch (rtype) { + case EAPT_IDENTITY: + case EAPT_NOTIFICATION: + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_MD5CHAP: + if (len <= 0) + break; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_SRP: + if (len < 3) + goto truncated; + GETCHAR(vallen, inp); + len--; + printer(arg, "-%d", vallen); + switch (vallen) { + case EAPSRP_CHALLENGE: + GETCHAR(vallen, inp); + len--; + if (vallen >= len) + goto truncated; + if (vallen > 0) { + printer(arg, " "); + } else { + printer(arg, " "); + } + INCPTR(vallen, inp); + len -= vallen; + GETCHAR(vallen, inp); + len--; + if (vallen >= len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + if (vallen == 0) { + printer(arg, " "); + } else { + printer(arg, " ", vallen, inp); + } + INCPTR(vallen, inp); + len -= vallen; + if (len == 0) { + printer(arg, " "); + } else { + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPSRP_SKEY: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_SVALIDATOR: + if (len < (int)sizeof (u32_t)) + break; + GETLONG(uval, inp); + len -= sizeof (u32_t); + if (uval & SRPVAL_EBIT) { + printer(arg, " E"); + uval &= ~SRPVAL_EBIT; + } + if (uval != 0) { + printer(arg, " f<%X>", uval); + } + if ((vallen = len) > SHA_DIGESTSIZE) + vallen = SHA_DIGESTSIZE; + printer(arg, " ", len, inp, + len < SHA_DIGESTSIZE ? "?" : ""); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPSRP_LWRECHALLENGE: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + default: + break; + } + break; + default: + break; + } + break; + + case EAP_RESPONSE: + if (len < 1) + break; + GETCHAR(rtype, inp); + len--; + if (rtype >= 1 && + rtype <= (int)sizeof (eap_typenames) / (int)sizeof (char *)) + printer(arg, " %s", eap_typenames[rtype-1]); + else + printer(arg, " type=0x%x", rtype); + switch (rtype) { + case EAPT_IDENTITY: + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } + break; + + case EAPT_NAK: + if (len <= 0) { + printer(arg, " "); + break; + } + GETCHAR(rtype, inp); + len--; + printer(arg, " = 1 && + rtype < (int)sizeof (eap_typenames) / (int)sizeof (char *)) + printer(arg, " (%s)", eap_typenames[rtype-1]); + printer(arg, ">"); + break; + + case EAPT_MD5CHAP: + if (len <= 0) { + printer(arg, " "); + break; + } + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + printer(arg, " ", vallen, inp); + INCPTR(vallen, inp); + len -= vallen; + if (len > 0) { + printer(arg, " "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, " "); + } + break; + + case EAPT_SRP: + if (len < 1) + goto truncated; + GETCHAR(vallen, inp); + len--; + printer(arg, "-%d", vallen); + switch (vallen) { + case EAPSRP_CKEY: + printer(arg, " ", len, inp); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_CVALIDATOR: + if (len < (int)sizeof (u32_t)) + break; + GETLONG(uval, inp); + len -= sizeof (u32_t); + if (uval & SRPVAL_EBIT) { + printer(arg, " E"); + uval &= ~SRPVAL_EBIT; + } + if (uval != 0) { + printer(arg, " f<%X>", uval); + } + printer(arg, " ", len, inp, + len == SHA_DIGESTSIZE ? "" : "?"); + INCPTR(len, inp); + len = 0; + break; + + case EAPSRP_ACK: + break; + + case EAPSRP_LWRECHALLENGE: + printer(arg, " ", len, inp, + len == SHA_DIGESTSIZE ? "" : "?"); + if ((vallen = len) > SHA_DIGESTSIZE) + vallen = SHA_DIGESTSIZE; + INCPTR(vallen, inp); + len -= vallen; + break; + default: + break; + } + break; + default: + break; + } + break; + + case EAP_SUCCESS: /* No payload expected for these! */ + case EAP_FAILURE: + default: + break; + + truncated: + printer(arg, " "); + break; + } + + if (len > 8) + printer(arg, "%8B...", inp); + else if (len > 0) + printer(arg, "%.*B", len, inp); + INCPTR(len, inp); + + return (inp - pstart); +} +#endif /* PRINTPKT_SUPPORT */ + +#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ecp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ecp.c new file mode 100644 index 0000000..728fb5f --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ecp.c @@ -0,0 +1,188 @@ +/* + * ecp.c - PPP Encryption Control Protocol. + * + * Copyright (c) 2002 Google, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Derived from ccp.c, which is: + * + * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/ecp.h" + +#if PPP_OPTIONS +static option_t ecp_option_list[] = { + { "noecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation" }, + { "-ecp", o_bool, &ecp_protent.enabled_flag, + "Disable ECP negotiation", OPT_ALIAS }, + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points from main code. + */ +static void ecp_init (int unit); +/* +static void ecp_open (int unit); +static void ecp_close (int unit, char *); +static void ecp_lowerup (int unit); +static void ecp_lowerdown (int); +static void ecp_input (int unit, u_char *pkt, int len); +static void ecp_protrej (int unit); +*/ +#if PRINTPKT_SUPPORT +static int ecp_printpkt (u_char *pkt, int len, + void (*printer) (void *, char *, ...), + void *arg); +#endif /* PRINTPKT_SUPPORT */ +/* +static void ecp_datainput (int unit, u_char *pkt, int len); +*/ + +const struct protent ecp_protent = { + PPP_ECP, + ecp_init, + NULL, /* ecp_input, */ + NULL, /* ecp_protrej, */ + NULL, /* ecp_lowerup, */ + NULL, /* ecp_lowerdown, */ + NULL, /* ecp_open, */ + NULL, /* ecp_close, */ +#if PRINTPKT_SUPPORT + ecp_printpkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, /* ecp_datainput, */ + 0, +#if PRINTPKT_SUPPORT + "ECP", + "Encrypted", +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + ecp_option_list, + NULL, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, + NULL +#endif /* DEMAND_SUPPORT */ +}; + +fsm ecp_fsm[NUM_PPP]; +ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ +ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ +ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ +ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ + +static const fsm_callbacks ecp_callbacks = { + NULL, /* ecp_resetci, */ + NULL, /* ecp_cilen, */ + NULL, /* ecp_addci, */ + NULL, /* ecp_ackci, */ + NULL, /* ecp_nakci, */ + NULL, /* ecp_rejci, */ + NULL, /* ecp_reqci, */ + NULL, /* ecp_up, */ + NULL, /* ecp_down, */ + NULL, + NULL, + NULL, + NULL, + NULL, /* ecp_extcode, */ + "ECP" +}; + +/* + * ecp_init - initialize ECP. + */ +static void +ecp_init(unit) + int unit; +{ + fsm *f = &ecp_fsm[unit]; + + f->unit = unit; + f->protocol = PPP_ECP; + f->callbacks = &ecp_callbacks; + fsm_init(f); + + memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); + memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); + +} + + +#if PRINTPKT_SUPPORT +static int +ecp_printpkt(p, plen, printer, arg) + u_char *p; + int plen; + void (*printer) (void *, char *, ...); + void *arg; +{ + return 0; +} +#endif /* PRINTPKT_SUPPORT */ + +#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eui64.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eui64.c new file mode 100644 index 0000000..e23a34e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/eui64.c @@ -0,0 +1,56 @@ +/* + * eui64.c - EUI64 routines for IPv6CP. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/eui64.h" + +/* + * eui64_ntoa - Make an ascii representation of an interface identifier + */ +char *eui64_ntoa(eui64_t e) { + static char buf[32]; + + snprintf(buf, 32, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", + e.e8[0], e.e8[1], e.e8[2], e.e8[3], + e.e8[4], e.e8[5], e.e8[6], e.e8[7]); + return buf; +} + +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/fsm.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/fsm.c new file mode 100644 index 0000000..71f2c95 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/fsm.c @@ -0,0 +1,798 @@ +/* + * fsm.c - {Link, IP} Control Protocol Finite State Machine. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/* + * TODO: + * Randomize fsm id on link/init. + * Deal with variable outgoing MTU. + */ + +#if 0 /* UNUSED */ +#include +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" + +static void fsm_timeout (void *); +static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len); +static void fsm_rconfack(fsm *f, int id, u_char *inp, int len); +static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len); +static void fsm_rtermreq(fsm *f, int id, u_char *p, int len); +static void fsm_rtermack(fsm *f); +static void fsm_rcoderej(fsm *f, u_char *inp, int len); +static void fsm_sconfreq(fsm *f, int retransmit); + +#define PROTO_NAME(f) ((f)->callbacks->proto_name) + +/* + * fsm_init - Initialize fsm. + * + * Initialize fsm state. + */ +void fsm_init(fsm *f) { + ppp_pcb *pcb = f->pcb; + f->state = PPP_FSM_INITIAL; + f->flags = 0; + f->id = 0; /* XXX Start with random id? */ + f->maxnakloops = pcb->settings.fsm_max_nak_loops; + f->term_reason_len = 0; +} + + +/* + * fsm_lowerup - The lower layer is up. + */ +void fsm_lowerup(fsm *f) { + switch( f->state ){ + case PPP_FSM_INITIAL: + f->state = PPP_FSM_CLOSED; + break; + + case PPP_FSM_STARTING: + if( f->flags & OPT_SILENT ) + f->state = PPP_FSM_STOPPED; + else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = PPP_FSM_REQSENT; + } + break; + + default: + FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ + } +} + + +/* + * fsm_lowerdown - The lower layer is down. + * + * Cancel all timeouts and inform upper layers. + */ +void fsm_lowerdown(fsm *f) { + switch( f->state ){ + case PPP_FSM_CLOSED: + f->state = PPP_FSM_INITIAL; + break; + + case PPP_FSM_STOPPED: + f->state = PPP_FSM_STARTING; + if( f->callbacks->starting ) + (*f->callbacks->starting)(f); + break; + + case PPP_FSM_CLOSING: + f->state = PPP_FSM_INITIAL; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case PPP_FSM_STOPPING: + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + f->state = PPP_FSM_STARTING; + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + break; + + case PPP_FSM_OPENED: + if( f->callbacks->down ) + (*f->callbacks->down)(f); + f->state = PPP_FSM_STARTING; + break; + + default: + FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ + } +} + + +/* + * fsm_open - Link is allowed to come up. + */ +void fsm_open(fsm *f) { + switch( f->state ){ + case PPP_FSM_INITIAL: + f->state = PPP_FSM_STARTING; + if( f->callbacks->starting ) + (*f->callbacks->starting)(f); + break; + + case PPP_FSM_CLOSED: + if( f->flags & OPT_SILENT ) + f->state = PPP_FSM_STOPPED; + else { + /* Send an initial configure-request */ + fsm_sconfreq(f, 0); + f->state = PPP_FSM_REQSENT; + } + break; + + case PPP_FSM_CLOSING: + f->state = PPP_FSM_STOPPING; + /* fall through */ + /* no break */ + case PPP_FSM_STOPPED: + case PPP_FSM_OPENED: + if( f->flags & OPT_RESTART ){ + fsm_lowerdown(f); + fsm_lowerup(f); + } + break; + default: + break; + } +} + +/* + * terminate_layer - Start process of shutting down the FSM + * + * Cancel any timeout running, notify upper layers we're done, and + * send a terminate-request message as configured. + */ +static void terminate_layer(fsm *f, int nextstate) { + ppp_pcb *pcb = f->pcb; + + if( f->state != PPP_FSM_OPENED ) + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + else if( f->callbacks->down ) + (*f->callbacks->down)(f); /* Inform upper layers we're down */ + + /* Init restart counter and send Terminate-Request */ + f->retransmits = pcb->settings.fsm_max_term_transmits; + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + + if (f->retransmits == 0) { + /* + * User asked for no terminate requests at all; just close it. + * We've already fired off one Terminate-Request just to be nice + * to the peer, but we're not going to wait for a reply. + */ + f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + return; + } + + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); + --f->retransmits; + + f->state = nextstate; +} + +/* + * fsm_close - Start closing connection. + * + * Cancel timeouts and either initiate close or possibly go directly to + * the PPP_FSM_CLOSED state. + */ +void fsm_close(fsm *f, const char *reason) { + f->term_reason = reason; + f->term_reason_len = (reason == NULL? 0: LWIP_MIN(strlen(reason), 0xFF) ); + switch( f->state ){ + case PPP_FSM_STARTING: + f->state = PPP_FSM_INITIAL; + break; + case PPP_FSM_STOPPED: + f->state = PPP_FSM_CLOSED; + break; + case PPP_FSM_STOPPING: + f->state = PPP_FSM_CLOSING; + break; + + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + case PPP_FSM_OPENED: + terminate_layer(f, PPP_FSM_CLOSING); + break; + default: + break; + } +} + + +/* + * fsm_timeout - Timeout expired. + */ +static void fsm_timeout(void *arg) { + fsm *f = (fsm *) arg; + ppp_pcb *pcb = f->pcb; + + switch (f->state) { + case PPP_FSM_CLOSING: + case PPP_FSM_STOPPING: + if( f->retransmits <= 0 ){ + /* + * We've waited for an ack long enough. Peer probably heard us. + */ + f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + } else { + /* Send Terminate-Request */ + fsm_sdata(f, TERMREQ, f->reqid = ++f->id, + (u_char *) f->term_reason, f->term_reason_len); + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); + --f->retransmits; + } + break; + + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + if (f->retransmits <= 0) { + ppp_warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); + f->state = PPP_FSM_STOPPED; + if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) + (*f->callbacks->finished)(f); + + } else { + /* Retransmit the configure-request */ + if (f->callbacks->retransmit) + (*f->callbacks->retransmit)(f); + fsm_sconfreq(f, 1); /* Re-send Configure-Request */ + if( f->state == PPP_FSM_ACKRCVD ) + f->state = PPP_FSM_REQSENT; + } + break; + + default: + FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); + /* no break */ + } +} + + +/* + * fsm_input - Input packet. + */ +void fsm_input(fsm *f, u_char *inpacket, int l) { + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (l < HEADERLEN) { + FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < HEADERLEN) { + FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); + return; + } + if (len > l) { + FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); + return; + } + len -= HEADERLEN; /* subtract header length */ + + if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){ + FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", + f->protocol, f->state)); + return; + } + + /* + * Action depends on code. + */ + switch (code) { + case CONFREQ: + fsm_rconfreq(f, id, inp, len); + break; + + case CONFACK: + fsm_rconfack(f, id, inp, len); + break; + + case CONFNAK: + case CONFREJ: + fsm_rconfnakrej(f, code, id, inp, len); + break; + + case TERMREQ: + fsm_rtermreq(f, id, inp, len); + break; + + case TERMACK: + fsm_rtermack(f); + break; + + case CODEREJ: + fsm_rcoderej(f, inp, len); + break; + + default: + if( !f->callbacks->extcode + || !(*f->callbacks->extcode)(f, code, id, inp, len) ) + fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); + break; + } +} + + +/* + * fsm_rconfreq - Receive Configure-Request. + */ +static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { + int code, reject_if_disagree; + + switch( f->state ){ + case PPP_FSM_CLOSED: + /* Go away, we're closed */ + fsm_sdata(f, TERMACK, id, NULL, 0); + return; + case PPP_FSM_CLOSING: + case PPP_FSM_STOPPING: + return; + + case PPP_FSM_OPENED: + /* Go down and restart negotiation */ + if( f->callbacks->down ) + (*f->callbacks->down)(f); /* Inform upper layers */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = PPP_FSM_REQSENT; + break; + + case PPP_FSM_STOPPED: + /* Negotiation started by our peer */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = PPP_FSM_REQSENT; + break; + default: + break; + } + + /* + * Pass the requested configuration options + * to protocol-specific code for checking. + */ + if (f->callbacks->reqci){ /* Check CI */ + reject_if_disagree = (f->nakloops >= f->maxnakloops); + code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); + } else if (len) + code = CONFREJ; /* Reject all CI */ + else + code = CONFACK; + + /* send the Ack, Nak or Rej to the peer */ + fsm_sdata(f, code, id, inp, len); + + if (code == CONFACK) { + if (f->state == PPP_FSM_ACKRCVD) { + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = PPP_FSM_OPENED; + if (f->callbacks->up) + (*f->callbacks->up)(f); /* Inform upper layers */ + } else + f->state = PPP_FSM_ACKSENT; + f->nakloops = 0; + + } else { + /* we sent CONFACK or CONFREJ */ + if (f->state != PPP_FSM_ACKRCVD) + f->state = PPP_FSM_REQSENT; + if( code == CONFNAK ) + ++f->nakloops; + } +} + + +/* + * fsm_rconfack - Receive Configure-Ack. + */ +static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; + + if (id != f->reqid || f->seen_ack) /* Expected id? */ + return; /* Nope, toss... */ + if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): + (len == 0)) ){ + /* Ack is bad - ignore it */ + ppp_error("Received bad configure-ack: %P", inp, len); + return; + } + f->seen_ack = 1; + f->rnakloops = 0; + + switch (f->state) { + case PPP_FSM_CLOSED: + case PPP_FSM_STOPPED: + fsm_sdata(f, TERMACK, id, NULL, 0); + break; + + case PPP_FSM_REQSENT: + f->state = PPP_FSM_ACKRCVD; + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; + break; + + case PPP_FSM_ACKRCVD: + /* Huh? an extra valid Ack? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = PPP_FSM_REQSENT; + break; + + case PPP_FSM_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + f->state = PPP_FSM_OPENED; + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; + if (f->callbacks->up) + (*f->callbacks->up)(f); /* Inform upper layers */ + break; + + case PPP_FSM_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = PPP_FSM_REQSENT; + break; + default: + break; + } +} + + +/* + * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. + */ +static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { + int ret; + int treat_as_reject; + + if (id != f->reqid || f->seen_ack) /* Expected id? */ + return; /* Nope, toss... */ + + if (code == CONFNAK) { + ++f->rnakloops; + treat_as_reject = (f->rnakloops >= f->maxnakloops); + if (f->callbacks->nakci == NULL + || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { + ppp_error("Received bad configure-nak: %P", inp, len); + return; + } + } else { + f->rnakloops = 0; + if (f->callbacks->rejci == NULL + || !(ret = f->callbacks->rejci(f, inp, len))) { + ppp_error("Received bad configure-rej: %P", inp, len); + return; + } + } + + f->seen_ack = 1; + + switch (f->state) { + case PPP_FSM_CLOSED: + case PPP_FSM_STOPPED: + fsm_sdata(f, TERMACK, id, NULL, 0); + break; + + case PPP_FSM_REQSENT: + case PPP_FSM_ACKSENT: + /* They didn't agree to what we wanted - try another request */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + if (ret < 0) + f->state = PPP_FSM_STOPPED; /* kludge for stopping CCP */ + else + fsm_sconfreq(f, 0); /* Send Configure-Request */ + break; + + case PPP_FSM_ACKRCVD: + /* Got a Nak/reject when we had already had an Ack?? oh well... */ + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + fsm_sconfreq(f, 0); + f->state = PPP_FSM_REQSENT; + break; + + case PPP_FSM_OPENED: + /* Go down and restart negotiation */ + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + fsm_sconfreq(f, 0); /* Send initial Configure-Request */ + f->state = PPP_FSM_REQSENT; + break; + default: + break; + } +} + + +/* + * fsm_rtermreq - Receive Terminate-Req. + */ +static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + + switch (f->state) { + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + f->state = PPP_FSM_REQSENT; /* Start over but keep trying */ + break; + + case PPP_FSM_OPENED: + if (len > 0) { + ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); + } else + ppp_info("%s terminated by peer", PROTO_NAME(f)); + f->retransmits = 0; + f->state = PPP_FSM_STOPPING; + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); + break; + default: + break; + } + + fsm_sdata(f, TERMACK, id, NULL, 0); +} + + +/* + * fsm_rtermack - Receive Terminate-Ack. + */ +static void fsm_rtermack(fsm *f) { + switch (f->state) { + case PPP_FSM_CLOSING: + UNTIMEOUT(fsm_timeout, f); + f->state = PPP_FSM_CLOSED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + break; + case PPP_FSM_STOPPING: + UNTIMEOUT(fsm_timeout, f); + f->state = PPP_FSM_STOPPED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + break; + + case PPP_FSM_ACKRCVD: + f->state = PPP_FSM_REQSENT; + break; + + case PPP_FSM_OPENED: + if (f->callbacks->down) + (*f->callbacks->down)(f); /* Inform upper layers */ + fsm_sconfreq(f, 0); + f->state = PPP_FSM_REQSENT; + break; + default: + break; + } +} + + +/* + * fsm_rcoderej - Receive an Code-Reject. + */ +static void fsm_rcoderej(fsm *f, u_char *inp, int len) { + u_char code, id; + + if (len < HEADERLEN) { + FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + ppp_warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); + + if( f->state == PPP_FSM_ACKRCVD ) + f->state = PPP_FSM_REQSENT; +} + + +/* + * fsm_protreject - Peer doesn't speak this protocol. + * + * Treat this as a catastrophic error (RXJ-). + */ +void fsm_protreject(fsm *f) { + switch( f->state ){ + case PPP_FSM_CLOSING: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + /* no break */ + case PPP_FSM_CLOSED: + f->state = PPP_FSM_CLOSED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + break; + + case PPP_FSM_STOPPING: + case PPP_FSM_REQSENT: + case PPP_FSM_ACKRCVD: + case PPP_FSM_ACKSENT: + UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ + /* fall through */ + /* no break */ + case PPP_FSM_STOPPED: + f->state = PPP_FSM_STOPPED; + if( f->callbacks->finished ) + (*f->callbacks->finished)(f); + break; + + case PPP_FSM_OPENED: + terminate_layer(f, PPP_FSM_STOPPING); + break; + + default: + FSMDEBUG(("%s: Protocol-reject event in state %d!", + PROTO_NAME(f), f->state)); + /* no break */ + } +} + + +/* + * fsm_sconfreq - Send a Configure-Request. + */ +static void fsm_sconfreq(fsm *f, int retransmit) { + ppp_pcb *pcb = f->pcb; + struct pbuf *p; + u_char *outp; + int cilen; + + if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){ + /* Not currently negotiating - reset options */ + if( f->callbacks->resetci ) + (*f->callbacks->resetci)(f); + f->nakloops = 0; + f->rnakloops = 0; + } + + if( !retransmit ){ + /* New request - reset retransmission counter, use new ID */ + f->retransmits = pcb->settings.fsm_max_conf_req_transmits; + f->reqid = ++f->id; + } + + f->seen_ack = 0; + + /* + * Make up the request packet + */ + if( f->callbacks->cilen && f->callbacks->addci ){ + cilen = (*f->callbacks->cilen)(f); + if( cilen > pcb->peer_mru - HEADERLEN ) + cilen = pcb->peer_mru - HEADERLEN; + } else + cilen = 0; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + /* send the request to our peer */ + outp = (u_char*)p->payload; + MAKEHEADER(outp, f->protocol); + PUTCHAR(CONFREQ, outp); + PUTCHAR(f->reqid, outp); + PUTSHORT(cilen + HEADERLEN, outp); + if (cilen != 0) { + (*f->callbacks->addci)(f, outp, &cilen); + } + + ppp_write(pcb, p); + + /* start the retransmit timer */ + --f->retransmits; + TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); +} + + +/* + * fsm_sdata - Send some data. + * + * Used for all packets sent to our peer by this module. + */ +void fsm_sdata(fsm *f, u_char code, u_char id, u_char *data, int datalen) { + ppp_pcb *pcb = f->pcb; + struct pbuf *p; + u_char *outp; + int outlen; + + /* Adjust length to be smaller than MTU */ + if (datalen > pcb->peer_mru - HEADERLEN) + datalen = pcb->peer_mru - HEADERLEN; + outlen = datalen + HEADERLEN; + + p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; +/* if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) -- was only for fsm_sconfreq() */ + MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); + MAKEHEADER(outp, f->protocol); + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + ppp_write(pcb, p); +} + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipcp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipcp.c new file mode 100644 index 0000000..970e69e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipcp.c @@ -0,0 +1,2274 @@ +/* + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/* + * TODO: + */ + +#if 0 /* UNUSED */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" + +#if 0 /* UNUSED */ +/* global vars */ +u32_t netmask = 0; /* IP netmask to set on interface */ +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ +#endif /* UNUSED */ + +#if 0 /* moved to ppp_settings */ +bool noremoteip = 0; /* Let him have no IP address */ +#endif /* moved to ppp_setting */ + +#if 0 /* UNUSED */ +/* Hook for a plugin to know when IP protocol has come up */ +void (*ip_up_hook) (void) = NULL; + +/* Hook for a plugin to know when IP protocol has come down */ +void (*ip_down_hook) (void) = NULL; + +/* Hook for a plugin to choose the remote IP address */ +void (*ip_choose_hook) (u32_t *) = NULL; +#endif /* UNUSED */ + +#if PPP_NOTIFY +/* Notifiers for when IPCP goes up and down */ +struct notifier *ip_up_notifier = NULL; +struct notifier *ip_down_notifier = NULL; +#endif /* PPP_NOTIFY */ + +/* local vars */ +#if 0 /* moved to ppp_pcb */ +static int default_route_set[NUM_PPP]; /* Have set up a default route */ +static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ +static int ipcp_is_up; /* have called np_up() */ +static int ipcp_is_open; /* haven't called np_finished() */ +static bool ask_for_local; /* request our address from peer */ +#endif /* moved to ppp_pcb */ +#if 0 /* UNUSED */ +static char vj_value[8]; /* string form of vj option value */ +static char netmask_str[20]; /* string form of netmask value */ +#endif /* UNUSED */ + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipcp_resetci(fsm *f); /* Reset our CI */ +static int ipcp_cilen(fsm *f); /* Return length of our CI */ +static void ipcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ +static int ipcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject);/* Peer nak'd our CI */ +static int ipcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ +static void ipcp_up(fsm *f); /* We're UP */ +static void ipcp_down(fsm *f); /* We're DOWN */ +static void ipcp_finished(fsm *f); /* Don't need lower layer */ + +static const fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ + ipcp_resetci, /* Reset our Configuration Information */ + ipcp_cilen, /* Length of our Configuration Information */ + ipcp_addci, /* Add our Configuration Information */ + ipcp_ackci, /* ACK our Configuration Information */ + ipcp_nakci, /* NAK our Configuration Information */ + ipcp_rejci, /* Reject our Configuration Information */ + ipcp_reqci, /* Request peer's Configuration Information */ + ipcp_up, /* Called when fsm reaches OPENED state */ + ipcp_down, /* Called when fsm leaves OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + NULL, /* Called to handle protocol-specific codes */ + "IPCP" /* String name of protocol */ +}; + +/* + * Command-line options. + */ +#if PPP_OPTIONS +static int setvjslots (char **); +static int setdnsaddr (char **); +static int setwinsaddr (char **); +static int setnetmask (char **); +int setipaddr (char *, char **, int); + +static void printipaddr (option_t *, void (*)(void *, char *,...),void *); + +static option_t ipcp_option_list[] = { + { "noip", o_bool, &ipcp_protent.enabled_flag, + "Disable IP and IPCP" }, + { "-ip", o_bool, &ipcp_protent.enabled_flag, + "Disable IP and IPCP", OPT_ALIAS }, + + { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, + "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, + { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, + "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, + &ipcp_allowoptions[0].neg_vj }, + + { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, + "Disable VJ connection-ID compression", OPT_A2CLR, + &ipcp_allowoptions[0].cflag }, + { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, + "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, + &ipcp_allowoptions[0].cflag }, + + { "vj-max-slots", o_special, (void *)setvjslots, + "Set maximum VJ header slots", + OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, + + { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, + "Accept peer's address for us", 1 }, + { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, + "Accept peer's address for it", 1 }, + + { "ipparam", o_string, &ipparam, + "Set ip script parameter", OPT_PRIO }, + + { "noipdefault", o_bool, &disable_defaultip, + "Don't use name for default IP adrs", 1 }, + + { "ms-dns", 1, (void *)setdnsaddr, + "DNS address for the peer's use" }, + { "ms-wins", 1, (void *)setwinsaddr, + "Nameserver for SMB over TCP/IP for peer" }, + + { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, + "Set timeout for IPCP", OPT_PRIO }, + { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, + "Set max #xmits for term-reqs", OPT_PRIO }, + { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, + "Set max #xmits for conf-reqs", OPT_PRIO }, + { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, + "Set max #conf-naks for IPCP", OPT_PRIO }, + + { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, + "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, + { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, + "disable defaultroute option", OPT_A2CLR, + &ipcp_wantoptions[0].default_route }, + { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, + "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, + &ipcp_wantoptions[0].default_route }, + + { "replacedefaultroute", o_bool, + &ipcp_wantoptions[0].replace_default_route, + "Replace default route", 1 + }, + { "noreplacedefaultroute", o_bool, + &ipcp_allowoptions[0].replace_default_route, + "Never replace default route", OPT_A2COPY, + &ipcp_wantoptions[0].replace_default_route }, + { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, + "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, + { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, + "disable proxyarp option", OPT_A2CLR, + &ipcp_wantoptions[0].proxy_arp }, + { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, + "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, + &ipcp_wantoptions[0].proxy_arp }, + + { "usepeerdns", o_bool, &usepeerdns, + "Ask peer for DNS address(es)", 1 }, + + { "netmask", o_special, (void *)setnetmask, + "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, + + { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, + "Disable old-style IP-Addresses usage", OPT_A2CLR, + &ipcp_allowoptions[0].old_addrs }, + { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, + "Disable IP-Address usage", OPT_A2CLR, + &ipcp_allowoptions[0].neg_addr }, + + { "noremoteip", o_bool, &noremoteip, + "Allow peer to have no IP address", 1 }, + + { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, + "Don't send our IP address to peer", OPT_A2CLR, + &ipcp_wantoptions[0].old_addrs}, + + { "IP addresses", o_wild, (void *) &setipaddr, + "set local and remote IP addresses", + OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points from main code. + */ +static void ipcp_init(ppp_pcb *pcb); +static void ipcp_open(ppp_pcb *pcb); +static void ipcp_close(ppp_pcb *pcb, const char *reason); +static void ipcp_lowerup(ppp_pcb *pcb); +static void ipcp_lowerdown(ppp_pcb *pcb); +static void ipcp_input(ppp_pcb *pcb, u_char *p, int len); +static void ipcp_protrej(ppp_pcb *pcb); +#if PRINTPKT_SUPPORT +static int ipcp_printpkt(u_char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS +static void ip_check_options (void); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT +static int ip_demand_conf (int); +static int ip_active_pkt (u_char *, int); +#endif /* DEMAND_SUPPORT */ +#if 0 /* UNUSED */ +static void create_resolv (u32_t, u32_t); +#endif /* UNUSED */ + +const struct protent ipcp_protent = { + PPP_IPCP, + ipcp_init, + ipcp_input, + ipcp_protrej, + ipcp_lowerup, + ipcp_lowerdown, + ipcp_open, + ipcp_close, +#if PRINTPKT_SUPPORT + ipcp_printpkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, + 1, +#if PRINTPKT_SUPPORT + "IPCP", + "IP", +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + ipcp_option_list, + ip_check_options, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + ip_demand_conf, + ip_active_pkt +#endif /* DEMAND_SUPPORT */ +}; + +static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute); + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ +#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ +#define CILEN_ADDR 6 /* new-style single address option */ +#define CILEN_ADDRS 10 /* old-style dual address option */ + + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +#if 0 /* UNUSED, already defined by lwIP */ +/* + * Make a string representation of a network IP address. + */ +char * +ip_ntoa(ipaddr) +u32_t ipaddr; +{ + static char b[64]; + + slprintf(b, sizeof(b), "%I", ipaddr); + return b; +} +#endif /* UNUSED, already defined by lwIP */ + +/* + * Option parsing. + */ +#if PPP_OPTIONS +/* + * setvjslots - set maximum number of connection slots for VJ compression + */ +static int +setvjslots(argv) + char **argv; +{ + int value; + +/* FIXME: found what int_option() did */ +#if PPP_OPTIONS + if (!int_option(*argv, &value)) + return 0; +#endif /* PPP_OPTIONS */ + + if (value < 2 || value > 16) { + option_error("vj-max-slots value must be between 2 and 16"); + return 0; + } + ipcp_wantoptions [0].maxslotindex = + ipcp_allowoptions[0].maxslotindex = value - 1; + slprintf(vj_value, sizeof(vj_value), "%d", value); + return 1; +} + +/* + * setdnsaddr - set the dns address(es) + */ +static int +setdnsaddr(argv) + char **argv; +{ + u32_t dns; + struct hostent *hp; + + dns = inet_addr(*argv); + if (dns == (u32_t) -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-dns option", + *argv); + return 0; + } + dns = *(u32_t *)hp->h_addr; + } + + /* We take the last 2 values given, the 2nd-last as the primary + and the last as the secondary. If only one is given it + becomes both primary and secondary. */ + if (ipcp_allowoptions[0].dnsaddr[1] == 0) + ipcp_allowoptions[0].dnsaddr[0] = dns; + else + ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; + + /* always set the secondary address value. */ + ipcp_allowoptions[0].dnsaddr[1] = dns; + + return (1); +} + +/* + * setwinsaddr - set the wins address(es) + * This is primrarly used with the Samba package under UNIX or for pointing + * the caller to the existing WINS server on a Windows NT platform. + */ +static int +setwinsaddr(argv) + char **argv; +{ + u32_t wins; + struct hostent *hp; + + wins = inet_addr(*argv); + if (wins == (u32_t) -1) { + if ((hp = gethostbyname(*argv)) == NULL) { + option_error("invalid address parameter '%s' for ms-wins option", + *argv); + return 0; + } + wins = *(u32_t *)hp->h_addr; + } + + /* We take the last 2 values given, the 2nd-last as the primary + and the last as the secondary. If only one is given it + becomes both primary and secondary. */ + if (ipcp_allowoptions[0].winsaddr[1] == 0) + ipcp_allowoptions[0].winsaddr[0] = wins; + else + ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; + + /* always set the secondary address value. */ + ipcp_allowoptions[0].winsaddr[1] = wins; + + return (1); +} + +/* + * setipaddr - Set the IP address + * If doit is 0, the call is to check whether this option is + * potentially an IP address specification. + * Not static so that plugins can call it to set the addresses + */ +int +setipaddr(arg, argv, doit) + char *arg; + char **argv; + int doit; +{ + struct hostent *hp; + char *colon; + u32_t local, remote; + ipcp_options *wo = &ipcp_wantoptions[0]; + static int prio_local = 0, prio_remote = 0; + + /* + * IP address pair separated by ":". + */ + if ((colon = strchr(arg, ':')) == NULL) + return 0; + if (!doit) + return 1; + + /* + * If colon first character, then no local addr. + */ + if (colon != arg && option_priority >= prio_local) { + *colon = '\0'; + if ((local = inet_addr(arg)) == (u32_t) -1) { + if ((hp = gethostbyname(arg)) == NULL) { + option_error("unknown host: %s", arg); + return 0; + } + local = *(u32_t *)hp->h_addr; + } + if (bad_ip_adrs(local)) { + option_error("bad local IP address %s", ip_ntoa(local)); + return 0; + } + if (local != 0) + wo->ouraddr = local; + *colon = ':'; + prio_local = option_priority; + } + + /* + * If colon last character, then no remote addr. + */ + if (*++colon != '\0' && option_priority >= prio_remote) { + if ((remote = inet_addr(colon)) == (u32_t) -1) { + if ((hp = gethostbyname(colon)) == NULL) { + option_error("unknown host: %s", colon); + return 0; + } + remote = *(u32_t *)hp->h_addr; + if (remote_name[0] == 0) + strlcpy(remote_name, colon, sizeof(remote_name)); + } + if (bad_ip_adrs(remote)) { + option_error("bad remote IP address %s", ip_ntoa(remote)); + return 0; + } + if (remote != 0) + wo->hisaddr = remote; + prio_remote = option_priority; + } + + return 1; +} + +static void +printipaddr(opt, printer, arg) + option_t *opt; + void (*printer) (void *, char *, ...); + void *arg; +{ + ipcp_options *wo = &ipcp_wantoptions[0]; + + if (wo->ouraddr != 0) + printer(arg, "%I", wo->ouraddr); + printer(arg, ":"); + if (wo->hisaddr != 0) + printer(arg, "%I", wo->hisaddr); +} + +/* + * setnetmask - set the netmask to be used on the interface. + */ +static int +setnetmask(argv) + char **argv; +{ + u32_t mask; + int n; + char *p; + + /* + * Unfortunately, if we use inet_addr, we can't tell whether + * a result of all 1s is an error or a valid 255.255.255.255. + */ + p = *argv; + n = parse_dotted_ip(p, &mask); + + mask = htonl(mask); + + if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { + option_error("invalid netmask value '%s'", *argv); + return 0; + } + + netmask = mask; + slprintf(netmask_str, sizeof(netmask_str), "%I", mask); + + return (1); +} + +int +parse_dotted_ip(p, vp) + char *p; + u32_t *vp; +{ + int n; + u32_t v, b; + char *endp, *p0 = p; + + v = 0; + for (n = 3;; --n) { + b = strtoul(p, &endp, 0); + if (endp == p) + return 0; + if (b > 255) { + if (n < 3) + return 0; + /* accept e.g. 0xffffff00 */ + *vp = b; + return endp - p0; + } + v |= b << (n * 8); + p = endp; + if (n == 0) + break; + if (*p != '.') + return 0; + ++p; + } + *vp = v; + return p - p0; +} +#endif /* PPP_OPTIONS */ + +/* + * ipcp_init - Initialize IPCP. + */ +static void ipcp_init(ppp_pcb *pcb) { + fsm *f = &pcb->ipcp_fsm; + + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; + + f->pcb = pcb; + f->protocol = PPP_IPCP; + f->callbacks = &ipcp_callbacks; + fsm_init(f); + + /* + * Some 3G modems use repeated IPCP NAKs as a way of stalling + * until they can contact a server on the network, so we increase + * the default number of NAKs we accept before we start treating + * them as rejects. + */ + f->maxnakloops = 100; + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->neg_addr = wo->old_addrs = 1; + wo->neg_vj = 1; + wo->vj_protocol = IPCP_VJ_COMP; + wo->maxslotindex = MAX_STATES - 1; /* really max index */ + wo->cflag = 1; + +#if 0 /* UNUSED */ + /* wanting default route by default */ + wo->default_route = 1; +#endif /* UNUSED */ + + /* max slots and slot-id compression are currently hardwired in */ + /* ppp_if.c to 16 and 1, this needs to be changed (among other */ + /* things) gmc */ + + ao->neg_addr = ao->old_addrs = 1; + ao->neg_vj = 1; + ao->maxslotindex = MAX_STATES - 1; + ao->cflag = 1; + +#if 0 /* UNUSED */ + /* + * XXX These control whether the user may use the proxyarp + * and defaultroute options. + */ + ao->proxy_arp = 1; + ao->default_route = 1; +#endif /* UNUSED */ +} + + +/* + * ipcp_open - IPCP is allowed to come up. + */ +static void ipcp_open(ppp_pcb *pcb) { + fsm *f = &pcb->ipcp_fsm; + fsm_open(f); + pcb->ipcp_is_open = 1; +} + + +/* + * ipcp_close - Take IPCP down. + */ +static void ipcp_close(ppp_pcb *pcb, const char *reason) { + fsm *f = &pcb->ipcp_fsm; + fsm_close(f, reason); +} + + +/* + * ipcp_lowerup - The lower layer is up. + */ +static void ipcp_lowerup(ppp_pcb *pcb) { + fsm *f = &pcb->ipcp_fsm; + fsm_lowerup(f); +} + + +/* + * ipcp_lowerdown - The lower layer is down. + */ +static void ipcp_lowerdown(ppp_pcb *pcb) { + fsm *f = &pcb->ipcp_fsm; + fsm_lowerdown(f); +} + + +/* + * ipcp_input - Input IPCP packet. + */ +static void ipcp_input(ppp_pcb *pcb, u_char *p, int len) { + fsm *f = &pcb->ipcp_fsm; + fsm_input(f, p, len); +} + + +/* + * ipcp_protrej - A Protocol-Reject was received for IPCP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void ipcp_protrej(ppp_pcb *pcb) { + fsm *f = &pcb->ipcp_fsm; + fsm_lowerdown(f); +} + + +/* + * ipcp_resetci - Reset our CI. + * Called by fsm_sconfreq, Send Configure Request. + */ +static void ipcp_resetci(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; + + wo->req_addr = (wo->neg_addr || wo->old_addrs) && + (ao->neg_addr || ao->old_addrs); + if (wo->ouraddr == 0) + wo->accept_local = 1; + if (wo->hisaddr == 0) + wo->accept_remote = 1; + wo->req_dns1 = pcb->settings.usepeerdns; /* Request DNS addresses from the peer */ + wo->req_dns2 = pcb->settings.usepeerdns; + *go = *wo; + if (!pcb->ask_for_local) + go->ouraddr = 0; +#if 0 /* UNUSED */ + if (ip_choose_hook) { + ip_choose_hook(&wo->hisaddr); + if (wo->hisaddr) { + wo->accept_remote = 0; + } + } +#endif /* UNUSED */ + BZERO(&pcb->ipcp_hisoptions, sizeof(ipcp_options)); +} + + +/* + * ipcp_cilen - Return length of our CI. + * Called by fsm_sconfreq, Send Configure Request. + */ +static int ipcp_cilen(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ho = &pcb->ipcp_hisoptions; + +#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) +#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) +#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) +#define LENCIDNS(neg) LENCIADDR(neg) +#define LENCIWINS(neg) LENCIADDR(neg) + + /* + * First see if we want to change our options to the old + * forms because we have received old forms from the peer. + */ + if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) + go->neg_addr = 0; + if (wo->neg_vj && !go->neg_vj && !go->old_vj) { + /* try an older style of VJ negotiation */ + /* use the old style only if the peer did */ + if (ho->neg_vj && ho->old_vj) { + go->neg_vj = 1; + go->old_vj = 1; + go->vj_protocol = ho->vj_protocol; + } + } + + return (LENCIADDRS(!go->neg_addr && go->old_addrs) + + LENCIVJ(go->neg_vj, go->old_vj) + + LENCIADDR(go->neg_addr) + + LENCIDNS(go->req_dns1) + + LENCIDNS(go->req_dns2) + + LENCIWINS(go->winsaddr[0]) + + LENCIWINS(go->winsaddr[1])) ; +} + + +/* + * ipcp_addci - Add our desired CIs to a packet. + * Called by fsm_sconfreq, Send Configure Request. + */ +static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = f->pcb; + ipcp_options *go = &pcb->ipcp_gotoptions; + int len = *lenp; + +#define ADDCIADDRS(opt, neg, val1, val2) \ + if (neg) { \ + if (len >= CILEN_ADDRS) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDRS, ucp); \ + l = ntohl(val1); \ + PUTLONG(l, ucp); \ + l = ntohl(val2); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDRS; \ + } else \ + go->old_addrs = 0; \ + } + +#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + if (!old) { \ + PUTCHAR(maxslotindex, ucp); \ + PUTCHAR(cflag, ucp); \ + } \ + len -= vjlen; \ + } else \ + neg = 0; \ + } + +#define ADDCIADDR(opt, neg, val) \ + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(val); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else \ + neg = 0; \ + } + +#define ADDCIDNS(opt, neg, addr) \ + if (neg) { \ + if (len >= CILEN_ADDR) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(addr); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else \ + neg = 0; \ + } + +#define ADDCIWINS(opt, addr) \ + if (addr) { \ + if (len >= CILEN_ADDR) { \ + u32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_ADDR, ucp); \ + l = ntohl(addr); \ + PUTLONG(l, ucp); \ + len -= CILEN_ADDR; \ + } else \ + addr = 0; \ + } + + ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, + go->hisaddr); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); + + ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); + + *lenp -= len; +} + + +/* + * ipcp_ackci - Ack our CIs. + * Called by fsm_rconfack, Receive Configure ACK. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int ipcp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipcp_options *go = &pcb->ipcp_gotoptions; + u_short cilen, citype, cishort; + u32_t cilong; + u_char cimaxslotindex, cicflag; + + /* + * CIs must be in exactly the same order that we sent... + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ + +#define ACKCIADDRS(opt, neg, val1, val2) \ + if (neg) { \ + u32_t l; \ + if ((len -= CILEN_ADDRS) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDRS || \ + citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val1 != cilong) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val2 != cilong) \ + goto bad; \ + } + +#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ + if (neg) { \ + int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ + if ((len -= vjlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != vjlen || \ + citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslotindex) \ + goto bad; \ + GETCHAR(cicflag, p); \ + if (cicflag != cflag) \ + goto bad; \ + } \ + } + +#define ACKCIADDR(opt, neg, val) \ + if (neg) { \ + u32_t l; \ + if ((len -= CILEN_ADDR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || \ + citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (val != cilong) \ + goto bad; \ + } + +#define ACKCIDNS(opt, neg, addr) \ + if (neg) { \ + u32_t l; \ + if ((len -= CILEN_ADDR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (addr != cilong) \ + goto bad; \ + } + +#define ACKCIWINS(opt, addr) \ + if (addr) { \ + u32_t l; \ + if ((len -= CILEN_ADDR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_ADDR || citype != opt) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + if (addr != cilong) \ + goto bad; \ + } + + ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, + go->hisaddr); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); + + ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); + + ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); + + ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); + +bad: + IPCPDEBUG(("ipcp_ackci: received bad Ack!")); + return (0); +} + +/* + * ipcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPCP is in the OPENED state. + * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = f->pcb; + ipcp_options *go = &pcb->ipcp_gotoptions; + u_char cimaxslotindex, cicflag; + u_char citype, cilen, *next; + u_short cishort; + u32_t ciaddr1, ciaddr2, l, cidnsaddr; + ipcp_options no; /* options we've seen Naks for */ + ipcp_options try_; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try_ = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIADDRS(opt, neg, code) \ + if ((neg) && \ + (cilen = p[1]) == CILEN_ADDRS && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + GETLONG(l, p); \ + ciaddr2 = htonl(l); \ + no.old_addrs = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIADDR(opt, neg, code) \ + if (go->neg && \ + (cilen = p[1]) == CILEN_ADDR && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + ciaddr1 = htonl(l); \ + no.neg = 1; \ + code \ + } + +#define NAKCIDNS(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cidnsaddr = htonl(l); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} address, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, + if (treat_as_reject) { + try_.old_addrs = 0; + } else { + if (go->accept_local && ciaddr1) { + /* take his idea of our address */ + try_.ouraddr = ciaddr1; + } + if (go->accept_remote && ciaddr2) { + /* take his idea of his address */ + try_.hisaddr = ciaddr2; + } + } + ); + + /* + * Accept the peer's value of maxslotindex provided that it + * is less than what we asked for. Turn off slot-ID compression + * if the peer wants. Send old-style compress-type option if + * the peer wants. + */ + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + if (treat_as_reject) { + try_.neg_vj = 0; + } else if (cilen == CILEN_VJ) { + GETCHAR(cimaxslotindex, p); + GETCHAR(cicflag, p); + if (cishort == IPCP_VJ_COMP) { + try_.old_vj = 0; + if (cimaxslotindex < go->maxslotindex) + try_.maxslotindex = cimaxslotindex; + if (!cicflag) + try_.cflag = 0; + } else { + try_.neg_vj = 0; + } + } else { + if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { + try_.old_vj = 1; + try_.vj_protocol = cishort; + } else { + try_.neg_vj = 0; + } + } + ); + + NAKCIADDR(CI_ADDR, neg_addr, + if (treat_as_reject) { + try_.neg_addr = 0; + try_.old_addrs = 0; + } else if (go->accept_local && ciaddr1) { + /* take his idea of our address */ + try_.ouraddr = ciaddr1; + } + ); + + NAKCIDNS(CI_MS_DNS1, req_dns1, + if (treat_as_reject) { + try_.req_dns1 = 0; + } else { + try_.dnsaddr[0] = cidnsaddr; + } + ); + + NAKCIDNS(CI_MS_DNS2, req_dns2, + if (treat_as_reject) { + try_.req_dns2 = 0; + } else { + try_.dnsaddr[1] = cidnsaddr; + } + ); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If they want to negotiate about IP addresses, we comply. + * If they want us to ask for compression, we refuse. + * If they want us to ask for ms-dns, we do that, since some + * peers get huffy if we don't. + */ + while (len >= CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) + goto bad; + next = p + cilen - 2; + + switch (citype) { + case CI_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) + goto bad; + no.neg_vj = 1; + break; + case CI_ADDRS: + if ((!go->neg_addr && go->old_addrs) || no.old_addrs + || cilen != CILEN_ADDRS) + goto bad; + try_.neg_addr = 0; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) + try_.ouraddr = ciaddr1; + GETLONG(l, p); + ciaddr2 = htonl(l); + if (ciaddr2 && go->accept_remote) + try_.hisaddr = ciaddr2; + no.old_addrs = 1; + break; + case CI_ADDR: + if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) + goto bad; + try_.old_addrs = 0; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1 && go->accept_local) + try_.ouraddr = ciaddr1; + if (try_.ouraddr != 0) + try_.neg_addr = 1; + no.neg_addr = 1; + break; + case CI_MS_DNS1: + if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + try_.dnsaddr[0] = htonl(l); + try_.req_dns1 = 1; + no.req_dns1 = 1; + break; + case CI_MS_DNS2: + if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + try_.dnsaddr[1] = htonl(l); + try_.req_dns2 = 1; + no.req_dns2 = 1; + break; + case CI_MS_WINS1: + case CI_MS_WINS2: + if (cilen != CILEN_ADDR) + goto bad; + GETLONG(l, p); + ciaddr1 = htonl(l); + if (ciaddr1) + try_.winsaddr[citype == CI_MS_WINS2] = ciaddr1; + break; + default: + break; + } + p = next; + } + + /* + * OK, the Nak is good. Now we can update state. + * If there are any remaining options, we ignore them. + */ + if (f->state != PPP_FSM_OPENED) + *go = try_; + + return 1; + +bad: + IPCPDEBUG(("ipcp_nakci: received bad Nak!")); + return 0; +} + + +/* + * ipcp_rejci - Reject some of our CIs. + * Callback from fsm_rconfnakrej. + */ +static int ipcp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipcp_options *go = &pcb->ipcp_gotoptions; + u_char cimaxslotindex, ciflag, cilen; + u_short cishort; + u32_t cilong; + ipcp_options try_; /* options to request next time */ + + try_ = *go; + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIADDRS(opt, neg, val1, val2) \ + if ((neg) && \ + (cilen = p[1]) == CILEN_ADDRS && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val1) \ + goto bad; \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val2) \ + goto bad; \ + try_.old_addrs = 0; \ + } + +#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ + if (go->neg && \ + p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) \ + goto bad; \ + if (!old) { \ + GETCHAR(cimaxslotindex, p); \ + if (cimaxslotindex != maxslot) \ + goto bad; \ + GETCHAR(ciflag, p); \ + if (ciflag != cflag) \ + goto bad; \ + } \ + try_.neg = 0; \ + } + +#define REJCIADDR(opt, neg, val) \ + if (go->neg && \ + (cilen = p[1]) == CILEN_ADDR && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != val) \ + goto bad; \ + try_.neg = 0; \ + } + +#define REJCIDNS(opt, neg, dnsaddr) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != dnsaddr) \ + goto bad; \ + try_.neg = 0; \ + } + +#define REJCIWINS(opt, addr) \ + if (addr && \ + ((cilen = p[1]) == CILEN_ADDR) && \ + len >= cilen && \ + p[0] == opt) { \ + u32_t l; \ + len -= cilen; \ + INCPTR(2, p); \ + GETLONG(l, p); \ + cilong = htonl(l); \ + /* Check rejected value. */ \ + if (cilong != addr) \ + goto bad; \ + try_.winsaddr[opt == CI_MS_WINS2] = 0; \ + } + + REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, + go->ouraddr, go->hisaddr); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, + go->maxslotindex, go->cflag); + + REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); + + REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); + + REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); + + REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); + + REJCIWINS(CI_MS_WINS2, go->winsaddr[1]); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + /* + * Now we can update state. + */ + if (f->state != PPP_FSM_OPENED) + *go = try_; + return 1; + +bad: + IPCPDEBUG(("ipcp_rejci: received bad Reject!")); + return 0; +} + + +/* + * ipcp_reqci - Check the peer's requested CIs and send appropriate response. + * Callback from fsm_rconfreq, Receive Configure Request + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + * + * inp = Requested CIs + * len = Length of requested CIs + */ +static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { + ppp_pcb *pcb = f->pcb; + ipcp_options *wo = &pcb->ipcp_wantoptions; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *ao = &pcb->ipcp_allowoptions; + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + u32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *ucp = inp; /* Pointer to current output char */ + int l = *len; /* Length left */ + u_char maxslotindex, cflag; + int d; + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + IPCPDEBUG(("ipcp_reqci: bad CI length!")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_ADDRS: + if (!ao->old_addrs || ho->neg_addr || + cilen != CILEN_ADDRS) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * If neither we nor he knows his address, reject the option. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + /* + * If he doesn't know our address, or if we both have our address + * but disagree about it, then NAK it with our idea. + */ + GETLONG(tl, p); /* Parse desination address (ours) */ + ciaddr2 = htonl(tl); + if (ciaddr2 != wo->ouraddr) { + if (ciaddr2 == 0 || !wo->accept_local) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->ouraddr); + PUTLONG(tl, p); + } + } else { + wo->ouraddr = ciaddr2; /* accept peer's idea */ + } + } + + ho->old_addrs = 1; + ho->hisaddr = ciaddr1; + ho->ouraddr = ciaddr2; + break; + + case CI_ADDR: + if (!ao->neg_addr || ho->old_addrs || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no address, or if we both have his address but + * disagree about it, then NAK it with our idea. + * In particular, if we don't know his address, but he does, + * then accept it. + */ + GETLONG(tl, p); /* Parse source address (his) */ + ciaddr1 = htonl(tl); + if (ciaddr1 != wo->hisaddr + && (ciaddr1 == 0 || !wo->accept_remote)) { + orc = CONFNAK; + if (!reject_if_disagree) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, p); + } + } else if (ciaddr1 == 0 && wo->hisaddr == 0) { + /* + * Don't ACK an address of 0.0.0.0 - reject it instead. + */ + orc = CONFREJ; + wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ + break; + } + + ho->neg_addr = 1; + ho->hisaddr = ciaddr1; + break; + + case CI_MS_DNS1: + case CI_MS_DNS2: + /* Microsoft primary or secondary DNS request */ + d = citype == CI_MS_DNS2; + + /* If we do not have a DNS address then we cannot send it */ + if (ao->dnsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->dnsaddr[d]) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->dnsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; + + case CI_MS_WINS1: + case CI_MS_WINS2: + /* Microsoft primary or secondary WINS request */ + d = citype == CI_MS_WINS2; + + /* If we do not have a DNS address then we cannot send it */ + if (ao->winsaddr[d] == 0 || + cilen != CILEN_ADDR) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETLONG(tl, p); + if (htonl(tl) != ao->winsaddr[d]) { + DECPTR(sizeof(u32_t), p); + tl = ntohl(ao->winsaddr[d]); + PUTLONG(tl, p); + orc = CONFNAK; + } + break; + + case CI_COMPRESSTYPE: + if (!ao->neg_vj || + (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + if (!(cishort == IPCP_VJ_COMP || + (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { + orc = CONFREJ; + break; + } + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + if (cilen == CILEN_VJ) { + GETCHAR(maxslotindex, p); + if (maxslotindex > ao->maxslotindex) { + orc = CONFNAK; + if (!reject_if_disagree){ + DECPTR(1, p); + PUTCHAR(ao->maxslotindex, p); + } + } + GETCHAR(cflag, p); + if (cflag && !ao->cflag) { + orc = CONFNAK; + if (!reject_if_disagree){ + DECPTR(1, p); + PUTCHAR(wo->cflag, p); + } + } + ho->maxslotindex = maxslotindex; + ho->cflag = cflag; + } else { + ho->old_vj = 1; + ho->maxslotindex = MAX_STATES - 1; + ho->cflag = 1; + } + break; + + default: + orc = CONFREJ; + break; + } +endswitch: + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) /* but prior CI wasnt? */ + continue; /* Don't send this one */ + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree) /* Getting fed up with sending NAKs? */ + orc = CONFREJ; /* Get tough if so */ + else { + if (rc == CONFREJ) /* Rejecting prior CI? */ + continue; /* Don't send this one */ + if (rc == CONFACK) { /* Ack'd all prior CIs? */ + rc = CONFNAK; /* Not anymore... */ + ucp = inp; /* Backup */ + } + } + } + + if (orc == CONFREJ && /* Reject this CI */ + rc != CONFREJ) { /* but no prior ones? */ + rc = CONFREJ; + ucp = inp; /* Backup */ + } + + /* Need to move CI? */ + if (ucp != cip) + MEMCPY(ucp, cip, cilen); /* Move it */ + + /* Update output pointer */ + INCPTR(cilen, ucp); + } + + /* + * If we aren't rejecting this packet, and we want to negotiate + * their address, and they didn't send their address, then we + * send a NAK with a CI_ADDR option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && + wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) { + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_addr = 0; /* don't ask again */ + } + PUTCHAR(CI_ADDR, ucp); + PUTCHAR(CILEN_ADDR, ucp); + tl = ntohl(wo->hisaddr); + PUTLONG(tl, ucp); + } + + *len = ucp - inp; /* Compute output length */ + IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +#if 0 /* UNUSED */ +/* + * ip_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void +ip_check_options() +{ + struct hostent *hp; + u32_t local; + ipcp_options *wo = &ipcp_wantoptions[0]; + + /* + * Default our local IP address based on our hostname. + * If local IP address already given, don't bother. + */ + if (wo->ouraddr == 0 && !disable_defaultip) { + /* + * Look up our hostname (possibly with domain name appended) + * and take the first IP address as our local IP address. + * If there isn't an IP address for our hostname, too bad. + */ + wo->accept_local = 1; /* don't insist on this default value */ + if ((hp = gethostbyname(hostname)) != NULL) { + local = *(u32_t *)hp->h_addr; + if (local != 0 && !bad_ip_adrs(local)) + wo->ouraddr = local; + } + } + ask_for_local = wo->ouraddr != 0 || !disable_defaultip; +} +#endif /* UNUSED */ + +#if DEMAND_SUPPORT +/* + * ip_demand_conf - configure the interface as though + * IPCP were up, for use with dial-on-demand. + */ +static int +ip_demand_conf(u) + int u; +{ + ppp_pcb *pcb = &ppp_pcb_list[u]; + ipcp_options *wo = &ipcp_wantoptions[u]; + + if (wo->hisaddr == 0 && !pcb->settings.noremoteip) { + /* make up an arbitrary address for the peer */ + wo->hisaddr = htonl(0x0a707070 + ifunit); + wo->accept_remote = 1; + } + if (wo->ouraddr == 0) { + /* make up an arbitrary address for us */ + wo->ouraddr = htonl(0x0a404040 + ifunit); + wo->accept_local = 1; + ask_for_local = 0; /* don't tell the peer this address */ + } + if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) + return 0; + if (!sifup(pcb)) + return 0; + if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE)) + return 0; +#if 0 /* UNUSED */ + if (wo->default_route) + if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr, + wo->replace_default_route)) + default_route_set[u] = 1; +#endif /* UNUSED */ + if (wo->proxy_arp) + if (sifproxyarp(pcb, wo->hisaddr)) + proxy_arp_set[u] = 1; + + ppp_notice("local IP address %I", wo->ouraddr); + if (wo->hisaddr) + ppp_notice("remote IP address %I", wo->hisaddr); + + return 1; +} +#endif /* DEMAND_SUPPORT */ + +/* + * ipcp_up - IPCP has come UP. + * + * Configure the IP network interface appropriately and bring it up. + */ +static void ipcp_up(fsm *f) { + ppp_pcb *pcb = f->pcb; + u32_t mask; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + ipcp_options *wo = &pcb->ipcp_wantoptions; + + IPCPDEBUG(("ipcp: up")); + + /* + * We must have a non-zero IP address for both ends of the link. + */ + if (!ho->neg_addr && !ho->old_addrs) + ho->hisaddr = wo->hisaddr; + + if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) + && wo->ouraddr != 0) { + ppp_error("Peer refused to agree to our IP address"); + ipcp_close(f->pcb, "Refused our IP address"); + return; + } + if (go->ouraddr == 0) { + ppp_error("Could not determine local IP address"); + ipcp_close(f->pcb, "Could not determine local IP address"); + return; + } + if (ho->hisaddr == 0 && !pcb->settings.noremoteip) { + ho->hisaddr = htonl(0x0a404040); + ppp_warn("Could not determine remote IP address: defaulting to %I", + ho->hisaddr); + } +#if 0 /* UNUSED */ + script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); + if (ho->hisaddr != 0) + script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); +#endif /* UNUSED */ + + if (!go->req_dns1) + go->dnsaddr[0] = 0; + if (!go->req_dns2) + go->dnsaddr[1] = 0; +#if 0 /* UNUSED */ + if (go->dnsaddr[0]) + script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); + if (go->dnsaddr[1]) + script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); +#endif /* UNUSED */ + if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { + sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); +#if 0 /* UNUSED */ + script_setenv("USEPEERDNS", "1", 0); + create_resolv(go->dnsaddr[0], go->dnsaddr[1]); +#endif /* UNUSED */ + } + +/* FIXME: check why it fails, just to know */ +#if 0 /* Unused */ + /* + * Check that the peer is allowed to use the IP address it wants. + */ + if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { + ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); + ipcp_close(f->unit, "Unauthorized remote IP address"); + return; + } +#endif /* Unused */ + + /* set tcp compression */ + sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex); + +#if DEMAND_SUPPORT + /* + * If we are doing dial-on-demand, the interface is already + * configured, so we put out any saved-up packets, then set the + * interface to pass IP packets. + */ + if (demand) { + if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { + ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, + wo->replace_default_route); + if (go->ouraddr != wo->ouraddr) { + ppp_warn("Local IP address changed to %I", go->ouraddr); + script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); + wo->ouraddr = go->ouraddr; + } else + script_unsetenv("OLDIPLOCAL"); + if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { + ppp_warn("Remote IP address changed to %I", ho->hisaddr); + script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); + wo->hisaddr = ho->hisaddr; + } else + script_unsetenv("OLDIPREMOTE"); + + /* Set the interface to the new addresses */ + mask = get_mask(go->ouraddr); + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { +#if PPP_DEBUG + ppp_warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + + /* assign a default route through the interface if required */ + if (ipcp_wantoptions[f->unit].default_route) + if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) + default_route_set[f->unit] = 1; + + /* Make a proxy ARP entry if requested. */ + if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) + if (sifproxyarp(pcb, ho->hisaddr)) + proxy_arp_set[f->unit] = 1; + + } + demand_rexmit(PPP_IP,go->ouraddr); + sifnpmode(pcb, PPP_IP, NPMODE_PASS); + + } else +#endif /* DEMAND_SUPPORT */ + { + /* + * Set IP addresses and (if specified) netmask. + */ + mask = get_mask(go->ouraddr); + +#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { +#if PPP_DEBUG + ppp_warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ + ipcp_close(f->pcb, "Interface configuration failed"); + return; + } +#endif + + /* bring the interface up for IP */ + if (!sifup(pcb)) { +#if PPP_DEBUG + ppp_warn("Interface failed to come up"); +#endif /* PPP_DEBUG */ + ipcp_close(f->pcb, "Interface configuration failed"); + return; + } + +#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) + if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { +#if PPP_DEBUG + ppp_warn("Interface configuration failed"); +#endif /* PPP_DEBUG */ + ipcp_close(f->unit, "Interface configuration failed"); + return; + } +#endif + sifnpmode(pcb, PPP_IP, NPMODE_PASS); + +#if 0 /* UNUSED */ + /* assign a default route through the interface if required */ + if (wo->default_route) + if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) + pcb->default_route_set = 1; +#endif /* UNUSED */ + + /* Make a proxy ARP entry if requested. */ + if (ho->hisaddr != 0 && wo->proxy_arp) + if (sifproxyarp(pcb, ho->hisaddr)) + pcb->proxy_arp_set = 1; + + wo->ouraddr = go->ouraddr; + + ppp_notice("local IP address %I", go->ouraddr); + if (ho->hisaddr != 0) + ppp_notice("remote IP address %I", ho->hisaddr); + if (go->dnsaddr[0]) + ppp_notice("primary DNS address %I", go->dnsaddr[0]); + if (go->dnsaddr[1]) + ppp_notice("secondary DNS address %I", go->dnsaddr[1]); + } + +#if PPP_STATS_SUPPORT + reset_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ + + np_up(pcb, PPP_IP); + pcb->ipcp_is_up = 1; + +#if PPP_NOTIFY + notify(ip_up_notifier, 0); +#endif /* PPP_NOTIFY */ +#if 0 /* UNUSED */ + if (ip_up_hook) + ip_up_hook(); +#endif /* UNUSED */ +} + + +/* + * ipcp_down - IPCP has gone DOWN. + * + * Take the IP network interface down, clear its addresses + * and delete routes through it. + */ +static void ipcp_down(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipcp_options *ho = &pcb->ipcp_hisoptions; + ipcp_options *go = &pcb->ipcp_gotoptions; + + IPCPDEBUG(("ipcp: down")); +#if PPP_STATS_SUPPORT + /* XXX a bit IPv4-centric here, we only need to get the stats + * before the interface is marked down. */ + /* XXX more correct: we must get the stats before running the notifiers, + * at least for the radius plugin */ + update_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ +#if PPP_NOTIFY + notify(ip_down_notifier, 0); +#endif /* PPP_NOTIFY */ +#if 0 /* UNUSED */ + if (ip_down_hook) + ip_down_hook(); +#endif /* UNUSED */ + if (pcb->ipcp_is_up) { + pcb->ipcp_is_up = 0; + np_down(pcb, PPP_IP); + } + sifvjcomp(pcb, 0, 0, 0); + +#if PPP_STATS_SUPPORT + print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), + * because print_link_stats() sets link_stats_valid + * to 0 (zero) */ +#endif /* PPP_STATS_SUPPORT */ + +#if DEMAND_SUPPORT + /* + * If we are doing dial-on-demand, set the interface + * to queue up outgoing packets (for now). + */ + if (demand) { + sifnpmode(pcb, PPP_IP, NPMODE_QUEUE); + } else +#endif /* DEMAND_SUPPORT */ + { + sifnpmode(pcb, PPP_IP, NPMODE_DROP); + sifdown(pcb); + ipcp_clear_addrs(pcb, go->ouraddr, + ho->hisaddr, 0); + cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); + } +} + + +/* + * ipcp_clear_addrs() - clear the interface addresses, routes, + * proxy arp entries, etc. + */ +static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute) { + LWIP_UNUSED_ARG(replacedefaultroute); + + if (pcb->proxy_arp_set) { + cifproxyarp(pcb, hisaddr); + pcb->proxy_arp_set = 0; + } +#if 0 /* UNUSED */ + /* If replacedefaultroute, sifdefaultroute will be called soon + * with replacedefaultroute set and that will overwrite the current + * default route. This is the case only when doing demand, otherwise + * during demand, this cifdefaultroute would restore the old default + * route which is not what we want in this case. In the non-demand + * case, we'll delete the default route and restore the old if there + * is one saved by an sifdefaultroute with replacedefaultroute. + */ + if (!replacedefaultroute && pcb->default_route_set) { + cifdefaultroute(pcb, ouraddr, hisaddr); + pcb->default_route_set = 0; + } +#endif /* UNUSED */ + cifaddr(pcb, ouraddr, hisaddr); +} + + +/* + * ipcp_finished - possibly shut down the lower layers. + */ +static void ipcp_finished(fsm *f) { + ppp_pcb *pcb = f->pcb; + if (pcb->ipcp_is_open) { + pcb->ipcp_is_open = 0; + np_finished(pcb, PPP_IP); + } +} + + +#if 0 /* UNUSED */ +/* + * create_resolv - create the replacement resolv.conf file + */ +static void +create_resolv(peerdns1, peerdns2) + u32_t peerdns1, peerdns2; +{ + +} +#endif /* UNUSED */ + +#if PRINTPKT_SUPPORT +/* + * ipcp_printpkt - print the contents of an IPCP packet. + */ +static const char *ipcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int ipcp_printpkt(u_char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg) { + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + u32_t cilong; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= (int)sizeof(ipcp_codenames) / (int)sizeof(char *)) + printer(arg, " %s", ipcp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_ADDRS: + if (olen == CILEN_ADDRS) { + p += 2; + GETLONG(cilong, p); + printer(arg, "addrs %I", htonl(cilong)); + GETLONG(cilong, p); + printer(arg, " %I", htonl(cilong)); + } + break; + case CI_COMPRESSTYPE: + if (olen >= CILEN_COMPRESS) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "compress "); + switch (cishort) { + case IPCP_VJ_COMP: + printer(arg, "VJ"); + break; + case IPCP_VJ_COMP_OLD: + printer(arg, "old-VJ"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_ADDR: + if (olen == CILEN_ADDR) { + p += 2; + GETLONG(cilong, p); + printer(arg, "addr %I", htonl(cilong)); + } + break; + case CI_MS_DNS1: + case CI_MS_DNS2: + p += 2; + GETLONG(cilong, p); + printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), + htonl(cilong)); + break; + case CI_MS_WINS1: + case CI_MS_WINS2: + p += 2; + GETLONG(cilong, p); + printer(arg, "ms-wins %I", htonl(cilong)); + break; + default: + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + ppp_print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + default: + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; +} +#endif /* PRINTPKT_SUPPORT */ + +#if DEMAND_SUPPORT +/* + * ip_active_pkt - see if this IP packet is worth bringing the link up for. + * We don't bring the link up for IP fragments or for TCP FIN packets + * with no data. + */ +#define IP_HDRLEN 20 /* bytes */ +#define IP_OFFMASK 0x1fff +#ifndef IPPROTO_TCP +#define IPPROTO_TCP 6 +#endif +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 + +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define net_short(x) (((x)[0] << 8) + (x)[1]) +#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) +#define get_ipoff(x) net_short((unsigned char *)(x) + 6) +#define get_ipproto(x) (((unsigned char *)(x))[9]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int +ip_active_pkt(pkt, len) + u_char *pkt; + int len; +{ + u_char *tcp; + int hlen; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP_HDRLEN) + return 0; + if ((get_ipoff(pkt) & IP_OFFMASK) != 0) + return 0; + if (get_ipproto(pkt) != IPPROTO_TCP) + return 1; + hlen = get_iphl(pkt) * 4; + if (len < hlen + TCP_HDRLEN) + return 0; + tcp = pkt + hlen; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) + return 0; + return 1; +} +#endif /* DEMAND_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipv6cp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipv6cp.c new file mode 100644 index 0000000..5ff6183 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ipv6cp.c @@ -0,0 +1,1498 @@ +/* + * ipv6cp.c - PPP IPV6 Control Protocol. + * + * Copyright (c) 1999 Tommi Komulainen. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Tommi Komulainen + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* Original version, based on RFC2023 : + + Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, + Alain.Durand@imag.fr, IMAG, + Jean-Luc.Richier@imag.fr, IMAG-LSR. + + Ce travail a �t� fait au sein du GIE DYADE (Groupement d'Int�r�t + �conomique ayant pour membres BULL S.A. et l'INRIA). + + Ce logiciel informatique est disponible aux conditions + usuelles dans la recherche, c'est-�-dire qu'il peut + �tre utilis�, copi�, modifi�, distribu� � l'unique + condition que ce texte soit conserv� afin que + l'origine de ce logiciel soit reconnue. + + Le nom de l'Institut National de Recherche en Informatique + et en Automatique (INRIA), de l'IMAG, ou d'une personne morale + ou physique ayant particip� � l'�laboration de ce logiciel ne peut + �tre utilis� sans son accord pr�alable explicite. + + Ce logiciel est fourni tel quel sans aucune garantie, + support ou responsabilit� d'aucune sorte. + Ce logiciel est d�riv� de sources d'origine + "University of California at Berkeley" et + "Digital Equipment Corporation" couvertes par des copyrights. + + L'Institut d'Informatique et de Math�matiques Appliqu�es de Grenoble (IMAG) + est une f�d�ration d'unit�s mixtes de recherche du CNRS, de l'Institut National + Polytechnique de Grenoble et de l'Universit� Joseph Fourier regroupant + sept laboratoires dont le laboratoire Logiciels, Syst�mes, R�seaux (LSR). + + This work has been done in the context of GIE DYADE (joint R & D venture + between BULL S.A. and INRIA). + + This software is available with usual "research" terms + with the aim of retain credits of the software. + Permission to use, copy, modify and distribute this software for any + purpose and without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies, + and the name of INRIA, IMAG, or any contributor not be used in advertising + or publicity pertaining to this material without the prior explicit + permission. The software is provided "as is" without any + warranties, support or liabilities of any kind. + This software is derived from source code from + "University of California at Berkeley" and + "Digital Equipment Corporation" protected by copyrights. + + Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) + is a federation of seven research units funded by the CNRS, National + Polytechnic Institute of Grenoble and University Joseph Fourier. + The research unit in Software, Systems, Networks (LSR) is member of IMAG. +*/ + +/* + * Derived from : + * + * + * ipcp.c - PPP IP Control Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ + */ + +/* + * TODO: + * + * Proxy Neighbour Discovery. + * + * Better defines for selecting the ordering of + * interface up / set address. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/fsm.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/ipv6cp.h" +#include "netif/ppp/magic.h" + +/* global vars */ +#if 0 /* UNUSED */ +int no_ifaceid_neg = 0; +#endif /* UNUSED */ + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void ipv6cp_resetci(fsm *f); /* Reset our CI */ +static int ipv6cp_cilen(fsm *f); /* Return length of our CI */ +static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ +static int ipv6cp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ +static int ipv6cp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ +static void ipv6cp_up(fsm *f); /* We're UP */ +static void ipv6cp_down(fsm *f); /* We're DOWN */ +static void ipv6cp_finished(fsm *f); /* Don't need lower layer */ + +static const fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ + ipv6cp_resetci, /* Reset our Configuration Information */ + ipv6cp_cilen, /* Length of our Configuration Information */ + ipv6cp_addci, /* Add our Configuration Information */ + ipv6cp_ackci, /* ACK our Configuration Information */ + ipv6cp_nakci, /* NAK our Configuration Information */ + ipv6cp_rejci, /* Reject our Configuration Information */ + ipv6cp_reqci, /* Request peer's Configuration Information */ + ipv6cp_up, /* Called when fsm reaches OPENED state */ + ipv6cp_down, /* Called when fsm leaves OPENED state */ + NULL, /* Called when we want the lower layer up */ + ipv6cp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + NULL, /* Called to handle protocol-specific codes */ + "IPV6CP" /* String name of protocol */ +}; + +#if PPP_OPTIONS +/* + * Command-line options. + */ +static int setifaceid(char **arg)); +static void printifaceid(option_t *, + void (*)(void *, char *, ...), void *)); + +static option_t ipv6cp_option_list[] = { + { "ipv6", o_special, (void *)setifaceid, + "Set interface identifiers for IPV6", + OPT_A2PRINTER, (void *)printifaceid }, + + { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, + { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, + { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, + "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, + + { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, + "Accept peer's interface identifier for us", 1 }, + + { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, + "Use (default) IPv4 address as interface identifier", 1 }, + + { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, + "Use uniquely-available persistent value for link local address", 1 }, + + { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, + "Set timeout for IPv6CP", OPT_PRIO }, + { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, + "Set max #xmits for term-reqs", OPT_PRIO }, + { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, + "Set max #xmits for conf-reqs", OPT_PRIO }, + { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, + "Set max #conf-naks for IPv6CP", OPT_PRIO }, + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points from main code. + */ +static void ipv6cp_init(ppp_pcb *pcb); +static void ipv6cp_open(ppp_pcb *pcb); +static void ipv6cp_close(ppp_pcb *pcb, const char *reason); +static void ipv6cp_lowerup(ppp_pcb *pcb); +static void ipv6cp_lowerdown(ppp_pcb *pcb); +static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len); +static void ipv6cp_protrej(ppp_pcb *pcb); +#if PPP_OPTIONS +static void ipv6_check_options(void); +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT +static int ipv6_demand_conf(int u); +#endif /* DEMAND_SUPPORT */ +#if PRINTPKT_SUPPORT +static int ipv6cp_printpkt(u_char *p, int plen, + void (*printer)(void *, const char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ +#if DEMAND_SUPPORT +static int ipv6_active_pkt(u_char *pkt, int len); +#endif /* DEMAND_SUPPORT */ + +const struct protent ipv6cp_protent = { + PPP_IPV6CP, + ipv6cp_init, + ipv6cp_input, + ipv6cp_protrej, + ipv6cp_lowerup, + ipv6cp_lowerdown, + ipv6cp_open, + ipv6cp_close, +#if PRINTPKT_SUPPORT + ipv6cp_printpkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, + 1, +#if PRINTPKT_SUPPORT + "IPV6CP", + "IPV6", +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + ipv6cp_option_list, + ipv6_check_options, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + ipv6_demand_conf, + ipv6_active_pkt +#endif /* DEMAND_SUPPORT */ +}; + +static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid); +#if 0 /* UNUSED */ +static void ipv6cp_script(char *)); +static void ipv6cp_script_done(void *)); +#endif /* UNUSED */ + +/* + * Lengths of configuration options. + */ +#define CILEN_VOID 2 +#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ +#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +#if 0 /* UNUSED */ +/* + * This state variable is used to ensure that we don't + * run an ipcp-up/down script while one is already running. + */ +static enum script_state { + s_down, + s_up, +} ipv6cp_script_state; +static pid_t ipv6cp_script_pid; +#endif /* UNUSED */ + +static char *llv6_ntoa(eui64_t ifaceid); + +#if PPP_OPTIONS +/* + * setifaceid - set the interface identifiers manually + */ +static int +setifaceid(argv) + char **argv; +{ + char *comma, *arg, c; + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + struct in6_addr addr; + static int prio_local, prio_remote; + +#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ + (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) + + arg = *argv; + if ((comma = strchr(arg, ',')) == NULL) + comma = arg + strlen(arg); + + /* + * If comma first character, then no local identifier + */ + if (comma != arg) { + c = *comma; + *comma = '\0'; + + if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (local): %s", arg); + return 0; + } + + if (option_priority >= prio_local) { + eui64_copy(addr.s6_addr32[2], wo->ourid); + wo->opt_local = 1; + prio_local = option_priority; + } + *comma = c; + } + + /* + * If comma last character, the no remote identifier + */ + if (*comma != 0 && *++comma != '\0') { + if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { + option_error("Illegal interface identifier (remote): %s", comma); + return 0; + } + if (option_priority >= prio_remote) { + eui64_copy(addr.s6_addr32[2], wo->hisid); + wo->opt_remote = 1; + prio_remote = option_priority; + } + } + + if (override_value("+ipv6", option_priority, option_source)) + ipv6cp_protent.enabled_flag = 1; + return 1; +} + +static void +printifaceid(opt, printer, arg) + option_t *opt; + void (*printer)(void *, char *, ...)); + void *arg; +{ + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + + if (wo->opt_local) + printer(arg, "%s", llv6_ntoa(wo->ourid)); + printer(arg, ","); + if (wo->opt_remote) + printer(arg, "%s", llv6_ntoa(wo->hisid)); +} +#endif /* PPP_OPTIONS */ + +/* + * Make a string representation of a network address. + */ +static char * +llv6_ntoa(eui64_t ifaceid) +{ + static char b[64]; + + sprintf(b, "fe80::%s", eui64_ntoa(ifaceid)); + return b; +} + + +/* + * ipv6cp_init - Initialize IPV6CP. + */ +static void ipv6cp_init(ppp_pcb *pcb) { + fsm *f = &pcb->ipv6cp_fsm; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; + + f->pcb = pcb; + f->protocol = PPP_IPV6CP; + f->callbacks = &ipv6cp_callbacks; + fsm_init(f); + + memset(wo, 0, sizeof(*wo)); + memset(ao, 0, sizeof(*ao)); + + wo->accept_local = 1; + wo->neg_ifaceid = 1; + ao->neg_ifaceid = 1; + +#ifdef IPV6CP_COMP + wo->neg_vj = 1; + ao->neg_vj = 1; + wo->vj_protocol = IPV6CP_COMP; +#endif + +} + + +/* + * ipv6cp_open - IPV6CP is allowed to come up. + */ +static void ipv6cp_open(ppp_pcb *pcb) { + fsm_open(&pcb->ipv6cp_fsm); +} + + +/* + * ipv6cp_close - Take IPV6CP down. + */ +static void ipv6cp_close(ppp_pcb *pcb, const char *reason) { + fsm_close(&pcb->ipv6cp_fsm, reason); +} + + +/* + * ipv6cp_lowerup - The lower layer is up. + */ +static void ipv6cp_lowerup(ppp_pcb *pcb) { + fsm_lowerup(&pcb->ipv6cp_fsm); +} + + +/* + * ipv6cp_lowerdown - The lower layer is down. + */ +static void ipv6cp_lowerdown(ppp_pcb *pcb) { + fsm_lowerdown(&pcb->ipv6cp_fsm); +} + + +/* + * ipv6cp_input - Input IPV6CP packet. + */ +static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len) { + fsm_input(&pcb->ipv6cp_fsm, p, len); +} + + +/* + * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. + * + * Pretend the lower layer went down, so we shut up. + */ +static void ipv6cp_protrej(ppp_pcb *pcb) { + fsm_lowerdown(&pcb->ipv6cp_fsm); +} + + +/* + * ipv6cp_resetci - Reset our CI. + */ +static void ipv6cp_resetci(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; + + wo->req_ifaceid = wo->neg_ifaceid && ao->neg_ifaceid; + + if (!wo->opt_local) { + eui64_magic_nz(wo->ourid); + } + + *go = *wo; + eui64_zero(go->hisid); /* last proposed interface identifier */ +} + + +/* + * ipv6cp_cilen - Return length of our CI. + */ +static int ipv6cp_cilen(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + +#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) +#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) + + return (LENCIIFACEID(go->neg_ifaceid) + + LENCIVJ(go->neg_vj)); +} + + +/* + * ipv6cp_addci - Add our desired CIs to a packet. + */ +static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + int len = *lenp; + +#define ADDCIVJ(opt, neg, val) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + if (len >= vjlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(vjlen, ucp); \ + PUTSHORT(val, ucp); \ + len -= vjlen; \ + } else \ + neg = 0; \ + } + +#define ADDCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if (len >= idlen) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(idlen, ucp); \ + eui64_put(val1, ucp); \ + len -= idlen; \ + } else \ + neg = 0; \ + } + + ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + *lenp -= len; +} + + +/* + * ipv6cp_ackci - Ack our CIs. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int ipv6cp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + u_short cilen, citype, cishort; + eui64_t ifaceid; + + /* + * CIs must be in exactly the same order that we sent... + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ + +#define ACKCIVJ(opt, neg, val) \ + if (neg) { \ + int vjlen = CILEN_COMPRESS; \ + if ((len -= vjlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != vjlen || \ + citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + } + +#define ACKCIIFACEID(opt, neg, val1) \ + if (neg) { \ + int idlen = CILEN_IFACEID; \ + if ((len -= idlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != idlen || \ + citype != opt) \ + goto bad; \ + eui64_get(ifaceid, p); \ + if (! eui64_equals(val1, ifaceid)) \ + goto bad; \ + } + + ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); + + ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); + +bad: + IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); + return (0); +} + +/* + * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if IPV6CP is in the OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + u_char citype, cilen, *next; + u_short cishort; + eui64_t ifaceid; + ipv6cp_options no; /* options we've seen Naks for */ + ipv6cp_options try_; /* options to request next time */ + + BZERO(&no, sizeof(no)); + try_ = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIIFACEID(opt, neg, code) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + no.neg = 1; \ + code \ + } + +#define NAKCIVJ(opt, neg, code) \ + if (go->neg && \ + ((cilen = p[1]) == CILEN_COMPRESS) && \ + len >= cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } + + /* + * Accept the peer's idea of {our,his} interface identifier, if different + * from our idea, only if the accept_{local,remote} flag is set. + */ + NAKCIIFACEID(CI_IFACEID, neg_ifaceid, + if (treat_as_reject) { + try_.neg_ifaceid = 0; + } else if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try_.ourid = ifaceid; + IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); + } + ); + +#ifdef IPV6CP_COMP + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + if (cishort == IPV6CP_COMP && !treat_as_reject) { + try_.vj_protocol = cishort; + } else { + try_.neg_vj = 0; + } + } + ); +#else + NAKCIVJ(CI_COMPRESSTYPE, neg_vj, + { + try_.neg_vj = 0; + } + ); +#endif + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If they want to negotiate about interface identifier, we comply. + * If they want us to ask for compression, we refuse. + */ + while (len >= CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) + goto bad; + next = p + cilen - 2; + + switch (citype) { + case CI_COMPRESSTYPE: + if (go->neg_vj || no.neg_vj || + (cilen != CILEN_COMPRESS)) + goto bad; + no.neg_vj = 1; + break; + case CI_IFACEID: + if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) + goto bad; + try_.neg_ifaceid = 1; + eui64_get(ifaceid, p); + if (go->accept_local) { + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->hisid)) /* bad luck */ + eui64_magic(ifaceid); + try_.ourid = ifaceid; + } + no.neg_ifaceid = 1; + break; + default: + break; + } + p = next; + } + + /* If there is still anything left, this packet is bad. */ + if (len != 0) + goto bad; + + /* + * OK, the Nak is good. Now we can update state. + */ + if (f->state != PPP_FSM_OPENED) + *go = try_; + + return 1; + +bad: + IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); + return 0; +} + + +/* + * ipv6cp_rejci - Reject some of our CIs. + */ +static int ipv6cp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + u_char cilen; + u_short cishort; + eui64_t ifaceid; + ipv6cp_options try_; /* options to request next time */ + + try_ = *go; + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIIFACEID(opt, neg, val1) \ + if (go->neg && \ + len >= (cilen = CILEN_IFACEID) && \ + p[1] == cilen && \ + p[0] == opt) { \ + len -= cilen; \ + INCPTR(2, p); \ + eui64_get(ifaceid, p); \ + /* Check rejected value. */ \ + if (! eui64_equals(ifaceid, val1)) \ + goto bad; \ + try_.neg = 0; \ + } + +#define REJCIVJ(opt, neg, val) \ + if (go->neg && \ + p[1] == CILEN_COMPRESS && \ + len >= p[1] && \ + p[0] == opt) { \ + len -= p[1]; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) \ + goto bad; \ + try_.neg = 0; \ + } + + REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); + + REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + /* + * Now we can update state. + */ + if (f->state != PPP_FSM_OPENED) + *go = try_; + return 1; + +bad: + IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); + return 0; +} + + +/* + * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + * + * inp = Requested CIs + * len = Length of requested CIs + * + */ +static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + u_char *cip, *next; /* Pointer to current and next CIs */ + u_short cilen, citype; /* Parsed len, type */ + u_short cishort; /* Parsed short value */ + eui64_t ifaceid; /* Parsed interface identifier */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *ucp = inp; /* Pointer to current output char */ + int l = *len; /* Length left */ + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_IFACEID: + IPV6CPDEBUG(("ipv6cp: received interface identifier ")); + + if (!ao->neg_ifaceid || + cilen != CILEN_IFACEID) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + + /* + * If he has no interface identifier, or if we both have same + * identifier then NAK it with new idea. + * In particular, if we don't know his identifier, but he does, + * then accept it. + */ + eui64_get(ifaceid, p); + IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); + if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { + orc = CONFREJ; /* Reject CI */ + break; + } + if (!eui64_iszero(wo->hisid) && + !eui64_equals(ifaceid, wo->hisid) && + eui64_iszero(go->hisid)) { + + orc = CONFNAK; + ifaceid = wo->hisid; + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } else + if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { + orc = CONFNAK; + if (eui64_iszero(go->hisid)) /* first time, try option */ + ifaceid = wo->hisid; + while (eui64_iszero(ifaceid) || + eui64_equals(ifaceid, go->ourid)) /* bad luck */ + eui64_magic(ifaceid); + go->hisid = ifaceid; + DECPTR(sizeof(ifaceid), p); + eui64_put(ifaceid, p); + } + + ho->neg_ifaceid = 1; + ho->hisid = ifaceid; + break; + + case CI_COMPRESSTYPE: + IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); + if (!ao->neg_vj || + (cilen != CILEN_COMPRESS)) { + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + IPV6CPDEBUG(("(%d)", cishort)); + +#ifdef IPV6CP_COMP + if (!(cishort == IPV6CP_COMP)) { + orc = CONFREJ; + break; + } + + ho->neg_vj = 1; + ho->vj_protocol = cishort; + break; +#else + orc = CONFREJ; + break; +#endif + + default: + orc = CONFREJ; + break; + } + +endswitch: + IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); + + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) /* but prior CI wasnt? */ + continue; /* Don't send this one */ + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree) /* Getting fed up with sending NAKs? */ + orc = CONFREJ; /* Get tough if so */ + else { + if (rc == CONFREJ) /* Rejecting prior CI? */ + continue; /* Don't send this one */ + if (rc == CONFACK) { /* Ack'd all prior CIs? */ + rc = CONFNAK; /* Not anymore... */ + ucp = inp; /* Backup */ + } + } + } + + if (orc == CONFREJ && /* Reject this CI */ + rc != CONFREJ) { /* but no prior ones? */ + rc = CONFREJ; + ucp = inp; /* Backup */ + } + + /* Need to move CI? */ + if (ucp != cip) + MEMCPY(ucp, cip, cilen); /* Move it */ + + /* Update output pointer */ + INCPTR(cilen, ucp); + } + + /* + * If we aren't rejecting this packet, and we want to negotiate + * their identifier and they didn't send their identifier, then we + * send a NAK with a CI_IFACEID option appended. We assume the + * input buffer is long enough that we can append the extra + * option safely. + */ + if (rc != CONFREJ && !ho->neg_ifaceid && + wo->req_ifaceid && !reject_if_disagree) { + if (rc == CONFACK) { + rc = CONFNAK; + ucp = inp; /* reset pointer */ + wo->req_ifaceid = 0; /* don't ask again */ + } + PUTCHAR(CI_IFACEID, ucp); + PUTCHAR(CILEN_IFACEID, ucp); + eui64_put(wo->hisid, ucp); + } + + *len = ucp - inp; /* Compute output length */ + IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); + return (rc); /* Return final code */ +} + +#if PPP_OPTIONS +/* + * ipv6_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. + */ +static void ipv6_check_options() { + ipv6cp_options *wo = &ipv6cp_wantoptions[0]; + + if (!ipv6cp_protent.enabled_flag) + return; + + /* + * Persistent link-local id is only used when user has not explicitly + * configure/hard-code the id + */ + if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { + + /* + * On systems where there are no Ethernet interfaces used, there + * may be other ways to obtain a persistent id. Right now, it + * will fall back to using magic [see eui64_magic] below when + * an EUI-48 from MAC address can't be obtained. Other possibilities + * include obtaining EEPROM serial numbers, or some other unique + * yet persistent number. On Sparc platforms, this is possible, + * but too bad there's no standards yet for x86 machines. + */ + if (ether_to_eui64(&wo->ourid)) { + wo->opt_local = 1; + } + } + + if (!wo->opt_local) { /* init interface identifier */ + if (wo->use_ip && eui64_iszero(wo->ourid)) { + eui64_setlo32(wo->ourid, ntohl(ipcp_wantoptions[0].ouraddr)); + if (!eui64_iszero(wo->ourid)) + wo->opt_local = 1; + } + + while (eui64_iszero(wo->ourid)) + eui64_magic(wo->ourid); + } + + if (!wo->opt_remote) { + if (wo->use_ip && eui64_iszero(wo->hisid)) { + eui64_setlo32(wo->hisid, ntohl(ipcp_wantoptions[0].hisaddr)); + if (!eui64_iszero(wo->hisid)) + wo->opt_remote = 1; + } + } + + if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { + option_error("local/remote LL address required for demand-dialling\n"); + exit(1); + } +} +#endif /* PPP_OPTIONS */ + +#if DEMAND_SUPPORT +/* + * ipv6_demand_conf - configure the interface as though + * IPV6CP were up, for use with dial-on-demand. + */ +static int ipv6_demand_conf(int u) { + ipv6cp_options *wo = &ipv6cp_wantoptions[u]; + + if (!sif6up(u)) + return 0; + + if (!sif6addr(u, wo->ourid, wo->hisid)) + return 0; + + if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) + return 0; + + ppp_notice("ipv6_demand_conf"); + ppp_notice("local LL address %s", llv6_ntoa(wo->ourid)); + ppp_notice("remote LL address %s", llv6_ntoa(wo->hisid)); + + return 1; +} +#endif /* DEMAND_SUPPORT */ + + +/* + * ipv6cp_up - IPV6CP has come UP. + * + * Configure the IPv6 network interface appropriately and bring it up. + */ +static void ipv6cp_up(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + + IPV6CPDEBUG(("ipv6cp: up")); + + /* + * We must have a non-zero LL address for both ends of the link. + */ + if (!ho->neg_ifaceid) + ho->hisid = wo->hisid; + +#if 0 /* UNUSED */ + if(!no_ifaceid_neg) { +#endif /* UNUSED */ + if (eui64_iszero(ho->hisid)) { + ppp_error("Could not determine remote LL address"); + ipv6cp_close(f->pcb, "Could not determine remote LL address"); + return; + } + if (eui64_iszero(go->ourid)) { + ppp_error("Could not determine local LL address"); + ipv6cp_close(f->pcb, "Could not determine local LL address"); + return; + } + if (eui64_equals(go->ourid, ho->hisid)) { + ppp_error("local and remote LL addresses are equal"); + ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); + return; + } +#if 0 /* UNUSED */ + } +#endif /* UNUSED */ +#if 0 /* UNUSED */ + script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); + script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); +#endif /* UNUSED */ + +#ifdef IPV6CP_COMP + /* set tcp compression */ + sif6comp(f->unit, ho->neg_vj); +#endif + +#if DEMAND_SUPPORT + /* + * If we are doing dial-on-demand, the interface is already + * configured, so we put out any saved-up packets, then set the + * interface to pass IPv6 packets. + */ + if (demand) { + if (! eui64_equals(go->ourid, wo->ourid) || + ! eui64_equals(ho->hisid, wo->hisid)) { + if (! eui64_equals(go->ourid, wo->ourid)) + warn("Local LL address changed to %s", + llv6_ntoa(go->ourid)); + if (! eui64_equals(ho->hisid, wo->hisid)) + warn("Remote LL address changed to %s", + llv6_ntoa(ho->hisid)); + ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid); + + /* Set the interface to the new addresses */ + if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { + if (debug) + warn("sif6addr failed"); + ipv6cp_close(f->unit, "Interface configuration failed"); + return; + } + + } + demand_rexmit(PPP_IPV6); + sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + + } else +#endif /* DEMAND_SUPPORT */ + { + /* + * Set LL addresses + */ + if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { + PPPDEBUG(LOG_DEBUG, ("sif6addr failed")); + ipv6cp_close(f->pcb, "Interface configuration failed"); + return; + } + + /* bring the interface up for IPv6 */ + if (!sif6up(f->pcb)) { + PPPDEBUG(LOG_DEBUG, ("sif6up failed (IPV6)")); + ipv6cp_close(f->pcb, "Interface configuration failed"); + return; + } + sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); + + ppp_notice("local LL address %s", llv6_ntoa(go->ourid)); + ppp_notice("remote LL address %s", llv6_ntoa(ho->hisid)); + } + + np_up(f->pcb, PPP_IPV6); + pcb->ipv6cp_is_up = 1; + +#if 0 /* UNUSED */ + /* + * Execute the ipv6-up script, like this: + * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL + */ + if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { + ipv6cp_script_state = s_up; + ipv6cp_script(_PATH_IPV6UP); + } +#endif /* UNUSED */ +} + + +/* + * ipv6cp_down - IPV6CP has gone DOWN. + * + * Take the IPv6 network interface down, clear its addresses + * and delete routes through it. + */ +static void ipv6cp_down(fsm *f) { + ppp_pcb *pcb = f->pcb; + ipv6cp_options *go = &pcb->ipv6cp_gotoptions; + ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; + + IPV6CPDEBUG(("ipv6cp: down")); +#if PPP_STATS_SUPPORT + update_link_stats(f->unit); +#endif /* PPP_STATS_SUPPORT */ + if (pcb->ipv6cp_is_up) { + pcb->ipv6cp_is_up = 0; + np_down(f->pcb, PPP_IPV6); + } +#ifdef IPV6CP_COMP + sif6comp(f->unit, 0); +#endif + +#if DEMAND_SUPPORT + /* + * If we are doing dial-on-demand, set the interface + * to queue up outgoing packets (for now). + */ + if (demand) { + sifnpmode(f->pcb, PPP_IPV6, NPMODE_QUEUE); + } else +#endif /* DEMAND_SUPPORT */ + { + sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP); + ipv6cp_clear_addrs(f->pcb, + go->ourid, + ho->hisid); + sif6down(f->pcb); + } + +#if 0 /* UNUSED */ + /* Execute the ipv6-down script */ + if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { + ipv6cp_script_state = s_down; + ipv6cp_script(_PATH_IPV6DOWN); + } +#endif /* UNUSED */ +} + + +/* + * ipv6cp_clear_addrs() - clear the interface addresses, routes, + * proxy neighbour discovery entries, etc. + */ +static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid) { + cif6addr(pcb, ourid, hisid); +} + + +/* + * ipv6cp_finished - possibly shut down the lower layers. + */ +static void ipv6cp_finished(fsm *f) { + np_finished(f->pcb, PPP_IPV6); +} + + +#if 0 /* UNUSED */ +/* + * ipv6cp_script_done - called when the ipv6-up or ipv6-down script + * has finished. + */ +static void +ipv6cp_script_done(arg) + void *arg; +{ + ipv6cp_script_pid = 0; + switch (ipv6cp_script_state) { + case s_up: + if (ipv6cp_fsm[0].state != PPP_FSM_OPENED) { + ipv6cp_script_state = s_down; + ipv6cp_script(_PATH_IPV6DOWN); + } + break; + case s_down: + if (ipv6cp_fsm[0].state == PPP_FSM_OPENED) { + ipv6cp_script_state = s_up; + ipv6cp_script(_PATH_IPV6UP); + } + break; + } +} + + +/* + * ipv6cp_script - Execute a script with arguments + * interface-name tty-name speed local-LL remote-LL. + */ +static void +ipv6cp_script(script) + char *script; +{ + char strspeed[32], strlocal[32], strremote[32]; + char *argv[8]; + + sprintf(strspeed, "%d", baud_rate); + strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); + strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); + + argv[0] = script; + argv[1] = ifname; + argv[2] = devnam; + argv[3] = strspeed; + argv[4] = strlocal; + argv[5] = strremote; + argv[6] = ipparam; + argv[7] = NULL; + + ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, + NULL, 0); +} +#endif /* UNUSED */ + +#if PRINTPKT_SUPPORT +/* + * ipv6cp_printpkt - print the contents of an IPV6CP packet. + */ +static const char *ipv6cp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej" +}; + +static int ipv6cp_printpkt(u_char *p, int plen, + void (*printer)(void *, const char *, ...), void *arg) { + int code, id, len, olen; + u_char *pstart, *optend; + u_short cishort; + eui64_t ifaceid; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= (int)sizeof(ipv6cp_codenames) / (int)sizeof(char *)) + printer(arg, " %s", ipv6cp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_COMPRESSTYPE: + if (olen >= CILEN_COMPRESS) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "compress "); + printer(arg, "0x%x", cishort); + } + break; + case CI_IFACEID: + if (olen == CILEN_IFACEID) { + p += 2; + eui64_get(ifaceid, p); + printer(arg, "addr %s", llv6_ntoa(ifaceid)); + } + break; + default: + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + ppp_print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + default: + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; +} +#endif /* PRINTPKT_SUPPORT */ + +#if DEMAND_SUPPORT +/* + * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. + * We don't bring the link up for IP fragments or for TCP FIN packets + * with no data. + */ +#define IP6_HDRLEN 40 /* bytes */ +#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ +#define TCP_HDRLEN 20 +#define TH_FIN 0x01 + +/* + * We use these macros because the IP header may be at an odd address, + * and some compilers might use word loads to get th_off or ip_hl. + */ + +#define get_ip6nh(x) (((unsigned char *)(x))[6]) +#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) +#define get_tcpflags(x) (((unsigned char *)(x))[13]) + +static int ipv6_active_pkt(u_char *pkt, int len) { + u_char *tcp; + + len -= PPP_HDRLEN; + pkt += PPP_HDRLEN; + if (len < IP6_HDRLEN) + return 0; + if (get_ip6nh(pkt) == IP6_NHDR_FRAG) + return 0; + if (get_ip6nh(pkt) != IPPROTO_TCP) + return 1; + if (len < IP6_HDRLEN + TCP_HDRLEN) + return 0; + tcp = pkt + IP6_HDRLEN; + if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) + return 0; + return 1; +} +#endif /* DEMAND_SUPPORT */ + +#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/lcp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/lcp.c new file mode 100644 index 0000000..5aa99da --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/lcp.c @@ -0,0 +1,2732 @@ +/* + * lcp.c - PPP Link Control Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/* + * TODO: + */ + +#if 0 /* UNUSED */ +#include +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#if CHAP_SUPPORT +#include "netif/ppp/chap-new.h" +#endif /* CHAP_SUPPORT */ +#include "netif/ppp/magic.h" + +/* + * When the link comes up we want to be able to wait for a short while, + * or until seeing some input from the peer, before starting to send + * configure-requests. We do this by delaying the fsm_lowerup call. + */ +/* steal a bit in fsm flags word */ +#define DELAYED_UP 0x80 + +static void lcp_delayed_up(void *arg); + +/* + * LCP-related command-line options. + */ +#if 0 /* UNUSED */ +int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ +int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +/* options */ +static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ +static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ +#endif /* UNUSED */ + +#if 0 /* UNUSED */ +#if PPP_LCP_ADAPTIVE +bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ +#endif +bool lax_recv = 0; /* accept control chars in asyncmap */ +bool noendpoint = 0; /* don't send/accept endpoint discriminator */ +#endif /* UNUSED */ + +#if PPP_OPTIONS +static int noopt (char **); +#endif /* PPP_OPTIONS */ + +#ifdef HAVE_MULTILINK +static int setendpoint (char **); +static void printendpoint (option_t *, void (*)(void *, char *, ...), + void *); +#endif /* HAVE_MULTILINK */ + +#if PPP_OPTIONS +static option_t lcp_option_list[] = { + /* LCP options */ + { "-all", o_special_noarg, (void *)noopt, + "Don't request/allow any LCP options" }, + + { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, + "Disable address/control compression", + OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, + { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, + "Disable address/control compression", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, + + { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, + "Set asyncmap (for received packets)", + OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, + { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, + "Set asyncmap (for received packets)", + OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, + { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, + "Disable asyncmap negotiation", + OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, + &lcp_allowoptions[0].neg_asyncmap }, + { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, + "Disable asyncmap negotiation", + OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, + &lcp_allowoptions[0].neg_asyncmap }, + + { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, + "Disable magic number negotiation (looped-back line detection)", + OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, + { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, + "Disable magic number negotiation (looped-back line detection)", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, + + { "mru", o_int, &lcp_wantoptions[0].mru, + "Set MRU (maximum received packet size) for negotiation", + OPT_PRIO, &lcp_wantoptions[0].neg_mru }, + { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, + "Disable MRU negotiation (use default 1500)", + OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, + { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, + "Disable MRU negotiation (use default 1500)", + OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, + + { "mtu", o_int, &lcp_allowoptions[0].mru, + "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, + + { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, + "Disable protocol field compression", + OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, + { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, + "Disable protocol field compression", + OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, + + { "passive", o_bool, &lcp_wantoptions[0].passive, + "Set passive mode", 1 }, + { "-p", o_bool, &lcp_wantoptions[0].passive, + "Set passive mode", OPT_ALIAS | 1 }, + + { "silent", o_bool, &lcp_wantoptions[0].silent, + "Set silent mode", 1 }, + + { "lcp-echo-failure", o_int, &lcp_echo_fails, + "Set number of consecutive echo failures to indicate link failure", + OPT_PRIO }, + { "lcp-echo-interval", o_int, &lcp_echo_interval, + "Set time in seconds between LCP echo requests", OPT_PRIO }, +#if PPP_LCP_ADAPTIVE + { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, + "Suppress LCP echo requests if traffic was received", 1 }, +#endif + { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, + "Set time in seconds between LCP retransmissions", OPT_PRIO }, + { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, + "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, + { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, + "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, + { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, + "Set limit on number of LCP configure-naks", OPT_PRIO }, + + { "receive-all", o_bool, &lax_recv, + "Accept all received control characters", 1 }, + +#ifdef HAVE_MULTILINK + { "mrru", o_int, &lcp_wantoptions[0].mrru, + "Maximum received packet size for multilink bundle", + OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, + + { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, + "Use short sequence numbers in multilink headers", + OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, + { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, + "Don't use short sequence numbers in multilink headers", + OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, + + { "endpoint", o_special, (void *) setendpoint, + "Endpoint discriminator for multilink", + OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, +#endif /* HAVE_MULTILINK */ + + { "noendpoint", o_bool, &noendpoint, + "Don't send or accept multilink endpoint discriminator", 1 }, + + {NULL} +}; +#endif /* PPP_OPTIONS */ + +/* + * Callbacks for fsm code. (CI = Configuration Information) + */ +static void lcp_resetci(fsm *f); /* Reset our CI */ +static int lcp_cilen(fsm *f); /* Return length of our CI */ +static void lcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI to pkt */ +static int lcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ +static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ +static int lcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ +static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree); /* Rcv peer CI */ +static void lcp_up(fsm *f); /* We're UP */ +static void lcp_down(fsm *f); /* We're DOWN */ +static void lcp_starting (fsm *); /* We need lower layer up */ +static void lcp_finished (fsm *); /* We need lower layer down */ +static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len); +static void lcp_rprotrej(fsm *f, u_char *inp, int len); + +/* + * routines to send LCP echos to peer + */ + +static void lcp_echo_lowerup(ppp_pcb *pcb); +static void lcp_echo_lowerdown(ppp_pcb *pcb); +static void LcpEchoTimeout(void *arg); +static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len); +static void LcpSendEchoRequest(fsm *f); +static void LcpLinkFailure(fsm *f); +static void LcpEchoCheck(fsm *f); + +static const fsm_callbacks lcp_callbacks = { /* LCP callback routines */ + lcp_resetci, /* Reset our Configuration Information */ + lcp_cilen, /* Length of our Configuration Information */ + lcp_addci, /* Add our Configuration Information */ + lcp_ackci, /* ACK our Configuration Information */ + lcp_nakci, /* NAK our Configuration Information */ + lcp_rejci, /* Reject our Configuration Information */ + lcp_reqci, /* Request peer's Configuration Information */ + lcp_up, /* Called when fsm reaches OPENED state */ + lcp_down, /* Called when fsm leaves OPENED state */ + lcp_starting, /* Called when we want the lower layer up */ + lcp_finished, /* Called when we want the lower layer down */ + NULL, /* Called when Protocol-Reject received */ + NULL, /* Retransmission is necessary */ + lcp_extcode, /* Called to handle LCP-specific codes */ + "LCP" /* String name of protocol */ +}; + +/* + * Protocol entry points. + * Some of these are called directly. + */ + +static void lcp_init(ppp_pcb *pcb); +static void lcp_input(ppp_pcb *pcb, u_char *p, int len); +static void lcp_protrej(ppp_pcb *pcb); +#if PRINTPKT_SUPPORT +static int lcp_printpkt(u_char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ + +const struct protent lcp_protent = { + PPP_LCP, + lcp_init, + lcp_input, + lcp_protrej, + lcp_lowerup, + lcp_lowerdown, + lcp_open, + lcp_close, +#if PRINTPKT_SUPPORT + lcp_printpkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, + 1, +#if PRINTPKT_SUPPORT + "LCP", + NULL, +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + lcp_option_list, + NULL, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, + NULL +#endif /* DEMAND_SUPPORT */ +}; + +/* + * Length of each type of configuration option (in octets) + */ +#define CILEN_VOID 2 +#define CILEN_CHAR 3 +#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ +#if CHAP_SUPPORT +#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ +#endif /* CHAP_SUPPORT */ +#define CILEN_LONG 6 /* CILEN_VOID + 4 */ +#if LQR_SUPPORT +#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ +#endif /* LQR_SUPPORT */ +#define CILEN_CBCP 3 + +#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ + (x) == CONFNAK ? "NAK" : "REJ") + +#if PPP_OPTIONS +/* + * noopt - Disable all options (why?). + */ +static int +noopt(argv) + char **argv; +{ + BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); + BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); + + return (1); +} +#endif /* PPP_OPTIONS */ + +#ifdef HAVE_MULTILINK +static int +setendpoint(argv) + char **argv; +{ + if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { + lcp_wantoptions[0].neg_endpoint = 1; + return 1; + } + option_error("Can't parse '%s' as an endpoint discriminator", *argv); + return 0; +} + +static void +printendpoint(opt, printer, arg) + option_t *opt; + void (*printer) (void *, char *, ...); + void *arg; +{ + printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); +} +#endif /* HAVE_MULTILINK */ + +/* + * lcp_init - Initialize LCP. + */ +static void lcp_init(ppp_pcb *pcb) { + fsm *f = &pcb->lcp_fsm; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + f->pcb = pcb; + f->protocol = PPP_LCP; + f->callbacks = &lcp_callbacks; + + fsm_init(f); + + BZERO(wo, sizeof(*wo)); + wo->neg_mru = 1; + wo->mru = DEFMRU; + wo->neg_asyncmap = 1; + wo->neg_magicnumber = 1; + wo->neg_pcompression = 1; + wo->neg_accompression = 1; + + BZERO(ao, sizeof(*ao)); + ao->neg_mru = 1; + ao->mru = MAXMRU; + ao->neg_asyncmap = 1; +#if CHAP_SUPPORT + ao->neg_chap = 1; + ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + ao->neg_upap = 1; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + ao->neg_eap = 1; +#endif /* EAP_SUPPORT */ + ao->neg_magicnumber = 1; + ao->neg_pcompression = 1; + ao->neg_accompression = 1; + ao->neg_endpoint = 1; + +#if PPPOS_SUPPORT + /* + * Set transmit escape for the flag and escape characters plus anything + * set for the allowable options. + */ + memset(pcb->xmit_accm, 0, sizeof(ext_accm)); + pcb->xmit_accm[15] = 0x60; + pcb->xmit_accm[0] = (u_char)((ao->asyncmap & 0xFF)); + pcb->xmit_accm[1] = (u_char)((ao->asyncmap >> 8) & 0xFF); + pcb->xmit_accm[2] = (u_char)((ao->asyncmap >> 16) & 0xFF); + pcb->xmit_accm[3] = (u_char)((ao->asyncmap >> 24) & 0xFF); + LCPDEBUG(("lcp_init: xmit_accm=%X %X %X %X\n", + pcb->xmit_accm[0], + pcb->xmit_accm[1], + pcb->xmit_accm[2], + pcb->xmit_accm[3])); +#endif /* PPPOS_SUPPORT */ +} + + +/* + * lcp_open - LCP is allowed to come up. + */ +void lcp_open(ppp_pcb *pcb) { + fsm *f = &pcb->lcp_fsm; + lcp_options *wo = &pcb->lcp_wantoptions; + + f->flags &= ~(OPT_PASSIVE | OPT_SILENT); + if (wo->passive) + f->flags |= OPT_PASSIVE; + if (wo->silent) + f->flags |= OPT_SILENT; + fsm_open(f); +} + + +/* + * lcp_close - Take LCP down. + */ +void lcp_close(ppp_pcb *pcb, const char *reason) { + fsm *f = &pcb->lcp_fsm; + int oldstate; + + if (pcb->phase != PPP_PHASE_DEAD && pcb->phase != PPP_PHASE_MASTER) + new_phase(pcb, PPP_PHASE_TERMINATE); + + if (f->flags & DELAYED_UP) { + UNTIMEOUT(lcp_delayed_up, f); + f->state = PPP_FSM_STOPPED; + } + oldstate = f->state; + + fsm_close(f, reason); + if (oldstate == PPP_FSM_STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { + /* + * This action is not strictly according to the FSM in RFC1548, + * but it does mean that the program terminates if you do a + * lcp_close() when a connection hasn't been established + * because we are in passive/silent mode or because we have + * delayed the fsm_lowerup() call and it hasn't happened yet. + */ + f->flags &= ~DELAYED_UP; + lcp_finished(f); + } +} + + +/* + * lcp_lowerup - The lower layer is up. + */ +void lcp_lowerup(ppp_pcb *pcb) { + lcp_options *wo = &pcb->lcp_wantoptions; +#if PPPOS_SUPPORT + lcp_options *ao = &pcb->lcp_allowoptions; +#endif /* PPPOS_SUPPORT */ + fsm *f = &pcb->lcp_fsm; + /* + * Don't use A/C or protocol compression on transmission, + * but accept A/C and protocol compressed packets + * if we are going to ask for A/C and protocol compression. + */ +#if PPPOS_SUPPORT + ppp_set_xaccm(pcb, &pcb->xmit_accm); +#endif /* PPPOS_SUPPORT */ + if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 + || ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff), + wo->neg_pcompression, wo->neg_accompression) < 0) + return; + pcb->peer_mru = PPP_MRU; + +#if PPPOS_SUPPORT + ao->asyncmap = (u_long)pcb->xmit_accm[0] + | ((u_long)pcb->xmit_accm[1] << 8) + | ((u_long)pcb->xmit_accm[2] << 16) + | ((u_long)pcb->xmit_accm[3] << 24); + LCPDEBUG(("lcp_lowerup: asyncmap=%X %X %X %X\n", + pcb->xmit_accm[3], + pcb->xmit_accm[2], + pcb->xmit_accm[1], + pcb->xmit_accm[0])); +#endif /* PPPOS_SUPPORT */ + + if (pcb->settings.listen_time != 0) { + f->flags |= DELAYED_UP; + TIMEOUTMS(lcp_delayed_up, f, pcb->settings.listen_time); + } else + fsm_lowerup(f); +} + + +/* + * lcp_lowerdown - The lower layer is down. + */ +void lcp_lowerdown(ppp_pcb *pcb) { + fsm *f = &pcb->lcp_fsm; + + if (f->flags & DELAYED_UP) { + f->flags &= ~DELAYED_UP; + UNTIMEOUT(lcp_delayed_up, f); + } else + fsm_lowerdown(f); +} + + +/* + * lcp_delayed_up - Bring the lower layer up now. + */ +static void lcp_delayed_up(void *arg) { + fsm *f = (fsm*)arg; + + if (f->flags & DELAYED_UP) { + f->flags &= ~DELAYED_UP; + fsm_lowerup(f); + } +} + + +/* + * lcp_input - Input LCP packet. + */ +static void lcp_input(ppp_pcb *pcb, u_char *p, int len) { + fsm *f = &pcb->lcp_fsm; + + if (f->flags & DELAYED_UP) { + f->flags &= ~DELAYED_UP; + UNTIMEOUT(lcp_delayed_up, f); + fsm_lowerup(f); + } + fsm_input(f, p, len); +} + +/* + * lcp_extcode - Handle a LCP-specific code. + */ +static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u_char *magp; + + switch( code ){ + case PROTREJ: + lcp_rprotrej(f, inp, len); + break; + + case ECHOREQ: + if (f->state != PPP_FSM_OPENED) + break; + magp = inp; + PUTLONG(go->magicnumber, magp); + fsm_sdata(f, ECHOREP, id, inp, len); + break; + + case ECHOREP: + lcp_received_echo_reply(f, id, inp, len); + break; + + case DISCREQ: + case IDENTIF: + case TIMEREM: + break; + + default: + return 0; + } + return 1; +} + + +/* + * lcp_rprotrej - Receive an Protocol-Reject. + * + * Figure out which protocol is rejected and inform it. + */ +static void lcp_rprotrej(fsm *f, u_char *inp, int len) { + int i; + const struct protent *protp; + u_short prot; +#if PPP_PROTOCOLNAME + const char *pname; +#endif /* PPP_PROTOCOLNAME */ + + if (len < 2) { + LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); + return; + } + + GETSHORT(prot, inp); + + /* + * Protocol-Reject packets received in any state other than the LCP + * OPENED state SHOULD be silently discarded. + */ + if( f->state != PPP_FSM_OPENED ){ + LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); + return; + } + +#if PPP_PROTOCOLNAME + pname = protocol_name(prot); +#endif /* PPP_PROTOCOLNAME */ + + /* + * Upcall the proper Protocol-Reject routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (protp->protocol == prot && protp->enabled_flag) { +#if PPP_PROTOCOLNAME + if (pname != NULL) + ppp_dbglog("Protocol-Reject for '%s' (0x%x) received", pname, + prot); + else +#endif /* PPP_PROTOCOLNAME */ + ppp_dbglog("Protocol-Reject for 0x%x received", prot); + (*protp->protrej)(f->pcb); + return; + } + +#if PPP_PROTOCOLNAME + if (pname != NULL) + ppp_warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, + prot); + else +#endif /* #if PPP_PROTOCOLNAME */ + ppp_warn("Protocol-Reject for unsupported protocol 0x%x", prot); +} + + +/* + * lcp_protrej - A Protocol-Reject was received. + */ +/*ARGSUSED*/ +static void lcp_protrej(ppp_pcb *pcb) { + /* + * Can't reject LCP! + */ + ppp_error("Received Protocol-Reject for LCP!"); + fsm_protreject(&pcb->lcp_fsm); +} + + +/* + * lcp_sprotrej - Send a Protocol-Reject for some protocol. + */ +void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) { + fsm *f = &pcb->lcp_fsm; + /* + * Send back the protocol and the information field of the + * rejected packet. We only get here if LCP is in the OPENED state. + */ +#if 0 + p += 2; + len -= 2; +#endif + + fsm_sdata(f, PROTREJ, ++f->id, + p, len); +} + + +/* + * lcp_resetci - Reset our CI. + */ +static void lcp_resetci(fsm *f) { + ppp_pcb *pcb = f->pcb; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + wo->magicnumber = magic(); + wo->numloops = 0; + *go = *wo; +#ifdef HAVE_MULTILINK + if (!multilink) { + go->neg_mrru = 0; +#endif /* HAVE_MULTILINK */ + go->neg_ssnhf = 0; + go->neg_endpoint = 0; +#ifdef HAVE_MULTILINK + } +#endif /* HAVE_MULTILINK */ + if (pcb->settings.noendpoint) + ao->neg_endpoint = 0; + pcb->peer_mru = PPP_MRU; + auth_reset(pcb); +} + + +/* + * lcp_cilen - Return length of our CI. + */ +static int lcp_cilen(fsm *f) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + +#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) +#if CHAP_SUPPORT +#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) +#endif /* CHAP_SUPPORT */ +#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) +#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) +#if LQR_SUPPORT +#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) +#endif /* LQR_SUPPORT */ +#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) + /* + * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will + * accept more than one. We prefer EAP first, then CHAP, then + * PAP. + */ + return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) + + LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + +#if EAP_SUPPORT + LENCISHORT(go->neg_eap) + +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT + LENCICHAP(!go->neg_eap && go->neg_chap) + +#endif /* EAP_SUPPORT */ +#if !EAP_SUPPORT + LENCICHAP(go->neg_chap) + +#endif /* !EAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + LENCISHORT(!go->neg_eap && go->neg_upap) + +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + LENCISHORT(!go->neg_chap && go->neg_upap) + +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + LENCISHORT(go->neg_upap) + +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ +#endif /* PAP_SUPPORT */ +#if LQR_SUPPORT + LENCILQR(go->neg_lqr) + +#endif /* LQR_SUPPORT */ + LENCICBCP(go->neg_cbcp) + + LENCILONG(go->neg_magicnumber) + + LENCIVOID(go->neg_pcompression) + + LENCIVOID(go->neg_accompression) + +#ifdef HAVE_MULTILINK + LENCISHORT(go->neg_mrru) + +#endif /* HAVE_MULTILINK */ + LENCIVOID(go->neg_ssnhf) + + (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); +} + + +/* + * lcp_addci - Add our desired CIs to a packet. + */ +static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u_char *start_ucp = ucp; + +#define ADDCIVOID(opt, neg) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_VOID, ucp); \ + } +#define ADDCISHORT(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_SHORT, ucp); \ + PUTSHORT(val, ucp); \ + } +#if CHAP_SUPPORT +#define ADDCICHAP(opt, neg, val) \ + if (neg) { \ + PUTCHAR((opt), ucp); \ + PUTCHAR(CILEN_CHAP, ucp); \ + PUTSHORT(PPP_CHAP, ucp); \ + PUTCHAR((CHAP_DIGEST(val)), ucp); \ + } +#endif /* CHAP_SUPPORT */ +#define ADDCILONG(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LONG, ucp); \ + PUTLONG(val, ucp); \ + } +#if LQR_SUPPORT +#define ADDCILQR(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_LQR, ucp); \ + PUTSHORT(PPP_LQR, ucp); \ + PUTLONG(val, ucp); \ + } +#endif /* LQR_SUPPORT */ +#define ADDCICHAR(opt, neg, val) \ + if (neg) { \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR, ucp); \ + PUTCHAR(val, ucp); \ + } +#define ADDCIENDP(opt, neg, class, val, len) \ + if (neg) { \ + int i; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(CILEN_CHAR + len, ucp); \ + PUTCHAR(class, ucp); \ + for (i = 0; i < len; ++i) \ + PUTCHAR(val[i], ucp); \ + } + + ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); + ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, + go->asyncmap); +#if EAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT + ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); +#endif /* EAP_SUPPORT */ +#if !EAP_SUPPORT + ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); +#endif /* !EAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ +#endif /* PAP_SUPPORT */ +#if LQR_SUPPORT + ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ + ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); +#ifdef HAVE_MULTILINK + ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); +#endif + ADDCIVOID(CI_SSNHF, go->neg_ssnhf); + ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, + go->endpoint.value, go->endpoint.length); + + if (ucp - start_ucp != *lenp) { + /* this should never happen, because peer_mtu should be 1500 */ + ppp_error("Bug in lcp_addci: wrong length"); + } +} + + +/* + * lcp_ackci - Ack our CIs. + * This should not modify any state if the Ack is bad. + * + * Returns: + * 0 - Ack was bad. + * 1 - Ack was good. + */ +static int lcp_ackci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u_char cilen, citype, cichar; + u_short cishort; + u32_t cilong; + + /* + * CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define ACKCIVOID(opt, neg) \ + if (neg) { \ + if ((len -= CILEN_VOID) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_VOID || \ + citype != opt) \ + goto bad; \ + } +#define ACKCISHORT(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_SHORT) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_SHORT || \ + citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != val) \ + goto bad; \ + } +#define ACKCICHAR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR || \ + citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != val) \ + goto bad; \ + } +#if CHAP_SUPPORT +#define ACKCICHAP(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_CHAP) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAP || \ + citype != (opt)) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != PPP_CHAP) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != (CHAP_DIGEST(val))) \ + goto bad; \ + } +#endif /* CHAP_SUPPORT */ +#define ACKCILONG(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LONG) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LONG || \ + citype != opt) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } +#if LQR_SUPPORT +#define ACKCILQR(opt, neg, val) \ + if (neg) { \ + if ((len -= CILEN_LQR) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_LQR || \ + citype != opt) \ + goto bad; \ + GETSHORT(cishort, p); \ + if (cishort != PPP_LQR) \ + goto bad; \ + GETLONG(cilong, p); \ + if (cilong != val) \ + goto bad; \ + } +#endif /* LQR_SUPPORT */ +#define ACKCIENDP(opt, neg, class, val, vlen) \ + if (neg) { \ + int i; \ + if ((len -= CILEN_CHAR + vlen) < 0) \ + goto bad; \ + GETCHAR(citype, p); \ + GETCHAR(cilen, p); \ + if (cilen != CILEN_CHAR + vlen || \ + citype != opt) \ + goto bad; \ + GETCHAR(cichar, p); \ + if (cichar != class) \ + goto bad; \ + for (i = 0; i < vlen; ++i) { \ + GETCHAR(cichar, p); \ + if (cichar != val[i]) \ + goto bad; \ + } \ + } + + ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru); + ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, + go->asyncmap); +#if EAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT + ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); +#endif /* EAP_SUPPORT */ +#if !EAP_SUPPORT + ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); +#endif /* !EAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ +#if EAP_SUPPORT && CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && CHAP_SUPPORT */ +#if EAP_SUPPORT && !CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); +#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ +#if !EAP_SUPPORT && CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ +#if !EAP_SUPPORT && !CHAP_SUPPORT + ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); +#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ +#endif /* PAP_SUPPORT */ +#if LQR_SUPPORT + ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ + ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); + ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); + ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); + ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); +#ifdef HAVE_MULTILINK + ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); +#endif /* HAVE_MULTILINK */ + ACKCIVOID(CI_SSNHF, go->neg_ssnhf); + ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, + go->endpoint.value, go->endpoint.length); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + return (1); +bad: + LCPDEBUG(("lcp_acki: received bad Ack!")); + return (0); +} + + +/* + * lcp_nakci - Peer has sent a NAK for some of our CIs. + * This should not modify any state if the Nak is bad + * or if LCP is in the OPENED state. + * + * Returns: + * 0 - Nak was bad. + * 1 - Nak was good. + */ +static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *wo = &pcb->lcp_wantoptions; + u_char citype, cichar, *next; + u_short cishort; + u32_t cilong; + lcp_options no; /* options we've seen Naks for */ + lcp_options try_; /* options to request next time */ + int looped_back = 0; + int cilen; + + BZERO(&no, sizeof(no)); + try_ = *go; + + /* + * Any Nak'd CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define NAKCIVOID(opt, neg) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + no.neg = 1; \ + try_.neg = 0; \ + } +#if CHAP_SUPPORT +#define NAKCICHAP(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#endif /* CHAP_SUPPORT */ +#define NAKCICHAR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[1] == CILEN_CHAR && \ + p[0] == opt) { \ + len -= CILEN_CHAR; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + no.neg = 1; \ + code \ + } +#define NAKCISHORT(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + no.neg = 1; \ + code \ + } +#define NAKCILONG(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } +#if LQR_SUPPORT +#define NAKCILQR(opt, neg, code) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + no.neg = 1; \ + code \ + } +#endif /* LQR_SUPPORT */ +#define NAKCIENDP(opt, neg) \ + if (go->neg && \ + len >= CILEN_CHAR && \ + p[0] == opt && \ + p[1] >= CILEN_CHAR && \ + p[1] <= len) { \ + len -= p[1]; \ + INCPTR(p[1], p); \ + no.neg = 1; \ + try_.neg = 0; \ + } + + /* + * NOTE! There must be no assignments to individual fields of *go in + * the code below. Any such assignment is a BUG! + */ + /* + * We don't care if they want to send us smaller packets than + * we want. Therefore, accept any MRU less than what we asked for, + * but then ignore the new value when setting the MRU in the kernel. + * If they send us a bigger MRU than what we asked, accept it, up to + * the limit of the default MRU we'd get if we didn't negotiate. + */ + if (go->neg_mru && go->mru != DEFMRU) { + NAKCISHORT(CI_MRU, neg_mru, + if (cishort <= wo->mru || cishort <= DEFMRU) + try_.mru = cishort; + ); + } + + /* + * Add any characters they want to our (receive-side) asyncmap. + */ + if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { + NAKCILONG(CI_ASYNCMAP, neg_asyncmap, + try_.asyncmap = go->asyncmap | cilong; + ); + } + + /* + * If they've nak'd our authentication-protocol, check whether + * they are proposing a different protocol, or a different + * hash algorithm for CHAP. + */ + if ((0 +#if CHAP_SUPPORT + || go->neg_chap +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + || go->neg_upap +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + || go->neg_eap +#endif /* EAP_SUPPORT */ + ) + && len >= CILEN_SHORT + && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { + cilen = p[1]; + len -= cilen; +#if CHAP_SUPPORT + no.neg_chap = go->neg_chap; +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + no.neg_upap = go->neg_upap; +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + no.neg_eap = go->neg_eap; +#endif /* EAP_SUPPORT */ + INCPTR(2, p); + GETSHORT(cishort, p); + +#if PAP_SUPPORT + if (cishort == PPP_PAP && cilen == CILEN_SHORT) { +#if EAP_SUPPORT + /* If we were asking for EAP, then we need to stop that. */ + if (go->neg_eap) + try_.neg_eap = 0; + else +#endif /* EAP_SUPPORT */ + +#if CHAP_SUPPORT + /* If we were asking for CHAP, then we need to stop that. */ + if (go->neg_chap) + try_.neg_chap = 0; + else +#endif /* CHAP_SUPPORT */ + + /* + * If we weren't asking for CHAP or EAP, then we were asking for + * PAP, in which case this Nak is bad. + */ + goto bad; + } else +#endif /* PAP_SUPPORT */ + +#if CHAP_SUPPORT + if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { + GETCHAR(cichar, p); +#if EAP_SUPPORT + /* Stop asking for EAP, if we were. */ + if (go->neg_eap) { + try_.neg_eap = 0; + /* Try to set up to use their suggestion, if possible */ + if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) + try_.chap_mdtype = CHAP_MDTYPE_D(cichar); + } else +#endif /* EAP_SUPPORT */ + if (go->neg_chap) { + /* + * We were asking for our preferred algorithm, they must + * want something different. + */ + if (cichar != CHAP_DIGEST(go->chap_mdtype)) { + if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { + /* Use their suggestion if we support it ... */ + try_.chap_mdtype = CHAP_MDTYPE_D(cichar); + } else { + /* ... otherwise, try our next-preferred algorithm. */ + try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype)); + if (try_.chap_mdtype == MDTYPE_NONE) /* out of algos */ + try_.neg_chap = 0; + } + } else { + /* + * Whoops, they Nak'd our algorithm of choice + * but then suggested it back to us. + */ + goto bad; + } + } else { + /* + * Stop asking for PAP if we were asking for it. + */ +#if PAP_SUPPORT + try_.neg_upap = 0; +#endif /* PAP_SUPPORT */ + } + + } else +#endif /* CHAP_SUPPORT */ + { + +#if EAP_SUPPORT + /* + * If we were asking for EAP, and they're Conf-Naking EAP, + * well, that's just strange. Nobody should do that. + */ + if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) + ppp_dbglog("Unexpected Conf-Nak for EAP"); + + /* + * We don't recognize what they're suggesting. + * Stop asking for what we were asking for. + */ + if (go->neg_eap) + try_.neg_eap = 0; + else +#endif /* EAP_SUPPORT */ + +#if CHAP_SUPPORT + if (go->neg_chap) + try_.neg_chap = 0; + else +#endif /* CHAP_SUPPORT */ + +#if PAP_SUPPORT + if(1) + try_.neg_upap = 0; + else +#endif /* PAP_SUPPORT */ + {} + + p += cilen - CILEN_SHORT; + } + } + +#if LQR_SUPPORT + /* + * If they can't cope with our link quality protocol, we'll have + * to stop asking for LQR. We haven't got any other protocol. + * If they Nak the reporting period, take their value XXX ? + */ + NAKCILQR(CI_QUALITY, neg_lqr, + if (cishort != PPP_LQR) + try_.neg_lqr = 0; + else + try_.lqr_period = cilong; + ); +#endif /* LQR_SUPPORT */ + + /* + * Only implementing CBCP...not the rest of the callback options + */ + NAKCICHAR(CI_CALLBACK, neg_cbcp, + try_.neg_cbcp = 0; + (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */ + ); + + /* + * Check for a looped-back line. + */ + NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, + try_.magicnumber = magic(); + looped_back = 1; + ); + + /* + * Peer shouldn't send Nak for protocol compression or + * address/control compression requests; they should send + * a Reject instead. If they send a Nak, treat it as a Reject. + */ + NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); + NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); + +#ifdef HAVE_MULTILINK + /* + * Nak for MRRU option - accept their value if it is smaller + * than the one we want. + */ + if (go->neg_mrru) { + NAKCISHORT(CI_MRRU, neg_mrru, + if (treat_as_reject) + try_.neg_mrru = 0; + else if (cishort <= wo->mrru) + try_.mrru = cishort; + ); + } +#else /* HAVE_MULTILINK */ + LWIP_UNUSED_ARG(treat_as_reject); +#endif /* HAVE_MULTILINK */ + + /* + * Nak for short sequence numbers shouldn't be sent, treat it + * like a reject. + */ + NAKCIVOID(CI_SSNHF, neg_ssnhf); + + /* + * Nak of the endpoint discriminator option is not permitted, + * treat it like a reject. + */ + NAKCIENDP(CI_EPDISC, neg_endpoint); + + /* + * There may be remaining CIs, if the peer is requesting negotiation + * on an option that we didn't include in our request packet. + * If we see an option that we requested, or one we've already seen + * in this packet, then this packet is bad. + * If we wanted to respond by starting to negotiate on the requested + * option(s), we could, but we don't, because except for the + * authentication type and quality protocol, if we are not negotiating + * an option, it is because we were told not to. + * For the authentication type, the Nak from the peer means + * `let me authenticate myself with you' which is a bit pointless. + * For the quality protocol, the Nak means `ask me to send you quality + * reports', but if we didn't ask for them, we don't want them. + * An option we don't recognize represents the peer asking to + * negotiate some option we don't support, so ignore it. + */ + while (len >= CILEN_VOID) { + GETCHAR(citype, p); + GETCHAR(cilen, p); + if (cilen < CILEN_VOID || (len -= cilen) < 0) + goto bad; + next = p + cilen - 2; + + switch (citype) { + case CI_MRU: + if ((go->neg_mru && go->mru != DEFMRU) + || no.neg_mru || cilen != CILEN_SHORT) + goto bad; + GETSHORT(cishort, p); + if (cishort < DEFMRU) { + try_.neg_mru = 1; + try_.mru = cishort; + } + break; + case CI_ASYNCMAP: + if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + || no.neg_asyncmap || cilen != CILEN_LONG) + goto bad; + break; + case CI_AUTHTYPE: + if (0 +#if CHAP_SUPPORT + || go->neg_chap || no.neg_chap +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + || go->neg_upap || no.neg_upap +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + || go->neg_eap || no.neg_eap +#endif /* EAP_SUPPORT */ + ) + goto bad; + break; + case CI_MAGICNUMBER: + if (go->neg_magicnumber || no.neg_magicnumber || + cilen != CILEN_LONG) + goto bad; + break; + case CI_PCOMPRESSION: + if (go->neg_pcompression || no.neg_pcompression + || cilen != CILEN_VOID) + goto bad; + break; + case CI_ACCOMPRESSION: + if (go->neg_accompression || no.neg_accompression + || cilen != CILEN_VOID) + goto bad; + break; +#if LQR_SUPPORT + case CI_QUALITY: + if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) + goto bad; + break; +#endif /* LQR_SUPPORT */ +#ifdef HAVE_MULTILINK + case CI_MRRU: + if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) + goto bad; + break; +#endif /* HAVE_MULTILINK */ + case CI_SSNHF: + if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) + goto bad; + try_.neg_ssnhf = 1; + break; + case CI_EPDISC: + if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) + goto bad; + break; + default: + break; + } + p = next; + } + + /* + * OK, the Nak is good. Now we can update state. + * If there are any options left we ignore them. + */ + if (f->state != PPP_FSM_OPENED) { + if (looped_back) { + if (++try_.numloops >= pcb->settings.lcp_loopbackfail) { + int errcode = PPPERR_LOOPBACK; + ppp_notice("Serial line is looped back."); + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(f->pcb, "Loopback detected"); + } + } else + try_.numloops = 0; + *go = try_; + } + + return 1; + +bad: + LCPDEBUG(("lcp_nakci: received bad Nak!")); + return 0; +} + + +/* + * lcp_rejci - Peer has Rejected some of our CIs. + * This should not modify any state if the Reject is bad + * or if LCP is in the OPENED state. + * + * Returns: + * 0 - Reject was bad. + * 1 - Reject was good. + */ +static int lcp_rejci(fsm *f, u_char *p, int len) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u_char cichar; + u_short cishort; + u32_t cilong; + lcp_options try_; /* options to request next time */ + + try_ = *go; + + /* + * Any Rejected CIs must be in exactly the same order that we sent. + * Check packet length and CI length at each step. + * If we find any deviations, then this packet is bad. + */ +#define REJCIVOID(opt, neg) \ + if (go->neg && \ + len >= CILEN_VOID && \ + p[1] == CILEN_VOID && \ + p[0] == opt) { \ + len -= CILEN_VOID; \ + INCPTR(CILEN_VOID, p); \ + try_.neg = 0; \ + } +#define REJCISHORT(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_SHORT && \ + p[1] == CILEN_SHORT && \ + p[0] == opt) { \ + len -= CILEN_SHORT; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + /* Check rejected value. */ \ + if (cishort != val) \ + goto bad; \ + try_.neg = 0; \ + } + +#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try_.neg = 0; \ + try_.neg_eap = try_.neg_upap = 0; \ + } +#endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */ + +#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try_.neg = 0; \ + try_.neg_upap = 0; \ + } +#endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */ + +#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try_.neg = 0; \ + try_.neg_eap = 0; \ + } +#endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */ + +#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT +#define REJCICHAP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CHAP && \ + p[1] == CILEN_CHAP && \ + p[0] == opt) { \ + len -= CILEN_CHAP; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ + goto bad; \ + try_.neg = 0; \ + } +#endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */ + +#define REJCILONG(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LONG && \ + p[1] == CILEN_LONG && \ + p[0] == opt) { \ + len -= CILEN_LONG; \ + INCPTR(2, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cilong != val) \ + goto bad; \ + try_.neg = 0; \ + } +#if LQR_SUPPORT +#define REJCILQR(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_LQR && \ + p[1] == CILEN_LQR && \ + p[0] == opt) { \ + len -= CILEN_LQR; \ + INCPTR(2, p); \ + GETSHORT(cishort, p); \ + GETLONG(cilong, p); \ + /* Check rejected value. */ \ + if (cishort != PPP_LQR || cilong != val) \ + goto bad; \ + try_.neg = 0; \ + } +#endif /* LQR_SUPPORT */ +#define REJCICBCP(opt, neg, val) \ + if (go->neg && \ + len >= CILEN_CBCP && \ + p[1] == CILEN_CBCP && \ + p[0] == opt) { \ + len -= CILEN_CBCP; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + /* Check rejected value. */ \ + if (cichar != val) \ + goto bad; \ + try_.neg = 0; \ + } +#define REJCIENDP(opt, neg, class, val, vlen) \ + if (go->neg && \ + len >= CILEN_CHAR + vlen && \ + p[0] == opt && \ + p[1] == CILEN_CHAR + vlen) { \ + int i; \ + len -= CILEN_CHAR + vlen; \ + INCPTR(2, p); \ + GETCHAR(cichar, p); \ + if (cichar != class) \ + goto bad; \ + for (i = 0; i < vlen; ++i) { \ + GETCHAR(cichar, p); \ + if (cichar != val[i]) \ + goto bad; \ + } \ + try_.neg = 0; \ + } + + REJCISHORT(CI_MRU, neg_mru, go->mru); + REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); +#if EAP_SUPPORT + REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); + if (!go->neg_eap) { +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT + REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); + if (!go->neg_chap) { +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + } +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + } +#endif /* EAP_SUPPORT */ +#if LQR_SUPPORT + REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); +#endif /* LQR_SUPPORT */ + REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); + REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); + REJCIVOID(CI_PCOMPRESSION, neg_pcompression); + REJCIVOID(CI_ACCOMPRESSION, neg_accompression); +#ifdef HAVE_MULTILINK + REJCISHORT(CI_MRRU, neg_mrru, go->mrru); +#endif /* HAVE_MULTILINK */ + REJCIVOID(CI_SSNHF, neg_ssnhf); + REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_, + go->endpoint.value, go->endpoint.length); + + /* + * If there are any remaining CIs, then this packet is bad. + */ + if (len != 0) + goto bad; + /* + * Now we can update state. + */ + if (f->state != PPP_FSM_OPENED) + *go = try_; + return 1; + +bad: + LCPDEBUG(("lcp_rejci: received bad Reject!")); + return 0; +} + + +/* + * lcp_reqci - Check the peer's requested CIs and send appropriate response. + * + * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified + * appropriately. If reject_if_disagree is non-zero, doesn't return + * CONFNAK; returns CONFREJ if it can't return CONFACK. + * + * inp = Requested CIs + * lenp = Length of requested CIs + */ +static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ho = &pcb->lcp_hisoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + u_char *cip, *next; /* Pointer to current and next CIs */ + int cilen, citype, cichar; /* Parsed len, type, char value */ + u_short cishort; /* Parsed short value */ + u32_t cilong; /* Parse long value */ + int rc = CONFACK; /* Final packet return code */ + int orc; /* Individual option return code */ + u_char *p; /* Pointer to next char to parse */ + u_char *rejp; /* Pointer to next char in reject frame */ + struct pbuf *nakp; /* Nak buffer */ + u_char *nakoutp; /* Pointer to next char in Nak frame */ + int l = *lenp; /* Length left */ + + /* + * Reset all his options. + */ + BZERO(ho, sizeof(*ho)); + + /* + * Process all his options. + */ + next = inp; + nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); + if(NULL == nakp) + return 0; + if(nakp->tot_len != nakp->len) { + pbuf_free(nakp); + return 0; + } + + nakoutp = (u_char*)nakp->payload; + rejp = inp; + while (l) { + orc = CONFACK; /* Assume success */ + cip = p = next; /* Remember begining of CI */ + if (l < 2 || /* Not enough data for CI header or */ + p[1] < 2 || /* CI length too small or */ + p[1] > l) { /* CI length too big? */ + LCPDEBUG(("lcp_reqci: bad CI length!")); + orc = CONFREJ; /* Reject bad CI */ + cilen = l; /* Reject till end of packet */ + l = 0; /* Don't loop again */ + citype = 0; + goto endswitch; + } + GETCHAR(citype, p); /* Parse CI type */ + GETCHAR(cilen, p); /* Parse CI length */ + l -= cilen; /* Adjust remaining length */ + next += cilen; /* Step to next CI */ + + switch (citype) { /* Check CI type */ + case CI_MRU: + if (!ao->neg_mru || /* Allow option? */ + cilen != CILEN_SHORT) { /* Check CI length */ + orc = CONFREJ; /* Reject CI */ + break; + } + GETSHORT(cishort, p); /* Parse MRU */ + + /* + * He must be able to receive at least our minimum. + * No need to check a maximum. If he sends a large number, + * we'll just ignore it. + */ + if (cishort < MINMRU) { + orc = CONFNAK; /* Nak CI */ + PUTCHAR(CI_MRU, nakoutp); + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(MINMRU, nakoutp); /* Give him a hint */ + break; + } + ho->neg_mru = 1; /* Remember he sent MRU */ + ho->mru = cishort; /* And remember value */ + break; + + case CI_ASYNCMAP: + if (!ao->neg_asyncmap || + cilen != CILEN_LONG) { + orc = CONFREJ; + break; + } + GETLONG(cilong, p); + + /* + * Asyncmap must have set at least the bits + * which are set in lcp_allowoptions[unit].asyncmap. + */ + if ((ao->asyncmap & ~cilong) != 0) { + orc = CONFNAK; + PUTCHAR(CI_ASYNCMAP, nakoutp); + PUTCHAR(CILEN_LONG, nakoutp); + PUTLONG(ao->asyncmap | cilong, nakoutp); + break; + } + ho->neg_asyncmap = 1; + ho->asyncmap = cilong; + break; + + case CI_AUTHTYPE: + if (cilen < CILEN_SHORT || + !(0 +#if PAP_SUPPORT + || ao->neg_upap +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || ao->neg_chap +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || ao->neg_eap +#endif /* EAP_SUPPORT */ + )) { + /* + * Reject the option if we're not willing to authenticate. + */ + ppp_dbglog("No auth is possible"); + orc = CONFREJ; + break; + } + GETSHORT(cishort, p); + + /* + * Authtype must be PAP, CHAP, or EAP. + * + * Note: if more than one of ao->neg_upap, ao->neg_chap, and + * ao->neg_eap are set, and the peer sends a Configure-Request + * with two or more authenticate-protocol requests, then we will + * reject the second request. + * Whether we end up doing CHAP, UPAP, or EAP depends then on + * the ordering of the CIs in the peer's Configure-Request. + */ + +#if PAP_SUPPORT + if (cishort == PPP_PAP) { + /* we've already accepted CHAP or EAP */ + if (0 +#if CHAP_SUPPORT + || ho->neg_chap +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || ho->neg_eap +#endif /* EAP_SUPPORT */ + || cilen != CILEN_SHORT) { + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); + orc = CONFREJ; + break; + } + if (!ao->neg_upap) { /* we don't want to do PAP */ + orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ + PUTCHAR(CI_AUTHTYPE, nakoutp); +#if EAP_SUPPORT + if (ao->neg_eap) { + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_EAP, nakoutp); + } else { +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + } +#endif /* EAP_SUPPORT */ + break; + } + ho->neg_upap = 1; + break; + } +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + if (cishort == PPP_CHAP) { + /* we've already accepted PAP or EAP */ + if ( +#if PAP_SUPPORT + ho->neg_upap || +#endif /* PAP_SUPPORT */ +#if EAP_SUPPORT + ho->neg_eap || +#endif /* EAP_SUPPORT */ + cilen != CILEN_CHAP) { + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); + orc = CONFREJ; + break; + } + if (!ao->neg_chap) { /* we don't want to do CHAP */ + orc = CONFNAK; /* NAK it and suggest EAP or PAP */ + PUTCHAR(CI_AUTHTYPE, nakoutp); + PUTCHAR(CILEN_SHORT, nakoutp); +#if EAP_SUPPORT + if (ao->neg_eap) { + PUTSHORT(PPP_EAP, nakoutp); + } else +#endif /* EAP_SUPPORT */ +#if PAP_SUPPORT + if(1) { + PUTSHORT(PPP_PAP, nakoutp); + } + else +#endif /* PAP_SUPPORT */ + {} + break; + } + GETCHAR(cichar, p); /* get digest type */ + if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { + /* + * We can't/won't do the requested type, + * suggest something else. + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakoutp); + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); + break; + } + ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ + ho->neg_chap = 1; + break; + } +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + if (cishort == PPP_EAP) { + /* we've already accepted CHAP or PAP */ + if ( +#if CHAP_SUPPORT + ho->neg_chap || +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + ho->neg_upap || +#endif /* PAP_SUPPORT */ + cilen != CILEN_SHORT) { + LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); + orc = CONFREJ; + break; + } + if (!ao->neg_eap) { /* we don't want to do EAP */ + orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ + PUTCHAR(CI_AUTHTYPE, nakoutp); +#if CHAP_SUPPORT + if (ao->neg_chap) { + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); + } else +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + if(1) { + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_PAP, nakoutp); + } else +#endif /* PAP_SUPPORT */ + {} + break; + } + ho->neg_eap = 1; + break; + } +#endif /* EAP_SUPPORT */ + + /* + * We don't recognize the protocol they're asking for. + * Nak it with something we're willing to do. + * (At this point we know ao->neg_upap || ao->neg_chap || + * ao->neg_eap.) + */ + orc = CONFNAK; + PUTCHAR(CI_AUTHTYPE, nakoutp); + +#if EAP_SUPPORT + if (ao->neg_eap) { + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_EAP, nakoutp); + } else +#endif /* EAP_SUPPORT */ +#if CHAP_SUPPORT + if (ao->neg_chap) { + PUTCHAR(CILEN_CHAP, nakoutp); + PUTSHORT(PPP_CHAP, nakoutp); + PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); + } else +#endif /* CHAP_SUPPORT */ +#if PAP_SUPPORT + if(1) { + PUTCHAR(CILEN_SHORT, nakoutp); + PUTSHORT(PPP_PAP, nakoutp); + } else +#endif /* PAP_SUPPORT */ + {} + break; + +#if LQR_SUPPORT + case CI_QUALITY: + if (!ao->neg_lqr || + cilen != CILEN_LQR) { + orc = CONFREJ; + break; + } + + GETSHORT(cishort, p); + GETLONG(cilong, p); + + /* + * Check the protocol and the reporting period. + * XXX When should we Nak this, and what with? + */ + if (cishort != PPP_LQR) { + orc = CONFNAK; + PUTCHAR(CI_QUALITY, nakoutp); + PUTCHAR(CILEN_LQR, nakoutp); + PUTSHORT(PPP_LQR, nakoutp); + PUTLONG(ao->lqr_period, nakoutp); + break; + } + break; +#endif /* LQR_SUPPORT */ + + case CI_MAGICNUMBER: + if (!(ao->neg_magicnumber || go->neg_magicnumber) || + cilen != CILEN_LONG) { + orc = CONFREJ; + break; + } + GETLONG(cilong, p); + + /* + * He must have a different magic number. + */ + if (go->neg_magicnumber && + cilong == go->magicnumber) { + cilong = magic(); /* Don't put magic() inside macro! */ + orc = CONFNAK; + PUTCHAR(CI_MAGICNUMBER, nakoutp); + PUTCHAR(CILEN_LONG, nakoutp); + PUTLONG(cilong, nakoutp); + break; + } + ho->neg_magicnumber = 1; + ho->magicnumber = cilong; + break; + + + case CI_PCOMPRESSION: + if (!ao->neg_pcompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_pcompression = 1; + break; + + case CI_ACCOMPRESSION: + if (!ao->neg_accompression || + cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_accompression = 1; + break; + +#ifdef HAVE_MULTILINK + case CI_MRRU: + if (!ao->neg_mrru + || !multilink + || cilen != CILEN_SHORT) { + orc = CONFREJ; + break; + } + + GETSHORT(cishort, p); + /* possibly should insist on a minimum/maximum MRRU here */ + ho->neg_mrru = 1; + ho->mrru = cishort; + break; +#endif /* HAVE_MULTILINK */ + + case CI_SSNHF: + if (!ao->neg_ssnhf +#ifdef HAVE_MULTILINK + || !multilink +#endif /* HAVE_MULTILINK */ + || cilen != CILEN_VOID) { + orc = CONFREJ; + break; + } + ho->neg_ssnhf = 1; + break; + + case CI_EPDISC: + if (!ao->neg_endpoint || + cilen < CILEN_CHAR || + cilen > CILEN_CHAR + MAX_ENDP_LEN) { + orc = CONFREJ; + break; + } + GETCHAR(cichar, p); + cilen -= CILEN_CHAR; + ho->neg_endpoint = 1; + ho->endpoint.class_ = cichar; + ho->endpoint.length = cilen; + MEMCPY(ho->endpoint.value, p, cilen); + INCPTR(cilen, p); + break; + + default: + LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); + orc = CONFREJ; + break; + } + +endswitch: + if (orc == CONFACK && /* Good CI */ + rc != CONFACK) /* but prior CI wasnt? */ + continue; /* Don't send this one */ + + if (orc == CONFNAK) { /* Nak this CI? */ + if (reject_if_disagree /* Getting fed up with sending NAKs? */ + && citype != CI_MAGICNUMBER) { + orc = CONFREJ; /* Get tough if so */ + } else { + if (rc == CONFREJ) /* Rejecting prior CI? */ + continue; /* Don't send this one */ + rc = CONFNAK; + } + } + if (orc == CONFREJ) { /* Reject this CI */ + rc = CONFREJ; + if (cip != rejp) /* Need to move rejected CI? */ + MEMCPY(rejp, cip, cilen); /* Move it */ + INCPTR(cilen, rejp); /* Update output pointer */ + } + } + + /* + * If we wanted to send additional NAKs (for unsent CIs), the + * code would go here. The extra NAKs would go at *nakoutp. + * At present there are no cases where we want to ask the + * peer to negotiate an option. + */ + + switch (rc) { + case CONFACK: + *lenp = next - inp; + break; + case CONFNAK: + /* + * Copy the Nak'd options from the nak buffer to the caller's buffer. + */ + *lenp = nakoutp - (u_char*)nakp->payload; + MEMCPY(inp, nakp->payload, *lenp); + break; + case CONFREJ: + *lenp = rejp - inp; + break; + default: + break; + } + + pbuf_free(nakp); + LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); + return (rc); /* Return final code */ +} + + +/* + * lcp_up - LCP has come UP. + */ +static void lcp_up(fsm *f) { + ppp_pcb *pcb = f->pcb; + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ho = &pcb->lcp_hisoptions; + lcp_options *go = &pcb->lcp_gotoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + int mtu, mru; + + if (!go->neg_magicnumber) + go->magicnumber = 0; + if (!ho->neg_magicnumber) + ho->magicnumber = 0; + + /* + * Set our MTU to the smaller of the MTU we wanted and + * the MRU our peer wanted. If we negotiated an MRU, + * set our MRU to the larger of value we wanted and + * the value we got in the negotiation. + * Note on the MTU: the link MTU can be the MRU the peer wanted, + * the interface MTU is set to the lowest of that, the + * MTU we want to use, and our link MRU. + */ + mtu = ho->neg_mru? ho->mru: PPP_MRU; + mru = go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU; +#ifdef HAVE_MULTILINK + if (!(multilink && go->neg_mrru && ho->neg_mrru)) +#endif /* HAVE_MULTILINK */ + netif_set_mtu(pcb, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); + ppp_send_config(pcb, mtu, + (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), + ho->neg_pcompression, ho->neg_accompression); + ppp_recv_config(pcb, mru, + (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), + go->neg_pcompression, go->neg_accompression); + + if (ho->neg_mru) + pcb->peer_mru = ho->mru; + + lcp_echo_lowerup(f->pcb); /* Enable echo messages */ + + link_established(pcb); +} + + +/* + * lcp_down - LCP has gone DOWN. + * + * Alert other protocols. + */ +static void lcp_down(fsm *f) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + + lcp_echo_lowerdown(f->pcb); + + link_down(pcb); + + ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0); + ppp_recv_config(pcb, PPP_MRU, + (go->neg_asyncmap? go->asyncmap: 0xffffffff), + go->neg_pcompression, go->neg_accompression); + pcb->peer_mru = PPP_MRU; +} + + +/* + * lcp_starting - LCP needs the lower layer up. + */ +static void lcp_starting(fsm *f) { + ppp_pcb *pcb = f->pcb; + link_required(pcb); +} + + +/* + * lcp_finished - LCP has finished with the lower layer. + */ +static void lcp_finished(fsm *f) { + ppp_pcb *pcb = f->pcb; + link_terminated(pcb); +} + + +#if PRINTPKT_SUPPORT +/* + * lcp_printpkt - print the contents of an LCP packet. + */ +static const char *lcp_codenames[] = { + "ConfReq", "ConfAck", "ConfNak", "ConfRej", + "TermReq", "TermAck", "CodeRej", "ProtRej", + "EchoReq", "EchoRep", "DiscReq", "Ident", + "TimeRem" +}; + +static int lcp_printpkt(u_char *p, int plen, + void (*printer) (void *, const char *, ...), void *arg) { + int code, id, len, olen, i; + u_char *pstart, *optend; + u_short cishort; + u32_t cilong; + + if (plen < HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= (int)sizeof(lcp_codenames) / (int)sizeof(char *)) + printer(arg, " %s", lcp_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= HEADERLEN; + switch (code) { + case CONFREQ: + case CONFACK: + case CONFNAK: + case CONFREJ: + /* print option list */ + while (len >= 2) { + GETCHAR(code, p); + GETCHAR(olen, p); + p -= 2; + if (olen < 2 || olen > len) { + break; + } + printer(arg, " <"); + len -= olen; + optend = p + olen; + switch (code) { + case CI_MRU: + if (olen == CILEN_SHORT) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "mru %d", cishort); + } + break; + case CI_ASYNCMAP: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "asyncmap 0x%x", cilong); + } + break; + case CI_AUTHTYPE: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "auth "); + GETSHORT(cishort, p); + switch (cishort) { +#if PAP_SUPPORT + case PPP_PAP: + printer(arg, "pap"); + break; +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + case PPP_CHAP: + printer(arg, "chap"); + if (p < optend) { + switch (*p) { + case CHAP_MD5: + printer(arg, " MD5"); + ++p; + break; +#if MSCHAP_SUPPORT + case CHAP_MICROSOFT: + printer(arg, " MS"); + ++p; + break; + + case CHAP_MICROSOFT_V2: + printer(arg, " MS-v2"); + ++p; + break; +#endif /* MSCHAP_SUPPORT */ + default: + break; + } + } + break; +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + case PPP_EAP: + printer(arg, "eap"); + break; +#endif /* EAP_SUPPORT */ + default: + printer(arg, "0x%x", cishort); + } + } + break; +#if LQR_SUPPORT + case CI_QUALITY: + if (olen >= CILEN_SHORT) { + p += 2; + printer(arg, "quality "); + GETSHORT(cishort, p); + switch (cishort) { + case PPP_LQR: + printer(arg, "lqr"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; +#endif /* LQR_SUPPORT */ + case CI_CALLBACK: + if (olen >= CILEN_CHAR) { + p += 2; + printer(arg, "callback "); + GETCHAR(cishort, p); + switch (cishort) { + case CBCP_OPT: + printer(arg, "CBCP"); + break; + default: + printer(arg, "0x%x", cishort); + } + } + break; + case CI_MAGICNUMBER: + if (olen == CILEN_LONG) { + p += 2; + GETLONG(cilong, p); + printer(arg, "magic 0x%x", cilong); + } + break; + case CI_PCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "pcomp"); + } + break; + case CI_ACCOMPRESSION: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "accomp"); + } + break; + case CI_MRRU: + if (olen == CILEN_SHORT) { + p += 2; + GETSHORT(cishort, p); + printer(arg, "mrru %d", cishort); + } + break; + case CI_SSNHF: + if (olen == CILEN_VOID) { + p += 2; + printer(arg, "ssnhf"); + } + break; + case CI_EPDISC: +#ifdef HAVE_MULTILINK + if (olen >= CILEN_CHAR) { + struct epdisc epd; + p += 2; + GETCHAR(epd.class, p); + epd.length = olen - CILEN_CHAR; + if (epd.length > MAX_ENDP_LEN) + epd.length = MAX_ENDP_LEN; + if (epd.length > 0) { + MEMCPY(epd.value, p, epd.length); + p += epd.length; + } + printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); + } +#else + printer(arg, "endpoint"); +#endif + break; + default: + break; + } + while (p < optend) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + printer(arg, ">"); + } + break; + + case TERMACK: + case TERMREQ: + if (len > 0 && *p >= ' ' && *p < 0x7f) { + printer(arg, " "); + ppp_print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + + case ECHOREQ: + case ECHOREP: + case DISCREQ: + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + len -= 4; + } + break; + + case IDENTIF: + case TIMEREM: + if (len >= 4) { + GETLONG(cilong, p); + printer(arg, " magic=0x%x", cilong); + len -= 4; + } + if (code == TIMEREM) { + if (len < 4) + break; + GETLONG(cilong, p); + printer(arg, " seconds=%u", cilong); + len -= 4; + } + if (len > 0) { + printer(arg, " "); + ppp_print_string((char *)p, len, printer, arg); + p += len; + len = 0; + } + break; + default: + break; + } + + /* print the rest of the bytes in the packet */ + for (i = 0; i < len && i < 32; ++i) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + if (i < len) { + printer(arg, " ..."); + p += len - i; + } + + return p - pstart; +} +#endif /* PRINTPKT_SUPPORT */ + +/* + * Time to shut down the link because there is nothing out there. + */ + +static void LcpLinkFailure(fsm *f) { + ppp_pcb *pcb = f->pcb; + if (f->state == PPP_FSM_OPENED) { + int errcode = PPPERR_PEERDEAD; + ppp_info("No response to %d echo-requests", pcb->lcp_echos_pending); + ppp_notice("Serial link appears to be disconnected."); + ppp_ioctl(pcb, PPPCTLS_ERRCODE, &errcode); + lcp_close(pcb, "Peer not responding"); + } +} + +/* + * Timer expired for the LCP echo requests from this process. + */ + +static void LcpEchoCheck(fsm *f) { + ppp_pcb *pcb = f->pcb; + + LcpSendEchoRequest (f); + if (f->state != PPP_FSM_OPENED) + return; + + /* + * Start the timer for the next interval. + */ + if (pcb->lcp_echo_timer_running) + ppp_warn("assertion lcp_echo_timer_running==0 failed"); + TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval); + pcb->lcp_echo_timer_running = 1; +} + +/* + * LcpEchoTimeout - Timer expired on the LCP echo + */ + +static void LcpEchoTimeout(void *arg) { + fsm *f = (fsm*)arg; + ppp_pcb *pcb = f->pcb; + if (pcb->lcp_echo_timer_running != 0) { + pcb->lcp_echo_timer_running = 0; + LcpEchoCheck ((fsm *) arg); + } +} + +/* + * LcpEchoReply - LCP has received a reply to the echo + */ + +static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u32_t magic; + LWIP_UNUSED_ARG(id); + + /* Check the magic number - don't count replies from ourselves. */ + if (len < 4) { + ppp_dbglog("lcp: received short Echo-Reply, length %d", len); + return; + } + GETLONG(magic, inp); + if (go->neg_magicnumber + && magic == go->magicnumber) { + ppp_warn("appear to have received our own echo-reply!"); + return; + } + + /* Reset the number of outstanding echo frames */ + pcb->lcp_echos_pending = 0; +} + +/* + * LcpSendEchoRequest - Send an echo request frame to the peer + */ + +static void LcpSendEchoRequest(fsm *f) { + ppp_pcb *pcb = f->pcb; + lcp_options *go = &pcb->lcp_gotoptions; + u32_t lcp_magic; + u_char pkt[4], *pktp; + + /* + * Detect the failure of the peer at this point. + */ + if (pcb->settings.lcp_echo_fails != 0) { + if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) { + LcpLinkFailure(f); + pcb->lcp_echos_pending = 0; + } + } + +#if PPP_LCP_ADAPTIVE + /* + * If adaptive echos have been enabled, only send the echo request if + * no traffic was received since the last one. + */ + if (pcb->settings.lcp_echo_adaptive) { + static unsigned int last_pkts_in = 0; + +#if PPP_STATS_SUPPORT + update_link_stats(f->unit); + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ + + if (link_stats.pkts_in != last_pkts_in) { + last_pkts_in = link_stats.pkts_in; + return; + } + } +#endif + + /* + * Make and send the echo request frame. + */ + if (f->state == PPP_FSM_OPENED) { + lcp_magic = go->magicnumber; + pktp = pkt; + PUTLONG(lcp_magic, pktp); + fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt); + ++pcb->lcp_echos_pending; + } +} + +/* + * lcp_echo_lowerup - Start the timer for the LCP frame + */ + +static void lcp_echo_lowerup(ppp_pcb *pcb) { + fsm *f = &pcb->lcp_fsm; + + /* Clear the parameters for generating echo frames */ + pcb->lcp_echos_pending = 0; + pcb->lcp_echo_number = 0; + pcb->lcp_echo_timer_running = 0; + + /* If a timeout interval is specified then start the timer */ + if (pcb->settings.lcp_echo_interval != 0) + LcpEchoCheck (f); +} + +/* + * lcp_echo_lowerdown - Stop the timer for the LCP frame + */ + +static void lcp_echo_lowerdown(ppp_pcb *pcb) { + fsm *f = &pcb->lcp_fsm; + + if (pcb->lcp_echo_timer_running != 0) { + UNTIMEOUT (LcpEchoTimeout, f); + pcb->lcp_echo_timer_running = 0; + } +} + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/magic.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/magic.c new file mode 100644 index 0000000..a6a5549 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/magic.c @@ -0,0 +1,267 @@ +/* + * magic.c - PPP Magic Number routines. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/***************************************************************************** +* randm.c - Random number generator program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* Copyright (c) 1998 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 98-06-03 Guy Lancaster , Global Election Systems Inc. +* Extracted from avos. +*****************************************************************************/ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/magic.h" + +#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ + +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "netif/ppp/polarssl/md5.h" +#else +#include "polarssl/md5.h" +#endif + +#define MAGIC_RANDPOOLSIZE 16 /* Bytes stored in the pool of randomness. */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static char magic_randpool[MAGIC_RANDPOOLSIZE]; /* Pool of randomness. */ +static long magic_randcount = 0; /* Pseudo-random incrementer */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ + +/* + * Churn the randomness pool on a random event. Call this early and often + * on random and semi-random system events to build randomness in time for + * usage. For randomly timed events, pass a null pointer and a zero length + * and this will use the system timer and other sources to add randomness. + * If new random data is available, pass a pointer to that and it will be + * included. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + */ +static void magic_churnrand(char *rand_data, u32_t rand_len) { + md5_context md5; + + /* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: %u@%P\n", rand_len, rand_data)); */ + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + if (rand_data) { + md5_update(&md5, (u_char *)rand_data, rand_len); + } else { + struct { + /* INCLUDE fields for any system sources of randomness */ + u32_t jiffies; + } sys_data; + sys_data.jiffies = sys_jiffies(); + /* Load sys_data fields here. */ + md5_update(&md5, (u_char *)&sys_data, sizeof(sys_data)); + } + md5_finish(&md5, (u_char *)magic_randpool); +/* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: -> 0\n")); */ +} + +/* + * Initialize the random number generator. + */ +void magic_init(void) { + magic_churnrand(NULL, 0); +} + +/* + * Randomize our random seed value. + */ +void magic_randomize(void) { + magic_churnrand(NULL, 0); +} + +/* + * random_bytes - Fill a buffer with random bytes. + * + * Use the random pool to generate random data. This degrades to pseudo + * random when used faster than randomness is supplied using magic_churnrand(). + * Note: It's important that there be sufficient randomness in magic_randpool + * before this is called for otherwise the range of the result may be + * narrow enough to make a search feasible. + * + * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 + * + * XXX Why does he not just call magic_churnrand() for each block? Probably + * so that you don't ever publish the seed which could possibly help + * predict future values. + * XXX Why don't we preserve md5 between blocks and just update it with + * magic_randcount each time? Probably there is a weakness but I wish that + * it was documented. + */ +void random_bytes(unsigned char *buf, u32_t buf_len) { + md5_context md5; + u_char tmp[16]; + u32_t n; + + while (buf_len > 0) { + n = LWIP_MIN(buf_len, MAGIC_RANDPOOLSIZE); + md5_starts(&md5); + md5_update(&md5, (u_char *)magic_randpool, sizeof(magic_randpool)); + md5_update(&md5, (u_char *)&magic_randcount, sizeof(magic_randcount)); + md5_finish(&md5, tmp); + magic_randcount++; + MEMCPY(buf, tmp, n); + buf += n; + buf_len -= n; + } +} + +/* + * Return a new random number. + */ +u32_t magic(void) { + u32_t new_rand; + + random_bytes((unsigned char *)&new_rand, sizeof(new_rand)); + + return new_rand; +} + +#else /* PPP_MD5_RANDM */ + +/*****************************/ +/*** LOCAL DATA STRUCTURES ***/ +/*****************************/ +static int magic_randomized = 0; /* Set when truely randomized. */ +static u32_t magic_randomseed = 0; /* Seed used for random number generation. */ + + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ + +/* + * Initialize the random number generator. + * + * Here we attempt to compute a random number seed but even if + * it isn't random, we'll randomize it later. + * + * The current method uses the fields from the real time clock, + * the idle process counter, the millisecond counter, and the + * hardware timer tick counter. When this is invoked + * in startup(), then the idle counter and timer values may + * repeat after each boot and the real time clock may not be + * operational. Thus we call it again on the first random + * event. + */ +void magic_init() { + magic_randomseed += sys_jiffies(); + + /* Initialize the Borland random number generator. */ + srand((unsigned)magic_randomseed); +} + +/* + * magic_init - Initialize the magic number generator. + * + * Randomize our random seed value. Here we use the fact that + * this function is called at *truely random* times by the polling + * and network functions. Here we only get 16 bits of new random + * value but we use the previous value to randomize the other 16 + * bits. + */ +void magic_randomize(void) { + static u32_t last_jiffies; + + if (!magic_randomized) { + magic_randomized = !0; + magic_init(); + /* The initialization function also updates the seed. */ + } else { + /* magic_randomseed += (magic_randomseed << 16) + TM1; */ + magic_randomseed += (sys_jiffies() - last_jiffies); /* XXX */ + } + last_jiffies = sys_jiffies(); +} + +/* + * Return a new random number. + * + * Here we use the Borland rand() function to supply a pseudo random + * number which we make truely random by combining it with our own + * seed which is randomized by truely random events. + * Thus the numbers will be truely random unless there have been no + * operator or network events in which case it will be pseudo random + * seeded by the real time clock. + */ +u32_t magic() { + return ((((u32_t)rand() << 16) + rand()) + magic_randomseed); +} + +#endif /* PPP_MD5_RANDM */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/multilink.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/multilink.c new file mode 100644 index 0000000..3bea516 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/multilink.c @@ -0,0 +1,609 @@ +/* + * multilink.c - support routines for multilink. + * + * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && defined(HAVE_MULTILINK) /* don't build if not configured for use in lwipopts.h */ + +/* Multilink support + * + * Multilink uses Samba TDB (Trivial Database Library), which + * we cannot port, because it needs a filesystem. + * + * We have to choose between doing a memory-shared TDB-clone, + * or dropping multilink support at all. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#include "netif/ppp/tdb.h" + +bool endpoint_specified; /* user gave explicit endpoint discriminator */ +char *bundle_id; /* identifier for our bundle */ +char *blinks_id; /* key for the list of links */ +bool doing_multilink; /* multilink was enabled and agreed to */ +bool multilink_master; /* we own the multilink bundle */ + +extern TDB_CONTEXT *pppdb; +extern char db_key[]; + +static void make_bundle_links (int append); +static void remove_bundle_link (void); +static void iterate_bundle_links (void (*func) (char *)); + +static int get_default_epdisc (struct epdisc *); +static int parse_num (char *str, const char *key, int *valp); +static int owns_unit (TDB_DATA pid, int unit); + +#define set_ip_epdisc(ep, addr) do { \ + ep->length = 4; \ + ep->value[0] = addr >> 24; \ + ep->value[1] = addr >> 16; \ + ep->value[2] = addr >> 8; \ + ep->value[3] = addr; \ +} while (0) + +#define LOCAL_IP_ADDR(addr) \ + (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ + || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ + || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ + +#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) + +void +mp_check_options() +{ + lcp_options *wo = &lcp_wantoptions[0]; + lcp_options *ao = &lcp_allowoptions[0]; + + doing_multilink = 0; + if (!multilink) + return; + /* if we're doing multilink, we have to negotiate MRRU */ + if (!wo->neg_mrru) { + /* mrru not specified, default to mru */ + wo->mrru = wo->mru; + wo->neg_mrru = 1; + } + ao->mrru = ao->mru; + ao->neg_mrru = 1; + + if (!wo->neg_endpoint && !noendpoint) { + /* get a default endpoint value */ + wo->neg_endpoint = get_default_epdisc(&wo->endpoint); + } +} + +/* + * Make a new bundle or join us to an existing bundle + * if we are doing multilink. + */ +int +mp_join_bundle() +{ + lcp_options *go = &lcp_gotoptions[0]; + lcp_options *ho = &lcp_hisoptions[0]; + lcp_options *ao = &lcp_allowoptions[0]; + int unit, pppd_pid; + int l, mtu; + char *p; + TDB_DATA key, pid, rec; + + if (doing_multilink) { + /* have previously joined a bundle */ + if (!go->neg_mrru || !ho->neg_mrru) { + notice("oops, didn't get multilink on renegotiation"); + lcp_close(pcb, "multilink required"); + return 0; + } + /* XXX should check the peer_authname and ho->endpoint + are the same as previously */ + return 0; + } + + if (!go->neg_mrru || !ho->neg_mrru) { + /* not doing multilink */ + if (go->neg_mrru) + notice("oops, multilink negotiated only for receive"); + mtu = ho->neg_mru? ho->mru: PPP_MRU; + if (mtu > ao->mru) + mtu = ao->mru; + if (demand) { + /* already have a bundle */ + cfg_bundle(0, 0, 0, 0); + netif_set_mtu(pcb, mtu); + return 0; + } + make_new_bundle(0, 0, 0, 0); + set_ifunit(1); + netif_set_mtu(pcb, mtu); + return 0; + } + + doing_multilink = 1; + + /* + * Find the appropriate bundle or join a new one. + * First we make up a name for the bundle. + * The length estimate is worst-case assuming every + * character has to be quoted. + */ + l = 4 * strlen(peer_authname) + 10; + if (ho->neg_endpoint) + l += 3 * ho->endpoint.length + 8; + if (bundle_name) + l += 3 * strlen(bundle_name) + 2; + bundle_id = malloc(l); + if (bundle_id == 0) + novm("bundle identifier"); + + p = bundle_id; + p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); + if (ho->neg_endpoint || bundle_name) + *p++ = '/'; + if (ho->neg_endpoint) + p += slprintf(p, bundle_id+l-p, "%s", + epdisc_to_str(&ho->endpoint)); + if (bundle_name) + p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); + + /* Make the key for the list of links belonging to the bundle */ + l = p - bundle_id; + blinks_id = malloc(l + 7); + if (blinks_id == NULL) + novm("bundle links key"); + slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); + + /* + * For demand mode, we only need to configure the bundle + * and attach the link. + */ + mtu = LWIP_MIN(ho->mrru, ao->mru); + if (demand) { + cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); + netif_set_mtu(pcb, mtu); + script_setenv("BUNDLE", bundle_id + 7, 1); + return 0; + } + + /* + * Check if the bundle ID is already in the database. + */ + unit = -1; + lock_db(); + key.dptr = bundle_id; + key.dsize = p - bundle_id; + pid = tdb_fetch(pppdb, key); + if (pid.dptr != NULL) { + /* bundle ID exists, see if the pppd record exists */ + rec = tdb_fetch(pppdb, pid); + if (rec.dptr != NULL && rec.dsize > 0) { + /* make sure the string is null-terminated */ + rec.dptr[rec.dsize-1] = 0; + /* parse the interface number */ + parse_num(rec.dptr, "IFNAME=ppp", &unit); + /* check the pid value */ + if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) + || !process_exists(pppd_pid) + || !owns_unit(pid, unit)) + unit = -1; + free(rec.dptr); + } + free(pid.dptr); + } + + if (unit >= 0) { + /* attach to existing unit */ + if (bundle_attach(unit)) { + set_ifunit(0); + script_setenv("BUNDLE", bundle_id + 7, 0); + make_bundle_links(1); + unlock_db(); + info("Link attached to %s", ifname); + return 1; + } + /* attach failed because bundle doesn't exist */ + } + + /* we have to make a new bundle */ + make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); + set_ifunit(1); + netif_set_mtu(pcb, mtu); + script_setenv("BUNDLE", bundle_id + 7, 1); + make_bundle_links(pcb); + unlock_db(); + info("New bundle %s created", ifname); + multilink_master = 1; + return 0; +} + +void mp_exit_bundle() +{ + lock_db(); + remove_bundle_link(); + unlock_db(); +} + +static void sendhup(char *str) +{ + int pid; + + if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) { + if (debug) + dbglog("sending SIGHUP to process %d", pid); + kill(pid, SIGHUP); + } +} + +void mp_bundle_terminated() +{ + TDB_DATA key; + + bundle_terminating = 1; + upper_layers_down(pcb); + notice("Connection terminated."); +#if PPP_STATS_SUPPORT + print_link_stats(); +#endif /* PPP_STATS_SUPPORT */ + if (!demand) { + remove_pidfiles(); + script_unsetenv("IFNAME"); + } + + lock_db(); + destroy_bundle(); + iterate_bundle_links(sendhup); + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + tdb_delete(pppdb, key); + unlock_db(); + + new_phase(PPP_PHASE_DEAD); + + doing_multilink = 0; + multilink_master = 0; +} + +static void make_bundle_links(int append) +{ + TDB_DATA key, rec; + char *p; + char entry[32]; + int l; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + slprintf(entry, sizeof(entry), "%s;", db_key); + p = entry; + if (append) { + rec = tdb_fetch(pppdb, key); + if (rec.dptr != NULL && rec.dsize > 0) { + rec.dptr[rec.dsize-1] = 0; + if (strstr(rec.dptr, db_key) != NULL) { + /* already in there? strange */ + warn("link entry already exists in tdb"); + return; + } + l = rec.dsize + strlen(entry); + p = malloc(l); + if (p == NULL) + novm("bundle link list"); + slprintf(p, l, "%s%s", rec.dptr, entry); + } else { + warn("bundle link list not found"); + } + if (rec.dptr != NULL) + free(rec.dptr); + } + rec.dptr = p; + rec.dsize = strlen(p) + 1; + if (tdb_store(pppdb, key, rec, TDB_REPLACE)) + error("couldn't %s bundle link list", + append? "update": "create"); + if (p != entry) + free(p); +} + +static void remove_bundle_link() +{ + TDB_DATA key, rec; + char entry[32]; + char *p, *q; + int l; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + slprintf(entry, sizeof(entry), "%s;", db_key); + + rec = tdb_fetch(pppdb, key); + if (rec.dptr == NULL || rec.dsize <= 0) { + if (rec.dptr != NULL) + free(rec.dptr); + return; + } + rec.dptr[rec.dsize-1] = 0; + p = strstr(rec.dptr, entry); + if (p != NULL) { + q = p + strlen(entry); + l = strlen(q) + 1; + memmove(p, q, l); + rec.dsize = p - rec.dptr + l; + if (tdb_store(pppdb, key, rec, TDB_REPLACE)) + error("couldn't update bundle link list (removal)"); + } + free(rec.dptr); +} + +static void iterate_bundle_links(void (*func)(char *)) +{ + TDB_DATA key, rec, pp; + char *p, *q; + + key.dptr = blinks_id; + key.dsize = strlen(blinks_id); + rec = tdb_fetch(pppdb, key); + if (rec.dptr == NULL || rec.dsize <= 0) { + error("bundle link list not found (iterating list)"); + if (rec.dptr != NULL) + free(rec.dptr); + return; + } + p = rec.dptr; + p[rec.dsize-1] = 0; + while ((q = strchr(p, ';')) != NULL) { + *q = 0; + key.dptr = p; + key.dsize = q - p; + pp = tdb_fetch(pppdb, key); + if (pp.dptr != NULL && pp.dsize > 0) { + pp.dptr[pp.dsize-1] = 0; + func(pp.dptr); + } + if (pp.dptr != NULL) + free(pp.dptr); + p = q + 1; + } + free(rec.dptr); +} + +static int +parse_num(str, key, valp) + char *str; + const char *key; + int *valp; +{ + char *p, *endp; + int i; + + p = strstr(str, key); + if (p != 0) { + p += strlen(key); + i = strtol(p, &endp, 10); + if (endp != p && (*endp == 0 || *endp == ';')) { + *valp = i; + return 1; + } + } + return 0; +} + +/* + * Check whether the pppd identified by `key' still owns ppp unit `unit'. + */ +static int +owns_unit(key, unit) + TDB_DATA key; + int unit; +{ + char ifkey[32]; + TDB_DATA kd, vd; + int ret = 0; + + slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); + kd.dptr = ifkey; + kd.dsize = strlen(ifkey); + vd = tdb_fetch(pppdb, kd); + if (vd.dptr != NULL) { + ret = vd.dsize == key.dsize + && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; + free(vd.dptr); + } + return ret; +} + +static int +get_default_epdisc(ep) + struct epdisc *ep; +{ + char *p; + struct hostent *hp; + u32_t addr; + + /* First try for an ethernet MAC address */ + p = get_first_ethernet(); + if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { + ep->class = EPD_MAC; + ep->length = 6; + return 1; + } + + /* see if our hostname corresponds to a reasonable IP address */ + hp = gethostbyname(hostname); + if (hp != NULL) { + addr = *(u32_t *)hp->h_addr; + if (!bad_ip_adrs(addr)) { + addr = ntohl(addr); + if (!LOCAL_IP_ADDR(addr)) { + ep->class = EPD_IP; + set_ip_epdisc(ep, addr); + return 1; + } + } + } + + return 0; +} + +/* + * epdisc_to_str - make a printable string from an endpoint discriminator. + */ + +static char *endp_class_names[] = { + "null", "local", "IP", "MAC", "magic", "phone" +}; + +char * +epdisc_to_str(ep) + struct epdisc *ep; +{ + static char str[MAX_ENDP_LEN*3+8]; + u_char *p = ep->value; + int i, mask = 0; + char *q, c, c2; + + if (ep->class == EPD_NULL && ep->length == 0) + return "null"; + if (ep->class == EPD_IP && ep->length == 4) { + u32_t addr; + + GETLONG(addr, p); + slprintf(str, sizeof(str), "IP:%I", htonl(addr)); + return str; + } + + c = ':'; + c2 = '.'; + if (ep->class == EPD_MAC && ep->length == 6) + c2 = ':'; + else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) + mask = 3; + q = str; + if (ep->class <= EPD_PHONENUM) + q += slprintf(q, sizeof(str)-1, "%s", + endp_class_names[ep->class]); + else + q += slprintf(q, sizeof(str)-1, "%d", ep->class); + c = ':'; + for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { + if ((i & mask) == 0) { + *q++ = c; + c = c2; + } + q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); + } + return str; +} + +static int hexc_val(int c) +{ + if (c >= 'a') + return c - 'a' + 10; + if (c >= 'A') + return c - 'A' + 10; + return c - '0'; +} + +int +str_to_epdisc(ep, str) + struct epdisc *ep; + char *str; +{ + int i, l; + char *p, *endp; + + for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { + int sl = strlen(endp_class_names[i]); + if (strncasecmp(str, endp_class_names[i], sl) == 0) { + str += sl; + break; + } + } + if (i > EPD_PHONENUM) { + /* not a class name, try a decimal class number */ + i = strtol(str, &endp, 10); + if (endp == str) + return 0; /* can't parse class number */ + str = endp; + } + ep->class = i; + if (*str == 0) { + ep->length = 0; + return 1; + } + if (*str != ':' && *str != '.') + return 0; + ++str; + + if (i == EPD_IP) { + u32_t addr; + i = parse_dotted_ip(str, &addr); + if (i == 0 || str[i] != 0) + return 0; + set_ip_epdisc(ep, addr); + return 1; + } + if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { + ep->length = 6; + return 1; + } + + p = str; + for (l = 0; l < MAX_ENDP_LEN; ++l) { + if (*str == 0) + break; + if (p <= str) + for (p = str; isxdigit(*p); ++p) + ; + i = p - str; + if (i == 0) + return 0; + ep->value[l] = hexc_val(*str++); + if ((i & 1) == 0) + ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); + if (*str == ':' || *str == '.') + ++str; + } + if (*str != 0 || (ep->class == EPD_MAC && l != 6)) + return 0; + ep->length = l; + return 1; +} + +#endif /* PPP_SUPPORT && HAVE_MULTILINK */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/README b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/README new file mode 100644 index 0000000..71f78fa --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/README @@ -0,0 +1,34 @@ +About PolarSSL files into lwIP PPP support +------------------------------------------ + +This folder contains some files fetched from the latest BSD release of +the PolarSSL project for ciphers and encryption methods we need for lwIP +PPP support. + +The PolarSSL files were cleaned to contain only the necessary struct +fields and functions needed for lwIP. + + +The PolarSSL API was not changed at all, so if you are already using +PolarSSL you can choose to skip the compilation of the included PolarSSL +library into lwIP: + +The following defines are available for flexibility: + +LWIP_INCLUDED_POLARSSL_MD4 ; Use lwIP internal PolarSSL for MD4 +LWIP_INCLUDED_POLARSSL_MD5 ; Use lwIP internal PolarSSL for MD5 +LWIP_INCLUDED_POLARSSL_SHA1 ; Use lwIP internal PolarSSL for SHA1 +LWIP_INCLUDED_POLARSSL_DES ; Use lwIP internal PolarSSL for DES + +If set (=1), the default if required by another enabled PPP feature unless +explicitly set to 0, using included lwIP PolarSSL. + +If clear (=0), using external PolarSSL. + +Undefined if not needed. + +Beware of the stack requirements which can be a lot larger if you are not +using our cleaned PolarSSL library. + + +PolarSSL project website: http://polarssl.org/ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/des.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/des.c new file mode 100644 index 0000000..38f3a74 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/des.c @@ -0,0 +1,422 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES + +#include "netif/ppp/polarssl/des.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const unsigned long SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const unsigned long SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const unsigned long SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const unsigned long SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const unsigned long SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const unsigned long SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const unsigned long SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const unsigned long SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const unsigned long LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const unsigned long RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } + +static void des_setkey( unsigned long SK[32], unsigned char key[8] ) +{ + int i; + unsigned long X, Y, T; + + GET_ULONG_BE( X, key, 0 ); + GET_ULONG_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +void des_setkey_enc( des_context *ctx, unsigned char key[8] ) +{ + des_setkey( ctx->sk, key ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +void des_setkey_dec( des_context *ctx, unsigned char key[8] ) +{ + int i; + + des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } +} + +/* + * DES-ECB block encryption/decryption + */ +void des_crypt_ecb( des_context *ctx, + unsigned char input[8], + unsigned char output[8] ) +{ + int i; + unsigned long X, Y, T, *SK; + + SK = ctx->sk; + + GET_ULONG_BE( X, input, 0 ); + GET_ULONG_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_ULONG_BE( Y, output, 0 ); + PUT_ULONG_BE( X, output, 4 ); +} + +#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md4.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md4.c new file mode 100644 index 0000000..8de2eb9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md4.c @@ -0,0 +1,279 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 + +#include "netif/ppp/polarssl/md4.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD4 context setup + */ +void md4_starts( md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md4_process( md4_context *ctx, unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD4 process buffer + */ +void md4_update( md4_context *ctx, unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, fill ); + md4_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md4_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md4_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD4 final digest + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md4_update( ctx, (unsigned char *) md4_padding, padn ); + md4_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD4( input buffer ) + */ +void md4( unsigned char *input, int ilen, unsigned char output[16] ) +{ + md4_context ctx; + + md4_starts( &ctx ); + md4_update( &ctx, input, ilen ); + md4_finish( &ctx, output ); +} + +#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md5.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md5.c new file mode 100644 index 0000000..50aa911 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/md5.c @@ -0,0 +1,298 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 + +#include "netif/ppp/polarssl/md5.h" + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_ULONG_LE +#define GET_ULONG_LE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] ) \ + | ( (unsigned long) (b)[(i) + 1] << 8 ) \ + | ( (unsigned long) (b)[(i) + 2] << 16 ) \ + | ( (unsigned long) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_ULONG_LE +#define PUT_ULONG_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* + * MD5 context setup + */ +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +static void md5_process( md5_context *ctx, unsigned char data[64] ) +{ + unsigned long X[16], A, B, C, D; + + GET_ULONG_LE( X[ 0], data, 0 ); + GET_ULONG_LE( X[ 1], data, 4 ); + GET_ULONG_LE( X[ 2], data, 8 ); + GET_ULONG_LE( X[ 3], data, 12 ); + GET_ULONG_LE( X[ 4], data, 16 ); + GET_ULONG_LE( X[ 5], data, 20 ); + GET_ULONG_LE( X[ 6], data, 24 ); + GET_ULONG_LE( X[ 7], data, 28 ); + GET_ULONG_LE( X[ 8], data, 32 ); + GET_ULONG_LE( X[ 9], data, 36 ); + GET_ULONG_LE( X[10], data, 40 ); + GET_ULONG_LE( X[11], data, 44 ); + GET_ULONG_LE( X[12], data, 48 ); + GET_ULONG_LE( X[13], data, 52 ); + GET_ULONG_LE( X[14], data, 56 ); + GET_ULONG_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +void md5_update( md5_context *ctx, unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_LE( low, msglen, 0 ); + PUT_ULONG_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, (unsigned char *) md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_ULONG_LE( ctx->state[0], output, 0 ); + PUT_ULONG_LE( ctx->state[1], output, 4 ); + PUT_ULONG_LE( ctx->state[2], output, 8 ); + PUT_ULONG_LE( ctx->state[3], output, 12 ); +} + +/* + * output = MD5( input buffer ) + */ +void md5( unsigned char *input, int ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); +} + +#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/sha1.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/sha1.c new file mode 100644 index 0000000..78fe46e --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/polarssl/sha1.c @@ -0,0 +1,333 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine + * + * Copyright (C) 2009 Paul Bakker + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the names of PolarSSL or XySSL nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 + +#include "netif/ppp/polarssl/sha1.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +static void sha1_process( sha1_context *ctx, unsigned char data[64] ) +{ + unsigned long temp, W[16], A, B, C, D, E; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ + W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, unsigned char *input, int ilen ) +{ + int fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + MEMCPY( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, (unsigned char *) sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); +} + +/* + * output = SHA-1( input buffer ) + */ +void sha1( unsigned char *input, int ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); +} + +#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ppp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ppp.c new file mode 100644 index 0000000..bc85396 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/ppp.c @@ -0,0 +1,2606 @@ +/***************************************************************************** +* ppp.c - Network Point to Point Protocol program file. +* +* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. +* portions Copyright (c) 1997 by Global Election Systems Inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 03-01-01 Marc Boucher +* Ported to lwIP. +* 97-11-05 Guy Lancaster , Global Election Systems Inc. +* Original. +*****************************************************************************/ + +/* + * ppp_defs.h - PPP definitions. + * + * if_pppvar.h - private structures and declarations for PPP. + * + * Copyright (c) 1994 The Australian National University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation is hereby granted, provided that the above copyright + * notice appears in all copies. This software is provided without any + * warranty, express or implied. The Australian National University + * makes no representations about the suitability of this software for + * any purpose. + * + * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY + * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF + * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO + * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, + * OR MODIFICATIONS. + */ + +/* + * if_ppp.h - Point-to-Point Protocol definitions. + * + * Copyright (c) 1989 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by Carnegie Mellon University. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/sys.h" +#include "lwip/tcpip.h" +#include "lwip/api.h" +#include "lwip/snmp.h" +#include "lwip/sio.h" +#include "lwip/sys.h" +#include "lwip/ip.h" /* for ip_input() */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" +#include "netif/ppp/ipcp.h" +#include "netif/ppp/magic.h" + +#if PAP_SUPPORT +#include "netif/ppp/upap.h" +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT +#include "netif/ppp/chap-new.h" +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT +#include "netif/ppp/eap.h" +#endif /* EAP_SUPPORT */ +#if CCP_SUPPORT +#include "netif/ppp/ccp.h" +#endif /* EAP_SUPPORT */ +#if ECP_SUPPORT +#include "netif/ppp/ecp.h" +#endif /* EAP_SUPPORT */ +#if VJ_SUPPORT +#include "netif/ppp/vj.h" +#endif /* VJ_SUPPORT */ +#if PPP_IPV6_SUPPORT +#include "netif/ppp/ipv6cp.h" +#endif /* PPP_IPV6_SUPPORT */ + +#if PPPOE_SUPPORT +#include "netif/ppp/pppoe.h" +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT +#include "netif/ppp/pppol2tp.h" +#endif /* PPPOL2TP_SUPPORT */ + +/* Global variables */ + +#if PPP_DEBUG +u8_t ppp_num; /* PPP Interface counter, used for debugging messages */ +#endif /* PPP_DEBUG */ + +/*************************/ +/*** LOCAL DEFINITIONS ***/ +/*************************/ + +/* FIXME: add stats per PPP session */ +#if PPP_STATS_SUPPORT +static struct timeval start_time; /* Time when link was started. */ +static struct pppd_stats old_link_stats; +struct pppd_stats link_stats; +unsigned link_connect_time; +int link_stats_valid; +#endif /* PPP_STATS_SUPPORT */ + +/* + * PPP Data Link Layer "protocol" table. + * One entry per supported protocol. + * The last entry must be NULL. + */ +const struct protent* const protocols[] = { + &lcp_protent, +#if PAP_SUPPORT + &pap_protent, +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + &chap_protent, +#endif /* CHAP_SUPPORT */ +#if CBCP_SUPPORT + &cbcp_protent, +#endif + &ipcp_protent, +#if PPP_IPV6_SUPPORT + &ipv6cp_protent, +#endif +#if CCP_SUPPORT + &ccp_protent, +#endif /* CCP_SUPPORT */ +#if ECP_SUPPORT + &ecp_protent, +#endif /* ECP_SUPPORT */ +#ifdef AT_CHANGE + &atcp_protent, +#endif +#if EAP_SUPPORT + &eap_protent, +#endif /* EAP_SUPPORT */ + NULL +}; + +/* Prototypes for procedures local to this file. */ +static void ppp_clear(ppp_pcb *pcb); +static void ppp_do_open(void *arg); +static void ppp_start(ppp_pcb *pcb); /** Initiate LCP open request */ +static void ppp_stop(ppp_pcb *pcb); +static void ppp_hup(ppp_pcb *pcb); + +static err_t ppp_netif_init_cb(struct netif *netif); +static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr); +#if PPP_IPV6_SUPPORT +static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr); +#endif /* PPP_IPV6_SUPPORT */ +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol); + +#if PPPOS_SUPPORT +#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & ppp_accm_mask[c & 0x07]) +static void ppp_over_serial_open(ppp_pcb *pcb); +static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol); +static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p); +static void ppp_drop(ppp_pcb_rx *pcrx); +#if PPP_INPROC_MULTITHREADED +static void pppos_input_callback(void *arg); +#endif /* PPP_INPROC_MULTITHREADED */ +static void ppp_free_current_input_packet(ppp_pcb_rx *pcrx); +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static void ppp_over_ethernet_open(ppp_pcb *pcb); +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol); +static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p); +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_open(ppp_pcb *pcb); +static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol); +static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p); +#endif /* PPPOL2TP_SUPPORT */ + +/***********************************/ +/*** PUBLIC FUNCTION DEFINITIONS ***/ +/***********************************/ + +/* Initialize the PPP subsystem. */ +int ppp_init(void) { + + /* + * Initialize magic number generator now so that protocols may + * use magic numbers in initialization. + */ + magic_init(); + + return 0; +} + +/* Create a new PPP session. */ +ppp_pcb *ppp_new(void) { + ppp_pcb *pcb; + + pcb = (ppp_pcb*)memp_malloc(MEMP_PPP_PCB); + if (pcb == NULL) { + return NULL; + } + + memset(pcb, 0, sizeof(ppp_pcb)); +#if PPP_DEBUG + pcb->num = ppp_num++; +#endif /* PPP_DEBUG */ + + /* default configuration */ + pcb->settings.usepeerdns = 1; + +#if PAP_SUPPORT + pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; + pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; +#if PPP_SERVER + pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; +#endif /* PPP_SERVER */ +#endif /* PAP_SUPPORT */ + +#if CHAP_SUPPORT + pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; + pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; +#if PPP_SERVER + pcb->settings.chap_rechallenge_time = CHAP_DEFREQTIME; +#endif /* PPP_SERVER */ +#endif /* CHAP_SUPPPORT */ + +#if EAP_SUPPORT + pcb->settings.eap_req_time = EAP_DEFREQTIME; + pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; +#if PPP_SERVER + pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; + pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; +#endif /* PPP_SERVER */ +#endif /* EAP_SUPPORT */ + + pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; + pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; + pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; + + pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; + pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; + pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; + pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; + + if (!netif_add(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr, (void *)pcb, ppp_netif_init_cb, NULL)) { + memp_free(MEMP_PPP_PCB, pcb); + PPPDEBUG(LOG_ERR, ("ppp_new[%d]: netif_add failed\n", pcb->num)); + return NULL; + } + + new_phase(pcb, PPP_PHASE_DEAD); + return pcb; +} + +void ppp_set_default(ppp_pcb *pcb) { + netif_set_default(&pcb->netif); +} + +void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { + +#if PAP_SUPPORT + if (authtype & PPPAUTHTYPE_PAP) { + pcb->settings.refuse_pap = 0; + } else { + pcb->settings.refuse_pap = 1; + } +#endif /* PAP_SUPPORT */ + +#if CHAP_SUPPORT + if (authtype & PPPAUTHTYPE_CHAP) { + pcb->settings.refuse_chap = 0; + } else { + pcb->settings.refuse_chap = 1; + } +#if MSCHAP_SUPPORT + if (authtype & PPPAUTHTYPE_MSCHAP) { + pcb->settings.refuse_mschap = 0; + pcb->settings.refuse_mschap_v2 = 0; + } else { + pcb->settings.refuse_mschap = 1; + pcb->settings.refuse_mschap_v2 = 1; + } +#endif /* MSCHAP_SUPPORT */ +#endif /* CHAP_SUPPORT */ + +#if EAP_SUPPORT + if (authtype & PPPAUTHTYPE_EAP) { + pcb->settings.refuse_eap = 0; + } else { + pcb->settings.refuse_eap = 1; + } +#endif /* EAP_SUPPORT */ + + if (user) { + pcb->settings.user = user; + } + + if (passwd) { + pcb->settings.passwd = passwd; + } +} + +#if PPP_NOTIFY_PHASE +void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { + pcb->notify_phase_cb = notify_phase_cb; + notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); +} +#endif /* PPP_NOTIFY_PHASE */ + +#if PPPOS_SUPPORT +int ppp_over_serial_create(ppp_pcb *pcb, sio_fd_t fd, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { + + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) { + return PPPERR_PARAM; + } + + pcb->fd = fd; + pcb->link_status_cb = link_status_cb; + pcb->ctx_cb = ctx_cb; + return PPPERR_NONE; +} + +/* + * ppp_set_xaccm - set the extended transmit ACCM for the interface. + */ +void ppp_set_xaccm(ppp_pcb *pcb, ext_accm *accm) { + SMEMCPY(pcb->out_accm, accm, sizeof(ext_accm)); + PPPDEBUG(LOG_INFO, ("ppp_set_xaccm[%d]: out_accm=%X %X %X %X\n", + pcb->num, + pcb->out_accm[0], + pcb->out_accm[1], + pcb->out_accm[2], + pcb->out_accm[3])); +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state); + +int ppp_over_ethernet_create(ppp_pcb *pcb, struct netif *ethif, const char *service_name, const char *concentrator_name, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { + + LWIP_UNUSED_ARG(service_name); + LWIP_UNUSED_ARG(concentrator_name); + + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) { + return PPPERR_PARAM; + } + + pcb->link_status_cb = link_status_cb; + pcb->ctx_cb = ctx_cb; + + if (pppoe_create(ethif, pcb, ppp_over_ethernet_link_status_cb, &pcb->pppoe_sc) != ERR_OK) { + return PPPERR_OPEN; + } + + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state); + +int ppp_over_l2tp_create(ppp_pcb *pcb, struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len, + ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { + + /* PPP is single-threaded: without a callback, + * there is no way to know when the link is up. */ + if (link_status_cb == NULL) { + return PPPERR_PARAM; + } + + pcb->link_status_cb = link_status_cb; + pcb->ctx_cb = ctx_cb; + + if (pppol2tp_create(pcb, ppp_over_l2tp_link_status_cb, &pcb->l2tp_pcb, netif, ipaddr, port, secret, secret_len) != ERR_OK) { + return PPPERR_OPEN; + } + + return PPPERR_NONE; +} +#endif /* PPPOL2TP_SUPPORT */ + +/* + * Open a PPP connection. + * + * This can only be called if PPP is in the dead phase. + * + * Holdoff is the time to wait (in seconds) before initiating + * the connection. + */ +int ppp_open(ppp_pcb *pcb, u16_t holdoff) { + if (pcb->phase != PPP_PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_open() called, holdoff=%d\n", holdoff)); + + if (holdoff == 0) { + ppp_do_open(pcb); + return PPPERR_NONE; + } + + new_phase(pcb, PPP_PHASE_HOLDOFF); + sys_timeout((u32_t)(holdoff*1000), ppp_do_open, pcb); + return PPPERR_NONE; +} + +/* + * Initiate the end of a PPP connection. + * Any outstanding packets in the queues are dropped. + * Return 0 on success, an error code on failure. + */ +int +ppp_close(ppp_pcb *pcb) +{ + int st = 0; + + pcb->err_code = PPPERR_USER; + + /* dead phase, nothing to do, call the status callback to be consistent */ + if (pcb->phase == PPP_PHASE_DEAD) { + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); + return PPPERR_NONE; + } + + /* holdoff phase, cancel the reconnection and call the status callback */ + if (pcb->phase == PPP_PHASE_HOLDOFF) { + sys_untimeout(ppp_do_open, pcb); + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); + return PPPERR_NONE; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_close() called\n")); + + /* Disconnect */ +#if PPPOE_SUPPORT + if (pcb->pppoe_sc) { + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); + /* This will leave us at PPP_PHASE_DEAD. */ + ppp_stop(pcb); + } else +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); + /* This will leave us at PPP_PHASE_DEAD. */ + ppp_stop(pcb); + } else +#endif /* PPPOL2TP_SUPPORT */ + { +#if PPPOS_SUPPORT + PPPDEBUG(LOG_DEBUG, ("ppp_close: unit %d kill_link -> ppp_stop\n", pcb->num)); + /* This will leave us at PPP_PHASE_DEAD. */ + ppp_stop(pcb); +#endif /* PPPOS_SUPPORT */ + } + + return st; +} + +/* This function is called when carrier is lost on the PPP channel. */ +void +ppp_sighup(ppp_pcb *pcb) +{ + PPPDEBUG(LOG_DEBUG, ("ppp_sighup: unit %d sig_hup -> ppp_hup\n", pcb->num)); + ppp_hup(pcb); +} + +/* + * Free the control block, clean everything except the PPP PCB itself + * and the netif, it allows you to change the underlying PPP protocol + * (eg. from PPPoE to PPPoS to switch from DSL to GPRS) without losing + * your PPP and netif handlers. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_free(ppp_pcb *pcb) { + if (pcb->phase != PPP_PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_free: unit %d\n", pcb->num)); + +#if PPPOE_SUPPORT + if (pcb->pppoe_sc) { + pppoe_destroy(pcb->pppoe_sc); + pcb->pppoe_sc = NULL; + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + pppol2tp_destroy(pcb->l2tp_pcb); + pcb->l2tp_pcb = NULL; + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + /* input pbuf left ? */ + ppp_free_current_input_packet(&pcb->rx); +#endif /* PPPOS_SUPPORT */ + + return 0; +} + +/* + * Release the control block. + * + * This can only be called if PPP is in the dead phase. + * + * You must use ppp_close() before if you wish to terminate + * an established PPP session. + * + * Return 0 on success, an error code on failure. + */ +int ppp_delete(ppp_pcb *pcb) { + int err; + + if (pcb->phase != PPP_PHASE_DEAD) { + return PPPERR_PARAM; + } + + PPPDEBUG(LOG_DEBUG, ("ppp_delete: unit %d\n", pcb->num)); + + netif_remove(&pcb->netif); + if( (err = ppp_free(pcb)) != PPPERR_NONE) { + return err; + } + + memp_free(MEMP_PPP_PCB, pcb); + return 0; +} + + + + +/************************************/ +/*** PRIVATE FUNCTION DEFINITIONS ***/ +/************************************/ + +/* Set a PPP PCB to its initial state */ +static void ppp_clear(ppp_pcb *pcb) { + const struct protent *protp; + int i; + + LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); + +#if PPP_STATS_SUPPORT + link_stats_valid = 0; +#endif /* PPP_STATS_SUPPORT */ + + memset(&pcb->phase, 0, sizeof(ppp_pcb) - ( (char*)&((ppp_pcb*)0)->phase - (char*)0 ) ); + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); + + /* + * Initialize each protocol. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + (*protp->init)(pcb); + } + + new_phase(pcb, PPP_PHASE_INITIALIZE); +} + +static void ppp_do_open(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); + +#if PPPOE_SUPPORT + if (pcb->pppoe_sc) { + ppp_over_ethernet_open(pcb); + return; + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + ppp_over_l2tp_open(pcb); + return; + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + ppp_over_serial_open(pcb); +#endif /* PPPOS_SUPPORT */ +} + +/** Initiate LCP open request */ +static void ppp_start(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_start: unit %d\n", pcb->num)); + lcp_open(pcb); /* Start protocol */ + lcp_lowerup(pcb); + PPPDEBUG(LOG_DEBUG, ("ppp_start: finished\n")); +} + +/** LCP close request */ +static void ppp_stop(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_stop: unit %d\n", pcb->num)); + lcp_close(pcb, "User request"); +} + +/** Called when carrier/link is lost */ +static void ppp_hup(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_hup: unit %d\n", pcb->num)); + lcp_lowerdown(pcb); + link_terminated(pcb); +} + +/* + * Pass the processed input packet to the appropriate handler. + * This function and all handlers run in the context of the tcpip_thread + */ +void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { + u16_t protocol; + + protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; + +#if PRINTPKT_SUPPORT + ppp_dump_packet("rcvd", (unsigned char *)pb->payload, pb->len); +#endif /* PRINTPKT_SUPPORT */ + + if(pbuf_header(pb, -(s16_t)sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + LINK_STATS_INC(link.recv); + snmp_inc_ifinucastpkts(&pcb->netif); + snmp_add_ifinoctets(&pcb->netif, pb->tot_len); + + /* + * Toss all non-LCP packets unless LCP is OPEN. + */ + if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { + ppp_dbglog("Discarded non-LCP packet when LCP not open"); + goto drop; + } + + /* + * Until we get past the authentication phase, toss all packets + * except LCP, LQR and authentication packets. + */ + if (pcb->phase <= PPP_PHASE_AUTHENTICATE + && !(protocol == PPP_LCP +#if LQR_SUPPORT + || protocol == PPP_LQR +#endif /* LQR_SUPPORT */ +#if PAP_SUPPORT + || protocol == PPP_PAP +#endif /* PAP_SUPPORT */ +#if CHAP_SUPPORT + || protocol == PPP_CHAP +#endif /* CHAP_SUPPORT */ +#if EAP_SUPPORT + || protocol == PPP_EAP +#endif /* EAP_SUPPORT */ + )) { + ppp_dbglog("discarding proto 0x%x in phase %d", + protocol, pcb->phase); + goto drop; + } + + /* FIXME: should we write protent to do that ? */ + + switch(protocol) { + +#if VJ_SUPPORT + case PPP_VJC_COMP: /* VJ compressed TCP */ + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->num, pb->len)); + /* + * Clip off the VJ header and prepend the rebuilt TCP/IP header and + * pass the result to IP. + */ + if (vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { + ip_input(pb, &pcb->netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->num)); + break; + + case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->num, pb->len)); + /* + * Process the TCP/IP header for VJ header compression and then pass + * the packet to IP. + */ + if (vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { + ip_input(pb, &pcb->netif); + return; + } + /* Something's wrong so drop it. */ + PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->num)); + break; +#endif /* VJ_SUPPORT */ + + case PPP_IP: /* Internet Protocol */ + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->num, pb->len)); + ip_input(pb, &pcb->netif); + return; + +#if PPP_IPV6_SUPPORT + case PPP_IPV6: /* Internet Protocol Version 6 */ + PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->num, pb->len)); + ip6_input(pb, &pcb->netif); + return; +#endif /* PPP_IPV6_SUPPORT */ + + default: { + + int i; + const struct protent *protp; + /* + * Upcall the proper protocol input routine. + */ + for (i = 0; (protp = protocols[i]) != NULL; ++i) { + if (protp->protocol == protocol && protp->enabled_flag) { + pb = ppp_singlebuf(pb); + (*protp->input)(pcb, (u_char*)pb->payload, pb->len); + goto out; + } +#if 0 /* UNUSED + * + * This is actually a (hacked?) way for the PPP kernel implementation to pass a + * data packet to the PPP daemon. The PPP daemon normally only do signaling + * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. + * + * This is only used by CCP, which we cannot support until we have a CCP data + * implementation. + */ + if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag + && protp->datainput != NULL) { + (*protp->datainput)(pcb, pb->payload, pb->len); + goto out; + } +#endif /* UNUSED */ + } + +#if PPP_DEBUG +#if PPP_PROTOCOLNAME + const char *pname = protocol_name(protocol); + if (pname != NULL) { + ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); + } else +#endif /* PPP_PROTOCOLNAME */ + ppp_warn("Unsupported protocol 0x%x received", protocol); +#endif /* PPP_DEBUG */ + if (pbuf_header(pb, (s16_t)sizeof(protocol))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + lcp_sprotrej(pcb, (u_char*)pb->payload, pb->len); + } + break; + } + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); + +out: + pbuf_free(pb); + magic_randomize(); + return; +} + +#if PPPOS_SUPPORT +#if PPP_FCS_TABLE +/* + * FCS lookup table as calculated by genfcstab. + */ +static const u_short fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; +#else /* PPP_FCS_TABLE */ +/* The HDLC polynomial: X**0 + X**5 + X**12 + X**16 (0x8408) */ +#define PPP_FCS_POLYNOMIAL 0x8408 +u16_t ppp_get_fcs(u8_t byte) { + unsigned int octet; + int bit; + octet = byte; + for (bit = 8; bit-- > 0; ) { + octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1); + } + return octet & 0xffff; +} +#endif /* PPP_FCS_TABLE */ + +/* PPP's Asynchronous-Control-Character-Map. The mask array is used + * to select the specific bit for a character. */ +static u_char ppp_accm_mask[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80 +}; +#endif /* PPPOS_SUPPORT */ + +/* + * ppp_netif_init_cb - netif init callback + */ +static err_t ppp_netif_init_cb(struct netif *netif) { + netif->name[0] = 'p'; + netif->name[1] = 'p'; + netif->output = ppp_netif_output_ip4; +#if PPP_IPV6_SUPPORT + netif->output_ip6 = ppp_netif_output_ip6; +#endif /* PPP_IPV6_SUPPORT */ + netif->flags = NETIF_FLAG_POINTTOPOINT | NETIF_FLAG_LINK_UP; +#if LWIP_NETIF_HOSTNAME + /* @todo: Initialize interface hostname */ + /* netif_set_hostname(netif, "lwip"); */ +#endif /* LWIP_NETIF_HOSTNAME */ + return ERR_OK; +} + + +/**********************************/ +/*** LOCAL FUNCTION DEFINITIONS ***/ +/**********************************/ + +#if PPPOS_SUPPORT +static void ppp_over_serial_open(ppp_pcb *pcb) { + + /* input pbuf left over from last session? */ + ppp_free_current_input_packet(&pcb->rx); + + ppp_clear(pcb); + + pcb->rx.pcb = pcb; + pcb->rx.fd = pcb->fd; + +#if VJ_SUPPORT + vj_compress_init(&pcb->vj_comp); +#endif /* VJ_SUPPORT */ + + /* + * Default the in and out accm so that escape and flag characters + * are always escaped. + */ + pcb->rx.in_accm[15] = 0x60; /* no need to protect since RX is not running */ + pcb->out_accm[15] = 0x60; + + /* + * Start the connection and handle incoming events (packet or timeout). + */ + PPPDEBUG(LOG_INFO, ("ppp_over_serial_open: unit %d: connecting\n", pcb->num)); + ppp_start(pcb); +} + +static void +pppos_put(ppp_pcb *pcb, struct pbuf *nb) +{ + struct pbuf *b; + int c; + + for(b = nb; b != NULL; b = b->next) { + c = sio_write(pcb->fd, (u8_t*)b->payload, b->len); + if(c != b->len) { + PPPDEBUG(LOG_WARNING, + ("PPP pppos_put: incomplete sio_write(fd:%"SZT_F", len:%d, c: 0x%"X8_F") c = %d\n", (size_t)pcb->fd, b->len, c, c)); + LINK_STATS_INC(link.err); + pcb->last_xmit = 0; /* prepend PPP_FLAG to next packet */ + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(nb); + return; + } + } + + snmp_add_ifoutoctets(&pcb->netif, nb->tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + pbuf_free(nb); + LINK_STATS_INC(link.xmit); +} + +/* + * ppp_append - append given character to end of given pbuf. If out_accm + * is not NULL and the character needs to be escaped, do so. + * If pbuf is full, append another. + * Return the current pbuf. + */ +static struct pbuf * +ppp_append(u_char c, struct pbuf *nb, ext_accm *out_accm) +{ + struct pbuf *tb = nb; + + /* Make sure there is room for the character and an escape code. + * Sure we don't quite fill the buffer if the character doesn't + * get escaped but is one character worth complicating this? */ + /* Note: We assume no packet header. */ + if (nb && (PBUF_POOL_BUFSIZE - nb->len) < 2) { + tb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (tb) { + nb->next = tb; + } else { + LINK_STATS_INC(link.memerr); + } + nb = tb; + } + + if (nb) { + if (out_accm && ESCAPE_P(*out_accm, c)) { + *((u_char*)nb->payload + nb->len++) = PPP_ESCAPE; + *((u_char*)nb->payload + nb->len++) = c ^ PPP_TRANS; + } else { + *((u_char*)nb->payload + nb->len++) = c; + } + } + + return tb; +} +#endif /* PPPOS_SUPPORT */ + + +/* Send a IPv4 packet on the given connection. + */ +static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, ip_addr_t *ipaddr) { + LWIP_UNUSED_ARG(ipaddr); + return ppp_netif_output(netif, pb, PPP_IP); +} + +#if PPP_IPV6_SUPPORT +/* Send a IPv6 packet on the given connection. + */ +static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, ip6_addr_t *ipaddr) { + LWIP_UNUSED_ARG(ipaddr); + return ppp_netif_output(netif, pb, PPP_IPV6); +} +#endif /* PPP_IPV6_SUPPORT */ + +/* Send a packet on the given connection. + * + * This is the low level function that send the PPP packet, + * only for IPv4 and IPv6 packets coming from lwIP. + */ +static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u_short protocol) { + ppp_pcb *pcb = (ppp_pcb*)netif->state; + + /* Validate parameters. */ + /* We let any protocol value go through - it can't hurt us + * and the peer will just drop it if it's not accepting it. */ + if (!pcb || !pb) { + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad params prot=%d pb=%p\n", + pcb->num, PPP_IP, (void*)pb)); + LINK_STATS_INC(link.opterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_ARG; + } + + /* Check that the link is up. */ + if (!pcb->if_up) { + PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->num)); + LINK_STATS_INC(link.rterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(netif); + return ERR_RTE; + } + +#if PPPOE_SUPPORT + if(pcb->pppoe_sc) { + return ppp_netif_output_over_ethernet(pcb, pb, protocol); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if(pcb->l2tp_pcb) { + return ppp_netif_output_over_l2tp(pcb, pb, protocol); + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + return ppp_netif_output_over_serial(pcb, pb, protocol); +#endif /* PPPOS_SUPPORT */ + +#if !PPPOS_SUPPORT + return ERR_OK; +#endif +} + +#if PPPOS_SUPPORT +static err_t ppp_netif_output_over_serial(ppp_pcb *pcb, struct pbuf *pb, u_short protocol) { + u_int fcs_out = PPP_INITFCS; + struct pbuf *head = NULL, *tail = NULL, *p; + u_char c; + + /* Grab an output buffer. */ + head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (head == NULL) { + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: first alloc fail\n", pcb->num)); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(&pcb->netif); + return ERR_MEM; + } + +#if VJ_SUPPORT + /* + * Attempt Van Jacobson header compression if VJ is configured and + * this is an IP packet. + */ + if (protocol == PPP_IP && pcb->vj_enabled) { + switch (vj_compress_tcp(&pcb->vj_comp, pb)) { + case TYPE_IP: + /* No change... + protocol = PPP_IP_PROTOCOL; */ + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + break; + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + default: + PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->num)); + LINK_STATS_INC(link.proterr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(head); + return ERR_VAL; + } + } +#endif /* VJ_SUPPORT */ + + tail = head; + + /* Build the PPP header. */ + if ((sys_jiffies() - pcb->last_xmit) >= PPP_MAXIDLEFLAG) { + tail = ppp_append(PPP_FLAG, tail, NULL); + } + + pcb->last_xmit = sys_jiffies(); + if (!pcb->accomp) { + fcs_out = PPP_FCS(fcs_out, PPP_ALLSTATIONS); + tail = ppp_append(PPP_ALLSTATIONS, tail, &pcb->out_accm); + fcs_out = PPP_FCS(fcs_out, PPP_UI); + tail = ppp_append(PPP_UI, tail, &pcb->out_accm); + } + if (!pcb->pcomp || protocol > 0xFF) { + c = (protocol >> 8) & 0xFF; + fcs_out = PPP_FCS(fcs_out, c); + tail = ppp_append(c, tail, &pcb->out_accm); + } + c = protocol & 0xFF; + fcs_out = PPP_FCS(fcs_out, c); + tail = ppp_append(c, tail, &pcb->out_accm); + + /* Load packet. */ + for(p = pb; p; p = p->next) { + int n; + u_char *sPtr; + + sPtr = (u_char*)p->payload; + n = p->len; + while (n-- > 0) { + c = *sPtr++; + + /* Update FCS before checking for special characters. */ + fcs_out = PPP_FCS(fcs_out, c); + + /* Copy to output buffer escaping special characters. */ + tail = ppp_append(c, tail, &pcb->out_accm); + } + } + + /* Add FCS and trailing flag. */ + c = ~fcs_out & 0xFF; + tail = ppp_append(c, tail, &pcb->out_accm); + c = (~fcs_out >> 8) & 0xFF; + tail = ppp_append(c, tail, &pcb->out_accm); + tail = ppp_append(PPP_FLAG, tail, NULL); + + /* If we failed to complete the packet, throw it away. */ + if (!tail) { + PPPDEBUG(LOG_WARNING, + ("ppp_netif_output[%d]: Alloc err - dropping proto=%d\n", + pcb->num, protocol)); + pbuf_free(head); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + snmp_inc_ifoutdiscards(&pcb->netif); + return ERR_MEM; + } + + /* Send it. */ + PPPDEBUG(LOG_INFO, ("ppp_netif_output[%d]: proto=0x%"X16_F"\n", pcb->num, protocol)); + + pppos_put(pcb, head); + return ERR_OK; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static err_t ppp_netif_output_over_ethernet(ppp_pcb *pcb, struct pbuf *p, u_short protocol) { + struct pbuf *pb; + int i=0; +#if LWIP_SNMP + u16_t tot_len; +#endif /* LWIP_SNMP */ + err_t err; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOE_HEADERLEN); + + pcb->last_xmit = sys_jiffies(); + + if (!pcb->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); +#if LWIP_SNMP + tot_len = pb->tot_len; +#endif /* LWIP_SNMP */ + + if( (err = pppoe_xmit(pcb->pppoe_sc, pb)) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return err; + } + + snmp_add_ifoutoctets(&pcb->netif, tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOE_SUPPORT */ + + +#if PPPOL2TP_SUPPORT +static err_t ppp_netif_output_over_l2tp(ppp_pcb *pcb, struct pbuf *p, u_short protocol) { + struct pbuf *pb; + int i=0; +#if LWIP_SNMP + u16_t tot_len; +#endif /* LWIP_SNMP */ + err_t err; + + /* @todo: try to use pbuf_header() here! */ + pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM); + if(!pb) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + return ERR_MEM; + } + + pbuf_header(pb, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); + + pcb->last_xmit = sys_jiffies(); + + if (!pcb->pcomp || protocol > 0xFF) { + *((u_char*)pb->payload + i++) = (protocol >> 8) & 0xFF; + } + *((u_char*)pb->payload + i) = protocol & 0xFF; + + pbuf_chain(pb, p); +#if LWIP_SNMP + tot_len = pb->tot_len; +#endif /* LWIP_SNMP */ + + if( (err = pppol2tp_xmit(pcb->l2tp_pcb, pb)) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return err; + } + + snmp_add_ifoutoctets(&pcb->netif, tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return ERR_OK; +} +#endif /* PPPOL2TP_SUPPORT */ + + +/* Get and set parameters for the given connection. + * Return 0 on success, an error code on failure. */ +int +ppp_ioctl(ppp_pcb *pcb, int cmd, void *arg) +{ + if(NULL == pcb) + return PPPERR_PARAM; + + switch(cmd) { + case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ + if (arg) { + *(int *)arg = (int)(pcb->if_up); + return PPPERR_NONE; + } + return PPPERR_PARAM; + break; + + case PPPCTLS_ERRCODE: /* Set the PPP error code. */ + if (arg) { + pcb->err_code = (u8_t)(*(int *)arg); + return PPPERR_NONE; + } + return PPPERR_PARAM; + break; + + case PPPCTLG_ERRCODE: /* Get the PPP error code. */ + if (arg) { + *(int *)arg = (int)(pcb->err_code); + return PPPERR_NONE; + } + return PPPERR_PARAM; + break; + +#if PPPOS_SUPPORT + case PPPCTLG_FD: /* Get the fd associated with the ppp */ + if (arg) { + *(sio_fd_t *)arg = pcb->fd; + return PPPERR_NONE; + } + return PPPERR_PARAM; + break; +#endif /* PPPOS_SUPPORT */ + + default: + break; + } + + return PPPERR_PARAM; +} + +/* + * Write a pbuf to a ppp link, only used from PPP functions + * to send PPP packets. + * + * IPv4 and IPv6 packets from lwIP are sent, respectively, + * with ppp_netif_output_ip4() and ppp_netif_output_ip6() + * functions (which are callbacks of the netif PPP interface). + * + * RETURN: >= 0 Number of characters written + * -1 Failed to write to device + */ +int ppp_write(ppp_pcb *pcb, struct pbuf *p) { +#if PRINTPKT_SUPPORT + ppp_dump_packet("sent", (unsigned char *)p->payload+2, p->len-2); +#endif /* PRINTPKT_SUPPORT */ + +#if PPPOE_SUPPORT + if(pcb->pppoe_sc) { + return ppp_write_over_ethernet(pcb, p); + } +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT + if(pcb->l2tp_pcb) { + return ppp_write_over_l2tp(pcb, p); + } +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT + return ppp_write_over_serial(pcb, p); +#endif /* PPPOS_SUPPORT */ + +#if !PPPOS_SUPPORT + pbuf_free(p); + return PPPERR_NONE; +#endif +} + +#if PPPOS_SUPPORT +static int ppp_write_over_serial(ppp_pcb *pcb, struct pbuf *p) { + u_char *s = (u_char*)p->payload; + int n = p->len; + u_char c; + u_int fcs_out; + struct pbuf *head, *tail; + + head = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); + if (head == NULL) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); + return PPPERR_ALLOC; + } + + tail = head; + + /* If the link has been idle, we'll send a fresh flag character to + * flush any noise. */ + if ((sys_jiffies() - pcb->last_xmit) >= PPP_MAXIDLEFLAG) { + tail = ppp_append(PPP_FLAG, tail, NULL); + } + pcb->last_xmit = sys_jiffies(); + + fcs_out = PPP_INITFCS; + /* Load output buffer. */ + while (n-- > 0) { + c = *s++; + + /* Update FCS before checking for special characters. */ + fcs_out = PPP_FCS(fcs_out, c); + + /* Copy to output buffer escaping special characters. */ + tail = ppp_append(c, tail, &pcb->out_accm); + } + + /* Add FCS and trailing flag. */ + c = ~fcs_out & 0xFF; + tail = ppp_append(c, tail, &pcb->out_accm); + c = (~fcs_out >> 8) & 0xFF; + tail = ppp_append(c, tail, &pcb->out_accm); + tail = ppp_append(PPP_FLAG, tail, NULL); + + /* If we failed to complete the packet, throw it away. + * Otherwise send it. */ + if (!tail) { + PPPDEBUG(LOG_WARNING, + ("ppp_write[%d]: Alloc err - dropping pbuf len=%d\n", pcb->num, head->len)); + /*"ppp_write[%d]: Alloc err - dropping %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ + pbuf_free(head); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); + return PPPERR_ALLOC; + } + + PPPDEBUG(LOG_INFO, ("ppp_write[%d]: len=%d\n", pcb->num, head->len)); + /* "ppp_write[%d]: %d:%.*H", pd, head->len, LWIP_MIN(head->len * 2, 40), head->payload)); */ + pppos_put(pcb, head); + pbuf_free(p); + return PPPERR_NONE; +} +#endif /* PPPOS_SUPPORT */ + +#if PPPOE_SUPPORT +static int ppp_write_over_ethernet(ppp_pcb *pcb, struct pbuf *p) { + struct pbuf *ph; /* Ethernet + PPPoE header */ +#if LWIP_SNMP + u16_t tot_len; +#endif /* LWIP_SNMP */ + + /* skip address & flags */ + pbuf_header(p, -(s16_t)2); + + ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); + if(!ph) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); + return PPPERR_ALLOC; + } + + pbuf_header(ph, -(s16_t)PPPOE_HEADERLEN); /* hide PPPoE header */ + pbuf_cat(ph, p); +#if LWIP_SNMP + tot_len = ph->tot_len; +#endif /* LWIP_SNMP */ + + pcb->last_xmit = sys_jiffies(); + + if(pppoe_xmit(pcb->pppoe_sc, ph) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pcb->netif, (u16_t)tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT +static int ppp_write_over_l2tp(ppp_pcb *pcb, struct pbuf *p) { + struct pbuf *ph; /* UDP + L2TP header */ +#if LWIP_SNMP + u16_t tot_len; +#endif /* LWIP_SNMP */ + + ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM); + if(!ph) { + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.proterr); + snmp_inc_ifoutdiscards(&pcb->netif); + pbuf_free(p); + return PPPERR_ALLOC; + } + + pbuf_header(ph, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */ + pbuf_cat(ph, p); +#if LWIP_SNMP + tot_len = ph->tot_len; +#endif /* LWIP_SNMP */ + + pcb->last_xmit = sys_jiffies(); + + if(pppol2tp_xmit(pcb->l2tp_pcb, ph) != ERR_OK) { + LINK_STATS_INC(link.err); + snmp_inc_ifoutdiscards(&pcb->netif); + return PPPERR_DEVICE; + } + + snmp_add_ifoutoctets(&pcb->netif, (u16_t)tot_len); + snmp_inc_ifoutucastpkts(&pcb->netif); + LINK_STATS_INC(link.xmit); + return PPPERR_NONE; +} +#endif /* PPPOL2TP_SUPPORT */ + +#if PPPOS_SUPPORT +/* + * Drop the input packet. + */ +static void +ppp_free_current_input_packet(ppp_pcb_rx *pcrx) +{ + if (pcrx->in_head != NULL) { + if (pcrx->in_tail && (pcrx->in_tail != pcrx->in_head)) { + pbuf_free(pcrx->in_tail); + } + pbuf_free(pcrx->in_head); + pcrx->in_head = NULL; + } + pcrx->in_tail = NULL; +} + +/* + * Drop the input packet and increase error counters. + */ +static void +ppp_drop(ppp_pcb_rx *pcrx) +{ +#if LWIP_SNMP || VJ_SUPPORT + ppp_pcb *pcb = (ppp_pcb*)pcrx->pcb; +#endif /* LWIP_SNMP || VJ_SUPPORT */ + if (pcrx->in_head != NULL) { +#if 0 + PPPDEBUG(LOG_INFO, ("ppp_drop: %d:%.*H\n", pcrx->in_head->len, min(60, pcrx->in_head->len * 2), pcrx->in_head->payload)); +#endif + PPPDEBUG(LOG_INFO, ("ppp_drop: pbuf len=%d, addr %p\n", pcrx->in_head->len, (void*)pcrx->in_head)); + } + ppp_free_current_input_packet(pcrx); +#if VJ_SUPPORT + vj_uncompress_err(&pcb->vj_comp); +#endif /* VJ_SUPPORT */ + + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); +} + +/** PPPoS input helper struct, must be packed since it is stored + * to pbuf->payload, which might be unaligned. */ +#if PPP_INPROC_MULTITHREADED +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct pppos_input_header { + PACK_STRUCT_FIELD(ppp_pcb *pcb); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif +#endif /* PPP_INPROC_MULTITHREADED */ + +/** Pass received raw characters to PPPoS to be decoded. This function is + * thread-safe and can be called from a dedicated RX-thread or from a main-loop. + * + * @param pcb PPP descriptor index, returned by ppp_new() + * @param data received data + * @param len length of received data + */ +void +pppos_input(ppp_pcb *pcb, u_char *s, int l) +{ + ppp_pcb_rx *pcrx = &pcb->rx; + struct pbuf *next_pbuf; + u_char cur_char; + u_char escaped; + SYS_ARCH_DECL_PROTECT(lev); + + PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", pcb->num, l)); + while (l-- > 0) { + cur_char = *s++; + + SYS_ARCH_PROTECT(lev); + escaped = ESCAPE_P(pcrx->in_accm, cur_char); + SYS_ARCH_UNPROTECT(lev); + /* Handle special characters. */ + if (escaped) { + /* Check for escape sequences. */ + /* XXX Note that this does not handle an escaped 0x5d character which + * would appear as an escape character. Since this is an ASCII ']' + * and there is no reason that I know of to escape it, I won't complicate + * the code to handle this case. GLL */ + if (cur_char == PPP_ESCAPE) { + pcrx->in_escaped = 1; + /* Check for the flag character. */ + } else if (cur_char == PPP_FLAG) { + /* If this is just an extra flag character, ignore it. */ + if (pcrx->in_state <= PDADDRESS) { + /* ignore it */; + /* If we haven't received the packet header, drop what has come in. */ + } else if (pcrx->in_state < PDDATA) { + PPPDEBUG(LOG_WARNING, + ("pppos_input[%d]: Dropping incomplete packet %d\n", + pcb->num, pcrx->in_state)); + LINK_STATS_INC(link.lenerr); + ppp_drop(pcrx); + /* If the fcs is invalid, drop the packet. */ + } else if (pcrx->in_fcs != PPP_GOODFCS) { + PPPDEBUG(LOG_INFO, + ("pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", + pcb->num, pcrx->in_fcs, pcrx->in_protocol)); + /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ + LINK_STATS_INC(link.chkerr); + ppp_drop(pcrx); + /* Otherwise it's a good packet so pass it on. */ + } else { + struct pbuf *inp; + /* Trim off the checksum. */ + if(pcrx->in_tail->len > 2) { + pcrx->in_tail->len -= 2; + + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); + } + } else { + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); + } + + pbuf_realloc(pcrx->in_head, pcrx->in_head->tot_len - 2); + } + + /* Dispatch the packet thereby consuming it. */ + inp = pcrx->in_head; + /* Packet consumed, release our references. */ + pcrx->in_head = NULL; + pcrx->in_tail = NULL; +#if IP_FORWARD || LWIP_IPV6_FORWARD + /* hide the room for Ethernet forwarding header */ + pbuf_header(inp, -(s16_t)PBUF_LINK_HLEN); +#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ +#if PPP_INPROC_MULTITHREADED + if(tcpip_callback_with_block(pppos_input_callback, inp, 0) != ERR_OK) { + PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", pcb->num)); + pbuf_free(inp); + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); + } +#else /* PPP_INPROC_MULTITHREADED */ + ppp_input(pcb, inp); +#endif /* PPP_INPROC_MULTITHREADED */ + } + + /* Prepare for a new packet. */ + pcrx->in_fcs = PPP_INITFCS; + pcrx->in_state = PDADDRESS; + pcrx->in_escaped = 0; + /* Other characters are usually control characters that may have + * been inserted by the physical layer so here we just drop them. */ + } else { + PPPDEBUG(LOG_WARNING, + ("pppos_input[%d]: Dropping ACCM char <%d>\n", pcb->num, cur_char)); + } + /* Process other characters. */ + } else { + /* Unencode escaped characters. */ + if (pcrx->in_escaped) { + pcrx->in_escaped = 0; + cur_char ^= PPP_TRANS; + } + + /* Process character relative to current state. */ + switch(pcrx->in_state) { + case PDIDLE: /* Idle state - waiting. */ + /* Drop the character if it's not 0xff + * we would have processed a flag character above. */ + if (cur_char != PPP_ALLSTATIONS) { + break; + } + /* no break */ + /* Fall through */ + + case PDSTART: /* Process start flag. */ + /* Prepare for a new packet. */ + pcrx->in_fcs = PPP_INITFCS; + /* no break */ + /* Fall through */ + + case PDADDRESS: /* Process address field. */ + if (cur_char == PPP_ALLSTATIONS) { + pcrx->in_state = PDCONTROL; + break; + } + /* no break */ + + /* Else assume compressed address and control fields so + * fall through to get the protocol... */ + case PDCONTROL: /* Process control field. */ + /* If we don't get a valid control code, restart. */ + if (cur_char == PPP_UI) { + pcrx->in_state = PDPROTOCOL1; + break; + } + /* no break */ + +#if 0 + else { + PPPDEBUG(LOG_WARNING, + ("pppos_input[%d]: Invalid control <%d>\n", pcb->num, cur_char)); + pcrx->in_state = PDSTART; + } +#endif + case PDPROTOCOL1: /* Process protocol field 1. */ + /* If the lower bit is set, this is the end of the protocol + * field. */ + if (cur_char & 1) { + pcrx->in_protocol = cur_char; + pcrx->in_state = PDDATA; + } else { + pcrx->in_protocol = (u_int)cur_char << 8; + pcrx->in_state = PDPROTOCOL2; + } + break; + case PDPROTOCOL2: /* Process protocol field 2. */ + pcrx->in_protocol |= cur_char; + pcrx->in_state = PDDATA; + break; + case PDDATA: /* Process data byte. */ + /* Make space to receive processed data. */ + if (pcrx->in_tail == NULL || pcrx->in_tail->len == PBUF_POOL_BUFSIZE) { + u16_t pbuf_alloc_len; + if (pcrx->in_tail != NULL) { + pcrx->in_tail->tot_len = pcrx->in_tail->len; + if (pcrx->in_tail != pcrx->in_head) { + pbuf_cat(pcrx->in_head, pcrx->in_tail); + /* give up the in_tail reference now */ + pcrx->in_tail = NULL; + } + } + /* If we haven't started a packet, we need a packet header. */ + pbuf_alloc_len = 0; +#if IP_FORWARD || LWIP_IPV6_FORWARD + /* If IP forwarding is enabled we are reserving PBUF_LINK_HLEN bytes so + * the packet is being allocated with enough header space to be + * forwarded (to Ethernet for example). + */ + if (pcrx->in_head == NULL) { + pbuf_alloc_len = PBUF_LINK_HLEN; + } +#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ + next_pbuf = pbuf_alloc(PBUF_RAW, pbuf_alloc_len, PBUF_POOL); + if (next_pbuf == NULL) { + /* No free buffers. Drop the input packet and let the + * higher layers deal with it. Continue processing + * the received pbuf chain in case a new packet starts. */ + PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE PBUFS!\n", pcb->num)); + LINK_STATS_INC(link.memerr); + ppp_drop(pcrx); + pcrx->in_state = PDSTART; /* Wait for flag sequence. */ + break; + } + if (pcrx->in_head == NULL) { + u8_t *payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len; +#if PPP_INPROC_MULTITHREADED + ((struct pppos_input_header*)payload)->pcb = pcb; + payload += sizeof(struct pppos_input_header); + next_pbuf->len += sizeof(struct pppos_input_header); +#endif /* PPP_INPROC_MULTITHREADED */ + next_pbuf->len += sizeof(pcrx->in_protocol); + *(payload++) = pcrx->in_protocol >> 8; + *(payload) = pcrx->in_protocol & 0xFF; + pcrx->in_head = next_pbuf; + } + pcrx->in_tail = next_pbuf; + } + /* Load character into buffer. */ + ((u_char*)pcrx->in_tail->payload)[pcrx->in_tail->len++] = cur_char; + break; + default: + break; + } + + /* update the frame check sequence number. */ + pcrx->in_fcs = PPP_FCS(pcrx->in_fcs, cur_char); + } + } /* while (l-- > 0), all bytes processed */ + + magic_randomize(); +} + +#if PPP_INPROC_MULTITHREADED +/* PPPoS input callback using one input pointer + */ +static void pppos_input_callback(void *arg) { + struct pbuf *pb = (struct pbuf*)arg; + ppp_pcb *pcb; + + pcb = ((struct pppos_input_header*)pb->payload)->pcb; + if(pbuf_header(pb, -(s16_t)sizeof(struct pppos_input_header))) { + LWIP_ASSERT("pbuf_header failed\n", 0); + goto drop; + } + + /* Dispatch the packet thereby consuming it. */ + ppp_input(pcb, pb); + return; + +drop: + LINK_STATS_INC(link.drop); + snmp_inc_ifindiscards(&pcb->netif); + pbuf_free(pb); +} +#endif /* PPP_INPROC_MULTITHREADED */ +#endif /* PPPOS_SUPPORT */ + +/* merge a pbuf chain into one pbuf */ +struct pbuf * ppp_singlebuf(struct pbuf *p) { + struct pbuf *q, *b; + u_char *pl; + + if(p->tot_len == p->len) { + return p; + } + + q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); + if(!q) { + PPPDEBUG(LOG_ERR, + ("ppp_singlebuf: unable to alloc new buf (%d)\n", p->tot_len)); + return p; /* live dangerously */ + } + + for(b = p, pl = (u_char*)q->payload; b != NULL; b = b->next) { + MEMCPY(pl, b->payload, b->len); + pl += b->len; + } + + pbuf_free(p); + + return q; +} + +#if PPPOE_SUPPORT +static void ppp_over_ethernet_link_status_cb(ppp_pcb *pcb, int state) { + int pppoe_err_code = PPPERR_NONE; + + switch(state) { + + /* PPPoE link is established, starting PPP negotiation */ + case PPPOE_CB_STATE_UP: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: UP, connecting\n", pcb->num)); + ppp_start(pcb); + return; + + /* PPPoE link normally down (i.e. asked to do so) */ + case PPPOE_CB_STATE_DOWN: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); + pppoe_err_code = PPPERR_CONNECT; + break; + + /* PPPoE link failed to setup (i.e. PADI/PADO timeout) */ + case PPPOE_CB_STATE_FAILED: + PPPDEBUG(LOG_INFO, ("ppp_over_ethernet_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); + pppoe_err_code = PPPERR_OPEN; + new_phase(pcb, PPP_PHASE_DEAD); + break; + + default: + break; + } + + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppoe_err_code, pcb->ctx_cb); +} + +static void ppp_over_ethernet_open(ppp_pcb *pcb) { + + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + ppp_clear(pcb); + + wo->mru = pcb->pppoe_sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = pcb->pppoe_sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + + pppoe_connect(pcb->pppoe_sc); +} +#endif /* PPPOE_SUPPORT */ + +#if PPPOL2TP_SUPPORT +static void ppp_over_l2tp_link_status_cb(ppp_pcb *pcb, int state) { + int pppol2tp_err_code = PPPERR_NONE; + + switch(state) { + + /* PPPoL2TP link is established, starting PPP negotiation */ + case PPPOL2TP_CB_STATE_UP: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: UP, connecting\n", pcb->num)); + ppp_start(pcb); + return; + + /* PPPoL2TP link normally down (i.e. asked to do so) */ + case PPPOL2TP_CB_STATE_DOWN: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: DOWN, disconnected\n", pcb->num)); + pppol2tp_err_code = PPPERR_CONNECT; + break; + + /* PPPoL2TP link failed to setup (i.e. L2TP timeout) */ + case PPPOL2TP_CB_STATE_FAILED: + PPPDEBUG(LOG_INFO, ("ppp_over_l2tp_link_status_cb: unit %d: FAILED, aborting\n", pcb->num)); + pppol2tp_err_code = PPPERR_OPEN; + new_phase(pcb, PPP_PHASE_DEAD); + break; + + default: + break; + } + + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : pppol2tp_err_code, pcb->ctx_cb); +} + +static void ppp_over_l2tp_open(ppp_pcb *pcb) { + + lcp_options *wo = &pcb->lcp_wantoptions; + lcp_options *ao = &pcb->lcp_allowoptions; + + ppp_clear(pcb); + + wo->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + wo->neg_asyncmap = 0; + wo->neg_pcompression = 0; + wo->neg_accompression = 0; + + ao->mru = 1500; /* FIXME: MTU depends if we support IP fragmentation or not */ + ao->neg_asyncmap = 0; + ao->neg_pcompression = 0; + ao->neg_accompression = 0; + + pppol2tp_connect(pcb->l2tp_pcb); +} +#endif /* PPPOL2TP_SUPPORT */ + +void ppp_link_down(ppp_pcb *pcb) { + LWIP_UNUSED_ARG(pcb); /* necessary if PPPDEBUG is defined to an empty function */ + PPPDEBUG(LOG_DEBUG, ("ppp_link_down: unit %d\n", pcb->num)); +} + +void ppp_link_terminated(ppp_pcb *pcb) { + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d\n", pcb->num)); + +#if PPPOE_SUPPORT + if (pcb->pppoe_sc) { + pppoe_disconnect(pcb->pppoe_sc); + } else +#endif /* PPPOE_SUPPORT */ +#if PPPOL2TP_SUPPORT + if (pcb->l2tp_pcb) { + pppol2tp_disconnect(pcb->l2tp_pcb); + } else +#endif /* PPPOL2TP_SUPPORT */ + { +#if PPPOS_SUPPORT + /* We cannot call ppp_free_current_input_packet() here because + * rx thread might still call pppos_input() + */ + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); + pcb->link_status_cb(pcb, pcb->err_code ? pcb->err_code : PPPERR_PROTOCOL, pcb->ctx_cb); +#endif /* PPPOS_SUPPORT */ + } + PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated: finished.\n")); +} + +#if LWIP_NETIF_STATUS_CALLBACK +/** Set the status callback of a PPP's netif + * + * @param pcb The PPP descriptor returned by ppp_new() + * @param status_callback pointer to the status callback function + * + * @see netif_set_status_callback + */ +void +ppp_set_netif_statuscallback(ppp_pcb *pcb, netif_status_callback_fn status_callback) +{ + netif_set_status_callback(&pcb->netif, status_callback); +} +#endif /* LWIP_NETIF_STATUS_CALLBACK */ + +#if LWIP_NETIF_LINK_CALLBACK +/** Set the link callback of a PPP's netif + * + * @param pcb The PPP descriptor returned by ppp_new() + * @param link_callback pointer to the link callback function + * + * @see netif_set_link_callback + */ +void +ppp_set_netif_linkcallback(ppp_pcb *pcb, netif_status_callback_fn link_callback) +{ + netif_set_link_callback(&pcb->netif, link_callback); +} +#endif /* LWIP_NETIF_LINK_CALLBACK */ + +/************************************************************************ + * Functions called by various PPP subsystems to configure + * the PPP interface or change the PPP phase. + */ + +/* + * new_phase - signal the start of a new phase of pppd's operation. + */ +void new_phase(ppp_pcb *pcb, int p) { + pcb->phase = p; + PPPDEBUG(LOG_DEBUG, ("ppp phase changed: unit %d: phase=%d\n", pcb->num, pcb->phase)); +#if PPP_NOTIFY_PHASE + if(NULL != pcb->notify_phase_cb) { + pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); + } +#endif /* PPP_NOTIFY_PHASE */ +} + +/* + * ppp_send_config - configure the transmit-side characteristics of + * the ppp interface. + */ +int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { +#if PPPOS_SUPPORT + int i; +#endif /* PPPOS_SUPPORT */ + LWIP_UNUSED_ARG(mtu); + + /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ + pcb->pcomp = pcomp; + pcb->accomp = accomp; + +#if PPPOS_SUPPORT + /* Load the ACCM bits for the 32 control codes. */ + for (i = 0; i < 32/8; i++) { + pcb->out_accm[i] = (u_char)((accm >> (8 * i)) & 0xFF); + } +#else + LWIP_UNUSED_ARG(accm); +#endif /* PPPOS_SUPPORT */ + +#if PPPOS_SUPPORT + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]: out_accm=%X %X %X %X\n", + pcb->num, + pcb->out_accm[0], pcb->out_accm[1], pcb->out_accm[2], pcb->out_accm[3])); +#else + PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->num) ); +#endif /* PPPOS_SUPPORT */ + return 0; +} + +/* + * ppp_recv_config - configure the receive-side characteristics of + * the ppp interface. + */ +int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { +#if PPPOS_SUPPORT + int i; + SYS_ARCH_DECL_PROTECT(lev); +#endif /* PPPOS_SUPPORT */ + + LWIP_UNUSED_ARG(accomp); + LWIP_UNUSED_ARG(pcomp); + LWIP_UNUSED_ARG(mru); + + /* Load the ACCM bits for the 32 control codes. */ +#if PPPOS_SUPPORT + SYS_ARCH_PROTECT(lev); + for (i = 0; i < 32 / 8; i++) { + /* @todo: does this work? ext_accm has been modified from pppd! */ + pcb->rx.in_accm[i] = (u_char)(accm >> (i * 8)); + } + SYS_ARCH_UNPROTECT(lev); +#else + LWIP_UNUSED_ARG(accm); +#endif /* PPPOS_SUPPORT */ + +#if PPPOS_SUPPORT + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]: in_accm=%X %X %X %X\n", + pcb->num, + pcb->rx.in_accm[0], pcb->rx.in_accm[1], pcb->rx.in_accm[2], pcb->rx.in_accm[3])); +#else + PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->num) ); +#endif /* PPPOS_SUPPORT */ + return 0; +} + + +/* + * sifaddr - Config the interface IP addresses and netmask. + */ +int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, + u32_t net_mask) { + + SMEMCPY(&pcb->addrs.our_ipaddr, &our_adr, sizeof(our_adr)); + SMEMCPY(&pcb->addrs.his_ipaddr, &his_adr, sizeof(his_adr)); + SMEMCPY(&pcb->addrs.netmask, &net_mask, sizeof(net_mask)); + return 1; +} + + +/******************************************************************** + * + * cifaddr - Clear the interface IP addresses, and delete routes + * through the interface if possible. + */ +int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { + + LWIP_UNUSED_ARG(our_adr); + LWIP_UNUSED_ARG(his_adr); + + IP4_ADDR(&pcb->addrs.our_ipaddr, 0,0,0,0); + IP4_ADDR(&pcb->addrs.his_ipaddr, 0,0,0,0); + IP4_ADDR(&pcb->addrs.netmask, 255,255,255,255); + return 1; +} + + +#if PPP_IPV6_SUPPORT +#define IN6_LLADDR_FROM_EUI64(ip6, eui64) do { \ + memset(&ip6.addr, 0, sizeof(ip6_addr_t)); \ + ip6.addr[0] = PP_HTONL(0xfe800000); \ + eui64_copy(eui64, ip6.addr[2]); \ + } while (0) + +/******************************************************************** + * + * sif6addr - Config the interface with an IPv6 link-local address + */ +int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { + + IN6_LLADDR_FROM_EUI64(pcb->addrs.our6_ipaddr, our_eui64); + IN6_LLADDR_FROM_EUI64(pcb->addrs.his6_ipaddr, his_eui64); + return 1; +} + +/******************************************************************** + * + * cif6addr - Remove IPv6 address from interface + */ +int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { + + LWIP_UNUSED_ARG(our_eui64); + LWIP_UNUSED_ARG(his_eui64); + + IP6_ADDR(&pcb->addrs.our6_ipaddr, 0, 0,0,0,0); + IP6_ADDR(&pcb->addrs.his6_ipaddr, 0, 0,0,0,0); + return 1; +} +#endif /* PPP_IPV6_SUPPORT */ + + +/* + * sdns - Config the DNS servers + */ +int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { + + SMEMCPY(&pcb->addrs.dns1, &ns1, sizeof(ns1)); + SMEMCPY(&pcb->addrs.dns2, &ns2, sizeof(ns2)); + return 1; +} + + +/******************************************************************** + * + * cdns - Clear the DNS servers + */ +int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { + + LWIP_UNUSED_ARG(ns1); + LWIP_UNUSED_ARG(ns2); + + IP4_ADDR(&pcb->addrs.dns1, 0,0,0,0); + IP4_ADDR(&pcb->addrs.dns2, 0,0,0,0); + return 1; +} + + +/* + * sifup - Config the interface up and enable IP packets to pass. + */ +int sifup(ppp_pcb *pcb) { + + netif_set_addr(&pcb->netif, &pcb->addrs.our_ipaddr, &pcb->addrs.netmask, + &pcb->addrs.his_ipaddr); + + netif_set_up(&pcb->netif); + pcb->if_up = 1; + pcb->err_code = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sifup: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); + return 1; +} + +/******************************************************************** + * + * sifdown - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ +int sifdown(ppp_pcb *pcb) { + + if(!pcb->if_up) + return 1; + + pcb->if_up = 0; + + if (1 +#if PPP_IPV6_SUPPORT + /* set the interface down if IPv6 is down as well */ + && !pcb->if6_up +#endif /* PPP_IPV6_SUPPORT */ + ) { + /* make sure the netif status callback is called */ + netif_set_down(&pcb->netif); + } + PPPDEBUG(LOG_DEBUG, ("sifdown: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); + return 1; +} + +#if PPP_IPV6_SUPPORT +/* + * sif6up - Config the interface up and enable IPv6 packets to pass. + */ +int sif6up(ppp_pcb *pcb) { + + ip6_addr_copy(pcb->netif.ip6_addr[0], pcb->addrs.our6_ipaddr); + netif_ip6_addr_set_state(&pcb->netif, 0, IP6_ADDR_PREFERRED); + + netif_set_up(&pcb->netif); + pcb->if6_up = 1; + pcb->err_code = PPPERR_NONE; + + PPPDEBUG(LOG_DEBUG, ("sif6up: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); + pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); + return 1; +} + +/******************************************************************** + * + * sif6down - Disable the indicated protocol and config the interface + * down if there are no remaining protocols. + */ +int sif6down(ppp_pcb *pcb) { + + if(!pcb->if6_up) + return 1; + + pcb->if6_up = 0; + /* set the interface down if IPv4 is down as well */ + if (!pcb->if_up) { + /* make sure the netif status callback is called */ + netif_set_down(&pcb->netif); + } + PPPDEBUG(LOG_DEBUG, ("sif6down: unit %d: err_code=%d\n", pcb->num, pcb->err_code)); + return 1; +} +#endif /* PPP_IPV6_SUPPORT */ + +/* + * sifnpmode - Set the mode for handling packets for a given NP. + */ +int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(proto); + LWIP_UNUSED_ARG(mode); + return 0; +} + +/* + * netif_set_mtu - set the MTU on the PPP network interface. + */ +void netif_set_mtu(ppp_pcb *pcb, int mtu) { + + pcb->netif.mtu = mtu; +} + +/* + * netif_get_mtu - get PPP interface MTU + */ +int netif_get_mtu(ppp_pcb *pcb) { + + return pcb->netif.mtu; +} + +/******************************************************************** + * + * sifproxyarp - Make a proxy ARP entry for the peer. + */ + +int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(his_adr); + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * cifproxyarp - Delete the proxy ARP entry for the peer. + */ + +int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(his_adr); + /* FIXME: do we really need that in IPCP ? */ + return 0; +} + +/******************************************************************** + * + * sifvjcomp - config tcp header compression + */ +int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { + +#if PPPOS_SUPPORT && VJ_SUPPORT + pcb->vj_enabled = vjcomp; + pcb->vj_comp.compressSlot = cidcomp; + pcb->vj_comp.maxSlotIndex = maxcid; + PPPDEBUG(LOG_INFO, ("sifvjcomp: VJ compress enable=%d slot=%d max slot=%d\n", + vjcomp, cidcomp, maxcid)); +#else /* PPPOS_SUPPORT && VJ_SUPPORT */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(vjcomp); + LWIP_UNUSED_ARG(cidcomp); + LWIP_UNUSED_ARG(maxcid); +#endif /* PPPOS_SUPPORT && VJ_SUPPORT */ + + return 0; +} + +#if PPP_IDLETIMELIMIT +/******************************************************************** + * + * get_idle_time - return how long the link has been idle. + */ +int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { + /* FIXME: add idle time support and make it optional */ + LWIP_UNUSED_ARG(pcb); + LWIP_UNUSED_ARG(ip); + return 1; +} +#endif /* PPP_IDLETIMELIMIT */ + +/******************************************************************** + * + * get_loop_output - get outgoing packets from the ppp device, + * and detect when we want to bring the real link up. + * Return value is 1 if we need to bring up the link, 0 otherwise. + */ +int get_loop_output(void) { + /* FIXME: necessary for "demand", do we really need to support on-demand ? */ + return 0; +} + +/******************************************************************** + * + * Return user specified netmask, modified by any mask we might determine + * for address `addr' (in network byte order). + * Here we scan through the system's list of interfaces, looking for + * any non-point-to-point interfaces which might appear to be on the same + * network as `addr'. If we find any, we OR in their netmask to the + * user-specified netmask. + */ +u32_t get_mask(u32_t addr) { +#if 0 + u32_t mask, nmask; + + addr = htonl(addr); + if (IP_CLASSA(addr)) { /* determine network mask for address class */ + nmask = IP_CLASSA_NET; + } else if (IP_CLASSB(addr)) { + nmask = IP_CLASSB_NET; + } else { + nmask = IP_CLASSC_NET; + } + + /* class D nets are disallowed by bad_ip_adrs */ + mask = PP_HTONL(0xffffff00UL) | htonl(nmask); + + /* XXX + * Scan through the system's network interfaces. + * Get each netmask and OR them into our mask. + */ + /* return mask; */ + return mask; +#endif + LWIP_UNUSED_ARG(addr); + return 0xFFFFFFFF; +} + + +#if PPP_PROTOCOLNAME +/* List of protocol names, to make our messages a little more informative. */ +struct protocol_list { + u_short proto; + const char *name; +} protocol_list[] = { + { 0x21, "IP" }, + { 0x23, "OSI Network Layer" }, + { 0x25, "Xerox NS IDP" }, + { 0x27, "DECnet Phase IV" }, + { 0x29, "Appletalk" }, + { 0x2b, "Novell IPX" }, + { 0x2d, "VJ compressed TCP/IP" }, + { 0x2f, "VJ uncompressed TCP/IP" }, + { 0x31, "Bridging PDU" }, + { 0x33, "Stream Protocol ST-II" }, + { 0x35, "Banyan Vines" }, + { 0x39, "AppleTalk EDDP" }, + { 0x3b, "AppleTalk SmartBuffered" }, + { 0x3d, "Multi-Link" }, + { 0x3f, "NETBIOS Framing" }, + { 0x41, "Cisco Systems" }, + { 0x43, "Ascom Timeplex" }, + { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, + { 0x47, "DCA Remote Lan" }, + { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, + { 0x4b, "SNA over 802.2" }, + { 0x4d, "SNA" }, + { 0x4f, "IP6 Header Compression" }, + { 0x51, "KNX Bridging Data" }, + { 0x53, "Encryption" }, + { 0x55, "Individual Link Encryption" }, + { 0x57, "IPv6" }, + { 0x59, "PPP Muxing" }, + { 0x5b, "Vendor-Specific Network Protocol" }, + { 0x61, "RTP IPHC Full Header" }, + { 0x63, "RTP IPHC Compressed TCP" }, + { 0x65, "RTP IPHC Compressed non-TCP" }, + { 0x67, "RTP IPHC Compressed UDP 8" }, + { 0x69, "RTP IPHC Compressed RTP 8" }, + { 0x6f, "Stampede Bridging" }, + { 0x73, "MP+" }, + { 0xc1, "NTCITS IPI" }, + { 0xfb, "single-link compression" }, + { 0xfd, "Compressed Datagram" }, + { 0x0201, "802.1d Hello Packets" }, + { 0x0203, "IBM Source Routing BPDU" }, + { 0x0205, "DEC LANBridge100 Spanning Tree" }, + { 0x0207, "Cisco Discovery Protocol" }, + { 0x0209, "Netcs Twin Routing" }, + { 0x020b, "STP - Scheduled Transfer Protocol" }, + { 0x020d, "EDP - Extreme Discovery Protocol" }, + { 0x0211, "Optical Supervisory Channel Protocol" }, + { 0x0213, "Optical Supervisory Channel Protocol" }, + { 0x0231, "Luxcom" }, + { 0x0233, "Sigma Network Systems" }, + { 0x0235, "Apple Client Server Protocol" }, + { 0x0281, "MPLS Unicast" }, + { 0x0283, "MPLS Multicast" }, + { 0x0285, "IEEE p1284.4 standard - data packets" }, + { 0x0287, "ETSI TETRA Network Protocol Type 1" }, + { 0x0289, "Multichannel Flow Treatment Protocol" }, + { 0x2063, "RTP IPHC Compressed TCP No Delta" }, + { 0x2065, "RTP IPHC Context State" }, + { 0x2067, "RTP IPHC Compressed UDP 16" }, + { 0x2069, "RTP IPHC Compressed RTP 16" }, + { 0x4001, "Cray Communications Control Protocol" }, + { 0x4003, "CDPD Mobile Network Registration Protocol" }, + { 0x4005, "Expand accelerator protocol" }, + { 0x4007, "ODSICP NCP" }, + { 0x4009, "DOCSIS DLL" }, + { 0x400B, "Cetacean Network Detection Protocol" }, + { 0x4021, "Stacker LZS" }, + { 0x4023, "RefTek Protocol" }, + { 0x4025, "Fibre Channel" }, + { 0x4027, "EMIT Protocols" }, + { 0x405b, "Vendor-Specific Protocol (VSP)" }, + { 0x8021, "Internet Protocol Control Protocol" }, + { 0x8023, "OSI Network Layer Control Protocol" }, + { 0x8025, "Xerox NS IDP Control Protocol" }, + { 0x8027, "DECnet Phase IV Control Protocol" }, + { 0x8029, "Appletalk Control Protocol" }, + { 0x802b, "Novell IPX Control Protocol" }, + { 0x8031, "Bridging NCP" }, + { 0x8033, "Stream Protocol Control Protocol" }, + { 0x8035, "Banyan Vines Control Protocol" }, + { 0x803d, "Multi-Link Control Protocol" }, + { 0x803f, "NETBIOS Framing Control Protocol" }, + { 0x8041, "Cisco Systems Control Protocol" }, + { 0x8043, "Ascom Timeplex" }, + { 0x8045, "Fujitsu LBLB Control Protocol" }, + { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, + { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, + { 0x804b, "SNA over 802.2 Control Protocol" }, + { 0x804d, "SNA Control Protocol" }, + { 0x804f, "IP6 Header Compression Control Protocol" }, + { 0x8051, "KNX Bridging Control Protocol" }, + { 0x8053, "Encryption Control Protocol" }, + { 0x8055, "Individual Link Encryption Control Protocol" }, + { 0x8057, "IPv6 Control Protocol" }, + { 0x8059, "PPP Muxing Control Protocol" }, + { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, + { 0x806f, "Stampede Bridging Control Protocol" }, + { 0x8073, "MP+ Control Protocol" }, + { 0x80c1, "NTCITS IPI Control Protocol" }, + { 0x80fb, "Single Link Compression Control Protocol" }, + { 0x80fd, "Compression Control Protocol" }, + { 0x8207, "Cisco Discovery Protocol Control" }, + { 0x8209, "Netcs Twin Routing" }, + { 0x820b, "STP - Control Protocol" }, + { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, + { 0x8235, "Apple Client Server Protocol Control" }, + { 0x8281, "MPLSCP" }, + { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, + { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, + { 0x8289, "Multichannel Flow Treatment Protocol" }, + { 0xc021, "Link Control Protocol" }, + { 0xc023, "Password Authentication Protocol" }, + { 0xc025, "Link Quality Report" }, + { 0xc027, "Shiva Password Authentication Protocol" }, + { 0xc029, "CallBack Control Protocol (CBCP)" }, + { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, + { 0xc02d, "BAP" }, + { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, + { 0xc081, "Container Control Protocol" }, + { 0xc223, "Challenge Handshake Authentication Protocol" }, + { 0xc225, "RSA Authentication Protocol" }, + { 0xc227, "Extensible Authentication Protocol" }, + { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, + { 0xc26f, "Stampede Bridging Authorization Protocol" }, + { 0xc281, "Proprietary Authentication Protocol" }, + { 0xc283, "Proprietary Authentication Protocol" }, + { 0xc481, "Proprietary Node ID Authentication Protocol" }, + { 0, NULL }, +}; + +/* + * protocol_name - find a name for a PPP protocol. + */ +const char * protocol_name(int proto) { + struct protocol_list *lp; + + for (lp = protocol_list; lp->proto != 0; ++lp) + if (proto == lp->proto) + return lp->name; + return NULL; +} +#endif /* PPP_PROTOCOLNAME */ + +#if PPP_STATS_SUPPORT + +/* ---- Note on PPP Stats support ---- + * + * The one willing link stats support should add the get_ppp_stats() + * to fetch statistics from lwIP. + */ + +/* + * reset_link_stats - "reset" stats when link goes up. + */ +void reset_link_stats(int u) { + if (!get_ppp_stats(u, &old_link_stats)) + return; + gettimeofday(&start_time, NULL); +} + +/* + * update_link_stats - get stats at link termination. + */ +void update_link_stats(int u) { + + struct timeval now; + char numbuf[32]; + + if (!get_ppp_stats(u, &link_stats) + || gettimeofday(&now, NULL) < 0) + return; + link_connect_time = now.tv_sec - start_time.tv_sec; + link_stats_valid = 1; + + link_stats.bytes_in -= old_link_stats.bytes_in; + link_stats.bytes_out -= old_link_stats.bytes_out; + link_stats.pkts_in -= old_link_stats.pkts_in; + link_stats.pkts_out -= old_link_stats.pkts_out; +} + +void print_link_stats() { + /* + * Print connect time and statistics. + */ + if (link_stats_valid) { + int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ + info("Connect time %d.%d minutes.", t/10, t%10); + info("Sent %u bytes, received %u bytes.", + link_stats.bytes_out, link_stats.bytes_in); + link_stats_valid = 0; + } +} +#endif /* PPP_STATS_SUPPORT */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppcrypt.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppcrypt.c new file mode 100644 index 0000000..097f702 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppcrypt.c @@ -0,0 +1,66 @@ +/* + * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 + * + * Extracted from chap_ms.c by James Carlson. + * + * Copyright (c) 1995 Eric Rosenquist. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/pppcrypt.h" + + +static u_char pppcrypt_get_7bits(u_char *input, int startBit) { + unsigned int word; + + word = (unsigned)input[startBit / 8] << 8; + word |= (unsigned)input[startBit / 8 + 1]; + + word >>= 15 - (startBit % 8 + 7); + + return word & 0xFE; +} + +/* IN 56 bit DES key missing parity bits + * OUT 64 bit DES key with parity bits added + */ +void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { + des_key[0] = pppcrypt_get_7bits(key, 0); + des_key[1] = pppcrypt_get_7bits(key, 7); + des_key[2] = pppcrypt_get_7bits(key, 14); + des_key[3] = pppcrypt_get_7bits(key, 21); + des_key[4] = pppcrypt_get_7bits(key, 28); + des_key[5] = pppcrypt_get_7bits(key, 35); + des_key[6] = pppcrypt_get_7bits(key, 42); + des_key[7] = pppcrypt_get_7bits(key, 49); +} + +#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppoe.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppoe.c new file mode 100644 index 0000000..2aa819c --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppoe.c @@ -0,0 +1,1113 @@ +/***************************************************************************** +* pppoe.c - PPP Over Ethernet implementation for lwIP. +* +* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. +* +* The authors hereby grant permission to use, copy, modify, distribute, +* and license this software and its documentation for any purpose, provided +* that existing copyright notices are retained in all copies and that this +* notice and the following disclaimer are included verbatim in any +* distributions. No written agreement, license, or royalty fee is required +* for any of the authorized uses. +* +* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +****************************************************************************** +* REVISION HISTORY +* +* 06-01-01 Marc Boucher +* Ported to lwIP. +*****************************************************************************/ + + + +/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#endif /* UNUSED */ + +#include "lwip/timers.h" +#include "lwip/memp.h" +#include "lwip/stats.h" + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppoe.h" + +/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ +#define PPPOE_ADD_16(PTR, VAL) \ + *(PTR)++ = (u8_t)((VAL) / 256); \ + *(PTR)++ = (u8_t)((VAL) % 256) + +/* Add a complete PPPoE header to the buffer pointed to by PTR */ +#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ + *(PTR)++ = PPPOE_VERTYPE; \ + *(PTR)++ = (CODE); \ + PPPOE_ADD_16(PTR, SESS); \ + PPPOE_ADD_16(PTR, LEN) + +#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ +#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ +#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ +#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ + +#ifdef PPPOE_SERVER +#error "PPPOE_SERVER is not yet supported under lwIP!" +/* from if_spppsubr.c */ +#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ +#endif + +/* FIXME: we should probably remove that, this is only used for debug purposes */ +#ifndef PPPOE_ERRORSTRING_LEN +#define PPPOE_ERRORSTRING_LEN 64 +#endif +static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN]; + + +/* management routines */ +static void pppoe_abort_connect(struct pppoe_softc *); +static void pppoe_clear_softc(struct pppoe_softc *, const char *); + +/* internal timeout handling */ +static void pppoe_timeout(void *); + +/* sending actual protocol controll packets */ +static err_t pppoe_send_padi(struct pppoe_softc *); +static err_t pppoe_send_padr(struct pppoe_softc *); +#ifdef PPPOE_SERVER +static err_t pppoe_send_pado(struct pppoe_softc *); +static err_t pppoe_send_pads(struct pppoe_softc *); +#endif +static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); + +/* internal helper functions */ +static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif); +static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif); + +/** linked list of created pppoe interfaces */ +static struct pppoe_softc *pppoe_softc_list; + +err_t +pppoe_create(struct netif *ethif, ppp_pcb *pcb, void (*link_status_cb)(ppp_pcb *pcb, int up), struct pppoe_softc **scptr) +{ + struct pppoe_softc *sc; + + sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF); + if (sc == NULL) { + *scptr = NULL; + return ERR_MEM; + } + memset(sc, 0, sizeof(struct pppoe_softc)); + + /* changed to real address later */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + + sc->pcb = pcb; + sc->sc_link_status_cb = link_status_cb; + sc->sc_ethif = ethif; + + /* put the new interface at the head of the list */ + sc->next = pppoe_softc_list; + pppoe_softc_list = sc; + + *scptr = sc; + + return ERR_OK; +} + +err_t +pppoe_destroy(struct pppoe_softc *sc) +{ + struct pppoe_softc *cur, *prev = NULL; + + /* find previous linked list entry */ + for (cur = pppoe_softc_list; cur != NULL; prev = cur, cur = cur->next) { + if (sc == cur) { + break; + } + } + + if (cur != sc) { + return ERR_IF; + } + + sys_untimeout(pppoe_timeout, sc); + if (prev == NULL) { + /* remove sc from the head of the list */ + pppoe_softc_list = sc->next; + } else { + /* remove sc from the list */ + prev->next = sc->next; + } + +#ifdef PPPOE_TODO + if (sc->sc_concentrator_name) { + mem_free(sc->sc_concentrator_name); + } + if (sc->sc_service_name) { + mem_free(sc->sc_service_name); + } +#endif /* PPPOE_TODO */ + memp_free(MEMP_PPPOE_IF, sc); + + return ERR_OK; +} + +/* + * Find the interface handling the specified session. + * Note: O(number of sessions open), this is a client-side only, mean + * and lean implementation, so number of open sessions typically should + * be 1. + */ +static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) { + struct pppoe_softc *sc; + + if (session == 0) { + return NULL; + } + + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { + if (sc->sc_state == PPPOE_STATE_SESSION + && sc->sc_session == session + && sc->sc_ethif == rcvif) { + return sc; + } + } + return NULL; +} + +/* Check host unique token passed and return appropriate softc pointer, + * or NULL if token is bogus. */ +static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) { + struct pppoe_softc *sc, *t; + + if (pppoe_softc_list == NULL) { + return NULL; + } + + if (len != sizeof sc) { + return NULL; + } + MEMCPY(&t, token, len); + + for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { + if (sc == t) { + break; + } + } + + if (sc == NULL) { + PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); + return NULL; + } + + /* should be safe to access *sc now */ + if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state)); + return NULL; + } + if (sc->sc_ethif != rcvif) { + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + return NULL; + } + return sc; +} + +static void +pppoe_linkstatus_up(struct pppoe_softc *sc) +{ + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_UP); +} + +/* analyze and handle a single received packet while not in session state */ +void +pppoe_disc_input(struct netif *netif, struct pbuf *pb) +{ + u16_t tag, len; + u16_t session, plen; + struct pppoe_softc *sc; + const char *err_msg; + char devname[6]; + u8_t *ac_cookie; + u16_t ac_cookie_len; +#ifdef PPPOE_SERVER + u8_t *hunique; + size_t hunique_len; +#endif + struct pppoehdr *ph; + struct pppoetag pt; + int off, err; + struct eth_hdr *ethhdr; + + /* don't do anything if there is not a single PPPoE instance */ + if (pppoe_softc_list == NULL) { + pbuf_free(pb); + return; + } + + pb = ppp_singlebuf(pb); + + strcpy(devname, "pppoe"); /* as long as we don't know which instance */ + err_msg = NULL; + if (pb->len < sizeof(*ethhdr)) { + goto done; + } + ethhdr = (struct eth_hdr *)pb->payload; + off = sizeof(*ethhdr); + + ac_cookie = NULL; + ac_cookie_len = 0; +#ifdef PPPOE_SERVER + hunique = NULL; + hunique_len = 0; +#endif + session = 0; + if (pb->len - off < (u16_t)PPPOE_HEADERLEN) { + PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len)); + goto done; + } + + ph = (struct pppoehdr *) (ethhdr + 1); + if (ph->vertype != PPPOE_VERTYPE) { + PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype)); + goto done; + } + session = ntohs(ph->session); + plen = ntohs(ph->plen); + off += sizeof(*ph); + + if (plen + off > pb->len) { + PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n", + pb->len - off, plen)); + goto done; + } + if(pb->tot_len == pb->len) { + pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */ + } + tag = 0; + len = 0; + sc = NULL; + while (off + sizeof(pt) <= pb->len) { + MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); + tag = ntohs(pt.tag); + len = ntohs(pt.len); + if (off + sizeof(pt) + len > pb->len) { + PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len)); + goto done; + } + switch (tag) { + case PPPOE_TAG_EOL: + goto breakbreak; + case PPPOE_TAG_SNAME: + break; /* ignored */ + case PPPOE_TAG_ACNAME: + break; /* ignored */ + case PPPOE_TAG_HUNIQUE: + if (sc != NULL) { + break; + } +#ifdef PPPOE_SERVER + hunique = (u8_t*)pb->payload + off + sizeof(pt); + hunique_len = len; +#endif + sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); + if (sc != NULL) { + devname[0] = sc->sc_ethif->name[0]; + devname[1] = sc->sc_ethif->name[1]; + devname[2] = sc->sc_ethif->num; + devname[3] = '\0'; + } + break; + case PPPOE_TAG_ACCOOKIE: + if (ac_cookie == NULL) { + ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); + ac_cookie_len = len; + } + break; + case PPPOE_TAG_SNAME_ERR: + err_msg = "SERVICE NAME ERROR"; + break; + case PPPOE_TAG_ACSYS_ERR: + err_msg = "AC SYSTEM ERROR"; + break; + case PPPOE_TAG_GENERIC_ERR: + err_msg = "GENERIC ERROR"; + break; + default: + break; + } + if (NULL != err_msg) { + if (len) { + u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1); + strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); + pppoe_error_tmp[error_len] = '\0'; + PPPDEBUG(LOG_DEBUG, ("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp)); + } else { + PPPDEBUG(LOG_DEBUG, ("%s: %s\n", devname, err_msg)); + } + } + off += sizeof(pt) + len; + } + +breakbreak:; + switch (ph->code) { + case PPPOE_CODE_PADI: +#ifdef PPPOE_SERVER + /* + * got service name, concentrator name, and/or host unique. + * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. + */ + if (LIST_EMPTY(&pppoe_softc_list)) { + goto done; + } + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { + continue; + } + if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + continue; + } + if (sc->sc_state == PPPOE_STATE_INITIAL) { + break; + } + } + if (sc == NULL) { + /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */ + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); + sc->sc_state = PPPOE_STATE_PADO_SENT; + pppoe_send_pado(sc); + break; +#endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADR: +#ifdef PPPOE_SERVER + /* + * get sc from ac_cookie if IFF_PASSIVE + */ + if (ac_cookie == NULL) { + /* be quiet if there is not a single pppoe instance */ + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n")); + goto done; + } + sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (!LIST_EMPTY(&pppoe_softc_list)) { + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n")); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + goto done; + } + if (hunique) { + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + } + sc->sc_hunique = mem_malloc(hunique_len); + if (sc->sc_hunique == NULL) { + goto done; + } + sc->sc_hunique_len = hunique_len; + MEMCPY(sc->sc_hunique, hunique, hunique_len); + } + pppoe_send_pads(sc); + sc->sc_state = PPPOE_STATE_SESSION; + pppoe_linkstatus_up(sc); /* notify upper layers */ + break; +#else + /* ignore, we are no access concentrator */ + goto done; +#endif /* PPPOE_SERVER */ + case PPPOE_CODE_PADO: + if (sc == NULL) { + /* be quiet if there is not a single pppoe instance */ + if (pppoe_softc_list != NULL) { + PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n")); + } + goto done; + } + if (sc->sc_state != PPPOE_STATE_PADI_SENT) { + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + goto done; + } + if (ac_cookie) { + sc->sc_ac_cookie_len = ac_cookie_len; + MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); + } + MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); + sys_untimeout(pppoe_timeout, sc); + sc->sc_padr_retried = 0; + sc->sc_state = PPPOE_STATE_PADR_SENT; + if ((err = pppoe_send_padr(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + case PPPOE_CODE_PADS: + if (sc == NULL) { + goto done; + } + sc->sc_session = session; + sys_untimeout(pppoe_timeout, sc); + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); + sc->sc_state = PPPOE_STATE_SESSION; + pppoe_linkstatus_up(sc); /* notify upper layers */ + break; + case PPPOE_CODE_PADT: + if (sc == NULL) { + goto done; + } + pppoe_clear_softc(sc, "received PADT"); + break; + default: + if(sc) { + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + (u16_t)ph->code, session)); + } else { + PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session)); + } + break; + } + +done: + pbuf_free(pb); + return; +} + +void +pppoe_data_input(struct netif *netif, struct pbuf *pb) +{ + u16_t session, plen; + struct pppoe_softc *sc; + struct pppoehdr *ph; +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + u8_t shost[ETHER_ADDR_LEN]; +#endif + +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); +#endif + if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + pb = ppp_singlebuf (pb); + + if (pb->len <= PPPOE_HEADERLEN) { + PPPDEBUG(LOG_DEBUG, ("pppoe (data): dropping too short packet: %d bytes\n", pb->len)); + goto drop; + } + + if (pb->len < sizeof(*ph)) { + PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n")); + goto drop; + } + ph = (struct pppoehdr *)pb->payload; + + if (ph->vertype != PPPOE_VERTYPE) { + PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype)); + goto drop; + } + if (ph->code != 0) { + goto drop; + } + + session = ntohs(ph->session); + sc = pppoe_find_softc_by_session(session, netif); + if (sc == NULL) { +#ifdef PPPOE_TERM_UNKNOWN_SESSIONS + PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session)); + pppoe_send_padt(netif, session, shost); +#endif + goto drop; + } + + plen = ntohs(ph->plen); + + if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n")); + LINK_STATS_INC(link.lenerr); + goto drop; + } + + PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, + pb->len, plen)); + + if (pb->len < plen) { + goto drop; + } + + /* Dispatch the packet thereby consuming it. */ + ppp_input(sc->pcb, pb); + return; + +drop: + pbuf_free(pb); +} + +static err_t +pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) +{ + struct eth_hdr *ethhdr; + u16_t etype; + err_t res; + + if (!sc->sc_ethif) { + pbuf_free(pb); + return ERR_IF; + } + + /* make room for Ethernet header - should not fail */ + if (pbuf_header(pb, (u16_t)(sizeof(struct eth_hdr))) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + ethhdr = (struct eth_hdr *)pb->payload; + etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; + ethhdr->type = htons(etype); + MEMCPY(ðhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); + MEMCPY(ðhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr)); + + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, + sc->sc_state, sc->sc_session, + sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], + pb->tot_len)); + + res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); + + pbuf_free(pb); + + return res; +} + +static err_t +pppoe_send_padi(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + int len; +#ifdef PPPOE_TODO + int l1 = 0, l2 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ + + if (sc->sc_state >PPPOE_STATE_PADI_SENT) { + PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state)); + } + + /* calculate length of frame (excluding ethernet header + pppoe header) */ + len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + l1 = (int)strlen(sc->sc_service_name); + len += l1; + } + if (sc->sc_concentrator_name != NULL) { + l2 = (int)strlen(sc->sc_concentrator_name); + len += 2 + 2 + l2; + } +#endif /* PPPOE_TODO */ + LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", + sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else +#endif /* PPPOE_TODO */ + { + PPPOE_ADD_16(p, 0); + } +#ifdef PPPOE_TODO + if (sc->sc_concentrator_name != NULL) { + PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); + PPPOE_ADD_16(p, l2); + MEMCPY(p, sc->sc_concentrator_name, l2); + p += l2; + } +#endif /* PPPOE_TODO */ + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + /* send pkt */ + return pppoe_output(sc, pb); +} + +static void +pppoe_timeout(void *arg) +{ + u32_t retry_wait; + int err; + struct pppoe_softc *sc = (struct pppoe_softc*)arg; + + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + + switch (sc->sc_state) { + case PPPOE_STATE_PADI_SENT: + /* + * We have two basic ways of retrying: + * - Quick retry mode: try a few times in short sequence + * - Slow retry mode: we already had a connection successfully + * established and will try infinitely (without user + * intervention) + * We only enter slow retry mode if IFF_LINK1 (aka autodial) + * is not set. + */ + if (sc->sc_padi_retried < 0xff) { + sc->sc_padi_retried++; + } + if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { +#if 0 + if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { + /* slow retry mode */ + retry_wait = PPPOE_SLOW_RETRY; + } else +#endif + { + pppoe_abort_connect(sc); + return; + } + } + /* initialize for quick retry mode */ + retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY); + if ((err = pppoe_send_padi(sc)) != 0) { + sc->sc_padi_retried--; + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(retry_wait, pppoe_timeout, sc); + break; + + case PPPOE_STATE_PADR_SENT: + sc->sc_padr_retried++; + if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_state = PPPOE_STATE_PADI_SENT; + sc->sc_padr_retried = 0; + if ((err = pppoe_send_padi(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); + return; + } + if ((err = pppoe_send_padr(sc)) != 0) { + sc->sc_padr_retried--; + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); + break; + default: + return; /* all done, work in peace */ + } +} + +/* Start a connection (i.e. initiate discovery phase) */ +int +pppoe_connect(struct pppoe_softc *sc) +{ + int err; + + if (sc->sc_state != PPPOE_STATE_INITIAL) { + return EBUSY; + } + + /* stop any timer */ + sys_untimeout(pppoe_timeout, sc); + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; +#ifdef PPPOE_SERVER + /* wait PADI if IFF_PASSIVE */ + if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { + return 0; + } +#endif + /* save state, in case we fail to send PADI */ + sc->sc_state = PPPOE_STATE_PADI_SENT; + if ((err = pppoe_send_padi(sc)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); + } + sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); + return err; +} + +/* disconnect */ +void +pppoe_disconnect(struct pppoe_softc *sc) +{ + if (sc->sc_state < PPPOE_STATE_SESSION) { + return; + } + + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); + + /* cleanup softc */ + sc->sc_state = PPPOE_STATE_INITIAL; + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; +#ifdef PPPOE_SERVER + if (sc->sc_hunique) { + mem_free(sc->sc_hunique); + sc->sc_hunique = NULL; + } + sc->sc_hunique_len = 0; +#endif + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; + + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_DOWN); /* notify upper layers */ + return; +} + +/* Connection attempt aborted */ +static void +pppoe_abort_connect(struct pppoe_softc *sc) +{ + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + + /* clear connection state */ + sc->sc_state = PPPOE_STATE_INITIAL; + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; + + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_FAILED); /* notify upper layers */ +} + +/* Send a PADR packet */ +static err_t +pppoe_send_padr(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len; +#ifdef PPPOE_TODO + size_t l1 = 0; /* XXX: gcc */ +#endif /* PPPOE_TODO */ + + if (sc->sc_state != PPPOE_STATE_PADR_SENT) { + return ERR_CONN; + } + + len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } +#endif /* PPPOE_TODO */ + if (sc->sc_ac_cookie_len > 0) { + len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ + } + LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", + sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload; + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); +#ifdef PPPOE_TODO + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else +#endif /* PPPOE_TODO */ + { + PPPOE_ADD_16(p, 0); + } + if (sc->sc_ac_cookie_len > 0) { + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sc->sc_ac_cookie_len); + MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); + p += sc->sc_ac_cookie_len; + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof sc); + + return pppoe_output(sc, pb); +} + +/* send a PADT packet */ +static err_t +pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) +{ + struct pbuf *pb; + struct eth_hdr *ethhdr; + err_t res; + u8_t *p; + + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + pbuf_header(pb, sizeof(struct eth_hdr)); + ethhdr = (struct eth_hdr *)pb->payload; + ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); + MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); + MEMCPY(ðhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr)); + + p = (u8_t*)(ethhdr + 1); + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); + + res = outgoing_if->linkoutput(outgoing_if, pb); + + pbuf_free(pb); + + return res; +} + +#ifdef PPPOE_SERVER +static err_t +pppoe_send_pado(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len; + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + /* calc length */ + len = 0; + /* include ac_cookie */ + len += 2 + 2 + sizeof(sc); + /* include hunique */ + len += 2 + 2 + sc->sc_hunique_len; + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload; + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); + PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); + PPPOE_ADD_16(p, sizeof(sc)); + MEMCPY(p, &sc, sizeof(sc)); + p += sizeof(sc); + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} + +static err_t +pppoe_send_pads(struct pppoe_softc *sc) +{ + struct pbuf *pb; + u8_t *p; + size_t len, l1 = 0; /* XXX: gcc */ + + if (sc->sc_state != PPPOE_STATE_PADO_SENT) { + return ERR_CONN; + } + + sc->sc_session = mono_time.tv_sec % 0xff + 1; + /* calc length */ + len = 0; + /* include hunique */ + len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ + if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ + l1 = strlen(sc->sc_service_name); + len += l1; + } + pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); + if (!pb) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + p = (u8_t*)pb->payload; + PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); + PPPOE_ADD_16(p, PPPOE_TAG_SNAME); + if (sc->sc_service_name != NULL) { + PPPOE_ADD_16(p, l1); + MEMCPY(p, sc->sc_service_name, l1); + p += l1; + } else { + PPPOE_ADD_16(p, 0); + } + PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); + PPPOE_ADD_16(p, sc->sc_hunique_len); + MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); + return pppoe_output(sc, pb); +} +#endif + +err_t +pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) +{ + u8_t *p; + size_t len; + + /* are we ready to process data yet? */ + if (sc->sc_state < PPPOE_STATE_SESSION) { + /*sppp_flush(&sc->sc_sppp.pp_if);*/ + pbuf_free(pb); + return ERR_CONN; + } + + len = pb->tot_len; + + /* make room for PPPoE header - should not fail */ + if (pbuf_header(pb, (u16_t)(PPPOE_HEADERLEN)) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + + p = (u8_t*)pb->payload; + PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); + + return pppoe_output(sc, pb); +} + +#if 0 /*def PFIL_HOOKS*/ +static int +pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) +{ + struct pppoe_softc *sc; + int s; + + if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { + return 0; + } + + LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { + if (sc->sc_ethif != ifp) { + continue; + } + if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { + sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); + PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n", + sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); + } + sc->sc_ethif = NULL; + pppoe_clear_softc(sc, "ethernet interface detached"); + } + + return 0; +} +#endif + +static void +pppoe_clear_softc(struct pppoe_softc *sc, const char *message) +{ + LWIP_UNUSED_ARG(message); + + /* stop timer */ + sys_untimeout(pppoe_timeout, sc); + PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); + /* fix our state */ + sc->sc_state = PPPOE_STATE_INITIAL; + + /* notify upper layers */ + sc->sc_link_status_cb(sc->pcb, PPPOE_CB_STATE_DOWN); + + /* clean up softc */ + MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); + sc->sc_ac_cookie_len = 0; + sc->sc_session = 0; + sc->sc_padi_retried = 0; + sc->sc_padr_retried = 0; +} +#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppol2tp.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppol2tp.c new file mode 100644 index 0000000..b526410 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/pppol2tp.c @@ -0,0 +1,1016 @@ +/** + * @file + * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file. + * + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ + +/* + * L2TP Support status: + * + * Supported: + * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) + * - LAC + * + * Not supported: + * - LNS (require PPP server support) + * - L2TPv3 ethernet pseudowires + * - L2TPv3 VLAN pseudowire + * - L2TPv3 PPP pseudowires + * - L2TPv3 IP encapsulation + * - L2TPv3 IP pseudowire + * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08 + * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel + * - Hidden AVPs + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "lwip/err.h" +#include "lwip/memp.h" +#include "lwip/netif.h" +#include "lwip/udp.h" + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppol2tp.h" + +#include "netif/ppp/magic.h" + +#if PPPOL2TP_AUTH_SUPPORT +#if LWIP_INCLUDED_POLARSSL_MD5 +#include "netif/ppp/polarssl/md5.h" +#else +#include "polarssl/md5.h" +#endif +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* Prototypes for procedures local to this file. */ +static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port); +static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, + struct pbuf *p, u16_t len, u16_t tunnel_id, u16_t session_id, u16_t ns, u16_t nr); +static void pppol2tp_timeout(void *arg); +static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp); +static void pppol2tp_clear(pppol2tp_pcb *l2tp); +static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp); +static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns); +static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns); + + +/* Create a new L2TP session. */ +err_t pppol2tp_create(ppp_pcb *ppp, void (*link_status_cb)(ppp_pcb *pcb, int status), pppol2tp_pcb **l2tpptr, + struct netif *netif, ip_addr_t *ipaddr, u16_t port, + u8_t *secret, u8_t secret_len) { + pppol2tp_pcb *l2tp; + struct udp_pcb *udp; + + l2tp = (pppol2tp_pcb *)memp_malloc(MEMP_PPPOL2TP_PCB); + if (l2tp == NULL) { + *l2tpptr = NULL; + return ERR_MEM; + } + + udp = udp_new(); + if (udp == NULL) { + memp_free(MEMP_PPPOL2TP_PCB, l2tp); + *l2tpptr = NULL; + return ERR_MEM; + } + udp_recv(udp, pppol2tp_input, l2tp); + + memset(l2tp, 0, sizeof(pppol2tp_pcb)); + l2tp->phase = PPPOL2TP_STATE_INITIAL; + l2tp->ppp = ppp; + l2tp->udp = udp; + l2tp->link_status_cb = link_status_cb; + l2tp->netif = netif; + ip_addr_set(&l2tp->remote_ip, ipaddr); + l2tp->remote_port = port; + #if PPPOL2TP_AUTH_SUPPORT + l2tp->secret = secret; + l2tp->secret_len = secret_len; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + *l2tpptr = l2tp; + return ERR_OK; +} + +/* Destroy a L2TP control block */ +err_t pppol2tp_destroy(pppol2tp_pcb *l2tp) { + + sys_untimeout(pppol2tp_timeout, l2tp); + if (l2tp->udp != NULL) { + udp_remove(l2tp->udp); + } + memp_free(MEMP_PPPOL2TP_PCB, l2tp); + return ERR_OK; +} + +/* Be a LAC, connect to a LNS. */ +err_t pppol2tp_connect(pppol2tp_pcb *l2tp) { + err_t err; + + if (l2tp->phase != PPPOL2TP_STATE_INITIAL) { + return ERR_VAL; + } + + pppol2tp_clear(l2tp); + + /* Listen to a random source port, we need to do that instead of using udp_connect() + * because the L2TP LNS might answer with its own random source port (!= 1701) + */ + udp_bind(l2tp->udp, IP_ADDR_ANY, 0); + +#if PPPOL2TP_AUTH_SUPPORT + /* Generate random vector */ + if (l2tp->secret != NULL) { + random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv)); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + do { + l2tp->remote_tunnel_id = magic(); + } while(l2tp->remote_tunnel_id == 0); + /* save state, in case we fail to send SCCRQ */ + l2tp->sccrq_retried = 0; + l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; + if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + return err; +} + +/* Disconnect */ +void pppol2tp_disconnect(pppol2tp_pcb *l2tp) { + + if (l2tp->phase < PPPOL2TP_STATE_DATA) { + return; + } + + l2tp->our_ns++; + pppol2tp_send_stopccn(l2tp, l2tp->our_ns); + + pppol2tp_clear(l2tp); + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_DOWN); /* notify upper layers */ +} + +/* UDP Callback for incoming L2TP frames */ +static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { + pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; + u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0; + u8_t *inp; + LWIP_UNUSED_ARG(pcb); + + if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) { + goto free_and_return; + } + + /* printf("-----------\nL2TP INPUT, %d\n", p->len); */ + p = ppp_singlebuf(p); + + /* L2TP header */ + if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) { + goto packet_too_short; + } + + inp = (u8_t*)p->payload; + GETSHORT(hflags, inp); + + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { + /* check mandatory flags for a control packet */ + if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n")); + goto free_and_return; + } + /* check forbidden flags for a control packet */ + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n")); + goto free_and_return; + } + } else { + /* check mandatory flags for a data packet */ + if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n")); + goto free_and_return; + } + } + + /* Expected header size */ + hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id); + if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { + hlen += sizeof(len); + } + if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { + hlen += sizeof(ns) + sizeof(nr); + } + if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { + hlen += sizeof(offset); + } + if (p->len < hlen) { + goto packet_too_short; + } + + if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { + GETSHORT(len, inp); + if (p->len < len || len < hlen) { + goto packet_too_short; + } + } + GETSHORT(tunnel_id, inp); + GETSHORT(session_id, inp); + if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { + GETSHORT(ns, inp); + GETSHORT(nr, inp); + } + if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { + GETSHORT(offset, inp) + if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */ + PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset)); + goto free_and_return; + } + hlen += offset; + if (p->len < hlen) { + goto packet_too_short; + } + INCPTR(offset, inp); + } + + /* printf("HLEN = %d\n", hlen); */ + + /* skip L2TP header */ + if (pbuf_header(p, -hlen) != 0) { + goto free_and_return; + } + + /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */ + PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n", + len, tunnel_id, session_id, ns, nr)); + + /* Control packet */ + if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { + pppol2tp_dispatch_control_packet(l2tp, addr, port, p, len, tunnel_id, session_id, ns, nr); + goto free_and_return; + } + + /* Data packet */ + if(l2tp->phase != PPPOL2TP_STATE_DATA) { + goto free_and_return; + } + if(tunnel_id != l2tp->remote_tunnel_id) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id)); + goto free_and_return; + } + if(session_id != l2tp->remote_session_id) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id)); + goto free_and_return; + } + /* + * skip address & flags if necessary + * + * RFC 2661 does not specify whether the PPP frame in the L2TP payload should + * have a HDLC header or not. We handle both cases for compatibility. + */ + GETSHORT(hflags, inp); + if (hflags == 0xff03) { + pbuf_header(p, -(s16_t)2); + } + /* Dispatch the packet thereby consuming it. */ + ppp_input(l2tp->ppp, p); + return; + +packet_too_short: + PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); +free_and_return: + pbuf_free(p); +} + +/* L2TP Control packet entry point */ +static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, struct ip_addr *addr, u16_t port, + struct pbuf *p, u16_t len, u16_t tunnel_id, u16_t session_id, u16_t ns, u16_t nr) { + u8_t *inp; + u16_t avplen, avpflags, vendorid, attributetype, messagetype=0; + err_t err; +#if PPPOL2TP_AUTH_SUPPORT + md5_context md5_ctx; + u8_t md5_hash[16]; + u8_t challenge_id = 0; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(tunnel_id); + LWIP_UNUSED_ARG(session_id); + + l2tp->peer_nr = nr; + l2tp->peer_ns = ns; + /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */ + + /* Handle the special case of the ICCN acknowledge */ + if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && l2tp->peer_nr > l2tp->our_ns) { + l2tp->phase = PPPOL2TP_STATE_DATA; + } + + /* ZLB packets */ + if (p->len == 0) { + return; + } + + inp = (u8_t*)p->payload; + /* Decode AVPs */ + while (p->len > 0) { + if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) { + goto packet_too_short; + } + GETSHORT(avpflags, inp); + avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK; + /* printf("AVPLEN = %d\n", avplen); */ + if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) { + goto packet_too_short; + } + GETSHORT(vendorid, inp); + GETSHORT(attributetype, inp); + avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype); + + /* Message type must be the first AVP */ + if (messagetype == 0) { + if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n")); + return; + } + GETSHORT(messagetype, inp); + /* printf("Message type = %d\n", messagetype); */ + switch(messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + /* Only accept SCCRP packet if we sent a SCCRQ */ + if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) { + goto send_zlb; + } + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + /* Only accept ICRP packet if we sent a IRCQ */ + if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) { + goto send_zlb; + } + break; + /* Stop Control Connection Notification */ + case PPPOL2TP_MESSAGETYPE_STOPCCN: + pppol2tp_send_zlb(l2tp, l2tp->our_ns); /* Ack the StopCCN before we switch to down state */ + if (l2tp->phase < PPPOL2TP_STATE_DATA) { + pppol2tp_abort_connect(l2tp); + } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { + /* Don't disconnect here, we let the LCP Echo/Reply find the fact + * that PPP session is down. Asking the PPP stack to end the session + * require strict checking about the PPP phase to prevent endless + * disconnection loops. + */ + } + return; + default: + break; + } + goto nextavp; + } + + /* Skip proprietary L2TP extensions */ + if (vendorid != 0) { + goto skipavp; + } + + switch (messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + switch (attributetype) { + case PPPOL2TP_AVPTYPE_TUNNELID: + if (avplen != sizeof(l2tp->source_tunnel_id) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n")); + return; + } + GETSHORT(l2tp->source_tunnel_id, inp); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id)); + goto nextavp; +#if PPPOL2TP_AUTH_SUPPORT + case PPPOL2TP_AVPTYPE_CHALLENGE: + if (avplen == 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n")); + return; + } + if (l2tp->secret == NULL) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n")); + pppol2tp_abort_connect(l2tp); + return; + } + /* Generate hash of ID, secret, challenge */ + md5_starts(&md5_ctx); + challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN; + md5_update(&md5_ctx, &challenge_id, 1); + md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); + md5_update(&md5_ctx, inp, avplen); + md5_finish(&md5_ctx, l2tp->challenge_hash); + l2tp->send_challenge = 1; + goto skipavp; + case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE: + if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n")); + return; + } + /* Generate hash of ID, secret, challenge */ + md5_starts(&md5_ctx); + challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP; + md5_update(&md5_ctx, &challenge_id, 1); + md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); + md5_update(&md5_ctx, l2tp->secret_rv, sizeof(l2tp->secret_rv)); + md5_finish(&md5_ctx, md5_hash); + if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n")); + pppol2tp_abort_connect(l2tp); + return; + } + goto skipavp; +#endif /* PPPOL2TP_AUTH_SUPPORT */ + default: + break; + } + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + switch (attributetype) { + case PPPOL2TP_AVPTYPE_SESSIONID: + if (avplen != sizeof(l2tp->source_session_id) ) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n")); + return; + } + GETSHORT(l2tp->source_session_id, inp); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id)); + goto nextavp; + default: + break; + } + break; + default: + break; + } + +skipavp: + INCPTR(avplen, inp); +nextavp: + /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */ + /* next AVP */ + if (pbuf_header(p, -avplen - sizeof(avpflags) - sizeof(vendorid) - sizeof(attributetype) ) != 0) { + return; + } + } + + switch(messagetype) { + /* Start Control Connection Reply */ + case PPPOL2TP_MESSAGETYPE_SCCRP: + do { + l2tp->remote_session_id = magic(); + } while(l2tp->remote_session_id == 0); + l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */ + l2tp->icrq_retried = 0; + l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT; + l2tp->our_ns++; + if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); + } + l2tp->our_ns++; + if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); + } + sys_untimeout(pppol2tp_timeout, l2tp); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + /* Incoming Call Reply */ + case PPPOL2TP_MESSAGETYPE_ICRP: + l2tp->iccn_retried = 0; + l2tp->phase = PPPOL2TP_STATE_ICCN_SENT; + l2tp->our_ns++; + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_UP); /* notify upper layers */ + if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); + } + sys_untimeout(pppol2tp_timeout, l2tp); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + /* Unhandled packet, send ZLB ACK */ + default: + goto send_zlb; + } + return; + +send_zlb: + pppol2tp_send_zlb(l2tp, l2tp->our_ns); + return; +packet_too_short: + PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); +} + +/* L2TP Timeout handler */ +static void pppol2tp_timeout(void *arg) { + pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; + err_t err; + u32_t retry_wait; + + PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n")); + + switch (l2tp->phase) { + case PPPOL2TP_STATE_SCCRQ_SENT: + /* backoff wait */ + if (l2tp->sccrq_retried < 0xff) { + l2tp->sccrq_retried++; + } + if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) { + pppol2tp_abort_connect(l2tp); + return; + } + retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY); + PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried)); + if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { + l2tp->sccrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); + } + sys_timeout(retry_wait, pppol2tp_timeout, l2tp); + break; + + case PPPOL2TP_STATE_ICRQ_SENT: + l2tp->icrq_retried++; + if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) { + pppol2tp_abort_connect(l2tp); + return; + } + PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried)); + if (l2tp->peer_nr <= l2tp->our_ns -1) { /* the SCCCN was not acknowledged */ + if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) { + l2tp->icrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + } + } + if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { + l2tp->icrq_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + + case PPPOL2TP_STATE_ICCN_SENT: + l2tp->iccn_retried++; + if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) { + pppol2tp_abort_connect(l2tp); + return; + } + PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried)); + if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { + l2tp->iccn_retried--; + PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); + } + sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); + break; + + default: + return; /* all done, work in peace */ + } +} + +/* Connection attempt aborted */ +static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) { + PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n")); + pppol2tp_clear(l2tp); + l2tp->link_status_cb(l2tp->ppp, PPPOL2TP_CB_STATE_FAILED); /* notify upper layers */ +} + +/* Reset L2TP control block to its initial state */ +static void pppol2tp_clear(pppol2tp_pcb *l2tp) { + /* stop any timer */ + sys_untimeout(pppol2tp_timeout, l2tp); + l2tp->phase = PPPOL2TP_STATE_INITIAL; + l2tp->tunnel_port = l2tp->remote_port; + l2tp->our_ns = 0; + l2tp->peer_nr = 0; + l2tp->peer_ns = 0; + l2tp->source_tunnel_id = 0; + l2tp->remote_tunnel_id = 0; + l2tp->source_session_id = 0; + l2tp->remote_session_id = 0; + /* l2tp->*_retried are cleared when used */ +} + +/* Initiate a new tunnel */ +static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8; +#if PPPOL2TP_AUTH_SUPPORT + if (l2tp->secret != NULL) { + len += 6 + sizeof(l2tp->secret_rv); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(0, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(0, p); /* NS Sequence number - to peer */ + PUTSHORT(0, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */ + + /* AVP - L2TP Version */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */ + PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */ + + /* AVP - Framing capabilities */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */ + PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */ + + /* AVP - Bearer capabilities */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */ + PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */ + + /* AVP - Host name */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */ + MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */ + INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p); + + /* AVP - Vendor name */ + PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */ + MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */ + INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p); + + /* AVP - Assign tunnel ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ + PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ + + /* AVP - Receive window size */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */ + PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */ + +#if PPPOL2TP_AUTH_SUPPORT + /* AVP - Challenge */ + if (l2tp->secret != NULL) { + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */ + MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */ + INCPTR(sizeof(l2tp->secret_rv), p); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +/* Complete tunnel establishment */ +static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8; +#if PPPOL2TP_AUTH_SUPPORT + if (l2tp->send_challenge) { + len += 6 + sizeof(l2tp->challenge_hash); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */ + +#if PPPOL2TP_AUTH_SUPPORT + /* AVP - Challenge response */ + if (l2tp->send_challenge) { + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */ + MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */ + INCPTR(sizeof(l2tp->challenge_hash), p); + } +#endif /* PPPOL2TP_AUTH_SUPPORT */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +/* Initiate a new session */ +static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + u32_t serialnumber; + + /* calculate UDP packet length */ + len = 12 +8 +8 +10; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */ + + /* AVP - Assign session ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */ + PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */ + + /* AVP - Call Serial Number */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */ + serialnumber = magic(); + PUTLONG(serialnumber, p); /* Attribute value: Serial number */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +/* Complete tunnel establishment */ +static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +10 +10; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(l2tp->source_session_id, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */ + + /* AVP - Framing type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */ + PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */ + + /* AVP - TX Connect speed */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ + PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +/* Send a ZLB ACK packet */ +static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +/* Send a StopCCN packet */ +static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { + struct pbuf *pb; + u8_t *p; + u16_t len; + + /* calculate UDP packet length */ + len = 12 +8 +8 +8; + + /* allocate a buffer */ + pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (pb == NULL) { + return ERR_MEM; + } + LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); + + p = (u8_t*)pb->payload; + /* fill in pkt */ + /* L2TP control header */ + PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); + PUTSHORT(len, p); /* Length */ + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(0, p); /* Session Id */ + PUTSHORT(ns, p); /* NS Sequence number - to peer */ + PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ + + /* AVP - Message type */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ + PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */ + + /* AVP - Assign tunnel ID */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ + PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ + + /* AVP - Result code */ + PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ + PUTSHORT(0, p); /* Vendor ID */ + PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ + PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { + u8_t *p; + + /* are we ready to process data yet? */ + if (l2tp->phase < PPPOL2TP_STATE_DATA) { + pbuf_free(pb); + return ERR_CONN; + } + + /* make room for L2TP header - should not fail */ + if (pbuf_header(pb, PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) { + /* bail out */ + PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n")); + LINK_STATS_INC(link.lenerr); + pbuf_free(pb); + return ERR_BUF; + } + + p = (u8_t*)pb->payload; + PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p); + PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ + PUTSHORT(l2tp->source_session_id, p); /* Session Id */ + + if(l2tp->netif) { + udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port, l2tp->netif); + } else { + udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->remote_port); + } + pbuf_free(pb); + return ERR_OK; +} + +#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/upap.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/upap.c new file mode 100644 index 0000000..14f80b6 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/upap.c @@ -0,0 +1,682 @@ +/* + * upap.c - User/Password Authentication Protocol. + * + * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +/* + * TODO: + */ + +#if 0 /* UNUSED */ +#include +#include +#endif /* UNUSED */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/upap.h" + +#if PPP_OPTIONS +/* + * Command-line options. + */ +static option_t pap_option_list[] = { + { "hide-password", o_bool, &hide_password, + "Don't output passwords to log", OPT_PRIO | 1 }, + { "show-password", o_bool, &hide_password, + "Show password string in debug log messages", OPT_PRIOSUB | 0 }, + + { "pap-restart", o_int, &upap[0].us_timeouttime, + "Set retransmit timeout for PAP", OPT_PRIO }, + { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, + "Set max number of transmissions for auth-reqs", OPT_PRIO }, + { "pap-timeout", o_int, &upap[0].us_reqtimeout, + "Set time limit for peer PAP authentication", OPT_PRIO }, + + { NULL } +}; +#endif /* PPP_OPTIONS */ + +/* + * Protocol entry points. + */ +static void upap_init(ppp_pcb *pcb); +static void upap_lowerup(ppp_pcb *pcb); +static void upap_lowerdown(ppp_pcb *pcb); +static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l); +static void upap_protrej(ppp_pcb *pcb); +#if PRINTPKT_SUPPORT +static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg); +#endif /* PRINTPKT_SUPPORT */ + +const struct protent pap_protent = { + PPP_PAP, + upap_init, + upap_input, + upap_protrej, + upap_lowerup, + upap_lowerdown, + NULL, + NULL, +#if PRINTPKT_SUPPORT + upap_printpkt, +#endif /* PRINTPKT_SUPPORT */ + NULL, + 1, +#if PRINTPKT_SUPPORT + "PAP", + NULL, +#endif /* PRINTPKT_SUPPORT */ +#if PPP_OPTIONS + pap_option_list, + NULL, +#endif /* PPP_OPTIONS */ +#if DEMAND_SUPPORT + NULL, + NULL +#endif /* DEMAND_SUPPORT */ +}; + +static void upap_timeout(void *arg); +#if PPP_SERVER +static void upap_reqtimeout(void *arg); +static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); +#endif /* PPP_SERVER */ +static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); +static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); +static void upap_sauthreq(ppp_pcb *pcb); +#if PPP_SERVER +static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen); +#endif /* PPP_SERVER */ + + +/* + * upap_init - Initialize a UPAP unit. + */ +static void upap_init(ppp_pcb *pcb) { + pcb->upap.us_user = NULL; + pcb->upap.us_userlen = 0; + pcb->upap.us_passwd = NULL; + pcb->upap.us_passwdlen = 0; + pcb->upap.us_clientstate = UPAPCS_INITIAL; +#if PPP_SERVER + pcb->upap.us_serverstate = UPAPSS_INITIAL; +#endif /* PPP_SERVER */ + pcb->upap.us_id = 0; +} + + +/* + * upap_authwithpeer - Authenticate us with our peer (start client). + * + * Set new state and send authenticate's. + */ +void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password) { + + if(!user || !password) + return; + + /* Save the username and password we're given */ + pcb->upap.us_user = user; + pcb->upap.us_userlen = LWIP_MIN(strlen(user), 0xff); + pcb->upap.us_passwd = password; + pcb->upap.us_passwdlen = LWIP_MIN(strlen(password), 0xff); + pcb->upap.us_transmits = 0; + + /* Lower layer up yet? */ + if (pcb->upap.us_clientstate == UPAPCS_INITIAL || + pcb->upap.us_clientstate == UPAPCS_PENDING) { + pcb->upap.us_clientstate = UPAPCS_PENDING; + return; + } + + upap_sauthreq(pcb); /* Start protocol */ +} + +#if PPP_SERVER +/* + * upap_authpeer - Authenticate our peer (start server). + * + * Set new state. + */ +void upap_authpeer(ppp_pcb *pcb) { + + /* Lower layer up yet? */ + if (pcb->upap.us_serverstate == UPAPSS_INITIAL || + pcb->upap.us_serverstate == UPAPSS_PENDING) { + pcb->upap.us_serverstate = UPAPSS_PENDING; + return; + } + + pcb->upap.us_serverstate = UPAPSS_LISTEN; + if (pcb->settings.pap_req_timeout > 0) + TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); +} +#endif /* PPP_SERVER */ + +/* + * upap_timeout - Retransmission timer for sending auth-reqs expired. + */ +static void upap_timeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) + return; + + if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) { + /* give up in disgust */ + ppp_error("No response to PAP authenticate-requests"); + pcb->upap.us_clientstate = UPAPCS_BADAUTH; + auth_withpeer_fail(pcb, PPP_PAP); + return; + } + + upap_sauthreq(pcb); /* Send Authenticate-Request */ +} + + +#if PPP_SERVER +/* + * upap_reqtimeout - Give up waiting for the peer to send an auth-req. + */ +static void upap_reqtimeout(void *arg) { + ppp_pcb *pcb = (ppp_pcb*)arg; + + if (pcb->upap.us_serverstate != UPAPSS_LISTEN) + return; /* huh?? */ + + auth_peer_fail(pcb, PPP_PAP); + pcb->upap.us_serverstate = UPAPSS_BADAUTH; +} +#endif /* PPP_SERVER */ + + +/* + * upap_lowerup - The lower layer is up. + * + * Start authenticating if pending. + */ +static void upap_lowerup(ppp_pcb *pcb) { + + if (pcb->upap.us_clientstate == UPAPCS_INITIAL) + pcb->upap.us_clientstate = UPAPCS_CLOSED; + else if (pcb->upap.us_clientstate == UPAPCS_PENDING) { + upap_sauthreq(pcb); /* send an auth-request */ + } + +#if PPP_SERVER + if (pcb->upap.us_serverstate == UPAPSS_INITIAL) + pcb->upap.us_serverstate = UPAPSS_CLOSED; + else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { + pcb->upap.us_serverstate = UPAPSS_LISTEN; + if (pcb->settings.pap_req_timeout > 0) + TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); + } +#endif /* PPP_SERVER */ +} + + +/* + * upap_lowerdown - The lower layer is down. + * + * Cancel all timeouts. + */ +static void upap_lowerdown(ppp_pcb *pcb) { + + if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ + UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ +#if PPP_SERVER + if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0) + UNTIMEOUT(upap_reqtimeout, pcb); +#endif /* PPP_SERVER */ + + pcb->upap.us_clientstate = UPAPCS_INITIAL; +#if PPP_SERVER + pcb->upap.us_serverstate = UPAPSS_INITIAL; +#endif /* PPP_SERVER */ +} + + +/* + * upap_protrej - Peer doesn't speak this protocol. + * + * This shouldn't happen. In any case, pretend lower layer went down. + */ +static void upap_protrej(ppp_pcb *pcb) { + + if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { + ppp_error("PAP authentication failed due to protocol-reject"); + auth_withpeer_fail(pcb, PPP_PAP); + } +#if PPP_SERVER + if (pcb->upap.us_serverstate == UPAPSS_LISTEN) { + ppp_error("PAP authentication of peer failed (protocol-reject)"); + auth_peer_fail(pcb, PPP_PAP); + } +#endif /* PPP_SERVER */ + upap_lowerdown(pcb); +} + + +/* + * upap_input - Input UPAP packet. + */ +static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { + u_char *inp; + u_char code, id; + int len; + + /* + * Parse header (code, id and length). + * If packet too short, drop it. + */ + inp = inpacket; + if (l < UPAP_HEADERLEN) { + UPAPDEBUG(("pap_input: rcvd short header.")); + return; + } + GETCHAR(code, inp); + GETCHAR(id, inp); + GETSHORT(len, inp); + if (len < UPAP_HEADERLEN) { + UPAPDEBUG(("pap_input: rcvd illegal length.")); + return; + } + if (len > l) { + UPAPDEBUG(("pap_input: rcvd short packet.")); + return; + } + len -= UPAP_HEADERLEN; + + /* + * Action depends on code. + */ + switch (code) { + case UPAP_AUTHREQ: +#if PPP_SERVER + upap_rauthreq(pcb, inp, id, len); +#endif /* PPP_SERVER */ + break; + + case UPAP_AUTHACK: + upap_rauthack(pcb, inp, id, len); + break; + + case UPAP_AUTHNAK: + upap_rauthnak(pcb, inp, id, len); + break; + + default: /* XXX Need code reject */ + break; + } +} + +#if PPP_SERVER +/* + * upap_rauth - Receive Authenticate. + */ +static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { + u_char ruserlen, rpasswdlen; + char *ruser; +#if 0 + char *rpasswd; +#endif + char rhostname[256]; + int retcode; + const char *msg; + int msglen; + + if (pcb->upap.us_serverstate < UPAPSS_LISTEN) + return; + + /* + * If we receive a duplicate authenticate-request, we are + * supposed to return the same status as for the first request. + */ + if (pcb->upap.us_serverstate == UPAPSS_OPEN) { + upap_sresp(pcb, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ + return; + } + if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { + upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ + return; + } + + /* + * Parse user/passwd. + */ + if (len < 1) { + UPAPDEBUG(("pap_rauth: rcvd short packet.")); + return; + } + GETCHAR(ruserlen, inp); + len -= sizeof (u_char) + ruserlen + sizeof (u_char); + if (len < 0) { + UPAPDEBUG(("pap_rauth: rcvd short packet.")); + return; + } + ruser = (char *) inp; + INCPTR(ruserlen, inp); + GETCHAR(rpasswdlen, inp); + if (len < rpasswdlen) { + UPAPDEBUG(("pap_rauth: rcvd short packet.")); + return; + } + + /* FIXME: we need a way to check peer secret */ +#if 0 + rpasswd = (char *) inp; + + /* + * Check the username and password given. + */ + retcode = check_passwd(pcb->upap.us_unit, ruser, ruserlen, rpasswd, + rpasswdlen, &msg); + BZERO(rpasswd, rpasswdlen); + + /* + * Check remote number authorization. A plugin may have filled in + * the remote number or added an allowed number, and rather than + * return an authenticate failure, is leaving it for us to verify. + */ + if (retcode == UPAP_AUTHACK) { + if (!auth_number()) { + /* We do not want to leak info about the pap result. */ + retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */ + warn("calling number %q is not authorized", remote_number); + } + } + + msglen = strlen(msg); + if (msglen > 255) + msglen = 255; +#else + /* only here to clean compiler warnings */ + retcode = UPAP_AUTHNAK; + msg = NULL; + msglen = 0; +#endif /* 0 */ + + upap_sresp(pcb, retcode, id, msg, msglen); + + /* Null terminate and clean remote name. */ + ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); + + if (retcode == UPAP_AUTHACK) { + pcb->upap.us_serverstate = UPAPSS_OPEN; + ppp_notice("PAP peer authentication succeeded for %q", rhostname); + auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); + } else { + pcb->upap.us_serverstate = UPAPSS_BADAUTH; + ppp_warn("PAP peer authentication failed for %q", rhostname); + auth_peer_fail(pcb, PPP_PAP); + } + + if (pcb->settings.pap_req_timeout > 0) + UNTIMEOUT(upap_reqtimeout, pcb); +} +#endif /* PPP_SERVER */ + +/* + * upap_rauthack - Receive Authenticate-Ack. + */ +static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) { + u_char msglen; + char *msg; + LWIP_UNUSED_ARG(id); + + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ + return; + + /* + * Parse message. + */ + if (len < 1) { + UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); + } else { + GETCHAR(msglen, inp); + if (msglen > 0) { + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG(("pap_rauthack: rcvd short packet.")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + } + } + + pcb->upap.us_clientstate = UPAPCS_OPEN; + + auth_withpeer_success(pcb, PPP_PAP, 0); +} + + +/* + * upap_rauthnak - Receive Authenticate-Nak. + */ +static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { + u_char msglen; + char *msg; + LWIP_UNUSED_ARG(id); + + if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ + return; + + /* + * Parse message. + */ + if (len < 1) { + UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); + } else { + GETCHAR(msglen, inp); + if (msglen > 0) { + len -= sizeof (u_char); + if (len < msglen) { + UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); + return; + } + msg = (char *) inp; + PRINTMSG(msg, msglen); + } + } + + pcb->upap.us_clientstate = UPAPCS_BADAUTH; + + ppp_error("PAP authentication failed"); + auth_withpeer_fail(pcb, PPP_PAP); +} + + +/* + * upap_sauthreq - Send an Authenticate-Request. + */ +static void upap_sauthreq(ppp_pcb *pcb) { + struct pbuf *p; + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + + pcb->upap.us_userlen + pcb->upap.us_passwdlen; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(UPAP_AUTHREQ, outp); + PUTCHAR(++pcb->upap.us_id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(pcb->upap.us_userlen, outp); + MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen); + INCPTR(pcb->upap.us_userlen, outp); + PUTCHAR(pcb->upap.us_passwdlen, outp); + MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); + + ppp_write(pcb, p); + + TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time); + ++pcb->upap.us_transmits; + pcb->upap.us_clientstate = UPAPCS_AUTHREQ; +} + +#if PPP_SERVER +/* + * upap_sresp - Send a response (ack or nak). + */ +static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) { + struct pbuf *p; + u_char *outp; + int outlen; + + outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; + p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); + if(NULL == p) + return; + if(p->tot_len != p->len) { + pbuf_free(p); + return; + } + + outp = (u_char*)p->payload; + MAKEHEADER(outp, PPP_PAP); + + PUTCHAR(code, outp); + PUTCHAR(id, outp); + PUTSHORT(outlen, outp); + PUTCHAR(msglen, outp); + MEMCPY(outp, msg, msglen); + + ppp_write(pcb, p); +} +#endif /* PPP_SERVER */ + +#if PRINTPKT_SUPPORT +/* + * upap_printpkt - print the contents of a PAP packet. + */ +static const char *upap_codenames[] = { + "AuthReq", "AuthAck", "AuthNak" +}; + +static int upap_printpkt(u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) { + int code, id, len; + int mlen, ulen, wlen; + char *user, *pwd, *msg; + u_char *pstart; + + if (plen < UPAP_HEADERLEN) + return 0; + pstart = p; + GETCHAR(code, p); + GETCHAR(id, p); + GETSHORT(len, p); + if (len < UPAP_HEADERLEN || len > plen) + return 0; + + if (code >= 1 && code <= (int)sizeof(upap_codenames) / (int)sizeof(char *)) + printer(arg, " %s", upap_codenames[code-1]); + else + printer(arg, " code=0x%x", code); + printer(arg, " id=0x%x", id); + len -= UPAP_HEADERLEN; + switch (code) { + case UPAP_AUTHREQ: + if (len < 1) + break; + ulen = p[0]; + if (len < ulen + 2) + break; + wlen = p[ulen + 1]; + if (len < ulen + wlen + 2) + break; + user = (char *) (p + 1); + pwd = (char *) (p + ulen + 2); + p += ulen + wlen + 2; + len -= ulen + wlen + 2; + printer(arg, " user="); + ppp_print_string(user, ulen, printer, arg); + printer(arg, " password="); +/* FIXME: require ppp_pcb struct as printpkt() argument */ +#if 0 + if (!pcb->settings.hide_password) +#endif + ppp_print_string(pwd, wlen, printer, arg); +#if 0 + else + printer(arg, ""); +#endif + break; + case UPAP_AUTHACK: + case UPAP_AUTHNAK: + if (len < 1) + break; + mlen = p[0]; + if (len < mlen + 1) + break; + msg = (char *) (p + 1); + p += mlen + 1; + len -= mlen + 1; + printer(arg, " "); + ppp_print_string(msg, mlen, printer, arg); + break; + default: + break; + } + + /* print the rest of the bytes in the packet */ + for (; len > 0; --len) { + GETCHAR(code, p); + printer(arg, " %.2x", code); + } + + return p - pstart; +} +#endif /* PRINTPKT_SUPPORT */ + +#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/utils.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/utils.c new file mode 100644 index 0000000..ecd305a --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/utils.c @@ -0,0 +1,964 @@ +/* + * utils.c - various utility functions used in pppd. + * + * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * 3. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Paul Mackerras + * ". + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#if 0 /* UNUSED */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef SVR4 +#include +#endif +#endif /* UNUSED */ + +#include /* isdigit() */ + +#include "netif/ppp/ppp_impl.h" + +#include "netif/ppp/fsm.h" +#include "netif/ppp/lcp.h" + +#if defined(SUNOS4) +extern char *strerror(); +#endif + +static void ppp_logit(int level, const char *fmt, va_list args); +static void ppp_log_write(int level, char *buf); +#if PRINTPKT_SUPPORT +static void ppp_vslp_printer(void *arg, const char *fmt, ...); +static void ppp_format_packet(u_char *p, int len, + void (*printer) (void *, const char *, ...), void *arg); + +struct buffer_info { + char *ptr; + int len; +}; +#endif /* PRINTPKT_SUPPORT */ + +/* + * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t ppp_strlcpy(char *dest, const char *src, size_t len) { + size_t ret = strlen(src); + + if (len != 0) { + if (ret < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len-1] = 0; + } + } + return ret; +} + +/* + * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +size_t ppp_strlcat(char *dest, const char *src, size_t len) { + size_t dlen = strlen(dest); + + return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); +} + + +/* + * ppp_slprintf - format a message into a buffer. Like sprintf except we + * also specify the length of the output buffer, and we handle + * %m (error message), %v (visible string), + * %q (quoted string), %t (current time) and %I (IP address) formats. + * Doesn't do floating-point formats. + * Returns the number of chars put into buf. + */ +int ppp_slprintf(char *buf, int buflen, const char *fmt, ...) { + va_list args; + int n; + + va_start(args, fmt); + n = ppp_vslprintf(buf, buflen, fmt, args); + va_end(args); + return n; +} + +/* + * ppp_vslprintf - like ppp_slprintf, takes a va_list instead of a list of args. + */ +#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) + +int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args) { + int c, i, n; + int width, prec, fillch; + int base, len, neg, quoted; + unsigned long val = 0; + const char *f; + char *str, *buf0; + unsigned char *p; + char num[32]; +#if 0 /* need port */ + time_t t; +#endif /* need port */ + u32_t ip; + static char hexchars[] = "0123456789abcdef"; +#if PRINTPKT_SUPPORT + struct buffer_info bufinfo; +#endif /* PRINTPKT_SUPPORT */ + + buf0 = buf; + --buflen; + while (buflen > 0) { + for (f = fmt; *f != '%' && *f != 0; ++f) + ; + if (f > fmt) { + len = f - fmt; + if (len > buflen) + len = buflen; + memcpy(buf, fmt, len); + buf += len; + buflen -= len; + fmt = f; + } + if (*fmt == 0) + break; + c = *++fmt; + width = 0; + prec = -1; + fillch = ' '; + if (c == '0') { + fillch = '0'; + c = *++fmt; + } + if (c == '*') { + width = va_arg(args, int); + c = *++fmt; + } else { + while (isdigit(c)) { + width = width * 10 + c - '0'; + c = *++fmt; + } + } + if (c == '.') { + c = *++fmt; + if (c == '*') { + prec = va_arg(args, int); + c = *++fmt; + } else { + prec = 0; + while (isdigit(c)) { + prec = prec * 10 + c - '0'; + c = *++fmt; + } + } + } + str = 0; + base = 0; + neg = 0; + ++fmt; + switch (c) { + case 'l': + c = *fmt++; + switch (c) { + case 'd': + val = va_arg(args, long); + if ((long)val < 0) { + neg = 1; + val = (unsigned long)-val; + } + base = 10; + break; + case 'u': + val = va_arg(args, unsigned long); + base = 10; + break; + default: + OUTCHAR('%'); + OUTCHAR('l'); + --fmt; /* so %lz outputs %lz etc. */ + continue; + } + break; + case 'd': + i = va_arg(args, int); + if (i < 0) { + neg = 1; + val = -i; + } else + val = i; + base = 10; + break; + case 'u': + val = va_arg(args, unsigned int); + base = 10; + break; + case 'o': + val = va_arg(args, unsigned int); + base = 8; + break; + case 'x': + case 'X': + val = va_arg(args, unsigned int); + base = 16; + break; + case 'p': + val = (unsigned long) va_arg(args, void *); + base = 16; + neg = 2; + break; + case 's': + str = va_arg(args, char *); + break; + case 'c': + num[0] = va_arg(args, int); + num[1] = 0; + str = num; + break; +#if 0 /* do we always have strerror() in embedded ? */ + case 'm': + str = strerror(errno); + break; +#endif /* do we always have strerror() in embedded ? */ + case 'I': + ip = va_arg(args, u32_t); + ip = ntohl(ip); + ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, + (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); + str = num; + break; +#if 0 /* need port */ + case 't': + time(&t); + str = ctime(&t); + str += 4; /* chop off the day name */ + str[15] = 0; /* chop off year and newline */ + break; +#endif /* need port */ + case 'v': /* "visible" string */ + case 'q': /* quoted string */ + quoted = c == 'q'; + p = va_arg(args, unsigned char *); + if (p == NULL) + p = (unsigned char *)""; + if (fillch == '0' && prec >= 0) { + n = prec; + } else { + n = strlen((char *)p); + if (prec >= 0 && n > prec) + n = prec; + } + while (n > 0 && buflen > 0) { + c = *p++; + --n; + if (!quoted && c >= 0x80) { + OUTCHAR('M'); + OUTCHAR('-'); + c -= 0x80; + } + if (quoted && (c == '"' || c == '\\')) + OUTCHAR('\\'); + if (c < 0x20 || (0x7f <= c && c < 0xa0)) { + if (quoted) { + OUTCHAR('\\'); + switch (c) { + case '\t': OUTCHAR('t'); break; + case '\n': OUTCHAR('n'); break; + case '\b': OUTCHAR('b'); break; + case '\f': OUTCHAR('f'); break; + default: + OUTCHAR('x'); + OUTCHAR(hexchars[c >> 4]); + OUTCHAR(hexchars[c & 0xf]); + } + } else { + if (c == '\t') + OUTCHAR(c); + else { + OUTCHAR('^'); + OUTCHAR(c ^ 0x40); + } + } + } else + OUTCHAR(c); + } + continue; +#if PRINTPKT_SUPPORT + case 'P': /* print PPP packet */ + bufinfo.ptr = buf; + bufinfo.len = buflen + 1; + p = va_arg(args, unsigned char *); + n = va_arg(args, int); + ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo); + buf = bufinfo.ptr; + buflen = bufinfo.len - 1; + continue; +#endif /* PRINTPKT_SUPPORT */ + case 'B': + p = va_arg(args, unsigned char *); + for (n = prec; n > 0; --n) { + c = *p++; + if (fillch == ' ') + OUTCHAR(' '); + OUTCHAR(hexchars[(c >> 4) & 0xf]); + OUTCHAR(hexchars[c & 0xf]); + } + continue; + default: + *buf++ = '%'; + if (c != '%') + --fmt; /* so %z outputs %z etc. */ + --buflen; + continue; + } + if (base != 0) { + str = num + sizeof(num); + *--str = 0; + while (str > num + neg) { + *--str = hexchars[val % base]; + val = val / base; + if (--prec <= 0 && val == 0) + break; + } + switch (neg) { + case 1: + *--str = '-'; + break; + case 2: + *--str = 'x'; + *--str = '0'; + break; + default: + break; + } + len = num + sizeof(num) - 1 - str; + } else { + len = strlen(str); + if (prec >= 0 && len > prec) + len = prec; + } + if (width > 0) { + if (width > buflen) + width = buflen; + if ((n = width - len) > 0) { + buflen -= n; + for (; n > 0; --n) + *buf++ = fillch; + } + } + if (len > buflen) + len = buflen; + memcpy(buf, str, len); + buf += len; + buflen -= len; + } + *buf = 0; + return buf - buf0; +} + +#if PRINTPKT_SUPPORT +/* + * vslp_printer - used in processing a %P format + */ +static void ppp_vslp_printer(void *arg, const char *fmt, ...) { + int n; + va_list pvar; + struct buffer_info *bi; + + va_start(pvar, fmt); + bi = (struct buffer_info *) arg; + n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar); + va_end(pvar); + + bi->ptr += n; + bi->len -= n; +} +#endif /* PRINTPKT_SUPPORT */ + +#if 0 /* UNUSED */ +/* + * log_packet - format a packet and log it. + */ + +void +log_packet(p, len, prefix, level) + u_char *p; + int len; + char *prefix; + int level; +{ + init_pr_log(prefix, level); + ppp_format_packet(p, len, pr_log, &level); + end_pr_log(); +} +#endif /* UNUSED */ + +#if PRINTPKT_SUPPORT +/* + * ppp_format_packet - make a readable representation of a packet, + * calling `printer(arg, format, ...)' to output it. + */ +static void ppp_format_packet(u_char *p, int len, + void (*printer) (void *, const char *, ...), void *arg) { + int i, n; + u_short proto; + const struct protent *protp; + + if (len >= 2) { + GETSHORT(proto, p); + len -= 2; + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (proto == protp->protocol) + break; + if (protp != NULL) { + printer(arg, "[%s", protp->name); + n = (*protp->printpkt)(p, len, printer, arg); + printer(arg, "]"); + p += n; + len -= n; + } else { + for (i = 0; (protp = protocols[i]) != NULL; ++i) + if (proto == (protp->protocol & ~0x8000)) + break; + if (protp != 0 && protp->data_name != 0) { + printer(arg, "[%s data]", protp->data_name); + if (len > 8) + printer(arg, "%.8B ...", p); + else + printer(arg, "%.*B", len, p); + len = 0; + } else + printer(arg, "[proto=0x%x]", proto); + } + } + + if (len > 32) + printer(arg, "%.32B ...", p); + else + printer(arg, "%.*B", len, p); +} +#endif /* PRINTPKT_SUPPORT */ + +#if 0 /* UNUSED */ +/* + * init_pr_log, end_pr_log - initialize and finish use of pr_log. + */ + +static char line[256]; /* line to be logged accumulated here */ +static char *linep; /* current pointer within line */ +static int llevel; /* level for logging */ + +void +init_pr_log(prefix, level) + const char *prefix; + int level; +{ + linep = line; + if (prefix != NULL) { + ppp_strlcpy(line, prefix, sizeof(line)); + linep = line + strlen(line); + } + llevel = level; +} + +void +end_pr_log() +{ + if (linep != line) { + *linep = 0; + ppp_log_write(llevel, line); + } +} + +/* + * pr_log - printer routine for outputting to log + */ +void +pr_log (void *arg, const char *fmt, ...) +{ + int l, n; + va_list pvar; + char *p, *eol; + char buf[256]; + + va_start(pvar, fmt); + n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar); + va_end(pvar); + + p = buf; + eol = strchr(buf, '\n'); + if (linep != line) { + l = (eol == NULL)? n: eol - buf; + if (linep + l < line + sizeof(line)) { + if (l > 0) { + memcpy(linep, buf, l); + linep += l; + } + if (eol == NULL) + return; + p = eol + 1; + eol = strchr(p, '\n'); + } + *linep = 0; + ppp_log_write(llevel, line); + linep = line; + } + + while (eol != NULL) { + *eol = 0; + ppp_log_write(llevel, p); + p = eol + 1; + eol = strchr(p, '\n'); + } + + /* assumes sizeof(buf) <= sizeof(line) */ + l = buf + n - p; + if (l > 0) { + memcpy(line, p, n); + linep = line + l; + } +} +#endif /* UNUSED */ + +/* + * ppp_print_string - print a readable representation of a string using + * printer. + */ +void ppp_print_string(char *p, int len, void (*printer) (void *, const char *, ...), void *arg) { + int c; + + printer(arg, "\""); + for (; len > 0; --len) { + c = *p++; + if (' ' <= c && c <= '~') { + if (c == '\\' || c == '"') + printer(arg, "\\"); + printer(arg, "%c", c); + } else { + switch (c) { + case '\n': + printer(arg, "\\n"); + break; + case '\r': + printer(arg, "\\r"); + break; + case '\t': + printer(arg, "\\t"); + break; + default: + printer(arg, "\\%.3o", c); + /* no break */ + } + } + } + printer(arg, "\""); +} + +/* + * ppp_logit - does the hard work for fatal et al. + */ +static void ppp_logit(int level, const char *fmt, va_list args) { + char buf[1024]; + + ppp_vslprintf(buf, sizeof(buf), fmt, args); + ppp_log_write(level, buf); +} + +static void ppp_log_write(int level, char *buf) { + LWIP_UNUSED_ARG(level); /* necessary if PPPDEBUG is defined to an empty function */ + LWIP_UNUSED_ARG(buf); + PPPDEBUG(level, ("%s\n", buf) ); +#if 0 + if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { + int n = strlen(buf); + + if (n > 0 && buf[n-1] == '\n') + --n; + if (write(log_to_fd, buf, n) != n + || write(log_to_fd, "\n", 1) != 1) + log_to_fd = -1; + } +#endif +} + +/* + * ppp_fatal - log an error message and die horribly. + */ +void ppp_fatal(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_ERR, fmt, pvar); + va_end(pvar); + +/* FIXME: find a way to die */ +#if 0 + die(1); /* as promised */ +#endif +} + +/* + * ppp_error - log an error message. + */ +void ppp_error(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_ERR, fmt, pvar); + va_end(pvar); +#if 0 /* UNUSED */ + ++error_count; +#endif /* UNUSED */ +} + +/* + * ppp_warn - log a warning message. + */ +void ppp_warn(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_WARNING, fmt, pvar); + va_end(pvar); +} + +/* + * ppp_notice - log a notice-level message. + */ +void ppp_notice(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_NOTICE, fmt, pvar); + va_end(pvar); +} + +/* + * ppp_info - log an informational message. + */ +void ppp_info(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_INFO, fmt, pvar); + va_end(pvar); +} + +/* + * ppp_dbglog - log a debug message. + */ +void ppp_dbglog(const char *fmt, ...) { + va_list pvar; + + va_start(pvar, fmt); + ppp_logit(LOG_DEBUG, fmt, pvar); + va_end(pvar); +} + +#if PRINTPKT_SUPPORT +/* + * ppp_dump_packet - print out a packet in readable form if it is interesting. + * Assumes len >= PPP_HDRLEN. + */ +void ppp_dump_packet(const char *tag, unsigned char *p, int len) { + int proto; + + /* + * don't print IPv4 and IPv6 packets. + */ + proto = (p[0] << 8) + p[1]; + if (proto == PPP_IP) + return; +#if PPP_IPV6_SUPPORT + if (proto == PPP_IPV6) + return; +#endif + + /* + * don't print LCP echo request/reply packets if the link is up. + */ + if (proto == PPP_LCP && len >= 2 + HEADERLEN) { + unsigned char *lcp = p + 2; + int l = (lcp[2] << 8) + lcp[3]; + + if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) + && l >= HEADERLEN && l <= len - 2) + return; + } + + ppp_dbglog("%s %P", tag, p, len); +} +#endif /* PRINTPKT_SUPPORT */ + +#if 0 /* Unused */ + +/* + * complete_read - read a full `count' bytes from fd, + * unless end-of-file or an error other than EINTR is encountered. + */ +ssize_t +complete_read(int fd, void *buf, size_t count) +{ + size_t done; + ssize_t nb; + char *ptr = buf; + + for (done = 0; done < count; ) { + nb = read(fd, ptr, count - done); + if (nb < 0) { + if (errno == EINTR) + continue; + return -1; + } + if (nb == 0) + break; + done += nb; + ptr += nb; + } + return done; +} + +/* Procedures for locking the serial device using a lock file. */ +#ifndef LOCK_DIR +#ifdef __linux__ +#define LOCK_DIR "/var/lock" +#else +#ifdef SVR4 +#define LOCK_DIR "/var/spool/locks" +#else +#define LOCK_DIR "/var/spool/lock" +#endif +#endif +#endif /* LOCK_DIR */ + +static char lock_file[MAXPATHLEN]; + +/* + * lock - create a lock file for the named device + */ +int +lock(dev) + char *dev; +{ +#ifdef LOCKLIB + int result; + + result = mklock (dev, (void *) 0); + if (result == 0) { + ppp_strlcpy(lock_file, dev, sizeof(lock_file)); + return 0; + } + + if (result > 0) + ppp_notice("Device %s is locked by pid %d", dev, result); + else + ppp_error("Can't create lock file %s", lock_file); + return -1; + +#else /* LOCKLIB */ + + char lock_buffer[12]; + int fd, pid, n; + +#ifdef SVR4 + struct stat sbuf; + + if (stat(dev, &sbuf) < 0) { + ppp_error("Can't get device number for %s: %m", dev); + return -1; + } + if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { + ppp_error("Can't lock %s: not a character device", dev); + return -1; + } + ppp_slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", + LOCK_DIR, major(sbuf.st_dev), + major(sbuf.st_rdev), minor(sbuf.st_rdev)); +#else + char *p; + char lockdev[MAXPATHLEN]; + + if ((p = strstr(dev, "dev/")) != NULL) { + dev = p + 4; + strncpy(lockdev, dev, MAXPATHLEN-1); + lockdev[MAXPATHLEN-1] = 0; + while ((p = strrchr(lockdev, '/')) != NULL) { + *p = '_'; + } + dev = lockdev; + } else + if ((p = strrchr(dev, '/')) != NULL) + dev = p + 1; + + ppp_slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); +#endif + + while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { + if (errno != EEXIST) { + ppp_error("Can't create lock file %s: %m", lock_file); + break; + } + + /* Read the lock file to find out who has the device locked. */ + fd = open(lock_file, O_RDONLY, 0); + if (fd < 0) { + if (errno == ENOENT) /* This is just a timing problem. */ + continue; + ppp_error("Can't open existing lock file %s: %m", lock_file); + break; + } +#ifndef LOCK_BINARY + n = read(fd, lock_buffer, 11); +#else + n = read(fd, &pid, sizeof(pid)); +#endif /* LOCK_BINARY */ + close(fd); + fd = -1; + if (n <= 0) { + ppp_error("Can't read pid from lock file %s", lock_file); + break; + } + + /* See if the process still exists. */ +#ifndef LOCK_BINARY + lock_buffer[n] = 0; + pid = atoi(lock_buffer); +#endif /* LOCK_BINARY */ + if (pid == getpid()) + return 1; /* somebody else locked it for us */ + if (pid == 0 + || (kill(pid, 0) == -1 && errno == ESRCH)) { + if (unlink (lock_file) == 0) { + ppp_notice("Removed stale lock on %s (pid %d)", dev, pid); + continue; + } + ppp_warn("Couldn't remove stale lock on %s", dev); + } else + ppp_notice("Device %s is locked by pid %d", dev, pid); + break; + } + + if (fd < 0) { + lock_file[0] = 0; + return -1; + } + + pid = getpid(); +#ifndef LOCK_BINARY + ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); + write (fd, lock_buffer, 11); +#else + write(fd, &pid, sizeof (pid)); +#endif + close(fd); + return 0; + +#endif +} + +/* + * relock - called to update our lockfile when we are about to detach, + * thus changing our pid (we fork, the child carries on, and the parent dies). + * Note that this is called by the parent, with pid equal to the pid + * of the child. This avoids a potential race which would exist if + * we had the child rewrite the lockfile (the parent might die first, + * and another process could think the lock was stale if it checked + * between when the parent died and the child rewrote the lockfile). + */ +int +relock(pid) + int pid; +{ +#ifdef LOCKLIB + /* XXX is there a way to do this? */ + return -1; +#else /* LOCKLIB */ + + int fd; + char lock_buffer[12]; + + if (lock_file[0] == 0) + return -1; + fd = open(lock_file, O_WRONLY, 0); + if (fd < 0) { + ppp_error("Couldn't reopen lock file %s: %m", lock_file); + lock_file[0] = 0; + return -1; + } + +#ifndef LOCK_BINARY + ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); + write (fd, lock_buffer, 11); +#else + write(fd, &pid, sizeof(pid)); +#endif /* LOCK_BINARY */ + close(fd); + return 0; + +#endif /* LOCKLIB */ +} + +/* + * unlock - remove our lockfile + */ +void +unlock() +{ + if (lock_file[0]) { +#ifdef LOCKLIB + (void) rmlock(lock_file, (void *) 0); +#else + unlink(lock_file); +#endif + lock_file[0] = 0; + } +} + +#endif /* Unused */ + +#endif /* PPP_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/vj.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/vj.c new file mode 100644 index 0000000..dc805ad --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/ppp/vj.c @@ -0,0 +1,657 @@ +/* + * Routines to compress and uncompess tcp packets (for transmission + * over low speed serial lines. + * + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: + * Initial distribution. + * + * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, + * so that the entire packet being decompressed doesn't have + * to be in contiguous memory (just the compressed header). + * + * Modified March 1998 by Guy Lancaster, glanca@gesn.com, + * for a 16 bit processor. + */ + +#include "lwip/opt.h" +#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ + +#include "netif/ppp/ppp_impl.h" +#include "netif/ppp/pppdebug.h" + +#include "netif/ppp/vj.h" + +#include + +#if LINK_STATS +#define INCR(counter) ++comp->stats.counter +#else +#define INCR(counter) +#endif + +void +vj_compress_init(struct vjcompress *comp) +{ + register u_char i; + register struct cstate *tstate = comp->tstate; + +#if MAX_SLOTS == 0 + memset((char *)comp, 0, sizeof(*comp)); +#endif + comp->maxSlotIndex = MAX_SLOTS - 1; + comp->compressSlot = 0; /* Disable slot ID compression by default. */ + for (i = MAX_SLOTS - 1; i > 0; --i) { + tstate[i].cs_id = i; + tstate[i].cs_next = &tstate[i - 1]; + } + tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; + tstate[0].cs_id = 0; + comp->last_cs = &tstate[0]; + comp->last_recv = 255; + comp->last_xmit = 255; + comp->flags = VJF_TOSS; +} + + +/* ENCODE encodes a number that is known to be non-zero. ENCODEZ + * checks for zero (since zero has to be encoded in the long, 3 byte + * form). + */ +#define ENCODE(n) { \ + if ((u_short)(n) >= 256) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} +#define ENCODEZ(n) { \ + if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \ + *cp++ = 0; \ + cp[1] = (u_char)(n); \ + cp[0] = (u_char)((n) >> 8); \ + cp += 2; \ + } else { \ + *cp++ = (u_char)(n); \ + } \ +} + +#define DECODEL(f) { \ + if (*cp == 0) {\ + u32_t tmp_ = ntohl(f) + ((cp[1] << 8) | cp[2]); \ + (f) = htonl(tmp_); \ + cp += 3; \ + } else { \ + u32_t tmp_ = ntohl(f) + (u32_t)*cp++; \ + (f) = htonl(tmp_); \ + } \ +} + +#define DECODES(f) { \ + if (*cp == 0) {\ + u_short tmp_ = ntohs(f) + (((u_short)cp[1] << 8) | cp[2]); \ + (f) = htons(tmp_); \ + cp += 3; \ + } else { \ + u_short tmp_ = ntohs(f) + (u_short)*cp++; \ + (f) = htons(tmp_); \ + } \ +} + +#define DECODEU(f) { \ + if (*cp == 0) {\ + (f) = htons(((u_short)cp[1] << 8) | cp[2]); \ + cp += 3; \ + } else { \ + (f) = htons((u_short)*cp++); \ + } \ +} + +/* + * vj_compress_tcp - Attempt to do Van Jacobson header compression on a + * packet. This assumes that nb and comp are not null and that the first + * buffer of the chain contains a valid IP header. + * Return the VJ type code indicating whether or not the packet was + * compressed. + */ +u_int +vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb) +{ + register struct ip_hdr *ip = (struct ip_hdr *)pb->payload; + register struct cstate *cs = comp->last_cs->cs_next; + register u_short hlen = IPH_HL(ip); + register struct tcp_hdr *oth; + register struct tcp_hdr *th; + register u_short deltaS, deltaA = 0; + register u_long deltaL; + register u_int changes = 0; + u_char new_seq[16]; + register u_char *cp = new_seq; + + /* + * Check that the packet is IP proto TCP. + */ + if (IPH_PROTO(ip) != IP_PROTO_TCP) { + return (TYPE_IP); + } + + /* + * Bail if this is an IP fragment or if the TCP packet isn't + * `compressible' (i.e., ACK isn't set or some other control bit is + * set). + */ + if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) { + return (TYPE_IP); + } + th = (struct tcp_hdr *)&((long *)ip)[hlen]; + if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { + return (TYPE_IP); + } + /* + * Packet is compressible -- we're going to send either a + * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need + * to locate (or create) the connection state. Special case the + * most recently used connection since it's most likely to be used + * again & we don't have to do any reordering if it's used. + */ + INCR(vjs_packets); + if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src) + || !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + || *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + /* + * Wasn't the first -- search for it. + * + * States are kept in a circularly linked list with + * last_cs pointing to the end of the list. The + * list is kept in lru order by moving a state to the + * head of the list whenever it is referenced. Since + * the list is short and, empirically, the connection + * we want is almost always near the front, we locate + * states via linear search. If we don't find a state + * for the datagram, the oldest state is (re-)used. + */ + register struct cstate *lcs; + register struct cstate *lastcs = comp->last_cs; + + do { + lcs = cs; cs = cs->cs_next; + INCR(vjs_searches); + if (ip_addr_cmp(&ip->src, &cs->cs_ip.src) + && ip_addr_cmp(&ip->dest, &cs->cs_ip.dest) + && *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) { + goto found; + } + } while (cs != lastcs); + + /* + * Didn't find it -- re-use oldest cstate. Send an + * uncompressed packet that tells the other side what + * connection number we're using for this conversation. + * Note that since the state list is circular, the oldest + * state points to the newest and we only need to set + * last_cs to update the lru linkage. + */ + INCR(vjs_misses); + comp->last_cs = lcs; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + return (TYPE_IP); + } + goto uncompressed; + + found: + /* + * Found it -- move to the front on the connection list. + */ + if (cs == lastcs) { + comp->last_cs = lcs; + } else { + lcs->cs_next = cs->cs_next; + cs->cs_next = lastcs->cs_next; + lastcs->cs_next = cs; + } + } + + oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen]; + deltaS = hlen; + hlen += TCPH_HDRLEN(th); + hlen <<= 2; + /* Check that the IP/TCP headers are contained in the first buffer. */ + if (hlen > pb->len) { + PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); + return (TYPE_IP); + } + + /* + * Make sure that only what we expect to change changed. The first + * line of the `if' checks the IP protocol version, header length & + * type of service. The 2nd line checks the "Don't fragment" bit. + * The 3rd line checks the time-to-live and protocol (the protocol + * check is unnecessary but costless). The 4th line checks the TCP + * header length. The 5th line checks IP options, if any. The 6th + * line checks TCP options, if any. If any of these things are + * different between the previous & current datagram, we send the + * current datagram `uncompressed'. + */ + if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] + || ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] + || ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] + || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) + || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) + || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { + goto uncompressed; + } + + /* + * Figure out which of the changing fields changed. The + * receiver expects changes in the order: urgent, window, + * ack, seq (the order minimizes the number of temporaries + * needed in this section of code). + */ + if (TCPH_FLAGS(th) & TCP_URG) { + deltaS = ntohs(th->urgp); + ENCODEZ(deltaS); + changes |= NEW_U; + } else if (th->urgp != oth->urgp) { + /* argh! URG not set but urp changed -- a sensible + * implementation should never do this but RFC793 + * doesn't prohibit the change so we have to deal + * with it. */ + goto uncompressed; + } + + if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) { + ENCODE(deltaS); + changes |= NEW_W; + } + + if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaA = (u_short)deltaL; + ENCODE(deltaA); + changes |= NEW_A; + } + + if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) { + if (deltaL > 0xffff) { + goto uncompressed; + } + deltaS = (u_short)deltaL; + ENCODE(deltaS); + changes |= NEW_S; + } + + switch(changes) { + case 0: + /* + * Nothing changed. If this packet contains data and the + * last one didn't, this is probably a data packet following + * an ack (normal on an interactive connection) and we send + * it compressed. Otherwise it's probably a retransmit, + * retransmitted ack or window probe. Send it uncompressed + * in case the other side missed the compressed version. + */ + if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && + ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { + break; + } + /* no break */ + /* fall through */ + + case SPECIAL_I: + case SPECIAL_D: + /* + * actual changes match one of our special case encodings -- + * send packet uncompressed. + */ + goto uncompressed; + + case NEW_S|NEW_A: + if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for echoed terminal traffic */ + changes = SPECIAL_I; + cp = new_seq; + } + break; + + case NEW_S: + if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { + /* special case for data xfer */ + changes = SPECIAL_D; + cp = new_seq; + } + break; + default: + break; + } + + deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip))); + if (deltaS != 1) { + ENCODEZ(deltaS); + changes |= NEW_I; + } + if (TCPH_FLAGS(th) & TCP_PSH) { + changes |= TCP_PUSH_BIT; + } + /* + * Grab the cksum before we overwrite it below. Then update our + * state with this packet's header. + */ + deltaA = ntohs(th->chksum); + MEMCPY(&cs->cs_ip, ip, hlen); + + /* + * We want to use the original packet as our compressed packet. + * (cp - new_seq) is the number of bytes we need for compressed + * sequence numbers. In addition we need one byte for the change + * mask, one for the connection id and two for the tcp checksum. + * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how + * many bytes of the original packet to toss so subtract the two to + * get the new packet size. + */ + deltaS = (u_short)(cp - new_seq); + if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { + comp->last_xmit = cs->cs_id; + hlen -= deltaS + 4; + if(pbuf_header(pb, -hlen)){ + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)(changes | NEW_C); + *cp++ = cs->cs_id; + } else { + hlen -= deltaS + 3; + if(pbuf_header(pb, -hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + } + cp = (u_char *)pb->payload; + *cp++ = (u_char)changes; + } + *cp++ = (u_char)(deltaA >> 8); + *cp++ = (u_char)deltaA; + MEMCPY(cp, new_seq, deltaS); + INCR(vjs_compressed); + return (TYPE_COMPRESSED_TCP); + + /* + * Update connection state cs & send uncompressed packet (that is, + * a regular ip/tcp packet but with the 'conversation id' we hope + * to use on future compressed packets in the protocol field). + */ +uncompressed: + MEMCPY(&cs->cs_ip, ip, hlen); + IPH_PROTO_SET(ip, cs->cs_id); + comp->last_xmit = cs->cs_id; + return (TYPE_UNCOMPRESSED_TCP); +} + +/* + * Called when we may have missed a packet. + */ +void +vj_uncompress_err(struct vjcompress *comp) +{ + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); +} + +/* + * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. + * Return 0 on success, -1 on failure. + */ +int +vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) +{ + register u_int hlen; + register struct cstate *cs; + register struct ip_hdr *ip; + + ip = (struct ip_hdr *)nb->payload; + hlen = IPH_HL(ip) << 2; + if (IPH_PROTO(ip) >= MAX_SLOTS + || hlen + sizeof(struct tcp_hdr) > nb->len + || (hlen += TCPH_HDRLEN(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2) + > nb->len + || hlen > MAX_HDR) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", + IPH_PROTO(ip), hlen, nb->len)); + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return -1; + } + cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; + comp->flags &=~ VJF_TOSS; + IPH_PROTO_SET(ip, IP_PROTO_TCP); + MEMCPY(&cs->cs_ip, ip, hlen); + cs->cs_hlen = (u_short)hlen; + INCR(vjs_uncompressedin); + return 0; +} + +/* + * Uncompress a packet of type TYPE_COMPRESSED_TCP. + * The packet is composed of a buffer chain and the first buffer + * must contain an accurate chain length. + * The first buffer must include the entire compressed TCP/IP header. + * This procedure replaces the compressed header with the uncompressed + * header and returns the length of the VJ header. + */ +int +vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) +{ + u_char *cp; + struct tcp_hdr *th; + struct cstate *cs; + u_short *bp; + struct pbuf *n0 = *nb; + u32_t tmp; + u_int vjlen, hlen, changes; + + INCR(vjs_compressedin); + cp = (u_char *)n0->payload; + changes = *cp++; + if (changes & NEW_C) { + /* + * Make sure the state index is in range, then grab the state. + * If we have a good state index, clear the 'discard' flag. + */ + if (*cp >= MAX_SLOTS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); + goto bad; + } + + comp->flags &=~ VJF_TOSS; + comp->last_recv = *cp++; + } else { + /* + * this packet has an implicit state index. If we've + * had a line error since the last time we got an + * explicit state index, we have to toss the packet. + */ + if (comp->flags & VJF_TOSS) { + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); + INCR(vjs_tossed); + return (-1); + } + } + cs = &comp->rstate[comp->last_recv]; + hlen = IPH_HL(&cs->cs_ip) << 2; + th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen]; + th->chksum = htons((*cp << 8) | cp[1]); + cp += 2; + if (changes & TCP_PUSH_BIT) { + TCPH_SET_FLAG(th, TCP_PSH); + } else { + TCPH_UNSET_FLAG(th, TCP_PSH); + } + + switch (changes & SPECIALS_MASK) { + case SPECIAL_I: + { + register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->ackno) + i; + th->ackno = htonl(tmp); + tmp = ntohl(th->seqno) + i; + th->seqno = htonl(tmp); + } + break; + + case SPECIAL_D: + /* some compilers can't nest inline assembler.. */ + tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; + th->seqno = htonl(tmp); + break; + + default: + if (changes & NEW_U) { + TCPH_SET_FLAG(th, TCP_URG); + DECODEU(th->urgp); + } else { + TCPH_UNSET_FLAG(th, TCP_URG); + } + if (changes & NEW_W) { + DECODES(th->wnd); + } + if (changes & NEW_A) { + DECODEL(th->ackno); + } + if (changes & NEW_S) { + DECODEL(th->seqno); + } + break; + } + if (changes & NEW_I) { + DECODES(cs->cs_ip._id); + } else { + IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1); + IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip))); + } + + /* + * At this point, cp points to the first byte of data in the + * packet. Fill in the IP total length and update the IP + * header checksum. + */ + vjlen = (u_short)(cp - (u_char*)n0->payload); + if (n0->len < vjlen) { + /* + * We must have dropped some characters (crc should detect + * this but the old slip framing won't) + */ + PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", + n0->len, vjlen)); + goto bad; + } + +#if BYTE_ORDER == LITTLE_ENDIAN + tmp = n0->tot_len - vjlen + cs->cs_hlen; + IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp)); +#else + IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen)); +#endif + + /* recompute the ip header checksum */ + bp = (u_short *) &cs->cs_ip; + IPH_CHKSUM_SET(&cs->cs_ip, 0); + for (tmp = 0; hlen > 0; hlen -= 2) { + tmp += *bp++; + } + tmp = (tmp & 0xffff) + (tmp >> 16); + tmp = (tmp & 0xffff) + (tmp >> 16); + IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp)); + + /* Remove the compressed header and prepend the uncompressed header. */ + if(pbuf_header(n0, -((s16_t)(vjlen)))) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { + struct pbuf *np, *q; + u8_t *bufptr; + +#if IP_FORWARD + /* If IP forwarding is enabled we are using a PBUF_LINK packet type so + * the packet is being allocated with enough header space to be + * forwarded (to Ethernet for example). + */ + np = pbuf_alloc(PBUF_LINK, n0->len + cs->cs_hlen, PBUF_POOL); +#else /* IP_FORWARD */ + np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); +#endif /* IP_FORWARD */ + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); + goto bad; + } + + if(pbuf_header(np, -cs->cs_hlen)) { + /* Can we cope with this failing? Just assert for now */ + LWIP_ASSERT("pbuf_header failed\n", 0); + goto bad; + } + + bufptr = (u8_t*)n0->payload; + for(q = np; q != NULL; q = q->next) { + MEMCPY(q->payload, bufptr, q->len); + bufptr += q->len; + } + + if(n0->next) { + pbuf_chain(np, n0->next); + pbuf_dechain(n0); + } + pbuf_free(n0); + n0 = np; + } + + if(pbuf_header(n0, cs->cs_hlen)) { + struct pbuf *np; + + LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); + np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); + if(!np) { + PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); + goto bad; + } + pbuf_cat(np, n0); + n0 = np; + } + LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); + MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); + + *nb = n0; + + return vjlen; + +bad: + comp->flags |= VJF_TOSS; + INCR(vjs_errorin); + return (-1); +} + +#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/slipif.c b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/slipif.c new file mode 100644 index 0000000..ca9f0b9 --- /dev/null +++ b/USDK/component/common/network/lwip/lwip_v1.5.0.beta/src/netif/slipif.c @@ -0,0 +1,546 @@ +/** + * @file + * SLIP Interface + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is built upon the file: src/arch/rtxc/netif/sioslip.c + * + * Author: Magnus Ivarsson + * Simon Goldschmidt + * + * Usage: This netif can be used in three ways: + * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() + * until data is received. + * 2) In your main loop, call slipif_poll() to check for new RX bytes, + * completed packets are fed into netif->input(). + * 3) Call slipif_received_byte[s]() from your serial RX ISR and + * slipif_process_rxqueue() from your main loop. ISR level decodes + * packets and puts completed packets on a queue which is fed into + * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for + * pbuf_alloc to work on ISR level!). + * + */ + +/* + * This is an arch independent SLIP netif. The specific serial hooks must be + * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send + */ + +#include "netif/slipif.h" +#include "lwip/opt.h" + +#if LWIP_HAVE_SLIPIF + +#include "lwip/def.h" +#include "lwip/pbuf.h" +#include "lwip/stats.h" +#include "lwip/snmp.h" +#include "lwip/sys.h" +#include "lwip/sio.h" + +#define SLIP_END 0xC0 /* 0300: start and end of every packet */ +#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ +#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ +#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ + +/** Maximum packet size that is received by this netif */ +#ifndef SLIP_MAX_SIZE +#define SLIP_MAX_SIZE 1500 +#endif + +/** Define this to the interface speed for SNMP + * (sio_fd is the sio_fd_t returned by sio_open). + * The default value of zero means 'unknown'. + */ +#ifndef SLIP_SIO_SPEED +#define SLIP_SIO_SPEED(sio_fd) 0 +#endif + +enum slipif_recv_state { + SLIP_RECV_NORMAL, + SLIP_RECV_ESCAPE, +}; + +struct slipif_priv { + sio_fd_t sd; + /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ + struct pbuf *p, *q; + u8_t state; + u16_t i, recved; +#if SLIP_RX_FROM_ISR + struct pbuf *rxpackets; +#endif +}; + +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output(struct netif *netif, struct pbuf *p) +{ + struct slipif_priv *priv; + struct pbuf *q; + u16_t i; + u8_t c; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + LWIP_ASSERT("p != NULL", (p != NULL)); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len)); + priv = netif->state; + + /* Send pbuf out on the serial I/O device. */ + /* Start with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + + for (q = p; q != NULL; q = q->next) { + for (i = 0; i < q->len; i++) { + c = ((u8_t *)q->payload)[i]; + switch (c) { + case SLIP_END: + /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_END, priv->sd); + break; + case SLIP_ESC: + /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ + sio_send(SLIP_ESC, priv->sd); + sio_send(SLIP_ESC_ESC, priv->sd); + break; + default: + /* normal byte - no need for escaping */ + sio_send(c, priv->sd); + break; + } + } + } + /* End with packet delimiter. */ + sio_send(SLIP_END, priv->sd); + return ERR_OK; +} + +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output_v4(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr) +{ + LWIP_UNUSED_ARG(ipaddr); + return slipif_output(netif, p); +} + +#if LWIP_IPV6 +/** + * Send a pbuf doing the necessary SLIP encapsulation + * + * Uses the serial layer's sio_send() + * + * @param netif the lwip network interface structure for this slipif + * @param p the pbuf chain packet to send + * @param ipaddr the ip address to send the packet to (not used for slipif) + * @return always returns ERR_OK since the serial layer does not provide return values + */ +static err_t +slipif_output_v6(struct netif *netif, struct pbuf *p, ip6_addr_t *ipaddr) +{ + LWIP_UNUSED_ARG(ipaddr); + return slipif_output(netif, p); +} +#endif /* LWIP_IPV6 */ + +/** + * Handle the incoming SLIP stream character by character + * + * @param netif the lwip network interface structure for this slipif + * @param c received character (multiple calls to this function will + * return a complete packet, NULL is returned before - used for polling) + * @return The IP packet when SLIP_END is received + */ +static struct pbuf* +slipif_rxbyte(struct netif *netif, u8_t c) +{ + struct slipif_priv *priv; + struct pbuf *t; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = netif->state; + + switch (priv->state) { + case SLIP_RECV_NORMAL: + switch (c) { + case SLIP_END: + if (priv->recved > 0) { + /* Received whole packet. */ + /* Trim the pbuf to the size of the received packet. */ + pbuf_realloc(priv->q, priv->recved); + + LINK_STATS_INC(link.recv); + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); + t = priv->q; + priv->p = priv->q = NULL; + priv->i = priv->recved = 0; + return t; + } + return NULL; + case SLIP_ESC: + priv->state = SLIP_RECV_ESCAPE; + return NULL; + } /* end switch (c) */ + break; + case SLIP_RECV_ESCAPE: + /* un-escape END or ESC bytes, leave other bytes + (although that would be a protocol error) */ + switch (c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + priv->state = SLIP_RECV_NORMAL; + break; + } /* end switch (priv->state) */ + + /* byte received, packet not yet completely received */ + if (priv->p == NULL) { + /* allocate a new pbuf */ + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); + priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN), PBUF_POOL); + + if (priv->p == NULL) { + LINK_STATS_INC(link.drop); + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); + /* don't process any further since we got no pbuf to receive to */ + return NULL; + } + + if (priv->q != NULL) { + /* 'chain' the pbuf to the existing chain */ + pbuf_cat(priv->q, priv->p); + } else { + /* p is the first pbuf in the chain */ + priv->q = priv->p; + } + } + + /* this automatically drops bytes if > SLIP_MAX_SIZE */ + if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { + ((u8_t *)priv->p->payload)[priv->i] = c; + priv->recved++; + priv->i++; + if (priv->i >= priv->p->len) { + /* on to the next pbuf */ + priv->i = 0; + if (priv->p->next != NULL && priv->p->next->len > 0) { + /* p is a chain, on to the next in the chain */ + priv->p = priv->p->next; + } else { + /* p is a single pbuf, set it to NULL so next time a new + * pbuf is allocated */ + priv->p = NULL; + } + } + } + return NULL; +} + +/** Like slipif_rxbyte, but passes completed packets to netif->input + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +static void +slipif_rxbyte_input(struct netif *netif, u8_t c) +{ + struct pbuf *p; + p = slipif_rxbyte(netif, c); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + } +} + +#if SLIP_USE_RX_THREAD +/** + * The SLIP input thread. + * + * Feed the IP layer with incoming packets + * + * @param nf the lwip network interface structure for this slipif + */ +static void +slipif_loop_thread(void *nf) +{ + u8_t c; + struct netif *netif = (struct netif *)nf; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + + while (1) { + if (sio_read(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } + } +} +#endif /* SLIP_USE_RX_THREAD */ + +/** + * SLIP netif initialization + * + * Call the arch specific sio_open and remember + * the opened device in the state field of the netif. + * + * @param netif the lwip network interface structure for this slipif + * @return ERR_OK if serial line could be opened, + * ERR_MEM if no memory could be allocated, + * ERR_IF is serial line couldn't be opened + * + * @note netif->num must contain the number of the serial port to open + * (0 by default). If netif->state is != NULL, it is interpreted as an + * u8_t pointer pointing to the serial port number instead of netif->num. + * + */ +err_t +slipif_init(struct netif *netif) +{ + struct slipif_priv *priv; + u8_t sio_num; + + LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); + + /* Allocate private data */ + priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); + if (!priv) { + return ERR_MEM; + } + + netif->name[0] = 's'; + netif->name[1] = 'l'; + netif->output = slipif_output_v4; +#if LWIP_IPV6 + netif->output_ip6 = slipif_output_v6; +#endif /* LWIP_IPV6 */ + netif->mtu = SLIP_MAX_SIZE; + netif->flags |= NETIF_FLAG_POINTTOPOINT; + + /* netif->state or netif->num contain the port number */ + if (netif->state != NULL) { + sio_num = *(u8_t*)netif->state; + } else { + sio_num = netif->num; + } + /* Try to open the serial port. */ + priv->sd = sio_open(sio_num); + if (!priv->sd) { + /* Opening the serial port failed. */ + mem_free(priv); + return ERR_IF; + } + + /* Initialize private data */ + priv->p = NULL; + priv->q = NULL; + priv->state = SLIP_RECV_NORMAL; + priv->i = 0; + priv->recved = 0; +#if SLIP_RX_FROM_ISR + priv->rxpackets = NULL; +#endif + + netif->state = priv; + + /* initialize the snmp variables and counters inside the struct netif */ + NETIF_INIT_SNMP(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); + +#if SLIP_USE_RX_THREAD + /* Create a thread to poll the serial line. */ + sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, + SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); +#endif /* SLIP_USE_RX_THREAD */ + return ERR_OK; +} + +/** + * Polls the serial device and feeds the IP layer with incoming packets. + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_poll(struct netif *netif) +{ + u8_t c; + struct slipif_priv *priv; + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + while (sio_tryread(priv->sd, &c, 1) > 0) { + slipif_rxbyte_input(netif, c); + } +} + +#if SLIP_RX_FROM_ISR +/** + * Feeds the IP layer with incoming packets that were receive + * + * @param netif The lwip network interface structure for this slipif + */ +void +slipif_process_rxqueue(struct netif *netif) +{ + struct slipif_priv *priv; + SYS_ARCH_DECL_PROTECT(old_level); + + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + priv = (struct slipif_priv *)netif->state; + + SYS_ARCH_PROTECT(old_level); + while (priv->rxpackets != NULL) { + struct pbuf *p = priv->rxpackets; +#if SLIP_RX_QUEUE + /* dequeue packet */ + struct pbuf *q = p; + while ((q->len != q->tot_len) && (q->next != NULL)) { + q = q->next; + } + priv->rxpackets = q->next; + q->next = NULL; +#else /* SLIP_RX_QUEUE */ + priv->rxpackets = NULL; +#endif /* SLIP_RX_QUEUE */ + SYS_ARCH_UNPROTECT(old_level); + if (netif->input(p, netif) != ERR_OK) { + pbuf_free(p); + } + SYS_ARCH_PROTECT(old_level); + } +} + +/** Like slipif_rxbyte, but queues completed packets. + * + * @param netif The lwip network interface structure for this slipif + * @param data Received serial byte + */ +static void +slipif_rxbyte_enqueue(struct netif *netif, u8_t data) +{ + struct pbuf *p; + struct slipif_priv *priv = (struct slipif_priv *)netif->state; + SYS_ARCH_DECL_PROTECT(old_level); + + p = slipif_rxbyte(netif, data); + if (p != NULL) { + SYS_ARCH_PROTECT(old_level); + if (priv->rxpackets != NULL) { +#if SLIP_RX_QUEUE + /* queue multiple pbufs */ + struct pbuf *q = p; + while(q->next != NULL) { + q = q->next; + } + q->next = p; + } else { +#else /* SLIP_RX_QUEUE */ + pbuf_free(priv->rxpackets); + } + { +#endif /* SLIP_RX_QUEUE */ + priv->rxpackets = p; + } + SYS_ARCH_UNPROTECT(old_level); + } +} + +/** + * Process a received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + */ +void +slipif_received_byte(struct netif *netif, u8_t data) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + slipif_rxbyte_enqueue(netif, data); +} + +/** + * Process multiple received byte, completed packets are put on a queue that is + * fed into IP through slipif_process_rxqueue(). + * + * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. + * + * @param netif The lwip network interface structure for this slipif + * @param data received character + * @param len Number of received characters + */ +void +slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) +{ + u8_t i; + u8_t *rxdata = data; + LWIP_ASSERT("netif != NULL", (netif != NULL)); + LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); + + for (i = 0; i < len; i++, rxdata++) { + slipif_rxbyte_enqueue(netif, *rxdata); + } +} +#endif /* SLIP_RX_FROM_ISR */ + +#endif /* LWIP_HAVE_SLIPIF */ diff --git a/USDK/component/common/network/mDNS/mDNS.h b/USDK/component/common/network/mDNS/mDNS.h new file mode 100644 index 0000000..e9e9b17 --- /dev/null +++ b/USDK/component/common/network/mDNS/mDNS.h @@ -0,0 +1,26 @@ +#ifndef _MDNS_H +#define _MDNS_H + +#include + +/* Text Record */ +typedef struct _TXTRecordRef_t { + char PrivateData[16]; +} TXTRecordRef; + +extern void TXTRecordCreate(TXTRecordRef *txtRecord, uint16_t bufferLen, void *buffer); +extern int TXTRecordSetValue(TXTRecordRef *txtRecord, const char *key, uint8_t valueSize, const void *value); +extern void TXTRecordDeallocate(TXTRecordRef *txtRecord); + +/* mDNS */ +typedef void *DNSServiceRef; + +extern int mDNSResponderInit(void); +extern void mDNSResponderDeinit(void); +extern DNSServiceRef mDNSRegisterService(char *name, char *service_type, char *domain, unsigned short port, TXTRecordRef *txtRecord); +extern void mDNSDeregisterService(DNSServiceRef serviceRef); +extern void mDNSUpdateService(DNSServiceRef serviceRef, TXTRecordRef *txtRecord, unsigned int ttl); +extern void mDNSRegisterAllInterfaces(void); +extern void mDNSDeregisterAllInterfaces(void); + +#endif /* _MDNS_H */ diff --git a/USDK/component/common/network/mDNS/mDNSPlatform.c b/USDK/component/common/network/mDNS/mDNSPlatform.c new file mode 100644 index 0000000..54fb774 --- /dev/null +++ b/USDK/component/common/network/mDNS/mDNSPlatform.c @@ -0,0 +1,37 @@ +#include +#include +extern struct netif xnetif[]; + +/*----------------------------------------------------------------------- + * Mandatory functions + *-----------------------------------------------------------------------*/ + +// Mandatory function for custom initialization +// called when mDNS initialization +void mDNSPlatformCustomInit(void) +{ + xnetif[0].flags |= NETIF_FLAG_IGMP; +} + +uint16_t mDNSPlatformHtons(uint16_t hostshort) +{ + return htons(hostshort); +} + +uint32_t mDNSPlatformInetAddr(char *cp) +{ + return inet_addr(cp); +} + +// Mandatory function to get hostname +// called when mDNS initialization +_WEAK char *mDNSPlatformHostname(void) +{ +#if LWIP_NETIF_HOSTNAME + return xnetif[0].hostname; +#else + return DEF_HOSTNAME; +#endif +} + +/*-----------------------------------------------------------------------*/ diff --git a/USDK/component/common/network/netbios/netbios.c b/USDK/component/common/network/netbios/netbios.c new file mode 100644 index 0000000..cb0db96 --- /dev/null +++ b/USDK/component/common/network/netbios/netbios.c @@ -0,0 +1,389 @@ +/** + * @file + * NetBIOS name service sample + * https://tools.ietf.org/html/rfc1002 + * Modified for RTL871x pvvx + */ + +#if 1 // def USE_NETBIOS + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + */ +#include "rtl8195a/rtl_common.h" +#include "rtl8195a.h" + +//#include "lwip/opt.h" +#include "netbios/netbios.h" + +#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ + +#include + +#include "ipv4/lwip/ip.h" +#include "lwip/udp.h" +#include "lwip/netif.h" +#include "lwip_netconf.h" +#include "platform/esp_comp.h" + +#define NETBIOS_CODE_ATTR +#define NETBIOS_DATA_ATTR + +extern struct netif xnetif[NET_IF_NUM]; + +#define NBS_DEF_NAME DEF_HOSTNAME + +/** This is an example implementation of a NetBIOS name server. + * It responds to name queries for a configurable name. + * Name resolving is not supported. + * + * Note that the device doesn't broadcast it's own name so can't + * detect duplicate names! + */ + +/** Since there's no standard function for case-insensitive string comparision, + * we need another define here: + * define this to stricmp() for windows or strcasecmp() for linux. + * If not defined, comparision is case sensitive and NETBIOS_LWIP_NAME must be + * uppercase + */ +#ifndef NETBIOS_STRCMP +#define NETBIOS_STRCMP(str1, str2) os_strcmp(str1, str2) +#endif + +/** default port number for "NetBIOS Name service */ +//#define NETBIOS_PORT 137 +/** NetBIOS name of LWIP device + * This must be uppercase until NETBIOS_STRCMP() is defined to a string + * comparision function that is case insensitive. + * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): + * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") + */ + +/** size of a NetBIOS name */ +//#define NETBIOS_NAME_LEN 16 // in netbios.h +char netbios_name[NET_IF_NUM][NETBIOS_NAME_LEN + 1]; // default netifs: 0 - SoftAP, 1 - Station, 2 - Ethernet + +/** The Time-To-Live for NetBIOS name responds (in seconds) + * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ +#define NETBIOS_NAME_TTL 300000 + +/** NetBIOS header flags */ +#define NETB_HFLAG_RESPONSE 0x8000U +#define NETB_HFLAG_OPCODE 0x7800U +#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U +#define NETB_HFLAG_AUTHORATIVE 0x0400U +#define NETB_HFLAG_TRUNCATED 0x0200U +#define NETB_HFLAG_RECURS_DESIRED 0x0100U +#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U +#define NETB_HFLAG_BROADCAST 0x0010U +#define NETB_HFLAG_REPLYCODE 0x0008U +#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U + +/** NetBIOS name flags */ +#define NETB_NFLAG_UNIQUE 0x8000U +#define NETB_NFLAG_NODETYPE 0x6000U +#define NETB_NFLAG_NODETYPE_HNODE 0x6000U +#define NETB_NFLAG_NODETYPE_MNODE 0x4000U +#define NETB_NFLAG_NODETYPE_PNODE 0x2000U +#define NETB_NFLAG_NODETYPE_BNODE 0x0000U + +/** NetBIOS message header */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_hdr { + PACK_STRUCT_FIELD(u16_t trans_id); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(u16_t questions); + PACK_STRUCT_FIELD(u16_t answerRRs); + PACK_STRUCT_FIELD(u16_t authorityRRs); + PACK_STRUCT_FIELD(u16_t additionalRRs); +}PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message name part */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_name_hdr { + PACK_STRUCT_FIELD(u8_t nametype); + PACK_STRUCT_FIELD(u8_t encname[(NETBIOS_NAME_LEN*2)+1]); + PACK_STRUCT_FIELD(u16_t type); + PACK_STRUCT_FIELD(u16_t cls); + PACK_STRUCT_FIELD(u32_t ttl); + PACK_STRUCT_FIELD(u16_t datalen); + PACK_STRUCT_FIELD(u16_t flags); + PACK_STRUCT_FIELD(ip_addr_p_t addr); +}PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/** NetBIOS message */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct netbios_resp { + struct netbios_hdr resp_hdr; + struct netbios_name_hdr resp_name; +}PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +//#define toupper(CH) \ +// (((CH) >= 'a' && (CH) <= 'z') ? ((CH) - 'a' + 'A') : (CH)) + + +/** NetBIOS decoding name */ +static int8_t NETBIOS_CODE_ATTR NBNS_decode(char *dst, char *src) +{ + uint8_t i, j; + char c; + + for(i=0, j=0; i<15; i++) + { + c = (src[j++]-'A')<<4; + c |= (src[j++]-'A')<<0; + if(c == ' ') + { + break; + } + dst[i] = toupper(c); + } + dst[i] = 0; + + return (((src[30]-'A')<<4)|(src[31]-'A')); // 0x00 = Workstation +} + +#if 0 +/** NetBIOS encoding name */ +static void NBNS_encode(char *dst, char *src, uint8_t type) +{ + uint8_t i, j; + char c; + + //encode name + for(i=0, j=0; (i<15) && src[i]; i++) + { + c = toupper(src[i]); + dst[j++] = 'A'+((c>>4)&0x0f); + dst[j++] = 'A'+((c>>0)&0x0f); + } + + //add spaces + for(; i<15; i++) + { + dst[j++] = 'A'+((' '>>4)&0x0f); + dst[j++] = 'A'+((' '>>0)&0x0f); + } + + //set type (0x00 = Workstation) + dst[j++] = 'A'+((type>>4)&0x0f); + dst[j++] = 'A'+((type>>0)&0x0f); +} +#endif + +/** NetBIOS Name service recv callback */ +static void NETBIOS_CODE_ATTR +netbios_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, + u16_t port) { + LWIP_UNUSED_ARG(arg); + /* if packet is valid */ + if (p != NULL && p->len >= sizeof(struct netbios_hdr) + sizeof(struct netbios_name_hdr) - 12) { + if (current_netif != NULL && current_netif->num < NET_IF_NUM) { + uint32 ip = current_netif->ip_addr.addr; + char *curbiosname = netbios_name[current_netif->num]; + if (curbiosname[0] != '\0' && ip != NULL + /* we only answer if we got a default interface */ + && (((ip ^ addr->addr) & current_netif->netmask.addr) == 0)) { // запрет ответа другой подсети +#if DEBUGSOO > 3 + os_printf("nbns: " IPSTR ",\t'%s'\n", IP2STR(&ip), curbiosname); +#endif + char netbiosname[NETBIOS_NAME_LEN + 1]; + os_memset(netbiosname, 0, sizeof(netbiosname)); + struct netbios_hdr* netbios_hdr = + (struct netbios_hdr*) p->payload; + struct netbios_name_hdr* netbios_name_hdr = + (struct netbios_name_hdr*) (netbios_hdr + 1); + /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ + /* if the packet is a NetBIOS name query question */ + if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) + == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) + && ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) + == 0) + && (netbios_hdr->questions == PP_NTOHS(1)) + && (netbios_name_hdr->cls == PP_NTOHS(1)) + && (netbios_name_hdr->type == PP_NTOHS(0x20))) { + /* decode the NetBIOS name */ + int8_t ret = NBNS_decode(netbiosname, + (char*) (netbios_name_hdr->encname)); + /* if the packet is for us */ +#if DEBUGSOO > 2 + if (ret == 0) os_printf("nbns: get " IPSTR ", '%s'\n", IP2STR(addr), + netbiosname); +#endif + if (ret == 0 && NETBIOS_STRCMP(curbiosname, netbiosname) == 0) { // netbiosname[0] == '*' +#if DEBUGSOO > 1 + os_printf("nbns: out " IPSTR ", '%s'\n", IP2STR(&ip), + curbiosname); +#endif + struct pbuf *q; + struct netbios_resp *resp; + + q = pbuf_alloc(PBUF_TRANSPORT, + sizeof(struct netbios_resp), PBUF_RAM); + if (q != NULL) { + resp = (struct netbios_resp*) q->payload; + + /* prepare NetBIOS header response */ + resp->resp_hdr.trans_id = netbios_hdr->trans_id; + resp->resp_hdr.flags = + PP_HTONS( + NETB_HFLAG_RESPONSE | NETB_HFLAG_OPCODE_NAME_QUERY | NETB_HFLAG_AUTHORATIVE | NETB_HFLAG_RECURS_DESIRED); + resp->resp_hdr.questions = 0; + resp->resp_hdr.answerRRs = PP_HTONS(1); + resp->resp_hdr.authorityRRs = 0; + resp->resp_hdr.additionalRRs = 0; + + /* prepare NetBIOS header datas */ + MEMCPY(resp->resp_name.encname, + netbios_name_hdr->encname, + sizeof(netbios_name_hdr->encname)); + resp->resp_name.nametype = + netbios_name_hdr->nametype; + resp->resp_name.type = netbios_name_hdr->type; + resp->resp_name.cls = netbios_name_hdr->cls; + resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); + resp->resp_name.datalen = PP_HTONS( + sizeof(resp->resp_name.flags) + + sizeof(resp->resp_name.addr)); + resp->resp_name.flags = PP_HTONS( + NETB_NFLAG_NODETYPE_BNODE); + + resp->resp_name.addr.addr = ip; // netif_default->ip_addr.addr; + /* send the NetBIOS response */ + udp_sendto(upcb, q, addr, port); + /* free the "reference" pbuf */ + pbuf_free(q); + } + } + } + } + } + /* free the pbuf */ + pbuf_free(p); + } +} + +struct udp_pcb * NETBIOS_CODE_ATTR netbios_pcb(void) { + struct udp_pcb *pcb; + for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { + if (pcb->local_port == NETBIOS_PORT) + return pcb; + } + return NULL; +} + +/* default netifs/interfacenum: 0 - SoftAP, 1 - Station, 2 - Ethernet */ + +bool NETBIOS_CODE_ATTR netbios_set_name(unsigned char interfacenum, char * name) { + if (interfacenum >= NET_IF_NUM) + return false; + int i; + uint8 * pnbn = netbios_name[interfacenum]; + uint8 * pmane = name; + if (name != NULL) { + for (i = 0; i < NETBIOS_NAME_LEN; i++) { + if (*pmane < ' ') + break; + else if (*pmane == ' ') + *pnbn++ = '_'; + else + *pnbn++ = toupper(*pmane); + pmane++; + }; + }; + *pnbn = '\0'; + return true; +} + +bool NETBIOS_CODE_ATTR netbios_off(void) { + struct udp_pcb *pcb = netbios_pcb(); + if (pcb == NULL) + return false; + udp_remove(pcb); + return true; +} + +void NETBIOS_CODE_ATTR netbios_init(void) { + struct udp_pcb *pcb; + char buf[NETBIOS_NAME_LEN]; + if (netbios_pcb() != NULL) + return; + + for(int i = 0; i < NET_IF_NUM; i++) { + if (netbios_name[i][0] == 0) { +#if LWIP_NETIF_HOSTNAME + if(xnetif[i].hostname != 0) { + netbios_set_name(i, xnetif[i].hostname); + } + else +#endif + { + sprintf(buf, NBS_DEF_NAME "%d", i); + netbios_set_name(i, buf); + }; + }; + }; + +#if DEBUGSOO > 1 + os_printf("NetBIOS init, interface "); + for(int i = 0; i < NET_IF_NUM; i++) { + os_printf("%d: '%s' ", i, netbios_name[i]); + } + os_printf("\n"); +#endif + pcb = udp_new(); + if (pcb != NULL) { + /* we have to be allowed to send broadcast packets! */ + pcb->so_options |= SOF_BROADCAST; + udp_bind(pcb, IP_ADDR_ANY, NETBIOS_PORT); + udp_recv(pcb, netbios_recv, pcb); + } +} +#endif /* LWIP_UDP */ + +#endif // USE_NETBIOS diff --git a/USDK/component/common/network/netbios/netbios.h b/USDK/component/common/network/netbios/netbios.h new file mode 100644 index 0000000..a843cc1 --- /dev/null +++ b/USDK/component/common/network/netbios/netbios.h @@ -0,0 +1,33 @@ +#ifndef __NETBIOS_H__ +#define __NETBIOS_H__ + +#include "lwip/opt.h" + +/** default port number for "NetBIOS Name service */ +#define NETBIOS_PORT 137 + +/** size of a NetBIOS name */ +#define NETBIOS_NAME_LEN 16 + +#ifndef NET_IF_NUM +#define NET_IF_NUM 2 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +//#if LWIP_NETIF_HOSTNAME +extern char netbios_name[NET_IF_NUM][NETBIOS_NAME_LEN + 1]; // default netifs/interfacenum: 0 - SoftAP, 1 - Station, 2 - Ethernet +//#endif + +// struct udp_pcb * netbios_pcb(void); +void netbios_init(void); +bool netbios_set_name(unsigned char interfacenum, char * name); // default netifs/interfacenum: 0 - SoftAP, 1 - Station, 2 - Ethernet +bool netbios_off(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETBIOS_H__ */ diff --git a/USDK/component/common/network/rtsp/rtp_api.h b/USDK/component/common/network/rtsp/rtp_api.h new file mode 100644 index 0000000..80ead3d --- /dev/null +++ b/USDK/component/common/network/rtsp/rtp_api.h @@ -0,0 +1,134 @@ +#ifndef _RTP_API_H_ +#define _RTP_API_H_ + +#include "dlist.h" +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" +#include "avcodec.h" +#include //for host network byte order convertion + +/* from error_base.h */ +#define EIO 5 /* I/O error */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EINVAL 22 /* Invalid argument */ + +#define RTP_BIG_ENDIAN 0 +#define RTP_HDR_SZ 12 + +#define RTP_SERVER_PORT_BASE 55608 +#define RTP_PORT_BASE 50020 +#define RTP_CLIENT_PORT_BASE 51020 +/* + * RTP data header from RFC1889 + */ +/* + * + * + * The RTP header has the following format: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |V=2|P|X| CC |M| PT | sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | timestamp | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | synchronization source (SSRC) identifier | + * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * | contributing source (CSRC) identifiers | + * | .... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * RTP data header + */ + +typedef struct { +#if RTP_BIG_ENDIAN + u16 version:2; /* protocol version */ + u16 p:1; /* padding flag */ + u16 x:1; /* header extension flag */ + u16 cc:4; /* CSRC count */ + u16 m:1; /* marker bit */ + u16 pt:7; /* payload type */ +#else /*RTP_LITTLE_ENDIAN*/ + u16 cc:4; /* CSRC count */ + u16 x:1; /* header extension flag */ + u16 p:1; /* padding flag */ + u16 version:2; /* protocol version */ + u16 pt:7; /* payload type */ + u16 m:1; /* marker bit */ +#endif + u16 seq; /* sequence number */ + u32 ts; /* timestamp */ + u32 ssrc; /* synchronization source */ + u32 *csrc; /* optional CSRC list, skip if cc is set to 0 here*/ +} rtp_hdr_t; + +/*sturcture to hold connect info*/ +struct connect_context +{ + int socket_id; + u8 *server_ip; + u16 server_port; + u8 *remote_ip; + u16 remote_port; +}; + +struct rtp_statistics +{ + u32 rtp_tick; + u32 rtp_tick_inc; + u32 base_timestamp; + /*for flow control*/ + u32 delay_threshold; //in ms + u32 timer1; //time before send + u32 timer2; //time after sent + u32 delta_timer; + u8 do_start_check; //indicate if start check need to be done + u32 sent_packet; + u32 drop_packet; +}; + +enum rtp_object_state +{ + RTP_OBJECT_IDLE = 0, + RTP_OBJECT_READY, + RTP_OBJECT_INUSE, + RTP_OBJECT_USED, +}; + +struct stream_context; +struct rtp_object; + +struct rtp_object +{ + struct list_head rtp_list; + _mutex list_lock; + rtp_hdr_t *rtphdr; + void *extra; //pointer to type specific structure + int index; //respective internal buffer index + u8 *data; // respective internal buffer data addr + int len; //one complete frame data length + u32 timestamp; //timestamp + u32 fs:1; //fragment start + u32 fe:1; //fragment end + u32 fk:1; //fragment keep indicator so that cannot avoid sending by flow control + u32 fd:29; //fragment data size (max size of 2^29-1) + enum rtp_object_state state; + struct connect_context connect_ctx; + int (*rtp_object_handler)(struct stream_context *stream_ctx, struct rtp_object *payload); +}; + +void rtp_object_init(struct rtp_object *payload); +void rtp_object_deinit(struct rtp_object *payload); +void rtp_object_set_fs(struct rtp_object *payload, int flag); +void rtp_object_set_fe(struct rtp_object *payload, int flag); +void rtp_object_set_fk(struct rtp_object *payload, int flag); +void rtp_object_set_fd(struct rtp_object *payload, int size); +void rtp_load_o_handler_by_codec_id(struct rtp_object *payload, int id); +void rtp_fill_header(rtp_hdr_t *rtphdr, int version, int padding, int extension, int cc, int marker, int pt, u16 seq, u32 ts, u32 ssrc); +int rtp_parse_header(u8 *src, rtp_hdr_t *rtphdr, int is_nbo); +void rtp_dump_header(rtp_hdr_t *rtphdr, int is_nbo); +#endif \ No newline at end of file diff --git a/USDK/component/common/network/rtsp/rtsp_api.h b/USDK/component/common/network/rtsp/rtsp_api.h new file mode 100644 index 0000000..7bc7fa5 --- /dev/null +++ b/USDK/component/common/network/rtsp/rtsp_api.h @@ -0,0 +1,336 @@ +#ifndef _RTSP_H_ +#define _RTSP_H_ + +#include "dlist.h" +#include "osdep_api.h" +#include "avcodec.h" + +#define RTSP_DEBUG 0 + +#if RTSP_DEBUG +#define RTSP_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define RTSP_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define RTSP_PRINTF(fmt, args...) +#define RTSP_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#endif + + +/*******************************************************general***************************************************************************/ + +struct stream_context +{ + struct list_head payload_entry; + _Mutex entry_lock; + _Sema sema; + void *protoCtx; // tranport layer protocol info.(eg.RTSP/HTTP) + int isProcess; + int allowStream; + int pt; //payload type + struct codec_info codec; + void *priv; // pointer to private data +}; + +/************************************************************** start of rtsp *************************************************************/ + +/*rtsp command list*/ +#define CMD_OPTIONS 1 +#define CMD_DESCRIBE 2 +#define CMD_SETUP 3 +#define CMD_TEARDOWN 4 +#define CMD_PLAY 5 +#define CMD_PAUSE 6 + +/*rtsp cast mode list*/ +#define UNICAST_UDP_MODE 1 +#define UNICAST_TCP_MODE 2 +#define MULTICAST_MODE 3 + +#define CRLF "\r\n" +#define BOUNDARY "amebaimagetest" +#define RTSP_RESPONSE_SIZE 512 //max size for request/response buffer +#define SERVER_PORT_RANGE_MIN 55608 +#define SERVER_PORT_RANGE_MAX 55625 +#define PORT_RANGE_MIN 50020 +#define PORT_RANGE_MAX 50036 + +#if (SERVER_PORT_RANGE_MIN >= SERVER_PORT_RANGE_MAX) || (PORT_RANGE_MIN >= PORT_RANGE_MAX) + #error "port range invalid" +#endif +#if ((SERVER_PORT_RANGE_MIN%2) != 0) || ((PORT_RANGE_MIN%2) != 0) + #error "minimal port value should be even" +#endif + +#define DEF_RTSP_PORT 554 +#define DEF_HTTP_PORT 5008 + +/************************************************************** end of rtsp *************************************************************/ + +/************************************************************** start of rtp **************************************************************/ + +#define DEF_RTP_PORT 27750 +#define RTP_BIG_ENDIAN 0 +#define RTP_HDR_SZ 12 +/*rtp payload type mapping and standard rtp payload type table*/ +#define RTP_PT_PCMU 0 +#define RTP_PT_GSM 3 +#define RTP_PT_G723 4 +#define RTP_PT_DVI4_R8000 5 +#define RTP_PT_DVI4_R16000 6 +#define RTP_PT_LPC 7 +#define RTP_PT_PCMA 8 +#define RTP_PT_G722 9 +#define RTP_PT_L16_C2 10 +#define RTP_PT_L16_C1 11 +#define RTP_PT_QCELP 12 +#define RTP_PT_CN 13 +#define RTP_PT_MPA 14 +#define RTP_PT_G728 15 +#define RTP_PT_DVI4_R11025 16 +#define RTP_PT_DVI4_R22050 17 +#define RTP_PT_G719 18 +#define RTP_PT_CELB 25 +#define RTP_PT_JPEG 26 +#define RTP_PT_NV 28 +#define RTP_PT_H261 31 +#define RTP_PT_MPV 32 +#define RTP_PT_MP2T 33 +#define RTP_PT_H263 34 +#define RTP_PT_RTCP_BASE 72 +#define RTP_PT_DYN_BASE 96 +#define RTP_PT_UNKNOWN -1 + +#include "section_config.h" +SDRAM_DATA_SECTION +static const struct { + int pt; //payload type + const char enc_name[6]; + int clock_rate; + int audio_channels; + } rtp_payload_types[] = { + //{0, "PCMU", 8000, 1}, + //{3, "GSM", 8000, 1}, + //{4, "G723", 8000, 1}, + //{5, "DVI4", 8000, 1}, + //{6, "DVI4", 16000, 1}, + //{7, "LPC", 8000, 1}, + //{8, "PCMA", 8000, 1}, + //{9, "G722", 8000, 1}, + //{10, "L16", 44100, 2}, + //{11, "L16", 44100, 1}, + //{12, "QCELP", 8000, 1}, + //{13, "CN", 8000, 1}, + //{14, "MPA", -1, -1}, + //{15, "G728", 8000, 1}, + //{16, "DVI4", 11025, 1}, + //{17, "DVI4", 22050, 1}, + //{18, "G729", 8000, 1}, + //{25, "CelB", 90000, -1}, + {26, "JPEG", 90000, -1}, + //{28, "nv", 90000, -1}, + //{31, "H261", 90000, -1}, + //{32, "MPV", 90000, -1}, + //{33, "MP2T", 90000, -1}, + //{34, "H263", 90000, -1}, + {-1, "", -1, -1} +}; + +#define RTP_STD_PT_SIZE /*25*/ 2 //length of rtp_payload_types + +/************************************************************** end of rtp **************************************************************/ + +/************************************************************** start of rtcp *************************************************************/ +#define RTP_SEQ_MOD (1<<16) +#define RTP_MAX_SDES 255 /* maximum text length for SDES */ + +typedef enum { + RTCP_SR = 200, + RTCP_RR = 201, + RTCP_SDES = 202, + RTCP_BYE = 203, + RTCP_APP = 204 +} rtcp_type_t; + +typedef enum { + RTCP_SDES_END = 0, + RTCP_SDES_CNAME = 1, + RTCP_SDES_NAME = 2, + RTCP_SDES_EMAIL = 3, + RTCP_SDES_PHONE = 4, + RTCP_SDES_LOC = 5, + RTCP_SDES_TOOL = 6, + RTCP_SDES_NOTE = 7, + RTCP_SDES_PRIV = 8 +} rtcp_sdes_type_t; + +/************************************************************** end of rtcp *************************************************************/ + +/************************************************************** start of rtsp *************************************************************/ + +typedef enum _rtsp_state rtsp_state; +enum _rtsp_state { + RTSP_INIT = 0, + RTSP_READY = 1, + RTSP_PLAYING = 2, +}; + +struct rtsp_session +{ + int id; + int version; + int start_time; + int end_time; + unsigned char *user; + unsigned char *name; +}; + +struct rtsp_transport +{ + int isRtp; //transport protocol + int isTcp; //lower transport protocol + int castMode; //unicast UDP(1) or unicast TCP(2) or multicast(3) + int port_min; + int port_max; + int clientport_min; + int clientport_max; + int serverport_min; + int serverport_max; + int ttl; //multicast time to live + //to be added if necessary +}; + +/*sturcture to hold connect info*/ +struct connect_context +{ + int socket_id; + u16 port; + unsigned char *server_ip; + unsigned char *remote_ip; +}; + + +struct rtsp_context +{ + rtsp_state state; //state for rtp streaming + int rtsp_cmd; //store request method type + int Cseq; + struct rtsp_transport transport; + struct rtsp_session session; + u8 *response; //enough to hold response + int content_len; + struct connect_context connect_ctx; //contain rtsp server info. + void *stream_ctx; //stream context it process + _Sema start_rtp_sema; //sema to start rtp processing + int is_rtp_start; + //to be added if necessary +}; + +/************************************************************** end of rtsp *************************************************************/ + +/************************************************************** start of rtp **************************************************************/ + + +/* + * RTP data header from RFC1889 + */ +/* + * + * + * The RTP header has the following format: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |V=2|P|X| CC |M| PT | sequence number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | timestamp | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | synchronization source (SSRC) identifier | + * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + * | contributing source (CSRC) identifiers | + * | .... | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * RTP data header + */ + +typedef struct { +#if RTP_BIG_ENDIAN + unsigned int version:2; /* protocol version */ + unsigned int p:1; /* padding flag */ + unsigned int x:1; /* header extension flag */ + unsigned int cc:4; /* CSRC count */ + unsigned int m:1; /* marker bit */ + unsigned int pt:7; /* payload type */ +#else /*RTP_LITTLE_ENDIAN*/ + unsigned int cc:4; /* CSRC count */ + unsigned int x:1; /* header extension flag */ + unsigned int p:1; /* padding flag */ + unsigned int version:2; /* protocol version */ + unsigned int pt:7; /* payload type */ + unsigned int m:1; /* marker bit */ +#endif + u16 seq; /* sequence number */ + u32 ts; /* timestamp */ + u32 ssrc; /* synchronization source */ +// u32 csrc[1]; /* optional CSRC list, skip because cc is set to 0 here*/ +} rtp_hdr_t; + +enum rtp_object_state +{ + RTP_OBJECT_IDLE = 1, + RTP_OBJECT_READY, + RTP_OBJECT_INUSE, + RTP_OBJECT_USED, +}; + +struct rtp_object +{ + struct list_head rtp_list; + _Mutex mutex; + rtp_hdr_t rtphdr; + u32 *extra; //pointer to type specific structure + int index; + unsigned char *data; + int len; + enum rtp_object_state state; //reserved for future use + struct connect_context connect_ctx; +}; + +/************************************************************** end of rtp **************************************************************/ + +/***************************************************************general******************************************************************/ +void stream_context_init(struct stream_context *stream_ctx); +void stream_context_free(struct stream_context *stream_ctx); + +/************************************************************** start of rtsp *************************************************************/ + +int rtsp_atoi(char * s); +int rtsp_context_init(struct rtsp_context *rtsp_ctx); +void rtsp_readheader(u8 *request_header); +u8 * rtsp_parsefield(u8 *buffer, char *field); //parse specific field line and return field data +u8 * rtsp_readline(struct rtsp_context *rtsp_ctx, u8 *ptr); //read line starting from ptr and store corresponding parameter in rtsp_ctx +void rtsp_getparam(struct rtsp_context *rtsp_ctx, u8 *rtsp_header); +void parse_rtsp_type(struct rtsp_context *rtsp_ctx, u8 *rtsp_header); +int rtp_tick_inc_to_fps(int tick_inc, int clock_rate); +int rtp_fps_to_tick_inc(int framerate, int clock_rate); +void gen_session_id(int *session_id); +void rtsp_formSdp(struct rtsp_context *rtsp_ctx, u8 *sdp_buffer, int size); +void rtsp_cmd_options(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_describe(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_setup(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_play(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_pause(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_teardown(struct rtsp_context *rtsp_ctx); +void rtsp_cmd_error(struct rtsp_context *rtsp_ctx); +void rtsp_init(void *param); + +/************************************************************** end of rtsp *************************************************************/ + +/************************************************************** start of rtp **************************************************************/ + +void fillRtpHeader(rtp_hdr_t *rtphdr, int version, int padding, int extension, int cc, int marker, int pt, u16 seq, u32 ts, u32 ssrc); + +/************************************************************** end of rtp **************************************************************/ + +#endif \ No newline at end of file diff --git a/USDK/component/common/network/rtsp/sdp.h b/USDK/component/common/network/rtsp/sdp.h new file mode 100644 index 0000000..7d6f9fc --- /dev/null +++ b/USDK/component/common/network/rtsp/sdp.h @@ -0,0 +1,45 @@ + +#ifndef _SDP_H_ +#define _SDP_H_ + +/* select one codec profile, here we choose AV PROFILE*/ +#include "avcodec.h" + +#define MAX_SDP_SIZE 512 +#define SDP_LINE_LEN 128 + + +struct sdp_session_level { + int sdp_version; /**< protocol version (currently 0) */ + int id; /**< session ID */ + int version; /**< session version */ + int start_time; /**< session start time (NTP time, in seconds), or 0 in case of permanent session */ + int end_time; /**< session end time (NTP time, in seconds), or 0 if the session is not bounded */ + int ttl; /**< TTL, in case of multicast stream */ + const char *user; /**< username of the session's creator */ + const char *nettype; /**< type of network (initially "IN") */ + const char *src_addr; /**< IP address of the machine from which the session was created */ + const char *src_type; /**< address type of src_addr */ + const char *dst_addr; /**< destination IP address (can be multicast) */ + const char *dst_type; /**< destination IP address type */ + const char *name; /**< session name (can be an empty string) */ +}; + +struct sdp_media_level { + int media_type; + int payload_type; + int framerate; + struct codec_info *codec; +}; + +struct sdp_info { + struct sdp_session_level session; + struct sdp_media_level media; + void *extra; +}; + + +int form_sdp_header(unsigned char *buffer, struct sdp_info *sdp, int size); +int form_sdp_media(unsigned char *buffer, struct sdp_info *sdp, int size); + +#endif //_SDP_H_ \ No newline at end of file diff --git a/USDK/component/common/network/rtsp/src2rtsp.h b/USDK/component/common/network/rtsp/src2rtsp.h new file mode 100644 index 0000000..ccfa692 --- /dev/null +++ b/USDK/component/common/network/rtsp/src2rtsp.h @@ -0,0 +1,100 @@ +#ifndef _SRC2RTSP_H_ +#define _SRC2RTSP_H_ + +/* Add by Ian -- This file contains parts used for rtsp to access lower layer stream src information*/ + +#include "dlist.h" +#include "basic_types.h" +#include "osdep_service.h" +//#include "osdep_api.h" +#include "rtsp/rtp_api.h" +#include "avcodec.h" + +#define SRC_FROM_UVC +//#define SRC_FROM_UAC +//#define SRC_FROM_SPI +#define SRC_FROM_I2S +#define SRC_FROM_STA + +#define SRC_TYPE_NUL 0 +#define SRC_TYPE_UVC 1 +#define SRC_TYPE_SPI 2 +#define SRC_TYPE_UAC 3 +#define SRC_TYPE_I2S 4 +#define SRC_TYPE_STA 7 + +struct FormatInfo +{ + struct codec_info codec; + u8 framerate; + u32 bitrate; + u32 height; + u32 width; +}; + +struct stream_flow +{ + int id; + void *prot_hook; //transport protocol hook + void *src; + int src_type; + struct FormatInfo currentFormatInfo; + int (*src_handler) (void *src, struct rtp_object *payload); + struct list_head input_queue; + _mutex input_lock; + struct list_head output_queue; + _mutex output_lock; + u8 is_src2rtsp_init; + u8 is_src2rtsp_start; + _sema start_src2rtsp_sema; + struct stream_flow *next; +}; + + +#ifdef SRC_FROM_UVC +#include "v4l2_intf.h" +struct uvc_streaming; +struct uvcManager +{ + struct uvc_streaming *stream; + streaming_state state; + struct FormatInfo currentFormatInfo; +}; +#endif + +#ifdef SRC_FROM_SPI + +#endif + +#ifdef SRC_FROM_UAC + +#endif + +#ifdef SRC_FROM_I2S +struct i2sManager{ + struct FormatInfo currentFormatInfo; +}; + +#endif + +#ifdef SRC_FROM_STA +struct rtsp_static_source_manager +{ + struct FormatInfo currentFormatInfo; +}; +#endif + +struct stream_flow* rtsp_stream_flow_create(void); +void rtsp_stream_flow_free(struct stream_flow *stream); +void rtsp_register_src_handler(struct stream_flow *stream, int (*src_handler) (void *stream_src, struct rtp_object *payload)); +int rtsp_get_src_currentFormatInfo(struct stream_flow *stream); +int rtsp_set_src_FormatInfo(struct stream_flow *stream, int codec_id, u8 framerate, u32 height, u32 width, u32 bitrate); +extern int rtsp_set_src_extra(struct stream_flow, void *param); +int rtsp_stream_flow_set(struct stream_flow *stream, void *source, int src_type); +int rtsp_stream_flow_update(struct stream_flow *stream); +int rtsp_stream_flow_concat(struct stream_flow *stream, struct stream_flow *stream_next); +void rtp_object_in_src_queue(struct rtp_object *payload, struct stream_flow *stream); +struct rtp_object *rtp_object_out_src_queue(struct stream_flow *stream); + + +#endif \ No newline at end of file diff --git a/USDK/component/common/network/sntp/sntp.c b/USDK/component/common/network/sntp/sntp.c new file mode 100644 index 0000000..8289a58 --- /dev/null +++ b/USDK/component/common/network/sntp/sntp.c @@ -0,0 +1,660 @@ +/** + * @file + * SNTP client module + * + * This is simple "SNTP" client for the lwIP raw API. + * It is a minimal implementation of SNTPv4 as specified in RFC 4330. + * + * For a list of some public NTP servers, see this link : + * http://support.ntp.org/bin/view/Servers/NTPPoolServers + * + * @todo: + * - set/change servers at runtime + * - complete SNTP_CHECK_RESPONSE checks 3 and 4 + * - support broadcast/multicast mode? + */ + +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt (lwIP raw API part) + */ + +#include "lwip/opt.h" + +#include "sntp.h" + +#include "lwip/lwip_timers.h" +#include "lwip/udp.h" +#include "lwip/dns.h" +#include "lwip/ip_addr.h" +#include "lwip/pbuf.h" + +#include +#include + +#if LWIP_UDP + +/** + * SNTP_DEBUG: Enable debugging for SNTP. + */ +#ifndef SNTP_DEBUG +#define SNTP_DEBUG LWIP_DBG_OFF +#endif + +/** SNTP server port */ +#ifndef SNTP_PORT +#define SNTP_PORT 123 +#endif + +/** Set this to 1 to allow SNTP_SERVER_ADDRESS to be a DNS name */ +#ifndef SNTP_SERVER_DNS +#define SNTP_SERVER_DNS 1 +#endif + +/** Set this to 1 to support more than one server */ +#ifndef SNTP_SUPPORT_MULTIPLE_SERVERS +#define SNTP_SUPPORT_MULTIPLE_SERVERS 0 +#endif + +/** \def SNTP_SERVER_ADDRESS + * \brief SNTP server address: + * - as IPv4 address in "u32_t" format + * - as a DNS name if SNTP_SERVER_DNS is set to 1 + * May contain multiple server names (e.g. "pool.ntp.org","second.time.server") + */ +#ifndef SNTP_SERVER_ADDRESS +#if SNTP_SERVER_DNS +#define SNTP_SERVER_ADDRESS "pool.ntp.org" +#else +#define SNTP_SERVER_ADDRESS "213.161.194.93" /* pool.ntp.org */ +#endif +#endif + +/** Sanity check: + * Define this to + * - 0 to turn off sanity checks (default; smaller code) + * - >= 1 to check address and port of the response packet to ensure the + * response comes from the server we sent the request to. + * - >= 2 to check returned Originate Timestamp against Transmit Timestamp + * sent to the server (to ensure response to older request). + * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp + * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast). + * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each + * greater than or equal to 0 and less than infinity, where infinity is + * currently a cozy number like one second. This check avoids using a + * server whose synchronization source has expired for a very long time. + */ +#ifndef SNTP_CHECK_RESPONSE +#define SNTP_CHECK_RESPONSE 0 +#endif + +/** According to the RFC, this shall be a random delay + * between 1 and 5 minutes (in milliseconds) to prevent load peaks. + * This can be defined to a random generation function, + * which must return the delay in milliseconds as u32_t. + * Turned off by default. + */ +#ifndef SNTP_STARTUP_DELAY +#define SNTP_STARTUP_DELAY 0 +#endif + +/** SNTP receive timeout - in milliseconds + * Also used as retry timeout - this shouldn't be too low. + * Default is 3 seconds. + */ +#ifndef SNTP_RECV_TIMEOUT +#define SNTP_RECV_TIMEOUT 3000 +#endif + +/** SNTP update delay - in milliseconds + * Default is 1 hour. + */ +#ifndef SNTP_UPDATE_DELAY +#define SNTP_UPDATE_DELAY 3600000 +#endif +#if (SNTP_UPDATE_DELAY < 15000) && !SNTP_SUPPRESS_DELAY_CHECK +#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds!" +#endif + +/* Realtek added for sntp update */ +static unsigned int sntp_update_tick = 0; +static time_t sntp_update_sec = 0; +static time_t sntp_update_usec = 0; + +#define SNTP_SET_SYSTEM_TIME_US(sec, usec) do { \ + sntp_update_tick = xTaskGetTickCount(); \ + sntp_update_sec = sec; \ + sntp_update_usec = usec; \ + } while(0) + +void sntp_get_lasttime(long *sec, long *usec, unsigned int *tick) +{ + *sec = sntp_update_sec; + *usec = sntp_update_usec; + *tick = sntp_update_tick; +} + +time_t sntp_gen_system_time(int timezone) +{ + struct tm current_tm; + unsigned int update_tick; + long update_sec, update_usec, current_sec = 0; + + sntp_get_lasttime(&update_sec, &update_usec, &update_tick); + + unsigned int current_tick = xTaskGetTickCount(); + + if(update_tick) { + long tick_diff_sec, tick_diff_ms; + + tick_diff_sec = (current_tick - update_tick) / configTICK_RATE_HZ; + tick_diff_ms = (current_tick - update_tick) % configTICK_RATE_HZ / portTICK_RATE_MS; + update_sec += tick_diff_sec; + update_usec += (tick_diff_ms * 1000); + current_sec = update_sec + update_usec / 1000000 + timezone * 3600; + } + else { +// current_sec = current_tick / configTICK_RATE_HZ; + current_sec = update_usec; + } + return current_sec; +/* + current_tm = *(localtime(¤t_sec)); + current_tm.tm_year += 1900; + current_tm.tm_mon += 1; + + return current_tm; +*/ +} +/* End of Realtek added */ + +/** SNTP macro to change system time and/or the update the RTC clock */ +#ifndef SNTP_SET_SYSTEM_TIME +#define SNTP_SET_SYSTEM_TIME(sec) ((void)sec) +#endif + +/** SNTP macro to change system time including microseconds */ +#ifdef SNTP_SET_SYSTEM_TIME_US +#define SNTP_CALC_TIME_US 1 +#define SNTP_RECEIVE_TIME_SIZE 2 +#else +#define SNTP_SET_SYSTEM_TIME_US(sec, us) +#define SNTP_CALC_TIME_US 0 +#define SNTP_RECEIVE_TIME_SIZE 1 +#endif + +/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2 + * to send in request and compare in response. + */ +#ifndef SNTP_GET_SYSTEM_TIME +#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0) +#endif + +/** Default retry timeout (in milliseconds) if the response + * received is invalid. + * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached. + */ +#ifndef SNTP_RETRY_TIMEOUT +#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT +#endif + +/** Maximum retry timeout (in milliseconds). */ +#ifndef SNTP_RETRY_TIMEOUT_MAX +#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10) +#endif + +/** Increase retry timeout with every retry sent + * Default is on to conform to RFC. + */ +#ifndef SNTP_RETRY_TIMEOUT_EXP +#define SNTP_RETRY_TIMEOUT_EXP 1 +#endif + +/* the various debug levels for this file */ +#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) +#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) +#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) +#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) +#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) + +#define SNTP_ERR_KOD 1 + +/* SNTP protocol defines */ +#define SNTP_MSG_LEN 48 + +#define SNTP_OFFSET_LI_VN_MODE 0 +#define SNTP_LI_MASK 0xC0 +#define SNTP_LI_NO_WARNING 0x00 +#define SNTP_LI_LAST_MINUTE_61_SEC 0x01 +#define SNTP_LI_LAST_MINUTE_59_SEC 0x02 +#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */ + +#define SNTP_VERSION_MASK 0x38 +#define SNTP_VERSION (4/* NTP Version 4*/<<3) + +#define SNTP_MODE_MASK 0x07 +#define SNTP_MODE_CLIENT 0x03 +#define SNTP_MODE_SERVER 0x04 +#define SNTP_MODE_BROADCAST 0x05 + +#define SNTP_OFFSET_STRATUM 1 +#define SNTP_STRATUM_KOD 0x00 + +#define SNTP_OFFSET_ORIGINATE_TIME 24 +#define SNTP_OFFSET_RECEIVE_TIME 32 +#define SNTP_OFFSET_TRANSMIT_TIME 40 + +/* number of seconds between 1900 and 1970 */ +#define DIFF_SEC_1900_1970 (2208988800UL) + +/** + * SNTP packet format (without optional fields) + * Timestamps are coded as 64 bits: + * - 32 bits seconds since Jan 01, 1970, 00:00 + * - 32 bits seconds fraction (0-padded) + * For future use, if the MSB in the seconds part is set, seconds are based + * on Feb 07, 2036, 06:28:16. + */ +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/bpstruct.h" +#endif +PACK_STRUCT_BEGIN +struct sntp_msg { + PACK_STRUCT_FIELD(u8_t li_vn_mode); + PACK_STRUCT_FIELD(u8_t stratum); + PACK_STRUCT_FIELD(u8_t poll); + PACK_STRUCT_FIELD(u8_t precision); + PACK_STRUCT_FIELD(u32_t root_delay); + PACK_STRUCT_FIELD(u32_t root_dispersion); + PACK_STRUCT_FIELD(u32_t reference_identifier); + PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); + PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); + PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); + PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); +} PACK_STRUCT_STRUCT; +PACK_STRUCT_END +#ifdef PACK_STRUCT_USE_INCLUDES +# include "arch/epstruct.h" +#endif + +/* function prototypes */ +static void sntp_request(void *arg); + +/** The UDP pcb used by the SNTP client */ +static struct udp_pcb* sntp_pcb; +/** Addresses of servers */ +static char* sntp_server_addresses[] = {SNTP_SERVER_ADDRESS}; +#if SNTP_SUPPORT_MULTIPLE_SERVERS +/** The currently used server (initialized to 0) */ +static u8_t sntp_current_server; +static u8_t sntp_num_servers = sizeof(sntp_server_addresses)/sizeof(char*); +#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ +#define sntp_current_server 0 +#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ + +#if SNTP_RETRY_TIMEOUT_EXP +#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT +/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */ +static u32_t sntp_retry_timeout; +#else /* SNTP_RETRY_TIMEOUT_EXP */ +#define SNTP_RESET_RETRY_TIMEOUT() +#define sntp_retry_timeout SNTP_RETRY_TIMEOUT +#endif /* SNTP_RETRY_TIMEOUT_EXP */ + +#if SNTP_CHECK_RESPONSE >= 1 +/** Saves the last server address to compare with response */ +static ip_addr_t sntp_last_server_address; +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + +#if SNTP_CHECK_RESPONSE >= 2 +/** Saves the last timestamp sent (which is sent back by the server) + * to compare against in response */ +static u32_t sntp_last_timestamp_sent[2]; +#endif /* SNTP_CHECK_RESPONSE >= 2 */ + +/** + * SNTP processing of received timestamp + */ +static void +sntp_process(u32_t *receive_timestamp) +{ + /* convert SNTP time (1900-based) to unix GMT time (1970-based) + * @todo: if MSB is 1, SNTP time is 2036-based! + */ + time_t t = (ntohl(receive_timestamp[0]) - DIFF_SEC_1900_1970); + +#if SNTP_CALC_TIME_US + u32_t us = ntohl(receive_timestamp[1]) / 4295; + SNTP_SET_SYSTEM_TIME_US(t, us); + /* display local time from GMT time */ + LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&t), us)); + +#else /* SNTP_CALC_TIME_US */ + + /* change system time and/or the update the RTC clock */ + SNTP_SET_SYSTEM_TIME(t); + /* display local time from GMT time */ + LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&t))); +#endif /* SNTP_CALC_TIME_US */ +} + +/** + * Initialize request struct to be sent to server. + */ +static void +sntp_initialize_request(struct sntp_msg *req) +{ + memset(req, 0, SNTP_MSG_LEN); + req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; + +#if SNTP_CHECK_RESPONSE >= 2 + { + u32_t sntp_time_sec, sntp_time_us; + /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */ + SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us); + sntp_last_timestamp_sent[0] = htonl(sntp_time_sec + DIFF_SEC_1900_1970); + req->transmit_timestamp[0] = sntp_last_timestamp_sent[0]; + /* we send/save us instead of fraction to be faster... */ + sntp_last_timestamp_sent[1] = htonl(sntp_time_us); + req->transmit_timestamp[1] = sntp_last_timestamp_sent[1]; + } +#endif /* SNTP_CHECK_RESPONSE >= 2 */ +} + +/** + * Retry: send a new request (and increase retry timeout). + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_retry(void* arg) +{ + LWIP_UNUSED_ARG(arg); + + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n", + sntp_retry_timeout)); + + /* set up a timer to send a retry and increase the retry delay */ + sys_timeout(sntp_retry_timeout, sntp_request, NULL); + +#if SNTP_RETRY_TIMEOUT_EXP + { + u32_t new_retry_timeout; + /* increase the timeout for next retry */ + new_retry_timeout = sntp_retry_timeout << 1; + /* limit to maximum timeout and prevent overflow */ + if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && + (new_retry_timeout > sntp_retry_timeout)) { + sntp_retry_timeout = new_retry_timeout; + } + } +#endif /* SNTP_RETRY_TIMEOUT_EXP */ +} + +#if SNTP_SUPPORT_MULTIPLE_SERVERS +/** + * If Kiss-of-Death is received (or another packet parsing error), + * try the next server or retry the current server and increase the retry + * timeout if only one server is available. + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_try_next_server(void* arg) +{ + LWIP_UNUSED_ARG(arg); + + if (sntp_num_servers > 1) { + /* new server: reset retry timeout */ + SNTP_RESET_RETRY_TIMEOUT(); + sntp_current_server++; + if (sntp_current_server >= sntp_num_servers) { + sntp_current_server = 0; + } + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", + (u16_t)sntp_current_server)); + /* instantly send a request to the next server */ + sntp_request(NULL); + } else { + sntp_retry(NULL); + } +} +#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ +/* Always retry on error if only one server is supported */ +#define sntp_try_next_server sntp_retry +#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ + +/** UDP recv callback for the sntp pcb */ +static void +sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, ip_addr_t *addr, u16_t port) +{ + u8_t mode; + u8_t stratum; + u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE]; + err_t err; + + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(pcb); + + /* packet received: stop retry timeout */ + sys_untimeout(sntp_try_next_server, NULL); + sys_untimeout(sntp_request, NULL); + + err = ERR_ARG; +#if SNTP_CHECK_RESPONSE >= 1 + /* check server address and port */ + if (ip_addr_cmp(addr, &sntp_last_server_address) && + (port == SNTP_PORT)) +#else /* SNTP_CHECK_RESPONSE >= 1 */ + LWIP_UNUSED_ARG(addr); + LWIP_UNUSED_ARG(port); +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + { + /* process the response */ + if (p->tot_len == SNTP_MSG_LEN) { + pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE); + mode &= SNTP_MODE_MASK; + /* if this is a SNTP response... */ + if ((mode == SNTP_MODE_SERVER) || + (mode == SNTP_MODE_BROADCAST)) { + pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM); + if (stratum == SNTP_STRATUM_KOD) { + /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ + err = SNTP_ERR_KOD; + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); + } else { +#if SNTP_CHECK_RESPONSE >= 2 + /* check originate_timetamp against sntp_last_timestamp_sent */ + u32_t originate_timestamp[2]; + pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME); + if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) || + (originate_timestamp[1] != sntp_last_timestamp_sent[1])) + { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n")); + } else +#endif /* SNTP_CHECK_RESPONSE >= 2 */ + /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ + { + /* correct answer */ + err = ERR_OK; + pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_RECEIVE_TIME); + } + } + } else { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); + } + } else { + LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); + } + } + pbuf_free(p); + if (err == ERR_OK) { + /* Correct response, reset retry timeout */ + SNTP_RESET_RETRY_TIMEOUT(); + + sntp_process(receive_timestamp); + + /* Set up timeout for next request */ + sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL); + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", + (u32_t)SNTP_UPDATE_DELAY)); + } else if (err == SNTP_ERR_KOD) { + /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ + sntp_try_next_server(NULL); + } else { + /* another error, try the same server again */ + sntp_retry(NULL); + } +} + +/** Actually send an sntp request to a server. + * + * @param server_addr resolved IP address of the SNTP server + */ +static void +sntp_send_request(ip_addr_t *server_addr) +{ + struct pbuf* p; + p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); + if (p != NULL) { + struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); + /* initialize request message */ + sntp_initialize_request(sntpmsg); + /* send request */ + udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); + /* free the pbuf after sending it */ + pbuf_free(p); + /* set up receive timeout: try next server or retry on timeout */ + sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); +#if SNTP_CHECK_RESPONSE >= 1 + /* save server address to verify it in sntp_recv */ + ip_addr_set(&sntp_last_server_address, server_addr); +#endif /* SNTP_CHECK_RESPONSE >= 1 */ + } else { + LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", + (u32_t)SNTP_RETRY_TIMEOUT)); + /* out of memory: set up a timer to send a retry */ + sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); + } +} + +#if SNTP_SERVER_DNS +/** + * DNS found callback when using DNS names as server address. + */ +static void +sntp_dns_found(const char* hostname, ip_addr_t *ipaddr, void *arg) +{ + LWIP_UNUSED_ARG(hostname); + LWIP_UNUSED_ARG(arg); + + if (ipaddr != NULL) { + /* Address resolved, send request */ + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); + sntp_send_request(ipaddr); + } else { + /* DNS resolving failed -> try another server */ + LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); + sntp_try_next_server(NULL); + } +} +#endif /* SNTP_SERVER_DNS */ + +/** + * Send out an sntp request. + * + * @param arg is unused (only necessary to conform to sys_timeout) + */ +static void +sntp_request(void *arg) +{ + ip_addr_t sntp_server_address; + err_t err; + + LWIP_UNUSED_ARG(arg); + + /* initialize SNTP server address */ +#if SNTP_SERVER_DNS + err = dns_gethostbyname(sntp_server_addresses[sntp_current_server], &sntp_server_address, + sntp_dns_found, NULL); + if (err == ERR_INPROGRESS) { + /* DNS request sent, wait for sntp_dns_found being called */ + LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); + return; + } +#else /* SNTP_SERVER_DNS */ + err = ipaddr_aton(sntp_server_addresses[sntp_current_server], &sntp_server_address) + ? ERR_OK : ERR_ARG; + +#endif /* SNTP_SERVER_DNS */ + + if (err == ERR_OK) { + sntp_send_request(&sntp_server_address); + } else { + /* address conversion failed, try another server */ + LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); + sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); + } +} + +/** + * Initialize this module. + * Send out request instantly or after SNTP_STARTUP_DELAY. + */ +void +sntp_init(void) +{ + if (sntp_pcb == NULL) { + SNTP_RESET_RETRY_TIMEOUT(); + sntp_pcb = udp_new(); + LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); + if (sntp_pcb != NULL) { + udp_recv(sntp_pcb, sntp_recv, NULL); +#if SNTP_STARTUP_DELAY + sys_timeout((u32_t)SNTP_STARTUP_DELAY, sntp_request, NULL); +#else + sntp_request(NULL); +#endif + rtl_printf("SNTP start.\n"); + } + } +} + +/** + * Stop this module. + */ +void +sntp_stop(void) +{ + if (sntp_pcb != NULL) { + sys_untimeout(sntp_request, NULL); + udp_remove(sntp_pcb); + sntp_pcb = NULL; + rtl_printf("SNTP stop.\n"); + } +} +#endif /* LWIP_UDP */ diff --git a/USDK/component/common/network/sntp/sntp.h b/USDK/component/common/network/sntp/sntp.h new file mode 100644 index 0000000..4122d63 --- /dev/null +++ b/USDK/component/common/network/sntp/sntp.h @@ -0,0 +1,21 @@ +#ifndef __SNTP_H__ +#define __SNTP_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void sntp_init(void); +void sntp_stop(void); + +/* Realtek added */ +void sntp_get_lasttime(long *sec, long *usec, unsigned int *tick); +time_t sntp_gen_system_time(int timezone); + +#ifdef __cplusplus +} +#endif + +#endif /* __SNTP_H__ */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/Makefile b/USDK/component/common/network/ssl/polarssl-1.3.8/Makefile new file mode 100644 index 0000000..4e901ff --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/Makefile @@ -0,0 +1,97 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +#*****************************************************************************# +# VARIABLES # +#*****************************************************************************# + + +MODULE_IFLAGS += -I../include + +#*****************************************************************************# +# Source FILE LIST # +#*****************************************************************************# + +CSRC = library/aesni.o \ + library/ccm.o \ + library/cipher.o \ + library/cipher_wrap.o \ + library/debug.o \ + library/ecp_ram.o \ + library/error.o \ + library/gcm.o \ + library/havege.o \ + library/memory_buffer_alloc.o \ + library/padlock.o \ + library/pbkdf2.o \ + library/pkcs5.o \ + library/pkcs11.o \ + library/pkcs12.o \ + library/pkparse.o \ + library/ssl_cache.o \ + library/ssl_cli.o \ + library/ssl_srv.o \ + library/ssl_ciphersuites.o \ + library/ssl_tls.o \ + library/threading.o \ + library/timing.o \ + library/version.o \ + library/version_features.o \ + library/x509.o \ + library/x509_create.o \ + library/x509_crl.o \ + library/x509_crt.o \ + library/x509_csr.o \ + library/x509write_crt.o \ + library/x509write_csr.o \ + ../ssl_ram_map/ssl_ram_map.o \ + ssl_self_test.o + +ROM_CSRC = + +ifeq ($(CONFIG_NORMAL_BUILD),y) #Normal + CSRC += $(ROM_CSRC) +else ifeq ($(CONFIG_RELEASE_BUILD),y) #CONFIG_RELEASE_BUILD + CSRC = +else + # Not change CSRC +endif + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = $(CSRC) + +#*****************************************************************************# +# Include Dependency # +#*****************************************************************************# +-include $(OBJS:.o=.d) + + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# +# Define the Rules to build the core targets +all: CORE_TARGETS COPY_RAM_OBJS + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + +#*****************************************************************************# +# CLEAN GENERATED FILES # +#*****************************************************************************# +clean: + $(REMOVE) library/*.o + $(REMOVE) library/*.i + $(REMOVE) library/*.s + $(REMOVE) library/*.d + $(REMOVE) ../ssl_ram_map/*.o + $(REMOVE) ../ssl_ram_map/*.i + $(REMOVE) ../ssl_ram_map/*.s + $(REMOVE) ../ssl_ram_map/*.d + +-include $(DEPS) diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aes.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aes.h new file mode 100644 index 0000000..d08073c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aes.h @@ -0,0 +1,264 @@ +/** + * \file aes.h + * + * \brief AES block cipher + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_AES_H +#define POLARSSL_AES_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +// Rename to fix function conflict to ROM codes +#define aes_init polarssl_aes_init + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +/* padlock.c and aesni.c rely on these values! */ +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */ +#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */ + +#if !defined(POLARSSL_AES_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief AES context structure + * + * \note buf is able to hold 32 extra bytes, which can be used: + * - for alignment purposes if VIA padlock is used, and/or + * - to simplify key expansion in the 256-bit case by + * generating an extra round key + */ +typedef struct +{ + int nr; /*!< number of rounds */ + uint32_t *rk; /*!< AES round keys */ + uint32_t buf[68]; /*!< unaligned data */ +#ifdef RTL_HW_CRYPTO + unsigned char enc_key[32]; + unsigned char dec_key[32]; +#endif +} +aes_context; + +/** + * \brief Initialize AES context + * + * \param ctx AES context to be initialized + */ +void aes_init( aes_context *ctx ); + +/** + * \brief Clear AES context + * + * \param ctx AES context to be cleared + */ +void aes_free( aes_context *ctx ); + +/** + * \brief AES key schedule (encryption) + * + * \param ctx AES context to be initialized + * \param key encryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief AES key schedule (decryption) + * + * \param ctx AES context to be initialized + * \param key decryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief AES-ECB block encryption/decryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int aes_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief AES-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH + */ +int aes_crypt_cbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/** + * \brief AES-CFB128 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int aes_crypt_cfb128( aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +/** + * \brief AES-CFB8 buffer encryption/decryption. + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int aes_crypt_cfb8( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/** + * \brief AES-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT. + * + * \param ctx AES context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int aes_crypt_ctr( aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_AES_ALT */ +#include "aes_alt.h" +#endif /* POLARSSL_AES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int aes_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* aes.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aesni.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aesni.h new file mode 100644 index 0000000..92b23cd --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/aesni.h @@ -0,0 +1,107 @@ +/** + * \file aesni.h + * + * \brief AES-NI for hardware AES acceleration on some Intel processors + * + * Copyright (C) 2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_AESNI_H +#define POLARSSL_AESNI_H + +#include "aes.h" + +#define POLARSSL_AESNI_AES 0x02000000u +#define POLARSSL_AESNI_CLMUL 0x00000002u + +#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && \ + ( defined(__amd64__) || defined(__x86_64__) ) && \ + ! defined(POLARSSL_HAVE_X86_64) +#define POLARSSL_HAVE_X86_64 +#endif + +#if defined(POLARSSL_HAVE_X86_64) + +/** + * \brief AES-NI features detection routine + * + * \param what The feature to detect + * (POLARSSL_AESNI_AES or POLARSSL_AESNI_CLMUL) + * + * \return 1 if CPU has support for the feature, 0 otherwise + */ +int aesni_supports( unsigned int what ); + +/** + * \brief AES-NI AES-ECB block en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 on success (cannot fail) + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief GCM multiplication: c = a * b in GF(2^128) + * + * \param c Result + * \param a First operand + * \param b Second operand + * + * \note Both operands and result are bit strings interpreted as + * elements of GF(2^128) as per the GCM spec. + */ +void aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ); + +/** + * \brief Compute decryption round keys from encryption round keys + * + * \param invkey Round keys for the equivalent inverse cipher + * \param fwdkey Original round keys (for encryption) + * \param nr Number of rounds (that is, number of round keys minus one) + */ +void aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ); + +/** + * \brief Perform key expansion (for encryption) + * + * \param rk Destination buffer where the round keys are written + * \param key Encryption key + * \param bits Key size in bits (must be 128, 192 or 256) + * + * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH + */ +int aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ); + +#endif /* POLARSSL_HAVE_X86_64 */ + +#endif /* POLARSSL_AESNI_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/arc4.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/arc4.h new file mode 100644 index 0000000..555f54f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/arc4.h @@ -0,0 +1,117 @@ +/** + * \file arc4.h + * + * \brief The ARCFOUR stream cipher + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ARC4_H +#define POLARSSL_ARC4_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if !defined(POLARSSL_ARC4_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief ARC4 context structure + */ +typedef struct +{ + int x; /*!< permutation index */ + int y; /*!< permutation index */ + unsigned char m[256]; /*!< permutation table */ +} +arc4_context; + +/** + * \brief Initialize ARC4 context + * + * \param ctx ARC4 context to be initialized + */ +void arc4_init( arc4_context *ctx ); + +/** + * \brief Clear ARC4 context + * + * \param ctx ARC4 context to be cleared + */ +void arc4_free( arc4_context *ctx ); + +/** + * \brief ARC4 key schedule + * + * \param ctx ARC4 context to be setup + * \param key the secret key + * \param keylen length of the key, in bytes + */ +void arc4_setup( arc4_context *ctx, const unsigned char *key, + unsigned int keylen ); + +/** + * \brief ARC4 cipher function + * + * \param ctx ARC4 context + * \param length length of the input data + * \param input buffer holding the input data + * \param output buffer for the output data + * + * \return 0 if successful + */ +int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_ARC4_ALT */ +#include "arc4_alt.h" +#endif /* POLARSSL_ARC4_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int arc4_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* arc4.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1.h new file mode 100644 index 0000000..eacdd08 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1.h @@ -0,0 +1,347 @@ +/** + * \file asn1.h + * + * \brief Generic ASN.1 parsing + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ASN1_H +#define POLARSSL_ASN1_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BIGNUM_C) +#include "bignum.h" +#endif + +#include + +/** + * \addtogroup asn1_module + * \{ + */ + +/** + * \name ASN1 Error codes + * These error codes are OR'ed to X509 error codes for + * higher error granularity. + * ASN1 is a standard to specify data structures. + * \{ + */ +#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */ +#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */ +#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */ +#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */ +#define POLARSSL_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */ +#define POLARSSL_ERR_ASN1_MALLOC_FAILED -0x006A /**< Memory allocation failed */ +#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */ + +/* \} name */ + +/** + * \name DER constants + * These constants comply with DER encoded the ANS1 type tags. + * DER encoding uses hexadecimal representation. + * An example DER sequence is:\n + * - 0x02 -- tag indicating INTEGER + * - 0x01 -- length in octets + * - 0x05 -- value + * Such sequences are typically read into \c ::x509_buf. + * \{ + */ +#define ASN1_BOOLEAN 0x01 +#define ASN1_INTEGER 0x02 +#define ASN1_BIT_STRING 0x03 +#define ASN1_OCTET_STRING 0x04 +#define ASN1_NULL 0x05 +#define ASN1_OID 0x06 +#define ASN1_UTF8_STRING 0x0C +#define ASN1_SEQUENCE 0x10 +#define ASN1_SET 0x11 +#define ASN1_PRINTABLE_STRING 0x13 +#define ASN1_T61_STRING 0x14 +#define ASN1_IA5_STRING 0x16 +#define ASN1_UTC_TIME 0x17 +#define ASN1_GENERALIZED_TIME 0x18 +#define ASN1_UNIVERSAL_STRING 0x1C +#define ASN1_BMP_STRING 0x1E +#define ASN1_PRIMITIVE 0x00 +#define ASN1_CONSTRUCTED 0x20 +#define ASN1_CONTEXT_SPECIFIC 0x80 +/* \} name */ +/* \} addtogroup asn1_module */ + +/** Returns the size of the binary string, without the trailing \\0 */ +#define OID_SIZE(x) (sizeof(x) - 1) + +/** + * Compares an asn1_buf structure to a reference OID. + * + * Only works for 'defined' oid_str values (OID_HMAC_SHA1), you cannot use a + * 'unsigned char *oid' here! + * + * Warning: returns true when the OIDs are equal (unlike memcmp)! + */ +#define OID_CMP(oid_str, oid_buf) \ + ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \ + memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Functions to parse ASN.1 data structures + * \{ + */ + +/** + * Type-length-value structure that allows for ASN1 using DER. + */ +typedef struct _asn1_buf +{ + int tag; /**< ASN1 type, e.g. ASN1_UTF8_STRING. */ + size_t len; /**< ASN1 length, e.g. in octets. */ + unsigned char *p; /**< ASN1 data, e.g. in ASCII. */ +} +asn1_buf; + +/** + * Container for ASN1 bit strings. + */ +typedef struct _asn1_bitstring +{ + size_t len; /**< ASN1 length, e.g. in octets. */ + unsigned char unused_bits; /**< Number of unused bits at the end of the string */ + unsigned char *p; /**< Raw ASN1 data for the bit string */ +} +asn1_bitstring; + +/** + * Container for a sequence of ASN.1 items + */ +typedef struct _asn1_sequence +{ + asn1_buf buf; /**< Buffer containing the given ASN.1 item. */ + struct _asn1_sequence *next; /**< The next entry in the sequence. */ +} +asn1_sequence; + +/** + * Container for a sequence or list of 'named' ASN.1 data items + */ +typedef struct _asn1_named_data +{ + asn1_buf oid; /**< The object identifier. */ + asn1_buf val; /**< The named value. */ + struct _asn1_named_data *next; /**< The next entry in the sequence. */ +} +asn1_named_data; + +/** + * \brief Get the length of an ASN.1 element. + * Updates the pointer to immediately behind the length. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param len The variable that will receive the value + * + * \return 0 if successful, POLARSSL_ERR_ASN1_OUT_OF_DATA on reaching + * end of data, POLARSSL_ERR_ASN1_INVALID_LENGTH if length is + * unparseable. + */ +int asn1_get_len( unsigned char **p, + const unsigned char *end, + size_t *len ); + +/** + * \brief Get the tag and length of the tag. Check for the requested tag. + * Updates the pointer to immediately behind the tag and length. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param len The variable that will receive the length + * \param tag The expected tag + * + * \return 0 if successful, POLARSSL_ERR_ASN1_UNEXPECTED_TAG if tag did + * not match requested tag, or another specific ASN.1 error code. + */ +int asn1_get_tag( unsigned char **p, + const unsigned char *end, + size_t *len, int tag ); + +/** + * \brief Retrieve a boolean ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param val The variable that will receive the value + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_bool( unsigned char **p, + const unsigned char *end, + int *val ); + +/** + * \brief Retrieve an integer ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param val The variable that will receive the value + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_int( unsigned char **p, + const unsigned char *end, + int *val ); + +/** + * \brief Retrieve a bitstring ASN.1 tag and its value. + * Updates the pointer to immediately behind the full tag. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param bs The variable that will receive the value + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_bitstring( unsigned char **p, const unsigned char *end, + asn1_bitstring *bs); + +/** + * \brief Retrieve a bitstring ASN.1 tag without unused bits and its + * value. + * Updates the pointer to the beginning of the bit/octet string. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param len Length of the actual bit/octect string in bytes + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ); + +/** + * \brief Parses and splits an ASN.1 "SEQUENCE OF " + * Updated the pointer to immediately behind the full sequence tag. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param cur First variable in the chain to fill + * \param tag Type of sequence + * + * \return 0 if successful or a specific ASN.1 error code. + */ +int asn1_get_sequence_of( unsigned char **p, + const unsigned char *end, + asn1_sequence *cur, + int tag); + +#if defined(POLARSSL_BIGNUM_C) +/** + * \brief Retrieve a MPI value from an integer ASN.1 tag. + * Updates the pointer to immediately behind the full tag. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param X The MPI that will receive the value + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int asn1_get_mpi( unsigned char **p, + const unsigned char *end, + mpi *X ); +#endif /* POLARSSL_BIGNUM_C */ + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param alg The buffer to receive the OID + * \param params The buffer to receive the params (if any) + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int asn1_get_alg( unsigned char **p, + const unsigned char *end, + asn1_buf *alg, asn1_buf *params ); + +/** + * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no + * params. + * Updates the pointer to immediately behind the full + * AlgorithmIdentifier. + * + * \param p The position in the ASN.1 data + * \param end End of data + * \param alg The buffer to receive the OID + * + * \return 0 if successful or a specific ASN.1 or MPI error code. + */ +int asn1_get_alg_null( unsigned char **p, + const unsigned char *end, + asn1_buf *alg ); + +/** + * \brief Find a specific named_data entry in a sequence or list based on + * the OID. + * + * \param list The list to seek through + * \param oid The OID to look for + * \param len Size of the OID + * + * \return NULL if not found, or a pointer to the existing entry. + */ +asn1_named_data *asn1_find_named_data( asn1_named_data *list, + const char *oid, size_t len ); + +/** + * \brief Free a asn1_named_data entry + * + * \param entry The named data entry to free + */ +void asn1_free_named_data( asn1_named_data *entry ); + +/** + * \brief Free all entries in a asn1_named_data list + * Head will be set to NULL + * + * \param head Pointer to the head of the list of named data entries to free + */ +void asn1_free_named_data_list( asn1_named_data **head ); + +#ifdef __cplusplus +} +#endif + +#endif /* asn1.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1write.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1write.h new file mode 100644 index 0000000..7a7fbf7 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/asn1write.h @@ -0,0 +1,243 @@ +/** + * \file asn1write.h + * + * \brief ASN.1 buffer writing functionality + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ASN1_WRITE_H +#define POLARSSL_ASN1_WRITE_H + +#include "asn1.h" + +#define ASN1_CHK_ADD(g, f) do { if( ( ret = f ) < 0 ) return( ret ); else \ + g += ret; } while( 0 ) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Write a length field in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param len the length to write + * + * \return the length written or a negative error code + */ +int asn1_write_len( unsigned char **p, unsigned char *start, size_t len ); + +/** + * \brief Write a ASN.1 tag in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param tag the tag to write + * + * \return the length written or a negative error code + */ +int asn1_write_tag( unsigned char **p, unsigned char *start, + unsigned char tag ); + +/** + * \brief Write raw buffer data + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param buf data buffer to write + * \param size length of the data buffer + * + * \return the length written or a negative error code + */ +int asn1_write_raw_buffer( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ); + +#if defined(POLARSSL_BIGNUM_C) +/** + * \brief Write a big number (ASN1_INTEGER) in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param X the MPI to write + * + * \return the length written or a negative error code + */ +int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ); +#endif /* POLARSSL_BIGNUM_C */ + +/** + * \brief Write a NULL tag (ASN1_NULL) with zero data in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * + * \return the length written or a negative error code + */ +int asn1_write_null( unsigned char **p, unsigned char *start ); + +/** + * \brief Write an OID tag (ASN1_OID) and data in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param oid the OID to write + * \param oid_len length of the OID + * + * \return the length written or a negative error code + */ +int asn1_write_oid( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len ); + +/** + * \brief Write an AlgorithmIdentifier sequence in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param oid the OID of the algorithm + * \param oid_len length of the OID + * \param par_len length of parameters, which must be already written. + * If 0, NULL parameters are added + * + * \return the length written or a negative error code + */ +int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len ); + +/** + * \brief Write a boolean tag (ASN1_BOOLEAN) and value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param boolean 0 or 1 + * + * \return the length written or a negative error code + */ +int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ); + +/** + * \brief Write an int tag (ASN1_INTEGER) and value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param val the integer value + * + * \return the length written or a negative error code + */ +int asn1_write_int( unsigned char **p, unsigned char *start, int val ); + +/** + * \brief Write a printable string tag (ASN1_PRINTABLE_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param text the text to write + * \param text_len length of the text + * + * \return the length written or a negative error code + */ +int asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ); + +/** + * \brief Write an IA5 string tag (ASN1_IA5_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param text the text to write + * \param text_len length of the text + * + * \return the length written or a negative error code + */ +int asn1_write_ia5_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ); + +/** + * \brief Write a bitstring tag (ASN1_BIT_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param buf the bitstring + * \param bits the total number of bits in the bitstring + * + * \return the length written or a negative error code + */ +int asn1_write_bitstring( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t bits ); + +/** + * \brief Write an octet string tag (ASN1_OCTET_STRING) and + * value in ASN.1 format + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param buf data buffer to write + * \param size length of the data buffer + * + * \return the length written or a negative error code + */ +int asn1_write_octet_string( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ); + +/** + * \brief Create or find a specific named_data entry for writing in a + * sequence or list based on the OID. If not already in there, + * a new entry is added to the head of the list. + * Warning: Destructive behaviour for the val data! + * + * \param list Pointer to the location of the head of the list to seek + * through (will be updated in case of a new entry) + * \param oid The OID to look for + * \param oid_len Size of the OID + * \param val Data to store (can be NULL if you want to fill it by hand) + * \param val_len Minimum length of the data buffer needed + * + * \return NULL if if there was a memory allocation error, or a pointer + * to the new / existing entry. + */ +asn1_named_data *asn1_store_named_data( asn1_named_data **list, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len ); + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_ASN1_WRITE_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/base64.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/base64.h new file mode 100644 index 0000000..d041493 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/base64.h @@ -0,0 +1,87 @@ +/** + * \file base64.h + * + * \brief RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_BASE64_H +#define POLARSSL_BASE64_H + +#include + +#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ +#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Encode a buffer into base64 format + * + * \param dst destination buffer + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be encoded + * + * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. + * *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dlen = 0 to obtain the + * required buffer size in *dlen + */ +int base64_encode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ); + +/** + * \brief Decode a base64-formatted buffer + * + * \param dst destination buffer (can be NULL for checking size) + * \param dlen size of the buffer + * \param src source buffer + * \param slen amount of data to be decoded + * + * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or + * POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is + * not correct. *dlen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *dst = NULL or *dlen = 0 to obtain + * the required buffer size in *dlen + */ +int base64_decode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int base64_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* base64.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bignum.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bignum.h new file mode 100644 index 0000000..1f4a1aa --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bignum.h @@ -0,0 +1,755 @@ +/** + * \file bignum.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_BIGNUM_H +#define POLARSSL_BIGNUM_H + +#include +#include + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +#if (_MSC_VER <= 1200) +typedef signed short int16_t; +typedef unsigned short uint16_t; +#else +typedef INT16 int16_t; +typedef UINT16 uint16_t; +#endif +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; +#else +#include +#endif /* _MSC_VER && !EFIX64 && !EFI32 */ + +#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ +#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ +#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ +#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ +#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ +#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ +#define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */ + +#define MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) + +/* + * Maximum size MPIs are allowed to grow to in number of limbs. + */ +#define POLARSSL_MPI_MAX_LIMBS 10000 + +#if !defined(POLARSSL_MPI_WINDOW_SIZE) +/* + * Maximum window size used for modular exponentiation. Default: 6 + * Minimum value: 1. Maximum value: 6. + * + * Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used + * for the sliding window calculation. (So 64 by default) + * + * Reduction in size, reduces speed. + */ +#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +#endif /* !POLARSSL_MPI_WINDOW_SIZE */ + +#if !defined(POLARSSL_MPI_MAX_SIZE) +/* + * Maximum size of MPIs allowed in bits and bytes for user-MPIs. + * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) + * + * Note: Calculations can results temporarily in larger MPIs. So the number + * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher. + */ +#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ +#endif /* !POLARSSL_MPI_MAX_SIZE */ + +#define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ + +/* + * When reading from files with mpi_read_file() and writing to files with + * mpi_write_file() the buffer should have space + * for a (short) label, the MPI (in the provided radix), the newline + * characters and the '\0'. + * + * By default we assume at least a 10 char label, a minimum radix of 10 + * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). + * Autosized at compile time for at least a 10 char label, a minimum radix + * of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size. + * + * This used to be statically sized to 1250 for a maximum of 4096 bit + * numbers (1234 decimal chars). + * + * Calculate using the formula: + * POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) + + * LabelSize + 6 + */ +#define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS ) +#define LN_2_DIV_LN_10_SCALE100 332 +#define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) + +/* + * Define the base integer type, architecture-wise + */ +#if defined(POLARSSL_HAVE_INT8) +typedef signed char t_sint; +typedef unsigned char t_uint; +typedef uint16_t t_udbl; +#define POLARSSL_HAVE_UDBL +#else +#if defined(POLARSSL_HAVE_INT16) +typedef int16_t t_sint; +typedef uint16_t t_uint; +typedef uint32_t t_udbl; +#define POLARSSL_HAVE_UDBL +#else + /* + * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes) + * by defining POLARSSL_HAVE_INT32 and undefining POLARSSL_HAVE_ASM + */ + #if ( ! defined(POLARSSL_HAVE_INT32) && \ + defined(_MSC_VER) && defined(_M_AMD64) ) + #define POLARSSL_HAVE_INT64 + typedef int64_t t_sint; + typedef uint64_t t_uint; + #else + #if ( ! defined(POLARSSL_HAVE_INT32) && \ + defined(__GNUC__) && ( \ + defined(__amd64__) || defined(__x86_64__) || \ + defined(__ppc64__) || defined(__powerpc64__) || \ + defined(__ia64__) || defined(__alpha__) || \ + (defined(__sparc__) && defined(__arch64__)) || \ + defined(__s390x__) ) ) + #define POLARSSL_HAVE_INT64 + typedef int64_t t_sint; + typedef uint64_t t_uint; + typedef unsigned int t_udbl __attribute__((mode(TI))); + #define POLARSSL_HAVE_UDBL + #else + #define POLARSSL_HAVE_INT32 + typedef int32_t t_sint; + typedef uint32_t t_uint; + #if ( defined(_MSC_VER) && defined(_M_IX86) ) + typedef uint64_t t_udbl; + #define POLARSSL_HAVE_UDBL + #else + #if defined( POLARSSL_HAVE_LONGLONG ) + typedef unsigned long long t_udbl; + #define POLARSSL_HAVE_UDBL + #endif + #endif + #endif /* !POLARSSL_HAVE_INT32 && __GNUC__ && 64-bit platform */ + #endif /* !POLARSSL_HAVE_INT32 && _MSC_VER && _M_AMD64 */ +#endif /* POLARSSL_HAVE_INT16 */ +#endif /* POLARSSL_HAVE_INT8 */ + +/* because Ameba have no __aeabi_uldivmod */ +#undef POLARSSL_HAVE_UDBL + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MPI structure + */ +typedef struct +{ + int s; /*!< integer sign */ + size_t n; /*!< total # of limbs */ + t_uint *p; /*!< pointer to limbs */ +} +mpi; + +/** + * \brief Initialize one MPI + * + * \param X One MPI to initialize. + */ +void mpi_init( mpi *X ); + +/** + * \brief Unallocate one MPI + * + * \param X One MPI to unallocate. + */ +void mpi_free( mpi *X ); + +/** + * \brief Enlarge to the specified number of limbs + * + * \param X MPI to grow + * \param nblimbs The target number of limbs + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_grow( mpi *X, size_t nblimbs ); + +/** + * \brief Resize down, keeping at least the specified number of limbs + * + * \param X MPI to shrink + * \param nblimbs The minimum number of limbs to keep + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shrink( mpi *X, size_t nblimbs ); + +/** + * \brief Copy the contents of Y into X + * + * \param X Destination MPI + * \param Y Source MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_copy( mpi *X, const mpi *Y ); + +/** + * \brief Swap the contents of X and Y + * + * \param X First MPI value + * \param Y Second MPI value + */ +void mpi_swap( mpi *X, mpi *Y ); + +/** + * \brief Safe conditional assignement X = Y if assign is 1 + * + * \param X MPI to conditionally assign to + * \param Y Value to be assigned + * \param assign 1: perform the assignment, 0: keep X's original value + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * + * \note This function is equivalent to + * if( assign ) mpi_copy( X, Y ); + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + */ +int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ); + +/** + * \brief Safe conditional swap X <-> Y if swap is 1 + * + * \param X First mpi value + * \param Y Second mpi value + * \param assign 1: perform the swap, 0: keep X and Y's original values + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * + * \note This function is equivalent to + * if( assign ) mpi_swap( X, Y ); + * except that it avoids leaking any information about whether + * the assignment was done or not (the above code may leak + * information through branch prediction and/or memory access + * patterns analysis). + */ +int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char assign ); + +/** + * \brief Set value from integer + * + * \param X MPI to set + * \param z Value to use + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_lset( mpi *X, t_sint z ); + +/** + * \brief Get a specific bit from X + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * + * \return Either a 0 or a 1 + */ +int mpi_get_bit( const mpi *X, size_t pos ); + +/** + * \brief Set a bit of X to a specific value of 0 or 1 + * + * \note Will grow X if necessary to set a bit to 1 in a not yet + * existing limb. Will not grow if bit should be set to 0 + * + * \param X MPI to use + * \param pos Zero-based index of the bit in X + * \param val The value to set the bit to (0 or 1) + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ); + +/** + * \brief Return the number of zero-bits before the least significant + * '1' bit + * + * Note: Thus also the zero-based index of the least significant '1' bit + * + * \param X MPI to use + */ +size_t mpi_lsb( const mpi *X ); + +/** + * \brief Return the number of bits up to and including the most + * significant '1' bit' + * + * Note: Thus also the one-based index of the most significant '1' bit + * + * \param X MPI to use + */ +size_t mpi_msb( const mpi *X ); + +/** + * \brief Return the total size in bytes + * + * \param X MPI to use + */ +size_t mpi_size( const mpi *X ); + +/** + * \brief Import from an ASCII string + * + * \param X Destination MPI + * \param radix Input numeric base + * \param s Null-terminated string buffer + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_string( mpi *X, int radix, const char *s ); + +/** + * \brief Export into an ASCII string + * + * \param X Source MPI + * \param radix Output numeric base + * \param s String buffer + * \param slen String buffer size + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code. + * *slen is always updated to reflect the amount + * of data that has (or would have) been written. + * + * \note Call this function with *slen = 0 to obtain the + * minimum required buffer size in *slen. + */ +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Read X from an opened file + * + * \param X Destination MPI + * \param radix Input numeric base + * \param fin Input file handle + * + * \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if + * the file read buffer is too small or a + * POLARSSL_ERR_MPI_XXX error code + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ); + +/** + * \brief Write X into an opened file, or stdout if fout is NULL + * + * \param p Prefix, can be NULL + * \param X Source MPI + * \param radix Output numeric base + * \param fout Output file handle (can be NULL) + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + * + * \note Set fout == NULL to print X on the console. + */ +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Import X from unsigned binary data, big endian + * + * \param X Destination MPI + * \param buf Input buffer + * \param buflen Input buffer size + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); + +/** + * \brief Export X into unsigned binary data, big endian. + * Always fills the whole buffer, which will start with zeros + * if the number is smaller. + * + * \param X Source MPI + * \param buf Output buffer + * \param buflen Output buffer size + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ); + +/** + * \brief Left-shift: X <<= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shift_l( mpi *X, size_t count ); + +/** + * \brief Right-shift: X >>= count + * + * \param X MPI to shift + * \param count Amount to shift + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_shift_r( mpi *X, size_t count ); + +/** + * \brief Compare unsigned values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if |X| is greater than |Y|, + * -1 if |X| is lesser than |Y| or + * 0 if |X| is equal to |Y| + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param Y Right-hand MPI + * + * \return 1 if X is greater than Y, + * -1 if X is lesser than Y or + * 0 if X is equal to Y + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ); + +/** + * \brief Compare signed values + * + * \param X Left-hand MPI + * \param z The integer value to compare to + * + * \return 1 if X is greater than z, + * -1 if X is lesser than z or + * 0 if X is equal to z + */ +int mpi_cmp_int( const mpi *X, t_sint z ); + +/** + * \brief Unsigned addition: X = |A| + |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Unsigned subtraction: X = |A| - |B| + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed subtraction: X = A - B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Signed addition: X = A + b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to add + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Signed subtraction: X = A - b + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to subtract + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Baseline multiplication: X = A * B + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); + +/** + * \brief Baseline multiplication: X = A * b + * Note: despite the functon signature, b is treated as a + * t_uint. Negative values of b are treated as large positive + * values. + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param b The integer value to multiply with + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ); + +/** + * \brief Division by mpi: A = Q * B + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Division by int: A = Q * b + R + * + * \param Q Destination MPI for the quotient + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 + * + * \note Either Q or R can be NULL. + */ +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ); + +/** + * \brief Modulo: R = A mod B + * + * \param R Destination MPI for the rest value + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); + +/** + * \brief Modulo: r = A mod b + * + * \param r Destination t_uint + * \param A Left-hand MPI + * \param b Integer to divide by + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, + * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); + +/** + * \brief Sliding-window exponentiation: X = A^E mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param E Exponent MPI + * \param N Modular MPI + * \param _RR Speed-up MPI used for recalculations + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or + * if E is negative + * + * \note _RR is used to avoid re-computing R*R mod N across + * multiple calls, which speeds up things a bit. It can + * be set to NULL if the extra performance is unneeded. + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); + +/** + * \brief Fill an MPI X with size bytes of random + * + * \param X Destination MPI + * \param size Size in bytes + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_fill_random( mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Greatest common divisor: G = gcd(A, B) + * + * \param G Destination MPI + * \param A Left-hand MPI + * \param B Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); + +/** + * \brief Modular inverse: X = A^-1 mod N + * + * \param X Destination MPI + * \param A Left-hand MPI + * \param N Right-hand MPI + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil + POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N + */ +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); + +/** + * \brief Miller-Rabin primality test + * + * \param X MPI to check + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime + */ +int mpi_is_prime( mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Prime number generation + * + * \param X Destination MPI + * \param nbits Required size of X in bits + * ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS ) + * \param dh_flag If 1, then (X-1)/2 will be prime too + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful (probably prime), + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 + */ +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mpi_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* bignum.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/blowfish.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/blowfish.h new file mode 100644 index 0000000..c652b46 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/blowfish.h @@ -0,0 +1,197 @@ +/** + * \file blowfish.h + * + * \brief Blowfish block cipher + * + * Copyright (C) 2012-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_BLOWFISH_H +#define POLARSSL_BLOWFISH_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define BLOWFISH_ENCRYPT 1 +#define BLOWFISH_DECRYPT 0 +#define BLOWFISH_MAX_KEY 448 +#define BLOWFISH_MIN_KEY 32 +#define BLOWFISH_ROUNDS 16 /**< Rounds to use. When increasing this value, make sure to extend the initialisation vectors */ +#define BLOWFISH_BLOCKSIZE 8 /* Blowfish uses 64 bit blocks */ + +#define POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH -0x0016 /**< Invalid key length. */ +#define POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH -0x0018 /**< Invalid data input length. */ + +#if !defined(POLARSSL_BLOWFISH_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Blowfish context structure + */ +typedef struct +{ + uint32_t P[BLOWFISH_ROUNDS + 2]; /*!< Blowfish round keys */ + uint32_t S[4][256]; /*!< key dependent S-boxes */ +} +blowfish_context; + +/** + * \brief Initialize Blowfish context + * + * \param ctx Blowfish context to be initialized + */ +void blowfish_init( blowfish_context *ctx ); + +/** + * \brief Clear Blowfish context + * + * \param ctx Blowfish context to be cleared + */ +void blowfish_free( blowfish_context *ctx ); + +/** + * \brief Blowfish key schedule + * + * \param ctx Blowfish context to be initialized + * \param key encryption key + * \param keysize must be between 32 and 448 bits + * + * \return 0 if successful, or POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH + */ +int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief Blowfish-ECB block encryption/decryption + * + * \param ctx Blowfish context + * \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT + * \param input 8-byte input block + * \param output 8-byte output block + * + * \return 0 if successful + */ +int blowfish_crypt_ecb( blowfish_context *ctx, + int mode, + const unsigned char input[BLOWFISH_BLOCKSIZE], + unsigned char output[BLOWFISH_BLOCKSIZE] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief Blowfish-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (8 bytes) + * + * \param ctx Blowfish context + * \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or + * POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH + */ +int blowfish_crypt_cbc( blowfish_context *ctx, + int mode, + size_t length, + unsigned char iv[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/** + * \brief Blowfish CFB buffer encryption/decryption. + * + * \param ctx Blowfish context + * \param mode BLOWFISH_ENCRYPT or BLOWFISH_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful + */ +int blowfish_crypt_cfb64( blowfish_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ); +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/** + * \brief Blowfish-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * \param ctx Blowfish context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 64-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int blowfish_crypt_ctr( blowfish_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[BLOWFISH_BLOCKSIZE], + unsigned char stream_block[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_BLOWFISH_ALT */ +#include "blowfish_alt.h" +#endif /* POLARSSL_BLOWFISH_ALT */ + +#endif /* blowfish.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bn_mul.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bn_mul.h new file mode 100644 index 0000000..64b59ff --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/bn_mul.h @@ -0,0 +1,873 @@ +/** + * \file bn_mul.h + * + * \brief Multi-precision integer library + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * Multiply source vector [s] with b, add result + * to destination vector [d] and set carry c. + * + * Currently supports: + * + * . IA-32 (386+) . AMD64 / EM64T + * . IA-32 (SSE2) . Motorola 68000 + * . PowerPC, 32-bit . MicroBlaze + * . PowerPC, 64-bit . TriCore + * . SPARC v8 . ARM v3+ + * . Alpha . MIPS32 + * . C, longlong . C, generic + */ +#ifndef POLARSSL_BN_MUL_H +#define POLARSSL_BN_MUL_H + +#include "bignum.h" + +#if defined(POLARSSL_HAVE_ASM) + +#if defined(__GNUC__) +#if defined(__i386__) + +#define MULADDC_INIT \ + asm( \ + "movl %%ebx, %0 \n\t" \ + "movl %5, %%esi \n\t" \ + "movl %6, %%edi \n\t" \ + "movl %7, %%ecx \n\t" \ + "movl %8, %%ebx \n\t" + +#define MULADDC_CORE \ + "lodsl \n\t" \ + "mull %%ebx \n\t" \ + "addl %%ecx, %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "addl (%%edi), %%eax \n\t" \ + "adcl $0, %%edx \n\t" \ + "movl %%edx, %%ecx \n\t" \ + "stosl \n\t" + +#if defined(POLARSSL_HAVE_SSE2) + +#define MULADDC_HUIT \ + "movd %%ecx, %%mm1 \n\t" \ + "movd %%ebx, %%mm0 \n\t" \ + "movd (%%edi), %%mm3 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd (%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "movd 4(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "movd 8(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd 12(%%esi), %%mm7 \n\t" \ + "pmuludq %%mm0, %%mm7 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 4(%%edi), %%mm3 \n\t" \ + "paddq %%mm4, %%mm3 \n\t" \ + "movd 8(%%edi), %%mm5 \n\t" \ + "paddq %%mm6, %%mm5 \n\t" \ + "movd 12(%%edi), %%mm4 \n\t" \ + "paddq %%mm4, %%mm7 \n\t" \ + "movd %%mm1, (%%edi) \n\t" \ + "movd 16(%%esi), %%mm2 \n\t" \ + "pmuludq %%mm0, %%mm2 \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 20(%%esi), %%mm4 \n\t" \ + "pmuludq %%mm0, %%mm4 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd 24(%%esi), %%mm6 \n\t" \ + "pmuludq %%mm0, %%mm6 \n\t" \ + "movd %%mm1, 4(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd 28(%%esi), %%mm3 \n\t" \ + "pmuludq %%mm0, %%mm3 \n\t" \ + "paddq %%mm5, %%mm1 \n\t" \ + "movd 16(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm2 \n\t" \ + "movd %%mm1, 8(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm7, %%mm1 \n\t" \ + "movd 20(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm4 \n\t" \ + "movd %%mm1, 12(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm2, %%mm1 \n\t" \ + "movd 24(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm6 \n\t" \ + "movd %%mm1, 16(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm4, %%mm1 \n\t" \ + "movd 28(%%edi), %%mm5 \n\t" \ + "paddq %%mm5, %%mm3 \n\t" \ + "movd %%mm1, 20(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm6, %%mm1 \n\t" \ + "movd %%mm1, 24(%%edi) \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "paddq %%mm3, %%mm1 \n\t" \ + "movd %%mm1, 28(%%edi) \n\t" \ + "addl $32, %%edi \n\t" \ + "addl $32, %%esi \n\t" \ + "psrlq $32, %%mm1 \n\t" \ + "movd %%mm1, %%ecx \n\t" + +#define MULADDC_STOP \ + "emms \n\t" \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); + +#else + +#define MULADDC_STOP \ + "movl %4, %%ebx \n\t" \ + "movl %%ecx, %1 \n\t" \ + "movl %%edi, %2 \n\t" \ + "movl %%esi, %3 \n\t" \ + : "=m" (t), "=m" (c), "=m" (d), "=m" (s) \ + : "m" (t), "m" (s), "m" (d), "m" (c), "m" (b) \ + : "eax", "ecx", "edx", "esi", "edi" \ + ); +#endif /* SSE2 */ +#endif /* i386 */ + +#if defined(__amd64__) || defined (__x86_64__) + +#define MULADDC_INIT \ + asm( \ + "movq %3, %%rsi \n\t" \ + "movq %4, %%rdi \n\t" \ + "movq %5, %%rcx \n\t" \ + "movq %6, %%rbx \n\t" \ + "xorq %%r8, %%r8 \n\t" + +#define MULADDC_CORE \ + "movq (%%rsi), %%rax \n\t" \ + "mulq %%rbx \n\t" \ + "addq $8, %%rsi \n\t" \ + "addq %%rcx, %%rax \n\t" \ + "movq %%r8, %%rcx \n\t" \ + "adcq $0, %%rdx \n\t" \ + "nop \n\t" \ + "addq %%rax, (%%rdi) \n\t" \ + "adcq %%rdx, %%rcx \n\t" \ + "addq $8, %%rdi \n\t" + +#define MULADDC_STOP \ + "movq %%rcx, %0 \n\t" \ + "movq %%rdi, %1 \n\t" \ + "movq %%rsi, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" \ + ); + +#endif /* AMD64 */ + +#if defined(__mc68020__) || defined(__mcpu32__) + +#define MULADDC_INIT \ + asm( \ + "movl %3, %%a2 \n\t" \ + "movl %4, %%a3 \n\t" \ + "movl %5, %%d3 \n\t" \ + "movl %6, %%d2 \n\t" \ + "moveq #0, %%d0 \n\t" + +#define MULADDC_CORE \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "moveq #0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d4, %%d3 \n\t" + +#define MULADDC_STOP \ + "movl %%d3, %0 \n\t" \ + "movl %%a3, %1 \n\t" \ + "movl %%a2, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "d2", "d3", "d4", "a2", "a3" \ + ); + +#define MULADDC_HUIT \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d4:%%d1 \n\t" \ + "addxl %%d3, %%d1 \n\t" \ + "addxl %%d0, %%d4 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "movel %%a2@+, %%d1 \n\t" \ + "mulul %%d2, %%d3:%%d1 \n\t" \ + "addxl %%d4, %%d1 \n\t" \ + "addxl %%d0, %%d3 \n\t" \ + "addl %%d1, %%a3@+ \n\t" \ + "addxl %%d0, %%d3 \n\t" + +#endif /* MC68000 */ + +#if defined(__powerpc64__) || defined(__ppc64__) + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( \ + "ld r3, %3 \n\t" \ + "ld r4, %4 \n\t" \ + "ld r5, %5 \n\t" \ + "ld r6, %6 \n\t" \ + "addi r3, r3, -8 \n\t" \ + "addi r4, r4, -8 \n\t" \ + "addic r5, r5, 0 \n\t" + +#define MULADDC_CORE \ + "ldu r7, 8(r3) \n\t" \ + "mulld r8, r7, r6 \n\t" \ + "mulhdu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "ld r7, 8(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stdu r8, 8(r4) \n\t" + +#define MULADDC_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 8 \n\t" \ + "addi r3, r3, 8 \n\t" \ + "std r5, %0 \n\t" \ + "std r4, %1 \n\t" \ + "std r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + + +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_INIT \ + asm( \ + "ld %%r3, %3 \n\t" \ + "ld %%r4, %4 \n\t" \ + "ld %%r5, %5 \n\t" \ + "ld %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -8 \n\t" \ + "addi %%r4, %%r4, -8 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_CORE \ + "ldu %%r7, 8(%%r3) \n\t" \ + "mulld %%r8, %%r7, %%r6 \n\t" \ + "mulhdu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "ld %%r7, 8(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stdu %%r8, 8(%%r4) \n\t" + +#define MULADDC_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 8 \n\t" \ + "addi %%r3, %%r3, 8 \n\t" \ + "std %%r5, %0 \n\t" \ + "std %%r4, %1 \n\t" \ + "std %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#endif /* __MACH__ && __APPLE__ */ + +#elif defined(__powerpc__) || defined(__ppc__) /* end PPC64/begin PPC32 */ + +#if defined(__MACH__) && defined(__APPLE__) + +#define MULADDC_INIT \ + asm( \ + "lwz r3, %3 \n\t" \ + "lwz r4, %4 \n\t" \ + "lwz r5, %5 \n\t" \ + "lwz r6, %6 \n\t" \ + "addi r3, r3, -4 \n\t" \ + "addi r4, r4, -4 \n\t" \ + "addic r5, r5, 0 \n\t" + +#define MULADDC_CORE \ + "lwzu r7, 4(r3) \n\t" \ + "mullw r8, r7, r6 \n\t" \ + "mulhwu r9, r7, r6 \n\t" \ + "adde r8, r8, r5 \n\t" \ + "lwz r7, 4(r4) \n\t" \ + "addze r5, r9 \n\t" \ + "addc r8, r8, r7 \n\t" \ + "stwu r8, 4(r4) \n\t" + +#define MULADDC_STOP \ + "addze r5, r5 \n\t" \ + "addi r4, r4, 4 \n\t" \ + "addi r3, r3, 4 \n\t" \ + "stw r5, %0 \n\t" \ + "stw r4, %1 \n\t" \ + "stw r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#else /* __MACH__ && __APPLE__ */ + +#define MULADDC_INIT \ + asm( \ + "lwz %%r3, %3 \n\t" \ + "lwz %%r4, %4 \n\t" \ + "lwz %%r5, %5 \n\t" \ + "lwz %%r6, %6 \n\t" \ + "addi %%r3, %%r3, -4 \n\t" \ + "addi %%r4, %%r4, -4 \n\t" \ + "addic %%r5, %%r5, 0 \n\t" + +#define MULADDC_CORE \ + "lwzu %%r7, 4(%%r3) \n\t" \ + "mullw %%r8, %%r7, %%r6 \n\t" \ + "mulhwu %%r9, %%r7, %%r6 \n\t" \ + "adde %%r8, %%r8, %%r5 \n\t" \ + "lwz %%r7, 4(%%r4) \n\t" \ + "addze %%r5, %%r9 \n\t" \ + "addc %%r8, %%r8, %%r7 \n\t" \ + "stwu %%r8, 4(%%r4) \n\t" + +#define MULADDC_STOP \ + "addze %%r5, %%r5 \n\t" \ + "addi %%r4, %%r4, 4 \n\t" \ + "addi %%r3, %%r3, 4 \n\t" \ + "stw %%r5, %0 \n\t" \ + "stw %%r4, %1 \n\t" \ + "stw %%r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4", "r5", "r6", "r7", "r8", "r9" \ + ); + +#endif /* __MACH__ && __APPLE__ */ + +#endif /* PPC32 */ + +/* + * The Sparc64 assembly is reported to be broken. + * Disable it for now, until we're able to fix it. + */ +#if 0 && defined(__sparc__) && defined(__sparc64__) + +#define MULADDC_INIT \ + asm( \ + "ldx %3, %%o0 \n\t" \ + "ldx %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + + #define MULADDC_STOP \ + "st %%o2, %0 \n\t" \ + "stx %%o1, %1 \n\t" \ + "stx %%o0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); +#endif /* SPARCv9 */ + +#if defined(__sparc__) && !defined(__sparc64__) + +#define MULADDC_INIT \ + asm( \ + "ld %3, %%o0 \n\t" \ + "ld %4, %%o1 \n\t" \ + "ld %5, %%o2 \n\t" \ + "ld %6, %%o3 \n\t" + +#define MULADDC_CORE \ + "ld [%%o0], %%o4 \n\t" \ + "inc 4, %%o0 \n\t" \ + "ld [%%o1], %%o5 \n\t" \ + "umul %%o3, %%o4, %%o4 \n\t" \ + "addcc %%o4, %%o2, %%o4 \n\t" \ + "rd %%y, %%g1 \n\t" \ + "addx %%g1, 0, %%g1 \n\t" \ + "addcc %%o4, %%o5, %%o4 \n\t" \ + "st %%o4, [%%o1] \n\t" \ + "addx %%g1, 0, %%o2 \n\t" \ + "inc 4, %%o1 \n\t" + +#define MULADDC_STOP \ + "st %%o2, %0 \n\t" \ + "st %%o1, %1 \n\t" \ + "st %%o0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "g1", "o0", "o1", "o2", "o3", "o4", \ + "o5" \ + ); + +#endif /* SPARCv8 */ + +#if defined(__microblaze__) || defined(microblaze) + +#define MULADDC_INIT \ + asm( \ + "lwi r3, %3 \n\t" \ + "lwi r4, %4 \n\t" \ + "lwi r5, %5 \n\t" \ + "lwi r6, %6 \n\t" \ + "andi r7, r6, 0xffff \n\t" \ + "bsrli r6, r6, 16 \n\t" + +#define MULADDC_CORE \ + "lhui r8, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "lhui r9, r3, 0 \n\t" \ + "addi r3, r3, 2 \n\t" \ + "mul r10, r9, r6 \n\t" \ + "mul r11, r8, r7 \n\t" \ + "mul r12, r9, r7 \n\t" \ + "mul r13, r8, r6 \n\t" \ + "bsrli r8, r10, 16 \n\t" \ + "bsrli r9, r11, 16 \n\t" \ + "add r13, r13, r8 \n\t" \ + "add r13, r13, r9 \n\t" \ + "bslli r10, r10, 16 \n\t" \ + "bslli r11, r11, 16 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r11 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "lwi r10, r4, 0 \n\t" \ + "add r12, r12, r10 \n\t" \ + "addc r13, r13, r0 \n\t" \ + "add r12, r12, r5 \n\t" \ + "addc r5, r13, r0 \n\t" \ + "swi r12, r4, 0 \n\t" \ + "addi r4, r4, 4 \n\t" + +#define MULADDC_STOP \ + "swi r5, %0 \n\t" \ + "swi r4, %1 \n\t" \ + "swi r3, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r3", "r4" "r5", "r6", "r7", "r8", \ + "r9", "r10", "r11", "r12", "r13" \ + ); + +#endif /* MicroBlaze */ + +#if defined(__tricore__) + +#define MULADDC_INIT \ + asm( \ + "ld.a %%a2, %3 \n\t" \ + "ld.a %%a3, %4 \n\t" \ + "ld.w %%d4, %5 \n\t" \ + "ld.w %%d1, %6 \n\t" \ + "xor %%d5, %%d5 \n\t" + +#define MULADDC_CORE \ + "ld.w %%d0, [%%a2+] \n\t" \ + "madd.u %%e2, %%e4, %%d0, %%d1 \n\t" \ + "ld.w %%d0, [%%a3] \n\t" \ + "addx %%d2, %%d2, %%d0 \n\t" \ + "addc %%d3, %%d3, 0 \n\t" \ + "mov %%d4, %%d3 \n\t" \ + "st.w [%%a3+], %%d2 \n\t" + +#define MULADDC_STOP \ + "st.w %0, %%d4 \n\t" \ + "st.a %1, %%a3 \n\t" \ + "st.a %2, %%a2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "d0", "d1", "e2", "d4", "a2", "a3" \ + ); + +#endif /* TriCore */ + +#if defined(__arm__) + +#if defined(__thumb__) && !defined(__thumb2__) + +#define MULADDC_INIT \ + asm( \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" \ + "lsr r7, r3, #16 \n\t" \ + "mov r9, r7 \n\t" \ + "lsl r7, r3, #16 \n\t" \ + "lsr r7, r7, #16 \n\t" \ + "mov r8, r7 \n\t" + +#define MULADDC_CORE \ + "ldmia r0!, {r6} \n\t" \ + "lsr r7, r6, #16 \n\t" \ + "lsl r6, r6, #16 \n\t" \ + "lsr r6, r6, #16 \n\t" \ + "mov r4, r8 \n\t" \ + "mul r4, r6 \n\t" \ + "mov r3, r9 \n\t" \ + "mul r6, r3 \n\t" \ + "mov r5, r9 \n\t" \ + "mul r5, r7 \n\t" \ + "mov r3, r8 \n\t" \ + "mul r7, r3 \n\t" \ + "lsr r3, r6, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "lsr r3, r7, #16 \n\t" \ + "add r5, r5, r3 \n\t" \ + "add r4, r4, r2 \n\t" \ + "mov r2, #0 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, r6, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + "lsl r3, r7, #16 \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r5, r2 \n\t" \ + "ldr r3, [r1] \n\t" \ + "add r4, r4, r3 \n\t" \ + "adc r2, r5 \n\t" \ + "stmia r1!, {r4} \n\t" + +#define MULADDC_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", "r7", "r8", "r9", "cc" \ + ); + +#else + +#define MULADDC_INIT \ + asm( \ + "ldr r0, %3 \n\t" \ + "ldr r1, %4 \n\t" \ + "ldr r2, %5 \n\t" \ + "ldr r3, %6 \n\t" + +#define MULADDC_CORE \ + "ldr r4, [r0], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r1] \n\t" \ + "umlal r2, r5, r3, r4 \n\t" \ + "adds r7, r6, r2 \n\t" \ + "adc r2, r5, #0 \n\t" \ + "str r7, [r1], #4 \n\t" + +#define MULADDC_STOP \ + "str r2, %0 \n\t" \ + "str r1, %1 \n\t" \ + "str r0, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "r0", "r1", "r2", "r3", "r4", "r5", \ + "r6", "r7", "cc" \ + ); + +#endif /* Thumb */ + +#endif /* ARMv3 */ + +#if defined(__alpha__) + +#define MULADDC_INIT \ + asm( \ + "ldq $1, %3 \n\t" \ + "ldq $2, %4 \n\t" \ + "ldq $3, %5 \n\t" \ + "ldq $4, %6 \n\t" + +#define MULADDC_CORE \ + "ldq $6, 0($1) \n\t" \ + "addq $1, 8, $1 \n\t" \ + "mulq $6, $4, $7 \n\t" \ + "umulh $6, $4, $6 \n\t" \ + "addq $7, $3, $7 \n\t" \ + "cmpult $7, $3, $3 \n\t" \ + "ldq $5, 0($2) \n\t" \ + "addq $7, $5, $7 \n\t" \ + "cmpult $7, $5, $5 \n\t" \ + "stq $7, 0($2) \n\t" \ + "addq $2, 8, $2 \n\t" \ + "addq $6, $3, $3 \n\t" \ + "addq $5, $3, $3 \n\t" + +#define MULADDC_STOP \ + "stq $3, %0 \n\t" \ + "stq $2, %1 \n\t" \ + "stq $1, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$1", "$2", "$3", "$4", "$5", "$6", "$7" \ + ); +#endif /* Alpha */ + +#if defined(__mips__) && !defined(__mips64__) + +#define MULADDC_INIT \ + asm( \ + "lw $10, %3 \n\t" \ + "lw $11, %4 \n\t" \ + "lw $12, %5 \n\t" \ + "lw $13, %6 \n\t" + +#define MULADDC_CORE \ + "lw $14, 0($10) \n\t" \ + "multu $13, $14 \n\t" \ + "addi $10, $10, 4 \n\t" \ + "mflo $14 \n\t" \ + "mfhi $9 \n\t" \ + "addu $14, $12, $14 \n\t" \ + "lw $15, 0($11) \n\t" \ + "sltu $12, $14, $12 \n\t" \ + "addu $15, $14, $15 \n\t" \ + "sltu $14, $15, $14 \n\t" \ + "addu $12, $12, $9 \n\t" \ + "sw $15, 0($11) \n\t" \ + "addu $12, $12, $14 \n\t" \ + "addi $11, $11, 4 \n\t" + +#define MULADDC_STOP \ + "sw $12, %0 \n\t" \ + "sw $11, %1 \n\t" \ + "sw $10, %2 \n\t" \ + : "=m" (c), "=m" (d), "=m" (s) \ + : "m" (s), "m" (d), "m" (c), "m" (b) \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \ + ); + +#endif /* MIPS */ +#endif /* GNUC */ + +#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) + +#define MULADDC_INIT \ + __asm mov esi, s \ + __asm mov edi, d \ + __asm mov ecx, c \ + __asm mov ebx, b + +#define MULADDC_CORE \ + __asm lodsd \ + __asm mul ebx \ + __asm add eax, ecx \ + __asm adc edx, 0 \ + __asm add eax, [edi] \ + __asm adc edx, 0 \ + __asm mov ecx, edx \ + __asm stosd + +#if defined(POLARSSL_HAVE_SSE2) + +#define EMIT __asm _emit + +#define MULADDC_HUIT \ + EMIT 0x0F EMIT 0x6E EMIT 0xC9 \ + EMIT 0x0F EMIT 0x6E EMIT 0xC3 \ + EMIT 0x0F EMIT 0x6E EMIT 0x1F \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x16 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xEE \ + EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xFC \ + EMIT 0x0F EMIT 0x7E EMIT 0x0F \ + EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \ + EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \ + EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCD \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCF \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCA \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCC \ + EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \ + EMIT 0x0F EMIT 0xD4 EMIT 0xDD \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCE \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0xD4 EMIT 0xCB \ + EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \ + EMIT 0x83 EMIT 0xC7 EMIT 0x20 \ + EMIT 0x83 EMIT 0xC6 EMIT 0x20 \ + EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \ + EMIT 0x0F EMIT 0x7E EMIT 0xC9 + +#define MULADDC_STOP \ + EMIT 0x0F EMIT 0x77 \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#else + +#define MULADDC_STOP \ + __asm mov c, ecx \ + __asm mov d, edi \ + __asm mov s, esi \ + +#endif /* SSE2 */ +#endif /* MSVC */ + +#endif /* POLARSSL_HAVE_ASM */ + +#if !defined(MULADDC_CORE) +#if defined(POLARSSL_HAVE_UDBL) + +#define MULADDC_INIT \ +{ \ + t_udbl r; \ + t_uint r0, r1; + +#define MULADDC_CORE \ + r = *(s++) * (t_udbl) b; \ + r0 = r; \ + r1 = r >> biL; \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#else +#define MULADDC_INIT \ +{ \ + t_uint s0, s1, b0, b1; \ + t_uint r0, r1, rx, ry; \ + b0 = ( b << biH ) >> biH; \ + b1 = ( b >> biH ); + +#define MULADDC_CORE \ + s0 = ( *s << biH ) >> biH; \ + s1 = ( *s >> biH ); s++; \ + rx = s0 * b1; r0 = s0 * b0; \ + ry = s1 * b0; r1 = s1 * b1; \ + r1 += ( rx >> biH ); \ + r1 += ( ry >> biH ); \ + rx <<= biH; ry <<= biH; \ + r0 += rx; r1 += (r0 < rx); \ + r0 += ry; r1 += (r0 < ry); \ + r0 += c; r1 += (r0 < c); \ + r0 += *d; r1 += (r0 < *d); \ + c = r1; *(d++) = r0; + +#define MULADDC_STOP \ +} + +#endif /* C (generic) */ +#endif /* C (longlong) */ + +#endif /* bn_mul.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/camellia.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/camellia.h new file mode 100644 index 0000000..8488d1d --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/camellia.h @@ -0,0 +1,229 @@ +/** + * \file camellia.h + * + * \brief Camellia block cipher + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CAMELLIA_H +#define POLARSSL_CAMELLIA_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define CAMELLIA_ENCRYPT 1 +#define CAMELLIA_DECRYPT 0 + +#define POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH -0x0024 /**< Invalid key length. */ +#define POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH -0x0026 /**< Invalid data input length. */ + +#if !defined(POLARSSL_CAMELLIA_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CAMELLIA context structure + */ +typedef struct +{ + int nr; /*!< number of rounds */ + uint32_t rk[68]; /*!< CAMELLIA round keys */ +} +camellia_context; + +/** + * \brief Initialize CAMELLIA context + * + * \param ctx CAMELLIA context to be initialized + */ +void camellia_init( camellia_context *ctx ); + +/** + * \brief Clear CAMELLIA context + * + * \param ctx CAMELLIA context to be cleared + */ +void camellia_free( camellia_context *ctx ); + +/** + * \brief CAMELLIA key schedule (encryption) + * + * \param ctx CAMELLIA context to be initialized + * \param key encryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH + */ +int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief CAMELLIA key schedule (decryption) + * + * \param ctx CAMELLIA context to be initialized + * \param key decryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH + */ +int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief CAMELLIA-ECB block encryption/decryption + * + * \param ctx CAMELLIA context + * \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if successful + */ +int camellia_crypt_ecb( camellia_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief CAMELLIA-CBC buffer encryption/decryption + * Length should be a multiple of the block + * size (16 bytes) + * + * \param ctx CAMELLIA context + * \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or + * POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH + */ +int camellia_crypt_cbc( camellia_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/** + * \brief CAMELLIA-CFB128 buffer encryption/decryption + * + * Note: Due to the nature of CFB you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIE_DECRYPT. + * + * \param ctx CAMELLIA context + * \param mode CAMELLIA_ENCRYPT or CAMELLIA_DECRYPT + * \param length length of the input data + * \param iv_off offset in IV (updated after use) + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or + * POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH + */ +int camellia_crypt_cfb128( camellia_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/** + * \brief CAMELLIA-CTR buffer encryption/decryption + * + * Warning: You have to keep the maximum use of your counter in mind! + * + * Note: Due to the nature of CTR you should use the same key schedule for + * both encryption and decryption. So a context initialized with + * camellia_setkey_enc() for both CAMELLIA_ENCRYPT and CAMELLIA_DECRYPT. + * + * \param ctx CAMELLIA context + * \param length The length of the data + * \param nc_off The offset in the current stream_block (for resuming + * within current cipher stream). The offset pointer to + * should be 0 at the start of a stream. + * \param nonce_counter The 128-bit nonce and counter. + * \param stream_block The saved stream-block for resuming. Is overwritten + * by the function. + * \param input The input data stream + * \param output The output data stream + * + * \return 0 if successful + */ +int camellia_crypt_ctr( camellia_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_CAMELLIA_ALT */ +#include "camellia_alt.h" +#endif /* POLARSSL_CAMELLIA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int camellia_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* camellia.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ccm.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ccm.h new file mode 100644 index 0000000..439152f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ccm.h @@ -0,0 +1,134 @@ +/** + * \file ccm.h + * + * \brief Counter with CBC-MAC (CCM) for 128-bit block ciphers + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CCM_H +#define POLARSSL_CCM_H + +#include "cipher.h" + +#define POLARSSL_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to function. */ +#define POLARSSL_ERR_CCM_AUTH_FAILED -0x000F /**< Authenticated decryption failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CCM context structure + */ +typedef struct { + cipher_context_t cipher_ctx; /*!< cipher context used */ +} +ccm_context; + +/** + * \brief CCM initialization (encryption and decryption) + * + * \param ctx CCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keysize key size in bits (must be acceptable by the cipher) + * + * \return 0 if successful, or a cipher specific error code + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ); + +/** + * \brief Free a CCM context and underlying cipher sub-context + * + * \param ctx CCM context to free + */ +void ccm_free( ccm_context *ctx ); + +/** + * \brief CCM buffer encryption + * + * \param ctx CCM context + * \param length length of the input data in bytes + * \param iv nonce (initialization vector) + * \param iv_len length of IV in bytes + * must be 2, 3, 4, 5, 6, 7 or 8 + * \param add additional data + * \param add_len length of additional data in bytes + * must be less than 2^16 - 2^8 + * \param input buffer holding the input data + * \param output buffer for holding the output data + * must be at least 'length' bytes wide + * \param tag buffer for holding the tag + * \param tag_len length of the tag to generate in bytes + * must be 4, 6, 8, 10, 14 or 16 + * + * \note The tag is written to a separate buffer. To get the tag + * concatenated with the output as in the CCM spec, use + * tag = output + length and make sure the output buffer is + * at least length + tag_len wide. + * + * \return 0 if successful + */ +int ccm_encrypt_and_tag( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ); + +/** + * \brief CCM buffer authenticated decryption + * + * \param ctx CCM context + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * \param tag buffer holding the tag + * \param tag_len length of the tag + * + * \return 0 if successful and authenticated, + * POLARSSL_ERR_CCM_AUTH_FAILED if tag does not match + */ +int ccm_auth_decrypt( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ); + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ccm_self_test( int verbose ); +#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_CGM_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/certs.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/certs.h new file mode 100644 index 0000000..ba7c028 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/certs.h @@ -0,0 +1,77 @@ +/** + * \file certs.h + * + * \brief Sample certificates and DHM parameters for testing + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CERTS_H +#define POLARSSL_CERTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Concatenation of all available CA certificates */ +extern const char test_ca_list[]; + +/* + * Convenience for users who just want a certificate: + * RSA by default, or ECDSA if RSA i not available + */ +extern const char *test_ca_crt; +extern const char *test_ca_key; +extern const char *test_ca_pwd; +extern const char *test_srv_crt; +extern const char *test_srv_key; +extern const char *test_cli_crt; +extern const char *test_cli_key; + +#if defined(POLARSSL_ECDSA_C) +extern const char test_ca_crt_ec[]; +extern const char test_ca_key_ec[]; +extern const char test_ca_pwd_ec[]; +extern const char test_srv_crt_ec[]; +extern const char test_srv_key_ec[]; +extern const char test_cli_crt_ec[]; +extern const char test_cli_key_ec[]; +#endif + +#if defined(POLARSSL_RSA_C) +extern const char test_ca_crt_rsa[]; +extern const char test_ca_key_rsa[]; +extern const char test_ca_pwd_rsa[]; +extern const char test_srv_crt_rsa[]; +extern const char test_srv_key_rsa[]; +extern const char test_cli_crt_rsa[]; +extern const char test_cli_key_rsa[]; +#endif + +#if defined(POLARSSL_DHM_C) +extern const char test_dhm_params[]; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* certs.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/check_config.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/check_config.h new file mode 100644 index 0000000..d0f5a9e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/check_config.h @@ -0,0 +1,336 @@ +/** + * \file check_config.h + * + * \brief Consistency checks for configuration options + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * It is recommended to include this file from your config.h + * in order to catch dependency issues early. + */ + +#ifndef POLARSSL_CHECK_CONFIG_H +#define POLARSSL_CHECK_CONFIG_H + +#if defined(POLARSSL_AESNI_C) && !defined(POLARSSL_HAVE_ASM) +#error "POLARSSL_AESNI_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_CERTS_C) && !defined(POLARSSL_PEM_PARSE_C) +#error "POLARSSL_CERTS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_CTR_DRBG_C) && !defined(POLARSSL_AES_C) +#error "POLARSSL_CTR_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_DHM_C) && !defined(POLARSSL_BIGNUM_C) +#error "POLARSSL_DHM_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDH_C) && !defined(POLARSSL_ECP_C) +#error "POLARSSL_ECDH_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDSA_C) && \ + ( !defined(POLARSSL_ECP_C) || \ + !defined(POLARSSL_ASN1_PARSE_C) || \ + !defined(POLARSSL_ASN1_WRITE_C) ) +#error "POLARSSL_ECDSA_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) && !defined(POLARSSL_HMAC_DRBG_C) +#error "POLARSSL_ECDSA_DETERMINISTIC defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ECP_C) && ( !defined(POLARSSL_BIGNUM_C) || ( \ + !defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP256R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP384R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_BP512R1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) && \ + !defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) ) ) +#error "POLARSSL_ECP_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_ENTROPY_C) && (!defined(POLARSSL_SHA512_C) && \ + !defined(POLARSSL_SHA256_C)) +#error "POLARSSL_ENTROPY_C defined, but not all prerequisites" +#endif +#if defined(POLARSSL_ENTROPY_C) && defined(POLARSSL_SHA512_C) && \ + defined(CTR_DRBG_ENTROPY_LEN) && (CTR_DRBG_ENTROPY_LEN > 64) +#error "CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(POLARSSL_ENTROPY_C) && \ + ( !defined(POLARSSL_SHA512_C) || defined(POLARSSL_ENTROPY_FORCE_SHA256) ) \ + && defined(CTR_DRBG_ENTROPY_LEN) && (CTR_DRBG_ENTROPY_LEN > 32) +#error "CTR_DRBG_ENTROPY_LEN value too high" +#endif +#if defined(POLARSSL_ENTROPY_C) && \ + defined(POLARSSL_ENTROPY_FORCE_SHA256) && !defined(POLARSSL_SHA256_C) +#error "POLARSSL_ENTROPY_FORCE_SHA256 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_GCM_C) && ( \ + !defined(POLARSSL_AES_C) && !defined(POLARSSL_CAMELLIA_C) ) +#error "POLARSSL_GCM_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_HAVEGE_C) && !defined(POLARSSL_TIMING_C) +#error "POLARSSL_HAVEGE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_HMAC_DRBG) && !defined(POLARSSL_MD_C) +#error "POLARSSL_HMAC_DRBG_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) && !defined(POLARSSL_DHM_C) +#error "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(POLARSSL_ECDH_C) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + ( !defined(POLARSSL_DHM_C) || !defined(POLARSSL_RSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_RSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) || !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + ( !defined(POLARSSL_ECDH_C) || !defined(POLARSSL_ECDSA_C) || \ + !defined(POLARSSL_X509_CRT_PARSE_C) ) +#error "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ + !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_X509_CRT_PARSE_C) ||\ + !defined(POLARSSL_PKCS1_V15) ) +#error "POLARSSL_KEY_EXCHANGE_RSA_ENABLED defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) && \ + ( !defined(POLARSSL_PLATFORM_C) || !defined(POLARSSL_PLATFORM_MEMORY) ) +#error "POLARSSL_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PADLOCK_C) && !defined(POLARSSL_HAVE_ASM) +#error "POLARSSL_PADLOCK_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PBKDF2_C) && !defined(POLARSSL_MD_C) +#error "POLARSSL_PBKDF2_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PEM_PARSE_C) && !defined(POLARSSL_BASE64_C) +#error "POLARSSL_PEM_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PEM_WRITE_C) && !defined(POLARSSL_BASE64_C) +#error "POLARSSL_PEM_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PK_PARSE_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PK_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PK_WRITE_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PK_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_PKCS11_C) && !defined(POLARSSL_PK_C) +#error "POLARSSL_PKCS11_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_RSA_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) ) +#error "POLARSSL_RSA_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) && \ + ( !defined(POLARSSL_RSA_C) || !defined(POLARSSL_PKCS1_V21) ) +#error "POLARSSL_X509_RSASSA_PSS_SUPPORT defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_SSL3) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_SSL3 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_TLS1 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_1) && ( !defined(POLARSSL_MD5_C) || \ + !defined(POLARSSL_SHA1_C) ) +#error "POLARSSL_SSL_PROTO_TLS1_1 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) && ( !defined(POLARSSL_SHA1_C) && \ + !defined(POLARSSL_SHA256_C) && !defined(POLARSSL_SHA512_C) ) +#error "POLARSSL_SSL_PROTO_TLS1_2 defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_CLI_C) && !defined(POLARSSL_SSL_TLS_C) +#error "POLARSSL_SSL_CLI_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && ( !defined(POLARSSL_CIPHER_C) || \ + !defined(POLARSSL_MD_C) ) +#error "POLARSSL_SSL_TLS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_SRV_C) && !defined(POLARSSL_SSL_TLS_C) +#error "POLARSSL_SSL_SRV_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (!defined(POLARSSL_SSL_PROTO_SSL3) && \ + !defined(POLARSSL_SSL_PROTO_TLS1) && !defined(POLARSSL_SSL_PROTO_TLS1_1) && \ + !defined(POLARSSL_SSL_PROTO_TLS1_2)) +#error "POLARSSL_SSL_TLS_C defined, but no protocols are active" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_1) && !defined(POLARSSL_SSL_PROTO_TLS1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_TLS1) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && !defined(POLARSSL_SSL_PROTO_TLS1_1)) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_TLS_C) && (defined(POLARSSL_SSL_PROTO_SSL3) && \ + defined(POLARSSL_SSL_PROTO_TLS1_2) && (!defined(POLARSSL_SSL_PROTO_TLS1) || \ + !defined(POLARSSL_SSL_PROTO_TLS1_1))) +#error "Illegal protocol selection" +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) && defined(POLARSSL_SSL_TLS_C) && \ + ( !defined(POLARSSL_AES_C) || !defined(POLARSSL_SHA256_C) || \ + !defined(POLARSSL_CIPHER_MODE_CBC) ) +#error "POLARSSL_SSL_SESSION_TICKETS_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) && \ + !defined(POLARSSL_X509_CRT_PARSE_C) +#error "POLARSSL_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_THREADING_PTHREAD) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_PTHREAD defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_ALT) +#if !defined(POLARSSL_THREADING_C) || defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_ALT defined, but not all prerequisites" +#endif +#define POLARSSL_THREADING_IMPL +#endif + +#if defined(POLARSSL_THREADING_C) && !defined(POLARSSL_THREADING_IMPL) +#error "POLARSSL_THREADING_C defined, single threading implementation required" +#endif +#undef POLARSSL_THREADING_IMPL + +#if defined(POLARSSL_VERSION_FEATURES) && !defined(POLARSSL_VERSION_C) +#error "POLARSSL_VERSION_FEATURES defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_USE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_PARSE_C) || \ + !defined(POLARSSL_PK_PARSE_C) ) +#error "POLARSSL_X509_USE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CREATE_C) && ( !defined(POLARSSL_BIGNUM_C) || \ + !defined(POLARSSL_OID_C) || !defined(POLARSSL_ASN1_WRITE_C) || \ + !defined(POLARSSL_PK_WRITE_C) ) +#error "POLARSSL_X509_CREATE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CRT_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRL_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CRL_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CSR_PARSE_C) && ( !defined(POLARSSL_X509_USE_C) ) +#error "POLARSSL_X509_CSR_PARSE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CRT_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) +#error "POLARSSL_X509_CRT_WRITE_C defined, but not all prerequisites" +#endif + +#if defined(POLARSSL_X509_CSR_WRITE_C) && ( !defined(POLARSSL_X509_CREATE_C) ) +#error "POLARSSL_X509_CSR_WRITE_C defined, but not all prerequisites" +#endif +/* +#if defined(POLARSSL_AES_C) || defined(POLARSSL_DES_C) +#if !defined(RTL_HW_CRYPTO) +#error "POLARSSL_AES_C or POLARSSL_DES_C defined, RTL_HW_CRYPTO required" +#endif +#endif +*/ +#if defined(SUPPORT_HW_SW_CRYPTO) && !defined(RTL_HW_CRYPTO) +#error "SUPPORT_HW_SW_CRYPTO defined, RTL_HW_CRYPTO required" +#endif + +#endif /* POLARSSL_CHECK_CONFIG_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher.h new file mode 100644 index 0000000..087e590 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher.h @@ -0,0 +1,760 @@ +/** + * \file cipher.h + * + * \brief Generic cipher wrapper. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef POLARSSL_CIPHER_H +#define POLARSSL_CIPHER_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) +#define POLARSSL_CIPHER_MODE_AEAD +#endif + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#define POLARSSL_CIPHER_MODE_WITH_PADDING +#endif + +#include + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +#define POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE -0x6080 /**< The selected feature is not available. */ +#define POLARSSL_ERR_CIPHER_BAD_INPUT_DATA -0x6100 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_CIPHER_ALLOC_FAILED -0x6180 /**< Failed to allocate memory. */ +#define POLARSSL_ERR_CIPHER_INVALID_PADDING -0x6200 /**< Input data contains invalid padding and is rejected. */ +#define POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED -0x6280 /**< Decryption of block requires a full block. */ +#define POLARSSL_ERR_CIPHER_AUTH_FAILED -0x6300 /**< Authentication failed (for AEAD modes). */ + +#define POLARSSL_CIPHER_VARIABLE_IV_LEN 0x01 /**< Cipher accepts IVs of variable length */ +#define POLARSSL_CIPHER_VARIABLE_KEY_LEN 0x02 /**< Cipher accepts keys of variable length */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + POLARSSL_CIPHER_ID_NONE = 0, + POLARSSL_CIPHER_ID_NULL, + POLARSSL_CIPHER_ID_AES, + POLARSSL_CIPHER_ID_DES, + POLARSSL_CIPHER_ID_3DES, + POLARSSL_CIPHER_ID_CAMELLIA, + POLARSSL_CIPHER_ID_BLOWFISH, + POLARSSL_CIPHER_ID_ARC4, +} cipher_id_t; + +typedef enum { + POLARSSL_CIPHER_NONE = 0, + POLARSSL_CIPHER_NULL, + POLARSSL_CIPHER_AES_128_ECB, + POLARSSL_CIPHER_AES_192_ECB, + POLARSSL_CIPHER_AES_256_ECB, + POLARSSL_CIPHER_AES_128_CBC, + POLARSSL_CIPHER_AES_192_CBC, + POLARSSL_CIPHER_AES_256_CBC, + POLARSSL_CIPHER_AES_128_CFB128, + POLARSSL_CIPHER_AES_192_CFB128, + POLARSSL_CIPHER_AES_256_CFB128, + POLARSSL_CIPHER_AES_128_CTR, + POLARSSL_CIPHER_AES_192_CTR, + POLARSSL_CIPHER_AES_256_CTR, + POLARSSL_CIPHER_AES_128_GCM, + POLARSSL_CIPHER_AES_192_GCM, + POLARSSL_CIPHER_AES_256_GCM, + POLARSSL_CIPHER_CAMELLIA_128_ECB, + POLARSSL_CIPHER_CAMELLIA_192_ECB, + POLARSSL_CIPHER_CAMELLIA_256_ECB, + POLARSSL_CIPHER_CAMELLIA_128_CBC, + POLARSSL_CIPHER_CAMELLIA_192_CBC, + POLARSSL_CIPHER_CAMELLIA_256_CBC, + POLARSSL_CIPHER_CAMELLIA_128_CFB128, + POLARSSL_CIPHER_CAMELLIA_192_CFB128, + POLARSSL_CIPHER_CAMELLIA_256_CFB128, + POLARSSL_CIPHER_CAMELLIA_128_CTR, + POLARSSL_CIPHER_CAMELLIA_192_CTR, + POLARSSL_CIPHER_CAMELLIA_256_CTR, + POLARSSL_CIPHER_CAMELLIA_128_GCM, + POLARSSL_CIPHER_CAMELLIA_192_GCM, + POLARSSL_CIPHER_CAMELLIA_256_GCM, + POLARSSL_CIPHER_DES_ECB, + POLARSSL_CIPHER_DES_CBC, + POLARSSL_CIPHER_DES_EDE_ECB, + POLARSSL_CIPHER_DES_EDE_CBC, + POLARSSL_CIPHER_DES_EDE3_ECB, + POLARSSL_CIPHER_DES_EDE3_CBC, + POLARSSL_CIPHER_BLOWFISH_ECB, + POLARSSL_CIPHER_BLOWFISH_CBC, + POLARSSL_CIPHER_BLOWFISH_CFB64, + POLARSSL_CIPHER_BLOWFISH_CTR, + POLARSSL_CIPHER_ARC4_128, + POLARSSL_CIPHER_AES_128_CCM, + POLARSSL_CIPHER_AES_192_CCM, + POLARSSL_CIPHER_AES_256_CCM, + POLARSSL_CIPHER_CAMELLIA_128_CCM, + POLARSSL_CIPHER_CAMELLIA_192_CCM, + POLARSSL_CIPHER_CAMELLIA_256_CCM, +} cipher_type_t; + +typedef enum { + POLARSSL_MODE_NONE = 0, + POLARSSL_MODE_ECB, + POLARSSL_MODE_CBC, + POLARSSL_MODE_CFB, + POLARSSL_MODE_OFB, /* Unused! */ + POLARSSL_MODE_CTR, + POLARSSL_MODE_GCM, + POLARSSL_MODE_STREAM, + POLARSSL_MODE_CCM, +} cipher_mode_t; + +typedef enum { + POLARSSL_PADDING_PKCS7 = 0, /**< PKCS7 padding (default) */ + POLARSSL_PADDING_ONE_AND_ZEROS, /**< ISO/IEC 7816-4 padding */ + POLARSSL_PADDING_ZEROS_AND_LEN, /**< ANSI X.923 padding */ + POLARSSL_PADDING_ZEROS, /**< zero padding (not reversible!) */ + POLARSSL_PADDING_NONE, /**< never pad (full blocks only) */ +} cipher_padding_t; + +typedef enum { + POLARSSL_OPERATION_NONE = -1, + POLARSSL_DECRYPT = 0, + POLARSSL_ENCRYPT, +} operation_t; + +enum { + /** Undefined key length */ + POLARSSL_KEY_LENGTH_NONE = 0, + /** Key length, in bits (including parity), for DES keys */ + POLARSSL_KEY_LENGTH_DES = 64, + /** Key length, in bits (including parity), for DES in two key EDE */ + POLARSSL_KEY_LENGTH_DES_EDE = 128, + /** Key length, in bits (including parity), for DES in three-key EDE */ + POLARSSL_KEY_LENGTH_DES_EDE3 = 192, +}; + +/** Maximum length of any IV, in bytes */ +#define POLARSSL_MAX_IV_LENGTH 16 +/** Maximum block size of any cipher, in bytes */ +#define POLARSSL_MAX_BLOCK_LENGTH 16 + +/** + * Base cipher information. The non-mode specific functions and values. + */ +typedef struct { + + /** Base Cipher type (e.g. POLARSSL_CIPHER_ID_AES) */ + cipher_id_t cipher; + + /** Encrypt using ECB */ + int (*ecb_func)( void *ctx, operation_t mode, + const unsigned char *input, unsigned char *output ); + + /** Encrypt using CBC */ + int (*cbc_func)( void *ctx, operation_t mode, size_t length, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); + + /** Encrypt using CFB (Full length) */ + int (*cfb_func)( void *ctx, operation_t mode, size_t length, size_t *iv_off, + unsigned char *iv, const unsigned char *input, + unsigned char *output ); + + /** Encrypt using CTR */ + int (*ctr_func)( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ); + + /** Encrypt using STREAM */ + int (*stream_func)( void *ctx, size_t length, + const unsigned char *input, unsigned char *output ); + + /** Set key for encryption purposes */ + int (*setkey_enc_func)( void *ctx, const unsigned char *key, + unsigned int key_length ); + + /** Set key for decryption purposes */ + int (*setkey_dec_func)( void *ctx, const unsigned char *key, + unsigned int key_length); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + +} cipher_base_t; + +/** + * Cipher information. Allows cipher functions to be called in a generic way. + */ +typedef struct { + /** Full cipher identifier (e.g. POLARSSL_CIPHER_AES_256_CBC) */ + cipher_type_t type; + + /** Cipher mode (e.g. POLARSSL_MODE_CBC) */ + cipher_mode_t mode; + + /** Cipher key length, in bits (default length for variable sized ciphers) + * (Includes parity bits for ciphers like DES) */ + unsigned int key_length; + + /** Name of the cipher */ + const char * name; + + /** IV/NONCE size, in bytes. + * For cipher that accept many sizes: recommended size */ + unsigned int iv_size; + + /** Flags for variable IV size, variable key size, etc. */ + int flags; + + /** block size, in bytes */ + unsigned int block_size; + + /** Base cipher information and functions */ + const cipher_base_t *base; + +} cipher_info_t; + +/** + * Generic cipher context. + */ +typedef struct { + /** Information about the associated cipher */ + const cipher_info_t *cipher_info; + + /** Key length to use */ + int key_length; + + /** Operation that the context's key has been initialised for */ + operation_t operation; + + /** Padding functions to use, if relevant for cipher mode */ + void (*add_padding)( unsigned char *output, size_t olen, size_t data_len ); + int (*get_padding)( unsigned char *input, size_t ilen, size_t *data_len ); + + /** Buffer for data that hasn't been encrypted yet */ + unsigned char unprocessed_data[POLARSSL_MAX_BLOCK_LENGTH]; + + /** Number of bytes that still need processing */ + size_t unprocessed_len; + + /** Current IV or NONCE_COUNTER for CTR-mode */ + unsigned char iv[POLARSSL_MAX_IV_LENGTH]; + + /** IV size in bytes (for ciphers with variable-length IVs) */ + size_t iv_size; + + /** Cipher-specific context */ + void *cipher_ctx; +} cipher_context_t; + +/** + * \brief Returns the list of ciphers supported by the generic cipher module. + * + * \return a statically allocated array of ciphers, the last entry + * is 0. + */ +const int *cipher_list( void ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher name. + * + * \param cipher_name Name of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_name, or NULL if not found. + */ +const cipher_info_t *cipher_info_from_string( const char *cipher_name ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher type. + * + * \param cipher_type Type of the cipher to search for. + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type ); + +/** + * \brief Returns the cipher information structure associated + * with the given cipher id, key size and mode. + * + * \param cipher_id Id of the cipher to search for + * (e.g. POLARSSL_CIPHER_ID_AES) + * \param key_length Length of the key in bits + * \param mode Cipher mode (e.g. POLARSSL_MODE_CBC) + * + * \return the cipher information structure associated with the + * given cipher_type, or NULL if not found. + */ +const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, + int key_length, + const cipher_mode_t mode ); + +/** + * \brief Initialize a cipher_context (as NONE) + */ +void cipher_init( cipher_context_t *ctx ); + +/** + * \brief Free and clear the cipher-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void cipher_free( cipher_context_t *ctx ); + +/** + * \brief Initialises and fills the cipher context structure with + * the appropriate values. + * + * \note Currently also clears structure. In future versions you + * will be required to call cipher_init() on the structure + * first. + * + * \param ctx context to initialise. May not be NULL. + * \param cipher_info cipher to use. + * + * \return 0 on success, + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA on parameter failure, + * POLARSSL_ERR_CIPHER_ALLOC_FAILED if allocation of the + * cipher-specific context failed. + */ +int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ); + +/** + * \brief Free the cipher-specific context of ctx. Freeing ctx + * itself remains the responsibility of the caller. + * + * \note Deprecated: Redirects to cipher_free() + * + * \param ctx Free the cipher-specific context + * + * \returns 0 + */ +int cipher_free_ctx( cipher_context_t *ctx ); + +/** + * \brief Returns the block size of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return size of the cipher's blocks, or 0 if ctx has not been + * initialised. + */ +static inline unsigned int cipher_get_block_size( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->block_size; +} + +/** + * \brief Returns the mode of operation for the cipher. + * (e.g. POLARSSL_MODE_CBC) + * + * \param ctx cipher's context. Must have been initialised. + * + * \return mode of operation, or POLARSSL_MODE_NONE if ctx + * has not been initialised. + */ +static inline cipher_mode_t cipher_get_cipher_mode( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return POLARSSL_MODE_NONE; + + return ctx->cipher_info->mode; +} + +/** + * \brief Returns the size of the cipher's IV/NONCE in bytes. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return If IV has not been set yet: (recommended) IV size + * (0 for ciphers not using IV/NONCE). + * If IV has already been set: actual size. + */ +static inline int cipher_get_iv_size( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + if( ctx->iv_size != 0 ) + return (int) ctx->iv_size; + + return ctx->cipher_info->iv_size; +} + +/** + * \brief Returns the type of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return type of the cipher, or POLARSSL_CIPHER_NONE if ctx has + * not been initialised. + */ +static inline cipher_type_t cipher_get_type( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return POLARSSL_CIPHER_NONE; + + return ctx->cipher_info->type; +} + +/** + * \brief Returns the name of the given cipher, as a string. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return name of the cipher, or NULL if ctx was not initialised. + */ +static inline const char *cipher_get_name( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return 0; + + return ctx->cipher_info->name; +} + +/** + * \brief Returns the key length of the cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return cipher's key length, in bits, or + * POLARSSL_KEY_LENGTH_NONE if ctx has not been + * initialised. + */ +static inline int cipher_get_key_size ( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return POLARSSL_KEY_LENGTH_NONE; + + return ctx->cipher_info->key_length; +} + +/** + * \brief Returns the operation of the given cipher. + * + * \param ctx cipher's context. Must have been initialised. + * + * \return operation (POLARSSL_ENCRYPT or POLARSSL_DECRYPT), + * or POLARSSL_OPERATION_NONE if ctx has not been + * initialised. + */ +static inline operation_t cipher_get_operation( const cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return POLARSSL_OPERATION_NONE; + + return ctx->operation; +} + +/** + * \brief Set the key to use with the given context. + * + * \param ctx generic cipher context. May not be NULL. Must have been + * initialised using cipher_context_from_type or + * cipher_context_from_string. + * \param key The key to use. + * \param key_length key length to use, in bits. + * \param operation Operation that the key will be used for, either + * POLARSSL_ENCRYPT or POLARSSL_DECRYPT. + * + * \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails or a cipher specific + * error code. + */ +int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, + int key_length, const operation_t operation ); + +#if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) +/** + * \brief Set padding mode, for cipher modes that use padding. + * (Default: PKCS7 padding.) + * + * \param ctx generic cipher context + * \param mode padding mode + * + * \returns 0 on success, POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE + * if selected padding mode is not supported, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if the cipher mode + * does not support padding. + */ +int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ); +#endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ + +/** + * \brief Set the initialization vector (IV) or nonce + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * + * \returns 0 on success, or POLARSSL_ERR_CIPHER_BAD_INPUT_DATA + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, this function has no effect. + */ +int cipher_set_iv( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ); + +/** + * \brief Finish preparation of the given context + * + * \param ctx generic cipher context + * + * \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA + * if parameter verification fails. + */ +int cipher_reset( cipher_context_t *ctx ); + +#if defined(POLARSSL_GCM_C) +/** + * \brief Add additional data (for AEAD ciphers). + * Currently only supported with GCM. + * Must be called exactly once, after cipher_reset(). + * + * \param ctx generic cipher context + * \param ad Additional data to use. + * \param ad_len Length of ad. + * + * \return 0 on success, or a specific error code. + */ +int cipher_update_ad( cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ); +#endif /* POLARSSL_GCM_C */ + +/** + * \brief Generic cipher update function. Encrypts/decrypts + * using the given cipher context. Writes as many block + * size'd blocks of data as possible to output. Any data + * that cannot be written immediately will either be added + * to the next block, or flushed when cipher_final is + * called. + * Exception: for POLARSSL_MODE_ECB, expects single block + * in size (e.g. 16 bytes for AES) + * + * \param ctx generic cipher context + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE on an + * unsupported mode for a cipher or a cipher specific + * error code. + * + * \note If the underlying cipher is GCM, all calls to this + * function, except the last one before cipher_finish(), + * must have ilen a multiple of the block size. + */ +int cipher_update( cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ); + +/** + * \brief Generic cipher finalisation function. If data still + * needs to be flushed from an incomplete block, data + * contained within it will be padded with the size of + * the last block, and written to the output buffer. + * + * \param ctx Generic cipher context + * \param output buffer to write data to. Needs block_size available. + * \param olen length of the data written to the output buffer. + * + * \returns 0 on success, POLARSSL_ERR_CIPHER_BAD_INPUT_DATA if + * parameter verification fails, + * POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, + * POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting or a cipher specific error code. + */ +int cipher_finish( cipher_context_t *ctx, + unsigned char *output, size_t *olen ); + +#if defined(POLARSSL_GCM_C) +/** + * \brief Write tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag buffer to write the tag + * \param tag_len Length of the tag to write + * + * \return 0 on success, or a specific error code. + */ +int cipher_write_tag( cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Check tag for AEAD ciphers. + * Currently only supported with GCM. + * Must be called after cipher_finish(). + * + * \param ctx Generic cipher context + * \param tag Buffer holding the tag + * \param tag_len Length of the tag to check + * + * \return 0 on success, or a specific error code. + */ +int cipher_check_tag( cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ); +#endif /* POLARSSL_GCM_C */ + +/** + * \brief Generic all-in-one encryption/decryption + * (for all ciphers except AEAD constructs). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. Should be able to hold at + * least ilen + block_size. Cannot be the same buffer as + * input! + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * + * \note Some ciphers don't use IVs nor NONCE. For these + * ciphers, use iv = NULL and iv_len = 0. + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED if decryption + * expected a full block but was not provided one, or + * POLARSSL_ERR_CIPHER_INVALID_PADDING on invalid padding + * while decrypting, or + * a cipher specific error code. + */ +int cipher_crypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ); + +#if defined(POLARSSL_CIPHER_MODE_AEAD) +/** + * \brief Generic autenticated encryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to authenticate. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer for the authentication tag + * \param tag_len desired tag length + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * a cipher specific error code. + */ +int cipher_auth_encrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ); + +/** + * \brief Generic autenticated decryption (AEAD ciphers). + * + * \param ctx generic cipher context + * \param iv IV to use (or NONCE_COUNTER for CTR-mode ciphers) + * \param iv_len IV length for ciphers with variable-size IV; + * discarded by ciphers with fixed-size IV. + * \param ad Additional data to be authenticated. + * \param ad_len Length of ad. + * \param input buffer holding the input data + * \param ilen length of the input data + * \param output buffer for the output data. + * Should be able to hold at least ilen. + * \param olen length of the output data, will be filled with the + * actual number of bytes written. + * \param tag buffer holding the authentication tag + * \param tag_len length of the authentication tag + * + * \returns 0 on success, or + * POLARSSL_ERR_CIPHER_BAD_INPUT_DATA, or + * POLARSSL_ERR_CIPHER_AUTH_FAILED if data isn't authentic, + * or a cipher specific error code. + * + * \note If the data is not authentic, then the output buffer + * is zeroed out to prevent the unauthentic plaintext to + * be used by mistake, making this interface safer. + */ +int cipher_auth_decrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ); +#endif /* POLARSSL_CIPHER_MODE_AEAD */ + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int cipher_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_CIPHER_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher_wrap.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher_wrap.h new file mode 100644 index 0000000..46bc757 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/cipher_wrap.h @@ -0,0 +1,57 @@ +/** + * \file cipher_wrap.h + * + * \brief Cipher wrappers. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CIPHER_WRAP_H +#define POLARSSL_CIPHER_WRAP_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#include "cipher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + cipher_type_t type; + const cipher_info_t *info; +} cipher_definition_t; + +extern const cipher_definition_t cipher_definitions[]; + +extern int supported_ciphers[]; + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_CIPHER_WRAP_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/compat-1.2.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/compat-1.2.h new file mode 100644 index 0000000..15b5aa1 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/compat-1.2.h @@ -0,0 +1,389 @@ +/** + * \file compat-1.2.h + * + * \brief Backwards compatibility header for PolarSSL-1.2 from PolarSSL-1.3 + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_COMPAT_1_2_H +#define POLARSSL_COMPAT_1_2_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +// Comment out to disable prototype change warnings +#define SHOW_PROTOTYPE_CHANGE_WARNINGS + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /* _MSC_VER */ + +#if defined(_MSC_VER) +// MSVC does not support #warning +#undef SHOW_PROTOTYPE_CHANGE_WARNINGS +#endif + +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "You can disable these warnings by commenting SHOW_PROTOTYPE_CHANGE_WARNINGS in compat-1.2.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#define POLARSSL_SHA2_C +#include "sha256.h" + +/* + * SHA-2 -> SHA-256 + */ +typedef sha256_context sha2_context; + +static inline void sha2_starts( sha256_context *ctx, int is224 ) { + sha256_starts( ctx, is224 ); +} +static inline void sha2_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) { + sha256_update( ctx, input, ilen ); +} +static inline void sha2_finish( sha256_context *ctx, unsigned char output[32] ) { + sha256_finish( ctx, output ); +} +static inline int sha2_file( const char *path, unsigned char output[32], int is224 ) { + return sha256_file( path, output, is224 ); +} +static inline void sha2( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) { + sha256( input, ilen, output, is224 ); +} +static inline void sha2_hmac_starts( sha256_context *ctx, const unsigned char *key, + size_t keylen, int is224 ) { + sha256_hmac_starts( ctx, key, keylen, is224 ); +} +static inline void sha2_hmac_update( sha256_context *ctx, const unsigned char *input, size_t ilen ) { + sha256_hmac_update( ctx, input, ilen ); +} +static inline void sha2_hmac_finish( sha256_context *ctx, unsigned char output[32] ) { + sha256_hmac_finish( ctx, output ); +} +static inline void sha2_hmac_reset( sha256_context *ctx ) { + sha256_hmac_reset( ctx ); +} +static inline void sha2_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) { + sha256_hmac( key, keylen, input, ilen, output, is224 ); +} +static inline int sha2_self_test( int verbose ) { + return sha256_self_test( verbose ); +} +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) +#define POLARSSL_SHA4_C +#include "sha512.h" + +/* + * SHA-4 -> SHA-512 + */ +typedef sha512_context sha4_context; + +static inline void sha4_starts( sha512_context *ctx, int is384 ) { + sha512_starts( ctx, is384 ); +} +static inline void sha4_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ) { + sha512_update( ctx, input, ilen ); +} +static inline void sha4_finish( sha512_context *ctx, unsigned char output[64] ) { + sha512_finish( ctx, output ); +} +static inline int sha4_file( const char *path, unsigned char output[64], int is384 ) { + return sha512_file( path, output, is384 ); +} +static inline void sha4( const unsigned char *input, size_t ilen, + unsigned char output[32], int is384 ) { + sha512( input, ilen, output, is384 ); +} +static inline void sha4_hmac_starts( sha512_context *ctx, const unsigned char *key, + size_t keylen, int is384 ) { + sha512_hmac_starts( ctx, key, keylen, is384 ); +} +static inline void sha4_hmac_update( sha512_context *ctx, const unsigned char *input, size_t ilen ) { + sha512_hmac_update( ctx, input, ilen ); +} +static inline void sha4_hmac_finish( sha512_context *ctx, unsigned char output[64] ) { + sha512_hmac_finish( ctx, output ); +} +static inline void sha4_hmac_reset( sha512_context *ctx ) { + sha512_hmac_reset( ctx ); +} +static inline void sha4_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) { + sha512_hmac( key, keylen, input, ilen, output, is384 ); +} +static inline int sha4_self_test( int verbose ) { + return sha512_self_test( verbose ); +} +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_CIPHER_C) +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "cipher_reset() prototype changed. Manual change required if used" +#endif +#endif + +#if defined(POLARSSL_RSA_C) +#define SIG_RSA_RAW POLARSSL_MD_NONE +#define SIG_RSA_MD2 POLARSSL_MD_MD2 +#define SIG_RSA_MD4 POLARSSL_MD_MD4 +#define SIG_RSA_MD5 POLARSSL_MD_MD5 +#define SIG_RSA_SHA1 POLARSSL_MD_SHA1 +#define SIG_RSA_SHA224 POLARSSL_MD_SHA224 +#define SIG_RSA_SHA256 POLARSSL_MD_SHA256 +#define SIG_RSA_SHA384 POLARSSL_MD_SHA384 +#define SIG_RSA_SHA512 POLARSSL_MD_SHA512 +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "rsa_pkcs1_verify() prototype changed. Manual change required if used" +#warning "rsa_pkcs1_decrypt() prototype changed. Manual change required if used" +#endif +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_DHM_C) +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "dhm_calc_secret() prototype changed. Manual change required if used" +#endif +#endif + +#if defined(POLARSSL_GCM_C) +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "gcm_init() prototype changed. Manual change required if used" +#endif +#endif + +#if defined(POLARSSL_SSL_CLI_C) +#if defined(SHOW_PROTOTYPE_CHANGE_WARNINGS) +#warning "ssl_set_own_cert() prototype changed. Change to ssl_set_own_cert_rsa(). Manual change required if used" +#endif +#endif + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +#include "x509.h" + +#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT POLARSSL_ERR_X509_INVALID_FORMAT +#define POLARSSL_ERR_X509_CERT_INVALID_VERSION POLARSSL_ERR_X509_INVALID_VERSION +#define POLARSSL_ERR_X509_CERT_INVALID_ALG POLARSSL_ERR_X509_INVALID_ALG +#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG POLARSSL_ERR_X509_UNKNOWN_SIG_ALG +#define POLARSSL_ERR_X509_CERT_INVALID_NAME POLARSSL_ERR_X509_INVALID_NAME +#define POLARSSL_ERR_X509_CERT_INVALID_DATE POLARSSL_ERR_X509_INVALID_DATE +#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS POLARSSL_ERR_X509_INVALID_EXTENSIONS +#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH POLARSSL_ERR_X509_SIG_MISMATCH +#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE POLARSSL_ERR_X509_INVALID_SIGNATURE +#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL POLARSSL_ERR_X509_INVALID_SERIAL +#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION POLARSSL_ERR_X509_UNKNOWN_VERSION + +static inline int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial ) { + return x509_serial_gets( buf, size, serial ); +} +static inline int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn ) { + return x509_dn_gets( buf, size, dn ); +} +static inline int x509parse_time_expired( const x509_time *time ) { + return x509_time_expired( time ); +} +#endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +#define POLARSSL_X509_PARSE_C +#include "x509_crt.h" +typedef x509_crt x509_cert; + +static inline int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, + size_t buflen ) { + return x509_crt_parse_der( chain, buf, buflen ); +} +static inline int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen ) { + return x509_crt_parse( chain, buf, buflen ); +} +static inline int x509parse_crtfile( x509_cert *chain, const char *path ) { + return x509_crt_parse_file( chain, path ); +} +static inline int x509parse_crtpath( x509_cert *chain, const char *path ) { + return x509_crt_parse_path( chain, path ); +} +static inline int x509parse_cert_info( char *buf, size_t size, const char *prefix, + const x509_cert *crt ) { + return x509_crt_info( buf, size, prefix, crt ); +} +static inline int x509parse_verify( x509_cert *crt, x509_cert *trust_ca, + x509_crl *ca_crl, const char *cn, int *flags, + int (*f_vrfy)(void *, x509_cert *, int, int *), + void *p_vrfy ) { + return x509_crt_verify( crt, trust_ca, ca_crl, cn, flags, f_vrfy, p_vrfy ); +} +static inline int x509parse_revoked( const x509_cert *crt, const x509_crl *crl ) { + return x509_crt_revoked( crt, crl ); +} +static inline void x509_free( x509_cert *crt ) { + x509_crt_free( crt ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#if defined(POLARSSL_X509_CRL_PARSE_C) +#define POLARSSL_X509_PARSE_C +#include "x509_crl.h" +static inline int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen ) { + return x509_crl_parse( chain, buf, buflen ); +} +static inline int x509parse_crlfile( x509_crl *chain, const char *path ) { + return x509_crl_parse_file( chain, path ); +} +static inline int x509parse_crl_info( char *buf, size_t size, const char *prefix, + const x509_crl *crl ) { + return x509_crl_info( buf, size, prefix, crl ); +} +#endif /* POLARSSL_X509_CRL_PARSE_C */ + +#if defined(POLARSSL_X509_CSR_PARSE_C) +#define POLARSSL_X509_PARSE_C +#include "x509_csr.h" +static inline int x509parse_csr( x509_csr *csr, const unsigned char *buf, size_t buflen ) { + return x509_csr_parse( csr, buf, buflen ); +} +static inline int x509parse_csrfile( x509_csr *csr, const char *path ) { + return x509_csr_parse_file( csr, path ); +} +static inline int x509parse_csr_info( char *buf, size_t size, const char *prefix, + const x509_csr *csr ) { + return x509_csr_info( buf, size, prefix, csr ); +} +#endif /* POLARSSL_X509_CSR_PARSE_C */ + +#if defined(POLARSSL_SSL_TLS_C) +#include "ssl_ciphersuites.h" + +#define ssl_default_ciphersuites ssl_list_ciphersuites() +#endif + +#if defined(POLARSSL_PK_PARSE_C) && defined(POLARSSL_RSA_C) +#include "rsa.h" +#include "pk.h" + +#define POLARSSL_ERR_X509_PASSWORD_MISMATCH POLARSSL_ERR_PK_PASSWORD_MISMATCH +#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT POLARSSL_ERR_PK_KEY_INVALID_FORMAT +#define POLARSSL_ERR_X509_UNKNOWN_PK_ALG POLARSSL_ERR_PK_UNKNOWN_PK_ALG +#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY POLARSSL_ERR_PK_INVALID_PUBKEY + +#if defined(POLARSSL_FS_IO) +static inline int x509parse_keyfile( rsa_context *rsa, const char *path, + const char *pwd ) { + int ret; + pk_context pk; + pk_init( &pk ); + ret = pk_parse_keyfile( &pk, path, pwd ); + if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) ) + ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + if( ret == 0 ) + rsa_copy( rsa, pk_rsa( pk ) ); + else + rsa_free( rsa ); + pk_free( &pk ); + return( ret ); +} +static inline int x509parse_public_keyfile( rsa_context *rsa, const char *path ) { + int ret; + pk_context pk; + pk_init( &pk ); + ret = pk_parse_public_keyfile( &pk, path ); + if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) ) + ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + if( ret == 0 ) + rsa_copy( rsa, pk_rsa( pk ) ); + else + rsa_free( rsa ); + pk_free( &pk ); + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +static inline int x509parse_key( rsa_context *rsa, const unsigned char *key, + size_t keylen, + const unsigned char *pwd, size_t pwdlen ) { + int ret; + pk_context pk; + pk_init( &pk ); + ret = pk_parse_key( &pk, key, keylen, pwd, pwdlen ); + if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) ) + ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + if( ret == 0 ) + rsa_copy( rsa, pk_rsa( pk ) ); + else + rsa_free( rsa ); + pk_free( &pk ); + return( ret ); +} + +static inline int x509parse_public_key( rsa_context *rsa, + const unsigned char *key, size_t keylen ) +{ + int ret; + pk_context pk; + pk_init( &pk ); + ret = pk_parse_public_key( &pk, key, keylen ); + if( ret == 0 && ! pk_can_do( &pk, POLARSSL_PK_RSA ) ) + ret = POLARSSL_ERR_PK_TYPE_MISMATCH; + if( ret == 0 ) + rsa_copy( rsa, pk_rsa( pk ) ); + else + rsa_free( rsa ); + pk_free( &pk ); + return( ret ); +} +#endif /* POLARSSL_PK_PARSE_C && POLARSSL_RSA_C */ + +#if defined(POLARSSL_PK_WRITE_C) && defined(POLARSSL_RSA_C) +#include "pk.h" +static inline int x509_write_pubkey_der( unsigned char *buf, size_t len, rsa_context *rsa ) { + int ret; + pk_context ctx; + if( ( ret = pk_init_ctx( &ctx, pk_info_from_type( POLARSSL_PK_RSA ) ) ) != 0 ) return( ret ); + if( ( ret = rsa_copy( pk_rsa( ctx ), rsa ) ) != 0 ) return( ret ); + ret = pk_write_pubkey_der( &ctx, buf, len ); + pk_free( &ctx ); + return( ret ); +} +static inline int x509_write_key_der( unsigned char *buf, size_t len, rsa_context *rsa ) { + int ret; + pk_context ctx; + if( ( ret = pk_init_ctx( &ctx, pk_info_from_type( POLARSSL_PK_RSA ) ) ) != 0 ) return( ret ); + if( ( ret = rsa_copy( pk_rsa( ctx ), rsa ) ) != 0 ) return( ret ); + ret = pk_write_key_der( &ctx, buf, len ); + pk_free( &ctx ); + return( ret ); +} +#endif /* POLARSSL_PK_WRITE_C && POLARSSL_RSA_C */ +#endif /* compat-1.2.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config.h new file mode 100644 index 0000000..b29e3b8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config.h @@ -0,0 +1,23 @@ +#define CONFIG_PROJECT_CUSTOM 0 +#define CONFIG_SSL_RSA 1 + +#if (defined CONFIG_PLATFORM_8195A) || (defined CONFIG_PLATFORM_8711B) +#include "section_config.h" +#include "rom_ssl_ram_map.h" +#define RTL_HW_CRYPTO +#define SUPPORT_HW_SW_CRYPTO +#endif + +#if defined (CONFIG_SSL_ROM) //define in ROM makefile +#include "polarssl/ssl_rom_lib.h" +#include "polarssl/config_rom.h" +#elif CONFIG_PROJECT_CUSTOM +#include "platform_stdlib.h" +#include "ssl_config.h" +#elif CONFIG_SSL_RSA +#include "platform_stdlib.h" +#include "polarssl/config_rsa.h" +#else +#include "platform_stdlib.h" +#include "polarssl/config_all.h" +#endif /* CONFIG_SSL_ROM */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_all.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_all.h new file mode 100644 index 0000000..5376221 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_all.h @@ -0,0 +1,2184 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. + */ +//#define POLARSSL_HAVE_INT8 + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. + */ +//#define POLARSSL_HAVE_INT16 + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the 'long long' type. + * (Only used on 32-bit platforms) + */ +#define POLARSSL_HAVE_LONGLONG + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +//#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define POLARSSL_HAVE_SSE2 + +/** + * \def POLARSSL_HAVE_TIME + * + * System has time.h and time() / localtime() / gettimeofday(). + * + * Comment if your system does not support time functions + */ +//#define POLARSSL_HAVE_TIME + +/** + * \def POLARSSL_HAVE_IPV6 + * + * System supports the basic socket interface for IPv6 (RFC 3493), + * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. + * + * Note: on Windows/MingW, XP or higher is required. + * + * Comment if your system does not support the IPv6 socket interface + */ +//#define POLARSSL_HAVE_IPV6 + +/** + * \def POLARSSL_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default PolarSSL uses the system-provided malloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" + * to allow you to set an alternative malloc() and free() function pointer. + * + * Requires: POLARSSL_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define POLARSSL_PLATFORM_MEMORY + +/** + * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. malloc() to + * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the POLARSSL_PLATFORM_STD_XXX defines. + * + * Requires: POLARSSL_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def POLARSSL_PLATFORM_XXX_ALT + * + * Uncomment a macro to let PolarSSL support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will + * provide a function "platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require POLARSSL_PLATFORM_C to be defined! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define POLARSSL_PLATFORM_PRINTF_ALT +//#define POLARSSL_PLATFORM_FPRINTF_ALT +/* \} name SECTION: System support */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for hardclock(), + * get_timer(), set_alarm() and m_sleep(). + * + * Only works if you have POLARSSL_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define POLARSSL_TIMING_ALT + +/** + * \def POLARSSL_XXX_ALT + * + * Uncomment a macro to let PolarSSL use your alternate core implementation of + * a symmetric or hash algorithm (e.g. platform specific assembly optimized + * implementations). Keep in mind that the function prototypes should remain + * the same. + * + * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer + * provide the "struct aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation for core algorithm + * functions + */ +//#define POLARSSL_AES_ALT +//#define POLARSSL_ARC4_ALT +//#define POLARSSL_BLOWFISH_ALT +//#define POLARSSL_CAMELLIA_ALT +//#define POLARSSL_DES_ALT +//#define POLARSSL_XTEA_ALT +//#define POLARSSL_MD2_ALT +//#define POLARSSL_MD4_ALT +//#define POLARSSL_MD5_ALT +//#define POLARSSL_RIPEMD160_ALT +//#define POLARSSL_SHA1_ALT +//#define POLARSSL_SHA256_ALT +//#define POLARSSL_SHA512_ALT + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * + */ +#define POLARSSL_AES_ROM_TABLES + +/** + * \def POLARSSL_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CBC + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * TLS_ECDH_ECDSA_WITH_NULL_SHA + * TLS_ECDH_RSA_WITH_NULL_SHA + * TLS_ECDHE_ECDSA_WITH_NULL_SHA + * TLS_ECDHE_RSA_WITH_NULL_SHA + * TLS_ECDHE_PSK_WITH_NULL_SHA384 + * TLS_ECDHE_PSK_WITH_NULL_SHA256 + * TLS_ECDHE_PSK_WITH_NULL_SHA + * TLS_DHE_PSK_WITH_NULL_SHA384 + * TLS_DHE_PSK_WITH_NULL_SHA256 + * TLS_DHE_PSK_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_SHA256 + * TLS_RSA_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_MD5 + * TLS_RSA_PSK_WITH_NULL_SHA384 + * TLS_RSA_PSK_WITH_NULL_SHA256 + * TLS_RSA_PSK_WITH_NULL_SHA + * TLS_PSK_WITH_NULL_SHA384 + * TLS_PSK_WITH_NULL_SHA256 + * TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define POLARSSL_CIPHER_NULL_CIPHER + +/** + * \def POLARSSL_CIPHER_PADDING_XXX + * + * Uncomment or comment macros to add support for specific padding modes + * in the cipher layer with cipher modes that support padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define POLARSSL_CIPHER_PADDING_PKCS7 +#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS +#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN +#define POLARSSL_CIPHER_PADDING_ZEROS + +/** + * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * TLS_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + +/** + * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with ssl_set_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES + +/** + * \def POLARSSL_ECP_XXXX_ENABLED + * + * Enables specific curves within the Elliptic Curve module. + * By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define POLARSSL_ECP_DP_SECP192R1_ENABLED +#define POLARSSL_ECP_DP_SECP224R1_ENABLED +#define POLARSSL_ECP_DP_SECP256R1_ENABLED +#define POLARSSL_ECP_DP_SECP384R1_ENABLED +#define POLARSSL_ECP_DP_SECP521R1_ENABLED +#define POLARSSL_ECP_DP_SECP192K1_ENABLED +#define POLARSSL_ECP_DP_SECP224K1_ENABLED +#define POLARSSL_ECP_DP_SECP256K1_ENABLED +#define POLARSSL_ECP_DP_BP256R1_ENABLED +#define POLARSSL_ECP_DP_BP384R1_ENABLED +#define POLARSSL_ECP_DP_BP512R1_ENABLED +//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! +#define POLARSSL_ECP_DP_M255_ENABLED +//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! +//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! + +/** + * \def POLARSSL_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define POLARSSL_ECP_NIST_OPTIM + +/** + * \def POLARSSL_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: POLARSSL_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define POLARSSL_ECDSA_DETERMINISTIC + +/** + * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + */ +#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def POLARSSL_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define POLARSSL_PK_PARSE_EC_EXTENDED + +/** + * \def POLARSSL_ERROR_STRERROR_BC + * + * Make available the backward compatible error_strerror() next to the + * current polarssl_strerror(). + * + * For new code, it is recommended to use polarssl_strerror() instead and + * disable this. + * + * Disable if you run into name conflicts and want to really remove the + * error_strerror() + */ +#define POLARSSL_ERROR_STRERROR_BC + +/** + * \def POLARSSL_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of polarssl_strerror() in + * third party libraries easier when POLARSSL_ERROR_C is disabled + * (no effect when POLARSSL_ERROR_C is enabled). + * + * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're + * not using polarssl_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * polarssl_strerror() + */ +#define POLARSSL_ERROR_STRERROR_DUMMY + +/** + * \def POLARSSL_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: POLARSSL_BIGNUM_C + */ +#define POLARSSL_GENPRIME + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define POLARSSL_FS_IO + +/** + * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define POLARSSL_NO_PLATFORM_ENTROPY + +/** + * \def POLARSSL_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: POLARSSL_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both POLARSSL_SHA256_C and + * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define POLARSSL_ENTROPY_FORCE_SHA256 + +/** + * \def POLARSSL_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define POLARSSL_MEMORY_DEBUG + +/** + * \def POLARSSL_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define POLARSSL_MEMORY_BACKTRACE + +/** + * \def POLARSSL_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: POLARSSL_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define POLARSSL_PKCS1_V15 + +/** + * \def POLARSSL_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define POLARSSL_PKCS1_V21 + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define POLARSSL_RSA_NO_CRT + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define POLARSSL_SELF_TEST + +/** + * \def POLARSSL_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, PolarSSL can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define POLARSSL_SSL_ALERT_MESSAGES + +/** + * \def POLARSSL_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define POLARSSL_SSL_DEBUG_ALL + +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define POLARSSL_SSL_HW_RECORD_ACCEL + +/** + * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (POLARSSL_SSL_SRV_C). + * + * Comment this macro to disable support for SSLv2 Client Hello messages. + */ +#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (POLARSSL_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def POLARSSL_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define POLARSSL_SSL_PROTO_SSL3 + +/** + * \def POLARSSL_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define POLARSSL_SSL_PROTO_TLS1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 + */ +#define POLARSSL_SSL_PROTO_TLS1_1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2. + * + * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 + */ +#define POLARSSL_SSL_PROTO_TLS1_2 + +/** + * \def POLARSSL_SSL_ALPN + * + * Enable support for Application Layer Protocol Negotiation. + * draft-ietf-tls-applayerprotoneg-05 + * + * Comment this macro to disable support for ALPN. + */ +#define POLARSSL_SSL_ALPN + +/** + * \def POLARSSL_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * + * Requires: POLARSSL_AES_C + * POLARSSL_SHA256_C + * POLARSSL_CIPHER_MODE_CBC + * + * Comment this macro to disable support for SSL session tickets + */ +#define POLARSSL_SSL_SESSION_TICKETS + +/** + * \def POLARSSL_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Comment this macro to disable support for server name indication in SSL + */ +#define POLARSSL_SSL_SERVER_NAME_INDICATION + +/** + * \def POLARSSL_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +#define POLARSSL_SSL_TRUNCATED_HMAC + +/** + * \def POLARSSL_SSL_SET_CURVES + * + * Enable ssl_set_curves(). + * + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * It will be enabled by default, or no longer an option, in the 1.4 branch. + * + * Uncomment to make ssl_set_curves() available. + */ +//#define POLARSSL_SSL_SET_CURVES + +/** + * \def POLARSSL_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define POLARSSL_THREADING_ALT + +/** + * \def POLARSSL_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define POLARSSL_THREADING_PTHREAD + +/** + * \def POLARSSL_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via version_check_feature(). + * + * Requires: POLARSSL_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define POLARSSL_VERSION_FEATURES + +/** + * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def POLARSSL_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +#define POLARSSL_X509_CHECK_KEY_USAGE + +/** + * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def POLARSSL_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +#define POLARSSL_X509_RSASSA_PSS_SUPPORT + +/** + * \def POLARSSL_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define POLARSSL_ZLIB_SUPPORT +/* \} name SECTION: PolarSSL feature support */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define POLARSSL_AESNI_C + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define POLARSSL_AES_C + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + * TLS_RSA_PSK_WITH_RC4_128_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_ARC4_C + +/** + * \def POLARSSL_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define POLARSSL_ASN1_PARSE_C + +/** + * \def POLARSSL_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +#define POLARSSL_ASN1_WRITE_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +#define POLARSSL_BLOWFISH_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define POLARSSL_CCM_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * Requires: POLARSSL_PEM_PARSE_C + * + * This module is used for testing (ssl_client/server). + */ +#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: POLARSSL_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +#define POLARSSL_CTR_DRBG_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +//#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: POLARSSL_ECP_C + */ +#define POLARSSL_ECDH_C + +/** + * \def POLARSSL_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C + */ +#define POLARSSL_ECDSA_C + +/** + * \def POLARSSL_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * + * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED + */ +#define POLARSSL_ECP_C + +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define POLARSSL_ENTROPY_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables polarssl_strerror(). + */ +#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define POLARSSL_GCM_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: POLARSSL_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define POLARSSL_HMAC_DRBG_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define POLARSSL_MD2_C + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define POLARSSL_MD4_C + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_MEMORY_C + * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. + */ + #ifndef POLARSSL_PLATFORM_MEMORY +#define POLARSSL_MEMORY_C +#endif + +/** + * \def POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces malloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: POLARSSL_PLATFORM_C + * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define POLARSSL_MEMORY_BUFFER_ALLOC_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define POLARSSL_OID_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define POLARSSL_PADLOCK_C + +/** + * \def POLARSSL_PBKDF2_C + * + * Enable PKCS#5 PBKDF2 key derivation function. + * DEPRECATED: Use POLARSSL_PKCS5_C instead + * + * Module: library/pbkdf2.c + * + * Requires: POLARSSL_PKCS5_C + * + * This module adds support for the PKCS#5 PBKDF2 key derivation function. + */ +#define POLARSSL_PBKDF2_C + +/** + * \def POLARSSL_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define POLARSSL_PEM_PARSE_C + +/** + * \def POLARSSL_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define POLARSSL_PEM_WRITE_C + +/** + * \def POLARSSL_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define POLARSSL_PK_C + +/** + * \def POLARSSL_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define POLARSSL_PK_PARSE_C + +/** + * \def POLARSSL_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define POLARSSL_PK_WRITE_C + +/** + * \def POLARSSL_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: POLARSSL_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define POLARSSL_PKCS5_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: POLARSSL_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define POLARSSL_PKCS11_C + +/** + * \def POLARSSL_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C + * Can use: POLARSSL_ARC4_C + * + * This module enables PKCS#12 functions. + */ +#define POLARSSL_PKCS12_C + +/** + * \def POLARSSL_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like malloc(), free(), printf(), fprintf() + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define POLARSSL_PLATFORM_C + +/** + * \def POLARSSL_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +#define POLARSSL_RIPEMD160_C + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +/** + * \def POLARSSL_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA2_C) + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define POLARSSL_SHA256_C + +/** + * \def POLARSSL_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA4_C) + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA512_C + +/** + * \def POLARSSL_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: POLARSSL_SSL_CACHE_C + */ +#define POLARSSL_SSL_CACHE_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/** + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C + * and at least one of the POLARSSL_SSL_PROTO_* defines + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_THREADING_C + * + * Enable the threading abstraction layer. + * By default PolarSSL assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either POLARSSL_THREADING_ALT or + * POLARSSL_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within PolarSSL + */ +//#define POLARSSL_THREADING_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C, + * POLARSSL_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define POLARSSL_X509_USE_C + +/** + * \def POLARSSL_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_CRT_PARSE_C + +/** + * \def POLARSSL_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +#define POLARSSL_X509_CRL_PARSE_C + +/** + * \def POLARSSL_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +#define POLARSSL_X509_CSR_PARSE_C + +/** + * \def POLARSSL_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +#define POLARSSL_X509_CREATE_C + +/** + * \def POLARSSL_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +#define POLARSSL_X509_CRT_WRITE_C + +/** + * \def POLARSSL_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +#define POLARSSL_X509_CSR_WRITE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define POLARSSL_XTEA_C + +/* \} name SECTION: PolarSSL modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ + +/* Memory buffer allocator options */ +//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ + +/* SSL Cache options */ +//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ + +#define RTL_CRYPTO_FRAGMENT 15360 /* 15*1024 < 16000 */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* Debug options */ +//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ + +/* \} name SECTION: Module configuration options */ + +#include "check_config.h" + +#endif /* POLARSSL_CONFIG_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_arduino.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_arduino.h new file mode 100644 index 0000000..96c7229 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_arduino.h @@ -0,0 +1,2189 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. + */ +//#define POLARSSL_HAVE_INT8 + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. + */ +//#define POLARSSL_HAVE_INT16 + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the 'long long' type. + * (Only used on 32-bit platforms) + */ +#define POLARSSL_HAVE_LONGLONG + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +//#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define POLARSSL_HAVE_SSE2 + +/** + * \def POLARSSL_HAVE_TIME + * + * System has time.h and time() / localtime() / gettimeofday(). + * + * Comment if your system does not support time functions + */ +//#define POLARSSL_HAVE_TIME + +/** + * \def POLARSSL_HAVE_IPV6 + * + * System supports the basic socket interface for IPv6 (RFC 3493), + * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. + * + * Note: on Windows/MingW, XP or higher is required. + * + * Comment if your system does not support the IPv6 socket interface + */ +//#define POLARSSL_HAVE_IPV6 + +/** + * \def POLARSSL_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default PolarSSL uses the system-provided malloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" + * to allow you to set an alternative malloc() and free() function pointer. + * + * Requires: POLARSSL_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define POLARSSL_PLATFORM_MEMORY + +/** + * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. malloc() to + * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the POLARSSL_PLATFORM_STD_XXX defines. + * + * Requires: POLARSSL_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def POLARSSL_PLATFORM_XXX_ALT + * + * Uncomment a macro to let PolarSSL support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will + * provide a function "platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require POLARSSL_PLATFORM_C to be defined! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define POLARSSL_PLATFORM_PRINTF_ALT +//#define POLARSSL_PLATFORM_FPRINTF_ALT +/* \} name SECTION: System support */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for hardclock(), + * get_timer(), set_alarm() and m_sleep(). + * + * Only works if you have POLARSSL_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define POLARSSL_TIMING_ALT + +/** + * \def POLARSSL_XXX_ALT + * + * Uncomment a macro to let PolarSSL use your alternate core implementation of + * a symmetric or hash algorithm (e.g. platform specific assembly optimized + * implementations). Keep in mind that the function prototypes should remain + * the same. + * + * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer + * provide the "struct aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation for core algorithm + * functions + */ +//#define POLARSSL_AES_ALT +//#define POLARSSL_ARC4_ALT +//#define POLARSSL_BLOWFISH_ALT +//#define POLARSSL_CAMELLIA_ALT +//#define POLARSSL_DES_ALT +//#define POLARSSL_XTEA_ALT +//#define POLARSSL_MD2_ALT +//#define POLARSSL_MD4_ALT +//#define POLARSSL_MD5_ALT +//#define POLARSSL_RIPEMD160_ALT +//#define POLARSSL_SHA1_ALT +//#define POLARSSL_SHA256_ALT +//#define POLARSSL_SHA512_ALT + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * + */ +#define POLARSSL_AES_ROM_TABLES + +/** + * \def POLARSSL_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CBC + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * TLS_ECDH_ECDSA_WITH_NULL_SHA + * TLS_ECDH_RSA_WITH_NULL_SHA + * TLS_ECDHE_ECDSA_WITH_NULL_SHA + * TLS_ECDHE_RSA_WITH_NULL_SHA + * TLS_ECDHE_PSK_WITH_NULL_SHA384 + * TLS_ECDHE_PSK_WITH_NULL_SHA256 + * TLS_ECDHE_PSK_WITH_NULL_SHA + * TLS_DHE_PSK_WITH_NULL_SHA384 + * TLS_DHE_PSK_WITH_NULL_SHA256 + * TLS_DHE_PSK_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_SHA256 + * TLS_RSA_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_MD5 + * TLS_RSA_PSK_WITH_NULL_SHA384 + * TLS_RSA_PSK_WITH_NULL_SHA256 + * TLS_RSA_PSK_WITH_NULL_SHA + * TLS_PSK_WITH_NULL_SHA384 + * TLS_PSK_WITH_NULL_SHA256 + * TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define POLARSSL_CIPHER_NULL_CIPHER + +/** + * \def POLARSSL_CIPHER_PADDING_XXX + * + * Uncomment or comment macros to add support for specific padding modes + * in the cipher layer with cipher modes that support padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define POLARSSL_CIPHER_PADDING_PKCS7 +#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS +#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN +#define POLARSSL_CIPHER_PADDING_ZEROS + +/** + * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * TLS_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + +/** + * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with ssl_set_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES + +/** + * \def POLARSSL_ECP_XXXX_ENABLED + * + * Enables specific curves within the Elliptic Curve module. + * By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define POLARSSL_ECP_DP_SECP192R1_ENABLED +#define POLARSSL_ECP_DP_SECP224R1_ENABLED +#define POLARSSL_ECP_DP_SECP256R1_ENABLED +#define POLARSSL_ECP_DP_SECP384R1_ENABLED +#define POLARSSL_ECP_DP_SECP521R1_ENABLED +#define POLARSSL_ECP_DP_SECP192K1_ENABLED +#define POLARSSL_ECP_DP_SECP224K1_ENABLED +#define POLARSSL_ECP_DP_SECP256K1_ENABLED +#define POLARSSL_ECP_DP_BP256R1_ENABLED +#define POLARSSL_ECP_DP_BP384R1_ENABLED +#define POLARSSL_ECP_DP_BP512R1_ENABLED +//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! +#define POLARSSL_ECP_DP_M255_ENABLED +//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! +//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! + +/** + * \def POLARSSL_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define POLARSSL_ECP_NIST_OPTIM + +/** + * \def POLARSSL_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: POLARSSL_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define POLARSSL_ECDSA_DETERMINISTIC + +/** + * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + */ +#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def POLARSSL_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define POLARSSL_PK_PARSE_EC_EXTENDED + +/** + * \def POLARSSL_ERROR_STRERROR_BC + * + * Make available the backward compatible error_strerror() next to the + * current polarssl_strerror(). + * + * For new code, it is recommended to use polarssl_strerror() instead and + * disable this. + * + * Disable if you run into name conflicts and want to really remove the + * error_strerror() + */ +#define POLARSSL_ERROR_STRERROR_BC + +/** + * \def POLARSSL_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of polarssl_strerror() in + * third party libraries easier when POLARSSL_ERROR_C is disabled + * (no effect when POLARSSL_ERROR_C is enabled). + * + * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're + * not using polarssl_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * polarssl_strerror() + */ +#define POLARSSL_ERROR_STRERROR_DUMMY + +/** + * \def POLARSSL_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: POLARSSL_BIGNUM_C + */ +#define POLARSSL_GENPRIME + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define POLARSSL_FS_IO + +/** + * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define POLARSSL_NO_PLATFORM_ENTROPY + +/** + * \def POLARSSL_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: POLARSSL_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both POLARSSL_SHA256_C and + * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define POLARSSL_ENTROPY_FORCE_SHA256 + +/** + * \def POLARSSL_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define POLARSSL_MEMORY_DEBUG + +/** + * \def POLARSSL_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define POLARSSL_MEMORY_BACKTRACE + +/** + * \def POLARSSL_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: POLARSSL_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define POLARSSL_PKCS1_V15 + +/** + * \def POLARSSL_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define POLARSSL_PKCS1_V21 + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define POLARSSL_RSA_NO_CRT + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define POLARSSL_SELF_TEST + +/** + * \def POLARSSL_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, PolarSSL can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define POLARSSL_SSL_ALERT_MESSAGES + +/** + * \def POLARSSL_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define POLARSSL_SSL_DEBUG_ALL + +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define POLARSSL_SSL_HW_RECORD_ACCEL + +/** + * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (POLARSSL_SSL_SRV_C). + * + * Comment this macro to disable support for SSLv2 Client Hello messages. + */ +//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (POLARSSL_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def POLARSSL_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define POLARSSL_SSL_PROTO_SSL3 + +/** + * \def POLARSSL_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define POLARSSL_SSL_PROTO_TLS1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 + */ +#define POLARSSL_SSL_PROTO_TLS1_1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2. + * + * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 + */ +#define POLARSSL_SSL_PROTO_TLS1_2 + +/** + * \def POLARSSL_SSL_ALPN + * + * Enable support for Application Layer Protocol Negotiation. + * draft-ietf-tls-applayerprotoneg-05 + * + * Comment this macro to disable support for ALPN. + */ +//#define POLARSSL_SSL_ALPN + +/** + * \def POLARSSL_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * + * Requires: POLARSSL_AES_C + * POLARSSL_SHA256_C + * POLARSSL_CIPHER_MODE_CBC + * + * Comment this macro to disable support for SSL session tickets + */ +#define POLARSSL_SSL_SESSION_TICKETS + +/** + * \def POLARSSL_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Comment this macro to disable support for server name indication in SSL + */ +#define POLARSSL_SSL_SERVER_NAME_INDICATION + +/** + * \def POLARSSL_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +#define POLARSSL_SSL_TRUNCATED_HMAC + +/** + * \def POLARSSL_SSL_SET_CURVES + * + * Enable ssl_set_curves(). + * + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * It will be enabled by default, or no longer an option, in the 1.4 branch. + * + * Uncomment to make ssl_set_curves() available. + */ +//#define POLARSSL_SSL_SET_CURVES + +/** + * \def POLARSSL_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define POLARSSL_THREADING_ALT + +/** + * \def POLARSSL_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define POLARSSL_THREADING_PTHREAD + +/** + * \def POLARSSL_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via version_check_feature(). + * + * Requires: POLARSSL_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define POLARSSL_VERSION_FEATURES + +/** + * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def POLARSSL_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +//#define POLARSSL_X509_CHECK_KEY_USAGE + +/** + * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +//#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def POLARSSL_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +//#define POLARSSL_X509_RSASSA_PSS_SUPPORT + +/** + * \def POLARSSL_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define POLARSSL_ZLIB_SUPPORT +/* \} name SECTION: PolarSSL feature support */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define POLARSSL_AESNI_C + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define POLARSSL_AES_C + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + * TLS_RSA_PSK_WITH_RC4_128_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_ARC4_C + +/** + * \def POLARSSL_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define POLARSSL_ASN1_PARSE_C + +/** + * \def POLARSSL_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +//#define POLARSSL_ASN1_WRITE_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define POLARSSL_BLOWFISH_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +//#define POLARSSL_CCM_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * Requires: POLARSSL_PEM_PARSE_C + * + * This module is used for testing (ssl_client/server). + */ +//#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: POLARSSL_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +//#define POLARSSL_CTR_DRBG_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +//#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +//#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +//#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: POLARSSL_ECP_C + */ +//#define POLARSSL_ECDH_C + +/** + * \def POLARSSL_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C + */ +//#define POLARSSL_ECDSA_C + +/** + * \def POLARSSL_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * + * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED + */ +//#define POLARSSL_ECP_C + +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define POLARSSL_ENTROPY_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables polarssl_strerror(). + */ +#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +//#define POLARSSL_GCM_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: POLARSSL_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +//#define POLARSSL_HMAC_DRBG_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define POLARSSL_MD2_C + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define POLARSSL_MD4_C + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_MEMORY_C + * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. + */ +//#define POLARSSL_MEMORY_C + +/** + * \def POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces malloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: POLARSSL_PLATFORM_C + * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define POLARSSL_MEMORY_BUFFER_ALLOC_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define POLARSSL_OID_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define POLARSSL_PADLOCK_C + +/** + * \def POLARSSL_PBKDF2_C + * + * Enable PKCS#5 PBKDF2 key derivation function. + * DEPRECATED: Use POLARSSL_PKCS5_C instead + * + * Module: library/pbkdf2.c + * + * Requires: POLARSSL_PKCS5_C + * + * This module adds support for the PKCS#5 PBKDF2 key derivation function. + */ +//#define POLARSSL_PBKDF2_C + +/** + * \def POLARSSL_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define POLARSSL_PEM_PARSE_C + +/** + * \def POLARSSL_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +//#define POLARSSL_PEM_WRITE_C + +/** + * \def POLARSSL_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define POLARSSL_PK_C + +/** + * \def POLARSSL_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define POLARSSL_PK_PARSE_C + +/** + * \def POLARSSL_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key write functions. + */ +//#define POLARSSL_PK_WRITE_C + +/** + * \def POLARSSL_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: POLARSSL_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +//#define POLARSSL_PKCS5_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: POLARSSL_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define POLARSSL_PKCS11_C + +/** + * \def POLARSSL_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C + * Can use: POLARSSL_ARC4_C + * + * This module enables PKCS#12 functions. + */ +//#define POLARSSL_PKCS12_C + +/** + * \def POLARSSL_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like malloc(), free(), printf(), fprintf() + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define POLARSSL_PLATFORM_C + +/** + * \def POLARSSL_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define POLARSSL_RIPEMD160_C + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +/** + * \def POLARSSL_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA2_C) + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define POLARSSL_SHA256_C + +/** + * \def POLARSSL_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA4_C) + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA512_C + +/** + * \def POLARSSL_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: POLARSSL_SSL_CACHE_C + */ +#define POLARSSL_SSL_CACHE_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/** + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C + * and at least one of the POLARSSL_SSL_PROTO_* defines + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_THREADING_C + * + * Enable the threading abstraction layer. + * By default PolarSSL assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either POLARSSL_THREADING_ALT or + * POLARSSL_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within PolarSSL + */ +//#define POLARSSL_THREADING_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C, + * POLARSSL_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define POLARSSL_X509_USE_C + +/** + * \def POLARSSL_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_CRT_PARSE_C + +/** + * \def POLARSSL_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +//#define POLARSSL_X509_CRL_PARSE_C + +/** + * \def POLARSSL_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +//#define POLARSSL_X509_CSR_PARSE_C + +/** + * \def POLARSSL_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +//#define POLARSSL_X509_CREATE_C + +/** + * \def POLARSSL_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +//#define POLARSSL_X509_CRT_WRITE_C + +/** + * \def POLARSSL_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +//#define POLARSSL_X509_CSR_WRITE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define POLARSSL_XTEA_C + +/* \} name SECTION: PolarSSL modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ + +/* Memory buffer allocator options */ +//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ + +/* SSL Cache options */ +//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +/* if ssl_handshake returned -0x7200 -> +SSL_MAX_CONTENT_LEN to sufficient size (maximum value is 16384). */ +extern unsigned int mfl_code_to_length[]; +#define SSL_MAX_CONTENT_LEN mfl_code_to_length[0] // default = 4096 /**< Size of the input / output buffer */ +//#define SSL_MAX_CONTENT_LEN 4096 // mfl_code_to_length[5] // = 4096*3 // 4096 /**< Size of the input / output buffer */ +//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ + +/* Realteck Ameba HW Crypto */ +#define RTL_HW_CRYPTO +#define SUPPORT_HW_SW_CRYPTO +#define RTL_CRYPTO_FRAGMENT 15360 /* 15*1024 < 16000 */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* Debug options */ +//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ + +/* \} name SECTION: Module configuration options */ + +#include "check_config.h" + +#endif /* POLARSSL_CONFIG_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rom.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rom.h new file mode 100644 index 0000000..74968ba --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rom.h @@ -0,0 +1,2188 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. + */ +//#define POLARSSL_HAVE_INT8 + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. + */ +//#define POLARSSL_HAVE_INT16 + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the 'long long' type. + * (Only used on 32-bit platforms) + */ +#define POLARSSL_HAVE_LONGLONG + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +//#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define POLARSSL_HAVE_SSE2 + +/** + * \def POLARSSL_HAVE_TIME + * + * System has time.h and time() / localtime() / gettimeofday(). + * + * Comment if your system does not support time functions + */ +//#define POLARSSL_HAVE_TIME + +/** + * \def POLARSSL_HAVE_IPV6 + * + * System supports the basic socket interface for IPv6 (RFC 3493), + * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. + * + * Note: on Windows/MingW, XP or higher is required. + * + * Comment if your system does not support the IPv6 socket interface + */ +//#define POLARSSL_HAVE_IPV6 + +/** + * \def POLARSSL_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default PolarSSL uses the system-provided malloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" + * to allow you to set an alternative malloc() and free() function pointer. + * + * Requires: POLARSSL_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define POLARSSL_PLATFORM_MEMORY + +/** + * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. malloc() to + * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the POLARSSL_PLATFORM_STD_XXX defines. + * + * Requires: POLARSSL_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def POLARSSL_PLATFORM_XXX_ALT + * + * Uncomment a macro to let PolarSSL support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will + * provide a function "platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require POLARSSL_PLATFORM_C to be defined! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define POLARSSL_PLATFORM_PRINTF_ALT +//#define POLARSSL_PLATFORM_FPRINTF_ALT +/* \} name SECTION: System support */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for hardclock(), + * get_timer(), set_alarm() and m_sleep(). + * + * Only works if you have POLARSSL_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define POLARSSL_TIMING_ALT + +/** + * \def POLARSSL_XXX_ALT + * + * Uncomment a macro to let PolarSSL use your alternate core implementation of + * a symmetric or hash algorithm (e.g. platform specific assembly optimized + * implementations). Keep in mind that the function prototypes should remain + * the same. + * + * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer + * provide the "struct aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation for core algorithm + * functions + */ +//#define POLARSSL_AES_ALT +//#define POLARSSL_ARC4_ALT +//#define POLARSSL_BLOWFISH_ALT +//#define POLARSSL_CAMELLIA_ALT +//#define POLARSSL_DES_ALT +//#define POLARSSL_XTEA_ALT +//#define POLARSSL_MD2_ALT +//#define POLARSSL_MD4_ALT +//#define POLARSSL_MD5_ALT +//#define POLARSSL_RIPEMD160_ALT +//#define POLARSSL_SHA1_ALT +//#define POLARSSL_SHA256_ALT +//#define POLARSSL_SHA512_ALT + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * + */ +#define POLARSSL_AES_ROM_TABLES + +/** + * \def POLARSSL_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CBC + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * TLS_ECDH_ECDSA_WITH_NULL_SHA + * TLS_ECDH_RSA_WITH_NULL_SHA + * TLS_ECDHE_ECDSA_WITH_NULL_SHA + * TLS_ECDHE_RSA_WITH_NULL_SHA + * TLS_ECDHE_PSK_WITH_NULL_SHA384 + * TLS_ECDHE_PSK_WITH_NULL_SHA256 + * TLS_ECDHE_PSK_WITH_NULL_SHA + * TLS_DHE_PSK_WITH_NULL_SHA384 + * TLS_DHE_PSK_WITH_NULL_SHA256 + * TLS_DHE_PSK_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_SHA256 + * TLS_RSA_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_MD5 + * TLS_RSA_PSK_WITH_NULL_SHA384 + * TLS_RSA_PSK_WITH_NULL_SHA256 + * TLS_RSA_PSK_WITH_NULL_SHA + * TLS_PSK_WITH_NULL_SHA384 + * TLS_PSK_WITH_NULL_SHA256 + * TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define POLARSSL_CIPHER_NULL_CIPHER + +/** + * \def POLARSSL_CIPHER_PADDING_XXX + * + * Uncomment or comment macros to add support for specific padding modes + * in the cipher layer with cipher modes that support padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define POLARSSL_CIPHER_PADDING_PKCS7 +#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS +#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN +#define POLARSSL_CIPHER_PADDING_ZEROS + +/** + * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * TLS_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + +/** + * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with ssl_set_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES + +/** + * \def POLARSSL_ECP_XXXX_ENABLED + * + * Enables specific curves within the Elliptic Curve module. + * By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define POLARSSL_ECP_DP_SECP192R1_ENABLED +#define POLARSSL_ECP_DP_SECP224R1_ENABLED +#define POLARSSL_ECP_DP_SECP256R1_ENABLED +#define POLARSSL_ECP_DP_SECP384R1_ENABLED +#define POLARSSL_ECP_DP_SECP521R1_ENABLED +#define POLARSSL_ECP_DP_SECP192K1_ENABLED +#define POLARSSL_ECP_DP_SECP224K1_ENABLED +#define POLARSSL_ECP_DP_SECP256K1_ENABLED +#define POLARSSL_ECP_DP_BP256R1_ENABLED +#define POLARSSL_ECP_DP_BP384R1_ENABLED +#define POLARSSL_ECP_DP_BP512R1_ENABLED +//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! +#define POLARSSL_ECP_DP_M255_ENABLED +//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! +//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! + +/** + * \def POLARSSL_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define POLARSSL_ECP_NIST_OPTIM + +/** + * \def POLARSSL_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: POLARSSL_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define POLARSSL_ECDSA_DETERMINISTIC + +/** + * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + */ +#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def POLARSSL_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define POLARSSL_PK_PARSE_EC_EXTENDED + +/** + * \def POLARSSL_ERROR_STRERROR_BC + * + * Make available the backward compatible error_strerror() next to the + * current polarssl_strerror(). + * + * For new code, it is recommended to use polarssl_strerror() instead and + * disable this. + * + * Disable if you run into name conflicts and want to really remove the + * error_strerror() + */ +#define POLARSSL_ERROR_STRERROR_BC + +/** + * \def POLARSSL_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of polarssl_strerror() in + * third party libraries easier when POLARSSL_ERROR_C is disabled + * (no effect when POLARSSL_ERROR_C is enabled). + * + * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're + * not using polarssl_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * polarssl_strerror() + */ +#define POLARSSL_ERROR_STRERROR_DUMMY + +/** + * \def POLARSSL_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: POLARSSL_BIGNUM_C + */ +#define POLARSSL_GENPRIME + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define POLARSSL_FS_IO + +/** + * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define POLARSSL_NO_PLATFORM_ENTROPY + +/** + * \def POLARSSL_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: POLARSSL_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both POLARSSL_SHA256_C and + * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define POLARSSL_ENTROPY_FORCE_SHA256 + +/** + * \def POLARSSL_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define POLARSSL_MEMORY_DEBUG + +/** + * \def POLARSSL_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define POLARSSL_MEMORY_BACKTRACE + +/** + * \def POLARSSL_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: POLARSSL_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define POLARSSL_PKCS1_V15 + +/** + * \def POLARSSL_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define POLARSSL_PKCS1_V21 + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define POLARSSL_RSA_NO_CRT + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define POLARSSL_SELF_TEST + +/** + * \def POLARSSL_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, PolarSSL can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define POLARSSL_SSL_ALERT_MESSAGES + +/** + * \def POLARSSL_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define POLARSSL_SSL_DEBUG_ALL + +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define POLARSSL_SSL_HW_RECORD_ACCEL + +/** + * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (POLARSSL_SSL_SRV_C). + * + * Comment this macro to disable support for SSLv2 Client Hello messages. + */ +//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (POLARSSL_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def POLARSSL_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define POLARSSL_SSL_PROTO_SSL3 + +/** + * \def POLARSSL_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define POLARSSL_SSL_PROTO_TLS1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 + */ +#define POLARSSL_SSL_PROTO_TLS1_1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2. + * + * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 + */ +#define POLARSSL_SSL_PROTO_TLS1_2 + +/** + * \def POLARSSL_SSL_ALPN + * + * Enable support for Application Layer Protocol Negotiation. + * draft-ietf-tls-applayerprotoneg-05 + * + * Comment this macro to disable support for ALPN. + */ +#define POLARSSL_SSL_ALPN + +/** + * \def POLARSSL_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * + * Requires: POLARSSL_AES_C + * POLARSSL_SHA256_C + * POLARSSL_CIPHER_MODE_CBC + * + * Comment this macro to disable support for SSL session tickets + */ +#define POLARSSL_SSL_SESSION_TICKETS + +/** + * \def POLARSSL_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Comment this macro to disable support for server name indication in SSL + */ +#define POLARSSL_SSL_SERVER_NAME_INDICATION + +/** + * \def POLARSSL_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +#define POLARSSL_SSL_TRUNCATED_HMAC + +/** + * \def POLARSSL_SSL_SET_CURVES + * + * Enable ssl_set_curves(). + * + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * It will be enabled by default, or no longer an option, in the 1.4 branch. + * + * Uncomment to make ssl_set_curves() available. + */ +//#define POLARSSL_SSL_SET_CURVES + +/** + * \def POLARSSL_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define POLARSSL_THREADING_ALT + +/** + * \def POLARSSL_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define POLARSSL_THREADING_PTHREAD + +/** + * \def POLARSSL_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via version_check_feature(). + * + * Requires: POLARSSL_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define POLARSSL_VERSION_FEATURES + +/** + * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def POLARSSL_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +#define POLARSSL_X509_CHECK_KEY_USAGE + +/** + * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def POLARSSL_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +#define POLARSSL_X509_RSASSA_PSS_SUPPORT + +/** + * \def POLARSSL_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define POLARSSL_ZLIB_SUPPORT +/* \} name SECTION: PolarSSL feature support */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define POLARSSL_AESNI_C + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define POLARSSL_AES_C + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + * TLS_RSA_PSK_WITH_RC4_128_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_ARC4_C + +/** + * \def POLARSSL_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define POLARSSL_ASN1_PARSE_C + +/** + * \def POLARSSL_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +#define POLARSSL_ASN1_WRITE_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define POLARSSL_BLOWFISH_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define POLARSSL_CCM_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * Requires: POLARSSL_PEM_PARSE_C + * + * This module is used for testing (ssl_client/server). + */ +//#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: POLARSSL_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +#define POLARSSL_CTR_DRBG_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +//#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: POLARSSL_ECP_C + */ +#define POLARSSL_ECDH_C + +/** + * \def POLARSSL_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C + */ +#define POLARSSL_ECDSA_C + +/** + * \def POLARSSL_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * + * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED + */ +#define POLARSSL_ECP_C + +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define POLARSSL_ENTROPY_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables polarssl_strerror(). + */ +//#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define POLARSSL_GCM_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: POLARSSL_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define POLARSSL_HMAC_DRBG_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define POLARSSL_MD2_C + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define POLARSSL_MD4_C + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_MEMORY_C + * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. + */ +//#define POLARSSL_MEMORY_C + +/** + * \def POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces malloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: POLARSSL_PLATFORM_C + * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define POLARSSL_MEMORY_BUFFER_ALLOC_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define POLARSSL_OID_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define POLARSSL_PADLOCK_C + +/** + * \def POLARSSL_PBKDF2_C + * + * Enable PKCS#5 PBKDF2 key derivation function. + * DEPRECATED: Use POLARSSL_PKCS5_C instead + * + * Module: library/pbkdf2.c + * + * Requires: POLARSSL_PKCS5_C + * + * This module adds support for the PKCS#5 PBKDF2 key derivation function. + */ +#define POLARSSL_PBKDF2_C + +/** + * \def POLARSSL_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define POLARSSL_PEM_PARSE_C + +/** + * \def POLARSSL_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define POLARSSL_PEM_WRITE_C + +/** + * \def POLARSSL_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define POLARSSL_PK_C + +/** + * \def POLARSSL_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define POLARSSL_PK_PARSE_C + +/** + * \def POLARSSL_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define POLARSSL_PK_WRITE_C + +/** + * \def POLARSSL_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: POLARSSL_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define POLARSSL_PKCS5_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: POLARSSL_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define POLARSSL_PKCS11_C + +/** + * \def POLARSSL_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C + * Can use: POLARSSL_ARC4_C + * + * This module enables PKCS#12 functions. + */ +#define POLARSSL_PKCS12_C + +/** + * \def POLARSSL_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like malloc(), free(), printf(), fprintf() + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define POLARSSL_PLATFORM_C + +/** + * \def POLARSSL_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define POLARSSL_RIPEMD160_C + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +/** + * \def POLARSSL_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA2_C) + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define POLARSSL_SHA256_C + +/** + * \def POLARSSL_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA4_C) + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA512_C + +/** + * \def POLARSSL_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: POLARSSL_SSL_CACHE_C + */ +#define POLARSSL_SSL_CACHE_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/** + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C + * and at least one of the POLARSSL_SSL_PROTO_* defines + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_THREADING_C + * + * Enable the threading abstraction layer. + * By default PolarSSL assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either POLARSSL_THREADING_ALT or + * POLARSSL_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within PolarSSL + */ +//#define POLARSSL_THREADING_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C, + * POLARSSL_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define POLARSSL_X509_USE_C + +/** + * \def POLARSSL_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_CRT_PARSE_C + +/** + * \def POLARSSL_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +#define POLARSSL_X509_CRL_PARSE_C + +/** + * \def POLARSSL_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +#define POLARSSL_X509_CSR_PARSE_C + +/** + * \def POLARSSL_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +#define POLARSSL_X509_CREATE_C + +/** + * \def POLARSSL_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +#define POLARSSL_X509_CRT_WRITE_C + +/** + * \def POLARSSL_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +#define POLARSSL_X509_CSR_WRITE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define POLARSSL_XTEA_C + +/* \} name SECTION: PolarSSL modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ + +/* Memory buffer allocator options */ +//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ + +/* SSL Cache options */ +//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ + +/* Realteck Ameba HW Crypto */ +#ifdef CONFIG_PLATFORM_8195A +#define RTL_HW_CRYPTO +#define SUPPORT_HW_SW_CRYPTO +#endif + +#define RTL_CRYPTO_FRAGMENT 15360 /* 15*1024 < 16000 */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* Debug options */ +//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ + +/* \} name SECTION: Module configuration options */ + +#include "check_config.h" + +#endif /* POLARSSL_CONFIG_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rsa.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rsa.h new file mode 100644 index 0000000..cc7ba8e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/config_rsa.h @@ -0,0 +1,2184 @@ +/** + * \file config.h + * + * \brief Configuration options (set of defines) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +#ifndef POLARSSL_CONFIG_H +#define POLARSSL_CONFIG_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def POLARSSL_HAVE_INT8 + * + * The system uses 8-bit wide native integers. + * + * Uncomment if native integers are 8-bit wide. + */ +//#define POLARSSL_HAVE_INT8 + +/** + * \def POLARSSL_HAVE_INT16 + * + * The system uses 16-bit wide native integers. + * + * Uncomment if native integers are 16-bit wide. + */ +//#define POLARSSL_HAVE_INT16 + +/** + * \def POLARSSL_HAVE_LONGLONG + * + * The compiler supports the 'long long' type. + * (Only used on 32-bit platforms) + */ +#define POLARSSL_HAVE_LONGLONG + +/** + * \def POLARSSL_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/timing.c + * library/padlock.c + * include/polarssl/bn_mul.h + * + * Comment to disable the use of assembly code. + */ +//#define POLARSSL_HAVE_ASM + +/** + * \def POLARSSL_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define POLARSSL_HAVE_SSE2 + +/** + * \def POLARSSL_HAVE_TIME + * + * System has time.h and time() / localtime() / gettimeofday(). + * + * Comment if your system does not support time functions + */ +//#define POLARSSL_HAVE_TIME + +/** + * \def POLARSSL_HAVE_IPV6 + * + * System supports the basic socket interface for IPv6 (RFC 3493), + * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage. + * + * Note: on Windows/MingW, XP or higher is required. + * + * Comment if your system does not support the IPv6 socket interface + */ +//#define POLARSSL_HAVE_IPV6 + +/** + * \def POLARSSL_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default PolarSSL uses the system-provided malloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()" + * to allow you to set an alternative malloc() and free() function pointer. + * + * Requires: POLARSSL_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +#ifdef CONFIG_HARDWARE_8188F +#define POLARSSL_PLATFORM_MEMORY +#endif +/** + * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. malloc() to + * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the POLARSSL_PLATFORM_STD_XXX defines. + * + * Requires: POLARSSL_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def POLARSSL_PLATFORM_XXX_ALT + * + * Uncomment a macro to let PolarSSL support the function in the platform + * abstraction layer. + * + * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will + * provide a function "platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require POLARSSL_PLATFORM_C to be defined! + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define POLARSSL_PLATFORM_PRINTF_ALT +//#define POLARSSL_PLATFORM_FPRINTF_ALT +/* \} name SECTION: System support */ + +/** + * \name SECTION: PolarSSL feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def POLARSSL_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for hardclock(), + * get_timer(), set_alarm() and m_sleep(). + * + * Only works if you have POLARSSL_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define POLARSSL_TIMING_ALT + +/** + * \def POLARSSL_XXX_ALT + * + * Uncomment a macro to let PolarSSL use your alternate core implementation of + * a symmetric or hash algorithm (e.g. platform specific assembly optimized + * implementations). Keep in mind that the function prototypes should remain + * the same. + * + * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer + * provide the "struct aes_context" definition and omit the base function + * declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation for core algorithm + * functions + */ +//#define POLARSSL_AES_ALT +//#define POLARSSL_ARC4_ALT +//#define POLARSSL_BLOWFISH_ALT +//#define POLARSSL_CAMELLIA_ALT +//#define POLARSSL_DES_ALT +//#define POLARSSL_XTEA_ALT +//#define POLARSSL_MD2_ALT +//#define POLARSSL_MD4_ALT +//#define POLARSSL_MD5_ALT +//#define POLARSSL_RIPEMD160_ALT +//#define POLARSSL_SHA1_ALT +//#define POLARSSL_SHA256_ALT +//#define POLARSSL_SHA512_ALT + +/** + * \def POLARSSL_AES_ROM_TABLES + * + * Store the AES tables in ROM. + * + * Uncomment this macro to store the AES tables in ROM. + * + */ +#define POLARSSL_AES_ROM_TABLES + +/** + * \def POLARSSL_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CBC + +/** + * \def POLARSSL_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CFB + +/** + * \def POLARSSL_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define POLARSSL_CIPHER_MODE_CTR + +/** + * \def POLARSSL_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable + * the following ciphersuites: + * TLS_ECDH_ECDSA_WITH_NULL_SHA + * TLS_ECDH_RSA_WITH_NULL_SHA + * TLS_ECDHE_ECDSA_WITH_NULL_SHA + * TLS_ECDHE_RSA_WITH_NULL_SHA + * TLS_ECDHE_PSK_WITH_NULL_SHA384 + * TLS_ECDHE_PSK_WITH_NULL_SHA256 + * TLS_ECDHE_PSK_WITH_NULL_SHA + * TLS_DHE_PSK_WITH_NULL_SHA384 + * TLS_DHE_PSK_WITH_NULL_SHA256 + * TLS_DHE_PSK_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_SHA256 + * TLS_RSA_WITH_NULL_SHA + * TLS_RSA_WITH_NULL_MD5 + * TLS_RSA_PSK_WITH_NULL_SHA384 + * TLS_RSA_PSK_WITH_NULL_SHA256 + * TLS_RSA_PSK_WITH_NULL_SHA + * TLS_PSK_WITH_NULL_SHA384 + * TLS_PSK_WITH_NULL_SHA256 + * TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define POLARSSL_CIPHER_NULL_CIPHER + +/** + * \def POLARSSL_CIPHER_PADDING_XXX + * + * Uncomment or comment macros to add support for specific padding modes + * in the cipher layer with cipher modes that support padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define POLARSSL_CIPHER_PADDING_PKCS7 +#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS +#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN +#define POLARSSL_CIPHER_PADDING_ZEROS + +/** + * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES + * + * Enable weak ciphersuites in SSL / TLS. + * Warning: Only do so when you know what you are doing. This allows for + * channels with virtually no security at all! + * + * This enables the following ciphersuites: + * TLS_RSA_WITH_DES_CBC_SHA + * TLS_DHE_RSA_WITH_DES_CBC_SHA + * + * Uncomment this macro to enable weak ciphersuites + */ +//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES + +/** + * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES + * + * Remove RC4 ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on RC4 from the default list as + * returned by ssl_list_ciphersuites(). However, it is still possible to + * enable (some of) them with ssl_set_ciphersuites() by including them + * explicitly. + * + * Uncomment this macro to remove RC4 ciphersuites by default. + */ +//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES + +/** + * \def POLARSSL_ECP_XXXX_ENABLED + * + * Enables specific curves within the Elliptic Curve module. + * By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define POLARSSL_ECP_DP_SECP192R1_ENABLED +#define POLARSSL_ECP_DP_SECP224R1_ENABLED +#define POLARSSL_ECP_DP_SECP256R1_ENABLED +#define POLARSSL_ECP_DP_SECP384R1_ENABLED +#define POLARSSL_ECP_DP_SECP521R1_ENABLED +#define POLARSSL_ECP_DP_SECP192K1_ENABLED +#define POLARSSL_ECP_DP_SECP224K1_ENABLED +#define POLARSSL_ECP_DP_SECP256K1_ENABLED +#define POLARSSL_ECP_DP_BP256R1_ENABLED +#define POLARSSL_ECP_DP_BP384R1_ENABLED +#define POLARSSL_ECP_DP_BP512R1_ENABLED +//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet! +#define POLARSSL_ECP_DP_M255_ENABLED +//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet! +//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet! + +/** + * \def POLARSSL_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define POLARSSL_ECP_NIST_OPTIM + +/** + * \def POLARSSL_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: POLARSSL_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +//#define POLARSSL_ECDSA_DETERMINISTIC + +/** + * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + */ +#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15, + * POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C, + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + */ +//#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +//#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def POLARSSL_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +//#define POLARSSL_PK_PARSE_EC_EXTENDED + +/** + * \def POLARSSL_ERROR_STRERROR_BC + * + * Make available the backward compatible error_strerror() next to the + * current polarssl_strerror(). + * + * For new code, it is recommended to use polarssl_strerror() instead and + * disable this. + * + * Disable if you run into name conflicts and want to really remove the + * error_strerror() + */ +#define POLARSSL_ERROR_STRERROR_BC + +/** + * \def POLARSSL_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of polarssl_strerror() in + * third party libraries easier when POLARSSL_ERROR_C is disabled + * (no effect when POLARSSL_ERROR_C is enabled). + * + * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're + * not using polarssl_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * polarssl_strerror() + */ +#define POLARSSL_ERROR_STRERROR_DUMMY + +/** + * \def POLARSSL_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: POLARSSL_BIGNUM_C + */ +#define POLARSSL_GENPRIME + +/** + * \def POLARSSL_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define POLARSSL_FS_IO + +/** + * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def POLARSSL_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define POLARSSL_NO_PLATFORM_ENTROPY + +/** + * \def POLARSSL_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: POLARSSL_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both POLARSSL_SHA256_C and + * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define POLARSSL_ENTROPY_FORCE_SHA256 + +/** + * \def POLARSSL_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define POLARSSL_MEMORY_DEBUG + +/** + * \def POLARSSL_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define POLARSSL_MEMORY_BACKTRACE + +/** + * \def POLARSSL_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: POLARSSL_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define POLARSSL_PKCS1_V15 + +/** + * \def POLARSSL_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: POLARSSL_MD_C, POLARSSL_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +//#define POLARSSL_PKCS1_V21 + +/** + * \def POLARSSL_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define POLARSSL_RSA_NO_CRT + +/** + * \def POLARSSL_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define POLARSSL_SELF_TEST + +/** + * \def POLARSSL_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, PolarSSL can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define POLARSSL_SSL_ALERT_MESSAGES + +/** + * \def POLARSSL_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define POLARSSL_SSL_DEBUG_ALL + +/** + * \def POLARSSL_SSL_HW_RECORD_ACCEL + * + * Enable hooking functions in SSL module for hardware acceleration of + * individual records. + * + * Uncomment this macro to enable hooking functions. + */ +//#define POLARSSL_SSL_HW_RECORD_ACCEL + +/** + * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + * + * Enable support for receiving and parsing SSLv2 Client Hello messages for the + * SSL Server module (POLARSSL_SSL_SRV_C). + * + * Comment this macro to disable support for SSLv2 Client Hello messages. + */ +//#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO + +/** + * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + * + * Pick the ciphersuite according to the client's preferences rather than ours + * in the SSL Server module (POLARSSL_SSL_SRV_C). + * + * Uncomment this macro to respect client's ciphersuite order + */ +//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE + +/** + * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def POLARSSL_SSL_PROTO_SSL3 + * + * Enable support for SSL 3.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for SSL 3.0 + */ +#define POLARSSL_SSL_PROTO_SSL3 + +/** + * \def POLARSSL_SSL_PROTO_TLS1 + * + * Enable support for TLS 1.0. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.0 + */ +#define POLARSSL_SSL_PROTO_TLS1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_1 + * + * Enable support for TLS 1.1. + * + * Requires: POLARSSL_MD5_C + * POLARSSL_SHA1_C + * + * Comment this macro to disable support for TLS 1.1 + */ +#define POLARSSL_SSL_PROTO_TLS1_1 + +/** + * \def POLARSSL_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2. + * + * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C + * (Depends on ciphersuites) + * + * Comment this macro to disable support for TLS 1.2 + */ +#define POLARSSL_SSL_PROTO_TLS1_2 + +/** + * \def POLARSSL_SSL_ALPN + * + * Enable support for Application Layer Protocol Negotiation. + * draft-ietf-tls-applayerprotoneg-05 + * + * Comment this macro to disable support for ALPN. + */ +//#define POLARSSL_SSL_ALPN + +/** + * \def POLARSSL_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * + * Requires: POLARSSL_AES_C + * POLARSSL_SHA256_C + * POLARSSL_CIPHER_MODE_CBC + * + * Comment this macro to disable support for SSL session tickets + */ +#define POLARSSL_SSL_SESSION_TICKETS + +/** + * \def POLARSSL_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Comment this macro to disable support for server name indication in SSL + */ +#define POLARSSL_SSL_SERVER_NAME_INDICATION + +/** + * \def POLARSSL_SSL_TRUNCATED_HMAC + * + * Enable support for RFC 6066 truncated HMAC in SSL. + * + * Comment this macro to disable support for truncated HMAC in SSL + */ +#define POLARSSL_SSL_TRUNCATED_HMAC + +/** + * \def POLARSSL_SSL_SET_CURVES + * + * Enable ssl_set_curves(). + * + * This is disabled by default since it breaks binary compatibility with the + * 1.3.x line. If you choose to enable it, you will need to rebuild your + * application against the new header files, relinking will not be enough. + * It will be enabled by default, or no longer an option, in the 1.4 branch. + * + * Uncomment to make ssl_set_curves() available. + */ +//#define POLARSSL_SSL_SET_CURVES + +/** + * \def POLARSSL_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define POLARSSL_THREADING_ALT + +/** + * \def POLARSSL_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: POLARSSL_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define POLARSSL_THREADING_PTHREAD + +/** + * \def POLARSSL_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via version_check_feature(). + * + * Requires: POLARSSL_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +//#define POLARSSL_VERSION_FEATURES + +/** + * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an extension in a v1 or v2 certificate. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 + +/** + * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + * + * If set, the X509 parser will not break-off when parsing an X509 certificate + * and encountering an unknown critical extension. + * + * Uncomment to prevent an error. + */ +//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION + +/** + * \def POLARSSL_X509_CHECK_KEY_USAGE + * + * Enable verification of the keyUsage extension (CA and leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused + * (intermediate) CA and leaf certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip keyUsage checking for both CA and leaf certificates. + */ +//#define POLARSSL_X509_CHECK_KEY_USAGE + +/** + * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + * + * Enable verification of the extendedKeyUsage extension (leaf certificates). + * + * Disabling this avoids problems with mis-issued and/or misused certificates. + * + * \warning Depending on your PKI use, disabling this can be a security risk! + * + * Comment to skip extendedKeyUsage checking for certificates. + */ +//#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +/** + * \def POLARSSL_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +//#define POLARSSL_X509_RSASSA_PSS_SUPPORT + +/** + * \def POLARSSL_ZLIB_SUPPORT + * + * If set, the SSL/TLS module uses ZLIB to support compression and + * decompression of packet data. + * + * \warning TLS-level compression MAY REDUCE SECURITY! See for example the + * CRIME attack. Before enabling this option, you should examine with care if + * CRIME or similar exploits may be a applicable to your use case. + * + * Used in: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This feature requires zlib library and headers to be present. + * + * Uncomment to enable use of ZLIB + */ +//#define POLARSSL_ZLIB_SUPPORT +/* \} name SECTION: PolarSSL feature support */ + +/** + * \name SECTION: PolarSSL modules + * + * This section enables or disables entire modules in PolarSSL + * \{ + */ + +/** + * \def POLARSSL_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define POLARSSL_AESNI_C + +/** + * \def POLARSSL_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/ssl_tls.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * TLS_RSA_WITH_AES_256_GCM_SHA384 + * TLS_RSA_WITH_AES_256_CBC_SHA256 + * TLS_RSA_WITH_AES_256_CBC_SHA + * TLS_RSA_WITH_AES_128_GCM_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA256 + * TLS_RSA_WITH_AES_128_CBC_SHA + * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * TLS_PSK_WITH_AES_256_GCM_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA384 + * TLS_PSK_WITH_AES_256_CBC_SHA + * TLS_PSK_WITH_AES_128_GCM_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA256 + * TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define POLARSSL_AES_C + +/** + * \def POLARSSL_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_RC4_128_SHA + * TLS_ECDH_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + * TLS_ECDHE_RSA_WITH_RC4_128_SHA + * TLS_ECDHE_PSK_WITH_RC4_128_SHA + * TLS_DHE_PSK_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_SHA + * TLS_RSA_WITH_RC4_128_MD5 + * TLS_RSA_PSK_WITH_RC4_128_SHA + * TLS_PSK_WITH_RC4_128_SHA + */ +#define POLARSSL_ARC4_C + +/** + * \def POLARSSL_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define POLARSSL_ASN1_PARSE_C + +/** + * \def POLARSSL_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +//#define POLARSSL_ASN1_WRITE_C + +/** + * \def POLARSSL_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define POLARSSL_BASE64_C + +/** + * \def POLARSSL_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define POLARSSL_BIGNUM_C + +/** + * \def POLARSSL_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +//#define POLARSSL_BLOWFISH_C + +/** + * \def POLARSSL_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +//#define POLARSSL_CAMELLIA_C + +/** + * \def POLARSSL_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +//#define POLARSSL_CCM_C + +/** + * \def POLARSSL_CERTS_C + * + * Enable the test certificates. + * + * Module: library/certs.c + * Caller: + * + * Requires: POLARSSL_PEM_PARSE_C + * + * This module is used for testing (ssl_client/server). + */ +//#define POLARSSL_CERTS_C + +/** + * \def POLARSSL_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ssl_tls.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define POLARSSL_CIPHER_C + +/** + * \def POLARSSL_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-256-based random generator. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: POLARSSL_AES_C + * + * This module provides the CTR_DRBG AES-256 random number generator. + */ +//#define POLARSSL_CTR_DRBG_C + +/** + * \def POLARSSL_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module provides debugging functions. + */ +//#define POLARSSL_DEBUG_C + +/** + * \def POLARSSL_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/ssl_tls.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_WITH_3DES_EDE_CBC_SHA + * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA + * TLS_PSK_WITH_3DES_EDE_CBC_SHA + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + */ +//#define POLARSSL_DES_C + +/** + * \def POLARSSL_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + */ +//#define POLARSSL_DHM_C + +/** + * \def POLARSSL_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: POLARSSL_ECP_C + */ +//#define POLARSSL_ECDH_C + +/** + * \def POLARSSL_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C + */ +//#define POLARSSL_ECDSA_C + +/** + * \def POLARSSL_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * + * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED + */ +//#define POLARSSL_ECP_C + +/** + * \def POLARSSL_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C + * + * This module provides a generic entropy pool + */ +//#define POLARSSL_ENTROPY_C + +/** + * \def POLARSSL_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables polarssl_strerror(). + */ +//#define POLARSSL_ERROR_C + +/** + * \def POLARSSL_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +//#define POLARSSL_GCM_C + +/** + * \def POLARSSL_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: POLARSSL_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define POLARSSL_HAVEGE_C + +/** + * \def POLARSSL_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: POLARSSL_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +//#define POLARSSL_HMAC_DRBG_C + +/** + * \def POLARSSL_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define POLARSSL_MD_C + +/** + * \def POLARSSL_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + */ +//#define POLARSSL_MD2_C + +/** + * \def POLARSSL_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + */ +//#define POLARSSL_MD4_C + +/** + * \def POLARSSL_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for SSL/TLS and X.509. + * PEM_PARSE uses MD5 for decrypting encrypted keys. + */ +#define POLARSSL_MD5_C + +/** + * \def POLARSSL_MEMORY_C + * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead. + */ +//#define POLARSSL_MEMORY_C + +/** + * \def POLARSSL_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces malloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: POLARSSL_PLATFORM_C + * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define POLARSSL_MEMORY_BUFFER_ALLOC_C + +/** + * \def POLARSSL_NET_C + * + * Enable the TCP/IP networking routines. + * + * Module: library/net.c + * + * This module provides TCP/IP networking routines. + */ +#define POLARSSL_NET_C + +/** + * \def POLARSSL_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define POLARSSL_OID_C + +/** + * \def POLARSSL_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: POLARSSL_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define POLARSSL_PADLOCK_C + +/** + * \def POLARSSL_PBKDF2_C + * + * Enable PKCS#5 PBKDF2 key derivation function. + * DEPRECATED: Use POLARSSL_PKCS5_C instead + * + * Module: library/pbkdf2.c + * + * Requires: POLARSSL_PKCS5_C + * + * This module adds support for the PKCS#5 PBKDF2 key derivation function. + */ +//#define POLARSSL_PBKDF2_C + +/** + * \def POLARSSL_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define POLARSSL_PEM_PARSE_C + +/** + * \def POLARSSL_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: POLARSSL_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +//#define POLARSSL_PEM_WRITE_C + +/** + * \def POLARSSL_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * Caller: library/ssl_tls.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define POLARSSL_PK_C + +/** + * \def POLARSSL_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define POLARSSL_PK_PARSE_C + +/** + * \def POLARSSL_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: POLARSSL_PK_C + * + * Uncomment to enable generic public key write functions. + */ +//#define POLARSSL_PK_WRITE_C + +/** + * \def POLARSSL_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: POLARSSL_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +//#define POLARSSL_PKCS5_C + +/** + * \def POLARSSL_PKCS11_C + * + * Enable wrapper for PKCS#11 smartcard support. + * + * Module: library/pkcs11.c + * Caller: library/pk.c + * + * Requires: POLARSSL_PK_C + * + * This module enables SSL/TLS PKCS #11 smartcard support. + * Requires the presence of the PKCS#11 helper library (libpkcs11-helper) + */ +//#define POLARSSL_PKCS11_C + +/** + * \def POLARSSL_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C + * Can use: POLARSSL_ARC4_C + * + * This module enables PKCS#12 functions. + */ +//#define POLARSSL_PKCS12_C + +/** + * \def POLARSSL_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like malloc(), free(), printf(), fprintf() + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define POLARSSL_PLATFORM_C + +/** + * \def POLARSSL_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +//#define POLARSSL_RIPEMD160_C + +/** + * \def POLARSSL_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C + */ +#define POLARSSL_RSA_C + +/** + * \def POLARSSL_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * library/x509write_crt.c + * + * This module is required for SSL/TLS and SHA1-signed certificates. + */ +#define POLARSSL_SHA1_C + +/** + * \def POLARSSL_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA2_C) + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define POLARSSL_SHA256_C + +/** + * \def POLARSSL_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * (Used to be POLARSSL_SHA4_C) + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_cli.c + * library/ssl_srv.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define POLARSSL_SHA512_C + +/** + * \def POLARSSL_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: POLARSSL_SSL_CACHE_C + */ +#define POLARSSL_SSL_CACHE_C + +/** + * \def POLARSSL_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl_cli.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ +#define POLARSSL_SSL_CLI_C + +/** + * \def POLARSSL_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl_srv.c + * Caller: + * + * Requires: POLARSSL_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +//#define POLARSSL_SSL_SRV_C + +/** + * \def POLARSSL_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * + * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C + * and at least one of the POLARSSL_SSL_PROTO_* defines + * + * This module is required for SSL/TLS. + */ +#define POLARSSL_SSL_TLS_C + +/** + * \def POLARSSL_THREADING_C + * + * Enable the threading abstraction layer. + * By default PolarSSL assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either POLARSSL_THREADING_ALT or + * POLARSSL_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within PolarSSL + */ +//#define POLARSSL_THREADING_C + +/** + * \def POLARSSL_TIMING_C + * + * Enable the portable timing interface. + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define POLARSSL_TIMING_C + +/** + * \def POLARSSL_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define POLARSSL_VERSION_C + +/** + * \def POLARSSL_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C, + * POLARSSL_PK_PARSE_C + * + * This module is required for the X.509 parsing modules. + */ +#define POLARSSL_X509_USE_C + +/** + * \def POLARSSL_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_cli.c + * library/ssl_srv.c + * library/ssl_tls.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ +#define POLARSSL_X509_CRT_PARSE_C + +/** + * \def POLARSSL_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +//#define POLARSSL_X509_CRL_PARSE_C + +/** + * \def POLARSSL_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: POLARSSL_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +//#define POLARSSL_X509_CSR_PARSE_C + +/** + * \def POLARSSL_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +//#define POLARSSL_X509_CREATE_C + +/** + * \def POLARSSL_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +//#define POLARSSL_X509_CRT_WRITE_C + +/** + * \def POLARSSL_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: POLARSSL_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ +//#define POLARSSL_X509_CSR_WRITE_C + +/** + * \def POLARSSL_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +//#define POLARSSL_XTEA_C + +/* \} name SECTION: PolarSSL modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ + +/* Memory buffer allocator options */ +//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define POLARSSL_PLATFORM_STD_MEM_HDR /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ + +/* SSL Cache options */ +//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ +//pvvx/#define SSL_MAX_CONTENT_LEN 4096 /**< Size of the input / output buffer */ +//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */ + + +#define RTL_CRYPTO_FRAGMENT 15360 /* 15*1024 < 16000 */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/* Debug options */ +//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ + +/* \} name SECTION: Module configuration options */ + +#include "check_config.h" + +#endif /* POLARSSL_CONFIG_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ctr_drbg.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ctr_drbg.h new file mode 100644 index 0000000..bebbfe9 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ctr_drbg.h @@ -0,0 +1,274 @@ +/** + * \file ctr_drbg.h + * + * \brief CTR_DRBG based on AES-256 (NIST SP 800-90) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_CTR_DRBG_H +#define POLARSSL_CTR_DRBG_H + +#include + +#include "aes.h" + +#define POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED -0x0034 /**< The entropy source failed. */ +#define POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG -0x0036 /**< Too many random requested in single call. */ +#define POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG -0x0038 /**< Input too large (Entropy + additional). */ +#define POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR -0x003A /**< Read/write error in file. */ + +#define CTR_DRBG_BLOCKSIZE 16 /**< Block size used by the cipher */ +#define CTR_DRBG_KEYSIZE 32 /**< Key size used by the cipher */ +#define CTR_DRBG_KEYBITS ( CTR_DRBG_KEYSIZE * 8 ) +#define CTR_DRBG_SEEDLEN ( CTR_DRBG_KEYSIZE + CTR_DRBG_BLOCKSIZE ) + /**< The seed length (counter + AES key) */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(CTR_DRBG_ENTROPY_LEN) +#if defined(POLARSSL_SHA512_C) && !defined(POLARSSL_ENTROPY_FORCE_SHA256) +#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +#else +#define CTR_DRBG_ENTROPY_LEN 32 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +#endif +#endif + +#if !defined(CTR_DRBG_RESEED_INTERVAL) +#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +#endif + +#if !defined(CTR_DRBG_MAX_INPUT) +#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +#endif + +#if !defined(CTR_DRBG_MAX_REQUEST) +#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +#endif + +#if !defined(CTR_DRBG_MAX_SEED_INPUT) +#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +#endif + +/* \} name SECTION: Module settings */ + +#define CTR_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define CTR_DRBG_PR_ON 1 /**< Prediction resistance enabled */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief CTR_DRBG context structure + */ +typedef struct +{ + unsigned char counter[16]; /*!< counter (V) */ + int reseed_counter; /*!< reseed counter */ + int prediction_resistance; /*!< enable prediction resistance (Automatic + reseed before every random generation) */ + size_t entropy_len; /*!< amount of entropy grabbed on each + (re)seed */ + int reseed_interval; /*!< reseed interval */ + + aes_context aes_ctx; /*!< AES context */ + + /* + * Callbacks (Entropy) + */ + int (*f_entropy)(void *, unsigned char *, size_t); + + void *p_entropy; /*!< context for the entropy function */ +} +ctr_drbg_context; + +/** + * \brief CTR_DRBG initialization + * + * Note: Personalization data can be provided in addition to the more generic + * entropy source to make this instantiation as unique as possible. + * + * \param ctx CTR_DRBG context to be initialized + * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer + * length) + * \param p_entropy Entropy context + * \param custom Personalization data (Device specific identifiers) + * (Can be NULL) + * \param len Length of personalization data + * + * \return 0 if successful, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED + */ +int ctr_drbg_init( ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ); + +/** + * \brief Clear CTR_CRBG context data + * + * \param ctx CTR_DRBG context to clear + */ +void ctr_drbg_free( ctr_drbg_context *ctx ); + +/** + * \brief Enable / disable prediction resistance (Default: Off) + * + * Note: If enabled, entropy is used for ctx->entropy_len before each call! + * Only use this if you have ample supply of good entropy! + * + * \param ctx CTR_DRBG context + * \param resistance CTR_DRBG_PR_ON or CTR_DRBG_PR_OFF + */ +void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, + int resistance ); + +/** + * \brief Set the amount of entropy grabbed on each (re)seed + * (Default: CTR_DRBG_ENTROPY_LEN) + * + * \param ctx CTR_DRBG context + * \param len Amount of entropy to grab + */ +void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, + size_t len ); + +/** + * \brief Set the reseed interval + * (Default: CTR_DRBG_RESEED_INTERVAL) + * + * \param ctx CTR_DRBG context + * \param interval Reseed interval + */ +void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, + int interval ); + +/** + * \brief CTR_DRBG reseeding (extracts data from entropy source) + * + * \param ctx CTR_DRBG context + * \param additional Additional data to add to state (Can be NULL) + * \param len Length of additional data + * + * \return 0 if successful, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED + */ +int ctr_drbg_reseed( ctr_drbg_context *ctx, + const unsigned char *additional, size_t len ); + +/** + * \brief CTR_DRBG update state + * + * \param ctx CTR_DRBG context + * \param additional Additional data to update state with + * \param add_len Length of additional data + */ +void ctr_drbg_update( ctr_drbg_context *ctx, + const unsigned char *additional, size_t add_len ); + +/** + * \brief CTR_DRBG generate random with additional update input + * + * Note: Automatically reseeds if reseed_counter is reached. + * + * \param p_rng CTR_DRBG context + * \param output Buffer to fill + * \param output_len Length of the buffer + * \param additional Additional data to update with (Can be NULL) + * \param add_len Length of additional data + * + * \return 0 if successful, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG + */ +int ctr_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, size_t add_len ); + +/** + * \brief CTR_DRBG generate random + * + * Note: Automatically reseeds if reseed_counter is reached. + * + * \param p_rng CTR_DRBG context + * \param output Buffer to fill + * \param output_len Length of the buffer + * + * \return 0 if successful, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG + */ +int ctr_drbg_random( void *p_rng, + unsigned char *output, size_t output_len ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx CTR_DRBG context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR on file error, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED + */ +int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance + * + * \param ctx CTR_DRBG context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR on file error, + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED or + * POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG + */ +int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ctr_drbg_self_test( int verbose ); + +/* Internal functions (do not call directly) */ +int ctr_drbg_init_entropy_len( ctr_drbg_context *, + int (*)(void *, unsigned char *, size_t), void *, + const unsigned char *, size_t, size_t ); + +#ifdef __cplusplus +} +#endif + +#endif /* ctr_drbg.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/debug.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/debug.h new file mode 100644 index 0000000..0dd79d5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/debug.h @@ -0,0 +1,152 @@ +/** + * \file debug.h + * + * \brief Debug functions + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_DEBUG_H +#define POLARSSL_DEBUG_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#include "ssl.h" +#if defined(POLARSSL_ECP_C) +#include "ecp.h" +#endif + +#if defined(POLARSSL_DEBUG_C) + +#define POLARSSL_DEBUG_LOG_FULL 0 /**< Include file:line in log lines */ +#define POLARSSL_DEBUG_LOG_RAW 1 /**< Only log raw debug lines */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_DEBUG_DFL_MODE) +#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */ +#endif + +/* \} name SECTION: Module settings */ + + +#define SSL_DEBUG_MSG( level, args ) \ + debug_print_msg( ssl, level, __FILE__, __LINE__, debug_fmt args ); + +#define SSL_DEBUG_RET( level, text, ret ) \ + debug_print_ret( ssl, level, __FILE__, __LINE__, text, ret ); + +#define SSL_DEBUG_BUF( level, text, buf, len ) \ + debug_print_buf( ssl, level, __FILE__, __LINE__, text, buf, len ); + +#if defined(POLARSSL_BIGNUM_C) +#define SSL_DEBUG_MPI( level, text, X ) \ + debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X ); +#endif + +#if defined(POLARSSL_ECP_C) +#define SSL_DEBUG_ECP( level, text, X ) \ + debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) +#define SSL_DEBUG_CRT( level, text, crt ) \ + debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt ); +#endif + +#else /* POLARSSL_DEBUG_C */ + +#define SSL_DEBUG_MSG( level, args ) do { } while( 0 ) +#define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 ) +#define SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 ) +#define SSL_DEBUG_MPI( level, text, X ) do { } while( 0 ) +#define SSL_DEBUG_ECP( level, text, X ) do { } while( 0 ) +#define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 ) + +#endif /* POLARSSL_DEBUG_C */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Set the log mode for the debug functions globally + * (Default value: POLARSSL_DEBUG_DFL_MODE) + * + * \param log_mode The log mode to use (POLARSSL_DEBUG_LOG_FULL or + * POLARSSL_DEBUG_LOG_RAW) + */ +void debug_set_log_mode( int log_mode ); + +/** + * \brief Set the level threshold to handle globally. Messages that have a + * level over the threshold value are ignored. + * (Default value: 0 (No debug)) + * + * \param threshold maximum level of messages to pass on + */ +void debug_set_threshold( int threshold ); + +char *debug_fmt( const char *format, ... ); + +void debug_print_msg( const ssl_context *ssl, int level, + const char *file, int line, const char *text ); + +void debug_print_ret( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret ); + +void debug_print_buf( const ssl_context *ssl, int level, + const char *file, int line, const char *text, + unsigned char *buf, size_t len ); + +#if defined(POLARSSL_BIGNUM_C) +void debug_print_mpi( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mpi *X ); +#endif + +#if defined(POLARSSL_ECP_C) +void debug_print_ecp( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const ecp_point *X ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) +void debug_print_crt( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const x509_crt *crt ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* debug.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/des.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/des.h new file mode 100644 index 0000000..8cf1a3b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/des.h @@ -0,0 +1,300 @@ +/** + * \file des.h + * + * \brief DES block cipher + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_DES_H +#define POLARSSL_DES_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ + +#define DES_KEY_SIZE 8 + +#if !defined(POLARSSL_DES_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + uint32_t sk[32]; /*!< DES subkeys */ +#ifdef RTL_HW_CRYPTO + unsigned char enc_key[DES_KEY_SIZE]; + unsigned char dec_key[DES_KEY_SIZE]; +#endif +} +des_context; + +/** + * \brief Triple-DES context structure + */ +typedef struct +{ + int mode; /*!< encrypt/decrypt */ + uint32_t sk[96]; /*!< 3DES subkeys */ +#ifdef RTL_HW_CRYPTO + unsigned char enc_key[DES_KEY_SIZE * 3]; + unsigned char dec_key[DES_KEY_SIZE * 3]; +#endif +} +des3_context; + +/** + * \brief Initialize DES context + * + * \param ctx DES context to be initialized + */ +void des_init( des_context *ctx ); + +/** + * \brief Clear DES context + * + * \param ctx DES context to be cleared + */ +void des_free( des_context *ctx ); + +/** + * \brief Initialize Triple-DES context + * + * \param ctx DES3 context to be initialized + */ +void des3_init( des3_context *ctx ); + +/** + * \brief Clear Triple-DES context + * + * \param ctx DES3 context to be cleared + */ +void des3_free( des3_context *ctx ); + +/** + * \brief Set key parity on the given key to odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + */ +void des_key_set_parity( unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief Check that key parity on the given key is odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + * + * \return 0 is parity was ok, 1 if parity was not correct. + */ +int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief Check that key is not a weak or semi-weak DES key + * + * \param key 8-byte secret key + * + * \return 0 if no weak key was found, 1 if a weak key was identified. + */ +int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ); + +/** + * \brief Triple-DES key schedule (112-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + */ +int des3_set2key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ); + +/** + * \brief Triple-DES key schedule (112-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + */ +int des3_set2key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ); + +/** + * \brief Triple-DES key schedule (168-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + */ +int des3_set3key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ); + +/** + * \brief Triple-DES key schedule (168-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + */ +int des3_set3key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief DES-CBC buffer encryption/decryption + * + * \param ctx DES context + * \param mode DES_ENCRYPT or DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +int des_crypt_cbc( des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/** + * \brief 3DES-ECB block encryption/decryption + * + * \param ctx 3DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int des3_crypt_ecb( des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief 3DES-CBC buffer encryption/decryption + * + * \param ctx 3DES context + * \param mode DES_ENCRYPT or DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH + */ +int des3_crypt_cbc( des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_DES_ALT */ +#include "des_alt.h" +#endif /* POLARSSL_DES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int des_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* des.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/dhm.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/dhm.h new file mode 100644 index 0000000..064472f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/dhm.h @@ -0,0 +1,311 @@ +/** + * \file dhm.h + * + * \brief Diffie-Hellman-Merkle key exchange + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_DHM_H +#define POLARSSL_DHM_H + +#include "bignum.h" + +/* + * DHM Error codes + */ +#define POLARSSL_ERR_DHM_BAD_INPUT_DATA -0x3080 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_DHM_READ_PARAMS_FAILED -0x3100 /**< Reading of the DHM parameters failed. */ +#define POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED -0x3180 /**< Making of the DHM parameters failed. */ +#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */ +#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */ +#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */ +#define POLARSSL_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */ +#define POLARSSL_ERR_DHM_MALLOC_FAILED -0x3400 /**< Allocation of memory failed. */ +#define POLARSSL_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read/write of file failed. */ + +/** + * RFC 2409 defines a number of standardized Diffie-Hellman groups + * that can be used. + * RFC 3526 defines a number of standardized Diffie-Hellman groups + * for IKE. + * RFC 5114 defines a number of standardized Diffie-Hellman groups + * that can be used. + * + * Some are included here for convenience. + * + * Included are: + * RFC 2409 6.2. 1024-bit MODP Group (Second Oakley Group) + * RFC 3526 3. 2048-bit MODP Group + * RFC 3526 4. 3072-bit MODP Group + * RFC 5114 2.1. 1024-bit MODP Group with 160-bit Prime Order Subgroup + * RFC 5114 2.2. 2048-bit MODP Group with 224-bit Prime Order Subgroup + */ +#define POLARSSL_DHM_RFC2409_MODP_1024_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ + "FFFFFFFFFFFFFFFF" + +#define POLARSSL_DHM_RFC2409_MODP_1024_G "02" + +#define POLARSSL_DHM_RFC3526_MODP_2048_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ + "15728E5A8AACAA68FFFFFFFFFFFFFFFF" + +#define POLARSSL_DHM_RFC3526_MODP_2048_G "02" + +#define POLARSSL_DHM_RFC3526_MODP_3072_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" \ + "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" \ + "83655D23DCA3AD961C62F356208552BB9ED529077096966D" \ + "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" \ + "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" \ + "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" \ + "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" \ + "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" \ + "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" \ + "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" \ + "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" \ + "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF" + +#define POLARSSL_DHM_RFC3526_MODP_3072_G "02" + +#define POLARSSL_DHM_RFC5114_MODP_1024_P \ + "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6" \ + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0" \ + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70" \ + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0" \ + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708" \ + "DF1FB2BC2E4A4371" + +#define POLARSSL_DHM_RFC5114_MODP_1024_G \ + "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F" \ + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213" \ + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1" \ + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A" \ + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24" \ + "855E6EEB22B3B2E5" + +#define POLARSSL_DHM_RFC5114_MODP_2048_P \ + "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1" \ + "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15" \ + "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212" \ + "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207" \ + "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708" \ + "B3BF8A317091883681286130BC8985DB1602E714415D9330" \ + "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D" \ + "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8" \ + "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763" \ + "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71" \ + "CF9DE5384E71B81C0AC4DFFE0C10E64F" + +#define POLARSSL_DHM_RFC5114_MODP_2048_G \ + "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"\ + "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"\ + "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"\ + "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"\ + "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"\ + "F180EB34118E98D119529A45D6F834566E3025E316A330EF"\ + "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"\ + "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"\ + "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"\ + "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"\ + "81BC087F2A7065B384B890D3191F2BFA" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DHM context structure + */ +typedef struct +{ + size_t len; /*!< size(P) in chars */ + mpi P; /*!< prime modulus */ + mpi G; /*!< generator */ + mpi X; /*!< secret value */ + mpi GX; /*!< self = G^X mod P */ + mpi GY; /*!< peer = G^Y mod P */ + mpi K; /*!< key = GY^X mod P */ + mpi RP; /*!< cached R^2 mod P */ + mpi Vi; /*!< blinding value */ + mpi Vf; /*!< un-blinding value */ + mpi pX; /*!< previous X */ +} +dhm_context; + +/** + * \brief Initialize DHM context + * + * \param ctx DHM context to be initialized + */ +void dhm_init( dhm_context *ctx ); + +/** + * \brief Parse the ServerKeyExchange parameters + * + * \param ctx DHM context + * \param p &(start of input buffer) + * \param end end of buffer + * + * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code + */ +int dhm_read_params( dhm_context *ctx, + unsigned char **p, + const unsigned char *end ); + +/** + * \brief Setup and write the ServerKeyExchange parameters + * + * \param ctx DHM context + * \param x_size private value size in bytes + * \param output destination buffer + * \param olen number of chars written + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note This function assumes that ctx->P and ctx->G + * have already been properly set (for example + * using mpi_read_string or mpi_read_binary). + * + * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code + */ +int dhm_make_params( dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Import the peer's public value G^Y + * + * \param ctx DHM context + * \param input input buffer + * \param ilen size of buffer + * + * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code + */ +int dhm_read_public( dhm_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief Create own private value X and export G^X + * + * \param ctx DHM context + * \param x_size private value size in bytes + * \param output destination buffer + * \param olen must be equal to ctx->P.len + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code + */ +int dhm_make_public( dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Derive and export the shared secret (G^Y)^X mod P + * + * \param ctx DHM context + * \param output destination buffer + * \param olen on entry, must hold the size of the destination buffer + * on exit, holds the actual number of bytes written + * \param f_rng RNG function, for blinding purposes + * \param p_rng RNG parameter + * + * \return 0 if successful, or an POLARSSL_ERR_DHM_XXX error code + * + * \note If non-NULL, f_rng is used to blind the input as + * countermeasure against timing attacks. Blinding is + * automatically used if and only if our secret value X is + * re-used and costs nothing otherwise, so it is recommended + * to always pass a non-NULL f_rng argument. + */ +int dhm_calc_secret( dhm_context *ctx, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Free and clear the components of a DHM key + * + * \param ctx DHM context to free and clear + */ +void dhm_free( dhm_context *ctx ); + +#if defined(POLARSSL_ASN1_PARSE_C) +/** \ingroup x509_module */ +/** + * \brief Parse DHM parameters + * + * \param dhm DHM context to be initialized + * \param dhmin input buffer + * \param dhminlen size of the buffer + * + * \return 0 if successful, or a specific DHM or PEM error code + */ +int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ); + +#if defined(POLARSSL_FS_IO) +/** \ingroup x509_module */ +/** + * \brief Load and parse DHM parameters + * + * \param dhm DHM context to be initialized + * \param path filename to read the DHM Parameters from + * + * \return 0 if successful, or a specific DHM or PEM error code + */ +int dhm_parse_dhmfile( dhm_context *dhm, const char *path ); +#endif /* POLARSSL_FS_IO */ +#endif /* POLARSSL_ASN1_PARSE_C */ + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int dhm_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* dhm.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdh.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdh.h new file mode 100644 index 0000000..525cade --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdh.h @@ -0,0 +1,225 @@ +/** + * \file ecdh.h + * + * \brief Elliptic curve Diffie-Hellman + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ECDH_H +#define POLARSSL_ECDH_H + +#include "ecp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * When importing from an EC key, select if it is our key or the peer's key + */ +typedef enum +{ + POLARSSL_ECDH_OURS, + POLARSSL_ECDH_THEIRS, +} ecdh_side; + +/** + * \brief ECDH context structure + */ +typedef struct +{ + ecp_group grp; /*!< elliptic curve used */ + mpi d; /*!< our secret value (private key) */ + ecp_point Q; /*!< our public value (public key) */ + ecp_point Qp; /*!< peer's public value (public key) */ + mpi z; /*!< shared secret */ + int point_format; /*!< format for point export in TLS messages */ + ecp_point Vi; /*!< blinding value (for later) */ + ecp_point Vf; /*!< un-blinding value (for later) */ + mpi _d; /*!< previous d (for later) */ +} +ecdh_context; + +/** + * \brief Generate a public key. + * Raw function that only does the core computation. + * + * \param grp ECP group + * \param d Destination MPI (secret exponent, aka private key) + * \param Q Destination point (public key) + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Compute shared secret + * Raw function that only does the core computation. + * + * \param grp ECP group + * \param z Destination MPI (shared secret) + * \param Q Public key from other party + * \param d Our secret exponent (private key) + * \param f_rng RNG function (see notes) + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + * + * \note If f_rng is not NULL, it is used to implement + * countermeasures against potential elaborate timing + * attacks, see \c ecp_mul() for details. + */ +int ecdh_compute_shared( ecp_group *grp, mpi *z, + const ecp_point *Q, const mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Initialize context + * + * \param ctx Context to initialize + */ +void ecdh_init( ecdh_context *ctx ); + +/** + * \brief Free context + * + * \param ctx Context to free + */ +void ecdh_free( ecdh_context *ctx ); + +/** + * \brief Generate a public key and a TLS ServerKeyExchange payload. + * (First function used by a TLS server for ECDHE.) + * + * \param ctx ECDH context + * \param olen number of chars written + * \param buf destination buffer + * \param blen length of buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note This function assumes that ctx->grp has already been + * properly set (for example using ecp_use_known_dp). + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_make_params( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Parse and procress a TLS ServerKeyExhange payload. + * (First function used by a TLS client for ECDHE.) + * + * \param ctx ECDH context + * \param buf pointer to start of input buffer + * \param end one past end of buffer + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_read_params( ecdh_context *ctx, + const unsigned char **buf, const unsigned char *end ); + +/** + * \brief Setup an ECDH context from an EC key. + * (Used by clients and servers in place of the + * ServerKeyEchange for static ECDH: import ECDH parameters + * from a certificate's EC key information.) + * + * \param ctx ECDH constext to set + * \param key EC key to use + * \param side Is it our key (1) or the peer's key (0) ? + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, + ecdh_side side ); + +/** + * \brief Generate a public key and a TLS ClientKeyExchange payload. + * (Second function used by a TLS client for ECDH(E).) + * + * \param ctx ECDH context + * \param olen number of bytes actually written + * \param buf destination buffer + * \param blen size of destination buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_make_public( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Parse and process a TLS ClientKeyExchange payload. + * (Second function used by a TLS server for ECDH(E).) + * + * \param ctx ECDH context + * \param buf start of input buffer + * \param blen length of input buffer + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_read_public( ecdh_context *ctx, + const unsigned char *buf, size_t blen ); + +/** + * \brief Derive and export the shared secret. + * (Last function used by both TLS client en servers.) + * + * \param ctx ECDH context + * \param olen number of bytes written + * \param buf destination buffer + * \param blen buffer length + * \param f_rng RNG function, see notes for \c ecdh_compute_shared() + * \param p_rng RNG parameter + * + * \return 0 if successful, or an POLARSSL_ERR_ECP_XXX error code + */ +int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ecdh_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* ecdh.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdsa.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdsa.h new file mode 100644 index 0000000..d99a17a --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecdsa.h @@ -0,0 +1,236 @@ +/** + * \file ecdsa.h + * + * \brief Elliptic curve DSA + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ECDSA_H +#define POLARSSL_ECDSA_H + +#include "ecp.h" + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +#include "md.h" +#endif + +/** + * \brief ECDSA context structure + * + * \note Purposefully begins with the same members as struct ecp_keypair. + */ +typedef struct +{ + ecp_group grp; /*!< elliptic curve used */ + mpi d; /*!< secret signature key */ + ecp_point Q; /*!< public signature key */ + mpi r; /*!< first integer from signature */ + mpi s; /*!< second integer from signature */ +} +ecdsa_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Compute ECDSA signature of a previously hashed message + * + * \param grp ECP group + * \param r First output integer + * \param s Second output integer + * \param d Private signing key + * \param buf Message hash + * \param blen Length of buf + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/** + * \brief Compute ECDSA signature of a previously hashed message + * (deterministic version) + * + * \param grp ECP group + * \param r First output integer + * \param s Second output integer + * \param d Private signing key + * \param buf Message hash + * \param blen Length of buf + * \param md_alg MD algorithm used to hash the message + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + md_type_t md_alg ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/** + * \brief Verify ECDSA signature of a previously hashed message + * + * \param grp ECP group + * \param buf Message hash + * \param blen Length of buf + * \param Q Public key to use for verification + * \param r First integer of the signature + * \param s Second integer of the signature + * + * \return 0 if successful, + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecdsa_verify( ecp_group *grp, + const unsigned char *buf, size_t blen, + const ecp_point *Q, const mpi *r, const mpi *s); + +/** + * \brief Compute ECDSA signature and write it to buffer, + * serialized as defined in RFC 4492 page 20. + * (Not thread-safe to use same context in multiple threads) + * + * \param ctx ECDSA context + * \param hash Message hash + * \param hlen Length of hash + * \param sig Buffer that will hold the signature + * \param slen Length of the signature written + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note The "sig" buffer must be at least as large as twice the + * size of the curve used, plus 7 (eg. 71 bytes if a 256-bit + * curve is used). + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or + * POLARSSL_ERR_ASN1 error code + */ +int ecdsa_write_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/** + * \brief Compute ECDSA signature and write it to buffer, + * serialized as defined in RFC 4492 page 20. + * Deterministic version, RFC 6979. + * (Not thread-safe to use same context in multiple threads) + * + * \param ctx ECDSA context + * \param hash Message hash + * \param hlen Length of hash + * \param sig Buffer that will hold the signature + * \param slen Length of the signature written + * \param md_alg MD algorithm used to hash the message + * + * \note The "sig" buffer must be at least as large as twice the + * size of the curve used, plus 7 (eg. 71 bytes if a 256-bit + * curve is used). + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP, POLARSSL_ERR_MPI or + * POLARSSL_ERR_ASN1 error code + */ +int ecdsa_write_signature_det( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + md_type_t md_alg ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/** + * \brief Read and verify an ECDSA signature + * + * \param ctx ECDSA context + * \param hash Message hash + * \param hlen Size of hash + * \param sig Signature to read and verify + * \param slen Size of sig + * + * \return 0 if successful, + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if signature is invalid, + * POLARSSL_ERR_ECP_SIG_LEN_MISTMATCH if the signature is + * valid but its actual length is less than siglen, + * or a POLARSSL_ERR_ECP or POLARSSL_ERR_MPI error code + */ +int ecdsa_read_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ); + +/** + * \brief Generate an ECDSA keypair on the given curve + * + * \param ctx ECDSA context in which the keypair should be stored + * \param gid Group (elliptic curve) to use. One of the various + * POLARSSL_ECP_DP_XXX macros depending on configuration. + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 on success, or a POLARSSL_ERR_ECP code. + */ +int ecdsa_genkey( ecdsa_context *ctx, ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Set an ECDSA context from an EC key pair + * + * \param ctx ECDSA context to set + * \param key EC key to use + * + * \return 0 on success, or a POLARSSL_ERR_ECP code. + */ +int ecdsa_from_keypair( ecdsa_context *ctx, const ecp_keypair *key ); + +/** + * \brief Initialize context + * + * \param ctx Context to initialize + */ +void ecdsa_init( ecdsa_context *ctx ); + +/** + * \brief Free context + * + * \param ctx Context to free + */ +void ecdsa_free( ecdsa_context *ctx ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ecdsa_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* ecdsa.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecp.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecp.h new file mode 100644 index 0000000..7192f1e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ecp.h @@ -0,0 +1,651 @@ +/** + * \file ecp.h + * + * \brief Elliptic curves over GF(p) + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ECP_H +#define POLARSSL_ECP_H + +#include "bignum.h" + +/* + * ECP error codes + */ +#define POLARSSL_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */ +#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< Requested curve not available. */ +#define POLARSSL_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */ +#define POLARSSL_ERR_ECP_MALLOC_FAILED -0x4D80 /**< Memory allocation failed. */ +#define POLARSSL_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */ +#define POLARSSL_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */ +#define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Domain parameters (curve, subgroup and generator) identifiers. + * + * Only curves over prime fields are supported. + * + * \warning This library does not support validation of arbitrary domain + * parameters. Therefore, only well-known domain parameters from trusted + * sources should be used. See ecp_use_known_dp(). + */ +typedef enum +{ + POLARSSL_ECP_DP_NONE = 0, + POLARSSL_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */ + POLARSSL_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */ + POLARSSL_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */ + POLARSSL_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */ + POLARSSL_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */ + POLARSSL_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */ + POLARSSL_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */ + POLARSSL_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */ + POLARSSL_ECP_DP_M221, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_M255, /*!< Curve25519 */ + POLARSSL_ECP_DP_M383, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_M511, /*!< (not implemented yet) */ + POLARSSL_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */ + POLARSSL_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */ + POLARSSL_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */ +} ecp_group_id; + +/** + * Number of supported curves (plus one for NONE). + * + * (Montgomery curves excluded for now.) + */ +#define POLARSSL_ECP_DP_MAX 12 + +/** + * Curve information for use by other modules + */ +typedef struct +{ + ecp_group_id grp_id; /*!< Internal identifier */ + uint16_t tls_id; /*!< TLS NamedCurve identifier */ + uint16_t size; /*!< Curve size in bits */ + const char *name; /*!< Human-friendly name */ +} ecp_curve_info; + +/** + * \brief ECP point structure (jacobian coordinates) + * + * \note All functions expect and return points satisfying + * the following condition: Z == 0 or Z == 1. (Other + * values of Z are used by internal functions only.) + * The point is zero, or "at infinity", if Z == 0. + * Otherwise, X and Y are its standard (affine) coordinates. + */ +typedef struct +{ + mpi X; /*!< the point's X coordinate */ + mpi Y; /*!< the point's Y coordinate */ + mpi Z; /*!< the point's Z coordinate */ +} +ecp_point; + +/** + * \brief ECP group structure + * + * We consider two types of curves equations: + * 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492) + * 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (M255 + draft) + * In both cases, a generator G for a prime-order subgroup is fixed. In the + * short weierstrass, this subgroup is actually the whole curve, and its + * cardinal is denoted by N. + * + * In the case of Short Weierstrass curves, our code requires that N is an odd + * prime. (Use odd in ecp_mul() and prime in ecdsa_sign() for blinding.) + * + * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is + * the quantity actually used in the formulas. Also, nbits is not the size of N + * but the required size for private keys. + * + * If modp is NULL, reduction modulo P is done using a generic algorithm. + * Otherwise, it must point to a function that takes an mpi in the range + * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more + * than pbits, so that the integer may be efficiently brought in the 0..P-1 + * range by a few additions or substractions. It must return 0 on success and + * non-zero on failure. + */ +typedef struct +{ + ecp_group_id id; /*!< internal group identifier */ + mpi P; /*!< prime modulus of the base field */ + mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */ + mpi B; /*!< 1. B in the equation, or 2. unused */ + ecp_point G; /*!< generator of the (sub)group used */ + mpi N; /*!< 1. the order of G, or 2. unused */ + size_t pbits; /*!< number of bits in P */ + size_t nbits; /*!< number of bits in 1. P, or 2. private keys */ + unsigned int h; /*!< internal: 1 if the constants are static */ + int (*modp)(mpi *); /*!< function for fast reduction mod P */ + int (*t_pre)(ecp_point *, void *); /*!< unused */ + int (*t_post)(ecp_point *, void *); /*!< unused */ + void *t_data; /*!< unused */ + ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */ + size_t T_size; /*!< number for pre-computed points */ +} +ecp_group; + +/** + * \brief ECP key pair structure + * + * A generic key pair that could be used for ECDSA, fixed ECDH, etc. + * + * \note Members purposefully in the same order as struc ecdsa_context. + */ +typedef struct +{ + ecp_group grp; /*!< Elliptic curve and base point */ + mpi d; /*!< our secret value */ + ecp_point Q; /*!< our public value */ +} +ecp_keypair; + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_ECP_MAX_BITS) +/** + * Maximum size of the groups (that is, of N and P) + */ +#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +#endif + +#define POLARSSL_ECP_MAX_BYTES ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 ) +#define POLARSSL_ECP_MAX_PT_LEN ( 2 * POLARSSL_ECP_MAX_BYTES + 1 ) + +#if !defined(POLARSSL_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: 6. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +#endif /* POLARSSL_ECP_WINDOW_SIZE */ + +#if !defined(POLARSSL_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ +#endif /* POLARSSL_ECP_FIXED_POINT_OPTIM */ + +/* \} name SECTION: Module settings */ + +/* + * Point formats, from RFC 4492's enum ECPointFormat + */ +#define POLARSSL_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */ +#define POLARSSL_ECP_PF_COMPRESSED 1 /**< Compressed point format */ + +/* + * Some other constants from RFC 4492 + */ +#define POLARSSL_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */ + +/** + * \brief Get the list of supported curves in order of preferrence + * (full information) + * + * \return A statically allocated array, the last entry is 0. + */ +const ecp_curve_info *ecp_curve_list( void ); + +/** + * \brief Get the list of supported curves in order of preferrence + * (grp_id only) + * + * \return A statically allocated array, + * terminated with POLARSSL_ECP_DP_NONE. + */ +const ecp_group_id *ecp_grp_id_list( void ); + +/** + * \brief Get curve information from an internal group identifier + * + * \param grp_id A POLARSSL_ECP_DP_XXX value + * + * \return The associated curve information or NULL + */ +const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id ); + +/** + * \brief Get curve information from a TLS NamedCurve value + * + * \param tls_id A POLARSSL_ECP_DP_XXX value + * + * \return The associated curve information or NULL + */ +const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id ); + +/** + * \brief Get curve information from a human-readable name + * + * \param name The name + * + * \return The associated curve information or NULL + */ +const ecp_curve_info *ecp_curve_info_from_name( const char *name ); + +/** + * \brief Initialize a point (as zero) + */ +void ecp_point_init( ecp_point *pt ); + +/** + * \brief Initialize a group (to something meaningless) + */ +void ecp_group_init( ecp_group *grp ); + +/** + * \brief Initialize a key pair (as an invalid one) + */ +void ecp_keypair_init( ecp_keypair *key ); + +/** + * \brief Free the components of a point + */ +void ecp_point_free( ecp_point *pt ); + +/** + * \brief Free the components of an ECP group + */ +void ecp_group_free( ecp_group *grp ); + +/** + * \brief Free the components of a key pair + */ +void ecp_keypair_free( ecp_keypair *key ); + +/** + * \brief Copy the contents of point Q into P + * + * \param P Destination point + * \param Q Source point + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int ecp_copy( ecp_point *P, const ecp_point *Q ); + +/** + * \brief Copy the contents of a group object + * + * \param dst Destination group + * \param src Source group + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int ecp_group_copy( ecp_group *dst, const ecp_group *src ); + +/** + * \brief Set a point to zero + * + * \param pt Destination point + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + */ +int ecp_set_zero( ecp_point *pt ); + +/** + * \brief Tell if a point is zero + * + * \param pt Point to test + * + * \return 1 if point is zero, 0 otherwise + */ +int ecp_is_zero( ecp_point *pt ); + +/** + * \brief Import a non-zero point from two ASCII strings + * + * \param P Destination point + * \param radix Input numeric base + * \param x First affine coordinate as a null-terminated string + * \param y Second affine coordinate as a null-terminated string + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + */ +int ecp_point_read_string( ecp_point *P, int radix, + const char *x, const char *y ); + +/** + * \brief Export a point into unsigned binary data + * + * \param grp Group to which the point should belong + * \param P Point to export + * \param format Point format, should be a POLARSSL_ECP_PF_XXX macro + * \param olen Length of the actual output + * \param buf Output buffer + * \param buflen Length of the output buffer + * + * \return 0 if successful, + * or POLARSSL_ERR_ECP_BAD_INPUT_DATA + * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL + */ +int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ); + +/** + * \brief Import a point from unsigned binary data + * + * \param grp Group to which the point should belong + * \param P Point to import + * \param buf Input buffer + * \param ilen Actual length of input + * + * \return 0 if successful, + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE if the point format + * is not implemented. + * + * \note This function does NOT check that the point actually + * belongs to the given group, see ecp_check_pubkey() for + * that. + */ +int ecp_point_read_binary( const ecp_group *grp, ecp_point *P, + const unsigned char *buf, size_t ilen ); + +/** + * \brief Import a point from a TLS ECPoint record + * + * \param grp ECP group used + * \param pt Destination point + * \param buf $(Start of input buffer) + * \param len Buffer length + * + * \return O if successful, + * POLARSSL_ERR_MPI_XXX if initialization failed + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid + */ +int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt, + const unsigned char **buf, size_t len ); + +/** + * \brief Export a point as a TLS ECPoint record + * + * \param grp ECP group used + * \param pt Point to export + * \param format Export format + * \param olen length of data written + * \param buf Buffer to write to + * \param blen Buffer length + * + * \return 0 if successful, + * or POLARSSL_ERR_ECP_BAD_INPUT_DATA + * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL + */ +int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ); + +/** + * \brief Import an ECP group from null-terminated ASCII strings + * + * \param grp Destination group + * \param radix Input numeric base + * \param p Prime modulus of the base field + * \param b Constant term in the equation + * \param gx The generator's X coordinate + * \param gy The generator's Y coordinate + * \param n The generator's order + * + * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code + * + * \note Sets all fields except modp. + */ +int ecp_group_read_string( ecp_group *grp, int radix, + const char *p, const char *b, + const char *gx, const char *gy, const char *n); + +/** + * \brief Set a group using well-known domain parameters + * + * \param grp Destination group + * \param index Index in the list of well-known domain parameters + * + * \return O if successful, + * POLARSSL_ERR_MPI_XXX if initialization failed + * POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups + * + * \note Index should be a value of RFC 4492's enum NamdeCurve, + * possibly in the form of a POLARSSL_ECP_DP_XXX macro. + */ +int ecp_use_known_dp( ecp_group *grp, ecp_group_id index ); + +/** + * \brief Set a group from a TLS ECParameters record + * + * \param grp Destination group + * \param buf &(Start of input buffer) + * \param len Buffer length + * + * \return O if successful, + * POLARSSL_ERR_MPI_XXX if initialization failed + * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid + */ +int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len ); + +/** + * \brief Write the TLS ECParameters record for a group + * + * \param grp ECP group used + * \param olen Number of bytes actually written + * \param buf Buffer to write to + * \param blen Buffer length + * + * \return 0 if successful, + * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL + */ +int ecp_tls_write_group( const ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen ); + +/** + * \brief Addition: R = P + Q + * + * \param grp ECP group + * \param R Destination point + * \param P Left-hand point + * \param Q Right-hand point + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * + * \note This function does not support Montgomery curves, such as + * Curve25519. + */ +int ecp_add( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ); + +/** + * \brief Subtraction: R = P - Q + * + * \param grp ECP group + * \param R Destination point + * \param P Left-hand point + * \param Q Right-hand point + * + * \return 0 if successful, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * + * \note This function does not support Montgomery curves, such as + * Curve25519. + */ +int ecp_sub( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ); + +/** + * \brief Multiplication by an integer: R = m * P + * (Not thread-safe to use same group in multiple threads) + * + * \param grp ECP group + * \param R Destination point + * \param m Integer by which to multiply + * \param P Point to multiply + * \param f_rng RNG function (see notes) + * \param p_rng RNG parameter + * + * \return 0 if successful, + * POLARSSL_ERR_ECP_INVALID_KEY if m is not a valid privkey + * or P is not a valid pubkey, + * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed + * + * \note In order to prevent timing attacks, this function + * executes the exact same sequence of (base field) + * operations for any valid m. It avoids any if-branch or + * array index depending on the value of m. + * + * \note If f_rng is not NULL, it is used to randomize intermediate + * results in order to prevent potential timing attacks + * targeting these results. It is recommended to always + * provide a non-NULL f_rng (the overhead is negligible). + */ +int ecp_mul( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Check that a point is a valid public key on this curve + * + * \param grp Curve/group the point should belong to + * \param pt Point to check + * + * \return 0 if point is a valid public key, + * POLARSSL_ERR_ECP_INVALID_KEY otherwise. + * + * \note This function only checks the point is non-zero, has valid + * coordinates and lies on the curve, but not that it is + * indeed a multiple of G. This is additional check is more + * expensive, isn't required by standards, and shouldn't be + * necessary if the group used has a small cofactor. In + * particular, it is useless for the NIST groups which all + * have a cofactor of 1. + * + * \note Uses bare components rather than an ecp_keypair structure + * in order to ease use with other structures such as + * ecdh_context of ecdsa_context. + */ +int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt ); + +/** + * \brief Check that an mpi is a valid private key for this curve + * + * \param grp Group used + * \param d Integer to check + * + * \return 0 if point is a valid private key, + * POLARSSL_ERR_ECP_INVALID_KEY otherwise. + * + * \note Uses bare components rather than an ecp_keypair structure + * in order to ease use with other structures such as + * ecdh_context of ecdsa_context. + */ +int ecp_check_privkey( const ecp_group *grp, const mpi *d ); + +/** + * \brief Generate a keypair + * + * \param grp ECP group + * \param d Destination MPI (secret part) + * \param Q Destination point (public part) + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + * + * \note Uses bare components rather than an ecp_keypair structure + * in order to ease use with other structures such as + * ecdh_context of ecdsa_context. + */ +int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Generate a keypair + * + * \param grp_id ECP group identifier + * \param key Destination keypair + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 if successful, + * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code + */ +int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int ecp_self_test( int verbose ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ecp.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy.h new file mode 100644 index 0000000..f5fa928 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy.h @@ -0,0 +1,246 @@ +/** + * \file entropy.h + * + * \brief Entropy accumulator implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ENTROPY_H +#define POLARSSL_ENTROPY_H + +#include + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA512_C) && !defined(POLARSSL_ENTROPY_FORCE_SHA256) +#include "sha512.h" +#define POLARSSL_ENTROPY_SHA512_ACCUMULATOR +#else +#if defined(POLARSSL_SHA256_C) +#define POLARSSL_ENTROPY_SHA256_ACCUMULATOR +#include "sha256.h" +#endif +#endif + +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + +#if defined(POLARSSL_HAVEGE_C) +#include "havege.h" +#endif + +#define POLARSSL_ERR_ENTROPY_SOURCE_FAILED -0x003C /**< Critical entropy source failure. */ +#define POLARSSL_ERR_ENTROPY_MAX_SOURCES -0x003E /**< No more sources can be added. */ +#define POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 /**< No sources have been added to poll. */ +#define POLARSSL_ERR_ENTROPY_FILE_IO_ERROR -0x0058 /**< Read/write error in file. */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(ENTROPY_MAX_SOURCES) +#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +#endif + +#if !defined(ENTROPY_MAX_GATHER) +#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +#endif + +/* \} name SECTION: Module settings */ + +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) +#define ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ +#else +#define ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ +#endif + +#define ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ +#define ENTROPY_SOURCE_MANUAL ENTROPY_MAX_SOURCES + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Entropy poll callback pointer + * + * \param data Callback-specific data pointer + * \param output Data to fill + * \param len Maximum size to provide + * \param olen The actual amount of bytes put into the buffer (Can be 0) + * + * \return 0 if no critical failures occurred, + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED otherwise + */ +typedef int (*f_source_ptr)(void *data, unsigned char *output, size_t len, + size_t *olen); + +/** + * \brief Entropy source state + */ +typedef struct +{ + f_source_ptr f_source; /**< The entropy source callback */ + void * p_source; /**< The callback data pointer */ + size_t size; /**< Amount received */ + size_t threshold; /**< Minimum level required before release */ +} +source_state; + +/** + * \brief Entropy context structure + */ +typedef struct +{ +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) + sha512_context accumulator; +#else + sha256_context accumulator; +#endif + int source_count; + source_state source[ENTROPY_MAX_SOURCES]; +#if defined(POLARSSL_HAVEGE_C) + havege_state havege_data; +#endif +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< mutex */ +#endif +} +entropy_context; + +/** + * \brief Initialize the context + * + * \param ctx Entropy context to initialize + */ +void entropy_init( entropy_context *ctx ); + +/** + * \brief Free the data in the context + * + * \param ctx Entropy context to free + */ +void entropy_free( entropy_context *ctx ); + +/** + * \brief Adds an entropy source to poll + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param ctx Entropy context + * \param f_source Entropy function + * \param p_source Function data + * \param threshold Minimum required from source before entropy is released + * ( with entropy_func() ) + * + * \return 0 if successful or POLARSSL_ERR_ENTROPY_MAX_SOURCES + */ +int entropy_add_source( entropy_context *ctx, + f_source_ptr f_source, void *p_source, + size_t threshold ); + +/** + * \brief Trigger an extra gather poll for the accumulator + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param ctx Entropy context + * + * \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_gather( entropy_context *ctx ); + +/** + * \brief Retrieve entropy from the accumulator + * (Maximum length: ENTROPY_BLOCK_SIZE) + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param data Entropy context + * \param output Buffer to fill + * \param len Number of bytes desired, must be at most ENTROPY_BLOCK_SIZE + * + * \return 0 if successful, or POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_func( void *data, unsigned char *output, size_t len ); + +/** + * \brief Add data to the accumulator manually + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param ctx Entropy context + * \param data Data to add + * \param len Length of data + * + * \return 0 if successful + */ +int entropy_update_manual( entropy_context *ctx, + const unsigned char *data, size_t len ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, or + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_write_seed_file( entropy_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance. No more than ENTROPY_MAX_SEED_SIZE bytes are + * read from the seed file. The rest is ignored. + * + * \param ctx Entropy context + * \param path Name of the file + * + * \return 0 if successful, + * POLARSSL_ERR_ENTROPY_FILE_IO_ERROR on file error, + * POLARSSL_ERR_ENTROPY_SOURCE_FAILED + */ +int entropy_update_seed_file( entropy_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int entropy_self_test( int verbose ); +#endif /* POLARSSL_SELF_TEST */ + +#ifdef __cplusplus +} +#endif + +#endif /* entropy.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy_poll.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy_poll.h new file mode 100644 index 0000000..92efa00 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/entropy_poll.h @@ -0,0 +1,79 @@ +/** + * \file entropy_poll.h + * + * \brief Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ENTROPY_POLL_H +#define POLARSSL_ENTROPY_POLL_H + +#include + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Default thresholds for built-in sources + */ +#define ENTROPY_MIN_PLATFORM 128 /**< Minimum for platform source */ +#define ENTROPY_MIN_HAVEGE 128 /**< Minimum for HAVEGE */ +#define ENTROPY_MIN_HARDCLOCK 32 /**< Minimum for hardclock() */ + +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) +/** + * \brief Platform-specific entropy poll callback + */ +int platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#if defined(POLARSSL_HAVEGE_C) +/** + * \brief HAVEGE based entropy poll callback + * + * Requires an HAVEGE state as its data pointer. + */ +int havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#if defined(POLARSSL_TIMING_C) +/** + * \brief hardclock-based entropy poll callback + */ +int hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* entropy_poll.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/error.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/error.h new file mode 100644 index 0000000..cdee952 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/error.h @@ -0,0 +1,123 @@ +/** + * \file error.h + * + * \brief Error to string translation + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_ERROR_H +#define POLARSSL_ERROR_H + +#include + +/** + * Error code layout. + * + * Currently we try to keep all error codes within the negative space of 16 + * bytes signed integers to support all platforms (-0x0000 - -0x8000). In + * addition we'd like to give two layers of information on the error if + * possible. + * + * For that purpose the error codes are segmented in the following manner: + * + * 16 bit error code bit-segmentation + * + * 1 bit - Sign bit + * 3 bits - High level module ID + * 5 bits - Module-dependent error code + * 7 bits - Low level module errors + * + * For historical reasons, low-level error codes are divided in even and odd, + * even codes were assigned first, and -1 is reserved for other errors. + * + * Low-level module errors (0x0002-0x007E, 0x0003-0x007F) + * + * Module Nr Codes assigned + * MPI 7 0x0002-0x0010 + * GCM 2 0x0012-0x0014 + * BLOWFISH 2 0x0016-0x0018 + * THREADING 3 0x001A-0x001E + * AES 2 0x0020-0x0022 + * CAMELLIA 2 0x0024-0x0026 + * XTEA 1 0x0028-0x0028 + * BASE64 2 0x002A-0x002C + * OID 1 0x002E-0x002E 0x000B-0x000B + * PADLOCK 1 0x0030-0x0030 + * DES 1 0x0032-0x0032 + * CTR_DBRG 4 0x0034-0x003A + * ENTROPY 3 0x003C-0x0040 + * NET 11 0x0042-0x0056 + * ENTROPY 1 0x0058-0x0058 + * ASN1 7 0x0060-0x006C + * MD2 1 0x0070-0x0070 + * MD4 1 0x0072-0x0072 + * MD5 1 0x0074-0x0074 + * SHA1 1 0x0076-0x0076 + * SHA256 1 0x0078-0x0078 + * SHA512 1 0x007A-0x007A + * PBKDF2 1 0x007C-0x007C + * RIPEMD160 1 0x007E-0x007E + * HMAC_DRBG 4 0x0003-0x0009 + * CCM 2 0x000D-0x000F + * + * High-level module nr (3 bits - 0x0...-0x7...) + * Name ID Nr of Errors + * PEM 1 9 + * PKCS#12 1 4 (Started from top) + * X509 2 18 + * PK 2 14 (Started from top, plus 0x2000) + * DHM 3 9 + * PKCS5 3 4 (Started from top) + * RSA 4 9 + * ECP 4 8 (Started from top) + * MD 5 4 + * CIPHER 6 6 + * SSL 6 9 (Started from top) + * SSL 7 31 + * + * Module dependent error code (5 bits 0x.00.-0x.F8.) + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Translate a PolarSSL error code into a string representation, + * Result is truncated if necessary and always includes a terminating + * null byte. + * + * \param errnum error code + * \param buffer buffer to place representation in + * \param buflen length of the buffer + */ +void polarssl_strerror( int errnum, char *buffer, size_t buflen ); + +#if defined(POLARSSL_ERROR_STRERROR_BC) +void error_strerror( int errnum, char *buffer, size_t buflen ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* error.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/gcm.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/gcm.h new file mode 100644 index 0000000..c2829a0 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/gcm.h @@ -0,0 +1,219 @@ +/** + * \file gcm.h + * + * \brief Galois/Counter mode for 128-bit block ciphers + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_GCM_H +#define POLARSSL_GCM_H + +#include "cipher.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; +#else +#include +#endif + +#define GCM_ENCRYPT 1 +#define GCM_DECRYPT 0 + +#define POLARSSL_ERR_GCM_AUTH_FAILED -0x0012 /**< Authenticated decryption failed. */ +#define POLARSSL_ERR_GCM_BAD_INPUT -0x0014 /**< Bad input parameters to function. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief GCM context structure + */ +typedef struct { + cipher_context_t cipher_ctx;/*!< cipher context used */ + uint64_t HL[16]; /*!< Precalculated HTable */ + uint64_t HH[16]; /*!< Precalculated HTable */ + uint64_t len; /*!< Total data length */ + uint64_t add_len; /*!< Total add length */ + unsigned char base_ectr[16];/*!< First ECTR for tag */ + unsigned char y[16]; /*!< Y working value */ + unsigned char buf[16]; /*!< buf working value */ + int mode; /*!< Encrypt or Decrypt */ +} +gcm_context; + +/** + * \brief GCM initialization (encryption) + * + * \param ctx GCM context to be initialized + * \param cipher cipher to use (a 128-bit block cipher) + * \param key encryption key + * \param keysize must be 128, 192 or 256 + * + * \return 0 if successful, or a cipher specific error code + */ +int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, + unsigned int keysize ); + +/** + * \brief GCM buffer encryption/decryption using a block cipher + * + * \note On encryption, the output buffer can be the same as the input buffer. + * On decryption, the output buffer cannot be the same as input buffer. + * If buffers overlap, the output buffer must trail at least 8 bytes + * behind the input buffer. + * + * \param ctx GCM context + * \param mode GCM_ENCRYPT or GCM_DECRYPT + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * \param tag_len length of the tag to generate + * \param tag buffer for holding the tag + * + * \return 0 if successful + */ +int gcm_crypt_and_tag( gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ); + +/** + * \brief GCM buffer authenticated decryption using a block cipher + * + * \note On decryption, the output buffer cannot be the same as input buffer. + * If buffers overlap, the output buffer must trail at least 8 bytes + * behind the input buffer. + * + * \param ctx GCM context + * \param length length of the input data + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data + * \param add_len length of additional data + * \param tag buffer holding the tag + * \param tag_len length of the tag + * \param input buffer holding the input data + * \param output buffer for holding the output data + * + * \return 0 if successful and authenticated, + * POLARSSL_ERR_GCM_AUTH_FAILED if tag does not match + */ +int gcm_auth_decrypt( gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic GCM stream start function + * + * \param ctx GCM context + * \param mode GCM_ENCRYPT or GCM_DECRYPT + * \param iv initialization vector + * \param iv_len length of IV + * \param add additional data (or NULL if length is 0) + * \param add_len length of additional data + * + * \return 0 if successful + */ +int gcm_starts( gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ); + +/** + * \brief Generic GCM update function. Encrypts/decrypts using the + * given GCM context. Expects input to be a multiple of 16 + * bytes! Only the last call before gcm_finish() can be less + * than 16 bytes! + * + * \note On decryption, the output buffer cannot be the same as input buffer. + * If buffers overlap, the output buffer must trail at least 8 bytes + * behind the input buffer. + * + * \param ctx GCM context + * \param length length of the input data + * \param input buffer holding the input data + * \param output buffer for holding the output data + * + * \return 0 if successful or POLARSSL_ERR_GCM_BAD_INPUT + */ +int gcm_update( gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic GCM finalisation function. Wraps up the GCM stream + * and generates the tag. The tag can have a maximum length of + * 16 bytes. + * + * \param ctx GCM context + * \param tag buffer for holding the tag (may be NULL if tag_len is 0) + * \param tag_len length of the tag to generate + * + * \return 0 if successful or POLARSSL_ERR_GCM_BAD_INPUT + */ +int gcm_finish( gcm_context *ctx, + unsigned char *tag, + size_t tag_len ); + +/** + * \brief Free a GCM context and underlying cipher sub-context + * + * \param ctx GCM context to free + */ +void gcm_free( gcm_context *ctx ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int gcm_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* gcm.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/havege.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/havege.h new file mode 100644 index 0000000..536eb08 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/havege.h @@ -0,0 +1,78 @@ +/** + * \file havege.h + * + * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_HAVEGE_H +#define POLARSSL_HAVEGE_H + +#include + +#define COLLECT_SIZE 1024 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief HAVEGE state structure + */ +typedef struct +{ + int PT1, PT2, offset[2]; + int pool[COLLECT_SIZE]; + int WALK[8192]; +} +havege_state; + +/** + * \brief HAVEGE initialization + * + * \param hs HAVEGE state to be initialized + */ +void havege_init( havege_state *hs ); + +/** + * \brief Clear HAVEGE state + * + * \param hs HAVEGE state to be cleared + */ +void havege_free( havege_state *hs ); + +/** + * \brief HAVEGE rand function + * + * \param p_rng A HAVEGE state + * \param output Buffer to fill + * \param len Length of buffer + * + * \return 0 + */ +int havege_random( void *p_rng, unsigned char *output, size_t len ); + +#ifdef __cplusplus +} +#endif + +#endif /* havege.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/hmac_drbg.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/hmac_drbg.h new file mode 100644 index 0000000..2d765d5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/hmac_drbg.h @@ -0,0 +1,284 @@ +/** + * \file hmac_drbg.h + * + * \brief HMAC_DRBG (NIST SP 800-90A) + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_HMAC_DRBG_H +#define POLARSSL_HMAC_DRBG_H + +#include "md.h" + +/* + * Error codes + */ +#define POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG -0x0003 /**< Too many random requested in single call. */ +#define POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG -0x0005 /**< Input too large (Entropy + additional). */ +#define POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR -0x0007 /**< Read/write error in file. */ +#define POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED -0x0009 /**< The entropy source failed. */ + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_HMAC_DRBG_RESEED_INTERVAL) +#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_INPUT) +#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_REQUEST) +#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +#endif + +#if !defined(POLARSSL_HMAC_DRBG_MAX_SEED_INPUT) +#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +#endif + +/* \} name SECTION: Module settings */ + +#define POLARSSL_HMAC_DRBG_PR_OFF 0 /**< No prediction resistance */ +#define POLARSSL_HMAC_DRBG_PR_ON 1 /**< Prediction resistance enabled */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * HMAC_DRBG context. + */ +typedef struct +{ + /* Working state: the key K is not stored explicitely, + * but is implied by the HMAC context */ + md_context_t md_ctx; /*!< HMAC context (inc. K) */ + unsigned char V[POLARSSL_MD_MAX_SIZE]; /*!< V in the spec */ + int reseed_counter; /*!< reseed counter */ + + /* Administrative state */ + size_t entropy_len; /*!< entropy bytes grabbed on each (re)seed */ + int prediction_resistance; /*!< enable prediction resistance (Automatic + reseed before every random generation) */ + int reseed_interval; /*!< reseed interval */ + + /* Callbacks */ + int (*f_entropy)(void *, unsigned char *, size_t); /*!< entropy function */ + void *p_entropy; /*!< context for the entropy function */ +} hmac_drbg_context; + +/** + * \brief HMAC_DRBG initialisation + * + * \param ctx HMAC_DRBG context to be initialised + * \param md_info MD algorithm to use for HMAC_DRBG + * \param f_entropy Entropy callback (p_entropy, buffer to fill, buffer + * length) + * \param p_entropy Entropy context + * \param custom Personalization data (Device specific identifiers) + * (Can be NULL) + * \param len Length of personalization data + * + * \note The "security strength" as defined by NIST is set to: + * 128 bits if md_alg is SHA-1, + * 192 bits if md_alg is SHA-224, + * 256 bits if md_alg is SHA-256 or higher. + * Note that SHA-256 is just as efficient as SHA-224. + * + * \return 0 if successful, or + * POLARSSL_ERR_MD_BAD_INPUT_DATA, or + * POLARSSL_ERR_MD_ALLOC_FAILED, or + * POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED. + */ +int hmac_drbg_init( hmac_drbg_context *ctx, + const md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ); + +/** + * \brief Initilisation of simpified HMAC_DRBG (never reseeds). + * (For use with deterministic ECDSA.) + * + * \param ctx HMAC_DRBG context to be initialised + * \param md_info MD algorithm to use for HMAC_DRBG + * \param data Concatenation of entropy string and additional data + * \param data_len Length of data in bytes + * + * \return 0 if successful, or + * POLARSSL_ERR_MD_BAD_INPUT_DATA, or + * POLARSSL_ERR_MD_ALLOC_FAILED. + */ +int hmac_drbg_init_buf( hmac_drbg_context *ctx, + const md_info_t * md_info, + const unsigned char *data, size_t data_len ); + +/** + * \brief Enable / disable prediction resistance (Default: Off) + * + * Note: If enabled, entropy is used for ctx->entropy_len before each call! + * Only use this if you have ample supply of good entropy! + * + * \param ctx HMAC_DRBG context + * \param resistance POLARSSL_HMAC_DRBG_PR_ON or POLARSSL_HMAC_DRBG_PR_OFF + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ); + +/** + * \brief Set the amount of entropy grabbed on each reseed + * (Default: given by the security strength, which + * depends on the hash used, see \c hmac_drbg_init() ) + * + * \param ctx HMAC_DRBG context + * \param len Amount of entropy to grab, in bytes + */ +void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, + size_t len ); + +/** + * \brief Set the reseed interval + * (Default: POLARSSL_HMAC_DRBG_RESEED_INTERVAL) + * + * \param ctx HMAC_DRBG context + * \param interval Reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, + int interval ); + +/** + * \brief HMAC_DRBG update state + * + * \param ctx HMAC_DRBG context + * \param additional Additional data to update state with, or NULL + * \param add_len Length of additional data, or 0 + * + * \note Additional data is optional, pass NULL and 0 as second + * third argument if no additional data is being used. + */ +void hmac_drbg_update( hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ); + +/** + * \brief HMAC_DRBG reseeding (extracts data from entropy source) + * + * \param ctx HMAC_DRBG context + * \param additional Additional data to add to state (Can be NULL) + * \param len Length of additional data + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + */ +int hmac_drbg_reseed( hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ); + +/** + * \brief HMAC_DRBG generate random with additional update input + * + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param output_len Length of the buffer + * \param additional Additional data to update with (can be NULL) + * \param add_len Length of additional data (can be 0) + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG, or + * POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG. + */ +int hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, + size_t add_len ); + +/** + * \brief HMAC_DRBG generate random + * + * Note: Automatically reseeds if reseed_counter is reached or PR is enabled. + * + * \param p_rng HMAC_DRBG context + * \param output Buffer to fill + * \param out_len Length of the buffer + * + * \return 0 if successful, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED, or + * POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG + */ +int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ); + +/** + * \brief Free an HMAC_DRBG context + * + * \param ctx HMAC_DRBG context to free. + */ +void hmac_drbg_free( hmac_drbg_context *ctx ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Write a seed file + * + * \param ctx HMAC_DRBG context + * \param path Name of the file + * + * \return 0 if successful, 1 on file error, or + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED + */ +int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path ); + +/** + * \brief Read and update a seed file. Seed is added to this + * instance + * + * \param ctx HMAC_DRBG context + * \param path Name of the file + * + * \return 0 if successful, 1 on file error, + * POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED or + * POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG + */ +int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ + + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int hmac_drbg_self_test( int verbose ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* hmac_drbg.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md.h new file mode 100644 index 0000000..81d8a2e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md.h @@ -0,0 +1,395 @@ +/** + * \file md.h + * + * \brief Generic message digest wrapper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD_H +#define POLARSSL_MD_H + +#include + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +#define POLARSSL_ERR_MD_FEATURE_UNAVAILABLE -0x5080 /**< The selected feature is not available. */ +#define POLARSSL_ERR_MD_BAD_INPUT_DATA -0x5100 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_MD_ALLOC_FAILED -0x5180 /**< Failed to allocate memory. */ +#define POLARSSL_ERR_MD_FILE_IO_ERROR -0x5200 /**< Opening or reading of file failed. */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + POLARSSL_MD_NONE=0, + POLARSSL_MD_MD2, + POLARSSL_MD_MD4, + POLARSSL_MD_MD5, + POLARSSL_MD_SHA1, + POLARSSL_MD_SHA224, + POLARSSL_MD_SHA256, + POLARSSL_MD_SHA384, + POLARSSL_MD_SHA512, + POLARSSL_MD_RIPEMD160, +} md_type_t; + +#if defined(POLARSSL_SHA512_C) +#define POLARSSL_MD_MAX_SIZE 64 /* longest known is SHA512 */ +#else +#define POLARSSL_MD_MAX_SIZE 32 /* longest known is SHA256 or less */ +#endif + +/** + * Message digest information. Allows message digest functions to be called + * in a generic way. + */ +typedef struct { + /** Digest identifier */ + md_type_t type; + + /** Name of the message digest */ + const char * name; + + /** Output length of the digest function */ + int size; + + /** Digest initialisation function */ + void (*starts_func)( void *ctx ); + + /** Digest update function */ + void (*update_func)( void *ctx, const unsigned char *input, size_t ilen ); + + /** Digest finalisation function */ + void (*finish_func)( void *ctx, unsigned char *output ); + + /** Generic digest function */ + void (*digest_func)( const unsigned char *input, size_t ilen, + unsigned char *output ); + + /** Generic file digest function */ + int (*file_func)( const char *path, unsigned char *output ); + + /** HMAC Initialisation function */ + void (*hmac_starts_func)( void *ctx, const unsigned char *key, + size_t keylen ); + + /** HMAC update function */ + void (*hmac_update_func)( void *ctx, const unsigned char *input, + size_t ilen ); + + /** HMAC finalisation function */ + void (*hmac_finish_func)( void *ctx, unsigned char *output); + + /** HMAC context reset function */ + void (*hmac_reset_func)( void *ctx ); + + /** Generic HMAC function */ + void (*hmac_func)( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + + /** Internal use only */ + void (*process_func)( void *ctx, const unsigned char *input ); +} md_info_t; + +/** + * Generic message digest context. + */ +typedef struct { + /** Information about the associated message digest */ + const md_info_t *md_info; + + /** Digest-specific context */ + void *md_ctx; +} md_context_t; + +#define MD_CONTEXT_T_INIT { \ + NULL, /* md_info */ \ + NULL, /* md_ctx */ \ +} + +/** + * \brief Returns the list of digests supported by the generic digest module. + * + * \return a statically allocated array of digests, the last entry + * is 0. + */ +const int *md_list( void ); + +/** + * \brief Returns the message digest information associated with the + * given digest name. + * + * \param md_name Name of the digest to search for. + * + * \return The message digest information associated with md_name or + * NULL if not found. + */ +const md_info_t *md_info_from_string( const char *md_name ); + +/** + * \brief Returns the message digest information associated with the + * given digest type. + * + * \param md_type type of digest to search for. + * + * \return The message digest information associated with md_type or + * NULL if not found. + */ +const md_info_t *md_info_from_type( md_type_t md_type ); + +/** + * \brief Initialize a md_context (as NONE) + */ +void md_init( md_context_t *ctx ); + +/** + * \brief Free and clear the message-specific context of ctx. + * Freeing ctx itself remains the responsibility of the + * caller. + */ +void md_free( md_context_t *ctx ); + +/** + * \brief Initialises and fills the message digest context structure + * with the appropriate values. + * + * \note Currently also clears structure. In future versions you + * will be required to call md_init() on the structure + * first. + * + * \param ctx context to initialise. May not be NULL. The + * digest-specific context (ctx->md_ctx) must be NULL. It will + * be allocated, and must be freed using md_free_ctx() later. + * \param md_info message digest to use. + * + * \returns \c 0 on success, \c POLARSSL_ERR_MD_BAD_INPUT_DATA on + * parameter failure, \c POLARSSL_ERR_MD_ALLOC_FAILED if + * allocation of the digest-specific context failed. + */ +int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ); + +/** + * \brief Free the message-specific context of ctx. Freeing ctx itself + * remains the responsibility of the caller. + * + * \note Deprecated: Redirects to md_free() + * + * \param ctx Free the message-specific context + * + * \returns 0 + */ +int md_free_ctx( md_context_t *ctx ); + +/** + * \brief Returns the size of the message digest output. + * + * \param md_info message digest info + * + * \return size of the message digest output. + */ +static inline unsigned char md_get_size( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( 0 ); + + return md_info->size; +} + +/** + * \brief Returns the type of the message digest output. + * + * \param md_info message digest info + * + * \return type of the message digest output. + */ +static inline md_type_t md_get_type( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( POLARSSL_MD_NONE ); + + return md_info->type; +} + +/** + * \brief Returns the name of the message digest output. + * + * \param md_info message digest info + * + * \return name of the message digest output. + */ +static inline const char *md_get_name( const md_info_t *md_info ) +{ + if( md_info == NULL ) + return( NULL ); + + return md_info->name; +} + +/** + * \brief Set-up the given context for a new message digest + * + * \param ctx generic message digest context. + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_starts( md_context_t *ctx ); + +/** + * \brief Generic message digest process buffer + * + * \param ctx Generic message digest context + * \param input buffer holding the datal + * \param ilen length of the input data + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief Generic message digest final digest + * + * \param ctx Generic message digest context + * \param output Generic message digest checksum result + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_finish( md_context_t *ctx, unsigned char *output ); + +/** + * \brief Output = message_digest( input buffer ) + * + * \param md_info message digest info + * \param input buffer holding the data + * \param ilen length of the input data + * \param output Generic message digest checksum result + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md( const md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ); + +/** + * \brief Output = message_digest( file contents ) + * + * \param md_info message digest info + * \param path input file name + * \param output generic message digest checksum result + * + * \return 0 if successful, POLARSSL_ERR_MD_FILE_OPEN_FAILED if fopen + * failed, POLARSSL_ERR_MD_FILE_READ_FAILED if fread failed, + * POLARSSL_ERR_MD_BAD_INPUT_DATA if md_info was NULL. + */ +int md_file( const md_info_t *md_info, const char *path, + unsigned char *output ); + +/** + * \brief Generic HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_hmac_starts( md_context_t *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief Generic HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_hmac_update( md_context_t *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief Generic HMAC final digest + * + * \param ctx HMAC context + * \param output Generic HMAC checksum result + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_hmac_finish( md_context_t *ctx, unsigned char *output); + +/** + * \brief Generic HMAC context reset + * + * \param ctx HMAC context to be reset + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_hmac_reset( md_context_t *ctx ); + +/** + * \brief Output = Generic_HMAC( hmac key, input buffer ) + * + * \param md_info message digest info + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output Generic HMAC-result + * + * \returns 0 on success, POLARSSL_ERR_MD_BAD_INPUT_DATA if parameter + * verification fails. + */ +int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ); + +/* Internal use */ +int md_process( md_context_t *ctx, const unsigned char *data ); + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_MD_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md2.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md2.h new file mode 100644 index 0000000..952b0bf --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md2.h @@ -0,0 +1,194 @@ +/** + * \file md2.h + * + * \brief MD2 message digest algorithm (hash function) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD2_H +#define POLARSSL_MD2_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#define POLARSSL_ERR_MD2_FILE_IO_ERROR -0x0070 /**< Read/write error in file. */ + +#if !defined(POLARSSL_MD2_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD2 context structure + */ +typedef struct +{ + unsigned char cksum[16]; /*!< checksum of the data block */ + unsigned char state[48]; /*!< intermediate digest state */ + unsigned char buffer[16]; /*!< data block being processed */ + + unsigned char ipad[16]; /*!< HMAC: inner padding */ + unsigned char opad[16]; /*!< HMAC: outer padding */ + size_t left; /*!< amount of data in buffer */ +} +md2_context; + +/** + * \brief Initialize MD2 context + * + * \param ctx MD2 context to be initialized + */ +void md2_init( md2_context *ctx ); + +/** + * \brief Clear MD2 context + * + * \param ctx MD2 context to be cleared + */ +void md2_free( md2_context *ctx ); + +/** + * \brief MD2 context setup + * + * \param ctx context to be initialized + */ +void md2_starts( md2_context *ctx ); + +/** + * \brief MD2 process buffer + * + * \param ctx MD2 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD2 final digest + * + * \param ctx MD2 context + * \param output MD2 checksum result + */ +void md2_finish( md2_context *ctx, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_MD2_ALT */ +#include "md2_alt.h" +#endif /* POLARSSL_MD2_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = MD2( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD2 checksum result + */ +void md2( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +/** + * \brief Output = MD2( file contents ) + * + * \param path input file name + * \param output MD2 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_MD2_FILE_IO_ERROR + */ +int md2_file( const char *path, unsigned char output[16] ); + +/** + * \brief MD2 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md2_hmac_starts( md2_context *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief MD2 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md2_hmac_update( md2_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief MD2 HMAC final digest + * + * \param ctx HMAC context + * \param output MD2 HMAC checksum result + */ +void md2_hmac_finish( md2_context *ctx, unsigned char output[16] ); + +/** + * \brief MD2 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void md2_hmac_reset( md2_context *ctx ); + +/** + * \brief Output = HMAC-MD2( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD2 result + */ +void md2_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md2_self_test( int verbose ); + +/* Internal use */ +void md2_process( md2_context *ctx ); + +#ifdef __cplusplus +} +#endif + +#endif /* md2.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md4.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md4.h new file mode 100644 index 0000000..fc5a5cd --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md4.h @@ -0,0 +1,200 @@ +/** + * \file md4.h + * + * \brief MD4 message digest algorithm (hash function) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD4_H +#define POLARSSL_MD4_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_MD4_FILE_IO_ERROR -0x0072 /**< Read/write error in file. */ + +#if !defined(POLARSSL_MD4_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD4 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +md4_context; + +/** + * \brief Initialize MD4 context + * + * \param ctx MD4 context to be initialized + */ +void md4_init( md4_context *ctx ); + +/** + * \brief Clear MD4 context + * + * \param ctx MD4 context to be cleared + */ +void md4_free( md4_context *ctx ); + +/** + * \brief MD4 context setup + * + * \param ctx context to be initialized + */ +void md4_starts( md4_context *ctx ); + +/** + * \brief MD4 process buffer + * + * \param ctx MD4 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD4 final digest + * + * \param ctx MD4 context + * \param output MD4 checksum result + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_MD4_ALT */ +#include "md4_alt.h" +#endif /* POLARSSL_MD4_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = MD4( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD4 checksum result + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +/** + * \brief Output = MD4( file contents ) + * + * \param path input file name + * \param output MD4 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_MD4_FILE_IO_ERROR + */ +int md4_file( const char *path, unsigned char output[16] ); + +/** + * \brief MD4 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md4_hmac_starts( md4_context *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief MD4 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md4_hmac_update( md4_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief MD4 HMAC final digest + * + * \param ctx HMAC context + * \param output MD4 HMAC checksum result + */ +void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ); + +/** + * \brief MD4 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void md4_hmac_reset( md4_context *ctx ); + +/** + * \brief Output = HMAC-MD4( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD4 result + */ +void md4_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md4_self_test( int verbose ); + +/* Internal use */ +void md4_process( md4_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#endif /* md4.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md5.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md5.h new file mode 100644 index 0000000..2f378f6 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md5.h @@ -0,0 +1,200 @@ +/** + * \file md5.h + * + * \brief MD5 message digest algorithm (hash function) + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD5_H +#define POLARSSL_MD5_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_MD5_FILE_IO_ERROR -0x0074 /**< Read/write error in file. */ + +#if !defined(POLARSSL_MD5_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief MD5 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[4]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +md5_context; + +/** + * \brief Initialize MD5 context + * + * \param ctx MD5 context to be initialized + */ +void md5_init( md5_context *ctx ); + +/** + * \brief Clear MD5 context + * + * \param ctx MD5 context to be cleared + */ +void md5_free( md5_context *ctx ); + +/** + * \brief MD5 context setup + * + * \param ctx context to be initialized + */ +void md5_starts( md5_context *ctx ); + +/** + * \brief MD5 process buffer + * + * \param ctx MD5 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief MD5 final digest + * + * \param ctx MD5 context + * \param output MD5 checksum result + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ); + +/* Internal use */ +void md5_process( md5_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_MD5_ALT */ +#include "md5_alt.h" +#endif /* POLARSSL_MD5_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = MD5( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output MD5 checksum result + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); + +/** + * \brief Output = MD5( file contents ) + * + * \param path input file name + * \param output MD5 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_MD5_FILE_IO_ERROR + */ +int md5_file( const char *path, unsigned char output[16] ); + +/** + * \brief MD5 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void md5_hmac_starts( md5_context *ctx, + const unsigned char *key, size_t keylen ); + +/** + * \brief MD5 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void md5_hmac_update( md5_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief MD5 HMAC final digest + * + * \param ctx HMAC context + * \param output MD5 HMAC checksum result + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ); + +/** + * \brief MD5 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void md5_hmac_reset( md5_context *ctx ); + +/** + * \brief Output = HMAC-MD5( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-MD5 result + */ +void md5_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int md5_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* md5.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md_wrap.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md_wrap.h new file mode 100644 index 0000000..eb1db0f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/md_wrap.h @@ -0,0 +1,71 @@ +/** + * \file md_wrap.h + * + * \brief Message digest wrappers. + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MD_WRAP_H +#define POLARSSL_MD_WRAP_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#include "md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(POLARSSL_MD2_C) +extern const md_info_t md2_info; +#endif +#if defined(POLARSSL_MD4_C) +extern const md_info_t md4_info; +#endif +#if defined(POLARSSL_MD5_C) +extern const md_info_t md5_info; +#endif +#if defined(POLARSSL_RIPEMD160_C) +extern const md_info_t ripemd160_info; +#endif +#if defined(POLARSSL_SHA1_C) +extern const md_info_t sha1_info; +#endif +#if defined(POLARSSL_SHA256_C) +extern const md_info_t sha224_info; +extern const md_info_t sha256_info; +#endif +#if defined(POLARSSL_SHA512_C) +extern const md_info_t sha384_info; +extern const md_info_t sha512_info; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_MD_WRAP_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory.h new file mode 100644 index 0000000..9b9cc62 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory.h @@ -0,0 +1,54 @@ +/** + * \file memory.h + * + * \brief Memory allocation layer (Deprecated to platform layer) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MEMORY_H +#define POLARSSL_MEMORY_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(POLARSSL_MEMORY_C) && !defined(POLARSSL_PLATFORM_MEMORY) +#define POLARSSL_PLATFORM_MEMORY +#endif + +#include "platform.h" +#include "memory_buffer_alloc.h" + +extern int platform_set_malloc_free( void * (*malloc_func)( size_t ), void (*free_func)( void * ) ); + +static int memory_set_own( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ) +{ + return platform_set_malloc_free( malloc_func, free_func ); +} + + +#endif /* memory.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory_buffer_alloc.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory_buffer_alloc.h new file mode 100644 index 0000000..c449752 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/memory_buffer_alloc.h @@ -0,0 +1,122 @@ +/** + * \file memory_buffer_alloc.h + * + * \brief Buffer-based memory allocator + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_MEMORY_BUFFER_ALLOC_H +#define POLARSSL_MEMORY_BUFFER_ALLOC_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_MEMORY_ALIGN_MULTIPLE) +#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ +#endif + +/* \} name SECTION: Module settings */ + +#define MEMORY_VERIFY_NONE 0 +#define MEMORY_VERIFY_ALLOC (1 << 0) +#define MEMORY_VERIFY_FREE (1 << 1) +#define MEMORY_VERIFY_ALWAYS (MEMORY_VERIFY_ALLOC | MEMORY_VERIFY_FREE) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initialize use of stack-based memory allocator. + * The stack-based allocator does memory management inside the + * presented buffer and does not call malloc() and free(). + * It sets the global polarssl_malloc() and polarssl_free() pointers + * to its own functions. + * (Provided polarssl_malloc() and polarssl_free() are thread-safe if + * POLARSSL_THREADING_C is defined) + * + * \note This code is not optimized and provides a straight-forward + * implementation of a stack-based memory allocator. + * + * \param buf buffer to use as heap + * \param len size of the buffer + * + * \return 0 if successful + */ +int memory_buffer_alloc_init( unsigned char *buf, size_t len ); + +/** + * \brief Free the mutex for thread-safety and clear remaining memory + */ +void memory_buffer_alloc_free( void ); + +/** + * \brief Determine when the allocator should automatically verify the state + * of the entire chain of headers / meta-data. + * (Default: MEMORY_VERIFY_NONE) + * + * \param verify One of MEMORY_VERIFY_NONE, MEMORY_VERIFY_ALLOC, + * MEMORY_VERIFY_FREE or MEMORY_VERIFY_ALWAYS + */ +void memory_buffer_set_verify( int verify ); + +#if defined(POLARSSL_MEMORY_DEBUG) +/** + * \brief Print out the status of the allocated memory (primarily for use + * after a program should have de-allocated all memory) + * Prints out a list of 'still allocated' blocks and their stack + * trace if POLARSSL_MEMORY_BACKTRACE is defined. + */ +void memory_buffer_alloc_status( void ); +#endif /* POLARSSL_MEMORY_DEBUG */ + +/** + * \brief Verifies that all headers in the memory buffer are correct + * and contain sane values. Helps debug buffer-overflow errors. + * + * Prints out first failure if POLARSSL_MEMORY_DEBUG is defined. + * Prints out full header information if POLARSSL_MEMORY_DEBUG_HEADERS + * is defined. (Includes stack trace information for each block if + * POLARSSL_MEMORY_BACKTRACE is defined as well). + * + * \returns 0 if verified, 1 otherwise + */ +int memory_buffer_alloc_verify( void ); + +#ifdef __cplusplus +} +#endif + +#endif /* memory_buffer_alloc.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/net.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/net.h new file mode 100644 index 0000000..22698b4 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/net.h @@ -0,0 +1,160 @@ +/** + * \file net.h + * + * \brief Network communication functions + * + * Copyright (C) 2006-2011, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_NET_H +#define POLARSSL_NET_H + +#include + +#define POLARSSL_ERR_NET_UNKNOWN_HOST -0x0056 /**< Failed to get an IP address for the given hostname. */ +#define POLARSSL_ERR_NET_SOCKET_FAILED -0x0042 /**< Failed to open a socket. */ +#define POLARSSL_ERR_NET_CONNECT_FAILED -0x0044 /**< The connection to the given server / port failed. */ +#define POLARSSL_ERR_NET_BIND_FAILED -0x0046 /**< Binding of the socket failed. */ +#define POLARSSL_ERR_NET_LISTEN_FAILED -0x0048 /**< Could not listen on the socket. */ +#define POLARSSL_ERR_NET_ACCEPT_FAILED -0x004A /**< Could not accept the incoming connection. */ +#define POLARSSL_ERR_NET_RECV_FAILED -0x004C /**< Reading information from the socket failed. */ +#define POLARSSL_ERR_NET_SEND_FAILED -0x004E /**< Sending information through the socket failed. */ +#define POLARSSL_ERR_NET_CONN_RESET -0x0050 /**< Connection was reset by peer. */ +#define POLARSSL_ERR_NET_WANT_READ -0x0052 /**< Connection requires a read call. */ +#define POLARSSL_ERR_NET_WANT_WRITE -0x0054 /**< Connection requires a write call. */ + +#define POLARSSL_NET_LISTEN_BACKLOG 10 /**< The backlog that listen() should use. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Initiate a TCP connection with host:port + * + * \param fd Socket to use + * \param host Host to connect to + * \param port Port to connect to + * + * \return 0 if successful, or one of: + * POLARSSL_ERR_NET_SOCKET_FAILED, + * POLARSSL_ERR_NET_UNKNOWN_HOST, + * POLARSSL_ERR_NET_CONNECT_FAILED + */ +int net_connect( int *fd, const char *host, int port ); + +/** + * \brief Create a listening socket on bind_ip:port. + * If bind_ip == NULL, all interfaces are binded. + * + * \param fd Socket to use + * \param bind_ip IP to bind to, can be NULL + * \param port Port number to use + * + * \return 0 if successful, or one of: + * POLARSSL_ERR_NET_SOCKET_FAILED, + * POLARSSL_ERR_NET_BIND_FAILED, + * POLARSSL_ERR_NET_LISTEN_FAILED + */ +int net_bind( int *fd, const char *bind_ip, int port ); + +/** + * \brief Accept a connection from a remote client + * + * \param bind_fd Relevant socket + * \param client_fd Will contain the connected client socket + * \param client_ip Will contain the client IP address + * Must be at least 4 bytes, or 16 if IPv6 is supported + * + * \return 0 if successful, POLARSSL_ERR_NET_ACCEPT_FAILED, or + * POLARSSL_ERR_NET_WANT_READ is bind_fd was set to + * non-blocking and accept() is blocking. + */ +int net_accept( int bind_fd, int *client_fd, void *client_ip ); + +/** + * \brief Set the socket blocking + * + * \param fd Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int net_set_block( int fd ); + +/** + * \brief Set the socket non-blocking + * + * \param fd Socket to set + * + * \return 0 if successful, or a non-zero error code + */ +int net_set_nonblock( int fd ); + +/** + * \brief Portable usleep helper + * + * \param usec Amount of microseconds to sleep + * + * \note Real amount of time slept will not be less than + * select()'s timeout granularity (typically, 10ms). + */ +void net_usleep( unsigned long usec ); + +/** + * \brief Read at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to write to + * \param len Maximum length of the buffer + * + * \return This function returns the number of bytes received, + * or a non-zero error code; POLARSSL_ERR_NET_WANT_READ + * indicates read() is blocking. + */ +int net_recv( void *ctx, unsigned char *buf, size_t len ); + +/** + * \brief Write at most 'len' characters. If no error occurs, + * the actual amount read is returned. + * + * \param ctx Socket + * \param buf The buffer to read from + * \param len The length of the buffer + * + * \return This function returns the number of bytes sent, + * or a non-zero error code; POLARSSL_ERR_NET_WANT_WRITE + * indicates write() is blocking. + */ +int net_send( void *ctx, const unsigned char *buf, size_t len ); + +/** + * \brief Gracefully shutdown the connection + * + * \param fd The socket to close + */ +void net_close( int fd ); + +#ifdef __cplusplus +} +#endif + +#endif /* net.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/oid.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/oid.h new file mode 100644 index 0000000..c4d5c3f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/oid.h @@ -0,0 +1,570 @@ +/** + * \file oid.h + * + * \brief Object Identifier (OID) database + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_OID_H +#define POLARSSL_OID_H + +#include +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#include "asn1.h" +#include "pk.h" +#if defined(POLARSSL_CIPHER_C) +#include "cipher.h" +#endif + +#if defined(POLARSSL_MD_C) +#include "md.h" +#endif + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +#include "x509.h" +#endif + +#define POLARSSL_ERR_OID_NOT_FOUND -0x002E /**< OID is not found. */ +#define POLARSSL_ERR_OID_BUF_TOO_SMALL -0x000B /**< output buffer is too small */ + +/* + * Top level OID tuples + */ +#define OID_ISO_MEMBER_BODIES "\x2a" /* {iso(1) member-body(2)} */ +#define OID_ISO_IDENTIFIED_ORG "\x2b" /* {iso(1) identified-organization(3)} */ +#define OID_ISO_CCITT_DS "\x55" /* {joint-iso-ccitt(2) ds(5)} */ +#define OID_ISO_ITU_COUNTRY "\x60" /* {joint-iso-itu-t(2) country(16)} */ + +/* + * ISO Member bodies OID parts + */ +#define OID_COUNTRY_US "\x86\x48" /* {us(840)} */ +#define OID_ORG_RSA_DATA_SECURITY "\x86\xf7\x0d" /* {rsadsi(113549)} */ +#define OID_RSA_COMPANY OID_ISO_MEMBER_BODIES OID_COUNTRY_US \ + OID_ORG_RSA_DATA_SECURITY /* {iso(1) member-body(2) us(840) rsadsi(113549)} */ +#define OID_ORG_ANSI_X9_62 "\xce\x3d" /* ansi-X9-62(10045) */ +#define OID_ANSI_X9_62 OID_ISO_MEMBER_BODIES OID_COUNTRY_US \ + OID_ORG_ANSI_X9_62 + +/* + * ISO Identified organization OID parts + */ +#define OID_ORG_DOD "\x06" /* {dod(6)} */ +#define OID_ORG_OIW "\x0e" +#define OID_OIW_SECSIG OID_ORG_OIW "\x03" +#define OID_OIW_SECSIG_ALG OID_OIW_SECSIG "\x02" +#define OID_OIW_SECSIG_SHA1 OID_OIW_SECSIG_ALG "\x1a" +#define OID_ORG_CERTICOM "\x81\x04" /* certicom(132) */ +#define OID_CERTICOM OID_ISO_IDENTIFIED_ORG OID_ORG_CERTICOM +#define OID_ORG_TELETRUST "\x24" /* teletrust(36) */ +#define OID_TELETRUST OID_ISO_IDENTIFIED_ORG OID_ORG_TELETRUST + +/* + * ISO ITU OID parts + */ +#define OID_ORGANIZATION "\x01" /* {organization(1)} */ +#define OID_ISO_ITU_US_ORG OID_ISO_ITU_COUNTRY OID_COUNTRY_US OID_ORGANIZATION /* {joint-iso-itu-t(2) country(16) us(840) organization(1)} */ + +#define OID_ORG_GOV "\x65" /* {gov(101)} */ +#define OID_GOV OID_ISO_ITU_US_ORG OID_ORG_GOV /* {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)} */ + +#define OID_ORG_NETSCAPE "\x86\xF8\x42" /* {netscape(113730)} */ +#define OID_NETSCAPE OID_ISO_ITU_US_ORG OID_ORG_NETSCAPE /* Netscape OID {joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730)} */ + +/* ISO arc for standard certificate and CRL extensions */ +#define OID_ID_CE OID_ISO_CCITT_DS "\x1D" /**< id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} */ + +/** + * Private Internet Extensions + * { iso(1) identified-organization(3) dod(6) internet(1) + * security(5) mechanisms(5) pkix(7) } + */ +#define OID_PKIX OID_ISO_IDENTIFIED_ORG OID_ORG_DOD "\x01\x05\x05\x07" + +/* + * Arc for standard naming attributes + */ +#define OID_AT OID_ISO_CCITT_DS "\x04" /**< id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4} */ +#define OID_AT_CN OID_AT "\x03" /**< id-at-commonName AttributeType:= {id-at 3} */ +#define OID_AT_SUR_NAME OID_AT "\x04" /**< id-at-surName AttributeType:= {id-at 4} */ +#define OID_AT_SERIAL_NUMBER OID_AT "\x05" /**< id-at-serialNumber AttributeType:= {id-at 5} */ +#define OID_AT_COUNTRY OID_AT "\x06" /**< id-at-countryName AttributeType:= {id-at 6} */ +#define OID_AT_LOCALITY OID_AT "\x07" /**< id-at-locality AttributeType:= {id-at 7} */ +#define OID_AT_STATE OID_AT "\x08" /**< id-at-state AttributeType:= {id-at 8} */ +#define OID_AT_ORGANIZATION OID_AT "\x0A" /**< id-at-organizationName AttributeType:= {id-at 10} */ +#define OID_AT_ORG_UNIT OID_AT "\x0B" /**< id-at-organizationalUnitName AttributeType:= {id-at 11} */ +#define OID_AT_TITLE OID_AT "\x0C" /**< id-at-title AttributeType:= {id-at 12} */ +#define OID_AT_POSTAL_ADDRESS OID_AT "\x10" /**< id-at-postalAddress AttributeType:= {id-at 16} */ +#define OID_AT_POSTAL_CODE OID_AT "\x11" /**< id-at-postalCode AttributeType:= {id-at 17} */ +#define OID_AT_GIVEN_NAME OID_AT "\x2A" /**< id-at-givenName AttributeType:= {id-at 42} */ +#define OID_AT_INITIALS OID_AT "\x2B" /**< id-at-initials AttributeType:= {id-at 43} */ +#define OID_AT_GENERATION_QUALIFIER OID_AT "\x2C" /**< id-at-generationQualifier AttributeType:= {id-at 44} */ +#define OID_AT_DN_QUALIFIER OID_AT "\x2E" /**< id-at-dnQualifier AttributeType:= {id-at 46} */ +#define OID_AT_PSEUDONYM OID_AT "\x41" /**< id-at-pseudonym AttributeType:= {id-at 65} */ + +#define OID_DOMAIN_COMPONENT "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19" /** id-domainComponent AttributeType:= {itu-t(0) data(9) pss(2342) ucl(19200300) pilot(100) pilotAttributeType(1) domainComponent(25)} */ + +/* + * OIDs for standard certificate extensions + */ +#define OID_AUTHORITY_KEY_IDENTIFIER OID_ID_CE "\x23" /**< id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } */ +#define OID_SUBJECT_KEY_IDENTIFIER OID_ID_CE "\x0E" /**< id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } */ +#define OID_KEY_USAGE OID_ID_CE "\x0F" /**< id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } */ +#define OID_CERTIFICATE_POLICIES OID_ID_CE "\x20" /**< id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } */ +#define OID_POLICY_MAPPINGS OID_ID_CE "\x21" /**< id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } */ +#define OID_SUBJECT_ALT_NAME OID_ID_CE "\x11" /**< id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } */ +#define OID_ISSUER_ALT_NAME OID_ID_CE "\x12" /**< id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } */ +#define OID_SUBJECT_DIRECTORY_ATTRS OID_ID_CE "\x09" /**< id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } */ +#define OID_BASIC_CONSTRAINTS OID_ID_CE "\x13" /**< id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } */ +#define OID_NAME_CONSTRAINTS OID_ID_CE "\x1E" /**< id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } */ +#define OID_POLICY_CONSTRAINTS OID_ID_CE "\x24" /**< id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } */ +#define OID_EXTENDED_KEY_USAGE OID_ID_CE "\x25" /**< id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } */ +#define OID_CRL_DISTRIBUTION_POINTS OID_ID_CE "\x1F" /**< id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } */ +#define OID_INIHIBIT_ANYPOLICY OID_ID_CE "\x36" /**< id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } */ +#define OID_FRESHEST_CRL OID_ID_CE "\x2E" /**< id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } */ + +/* + * Netscape certificate extensions + */ +#define OID_NS_CERT OID_NETSCAPE "\x01" +#define OID_NS_CERT_TYPE OID_NS_CERT "\x01" +#define OID_NS_BASE_URL OID_NS_CERT "\x02" +#define OID_NS_REVOCATION_URL OID_NS_CERT "\x03" +#define OID_NS_CA_REVOCATION_URL OID_NS_CERT "\x04" +#define OID_NS_RENEWAL_URL OID_NS_CERT "\x07" +#define OID_NS_CA_POLICY_URL OID_NS_CERT "\x08" +#define OID_NS_SSL_SERVER_NAME OID_NS_CERT "\x0C" +#define OID_NS_COMMENT OID_NS_CERT "\x0D" +#define OID_NS_DATA_TYPE OID_NETSCAPE "\x02" +#define OID_NS_CERT_SEQUENCE OID_NS_DATA_TYPE "\x05" + +/* + * OIDs for CRL extensions + */ +#define OID_PRIVATE_KEY_USAGE_PERIOD OID_ID_CE "\x10" +#define OID_CRL_NUMBER OID_ID_CE "\x14" /**< id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } */ + +/* + * X.509 v3 Extended key usage OIDs + */ +#define OID_ANY_EXTENDED_KEY_USAGE OID_EXTENDED_KEY_USAGE "\x00" /**< anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } */ + +#define OID_KP OID_PKIX "\x03" /**< id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } */ +#define OID_SERVER_AUTH OID_KP "\x01" /**< id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } */ +#define OID_CLIENT_AUTH OID_KP "\x02" /**< id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } */ +#define OID_CODE_SIGNING OID_KP "\x03" /**< id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } */ +#define OID_EMAIL_PROTECTION OID_KP "\x04" /**< id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } */ +#define OID_TIME_STAMPING OID_KP "\x08" /**< id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } */ +#define OID_OCSP_SIGNING OID_KP "\x09" /**< id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } */ + +/* + * PKCS definition OIDs + */ + +#define OID_PKCS OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */ +#define OID_PKCS1 OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */ +#define OID_PKCS5 OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */ +#define OID_PKCS9 OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */ +#define OID_PKCS12 OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */ + +/* + * PKCS#1 OIDs + */ +#define OID_PKCS1_RSA OID_PKCS1 "\x01" /**< rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 } */ +#define OID_PKCS1_MD2 OID_PKCS1 "\x02" /**< md2WithRSAEncryption ::= { pkcs-1 2 } */ +#define OID_PKCS1_MD4 OID_PKCS1 "\x03" /**< md4WithRSAEncryption ::= { pkcs-1 3 } */ +#define OID_PKCS1_MD5 OID_PKCS1 "\x04" /**< md5WithRSAEncryption ::= { pkcs-1 4 } */ +#define OID_PKCS1_SHA1 OID_PKCS1 "\x05" /**< sha1WithRSAEncryption ::= { pkcs-1 5 } */ +#define OID_PKCS1_SHA224 OID_PKCS1 "\x0e" /**< sha224WithRSAEncryption ::= { pkcs-1 14 } */ +#define OID_PKCS1_SHA256 OID_PKCS1 "\x0b" /**< sha256WithRSAEncryption ::= { pkcs-1 11 } */ +#define OID_PKCS1_SHA384 OID_PKCS1 "\x0c" /**< sha384WithRSAEncryption ::= { pkcs-1 12 } */ +#define OID_PKCS1_SHA512 OID_PKCS1 "\x0d" /**< sha512WithRSAEncryption ::= { pkcs-1 13 } */ + +#define OID_RSA_SHA_OBS "\x2B\x0E\x03\x02\x1D" + +#define OID_PKCS9_EMAIL OID_PKCS9 "\x01" /**< emailAddress AttributeType ::= { pkcs-9 1 } */ + +/* RFC 4055 */ +#define OID_RSASSA_PSS OID_PKCS1 "\x0a" /**< id-RSASSA-PSS ::= { pkcs-1 10 } */ +#define OID_MGF1 OID_PKCS1 "\x08" /**< id-mgf1 ::= { pkcs-1 8 } */ + +/* + * Digest algorithms + */ +#define OID_DIGEST_ALG_MD2 OID_RSA_COMPANY "\x02\x02" /**< id-md2 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } */ +#define OID_DIGEST_ALG_MD4 OID_RSA_COMPANY "\x02\x04" /**< id-md4 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 4 } */ +#define OID_DIGEST_ALG_MD5 OID_RSA_COMPANY "\x02\x05" /**< id-md5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } */ +#define OID_DIGEST_ALG_SHA1 OID_ISO_IDENTIFIED_ORG OID_OIW_SECSIG_SHA1 /**< id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 } */ +#define OID_DIGEST_ALG_SHA224 OID_GOV "\x03\x04\x02\x04" /**< id-sha224 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 4 } */ +#define OID_DIGEST_ALG_SHA256 OID_GOV "\x03\x04\x02\x01" /**< id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 } */ + +#define OID_DIGEST_ALG_SHA384 OID_GOV "\x03\x04\x02\x02" /**< id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 2 } */ + +#define OID_DIGEST_ALG_SHA512 OID_GOV "\x03\x04\x02\x03" /**< id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 } */ + +#define OID_HMAC_SHA1 OID_RSA_COMPANY "\x02\x07" /**< id-hmacWithSHA1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 7 } */ + +/* + * Encryption algorithms + */ +#define OID_DES_CBC OID_ISO_IDENTIFIED_ORG OID_OIW_SECSIG_ALG "\x07" /**< desCBC OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 7 } */ +#define OID_DES_EDE3_CBC OID_RSA_COMPANY "\x03\x07" /**< des-ede3-cbc OBJECT IDENTIFIER ::= { iso(1) member-body(2) -- us(840) rsadsi(113549) encryptionAlgorithm(3) 7 } */ + +/* + * PKCS#5 OIDs + */ +#define OID_PKCS5_PBKDF2 OID_PKCS5 "\x0c" /**< id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12} */ +#define OID_PKCS5_PBES2 OID_PKCS5 "\x0d" /**< id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13} */ +#define OID_PKCS5_PBMAC1 OID_PKCS5 "\x0e" /**< id-PBMAC1 OBJECT IDENTIFIER ::= {pkcs-5 14} */ + +/* + * PKCS#5 PBES1 algorithms + */ +#define OID_PKCS5_PBE_MD2_DES_CBC OID_PKCS5 "\x01" /**< pbeWithMD2AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 1} */ +#define OID_PKCS5_PBE_MD2_RC2_CBC OID_PKCS5 "\x04" /**< pbeWithMD2AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 4} */ +#define OID_PKCS5_PBE_MD5_DES_CBC OID_PKCS5 "\x03" /**< pbeWithMD5AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 3} */ +#define OID_PKCS5_PBE_MD5_RC2_CBC OID_PKCS5 "\x06" /**< pbeWithMD5AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 6} */ +#define OID_PKCS5_PBE_SHA1_DES_CBC OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */ +#define OID_PKCS5_PBE_SHA1_RC2_CBC OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */ + +/* + * PKCS#8 OIDs + */ +#define OID_PKCS9_CSR_EXT_REQ OID_PKCS9 "\x0e" /**< extensionRequest OBJECT IDENTIFIER ::= {pkcs-9 14} */ + +/* + * PKCS#12 PBE OIDs + */ +#define OID_PKCS12_PBE OID_PKCS12 "\x01" /**< pkcs-12PbeIds OBJECT IDENTIFIER ::= {pkcs-12 1} */ + +#define OID_PKCS12_PBE_SHA1_RC4_128 OID_PKCS12_PBE "\x01" /**< pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1} */ +#define OID_PKCS12_PBE_SHA1_RC4_40 OID_PKCS12_PBE "\x02" /**< pbeWithSHAAnd40BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 2} */ +#define OID_PKCS12_PBE_SHA1_DES3_EDE_CBC OID_PKCS12_PBE "\x03" /**< pbeWithSHAAnd3-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 3} */ +#define OID_PKCS12_PBE_SHA1_DES2_EDE_CBC OID_PKCS12_PBE "\x04" /**< pbeWithSHAAnd2-KeyTripleDES-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 4} */ +#define OID_PKCS12_PBE_SHA1_RC2_128_CBC OID_PKCS12_PBE "\x05" /**< pbeWithSHAAnd128BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 5} */ +#define OID_PKCS12_PBE_SHA1_RC2_40_CBC OID_PKCS12_PBE "\x06" /**< pbeWithSHAAnd40BitRC2-CBC OBJECT IDENTIFIER ::= {pkcs-12PbeIds 6} */ + +/* + * EC key algorithms from RFC 5480 + */ + +/* id-ecPublicKey OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 } */ +#define OID_EC_ALG_UNRESTRICTED OID_ANSI_X9_62 "\x02\01" + +/* id-ecDH OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) + * schemes(1) ecdh(12) } */ +#define OID_EC_ALG_ECDH OID_CERTICOM "\x01\x0c" + +/* + * ECParameters namedCurve identifiers, from RFC 5480, RFC 5639, and SEC2 + */ + +/* secp192r1 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 1 } */ +#define OID_EC_GRP_SECP192R1 OID_ANSI_X9_62 "\x03\x01\x01" + +/* secp224r1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 33 } */ +#define OID_EC_GRP_SECP224R1 OID_CERTICOM "\x00\x21" + +/* secp256r1 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3) prime(1) 7 } */ +#define OID_EC_GRP_SECP256R1 OID_ANSI_X9_62 "\x03\x01\x07" + +/* secp384r1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 34 } */ +#define OID_EC_GRP_SECP384R1 OID_CERTICOM "\x00\x22" + +/* secp521r1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 35 } */ +#define OID_EC_GRP_SECP521R1 OID_CERTICOM "\x00\x23" + +/* secp192k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 31 } */ +#define OID_EC_GRP_SECP192K1 OID_CERTICOM "\x00\x1f" + +/* secp224k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 32 } */ +#define OID_EC_GRP_SECP224K1 OID_CERTICOM "\x00\x20" + +/* secp256k1 OBJECT IDENTIFIER ::= { + * iso(1) identified-organization(3) certicom(132) curve(0) 10 } */ +#define OID_EC_GRP_SECP256K1 OID_CERTICOM "\x00\x0a" + +/* RFC 5639 4.1 + * ecStdCurvesAndGeneration OBJECT IDENTIFIER::= {iso(1) + * identified-organization(3) teletrust(36) algorithm(3) signature- + * algorithm(3) ecSign(2) 8} + * ellipticCurve OBJECT IDENTIFIER ::= {ecStdCurvesAndGeneration 1} + * versionOne OBJECT IDENTIFIER ::= {ellipticCurve 1} */ +#define OID_EC_BRAINPOOL_V1 OID_TELETRUST "\x03\x03\x02\x08\x01\x01" + +/* brainpoolP256r1 OBJECT IDENTIFIER ::= {versionOne 7} */ +#define OID_EC_GRP_BP256R1 OID_EC_BRAINPOOL_V1 "\x07" + +/* brainpoolP384r1 OBJECT IDENTIFIER ::= {versionOne 11} */ +#define OID_EC_GRP_BP384R1 OID_EC_BRAINPOOL_V1 "\x0B" + +/* brainpoolP512r1 OBJECT IDENTIFIER ::= {versionOne 13} */ +#define OID_EC_GRP_BP512R1 OID_EC_BRAINPOOL_V1 "\x0D" + +/* + * SEC1 C.1 + * + * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + * id-fieldType OBJECT IDENTIFIER ::= { ansi-X9-62 fieldType(1)} + */ +#define OID_ANSI_X9_62_FIELD_TYPE OID_ANSI_X9_62 "\x01" +#define OID_ANSI_X9_62_PRIME_FIELD OID_ANSI_X9_62_FIELD_TYPE "\x01" + +/* + * ECDSA signature identifiers, from RFC 5480 + */ +#define OID_ANSI_X9_62_SIG OID_ANSI_X9_62 "\x04" /* signatures(4) */ +#define OID_ANSI_X9_62_SIG_SHA2 OID_ANSI_X9_62_SIG "\x03" /* ecdsa-with-SHA2(3) */ + +/* ecdsa-with-SHA1 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 } */ +#define OID_ECDSA_SHA1 OID_ANSI_X9_62_SIG "\x01" + +/* ecdsa-with-SHA224 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 1 } */ +#define OID_ECDSA_SHA224 OID_ANSI_X9_62_SIG_SHA2 "\x01" + +/* ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 2 } */ +#define OID_ECDSA_SHA256 OID_ANSI_X9_62_SIG_SHA2 "\x02" + +/* ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 3 } */ +#define OID_ECDSA_SHA384 OID_ANSI_X9_62_SIG_SHA2 "\x03" + +/* ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) + * ecdsa-with-SHA2(3) 4 } */ +#define OID_ECDSA_SHA512 OID_ANSI_X9_62_SIG_SHA2 "\x04" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Base OID descriptor structure + */ +typedef struct { + const char *asn1; /*!< OID ASN.1 representation */ + size_t asn1_len; /*!< length of asn1 */ + const char *name; /*!< official name (e.g. from RFC) */ + const char *description; /*!< human friendly description */ +} oid_descriptor_t; + +/** + * \brief Translate an ASN.1 OID into its numeric representation + * (e.g. "\x2A\x86\x48\x86\xF7\x0D" into "1.2.840.113549") + * + * \param buf buffer to put representation in + * \param size size of the buffer + * \param oid OID to translate + * + * \return Length of the string written (excluding final NULL) or + * POLARSSL_ERR_OID_BUF_TO_SMALL in case of error + */ +int oid_get_numeric_string( char *buf, size_t size, const asn1_buf *oid ); + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +/** + * \brief Translate an X.509 extension OID into local values + * + * \param oid OID to use + * \param ext_type place to store the extension type + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_x509_ext_type( const asn1_buf *oid, int *ext_type ); +#endif + +/** + * \brief Translate an X.509 attribute type OID into the short name + * (e.g. the OID for an X520 Common Name into "CN") + * + * \param oid OID to use + * \param short_name place to store the string pointer + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_attr_short_name( const asn1_buf *oid, const char **short_name ); + +/** + * \brief Translate PublicKeyAlgorithm OID into pk_type + * + * \param oid OID to use + * \param pk_alg place to store public key algorithm + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg ); + +/** + * \brief Translate pk_type into PublicKeyAlgorithm OID + * + * \param pk_alg Public key type to look for + * \param oid place to store ASN.1 OID string pointer + * \param olen length of the OID + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_oid_by_pk_alg( pk_type_t pk_alg, + const char **oid, size_t *olen ); + +#if defined(POLARSSL_ECP_C) +/** + * \brief Translate NamedCurve OID into an EC group identifier + * + * \param oid OID to use + * \param grp_id place to store group id + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_ec_grp( const asn1_buf *oid, ecp_group_id *grp_id ); + +/** + * \brief Translate EC group identifier into NamedCurve OID + * + * \param grp_id EC group identifier + * \param oid place to store ASN.1 OID string pointer + * \param olen length of the OID + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_oid_by_ec_grp( ecp_group_id grp_id, + const char **oid, size_t *olen ); +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_MD_C) +/** + * \brief Translate SignatureAlgorithm OID into md_type and pk_type + * + * \param oid OID to use + * \param md_alg place to store message digest algorithm + * \param pk_alg place to store public key algorithm + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_sig_alg( const asn1_buf *oid, + md_type_t *md_alg, pk_type_t *pk_alg ); + +/** + * \brief Translate SignatureAlgorithm OID into description + * + * \param oid OID to use + * \param desc place to store string pointer + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_sig_alg_desc( const asn1_buf *oid, const char **desc ); + +/** + * \brief Translate md_type and pk_type into SignatureAlgorithm OID + * + * \param md_alg message digest algorithm + * \param pk_alg public key algorithm + * \param oid place to store ASN.1 OID string pointer + * \param olen length of the OID + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_oid_by_sig_alg( pk_type_t pk_alg, md_type_t md_alg, + const char **oid, size_t *olen ); + +/** + * \brief Translate hash algorithm OID into md_type + * + * \param oid OID to use + * \param md_alg place to store message digest algorithm + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_md_alg( const asn1_buf *oid, md_type_t *md_alg ); +#endif /* POLARSSL_MD_C */ + +/** + * \brief Translate Extended Key Usage OID into description + * + * \param oid OID to use + * \param desc place to store string pointer + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_extended_key_usage( const asn1_buf *oid, const char **desc ); + +/** + * \brief Translate md_type into hash algorithm OID + * + * \param md_alg message digest algorithm + * \param oid place to store ASN.1 OID string pointer + * \param olen length of the OID + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_oid_by_md( md_type_t md_alg, const char **oid, size_t *olen ); + +#if defined(POLARSSL_CIPHER_C) +/** + * \brief Translate encryption algorithm OID into cipher_type + * + * \param oid OID to use + * \param cipher_alg place to store cipher algorithm + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_cipher_alg( const asn1_buf *oid, cipher_type_t *cipher_alg ); +#endif /* POLARSSL_CIPHER_C */ + +#if defined(POLARSSL_PKCS12_C) +/** + * \brief Translate PKCS#12 PBE algorithm OID into md_type and + * cipher_type + * + * \param oid OID to use + * \param md_alg place to store message digest algorithm + * \param cipher_alg place to store cipher algorithm + * + * \return 0 if successful, or POLARSSL_ERR_OID_NOT_FOUND + */ +int oid_get_pkcs12_pbe_alg( const asn1_buf *oid, md_type_t *md_alg, + cipher_type_t *cipher_alg ); +#endif /* POLARSSL_PKCS12_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* oid.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/openssl.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/openssl.h new file mode 100644 index 0000000..b77e7da --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/openssl.h @@ -0,0 +1,140 @@ +/** + * \file openssl.h + * + * \brief OpenSSL wrapper (definitions, inline functions). + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * OpenSSL wrapper contributed by David Barett + */ +#ifndef POLARSSL_OPENSSL_H +#define POLARSSL_OPENSSL_H + +#include "aes.h" +#include "md5.h" +#include "rsa.h" +#include "sha1.h" + +#define AES_SIZE 16 +#define AES_BLOCK_SIZE 16 +#define AES_KEY aes_context +#define MD5_CTX md5_context +#define SHA_CTX sha1_context + +#define SHA1_Init( CTX ) \ + sha1_starts( (CTX) ) +#define SHA1_Update( CTX, BUF, LEN ) \ + sha1_update( (CTX), (unsigned char *)(BUF), (LEN) ) +#define SHA1_Final( OUT, CTX ) \ + sha1_finish( (CTX), (OUT) ) + +#define MD5_Init( CTX ) \ + md5_starts( (CTX) ) +#define MD5_Update( CTX, BUF, LEN ) \ + md5_update( (CTX), (unsigned char *)(BUF), (LEN) ) +#define MD5_Final( OUT, CTX ) \ + md5_finish( (CTX), (OUT) ) + +#define AES_set_encrypt_key( KEY, KEYSIZE, CTX ) \ + aes_setkey_enc( (CTX), (KEY), (KEYSIZE) ) +#define AES_set_decrypt_key( KEY, KEYSIZE, CTX ) \ + aes_setkey_dec( (CTX), (KEY), (KEYSIZE) ) +#define AES_cbc_encrypt( INPUT, OUTPUT, LEN, CTX, IV, MODE ) \ + aes_crypt_cbc( (CTX), (MODE), (LEN), (IV), (INPUT), (OUTPUT) ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * RSA stuff follows. TODO: needs cleanup + */ +inline int __RSA_Passthrough( void *output, void *input, int size ) +{ + memcpy( output, input, size ); + return size; +} + +inline rsa_context* d2i_RSA_PUBKEY( void *ignore, unsigned char **bufptr, + int len ) +{ + unsigned char *buffer = *(unsigned char **) bufptr; + rsa_context *rsa; + + /* + * Not a general-purpose parser: only parses public key from *exactly* + * openssl genrsa -out privkey.pem 512 (or 1024) + * openssl rsa -in privkey.pem -out privatekey.der -outform der + * openssl rsa -in privkey.pem -out pubkey.der -outform der -pubout + * + * TODO: make a general-purpose parse + */ + if( ignore != 0 || ( len != 94 && len != 162 ) ) + return( 0 ); + + rsa = (rsa_context *) malloc( sizeof( rsa_rsa ) ); + if( rsa == NULL ) + return( 0 ); + + memset( rsa, 0, sizeof( rsa_context ) ); + + if( ( len == 94 && + mpi_read_binary( &rsa->N, &buffer[ 25], 64 ) == 0 && + mpi_read_binary( &rsa->E, &buffer[ 91], 3 ) == 0 ) || + ( len == 162 && + mpi_read_binary( &rsa->N, &buffer[ 29], 128 ) == 0 ) && + mpi_read_binary( &rsa->E, &buffer[159], 3 ) == 0 ) + { + /* + * key read successfully + */ + rsa->len = ( mpi_msb( &rsa->N ) + 7 ) >> 3; + return( rsa ); + } + else + { + memset( rsa, 0, sizeof( rsa_context ) ); + free( rsa ); + return( 0 ); + } +} + +#define RSA rsa_context +#define RSA_PKCS1_PADDING 1 /* ignored; always encrypt with this */ +#define RSA_size( CTX ) (CTX)->len +#define RSA_free( CTX ) rsa_free( CTX ) +#define ERR_get_error( ) "ERR_get_error() not supported" +#define RSA_blinding_off( IGNORE ) + +#define d2i_RSAPrivateKey( a, b, c ) new rsa_context /* TODO: C++ bleh */ + +inline int RSA_public_decrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PUBLIC, &outsize, input, output ) ) return outsize; else return -1; } +inline int RSA_private_decrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { int outsize=size; if( !rsa_pkcs1_decrypt( key, RSA_PRIVATE, &outsize, input, output ) ) return outsize; else return -1; } +inline int RSA_public_encrypt ( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PUBLIC, size, input, output ) ) return RSA_size(key); else return -1; } +inline int RSA_private_encrypt( int size, unsigned char* input, unsigned char* output, RSA* key, int ignore ) { if( !rsa_pkcs1_encrypt( key, RSA_PRIVATE, size, input, output ) ) return RSA_size(key); else return -1; } + +#ifdef __cplusplus +} +#endif + +#endif /* openssl.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/padlock.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/padlock.h new file mode 100644 index 0000000..3c5f725 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/padlock.h @@ -0,0 +1,109 @@ +/** + * \file padlock.h + * + * \brief VIA PadLock ACE for HW encryption/decryption supported by some + * processors + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PADLOCK_H +#define POLARSSL_PADLOCK_H + +#include "aes.h" + +#define POLARSSL_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ + +#if defined(POLARSSL_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) + +#ifndef POLARSSL_HAVE_X86 +#define POLARSSL_HAVE_X86 +#endif + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef INT32 int32_t; +#else +#include +#endif + + +#define PADLOCK_RNG 0x000C +#define PADLOCK_ACE 0x00C0 +#define PADLOCK_PHE 0x0C00 +#define PADLOCK_PMM 0x3000 + +#define PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15)) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief PadLock detection routine + * + * \param feature The feature to detect + * + * \return 1 if CPU has support for the feature, 0 otherwise + */ +int padlock_supports( int feature ); + +/** + * \brief PadLock AES-ECB block en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if success, 1 if operation failed + */ +int padlock_xcryptecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + +/** + * \brief PadLock AES-CBC buffer en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if success, 1 if operation failed + */ +int padlock_xcryptcbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ); + +#ifdef __cplusplus +} +#endif + +#endif /* HAVE_X86 */ + +#endif /* padlock.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pbkdf2.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pbkdf2.h new file mode 100644 index 0000000..5ccb2fa --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pbkdf2.h @@ -0,0 +1,82 @@ +/** + * \file pbkdf2.h + * + * \brief Password-Based Key Derivation Function 2 (from PKCS#5) + * DEPRECATED: use pkcs5.h instead. + * + * \author Mathias Olsson + * + * Copyright (C) 2006-2012, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PBKDF2_H +#define POLARSSL_PBKDF2_H + +#include + +#include "md.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA -0x007C /**< Bad input parameters to function. */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief PKCS#5 PBKDF2 using HMAC + * DEPRECATED: Use pkcs5_pbkdf2_hmac() instead! + * + * \param ctx Generic HMAC context + * \param password Password to use when generating key + * \param plen Length of password + * \param salt Salt to use when generating key + * \param slen Length of salt + * \param iteration_count Iteration count + * \param key_length Length of generated key + * \param output Generated key. Must be at least as big as key_length + * + * \returns 0 on success, or a PolarSSL error code if verification fails. + */ +int pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, + size_t plen, const unsigned char *salt, size_t slen, + unsigned int iteration_count, + uint32_t key_length, unsigned char *output ); + +/** + * \brief Checkup routine + * DEPRECATED: Use pkcs5_self_test() instead! + * + * \return 0 if successful, or 1 if the test failed + */ +int pbkdf2_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* pbkdf2.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pem.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pem.h new file mode 100644 index 0000000..e606cf0 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pem.h @@ -0,0 +1,133 @@ +/** + * \file pem.h + * + * \brief Privacy Enhanced Mail (PEM) decoding + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PEM_H +#define POLARSSL_PEM_H + +#include + +/** + * \name PEM Error codes + * These error codes are returned in case of errors reading the + * PEM data. + * \{ + */ +#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT -0x1080 /**< No PEM header or footer found. */ +#define POLARSSL_ERR_PEM_INVALID_DATA -0x1100 /**< PEM string is not as expected. */ +#define POLARSSL_ERR_PEM_MALLOC_FAILED -0x1180 /**< Failed to allocate memory. */ +#define POLARSSL_ERR_PEM_INVALID_ENC_IV -0x1200 /**< RSA IV is not in hex-format. */ +#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG -0x1280 /**< Unsupported key encryption algorithm. */ +#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED -0x1300 /**< Private key password can't be empty. */ +#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH -0x1380 /**< Given private key password does not allow for correct decryption. */ +#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE -0x1400 /**< Unavailable feature, e.g. hashing/encryption combination. */ +#define POLARSSL_ERR_PEM_BAD_INPUT_DATA -0x1480 /**< Bad input parameters to function. */ +/* \} name */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(POLARSSL_PEM_PARSE_C) +/** + * \brief PEM context structure + */ +typedef struct +{ + unsigned char *buf; /*!< buffer for decoded data */ + size_t buflen; /*!< length of the buffer */ + unsigned char *info; /*!< buffer for extra header information */ +} +pem_context; + +/** + * \brief PEM context setup + * + * \param ctx context to be initialized + */ +void pem_init( pem_context *ctx ); + +/** + * \brief Read a buffer for PEM information and store the resulting + * data into the specified context buffers. + * + * \param ctx context to use + * \param header header string to seek and expect + * \param footer footer string to seek and expect + * \param data source data to look in + * \param pwd password for decryption (can be NULL) + * \param pwdlen length of password + * \param use_len destination for total length used (set after header is + * correctly read, so unless you get + * POLARSSL_ERR_PEM_BAD_INPUT_DATA or + * POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT, use_len is + * the length to skip) + * + * \note Attempts to check password correctness by verifying if + * the decrypted text starts with an ASN.1 sequence of + * appropriate length + * + * \return 0 on success, or a specific PEM error code + */ +int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, + const unsigned char *data, + const unsigned char *pwd, + size_t pwdlen, size_t *use_len ); + +/** + * \brief PEM context memory freeing + * + * \param ctx context to be freed + */ +void pem_free( pem_context *ctx ); +#endif /* POLARSSL_PEM_PARSE_C */ + +#if defined(POLARSSL_PEM_WRITE_C) +/** + * \brief Write a buffer of PEM information from a DER encoded + * buffer. + * + * \param header header string to write + * \param footer footer string to write + * \param der_data DER data to write + * \param der_len length of the DER data + * \param buf buffer to write to + * \param buf_len length of output buffer + * \param olen total length written / required (if buf_len is not enough) + * + * \return 0 on success, or a specific PEM or BASE64 error code. On + * POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL olen is the required + * size. + */ +int pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ); +#endif /* POLARSSL_PEM_WRITE_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* pem.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk.h new file mode 100644 index 0000000..754dda2 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk.h @@ -0,0 +1,632 @@ +/** + * \file pk.h + * + * \brief Public Key abstraction layer + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef POLARSSL_PK_H +#define POLARSSL_PK_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "md.h" + +#if defined(POLARSSL_RSA_C) +#include "rsa.h" +#endif + +#if defined(POLARSSL_ECP_C) +#include "ecp.h" +#endif + +#if defined(POLARSSL_ECDSA_C) +#include "ecdsa.h" +#endif + +#define POLARSSL_ERR_PK_MALLOC_FAILED -0x2F80 /**< Memory alloation failed. */ +#define POLARSSL_ERR_PK_TYPE_MISMATCH -0x2F00 /**< Type mismatch, eg attempt to encrypt with an ECDSA key */ +#define POLARSSL_ERR_PK_BAD_INPUT_DATA -0x2E80 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_PK_FILE_IO_ERROR -0x2E00 /**< Read/write of file failed. */ +#define POLARSSL_ERR_PK_KEY_INVALID_VERSION -0x2D80 /**< Unsupported key version */ +#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT -0x2D00 /**< Invalid key tag or value. */ +#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG -0x2C80 /**< Key algorithm is unsupported (only RSA and EC are supported). */ +#define POLARSSL_ERR_PK_PASSWORD_REQUIRED -0x2C00 /**< Private key password can't be empty. */ +#define POLARSSL_ERR_PK_PASSWORD_MISMATCH -0x2B80 /**< Given private key password does not allow for correct decryption. */ +#define POLARSSL_ERR_PK_INVALID_PUBKEY -0x2B00 /**< The pubkey tag or value is invalid (only RSA and EC are supported). */ +#define POLARSSL_ERR_PK_INVALID_ALG -0x2A80 /**< The algorithm tag or value is invalid. */ +#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE -0x2A00 /**< Elliptic curve is unsupported (only NIST curves are supported). */ +#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE -0x2980 /**< Unavailable feature, e.g. RSA disabled for RSA key. */ +#define POLARSSL_ERR_PK_SIG_LEN_MISMATCH -0x2000 /**< The signature is valid but its length is less than expected. */ + + +#if defined(POLARSSL_RSA_C) +/** + * Quick access to an RSA context inside a PK context. + * + * \warning You must make sure the PK context actually holds an RSA context + * before using this macro! + */ +#define pk_rsa( pk ) ( (rsa_context *) (pk).pk_ctx ) +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/** + * Quick access to an EC context inside a PK context. + * + * \warning You must make sure the PK context actually holds an EC context + * before using this macro! + */ +#define pk_ec( pk ) ( (ecp_keypair *) (pk).pk_ctx ) +#endif /* POLARSSL_ECP_C */ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Public key types + */ +typedef enum { + POLARSSL_PK_NONE=0, + POLARSSL_PK_RSA, + POLARSSL_PK_ECKEY, + POLARSSL_PK_ECKEY_DH, + POLARSSL_PK_ECDSA, + POLARSSL_PK_RSA_ALT, + POLARSSL_PK_RSASSA_PSS, +} pk_type_t; + +/** + * \brief Options for RSASSA-PSS signature verification. + * See \c rsa_rsassa_pss_verify_ext() + */ +typedef struct +{ + md_type_t mgf1_hash_id; + int expected_salt_len; + +} pk_rsassa_pss_options; + +/** + * \brief Types for interfacing with the debug module + */ +typedef enum +{ + POLARSSL_PK_DEBUG_NONE = 0, + POLARSSL_PK_DEBUG_MPI, + POLARSSL_PK_DEBUG_ECP, +} pk_debug_type; + +/** + * \brief Item to send to the debug module + */ +typedef struct +{ + pk_debug_type type; + const char *name; + void *value; +} pk_debug_item; + +/** Maximum number of item send for debugging, plus 1 */ +#define POLARSSL_PK_DEBUG_MAX_ITEMS 3 + +/** + * \brief Public key information and operations + */ +typedef struct +{ + /** Public key type */ + pk_type_t type; + + /** Type name */ + const char *name; + + /** Get key size in bits */ + size_t (*get_size)( const void * ); + + /** Tell if the context implements this type (e.g. ECKEY can do ECDSA) */ + int (*can_do)( pk_type_t type ); + + /** Verify signature */ + int (*verify_func)( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + + /** Make signature */ + int (*sign_func)( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + + /** Decrypt message */ + int (*decrypt_func)( void *ctx, const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + + /** Encrypt message */ + int (*encrypt_func)( void *ctx, const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + + /** Allocate a new context */ + void * (*ctx_alloc_func)( void ); + + /** Free the given context */ + void (*ctx_free_func)( void *ctx ); + + /** Interface with the debug module */ + void (*debug_func)( const void *ctx, pk_debug_item *items ); + +} pk_info_t; + +/** + * \brief Public key container + */ +typedef struct +{ + const pk_info_t * pk_info; /**< Public key informations */ + void * pk_ctx; /**< Underlying public key context */ +} pk_context; + +/** + * \brief Types for RSA-alt abstraction + */ +typedef int (*pk_rsa_alt_decrypt_func)( void *ctx, int mode, size_t *olen, + const unsigned char *input, unsigned char *output, + size_t output_max_len ); +typedef int (*pk_rsa_alt_sign_func)( void *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int mode, md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig ); +typedef size_t (*pk_rsa_alt_key_len_func)( void *ctx ); + +/** + * \brief Return information associated with the given PK type + * + * \param pk_type PK type to search for. + * + * \return The PK info associated with the type or NULL if not found. + */ +const pk_info_t *pk_info_from_type( pk_type_t pk_type ); + +/** + * \brief Initialize a pk_context (as NONE) + */ +void pk_init( pk_context *ctx ); + +/** + * \brief Free a pk_context + */ +void pk_free( pk_context *ctx ); + +/** + * \brief Initialize a PK context with the information given + * and allocates the type-specific PK subcontext. + * + * \param ctx Context to initialize. Must be empty (type NONE). + * \param info Information to use + * + * \return 0 on success, + * POLARSSL_ERR_PK_BAD_INPUT_DATA on invalid input, + * POLARSSL_ERR_PK_MALLOC_FAILED on allocation failure. + * + * \note For contexts holding an RSA-alt key, use + * \c pk_init_ctx_rsa_alt() instead. + */ +int pk_init_ctx( pk_context *ctx, const pk_info_t *info ); + +/** + * \brief Initialize an RSA-alt context + * + * \param ctx Context to initialize. Must be empty (type NONE). + * \param key RSA key pointer + * \param decrypt_func Decryption function + * \param sign_func Signing function + * \param key_len_func Function returning key length in bytes + * + * \return 0 on success, or POLARSSL_ERR_PK_BAD_INPUT_DATA if the + * context wasn't already initialized as RSA_ALT. + * + * \note This function replaces \c pk_init_ctx() for RSA-alt. + */ +int pk_init_ctx_rsa_alt( pk_context *ctx, void * key, + pk_rsa_alt_decrypt_func decrypt_func, + pk_rsa_alt_sign_func sign_func, + pk_rsa_alt_key_len_func key_len_func ); + +/** + * \brief Get the size in bits of the underlying key + * + * \param ctx Context to use + * + * \return Key size in bits, or 0 on error + */ +size_t pk_get_size( const pk_context *ctx ); + +/** + * \brief Get the length in bytes of the underlying key + * \param ctx Context to use + * + * \return Key length in bytes, or 0 on error + */ +static inline size_t pk_get_len( const pk_context *ctx ) +{ + return( ( pk_get_size( ctx ) + 7 ) / 8 ); +} + +/** + * \brief Tell if a context can do the operation given by type + * + * \param ctx Context to test + * \param type Target type + * + * \return 0 if context can't do the operations, + * 1 otherwise. + */ +int pk_can_do( pk_context *ctx, pk_type_t type ); + +/** + * \brief Verify signature (including padding if relevant). + * + * \param ctx PK context to use + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * + * \return 0 on success (signature is valid), + * POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is + * valid but its actual length is less than sig_len, + * or a specific error code. + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * Use \c pk_verify_ext( POLARSSL_PK_RSASSA_PSS, ... ) + * to verify RSASSA_PSS signatures. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be POLARSSL_MD_NONE, only if hash_len != 0 + */ +int pk_verify( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +/** + * \brief Verify signature, with options. + * (Includes verification of the padding depending on type.) + * + * \param type Signature type (inc. possible padding type) to verify + * \param options Pointer to type-specific options, or NULL + * \param ctx PK context to use + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Signature to verify + * \param sig_len Signature length + * + * \return 0 on success (signature is valid), + * POLARSSL_ERR_PK_TYPE_MISMATCH if the PK context can't be + * used for this type of signatures, + * POLARSSL_ERR_PK_SIG_LEN_MISMATCH if the signature is + * valid but its actual length is less than sig_len, + * or a specific error code. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be POLARSSL_MD_NONE, only if hash_len != 0 + * + * \note If type is POLARSSL_PK_RSASSA_PSS, then options must point + * to a pk_rsassa_pss_options structure, + * otherwise it must be NULL. + */ +int pk_verify_ext( pk_type_t type, const void *options, + pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +/** + * \brief Make signature, including padding if relevant. + * + * \param ctx PK context to use + * \param md_alg Hash algorithm used (see notes) + * \param hash Hash of the message to sign + * \param hash_len Hash length or 0 (see notes) + * \param sig Place to write the signature + * \param sig_len Number of bytes written + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \return 0 on success, or a specific error code. + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * There is no interface in the PK module to make RSASSA-PSS + * signatures yet. + * + * \note If hash_len is 0, then the length associated with md_alg + * is used instead, or an error returned if it is invalid. + * + * \note md_alg may be POLARSSL_MD_NONE, only if hash_len != 0 + */ +int pk_sign( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Decrypt message (including padding if relevant). + * + * \param ctx PK context to use + * \param input Input to decrypt + * \param ilen Input size + * \param output Decrypted output + * \param olen Decrypted message length + * \param osize Size of the output buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * + * \return 0 on success, or a specific error code. + */ +int pk_decrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Encrypt message (including padding if relevant). + * + * \param ctx PK context to use + * \param input Message to encrypt + * \param ilen Message size + * \param output Encrypted output + * \param olen Encrypted output length + * \param osize Size of the output buffer + * \param f_rng RNG function + * \param p_rng RNG parameter + * + * \note For RSA keys, the default padding type is PKCS#1 v1.5. + * + * \return 0 on success, or a specific error code. + */ +int pk_encrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +/** + * \brief Export debug information + * + * \param ctx Context to use + * \param items Place to write debug items + * + * \return 0 on success or POLARSSL_ERR_PK_BAD_INPUT_DATA + */ +int pk_debug( const pk_context *ctx, pk_debug_item *items ); + +/** + * \brief Access the type name + * + * \param ctx Context to use + * + * \return Type name on success, or "invalid PK" + */ +const char * pk_get_name( const pk_context *ctx ); + +/** + * \brief Get the key type + * + * \param ctx Context to use + * + * \return Type on success, or POLARSSL_PK_NONE + */ +pk_type_t pk_get_type( const pk_context *ctx ); + +#if defined(POLARSSL_PK_PARSE_C) +/** \ingroup pk_module */ +/** + * \brief Parse a private key + * + * \param ctx key to be initialized + * \param key input buffer + * \param keylen size of the buffer + * \param pwd password for decryption (optional) + * \param pwdlen size of the password + * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int pk_parse_key( pk_context *ctx, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ); + +/** \ingroup pk_module */ +/** + * \brief Parse a public key + * + * \param ctx key to be initialized + * \param key input buffer + * \param keylen size of the buffer + * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int pk_parse_public_key( pk_context *ctx, + const unsigned char *key, size_t keylen ); + +#if defined(POLARSSL_FS_IO) +/** \ingroup pk_module */ +/** + * \brief Load and parse a private key + * + * \param ctx key to be initialized + * \param path filename to read the private key from + * \param password password to decrypt the file (can be NULL) + * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int pk_parse_keyfile( pk_context *ctx, + const char *path, const char *password ); + +/** \ingroup pk_module */ +/** + * \brief Load and parse a public key + * + * \param ctx key to be initialized + * \param path filename to read the private key from + * + * \note On entry, ctx must be empty, either freshly initialised + * with pk_init() or reset with pk_free(). If you need a + * specific key type, check the result with pk_can_do(). + * + * \note The key is also checked for correctness. + * + * \return 0 if successful, or a specific PK or PEM error code + */ +int pk_parse_public_keyfile( pk_context *ctx, const char *path ); +#endif /* POLARSSL_FS_IO */ +#endif /* POLARSSL_PK_PARSE_C */ + +#if defined(POLARSSL_PK_WRITE_C) +/** + * \brief Write a private key to a PKCS#1 or SEC1 DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx private to write away + * \param buf buffer to write to + * \param size size of the buffer + * + * \return length of data written if successful, or a specific + * error code + */ +int pk_write_key_der( pk_context *ctx, unsigned char *buf, size_t size ); + +/** + * \brief Write a public key to a SubjectPublicKeyInfo DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx public key to write away + * \param buf buffer to write to + * \param size size of the buffer + * + * \return length of data written if successful, or a specific + * error code + */ +int pk_write_pubkey_der( pk_context *ctx, unsigned char *buf, size_t size ); + +#if defined(POLARSSL_PEM_WRITE_C) +/** + * \brief Write a public key to a PEM string + * + * \param ctx public key to write away + * \param buf buffer to write to + * \param size size of the buffer + * + * \return 0 successful, or a specific error code + */ +int pk_write_pubkey_pem( pk_context *ctx, unsigned char *buf, size_t size ); + +/** + * \brief Write a private key to a PKCS#1 or SEC1 PEM string + * + * \param ctx private to write away + * \param buf buffer to write to + * \param size size of the buffer + * + * \return 0 successful, or a specific error code + */ +int pk_write_key_pem( pk_context *ctx, unsigned char *buf, size_t size ); +#endif /* POLARSSL_PEM_WRITE_C */ +#endif /* POLARSSL_PK_WRITE_C */ + +/* + * WARNING: Low-level functions. You probably do not want to use these unless + * you are certain you do ;) + */ + +#if defined(POLARSSL_PK_PARSE_C) +/** + * \brief Parse a SubjectPublicKeyInfo DER structure + * + * \param p the position in the ASN.1 data + * \param end end of the buffer + * \param pk the key to fill + * + * \return 0 if successful, or a specific PK error code + */ +int pk_parse_subpubkey( unsigned char **p, const unsigned char *end, + pk_context *pk ); +#endif /* POLARSSL_PK_PARSE_C */ + +#if defined(POLARSSL_PK_WRITE_C) +/** + * \brief Write a subjectPublicKey to ASN.1 data + * Note: function works backwards in data buffer + * + * \param p reference to current position pointer + * \param start start of the buffer (for bounds-checking) + * \param key public key to write away + * + * \return the length written or a negative error code + */ +int pk_write_pubkey( unsigned char **p, unsigned char *start, + const pk_context *key ); +#endif /* POLARSSL_PK_WRITE_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_PK_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk_wrap.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk_wrap.h new file mode 100644 index 0000000..7baafb9 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pk_wrap.h @@ -0,0 +1,63 @@ +/** + * \file pk.h + * + * \brief Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef POLARSSL_PK_WRAP_H +#define POLARSSL_PK_WRAP_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "pk.h" + +/* Container for RSA-alt */ +typedef struct +{ + void *key; + pk_rsa_alt_decrypt_func decrypt_func; + pk_rsa_alt_sign_func sign_func; + pk_rsa_alt_key_len_func key_len_func; +} rsa_alt_context; + +#if defined(POLARSSL_RSA_C) +extern const pk_info_t rsa_info; +#endif + +#if defined(POLARSSL_ECP_C) +extern const pk_info_t eckey_info; +extern const pk_info_t eckeydh_info; +#endif + +#if defined(POLARSSL_ECDSA_C) +extern const pk_info_t ecdsa_info; +#endif + +extern const pk_info_t rsa_alt_info; + +#endif /* POLARSSL_PK_WRAP_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs11.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs11.h new file mode 100644 index 0000000..84f862d --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs11.h @@ -0,0 +1,174 @@ +/** + * \file pkcs11.h + * + * \brief Wrapper for PKCS#11 library libpkcs11-helper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PKCS11_H +#define POLARSSL_PKCS11_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PKCS11_C) + +#include "x509_crt.h" + +#include + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Context for PKCS #11 private keys. + */ +typedef struct { + pkcs11h_certificate_t pkcs11h_cert; + int len; +} pkcs11_context; + +/** + * Fill in a PolarSSL certificate, based on the given PKCS11 helper certificate. + * + * \param cert X.509 certificate to fill + * \param pkcs11h_cert PKCS #11 helper certificate + * + * \return 0 on success. + */ +int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11h_cert ); + +/** + * Initialise a pkcs11_context, storing the given certificate. Note that the + * pkcs11_context will take over control of the certificate, freeing it when + * done. + * + * \param priv_key Private key structure to fill. + * \param pkcs11_cert PKCS #11 helper certificate + * + * \return 0 on success + */ +int pkcs11_priv_key_init( pkcs11_context *priv_key, + pkcs11h_certificate_t pkcs11_cert ); + +/** + * Free the contents of the given private key context. Note that the structure + * itself is not freed. + * + * \param priv_key Private key structure to cleanup + */ +void pkcs11_priv_key_free( pkcs11_context *priv_key ); + +/** + * \brief Do an RSA private key decrypt, then remove the message + * padding + * + * \param ctx PKCS #11 context + * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param olen will contain the plaintext length + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int pkcs11_decrypt( pkcs11_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Do a private RSA to sign a message digest + * + * \param ctx PKCS #11 context + * \param mode must be RSA_PRIVATE, for compatibility with rsa.c's signature + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int pkcs11_sign( pkcs11_context *ctx, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * SSL/TLS wrappers for PKCS#11 functions + */ +static inline int ssl_pkcs11_decrypt( void *ctx, int mode, size_t *olen, + const unsigned char *input, unsigned char *output, + size_t output_max_len ) +{ + return pkcs11_decrypt( (pkcs11_context *) ctx, mode, olen, input, output, + output_max_len ); +} + +static inline int ssl_pkcs11_sign( void *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int mode, md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig ) +{ + ((void) f_rng); + ((void) p_rng); + return pkcs11_sign( (pkcs11_context *) ctx, mode, md_alg, + hashlen, hash, sig ); +} + +static inline size_t ssl_pkcs11_key_len( void *ctx ) +{ + return ( (pkcs11_context *) ctx )->len; +} + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_PKCS11_C */ + +#endif /* POLARSSL_PKCS11_H */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs12.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs12.h new file mode 100644 index 0000000..4bd5018 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs12.h @@ -0,0 +1,123 @@ +/** + * \file pkcs12.h + * + * \brief PKCS#12 Personal Information Exchange Syntax + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PKCS12_H +#define POLARSSL_PKCS12_H + +#include + +#include "md.h" +#include "cipher.h" +#include "asn1.h" + +#define POLARSSL_ERR_PKCS12_BAD_INPUT_DATA -0x1F80 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE -0x1F00 /**< Feature not available, e.g. unsupported encryption scheme. */ +#define POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT -0x1E80 /**< PBE ASN.1 data not as expected. */ +#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH -0x1E00 /**< Given private key password does not allow for correct decryption. */ + +#define PKCS12_DERIVE_KEY 1 /**< encryption/decryption key */ +#define PKCS12_DERIVE_IV 2 /**< initialization vector */ +#define PKCS12_DERIVE_MAC_KEY 3 /**< integrity / MAC key */ + +#define PKCS12_PBE_DECRYPT 0 +#define PKCS12_PBE_ENCRYPT 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief PKCS12 Password Based function (encryption / decryption) + * for pbeWithSHAAnd128BitRC4 + * + * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure + * \param mode either PKCS12_PBE_ENCRYPT or PKCS12_PBE_DECRYPT + * \param pwd the password used (may be NULL if no password is used) + * \param pwdlen length of the password (may be 0) + * \param input the input data + * \param len data length + * \param output the output buffer + * + * \return 0 if successful, or a PolarSSL error code + */ +int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *input, size_t len, + unsigned char *output ); + +/** + * \brief PKCS12 Password Based function (encryption / decryption) + * for cipher-based and md-based PBE's + * + * \param pbe_params an ASN1 buffer containing the pkcs-12PbeParams structure + * \param mode either PKCS12_PBE_ENCRYPT or PKCS12_PBE_DECRYPT + * \param cipher_type the cipher used + * \param md_type the md used + * \param pwd the password used (may be NULL if no password is used) + * \param pwdlen length of the password (may be 0) + * \param input the input data + * \param len data length + * \param output the output buffer + * + * \return 0 if successful, or a PolarSSL error code + */ +int pkcs12_pbe( asn1_buf *pbe_params, int mode, + cipher_type_t cipher_type, md_type_t md_type, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *input, size_t len, + unsigned char *output ); + +/** + * \brief The PKCS#12 derivation function uses a password and a salt + * to produce pseudo-random bits for a particular "purpose". + * + * Depending on the given id, this function can produce an + * encryption/decryption key, an nitialization vector or an + * integrity key. + * + * \param data buffer to store the derived data in + * \param datalen length to fill + * \param pwd password to use (may be NULL if no password is used) + * \param pwdlen length of the password (may be 0) + * \param salt salt buffer to use + * \param saltlen length of the salt + * \param md md type to use during the derivation + * \param id id that describes the purpose (can be PKCS12_DERIVE_KEY, + * PKCS12_DERIVE_IV or PKCS12_DERIVE_MAC_KEY) + * \param iterations number of iterations + * + * \return 0 if successful, or a MD, BIGNUM type error. + */ +int pkcs12_derivation( unsigned char *data, size_t datalen, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *salt, size_t saltlen, + md_type_t md, int id, int iterations ); + +#ifdef __cplusplus +} +#endif + +#endif /* pkcs12.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs5.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs5.h new file mode 100644 index 0000000..34e824b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/pkcs5.h @@ -0,0 +1,104 @@ +/** + * \file pkcs5.h + * + * \brief PKCS#5 functions + * + * \author Mathias Olsson + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PKCS5_H +#define POLARSSL_PKCS5_H + +#include + +#include "asn1.h" +#include "md.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_PKCS5_BAD_INPUT_DATA -0x3f80 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_PKCS5_INVALID_FORMAT -0x3f00 /**< Unexpected ASN.1 data. */ +#define POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE -0x3e80 /**< Requested encryption or digest alg not available. */ +#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH -0x3e00 /**< Given private key password does not allow for correct decryption. */ + +#define PKCS5_DECRYPT 0 +#define PKCS5_ENCRYPT 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief PKCS#5 PBES2 function + * + * \param pbe_params the ASN.1 algorithm parameters + * \param mode either PKCS5_DECRYPT or PKCS5_ENCRYPT + * \param pwd password to use when generating key + * \param pwdlen length of password + * \param data data to process + * \param datalen length of data + * \param output output buffer + * + * \returns 0 on success, or a PolarSSL error code if verification fails. + */ +int pkcs5_pbes2( asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t datalen, + unsigned char *output ); + +/** + * \brief PKCS#5 PBKDF2 using HMAC + * + * \param ctx Generic HMAC context + * \param password Password to use when generating key + * \param plen Length of password + * \param salt Salt to use when generating key + * \param slen Length of salt + * \param iteration_count Iteration count + * \param key_length Length of generated key + * \param output Generated key. Must be at least as big as key_length + * + * \returns 0 on success, or a PolarSSL error code if verification fails. + */ +int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, + size_t plen, const unsigned char *salt, size_t slen, + unsigned int iteration_count, + uint32_t key_length, unsigned char *output ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int pkcs5_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* pkcs5.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/platform.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/platform.h new file mode 100644 index 0000000..61734a0 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/platform.h @@ -0,0 +1,130 @@ +/** + * \file platform.h + * + * \brief PolarSSL Platform abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_PLATFORM_H +#define POLARSSL_PLATFORM_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef CONFIG_PLATFORM_8195A +#include "rom_ssl_ram_map.h" +#endif +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(POLARSSL_PLATFORM_NO_STD_FUNCTIONS) +#include +#if !defined(POLARSSL_PLATFORM_STD_PRINTF) +#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_FPRINTF) +#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_MALLOC) +#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use */ +#endif +#if !defined(POLARSSL_PLATFORM_STD_FREE) +#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use */ +#endif +#else /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(POLARSSL_PLATFORM_STD_MEM_HDR) +#include POLARSSL_PLATFORM_STD_MEM_HDR +#endif +#endif /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ + +/* \} name SECTION: Module settings */ + +/* + * The function pointers for malloc and free + */ +#if defined(POLARSSL_PLATFORM_MEMORY) +extern void * (*polarssl_malloc)( size_t len ); +extern void (*polarssl_free)( void *ptr ); + +/** + * \brief Set your own memory implementation function pointers + * + * \param malloc_func the malloc function implementation + * \param free_func the free function implementation + * + * \return 0 if successful + */ +int platform_set_malloc_free( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ); +#else /* POLARSSL_PLATFORM_ENTROPY */ +#define polarssl_malloc rom_ssl_ram_map.ssl_malloc +#define polarssl_free rom_ssl_ram_map.ssl_free +#endif /* POLARSSL_PLATFORM_ENTROPY */ + +/* + * The function pointers for printf + */ +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) +extern int (*polarssl_printf)( const char *format, ... ); + +/** + * \brief Set your own printf function pointer + * + * \param printf_func the printf function implementation + * + * \return 0 + */ +int platform_set_printf( int (*printf_func)( const char *, ... ) ); +#else /* POLARSSL_PLATFORM_PRINTF_ALT */ +#define polarssl_printf rom_ssl_ram_map.ssl_printf +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ + +/* + * The function pointers for fprintf + */ +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) +extern int (*polarssl_fprintf)( FILE *stream, const char *format, ... ); + +int platform_set_fprintf( int (*fprintf_func)( FILE *stream, const char *, + ... ) ); +#else +#define polarssl_fprintf fprintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* platform.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ripemd160.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ripemd160.h new file mode 100644 index 0000000..e3b66c9 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ripemd160.h @@ -0,0 +1,204 @@ +/** + * \file ripemd160.h + * + * \brief RIPE MD-160 message digest + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_RIPEMD160_H +#define POLARSSL_RIPEMD160_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR -0x007E /**< Read/write error in file. */ + +#if !defined(POLARSSL_RIPEMD160_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief RIPEMD-160 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +ripemd160_context; + +/** + * \brief Initialize RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be initialized + */ +void ripemd160_init( ripemd160_context *ctx ); + +/** + * \brief Clear RIPEMD-160 context + * + * \param ctx RIPEMD-160 context to be cleared + */ +void ripemd160_free( ripemd160_context *ctx ); + +/** + * \brief RIPEMD-160 context setup + * + * \param ctx context to be initialized + */ +void ripemd160_starts( ripemd160_context *ctx ); + +/** + * \brief RIPEMD-160 process buffer + * + * \param ctx RIPEMD-160 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void ripemd160_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief RIPEMD-160 final digest + * + * \param ctx RIPEMD-160 context + * \param output RIPEMD-160 checksum result + */ +void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] ); + +/* Internal use */ +void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_RIPEMD160_ALT */ +#include "ripemd160.h" +#endif /* POLARSSL_RIPEMD160_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = RIPEMD-160( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output RIPEMD-160 checksum result + */ +void ripemd160( const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Output = RIPEMD-160( file contents ) + * + * \param path input file name + * \param output RIPEMD-160 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR + */ +int ripemd160_file( const char *path, unsigned char output[20] ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief RIPEMD-160 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void ripemd160_hmac_starts( ripemd160_context *ctx, + const unsigned char *key, size_t keylen ); + +/** + * \brief RIPEMD-160 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void ripemd160_hmac_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ); + +/** + * \brief RIPEMD-160 HMAC final digest + * + * \param ctx HMAC context + * \param output RIPEMD-160 HMAC checksum result + */ +void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] ); + +/** + * \brief RIPEMD-160 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void ripemd160_hmac_reset( ripemd160_context *ctx ); + +/** + * \brief Output = HMAC-RIPEMD-160( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-RIPEMD-160 result + */ +void ripemd160_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int ripemd160_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* ripemd160.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/rsa.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/rsa.h new file mode 100644 index 0000000..c06c7d5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/rsa.h @@ -0,0 +1,647 @@ +/** + * \file rsa.h + * + * \brief The RSA public-key cryptosystem + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_RSA_H +#define POLARSSL_RSA_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "bignum.h" +#include "md.h" + +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + +/* + * RSA Error codes + */ +#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x4080 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_RSA_INVALID_PADDING -0x4100 /**< Input data contains invalid padding and is rejected. */ +#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x4180 /**< Something failed during generation of a key. */ +#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x4200 /**< Key failed to pass the libraries validity check. */ +#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x4280 /**< The public key operation failed. */ +#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x4300 /**< The private key operation failed. */ +#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x4380 /**< The PKCS#1 verification failed. */ +#define POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE -0x4400 /**< The output buffer for decryption is not large enough. */ +#define POLARSSL_ERR_RSA_RNG_FAILED -0x4480 /**< The random generator failed to generate non-zeros. */ + +/* + * RSA constants + */ +#define RSA_PUBLIC 0 +#define RSA_PRIVATE 1 + +#define RSA_PKCS_V15 0 +#define RSA_PKCS_V21 1 + +#define RSA_SIGN 1 +#define RSA_CRYPT 2 + +#define RSA_SALT_LEN_ANY -1 + +/* + * The above constants may be used even if the RSA module is compile out, + * eg for alternative (PKCS#11) RSA implemenations in the PK layers. + */ +#if defined(POLARSSL_RSA_C) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief RSA context structure + */ +typedef struct +{ + int ver; /*!< always 0 */ + size_t len; /*!< size(N) in chars */ + + mpi N; /*!< public modulus */ + mpi E; /*!< public exponent */ + + mpi D; /*!< private exponent */ + mpi P; /*!< 1st prime factor */ + mpi Q; /*!< 2nd prime factor */ + mpi DP; /*!< D % (P - 1) */ + mpi DQ; /*!< D % (Q - 1) */ + mpi QP; /*!< 1 / (Q % P) */ + + mpi RN; /*!< cached R^2 mod N */ + mpi RP; /*!< cached R^2 mod P */ + mpi RQ; /*!< cached R^2 mod Q */ + +#if !defined(POLARSSL_RSA_NO_CRT) + mpi Vi; /*!< cached blinding value */ + mpi Vf; /*!< cached un-blinding value */ +#endif + + int padding; /*!< RSA_PKCS_V15 for 1.5 padding and + RSA_PKCS_v21 for OAEP/PSS */ + int hash_id; /*!< Hash identifier of md_type_t as + specified in the md.h header file + for the EME-OAEP and EMSA-PSS + encoding */ +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< Thread-safety mutex */ +#endif +} +rsa_context; + +/** + * \brief Initialize an RSA context + * + * Note: Set padding to RSA_PKCS_V21 for the RSAES-OAEP + * encryption scheme and the RSASSA-PSS signature scheme. + * + * \param ctx RSA context to be initialized + * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 + * \param hash_id RSA_PKCS_V21 hash identifier + * + * \note The hash_id parameter is actually ignored + * when using RSA_PKCS_V15 padding. + * + * \note Choice of padding mode is strictly enforced for private key + * operations, since there might be security concerns in + * mixing padding modes. For public key operations it's merely + * a default value, which can be overriden by calling specific + * rsa_rsaes_xxx or rsa_rsassa_xxx functions. + * + * \note The chosen hash is always used for OEAP encryption. + * For PSS signatures, it's always used for making signatures, + * but can be overriden (and always is, if set to + * POLARSSL_MD_NONE) for verifying them. + */ +void rsa_init( rsa_context *ctx, + int padding, + int hash_id); + +/** + * \brief Set padding for an already initialized RSA context + * See \c rsa_init() for details. + * + * \param ctx RSA context to be set + * \param padding RSA_PKCS_V15 or RSA_PKCS_V21 + * \param hash_id RSA_PKCS_V21 hash identifier + */ +void rsa_set_padding( rsa_context *ctx, int padding, int hash_id); + +/** + * \brief Generate an RSA keypair + * + * \param ctx RSA context that will hold the key + * \param f_rng RNG function + * \param p_rng RNG parameter + * \param nbits size of the public key in bits + * \param exponent public exponent (e.g., 65537) + * + * \note rsa_init() must be called beforehand to setup + * the RSA context. + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_gen_key( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ); + +/** + * \brief Check a public RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_check_pubkey( const rsa_context *ctx ); + +/** + * \brief Check a private RSA key + * + * \param ctx RSA context to be checked + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + */ +int rsa_check_privkey( const rsa_context *ctx ); + +/** + * \brief Do an RSA public key operation + * + * \param ctx RSA context + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note This function does NOT take care of message + * padding. Also, be sure to set input[0] = 0 or assure that + * input is smaller than N. + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_public( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Do an RSA private key operation + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for blinding) + * \param p_rng RNG parameter + * \param input input buffer + * \param output output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The input and output buffers must be large + * enough (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_private( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic wrapper to perform a PKCS#1 encryption using the + * mode from the context. Add the message padding, then do an + * RSA operation. + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding + * and RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_pkcs1_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding and RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding + * and RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param label buffer holding the custom label to use + * \param label_len contains the label length + * \param ilen contains the plaintext length + * \param input buffer holding the data to be encrypted + * \param output buffer that will hold the ciphertext + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsaes_oaep_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ); + +/** + * \brief Generic wrapper to perform a PKCS#1 decryption using the + * mode from the context. Do an RSA operation, then remove + * the message padding + * + * \param ctx RSA context + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_pkcs1_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT) + * + * \param ctx RSA context + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param label buffer holding the custom label to use + * \param label_len contains the label length + * \param olen will contain the plaintext length + * \param input buffer holding the encrypted data + * \param output buffer that will hold the plaintext + * \param output_max_len maximum length of the output buffer + * + * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code + * + * \note The output buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise + * an error is thrown. + */ +int rsa_rsaes_oaep_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ); + +/** + * \brief Generic wrapper to perform a PKCS#1 signature using the + * mode from the context. Do a private RSA operation to sign + * a message digest + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding and for + * RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding, see comments on + * \note \c rsa_rsassa_pss_sign() for details on md_alg and hash_id. + */ +int rsa_pkcs1_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN) + * + * \param ctx RSA context + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN) + * + * \param ctx RSA context + * \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding and for + * RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer that will hold the ciphertext + * + * \return 0 if the signing operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note The hash_id in the RSA context is the one used for the + * encoding. md_alg in the function call is the type of hash + * that is encoded. According to RFC 3447 it is advised to + * keep both hashes the same. + */ +int rsa_rsassa_pss_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ); + +/** + * \brief Generic wrapper to perform a PKCS#1 verification using the + * mode from the context. Do a public RSA operation and check + * the message digest + * + * \param ctx points to an RSA public key + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note In case of PKCS#1 v2.1 encoding, see comments on + * \c rsa_rsassa_pss_verify() about md_alg and hash_id. + */ +int rsa_pkcs1_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY) + * + * \param ctx points to an RSA public key + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + */ +int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) + * (This is the "simple" version.) + * + * \param ctx points to an RSA public key + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note The hash_id in the RSA context is the one used for the + * verification. md_alg in the function call is the type of + * hash that is verified. According to RFC 3447 it is advised to + * keep both hashes the same. If hash_id in the RSA context is + * unset, the md_alg from the function call is used. + */ +int rsa_rsassa_pss_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ); + +/** + * \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY) + * (This is the version with "full" options.) + * + * \param ctx points to an RSA public key + * \param f_rng RNG function (Only needed for RSA_PRIVATE) + * \param p_rng RNG parameter + * \param mode RSA_PUBLIC or RSA_PRIVATE + * \param md_alg a POLARSSL_MD_* (use POLARSSL_MD_NONE for signing raw data) + * \param hashlen message digest length (for POLARSSL_MD_NONE only) + * \param hash buffer holding the message digest + * \param mgf1_hash_id message digest used for mask generation + * \param expected_salt_len Length of the salt used in padding, use + * RSA_SALT_LEN_ANY to accept any salt length + * \param sig buffer holding the ciphertext + * + * \return 0 if the verify operation was successful, + * or an POLARSSL_ERR_RSA_XXX error code + * + * \note The "sig" buffer must be as large as the size + * of ctx->N (eg. 128 bytes if RSA-1024 is used). + * + * \note The hash_id in the RSA context is ignored. + */ +int rsa_rsassa_pss_verify_ext( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ); + +/** + * \brief Copy the components of an RSA context + * + * \param dst Destination context + * \param src Source context + * + * \return O on success, + * POLARSSL_ERR_MPI_MALLOC_FAILED on memory allocation failure + */ +int rsa_copy( rsa_context *dst, const rsa_context *src ); + +/** + * \brief Free the components of an RSA key + * + * \param ctx RSA Context to free + */ +void rsa_free( rsa_context *ctx ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int rsa_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_RSA_C */ + +#endif /* rsa.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha1.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha1.h new file mode 100644 index 0000000..cb0c436 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha1.h @@ -0,0 +1,200 @@ +/** + * \file sha1.h + * + * \brief SHA-1 cryptographic hash function + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SHA1_H +#define POLARSSL_SHA1_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_SHA1_FILE_IO_ERROR -0x0076 /**< Read/write error in file. */ + +#if !defined(POLARSSL_SHA1_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-1 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[5]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ +} +sha1_context; + +/** + * \brief Initialize SHA-1 context + * + * \param ctx SHA-1 context to be initialized + */ +void sha1_init( sha1_context *ctx ); + +/** + * \brief Clear SHA-1 context + * + * \param ctx SHA-1 context to be cleared + */ +void sha1_free( sha1_context *ctx ); + +/** + * \brief SHA-1 context setup + * + * \param ctx context to be initialized + */ +void sha1_starts( sha1_context *ctx ); + +/** + * \brief SHA-1 process buffer + * + * \param ctx SHA-1 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ); + +/** + * \brief SHA-1 final digest + * + * \param ctx SHA-1 context + * \param output SHA-1 checksum result + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ); + +/* Internal use */ +void sha1_process( sha1_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_SHA1_ALT */ +#include "sha1_alt.h" +#endif /* POLARSSL_SHA1_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = SHA-1( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-1 checksum result + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ); + +/** + * \brief Output = SHA-1( file contents ) + * + * \param path input file name + * \param output SHA-1 checksum result + * + * \return 0 if successful, or POLARSSL_ERR_SHA1_FILE_IO_ERROR + */ +int sha1_file( const char *path, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ); + +/** + * \brief SHA-1 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-1 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-1 HMAC checksum result + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ); + +/** + * \brief SHA-1 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void sha1_hmac_reset( sha1_context *ctx ); + +/** + * \brief Output = HMAC-SHA-1( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-1 result + */ +void sha1_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha1_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha1.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha256.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha256.h new file mode 100644 index 0000000..b143674 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha256.h @@ -0,0 +1,208 @@ +/** + * \file sha256.h + * + * \brief SHA-224 and SHA-256 cryptographic hash function + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SHA256_H +#define POLARSSL_SHA256_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define POLARSSL_ERR_SHA256_FILE_IO_ERROR -0x0078 /**< Read/write error in file. */ + +#if !defined(POLARSSL_SHA256_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-256 context structure + */ +typedef struct +{ + uint32_t total[2]; /*!< number of bytes processed */ + uint32_t state[8]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + unsigned char ipad[64]; /*!< HMAC: inner padding */ + unsigned char opad[64]; /*!< HMAC: outer padding */ + int is224; /*!< 0 => SHA-256, else SHA-224 */ +} +sha256_context; + +/** + * \brief Initialize SHA-256 context + * + * \param ctx SHA-256 context to be initialized + */ +void sha256_init( sha256_context *ctx ); + +/** + * \brief Clear SHA-256 context + * + * \param ctx SHA-256 context to be cleared + */ +void sha256_free( sha256_context *ctx ); + +/** + * \brief SHA-256 context setup + * + * \param ctx context to be initialized + * \param is224 0 = use SHA256, 1 = use SHA224 + */ +void sha256_starts( sha256_context *ctx, int is224 ); + +/** + * \brief SHA-256 process buffer + * + * \param ctx SHA-256 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha256_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-256 final digest + * + * \param ctx SHA-256 context + * \param output SHA-224/256 checksum result + */ +void sha256_finish( sha256_context *ctx, unsigned char output[32] ); + +/* Internal use */ +void sha256_process( sha256_context *ctx, const unsigned char data[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_SHA256_ALT */ +#include "sha256_alt.h" +#endif /* POLARSSL_SHA256_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = SHA-256( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-224/256 checksum result + * \param is224 0 = use SHA256, 1 = use SHA224 + */ +void sha256( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ); + +/** + * \brief Output = SHA-256( file contents ) + * + * \param path input file name + * \param output SHA-224/256 checksum result + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \return 0 if successful, or POLARSSL_ERR_SHA256_FILE_IO_ERROR + */ +int sha256_file( const char *path, unsigned char output[32], int is224 ); + +/** + * \brief SHA-256 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param is224 0 = use SHA256, 1 = use SHA224 + */ +void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key, + size_t keylen, int is224 ); + +/** + * \brief SHA-256 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-256 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-224/256 HMAC checksum result + */ +void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] ); + +/** + * \brief SHA-256 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void sha256_hmac_reset( sha256_context *ctx ); + +/** + * \brief Output = HMAC-SHA-256( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-224/256 result + * \param is224 0 = use SHA256, 1 = use SHA224 + */ +void sha256_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha256_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha256.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha512.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha512.h new file mode 100644 index 0000000..dfbae4a --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/sha512.h @@ -0,0 +1,209 @@ +/** + * \file sha512.h + * + * \brief SHA-384 and SHA-512 cryptographic hash function + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SHA512_H +#define POLARSSL_SHA512_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) || defined(__WATCOMC__) + #define UL64(x) x##ui64 + typedef unsigned __int64 uint64_t; +#else + #include + #define UL64(x) x##ULL +#endif + +#define POLARSSL_ERR_SHA512_FILE_IO_ERROR -0x007A /**< Read/write error in file. */ + +#if !defined(POLARSSL_SHA512_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief SHA-512 context structure + */ +typedef struct +{ + uint64_t total[2]; /*!< number of bytes processed */ + uint64_t state[8]; /*!< intermediate digest state */ + unsigned char buffer[128]; /*!< data block being processed */ + + unsigned char ipad[128]; /*!< HMAC: inner padding */ + unsigned char opad[128]; /*!< HMAC: outer padding */ + int is384; /*!< 0 => SHA-512, else SHA-384 */ +} +sha512_context; + +/** + * \brief Initialize SHA-512 context + * + * \param ctx SHA-512 context to be initialized + */ +void sha512_init( sha512_context *ctx ); + +/** + * \brief Clear SHA-512 context + * + * \param ctx SHA-512 context to be cleared + */ +void sha512_free( sha512_context *ctx ); + +/** + * \brief SHA-512 context setup + * + * \param ctx context to be initialized + * \param is384 0 = use SHA512, 1 = use SHA384 + */ +void sha512_starts( sha512_context *ctx, int is384 ); + +/** + * \brief SHA-512 process buffer + * + * \param ctx SHA-512 context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha512_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-512 final digest + * + * \param ctx SHA-512 context + * \param output SHA-384/512 checksum result + */ +void sha512_finish( sha512_context *ctx, unsigned char output[64] ); + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_SHA512_ALT */ +#include "sha512_alt.h" +#endif /* POLARSSL_SHA512_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Output = SHA-512( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-384/512 checksum result + * \param is384 0 = use SHA512, 1 = use SHA384 + */ +void sha512( const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ); + +/** + * \brief Output = SHA-512( file contents ) + * + * \param path input file name + * \param output SHA-384/512 checksum result + * \param is384 0 = use SHA512, 1 = use SHA384 + * + * \return 0 if successful, or POLARSSL_ERR_SHA512_FILE_IO_ERROR + */ +int sha512_file( const char *path, unsigned char output[64], int is384 ); + +/** + * \brief SHA-512 HMAC context setup + * + * \param ctx HMAC context to be initialized + * \param is384 0 = use SHA512, 1 = use SHA384 + * \param key HMAC secret key + * \param keylen length of the HMAC key + */ +void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key, + size_t keylen, int is384 ); + +/** + * \brief SHA-512 HMAC process buffer + * + * \param ctx HMAC context + * \param input buffer holding the data + * \param ilen length of the input data + */ +void sha512_hmac_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ); + +/** + * \brief SHA-512 HMAC final digest + * + * \param ctx HMAC context + * \param output SHA-384/512 HMAC checksum result + */ +void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] ); + +/** + * \brief SHA-512 HMAC context reset + * + * \param ctx HMAC context to be reset + */ +void sha512_hmac_reset( sha512_context *ctx ); + +/** + * \brief Output = HMAC-SHA-512( hmac key, input buffer ) + * + * \param key HMAC secret key + * \param keylen length of the HMAC key + * \param input buffer holding the data + * \param ilen length of the input data + * \param output HMAC-SHA-384/512 result + * \param is384 0 = use SHA512, 1 = use SHA384 + */ +void sha512_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int sha512_self_test( int verbose ); + +/* Internal use */ +void sha512_process( sha512_context *ctx, const unsigned char data[128] ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha512.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl.h new file mode 100644 index 0000000..39b8264 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl.h @@ -0,0 +1,1816 @@ +/** + * \file ssl.h + * + * \brief SSL/TLS functions. + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SSL_H +#define POLARSSL_SSL_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#include "net.h" +#include "bignum.h" +#include "ecp.h" + +#include "ssl_ciphersuites.h" + +#if defined(POLARSSL_MD5_C) +#include "md5.h" +#endif + +#if defined(POLARSSL_SHA1_C) +#include "sha1.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#include "sha256.h" +#endif + +#if defined(POLARSSL_SHA512_C) +#include "sha512.h" +#endif + +// for session tickets +#if defined(POLARSSL_AES_C) +#include "aes.h" +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) +#include "x509_crt.h" +#include "x509_crl.h" +#endif + +#if defined(POLARSSL_DHM_C) +#include "dhm.h" +#endif + +#if defined(POLARSSL_ECDH_C) +#include "ecdh.h" +#endif + +#if defined(POLARSSL_ZLIB_SUPPORT) +#include "zlib.h" +#endif + +#if defined(POLARSSL_HAVE_TIME) +#include +#endif + +/* For convenience below and in programs */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#define POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED +#endif + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* + * SSL Error codes + */ +#define POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE -0x7080 /**< The requested feature is not available. */ +#define POLARSSL_ERR_SSL_BAD_INPUT_DATA -0x7100 /**< Bad input parameters to function. */ +#define POLARSSL_ERR_SSL_INVALID_MAC -0x7180 /**< Verification of the message MAC failed. */ +#define POLARSSL_ERR_SSL_INVALID_RECORD -0x7200 /**< An invalid SSL record was received. */ +#define POLARSSL_ERR_SSL_CONN_EOF -0x7280 /**< The connection indicated an EOF. */ +#define POLARSSL_ERR_SSL_UNKNOWN_CIPHER -0x7300 /**< An unknown cipher was received. */ +#define POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN -0x7380 /**< The server has no ciphersuites in common with the client. */ +#define POLARSSL_ERR_SSL_NO_RNG -0x7400 /**< No RNG was provided to the SSL module. */ +#define POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE -0x7480 /**< No client certification received from the client, but required by the authentication mode. */ +#define POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE -0x7500 /**< Our own certificate(s) is/are too large to send in an SSL message.*/ +#define POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED -0x7580 /**< The own certificate is not set, but needed by the server. */ +#define POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED -0x7600 /**< The own private key or pre-shared key is not set, but needed. */ +#define POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED -0x7680 /**< No CA Chain is set, but required to operate. */ +#define POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE -0x7700 /**< An unexpected message was received from our peer. */ +#define POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */ +#define POLARSSL_ERR_SSL_PEER_VERIFY_FAILED -0x7800 /**< Verification of our peer failed. */ +#define POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY -0x7880 /**< The peer notified us that the connection is going to be closed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO -0x7900 /**< Processing of the ClientHello handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO -0x7980 /**< Processing of the ServerHello handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE -0x7A00 /**< Processing of the Certificate handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST -0x7A80 /**< Processing of the CertificateRequest handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */ +#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */ +#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */ +#define POLARSSL_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */ +#define POLARSSL_ERR_SSL_MALLOC_FAILED -0x7F00 /**< Memory allocation failed */ +#define POLARSSL_ERR_SSL_HW_ACCEL_FAILED -0x7F80 /**< Hardware acceleration function returned with error */ +#define POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH -0x6F80 /**< Hardware acceleration function skipped / left alone data */ +#define POLARSSL_ERR_SSL_COMPRESSION_FAILED -0x6F00 /**< Processing of the compression / decompression failed */ +#define POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */ +#define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */ +#define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */ +#define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */ +#define POLARSSL_ERR_SSL_UNKNOWN_IDENTITY -0x6C80 /**< Unknown identity received (eg, PSK identity) */ +#define POLARSSL_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */ +#define POLARSSL_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */ + +/* + * Various constants + */ +#define SSL_MAJOR_VERSION_3 3 +#define SSL_MINOR_VERSION_0 0 /*!< SSL v3.0 */ +#define SSL_MINOR_VERSION_1 1 /*!< TLS v1.0 */ +#define SSL_MINOR_VERSION_2 2 /*!< TLS v1.1 */ +#define SSL_MINOR_VERSION_3 3 /*!< TLS v1.2 */ + +/* Determine minimum supported version */ +#define SSL_MIN_MAJOR_VERSION SSL_MAJOR_VERSION_3 + +#if defined(POLARSSL_SSL_PROTO_SSL3) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_0 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_1 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_1) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_2 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#define SSL_MIN_MINOR_VERSION SSL_MINOR_VERSION_3 +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +/* Determine maximum supported version */ +#define SSL_MAX_MAJOR_VERSION SSL_MAJOR_VERSION_3 + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_3 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1_1) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_2 +#else +#if defined(POLARSSL_SSL_PROTO_TLS1) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_1 +#else +#if defined(POLARSSL_SSL_PROTO_SSL3) +#define SSL_MAX_MINOR_VERSION SSL_MINOR_VERSION_0 +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +/* RFC 6066 section 4, see also mfl_code_to_length in ssl_tls.c + * NONE must be zero so that memset()ing structure to zero works */ +#define SSL_MAX_FRAG_LEN_NONE 0 /*!< don't use this extension */ +#define SSL_MAX_FRAG_LEN_512 1 /*!< MaxFragmentLength 2^9 */ +#define SSL_MAX_FRAG_LEN_1024 2 /*!< MaxFragmentLength 2^10 */ +#define SSL_MAX_FRAG_LEN_2048 3 /*!< MaxFragmentLength 2^11 */ +#define SSL_MAX_FRAG_LEN_4096 4 /*!< MaxFragmentLength 2^12 */ +#define SSL_MAX_FRAG_LEN_INVALID 5 /*!< first invalid value */ + +#define SSL_IS_CLIENT 0 +#define SSL_IS_SERVER 1 +#define SSL_COMPRESS_NULL 0 +#define SSL_COMPRESS_DEFLATE 1 + +#define SSL_VERIFY_NONE 0 +#define SSL_VERIFY_OPTIONAL 1 +#define SSL_VERIFY_REQUIRED 2 + +#define SSL_INITIAL_HANDSHAKE 0 +#define SSL_RENEGOTIATION 1 /* In progress */ +#define SSL_RENEGOTIATION_DONE 2 /* Done */ +#define SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ + +#define SSL_LEGACY_RENEGOTIATION 0 +#define SSL_SECURE_RENEGOTIATION 1 + +#define SSL_RENEGOTIATION_DISABLED 0 +#define SSL_RENEGOTIATION_ENABLED 1 + +#define SSL_RENEGOTIATION_NOT_ENFORCED -1 +#define SSL_RENEGO_MAX_RECORDS_DEFAULT 16 + +#define SSL_LEGACY_NO_RENEGOTIATION 0 +#define SSL_LEGACY_ALLOW_RENEGOTIATION 1 +#define SSL_LEGACY_BREAK_HANDSHAKE 2 + +#define SSL_TRUNC_HMAC_DISABLED 0 +#define SSL_TRUNC_HMAC_ENABLED 1 +#define SSL_TRUNCATED_HMAC_LEN 10 /* 80 bits, rfc 6066 section 7 */ + +#define SSL_SESSION_TICKETS_DISABLED 0 +#define SSL_SESSION_TICKETS_ENABLED 1 + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(SSL_DEFAULT_TICKET_LIFETIME) +#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */ +#endif + +/* + * Size of the input / output buffer. + * Note: the RFC defines the default size of SSL / TLS messages. If you + * change the value here, other clients / servers may not be able to + * communicate with you anymore. Only change this value if you control + * both sides of the connection and have it reduced at both sides, or + * if you're using the Max Fragment Length extension and you know all your + * peers are using it too! + */ +#if !defined(SSL_MAX_CONTENT_LEN) +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +extern unsigned int mfl_code_to_length[]; // pvvx +#define SSL_MAX_CONTENT_LEN mfl_code_to_length[0] // default = 16384 (!) +#else +#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +#endif +#endif + +/* \} name SECTION: Module settings */ + +/* + * Allow extra bytes for record, authentication and encryption overhead: + * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) + * and allow for a maximum of 1024 of compression expansion if + * enabled. + */ +#if defined(POLARSSL_ZLIB_SUPPORT) +#define SSL_COMPRESSION_ADD 1024 +#else +#define SSL_COMPRESSION_ADD 0 +#endif + +#if defined(POLARSSL_RC4_C) || defined(POLARSSL_CIPHER_MODE_CBC) +/* Ciphersuites using HMAC */ +#if defined(POLARSSL_SHA512_C) +#define SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ +#elif defined(POLARSSL_SHA256_C) +#define SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ +#else +#define SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ +#endif +#else +/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ +#define SSL_MAC_ADD 16 +#endif + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#define SSL_PADDING_ADD 256 +#else +#define SSL_PADDING_ADD 0 +#endif + +#define SSL_BUFFER_LEN (rom_ssl_ram_map.ssl_buffer_len) // pvvx -> int set_ssl_max_frag_len(int len) +/* + ( SSL_MAX_CONTENT_LEN \ + + SSL_COMPRESSION_ADD \ + + 29 // counter + header + IV \ + + SSL_MAC_ADD \ + + SSL_PADDING_ADD \ + ) +*/ +/* + * Signaling ciphersuite values (SCSV) + */ +#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ + +/* + * Supported Signature and Hash algorithms (For TLS 1.2) + * RFC 5246 section 7.4.1.4.1 + */ +#define SSL_HASH_NONE 0 +#define SSL_HASH_MD5 1 +#define SSL_HASH_SHA1 2 +#define SSL_HASH_SHA224 3 +#define SSL_HASH_SHA256 4 +#define SSL_HASH_SHA384 5 +#define SSL_HASH_SHA512 6 + +#define SSL_SIG_ANON 0 +#define SSL_SIG_RSA 1 +#define SSL_SIG_ECDSA 3 + +/* + * Client Certificate Types + * RFC 5246 section 7.4.4 plus RFC 4492 section 5.5 + */ +#define SSL_CERT_TYPE_RSA_SIGN 1 +#define SSL_CERT_TYPE_ECDSA_SIGN 64 + +/* + * Message, alert and handshake types + */ +#define SSL_MSG_CHANGE_CIPHER_SPEC 20 +#define SSL_MSG_ALERT 21 +#define SSL_MSG_HANDSHAKE 22 +#define SSL_MSG_APPLICATION_DATA 23 + +#define SSL_ALERT_LEVEL_WARNING 1 +#define SSL_ALERT_LEVEL_FATAL 2 + +#define SSL_ALERT_MSG_CLOSE_NOTIFY 0 /* 0x00 */ +#define SSL_ALERT_MSG_UNEXPECTED_MESSAGE 10 /* 0x0A */ +#define SSL_ALERT_MSG_BAD_RECORD_MAC 20 /* 0x14 */ +#define SSL_ALERT_MSG_DECRYPTION_FAILED 21 /* 0x15 */ +#define SSL_ALERT_MSG_RECORD_OVERFLOW 22 /* 0x16 */ +#define SSL_ALERT_MSG_DECOMPRESSION_FAILURE 30 /* 0x1E */ +#define SSL_ALERT_MSG_HANDSHAKE_FAILURE 40 /* 0x28 */ +#define SSL_ALERT_MSG_NO_CERT 41 /* 0x29 */ +#define SSL_ALERT_MSG_BAD_CERT 42 /* 0x2A */ +#define SSL_ALERT_MSG_UNSUPPORTED_CERT 43 /* 0x2B */ +#define SSL_ALERT_MSG_CERT_REVOKED 44 /* 0x2C */ +#define SSL_ALERT_MSG_CERT_EXPIRED 45 /* 0x2D */ +#define SSL_ALERT_MSG_CERT_UNKNOWN 46 /* 0x2E */ +#define SSL_ALERT_MSG_ILLEGAL_PARAMETER 47 /* 0x2F */ +#define SSL_ALERT_MSG_UNKNOWN_CA 48 /* 0x30 */ +#define SSL_ALERT_MSG_ACCESS_DENIED 49 /* 0x31 */ +#define SSL_ALERT_MSG_DECODE_ERROR 50 /* 0x32 */ +#define SSL_ALERT_MSG_DECRYPT_ERROR 51 /* 0x33 */ +#define SSL_ALERT_MSG_EXPORT_RESTRICTION 60 /* 0x3C */ +#define SSL_ALERT_MSG_PROTOCOL_VERSION 70 /* 0x46 */ +#define SSL_ALERT_MSG_INSUFFICIENT_SECURITY 71 /* 0x47 */ +#define SSL_ALERT_MSG_INTERNAL_ERROR 80 /* 0x50 */ +#define SSL_ALERT_MSG_USER_CANCELED 90 /* 0x5A */ +#define SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ +#define SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ +#define SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ +#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */ +#define SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL 120 /* 0x78 */ + +#define SSL_HS_HELLO_REQUEST 0 +#define SSL_HS_CLIENT_HELLO 1 +#define SSL_HS_SERVER_HELLO 2 +#define SSL_HS_NEW_SESSION_TICKET 4 +#define SSL_HS_CERTIFICATE 11 +#define SSL_HS_SERVER_KEY_EXCHANGE 12 +#define SSL_HS_CERTIFICATE_REQUEST 13 +#define SSL_HS_SERVER_HELLO_DONE 14 +#define SSL_HS_CERTIFICATE_VERIFY 15 +#define SSL_HS_CLIENT_KEY_EXCHANGE 16 +#define SSL_HS_FINISHED 20 + +/* + * TLS extensions + */ +#define TLS_EXT_SERVERNAME 0 +#define TLS_EXT_SERVERNAME_HOSTNAME 0 + +#define TLS_EXT_MAX_FRAGMENT_LENGTH 1 + +#define TLS_EXT_TRUNCATED_HMAC 4 + +#define TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10 +#define TLS_EXT_SUPPORTED_POINT_FORMATS 11 + +#define TLS_EXT_SIG_ALG 13 + +#define TLS_EXT_ALPN 16 + +#define TLS_EXT_SESSION_TICKET 35 + +#define TLS_EXT_RENEGOTIATION_INFO 0xFF01 + +/* + * TLS extension flags (for extensions with outgoing ServerHello content + * that need it (e.g. for RENEGOTIATION_INFO the server already knows because + * of state of the renegotiation flag, so no indicator is required) + */ +#define TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) + +/* + * Size defines + */ +#if !defined(POLARSSL_PSK_MAX_LEN) +#define POLARSSL_PSK_MAX_LEN 32 /* 256 bits */ +#endif + +/* Dummy type used only for its size */ +union _ssl_premaster_secret +{ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + unsigned char _pms_rsa[48]; /* RFC 5246 8.1.1 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + unsigned char _pms_dhm[POLARSSL_MPI_MAX_SIZE]; /* RFC 5246 8.1.2 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + unsigned char _pms_ecdh[POLARSSL_ECP_MAX_BYTES]; /* RFC 4492 5.10 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + unsigned char _pms_psk[4 + 2 * POLARSSL_PSK_MAX_LEN]; /* RFC 4279 2 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + unsigned char _pms_dhe_psk[4 + POLARSSL_MPI_MAX_SIZE + + POLARSSL_PSK_MAX_LEN]; /* RFC 4279 3 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + unsigned char _pms_rsa_psk[52 + POLARSSL_PSK_MAX_LEN]; /* RFC 4279 4 */ +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + unsigned char _pms_ecdhe_psk[4 + POLARSSL_ECP_MAX_BYTES + + POLARSSL_PSK_MAX_LEN]; /* RFC 5489 2 */ +#endif +}; + +#define POLARSSL_PREMASTER_SIZE sizeof( union _ssl_premaster_secret ) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Generic function pointers for allowing external RSA private key + * implementations. + */ +typedef int (*rsa_decrypt_func)( void *ctx, int mode, size_t *olen, + const unsigned char *input, unsigned char *output, + size_t output_max_len ); +typedef int (*rsa_sign_func)( void *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + int mode, md_type_t md_alg, unsigned int hashlen, + const unsigned char *hash, unsigned char *sig ); +typedef size_t (*rsa_key_len_func)( void *ctx ); + +/* + * SSL state machine + */ +typedef enum +{ + SSL_HELLO_REQUEST, + SSL_CLIENT_HELLO, + SSL_SERVER_HELLO, + SSL_SERVER_CERTIFICATE, + SSL_SERVER_KEY_EXCHANGE, + SSL_CERTIFICATE_REQUEST, + SSL_SERVER_HELLO_DONE, + SSL_CLIENT_CERTIFICATE, + SSL_CLIENT_KEY_EXCHANGE, + SSL_CERTIFICATE_VERIFY, + SSL_CLIENT_CHANGE_CIPHER_SPEC, + SSL_CLIENT_FINISHED, + SSL_SERVER_CHANGE_CIPHER_SPEC, + SSL_SERVER_FINISHED, + SSL_FLUSH_BUFFERS, + SSL_HANDSHAKE_WRAPUP, + SSL_HANDSHAKE_OVER, + SSL_SERVER_NEW_SESSION_TICKET, +} +ssl_states; + +typedef struct _ssl_session ssl_session; +typedef struct _ssl_context ssl_context; +typedef struct _ssl_transform ssl_transform; +typedef struct _ssl_handshake_params ssl_handshake_params; +#if defined(POLARSSL_SSL_SESSION_TICKETS) +typedef struct _ssl_ticket_keys ssl_ticket_keys; +#endif +#if defined(POLARSSL_X509_CRT_PARSE_C) +typedef struct _ssl_key_cert ssl_key_cert; +#endif + +/* + * This structure is used for storing current session data. + */ +struct _ssl_session +{ +#if defined(POLARSSL_HAVE_TIME) + time_t start; /*!< starting time */ +#endif + int ciphersuite; /*!< chosen ciphersuite */ + int compression; /*!< chosen compression */ + size_t length; /*!< session id length */ + unsigned char id[32]; /*!< session identifier */ + unsigned char master[48]; /*!< the master secret */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) + x509_crt *peer_cert; /*!< peer X.509 cert chain */ +#endif /* POLARSSL_X509_CRT_PARSE_C */ + int verify_result; /*!< verification result */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + unsigned char *ticket; /*!< RFC 5077 session ticket */ + size_t ticket_len; /*!< session ticket length */ + uint32_t ticket_lifetime; /*!< ticket lifetime hint */ +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + unsigned char mfl_code; /*!< MaxFragmentLength negotiated by peer */ +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + int trunc_hmac; /*!< flag for truncated hmac activation */ +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ +}; + +/* + * This structure contains a full set of runtime transform parameters + * either in negotiation or active. + */ +struct _ssl_transform +{ + /* + * Session specific crypto layer + */ + const ssl_ciphersuite_t *ciphersuite_info; + /*!< Chosen cipersuite_info */ + unsigned int keylen; /*!< symmetric key length */ + size_t minlen; /*!< min. ciphertext length */ + size_t ivlen; /*!< IV length */ + size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ + size_t maclen; /*!< MAC length */ + + unsigned char iv_enc[16]; /*!< IV (encryption) */ + unsigned char iv_dec[16]; /*!< IV (decryption) */ + +#if defined(POLARSSL_SSL_PROTO_SSL3) + /* Needed only for SSL v3.0 secret */ + unsigned char mac_enc[48]; /*!< SSL v3.0 secret (enc) */ + unsigned char mac_dec[48]; /*!< SSL v3.0 secret (dec) */ +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + + md_context_t md_ctx_enc; /*!< MAC (encryption) */ + md_context_t md_ctx_dec; /*!< MAC (decryption) */ + + cipher_context_t cipher_ctx_enc; /*!< encryption context */ + cipher_context_t cipher_ctx_dec; /*!< decryption context */ + + /* + * Session specific compression layer + */ +#if defined(POLARSSL_ZLIB_SUPPORT) + z_stream ctx_deflate; /*!< compression context */ + z_stream ctx_inflate; /*!< decompression context */ +#endif +}; + +/* + * This structure contains the parameters only needed during handshake. + */ +struct _ssl_handshake_params +{ + /* + * Handshake specific crypto variables + */ + int sig_alg; /*!< Hash algorithm for signature */ + int cert_type; /*!< Requested cert type */ + int verify_sig_alg; /*!< Signature algorithm for verify */ +#if defined(POLARSSL_DHM_C) + dhm_context dhm_ctx; /*!< DHM key exchange */ +#endif +#if defined(POLARSSL_ECDH_C) + ecdh_context ecdh_ctx; /*!< ECDH key exchange */ +#endif +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + const ecp_curve_info **curves; /*!< Supported elliptic curves */ +#endif +#if defined(POLARSSL_X509_CRT_PARSE_C) + /** + * Current key/cert or key/cert list. + * On client: pointer to ssl->key_cert, only the first entry used. + * On server: starts as a pointer to ssl->key_cert, then becomes + * a pointer to the chosen key from this list or the SNI list. + */ + ssl_key_cert *key_cert; +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ +#endif +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + /* + * Checksum contexts + */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + md5_context fin_md5; + sha1_context fin_sha1; +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) + sha256_context fin_sha256; +#endif +#if defined(POLARSSL_SHA512_C) + sha512_context fin_sha512; +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + void (*update_checksum)(ssl_context *, const unsigned char *, size_t); + void (*calc_verify)(ssl_context *, unsigned char *); + void (*calc_finished)(ssl_context *, unsigned char *, int); + int (*tls_prf)(const unsigned char *, size_t, const char *, + const unsigned char *, size_t, + unsigned char *, size_t); + + size_t pmslen; /*!< premaster length */ + + unsigned char randbytes[64]; /*!< random bytes */ + unsigned char premaster[POLARSSL_PREMASTER_SIZE]; + /*!< premaster secret */ + + int resume; /*!< session resume indicator*/ + int max_major_ver; /*!< max. major version client*/ + int max_minor_ver; /*!< max. minor version client*/ + int cli_exts; /*!< client extension presence*/ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + int new_session_ticket; /*!< use NewSessionTicket? */ +#endif /* POLARSSL_SSL_SESSION_TICKETS */ +}; + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +/* + * Parameters needed to secure session tickets + */ +struct _ssl_ticket_keys +{ + unsigned char key_name[16]; /*!< name to quickly discard bad tickets */ + aes_context enc; /*!< encryption context */ + aes_context dec; /*!< decryption context */ + unsigned char mac_key[16]; /*!< authentication key */ +}; +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/* + * List of certificate + private key pairs + */ +struct _ssl_key_cert +{ + x509_crt *cert; /*!< cert */ + pk_context *key; /*!< private key */ + int key_own_alloc; /*!< did we allocate key? */ + ssl_key_cert *next; /*!< next key/cert pair */ +}; +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +struct _ssl_context +{ + /* + * Miscellaneous + */ + int state; /*!< SSL handshake: current state */ + int renegotiation; /*!< Initial or renegotiation */ + int renego_records_seen; /*!< Records since renego request */ + + int major_ver; /*!< equal to SSL_MAJOR_VERSION_3 */ + int minor_ver; /*!< either 0 (SSL3) or 1 (TLS1.0) */ + + int max_major_ver; /*!< max. major version used */ + int max_minor_ver; /*!< max. minor version used */ + int min_major_ver; /*!< min. major version used */ + int min_minor_ver; /*!< min. minor version used */ + + /* + * Callbacks (RNG, debug, I/O, verification) + */ + int (*f_rng)(void *, unsigned char *, size_t); + void (*f_dbg)(void *, int, const char *); + int (*f_recv)(void *, unsigned char *, size_t); + int (*f_send)(void *, const unsigned char *, size_t); + int (*f_get_cache)(void *, ssl_session *); + int (*f_set_cache)(void *, const ssl_session *); + + void *p_rng; /*!< context for the RNG function */ + void *p_dbg; /*!< context for the debug function */ + void *p_recv; /*!< context for reading operations */ + void *p_send; /*!< context for writing operations */ + void *p_get_cache; /*!< context for cache retrieval */ + void *p_set_cache; /*!< context for cache store */ + void *p_hw_data; /*!< context for HW acceleration */ + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + int (*f_sni)(void *, ssl_context *, const unsigned char *, size_t); + void *p_sni; /*!< context for SNI extension */ +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) + int (*f_vrfy)(void *, x509_crt *, int, int *); + void *p_vrfy; /*!< context for verification */ +#endif + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + int (*f_psk)(void *, ssl_context *, const unsigned char *, size_t); + void *p_psk; /*!< context for PSK retrieval */ +#endif + + /* + * Session layer + */ + ssl_session *session_in; /*!< current session data (in) */ + ssl_session *session_out; /*!< current session data (out) */ + ssl_session *session; /*!< negotiated session data */ + ssl_session *session_negotiate; /*!< session data in negotiation */ + + ssl_handshake_params *handshake; /*!< params required only during + the handshake process */ + + /* + * Record layer transformations + */ + ssl_transform *transform_in; /*!< current transform params (in) */ + ssl_transform *transform_out; /*!< current transform params (in) */ + ssl_transform *transform; /*!< negotiated transform params */ + ssl_transform *transform_negotiate; /*!< transform params in negotiation */ + + /* + * Record layer (incoming data) + */ + unsigned char *in_ctr; /*!< 64-bit incoming message counter */ + unsigned char *in_hdr; /*!< 5-byte record header (in_ctr+8) */ + unsigned char *in_iv; /*!< ivlen-byte IV (in_hdr+5) */ + unsigned char *in_msg; /*!< message contents (in_iv+ivlen) */ + unsigned char *in_offt; /*!< read offset in application data */ + + int in_msgtype; /*!< record header: message type */ + size_t in_msglen; /*!< record header: message length */ + size_t in_left; /*!< amount of data read so far */ + + size_t in_hslen; /*!< current handshake message length */ + int nb_zero; /*!< # of 0-length encrypted messages */ + int record_read; /*!< record is already present */ + + /* + * Record layer (outgoing data) + */ + unsigned char *out_ctr; /*!< 64-bit outgoing message counter */ + unsigned char *out_hdr; /*!< 5-byte record header (out_ctr+8) */ + unsigned char *out_iv; /*!< ivlen-byte IV (out_hdr+5) */ + unsigned char *out_msg; /*!< message contents (out_iv+ivlen) */ + + int out_msgtype; /*!< record header: message type */ + size_t out_msglen; /*!< record header: message length */ + size_t out_left; /*!< amount of data not yet written */ + +#if defined(POLARSSL_ZLIB_SUPPORT) + unsigned char *compress_buf; /*!< zlib data buffer */ +#endif +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + unsigned char mfl_code; /*!< MaxFragmentLength chosen by us */ +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + + /* + * PKI layer + */ +#if defined(POLARSSL_X509_CRT_PARSE_C) + ssl_key_cert *key_cert; /*!< own certificate(s)/key(s) */ + + x509_crt *ca_chain; /*!< own trusted CA chain */ + x509_crl *ca_crl; /*!< trusted CA CRLs */ + const char *peer_cn; /*!< expected peer CN */ +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + /* + * Support for generating and checking session tickets + */ +#if defined(POLARSSL_SSL_SESSION_TICKETS) + ssl_ticket_keys *ticket_keys; /*!< keys for ticket encryption */ +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + + /* + * User settings + */ + int endpoint; /*!< 0: client, 1: server */ + int authmode; /*!< verification mode */ + int client_auth; /*!< flag for client auth. */ + int verify_result; /*!< verification result */ + int disable_renegotiation; /*!< enable/disable renegotiation */ + int allow_legacy_renegotiation; /*!< allow legacy renegotiation */ + int renego_max_records; /*!< grace period for renegotiation */ + const int *ciphersuite_list[4]; /*!< allowed ciphersuites / version */ +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *curve_list; /*!< allowed curves */ +#endif +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + int trunc_hmac; /*!< negotiate truncated hmac? */ +#endif +#if defined(POLARSSL_SSL_SESSION_TICKETS) + int session_tickets; /*!< use session tickets? */ + int ticket_lifetime; /*!< session ticket lifetime */ +#endif + +#if defined(POLARSSL_DHM_C) + mpi dhm_P; /*!< prime modulus for DHM */ + mpi dhm_G; /*!< generator for DHM */ +#endif + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + /* + * PSK values + */ + unsigned char *psk; + size_t psk_len; + unsigned char *psk_identity; + size_t psk_identity_len; +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + /* + * SNI extension + */ + unsigned char *hostname; + size_t hostname_len; +#endif + +#if defined(POLARSSL_SSL_ALPN) + /* + * ALPN extension + */ + const char **alpn_list; /*!< ordered list of supported protocols */ + const char *alpn_chosen; /*!< negotiated protocol */ +#endif + + /* + * Secure renegotiation + */ + int secure_renegotiation; /*!< does peer support legacy or + secure renegotiation */ + size_t verify_data_len; /*!< length of verify data stored */ + char own_verify_data[36]; /*!< previous handshake verify data */ + char peer_verify_data[36]; /*!< previous handshake verify data */ +}; + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + +#define SSL_CHANNEL_OUTBOUND 0 +#define SSL_CHANNEL_INBOUND 1 + +extern int (*ssl_hw_record_init)(ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + size_t keylen, + const unsigned char *iv_enc, const unsigned char *iv_dec, + size_t ivlen, + const unsigned char *mac_enc, const unsigned char *mac_dec, + size_t maclen); +extern int (*ssl_hw_record_activate)(ssl_context *ssl, int direction); +extern int (*ssl_hw_record_reset)(ssl_context *ssl); +extern int (*ssl_hw_record_write)(ssl_context *ssl); +extern int (*ssl_hw_record_read)(ssl_context *ssl); +extern int (*ssl_hw_record_finish)(ssl_context *ssl); +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ + +/** + * \brief Returns the list of ciphersuites supported by the SSL/TLS module. + * + * \return a statically allocated array of ciphersuites, the last + * entry is 0. + */ +const int *ssl_list_ciphersuites( void ); + +/** + * \brief Return the name of the ciphersuite associated with the + * given ID + * + * \param ciphersuite_id SSL ciphersuite ID + * + * \return a string containing the ciphersuite name + */ +const char *ssl_get_ciphersuite_name( const int ciphersuite_id ); + +/** + * \brief Return the ID of the ciphersuite associated with the + * given name + * + * \param ciphersuite_name SSL ciphersuite name + * + * \return the ID with the ciphersuite or 0 if not found + */ +int ssl_get_ciphersuite_id( const char *ciphersuite_name ); + +/** + * \brief Initialize an SSL context + * (An individual SSL context is not thread-safe) + * + * \param ssl SSL context + * + * \return 0 if successful, or POLARSSL_ERR_SSL_MALLOC_FAILED if + * memory allocation failed + */ +int ssl_init( ssl_context *ssl ); + +/** + * \brief Reset an already initialized SSL context for re-use + * while retaining application-set variables, function + * pointers and data. + * + * \param ssl SSL context + * \return 0 if successful, or POLASSL_ERR_SSL_MALLOC_FAILED, + POLARSSL_ERR_SSL_HW_ACCEL_FAILED or + * POLARSSL_ERR_SSL_COMPRESSION_FAILED + */ +int ssl_session_reset( ssl_context *ssl ); + +/** + * \brief Set the current endpoint type + * + * \param ssl SSL context + * \param endpoint must be SSL_IS_CLIENT or SSL_IS_SERVER + * + * \note This function should be called right after ssl_init() since + * some other ssl_set_foo() functions depend on it. + */ +void ssl_set_endpoint( ssl_context *ssl, int endpoint ); + +/** + * \brief Set the certificate verification mode + * + * \param ssl SSL context + * \param authmode can be: + * + * SSL_VERIFY_NONE: peer certificate is not checked (default), + * this is insecure and SHOULD be avoided. + * + * SSL_VERIFY_OPTIONAL: peer certificate is checked, however the + * handshake continues even if verification failed; + * ssl_get_verify_result() can be called after the + * handshake is complete. + * + * SSL_VERIFY_REQUIRED: peer *must* present a valid certificate, + * handshake is aborted if verification failed. + * + * \note On client, SSL_VERIFY_REQUIRED is the recommended mode. + * With SSL_VERIFY_OPTIONAL, the user needs to call ssl_get_verify_result() at + * the right time(s), which may not be obvious, while REQUIRED always perform + * the verification as soon as possible. For example, REQUIRED was protecting + * against the "triple handshake" attack even before it was found. + */ +void ssl_set_authmode( ssl_context *ssl, int authmode ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/** + * \brief Set the verification callback (Optional). + * + * If set, the verify callback is called for each + * certificate in the chain. For implementation + * information, please see \c x509parse_verify() + * + * \param ssl SSL context + * \param f_vrfy verification function + * \param p_vrfy verification parameter + */ +void ssl_set_verify( ssl_context *ssl, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/** + * \brief Set the random number generator callback + * + * \param ssl SSL context + * \param f_rng RNG function + * \param p_rng RNG parameter + */ +void ssl_set_rng( ssl_context *ssl, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +/** + * \brief Set the debug callback + * + * \param ssl SSL context + * \param f_dbg debug function + * \param p_dbg debug parameter + */ +void ssl_set_dbg( ssl_context *ssl, + void (*f_dbg)(void *, int, const char *), + void *p_dbg ); + +/** + * \brief Set the underlying BIO read and write callbacks + * + * \param ssl SSL context + * \param f_recv read callback + * \param p_recv read parameter + * \param f_send write callback + * \param p_send write parameter + */ +void ssl_set_bio( ssl_context *ssl, + int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, + int (*f_send)(void *, const unsigned char *, size_t), void *p_send ); + +/** + * \brief Set the session cache callbacks (server-side only) + * If not set, no session resuming is done. + * + * The session cache has the responsibility to check for stale + * entries based on timeout. See RFC 5246 for recommendations. + * + * Warning: session.peer_cert is cleared by the SSL/TLS layer on + * connection shutdown, so do not cache the pointer! Either set + * it to NULL or make a full copy of the certificate. + * + * The get callback is called once during the initial handshake + * to enable session resuming. The get function has the + * following parameters: (void *parameter, ssl_session *session) + * If a valid entry is found, it should fill the master of + * the session object with the cached values and return 0, + * return 1 otherwise. Optionally peer_cert can be set as well + * if it is properly present in cache entry. + * + * The set callback is called once during the initial handshake + * to enable session resuming after the entire handshake has + * been finished. The set function has the following parameters: + * (void *parameter, const ssl_session *session). The function + * should create a cache entry for future retrieval based on + * the data in the session structure and should keep in mind + * that the ssl_session object presented (and all its referenced + * data) is cleared by the SSL/TLS layer when the connection is + * terminated. It is recommended to add metadata to determine if + * an entry is still valid in the future. Return 0 if + * successfully cached, return 1 otherwise. + * + * \param ssl SSL context + * \param f_get_cache session get callback + * \param p_get_cache session get parameter + * \param f_set_cache session set callback + * \param p_set_cache session set parameter + */ +void ssl_set_session_cache( ssl_context *ssl, + int (*f_get_cache)(void *, ssl_session *), void *p_get_cache, + int (*f_set_cache)(void *, const ssl_session *), void *p_set_cache ); + +/** + * \brief Request resumption of session (client-side only) + * Session data is copied from presented session structure. + * + * \param ssl SSL context + * \param session session context + * + * \return 0 if successful, + * POLARSSL_ERR_SSL_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side or + * arguments are otherwise invalid + * + * \sa ssl_get_session() + */ +int ssl_set_session( ssl_context *ssl, const ssl_session *session ); + +/** + * \brief Set the list of allowed ciphersuites and the preference + * order. First in the list has the highest preference. + * (Overrides all version specific lists) + * + * Note: The PolarSSL SSL server uses its own preferences + * over the preference of the connection SSL client unless + * POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE is defined! + * + * \param ssl SSL context + * \param ciphersuites 0-terminated list of allowed ciphersuites + */ +void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites ); + +/** + * \brief Set the list of allowed ciphersuites and the + * preference order for a specific version of the protocol. + * (Only useful on the server side) + * + * \param ssl SSL context + * \param ciphersuites 0-terminated list of allowed ciphersuites + * \param major Major version number (only SSL_MAJOR_VERSION_3 + * supported) + * \param minor Minor version number (SSL_MINOR_VERSION_0, + * SSL_MINOR_VERSION_1 and SSL_MINOR_VERSION_2, + * SSL_MINOR_VERSION_3 supported) + */ +void ssl_set_ciphersuites_for_version( ssl_context *ssl, + const int *ciphersuites, + int major, int minor ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/** + * \brief Set the data required to verify peer certificate + * + * \param ssl SSL context + * \param ca_chain trusted CA chain (meaning all fully trusted top-level CAs) + * \param ca_crl trusted CA CRLs + * \param peer_cn expected peer CommonName (or NULL) + */ +void ssl_set_ca_chain( ssl_context *ssl, x509_crt *ca_chain, + x509_crl *ca_crl, const char *peer_cn ); + +/** + * \brief Set own certificate chain and private key + * + * \note own_cert should contain in order from the bottom up your + * certificate chain. The top certificate (self-signed) + * can be omitted. + * + * \note This function may be called more than once if you want to + * support multiple certificates (eg, one using RSA and one + * using ECDSA). However, on client, currently only the first + * certificate is used (subsequent calls have no effect). + * + * \param ssl SSL context + * \param own_cert own public certificate chain + * \param pk_key own private key + * + * \return 0 on success or POLARSSL_ERR_SSL_MALLOC_FAILED + */ +int ssl_set_own_cert( ssl_context *ssl, x509_crt *own_cert, + pk_context *pk_key ); + +#if defined(POLARSSL_RSA_C) +/** + * \brief Set own certificate chain and private RSA key + * + * Note: own_cert should contain IN order from the bottom + * up your certificate chain. The top certificate (self-signed) + * can be omitted. + * + * \warning This backwards-compatibility function is deprecated! + * Please use \c ssl_set_own_cert() instead. + * + * \param ssl SSL context + * \param own_cert own public certificate chain + * \param rsa_key own private RSA key + * + * \return 0 on success, or a specific error code. + */ +int ssl_set_own_cert_rsa( ssl_context *ssl, x509_crt *own_cert, + rsa_context *rsa_key ); +#endif /* POLARSSL_RSA_C */ + +/** + * \brief Set own certificate and alternate non-PolarSSL RSA private + * key and handling callbacks, such as the PKCS#11 wrappers + * or any other external private key handler. + * (see the respective RSA functions in rsa.h for documentation + * of the callback parameters, with the only change being + * that the rsa_context * is a void * in the callbacks) + * + * Note: own_cert should contain IN order from the bottom + * up your certificate chain. The top certificate (self-signed) + * can be omitted. + * + * \warning This backwards-compatibility function is deprecated! + * Please use \c pk_init_ctx_rsa_alt() + * and \c ssl_set_own_cert() instead. + * + * \param ssl SSL context + * \param own_cert own public certificate chain + * \param rsa_key alternate implementation private RSA key + * \param rsa_decrypt alternate implementation of \c rsa_pkcs1_decrypt() + * \param rsa_sign alternate implementation of \c rsa_pkcs1_sign() + * \param rsa_key_len function returning length of RSA key in bytes + * + * \return 0 on success, or a specific error code. + */ +int ssl_set_own_cert_alt( ssl_context *ssl, x509_crt *own_cert, + void *rsa_key, + rsa_decrypt_func rsa_decrypt, + rsa_sign_func rsa_sign, + rsa_key_len_func rsa_key_len ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +/** + * \brief Set the Pre Shared Key (PSK) and the identity name connected + * to it. + * + * \param ssl SSL context + * \param psk pointer to the pre-shared key + * \param psk_len pre-shared key length + * \param psk_identity pointer to the pre-shared key identity + * \param psk_identity_len identity key length + * + * \return 0 if successful or POLARSSL_ERR_SSL_MALLOC_FAILED + */ +int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, + const unsigned char *psk_identity, size_t psk_identity_len ); + +/** + * \brief Set the PSK callback (server-side only) (Optional). + * + * If set, the PSK callback is called for each + * handshake where a PSK ciphersuite was negotiated. + * The caller provides the identity received and wants to + * receive the actual PSK data and length. + * + * The callback has the following parameters: (void *parameter, + * ssl_context *ssl, const unsigned char *psk_identity, + * size_t identity_len) + * If a valid PSK identity is found, the callback should use + * ssl_set_psk() on the ssl context to set the correct PSK and + * identity and return 0. + * Any other return value will result in a denied PSK identity. + * + * \param ssl SSL context + * \param f_psk PSK identity function + * \param p_psk PSK identity parameter + */ +void ssl_set_psk_cb( ssl_context *ssl, + int (*f_psk)(void *, ssl_context *, const unsigned char *, + size_t), + void *p_psk ); +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(POLARSSL_DHM_C) +/** + * \brief Set the Diffie-Hellman public P and G values, + * read as hexadecimal strings (server-side only) + * (Default: POLARSSL_DHM_RFC5114_MODP_1024_[PG]) + * + * \param ssl SSL context + * \param dhm_P Diffie-Hellman-Merkle modulus + * \param dhm_G Diffie-Hellman-Merkle generator + * + * \return 0 if successful + */ +int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G ); + +/** + * \brief Set the Diffie-Hellman public P and G values, + * read from existing context (server-side only) + * + * \param ssl SSL context + * \param dhm_ctx Diffie-Hellman-Merkle context + * + * \return 0 if successful + */ +int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx ); +#endif /* POLARSSL_DHM_C */ + +#if defined(POLARSSL_SSL_SET_CURVES) +/** + * \brief Set the allowed curves in order of preference. + * (Default: all defined curves.) + * + * On server: this only affects selection of the ECDHE curve; + * the curves used for ECDH and ECDSA are determined by the + * list of available certificates instead. + * + * On client: this affects the list of curves offered for any + * use. The server can override our preference order. + * + * Both sides: limits the set of curves used by peer to the + * listed curves for any use (ECDH(E), certificates). + * + * \param ssl SSL context + * \param curves Ordered list of allowed curves, + * terminated by POLARSSL_ECP_DP_NONE. + */ +void ssl_set_curves( ssl_context *ssl, const ecp_group_id *curves ); +#endif /* POLARSSL_SSL_SET_CURVES */ + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) +/** + * \brief Set hostname for ServerName TLS extension + * (client-side only) + * + * + * \param ssl SSL context + * \param hostname the server hostname + * + * \return 0 if successful or POLARSSL_ERR_SSL_MALLOC_FAILED + */ +int ssl_set_hostname( ssl_context *ssl, const char *hostname ); + +/** + * \brief Set server side ServerName TLS extension callback + * (optional, server-side only). + * + * If set, the ServerName callback is called whenever the + * server receives a ServerName TLS extension from the client + * during a handshake. The ServerName callback has the + * following parameters: (void *parameter, ssl_context *ssl, + * const unsigned char *hostname, size_t len). If a suitable + * certificate is found, the callback should set the + * certificate and key to use with ssl_set_own_cert() (and + * possibly adjust the CA chain as well) and return 0. The + * callback should return -1 to abort the handshake at this + * point. + * + * \param ssl SSL context + * \param f_sni verification function + * \param p_sni verification parameter + */ +void ssl_set_sni( ssl_context *ssl, + int (*f_sni)(void *, ssl_context *, const unsigned char *, + size_t), + void *p_sni ); +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ + +#if defined(POLARSSL_SSL_ALPN) +/** + * \brief Set the supported Application Layer Protocols. + * + * \param ssl SSL context + * \param protos NULL-terminated list of supported protocols, + * in decreasing preference order. + * + * \return 0 on success, or POLARSSL_ERR_SSL_BAD_INPUT_DATA. + */ +int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos ); + +/** + * \brief Get the name of the negotiated Application Layer Protocol. + * This function should be called after the handshake is + * completed. + * + * \param ssl SSL context + * + * \return Protcol name, or NULL if no protocol was negotiated. + */ +const char *ssl_get_alpn_protocol( const ssl_context *ssl ); +#endif /* POLARSSL_SSL_ALPN */ + +/** + * \brief Set the maximum supported version sent from the client side + * and/or accepted at the server side + * (Default: SSL_MAX_MAJOR_VERSION, SSL_MAX_MINOR_VERSION) + * + * Note: This ignores ciphersuites from 'higher' versions. + * Note: Input outside of the SSL_MAX_XXXXX_VERSION and + * SSL_MIN_XXXXX_VERSION range is ignored. + * + * \param ssl SSL context + * \param major Major version number (only SSL_MAJOR_VERSION_3 supported) + * \param minor Minor version number (SSL_MINOR_VERSION_0, + * SSL_MINOR_VERSION_1 and SSL_MINOR_VERSION_2, + * SSL_MINOR_VERSION_3 supported) + */ +void ssl_set_max_version( ssl_context *ssl, int major, int minor ); + + +/** + * \brief Set the minimum accepted SSL/TLS protocol version + * (Default: SSL_MIN_MAJOR_VERSION, SSL_MIN_MINOR_VERSION) + * + * Note: Input outside of the SSL_MAX_XXXXX_VERSION and + * SSL_MIN_XXXXX_VERSION range is ignored. + * + * \param ssl SSL context + * \param major Major version number (only SSL_MAJOR_VERSION_3 supported) + * \param minor Minor version number (SSL_MINOR_VERSION_0, + * SSL_MINOR_VERSION_1 and SSL_MINOR_VERSION_2, + * SSL_MINOR_VERSION_3 supported) + */ +void ssl_set_min_version( ssl_context *ssl, int major, int minor ); + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +/** + * \brief Set the maximum fragment length to emit and/or negotiate + * (Default: SSL_MAX_CONTENT_LEN, usually 2^14 bytes) + * (Server: set maximum fragment length to emit, + * usually negotiated by the client during handshake + * (Client: set maximum fragment length to emit *and* + * negotiate with the server during handshake) + * + * \param ssl SSL context + * \param mfl_code Code for maximum fragment length (allowed values: + * SSL_MAX_FRAG_LEN_512, SSL_MAX_FRAG_LEN_1024, + * SSL_MAX_FRAG_LEN_2048, SSL_MAX_FRAG_LEN_4096) + * + * \return O if successful or POLARSSL_ERR_SSL_BAD_INPUT_DATA + */ +int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ); +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +/** + * \brief Activate negotiation of truncated HMAC (Client only) + * (Default: SSL_TRUNC_HMAC_ENABLED) + * + * \param ssl SSL context + * \param truncate Enable or disable (SSL_TRUNC_HMAC_ENABLED or + * SSL_TRUNC_HMAC_DISABLED) + * + * \return O if successful, + * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side + */ +int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ); +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +/** + * \brief Enable / Disable session tickets + * (Default: SSL_SESSION_TICKETS_ENABLED on client, + * SSL_SESSION_TICKETS_DISABLED on server) + * + * \note On server, ssl_set_rng() must be called before this function + * to allow generating the ticket encryption and + * authentication keys. + * + * \param ssl SSL context + * \param use_tickets Enable or disable (SSL_SESSION_TICKETS_ENABLED or + * SSL_SESSION_TICKETS_DISABLED) + * + * \return O if successful, + * or a specific error code (server only). + */ +int ssl_set_session_tickets( ssl_context *ssl, int use_tickets ); + +/** + * \brief Set session ticket lifetime (server only) + * (Default: SSL_DEFAULT_TICKET_LIFETIME (86400 secs / 1 day)) + * + * \param ssl SSL context + * \param lifetime session ticket lifetime + */ +void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime ); +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +/** + * \brief Enable / Disable renegotiation support for connection when + * initiated by peer + * (Default: SSL_RENEGOTIATION_DISABLED) + * + * Note: A server with support enabled is more vulnerable for a + * resource DoS by a malicious client. You should enable this on + * a client to enable server-initiated renegotiation. + * + * \param ssl SSL context + * \param renegotiation Enable or disable (SSL_RENEGOTIATION_ENABLED or + * SSL_RENEGOTIATION_DISABLED) + */ +void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ); + +/** + * \brief Prevent or allow legacy renegotiation. + * (Default: SSL_LEGACY_NO_RENEGOTIATION) + * + * SSL_LEGACY_NO_RENEGOTIATION allows connections to + * be established even if the peer does not support + * secure renegotiation, but does not allow renegotiation + * to take place if not secure. + * (Interoperable and secure option) + * + * SSL_LEGACY_ALLOW_RENEGOTIATION allows renegotiations + * with non-upgraded peers. Allowing legacy renegotiation + * makes the connection vulnerable to specific man in the + * middle attacks. (See RFC 5746) + * (Most interoperable and least secure option) + * + * SSL_LEGACY_BREAK_HANDSHAKE breaks off connections + * if peer does not support secure renegotiation. Results + * in interoperability issues with non-upgraded peers + * that do not support renegotiation altogether. + * (Most secure option, interoperability issues) + * + * \param ssl SSL context + * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, + * SSL_ALLOW_LEGACY_RENEGOTIATION or + * SSL_LEGACY_BREAK_HANDSHAKE) + */ +void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ); + +/** + * \brief Enforce server-requested renegotiation. + * (Default: enforced, max_records = 16) + * (No effect on client.) + * + * When a server requests a renegotiation, the client can + * comply or ignore the request. This function allows the + * server to decide if it should enforce its renegotiation + * requests by closing the connection if the client doesn't + * initiate a renegotiation. + * + * However, records could already be in transit from the + * client to the server when the request is emitted. In order + * to increase reliability, the server can accept a number of + * records containing application data before the ClientHello + * that was requested. + * + * The optimal value is highly dependent on the specific usage + * scenario. + * + * \param ssl SSL context + * \param max_records Use SSL_RENEGOTIATION_NOT_ENFORCED if you don't want to + * enforce renegotiation, or a non-negative value to enforce + * it but allow for a grace period of max_records records. + */ +void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records ); + +/** + * \brief Return the number of data bytes available to read + * + * \param ssl SSL context + * + * \return how many bytes are available in the read buffer + */ +size_t ssl_get_bytes_avail( const ssl_context *ssl ); + +/** + * \brief Return the result of the certificate verification + * + * \param ssl SSL context + * + * \return 0 if successful, or a combination of: + * BADCERT_EXPIRED + * BADCERT_REVOKED + * BADCERT_CN_MISMATCH + * BADCERT_NOT_TRUSTED + */ +int ssl_get_verify_result( const ssl_context *ssl ); + +/** + * \brief Return the name of the current ciphersuite + * + * \param ssl SSL context + * + * \return a string containing the ciphersuite name + */ +const char *ssl_get_ciphersuite( const ssl_context *ssl ); + +/** + * \brief Return the current SSL version (SSLv3/TLSv1/etc) + * + * \param ssl SSL context + * + * \return a string containing the SSL version + */ +const char *ssl_get_version( const ssl_context *ssl ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/** + * \brief Return the peer certificate from the current connection + * + * Note: Can be NULL in case no certificate was sent during + * the handshake. Different calls for the same connection can + * return the same or different pointers for the same + * certificate and even a different certificate altogether. + * The peer cert CAN change in a single connection if + * renegotiation is performed. + * + * \param ssl SSL context + * + * \return the current peer certificate + */ +const x509_crt *ssl_get_peer_cert( const ssl_context *ssl ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/** + * \brief Save session in order to resume it later (client-side only) + * Session data is copied to presented session structure. + * + * \warning Currently, peer certificate is lost in the operation. + * + * \param ssl SSL context + * \param session session context + * + * \return 0 if successful, + * POLARSSL_ERR_SSL_MALLOC_FAILED if memory allocation failed, + * POLARSSL_ERR_SSL_BAD_INPUT_DATA if used server-side or + * arguments are otherwise invalid + * + * \sa ssl_set_session() + */ +int ssl_get_session( const ssl_context *ssl, ssl_session *session ); + +/** + * \brief Perform the SSL handshake + * + * \param ssl SSL context + * + * \return 0 if successful, POLARSSL_ERR_NET_WANT_READ, + * POLARSSL_ERR_NET_WANT_WRITE, or a specific SSL error code. + */ +int ssl_handshake( ssl_context *ssl ); + +/** + * \brief Perform a single step of the SSL handshake + * + * Note: the state of the context (ssl->state) will be at + * the following state after execution of this function. + * Do not call this function if state is SSL_HANDSHAKE_OVER. + * + * \param ssl SSL context + * + * \return 0 if successful, POLARSSL_ERR_NET_WANT_READ, + * POLARSSL_ERR_NET_WANT_WRITE, or a specific SSL error code. + */ +int ssl_handshake_step( ssl_context *ssl ); + +/** + * \brief Initiate an SSL renegotiation on the running connection. + * Client: perform the renegotiation right now. + * Server: request renegotiation, which will be performed + * during the next call to ssl_read() if honored by client. + * + * \param ssl SSL context + * + * \return 0 if successful, or any ssl_handshake() return value. + */ +int ssl_renegotiate( ssl_context *ssl ); + +/** + * \brief Read at most 'len' application data bytes + * + * \param ssl SSL context + * \param buf buffer that will hold the data + * \param len how many bytes must be read + * + * \return This function returns the number of bytes read, 0 for EOF, + * or a negative error code. + */ +int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ); + +/** + * \brief Write exactly 'len' application data bytes + * + * \param ssl SSL context + * \param buf buffer holding the data + * \param len how many bytes must be written + * + * \return This function returns the number of bytes written, + * or a negative error code. + * + * \note When this function returns POLARSSL_ERR_NET_WANT_WRITE, + * it must be called later with the *same* arguments, + * until it returns a positive value. + */ +int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len ); + +/** + * \brief Send an alert message + * + * \param ssl SSL context + * \param level The alert level of the message + * (SSL_ALERT_LEVEL_WARNING or SSL_ALERT_LEVEL_FATAL) + * \param message The alert message (SSL_ALERT_MSG_*) + * + * \return 0 if successful, or a specific SSL error code. + */ +int ssl_send_alert_message( ssl_context *ssl, + unsigned char level, + unsigned char message ); +/** + * \brief Notify the peer that the connection is being closed + * + * \param ssl SSL context + */ +int ssl_close_notify( ssl_context *ssl ); + +/** + * \brief Free referenced items in an SSL context and clear memory + * + * \param ssl SSL context + */ +void ssl_free( ssl_context *ssl ); + +/** + * \brief Initialize SSL session structure + * + * \param session SSL session + */ +void ssl_session_init( ssl_session *session ); + +/** + * \brief Free referenced items in an SSL session including the + * peer certificate and clear memory + * + * \param session SSL session + */ +void ssl_session_free( ssl_session *session ); + +/** + * \brief Free referenced items in an SSL transform context and clear + * memory + * + * \param transform SSL transform context + */ +void ssl_transform_free( ssl_transform *transform ); + +/** + * \brief Free referenced items in an SSL handshake context and clear + * memory + * + * \param handshake SSL handshake context + */ +void ssl_handshake_free( ssl_handshake_params *handshake ); + +/* + * Internal functions (do not call directly) + */ +int ssl_handshake_client_step( ssl_context *ssl ); +int ssl_handshake_server_step( ssl_context *ssl ); +void ssl_handshake_wrapup( ssl_context *ssl ); + +int ssl_send_fatal_handshake_failure( ssl_context *ssl ); + +int ssl_derive_keys( ssl_context *ssl ); + +int ssl_read_record( ssl_context *ssl ); +/** + * \return 0 if successful, POLARSSL_ERR_SSL_CONN_EOF on EOF or + * another negative error code. + */ +int ssl_fetch_input( ssl_context *ssl, size_t nb_want ); + +int ssl_write_record( ssl_context *ssl ); +int ssl_flush_output( ssl_context *ssl ); + +int ssl_parse_certificate( ssl_context *ssl ); +int ssl_write_certificate( ssl_context *ssl ); + +int ssl_parse_change_cipher_spec( ssl_context *ssl ); +int ssl_write_change_cipher_spec( ssl_context *ssl ); + +int ssl_parse_finished( ssl_context *ssl ); +int ssl_write_finished( ssl_context *ssl ); + +void ssl_optimize_checksum( ssl_context *ssl, + const ssl_ciphersuite_t *ciphersuite_info ); + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ); +#endif + +#if defined(POLARSSL_PK_C) +unsigned char ssl_sig_from_pk( pk_context *pk ); +pk_type_t ssl_pk_alg_from_sig( unsigned char sig ); +#endif + +md_type_t ssl_md_alg_from_hash( unsigned char hash ); + +#if defined(POLARSSL_SSL_SET_CURVES) +int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) +static inline pk_context *ssl_own_key( ssl_context *ssl ) +{ + return( ssl->handshake->key_cert == NULL ? NULL + : ssl->handshake->key_cert->key ); +} + +static inline x509_crt *ssl_own_cert( ssl_context *ssl ) +{ + return( ssl->handshake->key_cert == NULL ? NULL + : ssl->handshake->key_cert->cert ); +} + +/* + * Check usage of a certificate wrt extensions: + * keyUsage, extendedKeyUsage (later), and nSCertType (later). + * + * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we + * check a cert we received from them)! + * + * Return 0 if everything is OK, -1 if not. + */ +int ssl_check_cert_usage( const x509_crt *cert, + const ssl_ciphersuite_t *ciphersuite, + int cert_endpoint ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/* constant-time buffer comparison */ +static inline int safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + const unsigned char *A = (const unsigned char *) a; + const unsigned char *B = (const unsigned char *) b; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= A[i] ^ B[i]; + + return( diff ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* ssl.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_cache.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_cache.h new file mode 100644 index 0000000..918fb60 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_cache.h @@ -0,0 +1,147 @@ +/** + * \file ssl_cache.h + * + * \brief SSL session cache implementation + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SSL_CACHE_H +#define POLARSSL_SSL_CACHE_H + +#include "ssl.h" + +#if defined(POLARSSL_THREADING_C) +#include "threading.h" +#endif + +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h or define them on the compiler command line. + * \{ + */ + +#if !defined(SSL_CACHE_DEFAULT_TIMEOUT) +#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /*!< 1 day */ +#endif + +#if !defined(SSL_CACHE_DEFAULT_MAX_ENTRIES) +#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /*!< Maximum entries in cache */ +#endif + +/* \} name SECTION: Module settings */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _ssl_cache_context ssl_cache_context; +typedef struct _ssl_cache_entry ssl_cache_entry; + +/** + * \brief This structure is used for storing cache entries + */ +struct _ssl_cache_entry +{ +#if defined(POLARSSL_HAVE_TIME) + time_t timestamp; /*!< entry timestamp */ +#endif + ssl_session session; /*!< entry session */ +#if defined(POLARSSL_X509_CRT_PARSE_C) + x509_buf peer_cert; /*!< entry peer_cert */ +#endif + ssl_cache_entry *next; /*!< chain pointer */ +}; + +/** + * \brief Cache context + */ +struct _ssl_cache_context +{ + ssl_cache_entry *chain; /*!< start of the chain */ + int timeout; /*!< cache entry timeout */ + int max_entries; /*!< maximum entries */ +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; /*!< mutex */ +#endif +}; + +/** + * \brief Initialize an SSL cache context + * + * \param cache SSL cache context + */ +void ssl_cache_init( ssl_cache_context *cache ); + +/** + * \brief Cache get callback implementation + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param data SSL cache context + * \param session session to retrieve entry for + */ +int ssl_cache_get( void *data, ssl_session *session ); + +/** + * \brief Cache set callback implementation + * (Thread-safe if POLARSSL_THREADING_C is enabled) + * + * \param data SSL cache context + * \param session session to store entry for + */ +int ssl_cache_set( void *data, const ssl_session *session ); + +#if defined(POLARSSL_HAVE_TIME) +/** + * \brief Set the cache timeout + * (Default: SSL_CACHE_DEFAULT_TIMEOUT (1 day)) + * + * A timeout of 0 indicates no timeout. + * + * \param cache SSL cache context + * \param timeout cache entry timeout in seconds + */ +void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout ); +#endif /* POLARSSL_HAVE_TIME */ + +/** + * \brief Set the cache timeout + * (Default: SSL_CACHE_DEFAULT_MAX_ENTRIES (50)) + * + * \param cache SSL cache context + * \param max cache entry maximum + */ +void ssl_cache_set_max_entries( ssl_cache_context *cache, int max ); + +/** + * \brief Free referenced items in a cache context and clear memory + * + * \param cache SSL cache context + */ +void ssl_cache_free( ssl_cache_context *cache ); + +#ifdef __cplusplus +} +#endif + +#endif /* ssl_cache.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_ciphersuites.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_ciphersuites.h new file mode 100644 index 0000000..c4f1ffe --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_ciphersuites.h @@ -0,0 +1,293 @@ +/** + * \file ssl_ciphersuites.h + * + * \brief SSL Ciphersuites for PolarSSL + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_SSL_CIPHERSUITES_H +#define POLARSSL_SSL_CIPHERSUITES_H + +#include "pk.h" +#include "cipher.h" +#include "md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Supported ciphersuites (Official IANA names) + */ +#define TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */ +#define TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */ + +#define TLS_RSA_WITH_RC4_128_MD5 0x04 +#define TLS_RSA_WITH_RC4_128_SHA 0x05 +#define TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */ + +#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A + +#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */ +#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16 + +#define TLS_PSK_WITH_NULL_SHA 0x2C /**< Weak! */ +#define TLS_DHE_PSK_WITH_NULL_SHA 0x2D /**< Weak! */ +#define TLS_RSA_PSK_WITH_NULL_SHA 0x2E /**< Weak! */ +#define TLS_RSA_WITH_AES_128_CBC_SHA 0x2F + +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 +#define TLS_RSA_WITH_AES_256_CBC_SHA 0x35 +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 + +#define TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */ +#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */ + +#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41 +#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 + +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */ + +#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 +#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 + +#define TLS_PSK_WITH_RC4_128_SHA 0x8A +#define TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B +#define TLS_PSK_WITH_AES_128_CBC_SHA 0x8C +#define TLS_PSK_WITH_AES_256_CBC_SHA 0x8D + +#define TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E +#define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F +#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90 +#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91 + +#define TLS_RSA_PSK_WITH_RC4_128_SHA 0x92 +#define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93 +#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94 +#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95 + +#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F /**< TLS 1.2 */ + +#define TLS_PSK_WITH_AES_128_GCM_SHA256 0xA8 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_256_GCM_SHA384 0xA9 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 0xAA /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 0xAB /**< TLS 1.2 */ +#define TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 0xAC /**< TLS 1.2 */ +#define TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 0xAD /**< TLS 1.2 */ + +#define TLS_PSK_WITH_AES_128_CBC_SHA256 0xAE +#define TLS_PSK_WITH_AES_256_CBC_SHA384 0xAF +#define TLS_PSK_WITH_NULL_SHA256 0xB0 /**< Weak! */ +#define TLS_PSK_WITH_NULL_SHA384 0xB1 /**< Weak! */ + +#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 0xB2 +#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 0xB3 +#define TLS_DHE_PSK_WITH_NULL_SHA256 0xB4 /**< Weak! */ +#define TLS_DHE_PSK_WITH_NULL_SHA384 0xB5 /**< Weak! */ + +#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 0xB6 +#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 0xB7 +#define TLS_RSA_PSK_WITH_NULL_SHA256 0xB8 /**< Weak! */ +#define TLS_RSA_PSK_WITH_NULL_SHA384 0xB9 /**< Weak! */ + +#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */ + +#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */ + +#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 /**< Weak! */ +#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /**< Not in SSL3! */ + +#define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 /**< Weak! */ +#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 /**< Not in SSL3! */ +#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 /**< Not in SSL3! */ +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /**< Not in SSL3! */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /**< Not in SSL3! */ + +#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B /**< Weak! */ +#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /**< Not in SSL3! */ + +#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 /**< Weak! */ +#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /**< Not in SSL3! */ + +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /**< TLS 1.2 */ + +#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /**< TLS 1.2 */ + +#define TLS_ECDHE_PSK_WITH_RC4_128_SHA 0xC033 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 0xC034 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA 0xC035 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA 0xC036 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 0xC037 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 0xC038 /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_NULL_SHA 0xC039 /**< Weak! No SSL3! */ +#define TLS_ECDHE_PSK_WITH_NULL_SHA256 0xC03A /**< Weak! No SSL3! */ +#define TLS_ECDHE_PSK_WITH_NULL_SHA384 0xC03B /**< Weak! No SSL3! */ + +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC072 /**< Not in SSL3! */ +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC073 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0xC074 /**< Not in SSL3! */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0xC075 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC076 /**< Not in SSL3! */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC077 /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xC078 /**< Not in SSL3! */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 0xC079 /**< Not in SSL3! */ + +#define TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07A /**< TLS 1.2 */ +#define TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07B /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC07C /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC07D /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC086 /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC087 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 0xC088 /**< TLS 1.2 */ +#define TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 0xC089 /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08A /**< TLS 1.2 */ +#define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08B /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 0xC08C /**< TLS 1.2 */ +#define TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 0xC08D /**< TLS 1.2 */ + +#define TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC08E /**< TLS 1.2 */ +#define TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC08F /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC090 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC091 /**< TLS 1.2 */ +#define TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 0xC092 /**< TLS 1.2 */ +#define TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 0xC093 /**< TLS 1.2 */ + +#define TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC094 +#define TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC095 +#define TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC096 +#define TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC097 +#define TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC098 +#define TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC099 +#define TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0xC09A /**< Not in SSL3! */ +#define TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0xC09B /**< Not in SSL3! */ + +#define TLS_RSA_WITH_AES_128_CCM 0xC09C /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_CCM 0xC09D /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 /**< TLS 1.2 */ +#define TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 /**< TLS 1.2 */ +#define TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_128_CCM 0xC0A4 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_256_CCM 0xC0A5 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_CCM 0xC0A6 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_256_CCM 0xC0A7 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_128_CCM_8 0xC0A8 /**< TLS 1.2 */ +#define TLS_PSK_WITH_AES_256_CCM_8 0xC0A9 /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_128_CCM_8 0xC0AA /**< TLS 1.2 */ +#define TLS_DHE_PSK_WITH_AES_256_CCM_8 0xC0AB /**< TLS 1.2 */ +/* The last two are named with PSK_DHE in the RFC, which looks like a typo */ + +#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM 0xC0AC /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM 0xC0AD /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE /**< TLS 1.2 */ +#define TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 0xC0AF /**< TLS 1.2 */ + +/* Reminder: update _ssl_premaster_secret when adding a new key exchange */ +typedef enum { + POLARSSL_KEY_EXCHANGE_NONE = 0, + POLARSSL_KEY_EXCHANGE_RSA, + POLARSSL_KEY_EXCHANGE_DHE_RSA, + POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + POLARSSL_KEY_EXCHANGE_PSK, + POLARSSL_KEY_EXCHANGE_DHE_PSK, + POLARSSL_KEY_EXCHANGE_RSA_PSK, + POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + POLARSSL_KEY_EXCHANGE_ECDH_RSA, + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, +} key_exchange_type_t; + +typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t; + +#define POLARSSL_CIPHERSUITE_WEAK 0x01 /**< Weak ciphersuite flag */ +#define POLARSSL_CIPHERSUITE_SHORT_TAG 0x02 /**< Short authentication tag, + eg for CCM_8 */ + +/** + * \brief This structure is used for storing ciphersuite information + */ +struct _ssl_ciphersuite_t +{ + int id; + const char * name; + + cipher_type_t cipher; + md_type_t mac; + key_exchange_type_t key_exchange; + + int min_major_ver; + int min_minor_ver; + int max_major_ver; + int max_minor_ver; + + unsigned char flags; +}; + +const int *ssl_list_ciphersuites( void ); + +const ssl_ciphersuite_t *ssl_ciphersuite_from_string( const char *ciphersuite_name ); +const ssl_ciphersuite_t *ssl_ciphersuite_from_id( int ciphersuite_id ); + +#if defined(POLARSSL_PK_C) +pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info ); +#endif + +int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info ); +int ssl_ciphersuite_uses_psk( const ssl_ciphersuite_t *info ); + +#ifdef __cplusplus +} +#endif + +#endif /* ssl_ciphersuites.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_rom_lib.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_rom_lib.h new file mode 100644 index 0000000..bfc84e0 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/ssl_rom_lib.h @@ -0,0 +1,61 @@ +#include +#define memcpy _memcpy +#define memcmp _memcmp +#define memset _memset +#define sscanf _sscanf +#define strncpy _strncpy +#define strnlen _strnlen +#define strlen _strlen +#define snprintf DiagSnPrintf + +#define strstr __rtl_strstr +#define vsnprintf __rtl_vfprintf_r +#define memmove __rtl_memmove + +/* these functions will be move to rom libc */ +#ifndef SSL_LIBC_ROM_PATCH +#define SSL_LIBC_ROM_PATCH + +SSL_ROM_TEXT_SECTION +static inline char __rtl_tolower_v1_00(const char c) +{ + return c | 0x20; +} + +SSL_ROM_TEXT_SECTION +static inline int __rtl_strcasecmp_v1_00(const char *s1, const char *s2) +{ + const unsigned char *ucs1 = (const unsigned char *) s1; + const unsigned char *ucs2 = (const unsigned char *) s2; + int d = 0; + for ( ; ; ) + { + const int c1 = __rtl_tolower_v1_00(*ucs1++); + const int c2 = __rtl_tolower_v1_00(*ucs2++); + if (((d = c1 - c2) != 0) || (c2 == '\0')) + break; + } + return d; +} + +SSL_ROM_TEXT_SECTION +static inline int __rtl_strncasecmp_v1_00(const char *s1, const char *s2, size_t n) +{ + const unsigned char *ucs1 = (const unsigned char *) s1; + const unsigned char *ucs2 = (const unsigned char *) s2; + int d = 0; + for ( ; n != 0; n--) + { + const int c1 = __rtl_tolower_v1_00(*ucs1++); + const int c2 = __rtl_tolower_v1_00(*ucs2++); + if (((d = c1 - c2) != 0) || (c2 == '\0')) + break; + } + return d; +} +#endif +#define strcasecmp __rtl_strcasecmp_v1_00 +#define strncasecmp __rtl_strncasecmp_v1_00 + +//#undef POLARSSL_HAVE_UDBL in bignum.h + diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/threading.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/threading.h new file mode 100644 index 0000000..1fc9f98 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/threading.h @@ -0,0 +1,86 @@ +/** + * \file threading.h + * + * \brief Threading abstraction layer + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_THREADING_H +#define POLARSSL_THREADING_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE -0x001A /**< The selected feature is not available. */ +#define POLARSSL_ERR_THREADING_BAD_INPUT_DATA -0x001C /**< Bad input parameters to function. */ +#define POLARSSL_ERR_THREADING_MUTEX_ERROR -0x001E /**< Locking / unlocking / free failed with error code. */ + +#if defined(POLARSSL_THREADING_PTHREAD) +#include +typedef pthread_mutex_t threading_mutex_t; +#endif + +#if defined(POLARSSL_THREADING_ALT) +/* You should define the threading_mutex_t type in your header */ +#include "threading_alt.h" + +/** + * \brief Set your alternate threading implementation function + * pointers + * + * \param mutex_init the init function implementation + * \param mutex_free the free function implementation + * \param mutex_lock the lock function implementation + * \param mutex_unlock the unlock function implementation + * + * \return 0 if successful + */ +int threading_set_alt( int (*mutex_init)( threading_mutex_t * ), + int (*mutex_free)( threading_mutex_t * ), + int (*mutex_lock)( threading_mutex_t * ), + int (*mutex_unlock)( threading_mutex_t * ) ); +#endif /* POLARSSL_THREADING_ALT_C */ + +/* + * The function pointers for mutex_init, mutex_free, mutex_ and mutex_unlock + * + * All these functions are expected to work or the result will be undefined. + */ +extern int (*polarssl_mutex_init)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_free)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_lock)( threading_mutex_t *mutex ); +extern int (*polarssl_mutex_unlock)( threading_mutex_t *mutex ); + +#ifdef __cplusplus +} +#endif + +#endif /* threading.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/timing.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/timing.h new file mode 100644 index 0000000..383120e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/timing.h @@ -0,0 +1,98 @@ +/** + * \file timing.h + * + * \brief Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_TIMING_H +#define POLARSSL_TIMING_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if !defined(POLARSSL_TIMING_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief timer structure + */ +struct hr_time +{ + unsigned char opaque[32]; +}; + +extern volatile int alarmed; + +/** + * \brief Return the CPU cycle counter value + */ +unsigned long hardclock( void ); + +/** + * \brief Return the elapsed time in milliseconds + * + * \param val points to a timer structure + * \param reset if set to 1, the timer is restarted + */ +unsigned long get_timer( struct hr_time *val, int reset ); + +/** + * \brief Setup an alarm clock + * + * \param seconds delay before the "alarmed" flag is set + */ +void set_alarm( int seconds ); + +/** + * \brief Sleep for a certain amount of time + * + * \param milliseconds delay in milliseconds + */ +void m_sleep( int milliseconds ); + +#if defined(POLARSSL_SELF_TEST) +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if a test failed + */ +int timing_self_test( int verbose ); +#endif + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_TIMING_ALT */ +#include "timing_alt.h" +#endif /* POLARSSL_TIMING_ALT */ + +#endif /* timing.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/version.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/version.h new file mode 100644 index 0000000..1ee2a3b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/version.h @@ -0,0 +1,114 @@ +/** + * \file version.h + * + * \brief Run-time version information + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This set of compile-time defines and run-time variables can be used to + * determine the version number of the PolarSSL library used. + */ +#ifndef POLARSSL_VERSION_H +#define POLARSSL_VERSION_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +/** + * The version number x.y.z is split into three parts. + * Major, Minor, Patchlevel + */ +#define POLARSSL_VERSION_MAJOR 1 +#define POLARSSL_VERSION_MINOR 3 +#define POLARSSL_VERSION_PATCH 8 + +/** + * The single version number has the following structure: + * MMNNPP00 + * Major version | Minor version | Patch version + */ +#define POLARSSL_VERSION_NUMBER 0x01030800 +#define POLARSSL_VERSION_STRING "1.3.8" +#define POLARSSL_VERSION_STRING_FULL "PolarSSL 1.3.8" + +#if defined(POLARSSL_VERSION_C) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the version number. + * + * \return The constructed version number in the format + * MMNNPP00 (Major, Minor, Patch). + */ +unsigned int version_get_number( void ); + +/** + * Get the version string ("x.y.z"). + * + * \param string The string that will receive the value. + * (Should be at least 9 bytes in size) + */ +void version_get_string( char *string ); + +/** + * Get the full version string ("PolarSSL x.y.z"). + * + * \param string The string that will receive the value. The PolarSSL version + * string will use 18 bytes AT MOST including a terminating + * null byte. + * (So the buffer should be at least 18 bytes to receive this + * version string). + */ +void version_get_string_full( char *string ); + +/** + * \brief Check if support for a feature was compiled into this + * PolarSSL binary. This allows you to see at runtime if the + * library was for instance compiled with or without + * Multi-threading support. + * + * Note: only checks against defines in the sections "System + * support", "PolarSSL modules" and "PolarSSL feature + * support" in config.h + * + * \param feature The string for the define to check (e.g. "POLARSSL_AES_C") + * + * \return 0 if the feature is present, -1 if the feature is not + * present and -2 if support for feature checking as a whole + * was not compiled in. + */ +int version_check_feature( const char *feature ); + +#ifdef __cplusplus +} +#endif + +#endif /* POLARSSL_VERSION_C */ + +#endif /* version.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509.h new file mode 100644 index 0000000..583cb83 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509.h @@ -0,0 +1,317 @@ +/** + * \file x509.h + * + * \brief X.509 generic defines and structures + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_X509_H +#define POLARSSL_X509_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "asn1.h" +#include "pk.h" + +#if defined(POLARSSL_RSA_C) +#include "rsa.h" +#endif + +/** + * \addtogroup x509_module + * \{ + */ + +/** + * \name X509 Error codes + * \{ + */ +#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x2080 /**< Unavailable feature, e.g. RSA hashing/encryption combination. */ +#define POLARSSL_ERR_X509_UNKNOWN_OID -0x2100 /**< Requested OID is unknown. */ +#define POLARSSL_ERR_X509_INVALID_FORMAT -0x2180 /**< The CRT/CRL/CSR format is invalid, e.g. different type expected. */ +#define POLARSSL_ERR_X509_INVALID_VERSION -0x2200 /**< The CRT/CRL/CSR version element is invalid. */ +#define POLARSSL_ERR_X509_INVALID_SERIAL -0x2280 /**< The serial tag or value is invalid. */ +#define POLARSSL_ERR_X509_INVALID_ALG -0x2300 /**< The algorithm tag or value is invalid. */ +#define POLARSSL_ERR_X509_INVALID_NAME -0x2380 /**< The name tag or value is invalid. */ +#define POLARSSL_ERR_X509_INVALID_DATE -0x2400 /**< The date tag or value is invalid. */ +#define POLARSSL_ERR_X509_INVALID_SIGNATURE -0x2480 /**< The signature tag or value invalid. */ +#define POLARSSL_ERR_X509_INVALID_EXTENSIONS -0x2500 /**< The extension tag or value is invalid. */ +#define POLARSSL_ERR_X509_UNKNOWN_VERSION -0x2580 /**< CRT/CRL/CSR has an unsupported version number. */ +#define POLARSSL_ERR_X509_UNKNOWN_SIG_ALG -0x2600 /**< Signature algorithm (oid) is unsupported. */ +#define POLARSSL_ERR_X509_SIG_MISMATCH -0x2680 /**< Signature algorithms do not match. (see \c ::x509_crt sig_oid) */ +#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x2700 /**< Certificate verification failed, e.g. CRL, CA or signature check failed. */ +#define POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT -0x2780 /**< Format not recognized as DER or PEM. */ +#define POLARSSL_ERR_X509_BAD_INPUT_DATA -0x2800 /**< Input invalid. */ +#define POLARSSL_ERR_X509_MALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ +#define POLARSSL_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ +/* \} name */ + +/** + * \name X509 Verify codes + * \{ + */ +#define BADCERT_EXPIRED 0x01 /**< The certificate validity has expired. */ +#define BADCERT_REVOKED 0x02 /**< The certificate has been revoked (is on a CRL). */ +#define BADCERT_CN_MISMATCH 0x04 /**< The certificate Common Name (CN) does not match with the expected CN. */ +#define BADCERT_NOT_TRUSTED 0x08 /**< The certificate is not correctly signed by the trusted CA. */ +#define BADCRL_NOT_TRUSTED 0x10 /**< CRL is not correctly signed by the trusted CA. */ +#define BADCRL_EXPIRED 0x20 /**< CRL is expired. */ +#define BADCERT_MISSING 0x40 /**< Certificate was missing. */ +#define BADCERT_SKIP_VERIFY 0x80 /**< Certificate verification was skipped. */ +#define BADCERT_OTHER 0x0100 /**< Other reason (can be used by verify callback) */ +#define BADCERT_FUTURE 0x0200 /**< The certificate validity starts in the future. */ +#define BADCRL_FUTURE 0x0400 /**< The CRL is from the future */ +/* \} name */ +/* \} addtogroup x509_module */ + +/* + * X.509 v3 Key Usage Extension flags + */ +#define KU_DIGITAL_SIGNATURE (0x80) /* bit 0 */ +#define KU_NON_REPUDIATION (0x40) /* bit 1 */ +#define KU_KEY_ENCIPHERMENT (0x20) /* bit 2 */ +#define KU_DATA_ENCIPHERMENT (0x10) /* bit 3 */ +#define KU_KEY_AGREEMENT (0x08) /* bit 4 */ +#define KU_KEY_CERT_SIGN (0x04) /* bit 5 */ +#define KU_CRL_SIGN (0x02) /* bit 6 */ + +/* + * Netscape certificate types + * (http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html) + */ + +#define NS_CERT_TYPE_SSL_CLIENT (0x80) /* bit 0 */ +#define NS_CERT_TYPE_SSL_SERVER (0x40) /* bit 1 */ +#define NS_CERT_TYPE_EMAIL (0x20) /* bit 2 */ +#define NS_CERT_TYPE_OBJECT_SIGNING (0x10) /* bit 3 */ +#define NS_CERT_TYPE_RESERVED (0x08) /* bit 4 */ +#define NS_CERT_TYPE_SSL_CA (0x04) /* bit 5 */ +#define NS_CERT_TYPE_EMAIL_CA (0x02) /* bit 6 */ +#define NS_CERT_TYPE_OBJECT_SIGNING_CA (0x01) /* bit 7 */ + +/* + * X.509 extension types + * + * Comments refer to the status for using certificates. Status can be + * different for writing certificates or reading CRLs or CSRs. + */ +#define EXT_AUTHORITY_KEY_IDENTIFIER (1 << 0) +#define EXT_SUBJECT_KEY_IDENTIFIER (1 << 1) +#define EXT_KEY_USAGE (1 << 2) /* Parsed but not used */ +#define EXT_CERTIFICATE_POLICIES (1 << 3) +#define EXT_POLICY_MAPPINGS (1 << 4) +#define EXT_SUBJECT_ALT_NAME (1 << 5) /* Supported (DNS) */ +#define EXT_ISSUER_ALT_NAME (1 << 6) +#define EXT_SUBJECT_DIRECTORY_ATTRS (1 << 7) +#define EXT_BASIC_CONSTRAINTS (1 << 8) /* Supported */ +#define EXT_NAME_CONSTRAINTS (1 << 9) +#define EXT_POLICY_CONSTRAINTS (1 << 10) +#define EXT_EXTENDED_KEY_USAGE (1 << 11) /* Parsed but not used */ +#define EXT_CRL_DISTRIBUTION_POINTS (1 << 12) +#define EXT_INIHIBIT_ANYPOLICY (1 << 13) +#define EXT_FRESHEST_CRL (1 << 14) + +#define EXT_NS_CERT_TYPE (1 << 16) /* Parsed (and then ?) */ + +/* + * Storage format identifiers + * Recognized formats: PEM and DER + */ +#define X509_FORMAT_DER 1 +#define X509_FORMAT_PEM 2 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup x509_module + * \{ */ + +/** + * \name Structures for parsing X.509 certificates, CRLs and CSRs + * \{ + */ + +/** + * Type-length-value structure that allows for ASN1 using DER. + */ +typedef asn1_buf x509_buf; + +/** + * Container for ASN1 bit strings. + */ +typedef asn1_bitstring x509_bitstring; + +/** + * Container for ASN1 named information objects. + * It allows for Relative Distinguished Names (e.g. cn=polarssl,ou=code,etc.). + */ +typedef asn1_named_data x509_name; + +/** + * Container for a sequence of ASN.1 items + */ +typedef asn1_sequence x509_sequence; + +/** Container for date and time (precision in seconds). */ +typedef struct _x509_time +{ + int year, mon, day; /**< Date. */ + int hour, min, sec; /**< Time. */ +} +x509_time; + +/** \} name Structures for parsing X.509 certificates, CRLs and CSRs */ +/** \} addtogroup x509_module */ + +/** + * \brief Store the certificate DN in printable form into buf; + * no more than size characters will be written. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param dn The X509 name to represent + * + * \return The amount of data written to the buffer, or -1 in + * case of an error. + */ +int x509_dn_gets( char *buf, size_t size, const x509_name *dn ); + +/** + * \brief Store the certificate serial in printable form into buf; + * no more than size characters will be written. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param serial The X509 serial to represent + * + * \return The amount of data written to the buffer, or -1 in + * case of an error. + */ +int x509_serial_gets( char *buf, size_t size, const x509_buf *serial ); + +/** + * \brief Give an known OID, return its descriptive string. + * (Deprecated. Use oid_get_extended_key_usage() instead.) + * Warning: only works for extended_key_usage OIDs! + * + * \param oid buffer containing the oid + * + * \return Return a string if the OID is known, + * or NULL otherwise. + */ +const char *x509_oid_get_description( x509_buf *oid ); + +/** + * \brief Give an OID, return a string version of its OID number. + * (Deprecated. Use oid_get_numeric_string() instead) + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param oid Buffer containing the OID + * + * \return Length of the string written (excluding final NULL) or + * POLARSSL_ERR_OID_BUF_TO_SMALL in case of error + */ +int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid ); + +/** + * \brief Check a given x509_time against the system time and check + * if it is not expired. + * + * \param time x509_time to check + * + * \return 0 if the x509_time is still valid, + * 1 otherwise. + */ +int x509_time_expired( const x509_time *time ); + +/** + * \brief Check a given x509_time against the system time and check + * if it is not from the future. + * + * \param time x509_time to check + * + * \return 0 if the x509_time is already valid, + * 1 otherwise. + */ +int x509_time_future( const x509_time *time ); + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int x509_self_test( int verbose ); + +/* + * Internal module functions. You probably do not want to use these unless you + * know you do. + */ +int x509_get_name( unsigned char **p, const unsigned char *end, + x509_name *cur ); +int x509_get_alg_null( unsigned char **p, const unsigned char *end, + x509_buf *alg ); +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ); +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) +int x509_get_rsassa_pss_params( const x509_buf *params, + md_type_t *md_alg, md_type_t *mgf_md, + int *salt_len ); +#endif +int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ); +int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params, + md_type_t *md_alg, pk_type_t *pk_alg, + void **sig_opts ); +int x509_get_time( unsigned char **p, const unsigned char *end, + x509_time *time ); +int x509_get_serial( unsigned char **p, const unsigned char *end, + x509_buf *serial ); +int x509_get_ext( unsigned char **p, const unsigned char *end, + x509_buf *ext, int tag ); +int x509_load_file( const char *path, unsigned char **buf, size_t *n ); +int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid, + pk_type_t pk_alg, md_type_t md_alg, + const void *sig_opts ); +int x509_key_size_helper( char *buf, size_t size, const char *name ); +int x509_string_to_names( asn1_named_data **head, const char *name ); +int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len ); +int x509_write_extensions( unsigned char **p, unsigned char *start, + asn1_named_data *first ); +int x509_write_names( unsigned char **p, unsigned char *start, + asn1_named_data *first ); +int x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ); + +#ifdef __cplusplus +} +#endif + +#endif /* x509.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crl.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crl.h new file mode 100644 index 0000000..9f597a8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crl.h @@ -0,0 +1,162 @@ +/** + * \file x509_crl.h + * + * \brief X.509 certificate revocation list parsing + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_X509_CRL_H +#define POLARSSL_X509_CRL_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup x509_module + * \{ */ + +/** + * \name Structures and functions for parsing CRLs + * \{ + */ + +/** + * Certificate revocation list entry. + * Contains the CA-specific serial numbers and revocation dates. + */ +typedef struct _x509_crl_entry +{ + x509_buf raw; + + x509_buf serial; + + x509_time revocation_date; + + x509_buf entry_ext; + + struct _x509_crl_entry *next; +} +x509_crl_entry; + +/** + * Certificate revocation list structure. + * Every CRL may have multiple entries. + */ +typedef struct _x509_crl +{ + x509_buf raw; /**< The raw certificate data (DER). */ + x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ + + int version; /**< CRL version (1=v1, 2=v2) */ + x509_buf sig_oid1; + + x509_buf issuer_raw; /**< The raw issuer data (DER). */ + + x509_name issuer; /**< The parsed issuer data (named information object). */ + + x509_time this_update; + x509_time next_update; + + x509_crl_entry entry; /**< The CRL entries containing the certificate revocation times for this CA. */ + + x509_buf crl_ext; + + x509_buf sig_oid2; + x509_buf sig; + md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ + + struct _x509_crl *next; +} +x509_crl; + +/** + * \brief Parse one or more CRLs and add them + * to the chained list + * + * \param chain points to the start of the chain + * \param buf buffer holding the CRL data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Load one or more CRLs and add them + * to the chained list + * + * \param chain points to the start of the chain + * \param path filename to read the CRLs from + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int x509_crl_parse_file( x509_crl *chain, const char *path ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Returns an informational string about the CRL. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param crl The X509 CRL to represent + * + * \return The amount of data written to the buffer, or -1 in + * case of an error. + */ +int x509_crl_info( char *buf, size_t size, const char *prefix, + const x509_crl *crl ); + +/** + * \brief Initialize a CRL (chain) + * + * \param crl CRL chain to initialize + */ +void x509_crl_init( x509_crl *crl ); + +/** + * \brief Unallocate all CRL data + * + * \param crl CRL chain to free + */ +void x509_crl_free( x509_crl *crl ); + +/* \} name */ +/* \} addtogroup x509_module */ + +#ifdef __cplusplus +} +#endif + +#endif /* x509_crl.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crt.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crt.h new file mode 100644 index 0000000..4bf8e56 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_crt.h @@ -0,0 +1,558 @@ +/** + * \file x509_crt.h + * + * \brief X.509 certificate parsing and writing + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_X509_CRT_H +#define POLARSSL_X509_CRT_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "x509.h" + +#include "x509_crl.h" + +/** + * \addtogroup x509_module + * \{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Structures and functions for parsing and writing X.509 certificates + * \{ + */ + +/** + * Container for an X.509 certificate. The certificate may be chained. + */ +typedef struct _x509_crt +{ + x509_buf raw; /**< The raw certificate data (DER). */ + x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ + + int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ + x509_buf serial; /**< Unique id for certificate issued by a specific CA. */ + x509_buf sig_oid1; /**< Signature algorithm, e.g. sha1RSA */ + + x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ + x509_buf subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ + + x509_name issuer; /**< The parsed issuer data (named information object). */ + x509_name subject; /**< The parsed subject data (named information object). */ + + x509_time valid_from; /**< Start time of certificate validity. */ + x509_time valid_to; /**< End time of certificate validity. */ + + pk_context pk; /**< Container for the public key context. */ + + x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ + x509_buf subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ + x509_buf v3_ext; /**< Optional X.509 v3 extensions. */ + x509_sequence subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName supported). */ + + int ext_types; /**< Bit string containing detected and parsed extensions */ + int ca_istrue; /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */ + int max_pathlen; /**< Optional Basic Constraint extension value: The maximum path length to the root certificate. Path length is 1 higher than RFC 5280 'meaning', so 1+ */ + + unsigned char key_usage; /**< Optional key usage extension value: See the values in x509.h */ + + x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ + + unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ + + x509_buf sig_oid2; /**< Signature algorithm. Must match sig_oid1. */ + x509_buf sig; /**< Signature: hash of the tbs part signed with the private key. */ + md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ + + struct _x509_crt *next; /**< Next certificate in the CA-chain. */ +} +x509_crt; + +#define X509_CRT_VERSION_1 0 +#define X509_CRT_VERSION_2 1 +#define X509_CRT_VERSION_3 2 + +#define X509_RFC5280_MAX_SERIAL_LEN 32 +#define X509_RFC5280_UTC_TIME_LEN 15 + +/** + * Container for writing a certificate (CRT) + */ +typedef struct _x509write_cert +{ + int version; + mpi serial; + pk_context *subject_key; + pk_context *issuer_key; + asn1_named_data *subject; + asn1_named_data *issuer; + md_type_t md_alg; + char not_before[X509_RFC5280_UTC_TIME_LEN + 1]; + char not_after[X509_RFC5280_UTC_TIME_LEN + 1]; + asn1_named_data *extensions; +} +x509write_cert; + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/** + * \brief Parse a single DER formatted certificate and add it + * to the chained list. + * + * \param chain points to the start of the chain + * \param buf buffer holding the certificate DER data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf, + size_t buflen ); + +/** + * \brief Parse one or more certificates and add them + * to the chained list. Parses permissively. If some + * certificates can be parsed, the result is the number + * of failed certificates it encountered. If none complete + * correctly, the first error is returned. + * + * \param chain points to the start of the chain + * \param buf buffer holding the certificate data + * \param buflen size of the buffer + * + * \return 0 if all certificates parsed successfully, a positive number + * if partly successful or a specific X509 or PEM error code + */ +int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Load one or more certificates and add them + * to the chained list. Parses permissively. If some + * certificates can be parsed, the result is the number + * of failed certificates it encountered. If none complete + * correctly, the first error is returned. + * + * \param chain points to the start of the chain + * \param path filename to read the certificates from + * + * \return 0 if all certificates parsed successfully, a positive number + * if partly successful or a specific X509 or PEM error code + */ +int x509_crt_parse_file( x509_crt *chain, const char *path ); + +/** + * \brief Load one or more certificate files from a path and add them + * to the chained list. Parses permissively. If some + * certificates can be parsed, the result is the number + * of failed certificates it encountered. If none complete + * correctly, the first error is returned. + * + * \warning This function is NOT thread-safe unless + * POLARSSL_THREADING_PTHREADS is defined. If you're using an + * alternative threading implementation, you should either use + * this function only in the main thread, or mutex it. + * + * \param chain points to the start of the chain + * \param path directory / folder to read the certificate files from + * + * \return 0 if all certificates parsed successfully, a positive number + * if partly successful or a specific X509 or PEM error code + */ +int x509_crt_parse_path( x509_crt *chain, const char *path ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Returns an informational string about the + * certificate. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param crt The X509 certificate to represent + * + * \return The amount of data written to the buffer, or -1 in + * case of an error. + */ +int x509_crt_info( char *buf, size_t size, const char *prefix, + const x509_crt *crt ); + +/** + * \brief Verify the certificate signature + * + * The verify callback is a user-supplied callback that + * can clear / modify / add flags for a certificate. If set, + * the verification callback is called for each + * certificate in the chain (from the trust-ca down to the + * presented crt). The parameters for the callback are: + * (void *parameter, x509_crt *crt, int certificate_depth, + * int *flags). With the flags representing current flags for + * that specific certificate and the certificate depth from + * the bottom (Peer cert depth = 0). + * + * All flags left after returning from the callback + * are also returned to the application. The function should + * return 0 for anything but a fatal error. + * + * \param crt a certificate to be verified + * \param trust_ca the trusted CA chain + * \param ca_crl the CRL chain for trusted CA's + * \param cn expected Common Name (can be set to + * NULL if the CN must not be verified) + * \param flags result of the verification + * \param f_vrfy verification function + * \param p_vrfy verification parameter + * + * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED, + * in which case *flags will have one or more of + * the following values set: + * BADCERT_EXPIRED -- + * BADCERT_REVOKED -- + * BADCERT_CN_MISMATCH -- + * BADCERT_NOT_TRUSTED + * or another error in case of a fatal error encountered + * during the verification process. + */ +int x509_crt_verify( x509_crt *crt, + x509_crt *trust_ca, + x509_crl *ca_crl, + const char *cn, int *flags, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ); + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) +/** + * \brief Check usage of certificate against keyUsage extension. + * + * \param crt Leaf certificate used. + * \param usage Intended usage(s) (eg KU_KEY_ENCIPHERMENT before using the + * certificate to perform an RSA key exchange). + * + * \return 0 is these uses of the certificate are allowed, + * POLARSSL_ERR_X509_BAD_INPUT_DATA if the keyUsage extension + * is present but does not contain all the bits set in the + * usage argument. + * + * \note You should only call this function on leaf certificates, on + * (intermediate) CAs the keyUsage extension is automatically + * checked by \c x509_crt_verify(). + */ +int x509_crt_check_key_usage( const x509_crt *crt, int usage ); +#endif /* POLARSSL_X509_CHECK_KEY_USAGE) */ + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +/** + * \brief Check usage of certificate against extentedJeyUsage. + * + * \param crt Leaf certificate used. + * \param usage_oid Intended usage (eg OID_SERVER_AUTH or OID_CLIENT_AUTH). + * \param usage_len Length of usage_oid (eg given by OID_SIZE()). + * + * \return 0 is this use of the certificate is allowed, + * POLARSSL_ERR_X509_BAD_INPUT_DATA if not. + * + * \note Usually only makes sense on leaf certificates. + */ +int x509_crt_check_extended_key_usage( const x509_crt *crt, + const char *usage_oid, + size_t usage_len ); +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) */ + +#if defined(POLARSSL_X509_CRL_PARSE_C) +/** + * \brief Verify the certificate revocation status + * + * \param crt a certificate to be verified + * \param crl the CRL to verify against + * + * \return 1 if the certificate is revoked, 0 otherwise + * + */ +int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl ); +#endif /* POLARSSL_X509_CRL_PARSE_C */ + +/** + * \brief Initialize a certificate (chain) + * + * \param crt Certificate chain to initialize + */ +void x509_crt_init( x509_crt *crt ); + +/** + * \brief Unallocate all certificate data + * + * \param crt Certificate chain to free + */ +void x509_crt_free( x509_crt *crt ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/* \} name */ +/* \} addtogroup x509_module */ + +#if defined(POLARSSL_X509_CRT_WRITE_C) +/** + * \brief Initialize a CRT writing context + * + * \param ctx CRT context to initialize + */ +void x509write_crt_init( x509write_cert *ctx ); + +/** + * \brief Set the verion for a Certificate + * Default: X509_CRT_VERSION_3 + * + * \param ctx CRT context to use + * \param version version to set (X509_CRT_VERSION_1, X509_CRT_VERSION_2 or + * X509_CRT_VERSION_3) + */ +void x509write_crt_set_version( x509write_cert *ctx, int version ); + +/** + * \brief Set the serial number for a Certificate. + * + * \param ctx CRT context to use + * \param serial serial number to set + * + * \return 0 if successful + */ +int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial ); + +/** + * \brief Set the validity period for a Certificate + * Timestamps should be in string format for UTC timezone + * i.e. "YYYYMMDDhhmmss" + * e.g. "20131231235959" for December 31st 2013 + * at 23:59:59 + * + * \param ctx CRT context to use + * \param not_before not_before timestamp + * \param not_after not_after timestamp + * + * \return 0 if timestamp was parsed successfully, or + * a specific error code + */ +int x509write_crt_set_validity( x509write_cert *ctx, const char *not_before, + const char *not_after ); + +/** + * \brief Set the issuer name for a Certificate + * Issuer names should contain a comma-separated list + * of OID types and values: + * e.g. "C=NL,O=Offspark,CN=PolarSSL CA" + * + * \param ctx CRT context to use + * \param issuer_name issuer name to set + * + * \return 0 if issuer name was parsed successfully, or + * a specific error code + */ +int x509write_crt_set_issuer_name( x509write_cert *ctx, + const char *issuer_name ); + +/** + * \brief Set the subject name for a Certificate + * Subject names should contain a comma-separated list + * of OID types and values: + * e.g. "C=NL,O=Offspark,CN=PolarSSL Server 1" + * + * \param ctx CRT context to use + * \param subject_name subject name to set + * + * \return 0 if subject name was parsed successfully, or + * a specific error code + */ +int x509write_crt_set_subject_name( x509write_cert *ctx, + const char *subject_name ); + +/** + * \brief Set the subject public key for the certificate + * + * \param ctx CRT context to use + * \param key public key to include + */ +void x509write_crt_set_subject_key( x509write_cert *ctx, pk_context *key ); + +/** + * \brief Set the issuer key used for signing the certificate + * + * \param ctx CRT context to use + * \param key private key to sign with + */ +void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key ); + +/** + * \brief Set the MD algorithm to use for the signature + * (e.g. POLARSSL_MD_SHA1) + * + * \param ctx CRT context to use + * \param md_alg MD algorithm to use + */ +void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg ); + +/** + * \brief Generic function to add to or replace an extension in the + * CRT + * + * \param ctx CRT context to use + * \param oid OID of the extension + * \param oid_len length of the OID + * \param critical if the extension is critical (per the RFC's definition) + * \param val value of the extension OCTET STRING + * \param val_len length of the value data + * + * \return 0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_extension( x509write_cert *ctx, + const char *oid, size_t oid_len, + int critical, + const unsigned char *val, size_t val_len ); + +/** + * \brief Set the basicConstraints extension for a CRT + * + * \param ctx CRT context to use + * \param is_ca is this a CA certificate + * \param max_pathlen maximum length of certificate chains below this + * certificate (only for CA certificates, -1 is + * inlimited) + * + * \return 0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_basic_constraints( x509write_cert *ctx, + int is_ca, int max_pathlen ); + +#if defined(POLARSSL_SHA1_C) +/** + * \brief Set the subjectKeyIdentifier extension for a CRT + * Requires that x509write_crt_set_subject_key() has been + * called before + * + * \param ctx CRT context to use + * + * \return 0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_subject_key_identifier( x509write_cert *ctx ); + +/** + * \brief Set the authorityKeyIdentifier extension for a CRT + * Requires that x509write_crt_set_issuer_key() has been + * called before + * + * \param ctx CRT context to use + * + * \return 0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_authority_key_identifier( x509write_cert *ctx ); +#endif /* POLARSSL_SHA1_C */ + +/** + * \brief Set the Key Usage Extension flags + * (e.g. KU_DIGITAL_SIGNATURE | KU_KEY_CERT_SIGN) + * + * \param ctx CRT context to use + * \param key_usage key usage flags to set + * + * \return 0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_key_usage( x509write_cert *ctx, unsigned char key_usage ); + +/** + * \brief Set the Netscape Cert Type flags + * (e.g. NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_EMAIL) + * + * \param ctx CRT context to use + * \param ns_cert_type Netscape Cert Type flags to set + * + * \return 0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_crt_set_ns_cert_type( x509write_cert *ctx, + unsigned char ns_cert_type ); + +/** + * \brief Free the contents of a CRT write context + * + * \param ctx CRT context to free + */ +void x509write_crt_free( x509write_cert *ctx ); + +/** + * \brief Write a built up certificate to a X509 DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx certificate to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return length of data written if successful, or a specific + * error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for countermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(POLARSSL_PEM_WRITE_C) +/** + * \brief Write a built up certificate to a X509 PEM string + * + * \param ctx certificate to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return 0 successful, or a specific error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for countermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int x509write_crt_pem( x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#endif /* POLARSSL_PEM_WRITE_C */ +#endif /* POLARSSL_X509_CRT_WRITE_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* x509_crt.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_csr.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_csr.h new file mode 100644 index 0000000..6591e38 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/x509_csr.h @@ -0,0 +1,295 @@ +/** + * \file x509_csr.h + * + * \brief X.509 certificate signing request parsing and writing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_X509_CSR_H +#define POLARSSL_X509_CSR_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include "x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup x509_module + * \{ */ + +/** + * \name Structures and functions for X.509 Certificate Signing Requests (CSR) + * \{ + */ + +/** + * Certificate Signing Request (CSR) structure. + */ +typedef struct _x509_csr +{ + x509_buf raw; /**< The raw CSR data (DER). */ + x509_buf cri; /**< The raw CertificateRequestInfo body (DER). */ + + int version; /**< CSR version (1=v1). */ + + x509_buf subject_raw; /**< The raw subject data (DER). */ + x509_name subject; /**< The parsed subject data (named information object). */ + + pk_context pk; /**< Container for the public key context. */ + + x509_buf sig_oid; + x509_buf sig; + md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. POLARSSL_MD_SHA256 */ + pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. POLARSSL_PK_RSA */ + void *sig_opts; /**< Signature options to be passed to pk_verify_ext(), e.g. for RSASSA-PSS */ +} +x509_csr; + +/** + * Container for writing a CSR + */ +typedef struct _x509write_csr +{ + pk_context *key; + asn1_named_data *subject; + md_type_t md_alg; + asn1_named_data *extensions; +} +x509write_csr; + +#if defined(POLARSSL_X509_CSR_PARSE_C) +/** + * \brief Load a Certificate Signing Request (CSR) in DER format + * + * \param csr CSR context to fill + * \param buf buffer holding the CRL data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 error code + */ +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ); + +/** + * \brief Load a Certificate Signing Request (CSR), DER or PEM format + * + * \param csr CSR context to fill + * \param buf buffer holding the CRL data + * \param buflen size of the buffer + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ); + +#if defined(POLARSSL_FS_IO) +/** + * \brief Load a Certificate Signing Request (CSR) + * + * \param csr CSR context to fill + * \param path filename to read the CSR from + * + * \return 0 if successful, or a specific X509 or PEM error code + */ +int x509_csr_parse_file( x509_csr *csr, const char *path ); +#endif /* POLARSSL_FS_IO */ + +/** + * \brief Returns an informational string about the + * CSR. + * + * \param buf Buffer to write to + * \param size Maximum size of buffer + * \param prefix A line prefix + * \param csr The X509 CSR to represent + * + * \return The length of the string written (exluding the terminating + * null byte), or a negative value in case of an error. + */ +int x509_csr_info( char *buf, size_t size, const char *prefix, + const x509_csr *csr ); + +/** + * \brief Initialize a CSR + * + * \param csr CSR to initialize + */ +void x509_csr_init( x509_csr *csr ); + +/** + * \brief Unallocate all CSR data + * + * \param csr CSR to free + */ +void x509_csr_free( x509_csr *csr ); +#endif /* POLARSSL_X509_CSR_PARSE_C */ + +/* \} name */ +/* \} addtogroup x509_module */ + +#if defined(POLARSSL_X509_CSR_WRITE_C) +/** + * \brief Initialize a CSR context + * + * \param ctx CSR context to initialize + */ +void x509write_csr_init( x509write_csr *ctx ); + +/** + * \brief Set the subject name for a CSR + * Subject names should contain a comma-separated list + * of OID types and values: + * e.g. "C=NL,O=Offspark,CN=PolarSSL Server 1" + * + * \param ctx CSR context to use + * \param subject_name subject name to set + * + * \return 0 if subject name was parsed successfully, or + * a specific error code + */ +int x509write_csr_set_subject_name( x509write_csr *ctx, + const char *subject_name ); + +/** + * \brief Set the key for a CSR (public key will be included, + * private key used to sign the CSR when writing it) + * + * \param ctx CSR context to use + * \param key Asymetric key to include + */ +void x509write_csr_set_key( x509write_csr *ctx, pk_context *key ); + +/** + * \brief Set the MD algorithm to use for the signature + * (e.g. POLARSSL_MD_SHA1) + * + * \param ctx CSR context to use + * \param md_alg MD algorithm to use + */ +void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg ); + +/** + * \brief Set the Key Usage Extension flags + * (e.g. KU_DIGITAL_SIGNATURE | KU_KEY_CERT_SIGN) + * + * \param ctx CSR context to use + * \param key_usage key usage flags to set + * + * \return 0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_csr_set_key_usage( x509write_csr *ctx, unsigned char key_usage ); + +/** + * \brief Set the Netscape Cert Type flags + * (e.g. NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_EMAIL) + * + * \param ctx CSR context to use + * \param ns_cert_type Netscape Cert Type flags to set + * + * \return 0 if successful, or POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_csr_set_ns_cert_type( x509write_csr *ctx, + unsigned char ns_cert_type ); + +/** + * \brief Generic function to add to or replace an extension in the + * CSR + * + * \param ctx CSR context to use + * \param oid OID of the extension + * \param oid_len length of the OID + * \param val value of the extension OCTET STRING + * \param val_len length of the value data + * + * \return 0 if successful, or a POLARSSL_ERR_X509WRITE_MALLOC_FAILED + */ +int x509write_csr_set_extension( x509write_csr *ctx, + const char *oid, size_t oid_len, + const unsigned char *val, size_t val_len ); + +/** + * \brief Free the contents of a CSR context + * + * \param ctx CSR context to free + */ +void x509write_csr_free( x509write_csr *ctx ); + +/** + * \brief Write a CSR (Certificate Signing Request) to a + * DER structure + * Note: data is written at the end of the buffer! Use the + * return value to determine where you should start + * using the buffer + * + * \param ctx CSR to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return length of data written if successful, or a specific + * error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for countermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + +#if defined(POLARSSL_PEM_WRITE_C) +/** + * \brief Write a CSR (Certificate Signing Request) to a + * PEM string + * + * \param ctx CSR to write away + * \param buf buffer to write to + * \param size size of the buffer + * \param f_rng RNG function (for signature, see note) + * \param p_rng RNG parameter + * + * \return 0 successful, or a specific error code + * + * \note f_rng may be NULL if RSA is used for signature and the + * signature is made offline (otherwise f_rng is desirable + * for couermeasures against timing attacks). + * ECDSA signatures always require a non-NULL f_rng. + */ +int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); +#endif /* POLARSSL_PEM_WRITE_C */ +#endif /* POLARSSL_X509_CSR_WRITE_C */ + +#ifdef __cplusplus +} +#endif + +#endif /* x509_csr.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/xtea.h b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/xtea.h new file mode 100644 index 0000000..794c5ef --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/include/polarssl/xtea.h @@ -0,0 +1,149 @@ +/** + * \file xtea.h + * + * \brief XTEA block cipher (32-bit) + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_XTEA_H +#define POLARSSL_XTEA_H + +#if !defined(POLARSSL_CONFIG_FILE) +#include "config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#define XTEA_ENCRYPT 1 +#define XTEA_DECRYPT 0 + +#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH -0x0028 /**< The data input has an invalid length. */ + +#if !defined(POLARSSL_XTEA_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief XTEA context structure + */ +typedef struct +{ + uint32_t k[4]; /*!< key */ +} +xtea_context; + +/** + * \brief Initialize XTEA context + * + * \param ctx XTEA context to be initialized + */ +void xtea_init( xtea_context *ctx ); + +/** + * \brief Clear XTEA context + * + * \param ctx XTEA context to be cleared + */ +void xtea_free( xtea_context *ctx ); + +/** + * \brief XTEA key schedule + * + * \param ctx XTEA context to be initialized + * \param key the secret key + */ +void xtea_setup( xtea_context *ctx, const unsigned char key[16] ); + +/** + * \brief XTEA cipher function + * + * \param ctx XTEA context + * \param mode XTEA_ENCRYPT or XTEA_DECRYPT + * \param input 8-byte input block + * \param output 8-byte output block + * + * \return 0 if successful + */ +int xtea_crypt_ecb( xtea_context *ctx, + int mode, + const unsigned char input[8], + unsigned char output[8] ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/** + * \brief XTEA CBC cipher function + * + * \param ctx XTEA context + * \param mode XTEA_ENCRYPT or XTEA_DECRYPT + * \param length the length of input, multiple of 8 + * \param iv initialization vector for CBC mode + * \param input input block + * \param output output block + * + * \return 0 if successful, + * POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH if the length % 8 != 0 + */ +int xtea_crypt_cbc( xtea_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#ifdef __cplusplus +} +#endif + +#else /* POLARSSL_XTEA_ALT */ +#include "xtea_alt.h" +#endif /* POLARSSL_XTEA_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int xtea_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* xtea.h */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/.gitignore b/USDK/component/common/network/ssl/polarssl-1.3.8/library/.gitignore new file mode 100644 index 0000000..9d80fa4 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/.gitignore @@ -0,0 +1,2 @@ +*.o +libpolarssl* diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/CMakeLists.txt b/USDK/component/common/network/ssl/polarssl-1.3.8/library/CMakeLists.txt new file mode 100644 index 0000000..bc986ee --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/CMakeLists.txt @@ -0,0 +1,136 @@ +option(USE_STATIC_POLARSSL_LIBRARY "Build PolarSSL static library." ON) +option(USE_SHARED_POLARSSL_LIBRARY "Build PolarSSL shared library." OFF) +option(LINK_WITH_PTHREAD "Explicitly link PolarSSL library to pthread." OFF) + +set(src + aes.c + aesni.c + arc4.c + asn1parse.c + asn1write.c + base64.c + bignum.c + blowfish.c + camellia.c + ccm.c + certs.c + cipher.c + cipher_wrap.c + ctr_drbg.c + debug.c + des.c + dhm.c + ecp.c + ecp_curves.c + ecdh.c + ecdsa.c + entropy.c + entropy_poll.c + error.c + gcm.c + havege.c + hmac_drbg.c + md.c + md_wrap.c + md2.c + md4.c + md5.c + memory_buffer_alloc.c + net.c + oid.c + padlock.c + pbkdf2.c + pem.c + pkcs5.c + pkcs11.c + pkcs12.c + pk.c + pk_wrap.c + pkparse.c + pkwrite.c + platform.c + ripemd160.c + rsa.c + sha1.c + sha256.c + sha512.c + ssl_cache.c + ssl_ciphersuites.c + ssl_cli.c + ssl_srv.c + ssl_tls.c + threading.c + timing.c + version.c + version_features.c + x509.c + x509_crt.c + x509_crl.c + x509_csr.c + x509_create.c + x509write_crt.c + x509write_csr.c + xtea.c +) + +if(WIN32) +set(libs ws2_32) +endif(WIN32) + +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS_CHECK} -Wmissing-declarations -Wmissing-prototypes") + set(CMAKE_C_FLAGS_CHECKFULL "${CMAKE_C_FLAGS_CHECK} -Wcast-qual") +endif(CMAKE_COMPILER_IS_GNUCC) + +if(CMAKE_COMPILER_IS_CLANG) + set(CMAKE_C_FLAGS_CHECK "${CMAKE_C_FLAGS_CHECK} -Wmissing-declarations -Wmissing-prototypes") +endif(CMAKE_COMPILER_IS_CLANG) + +if (NOT USE_STATIC_POLARSSL_LIBRARY AND NOT USE_SHARED_POLARSSL_LIBRARY) + message(FATAL_ERROR "Need to choose static or shared polarssl build!") +endif(NOT USE_STATIC_POLARSSL_LIBRARY AND NOT USE_SHARED_POLARSSL_LIBRARY) + +if(USE_STATIC_POLARSSL_LIBRARY AND USE_SHARED_POLARSSL_LIBRARY) + # if we build both static an shared, then let + # tests and programs link to the shared lib target + set(polarssl_static_target "polarssl_static") +elseif(USE_STATIC_POLARSSL_LIBRARY) + set(polarssl_static_target "polarssl") +endif() + +if(USE_STATIC_POLARSSL_LIBRARY) + add_library(${polarssl_static_target} STATIC ${src}) + set_target_properties(${polarssl_static_target} PROPERTIES OUTPUT_NAME polarssl) + target_link_libraries(${polarssl_static_target} ${libs}) + + if(ZLIB_FOUND) + target_link_libraries(${polarssl_static_target} ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) + + if(LINK_WITH_PTHREAD) + target_link_libraries(${polarssl_static_target} pthread) + endif() + + install(TARGETS ${polarssl_static_target} + DESTINATION ${LIB_INSTALL_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +endif() + +if(USE_SHARED_POLARSSL_LIBRARY) + add_library(polarssl SHARED ${src}) + set_target_properties(polarssl PROPERTIES VERSION 1.3.8 SOVERSION 7) + + target_link_libraries(polarssl ${libs}) + + if(ZLIB_FOUND) + target_link_libraries(polarssl ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) + + if(LINK_WITH_PTHREAD) + target_link_libraries(polarssl pthread) + endif() + + install(TARGETS polarssl + DESTINATION ${LIB_INSTALL_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +endif(USE_SHARED_POLARSSL_LIBRARY) diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/Makefile b/USDK/component/common/network/ssl/polarssl-1.3.8/library/Makefile new file mode 100644 index 0000000..d637417 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/Makefile @@ -0,0 +1,110 @@ + +# Also see "include/polarssl/config.h" + +# To compile on MinGW: add "-lws2_32" to LDFLAGS or define WINDOWS in your +# environment +# +CFLAGS += -I../include -D_FILE_OFFSET_BITS=64 -Wall -W -Wdeclaration-after-statement +OFLAGS = -O2 + +ifdef DEBUG +CFLAGS += -g3 +endif + +# MicroBlaze specific options: +# CFLAGS += -mno-xl-soft-mul -mxl-barrel-shift + +# To compile on Plan9: +# CFLAGS += -D_BSD_EXTENSION + +# To compile as a shared library: +ifdef SHARED +CFLAGS += -fPIC +endif + +SONAME=libpolarssl.so.7 + +DLEXT=so.7 +# OSX shared library extension: +# DLEXT=dylib + +# Windows shared library extension: +ifdef WINDOWS +DLEXT=dll +LDFLAGS += -lws2_32 +endif + +OBJS= aes.o aesni.o arc4.o \ + asn1parse.o \ + asn1write.o base64.o bignum.o \ + blowfish.o camellia.o ccm.o \ + certs.o cipher.o cipher_wrap.o \ + ctr_drbg.o debug.o des.o \ + dhm.o ecdh.o ecdsa.o \ + ecp.o ecp_curves.o \ + entropy.o entropy_poll.o \ + error.o gcm.o havege.o \ + hmac_drbg.o \ + md.o md_wrap.o md2.o \ + md4.o md5.o \ + memory_buffer_alloc.o net.o \ + oid.o \ + padlock.o pbkdf2.o pem.o \ + pkcs5.o pkcs11.o pkcs12.o \ + pk.o pk_wrap.o pkparse.o \ + pkwrite.o platform.o ripemd160.o \ + rsa.o sha1.o sha256.o \ + sha512.o ssl_cache.o ssl_cli.o \ + ssl_srv.o ssl_ciphersuites.o \ + ssl_tls.o threading.o timing.o \ + version.o version_features.o \ + x509.o x509_create.o \ + x509_crl.o x509_crt.o x509_csr.o \ + x509write_crt.o x509write_csr.o \ + xtea.o + +.SILENT: + +ifndef SHARED +all: static +else +all: shared +endif + +static: libpolarssl.a + +shared: libpolarssl.$(DLEXT) libpolarssl.so + +libpolarssl.a: $(OBJS) + echo " AR $@" + $(AR) r $@ $(OBJS) + echo " RL $@" + $(AR) s $@ + +libpolarssl.${DLEXT}: libpolarssl.a + echo " LD $@" + $(CC) ${LDFLAGS} -shared -Wl,-soname,$(SONAME) -o $@ $(OBJS) + +libpolarssl.so: libpolarssl.${DLEXT} + echo " LN $@ -> libpolarssl.${DLEXT}" + ln -sf libpolarssl.${DLEXT} $@ + +libpolarssl.dylib: libpolarssl.a + echo " LD $@" + $(CC) ${LDFLAGS} -dynamiclib -o $@ $(OBJS) + +libpolarssl.dll: libpolarssl.a + echo " LD $@" + $(CC) -shared -Wl,-soname,$@ -o $@ $(OBJS) -lws2_32 -lwinmm -lgdi32 + +.c.o: + echo " CC $<" + $(CC) $(CFLAGS) $(OFLAGS) -c $< + +clean: +ifndef WINDOWS + rm -f *.o libpolarssl.* +endif +ifdef WINDOWS + del /Q /F *.o libpolarssl.* +endif diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/aes.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/aes.c new file mode 100644 index 0000000..512c8b4 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/aes.c @@ -0,0 +1,1603 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#ifdef RTL_HW_CRYPTO +#include +#endif + +#if defined(POLARSSL_AES_C) + +#include "polarssl/aes.h" +#if defined(POLARSSL_PADLOCK_C) +#include "polarssl/padlock.h" +#endif +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_AES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#ifdef SUPPORT_HW_SW_CRYPTO + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +#if defined(POLARSSL_PADLOCK_C) && \ + ( defined(POLARSSL_HAVE_X86) || defined(PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(POLARSSL_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* POLARSSL_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif /* POLARSSL_AES_ROM_TABLES */ +#endif /* SUPPORT_HW_SW_CRYPTO */ + +void aes_init( aes_context *ctx ) +{ + memset( ctx, 0, sizeof( aes_context ) ); +} + +void aes_free( aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( aes_context ) ); +} + +/* + * AES key schedule (encryption) + */ +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + switch(keysize) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return(POLARSSL_ERR_AES_INVALID_KEY_LENGTH); + } + + memcpy(ctx->enc_key, key, (keysize / 8)); + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + unsigned int i; + uint32_t *RK; + +#if !defined(POLARSSL_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + + } +#endif + + switch( keysize ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = padlock_supports( PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_setkey_enc( (unsigned char *) ctx->rk, key, keysize ) ); +#endif + + for( i = 0; i < ( keysize >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +/* + * AES key schedule (decryption) + */ +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + switch(keysize) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return(POLARSSL_ERR_AES_INVALID_KEY_LENGTH); + } + + memcpy(ctx->dec_key, key, (keysize / 8)); + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i, j, ret; + aes_context cty; + uint32_t *RK; + uint32_t *SK; + + aes_init( &cty ); + +#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = padlock_supports( PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keysize */ + if( ( ret = aes_setkey_enc( &cty, key, keysize ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + { + aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + aes_free( &cty ); + + return( ret ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption/decryption + */ +int aes_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[32 + 4], *key_buf_aligned; + unsigned char *output_buf[16 + 4], *output_buf_aligned; + + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memset(output_buf, 0, 16 + 4); + + if(mode == AES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_init(key_buf_aligned, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_decrypt(input, 16, NULL, 0, output_buf_aligned); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_init(key_buf_aligned,((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_encrypt(input, 16, NULL, 0, output_buf_aligned); + } + + memcpy(output, output_buf_aligned, 16); + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( aes_padlock_ace ) + { + if( padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + if( mode == AES_DECRYPT ) + { + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + } + else /* AES_ENCRYPT */ + { + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + } + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +int aes_crypt_cbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[32 + 4], *key_buf_aligned; + unsigned char iv_buf[16 + 4], *iv_buf_aligned, iv_tmp[16]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 16) + return(POLARSSL_ERR_AES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 16); + memset(output_buf, 0, length + 4); + + if(mode == AES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_cbc_init(key_buf_aligned, ((ctx->nr - 6) * 4)); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 16), 16); + rom_ssl_ram_map.hw_crypto_aes_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 16); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 16), 16); + rom_ssl_ram_map.hw_crypto_aes_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 16); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_cbc_init(key_buf_aligned,((ctx->nr - 6) * 4)); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_aes_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 16), 16); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_aes_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 16), 16); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( aes_padlock_ace ) + { + if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int aes_crypt_cfb128( aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +#include +int aes_crypt_cfb8( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + if( mode == AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int aes_crypt_ctr( aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + aes_crypt_ecb( ctx, AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#endif /* !POLARSSL_AES_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char iv[16]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + aes_context ctx; + + memset( key, 0, 32 ); + aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CTR-128 (%s): ", + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 ); + + if( v == AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + aes_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_AES_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/aesni.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/aesni.c new file mode 100644 index 0000000..97f646e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/aesni.c @@ -0,0 +1,463 @@ +/* + * AES-NI support functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set + * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_AESNI_C) + +#include "polarssl/aesni.h" +#include + +#if defined(POLARSSL_HAVE_X86_64) + +/* + * AES-NI support detection routine + */ +int aesni_supports( unsigned int what ) +{ + static int done = 0; + static unsigned int c = 0; + + if( ! done ) + { + asm( "movl $1, %%eax \n\t" + "cpuid \n\t" + : "=c" (c) + : + : "eax", "ebx", "edx" ); + done = 1; + } + + return( ( c & what ) != 0 ); +} + +/* + * Binutils needs to be at least 2.19 to support AES-NI instructions. + * Unfortunately, a lot of users have a lower version now (2014-04). + * Emit bytecode directly in order to support "old" version of gas. + * + * Opcodes from the Intel architecture reference manual, vol. 3. + * We always use registers, so we don't need prefixes for memory operands. + * Operand macros are in gas order (src, dst) as opposed to Intel order + * (dst, src) in order to blend better into the surrounding assembly code. + */ +#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," +#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," +#define AESENC ".byte 0x66,0x0F,0x38,0xDC," +#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," +#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," +#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," +#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," + +#define xmm0_xmm0 "0xC0" +#define xmm0_xmm1 "0xC8" +#define xmm0_xmm2 "0xD0" +#define xmm0_xmm3 "0xD8" +#define xmm0_xmm4 "0xE0" +#define xmm1_xmm0 "0xC1" +#define xmm1_xmm2 "0xD1" + +/* + * AES-NI AES-ECB block en(de)cryption + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + asm( "movdqu (%3), %%xmm0 \n\t" // load input + "movdqu (%1), %%xmm1 \n\t" // load round key 0 + "pxor %%xmm1, %%xmm0 \n\t" // round 0 + "addq $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // normal rounds = nr - 1 + "test %2, %2 \n\t" // mode? + "jz 2f \n\t" // 0 = decrypt + + "1: \n\t" // encryption loop + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENC xmm1_xmm0 "\n\t" // do round + "addq $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // loop + "jnz 1b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENCLAST xmm1_xmm0 "\n\t" // last round + "jmp 3f \n\t" + + "2: \n\t" // decryption loop + "movdqu (%1), %%xmm1 \n\t" + AESDEC xmm1_xmm0 "\n\t" // do round + "addq $16, %1 \n\t" + "subl $1, %0 \n\t" + "jnz 2b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESDECLAST xmm1_xmm0 "\n\t" // last round + + "3: \n\t" + "movdqu %%xmm0, (%4) \n\t" // export output + : + : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) + : "memory", "cc", "xmm0", "xmm1" ); + + + return( 0 ); +} + +/* + * GCM multiplication: c = a times b in GF(2^128) + * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. + */ +void aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ) +{ + unsigned char aa[16], bb[16], cc[16]; + size_t i; + + /* The inputs are in big-endian order, so byte-reverse them */ + for( i = 0; i < 16; i++ ) + { + aa[i] = a[15 - i]; + bb[i] = b[15 - i]; + } + + asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 + "movdqu (%1), %%xmm1 \n\t" // b1:b0 + + /* + * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 + * using [CLMUL-WP] algorithm 1 (p. 13). + */ + "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 + "movdqa %%xmm1, %%xmm3 \n\t" // same + "movdqa %%xmm1, %%xmm4 \n\t" // same + PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 + PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 + PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 + PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 + "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 + "movdqa %%xmm4, %%xmm3 \n\t" // same + "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 + "pslldq $8, %%xmm3 \n\t" // e0+f0:0 + "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 + "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 + + /* + * Now shift the result one bit to the left, + * taking advantage of [CLMUL-WP] eq 27 (p. 20) + */ + "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 + "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 + "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 + "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 + "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 + "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 + "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 + "pslldq $8, %%xmm3 \n\t" // r0>>63:0 + "pslldq $8, %%xmm4 \n\t" // r2>>63:0 + "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 + "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 + "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 + "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 + + /* + * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 + * using [CLMUL-WP] algorithm 5 (p. 20). + * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). + */ + /* Step 2 (1) */ + "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 + "movdqa %%xmm1, %%xmm4 \n\t" // same + "movdqa %%xmm1, %%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a + "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b + "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c + + /* Step 2 (2) */ + "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b + "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c + "pslldq $8, %%xmm3 \n\t" // a+b+c:0 + "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 + + /* Steps 3 and 4 */ + "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' + "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' + "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' + "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' + "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' + // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing + // bits carried from d. Now get those\t bits back in. + "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // d<<63:stuff + "psllq $62, %%xmm4 \n\t" // d<<62:stuff + "psllq $57, %%xmm5 \n\t" // d<<57:stuff + "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff + "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff + "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d + "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 + "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 + "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 + + "movdqu %%xmm0, (%2) \n\t" // done + : + : "r" (aa), "r" (bb), "r" (cc) + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); + + /* Now byte-reverse the outputs */ + for( i = 0; i < 16; i++ ) + c[i] = cc[15 - i]; + + return; +} + +/* + * Compute decryption round keys from encryption round keys + */ +void aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ) +{ + unsigned char *ik = invkey; + const unsigned char *fk = fwdkey + 16 * nr; + + memcpy( ik, fk, 16 ); + + for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) + asm( "movdqu (%0), %%xmm0 \n\t" + AESIMC xmm0_xmm0 "\n\t" + "movdqu %%xmm0, (%1) \n\t" + : + : "r" (fk), "r" (ik) + : "memory", "xmm0" ); + + memcpy( ik, fk, 16 ); +} + +/* + * Key expansion, 128-bit case + */ +static void aesni_setkey_enc_128( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key + "movdqu %%xmm0, (%0) \n\t" // as round key 0 + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next round key. + * + * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff + * with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r7:r6:r5:r4 + * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 + "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm1 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! + "add $16, %0 \n\t" // point to next round key + "movdqu %%xmm0, (%0) \n\t" // write it + "ret \n\t" + + /* Main "loop" */ + "2: \n\t" + AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 192-bit case + */ +static void aesni_setkey_enc_192( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movq 16(%1), %%xmm1 \n\t" + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next 6 quarter-keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 + * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 + "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 + "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 + "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "ret \n\t" + + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" + + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 256-bit case + */ +static void aesni_setkey_enc_256( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movdqu 16(%1), %%xmm1 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next two round keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and + * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON + * + * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 + * and those have been written to the output buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + + /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) + * and proceed to generate next round key from there */ + AESKEYGENA xmm0_xmm2 ",0x00 \n\t" + "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm2, %%xmm1 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "ret \n\t" + + /* + * Main "loop" - Generating one more key than necessary, + * see definition of aes_context.buf + */ + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, wrapper + */ +int aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ) +{ + switch( bits ) + { + case 128: aesni_setkey_enc_128( rk, key ); break; + case 192: aesni_setkey_enc_192( rk, key ); break; + case 256: aesni_setkey_enc_256( rk, key ); break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + + return( 0 ); +} + +#endif /* POLARSSL_HAVE_X86_64 */ + +#endif /* POLARSSL_AESNI_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/arc4.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/arc4.c new file mode 100644 index 0000000..54e89ea --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/arc4.c @@ -0,0 +1,208 @@ +/* + * An implementation of the ARCFOUR algorithm + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ARCFOUR algorithm was publicly disclosed on 94/09. + * + * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ARC4_C) + +#include "polarssl/arc4.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_ARC4_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void arc4_init( arc4_context *ctx ) +{ + memset( ctx, 0, sizeof( arc4_context ) ); +} + +void arc4_free( arc4_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( arc4_context ) ); +} + +/* + * ARC4 key schedule + */ +void arc4_setup( arc4_context *ctx, const unsigned char *key, + unsigned int keylen ) +{ + int i, j, a; + unsigned int k; + unsigned char *m; + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for( i = 0; i < 256; i++ ) + m[i] = (unsigned char) i; + + j = k = 0; + + for( i = 0; i < 256; i++, k++ ) + { + if( k >= keylen ) k = 0; + + a = m[i]; + j = ( j + a + key[k] ) & 0xFF; + m[i] = m[j]; + m[j] = (unsigned char) a; + } +} + +/* + * ARC4 cipher function + */ +int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input, + unsigned char *output ) +{ + int x, y, a, b; + size_t i; + unsigned char *m; + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for( i = 0; i < length; i++ ) + { + x = ( x + 1 ) & 0xFF; a = m[x]; + y = ( y + a ) & 0xFF; b = m[y]; + + m[x] = (unsigned char) b; + m[y] = (unsigned char) a; + + output[i] = (unsigned char) + ( input[i] ^ m[(unsigned char)( a + b )] ); + } + + ctx->x = x; + ctx->y = y; + + return( 0 ); +} + +#endif /* !POLARSSL_ARC4_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +/* + * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: + * + * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 + */ +static const unsigned char arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +/* + * Checkup routine + */ +int arc4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char ibuf[8]; + unsigned char obuf[8]; + arc4_context ctx; + + arc4_init( &ctx ); + + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " ARC4 test #%d: ", i + 1 ); + + memcpy( ibuf, arc4_test_pt[i], 8 ); + + arc4_setup( &ctx, arc4_test_key[i], 8 ); + arc4_crypt( &ctx, 8, ibuf, obuf ); + + if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + arc4_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ARC4_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1parse.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1parse.c new file mode 100644 index 0000000..9744352 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1parse.c @@ -0,0 +1,391 @@ +/* + * Generic ASN.1 parsing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ASN1_PARSE_C) + +#include "polarssl/asn1.h" + +#if defined(POLARSSL_BIGNUM_C) +#include "polarssl/bignum.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include + +/* + * ASN.1 DER decoding routines + */ +int asn1_get_len( unsigned char **p, + const unsigned char *end, + size_t *len ) +{ + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( ( **p & 0x80 ) == 0 ) + *len = *(*p)++; + else + { + switch( **p & 0x7F ) + { + case 1: + if( ( end - *p ) < 2 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = (*p)[1]; + (*p) += 2; + break; + + case 2: + if( ( end - *p ) < 3 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 8 ) | (*p)[2]; + (*p) += 3; + break; + + case 3: + if( ( end - *p ) < 4 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3]; + (*p) += 4; + break; + + case 4: + if( ( end - *p ) < 5 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | + (*p)[4]; + (*p) += 5; + break; + + default: + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + } + } + + if( *len > (size_t) ( end - *p ) ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + return( 0 ); +} + +int asn1_get_tag( unsigned char **p, + const unsigned char *end, + size_t *len, int tag ) +{ + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( **p != tag ) + return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + (*p)++; + + return( asn1_get_len( p, end, len ) ); +} + +int asn1_get_bool( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 ) + return( ret ); + + if( len != 1 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + *val = ( **p != 0 ) ? 1 : 0; + (*p)++; + + return( 0 ); +} + +int asn1_get_int( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) + return( ret ); + + if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + *val = 0; + + while( len-- > 0 ) + { + *val = ( *val << 8 ) | **p; + (*p)++; + } + + return( 0 ); +} + +#if defined(POLARSSL_BIGNUM_C) +int asn1_get_mpi( unsigned char **p, + const unsigned char *end, + mpi *X ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) + return( ret ); + + ret = mpi_read_binary( X, *p, len ); + + *p += len; + + return( ret ); +} +#endif /* POLARSSL_BIGNUM_C */ + +int asn1_get_bitstring( unsigned char **p, const unsigned char *end, + asn1_bitstring *bs) +{ + int ret; + + /* Certificate type is a single byte bitstring */ + if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + /* Check length, subtract one for actual bit string length */ + if( bs->len < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + bs->len -= 1; + + /* Get number of unused bits, ensure unused bits <= 7 */ + bs->unused_bits = **p; + if( bs->unused_bits > 7 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + (*p)++; + + /* Get actual bitstring */ + bs->p = *p; + *p += bs->len; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Get a bit string without unused bits + */ +int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ) +{ + int ret; + + if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + if( (*len)-- < 2 || *(*p)++ != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + + + +/* + * Parses and splits an ASN.1 "SEQUENCE OF " + */ +int asn1_get_sequence_of( unsigned char **p, + const unsigned char *end, + asn1_sequence *cur, + int tag) +{ + int ret; + size_t len; + asn1_buf *buf; + + /* Get main sequence tag */ + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + buf = &(cur->buf); + buf->tag = **p; + + if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) + return( ret ); + + buf->p = *p; + *p += buf->len; + + /* Allocate and assign next pointer */ + if( *p < end ) + { + cur->next = (asn1_sequence *) polarssl_malloc( + sizeof( asn1_sequence ) ); + + if( cur->next == NULL ) + return( POLARSSL_ERR_ASN1_MALLOC_FAILED ); + + cur = cur->next; + } + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int asn1_get_alg( unsigned char **p, + const unsigned char *end, + asn1_buf *alg, asn1_buf *params ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + alg->tag = **p; + end = *p + len; + + if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 ) + return( ret ); + + alg->p = *p; + *p += alg->len; + + if( *p == end ) + { + memset( params, 0, sizeof(asn1_buf) ); + return( 0 ); + } + + params->tag = **p; + (*p)++; + + if( ( ret = asn1_get_len( p, end, ¶ms->len ) ) != 0 ) + return( ret ); + + params->p = *p; + *p += params->len; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int asn1_get_alg_null( unsigned char **p, + const unsigned char *end, + asn1_buf *alg ) +{ + int ret; + asn1_buf params; + + memset( ¶ms, 0, sizeof(asn1_buf) ); + + if( ( ret = asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) + return( ret ); + + if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + +void asn1_free_named_data( asn1_named_data *cur ) +{ + if( cur == NULL ) + return; + + polarssl_free( cur->oid.p ); + polarssl_free( cur->val.p ); + + memset( cur, 0, sizeof( asn1_named_data ) ); +} + +void asn1_free_named_data_list( asn1_named_data **head ) +{ + asn1_named_data *cur; + + while( ( cur = *head ) != NULL ) + { + *head = cur->next; + asn1_free_named_data( cur ); + polarssl_free( cur ); + } +} + +asn1_named_data *asn1_find_named_data( asn1_named_data *list, + const char *oid, size_t len ) +{ + while( list != NULL ) + { + if( list->oid.len == len && + memcmp( list->oid.p, oid, len ) == 0 ) + { + break; + } + + list = list->next; + } + + return( list ); +} + +#endif /* POLARSSL_ASN1_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1write.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1write.c new file mode 100644 index 0000000..ebc0e97 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/asn1write.c @@ -0,0 +1,366 @@ +/* + * ASN.1 buffer writing functionality + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ASN1_WRITE_C) + +#include "polarssl/asn1write.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +int asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) +{ + if( len < 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + return( 1 ); + } + + if( len <= 0xFF ) + { + if( *p - start < 2 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + *--(*p) = 0x81; + return( 2 ); + } + + if( *p - start < 3 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + // We assume we never have lengths larger than 65535 bytes + // + *--(*p) = len % 256; + *--(*p) = ( len / 256 ) % 256; + *--(*p) = 0x82; + + return( 3 ); +} + +int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) +{ + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = tag; + + return( 1 ); +} + +int asn1_write_raw_buffer( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + size_t len = 0; + + if( *p - start < (int) size ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len = size; + (*p) -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +#if defined(POLARSSL_BIGNUM_C) +int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) +{ + int ret; + size_t len = 0; + + // Write the MPI + // + len = mpi_size( X ); + + if( *p - start < (int) len ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + (*p) -= len; + MPI_CHK( mpi_write_binary( X, *p, len ) ); + + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( X->s ==1 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); + + ret = (int) len; + +cleanup: + return( ret ); +} +#endif /* POLARSSL_BIGNUM_C */ + +int asn1_write_null( unsigned char **p, unsigned char *start ) +{ + int ret; + size_t len = 0; + + // Write NULL + // + ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) ); + + return( (int) len ); +} + +int asn1_write_oid( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) oid, oid_len ) ); + ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) ); + + return( (int) len ); +} + +int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len ) +{ + int ret; + size_t len = 0; + + if( par_len == 0 ) + ASN1_CHK_ADD( len, asn1_write_null( p, start ) ); + else + len += par_len; + + ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) +{ + int ret; + size_t len = 0; + + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (boolean) ? 1 : 0; + len++; + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) ); + + return( (int) len ); +} + +int asn1_write_int( unsigned char **p, unsigned char *start, int val ) +{ + int ret; + size_t len = 0; + + // TODO negative values and values larger than 128 + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len += 1; + *--(*p) = val; + + if( val > 0 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); + + return( (int) len ); +} + +int asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) ); + + return( (int) len ); +} + +int asn1_write_ia5_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) ); + + return( (int) len ); +} + +int asn1_write_bitstring( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t bits ) +{ + int ret; + size_t len = 0, size; + + size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); + + // Calculate byte length + // + if( *p - start < (int) size + 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len = size + 1; + (*p) -= size; + memcpy( *p, buf, size ); + + // Write unused bits + // + *--(*p) = (unsigned char) (size * 8 - bits); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) ); + + return( (int) len ); +} + +int asn1_write_octet_string( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) ); + + return( (int) len ); +} + +asn1_named_data *asn1_store_named_data( asn1_named_data **head, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len ) +{ + asn1_named_data *cur; + + if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) + { + // Add new entry if not present yet based on OID + // + if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL ) + return( NULL ); + + memset( cur, 0, sizeof(asn1_named_data) ); + + cur->oid.len = oid_len; + cur->oid.p = polarssl_malloc( oid_len ); + if( cur->oid.p == NULL ) + { + polarssl_free( cur ); + return( NULL ); + } + + cur->val.len = val_len; + cur->val.p = polarssl_malloc( val_len ); + if( cur->val.p == NULL ) + { + polarssl_free( cur->oid.p ); + polarssl_free( cur ); + return( NULL ); + } + + memcpy( cur->oid.p, oid, oid_len ); + + cur->next = *head; + *head = cur; + } + else if( cur->val.len < val_len ) + { + // Enlarge existing value buffer if needed + // + polarssl_free( cur->val.p ); + cur->val.p = NULL; + + cur->val.len = val_len; + cur->val.p = polarssl_malloc( val_len ); + if( cur->val.p == NULL ) + { + polarssl_free( cur->oid.p ); + polarssl_free( cur ); + return( NULL ); + } + } + + if( val != NULL ) + memcpy( cur->val.p, val, val_len ); + + return( cur ); +} +#endif /* POLARSSL_ASN1_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/base64.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/base64.c new file mode 100644 index 0000000..39a8323 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/base64.c @@ -0,0 +1,273 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BASE64_C) + +#include "polarssl/base64.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +int base64_encode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + return( 0 ); + + n = ( slen << 3 ) / 6; + + switch( ( slen << 3 ) - ( n * 6 ) ) + { + case 2: n += 3; break; + case 4: n += 2; break; + default: break; + } + + if( *dlen < n + 1 ) + { + *dlen = n + 1; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = ( slen / 3 ) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( ( i + 1 ) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *dlen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int base64_decode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + uint32_t j, x; + unsigned char *p; + + for( i = n = j = 0; i < slen; i++ ) + { + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + if( src[i] == '=' && ++j > 2 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + return( 0 ); + + n = ( ( n * 6 ) + 7 ) >> 3; + n -= j; + + if( dst == NULL || *dlen < n ) + { + *dlen = n; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *dlen = p - dst; + + return( 0 ); +} + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int base64_self_test( int verbose ) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if( verbose != 0 ) + polarssl_printf( " Base64 encoding test: " ); + + len = sizeof( buffer ); + src = base64_test_dec; + + if( base64_encode( buffer, &len, src, 64 ) != 0 || + memcmp( base64_test_enc, buffer, 88 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n Base64 decoding test: " ); + + len = sizeof( buffer ); + src = base64_test_enc; + + if( base64_decode( buffer, &len, src, 88 ) != 0 || + memcmp( base64_test_dec, buffer, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_BASE64_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/bignum.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/bignum.c new file mode 100644 index 0000000..80cf0f8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/bignum.c @@ -0,0 +1,2344 @@ +/* + * Multi-precision integer library + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This MPI implementation is based on: + * + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * http://www.stillhq.com/extracted/gnupg-api/mpi/ + * http://math.libtomcrypt.com/files/tommath.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BIGNUM_C) + +#include "polarssl/bignum.h" +#include "polarssl/bn_mul.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define ciL (sizeof(t_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +/* + * Convert between bits/chars and number of limbs + */ +#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) +#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) + +/* + * Initialize one MPI + */ +void mpi_init( mpi *X ) +{ + if( X == NULL ) + return; + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +void mpi_free( mpi *X ) +{ + if( X == NULL ) + return; + + if( X->p != NULL ) + { + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +int mpi_grow( mpi *X, size_t nblimbs ) +{ + t_uint *p; + + if( nblimbs > POLARSSL_MPI_MAX_LIMBS ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + if( X->n < nblimbs ) + { + if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, nblimbs * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Resize down as much as possible, + * while keeping at least the specified number of limbs + */ +int mpi_shrink( mpi *X, size_t nblimbs ) +{ + t_uint *p; + size_t i; + + /* Actually resize up in this case */ + if( X->n <= nblimbs ) + return( mpi_grow( X, nblimbs ) ); + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + i++; + + if( i < nblimbs ) + i = nblimbs; + + if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, i * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, i * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->n = i; + X->p = p; + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +int mpi_copy( mpi *X, const mpi *Y ) +{ + int ret; + size_t i; + + if( X == Y ) + return( 0 ); + + if( Y->p == NULL ) + { + mpi_free( X ); + return( 0 ); + } + + for( i = Y->n - 1; i > 0; i-- ) + if( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MPI_CHK( mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +void mpi_swap( mpi *X, mpi *Y ) +{ + mpi T; + + memcpy( &T, X, sizeof( mpi ) ); + memcpy( X, Y, sizeof( mpi ) ); + memcpy( Y, &T, sizeof( mpi ) ); +} + +/* + * Conditionally assign X = Y, without leaking information + * about whether the assignment was made or not. + * (Leaking information about the respective sizes of X and Y is ok however.) + */ +int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ) +{ + int ret = 0; + size_t i; + + /* make sure assign is 0 or 1 */ + assign = ( assign != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + + X->s = X->s * ( 1 - assign ) + Y->s * assign; + + for( i = 0; i < Y->n; i++ ) + X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; + + for( ; i < X->n; i++ ) + X->p[i] *= ( 1 - assign ); + +cleanup: + return( ret ); +} + +/* + * Conditionally swap X and Y, without leaking information + * about whether the swap was made or not. + * Here it is not ok to simply swap the pointers, which whould lead to + * different memory access patterns when X and Y are used afterwards. + */ +int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap ) +{ + int ret, s; + size_t i; + t_uint tmp; + + if( X == Y ) + return( 0 ); + + /* make sure swap is 0 or 1 */ + swap = ( swap != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + MPI_CHK( mpi_grow( Y, X->n ) ); + + s = X->s; + X->s = X->s * ( 1 - swap ) + Y->s * swap; + Y->s = Y->s * ( 1 - swap ) + s * swap; + + + for( i = 0; i < X->n; i++ ) + { + tmp = X->p[i]; + X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; + Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; + } + +cleanup: + return( ret ); +} + +/* + * Set value from integer + */ +int mpi_lset( mpi *X, t_sint z ) +{ + int ret; + + MPI_CHK( mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Get a specific bit + */ +int mpi_get_bit( const mpi *X, size_t pos ) +{ + if( X->n * biL <= pos ) + return( 0 ); + + return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + + if( val != 0 && val != 1 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + if( X->n * biL <= pos ) + { + if( val == 0 ) + return( 0 ); + + MPI_CHK( mpi_grow( X, off + 1 ) ); + } + + X->p[off] &= ~( (t_uint) 0x01 << idx ); + X->p[off] |= (t_uint) val << idx; + +cleanup: + + return( ret ); +} + +/* + * Return the number of least significant bits + */ +size_t mpi_lsb( const mpi *X ) +{ + size_t i, j, count = 0; + + for( i = 0; i < X->n; i++ ) + for( j = 0; j < biL; j++, count++ ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Return the number of most significant bits + */ +size_t mpi_msb( const mpi *X ) +{ + size_t i, j; + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = biL; j > 0; j-- ) + if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 ) + break; + + return( ( i * biL ) + j ); +} + +/* + * Return the total size in bytes + */ +size_t mpi_size( const mpi *X ) +{ + return( ( mpi_msb( X ) + 7 ) >> 3 ); +} + +/* + * Convert an ASCII character to digit value + */ +static int mpi_get_digit( t_uint *d, int radix, char c ) +{ + *d = 255; + + if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; + if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; + if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; + + if( *d >= (t_uint) radix ) + return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); + + return( 0 ); +} + +/* + * Import from an ASCII string + */ +int mpi_read_string( mpi *X, int radix, const char *s ) +{ + int ret; + size_t i, j, slen, n; + t_uint d; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &T ); + + slen = strlen( s ); + + if( radix == 16 ) + { + n = BITS_TO_LIMBS( slen << 2 ); + + MPI_CHK( mpi_grow( X, n ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = slen, j = 0; i > 0; i--, j++ ) + { + if( i == 1 && s[i - 1] == '-' ) + { + X->s = -1; + break; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); + X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); + } + } + else + { + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = 0; i < slen; i++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + continue; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + MPI_CHK( mpi_mul_int( &T, X, radix ) ); + + if( X->s == 1 ) + { + MPI_CHK( mpi_add_int( X, &T, d ) ); + } + else + { + MPI_CHK( mpi_sub_int( X, &T, d ) ); + } + } + } + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +/* + * Helper to write the digits high-order first + */ +static int mpi_write_hlp( mpi *X, int radix, char **p ) +{ + int ret; + t_uint r; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( mpi_mod_int( &r, X, radix ) ); + MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); + + if( mpi_cmp_int( X, 0 ) != 0 ) + MPI_CHK( mpi_write_hlp( X, radix, p ) ); + + if( r < 10 ) + *(*p)++ = (char)( r + 0x30 ); + else + *(*p)++ = (char)( r + 0x37 ); + +cleanup: + + return( ret ); +} + +/* + * Export into an ASCII string + */ +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) +{ + int ret = 0; + size_t n; + char *p; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + n = mpi_msb( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + n += 3; + + if( *slen < n ) + { + *slen = n; + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + } + + p = s; + mpi_init( &T ); + + if( X->s == -1 ) + *p++ = '-'; + + if( radix == 16 ) + { + int c; + size_t i, j, k; + + for( i = X->n, k = 0; i > 0; i-- ) + { + for( j = ciL; j > 0; j-- ) + { + c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; + + if( c == 0 && k == 0 && ( i + j ) != 2 ) + continue; + + *(p++) = "0123456789ABCDEF" [c / 16]; + *(p++) = "0123456789ABCDEF" [c % 16]; + k = 1; + } + } + } + else + { + MPI_CHK( mpi_copy( &T, X ) ); + + if( T.s == -1 ) + T.s = 1; + + MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + } + + *p++ = '\0'; + *slen = p - s; + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Read X from an opened file + */ +int mpi_read_file( mpi *X, int radix, FILE *fin ) +{ + t_uint d; + size_t slen; + char *p; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; + + memset( s, 0, sizeof( s ) ); + if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + + slen = strlen( s ); + if( slen == sizeof( s ) - 2 ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + + p = s + slen; + while( --p >= s ) + if( mpi_get_digit( &d, radix, *p ) != 0 ) + break; + + return( mpi_read_string( X, radix, p + 1 ) ); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) +{ + int ret; + size_t n, slen, plen; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; + + n = sizeof( s ); + memset( s, 0, n ); + n -= 2; + + MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) ); + + if( p == NULL ) p = ""; + + plen = strlen( p ); + slen = strlen( s ); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if( fout != NULL ) + { + if( fwrite( p, 1, plen, fout ) != plen || + fwrite( s, 1, slen, fout ) != slen ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + } + else + polarssl_printf( "%s%s", p, s ); + +cleanup: + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * Import X from unsigned binary data, big endian + */ +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i, j, n; + + for( n = 0; n < buflen; n++ ) + if( buf[n] != 0 ) + break; + + MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = buflen, j = 0; i > n; i--, j++ ) + X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) +{ + size_t i, j, n; + + n = mpi_size( X ); + + if( buflen < n ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +int mpi_shift_l( mpi *X, size_t count ) +{ + int ret; + size_t i, v0, t1; + t_uint r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mpi_msb( X ) + count; + + if( X->n * biL < i ) + MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +int mpi_shift_r( mpi *X, size_t count ) +{ + size_t i, v0, v1; + t_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) + return mpi_lset( X, 0 ); + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = X->n; i > 0; i-- ) + { + r1 = X->p[i - 1] << (biL - v1); + X->p[i - 1] >>= v1; + X->p[i - 1] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +int mpi_cmp_abs( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( 1 ); + if( j > i ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_mpi( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( X->s ); + if( j > i ) return( -Y->s ); + + if( X->s > 0 && Y->s < 0 ) return( 1 ); + if( Y->s > 0 && X->s < 0 ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mpi_cmp_int( const mpi *X, t_sint z ) +{ + mpi Y; + t_uint p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + t_uint *o, *p, c; + + if( X == B ) + { + const mpi *T = A; A = X; B = T; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned additions. + */ + X->s = 1; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, j ) ); + + o = B->p; p = X->p; c = 0; + + for( i = 0; i < j; i++, o++, p++ ) + { + *p += c; c = ( *p < c ); + *p += *o; c += ( *p < *o ); + } + + while( c != 0 ) + { + if( i >= X->n ) + { + MPI_CHK( mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; p++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mpi subtraction + */ +static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) +{ + size_t i; + t_uint c, z; + + for( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned subtraction: X = |A| - |B| (HAC 14.9) + */ +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) +{ + mpi TB; + int ret; + size_t n; + + if( mpi_cmp_abs( A, B ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + mpi_init( &TB ); + + if( X == B ) + { + MPI_CHK( mpi_copy( &TB, B ) ); + B = &TB; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned subtractions. + */ + X->s = 1; + + ret = 0; + + for( n = B->n; n > 0; n-- ) + if( B->p[n - 1] != 0 ) + break; + + mpi_sub_hlp( n, B->p, X->p ); + +cleanup: + + mpi_free( &TB ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s < 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed subtraction: X = A - B + */ +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s > 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +int mpi_add_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed subtraction: X = A - b + */ +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mpi multiplication + */ +static +#if defined(__APPLE__) && defined(__arm__) +/* + * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) + * appears to need this to prevent bad ARM code generation at -O3. + */ +__attribute__ ((noinline)) +#endif +void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) +{ + t_uint c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else /* MULADDC_HUIT */ + for( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif /* MULADDC_HUIT */ + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while( c != 0 ); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + mpi TA, TB; + + mpi_init( &TA ); mpi_init( &TB ); + + if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } + if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } + + for( i = A->n; i > 0; i-- ) + if( A->p[i - 1] != 0 ) + break; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, i + j ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); + + X->s = A->s * B->s; + +cleanup: + + mpi_free( &TB ); mpi_free( &TA ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Division by mpi: A = Q * B + R (HAC 14.20) + */ +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, n, t, k; + mpi X, Y, Z, T1, T2; + + if( mpi_cmp_int( B, 0 ) == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + mpi_init( &T1 ); mpi_init( &T2 ); + + if( mpi_cmp_abs( A, B ) < 0 ) + { + if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); + if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); + return( 0 ); + } + + MPI_CHK( mpi_copy( &X, A ) ); + MPI_CHK( mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); + MPI_CHK( mpi_lset( &Z, 0 ) ); + MPI_CHK( mpi_grow( &T1, 2 ) ); + MPI_CHK( mpi_grow( &T2, 3 ) ); + + k = mpi_msb( &Y ) % biL; + if( k < biL - 1 ) + { + k = biL - 1 - k; + MPI_CHK( mpi_shift_l( &X, k ) ); + MPI_CHK( mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) ); + + while( mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) ); + } + MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) ); + + for( i = n; i > t ; i-- ) + { + if( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { + /* + * The version of Clang shipped by Apple with Mavericks around + * 2014-03 can't handle 128-bit division properly. Disable + * 128-bits division for this version. Let's be optimistic and + * assume it'll be fixed in the next minor version (next + * patchlevel is probably a bit too optimistic). + */ +#if defined(POLARSSL_HAVE_UDBL) && \ + ! ( defined(__x86_64__) && defined(__APPLE__) && \ + defined(__clang_major__) && __clang_major__ == 5 && \ + defined(__clang_minor__) && __clang_minor__ == 0 ) + t_udbl r; + + r = (t_udbl) X.p[i] << biL; + r |= (t_udbl) X.p[i - 1]; + r /= Y.p[t]; + if( r > ( (t_udbl) 1 << biL ) - 1 ) + r = ( (t_udbl) 1 << biL ) - 1; + + Z.p[i - t - 1] = (t_uint) r; +#else + /* + * __udiv_qrnnd_c, from gmp/longlong.h + */ + t_uint q0, q1, r0, r1; + t_uint d0, d1, d, m; + + d = Y.p[t]; + d0 = ( d << biH ) >> biH; + d1 = ( d >> biH ); + + q1 = X.p[i] / d1; + r1 = X.p[i] - d1 * q1; + r1 <<= biH; + r1 |= ( X.p[i - 1] >> biH ); + + m = q1 * d0; + if( r1 < m ) + { + q1--, r1 += d; + while( r1 >= d && r1 < m ) + q1--, r1 += d; + } + r1 -= m; + + q0 = r1 / d1; + r0 = r1 - d1 * q0; + r0 <<= biH; + r0 |= ( X.p[i - 1] << biH ) >> biH; + + m = q0 * d0; + if( r0 < m ) + { + q0--, r0 += d; + while( r0 >= d && r0 < m ) + q0--, r0 += d; + } + r0 -= m; + + Z.p[i - t - 1] = ( q1 << biH ) | q0; +#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */ + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MPI_CHK( mpi_lset( &T1, 0 ) ); + T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MPI_CHK( mpi_lset( &T2, 0 ) ); + T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; + T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); + + MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); + + if( mpi_cmp_int( &X, 0 ) < 0 ) + { + MPI_CHK( mpi_copy( &T1, &Y ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if( Q != NULL ) + { + MPI_CHK( mpi_copy( Q, &Z ) ); + Q->s = A->s * B->s; + } + + if( R != NULL ) + { + MPI_CHK( mpi_shift_r( &X, k ) ); + X.s = A->s; + MPI_CHK( mpi_copy( R, &X ) ); + + if( mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + mpi_free( &T1 ); mpi_free( &T2 ); + + return( ret ); +} + +/* + * Division by int: A = Q * b + R + */ +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_div_mpi( Q, R, A, &_B ) ); +} + +/* + * Modulo: R = A mod B + */ +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + + if( mpi_cmp_int( B, 0 ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); + + while( mpi_cmp_int( R, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( R, R, B ) ); + + while( mpi_cmp_mpi( R, B ) >= 0 ) + MPI_CHK( mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) +{ + size_t i; + t_uint x, y, z; + + if( b == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + if( b < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + /* + * handle trivial cases + */ + if( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for( i = A->n, y = 0; i > 0; i-- ) + { + x = A->p[i - 1]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if( A->s < 0 && y != 0 ) + y = b - y; + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +static void mpi_montg_init( t_uint *mm, const mpi *N ) +{ + t_uint x, m0 = N->p[0]; + unsigned int i; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + + for( i = biL; i >= 8; i /= 2 ) + x *= ( 2 - ( m0 * x ) ); + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, + const mpi *T ) +{ + size_t i, n, m; + t_uint u0, u1, *d; + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, ( n + 1 ) * ciL ); + + if( mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T ) +{ + t_uint z = 1; + mpi U; + + U.n = U.s = (int) z; + U.p = &z; + + mpi_montmul( A, &U, N, mm, T ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) +{ + int ret; + size_t wbits, wsize, one = 1; + size_t i, j, nblimbs; + size_t bufsize, nbits; + t_uint ei, mm, state; + mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos; + int neg; + + if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + if( mpi_cmp_int( E, 0 ) < 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mpi_init( &RR ); mpi_init( &T ); + mpi_init( &Apos ); + memset( W, 0, sizeof( W ) ); + + i = mpi_msb( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + if( wsize > POLARSSL_MPI_WINDOW_SIZE ) + wsize = POLARSSL_MPI_WINDOW_SIZE; + + j = N->n + 1; + MPI_CHK( mpi_grow( X, j ) ); + MPI_CHK( mpi_grow( &W[1], j ) ); + MPI_CHK( mpi_grow( &T, j * 2 ) ); + + /* + * Compensate for negative A (and correct at the end) + */ + neg = ( A->s == -1 ); + if( neg ) + { + MPI_CHK( mpi_copy( &Apos, A ) ); + Apos.s = 1; + A = &Apos; + } + + /* + * If 1st call, pre-compute R^2 mod N + */ + if( _RR == NULL || _RR->p == NULL ) + { + MPI_CHK( mpi_lset( &RR, 1 ) ); + MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); + MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); + + if( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if( mpi_cmp_mpi( A, N ) >= 0 ) + MPI_CHK( mpi_mod_mpi( &W[1], A, N ) ); + else + MPI_CHK( mpi_copy( &W[1], A ) ); + + mpi_montmul( &W[1], &RR, N, mm, &T ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MPI_CHK( mpi_copy( X, &RR ) ); + mpi_montred( X, N, mm, &T ); + + if( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = one << ( wsize - 1 ); + + MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[j], &W[1] ) ); + + for( i = 0; i < wsize - 1; i++ ) + mpi_montmul( &W[j], &W[j], N, mm, &T ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for( i = j + 1; i < ( one << wsize ); i++ ) + { + MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); + + mpi_montmul( &W[i], &W[1], N, mm, &T ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while( 1 ) + { + if( bufsize == 0 ) + { + if( nblimbs == 0 ) + break; + + nblimbs--; + + bufsize = sizeof( t_uint ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if( ei == 0 && state == 0 ) + continue; + + if( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + mpi_montmul( X, X, N, mm, &T ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= ( ei << ( wsize - nbits ) ); + + if( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for( i = 0; i < wsize; i++ ) + mpi_montmul( X, X, N, mm, &T ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + mpi_montmul( X, &W[wbits], N, mm, &T ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for( i = 0; i < nbits; i++ ) + { + mpi_montmul( X, X, N, mm, &T ); + + wbits <<= 1; + + if( ( wbits & ( one << wsize ) ) != 0 ) + mpi_montmul( X, &W[1], N, mm, &T ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred( X, N, mm, &T ); + + if( neg ) + { + X->s = -1; + MPI_CHK( mpi_add_mpi( X, N, X ) ); + } + +cleanup: + + for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) + mpi_free( &W[i] ); + + mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos ); + + if( _RR == NULL || _RR->p == NULL ) + mpi_free( &RR ); + + return( ret ); +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) +{ + int ret; + size_t lz, lzt; + mpi TG, TA, TB; + + mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB ); + + MPI_CHK( mpi_copy( &TA, A ) ); + MPI_CHK( mpi_copy( &TB, B ) ); + + lz = mpi_lsb( &TA ); + lzt = mpi_lsb( &TB ); + + if( lzt < lz ) + lz = lzt; + + MPI_CHK( mpi_shift_r( &TA, lz ) ); + MPI_CHK( mpi_shift_r( &TB, lz ) ); + + TA.s = TB.s = 1; + + while( mpi_cmp_int( &TA, 0 ) != 0 ) + { + MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); + MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); + + if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); + MPI_CHK( mpi_shift_r( &TA, 1 ) ); + } + else + { + MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); + MPI_CHK( mpi_shift_r( &TB, 1 ) ); + } + } + + MPI_CHK( mpi_shift_l( &TB, lz ) ); + MPI_CHK( mpi_copy( G, &TB ) ); + +cleanup: + + mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB ); + + return( ret ); +} + +/* + * Fill X with size bytes of random. + * + * Use a temporary bytes representation to make sure the result is the same + * regardless of the platform endianness (useful when f_rng is actually + * deterministic, eg for tests). + */ +int mpi_fill_random( mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + + if( size > POLARSSL_MPI_MAX_SIZE ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( f_rng( p_rng, buf, size ) ); + MPI_CHK( mpi_read_binary( X, buf, size ) ); + +cleanup: + return( ret ); +} + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ) +{ + int ret; + mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + + if( mpi_cmp_int( N, 0 ) <= 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 ); + mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV ); + mpi_init( &V1 ); mpi_init( &V2 ); + + MPI_CHK( mpi_gcd( &G, A, N ) ); + + if( mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); + MPI_CHK( mpi_copy( &TU, &TA ) ); + MPI_CHK( mpi_copy( &TB, N ) ); + MPI_CHK( mpi_copy( &TV, N ) ); + + MPI_CHK( mpi_lset( &U1, 1 ) ); + MPI_CHK( mpi_lset( &U2, 0 ) ); + MPI_CHK( mpi_lset( &V1, 0 ) ); + MPI_CHK( mpi_lset( &V2, 1 ) ); + + do + { + while( ( TU.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TU, 1 ) ); + + if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &U1, 1 ) ); + MPI_CHK( mpi_shift_r( &U2, 1 ) ); + } + + while( ( TV.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TV, 1 ) ); + + if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &V1, 1 ) ); + MPI_CHK( mpi_shift_r( &V2, 1 ) ); + } + + if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) + { + MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); + MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); + } + else + { + MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); + MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); + } + } + while( mpi_cmp_int( &TU, 0 ) != 0 ); + + while( mpi_cmp_int( &V1, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); + + while( mpi_cmp_mpi( &V1, N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); + + MPI_CHK( mpi_copy( X, &V1 ) ); + +cleanup: + + mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 ); + mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV ); + mpi_free( &V1 ); mpi_free( &V2 ); + + return( ret ); +} + +#if defined(POLARSSL_GENPRIME) + +static const int small_prime[] = +{ + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, + 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, + 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, + 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, + 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, + 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, -103 +}; + +/* + * Small divisors test (X must be positive) + * + * Return values: + * 0: no small factor (possible prime, more tests needed) + * 1: certain prime + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime + * other negative: error + */ +static int mpi_check_small_factors( const mpi *X ) +{ + int ret = 0; + size_t i; + t_uint r; + + if( ( X->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + for( i = 0; small_prime[i] > 0; i++ ) + { + if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) + return( 1 ); + + MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); + + if( r == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + +cleanup: + return( ret ); +} + +/* + * Miller-Rabin pseudo-primality test (HAC 4.24) + */ +static int mpi_miller_rabin( const mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i, j, n, s; + mpi W, R, T, A, RR; + + mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); + mpi_init( &RR ); + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + MPI_CHK( mpi_sub_int( &W, X, 1 ) ); + s = mpi_lsb( &W ); + MPI_CHK( mpi_copy( &R, &W ) ); + MPI_CHK( mpi_shift_r( &R, s ) ); + + i = mpi_msb( X ); + /* + * HAC, table 4.4 + */ + n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : + ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : + ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); + + for( i = 0; i < n; i++ ) + { + /* + * pick a random A, 1 < A < |X| - 1 + */ + MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); + + if( mpi_cmp_mpi( &A, &W ) >= 0 ) + { + j = mpi_msb( &A ) - mpi_msb( &W ); + MPI_CHK( mpi_shift_r( &A, j + 1 ) ); + } + A.p[0] |= 3; + + /* + * A = A^R mod |X| + */ + MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); + + if( mpi_cmp_mpi( &A, &W ) == 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + continue; + + j = 1; + while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) + { + /* + * A = A * A mod |X| + */ + MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); + MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); + + if( mpi_cmp_int( &A, 1 ) == 0 ) + break; + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if( mpi_cmp_mpi( &A, &W ) != 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); + mpi_free( &RR ); + + return( ret ); +} + +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +int mpi_is_prime( mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const mpi XX = { 1, X->n, X->p }; /* Abs(X) */ + + if( mpi_cmp_int( &XX, 0 ) == 0 || + mpi_cmp_int( &XX, 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + if( mpi_cmp_int( &XX, 2 ) == 0 ) + return( 0 ); + + if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) + { + if( ret == 1 ) + return( 0 ); + + return( ret ); + } + + return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); +} + +/* + * Prime number generation + */ +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t k, n; + t_uint r; + mpi Y; + + if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &Y ); + + n = BITS_TO_LIMBS( nbits ); + + MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); + + k = mpi_msb( X ); + if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); + if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); + + X->p[0] |= 3; + + if( dh_flag == 0 ) + { + while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) + { + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( X, X, 2 ) ); + } + } + else + { + /* + * An necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 + */ + MPI_CHK( mpi_mod_int( &r, X, 3 ) ); + if( r == 0 ) + MPI_CHK( mpi_add_int( X, X, 8 ) ); + else if( r == 1 ) + MPI_CHK( mpi_add_int( X, X, 4 ) ); + + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MPI_CHK( mpi_copy( &Y, X ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + + while( 1 ) + { + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if( ( ret = mpi_check_small_factors( X ) ) == 0 && + ( ret = mpi_check_small_factors( &Y ) ) == 0 && + ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && + ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) + { + break; + } + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + /* + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. + */ + MPI_CHK( mpi_add_int( X, X, 12 ) ); + MPI_CHK( mpi_add_int( &Y, &Y, 6 ) ); + } + } + +cleanup: + + mpi_free( &Y ); + + return( ret ); +} + +#endif /* POLARSSL_GENPRIME */ + +#if defined(POLARSSL_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mpi_self_test( int verbose ) +{ + int ret, i; + mpi A, E, N, X, Y, U, V; + + mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); + mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); + + MPI_CHK( mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MPI_CHK( mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MPI_CHK( mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #1 (mul_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MPI_CHK( mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #2 (div_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 || + mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #3 (exp_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #4 (inv_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #5 (simple gcd): " ); + + for( i = 0; i < GCD_PAIR_COUNT; i++ ) + { + MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); + MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed at %d\n", i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); + mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_BIGNUM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/blowfish.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/blowfish.c new file mode 100644 index 0000000..87396dc --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/blowfish.c @@ -0,0 +1,658 @@ +/* + * Blowfish implementation + * + * Copyright (C) 2012-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The Blowfish block cipher was designed by Bruce Schneier in 1993. + * http://www.schneier.com/blowfish.html + * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 + * + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BLOWFISH_C) + +#include "polarssl/blowfish.h" + +#if !defined(POLARSSL_BLOWFISH_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const uint32_t P[BLOWFISH_ROUNDS + 2] = { + 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, + 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, + 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, + 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, + 0x9216D5D9L, 0x8979FB1BL +}; + +/* declarations of data at the end of this file */ +static const uint32_t S[4][256]; + +static uint32_t F( blowfish_context *ctx, uint32_t x ) +{ + unsigned short a, b, c, d; + uint32_t y; + + d = (unsigned short)(x & 0xFF); + x >>= 8; + c = (unsigned short)(x & 0xFF); + x >>= 8; + b = (unsigned short)(x & 0xFF); + x >>= 8; + a = (unsigned short)(x & 0xFF); + y = ctx->S[0][a] + ctx->S[1][b]; + y = y ^ ctx->S[2][c]; + y = y + ctx->S[3][d]; + + return( y ); +} + +static void blowfish_enc( blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = 0; i < BLOWFISH_ROUNDS; ++i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[BLOWFISH_ROUNDS]; + Xl = Xl ^ ctx->P[BLOWFISH_ROUNDS + 1]; + + *xl = Xl; + *xr = Xr; +} + +static void blowfish_dec( blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = BLOWFISH_ROUNDS + 1; i > 1; --i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[1]; + Xl = Xl ^ ctx->P[0]; + + *xl = Xl; + *xr = Xr; +} + +void blowfish_init( blowfish_context *ctx ) +{ + memset( ctx, 0, sizeof( blowfish_context ) ); +} + +void blowfish_free( blowfish_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( blowfish_context ) ); +} + +/* + * Blowfish key schedule + */ +int blowfish_setkey( blowfish_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ + unsigned int i, j, k; + uint32_t data, datal, datar; + + if( keysize < BLOWFISH_MIN_KEY || keysize > BLOWFISH_MAX_KEY || + ( keysize % 8 ) ) + { + return( POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH ); + } + + keysize >>= 3; + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j++ ) + ctx->S[i][j] = S[i][j]; + } + + j = 0; + for( i = 0; i < BLOWFISH_ROUNDS + 2; ++i ) + { + data = 0x00000000; + for( k = 0; k < 4; ++k ) + { + data = ( data << 8 ) | key[j++]; + if( j >= keysize ) + j = 0; + } + ctx->P[i] = P[i] ^ data; + } + + datal = 0x00000000; + datar = 0x00000000; + + for( i = 0; i < BLOWFISH_ROUNDS + 2; i += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->P[i] = datal; + ctx->P[i + 1] = datar; + } + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->S[i][j] = datal; + ctx->S[i][j + 1] = datar; + } + } + return( 0 ); +} + +/* + * Blowfish-ECB block encryption/decryption + */ +int blowfish_crypt_ecb( blowfish_context *ctx, + int mode, + const unsigned char input[BLOWFISH_BLOCKSIZE], + unsigned char output[BLOWFISH_BLOCKSIZE] ) +{ + uint32_t X0, X1; + + GET_UINT32_BE( X0, input, 0 ); + GET_UINT32_BE( X1, input, 4 ); + + if( mode == BLOWFISH_DECRYPT ) + { + blowfish_dec( ctx, &X0, &X1 ); + } + else /* BLOWFISH_ENCRYPT */ + { + blowfish_enc( ctx, &X0, &X1 ); + } + + PUT_UINT32_BE( X0, output, 0 ); + PUT_UINT32_BE( X1, output, 4 ); + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * Blowfish-CBC buffer encryption/decryption + */ +int blowfish_crypt_cbc( blowfish_context *ctx, + int mode, + size_t length, + unsigned char iv[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[BLOWFISH_BLOCKSIZE]; + + if( length % BLOWFISH_BLOCKSIZE ) + return( POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); + + if( mode == BLOWFISH_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, BLOWFISH_BLOCKSIZE ); + blowfish_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < BLOWFISH_BLOCKSIZE;i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, BLOWFISH_BLOCKSIZE ); + + input += BLOWFISH_BLOCKSIZE; + output += BLOWFISH_BLOCKSIZE; + length -= BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < BLOWFISH_BLOCKSIZE; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + blowfish_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, BLOWFISH_BLOCKSIZE ); + + input += BLOWFISH_BLOCKSIZE; + output += BLOWFISH_BLOCKSIZE; + length -= BLOWFISH_BLOCKSIZE; + } + } + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * Blowfish CFB buffer encryption/decryption + */ +int blowfish_crypt_cfb64( blowfish_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == BLOWFISH_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * Blowfish CTR buffer encryption/decryption + */ +int blowfish_crypt_ctr( blowfish_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[BLOWFISH_BLOCKSIZE], + unsigned char stream_block[BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + blowfish_crypt_ecb( ctx, BLOWFISH_ENCRYPT, nonce_counter, + stream_block ); + + for( i = BLOWFISH_BLOCKSIZE; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) % BLOWFISH_BLOCKSIZE; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +static const uint32_t S[4][256] = { + { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, + 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, + 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, + 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, + 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, + 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, + 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, + 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, + 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, + 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, + 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, + 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, + 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, + 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, + 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, + 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, + 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, + 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, + 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, + 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, + 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, + 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, + 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, + 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, + 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, + 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, + 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, + 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, + 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, + 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, + 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, + 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, + 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, + 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, + 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, + 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, + 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, + 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, + 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, + 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, + 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, + 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, + 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, + 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, + 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, + 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, + 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, + 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, + 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, + 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, + 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, + 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, + 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, + 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, + 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, + 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, + 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, + 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, + 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, + 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, + 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, + 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, + 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, + 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, + { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, + 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, + 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, + 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, + 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, + 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, + 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, + 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, + 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, + 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, + 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, + 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, + 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, + 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, + 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, + 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, + 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, + 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, + 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, + 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, + 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, + 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, + 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, + 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, + 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, + 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, + 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, + 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, + 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, + 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, + 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, + 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, + 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, + 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, + 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, + 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, + 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, + 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, + 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, + 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, + 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, + 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, + 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, + 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, + 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, + 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, + 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, + 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, + 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, + 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, + 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, + 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, + 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, + 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, + 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, + 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, + 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, + 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, + 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, + 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, + 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, + 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, + 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, + 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, + { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, + 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, + 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, + 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, + 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, + 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, + 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, + 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, + 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, + 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, + 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, + 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, + 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, + 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, + 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, + 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, + 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, + 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, + 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, + 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, + 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, + 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, + 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, + 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, + 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, + 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, + 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, + 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, + 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, + 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, + 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, + 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, + 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, + 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, + 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, + 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, + 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, + 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, + 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, + 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, + 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, + 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, + 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, + 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, + 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, + 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, + 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, + 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, + 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, + 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, + 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, + 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, + 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, + 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, + 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, + 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, + 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, + 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, + 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, + 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, + 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, + 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, + 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, + 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, + { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, + 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, + 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, + 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, + 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, + 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, + 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, + 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, + 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, + 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, + 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, + 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, + 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, + 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, + 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, + 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, + 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, + 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, + 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, + 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, + 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, + 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, + 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, + 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, + 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, + 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, + 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, + 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, + 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, + 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, + 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, + 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, + 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, + 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, + 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, + 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, + 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, + 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, + 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, + 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, + 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, + 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, + 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, + 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, + 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, + 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, + 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, + 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, + 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, + 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, + 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, + 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, + 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, + 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, + 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, + 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, + 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, + 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, + 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, + 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, + 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, + 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, + 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, + 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } +}; + +#endif /* !POLARSSL_BLOWFISH_ALT */ +#endif /* POLARSSL_BLOWFISH_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/camellia.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/camellia.c new file mode 100644 index 0000000..a4968f4 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/camellia.c @@ -0,0 +1,1073 @@ +/* + * Camellia implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The Camellia block cipher was designed by NTT and Mitsubishi Electric + * Corporation. + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CAMELLIA_C) + +#include "polarssl/camellia.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_CAMELLIA_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const unsigned char SIGMA_CHARS[6][8] = +{ + { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, + { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, + { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, + { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, + { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, + { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } +}; + +#if defined(POLARSSL_CAMELLIA_SMALL_MEMORY) + +static const unsigned char FSb[256] = +{ + 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, + 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, + 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, + 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, + 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, + 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, + 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, + 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, + 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, + 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, + 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, + 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) +#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) +#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] + +#else /* POLARSSL_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char FSb[256] = +{ + 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, + 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, + 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, + 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, + 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, + 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, + 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, + 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, + 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, + 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, + 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 +}; + +static const unsigned char FSb2[256] = +{ + 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, + 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, + 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, + 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, + 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, + 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, + 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, + 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 +}; + +static const unsigned char FSb3[256] = +{ + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, + 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, + 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, + 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, + 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, + 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, + 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 +}; + +static const unsigned char FSb4[256] = +{ + 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, + 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, + 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, + 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, + 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, + 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, + 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, + 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, + 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, + 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, + 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) FSb2[(n)] +#define SBOX3(n) FSb3[(n)] +#define SBOX4(n) FSb4[(n)] + +#endif /* POLARSSL_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char shifts[2][4][4] = +{ + { + { 1, 1, 1, 1 }, /* KL */ + { 0, 0, 0, 0 }, /* KR */ + { 1, 1, 1, 1 }, /* KA */ + { 0, 0, 0, 0 } /* KB */ + }, + { + { 1, 0, 1, 1 }, /* KL */ + { 1, 1, 0, 1 }, /* KR */ + { 1, 1, 1, 0 }, /* KA */ + { 1, 1, 0, 1 } /* KB */ + } +}; + +static const signed char indexes[2][4][20] = +{ + { + { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, + 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ + { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, + 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ + }, + { + { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, + -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ + { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, + 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ + { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, + 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ + { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, + 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ + } +}; + +static const signed char transposes[2][20] = +{ + { + 21, 22, 23, 20, + -1, -1, -1, -1, + 18, 19, 16, 17, + 11, 8, 9, 10, + 15, 12, 13, 14 + }, + { + 25, 26, 27, 24, + 29, 30, 31, 28, + 18, 19, 16, 17, + -1, -1, -1, -1, + -1, -1, -1, -1 + } +}; + +/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ +#define ROTL(DEST, SRC, SHIFT) \ +{ \ + (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ + (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ + (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ + (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ +} + +#define FL(XL, XR, KL, KR) \ +{ \ + (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ + (XL) = ((XR) | (KR)) ^ (XL); \ +} + +#define FLInv(YL, YR, KL, KR) \ +{ \ + (YL) = ((YR) | (KR)) ^ (YL); \ + (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ +} + +#define SHIFT_AND_PLACE(INDEX, OFFSET) \ +{ \ + TK[0] = KC[(OFFSET) * 4 + 0]; \ + TK[1] = KC[(OFFSET) * 4 + 1]; \ + TK[2] = KC[(OFFSET) * 4 + 2]; \ + TK[3] = KC[(OFFSET) * 4 + 3]; \ + \ + for( i = 1; i <= 4; i++ ) \ + if( shifts[(INDEX)][(OFFSET)][i -1] ) \ + ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ + \ + for( i = 0; i < 20; i++ ) \ + if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ + RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ + } \ +} + +static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], + uint32_t z[2]) +{ + uint32_t I0, I1; + I0 = x[0] ^ k[0]; + I1 = x[1] ^ k[1]; + + I0 = (SBOX1((I0 >> 24) & 0xFF) << 24) | + (SBOX2((I0 >> 16) & 0xFF) << 16) | + (SBOX3((I0 >> 8) & 0xFF) << 8) | + (SBOX4((I0 ) & 0xFF) ); + I1 = (SBOX2((I1 >> 24) & 0xFF) << 24) | + (SBOX3((I1 >> 16) & 0xFF) << 16) | + (SBOX4((I1 >> 8) & 0xFF) << 8) | + (SBOX1((I1 ) & 0xFF) ); + + I0 ^= (I1 << 8) | (I1 >> 24); + I1 ^= (I0 << 16) | (I0 >> 16); + I0 ^= (I1 >> 8) | (I1 << 24); + I1 ^= (I0 >> 8) | (I0 << 24); + + z[0] ^= I1; + z[1] ^= I0; +} + +void camellia_init( camellia_context *ctx ) +{ + memset( ctx, 0, sizeof( camellia_context ) ); +} + +void camellia_free( camellia_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( camellia_context ) ); +} + +/* + * Camellia key schedule (encryption) + */ +int camellia_setkey_enc( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ + int idx; + size_t i; + uint32_t *RK; + unsigned char t[64]; + uint32_t SIGMA[6][2]; + uint32_t KC[16]; + uint32_t TK[20]; + + RK = ctx->rk; + + memset( t, 0, 64 ); + memset( RK, 0, sizeof(ctx->rk) ); + + switch( keysize ) + { + case 128: ctx->nr = 3; idx = 0; break; + case 192: + case 256: ctx->nr = 4; idx = 1; break; + default : return( POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH ); + } + + for( i = 0; i < keysize / 8; ++i ) + t[i] = key[i]; + + if( keysize == 192 ) { + for( i = 0; i < 8; i++ ) + t[24 + i] = ~t[16 + i]; + } + + /* + * Prepare SIGMA values + */ + for( i = 0; i < 6; i++ ) { + GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); + GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); + } + + /* + * Key storage in KC + * Order: KL, KR, KA, KB + */ + memset( KC, 0, sizeof(KC) ); + + /* Store KL, KR */ + for( i = 0; i < 8; i++ ) + GET_UINT32_BE( KC[i], t, i * 4 ); + + /* Generate KA */ + for( i = 0; i < 4; ++i ) + KC[8 + i] = KC[i] ^ KC[4 + i]; + + camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); + + for( i = 0; i < 4; ++i ) + KC[8 + i] ^= KC[i]; + + camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); + + if( keysize > 128 ) { + /* Generate KB */ + for( i = 0; i < 4; ++i ) + KC[12 + i] = KC[4 + i] ^ KC[8 + i]; + + camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); + camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); + } + + /* + * Generating subkeys + */ + + /* Manipulating KL */ + SHIFT_AND_PLACE( idx, 0 ); + + /* Manipulating KR */ + if( keysize > 128 ) { + SHIFT_AND_PLACE( idx, 1 ); + } + + /* Manipulating KA */ + SHIFT_AND_PLACE( idx, 2 ); + + /* Manipulating KB */ + if( keysize > 128 ) { + SHIFT_AND_PLACE( idx, 3 ); + } + + /* Do transpositions */ + for( i = 0; i < 20; i++ ) { + if( transposes[idx][i] != -1 ) { + RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; + } + } + + return( 0 ); +} + +/* + * Camellia key schedule (decryption) + */ +int camellia_setkey_dec( camellia_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ + int idx, ret; + size_t i; + camellia_context cty; + uint32_t *RK; + uint32_t *SK; + + camellia_init( &cty ); + + /* Also checks keysize */ + if( ( ret = camellia_setkey_enc( &cty, key, keysize ) ) ) + goto exit; + + ctx->nr = cty.nr; + idx = ( ctx->nr == 4 ); + + RK = ctx->rk; + SK = cty.rk + 24 * 2 + 8 * idx * 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) + { + *RK++ = *SK++; + *RK++ = *SK++; + } + + SK -= 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + camellia_free( &cty ); + + return( ret ); +} + +/* + * Camellia-ECB block encryption/decryption + */ +int camellia_crypt_ecb( camellia_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int NR; + uint32_t *RK, X[4]; + + ( (void) mode ); + + NR = ctx->nr; + RK = ctx->rk; + + GET_UINT32_BE( X[0], input, 0 ); + GET_UINT32_BE( X[1], input, 4 ); + GET_UINT32_BE( X[2], input, 8 ); + GET_UINT32_BE( X[3], input, 12 ); + + X[0] ^= *RK++; + X[1] ^= *RK++; + X[2] ^= *RK++; + X[3] ^= *RK++; + + while( NR ) { + --NR; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + + if( NR ) { + FL(X[0], X[1], RK[0], RK[1]); + RK += 2; + FLInv(X[2], X[3], RK[0], RK[1]); + RK += 2; + } + } + + X[2] ^= *RK++; + X[3] ^= *RK++; + X[0] ^= *RK++; + X[1] ^= *RK++; + + PUT_UINT32_BE( X[2], output, 0 ); + PUT_UINT32_BE( X[3], output, 4 ); + PUT_UINT32_BE( X[0], output, 8 ); + PUT_UINT32_BE( X[1], output, 12 ); + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * Camellia-CBC buffer encryption/decryption + */ +int camellia_crypt_cbc( camellia_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); + + if( mode == CAMELLIA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + camellia_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + camellia_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * Camellia-CFB128 buffer encryption/decryption + */ +int camellia_crypt_cfb128( camellia_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == CAMELLIA_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * Camellia-CTR buffer encryption/decryption + */ +int camellia_crypt_ctr( camellia_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + camellia_crypt_ecb( ctx, CAMELLIA_ENCRYPT, nonce_counter, + stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CTR */ +#endif /* !POLARSSL_CAMELLIA_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * Camellia test vectors from: + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt + * (For each bitlength: Key 0, Nr 39) + */ +#define CAMELLIA_TESTS_ECB 2 + +static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = +{ + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, +}; + +static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = +{ + { + { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, + 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, + { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, + 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } + }, + { + { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, + 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, + { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, + 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } + }, + { + { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, + { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, + 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } + } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#define CAMELLIA_TESTS_CBC 3 + +static const unsigned char camellia_test_cbc_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } + , + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } + , + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char camellia_test_cbc_iv[16] = + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } +; + +static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = +{ + { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, + { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, + { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } + +}; + +static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = +{ + { + { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, + 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, + { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, + 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, + { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, + 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } + }, + { + { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, + 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, + { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, + 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, + { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, + 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } + }, + { + { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, + 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, + { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, + 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, + { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, + 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } + } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * Camellia-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc5528.html + */ + +static const unsigned char camellia_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char camellia_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char camellia_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char camellia_test_ctr_ct[3][48] = +{ + { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, + 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, + { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, + 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, + 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, + 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, + { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, + 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, + 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, + 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, + 0xDF, 0x50, 0x86, 0x96 } +}; + +static const int camellia_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int camellia_self_test( int verbose ) +{ + int i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char src[16]; + unsigned char dst[16]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char iv[16]; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + size_t offset, len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + + camellia_context ctx; + + memset( key, 0, 32 ); + + for( j = 0; j < 6; j++ ) { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + polarssl_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, + (v == CAMELLIA_DECRYPT) ? "dec" : "enc"); + + for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { + memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); + + if( v == CAMELLIA_DECRYPT ) { + camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); + memcpy( dst, camellia_test_ecb_plain[i], 16 ); + } else { /* CAMELLIA_ENCRYPT */ + camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_plain[i], 16 ); + memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); + } + + camellia_crypt_ecb( &ctx, v, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( j = 0; j < 6; j++ ) + { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + polarssl_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, + ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( src, camellia_test_cbc_iv, 16 ); + memcpy( dst, camellia_test_cbc_iv, 16 ); + memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); + + if( v == CAMELLIA_DECRYPT ) { + camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + } else { + camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + } + + for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { + + if( v == CAMELLIA_DECRYPT ) { + memcpy( iv , src, 16 ); + memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); + memcpy( dst, camellia_test_cbc_plain[i], 16 ); + } else { /* CAMELLIA_ENCRYPT */ + memcpy( iv , dst, 16 ); + memcpy( src, camellia_test_cbc_plain[i], 16 ); + memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); + } + + camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " CAMELLIA-CTR-128 (%s): ", + ( v == CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); + memcpy( key, camellia_test_ctr_key[u], 16 ); + + offset = 0; + camellia_setkey_enc( &ctx, key, 128 ); + + if( v == CAMELLIA_DECRYPT ) + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_ct[u], len ); + + camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_pt[u], len ); + + camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_CAMELLIA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ccm.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ccm.c new file mode 100644 index 0000000..72d766b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ccm.c @@ -0,0 +1,456 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CCM_C) + +#include "polarssl/ccm.h" + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +int ccm_init( ccm_context *ctx, cipher_id_t cipher, + const unsigned char *key, unsigned int keysize ) +{ + int ret; + const cipher_info_t *cipher_info; + + memset( ctx, 0, sizeof( ccm_context ) ); + + cipher_init( &ctx->cipher_ctx ); + + cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize, + POLARSSL_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void ccm_free( ccm_context *ctx ) +{ + cipher_free( &ctx->cipher_ctx ); + polarssl_zeroize( ctx, sizeof( ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q = 16 - 1 - iv_len; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( POLARSSL_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + unsigned char use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int ccm_encrypt_and_tag( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int ccm_auth_decrypt( ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + polarssl_zeroize( output, length ); + return( POLARSSL_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif + +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#define NB_TESTS 3 + +/* + * The data is the same for all tests, only the used length changes + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][32] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int ccm_self_test( int verbose ) +{ + ccm_context ctx; + unsigned char out[32]; + size_t i; + int ret; + + if( ccm_init( &ctx, POLARSSL_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); + + ret = ccm_encrypt_and_tag( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + msg, out, + out + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + ret = ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + res[i], out, + res[i] + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + ccm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ + +#endif /* POLARSSL_CCM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/certs.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/certs.c new file mode 100644 index 0000000..a782bc1 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/certs.c @@ -0,0 +1,310 @@ +/* + * X.509 test certificates + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CERTS_C) + +#if defined(POLARSSL_ECDSA_C) +#define TEST_CA_CRT_EC \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ +"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ +"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ +"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ +"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ +"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ +"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ +"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ +"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ +"-----END CERTIFICATE-----\r\n" +const char test_ca_crt_ec[] = TEST_CA_CRT_EC; + +const char test_ca_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" +"\r\n" +"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" +"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" +"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" +"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" +"-----END EC PRIVATE KEY-----\r\n"; + +const char test_ca_pwd_ec[] = "PolarSSLTest"; + +const char test_srv_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" +"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" +"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" +"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" +"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" +"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" +"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" +"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" +"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char test_srv_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" +"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" +"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; + +const char test_cli_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" +"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" +"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" +"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" +"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" +"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" +"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" +"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char test_cli_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" +"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" +"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; +#else +#define TEST_CA_CRT_EC +#endif /* POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_RSA_C) +#define TEST_CA_CRT_RSA \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ +"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ +"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ +"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ +"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ +"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ +"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ +"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ +"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ +"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \ +"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \ +"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \ +"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \ +"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \ +"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \ +"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \ +"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ +"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ +"-----END CERTIFICATE-----\r\n" +const char test_ca_crt_rsa[] = TEST_CA_CRT_RSA; + +const char test_ca_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" +"\r\n" +"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" +"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" +"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" +"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" +"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" +"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" +"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" +"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" +"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" +"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" +"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" +"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" +"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" +"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" +"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" +"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" +"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" +"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" +"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" +"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" +"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" +"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" +"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" +"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" +"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; + +const char test_ca_pwd_rsa[] = "PolarSSLTest"; + +const char test_srv_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" +"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" +"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" +"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" +"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" +"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" +"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" +"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" +"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n" +"oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n" +"UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n" +"iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n" +"wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n" +"RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n" +"zhuYwjVuX6JHG0c=\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char test_srv_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" +"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" +"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" +"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" +"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" +"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" +"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" +"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" +"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" +"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" +"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" +"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" +"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" +"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" +"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" +"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" +"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" +"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" +"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" +"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" +"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" +"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" +"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" +"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" +"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; + + +const char test_cli_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" +"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" +"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" +"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" +"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" +"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" +"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" +"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" +"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n" +"AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n" +"LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n" +"Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n" +"8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n" +"xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n" +"D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char test_cli_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" +"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" +"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" +"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" +"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" +"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" +"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" +"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" +"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" +"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" +"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" +"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" +"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" +"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" +"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" +"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" +"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" +"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" +"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" +"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" +"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" +"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" +"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" +"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" +"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; +#else +#define TEST_CA_CRT_RSA +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_DHM_C) +const char test_dhm_params[] = +"-----BEGIN DH PARAMETERS-----\r\n" +"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" +"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" +"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" +"-----END DH PARAMETERS-----\r\n"; +#endif + +/* Concatenation of all available CA certificates */ +const char test_ca_list[] = TEST_CA_CRT_RSA TEST_CA_CRT_EC; + +#if defined(POLARSSL_RSA_C) +const char *test_ca_crt = test_ca_crt_rsa; +const char *test_ca_key = test_ca_key_rsa; +const char *test_ca_pwd = test_ca_pwd_rsa; +const char *test_srv_crt = test_srv_crt_rsa; +const char *test_srv_key = test_srv_key_rsa; +const char *test_cli_crt = test_cli_crt_rsa; +const char *test_cli_key = test_cli_key_rsa; +#else /* ! POLARSSL_RSA_C, so POLARSSL_ECDSA_C */ +const char *test_ca_crt = test_ca_crt_ec; +const char *test_ca_key = test_ca_key_ec; +const char *test_ca_pwd = test_ca_pwd_ec; +const char *test_srv_crt = test_srv_crt_ec; +const char *test_srv_key = test_srv_key_ec; +const char *test_cli_crt = test_cli_crt_ec; +const char *test_cli_key = test_cli_key_ec; +#endif /* POLARSSL_RSA_C */ + +#endif /* POLARSSL_CERTS_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher.c new file mode 100644 index 0000000..5cd30f8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher.c @@ -0,0 +1,917 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CIPHER_C) + +#include "polarssl/cipher.h" +#include "polarssl/cipher_wrap.h" + +#if defined(POLARSSL_GCM_C) +#include "polarssl/gcm.h" +#endif + +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + +#include + +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) +#define POLARSSL_CIPHER_MODE_STREAM +#endif + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +static int supported_init = 0; + +const int *cipher_list( void ) +{ + const cipher_definition_t *def; + int *type; + + if( ! supported_init ) + { + def = cipher_definitions; + type = supported_ciphers; + + while( def->type != 0 ) + *type++ = (*def++).type; + + *type = 0; + + supported_init = 1; + } + + return( supported_ciphers ); +} + +const cipher_info_t *cipher_info_from_type( const cipher_type_t cipher_type ) +{ + const cipher_definition_t *def; + + for( def = cipher_definitions; def->info != NULL; def++ ) + if( def->type == cipher_type ) + return( def->info ); + + return( NULL ); +} + +const cipher_info_t *cipher_info_from_string( const char *cipher_name ) +{ + const cipher_definition_t *def; + + if( NULL == cipher_name ) + return( NULL ); + + for( def = cipher_definitions; def->info != NULL; def++ ) + if( ! strcasecmp( def->info->name, cipher_name ) ) + return( def->info ); + + return( NULL ); +} + +const cipher_info_t *cipher_info_from_values( const cipher_id_t cipher_id, + int key_length, + const cipher_mode_t mode ) +{ + const cipher_definition_t *def; + + for( def = cipher_definitions; def->info != NULL; def++ ) + if( def->info->base->cipher == cipher_id && + def->info->key_length == (unsigned) key_length && + def->info->mode == mode ) + return( def->info ); + + return( NULL ); +} + +void cipher_init( cipher_context_t *ctx ) +{ + memset( ctx, 0, sizeof( cipher_context_t ) ); +} + +void cipher_free( cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + polarssl_zeroize( ctx, sizeof(cipher_context_t) ); +} + +int cipher_init_ctx( cipher_context_t *ctx, const cipher_info_t *cipher_info ) +{ + if( NULL == cipher_info || NULL == ctx ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( cipher_context_t ) ); + + if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) + return( POLARSSL_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cipher_info = cipher_info; + +#if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) + /* + * Ignore possible errors caused by a cipher mode that doesn't use padding + */ +#if defined(POLARSSL_CIPHER_PADDING_PKCS7) + (void) cipher_set_padding_mode( ctx, POLARSSL_PADDING_PKCS7 ); +#else + (void) cipher_set_padding_mode( ctx, POLARSSL_PADDING_NONE ); +#endif +#endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ + + return( 0 ); +} + +/* Deprecated, redirects to cipher_free() */ +int cipher_free_ctx( cipher_context_t *ctx ) +{ + cipher_free( ctx ); + + return( 0 ); +} + +int cipher_setkey( cipher_context_t *ctx, const unsigned char *key, + int key_length, const operation_t operation ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( ctx->cipher_info->flags & POLARSSL_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_length != key_length ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ctx->key_length = key_length; + ctx->operation = operation; + + /* + * For CFB and CTR mode always use the encryption key schedule + */ + if( POLARSSL_ENCRYPT == operation || + POLARSSL_MODE_CFB == ctx->cipher_info->mode || + POLARSSL_MODE_CTR == ctx->cipher_info->mode ) + { + return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_length ); + } + + if( POLARSSL_DECRYPT == operation ) + return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_length ); + + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); +} + +int cipher_set_iv( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ) +{ + size_t actual_iv_size; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + /* avoid buffer overflow in ctx->iv */ + if( iv_len > POLARSSL_MAX_IV_LENGTH ) + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + if( ( ctx->cipher_info->flags & POLARSSL_CIPHER_VARIABLE_IV_LEN ) != 0 ) + actual_iv_size = iv_len; + else + { + actual_iv_size = ctx->cipher_info->iv_size; + + /* avoid reading past the end of input buffer */ + if( actual_iv_size > iv_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( ctx->iv, iv, actual_iv_size ); + ctx->iv_size = actual_iv_size; + + return( 0 ); +} + +int cipher_reset( cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + ctx->unprocessed_len = 0; + + return( 0 ); +} + +#if defined(POLARSSL_GCM_C) +int cipher_update_ad( cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + return gcm_starts( (gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ); + } + + return( 0 ); +} +#endif /* POLARSSL_GCM_C */ + +int cipher_update( cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) +{ + int ret; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = 0; + + if( ctx->cipher_info->mode == POLARSSL_MODE_ECB ) + { + if( ilen != cipher_get_block_size( ctx ) ) + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + *olen = ilen; + + if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, + ctx->operation, input, output ) ) ) + { + return( ret ); + } + + return( 0 ); + } + +#if defined(POLARSSL_GCM_C) + if( ctx->cipher_info->mode == POLARSSL_MODE_GCM ) + { + *olen = ilen; + return gcm_update( (gcm_context *) ctx->cipher_ctx, ilen, input, + output ); + } +#endif + + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(POLARSSL_CIPHER_MODE_CBC) + if( ctx->cipher_info->mode == POLARSSL_MODE_CBC ) + { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if( ( ctx->operation == POLARSSL_DECRYPT && + ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) || + ( ctx->operation == POLARSSL_ENCRYPT && + ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) ) + { + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + ilen ); + + ctx->unprocessed_len += ilen; + return( 0 ); + } + + /* + * Process cached data first + */ + if( ctx->unprocessed_len != 0 ) + { + copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + copy_len ); + + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + *olen += cipher_get_block_size( ctx ); + output += cipher_get_block_size( ctx ); + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if( 0 != ilen ) + { + copy_len = ilen % cipher_get_block_size( ctx ); + if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT ) + copy_len = cipher_get_block_size( ctx ); + + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + copy_len ); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if( ilen ) + { + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen += ilen; + } + + return( 0 ); + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) + if( ctx->cipher_info->mode == POLARSSL_MODE_CFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, + ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, + input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) + if( ctx->cipher_info->mode == POLARSSL_MODE_CTR ) + { + if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, + ctx->unprocessed_data, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#if defined(POLARSSL_CIPHER_MODE_STREAM) + if( ctx->cipher_info->mode == POLARSSL_MODE_STREAM ) + { + if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, + ilen, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* POLARSSL_CIPHER_MODE_STREAM */ + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) +#if defined(POLARSSL_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding( unsigned char *output, size_t output_len, + size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for( i = 0; i < padding_len; i++ ) + output[data_len + i] = (unsigned char) padding_len; +} + +static int get_pkcs_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len; i++ ) + bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); + + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* POLARSSL_CIPHER_PADDING_PKCS7 */ + +#if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for( i = 1; i < padding_len; i++ ) + output[data_len + i] = 0x00; +} + +static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done, bad; + + if( NULL == input || NULL == data_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + bad = 0xFF; + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= ( i - 1 ) * ( done != prev_done ); + bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); + } + + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); + +} +#endif /* POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for( i = 1; i < padding_len; i++ ) + output[data_len + i - 1] = 0x00; + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len - 1; i++ ) + bad |= input[i] * ( i >= pad_idx ); + + return( POLARSSL_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(POLARSSL_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t i; + + for( i = data_len; i < output_len; i++ ) + output[i] = 0x00; +} + +static int get_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done; + + if( NULL == input || NULL == data_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= i * ( done != prev_done ); + } + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + if( NULL == input || NULL == data_len ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = input_len; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ + +int cipher_finish( cipher_context_t *ctx, + unsigned char *output, size_t *olen ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + *olen = 0; + + if( POLARSSL_MODE_CFB == ctx->cipher_info->mode || + POLARSSL_MODE_CTR == ctx->cipher_info->mode || + POLARSSL_MODE_GCM == ctx->cipher_info->mode || + POLARSSL_MODE_STREAM == ctx->cipher_info->mode ) + { + return( 0 ); + } + + if( POLARSSL_MODE_ECB == ctx->cipher_info->mode ) + { + if( ctx->unprocessed_len != 0 ) + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + +#if defined(POLARSSL_CIPHER_MODE_CBC) + if( POLARSSL_MODE_CBC == ctx->cipher_info->mode ) + { + int ret = 0; + + if( POLARSSL_ENCRYPT == ctx->operation ) + { + /* check for 'no padding' mode */ + if( NULL == ctx->add_padding ) + { + if( 0 != ctx->unprocessed_len ) + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + + ctx->add_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ), + ctx->unprocessed_len ); + } + else if( cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) + return( 0 ); + + return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + } + + /* cipher block */ + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + /* Set output size for decryption */ + if( POLARSSL_DECRYPT == ctx->operation ) + return ctx->get_padding( output, cipher_get_block_size( ctx ), + olen ); + + /* Set output size for encryption */ + *olen = cipher_get_block_size( ctx ); + return( 0 ); + } +#else + ((void) output); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(POLARSSL_CIPHER_MODE_WITH_PADDING) +int cipher_set_padding_mode( cipher_context_t *ctx, cipher_padding_t mode ) +{ + if( NULL == ctx || + POLARSSL_MODE_CBC != ctx->cipher_info->mode ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + + switch( mode ) + { +#if defined(POLARSSL_CIPHER_PADDING_PKCS7) + case POLARSSL_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) + case POLARSSL_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) + case POLARSSL_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(POLARSSL_CIPHER_PADDING_ZEROS) + case POLARSSL_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case POLARSSL_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_WITH_PADDING */ + +#if defined(POLARSSL_GCM_C) +int cipher_write_tag( cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + if( POLARSSL_ENCRYPT != ctx->operation ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + return gcm_finish( (gcm_context *) ctx->cipher_ctx, tag, tag_len ); + + return( 0 ); +} + +int cipher_check_tag( cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + + if( NULL == ctx || NULL == ctx->cipher_info || + POLARSSL_DECRYPT != ctx->operation ) + { + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + unsigned char check_tag[16]; + size_t i; + int diff; + + if( tag_len > sizeof( check_tag ) ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + if( 0 != ( ret = gcm_finish( (gcm_context *) ctx->cipher_ctx, + check_tag, tag_len ) ) ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + return( POLARSSL_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } + + return( 0 ); +} +#endif /* POLARSSL_GCM_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int cipher_crypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + if( ( ret = cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) + return( ret ); + + *olen += finish_olen; + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes + */ +int cipher_auth_encrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ +#if defined(POLARSSL_GCM_C) + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( gcm_crypt_and_tag( ctx->cipher_ctx, GCM_ENCRYPT, ilen, + iv, iv_len, ad, ad_len, input, output, + tag_len, tag ) ); + } +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_CCM_C) + if( POLARSSL_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* POLARSSL_CCM_C */ + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int cipher_auth_decrypt( cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ +#if defined(POLARSSL_GCM_C) + if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == POLARSSL_ERR_GCM_AUTH_FAILED ) + ret = POLARSSL_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_CCM_C) + if( POLARSSL_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == POLARSSL_ERR_CCM_AUTH_FAILED ) + ret = POLARSSL_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* POLARSSL_CCM_C */ + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* POLARSSL_CIPHER_MODE_AEAD */ + + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int cipher_self_test( int verbose ) +{ + ((void) verbose); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_CIPHER_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher_wrap.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher_wrap.c new file mode 100644 index 0000000..27aa3db --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/cipher_wrap.c @@ -0,0 +1,1451 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CIPHER_C) + +#include "polarssl/cipher_wrap.h" + +#if defined(POLARSSL_AES_C) +#include "polarssl/aes.h" +#endif + +#if defined(POLARSSL_ARC4_C) +#include "polarssl/arc4.h" +#endif + +#if defined(POLARSSL_CAMELLIA_C) +#include "polarssl/camellia.h" +#endif + +#if defined(POLARSSL_DES_C) +#include "polarssl/des.h" +#endif + +#if defined(POLARSSL_BLOWFISH_C) +#include "polarssl/blowfish.h" +#endif + +#if defined(POLARSSL_GCM_C) +#include "polarssl/gcm.h" +#endif + +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +#if defined(POLARSSL_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( gcm_context ) ); +} + +static void gcm_ctx_free( void *ctx ) +{ + gcm_free( ctx ); + polarssl_free( ctx ); +} +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( ccm_context ) ); +} + +static void ccm_ctx_free( void *ctx ) +{ + ccm_free( ctx ); + polarssl_free( ctx ); +} +#endif /* POLARSSL_CCM_C */ + +#if defined(POLARSSL_AES_C) + +static int aes_crypt_ecb_wrap( void *ctx, operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return aes_crypt_ecb( (aes_context *) ctx, operation, input, output ); +} + +static int aes_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CBC) + return aes_crypt_cbc( (aes_context *) ctx, operation, length, iv, input, + output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ +} + +static int aes_crypt_cfb128_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CFB) + return aes_crypt_cfb128( (aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv_off); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ +} + +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CTR) + return aes_crypt_ctr( (aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +#else + ((void) ctx); + ((void) length); + ((void) nc_off); + ((void) nonce_counter); + ((void) stream_block); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ +} + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return aes_setkey_dec( (aes_context *) ctx, key, key_length ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return aes_setkey_enc( (aes_context *) ctx, key, key_length ); +} + +static void * aes_ctx_alloc( void ) +{ + aes_context *aes = (aes_context *) polarssl_malloc( sizeof( aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + aes_free( (aes_context *) ctx ); + polarssl_free( ctx ); +} + +const cipher_base_t aes_info = { + POLARSSL_CIPHER_ID_AES, + aes_crypt_ecb_wrap, + aes_crypt_cbc_wrap, + aes_crypt_cfb128_wrap, + aes_crypt_ctr_wrap, + NULL, + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +const cipher_info_t aes_128_ecb_info = { + POLARSSL_CIPHER_AES_128_ECB, + POLARSSL_MODE_ECB, + 128, + "AES-128-ECB", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_192_ecb_info = { + POLARSSL_CIPHER_AES_192_ECB, + POLARSSL_MODE_ECB, + 192, + "AES-192-ECB", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_256_ecb_info = { + POLARSSL_CIPHER_AES_256_ECB, + POLARSSL_MODE_ECB, + 256, + "AES-256-ECB", + 16, + 0, + 16, + &aes_info +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t aes_128_cbc_info = { + POLARSSL_CIPHER_AES_128_CBC, + POLARSSL_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_192_cbc_info = { + POLARSSL_CIPHER_AES_192_CBC, + POLARSSL_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_256_cbc_info = { + POLARSSL_CIPHER_AES_256_CBC, + POLARSSL_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +const cipher_info_t aes_128_cfb128_info = { + POLARSSL_CIPHER_AES_128_CFB128, + POLARSSL_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_192_cfb128_info = { + POLARSSL_CIPHER_AES_192_CFB128, + POLARSSL_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_256_cfb128_info = { + POLARSSL_CIPHER_AES_256_CFB128, + POLARSSL_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +const cipher_info_t aes_128_ctr_info = { + POLARSSL_CIPHER_AES_128_CTR, + POLARSSL_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_192_ctr_info = { + POLARSSL_CIPHER_AES_192_CTR, + POLARSSL_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +const cipher_info_t aes_256_ctr_info = { + POLARSSL_CIPHER_AES_256_CTR, + POLARSSL_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#if defined(POLARSSL_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_AES, + key, key_length ); +} + +const cipher_base_t gcm_aes_info = { + POLARSSL_CIPHER_ID_AES, + NULL, + NULL, + NULL, + NULL, + NULL, + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +const cipher_info_t aes_128_gcm_info = { + POLARSSL_CIPHER_AES_128_GCM, + POLARSSL_MODE_GCM, + 128, + "AES-128-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +const cipher_info_t aes_192_gcm_info = { + POLARSSL_CIPHER_AES_192_GCM, + POLARSSL_MODE_GCM, + 192, + "AES-192-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +const cipher_info_t aes_256_gcm_info = { + POLARSSL_CIPHER_AES_256_GCM, + POLARSSL_MODE_GCM, + 256, + "AES-256-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return ccm_init( (ccm_context *) ctx, POLARSSL_CIPHER_ID_AES, + key, key_length ); +} + +const cipher_base_t ccm_aes_info = { + POLARSSL_CIPHER_ID_AES, + NULL, + NULL, + NULL, + NULL, + NULL, + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +const cipher_info_t aes_128_ccm_info = { + POLARSSL_CIPHER_AES_128_CCM, + POLARSSL_MODE_CCM, + 128, + "AES-128-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +const cipher_info_t aes_192_ccm_info = { + POLARSSL_CIPHER_AES_192_CCM, + POLARSSL_MODE_CCM, + 192, + "AES-192-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +const cipher_info_t aes_256_ccm_info = { + POLARSSL_CIPHER_AES_256_CCM, + POLARSSL_MODE_CCM, + 256, + "AES-256-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* POLARSSL_CCM_C */ + +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return camellia_crypt_ecb( (camellia_context *) ctx, operation, input, + output ); +} + +static int camellia_crypt_cbc_wrap( void *ctx, operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CBC) + return camellia_crypt_cbc( (camellia_context *) ctx, operation, length, iv, + input, output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ +} + +static int camellia_crypt_cfb128_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CFB) + return camellia_crypt_cfb128( (camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv_off); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ +} + +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CTR) + return camellia_crypt_ctr( (camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +#else + ((void) ctx); + ((void) length); + ((void) nc_off); + ((void) nonce_counter); + ((void) stream_block); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ +} + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return camellia_setkey_dec( (camellia_context *) ctx, key, key_length ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return camellia_setkey_enc( (camellia_context *) ctx, key, key_length ); +} + +static void * camellia_ctx_alloc( void ) +{ + camellia_context *ctx; + ctx = (camellia_context *) polarssl_malloc( sizeof( camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + camellia_free( (camellia_context *) ctx ); + polarssl_free( ctx ); +} + +const cipher_base_t camellia_info = { + POLARSSL_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, + camellia_crypt_cbc_wrap, + camellia_crypt_cfb128_wrap, + camellia_crypt_ctr_wrap, + NULL, + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +const cipher_info_t camellia_128_ecb_info = { + POLARSSL_CIPHER_CAMELLIA_128_ECB, + POLARSSL_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_192_ecb_info = { + POLARSSL_CIPHER_CAMELLIA_192_ECB, + POLARSSL_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_256_ecb_info = { + POLARSSL_CIPHER_CAMELLIA_256_ECB, + POLARSSL_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t camellia_128_cbc_info = { + POLARSSL_CIPHER_CAMELLIA_128_CBC, + POLARSSL_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_192_cbc_info = { + POLARSSL_CIPHER_CAMELLIA_192_CBC, + POLARSSL_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_256_cbc_info = { + POLARSSL_CIPHER_CAMELLIA_256_CBC, + POLARSSL_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +const cipher_info_t camellia_128_cfb128_info = { + POLARSSL_CIPHER_CAMELLIA_128_CFB128, + POLARSSL_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_192_cfb128_info = { + POLARSSL_CIPHER_CAMELLIA_192_CFB128, + POLARSSL_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_256_cfb128_info = { + POLARSSL_CIPHER_CAMELLIA_256_CFB128, + POLARSSL_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +const cipher_info_t camellia_128_ctr_info = { + POLARSSL_CIPHER_CAMELLIA_128_CTR, + POLARSSL_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_192_ctr_info = { + POLARSSL_CIPHER_CAMELLIA_192_CTR, + POLARSSL_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +const cipher_info_t camellia_256_ctr_info = { + POLARSSL_CIPHER_CAMELLIA_256_CTR, + POLARSSL_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#if defined(POLARSSL_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return gcm_init( (gcm_context *) ctx, POLARSSL_CIPHER_ID_CAMELLIA, + key, key_length ); +} + +const cipher_base_t gcm_camellia_info = { + POLARSSL_CIPHER_ID_CAMELLIA, + NULL, + NULL, + NULL, + NULL, + NULL, + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +const cipher_info_t camellia_128_gcm_info = { + POLARSSL_CIPHER_CAMELLIA_128_GCM, + POLARSSL_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +const cipher_info_t camellia_192_gcm_info = { + POLARSSL_CIPHER_CAMELLIA_192_GCM, + POLARSSL_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +const cipher_info_t camellia_256_gcm_info = { + POLARSSL_CIPHER_CAMELLIA_256_GCM, + POLARSSL_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return ccm_init( (ccm_context *) ctx, POLARSSL_CIPHER_ID_CAMELLIA, + key, key_length ); +} + +const cipher_base_t ccm_camellia_info = { + POLARSSL_CIPHER_ID_CAMELLIA, + NULL, + NULL, + NULL, + NULL, + NULL, + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +const cipher_info_t camellia_128_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_128_CCM, + POLARSSL_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +const cipher_info_t camellia_192_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_192_CCM, + POLARSSL_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +const cipher_info_t camellia_256_ccm_info = { + POLARSSL_CIPHER_CAMELLIA_256_CCM, + POLARSSL_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + POLARSSL_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* POLARSSL_CCM_C */ + +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return des_crypt_ecb( (des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return des3_crypt_ecb( (des3_context *) ctx, input, output ); +} + +static int des_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CBC) + return des_crypt_cbc( (des_context *) ctx, operation, length, iv, input, + output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ +} + +static int des3_crypt_cbc_wrap( void *ctx, operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CBC) + return des3_crypt_cbc( (des3_context *) ctx, operation, length, iv, input, + output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ +} + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des_setkey_dec( (des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des_setkey_enc( (des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des3_set2key_dec( (des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des3_set2key_enc( (des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des3_set3key_dec( (des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) key_length); + + return des3_set3key_enc( (des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + des_context *des = (des_context *) polarssl_malloc( sizeof( des_context ) ); + + if( des == NULL ) + return( NULL ); + + des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + des_free( (des_context *) ctx ); + polarssl_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + des3_context *des3; + des3 = (des3_context *) polarssl_malloc( sizeof( des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + des3_free( (des3_context *) ctx ); + polarssl_free( ctx ); +} + +const cipher_base_t des_info = { + POLARSSL_CIPHER_ID_DES, + des_crypt_ecb_wrap, + des_crypt_cbc_wrap, + NULL, + NULL, + NULL, + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +const cipher_info_t des_ecb_info = { + POLARSSL_CIPHER_DES_ECB, + POLARSSL_MODE_ECB, + POLARSSL_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t des_cbc_info = { + POLARSSL_CIPHER_DES_CBC, + POLARSSL_MODE_CBC, + POLARSSL_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +const cipher_base_t des_ede_info = { + POLARSSL_CIPHER_ID_DES, + des3_crypt_ecb_wrap, + des3_crypt_cbc_wrap, + NULL, + NULL, + NULL, + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +const cipher_info_t des_ede_ecb_info = { + POLARSSL_CIPHER_DES_EDE_ECB, + POLARSSL_MODE_ECB, + POLARSSL_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t des_ede_cbc_info = { + POLARSSL_CIPHER_DES_EDE_CBC, + POLARSSL_MODE_CBC, + POLARSSL_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +const cipher_base_t des_ede3_info = { + POLARSSL_CIPHER_ID_DES, + des3_crypt_ecb_wrap, + des3_crypt_cbc_wrap, + NULL, + NULL, + NULL, + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +const cipher_info_t des_ede3_ecb_info = { + POLARSSL_CIPHER_DES_EDE3_ECB, + POLARSSL_MODE_ECB, + POLARSSL_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t des_ede3_cbc_info = { + POLARSSL_CIPHER_DES_EDE3_CBC, + POLARSSL_MODE_CBC, + POLARSSL_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return blowfish_crypt_ecb( (blowfish_context *) ctx, operation, input, + output ); +} + +static int blowfish_crypt_cbc_wrap( void *ctx, operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CBC) + return blowfish_crypt_cbc( (blowfish_context *) ctx, operation, length, iv, + input, output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ +} + +static int blowfish_crypt_cfb64_wrap( void *ctx, operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CFB) + return blowfish_crypt_cfb64( (blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +#else + ((void) ctx); + ((void) operation); + ((void) length); + ((void) iv_off); + ((void) iv); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ +} + +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ +#if defined(POLARSSL_CIPHER_MODE_CTR) + return blowfish_crypt_ctr( (blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +#else + ((void) ctx); + ((void) length); + ((void) nc_off); + ((void) nonce_counter); + ((void) stream_block); + ((void) input); + ((void) output); + + return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ +} + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + return blowfish_setkey( (blowfish_context *) ctx, key, key_length ); +} + +static void * blowfish_ctx_alloc( void ) +{ + blowfish_context *ctx; + ctx = (blowfish_context *) polarssl_malloc( sizeof( blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + blowfish_free( (blowfish_context *) ctx ); + polarssl_free( ctx ); +} + +const cipher_base_t blowfish_info = { + POLARSSL_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, + blowfish_crypt_cbc_wrap, + blowfish_crypt_cfb64_wrap, + blowfish_crypt_ctr_wrap, + NULL, + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +const cipher_info_t blowfish_ecb_info = { + POLARSSL_CIPHER_BLOWFISH_ECB, + POLARSSL_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +const cipher_info_t blowfish_cbc_info = { + POLARSSL_CIPHER_BLOWFISH_CBC, + POLARSSL_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +const cipher_info_t blowfish_cfb64_info = { + POLARSSL_CIPHER_BLOWFISH_CFB64, + POLARSSL_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +const cipher_info_t blowfish_ctr_info = { + POLARSSL_CIPHER_BLOWFISH_CTR, + POLARSSL_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + POLARSSL_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* POLARSSL_CIPHER_MODE_CTR */ +#endif /* POLARSSL_BLOWFISH_C */ + +#if defined(POLARSSL_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( arc4_crypt( (arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + /* we get key_length in bits, arc4 expects it in bytes */ + if( key_length % 8 != 0 ) + return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA ); + + arc4_setup( (arc4_context *) ctx, key, key_length / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + arc4_context *ctx; + ctx = (arc4_context *) polarssl_malloc( sizeof( arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + arc4_free( (arc4_context *) ctx ); + polarssl_free( ctx ); +} + +const cipher_base_t arc4_base_info = { + POLARSSL_CIPHER_ID_ARC4, + NULL, + NULL, + NULL, + NULL, + arc4_crypt_stream_wrap, + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +const cipher_info_t arc4_128_info = { + POLARSSL_CIPHER_ARC4_128, + POLARSSL_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_length ) +{ + ((void) ctx); + ((void) key); + ((void) key_length); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ) +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +const cipher_base_t null_base_info = { + POLARSSL_CIPHER_ID_NULL, + NULL, + NULL, + NULL, + NULL, + null_crypt_stream, + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +const cipher_info_t null_cipher_info = { + POLARSSL_CIPHER_NULL, + POLARSSL_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */ + +const cipher_definition_t cipher_definitions[] = +{ +#if defined(POLARSSL_AES_C) + { POLARSSL_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { POLARSSL_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { POLARSSL_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(POLARSSL_CIPHER_MODE_CBC) + { POLARSSL_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { POLARSSL_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { POLARSSL_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CFB) + { POLARSSL_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { POLARSSL_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { POLARSSL_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + { POLARSSL_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { POLARSSL_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { POLARSSL_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(POLARSSL_GCM_C) + { POLARSSL_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { POLARSSL_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { POLARSSL_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(POLARSSL_CCM_C) + { POLARSSL_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { POLARSSL_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { POLARSSL_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_ARC4_C) + { POLARSSL_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(POLARSSL_BLOWFISH_C) + { POLARSSL_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(POLARSSL_CIPHER_MODE_CBC) + { POLARSSL_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CFB) + { POLARSSL_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + { POLARSSL_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* POLARSSL_BLOWFISH_C */ + +#if defined(POLARSSL_CAMELLIA_C) + { POLARSSL_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { POLARSSL_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { POLARSSL_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(POLARSSL_CIPHER_MODE_CBC) + { POLARSSL_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { POLARSSL_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { POLARSSL_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CFB) + { POLARSSL_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { POLARSSL_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { POLARSSL_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + { POLARSSL_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { POLARSSL_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { POLARSSL_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(POLARSSL_GCM_C) + { POLARSSL_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { POLARSSL_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { POLARSSL_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(POLARSSL_CCM_C) + { POLARSSL_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { POLARSSL_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { POLARSSL_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) + { POLARSSL_CIPHER_DES_ECB, &des_ecb_info }, + { POLARSSL_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { POLARSSL_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(POLARSSL_CIPHER_MODE_CBC) + { POLARSSL_CIPHER_DES_CBC, &des_cbc_info }, + { POLARSSL_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { POLARSSL_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) + { POLARSSL_CIPHER_NULL, &null_cipher_info }, +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ + + { (cipher_type_t)0, NULL } +}; + +#define NUM_CIPHERS sizeof cipher_definitions / sizeof cipher_definitions[0] +int supported_ciphers[NUM_CIPHERS]; + +#endif /* POLARSSL_CIPHER_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ctr_drbg.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ctr_drbg.c new file mode 100644 index 0000000..96ee4f1 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ctr_drbg.c @@ -0,0 +1,549 @@ +/* + * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The NIST SP 800-90 DRBGs are described in the following publucation. + * + * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CTR_DRBG_C) + +#include "polarssl/ctr_drbg.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST + * tests to succeed (which require known length fixed entropy) + */ +int ctr_drbg_init_entropy_len( + ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len, + size_t entropy_len ) +{ + int ret; + unsigned char key[CTR_DRBG_KEYSIZE]; + + memset( ctx, 0, sizeof(ctr_drbg_context) ); + memset( key, 0, CTR_DRBG_KEYSIZE ); + + aes_init( &ctx->aes_ctx ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->entropy_len = entropy_len; + ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL; + + /* + * Initialize with an empty key + */ + aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS ); + + if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int ctr_drbg_init( ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len, + CTR_DRBG_ENTROPY_LEN ) ); +} + +void ctr_drbg_free( ctr_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + aes_free( &ctx->aes_ctx ); + polarssl_zeroize( ctx, sizeof( ctr_drbg_context ) ); +} + +void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +static int block_cipher_df( unsigned char *output, + const unsigned char *data, size_t data_len ) +{ + unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16]; + unsigned char tmp[CTR_DRBG_SEEDLEN]; + unsigned char key[CTR_DRBG_KEYSIZE]; + unsigned char chain[CTR_DRBG_BLOCKSIZE]; + unsigned char *p, *iv; + aes_context aes_ctx; + + int i, j; + size_t buf_len, use_len; + + memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 ); + aes_init( &aes_ctx ); + + /* + * Construct IV (16 bytes) and S in buffer + * IV = Counter (in 32-bits) padded to 16 with zeroes + * S = Length input string (in 32-bits) || Length of output (in 32-bits) || + * data || 0x80 + * (Total is padded to a multiple of 16-bytes with zeroes) + */ + p = buf + CTR_DRBG_BLOCKSIZE; + *p++ = ( data_len >> 24 ) & 0xff; + *p++ = ( data_len >> 16 ) & 0xff; + *p++ = ( data_len >> 8 ) & 0xff; + *p++ = ( data_len ) & 0xff; + p += 3; + *p++ = CTR_DRBG_SEEDLEN; + memcpy( p, data, data_len ); + p[data_len] = 0x80; + + buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; + + for( i = 0; i < CTR_DRBG_KEYSIZE; i++ ) + key[i] = i; + + aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS ); + + /* + * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data + */ + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + p = buf; + memset( chain, 0, CTR_DRBG_BLOCKSIZE ); + use_len = buf_len; + + while( use_len > 0 ) + { + for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ ) + chain[i] ^= p[i]; + p += CTR_DRBG_BLOCKSIZE; + use_len -= ( use_len >= CTR_DRBG_BLOCKSIZE ) ? + CTR_DRBG_BLOCKSIZE : use_len; + + aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain ); + } + + memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE ); + + /* + * Update IV + */ + buf[3]++; + } + + /* + * Do final encryption with reduced data + */ + aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS ); + iv = tmp + CTR_DRBG_KEYSIZE; + p = output; + + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv ); + memcpy( p, iv, CTR_DRBG_BLOCKSIZE ); + p += CTR_DRBG_BLOCKSIZE; + } + + aes_free( &aes_ctx ); + + return( 0 ); +} + +static int ctr_drbg_update_internal( ctr_drbg_context *ctx, + const unsigned char data[CTR_DRBG_SEEDLEN] ) +{ + unsigned char tmp[CTR_DRBG_SEEDLEN]; + unsigned char *p = tmp; + int i, j; + + memset( tmp, 0, CTR_DRBG_SEEDLEN ); + + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + /* + * Increase counter + */ + for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p ); + + p += CTR_DRBG_BLOCKSIZE; + } + + for( i = 0; i < CTR_DRBG_SEEDLEN; i++ ) + tmp[i] ^= data[i]; + + /* + * Update key and counter + */ + aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS ); + memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE ); + + return( 0 ); +} + +void ctr_drbg_update( ctr_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + unsigned char add_input[CTR_DRBG_SEEDLEN]; + + if( add_len > 0 ) + { + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } +} + +int ctr_drbg_reseed( ctr_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[CTR_DRBG_MAX_SEED_INPUT]; + size_t seedlen = 0; + + if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT ) + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT ); + + /* + * Gather entropy_len bytes of entropy to seed state + */ + if( 0 != ctx->f_entropy( ctx->p_entropy, seed, + ctx->entropy_len ) ) + { + return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); + } + + seedlen += ctx->entropy_len; + + /* + * Add additional data + */ + if( additional && len ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* + * Reduce to 384 bits + */ + block_cipher_df( seed, seed, seedlen ); + + /* + * Update state + */ + ctr_drbg_update_internal( ctx, seed ); + ctx->reseed_counter = 1; + + return( 0 ); +} + +int ctr_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, size_t add_len ) +{ + int ret = 0; + ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng; + unsigned char add_input[CTR_DRBG_SEEDLEN]; + unsigned char *p = output; + unsigned char tmp[CTR_DRBG_BLOCKSIZE]; + int i; + size_t use_len; + + if( output_len > CTR_DRBG_MAX_REQUEST ) + return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG ); + + if( add_len > CTR_DRBG_MAX_INPUT ) + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( add_input, 0, CTR_DRBG_SEEDLEN ); + + if( ctx->reseed_counter > ctx->reseed_interval || + ctx->prediction_resistance ) + { + if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; + } + + if( add_len > 0 ) + { + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } + + while( output_len > 0 ) + { + /* + * Increase counter + */ + for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp ); + + use_len = ( output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : + output_len; + /* + * Copy random block to destination + */ + memcpy( p, tmp, use_len ); + p += use_len; + output_len -= use_len; + } + + ctr_drbg_update_internal( ctx, add_input ); + + ctx->reseed_counter++; + + return( 0 ); +} + +int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 ); +} + +#if defined(POLARSSL_FS_IO) +int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path ) +{ + int ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + + if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT ) + { + ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > CTR_DRBG_MAX_INPUT ) + { + fclose( f ); + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + ctr_drbg_update( ctx, buf, n ); + + return( ctr_drbg_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +static unsigned char entropy_source_pr[96] = + { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, + 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, + 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, + 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, + 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, + 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, + 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, + 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, + 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, + 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, + 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, + 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; + +static unsigned char entropy_source_nopr[64] = + { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, + 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, + 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, + 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, + 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, + 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, + 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, + 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; + +static const unsigned char nonce_pers_pr[16] = + { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, + 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; + +static const unsigned char nonce_pers_nopr[16] = + { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, + 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; + +static const unsigned char result_pr[16] = + { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, + 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; + +static const unsigned char result_nopr[16] = + { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, + 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; + +static size_t test_offset; +static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, + size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine + */ +int ctr_drbg_self_test( int verbose ) +{ + ctr_drbg_context ctx; + unsigned char buf[16]; + + /* + * Based on a NIST CTR_DRBG test vector (PR = True) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = TRUE) : " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_pr, nonce_pers_pr, 16, 32 ) ); + ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * Based on a NIST CTR_DRBG test vector (PR = FALSE) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = FALSE): " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( ctr_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( memcmp( buf, result_nopr, 16 ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_CTR_DRBG_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/debug.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/debug.c new file mode 100644 index 0000000..a81f502 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/debug.c @@ -0,0 +1,351 @@ +/* + * Debugging routines + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_DEBUG_C) + +#include "polarssl/debug.h" + +#include +#include + +#if defined(EFIX64) || defined(EFI32) +#include +#endif + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#if !defined snprintf +#define snprintf _snprintf +#endif + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif +#endif /* _MSC_VER */ + +static int debug_log_mode = POLARSSL_DEBUG_DFL_MODE; +static int debug_threshold = 0; + +void debug_set_log_mode( int log_mode ) +{ + debug_log_mode = log_mode; +} + +void debug_set_threshold( int threshold ) +{ + debug_threshold = threshold; +} + +char *debug_fmt( const char *format, ... ) +{ + va_list argp; + static char str[512]; + int maxlen = sizeof( str ) - 1; + + va_start( argp, format ); + vsnprintf( str, maxlen, format, argp ); + va_end( argp ); + + str[maxlen] = '\0'; + return( str ); +} + +void debug_print_msg( const ssl_context *ssl, int level, + const char *file, int line, const char *text ) +{ + char str[512]; + int maxlen = sizeof( str ) - 1; + + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_RAW ) + { + ssl->f_dbg( ssl->p_dbg, level, text ); + return; + } + + snprintf( str, maxlen, "%s(%04d): %s\n", file, line, text ); + str[maxlen] = '\0'; + ssl->f_dbg( ssl->p_dbg, level, str ); +} + +void debug_print_ret( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret ) +{ + char str[512]; + int maxlen = sizeof( str ) - 1; + size_t idx = 0; + + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "%s() returned %d (-0x%04x)\n", + text, ret, -ret ); + + str[maxlen] = '\0'; + ssl->f_dbg( ssl->p_dbg, level, str ); +} + +void debug_print_buf( const ssl_context *ssl, int level, + const char *file, int line, const char *text, + unsigned char *buf, size_t len ) +{ + char str[512]; + size_t i, maxlen = sizeof( str ) - 1, idx = 0; + + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "dumping '%s' (%u bytes)\n", + text, (unsigned int) len ); + + str[maxlen] = '\0'; + ssl->f_dbg( ssl->p_dbg, level, str ); + + idx = 0; + for( i = 0; i < len; i++ ) + { + if( i >= 4096 ) + break; + + if( i % 16 == 0 ) + { + if( i > 0 ) + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; + } + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + idx += snprintf( str + idx, maxlen - idx, "%04x: ", + (unsigned int) i ); + + } + + idx += snprintf( str + idx, maxlen - idx, " %02x", + (unsigned int) buf[i] ); + } + + if( len > 0 ) + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + } +} + +#if defined(POLARSSL_ECP_C) +void debug_print_ecp( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const ecp_point *X ) +{ + char str[512]; + int maxlen = sizeof( str ) - 1; + + if( ssl->f_dbg == NULL || level > debug_threshold ) + return; + + snprintf( str, maxlen, "%s(X)", text ); + str[maxlen] = '\0'; + debug_print_mpi( ssl, level, file, line, str, &X->X ); + + snprintf( str, maxlen, "%s(Y)", text ); + str[maxlen] = '\0'; + debug_print_mpi( ssl, level, file, line, str, &X->Y ); +} +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_BIGNUM_C) +void debug_print_mpi( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mpi *X ) +{ + char str[512]; + int j, k, maxlen = sizeof( str ) - 1, zeros = 1; + size_t i, n, idx = 0; + + if( ssl->f_dbg == NULL || X == NULL || level > debug_threshold ) + return; + + for( n = X->n - 1; n > 0; n-- ) + if( X->p[n] != 0 ) + break; + + for( j = ( sizeof(t_uint) << 3 ) - 1; j >= 0; j-- ) + if( ( ( X->p[n] >> j ) & 1 ) != 0 ) + break; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "value of '%s' (%d bits) is:\n", + text, (int) ( ( n * ( sizeof(t_uint) << 3 ) ) + j + 1 ) ); + + str[maxlen] = '\0'; + ssl->f_dbg( ssl->p_dbg, level, str ); + + idx = 0; + for( i = n + 1, j = 0; i > 0; i-- ) + { + if( zeros && X->p[i - 1] == 0 ) + continue; + + for( k = sizeof( t_uint ) - 1; k >= 0; k-- ) + { + if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) + continue; + else + zeros = 0; + + if( j % 16 == 0 ) + { + if( j > 0 ) + { + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); + idx = 0; + } + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + } + + idx += snprintf( str + idx, maxlen - idx, " %02x", (unsigned int) + ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); + + j++; + } + + } + + if( zeros == 1 ) + { + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + { + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + } + idx += snprintf( str + idx, maxlen - idx, " 00" ); + } + + snprintf( str + idx, maxlen - idx, "\n" ); + ssl->f_dbg( ssl->p_dbg, level, str ); +} +#endif /* POLARSSL_BIGNUM_C */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +static void debug_print_pk( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const pk_context *pk ) +{ + size_t i; + pk_debug_item items[POLARSSL_PK_DEBUG_MAX_ITEMS]; + char name[16]; + + memset( items, 0, sizeof( items ) ); + + if( pk_debug( pk, items ) != 0 ) + { + debug_print_msg( ssl, level, file, line, "invalid PK context" ); + return; + } + + for( i = 0; i < POLARSSL_PK_DEBUG_MAX_ITEMS; i++ ) + { + if( items[i].type == POLARSSL_PK_DEBUG_NONE ) + return; + + snprintf( name, sizeof( name ), "%s%s", text, items[i].name ); + name[sizeof( name ) - 1] = '\0'; + + if( items[i].type == POLARSSL_PK_DEBUG_MPI ) + debug_print_mpi( ssl, level, file, line, name, items[i].value ); + else +#if defined(POLARSSL_ECP_C) + if( items[i].type == POLARSSL_PK_DEBUG_ECP ) + debug_print_ecp( ssl, level, file, line, name, items[i].value ); + else +#endif + debug_print_msg( ssl, level, file, line, "should not happen" ); + } +} + +void debug_print_crt( const ssl_context *ssl, int level, + const char *file, int line, + const char *text, const x509_crt *crt ) +{ + char str[1024], prefix[64]; + int i = 0, maxlen = sizeof( prefix ) - 1, idx = 0; + + if( ssl->f_dbg == NULL || crt == NULL || level > debug_threshold ) + return; + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + { + snprintf( prefix, maxlen, "%s(%04d): ", file, line ); + prefix[maxlen] = '\0'; + } + else + prefix[0] = '\0'; + + maxlen = sizeof( str ) - 1; + + while( crt != NULL ) + { + char buf[1024]; + x509_crt_info( buf, sizeof( buf ) - 1, prefix, crt ); + + if( debug_log_mode == POLARSSL_DEBUG_LOG_FULL ) + idx = snprintf( str, maxlen, "%s(%04d): ", file, line ); + + snprintf( str + idx, maxlen - idx, "%s #%d:\n%s", + text, ++i, buf ); + + str[maxlen] = '\0'; + ssl->f_dbg( ssl->p_dbg, level, str ); + + debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); + + crt = crt->next; + } +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#endif /* POLARSSL_DEBUG_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/des.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/des.c new file mode 100644 index 0000000..6461167 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/des.c @@ -0,0 +1,1230 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#ifdef RTL_HW_CRYPTO +#include +#endif +#if defined(POLARSSL_DES_C) + +#include "polarssl/des.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_DES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const uint32_t SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const uint32_t SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const uint32_t SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const uint32_t SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const uint32_t SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const uint32_t SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const uint32_t SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const uint32_t SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const uint32_t LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const uint32_t RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } + +void des_init( des_context *ctx ) +{ + memset( ctx, 0, sizeof( des_context ) ); +} + +void des_free( des_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des_context ) ); +} + +void des3_init( des3_context *ctx ) +{ + memset( ctx, 0, sizeof( des3_context ) ); +} + +void des3_free( des3_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des3_context ) ); +} + +static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, + 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, + 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, + 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, + 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, + 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, + 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, + 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, + 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, + 254 }; + +void des_key_set_parity( unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < DES_KEY_SIZE; i++ ) + key[i] = odd_parity_table[key[i] / 2]; +} + +/* + * Check the given key's parity, returns 1 on failure, 0 on SUCCESS + */ +int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < DES_KEY_SIZE; i++ ) + if( key[i] != odd_parity_table[key[i] / 2] ) + return( 1 ); + + return( 0 ); +} + +/* + * Table of weak and semi-weak keys + * + * Source: http://en.wikipedia.org/wiki/Weak_key + * + * Weak: + * Alternating ones + zeros (0x0101010101010101) + * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) + * '0xE0E0E0E0F1F1F1F1' + * '0x1F1F1F1F0E0E0E0E' + * + * Semi-weak: + * 0x011F011F010E010E and 0x1F011F010E010E01 + * 0x01E001E001F101F1 and 0xE001E001F101F101 + * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 + * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E + * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E + * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 + * + */ + +#define WEAK_KEY_COUNT 16 + +static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] = +{ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } +}; + +int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < WEAK_KEY_COUNT; i++ ) + if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0 ) + return( 1 ); + + return( 0 ); +} + +static void des_setkey( uint32_t SK[32], const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + uint32_t X, Y, T; + + GET_UINT32_BE( X, key, 0 ); + GET_UINT32_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des_setkey( ctx->sk, key ); + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + int i; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +static void des3_set2key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[DES_KEY_SIZE*2] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i ]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i ]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * Triple-DES key schedule (112-bit, encryption) + */ +int des3_set2key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE * 2); + memcpy(ctx->enc_key + DES_KEY_SIZE * 2, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des3_set2key( ctx->sk, sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (112-bit, decryption) + */ +int des3_set2key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE * 2); + memcpy(ctx->dec_key + DES_KEY_SIZE * 2, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des3_set2key( sk, ctx->sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +static void des3_set3key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[24] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + des_setkey( esk + 64, key + 16 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * Triple-DES key schedule (168-bit, encryption) + */ +int des3_set3key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE * 3); + } +#endif /* RTL_HW_CRYPTO */ + des3_set3key( ctx->sk, sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (168-bit, decryption) + */ +int des3_set3key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE * 3); + } +#endif /* RTL_HW_CRYPTO */ + des3_set3key( sk, ctx->sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); + +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * DES-CBC buffer encryption/decryption + */ +int des_crypt_cbc( des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[8 + 4], *key_buf_aligned; + unsigned char iv_buf[8 + 4], *iv_buf_aligned, iv_tmp[8]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 8) + return(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 8); + memset(output_buf, 0, length + 4); + + if(mode == DES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, DES_KEY_SIZE); + rom_ssl_ram_map.hw_crypto_des_cbc_init(key_buf_aligned, DES_KEY_SIZE); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + rom_ssl_ram_map.hw_crypto_des_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 8), 8); + rom_ssl_ram_map.hw_crypto_des_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 8); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, DES_KEY_SIZE); + rom_ssl_ram_map.hw_crypto_des_cbc_init(key_buf_aligned, DES_KEY_SIZE); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_des_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_des_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 8), 8); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/* + * 3DES-ECB block encryption/decryption + */ +int des3_crypt_ecb( des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( X, Y ); + DES_ROUND( Y, X ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * 3DES-CBC buffer encryption/decryption + */ +int des3_crypt_cbc( des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[24 + 4], *key_buf_aligned; + unsigned char iv_buf[8 + 4], *iv_buf_aligned, iv_tmp[8]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 8) + return(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 8); + memset(output_buf, 0, length + 4); + + if(mode == DES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, DES_KEY_SIZE * 3); + rom_ssl_ram_map.hw_crypto_3des_cbc_init(key_buf_aligned, DES_KEY_SIZE * 3); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + rom_ssl_ram_map.hw_crypto_3des_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 8), 8); + rom_ssl_ram_map.hw_crypto_3des_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 8); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, DES_KEY_SIZE * 3); + rom_ssl_ram_map.hw_crypto_3des_cbc_init(key_buf_aligned, DES_KEY_SIZE * 3); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_3des_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_3des_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 8), 8); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des3_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des3_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#endif /* !POLARSSL_DES_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int des_self_test( int verbose ) +{ + int i, j, u, v, ret = 0; + des_context ctx; + des3_context ctx3; + unsigned char buf[8]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + des_init( &ctx ); + des3_init( &ctx3 ); + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_ecb( &ctx, buf, buf ); + else + des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + des_free( &ctx ); + des3_free( &ctx3 ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_DES_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/dhm.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/dhm.c new file mode 100644 index 0000000..089c11b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/dhm.c @@ -0,0 +1,598 @@ +/* + * Diffie-Hellman-Merkle key exchange + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * Reference: + * + * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12) + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_DHM_C) + +#include "polarssl/dhm.h" + +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_ASN1_PARSE_C) +#include "polarssl/asn1.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * helper to validate the mpi size and import it + */ +static int dhm_read_bignum( mpi *X, + unsigned char **p, + const unsigned char *end ) +{ + int ret, n; + + if( end - *p < 2 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + n = ( (*p)[0] << 8 ) | (*p)[1]; + (*p) += 2; + + if( (int)( end - *p ) < n ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 ) + return( POLARSSL_ERR_DHM_READ_PARAMS_FAILED + ret ); + + (*p) += n; + + return( 0 ); +} + +/* + * Verify sanity of parameter with regards to P + * + * Parameter should be: 2 <= public_param <= P - 2 + * + * For more information on the attack, see: + * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf + * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 + */ +static int dhm_check_range( const mpi *param, const mpi *P ) +{ + mpi L, U; + int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA; + + mpi_init( &L ); mpi_init( &U ); + + MPI_CHK( mpi_lset( &L, 2 ) ); + MPI_CHK( mpi_sub_int( &U, P, 2 ) ); + + if( mpi_cmp_mpi( param, &L ) >= 0 && + mpi_cmp_mpi( param, &U ) <= 0 ) + { + ret = 0; + } + +cleanup: + mpi_free( &L ); mpi_free( &U ); + return( ret ); +} + +void dhm_init( dhm_context *ctx ) +{ + memset( ctx, 0, sizeof( dhm_context ) ); +} + +/* + * Parse the ServerKeyExchange parameters + */ +int dhm_read_params( dhm_context *ctx, + unsigned char **p, + const unsigned char *end ) +{ + int ret; + + if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) + return( ret ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + ctx->len = mpi_size( &ctx->P ); + + return( 0 ); +} + +/* + * Setup and write the ServerKeyExchange parameters + */ +int dhm_make_params( dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + size_t n1, n2, n3; + unsigned char *p; + + if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + /* + * Generate X as large as possible ( < P ) + */ + do + { + mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + /* + * Calculate GX = G^X mod P + */ + MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + /* + * export P, G, GX + */ +#define DHM_MPI_EXPORT(X,n) \ + MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \ + *p++ = (unsigned char)( n >> 8 ); \ + *p++ = (unsigned char)( n ); p += n; + + n1 = mpi_size( &ctx->P ); + n2 = mpi_size( &ctx->G ); + n3 = mpi_size( &ctx->GX ); + + p = output; + DHM_MPI_EXPORT( &ctx->P , n1 ); + DHM_MPI_EXPORT( &ctx->G , n2 ); + DHM_MPI_EXPORT( &ctx->GX, n3 ); + + *olen = p - output; + + ctx->len = n1; + +cleanup: + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED + ret ); + + return( 0 ); +} + +/* + * Import the peer's public value G^Y + */ +int dhm_read_public( dhm_context *ctx, + const unsigned char *input, size_t ilen ) +{ + int ret; + + if( ctx == NULL || ilen < 1 || ilen > ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) + return( POLARSSL_ERR_DHM_READ_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Create own private value X and export G^X + */ +int dhm_make_public( dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + + if( ctx == NULL || olen < 1 || olen > ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + /* + * generate X and calculate GX = G^X mod P + */ + do + { + mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) ); + +cleanup: + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Use the blinding method and optimisation suggested in section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +static int dhm_update_blinding( dhm_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count; + + /* + * Don't use any blinding the first time a particular X is used, + * but remember it to use blinding next time. + */ + if( mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) + { + MPI_CHK( mpi_copy( &ctx->pX, &ctx->X ) ); + MPI_CHK( mpi_lset( &ctx->Vi, 1 ) ); + MPI_CHK( mpi_lset( &ctx->Vf, 1 ) ); + + return( 0 ); + } + + /* + * Ok, we need blinding. Can we re-use existing values? + * If yes, just update them by squaring them. + */ + if( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) + { + MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); + + MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); + + return( 0 ); + } + + /* + * We need to generate blinding values from scratch + */ + + /* Vi = random( 2, P-1 ) */ + count = 0; + do + { + mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->Vi, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + while( mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); + + /* Vf = Vi^-X mod P */ + MPI_CHK( mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); + MPI_CHK( mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); + +cleanup: + return( ret ); +} + +/* + * Derive and export the shared secret (G^Y)^X mod P + */ +int dhm_calc_secret( dhm_context *ctx, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mpi GYb; + + if( ctx == NULL || *olen < ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + mpi_init( &GYb ); + + /* Blind peer's value */ + if( f_rng != NULL ) + { + MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); + } + else + MPI_CHK( mpi_copy( &GYb, &ctx->GY ) ); + + /* Do modular exponentiation */ + MPI_CHK( mpi_exp_mod( &ctx->K, &GYb, &ctx->X, + &ctx->P, &ctx->RP ) ); + + /* Unblind secret value */ + if( f_rng != NULL ) + { + MPI_CHK( mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); + } + + *olen = mpi_size( &ctx->K ); + + MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) ); + +cleanup: + mpi_free( &GYb ); + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret ); + + return( 0 ); +} + +/* + * Free the components of a DHM key + */ +void dhm_free( dhm_context *ctx ) +{ + mpi_free( &ctx->pX); mpi_free( &ctx->Vf ); mpi_free( &ctx->Vi ); + mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY ); + mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G ); + mpi_free( &ctx->P ); + + polarssl_zeroize( ctx, sizeof( dhm_context ) ); +} + +#if defined(POLARSSL_ASN1_PARSE_C) +/* + * Parse DHM parameters + */ +int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ) +{ + int ret; + size_t len; + unsigned char *p, *end; +#if defined(POLARSSL_PEM_PARSE_C) + pem_context pem; + + pem_init( &pem ); + + ret = pem_read_buffer( &pem, + "-----BEGIN DH PARAMETERS-----", + "-----END DH PARAMETERS-----", + dhmin, NULL, 0, &dhminlen ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + dhminlen = pem.buflen; + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + goto exit; + + p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; +#else + p = (unsigned char *) dhmin; +#endif /* POLARSSL_PEM_PARSE_C */ + end = p + dhminlen; + + /* + * DHParams ::= SEQUENCE { + * prime INTEGER, -- P + * generator INTEGER, -- g + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + end = p + len; + + if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + if( p != end ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + goto exit; + } + + ret = 0; + + dhm->len = mpi_size( &dhm->P ); + +exit: +#if defined(POLARSSL_PEM_PARSE_C) + pem_free( &pem ); +#endif + if( ret != 0 ) + dhm_free( dhm ); + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load all data from a file into a given buffer. + */ +static int load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL ) + { + fclose( f ); + return( POLARSSL_ERR_DHM_MALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + polarssl_free( *buf ); + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + return( 0 ); +} + +/* + * Load and parse DHM parameters + */ +int dhm_parse_dhmfile( dhm_context *dhm, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = dhm_parse_dhm( dhm, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ +#endif /* POLARSSL_ASN1_PARSE_C */ + +#if defined(POLARSSL_SELF_TEST) + +#include "polarssl/certs.h" + +/* + * Checkup routine + */ +int dhm_self_test( int verbose ) +{ +#if defined(POLARSSL_CERTS_C) + int ret; + dhm_context dhm; + + dhm_init( &dhm ); + + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: " ); + + if( ( ret = dhm_parse_dhm( &dhm, (const unsigned char *) test_dhm_params, + strlen( test_dhm_params ) ) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + +exit: + dhm_free( &dhm ); + + return( ret ); +#else + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: skipped\n" ); + + return( 0 ); +#endif /* POLARSSL_CERTS_C */ +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_DHM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdh.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdh.c new file mode 100644 index 0000000..b93d82e --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdh.c @@ -0,0 +1,280 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * RFC 4492 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECDH_C) + +#include "polarssl/ecdh.h" + +/* + * Generate public key: simple wrapper around ecp_gen_keypair + */ +int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +int ecdh_compute_shared( ecp_group *grp, mpi *z, + const ecp_point *Q, const mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + ecp_point P; + + ecp_point_init( &P ); + + /* + * Make sure Q is a valid pubkey before using it + */ + MPI_CHK( ecp_check_pubkey( grp, Q ) ); + + MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); + + if( ecp_is_zero( &P ) ) + { + ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MPI_CHK( mpi_copy( z, &P.X ) ); + +cleanup: + ecp_point_free( &P ); + + return( ret ); +} + +/* + * Initialize context + */ +void ecdh_init( ecdh_context *ctx ) +{ + memset( ctx, 0, sizeof( ecdh_context ) ); +} + +/* + * Free context + */ +void ecdh_free( ecdh_context *ctx ) +{ + if( ctx == NULL ) + return; + + ecp_group_free( &ctx->grp ); + ecp_point_free( &ctx->Q ); + ecp_point_free( &ctx->Qp ); + ecp_point_free( &ctx->Vi ); + ecp_point_free( &ctx->Vf ); + mpi_free( &ctx->d ); + mpi_free( &ctx->z ); + mpi_free( &ctx->_d ); +} + +/* + * Setup and write the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int ecdh_make_params( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t grp_len, pt_len; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) ) + != 0 ) + return( ret ); + + buf += grp_len; + blen -= grp_len; + + if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + &pt_len, buf, blen ) ) != 0 ) + return( ret ); + + *olen = grp_len + pt_len; + return( 0 ); +} + +/* + * Read the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int ecdh_read_params( ecdh_context *ctx, + const unsigned char **buf, const unsigned char *end ) +{ + int ret; + + if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) + return( ret ); + + if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) + != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Get parameters from a keypair + */ +int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, + ecdh_side side ) +{ + int ret; + + if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) + return( ret ); + + /* If it's not our key, just import the public part as Qp */ + if( side == POLARSSL_ECDH_THEIRS ) + return( ecp_copy( &ctx->Qp, &key->Q ) ); + + /* Our key: import public (as Q) and private parts */ + if( side != POLARSSL_ECDH_OURS ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 || + ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Setup and export the client public value + */ +int ecdh_make_public( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + olen, buf, blen ); +} + +/* + * Parse and import the client's public value + */ +int ecdh_read_public( ecdh_context *ctx, + const unsigned char *buf, size_t blen ) +{ + int ret; + const unsigned char *p = buf; + + if( ctx == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) + return( ret ); + + if( (size_t)( p - buf ) != blen ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Derive and export the shared secret + */ +int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + if( mpi_size( &ctx->z ) > blen ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); + return mpi_write_binary( &ctx->z, buf, *olen ); +} + + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecdh_self_test( int verbose ) +{ + ((void) verbose ); + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECDH_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdsa.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdsa.c new file mode 100644 index 0000000..5af7f6b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecdsa.c @@ -0,0 +1,503 @@ +/* + * Elliptic curve DSA + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECDSA_C) + +#include "polarssl/ecdsa.h" +#include "polarssl/asn1write.h" + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +#include "polarssl/hmac_drbg.h" +#endif + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * This a hopefully temporary compatibility function. + * + * Since we can't ensure the caller will pass a valid md_alg before the next + * interface change, try to pick up a decent md by size. + * + * Argument is the minimum size in bytes of the MD output. + */ +static const md_info_t *md_info_by_size( size_t min_size ) +{ + const md_info_t *md_cur, *md_picked = NULL; + const int *md_alg; + + for( md_alg = md_list(); *md_alg != 0; md_alg++ ) + { + if( ( md_cur = md_info_from_type( *md_alg ) ) == NULL || + (size_t) md_cur->size < min_size || + ( md_picked != NULL && md_cur->size > md_picked->size ) ) + continue; + + md_picked = md_cur; + } + + return( md_picked ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Derive a suitable integer for group grp from a buffer of length len + * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 + */ +static int derive_mpi( const ecp_group *grp, mpi *x, + const unsigned char *buf, size_t blen ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MPI_CHK( mpi_read_binary( x, buf, use_size ) ); + if( use_size * 8 > grp->nbits ) + MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) ); + + /* While at it, reduce modulo N */ + if( mpi_cmp_mpi( x, &grp->N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( x, x, &grp->N ) ); + +cleanup: + return( ret ); +} + +/* + * Compute ECDSA signature of a hashed message (SEC1 4.1.3) + * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) + */ +int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, key_tries, sign_tries, blind_tries; + ecp_point R; + mpi k, e, t; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + ecp_point_init( &R ); + mpi_init( &k ); mpi_init( &e ); mpi_init( &t ); + + sign_tries = 0; + do + { + /* + * Steps 1-3: generate a suitable ephemeral keypair + * and set r = xR mod n + */ + key_tries = 0; + do + { + MPI_CHK( ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) ); + MPI_CHK( mpi_mod_mpi( r, &R.X, &grp->N ) ); + + if( key_tries++ > 10 ) + { + ret = POLARSSL_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mpi_cmp_int( r, 0 ) == 0 ); + + /* + * Step 5: derive MPI from hashed message + */ + MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + blind_tries = 0; + do + { + size_t n_size = ( grp->nbits + 7 ) / 8; + MPI_CHK( mpi_fill_random( &t, n_size, f_rng, p_rng ) ); + MPI_CHK( mpi_shift_r( &t, 8 * n_size - grp->nbits ) ); + + /* See ecp_gen_keypair() */ + if( ++blind_tries > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &t, 1 ) < 0 || + mpi_cmp_mpi( &t, &grp->N ) >= 0 ); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n + */ + MPI_CHK( mpi_mul_mpi( s, r, d ) ); + MPI_CHK( mpi_add_mpi( &e, &e, s ) ); + MPI_CHK( mpi_mul_mpi( &e, &e, &t ) ); + MPI_CHK( mpi_mul_mpi( &k, &k, &t ) ); + MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) ); + MPI_CHK( mpi_mul_mpi( s, s, &e ) ); + MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) ); + + if( sign_tries++ > 10 ) + { + ret = POLARSSL_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mpi_cmp_int( s, 0 ) == 0 ); + +cleanup: + ecp_point_free( &R ); + mpi_free( &k ); mpi_free( &e ); mpi_free( &t ); + + return( ret ); +} + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + */ +int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + md_type_t md_alg ) +{ + int ret; + hmac_drbg_context rng_ctx; + unsigned char data[2 * POLARSSL_ECP_MAX_BYTES]; + size_t grp_len = ( grp->nbits + 7 ) / 8; + const md_info_t *md_info; + mpi h; + + /* Temporary fallback */ + if( md_alg == POLARSSL_MD_NONE ) + md_info = md_info_by_size( blen ); + else + md_info = md_info_from_type( md_alg ); + + if( md_info == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + mpi_init( &h ); + memset( &rng_ctx, 0, sizeof( hmac_drbg_context ) ); + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MPI_CHK( mpi_write_binary( d, data, grp_len ) ); + MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); + MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) ); + hmac_drbg_init_buf( &rng_ctx, md_info, data, 2 * grp_len ); + + ret = ecdsa_sign( grp, r, s, d, buf, blen, + hmac_drbg_random, &rng_ctx ); + +cleanup: + hmac_drbg_free( &rng_ctx ); + mpi_free( &h ); + + return( ret ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Verify ECDSA signature of hashed message (SEC1 4.1.4) + * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) + */ +int ecdsa_verify( ecp_group *grp, + const unsigned char *buf, size_t blen, + const ecp_point *Q, const mpi *r, const mpi *s) +{ + int ret; + mpi e, s_inv, u1, u2; + ecp_point R, P; + + ecp_point_init( &R ); ecp_point_init( &P ); + mpi_init( &e ); mpi_init( &s_inv ); mpi_init( &u1 ); mpi_init( &u2 ); + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Step 1: make sure r and s are in range 1..n-1 + */ + if( mpi_cmp_int( r, 1 ) < 0 || mpi_cmp_mpi( r, &grp->N ) >= 0 || + mpi_cmp_int( s, 1 ) < 0 || mpi_cmp_mpi( s, &grp->N ) >= 0 ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Additional precaution: make sure Q is valid + */ + MPI_CHK( ecp_check_pubkey( grp, Q ) ); + + /* + * Step 3: derive MPI from hashed message + */ + MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Step 4: u1 = e / s mod n, u2 = r / s mod n + */ + MPI_CHK( mpi_inv_mod( &s_inv, s, &grp->N ) ); + + MPI_CHK( mpi_mul_mpi( &u1, &e, &s_inv ) ); + MPI_CHK( mpi_mod_mpi( &u1, &u1, &grp->N ) ); + + MPI_CHK( mpi_mul_mpi( &u2, r, &s_inv ) ); + MPI_CHK( mpi_mod_mpi( &u2, &u2, &grp->N ) ); + + /* + * Step 5: R = u1 G + u2 Q + * + * Since we're not using any secret data, no need to pass a RNG to + * ecp_mul() for countermesures. + */ + MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) ); + MPI_CHK( ecp_mul( grp, &P, &u2, Q, NULL, NULL ) ); + MPI_CHK( ecp_add( grp, &R, &R, &P ) ); + + if( ecp_is_zero( &R ) ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 6: convert xR to an integer (no-op) + * Step 7: reduce xR mod n (gives v) + */ + MPI_CHK( mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); + + /* + * Step 8: check if v (that is, R.X) is equal to r + */ + if( mpi_cmp_mpi( &R.X, r ) != 0 ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + ecp_point_free( &R ); ecp_point_free( &P ); + mpi_free( &e ); mpi_free( &s_inv ); mpi_free( &u1 ); mpi_free( &u2 ); + + return( ret ); +} + +/* + * RFC 4492 page 20: + * + * Ecdsa-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * Size is at most + * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s, + * twice that + 1 (tag) + 2 (len) for the sequence + * (assuming ECP_MAX_BYTES is less than 126 for r and s, + * and less than 124 (total len <= 255) for the sequence) + */ +#if POLARSSL_ECP_MAX_BYTES > 124 +#error "POLARSSL_ECP_MAX_BYTES bigger than expected, please fix MAX_SIG_LEN" +#endif +#define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) ) + +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1( ecdsa_context *ctx, + unsigned char *sig, size_t *slen ) +{ + int ret; + unsigned char buf[MAX_SIG_LEN]; + unsigned char *p = buf + sizeof( buf ); + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &p, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &p, buf, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + + memcpy( sig, p, len ); + *slen = len; + + return( 0 ); +} + +/* + * Compute and write signature + */ +int ecdsa_write_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, + hash, hlen, f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); +} + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Compute and write signature deterministically + */ +int ecdsa_write_signature_det( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + md_type_t md_alg ) +{ + int ret; + + if( ( ret = ecdsa_sign_det( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, + hash, hlen, md_alg ) ) != 0 ) + { + return( ret ); + } + + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Read and check signature + */ +int ecdsa_read_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ) +{ + int ret; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret ); + } + + if( p + len != end ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = asn1_get_mpi( &p, end, &ctx->r ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &ctx->s ) ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret ); + + if( ( ret = ecdsa_verify( &ctx->grp, hash, hlen, + &ctx->Q, &ctx->r, &ctx->s ) ) != 0 ) + return( ret ); + + if( p != end ) + return( POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +/* + * Generate key pair + */ +int ecdsa_genkey( ecdsa_context *ctx, ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + return( ecp_use_known_dp( &ctx->grp, gid ) || + ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); +} + +/* + * Set context from an ecp_keypair + */ +int ecdsa_from_keypair( ecdsa_context *ctx, const ecp_keypair *key ) +{ + int ret; + + if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || + ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 || + ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) + { + ecdsa_free( ctx ); + } + + return( ret ); +} + +/* + * Initialize context + */ +void ecdsa_init( ecdsa_context *ctx ) +{ + ecp_group_init( &ctx->grp ); + mpi_init( &ctx->d ); + ecp_point_init( &ctx->Q ); + mpi_init( &ctx->r ); + mpi_init( &ctx->s ); +} + +/* + * Free context + */ +void ecdsa_free( ecdsa_context *ctx ) +{ + ecp_group_free( &ctx->grp ); + mpi_free( &ctx->d ); + ecp_point_free( &ctx->Q ); + mpi_free( &ctx->r ); + mpi_free( &ctx->s ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecdsa_self_test( int verbose ) +{ + ((void) verbose ); + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECDSA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp.c new file mode 100644 index 0000000..afa7955 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp.c @@ -0,0 +1,2029 @@ +/* + * Elliptic curves over GF(p): generic functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone + * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf + * RFC 4492 for the related TLS structures and constants + * + * [M255] http://cr.yp.to/ecdh/curve25519-20060209.pdf + * + * [2] CORON, Jean-Sébastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et BÉNÉTEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_SELF_TEST) +/* + * Counts of point addition and doubling, and field multiplications. + * Used to test resistance of point multiplication to simple timing attacks. + */ +static unsigned long add_count, dbl_count, mul_count; +#endif + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP512R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +#define POLARSSL_ECP_SHORT_WEIERSTRASS +#endif + +#if defined(POLARSSL_ECP_DP_M221_ENABLED) || \ + defined(POLARSSL_ECP_DP_M255_ENABLED) || \ + defined(POLARSSL_ECP_DP_M383_ENABLED) || \ + defined(POLARSSL_ECP_DP_M511_ENABLED) +#define POLARSSL_ECP_MONTGOMERY +#endif + +/* + * Curve types: internal for now, might be exposed later + */ +typedef enum +{ + POLARSSL_ECP_TYPE_NONE = 0, + POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + POLARSSL_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} ecp_curve_type; + +/* + * List of supported curves: + * - internal ID + * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) + * - size in bits + * - readable name + * + * Curves are listed in order: largest curves first, and for a given size, + * fastest curves first. This provides the default order for the SSL module. + */ +static const ecp_curve_info ecp_supported_curves[] = +{ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + { POLARSSL_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + { POLARSSL_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + { POLARSSL_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + { POLARSSL_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + { POLARSSL_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + { POLARSSL_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + { POLARSSL_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + { POLARSSL_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + { POLARSSL_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + { POLARSSL_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, +#endif + { POLARSSL_ECP_DP_NONE, 0, 0, NULL }, +}; + +#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ + sizeof( ecp_supported_curves[0] ) + +static ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; + +/* + * List of supported curves and associated info + */ +const ecp_curve_info *ecp_curve_list( void ) +{ + return( ecp_supported_curves ); +} + +/* + * List of supported curves, group ID only + */ +const ecp_group_id *ecp_grp_id_list( void ) +{ + static int init_done = 0; + + if( ! init_done ) + { + size_t i = 0; + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + ecp_supported_grp_id[i++] = curve_info->grp_id; + } + ecp_supported_grp_id[i] = POLARSSL_ECP_DP_NONE; + + init_done = 1; + } + + return( ecp_supported_grp_id ); +} + +/* + * Get the curve info for the internal identifier + */ +const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->grp_id == grp_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the TLS identifier + */ +const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->tls_id == tls_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the name + */ +const ecp_curve_info *ecp_curve_info_from_name( const char *name ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( strcasecmp( curve_info->name, name ) == 0 ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the type of a curve + */ +static inline ecp_curve_type ecp_get_type( const ecp_group *grp ) +{ + if( grp->G.X.p == NULL ) + return( POLARSSL_ECP_TYPE_NONE ); + + if( grp->G.Y.p == NULL ) + return( POLARSSL_ECP_TYPE_MONTGOMERY ); + else + return( POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ); +} + +/* + * Initialize (the components of) a point + */ +void ecp_point_init( ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mpi_init( &pt->X ); + mpi_init( &pt->Y ); + mpi_init( &pt->Z ); +} + +/* + * Initialize (the components of) a group + */ +void ecp_group_init( ecp_group *grp ) +{ + if( grp == NULL ) + return; + + memset( grp, 0, sizeof( ecp_group ) ); +} + +/* + * Initialize (the components of) a key pair + */ +void ecp_keypair_init( ecp_keypair *key ) +{ + if( key == NULL ) + return; + + ecp_group_init( &key->grp ); + mpi_init( &key->d ); + ecp_point_init( &key->Q ); +} + +/* + * Unallocate (the components of) a point + */ +void ecp_point_free( ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mpi_free( &( pt->X ) ); + mpi_free( &( pt->Y ) ); + mpi_free( &( pt->Z ) ); +} + +/* + * Unallocate (the components of) a group + */ +void ecp_group_free( ecp_group *grp ) +{ + size_t i; + + if( grp == NULL ) + return; + + if( grp->h != 1 ) + { + mpi_free( &grp->P ); + mpi_free( &grp->A ); + mpi_free( &grp->B ); + ecp_point_free( &grp->G ); + mpi_free( &grp->N ); + } + + if( grp->T != NULL ) + { + for( i = 0; i < grp->T_size; i++ ) + ecp_point_free( &grp->T[i] ); + polarssl_free( grp->T ); + } + + polarssl_zeroize( grp, sizeof( ecp_group ) ); +} + +/* + * Unallocate (the components of) a key pair + */ +void ecp_keypair_free( ecp_keypair *key ) +{ + if( key == NULL ) + return; + + ecp_group_free( &key->grp ); + mpi_free( &key->d ); + ecp_point_free( &key->Q ); +} + +/* + * Copy the contents of a point + */ +int ecp_copy( ecp_point *P, const ecp_point *Q ) +{ + int ret; + + MPI_CHK( mpi_copy( &P->X, &Q->X ) ); + MPI_CHK( mpi_copy( &P->Y, &Q->Y ) ); + MPI_CHK( mpi_copy( &P->Z, &Q->Z ) ); + +cleanup: + return( ret ); +} + +/* + * Copy the contents of a group object + */ +int ecp_group_copy( ecp_group *dst, const ecp_group *src ) +{ + return ecp_use_known_dp( dst, src->id ); +} + +/* + * Set point to zero + */ +int ecp_set_zero( ecp_point *pt ) +{ + int ret; + + MPI_CHK( mpi_lset( &pt->X , 1 ) ); + MPI_CHK( mpi_lset( &pt->Y , 1 ) ); + MPI_CHK( mpi_lset( &pt->Z , 0 ) ); + +cleanup: + return( ret ); +} + +/* + * Tell if a point is zero + */ +int ecp_is_zero( ecp_point *pt ) +{ + return( mpi_cmp_int( &pt->Z, 0 ) == 0 ); +} + +/* + * Import a non-zero point from ASCII strings + */ +int ecp_point_read_string( ecp_point *P, int radix, + const char *x, const char *y ) +{ + int ret; + + MPI_CHK( mpi_read_string( &P->X, radix, x ) ); + MPI_CHK( mpi_read_string( &P->Y, radix, y ) ); + MPI_CHK( mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Export a point into unsigned binary data (SEC1 2.3.3) + */ +int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ) +{ + int ret = 0; + size_t plen; + + if( format != POLARSSL_ECP_PF_UNCOMPRESSED && + format != POLARSSL_ECP_PF_COMPRESSED ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Common case: P == 0 + */ + if( mpi_cmp_int( &P->Z, 0 ) == 0 ) + { + if( buflen < 1 ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x00; + *olen = 1; + + return( 0 ); + } + + plen = mpi_size( &grp->P ); + + if( format == POLARSSL_ECP_PF_UNCOMPRESSED ) + { + *olen = 2 * plen + 1; + + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x04; + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + } + else if( format == POLARSSL_ECP_PF_COMPRESSED ) + { + *olen = plen + 1; + + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 ); + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + } + +cleanup: + return( ret ); +} + +/* + * Import a point from unsigned binary data (SEC1 2.3.4) + */ +int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt, + const unsigned char *buf, size_t ilen ) +{ + int ret; + size_t plen; + + if ( ilen < 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( buf[0] == 0x00 ) + { + if( ilen == 1 ) + return( ecp_set_zero( pt ) ); + else + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + } + + plen = mpi_size( &grp->P ); + + if( buf[0] != 0x04 ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + if( ilen != 2 * plen + 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) ); + MPI_CHK( mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); + MPI_CHK( mpi_lset( &pt->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Import a point from a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt, + const unsigned char **buf, size_t buf_len ) +{ + unsigned char data_len; + const unsigned char *buf_start; + + /* + * We must have at least two bytes (1 for length, at least one for data) + */ + if( buf_len < 2 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + data_len = *(*buf)++; + if( data_len < 1 || data_len > buf_len - 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Save buffer start for read_binary and update buf + */ + buf_start = *buf; + *buf += data_len; + + return ecp_point_read_binary( grp, pt, buf_start, data_len ); +} + +/* + * Export a point as a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ) +{ + int ret; + + /* + * buffer length must be at least one, for our length byte + */ + if( blen < 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_point_write_binary( grp, pt, format, + olen, buf + 1, blen - 1) ) != 0 ) + return( ret ); + + /* + * write length to the first byte and update total length + */ + buf[0] = (unsigned char) *olen; + ++*olen; + + return( 0 ); +} + +/* + * Import an ECP group from ASCII strings, case A == -3 + */ +int ecp_group_read_string( ecp_group *grp, int radix, + const char *p, const char *b, + const char *gx, const char *gy, const char *n) +{ + int ret; + + MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); + MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); + MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); + MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} + +/* + * Set a group from an ECParameters record (RFC 4492) + */ +int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len ) +{ + uint16_t tls_id; + const ecp_curve_info *curve_info; + + /* + * We expect at least three bytes (see below) + */ + if( len < 3 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * First byte is curve_type; only named_curve is handled + */ + if( *(*buf)++ != POLARSSL_ECP_TLS_NAMED_CURVE ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Next two bytes are the namedcurve value + */ + tls_id = *(*buf)++; + tls_id <<= 8; + tls_id |= *(*buf)++; + + if( ( curve_info = ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + return ecp_use_known_dp( grp, curve_info->grp_id ); +} + +/* + * Write the ECParameters record corresponding to a group (RFC 4492) + */ +int ecp_tls_write_group( const ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen ) +{ + const ecp_curve_info *curve_info; + + if( ( curve_info = ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * We are going to write 3 bytes (see below) + */ + *olen = 3; + if( blen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + /* + * First byte is curve_type, always named_curve + */ + *buf++ = POLARSSL_ECP_TLS_NAMED_CURVE; + + /* + * Next two bytes are the namedcurve value + */ + buf[0] = curve_info->tls_id >> 8; + buf[1] = curve_info->tls_id & 0xFF; + + return( 0 ); +} + +/* + * Wrapper around fast quasi-modp functions, with fall-back to mpi_mod_mpi. + * See the documentation of struct ecp_group. + * + * This function is in the critial loop for ecp_mul, so pay attention to perf. + */ +static int ecp_modp( mpi *N, const ecp_group *grp ) +{ + int ret; + + if( grp->modp == NULL ) + return( mpi_mod_mpi( N, N, &grp->P ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + if( ( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 ) || + mpi_msb( N ) > 2 * grp->pbits ) + { + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + } + + MPI_CHK( grp->modp( N ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + while( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 ) + MPI_CHK( mpi_add_mpi( N, N, &grp->P ) ); + + while( mpi_cmp_mpi( N, &grp->P ) >= 0 ) + /* we known P, N and the result are positive */ + MPI_CHK( mpi_sub_abs( N, N, &grp->P ) ); + +cleanup: + return( ret ); +} + +/* + * Fast mod-p functions expect their argument to be in the 0..p^2 range. + * + * In order to guarantee that, we need to ensure that operands of + * mpi_mul_mpi are in the 0..p range. So, after each operation we will + * bring the result back to this range. + * + * The following macros are shortcuts for doing that. + */ + +/* + * Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi + */ +#if defined(POLARSSL_SELF_TEST) +#define INC_MUL_COUNT mul_count++; +#else +#define INC_MUL_COUNT +#endif + +#define MOD_MUL( N ) do { MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ + while( 0 ) + +/* + * Reduce a mpi mod p in-place, to use after mpi_sub_mpi + * N->s < 0 is a very fast test, which fails only if N is 0 + */ +#define MOD_SUB( N ) \ + while( N.s < 0 && mpi_cmp_int( &N, 0 ) != 0 ) \ + MPI_CHK( mpi_add_mpi( &N, &N, &grp->P ) ) + +/* + * Reduce a mpi mod p in-place, to use after mpi_add_mpi and mpi_mul_int. + * We known P, N and the result are positive, so sub_abs is correct, and + * a bit faster. + */ +#define MOD_ADD( N ) \ + while( mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ + MPI_CHK( mpi_sub_abs( &N, &N, &grp->P ) ) + +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) +/* + * For curves in short Weierstrass form, we do all the internal operations in + * Jacobian coordinates. + * + * For multiplication, we'll use a comb method with coutermeasueres against + * SPA, hence timing attacks. + */ + +/* + * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) + * Cost: 1N := 1I + 3M + 1S + */ +static int ecp_normalize_jac( const ecp_group *grp, ecp_point *pt ) +{ + int ret; + mpi Zi, ZZi; + + if( mpi_cmp_int( &pt->Z, 0 ) == 0 ) + return( 0 ); + + mpi_init( &Zi ); mpi_init( &ZZi ); + + /* + * X = X / Z^2 mod p + */ + MPI_CHK( mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); + MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); + + /* + * Y = Y / Z^3 mod p + */ + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); + + /* + * Z = 1 + */ + MPI_CHK( mpi_lset( &pt->Z, 1 ) ); + +cleanup: + + mpi_free( &Zi ); mpi_free( &ZZi ); + + return( ret ); +} + +/* + * Normalize jacobian coordinates of an array of (pointers to) points, + * using Montgomery's trick to perform only one inversion mod P. + * (See for example Cohen's "A Course in Computational Algebraic Number + * Theory", Algorithm 10.3.4.) + * + * Warning: fails (returning an error) if one of the points is zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * Cost: 1N(t) := 1I + (6t - 3)M + 1S + */ +static int ecp_normalize_jac_many( const ecp_group *grp, + ecp_point *T[], size_t t_len ) +{ + int ret; + size_t i; + mpi *c, u, Zi, ZZi; + + if( t_len < 2 ) + return( ecp_normalize_jac( grp, *T ) ); + + if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL ) + return( POLARSSL_ERR_ECP_MALLOC_FAILED ); + + mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi ); + for( i = 0; i < t_len; i++ ) + mpi_init( &c[i] ); + + /* + * c[i] = Z_0 * ... * Z_i + */ + MPI_CHK( mpi_copy( &c[0], &T[0]->Z ) ); + for( i = 1; i < t_len; i++ ) + { + MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); + MOD_MUL( c[i] ); + } + + /* + * u = 1 / (Z_0 * ... * Z_n) mod P + */ + MPI_CHK( mpi_inv_mod( &u, &c[t_len-1], &grp->P ) ); + + for( i = t_len - 1; ; i-- ) + { + /* + * Zi = 1 / Z_i mod p + * u = 1 / (Z_0 * ... * Z_i) mod P + */ + if( i == 0 ) { + MPI_CHK( mpi_copy( &Zi, &u ) ); + } + else + { + MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); + MPI_CHK( mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); + } + + /* + * proceed as in normalize() + */ + MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MPI_CHK( mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); + + /* + * Post-precessing: reclaim some memory by shrinking coordinates + * - not storing Z (always 1) + * - shrinking other coordinates, but still keeping the same number of + * limbs as P, as otherwise it will too likely be regrown too fast. + */ + MPI_CHK( mpi_shrink( &T[i]->X, grp->P.n ) ); + MPI_CHK( mpi_shrink( &T[i]->Y, grp->P.n ) ); + mpi_free( &T[i]->Z ); + + if( i == 0 ) + break; + } + +cleanup: + + mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi ); + for( i = 0; i < t_len; i++ ) + mpi_free( &c[i] ); + polarssl_free( c ); + + return( ret ); +} + +/* + * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. + * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid + */ +static int ecp_safe_invert_jac( const ecp_group *grp, + ecp_point *Q, + unsigned char inv ) +{ + int ret; + unsigned char nonzero; + mpi mQY; + + mpi_init( &mQY ); + + /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ + MPI_CHK( mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); + nonzero = mpi_cmp_int( &Q->Y, 0 ) != 0; + MPI_CHK( mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); + +cleanup: + mpi_free( &mQY ); + + return( ret ); +} + +/* + * Point doubling R = 2 P, Jacobian coordinates + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian/doubling/dbl-2007-bl.op3 + * with heavy variable renaming, some reordering and one minor modification + * (a = 2 * b, c = d - 2a replaced with c = d, c = c - b, c = c - b) + * in order to use a lot less intermediate variables (6 vs 25). + * + * Cost: 1D := 2M + 8S + */ +static int ecp_double_jac( const ecp_group *grp, ecp_point *R, + const ecp_point *P ) +{ + int ret; + mpi T1, T2, T3, X3, Y3, Z3; + +#if defined(POLARSSL_SELF_TEST) + dbl_count++; +#endif + + mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); + mpi_init( &X3 ); mpi_init( &Y3 ); mpi_init( &Z3 ); + + MPI_CHK( mpi_mul_mpi( &T3, &P->X, &P->X ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T2, &P->Y, &P->Y ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_mul_mpi( &Y3, &T2, &T2 ) ); MOD_MUL( Y3 ); + MPI_CHK( mpi_add_mpi( &X3, &P->X, &T2 ) ); MOD_ADD( X3 ); + MPI_CHK( mpi_mul_mpi( &X3, &X3, &X3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &Y3 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T3 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_mul_int( &T1, &X3, 2 ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &Z3, &P->Z, &P->Z ) ); MOD_MUL( Z3 ); + MPI_CHK( mpi_mul_mpi( &X3, &Z3, &Z3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_mul_int( &T3, &T3, 3 ) ); MOD_ADD( T3 ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) ); + X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */ + MOD_SUB( X3 ); + } + else + MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 ); + + MPI_CHK( mpi_add_mpi( &T3, &T3, &X3 ) ); MOD_ADD( T3 ); + MPI_CHK( mpi_mul_mpi( &X3, &T3, &T3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &X3 ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_mul_mpi( &T1, &T3, &T1 ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_int( &T3, &Y3, 8 ) ); MOD_ADD( T3 ); + MPI_CHK( mpi_sub_mpi( &Y3, &T1, &T3 ) ); MOD_SUB( Y3 ); + MPI_CHK( mpi_add_mpi( &T1, &P->Y, &P->Z ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &T1, &T1, &T1 ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &T2 ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_sub_mpi( &Z3, &T1, &Z3 ) ); MOD_SUB( Z3 ); + + MPI_CHK( mpi_copy( &R->X, &X3 ) ); + MPI_CHK( mpi_copy( &R->Y, &Y3 ) ); + MPI_CHK( mpi_copy( &R->Z, &Z3 ) ); + +cleanup: + mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); + mpi_free( &X3 ); mpi_free( &Y3 ); mpi_free( &Z3 ); + + return( ret ); +} + +/* + * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. + * None of these cases can happen as intermediate step in ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base point, the factor + * being less than its order, so none of them is zero; + * - Q is an odd multiple of the base point, P an even multiple, + * due to the choice of precomputed points in the modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as meaning 1. + * + * Cost: 1A := 8M + 3S + */ +static int ecp_add_mixed( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + mpi T1, T2, T3, T4, X, Y, Z; + +#if defined(POLARSSL_SELF_TEST) + add_count++; +#endif + + /* + * Trivial cases: P == 0 or Q == 0 (case 1) + */ + if( mpi_cmp_int( &P->Z, 0 ) == 0 ) + return( ecp_copy( R, Q ) ); + + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 0 ) == 0 ) + return( ecp_copy( R, P ) ); + + /* + * Make sure Q coordinates are normalized + */ + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 ); + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + + MPI_CHK( mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); + + /* Special cases (2) and (3) */ + if( mpi_cmp_int( &T1, 0 ) == 0 ) + { + if( mpi_cmp_int( &T2, 0 ) == 0 ) + { + ret = ecp_double_jac( grp, R, P ); + goto cleanup; + } + else + { + ret = ecp_set_zero( R ); + goto cleanup; + } + } + + MPI_CHK( mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); + MPI_CHK( mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); + MPI_CHK( mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); + MPI_CHK( mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); + MPI_CHK( mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); + MPI_CHK( mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); + + MPI_CHK( mpi_copy( &R->X, &X ) ); + MPI_CHK( mpi_copy( &R->Y, &Y ) ); + MPI_CHK( mpi_copy( &R->Z, &Z ) ); + +cleanup: + + mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); mpi_free( &T4 ); + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + + return( ret ); +} + +/* + * Addition: R = P + Q, result's coordinates normalized + */ +int ecp_add( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + MPI_CHK( ecp_add_mixed( grp, R, P, Q ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + return( ret ); +} + +/* + * Subtraction: R = P - Q, result's coordinates normalized + */ +int ecp_sub( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + ecp_point mQ; + + ecp_point_init( &mQ ); + + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + /* mQ = - Q */ + MPI_CHK( ecp_copy( &mQ, Q ) ); + if( mpi_cmp_int( &mQ.Y, 0 ) != 0 ) + MPI_CHK( mpi_sub_mpi( &mQ.Y, &grp->P, &mQ.Y ) ); + + MPI_CHK( ecp_add_mixed( grp, R, P, &mQ ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + ecp_point_free( &mQ ); + + return( ret ); +} + +/* + * Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_jac(). + * + * This countermeasure was first suggested in [2]. + */ +static int ecp_randomize_jac( const ecp_group *grp, ecp_point *pt, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mpi l, ll; + size_t p_size = ( grp->pbits + 7 ) / 8; + int count = 0; + + mpi_init( &l ); mpi_init( &ll ); + + /* Generate l such that 1 < l < p */ + do + { + mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &l, 1 ) <= 0 ); + + /* Z = l * Z */ + MPI_CHK( mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); + + /* X = l^2 * X */ + MPI_CHK( mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); + MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); + + /* Y = l^3 * Y */ + MPI_CHK( mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); + +cleanup: + mpi_free( &l ); mpi_free( &ll ); + + return( ret ); +} + +/* + * Check and define parameters used by the comb method (see below for details) + */ +#if POLARSSL_ECP_WINDOW_SIZE < 2 || POLARSSL_ECP_WINDOW_SIZE > 7 +#error "POLARSSL_ECP_WINDOW_SIZE out of bounds" +#endif + +/* d = ceil( n / w ) */ +#define COMB_MAX_D ( POLARSSL_ECP_MAX_BITS + 1 ) / 2 + +/* number of precomputed points */ +#define COMB_MAX_PRE ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) ) + +/* + * Compute the representation of m that will be used with our comb method. + * + * The basic comb method is described in GECC 3.44 for example. We use a + * modified version that provides resistance to SPA by avoiding zero + * digits in the representation as in [3]. We modify the method further by + * requiring that all K_i be odd, which has the small cost that our + * representation uses one more K_i, due to carries. + * + * Also, for the sake of compactness, only the seven low-order bits of x[i] + * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in + * the paper): it is set if and only if if s_i == -1; + * + * Calling conventions: + * - x is an array of size d + 1 + * - w is the size, ie number of teeth, of the comb, and must be between + * 2 and 7 (in practice, between 2 and POLARSSL_ECP_WINDOW_SIZE) + * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d + * (the result will be incorrect if these assumptions are not satisfied) + */ +static void ecp_comb_fixed( unsigned char x[], size_t d, + unsigned char w, const mpi *m ) +{ + size_t i, j; + unsigned char c, cc, adjust; + + memset( x, 0, d+1 ); + + /* First get the classical comb values (except for x_d = 0) */ + for( i = 0; i < d; i++ ) + for( j = 0; j < w; j++ ) + x[i] |= mpi_get_bit( m, i + d * j ) << j; + + /* Now make sure x_1 .. x_d are odd */ + c = 0; + for( i = 1; i <= d; i++ ) + { + /* Add carry and update it */ + cc = x[i] & c; + x[i] = x[i] ^ c; + c = cc; + + /* Adjust if needed, avoiding branches */ + adjust = 1 - ( x[i] & 0x01 ); + c |= x[i] & ( x[i-1] * adjust ); + x[i] = x[i] ^ ( x[i-1] * adjust ); + x[i-1] |= adjust << 7; + } +} + +/* + * Precompute points for the comb method + * + * If i = i_{w-1} ... i_1 is the binary representation of i, then + * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P + * + * T must be able to hold 2^{w - 1} elements + * + * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) + */ +static int ecp_precompute_comb( const ecp_group *grp, + ecp_point T[], const ecp_point *P, + unsigned char w, size_t d ) +{ + int ret; + unsigned char i, k; + size_t j; + ecp_point *cur, *TT[COMB_MAX_PRE - 1]; + + /* + * Set T[0] = P and + * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) + */ + MPI_CHK( ecp_copy( &T[0], P ) ); + + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + cur = T + i; + MPI_CHK( ecp_copy( cur, T + ( i >> 1 ) ) ); + for( j = 0; j < d; j++ ) + MPI_CHK( ecp_double_jac( grp, cur, cur ) ); + + TT[k++] = cur; + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + + /* + * Compute the remaining ones using the minimal number of additions + * Be careful to update T[2^l] only after using it! + */ + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + j = i; + while( j-- ) + { + MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); + TT[k++] = &T[i + j]; + } + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + +cleanup: + return( ret ); +} + +/* + * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] + */ +static int ecp_select_comb( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + unsigned char i ) +{ + int ret; + unsigned char ii, j; + + /* Ignore the "sign" bit and scale down */ + ii = ( i & 0x7Fu ) >> 1; + + /* Read the whole table to thwart cache-based timing attacks */ + for( j = 0; j < t_len; j++ ) + { + MPI_CHK( mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); + MPI_CHK( mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); + } + + /* Safely invert result if i is "negative" */ + MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); + +cleanup: + return( ret ); +} + +/* + * Core multiplication algorithm for the (modified) comb method. + * This part is actually common with the basic comb method (GECC 3.44) + * + * Cost: d A + d D + 1 R + */ +static int ecp_mul_comb_core( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + const unsigned char x[], size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + ecp_point Txi; + size_t i; + + ecp_point_init( &Txi ); + + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) ); + MPI_CHK( mpi_lset( &R->Z, 1 ) ); + if( f_rng != 0 ) + MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); + + while( i-- != 0 ) + { + MPI_CHK( ecp_double_jac( grp, R, R ) ); + MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) ); + MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); + } + +cleanup: + ecp_point_free( &Txi ); + + return( ret ); +} + +/* + * Multiplication using the comb method, + * for curves in short Weierstrass form + */ +static int ecp_mul_comb( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char w, m_is_odd, p_eq_g, pre_len, i; + size_t d; + unsigned char k[COMB_MAX_D + 1]; + ecp_point *T; + mpi M, mm; + + mpi_init( &M ); + mpi_init( &mm ); + + /* we need N to be odd to trnaform m in an odd number, check now */ + if( mpi_get_bit( &grp->N, 0 ) != 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Minimize the number of multiplications, that is minimize + * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) + * (see costs of the various parts, with 1S = 1M) + */ + w = grp->nbits >= 384 ? 5 : 4; + + /* + * If P == G, pre-compute a bit more, since this may be re-used later. + * Just adding one avoids upping the cost of the first mul too much, + * and the memory cost too. + */ +#if POLARSSL_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = ( mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && + mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); + if( p_eq_g ) + w++; +#else + p_eq_g = 0; +#endif + + /* + * Make sure w is within bounds. + * (The last test is useful only for very small curves in the test suite.) + */ + if( w > POLARSSL_ECP_WINDOW_SIZE ) + w = POLARSSL_ECP_WINDOW_SIZE; + if( w >= grp->nbits ) + w = 2; + + /* Other sizes that depend on w */ + pre_len = 1U << ( w - 1 ); + d = ( grp->nbits + w - 1 ) / w; + + /* + * Prepare precomputed points: if P == G we want to + * use grp->T if already initialized, or initialize it. + */ + T = p_eq_g ? grp->T : NULL; + + if( T == NULL ) + { + T = (ecp_point *) polarssl_malloc( pre_len * sizeof( ecp_point ) ); + if( T == NULL ) + { + ret = POLARSSL_ERR_ECP_MALLOC_FAILED; + goto cleanup; + } + + for( i = 0; i < pre_len; i++ ) + ecp_point_init( &T[i] ); + + MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) ); + + if( p_eq_g ) + { + grp->T = T; + grp->T_size = pre_len; + } + } + + /* + * Make sure M is odd (M = m or M = N - m, since N is odd) + * using the fact that m * P = - (N - m) * P + */ + m_is_odd = ( mpi_get_bit( m, 0 ) == 1 ); + MPI_CHK( mpi_copy( &M, m ) ); + MPI_CHK( mpi_sub_mpi( &mm, &grp->N, m ) ); + MPI_CHK( mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) ); + + /* + * Go for comb multiplication, R = M * P + */ + ecp_comb_fixed( k, d, w, &M ); + MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) ); + + /* + * Now get m * P from M * P and normalize it + */ + MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + + if( T != NULL && ! p_eq_g ) + { + for( i = 0; i < pre_len; i++ ) + ecp_point_free( &T[i] ); + polarssl_free( T ); + } + + mpi_free( &M ); + mpi_free( &mm ); + + if( ret != 0 ) + ecp_point_free( R ); + + return( ret ); +} + +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + +#if defined(POLARSSL_ECP_MONTGOMERY) +/* + * For Montgomery curves, we do all the internal arithmetic in projective + * coordinates. Import/export of points uses only the x coordinates, which is + * internaly represented as X / Z. + * + * For scalar multiplication, we'll use a Montgomery ladder. + */ + +/* + * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 + * Cost: 1M + 1I + */ +static int ecp_normalize_mxz( const ecp_group *grp, ecp_point *P ) +{ + int ret; + + MPI_CHK( mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_mxz(). + * + * This countermeasure was first suggested in [2]. + * Cost: 2M + */ +static int ecp_randomize_mxz( const ecp_group *grp, ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mpi l; + size_t p_size = ( grp->pbits + 7 ) / 8; + int count = 0; + + mpi_init( &l ); + + /* Generate l such that 1 < l < p */ + do + { + mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &l, 1 ) <= 0 ); + + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); + +cleanup: + mpi_free( &l ); + + return( ret ); +} + +/* + * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), + * for Montgomery curves in x/z coordinates. + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 + * with + * d = X1 + * P = (X2, Z2) + * Q = (X3, Z3) + * R = (X4, Z4) + * S = (X5, Z5) + * and eliminating temporary variables tO, ..., t4. + * + * Cost: 5M + 4S + */ +static int ecp_double_add_mxz( const ecp_group *grp, + ecp_point *R, ecp_point *S, + const ecp_point *P, const ecp_point *Q, + const mpi *d ) +{ + int ret; + mpi A, AA, B, BB, E, C, D, DA, CB; + + mpi_init( &A ); mpi_init( &AA ); mpi_init( &B ); + mpi_init( &BB ); mpi_init( &E ); mpi_init( &C ); + mpi_init( &D ); mpi_init( &DA ); mpi_init( &CB ); + + MPI_CHK( mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); + MPI_CHK( mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); + MPI_CHK( mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); + MPI_CHK( mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); + MPI_CHK( mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); + MPI_CHK( mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); + MPI_CHK( mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); + MPI_CHK( mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); + MPI_CHK( mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); + MPI_CHK( mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); + MPI_CHK( mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); + MPI_CHK( mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); + MPI_CHK( mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); + +cleanup: + mpi_free( &A ); mpi_free( &AA ); mpi_free( &B ); + mpi_free( &BB ); mpi_free( &E ); mpi_free( &C ); + mpi_free( &D ); mpi_free( &DA ); mpi_free( &CB ); + + return( ret ); +} + +/* + * Multiplication with Montgomery ladder in x/z coordinates, + * for curves in Montgomery form + */ +static int ecp_mul_mxz( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i; + unsigned char b; + ecp_point RP; + mpi PX; + + ecp_point_init( &RP ); mpi_init( &PX ); + + /* Save PX and read from P before writing to R, in case P == R */ + MPI_CHK( mpi_copy( &PX, &P->X ) ); + MPI_CHK( ecp_copy( &RP, P ) ); + + /* Set R to zero in modified x/z coordinates */ + MPI_CHK( mpi_lset( &R->X, 1 ) ); + MPI_CHK( mpi_lset( &R->Z, 0 ) ); + mpi_free( &R->Y ); + + /* RP.X might be sligtly larger than P, so reduce it */ + MOD_ADD( RP.X ); + + /* Randomize coordinates of the starting point */ + if( f_rng != NULL ) + MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); + + /* Loop invariant: R = result so far, RP = R + P */ + i = mpi_msb( m ); /* one past the (zero-based) most significant bit */ + while( i-- > 0 ) + { + b = mpi_get_bit( m, i ); + /* + * if (b) R = 2R + P else R = 2R, + * which is: + * if (b) double_add( RP, R, RP, R ) + * else double_add( R, RP, R, RP ) + * but using safe conditional swaps to avoid leaks + */ + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + } + + MPI_CHK( ecp_normalize_mxz( grp, R ) ); + +cleanup: + ecp_point_free( &RP ); mpi_free( &PX ); + + return( ret ); +} + +#endif /* POLARSSL_ECP_MONTGOMERY */ + +/* + * Multiplication R = m * P + */ +int ecp_mul( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + + /* Common sanity checks */ + if( mpi_cmp_int( &P->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_check_privkey( grp, m ) ) != 0 || + ( ret = ecp_check_pubkey( grp, P ) ) != 0 ) + return( ret ); + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) +/* + * Check that an affine point is valid as a public key, + * short weierstrass curves (SEC1 3.2.3.1) + */ +static int ecp_check_pubkey_sw( const ecp_group *grp, const ecp_point *pt ) +{ + int ret; + mpi YY, RHS; + + /* pt coordinates must be normalized for our checks */ + if( mpi_cmp_int( &pt->X, 0 ) < 0 || + mpi_cmp_int( &pt->Y, 0 ) < 0 || + mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || + mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + + mpi_init( &YY ); mpi_init( &RHS ); + + /* + * YY = Y^2 + * RHS = X (X^2 + A) + B = X^3 + A X + B + */ + MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); + MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); + } + else + { + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); + } + + MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); + + if( mpi_cmp_mpi( &YY, &RHS ) != 0 ) + ret = POLARSSL_ERR_ECP_INVALID_KEY; + +cleanup: + + mpi_free( &YY ); mpi_free( &RHS ); + + return( ret ); +} +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + + +#if defined(POLARSSL_ECP_MONTGOMERY) +/* + * Check validity of a public key for Montgomery curves with x-only schemes + */ +static int ecp_check_pubkey_mx( const ecp_group *grp, const ecp_point *pt ) +{ + /* [M255 p. 5] Just check X is the correct number of bytes */ + if( mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + + return( 0 ); +} +#endif /* POLARSSL_ECP_MONTGOMERY */ + +/* + * Check that a point is valid as a public key + */ +int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt ) +{ + /* Must use affine coordinates */ + if( mpi_cmp_int( &pt->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_check_pubkey_mx( grp, pt ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_check_pubkey_sw( grp, pt ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Check that an mpi is valid as a private key + */ +int ecp_check_privkey( const ecp_group *grp, const mpi *d ) +{ +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* see [M255] page 5 */ + if( mpi_get_bit( d, 0 ) != 0 || + mpi_get_bit( d, 1 ) != 0 || + mpi_get_bit( d, 2 ) != 0 || + mpi_msb( d ) - 1 != grp->nbits ) /* mpi_msb is one-based! */ + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* see SEC1 3.2 */ + if( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Generate a keypair + */ +int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* [M225] page 5 */ + size_t b; + + MPI_CHK( mpi_fill_random( d, n_size, f_rng, p_rng ) ); + + /* Make sure the most significant bit is nbits */ + b = mpi_msb( d ) - 1; /* mpi_msb is one-based */ + if( b > grp->nbits ) + MPI_CHK( mpi_shift_r( d, b - grp->nbits ) ); + else + MPI_CHK( mpi_set_bit( d, grp->nbits, 1 ) ); + + /* Make sure the last three bits are unset */ + MPI_CHK( mpi_set_bit( d, 0, 0 ) ); + MPI_CHK( mpi_set_bit( d, 1, 0 ) ); + MPI_CHK( mpi_set_bit( d, 2, 0 ) ); + } + else +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* SEC1 3.2.1: Generate d such that 1 <= n < N */ + int count = 0; + unsigned char rnd[POLARSSL_ECP_MAX_BYTES]; + + /* + * Match the procedure given in RFC 6979 (deterministic ECDSA): + * - use the same byte ordering; + * - keep the leftmost nbits bits of the generated octet string; + * - try until result is in the desired range. + * This also avoids any biais, which is especially important for ECDSA. + */ + do + { + MPI_CHK( f_rng( p_rng, rnd, n_size ) ); + MPI_CHK( mpi_read_binary( d, rnd, n_size ) ); + MPI_CHK( mpi_shift_r( d, 8 * n_size - grp->nbits ) ); + + /* + * Each try has at worst a probability 1/2 of failing (the msb has + * a probability 1/2 of being 0, and then the result will be < N), + * so after 30 tries failure probability is a most 2**(-30). + * + * For most curves, 1 try is enough with overwhelming probability, + * since N starts with a lot of 1s in binary, but some curves + * such as secp224k1 are actually very close to the worst case. + */ + if( ++count > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ); + } + else +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + +cleanup: + if( ret != 0 ) + return( ret ); + + return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); +} + +/* + * Generate a keypair, prettier wrapper + */ +int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + + if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 ) + return( ret ); + + return( ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecp_self_test( int verbose ) +{ + int ret; + size_t i; + ecp_group grp; + ecp_point R, P; + mpi m; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; + /* exponents especially adapted for secp192r1 */ + const char *exponents[] = + { + "000000000000000000000000000000000000000000000001", /* one */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ + "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ + }; + + ecp_group_init( &grp ); + ecp_point_init( &R ); + ecp_point_init( &P ); + mpi_init( &m ); + + /* Use secp192r1 if available, or any available curve */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) ); +#else + MPI_CHK( ecp_use_known_dp( &grp, ecp_curve_list()->grp_id ) ); +#endif + + if( verbose != 0 ) + polarssl_printf( " ECP test #1 (constant op_count, base point G): " ); + + /* Do a dummy multiplication first to trigger precomputation */ + MPI_CHK( mpi_lset( &m, 2 ) ); + MPI_CHK( ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " ECP test #2 (constant op_count, other point): " ); + /* We computed P = 2G last time, use it */ + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret < 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + ecp_group_free( &grp ); + ecp_point_free( &R ); + ecp_point_free( &P ); + mpi_free( &m ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECP_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp_curves.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp_curves.c new file mode 100644 index 0000000..4c0018c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ecp_curves.c @@ -0,0 +1,1380 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* + * Conversion macros for embedded constants: + * build lists of t_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(POLARSSL_HAVE_INT8) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + a, b, c, d, e, f, g, h + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + a, b, c, d + +#define BYTES_TO_T_UINT_2( a, b ) \ + a, b + +#elif defined(POLARSSL_HAVE_INT16) + +#define BYTES_TO_T_UINT_2( a, b ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ), \ + BYTES_TO_T_UINT_2( e, f ), \ + BYTES_TO_T_UINT_2( g, h ) + +#elif defined(POLARSSL_HAVE_INT32) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_4( a, b, 0, 0 ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_4( a, b, c, d ), \ + BYTES_TO_T_UINT_4( e, f, g, h ) + +#else /* 64-bits */ + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) | \ + ( (t_uint) e << 32 ) | \ + ( (t_uint) f << 40 ) | \ + ( (t_uint) g << 48 ) | \ + ( (t_uint) h << 56 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) + +#endif /* bits in t_uint */ + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +static const t_uint secp192r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp192r1_b[] = { + BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), + BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), + BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), +}; +static const t_uint secp192r1_gx[] = { + BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), + BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), + BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), +}; +static const t_uint secp192r1_gy[] = { + BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), + BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), + BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), +}; +static const t_uint secp192r1_n[] = { + BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), + BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +static const t_uint secp224r1_p[] = { + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), +}; +static const t_uint secp224r1_b[] = { + BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), + BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), + BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), + BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), +}; +static const t_uint secp224r1_gx[] = { + BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), + BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), + BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), + BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), +}; +static const t_uint secp224r1_gy[] = { + BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), + BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), + BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), + BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), +}; +static const t_uint secp224r1_n[] = { + BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), + BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +static const t_uint secp256r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp256r1_b[] = { + BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), + BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), + BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), + BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), +}; +static const t_uint secp256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), + BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), + BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), + BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), +}; +static const t_uint secp256r1_gy[] = { + BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), + BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), + BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), + BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), +}; +static const t_uint secp256r1_n[] = { + BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), + BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +static const t_uint secp384r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp384r1_b[] = { + BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), + BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), + BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), + BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), + BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), + BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), +}; +static const t_uint secp384r1_gx[] = { + BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), + BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), + BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), + BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), + BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), + BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), +}; +static const t_uint secp384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), + BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), + BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), + BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), + BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), + BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), +}; +static const t_uint secp384r1_n[] = { + BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), + BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), + BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +static const t_uint secp521r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +static const t_uint secp521r1_b[] = { + BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), + BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), + BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), + BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), + BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), + BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), + BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), + BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), + BYTES_TO_T_UINT_2( 0x51, 0x00 ), +}; +static const t_uint secp521r1_gx[] = { + BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), + BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), + BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), + BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), + BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), + BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), + BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), + BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), + BYTES_TO_T_UINT_2( 0xC6, 0x00 ), +}; +static const t_uint secp521r1_gy[] = { + BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), + BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), + BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), + BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), + BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), + BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), + BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), + BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), + BYTES_TO_T_UINT_2( 0x18, 0x01 ), +}; +static const t_uint secp521r1_n[] = { + BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), + BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), + BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), + BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), + BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +static const t_uint secp192k1_p[] = { + BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp192k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp192k1_b[] = { + BYTES_TO_T_UINT_2( 0x03, 0x00 ), +}; +static const t_uint secp192k1_gx[] = { + BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), + BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), + BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), +}; +static const t_uint secp192k1_gy[] = { + BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), + BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), + BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), +}; +static const t_uint secp192k1_n[] = { + BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), + BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +static const t_uint secp224k1_p[] = { + BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp224k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp224k1_b[] = { + BYTES_TO_T_UINT_2( 0x05, 0x00 ), +}; +static const t_uint secp224k1_gx[] = { + BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), + BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), + BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), + BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), +}; +static const t_uint secp224k1_gy[] = { + BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), + BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), + BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), + BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), +}; +static const t_uint secp224k1_n[] = { + BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), + BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), +}; +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +static const t_uint secp256k1_p[] = { + BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const t_uint secp256k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const t_uint secp256k1_b[] = { + BYTES_TO_T_UINT_2( 0x07, 0x00 ), +}; +static const t_uint secp256k1_gx[] = { + BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), + BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), + BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), + BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), +}; +static const t_uint secp256k1_gy[] = { + BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), + BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), + BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), + BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), +}; +static const t_uint secp256k1_n[] = { + BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), + BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) +static const t_uint brainpoolP256r1_p[] = { + BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), + BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), + BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +static const t_uint brainpoolP256r1_a[] = { + BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), + BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), + BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), + BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), +}; +static const t_uint brainpoolP256r1_b[] = { + BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), + BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), + BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), + BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), +}; +static const t_uint brainpoolP256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), + BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), + BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), + BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), +}; +static const t_uint brainpoolP256r1_gy[] = { + BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), + BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), + BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), + BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), +}; +static const t_uint brainpoolP256r1_n[] = { + BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), + BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), + BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) +static const t_uint brainpoolP384r1_p[] = { + BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), + BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), + BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), + BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +static const t_uint brainpoolP384r1_a[] = { + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), + BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), + BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), + BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), + BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), + BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), +}; +static const t_uint brainpoolP384r1_b[] = { + BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), + BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), + BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), + BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), + BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), +}; +static const t_uint brainpoolP384r1_gx[] = { + BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), + BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), + BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), + BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), + BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), + BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), +}; +static const t_uint brainpoolP384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), + BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), + BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), + BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), + BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), +}; +static const t_uint brainpoolP384r1_n[] = { + BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), + BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), + BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), + BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) +static const t_uint brainpoolP512r1_p[] = { + BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), + BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), + BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), + BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), + BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +static const t_uint brainpoolP512r1_a[] = { + BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), + BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), + BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), + BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), + BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), + BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), + BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), + BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), +}; +static const t_uint brainpoolP512r1_b[] = { + BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), + BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), + BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), + BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), + BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), + BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), + BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), + BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), +}; +static const t_uint brainpoolP512r1_gx[] = { + BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), + BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), + BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), + BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), + BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), + BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), + BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), + BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), +}; +static const t_uint brainpoolP512r1_gy[] = { + BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), + BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), + BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), + BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), + BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), + BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), + BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), +}; +static const t_uint brainpoolP512r1_n[] = { + BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), + BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), + BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), + BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), + BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof t_uint) + */ +static inline void ecp_mpi_load( mpi *X, const t_uint *p, size_t len ) +{ + X->s = 1; + X->n = len / sizeof( t_uint ); + X->p = (t_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +static inline void ecp_mpi_set1( mpi *X ) +{ + static t_uint one[] = { 1 }; + X->s = 1; + X->n = 1; + X->p = one; +} + +/* + * Make group available from embedded constants + */ +static int ecp_group_load( ecp_group *grp, + const t_uint *p, size_t plen, + const t_uint *a, size_t alen, + const t_uint *b, size_t blen, + const t_uint *gx, size_t gxlen, + const t_uint *gy, size_t gylen, + const t_uint *n, size_t nlen) +{ + ecp_mpi_load( &grp->P, p, plen ); + if( a != NULL ) + ecp_mpi_load( &grp->A, a, alen ); + ecp_mpi_load( &grp->B, b, blen ); + ecp_mpi_load( &grp->N, n, nlen ); + + ecp_mpi_load( &grp->G.X, gx, gxlen ); + ecp_mpi_load( &grp->G.Y, gy, gylen ); + ecp_mpi_set1( &grp->G.Z ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + + grp->h = 1; + + return( 0 ); +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521( mpi * ); +#endif + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +static int ecp_mod_p255( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1( mpi * ); +#endif + +#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#define LOAD_GROUP( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + NULL, 0, \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +/* + * Specialized function for creating the Curve25519 group + */ +static int ecp_use_curve25519( ecp_group *grp ) +{ + int ret; + + /* Actually ( A + 2 ) / 4 */ + MPI_CHK( mpi_read_string( &grp->A, 16, "01DB42" ) ); + + /* P = 2^255 - 19 */ + MPI_CHK( mpi_lset( &grp->P, 1 ) ); + MPI_CHK( mpi_shift_l( &grp->P, 255 ) ); + MPI_CHK( mpi_sub_int( &grp->P, &grp->P, 19 ) ); + grp->pbits = mpi_msb( &grp->P ); + + /* Y intentionaly not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MPI_CHK( mpi_lset( &grp->G.X, 9 ) ); + MPI_CHK( mpi_lset( &grp->G.Z, 1 ) ); + mpi_free( &grp->G.Y ); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) +{ + ecp_group_free( grp ); + + grp->id = id; + + switch( id ) + { +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + case POLARSSL_ECP_DP_SECP192R1: + NIST_MODP( p192 ); + return( LOAD_GROUP( secp192r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + case POLARSSL_ECP_DP_SECP224R1: + NIST_MODP( p224 ); + return( LOAD_GROUP( secp224r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + case POLARSSL_ECP_DP_SECP256R1: + NIST_MODP( p256 ); + return( LOAD_GROUP( secp256r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + case POLARSSL_ECP_DP_SECP384R1: + NIST_MODP( p384 ); + return( LOAD_GROUP( secp384r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + case POLARSSL_ECP_DP_SECP521R1: + NIST_MODP( p521 ); + return( LOAD_GROUP( secp521r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + case POLARSSL_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return( LOAD_GROUP_A( secp192k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + case POLARSSL_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return( LOAD_GROUP_A( secp224k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + case POLARSSL_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return( LOAD_GROUP_A( secp256k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + case POLARSSL_ECP_DP_BP256R1: + return( LOAD_GROUP_A( brainpoolP256r1 ) ); +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + case POLARSSL_ECP_DP_BP384R1: + return( LOAD_GROUP_A( brainpoolP384r1 ) ); +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + case POLARSSL_ECP_DP_BP512R1: + return( LOAD_GROUP_A( brainpoolP512r1 ) ); +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + case POLARSSL_ECP_DP_M255: + grp->modp = ecp_mod_p255; + return( ecp_use_curve25519( grp ) ); +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + + default: + ecp_group_free( grp ); + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic t_uint, we can + * use a t_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) +{ + unsigned char i; + t_uint c = 0; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64( t_uint *dst, t_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( t_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +static int ecp_mod_p192( mpi *N ) +{ + int ret; + t_uint c = 0; + t_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ + +#define MAX32 N->n / 4 +#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ + ( N->p[4*j+1] << 8 ) | \ + ( N->p[4*j+2] << 16 ) | \ + ( N->p[4*j+3] << 24 ) +#define STORE32 N->p[4*i+0] = (t_uint)( cur ); \ + N->p[4*i+1] = (t_uint)( cur >> 8 ); \ + N->p[4*i+2] = (t_uint)( cur >> 16 ); \ + N->p[4*i+3] = (t_uint)( cur >> 24 ); + +#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ + +#define MAX32 N->n / 2 +#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) +#define STORE32 N->p[2*i+0] = (t_uint)( cur ); \ + N->p[2*i+1] = (t_uint)( cur >> 16 ); + +#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((t_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (t_uint) cur; \ + } + +#endif /* sizeof( t_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mpi C; \ + t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( t_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( t_uint ) ); \ + \ + MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(POLARSSL_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((t_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (t_uint) -c; + + /* N = - ( C - N ) */ + MPI_CHK( mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224( mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +static int ecp_mod_p256( mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +static int ecp_mod_p384( mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || + POLARSSL_ECP_DP_SECP256R1_ENABLED || + POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of t_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) + +/* Bits to keep in the most significant t_uint */ +#if defined(POLARSSL_HAVE_INT8) +#define P521_MASK 0x01 +#else +#define P521_MASK 0x01FF +#endif + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +static int ecp_mod_p521( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when t_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + +/* Size of p255 in terms of t_uint */ +#define P255_WIDTH ( 255 / 8 / sizeof( t_uint ) + 1 ) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^255 A1, return A0 + 19 * A1 + */ +static int ecp_mod_p255( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P255_WIDTH + 2]; + + if( N->n < P255_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P255_WIDTH - 1 ); + if( M.n > P255_WIDTH + 1 ) + M.n = P255_WIDTH + 1; + M.p = Mp; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 255 % ( 8 * sizeof( t_uint ) ) ) ); + M.n++; /* Make room for multiplication by 19 */ + + /* N = A0 */ + MPI_CHK( mpi_set_bit( N, 255, 0 ) ); + for( i = P255_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + 19 * A1 */ + MPI_CHK( mpi_mul_int( &M, &M, 19 ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( t_uint ) ) // Max limbs in P +#define P_KOBLITZ_R ( 8 / sizeof( t_uint ) ) // Limbs in R +static inline int ecp_mod_koblitz( mpi *N, t_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, t_uint mask ) +{ + int ret; + size_t i; + mpi M, R; + t_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R]; + + if( N->n < p_limbs ) + return( 0 ); + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + + /* Second pass */ + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED) || + POLARSSL_ECP_DP_SECP224K1_ENABLED) || + POLARSSL_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 + */ +static int ecp_mod_p192k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + + return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +static int ecp_mod_p224k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + +#if defined(POLARSSL_HAVE_INT64) + return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); +#else + return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +#endif +} + +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +static int ecp_mod_p256k1( mpi *N ) +{ + static t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#endif /* POLARSSL_ECP_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy.c new file mode 100644 index 0000000..bc7fb0f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy.c @@ -0,0 +1,477 @@ +/* + * Entropy accumulator implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ENTROPY_C) + +#include "polarssl/entropy.h" +#include "polarssl/entropy_poll.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_HAVEGE_C) +#include "polarssl/havege.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ + +void entropy_init( entropy_context *ctx ) +{ + memset( ctx, 0, sizeof(entropy_context) ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &ctx->mutex ); +#endif + +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) + sha512_starts( &ctx->accumulator, 0 ); +#else + sha256_starts( &ctx->accumulator, 0 ); +#endif +#if defined(POLARSSL_HAVEGE_C) + havege_init( &ctx->havege_data ); +#endif + +#if !defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES) +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) + entropy_add_source( ctx, platform_entropy_poll, NULL, + ENTROPY_MIN_PLATFORM ); +#endif +#if defined(POLARSSL_TIMING_C) + entropy_add_source( ctx, hardclock_poll, NULL, ENTROPY_MIN_HARDCLOCK ); +#endif +#if defined(POLARSSL_HAVEGE_C) + entropy_add_source( ctx, havege_poll, &ctx->havege_data, + ENTROPY_MIN_HAVEGE ); +#endif +#endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */ +} + +void entropy_free( entropy_context *ctx ) +{ +#if defined(POLARSSL_HAVEGE_C) + havege_free( &ctx->havege_data ); +#endif + polarssl_zeroize( ctx, sizeof( entropy_context ) ); +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &ctx->mutex ); +#endif +} + +int entropy_add_source( entropy_context *ctx, + f_source_ptr f_source, void *p_source, + size_t threshold ) +{ + int index, ret = 0; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + index = ctx->source_count; + if( index >= ENTROPY_MAX_SOURCES ) + { + ret = POLARSSL_ERR_ENTROPY_MAX_SOURCES; + goto exit; + } + + ctx->source[index].f_source = f_source; + ctx->source[index].p_source = p_source; + ctx->source[index].threshold = threshold; + + ctx->source_count++; + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Entropy accumulator update + */ +static int entropy_update( entropy_context *ctx, unsigned char source_id, + const unsigned char *data, size_t len ) +{ + unsigned char header[2]; + unsigned char tmp[ENTROPY_BLOCK_SIZE]; + size_t use_len = len; + const unsigned char *p = data; + + if( use_len > ENTROPY_BLOCK_SIZE ) + { +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) + sha512( data, len, tmp, 0 ); +#else + sha256( data, len, tmp, 0 ); +#endif + p = tmp; + use_len = ENTROPY_BLOCK_SIZE; + } + + header[0] = source_id; + header[1] = use_len & 0xFF; + +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) + sha512_update( &ctx->accumulator, header, 2 ); + sha512_update( &ctx->accumulator, p, use_len ); +#else + sha256_update( &ctx->accumulator, header, 2 ); + sha256_update( &ctx->accumulator, p, use_len ); +#endif + + return( 0 ); +} + +int entropy_update_manual( entropy_context *ctx, + const unsigned char *data, size_t len ) +{ + int ret; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_update( ctx, ENTROPY_SOURCE_MANUAL, data, len ); + +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Run through the different sources to add entropy to our accumulator + */ +static int entropy_gather_internal( entropy_context *ctx ) +{ + int ret, i; + unsigned char buf[ENTROPY_MAX_GATHER]; + size_t olen; + + if( ctx->source_count == 0 ) + return( POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED ); + + /* + * Run through our entropy sources + */ + for( i = 0; i < ctx->source_count; i++ ) + { + olen = 0; + if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, + buf, ENTROPY_MAX_GATHER, &olen ) ) != 0 ) + { + return( ret ); + } + + /* + * Add if we actually gathered something + */ + if( olen > 0 ) + { + entropy_update( ctx, (unsigned char) i, buf, olen ); + ctx->source[i].size += olen; + } + } + + return( 0 ); +} + +/* + * Thread-safe wrapper for entropy_gather_internal() + */ +int entropy_gather( entropy_context *ctx ) +{ + int ret; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_gather_internal( ctx ); + +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +int entropy_func( void *data, unsigned char *output, size_t len ) +{ + int ret, count = 0, i, reached; + entropy_context *ctx = (entropy_context *) data; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( len > ENTROPY_BLOCK_SIZE ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + /* + * Always gather extra entropy before a call + */ + do + { + if( count++ > ENTROPY_MAX_LOOP ) + { + ret = POLARSSL_ERR_ENTROPY_SOURCE_FAILED; + goto exit; + } + + if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) + goto exit; + + reached = 0; + + for( i = 0; i < ctx->source_count; i++ ) + if( ctx->source[i].size >= ctx->source[i].threshold ) + reached++; + } + while( reached != ctx->source_count ); + + memset( buf, 0, ENTROPY_BLOCK_SIZE ); + +#if defined(POLARSSL_ENTROPY_SHA512_ACCUMULATOR) + sha512_finish( &ctx->accumulator, buf ); + + /* + * Reset accumulator and counters and recycle existing entropy + */ + memset( &ctx->accumulator, 0, sizeof( sha512_context ) ); + sha512_starts( &ctx->accumulator, 0 ); + sha512_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); + + /* + * Perform second SHA-512 on entropy + */ + sha512( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); +#else /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ + sha256_finish( &ctx->accumulator, buf ); + + /* + * Reset accumulator and counters and recycle existing entropy + */ + memset( &ctx->accumulator, 0, sizeof( sha256_context ) ); + sha256_starts( &ctx->accumulator, 0 ); + sha256_update( &ctx->accumulator, buf, ENTROPY_BLOCK_SIZE ); + + /* + * Perform second SHA-256 on entropy + */ + sha256( buf, ENTROPY_BLOCK_SIZE, buf, 0 ); +#endif /* POLARSSL_ENTROPY_SHA512_ACCUMULATOR */ + + for( i = 0; i < ctx->source_count; i++ ) + ctx->source[i].size = 0; + + memcpy( output, buf, len ); + + ret = 0; + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &ctx->mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +int entropy_write_seed_file( entropy_context *ctx, const char *path ) +{ + int ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ENTROPY_BLOCK_SIZE]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + if( ( ret = entropy_func( ctx, buf, ENTROPY_BLOCK_SIZE ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, ENTROPY_BLOCK_SIZE, f ) != ENTROPY_BLOCK_SIZE ) + { + ret = POLARSSL_ERR_ENTROPY_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int entropy_update_seed_file( entropy_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ ENTROPY_MAX_SEED_SIZE ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > ENTROPY_MAX_SEED_SIZE ) + n = ENTROPY_MAX_SEED_SIZE; + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_ENTROPY_FILE_IO_ERROR ); + } + + fclose( f ); + + entropy_update_manual( ctx, buf, n ); + + return( entropy_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif + +/* + * Dummy source function + */ +static int entropy_dummy_source( void *data, unsigned char *output, + size_t len, size_t *olen ) +{ + ((void) data); + + memset( output, 0x2a, len ); + *olen = len; + + return( 0 ); +} + +/* + * The actual entropy quality is hard to test, but we can at least + * test that the functions don't cause errors and write the correct + * amount of data to buffers. + */ +int entropy_self_test( int verbose ) +{ + int ret = 0; + entropy_context ctx; + unsigned char buf[ENTROPY_BLOCK_SIZE] = { 0 }; + unsigned char acc[ENTROPY_BLOCK_SIZE] = { 0 }; + size_t i, j; + + if( verbose != 0 ) + polarssl_printf( " ENTROPY test: " ); + + entropy_init( &ctx ); + + ret = entropy_add_source( &ctx, entropy_dummy_source, NULL, 16 ); + if( ret != 0 ) + goto cleanup; + + if( ( ret = entropy_gather( &ctx ) ) != 0 ) + goto cleanup; + + if( ( ret = entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) + goto cleanup; + + /* + * To test that entropy_func writes correct number of bytes: + * - use the whole buffer and rely on ASan to detect overruns + * - collect entropy 8 times and OR the result in an accumulator: + * any byte should then be 0 with probably 2^(-64), so requiring + * each of the 32 or 64 bytes to be non-zero has a false failure rate + * of at most 2^(-58) which is acceptable. + */ + for( i = 0; i < 8; i++ ) + { + if( ( ret = entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) + goto cleanup; + + for( j = 0; j < sizeof( buf ); j++ ) + acc[j] |= buf[j]; + } + + for( j = 0; j < sizeof( buf ); j++ ) + { + if( acc[j] == 0 ) + { + ret = 1; + goto cleanup; + } + } + +cleanup: + entropy_free( &ctx ); + + if( verbose != 0 ) + { + if( ret != 0 ) + polarssl_printf( "failed\n" ); + else + polarssl_printf( "passed\n" ); + + polarssl_printf( "\n" ); + } + + return( ret != 0 ); +} +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ENTROPY_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy_poll.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy_poll.c new file mode 100644 index 0000000..9ca9e95 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/entropy_poll.c @@ -0,0 +1,140 @@ +/* + * Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ENTROPY_C) + +#include "polarssl/entropy.h" +#include "polarssl/entropy_poll.h" + +#if defined(POLARSSL_TIMING_C) +#include "polarssl/timing.h" +#endif +#if defined(POLARSSL_HAVEGE_C) +#include "polarssl/havege.h" +#endif + +#if !defined(POLARSSL_NO_PLATFORM_ENTROPY) +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include +#include + +int platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + HCRYPTPROV provider; + ((void) data); + *olen = 0; + + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) + { + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + } + + if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + + CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +} +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +#include + +int platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + FILE *file; + size_t ret; + ((void) data); + + *olen = 0; + + file = fopen( "/dev/urandom", "rb" ); + if( file == NULL ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + + ret = fread( output, 1, len, file ); + if( ret != len ) + { + fclose( file ); + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + } + + fclose( file ); + *olen = len; + + return( 0 ); +} +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +#endif /* !POLARSSL_NO_PLATFORM_ENTROPY */ + +#if defined(POLARSSL_TIMING_C) +int hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned long timer = hardclock(); + ((void) data); + *olen = 0; + + if( len < sizeof(unsigned long) ) + return( 0 ); + + memcpy( output, &timer, sizeof(unsigned long) ); + *olen = sizeof(unsigned long); + + return( 0 ); +} +#endif /* POLARSSL_TIMING_C */ + +#if defined(POLARSSL_HAVEGE_C) +int havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + havege_state *hs = (havege_state *) data; + *olen = 0; + + if( havege_random( hs, output, len ) != 0 ) + return( POLARSSL_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = len; + + return( 0 ); +} +#endif /* POLARSSL_HAVEGE_C */ + +#endif /* POLARSSL_ENTROPY_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/error.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/error.c new file mode 100644 index 0000000..22234cf --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/error.c @@ -0,0 +1,769 @@ +/* + * Error message information + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ERROR_C) || defined(POLARSSL_ERROR_STRERROR_DUMMY) +#include "polarssl/error.h" +#endif + +#if defined(POLARSSL_ERROR_C) + +#if defined(POLARSSL_AES_C) +#include "polarssl/aes.h" +#endif + +#if defined(POLARSSL_BASE64_C) +#include "polarssl/base64.h" +#endif + +#if defined(POLARSSL_BIGNUM_C) +#include "polarssl/bignum.h" +#endif + +#if defined(POLARSSL_BLOWFISH_C) +#include "polarssl/blowfish.h" +#endif + +#if defined(POLARSSL_CAMELLIA_C) +#include "polarssl/camellia.h" +#endif + +#if defined(POLARSSL_CCM_C) +#include "polarssl/ccm.h" +#endif + +#if defined(POLARSSL_CIPHER_C) +#include "polarssl/cipher.h" +#endif + +#if defined(POLARSSL_CTR_DRBG_C) +#include "polarssl/ctr_drbg.h" +#endif + +#if defined(POLARSSL_DES_C) +#include "polarssl/des.h" +#endif + +#if defined(POLARSSL_DHM_C) +#include "polarssl/dhm.h" +#endif + +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif + +#if defined(POLARSSL_ENTROPY_C) +#include "polarssl/entropy.h" +#endif + +#if defined(POLARSSL_GCM_C) +#include "polarssl/gcm.h" +#endif + +#if defined(POLARSSL_HMAC_DRBG_C) +#include "polarssl/hmac_drbg.h" +#endif + +#if defined(POLARSSL_MD_C) +#include "polarssl/md.h" +#endif + +#if defined(POLARSSL_MD2_C) +#include "polarssl/md2.h" +#endif + +#if defined(POLARSSL_MD4_C) +#include "polarssl/md4.h" +#endif + +#if defined(POLARSSL_MD5_C) +#include "polarssl/md5.h" +#endif + +#if defined(POLARSSL_NET_C) +#include "polarssl/net.h" +#endif + +#if defined(POLARSSL_OID_C) +#include "polarssl/oid.h" +#endif + +#if defined(POLARSSL_PADLOCK_C) +#include "polarssl/padlock.h" +#endif + +#if defined(POLARSSL_PBKDF2_C) +#include "polarssl/pbkdf2.h" +#endif + +#if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PK_C) +#include "polarssl/pk.h" +#endif + +#if defined(POLARSSL_PKCS12_C) +#include "polarssl/pkcs12.h" +#endif + +#if defined(POLARSSL_PKCS5_C) +#include "polarssl/pkcs5.h" +#endif + +#if defined(POLARSSL_RIPEMD160_C) +#include "polarssl/ripemd160.h" +#endif + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif + +#if defined(POLARSSL_SHA1_C) +#include "polarssl/sha1.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#include "polarssl/sha256.h" +#endif + +#if defined(POLARSSL_SHA512_C) +#include "polarssl/sha512.h" +#endif + +#if defined(POLARSSL_SSL_TLS_C) +#include "polarssl/ssl.h" +#endif + +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +#include "polarssl/x509.h" +#endif + +#if defined(POLARSSL_XTEA_C) +#include "polarssl/xtea.h" +#endif + + +#include + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#define snprintf _snprintf +#endif + +void polarssl_strerror( int ret, char *buf, size_t buflen ) +{ + size_t len; + int use_ret; + + if( buflen == 0 ) + return; + + memset( buf, 0x00, buflen ); + /* Reduce buflen to make sure MSVC _snprintf() ends with \0 as well */ + buflen -= 1; + + if( ret < 0 ) + ret = -ret; + + if( ret & 0xFF80 ) + { + use_ret = ret & 0xFF80; + + // High level error codes + // + // BEGIN generated code +#if defined(POLARSSL_CIPHER_C) + if( use_ret == -(POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); + if( use_ret == -(POLARSSL_ERR_CIPHER_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "CIPHER - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_CIPHER_ALLOC_FAILED) ) + snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); + if( use_ret == -(POLARSSL_ERR_CIPHER_INVALID_PADDING) ) + snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" ); + if( use_ret == -(POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED) ) + snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); + if( use_ret == -(POLARSSL_ERR_CIPHER_AUTH_FAILED) ) + snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); +#endif /* POLARSSL_CIPHER_C */ + +#if defined(POLARSSL_DHM_C) + if( use_ret == -(POLARSSL_ERR_DHM_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "DHM - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_DHM_READ_PARAMS_FAILED) ) + snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED) ) + snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_READ_PUBLIC_FAILED) ) + snprintf( buf, buflen, "DHM - Reading of the public values failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED) ) + snprintf( buf, buflen, "DHM - Making of the public value failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_CALC_SECRET_FAILED) ) + snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_INVALID_FORMAT) ) + snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" ); + if( use_ret == -(POLARSSL_ERR_DHM_MALLOC_FAILED) ) + snprintf( buf, buflen, "DHM - Allocation of memory failed" ); + if( use_ret == -(POLARSSL_ERR_DHM_FILE_IO_ERROR) ) + snprintf( buf, buflen, "DHM - Read/write of file failed" ); +#endif /* POLARSSL_DHM_C */ + +#if defined(POLARSSL_ECP_C) + if( use_ret == -(POLARSSL_ERR_ECP_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "ECP - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_ECP_BUFFER_TOO_SMALL) ) + snprintf( buf, buflen, "ECP - The buffer is too small to write to" ); + if( use_ret == -(POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "ECP - Requested curve not available" ); + if( use_ret == -(POLARSSL_ERR_ECP_VERIFY_FAILED) ) + snprintf( buf, buflen, "ECP - The signature is not valid" ); + if( use_ret == -(POLARSSL_ERR_ECP_MALLOC_FAILED) ) + snprintf( buf, buflen, "ECP - Memory allocation failed" ); + if( use_ret == -(POLARSSL_ERR_ECP_RANDOM_FAILED) ) + snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" ); + if( use_ret == -(POLARSSL_ERR_ECP_INVALID_KEY) ) + snprintf( buf, buflen, "ECP - Invalid private or public key" ); + if( use_ret == -(POLARSSL_ERR_ECP_SIG_LEN_MISMATCH) ) + snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" ); +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_MD_C) + if( use_ret == -(POLARSSL_ERR_MD_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "MD - The selected feature is not available" ); + if( use_ret == -(POLARSSL_ERR_MD_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "MD - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_MD_ALLOC_FAILED) ) + snprintf( buf, buflen, "MD - Failed to allocate memory" ); + if( use_ret == -(POLARSSL_ERR_MD_FILE_IO_ERROR) ) + snprintf( buf, buflen, "MD - Opening or reading of file failed" ); +#endif /* POLARSSL_MD_C */ + +#if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C) + if( use_ret == -(POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT) ) + snprintf( buf, buflen, "PEM - No PEM header or footer found" ); + if( use_ret == -(POLARSSL_ERR_PEM_INVALID_DATA) ) + snprintf( buf, buflen, "PEM - PEM string is not as expected" ); + if( use_ret == -(POLARSSL_ERR_PEM_MALLOC_FAILED) ) + snprintf( buf, buflen, "PEM - Failed to allocate memory" ); + if( use_ret == -(POLARSSL_ERR_PEM_INVALID_ENC_IV) ) + snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" ); + if( use_ret == -(POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG) ) + snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" ); + if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_REQUIRED) ) + snprintf( buf, buflen, "PEM - Private key password can't be empty" ); + if( use_ret == -(POLARSSL_ERR_PEM_PASSWORD_MISMATCH) ) + snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" ); + if( use_ret == -(POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" ); + if( use_ret == -(POLARSSL_ERR_PEM_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "PEM - Bad input parameters to function" ); +#endif /* POLARSSL_PEM_PARSE_C || POLARSSL_PEM_WRITE_C */ + +#if defined(POLARSSL_PK_C) + if( use_ret == -(POLARSSL_ERR_PK_MALLOC_FAILED) ) + snprintf( buf, buflen, "PK - Memory alloation failed" ); + if( use_ret == -(POLARSSL_ERR_PK_TYPE_MISMATCH) ) + snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); + if( use_ret == -(POLARSSL_ERR_PK_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "PK - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_PK_FILE_IO_ERROR) ) + snprintf( buf, buflen, "PK - Read/write of file failed" ); + if( use_ret == -(POLARSSL_ERR_PK_KEY_INVALID_VERSION) ) + snprintf( buf, buflen, "PK - Unsupported key version" ); + if( use_ret == -(POLARSSL_ERR_PK_KEY_INVALID_FORMAT) ) + snprintf( buf, buflen, "PK - Invalid key tag or value" ); + if( use_ret == -(POLARSSL_ERR_PK_UNKNOWN_PK_ALG) ) + snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); + if( use_ret == -(POLARSSL_ERR_PK_PASSWORD_REQUIRED) ) + snprintf( buf, buflen, "PK - Private key password can't be empty" ); + if( use_ret == -(POLARSSL_ERR_PK_PASSWORD_MISMATCH) ) + snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" ); + if( use_ret == -(POLARSSL_ERR_PK_INVALID_PUBKEY) ) + snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); + if( use_ret == -(POLARSSL_ERR_PK_INVALID_ALG) ) + snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE) ) + snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); + if( use_ret == -(POLARSSL_ERR_PK_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); + if( use_ret == -(POLARSSL_ERR_PK_SIG_LEN_MISMATCH) ) + snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); +#endif /* POLARSSL_PK_C */ + +#if defined(POLARSSL_PKCS12_C) + if( use_ret == -(POLARSSL_ERR_PKCS12_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); + if( use_ret == -(POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT) ) + snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" ); + if( use_ret == -(POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH) ) + snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" ); +#endif /* POLARSSL_PKCS12_C */ + +#if defined(POLARSSL_PKCS5_C) + if( use_ret == -(POLARSSL_ERR_PKCS5_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_PKCS5_INVALID_FORMAT) ) + snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" ); + if( use_ret == -(POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" ); + if( use_ret == -(POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH) ) + snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" ); +#endif /* POLARSSL_PKCS5_C */ + +#if defined(POLARSSL_RSA_C) + if( use_ret == -(POLARSSL_ERR_RSA_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "RSA - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_RSA_INVALID_PADDING) ) + snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" ); + if( use_ret == -(POLARSSL_ERR_RSA_KEY_GEN_FAILED) ) + snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); + if( use_ret == -(POLARSSL_ERR_RSA_KEY_CHECK_FAILED) ) + snprintf( buf, buflen, "RSA - Key failed to pass the libraries validity check" ); + if( use_ret == -(POLARSSL_ERR_RSA_PUBLIC_FAILED) ) + snprintf( buf, buflen, "RSA - The public key operation failed" ); + if( use_ret == -(POLARSSL_ERR_RSA_PRIVATE_FAILED) ) + snprintf( buf, buflen, "RSA - The private key operation failed" ); + if( use_ret == -(POLARSSL_ERR_RSA_VERIFY_FAILED) ) + snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" ); + if( use_ret == -(POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE) ) + snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); + if( use_ret == -(POLARSSL_ERR_RSA_RNG_FAILED) ) + snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_SSL_TLS_C) + if( use_ret == -(POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "SSL - The requested feature is not available" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "SSL - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_SSL_INVALID_MAC) ) + snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_INVALID_RECORD) ) + snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); + if( use_ret == -(POLARSSL_ERR_SSL_CONN_EOF) ) + snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); + if( use_ret == -(POLARSSL_ERR_SSL_UNKNOWN_CIPHER) ) + snprintf( buf, buflen, "SSL - An unknown cipher was received" ); + if( use_ret == -(POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN) ) + snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); + if( use_ret == -(POLARSSL_ERR_SSL_NO_RNG) ) + snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); + if( use_ret == -(POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE) ) + snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); + if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE) ) + snprintf( buf, buflen, "SSL - DESCRIPTION MISSING" ); + if( use_ret == -(POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED) ) + snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); + if( use_ret == -(POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED) ) + snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); + if( use_ret == -(POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED) ) + snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); + if( use_ret == -(POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE) ) + snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); + if( use_ret == -(POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE) ) + { + snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); + return; + } + if( use_ret == -(POLARSSL_ERR_SSL_PEER_VERIFY_FAILED) ) + snprintf( buf, buflen, "SSL - Verification of our peer failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) ) + snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO) ) + snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO) ) + snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE) ) + snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) + snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) + snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) + snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) + snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) + snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) + snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) + snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) + snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_FINISHED) ) + snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_MALLOC_FAILED) ) + snprintf( buf, buflen, "SSL - Memory allocation failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FAILED) ) + snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); + if( use_ret == -(POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) + snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); + if( use_ret == -(POLARSSL_ERR_SSL_COMPRESSION_FAILED) ) + snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) + snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); + if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) + snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); + if( use_ret == -(POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED) ) + snprintf( buf, buflen, "SSL - Session ticket has expired" ); + if( use_ret == -(POLARSSL_ERR_SSL_PK_TYPE_MISMATCH) ) + snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); + if( use_ret == -(POLARSSL_ERR_SSL_UNKNOWN_IDENTITY) ) + snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); + if( use_ret == -(POLARSSL_ERR_SSL_INTERNAL_ERROR) ) + snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); + if( use_ret == -(POLARSSL_ERR_SSL_COUNTER_WRAPPING) ) + snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); +#endif /* POLARSSL_SSL_TLS_C */ + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) + if( use_ret == -(POLARSSL_ERR_X509_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); + if( use_ret == -(POLARSSL_ERR_X509_UNKNOWN_OID) ) + snprintf( buf, buflen, "X509 - Requested OID is unknown" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_FORMAT) ) + snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_VERSION) ) + snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_SERIAL) ) + snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_ALG) ) + snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_NAME) ) + snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_DATE) ) + snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_SIGNATURE) ) + snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_INVALID_EXTENSIONS) ) + snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_UNKNOWN_VERSION) ) + snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); + if( use_ret == -(POLARSSL_ERR_X509_UNKNOWN_SIG_ALG) ) + snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); + if( use_ret == -(POLARSSL_ERR_X509_SIG_MISMATCH) ) + snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::x509_crt sig_oid)" ); + if( use_ret == -(POLARSSL_ERR_X509_CERT_VERIFY_FAILED) ) + snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); + if( use_ret == -(POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT) ) + snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); + if( use_ret == -(POLARSSL_ERR_X509_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "X509 - Input invalid" ); + if( use_ret == -(POLARSSL_ERR_X509_MALLOC_FAILED) ) + snprintf( buf, buflen, "X509 - Allocation of memory failed" ); + if( use_ret == -(POLARSSL_ERR_X509_FILE_IO_ERROR) ) + snprintf( buf, buflen, "X509 - Read/write of file failed" ); +#endif /* POLARSSL_X509_USE,X509_CREATE_C */ + // END generated code + + if( strlen( buf ) == 0 ) + snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); + } + + use_ret = ret & ~0xFF80; + + if( use_ret == 0 ) + return; + + // If high level code is present, make a concatenation between both + // error strings. + // + len = strlen( buf ); + + if( len > 0 ) + { + if( buflen - len < 5 ) + return; + + snprintf( buf + len, buflen - len, " : " ); + + buf += len + 3; + buflen -= len + 3; + } + + // Low level error codes + // + // BEGIN generated code +#if defined(POLARSSL_AES_C) + if( use_ret == -(POLARSSL_ERR_AES_INVALID_KEY_LENGTH) ) + snprintf( buf, buflen, "AES - Invalid key length" ); + if( use_ret == -(POLARSSL_ERR_AES_INVALID_INPUT_LENGTH) ) + snprintf( buf, buflen, "AES - Invalid data input length" ); +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_ASN1_PARSE_C) + if( use_ret == -(POLARSSL_ERR_ASN1_OUT_OF_DATA) ) + snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); + if( use_ret == -(POLARSSL_ERR_ASN1_UNEXPECTED_TAG) ) + snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" ); + if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_LENGTH) ) + snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" ); + if( use_ret == -(POLARSSL_ERR_ASN1_LENGTH_MISMATCH) ) + snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" ); + if( use_ret == -(POLARSSL_ERR_ASN1_INVALID_DATA) ) + snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" ); + if( use_ret == -(POLARSSL_ERR_ASN1_MALLOC_FAILED) ) + snprintf( buf, buflen, "ASN1 - Memory allocation failed" ); + if( use_ret == -(POLARSSL_ERR_ASN1_BUF_TOO_SMALL) ) + snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" ); +#endif /* POLARSSL_ASN1_PARSE_C */ + +#if defined(POLARSSL_BASE64_C) + if( use_ret == -(POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL) ) + snprintf( buf, buflen, "BASE64 - Output buffer too small" ); + if( use_ret == -(POLARSSL_ERR_BASE64_INVALID_CHARACTER) ) + snprintf( buf, buflen, "BASE64 - Invalid character in input" ); +#endif /* POLARSSL_BASE64_C */ + +#if defined(POLARSSL_BIGNUM_C) + if( use_ret == -(POLARSSL_ERR_MPI_FILE_IO_ERROR) ) + snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" ); + if( use_ret == -(POLARSSL_ERR_MPI_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_MPI_INVALID_CHARACTER) ) + snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" ); + if( use_ret == -(POLARSSL_ERR_MPI_BUFFER_TOO_SMALL) ) + snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" ); + if( use_ret == -(POLARSSL_ERR_MPI_NEGATIVE_VALUE) ) + snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" ); + if( use_ret == -(POLARSSL_ERR_MPI_DIVISION_BY_ZERO) ) + snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" ); + if( use_ret == -(POLARSSL_ERR_MPI_NOT_ACCEPTABLE) ) + snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" ); + if( use_ret == -(POLARSSL_ERR_MPI_MALLOC_FAILED) ) + snprintf( buf, buflen, "BIGNUM - Memory allocation failed" ); +#endif /* POLARSSL_BIGNUM_C */ + +#if defined(POLARSSL_BLOWFISH_C) + if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_KEY_LENGTH) ) + snprintf( buf, buflen, "BLOWFISH - Invalid key length" ); + if( use_ret == -(POLARSSL_ERR_BLOWFISH_INVALID_INPUT_LENGTH) ) + snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); +#endif /* POLARSSL_BLOWFISH_C */ + +#if defined(POLARSSL_CAMELLIA_C) + if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_KEY_LENGTH) ) + snprintf( buf, buflen, "CAMELLIA - Invalid key length" ); + if( use_ret == -(POLARSSL_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) + snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_CCM_C) + if( use_ret == -(POLARSSL_ERR_CCM_BAD_INPUT) ) + snprintf( buf, buflen, "CCM - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_CCM_AUTH_FAILED) ) + snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); +#endif /* POLARSSL_CCM_C */ + +#if defined(POLARSSL_CTR_DRBG_C) + if( use_ret == -(POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) + snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); + if( use_ret == -(POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) + snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" ); + if( use_ret == -(POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG) ) + snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR) ) + snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" ); +#endif /* POLARSSL_CTR_DRBG_C */ + +#if defined(POLARSSL_DES_C) + if( use_ret == -(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH) ) + snprintf( buf, buflen, "DES - The data input has an invalid length" ); +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ENTROPY_C) + if( use_ret == -(POLARSSL_ERR_ENTROPY_SOURCE_FAILED) ) + snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_MAX_SOURCES) ) + snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_NO_SOURCES_DEFINED) ) + snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); + if( use_ret == -(POLARSSL_ERR_ENTROPY_FILE_IO_ERROR) ) + snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); +#endif /* POLARSSL_ENTROPY_C */ + +#if defined(POLARSSL_GCM_C) + if( use_ret == -(POLARSSL_ERR_GCM_AUTH_FAILED) ) + snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); + if( use_ret == -(POLARSSL_ERR_GCM_BAD_INPUT) ) + snprintf( buf, buflen, "GCM - Bad input parameters to function" ); +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_HMAC_DRBG_C) + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) + snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) + snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR) ) + snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); + if( use_ret == -(POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) + snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); +#endif /* POLARSSL_HMAC_DRBG_C */ + +#if defined(POLARSSL_MD2_C) + if( use_ret == -(POLARSSL_ERR_MD2_FILE_IO_ERROR) ) + snprintf( buf, buflen, "MD2 - Read/write error in file" ); +#endif /* POLARSSL_MD2_C */ + +#if defined(POLARSSL_MD4_C) + if( use_ret == -(POLARSSL_ERR_MD4_FILE_IO_ERROR) ) + snprintf( buf, buflen, "MD4 - Read/write error in file" ); +#endif /* POLARSSL_MD4_C */ + +#if defined(POLARSSL_MD5_C) + if( use_ret == -(POLARSSL_ERR_MD5_FILE_IO_ERROR) ) + snprintf( buf, buflen, "MD5 - Read/write error in file" ); +#endif /* POLARSSL_MD5_C */ + +#if defined(POLARSSL_NET_C) + if( use_ret == -(POLARSSL_ERR_NET_UNKNOWN_HOST) ) + snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); + if( use_ret == -(POLARSSL_ERR_NET_SOCKET_FAILED) ) + snprintf( buf, buflen, "NET - Failed to open a socket" ); + if( use_ret == -(POLARSSL_ERR_NET_CONNECT_FAILED) ) + snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); + if( use_ret == -(POLARSSL_ERR_NET_BIND_FAILED) ) + snprintf( buf, buflen, "NET - Binding of the socket failed" ); + if( use_ret == -(POLARSSL_ERR_NET_LISTEN_FAILED) ) + snprintf( buf, buflen, "NET - Could not listen on the socket" ); + if( use_ret == -(POLARSSL_ERR_NET_ACCEPT_FAILED) ) + snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); + if( use_ret == -(POLARSSL_ERR_NET_RECV_FAILED) ) + snprintf( buf, buflen, "NET - Reading information from the socket failed" ); + if( use_ret == -(POLARSSL_ERR_NET_SEND_FAILED) ) + snprintf( buf, buflen, "NET - Sending information through the socket failed" ); + if( use_ret == -(POLARSSL_ERR_NET_CONN_RESET) ) + snprintf( buf, buflen, "NET - Connection was reset by peer" ); + if( use_ret == -(POLARSSL_ERR_NET_WANT_READ) ) + snprintf( buf, buflen, "NET - Connection requires a read call" ); + if( use_ret == -(POLARSSL_ERR_NET_WANT_WRITE) ) + snprintf( buf, buflen, "NET - Connection requires a write call" ); +#endif /* POLARSSL_NET_C */ + +#if defined(POLARSSL_OID_C) + if( use_ret == -(POLARSSL_ERR_OID_NOT_FOUND) ) + snprintf( buf, buflen, "OID - OID is not found" ); + if( use_ret == -(POLARSSL_ERR_OID_BUF_TOO_SMALL) ) + snprintf( buf, buflen, "OID - output buffer is too small" ); +#endif /* POLARSSL_OID_C */ + +#if defined(POLARSSL_PADLOCK_C) + if( use_ret == -(POLARSSL_ERR_PADLOCK_DATA_MISALIGNED) ) + snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); +#endif /* POLARSSL_PADLOCK_C */ + +#if defined(POLARSSL_PBKDF2_C) + if( use_ret == -(POLARSSL_ERR_PBKDF2_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "PBKDF2 - Bad input parameters to function" ); +#endif /* POLARSSL_PBKDF2_C */ + +#if defined(POLARSSL_RIPEMD160_C) + if( use_ret == -(POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR) ) + snprintf( buf, buflen, "RIPEMD160 - Read/write error in file" ); +#endif /* POLARSSL_RIPEMD160_C */ + +#if defined(POLARSSL_SHA1_C) + if( use_ret == -(POLARSSL_ERR_SHA1_FILE_IO_ERROR) ) + snprintf( buf, buflen, "SHA1 - Read/write error in file" ); +#endif /* POLARSSL_SHA1_C */ + +#if defined(POLARSSL_SHA256_C) + if( use_ret == -(POLARSSL_ERR_SHA256_FILE_IO_ERROR) ) + snprintf( buf, buflen, "SHA256 - Read/write error in file" ); +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + if( use_ret == -(POLARSSL_ERR_SHA512_FILE_IO_ERROR) ) + snprintf( buf, buflen, "SHA512 - Read/write error in file" ); +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_THREADING_C) + if( use_ret == -(POLARSSL_ERR_THREADING_FEATURE_UNAVAILABLE) ) + snprintf( buf, buflen, "THREADING - The selected feature is not available" ); + if( use_ret == -(POLARSSL_ERR_THREADING_BAD_INPUT_DATA) ) + snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); + if( use_ret == -(POLARSSL_ERR_THREADING_MUTEX_ERROR) ) + snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); +#endif /* POLARSSL_THREADING_C */ + +#if defined(POLARSSL_XTEA_C) + if( use_ret == -(POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH) ) + snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); +#endif /* POLARSSL_XTEA_C */ + // END generated code + + if( strlen( buf ) != 0 ) + return; + + snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); +} + +#if defined(POLARSSL_ERROR_STRERROR_BC) +void error_strerror( int ret, char *buf, size_t buflen ) +{ + polarssl_strerror( ret, buf, buflen ); +} +#endif /* POLARSSL_ERROR_STRERROR_BC */ + +#else /* POLARSSL_ERROR_C */ + +#if defined(POLARSSL_ERROR_STRERROR_DUMMY) + +#include + +/* + * Provide an non-function in case POLARSSL_ERROR_C is not defined + */ +void polarssl_strerror( int ret, char *buf, size_t buflen ) +{ + ((void) ret); + + if( buflen > 0 ) + buf[0] = '\0'; +} + +#if defined(POLARSSL_ERROR_STRERROR_BC) +void error_strerror( int ret, char *buf, size_t buflen ) +{ + polarssl_strerror( ret, buf, buflen ); +} +#endif /* POLARSSL_ERROR_STRERROR_BC */ +#endif /* POLARSSL_ERROR_STRERROR_DUMMY */ + +#endif /* POLARSSL_ERROR_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/gcm.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/gcm.c new file mode 100644 index 0000000..77b1e0f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/gcm.c @@ -0,0 +1,948 @@ +/* + * NIST SP800-38D compliant GCM implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_GCM_C) + +#include "polarssl/gcm.h" + +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ +static int gcm_gen_table( gcm_context *ctx ) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + size_t olen = 0; + + memset( h, 0, 16 ); + if( ( ret = cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) + return( ret ); + + /* pack h as two 64-bits ints, big-endian */ + GET_UINT32_BE( hi, h, 0 ); + GET_UINT32_BE( lo, h, 4 ); + vh = (uint64_t) hi << 32 | lo; + + GET_UINT32_BE( hi, h, 8 ); + GET_UINT32_BE( lo, h, 12 ); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + /* With CLMUL support, we need only h, not the rest of the table */ + if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) + return( 0 ); +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for( i = 4; i > 0; i >>= 1 ) + { + uint32_t T = ( vl & 1 ) * 0xe1000000U; + vl = ( vh << 63 ) | ( vl >> 1 ); + vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for( i = 2; i < 16; i <<= 1 ) + { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for( j = 1; j < i; j++ ) + { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return( 0 ); +} + +int gcm_init( gcm_context *ctx, cipher_id_t cipher, const unsigned char *key, + unsigned int keysize ) +{ + int ret; + const cipher_info_t *cipher_info; + + memset( ctx, 0, sizeof(gcm_context) ); + + cipher_init( &ctx->cipher_ctx ); + + cipher_info = cipher_info_from_values( cipher, keysize, POLARSSL_MODE_ECB ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_GCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( POLARSSL_ERR_GCM_BAD_INPUT ); + + if( ( ret = cipher_init_ctx( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = cipher_setkey( &ctx->cipher_ctx, key, keysize, + POLARSSL_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = gcm_gen_table( ctx ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint64_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult( gcm_context *ctx, const unsigned char x[16], + unsigned char output[16] ) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_CLMUL ) ) { + unsigned char h[16]; + + PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + PUT_UINT32_BE( ctx->HH[8], h, 4 ); + PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + PUT_UINT32_BE( ctx->HL[8], h, 12 ); + + aesni_gcm_mult( output, x, h ); + return; + } +#endif /* POLARSSL_AESNI_C && POLARSSL_HAVE_X86_64 */ + + lo = x[15] & 0xf; + hi = x[15] >> 4; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for( i = 15; i >= 0; i-- ) + { + lo = x[i] & 0xf; + hi = x[i] >> 4; + + if( i != 15 ) + { + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + PUT_UINT32_BE( zh >> 32, output, 0 ); + PUT_UINT32_BE( zh, output, 4 ); + PUT_UINT32_BE( zl >> 32, output, 8 ); + PUT_UINT32_BE( zl, output, 12 ); +} + +int gcm_starts( gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ) +{ + int ret; + unsigned char work_buf[16]; + size_t i; + const unsigned char *p; + size_t use_len, olen = 0; + + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + if( ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( POLARSSL_ERR_GCM_BAD_INPUT ); + } + + memset( ctx->y, 0x00, sizeof(ctx->y) ); + memset( ctx->buf, 0x00, sizeof(ctx->buf) ); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if( iv_len == 12 ) + { + memcpy( ctx->y, iv, iv_len ); + ctx->y[15] = 1; + } + else + { + memset( work_buf, 0x00, 16 ); + PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + + p = iv; + while( iv_len > 0 ) + { + use_len = ( iv_len < 16 ) ? iv_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->y[i] ^= p[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + + iv_len -= use_len; + p += use_len; + } + + for( i = 0; i < 16; i++ ) + ctx->y[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + } + + if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + ctx->add_len = add_len; + p = add; + while( add_len > 0 ) + { + use_len = ( add_len < 16 ) ? add_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->buf[i] ^= p[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + add_len -= use_len; + p += use_len; + } + + return( 0 ); +} + +int gcm_update( gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char ectr[16]; + size_t i; + const unsigned char *p; + unsigned char *out_p = output; + size_t use_len, olen = 0; + + if( output > input && (size_t) ( output - input ) < length ) + return( POLARSSL_ERR_GCM_BAD_INPUT ); + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0x03FFFFE0llu ) + { + return( POLARSSL_ERR_GCM_BAD_INPUT ); + } + + ctx->len += length; + + p = input; + while( length > 0 ) + { + use_len = ( length < 16 ) ? length : 16; + + for( i = 16; i > 12; i-- ) + if( ++ctx->y[i - 1] != 0 ) + break; + + if( ( ret = cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + for( i = 0; i < use_len; i++ ) + { + if( ctx->mode == GCM_DECRYPT ) + ctx->buf[i] ^= p[i]; + out_p[i] = ectr[i] ^ p[i]; + if( ctx->mode == GCM_ENCRYPT ) + ctx->buf[i] ^= out_p[i]; + } + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + length -= use_len; + p += use_len; + out_p += use_len; + } + + return( 0 ); +} + +int gcm_finish( gcm_context *ctx, + unsigned char *tag, + size_t tag_len ) +{ + unsigned char work_buf[16]; + size_t i; + uint64_t orig_len = ctx->len * 8; + uint64_t orig_add_len = ctx->add_len * 8; + + if( tag_len > 16 || tag_len < 4 ) + return( POLARSSL_ERR_GCM_BAD_INPUT ); + + if( tag_len != 0 ) + memcpy( tag, ctx->base_ectr, tag_len ); + + if( orig_len || orig_add_len ) + { + memset( work_buf, 0x00, 16 ); + + PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + + for( i = 0; i < 16; i++ ) + ctx->buf[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + for( i = 0; i < tag_len; i++ ) + tag[i] ^= ctx->buf[i]; + } + + return( 0 ); +} + +int gcm_crypt_and_tag( gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ) +{ + int ret; + + if( ( ret = gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) + return( ret ); + + if( ( ret = gcm_update( ctx, length, input, output ) ) != 0 ) + return( ret ); + + if( ( ret = gcm_finish( ctx, tag, tag_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int gcm_auth_decrypt( gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char check_tag[16]; + size_t i; + int diff; + + if( ( ret = gcm_crypt_and_tag( ctx, GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + polarssl_zeroize( output, length ); + return( POLARSSL_ERR_GCM_AUTH_FAILED ); + } + + return( 0 ); +} + +void gcm_free( gcm_context *ctx ) +{ + cipher_free( &ctx->cipher_ctx ); + polarssl_zeroize( ctx, sizeof( gcm_context ) ); +} + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_AES_C) + +#include + +/* + * AES-GCM test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip + */ +#define MAX_TESTS 6 + +int key_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +unsigned char key[MAX_TESTS][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, +}; + +size_t iv_len[MAX_TESTS] = + { 12, 12, 12, 12, 8, 60 }; + +int iv_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 2 }; + +unsigned char iv[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b }, +}; + +size_t add_len[MAX_TESTS] = + { 0, 0, 0, 20, 20, 20 }; + +int add_index[MAX_TESTS] = + { 0, 0, 0, 1, 1, 1 }; + +unsigned char additional[MAX_TESTS][64] = +{ + { 0x00 }, + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 }, +}; + +size_t pt_len[MAX_TESTS] = + { 0, 16, 64, 60, 60, 60 }; + +int pt_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +unsigned char pt[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, +}; + +unsigned char ct[MAX_TESTS * 3][64] = +{ + { 0x00 }, + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 }, + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 }, + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 }, + { 0x00 }, + { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 }, + { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 }, + { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b }, + { 0x00 }, + { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 }, + { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f }, + { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f }, +}; + +unsigned char tag[MAX_TESTS * 3][16] = +{ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, + { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, + { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, + { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, + { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, + { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, + { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, + { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, + { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, + { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, + { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, + { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, + { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, +}; + +int gcm_self_test( int verbose ) +{ + gcm_context ctx; + unsigned char buf[64]; + unsigned char tag_buf[16]; + int i, j, ret; + cipher_id_t cipher = POLARSSL_CIPHER_ID_AES; + + for( j = 0; j < 3; j++ ) + { + int key_len = 128 + 64 * j; + + for( i = 0; i < MAX_TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "enc" ); + + gcm_init( &ctx, cipher, key[key_index[i]], key_len ); + + ret = gcm_crypt_and_tag( &ctx, GCM_ENCRYPT, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + pt[pt_index[i]], buf, 16, tag_buf ); + + if( ret != 0 || + memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + gcm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "dec" ); + + gcm_init( &ctx, cipher, key[key_index[i]], key_len ); + + ret = gcm_crypt_and_tag( &ctx, GCM_DECRYPT, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + ct[j * 6 + i], buf, 16, tag_buf ); + + if( ret != 0 || + memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + gcm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc" ); + + gcm_init( &ctx, cipher, key[key_index[i]], key_len ); + + ret = gcm_starts( &ctx, GCM_ENCRYPT, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = gcm_update( &ctx, 32, pt[pt_index[i]], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + ret = gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, + buf + 32 ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + ret = gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + ret = gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 || + memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + gcm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec" ); + + gcm_init( &ctx, cipher, key[key_index[i]], key_len ); + + ret = gcm_starts( &ctx, GCM_DECRYPT, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = gcm_update( &ctx, 32, ct[j * 6 + i], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + ret = gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, + buf + 32 ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + ret = gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + ret = gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 || + memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + gcm_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + } + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + + + +#endif /* POLARSSL_SELF_TEST && POLARSSL_AES_C */ + +#endif /* POLARSSL_GCM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/havege.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/havege.c new file mode 100644 index 0000000..3acd5bc --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/havege.c @@ -0,0 +1,247 @@ +/** + * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The HAVEGE RNG was designed by Andre Seznec in 2002. + * + * http://www.irisa.fr/caps/projects/hipsor/publi.php + * + * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_HAVEGE_C) + +#include "polarssl/havege.h" +#include "polarssl/timing.h" + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* ------------------------------------------------------------------------ + * On average, one iteration accesses two 8-word blocks in the havege WALK + * table, and generates 16 words in the RES array. + * + * The data read in the WALK table is updated and permuted after each use. + * The result of the hardware clock counter read is used for this update. + * + * 25 conditional tests are present. The conditional tests are grouped in + * two nested groups of 12 conditional tests and 1 test that controls the + * permutation; on average, there should be 6 tests executed and 3 of them + * should be mispredicted. + * ------------------------------------------------------------------------ + */ + +#define SWAP(X,Y) { int *T = X; X = Y; Y = T; } + +#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; +#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; + +#define TST1_LEAVE U1++; } +#define TST2_LEAVE U2++; } + +#define ONE_ITERATION \ + \ + PTEST = PT1 >> 20; \ + \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + \ + PTX = (PT1 >> 18) & 7; \ + PT1 &= 0x1FFF; \ + PT2 &= 0x1FFF; \ + CLK = (int) hardclock(); \ + \ + i = 0; \ + A = &WALK[PT1 ]; RES[i++] ^= *A; \ + B = &WALK[PT2 ]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \ + \ + IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \ + *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \ + *B = IN ^ U1; \ + *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \ + *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \ + \ + if( PTEST & 1 ) SWAP( A, C ); \ + \ + IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \ + *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \ + *B = IN; CLK = (int) hardclock(); \ + *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \ + *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 4]; \ + B = &WALK[PT2 ^ 1]; \ + \ + PTEST = PT2 >> 1; \ + \ + PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \ + PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \ + PTY = (PT2 >> 10) & 7; \ + \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + \ + C = &WALK[PT1 ^ 5]; \ + D = &WALK[PT2 ^ 5]; \ + \ + RES[i++] ^= *A; \ + RES[i++] ^= *B; \ + RES[i++] ^= *C; \ + RES[i++] ^= *D; \ + \ + IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \ + *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \ + *B = IN ^ U2; \ + *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \ + *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \ + \ + IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \ + *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \ + *B = IN; \ + *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ + *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ + \ + PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ + WALK[PT1 ^ PTX ^ 7] ) & (~1); \ + PT1 ^= (PT2 ^ 0x10) & 0x10; \ + \ + for( n++, i = 0; i < 16; i++ ) \ + hs->pool[n % COLLECT_SIZE] ^= RES[i]; + +/* + * Entropy gathering function + */ +static void havege_fill( havege_state *hs ) +{ + int i, n = 0; + int U1, U2, *A, *B, *C, *D; + int PT1, PT2, *WALK, RES[16]; + int PTX, PTY, CLK, PTEST, IN; + + WALK = hs->WALK; + PT1 = hs->PT1; + PT2 = hs->PT2; + + PTX = U1 = 0; + PTY = U2 = 0; + + memset( RES, 0, sizeof( RES ) ); + + while( n < COLLECT_SIZE * 4 ) + { + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + } + + hs->PT1 = PT1; + hs->PT2 = PT2; + + hs->offset[0] = 0; + hs->offset[1] = COLLECT_SIZE / 2; +} + +/* + * HAVEGE initialization + */ +void havege_init( havege_state *hs ) +{ + memset( hs, 0, sizeof( havege_state ) ); + + havege_fill( hs ); +} + +void havege_free( havege_state *hs ) +{ + if( hs == NULL ) + return; + + polarssl_zeroize( hs, sizeof( havege_state ) ); +} + +/* + * HAVEGE rand function + */ +int havege_random( void *p_rng, unsigned char *buf, size_t len ) +{ + int val; + size_t use_len; + havege_state *hs = (havege_state *) p_rng; + unsigned char *p = buf; + + while( len > 0 ) + { + use_len = len; + if( use_len > sizeof(int) ) + use_len = sizeof(int); + + if( hs->offset[1] >= COLLECT_SIZE ) + havege_fill( hs ); + + val = hs->pool[hs->offset[0]++]; + val ^= hs->pool[hs->offset[1]++]; + + memcpy( p, &val, use_len ); + + len -= use_len; + p += use_len; + } + + return( 0 ); +} + +#endif /* POLARSSL_HAVEGE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/hmac_drbg.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/hmac_drbg.c new file mode 100644 index 0000000..d691be1 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/hmac_drbg.c @@ -0,0 +1,502 @@ +/* + * HMAC_DRBG implementation (NIST SP 800-90) + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The NIST SP 800-90A DRBGs are described in the following publication. + * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + * References below are based on rev. 1 (January 2012). + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_HMAC_DRBG_C) + +#include "polarssl/hmac_drbg.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * HMAC_DRBG update, using optional additional data (10.1.2.2) + */ +void hmac_drbg_update( hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + size_t md_len = ctx->md_ctx.md_info->size; + unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; + unsigned char sep[1]; + unsigned char K[POLARSSL_MD_MAX_SIZE]; + + for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) + { + /* Step 1 or 4 */ + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_update( &ctx->md_ctx, sep, 1 ); + if( rounds == 2 ) + md_hmac_update( &ctx->md_ctx, additional, add_len ); + md_hmac_finish( &ctx->md_ctx, K ); + + /* Step 2 or 5 */ + md_hmac_starts( &ctx->md_ctx, K, md_len ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + } +} + +/* + * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) + */ +int hmac_drbg_init_buf( hmac_drbg_context *ctx, + const md_info_t * md_info, + const unsigned char *data, size_t data_len ) +{ + int ret; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + hmac_drbg_update( ctx, data, data_len ); + + return( 0 ); +} + +/* + * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) + */ +int hmac_drbg_reseed( hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT]; + size_t seedlen; + + /* III. Check input length */ + if( len > POLARSSL_HMAC_DRBG_MAX_INPUT || + ctx->entropy_len + len > POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ) + { + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ); + + /* IV. Gather entropy_len bytes of entropy for the seed */ + if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 ) + return( POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + + seedlen = ctx->entropy_len; + + /* 1. Concatenate entropy and additional data if any */ + if( additional != NULL && len != 0 ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* 2. Update state */ + hmac_drbg_update( ctx, seed, seedlen ); + + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; + + /* 4. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG initialisation (10.1.2.3 + 9.1) + */ +int hmac_drbg_init( hmac_drbg_context *ctx, + const md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + int ret; + size_t entropy_len; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->reseed_interval = POLARSSL_HMAC_DRBG_RESEED_INTERVAL; + + /* + * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by + * each hash function, then according to SP800-90A rev1 10.1 table 2, + * min_entropy_len (in bits) is security_strength. + * + * (This also matches the sizes used in the NIST test vectors.) + */ + entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ + + /* + * For initialisation, use more entropy to emulate a nonce + * (Again, matches test vectors.) + */ + ctx->entropy_len = entropy_len * 3 / 2; + + if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + ctx->entropy_len = entropy_len; + + return( 0 ); +} + +/* + * Set prediction resistance + */ +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +/* + * Set entropy length grabbed for reseeds + */ +void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +/* + * Set reseed interval + */ +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +/* + * HMAC_DRBG random function with optional additional data: + * 10.1.2.5 (arabic) + 9.3 (Roman) + */ +int hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t out_len, + const unsigned char *additional, size_t add_len ) +{ + int ret; + hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng; + size_t md_len = md_get_size( ctx->md_ctx.md_info ); + size_t left = out_len; + unsigned char *out = output; + + /* II. Check request length */ + if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST ) + return( POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); + + /* III. Check input length */ + if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT ) + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + + /* 1. (aka VII and IX) Check reseed counter and PR */ + if( ctx->f_entropy != NULL && /* For no-reseeding instances */ + ( ctx->prediction_resistance == POLARSSL_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) + { + if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; /* VII.4 */ + } + + /* 2. Use additional data if any */ + if( additional != NULL && add_len != 0 ) + hmac_drbg_update( ctx, additional, add_len ); + + /* 3, 4, 5. Generate bytes */ + while( left != 0 ) + { + size_t use_len = left > md_len ? md_len : left; + + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + + memcpy( out, ctx->V, use_len ); + out += use_len; + left -= use_len; + } + + /* 6. Update */ + hmac_drbg_update( ctx, additional, add_len ); + + /* 7. Update reseed counter */ + ctx->reseed_counter++; + + /* 8. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG random function + */ +int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) +{ + return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) ); +} + +/* + * Free an HMAC_DRBG context + */ +void hmac_drbg_free( hmac_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + md_free_ctx( &ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( hmac_drbg_context ) ); +} + +#if defined(POLARSSL_FS_IO) +int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + int ret; + FILE *f; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) + { + ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > POLARSSL_HMAC_DRBG_MAX_INPUT ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + hmac_drbg_update( ctx, buf, n ); + + return( hmac_drbg_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + + +#if defined(POLARSSL_SELF_TEST) + +#include + +#if !defined(POLARSSL_SHA1_C) +/* Dummy checkup routine */ +int hmac_drbg_self_test( int verbose ) +{ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int hmac_drbg_self_test( int verbose ) +{ + hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 ); + + /* + * PR = True + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_pr, + NULL, 0 ) ); + hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = False) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_nopr, + NULL, 0 ) ); + CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_HMAC_DRBG_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/md.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md.c new file mode 100644 index 0000000..7f9c5dc --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md.c @@ -0,0 +1,341 @@ +/** + * \file md.c + * + * \brief Generic message digest wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD_C) + +#include "polarssl/md.h" +#include "polarssl/md_wrap.h" + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +static const int supported_digests[] = { + +#if defined(POLARSSL_SHA512_C) + POLARSSL_MD_SHA384, + POLARSSL_MD_SHA512, +#endif + +#if defined(POLARSSL_SHA256_C) + POLARSSL_MD_SHA224, + POLARSSL_MD_SHA256, +#endif + +#if defined(POLARSSL_SHA1_C) + POLARSSL_MD_SHA1, +#endif + +#if defined(POLARSSL_RIPEMD160_C) + POLARSSL_MD_RIPEMD160, +#endif + +#if defined(POLARSSL_MD5_C) + POLARSSL_MD_MD5, +#endif + +#if defined(POLARSSL_MD4_C) + POLARSSL_MD_MD4, +#endif + +#if defined(POLARSSL_MD2_C) + POLARSSL_MD_MD2, +#endif + + POLARSSL_MD_NONE +}; + +const int *md_list( void ) +{ + return( supported_digests ); +} + +const md_info_t *md_info_from_string( const char *md_name ) +{ + if( NULL == md_name ) + return( NULL ); + + /* Get the appropriate digest information */ +#if defined(POLARSSL_MD2_C) + if( !strcasecmp( "MD2", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD2 ); +#endif +#if defined(POLARSSL_MD4_C) + if( !strcasecmp( "MD4", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD4 ); +#endif +#if defined(POLARSSL_MD5_C) + if( !strcasecmp( "MD5", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD5 ); +#endif +#if defined(POLARSSL_RIPEMD160_C) + if( !strcasecmp( "RIPEMD160", md_name ) ) + return md_info_from_type( POLARSSL_MD_RIPEMD160 ); +#endif +#if defined(POLARSSL_SHA1_C) + if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA1 ); +#endif +#if defined(POLARSSL_SHA256_C) + if( !strcasecmp( "SHA224", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA224 ); + if( !strcasecmp( "SHA256", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA256 ); +#endif +#if defined(POLARSSL_SHA512_C) + if( !strcasecmp( "SHA384", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA384 ); + if( !strcasecmp( "SHA512", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA512 ); +#endif + return( NULL ); +} + +const md_info_t *md_info_from_type( md_type_t md_type ) +{ + switch( md_type ) + { +#if defined(POLARSSL_MD2_C) + case POLARSSL_MD_MD2: + return( &md2_info ); +#endif +#if defined(POLARSSL_MD4_C) + case POLARSSL_MD_MD4: + return( &md4_info ); +#endif +#if defined(POLARSSL_MD5_C) + case POLARSSL_MD_MD5: + return( &md5_info ); +#endif +#if defined(POLARSSL_RIPEMD160_C) + case POLARSSL_MD_RIPEMD160: + return( &ripemd160_info ); +#endif +#if defined(POLARSSL_SHA1_C) + case POLARSSL_MD_SHA1: + return( &sha1_info ); +#endif +#if defined(POLARSSL_SHA256_C) + case POLARSSL_MD_SHA224: + return( &sha224_info ); + case POLARSSL_MD_SHA256: + return( &sha256_info ); +#endif +#if defined(POLARSSL_SHA512_C) + case POLARSSL_MD_SHA384: + return( &sha384_info ); + case POLARSSL_MD_SHA512: + return( &sha512_info ); +#endif + default: + return( NULL ); + } +} + +void md_init( md_context_t *ctx ) +{ + memset( ctx, 0, sizeof( md_context_t ) ); +} + +void md_free( md_context_t *ctx ) +{ + if( ctx == NULL ) + return; + + if( ctx->md_ctx ) + ctx->md_info->ctx_free_func( ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( md_context_t ) ); +} + +int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ) +{ + if( md_info == NULL || ctx == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( md_context_t ) ); + + if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_MD_ALLOC_FAILED ); + + ctx->md_info = md_info; + + md_info->starts_func( ctx->md_ctx ); + + return( 0 ); +} + +int md_free_ctx( md_context_t *ctx ) +{ + md_free( ctx ); + + return( 0 ); +} + +int md_starts( md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->starts_func( ctx->md_ctx ); + + return( 0 ); +} + +int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +int md_finish( md_context_t *ctx, unsigned char *output ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +int md( const md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + md_info->digest_func( input, ilen, output ); + + return( 0 ); +} + +int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + int ret; +#endif + + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + +#if defined(POLARSSL_FS_IO) + ret = md_info->file_func( path, output ); + if( ret != 0 ) + return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret ); + + return( ret ); +#else + ((void) path); + ((void) output); + + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_FS_IO */ +} + +int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen ); + + return( 0 ); +} + +int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +int md_hmac_finish( md_context_t *ctx, unsigned char *output ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +int md_hmac_reset( md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_reset_func( ctx->md_ctx ); + + return( 0 ); +} + +int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + md_info->hmac_func( key, keylen, input, ilen, output ); + + return( 0 ); +} + +int md_process( md_context_t *ctx, const unsigned char *data ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->process_func( ctx->md_ctx, data ); + + return( 0 ); +} + +#endif /* POLARSSL_MD_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/md2.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md2.c new file mode 100644 index 0000000..45bce37 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md2.c @@ -0,0 +1,398 @@ +/* + * RFC 1115/1319 compliant MD2 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD2 algorithm was designed by Ron Rivest in 1989. + * + * http://www.ietf.org/rfc/rfc1115.txt + * http://www.ietf.org/rfc/rfc1319.txt + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD2_C) + +#include "polarssl/md2.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_MD2_ALT) + +static const unsigned char PI_SUBST[256] = +{ + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, + 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, + 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, + 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, + 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, + 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, + 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, + 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, + 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, + 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, + 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, + 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, + 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, + 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, + 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, + 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, + 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, + 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, + 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, + 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, + 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, + 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, + 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + +void md2_init( md2_context *ctx ) +{ + memset( ctx, 0, sizeof( md2_context ) ); +} + +void md2_free( md2_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md2_context ) ); +} + +/* + * MD2 context setup + */ +void md2_starts( md2_context *ctx ) +{ + memset( ctx->cksum, 0, 16 ); + memset( ctx->state, 0, 46 ); + memset( ctx->buffer, 0, 16 ); + ctx->left = 0; +} + +void md2_process( md2_context *ctx ) +{ + int i, j; + unsigned char t = 0; + + for( i = 0; i < 16; i++ ) + { + ctx->state[i + 16] = ctx->buffer[i]; + ctx->state[i + 32] = + (unsigned char)( ctx->buffer[i] ^ ctx->state[i]); + } + + for( i = 0; i < 18; i++ ) + { + for( j = 0; j < 48; j++ ) + { + ctx->state[j] = (unsigned char) + ( ctx->state[j] ^ PI_SUBST[t] ); + t = ctx->state[j]; + } + + t = (unsigned char)( t + i ); + } + + t = ctx->cksum[15]; + + for( i = 0; i < 16; i++ ) + { + ctx->cksum[i] = (unsigned char) + ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); + t = ctx->cksum[i]; + } +} + +/* + * MD2 process buffer + */ +void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + + while( ilen > 0 ) + { + if( ctx->left + ilen > 16 ) + fill = 16 - ctx->left; + else + fill = ilen; + + memcpy( ctx->buffer + ctx->left, input, fill ); + + ctx->left += fill; + input += fill; + ilen -= fill; + + if( ctx->left == 16 ) + { + ctx->left = 0; + md2_process( ctx ); + } + } +} + +/* + * MD2 final digest + */ +void md2_finish( md2_context *ctx, unsigned char output[16] ) +{ + size_t i; + unsigned char x; + + x = (unsigned char)( 16 - ctx->left ); + + for( i = ctx->left; i < 16; i++ ) + ctx->buffer[i] = x; + + md2_process( ctx ); + + memcpy( ctx->buffer, ctx->cksum, 16 ); + md2_process( ctx ); + + memcpy( output, ctx->state, 16 ); +} + +#endif /* !POLARSSL_MD2_ALT */ + +/* + * output = MD2( input buffer ) + */ +void md2( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md2_context ctx; + + md2_init( &ctx ); + md2_starts( &ctx ); + md2_update( &ctx, input, ilen ); + md2_finish( &ctx, output ); + md2_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = MD2( file contents ) + */ +int md2_file( const char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md2_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_MD2_FILE_IO_ERROR ); + + md2_init( &ctx ); + md2_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md2_update( &ctx, buf, n ); + + md2_finish( &ctx, output ); + md2_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_MD2_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * MD2 HMAC context setup + */ +void md2_hmac_starts( md2_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[16]; + + if( keylen > 16 ) + { + md2( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 16 ); + memset( ctx->opad, 0x5C, 16 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md2_starts( ctx ); + md2_update( ctx, ctx->ipad, 16 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * MD2 HMAC process buffer + */ +void md2_hmac_update( md2_context *ctx, const unsigned char *input, + size_t ilen ) +{ + md2_update( ctx, input, ilen ); +} + +/* + * MD2 HMAC final digest + */ +void md2_hmac_finish( md2_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md2_finish( ctx, tmpbuf ); + md2_starts( ctx ); + md2_update( ctx, ctx->opad, 16 ); + md2_update( ctx, tmpbuf, 16 ); + md2_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * MD2 HMAC context reset + */ +void md2_hmac_reset( md2_context *ctx ) +{ + md2_starts( ctx ); + md2_update( ctx, ctx->ipad, 16 ); +} + +/* + * output = HMAC-MD2( hmac key, input buffer ) + */ +void md2_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ) +{ + md2_context ctx; + + md2_init( &ctx ); + md2_hmac_starts( &ctx, key, keylen ); + md2_hmac_update( &ctx, input, ilen ); + md2_hmac_finish( &ctx, output ); + md2_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * RFC 1319 test vectors + */ +static const char md2_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const unsigned char md2_test_sum[7][16] = +{ + { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, + 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 }, + { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72, + 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 }, + { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B, + 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB }, + { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B, + 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 }, + { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB, + 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B }, + { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39, + 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD }, + { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D, + 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 } +}; + +/* + * Checkup routine + */ +int md2_self_test( int verbose ) +{ + int i; + unsigned char md2sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " MD2 test #%d: ", i + 1 ); + + md2( (unsigned char *) md2_test_str[i], + strlen( md2_test_str[i] ), md2sum ); + + if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_MD2_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/md4.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md4.c new file mode 100644 index 0000000..f6b71d5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md4.c @@ -0,0 +1,494 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD4_C) + +#include "polarssl/md4.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_MD4_ALT) + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +void md4_init( md4_context *ctx ) +{ + memset( ctx, 0, sizeof( md4_context ) ); +} + +void md4_free( md4_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md4_context ) ); +} + +/* + * MD4 context setup + */ +void md4_starts( md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +void md4_process( md4_context *ctx, const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD4 process buffer + */ +void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + md4_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md4_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md4_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD4 final digest + */ +void md4_finish( md4_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md4_update( ctx, (unsigned char *) md4_padding, padn ); + md4_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); +} + +#endif /* !POLARSSL_MD4_ALT */ + +/* + * output = MD4( input buffer ) + */ +void md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md4_context ctx; + + md4_init( &ctx ); + md4_starts( &ctx ); + md4_update( &ctx, input, ilen ); + md4_finish( &ctx, output ); + md4_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = MD4( file contents ) + */ +int md4_file( const char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md4_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); + + md4_init( &ctx ); + md4_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md4_update( &ctx, buf, n ); + + md4_finish( &ctx, output ); + md4_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_MD4_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * MD4 HMAC context setup + */ +void md4_hmac_starts( md4_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md4( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md4_starts( ctx ); + md4_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * MD4 HMAC process buffer + */ +void md4_hmac_update( md4_context *ctx, const unsigned char *input, + size_t ilen ) +{ + md4_update( ctx, input, ilen ); +} + +/* + * MD4 HMAC final digest + */ +void md4_hmac_finish( md4_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md4_finish( ctx, tmpbuf ); + md4_starts( ctx ); + md4_update( ctx, ctx->opad, 64 ); + md4_update( ctx, tmpbuf, 16 ); + md4_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * MD4 HMAC context reset + */ +void md4_hmac_reset( md4_context *ctx ) +{ + md4_starts( ctx ); + md4_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-MD4( hmac key, input buffer ) + */ +void md4_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ) +{ + md4_context ctx; + + md4_init( &ctx ); + md4_hmac_starts( &ctx, key, keylen ); + md4_hmac_update( &ctx, input, ilen ); + md4_hmac_finish( &ctx, output ); + md4_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * RFC 1320 test vectors + */ +static const char md4_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const unsigned char md4_test_sum[7][16] = +{ + { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, + 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, + { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, + 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, + { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, + 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, + { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, + 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, + { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, + 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, + { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, + 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, + { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, + 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } +}; + +/* + * Checkup routine + */ +int md4_self_test( int verbose ) +{ + int i; + unsigned char md4sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " MD4 test #%d: ", i + 1 ); + + md4( (unsigned char *) md4_test_str[i], + strlen( md4_test_str[i] ), md4sum ); + + if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_MD4_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/md5.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md5.c new file mode 100644 index 0000000..89354bc --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md5.c @@ -0,0 +1,615 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD5_C) + +#include "polarssl/md5.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_MD5_ALT) + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +void md5_init( md5_context *ctx ) +{ + memset( ctx, 0, sizeof( md5_context ) ); +} + +void md5_free( md5_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md5_context ) ); +} + +/* + * MD5 context setup + */ +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +void md5_process( md5_context *ctx, const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); +} + +#endif /* !POLARSSL_MD5_ALT */ + +/* + * output = MD5( input buffer ) + */ +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_init( &ctx ); + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); + md5_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = MD5( file contents ) + */ +int md5_file( const char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md5_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); + + md5_init( &ctx ); + md5_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md5_update( &ctx, buf, n ); + + md5_finish( &ctx, output ); + md5_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * MD5 HMAC context setup + */ +void md5_hmac_starts( md5_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md5( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * MD5 HMAC process buffer + */ +void md5_hmac_update( md5_context *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_update( ctx, input, ilen ); +} + +/* + * MD5 HMAC final digest + */ +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md5_finish( ctx, tmpbuf ); + md5_starts( ctx ); + md5_update( ctx, ctx->opad, 64 ); + md5_update( ctx, tmpbuf, 16 ); + md5_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * MD5 HMAC context reset + */ +void md5_hmac_reset( md5_context *ctx ) +{ + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-MD5( hmac key, input buffer ) + */ +void md5_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ) +{ + md5_context ctx; + + md5_init( &ctx ); + md5_hmac_starts( &ctx, key, keylen ); + md5_hmac_update( &ctx, input, ilen ); + md5_hmac_finish( &ctx, output ); + md5_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * RFC 1321 test vectors + */ +static unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char md5_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int md5_hmac_test_keylen[7] = +{ + 16, 4, 16, 25, 16, 80, 80 +}; + +static unsigned char md5_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int md5_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char md5_hmac_test_sum[7][16] = +{ + { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, + 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, + { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, + 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, + { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, + 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, + { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, + 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, + { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, + 0xF9, 0xBA, 0xB9, 0x95 }, + { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, + 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, + { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, + 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } +}; + +/* + * Checkup routine + */ +int md5_self_test( int verbose ) +{ + int i, buflen; + unsigned char buf[1024]; + unsigned char md5sum[16]; + md5_context ctx; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " MD5 test #%d: ", i + 1 ); + + md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + md5_hmac_starts( &ctx, buf, buflen ); + } + else + md5_hmac_starts( &ctx, md5_hmac_test_key[i], + md5_hmac_test_keylen[i] ); + + md5_hmac_update( &ctx, md5_hmac_test_buf[i], + md5_hmac_test_buflen[i] ); + + md5_hmac_finish( &ctx, md5sum ); + + buflen = ( i == 4 ) ? 12 : 16; + + if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_MD5_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/md_wrap.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md_wrap.c new file mode 100644 index 0000000..de701d3 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/md_wrap.c @@ -0,0 +1,955 @@ +/** + * \file md_wrap.c + + * \brief Generic message digest wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD_C) + +#include "polarssl/md_wrap.h" + +#if defined(POLARSSL_MD2_C) +#include "polarssl/md2.h" +#endif + +#if defined(POLARSSL_MD4_C) +#include "polarssl/md4.h" +#endif + +#if defined(POLARSSL_MD5_C) +#include "polarssl/md5.h" +#endif + +#if defined(POLARSSL_RIPEMD160_C) +#include "polarssl/ripemd160.h" +#endif + +#if defined(POLARSSL_SHA1_C) +#include "polarssl/sha1.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#include "polarssl/sha256.h" +#endif + +#if defined(POLARSSL_SHA512_C) +#include "polarssl/sha512.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_MD2_C) + +static void md2_starts_wrap( void *ctx ) +{ + md2_starts( (md2_context *) ctx ); +} + +static void md2_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md2_update( (md2_context *) ctx, input, ilen ); +} + +static void md2_finish_wrap( void *ctx, unsigned char *output ) +{ + md2_finish( (md2_context *) ctx, output ); +} + +static int md2_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md2_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md2_hmac_starts( (md2_context *) ctx, key, keylen ); +} + +static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md2_hmac_update( (md2_context *) ctx, input, ilen ); +} + +static void md2_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md2_hmac_finish( (md2_context *) ctx, output ); +} + +static void md2_hmac_reset_wrap( void *ctx ) +{ + md2_hmac_reset( (md2_context *) ctx ); +} + +static void * md2_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md2_context ) ); +} + +static void md2_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md2_context ) ); + polarssl_free( ctx ); +} + +static void md2_process_wrap( void *ctx, const unsigned char *data ) +{ + ((void) data); + + md2_process( (md2_context *) ctx ); +} + +const md_info_t md2_info = { + POLARSSL_MD_MD2, + "MD2", + 16, + md2_starts_wrap, + md2_update_wrap, + md2_finish_wrap, + md2, + md2_file_wrap, + md2_hmac_starts_wrap, + md2_hmac_update_wrap, + md2_hmac_finish_wrap, + md2_hmac_reset_wrap, + md2_hmac, + md2_ctx_alloc, + md2_ctx_free, + md2_process_wrap, +}; + +#endif /* POLARSSL_MD2_C */ + +#if defined(POLARSSL_MD4_C) + +static void md4_starts_wrap( void *ctx ) +{ + md4_starts( (md4_context *) ctx ); +} + +static void md4_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md4_update( (md4_context *) ctx, input, ilen ); +} + +static void md4_finish_wrap( void *ctx, unsigned char *output ) +{ + md4_finish( (md4_context *) ctx, output ); +} + +static int md4_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md4_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md4_hmac_starts( (md4_context *) ctx, key, keylen ); +} + +static void md4_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md4_hmac_update( (md4_context *) ctx, input, ilen ); +} + +static void md4_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md4_hmac_finish( (md4_context *) ctx, output ); +} + +static void md4_hmac_reset_wrap( void *ctx ) +{ + md4_hmac_reset( (md4_context *) ctx ); +} + +static void *md4_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md4_context ) ); +} + +static void md4_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md4_context ) ); + polarssl_free( ctx ); +} + +static void md4_process_wrap( void *ctx, const unsigned char *data ) +{ + md4_process( (md4_context *) ctx, data ); +} + +const md_info_t md4_info = { + POLARSSL_MD_MD4, + "MD4", + 16, + md4_starts_wrap, + md4_update_wrap, + md4_finish_wrap, + md4, + md4_file_wrap, + md4_hmac_starts_wrap, + md4_hmac_update_wrap, + md4_hmac_finish_wrap, + md4_hmac_reset_wrap, + md4_hmac, + md4_ctx_alloc, + md4_ctx_free, + md4_process_wrap, +}; + +#endif /* POLARSSL_MD4_C */ + +#if defined(POLARSSL_MD5_C) + +static void md5_starts_wrap( void *ctx ) +{ + md5_starts( (md5_context *) ctx ); +} + +static void md5_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_update( (md5_context *) ctx, input, ilen ); +} + +static void md5_finish_wrap( void *ctx, unsigned char *output ) +{ + md5_finish( (md5_context *) ctx, output ); +} + +static int md5_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md5_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md5_hmac_starts( (md5_context *) ctx, key, keylen ); +} + +static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_hmac_update( (md5_context *) ctx, input, ilen ); +} + +static void md5_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md5_hmac_finish( (md5_context *) ctx, output ); +} + +static void md5_hmac_reset_wrap( void *ctx ) +{ + md5_hmac_reset( (md5_context *) ctx ); +} + +static void * md5_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md5_context ) ); +} + +static void md5_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md5_context ) ); + polarssl_free( ctx ); +} + +static void md5_process_wrap( void *ctx, const unsigned char *data ) +{ + md5_process( (md5_context *) ctx, data ); +} + +const md_info_t md5_info = { + POLARSSL_MD_MD5, + "MD5", + 16, + md5_starts_wrap, + md5_update_wrap, + md5_finish_wrap, + md5, + md5_file_wrap, + md5_hmac_starts_wrap, + md5_hmac_update_wrap, + md5_hmac_finish_wrap, + md5_hmac_reset_wrap, + md5_hmac, + md5_ctx_alloc, + md5_ctx_free, + md5_process_wrap, +}; + +#endif /* POLARSSL_MD5_C */ + +#if defined(POLARSSL_RIPEMD160_C) + +static void ripemd160_starts_wrap( void *ctx ) +{ + ripemd160_starts( (ripemd160_context *) ctx ); +} + +static void ripemd160_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_update( (ripemd160_context *) ctx, input, ilen ); +} + +static void ripemd160_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_finish( (ripemd160_context *) ctx, output ); +} + +static int ripemd160_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return ripemd160_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void ripemd160_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + ripemd160_hmac_starts( (ripemd160_context *) ctx, key, keylen ); +} + +static void ripemd160_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_hmac_update( (ripemd160_context *) ctx, input, ilen ); +} + +static void ripemd160_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_hmac_finish( (ripemd160_context *) ctx, output ); +} + +static void ripemd160_hmac_reset_wrap( void *ctx ) +{ + ripemd160_hmac_reset( (ripemd160_context *) ctx ); +} + +static void * ripemd160_ctx_alloc( void ) +{ + ripemd160_context *ctx; + ctx = (ripemd160_context *) polarssl_malloc( sizeof( ripemd160_context ) ); + + if( ctx == NULL ) + return( NULL ); + + ripemd160_init( ctx ); + + return( ctx ); +} + +static void ripemd160_ctx_free( void *ctx ) +{ + ripemd160_free( (ripemd160_context *) ctx ); + polarssl_free( ctx ); +} + +static void ripemd160_process_wrap( void *ctx, const unsigned char *data ) +{ + ripemd160_process( (ripemd160_context *) ctx, data ); +} + +const md_info_t ripemd160_info = { + POLARSSL_MD_RIPEMD160, + "RIPEMD160", + 20, + ripemd160_starts_wrap, + ripemd160_update_wrap, + ripemd160_finish_wrap, + ripemd160, + ripemd160_file_wrap, + ripemd160_hmac_starts_wrap, + ripemd160_hmac_update_wrap, + ripemd160_hmac_finish_wrap, + ripemd160_hmac_reset_wrap, + ripemd160_hmac, + ripemd160_ctx_alloc, + ripemd160_ctx_free, + ripemd160_process_wrap, +}; + +#endif /* POLARSSL_RIPEMD160_C */ + +#if defined(POLARSSL_SHA1_C) + +static void sha1_starts_wrap( void *ctx ) +{ + sha1_starts( (sha1_context *) ctx ); +} + +static void sha1_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_update( (sha1_context *) ctx, input, ilen ); +} + +static void sha1_finish_wrap( void *ctx, unsigned char *output ) +{ + sha1_finish( (sha1_context *) ctx, output ); +} + +static int sha1_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha1_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha1_hmac_starts( (sha1_context *) ctx, key, keylen ); +} + +static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_hmac_update( (sha1_context *) ctx, input, ilen ); +} + +static void sha1_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha1_hmac_finish( (sha1_context *) ctx, output ); +} + +static void sha1_hmac_reset_wrap( void *ctx ) +{ + sha1_hmac_reset( (sha1_context *) ctx ); +} + +static void * sha1_ctx_alloc( void ) +{ + sha1_context *ctx; + ctx = (sha1_context *) polarssl_malloc( sizeof( sha1_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha1_init( ctx ); + + return( ctx ); +} + +static void sha1_ctx_free( void *ctx ) +{ + sha1_free( (sha1_context *) ctx ); + polarssl_free( ctx ); +} + +static void sha1_process_wrap( void *ctx, const unsigned char *data ) +{ + sha1_process( (sha1_context *) ctx, data ); +} + +const md_info_t sha1_info = { + POLARSSL_MD_SHA1, + "SHA1", + 20, + sha1_starts_wrap, + sha1_update_wrap, + sha1_finish_wrap, + sha1, + sha1_file_wrap, + sha1_hmac_starts_wrap, + sha1_hmac_update_wrap, + sha1_hmac_finish_wrap, + sha1_hmac_reset_wrap, + sha1_hmac, + sha1_ctx_alloc, + sha1_ctx_free, + sha1_process_wrap, +}; + +#endif /* POLARSSL_SHA1_C */ + +/* + * Wrappers for generic message digests + */ +#if defined(POLARSSL_SHA256_C) + +static void sha224_starts_wrap( void *ctx ) +{ + sha256_starts( (sha256_context *) ctx, 1 ); +} + +static void sha224_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( (sha256_context *) ctx, input, ilen ); +} + +static void sha224_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_finish( (sha256_context *) ctx, output ); +} + +static void sha224_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256( input, ilen, output, 1 ); +} + +static int sha224_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha256_file( path, output, 1 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 1 ); +} + +static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_hmac_update( (sha256_context *) ctx, input, ilen ); +} + +static void sha224_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_hmac_finish( (sha256_context *) ctx, output ); +} + +static void sha224_hmac_reset_wrap( void *ctx ) +{ + sha256_hmac_reset( (sha256_context *) ctx ); +} + +static void sha224_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256_hmac( key, keylen, input, ilen, output, 1 ); +} + +static void * sha224_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( sha256_context ) ); +} + +static void sha224_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( sha256_context ) ); + polarssl_free( ctx ); +} + +static void sha224_process_wrap( void *ctx, const unsigned char *data ) +{ + sha256_process( (sha256_context *) ctx, data ); +} + +const md_info_t sha224_info = { + POLARSSL_MD_SHA224, + "SHA224", + 28, + sha224_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha224_wrap, + sha224_file_wrap, + sha224_hmac_starts_wrap, + sha224_hmac_update_wrap, + sha224_hmac_finish_wrap, + sha224_hmac_reset_wrap, + sha224_hmac_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_process_wrap, +}; + +static void sha256_starts_wrap( void *ctx ) +{ + sha256_starts( (sha256_context *) ctx, 0 ); +} + +static void sha256_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( (sha256_context *) ctx, input, ilen ); +} + +static void sha256_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_finish( (sha256_context *) ctx, output ); +} + +static void sha256_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256( input, ilen, output, 0 ); +} + +static int sha256_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha256_file( path, output, 0 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 0 ); +} + +static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_hmac_update( (sha256_context *) ctx, input, ilen ); +} + +static void sha256_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_hmac_finish( (sha256_context *) ctx, output ); +} + +static void sha256_hmac_reset_wrap( void *ctx ) +{ + sha256_hmac_reset( (sha256_context *) ctx ); +} + +static void sha256_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256_hmac( key, keylen, input, ilen, output, 0 ); +} + +static void * sha256_ctx_alloc( void ) +{ + sha256_context *ctx; + ctx = (sha256_context *) polarssl_malloc( sizeof( sha256_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha256_init( ctx ); + + return( ctx ); +} + +static void sha256_ctx_free( void *ctx ) +{ + sha256_free( (sha256_context *) ctx ); + polarssl_free( ctx ); +} + +static void sha256_process_wrap( void *ctx, const unsigned char *data ) +{ + sha256_process( (sha256_context *) ctx, data ); +} + +const md_info_t sha256_info = { + POLARSSL_MD_SHA256, + "SHA256", + 32, + sha256_starts_wrap, + sha256_update_wrap, + sha256_finish_wrap, + sha256_wrap, + sha256_file_wrap, + sha256_hmac_starts_wrap, + sha256_hmac_update_wrap, + sha256_hmac_finish_wrap, + sha256_hmac_reset_wrap, + sha256_hmac_wrap, + sha256_ctx_alloc, + sha256_ctx_free, + sha256_process_wrap, +}; + +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + +static void sha384_starts_wrap( void *ctx ) +{ + sha512_starts( (sha512_context *) ctx, 1 ); +} + +static void sha384_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_update( (sha512_context *) ctx, input, ilen ); +} + +static void sha384_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_finish( (sha512_context *) ctx, output ); +} + +static void sha384_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512( input, ilen, output, 1 ); +} + +static int sha384_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha512_file( path, output, 1 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 1 ); +} + +static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_hmac_update( (sha512_context *) ctx, input, ilen ); +} + +static void sha384_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_hmac_finish( (sha512_context *) ctx, output ); +} + +static void sha384_hmac_reset_wrap( void *ctx ) +{ + sha512_hmac_reset( (sha512_context *) ctx ); +} + +static void sha384_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512_hmac( key, keylen, input, ilen, output, 1 ); +} + +static void * sha384_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( sha512_context ) ); +} + +static void sha384_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( sha512_context ) ); + polarssl_free( ctx ); +} + +static void sha384_process_wrap( void *ctx, const unsigned char *data ) +{ + sha512_process( (sha512_context *) ctx, data ); +} + +const md_info_t sha384_info = { + POLARSSL_MD_SHA384, + "SHA384", + 48, + sha384_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha384_wrap, + sha384_file_wrap, + sha384_hmac_starts_wrap, + sha384_hmac_update_wrap, + sha384_hmac_finish_wrap, + sha384_hmac_reset_wrap, + sha384_hmac_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_process_wrap, +}; + +static void sha512_starts_wrap( void *ctx ) +{ + sha512_starts( (sha512_context *) ctx, 0 ); +} + +static void sha512_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_update( (sha512_context *) ctx, input, ilen ); +} + +static void sha512_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_finish( (sha512_context *) ctx, output ); +} + +static void sha512_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512( input, ilen, output, 0 ); +} + +static int sha512_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha512_file( path, output, 0 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 0 ); +} + +static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_hmac_update( (sha512_context *) ctx, input, ilen ); +} + +static void sha512_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_hmac_finish( (sha512_context *) ctx, output ); +} + +static void sha512_hmac_reset_wrap( void *ctx ) +{ + sha512_hmac_reset( (sha512_context *) ctx ); +} + +static void sha512_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512_hmac( key, keylen, input, ilen, output, 0 ); +} + +static void * sha512_ctx_alloc( void ) +{ + sha512_context *ctx; + ctx = (sha512_context *) polarssl_malloc( sizeof( sha512_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha512_init( ctx ); + + return( ctx ); +} + +static void sha512_ctx_free( void *ctx ) +{ + sha512_free( (sha512_context *) ctx ); + polarssl_free( ctx ); +} + +static void sha512_process_wrap( void *ctx, const unsigned char *data ) +{ + sha512_process( (sha512_context *) ctx, data ); +} + +const md_info_t sha512_info = { + POLARSSL_MD_SHA512, + "SHA512", + 64, + sha512_starts_wrap, + sha512_update_wrap, + sha512_finish_wrap, + sha512_wrap, + sha512_file_wrap, + sha512_hmac_starts_wrap, + sha512_hmac_update_wrap, + sha512_hmac_finish_wrap, + sha512_hmac_reset_wrap, + sha512_hmac_wrap, + sha512_ctx_alloc, + sha512_ctx_free, + sha512_process_wrap, +}; + +#endif /* POLARSSL_SHA512_C */ + +#endif /* POLARSSL_MD_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/memory_buffer_alloc.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/memory_buffer_alloc.c new file mode 100644 index 0000000..7710ba5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/memory_buffer_alloc.c @@ -0,0 +1,589 @@ +/* + * Buffer-based memory allocator + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) + +#include "polarssl/memory_buffer_alloc.h" + +#include + +#if defined(POLARSSL_MEMORY_DEBUG) +#include +#if defined(POLARSSL_MEMORY_BACKTRACE) +#include +#endif +#endif + +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_fprintf fprintf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define MAGIC1 0xFF00AA55 +#define MAGIC2 0xEE119966 +#define MAX_BT 20 + +typedef struct _memory_header memory_header; +struct _memory_header +{ + size_t magic1; + size_t size; + size_t alloc; + memory_header *prev; + memory_header *next; + memory_header *prev_free; + memory_header *next_free; +#if defined(POLARSSL_MEMORY_BACKTRACE) + char **trace; + size_t trace_count; +#endif + size_t magic2; +}; + +typedef struct +{ + unsigned char *buf; + size_t len; + memory_header *first; + memory_header *first_free; + size_t current_alloc_size; + int verify; +#if defined(POLARSSL_MEMORY_DEBUG) + size_t malloc_count; + size_t free_count; + size_t total_used; + size_t maximum_used; + size_t header_count; + size_t maximum_header_count; +#endif +#if defined(POLARSSL_THREADING_C) + threading_mutex_t mutex; +#endif +} +buffer_alloc_ctx; + +static buffer_alloc_ctx heap; + +#if defined(POLARSSL_MEMORY_DEBUG) +static void debug_header( memory_header *hdr ) +{ +#if defined(POLARSSL_MEMORY_BACKTRACE) + size_t i; +#endif + + polarssl_fprintf( stderr, "HDR: PTR(%10u), PREV(%10u), NEXT(%10u), " + "ALLOC(%u), SIZE(%10u)\n", + (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, + hdr->alloc, hdr->size ); + polarssl_fprintf( stderr, " FPREV(%10u), FNEXT(%10u)\n", + (size_t) hdr->prev_free, (size_t) hdr->next_free ); + +#if defined(POLARSSL_MEMORY_BACKTRACE) + polarssl_fprintf( stderr, "TRACE: \n" ); + for( i = 0; i < hdr->trace_count; i++ ) + polarssl_fprintf( stderr, "%s\n", hdr->trace[i] ); + polarssl_fprintf( stderr, "\n" ); +#endif +} + +static void debug_chain() +{ + memory_header *cur = heap.first; + + polarssl_fprintf( stderr, "\nBlock list\n" ); + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next; + } + + polarssl_fprintf( stderr, "Free list\n" ); + cur = heap.first_free; + + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next_free; + } +} +#endif /* POLARSSL_MEMORY_DEBUG */ + +static int verify_header( memory_header *hdr ) +{ + if( hdr->magic1 != MAGIC1 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->magic2 != MAGIC2 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->alloc > 1 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: alloc has illegal value\n" ); +#endif + return( 1 ); + } + + if( hdr->prev != NULL && hdr->prev == hdr->next ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: prev == next\n" ); +#endif + return( 1 ); + } + + if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: prev_free == next_free\n" ); +#endif + return( 1 ); + } + + return( 0 ); +} + +static int verify_chain() +{ + memory_header *prv = heap.first, *cur = heap.first->next; + + if( verify_header( heap.first ) != 0 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: verification of first header " + "failed\n" ); +#endif + return( 1 ); + } + + if( heap.first->prev != NULL ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: verification failed: " + "first->prev != NULL\n" ); +#endif + return( 1 ); + } + + while( cur != NULL ) + { + if( verify_header( cur ) != 0 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: verification of header " + "failed\n" ); +#endif + return( 1 ); + } + + if( cur->prev != prv ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: verification failed: " + "cur->prev != prv\n" ); +#endif + return( 1 ); + } + + prv = cur; + cur = cur->next; + } + + return( 0 ); +} + +static void *buffer_alloc_malloc( size_t len ) +{ + memory_header *new, *cur = heap.first_free; + unsigned char *p; +#if defined(POLARSSL_MEMORY_BACKTRACE) + void *trace_buffer[MAX_BT]; + size_t trace_cnt; +#endif + + if( heap.buf == NULL || heap.first == NULL ) + return( NULL ); + + if( len % POLARSSL_MEMORY_ALIGN_MULTIPLE ) + { + len -= len % POLARSSL_MEMORY_ALIGN_MULTIPLE; + len += POLARSSL_MEMORY_ALIGN_MULTIPLE; + } + + // Find block that fits + // + while( cur != NULL ) + { + if( cur->size >= len ) + break; + + cur = cur->next_free; + } + + if( cur == NULL ) + return( NULL ); + + if( cur->alloc != 0 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: block in free_list but allocated " + "data\n" ); +#endif + exit( 1 ); + } + +#if defined(POLARSSL_MEMORY_DEBUG) + heap.malloc_count++; +#endif + + // Found location, split block if > memory_header + 4 room left + // + if( cur->size - len < sizeof(memory_header) + + POLARSSL_MEMORY_ALIGN_MULTIPLE ) + { + cur->alloc = 1; + + // Remove from free_list + // + if( cur->prev_free != NULL ) + cur->prev_free->next_free = cur->next_free; + else + heap.first_free = cur->next_free; + + if( cur->next_free != NULL ) + cur->next_free->prev_free = cur->prev_free; + + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(POLARSSL_MEMORY_DEBUG) + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(POLARSSL_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + exit( 1 ); + + return( ( (unsigned char *) cur ) + sizeof(memory_header) ); + } + + p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; + new = (memory_header *) p; + + new->size = cur->size - len - sizeof(memory_header); + new->alloc = 0; + new->prev = cur; + new->next = cur->next; +#if defined(POLARSSL_MEMORY_BACKTRACE) + new->trace = NULL; + new->trace_count = 0; +#endif + new->magic1 = MAGIC1; + new->magic2 = MAGIC2; + + if( new->next != NULL ) + new->next->prev = new; + + // Replace cur with new in free_list + // + new->prev_free = cur->prev_free; + new->next_free = cur->next_free; + if( new->prev_free != NULL ) + new->prev_free->next_free = new; + else + heap.first_free = new; + + if( new->next_free != NULL ) + new->next_free->prev_free = new; + + cur->alloc = 1; + cur->size = len; + cur->next = new; + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(POLARSSL_MEMORY_DEBUG) + heap.header_count++; + if( heap.header_count > heap.maximum_header_count ) + heap.maximum_header_count = heap.header_count; + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(POLARSSL_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + exit( 1 ); + + return( ( (unsigned char *) cur ) + sizeof(memory_header) ); +} + +static void buffer_alloc_free( void *ptr ) +{ + memory_header *hdr, *old = NULL; + unsigned char *p = (unsigned char *) ptr; + + if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) + return; + + if( p < heap.buf || p > heap.buf + heap.len ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: polarssl_free() outside of managed " + "space\n" ); +#endif + exit( 1 ); + } + + p -= sizeof(memory_header); + hdr = (memory_header *) p; + + if( verify_header( hdr ) != 0 ) + exit( 1 ); + + if( hdr->alloc != 1 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + polarssl_fprintf( stderr, "FATAL: polarssl_free() on unallocated " + "data\n" ); +#endif + exit( 1 ); + } + + hdr->alloc = 0; + +#if defined(POLARSSL_MEMORY_DEBUG) + heap.free_count++; + heap.total_used -= hdr->size; +#endif + + // Regroup with block before + // + if( hdr->prev != NULL && hdr->prev->alloc == 0 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->prev->size += sizeof(memory_header) + hdr->size; + hdr->prev->next = hdr->next; + old = hdr; + hdr = hdr->prev; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + +#if defined(POLARSSL_MEMORY_BACKTRACE) + free( old->trace ); +#endif + memset( old, 0, sizeof(memory_header) ); + } + + // Regroup with block after + // + if( hdr->next != NULL && hdr->next->alloc == 0 ) + { +#if defined(POLARSSL_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->size += sizeof(memory_header) + hdr->next->size; + old = hdr->next; + hdr->next = hdr->next->next; + + if( hdr->prev_free != NULL || hdr->next_free != NULL ) + { + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr->next_free; + else + heap.first_free = hdr->next_free; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr->prev_free; + } + + hdr->prev_free = old->prev_free; + hdr->next_free = old->next_free; + + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr; + else + heap.first_free = hdr; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + +#if defined(POLARSSL_MEMORY_BACKTRACE) + free( old->trace ); +#endif + memset( old, 0, sizeof(memory_header) ); + } + + // Prepend to free_list if we have not merged + // (Does not have to stay in same order as prev / next list) + // + if( old == NULL ) + { + hdr->next_free = heap.first_free; + heap.first_free->prev_free = hdr; + heap.first_free = hdr; + } + +#if defined(POLARSSL_MEMORY_BACKTRACE) + hdr->trace = NULL; + hdr->trace_count = 0; +#endif + + if( ( heap.verify & MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) + exit( 1 ); +} + +void memory_buffer_set_verify( int verify ) +{ + heap.verify = verify; +} + +int memory_buffer_alloc_verify() +{ + return verify_chain(); +} + +#if defined(POLARSSL_MEMORY_DEBUG) +void memory_buffer_alloc_status() +{ + polarssl_fprintf( stderr, + "Current use: %u blocks / %u bytes, max: %u blocks / " + "%u bytes (total %u bytes), malloc / free: %u / %u\n", + heap.header_count, heap.total_used, + heap.maximum_header_count, heap.maximum_used, + heap.maximum_header_count * sizeof( memory_header ) + + heap.maximum_used, + heap.malloc_count, heap.free_count ); + + if( heap.first->next == NULL ) + polarssl_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); + else + { + polarssl_fprintf( stderr, "Memory currently allocated:\n" ); + debug_chain(); + } +} +#endif /* POLARSSL_MEMORY_DEBUG */ + +#if defined(POLARSSL_THREADING_C) +static void *buffer_alloc_malloc_mutexed( size_t len ) +{ + void *buf; + polarssl_mutex_lock( &heap.mutex ); + buf = buffer_alloc_malloc( len ); + polarssl_mutex_unlock( &heap.mutex ); + return( buf ); +} + +static void buffer_alloc_free_mutexed( void *ptr ) +{ + polarssl_mutex_lock( &heap.mutex ); + buffer_alloc_free( ptr ); + polarssl_mutex_unlock( &heap.mutex ); +} +#endif /* POLARSSL_THREADING_C */ + +int memory_buffer_alloc_init( unsigned char *buf, size_t len ) +{ + memset( &heap, 0, sizeof(buffer_alloc_ctx) ); + memset( buf, 0, len ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &heap.mutex ); + platform_set_malloc_free( buffer_alloc_malloc_mutexed, + buffer_alloc_free_mutexed ); +#else + platform_set_malloc_free( buffer_alloc_malloc, buffer_alloc_free ); +#endif + + if( (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE ) + { + buf += POLARSSL_MEMORY_ALIGN_MULTIPLE + - (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE; + len -= (size_t) buf % POLARSSL_MEMORY_ALIGN_MULTIPLE; + } + + heap.buf = buf; + heap.len = len; + + heap.first = (memory_header *) buf; + heap.first->size = len - sizeof(memory_header); + heap.first->magic1 = MAGIC1; + heap.first->magic2 = MAGIC2; + heap.first_free = heap.first; + return( 0 ); +} + +void memory_buffer_alloc_free() +{ +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &heap.mutex ); +#endif + polarssl_zeroize( &heap, sizeof(buffer_alloc_ctx) ); +} + +#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/net.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/net.c new file mode 100644 index 0000000..540ff2c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/net.c @@ -0,0 +1,602 @@ +/* + * TCP networking functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_NET_C) + +#include "polarssl/net.h" + +#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ + !defined(EFI32) + +#if defined(POLARSSL_HAVE_IPV6) +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +/* Enables getaddrinfo() & Co */ +#define _WIN32_WINNT 0x0501 +#include +#endif + +#include +#include + +#if defined(_MSC_VER) +#if defined(_WIN32_WCE) +#pragma comment( lib, "ws2.lib" ) +#else +#pragma comment( lib, "ws2_32.lib" ) +#endif +#endif /* _MSC_VER */ + +#define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0) +#define write(fd,buf,len) send(fd,(char*)buf,(int) len,0) +#define close(fd) closesocket(fd) + +static int wsa_init_done = 0; + +#elif defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) + +#include "lwip/sockets.h" +#include "lwip/inet.h" +#if LWIP_DNS +#include "lwip/netdb.h" +#endif +#include + +#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +#include +#include +#include +#include +#if defined(POLARSSL_HAVE_TIME) +#include +#endif +#include +#include +#include +#include +#include + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \ + defined(__DragonFly__) +#include +#elif defined(__APPLE__) || defined(HAVE_MACHINE_ENDIAN_H) || \ + defined(EFIX64) || defined(EFI32) +#include +#elif defined(sun) +#include +#elif defined(_AIX) || defined(HAVE_ARPA_NAMESER_COMPAT_H) +#include +#else +#include +#endif + +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +#include +#include + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#define snprintf _snprintf +#endif + +#if defined(POLARSSL_HAVE_TIME) +#include +#endif + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#if LWIP_SOCKET + +/* + * htons() is not always available. + * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and + * __BIG_ENDIAN to help determine endianness. + */ +#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ + __BYTE_ORDER == __BIG_ENDIAN +#define POLARSSL_HTONS(n) (n) +#define POLARSSL_HTONL(n) (n) +#else +#define POLARSSL_HTONS(n) ((((unsigned short)(n) & 0xFF ) << 8 ) | \ + (((unsigned short)(n) & 0xFF00 ) >> 8 )) +#define POLARSSL_HTONL(n) ((((unsigned long )(n) & 0xFF ) << 24) | \ + (((unsigned long )(n) & 0xFF00 ) << 8 ) | \ + (((unsigned long )(n) & 0xFF0000 ) >> 8 ) | \ + (((unsigned long )(n) & 0xFF000000) >> 24)) +#endif + +unsigned short net_htons( unsigned short n ); +unsigned long net_htonl( unsigned long n ); +#define net_htons(n) POLARSSL_HTONS(n) +#define net_htonl(n) POLARSSL_HTONL(n) + +/* + * Prepare for using the sockets interface + */ +static int net_prepare( void ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + WSADATA wsaData; + + if( wsa_init_done == 0 ) + { + if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) + return( POLARSSL_ERR_NET_SOCKET_FAILED ); + + wsa_init_done = 1; + } +#else +#if !defined(EFIX64) && !defined(EFI32) && !defined(__ICCARM__) && !defined(__CC_ARM) && !defined(__GNUC__) + signal( SIGPIPE, SIG_IGN ); +#endif +#endif + return( 0 ); +} + +/* + * Initiate a TCP connection with host:port + */ +int net_connect( int *fd, const char *host, int port ) +{ +#if defined(POLARSSL_HAVE_IPV6) + int ret; + struct addrinfo hints, *addr_list, *cur; + char port_str[6]; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* getaddrinfo expects port as a string */ + memset( port_str, 0, sizeof( port_str ) ); + snprintf( port_str, sizeof( port_str ), "%d", port ); + + /* Do name resolution with both IPv6 and IPv4, but only TCP */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + if( getaddrinfo( host, port_str, &hints, &addr_list ) != 0 ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a connection succeeds */ + ret = POLARSSL_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + *fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( *fd < 0 ) + { + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + if( connect( *fd, cur->ai_addr, cur->ai_addrlen ) == 0 ) + { + ret = 0; + break; + } + + close( *fd ); + ret = POLARSSL_ERR_NET_CONNECT_FAILED; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +#else + /* Legacy IPv4-only version */ + + int ret; + struct sockaddr_in server_addr; +#if LWIP_DNS + struct hostent *server_host; +#endif + if( ( ret = net_prepare() ) != 0 ) + return( ret ); +#if LWIP_DNS + if( ( server_host = gethostbyname( host ) ) == NULL ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); + + if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) + return( POLARSSL_ERR_NET_SOCKET_FAILED ); + + memcpy( (void *) &server_addr.sin_addr, + (void *) server_host->h_addr, + server_host->h_length ); +#else + if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) + return( POLARSSL_ERR_NET_SOCKET_FAILED ); + + server_addr.sin_len = sizeof(server_addr); + server_addr.sin_addr.s_addr = inet_addr(host); +#endif + + server_addr.sin_family = AF_INET; + server_addr.sin_port = net_htons( port ); + + if( connect( *fd, (struct sockaddr *) &server_addr, + sizeof( server_addr ) ) < 0 ) + { + close( *fd ); + return( POLARSSL_ERR_NET_CONNECT_FAILED ); + } + + return( 0 ); +#endif /* POLARSSL_HAVE_IPV6 */ +} + +/* + * Create a listening socket on bind_ip:port + */ +int net_bind( int *fd, const char *bind_ip, int port ) +{ +#if defined(POLARSSL_HAVE_IPV6) + int n, ret; + struct addrinfo hints, *addr_list, *cur; + char port_str[6]; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* getaddrinfo expects port as a string */ + memset( port_str, 0, sizeof( port_str ) ); + snprintf( port_str, sizeof( port_str ), "%d", port ); + + /* Bind to IPv6 and/or IPv4, but only in TCP */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if( bind_ip == NULL ) + hints.ai_flags = AI_PASSIVE; + + if( getaddrinfo( bind_ip, port_str, &hints, &addr_list ) != 0 ) + return( POLARSSL_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a binding succeeds */ + ret = POLARSSL_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + *fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( *fd < 0 ) + { + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + n = 1; + if( setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( *fd, cur->ai_addr, cur->ai_addrlen ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_BIND_FAILED; + continue; + } + + if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) + { + close( *fd ); + ret = POLARSSL_ERR_NET_LISTEN_FAILED; + continue; + } + + /* I we ever get there, it's a success */ + ret = 0; + break; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +#else + /* Legacy IPv4-only version */ + + int ret, n, c[4]; + struct sockaddr_in server_addr; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) + return( POLARSSL_ERR_NET_SOCKET_FAILED ); + + n = 1; + setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ); + + server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY ); + server_addr.sin_family = AF_INET; + server_addr.sin_port = net_htons( port ); + + if( bind_ip != NULL ) + { + memset( c, 0, sizeof( c ) ); + sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] ); + + for( n = 0; n < 4; n++ ) + if( c[n] < 0 || c[n] > 255 ) + break; + + if( n == 4 ) + server_addr.sin_addr.s_addr = net_htonl( + ( (uint32_t) c[0] << 24 ) | + ( (uint32_t) c[1] << 16 ) | + ( (uint32_t) c[2] << 8 ) | + ( (uint32_t) c[3] ) ); + } + + if( bind( *fd, (struct sockaddr *) &server_addr, + sizeof( server_addr ) ) < 0 ) + { + close( *fd ); + return( POLARSSL_ERR_NET_BIND_FAILED ); + } + + if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 ) + { + close( *fd ); + return( POLARSSL_ERR_NET_LISTEN_FAILED ); + } + + return( 0 ); +#endif /* POLARSSL_HAVE_IPV6 */ +} + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + */ +static int net_would_block( int fd ) +{ + ((void) fd); + return( WSAGetLastError() == WSAEWOULDBLOCK ); +} +#else +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + * + * Note: on a blocking socket this function always returns 0! + */ +static int net_would_block( int fd ) +{ +#if 0 + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + if( ( fcntl( fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) + return( 0 ); + + switch( errno ) + { +#if defined EAGAIN + case EAGAIN: +#endif +#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return( 1 ); + } +#endif + return( 0 ); +} +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* + * Accept a connection from a remote client + */ +int net_accept( int bind_fd, int *client_fd, void *client_ip ) +{ +#if defined(POLARSSL_HAVE_IPV6) + struct sockaddr_storage client_addr; +#else + struct sockaddr_in client_addr; +#endif + +#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ + defined(_SOCKLEN_T_DECLARED) + socklen_t n = (socklen_t) sizeof( client_addr ); +#else + int n = (int) sizeof( client_addr ); +#endif + + *client_fd = (int) accept( bind_fd, (struct sockaddr *) + &client_addr, &n ); + + if( *client_fd < 0 ) + { + if( net_would_block( *client_fd ) != 0 ) + return( POLARSSL_ERR_NET_WANT_READ ); + + return( POLARSSL_ERR_NET_ACCEPT_FAILED ); + } + + if( client_ip != NULL ) + { +#if defined(POLARSSL_HAVE_IPV6) + if( client_addr.ss_family == AF_INET ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + memcpy( client_ip, &addr4->sin_addr.s_addr, + sizeof( addr4->sin_addr.s_addr ) ); + } + else + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; + memcpy( client_ip, &addr6->sin6_addr.s6_addr, + sizeof( addr6->sin6_addr.s6_addr ) ); + } +#else + memcpy( client_ip, &client_addr.sin_addr.s_addr, + sizeof( client_addr.sin_addr.s_addr ) ); +#endif /* POLARSSL_HAVE_IPV6 */ + } + + return( 0 ); +} + +/* + * Set the socket blocking or non-blocking + */ +int net_set_block( int fd ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) || defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)) && !defined(EFIX64) && \ + !defined(EFI32) + unsigned long n = 0; + return( ioctlsocket( fd, FIONBIO, &n ) ); +#else + return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) ); +#endif +} + +int net_set_nonblock( int fd ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) || defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)) && !defined(EFIX64) && \ + !defined(EFI32) + unsigned long n = 1; + return( ioctlsocket( fd, FIONBIO, &n ) ); +#else + return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) ); +#endif +} + +#if defined(POLARSSL_HAVE_TIME) +/* + * Portable usleep helper + */ +void net_usleep( unsigned long usec ) +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = usec; + select( 0, NULL, NULL, NULL, &tv ); +} +#endif /* POLARSSL_HAVE_TIME */ + +/* + * Read at most 'len' characters + */ +int net_recv( void *ctx, unsigned char *buf, size_t len ) +{ + int fd = *((int *) ctx); + int ret = read( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( fd ) != 0 ) + return( POLARSSL_ERR_NET_WANT_READ ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( POLARSSL_ERR_NET_CONN_RESET ); +#else +#ifdef ERRNO + if( errno == EPIPE || errno == ECONNRESET ) + return( POLARSSL_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( POLARSSL_ERR_NET_WANT_READ ); +#endif +#endif + + return( POLARSSL_ERR_NET_RECV_FAILED ); + } + + return( ret ); +} + +/* + * Write at most 'len' characters + */ +int net_send( void *ctx, const unsigned char *buf, size_t len ) +{ + int fd = *((int *) ctx); + int ret = write( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( fd ) != 0 ) + return( POLARSSL_ERR_NET_WANT_WRITE ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( POLARSSL_ERR_NET_CONN_RESET ); +#else +#ifdef ERRNO + if( errno == EPIPE || errno == ECONNRESET ) + return( POLARSSL_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( POLARSSL_ERR_NET_WANT_WRITE ); +#endif +#endif + + return( POLARSSL_ERR_NET_SEND_FAILED ); + } + + return( ret ); +} + +/* + * Gracefully close the connection + */ +void net_close( int fd ) +{ + shutdown( fd, 2 ); + close( fd ); +} +#endif // LWIP_SOCKET + +#endif /* POLARSSL_NET_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/oid.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/oid.c new file mode 100644 index 0000000..f0afafe --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/oid.c @@ -0,0 +1,684 @@ +/** + * \file oid.c + * + * \brief Object Identifier (OID) database + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_OID_C) + +#include "polarssl/oid.h" +#include "polarssl/rsa.h" + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +#include "polarssl/x509.h" +#endif + +#include + +/* + * Macro to automatically add the size of #define'd OIDs + */ +#define ADD_LEN(s) s, OID_SIZE(s) + +/* + * Macro to generate an internal function for oid_XXX_from_asn1() (used by + * the other functions) + */ +#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ +static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid ) \ +{ \ + const TYPE_T *p = LIST; \ + const oid_descriptor_t *cur = (const oid_descriptor_t *) p; \ + if( p == NULL || oid == NULL ) return( NULL ); \ + while( cur->asn1 != NULL ) { \ + if( cur->asn1_len == oid->len && \ + memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ + return( p ); \ + } \ + p++; \ + cur = (const oid_descriptor_t *) p; \ + } \ + return( NULL ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from the + * descriptor of an oid_descriptor_t wrapper. + */ +#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->descriptor.ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from an + * oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving two attributes from an + * oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + *ATTR2 = data->ATTR2; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on a single + * attribute from a oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ +int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( POLARSSL_ERR_OID_NOT_FOUND ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on two + * attributes from a oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ + size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( POLARSSL_ERR_OID_NOT_FOUND ); \ +} + +/* + * For X520 attribute types + */ +typedef struct { + oid_descriptor_t descriptor; + const char *short_name; +} oid_x520_attr_t; + +static const oid_x520_attr_t oid_x520_attr_type[] = +{ + { + { ADD_LEN( OID_AT_CN ), "id-at-commonName", "Common Name" }, + "CN", + }, + { + { ADD_LEN( OID_AT_COUNTRY ), "id-at-countryName", "Country" }, + "C", + }, + { + { ADD_LEN( OID_AT_LOCALITY ), "id-at-locality", "Locality" }, + "L", + }, + { + { ADD_LEN( OID_AT_STATE ), "id-at-state", "State" }, + "ST", + }, + { + { ADD_LEN( OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, + "O", + }, + { + { ADD_LEN( OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, + "OU", + }, + { + { ADD_LEN( OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, + "emailAddress", + }, + { + { ADD_LEN( OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, + "serialNumber", + }, + { + { ADD_LEN( OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, + "postalAddress", + }, + { + { ADD_LEN( OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, + "postalCode", + }, + { + { ADD_LEN( OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, + "SN", + }, + { + { ADD_LEN( OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, + "GN", + }, + { + { ADD_LEN( OID_AT_INITIALS ), "id-at-initials", "Initials" }, + "initials", + }, + { + { ADD_LEN( OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, + "generationQualifier", + }, + { + { ADD_LEN( OID_AT_TITLE ), "id-at-title", "Title" }, + "title", + }, + { + { ADD_LEN( OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, + "dnQualifier", + }, + { + { ADD_LEN( OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, + "pseudonym", + }, + { + { ADD_LEN( OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, + "DC", + }, + { + { NULL, 0, NULL, NULL }, + NULL, + } +}; + +FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type); +FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name); + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +/* + * For X509 extensions + */ +typedef struct { + oid_descriptor_t descriptor; + int ext_type; +} oid_x509_ext_t; + +static const oid_x509_ext_t oid_x509_ext[] = +{ + { + { ADD_LEN( OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, + EXT_BASIC_CONSTRAINTS, + }, + { + { ADD_LEN( OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, + EXT_KEY_USAGE, + }, + { + { ADD_LEN( OID_EXTENDED_KEY_USAGE ), "id-ce-keyUsage", "Extended Key Usage" }, + EXT_EXTENDED_KEY_USAGE, + }, + { + { ADD_LEN( OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, + EXT_SUBJECT_ALT_NAME, + }, + { + { ADD_LEN( OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, + EXT_NS_CERT_TYPE, + }, + { + { NULL, 0, NULL, NULL }, + 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext); +FN_OID_GET_ATTR1(oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type); + +static const oid_descriptor_t oid_ext_key_usage[] = +{ + { ADD_LEN( OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, + { ADD_LEN( OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, + { ADD_LEN( OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, + { ADD_LEN( OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, + { ADD_LEN( OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, + { ADD_LEN( OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, + { NULL, 0, NULL, NULL }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage); +FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description); +#endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */ + +#if defined(POLARSSL_MD_C) +/* + * For SignatureAlgorithmIdentifier + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; + pk_type_t pk_alg; +} oid_sig_alg_t; + +static const oid_sig_alg_t oid_sig_alg[] = +{ + { + { ADD_LEN( OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, + POLARSSL_MD_MD2, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, + POLARSSL_MD_MD4, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, + POLARSSL_MD_MD5, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, + POLARSSL_MD_SHA224, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, + POLARSSL_MD_SHA256, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, + POLARSSL_MD_SHA384, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, + POLARSSL_MD_SHA512, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, + POLARSSL_MD_SHA224, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, + POLARSSL_MD_SHA256, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, + POLARSSL_MD_SHA384, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, + POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, + POLARSSL_MD_NONE, POLARSSL_PK_RSASSA_PSS, + }, + { + { NULL, 0, NULL, NULL }, + (md_type_t)0, (pk_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg); +FN_OID_GET_DESCRIPTOR_ATTR1(oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description); +FN_OID_GET_ATTR2(oid_get_sig_alg, oid_sig_alg_t, sig_alg, md_type_t, md_alg, pk_type_t, pk_alg); +FN_OID_GET_OID_BY_ATTR2(oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, pk_type_t, pk_alg, md_type_t, md_alg); +#endif /* POLARSSL_MD_C */ + +/* + * For PublicKeyInfo (PKCS1, RFC 5480) + */ +typedef struct { + oid_descriptor_t descriptor; + pk_type_t pk_alg; +} oid_pk_alg_t; + +static const oid_pk_alg_t oid_pk_alg[] = +{ + { + { ADD_LEN( OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, + POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, + POLARSSL_PK_ECKEY, + }, + { + { ADD_LEN( OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, + POLARSSL_PK_ECKEY_DH, + }, + { + { NULL, 0, NULL, NULL }, + (pk_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg); +FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, pk_type_t, pk_alg); + +#if defined(POLARSSL_ECP_C) +/* + * For namedCurve (RFC 5480) + */ +typedef struct { + oid_descriptor_t descriptor; + ecp_group_id grp_id; +} oid_ecp_grp_t; + +static const oid_ecp_grp_t oid_ecp_grp[] = +{ + { + { ADD_LEN( OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, + POLARSSL_ECP_DP_SECP192R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, + POLARSSL_ECP_DP_SECP224R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, + POLARSSL_ECP_DP_SECP256R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, + POLARSSL_ECP_DP_SECP384R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, + POLARSSL_ECP_DP_SECP521R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, + POLARSSL_ECP_DP_SECP192K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, + POLARSSL_ECP_DP_SECP224K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, + POLARSSL_ECP_DP_SECP256K1, + }, + { + { ADD_LEN( OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, + POLARSSL_ECP_DP_BP256R1, + }, + { + { ADD_LEN( OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, + POLARSSL_ECP_DP_BP384R1, + }, + { + { ADD_LEN( OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, + POLARSSL_ECP_DP_BP512R1, + }, + { + { NULL, 0, NULL, NULL }, + 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp); +FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, ecp_group_id, grp_id); +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_CIPHER_C) +/* + * For PKCS#5 PBES2 encryption algorithm + */ +typedef struct { + oid_descriptor_t descriptor; + cipher_type_t cipher_alg; +} oid_cipher_alg_t; + +static const oid_cipher_alg_t oid_cipher_alg[] = +{ + { + { ADD_LEN( OID_DES_CBC ), "desCBC", "DES-CBC" }, + POLARSSL_CIPHER_DES_CBC, + }, + { + { ADD_LEN( OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, + POLARSSL_CIPHER_DES_EDE3_CBC, + }, + { + { NULL, 0, NULL, NULL }, + (cipher_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg); +FN_OID_GET_ATTR1(oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, cipher_type_t, cipher_alg); +#endif /* POLARSSL_CIPHER_C */ + +#if defined(POLARSSL_MD_C) +/* + * For digestAlgorithm + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; +} oid_md_alg_t; + +static const oid_md_alg_t oid_md_alg[] = +{ + { + { ADD_LEN( OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, + POLARSSL_MD_MD2, + }, + { + { ADD_LEN( OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, + POLARSSL_MD_MD4, + }, + { + { ADD_LEN( OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, + POLARSSL_MD_MD5, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, + POLARSSL_MD_SHA1, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, + POLARSSL_MD_SHA224, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, + POLARSSL_MD_SHA256, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, + POLARSSL_MD_SHA384, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, + POLARSSL_MD_SHA512, + }, + { + { NULL, 0, NULL, NULL }, + (md_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg); +FN_OID_GET_ATTR1(oid_get_md_alg, oid_md_alg_t, md_alg, md_type_t, md_alg); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, md_type_t, md_alg); +#endif /* POLARSSL_MD_C */ + +#if defined(POLARSSL_PKCS12_C) +/* + * For PKCS#12 PBEs + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; + cipher_type_t cipher_alg; +} oid_pkcs12_pbe_alg_t; + +static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = +{ + { + { ADD_LEN( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, + POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE3_CBC, + }, + { + { ADD_LEN( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, + POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE_CBC, + }, + { + { NULL, 0, NULL, NULL }, + 0, 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg); +FN_OID_GET_ATTR2(oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, md_type_t, md_alg, cipher_type_t, cipher_alg); +#endif /* POLARSSL_PKCS12_C */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + \ + if( (unsigned int) ret >= n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +/* Return the x.y.z.... style numeric string for the given OID */ +int oid_get_numeric_string( char *buf, size_t size, + const asn1_buf *oid ) +{ + int ret; + size_t i, n; + unsigned int value; + char *p; + + p = buf; + n = size; + + /* First byte contains first two dots */ + if( oid->len > 0 ) + { + ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); + SAFE_SNPRINTF(); + } + + value = 0; + for( i = 1; i < oid->len; i++ ) + { + /* Prevent overflow in value. */ + if( ( ( value << 7 ) >> 7 ) != value ) + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); + + value <<= 7; + value += oid->p[i] & 0x7F; + + if( !( oid->p[i] & 0x80 ) ) + { + /* Last byte */ + ret = snprintf( p, n, ".%d", value ); + SAFE_SNPRINTF(); + value = 0; + } + } + + return( (int) ( size - n ) ); +} + +#endif /* POLARSSL_OID_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/padlock.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/padlock.c new file mode 100644 index 0000000..5d06390 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/padlock.c @@ -0,0 +1,168 @@ +/* + * VIA PadLock support functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This implementation is based on the VIA PadLock Programming Guide: + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ + * programming_guide.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PADLOCK_C) + +#include "polarssl/padlock.h" + +#if defined(POLARSSL_HAVE_X86) + +/* + * PadLock detection routine + */ +int padlock_supports( int feature ) +{ + static int flags = -1; + int ebx = 0, edx = 0; + + if( flags == -1 ) + { + asm( "movl %%ebx, %0 \n\t" + "movl $0xC0000000, %%eax \n\t" + "cpuid \n\t" + "cmpl $0xC0000001, %%eax \n\t" + "movl $0, %%edx \n\t" + "jb unsupported \n\t" + "movl $0xC0000001, %%eax \n\t" + "cpuid \n\t" + "unsupported: \n\t" + "movl %%edx, %1 \n\t" + "movl %2, %%ebx \n\t" + : "=m" (ebx), "=m" (edx) + : "m" (ebx) + : "eax", "ecx", "edx" ); + + flags = edx; + } + + return( flags & feature ); +} + +/* + * PadLock AES-ECB block en(de)cryption + */ +int padlock_xcryptecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int ebx = 0; + uint32_t *rk; + uint32_t *blk; + uint32_t *ctrl; + unsigned char buf[256]; + + rk = ctx->rk; + blk = PADLOCK_ALIGN16( buf ); + memcpy( blk, input, 16 ); + + ctrl = blk + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl $1, %%ecx \n\t" + "movl %2, %%edx \n\t" + "movl %3, %%ebx \n\t" + "movl %4, %%esi \n\t" + "movl %4, %%edi \n\t" + ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) + : "ecx", "edx", "esi", "edi" ); + + memcpy( output, blk, 16 ); + + return( 0 ); +} + +/* + * PadLock AES-CBC buffer en(de)cryption + */ +int padlock_xcryptcbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ebx = 0; + size_t count; + uint32_t *rk; + uint32_t *iw; + uint32_t *ctrl; + unsigned char buf[256]; + + if( ( (long) input & 15 ) != 0 || + ( (long) output & 15 ) != 0 ) + return( POLARSSL_ERR_PADLOCK_DATA_MISALIGNED ); + + rk = ctx->rk; + iw = PADLOCK_ALIGN16( buf ); + memcpy( iw, iv, 16 ); + + ctrl = iw + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); + + count = ( length + 15 ) >> 4; + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl %2, %%ecx \n\t" + "movl %3, %%edx \n\t" + "movl %4, %%ebx \n\t" + "movl %5, %%esi \n\t" + "movl %6, %%edi \n\t" + "movl %7, %%eax \n\t" + ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (count), "m" (ctrl), + "m" (rk), "m" (input), "m" (output), "m" (iw) + : "eax", "ecx", "edx", "esi", "edi" ); + + memcpy( iv, iw, 16 ); + + return( 0 ); +} + +#endif /* POLARSSL_HAVE_X86 */ + +#endif /* POLARSSL_PADLOCK_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pbkdf2.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pbkdf2.c new file mode 100644 index 0000000..e76f066 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pbkdf2.c @@ -0,0 +1,64 @@ +/** + * \file pbkdf2.c + * + * \brief Password-Based Key Derivation Function 2 (from PKCS#5) + * DEPRECATED: Use pkcs5.c instead + * + * \author Mathias Olsson + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * PBKDF2 is part of PKCS#5 + * + * http://tools.ietf.org/html/rfc2898 (Specification) + * http://tools.ietf.org/html/rfc6070 (Test vectors) + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PBKDF2_C) + +#include "polarssl/pbkdf2.h" +#include "polarssl/pkcs5.h" + +int pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, size_t plen, + const unsigned char *salt, size_t slen, + unsigned int iteration_count, + uint32_t key_length, unsigned char *output ) +{ + return pkcs5_pbkdf2_hmac( ctx, password, plen, salt, slen, iteration_count, + key_length, output ); +} + +#if defined(POLARSSL_SELF_TEST) +int pbkdf2_self_test( int verbose ) +{ + return pkcs5_self_test( verbose ); +} +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_PBKDF2_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pem.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pem.c new file mode 100644 index 0000000..485d829 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pem.c @@ -0,0 +1,445 @@ +/* + * Privacy Enhanced Mail (PEM) decoding + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#include "polarssl/base64.h" +#include "polarssl/des.h" +#include "polarssl/aes.h" +#include "polarssl/md5.h" +#include "polarssl/cipher.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_PEM_PARSE_C) +void pem_init( pem_context *ctx ) +{ + memset( ctx, 0, sizeof( pem_context ) ); +} + +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) +/* + * Read a 16-byte hex string and convert it to binary + */ +static int pem_get_iv( const unsigned char *s, unsigned char *iv, + size_t iv_len ) +{ + size_t i, j, k; + + memset( iv, 0, iv_len ); + + for( i = 0; i < iv_len * 2; i++, s++ ) + { + if( *s >= '0' && *s <= '9' ) j = *s - '0'; else + if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else + if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + k = ( ( i & 1 ) != 0 ) ? j : j << 4; + + iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); + } + + return( 0 ); +} + +static void pem_pbkdf1( unsigned char *key, size_t keylen, + unsigned char *iv, + const unsigned char *pwd, size_t pwdlen ) +{ + md5_context md5_ctx; + unsigned char md5sum[16]; + size_t use_len; + + md5_init( &md5_ctx ); + + /* + * key[ 0..15] = MD5(pwd || IV) + */ + md5_starts( &md5_ctx ); + md5_update( &md5_ctx, pwd, pwdlen ); + md5_update( &md5_ctx, iv, 8 ); + md5_finish( &md5_ctx, md5sum ); + + if( keylen <= 16 ) + { + memcpy( key, md5sum, keylen ); + + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); + return; + } + + memcpy( key, md5sum, 16 ); + + /* + * key[16..23] = MD5(key[ 0..15] || pwd || IV]) + */ + md5_starts( &md5_ctx ); + md5_update( &md5_ctx, md5sum, 16 ); + md5_update( &md5_ctx, pwd, pwdlen ); + md5_update( &md5_ctx, iv, 8 ); + md5_finish( &md5_ctx, md5sum ); + + use_len = 16; + if( keylen < 32 ) + use_len = keylen - 16; + + memcpy( key + 16, md5sum, use_len ); + + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); +} + +#if defined(POLARSSL_DES_C) +/* + * Decrypt with DES-CBC, using PBKDF1 for key derivation + */ +static void pem_des_decrypt( unsigned char des_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + des_context des_ctx; + unsigned char des_key[8]; + + des_init( &des_ctx ); + + pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ); + + des_setkey_dec( &des_ctx, des_key ); + des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen, + des_iv, buf, buf ); + + des_free( &des_ctx ); + polarssl_zeroize( des_key, 8 ); +} + +/* + * Decrypt with 3DES-CBC, using PBKDF1 for key derivation + */ +static void pem_des3_decrypt( unsigned char des3_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + des3_context des3_ctx; + unsigned char des3_key[24]; + + des3_init( &des3_ctx ); + + pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ); + + des3_set3key_dec( &des3_ctx, des3_key ); + des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen, + des3_iv, buf, buf ); + + des3_free( &des3_ctx ); + polarssl_zeroize( des3_key, 24 ); +} +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) +/* + * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation + */ +static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + aes_context aes_ctx; + unsigned char aes_key[32]; + + aes_init( &aes_ctx ); + + pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); + + aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ); + aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen, + aes_iv, buf, buf ); + + aes_free( &aes_ctx ); + polarssl_zeroize( aes_key, keylen ); +} +#endif /* POLARSSL_AES_C */ + +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + +int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, + const unsigned char *data, const unsigned char *pwd, + size_t pwdlen, size_t *use_len ) +{ + int ret, enc; + size_t len; + unsigned char *buf; + const unsigned char *s1, *s2, *end; +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + unsigned char pem_iv[16]; + cipher_type_t enc_alg = POLARSSL_CIPHER_NONE; +#else + ((void) pwd); + ((void) pwdlen); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + + if( ctx == NULL ) + return( POLARSSL_ERR_PEM_BAD_INPUT_DATA ); + + s1 = (unsigned char *) strstr( (const char *) data, header ); + + if( s1 == NULL ) + return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s2 = (unsigned char *) strstr( (const char *) data, footer ); + + if( s2 == NULL || s2 <= s1 ) + return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s1 += strlen( header ); + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + end = s2; + end += strlen( footer ); + if( *end == '\r' ) end++; + if( *end == '\n' ) end++; + *use_len = end - data; + + enc = 0; + + if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) + { +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + enc++; + + s1 += 22; + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_INVALID_DATA ); + + +#if defined(POLARSSL_DES_C) + if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) + { + enc_alg = POLARSSL_CIPHER_DES_EDE3_CBC; + + s1 += 23; + if( pem_get_iv( s1, pem_iv, 8 ) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } + else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) + { + enc_alg = POLARSSL_CIPHER_DES_CBC; + + s1 += 18; + if( pem_get_iv( s1, pem_iv, 8) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) + if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) + { + if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_128_CBC; + else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_192_CBC; + else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_256_CBC; + else + return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG ); + + s1 += 22; + if( pem_get_iv( s1, pem_iv, 16 ) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 32; + } +#endif /* POLARSSL_AES_C */ + + if( enc_alg == POLARSSL_CIPHER_NONE ) + return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG ); + + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_INVALID_DATA ); +#else + return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + } + + len = 0; + ret = base64_decode( NULL, &len, s1, s2 - s1 ); + + if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER ) + return( POLARSSL_ERR_PEM_INVALID_DATA + ret ); + + if( ( buf = (unsigned char *) polarssl_malloc( len ) ) == NULL ) + return( POLARSSL_ERR_PEM_MALLOC_FAILED ); + + if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_INVALID_DATA + ret ); + } + + if( enc != 0 ) + { +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + if( pwd == NULL ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED ); + } + +#if defined(POLARSSL_DES_C) + if( enc_alg == POLARSSL_CIPHER_DES_EDE3_CBC ) + pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_DES_CBC ) + pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) + if( enc_alg == POLARSSL_CIPHER_AES_128_CBC ) + pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_AES_192_CBC ) + pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_AES_256_CBC ) + pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); +#endif /* POLARSSL_AES_C */ + + /* + * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 + * length bytes (allow 4 to be sure) in all known use cases. + * + * Use that as heurisitic to try detecting password mismatchs. + */ + if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH ); + } +#else + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + } + + ctx->buf = buf; + ctx->buflen = len; + + return( 0 ); +} + +void pem_free( pem_context *ctx ) +{ + polarssl_free( ctx->buf ); + polarssl_free( ctx->info ); + + polarssl_zeroize( ctx, sizeof( pem_context ) ); +} +#endif /* POLARSSL_PEM_PARSE_C */ + +#if defined(POLARSSL_PEM_WRITE_C) +int pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ) +{ + int ret; + unsigned char *encode_buf, *c, *p = buf; + size_t len = 0, use_len = 0, add_len = 0; + + base64_encode( NULL, &use_len, der_data, der_len ); + add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + + if( use_len + add_len > buf_len ) + { + *olen = use_len + add_len; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + if( ( encode_buf = polarssl_malloc( use_len ) ) == NULL ) + return( POLARSSL_ERR_PEM_MALLOC_FAILED ); + + if( ( ret = base64_encode( encode_buf, &use_len, der_data, + der_len ) ) != 0 ) + { + polarssl_free( encode_buf ); + return( ret ); + } + + memcpy( p, header, strlen( header ) ); + p += strlen( header ); + c = encode_buf; + + while( use_len ) + { + len = ( use_len > 64 ) ? 64 : use_len; + memcpy( p, c, len ); + use_len -= len; + p += len; + c += len; + *p++ = '\n'; + } + + memcpy( p, footer, strlen( footer ) ); + p += strlen( footer ); + + *p++ = '\0'; + *olen = p - buf; + + polarssl_free( encode_buf ); + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ +#endif /* POLARSSL_PEM_PARSE_C || POLARSSL_PEM_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk.c new file mode 100644 index 0000000..11faf3c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk.c @@ -0,0 +1,351 @@ +/* + * Public Key abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_C) + +#include "polarssl/pk.h" +#include "polarssl/pk_wrap.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Initialise a pk_context + */ +void pk_init( pk_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->pk_info = NULL; + ctx->pk_ctx = NULL; +} + +/* + * Free (the components of) a pk_context + */ +void pk_free( pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return; + + ctx->pk_info->ctx_free_func( ctx->pk_ctx ); + + polarssl_zeroize( ctx, sizeof( pk_context ) ); +} + +/* + * Get pk_info structure from type + */ +const pk_info_t * pk_info_from_type( pk_type_t pk_type ) +{ + switch( pk_type ) { +#if defined(POLARSSL_RSA_C) + case POLARSSL_PK_RSA: + return( &rsa_info ); +#endif +#if defined(POLARSSL_ECP_C) + case POLARSSL_PK_ECKEY: + return( &eckey_info ); + case POLARSSL_PK_ECKEY_DH: + return( &eckeydh_info ); +#endif +#if defined(POLARSSL_ECDSA_C) + case POLARSSL_PK_ECDSA: + return( &ecdsa_info ); +#endif + /* POLARSSL_PK_RSA_ALT omitted on purpose */ + default: + return( NULL ); + } +} + +/* + * Initialise context + */ +int pk_init_ctx( pk_context *ctx, const pk_info_t *info ) +{ + if( ctx == NULL || info == NULL || ctx->pk_info != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + + ctx->pk_info = info; + + return( 0 ); +} + +/* + * Initialize an RSA-alt context + */ +int pk_init_ctx_rsa_alt( pk_context *ctx, void * key, + pk_rsa_alt_decrypt_func decrypt_func, + pk_rsa_alt_sign_func sign_func, + pk_rsa_alt_key_len_func key_len_func ) +{ + rsa_alt_context *rsa_alt; + const pk_info_t *info = &rsa_alt_info; + + if( ctx == NULL || ctx->pk_info != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + + ctx->pk_info = info; + + rsa_alt = (rsa_alt_context *) ctx->pk_ctx; + + rsa_alt->key = key; + rsa_alt->decrypt_func = decrypt_func; + rsa_alt->sign_func = sign_func; + rsa_alt->key_len_func = key_len_func; + + return( 0 ); +} + +/* + * Tell if a PK can do the operations of the given type + */ +int pk_can_do( pk_context *ctx, pk_type_t type ) +{ + /* null or NONE context can't do anything */ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->can_do( type ) ); +} + +/* + * Helper for pk_sign and pk_verify + */ +static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len ) +{ + const md_info_t *md_info; + + if( *hash_len != 0 ) + return( 0 ); + + if( ( md_info = md_info_from_type( md_alg ) ) == NULL ) + return( -1 ); + + *hash_len = md_info->size; + return( 0 ); +} + +/* + * Verify a signature + */ +int pk_verify( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->verify_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len ) ); +} + +/* + * Verify a signature with options + */ +int pk_verify_ext( pk_type_t type, const void *options, + pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ! pk_can_do( ctx, type ) ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + if( type == POLARSSL_PK_RSASSA_PSS ) + { +#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21) + int ret; + const pk_rsassa_pss_options *pss_opts; + + if( options == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + pss_opts = (const pk_rsassa_pss_options *) options; + + if( sig_len < pk_get_len( ctx ) ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ), + NULL, NULL, RSA_PUBLIC, + md_alg, hash_len, hash, + pss_opts->mgf1_hash_id, + pss_opts->expected_salt_len, + sig ); + if( ret != 0 ) + return( ret ); + + if( sig_len > pk_get_len( ctx ) ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +#else + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); +#endif + } + + /* General case: no options */ + if( options != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); +} + +/* + * Make a signature + */ +int pk_sign( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->sign_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len, f_rng, p_rng ) ); +} + +/* + * Decrypt message + */ +int pk_decrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->decrypt_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Encrypt message + */ +int pk_encrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->encrypt_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Get key size in bits + */ +size_t pk_get_size( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->get_size( ctx->pk_ctx ) ); +} + +/* + * Export debug information + */ +int pk_debug( const pk_context *ctx, pk_debug_item *items ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->debug_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + ctx->pk_info->debug_func( ctx->pk_ctx, items ); + return( 0 ); +} + +/* + * Access the PK type name + */ +const char * pk_get_name( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( "invalid PK" ); + + return( ctx->pk_info->name ); +} + +/* + * Access the PK type + */ +pk_type_t pk_get_type( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_PK_NONE ); + + return( ctx->pk_info->type ); +} + +#endif /* POLARSSL_PK_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk_wrap.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk_wrap.c new file mode 100644 index 0000000..5e9ff60 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pk_wrap.c @@ -0,0 +1,452 @@ +/* + * Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_C) + +#include "polarssl/pk_wrap.h" + +/* Even if RSA not activated, for the sake of RSA-alt */ +#include "polarssl/rsa.h" + +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif + +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_RSA_C) +static int rsa_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_RSA || + type == POLARSSL_PK_RSASSA_PSS ); +} + +static size_t rsa_get_size( const void *ctx ) +{ + return( 8 * ((const rsa_context *) ctx)->len ); +} + +static int rsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + + if( sig_len < ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, + RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + if( sig_len > ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +static int rsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + *sig_len = ((rsa_context *) ctx)->len; + + return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ilen != ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_pkcs1_decrypt( (rsa_context *) ctx, f_rng, p_rng, + RSA_PRIVATE, olen, input, output, osize ) ); +} + +static int rsa_encrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + ((void) osize); + + *olen = ((rsa_context *) ctx)->len; + + return( rsa_pkcs1_encrypt( (rsa_context *) ctx, + f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) ); +} + +static void *rsa_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( rsa_context ) ); + + if( ctx != NULL ) + rsa_init( (rsa_context *) ctx, 0, 0 ); + + return( ctx ); +} + +static void rsa_free_wrap( void *ctx ) +{ + rsa_free( (rsa_context *) ctx ); + polarssl_free( ctx ); +} + +static void rsa_debug( const void *ctx, pk_debug_item *items ) +{ + items->type = POLARSSL_PK_DEBUG_MPI; + items->name = "rsa.N"; + items->value = &( ((rsa_context *) ctx)->N ); + + items++; + + items->type = POLARSSL_PK_DEBUG_MPI; + items->name = "rsa.E"; + items->value = &( ((rsa_context *) ctx)->E ); +} + +const pk_info_t rsa_info = { + POLARSSL_PK_RSA, + "RSA", + rsa_get_size, + rsa_can_do, + rsa_verify_wrap, + rsa_sign_wrap, + rsa_decrypt_wrap, + rsa_encrypt_wrap, + rsa_alloc_wrap, + rsa_free_wrap, + rsa_debug, +}; +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * Generic EC key + */ +static int eckey_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECKEY || + type == POLARSSL_PK_ECKEY_DH || + type == POLARSSL_PK_ECDSA ); +} + +static size_t eckey_get_size( const void *ctx ) +{ + return( ((ecp_keypair *) ctx)->grp.pbits ); +} + +#if defined(POLARSSL_ECDSA_C) +/* Forward declarations */ +static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +static int eckey_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ecdsa_context ecdsa; + + ecdsa_init( &ecdsa ); + + if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); + + ecdsa_free( &ecdsa ); + + return( ret ); +} + +static int eckey_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + ecdsa_context ecdsa; + + ecdsa_init( &ecdsa ); + + if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, + f_rng, p_rng ); + + ecdsa_free( &ecdsa ); + + return( ret ); +} + +#endif /* POLARSSL_ECDSA_C */ + +static void *eckey_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( ecp_keypair ) ); + + if( ctx != NULL ) + ecp_keypair_init( ctx ); + + return( ctx ); +} + +static void eckey_free_wrap( void *ctx ) +{ + ecp_keypair_free( (ecp_keypair *) ctx ); + polarssl_free( ctx ); +} + +static void eckey_debug( const void *ctx, pk_debug_item *items ) +{ + items->type = POLARSSL_PK_DEBUG_ECP; + items->name = "eckey.Q"; + items->value = &( ((ecp_keypair *) ctx)->Q ); +} + +const pk_info_t eckey_info = { + POLARSSL_PK_ECKEY, + "EC", + eckey_get_size, + eckey_can_do, +#if defined(POLARSSL_ECDSA_C) + eckey_verify_wrap, + eckey_sign_wrap, +#else + NULL, + NULL, +#endif + NULL, + NULL, + eckey_alloc_wrap, + eckey_free_wrap, + eckey_debug, +}; + +/* + * EC key restricted to ECDH + */ +static int eckeydh_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECKEY || + type == POLARSSL_PK_ECKEY_DH ); +} + +const pk_info_t eckeydh_info = { + POLARSSL_PK_ECKEY_DH, + "EC_DH", + eckey_get_size, /* Same underlying key structure */ + eckeydh_can_do, + NULL, + NULL, + NULL, + NULL, + eckey_alloc_wrap, /* Same underlying key structure */ + eckey_free_wrap, /* Same underlying key structure */ + eckey_debug, /* Same underlying key structure */ +}; +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_ECDSA_C) +static int ecdsa_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECDSA ); +} + +static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ((void) md_alg); + + ret = ecdsa_read_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); +} + +static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + /* Use deterministic ECDSA by default if available */ +#if defined(POLARSSL_ECDSA_DETERMINISTIC) + ((void) f_rng); + ((void) p_rng); + + return( ecdsa_write_signature_det( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len, md_alg ) ); +#else + ((void) md_alg); + + return( ecdsa_write_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len, f_rng, p_rng ) ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ +} + +static void *ecdsa_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( ecdsa_context ) ); + + if( ctx != NULL ) + ecdsa_init( (ecdsa_context *) ctx ); + + return( ctx ); +} + +static void ecdsa_free_wrap( void *ctx ) +{ + ecdsa_free( (ecdsa_context *) ctx ); + polarssl_free( ctx ); +} + +const pk_info_t ecdsa_info = { + POLARSSL_PK_ECDSA, + "ECDSA", + eckey_get_size, /* Compatible key structures */ + ecdsa_can_do, + ecdsa_verify_wrap, + ecdsa_sign_wrap, + NULL, + NULL, + ecdsa_alloc_wrap, + ecdsa_free_wrap, + eckey_debug, /* Compatible key structures */ +}; +#endif /* POLARSSL_ECDSA_C */ + +/* + * Support for alternative RSA-private implementations + */ + +static int rsa_alt_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_RSA ); +} + +static size_t rsa_alt_get_size( const void *ctx ) +{ + const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx; + + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); +} + +static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx; + + *sig_len = rsa_alt->key_len_func( rsa_alt->key ); + + return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_alt_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx; + + ((void) f_rng); + ((void) p_rng); + + if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_alt->decrypt_func( rsa_alt->key, + RSA_PRIVATE, olen, input, output, osize ) ); +} + +static void *rsa_alt_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) ); + + if( ctx != NULL ) + memset( ctx, 0, sizeof( rsa_alt_context ) ); + + return( ctx ); +} + +static void rsa_alt_free_wrap( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( rsa_alt_context ) ); + polarssl_free( ctx ); +} + +const pk_info_t rsa_alt_info = { + POLARSSL_PK_RSA_ALT, + "RSA-alt", + rsa_alt_get_size, + rsa_alt_can_do, + NULL, + rsa_alt_sign_wrap, + rsa_alt_decrypt_wrap, + NULL, + rsa_alt_alloc_wrap, + rsa_alt_free_wrap, + NULL, +}; + +#endif /* POLARSSL_PK_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs11.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs11.c new file mode 100644 index 0000000..64e7ce3 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs11.c @@ -0,0 +1,236 @@ +/** + * \file pkcs11.c + * + * \brief Wrapper for PKCS#11 library libpkcs11-helper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/pkcs11.h" + +#if defined(POLARSSL_PKCS11_C) +#include "polarssl/md.h" +#include "polarssl/oid.h" +#include "polarssl/x509_crt.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +int pkcs11_x509_cert_init( x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + unsigned char *cert_blob = NULL; + size_t cert_blob_size = 0; + + if( cert == NULL ) + { + ret = 2; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, + &cert_blob_size ) != CKR_OK ) + { + ret = 3; + goto cleanup; + } + + cert_blob = polarssl_malloc( cert_blob_size ); + if( NULL == cert_blob ) + { + ret = 4; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, + &cert_blob_size ) != CKR_OK ) + { + ret = 5; + goto cleanup; + } + + if( 0 != x509_crt_parse( cert, cert_blob, cert_blob_size ) ) + { + ret = 6; + goto cleanup; + } + + ret = 0; + +cleanup: + if( NULL != cert_blob ) + polarssl_free( cert_blob ); + + return( ret ); +} + + +int pkcs11_priv_key_init( pkcs11_context *priv_key, + pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + x509_crt cert; + + x509_crt_init( &cert ); + + if( priv_key == NULL ) + goto cleanup; + + if( 0 != pkcs11_x509_cert_init( &cert, pkcs11_cert ) ) + goto cleanup; + + priv_key->len = pk_get_len( &cert.pk ); + priv_key->pkcs11h_cert = pkcs11_cert; + + ret = 0; + +cleanup: + x509_crt_free( &cert ); + + return( ret ); +} + +void pkcs11_priv_key_free( pkcs11_context *priv_key ) +{ + if( NULL != priv_key ) + pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); +} + +int pkcs11_decrypt( pkcs11_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + size_t input_len, output_len; + + if( NULL == ctx ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( RSA_PRIVATE != mode ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + output_len = input_len = ctx->len; + + if( input_len < 16 || input_len > output_max_len ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + /* Determine size of output buffer */ + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, NULL, &output_len ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + if( output_len > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, output, &output_len ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + *olen = output_len; + return( 0 ); +} + +int pkcs11_sign( pkcs11_context *ctx, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t sig_len = 0, asn_len = 0, oid_size = 0; + unsigned char *p = sig; + const char *oid; + + if( NULL == ctx ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( RSA_PRIVATE != mode ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( md_alg != POLARSSL_MD_NONE ) + { + const md_info_t *md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + asn_len = 10 + oid_size; + } + + sig_len = ctx->len; + if( hashlen > sig_len || asn_len > sig_len || + hashlen + asn_len > sig_len ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + if( md_alg != POLARSSL_MD_NONE ) + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = ASN1_NULL; + *p++ = 0x00; + *p++ = ASN1_OCTET_STRING; + *p++ = hashlen; + } + + memcpy( p, hash, hashlen ); + + if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, + asn_len + hashlen, sig, &sig_len ) != CKR_OK ) + { + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +#endif /* defined(POLARSSL_PKCS11_C) */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs12.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs12.c new file mode 100644 index 0000000..0cf2edf --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs12.c @@ -0,0 +1,360 @@ +/* + * PKCS#12 Personal Information Exchange Syntax + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 + * + * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf + * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PKCS12_C) + +#include "polarssl/pkcs12.h" +#include "polarssl/asn1.h" +#include "polarssl/cipher.h" + +#if defined(POLARSSL_ARC4_C) +#include "polarssl/arc4.h" +#endif + +#if defined(POLARSSL_DES_C) +#include "polarssl/des.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +static int pkcs12_parse_pbe_params( asn1_buf *params, + asn1_buf *salt, int *iterations ) +{ + int ret; + unsigned char **p = ¶ms->p; + const unsigned char *end = params->p + params->len; + + /* + * pkcs-12PbeParams ::= SEQUENCE { + * salt OCTET STRING, + * iterations INTEGER + * } + * + */ + if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + if( ( ret = asn1_get_tag( p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); + + salt->p = *p; + *p += salt->len; + + if( ( ret = asn1_get_int( p, end, iterations ) ) != 0 ) + return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); + + if( *p != end ) + return( POLARSSL_ERR_PKCS12_PBE_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +static int pkcs12_pbe_derive_key_iv( asn1_buf *pbe_params, md_type_t md_type, + const unsigned char *pwd, size_t pwdlen, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen ) +{ + int ret, iterations; + asn1_buf salt; + size_t i; + unsigned char unipwd[258]; + + memset( &salt, 0, sizeof(asn1_buf) ); + memset( &unipwd, 0, sizeof(unipwd) ); + + if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, + &iterations ) ) != 0 ) + return( ret ); + + for( i = 0; i < pwdlen; i++ ) + unipwd[i * 2 + 1] = pwd[i]; + + if( ( ret = pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, + salt.p, salt.len, md_type, + PKCS12_DERIVE_KEY, iterations ) ) != 0 ) + { + return( ret ); + } + + if( iv == NULL || ivlen == 0 ) + return( 0 ); + + if( ( ret = pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, + salt.p, salt.len, md_type, + PKCS12_DERIVE_IV, iterations ) ) != 0 ) + { + return( ret ); + } + return( 0 ); +} + +int pkcs12_pbe_sha1_rc4_128( asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t len, + unsigned char *output ) +{ +#if !defined(POLARSSL_ARC4_C) + ((void) pbe_params); + ((void) mode); + ((void) pwd); + ((void) pwdlen); + ((void) data); + ((void) len); + ((void) output); + return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); +#else + int ret; + unsigned char key[16]; + arc4_context ctx; + ((void) mode); + + arc4_init( &ctx ); + + if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, POLARSSL_MD_SHA1, + pwd, pwdlen, + key, 16, NULL, 0 ) ) != 0 ) + { + return( ret ); + } + + arc4_setup( &ctx, key, 16 ); + if( ( ret = arc4_crypt( &ctx, len, data, output ) ) != 0 ) + goto exit; + +exit: + polarssl_zeroize( key, sizeof( key ) ); + arc4_free( &ctx ); + + return( ret ); +#endif /* POLARSSL_ARC4_C */ +} + +int pkcs12_pbe( asn1_buf *pbe_params, int mode, + cipher_type_t cipher_type, md_type_t md_type, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t len, + unsigned char *output ) +{ + int ret, keylen = 0; + unsigned char key[32]; + unsigned char iv[16]; + const cipher_info_t *cipher_info; + cipher_context_t cipher_ctx; + size_t olen = 0; + + cipher_info = cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); + + keylen = cipher_info->key_length / 8; + + if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, + key, keylen, + iv, cipher_info->iv_size ) ) != 0 ) + { + return( ret ); + } + + cipher_init( &cipher_ctx ); + + if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) + goto exit; + + if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 ) + goto exit; + + if( ( ret = cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) + goto exit; + + if( ( ret = cipher_reset( &cipher_ctx ) ) != 0 ) + goto exit; + + if( ( ret = cipher_update( &cipher_ctx, data, len, + output, &olen ) ) != 0 ) + { + goto exit; + } + + if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) + ret = POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH; + +exit: + polarssl_zeroize( key, sizeof( key ) ); + polarssl_zeroize( iv, sizeof( iv ) ); + cipher_free( &cipher_ctx ); + + return( ret ); +} + +static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, + const unsigned char *filler, size_t fill_len ) +{ + unsigned char *p = data; + size_t use_len; + + while( data_len > 0 ) + { + use_len = ( data_len > fill_len ) ? fill_len : data_len; + memcpy( p, filler, use_len ); + p += use_len; + data_len -= use_len; + } +} + +int pkcs12_derivation( unsigned char *data, size_t datalen, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *salt, size_t saltlen, + md_type_t md_type, int id, int iterations ) +{ + int ret; + unsigned int j; + + unsigned char diversifier[128]; + unsigned char salt_block[128], pwd_block[128], hash_block[128]; + unsigned char hash_output[POLARSSL_MD_MAX_SIZE]; + unsigned char *p; + unsigned char c; + + size_t hlen, use_len, v, i; + + const md_info_t *md_info; + md_context_t md_ctx; + + // This version only allows max of 64 bytes of password or salt + if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) + return( POLARSSL_ERR_PKCS12_BAD_INPUT_DATA ); + + md_info = md_info_from_type( md_type ); + if( md_info == NULL ) + return( POLARSSL_ERR_PKCS12_FEATURE_UNAVAILABLE ); + + md_init( &md_ctx ); + + if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) + return( ret ); + hlen = md_get_size( md_info ); + + if( hlen <= 32 ) + v = 64; + else + v = 128; + + memset( diversifier, (unsigned char) id, v ); + + pkcs12_fill_buffer( salt_block, v, salt, saltlen ); + pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); + + p = data; + while( datalen > 0 ) + { + // Calculate hash( diversifier || salt_block || pwd_block ) + if( ( ret = md_starts( &md_ctx ) ) != 0 ) + goto exit; + + if( ( ret = md_update( &md_ctx, diversifier, v ) ) != 0 ) + goto exit; + + if( ( ret = md_update( &md_ctx, salt_block, v ) ) != 0 ) + goto exit; + + if( ( ret = md_update( &md_ctx, pwd_block, v ) ) != 0 ) + goto exit; + + if( ( ret = md_finish( &md_ctx, hash_output ) ) != 0 ) + goto exit; + + // Perform remaining ( iterations - 1 ) recursive hash calculations + for( i = 1; i < (size_t) iterations; i++ ) + { + if( ( ret = md( md_info, hash_output, hlen, hash_output ) ) != 0 ) + goto exit; + } + + use_len = ( datalen > hlen ) ? hlen : datalen; + memcpy( p, hash_output, use_len ); + datalen -= use_len; + p += use_len; + + if( datalen == 0 ) + break; + + // Concatenating copies of hash_output into hash_block (B) + pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); + + // B += 1 + for( i = v; i > 0; i-- ) + if( ++hash_block[i - 1] != 0 ) + break; + + // salt_block += B + c = 0; + for( i = v; i > 0; i-- ) + { + j = salt_block[i - 1] + hash_block[i - 1] + c; + c = (unsigned char) (j >> 8); + salt_block[i - 1] = j & 0xFF; + } + + // pwd_block += B + c = 0; + for( i = v; i > 0; i-- ) + { + j = pwd_block[i - 1] + hash_block[i - 1] + c; + c = (unsigned char) (j >> 8); + pwd_block[i - 1] = j & 0xFF; + } + } + + ret = 0; + +exit: + polarssl_zeroize( salt_block, sizeof( salt_block ) ); + polarssl_zeroize( pwd_block, sizeof( pwd_block ) ); + polarssl_zeroize( hash_block, sizeof( hash_block ) ); + polarssl_zeroize( hash_output, sizeof( hash_output ) ); + + md_free( &md_ctx ); + + return( ret ); +} + +#endif /* POLARSSL_PKCS12_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs5.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs5.c new file mode 100644 index 0000000..e769783 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkcs5.c @@ -0,0 +1,417 @@ +/** + * \file pkcs5.c + * + * \brief PKCS#5 functions + * + * \author Mathias Olsson + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * PKCS#5 includes PBKDF2 and more + * + * http://tools.ietf.org/html/rfc2898 (Specification) + * http://tools.ietf.org/html/rfc6070 (Test vectors) + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PKCS5_C) + +#include "polarssl/pkcs5.h" +#include "polarssl/asn1.h" +#include "polarssl/cipher.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +static int pkcs5_parse_pbkdf2_params( const asn1_buf *params, + asn1_buf *salt, int *iterations, + int *keylen, md_type_t *md_type ) +{ + int ret; + asn1_buf prf_alg_oid; + unsigned char *p = params->p; + const unsigned char *end = params->p + params->len; + + if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + /* + * PBKDF2-params ::= SEQUENCE { + * salt OCTET STRING, + * iterationCount INTEGER, + * keyLength INTEGER OPTIONAL + * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 + * } + * + */ + if( ( ret = asn1_get_tag( &p, end, &salt->len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + + salt->p = p; + p += salt->len; + + if( ( ret = asn1_get_int( &p, end, iterations ) ) != 0 ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_int( &p, end, keylen ) ) != 0 ) + { + if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + } + + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + + if( !OID_CMP( OID_HMAC_SHA1, &prf_alg_oid ) ) + return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + *md_type = POLARSSL_MD_SHA1; + + if( p != end ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int pkcs5_pbes2( asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t datalen, + unsigned char *output ) +{ + int ret, iterations = 0, keylen = 0; + unsigned char *p, *end; + asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; + asn1_buf salt; + md_type_t md_type = POLARSSL_MD_SHA1; + unsigned char key[32], iv[32]; + size_t olen = 0; + const md_info_t *md_info; + const cipher_info_t *cipher_info; + md_context_t md_ctx; + cipher_type_t cipher_alg; + cipher_context_t cipher_ctx; + + p = pbe_params->p; + end = p + pbe_params->len; + + /* + * PBES2-params ::= SEQUENCE { + * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, + * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} + * } + */ + if( pbe_params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + if( ( ret = asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 ) + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + + // Only PBKDF2 supported at the moment + // + if( !OID_CMP( OID_PKCS5_PBKDF2, &kdf_alg_oid ) ) + return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, + &salt, &iterations, &keylen, + &md_type ) ) != 0 ) + { + return( ret ); + } + + md_info = md_info_from_type( md_type ); + if( md_info == NULL ) + return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + if( ( ret = asn1_get_alg( &p, end, &enc_scheme_oid, + &enc_scheme_params ) ) != 0 ) + { + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret ); + } + + if( oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) + return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + cipher_info = cipher_info_from_type( cipher_alg ); + if( cipher_info == NULL ) + return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + /* + * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored + * since it is optional and we don't know if it was set or not + */ + keylen = cipher_info->key_length / 8; + + if( enc_scheme_params.tag != ASN1_OCTET_STRING || + enc_scheme_params.len != cipher_info->iv_size ) + { + return( POLARSSL_ERR_PKCS5_INVALID_FORMAT ); + } + + md_init( &md_ctx ); + cipher_init( &cipher_ctx ); + + memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); + + if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 ) + goto exit; + + if( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, + iterations, keylen, key ) ) != 0 ) + { + goto exit; + } + + if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 ) + goto exit; + + if( ( ret = cipher_setkey( &cipher_ctx, key, 8 * keylen, mode ) ) != 0 ) + goto exit; + + if( ( ret = cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, + data, datalen, output, &olen ) ) != 0 ) + ret = POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH; + +exit: + md_free( &md_ctx ); + cipher_free( &cipher_ctx ); + + return( ret ); +} + +int pkcs5_pbkdf2_hmac( md_context_t *ctx, const unsigned char *password, + size_t plen, const unsigned char *salt, size_t slen, + unsigned int iteration_count, + uint32_t key_length, unsigned char *output ) +{ + int ret, j; + unsigned int i; + unsigned char md1[POLARSSL_MD_MAX_SIZE]; + unsigned char work[POLARSSL_MD_MAX_SIZE]; + unsigned char md_size = md_get_size( ctx->md_info ); + size_t use_len; + unsigned char *out_p = output; + unsigned char counter[4]; + + memset( counter, 0, 4 ); + counter[3] = 1; + + if( iteration_count > 0xFFFFFFFF ) + return( POLARSSL_ERR_PKCS5_BAD_INPUT_DATA ); + + while( key_length ) + { + // U1 ends up in work + // + if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 ) + return( ret ); + + if( ( ret = md_hmac_update( ctx, salt, slen ) ) != 0 ) + return( ret ); + + if( ( ret = md_hmac_update( ctx, counter, 4 ) ) != 0 ) + return( ret ); + + if( ( ret = md_hmac_finish( ctx, work ) ) != 0 ) + return( ret ); + + memcpy( md1, work, md_size ); + + for( i = 1; i < iteration_count; i++ ) + { + // U2 ends up in md1 + // + if( ( ret = md_hmac_starts( ctx, password, plen ) ) != 0 ) + return( ret ); + + if( ( ret = md_hmac_update( ctx, md1, md_size ) ) != 0 ) + return( ret ); + + if( ( ret = md_hmac_finish( ctx, md1 ) ) != 0 ) + return( ret ); + + // U1 xor U2 + // + for( j = 0; j < md_size; j++ ) + work[j] ^= md1[j]; + } + + use_len = ( key_length < md_size ) ? key_length : md_size; + memcpy( out_p, work, use_len ); + + key_length -= (uint32_t) use_len; + out_p += use_len; + + for( i = 4; i > 0; i-- ) + if( ++counter[i - 1] != 0 ) + break; + } + + return( 0 ); +} + +#if defined(POLARSSL_SELF_TEST) + +#if !defined(POLARSSL_SHA1_C) +int pkcs5_self_test( int verbose ) +{ + if( verbose != 0 ) + polarssl_printf( " PBKDF2 (SHA1): skipped\n\n" ); + + return( 0 ); +} +#else + +#include + +#define MAX_TESTS 6 + +size_t plen[MAX_TESTS] = + { 8, 8, 8, 8, 24, 9 }; + +unsigned char password[MAX_TESTS][32] = +{ + "password", + "password", + "password", + "password", + "passwordPASSWORDpassword", + "pass\0word", +}; + +size_t slen[MAX_TESTS] = + { 4, 4, 4, 4, 36, 5 }; + +unsigned char salt[MAX_TESTS][40] = +{ + "salt", + "salt", + "salt", + "salt", + "saltSALTsaltSALTsaltSALTsaltSALTsalt", + "sa\0lt", +}; + +uint32_t it_cnt[MAX_TESTS] = + { 1, 2, 4096, 16777216, 4096, 4096 }; + +uint32_t key_len[MAX_TESTS] = + { 20, 20, 20, 20, 25, 16 }; + + +unsigned char result_key[MAX_TESTS][32] = +{ + { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, + 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, + 0x2f, 0xe0, 0x37, 0xa6 }, + { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, + 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, + 0xd8, 0xde, 0x89, 0x57 }, + { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, + 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, + 0x65, 0xa4, 0x29, 0xc1 }, + { 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4, + 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c, + 0x26, 0x34, 0xe9, 0x84 }, + { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, + 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, + 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, + 0x38 }, + { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, + 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, +}; + +int pkcs5_self_test( int verbose ) +{ + md_context_t sha1_ctx; + const md_info_t *info_sha1; + int ret, i; + unsigned char key[64]; + + md_init( &sha1_ctx ); + + info_sha1 = md_info_from_type( POLARSSL_MD_SHA1 ); + if( info_sha1 == NULL ) + { + ret = 1; + goto exit; + } + + if( ( ret = md_init_ctx( &sha1_ctx, info_sha1 ) ) != 0 ) + { + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( " PBKDF2 note: test #3 may be slow!\n" ); + + for( i = 0; i < MAX_TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " PBKDF2 (SHA1) #%d: ", i ); + + ret = pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], + slen[i], it_cnt[i], key_len[i], key ); + if( ret != 0 || + memcmp( result_key[i], key, key_len[i] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + polarssl_printf( "\n" ); + +exit: + md_free( &sha1_ctx ); + + return( 0 ); +} +#endif /* POLARSSL_SHA1_C */ + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_PKCS5_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkparse.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkparse.c new file mode 100644 index 0000000..29217a2 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkparse.c @@ -0,0 +1,1256 @@ +/* + * Public Key layer for parsing key files and structures + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_PARSE_C) + +#include "polarssl/pk.h" +#include "polarssl/asn1.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif +#if defined(POLARSSL_PKCS5_C) +#include "polarssl/pkcs5.h" +#endif +#if defined(POLARSSL_PKCS12_C) +#include "polarssl/pkcs12.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#if defined(POLARSSL_FS_IO) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Load all data from a file into a given buffer. + */ +static int load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_PK_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( POLARSSL_ERR_PK_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL ) + { + fclose( f ); + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + polarssl_free( *buf ); + return( POLARSSL_ERR_PK_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + return( 0 ); +} + +/* + * Load and parse a private key + */ +int pk_parse_keyfile( pk_context *ctx, + const char *path, const char *pwd ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + if( pwd == NULL ) + ret = pk_parse_key( ctx, buf, n, NULL, 0 ); + else + ret = pk_parse_key( ctx, buf, n, + (const unsigned char *) pwd, strlen( pwd ) ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} + +/* + * Load and parse a public key + */ +int pk_parse_public_keyfile( pk_context *ctx, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = pk_parse_public_key( ctx, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_ECP_C) +/* Minimally parse an ECParameters buffer to and asn1_buf + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } + * -- implicitCurve NULL + * } + */ +static int pk_get_ecparams( unsigned char **p, const unsigned char *end, + asn1_buf *params ) +{ + int ret; + + /* Tag may be either OID or SEQUENCE */ + params->tag = **p; + if( params->tag != ASN1_OID +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) +#endif + ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + } + + if( ( ret = asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + params->p = *p; + *p += params->len; + + if( *p != end ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. + * WARNING: the resulting group should only be used with + * pk_group_id_from_specified(), since its base point may not be set correctly + * if it was encoded compressed. + * + * SpecifiedECDomain ::= SEQUENCE { + * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), + * fieldID FieldID {{FieldTypes}}, + * curve Curve, + * base ECPoint, + * order INTEGER, + * cofactor INTEGER OPTIONAL, + * hash HashAlgorithm OPTIONAL, + * ... + * } + * + * We only support prime-field as field type, and ignore hash and cofactor. + */ +static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp ) +{ + int ret; + unsigned char *p = params->p; + const unsigned char * const end = params->p + params->len; + const unsigned char *end_field, *end_curve; + size_t len; + int ver; + + /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ + if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ver < 1 || ver > 3 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + + /* + * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field + * fieldType FIELD-ID.&id({IOSet}), + * parameters FIELD-ID.&Type({IOSet}{@fieldType}) + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_field = p + len; + + /* + * FIELD-ID ::= TYPE-IDENTIFIER + * FieldTypes FIELD-ID ::= { + * { Prime-p IDENTIFIED BY prime-field } | + * { Characteristic-two IDENTIFIED BY characteristic-two-field } + * } + * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + */ + if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 ) + return( ret ); + + if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) || + memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) + { + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + } + + p += len; + + /* Prime-p ::= INTEGER -- Field of size p. */ + if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->pbits = mpi_msb( &grp->P ); + + if( p != end_field ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Curve ::= SEQUENCE { + * a FieldElement, + * b FieldElement, + * seed BIT STRING OPTIONAL + * -- Shall be present if used in SpecifiedECDomain + * -- with version equal to ecdpVer2 or ecdpVer3 + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_curve = p + len; + + /* + * FieldElement ::= OCTET STRING + * containing an integer in the case of a prime field + */ + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 || + ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 || + ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + /* Ignore seed BIT STRING OPTIONAL */ + if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 ) + p += len; + + if( p != end_curve ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * ECPoint ::= OCTET STRING + */ + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = ecp_point_read_binary( grp, &grp->G, + ( const unsigned char *) p, len ) ) != 0 ) + { + /* + * If we can't read the point because it's compressed, cheat by + * reading only the X coordinate and the parity bit of Y. + */ + if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE || + ( p[0] != 0x02 && p[0] != 0x03 ) || + len != mpi_size( &grp->P ) + 1 || + mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || + mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || + mpi_lset( &grp->G.Z, 1 ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + } + } + + p += len; + + /* + * order INTEGER + */ + if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->nbits = mpi_msb( &grp->N ); + + /* + * Allow optional elements by purposefully not enforcing p == end here. + */ + + return( 0 ); +} + +/* + * Find the group id associated with an (almost filled) group as generated by + * pk_group_from_specified(), or return an error if unknown. + */ +static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id ) +{ + int ret = 0; + ecp_group ref; + const ecp_group_id *id; + + ecp_group_init( &ref ); + + for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ ) + { + /* Load the group associated to that id */ + ecp_group_free( &ref ); + MPI_CHK( ecp_use_known_dp( &ref, *id ) ); + + /* Compare to the group we were given, starting with easy tests */ + if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && + mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && + mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && + mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && + mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && + mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && + mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && + /* For Y we may only know the parity bit, so compare only that */ + mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) ) + { + break; + } + + } + +cleanup: + ecp_group_free( &ref ); + + *grp_id = *id; + + if( ret == 0 && *id == POLARSSL_ECP_DP_NONE ) + ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE; + + return( ret ); +} + +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID + */ +static int pk_group_id_from_specified( const asn1_buf *params, + ecp_group_id *grp_id ) +{ + int ret; + ecp_group grp; + + ecp_group_init( &grp ); + + if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) + goto cleanup; + + ret = pk_group_id_from_group( &grp, grp_id ); + +cleanup: + ecp_group_free( &grp ); + + return( ret ); +} +#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */ + +/* + * Use EC parameters to initialise an EC group + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } + * -- implicitCurve NULL + */ +static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp ) +{ + int ret; + ecp_group_id grp_id; + + if( params->tag == ASN1_OID ) + { + if( oid_get_ec_grp( params, &grp_id ) != 0 ) + return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE ); + } + else + { +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) + return( ret ); +#else + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); +#endif + } + + /* + * grp may already be initilialized; if so, make sure IDs match + */ + if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + + if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * EC public key is an EC point + * + * The caller is responsible for clearing the structure upon failure if + * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE + * return code of ecp_point_read_binary() and leave p in a usable state. + */ +static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, + ecp_keypair *key ) +{ + int ret; + + if( ( ret = ecp_point_read_binary( &key->grp, &key->Q, + (const unsigned char *) *p, end - *p ) ) == 0 ) + { + ret = ecp_check_pubkey( &key->grp, &key->Q ); + } + + /* + * We know ecp_point_read_binary consumed all bytes or failed + */ + *p = (unsigned char *) end; + + return( ret ); +} +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int pk_get_rsapubkey( unsigned char **p, + const unsigned char *end, + rsa_context *rsa ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 || + ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p != end ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = rsa_check_pubkey( rsa ) ) != 0 ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY ); + + rsa->len = mpi_size( &rsa->N ); + + return( 0 ); +} +#endif /* POLARSSL_RSA_C */ + +/* Get a PK algorithm identifier + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ +static int pk_get_pk_alg( unsigned char **p, + const unsigned char *end, + pk_type_t *pk_alg, asn1_buf *params ) +{ + int ret; + asn1_buf alg_oid; + + memset( params, 0, sizeof(asn1_buf) ); + + if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) + return( POLARSSL_ERR_PK_INVALID_ALG + ret ); + + if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + /* + * No parameters with RSA (only for EC) + */ + if( *pk_alg == POLARSSL_PK_RSA && + ( ( params->tag != ASN1_NULL && params->tag != 0 ) || + params->len != 0 ) ) + { + return( POLARSSL_ERR_PK_INVALID_ALG ); + } + + return( 0 ); +} + +/* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ +int pk_parse_subpubkey( unsigned char **p, const unsigned char *end, + pk_context *pk ) +{ + int ret; + size_t len; + asn1_buf alg_params; + pk_type_t pk_alg = POLARSSL_PK_NONE; + const pk_info_t *pk_info; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = *p + len; + + if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) + return( ret ); + + if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_PK_INVALID_PUBKEY + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ) + return( ret ); + +#if defined(POLARSSL_RSA_C) + if( pk_alg == POLARSSL_PK_RSA ) + { + ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) ); + } else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY ) + { + ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp ); + if( ret == 0 ) + ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) ); + } else +#endif /* POLARSSL_ECP_C */ + ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG; + + if( ret == 0 && *p != end ) + ret = POLARSSL_ERR_PK_INVALID_PUBKEY + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + if( ret != 0 ) + pk_free( pk ); + + return( ret ); +} + +#if defined(POLARSSL_RSA_C) +/* + * Parse a PKCS#1 encoded private RSA key + */ +static int pk_parse_key_pkcs1_der( rsa_context *rsa, + const unsigned char *key, + size_t keylen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + + p = (unsigned char *) key; + end = p + keylen; + + /* + * This function parses the RSAPrivateKey (PKCS#1) + * + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + if( rsa->ver != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_VERSION ); + } + + if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) + { + rsa_free( rsa ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + rsa->len = mpi_size( &rsa->N ); + + if( p != end ) + { + rsa_free( rsa ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + if( ( ret = rsa_check_privkey( rsa ) ) != 0 ) + { + rsa_free( rsa ); + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * Parse a SEC1 encoded private EC key + */ +static int pk_parse_key_sec1_der( ecp_keypair *eck, + const unsigned char *key, + size_t keylen ) +{ + int ret; + int version, pubkey_done; + size_t len; + asn1_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + unsigned char *end2; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( version != 1 ) + return( POLARSSL_ERR_PK_KEY_INVALID_VERSION ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + /* + * Is 'parameters' present? + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || + ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( ret ); + } + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + /* + * Is 'publickey' present? If not, or if we can't read it (eg because it + * is compressed), create it from the private key. + */ + pubkey_done = 0; + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( p + len != end2 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) + pubkey_done = 1; + else + { + /* + * The only acceptable failure mode of pk_get_ecpubkey() above + * is if the point format is not recognized. + */ + if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); + } + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + if( ! pubkey_done && + ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, + NULL, NULL ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) + { + ecp_keypair_free( eck ); + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_ECP_C */ + +/* + * Parse an unencrypted PKCS#8 encoded private key + */ +static int pk_parse_key_pkcs8_unencrypted_der( + pk_context *pk, + const unsigned char* key, + size_t keylen ) +{ + int ret, version; + size_t len; + asn1_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + pk_type_t pk_alg = POLARSSL_PK_NONE; + const pk_info_t *pk_info; + + /* + * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) + * + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * Version ::= INTEGER + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * PrivateKey ::= OCTET STRING + * + * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey + */ + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( version != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret ); + + if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( len < 1 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ) + return( ret ); + +#if defined(POLARSSL_RSA_C) + if( pk_alg == POLARSSL_PK_RSA ) + { + if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 ) + { + pk_free( pk ); + return( ret ); + } + } else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH ) + { + if( ( ret = pk_use_ecparams( ¶ms, &pk_ec( *pk )->grp ) ) != 0 || + ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 ) + { + pk_free( pk ); + return( ret ); + } + } else +#endif /* POLARSSL_ECP_C */ + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + return( 0 ); +} + +/* + * Parse an encrypted PKCS#8 encoded private key + */ +static int pk_parse_key_pkcs8_encrypted_der( + pk_context *pk, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) +{ + int ret, decrypted = 0; + size_t len; + unsigned char buf[2048]; + unsigned char *p, *end; + asn1_buf pbe_alg_oid, pbe_params; +#if defined(POLARSSL_PKCS12_C) + cipher_type_t cipher_alg; + md_type_t md_alg; +#endif + + memset( buf, 0, sizeof( buf ) ); + + p = (unsigned char *) key; + end = p + keylen; + + if( pwdlen == 0 ) + return( POLARSSL_ERR_PK_PASSWORD_REQUIRED ); + + /* + * This function parses the EncryptedPrivatKeyInfo object (PKCS#8) + * + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm EncryptionAlgorithmIdentifier, + * encryptedData EncryptedData + * } + * + * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * + * EncryptedData ::= OCTET STRING + * + * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( len > sizeof( buf ) ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + /* + * Decrypt EncryptedData with appropriate PDE + */ +#if defined(POLARSSL_PKCS12_C) + if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) + { + if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT, + cipher_alg, md_alg, + pwd, pwdlen, p, len, buf ) ) != 0 ) + { + if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH ) + return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + + return( ret ); + } + + decrypted = 1; + } + else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) ) + { + if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params, + PKCS12_PBE_DECRYPT, + pwd, pwdlen, + p, len, buf ) ) != 0 ) + { + return( ret ); + } + + // Best guess for password mismatch when using RC4. If first tag is + // not ASN1_CONSTRUCTED | ASN1_SEQUENCE + // + if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + + decrypted = 1; + } + else +#endif /* POLARSSL_PKCS12_C */ +#if defined(POLARSSL_PKCS5_C) + if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) ) + { + if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen, + p, len, buf ) ) != 0 ) + { + if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH ) + return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + + return( ret ); + } + + decrypted = 1; + } + else +#endif /* POLARSSL_PKCS5_C */ + { + ((void) pwd); + } + + if( decrypted == 0 ) + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); +} + +/* + * Parse a private key + */ +int pk_parse_key( pk_context *pk, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) +{ + int ret; + const pk_info_t *pk_info; + +#if defined(POLARSSL_PEM_PARSE_C) + size_t len; + pem_context pem; + + pem_init( &pem ); + +#if defined(POLARSSL_RSA_C) + ret = pem_read_buffer( &pem, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + key, pwd, pwdlen, &len ); + if( ret == 0 ) + { + if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), + pem.buf, pem.buflen ) ) != 0 ) + { + pk_free( pk ); + } + + pem_free( &pem ); + return( ret ); + } + else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH ) + return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED ) + return( POLARSSL_ERR_PK_PASSWORD_REQUIRED ); + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) + ret = pem_read_buffer( &pem, + "-----BEGIN EC PRIVATE KEY-----", + "-----END EC PRIVATE KEY-----", + key, pwd, pwdlen, &len ); + if( ret == 0 ) + { + if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), + pem.buf, pem.buflen ) ) != 0 ) + { + pk_free( pk ); + } + + pem_free( &pem ); + return( ret ); + } + else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH ) + return( POLARSSL_ERR_PK_PASSWORD_MISMATCH ); + else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED ) + return( POLARSSL_ERR_PK_PASSWORD_REQUIRED ); + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#endif /* POLARSSL_ECP_C */ + + ret = pem_read_buffer( &pem, + "-----BEGIN PRIVATE KEY-----", + "-----END PRIVATE KEY-----", + key, NULL, 0, &len ); + if( ret == 0 ) + { + if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, + pem.buf, pem.buflen ) ) != 0 ) + { + pk_free( pk ); + } + + pem_free( &pem ); + return( ret ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); + + ret = pem_read_buffer( &pem, + "-----BEGIN ENCRYPTED PRIVATE KEY-----", + "-----END ENCRYPTED PRIVATE KEY-----", + key, NULL, 0, &len ); + if( ret == 0 ) + { + if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, + pem.buf, pem.buflen, + pwd, pwdlen ) ) != 0 ) + { + pk_free( pk ); + } + + pem_free( &pem ); + return( ret ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#else + ((void) pwd); + ((void) pwdlen); +#endif /* POLARSSL_PEM_PARSE_C */ + + /* + * At this point we only know it's not a PEM formatted key. Could be any + * of the known DER encoded private key formats + * + * We try the different DER format parsers to see if one passes without + * error + */ + if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen, + pwd, pwdlen ) ) == 0 ) + { + return( 0 ); + } + + pk_free( pk ); + + if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH ) + { + return( ret ); + } + + if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) + return( 0 ); + + pk_free( pk ); + +#if defined(POLARSSL_RSA_C) + if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 ) + { + return( 0 ); + } + + pk_free( pk ); +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) + if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL ) + return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 ) + { + return( 0 ); + } + + pk_free( pk ); +#endif /* POLARSSL_ECP_C */ + + return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT ); +} + +/* + * Parse a public key + */ +int pk_parse_public_key( pk_context *ctx, + const unsigned char *key, size_t keylen ) +{ + int ret; + unsigned char *p; +#if defined(POLARSSL_PEM_PARSE_C) + size_t len; + pem_context pem; + + pem_init( &pem ); + ret = pem_read_buffer( &pem, + "-----BEGIN PUBLIC KEY-----", + "-----END PUBLIC KEY-----", + key, NULL, 0, &len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + key = pem.buf; + keylen = pem.buflen; + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + return( ret ); + } +#endif /* POLARSSL_PEM_PARSE_C */ + p = (unsigned char *) key; + + ret = pk_parse_subpubkey( &p, p + keylen, ctx ); + +#if defined(POLARSSL_PEM_PARSE_C) + pem_free( &pem ); +#endif + + return( ret ); +} + +#endif /* POLARSSL_PK_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkwrite.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkwrite.c new file mode 100644 index 0000000..3b0bbdb --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/pkwrite.c @@ -0,0 +1,358 @@ +/* + * Public Key layer for writing key files and structures + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_WRITE_C) + +#include "polarssl/pk.h" +#include "polarssl/asn1write.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif +#if defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#if defined(POLARSSL_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, + rsa_context *rsa ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * EC public key is an EC point + */ +static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, + ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + unsigned char buf[POLARSSL_ECP_MAX_PT_LEN]; + + if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q, + POLARSSL_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof( buf ) ) ) != 0 ) + { + return( ret ); + } + + if( *p - start < (int) len ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *p -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +/* + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * } + */ +static int pk_write_ec_param( unsigned char **p, unsigned char *start, + ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + const char *oid; + size_t oid_len; + + if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) + return( ret ); + + ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); + + return( (int) len ); +} +#endif /* POLARSSL_ECP_C */ + +int pk_write_pubkey( unsigned char **p, unsigned char *start, + const pk_context *key ) +{ + int ret; + size_t len = 0; + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) ); + else +#endif +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) ); + else +#endif + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c; + size_t len = 0, par_len = 0, oid_len; + const char *oid; + + c = buf + size; + + ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) ); + + if( c - buf < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + /* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + *--c = 0; + len += 1; + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); + + if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), + &oid, &oid_len ) ) != 0 ) + { + return( ret ); + } + +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) ); + } +#endif + + ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, + par_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c = buf + size; + size_t len = 0; + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + { + rsa_context *rsa = pk_rsa( *key ); + + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) ); + ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + } + else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + ecp_keypair *ec = pk_ec( *key ); + size_t pub_len = 0, par_len = 0; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + + /* publicKey */ + ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); + + if( c - buf < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + *--c = 0; + pub_len += 1; + + ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); + ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); + + ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); + ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ); + len += pub_len; + + /* parameters */ + ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); + + ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) ); + ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); + len += par_len; + + /* privateKey: write as MPI then fix tag */ + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) ); + *c = ASN1_OCTET_STRING; + + /* version */ + ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + } + else +#endif /* POLARSSL_ECP_C */ + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +#if defined(POLARSSL_PEM_WRITE_C) + +#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" +#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" + +#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" +#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" + +int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = pk_write_pubkey_der( key, output_buf, + sizeof(output_buf) ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[4096]; + const char *begin, *end; + size_t olen = 0; + + if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) + return( ret ); + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + { + begin = PEM_BEGIN_PRIVATE_KEY_RSA; + end = PEM_END_PRIVATE_KEY_RSA; + } + else +#endif +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + begin = PEM_BEGIN_PRIVATE_KEY_EC; + end = PEM_END_PRIVATE_KEY_EC; + } + else +#endif + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + if( ( ret = pem_write_buffer( begin, end, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ + +#endif /* POLARSSL_PK_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/platform.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/platform.c new file mode 100644 index 0000000..d57cbc8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/platform.c @@ -0,0 +1,116 @@ +/* + * Platform abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PLATFORM_C) + +#include "polarssl/platform.h" + +#if defined(POLARSSL_PLATFORM_MEMORY) +#if !defined(POLARSSL_PLATFORM_STD_MALLOC) +static void *platform_malloc_uninit( size_t len ) +{ + ((void) len); + return( NULL ); +} + +#define POLARSSL_PLATFORM_STD_MALLOC platform_malloc_uninit +#endif /* !POLARSSL_PLATFORM_STD_MALLOC */ + +#if !defined(POLARSSL_PLATFORM_STD_FREE) +static void platform_free_uninit( void *ptr ) +{ + ((void) ptr); +} + +#define POLARSSL_PLATFORM_STD_FREE platform_free_uninit +#endif /* !POLARSSL_PLATFORM_STD_FREE */ + +void * (*polarssl_malloc)( size_t ) = POLARSSL_PLATFORM_STD_MALLOC; +void (*polarssl_free)( void * ) = POLARSSL_PLATFORM_STD_FREE; + +int platform_set_malloc_free( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ) +{ + polarssl_malloc = malloc_func; + polarssl_free = free_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_MEMORY */ + +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) +#if !defined(POLARSSL_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit( const char *format, ... ) +{ + ((void) format); + return( 0 ); +} + +#define POLARSSL_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !POLARSSL_PLATFORM_STD_PRINTF */ + +int (*polarssl_printf)( const char *, ... ) = POLARSSL_PLATFORM_STD_PRINTF; + +int platform_set_printf( int (*printf_func)( const char *, ... ) ) +{ + polarssl_printf = printf_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ + +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) +#if !defined(POLARSSL_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) +{ + ((void) stream); + ((void) format); + return( 0 ); +} + +#define POLARSSL_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !POLARSSL_PLATFORM_STD_FPRINTF */ + +int (*polarssl_fprintf)( FILE *, const char *, ... ) = + POLARSSL_PLATFORM_STD_FPRINTF; + +int platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) +{ + polarssl_fprintf = fprintf_func; + return( 0 ); +} +#endif /* POLARSSL_PLATFORM_FPRINTF_ALT */ + +#endif /* POLARSSL_PLATFORM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ripemd160.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ripemd160.c new file mode 100644 index 0000000..fcd7760 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ripemd160.c @@ -0,0 +1,653 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2014-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_RIPEMD160_C) + +#include "polarssl/ripemd160.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void ripemd160_init( ripemd160_context *ctx ) +{ + memset( ctx, 0, sizeof( ripemd160_context ) ); +} + +void ripemd160_free( ripemd160_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( ripemd160_context ) ); +} + +/* + * RIPEMD-160 context setup + */ +void ripemd160_starts( ripemd160_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +/* + * Process one block + */ +void ripemd160_process( ripemd160_context *ctx, const unsigned char data[64] ) +{ + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + ctx->state[0] = C; +} + +/* + * RIPEMD-160 process buffer + */ +void ripemd160_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + ripemd160_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + ripemd160_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char ripemd160_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * RIPEMD-160 final digest + */ +void ripemd160_finish( ripemd160_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + ripemd160_update( ctx, ripemd160_padding, padn ); + ripemd160_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); +} + +/* + * output = RIPEMD-160( input buffer ) + */ +void ripemd160( const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + ripemd160_context ctx; + + ripemd160_init( &ctx ); + ripemd160_starts( &ctx ); + ripemd160_update( &ctx, input, ilen ); + ripemd160_finish( &ctx, output ); + ripemd160_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = RIPEMD-160( file contents ) + */ +int ripemd160_file( const char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + ripemd160_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR ); + + ripemd160_init( &ctx ); + ripemd160_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + ripemd160_update( &ctx, buf, n ); + + ripemd160_finish( &ctx, output ); + ripemd160_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_RIPEMD160_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * RIPEMD-160 HMAC context setup + */ +void ripemd160_hmac_starts( ripemd160_context *ctx, + const unsigned char *key, size_t keylen ) +{ + size_t i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + ripemd160( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * RIPEMD-160 HMAC process buffer + */ +void ripemd160_hmac_update( ripemd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + ripemd160_update( ctx, input, ilen ); +} + +/* + * RIPEMD-160 HMAC final digest + */ +void ripemd160_hmac_finish( ripemd160_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + ripemd160_finish( ctx, tmpbuf ); + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->opad, 64 ); + ripemd160_update( ctx, tmpbuf, 20 ); + ripemd160_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * RIPEMD-160 HMAC context reset + */ +void ripemd160_hmac_reset( ripemd160_context *ctx ) +{ + ripemd160_starts( ctx ); + ripemd160_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-RIPEMD-160( hmac key, input buffer ) + */ +void ripemd160_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + ripemd160_context ctx; + + ripemd160_init( &ctx ); + ripemd160_hmac_starts( &ctx, key, keylen ); + ripemd160_hmac_update( &ctx, input, ilen ); + ripemd160_hmac_finish( &ctx, output ); + ripemd160_free( &ctx ); +} + + +#if defined(POLARSSL_SELF_TEST) +/* + * Test vectors from the RIPEMD-160 paper and + * http://homes.esat.kuleuven.be/~bosselae/ripemd160.html#HMAC + */ +#define TESTS 8 +#define KEYS 2 +static const char *ripemd160_test_input[TESTS] = +{ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", +}; + +static const unsigned char ripemd160_test_md[TESTS][20] = +{ + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, + { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, + 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, + { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, + 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, +}; + +static const unsigned char ripemd160_test_hmac[KEYS][TESTS][20] = +{ + { + { 0xcf, 0x38, 0x76, 0x77, 0xbf, 0xda, 0x84, 0x83, 0xe6, 0x3b, + 0x57, 0xe0, 0x6c, 0x3b, 0x5e, 0xcd, 0x8b, 0x7f, 0xc0, 0x55 }, + { 0x0d, 0x35, 0x1d, 0x71, 0xb7, 0x8e, 0x36, 0xdb, 0xb7, 0x39, + 0x1c, 0x81, 0x0a, 0x0d, 0x2b, 0x62, 0x40, 0xdd, 0xba, 0xfc }, + { 0xf7, 0xef, 0x28, 0x8c, 0xb1, 0xbb, 0xcc, 0x61, 0x60, 0xd7, + 0x65, 0x07, 0xe0, 0xa3, 0xbb, 0xf7, 0x12, 0xfb, 0x67, 0xd6 }, + { 0xf8, 0x36, 0x62, 0xcc, 0x8d, 0x33, 0x9c, 0x22, 0x7e, 0x60, + 0x0f, 0xcd, 0x63, 0x6c, 0x57, 0xd2, 0x57, 0x1b, 0x1c, 0x34 }, + { 0x84, 0x3d, 0x1c, 0x4e, 0xb8, 0x80, 0xac, 0x8a, 0xc0, 0xc9, + 0xc9, 0x56, 0x96, 0x50, 0x79, 0x57, 0xd0, 0x15, 0x5d, 0xdb }, + { 0x60, 0xf5, 0xef, 0x19, 0x8a, 0x2d, 0xd5, 0x74, 0x55, 0x45, + 0xc1, 0xf0, 0xc4, 0x7a, 0xa3, 0xfb, 0x57, 0x76, 0xf8, 0x81 }, + { 0xe4, 0x9c, 0x13, 0x6a, 0x9e, 0x56, 0x27, 0xe0, 0x68, 0x1b, + 0x80, 0x8a, 0x3b, 0x97, 0xe6, 0xa6, 0xe6, 0x61, 0xae, 0x79 }, + { 0x31, 0xbe, 0x3c, 0xc9, 0x8c, 0xee, 0x37, 0xb7, 0x9b, 0x06, + 0x19, 0xe3, 0xe1, 0xc2, 0xbe, 0x4f, 0x1a, 0xa5, 0x6e, 0x6c }, + }, + { + { 0xfe, 0x69, 0xa6, 0x6c, 0x74, 0x23, 0xee, 0xa9, 0xc8, 0xfa, + 0x2e, 0xff, 0x8d, 0x9d, 0xaf, 0xb4, 0xf1, 0x7a, 0x62, 0xf5 }, + { 0x85, 0x74, 0x3e, 0x89, 0x9b, 0xc8, 0x2d, 0xbf, 0xa3, 0x6f, + 0xaa, 0xa7, 0xa2, 0x5b, 0x7c, 0xfd, 0x37, 0x24, 0x32, 0xcd }, + { 0x6e, 0x4a, 0xfd, 0x50, 0x1f, 0xa6, 0xb4, 0xa1, 0x82, 0x3c, + 0xa3, 0xb1, 0x0b, 0xd9, 0xaa, 0x0b, 0xa9, 0x7b, 0xa1, 0x82 }, + { 0x2e, 0x06, 0x6e, 0x62, 0x4b, 0xad, 0xb7, 0x6a, 0x18, 0x4c, + 0x8f, 0x90, 0xfb, 0xa0, 0x53, 0x33, 0x0e, 0x65, 0x0e, 0x92 }, + { 0x07, 0xe9, 0x42, 0xaa, 0x4e, 0x3c, 0xd7, 0xc0, 0x4d, 0xed, + 0xc1, 0xd4, 0x6e, 0x2e, 0x8c, 0xc4, 0xc7, 0x41, 0xb3, 0xd9 }, + { 0xb6, 0x58, 0x23, 0x18, 0xdd, 0xcf, 0xb6, 0x7a, 0x53, 0xa6, + 0x7d, 0x67, 0x6b, 0x8a, 0xd8, 0x69, 0xad, 0xed, 0x62, 0x9a }, + { 0xf1, 0xbe, 0x3e, 0xe8, 0x77, 0x70, 0x31, 0x40, 0xd3, 0x4f, + 0x97, 0xea, 0x1a, 0xb3, 0xa0, 0x7c, 0x14, 0x13, 0x33, 0xe2 }, + { 0x85, 0xf1, 0x64, 0x70, 0x3e, 0x61, 0xa6, 0x31, 0x31, 0xbe, + 0x7e, 0x45, 0x95, 0x8e, 0x07, 0x94, 0x12, 0x39, 0x04, 0xf9 }, + }, +}; + +static const unsigned char ripemd160_test_key[KEYS][20] = +{ + { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, + 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x23, 0x45, 0x67 }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, + 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33 }, +}; + +/* + * Checkup routine + */ +int ripemd160_self_test( int verbose ) +{ + int i, j; + unsigned char output[20]; + + memset( output, 0, sizeof output ); + + for( i = 0; i < TESTS; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " RIPEMD-160 test #%d: ", i + 1 ); + + ripemd160( (const unsigned char *) ripemd160_test_input[i], + strlen( ripemd160_test_input[i] ), + output ); + + if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + for( j = 0; j < KEYS; j++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-RIPEMD-160 test #%d, key #%d: ", + i + 1, j + 1 ); + + ripemd160_hmac( ripemd160_test_key[j], 20, + (const unsigned char *) ripemd160_test_input[i], + strlen( ripemd160_test_input[i] ), + output ); + + if( memcmp( output, ripemd160_test_hmac[j][i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + } + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_RIPEMD160_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/Makefile b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/Makefile new file mode 100644 index 0000000..32d4957 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/Makefile @@ -0,0 +1,73 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +#*****************************************************************************# +# VARIABLES # +#*****************************************************************************# + + +MODULE_IFLAGS += -I../../include -fno-tree-switch-conversion + +GLOBAL_CFLAGS += -DCONFIG_SSL_ROM + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = + +ROM_CSRC = aes.o \ + arc4.o \ + asn1parse.o \ + asn1write.o \ + base64.o \ + bignum.o \ + ctr_drbg.o \ + des.o \ + dhm.o \ + ecdh.o \ + ecdsa.o \ + ecp.o \ + ecp_curves.o \ + hmac_drbg.o \ + md.o \ + md_wrap.o \ + md5.o \ + oid.o \ + pem.o \ + pk.o \ + pk_wrap.o \ + pkwrite.o \ + rsa.o \ + sha1.o \ + sha256.o \ + sha512.o \ + ../../../ssl_ram_map/rom/rom_ssl_ram_map.o + +OBJS = $(ROM_CSRC) + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS RENAME_ROM_OBJS COPY_ROM_OBJS + + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) $(ASM_OBJS) + + +#*****************************************************************************# +# RULES TO CLEAN TARGETS # +#*****************************************************************************# +clean: + $(REMOVE) *.o + $(REMOVE) *.i + $(REMOVE) *.s + $(REMOVE) *.d + +-include $(DEPS) diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/aes.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/aes.c new file mode 100644 index 0000000..12afa76 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/aes.c @@ -0,0 +1,1625 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#ifdef RTL_HW_CRYPTO +#include +#endif + +#if defined(POLARSSL_AES_C) + +#include "polarssl/aes.h" +#if defined(POLARSSL_PADLOCK_C) +#include "polarssl/padlock.h" +#endif +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_AES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#ifdef SUPPORT_HW_SW_CRYPTO + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +#if defined(POLARSSL_PADLOCK_C) && \ + ( defined(POLARSSL_HAVE_X86) || defined(PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(POLARSSL_AES_ROM_TABLES) +/* + * Forward S-box + */ +SSL_ROM_DATA_SECTION +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +SSL_ROM_DATA_SECTION +static const uint32_t FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +SSL_ROM_DATA_SECTION +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +SSL_ROM_DATA_SECTION +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +SSL_ROM_DATA_SECTION +static const uint32_t FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +SSL_ROM_DATA_SECTION +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +SSL_ROM_DATA_SECTION +static const uint32_t RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +SSL_ROM_DATA_SECTION +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +SSL_ROM_DATA_SECTION +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +SSL_ROM_DATA_SECTION +static const uint32_t RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +SSL_ROM_DATA_SECTION +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* POLARSSL_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +SSL_ROM_TEXT_SECTION +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif /* POLARSSL_AES_ROM_TABLES */ +#endif /* SUPPORT_HW_SW_CRYPTO */ + +SSL_ROM_TEXT_SECTION +void aes_init( aes_context *ctx ) +{ + memset( ctx, 0, sizeof( aes_context ) ); +} + +SSL_ROM_TEXT_SECTION +void aes_free( aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( aes_context ) ); +} + +/* + * AES key schedule (encryption) + */ +SSL_ROM_TEXT_SECTION +int aes_setkey_enc( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + switch(keysize) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return(POLARSSL_ERR_AES_INVALID_KEY_LENGTH); + } + + memcpy(ctx->enc_key, key, (keysize / 8)); + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + unsigned int i; + uint32_t *RK; + +#if !defined(POLARSSL_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + + } +#endif + + switch( keysize ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = padlock_supports( PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_setkey_enc( (unsigned char *) ctx->rk, key, keysize ) ); +#endif + + for( i = 0; i < ( keysize >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +/* + * AES key schedule (decryption) + */ +SSL_ROM_TEXT_SECTION +int aes_setkey_dec( aes_context *ctx, const unsigned char *key, + unsigned int keysize ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + switch(keysize) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return(POLARSSL_ERR_AES_INVALID_KEY_LENGTH); + } + + memcpy(ctx->dec_key, key, (keysize / 8)); + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i, j, ret; + aes_context cty; + uint32_t *RK; + uint32_t *SK; + + aes_init( &cty ); + +#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = padlock_supports( PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keysize */ + if( ( ret = aes_setkey_enc( &cty, key, keysize ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + { + aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + aes_free( &cty ); + + return( ret ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int aes_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[32 + 4], *key_buf_aligned; + unsigned char *output_buf[16 + 4], *output_buf_aligned; + + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memset(output_buf, 0, 16 + 4); + + if(mode == AES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_init(key_buf_aligned, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_decrypt(input, 16, NULL, 0, output_buf_aligned); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_init(key_buf_aligned,((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_ecb_encrypt(input, 16, NULL, 0, output_buf_aligned); + } + + memcpy(output, output_buf_aligned, 16); + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supports( POLARSSL_AESNI_AES ) ) + return( aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( aes_padlock_ace ) + { + if( padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + if( mode == AES_DECRYPT ) + { + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + } + else /* AES_ENCRYPT */ + { + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + } + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int aes_crypt_cbc( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[32 + 4], *key_buf_aligned; + unsigned char iv_buf[16 + 4], *iv_buf_aligned, iv_tmp[16]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 16) + return(POLARSSL_ERR_AES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 16); + memset(output_buf, 0, length + 4); + + if(mode == AES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_cbc_init(key_buf_aligned, ((ctx->nr - 6) * 4)); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 16), 16); + rom_ssl_ram_map.hw_crypto_aes_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 16); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 16), 16); + rom_ssl_ram_map.hw_crypto_aes_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 16); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, ((ctx->nr - 6) * 4)); + rom_ssl_ram_map.hw_crypto_aes_cbc_init(key_buf_aligned,((ctx->nr - 6) * 4)); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_aes_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 16), 16); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_aes_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 16, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 16), 16); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) + if( aes_padlock_ace ) + { + if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int aes_crypt_cfb128( aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +#include +SSL_ROM_TEXT_SECTION +int aes_crypt_cfb8( aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv ); + + if( mode == AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /*POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int aes_crypt_ctr( aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + aes_crypt_ecb( ctx, AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +#endif /* !POLARSSL_AES_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char iv[16]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + aes_context ctx; + + memset( key, 0, 32 ); + aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CTR-128 (%s): ", + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 ); + + if( v == AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + aes_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_AES_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/arc4.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/arc4.c new file mode 100644 index 0000000..52781d8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/arc4.c @@ -0,0 +1,213 @@ +/* + * An implementation of the ARCFOUR algorithm + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ARCFOUR algorithm was publicly disclosed on 94/09. + * + * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ARC4_C) + +#include "polarssl/arc4.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_ARC4_ALT) + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +SSL_ROM_TEXT_SECTION +void arc4_init( arc4_context *ctx ) +{ + memset( ctx, 0, sizeof( arc4_context ) ); +} + +SSL_ROM_TEXT_SECTION +void arc4_free( arc4_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( arc4_context ) ); +} + +/* + * ARC4 key schedule + */ +SSL_ROM_TEXT_SECTION +void arc4_setup( arc4_context *ctx, const unsigned char *key, + unsigned int keylen ) +{ + int i, j, a; + unsigned int k; + unsigned char *m; + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for( i = 0; i < 256; i++ ) + m[i] = (unsigned char) i; + + j = k = 0; + + for( i = 0; i < 256; i++, k++ ) + { + if( k >= keylen ) k = 0; + + a = m[i]; + j = ( j + a + key[k] ) & 0xFF; + m[i] = m[j]; + m[j] = (unsigned char) a; + } +} + +/* + * ARC4 cipher function + */ +SSL_ROM_TEXT_SECTION +int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input, + unsigned char *output ) +{ + int x, y, a, b; + size_t i; + unsigned char *m; + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for( i = 0; i < length; i++ ) + { + x = ( x + 1 ) & 0xFF; a = m[x]; + y = ( y + a ) & 0xFF; b = m[y]; + + m[x] = (unsigned char) b; + m[y] = (unsigned char) a; + + output[i] = (unsigned char) + ( input[i] ^ m[(unsigned char)( a + b )] ); + } + + ctx->x = x; + ctx->y = y; + + return( 0 ); +} + +#endif /* !POLARSSL_ARC4_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +/* + * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: + * + * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 + */ +static const unsigned char arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +/* + * Checkup routine + */ +int arc4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char ibuf[8]; + unsigned char obuf[8]; + arc4_context ctx; + + arc4_init( &ctx ); + + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " ARC4 test #%d: ", i + 1 ); + + memcpy( ibuf, arc4_test_pt[i], 8 ); + + arc4_setup( &ctx, arc4_test_key[i], 8 ); + arc4_crypt( &ctx, 8, ibuf, obuf ); + + if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + arc4_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ARC4_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1parse.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1parse.c new file mode 100644 index 0000000..d1c0bab --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1parse.c @@ -0,0 +1,404 @@ +/* + * Generic ASN.1 parsing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ASN1_PARSE_C) + +#include "polarssl/asn1.h" + +#if defined(POLARSSL_BIGNUM_C) +#include "polarssl/bignum.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include + +/* + * ASN.1 DER decoding routines + */ +SSL_ROM_TEXT_SECTION +int asn1_get_len( unsigned char **p, + const unsigned char *end, + size_t *len ) +{ + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( ( **p & 0x80 ) == 0 ) + *len = *(*p)++; + else + { + switch( **p & 0x7F ) + { + case 1: + if( ( end - *p ) < 2 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = (*p)[1]; + (*p) += 2; + break; + + case 2: + if( ( end - *p ) < 3 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 8 ) | (*p)[2]; + (*p) += 3; + break; + + case 3: + if( ( end - *p ) < 4 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 16 ) | ( (*p)[2] << 8 ) | (*p)[3]; + (*p) += 4; + break; + + case 4: + if( ( end - *p ) < 5 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (*p)[1] << 24 ) | ( (*p)[2] << 16 ) | ( (*p)[3] << 8 ) | + (*p)[4]; + (*p) += 5; + break; + + default: + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + } + } + + if( *len > (size_t) ( end - *p ) ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_get_tag( unsigned char **p, + const unsigned char *end, + size_t *len, int tag ) +{ + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( **p != tag ) + return( POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + (*p)++; + + return( asn1_get_len( p, end, len ) ); +} + +SSL_ROM_TEXT_SECTION +int asn1_get_bool( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 ) + return( ret ); + + if( len != 1 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + *val = ( **p != 0 ) ? 1 : 0; + (*p)++; + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_get_int( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) + return( ret ); + + if( len > sizeof( int ) || ( **p & 0x80 ) != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + *val = 0; + + while( len-- > 0 ) + { + *val = ( *val << 8 ) | **p; + (*p)++; + } + + return( 0 ); +} + +#if defined(POLARSSL_BIGNUM_C) +SSL_ROM_TEXT_SECTION +int asn1_get_mpi( unsigned char **p, + const unsigned char *end, + mpi *X ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) + return( ret ); + + ret = mpi_read_binary( X, *p, len ); + + *p += len; + + return( ret ); +} +#endif /* POLARSSL_BIGNUM_C */ + +SSL_ROM_TEXT_SECTION +int asn1_get_bitstring( unsigned char **p, const unsigned char *end, + asn1_bitstring *bs) +{ + int ret; + + /* Certificate type is a single byte bitstring */ + if( ( ret = asn1_get_tag( p, end, &bs->len, ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + /* Check length, subtract one for actual bit string length */ + if( bs->len < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + bs->len -= 1; + + /* Get number of unused bits, ensure unused bits <= 7 */ + bs->unused_bits = **p; + if( bs->unused_bits > 7 ) + return( POLARSSL_ERR_ASN1_INVALID_LENGTH ); + (*p)++; + + /* Get actual bitstring */ + bs->p = *p; + *p += bs->len; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Get a bit string without unused bits + */ +SSL_ROM_TEXT_SECTION +int asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ) +{ + int ret; + + if( ( ret = asn1_get_tag( p, end, len, ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + if( (*len)-- < 2 || *(*p)++ != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + + + +/* + * Parses and splits an ASN.1 "SEQUENCE OF " + */ +SSL_ROM_TEXT_SECTION +int asn1_get_sequence_of( unsigned char **p, + const unsigned char *end, + asn1_sequence *cur, + int tag) +{ + int ret; + size_t len; + asn1_buf *buf; + + /* Get main sequence tag */ + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + buf = &(cur->buf); + buf->tag = **p; + + if( ( ret = asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) + return( ret ); + + buf->p = *p; + *p += buf->len; + + /* Allocate and assign next pointer */ + if( *p < end ) + { + cur->next = (asn1_sequence *) polarssl_malloc( + sizeof( asn1_sequence ) ); + + if( cur->next == NULL ) + return( POLARSSL_ERR_ASN1_MALLOC_FAILED ); + + cur = cur->next; + } + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_get_alg( unsigned char **p, + const unsigned char *end, + asn1_buf *alg, asn1_buf *params ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + alg->tag = **p; + end = *p + len; + + if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 ) + return( ret ); + + alg->p = *p; + *p += alg->len; + + if( *p == end ) + { + memset( params, 0, sizeof(asn1_buf) ); + return( 0 ); + } + + params->tag = **p; + (*p)++; + + if( ( ret = asn1_get_len( p, end, ¶ms->len ) ) != 0 ) + return( ret ); + + params->p = *p; + *p += params->len; + + if( *p != end ) + return( POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_get_alg_null( unsigned char **p, + const unsigned char *end, + asn1_buf *alg ) +{ + int ret; + asn1_buf params; + + memset( ¶ms, 0, sizeof(asn1_buf) ); + + if( ( ret = asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) + return( ret ); + + if( ( params.tag != ASN1_NULL && params.tag != 0 ) || params.len != 0 ) + return( POLARSSL_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +void asn1_free_named_data( asn1_named_data *cur ) +{ + if( cur == NULL ) + return; + + polarssl_free( cur->oid.p ); + polarssl_free( cur->val.p ); + + memset( cur, 0, sizeof( asn1_named_data ) ); +} + +SSL_ROM_TEXT_SECTION +void asn1_free_named_data_list( asn1_named_data **head ) +{ + asn1_named_data *cur; + + while( ( cur = *head ) != NULL ) + { + *head = cur->next; + asn1_free_named_data( cur ); + polarssl_free( cur ); + } +} + +SSL_ROM_TEXT_SECTION +asn1_named_data *asn1_find_named_data( asn1_named_data *list, + const char *oid, size_t len ) +{ + while( list != NULL ) + { + if( list->oid.len == len && + memcmp( list->oid.p, oid, len ) == 0 ) + { + break; + } + + list = list->next; + } + + return( list ); +} + +#endif /* POLARSSL_ASN1_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1write.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1write.c new file mode 100644 index 0000000..7614580 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/asn1write.c @@ -0,0 +1,380 @@ +/* + * ASN.1 buffer writing functionality + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ASN1_WRITE_C) + +#include "polarssl/asn1write.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +SSL_ROM_TEXT_SECTION +int asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) +{ + if( len < 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + return( 1 ); + } + + if( len <= 0xFF ) + { + if( *p - start < 2 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + *--(*p) = 0x81; + return( 2 ); + } + + if( *p - start < 3 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + // We assume we never have lengths larger than 65535 bytes + // + *--(*p) = len % 256; + *--(*p) = ( len / 256 ) % 256; + *--(*p) = 0x82; + + return( 3 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) +{ + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = tag; + + return( 1 ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_raw_buffer( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + size_t len = 0; + + if( *p - start < (int) size ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len = size; + (*p) -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +#if defined(POLARSSL_BIGNUM_C) +SSL_ROM_TEXT_SECTION +int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) +{ + int ret; + size_t len = 0; + + // Write the MPI + // + len = mpi_size( X ); + + if( *p - start < (int) len ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + (*p) -= len; + MPI_CHK( mpi_write_binary( X, *p, len ) ); + + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( X->s ==1 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); + + ret = (int) len; + +cleanup: + return( ret ); +} +#endif /* POLARSSL_BIGNUM_C */ + +SSL_ROM_TEXT_SECTION +int asn1_write_null( unsigned char **p, unsigned char *start ) +{ + int ret; + size_t len = 0; + + // Write NULL + // + ASN1_CHK_ADD( len, asn1_write_len( p, start, 0) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_NULL ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_oid( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) oid, oid_len ) ); + ASN1_CHK_ADD( len , asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len , asn1_write_tag( p, start, ASN1_OID ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len ) +{ + int ret; + size_t len = 0; + + if( par_len == 0 ) + ASN1_CHK_ADD( len, asn1_write_null( p, start ) ); + else + len += par_len; + + ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) +{ + int ret; + size_t len = 0; + + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (boolean) ? 1 : 0; + len++; + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BOOLEAN ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_int( unsigned char **p, unsigned char *start, int val ) +{ + int ret; + size_t len = 0; + + // TODO negative values and values larger than 128 + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len += 1; + *--(*p) = val; + + if( val > 0 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_PRINTABLE_STRING ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_ia5_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_IA5_STRING ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_bitstring( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t bits ) +{ + int ret; + size_t len = 0, size; + + size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); + + // Calculate byte length + // + if( *p - start < (int) size + 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len = size + 1; + (*p) -= size; + memcpy( *p, buf, size ); + + // Write unused bits + // + *--(*p) = (unsigned char) (size * 8 - bits); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int asn1_write_octet_string( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, buf, size ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +asn1_named_data *asn1_store_named_data( asn1_named_data **head, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len ) +{ + asn1_named_data *cur; + + if( ( cur = asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) + { + // Add new entry if not present yet based on OID + // + if( ( cur = polarssl_malloc( sizeof(asn1_named_data) ) ) == NULL ) + return( NULL ); + + memset( cur, 0, sizeof(asn1_named_data) ); + + cur->oid.len = oid_len; + cur->oid.p = polarssl_malloc( oid_len ); + if( cur->oid.p == NULL ) + { + polarssl_free( cur ); + return( NULL ); + } + + cur->val.len = val_len; + cur->val.p = polarssl_malloc( val_len ); + if( cur->val.p == NULL ) + { + polarssl_free( cur->oid.p ); + polarssl_free( cur ); + return( NULL ); + } + + memcpy( cur->oid.p, oid, oid_len ); + + cur->next = *head; + *head = cur; + } + else if( cur->val.len < val_len ) + { + // Enlarge existing value buffer if needed + // + polarssl_free( cur->val.p ); + cur->val.p = NULL; + + cur->val.len = val_len; + cur->val.p = polarssl_malloc( val_len ); + if( cur->val.p == NULL ) + { + polarssl_free( cur->oid.p ); + polarssl_free( cur ); + return( NULL ); + } + } + + if( val != NULL ) + memcpy( cur->val.p, val, val_len ); + + return( cur ); +} +#endif /* POLARSSL_ASN1_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/base64.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/base64.c new file mode 100644 index 0000000..4366f9d --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/base64.c @@ -0,0 +1,277 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BASE64_C) + +#include "polarssl/base64.h" + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +SSL_ROM_DATA_SECTION +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +SSL_ROM_DATA_SECTION +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 127, 127, 127, 127, 127, 127, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 127, 127, 127, 127, 127 +}; + +/* + * Encode a buffer into base64 format + */ +SSL_ROM_TEXT_SECTION +int base64_encode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + return( 0 ); + + n = ( slen << 3 ) / 6; + + switch( ( slen << 3 ) - ( n * 6 ) ) + { + case 2: n += 3; break; + case 4: n += 2; break; + default: break; + } + + if( *dlen < n + 1 ) + { + *dlen = n + 1; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = ( slen / 3 ) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( ( i + 1 ) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *dlen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +SSL_ROM_TEXT_SECTION +int base64_decode( unsigned char *dst, size_t *dlen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + uint32_t j, x; + unsigned char *p; + + for( i = n = j = 0; i < slen; i++ ) + { + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + if( src[i] == '=' && ++j > 2 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( POLARSSL_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + return( 0 ); + + n = ( ( n * 6 ) + 7 ) >> 3; + n -= j; + + if( dst == NULL || *dlen < n ) + { + *dlen = n; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *dlen = p - dst; + + return( 0 ); +} + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int base64_self_test( int verbose ) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if( verbose != 0 ) + polarssl_printf( " Base64 encoding test: " ); + + len = sizeof( buffer ); + src = base64_test_dec; + + if( base64_encode( buffer, &len, src, 64 ) != 0 || + memcmp( base64_test_enc, buffer, 88 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n Base64 decoding test: " ); + + len = sizeof( buffer ); + src = base64_test_enc; + + if( base64_decode( buffer, &len, src, 88 ) != 0 || + memcmp( base64_test_dec, buffer, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_BASE64_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/bignum.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/bignum.c new file mode 100644 index 0000000..77829ed --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/bignum.c @@ -0,0 +1,2400 @@ +/* + * Multi-precision integer library + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * This MPI implementation is based on: + * + * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf + * http://www.stillhq.com/extracted/gnupg-api/mpi/ + * http://math.libtomcrypt.com/files/tommath.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_BIGNUM_C) + +#include "polarssl/bignum.h" +#include "polarssl/bn_mul.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define ciL (sizeof(t_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +/* + * Convert between bits/chars and number of limbs + */ +#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) +#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) + +/* + * Initialize one MPI + */ +SSL_ROM_TEXT_SECTION +void mpi_init( mpi *X ) +{ + if( X == NULL ) + return; + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +SSL_ROM_TEXT_SECTION +void mpi_free( mpi *X ) +{ + if( X == NULL ) + return; + + if( X->p != NULL ) + { + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +SSL_ROM_TEXT_SECTION +int mpi_grow( mpi *X, size_t nblimbs ) +{ + t_uint *p; + + if( nblimbs > POLARSSL_MPI_MAX_LIMBS ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + if( X->n < nblimbs ) + { + if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, nblimbs * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Resize down as much as possible, + * while keeping at least the specified number of limbs + */ +SSL_ROM_TEXT_SECTION +int mpi_shrink( mpi *X, size_t nblimbs ) +{ + t_uint *p; + size_t i; + + /* Actually resize up in this case */ + if( X->n <= nblimbs ) + return( mpi_grow( X, nblimbs ) ); + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + i++; + + if( i < nblimbs ) + i = nblimbs; + + if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL ) + return( POLARSSL_ERR_MPI_MALLOC_FAILED ); + + memset( p, 0, i * ciL ); + + if( X->p != NULL ) + { + memcpy( p, X->p, i * ciL ); + polarssl_zeroize( X->p, X->n * ciL ); + polarssl_free( X->p ); + } + + X->n = i; + X->p = p; + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +SSL_ROM_TEXT_SECTION +int mpi_copy( mpi *X, const mpi *Y ) +{ + int ret; + size_t i; + + if( X == Y ) + return( 0 ); + + if( Y->p == NULL ) + { + mpi_free( X ); + return( 0 ); + } + + for( i = Y->n - 1; i > 0; i-- ) + if( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MPI_CHK( mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +SSL_ROM_TEXT_SECTION +void mpi_swap( mpi *X, mpi *Y ) +{ + mpi T; + + memcpy( &T, X, sizeof( mpi ) ); + memcpy( X, Y, sizeof( mpi ) ); + memcpy( Y, &T, sizeof( mpi ) ); +} + +/* + * Conditionally assign X = Y, without leaking information + * about whether the assignment was made or not. + * (Leaking information about the respective sizes of X and Y is ok however.) + */ +SSL_ROM_TEXT_SECTION +int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ) +{ + int ret = 0; + size_t i; + + /* make sure assign is 0 or 1 */ + assign = ( assign != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + + X->s = X->s * ( 1 - assign ) + Y->s * assign; + + for( i = 0; i < Y->n; i++ ) + X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; + + for( ; i < X->n; i++ ) + X->p[i] *= ( 1 - assign ); + +cleanup: + return( ret ); +} + +/* + * Conditionally swap X and Y, without leaking information + * about whether the swap was made or not. + * Here it is not ok to simply swap the pointers, which whould lead to + * different memory access patterns when X and Y are used afterwards. + */ +SSL_ROM_TEXT_SECTION +int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap ) +{ + int ret, s; + size_t i; + t_uint tmp; + + if( X == Y ) + return( 0 ); + + /* make sure swap is 0 or 1 */ + swap = ( swap != 0 ); + + MPI_CHK( mpi_grow( X, Y->n ) ); + MPI_CHK( mpi_grow( Y, X->n ) ); + + s = X->s; + X->s = X->s * ( 1 - swap ) + Y->s * swap; + Y->s = Y->s * ( 1 - swap ) + s * swap; + + + for( i = 0; i < X->n; i++ ) + { + tmp = X->p[i]; + X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; + Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; + } + +cleanup: + return( ret ); +} + +/* + * Set value from integer + */ +SSL_ROM_TEXT_SECTION +int mpi_lset( mpi *X, t_sint z ) +{ + int ret; + + MPI_CHK( mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Get a specific bit + */ +SSL_ROM_TEXT_SECTION +int mpi_get_bit( const mpi *X, size_t pos ) +{ + if( X->n * biL <= pos ) + return( 0 ); + + return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +SSL_ROM_TEXT_SECTION +int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + + if( val != 0 && val != 1 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + if( X->n * biL <= pos ) + { + if( val == 0 ) + return( 0 ); + + MPI_CHK( mpi_grow( X, off + 1 ) ); + } + + X->p[off] &= ~( (t_uint) 0x01 << idx ); + X->p[off] |= (t_uint) val << idx; + +cleanup: + + return( ret ); +} + +/* + * Return the number of least significant bits + */ +SSL_ROM_TEXT_SECTION +size_t mpi_lsb( const mpi *X ) +{ + size_t i, j, count = 0; + + for( i = 0; i < X->n; i++ ) + for( j = 0; j < biL; j++, count++ ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Return the number of most significant bits + */ +SSL_ROM_TEXT_SECTION +size_t mpi_msb( const mpi *X ) +{ + size_t i, j; + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + + for( j = biL; j > 0; j-- ) + if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 ) + break; + + return( ( i * biL ) + j ); +} + +/* + * Return the total size in bytes + */ +SSL_ROM_TEXT_SECTION +size_t mpi_size( const mpi *X ) +{ + return( ( mpi_msb( X ) + 7 ) >> 3 ); +} + +/* + * Convert an ASCII character to digit value + */ +SSL_ROM_TEXT_SECTION +static int mpi_get_digit( t_uint *d, int radix, char c ) +{ + *d = 255; + + if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; + if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; + if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; + + if( *d >= (t_uint) radix ) + return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); + + return( 0 ); +} + +/* + * Import from an ASCII string + */ +SSL_ROM_TEXT_SECTION +int mpi_read_string( mpi *X, int radix, const char *s ) +{ + int ret; + size_t i, j, slen, n; + t_uint d; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &T ); + + slen = strlen( s ); + + if( radix == 16 ) + { + n = BITS_TO_LIMBS( slen << 2 ); + + MPI_CHK( mpi_grow( X, n ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = slen, j = 0; i > 0; i--, j++ ) + { + if( i == 1 && s[i - 1] == '-' ) + { + X->s = -1; + break; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); + X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); + } + } + else + { + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = 0; i < slen; i++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + continue; + } + + MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + MPI_CHK( mpi_mul_int( &T, X, radix ) ); + + if( X->s == 1 ) + { + MPI_CHK( mpi_add_int( X, &T, d ) ); + } + else + { + MPI_CHK( mpi_sub_int( X, &T, d ) ); + } + } + } + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +/* + * Helper to write the digits high-order first + */ +SSL_ROM_TEXT_SECTION +static int mpi_write_hlp( mpi *X, int radix, char **p ) +{ + int ret; + t_uint r; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( mpi_mod_int( &r, X, radix ) ); + MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); + + if( mpi_cmp_int( X, 0 ) != 0 ) + MPI_CHK( mpi_write_hlp( X, radix, p ) ); + + if( r < 10 ) + *(*p)++ = (char)( r + 0x30 ); + else + *(*p)++ = (char)( r + 0x37 ); + +cleanup: + + return( ret ); +} + +/* + * Export into an ASCII string + */ +SSL_ROM_TEXT_SECTION +int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) +{ + int ret = 0; + size_t n; + char *p; + mpi T; + + if( radix < 2 || radix > 16 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + n = mpi_msb( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + n += 3; + + if( *slen < n ) + { + *slen = n; + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + } + + p = s; + mpi_init( &T ); + + if( X->s == -1 ) + *p++ = '-'; + + if( radix == 16 ) + { + int c; + size_t i, j, k; + + for( i = X->n, k = 0; i > 0; i-- ) + { + for( j = ciL; j > 0; j-- ) + { + c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; + + if( c == 0 && k == 0 && ( i + j ) != 2 ) + continue; + + *(p++) = "0123456789ABCDEF" [c / 16]; + *(p++) = "0123456789ABCDEF" [c % 16]; + k = 1; + } + } + } + else + { + MPI_CHK( mpi_copy( &T, X ) ); + + if( T.s == -1 ) + T.s = 1; + + MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + } + + *p++ = '\0'; + *slen = p - s; + +cleanup: + + mpi_free( &T ); + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Read X from an opened file + */ +SSL_ROM_TEXT_SECTION +int mpi_read_file( mpi *X, int radix, FILE *fin ) +{ + t_uint d; + size_t slen; + char *p; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; + + memset( s, 0, sizeof( s ) ); + if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + + slen = strlen( s ); + if( slen == sizeof( s ) - 2 ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + + p = s + slen; + while( --p >= s ) + if( mpi_get_digit( &d, radix, *p ) != 0 ) + break; + + return( mpi_read_string( X, radix, p + 1 ) ); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +SSL_ROM_TEXT_SECTION +int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) +{ + int ret; + size_t n, slen, plen; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; + + n = sizeof( s ); + memset( s, 0, n ); + n -= 2; + + MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) ); + + if( p == NULL ) p = ""; + + plen = strlen( p ); + slen = strlen( s ); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if( fout != NULL ) + { + if( fwrite( p, 1, plen, fout ) != plen || + fwrite( s, 1, slen, fout ) != slen ) + return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); + } + else + polarssl_printf( "%s%s", p, s ); + +cleanup: + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * Import X from unsigned binary data, big endian + */ +SSL_ROM_TEXT_SECTION +int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i, j, n; + + for( n = 0; n < buflen; n++ ) + if( buf[n] != 0 ) + break; + + MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i = buflen, j = 0; i > n; i--, j++ ) + X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +SSL_ROM_TEXT_SECTION +int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) +{ + size_t i, j, n; + + n = mpi_size( X ); + + if( buflen < n ) + return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +SSL_ROM_TEXT_SECTION +int mpi_shift_l( mpi *X, size_t count ) +{ + int ret; + size_t i, v0, t1; + t_uint r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mpi_msb( X ) + count; + + if( X->n * biL < i ) + MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +SSL_ROM_TEXT_SECTION +int mpi_shift_r( mpi *X, size_t count ) +{ + size_t i, v0, v1; + t_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) + return mpi_lset( X, 0 ); + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = X->n; i > 0; i-- ) + { + r1 = X->p[i - 1] << (biL - v1); + X->p[i - 1] >>= v1; + X->p[i - 1] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +SSL_ROM_TEXT_SECTION +int mpi_cmp_abs( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( 1 ); + if( j > i ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +SSL_ROM_TEXT_SECTION +int mpi_cmp_mpi( const mpi *X, const mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( X->s ); + if( j > i ) return( -Y->s ); + + if( X->s > 0 && Y->s < 0 ) return( 1 ); + if( Y->s > 0 && X->s < 0 ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +SSL_ROM_TEXT_SECTION +int mpi_cmp_int( const mpi *X, t_sint z ) +{ + mpi Y; + t_uint p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +SSL_ROM_TEXT_SECTION +int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + t_uint *o, *p, c; + + if( X == B ) + { + const mpi *T = A; A = X; B = T; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned additions. + */ + X->s = 1; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, j ) ); + + o = B->p; p = X->p; c = 0; + + for( i = 0; i < j; i++, o++, p++ ) + { + *p += c; c = ( *p < c ); + *p += *o; c += ( *p < *o ); + } + + while( c != 0 ) + { + if( i >= X->n ) + { + MPI_CHK( mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; p++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mpi subtraction + */ +SSL_ROM_TEXT_SECTION +static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) +{ + size_t i; + t_uint c, z; + + for( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned subtraction: X = |A| - |B| (HAC 14.9) + */ +SSL_ROM_TEXT_SECTION +int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) +{ + mpi TB; + int ret; + size_t n; + + if( mpi_cmp_abs( A, B ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + mpi_init( &TB ); + + if( X == B ) + { + MPI_CHK( mpi_copy( &TB, B ) ); + B = &TB; + } + + if( X != A ) + MPI_CHK( mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned subtractions. + */ + X->s = 1; + + ret = 0; + + for( n = B->n; n > 0; n-- ) + if( B->p[n - 1] != 0 ) + break; + + mpi_sub_hlp( n, B->p, X->p ); + +cleanup: + + mpi_free( &TB ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +SSL_ROM_TEXT_SECTION +int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s < 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed subtraction: X = A - B + */ +SSL_ROM_TEXT_SECTION +int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s > 0 ) + { + if( mpi_cmp_abs( A, B ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MPI_CHK( mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MPI_CHK( mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +SSL_ROM_TEXT_SECTION +int mpi_add_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed subtraction: X = A - b + */ +SSL_ROM_TEXT_SECTION +int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mpi multiplication + */ +SSL_ROM_TEXT_SECTION +static +#if defined(__APPLE__) && defined(__arm__) +/* + * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) + * appears to need this to prevent bad ARM code generation at -O3. + */ +__attribute__ ((noinline)) +#endif +void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b ) +{ + t_uint c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else /* MULADDC_HUIT */ + for( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif /* MULADDC_HUIT */ + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while( c != 0 ); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +SSL_ROM_TEXT_SECTION +int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, j; + mpi TA, TB; + + mpi_init( &TA ); mpi_init( &TB ); + + if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } + if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; } + + for( i = A->n; i > 0; i-- ) + if( A->p[i - 1] != 0 ) + break; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MPI_CHK( mpi_grow( X, i + j ) ); + MPI_CHK( mpi_lset( X, 0 ) ); + + for( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); + + X->s = A->s * B->s; + +cleanup: + + mpi_free( &TB ); mpi_free( &TA ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +SSL_ROM_TEXT_SECTION +int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Division by mpi: A = Q * B + R (HAC 14.20) + */ +SSL_ROM_TEXT_SECTION +int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + size_t i, n, t, k; + mpi X, Y, Z, T1, T2; + + if( mpi_cmp_int( B, 0 ) == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + mpi_init( &T1 ); mpi_init( &T2 ); + + if( mpi_cmp_abs( A, B ) < 0 ) + { + if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); + if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); + return( 0 ); + } + + MPI_CHK( mpi_copy( &X, A ) ); + MPI_CHK( mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); + MPI_CHK( mpi_lset( &Z, 0 ) ); + MPI_CHK( mpi_grow( &T1, 2 ) ); + MPI_CHK( mpi_grow( &T2, 3 ) ); + + k = mpi_msb( &Y ) % biL; + if( k < biL - 1 ) + { + k = biL - 1 - k; + MPI_CHK( mpi_shift_l( &X, k ) ); + MPI_CHK( mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) ); + + while( mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) ); + } + MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) ); + + for( i = n; i > t ; i-- ) + { + if( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { + /* + * The version of Clang shipped by Apple with Mavericks around + * 2014-03 can't handle 128-bit division properly. Disable + * 128-bits division for this version. Let's be optimistic and + * assume it'll be fixed in the next minor version (next + * patchlevel is probably a bit too optimistic). + */ +#if defined(POLARSSL_HAVE_UDBL) && \ + ! ( defined(__x86_64__) && defined(__APPLE__) && \ + defined(__clang_major__) && __clang_major__ == 5 && \ + defined(__clang_minor__) && __clang_minor__ == 0 ) + t_udbl r; + + r = (t_udbl) X.p[i] << biL; + r |= (t_udbl) X.p[i - 1]; + r /= Y.p[t]; + if( r > ( (t_udbl) 1 << biL ) - 1 ) + r = ( (t_udbl) 1 << biL ) - 1; + + Z.p[i - t - 1] = (t_uint) r; +#else + /* + * __udiv_qrnnd_c, from gmp/longlong.h + */ + t_uint q0, q1, r0, r1; + t_uint d0, d1, d, m; + + d = Y.p[t]; + d0 = ( d << biH ) >> biH; + d1 = ( d >> biH ); + + q1 = X.p[i] / d1; + r1 = X.p[i] - d1 * q1; + r1 <<= biH; + r1 |= ( X.p[i - 1] >> biH ); + + m = q1 * d0; + if( r1 < m ) + { + q1--, r1 += d; + while( r1 >= d && r1 < m ) + q1--, r1 += d; + } + r1 -= m; + + q0 = r1 / d1; + r0 = r1 - d1 * q0; + r0 <<= biH; + r0 |= ( X.p[i - 1] << biH ) >> biH; + + m = q0 * d0; + if( r0 < m ) + { + q0--, r0 += d; + while( r0 >= d && r0 < m ) + q0--, r0 += d; + } + r0 -= m; + + Z.p[i - t - 1] = ( q1 << biH ) | q0; +#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */ + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MPI_CHK( mpi_lset( &T1, 0 ) ); + T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MPI_CHK( mpi_lset( &T2, 0 ) ); + T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; + T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while( mpi_cmp_mpi( &T1, &T2 ) > 0 ); + + MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); + + if( mpi_cmp_int( &X, 0 ) < 0 ) + { + MPI_CHK( mpi_copy( &T1, &Y ) ); + MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if( Q != NULL ) + { + MPI_CHK( mpi_copy( Q, &Z ) ); + Q->s = A->s * B->s; + } + + if( R != NULL ) + { + MPI_CHK( mpi_shift_r( &X, k ) ); + X.s = A->s; + MPI_CHK( mpi_copy( R, &X ) ); + + if( mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + mpi_free( &T1 ); mpi_free( &T2 ); + + return( ret ); +} + +/* + * Division by int: A = Q * b + R + */ +SSL_ROM_TEXT_SECTION +int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ) +{ + mpi _B; + t_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mpi_div_mpi( Q, R, A, &_B ) ); +} + +/* + * Modulo: R = A mod B + */ +SSL_ROM_TEXT_SECTION +int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) +{ + int ret; + + if( mpi_cmp_int( B, 0 ) < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); + + while( mpi_cmp_int( R, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( R, R, B ) ); + + while( mpi_cmp_mpi( R, B ) >= 0 ) + MPI_CHK( mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +SSL_ROM_TEXT_SECTION +int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) +{ + size_t i; + t_uint x, y, z; + + if( b == 0 ) + return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); + + if( b < 0 ) + return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); + + /* + * handle trivial cases + */ + if( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for( i = A->n, y = 0; i > 0; i-- ) + { + x = A->p[i - 1]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if( A->s < 0 && y != 0 ) + y = b - y; + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +SSL_ROM_TEXT_SECTION +static void mpi_montg_init( t_uint *mm, const mpi *N ) +{ + t_uint x, m0 = N->p[0]; + unsigned int i; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + + for( i = biL; i >= 8; i /= 2 ) + x *= ( 2 - ( m0 * x ) ); + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +SSL_ROM_TEXT_SECTION +static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, + const mpi *T ) +{ + size_t i, n, m; + t_uint u0, u1, *d; + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, ( n + 1 ) * ciL ); + + if( mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +SSL_ROM_TEXT_SECTION +static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T ) +{ + t_uint z = 1; + mpi U; + + U.n = U.s = (int) z; + U.p = &z; + + mpi_montmul( A, &U, N, mm, T ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +SSL_ROM_TEXT_SECTION +int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ) +{ + int ret; + size_t wbits, wsize, one = 1; + size_t i, j, nblimbs; + size_t bufsize, nbits; + t_uint ei, mm, state; + mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos; + int neg; + + if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + if( mpi_cmp_int( E, 0 ) < 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mpi_init( &RR ); mpi_init( &T ); + mpi_init( &Apos ); + memset( W, 0, sizeof( W ) ); + + i = mpi_msb( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + if( wsize > POLARSSL_MPI_WINDOW_SIZE ) + wsize = POLARSSL_MPI_WINDOW_SIZE; + + j = N->n + 1; + MPI_CHK( mpi_grow( X, j ) ); + MPI_CHK( mpi_grow( &W[1], j ) ); + MPI_CHK( mpi_grow( &T, j * 2 ) ); + + /* + * Compensate for negative A (and correct at the end) + */ + neg = ( A->s == -1 ); + if( neg ) + { + MPI_CHK( mpi_copy( &Apos, A ) ); + Apos.s = 1; + A = &Apos; + } + + /* + * If 1st call, pre-compute R^2 mod N + */ + if( _RR == NULL || _RR->p == NULL ) + { + MPI_CHK( mpi_lset( &RR, 1 ) ); + MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); + MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); + + if( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if( mpi_cmp_mpi( A, N ) >= 0 ) + MPI_CHK( mpi_mod_mpi( &W[1], A, N ) ); + else + MPI_CHK( mpi_copy( &W[1], A ) ); + + mpi_montmul( &W[1], &RR, N, mm, &T ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MPI_CHK( mpi_copy( X, &RR ) ); + mpi_montred( X, N, mm, &T ); + + if( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = one << ( wsize - 1 ); + + MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[j], &W[1] ) ); + + for( i = 0; i < wsize - 1; i++ ) + mpi_montmul( &W[j], &W[j], N, mm, &T ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for( i = j + 1; i < ( one << wsize ); i++ ) + { + MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); + MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) ); + + mpi_montmul( &W[i], &W[1], N, mm, &T ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while( 1 ) + { + if( bufsize == 0 ) + { + if( nblimbs == 0 ) + break; + + nblimbs--; + + bufsize = sizeof( t_uint ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if( ei == 0 && state == 0 ) + continue; + + if( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + mpi_montmul( X, X, N, mm, &T ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= ( ei << ( wsize - nbits ) ); + + if( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for( i = 0; i < wsize; i++ ) + mpi_montmul( X, X, N, mm, &T ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + mpi_montmul( X, &W[wbits], N, mm, &T ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for( i = 0; i < nbits; i++ ) + { + mpi_montmul( X, X, N, mm, &T ); + + wbits <<= 1; + + if( ( wbits & ( one << wsize ) ) != 0 ) + mpi_montmul( X, &W[1], N, mm, &T ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + mpi_montred( X, N, mm, &T ); + + if( neg ) + { + X->s = -1; + MPI_CHK( mpi_add_mpi( X, N, X ) ); + } + +cleanup: + + for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) + mpi_free( &W[i] ); + + mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos ); + + if( _RR == NULL || _RR->p == NULL ) + mpi_free( &RR ); + + return( ret ); +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +SSL_ROM_TEXT_SECTION +int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) +{ + int ret; + size_t lz, lzt; + mpi TG, TA, TB; + + mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB ); + + MPI_CHK( mpi_copy( &TA, A ) ); + MPI_CHK( mpi_copy( &TB, B ) ); + + lz = mpi_lsb( &TA ); + lzt = mpi_lsb( &TB ); + + if( lzt < lz ) + lz = lzt; + + MPI_CHK( mpi_shift_r( &TA, lz ) ); + MPI_CHK( mpi_shift_r( &TB, lz ) ); + + TA.s = TB.s = 1; + + while( mpi_cmp_int( &TA, 0 ) != 0 ) + { + MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); + MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); + + if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) + { + MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); + MPI_CHK( mpi_shift_r( &TA, 1 ) ); + } + else + { + MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); + MPI_CHK( mpi_shift_r( &TB, 1 ) ); + } + } + + MPI_CHK( mpi_shift_l( &TB, lz ) ); + MPI_CHK( mpi_copy( G, &TB ) ); + +cleanup: + + mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB ); + + return( ret ); +} + +/* + * Fill X with size bytes of random. + * + * Use a temporary bytes representation to make sure the result is the same + * regardless of the platform endianness (useful when f_rng is actually + * deterministic, eg for tests). + */ +SSL_ROM_TEXT_SECTION +int mpi_fill_random( mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + + if( size > POLARSSL_MPI_MAX_SIZE ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + MPI_CHK( f_rng( p_rng, buf, size ) ); + MPI_CHK( mpi_read_binary( X, buf, size ) ); + +cleanup: + return( ret ); +} + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +SSL_ROM_TEXT_SECTION +int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ) +{ + int ret; + mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + + if( mpi_cmp_int( N, 0 ) <= 0 ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 ); + mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV ); + mpi_init( &V1 ); mpi_init( &V2 ); + + MPI_CHK( mpi_gcd( &G, A, N ) ); + + if( mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); + MPI_CHK( mpi_copy( &TU, &TA ) ); + MPI_CHK( mpi_copy( &TB, N ) ); + MPI_CHK( mpi_copy( &TV, N ) ); + + MPI_CHK( mpi_lset( &U1, 1 ) ); + MPI_CHK( mpi_lset( &U2, 0 ) ); + MPI_CHK( mpi_lset( &V1, 0 ) ); + MPI_CHK( mpi_lset( &V2, 1 ) ); + + do + { + while( ( TU.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TU, 1 ) ); + + if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &U1, 1 ) ); + MPI_CHK( mpi_shift_r( &U2, 1 ) ); + } + + while( ( TV.p[0] & 1 ) == 0 ) + { + MPI_CHK( mpi_shift_r( &TV, 1 ) ); + + if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) + { + MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); + } + + MPI_CHK( mpi_shift_r( &V1, 1 ) ); + MPI_CHK( mpi_shift_r( &V2, 1 ) ); + } + + if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) + { + MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); + MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); + MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); + } + else + { + MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); + MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); + MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); + } + } + while( mpi_cmp_int( &TU, 0 ) != 0 ); + + while( mpi_cmp_int( &V1, 0 ) < 0 ) + MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); + + while( mpi_cmp_mpi( &V1, N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); + + MPI_CHK( mpi_copy( X, &V1 ) ); + +cleanup: + + mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 ); + mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV ); + mpi_free( &V1 ); mpi_free( &V2 ); + + return( ret ); +} + +#if defined(POLARSSL_GENPRIME) + +SSL_ROM_DATA_SECTION +static const int small_prime[] = +{ + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, + 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, + 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, + 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, + 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, + 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, -103 +}; + +/* + * Small divisors test (X must be positive) + * + * Return values: + * 0: no small factor (possible prime, more tests needed) + * 1: certain prime + * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime + * other negative: error + */ +SSL_ROM_TEXT_SECTION +static int mpi_check_small_factors( const mpi *X ) +{ + int ret = 0; + size_t i; + t_uint r; + + if( ( X->p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + for( i = 0; small_prime[i] > 0; i++ ) + { + if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) + return( 1 ); + + MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); + + if( r == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + +cleanup: + return( ret ); +} + +/* + * Miller-Rabin pseudo-primality test (HAC 4.24) + */ +SSL_ROM_TEXT_SECTION +static int mpi_miller_rabin( const mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i, j, n, s; + mpi W, R, T, A, RR; + + mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); + mpi_init( &RR ); + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + MPI_CHK( mpi_sub_int( &W, X, 1 ) ); + s = mpi_lsb( &W ); + MPI_CHK( mpi_copy( &R, &W ) ); + MPI_CHK( mpi_shift_r( &R, s ) ); + + i = mpi_msb( X ); + /* + * HAC, table 4.4 + */ + n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : + ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : + ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); + + for( i = 0; i < n; i++ ) + { + /* + * pick a random A, 1 < A < |X| - 1 + */ + MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); + + if( mpi_cmp_mpi( &A, &W ) >= 0 ) + { + j = mpi_msb( &A ) - mpi_msb( &W ); + MPI_CHK( mpi_shift_r( &A, j + 1 ) ); + } + A.p[0] |= 3; + + /* + * A = A^R mod |X| + */ + MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); + + if( mpi_cmp_mpi( &A, &W ) == 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + continue; + + j = 1; + while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) + { + /* + * A = A * A mod |X| + */ + MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); + MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); + + if( mpi_cmp_int( &A, 1 ) == 0 ) + break; + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if( mpi_cmp_mpi( &A, &W ) != 0 || + mpi_cmp_int( &A, 1 ) == 0 ) + { + ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); + mpi_free( &RR ); + + return( ret ); +} + +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +SSL_ROM_TEXT_SECTION +int mpi_is_prime( mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const mpi XX = { 1, X->n, X->p }; /* Abs(X) */ + + if( mpi_cmp_int( &XX, 0 ) == 0 || + mpi_cmp_int( &XX, 1 ) == 0 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + + if( mpi_cmp_int( &XX, 2 ) == 0 ) + return( 0 ); + + if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) + { + if( ret == 1 ) + return( 0 ); + + return( ret ); + } + + return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); +} + +/* + * Prime number generation + */ +SSL_ROM_TEXT_SECTION +int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t k, n; + t_uint r; + mpi Y; + + if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS ) + return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); + + mpi_init( &Y ); + + n = BITS_TO_LIMBS( nbits ); + + MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); + + k = mpi_msb( X ); + if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) ); + if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) ); + + X->p[0] |= 3; + + if( dh_flag == 0 ) + { + while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) + { + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MPI_CHK( mpi_add_int( X, X, 2 ) ); + } + } + else + { + /* + * An necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 + */ + MPI_CHK( mpi_mod_int( &r, X, 3 ) ); + if( r == 0 ) + MPI_CHK( mpi_add_int( X, X, 8 ) ); + else if( r == 1 ) + MPI_CHK( mpi_add_int( X, X, 4 ) ); + + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MPI_CHK( mpi_copy( &Y, X ) ); + MPI_CHK( mpi_shift_r( &Y, 1 ) ); + + while( 1 ) + { + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if( ( ret = mpi_check_small_factors( X ) ) == 0 && + ( ret = mpi_check_small_factors( &Y ) ) == 0 && + ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && + ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) + { + break; + } + + if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + /* + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. + */ + MPI_CHK( mpi_add_int( X, X, 12 ) ); + MPI_CHK( mpi_add_int( &Y, &Y, 6 ) ); + } + } + +cleanup: + + mpi_free( &Y ); + + return( ret ); +} + +#endif /* POLARSSL_GENPRIME */ + +#if defined(POLARSSL_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +SSL_ROM_DATA_SECTION +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +SSL_ROM_TEXT_SECTION +int mpi_self_test( int verbose ) +{ + int ret, i; + mpi A, E, N, X, Y, U, V; + + mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); + mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); + + MPI_CHK( mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MPI_CHK( mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MPI_CHK( mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #1 (mul_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MPI_CHK( mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #2 (div_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 || + mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #3 (exp_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #4 (inv_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #5 (simple gcd): " ); + + for( i = 0; i < GCD_PAIR_COUNT; i++ ) + { + MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); + MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed at %d\n", i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); + mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_BIGNUM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ctr_drbg.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ctr_drbg.c new file mode 100644 index 0000000..16c83a3 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ctr_drbg.c @@ -0,0 +1,564 @@ +/* + * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The NIST SP 800-90 DRBGs are described in the following publucation. + * + * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_CTR_DRBG_C) + +#include "polarssl/ctr_drbg.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Non-public function wrapped by ctr_crbg_init(). Necessary to allow NIST + * tests to succeed (which require known length fixed entropy) + */ +SSL_ROM_TEXT_SECTION +int ctr_drbg_init_entropy_len( + ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len, + size_t entropy_len ) +{ + int ret; + unsigned char key[CTR_DRBG_KEYSIZE]; + + memset( ctx, 0, sizeof(ctr_drbg_context) ); + memset( key, 0, CTR_DRBG_KEYSIZE ); + + aes_init( &ctx->aes_ctx ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->entropy_len = entropy_len; + ctx->reseed_interval = CTR_DRBG_RESEED_INTERVAL; + + /* + * Initialize with an empty key + */ + aes_setkey_enc( &ctx->aes_ctx, key, CTR_DRBG_KEYBITS ); + + if( ( ret = ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int ctr_drbg_init( ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + return( ctr_drbg_init_entropy_len( ctx, f_entropy, p_entropy, custom, len, + CTR_DRBG_ENTROPY_LEN ) ); +} + +SSL_ROM_TEXT_SECTION +void ctr_drbg_free( ctr_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + aes_free( &ctx->aes_ctx ); + polarssl_zeroize( ctx, sizeof( ctr_drbg_context ) ); +} + +SSL_ROM_TEXT_SECTION +void ctr_drbg_set_prediction_resistance( ctr_drbg_context *ctx, int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +SSL_ROM_TEXT_SECTION +void ctr_drbg_set_entropy_len( ctr_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +SSL_ROM_TEXT_SECTION +void ctr_drbg_set_reseed_interval( ctr_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +SSL_ROM_TEXT_SECTION +static int block_cipher_df( unsigned char *output, + const unsigned char *data, size_t data_len ) +{ + unsigned char buf[CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16]; + unsigned char tmp[CTR_DRBG_SEEDLEN]; + unsigned char key[CTR_DRBG_KEYSIZE]; + unsigned char chain[CTR_DRBG_BLOCKSIZE]; + unsigned char *p, *iv; + aes_context aes_ctx; + + int i, j; + size_t buf_len, use_len; + + memset( buf, 0, CTR_DRBG_MAX_SEED_INPUT + CTR_DRBG_BLOCKSIZE + 16 ); + aes_init( &aes_ctx ); + + /* + * Construct IV (16 bytes) and S in buffer + * IV = Counter (in 32-bits) padded to 16 with zeroes + * S = Length input string (in 32-bits) || Length of output (in 32-bits) || + * data || 0x80 + * (Total is padded to a multiple of 16-bytes with zeroes) + */ + p = buf + CTR_DRBG_BLOCKSIZE; + *p++ = ( data_len >> 24 ) & 0xff; + *p++ = ( data_len >> 16 ) & 0xff; + *p++ = ( data_len >> 8 ) & 0xff; + *p++ = ( data_len ) & 0xff; + p += 3; + *p++ = CTR_DRBG_SEEDLEN; + memcpy( p, data, data_len ); + p[data_len] = 0x80; + + buf_len = CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; + + for( i = 0; i < CTR_DRBG_KEYSIZE; i++ ) + key[i] = i; + + aes_setkey_enc( &aes_ctx, key, CTR_DRBG_KEYBITS ); + + /* + * Reduce data to POLARSSL_CTR_DRBG_SEEDLEN bytes of data + */ + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + p = buf; + memset( chain, 0, CTR_DRBG_BLOCKSIZE ); + use_len = buf_len; + + while( use_len > 0 ) + { + for( i = 0; i < CTR_DRBG_BLOCKSIZE; i++ ) + chain[i] ^= p[i]; + p += CTR_DRBG_BLOCKSIZE; + use_len -= ( use_len >= CTR_DRBG_BLOCKSIZE ) ? + CTR_DRBG_BLOCKSIZE : use_len; + + aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, chain, chain ); + } + + memcpy( tmp + j, chain, CTR_DRBG_BLOCKSIZE ); + + /* + * Update IV + */ + buf[3]++; + } + + /* + * Do final encryption with reduced data + */ + aes_setkey_enc( &aes_ctx, tmp, CTR_DRBG_KEYBITS ); + iv = tmp + CTR_DRBG_KEYSIZE; + p = output; + + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + aes_crypt_ecb( &aes_ctx, AES_ENCRYPT, iv, iv ); + memcpy( p, iv, CTR_DRBG_BLOCKSIZE ); + p += CTR_DRBG_BLOCKSIZE; + } + + aes_free( &aes_ctx ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static int ctr_drbg_update_internal( ctr_drbg_context *ctx, + const unsigned char data[CTR_DRBG_SEEDLEN] ) +{ + unsigned char tmp[CTR_DRBG_SEEDLEN]; + unsigned char *p = tmp; + int i, j; + + memset( tmp, 0, CTR_DRBG_SEEDLEN ); + + for( j = 0; j < CTR_DRBG_SEEDLEN; j += CTR_DRBG_BLOCKSIZE ) + { + /* + * Increase counter + */ + for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, p ); + + p += CTR_DRBG_BLOCKSIZE; + } + + for( i = 0; i < CTR_DRBG_SEEDLEN; i++ ) + tmp[i] ^= data[i]; + + /* + * Update key and counter + */ + aes_setkey_enc( &ctx->aes_ctx, tmp, CTR_DRBG_KEYBITS ); + memcpy( ctx->counter, tmp + CTR_DRBG_KEYSIZE, CTR_DRBG_BLOCKSIZE ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +void ctr_drbg_update( ctr_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + unsigned char add_input[CTR_DRBG_SEEDLEN]; + + if( add_len > 0 ) + { + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } +} + +SSL_ROM_TEXT_SECTION +int ctr_drbg_reseed( ctr_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[CTR_DRBG_MAX_SEED_INPUT]; + size_t seedlen = 0; + + if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT ) + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT ); + + /* + * Gather entropy_len bytes of entropy to seed state + */ + if( 0 != ctx->f_entropy( ctx->p_entropy, seed, + ctx->entropy_len ) ) + { + return( POLARSSL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); + } + + seedlen += ctx->entropy_len; + + /* + * Add additional data + */ + if( additional && len ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* + * Reduce to 384 bits + */ + block_cipher_df( seed, seed, seedlen ); + + /* + * Update state + */ + ctr_drbg_update_internal( ctx, seed ); + ctx->reseed_counter = 1; + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int ctr_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, size_t add_len ) +{ + int ret = 0; + ctr_drbg_context *ctx = (ctr_drbg_context *) p_rng; + unsigned char add_input[CTR_DRBG_SEEDLEN]; + unsigned char *p = output; + unsigned char tmp[CTR_DRBG_BLOCKSIZE]; + int i; + size_t use_len; + + if( output_len > CTR_DRBG_MAX_REQUEST ) + return( POLARSSL_ERR_CTR_DRBG_REQUEST_TOO_BIG ); + + if( add_len > CTR_DRBG_MAX_INPUT ) + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( add_input, 0, CTR_DRBG_SEEDLEN ); + + if( ctx->reseed_counter > ctx->reseed_interval || + ctx->prediction_resistance ) + { + if( ( ret = ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; + } + + if( add_len > 0 ) + { + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } + + while( output_len > 0 ) + { + /* + * Increase counter + */ + for( i = CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + aes_crypt_ecb( &ctx->aes_ctx, AES_ENCRYPT, ctx->counter, tmp ); + + use_len = ( output_len > CTR_DRBG_BLOCKSIZE ) ? CTR_DRBG_BLOCKSIZE : + output_len; + /* + * Copy random block to destination + */ + memcpy( p, tmp, use_len ); + p += use_len; + output_len -= use_len; + } + + ctr_drbg_update_internal( ctx, add_input ); + + ctx->reseed_counter++; + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + return ctr_drbg_random_with_add( p_rng, output, output_len, NULL, 0 ); +} + +#if defined(POLARSSL_FS_IO) +SSL_ROM_TEXT_SECTION +int ctr_drbg_write_seed_file( ctr_drbg_context *ctx, const char *path ) +{ + int ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + + if( ( ret = ctr_drbg_random( ctx, buf, CTR_DRBG_MAX_INPUT ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, CTR_DRBG_MAX_INPUT, f ) != CTR_DRBG_MAX_INPUT ) + { + ret = POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +SSL_ROM_TEXT_SECTION +int ctr_drbg_update_seed_file( ctr_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > CTR_DRBG_MAX_INPUT ) + { + fclose( f ); + return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + ctr_drbg_update( ctx, buf, n ); + + return( ctr_drbg_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +static unsigned char entropy_source_pr[96] = + { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, + 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, + 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, + 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, + 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, + 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, + 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, + 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, + 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, + 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, + 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, + 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; + +static unsigned char entropy_source_nopr[64] = + { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, + 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, + 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, + 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, + 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, + 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, + 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, + 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; + +static const unsigned char nonce_pers_pr[16] = + { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, + 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; + +static const unsigned char nonce_pers_nopr[16] = + { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, + 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; + +static const unsigned char result_pr[16] = + { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, + 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; + +static const unsigned char result_nopr[16] = + { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, + 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; + +static size_t test_offset; +static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, + size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine + */ +int ctr_drbg_self_test( int verbose ) +{ + ctr_drbg_context ctx; + unsigned char buf[16]; + + /* + * Based on a NIST CTR_DRBG test vector (PR = True) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = TRUE) : " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_pr, nonce_pers_pr, 16, 32 ) ); + ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( memcmp( buf, result_pr, CTR_DRBG_BLOCKSIZE ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * Based on a NIST CTR_DRBG test vector (PR = FALSE) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = FALSE): " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( ctr_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( memcmp( buf, result_nopr, 16 ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_CTR_DRBG_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/des.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/des.c new file mode 100644 index 0000000..0af6fe3 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/des.c @@ -0,0 +1,1263 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif +#ifdef RTL_HW_CRYPTO +#include +#endif +#if defined(POLARSSL_DES_C) + +#include "polarssl/des.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_DES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +SSL_ROM_DATA_SECTION +static const uint32_t SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +SSL_ROM_DATA_SECTION +static const uint32_t LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +SSL_ROM_DATA_SECTION +static const uint32_t RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } + +SSL_ROM_TEXT_SECTION +void des_init( des_context *ctx ) +{ + memset( ctx, 0, sizeof( des_context ) ); +} + +SSL_ROM_TEXT_SECTION +void des_free( des_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des_context ) ); +} + +SSL_ROM_TEXT_SECTION +void des3_init( des3_context *ctx ) +{ + memset( ctx, 0, sizeof( des3_context ) ); +} + +SSL_ROM_TEXT_SECTION +void des3_free( des3_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( des3_context ) ); +} + +SSL_ROM_DATA_SECTION +static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, + 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, + 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, + 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, + 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, + 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, + 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, + 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, + 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, + 254 }; + +SSL_ROM_TEXT_SECTION +void des_key_set_parity( unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < DES_KEY_SIZE; i++ ) + key[i] = odd_parity_table[key[i] / 2]; +} + +/* + * Check the given key's parity, returns 1 on failure, 0 on SUCCESS + */ +SSL_ROM_TEXT_SECTION +int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < DES_KEY_SIZE; i++ ) + if( key[i] != odd_parity_table[key[i] / 2] ) + return( 1 ); + + return( 0 ); +} + +/* + * Table of weak and semi-weak keys + * + * Source: http://en.wikipedia.org/wiki/Weak_key + * + * Weak: + * Alternating ones + zeros (0x0101010101010101) + * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) + * '0xE0E0E0E0F1F1F1F1' + * '0x1F1F1F1F0E0E0E0E' + * + * Semi-weak: + * 0x011F011F010E010E and 0x1F011F010E010E01 + * 0x01E001E001F101F1 and 0xE001E001F101F101 + * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 + * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E + * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E + * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 + * + */ + +#define WEAK_KEY_COUNT 16 + +SSL_ROM_DATA_SECTION +static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] = +{ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } +}; + +SSL_ROM_TEXT_SECTION +int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < WEAK_KEY_COUNT; i++ ) + if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0 ) + return( 1 ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static void des_setkey( uint32_t SK[32], const unsigned char key[DES_KEY_SIZE] ) +{ + int i; + uint32_t X, Y, T; + + GET_UINT32_BE( X, key, 0 ); + GET_UINT32_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} + +/* + * DES key schedule (56-bit, encryption) + */ +SSL_ROM_TEXT_SECTION +int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des_setkey( ctx->sk, key ); + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +SSL_ROM_TEXT_SECTION +int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] ) +{ + int i; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static void des3_set2key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[DES_KEY_SIZE*2] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i ]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i ]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * Triple-DES key schedule (112-bit, encryption) + */ +SSL_ROM_TEXT_SECTION +int des3_set2key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE * 2); + memcpy(ctx->enc_key + DES_KEY_SIZE * 2, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des3_set2key( ctx->sk, sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (112-bit, decryption) + */ +SSL_ROM_TEXT_SECTION +int des3_set2key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE * 2); + memcpy(ctx->dec_key + DES_KEY_SIZE * 2, key, DES_KEY_SIZE); + } +#endif /* RTL_HW_CRYPTO */ + des3_set2key( sk, ctx->sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static void des3_set3key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[24] ) +{ + int i; + + des_setkey( esk, key ); + des_setkey( dsk + 32, key + 8 ); + des_setkey( esk + 64, key + 16 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * Triple-DES key schedule (168-bit, encryption) + */ +SSL_ROM_TEXT_SECTION +int des3_set3key_enc( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->enc_key, key, DES_KEY_SIZE * 3); + } +#endif /* RTL_HW_CRYPTO */ + des3_set3key( ctx->sk, sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (168-bit, decryption) + */ +SSL_ROM_TEXT_SECTION +int des3_set3key_dec( des3_context *ctx, + const unsigned char key[DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + memcpy(ctx->dec_key, key, DES_KEY_SIZE * 3); + } +#endif /* RTL_HW_CRYPTO */ + des3_set3key( sk, ctx->sk, key ); + polarssl_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int des_crypt_ecb( des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); + +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * DES-CBC buffer encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int des_crypt_cbc( des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[8 + 4], *key_buf_aligned; + unsigned char iv_buf[8 + 4], *iv_buf_aligned, iv_tmp[8]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 8) + return(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 8); + memset(output_buf, 0, length + 4); + + if(mode == DES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, DES_KEY_SIZE); + rom_ssl_ram_map.hw_crypto_des_cbc_init(key_buf_aligned, DES_KEY_SIZE); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + rom_ssl_ram_map.hw_crypto_des_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 8), 8); + rom_ssl_ram_map.hw_crypto_des_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 8); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, DES_KEY_SIZE); + rom_ssl_ram_map.hw_crypto_des_cbc_init(key_buf_aligned, DES_KEY_SIZE); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_des_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_des_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 8), 8); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/* + * 3DES-ECB block encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int des3_crypt_ecb( des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( X, Y ); + DES_ROUND( Y, X ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * 3DES-CBC buffer encryption/decryption + */ +SSL_ROM_TEXT_SECTION +int des3_crypt_cbc( des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ +#ifdef RTL_HW_CRYPTO + if(rom_ssl_ram_map.use_hw_crypto_func) + { + unsigned char key_buf[24 + 4], *key_buf_aligned; + unsigned char iv_buf[8 + 4], *iv_buf_aligned, iv_tmp[8]; + unsigned char *output_buf, *output_buf_aligned; + size_t length_done = 0; + + if(length % 8) + return(POLARSSL_ERR_DES_INVALID_INPUT_LENGTH); + + if(length > 0) + { + key_buf_aligned = (unsigned char *) (((unsigned int) key_buf + 4) / 4 * 4); + iv_buf_aligned = (unsigned char *) (((unsigned int) iv_buf + 4) / 4 * 4); + output_buf = polarssl_malloc(length + 4); + + if(output_buf == NULL) + return -1; + + output_buf_aligned = (unsigned char *) (((unsigned int) output_buf + 4) / 4 * 4); + memcpy(iv_buf_aligned, iv, 8); + memset(output_buf, 0, length + 4); + + if(mode == DES_DECRYPT) + { + memcpy(key_buf_aligned, ctx->dec_key, DES_KEY_SIZE * 3); + rom_ssl_ram_map.hw_crypto_3des_cbc_init(key_buf_aligned, DES_KEY_SIZE * 3); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + memcpy(iv_tmp, (input + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + rom_ssl_ram_map.hw_crypto_3des_cbc_decrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, iv_tmp, 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + memcpy(iv_tmp, (input + length - 8), 8); + rom_ssl_ram_map.hw_crypto_3des_cbc_decrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, iv_tmp, 8); + } + else + { + memcpy(key_buf_aligned, ctx->enc_key, DES_KEY_SIZE * 3); + rom_ssl_ram_map.hw_crypto_3des_cbc_init(key_buf_aligned, DES_KEY_SIZE * 3); + + while((length - length_done) > RTL_CRYPTO_FRAGMENT) + { + rom_ssl_ram_map.hw_crypto_3des_cbc_encrypt(input + length_done, RTL_CRYPTO_FRAGMENT, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv_buf_aligned, (output_buf_aligned + length_done + RTL_CRYPTO_FRAGMENT - 8), 8); + length_done += RTL_CRYPTO_FRAGMENT; + } + + rom_ssl_ram_map.hw_crypto_3des_cbc_encrypt(input + length_done, length - length_done, iv_buf_aligned, 8, output_buf_aligned + length_done); + memcpy(iv, (output_buf_aligned + length - 8), 8); + } + + memcpy(output, output_buf_aligned, length); + polarssl_free(output_buf); + } + + return 0; + } +#endif /* RTL_HW_CRYPTO */ +#ifdef SUPPORT_HW_SW_CRYPTO + else + { + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + des3_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + des3_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); + } +#endif /* SUPPORT_HW_SW_CRYPTO */ +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#endif /* !POLARSSL_DES_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include + +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int des_self_test( int verbose ) +{ + int i, j, u, v, ret = 0; + des_context ctx; + des3_context ctx3; + unsigned char buf[8]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + des_init( &ctx ); + des3_init( &ctx3 ); + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_ecb( &ctx, buf, buf ); + else + des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + des_free( &ctx ); + des3_free( &ctx3 ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_DES_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/dhm.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/dhm.c new file mode 100644 index 0000000..9565d36 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/dhm.c @@ -0,0 +1,613 @@ +/* + * Diffie-Hellman-Merkle key exchange + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * Reference: + * + * http://www.cacr.math.uwaterloo.ca/hac/ (chapter 12) + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_DHM_C) + +#include "polarssl/dhm.h" + +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_ASN1_PARSE_C) +#include "polarssl/asn1.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * helper to validate the mpi size and import it + */ +SSL_ROM_TEXT_SECTION +static int dhm_read_bignum( mpi *X, + unsigned char **p, + const unsigned char *end ) +{ + int ret, n; + + if( end - *p < 2 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + n = ( (*p)[0] << 8 ) | (*p)[1]; + (*p) += 2; + + if( (int)( end - *p ) < n ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mpi_read_binary( X, *p, n ) ) != 0 ) + return( POLARSSL_ERR_DHM_READ_PARAMS_FAILED + ret ); + + (*p) += n; + + return( 0 ); +} + +/* + * Verify sanity of parameter with regards to P + * + * Parameter should be: 2 <= public_param <= P - 2 + * + * For more information on the attack, see: + * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf + * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 + */ +SSL_ROM_TEXT_SECTION +static int dhm_check_range( const mpi *param, const mpi *P ) +{ + mpi L, U; + int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA; + + mpi_init( &L ); mpi_init( &U ); + + MPI_CHK( mpi_lset( &L, 2 ) ); + MPI_CHK( mpi_sub_int( &U, P, 2 ) ); + + if( mpi_cmp_mpi( param, &L ) >= 0 && + mpi_cmp_mpi( param, &U ) <= 0 ) + { + ret = 0; + } + +cleanup: + mpi_free( &L ); mpi_free( &U ); + return( ret ); +} + +SSL_ROM_TEXT_SECTION +void dhm_init( dhm_context *ctx ) +{ + memset( ctx, 0, sizeof( dhm_context ) ); +} + +/* + * Parse the ServerKeyExchange parameters + */ +SSL_ROM_TEXT_SECTION +int dhm_read_params( dhm_context *ctx, + unsigned char **p, + const unsigned char *end ) +{ + int ret; + + if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) + return( ret ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + ctx->len = mpi_size( &ctx->P ); + + return( 0 ); +} + +/* + * Setup and write the ServerKeyExchange parameters + */ +SSL_ROM_TEXT_SECTION +int dhm_make_params( dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + size_t n1, n2, n3; + unsigned char *p; + + if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + /* + * Generate X as large as possible ( < P ) + */ + do + { + mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + /* + * Calculate GX = G^X mod P + */ + MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + /* + * export P, G, GX + */ +#define DHM_MPI_EXPORT(X,n) \ + MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \ + *p++ = (unsigned char)( n >> 8 ); \ + *p++ = (unsigned char)( n ); p += n; + + n1 = mpi_size( &ctx->P ); + n2 = mpi_size( &ctx->G ); + n3 = mpi_size( &ctx->GX ); + + p = output; + DHM_MPI_EXPORT( &ctx->P , n1 ); + DHM_MPI_EXPORT( &ctx->G , n2 ); + DHM_MPI_EXPORT( &ctx->GX, n3 ); + + *olen = p - output; + + ctx->len = n1; + +cleanup: + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED + ret ); + + return( 0 ); +} + +/* + * Import the peer's public value G^Y + */ +SSL_ROM_TEXT_SECTION +int dhm_read_public( dhm_context *ctx, + const unsigned char *input, size_t ilen ) +{ + int ret; + + if( ctx == NULL || ilen < 1 || ilen > ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) + return( POLARSSL_ERR_DHM_READ_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Create own private value X and export G^X + */ +SSL_ROM_TEXT_SECTION +int dhm_make_public( dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + + if( ctx == NULL || olen < 1 || olen > ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + /* + * generate X and calculate GX = G^X mod P + */ + do + { + mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) ); + +cleanup: + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Use the blinding method and optimisation suggested in section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +SSL_ROM_TEXT_SECTION +static int dhm_update_blinding( dhm_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count; + + /* + * Don't use any blinding the first time a particular X is used, + * but remember it to use blinding next time. + */ + if( mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) + { + MPI_CHK( mpi_copy( &ctx->pX, &ctx->X ) ); + MPI_CHK( mpi_lset( &ctx->Vi, 1 ) ); + MPI_CHK( mpi_lset( &ctx->Vf, 1 ) ); + + return( 0 ); + } + + /* + * Ok, we need blinding. Can we re-use existing values? + * If yes, just update them by squaring them. + */ + if( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) + { + MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); + + MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); + + return( 0 ); + } + + /* + * We need to generate blinding values from scratch + */ + + /* Vi = random( 2, P-1 ) */ + count = 0; + do + { + mpi_fill_random( &ctx->Vi, mpi_size( &ctx->P ), f_rng, p_rng ); + + while( mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &ctx->Vi, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); + } + while( mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); + + /* Vf = Vi^-X mod P */ + MPI_CHK( mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); + MPI_CHK( mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); + +cleanup: + return( ret ); +} + +/* + * Derive and export the shared secret (G^Y)^X mod P + */ +SSL_ROM_TEXT_SECTION +int dhm_calc_secret( dhm_context *ctx, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mpi GYb; + + if( ctx == NULL || *olen < ctx->len ) + return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + mpi_init( &GYb ); + + /* Blind peer's value */ + if( f_rng != NULL ) + { + MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); + } + else + MPI_CHK( mpi_copy( &GYb, &ctx->GY ) ); + + /* Do modular exponentiation */ + MPI_CHK( mpi_exp_mod( &ctx->K, &GYb, &ctx->X, + &ctx->P, &ctx->RP ) ); + + /* Unblind secret value */ + if( f_rng != NULL ) + { + MPI_CHK( mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); + } + + *olen = mpi_size( &ctx->K ); + + MPI_CHK( mpi_write_binary( &ctx->K, output, *olen ) ); + +cleanup: + mpi_free( &GYb ); + + if( ret != 0 ) + return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret ); + + return( 0 ); +} + +/* + * Free the components of a DHM key + */ +SSL_ROM_TEXT_SECTION +void dhm_free( dhm_context *ctx ) +{ + mpi_free( &ctx->pX); mpi_free( &ctx->Vf ); mpi_free( &ctx->Vi ); + mpi_free( &ctx->RP ); mpi_free( &ctx->K ); mpi_free( &ctx->GY ); + mpi_free( &ctx->GX ); mpi_free( &ctx->X ); mpi_free( &ctx->G ); + mpi_free( &ctx->P ); + + polarssl_zeroize( ctx, sizeof( dhm_context ) ); +} + +#if defined(POLARSSL_ASN1_PARSE_C) +/* + * Parse DHM parameters + */ +SSL_ROM_TEXT_SECTION +int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ) +{ + int ret; + size_t len; + unsigned char *p, *end; +#if defined(POLARSSL_PEM_PARSE_C) + pem_context pem; + + pem_init( &pem ); + + ret = pem_read_buffer( &pem, + "-----BEGIN DH PARAMETERS-----", + "-----END DH PARAMETERS-----", + dhmin, NULL, 0, &dhminlen ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + dhminlen = pem.buflen; + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + goto exit; + + p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; +#else + p = (unsigned char *) dhmin; +#endif /* POLARSSL_PEM_PARSE_C */ + end = p + dhminlen; + + /* + * DHParams ::= SEQUENCE { + * prime INTEGER, -- P + * generator INTEGER, -- g + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + end = p + len; + + if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + if( p != end ) + { + ret = POLARSSL_ERR_DHM_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + goto exit; + } + + ret = 0; + + dhm->len = mpi_size( &dhm->P ); + +exit: +#if defined(POLARSSL_PEM_PARSE_C) + pem_free( &pem ); +#endif + if( ret != 0 ) + dhm_free( dhm ); + + return( ret ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load all data from a file into a given buffer. + */ +SSL_ROM_TEXT_SECTION +static int load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL ) + { + fclose( f ); + return( POLARSSL_ERR_DHM_MALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + polarssl_free( *buf ); + return( POLARSSL_ERR_DHM_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + return( 0 ); +} + +/* + * Load and parse DHM parameters + */ +SSL_ROM_TEXT_SECTION +int dhm_parse_dhmfile( dhm_context *dhm, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = dhm_parse_dhm( dhm, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ +#endif /* POLARSSL_ASN1_PARSE_C */ + +#if defined(POLARSSL_SELF_TEST) + +#include "polarssl/certs.h" + +/* + * Checkup routine + */ +SSL_ROM_TEXT_SECTION +int dhm_self_test( int verbose ) +{ +#if defined(POLARSSL_CERTS_C) + int ret; + dhm_context dhm; + + dhm_init( &dhm ); + + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: " ); + + if( ( ret = dhm_parse_dhm( &dhm, (const unsigned char *) test_dhm_params, + strlen( test_dhm_params ) ) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + +exit: + dhm_free( &dhm ); + + return( ret ); +#else + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: skipped\n" ); + + return( 0 ); +#endif /* POLARSSL_CERTS_C */ +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_DHM_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdh.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdh.c new file mode 100644 index 0000000..0a0921b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdh.c @@ -0,0 +1,290 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * RFC 4492 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECDH_C) + +#include "polarssl/ecdh.h" + +/* + * Generate public key: simple wrapper around ecp_gen_keypair + */ +SSL_ROM_TEXT_SECTION +int ecdh_gen_public( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +SSL_ROM_TEXT_SECTION +int ecdh_compute_shared( ecp_group *grp, mpi *z, + const ecp_point *Q, const mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + ecp_point P; + + ecp_point_init( &P ); + + /* + * Make sure Q is a valid pubkey before using it + */ + MPI_CHK( ecp_check_pubkey( grp, Q ) ); + + MPI_CHK( ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); + + if( ecp_is_zero( &P ) ) + { + ret = POLARSSL_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MPI_CHK( mpi_copy( z, &P.X ) ); + +cleanup: + ecp_point_free( &P ); + + return( ret ); +} + +/* + * Initialize context + */ +SSL_ROM_TEXT_SECTION +void ecdh_init( ecdh_context *ctx ) +{ + memset( ctx, 0, sizeof( ecdh_context ) ); +} + +/* + * Free context + */ +SSL_ROM_TEXT_SECTION +void ecdh_free( ecdh_context *ctx ) +{ + if( ctx == NULL ) + return; + + ecp_group_free( &ctx->grp ); + ecp_point_free( &ctx->Q ); + ecp_point_free( &ctx->Qp ); + ecp_point_free( &ctx->Vi ); + ecp_point_free( &ctx->Vf ); + mpi_free( &ctx->d ); + mpi_free( &ctx->z ); + mpi_free( &ctx->_d ); +} + +/* + * Setup and write the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +SSL_ROM_TEXT_SECTION +int ecdh_make_params( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t grp_len, pt_len; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + if( ( ret = ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) ) + != 0 ) + return( ret ); + + buf += grp_len; + blen -= grp_len; + + if( ( ret = ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + &pt_len, buf, blen ) ) != 0 ) + return( ret ); + + *olen = grp_len + pt_len; + return( 0 ); +} + +/* + * Read the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +SSL_ROM_TEXT_SECTION +int ecdh_read_params( ecdh_context *ctx, + const unsigned char **buf, const unsigned char *end ) +{ + int ret; + + if( ( ret = ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) + return( ret ); + + if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) + != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Get parameters from a keypair + */ +SSL_ROM_TEXT_SECTION +int ecdh_get_params( ecdh_context *ctx, const ecp_keypair *key, + ecdh_side side ) +{ + int ret; + + if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) + return( ret ); + + /* If it's not our key, just import the public part as Qp */ + if( side == POLARSSL_ECDH_THEIRS ) + return( ecp_copy( &ctx->Qp, &key->Q ) ); + + /* Our key: import public (as Q) and private parts */ + if( side != POLARSSL_ECDH_OURS ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 || + ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Setup and export the client public value + */ +SSL_ROM_TEXT_SECTION +int ecdh_make_public( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + return ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + olen, buf, blen ); +} + +/* + * Parse and import the client's public value + */ +SSL_ROM_TEXT_SECTION +int ecdh_read_public( ecdh_context *ctx, + const unsigned char *buf, size_t blen ) +{ + int ret; + const unsigned char *p = buf; + + if( ctx == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) + return( ret ); + + if( (size_t)( p - buf ) != blen ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Derive and export the shared secret + */ +SSL_ROM_TEXT_SECTION +int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + if( mpi_size( &ctx->z ) > blen ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); + return mpi_write_binary( &ctx->z, buf, *olen ); +} + + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecdh_self_test( int verbose ) +{ + ((void) verbose ); + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECDH_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdsa.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdsa.c new file mode 100644 index 0000000..a60a53a --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecdsa.c @@ -0,0 +1,516 @@ +/* + * Elliptic curve DSA + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECDSA_C) + +#include "polarssl/ecdsa.h" +#include "polarssl/asn1write.h" + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +#include "polarssl/hmac_drbg.h" +#endif + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * This a hopefully temporary compatibility function. + * + * Since we can't ensure the caller will pass a valid md_alg before the next + * interface change, try to pick up a decent md by size. + * + * Argument is the minimum size in bytes of the MD output. + */ +SSL_ROM_TEXT_SECTION +static const md_info_t *md_info_by_size( size_t min_size ) +{ + const md_info_t *md_cur, *md_picked = NULL; + const int *md_alg; + + for( md_alg = md_list(); *md_alg != 0; md_alg++ ) + { + if( ( md_cur = md_info_from_type( *md_alg ) ) == NULL || + (size_t) md_cur->size < min_size || + ( md_picked != NULL && md_cur->size > md_picked->size ) ) + continue; + + md_picked = md_cur; + } + + return( md_picked ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Derive a suitable integer for group grp from a buffer of length len + * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 + */ +SSL_ROM_TEXT_SECTION +static int derive_mpi( const ecp_group *grp, mpi *x, + const unsigned char *buf, size_t blen ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MPI_CHK( mpi_read_binary( x, buf, use_size ) ); + if( use_size * 8 > grp->nbits ) + MPI_CHK( mpi_shift_r( x, use_size * 8 - grp->nbits ) ); + + /* While at it, reduce modulo N */ + if( mpi_cmp_mpi( x, &grp->N ) >= 0 ) + MPI_CHK( mpi_sub_mpi( x, x, &grp->N ) ); + +cleanup: + return( ret ); +} + +/* + * Compute ECDSA signature of a hashed message (SEC1 4.1.3) + * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) + */ +SSL_ROM_TEXT_SECTION +int ecdsa_sign( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, key_tries, sign_tries, blind_tries; + ecp_point R; + mpi k, e, t; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + ecp_point_init( &R ); + mpi_init( &k ); mpi_init( &e ); mpi_init( &t ); + + sign_tries = 0; + do + { + /* + * Steps 1-3: generate a suitable ephemeral keypair + * and set r = xR mod n + */ + key_tries = 0; + do + { + MPI_CHK( ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) ); + MPI_CHK( mpi_mod_mpi( r, &R.X, &grp->N ) ); + + if( key_tries++ > 10 ) + { + ret = POLARSSL_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mpi_cmp_int( r, 0 ) == 0 ); + + /* + * Step 5: derive MPI from hashed message + */ + MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + blind_tries = 0; + do + { + size_t n_size = ( grp->nbits + 7 ) / 8; + MPI_CHK( mpi_fill_random( &t, n_size, f_rng, p_rng ) ); + MPI_CHK( mpi_shift_r( &t, 8 * n_size - grp->nbits ) ); + + /* See ecp_gen_keypair() */ + if( ++blind_tries > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &t, 1 ) < 0 || + mpi_cmp_mpi( &t, &grp->N ) >= 0 ); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n + */ + MPI_CHK( mpi_mul_mpi( s, r, d ) ); + MPI_CHK( mpi_add_mpi( &e, &e, s ) ); + MPI_CHK( mpi_mul_mpi( &e, &e, &t ) ); + MPI_CHK( mpi_mul_mpi( &k, &k, &t ) ); + MPI_CHK( mpi_inv_mod( s, &k, &grp->N ) ); + MPI_CHK( mpi_mul_mpi( s, s, &e ) ); + MPI_CHK( mpi_mod_mpi( s, s, &grp->N ) ); + + if( sign_tries++ > 10 ) + { + ret = POLARSSL_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mpi_cmp_int( s, 0 ) == 0 ); + +cleanup: + ecp_point_free( &R ); + mpi_free( &k ); mpi_free( &e ); mpi_free( &t ); + + return( ret ); +} + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + */ +SSL_ROM_TEXT_SECTION +int ecdsa_sign_det( ecp_group *grp, mpi *r, mpi *s, + const mpi *d, const unsigned char *buf, size_t blen, + md_type_t md_alg ) +{ + int ret; + hmac_drbg_context rng_ctx; + unsigned char data[2 * POLARSSL_ECP_MAX_BYTES]; + size_t grp_len = ( grp->nbits + 7 ) / 8; + const md_info_t *md_info; + mpi h; + + /* Temporary fallback */ + if( md_alg == POLARSSL_MD_NONE ) + md_info = md_info_by_size( blen ); + else + md_info = md_info_from_type( md_alg ); + + if( md_info == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + mpi_init( &h ); + memset( &rng_ctx, 0, sizeof( hmac_drbg_context ) ); + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MPI_CHK( mpi_write_binary( d, data, grp_len ) ); + MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); + MPI_CHK( mpi_write_binary( &h, data + grp_len, grp_len ) ); + hmac_drbg_init_buf( &rng_ctx, md_info, data, 2 * grp_len ); + + ret = ecdsa_sign( grp, r, s, d, buf, blen, + hmac_drbg_random, &rng_ctx ); + +cleanup: + hmac_drbg_free( &rng_ctx ); + mpi_free( &h ); + + return( ret ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Verify ECDSA signature of hashed message (SEC1 4.1.4) + * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) + */ +SSL_ROM_TEXT_SECTION +int ecdsa_verify( ecp_group *grp, + const unsigned char *buf, size_t blen, + const ecp_point *Q, const mpi *r, const mpi *s) +{ + int ret; + mpi e, s_inv, u1, u2; + ecp_point R, P; + + ecp_point_init( &R ); ecp_point_init( &P ); + mpi_init( &e ); mpi_init( &s_inv ); mpi_init( &u1 ); mpi_init( &u2 ); + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Step 1: make sure r and s are in range 1..n-1 + */ + if( mpi_cmp_int( r, 1 ) < 0 || mpi_cmp_mpi( r, &grp->N ) >= 0 || + mpi_cmp_int( s, 1 ) < 0 || mpi_cmp_mpi( s, &grp->N ) >= 0 ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Additional precaution: make sure Q is valid + */ + MPI_CHK( ecp_check_pubkey( grp, Q ) ); + + /* + * Step 3: derive MPI from hashed message + */ + MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Step 4: u1 = e / s mod n, u2 = r / s mod n + */ + MPI_CHK( mpi_inv_mod( &s_inv, s, &grp->N ) ); + + MPI_CHK( mpi_mul_mpi( &u1, &e, &s_inv ) ); + MPI_CHK( mpi_mod_mpi( &u1, &u1, &grp->N ) ); + + MPI_CHK( mpi_mul_mpi( &u2, r, &s_inv ) ); + MPI_CHK( mpi_mod_mpi( &u2, &u2, &grp->N ) ); + + /* + * Step 5: R = u1 G + u2 Q + * + * Since we're not using any secret data, no need to pass a RNG to + * ecp_mul() for countermesures. + */ + MPI_CHK( ecp_mul( grp, &R, &u1, &grp->G, NULL, NULL ) ); + MPI_CHK( ecp_mul( grp, &P, &u2, Q, NULL, NULL ) ); + MPI_CHK( ecp_add( grp, &R, &R, &P ) ); + + if( ecp_is_zero( &R ) ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 6: convert xR to an integer (no-op) + * Step 7: reduce xR mod n (gives v) + */ + MPI_CHK( mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); + + /* + * Step 8: check if v (that is, R.X) is equal to r + */ + if( mpi_cmp_mpi( &R.X, r ) != 0 ) + { + ret = POLARSSL_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + ecp_point_free( &R ); ecp_point_free( &P ); + mpi_free( &e ); mpi_free( &s_inv ); mpi_free( &u1 ); mpi_free( &u2 ); + + return( ret ); +} + +/* + * RFC 4492 page 20: + * + * Ecdsa-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * + * Size is at most + * 1 (tag) + 1 (len) + 1 (initial 0) + ECP_MAX_BYTES for each of r and s, + * twice that + 1 (tag) + 2 (len) for the sequence + * (assuming ECP_MAX_BYTES is less than 126 for r and s, + * and less than 124 (total len <= 255) for the sequence) + */ +#if POLARSSL_ECP_MAX_BYTES > 124 +#error "POLARSSL_ECP_MAX_BYTES bigger than expected, please fix MAX_SIG_LEN" +#endif +#define MAX_SIG_LEN ( 3 + 2 * ( 2 + POLARSSL_ECP_MAX_BYTES ) ) + +/* + * Convert a signature (given by context) to ASN.1 + */ +SSL_ROM_TEXT_SECTION +static int ecdsa_signature_to_asn1( ecdsa_context *ctx, + unsigned char *sig, size_t *slen ) +{ + int ret; + unsigned char buf[MAX_SIG_LEN]; + unsigned char *p = buf + sizeof( buf ); + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->s ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &p, buf, &ctx->r ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &p, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &p, buf, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ); + + memcpy( sig, p, len ); + *slen = len; + + return( 0 ); +} + +/* + * Compute and write signature + */ +SSL_ROM_TEXT_SECTION +int ecdsa_write_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ( ret = ecdsa_sign( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, + hash, hlen, f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); +} + +#if defined(POLARSSL_ECDSA_DETERMINISTIC) +/* + * Compute and write signature deterministically + */ +SSL_ROM_TEXT_SECTION +int ecdsa_write_signature_det( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + md_type_t md_alg ) +{ + int ret; + + if( ( ret = ecdsa_sign_det( &ctx->grp, &ctx->r, &ctx->s, &ctx->d, + hash, hlen, md_alg ) ) != 0 ) + { + return( ret ); + } + + return( ecdsa_signature_to_asn1( ctx, sig, slen ) ); +} +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ + +/* + * Read and check signature + */ +SSL_ROM_TEXT_SECTION +int ecdsa_read_signature( ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ) +{ + int ret; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret ); + } + + if( p + len != end ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = asn1_get_mpi( &p, end, &ctx->r ) ) != 0 || + ( ret = asn1_get_mpi( &p, end, &ctx->s ) ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA + ret ); + + if( ( ret = ecdsa_verify( &ctx->grp, hash, hlen, + &ctx->Q, &ctx->r, &ctx->s ) ) != 0 ) + return( ret ); + + if( p != end ) + return( POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +/* + * Generate key pair + */ +SSL_ROM_TEXT_SECTION +int ecdsa_genkey( ecdsa_context *ctx, ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + return( ecp_use_known_dp( &ctx->grp, gid ) || + ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); +} + +/* + * Set context from an ecp_keypair + */ +SSL_ROM_TEXT_SECTION +int ecdsa_from_keypair( ecdsa_context *ctx, const ecp_keypair *key ) +{ + int ret; + + if( ( ret = ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || + ( ret = mpi_copy( &ctx->d, &key->d ) ) != 0 || + ( ret = ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) + { + ecdsa_free( ctx ); + } + + return( ret ); +} + +/* + * Initialize context + */ +SSL_ROM_TEXT_SECTION +void ecdsa_init( ecdsa_context *ctx ) +{ + ecp_group_init( &ctx->grp ); + mpi_init( &ctx->d ); + ecp_point_init( &ctx->Q ); + mpi_init( &ctx->r ); + mpi_init( &ctx->s ); +} + +/* + * Free context + */ +SSL_ROM_TEXT_SECTION +void ecdsa_free( ecdsa_context *ctx ) +{ + ecp_group_free( &ctx->grp ); + mpi_free( &ctx->d ); + ecp_point_free( &ctx->Q ); + mpi_free( &ctx->r ); + mpi_free( &ctx->s ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecdsa_self_test( int verbose ) +{ + ((void) verbose ); + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECDSA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp.c new file mode 100644 index 0000000..a96172f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp.c @@ -0,0 +1,2080 @@ +/* + * Elliptic curves over GF(p): generic functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone + * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf + * RFC 4492 for the related TLS structures and constants + * + * [M255] http://cr.yp.to/ecdh/curve25519-20060209.pdf + * + * [2] CORON, Jean-Sébastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et BÉNÉTEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_SELF_TEST) +/* + * Counts of point addition and doubling, and field multiplications. + * Used to test resistance of point multiplication to simple timing attacks. + */ +static unsigned long add_count, dbl_count, mul_count; +#endif + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP384R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_BP512R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +#define POLARSSL_ECP_SHORT_WEIERSTRASS +#endif + +#if defined(POLARSSL_ECP_DP_M221_ENABLED) || \ + defined(POLARSSL_ECP_DP_M255_ENABLED) || \ + defined(POLARSSL_ECP_DP_M383_ENABLED) || \ + defined(POLARSSL_ECP_DP_M511_ENABLED) +#define POLARSSL_ECP_MONTGOMERY +#endif + +/* + * Curve types: internal for now, might be exposed later + */ +typedef enum +{ + POLARSSL_ECP_TYPE_NONE = 0, + POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + POLARSSL_ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} ecp_curve_type; + +/* + * List of supported curves: + * - internal ID + * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) + * - size in bits + * - readable name + * + * Curves are listed in order: largest curves first, and for a given size, + * fastest curves first. This provides the default order for the SSL module. + */ +SSL_ROM_DATA_SECTION +static const ecp_curve_info ecp_supported_curves[] = +{ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + { POLARSSL_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + { POLARSSL_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + { POLARSSL_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + { POLARSSL_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + { POLARSSL_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + { POLARSSL_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, +#endif +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + { POLARSSL_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + { POLARSSL_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + { POLARSSL_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + { POLARSSL_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + { POLARSSL_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, +#endif + { POLARSSL_ECP_DP_NONE, 0, 0, NULL }, +}; + +#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ + sizeof( ecp_supported_curves[0] ) + +//static ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; + +/* + * List of supported curves and associated info + */ +SSL_ROM_TEXT_SECTION +const ecp_curve_info *ecp_curve_list( void ) +{ + return( ecp_supported_curves ); +} + +/* + * List of supported curves, group ID only + */ +#if 0 +const ecp_group_id *ecp_grp_id_list( void ) +{ + static int init_done = 0; + + if( ! init_done ) + { + size_t i = 0; + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + ecp_supported_grp_id[i++] = curve_info->grp_id; + } + ecp_supported_grp_id[i] = POLARSSL_ECP_DP_NONE; + + init_done = 1; + } + + return( ecp_supported_grp_id ); +} +#endif +/* + * Get the curve info for the internal identifier + */ +SSL_ROM_TEXT_SECTION +const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->grp_id == grp_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the TLS identifier + */ +SSL_ROM_TEXT_SECTION +const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->tls_id == tls_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the name + */ +SSL_ROM_TEXT_SECTION +const ecp_curve_info *ecp_curve_info_from_name( const char *name ) +{ + const ecp_curve_info *curve_info; + + for( curve_info = ecp_curve_list(); + curve_info->grp_id != POLARSSL_ECP_DP_NONE; + curve_info++ ) + { + if( strcasecmp( curve_info->name, name ) == 0 ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the type of a curve + */ +SSL_ROM_TEXT_SECTION +static inline ecp_curve_type ecp_get_type( const ecp_group *grp ) +{ + if( grp->G.X.p == NULL ) + return( POLARSSL_ECP_TYPE_NONE ); + + if( grp->G.Y.p == NULL ) + return( POLARSSL_ECP_TYPE_MONTGOMERY ); + else + return( POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ); +} + +/* + * Initialize (the components of) a point + */ +SSL_ROM_TEXT_SECTION +void ecp_point_init( ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mpi_init( &pt->X ); + mpi_init( &pt->Y ); + mpi_init( &pt->Z ); +} + +/* + * Initialize (the components of) a group + */ +SSL_ROM_TEXT_SECTION +void ecp_group_init( ecp_group *grp ) +{ + if( grp == NULL ) + return; + + memset( grp, 0, sizeof( ecp_group ) ); +} + +/* + * Initialize (the components of) a key pair + */ +SSL_ROM_TEXT_SECTION +void ecp_keypair_init( ecp_keypair *key ) +{ + if( key == NULL ) + return; + + ecp_group_init( &key->grp ); + mpi_init( &key->d ); + ecp_point_init( &key->Q ); +} + +/* + * Unallocate (the components of) a point + */ +SSL_ROM_TEXT_SECTION +void ecp_point_free( ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mpi_free( &( pt->X ) ); + mpi_free( &( pt->Y ) ); + mpi_free( &( pt->Z ) ); +} + +/* + * Unallocate (the components of) a group + */ +SSL_ROM_TEXT_SECTION +void ecp_group_free( ecp_group *grp ) +{ + size_t i; + + if( grp == NULL ) + return; + + if( grp->h != 1 ) + { + mpi_free( &grp->P ); + mpi_free( &grp->A ); + mpi_free( &grp->B ); + ecp_point_free( &grp->G ); + mpi_free( &grp->N ); + } + + if( grp->T != NULL ) + { + for( i = 0; i < grp->T_size; i++ ) + ecp_point_free( &grp->T[i] ); + polarssl_free( grp->T ); + } + + polarssl_zeroize( grp, sizeof( ecp_group ) ); +} + +/* + * Unallocate (the components of) a key pair + */ +SSL_ROM_TEXT_SECTION +void ecp_keypair_free( ecp_keypair *key ) +{ + if( key == NULL ) + return; + + ecp_group_free( &key->grp ); + mpi_free( &key->d ); + ecp_point_free( &key->Q ); +} + +/* + * Copy the contents of a point + */ +SSL_ROM_TEXT_SECTION +int ecp_copy( ecp_point *P, const ecp_point *Q ) +{ + int ret; + + MPI_CHK( mpi_copy( &P->X, &Q->X ) ); + MPI_CHK( mpi_copy( &P->Y, &Q->Y ) ); + MPI_CHK( mpi_copy( &P->Z, &Q->Z ) ); + +cleanup: + return( ret ); +} + +/* + * Copy the contents of a group object + */ +SSL_ROM_TEXT_SECTION +int ecp_group_copy( ecp_group *dst, const ecp_group *src ) +{ + return ecp_use_known_dp( dst, src->id ); +} + +/* + * Set point to zero + */ +SSL_ROM_TEXT_SECTION +int ecp_set_zero( ecp_point *pt ) +{ + int ret; + + MPI_CHK( mpi_lset( &pt->X , 1 ) ); + MPI_CHK( mpi_lset( &pt->Y , 1 ) ); + MPI_CHK( mpi_lset( &pt->Z , 0 ) ); + +cleanup: + return( ret ); +} + +/* + * Tell if a point is zero + */ +SSL_ROM_TEXT_SECTION +int ecp_is_zero( ecp_point *pt ) +{ + return( mpi_cmp_int( &pt->Z, 0 ) == 0 ); +} + +/* + * Import a non-zero point from ASCII strings + */ +SSL_ROM_TEXT_SECTION +int ecp_point_read_string( ecp_point *P, int radix, + const char *x, const char *y ) +{ + int ret; + + MPI_CHK( mpi_read_string( &P->X, radix, x ) ); + MPI_CHK( mpi_read_string( &P->Y, radix, y ) ); + MPI_CHK( mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Export a point into unsigned binary data (SEC1 2.3.3) + */ +SSL_ROM_TEXT_SECTION +int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ) +{ + int ret = 0; + size_t plen; + + if( format != POLARSSL_ECP_PF_UNCOMPRESSED && + format != POLARSSL_ECP_PF_COMPRESSED ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Common case: P == 0 + */ + if( mpi_cmp_int( &P->Z, 0 ) == 0 ) + { + if( buflen < 1 ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x00; + *olen = 1; + + return( 0 ); + } + + plen = mpi_size( &grp->P ); + + if( format == POLARSSL_ECP_PF_UNCOMPRESSED ) + { + *olen = 2 * plen + 1; + + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x04; + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + MPI_CHK( mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + } + else if( format == POLARSSL_ECP_PF_COMPRESSED ) + { + *olen = plen + 1; + + if( buflen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x02 + mpi_get_bit( &P->Y, 0 ); + MPI_CHK( mpi_write_binary( &P->X, buf + 1, plen ) ); + } + +cleanup: + return( ret ); +} + +/* + * Import a point from unsigned binary data (SEC1 2.3.4) + */ +SSL_ROM_TEXT_SECTION +int ecp_point_read_binary( const ecp_group *grp, ecp_point *pt, + const unsigned char *buf, size_t ilen ) +{ + int ret; + size_t plen; + + if ( ilen < 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( buf[0] == 0x00 ) + { + if( ilen == 1 ) + return( ecp_set_zero( pt ) ); + else + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + } + + plen = mpi_size( &grp->P ); + + if( buf[0] != 0x04 ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + if( ilen != 2 * plen + 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + MPI_CHK( mpi_read_binary( &pt->X, buf + 1, plen ) ); + MPI_CHK( mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); + MPI_CHK( mpi_lset( &pt->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Import a point from a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +SSL_ROM_TEXT_SECTION +int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt, + const unsigned char **buf, size_t buf_len ) +{ + unsigned char data_len; + const unsigned char *buf_start; + + /* + * We must have at least two bytes (1 for length, at least one for data) + */ + if( buf_len < 2 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + data_len = *(*buf)++; + if( data_len < 1 || data_len > buf_len - 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Save buffer start for read_binary and update buf + */ + buf_start = *buf; + *buf += data_len; + + return ecp_point_read_binary( grp, pt, buf_start, data_len ); +} + +/* + * Export a point as a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +SSL_ROM_TEXT_SECTION +int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ) +{ + int ret; + + /* + * buffer length must be at least one, for our length byte + */ + if( blen < 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_point_write_binary( grp, pt, format, + olen, buf + 1, blen - 1) ) != 0 ) + return( ret ); + + /* + * write length to the first byte and update total length + */ + buf[0] = (unsigned char) *olen; + ++*olen; + + return( 0 ); +} + +/* + * Import an ECP group from ASCII strings, case A == -3 + */ +SSL_ROM_TEXT_SECTION +int ecp_group_read_string( ecp_group *grp, int radix, + const char *p, const char *b, + const char *gx, const char *gy, const char *n) +{ + int ret; + + MPI_CHK( mpi_read_string( &grp->P, radix, p ) ); + MPI_CHK( mpi_read_string( &grp->B, radix, b ) ); + MPI_CHK( ecp_point_read_string( &grp->G, radix, gx, gy ) ); + MPI_CHK( mpi_read_string( &grp->N, radix, n ) ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} + +/* + * Set a group from an ECParameters record (RFC 4492) + */ +SSL_ROM_TEXT_SECTION +int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len ) +{ + uint16_t tls_id; + const ecp_curve_info *curve_info; + + /* + * We expect at least three bytes (see below) + */ + if( len < 3 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * First byte is curve_type; only named_curve is handled + */ + if( *(*buf)++ != POLARSSL_ECP_TLS_NAMED_CURVE ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Next two bytes are the namedcurve value + */ + tls_id = *(*buf)++; + tls_id <<= 8; + tls_id |= *(*buf)++; + + if( ( curve_info = ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + return ecp_use_known_dp( grp, curve_info->grp_id ); +} + +/* + * Write the ECParameters record corresponding to a group (RFC 4492) + */ +SSL_ROM_TEXT_SECTION +int ecp_tls_write_group( const ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen ) +{ + const ecp_curve_info *curve_info; + + if( ( curve_info = ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * We are going to write 3 bytes (see below) + */ + *olen = 3; + if( blen < *olen ) + return( POLARSSL_ERR_ECP_BUFFER_TOO_SMALL ); + + /* + * First byte is curve_type, always named_curve + */ + *buf++ = POLARSSL_ECP_TLS_NAMED_CURVE; + + /* + * Next two bytes are the namedcurve value + */ + buf[0] = curve_info->tls_id >> 8; + buf[1] = curve_info->tls_id & 0xFF; + + return( 0 ); +} + +/* + * Wrapper around fast quasi-modp functions, with fall-back to mpi_mod_mpi. + * See the documentation of struct ecp_group. + * + * This function is in the critial loop for ecp_mul, so pay attention to perf. + */ +SSL_ROM_TEXT_SECTION +static int ecp_modp( mpi *N, const ecp_group *grp ) +{ + int ret; + + if( grp->modp == NULL ) + return( mpi_mod_mpi( N, N, &grp->P ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + if( ( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 ) || + mpi_msb( N ) > 2 * grp->pbits ) + { + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + } + + MPI_CHK( grp->modp( N ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + while( N->s < 0 && mpi_cmp_int( N, 0 ) != 0 ) + MPI_CHK( mpi_add_mpi( N, N, &grp->P ) ); + + while( mpi_cmp_mpi( N, &grp->P ) >= 0 ) + /* we known P, N and the result are positive */ + MPI_CHK( mpi_sub_abs( N, N, &grp->P ) ); + +cleanup: + return( ret ); +} + +/* + * Fast mod-p functions expect their argument to be in the 0..p^2 range. + * + * In order to guarantee that, we need to ensure that operands of + * mpi_mul_mpi are in the 0..p range. So, after each operation we will + * bring the result back to this range. + * + * The following macros are shortcuts for doing that. + */ + +/* + * Reduce a mpi mod p in-place, general case, to use after mpi_mul_mpi + */ +#if defined(POLARSSL_SELF_TEST) +#define INC_MUL_COUNT mul_count++; +#else +#define INC_MUL_COUNT +#endif + +#define MOD_MUL( N ) do { MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ + while( 0 ) + +/* + * Reduce a mpi mod p in-place, to use after mpi_sub_mpi + * N->s < 0 is a very fast test, which fails only if N is 0 + */ +#define MOD_SUB( N ) \ + while( N.s < 0 && mpi_cmp_int( &N, 0 ) != 0 ) \ + MPI_CHK( mpi_add_mpi( &N, &N, &grp->P ) ) + +/* + * Reduce a mpi mod p in-place, to use after mpi_add_mpi and mpi_mul_int. + * We known P, N and the result are positive, so sub_abs is correct, and + * a bit faster. + */ +#define MOD_ADD( N ) \ + while( mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ + MPI_CHK( mpi_sub_abs( &N, &N, &grp->P ) ) + +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) +/* + * For curves in short Weierstrass form, we do all the internal operations in + * Jacobian coordinates. + * + * For multiplication, we'll use a comb method with coutermeasueres against + * SPA, hence timing attacks. + */ + +/* + * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) + * Cost: 1N := 1I + 3M + 1S + */ +SSL_ROM_TEXT_SECTION +static int ecp_normalize_jac( const ecp_group *grp, ecp_point *pt ) +{ + int ret; + mpi Zi, ZZi; + + if( mpi_cmp_int( &pt->Z, 0 ) == 0 ) + return( 0 ); + + mpi_init( &Zi ); mpi_init( &ZZi ); + + /* + * X = X / Z^2 mod p + */ + MPI_CHK( mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); + MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); + + /* + * Y = Y / Z^3 mod p + */ + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); + + /* + * Z = 1 + */ + MPI_CHK( mpi_lset( &pt->Z, 1 ) ); + +cleanup: + + mpi_free( &Zi ); mpi_free( &ZZi ); + + return( ret ); +} + +/* + * Normalize jacobian coordinates of an array of (pointers to) points, + * using Montgomery's trick to perform only one inversion mod P. + * (See for example Cohen's "A Course in Computational Algebraic Number + * Theory", Algorithm 10.3.4.) + * + * Warning: fails (returning an error) if one of the points is zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * Cost: 1N(t) := 1I + (6t - 3)M + 1S + */ +SSL_ROM_TEXT_SECTION +static int ecp_normalize_jac_many( const ecp_group *grp, + ecp_point *T[], size_t t_len ) +{ + int ret; + size_t i; + mpi *c, u, Zi, ZZi; + + if( t_len < 2 ) + return( ecp_normalize_jac( grp, *T ) ); + + if( ( c = (mpi *) polarssl_malloc( t_len * sizeof( mpi ) ) ) == NULL ) + return( POLARSSL_ERR_ECP_MALLOC_FAILED ); + + mpi_init( &u ); mpi_init( &Zi ); mpi_init( &ZZi ); + for( i = 0; i < t_len; i++ ) + mpi_init( &c[i] ); + + /* + * c[i] = Z_0 * ... * Z_i + */ + MPI_CHK( mpi_copy( &c[0], &T[0]->Z ) ); + for( i = 1; i < t_len; i++ ) + { + MPI_CHK( mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); + MOD_MUL( c[i] ); + } + + /* + * u = 1 / (Z_0 * ... * Z_n) mod P + */ + MPI_CHK( mpi_inv_mod( &u, &c[t_len-1], &grp->P ) ); + + for( i = t_len - 1; ; i-- ) + { + /* + * Zi = 1 / Z_i mod p + * u = 1 / (Z_0 * ... * Z_i) mod P + */ + if( i == 0 ) { + MPI_CHK( mpi_copy( &Zi, &u ) ); + } + else + { + MPI_CHK( mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); + MPI_CHK( mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); + } + + /* + * proceed as in normalize() + */ + MPI_CHK( mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MPI_CHK( mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); + MPI_CHK( mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); + + /* + * Post-precessing: reclaim some memory by shrinking coordinates + * - not storing Z (always 1) + * - shrinking other coordinates, but still keeping the same number of + * limbs as P, as otherwise it will too likely be regrown too fast. + */ + MPI_CHK( mpi_shrink( &T[i]->X, grp->P.n ) ); + MPI_CHK( mpi_shrink( &T[i]->Y, grp->P.n ) ); + mpi_free( &T[i]->Z ); + + if( i == 0 ) + break; + } + +cleanup: + + mpi_free( &u ); mpi_free( &Zi ); mpi_free( &ZZi ); + for( i = 0; i < t_len; i++ ) + mpi_free( &c[i] ); + polarssl_free( c ); + + return( ret ); +} + +/* + * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. + * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid + */ +SSL_ROM_TEXT_SECTION +static int ecp_safe_invert_jac( const ecp_group *grp, + ecp_point *Q, + unsigned char inv ) +{ + int ret; + unsigned char nonzero; + mpi mQY; + + mpi_init( &mQY ); + + /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ + MPI_CHK( mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); + nonzero = mpi_cmp_int( &Q->Y, 0 ) != 0; + MPI_CHK( mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); + +cleanup: + mpi_free( &mQY ); + + return( ret ); +} + +/* + * Point doubling R = 2 P, Jacobian coordinates + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian/doubling/dbl-2007-bl.op3 + * with heavy variable renaming, some reordering and one minor modification + * (a = 2 * b, c = d - 2a replaced with c = d, c = c - b, c = c - b) + * in order to use a lot less intermediate variables (6 vs 25). + * + * Cost: 1D := 2M + 8S + */ +SSL_ROM_TEXT_SECTION +static int ecp_double_jac( const ecp_group *grp, ecp_point *R, + const ecp_point *P ) +{ + int ret; + mpi T1, T2, T3, X3, Y3, Z3; + +#if defined(POLARSSL_SELF_TEST) + dbl_count++; +#endif + + mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); + mpi_init( &X3 ); mpi_init( &Y3 ); mpi_init( &Z3 ); + + MPI_CHK( mpi_mul_mpi( &T3, &P->X, &P->X ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T2, &P->Y, &P->Y ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_mul_mpi( &Y3, &T2, &T2 ) ); MOD_MUL( Y3 ); + MPI_CHK( mpi_add_mpi( &X3, &P->X, &T2 ) ); MOD_ADD( X3 ); + MPI_CHK( mpi_mul_mpi( &X3, &X3, &X3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &Y3 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T3 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_mul_int( &T1, &X3, 2 ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &Z3, &P->Z, &P->Z ) ); MOD_MUL( Z3 ); + MPI_CHK( mpi_mul_mpi( &X3, &Z3, &Z3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_mul_int( &T3, &T3, 3 ) ); MOD_ADD( T3 ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_mul_int( &X3, &X3, 3 ) ); + X3.s = -1; /* mpi_mul_int doesn't handle negative numbers */ + MOD_SUB( X3 ); + } + else + MPI_CHK( mpi_mul_mpi( &X3, &X3, &grp->A ) ); MOD_MUL( X3 ); + + MPI_CHK( mpi_add_mpi( &T3, &T3, &X3 ) ); MOD_ADD( T3 ); + MPI_CHK( mpi_mul_mpi( &X3, &T3, &T3 ) ); MOD_MUL( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &X3, &X3, &T1 ) ); MOD_SUB( X3 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &X3 ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_mul_mpi( &T1, &T3, &T1 ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_int( &T3, &Y3, 8 ) ); MOD_ADD( T3 ); + MPI_CHK( mpi_sub_mpi( &Y3, &T1, &T3 ) ); MOD_SUB( Y3 ); + MPI_CHK( mpi_add_mpi( &T1, &P->Y, &P->Z ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &T1, &T1, &T1 ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &T2 ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_sub_mpi( &Z3, &T1, &Z3 ) ); MOD_SUB( Z3 ); + + MPI_CHK( mpi_copy( &R->X, &X3 ) ); + MPI_CHK( mpi_copy( &R->Y, &Y3 ) ); + MPI_CHK( mpi_copy( &R->Z, &Z3 ) ); + +cleanup: + mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); + mpi_free( &X3 ); mpi_free( &Y3 ); mpi_free( &Z3 ); + + return( ret ); +} + +/* + * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. + * None of these cases can happen as intermediate step in ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base point, the factor + * being less than its order, so none of them is zero; + * - Q is an odd multiple of the base point, P an even multiple, + * due to the choice of precomputed points in the modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as meaning 1. + * + * Cost: 1A := 8M + 3S + */ +SSL_ROM_TEXT_SECTION +static int ecp_add_mixed( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + mpi T1, T2, T3, T4, X, Y, Z; + +#if defined(POLARSSL_SELF_TEST) + add_count++; +#endif + + /* + * Trivial cases: P == 0 or Q == 0 (case 1) + */ + if( mpi_cmp_int( &P->Z, 0 ) == 0 ) + return( ecp_copy( R, Q ) ); + + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 0 ) == 0 ) + return( ecp_copy( R, P ) ); + + /* + * Make sure Q coordinates are normalized + */ + if( Q->Z.p != NULL && mpi_cmp_int( &Q->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + mpi_init( &T1 ); mpi_init( &T2 ); mpi_init( &T3 ); mpi_init( &T4 ); + mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); + + MPI_CHK( mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); + MPI_CHK( mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); + MPI_CHK( mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); + MPI_CHK( mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); + + /* Special cases (2) and (3) */ + if( mpi_cmp_int( &T1, 0 ) == 0 ) + { + if( mpi_cmp_int( &T2, 0 ) == 0 ) + { + ret = ecp_double_jac( grp, R, P ); + goto cleanup; + } + else + { + ret = ecp_set_zero( R ); + goto cleanup; + } + } + + MPI_CHK( mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); + MPI_CHK( mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); + MPI_CHK( mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); + MPI_CHK( mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); + MPI_CHK( mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); + MPI_CHK( mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); + MPI_CHK( mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); + MPI_CHK( mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); + MPI_CHK( mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); + + MPI_CHK( mpi_copy( &R->X, &X ) ); + MPI_CHK( mpi_copy( &R->Y, &Y ) ); + MPI_CHK( mpi_copy( &R->Z, &Z ) ); + +cleanup: + + mpi_free( &T1 ); mpi_free( &T2 ); mpi_free( &T3 ); mpi_free( &T4 ); + mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); + + return( ret ); +} + +/* + * Addition: R = P + Q, result's coordinates normalized + */ +SSL_ROM_TEXT_SECTION +int ecp_add( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + MPI_CHK( ecp_add_mixed( grp, R, P, Q ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + return( ret ); +} + +/* + * Subtraction: R = P - Q, result's coordinates normalized + */ +SSL_ROM_TEXT_SECTION +int ecp_sub( const ecp_group *grp, ecp_point *R, + const ecp_point *P, const ecp_point *Q ) +{ + int ret; + ecp_point mQ; + + ecp_point_init( &mQ ); + + if( ecp_get_type( grp ) != POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + + /* mQ = - Q */ + MPI_CHK( ecp_copy( &mQ, Q ) ); + if( mpi_cmp_int( &mQ.Y, 0 ) != 0 ) + MPI_CHK( mpi_sub_mpi( &mQ.Y, &grp->P, &mQ.Y ) ); + + MPI_CHK( ecp_add_mixed( grp, R, P, &mQ ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + ecp_point_free( &mQ ); + + return( ret ); +} + +/* + * Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_jac(). + * + * This countermeasure was first suggested in [2]. + */ +SSL_ROM_TEXT_SECTION +static int ecp_randomize_jac( const ecp_group *grp, ecp_point *pt, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mpi l, ll; + size_t p_size = ( grp->pbits + 7 ) / 8; + int count = 0; + + mpi_init( &l ); mpi_init( &ll ); + + /* Generate l such that 1 < l < p */ + do + { + mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &l, 1 ) <= 0 ); + + /* Z = l * Z */ + MPI_CHK( mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); + + /* X = l^2 * X */ + MPI_CHK( mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); + MPI_CHK( mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); + + /* Y = l^3 * Y */ + MPI_CHK( mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); + MPI_CHK( mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); + +cleanup: + mpi_free( &l ); mpi_free( &ll ); + + return( ret ); +} + +/* + * Check and define parameters used by the comb method (see below for details) + */ +#if POLARSSL_ECP_WINDOW_SIZE < 2 || POLARSSL_ECP_WINDOW_SIZE > 7 +#error "POLARSSL_ECP_WINDOW_SIZE out of bounds" +#endif + +/* d = ceil( n / w ) */ +#define COMB_MAX_D ( POLARSSL_ECP_MAX_BITS + 1 ) / 2 + +/* number of precomputed points */ +#define COMB_MAX_PRE ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) ) + +/* + * Compute the representation of m that will be used with our comb method. + * + * The basic comb method is described in GECC 3.44 for example. We use a + * modified version that provides resistance to SPA by avoiding zero + * digits in the representation as in [3]. We modify the method further by + * requiring that all K_i be odd, which has the small cost that our + * representation uses one more K_i, due to carries. + * + * Also, for the sake of compactness, only the seven low-order bits of x[i] + * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in + * the paper): it is set if and only if if s_i == -1; + * + * Calling conventions: + * - x is an array of size d + 1 + * - w is the size, ie number of teeth, of the comb, and must be between + * 2 and 7 (in practice, between 2 and POLARSSL_ECP_WINDOW_SIZE) + * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d + * (the result will be incorrect if these assumptions are not satisfied) + */ +SSL_ROM_TEXT_SECTION +static void ecp_comb_fixed( unsigned char x[], size_t d, + unsigned char w, const mpi *m ) +{ + size_t i, j; + unsigned char c, cc, adjust; + + memset( x, 0, d+1 ); + + /* First get the classical comb values (except for x_d = 0) */ + for( i = 0; i < d; i++ ) + for( j = 0; j < w; j++ ) + x[i] |= mpi_get_bit( m, i + d * j ) << j; + + /* Now make sure x_1 .. x_d are odd */ + c = 0; + for( i = 1; i <= d; i++ ) + { + /* Add carry and update it */ + cc = x[i] & c; + x[i] = x[i] ^ c; + c = cc; + + /* Adjust if needed, avoiding branches */ + adjust = 1 - ( x[i] & 0x01 ); + c |= x[i] & ( x[i-1] * adjust ); + x[i] = x[i] ^ ( x[i-1] * adjust ); + x[i-1] |= adjust << 7; + } +} + +/* + * Precompute points for the comb method + * + * If i = i_{w-1} ... i_1 is the binary representation of i, then + * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P + * + * T must be able to hold 2^{w - 1} elements + * + * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) + */ +SSL_ROM_TEXT_SECTION +static int ecp_precompute_comb( const ecp_group *grp, + ecp_point T[], const ecp_point *P, + unsigned char w, size_t d ) +{ + int ret; + unsigned char i, k; + size_t j; + ecp_point *cur, *TT[COMB_MAX_PRE - 1]; + + /* + * Set T[0] = P and + * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) + */ + MPI_CHK( ecp_copy( &T[0], P ) ); + + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + cur = T + i; + MPI_CHK( ecp_copy( cur, T + ( i >> 1 ) ) ); + for( j = 0; j < d; j++ ) + MPI_CHK( ecp_double_jac( grp, cur, cur ) ); + + TT[k++] = cur; + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + + /* + * Compute the remaining ones using the minimal number of additions + * Be careful to update T[2^l] only after using it! + */ + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + j = i; + while( j-- ) + { + MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); + TT[k++] = &T[i + j]; + } + } + + MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + +cleanup: + return( ret ); +} + +/* + * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] + */ +SSL_ROM_TEXT_SECTION +static int ecp_select_comb( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + unsigned char i ) +{ + int ret; + unsigned char ii, j; + + /* Ignore the "sign" bit and scale down */ + ii = ( i & 0x7Fu ) >> 1; + + /* Read the whole table to thwart cache-based timing attacks */ + for( j = 0; j < t_len; j++ ) + { + MPI_CHK( mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); + MPI_CHK( mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); + } + + /* Safely invert result if i is "negative" */ + MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); + +cleanup: + return( ret ); +} + +/* + * Core multiplication algorithm for the (modified) comb method. + * This part is actually common with the basic comb method (GECC 3.44) + * + * Cost: d A + d D + 1 R + */ +SSL_ROM_TEXT_SECTION +static int ecp_mul_comb_core( const ecp_group *grp, ecp_point *R, + const ecp_point T[], unsigned char t_len, + const unsigned char x[], size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + ecp_point Txi; + size_t i; + + ecp_point_init( &Txi ); + + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) ); + MPI_CHK( mpi_lset( &R->Z, 1 ) ); + if( f_rng != 0 ) + MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); + + while( i-- != 0 ) + { + MPI_CHK( ecp_double_jac( grp, R, R ) ); + MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) ); + MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); + } + +cleanup: + ecp_point_free( &Txi ); + + return( ret ); +} + +/* + * Multiplication using the comb method, + * for curves in short Weierstrass form + */ +SSL_ROM_TEXT_SECTION +static int ecp_mul_comb( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char w, m_is_odd, p_eq_g, pre_len, i; + size_t d; + unsigned char k[COMB_MAX_D + 1]; + ecp_point *T; + mpi M, mm; + + mpi_init( &M ); + mpi_init( &mm ); + + /* we need N to be odd to trnaform m in an odd number, check now */ + if( mpi_get_bit( &grp->N, 0 ) != 1 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Minimize the number of multiplications, that is minimize + * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) + * (see costs of the various parts, with 1S = 1M) + */ + w = grp->nbits >= 384 ? 5 : 4; + + /* + * If P == G, pre-compute a bit more, since this may be re-used later. + * Just adding one avoids upping the cost of the first mul too much, + * and the memory cost too. + */ +#if POLARSSL_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = ( mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && + mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); + if( p_eq_g ) + w++; +#else + p_eq_g = 0; +#endif + + /* + * Make sure w is within bounds. + * (The last test is useful only for very small curves in the test suite.) + */ + if( w > POLARSSL_ECP_WINDOW_SIZE ) + w = POLARSSL_ECP_WINDOW_SIZE; + if( w >= grp->nbits ) + w = 2; + + /* Other sizes that depend on w */ + pre_len = 1U << ( w - 1 ); + d = ( grp->nbits + w - 1 ) / w; + + /* + * Prepare precomputed points: if P == G we want to + * use grp->T if already initialized, or initialize it. + */ + T = p_eq_g ? grp->T : NULL; + + if( T == NULL ) + { + T = (ecp_point *) polarssl_malloc( pre_len * sizeof( ecp_point ) ); + if( T == NULL ) + { + ret = POLARSSL_ERR_ECP_MALLOC_FAILED; + goto cleanup; + } + + for( i = 0; i < pre_len; i++ ) + ecp_point_init( &T[i] ); + + MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) ); + + if( p_eq_g ) + { + grp->T = T; + grp->T_size = pre_len; + } + } + + /* + * Make sure M is odd (M = m or M = N - m, since N is odd) + * using the fact that m * P = - (N - m) * P + */ + m_is_odd = ( mpi_get_bit( m, 0 ) == 1 ); + MPI_CHK( mpi_copy( &M, m ) ); + MPI_CHK( mpi_sub_mpi( &mm, &grp->N, m ) ); + MPI_CHK( mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) ); + + /* + * Go for comb multiplication, R = M * P + */ + ecp_comb_fixed( k, d, w, &M ); + MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) ); + + /* + * Now get m * P from M * P and normalize it + */ + MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) ); + MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + + if( T != NULL && ! p_eq_g ) + { + for( i = 0; i < pre_len; i++ ) + ecp_point_free( &T[i] ); + polarssl_free( T ); + } + + mpi_free( &M ); + mpi_free( &mm ); + + if( ret != 0 ) + ecp_point_free( R ); + + return( ret ); +} + +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + +#if defined(POLARSSL_ECP_MONTGOMERY) +/* + * For Montgomery curves, we do all the internal arithmetic in projective + * coordinates. Import/export of points uses only the x coordinates, which is + * internaly represented as X / Z. + * + * For scalar multiplication, we'll use a Montgomery ladder. + */ + +/* + * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 + * Cost: 1M + 1I + */ +SSL_ROM_TEXT_SECTION +static int ecp_normalize_mxz( const ecp_group *grp, ecp_point *P ) +{ + int ret; + + MPI_CHK( mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_mxz(). + * + * This countermeasure was first suggested in [2]. + * Cost: 2M + */ +SSL_ROM_TEXT_SECTION +static int ecp_randomize_mxz( const ecp_group *grp, ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mpi l; + size_t p_size = ( grp->pbits + 7 ) / 8; + int count = 0; + + mpi_init( &l ); + + /* Generate l such that 1 < l < p */ + do + { + mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MPI_CHK( mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( &l, 1 ) <= 0 ); + + MPI_CHK( mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); + MPI_CHK( mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); + +cleanup: + mpi_free( &l ); + + return( ret ); +} + +/* + * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), + * for Montgomery curves in x/z coordinates. + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 + * with + * d = X1 + * P = (X2, Z2) + * Q = (X3, Z3) + * R = (X4, Z4) + * S = (X5, Z5) + * and eliminating temporary variables tO, ..., t4. + * + * Cost: 5M + 4S + */ +SSL_ROM_TEXT_SECTION +static int ecp_double_add_mxz( const ecp_group *grp, + ecp_point *R, ecp_point *S, + const ecp_point *P, const ecp_point *Q, + const mpi *d ) +{ + int ret; + mpi A, AA, B, BB, E, C, D, DA, CB; + + mpi_init( &A ); mpi_init( &AA ); mpi_init( &B ); + mpi_init( &BB ); mpi_init( &E ); mpi_init( &C ); + mpi_init( &D ); mpi_init( &DA ); mpi_init( &CB ); + + MPI_CHK( mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); + MPI_CHK( mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); + MPI_CHK( mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); + MPI_CHK( mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); + MPI_CHK( mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); + MPI_CHK( mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); + MPI_CHK( mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); + MPI_CHK( mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); + MPI_CHK( mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); + MPI_CHK( mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); + MPI_CHK( mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); + MPI_CHK( mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); + MPI_CHK( mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); + MPI_CHK( mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); + MPI_CHK( mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); + +cleanup: + mpi_free( &A ); mpi_free( &AA ); mpi_free( &B ); + mpi_free( &BB ); mpi_free( &E ); mpi_free( &C ); + mpi_free( &D ); mpi_free( &DA ); mpi_free( &CB ); + + return( ret ); +} + +/* + * Multiplication with Montgomery ladder in x/z coordinates, + * for curves in Montgomery form + */ +SSL_ROM_TEXT_SECTION +static int ecp_mul_mxz( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i; + unsigned char b; + ecp_point RP; + mpi PX; + + ecp_point_init( &RP ); mpi_init( &PX ); + + /* Save PX and read from P before writing to R, in case P == R */ + MPI_CHK( mpi_copy( &PX, &P->X ) ); + MPI_CHK( ecp_copy( &RP, P ) ); + + /* Set R to zero in modified x/z coordinates */ + MPI_CHK( mpi_lset( &R->X, 1 ) ); + MPI_CHK( mpi_lset( &R->Z, 0 ) ); + mpi_free( &R->Y ); + + /* RP.X might be sligtly larger than P, so reduce it */ + MOD_ADD( RP.X ); + + /* Randomize coordinates of the starting point */ + if( f_rng != NULL ) + MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); + + /* Loop invariant: R = result so far, RP = R + P */ + i = mpi_msb( m ); /* one past the (zero-based) most significant bit */ + while( i-- > 0 ) + { + b = mpi_get_bit( m, i ); + /* + * if (b) R = 2R + P else R = 2R, + * which is: + * if (b) double_add( RP, R, RP, R ) + * else double_add( R, RP, R, RP ) + * but using safe conditional swaps to avoid leaks + */ + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); + MPI_CHK( mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MPI_CHK( mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + } + + MPI_CHK( ecp_normalize_mxz( grp, R ) ); + +cleanup: + ecp_point_free( &RP ); mpi_free( &PX ); + + return( ret ); +} + +#endif /* POLARSSL_ECP_MONTGOMERY */ + +/* + * Multiplication R = m * P + */ +SSL_ROM_TEXT_SECTION +int ecp_mul( ecp_group *grp, ecp_point *R, + const mpi *m, const ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + + /* Common sanity checks */ + if( mpi_cmp_int( &P->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = ecp_check_privkey( grp, m ) ) != 0 || + ( ret = ecp_check_pubkey( grp, P ) ) != 0 ) + return( ret ); + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_mul_comb( grp, R, m, P, f_rng, p_rng ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) +/* + * Check that an affine point is valid as a public key, + * short weierstrass curves (SEC1 3.2.3.1) + */ +SSL_ROM_TEXT_SECTION +static int ecp_check_pubkey_sw( const ecp_group *grp, const ecp_point *pt ) +{ + int ret; + mpi YY, RHS; + + /* pt coordinates must be normalized for our checks */ + if( mpi_cmp_int( &pt->X, 0 ) < 0 || + mpi_cmp_int( &pt->Y, 0 ) < 0 || + mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || + mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + + mpi_init( &YY ); mpi_init( &RHS ); + + /* + * YY = Y^2 + * RHS = X (X^2 + A) + B = X^3 + A X + B + */ + MPI_CHK( mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); + MPI_CHK( mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MPI_CHK( mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); + } + else + { + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); + } + + MPI_CHK( mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); + MPI_CHK( mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); + + if( mpi_cmp_mpi( &YY, &RHS ) != 0 ) + ret = POLARSSL_ERR_ECP_INVALID_KEY; + +cleanup: + + mpi_free( &YY ); mpi_free( &RHS ); + + return( ret ); +} +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + + +#if defined(POLARSSL_ECP_MONTGOMERY) +/* + * Check validity of a public key for Montgomery curves with x-only schemes + */ +SSL_ROM_TEXT_SECTION +static int ecp_check_pubkey_mx( const ecp_group *grp, const ecp_point *pt ) +{ + /* [M255 p. 5] Just check X is the correct number of bytes */ + if( mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + + return( 0 ); +} +#endif /* POLARSSL_ECP_MONTGOMERY */ + +/* + * Check that a point is valid as a public key + */ +SSL_ROM_TEXT_SECTION +int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt ) +{ + /* Must use affine coordinates */ + if( mpi_cmp_int( &pt->Z, 1 ) != 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + return( ecp_check_pubkey_mx( grp, pt ) ); +#endif +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_check_pubkey_sw( grp, pt ) ); +#endif + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Check that an mpi is valid as a private key + */ +SSL_ROM_TEXT_SECTION +int ecp_check_privkey( const ecp_group *grp, const mpi *d ) +{ +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* see [M255] page 5 */ + if( mpi_get_bit( d, 0 ) != 0 || + mpi_get_bit( d, 1 ) != 0 || + mpi_get_bit( d, 2 ) != 0 || + mpi_msb( d ) - 1 != grp->nbits ) /* mpi_msb is one-based! */ + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* see SEC1 3.2 */ + if( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ) + return( POLARSSL_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Generate a keypair + */ +SSL_ROM_TEXT_SECTION +int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + +#if defined(POLARSSL_ECP_MONTGOMERY) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_MONTGOMERY ) + { + /* [M225] page 5 */ + size_t b; + + MPI_CHK( mpi_fill_random( d, n_size, f_rng, p_rng ) ); + + /* Make sure the most significant bit is nbits */ + b = mpi_msb( d ) - 1; /* mpi_msb is one-based */ + if( b > grp->nbits ) + MPI_CHK( mpi_shift_r( d, b - grp->nbits ) ); + else + MPI_CHK( mpi_set_bit( d, grp->nbits, 1 ) ); + + /* Make sure the last three bits are unset */ + MPI_CHK( mpi_set_bit( d, 0, 0 ) ); + MPI_CHK( mpi_set_bit( d, 1, 0 ) ); + MPI_CHK( mpi_set_bit( d, 2, 0 ) ); + } + else +#endif /* POLARSSL_ECP_MONTGOMERY */ +#if defined(POLARSSL_ECP_SHORT_WEIERSTRASS) + if( ecp_get_type( grp ) == POLARSSL_ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* SEC1 3.2.1: Generate d such that 1 <= n < N */ + int count = 0; + unsigned char rnd[POLARSSL_ECP_MAX_BYTES]; + + /* + * Match the procedure given in RFC 6979 (deterministic ECDSA): + * - use the same byte ordering; + * - keep the leftmost nbits bits of the generated octet string; + * - try until result is in the desired range. + * This also avoids any biais, which is especially important for ECDSA. + */ + do + { + MPI_CHK( f_rng( p_rng, rnd, n_size ) ); + MPI_CHK( mpi_read_binary( d, rnd, n_size ) ); + MPI_CHK( mpi_shift_r( d, 8 * n_size - grp->nbits ) ); + + /* + * Each try has at worst a probability 1/2 of failing (the msb has + * a probability 1/2 of being 0, and then the result will be < N), + * so after 30 tries failure probability is a most 2**(-30). + * + * For most curves, 1 try is enough with overwhelming probability, + * since N starts with a lot of 1s in binary, but some curves + * such as secp224k1 are actually very close to the worst case. + */ + if( ++count > 30 ) + return( POLARSSL_ERR_ECP_RANDOM_FAILED ); + } + while( mpi_cmp_int( d, 1 ) < 0 || + mpi_cmp_mpi( d, &grp->N ) >= 0 ); + } + else +#endif /* POLARSSL_ECP_SHORT_WEIERSTRASS */ + return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); + +cleanup: + if( ret != 0 ) + return( ret ); + + return( ecp_mul( grp, Q, d, &grp->G, f_rng, p_rng ) ); +} + +/* + * Generate a keypair, prettier wrapper + */ +SSL_ROM_TEXT_SECTION +int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + + if( ( ret = ecp_use_known_dp( &key->grp, grp_id ) ) != 0 ) + return( ret ); + + return( ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * Checkup routine + */ +int ecp_self_test( int verbose ) +{ + int ret; + size_t i; + ecp_group grp; + ecp_point R, P; + mpi m; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; + /* exponents especially adapted for secp192r1 */ + const char *exponents[] = + { + "000000000000000000000000000000000000000000000001", /* one */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ + "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ + }; + + ecp_group_init( &grp ); + ecp_point_init( &R ); + ecp_point_init( &P ); + mpi_init( &m ); + + /* Use secp192r1 if available, or any available curve */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) ); +#else + MPI_CHK( ecp_use_known_dp( &grp, ecp_curve_list()->grp_id ) ); +#endif + + if( verbose != 0 ) + polarssl_printf( " ECP test #1 (constant op_count, base point G): " ); + + /* Do a dummy multiplication first to trigger precomputation */ + MPI_CHK( mpi_lset( &m, 2 ) ); + MPI_CHK( ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " ECP test #2 (constant op_count, other point): " ); + /* We computed P = 2G last time, use it */ + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret < 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + ecp_group_free( &grp ); + ecp_point_free( &R ); + ecp_point_free( &P ); + mpi_free( &m ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_ECP_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp_curves.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp_curves.c new file mode 100644 index 0000000..a30e700 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/ecp_curves.c @@ -0,0 +1,1461 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_ECP_C) + +#include "polarssl/ecp.h" + +#if defined(_MSC_VER) && !defined(inline) +#define inline _inline +#else +#if defined(__ARMCC_VERSION) && !defined(inline) +#define inline __inline +#endif /* __ARMCC_VERSION */ +#endif /*_MSC_VER */ + +/* + * Conversion macros for embedded constants: + * build lists of t_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(POLARSSL_HAVE_INT8) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + a, b, c, d, e, f, g, h + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + a, b, c, d + +#define BYTES_TO_T_UINT_2( a, b ) \ + a, b + +#elif defined(POLARSSL_HAVE_INT16) + +#define BYTES_TO_T_UINT_2( a, b ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_2( a, b ), \ + BYTES_TO_T_UINT_2( c, d ), \ + BYTES_TO_T_UINT_2( e, f ), \ + BYTES_TO_T_UINT_2( g, h ) + +#elif defined(POLARSSL_HAVE_INT32) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_4( a, b, 0, 0 ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_4( a, b, c, d ), \ + BYTES_TO_T_UINT_4( e, f, g, h ) + +#else /* 64-bits */ + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + ( (t_uint) a << 0 ) | \ + ( (t_uint) b << 8 ) | \ + ( (t_uint) c << 16 ) | \ + ( (t_uint) d << 24 ) | \ + ( (t_uint) e << 32 ) | \ + ( (t_uint) f << 40 ) | \ + ( (t_uint) g << 48 ) | \ + ( (t_uint) h << 56 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) + +#endif /* bits in t_uint */ + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp192r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192r1_b[] = { + BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), + BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), + BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192r1_gx[] = { + BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), + BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), + BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192r1_gy[] = { + BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), + BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), + BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192r1_n[] = { + BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), + BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp224r1_p[] = { + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224r1_b[] = { + BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), + BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), + BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), + BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224r1_gx[] = { + BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), + BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), + BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), + BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224r1_gy[] = { + BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), + BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), + BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), + BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224r1_n[] = { + BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), + BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp256r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256r1_b[] = { + BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), + BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), + BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), + BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), + BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), + BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), + BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256r1_gy[] = { + BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), + BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), + BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), + BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256r1_n[] = { + BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), + BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp384r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp384r1_b[] = { + BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), + BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), + BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), + BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), + BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), + BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp384r1_gx[] = { + BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), + BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), + BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), + BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), + BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), + BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), + BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), + BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), + BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), + BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), + BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp384r1_n[] = { + BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), + BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), + BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp521r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp521r1_b[] = { + BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), + BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), + BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), + BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), + BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), + BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), + BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), + BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), + BYTES_TO_T_UINT_2( 0x51, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp521r1_gx[] = { + BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), + BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), + BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), + BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), + BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), + BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), + BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), + BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), + BYTES_TO_T_UINT_2( 0xC6, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp521r1_gy[] = { + BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), + BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), + BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), + BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), + BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), + BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), + BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), + BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), + BYTES_TO_T_UINT_2( 0x18, 0x01 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp521r1_n[] = { + BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), + BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), + BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), + BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), + BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_p[] = { + BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_b[] = { + BYTES_TO_T_UINT_2( 0x03, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_gx[] = { + BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), + BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), + BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_gy[] = { + BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), + BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), + BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp192k1_n[] = { + BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), + BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_p[] = { + BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_b[] = { + BYTES_TO_T_UINT_2( 0x05, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_gx[] = { + BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), + BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), + BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), + BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_gy[] = { + BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), + BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), + BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), + BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp224k1_n[] = { + BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), + BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), +}; +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_p[] = { + BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_b[] = { + BYTES_TO_T_UINT_2( 0x07, 0x00 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_gx[] = { + BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), + BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), + BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), + BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_gy[] = { + BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), + BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), + BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), + BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint secp256k1_n[] = { + BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), + BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_p[] = { + BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), + BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), + BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_a[] = { + BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), + BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), + BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), + BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_b[] = { + BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), + BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), + BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), + BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), + BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), + BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), + BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_gy[] = { + BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), + BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), + BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), + BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP256r1_n[] = { + BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), + BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), + BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_p[] = { + BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), + BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), + BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), + BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_a[] = { + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), + BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), + BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), + BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), + BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), + BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_b[] = { + BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), + BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), + BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), + BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), + BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_gx[] = { + BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), + BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), + BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), + BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), + BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), + BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), + BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), + BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), + BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), + BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP384r1_n[] = { + BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), + BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), + BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), + BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_p[] = { + BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), + BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), + BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), + BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), + BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_a[] = { + BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), + BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), + BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), + BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), + BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), + BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), + BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), + BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_b[] = { + BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), + BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), + BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), + BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), + BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), + BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), + BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), + BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_gx[] = { + BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), + BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), + BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), + BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), + BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), + BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), + BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), + BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_gy[] = { + BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), + BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), + BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), + BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), + BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), + BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), + BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), +}; +SSL_ROM_DATA_SECTION +static const t_uint brainpoolP512r1_n[] = { + BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), + BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), + BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), + BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), + BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof t_uint) + */ +SSL_ROM_TEXT_SECTION +static inline void ecp_mpi_load( mpi *X, const t_uint *p, size_t len ) +{ + X->s = 1; + X->n = len / sizeof( t_uint ); + X->p = (t_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +SSL_ROM_TEXT_SECTION +static inline void ecp_mpi_set1( mpi *X ) +{ + SSL_ROM_DATA_SECTION static const t_uint one[] = { 1 }; + X->s = 1; + X->n = 1; + X->p = one; +} + +/* + * Make group available from embedded constants + */ +SSL_ROM_TEXT_SECTION +static int ecp_group_load( ecp_group *grp, + const t_uint *p, size_t plen, + const t_uint *a, size_t alen, + const t_uint *b, size_t blen, + const t_uint *gx, size_t gxlen, + const t_uint *gy, size_t gylen, + const t_uint *n, size_t nlen) +{ + ecp_mpi_load( &grp->P, p, plen ); + if( a != NULL ) + ecp_mpi_load( &grp->A, a, alen ); + ecp_mpi_load( &grp->B, b, blen ); + ecp_mpi_load( &grp->N, n, nlen ); + + ecp_mpi_load( &grp->G.X, gx, gxlen ); + ecp_mpi_load( &grp->G.Y, gy, gylen ); + ecp_mpi_set1( &grp->G.Z ); + + grp->pbits = mpi_msb( &grp->P ); + grp->nbits = mpi_msb( &grp->N ); + + grp->h = 1; + + return( 0 ); +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521( mpi * ); +#endif + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +static int ecp_mod_p255( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1( mpi * ); +#endif +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1( mpi * ); +#endif + +#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#define LOAD_GROUP( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + NULL, 0, \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) +/* + * Specialized function for creating the Curve25519 group + */ +SSL_ROM_TEXT_SECTION +static int ecp_use_curve25519( ecp_group *grp ) +{ + int ret; + + /* Actually ( A + 2 ) / 4 */ + MPI_CHK( mpi_read_string( &grp->A, 16, "01DB42" ) ); + + /* P = 2^255 - 19 */ + MPI_CHK( mpi_lset( &grp->P, 1 ) ); + MPI_CHK( mpi_shift_l( &grp->P, 255 ) ); + MPI_CHK( mpi_sub_int( &grp->P, &grp->P, 19 ) ); + grp->pbits = mpi_msb( &grp->P ); + + /* Y intentionaly not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MPI_CHK( mpi_lset( &grp->G.X, 9 ) ); + MPI_CHK( mpi_lset( &grp->G.Z, 1 ) ); + mpi_free( &grp->G.Y ); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if( ret != 0 ) + ecp_group_free( grp ); + + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +SSL_ROM_TEXT_SECTION +int ecp_use_known_dp( ecp_group *grp, ecp_group_id id ) +{ + ecp_group_free( grp ); + + grp->id = id; + + switch( id ) + { +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + case POLARSSL_ECP_DP_SECP192R1: + NIST_MODP( p192 ); + return( LOAD_GROUP( secp192r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + case POLARSSL_ECP_DP_SECP224R1: + NIST_MODP( p224 ); + return( LOAD_GROUP( secp224r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + case POLARSSL_ECP_DP_SECP256R1: + NIST_MODP( p256 ); + return( LOAD_GROUP( secp256r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + case POLARSSL_ECP_DP_SECP384R1: + NIST_MODP( p384 ); + return( LOAD_GROUP( secp384r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + case POLARSSL_ECP_DP_SECP521R1: + NIST_MODP( p521 ); + return( LOAD_GROUP( secp521r1 ) ); +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + case POLARSSL_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return( LOAD_GROUP_A( secp192k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + case POLARSSL_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return( LOAD_GROUP_A( secp224k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + case POLARSSL_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return( LOAD_GROUP_A( secp256k1 ) ); +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + case POLARSSL_ECP_DP_BP256R1: + return( LOAD_GROUP_A( brainpoolP256r1 ) ); +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + case POLARSSL_ECP_DP_BP384R1: + return( LOAD_GROUP_A( brainpoolP384r1 ) ); +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + case POLARSSL_ECP_DP_BP512R1: + return( LOAD_GROUP_A( brainpoolP512r1 ) ); +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + case POLARSSL_ECP_DP_M255: + grp->modp = ecp_mod_p255; + return( ecp_use_curve25519( grp ) ); +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + + default: + ecp_group_free( grp ); + return( POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(POLARSSL_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic t_uint, we can + * use a t_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +SSL_ROM_TEXT_SECTION +static inline void add64( t_uint *dst, t_uint *src, t_uint *carry ) +{ + unsigned char i; + t_uint c = 0; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +SSL_ROM_TEXT_SECTION +static inline void carry64( t_uint *dst, t_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( t_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( t_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p192( mpi *N ) +{ + int ret; + t_uint c = 0; + t_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MPI_CHK( mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(POLARSSL_HAVE_INT8) /* 8 bit */ + +#define MAX32 N->n / 4 +#define A( j ) (uint32_t)( N->p[4*j+0] ) | \ + ( N->p[4*j+1] << 8 ) | \ + ( N->p[4*j+2] << 16 ) | \ + ( N->p[4*j+3] << 24 ) +#define STORE32 N->p[4*i+0] = (t_uint)( cur ); \ + N->p[4*i+1] = (t_uint)( cur >> 8 ); \ + N->p[4*i+2] = (t_uint)( cur >> 16 ); \ + N->p[4*i+3] = (t_uint)( cur >> 24 ); + +#elif defined(POLARSSL_HAVE_INT16) /* 16 bit */ + +#define MAX32 N->n / 2 +#define A( j ) (uint32_t)( N->p[2*j] ) | ( N->p[2*j+1] << 16 ) +#define STORE32 N->p[2*i+0] = (t_uint)( cur ); \ + N->p[2*i+1] = (t_uint)( cur >> 16 ); + +#elif defined(POLARSSL_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((t_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (t_uint) cur; \ + } + +#endif /* sizeof( t_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +SSL_ROM_TEXT_SECTION +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +SSL_ROM_TEXT_SECTION +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mpi C; \ + t_uint Cp[ b / 8 / sizeof( t_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( t_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( t_uint ) ); \ + \ + MPI_CHK( mpi_grow( N, b * 2 / 8 / sizeof( t_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +SSL_ROM_TEXT_SECTION +static inline int fix_negative( mpi *N, signed char c, mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(POLARSSL_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((t_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (t_uint) -c; + + /* N = - ( C - N ) */ + MPI_CHK( mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p224( mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p256( mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p384( mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED || + POLARSSL_ECP_DP_SECP256R1_ENABLED || + POLARSSL_ECP_DP_SECP384R1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of t_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( t_uint ) + 1 ) + +/* Bits to keep in the most significant t_uint */ +#if defined(POLARSSL_HAVE_INT8) +#define P521_MASK 0x01 +#else +#define P521_MASK 0x01FF +#endif + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p521( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when t_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 521 % ( 8 * sizeof( t_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ + +#endif /* POLARSSL_ECP_NIST_OPTIM */ + +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + +/* Size of p255 in terms of t_uint */ +#define P255_WIDTH ( 255 / 8 / sizeof( t_uint ) + 1 ) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^255 A1, return A0 + 19 * A1 + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p255( mpi *N ) +{ + int ret; + size_t i; + mpi M; + t_uint Mp[P255_WIDTH + 2]; + + if( N->n < P255_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P255_WIDTH - 1 ); + if( M.n > P255_WIDTH + 1 ) + M.n = P255_WIDTH + 1; + M.p = Mp; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( t_uint ) ); + MPI_CHK( mpi_shift_r( &M, 255 % ( 8 * sizeof( t_uint ) ) ) ); + M.n++; /* Make room for multiplication by 19 */ + + /* N = A0 */ + MPI_CHK( mpi_set_bit( N, 255, 0 ) ); + for( i = P255_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + 19 * A1 */ + MPI_CHK( mpi_mul_int( &M, &M, 19 ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) || \ + defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( t_uint ) ) // Max limbs in P +#define P_KOBLITZ_R ( 8 / sizeof( t_uint ) ) // Limbs in R +SSL_ROM_TEXT_SECTION +static inline int ecp_mod_koblitz( mpi *N, t_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, t_uint mask ) +{ + int ret; + size_t i; + mpi M, R; + t_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R]; + + if( N->n < p_limbs ) + return( 0 ); + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + + /* Second pass */ + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( t_uint ) ); + if( shift != 0 ) + MPI_CHK( mpi_shift_r( &M, shift ) ); + M.n += R.n - adjust; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MPI_CHK( mpi_mul_mpi( &M, &M, &R ) ); + MPI_CHK( mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED) || + POLARSSL_ECP_DP_SECP224K1_ENABLED) || + POLARSSL_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p192k1( mpi *N ) +{ + SSL_ROM_DATA_SECTION static const t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + + return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p224k1( mpi *N ) +{ + SSL_ROM_DATA_SECTION static const t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + +#if defined(POLARSSL_HAVE_INT64) + return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); +#else + return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +#endif +} + +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ + +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +SSL_ROM_TEXT_SECTION +static int ecp_mod_p256k1( mpi *N ) +{ + SSL_ROM_DATA_SECTION static const t_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( t_uint ), 0, 0, 0 ) ); +} +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ + +#endif /* POLARSSL_ECP_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/hmac_drbg.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/hmac_drbg.c new file mode 100644 index 0000000..5de7c25 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/hmac_drbg.c @@ -0,0 +1,515 @@ +/* + * HMAC_DRBG implementation (NIST SP 800-90) + * + * Copyright (C) 2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * The NIST SP 800-90A DRBGs are described in the following publication. + * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + * References below are based on rev. 1 (January 2012). + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_HMAC_DRBG_C) + +#include "polarssl/hmac_drbg.h" + +#if defined(POLARSSL_FS_IO) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * HMAC_DRBG update, using optional additional data (10.1.2.2) + */ +SSL_ROM_TEXT_SECTION +void hmac_drbg_update( hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + size_t md_len = ctx->md_ctx.md_info->size; + unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; + unsigned char sep[1]; + unsigned char K[POLARSSL_MD_MAX_SIZE]; + + for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) + { + /* Step 1 or 4 */ + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_update( &ctx->md_ctx, sep, 1 ); + if( rounds == 2 ) + md_hmac_update( &ctx->md_ctx, additional, add_len ); + md_hmac_finish( &ctx->md_ctx, K ); + + /* Step 2 or 5 */ + md_hmac_starts( &ctx->md_ctx, K, md_len ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + } +} + +/* + * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) + */ +SSL_ROM_TEXT_SECTION +int hmac_drbg_init_buf( hmac_drbg_context *ctx, + const md_info_t * md_info, + const unsigned char *data, size_t data_len ) +{ + int ret; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + hmac_drbg_update( ctx, data, data_len ); + + return( 0 ); +} + +/* + * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) + */ +SSL_ROM_TEXT_SECTION +int hmac_drbg_reseed( hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[POLARSSL_HMAC_DRBG_MAX_SEED_INPUT]; + size_t seedlen; + + /* III. Check input length */ + if( len > POLARSSL_HMAC_DRBG_MAX_INPUT || + ctx->entropy_len + len > POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ) + { + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + memset( seed, 0, POLARSSL_HMAC_DRBG_MAX_SEED_INPUT ); + + /* IV. Gather entropy_len bytes of entropy for the seed */ + if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 ) + return( POLARSSL_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + + seedlen = ctx->entropy_len; + + /* 1. Concatenate entropy and additional data if any */ + if( additional != NULL && len != 0 ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* 2. Update state */ + hmac_drbg_update( ctx, seed, seedlen ); + + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; + + /* 4. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG initialisation (10.1.2.3 + 9.1) + */ +SSL_ROM_TEXT_SECTION +int hmac_drbg_init( hmac_drbg_context *ctx, + const md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + int ret; + size_t entropy_len; + + memset( ctx, 0, sizeof( hmac_drbg_context ) ); + + md_init( &ctx->md_ctx ); + + if( ( ret = md_init_ctx( &ctx->md_ctx, md_info ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + md_hmac_starts( &ctx->md_ctx, ctx->V, md_info->size ); + memset( ctx->V, 0x01, md_info->size ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->reseed_interval = POLARSSL_HMAC_DRBG_RESEED_INTERVAL; + + /* + * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by + * each hash function, then according to SP800-90A rev1 10.1 table 2, + * min_entropy_len (in bits) is security_strength. + * + * (This also matches the sizes used in the NIST test vectors.) + */ + entropy_len = md_info->size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_info->size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ + + /* + * For initialisation, use more entropy to emulate a nonce + * (Again, matches test vectors.) + */ + ctx->entropy_len = entropy_len * 3 / 2; + + if( ( ret = hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + ctx->entropy_len = entropy_len; + + return( 0 ); +} + +/* + * Set prediction resistance + */ +SSL_ROM_TEXT_SECTION +void hmac_drbg_set_prediction_resistance( hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +/* + * Set entropy length grabbed for reseeds + */ +SSL_ROM_TEXT_SECTION +void hmac_drbg_set_entropy_len( hmac_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +/* + * Set reseed interval + */ +SSL_ROM_TEXT_SECTION +void hmac_drbg_set_reseed_interval( hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +/* + * HMAC_DRBG random function with optional additional data: + * 10.1.2.5 (arabic) + 9.3 (Roman) + */ +SSL_ROM_TEXT_SECTION +int hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t out_len, + const unsigned char *additional, size_t add_len ) +{ + int ret; + hmac_drbg_context *ctx = (hmac_drbg_context *) p_rng; + size_t md_len = md_get_size( ctx->md_ctx.md_info ); + size_t left = out_len; + unsigned char *out = output; + + /* II. Check request length */ + if( out_len > POLARSSL_HMAC_DRBG_MAX_REQUEST ) + return( POLARSSL_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); + + /* III. Check input length */ + if( add_len > POLARSSL_HMAC_DRBG_MAX_INPUT ) + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + + /* 1. (aka VII and IX) Check reseed counter and PR */ + if( ctx->f_entropy != NULL && /* For no-reseeding instances */ + ( ctx->prediction_resistance == POLARSSL_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) + { + if( ( ret = hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; /* VII.4 */ + } + + /* 2. Use additional data if any */ + if( additional != NULL && add_len != 0 ) + hmac_drbg_update( ctx, additional, add_len ); + + /* 3, 4, 5. Generate bytes */ + while( left != 0 ) + { + size_t use_len = left > md_len ? md_len : left; + + md_hmac_reset( &ctx->md_ctx ); + md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + md_hmac_finish( &ctx->md_ctx, ctx->V ); + + memcpy( out, ctx->V, use_len ); + out += use_len; + left -= use_len; + } + + /* 6. Update */ + hmac_drbg_update( ctx, additional, add_len ); + + /* 7. Update reseed counter */ + ctx->reseed_counter++; + + /* 8. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG random function + */ +SSL_ROM_TEXT_SECTION +int hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) +{ + return( hmac_drbg_random_with_add( p_rng, output, out_len, NULL, 0 ) ); +} + +/* + * Free an HMAC_DRBG context + */ +SSL_ROM_TEXT_SECTION +void hmac_drbg_free( hmac_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + + md_free_ctx( &ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( hmac_drbg_context ) ); +} + +#if defined(POLARSSL_FS_IO) +SSL_ROM_TEXT_SECTION +int hmac_drbg_write_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + int ret; + FILE *f; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + if( ( ret = hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) + { + ret = POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +SSL_ROM_TEXT_SECTION +int hmac_drbg_update_seed_file( hmac_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ POLARSSL_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > POLARSSL_HMAC_DRBG_MAX_INPUT ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( POLARSSL_ERR_HMAC_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + hmac_drbg_update( ctx, buf, n ); + + return( hmac_drbg_write_seed_file( ctx, path ) ); +} +#endif /* POLARSSL_FS_IO */ + + +#if defined(POLARSSL_SELF_TEST) + +#include + +#if !defined(POLARSSL_SHA1_C) +/* Dummy checkup routine */ +int hmac_drbg_self_test( int verbose ) +{ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int hmac_drbg_self_test( int verbose ) +{ + hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 ); + + /* + * PR = True + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_pr, + NULL, 0 ) ); + hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = False) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_nopr, + NULL, 0 ) ); + CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_HMAC_DRBG_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md.c new file mode 100644 index 0000000..d554e26 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md.c @@ -0,0 +1,361 @@ +/** + * \file md.c + * + * \brief Generic message digest wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD_C) + +#include "polarssl/md.h" +#include "polarssl/md_wrap.h" + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +SSL_ROM_DATA_SECTION +static const int supported_digests[] = { + +#if defined(POLARSSL_SHA512_C) + POLARSSL_MD_SHA384, + POLARSSL_MD_SHA512, +#endif + +#if defined(POLARSSL_SHA256_C) + POLARSSL_MD_SHA224, + POLARSSL_MD_SHA256, +#endif + +#if defined(POLARSSL_SHA1_C) + POLARSSL_MD_SHA1, +#endif + +#if defined(POLARSSL_RIPEMD160_C) + POLARSSL_MD_RIPEMD160, +#endif + +#if defined(POLARSSL_MD5_C) + POLARSSL_MD_MD5, +#endif + +#if defined(POLARSSL_MD4_C) + POLARSSL_MD_MD4, +#endif + +#if defined(POLARSSL_MD2_C) + POLARSSL_MD_MD2, +#endif + + POLARSSL_MD_NONE +}; + +SSL_ROM_TEXT_SECTION +const int *md_list( void ) +{ + return( supported_digests ); +} + +SSL_ROM_TEXT_SECTION +const md_info_t *md_info_from_string( const char *md_name ) +{ + if( NULL == md_name ) + return( NULL ); + + /* Get the appropriate digest information */ +#if defined(POLARSSL_MD2_C) + if( !strcasecmp( "MD2", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD2 ); +#endif +#if defined(POLARSSL_MD4_C) + if( !strcasecmp( "MD4", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD4 ); +#endif +#if defined(POLARSSL_MD5_C) + if( !strcasecmp( "MD5", md_name ) ) + return md_info_from_type( POLARSSL_MD_MD5 ); +#endif +#if defined(POLARSSL_RIPEMD160_C) + if( !strcasecmp( "RIPEMD160", md_name ) ) + return md_info_from_type( POLARSSL_MD_RIPEMD160 ); +#endif +#if defined(POLARSSL_SHA1_C) + if( !strcasecmp( "SHA1", md_name ) || !strcasecmp( "SHA", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA1 ); +#endif +#if defined(POLARSSL_SHA256_C) + if( !strcasecmp( "SHA224", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA224 ); + if( !strcasecmp( "SHA256", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA256 ); +#endif +#if defined(POLARSSL_SHA512_C) + if( !strcasecmp( "SHA384", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA384 ); + if( !strcasecmp( "SHA512", md_name ) ) + return md_info_from_type( POLARSSL_MD_SHA512 ); +#endif + return( NULL ); +} + +SSL_ROM_TEXT_SECTION +const md_info_t *md_info_from_type( md_type_t md_type ) +{ + switch( md_type ) + { +#if defined(POLARSSL_MD2_C) + case POLARSSL_MD_MD2: + return( &md2_info ); +#endif +#if defined(POLARSSL_MD4_C) + case POLARSSL_MD_MD4: + return( &md4_info ); +#endif +#if defined(POLARSSL_MD5_C) + case POLARSSL_MD_MD5: + return( &md5_info ); +#endif +#if defined(POLARSSL_RIPEMD160_C) + case POLARSSL_MD_RIPEMD160: + return( &ripemd160_info ); +#endif +#if defined(POLARSSL_SHA1_C) + case POLARSSL_MD_SHA1: + return( &sha1_info ); +#endif +#if defined(POLARSSL_SHA256_C) + case POLARSSL_MD_SHA224: + return( &sha224_info ); + case POLARSSL_MD_SHA256: + return( &sha256_info ); +#endif +#if defined(POLARSSL_SHA512_C) + case POLARSSL_MD_SHA384: + return( &sha384_info ); + case POLARSSL_MD_SHA512: + return( &sha512_info ); +#endif + default: + return( NULL ); + } +} + +SSL_ROM_TEXT_SECTION +void md_init( md_context_t *ctx ) +{ + memset( ctx, 0, sizeof( md_context_t ) ); +} + +SSL_ROM_TEXT_SECTION +void md_free( md_context_t *ctx ) +{ + if( ctx == NULL ) + return; + + if( ctx->md_ctx ) + ctx->md_info->ctx_free_func( ctx->md_ctx ); + + polarssl_zeroize( ctx, sizeof( md_context_t ) ); +} + +SSL_ROM_TEXT_SECTION +int md_init_ctx( md_context_t *ctx, const md_info_t *md_info ) +{ + if( md_info == NULL || ctx == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( md_context_t ) ); + + if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_MD_ALLOC_FAILED ); + + ctx->md_info = md_info; + + md_info->starts_func( ctx->md_ctx ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_free_ctx( md_context_t *ctx ) +{ + md_free( ctx ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_starts( md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->starts_func( ctx->md_ctx ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_finish( md_context_t *ctx, unsigned char *output ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md( const md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + md_info->digest_func( input, ilen, output ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_file( const md_info_t *md_info, const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + int ret; +#endif + + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + +#if defined(POLARSSL_FS_IO) + ret = md_info->file_func( path, output ); + if( ret != 0 ) + return( POLARSSL_ERR_MD_FILE_IO_ERROR + ret ); + + return( ret ); +#else + ((void) path); + ((void) output); + + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_FS_IO */ +} + +SSL_ROM_TEXT_SECTION +int md_hmac_starts( md_context_t *ctx, const unsigned char *key, size_t keylen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_starts_func( ctx->md_ctx, key, keylen ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_hmac_update( md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_hmac_finish( md_context_t *ctx, unsigned char *output ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_hmac_reset( md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->hmac_reset_func( ctx->md_ctx ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_hmac( const md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + if( md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + md_info->hmac_func( key, keylen, input, ilen, output ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int md_process( md_context_t *ctx, const unsigned char *data ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( POLARSSL_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->process_func( ctx->md_ctx, data ); + + return( 0 ); +} + +#endif /* POLARSSL_MD_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md5.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md5.c new file mode 100644 index 0000000..f14ef7a --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md5.c @@ -0,0 +1,630 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD5_C) + +#include "polarssl/md5.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_MD5_ALT) + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ +} +#endif + +SSL_ROM_TEXT_SECTION +void md5_init( md5_context *ctx ) +{ + memset( ctx, 0, sizeof( md5_context ) ); +} + +SSL_ROM_TEXT_SECTION +void md5_free( md5_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( md5_context ) ); +} + +/* + * MD5 context setup + */ +SSL_ROM_TEXT_SECTION +void md5_starts( md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +SSL_ROM_TEXT_SECTION +void md5_process( md5_context *ctx, const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} + +/* + * MD5 process buffer + */ +SSL_ROM_TEXT_SECTION +void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +SSL_ROM_DATA_SECTION +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +SSL_ROM_TEXT_SECTION +void md5_finish( md5_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + md5_update( ctx, md5_padding, padn ); + md5_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); +} + +#endif /* !POLARSSL_MD5_ALT */ + +/* + * output = MD5( input buffer ) + */ +SSL_ROM_TEXT_SECTION +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + md5_context ctx; + + md5_init( &ctx ); + md5_starts( &ctx ); + md5_update( &ctx, input, ilen ); + md5_finish( &ctx, output ); + md5_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = MD5( file contents ) + */ +SSL_ROM_TEXT_SECTION +int md5_file( const char *path, unsigned char output[16] ) +{ + FILE *f; + size_t n; + md5_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); + + md5_init( &ctx ); + md5_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md5_update( &ctx, buf, n ); + + md5_finish( &ctx, output ); + md5_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_MD5_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * MD5 HMAC context setup + */ +SSL_ROM_TEXT_SECTION +void md5_hmac_starts( md5_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[16]; + + if( keylen > 64 ) + { + md5( key, keylen, sum ); + keylen = 16; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * MD5 HMAC process buffer + */ +SSL_ROM_TEXT_SECTION +void md5_hmac_update( md5_context *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_update( ctx, input, ilen ); +} + +/* + * MD5 HMAC final digest + */ +SSL_ROM_TEXT_SECTION +void md5_hmac_finish( md5_context *ctx, unsigned char output[16] ) +{ + unsigned char tmpbuf[16]; + + md5_finish( ctx, tmpbuf ); + md5_starts( ctx ); + md5_update( ctx, ctx->opad, 64 ); + md5_update( ctx, tmpbuf, 16 ); + md5_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * MD5 HMAC context reset + */ +SSL_ROM_TEXT_SECTION +void md5_hmac_reset( md5_context *ctx ) +{ + md5_starts( ctx ); + md5_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-MD5( hmac key, input buffer ) + */ +SSL_ROM_TEXT_SECTION +void md5_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[16] ) +{ + md5_context ctx; + + md5_init( &ctx ); + md5_hmac_starts( &ctx, key, keylen ); + md5_hmac_update( &ctx, input, ilen ); + md5_hmac_finish( &ctx, output ); + md5_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * RFC 1321 test vectors + */ +static unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char md5_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int md5_hmac_test_keylen[7] = +{ + 16, 4, 16, 25, 16, 80, 80 +}; + +static unsigned char md5_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int md5_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char md5_hmac_test_sum[7][16] = +{ + { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, + 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, + { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, + 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, + { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, + 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, + { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, + 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, + { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, + 0xF9, 0xBA, 0xB9, 0x95 }, + { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, + 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, + { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, + 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } +}; + +/* + * Checkup routine + */ +int md5_self_test( int verbose ) +{ + int i, buflen; + unsigned char buf[1024]; + unsigned char md5sum[16]; + md5_context ctx; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " MD5 test #%d: ", i + 1 ); + + md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + md5_hmac_starts( &ctx, buf, buflen ); + } + else + md5_hmac_starts( &ctx, md5_hmac_test_key[i], + md5_hmac_test_keylen[i] ); + + md5_hmac_update( &ctx, md5_hmac_test_buf[i], + md5_hmac_test_buflen[i] ); + + md5_hmac_finish( &ctx, md5sum ); + + buflen = ( i == 4 ) ? 12 : 16; + + if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_MD5_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md_wrap.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md_wrap.c new file mode 100644 index 0000000..c30a023 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/md_wrap.c @@ -0,0 +1,1072 @@ +/** + * \file md_wrap.c + + * \brief Generic message digest wrapper for PolarSSL + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_MD_C) + +#include "polarssl/md_wrap.h" + +#if defined(POLARSSL_MD2_C) +#include "polarssl/md2.h" +#endif + +#if defined(POLARSSL_MD4_C) +#include "polarssl/md4.h" +#endif + +#if defined(POLARSSL_MD5_C) +#include "polarssl/md5.h" +#endif + +#if defined(POLARSSL_RIPEMD160_C) +#include "polarssl/ripemd160.h" +#endif + +#if defined(POLARSSL_SHA1_C) +#include "polarssl/sha1.h" +#endif + +#if defined(POLARSSL_SHA256_C) +#include "polarssl/sha256.h" +#endif + +#if defined(POLARSSL_SHA512_C) +#include "polarssl/sha512.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_MD2_C) + +SSL_ROM_TEXT_SECTION +static void md2_starts_wrap( void *ctx ) +{ + md2_starts( (md2_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md2_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md2_update( (md2_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md2_finish_wrap( void *ctx, unsigned char *output ) +{ + md2_finish( (md2_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static int md2_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md2_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void md2_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md2_hmac_starts( (md2_context *) ctx, key, keylen ); +} + +SSL_ROM_TEXT_SECTION +static void md2_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md2_hmac_update( (md2_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md2_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md2_hmac_finish( (md2_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void md2_hmac_reset_wrap( void *ctx ) +{ + md2_hmac_reset( (md2_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void * md2_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md2_context ) ); +} + +SSL_ROM_TEXT_SECTION +static void md2_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md2_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md2_process_wrap( void *ctx, const unsigned char *data ) +{ + ((void) data); + + md2_process( (md2_context *) ctx ); +} + +SSL_ROM_DATA_SECTION +const md_info_t md2_info = { + POLARSSL_MD_MD2, + "MD2", + 16, + md2_starts_wrap, + md2_update_wrap, + md2_finish_wrap, + md2, + md2_file_wrap, + md2_hmac_starts_wrap, + md2_hmac_update_wrap, + md2_hmac_finish_wrap, + md2_hmac_reset_wrap, + md2_hmac, + md2_ctx_alloc, + md2_ctx_free, + md2_process_wrap, +}; + +#endif /* POLARSSL_MD2_C */ + +#if defined(POLARSSL_MD4_C) + +SSL_ROM_TEXT_SECTION +static void md4_starts_wrap( void *ctx ) +{ + md4_starts( (md4_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md4_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md4_update( (md4_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md4_finish_wrap( void *ctx, unsigned char *output ) +{ + md4_finish( (md4_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static int md4_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md4_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void md4_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md4_hmac_starts( (md4_context *) ctx, key, keylen ); +} + +SSL_ROM_TEXT_SECTION +static void md4_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md4_hmac_update( (md4_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md4_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md4_hmac_finish( (md4_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void md4_hmac_reset_wrap( void *ctx ) +{ + md4_hmac_reset( (md4_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void *md4_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md4_context ) ); +} + +SSL_ROM_TEXT_SECTION +static void md4_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md4_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md4_process_wrap( void *ctx, const unsigned char *data ) +{ + md4_process( (md4_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t md4_info = { + POLARSSL_MD_MD4, + "MD4", + 16, + md4_starts_wrap, + md4_update_wrap, + md4_finish_wrap, + md4, + md4_file_wrap, + md4_hmac_starts_wrap, + md4_hmac_update_wrap, + md4_hmac_finish_wrap, + md4_hmac_reset_wrap, + md4_hmac, + md4_ctx_alloc, + md4_ctx_free, + md4_process_wrap, +}; + +#endif /* POLARSSL_MD4_C */ + +#if defined(POLARSSL_MD5_C) + +SSL_ROM_TEXT_SECTION +static void md5_starts_wrap( void *ctx ) +{ + md5_starts( (md5_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md5_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_update( (md5_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md5_finish_wrap( void *ctx, unsigned char *output ) +{ + md5_finish( (md5_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static int md5_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return md5_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void md5_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + md5_hmac_starts( (md5_context *) ctx, key, keylen ); +} + +SSL_ROM_TEXT_SECTION +static void md5_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + md5_hmac_update( (md5_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void md5_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + md5_hmac_finish( (md5_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void md5_hmac_reset_wrap( void *ctx ) +{ + md5_hmac_reset( (md5_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void * md5_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( md5_context ) ); +} + +SSL_ROM_TEXT_SECTION +static void md5_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( md5_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void md5_process_wrap( void *ctx, const unsigned char *data ) +{ + md5_process( (md5_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t md5_info = { + POLARSSL_MD_MD5, + "MD5", + 16, + md5_starts_wrap, + md5_update_wrap, + md5_finish_wrap, + md5, + md5_file_wrap, + md5_hmac_starts_wrap, + md5_hmac_update_wrap, + md5_hmac_finish_wrap, + md5_hmac_reset_wrap, + md5_hmac, + md5_ctx_alloc, + md5_ctx_free, + md5_process_wrap, +}; + +#endif /* POLARSSL_MD5_C */ + +#if defined(POLARSSL_RIPEMD160_C) + +SSL_ROM_TEXT_SECTION +static void ripemd160_starts_wrap( void *ctx ) +{ + ripemd160_starts( (ripemd160_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_update( (ripemd160_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_finish( (ripemd160_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static int ripemd160_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return ripemd160_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + ripemd160_hmac_starts( (ripemd160_context *) ctx, key, keylen ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + ripemd160_hmac_update( (ripemd160_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + ripemd160_hmac_finish( (ripemd160_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_hmac_reset_wrap( void *ctx ) +{ + ripemd160_hmac_reset( (ripemd160_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void * ripemd160_ctx_alloc( void ) +{ + ripemd160_context *ctx; + ctx = (ripemd160_context *) polarssl_malloc( sizeof( ripemd160_context ) ); + + if( ctx == NULL ) + return( NULL ); + + ripemd160_init( ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_ctx_free( void *ctx ) +{ + ripemd160_free( (ripemd160_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void ripemd160_process_wrap( void *ctx, const unsigned char *data ) +{ + ripemd160_process( (ripemd160_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t ripemd160_info = { + POLARSSL_MD_RIPEMD160, + "RIPEMD160", + 20, + ripemd160_starts_wrap, + ripemd160_update_wrap, + ripemd160_finish_wrap, + ripemd160, + ripemd160_file_wrap, + ripemd160_hmac_starts_wrap, + ripemd160_hmac_update_wrap, + ripemd160_hmac_finish_wrap, + ripemd160_hmac_reset_wrap, + ripemd160_hmac, + ripemd160_ctx_alloc, + ripemd160_ctx_free, + ripemd160_process_wrap, +}; + +#endif /* POLARSSL_RIPEMD160_C */ + +#if defined(POLARSSL_SHA1_C) + +SSL_ROM_TEXT_SECTION +static void sha1_starts_wrap( void *ctx ) +{ + sha1_starts( (sha1_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_update( (sha1_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_finish_wrap( void *ctx, unsigned char *output ) +{ + sha1_finish( (sha1_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static int sha1_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha1_file( path, output ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void sha1_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha1_hmac_starts( (sha1_context *) ctx, key, keylen ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_hmac_update( (sha1_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha1_hmac_finish( (sha1_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_hmac_reset_wrap( void *ctx ) +{ + sha1_hmac_reset( (sha1_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void * sha1_ctx_alloc( void ) +{ + sha1_context *ctx; + ctx = (sha1_context *) polarssl_malloc( sizeof( sha1_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha1_init( ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_ctx_free( void *ctx ) +{ + sha1_free( (sha1_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha1_process_wrap( void *ctx, const unsigned char *data ) +{ + sha1_process( (sha1_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t sha1_info = { + POLARSSL_MD_SHA1, + "SHA1", + 20, + sha1_starts_wrap, + sha1_update_wrap, + sha1_finish_wrap, + sha1, + sha1_file_wrap, + sha1_hmac_starts_wrap, + sha1_hmac_update_wrap, + sha1_hmac_finish_wrap, + sha1_hmac_reset_wrap, + sha1_hmac, + sha1_ctx_alloc, + sha1_ctx_free, + sha1_process_wrap, +}; + +#endif /* POLARSSL_SHA1_C */ + +/* + * Wrappers for generic message digests + */ +#if defined(POLARSSL_SHA256_C) + +SSL_ROM_TEXT_SECTION +static void sha224_starts_wrap( void *ctx ) +{ + sha256_starts( (sha256_context *) ctx, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( (sha256_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_finish( (sha256_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256( input, ilen, output, 1 ); +} + +SSL_ROM_TEXT_SECTION +static int sha224_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha256_file( path, output, 1 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void sha224_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_hmac_update( (sha256_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_hmac_finish( (sha256_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_hmac_reset_wrap( void *ctx ) +{ + sha256_hmac_reset( (sha256_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256_hmac( key, keylen, input, ilen, output, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void * sha224_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( sha256_context ) ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( sha256_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha224_process_wrap( void *ctx, const unsigned char *data ) +{ + sha256_process( (sha256_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t sha224_info = { + POLARSSL_MD_SHA224, + "SHA224", + 28, + sha224_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha224_wrap, + sha224_file_wrap, + sha224_hmac_starts_wrap, + sha224_hmac_update_wrap, + sha224_hmac_finish_wrap, + sha224_hmac_reset_wrap, + sha224_hmac_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_process_wrap, +}; + +SSL_ROM_TEXT_SECTION +static void sha256_starts_wrap( void *ctx ) +{ + sha256_starts( (sha256_context *) ctx, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( (sha256_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_finish( (sha256_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256( input, ilen, output, 0 ); +} + +SSL_ROM_TEXT_SECTION +static int sha256_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha256_file( path, output, 0 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void sha256_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha256_hmac_starts( (sha256_context *) ctx, key, keylen, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_hmac_update( (sha256_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha256_hmac_finish( (sha256_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_hmac_reset_wrap( void *ctx ) +{ + sha256_hmac_reset( (sha256_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha256_hmac( key, keylen, input, ilen, output, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void * sha256_ctx_alloc( void ) +{ + sha256_context *ctx; + ctx = (sha256_context *) polarssl_malloc( sizeof( sha256_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha256_init( ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_ctx_free( void *ctx ) +{ + sha256_free( (sha256_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha256_process_wrap( void *ctx, const unsigned char *data ) +{ + sha256_process( (sha256_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t sha256_info = { + POLARSSL_MD_SHA256, + "SHA256", + 32, + sha256_starts_wrap, + sha256_update_wrap, + sha256_finish_wrap, + sha256_wrap, + sha256_file_wrap, + sha256_hmac_starts_wrap, + sha256_hmac_update_wrap, + sha256_hmac_finish_wrap, + sha256_hmac_reset_wrap, + sha256_hmac_wrap, + sha256_ctx_alloc, + sha256_ctx_free, + sha256_process_wrap, +}; + +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + +SSL_ROM_TEXT_SECTION +static void sha384_starts_wrap( void *ctx ) +{ + sha512_starts( (sha512_context *) ctx, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_update( (sha512_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_finish( (sha512_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512( input, ilen, output, 1 ); +} + +SSL_ROM_TEXT_SECTION +static int sha384_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha512_file( path, output, 1 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void sha384_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_hmac_update( (sha512_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_hmac_finish( (sha512_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_hmac_reset_wrap( void *ctx ) +{ + sha512_hmac_reset( (sha512_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512_hmac( key, keylen, input, ilen, output, 1 ); +} + +SSL_ROM_TEXT_SECTION +static void * sha384_ctx_alloc( void ) +{ + return polarssl_malloc( sizeof( sha512_context ) ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_ctx_free( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( sha512_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha384_process_wrap( void *ctx, const unsigned char *data ) +{ + sha512_process( (sha512_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t sha384_info = { + POLARSSL_MD_SHA384, + "SHA384", + 48, + sha384_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha384_wrap, + sha384_file_wrap, + sha384_hmac_starts_wrap, + sha384_hmac_update_wrap, + sha384_hmac_finish_wrap, + sha384_hmac_reset_wrap, + sha384_hmac_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_process_wrap, +}; + +SSL_ROM_TEXT_SECTION +static void sha512_starts_wrap( void *ctx ) +{ + sha512_starts( (sha512_context *) ctx, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_update( (sha512_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_finish( (sha512_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512( input, ilen, output, 0 ); +} + +SSL_ROM_TEXT_SECTION +static int sha512_file_wrap( const char *path, unsigned char *output ) +{ +#if defined(POLARSSL_FS_IO) + return sha512_file( path, output, 0 ); +#else + ((void) path); + ((void) output); + return( POLARSSL_ERR_MD_FEATURE_UNAVAILABLE ); +#endif +} + +SSL_ROM_TEXT_SECTION +static void sha512_hmac_starts_wrap( void *ctx, const unsigned char *key, + size_t keylen ) +{ + sha512_hmac_starts( (sha512_context *) ctx, key, keylen, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_hmac_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + sha512_hmac_update( (sha512_context *) ctx, input, ilen ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_hmac_finish_wrap( void *ctx, unsigned char *output ) +{ + sha512_hmac_finish( (sha512_context *) ctx, output ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_hmac_reset_wrap( void *ctx ) +{ + sha512_hmac_reset( (sha512_context *) ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_hmac_wrap( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + sha512_hmac( key, keylen, input, ilen, output, 0 ); +} + +SSL_ROM_TEXT_SECTION +static void * sha512_ctx_alloc( void ) +{ + sha512_context *ctx; + ctx = (sha512_context *) polarssl_malloc( sizeof( sha512_context ) ); + + if( ctx == NULL ) + return( NULL ); + + sha512_init( ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_ctx_free( void *ctx ) +{ + sha512_free( (sha512_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void sha512_process_wrap( void *ctx, const unsigned char *data ) +{ + sha512_process( (sha512_context *) ctx, data ); +} + +SSL_ROM_DATA_SECTION +const md_info_t sha512_info = { + POLARSSL_MD_SHA512, + "SHA512", + 64, + sha512_starts_wrap, + sha512_update_wrap, + sha512_finish_wrap, + sha512_wrap, + sha512_file_wrap, + sha512_hmac_starts_wrap, + sha512_hmac_update_wrap, + sha512_hmac_finish_wrap, + sha512_hmac_reset_wrap, + sha512_hmac_wrap, + sha512_ctx_alloc, + sha512_ctx_free, + sha512_process_wrap, +}; + +#endif /* POLARSSL_SHA512_C */ + +#endif /* POLARSSL_MD_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/oid.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/oid.c new file mode 100644 index 0000000..55e93c2 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/oid.c @@ -0,0 +1,695 @@ +/** + * \file oid.c + * + * \brief Object Identifier (OID) database + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_OID_C) + +#include "polarssl/oid.h" +#include "polarssl/rsa.h" + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +#include "polarssl/x509.h" +#endif + +#include + +/* + * Macro to automatically add the size of #define'd OIDs + */ +#define ADD_LEN(s) s, OID_SIZE(s) + +/* + * Macro to generate an internal function for oid_XXX_from_asn1() (used by + * the other functions) + */ +#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ +SSL_ROM_TEXT_SECTION static const TYPE_T * oid_ ## NAME ## _from_asn1( const asn1_buf *oid ) \ +{ \ + const TYPE_T *p = LIST; \ + const oid_descriptor_t *cur = (const oid_descriptor_t *) p; \ + if( p == NULL || oid == NULL ) return( NULL ); \ + while( cur->asn1 != NULL ) { \ + if( cur->asn1_len == oid->len && \ + memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ + return( p ); \ + } \ + p++; \ + cur = (const oid_descriptor_t *) p; \ + } \ + return( NULL ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from the + * descriptor of an oid_descriptor_t wrapper. + */ +#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +SSL_ROM_TEXT_SECTION int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->descriptor.ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from an + * oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +SSL_ROM_TEXT_SECTION int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving two attributes from an + * oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +SSL_ROM_TEXT_SECTION int FN_NAME( const asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( POLARSSL_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + *ATTR2 = data->ATTR2; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on a single + * attribute from a oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ +SSL_ROM_TEXT_SECTION int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( POLARSSL_ERR_OID_NOT_FOUND ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on two + * attributes from a oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +SSL_ROM_TEXT_SECTION int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ + size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( POLARSSL_ERR_OID_NOT_FOUND ); \ +} + +/* + * For X520 attribute types + */ +typedef struct { + oid_descriptor_t descriptor; + const char *short_name; +} oid_x520_attr_t; + +SSL_ROM_DATA_SECTION +static const oid_x520_attr_t oid_x520_attr_type[] = +{ + { + { ADD_LEN( OID_AT_CN ), "id-at-commonName", "Common Name" }, + "CN", + }, + { + { ADD_LEN( OID_AT_COUNTRY ), "id-at-countryName", "Country" }, + "C", + }, + { + { ADD_LEN( OID_AT_LOCALITY ), "id-at-locality", "Locality" }, + "L", + }, + { + { ADD_LEN( OID_AT_STATE ), "id-at-state", "State" }, + "ST", + }, + { + { ADD_LEN( OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, + "O", + }, + { + { ADD_LEN( OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, + "OU", + }, + { + { ADD_LEN( OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, + "emailAddress", + }, + { + { ADD_LEN( OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, + "serialNumber", + }, + { + { ADD_LEN( OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, + "postalAddress", + }, + { + { ADD_LEN( OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, + "postalCode", + }, + { + { ADD_LEN( OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, + "SN", + }, + { + { ADD_LEN( OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, + "GN", + }, + { + { ADD_LEN( OID_AT_INITIALS ), "id-at-initials", "Initials" }, + "initials", + }, + { + { ADD_LEN( OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, + "generationQualifier", + }, + { + { ADD_LEN( OID_AT_TITLE ), "id-at-title", "Title" }, + "title", + }, + { + { ADD_LEN( OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, + "dnQualifier", + }, + { + { ADD_LEN( OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, + "pseudonym", + }, + { + { ADD_LEN( OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, + "DC", + }, + { + { NULL, 0, NULL, NULL }, + NULL, + } +}; + +FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type); +FN_OID_GET_ATTR1(oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name); + +#if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) +/* + * For X509 extensions + */ +typedef struct { + oid_descriptor_t descriptor; + int ext_type; +} oid_x509_ext_t; + +SSL_ROM_DATA_SECTION +static const oid_x509_ext_t oid_x509_ext[] = +{ + { + { ADD_LEN( OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, + EXT_BASIC_CONSTRAINTS, + }, + { + { ADD_LEN( OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, + EXT_KEY_USAGE, + }, + { + { ADD_LEN( OID_EXTENDED_KEY_USAGE ), "id-ce-keyUsage", "Extended Key Usage" }, + EXT_EXTENDED_KEY_USAGE, + }, + { + { ADD_LEN( OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, + EXT_SUBJECT_ALT_NAME, + }, + { + { ADD_LEN( OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, + EXT_NS_CERT_TYPE, + }, + { + { NULL, 0, NULL, NULL }, + 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext); +FN_OID_GET_ATTR1(oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type); + +SSL_ROM_DATA_SECTION +static const oid_descriptor_t oid_ext_key_usage[] = +{ + { ADD_LEN( OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, + { ADD_LEN( OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, + { ADD_LEN( OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, + { ADD_LEN( OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, + { ADD_LEN( OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, + { ADD_LEN( OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, + { NULL, 0, NULL, NULL }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_descriptor_t, ext_key_usage, oid_ext_key_usage); +FN_OID_GET_ATTR1(oid_get_extended_key_usage, oid_descriptor_t, ext_key_usage, const char *, description); +#endif /* POLARSSL_X509_USE_C || POLARSSL_X509_CREATE_C */ + +#if defined(POLARSSL_MD_C) +/* + * For SignatureAlgorithmIdentifier + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; + pk_type_t pk_alg; +} oid_sig_alg_t; + +SSL_ROM_DATA_SECTION +static const oid_sig_alg_t oid_sig_alg[] = +{ + { + { ADD_LEN( OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, + POLARSSL_MD_MD2, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, + POLARSSL_MD_MD4, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, + POLARSSL_MD_MD5, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, + POLARSSL_MD_SHA224, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, + POLARSSL_MD_SHA256, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, + POLARSSL_MD_SHA384, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, + POLARSSL_MD_SHA512, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, + POLARSSL_MD_SHA1, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, + POLARSSL_MD_SHA224, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, + POLARSSL_MD_SHA256, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, + POLARSSL_MD_SHA384, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, + POLARSSL_MD_SHA512, POLARSSL_PK_ECDSA, + }, + { + { ADD_LEN( OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, + POLARSSL_MD_NONE, POLARSSL_PK_RSASSA_PSS, + }, + { + { NULL, 0, NULL, NULL }, + (md_type_t)0, (pk_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg); +FN_OID_GET_DESCRIPTOR_ATTR1(oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description); +FN_OID_GET_ATTR2(oid_get_sig_alg, oid_sig_alg_t, sig_alg, md_type_t, md_alg, pk_type_t, pk_alg); +FN_OID_GET_OID_BY_ATTR2(oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, pk_type_t, pk_alg, md_type_t, md_alg); +#endif /* POLARSSL_MD_C */ + +/* + * For PublicKeyInfo (PKCS1, RFC 5480) + */ +typedef struct { + oid_descriptor_t descriptor; + pk_type_t pk_alg; +} oid_pk_alg_t; + +SSL_ROM_DATA_SECTION +static const oid_pk_alg_t oid_pk_alg[] = +{ + { + { ADD_LEN( OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, + POLARSSL_PK_RSA, + }, + { + { ADD_LEN( OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, + POLARSSL_PK_ECKEY, + }, + { + { ADD_LEN( OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, + POLARSSL_PK_ECKEY_DH, + }, + { + { NULL, 0, NULL, NULL }, + (pk_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg); +FN_OID_GET_ATTR1(oid_get_pk_alg, oid_pk_alg_t, pk_alg, pk_type_t, pk_alg); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, pk_type_t, pk_alg); + +#if defined(POLARSSL_ECP_C) +/* + * For namedCurve (RFC 5480) + */ +typedef struct { + oid_descriptor_t descriptor; + ecp_group_id grp_id; +} oid_ecp_grp_t; + +SSL_ROM_DATA_SECTION +static const oid_ecp_grp_t oid_ecp_grp[] = +{ + { + { ADD_LEN( OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, + POLARSSL_ECP_DP_SECP192R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, + POLARSSL_ECP_DP_SECP224R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, + POLARSSL_ECP_DP_SECP256R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, + POLARSSL_ECP_DP_SECP384R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, + POLARSSL_ECP_DP_SECP521R1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, + POLARSSL_ECP_DP_SECP192K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, + POLARSSL_ECP_DP_SECP224K1, + }, + { + { ADD_LEN( OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, + POLARSSL_ECP_DP_SECP256K1, + }, + { + { ADD_LEN( OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, + POLARSSL_ECP_DP_BP256R1, + }, + { + { ADD_LEN( OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, + POLARSSL_ECP_DP_BP384R1, + }, + { + { ADD_LEN( OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, + POLARSSL_ECP_DP_BP512R1, + }, + { + { NULL, 0, NULL, NULL }, + 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp); +FN_OID_GET_ATTR1(oid_get_ec_grp, oid_ecp_grp_t, grp_id, ecp_group_id, grp_id); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, ecp_group_id, grp_id); +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_CIPHER_C) +/* + * For PKCS#5 PBES2 encryption algorithm + */ +typedef struct { + oid_descriptor_t descriptor; + cipher_type_t cipher_alg; +} oid_cipher_alg_t; + +SSL_ROM_DATA_SECTION +static const oid_cipher_alg_t oid_cipher_alg[] = +{ + { + { ADD_LEN( OID_DES_CBC ), "desCBC", "DES-CBC" }, + POLARSSL_CIPHER_DES_CBC, + }, + { + { ADD_LEN( OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, + POLARSSL_CIPHER_DES_EDE3_CBC, + }, + { + { NULL, 0, NULL, NULL }, + (cipher_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg); +FN_OID_GET_ATTR1(oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, cipher_type_t, cipher_alg); +#endif /* POLARSSL_CIPHER_C */ + +#if defined(POLARSSL_MD_C) +/* + * For digestAlgorithm + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; +} oid_md_alg_t; + +SSL_ROM_DATA_SECTION +static const oid_md_alg_t oid_md_alg[] = +{ + { + { ADD_LEN( OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, + POLARSSL_MD_MD2, + }, + { + { ADD_LEN( OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, + POLARSSL_MD_MD4, + }, + { + { ADD_LEN( OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, + POLARSSL_MD_MD5, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, + POLARSSL_MD_SHA1, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, + POLARSSL_MD_SHA224, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, + POLARSSL_MD_SHA256, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, + POLARSSL_MD_SHA384, + }, + { + { ADD_LEN( OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, + POLARSSL_MD_SHA512, + }, + { + { NULL, 0, NULL, NULL }, + (md_type_t)0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg); +FN_OID_GET_ATTR1(oid_get_md_alg, oid_md_alg_t, md_alg, md_type_t, md_alg); +FN_OID_GET_OID_BY_ATTR1(oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, md_type_t, md_alg); +#endif /* POLARSSL_MD_C */ + +#if defined(POLARSSL_PKCS12_C) +/* + * For PKCS#12 PBEs + */ +typedef struct { + oid_descriptor_t descriptor; + md_type_t md_alg; + cipher_type_t cipher_alg; +} oid_pkcs12_pbe_alg_t; + +SSL_ROM_DATA_SECTION +static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = +{ + { + { ADD_LEN( OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, + POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE3_CBC, + }, + { + { ADD_LEN( OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, + POLARSSL_MD_SHA1, POLARSSL_CIPHER_DES_EDE_CBC, + }, + { + { NULL, 0, NULL, NULL }, + 0, 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg); +FN_OID_GET_ATTR2(oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, md_type_t, md_alg, cipher_type_t, cipher_alg); +#endif /* POLARSSL_PKCS12_C */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +SSL_ROM_TEXT_SECTION +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + \ + if( (unsigned int) ret >= n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +/* Return the x.y.z.... style numeric string for the given OID */ +SSL_ROM_TEXT_SECTION +int oid_get_numeric_string( char *buf, size_t size, + const asn1_buf *oid ) +{ + int ret; + size_t i, n; + unsigned int value; + char *p; + + p = buf; + n = size; + + /* First byte contains first two dots */ + if( oid->len > 0 ) + { + ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); + SAFE_SNPRINTF(); + } + + value = 0; + for( i = 1; i < oid->len; i++ ) + { + /* Prevent overflow in value. */ + if( ( ( value << 7 ) >> 7 ) != value ) + return( POLARSSL_ERR_OID_BUF_TOO_SMALL ); + + value <<= 7; + value += oid->p[i] & 0x7F; + + if( !( oid->p[i] & 0x80 ) ) + { + /* Last byte */ + ret = snprintf( p, n, ".%d", value ); + SAFE_SNPRINTF(); + value = 0; + } + } + + return( (int) ( size - n ) ); +} + +#endif /* POLARSSL_OID_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pem.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pem.c new file mode 100644 index 0000000..3affaaa --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pem.c @@ -0,0 +1,455 @@ +/* + * Privacy Enhanced Mail (PEM) decoding + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#include "polarssl/base64.h" +#include "polarssl/des.h" +#include "polarssl/aes.h" +#include "polarssl/md5.h" +#include "polarssl/cipher.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_PEM_PARSE_C) +SSL_ROM_TEXT_SECTION +void pem_init( pem_context *ctx ) +{ + memset( ctx, 0, sizeof( pem_context ) ); +} + +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) +/* + * Read a 16-byte hex string and convert it to binary + */ +SSL_ROM_TEXT_SECTION +static int pem_get_iv( const unsigned char *s, unsigned char *iv, + size_t iv_len ) +{ + size_t i, j, k; + + memset( iv, 0, iv_len ); + + for( i = 0; i < iv_len * 2; i++, s++ ) + { + if( *s >= '0' && *s <= '9' ) j = *s - '0'; else + if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else + if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + k = ( ( i & 1 ) != 0 ) ? j : j << 4; + + iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); + } + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static void pem_pbkdf1( unsigned char *key, size_t keylen, + unsigned char *iv, + const unsigned char *pwd, size_t pwdlen ) +{ + md5_context md5_ctx; + unsigned char md5sum[16]; + size_t use_len; + + md5_init( &md5_ctx ); + + /* + * key[ 0..15] = MD5(pwd || IV) + */ + md5_starts( &md5_ctx ); + md5_update( &md5_ctx, pwd, pwdlen ); + md5_update( &md5_ctx, iv, 8 ); + md5_finish( &md5_ctx, md5sum ); + + if( keylen <= 16 ) + { + memcpy( key, md5sum, keylen ); + + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); + return; + } + + memcpy( key, md5sum, 16 ); + + /* + * key[16..23] = MD5(key[ 0..15] || pwd || IV]) + */ + md5_starts( &md5_ctx ); + md5_update( &md5_ctx, md5sum, 16 ); + md5_update( &md5_ctx, pwd, pwdlen ); + md5_update( &md5_ctx, iv, 8 ); + md5_finish( &md5_ctx, md5sum ); + + use_len = 16; + if( keylen < 32 ) + use_len = keylen - 16; + + memcpy( key + 16, md5sum, use_len ); + + md5_free( &md5_ctx ); + polarssl_zeroize( md5sum, 16 ); +} + +#if defined(POLARSSL_DES_C) +/* + * Decrypt with DES-CBC, using PBKDF1 for key derivation + */ +SSL_ROM_TEXT_SECTION +static void pem_des_decrypt( unsigned char des_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + des_context des_ctx; + unsigned char des_key[8]; + + des_init( &des_ctx ); + + pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ); + + des_setkey_dec( &des_ctx, des_key ); + des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen, + des_iv, buf, buf ); + + des_free( &des_ctx ); + polarssl_zeroize( des_key, 8 ); +} + +/* + * Decrypt with 3DES-CBC, using PBKDF1 for key derivation + */ +SSL_ROM_TEXT_SECTION +static void pem_des3_decrypt( unsigned char des3_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + des3_context des3_ctx; + unsigned char des3_key[24]; + + des3_init( &des3_ctx ); + + pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ); + + des3_set3key_dec( &des3_ctx, des3_key ); + des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen, + des3_iv, buf, buf ); + + des3_free( &des3_ctx ); + polarssl_zeroize( des3_key, 24 ); +} +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) +/* + * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation + */ +SSL_ROM_TEXT_SECTION +static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + aes_context aes_ctx; + unsigned char aes_key[32]; + + aes_init( &aes_ctx ); + + pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); + + aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ); + aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen, + aes_iv, buf, buf ); + + aes_free( &aes_ctx ); + polarssl_zeroize( aes_key, keylen ); +} +#endif /* POLARSSL_AES_C */ + +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + +SSL_ROM_TEXT_SECTION +int pem_read_buffer( pem_context *ctx, const char *header, const char *footer, + const unsigned char *data, const unsigned char *pwd, + size_t pwdlen, size_t *use_len ) +{ + int ret, enc; + size_t len; + unsigned char *buf; + const unsigned char *s1, *s2, *end; +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + unsigned char pem_iv[16]; + cipher_type_t enc_alg = POLARSSL_CIPHER_NONE; +#else + ((void) pwd); + ((void) pwdlen); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + + if( ctx == NULL ) + return( POLARSSL_ERR_PEM_BAD_INPUT_DATA ); + + s1 = (unsigned char *) strstr( (const char *) data, header ); + + if( s1 == NULL ) + return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s2 = (unsigned char *) strstr( (const char *) data, footer ); + + if( s2 == NULL || s2 <= s1 ) + return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s1 += strlen( header ); + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + end = s2; + end += strlen( footer ); + if( *end == '\r' ) end++; + if( *end == '\n' ) end++; + *use_len = end - data; + + enc = 0; + + if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) + { +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + enc++; + + s1 += 22; + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_INVALID_DATA ); + + +#if defined(POLARSSL_DES_C) + if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) + { + enc_alg = POLARSSL_CIPHER_DES_EDE3_CBC; + + s1 += 23; + if( pem_get_iv( s1, pem_iv, 8 ) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } + else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) + { + enc_alg = POLARSSL_CIPHER_DES_CBC; + + s1 += 18; + if( pem_get_iv( s1, pem_iv, 8) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) + if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) + { + if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_128_CBC; + else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_192_CBC; + else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) + enc_alg = POLARSSL_CIPHER_AES_256_CBC; + else + return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG ); + + s1 += 22; + if( pem_get_iv( s1, pem_iv, 16 ) != 0 ) + return( POLARSSL_ERR_PEM_INVALID_ENC_IV ); + + s1 += 32; + } +#endif /* POLARSSL_AES_C */ + + if( enc_alg == POLARSSL_CIPHER_NONE ) + return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG ); + + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( POLARSSL_ERR_PEM_INVALID_DATA ); +#else + return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + } + + len = 0; + ret = base64_decode( NULL, &len, s1, s2 - s1 ); + + if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER ) + return( POLARSSL_ERR_PEM_INVALID_DATA + ret ); + + if( ( buf = (unsigned char *) polarssl_malloc( len ) ) == NULL ) + return( POLARSSL_ERR_PEM_MALLOC_FAILED ); + + if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_INVALID_DATA + ret ); + } + + if( enc != 0 ) + { +#if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) ) + if( pwd == NULL ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED ); + } + +#if defined(POLARSSL_DES_C) + if( enc_alg == POLARSSL_CIPHER_DES_EDE3_CBC ) + pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_DES_CBC ) + pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_AES_C) + if( enc_alg == POLARSSL_CIPHER_AES_128_CBC ) + pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_AES_192_CBC ) + pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); + else if( enc_alg == POLARSSL_CIPHER_AES_256_CBC ) + pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); +#endif /* POLARSSL_AES_C */ + + /* + * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 + * length bytes (allow 4 to be sure) in all known use cases. + * + * Use that as heurisitic to try detecting password mismatchs. + */ + if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) + { + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH ); + } +#else + polarssl_free( buf ); + return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_MD5_C && POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_DES_C ) */ + } + + ctx->buf = buf; + ctx->buflen = len; + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +void pem_free( pem_context *ctx ) +{ + polarssl_free( ctx->buf ); + polarssl_free( ctx->info ); + + polarssl_zeroize( ctx, sizeof( pem_context ) ); +} +#endif /* POLARSSL_PEM_PARSE_C */ + +#if defined(POLARSSL_PEM_WRITE_C) +SSL_ROM_TEXT_SECTION +int pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ) +{ + int ret; + unsigned char *encode_buf, *c, *p = buf; + size_t len = 0, use_len = 0, add_len = 0; + + base64_encode( NULL, &use_len, der_data, der_len ); + add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + + if( use_len + add_len > buf_len ) + { + *olen = use_len + add_len; + return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + if( ( encode_buf = polarssl_malloc( use_len ) ) == NULL ) + return( POLARSSL_ERR_PEM_MALLOC_FAILED ); + + if( ( ret = base64_encode( encode_buf, &use_len, der_data, + der_len ) ) != 0 ) + { + polarssl_free( encode_buf ); + return( ret ); + } + + memcpy( p, header, strlen( header ) ); + p += strlen( header ); + c = encode_buf; + + while( use_len ) + { + len = ( use_len > 64 ) ? 64 : use_len; + memcpy( p, c, len ); + use_len -= len; + p += len; + c += len; + *p++ = '\n'; + } + + memcpy( p, footer, strlen( footer ) ); + p += strlen( footer ); + + *p++ = '\0'; + *olen = p - buf; + + polarssl_free( encode_buf ); + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ +#endif /* POLARSSL_PEM_PARSE_C || POLARSSL_PEM_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk.c new file mode 100644 index 0000000..f90bf8c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk.c @@ -0,0 +1,368 @@ +/* + * Public Key abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_C) + +#include "polarssl/pk.h" +#include "polarssl/pk_wrap.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Initialise a pk_context + */ +SSL_ROM_TEXT_SECTION +void pk_init( pk_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->pk_info = NULL; + ctx->pk_ctx = NULL; +} + +/* + * Free (the components of) a pk_context + */ +SSL_ROM_TEXT_SECTION +void pk_free( pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return; + + ctx->pk_info->ctx_free_func( ctx->pk_ctx ); + + polarssl_zeroize( ctx, sizeof( pk_context ) ); +} + +/* + * Get pk_info structure from type + */ +SSL_ROM_TEXT_SECTION +const pk_info_t * pk_info_from_type( pk_type_t pk_type ) +{ + switch( pk_type ) { +#if defined(POLARSSL_RSA_C) + case POLARSSL_PK_RSA: + return( &rsa_info ); +#endif +#if defined(POLARSSL_ECP_C) + case POLARSSL_PK_ECKEY: + return( &eckey_info ); + case POLARSSL_PK_ECKEY_DH: + return( &eckeydh_info ); +#endif +#if defined(POLARSSL_ECDSA_C) + case POLARSSL_PK_ECDSA: + return( &ecdsa_info ); +#endif + /* POLARSSL_PK_RSA_ALT omitted on purpose */ + default: + return( NULL ); + } +} + +/* + * Initialise context + */ +SSL_ROM_TEXT_SECTION +int pk_init_ctx( pk_context *ctx, const pk_info_t *info ) +{ + if( ctx == NULL || info == NULL || ctx->pk_info != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + + ctx->pk_info = info; + + return( 0 ); +} + +/* + * Initialize an RSA-alt context + */ +SSL_ROM_TEXT_SECTION +int pk_init_ctx_rsa_alt( pk_context *ctx, void * key, + pk_rsa_alt_decrypt_func decrypt_func, + pk_rsa_alt_sign_func sign_func, + pk_rsa_alt_key_len_func key_len_func ) +{ + rsa_alt_context *rsa_alt; + const pk_info_t *info = &rsa_alt_info; + + if( ctx == NULL || ctx->pk_info != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( POLARSSL_ERR_PK_MALLOC_FAILED ); + + ctx->pk_info = info; + + rsa_alt = (rsa_alt_context *) ctx->pk_ctx; + + rsa_alt->key = key; + rsa_alt->decrypt_func = decrypt_func; + rsa_alt->sign_func = sign_func; + rsa_alt->key_len_func = key_len_func; + + return( 0 ); +} + +/* + * Tell if a PK can do the operations of the given type + */ +SSL_ROM_TEXT_SECTION +int pk_can_do( pk_context *ctx, pk_type_t type ) +{ + /* null or NONE context can't do anything */ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->can_do( type ) ); +} + +/* + * Helper for pk_sign and pk_verify + */ +SSL_ROM_TEXT_SECTION +static inline int pk_hashlen_helper( md_type_t md_alg, size_t *hash_len ) +{ + const md_info_t *md_info; + + if( *hash_len != 0 ) + return( 0 ); + + if( ( md_info = md_info_from_type( md_alg ) ) == NULL ) + return( -1 ); + + *hash_len = md_info->size; + return( 0 ); +} + +/* + * Verify a signature + */ +SSL_ROM_TEXT_SECTION +int pk_verify( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->verify_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len ) ); +} + +/* + * Verify a signature with options + */ +SSL_ROM_TEXT_SECTION +int pk_verify_ext( pk_type_t type, const void *options, + pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ! pk_can_do( ctx, type ) ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + if( type == POLARSSL_PK_RSASSA_PSS ) + { +#if defined(POLARSSL_RSA_C) && defined(POLARSSL_PKCS1_V21) + int ret; + const pk_rsassa_pss_options *pss_opts; + + if( options == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + pss_opts = (const pk_rsassa_pss_options *) options; + + if( sig_len < pk_get_len( ctx ) ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + ret = rsa_rsassa_pss_verify_ext( pk_rsa( *ctx ), + NULL, NULL, RSA_PUBLIC, + md_alg, hash_len, hash, + pss_opts->mgf1_hash_id, + pss_opts->expected_salt_len, + sig ); + if( ret != 0 ) + return( ret ); + + if( sig_len > pk_get_len( ctx ) ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +#else + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); +#endif + } + + /* General case: no options */ + if( options != NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + return( pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); +} + +/* + * Make a signature + */ +SSL_ROM_TEXT_SECTION +int pk_sign( pk_context *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->sign_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len, f_rng, p_rng ) ); +} + +/* + * Decrypt message + */ +SSL_ROM_TEXT_SECTION +int pk_decrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->decrypt_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Encrypt message + */ +SSL_ROM_TEXT_SECTION +int pk_encrypt( pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->encrypt_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Get key size in bits + */ +SSL_ROM_TEXT_SECTION +size_t pk_get_size( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->get_size( ctx->pk_ctx ) ); +} + +/* + * Export debug information + */ +SSL_ROM_TEXT_SECTION +int pk_debug( const pk_context *ctx, pk_debug_item *items ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->debug_func == NULL ) + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); + + ctx->pk_info->debug_func( ctx->pk_ctx, items ); + return( 0 ); +} + +/* + * Access the PK type name + */ +SSL_ROM_TEXT_SECTION +const char * pk_get_name( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( "invalid PK" ); + + return( ctx->pk_info->name ); +} + +/* + * Access the PK type + */ +SSL_ROM_TEXT_SECTION +pk_type_t pk_get_type( const pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( POLARSSL_PK_NONE ); + + return( ctx->pk_info->type ); +} + +#endif /* POLARSSL_PK_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk_wrap.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk_wrap.c new file mode 100644 index 0000000..87881b5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pk_wrap.c @@ -0,0 +1,485 @@ +/* + * Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_C) + +#include "polarssl/pk_wrap.h" + +/* Even if RSA not activated, for the sake of RSA-alt */ +#include "polarssl/rsa.h" + +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif + +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_RSA_C) +SSL_ROM_TEXT_SECTION +static int rsa_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_RSA || + type == POLARSSL_PK_RSASSA_PSS ); +} + +SSL_ROM_TEXT_SECTION +static size_t rsa_get_size( const void *ctx ) +{ + return( 8 * ((const rsa_context *) ctx)->len ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + + if( sig_len < ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = rsa_pkcs1_verify( (rsa_context *) ctx, NULL, NULL, + RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + if( sig_len > ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + *sig_len = ((rsa_context *) ctx)->len; + + return( rsa_pkcs1_sign( (rsa_context *) ctx, f_rng, p_rng, RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ilen != ((rsa_context *) ctx)->len ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_pkcs1_decrypt( (rsa_context *) ctx, f_rng, p_rng, + RSA_PRIVATE, olen, input, output, osize ) ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_encrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + ((void) osize); + + *olen = ((rsa_context *) ctx)->len; + + return( rsa_pkcs1_encrypt( (rsa_context *) ctx, + f_rng, p_rng, RSA_PUBLIC, ilen, input, output ) ); +} + +SSL_ROM_TEXT_SECTION +static void *rsa_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( rsa_context ) ); + + if( ctx != NULL ) + rsa_init( (rsa_context *) ctx, 0, 0 ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void rsa_free_wrap( void *ctx ) +{ + rsa_free( (rsa_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void rsa_debug( const void *ctx, pk_debug_item *items ) +{ + items->type = POLARSSL_PK_DEBUG_MPI; + items->name = "rsa.N"; + items->value = &( ((rsa_context *) ctx)->N ); + + items++; + + items->type = POLARSSL_PK_DEBUG_MPI; + items->name = "rsa.E"; + items->value = &( ((rsa_context *) ctx)->E ); +} + +SSL_ROM_DATA_SECTION +const pk_info_t rsa_info = { + POLARSSL_PK_RSA, + "RSA", + rsa_get_size, + rsa_can_do, + rsa_verify_wrap, + rsa_sign_wrap, + rsa_decrypt_wrap, + rsa_encrypt_wrap, + rsa_alloc_wrap, + rsa_free_wrap, + rsa_debug, +}; +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * Generic EC key + */ +SSL_ROM_TEXT_SECTION +static int eckey_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECKEY || + type == POLARSSL_PK_ECKEY_DH || + type == POLARSSL_PK_ECDSA ); +} + +SSL_ROM_TEXT_SECTION +static size_t eckey_get_size( const void *ctx ) +{ + return( ((ecp_keypair *) ctx)->grp.pbits ); +} + +#if defined(POLARSSL_ECDSA_C) +/* Forward declarations */ +static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +SSL_ROM_TEXT_SECTION +static int eckey_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ecdsa_context ecdsa; + + ecdsa_init( &ecdsa ); + + if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); + + ecdsa_free( &ecdsa ); + + return( ret ); +} + +SSL_ROM_TEXT_SECTION +static int eckey_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + ecdsa_context ecdsa; + + ecdsa_init( &ecdsa ); + + if( ( ret = ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, + f_rng, p_rng ); + + ecdsa_free( &ecdsa ); + + return( ret ); +} + +#endif /* POLARSSL_ECDSA_C */ + +SSL_ROM_TEXT_SECTION +static void *eckey_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( ecp_keypair ) ); + + if( ctx != NULL ) + ecp_keypair_init( ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void eckey_free_wrap( void *ctx ) +{ + ecp_keypair_free( (ecp_keypair *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void eckey_debug( const void *ctx, pk_debug_item *items ) +{ + items->type = POLARSSL_PK_DEBUG_ECP; + items->name = "eckey.Q"; + items->value = &( ((ecp_keypair *) ctx)->Q ); +} + +SSL_ROM_DATA_SECTION +const pk_info_t eckey_info = { + POLARSSL_PK_ECKEY, + "EC", + eckey_get_size, + eckey_can_do, +#if defined(POLARSSL_ECDSA_C) + eckey_verify_wrap, + eckey_sign_wrap, +#else + NULL, + NULL, +#endif + NULL, + NULL, + eckey_alloc_wrap, + eckey_free_wrap, + eckey_debug, +}; + +/* + * EC key restricted to ECDH + */ +SSL_ROM_TEXT_SECTION +static int eckeydh_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECKEY || + type == POLARSSL_PK_ECKEY_DH ); +} + +SSL_ROM_DATA_SECTION +const pk_info_t eckeydh_info = { + POLARSSL_PK_ECKEY_DH, + "EC_DH", + eckey_get_size, /* Same underlying key structure */ + eckeydh_can_do, + NULL, + NULL, + NULL, + NULL, + eckey_alloc_wrap, /* Same underlying key structure */ + eckey_free_wrap, /* Same underlying key structure */ + eckey_debug, /* Same underlying key structure */ +}; +#endif /* POLARSSL_ECP_C */ + +#if defined(POLARSSL_ECDSA_C) +SSL_ROM_TEXT_SECTION +static int ecdsa_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_ECDSA ); +} + +SSL_ROM_TEXT_SECTION +static int ecdsa_verify_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ((void) md_alg); + + ret = ecdsa_read_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == POLARSSL_ERR_ECP_SIG_LEN_MISMATCH ) + return( POLARSSL_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); +} + +SSL_ROM_TEXT_SECTION +static int ecdsa_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + /* Use deterministic ECDSA by default if available */ +#if defined(POLARSSL_ECDSA_DETERMINISTIC) + ((void) f_rng); + ((void) p_rng); + + return( ecdsa_write_signature_det( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len, md_alg ) ); +#else + ((void) md_alg); + + return( ecdsa_write_signature( (ecdsa_context *) ctx, + hash, hash_len, sig, sig_len, f_rng, p_rng ) ); +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ +} + +SSL_ROM_TEXT_SECTION +static void *ecdsa_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( ecdsa_context ) ); + + if( ctx != NULL ) + ecdsa_init( (ecdsa_context *) ctx ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void ecdsa_free_wrap( void *ctx ) +{ + ecdsa_free( (ecdsa_context *) ctx ); + polarssl_free( ctx ); +} + +SSL_ROM_DATA_SECTION +const pk_info_t ecdsa_info = { + POLARSSL_PK_ECDSA, + "ECDSA", + eckey_get_size, /* Compatible key structures */ + ecdsa_can_do, + ecdsa_verify_wrap, + ecdsa_sign_wrap, + NULL, + NULL, + ecdsa_alloc_wrap, + ecdsa_free_wrap, + eckey_debug, /* Compatible key structures */ +}; +#endif /* POLARSSL_ECDSA_C */ + +/* + * Support for alternative RSA-private implementations + */ +SSL_ROM_TEXT_SECTION +static int rsa_alt_can_do( pk_type_t type ) +{ + return( type == POLARSSL_PK_RSA ); +} + +SSL_ROM_TEXT_SECTION +static size_t rsa_alt_get_size( const void *ctx ) +{ + const rsa_alt_context *rsa_alt = (const rsa_alt_context *) ctx; + + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_alt_sign_wrap( void *ctx, md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx; + + *sig_len = rsa_alt->key_len_func( rsa_alt->key ); + + return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +SSL_ROM_TEXT_SECTION +static int rsa_alt_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + rsa_alt_context *rsa_alt = (rsa_alt_context *) ctx; + + ((void) f_rng); + ((void) p_rng); + + if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_alt->decrypt_func( rsa_alt->key, + RSA_PRIVATE, olen, input, output, osize ) ); +} + +SSL_ROM_TEXT_SECTION +static void *rsa_alt_alloc_wrap( void ) +{ + void *ctx = polarssl_malloc( sizeof( rsa_alt_context ) ); + + if( ctx != NULL ) + memset( ctx, 0, sizeof( rsa_alt_context ) ); + + return( ctx ); +} + +SSL_ROM_TEXT_SECTION +static void rsa_alt_free_wrap( void *ctx ) +{ + polarssl_zeroize( ctx, sizeof( rsa_alt_context ) ); + polarssl_free( ctx ); +} + +SSL_ROM_DATA_SECTION +const pk_info_t rsa_alt_info = { + POLARSSL_PK_RSA_ALT, + "RSA-alt", + rsa_alt_get_size, + rsa_alt_can_do, + NULL, + rsa_alt_sign_wrap, + rsa_alt_decrypt_wrap, + NULL, + rsa_alt_alloc_wrap, + rsa_alt_free_wrap, + NULL, +}; + +#endif /* POLARSSL_PK_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pkwrite.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pkwrite.c new file mode 100644 index 0000000..335f322 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/pkwrite.c @@ -0,0 +1,366 @@ +/* + * Public Key layer for writing key files and structures + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_PK_WRITE_C) + +#include "polarssl/pk.h" +#include "polarssl/asn1write.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif +#if defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#if defined(POLARSSL_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +SSL_ROM_TEXT_SECTION +static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, + rsa_context *rsa ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECP_C) +/* + * EC public key is an EC point + */ +SSL_ROM_TEXT_SECTION +static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, + ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + unsigned char buf[POLARSSL_ECP_MAX_PT_LEN]; + + if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q, + POLARSSL_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof( buf ) ) ) != 0 ) + { + return( ret ); + } + + if( *p - start < (int) len ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + *p -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +/* + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * } + */ +SSL_ROM_TEXT_SECTION +static int pk_write_ec_param( unsigned char **p, unsigned char *start, + ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + const char *oid; + size_t oid_len; + + if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) + return( ret ); + + ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); + + return( (int) len ); +} +#endif /* POLARSSL_ECP_C */ + +SSL_ROM_TEXT_SECTION +int pk_write_pubkey( unsigned char **p, unsigned char *start, + const pk_context *key ) +{ + int ret; + size_t len = 0; + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) ); + else +#endif +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) ); + else +#endif + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c; + size_t len = 0, par_len = 0, oid_len; + const char *oid; + + c = buf + size; + + ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) ); + + if( c - buf < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + /* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + *--c = 0; + len += 1; + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); + + if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), + &oid, &oid_len ) ) != 0 ) + { + return( ret ); + } + +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) ); + } +#endif + + ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, + par_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +SSL_ROM_TEXT_SECTION +int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c = buf + size; + size_t len = 0; + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + { + rsa_context *rsa = pk_rsa( *key ); + + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) ); + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) ); + ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + } + else +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + ecp_keypair *ec = pk_ec( *key ); + size_t pub_len = 0, par_len = 0; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + + /* publicKey */ + ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); + + if( c - buf < 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + *--c = 0; + pub_len += 1; + + ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); + ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); + + ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); + ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ); + len += pub_len; + + /* parameters */ + ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); + + ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) ); + ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); + len += par_len; + + /* privateKey: write as MPI then fix tag */ + ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) ); + *c = ASN1_OCTET_STRING; + + /* version */ + ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + } + else +#endif /* POLARSSL_ECP_C */ + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +#if defined(POLARSSL_PEM_WRITE_C) + +#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" +#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" + +#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" +#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" + +SSL_ROM_TEXT_SECTION +int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = pk_write_pubkey_der( key, output_buf, + sizeof(output_buf) ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +SSL_ROM_TEXT_SECTION +int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[4096]; + const char *begin, *end; + size_t olen = 0; + + if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) + return( ret ); + +#if defined(POLARSSL_RSA_C) + if( pk_get_type( key ) == POLARSSL_PK_RSA ) + { + begin = PEM_BEGIN_PRIVATE_KEY_RSA; + end = PEM_END_PRIVATE_KEY_RSA; + } + else +#endif +#if defined(POLARSSL_ECP_C) + if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) + { + begin = PEM_BEGIN_PRIVATE_KEY_EC; + end = PEM_END_PRIVATE_KEY_EC; + } + else +#endif + return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); + + if( ( ret = pem_write_buffer( begin, end, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ + +#endif /* POLARSSL_PK_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/rsa.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/rsa.c new file mode 100644 index 0000000..544fb38 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/rsa.c @@ -0,0 +1,1689 @@ +/* + * The RSA public-key cryptosystem + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman. + * + * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf + * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_RSA_C) + +#include "polarssl/rsa.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_PKCS1_V21) +#include "polarssl/md.h" +#endif + +#include +#include + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* + * Initialize an RSA context + */ +SSL_ROM_TEXT_SECTION +void rsa_init( rsa_context *ctx, + int padding, + int hash_id ) +{ + memset( ctx, 0, sizeof( rsa_context ) ); + + rsa_set_padding( ctx, padding, hash_id ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &ctx->mutex ); +#endif +} + +/* + * Set padding for an existing RSA context + */ +SSL_ROM_TEXT_SECTION +void rsa_set_padding( rsa_context *ctx, int padding, int hash_id ) +{ + ctx->padding = padding; + ctx->hash_id = hash_id; +} + +#if defined(POLARSSL_GENPRIME) + +/* + * Generate an RSA keypair + */ +SSL_ROM_TEXT_SECTION +int rsa_gen_key( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ) +{ + int ret; + mpi P1, Q1, H, G; + + if( f_rng == NULL || nbits < 128 || exponent < 3 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &G ); + + /* + * find primes P and Q with Q < P so that: + * GCD( E, (P-1)*(Q-1) ) == 1 + */ + MPI_CHK( mpi_lset( &ctx->E, exponent ) ); + + do + { + MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, + f_rng, p_rng ) ); + + MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0, + f_rng, p_rng ) ); + + if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) + mpi_swap( &ctx->P, &ctx->Q ); + + if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) + continue; + + MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); + if( mpi_msb( &ctx->N ) != nbits ) + continue; + + MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); + MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); + MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); + } + while( mpi_cmp_int( &G, 1 ) != 0 ); + + /* + * D = E^-1 mod ((P-1)*(Q-1)) + * DP = D mod (P - 1) + * DQ = D mod (Q - 1) + * QP = Q^-1 mod P + */ + MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) ); + MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) ); + MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) ); + MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) ); + + ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3; + +cleanup: + + mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &G ); + + if( ret != 0 ) + { + rsa_free( ctx ); + return( POLARSSL_ERR_RSA_KEY_GEN_FAILED + ret ); + } + + return( 0 ); +} + +#endif /* POLARSSL_GENPRIME */ + +/* + * Check a public RSA key + */ +SSL_ROM_TEXT_SECTION +int rsa_check_pubkey( const rsa_context *ctx ) +{ + if( !ctx->N.p || !ctx->E.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( ( ctx->N.p[0] & 1 ) == 0 || + ( ctx->E.p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( mpi_msb( &ctx->N ) < 128 || + mpi_msb( &ctx->N ) > POLARSSL_MPI_MAX_BITS ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( mpi_msb( &ctx->E ) < 2 || + mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + return( 0 ); +} + +/* + * Check a private RSA key + */ +SSL_ROM_TEXT_SECTION +int rsa_check_privkey( const rsa_context *ctx ) +{ + int ret; + mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; + + if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) + return( ret ); + + if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 ); + mpi_init( &H ); mpi_init( &I ); mpi_init( &G ); mpi_init( &G2 ); + mpi_init( &L1 ); mpi_init( &L2 ); mpi_init( &DP ); mpi_init( &DQ ); + mpi_init( &QP ); + + MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); + MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); + MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); + MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); + MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); + + MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) ); + MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) ); + MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) ); + + MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); + MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); + MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); + /* + * Check for a valid PKCS1v2 private key + */ + if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || + mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || + mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || + mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || + mpi_cmp_int( &L2, 0 ) != 0 || + mpi_cmp_int( &I, 1 ) != 0 || + mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED; + } + +cleanup: + mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 ); + mpi_free( &H ); mpi_free( &I ); mpi_free( &G ); mpi_free( &G2 ); + mpi_free( &L1 ); mpi_free( &L2 ); mpi_free( &DP ); mpi_free( &DQ ); + mpi_free( &QP ); + + if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED ) + return( ret ); + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED + ret ); + + return( 0 ); +} + +/* + * Do an RSA public key operation + */ +SSL_ROM_TEXT_SECTION +int rsa_public( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mpi T; + + mpi_init( &T ); + + MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); + + if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + mpi_free( &T ); + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + olen = ctx->len; + MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); + MPI_CHK( mpi_write_binary( &T, output, olen ) ); + +cleanup: + + mpi_free( &T ); + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +#if !defined(POLARSSL_RSA_NO_CRT) +/* + * Generate or update blinding values, see section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology—CRYPTO?6. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +SSL_ROM_TEXT_SECTION +static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count = 0; + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_lock( &ctx->mutex ); +#endif + + if( ctx->Vf.p != NULL ) + { + /* We already have blinding values, just update them by squaring */ + MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); + MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); + + goto done; + } + + /* Unblinding value: Vf = random number, invertible mod N */ + do { + if( count++ > 10 ) + return( POLARSSL_ERR_RSA_RNG_FAILED ); + + MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); + MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); + + /* Blinding value: Vi = Vf^(-e) mod N */ + MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); + +done: + if( Vi != &ctx->Vi ) + { + MPI_CHK( mpi_copy( Vi, &ctx->Vi ) ); + MPI_CHK( mpi_copy( Vf, &ctx->Vf ) ); + } + +cleanup: +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_unlock( &ctx->mutex ); +#endif + + return( ret ); +} +#endif /* !POLARSSL_RSA_NO_CRT */ + +/* + * Do an RSA private key operation + */ +SSL_ROM_TEXT_SECTION +int rsa_private( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mpi T, T1, T2; +#if !defined(POLARSSL_RSA_NO_CRT) + mpi *Vi, *Vf; + + /* + * When using the Chinese Remainder Theorem, we use blinding values. + * Without threading, we just read them directly from the context, + * otherwise we make a local copy in order to reduce locking contention. + */ +#if defined(POLARSSL_THREADING_C) + mpi Vi_copy, Vf_copy; + + mpi_init( &Vi_copy ); mpi_init( &Vf_copy ); + Vi = &Vi_copy; + Vf = &Vf_copy; +#else + Vi = &ctx->Vi; + Vf = &ctx->Vf; +#endif +#endif /* !POLARSSL_RSA_NO_CRT */ + + mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 ); + + MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); + if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + mpi_free( &T ); + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + +#if defined(POLARSSL_RSA_NO_CRT) + ((void) f_rng); + ((void) p_rng); + MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); +#else + if( f_rng != NULL ) + { + /* + * Blinding + * T = T * Vi mod N + */ + MPI_CHK( rsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &T, &T, Vi ) ); + MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); + } + + /* + * faster decryption using the CRT + * + * T1 = input ^ dP mod P + * T2 = input ^ dQ mod Q + */ + MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); + MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); + + /* + * T = (T1 - T2) * (Q^-1 mod P) mod P + */ + MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) ); + MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) ); + MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) ); + + /* + * T = T2 + T * Q + */ + MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) ); + MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) ); + + if( f_rng != NULL ) + { + /* + * Unblind + * T = T * Vf mod N + */ + MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) ); + MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); + } +#endif /* POLARSSL_RSA_NO_CRT */ + + olen = ctx->len; + MPI_CHK( mpi_write_binary( &T, output, olen ) ); + +cleanup: + mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 ); +#if !defined(POLARSSL_RSA_NO_CRT) && defined(POLARSSL_THREADING_C) + mpi_free( &Vi_copy ); mpi_free( &Vf_copy ); +#endif + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret ); + + return( 0 ); +} + +#if defined(POLARSSL_PKCS1_V21) +/** + * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. + * + * \param dst buffer to mask + * \param dlen length of destination buffer + * \param src source of the mask generation + * \param slen length of the source buffer + * \param md_ctx message digest context to use + */ +SSL_ROM_TEXT_SECTION +static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, + size_t slen, md_context_t *md_ctx ) +{ + unsigned char mask[POLARSSL_MD_MAX_SIZE]; + unsigned char counter[4]; + unsigned char *p; + unsigned int hlen; + size_t i, use_len; + + memset( mask, 0, POLARSSL_MD_MAX_SIZE ); + memset( counter, 0, 4 ); + + hlen = md_ctx->md_info->size; + + // Generate and apply dbMask + // + p = dst; + + while( dlen > 0 ) + { + use_len = hlen; + if( dlen < hlen ) + use_len = dlen; + + md_starts( md_ctx ); + md_update( md_ctx, src, slen ); + md_update( md_ctx, counter, 4 ); + md_finish( md_ctx, mask ); + + for( i = 0; i < use_len; ++i ) + *p++ ^= mask[i]; + + counter[3]++; + + dlen -= use_len; + } +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsaes_oaep_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t olen; + int ret; + unsigned char *p = output; + unsigned int hlen; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + hlen = md_get_size( md_info ); + + if( olen < ilen + 2 * hlen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + memset( output, 0, olen ); + + *p++ = 0; + + // Generate a random octet string seed + // + if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + p += hlen; + + // Construct DB + // + md( md_info, label, label_len, p ); + p += hlen; + p += olen - 2 * hlen - 2 - ilen; + *p++ = 1; + memcpy( p, input, ilen ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + // maskedDB: Apply dbMask to DB + // + mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, + &md_ctx ); + + // maskedSeed: Apply seedMask to seed + // + mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, + &md_ctx ); + + md_free( &md_ctx ); + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, output, output ) + : rsa_private( ctx, f_rng, p_rng, output, output ) ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t nb_pad, olen; + int ret; + unsigned char *p = output; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + if( olen < ilen + 11 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad = olen - 3 - ilen; + + *p++ = 0; + if( mode == RSA_PUBLIC ) + { + *p++ = RSA_CRYPT; + + //while( nb_pad-- > 0 ) + while( nb_pad > 0 ) + { + nb_pad --; + int rng_dl = 100; + + do { + ret = f_rng( p_rng, p, 1 ); + } while( *p == 0 && --rng_dl && ret == 0 ); + + // Check if RNG failed to generate data + // + if( rng_dl == 0 || ret != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + p++; + } + } + else + { + *p++ = RSA_SIGN; + + //while( nb_pad-- > 0 ) + while( nb_pad > 0 ) + { + nb_pad --; + *p++ = 0xFF; + } + } + + *p++ = 0; + memcpy( p, input, ilen ); + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, output, output ) + : rsa_private( ctx, f_rng, p_rng, output, output ) ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Add the message padding, then do an RSA operation + */ +SSL_ROM_TEXT_SECTION +int rsa_pkcs1_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, + input, output ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, + ilen, input, output ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsaes_oaep_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + int ret; + size_t ilen, i, pad_len; + unsigned char *p, bad, pad_done; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + unsigned char lhash[POLARSSL_MD_MAX_SIZE]; + unsigned int hlen; + const md_info_t *md_info; + md_context_t md_ctx; + + /* + * Parameters sanity checks + */ + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + /* + * RSA operation + */ + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, input, buf ) + : rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + /* + * Unmask data and generate lHash + */ + hlen = md_get_size( md_info ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + /* Generate lHash */ + md( md_info, label, label_len, lhash ); + + /* seed: Apply seedMask to maskedSeed */ + mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, + &md_ctx ); + + /* DB: Apply dbMask to maskedDB */ + mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, + &md_ctx ); + + md_free( &md_ctx ); + + /* + * Check contents, in "constant-time" + */ + p = buf; + bad = 0; + + bad |= *p++; /* First byte must be 0 */ + + p += hlen; /* Skip seed */ + + /* Check lHash */ + for( i = 0; i < hlen; i++ ) + bad |= lhash[i] ^ *p++; + + /* Get zero-padding len, but always read till end of buffer + * (minus one, for the 01 byte) */ + pad_len = 0; + pad_done = 0; + for( i = 0; i < ilen - 2 * hlen - 2; i++ ) + { + pad_done |= p[i]; + pad_len += ( pad_done == 0 ); + } + + p += pad_len; + bad |= *p++ ^ 0x01; + + /* + * The only information "leaked" is whether the padding was correct or not + * (eg, no data is copied if it was not correct). This meets the + * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between + * the different error conditions. + */ + if( bad != 0 ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + int ret; + size_t ilen, pad_count = 0, i; + unsigned char *p, bad, pad_done = 0; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, input, buf ) + : rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + bad = 0; + + /* + * Check and get padding len in "constant-time" + */ + bad |= *p++; /* First byte must be 0 */ + + /* This test does not depend on secret data */ + if( mode == RSA_PRIVATE ) + { + bad |= *p++ ^ RSA_CRYPT; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] == 0 ); + pad_count += ( pad_done == 0 ); + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + else + { + bad |= *p++ ^ RSA_SIGN; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] != 0xFF ); + pad_count += ( pad_done == 0 ); + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + + if( bad ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation, then remove the message padding + */ +SSL_ROM_TEXT_SECTION +int rsa_pkcs1_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, + input, output, output_max_len ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, + olen, input, output, + output_max_len ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsassa_pss_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t olen; + unsigned char *p = sig; + unsigned char salt[POLARSSL_MD_MAX_SIZE]; + unsigned int slen, hlen, offset = 0; + int ret; + size_t msb; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + if( md_alg != POLARSSL_MD_NONE ) + { + // Gather length of hash to sign + // + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + } + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hlen = md_get_size( md_info ); + slen = hlen; + + if( olen < hlen + slen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + memset( sig, 0, olen ); + + // Generate salt of length slen + // + if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + // Note: EMSA-PSS encoding is over the length of N - 1 bits + // + msb = mpi_msb( &ctx->N ) - 1; + p += olen - hlen * 2 - 2; + *p++ = 0x01; + memcpy( p, salt, slen ); + p += slen; + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + // Generate H = Hash( M' ) + // + md_starts( &md_ctx ); + md_update( &md_ctx, p, 8 ); + md_update( &md_ctx, hash, hashlen ); + md_update( &md_ctx, salt, slen ); + md_finish( &md_ctx, p ); + + // Compensate for boundary condition when applying mask + // + if( msb % 8 == 0 ) + offset = 1; + + // maskedDB: Apply dbMask to DB + // + mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); + + md_free( &md_ctx ); + + msb = mpi_msb( &ctx->N ) - 1; + sig[0] &= 0xFF >> ( olen * 8 - msb ); + + p += hlen; + *p++ = 0xBC; + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, sig ) + : rsa_private( ctx, f_rng, p_rng, sig, sig ) ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function + */ +/* + * Do an RSA operation to sign the message digest + */ +SSL_ROM_TEXT_SECTION +int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t nb_pad, olen, oid_size = 0; + unsigned char *p = sig; + const char *oid; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + nb_pad = olen - 3; + + if( md_alg != POLARSSL_MD_NONE ) + { + const md_info_t *md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad -= 10 + oid_size; + + hashlen = md_get_size( md_info ); + } + + nb_pad -= hashlen; + + if( ( nb_pad < 8 ) || ( nb_pad > olen ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + *p++ = 0; + *p++ = RSA_SIGN; + memset( p, 0xFF, nb_pad ); + p += nb_pad; + *p++ = 0; + + if( md_alg == POLARSSL_MD_NONE ) + { + memcpy( p, hash, hashlen ); + } + else + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = ASN1_NULL; + *p++ = 0x00; + *p++ = ASN1_OCTET_STRING; + *p++ = hashlen; + memcpy( p, hash, hashlen ); + } + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, sig ) + : rsa_private( ctx, f_rng, p_rng, sig, sig ) ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation to sign the message digest + */ +SSL_ROM_TEXT_SECTION +int rsa_pkcs1_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsassa_pss_verify_ext( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ) +{ + int ret; + size_t siglen; + unsigned char *p; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + unsigned char result[POLARSSL_MD_MAX_SIZE]; + unsigned char zeros[8]; + unsigned int hlen; + size_t slen, msb; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, buf ) + : rsa_private( ctx, f_rng, p_rng, sig, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( buf[siglen - 1] != 0xBC ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( md_alg != POLARSSL_MD_NONE ) + { + // Gather length of hash to sign + // + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + } + + md_info = md_info_from_type( mgf1_hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hlen = md_get_size( md_info ); + slen = siglen - hlen - 1; /* Currently length of salt + padding */ + + memset( zeros, 0, 8 ); + + // Note: EMSA-PSS verification is over the length of N - 1 bits + // + msb = mpi_msb( &ctx->N ) - 1; + + // Compensate for boundary condition when applying mask + // + if( msb % 8 == 0 ) + { + p++; + siglen -= 1; + } + if( buf[0] >> ( 8 - siglen * 8 + msb ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); + + buf[0] &= 0xFF >> ( siglen * 8 - msb ); + + while( p < buf + siglen && *p == 0 ) + p++; + + if( p == buf + siglen || + *p++ != 0x01 ) + { + md_free( &md_ctx ); + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + + /* Actual salt len */ + slen -= p - buf; + + if( expected_salt_len != RSA_SALT_LEN_ANY && + slen != (size_t) expected_salt_len ) + { + md_free( &md_ctx ); + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + + // Generate H = Hash( M' ) + // + md_starts( &md_ctx ); + md_update( &md_ctx, zeros, 8 ); + md_update( &md_ctx, hash, hashlen ); + md_update( &md_ctx, p, slen ); + md_finish( &md_ctx, result ); + + md_free( &md_ctx ); + + if( memcmp( p + slen, result, hlen ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); +} + +/* + * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsassa_pss_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + md_type_t mgf1_hash_id = ( ctx->hash_id != POLARSSL_MD_NONE ) + ? (md_type_t) ctx->hash_id + : md_alg; + + return( rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, + md_alg, hashlen, hash, + mgf1_hash_id, RSA_SALT_LEN_ANY, + sig ) ); + +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function + */ +SSL_ROM_TEXT_SECTION +int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + int ret; + size_t len, siglen, asn1_len; + unsigned char *p, *end; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + md_type_t msg_md_alg; + const md_info_t *md_info; + asn1_buf oid; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, buf ) + : rsa_private( ctx, f_rng, p_rng, sig, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( *p++ != 0 || *p++ != RSA_SIGN ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + while( *p != 0 ) + { + if( p >= buf + siglen - 1 || *p != 0xFF ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + p++; + } + p++; + + len = siglen - ( p - buf ); + + if( len == hashlen && md_alg == POLARSSL_MD_NONE ) + { + if( memcmp( p, hash, hashlen ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + hashlen = md_get_size( md_info ); + + end = p + len; + + // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure + // + if( ( ret = asn1_get_tag( &p, end, &asn1_len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 2 != len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &asn1_len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 6 + hashlen != len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + oid.p = p; + p += oid.len; + + if( oid_get_md_alg( &oid, &msg_md_alg ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( md_alg != msg_md_alg ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + /* + * assume the algorithm parameters must be NULL + */ + if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len != hashlen ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( memcmp( p, hash, hashlen ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + p += hashlen; + + if( p != end ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation and check the message digest + */ +SSL_ROM_TEXT_SECTION +int rsa_pkcs1_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +/* + * Copy the components of an RSA key + */ +SSL_ROM_TEXT_SECTION +int rsa_copy( rsa_context *dst, const rsa_context *src ) +{ + int ret; + + dst->ver = src->ver; + dst->len = src->len; + + MPI_CHK( mpi_copy( &dst->N, &src->N ) ); + MPI_CHK( mpi_copy( &dst->E, &src->E ) ); + + MPI_CHK( mpi_copy( &dst->D, &src->D ) ); + MPI_CHK( mpi_copy( &dst->P, &src->P ) ); + MPI_CHK( mpi_copy( &dst->Q, &src->Q ) ); + MPI_CHK( mpi_copy( &dst->DP, &src->DP ) ); + MPI_CHK( mpi_copy( &dst->DQ, &src->DQ ) ); + MPI_CHK( mpi_copy( &dst->QP, &src->QP ) ); + + MPI_CHK( mpi_copy( &dst->RN, &src->RN ) ); + MPI_CHK( mpi_copy( &dst->RP, &src->RP ) ); + MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) ); + +#if !defined(POLARSSL_RSA_NO_CRT) + MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) ); + MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) ); +#endif + + dst->padding = src->padding; + dst->hash_id = src->hash_id; + +cleanup: + if( ret != 0 ) + rsa_free( dst ); + + return( ret ); +} + +/* + * Free the components of an RSA key + */ +SSL_ROM_TEXT_SECTION +void rsa_free( rsa_context *ctx ) +{ +#if !defined(POLARSSL_RSA_NO_CRT) + mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf ); +#endif + mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN ); + mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP ); + mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D ); + mpi_free( &ctx->E ); mpi_free( &ctx->N ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &ctx->mutex ); +#endif +} + +#if defined(POLARSSL_SELF_TEST) + +#include "polarssl/sha1.h" + +/* + * Example RSA-1024 keypair, for test purposes + */ +#define KEY_LEN 128 + +#define RSA_N "9292758453063D803DD603D5E777D788" \ + "8ED1D5BF35786190FA2F23EBC0848AEA" \ + "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ + "7130B9CED7ACDF54CFC7555AC14EEBAB" \ + "93A89813FBF3C4F8066D2D800F7C38A8" \ + "1AE31942917403FF4946B0A83D3D3E05" \ + "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ + "5E94BB77B07507233A0BC7BAC8F90F79" + +#define RSA_E "10001" + +#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ + "66CA472BC44D253102F8B4A9D3BFA750" \ + "91386C0077937FE33FA3252D28855837" \ + "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ + "DF79C5CE07EE72C7F123142198164234" \ + "CABB724CF78B8173B9F880FC86322407" \ + "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ + "071513A1E85B5DFA031F21ECAE91A34D" + +#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ + "2C01CAD19EA484A87EA4377637E75500" \ + "FCB2005C5C7DD6EC4AC023CDA285D796" \ + "C3D9E75E1EFC42488BB4F1D13AC30A57" + +#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ + "E211C2B9E5DB1ED0BF61D0D9899620F4" \ + "910E4168387E3C30AA1E00C339A79508" \ + "8452DD96A9A5EA5D9DCA68DA636032AF" + +#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \ + "3C94D22288ACD763FD8E5600ED4A702D" \ + "F84198A5F06C2E72236AE490C93F07F8" \ + "3CC559CD27BC2D1CA488811730BB5725" + +#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \ + "D8AAEA56749EA28623272E4F7D0592AF" \ + "7C1F1313CAC9471B5C523BFE592F517B" \ + "407A1BD76C164B93DA2D32A383E58357" + +#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \ + "F38D18D2B2F0E2DD275AA977E2BF4411" \ + "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ + "A74206CEC169D74BF5A8C50D6F48EA08" + +#define PT_LEN 24 +#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ + "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" + +#if defined(POLARSSL_PKCS1_V15) +SSL_ROM_TEXT_SECTION +static int myrand( void *rng_state, unsigned char *output, size_t len ) +{ +#if !defined(__OpenBSD__) + size_t i; + + if( rng_state != NULL ) + rng_state = NULL; + + for( i = 0; i < len; ++i ) + output[i] = rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Checkup routine + */ +SSL_ROM_TEXT_SECTION +int rsa_self_test( int verbose ) +{ + int ret = 0; +#if defined(POLARSSL_PKCS1_V15) + size_t len; + rsa_context rsa; + unsigned char rsa_plaintext[PT_LEN]; + unsigned char rsa_decrypted[PT_LEN]; + unsigned char rsa_ciphertext[KEY_LEN]; +#if defined(POLARSSL_SHA1_C) + unsigned char sha1sum[20]; +#endif + + rsa_init( &rsa, RSA_PKCS_V15, 0 ); + + rsa.len = KEY_LEN; + MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); + MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); + MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); + MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); + MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); + MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); + MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); + MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); + + if( verbose != 0 ) + polarssl_printf( " RSA key validation: " ); + + if( rsa_check_pubkey( &rsa ) != 0 || + rsa_check_privkey( &rsa ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 encryption : " ); + + memcpy( rsa_plaintext, RSA_PT, PT_LEN ); + + if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN, + rsa_plaintext, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 decryption : " ); + + if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, + rsa_ciphertext, rsa_decrypted, + sizeof(rsa_decrypted) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + +#if defined(POLARSSL_SHA1_C) + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 data sign : " ); + + sha1( rsa_plaintext, PT_LEN, sha1sum ); + + if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 sig. verify: " ); + + if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); +#endif /* POLARSSL_SHA1_C */ + +cleanup: + rsa_free( &rsa ); +#else /* POLARSSL_PKCS1_V15 */ + ((void) verbose); +#endif /* POLARSSL_PKCS1_V15 */ + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_RSA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha1.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha1.c new file mode 100644 index 0000000..b0ce28c --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha1.c @@ -0,0 +1,676 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA1_C) + +#include "polarssl/sha1.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA1_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +SSL_ROM_TEXT_SECTION +void sha1_init( sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( sha1_context ) ); +} + +SSL_ROM_TEXT_SECTION +void sha1_free( sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha1_context ) ); +} + +/* + * SHA-1 context setup + */ +SSL_ROM_TEXT_SECTION +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +SSL_ROM_TEXT_SECTION +void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp, W[16], A, B, C, D, E; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +SSL_ROM_TEXT_SECTION +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +SSL_ROM_DATA_SECTION +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +SSL_ROM_TEXT_SECTION +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); +} + +#endif /* !POLARSSL_SHA1_ALT */ + +/* + * output = SHA-1( input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-1( file contents ) + */ +SSL_ROM_TEXT_SECTION +int sha1_file( const char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + sha1_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + + sha1_init( &ctx ); + sha1_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha1_update( &ctx, buf, n ); + + sha1_finish( &ctx, output ); + sha1_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-1 HMAC context setup + */ +SSL_ROM_TEXT_SECTION +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + sha1( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-1 HMAC process buffer + */ +SSL_ROM_TEXT_SECTION +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_update( ctx, input, ilen ); +} + +/* + * SHA-1 HMAC final digest + */ +SSL_ROM_TEXT_SECTION +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + sha1_finish( ctx, tmpbuf ); + sha1_starts( ctx ); + sha1_update( ctx, ctx->opad, 64 ); + sha1_update( ctx, tmpbuf, 20 ); + sha1_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA1 HMAC context reset + */ +SSL_ROM_TEXT_SECTION +void sha1_hmac_reset( sha1_context *ctx ) +{ + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-SHA-1( hmac key, input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha1_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_hmac_starts( &ctx, key, keylen ); + sha1_hmac_update( &ctx, input, ilen ); + sha1_hmac_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + sha1_init( &ctx ); + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha1_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA1_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha256.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha256.c new file mode 100644 index 0000000..72c59af --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha256.c @@ -0,0 +1,757 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-256 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA256_C) + +#include "polarssl/sha256.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA256_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +SSL_ROM_TEXT_SECTION +void sha256_init( sha256_context *ctx ) +{ + memset( ctx, 0, sizeof( sha256_context ) ); +} + +SSL_ROM_TEXT_SECTION +void sha256_free( sha256_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha256_context ) ); +} + +/* + * SHA-256 context setup + */ +SSL_ROM_TEXT_SECTION +void sha256_starts( sha256_context *ctx, int is224 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is224 == 0 ) + { + /* SHA-256 */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + } + + ctx->is224 = is224; +} + +SSL_ROM_TEXT_SECTION +void sha256_process( sha256_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A, B, C, D, E, F, G, H; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); + P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); + P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); + P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); + P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); + P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); + P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); + P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); + P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); + P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); + P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); + P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); + P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); + P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); + P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); + P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); + P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); + P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); + P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); + P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); + P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); + P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); + P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); + P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); + P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); + P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); + P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); + P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); + P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); + P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); + P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); + P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); + P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); + P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); + P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); + P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); + P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); + P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); + P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); + P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); + P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); + P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); + P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); + P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); + P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); + P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); + P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); + P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); + P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); + P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); + P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); + P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); + P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); + P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); + P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); + P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); + P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); + P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); + P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); + P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); + P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); + P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); + P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); + P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/* + * SHA-256 process buffer + */ +SSL_ROM_TEXT_SECTION +void sha256_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha256_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha256_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +SSL_ROM_DATA_SECTION +static const unsigned char sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-256 final digest + */ +SSL_ROM_TEXT_SECTION +void sha256_finish( sha256_context *ctx, unsigned char output[32] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha256_update( ctx, sha256_padding, padn ); + sha256_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); + + if( ctx->is224 == 0 ) + PUT_UINT32_BE( ctx->state[7], output, 28 ); +} + +#endif /* !POLARSSL_SHA256_ALT */ + +/* + * output = SHA-256( input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha256( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + sha256_context ctx; + + sha256_init( &ctx ); + sha256_starts( &ctx, is224 ); + sha256_update( &ctx, input, ilen ); + sha256_finish( &ctx, output ); + sha256_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-256( file contents ) + */ +SSL_ROM_TEXT_SECTION +int sha256_file( const char *path, unsigned char output[32], int is224 ) +{ + FILE *f; + size_t n; + sha256_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); + + sha256_init( &ctx ); + sha256_starts( &ctx, is224 ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha256_update( &ctx, buf, n ); + + sha256_finish( &ctx, output ); + sha256_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-256 HMAC context setup + */ +SSL_ROM_TEXT_SECTION +void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key, + size_t keylen, int is224 ) +{ + size_t i; + unsigned char sum[32]; + + if( keylen > 64 ) + { + sha256( key, keylen, sum, is224 ); + keylen = ( is224 ) ? 28 : 32; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha256_starts( ctx, is224 ); + sha256_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-256 HMAC process buffer + */ +SSL_ROM_TEXT_SECTION +void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( ctx, input, ilen ); +} + +/* + * SHA-256 HMAC final digest + */ +SSL_ROM_TEXT_SECTION +void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] ) +{ + int is224, hlen; + unsigned char tmpbuf[32]; + + is224 = ctx->is224; + hlen = ( is224 == 0 ) ? 32 : 28; + + sha256_finish( ctx, tmpbuf ); + sha256_starts( ctx, is224 ); + sha256_update( ctx, ctx->opad, 64 ); + sha256_update( ctx, tmpbuf, hlen ); + sha256_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA-256 HMAC context reset + */ +SSL_ROM_TEXT_SECTION +void sha256_hmac_reset( sha256_context *ctx ) +{ + sha256_starts( ctx, ctx->is224 ); + sha256_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-SHA-256( hmac key, input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha256_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + sha256_context ctx; + + sha256_init( &ctx ); + sha256_hmac_starts( &ctx, key, keylen, is224 ); + sha256_hmac_update( &ctx, input, ilen ); + sha256_hmac_finish( &ctx, output ); + sha256_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha256_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha256_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha256_test_sum[6][32] = +{ + /* + * SHA-224 test vectors + */ + { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, + 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, + 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, + 0xE3, 0x6C, 0x9D, 0xA7 }, + { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, + 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, + 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, + 0x52, 0x52, 0x25, 0x25 }, + { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, + 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, + 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, + 0x4E, 0xE7, 0xAD, 0x67 }, + + /* + * SHA-256 test vectors + */ + { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, + { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, + { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha256_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha256_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha256_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha256_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha256_hmac_test_sum[14][32] = +{ + /* + * HMAC-SHA-224 test vectors + */ + { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19, + 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F, + 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F, + 0x53, 0x68, 0x4B, 0x22 }, + { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF, + 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F, + 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00, + 0x8F, 0xD0, 0x5E, 0x44 }, + { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6, + 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64, + 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1, + 0xEC, 0x83, 0x33, 0xEA }, + { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC, + 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C, + 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D, + 0xE7, 0xAF, 0xEC, 0x5A }, + { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37, + 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 }, + { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD, + 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2, + 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27, + 0x3F, 0xA6, 0x87, 0x0E }, + { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02, + 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD, + 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9, + 0xF6, 0xF5, 0x65, 0xD1 }, + + /* + * HMAC-SHA-256 test vectors + */ + { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53, + 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B, + 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7, + 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 }, + { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E, + 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7, + 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83, + 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 }, + { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46, + 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7, + 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22, + 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE }, + { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E, + 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A, + 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07, + 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B }, + { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0, + 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B }, + { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F, + 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F, + 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14, + 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 }, + { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB, + 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44, + 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93, + 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 } +}; + +/* + * Checkup routine + */ +int sha256_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha256sum[32]; + sha256_context ctx; + + sha256_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + sha256_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha256_update( &ctx, buf, buflen ); + } + else + sha256_update( &ctx, sha256_test_buf[j], + sha256_test_buflen[j] ); + + sha256_finish( &ctx, sha256sum ); + + if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha256_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha256_hmac_starts( &ctx, sha256_hmac_test_key[j], + sha256_hmac_test_keylen[j], k ); + + sha256_hmac_update( &ctx, sha256_hmac_test_buf[j], + sha256_hmac_test_buflen[j] ); + + sha256_hmac_finish( &ctx, sha256sum ); + + buflen = ( j == 4 ) ? 16 : 32 - k * 4; + + if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha256_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA256_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha512.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha512.c new file mode 100644 index 0000000..fb1aba9 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rom/sha512.c @@ -0,0 +1,812 @@ +/* + * FIPS-180-2 compliant SHA-384/512 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-512 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA512_C) + +#include "polarssl/sha512.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +SSL_ROM_TEXT_SECTION +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA512_ALT) + +/* + * 64-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#ifndef PUT_UINT64_BE +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} +#endif /* PUT_UINT64_BE */ + +/* + * Round constants + */ +SSL_ROM_DATA_SECTION +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + +SSL_ROM_TEXT_SECTION +void sha512_init( sha512_context *ctx ) +{ + memset( ctx, 0, sizeof( sha512_context ) ); +} + +SSL_ROM_TEXT_SECTION +void sha512_free( sha512_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha512_context ) ); +} + +/* + * SHA-512 context setup + */ +SSL_ROM_TEXT_SECTION +void sha512_starts( sha512_context *ctx, int is384 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is384 == 0 ) + { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } + else + { + /* SHA-384 */ + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } + + ctx->is384 = is384; +} + +SSL_ROM_TEXT_SECTION +void sha512_process( sha512_context *ctx, const unsigned char data[128] ) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A, B, C, D, E, F, G, H; + +#define SHR(x,n) (x >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + for( i = 0; i < 16; i++ ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + + for( ; i < 80; i++ ) + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[i - 16]; + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + i = 0; + + do + { + P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; + P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; + P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; + P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; + P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; + P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; + P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; + P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; + } + while( i < 80 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/* + * SHA-512 process buffer + */ +SSL_ROM_TEXT_SECTION +void sha512_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + unsigned int left; + + if( ilen == 0 ) + return; + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if( ctx->total[0] < (uint64_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha512_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 128 ) + { + sha512_process( ctx, input ); + input += 128; + ilen -= 128; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +SSL_ROM_DATA_SECTION +static const unsigned char sha512_padding[128] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-512 final digest + */ +SSL_ROM_TEXT_SECTION +void sha512_finish( sha512_context *ctx, unsigned char output[64] ) +{ + size_t last, padn; + uint64_t high, low; + unsigned char msglen[16]; + + high = ( ctx->total[0] >> 61 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT64_BE( high, msglen, 0 ); + PUT_UINT64_BE( low, msglen, 8 ); + + last = (size_t)( ctx->total[0] & 0x7F ); + padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + + sha512_update( ctx, sha512_padding, padn ); + sha512_update( ctx, msglen, 16 ); + + PUT_UINT64_BE( ctx->state[0], output, 0 ); + PUT_UINT64_BE( ctx->state[1], output, 8 ); + PUT_UINT64_BE( ctx->state[2], output, 16 ); + PUT_UINT64_BE( ctx->state[3], output, 24 ); + PUT_UINT64_BE( ctx->state[4], output, 32 ); + PUT_UINT64_BE( ctx->state[5], output, 40 ); + + if( ctx->is384 == 0 ) + { + PUT_UINT64_BE( ctx->state[6], output, 48 ); + PUT_UINT64_BE( ctx->state[7], output, 56 ); + } +} + +#endif /* !POLARSSL_SHA512_ALT */ + +/* + * output = SHA-512( input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha512( const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) +{ + sha512_context ctx; + + sha512_init( &ctx ); + sha512_starts( &ctx, is384 ); + sha512_update( &ctx, input, ilen ); + sha512_finish( &ctx, output ); + sha512_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-512( file contents ) + */ +SSL_ROM_TEXT_SECTION +int sha512_file( const char *path, unsigned char output[64], int is384 ) +{ + FILE *f; + size_t n; + sha512_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); + + sha512_init( &ctx ); + sha512_starts( &ctx, is384 ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha512_update( &ctx, buf, n ); + + sha512_finish( &ctx, output ); + sha512_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-512 HMAC context setup + */ +SSL_ROM_TEXT_SECTION +void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key, + size_t keylen, int is384 ) +{ + size_t i; + unsigned char sum[64]; + + if( keylen > 128 ) + { + sha512( key, keylen, sum, is384 ); + keylen = ( is384 ) ? 48 : 64; + key = sum; + } + + memset( ctx->ipad, 0x36, 128 ); + memset( ctx->opad, 0x5C, 128 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha512_starts( ctx, is384 ); + sha512_update( ctx, ctx->ipad, 128 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-512 HMAC process buffer + */ +SSL_ROM_TEXT_SECTION +void sha512_hmac_update( sha512_context *ctx, + const unsigned char *input, size_t ilen ) +{ + sha512_update( ctx, input, ilen ); +} + +/* + * SHA-512 HMAC final digest + */ +SSL_ROM_TEXT_SECTION +void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] ) +{ + int is384, hlen; + unsigned char tmpbuf[64]; + + is384 = ctx->is384; + hlen = ( is384 == 0 ) ? 64 : 48; + + sha512_finish( ctx, tmpbuf ); + sha512_starts( ctx, is384 ); + sha512_update( ctx, ctx->opad, 128 ); + sha512_update( ctx, tmpbuf, hlen ); + sha512_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA-512 HMAC context reset + */ +SSL_ROM_TEXT_SECTION +void sha512_hmac_reset( sha512_context *ctx ) +{ + sha512_starts( ctx, ctx->is384 ); + sha512_update( ctx, ctx->ipad, 128 ); +} + +/* + * output = HMAC-SHA-512( hmac key, input buffer ) + */ +SSL_ROM_TEXT_SECTION +void sha512_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) +{ + sha512_context ctx; + + sha512_init( &ctx ); + sha512_hmac_starts( &ctx, key, keylen, is384 ); + sha512_hmac_update( &ctx, input, ilen ); + sha512_hmac_finish( &ctx, output ); + sha512_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha512_test_buf[3][113] = +{ + { "abc" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "" } +}; + +static const int sha512_test_buflen[3] = +{ + 3, 112, 1000 +}; + +static const unsigned char sha512_test_sum[6][64] = +{ + /* + * SHA-384 test vectors + */ + { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, + 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, + 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, + 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, + 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, + 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, + { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, + 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, + 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, + 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, + 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, + 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, + { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, + 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, + 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, + 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, + 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, + 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, + + /* + * SHA-512 test vectors + */ + { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, + 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, + 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, + 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, + 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, + 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, + 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, + 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, + { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, + { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, + 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, + 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, + 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, + 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, + 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, + 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha512_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha512_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha512_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha512_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha512_hmac_test_sum[14][64] = +{ + /* + * HMAC-SHA-384 test vectors + */ + { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62, + 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F, + 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6, + 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C, + 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F, + 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 }, + { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31, + 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B, + 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47, + 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E, + 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7, + 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 }, + { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A, + 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F, + 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB, + 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B, + 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9, + 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 }, + { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85, + 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7, + 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C, + 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E, + 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79, + 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB }, + { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23, + 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 }, + { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90, + 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4, + 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F, + 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6, + 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82, + 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 }, + { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D, + 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C, + 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A, + 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5, + 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D, + 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E }, + + /* + * HMAC-SHA-512 test vectors + */ + { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D, + 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0, + 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78, + 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE, + 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02, + 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4, + 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70, + 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 }, + { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2, + 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3, + 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6, + 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54, + 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A, + 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD, + 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B, + 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 }, + { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84, + 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9, + 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36, + 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39, + 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8, + 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07, + 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26, + 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB }, + { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69, + 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7, + 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D, + 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB, + 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4, + 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63, + 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D, + 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD }, + { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53, + 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 }, + { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB, + 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4, + 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1, + 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52, + 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98, + 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52, + 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC, + 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 }, + { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA, + 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD, + 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86, + 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44, + 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1, + 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15, + 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60, + 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 } +}; + +/* + * Checkup routine + */ +int sha512_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha512sum[64]; + sha512_context ctx; + + sha512_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + sha512_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha512_update( &ctx, buf, buflen ); + } + else + sha512_update( &ctx, sha512_test_buf[j], + sha512_test_buflen[j] ); + + sha512_finish( &ctx, sha512sum ); + + if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha512_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha512_hmac_starts( &ctx, sha512_hmac_test_key[j], + sha512_hmac_test_keylen[j], k ); + + sha512_hmac_update( &ctx, sha512_hmac_test_buf[j], + sha512_hmac_test_buflen[j] ); + + sha512_hmac_finish( &ctx, sha512sum ); + + buflen = ( j == 4 ) ? 16 : 64 - k * 16; + + if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha512_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA512_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/rsa.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rsa.c new file mode 100644 index 0000000..a4bf212 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/rsa.c @@ -0,0 +1,1663 @@ +/* + * The RSA public-key cryptosystem + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman. + * + * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf + * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_RSA_C) + +#include "polarssl/rsa.h" +#include "polarssl/oid.h" + +#if defined(POLARSSL_PKCS1_V21) +#include "polarssl/md.h" +#endif + +#include +#include + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* + * Initialize an RSA context + */ +void rsa_init( rsa_context *ctx, + int padding, + int hash_id ) +{ + memset( ctx, 0, sizeof( rsa_context ) ); + + rsa_set_padding( ctx, padding, hash_id ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &ctx->mutex ); +#endif +} + +/* + * Set padding for an existing RSA context + */ +void rsa_set_padding( rsa_context *ctx, int padding, int hash_id ) +{ + ctx->padding = padding; + ctx->hash_id = hash_id; +} + +#if defined(POLARSSL_GENPRIME) + +/* + * Generate an RSA keypair + */ +int rsa_gen_key( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ) +{ + int ret; + mpi P1, Q1, H, G; + + if( f_rng == NULL || nbits < 128 || exponent < 3 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &G ); + + /* + * find primes P and Q with Q < P so that: + * GCD( E, (P-1)*(Q-1) ) == 1 + */ + MPI_CHK( mpi_lset( &ctx->E, exponent ) ); + + do + { + MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, + f_rng, p_rng ) ); + + MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0, + f_rng, p_rng ) ); + + if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) + mpi_swap( &ctx->P, &ctx->Q ); + + if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) + continue; + + MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); + if( mpi_msb( &ctx->N ) != nbits ) + continue; + + MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); + MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); + MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); + } + while( mpi_cmp_int( &G, 1 ) != 0 ); + + /* + * D = E^-1 mod ((P-1)*(Q-1)) + * DP = D mod (P - 1) + * DQ = D mod (Q - 1) + * QP = Q^-1 mod P + */ + MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) ); + MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) ); + MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) ); + MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) ); + + ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3; + +cleanup: + + mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &G ); + + if( ret != 0 ) + { + rsa_free( ctx ); + return( POLARSSL_ERR_RSA_KEY_GEN_FAILED + ret ); + } + + return( 0 ); +} + +#endif /* POLARSSL_GENPRIME */ + +/* + * Check a public RSA key + */ +int rsa_check_pubkey( const rsa_context *ctx ) +{ + if( !ctx->N.p || !ctx->E.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( ( ctx->N.p[0] & 1 ) == 0 || + ( ctx->E.p[0] & 1 ) == 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( mpi_msb( &ctx->N ) < 128 || + mpi_msb( &ctx->N ) > POLARSSL_MPI_MAX_BITS ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + if( mpi_msb( &ctx->E ) < 2 || + mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + return( 0 ); +} + +/* + * Check a private RSA key + */ +int rsa_check_privkey( const rsa_context *ctx ) +{ + int ret; + mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; + + if( ( ret = rsa_check_pubkey( ctx ) ) != 0 ) + return( ret ); + + if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED ); + + mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 ); + mpi_init( &H ); mpi_init( &I ); mpi_init( &G ); mpi_init( &G2 ); + mpi_init( &L1 ); mpi_init( &L2 ); mpi_init( &DP ); mpi_init( &DQ ); + mpi_init( &QP ); + + MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); + MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); + MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) ); + MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) ); + MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) ); + + MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) ); + MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) ); + MPI_CHK( mpi_mod_mpi( &I, &DE, &L1 ) ); + + MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); + MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); + MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); + /* + * Check for a valid PKCS1v2 private key + */ + if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || + mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || + mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || + mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || + mpi_cmp_int( &L2, 0 ) != 0 || + mpi_cmp_int( &I, 1 ) != 0 || + mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED; + } + +cleanup: + mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 ); + mpi_free( &H ); mpi_free( &I ); mpi_free( &G ); mpi_free( &G2 ); + mpi_free( &L1 ); mpi_free( &L2 ); mpi_free( &DP ); mpi_free( &DQ ); + mpi_free( &QP ); + + if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED ) + return( ret ); + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED + ret ); + + return( 0 ); +} + +/* + * Do an RSA public key operation + */ +int rsa_public( rsa_context *ctx, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mpi T; + + mpi_init( &T ); + + MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); + + if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + mpi_free( &T ); + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + + olen = ctx->len; + MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); + MPI_CHK( mpi_write_binary( &T, output, olen ) ); + +cleanup: + + mpi_free( &T ); + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +#if !defined(POLARSSL_RSA_NO_CRT) +/* + * Generate or update blinding values, see section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count = 0; + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_lock( &ctx->mutex ); +#endif + + if( ctx->Vf.p != NULL ) + { + /* We already have blinding values, just update them by squaring */ + MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); + MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); + + goto done; + } + + /* Unblinding value: Vf = random number, invertible mod N */ + do { + if( count++ > 10 ) + return( POLARSSL_ERR_RSA_RNG_FAILED ); + + MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); + MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); + + /* Blinding value: Vi = Vf^(-e) mod N */ + MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); + +done: + if( Vi != &ctx->Vi ) + { + MPI_CHK( mpi_copy( Vi, &ctx->Vi ) ); + MPI_CHK( mpi_copy( Vf, &ctx->Vf ) ); + } + +cleanup: +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_unlock( &ctx->mutex ); +#endif + + return( ret ); +} +#endif /* !POLARSSL_RSA_NO_CRT */ + +/* + * Do an RSA private key operation + */ +int rsa_private( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mpi T, T1, T2; +#if !defined(POLARSSL_RSA_NO_CRT) + mpi *Vi, *Vf; + + /* + * When using the Chinese Remainder Theorem, we use blinding values. + * Without threading, we just read them directly from the context, + * otherwise we make a local copy in order to reduce locking contention. + */ +#if defined(POLARSSL_THREADING_C) + mpi Vi_copy, Vf_copy; + + mpi_init( &Vi_copy ); mpi_init( &Vf_copy ); + Vi = &Vi_copy; + Vf = &Vf_copy; +#else + Vi = &ctx->Vi; + Vf = &ctx->Vf; +#endif +#endif /* !POLARSSL_RSA_NO_CRT */ + + mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 ); + + MPI_CHK( mpi_read_binary( &T, input, ctx->len ) ); + if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + mpi_free( &T ); + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + } + +#if defined(POLARSSL_RSA_NO_CRT) + ((void) f_rng); + ((void) p_rng); + MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); +#else + if( f_rng != NULL ) + { + /* + * Blinding + * T = T * Vi mod N + */ + MPI_CHK( rsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) ); + MPI_CHK( mpi_mul_mpi( &T, &T, Vi ) ); + MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); + } + + /* + * faster decryption using the CRT + * + * T1 = input ^ dP mod P + * T2 = input ^ dQ mod Q + */ + MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); + MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); + + /* + * T = (T1 - T2) * (Q^-1 mod P) mod P + */ + MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) ); + MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) ); + MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) ); + + /* + * T = T2 + T * Q + */ + MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) ); + MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) ); + + if( f_rng != NULL ) + { + /* + * Unblind + * T = T * Vf mod N + */ + MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) ); + MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) ); + } +#endif /* POLARSSL_RSA_NO_CRT */ + + olen = ctx->len; + MPI_CHK( mpi_write_binary( &T, output, olen ) ); + +cleanup: + mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 ); +#if !defined(POLARSSL_RSA_NO_CRT) && defined(POLARSSL_THREADING_C) + mpi_free( &Vi_copy ); mpi_free( &Vf_copy ); +#endif + + if( ret != 0 ) + return( POLARSSL_ERR_RSA_PRIVATE_FAILED + ret ); + + return( 0 ); +} + +#if defined(POLARSSL_PKCS1_V21) +/** + * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. + * + * \param dst buffer to mask + * \param dlen length of destination buffer + * \param src source of the mask generation + * \param slen length of the source buffer + * \param md_ctx message digest context to use + */ +static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, + size_t slen, md_context_t *md_ctx ) +{ + unsigned char mask[POLARSSL_MD_MAX_SIZE]; + unsigned char counter[4]; + unsigned char *p; + unsigned int hlen; + size_t i, use_len; + + memset( mask, 0, POLARSSL_MD_MAX_SIZE ); + memset( counter, 0, 4 ); + + hlen = md_ctx->md_info->size; + + // Generate and apply dbMask + // + p = dst; + + while( dlen > 0 ) + { + use_len = hlen; + if( dlen < hlen ) + use_len = dlen; + + md_starts( md_ctx ); + md_update( md_ctx, src, slen ); + md_update( md_ctx, counter, 4 ); + md_finish( md_ctx, mask ); + + for( i = 0; i < use_len; ++i ) + *p++ ^= mask[i]; + + counter[3]++; + + dlen -= use_len; + } +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function + */ +int rsa_rsaes_oaep_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t olen; + int ret; + unsigned char *p = output; + unsigned int hlen; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + hlen = md_get_size( md_info ); + + if( olen < ilen + 2 * hlen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + memset( output, 0, olen ); + + *p++ = 0; + + // Generate a random octet string seed + // + if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + p += hlen; + + // Construct DB + // + md( md_info, label, label_len, p ); + p += hlen; + p += olen - 2 * hlen - 2 - ilen; + *p++ = 1; + memcpy( p, input, ilen ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + // maskedDB: Apply dbMask to DB + // + mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, + &md_ctx ); + + // maskedSeed: Apply seedMask to seed + // + mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, + &md_ctx ); + + md_free( &md_ctx ); + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, output, output ) + : rsa_private( ctx, f_rng, p_rng, output, output ) ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function + */ +int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t nb_pad, olen; + int ret; + unsigned char *p = output; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + if( olen < ilen + 11 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad = olen - 3 - ilen; + + *p++ = 0; + if( mode == RSA_PUBLIC ) + { + *p++ = RSA_CRYPT; + + //while( nb_pad-- > 0 ) + while( nb_pad > 0 ) + { + nb_pad --; + int rng_dl = 100; + + do { + ret = f_rng( p_rng, p, 1 ); + } while( *p == 0 && --rng_dl && ret == 0 ); + + // Check if RNG failed to generate data + // + if( rng_dl == 0 || ret != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + p++; + } + } + else + { + *p++ = RSA_SIGN; + + //while( nb_pad-- > 0 ) + while( nb_pad > 0 ) + { + nb_pad --; + *p++ = 0xFF; + } + } + + *p++ = 0; + memcpy( p, input, ilen ); + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, output, output ) + : rsa_private( ctx, f_rng, p_rng, output, output ) ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Add the message padding, then do an RSA operation + */ +int rsa_pkcs1_encrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, + input, output ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, + ilen, input, output ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function + */ +int rsa_rsaes_oaep_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + int ret; + size_t ilen, i, pad_len; + unsigned char *p, bad, pad_done; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + unsigned char lhash[POLARSSL_MD_MAX_SIZE]; + unsigned int hlen; + const md_info_t *md_info; + md_context_t md_ctx; + + /* + * Parameters sanity checks + */ + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + /* + * RSA operation + */ + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, input, buf ) + : rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + /* + * Unmask data and generate lHash + */ + hlen = md_get_size( md_info ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + /* Generate lHash */ + md( md_info, label, label_len, lhash ); + + /* seed: Apply seedMask to maskedSeed */ + mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, + &md_ctx ); + + /* DB: Apply dbMask to maskedDB */ + mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, + &md_ctx ); + + md_free( &md_ctx ); + + /* + * Check contents, in "constant-time" + */ + p = buf; + bad = 0; + + bad |= *p++; /* First byte must be 0 */ + + p += hlen; /* Skip seed */ + + /* Check lHash */ + for( i = 0; i < hlen; i++ ) + bad |= lhash[i] ^ *p++; + + /* Get zero-padding len, but always read till end of buffer + * (minus one, for the 01 byte) */ + pad_len = 0; + pad_done = 0; + for( i = 0; i < ilen - 2 * hlen - 2; i++ ) + { + pad_done |= p[i]; + pad_len += ( pad_done == 0 ); + } + + p += pad_len; + bad |= *p++ ^ 0x01; + + /* + * The only information "leaked" is whether the padding was correct or not + * (eg, no data is copied if it was not correct). This meets the + * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between + * the different error conditions. + */ + if( bad != 0 ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function + */ +int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + int ret; + size_t ilen, pad_count = 0, i; + unsigned char *p, bad, pad_done = 0; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, input, buf ) + : rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + bad = 0; + + /* + * Check and get padding len in "constant-time" + */ + bad |= *p++; /* First byte must be 0 */ + + /* This test does not depend on secret data */ + if( mode == RSA_PRIVATE ) + { + bad |= *p++ ^ RSA_CRYPT; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] == 0 ); + pad_count += ( pad_done == 0 ); + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + else + { + bad |= *p++ ^ RSA_SIGN; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] != 0xFF ); + pad_count += ( pad_done == 0 ); + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + + if( bad ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation, then remove the message padding + */ +int rsa_pkcs1_decrypt( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, + input, output, output_max_len ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, + olen, input, output, + output_max_len ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function + */ +int rsa_rsassa_pss_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t olen; + unsigned char *p = sig; + unsigned char salt[POLARSSL_MD_MAX_SIZE]; + unsigned int slen, hlen, offset = 0; + int ret; + size_t msb; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + if( md_alg != POLARSSL_MD_NONE ) + { + // Gather length of hash to sign + // + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + } + + md_info = md_info_from_type( ctx->hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hlen = md_get_size( md_info ); + slen = hlen; + + if( olen < hlen + slen + 2 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + memset( sig, 0, olen ); + + // Generate salt of length slen + // + if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) + return( POLARSSL_ERR_RSA_RNG_FAILED + ret ); + + // Note: EMSA-PSS encoding is over the length of N - 1 bits + // + msb = mpi_msb( &ctx->N ) - 1; + p += olen - hlen * 2 - 2; + *p++ = 0x01; + memcpy( p, salt, slen ); + p += slen; + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + // Generate H = Hash( M' ) + // + md_starts( &md_ctx ); + md_update( &md_ctx, p, 8 ); + md_update( &md_ctx, hash, hashlen ); + md_update( &md_ctx, salt, slen ); + md_finish( &md_ctx, p ); + + // Compensate for boundary condition when applying mask + // + if( msb % 8 == 0 ) + offset = 1; + + // maskedDB: Apply dbMask to DB + // + mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); + + md_free( &md_ctx ); + + msb = mpi_msb( &ctx->N ) - 1; + sig[0] &= 0xFF >> ( olen * 8 - msb ); + + p += hlen; + *p++ = 0xBC; + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, sig ) + : rsa_private( ctx, f_rng, p_rng, sig, sig ) ); +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function + */ +/* + * Do an RSA operation to sign the message digest + */ +int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t nb_pad, olen, oid_size = 0; + unsigned char *p = sig; + const char *oid; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + nb_pad = olen - 3; + + if( md_alg != POLARSSL_MD_NONE ) + { + const md_info_t *md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad -= 10 + oid_size; + + hashlen = md_get_size( md_info ); + } + + nb_pad -= hashlen; + + if( ( nb_pad < 8 ) || ( nb_pad > olen ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + *p++ = 0; + *p++ = RSA_SIGN; + memset( p, 0xFF, nb_pad ); + p += nb_pad; + *p++ = 0; + + if( md_alg == POLARSSL_MD_NONE ) + { + memcpy( p, hash, hashlen ); + } + else + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = ASN1_NULL; + *p++ = 0x00; + *p++ = ASN1_OCTET_STRING; + *p++ = hashlen; + memcpy( p, hash, hashlen ); + } + + return( ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, sig ) + : rsa_private( ctx, f_rng, p_rng, sig, sig ) ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation to sign the message digest + */ +int rsa_pkcs1_sign( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(POLARSSL_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +int rsa_rsassa_pss_verify_ext( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ) +{ + int ret; + size_t siglen; + unsigned char *p; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + unsigned char result[POLARSSL_MD_MAX_SIZE]; + unsigned char zeros[8]; + unsigned int hlen; + size_t slen, msb; + const md_info_t *md_info; + md_context_t md_ctx; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V21 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, buf ) + : rsa_private( ctx, f_rng, p_rng, sig, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( buf[siglen - 1] != 0xBC ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + if( md_alg != POLARSSL_MD_NONE ) + { + // Gather length of hash to sign + // + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = md_get_size( md_info ); + } + + md_info = md_info_from_type( mgf1_hash_id ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + hlen = md_get_size( md_info ); + slen = siglen - hlen - 1; /* Currently length of salt + padding */ + + memset( zeros, 0, 8 ); + + // Note: EMSA-PSS verification is over the length of N - 1 bits + // + msb = mpi_msb( &ctx->N ) - 1; + + // Compensate for boundary condition when applying mask + // + if( msb % 8 == 0 ) + { + p++; + siglen -= 1; + } + if( buf[0] >> ( 8 - siglen * 8 + msb ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + md_init( &md_ctx ); + md_init_ctx( &md_ctx, md_info ); + + mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); + + buf[0] &= 0xFF >> ( siglen * 8 - msb ); + + while( p < buf + siglen && *p == 0 ) + p++; + + if( p == buf + siglen || + *p++ != 0x01 ) + { + md_free( &md_ctx ); + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + + /* Actual salt len */ + slen -= p - buf; + + if( expected_salt_len != RSA_SALT_LEN_ANY && + slen != (size_t) expected_salt_len ) + { + md_free( &md_ctx ); + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } + + // Generate H = Hash( M' ) + // + md_starts( &md_ctx ); + md_update( &md_ctx, zeros, 8 ); + md_update( &md_ctx, hash, hashlen ); + md_update( &md_ctx, p, slen ); + md_finish( &md_ctx, result ); + + md_free( &md_ctx ); + + if( memcmp( p + slen, result, hlen ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); +} + +/* + * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +int rsa_rsassa_pss_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + md_type_t mgf1_hash_id = ( ctx->hash_id != POLARSSL_MD_NONE ) + ? (md_type_t) ctx->hash_id + : md_alg; + + return( rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, + md_alg, hashlen, hash, + mgf1_hash_id, RSA_SALT_LEN_ANY, + sig ) ); + +} +#endif /* POLARSSL_PKCS1_V21 */ + +#if defined(POLARSSL_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function + */ +int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + int ret; + size_t len, siglen, asn1_len; + unsigned char *p, *end; + unsigned char buf[POLARSSL_MPI_MAX_SIZE]; + md_type_t msg_md_alg; + const md_info_t *md_info; + asn1_buf oid; + + if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == RSA_PUBLIC ) + ? rsa_public( ctx, sig, buf ) + : rsa_private( ctx, f_rng, p_rng, sig, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( *p++ != 0 || *p++ != RSA_SIGN ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + + while( *p != 0 ) + { + if( p >= buf + siglen - 1 || *p != 0xFF ) + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + p++; + } + p++; + + len = siglen - ( p - buf ); + + if( len == hashlen && md_alg == POLARSSL_MD_NONE ) + { + if( memcmp( p, hash, hashlen ) == 0 ) + return( 0 ); + else + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + } + + md_info = md_info_from_type( md_alg ); + if( md_info == NULL ) + return( POLARSSL_ERR_RSA_BAD_INPUT_DATA ); + hashlen = md_get_size( md_info ); + + end = p + len; + + // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure + // + if( ( ret = asn1_get_tag( &p, end, &asn1_len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 2 != len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &asn1_len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 6 + hashlen != len ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + oid.p = p; + p += oid.len; + + if( oid_get_md_alg( &oid, &msg_md_alg ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( md_alg != msg_md_alg ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + /* + * assume the algorithm parameters must be NULL + */ + if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len != hashlen ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + if( memcmp( p, hash, hashlen ) != 0 ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + p += hashlen; + + if( p != end ) + return( POLARSSL_ERR_RSA_VERIFY_FAILED ); + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Do an RSA operation and check the message digest + */ +int rsa_pkcs1_verify( rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(POLARSSL_PKCS1_V15) + case RSA_PKCS_V15: + return rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(POLARSSL_PKCS1_V21) + case RSA_PKCS_V21: + return rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( POLARSSL_ERR_RSA_INVALID_PADDING ); + } +} + +/* + * Copy the components of an RSA key + */ +int rsa_copy( rsa_context *dst, const rsa_context *src ) +{ + int ret; + + dst->ver = src->ver; + dst->len = src->len; + + MPI_CHK( mpi_copy( &dst->N, &src->N ) ); + MPI_CHK( mpi_copy( &dst->E, &src->E ) ); + + MPI_CHK( mpi_copy( &dst->D, &src->D ) ); + MPI_CHK( mpi_copy( &dst->P, &src->P ) ); + MPI_CHK( mpi_copy( &dst->Q, &src->Q ) ); + MPI_CHK( mpi_copy( &dst->DP, &src->DP ) ); + MPI_CHK( mpi_copy( &dst->DQ, &src->DQ ) ); + MPI_CHK( mpi_copy( &dst->QP, &src->QP ) ); + + MPI_CHK( mpi_copy( &dst->RN, &src->RN ) ); + MPI_CHK( mpi_copy( &dst->RP, &src->RP ) ); + MPI_CHK( mpi_copy( &dst->RQ, &src->RQ ) ); + +#if !defined(POLARSSL_RSA_NO_CRT) + MPI_CHK( mpi_copy( &dst->Vi, &src->Vi ) ); + MPI_CHK( mpi_copy( &dst->Vf, &src->Vf ) ); +#endif + + dst->padding = src->padding; + dst->hash_id = src->hash_id; + +cleanup: + if( ret != 0 ) + rsa_free( dst ); + + return( ret ); +} + +/* + * Free the components of an RSA key + */ +void rsa_free( rsa_context *ctx ) +{ +#if !defined(POLARSSL_RSA_NO_CRT) + mpi_free( &ctx->Vi ); mpi_free( &ctx->Vf ); +#endif + mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN ); + mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP ); + mpi_free( &ctx->Q ); mpi_free( &ctx->P ); mpi_free( &ctx->D ); + mpi_free( &ctx->E ); mpi_free( &ctx->N ); + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &ctx->mutex ); +#endif +} + +#if defined(POLARSSL_SELF_TEST) + +#include "polarssl/sha1.h" + +/* + * Example RSA-1024 keypair, for test purposes + */ +#define KEY_LEN 128 + +#define RSA_N "9292758453063D803DD603D5E777D788" \ + "8ED1D5BF35786190FA2F23EBC0848AEA" \ + "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ + "7130B9CED7ACDF54CFC7555AC14EEBAB" \ + "93A89813FBF3C4F8066D2D800F7C38A8" \ + "1AE31942917403FF4946B0A83D3D3E05" \ + "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ + "5E94BB77B07507233A0BC7BAC8F90F79" + +#define RSA_E "10001" + +#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ + "66CA472BC44D253102F8B4A9D3BFA750" \ + "91386C0077937FE33FA3252D28855837" \ + "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ + "DF79C5CE07EE72C7F123142198164234" \ + "CABB724CF78B8173B9F880FC86322407" \ + "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ + "071513A1E85B5DFA031F21ECAE91A34D" + +#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ + "2C01CAD19EA484A87EA4377637E75500" \ + "FCB2005C5C7DD6EC4AC023CDA285D796" \ + "C3D9E75E1EFC42488BB4F1D13AC30A57" + +#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ + "E211C2B9E5DB1ED0BF61D0D9899620F4" \ + "910E4168387E3C30AA1E00C339A79508" \ + "8452DD96A9A5EA5D9DCA68DA636032AF" + +#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \ + "3C94D22288ACD763FD8E5600ED4A702D" \ + "F84198A5F06C2E72236AE490C93F07F8" \ + "3CC559CD27BC2D1CA488811730BB5725" + +#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \ + "D8AAEA56749EA28623272E4F7D0592AF" \ + "7C1F1313CAC9471B5C523BFE592F517B" \ + "407A1BD76C164B93DA2D32A383E58357" + +#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \ + "F38D18D2B2F0E2DD275AA977E2BF4411" \ + "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ + "A74206CEC169D74BF5A8C50D6F48EA08" + +#define PT_LEN 24 +#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ + "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" + +#if defined(POLARSSL_PKCS1_V15) +static int myrand( void *rng_state, unsigned char *output, size_t len ) +{ +#if !defined(__OpenBSD__) + size_t i; + + if( rng_state != NULL ) + rng_state = NULL; + + for( i = 0; i < len; ++i ) + output[i] = rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Checkup routine + */ +int rsa_self_test( int verbose ) +{ + int ret = 0; +#if defined(POLARSSL_PKCS1_V15) + size_t len; + rsa_context rsa; + unsigned char rsa_plaintext[PT_LEN]; + unsigned char rsa_decrypted[PT_LEN]; + unsigned char rsa_ciphertext[KEY_LEN]; +#if defined(POLARSSL_SHA1_C) + unsigned char sha1sum[20]; +#endif + + rsa_init( &rsa, RSA_PKCS_V15, 0 ); + + rsa.len = KEY_LEN; + MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); + MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); + MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); + MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); + MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); + MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); + MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); + MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); + + if( verbose != 0 ) + polarssl_printf( " RSA key validation: " ); + + if( rsa_check_pubkey( &rsa ) != 0 || + rsa_check_privkey( &rsa ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 encryption : " ); + + memcpy( rsa_plaintext, RSA_PT, PT_LEN ); + + if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN, + rsa_plaintext, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 decryption : " ); + + if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, + rsa_ciphertext, rsa_decrypted, + sizeof(rsa_decrypted) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + +#if defined(POLARSSL_SHA1_C) + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 data sign : " ); + + sha1( rsa_plaintext, PT_LEN, sha1sum ); + + if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 sig. verify: " ); + + if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); +#endif /* POLARSSL_SHA1_C */ + +cleanup: + rsa_free( &rsa ); +#else /* POLARSSL_PKCS1_V15 */ + ((void) verbose); +#endif /* POLARSSL_PKCS1_V15 */ + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_RSA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha1.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha1.c new file mode 100644 index 0000000..20408c7 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha1.c @@ -0,0 +1,661 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA1_C) + +#include "polarssl/sha1.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA1_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void sha1_init( sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( sha1_context ) ); +} + +void sha1_free( sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha1_context ) ); +} + +/* + * SHA-1 context setup + */ +void sha1_starts( sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +void sha1_process( sha1_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp, W[16], A, B, C, D, E; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} + +/* + * SHA-1 process buffer + */ +void sha1_update( sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void sha1_finish( sha1_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha1_update( ctx, sha1_padding, padn ); + sha1_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); +} + +#endif /* !POLARSSL_SHA1_ALT */ + +/* + * output = SHA-1( input buffer ) + */ +void sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_starts( &ctx ); + sha1_update( &ctx, input, ilen ); + sha1_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-1( file contents ) + */ +int sha1_file( const char *path, unsigned char output[20] ) +{ + FILE *f; + size_t n; + sha1_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + + sha1_init( &ctx ); + sha1_starts( &ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha1_update( &ctx, buf, n ); + + sha1_finish( &ctx, output ); + sha1_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA1_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-1 HMAC context setup + */ +void sha1_hmac_starts( sha1_context *ctx, const unsigned char *key, + size_t keylen ) +{ + size_t i; + unsigned char sum[20]; + + if( keylen > 64 ) + { + sha1( key, keylen, sum ); + keylen = 20; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-1 HMAC process buffer + */ +void sha1_hmac_update( sha1_context *ctx, const unsigned char *input, + size_t ilen ) +{ + sha1_update( ctx, input, ilen ); +} + +/* + * SHA-1 HMAC final digest + */ +void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] ) +{ + unsigned char tmpbuf[20]; + + sha1_finish( ctx, tmpbuf ); + sha1_starts( ctx ); + sha1_update( ctx, ctx->opad, 64 ); + sha1_update( ctx, tmpbuf, 20 ); + sha1_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA1 HMAC context reset + */ +void sha1_hmac_reset( sha1_context *ctx ) +{ + sha1_starts( ctx ); + sha1_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-SHA-1( hmac key, input buffer ) + */ +void sha1_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + sha1_context ctx; + + sha1_init( &ctx ); + sha1_hmac_starts( &ctx, key, keylen ); + sha1_hmac_update( &ctx, input, ilen ); + sha1_hmac_finish( &ctx, output ); + sha1_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + sha1_init( &ctx ); + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha1_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA1_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha256.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha256.c new file mode 100644 index 0000000..4fc6698 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha256.c @@ -0,0 +1,742 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-256 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA256_C) + +#include "polarssl/sha256.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA256_ALT) + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void sha256_init( sha256_context *ctx ) +{ + memset( ctx, 0, sizeof( sha256_context ) ); +} + +void sha256_free( sha256_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha256_context ) ); +} + +/* + * SHA-256 context setup + */ +void sha256_starts( sha256_context *ctx, int is224 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is224 == 0 ) + { + /* SHA-256 */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + } + + ctx->is224 = is224; +} + +void sha256_process( sha256_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A, B, C, D, E, F, G, H; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); + P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); + P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); + P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); + P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); + P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); + P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); + P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); + P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); + P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); + P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); + P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); + P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); + P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); + P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); + P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); + P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); + P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); + P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); + P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); + P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); + P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); + P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); + P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); + P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); + P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); + P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); + P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); + P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); + P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); + P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); + P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); + P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); + P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); + P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); + P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); + P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); + P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); + P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); + P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); + P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); + P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); + P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); + P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); + P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); + P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); + P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); + P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); + P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); + P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); + P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); + P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); + P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); + P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); + P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); + P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); + P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); + P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); + P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); + P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); + P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); + P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); + P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); + P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/* + * SHA-256 process buffer + */ +void sha256_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha256_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha256_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-256 final digest + */ +void sha256_finish( sha256_context *ctx, unsigned char output[32] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha256_update( ctx, sha256_padding, padn ); + sha256_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); + + if( ctx->is224 == 0 ) + PUT_UINT32_BE( ctx->state[7], output, 28 ); +} + +#endif /* !POLARSSL_SHA256_ALT */ + +/* + * output = SHA-256( input buffer ) + */ +void sha256( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + sha256_context ctx; + + sha256_init( &ctx ); + sha256_starts( &ctx, is224 ); + sha256_update( &ctx, input, ilen ); + sha256_finish( &ctx, output ); + sha256_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-256( file contents ) + */ +int sha256_file( const char *path, unsigned char output[32], int is224 ) +{ + FILE *f; + size_t n; + sha256_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); + + sha256_init( &ctx ); + sha256_starts( &ctx, is224 ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha256_update( &ctx, buf, n ); + + sha256_finish( &ctx, output ); + sha256_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA256_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-256 HMAC context setup + */ +void sha256_hmac_starts( sha256_context *ctx, const unsigned char *key, + size_t keylen, int is224 ) +{ + size_t i; + unsigned char sum[32]; + + if( keylen > 64 ) + { + sha256( key, keylen, sum, is224 ); + keylen = ( is224 ) ? 28 : 32; + key = sum; + } + + memset( ctx->ipad, 0x36, 64 ); + memset( ctx->opad, 0x5C, 64 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha256_starts( ctx, is224 ); + sha256_update( ctx, ctx->ipad, 64 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-256 HMAC process buffer + */ +void sha256_hmac_update( sha256_context *ctx, const unsigned char *input, + size_t ilen ) +{ + sha256_update( ctx, input, ilen ); +} + +/* + * SHA-256 HMAC final digest + */ +void sha256_hmac_finish( sha256_context *ctx, unsigned char output[32] ) +{ + int is224, hlen; + unsigned char tmpbuf[32]; + + is224 = ctx->is224; + hlen = ( is224 == 0 ) ? 32 : 28; + + sha256_finish( ctx, tmpbuf ); + sha256_starts( ctx, is224 ); + sha256_update( ctx, ctx->opad, 64 ); + sha256_update( ctx, tmpbuf, hlen ); + sha256_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA-256 HMAC context reset + */ +void sha256_hmac_reset( sha256_context *ctx ) +{ + sha256_starts( ctx, ctx->is224 ); + sha256_update( ctx, ctx->ipad, 64 ); +} + +/* + * output = HMAC-SHA-256( hmac key, input buffer ) + */ +void sha256_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + sha256_context ctx; + + sha256_init( &ctx ); + sha256_hmac_starts( &ctx, key, keylen, is224 ); + sha256_hmac_update( &ctx, input, ilen ); + sha256_hmac_finish( &ctx, output ); + sha256_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha256_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha256_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha256_test_sum[6][32] = +{ + /* + * SHA-224 test vectors + */ + { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, + 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, + 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, + 0xE3, 0x6C, 0x9D, 0xA7 }, + { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, + 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, + 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, + 0x52, 0x52, 0x25, 0x25 }, + { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, + 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, + 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, + 0x4E, 0xE7, 0xAD, 0x67 }, + + /* + * SHA-256 test vectors + */ + { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, + { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, + { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha256_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha256_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha256_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha256_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha256_hmac_test_sum[14][32] = +{ + /* + * HMAC-SHA-224 test vectors + */ + { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19, + 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F, + 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F, + 0x53, 0x68, 0x4B, 0x22 }, + { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF, + 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F, + 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00, + 0x8F, 0xD0, 0x5E, 0x44 }, + { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6, + 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64, + 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1, + 0xEC, 0x83, 0x33, 0xEA }, + { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC, + 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C, + 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D, + 0xE7, 0xAF, 0xEC, 0x5A }, + { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37, + 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 }, + { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD, + 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2, + 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27, + 0x3F, 0xA6, 0x87, 0x0E }, + { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02, + 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD, + 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9, + 0xF6, 0xF5, 0x65, 0xD1 }, + + /* + * HMAC-SHA-256 test vectors + */ + { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53, + 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B, + 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7, + 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 }, + { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E, + 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7, + 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83, + 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 }, + { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46, + 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7, + 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22, + 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE }, + { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E, + 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A, + 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07, + 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B }, + { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0, + 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B }, + { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F, + 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F, + 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14, + 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 }, + { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB, + 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44, + 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93, + 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 } +}; + +/* + * Checkup routine + */ +int sha256_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha256sum[32]; + sha256_context ctx; + + sha256_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + sha256_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha256_update( &ctx, buf, buflen ); + } + else + sha256_update( &ctx, sha256_test_buf[j], + sha256_test_buflen[j] ); + + sha256_finish( &ctx, sha256sum ); + + if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha256_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha256_hmac_starts( &ctx, sha256_hmac_test_key[j], + sha256_hmac_test_keylen[j], k ); + + sha256_hmac_update( &ctx, sha256_hmac_test_buf[j], + sha256_hmac_test_buflen[j] ); + + sha256_hmac_finish( &ctx, sha256sum ); + + buflen = ( j == 4 ) ? 16 : 32 - k * 4; + + if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha256_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA256_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha512.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha512.c new file mode 100644 index 0000000..f1d1525 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/sha512.c @@ -0,0 +1,796 @@ +/* + * FIPS-180-2 compliant SHA-384/512 implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SHA-512 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SHA512_C) + +#include "polarssl/sha512.h" + +#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST) +#include +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if !defined(POLARSSL_SHA512_ALT) + +/* + * 64-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#ifndef PUT_UINT64_BE +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} +#endif /* PUT_UINT64_BE */ + +/* + * Round constants + */ +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + +void sha512_init( sha512_context *ctx ) +{ + memset( ctx, 0, sizeof( sha512_context ) ); +} + +void sha512_free( sha512_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( sha512_context ) ); +} + +/* + * SHA-512 context setup + */ +void sha512_starts( sha512_context *ctx, int is384 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is384 == 0 ) + { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } + else + { + /* SHA-384 */ + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } + + ctx->is384 = is384; +} + +void sha512_process( sha512_context *ctx, const unsigned char data[128] ) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A, B, C, D, E, F, G, H; + +#define SHR(x,n) (x >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + for( i = 0; i < 16; i++ ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + + for( ; i < 80; i++ ) + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[i - 16]; + } + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + i = 0; + + do + { + P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; + P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; + P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; + P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; + P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; + P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; + P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; + P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; + } + while( i < 80 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/* + * SHA-512 process buffer + */ +void sha512_update( sha512_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + unsigned int left; + + if( ilen == 0 ) + return; + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if( ctx->total[0] < (uint64_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + sha512_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 128 ) + { + sha512_process( ctx, input ); + input += 128; + ilen -= 128; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha512_padding[128] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-512 final digest + */ +void sha512_finish( sha512_context *ctx, unsigned char output[64] ) +{ + size_t last, padn; + uint64_t high, low; + unsigned char msglen[16]; + + high = ( ctx->total[0] >> 61 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT64_BE( high, msglen, 0 ); + PUT_UINT64_BE( low, msglen, 8 ); + + last = (size_t)( ctx->total[0] & 0x7F ); + padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + + sha512_update( ctx, sha512_padding, padn ); + sha512_update( ctx, msglen, 16 ); + + PUT_UINT64_BE( ctx->state[0], output, 0 ); + PUT_UINT64_BE( ctx->state[1], output, 8 ); + PUT_UINT64_BE( ctx->state[2], output, 16 ); + PUT_UINT64_BE( ctx->state[3], output, 24 ); + PUT_UINT64_BE( ctx->state[4], output, 32 ); + PUT_UINT64_BE( ctx->state[5], output, 40 ); + + if( ctx->is384 == 0 ) + { + PUT_UINT64_BE( ctx->state[6], output, 48 ); + PUT_UINT64_BE( ctx->state[7], output, 56 ); + } +} + +#endif /* !POLARSSL_SHA512_ALT */ + +/* + * output = SHA-512( input buffer ) + */ +void sha512( const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) +{ + sha512_context ctx; + + sha512_init( &ctx ); + sha512_starts( &ctx, is384 ); + sha512_update( &ctx, input, ilen ); + sha512_finish( &ctx, output ); + sha512_free( &ctx ); +} + +#if defined(POLARSSL_FS_IO) +/* + * output = SHA-512( file contents ) + */ +int sha512_file( const char *path, unsigned char output[64], int is384 ) +{ + FILE *f; + size_t n; + sha512_context ctx; + unsigned char buf[1024]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); + + sha512_init( &ctx ); + sha512_starts( &ctx, is384 ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha512_update( &ctx, buf, n ); + + sha512_finish( &ctx, output ); + sha512_free( &ctx ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( POLARSSL_ERR_SHA512_FILE_IO_ERROR ); + } + + fclose( f ); + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +/* + * SHA-512 HMAC context setup + */ +void sha512_hmac_starts( sha512_context *ctx, const unsigned char *key, + size_t keylen, int is384 ) +{ + size_t i; + unsigned char sum[64]; + + if( keylen > 128 ) + { + sha512( key, keylen, sum, is384 ); + keylen = ( is384 ) ? 48 : 64; + key = sum; + } + + memset( ctx->ipad, 0x36, 128 ); + memset( ctx->opad, 0x5C, 128 ); + + for( i = 0; i < keylen; i++ ) + { + ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] ); + ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] ); + } + + sha512_starts( ctx, is384 ); + sha512_update( ctx, ctx->ipad, 128 ); + + polarssl_zeroize( sum, sizeof( sum ) ); +} + +/* + * SHA-512 HMAC process buffer + */ +void sha512_hmac_update( sha512_context *ctx, + const unsigned char *input, size_t ilen ) +{ + sha512_update( ctx, input, ilen ); +} + +/* + * SHA-512 HMAC final digest + */ +void sha512_hmac_finish( sha512_context *ctx, unsigned char output[64] ) +{ + int is384, hlen; + unsigned char tmpbuf[64]; + + is384 = ctx->is384; + hlen = ( is384 == 0 ) ? 64 : 48; + + sha512_finish( ctx, tmpbuf ); + sha512_starts( ctx, is384 ); + sha512_update( ctx, ctx->opad, 128 ); + sha512_update( ctx, tmpbuf, hlen ); + sha512_finish( ctx, output ); + + polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) ); +} + +/* + * SHA-512 HMAC context reset + */ +void sha512_hmac_reset( sha512_context *ctx ) +{ + sha512_starts( ctx, ctx->is384 ); + sha512_update( ctx, ctx->ipad, 128 ); +} + +/* + * output = HMAC-SHA-512( hmac key, input buffer ) + */ +void sha512_hmac( const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) +{ + sha512_context ctx; + + sha512_init( &ctx ); + sha512_hmac_starts( &ctx, key, keylen, is384 ); + sha512_hmac_update( &ctx, input, ilen ); + sha512_hmac_finish( &ctx, output ); + sha512_free( &ctx ); +} + +#if defined(POLARSSL_SELF_TEST) + +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha512_test_buf[3][113] = +{ + { "abc" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "" } +}; + +static const int sha512_test_buflen[3] = +{ + 3, 112, 1000 +}; + +static const unsigned char sha512_test_sum[6][64] = +{ + /* + * SHA-384 test vectors + */ + { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, + 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, + 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, + 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, + 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, + 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, + { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, + 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, + 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, + 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, + 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, + 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, + { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, + 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, + 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, + 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, + 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, + 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, + + /* + * SHA-512 test vectors + */ + { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, + 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, + 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, + 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, + 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, + 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, + 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, + 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, + { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, + { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, + 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, + 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, + 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, + 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, + 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, + 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha512_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha512_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha512_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha512_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha512_hmac_test_sum[14][64] = +{ + /* + * HMAC-SHA-384 test vectors + */ + { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62, + 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F, + 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6, + 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C, + 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F, + 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 }, + { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31, + 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B, + 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47, + 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E, + 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7, + 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 }, + { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A, + 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F, + 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB, + 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B, + 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9, + 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 }, + { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85, + 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7, + 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C, + 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E, + 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79, + 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB }, + { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23, + 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 }, + { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90, + 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4, + 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F, + 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6, + 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82, + 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 }, + { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D, + 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C, + 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A, + 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5, + 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D, + 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E }, + + /* + * HMAC-SHA-512 test vectors + */ + { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D, + 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0, + 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78, + 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE, + 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02, + 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4, + 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70, + 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 }, + { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2, + 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3, + 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6, + 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54, + 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A, + 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD, + 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B, + 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 }, + { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84, + 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9, + 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36, + 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39, + 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8, + 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07, + 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26, + 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB }, + { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69, + 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7, + 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D, + 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB, + 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4, + 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63, + 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D, + 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD }, + { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53, + 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 }, + { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB, + 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4, + 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1, + 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52, + 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98, + 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52, + 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC, + 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 }, + { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA, + 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD, + 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86, + 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44, + 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1, + 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15, + 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60, + 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 } +}; + +/* + * Checkup routine + */ +int sha512_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha512sum[64]; + sha512_context ctx; + + sha512_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + sha512_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha512_update( &ctx, buf, buflen ); + } + else + sha512_update( &ctx, sha512_test_buf[j], + sha512_test_buflen[j] ); + + sha512_finish( &ctx, sha512sum ); + + if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha512_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha512_hmac_starts( &ctx, sha512_hmac_test_key[j], + sha512_hmac_test_keylen[j], k ); + + sha512_hmac_update( &ctx, sha512_hmac_test_buf[j], + sha512_hmac_test_buflen[j] ); + + sha512_hmac_finish( &ctx, sha512sum ); + + buflen = ( j == 4 ) ? 16 : 64 - k * 16; + + if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha512_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_SHA512_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cache.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cache.c new file mode 100644 index 0000000..836b685 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cache.c @@ -0,0 +1,335 @@ +/* + * SSL session cache implementation + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_CACHE_C) + +#include "polarssl/ssl_cache.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +void ssl_cache_init( ssl_cache_context *cache ) +{ + memset( cache, 0, sizeof( ssl_cache_context ) ); + + cache->timeout = SSL_CACHE_DEFAULT_TIMEOUT; + cache->max_entries = SSL_CACHE_DEFAULT_MAX_ENTRIES; + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_init( &cache->mutex ); +#endif +} + +int ssl_cache_get( void *data, ssl_session *session ) +{ + int ret = 1; +#if defined(POLARSSL_HAVE_TIME) + time_t t = time( NULL ); +#endif + ssl_cache_context *cache = (ssl_cache_context *) data; + ssl_cache_entry *cur, *entry; + +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_lock( &cache->mutex ) != 0 ) + return( 1 ); +#endif + + cur = cache->chain; + entry = NULL; + + while( cur != NULL ) + { + entry = cur; + cur = cur->next; + +#if defined(POLARSSL_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - entry->timestamp ) > cache->timeout ) + continue; +#endif + + if( session->ciphersuite != entry->session.ciphersuite || + session->compression != entry->session.compression || + session->length != entry->session.length ) + continue; + + if( memcmp( session->id, entry->session.id, + entry->session.length ) != 0 ) + continue; + + memcpy( session->master, entry->session.master, 48 ); + + session->verify_result = entry->session.verify_result; + +#if defined(POLARSSL_X509_CRT_PARSE_C) + /* + * Restore peer certificate (without rest of the original chain) + */ + if( entry->peer_cert.p != NULL ) + { + session->peer_cert = + (x509_crt *) polarssl_malloc( sizeof(x509_crt) ); + + if( session->peer_cert == NULL ) + { + ret = 1; + goto exit; + } + + x509_crt_init( session->peer_cert ); + if( x509_crt_parse( session->peer_cert, entry->peer_cert.p, + entry->peer_cert.len ) != 0 ) + { + polarssl_free( session->peer_cert ); + session->peer_cert = NULL; + ret = 1; + goto exit; + } + } +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + ret = 0; + goto exit; + } + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +int ssl_cache_set( void *data, const ssl_session *session ) +{ + int ret = 1; +#if defined(POLARSSL_HAVE_TIME) + time_t t = time( NULL ), oldest = 0; + ssl_cache_entry *old = NULL; +#endif + ssl_cache_context *cache = (ssl_cache_context *) data; + ssl_cache_entry *cur, *prv; + int count = 0; + +#if defined(POLARSSL_THREADING_C) + if( ( ret = polarssl_mutex_lock( &cache->mutex ) ) != 0 ) + return( ret ); +#endif + + cur = cache->chain; + prv = NULL; + + while( cur != NULL ) + { + count++; + +#if defined(POLARSSL_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - cur->timestamp ) > cache->timeout ) + { + cur->timestamp = t; + break; /* expired, reuse this slot, update timestamp */ + } +#endif + + if( memcmp( session->id, cur->session.id, cur->session.length ) == 0 ) + break; /* client reconnected, keep timestamp for session id */ + +#if defined(POLARSSL_HAVE_TIME) + if( oldest == 0 || cur->timestamp < oldest ) + { + oldest = cur->timestamp; + old = cur; + } +#endif + + prv = cur; + cur = cur->next; + } + + if( cur == NULL ) + { +#if defined(POLARSSL_HAVE_TIME) + /* + * Reuse oldest entry if max_entries reached + */ + if( count >= cache->max_entries ) + { + if( old == NULL ) + { + ret = 1; + goto exit; + } + + cur = old; + } +#else /* POLARSSL_HAVE_TIME */ + /* + * Reuse first entry in chain if max_entries reached, + * but move to last place + */ + if( count >= cache->max_entries ) + { + if( cache->chain == NULL ) + { + ret = 1; + goto exit; + } + + cur = cache->chain; + cache->chain = cur->next; + cur->next = NULL; + prv->next = cur; + } +#endif /* POLARSSL_HAVE_TIME */ + else + { + /* + * max_entries not reached, create new entry + */ + cur = (ssl_cache_entry *) + polarssl_malloc( sizeof(ssl_cache_entry) ); + if( cur == NULL ) + { + ret = 1; + goto exit; + } + + memset( cur, 0, sizeof(ssl_cache_entry) ); + + if( prv == NULL ) + cache->chain = cur; + else + prv->next = cur; + } + +#if defined(POLARSSL_HAVE_TIME) + cur->timestamp = t; +#endif + } + + memcpy( &cur->session, session, sizeof( ssl_session ) ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + /* + * If we're reusing an entry, free its certificate first + */ + if( cur->peer_cert.p != NULL ) + { + polarssl_free( cur->peer_cert.p ); + memset( &cur->peer_cert, 0, sizeof(x509_buf) ); + } + + /* + * Store peer certificate + */ + if( session->peer_cert != NULL ) + { + cur->peer_cert.p = (unsigned char *) + polarssl_malloc( session->peer_cert->raw.len ); + if( cur->peer_cert.p == NULL ) + { + ret = 1; + goto exit; + } + + memcpy( cur->peer_cert.p, session->peer_cert->raw.p, + session->peer_cert->raw.len ); + cur->peer_cert.len = session->peer_cert->raw.len; + + cur->session.peer_cert = NULL; + } +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + ret = 0; + +exit: +#if defined(POLARSSL_THREADING_C) + if( polarssl_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +#if defined(POLARSSL_HAVE_TIME) +void ssl_cache_set_timeout( ssl_cache_context *cache, int timeout ) +{ + if( timeout < 0 ) timeout = 0; + + cache->timeout = timeout; +} +#endif /* POLARSSL_HAVE_TIME */ + +void ssl_cache_set_max_entries( ssl_cache_context *cache, int max ) +{ + if( max < 0 ) max = 0; + + cache->max_entries = max; +} + +void ssl_cache_free( ssl_cache_context *cache ) +{ + ssl_cache_entry *cur, *prv; + + cur = cache->chain; + + while( cur != NULL ) + { + prv = cur; + cur = cur->next; + + ssl_session_free( &prv->session ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + polarssl_free( prv->peer_cert.p ); +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + polarssl_free( prv ); + } + +#if defined(POLARSSL_THREADING_C) + polarssl_mutex_free( &cache->mutex ); +#endif +} + +#endif /* POLARSSL_SSL_CACHE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_ciphersuites.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_ciphersuites.c new file mode 100644 index 0000000..df838e2 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_ciphersuites.c @@ -0,0 +1,1843 @@ +/** + * \file ssl_ciphersuites.c + * + * \brief SSL ciphersuites for PolarSSL + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_TLS_C) + +#include "polarssl/ssl_ciphersuites.h" +#include "polarssl/ssl.h" + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +/* + * Ordered from most preferred to least preferred in terms of security. + * + * Current rule (except rc4, weak and null which come last): + * 1. By key exchange: + * Forward-secure non-PSK > forward-secure PSK > other non-PSK > other PSK + * 2. By key length and cipher: + * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES + * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 + * 4. By hash function used when relevant + * 5. By key exchange/auth again: EC > non-EC + */ +static const int ciphersuite_preference[] = +{ +#if defined(SSL_CIPHERSUITES) + SSL_CIPHERSUITES, +#else + /* All AES-256 ephemeral suites */ + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + TLS_DHE_RSA_WITH_AES_256_CCM_8, + + /* All CAMELLIA-256 ephemeral suites */ + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + + /* All AES-128 ephemeral suites */ + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_128_CCM, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + TLS_DHE_RSA_WITH_AES_128_CCM_8, + + /* All CAMELLIA-128 ephemeral suites */ + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + + /* All remaining >= 128-bit ephemeral suites */ + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + + /* The PSK ephemeral suites */ + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_256_CCM, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_PSK_WITH_AES_256_CCM_8, + + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_128_CCM, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_AES_128_CCM_8, + + TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + + /* All AES-256 suites */ + TLS_RSA_WITH_AES_256_GCM_SHA384, + TLS_RSA_WITH_AES_256_CCM, + TLS_RSA_WITH_AES_256_CBC_SHA256, + TLS_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_RSA_WITH_AES_256_CCM_8, + + /* All CAMELLIA-256 suites */ + TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + + /* All AES-128 suites */ + TLS_RSA_WITH_AES_128_GCM_SHA256, + TLS_RSA_WITH_AES_128_CCM, + TLS_RSA_WITH_AES_128_CBC_SHA256, + TLS_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_RSA_WITH_AES_128_CCM_8, + + /* All CAMELLIA-128 suites */ + TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + + /* All remaining >= 128-bit suites */ + TLS_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + + /* The RSA PSK suites */ + TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA, + TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, + TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, + + TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA, + TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, + TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, + + TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + + /* The PSK suites */ + TLS_PSK_WITH_AES_256_GCM_SHA384, + TLS_PSK_WITH_AES_256_CCM, + TLS_PSK_WITH_AES_256_CBC_SHA384, + TLS_PSK_WITH_AES_256_CBC_SHA, + TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, + TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_PSK_WITH_AES_256_CCM_8, + + TLS_PSK_WITH_AES_128_GCM_SHA256, + TLS_PSK_WITH_AES_128_CCM, + TLS_PSK_WITH_AES_128_CBC_SHA256, + TLS_PSK_WITH_AES_128_CBC_SHA, + TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, + TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_PSK_WITH_AES_128_CCM_8, + + TLS_PSK_WITH_3DES_EDE_CBC_SHA, + + /* RC4 suites */ + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDHE_PSK_WITH_RC4_128_SHA, + TLS_DHE_PSK_WITH_RC4_128_SHA, + TLS_RSA_WITH_RC4_128_SHA, + TLS_RSA_WITH_RC4_128_MD5, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_RSA_PSK_WITH_RC4_128_SHA, + TLS_PSK_WITH_RC4_128_SHA, + + /* Weak suites */ + TLS_DHE_RSA_WITH_DES_CBC_SHA, + TLS_RSA_WITH_DES_CBC_SHA, + + /* NULL suites */ + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_PSK_WITH_NULL_SHA384, + TLS_ECDHE_PSK_WITH_NULL_SHA256, + TLS_ECDHE_PSK_WITH_NULL_SHA, + TLS_DHE_PSK_WITH_NULL_SHA384, + TLS_DHE_PSK_WITH_NULL_SHA256, + TLS_DHE_PSK_WITH_NULL_SHA, + + TLS_RSA_WITH_NULL_SHA256, + TLS_RSA_WITH_NULL_SHA, + TLS_RSA_WITH_NULL_MD5, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_RSA_PSK_WITH_NULL_SHA384, + TLS_RSA_PSK_WITH_NULL_SHA256, + TLS_RSA_PSK_WITH_NULL_SHA, + TLS_PSK_WITH_NULL_SHA384, + TLS_PSK_WITH_NULL_SHA256, + TLS_PSK_WITH_NULL_SHA, + +#endif + 0 +}; + +static const ssl_ciphersuite_t ciphersuite_definitions[] = +{ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#if defined(POLARSSL_CCM_C) + { TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA512_C) && defined(POLARSSL_GCM_C) + { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C && POLARSSL_GCM_C */ + +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_GCM_C) + { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA512_C) && defined(POLARSSL_GCM_C) + { TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C && POLARSSL_GCM_C */ + +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_GCM_C) + { TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_CCM_C) + { TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_MD5_C) + { TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_MD5, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif + +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif +#endif /* POLARSSL_ARC4_C */ +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_SHA1_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) + { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_GCM_C) + { TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + { TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ + +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDH_ECDSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CCM_C) + { TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", + POLARSSL_CIPHER_AES_256_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, + { TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + { TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", + POLARSSL_CIPHER_AES_128_CCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_SHORT_TAG }, +#endif /* POLARSSL_CCM_C */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(POLARSSL_AES_C) + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(POLARSSL_AES_C) +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", + POLARSSL_CIPHER_AES_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", + POLARSSL_CIPHER_AES_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ + +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ + +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", + POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, + + { TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", + POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_AES_C */ + +#if defined(POLARSSL_CAMELLIA_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_CBC, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_CBC, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_GCM_C) +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", + POLARSSL_CIPHER_CAMELLIA_128_GCM, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) + { TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", + POLARSSL_CIPHER_CAMELLIA_256_GCM, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_GCM_C */ +#endif /* POLARSSL_CAMELLIA_C */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", + POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ + +#if defined(POLARSSL_ARC4_C) +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", + POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + 0 }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_ARC4_C */ +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) +#if defined(POLARSSL_CIPHER_NULL_CIPHER) +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) +#if defined(POLARSSL_MD5_C) + { TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", + POLARSSL_CIPHER_NULL, POLARSSL_MD_MD5, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ + +#if defined(POLARSSL_SHA256_C) + { TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA512_C) + { TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ + +#if defined(POLARSSL_SHA256_C) + { TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA512_C) + { TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_DHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ + +#if defined(POLARSSL_SHA256_C) + { TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA512_C) + { TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_ECDHE_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ + +#if defined(POLARSSL_SHA256_C) + { TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA256, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif + +#if defined(POLARSSL_SHA512_C) + { TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", + POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA384, POLARSSL_KEY_EXCHANGE_RSA_PSK, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ + +#if defined(POLARSSL_DES_C) +#if defined(POLARSSL_CIPHER_MODE_CBC) +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", + POLARSSL_CIPHER_DES_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) +#if defined(POLARSSL_SHA1_C) + { TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", + POLARSSL_CIPHER_DES_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0, + SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3, + POLARSSL_CIPHERSUITE_WEAK }, +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* POLARSSL_DES_C */ +#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */ + + { 0, "", 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +#if defined(SSL_CIPHERSUITES) +const int *ssl_list_ciphersuites( void ) +{ + return( ciphersuite_preference ); +} +#else +#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ + sizeof( ciphersuite_definitions[0] ) +static int supported_ciphersuites[MAX_CIPHERSUITES]; +static int supported_init = 0; + +const int *ssl_list_ciphersuites( void ) +{ + /* + * On initial call filter out all ciphersuites not supported by current + * build based on presence in the ciphersuite_definitions. + */ + if( supported_init == 0 ) + { + const int *p; + int *q; + + for( p = ciphersuite_preference, q = supported_ciphersuites; + *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; + p++ ) + { +#if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES) + const ssl_ciphersuite_t *cs_info; + if( ( cs_info = ssl_ciphersuite_from_id( *p ) ) != NULL && + cs_info->cipher != POLARSSL_CIPHER_ARC4_128 ) +#else + if( ssl_ciphersuite_from_id( *p ) != NULL ) +#endif + *(q++) = *p; + } + *q = 0; + + supported_init = 1; + } + + return( supported_ciphersuites ); +}; +#endif /* SSL_CIPHERSUITES */ + +const ssl_ciphersuite_t *ssl_ciphersuite_from_string( + const char *ciphersuite_name ) +{ + const ssl_ciphersuite_t *cur = ciphersuite_definitions; + + if( NULL == ciphersuite_name ) + return( NULL ); + + while( cur->id != 0 ) + { + if( 0 == strcasecmp( cur->name, ciphersuite_name ) ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const ssl_ciphersuite_t *ssl_ciphersuite_from_id( int ciphersuite ) +{ + const ssl_ciphersuite_t *cur = ciphersuite_definitions; + + while( cur->id != 0 ) + { + if( cur->id == ciphersuite ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const char *ssl_get_ciphersuite_name( const int ciphersuite_id ) +{ + const ssl_ciphersuite_t *cur; + + cur = ssl_ciphersuite_from_id( ciphersuite_id ); + + if( cur == NULL ) + return( "unknown" ); + + return( cur->name ); +} + +int ssl_get_ciphersuite_id( const char *ciphersuite_name ) +{ + const ssl_ciphersuite_t *cur; + + cur = ssl_ciphersuite_from_string( ciphersuite_name ); + + if( cur == NULL ) + return( 0 ); + + return( cur->id ); +} + +#if defined(POLARSSL_PK_C) +pk_type_t ssl_get_ciphersuite_sig_pk_alg( const ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case POLARSSL_KEY_EXCHANGE_RSA: + case POLARSSL_KEY_EXCHANGE_DHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: + case POLARSSL_KEY_EXCHANGE_RSA_PSK: + return( POLARSSL_PK_RSA ); + + case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: + return( POLARSSL_PK_ECDSA ); + + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: + return( POLARSSL_PK_ECKEY ); + + default: + return( POLARSSL_PK_NONE ); + } +} +#endif /* POLARSSL_PK_C */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) +int ssl_ciphersuite_uses_ec( const ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +int ssl_ciphersuite_uses_psk( const ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case POLARSSL_KEY_EXCHANGE_PSK: + case POLARSSL_KEY_EXCHANGE_RSA_PSK: + case POLARSSL_KEY_EXCHANGE_DHE_PSK: + case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#endif /* POLARSSL_SSL_TLS_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cli.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cli.c new file mode 100644 index 0000000..034f2bf --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_cli.c @@ -0,0 +1,2639 @@ +/* + * SSLv3/TLSv1 client-side functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_CLI_C) + +#include "polarssl/debug.h" +#include "polarssl/ssl.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include + +#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) +#include +typedef UINT32 uint32_t; +#else +#include +#endif + +#if defined(POLARSSL_HAVE_TIME) +#include +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) +static void ssl_write_hostname_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + *olen = 0; + + if( ssl->hostname == NULL ) + return; + + SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", + ssl->hostname ) ); + + /* + * struct { + * NameType name_type; + * select (name_type) { + * case host_name: HostName; + * } name; + * } ServerName; + * + * enum { + * host_name(0), (255) + * } NameType; + * + * opaque HostName<1..2^16-1>; + * + * struct { + * ServerName server_name_list<1..2^16-1> + * } ServerNameList; + */ + *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME ) & 0xFF ); + + *p++ = (unsigned char)( ( (ssl->hostname_len + 5) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (ssl->hostname_len + 5) ) & 0xFF ); + + *p++ = (unsigned char)( ( (ssl->hostname_len + 3) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (ssl->hostname_len + 3) ) & 0xFF ); + + *p++ = (unsigned char)( ( TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); + *p++ = (unsigned char)( ( ssl->hostname_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ssl->hostname_len ) & 0xFF ); + + memcpy( p, ssl->hostname, ssl->hostname_len ); + + *olen = ssl->hostname_len + 9; +} +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ + +static void ssl_write_renegotiation_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + *olen = 0; + + if( ssl->renegotiation != SSL_RENEGOTIATION ) + return; + + SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + + /* + * Secure renegotiation + */ + *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + + *p++ = 0x00; + *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; + *p++ = ssl->verify_data_len & 0xFF; + + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + + *olen = 5 + ssl->verify_data_len; +} + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +static void ssl_write_signature_algorithms_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + size_t sig_alg_len = 0; +#if defined(POLARSSL_RSA_C) || defined(POLARSSL_ECDSA_C) + unsigned char *sig_alg_list = buf + 6; +#endif + + *olen = 0; + + if( ssl->max_minor_ver != SSL_MINOR_VERSION_3 ) + return; + + SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); + + /* + * Prepare signature_algorithms extension (TLS 1.2) + */ +#if defined(POLARSSL_RSA_C) +#if defined(POLARSSL_SHA512_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA512; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA384; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; +#endif +#if defined(POLARSSL_SHA256_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA256; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA224; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; +#endif +#if defined(POLARSSL_SHA1_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA1; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; +#endif +#if defined(POLARSSL_MD5_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_MD5; + sig_alg_list[sig_alg_len++] = SSL_SIG_RSA; +#endif +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_ECDSA_C) +#if defined(POLARSSL_SHA512_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA512; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA384; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; +#endif +#if defined(POLARSSL_SHA256_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA256; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA224; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; +#endif +#if defined(POLARSSL_SHA1_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA1; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; +#endif +#if defined(POLARSSL_MD5_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_MD5; + sig_alg_list[sig_alg_len++] = SSL_SIG_ECDSA; +#endif +#endif /* POLARSSL_ECDSA_C */ + + /* + * enum { + * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), + * sha512(6), (255) + * } HashAlgorithm; + * + * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } + * SignatureAlgorithm; + * + * struct { + * HashAlgorithm hash; + * SignatureAlgorithm signature; + * } SignatureAndHashAlgorithm; + * + * SignatureAndHashAlgorithm + * supported_signature_algorithms<2..2^16-2>; + */ + *p++ = (unsigned char)( ( TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SIG_ALG ) & 0xFF ); + + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); + + *olen = 6 + sig_alg_len; +} +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) +static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + unsigned char *elliptic_curve_list = p + 6; + size_t elliptic_curve_len = 0; + const ecp_curve_info *info; +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *grp_id; +#else + ((void) ssl); +#endif + + *olen = 0; + + SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); + +#if defined(POLARSSL_SSL_SET_CURVES) + for( grp_id = ssl->curve_list; *grp_id != POLARSSL_ECP_DP_NONE; grp_id++ ) + { + info = ecp_curve_info_from_grp_id( *grp_id ); +#else + for( info = ecp_curve_list(); info->grp_id != POLARSSL_ECP_DP_NONE; info++ ) + { +#endif + + elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; + elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; + } + + if( elliptic_curve_len == 0 ) + return; + + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); + + *olen = 6 + elliptic_curve_len; +} + +static void ssl_write_supported_point_formats_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + ((void) ssl); + + *olen = 0; + + SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + + *p++ = 0x00; + *p++ = 2; + + *p++ = 1; + *p++ = POLARSSL_ECP_PF_UNCOMPRESSED; + + *olen = 6; +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +static void ssl_write_max_fragment_length_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ) { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + + *p++ = 0x00; + *p++ = 1; + + *p++ = ssl->mfl_code; + + *olen = 5; +} +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +static void ssl_write_truncated_hmac_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->trunc_hmac == SSL_TRUNC_HMAC_DISABLED ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static void ssl_write_session_ticket_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + size_t tlen = ssl->session_negotiate->ticket_len; + + if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET ) & 0xFF ); + + *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( tlen ) & 0xFF ); + + *olen = 4; + + if( ssl->session_negotiate->ticket == NULL || + ssl->session_negotiate->ticket_len == 0 ) + { + return; + } + + SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); + + memcpy( p, ssl->session_negotiate->ticket, tlen ); + + *olen += tlen; +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_SSL_ALPN) +static void ssl_write_alpn_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const char **cur; + + if( ssl->alpn_list == NULL ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Skip writing extension and list length for now */ + p += 4; + + for( cur = ssl->alpn_list; *cur != NULL; cur++ ) + { + *p = (unsigned char)( strlen( *cur ) & 0xFF ); + memcpy( p + 1, *cur, *p ); + p += 1 + *p; + } + + *olen = p - buf; + + /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); +} +#endif /* POLARSSL_SSL_ALPN */ + +static int ssl_write_client_hello( ssl_context *ssl ) +{ + int ret; + size_t i, n, olen, ext_len = 0; + unsigned char *buf; + unsigned char *p, *q; +#if defined(POLARSSL_HAVE_TIME) + time_t t; +#endif + const int *ciphersuites; + const ssl_ciphersuite_t *ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); + + if( ssl->f_rng == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( POLARSSL_ERR_SSL_NO_RNG ); + } + + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) + { + ssl->major_ver = ssl->min_major_ver; + ssl->minor_ver = ssl->min_minor_ver; + } + + if( ssl->max_major_ver == 0 && ssl->max_minor_ver == 0 ) + { + ssl->max_major_ver = SSL_MAX_MAJOR_VERSION; + ssl->max_minor_ver = SSL_MAX_MINOR_VERSION; + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 highest version supported + * 6 . 9 current UNIX time + * 10 . 37 random bytes + */ + buf = ssl->out_msg; + p = buf + 4; + + *p++ = (unsigned char) ssl->max_major_ver; + *p++ = (unsigned char) ssl->max_minor_ver; + + SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", + buf[4], buf[5] ) ); + +#if defined(POLARSSL_HAVE_TIME) + t = time( NULL ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); + + SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); +#else + if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 ) + return( ret ); + + p += 4; +#endif /* POLARSSL_HAVE_TIME */ + + if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 ) + return( ret ); + + p += 28; + + memcpy( ssl->handshake->randbytes, buf + 6, 32 ); + + SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 6, 32 ); + + /* + * 38 . 38 session id length + * 39 . 39+n session id + * 40+n . 41+n ciphersuitelist length + * 42+n . .. ciphersuitelist + * .. . .. compression methods length + * .. . .. compression methods + * .. . .. extensions length + * .. . .. extensions + */ + n = ssl->session_negotiate->length; + + if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE || n < 16 || n > 32 || + ssl->handshake->resume == 0 ) + { + n = 0; + } + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + /* + * RFC 5077 section 3.4: "When presenting a ticket, the client MAY + * generate and include a Session ID in the TLS ClientHello." + */ + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && + ssl->session_negotiate->ticket != NULL && + ssl->session_negotiate->ticket_len != 0 ) + { + ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, 32 ); + + if( ret != 0 ) + return( ret ); + + ssl->session_negotiate->length = n = 32; + } +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + + *p++ = (unsigned char) n; + + for( i = 0; i < n; i++ ) + *p++ = ssl->session_negotiate->id[i]; + + SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); + SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); + + ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + n = 0; + q = p; + + // Skip writing ciphersuite length for now + p += 2; + + /* + * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) + { + *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); + *p++ = (unsigned char)( SSL_EMPTY_RENEGOTIATION_INFO ); + n++; + } + + for( i = 0; ciphersuites[i] != 0; i++ ) + { + ciphersuite_info = ssl_ciphersuite_from_id( ciphersuites[i] ); + + if( ciphersuite_info == NULL ) + continue; + + if( ciphersuite_info->min_minor_ver > ssl->max_minor_ver || + ciphersuite_info->max_minor_ver < ssl->min_minor_ver ) + continue; + + SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %2d", + ciphersuites[i] ) ); + + n++; + *p++ = (unsigned char)( ciphersuites[i] >> 8 ); + *p++ = (unsigned char)( ciphersuites[i] ); + } + + *q++ = (unsigned char)( n >> 7 ); + *q++ = (unsigned char)( n << 1 ); + + SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) ); + + +#if defined(POLARSSL_ZLIB_SUPPORT) + SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); + SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", + SSL_COMPRESS_DEFLATE, SSL_COMPRESS_NULL ) ); + + *p++ = 2; + *p++ = SSL_COMPRESS_DEFLATE; + *p++ = SSL_COMPRESS_NULL; +#else + SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); + SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", SSL_COMPRESS_NULL ) ); + + *p++ = 1; + *p++ = SSL_COMPRESS_NULL; +#endif /* POLARSSL_ZLIB_SUPPORT */ + + // First write extensions, then the total length + // +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + + ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", + ext_len ) ); + + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } + + ssl->out_msglen = p - buf; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_CLIENT_HELLO; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); + + return( 0 ); +} + +static int ssl_parse_renegotiation_info( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) + { + if( len != 1 || buf[0] != 0x0 ) + { + SSL_DEBUG_MSG( 1, ( "non-zero length renegotiated connection field" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; + } + else + { + /* Check verify-data in constant-time. The length OTOH is no secret */ + if( len != 1 + ssl->verify_data_len * 2 || + buf[0] != ssl->verify_data_len * 2 || + safer_memcmp( buf + 1, + ssl->own_verify_data, ssl->verify_data_len ) != 0 || + safer_memcmp( buf + 1 + ssl->verify_data_len, + ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "non-matching renegotiated connection field" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + + return( 0 ); +} + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + /* + * server should use the extension only if we did, + * and if so the server's value should match ours (and len is always 1) + */ + if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE || + len != 1 || + buf[0] != ssl->mfl_code ) + { + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + return( 0 ); +} +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +static int ssl_parse_truncated_hmac_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->trunc_hmac == SSL_TRUNC_HMAC_DISABLED || + len != 0 ) + { + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; + + return( 0 ); +} +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static int ssl_parse_session_ticket_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED || + len != 0 ) + { + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->handshake->new_session_ticket = 1; + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) +static int ssl_parse_supported_point_formats_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size; + const unsigned char *p; + + list_size = buf[0]; + if( list_size + 1 != len ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + p = buf + 1; + while( list_size > 0 ) + { + if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED || + p[0] == POLARSSL_ECP_PF_COMPRESSED ) + { + ssl->handshake->ecdh_ctx.point_format = p[0]; + SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); + return( 0 ); + } + + list_size--; + p++; + } + + SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_ALPN) +static int ssl_parse_alpn_ext( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, name_len; + const char **p; + + /* If we didn't send it, the server shouldn't send it */ + if( ssl->alpn_list == NULL ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + * + * the "ProtocolNameList" MUST contain exactly one "ProtocolName" + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + name_len = buf[2]; + if( name_len != list_len - 1 ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* Check that the server chosen protocol was in our list and save it */ + for( p = ssl->alpn_list; *p != NULL; p++ ) + { + if( name_len == strlen( *p ) && + memcmp( buf + 3, *p, name_len ) == 0 ) + { + ssl->alpn_chosen = *p; + return( 0 ); + } + } + + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); +} +#endif /* POLARSSL_SSL_ALPN */ + +static int ssl_parse_server_hello( ssl_context *ssl ) +{ + int ret, i, comp; + size_t n; + size_t ext_len = 0; + unsigned char *buf, *ext; + int renegotiation_info_seen = 0; + int handshake_failure = 0; +#if defined(POLARSSL_DEBUG_C) + uint32_t t; +#endif + + SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 protocol version + * 6 . 9 UNIX time() + * 10 . 37 random bytes + */ + buf = ssl->in_msg; + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", + buf[4], buf[5] ) ); + + if( ssl->in_hslen < 42 || + buf[0] != SSL_HS_SERVER_HELLO || + buf[4] != SSL_MAJOR_VERSION_3 ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( buf[5] > ssl->max_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ssl->minor_ver = buf[5]; + + if( ssl->minor_ver < ssl->min_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "server only supports ssl smaller than minimum" + " [%d:%d] < [%d:%d]", ssl->major_ver, + ssl->minor_ver, buf[4], buf[5] ) ); + + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_PROTOCOL_VERSION ); + + return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + +#if defined(POLARSSL_DEBUG_C) + t = ( (uint32_t) buf[6] << 24 ) + | ( (uint32_t) buf[7] << 16 ) + | ( (uint32_t) buf[8] << 8 ) + | ( (uint32_t) buf[9] ); + SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); +#endif + + memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); + + n = buf[38]; + + SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); + + if( n > 32 ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + /* + * 38 . 38 session id length + * 39 . 38+n session id + * 39+n . 40+n chosen ciphersuite + * 41+n . 41+n chosen compression alg. + * 42+n . 43+n extensions length + * 44+n . 44+n+m extensions + */ + if( ssl->in_hslen > 42 + n ) + { + ext_len = ( ( buf[42 + n] << 8 ) + | ( buf[43 + n] ) ); + + if( ( ext_len > 0 && ext_len < 4 ) || + ssl->in_hslen != 44 + n + ext_len ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + + i = ( buf[39 + n] << 8 ) | buf[40 + n]; + comp = buf[41 + n]; + + /* + * Initialize update checksum functions + */ + ssl->transform_negotiate->ciphersuite_info = ssl_ciphersuite_from_id( i ); + + if( ssl->transform_negotiate->ciphersuite_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + + SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); + SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); + + /* + * Check if the session can be resumed + */ + if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE || + ssl->handshake->resume == 0 || n == 0 || + ssl->session_negotiate->ciphersuite != i || + ssl->session_negotiate->compression != comp || + ssl->session_negotiate->length != n || + memcmp( ssl->session_negotiate->id, buf + 39, n ) != 0 ) + { + ssl->state++; + ssl->handshake->resume = 0; +#if defined(POLARSSL_HAVE_TIME) + ssl->session_negotiate->start = time( NULL ); +#endif + ssl->session_negotiate->ciphersuite = i; + ssl->session_negotiate->compression = comp; + ssl->session_negotiate->length = n; + memcpy( ssl->session_negotiate->id, buf + 39, n ); + } + else + { + ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_derive_keys", ret ); + return( ret ); + } + } + + SSL_DEBUG_MSG( 3, ( "%s session has been resumed", + ssl->handshake->resume ? "a" : "no" ) ); + + SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %d", i ) ); + SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[41 + n] ) ); + + i = 0; + while( 1 ) + { + if( ssl->ciphersuite_list[ssl->minor_ver][i] == 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( ssl->ciphersuite_list[ssl->minor_ver][i++] == + ssl->session_negotiate->ciphersuite ) + { + break; + } + } + + if( comp != SSL_COMPRESS_NULL +#if defined(POLARSSL_ZLIB_SUPPORT) + && comp != SSL_COMPRESS_DEFLATE +#endif + ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + ssl->session_negotiate->compression = comp; + + ext = buf + 44 + n; + + SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); + + while( ext_len ) + { + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); + + if( ext_size + 4 > ext_len ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + switch( ext_id ) + { + case TLS_EXT_RENEGOTIATION_INFO: + SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); + renegotiation_info_seen = 1; + + if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, + ext_size ) ) != 0 ) + return( ret ); + + break; + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + case TLS_EXT_MAX_FRAGMENT_LENGTH: + SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); + + if( ( ret = ssl_parse_max_fragment_length_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + case TLS_EXT_TRUNCATED_HMAC: + SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); + + if( ( ret = ssl_parse_truncated_hmac_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + case TLS_EXT_SESSION_TICKET: + SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) ); + + if( ( ret = ssl_parse_session_ticket_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + case TLS_EXT_SUPPORTED_POINT_FORMATS: + SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); + + if( ( ret = ssl_parse_supported_point_formats_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_ALPN) + case TLS_EXT_ALPN: + SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + + break; +#endif /* POLARSSL_SSL_ALPN */ + + default: + SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + ext_id ) ); + } + + ext_len -= 4 + ext_size; + ext += 4 + ext_size; + + if( ext_len > 0 && ext_len < 4 ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + + /* + * Renegotiation security checks + */ + if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION && + renegotiation_info_seen == 0 ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION ) + { + SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + renegotiation_info_seen == 1 ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); + handshake_failure = 1; + } + + if( handshake_failure == 1 ) + { + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); + + return( 0 ); +} + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) +static int ssl_parse_server_dh_params( ssl_context *ssl, unsigned char **p, + unsigned char *end ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + + /* + * Ephemeral DH parameters: + * + * struct { + * opaque dh_p<1..2^16-1>; + * opaque dh_g<1..2^16-1>; + * opaque dh_Ys<1..2^16-1>; + * } ServerDHParams; + */ + if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 2, ( "dhm_read_params" ), ret ); + return( ret ); + } + + if( ssl->handshake->dhm_ctx.len < 64 || + ssl->handshake->dhm_ctx.len > 512 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); + SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); + SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_check_server_ecdh_params( const ssl_context *ssl ) +{ + const ecp_curve_info *curve_info; + + curve_info = ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id ); + if( curve_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); + +#if defined(POLARSSL_SSL_ECP_SET_CURVES) + if( ! ssl_curve_is_acceptable( ssl, ssl->handshake->ecdh_ctx.grp.id ) ) +#else + if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || + ssl->handshake->ecdh_ctx.grp.nbits > 521 ) +#endif + return( -1 ); + + SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +static int ssl_parse_server_ecdh_params( ssl_context *ssl, + unsigned char **p, + unsigned char *end ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + + /* + * Ephemeral ECDH parameters: + * + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ + if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx, + (const unsigned char **) p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ecdh_read_params" ), ret ); + return( ret ); + } + + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +static int ssl_parse_server_psk_hint( ssl_context *ssl, + unsigned char **p, + unsigned char *end ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + size_t len; + ((void) ssl); + + /* + * PSK parameters: + * + * opaque psk_identity_hint<0..2^16-1>; + */ + len = (*p)[0] << 8 | (*p)[1]; + *p += 2; + + if( (*p) + len > end ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + // TODO: Retrieve PSK identity hint and callback to app + // + *p += len; + ret = 0; + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) +/* + * Generate a pre-master secret and encrypt it with the server's RSA key + */ +static int ssl_write_encrypted_pms( ssl_context *ssl, + size_t offset, size_t *olen, + size_t pms_offset ) +{ + int ret; + size_t len_bytes = ssl->minor_ver == SSL_MINOR_VERSION_0 ? 0 : 2; + unsigned char *p = ssl->handshake->premaster + pms_offset; + + /* + * Generate (part of) the pre-master as + * struct { + * ProtocolVersion client_version; + * opaque random[46]; + * } PreMasterSecret; + */ + p[0] = (unsigned char) ssl->max_major_ver; + p[1] = (unsigned char) ssl->max_minor_ver; + + if( ( ret = ssl->f_rng( ssl->p_rng, p + 2, 46 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "f_rng", ret ); + return( ret ); + } + + ssl->handshake->pmslen = 48; + + /* + * Now write it out, encrypted + */ + if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, + POLARSSL_PK_RSA ) ) + { + SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = pk_encrypt( &ssl->session_negotiate->peer_cert->pk, + p, ssl->handshake->pmslen, + ssl->out_msg + offset + len_bytes, olen, + SSL_MAX_CONTENT_LEN - offset - len_bytes, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "rsa_pkcs1_encrypt", ret ); + return( ret ); + } + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( len_bytes == 2 ) + { + ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); + ssl->out_msg[offset+1] = (unsigned char)( *olen ); + *olen += 2; + } +#endif + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_signature_algorithm( ssl_context *ssl, + unsigned char **p, + unsigned char *end, + md_type_t *md_alg, + pk_type_t *pk_alg ) +{ + ((void) ssl); + *md_alg = POLARSSL_MD_NONE; + *pk_alg = POLARSSL_PK_NONE; + + /* Only in TLS 1.2 */ + if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) + { + return( 0 ); + } + + if( (*p) + 2 > end ) + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + + /* + * Get hash algorithm + */ + if( ( *md_alg = ssl_md_alg_from_hash( (*p)[0] ) ) == POLARSSL_MD_NONE ) + { + SSL_DEBUG_MSG( 2, ( "Server used unsupported " + "HashAlgorithm %d", *(p)[0] ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + /* + * Get signature algorithm + */ + if( ( *pk_alg = ssl_pk_alg_from_sig( (*p)[1] ) ) == POLARSSL_PK_NONE ) + { + SSL_DEBUG_MSG( 2, ( "server used unsupported " + "SignatureAlgorithm %d", (*p)[1] ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); + SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); + *p += 2; + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( ssl_context *ssl ) +{ + int ret; + const ecp_keypair *peer_key; + + if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, + POLARSSL_PK_ECKEY ) ) + { + SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + peer_key = pk_ec( ssl->session_negotiate->peer_cert->pk ); + + if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, + POLARSSL_ECDH_THEIRS ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret ); + return( ret ); + } + + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +static int ssl_parse_server_key_exchange( ssl_context *ssl ) +{ + int ret; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + unsigned char *p, *end; +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + size_t sig_len, params_len; + unsigned char hash[64]; + md_type_t md_alg = POLARSSL_MD_NONE; + size_t hashlen; + pk_type_t pk_alg = POLARSSL_PK_NONE; +#endif + + SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); + } + ((void) p); + ((void) end); +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); + } + ((void) p); + ((void) end); +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server + * doesn't use a psk_identity_hint + */ + if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE ) + { + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + { + ssl->record_read = 1; + goto exit; + } + + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + p = ssl->in_msg + 4; + end = ssl->in_msg + ssl->in_hslen; + SSL_DEBUG_BUF( 3, "server key exchange", p, ssl->in_hslen - 4 ); + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } /* FALLTROUGH */ +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + ; /* nothing more to do */ + else +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + { + if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + { + params_len = p - ( ssl->in_msg + 4 ); + + /* + * Handle the digitally-signed structure + */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + if( ssl_parse_signature_algorithm( ssl, &p, end, + &md_alg, &pk_alg ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + if( pk_alg != ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) + { + pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + + /* Default hash for ECDSA is SHA-1 */ + if( pk_alg == POLARSSL_PK_ECDSA && md_alg == POLARSSL_MD_NONE ) + md_alg = POLARSSL_MD_SHA1; + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * Read signature + */ + sig_len = ( p[0] << 8 ) | p[1]; + p += 2; + + if( end != p + sig_len ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + SSL_DEBUG_BUF( 3, "signature", p, sig_len ); + + /* + * Compute the hash that has been signed + */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( md_alg == POLARSSL_MD_NONE ) + { + md5_context md5; + sha1_context sha1; + + md5_init( &md5 ); + sha1_init( &sha1 ); + + hashlen = 36; + + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(ClientHello.random + ServerHello.random + * + ServerParams); + * sha_hash + * SHA(ClientHello.random + ServerHello.random + * + ServerParams); + */ + md5_starts( &md5 ); + md5_update( &md5, ssl->handshake->randbytes, 64 ); + md5_update( &md5, ssl->in_msg + 4, params_len ); + md5_finish( &md5, hash ); + + sha1_starts( &sha1 ); + sha1_update( &sha1, ssl->handshake->randbytes, 64 ); + sha1_update( &sha1, ssl->in_msg + 4, params_len ); + sha1_finish( &sha1, hash + 16 ); + + md5_free( &md5 ); + sha1_free( &sha1 ); + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( md_alg != POLARSSL_MD_NONE ) + { + md_context_t ctx; + + md_init( &ctx ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + + /* + * digitally-signed struct { + * opaque client_random[32]; + * opaque server_random[32]; + * ServerDHParams params; + * }; + */ + if( ( ret = md_init_ctx( &ctx, + md_info_from_type( md_alg ) ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "md_init_ctx", ret ); + return( ret ); + } + + md_starts( &ctx ); + md_update( &ctx, ssl->handshake->randbytes, 64 ); + md_update( &ctx, ssl->in_msg + 4, params_len ); + md_finish( &ctx, hash ); + md_free( &ctx ); + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( md_info_from_type( md_alg ) )->size ); + + /* + * Verify signature + */ + if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) + { + SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash, hashlen, p, sig_len ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "pk_verify", ret ); + return( ret ); + } + } +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +exit: + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); + + return( 0 ); +} + +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_certificate_request( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_parse_certificate_request( ssl_context *ssl ) +{ + int ret; + unsigned char *buf, *p; + size_t n = 0, m = 0; + size_t cert_type_len = 0, dn_len = 0; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 4 cert type count + * 5 .. m-1 cert types + * m .. m+1 sig alg length (TLS 1.2 only) + * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) + * n .. n+1 length of all DNs + * n+2 .. n+3 length of DN 1 + * n+4 .. ... Distinguished Name #1 + * ... .. ... length of DN 2, etc. + */ + if( ssl->record_read == 0 ) + { + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + ssl->record_read = 1; + } + + ssl->client_auth = 0; + ssl->state++; + + if( ssl->in_msg[0] == SSL_HS_CERTIFICATE_REQUEST ) + ssl->client_auth++; + + SSL_DEBUG_MSG( 3, ( "got %s certificate request", + ssl->client_auth ? "a" : "no" ) ); + + if( ssl->client_auth == 0 ) + goto exit; + + ssl->record_read = 0; + + // TODO: handshake_failure alert for an anonymous server to request + // client authentication + + buf = ssl->in_msg; + + // Retrieve cert types + // + cert_type_len = buf[4]; + n = cert_type_len; + + if( ssl->in_hslen < 6 + n ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + + p = buf + 5; + while( cert_type_len > 0 ) + { +#if defined(POLARSSL_RSA_C) + if( *p == SSL_CERT_TYPE_RSA_SIGN && + pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) ) + { + ssl->handshake->cert_type = SSL_CERT_TYPE_RSA_SIGN; + break; + } + else +#endif +#if defined(POLARSSL_ECDSA_C) + if( *p == SSL_CERT_TYPE_ECDSA_SIGN && + pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECDSA ) ) + { + ssl->handshake->cert_type = SSL_CERT_TYPE_ECDSA_SIGN; + break; + } + else +#endif + { + ; /* Unsupported cert type, ignore */ + } + + cert_type_len--; + p++; + } + +/* + Note by Owen: + Test with Hostapd internal TLS, find that it didn't put the SignatureAndHashAlgorithm field +*/ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + /* Ignored, see comments about hash in write_certificate_verify */ + // TODO: should check the signature part against our pk_key though + size_t sig_alg_len = ( ( buf[5 + n] << 8 ) + | ( buf[6 + n] ) ); + + p = buf + 7 + n; + m += 2; + n += sig_alg_len; + + if( ssl->in_hslen < 6 + n ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + /* Ignore certificate_authorities, we only have one cert anyway */ + // TODO: should not send cert if no CA matches + dn_len = ( ( buf[5 + m + n] << 8 ) + | ( buf[6 + m + n] ) ); + + n += dn_len; + if( ssl->in_hslen != 7 + m + n ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + +exit: + SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); + + return( 0 ); +} +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +static int ssl_parse_server_hello_done( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); + + if( ssl->record_read == 0 ) + { + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + } + ssl->record_read = 0; + + if( ssl->in_hslen != 4 || + ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE ) + { + SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); + } + + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); + + return( 0 ); +} + +static int ssl_write_client_key_exchange( ssl_context *ssl ) +{ + int ret; + size_t i, n; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ) + { + /* + * DHM key exchange -- send G^X mod P + */ + n = ssl->handshake->dhm_ctx.len; + + ssl->out_msg[4] = (unsigned char)( n >> 8 ); + ssl->out_msg[5] = (unsigned char)( n ); + i = 6; + + ret = dhm_make_public( &ssl->handshake->dhm_ctx, + (int) mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->f_rng, ssl->p_rng ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_make_public", ret ); + return( ret ); + } + + SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); + SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); + + ssl->handshake->pmslen = POLARSSL_PREMASTER_SIZE; + + if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + &ssl->handshake->pmslen, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); + return( ret ); + } + + SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + /* + * ECDH key exchange -- send client public value + */ + i = 4; + + ret = ecdh_make_public( &ssl->handshake->ecdh_ctx, + &n, + &ssl->out_msg[i], 1000, + ssl->f_rng, ssl->p_rng ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_make_public", ret ); + return( ret ); + } + + SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); + + if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + POLARSSL_MPI_MAX_SIZE, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + return( ret ); + } + + SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * opaque psk_identity<0..2^16-1>; + */ + if( ssl->psk == NULL || ssl->psk_identity == NULL ) + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); + + i = 4; + n = ssl->psk_identity_len; + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); + + memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len ); + i += ssl->psk_identity_len; + +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ) + { + n = 0; + } + else +#endif +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + { + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) + return( ret ); + } + else +#endif +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + /* + * ClientDiffieHellmanPublic public (DHM send G^X mod P) + */ + n = ssl->handshake->dhm_ctx.len; + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); + + ret = dhm_make_public( &ssl->handshake->dhm_ctx, + (int) mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->f_rng, ssl->p_rng ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_make_public", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * ClientECDiffieHellmanPublic public; + */ + ret = ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, + &ssl->out_msg[i], SSL_MAX_CONTENT_LEN - i, + ssl->f_rng, ssl->p_rng ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_make_public", ret ); + return( ret ); + } + + SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ) + { + i = 4; + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 ) + return( ret ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ + { + ((void) ciphersuite_info); + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_derive_keys", ret ); + return( ret ); + } + + ssl->out_msglen = i + n; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_CLIENT_KEY_EXCHANGE; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); + + return( 0 ); +} + +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_write_certificate_verify( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_write_certificate_verify( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + size_t n = 0, offset = 0; + unsigned char hash[48]; + unsigned char *hash_start = hash; + md_type_t md_alg = POLARSSL_MD_NONE; + unsigned int hashlen; + + SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->client_auth == 0 || ssl_own_cert( ssl ) == NULL ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl_own_key( ssl ) == NULL ) + { + SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Make an RSA signature of the handshake digests + */ + ssl->handshake->calc_verify( ssl, hash ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) + { + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(handshake_messages); + * + * sha_hash + * SHA(handshake_messages); + */ + hashlen = 36; + md_alg = POLARSSL_MD_NONE; + + /* + * For ECDSA, default hash is SHA-1 only + */ + if( pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECDSA ) ) + { + hash_start += 16; + hashlen -= 16; + md_alg = POLARSSL_MD_SHA1; + } + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + /* + * digitally-signed struct { + * opaque handshake_messages[handshake_messages_length]; + * }; + * + * Taking shortcut here. We assume that the server always allows the + * PRF Hash function and has sent it in the allowed signature + * algorithms list received in the Certificate Request message. + * + * Until we encounter a server that does not, we will take this + * shortcut. + * + * Reason: Otherwise we should have running hashes for SHA512 and SHA224 + * in order to satisfy 'weird' needs from the server side. + */ + if( ssl->transform_negotiate->ciphersuite_info->mac == + POLARSSL_MD_SHA384 ) + { + md_alg = POLARSSL_MD_SHA384; + ssl->out_msg[4] = SSL_HASH_SHA384; + } + else + { + md_alg = POLARSSL_MD_SHA256; + ssl->out_msg[4] = SSL_HASH_SHA256; + } + ssl->out_msg[5] = ssl_sig_from_pk( ssl_own_key( ssl ) ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + offset = 2; + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = pk_sign( ssl_own_key( ssl ), md_alg, hash_start, hashlen, + ssl->out_msg + 6 + offset, &n, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "pk_sign", ret ); + return( ret ); + } + + ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); + ssl->out_msg[5 + offset] = (unsigned char)( n ); + + ssl->out_msglen = 6 + n + offset; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); + + return( ret ); +} +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static int ssl_parse_new_session_ticket( ssl_context *ssl ) +{ + int ret; + uint32_t lifetime; + size_t ticket_len; + unsigned char *ticket; + + SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * struct { + * uint32 ticket_lifetime_hint; + * opaque ticket<0..2^16-1>; + * } NewSessionTicket; + * + * 0 . 0 handshake message type + * 1 . 3 handshake message length + * 4 . 7 ticket_lifetime_hint + * 8 . 9 ticket_len (n) + * 10 . 9+n ticket content + */ + if( ssl->in_msg[0] != SSL_HS_NEW_SESSION_TICKET || + ssl->in_hslen < 10 ) + { + SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); + } + + lifetime = ( ssl->in_msg[4] << 24 ) | ( ssl->in_msg[5] << 16 ) | + ( ssl->in_msg[6] << 8 ) | ( ssl->in_msg[7] ); + + ticket_len = ( ssl->in_msg[8] << 8 ) | ( ssl->in_msg[9] ); + + if( ticket_len + 10 != ssl->in_hslen ) + { + SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); + } + + SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) ); + + /* We're not waiting for a NewSessionTicket message any more */ + ssl->handshake->new_session_ticket = 0; + + /* + * Zero-length ticket means the server changed his mind and doesn't want + * to send a ticket after all, so just forget it + */ + if( ticket_len == 0 ) + return( 0 ); + + polarssl_zeroize( ssl->session_negotiate->ticket, + ssl->session_negotiate->ticket_len ); + polarssl_free( ssl->session_negotiate->ticket ); + ssl->session_negotiate->ticket = NULL; + ssl->session_negotiate->ticket_len = 0; + + if( ( ticket = polarssl_malloc( ticket_len ) ) == NULL ) + { + SSL_DEBUG_MSG( 1, ( "ticket malloc failed" ) ); + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + + memcpy( ticket, ssl->in_msg + 10, ticket_len ); + + ssl->session_negotiate->ticket = ticket; + ssl->session_negotiate->ticket_len = ticket_len; + ssl->session_negotiate->ticket_lifetime = lifetime; + + /* + * RFC 5077 section 3.4: + * "If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello." + */ + SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) ); + ssl->session_negotiate->length = 0; + + SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +/* + * SSL handshake -- client side -- single step + */ +int ssl_handshake_client_step( ssl_context *ssl ) +{ + int ret = 0; + + if( ssl->state == SSL_HANDSHAKE_OVER ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); + + if( ( ret = ssl_flush_output( ssl ) ) != 0 ) + return( ret ); + + switch( ssl->state ) + { + case SSL_HELLO_REQUEST: + ssl->state = SSL_CLIENT_HELLO; + break; + + /* + * ==> ClientHello + */ + case SSL_CLIENT_HELLO: + ret = ssl_write_client_hello( ssl ); + break; + + /* + * <== ServerHello + * Certificate + * ( ServerKeyExchange ) + * ( CertificateRequest ) + * ServerHelloDone + */ + case SSL_SERVER_HELLO: + ret = ssl_parse_server_hello( ssl ); + break; + + case SSL_SERVER_CERTIFICATE: + ret = ssl_parse_certificate( ssl ); + break; + + case SSL_SERVER_KEY_EXCHANGE: + ret = ssl_parse_server_key_exchange( ssl ); + break; + + case SSL_CERTIFICATE_REQUEST: + ret = ssl_parse_certificate_request( ssl ); + break; + + case SSL_SERVER_HELLO_DONE: + ret = ssl_parse_server_hello_done( ssl ); + break; + + /* + * ==> ( Certificate/Alert ) + * ClientKeyExchange + * ( CertificateVerify ) + * ChangeCipherSpec + * Finished + */ + case SSL_CLIENT_CERTIFICATE: + ret = ssl_write_certificate( ssl ); + break; + + case SSL_CLIENT_KEY_EXCHANGE: + ret = ssl_write_client_key_exchange( ssl ); + break; + + case SSL_CERTIFICATE_VERIFY: + ret = ssl_write_certificate_verify( ssl ); + break; + + case SSL_CLIENT_CHANGE_CIPHER_SPEC: + ret = ssl_write_change_cipher_spec( ssl ); + break; + + case SSL_CLIENT_FINISHED: + ret = ssl_write_finished( ssl ); + break; + + /* + * <== ( NewSessionTicket ) + * ChangeCipherSpec + * Finished + */ + case SSL_SERVER_CHANGE_CIPHER_SPEC: +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( ssl->handshake->new_session_ticket != 0 ) + ret = ssl_parse_new_session_ticket( ssl ); + else +#endif + ret = ssl_parse_change_cipher_spec( ssl ); + break; + + case SSL_SERVER_FINISHED: + ret = ssl_parse_finished( ssl ); + break; + + case SSL_FLUSH_BUFFERS: + SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); + ssl->state = SSL_HANDSHAKE_WRAPUP; + break; + + case SSL_HANDSHAKE_WRAPUP: + ssl_handshake_wrapup( ssl ); + break; + + default: + SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ret ); +} +#endif /* POLARSSL_SSL_CLI_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_srv.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_srv.c new file mode 100644 index 0000000..25be988 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_srv.c @@ -0,0 +1,3269 @@ +/* + * SSLv3/TLSv1 server-side functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_SRV_C) + +#include "polarssl/debug.h" +#include "polarssl/ssl.h" +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include + +#if defined(POLARSSL_HAVE_TIME) +#include +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Serialize a session in the following format: + * 0 . n-1 session structure, n = sizeof(ssl_session) + * n . n+2 peer_cert length = m (0 if no certificate) + * n+3 . n+2+m peer cert ASN.1 + * + * Assumes ticket is NULL (always true on server side). + */ +static int ssl_save_session( const ssl_session *session, + unsigned char *buf, size_t buf_len, + size_t *olen ) +{ + unsigned char *p = buf; + size_t left = buf_len; +#if defined(POLARSSL_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + if( left < sizeof( ssl_session ) ) + return( -1 ); + + memcpy( p, session, sizeof( ssl_session ) ); + p += sizeof( ssl_session ); + left -= sizeof( ssl_session ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + if( session->peer_cert == NULL ) + cert_len = 0; + else + cert_len = session->peer_cert->raw.len; + + if( left < 3 + cert_len ) + return( -1 ); + + *p++ = (unsigned char)( cert_len >> 16 & 0xFF ); + *p++ = (unsigned char)( cert_len >> 8 & 0xFF ); + *p++ = (unsigned char)( cert_len & 0xFF ); + + if( session->peer_cert != NULL ) + memcpy( p, session->peer_cert->raw.p, cert_len ); + + p += cert_len; +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + *olen = p - buf; + + return( 0 ); +} + +/* + * Unserialise session, see ssl_save_session() + */ +static int ssl_load_session( ssl_session *session, + const unsigned char *buf, size_t len ) +{ + const unsigned char *p = buf; + const unsigned char * const end = buf + len; +#if defined(POLARSSL_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + if( p + sizeof( ssl_session ) > end ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( session, p, sizeof( ssl_session ) ); + p += sizeof( ssl_session ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + if( p + 3 > end ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; + p += 3; + + if( cert_len == 0 ) + { + session->peer_cert = NULL; + } + else + { + int ret; + + if( p + cert_len > end ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + session->peer_cert = polarssl_malloc( sizeof( x509_crt ) ); + + if( session->peer_cert == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + x509_crt_init( session->peer_cert ); + + if( ( ret = x509_crt_parse_der( session->peer_cert, + p, cert_len ) ) != 0 ) + { + x509_crt_free( session->peer_cert ); + polarssl_free( session->peer_cert ); + session->peer_cert = NULL; + return( ret ); + } + + p += cert_len; + } +#endif /* POLARSSL_X509_CRT_PARSE_C */ + + if( p != end ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Create session ticket, secured as recommended in RFC 5077 section 4: + * + * struct { + * opaque key_name[16]; + * opaque iv[16]; + * opaque encrypted_state<0..2^16-1>; + * opaque mac[32]; + * } ticket; + * + * (the internal state structure differs, however). + */ +static int ssl_write_ticket( ssl_context *ssl, size_t *tlen ) +{ + int ret; + unsigned char * const start = ssl->out_msg + 10; + unsigned char *p = start; + unsigned char *state; + unsigned char iv[16]; + size_t clear_len, enc_len, pad_len, i; + + *tlen = 0; + + if( ssl->ticket_keys == NULL ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + /* Write key name */ + memcpy( p, ssl->ticket_keys->key_name, 16 ); + p += 16; + + /* Generate and write IV (with a copy for aes_crypt) */ + if( ( ret = ssl->f_rng( ssl->p_rng, p, 16 ) ) != 0 ) + return( ret ); + memcpy( iv, p, 16 ); + p += 16; + + /* + * Dump session state + * + * After the session state itself, we still need room for 16 bytes of + * padding and 32 bytes of MAC, so there's only so much room left + */ + state = p + 2; + if( ssl_save_session( ssl->session_negotiate, state, + SSL_MAX_CONTENT_LEN - ( state - ssl->out_ctr ) - 48, + &clear_len ) != 0 ) + { + return( POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE ); + } + SSL_DEBUG_BUF( 3, "session ticket cleartext", state, clear_len ); + + /* Apply PKCS padding */ + pad_len = 16 - clear_len % 16; + enc_len = clear_len + pad_len; + for( i = clear_len; i < enc_len; i++ ) + state[i] = (unsigned char) pad_len; + + /* Encrypt */ + if( ( ret = aes_crypt_cbc( &ssl->ticket_keys->enc, AES_ENCRYPT, + enc_len, iv, state, state ) ) != 0 ) + { + return( ret ); + } + + /* Write length */ + *p++ = (unsigned char)( ( enc_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( enc_len ) & 0xFF ); + p = state + enc_len; + + /* Compute and write MAC( key_name + iv + enc_state_len + enc_state ) */ + sha256_hmac( ssl->ticket_keys->mac_key, 16, start, p - start, p, 0 ); + p += 32; + + *tlen = p - start; + + SSL_DEBUG_BUF( 3, "session ticket structure", start, *tlen ); + + return( 0 ); +} + +/* + * Load session ticket (see ssl_write_ticket for structure) + */ +static int ssl_parse_ticket( ssl_context *ssl, + unsigned char *buf, + size_t len ) +{ + int ret; + ssl_session session; + unsigned char *key_name = buf; + unsigned char *iv = buf + 16; + unsigned char *enc_len_p = iv + 16; + unsigned char *ticket = enc_len_p + 2; + unsigned char *mac; + unsigned char computed_mac[32]; + size_t enc_len, clear_len, i; + unsigned char pad_len, diff; + + SSL_DEBUG_BUF( 3, "session ticket structure", buf, len ); + + if( len < 34 || ssl->ticket_keys == NULL ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; + mac = ticket + enc_len; + + if( len != enc_len + 66 ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + /* Check name, in constant time though it's not a big secret */ + diff = 0; + for( i = 0; i < 16; i++ ) + diff |= key_name[i] ^ ssl->ticket_keys->key_name[i]; + /* don't return yet, check the MAC anyway */ + + /* Check mac, with constant-time buffer comparison */ + sha256_hmac( ssl->ticket_keys->mac_key, 16, buf, len - 32, + computed_mac, 0 ); + + for( i = 0; i < 32; i++ ) + diff |= mac[i] ^ computed_mac[i]; + + /* Now return if ticket is not authentic, since we want to avoid + * decrypting arbitrary attacker-chosen data */ + if( diff != 0 ) + return( POLARSSL_ERR_SSL_INVALID_MAC ); + + /* Decrypt */ + if( ( ret = aes_crypt_cbc( &ssl->ticket_keys->dec, AES_DECRYPT, + enc_len, iv, ticket, ticket ) ) != 0 ) + { + return( ret ); + } + + /* Check PKCS padding */ + pad_len = ticket[enc_len - 1]; + + ret = 0; + for( i = 2; i < pad_len; i++ ) + if( ticket[enc_len - i] != pad_len ) + ret = POLARSSL_ERR_SSL_BAD_INPUT_DATA; + if( ret != 0 ) + return( ret ); + + clear_len = enc_len - pad_len; + + SSL_DEBUG_BUF( 3, "session ticket cleartext", ticket, clear_len ); + + /* Actually load session */ + if( ( ret = ssl_load_session( &session, ticket, clear_len ) ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "failed to parse ticket content" ) ); + ssl_session_free( &session ); + return( ret ); + } + +#if defined(POLARSSL_HAVE_TIME) + /* Check if still valid */ + if( (int) ( time( NULL) - session.start ) > ssl->ticket_lifetime ) + { + SSL_DEBUG_MSG( 1, ( "session ticket expired" ) ); + ssl_session_free( &session ); + return( POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED ); + } +#endif + + /* + * Keep the session ID sent by the client, since we MUST send it back to + * inform him we're accepting the ticket (RFC 5077 section 3.4) + */ + session.length = ssl->session_negotiate->length; + memcpy( &session.id, ssl->session_negotiate->id, session.length ); + + ssl_session_free( ssl->session_negotiate ); + memcpy( ssl->session_negotiate, &session, sizeof( ssl_session ) ); + + /* Zeroize instead of free as we copied the content */ + polarssl_zeroize( &session, sizeof( ssl_session ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) +/* + * Wrapper around f_sni, allowing use of ssl_set_own_cert() but + * making it act on ssl->hanshake->sni_key_cert instead. + */ +static int ssl_sni_wrapper( ssl_context *ssl, + const unsigned char* name, size_t len ) +{ + int ret; + ssl_key_cert *key_cert_ori = ssl->key_cert; + + ssl->key_cert = NULL; + ret = ssl->f_sni( ssl->p_sni, ssl, name, len ); + ssl->handshake->sni_key_cert = ssl->key_cert; + + ssl->key_cert = key_cert_ori; + + return( ret ); +} + +static int ssl_parse_servername_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + size_t servername_list_size, hostname_len; + const unsigned char *p; + + SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); + + servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( servername_list_size + 2 != len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + p = buf + 2; + while( servername_list_size > 0 ) + { + hostname_len = ( ( p[1] << 8 ) | p[2] ); + if( hostname_len + 3 > servername_list_size ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( p[0] == TLS_EXT_SERVERNAME_HOSTNAME ) + { + ret = ssl_sni_wrapper( ssl, p + 3, hostname_len ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_UNRECOGNIZED_NAME ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + return( 0 ); + } + + servername_list_size -= hostname_len + 3; + p += hostname_len + 3; + } + + if( servername_list_size != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + return( 0 ); +} +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ + +static int ssl_parse_renegotiation_info( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE ) + { + if( len != 1 || buf[0] != 0x0 ) + { + SSL_DEBUG_MSG( 1, ( "non-zero length renegotiated connection field" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; + } + else + { + /* Check verify-data in constant-time. The length OTOH is no secret */ + if( len != 1 + ssl->verify_data_len || + buf[0] != ssl->verify_data_len || + safer_memcmp( buf + 1, ssl->peer_verify_data, + ssl->verify_data_len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "non-matching renegotiated connection field" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } + + return( 0 ); +} + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +static int ssl_parse_signature_algorithms_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t sig_alg_list_size; + const unsigned char *p; + const unsigned char *end = buf + len; + const int *md_cur; + + + sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( sig_alg_list_size + 2 != len || + sig_alg_list_size % 2 != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * For now, ignore the SignatureAlgorithm part and rely on offered + * ciphersuites only for that part. To be fixed later. + * + * So, just look at the HashAlgorithm part. + */ + for( md_cur = md_list(); *md_cur != POLARSSL_MD_NONE; md_cur++ ) { + for( p = buf + 2; p < end; p += 2 ) { + if( *md_cur == (int) ssl_md_alg_from_hash( p[0] ) ) { + ssl->handshake->sig_alg = p[0]; + break; + } + } + } + + SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", + ssl->handshake->sig_alg ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) +static int ssl_parse_supported_elliptic_curves( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size, our_size; + const unsigned char *p; + const ecp_curve_info *curve_info, **curves; + + list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( list_size + 2 != len || + list_size % 2 != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Don't allow our peer to make us allocate too much memory, + * and leave room for a final 0 */ + our_size = list_size / 2 + 1; + if( our_size > POLARSSL_ECP_DP_MAX ) + our_size = POLARSSL_ECP_DP_MAX; + + if( ( curves = polarssl_malloc( our_size * sizeof( *curves ) ) ) == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + /* explicit void pointer cast for buggy MS compiler */ + memset( (void *) curves, 0, our_size * sizeof( *curves ) ); + ssl->handshake->curves = curves; + + p = buf + 2; + while( list_size > 0 && our_size > 1 ) + { + curve_info = ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); + + if( curve_info != NULL ) + { + *curves++ = curve_info; + our_size--; + } + + list_size -= 2; + p += 2; + } + + return( 0 ); +} + +static int ssl_parse_supported_point_formats( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size; + const unsigned char *p; + + list_size = buf[0]; + if( list_size + 1 != len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + p = buf + 2; + while( list_size > 0 ) + { + if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED || + p[0] == POLARSSL_ECP_PF_COMPRESSED ) + { + ssl->handshake->ecdh_ctx.point_format = p[0]; + SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); + return( 0 ); + } + + list_size--; + p++; + } + + return( 0 ); +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +static int ssl_parse_max_fragment_length_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 1 || buf[0] >= SSL_MAX_FRAG_LEN_INVALID ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->session_negotiate->mfl_code = buf[0]; + + return( 0 ); +} +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +static int ssl_parse_truncated_hmac_ext( ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ((void) buf); + + ssl->session_negotiate->trunc_hmac = SSL_TRUNC_HMAC_ENABLED; + + return( 0 ); +} +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static int ssl_parse_session_ticket_ext( ssl_context *ssl, + unsigned char *buf, + size_t len ) +{ + int ret; + + if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED ) + return( 0 ); + + /* Remember the client asked us to send a new ticket */ + ssl->handshake->new_session_ticket = 1; + + SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); + + if( len == 0 ) + return( 0 ); + + if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ) + { + SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); + return( 0 ); + } + + /* + * Failures are ok: just ignore the ticket and proceed. + */ + if( ( ret = ssl_parse_ticket( ssl, buf, len ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_parse_ticket", ret ); + return( 0 ); + } + + SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); + + ssl->handshake->resume = 1; + + /* Don't send a new ticket after all, this one is OK */ + ssl->handshake->new_session_ticket = 0; + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_SSL_ALPN) +static int ssl_parse_alpn_ext( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, cur_len, ours_len; + const unsigned char *theirs, *start, *end; + const char **ours; + + /* If ALPN not configured, just ignore the extension */ + if( ssl->alpn_list == NULL ) + return( 0 ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + /* + * Use our order of preference + */ + start = buf + 2; + end = buf + len; + for( ours = ssl->alpn_list; *ours != NULL; ours++ ) + { + ours_len = strlen( *ours ); + for( theirs = start; theirs != end; theirs += cur_len ) + { + /* If the list is well formed, we should get equality first */ + if( theirs > end ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + cur_len = *theirs++; + + /* Empty strings MUST NOT be included */ + if( cur_len == 0 ) + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + if( cur_len == ours_len && + memcmp( theirs, *ours, cur_len ) == 0 ) + { + ssl->alpn_chosen = *ours; + return( 0 ); + } + } + } + + /* If we get there, no match was found */ + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); +} +#endif /* POLARSSL_SSL_ALPN */ + +/* + * Auxiliary functions for ServerHello parsing and related actions + */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/* + * Return 1 if the given EC key uses the given curve, 0 otherwise + */ +#if defined(POLARSSL_ECDSA_C) +static int ssl_key_matches_curves( pk_context *pk, + const ecp_curve_info **curves ) +{ + const ecp_curve_info **crv = curves; + ecp_group_id grp_id = pk_ec( *pk )->grp.id; + + while( *crv != NULL ) + { + if( (*crv)->grp_id == grp_id ) + return( 1 ); + crv++; + } + + return( 0 ); +} +#endif /* POLARSSL_ECDSA_C */ + +/* + * Try picking a certificate for this ciphersuite, + * return 0 on success and -1 on failure. + */ +static int ssl_pick_cert( ssl_context *ssl, + const ssl_ciphersuite_t * ciphersuite_info ) +{ + ssl_key_cert *cur, *list; + pk_type_t pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_key_cert != NULL ) + list = ssl->handshake->sni_key_cert; + else +#endif + list = ssl->handshake->key_cert; + + if( pk_alg == POLARSSL_PK_NONE ) + return( 0 ); + + for( cur = list; cur != NULL; cur = cur->next ) + { + if( ! pk_can_do( cur->key, pk_alg ) ) + continue; + + /* + * This avoids sending the client a cert it'll reject based on + * keyUsage or other extensions. + * + * It also allows the user to provision different certificates for + * different uses based on keyUsage, eg if they want to avoid signing + * and decrypting with the same RSA key. + */ + if( ssl_check_cert_usage( cur->cert, ciphersuite_info, + SSL_IS_SERVER ) != 0 ) + { + continue; + } + +#if defined(POLARSSL_ECDSA_C) + if( pk_alg == POLARSSL_PK_ECDSA ) + { + if( ssl_key_matches_curves( cur->key, ssl->handshake->curves ) ) + break; + } + else +#endif + break; + } + + if( cur == NULL ) + return( -1 ); + + ssl->handshake->key_cert = cur; + return( 0 ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +/* + * Check if a given ciphersuite is suitable for use with our config/keys/etc + * Sets ciphersuite_info only if the suite matches. + */ +static int ssl_ciphersuite_match( ssl_context *ssl, int suite_id, + const ssl_ciphersuite_t **ciphersuite_info ) +{ + const ssl_ciphersuite_t *suite_info; + + suite_info = ssl_ciphersuite_from_id( suite_id ); + if( suite_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", suite_id ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + if( suite_info->min_minor_ver > ssl->minor_ver || + suite_info->max_minor_ver < ssl->minor_ver ) + return( 0 ); + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + if( ssl_ciphersuite_uses_ec( suite_info ) && + ( ssl->handshake->curves == NULL || + ssl->handshake->curves[0] == NULL ) ) + return( 0 ); +#endif + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + /* If the ciphersuite requires a pre-shared key and we don't + * have one, skip it now rather than failing later */ + if( ssl_ciphersuite_uses_psk( suite_info ) && + ssl->f_psk == NULL && + ( ssl->psk == NULL || ssl->psk_identity == NULL || + ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) ) + return( 0 ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) + /* + * Final check: if ciphersuite requires us to have a + * certificate/key of a particular type: + * - select the appropriate certificate if we have one, or + * - try the next ciphersuite if we don't + * This must be done last since we modify the key_cert list. + */ + if( ssl_pick_cert( ssl, suite_info ) != 0 ) + return( 0 ); +#endif + + *ciphersuite_info = suite_info; + return( 0 ); +} + +#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) +static int ssl_parse_client_hello_v2( ssl_context *ssl ) +{ + int ret; + unsigned int i, j; + size_t n; + unsigned int ciph_len, sess_len, chal_len; + unsigned char *buf, *p; + const int *ciphersuites; + const ssl_ciphersuite_t *ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); + + if( ssl->renegotiation != SSL_INITIAL_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + buf = ssl->in_hdr; + + SSL_DEBUG_BUF( 4, "record header", buf, 5 ); + + SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", + buf[2] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", + ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]", + buf[3], buf[4] ) ); + + /* + * SSLv2 Client Hello + * + * Record layer: + * 0 . 1 message length + * + * SSL layer: + * 2 . 2 message type + * 3 . 4 protocol version + */ + if( buf[2] != SSL_HS_CLIENT_HELLO || + buf[3] != SSL_MAJOR_VERSION_3 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; + + if( n < 17 || n > 512 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->major_ver = SSL_MAJOR_VERSION_3; + ssl->minor_ver = ( buf[4] <= ssl->max_minor_ver ) + ? buf[4] : ssl->max_minor_ver; + + if( ssl->minor_ver < ssl->min_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, + ssl->min_major_ver, ssl->min_minor_ver ) ); + + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_PROTOCOL_VERSION ); + return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + + ssl->handshake->max_major_ver = buf[3]; + ssl->handshake->max_minor_ver = buf[4]; + + if( ( ret = ssl_fetch_input( ssl, 2 + n ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); + return( ret ); + } + + ssl->handshake->update_checksum( ssl, buf + 2, n ); + + buf = ssl->in_msg; + n = ssl->in_left - 5; + + /* + * 0 . 1 ciphersuitelist length + * 2 . 3 session id length + * 4 . 5 challenge length + * 6 . .. ciphersuitelist + * .. . .. session id + * .. . .. challenge + */ + SSL_DEBUG_BUF( 4, "record contents", buf, n ); + + ciph_len = ( buf[0] << 8 ) | buf[1]; + sess_len = ( buf[2] << 8 ) | buf[3]; + chal_len = ( buf[4] << 8 ) | buf[5]; + + SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", + ciph_len, sess_len, chal_len ) ); + + /* + * Make sure each parameter length is valid + */ + if( ciph_len < 3 || ( ciph_len % 3 ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( sess_len > 32 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( chal_len < 8 || chal_len > 32 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( n != 6 + ciph_len + sess_len + chal_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", + buf + 6, ciph_len ); + SSL_DEBUG_BUF( 3, "client hello, session id", + buf + 6 + ciph_len, sess_len ); + SSL_DEBUG_BUF( 3, "client hello, challenge", + buf + 6 + ciph_len + sess_len, chal_len ); + + p = buf + 6 + ciph_len; + ssl->session_negotiate->length = sess_len; + memset( ssl->session_negotiate->id, 0, + sizeof( ssl->session_negotiate->id ) ); + memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->length ); + + p += sess_len; + memset( ssl->handshake->randbytes, 0, 64 ); + memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); + + /* + * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ + for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) + { + if( p[0] == 0 && p[1] == 0 && p[2] == SSL_EMPTY_RENEGOTIATION_INFO ) + { + SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); + if( ssl->renegotiation == SSL_RENEGOTIATION ) + { + SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; + break; + } + } + + ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else + for( i = 0; ciphersuites[i] != 0; i++ ) + { + for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) +#endif + { + if( p[0] != 0 || + p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; + + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) + goto have_ciphersuite_v2; + } + } + + SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + +have_ciphersuite_v2: + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + + /* + * SSLv2 Client Hello relevant renegotiation security checks + */ + if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->in_left = 0; + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ + +static int ssl_parse_client_hello( ssl_context *ssl ) +{ + int ret; + unsigned int i, j; + size_t n; + unsigned int ciph_len, sess_len; + unsigned int comp_len; + unsigned int ext_len = 0; + unsigned char *buf, *p, *ext; + int renegotiation_info_seen = 0; + int handshake_failure = 0; + const int *ciphersuites; + const ssl_ciphersuite_t *ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); + + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && + ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); + return( ret ); + } + + buf = ssl->in_hdr; + +#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + if( ( buf[0] & 0x80 ) != 0 ) + return ssl_parse_client_hello_v2( ssl ); +#endif + + SSL_DEBUG_BUF( 4, "record header", buf, 5 ); + + SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", + buf[0] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", + ( buf[3] << 8 ) | buf[4] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v3, protocol ver: [%d:%d]", + buf[1], buf[2] ) ); + + /* + * SSLv3/TLS Client Hello + * + * Record layer: + * 0 . 0 message type + * 1 . 2 protocol version + * 3 . 4 message length + */ + + /* According to RFC 5246 Appendix E.1, the version here is typically + * "{03,00}, the lowest version number supported by the client, [or] the + * value of ClientHello.client_version", so the only meaningful check here + * is the major version shouldn't be less than 3 */ + if( buf[0] != SSL_MSG_HANDSHAKE || + buf[1] < SSL_MAJOR_VERSION_3 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + n = ( buf[3] << 8 ) | buf[4]; + + if( n < 45 || n > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( ssl->renegotiation == SSL_INITIAL_HANDSHAKE && + ( ret = ssl_fetch_input( ssl, 5 + n ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); + return( ret ); + } + + buf = ssl->in_msg; + if( !ssl->renegotiation ) + n = ssl->in_left - 5; + else + n = ssl->in_msglen; + + ssl->handshake->update_checksum( ssl, buf, n ); + + /* + * SSL layer: + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 protocol version + * 6 . 9 UNIX time() + * 10 . 37 random bytes + * 38 . 38 session id length + * 39 . 38+x session id + * 39+x . 40+x ciphersuitelist length + * 41+x . 40+y ciphersuitelist + * 41+y . 41+y compression alg length + * 42+y . 41+z compression algs + * .. . .. extensions + */ + SSL_DEBUG_BUF( 4, "record contents", buf, n ); + + SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", + buf[0] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", + ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); + SSL_DEBUG_MSG( 3, ( "client hello v3, max. version: [%d:%d]", + buf[4], buf[5] ) ); + + /* + * Check the handshake type and protocol version + */ + if( buf[0] != SSL_HS_CLIENT_HELLO ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->major_ver = buf[4]; + ssl->minor_ver = buf[5]; + + ssl->handshake->max_major_ver = ssl->major_ver; + ssl->handshake->max_minor_ver = ssl->minor_ver; + + if( ssl->major_ver < ssl->min_major_ver || + ssl->minor_ver < ssl->min_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, + ssl->min_major_ver, ssl->min_minor_ver ) ); + + ssl_send_alert_message( ssl, SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_PROTOCOL_VERSION ); + + return( POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + + if( ssl->major_ver > ssl->max_major_ver ) + { + ssl->major_ver = ssl->max_major_ver; + ssl->minor_ver = ssl->max_minor_ver; + } + else if( ssl->minor_ver > ssl->max_minor_ver ) + ssl->minor_ver = ssl->max_minor_ver; + + memcpy( ssl->handshake->randbytes, buf + 6, 32 ); + + /* + * Check the handshake message length + */ + if( buf[1] != 0 || n != (unsigned int) 4 + ( ( buf[2] << 8 ) | buf[3] ) ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Check the session length + */ + sess_len = buf[38]; + + if( sess_len > 32 || sess_len > n - 42 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->session_negotiate->length = sess_len; + memset( ssl->session_negotiate->id, 0, + sizeof( ssl->session_negotiate->id ) ); + memcpy( ssl->session_negotiate->id, buf + 39, + ssl->session_negotiate->length ); + + /* + * Check the ciphersuitelist length + */ + ciph_len = ( buf[39 + sess_len] << 8 ) + | ( buf[40 + sess_len] ); + + if( ciph_len < 2 || ( ciph_len % 2 ) != 0 || ciph_len > n - 42 - sess_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Check the compression algorithms length + */ + comp_len = buf[41 + sess_len + ciph_len]; + + if( comp_len < 1 || comp_len > 16 || + comp_len > n - 42 - sess_len - ciph_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Check the extension length + */ + if( n > 42 + sess_len + ciph_len + comp_len ) + { + ext_len = ( buf[42 + sess_len + ciph_len + comp_len] << 8 ) + | ( buf[43 + sess_len + ciph_len + comp_len] ); + + if( ( ext_len > 0 && ext_len < 4 ) || + n != 44 + sess_len + ciph_len + comp_len + ext_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + SSL_DEBUG_BUF( 3, "Ext", buf + 44 + sess_len + ciph_len + comp_len, ext_len); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } + + ssl->session_negotiate->compression = SSL_COMPRESS_NULL; +#if defined(POLARSSL_ZLIB_SUPPORT) + for( i = 0; i < comp_len; ++i ) + { + if( buf[42 + sess_len + ciph_len + i] == SSL_COMPRESS_DEFLATE ) + { + ssl->session_negotiate->compression = SSL_COMPRESS_DEFLATE; + break; + } + } +#endif + + SSL_DEBUG_BUF( 3, "client hello, random bytes", + buf + 6, 32 ); + SSL_DEBUG_BUF( 3, "client hello, session id", + buf + 38, sess_len ); + SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", + buf + 41 + sess_len, ciph_len ); + SSL_DEBUG_BUF( 3, "client hello, compression", + buf + 42 + sess_len + ciph_len, comp_len ); + + /* + * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ + for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 ) + { + if( p[0] == 0 && p[1] == SSL_EMPTY_RENEGOTIATION_INFO ) + { + SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); + if( ssl->renegotiation == SSL_RENEGOTIATION ) + { + SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + ssl->secure_renegotiation = SSL_SECURE_RENEGOTIATION; + break; + } + } + + ext = buf + 44 + sess_len + ciph_len + comp_len; + + while( ext_len ) + { + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); + + if( ext_size + 4 > ext_len ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + switch( ext_id ) + { +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + case TLS_EXT_SERVERNAME: + SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); + if( ssl->f_sni == NULL ) + break; + + ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ + + case TLS_EXT_RENEGOTIATION_INFO: + SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); + renegotiation_info_seen = 1; + + ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + case TLS_EXT_SIG_ALG: + SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); + if( ssl->renegotiation == SSL_RENEGOTIATION ) + break; + + ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: + SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); + + ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; + + case TLS_EXT_SUPPORTED_POINT_FORMATS: + SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); + ssl->handshake->cli_exts |= TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; + + ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + case TLS_EXT_MAX_FRAGMENT_LENGTH: + SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); + + ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + case TLS_EXT_TRUNCATED_HMAC: + SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); + + ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + case TLS_EXT_SESSION_TICKET: + SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); + + ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +#if defined(POLARSSL_SSL_ALPN) + case TLS_EXT_ALPN: + SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + + default: + SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + ext_id ) ); + } + + ext_len -= 4 + ext_size; + ext += 4 + ext_size; + + if( ext_len > 0 && ext_len < 4 ) + { + SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } + + /* + * Renegotiation security checks + */ + if( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == SSL_LEGACY_BREAK_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_SECURE_RENEGOTIATION && + renegotiation_info_seen == 0 ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == SSL_LEGACY_NO_RENEGOTIATION ) + { + SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); + handshake_failure = 1; + } + else if( ssl->renegotiation == SSL_RENEGOTIATION && + ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + renegotiation_info_seen == 1 ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); + handshake_failure = 1; + } + + if( handshake_failure == 1 ) + { + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Search for a matching ciphersuite + * (At the end because we need information from the EC-based extensions + * and certificate from the SNI callback triggered by the SNI extension.) + */ + ciphersuites = ssl->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else + for( i = 0; ciphersuites[i] != 0; i++ ) + { + for( j = 0, p = buf + 41 + sess_len; j < ciph_len; j += 2, p += 2 ) +#endif + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; + + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) + goto have_ciphersuite; + } + } + + SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + +have_ciphersuite: + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + + ssl->in_left = 0; + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); + + return( 0 ); +} + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +static void ssl_write_truncated_hmac_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->session_negotiate->trunc_hmac == SSL_TRUNC_HMAC_DISABLED ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static void ssl_write_session_ticket_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->handshake->new_session_ticket == 0 ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +static void ssl_write_renegotiation_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->secure_renegotiation != SSL_SECURE_RENEGOTIATION ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + + *p++ = 0x00; + *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; + *p++ = ssl->verify_data_len * 2 & 0xFF; + + memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); + p += ssl->verify_data_len; + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + p += ssl->verify_data_len; + + *olen = 5 + ssl->verify_data_len * 2; +} + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +static void ssl_write_max_fragment_length_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->session_negotiate->mfl_code == SSL_MAX_FRAG_LEN_NONE ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + + *p++ = 0x00; + *p++ = 1; + + *p++ = ssl->session_negotiate->mfl_code; + + *olen = 5; +} +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) +static void ssl_write_supported_point_formats_ext( ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + ((void) ssl); + + if( ( ssl->handshake->cli_exts & + TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); + + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + + *p++ = 0x00; + *p++ = 2; + + *p++ = 1; + *p++ = POLARSSL_ECP_PF_UNCOMPRESSED; + + *olen = 6; +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_SSL_ALPN ) +static void ssl_write_alpn_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + if( ssl->alpn_chosen == NULL ) + { + *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); + + /* + * 0 . 1 ext identifier + * 2 . 3 ext length + * 4 . 5 protocol list length + * 6 . 6 protocol name length + * 7 . 7+n protocol name + */ + buf[0] = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF ); + + *olen = 7 + strlen( ssl->alpn_chosen ); + + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); + + memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); +} +#endif /* POLARSSL_ECDH_C || POLARSSL_ECDSA_C */ + +static int ssl_write_server_hello( ssl_context *ssl ) +{ +#if defined(POLARSSL_HAVE_TIME) + time_t t; +#endif + int ret; + size_t olen, ext_len = 0, n; + unsigned char *buf, *p; + + SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); + + if( ssl->f_rng == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( POLARSSL_ERR_SSL_NO_RNG ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 protocol version + * 6 . 9 UNIX time() + * 10 . 37 random bytes + */ + buf = ssl->out_msg; + p = buf + 4; + + *p++ = (unsigned char) ssl->major_ver; + *p++ = (unsigned char) ssl->minor_ver; + + SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", + buf[4], buf[5] ) ); + +#if defined(POLARSSL_HAVE_TIME) + t = time( NULL ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); + + SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); +#else + if( ( ret = ssl->f_rng( ssl->p_rng, p, 4 ) ) != 0 ) + return( ret ); + + p += 4; +#endif /* POLARSSL_HAVE_TIME */ + + if( ( ret = ssl->f_rng( ssl->p_rng, p, 28 ) ) != 0 ) + return( ret ); + + p += 28; + + memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); + + SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); + + /* + * Resume is 0 by default, see ssl_handshake_init(). + * It may be already set to 1 by ssl_parse_session_ticket_ext(). + * If not, try looking up session ID in our cache. + */ + if( ssl->handshake->resume == 0 && + ssl->renegotiation == SSL_INITIAL_HANDSHAKE && + ssl->session_negotiate->length != 0 && + ssl->f_get_cache != NULL && + ssl->f_get_cache( ssl->p_get_cache, ssl->session_negotiate ) == 0 ) + { + SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); + ssl->handshake->resume = 1; + } + + if( ssl->handshake->resume == 0 ) + { + /* + * New session, create a new session id, + * unless we're about to issue a session ticket + */ + ssl->state++; + +#if defined(POLARSSL_HAVE_TIME) + ssl->session_negotiate->start = time( NULL ); +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( ssl->handshake->new_session_ticket != 0 ) + { + ssl->session_negotiate->length = n = 0; + memset( ssl->session_negotiate->id, 0, 32 ); + } + else +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + { + ssl->session_negotiate->length = n = 32; + if( ( ret = ssl->f_rng( ssl->p_rng, ssl->session_negotiate->id, + n ) ) != 0 ) + return( ret ); + } + } + else + { + /* + * Resuming a session + */ + n = ssl->session_negotiate->length; + ssl->state = SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_derive_keys", ret ); + return( ret ); + } + } + + /* + * 38 . 38 session id length + * 39 . 38+n session id + * 39+n . 40+n chosen ciphersuite + * 41+n . 41+n chosen compression alg. + * 42+n . 43+n extensions length + * 44+n . 43+n+m extensions + */ + *p++ = (unsigned char) ssl->session_negotiate->length; + memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->length ); + p += ssl->session_negotiate->length; + + SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); + SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); + SSL_DEBUG_MSG( 3, ( "%s session has been resumed", + ssl->handshake->resume ? "a" : "no" ) ); + + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); + *p++ = (unsigned char)( ssl->session_negotiate->compression ); + + SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", + ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); + SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", + ssl->session_negotiate->compression ) ); + + /* + * First write extensions, then the total length + */ + ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(POLARSSL_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); + + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } + + ssl->out_msglen = p - buf; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_SERVER_HELLO; + + ret = ssl_write_record( ssl ); + + SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); + + return( ret ); +} + +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_write_certificate_request( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_write_certificate_request( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + size_t dn_size, total_dn_size; /* excluding length bytes */ + size_t ct_len, sa_len; /* including length bytes */ + unsigned char *buf, *p; + const x509_crt *crt; + + SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); + + ssl->state++; + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ssl->authmode == SSL_VERIFY_NONE ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); + return( 0 ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 4 cert type count + * 5 .. m-1 cert types + * m .. m+1 sig alg length (TLS 1.2 only) + * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) + * n .. n+1 length of all DNs + * n+2 .. n+3 length of DN 1 + * n+4 .. ... Distinguished Name #1 + * ... .. ... length of DN 2, etc. + */ + buf = ssl->out_msg; + p = buf + 4; + + /* + * Supported certificate types + * + * ClientCertificateType certificate_types<1..2^8-1>; + * enum { (255) } ClientCertificateType; + */ + ct_len = 0; + +#if defined(POLARSSL_RSA_C) + p[1 + ct_len++] = SSL_CERT_TYPE_RSA_SIGN; +#endif +#if defined(POLARSSL_ECDSA_C) + p[1 + ct_len++] = SSL_CERT_TYPE_ECDSA_SIGN; +#endif + + p[0] = (unsigned char) ct_len++; + p += ct_len; + + sa_len = 0; +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + /* + * Add signature_algorithms for verify (TLS 1.2) + * + * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; + * + * struct { + * HashAlgorithm hash; + * SignatureAlgorithm signature; + * } SignatureAndHashAlgorithm; + * + * enum { (255) } HashAlgorithm; + * enum { (255) } SignatureAlgorithm; + */ + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + /* + * Only use current running hash algorithm that is already required + * for requested ciphersuite. + */ + ssl->handshake->verify_sig_alg = SSL_HASH_SHA256; + + if( ssl->transform_negotiate->ciphersuite_info->mac == + POLARSSL_MD_SHA384 ) + { + ssl->handshake->verify_sig_alg = SSL_HASH_SHA384; + } + + /* + * Supported signature algorithms + */ +#if defined(POLARSSL_RSA_C) + p[2 + sa_len++] = ssl->handshake->verify_sig_alg; + p[2 + sa_len++] = SSL_SIG_RSA; +#endif +#if defined(POLARSSL_ECDSA_C) + p[2 + sa_len++] = ssl->handshake->verify_sig_alg; + p[2 + sa_len++] = SSL_SIG_ECDSA; +#endif + + p[0] = (unsigned char)( sa_len >> 8 ); + p[1] = (unsigned char)( sa_len ); + sa_len += 2; + p += sa_len; + } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + /* + * DistinguishedName certificate_authorities<0..2^16-1>; + * opaque DistinguishedName<1..2^16-1>; + */ + p += 2; + crt = ssl->ca_chain; + + total_dn_size = 0; + while( crt != NULL && crt->version != 0 ) + { + if( p - buf > 4096 ) + break; + + dn_size = crt->subject_raw.len; + *p++ = (unsigned char)( dn_size >> 8 ); + *p++ = (unsigned char)( dn_size ); + memcpy( p, crt->subject_raw.p, dn_size ); + p += dn_size; + + SSL_DEBUG_BUF( 3, "requested DN", p, dn_size ); + + total_dn_size += 2 + dn_size; + crt = crt->next; + } + + ssl->out_msglen = p - buf; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST; + ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); + ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); + + ret = ssl_write_record( ssl ); + + SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); + + return( ret ); +} +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( ssl_context *ssl ) +{ + int ret; + + if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_ECKEY ) ) + { + SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = ecdh_get_params( &ssl->handshake->ecdh_ctx, + pk_ec( *ssl_own_key( ssl ) ), + POLARSSL_ECDH_OURS ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ecdh_get_params" ), ret ); + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +static int ssl_write_server_key_exchange( ssl_context *ssl ) +{ + int ret; + size_t n = 0; + const ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + unsigned char *p = ssl->out_msg + 4; + unsigned char *dig_signed = p; + size_t dig_signed_len = 0, len; + ((void) dig_signed); + ((void) dig_signed_len); +#endif + + SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + ssl_get_ecdh_params_from_cert( ssl ); + + SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + /* TODO: Support identity hints */ + *(p++) = 0x00; + *(p++) = 0x00; + + n += 2; + } +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + /* + * Ephemeral DH parameters: + * + * struct { + * opaque dh_p<1..2^16-1>; + * opaque dh_g<1..2^16-1>; + * opaque dh_Ys<1..2^16-1>; + * } ServerDHParams; + */ + if( ( ret = mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->dhm_P ) ) != 0 || + ( ret = mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->dhm_G ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_copy", ret ); + return( ret ); + } + + if( ( ret = dhm_make_params( &ssl->handshake->dhm_ctx, + (int) mpi_size( &ssl->handshake->dhm_ctx.P ), + p, &len, ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_make_params", ret ); + return( ret ); + } + + dig_signed = p; + dig_signed_len = len; + + p += len; + n += len; + + SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); + SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); + SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); + SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); + } +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * Ephemeral ECDH parameters: + * + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ + const ecp_curve_info **curve = NULL; +#if defined(POLARSSL_SSL_SET_CURVES) + const ecp_group_id *gid; + + /* Match our preference list against the offered curves */ + for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ ) + for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) + if( (*curve)->grp_id == *gid ) + goto curve_matching_done; + +curve_matching_done: +#else + curve = ssl->handshake->curves; +#endif + + if( *curve == NULL ) + { + SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + } + + SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); + + if( ( ret = ecp_use_known_dp( &ssl->handshake->ecdh_ctx.grp, + (*curve)->grp_id ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecp_use_known_dp", ret ); + return( ret ); + } + + if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, + p, SSL_MAX_CONTENT_LEN - n, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_make_params", ret ); + return( ret ); + } + + dig_signed = p; + dig_signed_len = len; + + p += len; + n += len; + + SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); + } +#endif /* POLARSSL_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + { + size_t signature_len = 0; + unsigned int hashlen = 0; + unsigned char hash[64]; + md_type_t md_alg = POLARSSL_MD_NONE; + + /* + * Choose hash algorithm. NONE means MD5 + SHA1 here. + */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + md_alg = ssl_md_alg_from_hash( ssl->handshake->sig_alg ); + + if( md_alg == POLARSSL_MD_NONE ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ciphersuite_info->key_exchange == + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA ) + { + md_alg = POLARSSL_MD_SHA1; + } + else +#endif + { + md_alg = POLARSSL_MD_NONE; + } + + /* + * Compute the hash to be signed + */ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( md_alg == POLARSSL_MD_NONE ) + { + md5_context md5; + sha1_context sha1; + + md5_init( &md5 ); + sha1_init( &sha1 ); + + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(ClientHello.random + ServerHello.random + * + ServerParams); + * sha_hash + * SHA(ClientHello.random + ServerHello.random + * + ServerParams); + */ + md5_starts( &md5 ); + md5_update( &md5, ssl->handshake->randbytes, 64 ); + md5_update( &md5, dig_signed, dig_signed_len ); + md5_finish( &md5, hash ); + + sha1_starts( &sha1 ); + sha1_update( &sha1, ssl->handshake->randbytes, 64 ); + sha1_update( &sha1, dig_signed, dig_signed_len ); + sha1_finish( &sha1, hash + 16 ); + + hashlen = 36; + + md5_free( &md5 ); + sha1_free( &sha1 ); + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || \ + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( md_alg != POLARSSL_MD_NONE ) + { + md_context_t ctx; + const md_info_t *md_info = md_info_from_type( md_alg ); + + md_init( &ctx ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + + /* + * digitally-signed struct { + * opaque client_random[32]; + * opaque server_random[32]; + * ServerDHParams params; + * }; + */ + if( ( ret = md_init_ctx( &ctx, md_info ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "md_init_ctx", ret ); + return( ret ); + } + + md_starts( &ctx ); + md_update( &ctx, ssl->handshake->randbytes, 64 ); + md_update( &ctx, dig_signed, dig_signed_len ); + md_finish( &ctx, hash ); + md_free( &ctx ); + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( md_info_from_type( md_alg ) )->size ); + + /* + * Make the signature + */ + if( ssl_own_key( ssl ) == NULL ) + { + SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + *(p++) = ssl->handshake->sig_alg; + *(p++) = ssl_sig_from_pk( ssl_own_key( ssl ) ); + + n += 2; + } +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + if( ( ret = pk_sign( ssl_own_key( ssl ), md_alg, hash, hashlen, + p + 2 , &signature_len, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "pk_sign", ret ); + return( ret ); + } + + *(p++) = (unsigned char)( signature_len >> 8 ); + *(p++) = (unsigned char)( signature_len ); + n += 2; + + SSL_DEBUG_BUF( 3, "my signature", p, signature_len ); + + p += signature_len; + n += signature_len; + } +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || + POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + + ssl->out_msglen = 4 + n; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_SERVER_KEY_EXCHANGE; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); + + return( 0 ); +} + +static int ssl_write_server_hello_done( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); + + ssl->out_msglen = 4; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_SERVER_HELLO_DONE; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); + + return( 0 ); +} + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) +static int ssl_parse_client_dh_public( ssl_context *ssl, unsigned char **p, + const unsigned char *end ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + size_t n; + + /* + * Receive G^Y mod P, premaster = (G^Y)^X mod P + */ + if( *p + 2 > end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + n = ( (*p)[0] << 8 ) | (*p)[1]; + *p += 2; + + if( *p + n > end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_read_public", ret ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + *p += n; + + SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) +static int ssl_parse_encrypted_pms( ssl_context *ssl, + const unsigned char *p, + const unsigned char *end, + size_t pms_offset ) +{ + int ret; + size_t len = pk_get_len( ssl_own_key( ssl ) ); + unsigned char *pms = ssl->handshake->premaster + pms_offset; + + if( ! pk_can_do( ssl_own_key( ssl ), POLARSSL_PK_RSA ) ) + { + SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Decrypt the premaster using own private RSA key + */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver != SSL_MINOR_VERSION_0 ) + { + if( *p++ != ( ( len >> 8 ) & 0xFF ) || + *p++ != ( ( len ) & 0xFF ) ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + } +#endif + + if( p + len != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + ret = pk_decrypt( ssl_own_key( ssl ), p, len, + pms, &ssl->handshake->pmslen, + sizeof( ssl->handshake->premaster ) - pms_offset, + ssl->f_rng, ssl->p_rng ); + + if( ret != 0 || ssl->handshake->pmslen != 48 || + pms[0] != ssl->handshake->max_major_ver || + pms[1] != ssl->handshake->max_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + + /* + * Protection against Bleichenbacher's attack: + * invalid PKCS#1 v1.5 padding must not cause + * the connection to end immediately; instead, + * send a bad_record_mac later in the handshake. + */ + ssl->handshake->pmslen = 48; + + ret = ssl->f_rng( ssl->p_rng, pms, ssl->handshake->pmslen ); + if( ret != 0 ) + return( ret ); + } + + return( ret ); +} +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +static int ssl_parse_client_psk_identity( ssl_context *ssl, unsigned char **p, + const unsigned char *end ) +{ + int ret = 0; + size_t n; + + if( ssl->f_psk == NULL && + ( ssl->psk == NULL || ssl->psk_identity == NULL || + ssl->psk_identity_len == 0 || ssl->psk_len == 0 ) ) + { + SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); + return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Receive client pre-shared key identity name + */ + if( *p + 2 > end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + n = ( (*p)[0] << 8 ) | (*p)[1]; + *p += 2; + + if( n < 1 || n > 65535 || *p + n > end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ssl->f_psk != NULL ) + { + if( ssl->f_psk( ssl->p_psk, ssl, *p, n ) != 0 ) + ret = POLARSSL_ERR_SSL_UNKNOWN_IDENTITY; + } + else + { + /* Identity is not a big secret since clients send it in the clear, + * but treat it carefully anyway, just in case */ + if( n != ssl->psk_identity_len || + safer_memcmp( ssl->psk_identity, *p, n ) != 0 ) + { + ret = POLARSSL_ERR_SSL_UNKNOWN_IDENTITY; + } + } + + if( ret == POLARSSL_ERR_SSL_UNKNOWN_IDENTITY ) + { + SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); + if( ( ret = ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 ) + { + return( ret ); + } + + return( POLARSSL_ERR_SSL_UNKNOWN_IDENTITY ); + } + + *p += n; + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +static int ssl_parse_client_key_exchange( ssl_context *ssl ) +{ + int ret; + const ssl_ciphersuite_t *ciphersuite_info; + + ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ssl->in_msg[0] != SSL_HS_CLIENT_KEY_EXCHANGE ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ) + { + unsigned char *p = ssl->in_msg + 4; + unsigned char *end = ssl->in_msg + ssl->in_hslen; + + if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); + return( ret ); + } + + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + ssl->handshake->pmslen = POLARSSL_PREMASTER_SIZE; + + if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + &ssl->handshake->pmslen, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx, + ssl->in_msg + 4, ssl->in_hslen - 4 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_read_public", ret ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); + + if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + POLARSSL_MPI_MAX_SIZE, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED || + POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ) + { + unsigned char *p = ssl->in_msg + 4; + unsigned char *end = ssl->in_msg + ssl->in_hslen; + + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + { + unsigned char *p = ssl->in_msg + 4; + unsigned char *end = ssl->in_msg + ssl->in_hslen; + + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); + return( ret ); + } + + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + unsigned char *p = ssl->in_msg + 4; + unsigned char *end = ssl->in_msg + ssl->in_hslen; + + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); + return( ret ); + } + + if( p != end ) + { + SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + unsigned char *p = ssl->in_msg + 4; + unsigned char *end = ssl->in_msg + ssl->in_hslen; + + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx, + p, end - p ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_read_public", ret ); + return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); + + if( ( ret = ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA ) + { + if( ( ret = ssl_parse_encrypted_pms( ssl, + ssl->in_msg + 4, + ssl->in_msg + ssl->in_hslen, + 0 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); + return( ret ); + } + } + else +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = ssl_derive_keys( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_derive_keys", ret ); + return( ret ); + } + + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); + + return( 0 ); +} + +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_certificate_verify( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_parse_certificate_verify( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + size_t sa_len, sig_len; + unsigned char hash[48]; + unsigned char *hash_start = hash; + size_t hashlen; +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + pk_type_t pk_alg; +#endif + md_type_t md_alg; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->session_negotiate->peer_cert == NULL ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + ssl->handshake->calc_verify( ssl, hash ); + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + ssl->state++; + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + if( ssl->in_msg[0] != SSL_HS_CERTIFICATE_VERIFY ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 sig alg (TLS 1.2 only) + * 4+n . 5+n signature length (n = sa_len) + * 6+n . 6+n+m signature (m = sig_len) + */ + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver != SSL_MINOR_VERSION_3 ) + { + sa_len = 0; + + md_alg = POLARSSL_MD_NONE; + hashlen = 36; + + /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ + if( pk_can_do( &ssl->session_negotiate->peer_cert->pk, + POLARSSL_PK_ECDSA ) ) + { + hash_start += 16; + hashlen -= 16; + md_alg = POLARSSL_MD_SHA1; + } + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 || POLARSSL_SSL_PROTO_TLS1 || + POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + sa_len = 2; + + /* + * Hash + */ + if( ssl->in_msg[4] != ssl->handshake->verify_sig_alg ) + { + SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" + " for verify message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + md_alg = ssl_md_alg_from_hash( ssl->handshake->verify_sig_alg ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + + /* + * Signature + */ + if( ( pk_alg = ssl_pk_alg_from_sig( ssl->in_msg[5] ) ) + == POLARSSL_PK_NONE ) + { + SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" + " for verify message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + /* + * Check the certificate's key type matches the signature alg + */ + if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) + { + SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + sig_len = ( ssl->in_msg[4 + sa_len] << 8 ) | ssl->in_msg[5 + sa_len]; + + if( sa_len + sig_len + 6 != ssl->in_hslen ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + if( ( ret = pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash_start, hashlen, + ssl->in_msg + 6 + sa_len, sig_len ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "pk_verify", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); + + return( ret ); +} +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED && + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static int ssl_write_new_session_ticket( ssl_context *ssl ) +{ + int ret; + size_t tlen; + uint32_t lifetime = (uint32_t) ssl->ticket_lifetime; + + SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) ); + + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_NEW_SESSION_TICKET; + + /* + * struct { + * uint32 ticket_lifetime_hint; + * opaque ticket<0..2^16-1>; + * } NewSessionTicket; + * + * 4 . 7 ticket_lifetime_hint (0 = unspecified) + * 8 . 9 ticket_len (n) + * 10 . 9+n ticket content + */ + + ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; + ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; + ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; + ssl->out_msg[7] = ( lifetime ) & 0xFF; + + if( ( ret = ssl_write_ticket( ssl, &tlen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_ticket", ret ); + tlen = 0; + } + + ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); + + ssl->out_msglen = 10 + tlen; + + /* + * Morally equivalent to updating ssl->state, but NewSessionTicket and + * ChangeCipherSpec share the same state. + */ + ssl->handshake->new_session_ticket = 0; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +/* + * SSL handshake -- server side -- single step + */ +int ssl_handshake_server_step( ssl_context *ssl ) +{ + int ret = 0; + + if( ssl->state == SSL_HANDSHAKE_OVER ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) ); + + if( ( ret = ssl_flush_output( ssl ) ) != 0 ) + return( ret ); + + switch( ssl->state ) + { + case SSL_HELLO_REQUEST: + ssl->state = SSL_CLIENT_HELLO; + break; + + /* + * <== ClientHello + */ + case SSL_CLIENT_HELLO: + ret = ssl_parse_client_hello( ssl ); + break; + + /* + * ==> ServerHello + * Certificate + * ( ServerKeyExchange ) + * ( CertificateRequest ) + * ServerHelloDone + */ + case SSL_SERVER_HELLO: + ret = ssl_write_server_hello( ssl ); + break; + + case SSL_SERVER_CERTIFICATE: + ret = ssl_write_certificate( ssl ); + break; + + case SSL_SERVER_KEY_EXCHANGE: + ret = ssl_write_server_key_exchange( ssl ); + break; + + case SSL_CERTIFICATE_REQUEST: + ret = ssl_write_certificate_request( ssl ); + break; + + case SSL_SERVER_HELLO_DONE: + ret = ssl_write_server_hello_done( ssl ); + break; + + /* + * <== ( Certificate/Alert ) + * ClientKeyExchange + * ( CertificateVerify ) + * ChangeCipherSpec + * Finished + */ + case SSL_CLIENT_CERTIFICATE: + ret = ssl_parse_certificate( ssl ); + break; + + case SSL_CLIENT_KEY_EXCHANGE: + ret = ssl_parse_client_key_exchange( ssl ); + break; + + case SSL_CERTIFICATE_VERIFY: + ret = ssl_parse_certificate_verify( ssl ); + break; + + case SSL_CLIENT_CHANGE_CIPHER_SPEC: + ret = ssl_parse_change_cipher_spec( ssl ); + break; + + case SSL_CLIENT_FINISHED: + ret = ssl_parse_finished( ssl ); + break; + + /* + * ==> ( NewSessionTicket ) + * ChangeCipherSpec + * Finished + */ + case SSL_SERVER_CHANGE_CIPHER_SPEC: +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( ssl->handshake->new_session_ticket != 0 ) + ret = ssl_write_new_session_ticket( ssl ); + else +#endif + ret = ssl_write_change_cipher_spec( ssl ); + break; + + case SSL_SERVER_FINISHED: + ret = ssl_write_finished( ssl ); + break; + + case SSL_FLUSH_BUFFERS: + SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); + ssl->state = SSL_HANDSHAKE_WRAPUP; + break; + + case SSL_HANDSHAKE_WRAPUP: + ssl_handshake_wrapup( ssl ); + break; + + default: + SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ret ); +} +#endif /* POLARSSL_SSL_SRV_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_tls.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_tls.c new file mode 100644 index 0000000..70b3711 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/ssl_tls.c @@ -0,0 +1,4884 @@ +/* + * SSLv3/TLSv1 shared functions + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The SSL 3.0 specification was drafted by Netscape in 1996, + * and became an IETF standard in 1999. + * + * http://wp.netscape.com/eng/ssl3/ + * http://www.ietf.org/rfc/rfc2246.txt + * http://www.ietf.org/rfc/rfc4346.txt + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SSL_TLS_C) + +#include "polarssl/debug.h" +#include "polarssl/ssl.h" + +#if defined(POLARSSL_X509_CRT_PARSE_C) && \ + defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +#include "polarssl/oid.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include + +#include "hal_crypto.h" + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +/* + * Convert max_fragment_length codes to length. + * RFC 6066 says: + * enum{ + * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) + * } MaxFragmentLength; + * and we add 0 -> extension unused + */ +//static +unsigned int mfl_code_to_length[SSL_MAX_FRAG_LEN_INVALID] = +{ + 16384, /* = SSL_MAX_CONTENT_LEN */ /* SSL_MAX_FRAG_LEN_NONE */ + 512, /* SSL_MAX_FRAG_LEN_512 */ + 1024, /* SSL_MAX_FRAG_LEN_1024 */ + 2048, /* SSL_MAX_FRAG_LEN_2048 */ + 4096, /* SSL_MAX_FRAG_LEN_4096 */ +}; +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +static int ssl_session_copy( ssl_session *dst, const ssl_session *src ) +{ + ssl_session_free( dst ); + memcpy( dst, src, sizeof( ssl_session ) ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + if( src->peer_cert != NULL ) + { + int ret; + + dst->peer_cert = (x509_crt *) polarssl_malloc( sizeof(x509_crt) ); + if( dst->peer_cert == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + x509_crt_init( dst->peer_cert ); + + if( ( ret = x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, + src->peer_cert->raw.len ) ) != 0 ) + { + polarssl_free( dst->peer_cert ); + dst->peer_cert = NULL; + return( ret ); + } + } +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( src->ticket != NULL ) + { + dst->ticket = (unsigned char *) polarssl_malloc( src->ticket_len ); + if( dst->ticket == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + memcpy( dst->ticket, src->ticket, src->ticket_len ); + } +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + + return( 0 ); +} + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) +int (*ssl_hw_record_init)( ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + size_t keylen, + const unsigned char *iv_enc, const unsigned char *iv_dec, + size_t ivlen, + const unsigned char *mac_enc, const unsigned char *mac_dec, + size_t maclen ) = NULL; +int (*ssl_hw_record_activate)( ssl_context *ssl, int direction) = NULL; +int (*ssl_hw_record_reset)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_write)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_read)( ssl_context *ssl ) = NULL; +int (*ssl_hw_record_finish)( ssl_context *ssl ) = NULL; +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ + +/* + * Key material generation + */ +#if defined(POLARSSL_SSL_PROTO_SSL3) +static int ssl3_prf( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t i; + md5_context md5; + sha1_context sha1; + unsigned char padding[16]; + unsigned char sha1sum[20]; + ((void)label); + + md5_init( &md5 ); + sha1_init( &sha1 ); + + /* + * SSLv3: + * block = + * MD5( secret + SHA1( 'A' + secret + random ) ) + + * MD5( secret + SHA1( 'BB' + secret + random ) ) + + * MD5( secret + SHA1( 'CCC' + secret + random ) ) + + * ... + */ + for( i = 0; i < dlen / 16; i++ ) + { + memset( padding, (unsigned char) ('A' + i), 1 + i ); + + sha1_starts( &sha1 ); + sha1_update( &sha1, padding, 1 + i ); + sha1_update( &sha1, secret, slen ); + sha1_update( &sha1, random, rlen ); + sha1_finish( &sha1, sha1sum ); + + md5_starts( &md5 ); + md5_update( &md5, secret, slen ); + md5_update( &md5, sha1sum, 20 ); + md5_finish( &md5, dstbuf + i * 16 ); + } + + md5_free( &md5 ); + sha1_free( &sha1 ); + + polarssl_zeroize( padding, sizeof( padding ) ); + polarssl_zeroize( sha1sum, sizeof( sha1sum ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) +static int tls1_prf( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t nb, hs; + size_t i, j, k; + const unsigned char *S1, *S2; + unsigned char tmp[128]; + unsigned char h_i[20]; + + if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + hs = ( slen + 1 ) / 2; + S1 = secret; + S2 = secret + slen - hs; + + nb = strlen( label ); + memcpy( tmp + 20, label, nb ); + memcpy( tmp + 20 + nb, random, rlen ); + nb += rlen; + + /* + * First compute P_md5(secret,label+random)[0..dlen] + */ + md5_hmac( S1, hs, tmp + 20, nb, 4 + tmp ); + + for( i = 0; i < dlen; i += 16 ) + { + md5_hmac( S1, hs, 4 + tmp, 16 + nb, h_i ); + md5_hmac( S1, hs, 4 + tmp, 16, 4 + tmp ); + + k = ( i + 16 > dlen ) ? dlen % 16 : 16; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = h_i[j]; + } + + /* + * XOR out with P_sha1(secret,label+random)[0..dlen] + */ + sha1_hmac( S2, hs, tmp + 20, nb, tmp ); + + for( i = 0; i < dlen; i += 20 ) + { + sha1_hmac( S2, hs, tmp, 20 + nb, h_i ); + sha1_hmac( S2, hs, tmp, 20, tmp ); + + k = ( i + 20 > dlen ) ? dlen % 20 : 20; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); + } + + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_PROTO_TLS1) || POLARSSL_SSL_PROTO_TLS1_1 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +static int tls_prf_sha256( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t nb; + size_t i, j, k; + unsigned char tmp[128]; + unsigned char h_i[32]; + + if( sizeof( tmp ) < 32 + strlen( label ) + rlen ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + nb = strlen( label ); + memcpy( tmp + 32, label, nb ); + memcpy( tmp + 32 + nb, random, rlen ); + nb += rlen; + + /* + * Compute P_(secret, label + random)[0..dlen] + */ + sha256_hmac( secret, slen, tmp + 32, nb, tmp, 0 ); + + for( i = 0; i < dlen; i += 32 ) + { + sha256_hmac( secret, slen, tmp, 32 + nb, h_i, 0 ); + sha256_hmac( secret, slen, tmp, 32, tmp, 0 ); + + k = ( i + 32 > dlen ) ? dlen % 32 : 32; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = h_i[j]; + } + + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); + + return( 0 ); +} +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) +static int tls_prf_sha384( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t nb; + size_t i, j, k; + unsigned char tmp[128]; + unsigned char h_i[48]; + + if( sizeof( tmp ) < 48 + strlen( label ) + rlen ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + nb = strlen( label ); + memcpy( tmp + 48, label, nb ); + memcpy( tmp + 48 + nb, random, rlen ); + nb += rlen; + + /* + * Compute P_(secret, label + random)[0..dlen] + */ + sha512_hmac( secret, slen, tmp + 48, nb, tmp, 1 ); + + for( i = 0; i < dlen; i += 48 ) + { + sha512_hmac( secret, slen, tmp, 48 + nb, h_i, 1 ); + sha512_hmac( secret, slen, tmp, 48, tmp, 1 ); + + k = ( i + 48 > dlen ) ? dlen % 48 : 48; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = h_i[j]; + } + + polarssl_zeroize( tmp, sizeof( tmp ) ); + polarssl_zeroize( h_i, sizeof( h_i ) ); + + return( 0 ); +} +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +static void ssl_update_checksum_start( ssl_context *, const unsigned char *, size_t ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( ssl_context *, const unsigned char *, size_t ); +#endif + +#if defined(POLARSSL_SSL_PROTO_SSL3) +static void ssl_calc_verify_ssl( ssl_context *, unsigned char * ); +static void ssl_calc_finished_ssl( ssl_context *, unsigned char *, int ); +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) +static void ssl_calc_verify_tls( ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls( ssl_context *, unsigned char *, int ); +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +static void ssl_update_checksum_sha256( ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha256( ssl_context *,unsigned char * ); +static void ssl_calc_finished_tls_sha256( ssl_context *,unsigned char *, int ); +#endif + +#if defined(POLARSSL_SHA512_C) +static void ssl_update_checksum_sha384( ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha384( ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls_sha384( ssl_context *, unsigned char *, int ); +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +int ssl_derive_keys( ssl_context *ssl ) +{ + int ret = 0; + unsigned char tmp[64]; + unsigned char keyblk[256]; + unsigned char *key1; + unsigned char *key2; + unsigned char *mac_enc; + unsigned char *mac_dec; + size_t iv_copy_len; + const cipher_info_t *cipher_info; + const md_info_t *md_info; + + ssl_session *session = ssl->session_negotiate; + ssl_transform *transform = ssl->transform_negotiate; + ssl_handshake_params *handshake = ssl->handshake; + + SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); + + cipher_info = cipher_info_from_type( transform->ciphersuite_info->cipher ); + if( cipher_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", + transform->ciphersuite_info->cipher ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + md_info = md_info_from_type( transform->ciphersuite_info->mac ); + if( md_info == NULL ) + { + SSL_DEBUG_MSG( 1, ( "md info for %d not found", + transform->ciphersuite_info->mac ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions + */ +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + handshake->tls_prf = ssl3_prf; + handshake->calc_verify = ssl_calc_verify_ssl; + handshake->calc_finished = ssl_calc_finished_ssl; + } + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls1_prf; + handshake->calc_verify = ssl_calc_verify_tls; + handshake->calc_finished = ssl_calc_finished_tls; + } + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA512_C) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 && + transform->ciphersuite_info->mac == POLARSSL_MD_SHA384 ) + { + handshake->tls_prf = tls_prf_sha384; + handshake->calc_verify = ssl_calc_verify_tls_sha384; + handshake->calc_finished = ssl_calc_finished_tls_sha384; + } + else +#endif +#if defined(POLARSSL_SHA256_C) + if( ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls_prf_sha256; + handshake->calc_verify = ssl_calc_verify_tls_sha256; + handshake->calc_finished = ssl_calc_finished_tls_sha256; + } + else +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * SSLv3: + * master = + * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) + * + * TLSv1+: + * master = PRF( premaster, "master secret", randbytes )[0..47] + */ + if( handshake->resume == 0 ) + { + SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, + handshake->pmslen ); + + handshake->tls_prf( handshake->premaster, handshake->pmslen, + "master secret", + handshake->randbytes, 64, session->master, 48 ); + + polarssl_zeroize( handshake->premaster, sizeof(handshake->premaster) ); + } + else + SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); + + /* + * Swap the client and server random values. + */ + memcpy( tmp, handshake->randbytes, 64 ); + memcpy( handshake->randbytes, tmp + 32, 32 ); + memcpy( handshake->randbytes + 32, tmp, 32 ); + polarssl_zeroize( tmp, sizeof( tmp ) ); + + /* + * SSLv3: + * key block = + * MD5( master + SHA1( 'A' + master + randbytes ) ) + + * MD5( master + SHA1( 'BB' + master + randbytes ) ) + + * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + + * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + + * ... + * + * TLSv1: + * key block = PRF( master, "key expansion", randbytes ) + */ + handshake->tls_prf( session->master, 48, "key expansion", + handshake->randbytes, 64, keyblk, 256 ); + + SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", + ssl_get_ciphersuite_name( session->ciphersuite ) ) ); + SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); + SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); + SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); + + polarssl_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) ); + + /* + * Determine the appropriate key, IV and MAC length. + */ + + transform->keylen = cipher_info->key_length / 8; + + if( cipher_info->mode == POLARSSL_MODE_GCM || + cipher_info->mode == POLARSSL_MODE_CCM ) + { + transform->maclen = 0; + + transform->ivlen = 12; + transform->fixed_ivlen = 4; + + /* Minimum length is expicit IV + tag */ + transform->minlen = transform->ivlen - transform->fixed_ivlen + + ( transform->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); + } + else + { + int ret; + + /* Initialize HMAC contexts */ + if( ( ret = md_init_ctx( &transform->md_ctx_enc, md_info ) ) != 0 || + ( ret = md_init_ctx( &transform->md_ctx_dec, md_info ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "md_init_ctx", ret ); + return( ret ); + } + + /* Get MAC length */ + transform->maclen = md_get_size( md_info ); + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + /* + * If HMAC is to be truncated, we shall keep the leftmost bytes, + * (rfc 6066 page 13 or rfc 2104 section 4), + * so we only need to adjust the length here. + */ + if( session->trunc_hmac == SSL_TRUNC_HMAC_ENABLED ) + transform->maclen = SSL_TRUNCATED_HMAC_LEN; +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + + /* IV length */ + transform->ivlen = cipher_info->iv_size; + + /* Minimum length */ + if( cipher_info->mode == POLARSSL_MODE_STREAM ) + transform->minlen = transform->maclen; + else + { + /* + * GenericBlockCipher: + * first multiple of blocklen greater than maclen + * + IV except for SSL3 and TLS 1.0 + */ + transform->minlen = transform->maclen + + cipher_info->block_size + - transform->maclen % cipher_info->block_size; + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 || + ssl->minor_ver == SSL_MINOR_VERSION_1 ) + ; /* No need to adjust minlen */ + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == SSL_MINOR_VERSION_2 || + ssl->minor_ver == SSL_MINOR_VERSION_3 ) + { + transform->minlen += transform->ivlen; + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + } + + SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", + transform->keylen, transform->minlen, transform->ivlen, + transform->maclen ) ); + + /* + * Finally setup the cipher contexts, IVs and MAC secrets. + */ + if( ssl->endpoint == SSL_IS_CLIENT ) + { + key1 = keyblk + transform->maclen * 2; + key2 = keyblk + transform->maclen * 2 + transform->keylen; + + mac_enc = keyblk; + mac_dec = keyblk + transform->maclen; + + /* + * This is not used in TLS v1.1. + */ + iv_copy_len = ( transform->fixed_ivlen ) ? + transform->fixed_ivlen : transform->ivlen; + memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, + iv_copy_len ); + } + else + { + key1 = keyblk + transform->maclen * 2 + transform->keylen; + key2 = keyblk + transform->maclen * 2; + + mac_enc = keyblk + transform->maclen; + mac_dec = keyblk; + + /* + * This is not used in TLS v1.1. + */ + iv_copy_len = ( transform->fixed_ivlen ) ? + transform->fixed_ivlen : transform->ivlen; + memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, + iv_copy_len ); + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + if( transform->maclen > sizeof transform->mac_enc ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( transform->mac_enc, mac_enc, transform->maclen ); + memcpy( transform->mac_dec, mac_dec, transform->maclen ); + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) + { + md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen ); + md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen ); + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_init != NULL ) + { + int ret = 0; + + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_init()" ) ); + + if( ( ret = ssl_hw_record_init( ssl, key1, key2, transform->keylen, + transform->iv_enc, transform->iv_dec, + iv_copy_len, + mac_enc, mac_dec, + transform->maclen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_init", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ + + if( ( ret = cipher_init_ctx( &transform->cipher_ctx_enc, + cipher_info ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_init_ctx", ret ); + return( ret ); + } + + if( ( ret = cipher_init_ctx( &transform->cipher_ctx_dec, + cipher_info ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_init_ctx", ret ); + return( ret ); + } + + if( ( ret = cipher_setkey( &transform->cipher_ctx_enc, key1, + cipher_info->key_length, + POLARSSL_ENCRYPT ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_setkey", ret ); + return( ret ); + } + + if( ( ret = cipher_setkey( &transform->cipher_ctx_dec, key2, + cipher_info->key_length, + POLARSSL_DECRYPT ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_setkey", ret ); + return( ret ); + } + +#if defined(POLARSSL_CIPHER_MODE_CBC) + if( cipher_info->mode == POLARSSL_MODE_CBC ) + { + if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_enc, + POLARSSL_PADDING_NONE ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_set_padding_mode", ret ); + return( ret ); + } + + if( ( ret = cipher_set_padding_mode( &transform->cipher_ctx_dec, + POLARSSL_PADDING_NONE ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_set_padding_mode", ret ); + return( ret ); + } + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + polarssl_zeroize( keyblk, sizeof( keyblk ) ); + +#if defined(POLARSSL_ZLIB_SUPPORT) + // Initialize compression + // + if( session->compression == SSL_COMPRESS_DEFLATE ) + { + if( ssl->compress_buf == NULL ) + { + SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); + ssl->compress_buf = polarssl_malloc( SSL_BUFFER_LEN ); + if( ssl->compress_buf == NULL ) + { + SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", + SSL_BUFFER_LEN ) ); + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + } + + SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); + + memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); + memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); + + if( deflateInit( &transform->ctx_deflate, + Z_DEFAULT_COMPRESSION ) != Z_OK || + inflateInit( &transform->ctx_inflate ) != Z_OK ) + { + SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); + return( POLARSSL_ERR_SSL_COMPRESSION_FAILED ); + } + } +#endif /* POLARSSL_ZLIB_SUPPORT */ + + SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); + + return( 0 ); +} + +#if defined(POLARSSL_SSL_PROTO_SSL3) +void ssl_calc_verify_ssl( ssl_context *ssl, unsigned char hash[36] ) +{ + md5_context md5; + sha1_context sha1; + unsigned char pad_1[48]; + unsigned char pad_2[48]; + + SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); + + memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) ); + memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) ); + + memset( pad_1, 0x36, 48 ); + memset( pad_2, 0x5C, 48 ); + + md5_update( &md5, ssl->session_negotiate->master, 48 ); + md5_update( &md5, pad_1, 48 ); + md5_finish( &md5, hash ); + + md5_starts( &md5 ); + md5_update( &md5, ssl->session_negotiate->master, 48 ); + md5_update( &md5, pad_2, 48 ); + md5_update( &md5, hash, 16 ); + md5_finish( &md5, hash ); + + sha1_update( &sha1, ssl->session_negotiate->master, 48 ); + sha1_update( &sha1, pad_1, 40 ); + sha1_finish( &sha1, hash + 16 ); + + sha1_starts( &sha1 ); + sha1_update( &sha1, ssl->session_negotiate->master, 48 ); + sha1_update( &sha1, pad_2, 40 ); + sha1_update( &sha1, hash + 16, 20 ); + sha1_finish( &sha1, hash + 16 ); + + SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); + SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + md5_free( &md5 ); + sha1_free( &sha1 ); + + return; +} +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) +void ssl_calc_verify_tls( ssl_context *ssl, unsigned char hash[36] ) +{ + md5_context md5; + sha1_context sha1; + + SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); + + memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) ); + memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) ); + + md5_finish( &md5, hash ); + sha1_finish( &sha1, hash + 16 ); + + SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); + SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + md5_free( &md5 ); + sha1_free( &sha1 ); + + return; +} +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +void ssl_calc_verify_tls_sha256( ssl_context *ssl, unsigned char hash[32] ) +{ + sha256_context sha256; + + SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); + + memcpy( &sha256, &ssl->handshake->fin_sha256, sizeof(sha256_context) ); + sha256_finish( &sha256, hash ); + + SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); + SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + sha256_free( &sha256 ); + + return; +} +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) +void ssl_calc_verify_tls_sha384( ssl_context *ssl, unsigned char hash[48] ) +{ + sha512_context sha512; + + SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); + + memcpy( &sha512, &ssl->handshake->fin_sha512, sizeof(sha512_context) ); + sha512_finish( &sha512, hash ); + + SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); + SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + sha512_free( &sha512 ); + + return; +} +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +int ssl_psk_derive_premaster( ssl_context *ssl, key_exchange_type_t key_ex ) +{ + unsigned char *p = ssl->handshake->premaster; + unsigned char *end = p + sizeof( ssl->handshake->premaster ); + + /* + * PMS = struct { + * opaque other_secret<0..2^16-1>; + * opaque psk<0..2^16-1>; + * }; + * with "other_secret" depending on the particular key exchange + */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_PSK ) + { + if( end - p < 2 + (int) ssl->psk_len ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( ssl->psk_len >> 8 ); + *(p++) = (unsigned char)( ssl->psk_len ); + p += ssl->psk_len; + } + else +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_RSA_PSK ) + { + /* + * other_secret already set by the ClientKeyExchange message, + * and is 48 bytes long + */ + *p++ = 0; + *p++ = 48; + p += 48; + } + else +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PKS_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_DHE_PSK ) + { + int ret; + size_t len = end - ( p + 2 ); + + /* Write length only when we know the actual value */ + if( ( ret = dhm_calc_secret( &ssl->handshake->dhm_ctx, + p + 2, &len, + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "dhm_calc_secret", ret ); + return( ret ); + } + *(p++) = (unsigned char)( len >> 8 ); + *(p++) = (unsigned char)( len ); + p += len; + + SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( key_ex == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + int ret; + size_t zlen; + + if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, + p + 2, end - ( p + 2 ), + ssl->f_rng, ssl->p_rng ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret ); + return( ret ); + } + + *(p++) = (unsigned char)( zlen >> 8 ); + *(p++) = (unsigned char)( zlen ); + p += zlen; + + SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + /* opaque psk<0..2^16-1>; */ + if( end - p < 2 + (int) ssl->psk_len ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( ssl->psk_len >> 8 ); + *(p++) = (unsigned char)( ssl->psk_len ); + memcpy( p, ssl->psk, ssl->psk_len ); + p += ssl->psk_len; + + ssl->handshake->pmslen = p - ssl->handshake->premaster; + + return( 0 ); +} +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(POLARSSL_SSL_PROTO_SSL3) +/* + * SSLv3.0 MAC functions + */ +static void ssl_mac( md_context_t *md_ctx, unsigned char *secret, + unsigned char *buf, size_t len, + unsigned char *ctr, int type ) +{ + unsigned char header[11]; + unsigned char padding[48]; + int padlen = 0; + int md_size = md_get_size( md_ctx->md_info ); + int md_type = md_get_type( md_ctx->md_info ); + + if( md_type == POLARSSL_MD_MD5 ) + padlen = 48; + else if( md_type == POLARSSL_MD_SHA1 ) + padlen = 40; + else if( md_type == POLARSSL_MD_SHA256 ) + padlen = 32; + else if( md_type == POLARSSL_MD_SHA384 ) + padlen = 16; + + memcpy( header, ctr, 8 ); + header[ 8] = (unsigned char) type; + header[ 9] = (unsigned char)( len >> 8 ); + header[10] = (unsigned char)( len ); + + memset( padding, 0x36, padlen ); + md_starts( md_ctx ); + md_update( md_ctx, secret, md_size ); + md_update( md_ctx, padding, padlen ); + md_update( md_ctx, header, 11 ); + md_update( md_ctx, buf, len ); + md_finish( md_ctx, buf + len ); + + memset( padding, 0x5C, padlen ); + md_starts( md_ctx ); + md_update( md_ctx, secret, md_size ); + md_update( md_ctx, padding, padlen ); + md_update( md_ctx, buf + len, md_size ); + md_finish( md_ctx, buf + len ); +} +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +/* + * Encryption/decryption functions + */ +static int ssl_encrypt_buf( ssl_context *ssl ) +{ + size_t i; + const cipher_mode_t mode = cipher_get_cipher_mode( + &ssl->transform_out->cipher_ctx_enc ); + + SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); + + /* + * Add MAC before encrypt, except for AEAD modes + */ +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ + ( defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) || defined(POLARSSL_DES_C) ) ) + if( mode != POLARSSL_MODE_GCM && + mode != POLARSSL_MODE_CCM ) + { +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + ssl_mac( &ssl->transform_out->md_ctx_enc, + ssl->transform_out->mac_enc, + ssl->out_msg, ssl->out_msglen, + ssl->out_ctr, ssl->out_msgtype ); + } + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) + { + md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 13 ); + md_hmac_update( &ssl->transform_out->md_ctx_enc, + ssl->out_msg, ssl->out_msglen ); + md_hmac_finish( &ssl->transform_out->md_ctx_enc, + ssl->out_msg + ssl->out_msglen ); + md_hmac_reset( &ssl->transform_out->md_ctx_enc ); + } + else +#endif + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_BUF( 4, "computed mac", + ssl->out_msg + ssl->out_msglen, + ssl->transform_out->maclen ); + + ssl->out_msglen += ssl->transform_out->maclen; + } +#endif /* AEAD not the only option */ + + /* + * Encrypt + */ +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) + if( mode == POLARSSL_MODE_STREAM ) + { + int ret; + size_t olen = 0; + + SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); + + SSL_DEBUG_BUF( 4, "before encrypt: output payload", + ssl->out_msg, ssl->out_msglen ); + + if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + ssl->out_msg, ssl->out_msglen, + ssl->out_msg, &olen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); + return( ret ); + } + + if( ssl->out_msglen != olen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */ +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) + if( mode == POLARSSL_MODE_GCM || + mode == POLARSSL_MODE_CCM ) + { + int ret; + size_t enc_msglen, olen; + unsigned char *enc_msg; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_out->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; + + memcpy( add_data, ssl->out_ctr, 8 ); + add_data[8] = ssl->out_msgtype; + add_data[9] = ssl->major_ver; + add_data[10] = ssl->minor_ver; + add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->out_msglen & 0xFF; + + SSL_DEBUG_BUF( 4, "additional data used for AEAD", + add_data, 13 ); + + /* + * Generate IV + */ + ret = ssl->f_rng( ssl->p_rng, + ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + if( ret != 0 ) + return( ret ); + + memcpy( ssl->out_iv, + ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + + SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen - + ssl->transform_out->fixed_ivlen; + + SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); + + SSL_DEBUG_BUF( 4, "before encrypt: output payload", + ssl->out_msg, ssl->out_msglen ); + + /* + * Encrypt and authenticate + */ + if( ( ret = cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + add_data, 13, + enc_msg, enc_msglen, + enc_msg, &olen, + enc_msg + enc_msglen, taglen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_auth_encrypt", ret ); + return( ret ); + } + + if( olen != enc_msglen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->out_msglen += taglen; + + SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); + } + else +#endif /* POLARSSL_GCM_C || POLARSSL_CCM_C */ +#if defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) || defined(POLARSSL_DES_C) ) + if( mode == POLARSSL_MODE_CBC ) + { + int ret; + unsigned char *enc_msg; + size_t enc_msglen, padlen, olen = 0; + + padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % + ssl->transform_out->ivlen; + if( padlen == ssl->transform_out->ivlen ) + padlen = 0; + + for( i = 0; i <= padlen; i++ ) + ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; + + ssl->out_msglen += padlen + 1; + + enc_msglen = ssl->out_msglen; + enc_msg = ssl->out_msg; + +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + /* + * Prepend per-record IV for block cipher in TLS v1.1 and up as per + * Method 1 (6.2.3.2. in RFC4346 and RFC5246) + */ + if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) + { + /* + * Generate IV + */ + int ret = ssl->f_rng( ssl->p_rng, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); + if( ret != 0 ) + return( ret ); + + memcpy( ssl->out_iv, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); + + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen; + } +#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */ + + SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of IV and %d bytes of padding", + ssl->out_msglen, ssl->transform_out->ivlen, + padlen + 1 ) ); + + SSL_DEBUG_BUF( 4, "before encrypt: output payload", + ssl->out_iv, ssl->out_msglen ); + + if( ( ret = cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + enc_msg, enc_msglen, + enc_msg, &olen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); + return( ret ); + } + + if( enc_msglen != olen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) + if( ssl->minor_ver < SSL_MINOR_VERSION_2 ) + { + /* + * Save IV in SSL3 and TLS1 + */ + memcpy( ssl->transform_out->iv_enc, + ssl->transform_out->cipher_ctx_enc.iv, + ssl->transform_out->ivlen ); + } +#endif + } + else +#endif /* POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + for( i = 8; i > 0; i-- ) + if( ++ssl->out_ctr[i - 1] != 0 ) + break; + + /* The loops goes to its end iff the counter is wrapping */ + if( i == 0 ) + { + SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); + return( POLARSSL_ERR_SSL_COUNTER_WRAPPING ); + } + + SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); + + return( 0 ); +} + +#define POLARSSL_SSL_MAX_MAC_SIZE 48 + +static int ssl_decrypt_buf( ssl_context *ssl ) +{ + size_t i; + const cipher_mode_t mode = cipher_get_cipher_mode( + &ssl->transform_in->cipher_ctx_dec ); +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ + ( defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) || defined(POLARSSL_DES_C) ) ) + size_t padlen = 0, correct = 1; +#endif + + SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); + + if( ssl->in_msglen < ssl->transform_in->minlen ) + { + SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", + ssl->in_msglen, ssl->transform_in->minlen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) + if( mode == POLARSSL_MODE_STREAM ) + { + int ret; + size_t olen = 0; + + padlen = 0; + + if( ( ret = cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + ssl->in_msg, ssl->in_msglen, + ssl->in_msg, &olen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); + return( ret ); + } + + if( ssl->in_msglen != olen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* POLARSSL_ARC4_C || POLARSSL_CIPHER_NULL_CIPHER */ +#if defined(POLARSSL_GCM_C) || defined(POLARSSL_CCM_C) + if( mode == POLARSSL_MODE_GCM || + mode == POLARSSL_MODE_CCM ) + { + int ret; + size_t dec_msglen, olen; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_in->ciphersuite_info->flags & + POLARSSL_CIPHERSUITE_SHORT_TAG ? 8 : 16; + unsigned char explicit_iv_len = ssl->transform_in->ivlen - + ssl->transform_in->fixed_ivlen; + + if( ssl->in_msglen < explicit_iv_len + taglen ) + { + SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " + "+ taglen (%d)", ssl->in_msglen, + explicit_iv_len, taglen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; + + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + ssl->in_msglen = dec_msglen; + + memcpy( add_data, ssl->in_ctr, 8 ); + add_data[8] = ssl->in_msgtype; + add_data[9] = ssl->major_ver; + add_data[10] = ssl->minor_ver; + add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->in_msglen & 0xFF; + + SSL_DEBUG_BUF( 4, "additional data used for AEAD", + add_data, 13 ); + + memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, + ssl->in_iv, + ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen ); + + SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, + ssl->transform_in->ivlen ); + SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); + + /* + * Decrypt and authenticate + */ + if( ( ret = cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + add_data, 13, + dec_msg, dec_msglen, + dec_msg_result, &olen, + dec_msg + dec_msglen, taglen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_auth_decrypt", ret ); + + if( ret == POLARSSL_ERR_CIPHER_AUTH_FAILED ) + return( POLARSSL_ERR_SSL_INVALID_MAC ); + + return( ret ); + } + + if( olen != dec_msglen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* POLARSSL_GCM_C || POLARSSL_CCM_C */ +#if defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) || defined(POLARSSL_DES_C) ) + if( mode == POLARSSL_MODE_CBC ) + { + /* + * Decrypt and check the padding + */ + int ret; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + size_t dec_msglen; + size_t minlen = 0; + size_t olen = 0; + + /* + * Check immediate ciphertext sanity + */ + if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) + { + SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", + ssl->in_msglen, ssl->transform_in->ivlen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) + minlen += ssl->transform_in->ivlen; +#endif + + if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || + ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) + { + SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " + "+ 1 ) ( + expl IV )", ssl->in_msglen, + ssl->transform_in->ivlen, + ssl->transform_in->maclen ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + + dec_msglen = ssl->in_msglen; + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + +#if defined(POLARSSL_SSL_PROTO_TLS1_1) || defined(POLARSSL_SSL_PROTO_TLS1_2) + /* + * Initialize for prepended IV for block cipher in TLS v1.1 and up + */ + if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) + { + dec_msglen -= ssl->transform_in->ivlen; + ssl->in_msglen -= ssl->transform_in->ivlen; + + for( i = 0; i < ssl->transform_in->ivlen; i++ ) + ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; + } +#endif /* POLARSSL_SSL_PROTO_TLS1_1 || POLARSSL_SSL_PROTO_TLS1_2 */ + + if( ( ret = cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + dec_msg, dec_msglen, + dec_msg_result, &olen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "cipher_crypt", ret ); + return( ret ); + } + + if( dec_msglen != olen ) + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) + if( ssl->minor_ver < SSL_MINOR_VERSION_2 ) + { + /* + * Save IV in SSL3 and TLS1 + */ + memcpy( ssl->transform_in->iv_dec, + ssl->transform_in->cipher_ctx_dec.iv, + ssl->transform_in->ivlen ); + } +#endif + + padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; + + if( ssl->in_msglen < ssl->transform_in->maclen + padlen ) + { +#if defined(POLARSSL_SSL_DEBUG_ALL) + SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", + ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); +#endif + padlen = 0; + correct = 0; + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + if( padlen > ssl->transform_in->ivlen ) + { +#if defined(POLARSSL_SSL_DEBUG_ALL) + SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " + "should be no more than %d", + padlen, ssl->transform_in->ivlen ) ); +#endif + correct = 0; + } + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > SSL_MINOR_VERSION_0 ) + { + /* + * TLSv1+: always check the padding up to the first failure + * and fake check up to 256 bytes of padding + */ + size_t pad_count = 0, real_count = 1; + size_t padding_idx = ssl->in_msglen - padlen - 1; + + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen >= ssl->in_msglen + * + * 2. padding_idx >= SSL_MAX_CONTENT_LEN + + * ssl->transform_in->maclen + * + * In both cases we reset padding_idx to a safe value (0) to + * prevent out-of-buffer reads. + */ + correct &= ( ssl->in_msglen >= padlen + 1 ); + correct &= ( padding_idx < SSL_MAX_CONTENT_LEN + + ssl->transform_in->maclen ); + + padding_idx *= correct; + + for( i = 1; i <= 256; i++ ) + { + real_count &= ( i <= padlen ); + pad_count += real_count * + ( ssl->in_msg[padding_idx + i] == padlen - 1 ); + } + + correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ + +#if defined(POLARSSL_SSL_DEBUG_ALL) + if( padlen > 0 && correct == 0 ) + SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); +#endif + padlen &= correct * 0x1FF; + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* POLARSSL_CIPHER_MODE_CBC && + ( POLARSSL_AES_C || POLARSSL_CAMELLIA_C ) */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_BUF( 4, "raw buffer after decryption", + ssl->in_msg, ssl->in_msglen ); + + /* + * Always compute the MAC (RFC4346, CBCTIME), except for AEAD of course + */ +#if defined(POLARSSL_ARC4_C) || defined(POLARSSL_CIPHER_NULL_CIPHER) || \ + ( defined(POLARSSL_CIPHER_MODE_CBC) && \ + ( defined(POLARSSL_AES_C) || defined(POLARSSL_CAMELLIA_C) || defined(POLARSSL_DES_C) ) ) + if( mode != POLARSSL_MODE_GCM && + mode != POLARSSL_MODE_CCM ) + { + unsigned char tmp[POLARSSL_SSL_MAX_MAC_SIZE]; + + ssl->in_msglen -= ( ssl->transform_in->maclen + padlen ); + + ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 ); + ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen ); + + memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + ssl_mac( &ssl->transform_in->md_ctx_dec, + ssl->transform_in->mac_dec, + ssl->in_msg, ssl->in_msglen, + ssl->in_ctr, ssl->in_msgtype ); + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > SSL_MINOR_VERSION_0 ) + { + /* + * Process MAC and always update for padlen afterwards to make + * total time independent of padlen + * + * extra_run compensates MAC check for padlen + * + * Known timing attacks: + * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) + * + * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values + * correctly. (We round down instead of up, so -56 is the correct + * value for our calculations instead of -55) + */ + size_t j, extra_run = 0; + extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - + ( 13 + ssl->in_msglen + 8 ) / 64; + + extra_run &= correct * 0xFF; + + md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 13 ); + md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, + ssl->in_msglen ); + md_hmac_finish( &ssl->transform_in->md_ctx_dec, + ssl->in_msg + ssl->in_msglen ); + for( j = 0; j < extra_run; j++ ) + md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); + + md_hmac_reset( &ssl->transform_in->md_ctx_dec ); + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + + SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen ); + SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ); + + if( safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ) != 0 ) + { +#if defined(POLARSSL_SSL_DEBUG_ALL) + SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); +#endif + correct = 0; + } + + /* + * Finally check the correct flag + */ + if( correct == 0 ) + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } +#endif /* AEAD not the only option */ + + if( ssl->in_msglen == 0 ) + { + ssl->nb_zero++; + + /* + * Three or more empty messages may be a DoS attack + * (excessive CPU consumption). + */ + if( ssl->nb_zero > 3 ) + { + SSL_DEBUG_MSG( 1, ( "received four consecutive empty " + "messages, possible DoS attack" ) ); + return( POLARSSL_ERR_SSL_INVALID_MAC ); + } + } + else + ssl->nb_zero = 0; + + for( i = 8; i > 0; i-- ) + if( ++ssl->in_ctr[i - 1] != 0 ) + break; + + /* The loops goes to its end iff the counter is wrapping */ + if( i == 0 ) + { + SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); + return( POLARSSL_ERR_SSL_COUNTER_WRAPPING ); + } + + SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); + + return( 0 ); +} + +#if defined(POLARSSL_ZLIB_SUPPORT) +/* + * Compression/decompression functions + */ +static int ssl_compress_buf( ssl_context *ssl ) +{ + int ret; + unsigned char *msg_post = ssl->out_msg; + size_t len_pre = ssl->out_msglen; + unsigned char *msg_pre = ssl->compress_buf; + + SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); + + if( len_pre == 0 ) + return( 0 ); + + memcpy( msg_pre, ssl->out_msg, len_pre ); + + SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", + ssl->out_msglen ) ); + + SSL_DEBUG_BUF( 4, "before compression: output payload", + ssl->out_msg, ssl->out_msglen ); + + ssl->transform_out->ctx_deflate.next_in = msg_pre; + ssl->transform_out->ctx_deflate.avail_in = len_pre; + ssl->transform_out->ctx_deflate.next_out = msg_post; + ssl->transform_out->ctx_deflate.avail_out = SSL_BUFFER_LEN; + + ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); + if( ret != Z_OK ) + { + SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); + return( POLARSSL_ERR_SSL_COMPRESSION_FAILED ); + } + + ssl->out_msglen = SSL_BUFFER_LEN - + ssl->transform_out->ctx_deflate.avail_out; + + SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", + ssl->out_msglen ) ); + + SSL_DEBUG_BUF( 4, "after compression: output payload", + ssl->out_msg, ssl->out_msglen ); + + SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); + + return( 0 ); +} + +static int ssl_decompress_buf( ssl_context *ssl ) +{ + int ret; + unsigned char *msg_post = ssl->in_msg; + size_t len_pre = ssl->in_msglen; + unsigned char *msg_pre = ssl->compress_buf; + + SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); + + if( len_pre == 0 ) + return( 0 ); + + memcpy( msg_pre, ssl->in_msg, len_pre ); + + SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", + ssl->in_msglen ) ); + + SSL_DEBUG_BUF( 4, "before decompression: input payload", + ssl->in_msg, ssl->in_msglen ); + + ssl->transform_in->ctx_inflate.next_in = msg_pre; + ssl->transform_in->ctx_inflate.avail_in = len_pre; + ssl->transform_in->ctx_inflate.next_out = msg_post; + ssl->transform_in->ctx_inflate.avail_out = SSL_MAX_CONTENT_LEN; + + ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); + if( ret != Z_OK ) + { + SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); + return( POLARSSL_ERR_SSL_COMPRESSION_FAILED ); + } + + ssl->in_msglen = SSL_MAX_CONTENT_LEN - + ssl->transform_in->ctx_inflate.avail_out; + + SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", + ssl->in_msglen ) ); + + SSL_DEBUG_BUF( 4, "after decompression: input payload", + ssl->in_msg, ssl->in_msglen ); + + SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); + + return( 0 ); +} +#endif /* POLARSSL_ZLIB_SUPPORT */ + +/* + * Fill the input message buffer + */ +int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) +{ + int ret; + size_t len; + + SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); + + if( nb_want > SSL_BUFFER_LEN - 8 ) + { + SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + while( ssl->in_left < nb_want ) + { + len = nb_want - ssl->in_left; + ret = ssl->f_recv( ssl->p_recv, ssl->in_hdr + ssl->in_left, len ); + + SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", + ssl->in_left, nb_want ) ); + SSL_DEBUG_RET( 2, "ssl->f_recv", ret ); + + if( ret == 0 ) + return( POLARSSL_ERR_SSL_CONN_EOF ); + + if( ret < 0 ) + return( ret ); + + ssl->in_left += ret; + } + + SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); + + return( 0 ); +} + +/* + * Flush any data not yet written + */ +int ssl_flush_output( ssl_context *ssl ) +{ + int ret; + unsigned char *buf; + + SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); + + while( ssl->out_left > 0 ) + { + SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", + 5 + ssl->out_msglen, ssl->out_left ) ); + + buf = ssl->out_hdr + 5 + ssl->out_msglen - ssl->out_left; + ret = ssl->f_send( ssl->p_send, buf, ssl->out_left ); + + SSL_DEBUG_RET( 2, "ssl->f_send", ret ); + + if( ret <= 0 ) + return( ret ); + + ssl->out_left -= ret; + } + + SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); + + return( 0 ); +} + +/* + * Record layer functions + */ +int ssl_write_record( ssl_context *ssl ) +{ + int ret, done = 0; + size_t len = ssl->out_msglen; + + SSL_DEBUG_MSG( 2, ( "=> write record" ) ); + + if( ssl->out_msgtype == SSL_MSG_HANDSHAKE ) + { + ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 ); + ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 ); + ssl->out_msg[3] = (unsigned char)( ( len - 4 ) ); + + if( ssl->out_msg[0] != SSL_HS_HELLO_REQUEST ) + ssl->handshake->update_checksum( ssl, ssl->out_msg, len ); + } + +#if defined(POLARSSL_ZLIB_SUPPORT) + if( ssl->transform_out != NULL && + ssl->session_out->compression == SSL_COMPRESS_DEFLATE ) + { + if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); + return( ret ); + } + + len = ssl->out_msglen; + } +#endif /*POLARSSL_ZLIB_SUPPORT */ + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_write != NULL ) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_write()" ) ); + + ret = ssl_hw_record_write( ssl ); + if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_write", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( ret == 0 ) + done = 1; + } +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ + if( !done ) + { + ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + ssl->out_hdr[1] = (unsigned char) ssl->major_ver; + ssl->out_hdr[2] = (unsigned char) ssl->minor_ver; + ssl->out_hdr[3] = (unsigned char)( len >> 8 ); + ssl->out_hdr[4] = (unsigned char)( len ); + + if( ssl->transform_out != NULL ) + { + if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); + return( ret ); + } + + len = ssl->out_msglen; + ssl->out_hdr[3] = (unsigned char)( len >> 8 ); + ssl->out_hdr[4] = (unsigned char)( len ); + } + + ssl->out_left = 5 + ssl->out_msglen; + + SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], + ( ssl->out_hdr[3] << 8 ) | ssl->out_hdr[4] ) ); + + SSL_DEBUG_BUF( 4, "output record sent to network", + ssl->out_hdr, 5 + ssl->out_msglen ); + } + + if( ( ret = ssl_flush_output( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_flush_output", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write record" ) ); + + return( 0 ); +} + +int ssl_read_record( ssl_context *ssl ) +{ + int ret, done = 0; + + SSL_DEBUG_MSG( 2, ( "=> read record" ) ); + + if( ssl->in_hslen != 0 && + ssl->in_hslen < ssl->in_msglen ) + { + /* + * Get next Handshake message in the current record + */ + ssl->in_msglen -= ssl->in_hslen; + + memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, + ssl->in_msglen ); + + ssl->in_hslen = 4; + ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3]; + + SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" + " %d, type = %d, hslen = %d", + ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); + + if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad handshake length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->in_msglen < ssl->in_hslen ) + { + SSL_DEBUG_MSG( 1, ( "bad handshake length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->state != SSL_HANDSHAKE_OVER ) + ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + + return( 0 ); + } + + ssl->in_hslen = 0; + + /* + * Read the record header and validate it + */ + if( ( ret = ssl_fetch_input( ssl, 5 ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); + return( ret ); + } + + ssl->in_msgtype = ssl->in_hdr[0]; + ssl->in_msglen = ( ssl->in_hdr[3] << 8 ) | ssl->in_hdr[4]; + + SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->in_hdr[0], ssl->in_hdr[1], ssl->in_hdr[2], + ( ssl->in_hdr[3] << 8 ) | ssl->in_hdr[4] ) ); + + if( ssl->in_hdr[1] != ssl->major_ver ) + { + SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->in_hdr[2] > ssl->max_minor_ver ) + { + SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + /* Sanity check (outer boundaries) */ + if( ssl->in_msglen < 1 || ssl->in_msglen > SSL_BUFFER_LEN - 13 ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + /* + * Make sure the message length is acceptable for the current transform + * and protocol version. + */ + if( ssl->transform_in == NULL ) + { + if( ssl->in_msglen > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + } + else + { + if( ssl->in_msglen < ssl->transform_in->minlen ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 && + ssl->in_msglen > ssl->transform_in->minlen + SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + /* + * TLS encrypted messages can have up to 256 bytes of padding + */ + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 && + ssl->in_msglen > ssl->transform_in->minlen + + SSL_MAX_CONTENT_LEN + 256 ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } +#endif + } + + /* + * Read and optionally decrypt the message contents + */ + if( ( ret = ssl_fetch_input( ssl, 5 + ssl->in_msglen ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_fetch_input", ret ); + return( ret ); + } + + SSL_DEBUG_BUF( 4, "input record from network", + ssl->in_hdr, 5 + ssl->in_msglen ); + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_read != NULL ) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_read()" ) ); + + ret = ssl_hw_record_read( ssl ); + if( ret != 0 && ret != POLARSSL_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_read", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( ret == 0 ) + done = 1; + } +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ + if( !done && ssl->transform_in != NULL ) + { + if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) + { +#if defined(POLARSSL_SSL_ALERT_MESSAGES) + if( ret == POLARSSL_ERR_SSL_INVALID_MAC ) + { + ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_BAD_RECORD_MAC ); + } +#endif + SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); + return( ret ); + } + + SSL_DEBUG_BUF( 4, "input payload after decrypt", + ssl->in_msg, ssl->in_msglen ); + + if( ssl->in_msglen > SSL_MAX_CONTENT_LEN ) + { + SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + } + +#if defined(POLARSSL_ZLIB_SUPPORT) + if( ssl->transform_in != NULL && + ssl->session_in->compression == SSL_COMPRESS_DEFLATE ) + { + if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); + return( ret ); + } + + ssl->in_hdr[3] = (unsigned char)( ssl->in_msglen >> 8 ); + ssl->in_hdr[4] = (unsigned char)( ssl->in_msglen ); + } +#endif /* POLARSSL_ZLIB_SUPPORT */ + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE && + ssl->in_msgtype != SSL_MSG_ALERT && + ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC && + ssl->in_msgtype != SSL_MSG_APPLICATION_DATA ) + { + SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); + + if( ( ret = ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_UNEXPECTED_MESSAGE ) ) != 0 ) + { + return( ret ); + } + + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->in_msgtype == SSL_MSG_HANDSHAKE ) + { + ssl->in_hslen = 4; + ssl->in_hslen += ( ssl->in_msg[2] << 8 ) | ssl->in_msg[3]; + + SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" + " %d, type = %d, hslen = %d", + ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); + + /* + * Additional checks to validate the handshake header + */ + if( ssl->in_msglen < 4 || ssl->in_msg[1] != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad handshake length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->in_msglen < ssl->in_hslen ) + { + SSL_DEBUG_MSG( 1, ( "bad handshake length" ) ); + return( POLARSSL_ERR_SSL_INVALID_RECORD ); + } + + if( ssl->state != SSL_HANDSHAKE_OVER ) + ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + } + + if( ssl->in_msgtype == SSL_MSG_ALERT ) + { + SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", + ssl->in_msg[0], ssl->in_msg[1] ) ); + + /* + * Ignore non-fatal alerts, except close_notify + */ + if( ssl->in_msg[0] == SSL_ALERT_LEVEL_FATAL ) + { + SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", + ssl->in_msg[1] ) ); + /** + * Subtract from error code as ssl->in_msg[1] is 7-bit positive + * error identifier. + */ + return( POLARSSL_ERR_SSL_FATAL_ALERT_MESSAGE ); + } + + if( ssl->in_msg[0] == SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == SSL_ALERT_MSG_CLOSE_NOTIFY ) + { + SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); + return( POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY ); + } + } + + ssl->in_left = 0; + + SSL_DEBUG_MSG( 2, ( "<= read record" ) ); + + return( 0 ); +} + +int ssl_send_fatal_handshake_failure( ssl_context *ssl ) +{ + int ret; + + if( ( ret = ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_FATAL, + SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +int ssl_send_alert_message( ssl_context *ssl, + unsigned char level, + unsigned char message ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); + + ssl->out_msgtype = SSL_MSG_ALERT; + ssl->out_msglen = 2; + ssl->out_msg[0] = level; + ssl->out_msg[1] = message; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); + + return( 0 ); +} + +/* + * Handshake functions + */ +#if !defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +int ssl_write_certificate( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} + +int ssl_parse_certificate( ssl_context *ssl ) +{ + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); +} +#else +int ssl_write_certificate( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, n; + const x509_crt *crt; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->endpoint == SSL_IS_CLIENT ) + { + if( ssl->client_auth == 0 ) + { + SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(POLARSSL_SSL_PROTO_SSL3) + /* + * If using SSLv3 and got no cert, send an Alert message + * (otherwise an empty Certificate message will be sent). + */ + if( ssl_own_cert( ssl ) == NULL && + ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + ssl->out_msglen = 2; + ssl->out_msgtype = SSL_MSG_ALERT; + ssl->out_msg[0] = SSL_ALERT_LEVEL_WARNING; + ssl->out_msg[1] = SSL_ALERT_MSG_NO_CERT; + + SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); + goto write_msg; + } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + } + else /* SSL_IS_SERVER */ + { + if( ssl_own_cert( ssl ) == NULL ) + { + SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) ); + return( POLARSSL_ERR_SSL_CERTIFICATE_REQUIRED ); + } + } + + SSL_DEBUG_CRT( 3, "own certificate", ssl_own_cert( ssl ) ); + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 6 length of all certs + * 7 . 9 length of cert. 1 + * 10 . n-1 peer certificate + * n . n+2 length of cert. 2 + * n+3 . ... upper level cert, etc. + */ + i = 7; + crt = ssl_own_cert( ssl ); + + while( crt != NULL ) + { + n = crt->raw.len; + if( n > SSL_MAX_CONTENT_LEN - 3 - i ) + { + SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", + i + 3 + n, SSL_MAX_CONTENT_LEN ) ); + return( POLARSSL_ERR_SSL_CERTIFICATE_TOO_LARGE ); + } + + ssl->out_msg[i ] = (unsigned char)( n >> 16 ); + ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); + ssl->out_msg[i + 2] = (unsigned char)( n ); + + i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); + i += n; crt = crt->next; + } + + ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); + ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); + ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); + + ssl->out_msglen = i; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_CERTIFICATE; + +#if defined(POLARSSL_SSL_PROTO_SSL3) +write_msg: +#endif + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write certificate" ) ); + + return( ret ); +} + +int ssl_parse_certificate( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, n; + const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); + + if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_PSK ) + { + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->endpoint == SSL_IS_SERVER && + ( ssl->authmode == SSL_VERIFY_NONE || + ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_RSA_PSK ) ) + { + ssl->session_negotiate->verify_result = BADCERT_SKIP_VERIFY; + SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + ssl->state++; + +#if defined(POLARSSL_SSL_PROTO_SSL3) + /* + * Check if the client sent an empty certificate + */ + if( ssl->endpoint == SSL_IS_SERVER && + ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + if( ssl->in_msglen == 2 && + ssl->in_msgtype == SSL_MSG_ALERT && + ssl->in_msg[0] == SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == SSL_ALERT_MSG_NO_CERT ) + { + SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); + + ssl->session_negotiate->verify_result = BADCERT_MISSING; + if( ssl->authmode == SSL_VERIFY_OPTIONAL ) + return( 0 ); + else + return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + } +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->endpoint == SSL_IS_SERVER && + ssl->minor_ver != SSL_MINOR_VERSION_0 ) + { + if( ssl->in_hslen == 7 && + ssl->in_msgtype == SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == SSL_HS_CERTIFICATE && + memcmp( ssl->in_msg + 4, "\0\0\0", 3 ) == 0 ) + { + SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); + + ssl->session_negotiate->verify_result = BADCERT_MISSING; + if( ssl->authmode == SSL_VERIFY_REQUIRED ) + return( POLARSSL_ERR_SSL_NO_CLIENT_CERTIFICATE ); + else + return( 0 ); + } + } +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || \ + POLARSSL_SSL_PROTO_TLS1_2 */ + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->in_msg[0] != SSL_HS_CERTIFICATE || ssl->in_hslen < 10 ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + /* + * Same message structure as in ssl_write_certificate() + */ + n = ( ssl->in_msg[5] << 8 ) | ssl->in_msg[6]; + + if( ssl->in_msg[4] != 0 || ssl->in_hslen != 7 + n ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + /* In case we tried to reuse a session but it failed */ + if( ssl->session_negotiate->peer_cert != NULL ) + { + x509_crt_free( ssl->session_negotiate->peer_cert ); + polarssl_free( ssl->session_negotiate->peer_cert ); + } + + if( ( ssl->session_negotiate->peer_cert = (x509_crt *) polarssl_malloc( + sizeof( x509_crt ) ) ) == NULL ) + { + SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", + sizeof( x509_crt ) ) ); + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + + x509_crt_init( ssl->session_negotiate->peer_cert ); + + i = 7; + + while( i < ssl->in_hslen ) + { + if( ssl->in_msg[i] != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) + | (unsigned int) ssl->in_msg[i + 2]; + i += 3; + + if( n < 128 || i + n > ssl->in_hslen ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + ret = x509_crt_parse_der( ssl->session_negotiate->peer_cert, + ssl->in_msg + i, n ); + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, " x509_crt_parse_der", ret ); + return( ret ); + } + + i += n; + } + + SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); + + /* + * On client, make sure the server cert doesn't change during renego to + * avoid "triple handshake" attack: https://secure-resumption.com/ + */ + if( ssl->endpoint == SSL_IS_CLIENT && + ssl->renegotiation == SSL_RENEGOTIATION ) + { + if( ssl->session->peer_cert == NULL ) + { + SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + if( ssl->session->peer_cert->raw.len != + ssl->session_negotiate->peer_cert->raw.len || + memcmp( ssl->session->peer_cert->raw.p, + ssl->session_negotiate->peer_cert->raw.p, + ssl->session->peer_cert->raw.len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE ); + } + } + + if( ssl->authmode != SSL_VERIFY_NONE ) + { + if( ssl->ca_chain == NULL ) + { + SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); + return( POLARSSL_ERR_SSL_CA_CHAIN_REQUIRED ); + } + + /* + * Main check: verify certificate + */ + ret = x509_crt_verify( ssl->session_negotiate->peer_cert, + ssl->ca_chain, ssl->ca_crl, ssl->peer_cn, + &ssl->session_negotiate->verify_result, + ssl->f_vrfy, ssl->p_vrfy ); + + if( ret != 0 ) + { + SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); + } + + /* + * Secondary checks: always done, but change 'ret' only if it was 0 + */ + +#if defined(POLARSSL_SSL_SET_CURVES) + { + pk_context *pk = &ssl->session_negotiate->peer_cert->pk; + + /* If certificate uses an EC key, make sure the curve is OK */ + if( pk_can_do( pk, POLARSSL_PK_ECKEY ) && + ! ssl_curve_is_acceptable( ssl, pk_ec( *pk )->grp.id ) ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); + if( ret == 0 ) + ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; + } + } +#endif /* POLARSSL_SSL_SET_CURVES */ + + if( ssl_check_cert_usage( ssl->session_negotiate->peer_cert, + ciphersuite_info, + ! ssl->endpoint ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); + if( ret == 0 ) + ret = POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE; + } + + if( ssl->authmode != SSL_VERIFY_REQUIRED ) + ret = 0; + } + + SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); + + return( ret ); +} +#endif /* !POLARSSL_KEY_EXCHANGE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED + !POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED + !POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +int ssl_write_change_cipher_spec( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); + + ssl->out_msgtype = SSL_MSG_CHANGE_CIPHER_SPEC; + ssl->out_msglen = 1; + ssl->out_msg[0] = 1; + + ssl->state++; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); + + return( 0 ); +} + +int ssl_parse_change_cipher_spec( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_CHANGE_CIPHER_SPEC ) + { + SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 ) + { + SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC ); + } + + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); + + return( 0 ); +} + +void ssl_optimize_checksum( ssl_context *ssl, + const ssl_ciphersuite_t *ciphersuite_info ) +{ + ((void) ciphersuite_info); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < SSL_MINOR_VERSION_3 ) + ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; + else +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA512_C) + if( ciphersuite_info->mac == POLARSSL_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha384; + else +#endif +#if defined(POLARSSL_SHA256_C) + if( ciphersuite_info->mac != POLARSSL_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha256; + else +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return; + } +} + +static void ssl_update_checksum_start( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + md5_update( &ssl->handshake->fin_md5 , buf, len ); + sha1_update( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) + sha256_update( &ssl->handshake->fin_sha256, buf, len ); +#endif +#if defined(POLARSSL_SHA512_C) + sha512_update( &ssl->handshake->fin_sha512, buf, len ); +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +} + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + md5_update( &ssl->handshake->fin_md5 , buf, len ); + sha1_update( &ssl->handshake->fin_sha1, buf, len ); +} +#endif + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +static void ssl_update_checksum_sha256( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + sha256_update( &ssl->handshake->fin_sha256, buf, len ); +} +#endif + +#if defined(POLARSSL_SHA512_C) +static void ssl_update_checksum_sha384( ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + sha512_update( &ssl->handshake->fin_sha512, buf, len ); +} +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +#if defined(POLARSSL_SSL_PROTO_SSL3) +static void ssl_calc_finished_ssl( + ssl_context *ssl, unsigned char *buf, int from ) +{ + const char *sender; + md5_context md5; + sha1_context sha1; + + unsigned char padbuf[48]; + unsigned char md5sum[16]; + unsigned char sha1sum[20]; + + ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); + + memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) ); + memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) ); + + /* + * SSLv3: + * hash = + * MD5( master + pad2 + + * MD5( handshake + sender + master + pad1 ) ) + * + SHA1( master + pad2 + + * SHA1( handshake + sender + master + pad1 ) ) + */ + +#if !defined(POLARSSL_MD5_ALT) + SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(POLARSSL_SHA1_ALT) + SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == SSL_IS_CLIENT ) ? "CLNT" + : "SRVR"; + + memset( padbuf, 0x36, 48 ); + + md5_update( &md5, (const unsigned char *) sender, 4 ); + md5_update( &md5, session->master, 48 ); + md5_update( &md5, padbuf, 48 ); + md5_finish( &md5, md5sum ); + + sha1_update( &sha1, (const unsigned char *) sender, 4 ); + sha1_update( &sha1, session->master, 48 ); + sha1_update( &sha1, padbuf, 40 ); + sha1_finish( &sha1, sha1sum ); + + memset( padbuf, 0x5C, 48 ); + + md5_starts( &md5 ); + md5_update( &md5, session->master, 48 ); + md5_update( &md5, padbuf, 48 ); + md5_update( &md5, md5sum, 16 ); + md5_finish( &md5, buf ); + + sha1_starts( &sha1 ); + sha1_update( &sha1, session->master, 48 ); + sha1_update( &sha1, padbuf , 40 ); + sha1_update( &sha1, sha1sum, 20 ); + sha1_finish( &sha1, buf + 16 ); + + SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); + + md5_free( &md5 ); + sha1_free( &sha1 ); + + polarssl_zeroize( padbuf, sizeof( padbuf ) ); + polarssl_zeroize( md5sum, sizeof( md5sum ) ); + polarssl_zeroize( sha1sum, sizeof( sha1sum ) ); + + SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* POLARSSL_SSL_PROTO_SSL3 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) +static void ssl_calc_finished_tls( + ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + md5_context md5; + sha1_context sha1; + unsigned char padbuf[36]; + + ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); + + memcpy( &md5 , &ssl->handshake->fin_md5 , sizeof(md5_context) ); + memcpy( &sha1, &ssl->handshake->fin_sha1, sizeof(sha1_context) ); + + /* + * TLSv1: + * hash = PRF( master, finished_label, + * MD5( handshake ) + SHA1( handshake ) )[0..11] + */ + +#if !defined(POLARSSL_MD5_ALT) + SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(POLARSSL_SHA1_ALT) + SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + md5_finish( &md5, padbuf ); + sha1_finish( &sha1, padbuf + 16 ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 36, buf, len ); + + SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + md5_free( &md5 ); + sha1_free( &sha1 ); + + polarssl_zeroize( padbuf, sizeof( padbuf ) ); + + SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 */ + +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) +static void ssl_calc_finished_tls_sha256( + ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + sha256_context sha256; + unsigned char padbuf[32]; + + ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); + + memcpy( &sha256, &ssl->handshake->fin_sha256, sizeof(sha256_context) ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(POLARSSL_SHA256_ALT) + SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) + sha256.state, sizeof( sha256.state ) ); +#endif + + sender = ( from == SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + sha256_finish( &sha256, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 32, buf, len ); + + SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + sha256_free( &sha256 ); + + polarssl_zeroize( padbuf, sizeof( padbuf ) ); + + SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* POLARSSL_SHA256_C */ + +#if defined(POLARSSL_SHA512_C) +static void ssl_calc_finished_tls_sha384( + ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + sha512_context sha512; + unsigned char padbuf[48]; + + ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); + + memcpy( &sha512, &ssl->handshake->fin_sha512, sizeof(sha512_context) ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(POLARSSL_SHA512_ALT) + SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) + sha512.state, sizeof( sha512.state ) ); +#endif + + sender = ( from == SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + sha512_finish( &sha512, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 48, buf, len ); + + SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + sha512_free( &sha512 ); + + polarssl_zeroize( padbuf, sizeof( padbuf ) ); + + SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* POLARSSL_SHA512_C */ +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + +void ssl_handshake_wrapup( ssl_context *ssl ) +{ + int resume = ssl->handshake->resume; + + SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); + + /* + * Free our handshake params + */ + ssl_handshake_free( ssl->handshake ); + polarssl_free( ssl->handshake ); + ssl->handshake = NULL; + + if( ssl->renegotiation == SSL_RENEGOTIATION ) + { + ssl->renegotiation = SSL_RENEGOTIATION_DONE; + ssl->renego_records_seen = 0; + } + + /* + * Switch in our now active transform context + */ + if( ssl->transform ) + { + ssl_transform_free( ssl->transform ); + polarssl_free( ssl->transform ); + } + ssl->transform = ssl->transform_negotiate; + ssl->transform_negotiate = NULL; + + if( ssl->session ) + { + ssl_session_free( ssl->session ); + polarssl_free( ssl->session ); + } + ssl->session = ssl->session_negotiate; + ssl->session_negotiate = NULL; + + /* + * Add cache entry + */ + if( ssl->f_set_cache != NULL && + ssl->session->length != 0 && + resume == 0 ) + { + if( ssl->f_set_cache( ssl->p_set_cache, ssl->session ) != 0 ) + SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); + } + + ssl->state++; + + SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); +} + +int ssl_write_finished( ssl_context *ssl ) +{ + int ret, hash_len; + + SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); + + /* + * Set the out_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) + { + ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->out_msg = ssl->out_iv; + + ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->endpoint ); + + // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63) + hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; + + ssl->verify_data_len = hash_len; + memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); + + ssl->out_msglen = 4 + hash_len; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_FINISHED; + + /* + * In case of session resuming, invert the client and server + * ChangeCipherSpec messages order. + */ + if( ssl->handshake->resume != 0 ) + { + if( ssl->endpoint == SSL_IS_CLIENT ) + ssl->state = SSL_HANDSHAKE_WRAPUP; + else + ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC; + } + else + ssl->state++; + + /* + * Switch to our negotiated transform and session parameters for outbound + * data. + */ + SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); + ssl->transform_out = ssl->transform_negotiate; + ssl->session_out = ssl->session_negotiate; + memset( ssl->out_ctr, 0, 8 ); + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_activate != NULL ) + { + if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_OUTBOUND ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); + + return( 0 ); +} + +int ssl_parse_finished( ssl_context *ssl ) +{ + int ret; + unsigned int hash_len; + unsigned char buf[36]; + + SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); + + ssl->handshake->calc_finished( ssl, buf, ssl->endpoint ^ 1 ); + + /* + * Switch to our negotiated transform and session parameters for inbound + * data. + */ + SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); + ssl->transform_in = ssl->transform_negotiate; + ssl->session_in = ssl->session_negotiate; + memset( ssl->in_ctr, 0, 8 ); + + /* + * Set the in_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= SSL_MINOR_VERSION_2 ) + { + ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->in_msg = ssl->in_iv; + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_activate != NULL ) + { + if( ( ret = ssl_hw_record_activate( ssl, SSL_CHANNEL_INBOUND ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_activate", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + // TODO TLS/1.2 Hash length is determined by cipher suite (Page 63) + hash_len = ( ssl->minor_ver == SSL_MINOR_VERSION_0 ) ? 36 : 12; + + if( ssl->in_msg[0] != SSL_HS_FINISHED || + ssl->in_hslen != 4 + hash_len ) + { + SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_FINISHED ); + } + + if( safer_memcmp( ssl->in_msg + 4, buf, hash_len ) != 0 ) + { + SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( POLARSSL_ERR_SSL_BAD_HS_FINISHED ); + } + + ssl->verify_data_len = hash_len; + memcpy( ssl->peer_verify_data, buf, hash_len ); + + if( ssl->handshake->resume != 0 ) + { + if( ssl->endpoint == SSL_IS_CLIENT ) + ssl->state = SSL_CLIENT_CHANGE_CIPHER_SPEC; + + if( ssl->endpoint == SSL_IS_SERVER ) + ssl->state = SSL_HANDSHAKE_WRAPUP; + } + else + ssl->state++; + + SSL_DEBUG_MSG( 2, ( "<= parse finished" ) ); + + return( 0 ); +} + +static void ssl_handshake_params_init( ssl_handshake_params *handshake ) +{ + memset( handshake, 0, sizeof( ssl_handshake_params ) ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) || defined(POLARSSL_SSL_PROTO_TLS1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_1) + md5_init( &handshake->fin_md5 ); + sha1_init( &handshake->fin_sha1 ); + md5_starts( &handshake->fin_md5 ); + sha1_starts( &handshake->fin_sha1 ); +#endif +#if defined(POLARSSL_SSL_PROTO_TLS1_2) +#if defined(POLARSSL_SHA256_C) + sha256_init( &handshake->fin_sha256 ); + sha256_starts( &handshake->fin_sha256, 0 ); +#endif +#if defined(POLARSSL_SHA512_C) + sha512_init( &handshake->fin_sha512 ); + sha512_starts( &handshake->fin_sha512, 1 ); +#endif +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ + + handshake->update_checksum = ssl_update_checksum_start; + handshake->sig_alg = SSL_HASH_SHA1; + +#if defined(POLARSSL_DHM_C) + dhm_init( &handshake->dhm_ctx ); +#endif +#if defined(POLARSSL_ECDH_C) + ecdh_init( &handshake->ecdh_ctx ); +#endif +} + +static void ssl_transform_init( ssl_transform *transform ) +{ + memset( transform, 0, sizeof(ssl_transform) ); + + cipher_init( &transform->cipher_ctx_enc ); + cipher_init( &transform->cipher_ctx_dec ); + + md_init( &transform->md_ctx_enc ); + md_init( &transform->md_ctx_dec ); +} + +void ssl_session_init( ssl_session *session ) +{ + memset( session, 0, sizeof(ssl_session) ); +} + +static int ssl_handshake_init( ssl_context *ssl ) +{ + /* Clear old handshake information if present */ + if( ssl->transform_negotiate ) + ssl_transform_free( ssl->transform_negotiate ); + if( ssl->session_negotiate ) + ssl_session_free( ssl->session_negotiate ); + if( ssl->handshake ) + ssl_handshake_free( ssl->handshake ); + + /* + * Either the pointers are now NULL or cleared properly and can be freed. + * Now allocate missing structures. + */ + if( ssl->transform_negotiate == NULL ) + { + ssl->transform_negotiate = + (ssl_transform *) polarssl_malloc( sizeof(ssl_transform) ); + } + + if( ssl->session_negotiate == NULL ) + { + ssl->session_negotiate = + (ssl_session *) polarssl_malloc( sizeof(ssl_session) ); + } + + if( ssl->handshake == NULL) + { + ssl->handshake = (ssl_handshake_params *) + polarssl_malloc( sizeof(ssl_handshake_params) ); + } + + /* All pointers should exist and can be directly freed without issue */ + if( ssl->handshake == NULL || + ssl->transform_negotiate == NULL || + ssl->session_negotiate == NULL ) + { + SSL_DEBUG_MSG( 1, ( "malloc() of ssl sub-contexts failed" ) ); + + polarssl_free( ssl->handshake ); + polarssl_free( ssl->transform_negotiate ); + polarssl_free( ssl->session_negotiate ); + + ssl->handshake = NULL; + ssl->transform_negotiate = NULL; + ssl->session_negotiate = NULL; + + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + + /* Initialize structures */ + ssl_session_init( ssl->session_negotiate ); + ssl_transform_init( ssl->transform_negotiate ); + ssl_handshake_params_init( ssl->handshake ); + +#if defined(POLARSSL_X509_CRT_PARSE_C) + ssl->handshake->key_cert = ssl->key_cert; +#endif + + return( 0 ); +} + +/* + * Initialize an SSL context + */ +int ssl_init( ssl_context *ssl ) +{ + int ret; + int len = SSL_BUFFER_LEN; + + memset( ssl, 0, sizeof( ssl_context ) ); + + /* + * Sane defaults + */ + ssl->min_major_ver = SSL_MIN_MAJOR_VERSION; + ssl->min_minor_ver = SSL_MIN_MINOR_VERSION; + ssl->max_major_ver = SSL_MAX_MAJOR_VERSION; + ssl->max_minor_ver = SSL_MAX_MINOR_VERSION; + + ssl_set_ciphersuites( ssl, ssl_list_ciphersuites() ); + + ssl->renego_max_records = SSL_RENEGO_MAX_RECORDS_DEFAULT; + +#if defined(POLARSSL_DHM_C) + if( ( ret = mpi_read_string( &ssl->dhm_P, 16, + POLARSSL_DHM_RFC5114_MODP_1024_P) ) != 0 || + ( ret = mpi_read_string( &ssl->dhm_G, 16, + POLARSSL_DHM_RFC5114_MODP_1024_G) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_read_string", ret ); + return( ret ); + } +#endif + + /* + * Prepare base structures + */ + ssl->in_ctr = (unsigned char *) polarssl_malloc( len ); + ssl->in_hdr = ssl->in_ctr + 8; + ssl->in_iv = ssl->in_ctr + 13; + ssl->in_msg = ssl->in_ctr + 13; + + if( ssl->in_ctr == NULL ) + { + SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) ); + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + + ssl->out_ctr = (unsigned char *) polarssl_malloc( len ); + ssl->out_hdr = ssl->out_ctr + 8; + ssl->out_iv = ssl->out_ctr + 13; + ssl->out_msg = ssl->out_ctr + 13; + + if( ssl->out_ctr == NULL ) + { + SSL_DEBUG_MSG( 1, ( "malloc(%d bytes) failed", len ) ); + polarssl_free( ssl->in_ctr ); + ssl->in_ctr = NULL; + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + } + + memset( ssl-> in_ctr, 0, SSL_BUFFER_LEN ); + memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + ssl->ticket_lifetime = SSL_DEFAULT_TICKET_LIFETIME; +#endif + +#if defined(POLARSSL_SSL_SET_CURVES) + ssl->curve_list = ecp_grp_id_list( ); +#endif + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + /* + move the cryptoEngine from main to here + */ + if ( rtl_cryptoEngine_init() != 0 ) { + DiagPrintf("crypto engine init failed\r\n"); + } + + + return( 0 ); +} + +/* + * Reset an initialized and used SSL context for re-use while retaining + * all application-set variables, function pointers and data. + */ +int ssl_session_reset( ssl_context *ssl ) +{ + int ret; + + ssl->state = SSL_HELLO_REQUEST; + ssl->renegotiation = SSL_INITIAL_HANDSHAKE; + ssl->secure_renegotiation = SSL_LEGACY_RENEGOTIATION; + + ssl->verify_data_len = 0; + memset( ssl->own_verify_data, 0, 36 ); + memset( ssl->peer_verify_data, 0, 36 ); + + ssl->in_offt = NULL; + + ssl->in_msg = ssl->in_ctr + 13; + ssl->in_msgtype = 0; + ssl->in_msglen = 0; + ssl->in_left = 0; + + ssl->in_hslen = 0; + ssl->nb_zero = 0; + ssl->record_read = 0; + + ssl->out_msg = ssl->out_ctr + 13; + ssl->out_msgtype = 0; + ssl->out_msglen = 0; + ssl->out_left = 0; + + ssl->transform_in = NULL; + ssl->transform_out = NULL; + + ssl->renego_records_seen = 0; + + memset( ssl->out_ctr, 0, SSL_BUFFER_LEN ); + memset( ssl->in_ctr, 0, SSL_BUFFER_LEN ); + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_reset != NULL ) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_reset()" ) ); + if( ( ret = ssl_hw_record_reset( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_hw_record_reset", ret ); + return( POLARSSL_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + + if( ssl->transform ) + { + ssl_transform_free( ssl->transform ); + polarssl_free( ssl->transform ); + ssl->transform = NULL; + } + + if( ssl->session ) + { + ssl_session_free( ssl->session ); + polarssl_free( ssl->session ); + ssl->session = NULL; + } + +#if defined(POLARSSL_SSL_ALPN) + ssl->alpn_chosen = NULL; +#endif + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +static void ssl_ticket_keys_free( ssl_ticket_keys *tkeys ) +{ + aes_free( &tkeys->enc ); + aes_free( &tkeys->dec ); + + polarssl_zeroize( tkeys, sizeof(ssl_ticket_keys) ); +} + +/* + * Allocate and initialize ticket keys + */ +static int ssl_ticket_keys_init( ssl_context *ssl ) +{ + int ret; + ssl_ticket_keys *tkeys; + unsigned char buf[16]; + + if( ssl->ticket_keys != NULL ) + return( 0 ); + + tkeys = (ssl_ticket_keys *) polarssl_malloc( sizeof(ssl_ticket_keys) ); + if( tkeys == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + aes_init( &tkeys->enc ); + aes_init( &tkeys->dec ); + + if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->key_name, 16 ) ) != 0 ) + { + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); + return( ret ); + } + + if( ( ret = ssl->f_rng( ssl->p_rng, buf, 16 ) ) != 0 || + ( ret = aes_setkey_enc( &tkeys->enc, buf, 128 ) ) != 0 || + ( ret = aes_setkey_dec( &tkeys->dec, buf, 128 ) ) != 0 ) + { + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); + return( ret ); + } + + if( ( ret = ssl->f_rng( ssl->p_rng, tkeys->mac_key, 16 ) ) != 0 ) + { + ssl_ticket_keys_free( tkeys ); + polarssl_free( tkeys ); + return( ret ); + } + + ssl->ticket_keys = tkeys; + + return( 0 ); +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +/* + * SSL set accessors + */ +void ssl_set_endpoint( ssl_context *ssl, int endpoint ) +{ + ssl->endpoint = endpoint; + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( endpoint == SSL_IS_CLIENT ) + ssl->session_tickets = SSL_SESSION_TICKETS_ENABLED; +#endif +} + +void ssl_set_authmode( ssl_context *ssl, int authmode ) +{ + ssl->authmode = authmode; +} + +#if defined(POLARSSL_X509_CRT_PARSE_C) +void ssl_set_verify( ssl_context *ssl, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ) +{ + ssl->f_vrfy = f_vrfy; + ssl->p_vrfy = p_vrfy; +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +void ssl_set_rng( ssl_context *ssl, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + ssl->f_rng = f_rng; + ssl->p_rng = p_rng; +} + +void ssl_set_dbg( ssl_context *ssl, + void (*f_dbg)(void *, int, const char *), + void *p_dbg ) +{ + ssl->f_dbg = f_dbg; + ssl->p_dbg = p_dbg; +} + +void ssl_set_bio( ssl_context *ssl, + int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, + int (*f_send)(void *, const unsigned char *, size_t), void *p_send ) +{ + ssl->f_recv = f_recv; + ssl->f_send = f_send; + ssl->p_recv = p_recv; + ssl->p_send = p_send; +} + +void ssl_set_session_cache( ssl_context *ssl, + int (*f_get_cache)(void *, ssl_session *), void *p_get_cache, + int (*f_set_cache)(void *, const ssl_session *), void *p_set_cache ) +{ + ssl->f_get_cache = f_get_cache; + ssl->p_get_cache = p_get_cache; + ssl->f_set_cache = f_set_cache; + ssl->p_set_cache = p_set_cache; +} + +int ssl_set_session( ssl_context *ssl, const ssl_session *session ) +{ + int ret; + + if( ssl == NULL || + session == NULL || + ssl->session_negotiate == NULL || + ssl->endpoint != SSL_IS_CLIENT ) + { + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 ) + return( ret ); + + ssl->handshake->resume = 1; + + return( 0 ); +} + +void ssl_set_ciphersuites( ssl_context *ssl, const int *ciphersuites ) +{ + ssl->ciphersuite_list[SSL_MINOR_VERSION_0] = ciphersuites; + ssl->ciphersuite_list[SSL_MINOR_VERSION_1] = ciphersuites; + ssl->ciphersuite_list[SSL_MINOR_VERSION_2] = ciphersuites; + ssl->ciphersuite_list[SSL_MINOR_VERSION_3] = ciphersuites; +} + +void ssl_set_ciphersuites_for_version( ssl_context *ssl, + const int *ciphersuites, + int major, int minor ) +{ + if( major != SSL_MAJOR_VERSION_3 ) + return; + + if( minor < SSL_MINOR_VERSION_0 || minor > SSL_MINOR_VERSION_3 ) + return; + + ssl->ciphersuite_list[minor] = ciphersuites; +} + +#if defined(POLARSSL_X509_CRT_PARSE_C) +/* Add a new (empty) key_cert entry an return a pointer to it */ +static ssl_key_cert *ssl_add_key_cert( ssl_context *ssl ) +{ + ssl_key_cert *key_cert, *last; + + key_cert = (ssl_key_cert *) polarssl_malloc( sizeof(ssl_key_cert) ); + if( key_cert == NULL ) + return( NULL ); + + memset( key_cert, 0, sizeof( ssl_key_cert ) ); + + /* Append the new key_cert to the (possibly empty) current list */ + if( ssl->key_cert == NULL ) + { + ssl->key_cert = key_cert; + if( ssl->handshake != NULL ) + ssl->handshake->key_cert = key_cert; + } + else + { + last = ssl->key_cert; + while( last->next != NULL ) + last = last->next; + last->next = key_cert; + } + + return( key_cert ); +} + +void ssl_set_ca_chain( ssl_context *ssl, x509_crt *ca_chain, + x509_crl *ca_crl, const char *peer_cn ) +{ + ssl->ca_chain = ca_chain; + ssl->ca_crl = ca_crl; + ssl->peer_cn = peer_cn; +} + +int ssl_set_own_cert( ssl_context *ssl, x509_crt *own_cert, + pk_context *pk_key ) +{ + ssl_key_cert *key_cert = ssl_add_key_cert( ssl ); + + if( key_cert == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + key_cert->cert = own_cert; + key_cert->key = pk_key; + + return( 0 ); +} + +#if defined(POLARSSL_RSA_C) +int ssl_set_own_cert_rsa( ssl_context *ssl, x509_crt *own_cert, + rsa_context *rsa_key ) +{ + int ret; + ssl_key_cert *key_cert = ssl_add_key_cert( ssl ); + + if( key_cert == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + key_cert->key = (pk_context *) polarssl_malloc( sizeof(pk_context) ); + if( key_cert->key == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + pk_init( key_cert->key ); + + ret = pk_init_ctx( key_cert->key, pk_info_from_type( POLARSSL_PK_RSA ) ); + if( ret != 0 ) + return( ret ); + + if( ( ret = rsa_copy( pk_rsa( *key_cert->key ), rsa_key ) ) != 0 ) + return( ret ); + + key_cert->cert = own_cert; + key_cert->key_own_alloc = 1; + + return( 0 ); +} +#endif /* POLARSSL_RSA_C */ + +int ssl_set_own_cert_alt( ssl_context *ssl, x509_crt *own_cert, + void *rsa_key, + rsa_decrypt_func rsa_decrypt, + rsa_sign_func rsa_sign, + rsa_key_len_func rsa_key_len ) +{ + int ret; + ssl_key_cert *key_cert = ssl_add_key_cert( ssl ); + + if( key_cert == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + key_cert->key = (pk_context *) polarssl_malloc( sizeof(pk_context) ); + if( key_cert->key == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + pk_init( key_cert->key ); + + if( ( ret = pk_init_ctx_rsa_alt( key_cert->key, rsa_key, + rsa_decrypt, rsa_sign, rsa_key_len ) ) != 0 ) + return( ret ); + + key_cert->cert = own_cert; + key_cert->key_own_alloc = 1; + + return( 0 ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) +int ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len, + const unsigned char *psk_identity, size_t psk_identity_len ) +{ + if( psk == NULL || psk_identity == NULL ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + if( psk_len > POLARSSL_PSK_MAX_LEN ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + if( ssl->psk != NULL ) + { + polarssl_free( ssl->psk ); + polarssl_free( ssl->psk_identity ); + } + + ssl->psk_len = psk_len; + ssl->psk_identity_len = psk_identity_len; + + ssl->psk = (unsigned char *) polarssl_malloc( ssl->psk_len ); + ssl->psk_identity = (unsigned char *) + polarssl_malloc( ssl->psk_identity_len ); + + if( ssl->psk == NULL || ssl->psk_identity == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + memcpy( ssl->psk, psk, ssl->psk_len ); + memcpy( ssl->psk_identity, psk_identity, ssl->psk_identity_len ); + + return( 0 ); +} + +void ssl_set_psk_cb( ssl_context *ssl, + int (*f_psk)(void *, ssl_context *, const unsigned char *, + size_t), + void *p_psk ) +{ + ssl->f_psk = f_psk; + ssl->p_psk = p_psk; +} +#endif /* POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(POLARSSL_DHM_C) +int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G ) +{ + int ret; + + if( ( ret = mpi_read_string( &ssl->dhm_P, 16, dhm_P ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_read_string", ret ); + return( ret ); + } + + if( ( ret = mpi_read_string( &ssl->dhm_G, 16, dhm_G ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_read_string", ret ); + return( ret ); + } + + return( 0 ); +} + +int ssl_set_dh_param_ctx( ssl_context *ssl, dhm_context *dhm_ctx ) +{ + int ret; + + if( ( ret = mpi_copy( &ssl->dhm_P, &dhm_ctx->P ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_copy", ret ); + return( ret ); + } + + if( ( ret = mpi_copy( &ssl->dhm_G, &dhm_ctx->G ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "mpi_copy", ret ); + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_DHM_C */ + +#if defined(POLARSSL_SSL_SET_CURVES) +/* + * Set the allowed elliptic curves + */ +void ssl_set_curves( ssl_context *ssl, const ecp_group_id *curve_list ) +{ + ssl->curve_list = curve_list; +} +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) +int ssl_set_hostname( ssl_context *ssl, const char *hostname ) +{ + if( hostname == NULL ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + ssl->hostname_len = strlen( hostname ); + + if( ssl->hostname_len + 1 == 0 ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + ssl->hostname = (unsigned char *) polarssl_malloc( ssl->hostname_len + 1 ); + + if( ssl->hostname == NULL ) + return( POLARSSL_ERR_SSL_MALLOC_FAILED ); + + memcpy( ssl->hostname, (const unsigned char *) hostname, + ssl->hostname_len ); + + ssl->hostname[ssl->hostname_len] = '\0'; + + return( 0 ); +} + +void ssl_set_sni( ssl_context *ssl, + int (*f_sni)(void *, ssl_context *, + const unsigned char *, size_t), + void *p_sni ) +{ + ssl->f_sni = f_sni; + ssl->p_sni = p_sni; +} +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ + +#if defined(POLARSSL_SSL_ALPN) +int ssl_set_alpn_protocols( ssl_context *ssl, const char **protos ) +{ + size_t cur_len, tot_len; + const char **p; + + /* + * "Empty strings MUST NOT be included and byte strings MUST NOT be + * truncated". Check lengths now rather than later. + */ + tot_len = 0; + for( p = protos; *p != NULL; p++ ) + { + cur_len = strlen( *p ); + tot_len += cur_len; + + if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + ssl->alpn_list = protos; + + return( 0 ); +} + +const char *ssl_get_alpn_protocol( const ssl_context *ssl ) +{ + return( ssl->alpn_chosen ); +} +#endif /* POLARSSL_SSL_ALPN */ + +void ssl_set_max_version( ssl_context *ssl, int major, int minor ) +{ + if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION && + minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION ) + { + ssl->max_major_ver = major; + ssl->max_minor_ver = minor; + } +} + +void ssl_set_min_version( ssl_context *ssl, int major, int minor ) +{ + if( major >= SSL_MIN_MAJOR_VERSION && major <= SSL_MAX_MAJOR_VERSION && + minor >= SSL_MIN_MINOR_VERSION && minor <= SSL_MAX_MINOR_VERSION ) + { + ssl->min_major_ver = major; + ssl->min_minor_ver = minor; + } +} + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) +int ssl_set_max_frag_len( ssl_context *ssl, unsigned char mfl_code ) +{ + if( mfl_code >= SSL_MAX_FRAG_LEN_INVALID || + mfl_code_to_length[mfl_code] > SSL_MAX_CONTENT_LEN ) + { + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + ssl->mfl_code = mfl_code; + + return( 0 ); +} +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) +int ssl_set_truncated_hmac( ssl_context *ssl, int truncate ) +{ + if( ssl->endpoint != SSL_IS_CLIENT ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + ssl->trunc_hmac = truncate; + + return( 0 ); +} +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ + +void ssl_set_renegotiation( ssl_context *ssl, int renegotiation ) +{ + ssl->disable_renegotiation = renegotiation; +} + +void ssl_legacy_renegotiation( ssl_context *ssl, int allow_legacy ) +{ + ssl->allow_legacy_renegotiation = allow_legacy; +} + +void ssl_set_renegotiation_enforced( ssl_context *ssl, int max_records ) +{ + ssl->renego_max_records = max_records; +} + +#if defined(POLARSSL_SSL_SESSION_TICKETS) +int ssl_set_session_tickets( ssl_context *ssl, int use_tickets ) +{ + ssl->session_tickets = use_tickets; + + if( ssl->endpoint == SSL_IS_CLIENT ) + return( 0 ); + + if( ssl->f_rng == NULL ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + return( ssl_ticket_keys_init( ssl ) ); +} + +void ssl_set_session_ticket_lifetime( ssl_context *ssl, int lifetime ) +{ + ssl->ticket_lifetime = lifetime; +} +#endif /* POLARSSL_SSL_SESSION_TICKETS */ + +/* + * SSL get accessors + */ +size_t ssl_get_bytes_avail( const ssl_context *ssl ) +{ + return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); +} + +int ssl_get_verify_result( const ssl_context *ssl ) +{ + return( ssl->session->verify_result ); +} + +const char *ssl_get_ciphersuite( const ssl_context *ssl ) +{ + if( ssl == NULL || ssl->session == NULL ) + return( NULL ); + + return ssl_get_ciphersuite_name( ssl->session->ciphersuite ); +} + +const char *ssl_get_version( const ssl_context *ssl ) +{ + switch( ssl->minor_ver ) + { + case SSL_MINOR_VERSION_0: + return( "SSLv3.0" ); + + case SSL_MINOR_VERSION_1: + return( "TLSv1.0" ); + + case SSL_MINOR_VERSION_2: + return( "TLSv1.1" ); + + case SSL_MINOR_VERSION_3: + return( "TLSv1.2" ); + + default: + break; + } + return( "unknown" ); +} + +#if defined(POLARSSL_X509_CRT_PARSE_C) +const x509_crt *ssl_get_peer_cert( const ssl_context *ssl ) +{ + if( ssl == NULL || ssl->session == NULL ) + return( NULL ); + + return( ssl->session->peer_cert ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +int ssl_get_session( const ssl_context *ssl, ssl_session *dst ) +{ + if( ssl == NULL || + dst == NULL || + ssl->session == NULL || + ssl->endpoint != SSL_IS_CLIENT ) + { + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ssl_session_copy( dst, ssl->session ) ); +} + +/* + * Perform a single step of the SSL handshake + */ +int ssl_handshake_step( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + +#if defined(POLARSSL_SSL_CLI_C) + if( ssl->endpoint == SSL_IS_CLIENT ) + ret = ssl_handshake_client_step( ssl ); +#endif + +#if defined(POLARSSL_SSL_SRV_C) + if( ssl->endpoint == SSL_IS_SERVER ) + ret = ssl_handshake_server_step( ssl ); +#endif + + return( ret ); +} + +/* + * Perform the SSL handshake + */ +int ssl_handshake( ssl_context *ssl ) +{ + int ret = 0; + + SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); + + while( ssl->state != SSL_HANDSHAKE_OVER ) + { + ret = ssl_handshake_step( ssl ); + + if( ret != 0 ) + break; + } + + SSL_DEBUG_MSG( 2, ( "<= handshake" ) ); + + return( ret ); +} + +#if defined(POLARSSL_SSL_SRV_C) +/* + * Write HelloRequest to request renegotiation on server + */ +static int ssl_write_hello_request( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> write hello request" ) ); + + ssl->out_msglen = 4; + ssl->out_msgtype = SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = SSL_HS_HELLO_REQUEST; + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + + ssl->renegotiation = SSL_RENEGOTIATION_PENDING; + + SSL_DEBUG_MSG( 2, ( "<= write hello request" ) ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SRV_C */ + +/* + * Actually renegotiate current connection, triggered by either: + * - calling ssl_renegotiate() on client, + * - receiving a HelloRequest on client during ssl_read(), + * - receiving any handshake message on server during ssl_read() after the + * initial handshake is completed + * If the handshake doesn't complete due to waiting for I/O, it will continue + * during the next calls to ssl_renegotiate() or ssl_read() respectively. + */ +static int ssl_start_renegotiation( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) ); + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + ssl->state = SSL_HELLO_REQUEST; + ssl->renegotiation = SSL_RENEGOTIATION; + + if( ( ret = ssl_handshake( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_handshake", ret ); + return( ret ); + } + + SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) ); + + return( 0 ); +} + +/* + * Renegotiate current connection on client, + * or request renegotiation on server + */ +int ssl_renegotiate( ssl_context *ssl ) +{ + int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE; + +#if defined(POLARSSL_SSL_SRV_C) + /* On server, just send the request */ + if( ssl->endpoint == SSL_IS_SERVER ) + { + if( ssl->state != SSL_HANDSHAKE_OVER ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + return( ssl_write_hello_request( ssl ) ); + } +#endif /* POLARSSL_SSL_SRV_C */ + +#if defined(POLARSSL_SSL_CLI_C) + /* + * On client, either start the renegotiation process or, + * if already in progress, continue the handshake + */ + if( ssl->renegotiation != SSL_RENEGOTIATION ) + { + if( ssl->state != SSL_HANDSHAKE_OVER ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + + if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); + return( ret ); + } + } + else + { + if( ( ret = ssl_handshake( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_handshake", ret ); + return( ret ); + } + } +#endif /* POLARSSL_SSL_CLI_C */ + + return( ret ); +} + +/* + * Receive application data decrypted from the SSL layer + */ +int ssl_read( ssl_context *ssl, unsigned char *buf, size_t len ) +{ + int ret; + size_t n; + + SSL_DEBUG_MSG( 2, ( "=> read" ) ); + + if( ssl->state != SSL_HANDSHAKE_OVER ) + { + if( ( ret = ssl_handshake( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_handshake", ret ); + return( ret ); + } + } + + if( ssl->in_offt == NULL ) + { + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + if( ret == POLARSSL_ERR_SSL_CONN_EOF ) + return( 0 ); + + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msglen == 0 && + ssl->in_msgtype == SSL_MSG_APPLICATION_DATA ) + { + /* + * OpenSSL sends empty messages to randomize the IV + */ + if( ( ret = ssl_read_record( ssl ) ) != 0 ) + { + if( ret == POLARSSL_ERR_SSL_CONN_EOF ) + return( 0 ); + + SSL_DEBUG_RET( 1, "ssl_read_record", ret ); + return( ret ); + } + } + + if( ssl->in_msgtype == SSL_MSG_HANDSHAKE ) + { + SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); + + if( ssl->endpoint == SSL_IS_CLIENT && + ( ssl->in_msg[0] != SSL_HS_HELLO_REQUEST || + ssl->in_hslen != 4 ) ) + { + SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->disable_renegotiation == SSL_RENEGOTIATION_DISABLED || + ( ssl->secure_renegotiation == SSL_LEGACY_RENEGOTIATION && + ssl->allow_legacy_renegotiation == + SSL_LEGACY_NO_RENEGOTIATION ) ) + { + SSL_DEBUG_MSG( 3, ( "ignoring renegotiation, sending alert" ) ); + +#if defined(POLARSSL_SSL_PROTO_SSL3) + if( ssl->minor_ver == SSL_MINOR_VERSION_0 ) + { + /* + * SSLv3 does not have a "no_renegotiation" alert + */ + if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + } + else +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) || defined(POLARSSL_SSL_PROTO_TLS1_1) || \ + defined(POLARSSL_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= SSL_MINOR_VERSION_1 ) + { + if( ( ret = ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_WARNING, + SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) + { + return( ret ); + } + } + else +#endif /* POLARSSL_SSL_PROTO_TLS1 || POLARSSL_SSL_PROTO_TLS1_1 || + POLARSSL_SSL_PROTO_TLS1_2 */ + { + SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( POLARSSL_ERR_SSL_INTERNAL_ERROR ); + } + } + else + { + if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); + return( ret ); + } + + return( POLARSSL_ERR_NET_WANT_READ ); + } + } + else if( ssl->renegotiation == SSL_RENEGOTIATION_PENDING ) + { + ssl->renego_records_seen++; + + if( ssl->renego_max_records >= 0 && + ssl->renego_records_seen > ssl->renego_max_records ) + { + SSL_DEBUG_MSG( 1, ( "renegotiation requested, " + "but not honored by client" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + } + else if( ssl->in_msgtype != SSL_MSG_APPLICATION_DATA ) + { + SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); + return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + ssl->in_offt = ssl->in_msg; + } + + n = ( len < ssl->in_msglen ) + ? len : ssl->in_msglen; + + memcpy( buf, ssl->in_offt, n ); + ssl->in_msglen -= n; + + if( ssl->in_msglen == 0 ) + /* all bytes consumed */ + ssl->in_offt = NULL; + else + /* more data available */ + ssl->in_offt += n; + + SSL_DEBUG_MSG( 2, ( "<= read" ) ); + + return( (int) n ); +} + +/* + * Send application data to be encrypted by the SSL layer + */ +int ssl_write( ssl_context *ssl, const unsigned char *buf, size_t len ) +{ + int ret; + size_t n; + unsigned int max_len = SSL_MAX_CONTENT_LEN; + + SSL_DEBUG_MSG( 2, ( "=> write" ) ); + + if( ssl->state != SSL_HANDSHAKE_OVER ) + { + if( ( ret = ssl_handshake( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_handshake", ret ); + return( ret ); + } + } + +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + /* + * Assume mfl_code is correct since it was checked when set + */ + max_len = mfl_code_to_length[ssl->mfl_code]; + + /* + * Check if a smaller max length was negotiated + */ + if( ssl->session_out != NULL && + mfl_code_to_length[ssl->session_out->mfl_code] < max_len ) + { + max_len = mfl_code_to_length[ssl->session_out->mfl_code]; + } +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ + + n = ( len < max_len) ? len : max_len; + + if( ssl->out_left != 0 ) + { + if( ( ret = ssl_flush_output( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_flush_output", ret ); + return( ret ); + } + } + else + { + ssl->out_msglen = n; + ssl->out_msgtype = SSL_MSG_APPLICATION_DATA; + memcpy( ssl->out_msg, buf, n ); + + if( ( ret = ssl_write_record( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_write_record", ret ); + return( ret ); + } + } + + SSL_DEBUG_MSG( 2, ( "<= write" ) ); + + return( (int) n ); +} + +/* + * Notify the peer that the connection is being closed + */ +int ssl_close_notify( ssl_context *ssl ) +{ + int ret; + + SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); + + if( ( ret = ssl_flush_output( ssl ) ) != 0 ) + { + SSL_DEBUG_RET( 1, "ssl_flush_output", ret ); + return( ret ); + } + + if( ssl->state == SSL_HANDSHAKE_OVER ) + { + if( ( ret = ssl_send_alert_message( ssl, + SSL_ALERT_LEVEL_WARNING, + SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) + { + return( ret ); + } + } + + SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); + + return( ret ); +} + +void ssl_transform_free( ssl_transform *transform ) +{ + if( transform == NULL ) + return; + +#if defined(POLARSSL_ZLIB_SUPPORT) + deflateEnd( &transform->ctx_deflate ); + inflateEnd( &transform->ctx_inflate ); +#endif + + cipher_free( &transform->cipher_ctx_enc ); + cipher_free( &transform->cipher_ctx_dec ); + + md_free( &transform->md_ctx_enc ); + md_free( &transform->md_ctx_dec ); + + polarssl_zeroize( transform, sizeof( ssl_transform ) ); +} + +#if defined(POLARSSL_X509_CRT_PARSE_C) +static void ssl_key_cert_free( ssl_key_cert *key_cert ) +{ + ssl_key_cert *cur = key_cert, *next; + + while( cur != NULL ) + { + next = cur->next; + + if( cur->key_own_alloc ) + { + pk_free( cur->key ); + polarssl_free( cur->key ); + } + polarssl_free( cur ); + + cur = next; + } +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +void ssl_handshake_free( ssl_handshake_params *handshake ) +{ + if( handshake == NULL ) + return; + +#if defined(POLARSSL_DHM_C) + dhm_free( &handshake->dhm_ctx ); +#endif +#if defined(POLARSSL_ECDH_C) + ecdh_free( &handshake->ecdh_ctx ); +#endif + +#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C) + /* explicit void pointer cast for buggy MS compiler */ + polarssl_free( (void *) handshake->curves ); +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) && \ + defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + /* + * Free only the linked list wrapper, not the keys themselves + * since the belong to the SNI callback + */ + if( handshake->sni_key_cert != NULL ) + { + ssl_key_cert *cur = handshake->sni_key_cert, *next; + + while( cur != NULL ) + { + next = cur->next; + polarssl_free( cur ); + cur = next; + } + } +#endif /* POLARSSL_X509_CRT_PARSE_C && POLARSSL_SSL_SERVER_NAME_INDICATION */ + + polarssl_zeroize( handshake, sizeof( ssl_handshake_params ) ); +} + +void ssl_session_free( ssl_session *session ) +{ + if( session == NULL ) + return; + +#if defined(POLARSSL_X509_CRT_PARSE_C) + if( session->peer_cert != NULL ) + { + x509_crt_free( session->peer_cert ); + polarssl_free( session->peer_cert ); + } +#endif + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + polarssl_free( session->ticket ); +#endif + + polarssl_zeroize( session, sizeof( ssl_session ) ); +} + +/* + * Free an SSL context + */ +void ssl_free( ssl_context *ssl ) +{ + if( ssl == NULL ) + return; + + SSL_DEBUG_MSG( 2, ( "=> free" ) ); + + if( ssl->out_ctr != NULL ) + { + polarssl_zeroize( ssl->out_ctr, SSL_BUFFER_LEN ); + polarssl_free( ssl->out_ctr ); + } + + if( ssl->in_ctr != NULL ) + { + polarssl_zeroize( ssl->in_ctr, SSL_BUFFER_LEN ); + polarssl_free( ssl->in_ctr ); + } + +#if defined(POLARSSL_ZLIB_SUPPORT) + if( ssl->compress_buf != NULL ) + { + polarssl_zeroize( ssl->compress_buf, SSL_BUFFER_LEN ); + polarssl_free( ssl->compress_buf ); + } +#endif + +#if defined(POLARSSL_DHM_C) + mpi_free( &ssl->dhm_P ); + mpi_free( &ssl->dhm_G ); +#endif + + if( ssl->transform ) + { + ssl_transform_free( ssl->transform ); + polarssl_free( ssl->transform ); + } + + if( ssl->handshake ) + { + ssl_handshake_free( ssl->handshake ); + ssl_transform_free( ssl->transform_negotiate ); + ssl_session_free( ssl->session_negotiate ); + + polarssl_free( ssl->handshake ); + polarssl_free( ssl->transform_negotiate ); + polarssl_free( ssl->session_negotiate ); + } + + if( ssl->session ) + { + ssl_session_free( ssl->session ); + polarssl_free( ssl->session ); + } + +#if defined(POLARSSL_SSL_SESSION_TICKETS) + if( ssl->ticket_keys ) + { + ssl_ticket_keys_free( ssl->ticket_keys ); + polarssl_free( ssl->ticket_keys ); + } +#endif + +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + if( ssl->hostname != NULL ) + { + polarssl_zeroize( ssl->hostname, ssl->hostname_len ); + polarssl_free( ssl->hostname ); + ssl->hostname_len = 0; + } +#endif + +#if defined(POLARSSL_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( ssl->psk != NULL ) + { + polarssl_zeroize( ssl->psk, ssl->psk_len ); + polarssl_zeroize( ssl->psk_identity, ssl->psk_identity_len ); + polarssl_free( ssl->psk ); + polarssl_free( ssl->psk_identity ); + ssl->psk_len = 0; + ssl->psk_identity_len = 0; + } +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) + ssl_key_cert_free( ssl->key_cert ); +#endif + +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + if( ssl_hw_record_finish != NULL ) + { + SSL_DEBUG_MSG( 2, ( "going for ssl_hw_record_finish()" ) ); + ssl_hw_record_finish( ssl ); + } +#endif + + SSL_DEBUG_MSG( 2, ( "<= free" ) ); + + /* Actually clear after last debug message */ + polarssl_zeroize( ssl, sizeof( ssl_context ) ); +} + +#if defined(POLARSSL_PK_C) +/* + * Convert between POLARSSL_PK_XXX and SSL_SIG_XXX + */ +unsigned char ssl_sig_from_pk( pk_context *pk ) +{ +#if defined(POLARSSL_RSA_C) + if( pk_can_do( pk, POLARSSL_PK_RSA ) ) + return( SSL_SIG_RSA ); +#endif +#if defined(POLARSSL_ECDSA_C) + if( pk_can_do( pk, POLARSSL_PK_ECDSA ) ) + return( SSL_SIG_ECDSA ); +#endif + return( SSL_SIG_ANON ); +} + +pk_type_t ssl_pk_alg_from_sig( unsigned char sig ) +{ + switch( sig ) + { +#if defined(POLARSSL_RSA_C) + case SSL_SIG_RSA: + return( POLARSSL_PK_RSA ); +#endif +#if defined(POLARSSL_ECDSA_C) + case SSL_SIG_ECDSA: + return( POLARSSL_PK_ECDSA ); +#endif + default: + return( POLARSSL_PK_NONE ); + } +} +#endif /* POLARSSL_PK_C */ + +/* + * Convert between SSL_HASH_XXX and POLARSSL_MD_XXX + */ +md_type_t ssl_md_alg_from_hash( unsigned char hash ) +{ + switch( hash ) + { +#if defined(POLARSSL_MD5_C) + case SSL_HASH_MD5: + return( POLARSSL_MD_MD5 ); +#endif +#if defined(POLARSSL_SHA1_C) + case SSL_HASH_SHA1: + return( POLARSSL_MD_SHA1 ); +#endif +#if defined(POLARSSL_SHA256_C) + case SSL_HASH_SHA224: + return( POLARSSL_MD_SHA224 ); + case SSL_HASH_SHA256: + return( POLARSSL_MD_SHA256 ); +#endif +#if defined(POLARSSL_SHA512_C) + case SSL_HASH_SHA384: + return( POLARSSL_MD_SHA384 ); + case SSL_HASH_SHA512: + return( POLARSSL_MD_SHA512 ); +#endif + default: + return( POLARSSL_MD_NONE ); + } +} + +#if defined(POLARSSL_SSL_SET_CURVES) +/* + * Check is a curve proposed by the peer is in our list. + * Return 1 if we're willing to use it, 0 otherwise. + */ +int ssl_curve_is_acceptable( const ssl_context *ssl, ecp_group_id grp_id ) +{ + const ecp_group_id *gid; + + for( gid = ssl->curve_list; *gid != POLARSSL_ECP_DP_NONE; gid++ ) + if( *gid == grp_id ) + return( 1 ); + + return( 0 ); +} +#endif /* POLARSSL_SSL_SET_CURVES */ + +#if defined(POLARSSL_X509_CRT_PARSE_C) +int ssl_check_cert_usage( const x509_crt *cert, + const ssl_ciphersuite_t *ciphersuite, + int cert_endpoint ) +{ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + int usage = 0; +#endif +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + const char *ext_oid; + size_t ext_len; +#endif + +#if !defined(POLARSSL_X509_CHECK_KEY_USAGE) && \ + !defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + ((void) cert); + ((void) cert_endpoint); +#endif + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( cert_endpoint == SSL_IS_SERVER ) + { + /* Server part of the key exchange */ + switch( ciphersuite->key_exchange ) + { + case POLARSSL_KEY_EXCHANGE_RSA: + case POLARSSL_KEY_EXCHANGE_RSA_PSK: + usage = KU_KEY_ENCIPHERMENT; + break; + + case POLARSSL_KEY_EXCHANGE_DHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_RSA: + case POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA: + usage = KU_DIGITAL_SIGNATURE; + break; + + case POLARSSL_KEY_EXCHANGE_ECDH_RSA: + case POLARSSL_KEY_EXCHANGE_ECDH_ECDSA: + usage = KU_KEY_AGREEMENT; + break; + + /* Don't use default: we want warnings when adding new values */ + case POLARSSL_KEY_EXCHANGE_NONE: + case POLARSSL_KEY_EXCHANGE_PSK: + case POLARSSL_KEY_EXCHANGE_DHE_PSK: + case POLARSSL_KEY_EXCHANGE_ECDHE_PSK: + usage = 0; + } + } + else + { + /* Client auth: we only implement rsa_sign and ecdsa_sign for now */ + usage = KU_DIGITAL_SIGNATURE; + } + + if( x509_crt_check_key_usage( cert, usage ) != 0 ) + return( -1 ); +#else + ((void) ciphersuite); +#endif /* POLARSSL_X509_CHECK_KEY_USAGE */ + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + if( cert_endpoint == SSL_IS_SERVER ) + { + ext_oid = OID_SERVER_AUTH; + ext_len = OID_SIZE( OID_SERVER_AUTH ); + } + else + { + ext_oid = OID_CLIENT_AUTH; + ext_len = OID_SIZE( OID_CLIENT_AUTH ); + } + + if( x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) + return( -1 ); +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ + + return( 0 ); +} +#endif /* POLARSSL_X509_CRT_PARSE_C */ + +#endif /* POLARSSL_SSL_TLS_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/threading.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/threading.c new file mode 100644 index 0000000..522c70f --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/threading.c @@ -0,0 +1,113 @@ +/* + * Threading abstraction layer + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_THREADING_C) + +#include "polarssl/threading.h" + +#if defined(POLARSSL_THREADING_PTHREAD) +static int threading_mutex_init_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_init( mutex, NULL ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_free_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_destroy( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_lock_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_lock( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_unlock_pthread( threading_mutex_t *mutex ) +{ + if( mutex == NULL ) + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_unlock( mutex ) != 0 ) + return( POLARSSL_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_init_pthread; +int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_free_pthread; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_lock_pthread; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_unlock_pthread; +#endif /* POLARSSL_THREADING_PTHREAD */ + +#if defined(POLARSSL_THREADING_ALT) +static int threading_mutex_fail( threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( POLARSSL_ERR_THREADING_BAD_INPUT_DATA ); +} + +int (*polarssl_mutex_init)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_free)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_lock)( threading_mutex_t * ) = threading_mutex_fail; +int (*polarssl_mutex_unlock)( threading_mutex_t * ) = threading_mutex_fail; + +int threading_set_alt( int (*mutex_init)( threading_mutex_t * ), + int (*mutex_free)( threading_mutex_t * ), + int (*mutex_lock)( threading_mutex_t * ), + int (*mutex_unlock)( threading_mutex_t * ) ) +{ + polarssl_mutex_init = mutex_init; + polarssl_mutex_free = mutex_free; + polarssl_mutex_lock = mutex_lock; + polarssl_mutex_unlock = mutex_unlock; + + return( 0 ); +} +#endif /* POLARSSL_THREADING_ALT_C */ + +#endif /* POLARSSL_THREADING_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/timing.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/timing.c new file mode 100644 index 0000000..6c1dfa4 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/timing.c @@ -0,0 +1,500 @@ +/* + * Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_SELF_TEST) && defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#include +#define polarssl_printf printf +#endif + +#if defined(POLARSSL_TIMING_C) && !defined(POLARSSL_TIMING_ALT) + +#include "polarssl/timing.h" + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#include +#include + +struct _hr_time +{ + LARGE_INTEGER start; +}; + +#else + +#include +#include +#include +#include +#include + +struct _hr_time +{ + struct timeval start; +}; + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long tsc; + __asm rdtsc + __asm mov [tsc], eax + return( tsc ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && defined(__i386__) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __i386__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo | ( hi << 32 ) ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && ( __amd64__ || __x86_64__ ) */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long tbl, tbu0, tbu1; + + do + { + asm volatile( "mftbu %0" : "=r" (tbu0) ); + asm volatile( "mftb %0" : "=r" (tbl ) ); + asm volatile( "mftbu %0" : "=r" (tbu1) ); + } + while( tbu0 != tbu1 ); + + return( tbl ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && ( __powerpc__ || __ppc__ ) */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc64__) + +#if defined(__OpenBSD__) +#warning OpenBSD does not allow access to tick register using software version instead +#else +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long tick; + asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); + return( tick ); +} +#endif /* __OpenBSD__ */ +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __sparc64__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long tick; + asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); + asm volatile( "mov %%g1, %0" : "=r" (tick) ); + return( tick ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __sparc__ && !__sparc64__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && defined(__alpha__) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long cc; + asm volatile( "rpcc %0" : "=r" (cc) ); + return( cc & 0xFFFFFFFF ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __alpha__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(POLARSSL_HAVE_ASM) && \ + defined(__GNUC__) && defined(__ia64__) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + unsigned long itc; + asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); + return( itc ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && POLARSSL_HAVE_ASM && + __GNUC__ && __ia64__ */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) && defined(_MSC_VER) && \ + !defined(EFIX64) && !defined(EFI32) + +#define POLARSSL_HAVE_HARDCLOCK + +unsigned long hardclock( void ) +{ + LARGE_INTEGER offset; + + QueryPerformanceCounter( &offset ); + + return( (unsigned long)( offset.QuadPart ) ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ + +#if !defined(POLARSSL_HAVE_HARDCLOCK) + +#define POLARSSL_HAVE_HARDCLOCK + +static int hardclock_init = 0; +static struct timeval tv_init; + +unsigned long hardclock( void ) +{ + struct timeval tv_cur; + + if( hardclock_init == 0 ) + { + gettimeofday( &tv_init, NULL ); + hardclock_init = 1; + } + + gettimeofday( &tv_cur, NULL ); + return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + + ( tv_cur.tv_usec - tv_init.tv_usec ) ); +} +#endif /* !POLARSSL_HAVE_HARDCLOCK */ + +volatile int alarmed = 0; + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +unsigned long get_timer( struct hr_time *val, int reset ) +{ + unsigned long delta; + LARGE_INTEGER offset, hfreq; + struct _hr_time *t = (struct _hr_time *) val; + + QueryPerformanceCounter( &offset ); + QueryPerformanceFrequency( &hfreq ); + + delta = (unsigned long)( ( 1000 * + ( offset.QuadPart - t->start.QuadPart ) ) / + hfreq.QuadPart ); + + if( reset ) + QueryPerformanceCounter( &t->start ); + + return( delta ); +} + +DWORD WINAPI TimerProc( LPVOID uElapse ) +{ + Sleep( (DWORD) uElapse ); + alarmed = 1; + return( TRUE ); +} + +void set_alarm( int seconds ) +{ + DWORD ThreadId; + + alarmed = 0; + CloseHandle( CreateThread( NULL, 0, TimerProc, + (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) ); +} + +void m_sleep( int milliseconds ) +{ + Sleep( milliseconds ); +} + +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +unsigned long get_timer( struct hr_time *val, int reset ) +{ + unsigned long delta; + struct timeval offset; + struct _hr_time *t = (struct _hr_time *) val; + + gettimeofday( &offset, NULL ); + + delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 + + ( offset.tv_usec - t->start.tv_usec ) / 1000; + + if( reset ) + { + t->start.tv_sec = offset.tv_sec; + t->start.tv_usec = offset.tv_usec; + } + + return( delta ); +} + +#if defined(INTEGRITY) +void m_sleep( int milliseconds ) +{ + usleep( milliseconds * 1000 ); +} + +#else /* INTEGRITY */ + +static void sighandler( int signum ) +{ + alarmed = 1; + signal( signum, sighandler ); +} + +void set_alarm( int seconds ) +{ + alarmed = 0; + signal( SIGALRM, sighandler ); + alarm( seconds ); +} + +void m_sleep( int milliseconds ) +{ + struct timeval tv; + + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = ( milliseconds % 1000 ) * 1000; + + select( 0, NULL, NULL, NULL, &tv ); +} +#endif /* INTEGRITY */ + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +#if defined(POLARSSL_SELF_TEST) + +/* To test net_usleep against our functions */ +#if defined(POLARSSL_NET_C) +#include "polarssl/net.h" +#endif + +/* + * Busy-waits for the given number of milliseconds. + * Used for testing hardclock. + */ +static void busy_msleep( unsigned long msec ) +{ + struct hr_time hires; + unsigned long i = 0; /* for busy-waiting */ + volatile unsigned long j; /* to prevent optimisation */ + + (void) get_timer( &hires, 1 ); + + while( get_timer( &hires, 0 ) < msec ) + i++; + + j = i; + (void) j; +} + +/* + * Checkup routine + * + * Warning: this is work in progress, some tests may not be reliable enough + * yet! False positives may happen. + */ +int timing_self_test( int verbose ) +{ + unsigned long cycles, ratio; + unsigned long millisecs, secs; + int hardfail; + struct hr_time hires; + + if( verbose != 0 ) + polarssl_printf( " TIMING tests note: will take some time!\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #1 (m_sleep / get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + m_sleep( 500 * secs ); + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 450 * secs || millisecs > 550 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #2 (set_alarm / get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + set_alarm( secs ); + while( !alarmed ) + ; + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 900 * secs || millisecs > 1100 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " TIMING test #3 (hardclock / get_timer): " ); + + /* + * Allow one failure for possible counter wrapping. + * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; + * since the whole test is about 10ms, it shouldn't happen twice in a row. + */ + hardfail = 0; + +hard_test: + if( hardfail > 1 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + /* Get a reference ratio cycles/ms */ + millisecs = 1; + cycles = hardclock(); + busy_msleep( millisecs ); + cycles = hardclock() - cycles; + ratio = cycles / millisecs; + + /* Check that the ratio is mostly constant */ + for( millisecs = 2; millisecs <= 4; millisecs++ ) + { + cycles = hardclock(); + busy_msleep( millisecs ); + cycles = hardclock() - cycles; + + /* Allow variation up to 20% */ + if( cycles / millisecs < ratio - ratio / 5 || + cycles / millisecs > ratio + ratio / 5 ) + { + hardfail++; + goto hard_test; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +#if defined(POLARSSL_NET_C) + if( verbose != 0 ) + polarssl_printf( " TIMING test #4 (net_usleep/ get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) get_timer( &hires, 1 ); + + net_usleep( 500000 * secs ); + + millisecs = get_timer( &hires, 0 ); + + if( millisecs < 450 * secs || millisecs > 550 * secs ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); +#endif /* POLARSSL_NET_C */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_TIMING_C && !POLARSSL_TIMING_ALT */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/version.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/version.c new file mode 100644 index 0000000..c3c708a --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/version.c @@ -0,0 +1,56 @@ +/* + * Version information + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_VERSION_C) + +#include "polarssl/version.h" +#include + +const char version[] = POLARSSL_VERSION_STRING; + +unsigned int version_get_number() +{ + return( POLARSSL_VERSION_NUMBER ); +} + +void version_get_string( char *string ) +{ + memcpy( string, POLARSSL_VERSION_STRING, + sizeof( POLARSSL_VERSION_STRING ) ); +} + +void version_get_string_full( char *string ) +{ + memcpy( string, POLARSSL_VERSION_STRING_FULL, + sizeof( POLARSSL_VERSION_STRING_FULL ) ); +} + +#endif /* POLARSSL_VERSION_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/version_features.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/version_features.c new file mode 100644 index 0000000..1023198 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/version_features.c @@ -0,0 +1,560 @@ +/* + * Version feature information + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_VERSION_C) + +#include "polarssl/version.h" + +#include + +#if defined(_MSC_VER) && !defined strcasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strcasecmp _stricmp +#endif + +const char *features[] = { +#if defined(POLARSSL_VERSION_FEATURES) +#if defined(POLARSSL_HAVE_INT8) + "POLARSSL_HAVE_INT8", +#endif /* POLARSSL_HAVE_INT8 */ +#if defined(POLARSSL_HAVE_INT16) + "POLARSSL_HAVE_INT16", +#endif /* POLARSSL_HAVE_INT16 */ +#if defined(POLARSSL_HAVE_LONGLONG) + "POLARSSL_HAVE_LONGLONG", +#endif /* POLARSSL_HAVE_LONGLONG */ +#if defined(POLARSSL_HAVE_ASM) + "POLARSSL_HAVE_ASM", +#endif /* POLARSSL_HAVE_ASM */ +#if defined(POLARSSL_HAVE_SSE2) + "POLARSSL_HAVE_SSE2", +#endif /* POLARSSL_HAVE_SSE2 */ +#if defined(POLARSSL_HAVE_TIME) + "POLARSSL_HAVE_TIME", +#endif /* POLARSSL_HAVE_TIME */ +#if defined(POLARSSL_HAVE_IPV6) + "POLARSSL_HAVE_IPV6", +#endif /* POLARSSL_HAVE_IPV6 */ +#if defined(POLARSSL_PLATFORM_MEMORY) + "POLARSSL_PLATFORM_MEMORY", +#endif /* POLARSSL_PLATFORM_MEMORY */ +#if defined(POLARSSL_PLATFORM_NO_STD_FUNCTIONS) + "POLARSSL_PLATFORM_NO_STD_FUNCTIONS", +#endif /* POLARSSL_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(POLARSSL_PLATFORM_PRINTF_ALT) + "POLARSSL_PLATFORM_PRINTF_ALT", +#endif /* POLARSSL_PLATFORM_PRINTF_ALT */ +#if defined(POLARSSL_PLATFORM_FPRINTF_ALT) + "POLARSSL_PLATFORM_FPRINTF_ALT", +#endif /* POLARSSL_PLATFORM_FPRINTF_ALT */ +#if defined(POLARSSL_TIMING_ALT) + "POLARSSL_TIMING_ALT", +#endif /* POLARSSL_TIMING_ALT */ +#if defined(POLARSSL_AES_ALT) + "POLARSSL_AES_ALT", +#endif /* POLARSSL_AES_ALT */ +#if defined(POLARSSL_ARC4_ALT) + "POLARSSL_ARC4_ALT", +#endif /* POLARSSL_ARC4_ALT */ +#if defined(POLARSSL_BLOWFISH_ALT) + "POLARSSL_BLOWFISH_ALT", +#endif /* POLARSSL_BLOWFISH_ALT */ +#if defined(POLARSSL_CAMELLIA_ALT) + "POLARSSL_CAMELLIA_ALT", +#endif /* POLARSSL_CAMELLIA_ALT */ +#if defined(POLARSSL_DES_ALT) + "POLARSSL_DES_ALT", +#endif /* POLARSSL_DES_ALT */ +#if defined(POLARSSL_XTEA_ALT) + "POLARSSL_XTEA_ALT", +#endif /* POLARSSL_XTEA_ALT */ +#if defined(POLARSSL_MD2_ALT) + "POLARSSL_MD2_ALT", +#endif /* POLARSSL_MD2_ALT */ +#if defined(POLARSSL_MD4_ALT) + "POLARSSL_MD4_ALT", +#endif /* POLARSSL_MD4_ALT */ +#if defined(POLARSSL_MD5_ALT) + "POLARSSL_MD5_ALT", +#endif /* POLARSSL_MD5_ALT */ +#if defined(POLARSSL_RIPEMD160_ALT) + "POLARSSL_RIPEMD160_ALT", +#endif /* POLARSSL_RIPEMD160_ALT */ +#if defined(POLARSSL_SHA1_ALT) + "POLARSSL_SHA1_ALT", +#endif /* POLARSSL_SHA1_ALT */ +#if defined(POLARSSL_SHA256_ALT) + "POLARSSL_SHA256_ALT", +#endif /* POLARSSL_SHA256_ALT */ +#if defined(POLARSSL_SHA512_ALT) + "POLARSSL_SHA512_ALT", +#endif /* POLARSSL_SHA512_ALT */ +#if defined(POLARSSL_AES_ROM_TABLES) + "POLARSSL_AES_ROM_TABLES", +#endif /* POLARSSL_AES_ROM_TABLES */ +#if defined(POLARSSL_CIPHER_MODE_CBC) + "POLARSSL_CIPHER_MODE_CBC", +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#if defined(POLARSSL_CIPHER_MODE_CFB) + "POLARSSL_CIPHER_MODE_CFB", +#endif /* POLARSSL_CIPHER_MODE_CFB */ +#if defined(POLARSSL_CIPHER_MODE_CTR) + "POLARSSL_CIPHER_MODE_CTR", +#endif /* POLARSSL_CIPHER_MODE_CTR */ +#if defined(POLARSSL_CIPHER_NULL_CIPHER) + "POLARSSL_CIPHER_NULL_CIPHER", +#endif /* POLARSSL_CIPHER_NULL_CIPHER */ +#if defined(POLARSSL_CIPHER_PADDING_PKCS7) + "POLARSSL_CIPHER_PADDING_PKCS7", +#endif /* POLARSSL_CIPHER_PADDING_PKCS7 */ +#if defined(POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS) + "POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS", +#endif /* POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS */ +#if defined(POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN) + "POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN", +#endif /* POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN */ +#if defined(POLARSSL_CIPHER_PADDING_ZEROS) + "POLARSSL_CIPHER_PADDING_ZEROS", +#endif /* POLARSSL_CIPHER_PADDING_ZEROS */ +#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) + "POLARSSL_ENABLE_WEAK_CIPHERSUITES", +#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */ +#if defined(POLARSSL_REMOVE_ARC4_CIPHERSUITES) + "POLARSSL_REMOVE_ARC4_CIPHERSUITES", +#endif /* POLARSSL_REMOVE_ARC4_CIPHERSUITES */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + "POLARSSL_ECP_DP_SECP192R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP192R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP224R1_ENABLED) + "POLARSSL_ECP_DP_SECP224R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP224R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP256R1_ENABLED) + "POLARSSL_ECP_DP_SECP256R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP256R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP384R1_ENABLED) + "POLARSSL_ECP_DP_SECP384R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP384R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP521R1_ENABLED) + "POLARSSL_ECP_DP_SECP521R1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP521R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP192K1_ENABLED) + "POLARSSL_ECP_DP_SECP192K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP192K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP224K1_ENABLED) + "POLARSSL_ECP_DP_SECP224K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP224K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_SECP256K1_ENABLED) + "POLARSSL_ECP_DP_SECP256K1_ENABLED", +#endif /* POLARSSL_ECP_DP_SECP256K1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP256R1_ENABLED) + "POLARSSL_ECP_DP_BP256R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP256R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP384R1_ENABLED) + "POLARSSL_ECP_DP_BP384R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP384R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_BP512R1_ENABLED) + "POLARSSL_ECP_DP_BP512R1_ENABLED", +#endif /* POLARSSL_ECP_DP_BP512R1_ENABLED */ +#if defined(POLARSSL_ECP_DP_M221_ENABLED) + "POLARSSL_ECP_DP_M221_ENABLED", +#endif /* POLARSSL_ECP_DP_M221_ENABLED */ +#if defined(POLARSSL_ECP_DP_M255_ENABLED) + "POLARSSL_ECP_DP_M255_ENABLED", +#endif /* POLARSSL_ECP_DP_M255_ENABLED */ +#if defined(POLARSSL_ECP_DP_M383_ENABLED) + "POLARSSL_ECP_DP_M383_ENABLED", +#endif /* POLARSSL_ECP_DP_M383_ENABLED */ +#if defined(POLARSSL_ECP_DP_M511_ENABLED) + "POLARSSL_ECP_DP_M511_ENABLED", +#endif /* POLARSSL_ECP_DP_M511_ENABLED */ +#if defined(POLARSSL_ECP_NIST_OPTIM) + "POLARSSL_ECP_NIST_OPTIM", +#endif /* POLARSSL_ECP_NIST_OPTIM */ +#if defined(POLARSSL_ECDSA_DETERMINISTIC) + "POLARSSL_ECDSA_DETERMINISTIC", +#endif /* POLARSSL_ECDSA_DETERMINISTIC */ +#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED) + "POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED) + "POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED", +#endif /* POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED */ +#if defined(POLARSSL_PK_PARSE_EC_EXTENDED) + "POLARSSL_PK_PARSE_EC_EXTENDED", +#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */ +#if defined(POLARSSL_ERROR_STRERROR_BC) + "POLARSSL_ERROR_STRERROR_BC", +#endif /* POLARSSL_ERROR_STRERROR_BC */ +#if defined(POLARSSL_ERROR_STRERROR_DUMMY) + "POLARSSL_ERROR_STRERROR_DUMMY", +#endif /* POLARSSL_ERROR_STRERROR_DUMMY */ +#if defined(POLARSSL_GENPRIME) + "POLARSSL_GENPRIME", +#endif /* POLARSSL_GENPRIME */ +#if defined(POLARSSL_FS_IO) + "POLARSSL_FS_IO", +#endif /* POLARSSL_FS_IO */ +#if defined(POLARSSL_NO_DEFAULT_ENTROPY_SOURCES) + "POLARSSL_NO_DEFAULT_ENTROPY_SOURCES", +#endif /* POLARSSL_NO_DEFAULT_ENTROPY_SOURCES */ +#if defined(POLARSSL_NO_PLATFORM_ENTROPY) + "POLARSSL_NO_PLATFORM_ENTROPY", +#endif /* POLARSSL_NO_PLATFORM_ENTROPY */ +#if defined(POLARSSL_ENTROPY_FORCE_SHA256) + "POLARSSL_ENTROPY_FORCE_SHA256", +#endif /* POLARSSL_ENTROPY_FORCE_SHA256 */ +#if defined(POLARSSL_MEMORY_DEBUG) + "POLARSSL_MEMORY_DEBUG", +#endif /* POLARSSL_MEMORY_DEBUG */ +#if defined(POLARSSL_MEMORY_BACKTRACE) + "POLARSSL_MEMORY_BACKTRACE", +#endif /* POLARSSL_MEMORY_BACKTRACE */ +#if defined(POLARSSL_PKCS1_V15) + "POLARSSL_PKCS1_V15", +#endif /* POLARSSL_PKCS1_V15 */ +#if defined(POLARSSL_PKCS1_V21) + "POLARSSL_PKCS1_V21", +#endif /* POLARSSL_PKCS1_V21 */ +#if defined(POLARSSL_RSA_NO_CRT) + "POLARSSL_RSA_NO_CRT", +#endif /* POLARSSL_RSA_NO_CRT */ +#if defined(POLARSSL_SELF_TEST) + "POLARSSL_SELF_TEST", +#endif /* POLARSSL_SELF_TEST */ +#if defined(POLARSSL_SSL_ALERT_MESSAGES) + "POLARSSL_SSL_ALERT_MESSAGES", +#endif /* POLARSSL_SSL_ALERT_MESSAGES */ +#if defined(POLARSSL_SSL_DEBUG_ALL) + "POLARSSL_SSL_DEBUG_ALL", +#endif /* POLARSSL_SSL_DEBUG_ALL */ +#if defined(POLARSSL_SSL_HW_RECORD_ACCEL) + "POLARSSL_SSL_HW_RECORD_ACCEL", +#endif /* POLARSSL_SSL_HW_RECORD_ACCEL */ +#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + "POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", +#endif /* POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ +#if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + "POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE", +#endif /* POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + "POLARSSL_SSL_MAX_FRAGMENT_LENGTH", +#endif /* POLARSSL_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(POLARSSL_SSL_PROTO_SSL3) + "POLARSSL_SSL_PROTO_SSL3", +#endif /* POLARSSL_SSL_PROTO_SSL3 */ +#if defined(POLARSSL_SSL_PROTO_TLS1) + "POLARSSL_SSL_PROTO_TLS1", +#endif /* POLARSSL_SSL_PROTO_TLS1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_1) + "POLARSSL_SSL_PROTO_TLS1_1", +#endif /* POLARSSL_SSL_PROTO_TLS1_1 */ +#if defined(POLARSSL_SSL_PROTO_TLS1_2) + "POLARSSL_SSL_PROTO_TLS1_2", +#endif /* POLARSSL_SSL_PROTO_TLS1_2 */ +#if defined(POLARSSL_SSL_ALPN) + "POLARSSL_SSL_ALPN", +#endif /* POLARSSL_SSL_ALPN */ +#if defined(POLARSSL_SSL_SESSION_TICKETS) + "POLARSSL_SSL_SESSION_TICKETS", +#endif /* POLARSSL_SSL_SESSION_TICKETS */ +#if defined(POLARSSL_SSL_SERVER_NAME_INDICATION) + "POLARSSL_SSL_SERVER_NAME_INDICATION", +#endif /* POLARSSL_SSL_SERVER_NAME_INDICATION */ +#if defined(POLARSSL_SSL_TRUNCATED_HMAC) + "POLARSSL_SSL_TRUNCATED_HMAC", +#endif /* POLARSSL_SSL_TRUNCATED_HMAC */ +#if defined(POLARSSL_SSL_SET_CURVES) + "POLARSSL_SSL_SET_CURVES", +#endif /* POLARSSL_SSL_SET_CURVES */ +#if defined(POLARSSL_THREADING_ALT) + "POLARSSL_THREADING_ALT", +#endif /* POLARSSL_THREADING_ALT */ +#if defined(POLARSSL_THREADING_PTHREAD) + "POLARSSL_THREADING_PTHREAD", +#endif /* POLARSSL_THREADING_PTHREAD */ +#if defined(POLARSSL_VERSION_FEATURES) + "POLARSSL_VERSION_FEATURES", +#endif /* POLARSSL_VERSION_FEATURES */ +#if defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) + "POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3", +#endif /* POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3 */ +#if defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + "POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", +#endif /* POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + "POLARSSL_X509_CHECK_KEY_USAGE", +#endif /* POLARSSL_X509_CHECK_KEY_USAGE */ +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) + "POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE", +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + "POLARSSL_X509_RSASSA_PSS_SUPPORT", +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ +#if defined(POLARSSL_ZLIB_SUPPORT) + "POLARSSL_ZLIB_SUPPORT", +#endif /* POLARSSL_ZLIB_SUPPORT */ +#if defined(POLARSSL_AESNI_C) + "POLARSSL_AESNI_C", +#endif /* POLARSSL_AESNI_C */ +#if defined(POLARSSL_AES_C) + "POLARSSL_AES_C", +#endif /* POLARSSL_AES_C */ +#if defined(POLARSSL_ARC4_C) + "POLARSSL_ARC4_C", +#endif /* POLARSSL_ARC4_C */ +#if defined(POLARSSL_ASN1_PARSE_C) + "POLARSSL_ASN1_PARSE_C", +#endif /* POLARSSL_ASN1_PARSE_C */ +#if defined(POLARSSL_ASN1_WRITE_C) + "POLARSSL_ASN1_WRITE_C", +#endif /* POLARSSL_ASN1_WRITE_C */ +#if defined(POLARSSL_BASE64_C) + "POLARSSL_BASE64_C", +#endif /* POLARSSL_BASE64_C */ +#if defined(POLARSSL_BIGNUM_C) + "POLARSSL_BIGNUM_C", +#endif /* POLARSSL_BIGNUM_C */ +#if defined(POLARSSL_BLOWFISH_C) + "POLARSSL_BLOWFISH_C", +#endif /* POLARSSL_BLOWFISH_C */ +#if defined(POLARSSL_CAMELLIA_C) + "POLARSSL_CAMELLIA_C", +#endif /* POLARSSL_CAMELLIA_C */ +#if defined(POLARSSL_CCM_C) + "POLARSSL_CCM_C", +#endif /* POLARSSL_CCM_C */ +#if defined(POLARSSL_CERTS_C) + "POLARSSL_CERTS_C", +#endif /* POLARSSL_CERTS_C */ +#if defined(POLARSSL_CIPHER_C) + "POLARSSL_CIPHER_C", +#endif /* POLARSSL_CIPHER_C */ +#if defined(POLARSSL_CTR_DRBG_C) + "POLARSSL_CTR_DRBG_C", +#endif /* POLARSSL_CTR_DRBG_C */ +#if defined(POLARSSL_DEBUG_C) + "POLARSSL_DEBUG_C", +#endif /* POLARSSL_DEBUG_C */ +#if defined(POLARSSL_DES_C) + "POLARSSL_DES_C", +#endif /* POLARSSL_DES_C */ +#if defined(POLARSSL_DHM_C) + "POLARSSL_DHM_C", +#endif /* POLARSSL_DHM_C */ +#if defined(POLARSSL_ECDH_C) + "POLARSSL_ECDH_C", +#endif /* POLARSSL_ECDH_C */ +#if defined(POLARSSL_ECDSA_C) + "POLARSSL_ECDSA_C", +#endif /* POLARSSL_ECDSA_C */ +#if defined(POLARSSL_ECP_C) + "POLARSSL_ECP_C", +#endif /* POLARSSL_ECP_C */ +#if defined(POLARSSL_ENTROPY_C) + "POLARSSL_ENTROPY_C", +#endif /* POLARSSL_ENTROPY_C */ +#if defined(POLARSSL_ERROR_C) + "POLARSSL_ERROR_C", +#endif /* POLARSSL_ERROR_C */ +#if defined(POLARSSL_GCM_C) + "POLARSSL_GCM_C", +#endif /* POLARSSL_GCM_C */ +#if defined(POLARSSL_HAVEGE_C) + "POLARSSL_HAVEGE_C", +#endif /* POLARSSL_HAVEGE_C */ +#if defined(POLARSSL_HMAC_DRBG_C) + "POLARSSL_HMAC_DRBG_C", +#endif /* POLARSSL_HMAC_DRBG_C */ +#if defined(POLARSSL_MD_C) + "POLARSSL_MD_C", +#endif /* POLARSSL_MD_C */ +#if defined(POLARSSL_MD2_C) + "POLARSSL_MD2_C", +#endif /* POLARSSL_MD2_C */ +#if defined(POLARSSL_MD4_C) + "POLARSSL_MD4_C", +#endif /* POLARSSL_MD4_C */ +#if defined(POLARSSL_MD5_C) + "POLARSSL_MD5_C", +#endif /* POLARSSL_MD5_C */ +#if defined(POLARSSL_MEMORY_C) + "POLARSSL_MEMORY_C", +#endif /* POLARSSL_MEMORY_C */ +#if defined(POLARSSL_MEMORY_BUFFER_ALLOC_C) + "POLARSSL_MEMORY_BUFFER_ALLOC_C", +#endif /* POLARSSL_MEMORY_BUFFER_ALLOC_C */ +#if defined(POLARSSL_NET_C) + "POLARSSL_NET_C", +#endif /* POLARSSL_NET_C */ +#if defined(POLARSSL_OID_C) + "POLARSSL_OID_C", +#endif /* POLARSSL_OID_C */ +#if defined(POLARSSL_PADLOCK_C) + "POLARSSL_PADLOCK_C", +#endif /* POLARSSL_PADLOCK_C */ +#if defined(POLARSSL_PBKDF2_C) + "POLARSSL_PBKDF2_C", +#endif /* POLARSSL_PBKDF2_C */ +#if defined(POLARSSL_PEM_PARSE_C) + "POLARSSL_PEM_PARSE_C", +#endif /* POLARSSL_PEM_PARSE_C */ +#if defined(POLARSSL_PEM_WRITE_C) + "POLARSSL_PEM_WRITE_C", +#endif /* POLARSSL_PEM_WRITE_C */ +#if defined(POLARSSL_PK_C) + "POLARSSL_PK_C", +#endif /* POLARSSL_PK_C */ +#if defined(POLARSSL_PK_PARSE_C) + "POLARSSL_PK_PARSE_C", +#endif /* POLARSSL_PK_PARSE_C */ +#if defined(POLARSSL_PK_WRITE_C) + "POLARSSL_PK_WRITE_C", +#endif /* POLARSSL_PK_WRITE_C */ +#if defined(POLARSSL_PKCS5_C) + "POLARSSL_PKCS5_C", +#endif /* POLARSSL_PKCS5_C */ +#if defined(POLARSSL_PKCS11_C) + "POLARSSL_PKCS11_C", +#endif /* POLARSSL_PKCS11_C */ +#if defined(POLARSSL_PKCS12_C) + "POLARSSL_PKCS12_C", +#endif /* POLARSSL_PKCS12_C */ +#if defined(POLARSSL_PLATFORM_C) + "POLARSSL_PLATFORM_C", +#endif /* POLARSSL_PLATFORM_C */ +#if defined(POLARSSL_RIPEMD160_C) + "POLARSSL_RIPEMD160_C", +#endif /* POLARSSL_RIPEMD160_C */ +#if defined(POLARSSL_RSA_C) + "POLARSSL_RSA_C", +#endif /* POLARSSL_RSA_C */ +#if defined(POLARSSL_SHA1_C) + "POLARSSL_SHA1_C", +#endif /* POLARSSL_SHA1_C */ +#if defined(POLARSSL_SHA256_C) + "POLARSSL_SHA256_C", +#endif /* POLARSSL_SHA256_C */ +#if defined(POLARSSL_SHA512_C) + "POLARSSL_SHA512_C", +#endif /* POLARSSL_SHA512_C */ +#if defined(POLARSSL_SSL_CACHE_C) + "POLARSSL_SSL_CACHE_C", +#endif /* POLARSSL_SSL_CACHE_C */ +#if defined(POLARSSL_SSL_CLI_C) + "POLARSSL_SSL_CLI_C", +#endif /* POLARSSL_SSL_CLI_C */ +#if defined(POLARSSL_SSL_SRV_C) + "POLARSSL_SSL_SRV_C", +#endif /* POLARSSL_SSL_SRV_C */ +#if defined(POLARSSL_SSL_TLS_C) + "POLARSSL_SSL_TLS_C", +#endif /* POLARSSL_SSL_TLS_C */ +#if defined(POLARSSL_THREADING_C) + "POLARSSL_THREADING_C", +#endif /* POLARSSL_THREADING_C */ +#if defined(POLARSSL_TIMING_C) + "POLARSSL_TIMING_C", +#endif /* POLARSSL_TIMING_C */ +#if defined(POLARSSL_VERSION_C) + "POLARSSL_VERSION_C", +#endif /* POLARSSL_VERSION_C */ +#if defined(POLARSSL_X509_USE_C) + "POLARSSL_X509_USE_C", +#endif /* POLARSSL_X509_USE_C */ +#if defined(POLARSSL_X509_CRT_PARSE_C) + "POLARSSL_X509_CRT_PARSE_C", +#endif /* POLARSSL_X509_CRT_PARSE_C */ +#if defined(POLARSSL_X509_CRL_PARSE_C) + "POLARSSL_X509_CRL_PARSE_C", +#endif /* POLARSSL_X509_CRL_PARSE_C */ +#if defined(POLARSSL_X509_CSR_PARSE_C) + "POLARSSL_X509_CSR_PARSE_C", +#endif /* POLARSSL_X509_CSR_PARSE_C */ +#if defined(POLARSSL_X509_CREATE_C) + "POLARSSL_X509_CREATE_C", +#endif /* POLARSSL_X509_CREATE_C */ +#if defined(POLARSSL_X509_CRT_WRITE_C) + "POLARSSL_X509_CRT_WRITE_C", +#endif /* POLARSSL_X509_CRT_WRITE_C */ +#if defined(POLARSSL_X509_CSR_WRITE_C) + "POLARSSL_X509_CSR_WRITE_C", +#endif /* POLARSSL_X509_CSR_WRITE_C */ +#if defined(POLARSSL_XTEA_C) + "POLARSSL_XTEA_C", +#endif /* POLARSSL_XTEA_C */ +#endif /* POLARSSL_VERSION_FEATURES */ + NULL +}; + +int version_check_feature( const char *feature ) +{ + const char **idx = features; + + if( *idx == NULL ) + return( -2 ); + + if( feature == NULL ) + return( -1 ); + + while( *idx != NULL ) + { + if( !strcasecmp( *idx, feature ) ) + return( 0 ); + idx++; + } + return( -1 ); +} + +#endif /* POLARSSL_VERSION_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509.c new file mode 100644 index 0000000..17c7a7d --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509.c @@ -0,0 +1,1102 @@ +/* + * X.509 common functions for parsing and verification + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_USE_C) + +#include "polarssl/x509.h" +#include "polarssl/asn1.h" +#include "polarssl/oid.h" +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else +#include +#endif + +#if defined(EFIX64) || defined(EFI32) +#include +#endif + +#if defined(POLARSSL_FS_IO) +#include +#if !defined(_WIN32) +#include +#include +#include +#endif +#endif + +/* + * CertificateSerialNumber ::= INTEGER + */ +int x509_get_serial( unsigned char **p, const unsigned char *end, + x509_buf *serial ) +{ + int ret; + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_SERIAL + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) && + **p != ASN1_INTEGER ) + return( POLARSSL_ERR_X509_INVALID_SERIAL + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + serial->tag = *(*p)++; + + if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_SERIAL + ret ); + + serial->p = *p; + *p += serial->len; + + return( 0 ); +} + +/* Get an algorithm identifier without parameters (eg for signatures) + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ +int x509_get_alg_null( unsigned char **p, const unsigned char *end, + x509_buf *alg ) +{ + int ret; + + if( ( ret = asn1_get_alg_null( p, end, alg ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +/* + * Parse an algorithm identifier with (optional) paramaters + */ +int x509_get_alg( unsigned char **p, const unsigned char *end, + x509_buf *alg, x509_buf *params ) +{ + int ret; + + if( ( ret = asn1_get_alg( p, end, alg, params ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) +/* + * HashAlgorithm ::= AlgorithmIdentifier + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + * + * For HashAlgorithm, parameters MUST be NULL or absent. + */ +static int x509_get_hash_alg( const x509_buf *alg, md_type_t *md_alg ) +{ + int ret; + unsigned char *p; + const unsigned char *end; + x509_buf md_oid; + size_t len; + + /* Make sure we got a SEQUENCE and setup bounds */ + if( alg->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) alg->p; + end = p + alg->len; + + if( p >= end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + /* Parse md_oid */ + md_oid.tag = *p; + + if( ( ret = asn1_get_tag( &p, end, &md_oid.len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + md_oid.p = p; + p += md_oid.len; + + /* Get md_alg from md_oid */ + if( ( ret = oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + /* Make sure params is absent of NULL */ + if( p == end ) + return( 0 ); + + if( ( ret = asn1_get_tag( &p, end, &len, ASN1_NULL ) ) != 0 || len != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] INTEGER DEFAULT 1 } + * -- Note that the tags in this Sequence are explicit. + * + * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value + * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other + * option. Enfore this at parsing time. + */ +int x509_get_rsassa_pss_params( const x509_buf *params, + md_type_t *md_alg, md_type_t *mgf_md, + int *salt_len ) +{ + int ret; + unsigned char *p; + const unsigned char *end, *end2; + size_t len; + x509_buf alg_id, alg_params; + + /* First set everything to defaults */ + *md_alg = POLARSSL_MD_SHA1; + *mgf_md = POLARSSL_MD_SHA1; + *salt_len = 20; + + /* Make sure params is a SEQUENCE and setup bounds */ + if( params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) params->p; + end = p + params->len; + + if( p == end ) + return( 0 ); + + /* + * HashAlgorithm + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + end2 = p + len; + + /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ + if( ( ret = x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) + return( ret ); + + if( ( ret = oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * MaskGenAlgorithm + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ + if( ( ret = x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) + return( ret ); + + /* Only MFG1 is recognised for now */ + if( ! OID_CMP( OID_MGF1, &alg_id ) ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE + + POLARSSL_ERR_OID_NOT_FOUND ); + + /* Parse HashAlgorithm */ + if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) + return( ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * salt_len + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 2 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = asn1_get_int( &p, end2, salt_len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * trailer_field (if present, must be 1) + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) == 0 ) + { + int trailer_field; + + end2 = p + len; + + if( ( ret = asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + if( trailer_field != 1 ) + return( POLARSSL_ERR_X509_INVALID_ALG ); + } + else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( POLARSSL_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( POLARSSL_ERR_X509_INVALID_ALG + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + +/* + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ +static int x509_get_attr_type_value( unsigned char **p, + const unsigned char *end, + x509_name *cur ) +{ + int ret; + size_t len; + x509_buf *oid; + x509_buf *val; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_NAME + ret ); + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_NAME + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + oid = &cur->oid; + oid->tag = **p; + + if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_NAME + ret ); + + oid->p = *p; + *p += oid->len; + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_NAME + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING && + **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING && + **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING ) + return( POLARSSL_ERR_X509_INVALID_NAME + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + val = &cur->val; + val->tag = *(*p)++; + + if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_NAME + ret ); + + val->p = *p; + *p += val->len; + + cur->next = NULL; + + return( 0 ); +} + +/* + * RelativeDistinguishedName ::= + * SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ +int x509_get_name( unsigned char **p, const unsigned char *end, + x509_name *cur ) +{ + int ret; + size_t len; + const unsigned char *end2; + x509_name *use; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_NAME + ret ); + + end2 = end; + end = *p + len; + use = cur; + + do + { + if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 ) + return( ret ); + + if( *p != end ) + { + use->next = (x509_name *) polarssl_malloc( + sizeof( x509_name ) ); + + if( use->next == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + memset( use->next, 0, sizeof( x509_name ) ); + + use = use->next; + } + } + while( *p != end ); + + /* + * recurse until end of SEQUENCE is reached + */ + if( *p == end2 ) + return( 0 ); + + cur->next = (x509_name *) polarssl_malloc( + sizeof( x509_name ) ); + + if( cur->next == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + memset( cur->next, 0, sizeof( x509_name ) ); + + return( x509_get_name( p, end2, cur->next ) ); +} + +/* + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + */ +int x509_get_time( unsigned char **p, const unsigned char *end, + x509_time *time ) +{ + int ret; + size_t len; + char date[64]; + unsigned char tag; + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_DATE + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + tag = **p; + + if( tag == ASN1_UTC_TIME ) + { + (*p)++; + ret = asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( POLARSSL_ERR_X509_INVALID_DATE + ret ); + + memset( date, 0, sizeof( date ) ); + memcpy( date, *p, ( len < sizeof( date ) - 1 ) ? + len : sizeof( date ) - 1 ); + + if( sscanf( date, "%2d%2d%2d%2d%2d%2dZ", + &time->year, &time->mon, &time->day, + &time->hour, &time->min, &time->sec ) < 5 ) + return( POLARSSL_ERR_X509_INVALID_DATE ); + + time->year += 100 * ( time->year < 50 ); + time->year += 1900; + + *p += len; + + return( 0 ); + } + else if( tag == ASN1_GENERALIZED_TIME ) + { + (*p)++; + ret = asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( POLARSSL_ERR_X509_INVALID_DATE + ret ); + + memset( date, 0, sizeof( date ) ); + memcpy( date, *p, ( len < sizeof( date ) - 1 ) ? + len : sizeof( date ) - 1 ); + + if( sscanf( date, "%4d%2d%2d%2d%2d%2dZ", + &time->year, &time->mon, &time->day, + &time->hour, &time->min, &time->sec ) < 5 ) + return( POLARSSL_ERR_X509_INVALID_DATE ); + + *p += len; + + return( 0 ); + } + else + return( POLARSSL_ERR_X509_INVALID_DATE + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); +} + +int x509_get_sig( unsigned char **p, const unsigned char *end, x509_buf *sig ) +{ + int ret; + size_t len; + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_SIGNATURE + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + sig->tag = **p; + + if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_SIGNATURE + ret ); + + sig->len = len; + sig->p = *p; + + *p += len; + + return( 0 ); +} + +/* + * Get signature algorithm from alg OID and optional parameters + */ +int x509_get_sig_alg( const x509_buf *sig_oid, const x509_buf *sig_params, + md_type_t *md_alg, pk_type_t *pk_alg, + void **sig_opts ) +{ + int ret; + + if( *sig_opts != NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + if( ( ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) + return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG + ret ); + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + if( *pk_alg == POLARSSL_PK_RSASSA_PSS ) + { + pk_rsassa_pss_options *pss_opts; + + pss_opts = polarssl_malloc( sizeof( pk_rsassa_pss_options ) ); + if( pss_opts == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + ret = x509_get_rsassa_pss_params( sig_params, + md_alg, + &pss_opts->mgf1_hash_id, + &pss_opts->expected_salt_len ); + if( ret != 0 ) + { + polarssl_free( pss_opts ); + return( ret ); + } + + *sig_opts = (void *) pss_opts; + } + else +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + { + /* Make sure parameters are absent or NULL */ + if( ( sig_params->tag != ASN1_NULL && sig_params->tag != 0 ) || + sig_params->len != 0 ) + return( POLARSSL_ERR_X509_INVALID_ALG ); + } + + return( 0 ); +} + +/* + * X.509 Extensions (No parsing of extensions, pointer should + * be either manually updated or extensions should be parsed! + */ +int x509_get_ext( unsigned char **p, const unsigned char *end, + x509_buf *ext, int tag ) +{ + int ret; + size_t len; + + if( *p == end ) + return( 0 ); + + ext->tag = **p; + + if( ( ret = asn1_get_tag( p, end, &ext->len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 ) + return( ret ); + + ext->p = *p; + end = *p + ext->len; + + /* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( end != *p + len ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load all data from a file into a given buffer. + */ +int x509_load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL ) + { + fclose( f ); + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + polarssl_free( *buf ); + return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + return( 0 ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +/* + * Store the name in printable form into buf; no more + * than size characters will be written + */ +int x509_dn_gets( char *buf, size_t size, const x509_name *dn ) +{ + int ret; + size_t i, n; + unsigned char c; + const x509_name *name; + const char *short_name = NULL; + char s[128], *p; + + memset( s, 0, sizeof( s ) ); + + name = dn; + p = buf; + n = size; + + while( name != NULL ) + { + if( !name->oid.p ) + { + name = name->next; + continue; + } + + if( name != dn ) + { + ret = snprintf( p, n, ", " ); + SAFE_SNPRINTF(); + } + + ret = oid_get_attr_short_name( &name->oid, &short_name ); + + if( ret == 0 ) + ret = snprintf( p, n, "%s=", short_name ); + else + ret = snprintf( p, n, "\?\?=" ); + SAFE_SNPRINTF(); + + for( i = 0; i < name->val.len; i++ ) + { + if( i >= sizeof( s ) - 1 ) + break; + + c = name->val.p[i]; + if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) + s[i] = '?'; + else s[i] = c; + } + s[i] = '\0'; + ret = snprintf( p, n, "%s", s ); + SAFE_SNPRINTF(); + name = name->next; + } + + return( (int) ( size - n ) ); +} + +/* + * Store the serial in printable form into buf; no more + * than size characters will be written + */ +int x509_serial_gets( char *buf, size_t size, const x509_buf *serial ) +{ + int ret; + size_t i, n, nr; + char *p; + + p = buf; + n = size; + + nr = ( serial->len <= 32 ) + ? serial->len : 28; + + for( i = 0; i < nr; i++ ) + { + if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) + continue; + + ret = snprintf( p, n, "%02X%s", + serial->p[i], ( i < nr - 1 ) ? ":" : "" ); + SAFE_SNPRINTF(); + } + + if( nr != serial->len ) + { + ret = snprintf( p, n, "...." ); + SAFE_SNPRINTF(); + } + + return( (int) ( size - n ) ); +} + +/* + * Helper for writing signature algorithms + */ +int x509_sig_alg_gets( char *buf, size_t size, const x509_buf *sig_oid, + pk_type_t pk_alg, md_type_t md_alg, + const void *sig_opts ) +{ + int ret; + char *p = buf; + size_t n = size; + const char *desc = NULL; + + ret = oid_get_sig_alg_desc( sig_oid, &desc ); + if( ret != 0 ) + ret = snprintf( p, n, "???" ); + else + ret = snprintf( p, n, "%s", desc ); + SAFE_SNPRINTF(); + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + if( pk_alg == POLARSSL_PK_RSASSA_PSS ) + { + const pk_rsassa_pss_options *pss_opts; + const md_info_t *md_info, *mgf_md_info; + + pss_opts = (const pk_rsassa_pss_options *) sig_opts; + + md_info = md_info_from_type( md_alg ); + mgf_md_info = md_info_from_type( pss_opts->mgf1_hash_id ); + + ret = snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", + md_info ? md_info->name : "???", + mgf_md_info ? mgf_md_info->name : "???", + pss_opts->expected_salt_len ); + SAFE_SNPRINTF(); + } +#else + ((void) pk_alg); + ((void) md_alg); + ((void) sig_opts); +#endif /* POLARSSL_X509_RSASSA_PSS_SUPPORT */ + + return( (int) size - n ); +} + +/* + * Helper for writing "RSA key size", "EC key size", etc + */ +int x509_key_size_helper( char *buf, size_t size, const char *name ) +{ + char *p = buf; + size_t n = size; + int ret; + + if( strlen( name ) + sizeof( " key size" ) > size ) + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); + + ret = snprintf( p, n, "%s key size", name ); + SAFE_SNPRINTF(); + + return( 0 ); +} + +/* + * Return an informational string describing the given OID + */ +const char *x509_oid_get_description( x509_buf *oid ) +{ + const char *desc = NULL; + int ret; + + ret = oid_get_extended_key_usage( oid, &desc ); + + if( ret != 0 ) + return( NULL ); + + return( desc ); +} + +/* Return the x.y.z.... style numeric string for the given OID */ +int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid ) +{ + return oid_get_numeric_string( buf, size, oid ); +} + +/* + * Return 0 if the x509_time is still valid, or 1 otherwise. + */ +#if defined(POLARSSL_HAVE_TIME) + +static void x509_get_current_time( x509_time *now ) +{ +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + SYSTEMTIME st; + + GetSystemTime( &st ); + + now->year = st.wYear; + now->mon = st.wMonth; + now->day = st.wDay; + now->hour = st.wHour; + now->min = st.wMinute; + now->sec = st.wSecond; +#else + struct tm lt; + time_t tt; + + tt = time( NULL ); + gmtime_r( &tt, < ); + + now->year = lt.tm_year + 1900; + now->mon = lt.tm_mon + 1; + now->day = lt.tm_mday; + now->hour = lt.tm_hour; + now->min = lt.tm_min; + now->sec = lt.tm_sec; +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +} + +/* + * Return 0 if before <= after, 1 otherwise + */ +static int x509_check_time( const x509_time *before, const x509_time *after ) +{ + if( before->year > after->year ) + return( 1 ); + + if( before->year == after->year && + before->mon > after->mon ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day > after->day ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour > after->hour ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min > after->min ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min == after->min && + before->sec > after->sec ) + return( 1 ); + + return( 0 ); +} + +int x509_time_expired( const x509_time *to ) +{ + x509_time now; + + x509_get_current_time( &now ); + + return( x509_check_time( &now, to ) ); +} + +int x509_time_future( const x509_time *from ) +{ + x509_time now; + + x509_get_current_time( &now ); + + return( x509_check_time( from, &now ) ); +} + +#else /* POLARSSL_HAVE_TIME */ + +int x509_time_expired( const x509_time *to ) +{ + ((void) to); + return( 0 ); +} + +int x509_time_future( const x509_time *from ) +{ + ((void) from); + return( 0 ); +} +#endif /* POLARSSL_HAVE_TIME */ + +#if defined(POLARSSL_SELF_TEST) + +#include "polarssl/x509_crt.h" +#include "polarssl/certs.h" + +/* + * Checkup routine + */ +int x509_self_test( int verbose ) +{ +#if defined(POLARSSL_CERTS_C) && defined(POLARSSL_SHA1_C) + int ret; + int flags; + x509_crt cacert; + x509_crt clicert; + + if( verbose != 0 ) + polarssl_printf( " X.509 certificate load: " ); + + x509_crt_init( &clicert ); + + ret = x509_crt_parse( &clicert, (const unsigned char *) test_cli_crt, + strlen( test_cli_crt ) ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( ret ); + } + + x509_crt_init( &cacert ); + + ret = x509_crt_parse( &cacert, (const unsigned char *) test_ca_crt, + strlen( test_ca_crt ) ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( ret ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n X.509 signature verify: "); + + ret = x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); + if( ret != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + polarssl_printf( "ret = %d, &flags = %04x\n", ret, flags ); + + return( ret ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n"); + + x509_crt_free( &cacert ); + x509_crt_free( &clicert ); + + return( 0 ); +#else + ((void) verbose); + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); +#endif /* POLARSSL_CERTS_C && POLARSSL_SHA1_C */ +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_X509_USE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_create.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_create.c new file mode 100644 index 0000000..1019313 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_create.c @@ -0,0 +1,318 @@ +/* + * X.509 base functions for creating certificates / CSRs + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CREATE_C) + +#include "polarssl/x509.h" +#include "polarssl/asn1write.h" +#include "polarssl/oid.h" + +#if defined(_MSC_VER) && !defined strncasecmp && !defined(EFIX64) && \ + !defined(EFI32) +#define strncasecmp _strnicmp +#endif + +typedef struct { + const char *name; + size_t name_len; + const char*oid; +} x509_attr_descriptor_t; + +#define ADD_STRLEN( s ) s, sizeof( s ) - 1 + +static const x509_attr_descriptor_t x509_attrs[] = +{ + { ADD_STRLEN( "CN" ), OID_AT_CN }, + { ADD_STRLEN( "commonName" ), OID_AT_CN }, + { ADD_STRLEN( "C" ), OID_AT_COUNTRY }, + { ADD_STRLEN( "countryName" ), OID_AT_COUNTRY }, + { ADD_STRLEN( "O" ), OID_AT_ORGANIZATION }, + { ADD_STRLEN( "organizationName" ), OID_AT_ORGANIZATION }, + { ADD_STRLEN( "L" ), OID_AT_LOCALITY }, + { ADD_STRLEN( "locality" ), OID_AT_LOCALITY }, + { ADD_STRLEN( "R" ), OID_PKCS9_EMAIL }, + { ADD_STRLEN( "OU" ), OID_AT_ORG_UNIT }, + { ADD_STRLEN( "organizationalUnitName" ), OID_AT_ORG_UNIT }, + { ADD_STRLEN( "ST" ), OID_AT_STATE }, + { ADD_STRLEN( "stateOrProvinceName" ), OID_AT_STATE }, + { ADD_STRLEN( "emailAddress" ), OID_PKCS9_EMAIL }, + { ADD_STRLEN( "serialNumber" ), OID_AT_SERIAL_NUMBER }, + { ADD_STRLEN( "postalAddress" ), OID_AT_POSTAL_ADDRESS }, + { ADD_STRLEN( "postalCode" ), OID_AT_POSTAL_CODE }, + { ADD_STRLEN( "dnQualifier" ), OID_AT_DN_QUALIFIER }, + { ADD_STRLEN( "title" ), OID_AT_TITLE }, + { ADD_STRLEN( "surName" ), OID_AT_SUR_NAME }, + { ADD_STRLEN( "SN" ), OID_AT_SUR_NAME }, + { ADD_STRLEN( "givenName" ), OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "GN" ), OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "initials" ), OID_AT_INITIALS }, + { ADD_STRLEN( "pseudonym" ), OID_AT_PSEUDONYM }, + { ADD_STRLEN( "generationQualifier" ), OID_AT_GENERATION_QUALIFIER }, + { ADD_STRLEN( "domainComponent" ), OID_DOMAIN_COMPONENT }, + { ADD_STRLEN( "DC" ), OID_DOMAIN_COMPONENT }, + { NULL, 0, NULL } +}; + +static const char *x509_at_oid_from_name( const char *name, size_t name_len ) +{ + const x509_attr_descriptor_t *cur; + + for( cur = x509_attrs; cur->name != NULL; cur++ ) + if( cur->name_len == name_len && + strncasecmp( cur->name, name, name_len ) == 0 ) + break; + + return( cur->oid ); +} + +int x509_string_to_names( asn1_named_data **head, const char *name ) +{ + int ret = 0; + const char *s = name, *c = s; + const char *end = s + strlen( s ); + const char *oid = NULL; + int in_tag = 1; + + /* Clear existing chain if present */ + asn1_free_named_data_list( head ); + + while( c <= end ) + { + if( in_tag && *c == '=' ) + { + if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) + { + ret = POLARSSL_ERR_X509_UNKNOWN_OID; + goto exit; + } + + s = c + 1; + in_tag = 0; + } + + if( !in_tag && ( *c == ',' || c == end ) ) + { + if( asn1_store_named_data( head, oid, strlen( oid ), + (unsigned char *) s, + c - s ) == NULL ) + { + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + } + + while( c < end && *(c + 1) == ' ' ) + c++; + + s = c + 1; + in_tag = 1; + } + c++; + } + +exit: + + return( ret ); +} + +/* The first byte of the value in the asn1_named_data structure is reserved + * to store the critical boolean for us + */ +int x509_set_extension( asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, size_t val_len ) +{ + asn1_named_data *cur; + + if( ( cur = asn1_store_named_data( head, oid, oid_len, + NULL, val_len + 1 ) ) == NULL ) + { + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + } + + cur->val.p[0] = critical; + memcpy( cur->val.p + 1, val, val_len ); + + return( 0 ); +} + +/* + * RelativeDistinguishedName ::= + * SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ +static int x509_write_name( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + const unsigned char *name, size_t name_len ) +{ + int ret; + size_t len = 0; + + // Write PrintableString for all except OID_PKCS9_EMAIL + // + if( OID_SIZE( OID_PKCS9_EMAIL ) == oid_len && + memcmp( oid, OID_PKCS9_EMAIL, oid_len ) == 0 ) + { + ASN1_CHK_ADD( len, asn1_write_ia5_string( p, start, + (const char *) name, + name_len ) ); + } + else + { + ASN1_CHK_ADD( len, asn1_write_printable_string( p, start, + (const char *) name, + name_len ) ); + } + + // Write OID + // + ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SET ) ); + + return( (int) len ); +} + +int x509_write_names( unsigned char **p, unsigned char *start, + asn1_named_data *first ) +{ + int ret; + size_t len = 0; + asn1_named_data *cur = first; + + while( cur != NULL ) + { + ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p, + cur->oid.len, + cur->val.p, cur->val.len ) ); + cur = cur->next; + } + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ) +{ + int ret; + size_t len = 0; + + if( *p - start < (int) size + 1 ) + return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); + + len = size; + (*p) -= len; + memcpy( *p, sig, len ); + + *--(*p) = 0; + len += 1; + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) ); + + // Write OID + // + ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid, + oid_len, 0 ) ); + + return( (int) len ); +} + +static int x509_write_extension( unsigned char **p, unsigned char *start, + asn1_named_data *ext ) +{ + int ret; + size_t len = 0; + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->val.p + 1, + ext->val.len - 1 ) ); + ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->val.len - 1 ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OCTET_STRING ) ); + + if( ext->val.p[0] != 0 ) + { + ASN1_CHK_ADD( len, asn1_write_bool( p, start, 1 ) ); + } + + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, ext->oid.p, + ext->oid.len ) ); + ASN1_CHK_ADD( len, asn1_write_len( p, start, ext->oid.len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_OID ) ); + + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +/* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING + * -- contains the DER encoding of an ASN.1 value + * -- corresponding to the extension type identified + * -- by extnID + * } + */ +int x509_write_extensions( unsigned char **p, unsigned char *start, + asn1_named_data *first ) +{ + int ret; + size_t len = 0; + asn1_named_data *cur_ext = first; + + while( cur_ext != NULL ) + { + ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); + cur_ext = cur_ext->next; + } + + return( (int) len ); +} + +#endif /* POLARSSL_X509_CREATE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crl.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crl.c new file mode 100644 index 0000000..7dd53c2 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crl.c @@ -0,0 +1,768 @@ +/* + * X.509 Certidicate Revocation List (CRL) parsing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CRL_PARSE_C) + +#include "polarssl/x509_crl.h" +#include "polarssl/oid.h" +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#include +#else +#include +#endif + +#if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32) +#include +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Version ::= INTEGER { v1(0), v2(1) } + */ +static int x509_crl_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + + if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( POLARSSL_ERR_X509_INVALID_VERSION + ret ); + } + + return( 0 ); +} + +/* + * X.509 CRL v2 extensions (no extensions parsed yet.) + */ +static int x509_get_crl_ext( unsigned char **p, + const unsigned char *end, + x509_buf *ext ) +{ + int ret; + size_t len = 0; + + /* Get explicit tag */ + if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + while( *p < end ) + { + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + *p += len; + } + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 CRL v2 entry extensions (no extensions parsed yet.) + */ +static int x509_get_crl_entry_ext( unsigned char **p, + const unsigned char *end, + x509_buf *ext ) +{ + int ret; + size_t len = 0; + + /* OPTIONAL */ + if( end <= *p ) + return( 0 ); + + ext->tag = **p; + ext->p = *p; + + /* + * Get CRL-entry extension sequence header + * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2 + */ + if( ( ret = asn1_get_tag( p, end, &ext->len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + ext->p = NULL; + return( 0 ); + } + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + } + + end = *p + ext->len; + + if( end != *p + ext->len ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + *p += len; + } + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 CRL Entries + */ +static int x509_get_entries( unsigned char **p, + const unsigned char *end, + x509_crl_entry *entry ) +{ + int ret; + size_t entry_len; + x509_crl_entry *cur_entry = entry; + + if( *p == end ) + return( 0 ); + + if( ( ret = asn1_get_tag( p, end, &entry_len, + ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + end = *p + entry_len; + + while( *p < end ) + { + size_t len2; + const unsigned char *end2; + + if( ( ret = asn1_get_tag( p, end, &len2, + ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 ) + { + return( ret ); + } + + cur_entry->raw.tag = **p; + cur_entry->raw.p = *p; + cur_entry->raw.len = len2; + end2 = *p + len2; + + if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 ) + return( ret ); + + if( ( ret = x509_get_time( p, end2, + &cur_entry->revocation_date ) ) != 0 ) + return( ret ); + + if( ( ret = x509_get_crl_entry_ext( p, end2, + &cur_entry->entry_ext ) ) != 0 ) + return( ret ); + + if( *p < end ) + { + cur_entry->next = polarssl_malloc( sizeof( x509_crl_entry ) ); + + if( cur_entry->next == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + cur_entry = cur_entry->next; + memset( cur_entry, 0, sizeof( x509_crl_entry ) ); + } + } + + return( 0 ); +} + +/* + * Parse one or more CRLs and add them to the chained list + */ +int x509_crl_parse( x509_crl *chain, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + x509_crl *crl; + x509_buf sig_params1, sig_params2; + +#if defined(POLARSSL_PEM_PARSE_C) + size_t use_len; + pem_context pem; +#endif + + memset( &sig_params1, 0, sizeof( x509_buf ) ); + memset( &sig_params2, 0, sizeof( x509_buf ) ); + + crl = chain; + + /* + * Check for valid input + */ + if( crl == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + while( crl->version != 0 && crl->next != NULL ) + crl = crl->next; + + /* + * Add new CRL on the end of the chain if needed. + */ + if( crl->version != 0 && crl->next == NULL ) + { + crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) ); + + if( crl->next == NULL ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + } + + crl = crl->next; + x509_crl_init( crl ); + } + +#if defined(POLARSSL_PEM_PARSE_C) + pem_init( &pem ); + ret = pem_read_buffer( &pem, + "-----BEGIN X509 CRL-----", + "-----END X509 CRL-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + buflen -= use_len; + buf += use_len; + + /* + * Steal PEM buffer + */ + p = pem.buf; + pem.buf = NULL; + len = pem.buflen; + pem_free( &pem ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + return( ret ); + } + else +#endif /* POLARSSL_PEM_PARSE_C */ + { + /* + * nope, copy the raw DER data + */ + p = (unsigned char *) polarssl_malloc( len = buflen ); + + if( p == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + memcpy( p, buf, buflen ); + + buflen = 0; + } + + crl->raw.p = p; + crl->raw.len = len; + end = p + len; + + /* + * CertificateList ::= SEQUENCE { + * tbsCertList TBSCertList, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT ); + } + + if( len != (size_t) ( end - p ) ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + /* + * TBSCertList ::= SEQUENCE { + */ + crl->tbs.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + crl->tbs.len = end - crl->tbs.p; + + /* + * Version ::= INTEGER OPTIONAL { v1(0), v2(1) } + * -- if present, MUST be v2 + * + * signature AlgorithmIdentifier + */ + if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || + ( ret = x509_get_alg( &p, end, &crl->sig_oid1, &sig_params1 ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + crl->version++; + + if( crl->version > 2 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); + } + + if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &sig_params1, + &crl->sig_md, &crl->sig_pk, + &crl->sig_opts ) ) != 0 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); + } + + /* + * issuer Name + */ + crl->issuer_raw.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + crl->issuer_raw.len = p - crl->issuer_raw.p; + + /* + * thisUpdate Time + * nextUpdate Time OPTIONAL + */ + if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 ) + { + if( ret != ( POLARSSL_ERR_X509_INVALID_DATE + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) && + ret != ( POLARSSL_ERR_X509_INVALID_DATE + + POLARSSL_ERR_ASN1_OUT_OF_DATA ) ) + { + x509_crl_free( crl ); + return( ret ); + } + } + + /* + * revokedCertificates SEQUENCE OF SEQUENCE { + * userCertificate CertificateSerialNumber, + * revocationDate Time, + * crlEntryExtensions Extensions OPTIONAL + * -- if present, MUST be v2 + * } OPTIONAL + */ + if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + /* + * crlExtensions EXPLICIT Extensions OPTIONAL + * -- if present, MUST be v2 + */ + if( crl->version == 2 ) + { + ret = x509_get_crl_ext( &p, end, &crl->crl_ext ); + + if( ret != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + } + + if( p != end ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + end = crl->raw.p + crl->raw.len; + + /* + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2, &sig_params2 ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + if( crl->sig_oid1.len != crl->sig_oid2.len || + memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 || + sig_params1.len != sig_params2.len || + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_SIG_MISMATCH ); + } + + if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 ) + { + x509_crl_free( crl ); + return( ret ); + } + + if( p != end ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + if( buflen > 0 ) + { + crl->next = (x509_crl *) polarssl_malloc( sizeof( x509_crl ) ); + + if( crl->next == NULL ) + { + x509_crl_free( crl ); + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + } + + crl = crl->next; + x509_crl_init( crl ); + + return( x509_crl_parse( crl, buf, buflen ) ); + } + + return( 0 ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load one or more CRLs and add them to the chained list + */ +int x509_crl_parse_file( x509_crl *chain, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = x509_crl_parse( chain, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +/* + * Return an informational string about the certificate. + */ +#define BEFORE_COLON 14 +#define BC "14" +/* + * Return an informational string about the CRL. + */ +int x509_crl_info( char *buf, size_t size, const char *prefix, + const x509_crl *crl ) +{ + int ret; + size_t n; + char *p; + const x509_crl_entry *entry; + + p = buf; + n = size; + + ret = snprintf( p, n, "%sCRL version : %d", + prefix, crl->version ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%sissuer name : ", prefix ); + SAFE_SNPRINTF(); + ret = x509_dn_gets( p, n, &crl->issuer ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%sthis update : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crl->this_update.year, crl->this_update.mon, + crl->this_update.day, crl->this_update.hour, + crl->this_update.min, crl->this_update.sec ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%snext update : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crl->next_update.year, crl->next_update.mon, + crl->next_update.day, crl->next_update.hour, + crl->next_update.min, crl->next_update.sec ); + SAFE_SNPRINTF(); + + entry = &crl->entry; + + ret = snprintf( p, n, "\n%sRevoked certificates:", + prefix ); + SAFE_SNPRINTF(); + + while( entry != NULL && entry->raw.len != 0 ) + { + ret = snprintf( p, n, "\n%sserial number: ", + prefix ); + SAFE_SNPRINTF(); + + ret = x509_serial_gets( p, n, &entry->serial ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, " revocation date: " \ + "%04d-%02d-%02d %02d:%02d:%02d", + entry->revocation_date.year, entry->revocation_date.mon, + entry->revocation_date.day, entry->revocation_date.hour, + entry->revocation_date.min, entry->revocation_date.sec ); + SAFE_SNPRINTF(); + + entry = entry->next; + } + + ret = snprintf( p, n, "\n%ssigned using : ", prefix ); + SAFE_SNPRINTF(); + + ret = x509_sig_alg_gets( p, n, &crl->sig_oid1, crl->sig_pk, crl->sig_md, + crl->sig_opts ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n" ); + SAFE_SNPRINTF(); + + return( (int) ( size - n ) ); +} + +/* + * Initialize a CRL chain + */ +void x509_crl_init( x509_crl *crl ) +{ + memset( crl, 0, sizeof(x509_crl) ); +} + +/* + * Unallocate all CRL data + */ +void x509_crl_free( x509_crl *crl ) +{ + x509_crl *crl_cur = crl; + x509_crl *crl_prv; + x509_name *name_cur; + x509_name *name_prv; + x509_crl_entry *entry_cur; + x509_crl_entry *entry_prv; + + if( crl == NULL ) + return; + + do + { +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( crl_cur->sig_opts ); +#endif + + name_cur = crl_cur->issuer.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + polarssl_zeroize( name_prv, sizeof( x509_name ) ); + polarssl_free( name_prv ); + } + + entry_cur = crl_cur->entry.next; + while( entry_cur != NULL ) + { + entry_prv = entry_cur; + entry_cur = entry_cur->next; + polarssl_zeroize( entry_prv, sizeof( x509_crl_entry ) ); + polarssl_free( entry_prv ); + } + + if( crl_cur->raw.p != NULL ) + { + polarssl_zeroize( crl_cur->raw.p, crl_cur->raw.len ); + polarssl_free( crl_cur->raw.p ); + } + + crl_cur = crl_cur->next; + } + while( crl_cur != NULL ); + + crl_cur = crl; + do + { + crl_prv = crl_cur; + crl_cur = crl_cur->next; + + polarssl_zeroize( crl_prv, sizeof( x509_crl ) ); + if( crl_prv != crl ) + polarssl_free( crl_prv ); + } + while( crl_cur != NULL ); +} + +#endif /* POLARSSL_X509_CRL_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crt.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crt.c new file mode 100644 index 0000000..03cdda8 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_crt.c @@ -0,0 +1,2018 @@ +/* + * X.509 certificate parsing and verification + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CRT_PARSE_C) + +#include "polarssl/x509_crt.h" +#include "polarssl/oid.h" +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#if defined(POLARSSL_THREADING_C) +#include "polarssl/threading.h" +#endif + +#include +#include +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else +#include +#endif + +#if defined(EFIX64) || defined(EFI32) +#include +#endif + +#if defined(POLARSSL_FS_IO) +#include +#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) +#include +#include +#include +#endif +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ +static int x509_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( ret ); + } + + end = *p + len; + + if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_VERSION + ret ); + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_VERSION + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + */ +static int x509_get_dates( unsigned char **p, + const unsigned char *end, + x509_time *from, + x509_time *to ) +{ + int ret; + size_t len; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_DATE + ret ); + + end = *p + len; + + if( ( ret = x509_get_time( p, end, from ) ) != 0 ) + return( ret ); + + if( ( ret = x509_get_time( p, end, to ) ) != 0 ) + return( ret ); + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_DATE + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 v2/v3 unique identifier (not parsed) + */ +static int x509_get_uid( unsigned char **p, + const unsigned char *end, + x509_buf *uid, int n ) +{ + int ret; + + if( *p == end ) + return( 0 ); + + uid->tag = **p; + + if( ( ret = asn1_get_tag( p, end, &uid->len, + ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + uid->p = *p; + *p += uid->len; + + return( 0 ); +} + +static int x509_get_basic_constraints( unsigned char **p, + const unsigned char *end, + int *ca_istrue, + int *max_pathlen ) +{ + int ret; + size_t len; + + /* + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ + *ca_istrue = 0; /* DEFAULT FALSE */ + *max_pathlen = 0; /* endless */ + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p == end ) + return( 0 ); + + if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + ret = asn1_get_int( p, end, ca_istrue ); + + if( ret != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *ca_istrue != 0 ) + *ca_istrue = 1; + } + + if( *p == end ) + return( 0 ); + + if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + (*max_pathlen)++; + + return( 0 ); +} + +static int x509_get_ns_cert_type( unsigned char **p, + const unsigned char *end, + unsigned char *ns_cert_type) +{ + int ret; + x509_bitstring bs = { 0, 0, NULL }; + + if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( bs.len != 1 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + /* Get actual bitstring */ + *ns_cert_type = *bs.p; + return( 0 ); +} + +static int x509_get_key_usage( unsigned char **p, + const unsigned char *end, + unsigned char *key_usage) +{ + int ret; + x509_bitstring bs = { 0, 0, NULL }; + + if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( bs.len < 1 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + /* Get actual bitstring */ + *key_usage = *bs.p; + return( 0 ); +} + +/* + * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + * + * KeyPurposeId ::= OBJECT IDENTIFIER + */ +static int x509_get_ext_key_usage( unsigned char **p, + const unsigned char *end, + x509_sequence *ext_key_usage) +{ + int ret; + + if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Sequence length must be >= 1 */ + if( ext_key_usage->buf.p == NULL ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_INVALID_LENGTH ); + + return( 0 ); +} + +/* + * SubjectAltName ::= GeneralNames + * + * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName + * + * GeneralName ::= CHOICE { + * otherName [0] OtherName, + * rfc822Name [1] IA5String, + * dNSName [2] IA5String, + * x400Address [3] ORAddress, + * directoryName [4] Name, + * ediPartyName [5] EDIPartyName, + * uniformResourceIdentifier [6] IA5String, + * iPAddress [7] OCTET STRING, + * registeredID [8] OBJECT IDENTIFIER } + * + * OtherName ::= SEQUENCE { + * type-id OBJECT IDENTIFIER, + * value [0] EXPLICIT ANY DEFINED BY type-id } + * + * EDIPartyName ::= SEQUENCE { + * nameAssigner [0] DirectoryString OPTIONAL, + * partyName [1] DirectoryString } + * + * NOTE: PolarSSL only parses and uses dNSName at this point. + */ +static int x509_get_subject_alt_name( unsigned char **p, + const unsigned char *end, + x509_sequence *subject_alt_name ) +{ + int ret; + size_t len, tag_len; + asn1_buf *buf; + unsigned char tag; + asn1_sequence *cur = subject_alt_name; + + /* Get main sequence tag */ + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p + len != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + tag = **p; + (*p)++; + if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + + /* Skip everything but DNS name */ + if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) ) + { + *p += tag_len; + continue; + } + + /* Allocate and assign next pointer */ + if( cur->buf.p != NULL ) + { + cur->next = (asn1_sequence *) polarssl_malloc( + sizeof( asn1_sequence ) ); + + if( cur->next == NULL ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_MALLOC_FAILED ); + + memset( cur->next, 0, sizeof( asn1_sequence ) ); + cur = cur->next; + } + + buf = &(cur->buf); + buf->tag = tag; + buf->p = *p; + buf->len = tag_len; + *p += buf->len; + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 v3 extensions + * + * TODO: Perform all of the basic constraints tests required by the RFC + * TODO: Set values for undetected extensions to a sane default? + * + */ +static int x509_get_crt_ext( unsigned char **p, + const unsigned char *end, + x509_crt *crt ) +{ + int ret; + size_t len; + unsigned char *end_ext_data, *end_ext_octet; + + if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + while( *p < end ) + { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + int ext_type = 0; + + if( ( ret = asn1_get_tag( p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + end_ext_data = *p + len; + + /* Get extension ID */ + extn_oid.tag = **p; + + if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + extn_oid.p = *p; + *p += extn_oid.len; + + if( ( end - *p ) < 1 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_OUT_OF_DATA ); + + /* Get optional critical */ + if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && + ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Data should be octet string type */ + if( ( ret = asn1_get_tag( p, end_ext_data, &len, + ASN1_OCTET_STRING ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); + + end_ext_octet = *p + len; + + if( end_ext_octet != end_ext_data ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Detect supported extensions + */ + ret = oid_get_x509_ext_type( &extn_oid, &ext_type ); + + if( ret != 0 ) + { + /* No parser found, skip extension */ + *p = end_ext_octet; + +#if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + if( is_critical ) + { + /* Data is marked as critical: fail */ + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); + } +#endif + continue; + } + + crt->ext_types |= ext_type; + + switch( ext_type ) + { + case EXT_BASIC_CONSTRAINTS: + /* Parse basic constraints */ + if( ( ret = x509_get_basic_constraints( p, end_ext_octet, + &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) + return( ret ); + break; + + case EXT_KEY_USAGE: + /* Parse key usage */ + if( ( ret = x509_get_key_usage( p, end_ext_octet, + &crt->key_usage ) ) != 0 ) + return( ret ); + break; + + case EXT_EXTENDED_KEY_USAGE: + /* Parse extended key usage */ + if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + break; + + case EXT_SUBJECT_ALT_NAME: + /* Parse subject alt name */ + if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); + break; + + case EXT_NS_CERT_TYPE: + /* Parse netscape certificate type */ + if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, + &crt->ns_cert_type ) ) != 0 ) + return( ret ); + break; + + default: + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + } + } + + if( *p != end ) + return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Parse and fill a single X.509 certificate in DER format + */ +static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, + size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end, *crt_end; + x509_buf sig_params1, sig_params2; + + memset( &sig_params1, 0, sizeof( x509_buf ) ); + memset( &sig_params2, 0, sizeof( x509_buf ) ); + + /* + * Check for valid input + */ + if( crt == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + p = (unsigned char *) polarssl_malloc( len = buflen ); + + if( p == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + memcpy( p, buf, buflen ); + + crt->raw.p = p; + crt->raw.len = len; + end = p + len; + + /* + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT ); + } + + if( len > (size_t) ( end - p ) ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + crt_end = p + len; + + /* + * TBSCertificate ::= SEQUENCE { + */ + crt->tbs.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + crt->tbs.len = end - crt->tbs.p; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * + * CertificateSerialNumber ::= INTEGER + * + * signature AlgorithmIdentifier + */ + if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || + ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || + ( ret = x509_get_alg( &p, end, &crt->sig_oid1, + &sig_params1 ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + crt->version++; + + if( crt->version > 3 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); + } + + if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1, + &crt->sig_md, &crt->sig_pk, + &crt->sig_opts ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + /* + * issuer Name + */ + crt->issuer_raw.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + crt->issuer_raw.len = p - crt->issuer_raw.p; + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + * + */ + if( ( ret = x509_get_dates( &p, end, &crt->valid_from, + &crt->valid_to ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + /* + * subject Name + */ + crt->subject_raw.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + crt->subject_raw.len = p - crt->subject_raw.p; + + /* + * SubjectPublicKeyInfo + */ + if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + /* + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version shall be v3 + */ + if( crt->version == 2 || crt->version == 3 ) + { + ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); + if( ret != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + } + + if( crt->version == 2 || crt->version == 3 ) + { + ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); + if( ret != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + } + +#if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) + if( crt->version == 3 ) + { +#endif + ret = x509_get_crt_ext( &p, end, crt ); + if( ret != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } +#if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) + } +#endif + + if( p != end ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + end = crt_end; + + /* + * } + * -- end of TBSCertificate + * + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + if( crt->sig_oid1.len != crt->sig_oid2.len || + memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 || + sig_params1.len != sig_params2.len || + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_SIG_MISMATCH ); + } + + if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 ) + { + x509_crt_free( crt ); + return( ret ); + } + + if( p != end ) + { + x509_crt_free( crt ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); +} + +/* + * Parse one X.509 certificate in DER format from a buffer and add them to a + * chained list + */ +int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf, + size_t buflen ) +{ + int ret; + x509_crt *crt = chain, *prev = NULL; + + /* + * Check for valid input + */ + if( crt == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + while( crt->version != 0 && crt->next != NULL ) + { + prev = crt; + crt = crt->next; + } + + /* + * Add new certificate on the end of the chain if needed. + */ + if( crt->version != 0 && crt->next == NULL ) + { + crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) ); + + if( crt->next == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + prev = crt; + crt = crt->next; + x509_crt_init( crt ); + } + + if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) + { + if( prev ) + prev->next = NULL; + + if( crt != chain ) + polarssl_free( crt ); + + return( ret ); + } + + return( 0 ); +} + +/* + * Parse one or more PEM certificates from a buffer and add them to the chained + * list + */ +int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen ) +{ + int success = 0, first_error = 0, total_failed = 0; + int buf_format = X509_FORMAT_DER; + + /* + * Check for valid input + */ + if( chain == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + /* + * Determine buffer content. Buffer contains either one DER certificate or + * one or more PEM certificates. + */ +#if defined(POLARSSL_PEM_PARSE_C) + if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) + buf_format = X509_FORMAT_PEM; +#endif + + if( buf_format == X509_FORMAT_DER ) + return x509_crt_parse_der( chain, buf, buflen ); + +#if defined(POLARSSL_PEM_PARSE_C) + if( buf_format == X509_FORMAT_PEM ) + { + int ret; + pem_context pem; + + while( buflen > 0 ) + { + size_t use_len; + pem_init( &pem ); + + ret = pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE-----", + "-----END CERTIFICATE-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + buflen -= use_len; + buf += use_len; + } + else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA ) + { + return( ret ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + + /* + * PEM header and footer were found + */ + buflen -= use_len; + buf += use_len; + + if( first_error == 0 ) + first_error = ret; + + continue; + } + else + break; + + ret = x509_crt_parse_der( chain, pem.buf, pem.buflen ); + + pem_free( &pem ); + + if( ret != 0 ) + { + /* + * Quit parsing on a memory error + */ + if( ret == POLARSSL_ERR_X509_MALLOC_FAILED ) + return( ret ); + + if( first_error == 0 ) + first_error = ret; + + total_failed++; + continue; + } + + success = 1; + } + } +#endif /* POLARSSL_PEM_PARSE_C */ + + if( success ) + return( total_failed ); + else if( first_error ) + return( first_error ); + else + return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load one or more certificates and add them to the chained list + */ +int x509_crt_parse_file( x509_crt *chain, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = x509_crt_parse( chain, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} + +#if defined(POLARSSL_THREADING_PTHREAD) +static threading_mutex_t readdir_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + +int x509_crt_parse_path( x509_crt *chain, const char *path ) +{ + int ret = 0; +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + int w_ret; + WCHAR szDir[MAX_PATH]; + char filename[MAX_PATH]; + char *p; + int len = (int) strlen( path ); + + WIN32_FIND_DATAW file_data; + HANDLE hFind; + + if( len > MAX_PATH - 3 ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + memset( szDir, 0, sizeof(szDir) ); + memset( filename, 0, MAX_PATH ); + memcpy( filename, path, len ); + filename[len++] = '\\'; + p = filename + len; + filename[len++] = '*'; + + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, + MAX_PATH - 3 ); + + hFind = FindFirstFileW( szDir, &file_data ); + if( hFind == INVALID_HANDLE_VALUE ) + return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + + len = MAX_PATH - len; + do + { + memset( p, 0, len ); + + if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + continue; + + w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, + lstrlenW( file_data.cFileName ), + p, len - 1, + NULL, NULL ); + + w_ret = x509_crt_parse_file( chain, filename ); + if( w_ret < 0 ) + ret++; + else + ret += w_ret; + } + while( FindNextFileW( hFind, &file_data ) != 0 ); + + if( GetLastError() != ERROR_NO_MORE_FILES ) + ret = POLARSSL_ERR_X509_FILE_IO_ERROR; + + FindClose( hFind ); +#else /* _WIN32 */ + int t_ret; + struct stat sb; + struct dirent *entry; + char entry_name[255]; + DIR *dir = opendir( path ); + + if( dir == NULL ) + return( POLARSSL_ERR_X509_FILE_IO_ERROR ); + +#if defined(POLARSSL_THREADING_PTHREAD) + if( ( ret = polarssl_mutex_lock( &readdir_mutex ) ) != 0 ) + return( ret ); +#endif + + while( ( entry = readdir( dir ) ) != NULL ) + { + snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name ); + + if( stat( entry_name, &sb ) == -1 ) + { + closedir( dir ); + ret = POLARSSL_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } + + if( !S_ISREG( sb.st_mode ) ) + continue; + + // Ignore parse errors + // + t_ret = x509_crt_parse_file( chain, entry_name ); + if( t_ret < 0 ) + ret++; + else + ret += t_ret; + } + closedir( dir ); + +cleanup: +#if defined(POLARSSL_THREADING_PTHREAD) + if( polarssl_mutex_unlock( &readdir_mutex ) != 0 ) + ret = POLARSSL_ERR_THREADING_MUTEX_ERROR; +#endif + +#endif /* _WIN32 */ + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +static int x509_info_subject_alt_name( char **buf, size_t *size, + const x509_sequence *subject_alt_name ) +{ + size_t i; + size_t n = *size; + char *p = *buf; + const x509_sequence *cur = subject_alt_name; + const char *sep = ""; + size_t sep_len = 0; + + while( cur != NULL ) + { + if( cur->buf.len + sep_len >= n ) + { + *p = '\0'; + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); + } + + n -= cur->buf.len + sep_len; + for( i = 0; i < sep_len; i++ ) + *p++ = sep[i]; + for( i = 0; i < cur->buf.len; i++ ) + *p++ = cur->buf.p[i]; + + sep = ", "; + sep_len = 2; + + cur = cur->next; + } + + *p = '\0'; + + *size = n; + *buf = p; + + return( 0 ); +} + +#define PRINT_ITEM(i) \ + { \ + ret = snprintf( p, n, "%s" i, sep ); \ + SAFE_SNPRINTF(); \ + sep = ", "; \ + } + +#define CERT_TYPE(type,name) \ + if( ns_cert_type & type ) \ + PRINT_ITEM( name ); + +static int x509_info_cert_type( char **buf, size_t *size, + unsigned char ns_cert_type ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); + CERT_TYPE( NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); + CERT_TYPE( NS_CERT_TYPE_EMAIL, "Email" ); + CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); + CERT_TYPE( NS_CERT_TYPE_RESERVED, "Reserved" ); + CERT_TYPE( NS_CERT_TYPE_SSL_CA, "SSL CA" ); + CERT_TYPE( NS_CERT_TYPE_EMAIL_CA, "Email CA" ); + CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +#define KEY_USAGE(code,name) \ + if( key_usage & code ) \ + PRINT_ITEM( name ); + +static int x509_info_key_usage( char **buf, size_t *size, + unsigned char key_usage ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + KEY_USAGE( KU_DIGITAL_SIGNATURE, "Digital Signature" ); + KEY_USAGE( KU_NON_REPUDIATION, "Non Repudiation" ); + KEY_USAGE( KU_KEY_ENCIPHERMENT, "Key Encipherment" ); + KEY_USAGE( KU_DATA_ENCIPHERMENT, "Data Encipherment" ); + KEY_USAGE( KU_KEY_AGREEMENT, "Key Agreement" ); + KEY_USAGE( KU_KEY_CERT_SIGN, "Key Cert Sign" ); + KEY_USAGE( KU_CRL_SIGN, "CRL Sign" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +static int x509_info_ext_key_usage( char **buf, size_t *size, + const x509_sequence *extended_key_usage ) +{ + int ret; + const char *desc; + size_t n = *size; + char *p = *buf; + const x509_sequence *cur = extended_key_usage; + const char *sep = ""; + + while( cur != NULL ) + { + if( oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) + desc = "???"; + + ret = snprintf( p, n, "%s%s", sep, desc ); + SAFE_SNPRINTF(); + + sep = ", "; + + cur = cur->next; + } + + *size = n; + *buf = p; + + return( 0 ); +} + +/* + * Return an informational string about the certificate. + */ +#define BEFORE_COLON 18 +#define BC "18" +int x509_crt_info( char *buf, size_t size, const char *prefix, + const x509_crt *crt ) +{ + int ret; + size_t n; + char *p; + char key_size_str[BEFORE_COLON]; + + p = buf; + n = size; + + ret = snprintf( p, n, "%scert. version : %d\n", + prefix, crt->version ); + SAFE_SNPRINTF(); + ret = snprintf( p, n, "%sserial number : ", + prefix ); + SAFE_SNPRINTF(); + + ret = x509_serial_gets( p, n, &crt->serial ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%sissuer name : ", prefix ); + SAFE_SNPRINTF(); + ret = x509_dn_gets( p, n, &crt->issuer ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%ssubject name : ", prefix ); + SAFE_SNPRINTF(); + ret = x509_dn_gets( p, n, &crt->subject ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%sissued on : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crt->valid_from.year, crt->valid_from.mon, + crt->valid_from.day, crt->valid_from.hour, + crt->valid_from.min, crt->valid_from.sec ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%sexpires on : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crt->valid_to.year, crt->valid_to.mon, + crt->valid_to.day, crt->valid_to.hour, + crt->valid_to.min, crt->valid_to.sec ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%ssigned using : ", prefix ); + SAFE_SNPRINTF(); + + ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk, + crt->sig_md, crt->sig_opts ); + SAFE_SNPRINTF(); + + /* Key size */ + if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, + pk_get_name( &crt->pk ) ) ) != 0 ) + { + return( ret ); + } + + ret = snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, + (int) pk_get_size( &crt->pk ) ); + SAFE_SNPRINTF(); + + /* + * Optional extensions + */ + + if( crt->ext_types & EXT_BASIC_CONSTRAINTS ) + { + ret = snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, + crt->ca_istrue ? "true" : "false" ); + SAFE_SNPRINTF(); + + if( crt->max_pathlen > 0 ) + { + ret = snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); + SAFE_SNPRINTF(); + } + } + + if( crt->ext_types & EXT_SUBJECT_ALT_NAME ) + { + ret = snprintf( p, n, "\n%ssubject alt name : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_subject_alt_name( &p, &n, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_NS_CERT_TYPE ) + { + ret = snprintf( p, n, "\n%scert. type : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_KEY_USAGE ) + { + ret = snprintf( p, n, "\n%skey usage : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) + { + ret = snprintf( p, n, "\n%sext key usage : ", prefix ); + SAFE_SNPRINTF(); + + if( ( ret = x509_info_ext_key_usage( &p, &n, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + } + + ret = snprintf( p, n, "\n" ); + SAFE_SNPRINTF(); + + return( (int) ( size - n ) ); +} + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) +int x509_crt_check_key_usage( const x509_crt *crt, int usage ) +{ + if( ( crt->ext_types & EXT_KEY_USAGE ) != 0 && + ( crt->key_usage & usage ) != usage ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + return( 0 ); +} +#endif + +#if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) +int x509_crt_check_extended_key_usage( const x509_crt *crt, + const char *usage_oid, + size_t usage_len ) +{ + const x509_sequence *cur; + + /* Extension is not mandatory, absent means no restriction */ + if( ( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) == 0 ) + return( 0 ); + + /* + * Look for the requested usage (or wildcard ANY) in our list + */ + for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) + { + const x509_buf *cur_oid = &cur->buf; + + if( cur_oid->len == usage_len && + memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) + { + return( 0 ); + } + + if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) ) + return( 0 ); + } + + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); +} +#endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ + +#if defined(POLARSSL_X509_CRL_PARSE_C) +/* + * Return 1 if the certificate is revoked, or 0 otherwise. + */ +int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl ) +{ + const x509_crl_entry *cur = &crl->entry; + + while( cur != NULL && cur->serial.len != 0 ) + { + if( crt->serial.len == cur->serial.len && + memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) + { + if( x509_time_expired( &cur->revocation_date ) ) + return( 1 ); + } + + cur = cur->next; + } + + return( 0 ); +} + +/* + * Check that the given certificate is valid according to the CRL. + */ +static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, + x509_crl *crl_list) +{ + int flags = 0; + unsigned char hash[POLARSSL_MD_MAX_SIZE]; + const md_info_t *md_info; + + if( ca == NULL ) + return( flags ); + + /* + * TODO: What happens if no CRL is present? + * Suggestion: Revocation state should be unknown if no CRL is present. + * For backwards compatibility this is not yet implemented. + */ + + while( crl_list != NULL ) + { + if( crl_list->version == 0 || + crl_list->issuer_raw.len != ca->subject_raw.len || + memcmp( crl_list->issuer_raw.p, ca->subject_raw.p, + crl_list->issuer_raw.len ) != 0 ) + { + crl_list = crl_list->next; + continue; + } + + /* + * Check if the CA is configured to sign CRLs + */ +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( x509_crt_check_key_usage( ca, KU_CRL_SIGN ) != 0 ) + { + flags |= BADCRL_NOT_TRUSTED; + break; + } +#endif + + /* + * Check if CRL is correctly signed by the trusted CA + */ + md_info = md_info_from_type( crl_list->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown' hash + */ + flags |= BADCRL_NOT_TRUSTED; + break; + } + + md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); + + if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, + crl_list->sig_md, hash, md_info->size, + crl_list->sig.p, crl_list->sig.len ) != 0 ) + { + flags |= BADCRL_NOT_TRUSTED; + break; + } + + /* + * Check for validity of CRL (Do not drop out) + */ + if( x509_time_expired( &crl_list->next_update ) ) + flags |= BADCRL_EXPIRED; + + if( x509_time_future( &crl_list->this_update ) ) + flags |= BADCRL_FUTURE; + + /* + * Check if certificate is revoked + */ + if( x509_crt_revoked( crt, crl_list ) ) + { + flags |= BADCERT_REVOKED; + break; + } + + crl_list = crl_list->next; + } + return( flags ); +} +#endif /* POLARSSL_X509_CRL_PARSE_C */ + +// Equal == 0, inequal == 1 +static int x509_name_cmp( const void *s1, const void *s2, size_t len ) +{ + size_t i; + unsigned char diff; + const unsigned char *n1 = s1, *n2 = s2; + + for( i = 0; i < len; i++ ) + { + diff = n1[i] ^ n2[i]; + + if( diff == 0 ) + continue; + + if( diff == 32 && + ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || + ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) + { + continue; + } + + return( 1 ); + } + + return( 0 ); +} + +static int x509_wildcard_verify( const char *cn, x509_buf *name ) +{ + size_t i; + size_t cn_idx = 0, cn_len = strlen( cn ); + + if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) + return( 0 ); + + for( i = 0; i < cn_len; ++i ) + { + if( cn[i] == '.' ) + { + cn_idx = i; + break; + } + } + + if( cn_idx == 0 ) + return( 0 ); + + if( cn_len - cn_idx == name->len - 1 && + x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) + { + return( 1 ); + } + + return( 0 ); +} + +/* + * Check if 'parent' is a suitable parent (signing CA) for 'child'. + * Return 0 if yes, -1 if not. + * + * top means parent is a locally-trusted certificate + * bottom means child is the end entity cert + */ +static int x509_crt_check_parent( const x509_crt *child, + const x509_crt *parent, + int top, int bottom ) +{ + int need_ca_bit; + + /* Parent must be the issuer */ + if( child->issuer_raw.len != parent->subject_raw.len || + memcmp( child->issuer_raw.p, parent->subject_raw.p, + child->issuer_raw.len ) != 0 ) + { + return( -1 ); + } + + /* Parent must have the basicConstraints CA bit set as a general rule */ + need_ca_bit = 1; + + /* Exception: v1/v2 certificates that are locally trusted. */ + if( top && parent->version < 3 ) + need_ca_bit = 0; + + /* Exception: self-signed end-entity certs that are locally trusted. */ + if( top && bottom && + child->raw.len == parent->raw.len && + memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) + { + need_ca_bit = 0; + } + + if( need_ca_bit && ! parent->ca_istrue ) + return( -1 ); + +#if defined(POLARSSL_X509_CHECK_KEY_USAGE) + if( need_ca_bit && + x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 ) + { + return( -1 ); + } +#endif + + return( 0 ); +} + +static int x509_crt_verify_top( + x509_crt *child, x509_crt *trust_ca, + x509_crl *ca_crl, int path_cnt, int *flags, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ) +{ + int ret; + int ca_flags = 0, check_path_cnt = path_cnt + 1; + unsigned char hash[POLARSSL_MD_MAX_SIZE]; + const md_info_t *md_info; + + if( x509_time_expired( &child->valid_to ) ) + *flags |= BADCERT_EXPIRED; + + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; + + /* + * Child is the top of the chain. Check against the trust_ca list. + */ + *flags |= BADCERT_NOT_TRUSTED; + + md_info = md_info_from_type( child->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown', no need to try any CA + */ + trust_ca = NULL; + } + else + md( md_info, child->tbs.p, child->tbs.len, hash ); + + for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) + { + if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) + continue; + + /* + * Reduce path_len to check against if top of the chain is + * the same as the trusted CA + */ + if( child->subject_raw.len == trust_ca->subject_raw.len && + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->issuer_raw.len ) == 0 ) + { + check_path_cnt--; + } + + if( trust_ca->max_pathlen > 0 && + trust_ca->max_pathlen < check_path_cnt ) + { + continue; + } + + if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, + child->sig_md, hash, md_info->size, + child->sig.p, child->sig.len ) != 0 ) + { + continue; + } + + /* + * Top of chain is signed by a trusted CA + */ + *flags &= ~BADCERT_NOT_TRUSTED; + break; + } + + /* + * If top of chain is not the same as the trusted CA send a verify request + * to the callback for any issues with validity and CRL presence for the + * trusted CA certificate. + */ + if( trust_ca != NULL && + ( child->subject_raw.len != trust_ca->subject_raw.len || + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->issuer_raw.len ) != 0 ) ) + { +#if defined(POLARSSL_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the chain's top crt */ + *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl ); +#else + ((void) ca_crl); +#endif + + if( x509_time_expired( &trust_ca->valid_to ) ) + ca_flags |= BADCERT_EXPIRED; + + if( x509_time_future( &trust_ca->valid_from ) ) + ca_flags |= BADCERT_FUTURE; + + if( NULL != f_vrfy ) + { + if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, + &ca_flags ) ) != 0 ) + { + return( ret ); + } + } + } + + /* Call callback on top cert */ + if( NULL != f_vrfy ) + { + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) + return( ret ); + } + + *flags |= ca_flags; + + return( 0 ); +} + +static int x509_crt_verify_child( + x509_crt *child, x509_crt *parent, x509_crt *trust_ca, + x509_crl *ca_crl, int path_cnt, int *flags, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ) +{ + int ret; + int parent_flags = 0; + unsigned char hash[POLARSSL_MD_MAX_SIZE]; + x509_crt *grandparent; + const md_info_t *md_info; + + if( x509_time_expired( &child->valid_to ) ) + *flags |= BADCERT_EXPIRED; + + if( x509_time_future( &child->valid_from ) ) + *flags |= BADCERT_FUTURE; + + md_info = md_info_from_type( child->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown' hash + */ + *flags |= BADCERT_NOT_TRUSTED; + } + else + { + md( md_info, child->tbs.p, child->tbs.len, hash ); + + if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, + child->sig_md, hash, md_info->size, + child->sig.p, child->sig.len ) != 0 ) + { + *flags |= BADCERT_NOT_TRUSTED; + } + } + +#if defined(POLARSSL_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the given crt */ + *flags |= x509_crt_verifycrl(child, parent, ca_crl); +#endif + + /* Look for a grandparent upwards the chain */ + for( grandparent = parent->next; + grandparent != NULL; + grandparent = grandparent->next ) + { + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; + } + + /* Is our parent part of the chain or at the top? */ + if( grandparent != NULL ) + { + ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, + path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + ret = x509_crt_verify_top( parent, trust_ca, ca_crl, + path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + + /* child is verified to be a child of the parent, call verify callback */ + if( NULL != f_vrfy ) + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) + return( ret ); + + *flags |= parent_flags; + + return( 0 ); +} + +/* + * Verify the certificate validity + */ +int x509_crt_verify( x509_crt *crt, + x509_crt *trust_ca, + x509_crl *ca_crl, + const char *cn, int *flags, + int (*f_vrfy)(void *, x509_crt *, int, int *), + void *p_vrfy ) +{ + size_t cn_len; + int ret; + int pathlen = 0; + x509_crt *parent; + x509_name *name; + x509_sequence *cur = NULL; + + *flags = 0; + + if( cn != NULL ) + { + name = &crt->subject; + cn_len = strlen( cn ); + + if( crt->ext_types & EXT_SUBJECT_ALT_NAME ) + { + cur = &crt->subject_alt_names; + + while( cur != NULL ) + { + if( cur->buf.len == cn_len && + x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 ) + break; + + if( cur->buf.len > 2 && + memcmp( cur->buf.p, "*.", 2 ) == 0 && + x509_wildcard_verify( cn, &cur->buf ) ) + break; + + cur = cur->next; + } + + if( cur == NULL ) + *flags |= BADCERT_CN_MISMATCH; + } + else + { + while( name != NULL ) + { + if( OID_CMP( OID_AT_CN, &name->oid ) ) + { + if( name->val.len == cn_len && + x509_name_cmp( name->val.p, cn, cn_len ) == 0 ) + break; + + if( name->val.len > 2 && + memcmp( name->val.p, "*.", 2 ) == 0 && + x509_wildcard_verify( cn, &name->val ) ) + break; + } + + name = name->next; + } + + if( name == NULL ) + *flags |= BADCERT_CN_MISMATCH; + } + } + + /* Look for a parent upwards the chain */ + for( parent = crt->next; parent != NULL; parent = parent->next ) + { + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; + } + + /* Are we part of the chain or at the top? */ + if( parent != NULL ) + { + ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, + pathlen, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + ret = x509_crt_verify_top( crt, trust_ca, ca_crl, + pathlen, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + + if( *flags != 0 ) + return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED ); + + return( 0 ); +} + +/* + * Initialize a certificate chain + */ +void x509_crt_init( x509_crt *crt ) +{ + memset( crt, 0, sizeof(x509_crt) ); +} + +/* + * Unallocate all certificate data + */ +void x509_crt_free( x509_crt *crt ) +{ + x509_crt *cert_cur = crt; + x509_crt *cert_prv; + x509_name *name_cur; + x509_name *name_prv; + x509_sequence *seq_cur; + x509_sequence *seq_prv; + + if( crt == NULL ) + return; + + do + { + pk_free( &cert_cur->pk ); + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( cert_cur->sig_opts ); +#endif + + name_cur = cert_cur->issuer.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + polarssl_zeroize( name_prv, sizeof( x509_name ) ); + polarssl_free( name_prv ); + } + + name_cur = cert_cur->subject.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + polarssl_zeroize( name_prv, sizeof( x509_name ) ); + polarssl_free( name_prv ); + } + + seq_cur = cert_cur->ext_key_usage.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); + polarssl_free( seq_prv ); + } + + seq_cur = cert_cur->subject_alt_names.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); + polarssl_free( seq_prv ); + } + + if( cert_cur->raw.p != NULL ) + { + polarssl_zeroize( cert_cur->raw.p, cert_cur->raw.len ); + polarssl_free( cert_cur->raw.p ); + } + + cert_cur = cert_cur->next; + } + while( cert_cur != NULL ); + + cert_cur = crt; + do + { + cert_prv = cert_cur; + cert_cur = cert_cur->next; + + polarssl_zeroize( cert_prv, sizeof( x509_crt ) ); + if( cert_prv != crt ) + polarssl_free( cert_prv ); + } + while( cert_cur != NULL ); +} + +#endif /* POLARSSL_X509_CRT_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_csr.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_csr.c new file mode 100644 index 0000000..0b4f771 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509_csr.c @@ -0,0 +1,465 @@ +/* + * X.509 Certificate Signing Request (CSR) parsing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CSR_PARSE_C) + +#include "polarssl/x509_csr.h" +#include "polarssl/oid.h" +#if defined(POLARSSL_PEM_PARSE_C) +#include "polarssl/pem.h" +#endif + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_malloc malloc +#define polarssl_free free +#endif + +#include +#include + +#if defined(POLARSSL_FS_IO) || defined(EFIX64) || defined(EFI32) +#include +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Version ::= INTEGER { v1(0) } + */ +static int x509_csr_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + + if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) + { + if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( POLARSSL_ERR_X509_INVALID_VERSION + ret ); + } + + return( 0 ); +} + +/* + * Parse a CSR in DER format + */ +int x509_csr_parse_der( x509_csr *csr, + const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + x509_buf sig_params; + + memset( &sig_params, 0, sizeof( x509_buf ) ); + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + x509_csr_init( csr ); + + /* + * first copy the raw DER data + */ + p = (unsigned char *) polarssl_malloc( len = buflen ); + + if( p == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); + + memcpy( p, buf, buflen ); + + csr->raw.p = p; + csr->raw.len = len; + end = p + len; + + /* + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + * } + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT ); + } + + if( len != (size_t) ( end - p ) ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + /* + * CertificationRequestInfo ::= SEQUENCE { + */ + csr->cri.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + csr->cri.len = end - csr->cri.p; + + /* + * Version ::= INTEGER { v1(0) } + */ + if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) + { + x509_csr_free( csr ); + return( ret ); + } + + csr->version++; + + if( csr->version != 1 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); + } + + /* + * subject Name + */ + csr->subject_raw.p = p; + + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) + { + x509_csr_free( csr ); + return( ret ); + } + + csr->subject_raw.len = p - csr->subject_raw.p; + + /* + * subjectPKInfo SubjectPublicKeyInfo + */ + if( ( ret = pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) + { + x509_csr_free( csr ); + return( ret ); + } + + /* + * attributes [0] Attributes + */ + if( ( ret = asn1_get_tag( &p, end, &len, + ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) ) != 0 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); + } + // TODO Parse Attributes / extension requests + + p += len; + + end = csr->raw.p + csr->raw.len; + + /* + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + */ + if( ( ret = x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) + { + x509_csr_free( csr ); + return( ret ); + } + + if( ( ret = x509_get_sig_alg( &csr->sig_oid, &sig_params, + &csr->sig_md, &csr->sig_pk, + &csr->sig_opts ) ) != 0 ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_UNKNOWN_SIG_ALG ); + } + + if( ( ret = x509_get_sig( &p, end, &csr->sig ) ) != 0 ) + { + x509_csr_free( csr ); + return( ret ); + } + + if( p != end ) + { + x509_csr_free( csr ); + return( POLARSSL_ERR_X509_INVALID_FORMAT + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); +} + +/* + * Parse a CSR, allowing for PEM or raw DER encoding + */ +int x509_csr_parse( x509_csr *csr, const unsigned char *buf, size_t buflen ) +{ + int ret; +#if defined(POLARSSL_PEM_PARSE_C) + size_t use_len; + pem_context pem; +#endif + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + +#if defined(POLARSSL_PEM_PARSE_C) + pem_init( &pem ); + ret = pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE REQUEST-----", + "-----END CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded, parse the result + */ + if( ( ret = x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) + return( ret ); + + pem_free( &pem ); + return( 0 ); + } + else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + pem_free( &pem ); + return( ret ); + } + else +#endif /* POLARSSL_PEM_PARSE_C */ + return( x509_csr_parse_der( csr, buf, buflen ) ); +} + +#if defined(POLARSSL_FS_IO) +/* + * Load a CSR into the structure + */ +int x509_csr_parse_file( x509_csr *csr, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = x509_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = x509_csr_parse( csr, buf, n ); + + polarssl_zeroize( buf, n + 1 ); + polarssl_free( buf ); + + return( ret ); +} +#endif /* POLARSSL_FS_IO */ + +#if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ + !defined(EFI32) +#include + +#if !defined vsnprintf +#define vsnprintf _vsnprintf +#endif // vsnprintf + +/* + * Windows _snprintf and _vsnprintf are not compatible to linux versions. + * Result value is not size of buffer needed, but -1 if no fit is possible. + * + * This fuction tries to 'fix' this by at least suggesting enlarging the + * size by 20. + */ +static int compat_snprintf( char *str, size_t size, const char *format, ... ) +{ + va_list ap; + int res = -1; + + va_start( ap, format ); + + res = vsnprintf( str, size, format, ap ); + + va_end( ap ); + + // No quick fix possible + if( res < 0 ) + return( (int) size + 20 ); + + return( res ); +} + +#define snprintf compat_snprintf +#endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ + +#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 + +#define SAFE_SNPRINTF() \ +{ \ + if( ret == -1 ) \ + return( -1 ); \ + \ + if( (unsigned int) ret > n ) { \ + p[n - 1] = '\0'; \ + return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ + } \ + \ + n -= (unsigned int) ret; \ + p += (unsigned int) ret; \ +} + +#define BEFORE_COLON 14 +#define BC "14" +/* + * Return an informational string about the CSR. + */ +int x509_csr_info( char *buf, size_t size, const char *prefix, + const x509_csr *csr ) +{ + int ret; + size_t n; + char *p; + char key_size_str[BEFORE_COLON]; + + p = buf; + n = size; + + ret = snprintf( p, n, "%sCSR version : %d", + prefix, csr->version ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%ssubject name : ", prefix ); + SAFE_SNPRINTF(); + ret = x509_dn_gets( p, n, &csr->subject ); + SAFE_SNPRINTF(); + + ret = snprintf( p, n, "\n%ssigned using : ", prefix ); + SAFE_SNPRINTF(); + + ret = x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, + csr->sig_opts ); + SAFE_SNPRINTF(); + + if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, + pk_get_name( &csr->pk ) ) ) != 0 ) + { + return( ret ); + } + + ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, + (int) pk_get_size( &csr->pk ) ); + SAFE_SNPRINTF(); + + return( (int) ( size - n ) ); +} + +/* + * Initialize a CSR + */ +void x509_csr_init( x509_csr *csr ) +{ + memset( csr, 0, sizeof(x509_csr) ); +} + +/* + * Unallocate all CSR data + */ +void x509_csr_free( x509_csr *csr ) +{ + x509_name *name_cur; + x509_name *name_prv; + + if( csr == NULL ) + return; + + pk_free( &csr->pk ); + +#if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) + polarssl_free( csr->sig_opts ); +#endif + + name_cur = csr->subject.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + polarssl_zeroize( name_prv, sizeof( x509_name ) ); + polarssl_free( name_prv ); + } + + if( csr->raw.p != NULL ) + { + polarssl_zeroize( csr->raw.p, csr->raw.len ); + polarssl_free( csr->raw.p ); + } + + polarssl_zeroize( csr, sizeof( x509_csr ) ); +} + +#endif /* POLARSSL_X509_CSR_PARSE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_crt.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_crt.c new file mode 100644 index 0000000..e298c24 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_crt.c @@ -0,0 +1,452 @@ +/* + * X.509 certificate writing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * References: + * - certificates: RFC 5280, updated by RFC 6818 + * - CSRs: PKCS#10 v1.7 aka RFC 2986 + * - attributes: PKCS#9 v2.0 aka RFC 2985 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CRT_WRITE_C) + +#include "polarssl/x509_crt.h" +#include "polarssl/oid.h" +#include "polarssl/asn1write.h" +#include "polarssl/sha1.h" + +#if defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#endif /* POLARSSL_PEM_WRITE_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void x509write_crt_init( x509write_cert *ctx ) +{ + memset( ctx, 0, sizeof(x509write_cert) ); + + mpi_init( &ctx->serial ); + ctx->version = X509_CRT_VERSION_3; +} + +void x509write_crt_free( x509write_cert *ctx ) +{ + mpi_free( &ctx->serial ); + + asn1_free_named_data_list( &ctx->subject ); + asn1_free_named_data_list( &ctx->issuer ); + asn1_free_named_data_list( &ctx->extensions ); + + polarssl_zeroize( ctx, sizeof(x509write_cert) ); +} + +void x509write_crt_set_version( x509write_cert *ctx, int version ) +{ + ctx->version = version; +} + +void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg ) +{ + ctx->md_alg = md_alg; +} + +void x509write_crt_set_subject_key( x509write_cert *ctx, pk_context *key ) +{ + ctx->subject_key = key; +} + +void x509write_crt_set_issuer_key( x509write_cert *ctx, pk_context *key ) +{ + ctx->issuer_key = key; +} + +int x509write_crt_set_subject_name( x509write_cert *ctx, + const char *subject_name ) +{ + return x509_string_to_names( &ctx->subject, subject_name ); +} + +int x509write_crt_set_issuer_name( x509write_cert *ctx, + const char *issuer_name ) +{ + return x509_string_to_names( &ctx->issuer, issuer_name ); +} + +int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial ) +{ + int ret; + + if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int x509write_crt_set_validity( x509write_cert *ctx, const char *not_before, + const char *not_after ) +{ + if( strlen( not_before ) != X509_RFC5280_UTC_TIME_LEN - 1 || + strlen( not_after ) != X509_RFC5280_UTC_TIME_LEN - 1 ) + { + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + } + strncpy( ctx->not_before, not_before, X509_RFC5280_UTC_TIME_LEN ); + strncpy( ctx->not_after , not_after , X509_RFC5280_UTC_TIME_LEN ); + ctx->not_before[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; + ctx->not_after[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; + + return( 0 ); +} + +int x509write_crt_set_extension( x509write_cert *ctx, + const char *oid, size_t oid_len, + int critical, + const unsigned char *val, size_t val_len ) +{ + return x509_set_extension( &ctx->extensions, oid, oid_len, + critical, val, val_len ); +} + +int x509write_crt_set_basic_constraints( x509write_cert *ctx, + int is_ca, int max_pathlen ) +{ + int ret; + unsigned char buf[9]; + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + + if( is_ca && max_pathlen > 127 ) + return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); + + if( is_ca ) + { + if( max_pathlen >= 0 ) + { + ASN1_CHK_ADD( len, asn1_write_int( &c, buf, max_pathlen ) ); + } + ASN1_CHK_ADD( len, asn1_write_bool( &c, buf, 1 ) ); + } + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return x509write_crt_set_extension( ctx, OID_BASIC_CONSTRAINTS, + OID_SIZE( OID_BASIC_CONSTRAINTS ), + 0, buf + sizeof(buf) - len, len ); +} + +#if defined(POLARSSL_SHA1_C) +int x509write_crt_set_subject_key_identifier( x509write_cert *ctx ) +{ + int ret; + unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->subject_key ) ); + + sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); + c = buf + sizeof(buf) - 20; + len = 20; + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_OCTET_STRING ) ); + + return x509write_crt_set_extension( ctx, OID_SUBJECT_KEY_IDENTIFIER, + OID_SIZE( OID_SUBJECT_KEY_IDENTIFIER ), + 0, buf + sizeof(buf) - len, len ); +} + +int x509write_crt_set_authority_key_identifier( x509write_cert *ctx ) +{ + int ret; + unsigned char buf[POLARSSL_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, ctx->issuer_key ) ); + + sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); + c = buf + sizeof(buf) - 20; + len = 20; + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONTEXT_SPECIFIC | 0 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return x509write_crt_set_extension( ctx, OID_AUTHORITY_KEY_IDENTIFIER, + OID_SIZE( OID_AUTHORITY_KEY_IDENTIFIER ), + 0, buf + sizeof(buf) - len, len ); +} +#endif /* POLARSSL_SHA1_C */ + +int x509write_crt_set_key_usage( x509write_cert *ctx, unsigned char key_usage ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) + return( ret ); + + ret = x509write_crt_set_extension( ctx, OID_KEY_USAGE, + OID_SIZE( OID_KEY_USAGE ), + 1, buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int x509write_crt_set_ns_cert_type( x509write_cert *ctx, + unsigned char ns_cert_type ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + return( ret ); + + ret = x509write_crt_set_extension( ctx, OID_NS_CERT_TYPE, + OID_SIZE( OID_NS_CERT_TYPE ), + 0, buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +static int x509_write_time( unsigned char **p, unsigned char *start, + const char *time, size_t size ) +{ + int ret; + size_t len = 0; + + /* + * write ASN1_UTC_TIME if year < 2050 (2 bytes shorter) + */ + if( time[0] == '2' && time[1] == '0' && time [2] < '5' ) + { + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) time + 2, + size - 2 ) ); + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_UTC_TIME ) ); + } + else + { + ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start, + (const unsigned char *) time, + size ) ); + ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_GENERALIZED_TIME ) ); + } + + return( (int) len ); +} + +int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const char *sig_oid; + size_t sig_oid_len = 0; + unsigned char *c, *c2; + unsigned char hash[64]; + unsigned char sig[POLARSSL_MPI_MAX_SIZE]; + unsigned char tmp_buf[2048]; + size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; + size_t len = 0; + pk_type_t pk_alg; + + /* + * Prepare data to be signed in tmp_buf + */ + c = tmp_buf + sizeof( tmp_buf ); + + /* Signature algorithm needed in TBS, and later for actual signature */ + pk_alg = pk_get_type( ctx->issuer_key ); + if( pk_alg == POLARSSL_PK_ECKEY ) + pk_alg = POLARSSL_PK_ECDSA; + + if( ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, + &sig_oid, &sig_oid_len ) ) != 0 ) + { + return( ret ); + } + + /* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + */ + ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED | 3 ) ); + + /* + * SubjectPublicKeyInfo + */ + ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->subject_key, + tmp_buf, c - tmp_buf ) ); + c -= pub_len; + len += pub_len; + + /* + * Subject ::= Name + */ + ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) ); + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + */ + sub_len = 0; + + ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, + X509_RFC5280_UTC_TIME_LEN ) ); + + ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, + X509_RFC5280_UTC_TIME_LEN ) ); + + len += sub_len; + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + /* + * Issuer ::= Name + */ + ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) ); + + /* + * Signature ::= AlgorithmIdentifier + */ + ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf, + sig_oid, strlen( sig_oid ), 0 ) ); + + /* + * Serial ::= INTEGER + */ + ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + sub_len = 0; + ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) ); + len += sub_len; + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | + ASN1_CONSTRUCTED | 0 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + /* + * Make signature + */ + md( md_info_from_type( ctx->md_alg ), c, len, hash ); + + if( ( ret = pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + /* + * Write data to output buffer + */ + c2 = buf + size; + ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf, + sig_oid, sig_oid_len, sig, sig_len ) ); + + c2 -= len; + memcpy( c2, c, len ); + + len += sig_and_oid_len; + ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" +#define PEM_END_CRT "-----END CERTIFICATE-----\n" + +#if defined(POLARSSL_PEM_WRITE_C) +int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = x509write_crt_der( crt, output_buf, sizeof(output_buf), + f_rng, p_rng ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ + +#endif /* POLARSSL_X509_CRT_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_csr.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_csr.c new file mode 100644 index 0000000..53ae9c6 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/x509write_csr.c @@ -0,0 +1,260 @@ +/* + * X.509 Certificate Signing Request writing + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +/* + * References: + * - CSRs: PKCS#10 v1.7 aka RFC 2986 + * - attributes: PKCS#9 v2.0 aka RFC 2985 + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_X509_CSR_WRITE_C) + +#include "polarssl/x509_csr.h" +#include "polarssl/oid.h" +#include "polarssl/asn1write.h" + +#if defined(POLARSSL_PEM_WRITE_C) +#include "polarssl/pem.h" +#endif + +#include +#include + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void x509write_csr_init( x509write_csr *ctx ) +{ + memset( ctx, 0, sizeof(x509write_csr) ); +} + +void x509write_csr_free( x509write_csr *ctx ) +{ + asn1_free_named_data_list( &ctx->subject ); + asn1_free_named_data_list( &ctx->extensions ); + + polarssl_zeroize( ctx, sizeof(x509write_csr) ); +} + +void x509write_csr_set_md_alg( x509write_csr *ctx, md_type_t md_alg ) +{ + ctx->md_alg = md_alg; +} + +void x509write_csr_set_key( x509write_csr *ctx, pk_context *key ) +{ + ctx->key = key; +} + +int x509write_csr_set_subject_name( x509write_csr *ctx, + const char *subject_name ) +{ + return x509_string_to_names( &ctx->subject, subject_name ); +} + +int x509write_csr_set_extension( x509write_csr *ctx, + const char *oid, size_t oid_len, + const unsigned char *val, size_t val_len ) +{ + return x509_set_extension( &ctx->extensions, oid, oid_len, + 0, val, val_len ); +} + +int x509write_csr_set_key_usage( x509write_csr *ctx, unsigned char key_usage ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) + return( ret ); + + ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE, + OID_SIZE( OID_KEY_USAGE ), + buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int x509write_csr_set_ns_cert_type( x509write_csr *ctx, + unsigned char ns_cert_type ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + return( ret ); + + ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE, + OID_SIZE( OID_NS_CERT_TYPE ), + buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int x509write_csr_der( x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const char *sig_oid; + size_t sig_oid_len = 0; + unsigned char *c, *c2; + unsigned char hash[64]; + unsigned char sig[POLARSSL_MPI_MAX_SIZE]; + unsigned char tmp_buf[2048]; + size_t pub_len = 0, sig_and_oid_len = 0, sig_len; + size_t len = 0; + pk_type_t pk_alg; + + /* + * Prepare data to be signed in tmp_buf + */ + c = tmp_buf + sizeof( tmp_buf ); + + ASN1_CHK_ADD( len, x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); + + if( len ) + { + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SET ) ); + + ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ, + OID_SIZE( OID_PKCS9_CSR_EXT_REQ ) ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + } + + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_CONTEXT_SPECIFIC ) ); + + ASN1_CHK_ADD( pub_len, pk_write_pubkey_der( ctx->key, + tmp_buf, c - tmp_buf ) ); + c -= pub_len; + len += pub_len; + + /* + * Subject ::= Name + */ + ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) ); + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) ); + + ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + /* + * Prepare signature + */ + md( md_info_from_type( ctx->md_alg ), c, len, hash ); + + pk_alg = pk_get_type( ctx->key ); + if( pk_alg == POLARSSL_PK_ECKEY ) + pk_alg = POLARSSL_PK_ECDSA; + + if( ( ret = pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, + f_rng, p_rng ) ) != 0 || + ( ret = oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, + &sig_oid, &sig_oid_len ) ) != 0 ) + { + return( ret ); + } + + /* + * Write data to output buffer + */ + c2 = buf + size; + ASN1_CHK_ADD( sig_and_oid_len, x509_write_sig( &c2, buf, + sig_oid, sig_oid_len, sig, sig_len ) ); + + c2 -= len; + memcpy( c2, c, len ); + + len += sig_and_oid_len; + ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) ); + ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | + ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" +#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" + +#if defined(POLARSSL_PEM_WRITE_C) +int x509write_csr_pem( x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = x509write_csr_der( ctx, output_buf, sizeof(output_buf), + f_rng, p_rng ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* POLARSSL_PEM_WRITE_C */ + +#endif /* POLARSSL_X509_CSR_WRITE_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/library/xtea.c b/USDK/component/common/network/ssl/polarssl-1.3.8/library/xtea.c new file mode 100644 index 0000000..75215c5 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/library/xtea.c @@ -0,0 +1,283 @@ +/* + * An 32-bit implementation of the XTEA algorithm + * + * Copyright (C) 2006-2014, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#if !defined(POLARSSL_CONFIG_FILE) +#include "polarssl/config.h" +#else +#include POLARSSL_CONFIG_FILE +#endif + +#if defined(POLARSSL_XTEA_C) + +#include "polarssl/xtea.h" + +#if defined(POLARSSL_PLATFORM_C) +#include "polarssl/platform.h" +#else +#define polarssl_printf printf +#endif + +#if !defined(POLARSSL_XTEA_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void polarssl_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void xtea_init( xtea_context *ctx ) +{ + memset( ctx, 0, sizeof( xtea_context ) ); +} + +void xtea_free( xtea_context *ctx ) +{ + if( ctx == NULL ) + return; + + polarssl_zeroize( ctx, sizeof( xtea_context ) ); +} + +/* + * XTEA key schedule + */ +void xtea_setup( xtea_context *ctx, const unsigned char key[16] ) +{ + int i; + + memset( ctx, 0, sizeof(xtea_context) ); + + for( i = 0; i < 4; i++ ) + { + GET_UINT32_BE( ctx->k[i], key, i << 2 ); + } +} + +/* + * XTEA encrypt function + */ +int xtea_crypt_ecb( xtea_context *ctx, int mode, + const unsigned char input[8], unsigned char output[8]) +{ + uint32_t *k, v0, v1, i; + + k = ctx->k; + + GET_UINT32_BE( v0, input, 0 ); + GET_UINT32_BE( v1, input, 4 ); + + if( mode == XTEA_ENCRYPT ) + { + uint32_t sum = 0, delta = 0x9E3779B9; + + for( i = 0; i < 32; i++ ) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + } + } + else /* XTEA_DECRYPT */ + { + uint32_t delta = 0x9E3779B9, sum = delta * 32; + + for( i = 0; i < 32; i++ ) + { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } + } + + PUT_UINT32_BE( v0, output, 0 ); + PUT_UINT32_BE( v1, output, 4 ); + + return( 0 ); +} + +#if defined(POLARSSL_CIPHER_MODE_CBC) +/* + * XTEA-CBC buffer encryption/decryption + */ +int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length, + unsigned char iv[8], const unsigned char *input, + unsigned char *output) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH ); + + if( mode == XTEA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + xtea_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + xtea_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* POLARSSL_CIPHER_MODE_CBC */ +#endif /* !POLARSSL_XTEA_ALT */ + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +/* + * XTEA tests vectors (non-official) + */ + +static const unsigned char xtea_test_key[6][16] = +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char xtea_test_pt[6][8] = +{ + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } +}; + +static const unsigned char xtea_test_ct[6][8] = +{ + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } +}; + +/* + * Checkup routine + */ +int xtea_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char buf[8]; + xtea_context ctx; + + xtea_init( &ctx ); + for( i = 0; i < 6; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " XTEA test #%d: ", i + 1 ); + + memcpy( buf, xtea_test_pt[i], 8 ); + + xtea_setup( &ctx, xtea_test_key[i] ); + xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf ); + + if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + xtea_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#endif /* POLARSSL_XTEA_C */ diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_rom.mk b/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_rom.mk new file mode 100644 index 0000000..eec5e6b --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_rom.mk @@ -0,0 +1,20 @@ + +#*****************************************************************************# +# ROM Object FILE LIST # +#*****************************************************************************# +SSL_ROM_OBJS = aes.o arc4.o \ + asn1parse.o \ + asn1write.o base64.o bignum.o \ + ctr_drbg.o des.o \ + dhm.o ecdh.o ecdsa.o \ + ecp.o ecp_curves.o \ + hmac_drbg.o \ + md.o md_wrap.o \ + md5.o \ + oid.o \ + pem.o \ + pk.o pk_wrap.o \ + pkwrite.o \ + rsa.o sha1.o sha256.o \ + sha512.o \ + rom_ssl_ram_map.o diff --git a/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c b/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c new file mode 100644 index 0000000..921a748 --- /dev/null +++ b/USDK/component/common/network/ssl/polarssl-1.3.8/ssl_self_test.c @@ -0,0 +1,2657 @@ +#include "polarssl/config_rom.h" +#define polarssl_printf DiagPrintf + +#define AES_POLARSSL_SELF_TEST +#define ARC4_POLARSSL_SELF_TEST +#define BASE64_POLARSSL_SELF_TEST +#define BIGNUM_POLARSSL_SELF_TEST +#define CTR_DRBG_POLARSSL_SELF_TEST +#define DES_POLARSSL_SELF_TEST +#define DHM_POLARSSL_SELF_TEST +//#define ECP_POLARSSL_SELF_TEST //need open part of ecp rom code self test +#define HMAC_DRBG_POLARSSL_SELF_TEST +#define MD5_POLARSSL_SELF_TEST +#define RSA_POLARSSL_SELF_TEST +#define SHA1_POLARSSL_SELF_TEST +#define SHA256_POLARSSL_SELF_TEST +#define SHA512_POLARSSL_SELF_TEST + +#if defined(AES_POLARSSL_SELF_TEST) +#if defined(POLARSSL_AES_C) + +#include "polarssl/aes.h" +#if defined(POLARSSL_PADLOCK_C) +#include "polarssl/padlock.h" +#endif +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif + +#include + +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* POLARSSL_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char iv[16]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(POLARSSL_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + aes_context ctx; + + memset( key, 0, 32 ); + aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == AES_DECRYPT ) + { + aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +#if defined(POLARSSL_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CFB */ + +#if defined(POLARSSL_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " AES-CTR-128 (%s): ", + ( v == AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + aes_setkey_enc( &ctx, key, 128 ); + + if( v == AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); +#endif /* POLARSSL_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + aes_free( &ctx ); + + return( ret ); +} +#endif +#endif /* POLARSSL_SELF_TEST */ + +#if defined(ARC4_POLARSSL_SELF_TEST) + +#include "polarssl/arc4.h" +#include +#include + +/* + * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: + * + * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 + */ +static const unsigned char arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +/* + * Checkup routine + */ +int arc4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char ibuf[8]; + unsigned char obuf[8]; + arc4_context ctx; + + arc4_init( &ctx ); + + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " ARC4 test #%d: ", i + 1 ); + + memcpy( ibuf, arc4_test_pt[i], 8 ); + + arc4_setup( &ctx, arc4_test_key[i], 8 ); + arc4_crypt( &ctx, 8, ibuf, obuf ); + + if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + arc4_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(BASE64_POLARSSL_SELF_TEST) + +#include "polarssl/base64.h" +#include +#include + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int base64_self_test( int verbose ) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if( verbose != 0 ) + polarssl_printf( " Base64 encoding test: " ); + + len = sizeof( buffer ); + src = base64_test_dec; + + if( base64_encode( buffer, &len, src, 64 ) != 0 || + memcmp( base64_test_enc, buffer, 88 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n Base64 decoding test: " ); + + len = sizeof( buffer ); + src = base64_test_enc; + + if( base64_decode( buffer, &len, src, 88 ) != 0 || + memcmp( base64_test_dec, buffer, 64 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(BIGNUM_POLARSSL_SELF_TEST) + +#include "polarssl/bignum.h" +#include "polarssl/bn_mul.h" + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mpi_self_test( int verbose ) +{ + int ret, i; + mpi A, E, N, X, Y, U, V; + + mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); + mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); + + MPI_CHK( mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MPI_CHK( mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MPI_CHK( mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #1 (mul_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MPI_CHK( mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #2 (div_mpi): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 || + mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #3 (exp_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); + + MPI_CHK( mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #4 (inv_mod): " ); + + if( mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " MPI test #5 (simple gcd): " ); + + for( i = 0; i < GCD_PAIR_COUNT; i++ ) + { + MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); + MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MPI_CHK( mpi_gcd( &A, &X, &Y ) ); + + if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed at %d\n", i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); + mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(CTR_DRBG_POLARSSL_SELF_TEST) + +#include "polarssl/ctr_drbg.h" +#include + +static unsigned char entropy_source_pr[96] = + { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, + 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, + 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, + 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, + 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, + 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, + 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, + 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, + 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, + 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, + 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, + 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; + +static unsigned char entropy_source_nopr[64] = + { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, + 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, + 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, + 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, + 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, + 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, + 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, + 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; + +static const unsigned char nonce_pers_pr[16] = + { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, + 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; + +static const unsigned char nonce_pers_nopr[16] = + { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, + 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; + +static const unsigned char ctr_drbg_result_pr[16] = + { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, + 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; + +static const unsigned char ctr_drbg_result_nopr[16] = + { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, + 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; + +static size_t test_offset; +static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, + size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine + */ +int ctr_drbg_self_test( int verbose ) +{ + ctr_drbg_context ctx; + unsigned char buf[16]; + + /* + * Based on a NIST CTR_DRBG test vector (PR = True) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = TRUE) : " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_pr, nonce_pers_pr, 16, 32 ) ); + ctr_drbg_set_prediction_resistance( &ctx, CTR_DRBG_PR_ON ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( ctr_drbg_random( &ctx, buf, CTR_DRBG_BLOCKSIZE ) ); + CHK( memcmp( buf, ctr_drbg_result_pr, CTR_DRBG_BLOCKSIZE ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * Based on a NIST CTR_DRBG test vector (PR = FALSE) + */ + if( verbose != 0 ) + polarssl_printf( " CTR_DRBG (PR = FALSE): " ); + + test_offset = 0; + CHK( ctr_drbg_init_entropy_len( &ctx, ctr_drbg_self_test_entropy, + entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( ctr_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( memcmp( buf, ctr_drbg_result_nopr, 16 ) ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SELF_TEST */ + +#if defined(DES_POLARSSL_SELF_TEST) + +#include "polarssl/des.h" +#include + +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +#if defined(POLARSSL_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; +#endif /* POLARSSL_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int des_self_test( int verbose ) +{ + int i, j, u, v, ret = 0; + des_context ctx; + des3_context ctx3; + unsigned char buf[8]; +#if defined(POLARSSL_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + des_init( &ctx ); + des3_init( &ctx3 ); + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_ecb( &ctx, buf, buf ); + else + des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +#if defined(POLARSSL_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + polarssl_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } +#endif /* POLARSSL_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + des_free( &ctx ); + des3_free( &ctx3 ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(DHM_POLARSSL_SELF_TEST) + +#include "polarssl/dhm.h" +#include "polarssl/certs.h" + +/* + * Checkup routine + */ +int dhm_self_test( int verbose ) +{ +#if defined(POLARSSL_CERTS_C) + int ret; + dhm_context dhm; + + dhm_init( &dhm ); + + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: " ); + + if( ( ret = dhm_parse_dhm( &dhm, (const unsigned char *) test_dhm_params, + strlen( test_dhm_params ) ) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); + +exit: + dhm_free( &dhm ); + + return( ret ); +#else + if( verbose != 0 ) + polarssl_printf( " DHM parameter load: skipped\n" ); + + return( 0 ); +#endif /* POLARSSL_CERTS_C */ +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(ECP_POLARSSL_SELF_TEST) + +#include "polarssl/ecp.h" + +/* + * Counts of point addition and doubling, and field multiplications. + * Used to test resistance of point multiplication to simple timing attacks. + */ +extern unsigned long add_count, dbl_count, mul_count; + +/* + * Checkup routine + */ +int ecp_self_test( int verbose ) +{ + int ret; + size_t i; + ecp_group grp; + ecp_point R, P; + mpi m; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; + /* exponents especially adapted for secp192r1 */ + const char *exponents[] = + { + "000000000000000000000000000000000000000000000001", /* one */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ + "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ + }; + + ecp_group_init( &grp ); + ecp_point_init( &R ); + ecp_point_init( &P ); + mpi_init( &m ); + + /* Use secp192r1 if available, or any available curve */ +#if defined(POLARSSL_ECP_DP_SECP192R1_ENABLED) + MPI_CHK( ecp_use_known_dp( &grp, POLARSSL_ECP_DP_SECP192R1 ) ); +#else + MPI_CHK( ecp_use_known_dp( &grp, ecp_curve_list()->grp_id ) ); +#endif + + if( verbose != 0 ) + polarssl_printf( " ECP test #1 (constant op_count, base point G): " ); + + /* Do a dummy multiplication first to trigger precomputation */ + MPI_CHK( mpi_lset( &m, 2 ) ); + MPI_CHK( ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( " ECP test #2 (constant op_count, other point): " ); + /* We computed P = 2G last time, use it */ + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MPI_CHK( mpi_read_string( &m, 16, exponents[0] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MPI_CHK( mpi_read_string( &m, 16, exponents[i] ) ); + MPI_CHK( ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + polarssl_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + +cleanup: + + if( ret < 0 && verbose != 0 ) + polarssl_printf( "Unexpected error, return code = %08X\n", ret ); + + ecp_group_free( &grp ); + ecp_point_free( &R ); + ecp_point_free( &P ); + mpi_free( &m ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(HMAC_DRBG_POLARSSL_SELF_TEST) + +#include "polarssl/hmac_drbg.h" +#include + +#if !defined(POLARSSL_SHA1_C) +/* Dummy checkup routine */ +int hmac_drbg_self_test( int verbose ) +{ + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char hmac_drbg_result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char hmac_drbg_result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + polarssl_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int hmac_drbg_self_test( int verbose ) +{ + hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const md_info_t *md_info = md_info_from_type( POLARSSL_MD_SHA1 ); + + /* + * PR = True + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_pr, + NULL, 0 ) ); + hmac_drbg_set_prediction_resistance( &ctx, POLARSSL_HMAC_DRBG_PR_ON ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, hmac_drbg_result_pr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + polarssl_printf( " HMAC_DRBG (PR = False) : " ); + + test_offset = 0; + CHK( hmac_drbg_init( &ctx, md_info, + hmac_drbg_self_test_entropy, entropy_nopr, + NULL, 0 ) ); + CHK( hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, hmac_drbg_result_nopr, OUTPUT_LEN ) ); + hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} +#endif /* POLARSSL_SHA1_C */ +#endif /* POLARSSL_SELF_TEST */ + +#if defined(MD5_POLARSSL_SELF_TEST) + +#include "polarssl/md5.h" + +/* + * RFC 1321 test vectors + */ +static unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char md5_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int md5_hmac_test_keylen[7] = +{ + 16, 4, 16, 25, 16, 80, 80 +}; + +static unsigned char md5_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int md5_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char md5_hmac_test_sum[7][16] = +{ + { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C, + 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D }, + { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03, + 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 }, + { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88, + 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 }, + { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA, + 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 }, + { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00, + 0xF9, 0xBA, 0xB9, 0x95 }, + { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F, + 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD }, + { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE, + 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E } +}; + +/* + * Checkup routine + */ +int md5_self_test( int verbose ) +{ + int i, buflen; + unsigned char buf[1024]; + unsigned char md5sum[16]; + md5_context ctx; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " MD5 test #%d: ", i + 1 ); + + md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + md5_hmac_starts( &ctx, buf, buflen ); + } + else + md5_hmac_starts( &ctx, md5_hmac_test_key[i], + md5_hmac_test_keylen[i] ); + + md5_hmac_update( &ctx, md5_hmac_test_buf[i], + md5_hmac_test_buflen[i] ); + + md5_hmac_finish( &ctx, md5sum ); + + buflen = ( i == 4 ) ? 12 : 16; + + if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + return( 0 ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(RSA_POLARSSL_SELF_TEST) + +#include "polarssl/rsa.h" +#include "polarssl/oid.h" +#include "polarssl/sha1.h" + +/* + * Example RSA-1024 keypair, for test purposes + */ +#define KEY_LEN 128 + +#define RSA_N "9292758453063D803DD603D5E777D788" \ + "8ED1D5BF35786190FA2F23EBC0848AEA" \ + "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ + "7130B9CED7ACDF54CFC7555AC14EEBAB" \ + "93A89813FBF3C4F8066D2D800F7C38A8" \ + "1AE31942917403FF4946B0A83D3D3E05" \ + "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ + "5E94BB77B07507233A0BC7BAC8F90F79" + +#define RSA_E "10001" + +#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ + "66CA472BC44D253102F8B4A9D3BFA750" \ + "91386C0077937FE33FA3252D28855837" \ + "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ + "DF79C5CE07EE72C7F123142198164234" \ + "CABB724CF78B8173B9F880FC86322407" \ + "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ + "071513A1E85B5DFA031F21ECAE91A34D" + +#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ + "2C01CAD19EA484A87EA4377637E75500" \ + "FCB2005C5C7DD6EC4AC023CDA285D796" \ + "C3D9E75E1EFC42488BB4F1D13AC30A57" + +#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ + "E211C2B9E5DB1ED0BF61D0D9899620F4" \ + "910E4168387E3C30AA1E00C339A79508" \ + "8452DD96A9A5EA5D9DCA68DA636032AF" + +#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \ + "3C94D22288ACD763FD8E5600ED4A702D" \ + "F84198A5F06C2E72236AE490C93F07F8" \ + "3CC559CD27BC2D1CA488811730BB5725" + +#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \ + "D8AAEA56749EA28623272E4F7D0592AF" \ + "7C1F1313CAC9471B5C523BFE592F517B" \ + "407A1BD76C164B93DA2D32A383E58357" + +#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \ + "F38D18D2B2F0E2DD275AA977E2BF4411" \ + "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ + "A74206CEC169D74BF5A8C50D6F48EA08" + +#define PT_LEN 24 +#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ + "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" + +#if defined(POLARSSL_PKCS1_V15) +static int myrand( void *rng_state, unsigned char *output, size_t len ) +{ +#if !defined(__OpenBSD__) + size_t i; + + if( rng_state != NULL ) + rng_state = NULL; + + for( i = 0; i < len; ++i ) + output[i] = Rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ + + return( 0 ); +} +#endif /* POLARSSL_PKCS1_V15 */ + +/* + * Checkup routine + */ +int rsa_self_test( int verbose ) +{ + int ret = 0; +#if defined(POLARSSL_PKCS1_V15) + size_t len; + rsa_context rsa; + unsigned char rsa_plaintext[PT_LEN]; + unsigned char rsa_decrypted[PT_LEN]; + unsigned char rsa_ciphertext[KEY_LEN]; +#if defined(POLARSSL_SHA1_C) + unsigned char sha1sum[20]; +#endif + + rsa_init( &rsa, RSA_PKCS_V15, 0 ); + + rsa.len = KEY_LEN; + MPI_CHK( mpi_read_string( &rsa.N , 16, RSA_N ) ); + MPI_CHK( mpi_read_string( &rsa.E , 16, RSA_E ) ); + MPI_CHK( mpi_read_string( &rsa.D , 16, RSA_D ) ); + MPI_CHK( mpi_read_string( &rsa.P , 16, RSA_P ) ); + MPI_CHK( mpi_read_string( &rsa.Q , 16, RSA_Q ) ); + MPI_CHK( mpi_read_string( &rsa.DP, 16, RSA_DP ) ); + MPI_CHK( mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); + MPI_CHK( mpi_read_string( &rsa.QP, 16, RSA_QP ) ); + + if( verbose != 0 ) + polarssl_printf( " RSA key validation: " ); + + if( rsa_check_pubkey( &rsa ) != 0 || + rsa_check_privkey( &rsa ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 encryption : " ); + + memcpy( rsa_plaintext, RSA_PT, PT_LEN ); + + if( rsa_pkcs1_encrypt( &rsa, myrand, NULL, RSA_PUBLIC, PT_LEN, + rsa_plaintext, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 decryption : " ); + + if( rsa_pkcs1_decrypt( &rsa, myrand, NULL, RSA_PRIVATE, &len, + rsa_ciphertext, rsa_decrypted, + sizeof(rsa_decrypted) ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + +#if defined(POLARSSL_SHA1_C) + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 data sign : " ); + + sha1( rsa_plaintext, PT_LEN, sha1sum ); + + if( rsa_pkcs1_sign( &rsa, myrand, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n PKCS#1 sig. verify: " ); + + if( rsa_pkcs1_verify( &rsa, NULL, NULL, RSA_PUBLIC, POLARSSL_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + polarssl_printf( "passed\n\n" ); +#endif /* POLARSSL_SHA1_C */ + +cleanup: + rsa_free( &rsa ); +#else /* POLARSSL_PKCS1_V15 */ + ((void) verbose); +#endif /* POLARSSL_PKCS1_V15 */ + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(SHA1_POLARSSL_SELF_TEST) + +#include "polarssl/sha1.h" + +/* + * FIPS-180-1 test vectors + */ +static unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * RFC 2202 test vectors + */ +static unsigned char sha1_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 80 times */ + { "" } +}; + +static const int sha1_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 80, 80 +}; + +static unsigned char sha1_hmac_test_buf[7][74] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "Test Using Larger Than Block-Size Key and Larger" + " Than One Block-Size Data" } +}; + +static const int sha1_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 73 +}; + +static const unsigned char sha1_hmac_test_sum[7][20] = +{ + { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B, + 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 }, + { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74, + 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 }, + { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3, + 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 }, + { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84, + 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA }, + { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2, + 0x7B, 0xE1 }, + { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70, + 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 }, + { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B, + 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 } +}; + +/* + * Checkup routine + */ +int sha1_self_test( int verbose ) +{ + int i, j, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + sha1_context ctx; + + sha1_init( &ctx ); + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " SHA-1 test #%d: ", i + 1 ); + + sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha1_update( &ctx, buf, buflen ); + } + else + sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-1 test #%d: ", i + 1 ); + + if( i == 5 || i == 6 ) + { + memset( buf, '\xAA', buflen = 80 ); + sha1_hmac_starts( &ctx, buf, buflen ); + } + else + sha1_hmac_starts( &ctx, sha1_hmac_test_key[i], + sha1_hmac_test_keylen[i] ); + + sha1_hmac_update( &ctx, sha1_hmac_test_buf[i], + sha1_hmac_test_buflen[i] ); + + sha1_hmac_finish( &ctx, sha1sum ); + + buflen = ( i == 4 ) ? 12 : 20; + + if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha1_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(SHA256_POLARSSL_SELF_TEST) + +#include "polarssl/sha256.h" + +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha256_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha256_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha256_test_sum[6][32] = +{ + /* + * SHA-224 test vectors + */ + { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, + 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, + 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, + 0xE3, 0x6C, 0x9D, 0xA7 }, + { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, + 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, + 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, + 0x52, 0x52, 0x25, 0x25 }, + { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, + 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, + 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, + 0x4E, 0xE7, 0xAD, 0x67 }, + + /* + * SHA-256 test vectors + */ + { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, + { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, + { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha256_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha256_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha256_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha256_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha256_hmac_test_sum[14][32] = +{ + /* + * HMAC-SHA-224 test vectors + */ + { 0x89, 0x6F, 0xB1, 0x12, 0x8A, 0xBB, 0xDF, 0x19, + 0x68, 0x32, 0x10, 0x7C, 0xD4, 0x9D, 0xF3, 0x3F, + 0x47, 0xB4, 0xB1, 0x16, 0x99, 0x12, 0xBA, 0x4F, + 0x53, 0x68, 0x4B, 0x22 }, + { 0xA3, 0x0E, 0x01, 0x09, 0x8B, 0xC6, 0xDB, 0xBF, + 0x45, 0x69, 0x0F, 0x3A, 0x7E, 0x9E, 0x6D, 0x0F, + 0x8B, 0xBE, 0xA2, 0xA3, 0x9E, 0x61, 0x48, 0x00, + 0x8F, 0xD0, 0x5E, 0x44 }, + { 0x7F, 0xB3, 0xCB, 0x35, 0x88, 0xC6, 0xC1, 0xF6, + 0xFF, 0xA9, 0x69, 0x4D, 0x7D, 0x6A, 0xD2, 0x64, + 0x93, 0x65, 0xB0, 0xC1, 0xF6, 0x5D, 0x69, 0xD1, + 0xEC, 0x83, 0x33, 0xEA }, + { 0x6C, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3C, 0xAC, + 0x6A, 0x2A, 0xBC, 0x1B, 0xB3, 0x82, 0x62, 0x7C, + 0xEC, 0x6A, 0x90, 0xD8, 0x6E, 0xFC, 0x01, 0x2D, + 0xE7, 0xAF, 0xEC, 0x5A }, + { 0x0E, 0x2A, 0xEA, 0x68, 0xA9, 0x0C, 0x8D, 0x37, + 0xC9, 0x88, 0xBC, 0xDB, 0x9F, 0xCA, 0x6F, 0xA8 }, + { 0x95, 0xE9, 0xA0, 0xDB, 0x96, 0x20, 0x95, 0xAD, + 0xAE, 0xBE, 0x9B, 0x2D, 0x6F, 0x0D, 0xBC, 0xE2, + 0xD4, 0x99, 0xF1, 0x12, 0xF2, 0xD2, 0xB7, 0x27, + 0x3F, 0xA6, 0x87, 0x0E }, + { 0x3A, 0x85, 0x41, 0x66, 0xAC, 0x5D, 0x9F, 0x02, + 0x3F, 0x54, 0xD5, 0x17, 0xD0, 0xB3, 0x9D, 0xBD, + 0x94, 0x67, 0x70, 0xDB, 0x9C, 0x2B, 0x95, 0xC9, + 0xF6, 0xF5, 0x65, 0xD1 }, + + /* + * HMAC-SHA-256 test vectors + */ + { 0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53, + 0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B, + 0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7, + 0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7 }, + { 0x5B, 0xDC, 0xC1, 0x46, 0xBF, 0x60, 0x75, 0x4E, + 0x6A, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xC7, + 0x5A, 0x00, 0x3F, 0x08, 0x9D, 0x27, 0x39, 0x83, + 0x9D, 0xEC, 0x58, 0xB9, 0x64, 0xEC, 0x38, 0x43 }, + { 0x77, 0x3E, 0xA9, 0x1E, 0x36, 0x80, 0x0E, 0x46, + 0x85, 0x4D, 0xB8, 0xEB, 0xD0, 0x91, 0x81, 0xA7, + 0x29, 0x59, 0x09, 0x8B, 0x3E, 0xF8, 0xC1, 0x22, + 0xD9, 0x63, 0x55, 0x14, 0xCE, 0xD5, 0x65, 0xFE }, + { 0x82, 0x55, 0x8A, 0x38, 0x9A, 0x44, 0x3C, 0x0E, + 0xA4, 0xCC, 0x81, 0x98, 0x99, 0xF2, 0x08, 0x3A, + 0x85, 0xF0, 0xFA, 0xA3, 0xE5, 0x78, 0xF8, 0x07, + 0x7A, 0x2E, 0x3F, 0xF4, 0x67, 0x29, 0x66, 0x5B }, + { 0xA3, 0xB6, 0x16, 0x74, 0x73, 0x10, 0x0E, 0xE0, + 0x6E, 0x0C, 0x79, 0x6C, 0x29, 0x55, 0x55, 0x2B }, + { 0x60, 0xE4, 0x31, 0x59, 0x1E, 0xE0, 0xB6, 0x7F, + 0x0D, 0x8A, 0x26, 0xAA, 0xCB, 0xF5, 0xB7, 0x7F, + 0x8E, 0x0B, 0xC6, 0x21, 0x37, 0x28, 0xC5, 0x14, + 0x05, 0x46, 0x04, 0x0F, 0x0E, 0xE3, 0x7F, 0x54 }, + { 0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB, + 0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44, + 0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93, + 0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2 } +}; + +/* + * Checkup routine + */ +int sha256_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha256sum[32]; + sha256_context ctx; + + sha256_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + sha256_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha256_update( &ctx, buf, buflen ); + } + else + sha256_update( &ctx, sha256_test_buf[j], + sha256_test_buflen[j] ); + + sha256_finish( &ctx, sha256sum ); + + if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha256_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha256_hmac_starts( &ctx, sha256_hmac_test_key[j], + sha256_hmac_test_keylen[j], k ); + + sha256_hmac_update( &ctx, sha256_hmac_test_buf[j], + sha256_hmac_test_buflen[j] ); + + sha256_hmac_finish( &ctx, sha256sum ); + + buflen = ( j == 4 ) ? 16 : 32 - k * 4; + + if( memcmp( sha256sum, sha256_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha256_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +#if defined(SHA512_POLARSSL_SELF_TEST) + +#include "polarssl/sha512.h" + +/* + * FIPS-180-2 test vectors + */ +static unsigned char sha512_test_buf[3][113] = +{ + { "abc" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "" } +}; + +static const int sha512_test_buflen[3] = +{ + 3, 112, 1000 +}; + +static const unsigned char sha512_test_sum[6][64] = +{ + /* + * SHA-384 test vectors + */ + { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, + 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, + 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, + 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, + 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, + 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, + { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, + 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, + 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, + 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, + 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, + 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, + { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, + 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, + 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, + 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, + 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, + 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, + + /* + * SHA-512 test vectors + */ + { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, + 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, + 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, + 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, + 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, + 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, + 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, + 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, + { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, + { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, + 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, + 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, + 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, + 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, + 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, + 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } +}; + +/* + * RFC 4231 test vectors + */ +static unsigned char sha512_hmac_test_key[7][26] = +{ + { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" + "\x0B\x0B\x0B\x0B" }, + { "Jefe" }, + { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA" }, + { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19" }, + { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" + "\x0C\x0C\x0C\x0C" }, + { "" }, /* 0xAA 131 times */ + { "" } +}; + +static const int sha512_hmac_test_keylen[7] = +{ + 20, 4, 20, 25, 20, 131, 131 +}; + +static unsigned char sha512_hmac_test_buf[7][153] = +{ + { "Hi There" }, + { "what do ya want for nothing?" }, + { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" }, + { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" + "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" }, + { "Test With Truncation" }, + { "Test Using Larger Than Block-Size Key - Hash Key First" }, + { "This is a test using a larger than block-size key " + "and a larger than block-size data. The key needs to " + "be hashed before being used by the HMAC algorithm." } +}; + +static const int sha512_hmac_test_buflen[7] = +{ + 8, 28, 50, 50, 20, 54, 152 +}; + +static const unsigned char sha512_hmac_test_sum[14][64] = +{ + /* + * HMAC-SHA-384 test vectors + */ + { 0xAF, 0xD0, 0x39, 0x44, 0xD8, 0x48, 0x95, 0x62, + 0x6B, 0x08, 0x25, 0xF4, 0xAB, 0x46, 0x90, 0x7F, + 0x15, 0xF9, 0xDA, 0xDB, 0xE4, 0x10, 0x1E, 0xC6, + 0x82, 0xAA, 0x03, 0x4C, 0x7C, 0xEB, 0xC5, 0x9C, + 0xFA, 0xEA, 0x9E, 0xA9, 0x07, 0x6E, 0xDE, 0x7F, + 0x4A, 0xF1, 0x52, 0xE8, 0xB2, 0xFA, 0x9C, 0xB6 }, + { 0xAF, 0x45, 0xD2, 0xE3, 0x76, 0x48, 0x40, 0x31, + 0x61, 0x7F, 0x78, 0xD2, 0xB5, 0x8A, 0x6B, 0x1B, + 0x9C, 0x7E, 0xF4, 0x64, 0xF5, 0xA0, 0x1B, 0x47, + 0xE4, 0x2E, 0xC3, 0x73, 0x63, 0x22, 0x44, 0x5E, + 0x8E, 0x22, 0x40, 0xCA, 0x5E, 0x69, 0xE2, 0xC7, + 0x8B, 0x32, 0x39, 0xEC, 0xFA, 0xB2, 0x16, 0x49 }, + { 0x88, 0x06, 0x26, 0x08, 0xD3, 0xE6, 0xAD, 0x8A, + 0x0A, 0xA2, 0xAC, 0xE0, 0x14, 0xC8, 0xA8, 0x6F, + 0x0A, 0xA6, 0x35, 0xD9, 0x47, 0xAC, 0x9F, 0xEB, + 0xE8, 0x3E, 0xF4, 0xE5, 0x59, 0x66, 0x14, 0x4B, + 0x2A, 0x5A, 0xB3, 0x9D, 0xC1, 0x38, 0x14, 0xB9, + 0x4E, 0x3A, 0xB6, 0xE1, 0x01, 0xA3, 0x4F, 0x27 }, + { 0x3E, 0x8A, 0x69, 0xB7, 0x78, 0x3C, 0x25, 0x85, + 0x19, 0x33, 0xAB, 0x62, 0x90, 0xAF, 0x6C, 0xA7, + 0x7A, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9C, + 0xC5, 0x57, 0x7C, 0x6E, 0x1F, 0x57, 0x3B, 0x4E, + 0x68, 0x01, 0xDD, 0x23, 0xC4, 0xA7, 0xD6, 0x79, + 0xCC, 0xF8, 0xA3, 0x86, 0xC6, 0x74, 0xCF, 0xFB }, + { 0x3A, 0xBF, 0x34, 0xC3, 0x50, 0x3B, 0x2A, 0x23, + 0xA4, 0x6E, 0xFC, 0x61, 0x9B, 0xAE, 0xF8, 0x97 }, + { 0x4E, 0xCE, 0x08, 0x44, 0x85, 0x81, 0x3E, 0x90, + 0x88, 0xD2, 0xC6, 0x3A, 0x04, 0x1B, 0xC5, 0xB4, + 0x4F, 0x9E, 0xF1, 0x01, 0x2A, 0x2B, 0x58, 0x8F, + 0x3C, 0xD1, 0x1F, 0x05, 0x03, 0x3A, 0xC4, 0xC6, + 0x0C, 0x2E, 0xF6, 0xAB, 0x40, 0x30, 0xFE, 0x82, + 0x96, 0x24, 0x8D, 0xF1, 0x63, 0xF4, 0x49, 0x52 }, + { 0x66, 0x17, 0x17, 0x8E, 0x94, 0x1F, 0x02, 0x0D, + 0x35, 0x1E, 0x2F, 0x25, 0x4E, 0x8F, 0xD3, 0x2C, + 0x60, 0x24, 0x20, 0xFE, 0xB0, 0xB8, 0xFB, 0x9A, + 0xDC, 0xCE, 0xBB, 0x82, 0x46, 0x1E, 0x99, 0xC5, + 0xA6, 0x78, 0xCC, 0x31, 0xE7, 0x99, 0x17, 0x6D, + 0x38, 0x60, 0xE6, 0x11, 0x0C, 0x46, 0x52, 0x3E }, + + /* + * HMAC-SHA-512 test vectors + */ + { 0x87, 0xAA, 0x7C, 0xDE, 0xA5, 0xEF, 0x61, 0x9D, + 0x4F, 0xF0, 0xB4, 0x24, 0x1A, 0x1D, 0x6C, 0xB0, + 0x23, 0x79, 0xF4, 0xE2, 0xCE, 0x4E, 0xC2, 0x78, + 0x7A, 0xD0, 0xB3, 0x05, 0x45, 0xE1, 0x7C, 0xDE, + 0xDA, 0xA8, 0x33, 0xB7, 0xD6, 0xB8, 0xA7, 0x02, + 0x03, 0x8B, 0x27, 0x4E, 0xAE, 0xA3, 0xF4, 0xE4, + 0xBE, 0x9D, 0x91, 0x4E, 0xEB, 0x61, 0xF1, 0x70, + 0x2E, 0x69, 0x6C, 0x20, 0x3A, 0x12, 0x68, 0x54 }, + { 0x16, 0x4B, 0x7A, 0x7B, 0xFC, 0xF8, 0x19, 0xE2, + 0xE3, 0x95, 0xFB, 0xE7, 0x3B, 0x56, 0xE0, 0xA3, + 0x87, 0xBD, 0x64, 0x22, 0x2E, 0x83, 0x1F, 0xD6, + 0x10, 0x27, 0x0C, 0xD7, 0xEA, 0x25, 0x05, 0x54, + 0x97, 0x58, 0xBF, 0x75, 0xC0, 0x5A, 0x99, 0x4A, + 0x6D, 0x03, 0x4F, 0x65, 0xF8, 0xF0, 0xE6, 0xFD, + 0xCA, 0xEA, 0xB1, 0xA3, 0x4D, 0x4A, 0x6B, 0x4B, + 0x63, 0x6E, 0x07, 0x0A, 0x38, 0xBC, 0xE7, 0x37 }, + { 0xFA, 0x73, 0xB0, 0x08, 0x9D, 0x56, 0xA2, 0x84, + 0xEF, 0xB0, 0xF0, 0x75, 0x6C, 0x89, 0x0B, 0xE9, + 0xB1, 0xB5, 0xDB, 0xDD, 0x8E, 0xE8, 0x1A, 0x36, + 0x55, 0xF8, 0x3E, 0x33, 0xB2, 0x27, 0x9D, 0x39, + 0xBF, 0x3E, 0x84, 0x82, 0x79, 0xA7, 0x22, 0xC8, + 0x06, 0xB4, 0x85, 0xA4, 0x7E, 0x67, 0xC8, 0x07, + 0xB9, 0x46, 0xA3, 0x37, 0xBE, 0xE8, 0x94, 0x26, + 0x74, 0x27, 0x88, 0x59, 0xE1, 0x32, 0x92, 0xFB }, + { 0xB0, 0xBA, 0x46, 0x56, 0x37, 0x45, 0x8C, 0x69, + 0x90, 0xE5, 0xA8, 0xC5, 0xF6, 0x1D, 0x4A, 0xF7, + 0xE5, 0x76, 0xD9, 0x7F, 0xF9, 0x4B, 0x87, 0x2D, + 0xE7, 0x6F, 0x80, 0x50, 0x36, 0x1E, 0xE3, 0xDB, + 0xA9, 0x1C, 0xA5, 0xC1, 0x1A, 0xA2, 0x5E, 0xB4, + 0xD6, 0x79, 0x27, 0x5C, 0xC5, 0x78, 0x80, 0x63, + 0xA5, 0xF1, 0x97, 0x41, 0x12, 0x0C, 0x4F, 0x2D, + 0xE2, 0xAD, 0xEB, 0xEB, 0x10, 0xA2, 0x98, 0xDD }, + { 0x41, 0x5F, 0xAD, 0x62, 0x71, 0x58, 0x0A, 0x53, + 0x1D, 0x41, 0x79, 0xBC, 0x89, 0x1D, 0x87, 0xA6 }, + { 0x80, 0xB2, 0x42, 0x63, 0xC7, 0xC1, 0xA3, 0xEB, + 0xB7, 0x14, 0x93, 0xC1, 0xDD, 0x7B, 0xE8, 0xB4, + 0x9B, 0x46, 0xD1, 0xF4, 0x1B, 0x4A, 0xEE, 0xC1, + 0x12, 0x1B, 0x01, 0x37, 0x83, 0xF8, 0xF3, 0x52, + 0x6B, 0x56, 0xD0, 0x37, 0xE0, 0x5F, 0x25, 0x98, + 0xBD, 0x0F, 0xD2, 0x21, 0x5D, 0x6A, 0x1E, 0x52, + 0x95, 0xE6, 0x4F, 0x73, 0xF6, 0x3F, 0x0A, 0xEC, + 0x8B, 0x91, 0x5A, 0x98, 0x5D, 0x78, 0x65, 0x98 }, + { 0xE3, 0x7B, 0x6A, 0x77, 0x5D, 0xC8, 0x7D, 0xBA, + 0xA4, 0xDF, 0xA9, 0xF9, 0x6E, 0x5E, 0x3F, 0xFD, + 0xDE, 0xBD, 0x71, 0xF8, 0x86, 0x72, 0x89, 0x86, + 0x5D, 0xF5, 0xA3, 0x2D, 0x20, 0xCD, 0xC9, 0x44, + 0xB6, 0x02, 0x2C, 0xAC, 0x3C, 0x49, 0x82, 0xB1, + 0x0D, 0x5E, 0xEB, 0x55, 0xC3, 0xE4, 0xDE, 0x15, + 0x13, 0x46, 0x76, 0xFB, 0x6D, 0xE0, 0x44, 0x60, + 0x65, 0xC9, 0x74, 0x40, 0xFA, 0x8C, 0x6A, 0x58 } +}; + +/* + * Checkup routine + */ +int sha512_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha512sum[64]; + sha512_context ctx; + + sha512_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + polarssl_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + sha512_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + sha512_update( &ctx, buf, buflen ); + } + else + sha512_update( &ctx, sha512_test_buf[j], + sha512_test_buflen[j] ); + + sha512_finish( &ctx, sha512sum ); + + if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + + for( i = 0; i < 14; i++ ) + { + j = i % 7; + k = i < 7; + + if( verbose != 0 ) + polarssl_printf( " HMAC-SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + if( j == 5 || j == 6 ) + { + memset( buf, '\xAA', buflen = 131 ); + sha512_hmac_starts( &ctx, buf, buflen, k ); + } + else + sha512_hmac_starts( &ctx, sha512_hmac_test_key[j], + sha512_hmac_test_keylen[j], k ); + + sha512_hmac_update( &ctx, sha512_hmac_test_buf[j], + sha512_hmac_test_buflen[j] ); + + sha512_hmac_finish( &ctx, sha512sum ); + + buflen = ( j == 4 ) ? 16 : 64 - k * 16; + + if( memcmp( sha512sum, sha512_hmac_test_sum[i], buflen ) != 0 ) + { + if( verbose != 0 ) + polarssl_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + polarssl_printf( "passed\n" ); + } + + if( verbose != 0 ) + polarssl_printf( "\n" ); + +exit: + sha512_free( &ctx ); + + return( ret ); +} + +#endif /* POLARSSL_SELF_TEST */ + +extern void *pvPortMalloc(unsigned int xWantedSize); +extern void vPortFree(void *pv); + +int ssl_self_test( int verbose ) +{ + platform_set_malloc_free(pvPortMalloc, vPortFree); + + if (rom_ssl_ram_map.use_hw_crypto_func && rtl_cryptoEngine_init() != SUCCESS) { + polarssl_printf("Use HW Crypto, but Crypto Engine Init fail!!!\n"); + return -1; + } + + aes_self_test(1); + arc4_self_test(1); + base64_self_test(1); + mpi_self_test(1); + ctr_drbg_self_test(1); //bignum + des_self_test(1); + dhm_self_test(1); +#if defined(ECP_POLARSSL_SELF_TEST) + ecp_self_test(1); +#endif + hmac_drbg_self_test(1); + md5_self_test(1); + rsa_self_test(1); + sha1_self_test(1); + sha256_self_test(1); + sha512_self_test(1); + + return 0; +} diff --git a/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.c b/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.c new file mode 100644 index 0000000..7a4d481 --- /dev/null +++ b/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.c @@ -0,0 +1,13 @@ +#include +#include + +#ifndef SSL_RAM_MAP_SECTION +#define SSL_RAM_MAP_SECTION +#endif + +/* RAM table referred by SSL ROM */ +SSL_RAM_MAP_SECTION +struct _rom_ssl_ram_map rom_ssl_ram_map; + +SSL_RAM_MAP_SECTION +int ssl_max_frag_len; \ No newline at end of file diff --git a/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.h b/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.h new file mode 100644 index 0000000..eb0bbb6 --- /dev/null +++ b/USDK/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.h @@ -0,0 +1,59 @@ +#ifndef ROM_SSL_RAM_MAP_H +#define ROM_SSL_RAM_MAP_H + +#include "basic_types.h" + +struct _rom_ssl_ram_map { + /* OS interface */ + void *(*ssl_malloc)(unsigned int sz); + void (*ssl_free)(void *); + int (*ssl_printf)(const char *, ...); + + //AES HW CRYPTO + int (*hw_crypto_aes_ecb_init)(const u8* key, const u32 keylen); + int (*hw_crypto_aes_ecb_decrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_aes_ecb_encrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_aes_cbc_init)(const u8* key, const u32 keylen); + int (*hw_crypto_aes_cbc_decrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_aes_cbc_encrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + + //DES HW CRYPTO + int (*hw_crypto_des_cbc_init)(const u8* key, const u32 keylen); + int (*hw_crypto_des_cbc_decrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_des_cbc_encrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_3des_cbc_init)(const u8* key, const u32 keylen); + int (*hw_crypto_3des_cbc_decrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + int (*hw_crypto_3des_cbc_encrypt)( + const u8* message, const u32 msglen, + const u8* iv, const u32 ivlen, + u8* pResult); + + /* Variables */ + u32 use_hw_crypto_func; + u32 ssl_buffer_len; +}; + +extern struct _rom_ssl_ram_map rom_ssl_ram_map; + +#endif /* ROM_SSL_RAM_MAP_H */ diff --git a/USDK/component/common/network/ssl/ssl_ram_map/ssl_ram_map.c b/USDK/component/common/network/ssl/ssl_ram_map/ssl_ram_map.c new file mode 100644 index 0000000..33d2d4b --- /dev/null +++ b/USDK/component/common/network/ssl/ssl_ram_map/ssl_ram_map.c @@ -0,0 +1,88 @@ +#include "rom_ssl_ram_map.h" +#include +#include + +extern struct _rom_ssl_ram_map rom_ssl_ram_map; + +//AES HW CRYPTO +extern int rtl_crypto_aes_ecb_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_aes_ecb_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_aes_ecb_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_aes_cbc_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_aes_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_aes_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); + +//DES HW CRYPTO +extern int rtl_crypto_des_cbc_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_des_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_des_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_3des_cbc_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_3des_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); +extern int rtl_crypto_3des_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, + OUT u8* pResult); + +extern int ssl_max_frag_len; + +int platform_set_malloc_free( void * (*malloc_func)( size_t ), + void (*free_func)( void * ) ) +{ + /* OS interface */ + rom_ssl_ram_map.ssl_malloc = malloc_func; + rom_ssl_ram_map.ssl_free = free_func; + rom_ssl_ram_map.ssl_printf = (int (*)(char const *, ...))DiagPrintf; + + //AES HW CRYPTO + rom_ssl_ram_map.hw_crypto_aes_ecb_init = rtl_crypto_aes_ecb_init; + rom_ssl_ram_map.hw_crypto_aes_ecb_decrypt = rtl_crypto_aes_ecb_decrypt; + rom_ssl_ram_map.hw_crypto_aes_ecb_encrypt = rtl_crypto_aes_ecb_encrypt; + rom_ssl_ram_map.hw_crypto_aes_cbc_init = rtl_crypto_aes_cbc_init; + rom_ssl_ram_map.hw_crypto_aes_cbc_decrypt = rtl_crypto_aes_cbc_decrypt; + rom_ssl_ram_map.hw_crypto_aes_cbc_encrypt = rtl_crypto_aes_cbc_encrypt; + + //DES HW CRYPTO + rom_ssl_ram_map.hw_crypto_des_cbc_init = rtl_crypto_des_cbc_init; + rom_ssl_ram_map.hw_crypto_des_cbc_decrypt = rtl_crypto_des_cbc_decrypt; + rom_ssl_ram_map.hw_crypto_des_cbc_encrypt = rtl_crypto_des_cbc_encrypt; + rom_ssl_ram_map.hw_crypto_3des_cbc_init = rtl_crypto_3des_cbc_init; + rom_ssl_ram_map.hw_crypto_3des_cbc_decrypt = rtl_crypto_3des_cbc_decrypt; + rom_ssl_ram_map.hw_crypto_3des_cbc_encrypt = rtl_crypto_3des_cbc_encrypt; + + /* Variables */ + rom_ssl_ram_map.use_hw_crypto_func = 1; + + int len = ssl_max_frag_len; + if(len == 0) len = 8192; + else if(len < 512) len = 512; + else if(len > 16384) len = 16384; + rom_ssl_ram_map.ssl_buffer_len = len + SSL_COMPRESSION_ADD + + 29 /* counter + header + IV */ + + SSL_MAC_ADD + + SSL_PADDING_ADD; +#if defined(POLARSSL_SSL_MAX_FRAGMENT_LENGTH) + mfl_code_to_length[0] = len; +#endif + return 0; +} diff --git a/USDK/component/common/network/websocket/libwsclient.h b/USDK/component/common/network/websocket/libwsclient.h new file mode 100644 index 0000000..f0ee8b3 --- /dev/null +++ b/USDK/component/common/network/websocket/libwsclient.h @@ -0,0 +1,120 @@ +#ifndef EASYWSCLIENT_H +#define EASYWSCLIENT_H +#include + +/****************Define the debug message level*********************/ +#define DEBUG_WSCLIENT 1 + +#define WSCLIENT_LOG(level, fmt, ...) printf("\n\r[WSCLIENT %s] %s: " fmt "\n", level, __FUNCTION__, ##__VA_ARGS__) +#if DEBUG_WSCLIENT == 2 +#define WSCLIENT_DEBUG(fmt, ...) WSCLIENT_LOG("DEBUG", fmt, ##__VA_ARGS__) +#else +#define WSCLIENT_DEBUG(fmt, ...) +#endif +#if DEBUG_WSCLIENT +#define WSCLIENT_ERROR(fmt, ...) WSCLIENT_LOG("ERROR", fmt, ##__VA_ARGS__) +#else +#define WSCLIENT_ERROR(fmt, ...) +#endif +/*******************************************************************/ + +/****************Define the structures used*************************/ +typedef enum{ + CLOSING, + CLOSED, + CONNECTING, + OPEN +} readyStateValues; + +struct wsheader_type{ + unsigned header_size; + int fin; + int mask; + enum opcode_type { + CONTINUATION = 0x0, + TEXT_FRAME = 0x1, + BINARY_FRAME = 0x2, + CLOSE = 8, + PING = 9, + PONG = 0xa, + } opcode; + int N0; + uint64_t N; + uint8_t masking_key[4]; +}; + +struct _wsclient_context; +struct _ssl_context; + +struct ssl_fun_ops{ + int (*memory_set_own)( void * (*malloc_func)( size_t ),void (*free_func)( void * ) ); + int (*net_connect)( int *fd, const char *host, int port ); + int (*ssl_init)( struct _ssl_context *ssl ); + void (*ssl_set_endpoint)( struct _ssl_context *ssl, int endpoint ); + void (*ssl_set_authmode)( struct _ssl_context *ssl, int authmode ); + void (*ssl_set_rng)( struct _ssl_context *ssl, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ); + void (*ssl_set_bio)( struct _ssl_context *ssl, + int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, + int (*f_send)(void *, const unsigned char *, size_t), void *p_send ); + int (*ssl_handshake)( struct _ssl_context *ssl ); + void (*net_close)( int fd ); + void (*ssl_free)( struct _ssl_context *ssl ); + int (*ssl_read)( struct _ssl_context *ssl, unsigned char *buf, size_t len ); + int (*ssl_write)( struct _ssl_context *ssl, const unsigned char *buf, size_t len ); + const char *(*ssl_get_ciphersuite)( const struct _ssl_context *ssl ); + int (*net_recv)( void *ctx, unsigned char *buf, size_t len ); + int (*net_send)( void *ctx, const unsigned char *buf, size_t len ); +}; + +struct ws_fun_ops{ + int (*hostname_connect)(struct _wsclient_context *wsclient); + void (*client_close)(struct _wsclient_context *wsclient); + int (*client_send)(struct _wsclient_context *wsclient, unsigned char *data, size_t data_len); + int (*client_read)(struct _wsclient_context *wsclient, unsigned char *data, size_t data_len); + struct ssl_fun_ops ssl_fun_ops; +}; + +typedef struct _wsclient_context{ + char host[128]; + char path[128]; + char origin[200]; + int port; + uint8_t use_ssl; + int sockfd; + readyStateValues readyState; + int tx_len; + void *ssl; + uint8_t *txbuf; + uint8_t *rxbuf; + uint8_t *receivedData; + struct ws_fun_ops fun_ops; +}wsclient_context; +/*******************************************************************/ + +/****************General functions used by wsclient*****************/ +void ws_get_random_bytes(void *buf, size_t len); +void* ws_malloc(unsigned int size); +void ws_free(void *buf); +int ws_client_handshake(wsclient_context *wsclient); +int ws_check_handshake(wsclient_context *wsclient); +void ws_sendData(uint8_t type, size_t message_size, uint8_t* message, int useMask, wsclient_context *wsclient); +/*******************************************************************/ + +/*************Functions used by wsclient without SSL****************/ + +int ws_hostname_connect(wsclient_context *wsclient); +int ws_client_read(wsclient_context *wsclient, unsigned char *data, size_t data_len); +int ws_client_send(wsclient_context *wsclient, unsigned char *data, size_t data_len); +void ws_client_close(wsclient_context *wsclient); +/*******************************************************************/ + +/***************Functions used by wsclient with SSL*****************/ +int wss_hostname_connect(wsclient_context *wsclient); +int wss_client_read(wsclient_context *wsclient, unsigned char *data, size_t data_len); +int wss_client_send(wsclient_context *wsclient, unsigned char *data, size_t data_len); +void wss_client_close(wsclient_context *wsclient); +/*******************************************************************/ + +#endif diff --git a/USDK/component/common/network/websocket/wsclient_api.h b/USDK/component/common/network/websocket/wsclient_api.h new file mode 100644 index 0000000..77a53f1 --- /dev/null +++ b/USDK/component/common/network/websocket/wsclient_api.h @@ -0,0 +1,104 @@ +#ifndef WSCLIENT_H +#define WSCLIENT_H +#include + + +/******Define the maximum bytes of data send and receive********/ +#define MAX_DATA_LEN 1500 +/****************Define if using the polarssl*******************/ +#define USING_SSL + +/******************Define the function used*********************/ +#ifdef USING_SSL +int wss_set_fun_ops(wsclient_context *wsclient); +#define wsclient_set_fun_ops(wsclient) wss_set_fun_ops(wsclient) +#else +int ws_set_fun_ops(wsclient_context *wsclient); +#define wsclient_set_fun_ops(wsclient) ws_set_fun_ops(wsclient) +#endif +/***************************************************************/ + +/************************************************************************************************* +** Function Name : create_wsclient +** Description : Creating the websocket client context structure +** Input : url:websocket server's url +** port:websocket server's port, if not given, default 80 for "ws", 443 for "wss" +** origin: the address or url of your self +** Return : Created: websocket client context structure +** Failed: NULL +**************************************************************************************************/ +wsclient_context *create_wsclient(char *url, int port, char *path, char* origin); + +/************************************************************************************************* +** Function Name : ws_connect_url +** Description : Connecting to the websocket server +** Input : wsclient: the websocket client context created by create_wsclientfunction +** Return : Connected: the socket value +** Failed: -1 +**************************************************************************************************/ +int ws_connect_url(wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_send +** Description : Create the sending string data and copy to tx_buf +** Input : message: the string that send to server(cannot exceeding the MAX_DATA_LEN +** message_len: the length of the string +** use_mask: 0/1; 1 means using mask for bynary +** wsclient: the websocket client context +** Return : None +**************************************************************************************************/ +void ws_send(char* message, int message_len, int use_mask, wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_sendBinary +** Description : Create the sending binary data and copy to tx_buf +** Input : message: the binary that send to server(cannot exceeding the MAX_DATA_LEN +** message_len: the length of the binary +** use_mask: 0/1; 1 means using mask for bynary +** wsclient: the websocket client context +** Return : None +**************************************************************************************************/ +void ws_sendBinary(uint8_t* message, int message_len, int use_mask, wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_sendPing +** Description : Sending Ping to websocket server +** Input : wsclient: the websocket client context +** Return : None +**************************************************************************************************/ +void ws_sendPing(wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_poll +** Description : Receicing data from server and send the data in tx_buf +** Input : timeout(in milliseconds) + wsclient: the websocket client context +** Return : None +**************************************************************************************************/ +void ws_poll(int timeout, wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_dispatch +** Description : callback function when getting message from server +** Input : function that resolve the message received and the message length +** Return : None +**************************************************************************************************/ +void ws_dispatch(void (*callback)(wsclient_context *, int)) ; + +/************************************************************************************************* +** Function Name : ws_getReadyState +** Description : Getting the connection status +** Input : wsclient: the websocket client context +** Return : readyStateValues(4 types:CLOSING, CLOSED, CONNECTING, OPEN) +**************************************************************************************************/ +readyStateValues ws_getReadyState(wsclient_context *wsclient); + +/************************************************************************************************* +** Function Name : ws_close +** Description : Closing the connection with websocket server +** Input : wsclient: the websocket client context +** Return : None +**************************************************************************************************/ +void ws_close(wsclient_context *wsclient); + +#endif diff --git a/USDK/component/common/test/wlan/wlan_test_inc.h b/USDK/component/common/test/wlan/wlan_test_inc.h new file mode 100644 index 0000000..de1e156 --- /dev/null +++ b/USDK/component/common/test/wlan/wlan_test_inc.h @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------// +#ifndef __MAIN_TEST_H +#define __MAIN_TEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported test functions ------------------------------------------------------- */ +void do_ping_test(char *ip, int size, int count, int interval); +void do_ping_call(char *ip, int loop, int count); +void do_deinit_test(int mode, int ap_started); +void interactive_question(char *question, char *choice, char *buf, int buf_size); +void start_interactive_mode(void); +void post_init(unsigned int config_start_ap); + +#ifdef __cplusplus + } +#endif + +#endif // __MAIN_TEST_H + +//----------------------------------------------------------------------------// diff --git a/USDK/component/common/utilities/cJSON.c b/USDK/component/common/utilities/cJSON.c new file mode 100644 index 0000000..a13fbbd --- /dev/null +++ b/USDK/component/common/utilities/cJSON.c @@ -0,0 +1,596 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + +static const char *ep; + +const char *cJSON_GetErrorPtr(void) {return ep;} + +static int cJSON_strcasecmp(const char *s1,const char *s2) +{ + if (!s1) return (s1==s2)?0:1;if (!s2) return 1; + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; + return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + + len = strlen(str) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy,str,len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(void) +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node,0,sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (c->string) cJSON_free(c->string); + cJSON_free(c); + c=next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + if (*num=='-') sign=-1,num++; /* Has sign? */ + if (*num=='0') num++; /* is zero */ + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ + if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ + if (*num=='e' || *num=='E') /* Exponent? */ + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) + { + str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str,"%d",item->valueint); + } + else + { + str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); + else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else sprintf(str,"%f",d); + } + } + return str; +} + +static unsigned parse_hex4(const char *str) +{ + unsigned h=0; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; + if (*str!='\"') {ep=str;return 0;} /* not a string! */ + + while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': /* transcode utf16 to utf8. */ + uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ + + if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ + uc2=parse_hex4(ptr+3);ptr+=6; + if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ + uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); + } + + len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; + + switch (len) { + case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 =(uc | firstByteMark[len]); + } + ptr2+=len; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) +{ + const char *ptr;char *ptr2,*out;int len=0;unsigned char token; + + if (!str) return cJSON_strdup(""); + ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} + + out=(char*)cJSON_malloc(len+3); + if (!out) return 0; + + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth,int fmt); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth,int fmt); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth,int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} + +/* Parse an object - create a new root, and populate. */ +cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) +{ + const char *end=0; + cJSON *c=cJSON_New_Item(); + ep=0; + if (!c) return 0; /* memory fail */ + + end=parse_value(c,skip(value)); + if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} + if (return_parse_end) *return_parse_end=end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} + +/* Render a cJSON item/entity/structure to text. */ +char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} +char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + ep=value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item,int depth,int fmt) +{ + char *out=0; + if (!item) return 0; + switch ((item->type)&255) + { + case cJSON_NULL: out=cJSON_strdup("null"); break; + case cJSON_False: out=cJSON_strdup("false");break; + case cJSON_True: out=cJSON_strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth,fmt);break; + case cJSON_Object: out=print_object(item,depth,fmt);break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') {ep=value;return 0;} /* not an array! */ + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + if (!value) return 0; /* memory fail */ + } + + if (*value==']') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item,int depth,int fmt) +{ + char **entries; + char *out=0,*ptr,*ret;int len=5; + cJSON *child=item->child; + int numentries=0,i=0,fail=0; + + /* How many entries in the array? */ + while (child) numentries++,child=child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + out=(char*)cJSON_malloc(3); + if (out) strcpy(out,"[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + memset(entries,0,numentries*sizeof(char*)); + /* Retrieve all the results: */ + child=item->child; + while (child && !fail) + { + ret=print_value(child,depth+1,fmt); + entries[i++]=ret; + if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; + child=child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail=1; + + /* Handle failure. */ + if (fail) + { + for (i=0;itype=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; + value=skip(parse_string(child,skip(value))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value=='}') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item,int depth,int fmt) +{ + char **entries=0,**names=0; + char *out=0,*ptr,*ret,*str;int len=7,i=0,j; + cJSON *child=item->child; + int numentries=0,fail=0; + /* Count the number of entries. */ + while (child) numentries++,child=child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + out=(char*)cJSON_malloc(fmt?depth+4:3); + if (!out) return 0; + ptr=out;*ptr++='{'; + if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; + while (child) + { + names[i]=str=print_string_ptr(child->string); + entries[i++]=ret=print_value(child,depth,fmt); + if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; + child=child->next; + } + + /* Try to allocate the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + if (!out) fail=1; + + /* Handle failure */ + if (fail) + { + for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} +void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} + +cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; + if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} +void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} +void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} + +/* Replace array/object items with new ones. */ +void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; + newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; + if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} +void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){if(newitem->string) cJSON_free(newitem->string);newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} + +/* Create basic types: */ +cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} +cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} +cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} +cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} + +/* Create Arrays: */ +cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} + +/* Duplication */ +cJSON *cJSON_Duplicate(cJSON *item,int recurse) +{ + cJSON *newitem,*cptr,*nptr=0,*newchild; + /* Bail on bad ptr */ + if (!item) return 0; + /* Create new item */ + newitem=cJSON_New_Item(); + if (!newitem) return 0; + /* Copy over all vars */ + newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; + if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} + if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} + /* If non-recursive, then we're done! */ + if (!recurse) return newitem; + /* Walk the ->next chain for the child. */ + cptr=item->child; + while (cptr) + { + newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) {cJSON_Delete(newitem);return 0;} + if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ + cptr=cptr->next; + } + return newitem; +} + +void cJSON_Minify(char *json) +{ + char *into=json; + while (*json) + { + if (*json==' ') json++; + else if (*json=='\t') json++; // Whitespace characters. + else if (*json=='\r') json++; + else if (*json=='\n') json++; + else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line. + else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments. + else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive. + else *into++=*json++; // All other characters. + } + *into=0; // and null-terminate. +} diff --git a/USDK/component/common/utilities/cJSON.h b/USDK/component/common/utilities/cJSON.h new file mode 100644 index 0000000..0d886d6 --- /dev/null +++ b/USDK/component/common/utilities/cJSON.h @@ -0,0 +1,145 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks* hooks); + + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(void); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); +extern void cJSON_DeleteItemFromArray(cJSON *array,int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); + +extern void cJSON_Minify(char *json); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/common/utilities/http_client.c b/USDK/component/common/utilities/http_client.c new file mode 100644 index 0000000..44a082d --- /dev/null +++ b/USDK/component/common/utilities/http_client.c @@ -0,0 +1,137 @@ +//#include +//#include +//#include + +#include "platform/platform_stdlib.h" + +#include "FreeRTOS.h" + +const char * http_strstr(const char *str1, const char *str2) { + char *a, *b; + + /* First scan quickly through the two strings looking for a + * single-character match. When it's found, then compare the + * rest of the substring. + */ + + b = (char *)str2; + if (*b == 0) { + return str1; + } + for ( ; *str1 != 0; str1 += 1) { + if (*str1 != *b) { + continue; + } + a = (char *)str1; + while (1) { + if (*b == 0) { + return str1; + } + if (*a++ != *b++) { + break; + } + } + b = (char *)str2; + } + return (char *) 0; +} + +static void* http_malloc(unsigned int size) +{ + return pvPortMalloc(size); +} + +void http_free(void *buf) +{ + vPortFree(buf); +} + +static char *http_itoa(int value) +{ + char *val_str; + int tmp = value, len = 1; + + while((tmp /= 10) > 0) + len ++; + + val_str = (char *) http_malloc(len + 1); + sprintf(val_str, "%d", value); + + return val_str; +} + +char *http_post_header(char *host, char *resource, char *type, int data_len) +{ + char *len_str = http_itoa(data_len); + char *header = (char *) http_malloc(strlen("POST ") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ") + strlen(host) + + strlen("\r\nContent-Type: ") + strlen(type) + strlen("\r\nContent-Length: ") + strlen(len_str) + strlen("\r\n\r\n") + 1); + sprintf(header, "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n", resource, host, type, len_str); + http_free(len_str); + + return header; +} + +char *http_get_header(char *host, char *resource) +{ + char *header = (char *) http_malloc(strlen("GET ") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ") + strlen(host) + strlen("\r\n\r\n") + 1); + sprintf(header, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", resource, host); + + return header; +} + +char *http_response_header(char *buf, int response_len) +{ + char *http_response, *http_header = NULL, *header_end; + int header_len; + + http_response = (char *) http_malloc(response_len + 1); + memcpy(http_response, buf, response_len); + http_response[response_len] = '\0'; + + if(strncmp(http_response, "HTTP", 4) == 0) { + if((header_end = (char *)http_strstr(http_response, "\r\n\r\n")) != NULL) { + header_end += 4; + header_len = header_end - http_response; + http_header = (char *) http_malloc(header_len + 1); + memcpy(http_header, http_response, header_len); + http_header[header_len] = '\0'; + } + } + + http_free(http_response); + + return http_header; +} + +char *http_response_body(char *buf, int response_len) +{ + char *http_response, *http_body = NULL, *body_start; + int body_len; + + http_response = (char *) http_malloc(response_len + 1); + memcpy(http_response, buf, response_len); + http_response[response_len] = '\0'; + + if(strncmp(http_response, "HTTP", 4) == 0) { + if((body_start = (char *)http_strstr(http_response, "\r\n\r\n")) != NULL) { + body_start += 4; + body_len = http_response + response_len - body_start; + + if(body_len > 0) { + http_body = (char *) http_malloc(body_len + 1); + memcpy(http_body, body_start, body_len); + http_body[body_len] = '\0'; + } + + http_free(http_response); + } + else { + http_body = http_response; + } + } + else { + http_body = http_response; + } + + return http_body; +} diff --git a/USDK/component/common/utilities/http_client.h b/USDK/component/common/utilities/http_client.h new file mode 100644 index 0000000..8955188 --- /dev/null +++ b/USDK/component/common/utilities/http_client.h @@ -0,0 +1,10 @@ +#ifndef _HTTP_H_ +#define _HTTP_H_ + +char *http_post_header(char *address, char *resource, char *type, int data_len); +char *http_get_header(char *address, char *resource); +char *http_response_header(char *buf, int response_len); +char *http_response_body(char *buf, int response_len); +void http_free(void *buf); + +#endif diff --git a/USDK/component/common/utilities/ssl_client.c b/USDK/component/common/utilities/ssl_client.c new file mode 100644 index 0000000..a2faa1d --- /dev/null +++ b/USDK/component/common/utilities/ssl_client.c @@ -0,0 +1,248 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "polarssl/config.h" +#include "platform_opts.h" + +#if CONFIG_SSL_CLIENT + +#include +#include + +#include "polarssl/net.h" +#include "polarssl/ssl.h" +#include "polarssl/error.h" +#include "polarssl/memory.h" + +#define SERVER_PORT 443 +#define SERVER_HOST "192.168.13.15" +#define GET_REQUEST "GET / HTTP/1.0\r\n\r\n" +#define DEBUG_LEVEL 0 + +//#define SSL_CLIENT_EXT +#ifdef SSL_CLIENT_EXT +#define STACKSIZE 2048 +#else +#define STACKSIZE 1150 +#endif + +static int is_task = 0; +static char server_host[16]; +static size_t min_heap_size = 0; + +static void my_debug(void *ctx, int level, const char *str) +{ + if(level <= DEBUG_LEVEL) { + printf("\n\r%s", str); + } +} + +static int my_random(void *p_rng, unsigned char *output, size_t output_len) +{ + rtw_get_random_bytes(output, output_len); + return 0; +} + +void* my_malloc(size_t size) +{ + void *ptr = pvPortMalloc(size); + size_t current_heap_size = xPortGetFreeHeapSize(); + + if((current_heap_size < min_heap_size) || (min_heap_size == 0)) + min_heap_size = current_heap_size; + + return ptr; +} + +#define my_free vPortFree + +static void ssl_client(void *param) +{ + int ret, len, server_fd = -1; + unsigned char buf[512]; + ssl_context ssl; + int retry_count = 0; + + memory_set_own(my_malloc, my_free); + + /* + * 1. Start the connection + */ + printf(" . Connecting to tcp/%s/%d...\n", server_host, SERVER_PORT); + + if((ret = net_connect(&server_fd, server_host, SERVER_PORT)) != 0) { + printf(" failed\n ! net_connect returned %d\n", ret); + goto exit1; + } + + printf(" ok\n"); + + /* + * 2. Setup stuff + */ + printf(" . Setting up the SSL/TLS structure...\n" ); + + if((ret = ssl_init(&ssl)) != 0) { + printf(" failed\n ! ssl_init returned %d\n", ret); + goto exit; + } +#ifdef SSL_CLIENT_EXT + if((ret = ssl_client_ext_init()) != 0) { + printf(" failed\n ! ssl_client_ext_init returned %d\n", ret); + goto exit; + } +#endif + ssl_set_endpoint(&ssl, SSL_IS_CLIENT); + ssl_set_authmode(&ssl, SSL_VERIFY_NONE); + ssl_set_rng(&ssl, my_random, NULL); + ssl_set_bio(&ssl, net_recv, &server_fd, net_send, &server_fd); + ssl_set_dbg(&ssl, my_debug, NULL); +#ifdef POLARSSL_DEBUG_C + debug_set_threshold(DEBUG_LEVEL); +#endif +#ifdef SSL_CLIENT_EXT + if((ret = ssl_client_ext_setup(&ssl)) != 0) { + printf(" failed\n ! ssl_client_ext_setup returned %d\n", ret); + goto exit; + } +#endif + + printf(" ok\n"); + + /* + * 3. Handshake + */ + printf(" . Performing the SSL/TLS handshake...\n"); + + while((ret = ssl_handshake(&ssl)) != 0) { + if((ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE + && ret != POLARSSL_ERR_NET_RECV_FAILED) || retry_count >= 5) { + printf(" failed\n ! ssl_handshake returned -0x%x\n", -ret); + goto exit; + } + retry_count++; + } + + printf(" ok\n"); + printf(" . Use ciphersuite %s\n", ssl_get_ciphersuite(&ssl)); + + /* + * 4. Write the GET request + */ + printf(" > Write to server:\n"); + + len = sprintf((char *) buf, GET_REQUEST); + + while((ret = ssl_write(&ssl, buf, len)) <= 0) { + if(ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE) { + printf(" failed\n ! ssl_write returned %d\n", ret); + goto exit; + } + } + + len = ret; + printf(" %d bytes written\n%s\n", len, (char *) buf); + + /* + * 5. Read the HTTP response + */ + printf(" < Read from server:"); + + do { + len = sizeof(buf) - 1; + memset(buf, 0, sizeof(buf)); + ret = ssl_read(&ssl, buf, len); + + if(ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE) + continue; + + if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) + break; + + if(ret < 0) { + printf(" failed\n ! ssl_read returned %d\n", ret); + break; + } + + if(ret == 0) { + printf("EOF\n"); + break; + } + + len = ret; + printf(" %d bytes read\n%s\n", len, (char *) buf); + } + while(1); + + ssl_close_notify(&ssl); + +exit: + +#ifdef POLARSSL_ERROR_C + if(ret != 0) { + char error_buf[100]; + polarssl_strerror(ret, error_buf, 100); + printf("\nLast error was: %d - %s\n", ret, error_buf); + } +#endif + + net_close(server_fd); + ssl_free(&ssl); +#ifdef SSL_CLIENT_EXT + ssl_client_ext_free(); +#endif +exit1: + + if(is_task) { +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("\nMin available stack size of %s = %d * %d bytes\n", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + + if(min_heap_size > 0) + printf("\nMin available heap size = %d bytes during %s\n", min_heap_size, __FUNCTION__); + + vTaskDelete(NULL); + } + + if(param != NULL) + *((int *) param) = ret; +} + +void start_ssl_client(void) +{ + is_task = 1; + //strcpy(server_host, SERVER_HOST); + + if(xTaskCreate(ssl_client, "ssl_client", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("%s xTaskCreate failed\n", __FUNCTION__); +} + +void do_ssl_connect(void) +{ + int ret; + static int success = 0; + static int fail = 0; + + is_task = 0; + strcpy(server_host, SERVER_HOST); + ssl_client(&ret); + + if(ret != 0) + printf("%s fail (success %d times, fail %d times)\n", __FUNCTION__, success, ++ fail); + else + printf("%s success (success %d times, fail %d times)\n", __FUNCTION__, ++ success, fail); +} + +void cmd_ssl_client(int argc, char **argv) +{ + if(argc == 2) { + strcpy(server_host, argv[1]); + } + else { + printf("Usage: %s SSL_SERVER_HOST\n", argv[0]); + return; + } + + start_ssl_client(); +} + +#endif // #if CONFIG_SSL_CLIENT diff --git a/USDK/component/common/utilities/ssl_client_ext.c b/USDK/component/common/utilities/ssl_client_ext.c new file mode 100644 index 0000000..2e3c44d --- /dev/null +++ b/USDK/component/common/utilities/ssl_client_ext.c @@ -0,0 +1,184 @@ +#include +#include +#include "platform_opts.h" + +#if CONFIG_SSL_CLIENT +//#define SSL_VERIFY_CLIENT +//#define SSL_VERIFY_SERVER + +#ifdef SSL_VERIFY_CLIENT +static x509_crt* _cli_crt = NULL; +static pk_context* _clikey_rsa = NULL; + +static const char *test_client_key = \ +"-----BEGIN RSA PRIVATE KEY-----\r\n" \ +"MIICXgIBAAKBgQDKLbkPtV0uhoqkHxHl/sZlq5TrUqu6pScqGkMnEUDKIFR5QMNf\r\n" \ +"qLgbGPwbreN4AkHQlvqnn/2Swz1uurUH4pxcGp54j7QmANXvd5hJtCMhPpDcPS6k\r\n" \ +"ldlIJ8y3KoCoqAot6uo9IL/IKKk3aOQqeHKayIyjOOksjMkgeE8/gCpmFQIDAQAB\r\n" \ +"AoGBAKoSBj+Bh83wXUWr4SmAxLGXwSCnHVBXRveyudRuPfsJcSXCZdbdHWml/cTm\r\n" \ +"5Jb6BxUJO/avreW8GLxBkLD+XhnXlkw1RJ8FYZPXdzlNJzoYyVK0GZ/qyGacEEFt\r\n" \ +"ekvGfBJIq+7ksKcJt5c9qARClOvauYLRGwubl64xD6PupSINAkEA+5C395h227nc\r\n" \ +"5zF8s2rYBP78i5uS7hKqqVjGy8pcIFHiM/0ehzcN3V3gJXLjkAbXfvP0h/tm8eQG\r\n" \ +"QUpJBY/YLwJBAM2+IOfTmEBxrpASUeN1Lx9yg0+Swyz8oz2a2blfFwbpCWBi18M2\r\n" \ +"huo+YECeMggqBBYwgQ9J2ixpaj/e9+0pkPsCQQDztTWkFf4/y4WoLBcEseNoo6YB\r\n" \ +"kcv7+/V9bdXZI8ewP+OGPhdPIxS5efJmFTFEHHy0Lp6dBf6rJB6zLcYkL0BdAkEA\r\n" \ +"nGBqeknlavX9DBwgiZXD308WZyDRoBvVpzlPSwnvYp01N0FpZULIgLowRmz28iWd\r\n" \ +"PZBYR9qGLUNiMnGyV1xEiQJAOdlBM4M9Xj2Z9inCdkgFkbIOSe5kvIPC24CjZyyG\r\n" \ +"g3lK/YezoDmdD//OLoY81y6VdO5dwjm7P0wZB63EDRidHA==\r\n" \ +"-----END RSA PRIVATE KEY-----\r\n"; + +static const char *test_client_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIC4DCCAkmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB7MQswCQYDVQQGEwJDTjEL\r\n" \ +"MAkGA1UECAwCSlMxCzAJBgNVBAcMAlNaMRAwDgYDVQQKDAdSZWFsc2lsMRAwDgYD\r\n" \ +"VQQLDAdSZWFsdGVrMRAwDgYDVQQDDAdSZWFsc2lsMRwwGgYJKoZIhvcNAQkBFg1h\r\n" \ +"QHJlYWxzaWwuY29tMB4XDTE1MTIyMzA2NTI0MFoXDTE2MTIyMjA2NTI0MFowdDEL\r\n" \ +"MAkGA1UEBhMCQ04xCzAJBgNVBAgMAkpTMRAwDgYDVQQKDAdSZWFsc2lsMRAwDgYD\r\n" \ +"VQQLDAdSZWFsdGVrMRYwFAYDVQQDDA0xOTIuMTY4LjEuMTQxMRwwGgYJKoZIhvcN\r\n" \ +"AQkBFg1jQHJlYWxzaWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK\r\n" \ +"LbkPtV0uhoqkHxHl/sZlq5TrUqu6pScqGkMnEUDKIFR5QMNfqLgbGPwbreN4AkHQ\r\n" \ +"lvqnn/2Swz1uurUH4pxcGp54j7QmANXvd5hJtCMhPpDcPS6kldlIJ8y3KoCoqAot\r\n" \ +"6uo9IL/IKKk3aOQqeHKayIyjOOksjMkgeE8/gCpmFQIDAQABo3sweTAJBgNVHRME\r\n" \ +"AjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0\r\n" \ +"ZTAdBgNVHQ4EFgQUJLmwJNyKHCTEspNTPNpbPjXkjnQwHwYDVR0jBBgwFoAUAfLa\r\n" \ +"cSF933h+3pYNcs36lvm7yEkwDQYJKoZIhvcNAQELBQADgYEAlo495gu94nMHFYx4\r\n" \ +"+V7PjwGIqanqwLjsem9qvwJa/K1QoM4JxnqRXFUdSfZMhnlrMgPer4fDHpWAutWB\r\n" \ +"X2Fiww+VVJSn8Go0seK8RQf8n/n3rJ5B3lef1Po2zHchELWhlFT6k5Won7gp64RN\r\n" \ +"9PcwFFy0Va/bkJsot//kdZNKs/g=\r\n" \ +"-----END CERTIFICATE-----\r\n"; +#endif + +#ifdef SSL_VERIFY_SERVER +static x509_crt* _ca_crt = NULL; + +static const char *test_ca_cert = \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIICxDCCAi2gAwIBAgIJANdeY8UOfqpBMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNV\r\n" \ +"BAYTAkNOMQswCQYDVQQIDAJKUzELMAkGA1UEBwwCU1oxEDAOBgNVBAoMB1JlYWxz\r\n" \ +"aWwxEDAOBgNVBAsMB1JlYWx0ZWsxEDAOBgNVBAMMB1JlYWxzaWwxHDAaBgkqhkiG\r\n" \ +"9w0BCQEWDWFAcmVhbHNpbC5jb20wHhcNMTUxMjIzMDYzMDA1WhcNMTYxMjIyMDYz\r\n" \ +"MDA1WjB7MQswCQYDVQQGEwJDTjELMAkGA1UECAwCSlMxCzAJBgNVBAcMAlNaMRAw\r\n" \ +"DgYDVQQKDAdSZWFsc2lsMRAwDgYDVQQLDAdSZWFsdGVrMRAwDgYDVQQDDAdSZWFs\r\n" \ +"c2lsMRwwGgYJKoZIhvcNAQkBFg1hQHJlYWxzaWwuY29tMIGfMA0GCSqGSIb3DQEB\r\n" \ +"AQUAA4GNADCBiQKBgQCmfNpluJZP0Sla+MIYzRGA1rljK5VncuBKQiKBF4BdO73H\r\n" \ +"OTUoT0ydR7x7lS2Ns1HQop2oldroJVBj38+pLci1i/3flkONCDfsWOzfcGZ9RItq\r\n" \ +"Zf9eQI8CEZI5i0Fvi3mgaoqCXvutFBrtTQRNsKQD69SqxEWWPb1y+Fd2nONeawID\r\n" \ +"AQABo1AwTjAdBgNVHQ4EFgQUAfLacSF933h+3pYNcs36lvm7yEkwHwYDVR0jBBgw\r\n" \ +"FoAUAfLacSF933h+3pYNcs36lvm7yEkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\r\n" \ +"AQsFAAOBgQA6McwC1Vk4k/5Bh/sf9cfwSK9A0ecaIH0NizYoWpWRAsv7TDgj0PbO\r\n" \ +"Qqxi/QhpuYezgRqKqAv7QYNSQa39X7opzSsdSGtTnId374PZZeCDqZpfcAbsNk5o\r\n" \ +"6HLpJ27esFa/flTL0FtmO+AT2uiPMvRP0a4u4uuLQK2Jgm/CmzJ47w==\r\n" \ +"-----END CERTIFICATE-----\r\n"; + +static int my_verify(void *data, x509_crt *crt, int depth, int *flags) +{ + char buf[1024]; + ((void) data); + + printf("Verify requested for (Depth %d):\n", depth); + x509_crt_info(buf, sizeof(buf) - 1, "", crt); + printf("%s", buf); + + if(((*flags) & BADCERT_EXPIRED) != 0) + printf("server certificate has expired\n"); + + if(((*flags) & BADCERT_REVOKED) != 0) + printf(" ! server certificate has been revoked\n"); + + if(((*flags) & BADCERT_CN_MISMATCH) != 0) + printf(" ! CN mismatch\n"); + + if(((*flags) & BADCERT_NOT_TRUSTED) != 0) + printf(" ! self-signed or not signed by a trusted CA\n"); + + if(((*flags) & BADCRL_NOT_TRUSTED) != 0) + printf(" ! CRL not trusted\n"); + + if(((*flags) & BADCRL_EXPIRED) != 0) + printf(" ! CRL expired\n"); + + if(((*flags) & BADCERT_OTHER) != 0) + printf(" ! other (unknown) flag\n"); + + if((*flags) == 0) + printf(" Certificate verified without error flags\n"); + + return(0); +} +#endif + +int ssl_client_ext_init(void) +{ +#ifdef SSL_VERIFY_CLIENT + _cli_crt = polarssl_malloc(sizeof(x509_crt)); + + if(_cli_crt) + x509_crt_init(_cli_crt); + else + return -1; + + _clikey_rsa = polarssl_malloc(sizeof(pk_context)); + + if(_clikey_rsa) + pk_init(_clikey_rsa); + else + return -1; +#endif +#ifdef SSL_VERIFY_SERVER + _ca_crt = polarssl_malloc(sizeof(x509_crt)); + + if(_ca_crt) + x509_crt_init(_ca_crt); + else + return -1; +#endif + return 0; +} + +void ssl_client_ext_free(void) +{ +#ifdef SSL_VERIFY_CLIENT + if(_cli_crt) { + x509_crt_free(_cli_crt); + polarssl_free(_cli_crt); + _cli_crt = NULL; + } + + if(_clikey_rsa) { + pk_free(_clikey_rsa); + polarssl_free(_clikey_rsa); + _clikey_rsa = NULL; + } +#endif +#ifdef SSL_VERIFY_SERVER + if(_ca_crt) { + x509_crt_free(_ca_crt); + polarssl_free(_ca_crt); + _ca_crt = NULL; + } +#endif +} + +int ssl_client_ext_setup(ssl_context *ssl) +{ +#ifdef SSL_VERIFY_CLIENT + if(x509_crt_parse(_cli_crt, test_client_cert, strlen(test_client_cert)) != 0) + return -1; + + if(pk_parse_key(_clikey_rsa, test_client_key, strlen(test_client_key), NULL, 0) != 0) + return -1; + + ssl_set_own_cert(ssl, _cli_crt, _clikey_rsa); +#endif +#ifdef SSL_VERIFY_SERVER + if(x509_crt_parse(_ca_crt, test_ca_cert, strlen(test_ca_cert)) != 0) + return -1; + + ssl_set_ca_chain(ssl, _ca_crt, NULL, NULL); + ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED); + ssl_set_verify(ssl, my_verify, NULL); +#endif + return 0; +} + +#endif //#if CONFIG_SSL_CLIENT diff --git a/USDK/component/common/utilities/tcpecho.c b/USDK/component/common/utilities/tcpecho.c new file mode 100644 index 0000000..f3ef233 --- /dev/null +++ b/USDK/component/common/utilities/tcpecho.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#include "lwip/opt.h" + +#if LWIP_NETCONN + +#include "lwip/sys.h" +#include "lwip/api.h" + +#define TCPECHO_THREAD_PRIO ( tskIDLE_PRIORITY + 3 ) + + + +/*-----------------------------------------------------------------------------------*/ +static void tcpecho_thread(void *arg) +{ + struct netconn *conn, *newconn; + err_t err; + + LWIP_UNUSED_ARG(arg); + + /* Create a new connection identifier. */ + conn = netconn_new(NETCONN_TCP); + + if (conn!=NULL) + { + /* Bind connection to well known port number 7. */ + err = netconn_bind(conn, NULL, 7); + + if (err == ERR_OK) + { + /* Tell connection to go into listening mode. */ + netconn_listen(conn); + + while (1) + { + /* Grab new connection. */ + newconn = netconn_accept(conn); + + /* Process the new connection. */ + if (newconn) + { + struct netbuf *buf; + void *data; + u16_t len; + + while ((buf = netconn_recv(newconn)) != NULL) + { + do + { + netbuf_data(buf, &data, &len); + netconn_write(newconn, data, len, NETCONN_COPY); + + } + while (netbuf_next(buf) >= 0); + + netbuf_delete(buf); + } + + /* Close connection and discard connection identifier. */ + netconn_close(newconn); + netconn_delete(newconn); + } + } + } + else + { + printf(" can not bind TCP netconn"); + } + } + else + { + printf("can not create TCP netconn"); + } +} +/*-----------------------------------------------------------------------------------*/ + +void tcpecho_init(void) +{ + sys_thread_new("tcpecho", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO); +} +/*-----------------------------------------------------------------------------------*/ + +void cmd_tcpecho(int argc, char **argv) +{ + printf("\n\rInit TCP ECHO Server ..."); + tcpecho_init(); + printf("\n\r\nPlease use echotool to connect to this echo server. ex. echotool 192.168.0.1 /p tcp /r 7 /n 0"); +} +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/utilities/tcptest.c b/USDK/component/common/utilities/tcptest.c new file mode 100644 index 0000000..053ce30 --- /dev/null +++ b/USDK/component/common/utilities/tcptest.c @@ -0,0 +1,938 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "main.h" + +#if CONFIG_BSD_TCP + +#include +#if LWIP_SOCKET +#include +#include +#include +#include + +#include "wifi_util.h" + +#define PER_SECOND_REPORT 1 +#define BSD_STACK_SIZE 2048 +#define DEFAULT_PORT 5001 +#define DEFAULT_TIME 10 +#define SERVER_BUF_SIZE 1500 +#define CLIENT_BUF_SIZE 1460 +#define KB 1024 +#define MB 1048576//1024*1024 +#define DEFAULT_TCP_BANDWIDTH 131072 //128*1024Bytes = 1Mbits +#define DEFAULT_UDP_BANDWIDTH 131072 //128*1024Bytes = 1Mbits +#define DEFAULT_UDP_TOS_VALUE 96 // BE=96 + + +struct iperf_data_t{ + char server_ip[16]; + int server_fd; + int client_fd; + uint16_t port; + unsigned char start; + unsigned int buf_size; + uint32_t time; + uint64_t total_size; + uint64_t bandwidth; + uint8_t tos_value; +}; + +struct iperf_data_t tcp_server_data,tcp_client_data,udp_server_data,udp_client_data; + +xTaskHandle g_tcp_server_task = NULL; +xTaskHandle g_tcp_client_task = NULL; +xTaskHandle g_udp_client_task = NULL; +xTaskHandle g_udp_server_task = NULL; +unsigned char g_tcp_terminate = 0; +unsigned char g_udp_terminate = 0; + +int tcp_client_func(struct iperf_data_t iperf_data) +{ + struct sockaddr_in ser_addr; + char *buffer = NULL; + int i=0; + uint32_t start_time, end_time, report_start_time; + uint64_t total_size=0,report_size=0; + + buffer = pvPortMalloc(iperf_data.buf_size); + if(!buffer){ + printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); + goto Exit2; + } + //filling the buffer + for (i = 0; i < iperf_data.buf_size; i++){ + buffer[i] = (char)(i % 10); + } + + //create socket + if( (iperf_data.client_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ + printf("\n\r[ERROR] %s: Create TCP socket failed",__func__); + goto Exit2; + } + + //initialize value in dest + memset(&ser_addr, 0, sizeof(ser_addr)); + ser_addr.sin_family = AF_INET; + ser_addr.sin_port = htons(iperf_data.port); + ser_addr.sin_addr.s_addr = inet_addr(iperf_data.server_ip); + + printf("\n\r%s: Server IP=%s, port=%d", __func__,iperf_data.server_ip, iperf_data.port); + printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.client_fd); + + //Connecting to server + if( connect(iperf_data.client_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ + printf("\n\r[ERROR] %s: Connect to server failed",__func__); + goto Exit1; + } + printf("\n\r%s: Connect to server successfully",__func__); + if(iperf_data.total_size == 0){ + start_time = xTaskGetTickCount(); + end_time = start_time; + report_start_time = start_time; + while ( ((end_time - start_time) <= (configTICK_RATE_HZ * iperf_data.time)) && (!g_tcp_terminate) ) { + if( send(iperf_data.client_fd, buffer, iperf_data.buf_size,0) <= 0){ + printf("\n\r[ERROR] %s: TCP client send data error",__func__); + goto Exit1; + } + total_size+=iperf_data.buf_size; + report_size+=iperf_data.buf_size; + end_time = xTaskGetTickCount(); + if(((end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); +#endif + report_start_time = end_time; + report_size = 0; + } + else if( (iperf_data.bandwidth!=0) && (report_size >= iperf_data.bandwidth) ){ + while((end_time - report_start_time) < configTICK_RATE_HZ){ + end_time = xTaskGetTickCount(); + } +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); +#endif + report_start_time = end_time; + report_size = 0; + } + } + } + else{ + start_time = xTaskGetTickCount(); + end_time = start_time; + report_start_time = start_time; + while ( (total_size < iperf_data.total_size) && (!g_tcp_terminate) ) { + if( send(iperf_data.client_fd, buffer, iperf_data.buf_size,0) <= 0){ + printf("\n\r[ERROR] %s: TCP client send data error",__func__); + goto Exit1; + } + total_size+=iperf_data.buf_size; + report_size+=iperf_data.buf_size; + end_time = xTaskGetTickCount(); + if(((end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); +#endif + report_start_time = end_time; + report_size = 0; + } + else if( (iperf_data.bandwidth!=0) && (report_size >= iperf_data.bandwidth) ){ + while((end_time - report_start_time) < configTICK_RATE_HZ){ + end_time = xTaskGetTickCount(); + } +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(report_size/KB),(uint32_t)(end_time-report_start_time),((uint32_t)(report_size*8)/(end_time - report_start_time))); +#endif + report_start_time = end_time; + report_size = 0; + } + } + } + printf("\n\r%s: [END] Totally send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(total_size/KB),(uint32_t)(end_time-start_time),((uint32_t)(total_size*8)/(end_time - start_time))); + +Exit1: + closesocket(iperf_data.client_fd); +Exit2: + printf("\n\r%s: Close client socket",__func__); + if(buffer) + vPortFree(buffer); + return 0; +} + +int tcp_server_func(struct iperf_data_t iperf_data) +{ + struct sockaddr_in ser_addr , client_addr; + char *buffer = NULL; + int addrlen = sizeof(struct sockaddr_in); + int n = 1; + int recv_size=0; + uint64_t total_size=0,report_size=0; + uint32_t start_time, report_start_time, report_end_time; + + buffer = pvPortMalloc(iperf_data.buf_size); + if(!buffer){ + printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); + goto Exit3; + } + + //create socket + if((iperf_data.server_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ + printf("\n\r[ERROR] %s: Create socket failed",__func__); + goto Exit3; + } + + printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.server_fd); + + setsockopt( iperf_data.server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); + + //initialize structure dest + memset(&ser_addr, 0, sizeof(ser_addr)); + ser_addr.sin_family = AF_INET; + ser_addr.sin_port = htons(iperf_data.port); + ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + // binding the TCP socket to the TCP server address + if( bind(iperf_data.server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ + printf("\n\r[ERROR] %s: Bind socket failed",__func__); + goto Exit2; + } + printf("\n\r%s: Bind socket successfully",__func__); + + //Make it listen to socket with max 20 connections + if( listen(iperf_data.server_fd, 20) != 0){ + printf("\n\r[ERROR] %s: Listen socket failed",__func__); + goto Exit2; + } + printf("\n\r%s: Listen port %d",__func__,iperf_data.port); + +Restart: + if( (iperf_data.client_fd = accept(iperf_data.server_fd, (struct sockaddr*)&client_addr, &addrlen)) < 0){ + printf("\n\r[ERROR] %s: Accept TCP client socket error!",__func__); + goto Exit2; + } + printf("\n\r%s: Accept connection successfully",__func__); + + start_time = xTaskGetTickCount(); + report_start_time = start_time; + while (!g_tcp_terminate) { + recv_size = recv(iperf_data.client_fd, buffer, iperf_data.buf_size, 0); //MSG_DONTWAIT MSG_WAITALL + if( recv_size < 0){ + printf("\n\r[ERROR] %s: Receive data failed",__func__); + goto Exit1; + } + else if(recv_size == 0){ + printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (total_size/KB),(uint32_t) (report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); + total_size=0; + close(iperf_data.client_fd); + goto Restart; + } + report_end_time = xTaskGetTickCount(); + total_size+=recv_size; + report_size+=recv_size; + if(((report_end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((report_end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { +#if PER_SECOND_REPORT + printf("\n\r%s: Receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (report_size/KB),(uint32_t) (report_end_time-report_start_time),((uint32_t)(report_size*8)/(report_end_time - report_start_time))); +#endif + report_start_time = report_end_time; + report_size = 0; + } + else if((report_end_time - report_start_time) > (configTICK_RATE_HZ * 2)){ + report_start_time = report_end_time; + start_time = report_end_time; + report_size = 0; + } + } + printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t) (total_size/KB),(uint32_t) (report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); + +Exit1: + // close the connected socket after receiving from connected TCP client + close(iperf_data.client_fd); + +Exit2: + // close the listening socket + close(iperf_data.server_fd); + +Exit3: + if(buffer) + vPortFree(buffer); + return 0; +} + +int udp_client_func(struct iperf_data_t iperf_data) +{ + struct sockaddr_in ser_addr; + char *buffer = NULL; + int i=0; + int addrlen = sizeof(struct sockaddr_in); + uint32_t start_time, end_time, bandwidth_time; + uint64_t total_size=0, bandwidth_size=0; + + + buffer = pvPortMalloc(iperf_data.buf_size); + if(!buffer){ + printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); + goto Exit2; + } + + //filling the buffer + for (i = 0; i < iperf_data.buf_size; i++){ + buffer[i] = (char)(i % 10); + } + + //create socket + if( (iperf_data.client_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ + printf("\n\r[ERROR] %s: Create UDP socket failed",__func__); + goto Exit2; + } + + //initialize value in dest + memset(&ser_addr, 0, sizeof(ser_addr)); + ser_addr.sin_family = AF_INET; + ser_addr.sin_port = htons(iperf_data.port); + ser_addr.sin_addr.s_addr = inet_addr(iperf_data.server_ip); + + printf("\n\r%s: Server IP=%s, port=%d", __func__,iperf_data.server_ip, iperf_data.port); + printf("\n\r%s: Create socket fd = %d", __func__,iperf_data.client_fd); + + lwip_setsockopt(iperf_data.client_fd,IPPROTO_IP,IP_TOS,&iperf_data.tos_value,sizeof(iperf_data.tos_value)); + + if(iperf_data.total_size == 0){ + start_time = xTaskGetTickCount(); + end_time = start_time; + bandwidth_time = start_time; + while ( ((end_time - start_time) <= (configTICK_RATE_HZ * iperf_data.time)) && (!g_udp_terminate) ) { + if( sendto(iperf_data.client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){ + //printf("\n\r[ERROR] %s: UDP client send data error",__func__); + }else{ + total_size+=iperf_data.buf_size; + bandwidth_size+=iperf_data.buf_size; + } + + if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){ +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t)( bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); +#endif + bandwidth_time = end_time; + bandwidth_size = 0; + }else{ + if(bandwidth_size >= iperf_data.bandwidth){ + while((end_time - bandwidth_time) < configTICK_RATE_HZ){ + end_time = xTaskGetTickCount(); + } +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); +#endif + bandwidth_time = end_time; + bandwidth_size = 0; + } + } + + end_time = xTaskGetTickCount(); + } + } + else{ + start_time = xTaskGetTickCount(); + end_time = start_time; + bandwidth_time = start_time; + while ( (total_size < iperf_data.total_size) && (!g_udp_terminate) ) { + if( sendto(iperf_data.client_fd, buffer, iperf_data.buf_size,0,(struct sockaddr*)&ser_addr, addrlen) < 0){ + //printf("\n\r[ERROR] %s: UDP client send data error",__func__); + }else{ + total_size+=iperf_data.buf_size; + bandwidth_size+=iperf_data.buf_size; + } + if((end_time - bandwidth_time) >= (configTICK_RATE_HZ*1)){ +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); +#endif + bandwidth_time = end_time; + bandwidth_size = 0; + }else{ + if(bandwidth_size >= iperf_data.bandwidth){ + while((end_time - bandwidth_time) < (configTICK_RATE_HZ*1)){ + end_time = xTaskGetTickCount(); + } +#if PER_SECOND_REPORT + printf("\n\r%s: Send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(bandwidth_size/KB),(uint32_t)(end_time-bandwidth_time),((uint32_t)(bandwidth_size*8)/(end_time - bandwidth_time))); +#endif + bandwidth_time = end_time; + bandwidth_size = 0; + } + } + end_time = xTaskGetTickCount(); + } + } + printf("\n\r%s: [END] Totally send %d KBytes in %d ms, %d Kbits/sec",__func__, (uint32_t)(total_size/KB),(uint32_t)(end_time-start_time),((uint32_t)(total_size*8)/(end_time - start_time))); + +Exit1: + close(iperf_data.client_fd); +Exit2: + printf("\n\r%s: Close client socket",__func__); + if(buffer) + vPortFree(buffer); + return 0; +} + +int udp_server_func(struct iperf_data_t iperf_data) +{ + int server_fd; + struct sockaddr_in ser_addr , client_addr; + char *buffer = NULL; + int addrlen = sizeof(struct sockaddr_in); + int n = 1; + uint32_t start_time, report_start_time, report_end_time; + int recv_size=0; + uint64_t total_size=0,report_size=0; + + buffer = pvPortMalloc(iperf_data.buf_size); + if(!buffer){ + printf("\n\r[ERROR] %s: Alloc buffer failed",__func__); + goto Exit2; + } + + //create socket + if((iperf_data.server_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){ + printf("\n\r[ERROR] %s: Create socket failed",__func__); + goto Exit2; + } + + printf("\n\r%s: Create socket fd = %d, port = %d", __func__,iperf_data.server_fd,iperf_data.port); + + setsockopt( iperf_data.server_fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof( n ) ); + + //initialize structure dest + memset(&ser_addr, 0, sizeof(ser_addr)); + ser_addr.sin_family = AF_INET; + ser_addr.sin_port = htons(iperf_data.port); + ser_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + // binding the TCP socket to the TCP server address + if( bind(iperf_data.server_fd, (struct sockaddr*)&ser_addr, sizeof(ser_addr)) < 0){ + printf("\n\r[ERROR] %s: Bind socket failed",__func__); + goto Exit1; + } + + printf("\n\r%s: Bind socket successfully",__func__); + + start_time = xTaskGetTickCount(); + report_start_time = start_time; + + while (!g_udp_terminate) { + recv_size = recvfrom(iperf_data.server_fd,buffer,iperf_data.buf_size,0,(struct sockaddr *) &client_addr,&addrlen); + if( recv_size < 0){ + printf("\n\r[ERROR] %s: Receive data failed",__func__); + goto Exit1; + } + // ack data to client + // Not send ack to prevent send fail due to limited skb, but it will have warning at iperf client + //sendto(server_fd,buffer,ret,0,(struct sockaddr*)&client_addr,sizeof(client_addr)); + + report_end_time = xTaskGetTickCount(); + total_size+=recv_size; + report_size+=recv_size; + if(((report_end_time - report_start_time) >= (configTICK_RATE_HZ * 1)) && ((report_end_time - report_start_time) <= (configTICK_RATE_HZ * 2))) { +#if PER_SECOND_REPORT + printf("\n\r%s: Receive %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t) (report_size/KB),(uint32_t)(report_end_time-report_start_time),((uint32_t)(report_size*8)/(report_end_time - report_start_time))); +#endif + report_start_time = report_end_time; + report_size = 0; + } + else if((report_end_time - report_start_time) > (configTICK_RATE_HZ * 2)){ + report_start_time = report_end_time; + start_time = report_end_time; + report_size = 0; + } + } + printf("\n\r%s: [END] Totally receive %d KBytes in %d ms, %d Kbits/sec",__func__,(uint32_t) (total_size/KB),(uint32_t)(report_end_time-start_time),((uint32_t)(total_size*8)/(report_end_time - start_time))); + +Exit1: + // close the listening socket + close(iperf_data.server_fd); + +Exit2: + if(buffer) + vPortFree(buffer); + return 0; +} + +static void tcp_client_handler(void *param) +{ + vTaskDelay(100); + if(tcp_client_data.port == 0) + tcp_client_data.port = DEFAULT_PORT; + if(tcp_client_data.time == 0) + tcp_client_data.time = DEFAULT_TIME; + if(tcp_client_data.buf_size == 0) + tcp_client_data.buf_size = CLIENT_BUF_SIZE; + + printf("\n\rTCP: Start TCP client!"); + tcp_client_func(tcp_client_data); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + printf("\n\rTCP: TCP client stopped!"); + g_tcp_client_task = NULL; + vTaskDelete(NULL); +} + +static void tcp_server_handler(void *param) +{ + vTaskDelay(100); + if(tcp_server_data.port == 0) + tcp_server_data.port = DEFAULT_PORT; + if(tcp_server_data.buf_size == 0) + tcp_server_data.buf_size = SERVER_BUF_SIZE; + + printf("\n\rTCP: Start TCP server!"); + tcp_server_func(tcp_server_data); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("\n\rMin available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + printf("\n\rTCP: TCP server stopped!"); + g_tcp_server_task = NULL; + vTaskDelete(NULL); +} + +void udp_client_handler(void *param) +{ + vTaskDelay(100); + if(udp_client_data.port == 0) + udp_client_data.port = DEFAULT_PORT; + if(udp_client_data.time == 0) + udp_client_data.time = DEFAULT_TIME; + if(udp_client_data.bandwidth == 0) + udp_client_data.bandwidth = DEFAULT_UDP_BANDWIDTH; + if(udp_client_data.buf_size == 0) + udp_client_data.buf_size = CLIENT_BUF_SIZE; + if(udp_client_data.tos_value == 0) + udp_client_data.tos_value = DEFAULT_UDP_TOS_VALUE; + + printf("\n\rUDP: Start UDP client!"); + udp_client_func(udp_client_data); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("\n\rMin available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + + printf("\n\rUDP: UDP client stopped!"); + g_udp_client_task = NULL; + vTaskDelete(NULL); +} + +void udp_server_handler(void *param) +{ + vTaskDelay(100); + if(udp_server_data.port == 0) + udp_server_data.port = DEFAULT_PORT; + if(udp_server_data.buf_size == 0) + udp_server_data.buf_size = SERVER_BUF_SIZE; + + printf("\n\rUDP: Start UDP server!"); + udp_server_func(udp_server_data); + +#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1) + printf("\n\rMin available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE)); +#endif + + printf("\n\rUDP: UDP server stopped!"); + g_udp_server_task = NULL; + vTaskDelete(NULL); +} + +uint64_t km_parser(char *buf, int len) +{ + uint64_t ret=0; + int keyword_num=0; + char num_str[17] = "\0"; + uint64_t num; + + if(len>16) + return ret; + + while((buf[keyword_num] != '\0')&&(keyword_num=0){ + close(tcp_server_data.server_fd); + } + if(tcp_server_data.client_fd >=0){ + close(tcp_server_data.client_fd); + } + printf("\n\rTCP server stopped!\n"); + vTaskDelete(g_tcp_server_task); + g_tcp_server_task = NULL; + } + + return; + } + else{ + goto Exit; + } + } + else if(strcmp(argv[argv_count-1], "-c") == 0){ + if(g_tcp_client_task){ + printf("\n\rTCP: TCP client is already running. Please enter \"ATWT=stop\" to stop it."); + return; + }else{ + if(argc < (argv_count+1)) + goto Exit; + memset(&tcp_client_data,0,sizeof(struct iperf_data_t)); + tcp_client_data.start = 1; + strncpy(tcp_client_data.server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2])); + argv_count+=2; + } + } + else{ + goto Exit; + } + } + else{ + if(strcmp(argv[argv_count-1], "-t") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(tcp_client_data.start){ + tcp_client_data.time = atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-p") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(tcp_server_data.start){ + tcp_server_data.port = (uint16_t) atoi(argv[argv_count]); + } + else if(tcp_client_data.start){ + tcp_client_data.port = (uint16_t) atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-n") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(tcp_client_data.start){ + tcp_client_data.total_size = km_parser(argv[argv_count],strlen(argv[argv_count])); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-d") == 0){ + if(tcp_client_data.start){ + tcp_client_data.bandwidth = DEFAULT_TCP_BANDWIDTH; + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-l") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(tcp_server_data.start){ + tcp_server_data.buf_size = atoi(argv[argv_count]); + } + else if(tcp_client_data.start){ + tcp_client_data.buf_size = atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else{ + goto Exit; + } + } + } + + if(tcp_server_data.start && (NULL == g_tcp_server_task)){ + if(xTaskCreate(tcp_server_handler, "tcp_server_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_tcp_server_task) != pdPASS) + printf("\n\rTCP ERROR: Create TCP server task failed."); + } + if(tcp_client_data.start && (NULL == g_tcp_client_task)){ + if(xTaskCreate(tcp_client_handler, "tcp_client_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_tcp_client_task) != pdPASS) + printf("\n\rTCP ERROR: Create TCP client task failed."); + } + + return; +Exit: + printf("\n\r[ATWT] Command format ERROR!\n"); + printf("\n\r[ATWT] Usage: ATWT=[-s|-c,host|stop],[options]\n"); + printf("\n\r Client/Server:\n"); + printf(" \r stop terminate client & server\n"); + printf(" \r -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" \r -p # server port to listen on/connect to (default 5001)\n"); + printf("\n\r Server specific:\n"); + printf(" \r -s run in server mode\n"); + printf("\n\r Client specific:\n"); + printf(" \r -c run in client mode, connecting to \n"); + printf(" \r -d Do a bidirectional test simultaneously\n"); + printf(" \r -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" \r -n #[KM] number of bytes to transmit (instead of -t)\n"); + printf("\n\r Example:\n"); + printf(" \r ATWT=-s,-p,5002\n"); + printf(" \r ATWT=-c,192.168.1.2,-t,100,-p,5002\n"); + return; +} + +void cmd_udp(int argc, char **argv) +{ + int argv_count = 2; + uint8_t tos_value = 0; + + if(argc < 2) + goto Exit; + + g_udp_terminate = 0; + + while(argv_count<=argc){ + //first operation + if(argv_count == 2){ + if(strcmp(argv[argv_count-1], "-s") == 0){ + if(g_udp_server_task){ + printf("\n\rUDP: UDP Server is already running."); + return; + }else{ + memset(&udp_server_data,0,sizeof(struct iperf_data_t)); + udp_server_data.start = 1; + argv_count++; + } + } + else if(strcmp(argv[argv_count-1], "stop") == 0){ + if(argc == 2){ + vTaskDelay(100); + g_udp_terminate = 1; + udp_server_data.start = 0; + udp_client_data.start = 0; + + if(g_udp_server_task){ + if(udp_server_data.server_fd >=0){ + close(udp_server_data.server_fd); + } + printf("\n\rUDP server stopped!\n"); + vTaskDelete(g_udp_server_task); + g_udp_server_task = NULL; + } + + return; + } + else{ + goto Exit; + } + } + else if(strcmp(argv[argv_count-1], "-c") == 0){ + if(g_udp_client_task){ + printf("\n\rUDP: UDP client is already running. Please enter \"ATWU=stop\" to stop it."); + return; + }else{ + if(argc < (argv_count+1)) + goto Exit; + memset(&udp_client_data,0,sizeof(struct iperf_data_t)); + udp_client_data.start = 1; + strncpy(udp_client_data.server_ip, argv[2], (strlen(argv[2])>16)?16:strlen(argv[2])); + argv_count+=2; + } + } + else{ + goto Exit; + } + } + else{ + if(strcmp(argv[argv_count-1], "-t") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(udp_client_data.start){ + udp_client_data.time = atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-p") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(udp_server_data.start){ + udp_server_data.port = (uint16_t) atoi(argv[argv_count]); + } + else if(udp_client_data.start){ + udp_client_data.port = (uint16_t) atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-n") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(udp_client_data.start){ + udp_client_data.total_size = km_parser(argv[argv_count],strlen(argv[argv_count])); + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-b") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(udp_client_data.start){ + udp_client_data.bandwidth = km_parser(argv[argv_count],strlen(argv[argv_count])); + udp_client_data.bandwidth = udp_client_data.bandwidth/8;//bits to Bytes + } + else{ + goto Exit; + } + argv_count+=2; + } + else if(strcmp(argv[argv_count-1], "-d") == 0){ + if(udp_client_data.start){ + udp_client_data.bandwidth = DEFAULT_UDP_BANDWIDTH; + } + else{ + goto Exit; + } + argv_count+=1; + } +#if CONFIG_WLAN + else if(strcmp(argv[argv_count-1], "-S") == 0){ //for wmm test + if(argc < (argv_count+1)) + goto Exit; + if(udp_client_data.start){ + if(atoi(argv[argv_count]) >= 0 && atoi(argv[argv_count]) <= 255){ + tos_value = (uint8_t) atoi(argv[argv_count]); + wext_set_tos_value(WLAN0_NAME, &tos_value); + udp_client_data.tos_value = tos_value; + } + else{ + goto Exit; + } + } + else{ + goto Exit; + } + argv_count+=2; + } +#endif + else if(strcmp(argv[argv_count-1], "-l") == 0){ + if(argc < (argv_count+1)) + goto Exit; + if(udp_server_data.start){ + udp_server_data.buf_size = atoi(argv[argv_count]); + } + else if(udp_client_data.start){ + udp_client_data.buf_size = atoi(argv[argv_count]); + } + else{ + goto Exit; + } + argv_count+=2; + } + else{ + goto Exit; + } + } + } + + if(udp_server_data.start && (NULL == g_udp_server_task)){ + if(xTaskCreate(udp_server_handler, "udp_server_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_udp_server_task) != pdPASS) + printf("\r\nUDP ERROR: Create UDP server task failed."); + } + + if(udp_client_data.start && (NULL == g_udp_client_task)){ + if(xTaskCreate(udp_client_handler, "udp_client_handler", BSD_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1 + PRIORITIE_OFFSET, &g_udp_client_task) != pdPASS) + printf("\r\nUDP ERROR: Create UDP client task failed."); + } + + return; + +Exit: + printf("\n\r[ATWU] Command format ERROR!\n"); + printf("\n\r[ATWU] Usage: ATWU=[-s|-c,host|stop][options]\n"); + printf("\n\r Client/Server:\n"); + printf(" \r stop terminate client & server\n"); + printf(" \r -l # length of buffer to read or write (default 1460 Bytes)\n"); + printf(" \r -p # server port to listen on/connect to (default 5001)\n"); + printf("\n\r Server specific:\n"); + printf(" \r -s run in server mode\n"); + printf("\n\r Client specific:\n"); + printf(" \r -b #[KM] for UDP, bandwidth to send at in bits/sec (default 1 Mbit/sec)\n"); + printf(" \r -c run in client mode, connecting to \n"); + printf(" \r -d Do a bidirectional test simultaneously\n"); + printf(" \r -t # time in seconds to transmit for (default 10 secs)\n"); + printf(" \r -n #[KM] number of bytes to transmit (instead of -t)\n"); +#if CONFIG_WLAN + printf(" \r -S # set the IP 'type of service'\n"); +#endif + printf("\n\r Example:\n"); + printf(" \r ATWU=-s,-p,5002\n"); + printf(" \r ATWU=-c,192.168.1.2,-t,100,-p,5002\n"); + return; +} + +#endif // CONFIG_BSD_TCP + +#endif // LWIP_SOCKET + diff --git a/USDK/component/common/utilities/uart_socket.c b/USDK/component/common/utilities/uart_socket.c new file mode 100644 index 0000000..de63d12 --- /dev/null +++ b/USDK/component/common/utilities/uart_socket.c @@ -0,0 +1,372 @@ +#include "lwip/api.h" +#include "PinNames.h" +#include "sockets.h" +#include "uart_socket.h" +#include "autoconf.h" + +#if CONFIG_UART_SOCKET + +#define UART_SOCKET_USE_DMA_TX 1 +/*********************************************************************** + * Macros * + ***********************************************************************/ +#define uart_printf printf +#define uart_print_data(x, d, l) \ +do{\ + int i;\ + uart_printf("\n%s: Len=%d\n", (x), (l));\ + for(i = 0; i < (l); i++)\ + uart_printf("%02x ", (d)[i]);\ + uart_printf("\n");\ +}while(0); + +/************************************************************************ + * extern funtions * + ************************************************************************/ +extern void lwip_selectevindicate(int fd); +extern void lwip_setsockrcvevent(int fd, int rcvevent); +extern int lwip_allocsocketsd(); + +/************************************************************************* +* uart releated fuantions * +*************************************************************************/ +static void uart_irq(uint32_t id, SerialIrq event) +{ + uart_socket_t *u = (uart_socket_t *)id; + + if(event == RxIrq) { + if( u->rx_start == 0 ){ + RtlUpSemaFromISR(&u->action_sema); //up action semaphore + u->rx_start = 1; // set this flag in uart_irq to indicate data recved + } + u->recv_buf[u->prxwrite++] = serial_getc(&u->sobj); + if(u->prxwrite > (UART_RECV_BUFFER_LEN -1)){ //restart from head if reach tail + u->prxwrite = 0; + u->rxoverlap = 1; //set overlap indicated that overlaped + } + if(u->rxoverlap && (u->prxwrite + 1) > u->prxread ){ + u->prxread = u->prxwrite; //if pwrite overhead pread ,pread is always flow rwrite + } + u->last_update = xTaskGetTickCountFromISR(); // update tick everytime recved data + } + + if(event == TxIrq){ + } +} + +static void uart_send_stream_done(uint32_t id) +{ + uart_socket_t *u = (uart_socket_t *)id; + + //u->tx_start = 0; + memset(u->send_buf,0, UART_SEND_BUFFER_LEN); //zero set uart_send_buf + RtlUpSemaFromISR(&u->tx_sema); + RtlUpSemaFromISR(&u->dma_tx_sema); +} + +static int uart_send_stream(uart_socket_t *u, char* pbuf, int len) +{ + int ret; + + if(!len || (!pbuf) || !u){ + uart_printf("input error,size should not be null\r\n"); + return -1; + } + +#if UART_SOCKET_USE_DMA_TX + while(RtlDownSema(&u->dma_tx_sema) == pdTRUE){ + ret = serial_send_stream_dma(&u->sobj, pbuf, len); + if(ret != HAL_OK){ + RtlUpSema(&u->dma_tx_sema); + return -1; + }else{ + return 0; + } + } +#else + while (len){ + serial_putc(&u->sobj, *pbuf); + len--; + pbuf++; + } +#endif + + return 0; +} + +static s32 uart_wait_rx_complete(uart_socket_t *u) +{ + s32 tick_current = xTaskGetTickCount(); + + while((tick_current -u->last_update) < UART_MAX_DELAY_TIME ){ + vTaskDelay(5); + tick_current = xTaskGetTickCount(); + } + return 0; +} + +static void uart_action_handler(void* param) +{ + uart_socket_t *u = (uart_socket_t*)param; + if(!u) + goto Exit; + + while(RtlDownSema(&u->action_sema) == pdTRUE) { + if(u->fd == -1) + goto Exit; + if(u->rx_start){ + /* Blocked here to wait uart rx data completed */ + uart_wait_rx_complete(u); + + /* As we did not register netconn callback function.,so call lwip_selectevindicate unblocking select */ + lwip_setsockrcvevent(u->fd, 1); + lwip_selectevindicate(u->fd); //unblocking select() + u->rx_start = 0; + } + if(u->tx_start){ +#if 1 + if (u->tx_bytes < 128) { + uart_print_data("TX:", u->send_buf, u->tx_bytes); + } else { + uart_printf("\nTX:: Len=%d\n", u->tx_bytes); + } +#endif + //if(serial_send_stream_dma(&u->sobj, (char*)u->send_buf, u->tx_bytes) == -1){ + if(uart_send_stream(u, (char*)u->send_buf, u->tx_bytes) == -1){ + uart_printf("uart send data error!"); + } else { + u->tx_start = 0; +#if (UART_SOCKET_USE_DMA_TX == 0) + memset(u->send_buf,0, UART_SEND_BUFFER_LEN); //zero set uart_send_buf + RtlUpSema(&u->tx_sema); +#endif + } + } + } +Exit: + vTaskDelete(NULL); +} + + +uart_socket_t* uart_open(uart_set_str *puartpara) +{ + PinName uart_tx = PA_7;//PA_4; //PA_7 + PinName uart_rx = PA_6;//PA_0; //PA_6 + uart_socket_t *u; + + u = (uart_socket_t *)RtlZmalloc(sizeof(uart_socket_t)); + if(!u){ + uart_printf("%s(): Alloc memory for uart_socket failed!\n", __func__); + return NULL; + } + + /*initial uart */ + serial_init(&u->sobj, uart_tx,uart_rx); + serial_baud(&u->sobj,puartpara->BaudRate); + serial_format(&u->sobj, puartpara->number, (SerialParity)puartpara->parity, puartpara->StopBits); + + /*uart irq handle*/ + serial_irq_handler(&u->sobj, uart_irq, (int)u); + serial_irq_set(&u->sobj, RxIrq, 1); + serial_irq_set(&u->sobj, TxIrq, 1); + +#if UART_SOCKET_USE_DMA_TX + serial_send_comp_handler(&u->sobj, (void*)uart_send_stream_done, (uint32_t)u); +#endif + + /*alloc a socket*/ + u->fd = lwip_allocsocketsd(); + if(u->fd == -1){ + uart_printf("Failed to alloc uart socket!\n"); + goto Exit2; + } + /*init uart related semaphore*/ + RtlInitSema(&u->action_sema, 0); + RtlInitSema(&u->tx_sema, 1); + RtlInitSema(&u->dma_tx_sema, 1); + + /*create uart_thread to handle send&recv data*/ + { +#define UART_ACTION_STACKSIZE 256 //USE_MIN_STACK_SIZE modify from 512 to 256 +#define UART_ACTION_PRIORITY 1 + if(xTaskCreate(uart_action_handler, ((const char*)"uart_action"), UART_ACTION_STACKSIZE, u, UART_ACTION_PRIORITY, NULL) != pdPASS){ + uart_printf("%s xTaskCreate(uart_action) failed", __FUNCTION__); + goto Exit1; + } + } + return u; +Exit1: + /* Free uart related semaphore */ + RtlFreeSema(&u->action_sema); + RtlFreeSema(&u->tx_sema); + RtlFreeSema(&u->dma_tx_sema); +Exit2: + RtlMfree((u8*)u, sizeof(uart_socket_t)); + return NULL; +} + +int uart_close(uart_socket_t *u) +{ + if(!u){ + uart_printf("uart_close(): u is NULL!\r\n"); + return -1; + } + /* Close uart socket */ + if(lwip_close(u->fd) == -1){ + uart_printf("%s(): close uart failed!", __func__); + } + /* Delete uart_action task */ + u->fd = -1; + RtlUpSema(&u->action_sema); + RtlMsleepOS(20); + + /* Free uart related semaphore */ + RtlFreeSema(&u->action_sema); + RtlFreeSema(&u->tx_sema); + RtlFreeSema(&u->dma_tx_sema); + + /* Free serial */ + serial_free(&u->sobj); + + RtlMfree((u8 *)u, sizeof(uart_socket_t)); + + return 0; +} + +int uart_read(uart_socket_t *u, void *read_buf, size_t size) +{ + /*the same as socket*/ + int read_bytes = 0; + int pread_local,pwrite_local; + char *ptr = (char *)read_buf; + + uart_printf("==>uart_read()\n"); + if(!size || !read_buf || !u){ + uart_printf("uart_read(): input error,size should not be null\r\n"); + return -1; + } + + pread_local = u->prxread; + pwrite_local = u->prxwrite; + /*calculate how much data not read */ + if(!u->rxoverlap){ + read_bytes = pwrite_local - pread_local; + } else { + read_bytes = (UART_RECV_BUFFER_LEN - pread_local) + pwrite_local; + } + /*decide how much data shoule copy to application*/ + if(size < read_bytes) + read_bytes = size; + + if(!u->rxoverlap){ + memcpy(ptr, (u->recv_buf+ pread_local), read_bytes ); + } else { + uart_printf("uart recv buf is write through!\n"); + if((pread_local + read_bytes) > UART_RECV_BUFFER_LEN){ + memcpy(ptr,(u->recv_buf+ pread_local), (UART_RECV_BUFFER_LEN-pread_local)); + memcpy(ptr+(UART_RECV_BUFFER_LEN-pread_local), u->recv_buf, read_bytes-(UART_RECV_BUFFER_LEN- pread_local)); + } else + memcpy(ptr,(u->recv_buf+ pread_local), read_bytes); + } + lwip_setsockrcvevent(u->fd, 0); + + if((pread_local + read_bytes) >= UART_RECV_BUFFER_LEN){ //update pread + u->prxread = (pread_local + read_bytes) - UART_RECV_BUFFER_LEN; + u->rxoverlap = 0; //clean overlap flags + } else + u->prxread = pread_local + read_bytes; + + return read_bytes; + +} + + +int uart_write(uart_socket_t *u, void *pbuf, size_t size) +{ + if(!size || !pbuf || !u){ + uart_printf("input error,please check!"); + return -1; + } + if(RtlDownSema(&u->tx_sema)){ + //uart_printf("[%d]:uart_write %d!\n", xTaskGetTickCount(), size); + memcpy(u->send_buf, pbuf, size); + u->tx_bytes = size; + u->tx_start = 1; //set uart tx start + RtlUpSema(&u->action_sema); // let uart_handle_run through + } else { + uart_printf("uart write buf error!"); + return -1; + } + + return size; +} + +void uart_socket_example(void *param) +{ + char tx_data[] = {0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + uart_set_str uartset; + struct timeval tv; + fd_set readfds; + int read_len = 0, count = 0; + int ret = 0; + char rxbuf[512]; + int uart_fd; + uart_socket_t *uart_socket = NULL; + + uartset.BaudRate = 9600; + uartset.number = 8; + uartset.StopBits = 0; + uartset.FlowControl = 0; + uartset.parity = 0; + strcpy(uartset.UartName, "uart0"); + + uart_socket = uart_open(&uartset); + if(uart_socket == NULL){ + uart_printf("Init uart socket failed!\n"); + goto Exit; + } + uart_fd = uart_socket->fd; + uart_printf("\nOpen uart socket: %d\n", uart_fd); + while(1) + { + FD_ZERO(&readfds); + FD_SET(uart_fd, &readfds); + tv.tv_sec = 0; + tv.tv_usec = 20000; + if(count++ == 50){ + uart_write(uart_socket, tx_data, sizeof(tx_data)); + //uart_print_data("TX:", tx_data, sizeof(tx_data)); + count = 0; + } + ret = select(uart_fd + 1, &readfds, NULL, NULL, &tv); + //uart_printf("[%d] select ret = %x count=%d\n", xTaskGetTickCount(), ret, count); + if(ret > 0) + { + if(FD_ISSET(uart_fd, &readfds)) + { + read_len = uart_read(uart_socket, rxbuf, sizeof(rxbuf)); + if(read_len > 0) + { + uart_print_data("RX:", rxbuf, read_len); + if(rtl_strncmp(rxbuf, "close", 5) == 0) + break; + } + } + //else for other sockets + } + } + uart_printf("Exit uart socket example!\n"); + uart_close(uart_socket); +Exit: + vTaskDelete(NULL); +} + +void uart_socket() +{ +#define UART_SOCKET_STACK_SIZE 512 +#define UART_SOCKET_PRIORITY 1 + if(xTaskCreate(uart_socket_example, "uart_socket", UART_SOCKET_STACK_SIZE, NULL, UART_SOCKET_PRIORITY, NULL) != pdPASS) + uart_printf("%s xTaskCreate failed", __FUNCTION__); +} + +#endif // #if CONFIG_UART_SOCKET diff --git a/USDK/component/common/utilities/uart_socket.h b/USDK/component/common/utilities/uart_socket.h new file mode 100644 index 0000000..8e79cba --- /dev/null +++ b/USDK/component/common/utilities/uart_socket.h @@ -0,0 +1,52 @@ +#ifndef __UART_SOCKET_H_ +#define __UART_SOCKET_H_ + +#include "osdep_api.h" +#include "serial_api.h" +#include "serial_ex_api.h" + +#if CONFIG_UART_SOCKET +#define UART_SEND_BUFFER_LEN 512 +#define UART_RECV_BUFFER_LEN 1024 +#define UART_MAX_DELAY_TIME 20 + +typedef struct _uart_set_str +{ + char UartName[8]; // the name of uart + int BaudRate; //The baud rate + char number; //The number of data bits + char parity; //The parity(default NONE) + char StopBits; //The number of stop bits + char FlowControl; //support flow control is 1 +}uart_set_str; + +typedef struct _uart_socket_t +{ + serial_t sobj; + int fd; + + /* Used for UART RX */ + u32 rx_start; + //u32 rx_bytes; + u32 prxread; + u32 prxwrite; + u32 rxoverlap; + u32 last_update; //tick count when rx byte + u8 recv_buf[UART_RECV_BUFFER_LEN]; + + u32 tx_start; + u32 tx_bytes; + u8 send_buf[UART_SEND_BUFFER_LEN]; + _Sema tx_sema; + _Sema dma_tx_sema; + + _Sema action_sema; +}uart_socket_t; + +uart_socket_t* uart_open(uart_set_str *puartpara); +int uart_close(uart_socket_t *u); +int uart_read(uart_socket_t *u, void *read_buf, size_t size); +int uart_write(uart_socket_t *u, void *pbuf, size_t size); + +#endif // #if CONFIG_UART_SOCKET +#endif //__UART_SOCKET_H_ diff --git a/USDK/component/common/utilities/uart_ymodem.c b/USDK/component/common/utilities/uart_ymodem.c new file mode 100644 index 0000000..582bbcb --- /dev/null +++ b/USDK/component/common/utilities/uart_ymodem.c @@ -0,0 +1,656 @@ +/****************************************uart _ymodem.c**************************************************/ + +#include "osdep_service.h" +#include "uart_ymodem.h" +#include "PinNames.h" + +#if CONFIG_UART_SOCKET +/***************************************************************************************** +* uart basic functions * +******************************************************************************************/ + void uarty_irq(uint32_t id, SerialIrq event) +{ + uart_ymodem_t *ptr = (uart_ymodem_t *)id; + //u8 ch = 0; + if(event == RxIrq) { + if(ptr->uart_recv_index == 0){ + RtlUpSemaFromISR(&ptr->uart_rx_sema);//up uart rx semaphore + } + if(ptr->uart_recv_index == RCV_BUF_SIZE) + ptr->uart_recv_index = 0; + //ch = serial_getc(&ptr->sobj); + // printf("[%d] 0x%x\r\n", ptr->uart_recv_index, ch); + ptr->uart_irq_buf[ptr->uart_recv_index++] = serial_getc(&ptr->sobj); + ptr->tick_last_update = xTaskGetTickCountFromISR(); // update tick everytime recved data + } + + if(event == TxIrq){ +// uart_send_string(sobj, "\r\n8195a$"); +// rcv_ch = 0; + } +} + +void uart_init(uart_ymodem_t *ptr) +{ +// serial_t sobj; + + //uart init + serial_init(&ptr->sobj,UART_TX,UART_RX); + serial_baud(&ptr->sobj,UART_BAUDRATE); //set baudrate 38400 + serial_format(&ptr->sobj, 8, ParityNone, 0); + + serial_irq_handler(&ptr->sobj, uarty_irq, (int)ptr); + serial_irq_set(&ptr->sobj, RxIrq, 1); + serial_irq_set(&ptr->sobj, TxIrq, 1); + + RtlInitSema(&ptr->uart_rx_sema, 0); +} +void uart_sendbyte(uart_ymodem_t *ptr,u8 sendc ) +{ + + serial_putc(&ptr->sobj, sendc); +// printf(" uart send 0x%x\r\n",sendc); +} + +int uart_recvbytetimeout(uart_ymodem_t *uart_ymodem,u8 *ptr) +{ + int ret = 0; +// static int uart_recv_buf_index = 0; + +// printf(" [%d] = %x\r\n",uart_ymodem->uart_recv_buf_index,uart_ymodem->uart_irq_buf[uart_ymodem->uart_recv_buf_index]); + *ptr = uart_ymodem->uart_irq_buf[uart_ymodem->uart_recv_buf_index]; + uart_ymodem->uart_recv_buf_index++; + if(uart_ymodem->uart_recv_buf_index == RCV_BUF_SIZE) + uart_ymodem->uart_recv_buf_index = 0; + return ret; +} + +void uart_rxempty(uart_ymodem_t *ptr) +{ + /*clean uart recv buf*/ +// printf("Uart_RxEmpty\r\n"); + memset(ptr->uart_irq_buf, 0, RCV_BUF_SIZE); + memset(ptr->uart_rcv_buf, 0, RCV_BUF_SIZE); + ptr->uart_recv_buf_index = 0; + ptr->uart_recv_index = 0; +} +/***************************************************************************************** +* flash function * +******************************************************************************************/ +int ymodem_flashwrite(int flashadd, u8 *pbuf, int len) +{ + + int ret = 0; + flash_t flash; + +// if(!FLASH_ADDRESS_CHECK_WRITE_ERASE(flashadd)){ +// ret = -1; +// return ret; +// } + if( len == 0){ + printf("input error,data length should not be null!\r\n"); + ret = -1; + return ret; + } + else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented. + len += 4 - ((len%4)==0 ? 4 : (len%4)); + + while(len){ + if(flash_write_word(&flash, flashadd, *(unsigned int *)pbuf) !=1 ){ + printf("write flash error!\r\n"); + ret = -1; + return ret; + } + len -= 4; + pbuf += 4; + flashadd += 4; + } + + return ret; +} +/****************************uart_ymodem_init**********************************/ +void uart_ymodem_init(uart_ymodem_t *uart_ymodem_ptr) +{ +// u32 ret = 0; +#if CONFIG_CALC_FILE_SIZE + u8 filename[33] = {0}; //file name: max 32 bytes+ '\0'=33 +#endif + //init uart struct + uart_ymodem_ptr->cur_num = 0; + uart_ymodem_ptr->filelen = 0 ; +#if CONFIG_CALC_FILE_SIZE + uart_ymodem_ptr->filename = &filename[0]; +#endif + uart_ymodem_ptr->len = 0; + uart_ymodem_ptr->nxt_num = 0; + uart_ymodem_ptr->modemtype = 2; //ymodem protocol + uart_ymodem_ptr->rec_err = 0; + uart_ymodem_ptr->crc_mode = 1; //crc check + uart_ymodem_ptr->uart_recv_buf_index = 0; + uart_ymodem_ptr->uart_recv_index = 0; + uart_ymodem_ptr->image_address = IMAGE_TWO; + +// return uart_ymodem_ptr; +} + +void uart_ymodem_deinit(uart_ymodem_t *ptr) +{ + + /* Free uart_rx-sema */ + RtlFreeSema(&ptr->uart_rx_sema); + + /* Free serial */ + serial_free(&ptr->sobj); + + /* Free uart_ymodem_t */ + RtlMfree((u8 *)ptr,sizeof(uart_ymodem_t)); +} + +#if CONFIG_CALC_FILE_SIZE +unsigned int buf_filelen(u8 *ptr) +{ + int datatype=10, result=0; + + if (ptr[0]=='0' && (ptr[1]=='x' && ptr[1]=='X')) + { + datatype = 16; + ptr += 2; + } + + for ( ; *ptr!='\0'; ptr++) + { + if (*ptr>= '0' && *ptr<='9') + { + result =result*datatype+*ptr-'0'; + } + else + { + if (datatype == 10) + { + return result; + } + else + { + if (*ptr>='A' && *ptr<='F') + { + result = result*16 + *ptr-55; //55 = 'A'-10 + } + else if (*ptr>='a' && *ptr<='f') + { + result = result*16 + *ptr-87; //87 = 'a'-10 + } + else + { + return result; + } + } + } + } + return result; +} +#endif +void modem_cancle(uart_ymodem_t *ptr) +{ + uart_sendbyte(ptr,0x18); + uart_sendbyte(ptr,0x18); + uart_sendbyte(ptr,0x18); + uart_sendbyte(ptr,0x18); + uart_sendbyte(ptr,0x18); +} + +int start_next_round(uart_ymodem_t *ptr) +{ + int ret = 0; + +// printf(" uart ymodedm transfer %d block\r\n",ptr->nxt_num); + //clean recv buf + if(!ptr->rec_err){ + uart_rxempty(ptr); + } + else{ + ret = -1; + printf("\r\n recv data error!"); + } + + if (ptr->nxt_num == 0) + { + if (ptr->crc_mode) + { + uart_sendbyte(ptr,MODEM_C); //first receiver send c + } + else + { + uart_sendbyte(ptr,MODEM_NAK); + } + } + else + { + if (ptr->rec_err) + { + uart_sendbyte(ptr,MODEM_NAK); + } + else + { + if (ptr->nxt_num == 1) + { + if (ptr->crc_mode) + { + uart_sendbyte(ptr,MODEM_ACK); + uart_sendbyte(ptr,MODEM_C); + } + else + { + uart_sendbyte(ptr,MODEM_NAK); + } + } + else + { + uart_sendbyte(ptr,MODEM_ACK); + } + } + } + return ret; +} +int data_write_to_flash(uart_ymodem_t *ptr) +{ + int ret = 0; +// uint32_t update_image_address = IMAGE_TWO; + static int offset = 0x0; + u32 data; + static int flags = 1; //write update image header only once +// int file_blk_size = 0 + + flash_read_word(&ptr->flash, OFFSET_DATA, &data); +// file_blk_size = ((ptr->filelen - 1)/4096) + 1; + if(data == ~0x0){ + flash_write_word(&ptr->flash, OFFSET_DATA, ptr->image_address); + } +// printf("image_address get from flash = 0x%x\n\r",ptr->image_address); + //erase flash where to be written,since ymodem blk size can be 128 or 1024,so, erase once when gather 4096 + if(offset ==0 || (offset % 4096)==0){ + flash_erase_sector(&ptr->flash, ptr->image_address + offset); + } + //write to flash + //write back image size and address + if(!flags){ + flash_write_word(&ptr->flash, ptr->image_address, ptr->filelen); + flash_write_word(&ptr->flash, ptr->image_address+4,0x10004000); + flags = 1; + } +// ymodem_flashwrite(update_image_address + offset, ptr->uart_rcv_buf, ptr->len); + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_write(&ptr->flash, ptr->image_address+offset, ptr->len, ptr->uart_rcv_buf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + offset += ptr->len; + + return ret; +} +int block_num_check(uart_ymodem_t *ptr) +{ + + u8 blk,cblk; + int stat, ret = 0; + /**************** check blk and blk complement *********************/ + stat = uart_recvbytetimeout(ptr,&blk); //blk num,bytes 2 + if (stat != 0) + { + ret = -1; + } + printf(" blk num = %x\r\n", blk); + + stat = uart_recvbytetimeout(ptr,&cblk); //block num complement,bytes 3 + if (stat != 0) + { + ret = -1; + } +// printf(" block num cmpl = %x\r\n",cblk); + + if (blk+cblk != 0xff) + { + ret = -1; + } + return ret; + +} + +int calc_file_name_size(uart_ymodem_t *ptr,u8* bufptr) +{ + int ret = 0; + u8* nameptr = ptr->filename; + + while (*bufptr != '\0'){ + *nameptr++ = *bufptr++; + } + *nameptr = '\0'; + bufptr++; + while (*bufptr == ' ') + { + bufptr++; + } + //file length + ptr->filelen = buf_filelen(bufptr); + + return ret; +} + +int crc_check(uart_ymodem_t *ptr) +{ + u8 crch, crcl; + u8 *in_ptr; + int stat,i,ret = 0; + u32 cksum = 0; + + stat = uart_recvbytetimeout(ptr,&crch); //CRC byte 1 + if (stat != 0){ + ret = 1; + } +// printf(" char recved CRC byte 1 = %x\r\n", crch); + if (ptr->crc_mode){ + stat = uart_recvbytetimeout(ptr,&crcl); //CRC byte 2 + if (stat != 0){ + ret = 1; + } + } +// printf(" char recved CRC byte 2 = %x\r\n", crcl); +#if CRC_CHECK + for (i=0; ilen; i++) //sum check for last block + { + cksum += ptr->uart_rcv_buf[i]; + } + if(cksum == 0) + { + ret = 2; + return ret; + } + + if (ptr->crc_mode) + { + in_ptr = ptr->uart_rcv_buf; + cksum = 0; + + for (stat=ptr->len ; stat>0; stat--) + { + cksum = cksum^(int)(*in_ptr++) << 8; + for (i=8; i !=0; i--) + { + if (cksum & 0x8000) + cksum = cksum << 1 ^ 0x1021; + else + cksum = cksum << 1; + } + + } + cksum &= 0xffff; + + if (cksum != (crch<<8 | crcl)) + { + ptr->rec_err = 1; + ret = 1; + } + } + else + { + for (i=0; ilen; i++) //sum check + { + cksum += ptr->uart_rcv_buf[i]; + } + if ((cksum&0xff)!=crch) + { + ptr->rec_err = 1; + ret = 1; + } + } +#endif + return ret; + +} +#if DUMP_DATA +void flash_dump_data(uart_ymodem_t *ptr) +{ + int i,offset = 0; + u32 data; + printf("flash dump data"); + for(i = 0;i< ptr->filelen;i+=4){ + flash_read_word(&ptr->flash, ptr->image_address + 0x10 + offset, &data); + offset += 4; + printf("%x ",data); + } +} +#endif +#if AUTO_REBOOT +void auto_reboot(void) +{ + // Set processor clock to default before system reset + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); + osDelay(100); + + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ + while(1) osDelay(1000); +} +#endif + +int set_signature(uart_ymodem_t *ptr) +{ + int ret = 0; + uint32_t sig_readback0,sig_readback1; + uint32_t oldimg2addr; + + //old image address + flash_read_word(&ptr->flash, 0x18, &oldimg2addr); + oldimg2addr = (oldimg2addr&0xFFFF)*1024; + printf(" lod image address 0x%x\n\r",oldimg2addr); + //Set signature in New Image 2 addr + 8 and + 12 +// flash_write_word(&ptr->flash,ptr->image_address + 8, 0x35393138);//0x35393138 +// flash_write_word(&ptr->flash,ptr->image_address + 12, 0x31313738); +// flash_read_word(&ptr->flash, ptr->image_address + 8, &sig_readback0); +// flash_read_word(&ptr->flash, ptr->image_address + 12, &sig_readback1); +// printf(" new signature %x,%x,\n\r",sig_readback0, sig_readback1); +#if 1 + flash_write_word(&ptr->flash,oldimg2addr + 8, 0x35393130); + flash_write_word(&ptr->flash,oldimg2addr + 12, 0x31313738); + flash_read_word(&ptr->flash, oldimg2addr + 8, &sig_readback0); + flash_read_word(&ptr->flash, oldimg2addr + 12, &sig_readback1); + printf(" old signature %x,%x\n\r",sig_readback0, sig_readback1); +#endif + printf(" set signature success!\n\r"); + + return ret; +} + +static void uart_ymodem_thread(void* param) +{ + u8 ch; + u32 stat, error_bit = 0, transfer_over = 0; + u32 can_counter = 0, eot_counter = 0; + u32 i, send_count = 0 , ret = 0; + static int first_time = 1; + uart_ymodem_t *ymodem_ptr = (uart_ymodem_t *)param; + printf(" ==>uart ymodem_task\r\n"); + while(1) + { + //wait 2min,2*60*1000/100 + if(send_count >= (2*60*10)){ + error_bit = 6; + printf("no response after 2min\r\n"); + goto exit; + } + else{ + if (ymodem_ptr->crc_mode){ + uart_sendbyte(ymodem_ptr,MODEM_C); //first receiver send c + } + else{ + uart_sendbyte(ymodem_ptr,MODEM_NAK); + } + send_count++; + } + if(xSemaphoreTake(ymodem_ptr->uart_rx_sema, 0) == pdTRUE){ + RtlUpSema(&ymodem_ptr->uart_rx_sema); + break; + } + else + // send every 100ms + vTaskDelay(100); + } +start: + while(xSemaphoreTake(ymodem_ptr->uart_rx_sema, portMAX_DELAY) == pdTRUE){ +// ymodem_ptr->tick_current = ymodem_ptr->tick_last_update = xTaskGetTickCount(); + ymodem_ptr->tick_current = xTaskGetTickCount(); + while((int)(ymodem_ptr->tick_current - ymodem_ptr->tick_last_update) < 50 ){ + ymodem_ptr->tick_current = xTaskGetTickCount(); + vTaskDelay(5); + } + printf("uart_recv_index = %d current=%d last=%d\r\n",ymodem_ptr->uart_recv_index, ymodem_ptr->tick_current, ymodem_ptr->tick_last_update); + /*uart data recv done and process what we have recvied*/ + stat = uart_recvbytetimeout(ymodem_ptr,&ch); + if (stat == 0) + { + switch (ch) + { + case MODEM_SOH : + ymodem_ptr->len = 128; +// printf(" char recved was MODEM_SOH!\r\n"); + break; + case MODEM_STX : + ymodem_ptr->len = 1024; +// printf(" char recved was MODEM_STX!\r\n"); + break; + case MODEM_CAN : + if ((++can_counter) >= MODEM_CAN_COUNT) + { + error_bit = 1; + goto exit; + } +// printf(" char recved was MODEM_CAN!\r\n"); + break; + case MODEM_EOT : +// printf(" char recved was MODEM_EOT!\r\n"); + if ((++eot_counter) >= MODEM_EOT_COUNT) + { + uart_sendbyte(ymodem_ptr,MODEM_ACK); + if (ymodem_ptr->modemtype == 2) //Ymodem protocol + { + uart_sendbyte(ymodem_ptr,MODEM_C); //first send a C + uart_sendbyte(ymodem_ptr,MODEM_ACK); //then send ack + uart_sendbyte(ymodem_ptr,MODEM_C); // and then send c + modem_cancle(ymodem_ptr); //cancel the transits + } + transfer_over = 1; + goto exit; + } + else + { + uart_sendbyte(ymodem_ptr,MODEM_ACK); + uart_sendbyte(ymodem_ptr,MODEM_C); + goto start; + } + break; + default: + error_bit = 1; + goto exit; + break; + } + } + + //block num check + if(block_num_check(ymodem_ptr)){ + error_bit = 2; + goto exit; + } +#if CONFIG_CALC_FILE_SIZE + // calculate file name and file size + if(ymodem_ptr->nxt_num == 0 && first_time){ + error_bit = calc_file_name_size(ymodem_ptr,&ymodem_ptr->uart_irq_buf[3]); +// first_time = 0; + } +#endif + //copy data from uart irq buf to uart recv buf without header + for (i=0; ilen; i++) + { + stat = uart_recvbytetimeout(ymodem_ptr,&ymodem_ptr->uart_rcv_buf[i]); +// printf(" data recv[%d] =%x\r\n",i,ymodem_ptr->uart_rcv_buf[i]); + } + //write data to flash,but do not write first block data + if(ymodem_ptr->nxt_num != 0 || !first_time){ + if(data_write_to_flash(ymodem_ptr)){ + error_bit = 3; + goto exit; + } + first_time = 0; + } + //crc check + ret = crc_check(ymodem_ptr); + if(ret == 1){ + error_bit = 4; + goto exit; + } + else if(ret == 2 && ymodem_ptr->nxt_num == 0xff){ + printf(" next num = %x\r\n",ymodem_ptr->nxt_num); + transfer_over = 1; + goto exit; + } + +#if 0 //avoid skip block + uart_ymodem->cur_num = blk; + if (blk != uart_ymodem->nxt_num) + { + error_bit = -1; + } +#endif + ymodem_ptr->nxt_num++; + ymodem_ptr->rec_err=0; + //start another round + if(start_next_round(ymodem_ptr)){ + error_bit = 5; + printf(" start next round failed!\r\n"); + goto exit; + } +} +exit: + //if anything goes wrong or transfer over,we kill ourself. + if(error_bit || transfer_over){ + if(error_bit) + printf("error! error bit = %d\r\n",error_bit); + else{ + printf(" [%s, %d Bytes] transfer_over!\r\n",ymodem_ptr->filename,ymodem_ptr->filelen); + set_signature(ymodem_ptr); +#if DUMP_DATA + flash_dump_data(ymodem_ptr); +#endif +#if AUTO_REBOOT + auto_reboot(); +#endif + } + } + first_time = 1; + uart_ymodem_deinit(ymodem_ptr); + vTaskDelete(NULL); +} + +int uart_ymodem(void) +{ + int ret = 0; + uart_ymodem_t *uart_ymodem_ptr; + + printf("uart ymodem update start\r\n"); + uart_ymodem_ptr = (uart_ymodem_t *)RtlMalloc(sizeof(uart_ymodem_t)); + if(!uart_ymodem_ptr){ + printf("uart ymodem malloc fail!\r\n"); + ret = -1; + return ret; + } + uart_ymodem_init(uart_ymodem_ptr); + if(ret == -1){ + ret = -1; + return ret; + } + //uart initial + uart_init(uart_ymodem_ptr); + if(xTaskCreate(uart_ymodem_thread, ((const char*)"uart_ymodem_thread"), UART_YMODEM_TASK_DEPTH, uart_ymodem_ptr, UART_YMODEM_TASK_PRIORITY, NULL) != pdPASS) + printf("%s xTaskCreate(uart_thread) failed\r\n", __FUNCTION__); + + return ret; +} +#endif // #if CONFIG_UART_SOCKET diff --git a/USDK/component/common/utilities/uart_ymodem.h b/USDK/component/common/utilities/uart_ymodem.h new file mode 100644 index 0000000..7cc0bde --- /dev/null +++ b/USDK/component/common/utilities/uart_ymodem.h @@ -0,0 +1,89 @@ +/****************************************uart_ymodem.h**************************************************/ + +#ifndef __YMODEM_H_ +#define __YMODEM_H_ + +#if CONFIG_UART_SOCKET + +#include "osdep_api.h" +#include "serial_api.h" +#include "flash_api.h" +#include "device_lock.h" +/*********************************************************************** + * Macros * + ***********************************************************************/ +// 8711AM +#define UART_TX PA_7 +#define UART_RX PA_6 +//8711AF +//#define UART_TX PA_4 +//#define UART_RX PA_0 + +#define UART_BAUDRATE 115200 +#define UART_YMODEM_TASK_PRIORITY 5 +#define UART_YMODEM_TASK_DEPTH 512 + +#define CONFIG_CALC_FILE_SIZE 1 +#define CRC_CHECK 1 +#define AUTO_REBOOT 0 +#define DUMP_DATA 0 + +#define OFFSET_DATA FLASH_SYSTEM_DATA_ADDR +#define IMAGE_TWO (0x80000) +//Y-modem related +#define MODEM_MAX_RETRIES 1 +#define MODEM_CRC_RETRIES 51 +#define MODEM_CAN_COUNT 3 +#define MODEM_EOT_COUNT 1 + +// ymodem protocol definition +#define MODEM_SOH 0x01 +#define MODEM_STX 0x02 +#define MODEM_EOT 0x04 +#define MODEM_ACK 0x06 +#define MODEM_NAK 0x15 +#define MODEM_CAN 0x18 +#define MODEM_C 0x43 +// 1 block size byte + 2 block number bytes + 1024 data body + 2 crc bytes +#define RCV_BUF_SIZE ((1)+(2)+(1024)+(2)) +/******************************** data struct **********************************/ +typedef struct _uart_ymodem_t +{ + serial_t sobj; + flash_t flash; + + /* Used for UART RX */ + u8 uart_rcv_buf[RCV_BUF_SIZE]; + u8 uart_irq_buf[RCV_BUF_SIZE]; + _Sema uart_rx_sema; + u32 image_address; + + u32 tick_last_update; + u32 tick_current; + u32 uart_recv_index; + u32 uart_recv_buf_index; + /* uart ymodem related*/ + u32 modemtype; + u32 crc_mode; + u32 nxt_num; //next block num + u32 cur_num; //current block num + u32 len; + u32 rec_err; //blcok data recv status + u32 filelen; //Ymodem file length + u8 *buf; //data buf + u8 *filename; //file name +}uart_ymodem_t; + + +#ifdef __cplusplus + extern "C"{ +#endif + +extern int uart_ymodem(void); + +#ifdef __cplusplus + } +#endif + +#endif +#endif //#if CONFIG_UART_SOCKET diff --git a/USDK/component/common/utilities/udpecho.c b/USDK/component/common/utilities/udpecho.c new file mode 100644 index 0000000..25e54f5 --- /dev/null +++ b/USDK/component/common/utilities/udpecho.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + + +#include "lwip/opt.h" + +#if LWIP_NETCONN + +#include "lwip/api.h" +#include "lwip/sys.h" + + +#define UDPECHO_THREAD_PRIO ( tskIDLE_PRIORITY + 3 ) + +static struct netconn *conn; +static struct netbuf *buf; +static struct ip_addr *addr; +static unsigned short port; +/*-----------------------------------------------------------------------------------*/ +static void udpecho_thread(void *arg) +{ + err_t err; + + LWIP_UNUSED_ARG(arg); + + conn = netconn_new(NETCONN_UDP); + if (conn!= NULL) + { + err = netconn_bind(conn, IP_ADDR_ANY, 7); + if (err == ERR_OK) + { + while (1) + { + buf = netconn_recv(conn); + + if (buf!= NULL) + { + addr = netbuf_fromaddr(buf); + port = netbuf_fromport(buf); + netconn_connect(conn, addr, port); + buf->addr = NULL; + netconn_send(conn,buf); + netbuf_delete(buf); + } + } + } + else + { + printf("can not bind netconn"); + } + } + else + { + printf("can create new UDP netconn"); + } +} +/*-----------------------------------------------------------------------------------*/ +void udpecho_init(void) +{ + sys_thread_new("udpecho", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE,UDPECHO_THREAD_PRIO ); +} + +#endif /* LWIP_NETCONN */ diff --git a/USDK/component/common/utilities/update.c b/USDK/component/common/utilities/update.c new file mode 100644 index 0000000..9dce4f0 --- /dev/null +++ b/USDK/component/common/utilities/update.c @@ -0,0 +1,1085 @@ +#include +#include +#include +#include +#include +#if LWIP_SOCKET +#include + +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#include +#if defined(STM32F2XX) +#include +#elif defined(STM32F4XX) +#include +#elif defined(STM32f1xx) +#include +#endif +#include "cloud_updater.h" +#else +#include "flash_api.h" +#include +#endif +#include "update.h" +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#define OFFSET_DATA FLASH_SYSTEM_DATA_ADDR +#define IMAGE_2 0x0000B000 +#define WRITE_OTA_ADDR 1 +#define CONFIG_CUSTOM_SIGNATURE 1 +#define SWAP_UPDATE 0 + +#if WRITE_OTA_ADDR +#define BACKUP_SECTOR (FLASH_SYSTEM_DATA_ADDR - 0x1000) +#endif + +#if CONFIG_CUSTOM_SIGNATURE +/* --------------------------------------------------- + * Customized Signature + * ---------------------------------------------------*/ +// This signature can be used to verify the correctness of the image +// It will be located in fixed location in application image +/* Moved in main.c +#include "section_config.h" +SECTION(".custom.validate.rodata") +const unsigned char cus_sig[32] = "Customer Signature-modelxxx"; +*/ +#endif + +#else +#define CONFIG_SECTOR FLASH_Sector_1 +#define APPLICATION_SECTOR FLASH_Sector_2 +#define UPDATE_SECTOR FLASH_Sector_8 +#endif +#define STACK_SIZE 1024 +#define TASK_PRIORITY tskIDLE_PRIORITY + 1 +#define BUF_SIZE 512 +#define ETH_ALEN 6 + +#define SERVER_LOCAL 1 +#define SERVER_CLOUD 2 +#define SERVER_TYPE SERVER_LOCAL +#define UPDATE_DBG 1 + +#if (SERVER_TYPE == SERVER_LOCAL) +typedef struct +{ + uint32_t ip_addr; + uint16_t port; +}update_cfg_local_t; +#endif + +#if (SERVER_TYPE == SERVER_CLOUD) +#define REPOSITORY_LEN 16 +#define FILE_PATH_LEN 64 +typedef struct +{ + uint8_t repository[REPOSITORY_LEN]; + uint8_t file_path[FILE_PATH_LEN]; +}update_cfg_cloud_t; +#endif + +sys_thread_t TaskOTA = NULL; +//--------------------------------------------------------------------- +static void* update_malloc(unsigned int size) +{ + return pvPortMalloc(size); +} + +//--------------------------------------------------------------------- +static void update_free(void *buf) +{ + vPortFree(buf); +} + +//--------------------------------------------------------------------- +#if (SERVER_TYPE == SERVER_LOCAL) +#if defined(STM32F2XX) ||(STM32F4XX) +static void update_ota_local_task(void *param) +{ + int server_socket = 0; + struct sockaddr_in server_addr; + char *buf; + int read_bytes, size = 0, i; + update_cfg_local_t *cfg = (update_cfg_local_t*)param; + uint32_t address, checksum = 0; +#if CONFIG_WRITE_MAC_TO_FLASH + char mac[ETH_ALEN]; +#endif + printf("[%s] Update task start\n", __FUNCTION__); + buf = update_malloc(BUF_SIZE); + if(!buf){ + printf("[%s] Alloc buffer failed\n", __FUNCTION__); + goto update_ota_exit; + } + // Connect socket + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if(server_socket < 0){ + printf("[%s] Create socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = cfg->ip_addr; + server_addr.sin_port = cfg->port; + + if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){ + printf("[%s] socket connect failed\n", __FUNCTION__); + goto update_ota_exit; + } + // Erase config sectors + if(flash_EraseSector(CONFIG_SECTOR) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } +#if CONFIG_WRITE_MAC_TO_FLASH + // Read MAC address + if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Read MAC error\n", __FUNCTION__); + goto update_ota_exit; + } +#endif + // Erase update sectors + for(i = UPDATE_SECTOR; i <= FLASH_Sector_11; i += 8){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } + // Write update sectors + address = flash_SectorAddress(UPDATE_SECTOR); + printf("\n"); + while(1){ + read_bytes = read(server_socket, buf, BUF_SIZE); + if(read_bytes == 0) break; // Read end + if(read_bytes < 0){ + printf("[%s] Read socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + if(flash_Wrtie(address + size, buf, read_bytes) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes; + for(i = 0; i < read_bytes; i ++) + checksum += buf[i]; + printf("Update file size = %d\n", size); + } +#if CONFIG_WRITE_MAC_TO_FLASH + //Write MAC address + if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){ + if(flash_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Write MAC failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#endif + // Write config sectors + address = flash_SectorAddress(CONFIG_SECTOR); + if( (flash_Wrtie(address, (char*)&size, 4) < 0) || + (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + printf("[%s] Update OTA success!\n", __FUNCTION__); +update_ota_exit: + if(buf) + update_free(buf); + if(server_socket >= 0) + close(server_socket); + if(param) + update_free(param); + TaskOTA = NULL; + printf("[%s] Update task exit\n", __FUNCTION__); + vTaskDelete(NULL); + return; +} +#elif defined(STM32f1xx) +static void update_ota_local_task(void *param) +{ + int server_socket; + struct sockaddr_in server_addr; + char *buf, flag_a = 0; + int read_bytes, size = 0, i; + update_cfg_local_t *cfg = (update_cfg_local_t*)param; + uint32_t address, checksum = 0; + uint16_t a = 0; +#if CONFIG_WRITE_MAC_TO_FLASH + char mac[ETH_ALEN]; +#endif + + printf("[%s] Update task start\n", __FUNCTION__); + buf = update_malloc(BUF_SIZE); + if(!buf){ + printf("[%s] Alloc buffer failed\n", __FUNCTION__); + goto update_ota_exit; + } + // Connect socket + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if(server_socket < 0){ + printf("[%s] Create socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = cfg->ip_addr; + server_addr.sin_port = cfg->port; + + if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){ + printf("[%s] socket connect failed\n", __FUNCTION__); + goto update_ota_exit; + } + // Erase config sectors + for(i = CONFIG_SECTOR; i < APPLICATION_SECTOR; i += FLASH_PAGE_SIZE){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#if CONFIG_WRITE_MAC_TO_FLASH + // Read MAC address + if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Read MAC error\n", __FUNCTION__); + goto update_ota_exit; + } +#endif + + // Erase update sectors + for(i = UPDATE_SECTOR; i < FLASH_Sector_0 + FLASH_SIZE; i += FLASH_PAGE_SIZE){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } + // Write update sectors + address = UPDATE_SECTOR; + printf("\n"); + while(1){ + read_bytes = read(server_socket, buf, BUF_SIZE); + if(read_bytes == 0) break; // Read end + if(read_bytes < 0){ + printf("[%s] Read socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + if(flag_a == 0){ + if(read_bytes % 2 != 0){ + a = buf[read_bytes - 1]; + flag_a = 1; + if(flash_Wrtie(address + size, buf, read_bytes - 1) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 1; + } + else{ + if(flash_Wrtie(address + size, buf, read_bytes) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes; + } + } + else{ + a = buf[0] << 8 | a; + if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += 2; + a = 0; + flag_a = 0; + if((read_bytes - 1) % 2 != 0){ + a = buf[read_bytes - 1]; + flag_a = 1; + if(flash_Wrtie(address + size, buf + 1, read_bytes - 2) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 2; + } + else{ + if(flash_Wrtie(address + size, buf + 1, read_bytes - 1) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 1; + } + } + for(i = 0; i < read_bytes; i ++) + checksum += buf[i]; + printf("Update file size = %d\n", size); + } + if(flag_a){ + if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ + printf("[%s] Write sector failed", __FUNCTION__); + goto update_ota_exit; + } + size += 1; + } +#if CONFIG_WRITE_MAC_TO_FLASH + //Write MAC address + if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){ + if(flash_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Write MAC failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#endif + + // Write config sectors + address = CONFIG_SECTOR; + if( (flash_Wrtie(address, (char*)&size, 4) < 0) || + (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + printf("[%s] Update OTA success!\n", __FUNCTION__); +update_ota_exit: + if(buf) + update_free(buf); + if(server_socket >= 0) + close(server_socket); + if(param) + update_free(param); + TaskOTA = NULL; + printf("[%s] Update task exit\n", __FUNCTION__); + vTaskDelete(NULL); + return; +} + +#elif defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + +extern int osDelay (uint32_t millisec); + +void ota_platform_reset(void) +{ + //wifi_off(); + + // Set processor clock to default before system reset + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); + osDelay(100); + + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ + while(1) osDelay(1000); +} +#if WRITE_OTA_ADDR +int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr) +{ + uint32_t data, i = 0; + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(flash, OFFSET_DATA, &data); + printf("[%s] data 0x%x ota_addr 0x%x\n", __FUNCTION__, data, ota_addr); + if(data == ~0x0){ + flash_write_word(flash, OFFSET_DATA, ota_addr); + }else{ + //erase backup sector + flash_erase_sector(flash, BACKUP_SECTOR); + //backup system data to backup sector + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(flash, OFFSET_DATA + i, &data); + if(i == 0) + data = ota_addr; + flash_write_word(flash, BACKUP_SECTOR + i,data); + } + //erase system data + flash_erase_sector(flash, OFFSET_DATA); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(flash, BACKUP_SECTOR + i, &data); + flash_write_word(flash, OFFSET_DATA + i,data); + } + //erase backup sector + flash_erase_sector(flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + return 0; +} +#endif +static void update_ota_local_task(void *param) +{ + int server_socket; + struct sockaddr_in server_addr; + unsigned char *buf; + union { uint32_t u; unsigned char c[4]; } file_checksum; + int read_bytes = 0, size = 0, i = 0; + update_cfg_local_t *cfg = (update_cfg_local_t *)param; + uint32_t address, checksum = 0, flash_checksum=0; + flash_t flash; + uint32_t NewImg2BlkSize = 0, NewImg2Len = 0, NewImg2Addr = 0, file_info[3]; + uint32_t Img2Len = 0; + int ret = -1 ; + //uint8_t signature[8] = {0x38,0x31,0x39,0x35,0x38,0x37,0x31,0x31}; + uint32_t IMAGE_x = 0, ImgxLen = 0, ImgxAddr = 0; +#if WRITE_OTA_ADDR + uint32_t ota_addr = 0x80000; +#endif +#if CONFIG_CUSTOM_SIGNATURE + char custom_sig[32] = "Customer Signature-modelxxx\n"; + uint32_t read_custom_sig[8]; +#endif + printf("[%s] Update task start\n", __FUNCTION__); + buf = update_malloc(BUF_SIZE); + if(!buf){ + printf("[%s] Alloc buffer failed\n", __FUNCTION__); + goto update_ota_exit; + } + // Connect socket + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if(server_socket < 0){ + printf("[%s] Create socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = cfg->ip_addr; + server_addr.sin_port = cfg->port; + + if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){ + printf("[%s] socket connect failed\n", __FUNCTION__); + goto update_ota_exit; + } + DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_); + +#if 1 + // The upgraded image2 pointer must 4K aligned and should not overlap with Default Image2 + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, IMAGE_2, &Img2Len); + IMAGE_x = IMAGE_2 + Img2Len + 0x10; + flash_read_word(&flash, IMAGE_x, &ImgxLen); + flash_read_word(&flash, IMAGE_x+4, &ImgxAddr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + if(ImgxAddr==0x30000000){ + printf("[%s] IMAGE_3 0x%x Img3Len 0x%x\n", __FUNCTION__, IMAGE_x, ImgxLen); + }else{ + printf("[%s] no IMAGE_3\n", __FUNCTION__); + // no image3 + IMAGE_x = IMAGE_2; + ImgxLen = Img2Len; + } +#if WRITE_OTA_ADDR + if((ota_addr > IMAGE_x) && ((ota_addr < (IMAGE_x+ImgxLen))) || + (ota_addr < IMAGE_x) || + ((ota_addr & 0xfff) != 0)|| + (ota_addr == ~0x0)){ + printf("[%s] illegal ota addr 0x%x\n", __FUNCTION__, ota_addr); + goto update_ota_exit; + }else + write_ota_addr_to_system_data( &flash, ota_addr); +#endif + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, OFFSET_DATA, &NewImg2Addr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + if((NewImg2Addr > IMAGE_x) && ((NewImg2Addr < (IMAGE_x+ImgxLen))) || + (NewImg2Addr < IMAGE_x) || + ((NewImg2Addr & 0xfff) != 0)|| + (NewImg2Addr == ~0x0)){ + printf("[%s] Invalid OTA Address 0x%x\n", __FUNCTION__, NewImg2Addr); + goto update_ota_exit; + } +#else + //For test, hard code addr + NewImg2Addr = 0x80000; +#endif + + //Clear file_info + memset(file_info, 0, sizeof(file_info)); + + if(file_info[0] == 0){ + printf("[%s] Read info first\n", __FUNCTION__); + read_bytes = read(server_socket, file_info, sizeof(file_info)); + // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X + // !W checksum !W padding 0 !W file size !W + // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X + printf("[%s] info %d bytes", __FUNCTION__, read_bytes); + printf("[%s] tx chechsum 0x%x, file size 0x%x\n", __FUNCTION__, file_info[0],file_info[2]); + if(file_info[2] == 0){ + printf("[%s] No checksum and file size\n", __FUNCTION__); + goto update_ota_exit; + } + } + +#if SWAP_UPDATE + uint32_t SigImage0,SigImage1; + uint32_t Part1Addr=0xFFFFFFFF, Part2Addr=0xFFFFFFFF, ATSCAddr=0xFFFFFFFF; + uint32_t OldImg2Addr; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, 0x18, &Part1Addr); + Part1Addr = (Part1Addr&0xFFFF)*1024; // first partition + Part2Addr = NewImg2Addr; + + // read Part1/Part2 signature + flash_read_word(&flash, Part1Addr+8, &SigImage0); + flash_read_word(&flash, Part1Addr+12, &SigImage1); + printf("[%s] Part1 Sig %x\n", __FUNCTION__, SigImage0); + if(SigImage0==0x30303030 && SigImage1==0x30303030) + ATSCAddr = Part1Addr; // ATSC signature + else if(SigImage0==0x35393138 && SigImage1==0x31313738) + OldImg2Addr = Part1Addr; // newer version, change to older version + else + NewImg2Addr = Part1Addr; // update to older version + + flash_read_word(&flash, Part2Addr+8, &SigImage0); + flash_read_word(&flash, Part2Addr+12, &SigImage1); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("[%s] Part2 Sig %x\n", __FUNCTION__, SigImage0); + if(SigImage0==0x30303030 && SigImage1==0x30303030) + ATSCAddr = Part2Addr; // ATSC signature + else if(SigImage0==0x35393138 && SigImage1==0x31313738) + OldImg2Addr = Part2Addr; + else + NewImg2Addr = Part2Addr; + + // update ATSC clear partitin first + if(ATSCAddr != ~0x0){ + OldImg2Addr = NewImg2Addr; + NewImg2Addr = ATSCAddr; + } + + printf("[%s] New %x, Old %x\n", __FUNCTION__, NewImg2Addr, OldImg2Addr); + + if( NewImg2Addr==Part1Addr ){ + if( file_info[2] > (Part2Addr-Part1Addr) ){ // firmware size too large + printf("[%s] Part1 size < OTA size\n", __FUNCTION__); + goto update_ota_exit; + // or update to partition2 + // NewImg2Addr = Part2Addr; + } + } + +#endif + + //Erase upgraded image 2 region + if(NewImg2Len == 0){ + NewImg2Len = file_info[2]; + printf("[%s] NewImg2Len %d\n", __FUNCTION__, NewImg2Len); + if((int)NewImg2Len > 0){ + NewImg2BlkSize = ((NewImg2Len - 1)/4096) + 1; + printf("[%s] NewImg2BlkSize %d 0x%8x\n", __FUNCTION__, NewImg2BlkSize, NewImg2BlkSize); + device_mutex_lock(RT_DEV_LOCK_FLASH); + for( i = 0; i < NewImg2BlkSize; i++) + flash_erase_sector(&flash, NewImg2Addr + i * 4096); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + }else{ + printf("[%s] Size INVALID\n", __FUNCTION__); + goto update_ota_exit; + } + } + + printf("[%s] NewImg2Addr 0x%x\n", __FUNCTION__, NewImg2Addr); + + // reset + file_checksum.u = 0; + // Write New Image 2 sector + if(NewImg2Addr != ~0x0){ + address = NewImg2Addr; + printf(""); + while(1){ + memset(buf, 0, BUF_SIZE); + read_bytes = read(server_socket, buf, BUF_SIZE); + if(read_bytes == 0) break; // Read end + if(read_bytes < 0){ + printf("[%s] Read socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + checksum += file_checksum.c[0]; // not read end, this is not attached checksum + checksum += file_checksum.c[1]; + checksum += file_checksum.c[2]; + checksum += file_checksum.c[3]; + //printf("[%s] read_bytes %d", __FUNCTION__, read_bytes); + + #if 1 + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(flash_stream_write(&flash, address + size, read_bytes, buf) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto update_ota_exit; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + size += read_bytes; + for(i = 0; i < read_bytes-4; i ++) + checksum += buf[i]; + file_checksum.c[0] = buf[read_bytes-4]; // checksum attached at file end + file_checksum.c[1] = buf[read_bytes-3]; + file_checksum.c[2] = buf[read_bytes-2]; + file_checksum.c[3] = buf[read_bytes-1]; + #else + size += read_bytes; + for(i = 0; i < read_bytes-4; i ++){ + checksum += buf[i]; + } + file_checksum.c[0] = buf[read_bytes-4]; // checksum attached at file end + file_checksum.c[1] = buf[read_bytes-3]; + file_checksum.c[2] = buf[read_bytes-2]; + file_checksum.c[3] = buf[read_bytes-1]; + #endif + + if(size == NewImg2Len) + break; + } + printf("\n"); + + // read flash data back and calculate checksum + for(i=0;iBUF_SIZE?BUF_SIZE:(size-4-i); + flash_stream_read(&flash, NewImg2Addr+i, rlen, buf); + for(k=0;k= 0) + close(server_socket); + if(param) + update_free(param); + TaskOTA = NULL; + printf("[%s] Update task exit\n", __FUNCTION__); + if(!ret){ + printf("[%s] Ready to reboot\n", __FUNCTION__); + ota_platform_reset(); + } + vTaskDelete(NULL); + return; + +} +#endif + +//--------------------------------------------------------------------- +int update_ota_local(char *ip, int port) +{ + update_cfg_local_t *pUpdateCfg; + + if(TaskOTA){ + printf("[%s] Update task has created.\n", __FUNCTION__); + return 0; + } + pUpdateCfg = update_malloc(sizeof(update_cfg_local_t)); + if(pUpdateCfg == NULL){ + printf("[%s] Alloc update cfg failed\n", __FUNCTION__); + return -1; + } + pUpdateCfg->ip_addr = inet_addr(ip); + pUpdateCfg->port = ntohs(port); + + if(xTaskCreate(update_ota_local_task, "OTA_server\n", STACK_SIZE, pUpdateCfg, TASK_PRIORITY, &TaskOTA) != pdPASS){ + update_free(pUpdateCfg); + printf("[%s] Create update task failed\n", __FUNCTION__); + } + return 0; +} +#endif // #if (SERVER_TYPE == SERVER_LOCAL) + +//--------------------------------------------------------------------- +#if (SERVER_TYPE == SERVER_CLOUD) +#if defined(STM32F2XX) ||(STM32F4XX) +static void update_ota_cloud_task(void *param) +{ + struct updater_ctx ctx; + char *buf; + int read_bytes, size = 0, i; + uint32_t address, checksum = 0; + update_cfg_cloud_t *cfg = (update_cfg_cloud_t*)param; +#if CONFIG_WRITE_MAC_TO_FLASH + char mac[ETH_ALEN]; +#endif + printf("[%s] Update task start\n", __FUNCTION__); + buf = update_malloc(BUF_SIZE); + if(!buf){ + printf("[%s] Alloc buffer failed\n", __FUNCTION__); + goto update_ota_exit_1; + } + // Init ctx + if(updater_init_ctx(&ctx, (char*)cfg->repository, (char*)cfg->file_path) != 0) { + printf("[%s] Cloud ctx init failed\n", __FUNCTION__); + goto update_ota_exit_1; + } + printf("[%s] Firmware link: %s, size = %d bytes, checksum = 0x%08x, version = %s\n", __FUNCTION__, + ctx.link, ctx.size, ctx.checksum, ctx.version); + + // Erase config sectors + if(flash_EraseSector(CONFIG_SECTOR) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } +#if CONFIG_WRITE_MAC_TO_FLASH + // Read MAC address + if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Read MAC error\n", __FUNCTION__); + goto update_ota_exit; + } +#endif + // Erase update sectors + for(i = UPDATE_SECTOR; i <= FLASH_Sector_11; i += 8){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } + // Write update sectors + address = flash_SectorAddress(UPDATE_SECTOR); + printf("\n"); + while(ctx.bytes < ctx.size){ + read_bytes = updater_read_bytes(&ctx, (unsigned char*)buf, BUF_SIZE); + if(read_bytes == 0) break; // Read end + if(read_bytes < 0){ + printf("[%s] Read socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + if(flash_Wrtie(address + size, buf, read_bytes) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes; + for(i = 0; i < read_bytes; i ++) + checksum += buf[i]; + printf("\rUpdate file size = %d/%d bytes\n", ctx.bytes, ctx.size); + } + printf("[%s] ctx checksum = %08x, computed checksum = %08x\n", __FUNCTION__, ctx.checksum, checksum); + if(checksum != ctx.checksum){ + printf("[%s] Checksum error\n", __FUNCTION__); + goto update_ota_exit; + } +#if CONFIG_WRITE_MAC_TO_FLASH + //Write MAC address + if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){ + if(flash_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Write MAC failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#endif + // Write config sectors + address = flash_SectorAddress(CONFIG_SECTOR); + if( (flash_Wrtie(address, (char*)&size, 4) < 0) || + (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + printf("[%s] Update OTA success!\n", __FUNCTION__); + +update_ota_exit: + updater_free_ctx(&ctx); +update_ota_exit_1: + if(buf) + update_free(buf); + if(param) + update_free(param); + TaskOTA = NULL; + printf("[%s] Update task exit\n", __FUNCTION__); + vTaskDelete(NULL); + return; +} +#elif defined(STM32f1xx) +static void update_ota_cloud_task(void *param) +{ + struct updater_ctx ctx; + char *buf, flag_a = 0; + int read_bytes, size = 0, i; + uint32_t address, checksum = 0; + update_cfg_cloud_t *cfg = (update_cfg_cloud_t*)param; + uint16_t a = 0; +#if CONFIG_WRITE_MAC_TO_FLASH + char mac[ETH_ALEN]; +#endif + printf("[%s] Update task start\n", __FUNCTION__); + buf = update_malloc(BUF_SIZE); + if(!buf){ + printf("[%s] Alloc buffer failed\n", __FUNCTION__); + goto update_ota_exit_1; + } + // Init ctx + if(updater_init_ctx(&ctx, (char*)cfg->repository, (char*)cfg->file_path) != 0) { + printf("[%s] Cloud ctx init failed\n", __FUNCTION__); + goto update_ota_exit_1; + } + printf("[%s] Firmware link: %s, size = %d bytes, checksum = 0x%08x, version = %s\n", __FUNCTION__, + ctx.link, ctx.size, ctx.checksum, ctx.version); + + // Erase config sectors + for(i = CONFIG_SECTOR; i < APPLICATION_SECTOR; i += FLASH_PAGE_SIZE){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#if CONFIG_WRITE_MAC_TO_FLASH + // Read MAC address + if(flash_Read(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Read MAC error\n", __FUNCTION__); + goto update_ota_exit; + } +#endif + + // Erase update sectors + for(i = UPDATE_SECTOR; i < FLASH_Sector_0 + FLASH_SIZE; i += FLASH_PAGE_SIZE){ + if(flash_EraseSector(i) < 0){ + printf("[%s] Erase sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + } + // Write update sectors + address = UPDATE_SECTOR; + printf("\n"); + while(ctx.bytes < ctx.size){ + read_bytes = updater_read_bytes(&ctx, (unsigned char*)buf, BUF_SIZE); + if(read_bytes == 0) break; // Read end + if(read_bytes < 0){ + printf("[%s] Read socket failed\n", __FUNCTION__); + goto update_ota_exit; + } + if(flag_a == 0){ + if(read_bytes % 2 != 0){ + a = buf[read_bytes - 1]; + flag_a = 1; + if(flash_Wrtie(address + size, buf, read_bytes - 1) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 1; + } + else{ + if(flash_Wrtie(address + size, buf, read_bytes) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes; + } + } + else{ + a = buf[0]<< 8 |a; + if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += 2; + a = 0; + flag_a = 0; + if((read_bytes - 1) % 2 != 0){ + a = buf[read_bytes - 1]; + flag_a = 1; + if(flash_Wrtie(address + size, buf + 1, read_bytes - 2) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 2; + } + else{ + if(flash_Wrtie(address + size, buf + 1, read_bytes - 1) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += read_bytes - 1; + } + } + for(i = 0; i < read_bytes; i ++) + checksum += buf[i]; + printf("\rUpdate file size = %d/%d bytes\n", ctx.bytes, ctx.size); + } + if(flag_a){ + if(flash_Wrtie(address + size, (char*)(&a), 2) < 0){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + size += 1; + } + printf("[%s] ctx checksum = %08x, computed checksum = %08x\n", __FUNCTION__, ctx.checksum, checksum); + if(checksum != ctx.checksum){ + printf("[%s] Checksum error\n", __FUNCTION__); + goto update_ota_exit; + } +#if CONFIG_WRITE_MAC_TO_FLASH + //Write MAC address + if(!(mac[0]==0xff&&mac[1]==0xff&&mac[2]==0xff&&mac[3]==0xff&&mac[4]==0xff&&mac[5]==0xff)){ + if(flash_Wrtie(FLASH_ADD_STORE_MAC, mac, ETH_ALEN) < 0){ + printf("[%s] Write MAC failed\n", __FUNCTION__); + goto update_ota_exit; + } + } +#endif + + // Write config sectors + address = CONFIG_SECTOR; + if( (flash_Wrtie(address, (char*)&size, 4) < 0) || + (flash_Wrtie(address+4, (char*)&checksum, 4) < 0) ){ + printf("[%s] Write sector failed\n", __FUNCTION__); + goto update_ota_exit; + } + printf("[%s] Update OTA success!\n", __FUNCTION__); + +update_ota_exit: + updater_free_ctx(&ctx); +update_ota_exit_1: + if(buf) + update_free(buf); + if(param) + update_free(param); + TaskOTA = NULL; + printf("[%s] Update task exit\n", __FUNCTION__); + vTaskDelete(NULL); + return; +} + +#endif + +//--------------------------------------------------------------------- +int update_ota_cloud(char *repository, char *file_path) +{ + update_cfg_cloud_t *pUpdateCfg; + + if(TaskOTA){ + printf("[%s] Update task has created.\n", __FUNCTION__); + return 0; + } + pUpdateCfg = update_malloc(sizeof(update_cfg_cloud_t)); + if(pUpdateCfg == NULL){ + printf("[%s] Alloc update cfg failed.\n", __FUNCTION__); + goto exit; + } + if(strlen(repository) > (REPOSITORY_LEN-1)){ + printf("[%s] Repository length is too long.\n", __FUNCTION__); + goto exit; + } + if(strlen(file_path) > (FILE_PATH_LEN-1)){ + printf("[%s] File path length is too long.\n", __FUNCTION__); + goto exit; + } + strcpy((char*)pUpdateCfg->repository, repository); + strcpy((char*)pUpdateCfg->file_path, file_path); + + if(xTaskCreate(update_ota_cloud_task, "OTA_server", STACK_SIZE, pUpdateCfg, TASK_PRIORITY, &TaskOTA) != pdPASS){ + printf("[%s] Create update task failed\n", __FUNCTION__); + goto exit; + } + +exit: + update_free(pUpdateCfg); + return 0; +} +#endif // #if (SERVER_TYPE == SERVER_CLOUD) + +//--------------------------------------------------------------------- +void cmd_update(int argc, char **argv) +{ +// printf("[%s] Firmware A", __FUNCTION__); +#if (SERVER_TYPE == SERVER_LOCAL) + int port; + if(argc != 3){ + printf("[%s] Usage: update IP PORT\n", __FUNCTION__); + return; + } + port = atoi(argv[2]); + update_ota_local(argv[1], port); +#endif +#if (SERVER_TYPE == SERVER_CLOUD) + if(argc != 3){ + printf("[%s] Usage: update REPOSITORY FILE_PATH\n", __FUNCTION__); + return; + } + update_ota_cloud(argv[1], argv[2]); +#endif +} + +// chose to boot ota image or not +void cmd_ota_image(bool cmd){ + flash_t flash; + uint32_t Part1Addr = 0xFFFFFFFF,Part2Addr = 0xFFFFFFFF; + uint8_t *pbuf = NULL; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, 0x18, &Part1Addr); + Part1Addr = (Part1Addr&0xFFFF)*1024; // first partition + flash_read_word(&flash, OFFSET_DATA, &Part2Addr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + if(Part2Addr == ~0x0) + return; + + pbuf = update_malloc(FLASH_SECTOR_SIZE); + if(!pbuf) return; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf); + if (cmd == 1) + memcpy((char*)pbuf+8, IMG_SIGN_RUN, 8); + else + memcpy((char*)pbuf+8, IMG_SIGN_SWP, 8); + + flash_erase_sector(&flash, Part2Addr); + flash_stream_write(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + +#if SWAP_UPDATE + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf); + if (cmd == 1) + memcpy((char*)pbuf+8, IMG_SIGN_SWP, 8); + else + memcpy((char*)pbuf+8, IMG_SIGN_RUN, 8); + + flash_erase_sector(&flash, Part1Addr); + flash_stream_write(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif + update_free(pbuf); +} +//--------------------------------------------------------------------- + +#endif // LWIP_SOCKET diff --git a/USDK/component/common/utilities/update.h b/USDK/component/common/utilities/update.h new file mode 100644 index 0000000..cc5e90e --- /dev/null +++ b/USDK/component/common/utilities/update.h @@ -0,0 +1,11 @@ +#ifndef UPDATE_H +#define UPDATE_H + +//-------------------------------------------------------------------------- +int update_ota_local(char *ip, int port); +int update_ota_cloud(char *repository, char *file_path); +void cmd_update(int argc, char **argv); +void cmd_ota_image(bool cmd); + +//---------------------------------------------------------------------------- +#endif diff --git a/USDK/component/common/utilities/webserver.c b/USDK/component/common/utilities/webserver.c new file mode 100644 index 0000000..ffaed07 --- /dev/null +++ b/USDK/component/common/utilities/webserver.c @@ -0,0 +1,1378 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + Implements a simplistic WEB server. Every time a connection is made and + data is received a dynamic page that shows the current TCP/IP statistics + is generated and returned. The connection is then closed. + + This file was adapted from a FreeRTOS lwIP slip demo supplied by a third + party. +*/ + +/* ------------------------ System includes ------------------------------- */ + + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/ip.h" +#include "lwip/memp.h" +#include "lwip/stats.h" +#include "netif/loopif.h" + +/* ------------------------ Project includes ------------------------------ */ +#include +#include "main.h" + +#include "webserver.h" +#include "wlan_intf.h" + + +#define CONFIG_READ_FLASH 1 + + +#ifdef CONFIG_READ_FLASH + +#ifndef CONFIG_PLATFORM_AMEBA_X + +#include +#if defined(STM32F2XX) +#include +#elif defined(STM32F4XX) +#include +#elif defined(STM32f1xx) +#include +#endif + +#else +#include "flash_api.h" +#include "flash_eep.h" +#include "feep_config.h" +#include "device_lock.h" + +#ifndef FEEP_ID_WIFI_AP_CFG +#define FEEP_ID_WIFI_AP_CFG 0x5731 +#endif + +#define DATA_SECTOR AP_SETTING_SECTOR +#define BACKUP_SECTOR (0x00008000) + +#endif +#endif +/* ------------------------ Defines --------------------------------------- */ +/* The size of the buffer in which the dynamic WEB page is created. */ +#define webMAX_PAGE_SIZE (3200/* 2800 */) /*FSL: buffer containing array*/ +#define LOCAL_BUF_SIZE 800 +#define AP_SETTING_ADDR AP_SETTING_SECTOR +/* Standard GET response. */ +#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" + +/* The port on which we listen. */ +#define webHTTP_PORT ( 80 ) + +/* Delay on close error. */ +#define webSHORT_DELAY ( 10 ) + +#define USE_DIV_CSS 1 + +#if USE_DIV_CSS + +/* Format of the dynamic page that is returned on each connection. */ +#define webHTML_HEAD_START \ +"\ +\ +" +/* +\ +\ +\ +*/ + +#define webHTML_TITLE \ +"Realtek SoftAP Config UI" + +#define webHTML_BODY_START \ +"\ +\ +
\ +
\ +
\ +Realtek SoftAP Configuration\ +
" + + + +#define webHTML_CSS \ +"" + + + +#define webHTML_END \ +"
\ +\ +
\ +
\ +Copyright ©realtek.com\ +
\ +
\ +
\ +\ +\ +" + +#define webWaitHTML_START \ +"\ +\ +" +#define webWaitHTML_END \ +"\ +\ +

\ +

SoftAP is now restarting!

\ +

Please wait a moment and reconnect!

\ +

"\ +"\r\n" \ +"" + +#define onChangeSecType \ +"" + +#define onSubmitForm \ +"" + + + +#else + + +/* Format of the dynamic page that is returned on each connection. */ +#define webHTML_HEAD_START \ +"\ +\ +" +/* +\ +\ +\ +*/ + +#define webHTML_BODY_START \ +"\ +\ +\r\n\r\n
\ +\ +\ +\ +" + +#define webHTML_END \ +"\ +\ +\ +\ +\ +\ +
\ +

Realtek SoftAP Configuration

\ +
\ +
\ +Copyright ?realtek.com
\ +\r\n
" \ +"\r\n" \ +"" + +#define webWaitHTML_START \ +"\ +\ +" +#define webWaitHTML_END \ +"\ +\ +

\ +

SoftAP is now restarting!

\ +

Please wait a moment and reconnect!

\ +

"\ +"\r\n" \ +"" + +#define onChangeSecType \ +"" + +#define onSubmitForm \ +"" + + + + +#endif + + + + +/* +alert(\"Please enter your password!\");\ +return false;\ +}\ +if(z.value.length < 8)\ +{\ +alert(\"Your password is too short!(8-64)\");\ +return false;\ +}\ +if(z.value.length>64)\ +{\ +alert(\"Your password is too long!(8-64)\");\ +*/ + +#define MAX_SOFTAP_SSID_LEN 32 +#define MAX_PASSWORD_LEN 64 +#define MAX_CHANNEL_NUM 13 + +#if INCLUDE_uxTaskGetStackHighWaterMark + static volatile unsigned portBASE_TYPE uxHighWaterMark_web = 0; +#endif + +/* ------------------------ Prototypes ------------------------------------ */ +static void vProcessConnection( struct netconn *pxNetCon ); + +/*------------------------------------------------------------------------------*/ +/* GLOBALS */ +/*------------------------------------------------------------------------------*/ +rtw_wifi_setting_t wifi_setting = {RTW_MODE_NONE, {0}, 0, RTW_SECURITY_OPEN, {0}}; + + + + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif + +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif + +static void LoadWifiSetting() +{ + const char *ifname = WLAN0_NAME; + + if(rltk_wlan_running(WLAN1_IDX)) + {//STA_AP_MODE + ifname = WLAN1_NAME; + } + + wifi_get_setting(ifname, &wifi_setting); + + //printf("\r\nLoadWifiSetting(): wifi_setting.ssid=%s\n", wifi_setting.ssid); + //printf("\r\nLoadWifiSetting(): wifi_setting.channel=%d\n", wifi_setting.channel); + //printf("\r\nLoadWifiSetting(): wifi_setting.security_type=%d\n", wifi_setting.security_type); + //printf("\r\nLoadWifiSetting(): wifi_setting.password=%s\n", wifi_setting.password); +} + +#if CONFIG_READ_FLASH +#ifndef CONFIG_PLATFORM_AMEBA_X +void LoadWifiConfig() +{ + rtw_wifi_config_t local_config; + uint32_t address; +#ifdef STM32F10X_XL + address = 0x08080000; //bank2 domain +#else + uint16_t sector_nb = FLASH_Sector_11; + address = flash_SectorAddress(sector_nb); +#endif + printf("\r\nLoadWifiConfig(): Read from FLASH!\n"); + flash_Read(address, (char *)&local_config, sizeof(local_config)); + + printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode); + printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid); + printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel); + printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type); + printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password); + + if(local_config.boot_mode == 0x77665502) + { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + wifi_setting.security_type = local_config.security_type; + if(local_config.password_len > 64) + local_config.password_len = 64; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else + { + LoadWifiSetting(); + } +} + +int StoreApInfo() +{ +#ifdef USE_FLASH_EEP + rtw_wifi_config_t wifi_config; + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + if(wifi_setting.security_type !=0) + wifi_config.security_type = 1; + else + wifi_config.security_type = 0; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); + flash_write_cfg((uint8_t *)(&wifi_config), FEEP_ID_WIFI_AP_CFG, sizeof(wifi_config)); +#else + rtw_wifi_config_t wifi_config; + uint32_t address; +#ifdef STM32F10X_XL + address = 0x08080000; //bank2 domain +#else + uint16_t sector_nb = FLASH_Sector_11; + address = flash_SectorAddress(sector_nb); +#endif + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); +#ifdef STM32F10X_XL + FLASH_ErasePage(address); +#else + flash_EraseSector(sector_nb); +#endif + flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t)); +#endif // USE_FLASH_EEP + return 0; +} + + +#else + +void LoadWifiConfig() +{ + rtw_wifi_config_t local_config; + local_config.boot_mode = 0; + +#ifdef USE_FLASH_EEP + if(flash_read_cfg((uint8_t *)(&local_config), FEEP_ID_WIFI_AP_CFG, sizeof(rtw_wifi_config_t)) >= sizeof(rtw_wifi_config_t)) { + printf("%s: Read from FLASH!\n", __FUNCTION__); + printf("%s: local_config.boot_mode=0x%x\n", __FUNCTION__, local_config.boot_mode); + printf("%s: local_config.ssid=%s\n", __FUNCTION__, local_config.ssid); + printf("%s: local_config.channel=%d\n", __FUNCTION__, local_config.channel); + printf("%s: local_config.security_type=%d\n", __FUNCTION__, local_config.security_type); + printf("%s: local_config.password=%s\n", __FUNCTION__, local_config.password); + } + if(local_config.boot_mode == 0x77665502) { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + if(local_config.security_type == 1) + wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK; + else + wifi_setting.security_type = RTW_SECURITY_OPEN; + if(local_config.password_len > 32) + local_config.password_len = 32; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else { + LoadWifiSetting(); + } + +#else + + flash_t flash; + + uint32_t address; + + address = DATA_SECTOR; + + + //memset(&local_config,0,sizeof(rtw_wifi_config_t)); + printf("\r\nLoadWifiConfig(): Read from FLASH!\n"); + // flash_Read(address, &local_config, sizeof(local_config)); + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),(uint8_t *)(&local_config)); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode); + printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid); + printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel); + printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type); + printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password); + + if(local_config.boot_mode == 0x77665502) + { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + if(local_config.security_type == 1) + wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK; + else + wifi_setting.security_type = RTW_SECURITY_OPEN; + if(local_config.password_len > 64) + local_config.password_len = 64; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else + { + LoadWifiSetting(); + } +#endif // USE_FLASH_EEP +} + +int StoreApInfo() +{ +#ifdef USE_FLASH_EEP + rtw_wifi_config_t wifi_config; + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + if(wifi_setting.security_type !=0) + wifi_config.security_type = 1; + else + wifi_config.security_type = 0; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); + flash_write_cfg((uint8_t *)(&wifi_config), FEEP_ID_WIFI_AP_CFG, sizeof(wifi_config)); +#else + + flash_t flash; + + rtw_wifi_config_t wifi_config; + uint32_t address; + uint32_t data,i = 0; + + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + + address = DATA_SECTOR; + + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + if(wifi_setting.security_type !=0) + wifi_config.security_type = 1; + else + wifi_config.security_type = 0; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); + //printf("\n\r &wifi_config = 0x%x",&wifi_config); + + flash_read_word(&flash,address,&data); + + + if(data == ~0x0){ + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + }else{ + //flash_EraseSector(sector_nb); + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash,BACKUP_SECTOR); + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, DATA_SECTOR + i, &data); + if(i < sizeof(rtw_wifi_config_t)) + { + memcpy(&data,(char *)(&wifi_config) + i,4); + //printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i)); + //printf("\n\r Data = %d",data); + } + flash_write_word(&flash, BACKUP_SECTOR + i,data); + } + flash_read_word(&flash,BACKUP_SECTOR + 68,&data); + //printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data); + //erase system data + flash_erase_sector(&flash, DATA_SECTOR); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, BACKUP_SECTOR + i, &data); + flash_write_word(&flash, DATA_SECTOR + i,data); + } + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + //flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t)); + //flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); + //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); + //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); + //printf("\n\r Base + 0x000FF000 +4 wifi config = %s",data[4]); + //printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]); + +#endif // USE_FLASH_EEP + return 0; +} + +int EraseApinfo(){ +#ifdef USE_FLASH_EEP + flash_write_cfg(NULL, FEEP_ID_WIFI_AP_CFG, 0); +#else + + flash_t flash; + uint32_t address; + + address = DATA_SECTOR; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash, address); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif // USE_FLASH_EEP + return 0; +} +#endif + +#endif + +static void RestartSoftAP() +{ + //printf("\r\nRestartAP: ssid=%s", wifi_setting.ssid); + //printf("\r\nRestartAP: ssid_len=%d", strlen((char*)wifi_setting.ssid)); + //printf("\r\nRestartAP: security_type=%d", wifi_setting.security_type); + //printf("\r\nRestartAP: password=%s", wifi_setting.password); + //printf("\r\nRestartAP: password_len=%d", strlen((char*)wifi_setting.password)); + //printf("\r\nRestartAP: channel=%d\n", wifi_setting.channel); + wifi_restart_ap(wifi_setting.ssid, + wifi_setting.security_type, + wifi_setting.password, +// strlen((char*)wifi_setting.ssid), +// strlen((char*)wifi_setting.password), + wifi_setting.channel); +} + + +u32 web_atoi(char* s) +{ + int num=0,flag=0; + int i; + + for(i=0;i<=strlen(s);i++) + { + if(s[i] >= '0' && s[i] <= '9') + num = num * 10 + s[i] -'0'; + else if(s[0] == '-' && i==0) + flag =1; + else + break; + } + + if(flag == 1) + num = num * -1; + + return(num); +} + +static void CreateSsidTableItem(char *pbuf, u8_t *ssid, u8_t ssid_len) +{ + char local_ssid[MAX_SOFTAP_SSID_LEN+1]; + + if(ssid_len > MAX_SOFTAP_SSID_LEN) + ssid_len = MAX_SOFTAP_SSID_LEN; + memcpy(local_ssid, ssid, ssid_len); + local_ssid[ssid_len] = '\0'; + +#if USE_DIV_CSS + sprintf(pbuf, "
SoftAP SSID:
" \ + "
", + local_ssid); +#else + sprintf(pbuf, "" + "" + "SoftAP SSID:
" + "" + "" + "
" + "" + "", + local_ssid); + +#endif + //printf("\r\nstrlen(SsidTableItem)=%d\n", strlen(pbuf)); +} + +static void CreateSecTypeTableItem(char *pbuf, u32_t sectype) +{ + u8_t flag[2] = {0, 0}; + + if(sectype == RTW_SECURITY_OPEN) + flag[0] = 1; + else if(sectype == RTW_SECURITY_WPA2_AES_PSK) + flag[1] = 1; + else + return; + +#if USE_DIV_CSS + sprintf(pbuf, "
Security Type:
"\ + "
", + flag[0]?"selected":"", + flag[1]?"selected":""); +#else + sprintf(pbuf, "" + "" + "Security Type:
" + "" + "" + "" + "" + "", + flag[0]?"selected":"", + flag[1]?"selected":""); + + +#endif + + //printf("\r\nstrlen(SecTypeTableItem)=%d\n", strlen(pbuf)); +} + +static void CreatePasswdTableItem(char *pbuf, u8_t *password, u8_t passwd_len) +{ + char local_passwd[MAX_PASSWORD_LEN+1]; + + if(passwd_len > MAX_PASSWORD_LEN) + passwd_len = MAX_PASSWORD_LEN; + if(passwd_len > 0) + { + memcpy(local_passwd, password, passwd_len); + local_passwd[passwd_len] = '\0'; + } + +#if USE_DIV_CSS + + sprintf(pbuf, "
Password:
"\ + "
"\ + ""\ + "
", + passwd_len?local_passwd:""); +#else + sprintf(pbuf, "" + "" + "Password:
" + "" + "" + "
" + "" + "", + passwd_len?local_passwd:""); + + +#endif + + + //printf("\r\nstrlen(passwordTableItem)=%d\n", strlen(pbuf)); +} + +static void CreateChannelTableItem(char *pbuf, u8_t channel) +{ + u8_t flag[MAX_CHANNEL_NUM+1] = {0}; + + if(channel > MAX_CHANNEL_NUM){ + printf("Channel(%d) is out of range!\n", channel); + channel = 1; + } + flag[channel] = 1; + +#if USE_DIV_CSS + + sprintf(pbuf, "
Channel:
" + "
", + + flag[1]?"selected":"", + flag[2]?"selected":"", + flag[3]?"selected":"", + flag[4]?"selected":"", + flag[5]?"selected":"", + flag[6]?"selected":"", + flag[7]?"selected":"", + flag[8]?"selected":"", + flag[9]?"selected":"", + flag[10]?"selected":"", + flag[11]?"selected":""); +#else + sprintf(pbuf, "" + "" + "Channel:
" + "" + "" + "" + "" + "", + flag[1]?"selected":"", + flag[2]?"selected":"", + flag[3]?"selected":"", + flag[4]?"selected":"", + flag[5]?"selected":"", + flag[6]?"selected":"", + flag[7]?"selected":"", + flag[8]?"selected":"", + flag[9]?"selected":"", + flag[10]?"selected":"", + flag[11]?"selected":""); + + +#endif + + //printf("\r\nstrlen(ChannelTableItem)=%d\n", strlen(pbuf)); +} + +static void GenerateIndexHtmlPage(portCHAR* cDynamicPage, portCHAR *LocalBuf) +{ + /* Generate the page index.html... + ... First the page header. */ + strcpy( cDynamicPage, webHTML_HEAD_START ); + + /* Add script */ + strcat( cDynamicPage, onChangeSecType ); + strcat( cDynamicPage, onSubmitForm); +#if USE_DIV_CSS + /* add css */ + strcat( cDynamicPage, webHTML_CSS); + + strcat( cDynamicPage, webHTML_TITLE); +#endif + /* Add Body start */ + strcat( cDynamicPage, webHTML_BODY_START ); + + /* Add SSID */ + CreateSsidTableItem(LocalBuf, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + strcat( cDynamicPage, LocalBuf ); + + /* Add SECURITY TYPE */ + CreateSecTypeTableItem(LocalBuf, wifi_setting.security_type); + strcat( cDynamicPage, LocalBuf ); + + /* Add PASSWORD */ + CreatePasswdTableItem(LocalBuf, wifi_setting.password, strlen((char*)wifi_setting.password)); + strcat( cDynamicPage, LocalBuf ); + + /* Add CHANNEL */ + CreateChannelTableItem(LocalBuf, wifi_setting.channel); + strcat( cDynamicPage, LocalBuf ); + + /* ... Finally the page footer. */ + strcat( cDynamicPage, webHTML_END ); + //printf("\r\nGenerateIndexHtmlPage(): %s\n", cDynamicPage); + printf("\r\nGenerateIndexHtmlPage Len: %d\n", strlen( cDynamicPage )); +} + +static void GenerateWaitHtmlPage(portCHAR* cDynamicPage) +{ + /* Generate the dynamic page... + ... First the page header. */ + strcpy( cDynamicPage, webWaitHTML_START ); + + /* ... Finally the page footer. */ + strcat( cDynamicPage, webWaitHTML_END); + + //printf("\r\nGenerateWaitHtmlPage(): %s\n", cDynamicPage); + //printf("\r\nGenerateWaitHtmlPage Len: %d\n", strlen( cDynamicPage )); +} + +static void http_translate_url_encode(char *ptr) +{ + + char *data = ptr; + char tmp_data[3] = {0}; + char outdata[33] = {0}; + int buffer; + char *outdata_ptr = outdata; + + while (*data != '\0') { + + if (*data == '%') { + if ((*(data + 1) != 0) && (*(data + 2) != 0)) { + tmp_data[0] = *(data + 1); + tmp_data[1] = *(data + 2); + sscanf(tmp_data, "%x", &buffer); + *outdata_ptr = (char)buffer; + + /* destroy data */ + *data = 0; + *(data+1) = 0; + *(data+2) = 0; + + data += 2; + outdata_ptr++; + } + + } else { + *outdata_ptr = *data; + if (*data == '+') + *outdata_ptr = ' '; + outdata_ptr++; + } + data++; + } + strcpy(ptr, outdata); + +} + +static u8_t ProcessPostMessage(struct netbuf *pxRxBuffer, portCHAR *LocalBuf) +{ + struct pbuf *p; + portCHAR *pcRxString, *ptr; + unsigned portSHORT usLength; + u8_t bChanged = 0; + rtw_security_t secType; + u8_t channel; + u8_t len = 0; + + pcRxString = LocalBuf; + p = pxRxBuffer->p; + usLength = p->tot_len; + //printf("\r\n !!!!!!!!!POST!p->tot_len =%d p->len=%d\n", p->tot_len, p->len); + while(p) + { + memcpy(pcRxString, p->payload, p->len); + pcRxString += p->len; + p = p->next; + } + pcRxString = LocalBuf; + pcRxString[usLength] = '\0'; + //printf("\r\n usLength=%d pcRxString = %s\n", usLength, pcRxString); + + ptr = (char*)strstr(pcRxString, "Ssid="); + if(ptr) + { + //printf("ssid passed = %s\n", ptr); + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 5; + http_translate_url_encode(ptr); + if(strcmp((char*)wifi_setting.ssid, ptr)) + { + bChanged = 1; + len = strlen(ptr); + if(len > MAX_SOFTAP_SSID_LEN){ + len = MAX_SOFTAP_SSID_LEN; + ptr[len] = '\0'; + } + strcpy((char*)wifi_setting.ssid, ptr); + } + } + + + printf("\r\n get wifi_config.ssid = %s\n", wifi_setting.ssid); + ptr = (char*)strstr(pcRxString, "Security+Type="); + if(ptr) + { + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 14; + if(!strcmp(ptr, "open")) + secType = RTW_SECURITY_OPEN; + else if(!strcmp(ptr, "wpa2-aes")) + secType = RTW_SECURITY_WPA2_AES_PSK; + else + secType = RTW_SECURITY_OPEN; + if(wifi_setting.security_type != secType) + { + bChanged = 1; + wifi_setting.security_type = secType; + } + } + + //printf("\r\n wifi_config.security_type = %d\n", wifi_setting.security_type); + if(wifi_setting.security_type > RTW_SECURITY_OPEN) + { + ptr = (char*)strstr(pcRxString, "Password="); + if(ptr) + { + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 9; + if(strcmp((char*)wifi_setting.password, ptr)) + { + bChanged = 1; + len = strlen(ptr); + if(len > MAX_PASSWORD_LEN){ + len = MAX_PASSWORD_LEN; + ptr[len] = '\0'; + } + strcpy((char*)wifi_setting.password, ptr); + } + } + //printf("\r\n wifi_config.password = %s\n", wifi_setting.password); + } + ptr = (char*)strstr(pcRxString, "Channel="); + if(ptr) + { + ptr += 8; + channel = web_atoi(ptr); + if((channel>MAX_CHANNEL_NUM)||(channel < 1)) + channel = 1; + if(wifi_setting.channel !=channel) + { + bChanged = 1; + wifi_setting.channel = channel; + } + } + //printf("\r\n wifi_config.channel = %d\n", wifi_setting.channel); + + return bChanged; +} + +struct netconn *pxHTTPListener = NULL; +static void vProcessConnection( struct netconn *pxNetCon ) +{ + static portCHAR cDynamicPage[webMAX_PAGE_SIZE]; + struct netbuf *pxRxBuffer, *pxRxBuffer1 = NULL; + portCHAR *pcRxString; + unsigned portSHORT usLength; + static portCHAR LocalBuf[LOCAL_BUF_SIZE]; + u8_t bChanged = 0; + int ret_recv = ERR_OK; + int ret_accept = ERR_OK; + char *ptr = NULL; + + /* Load WiFi Setting*/ + LoadWifiSetting(); + + /* We expect to immediately get data. */ + port_netconn_recv( pxNetCon , pxRxBuffer, ret_recv); + + if( pxRxBuffer != NULL && ret_recv == ERR_OK) + { + /* Where is the data? */ + netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength ); + + //printf("\r\nusLength=%d pcRxString = \n%s\n", usLength, pcRxString); + /* Is this a GET? We don't handle anything else. */ + if( !strncmp( pcRxString, "GET", 3 ) ) + { + //printf("\r\nusLength=%d pcRxString=%s \n", usLength, pcRxString); + //pcRxString = cDynamicPage; + + /* Write out the HTTP OK header. */ + netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY ); + + /* Generate index.html page. */ + GenerateIndexHtmlPage(cDynamicPage, LocalBuf); + + /* Write out the dynamically generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + } + else if(!strncmp( pcRxString, "POST", 4 ) ) + { + /* Write out the HTTP OK header. */ + netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY ); + + bChanged = ProcessPostMessage(pxRxBuffer, LocalBuf); + if(bChanged == 0){ + port_netconn_recv( pxNetCon , pxRxBuffer1, ret_recv); + if(pxRxBuffer != NULL && ret_recv == ERR_OK){ + bChanged = ProcessPostMessage(pxRxBuffer1, LocalBuf); + netbuf_delete( pxRxBuffer1 ); + } + } + if(bChanged) + { + GenerateWaitHtmlPage(cDynamicPage); + + /* Write out the generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif + } + else + { + /* Generate index.html page. */ + GenerateIndexHtmlPage(cDynamicPage, LocalBuf); + + /* Write out the generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + } + } + netbuf_delete( pxRxBuffer ); + } + netconn_close( pxNetCon ); + + if(bChanged) + { + struct netconn *pxNewConnection; + vTaskDelay(200/portTICK_RATE_MS); + //printf("\r\n%d:before restart ap\n", xTaskGetTickCount()); + RestartSoftAP(); + //printf("\r\n%d:after restart ap\n", xTaskGetTickCount()); + pxHTTPListener->recv_timeout = 1; + port_netconn_accept( pxHTTPListener , pxNewConnection, ret_accept); + if( pxNewConnection != NULL && ret_accept == ERR_OK) + { + //printf("\r\n%d: got a conn\n", xTaskGetTickCount()); + netconn_close( pxNewConnection ); + while( netconn_delete( pxNewConnection ) != ERR_OK ) + { + vTaskDelay( webSHORT_DELAY ); + } + } + //printf("\r\n%d:end\n", xTaskGetTickCount()); + pxHTTPListener->recv_timeout = 0; + } +} + +/*------------------------------------------------------------*/ +xTaskHandle webs_task = NULL; +xSemaphoreHandle webs_sema = NULL; +u8_t webs_terminate = 0; +void vBasicWEBServer( void *pvParameters ) +{ + struct netconn *pxNewConnection; + //struct ip_addr xIpAddr, xNetMast, xGateway; + extern err_t ethernetif_init( struct netif *netif ); + int ret = ERR_OK; + /* Parameters are not used - suppress compiler error. */ + ( void )pvParameters; + + /* Create a new tcp connection handle */ + pxHTTPListener = netconn_new( NETCONN_TCP ); + ip_set_option(pxHTTPListener->pcb.ip, SOF_REUSEADDR); + netconn_bind( pxHTTPListener, NULL, webHTTP_PORT ); + netconn_listen( pxHTTPListener ); + +#if CONFIG_READ_FLASH + /* Load wifi_config */ + LoadWifiConfig(); + RestartSoftAP(); +#endif + //printf("\r\n-0\n"); + + /* Loop forever */ + for( ;; ) + { + if(webs_terminate) + break; + + //printf("\r\n%d:-1\n", xTaskGetTickCount()); + /* Wait for connection. */ + port_netconn_accept( pxHTTPListener , pxNewConnection, ret); + //printf("\r\n%d:-2\n", xTaskGetTickCount()); + + if( pxNewConnection != NULL && ret == ERR_OK) + { + /* Service connection. */ + vProcessConnection( pxNewConnection ); + while( netconn_delete( pxNewConnection ) != ERR_OK ) + { + vTaskDelay( webSHORT_DELAY ); + } + } + //printf("\r\n%d:-3\n", xTaskGetTickCount()); + } + //printf("\r\n-4\n"); + if(pxHTTPListener) + { + netconn_close(pxHTTPListener); + netconn_delete(pxHTTPListener); + pxHTTPListener = NULL; + } + + //printf("\r\nExit Web Server Thread!\n"); + xSemaphoreGive(webs_sema); +} + +#define STACKSIZE 512 +void start_web_server() +{ + printf("\r\nWEB:Enter start web server!\n"); + webs_terminate = 0; + if(webs_task == NULL) + { + if(xTaskCreate(vBasicWEBServer, (const char *)"web_server", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, &webs_task) != pdPASS) + printf("\n\rWEB: Create webserver task failed!\n"); + } + if(webs_sema == NULL) + { + webs_sema = xSemaphoreCreateCounting(0xffffffff, 0); //Set max count 0xffffffff + } + //printf("\r\nWEB:Exit start web server!\n"); +} + +void stop_web_server() +{ + //printf("\r\nWEB:Enter stop web server!\n"); + webs_terminate = 1; + if(pxHTTPListener) + netconn_abort(pxHTTPListener); + if(webs_sema) + { + if(xSemaphoreTake(webs_sema, 15 * configTICK_RATE_HZ) != pdTRUE) + { + if(pxHTTPListener) + { + netconn_close(pxHTTPListener); + netconn_delete(pxHTTPListener); + pxHTTPListener = NULL; + } + printf("\r\nWEB: Take webs sema(%p) failed!!!!!!!!!!!\n", webs_sema); + } + vSemaphoreDelete(webs_sema); + webs_sema = NULL; + } + if(webs_task) + { + vTaskDelete(webs_task); + webs_task = NULL; + } + printf("\r\nWEB:Exit stop web server!\n"); +} diff --git a/USDK/component/common/utilities/webserver.h b/USDK/component/common/utilities/webserver.h new file mode 100644 index 0000000..2586881 --- /dev/null +++ b/USDK/component/common/utilities/webserver.h @@ -0,0 +1,72 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +#ifndef BASIC_WEB_SERVER_H +#define BASIC_WEB_SERVER_H + +#include +/*------------------------------------------------------------------------------*/ +/* MACROS */ +/*------------------------------------------------------------------------------*/ +#define basicwebWEBSERVER_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +#define lwipBASIC_SERVER_STACK_SIZE 256 + +/*------------------------------------------------------------------------------*/ + +/* The function that implements the WEB server task. */ +extern void start_web_server(void); + +#endif /* + */ + diff --git a/USDK/component/common/utilities/webserver1.c b/USDK/component/common/utilities/webserver1.c new file mode 100644 index 0000000..880dd54 --- /dev/null +++ b/USDK/component/common/utilities/webserver1.c @@ -0,0 +1,1356 @@ +/* + FreeRTOS V6.0.4 - Copyright (C) 2010 Real Time Engineers Ltd. + + *************************************************************************** + * * + * If you are: * + * * + * + New to FreeRTOS, * + * + Wanting to learn FreeRTOS or multitasking in general quickly * + * + Looking for basic training, * + * + Wanting to improve your FreeRTOS skills and productivity * + * * + * then take a look at the FreeRTOS eBook * + * * + * "Using the FreeRTOS Real Time Kernel - a Practical Guide" * + * http://www.FreeRTOS.org/Documentation * + * * + * A pdf reference manual is also available. Both are usually delivered * + * to your inbox within 20 minutes to two hours when purchased between 8am * + * and 8pm GMT (although please allow up to 24 hours in case of * + * exceptional circumstances). Thank you for your support! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + ***NOTE*** The exception to the GPL is included to allow you to distribute + a combined work that includes FreeRTOS without being obliged to provide the + source code for proprietary components outside of the FreeRTOS kernel. + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/* + Implements a simplistic WEB server. Every time a connection is made and + data is received a dynamic page that shows the current TCP/IP statistics + is generated and returned. The connection is then closed. + + This file was adapted from a FreeRTOS lwIP slip demo supplied by a third + party. +*/ + +/* ------------------------ System includes ------------------------------- */ + + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "lwip/api.h" +#include "lwip/tcpip.h" +#include "lwip/ip.h" +#include "lwip/memp.h" +#include "lwip/stats.h" +#include "netif/loopif.h" + +/* ------------------------ Project includes ------------------------------ */ +#include +#include "main.h" + +#if CONFIG_WEBSERVER + +#include "webserver.h" +#include "wlan_intf.h" + +#define CONFIG_READ_FLASH 1 + +#ifdef CONFIG_READ_FLASH + +#ifndef CONFIG_PLATFORM_8195A + +#include +#if defined(STM32F2XX) +#include +#elif defined(STM32F4XX) +#include +#elif defined(STM32f1xx) +#include +#endif + +#else +#include "flash_api.h" +#include "flash_eep.h" +#include "feep_config.h" +#include "device_lock.h" + +#ifndef FEEP_ID_WIFI_AP_CFG +#define FEEP_ID_WIFI_AP_CFG 0x5731 +#endif + +#define DATA_SECTOR AP_SETTING_SECTOR +#define BACKUP_SECTOR (0x00008000) + +#endif +#endif +/* ------------------------ Defines --------------------------------------- */ +/* The size of the buffer in which the dynamic WEB page is created. */ +#define webMAX_PAGE_SIZE (3200/* 2800 */) /*FSL: buffer containing array*/ +#define LOCAL_BUF_SIZE 800 +#define AP_SETTING_ADDR AP_SETTING_SECTOR +/* Standard GET response. */ +#define webHTTP_OK "HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n" + +/* The port on which we listen. */ +#define webHTTP_PORT ( 80 ) + +/* Delay on close error. */ +#define webSHORT_DELAY ( 10 ) + +#define USE_DIV_CSS 1 + +#if USE_DIV_CSS + +/* Format of the dynamic page that is returned on each connection. */ +#define webHTML_HEAD_START \ +"\ +\ +" +/* +\ +\ +\ +*/ + +#define webHTML_TITLE \ +"Realtek SoftAP Config UI" + +#define webHTML_BODY_START \ +"\ +\ +
\ +
\ +
\ +Realtek SoftAP Configuration\ +
" + + + +#define webHTML_CSS \ +"" + + + +#define webHTML_END \ +"
\ +\ +
\ +
\ +Copyright ©realtek.com\ +
\ +
\ +
\ +\ +\ +" + +#define webWaitHTML_START \ +"\ +\ +" +#define webWaitHTML_END \ +"\ +\ +

\ +

SoftAP is now restarting!

\ +

Please wait a moment and reconnect!

\ +

"\ +"\r\n" \ +"" + +#define onChangeSecType \ +"" + +#define onSubmitForm \ +"" + + + +#else + + +/* Format of the dynamic page that is returned on each connection. */ +#define webHTML_HEAD_START \ +"\ +\ +" +/* +\ +\ +\ +*/ + +#define webHTML_BODY_START \ +"\ +\ +\r\n\r\n
\ +\ +\ +\ +" + +#define webHTML_END \ +"\ +\ +\ +\ +\ +\ +
\ +

Realtek SoftAP Configuration

\ +
\ +
\ +Copyright ?realtek.com
\ +\r\n
" \ +"\r\n" \ +"" + +#define webWaitHTML_START \ +"\ +\ +" +#define webWaitHTML_END \ +"\ +\ +

\ +

SoftAP is now restarting!

\ +

Please wait a moment and reconnect!

\ +

"\ +"\r\n" \ +"" + +#define onChangeSecType \ +"" + +#define onSubmitForm \ +"" + + + + +#endif + + + + +/* +alert(\"Please enter your password!\");\ +return false;\ +}\ +if(z.value.length < 8)\ +{\ +alert(\"Your password is too short!(8-32)\");\ +return false;\ +}\ +if(z.value.length>32)\ +{\ +alert(\"Your password is too long!(8-32)\");\ +*/ + +#define MAX_SOFTAP_SSID_LEN 32 +#define MAX_PASSWORD_LEN 32 +#define MAX_CHANNEL_NUM 13 + +#if INCLUDE_uxTaskGetStackHighWaterMark + static volatile unsigned portBASE_TYPE uxHighWaterMark_web = 0; +#endif + +/* ------------------------ Prototypes ------------------------------------ */ +static void vProcessConnection( struct netconn *pxNetCon ); + +/*------------------------------------------------------------------------------*/ +/* GLOBALS */ +/*------------------------------------------------------------------------------*/ +rtw_wifi_setting_t wifi_setting = {RTW_MODE_NONE, {0}, 0, RTW_SECURITY_OPEN, {0}}; + + +#ifndef WLAN0_NAME + #define WLAN0_NAME "wlan0" +#endif + +#ifndef WLAN1_NAME + #define WLAN1_NAME "wlan1" +#endif + +static void LoadWifiSetting() +{ + const char *ifname = WLAN0_NAME; + + if(rltk_wlan_running(WLAN1_IDX)) + {//STA_AP_MODE + ifname = WLAN1_NAME; + } + + wifi_get_setting(ifname, &wifi_setting); + + //printf("\r\nLoadWifiSetting(): wifi_setting.ssid=%s\n", wifi_setting.ssid); + //printf("\r\nLoadWifiSetting(): wifi_setting.channel=%d\n", wifi_setting.channel); + //printf("\r\nLoadWifiSetting(): wifi_setting.security_type=%d\n", wifi_setting.security_type); + //printf("\r\nLoadWifiSetting(): wifi_setting.password=%s\n", wifi_setting.password); +} + +#if CONFIG_READ_FLASH +#ifndef CONFIG_PLATFORM_8195A +void LoadWifiConfig() +{ + rtw_wifi_config_t local_config; + uint32_t address; +#ifdef STM32F10X_XL + address = 0x08080000; //bank2 domain +#else + uint16_t sector_nb = FLASH_Sector_11; + address = flash_SectorAddress(sector_nb); +#endif + printf("\r\nLoadWifiConfig(): Read from FLASH!\n"); + flash_Read(address, (char *)&local_config, sizeof(local_config)); + + printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode); + printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid); + printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel); + printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type); + printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password); + + if(local_config.boot_mode == 0x77665502) + { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + wifi_setting.security_type = local_config.security_type; + if(local_config.password_len > 32) + local_config.password_len = 32; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else + { + LoadWifiSetting(); + } +} + +int StoreApInfo() +{ + rtw_wifi_config_t wifi_config; + uint32_t address; +#ifdef STM32F10X_XL + address = 0x08080000; //bank2 domain +#else + uint16_t sector_nb = FLASH_Sector_11; + address = flash_SectorAddress(sector_nb); +#endif + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); +#ifdef STM32F10X_XL + FLASH_ErasePage(address); +#else + flash_EraseSector(sector_nb); +#endif + flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t)); + + return 0; +} + + +#else + +void LoadWifiConfig() +{ + rtw_wifi_config_t local_config; + local_config.boot_mode = 0; +#ifdef USE_FLASH_EEP + if(flash_read_cfg((uint8_t *)(&local_config), FEEP_ID_WIFI_AP_CFG, sizeof(rtw_wifi_config_t)) >= sizeof(rtw_wifi_config_t)) { + printf("%s: Read from FLASH!\n", __FUNCTION__); + printf("%s: local_config.boot_mode=0x%x\n", __FUNCTION__, local_config.boot_mode); + printf("%s: local_config.ssid=%s\n", __FUNCTION__, local_config.ssid); + printf("%s: local_config.channel=%d\n", __FUNCTION__, local_config.channel); + printf("%s: local_config.security_type=%d\n", __FUNCTION__, local_config.security_type); + printf("%s: local_config.password=%s\n", __FUNCTION__, local_config.password); + } + if(local_config.boot_mode == 0x77665502) { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + if(local_config.security_type == 1) + wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK; + else + wifi_setting.security_type = RTW_SECURITY_OPEN; + if(local_config.password_len > 32) + local_config.password_len = 32; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else { + LoadWifiSetting(); + } + +#else + flash_t flash; + uint32_t address; + address = DATA_SECTOR; + + + //memset(&local_config,0,sizeof(rtw_wifi_config_t)); + printf("\r\nLoadWifiConfig(): Read from FLASH!\n"); + // flash_Read(address, &local_config, sizeof(local_config)); + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),(uint8_t *)(&local_config)); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + + printf("\r\nLoadWifiConfig(): local_config.boot_mode=0x%x\n", local_config.boot_mode); + printf("\r\nLoadWifiConfig(): local_config.ssid=%s\n", local_config.ssid); + printf("\r\nLoadWifiConfig(): local_config.channel=%d\n", local_config.channel); + printf("\r\nLoadWifiConfig(): local_config.security_type=%d\n", local_config.security_type); + printf("\r\nLoadWifiConfig(): local_config.password=%s\n", local_config.password); + + if(local_config.boot_mode == 0x77665502) + { + wifi_setting.mode = RTW_MODE_AP; + if(local_config.ssid_len > 32) + local_config.ssid_len = 32; + memcpy(wifi_setting.ssid, local_config.ssid, local_config.ssid_len); + wifi_setting.ssid[local_config.ssid_len] = '\0'; + wifi_setting.channel = local_config.channel; + if(local_config.security_type == 1) + wifi_setting.security_type = RTW_SECURITY_WPA2_AES_PSK; + else + wifi_setting.security_type = RTW_SECURITY_OPEN; + if(local_config.password_len > 32) + local_config.password_len = 32; + memcpy(wifi_setting.password, local_config.password, local_config.password_len); + wifi_setting.password[local_config.password_len] = '\0'; + } + else + { + LoadWifiSetting(); + } +#endif +} + +int StoreApInfo() +{ +#ifdef USE_FLASH_EEP + rtw_wifi_config_t wifi_config; + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + if(wifi_setting.security_type !=0) + wifi_config.security_type = 1; + else + wifi_config.security_type = 0; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); + flash_write_cfg((uint8_t *)(&wifi_config), FEEP_ID_WIFI_AP_CFG, sizeof(wifi_config)); +#else + flash_t flash; + + rtw_wifi_config_t wifi_config; + uint32_t address; + uint32_t data,i = 0; + + // clean wifi_config first + memset(&wifi_config, 0x00, sizeof(rtw_wifi_config_t)); + + address = DATA_SECTOR; + + wifi_config.boot_mode = 0x77665502; + memcpy(wifi_config.ssid, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + wifi_config.ssid_len = strlen((char*)wifi_setting.ssid); + wifi_config.security_type = wifi_setting.security_type; + if(wifi_setting.security_type !=0) + wifi_config.security_type = 1; + else + wifi_config.security_type = 0; + memcpy(wifi_config.password, wifi_setting.password, strlen((char*)wifi_setting.password)); + wifi_config.password_len= strlen((char*)wifi_setting.password); + wifi_config.channel = wifi_setting.channel; + printf("\n\rWritting boot mode 0x77665502 and Wi-Fi setting to flash ..."); + //printf("\n\r &wifi_config = 0x%x",&wifi_config); + + flash_read_word(&flash,address,&data); + + + if(data == ~0x0){ + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + }else{ + //flash_EraseSector(sector_nb); + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash,BACKUP_SECTOR); + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, DATA_SECTOR + i, &data); + if(i < sizeof(rtw_wifi_config_t)) + { + memcpy(&data,(char *)(&wifi_config) + i,4); + //printf("\n\r Wifi_config + %d = 0x%x",i,(void *)(&wifi_config + i)); + //printf("\n\r Data = %d",data); + } + flash_write_word(&flash, BACKUP_SECTOR + i,data); + } + flash_read_word(&flash,BACKUP_SECTOR + 68,&data); + //printf("\n\r Base + BACKUP_SECTOR + 68 wifi channel = %d",data); + //erase system data + flash_erase_sector(&flash, DATA_SECTOR); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(&flash, BACKUP_SECTOR + i, &data); + flash_write_word(&flash, DATA_SECTOR + i,data); + } + //erase backup sector + flash_erase_sector(&flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + //flash_Wrtie(address, (char *)&wifi_config, sizeof(rtw_wifi_config_t)); + //flash_stream_write(&flash, address,sizeof(rtw_wifi_config_t), (uint8_t *)&wifi_config); + //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); + //flash_stream_read(&flash, address, sizeof(rtw_wifi_config_t),data); + //printf("\n\r Base + 0x000FF000 +4 wifi config = %s",data[4]); + //printf("\n\r Base + 0x000FF000 +71 wifi channel = %d",data[71]); +#endif + return 0; +} + +int EraseApinfo() { +#ifdef USE_FLASH_EEP + flash_write_cfg(NULL, FEEP_ID_WIFI_AP_CFG, 0); +#else + flash_t flash; + uint32_t address; + + address = DATA_SECTOR; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash, address); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif + return 0; +} +#endif + +#endif + +static void RestartSoftAP() +{ + //printf("\r\nRestartAP: ssid=%s", wifi_setting.ssid); + //printf("\r\nRestartAP: ssid_len=%d", strlen((char*)wifi_setting.ssid)); + //printf("\r\nRestartAP: security_type=%d", wifi_setting.security_type); + //printf("\r\nRestartAP: password=%s", wifi_setting.password); + //printf("\r\nRestartAP: password_len=%d", strlen((char*)wifi_setting.password)); + //printf("\r\nRestartAP: channel=%d\n", wifi_setting.channel); + wifi_restart_ap(wifi_setting.ssid, + wifi_setting.security_type, + wifi_setting.password, +// strlen((char*)wifi_setting.ssid), +// strlen((char*)wifi_setting.password), + wifi_setting.channel); +} + + +u32 web_atoi(char* s) +{ + int num=0,flag=0; + int i; + + for(i=0;i<=strlen(s);i++) + { + if(s[i] >= '0' && s[i] <= '9') + num = num * 10 + s[i] -'0'; + else if(s[0] == '-' && i==0) + flag =1; + else + break; + } + + if(flag == 1) + num = num * -1; + + return(num); +} + +static void CreateSsidTableItem(char *pbuf, u8_t *ssid, u8_t ssid_len) +{ + char local_ssid[MAX_SOFTAP_SSID_LEN+1]; + + if(ssid_len > MAX_SOFTAP_SSID_LEN) + ssid_len = MAX_SOFTAP_SSID_LEN; + memcpy(local_ssid, ssid, ssid_len); + local_ssid[ssid_len] = '\0'; + +#if USE_DIV_CSS + sprintf(pbuf, "
SoftAP SSID:
" \ + "
", + local_ssid); +#else + sprintf(pbuf, "" + "" + "SoftAP SSID:
" + "" + "" + "
" + "" + "", + local_ssid); + +#endif + //printf("\r\nstrlen(SsidTableItem)=%d\n", strlen(pbuf)); +} + +static void CreateSecTypeTableItem(char *pbuf, u32_t sectype) +{ + u8_t flag[2] = {0, 0}; + + if(sectype == RTW_SECURITY_OPEN) + flag[0] = 1; + else if(sectype == RTW_SECURITY_WPA2_AES_PSK) + flag[1] = 1; + else + return; + +#if USE_DIV_CSS + sprintf(pbuf, "
Security Type:
"\ + "
", + flag[0]?"selected":"", + flag[1]?"selected":""); +#else + sprintf(pbuf, "" + "" + "Security Type:
" + "" + "" + "" + "" + "", + flag[0]?"selected":"", + flag[1]?"selected":""); + + +#endif + + //printf("\r\nstrlen(SecTypeTableItem)=%d\n", strlen(pbuf)); +} + +static void CreatePasswdTableItem(char *pbuf, u8_t *password, u8_t passwd_len) +{ + char local_passwd[MAX_PASSWORD_LEN+1]; + + if(passwd_len > MAX_PASSWORD_LEN) + passwd_len = MAX_PASSWORD_LEN; + if(passwd_len > 0) + { + memcpy(local_passwd, password, passwd_len); + local_passwd[passwd_len] = '\0'; + } + +#if USE_DIV_CSS + + sprintf(pbuf, "
Password:
"\ + "
"\ + ""\ + "
", + passwd_len?local_passwd:""); +#else + sprintf(pbuf, "" + "" + "Password:
" + "" + "" + "
" + "" + "", + passwd_len?local_passwd:""); + + +#endif + + + //printf("\r\nstrlen(passwordTableItem)=%d\n", strlen(pbuf)); +} + +static void CreateChannelTableItem(char *pbuf, u8_t channel) +{ + u8_t flag[MAX_CHANNEL_NUM+1] = {0}; + + if(channel > MAX_CHANNEL_NUM){ + printf("Channel(%d) is out of range!\n", channel); + channel = 1; + } + flag[channel] = 1; + +#if USE_DIV_CSS + + sprintf(pbuf, "
Channel:
" + "
", + + flag[1]?"selected":"", + flag[2]?"selected":"", + flag[3]?"selected":"", + flag[4]?"selected":"", + flag[5]?"selected":"", + flag[6]?"selected":"", + flag[7]?"selected":"", + flag[8]?"selected":"", + flag[9]?"selected":"", + flag[10]?"selected":"", + flag[11]?"selected":""); +#else + sprintf(pbuf, "" + "" + "Channel:
" + "" + "" + "" + "" + "", + flag[1]?"selected":"", + flag[2]?"selected":"", + flag[3]?"selected":"", + flag[4]?"selected":"", + flag[5]?"selected":"", + flag[6]?"selected":"", + flag[7]?"selected":"", + flag[8]?"selected":"", + flag[9]?"selected":"", + flag[10]?"selected":"", + flag[11]?"selected":""); + + +#endif + + //printf("\r\nstrlen(ChannelTableItem)=%d\n", strlen(pbuf)); +} + +static void GenerateIndexHtmlPage(portCHAR* cDynamicPage, portCHAR *LocalBuf) +{ + /* Generate the page index.html... + ... First the page header. */ + strcpy( cDynamicPage, webHTML_HEAD_START ); + + /* Add script */ + strcat( cDynamicPage, onChangeSecType ); + strcat( cDynamicPage, onSubmitForm); +#if USE_DIV_CSS + /* add css */ + strcat( cDynamicPage, webHTML_CSS); + + strcat( cDynamicPage, webHTML_TITLE); +#endif + /* Add Body start */ + strcat( cDynamicPage, webHTML_BODY_START ); + + /* Add SSID */ + CreateSsidTableItem(LocalBuf, wifi_setting.ssid, strlen((char*)wifi_setting.ssid)); + strcat( cDynamicPage, LocalBuf ); + + /* Add SECURITY TYPE */ + CreateSecTypeTableItem(LocalBuf, wifi_setting.security_type); + strcat( cDynamicPage, LocalBuf ); + + /* Add PASSWORD */ + CreatePasswdTableItem(LocalBuf, wifi_setting.password, strlen((char*)wifi_setting.password)); + strcat( cDynamicPage, LocalBuf ); + + /* Add CHANNEL */ + CreateChannelTableItem(LocalBuf, wifi_setting.channel); + strcat( cDynamicPage, LocalBuf ); + + /* ... Finally the page footer. */ + strcat( cDynamicPage, webHTML_END ); + //printf("\r\nGenerateIndexHtmlPage(): %s\n", cDynamicPage); + printf("\r\nGenerateIndexHtmlPage Len: %d\n", strlen( cDynamicPage )); +} + +static void GenerateWaitHtmlPage(portCHAR* cDynamicPage) +{ + /* Generate the dynamic page... + ... First the page header. */ + strcpy( cDynamicPage, webWaitHTML_START ); + + /* ... Finally the page footer. */ + strcat( cDynamicPage, webWaitHTML_END); + + //printf("\r\nGenerateWaitHtmlPage(): %s\n", cDynamicPage); + //printf("\r\nGenerateWaitHtmlPage Len: %d\n", strlen( cDynamicPage )); +} + + + +static void http_translate_url_encode(char *ptr) +{ + + char *data = ptr; + char tmp_data[3] = {0}; + char outdata[33] = {0}; + int buffer; + char *outdata_ptr = outdata; + + while (*data != '\0') { + + if (*data == '%') { + if ((*(data + 1) != 0) && (*(data + 2) != 0)) { + tmp_data[0] = *(data + 1); + tmp_data[1] = *(data + 2); + sscanf(tmp_data, "%x", &buffer); + *outdata_ptr = (char)buffer; + + /* destroy data */ + *data = 0; + *(data+1) = 0; + *(data+2) = 0; + + data += 2; + outdata_ptr++; + } + + } else { + *outdata_ptr = *data; + if (*data == '+') + *outdata_ptr = ' '; + outdata_ptr++; + } + data++; + } + strcpy(ptr, outdata); + +} + +static u8_t ProcessPostMessage(struct netbuf *pxRxBuffer, portCHAR *LocalBuf) +{ + struct pbuf *p; + portCHAR *pcRxString, *ptr; + unsigned portSHORT usLength; + u8_t bChanged = 0; + rtw_security_t secType; + u8_t channel; + u8_t len = 0; + + pcRxString = LocalBuf; + p = pxRxBuffer->p; + usLength = p->tot_len; + //printf("\r\n !POST!p->tot_len =%d p->len=%d\n", p->tot_len, p->len); + while(p) + { + memcpy(pcRxString, p->payload, p->len); + pcRxString += p->len; + p = p->next; + } + pcRxString = LocalBuf; + pcRxString[usLength] = '\0'; + //printf("\r\n usLength=%d pcRxString = %s\n", usLength, pcRxString); + + ptr = (char*)strstr(pcRxString, "Ssid="); + if(ptr) + { + //printf("ssid passed = %s\n", ptr); + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 5; + http_translate_url_encode(ptr); + if(strcmp((char*)wifi_setting.ssid, ptr)) + { + bChanged = 1; + len = strlen(ptr); + if(len > MAX_SOFTAP_SSID_LEN){ + len = MAX_SOFTAP_SSID_LEN; + ptr[len] = '\0'; + } + strcpy((char*)wifi_setting.ssid, ptr); + } + } + + + printf("\r\n get wifi_config.ssid = %s\n", wifi_setting.ssid); + ptr = (char*)strstr(pcRxString, "Security+Type="); + if(ptr) + { + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 14; + if(!strcmp(ptr, "open")) + secType = RTW_SECURITY_OPEN; + else if(!strcmp(ptr, "wpa2-aes")) + secType = RTW_SECURITY_WPA2_AES_PSK; + else + secType = RTW_SECURITY_OPEN; + if(wifi_setting.security_type != secType) + { + bChanged = 1; + wifi_setting.security_type = secType; + } + } + + //printf("\r\n wifi_config.security_type = %d\n", wifi_setting.security_type); + if(wifi_setting.security_type > RTW_SECURITY_OPEN) + { + ptr = (char*)strstr(pcRxString, "Password="); + if(ptr) + { + pcRxString = (char*)strstr(ptr, "&"); + *pcRxString++ = '\0'; + ptr += 9; + if(strcmp((char*)wifi_setting.password, ptr)) + { + bChanged = 1; + len = strlen(ptr); + if(len > MAX_PASSWORD_LEN){ + len = MAX_PASSWORD_LEN; + ptr[len] = '\0'; + } + strcpy((char*)wifi_setting.password, ptr); + } + } + //printf("\r\n wifi_config.password = %s\n", wifi_setting.password); + } + ptr = (char*)strstr(pcRxString, "Channel="); + if(ptr) + { + ptr += 8; + channel = web_atoi(ptr); + if((channel>MAX_CHANNEL_NUM)||(channel < 1)) + channel = 1; + if(wifi_setting.channel !=channel) + { + bChanged = 1; + wifi_setting.channel = channel; + } + } + //printf("\r\n wifi_config.channel = %d\n", wifi_setting.channel); + + return bChanged; +} + +struct netconn *pxHTTPListener = NULL; +static void vProcessConnection( struct netconn *pxNetCon ) +{ + static portCHAR cDynamicPage[webMAX_PAGE_SIZE]; + struct netbuf *pxRxBuffer, *pxRxBuffer1 = NULL; + portCHAR *pcRxString; + unsigned portSHORT usLength; + static portCHAR LocalBuf[LOCAL_BUF_SIZE]; + u8_t bChanged = 0; + int ret_recv = ERR_OK; + int ret_accept = ERR_OK; + char *ptr = NULL; + + /* Load WiFi Setting*/ + LoadWifiSetting(); + + /* We expect to immediately get data. */ + port_netconn_recv( pxNetCon , pxRxBuffer, ret_recv); + + if( pxRxBuffer != NULL && ret_recv == ERR_OK) + { + /* Where is the data? */ + netbuf_data( pxRxBuffer, ( void * )&pcRxString, &usLength ); + + //printf("\r\nusLength=%d pcRxString = \n%s\n", usLength, pcRxString); + /* Is this a GET? We don't handle anything else. */ + if( !strncmp( pcRxString, "GET", 3 ) ) + { + //printf("\r\nusLength=%d pcRxString=%s \n", usLength, pcRxString); + //pcRxString = cDynamicPage; + + /* Write out the HTTP OK header. */ + netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY ); + + /* Generate index.html page. */ + GenerateIndexHtmlPage(cDynamicPage, LocalBuf); + + /* Write out the dynamically generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + } + else if(!strncmp( pcRxString, "POST", 4 ) ) + { + /* Write out the HTTP OK header. */ + netconn_write( pxNetCon, webHTTP_OK, ( u16_t ) strlen( webHTTP_OK ), NETCONN_COPY ); + + bChanged = ProcessPostMessage(pxRxBuffer, LocalBuf); + if(bChanged == 0){ + port_netconn_recv( pxNetCon , pxRxBuffer1, ret_recv); + if(pxRxBuffer != NULL && ret_recv == ERR_OK){ + bChanged = ProcessPostMessage(pxRxBuffer1, LocalBuf); + netbuf_delete( pxRxBuffer1 ); + } + } + if(bChanged) + { + GenerateWaitHtmlPage(cDynamicPage); + + /* Write out the generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + +#if CONFIG_READ_FLASH + StoreApInfo(); +#endif + } + else + { + /* Generate index.html page. */ + GenerateIndexHtmlPage(cDynamicPage, LocalBuf); + + /* Write out the generated page. */ + netconn_write( pxNetCon, cDynamicPage, ( u16_t ) strlen( cDynamicPage ), NETCONN_COPY ); + } + } + netbuf_delete( pxRxBuffer ); + } + netconn_close( pxNetCon ); + + if(bChanged) + { + struct netconn *pxNewConnection; + vTaskDelay(200/portTICK_RATE_MS); + //printf("\r\n%d:before restart ap\n", xTaskGetTickCount()); + RestartSoftAP(); + //printf("\r\n%d:after restart ap\n", xTaskGetTickCount()); + pxHTTPListener->recv_timeout = 1; + port_netconn_accept( pxHTTPListener , pxNewConnection, ret_accept); + if( pxNewConnection != NULL && ret_accept == ERR_OK) + { + //printf("\r\n%d: got a conn\n", xTaskGetTickCount()); + netconn_close( pxNewConnection ); + while( netconn_delete( pxNewConnection ) != ERR_OK ) + { + vTaskDelay( webSHORT_DELAY ); + } + } + //printf("\r\n%d:end\n", xTaskGetTickCount()); + pxHTTPListener->recv_timeout = 0; + } +} + +/*------------------------------------------------------------*/ +xTaskHandle webs_task = NULL; +xSemaphoreHandle webs_sema = NULL; +u8_t webs_terminate = 0; +void vBasicWEBServer( void *pvParameters ) +{ + struct netconn *pxNewConnection; + //struct ip_addr xIpAddr, xNetMast, xGateway; + extern err_t ethernetif_init( struct netif *netif ); + int ret = ERR_OK; + /* Parameters are not used - suppress compiler error. */ + ( void )pvParameters; + + /* Create a new tcp connection handle */ + pxHTTPListener = netconn_new( NETCONN_TCP ); + ip_set_option(pxHTTPListener->pcb.ip, SOF_REUSEADDR); + netconn_bind( pxHTTPListener, NULL, webHTTP_PORT ); + netconn_listen( pxHTTPListener ); + +#if CONFIG_READ_FLASH + /* Load wifi_config */ + LoadWifiConfig(); + RestartSoftAP(); +#endif + //printf("\r\n-0\n"); + + /* Loop forever */ + for( ;; ) + { + if(webs_terminate) + break; + + //printf("\r\n%d:-1\n", xTaskGetTickCount()); + /* Wait for connection. */ + port_netconn_accept( pxHTTPListener , pxNewConnection, ret); + //printf("\r\n%d:-2\n", xTaskGetTickCount()); + + if( pxNewConnection != NULL && ret == ERR_OK) + { + /* Service connection. */ + vProcessConnection( pxNewConnection ); + while( netconn_delete( pxNewConnection ) != ERR_OK ) + { + vTaskDelay( webSHORT_DELAY ); + } + } + //printf("\r\n%d:-3\n", xTaskGetTickCount()); + } + //printf("\r\n-4\n"); + if(pxHTTPListener) + { + netconn_close(pxHTTPListener); + netconn_delete(pxHTTPListener); + pxHTTPListener = NULL; + } + + //printf("\r\nExit Web Server Thread!\n"); + xSemaphoreGive(webs_sema); +} + +#define STACKSIZE 512 +void start_web_server() +{ + printf("\r\nWEB:Enter start web server!\n"); + webs_terminate = 0; + if(webs_task == NULL) + { + if(xTaskCreate(vBasicWEBServer, (const char *)"web_server", STACKSIZE, NULL, tskIDLE_PRIORITY + 1, &webs_task) != pdPASS) + printf("\n\rWEB: Create webserver task failed!\n"); + } + if(webs_sema == NULL) + { + webs_sema = xSemaphoreCreateCounting(0xffffffff, 0); //Set max count 0xffffffff + } + //printf("\r\nWEB:Exit start web server!\n"); +} + +void stop_web_server() +{ + //printf("\r\nWEB:Enter stop web server!\n"); + webs_terminate = 1; + if(pxHTTPListener) + netconn_abort(pxHTTPListener); + if(webs_sema) + { + if(xSemaphoreTake(webs_sema, 15 * configTICK_RATE_HZ) != pdTRUE) + { + if(pxHTTPListener) + { + netconn_close(pxHTTPListener); + netconn_delete(pxHTTPListener); + pxHTTPListener = NULL; + } + printf("\r\nWEB: Take webs sema(%p) failed!\n", webs_sema); + } + vSemaphoreDelete(webs_sema); + webs_sema = NULL; + } + if(webs_task) + { + vTaskDelete(webs_task); + webs_task = NULL; + } + printf("\r\nWEB:Exit stop web server!\n"); +} + +#endif // #if CONFIG_WEBSERVER diff --git a/USDK/component/common/utilities/xml.c b/USDK/component/common/utilities/xml.c new file mode 100644 index 0000000..934e304 --- /dev/null +++ b/USDK/component/common/utilities/xml.c @@ -0,0 +1,1376 @@ +/* +Author: Alex Fang + +Tree Structure + root root + | ^ ^ + child | | + | parent parent + v | | +NULL<-prev-child1-next-><-prev-child2-next->NULL +*/ + +#include "platform/platform_stdlib.h" +#include "FreeRTOS.h" +#include "xml.h" + +static struct xml_node *_xml_new_element(char *prefix, char *name, char *uri, char *attr); + +char *xml_strstr(const char *str1, const char *str2) { + char *a, *b; + + /* First scan quickly through the two strings looking for a + * single-character match. When it's found, then compare the + * rest of the substring. + */ + + b = (char *)str2; + if (*b == 0) { + return (char *)str1; + } + for ( ; *str1 != 0; str1 += 1) { + if (*str1 != *b) { + continue; + } + a = (char *)str1; + while (1) { + if (*b == 0) { + return (char *)str1; + } + if (*a++ != *b++) { + break; + } + } + b = (char *)str2; + } + return (char *) 0; +} + +static void *xml_malloc(unsigned int size) +{ + return pvPortMalloc(size); +} + +void xml_free(void *buf) +{ + vPortFree(buf); +} + +static char *str_strip(char *str, unsigned int str_len) +{ + char *front, *rear; + char *strip = NULL; + int strip_len; + + if(!str || (str_len <= 0)) + return NULL; + + for(front = str; front < (str + str_len); front ++) + if(*front != ' ') break; + + if(front == (str + str_len)) + return NULL; + + for(rear = (str + str_len - 1); rear >= front; rear --) + if(*rear != ' ') break; + + if(front == rear) { + strip_len = 1; + strip = (char *) xml_malloc(strip_len + 1); + memcpy(strip, front, strip_len); + strip[strip_len] = '\0'; + } + else { + strip_len = rear + 1 - front; + strip = (char *) xml_malloc(strip_len + 1); + memcpy(strip, front, strip_len); + strip[strip_len] = '\0'; + } + + return strip; +} + +/* TAG Format: + * STag ::= '<' Name (S Attribute)* S? '>' + * ETag ::= '' + * EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' + */ +static void _parse_tag(char *tag, char **prefix, char **name, char **uri, char **attr) +{ + char *prefix_char, *ns_tag, *ns_front; + int have_prefix = 0; + int have_uri = 0; + + prefix_char = strchr(tag, ':'); + + if(prefix_char) { + char *tag_sep = strchr(tag, ' '); + + if(!tag_sep) + have_prefix = 1; + else if(prefix_char < tag_sep) + have_prefix = 1; + } + + if(have_prefix) { + *prefix = str_strip(tag, prefix_char - tag); + ns_tag = (char *) xml_malloc(strlen(" xmlns:") + strlen(*prefix) + 1); + sprintf(ns_tag, " xmlns:%s", *prefix); + ns_front = xml_strstr(tag, ns_tag); + xml_free(ns_tag); + } + else { + *prefix = NULL; + ns_tag = " xmlns"; + ns_front = xml_strstr(tag, ns_tag); + } + + if(ns_front) + have_uri = 1; + + if(have_prefix && have_uri) { + char *uri_front, *uri_rear, *tag_sep, ns_sep; + int uri_len; + + tag_sep = strchr(prefix_char + 1, ' '); + *name = str_strip(prefix_char + 1, tag_sep - (prefix_char + 1)); + + if(attr) + *attr = str_strip(tag_sep, tag + strlen(tag) - tag_sep); + + if(*(strchr(ns_front, '=') + 1) == '\'') + ns_sep = '\''; + else + ns_sep = '\"'; + + uri_front = strchr(ns_front, ns_sep) + 1; + uri_rear = strchr(uri_front, ns_sep); + uri_len = uri_rear - uri_front; + *uri = (char *) xml_malloc(uri_len + 1); + memcpy(*uri, uri_front, uri_len); + (*uri)[uri_len] = '\0'; + } + else if(have_prefix) { + char *tag_sep; + + *uri = NULL; + tag_sep = strchr(prefix_char + 1, ' '); + + if(tag_sep) { + *name = str_strip(prefix_char + 1, tag_sep - (prefix_char + 1)); + + if(attr) + *attr = str_strip(tag_sep, tag + strlen(tag) - tag_sep); + } + else { + *name = str_strip(prefix_char + 1, tag + strlen(tag) - (prefix_char + 1)); + + if(attr) + *attr = NULL; + } + } + else if(have_uri) { + char *uri_front, *uri_rear, *tag_sep, ns_sep; + int uri_len; + + tag_sep = strchr(tag, ' '); + *name = str_strip(tag, tag_sep - tag); + + if(attr) + *attr = str_strip(tag_sep, tag + strlen(tag) - tag_sep); + + if(*(strchr(ns_front, '=') + 1) == '\'') + ns_sep = '\''; + else + ns_sep = '\"'; + + uri_front = strchr(ns_front, ns_sep) + 1; + uri_rear = strchr(uri_front, ns_sep); + uri_len = uri_rear - uri_front; + *uri = (char *) xml_malloc(uri_len + 1); + memcpy(*uri, uri_front, uri_len); + (*uri)[uri_len] = '\0'; + } + else { + char *tag_sep; + + *uri = NULL; + tag_sep = strchr(tag, ' '); + + if(tag_sep) { + *name = str_strip(tag, tag_sep - tag); + + if(attr) + *attr = str_strip(tag_sep, tag + strlen(tag) - tag_sep); + } + else { + *name = str_strip(tag, strlen(tag)); + + if(attr) + *attr = NULL; + } + } +} + +static void parse_tag(char *tag, char **prefix, char **name, char **uri) +{ + _parse_tag(tag, prefix, name, uri, NULL); +} + +int xml_doc_name(char *doc_buf, int doc_len, char **doc_prefix, char **doc_name, char **doc_uri) +{ + char *xml_buf, *cur_pos, *tag_front, *tag_rear; + char *start_tag, *end_tag1, *end_tag2; + int tag_len, ret = -1; + + xml_buf = (char *) xml_malloc(doc_len + 1); + memcpy(xml_buf, doc_buf, doc_len); + xml_buf[doc_len] = '\0'; + + cur_pos = xml_buf; + + while(cur_pos < (xml_buf + doc_len)) { + if((tag_front = strchr(cur_pos, '<')) != NULL) { + tag_front ++; + + if((tag_rear = strchr(tag_front, '>')) != NULL) { + char *prefix = NULL, *name = NULL, *uri = NULL; + + //Element without content + if(*(tag_rear - 1) == '/') { + tag_len = tag_rear - 1 - tag_front; + start_tag = (char *) xml_malloc(tag_len + 1); + memcpy(start_tag, tag_front, tag_len); + start_tag[tag_len] = '\0'; + parse_tag(start_tag, &prefix, &name, &uri); + xml_free(start_tag); + *doc_name = name; + *doc_prefix = prefix; + *doc_uri = uri; + ret = 0; + cur_pos = xml_buf + doc_len; + } + //Element with content + else { + tag_len = tag_rear - tag_front; + start_tag = (char *) xml_malloc(tag_len + 1); + memcpy(start_tag, tag_front, tag_len); + start_tag[tag_len] = '\0'; + parse_tag(start_tag, &prefix, &name, &uri); + xml_free(start_tag); + + if(prefix) { + end_tag1 = (char *) xml_malloc(strlen(prefix) + strlen(name) + 5); + sprintf(end_tag1, "", prefix, name); + end_tag2 = (char *) xml_malloc(strlen(prefix) + strlen(name) + 5); + sprintf(end_tag2, "", name); + end_tag2 = (char *) xml_malloc(strlen(name) + 4); + sprintf(end_tag2, "')) != NULL) { + char *doc_front, *doc_rear, *start_tag, *end_tag1, *end_tag2; + char *prefix = NULL, *name = NULL, *uri = NULL, *attr = NULL; + int tag_len; + + //Element without content + if(*(tag_rear - 1) == '/') { + doc_front = tag_rear + 1; + tag_len = tag_rear - 1 - tag_front; + start_tag = (char *) xml_malloc(tag_len + 1); + memcpy(start_tag, tag_front, tag_len); + start_tag[tag_len] = '\0'; + _parse_tag(start_tag, &prefix, &name, &uri, &attr); + node = _xml_new_element(prefix, name, uri, attr); + + if(root) { + xml_add_child(root, node); + cur_pos = doc_front; + } + else { + root = node; + cur_pos = xml_buf + doc_len; + } + } + //Element with content + else { + doc_front = tag_rear + 1; + tag_len = tag_rear - tag_front; + start_tag = (char *) xml_malloc(tag_len + 1); + memcpy(start_tag, tag_front, tag_len); + start_tag[tag_len] = '\0'; + _parse_tag(start_tag, &prefix, &name, &uri, &attr); + + if(prefix) { + end_tag1 = (char *) xml_malloc(strlen(prefix) + strlen(name) + 5); + sprintf(end_tag1, "", prefix, name); + end_tag2 = (char *) xml_malloc(strlen(prefix) + strlen(name) + 5); + sprintf(end_tag2, "", name); + end_tag2 = (char *) xml_malloc(strlen(name) + 4); + sprintf(end_tag2, "') + 1; + } + else { + root = node; + _xml_parse_doc(doc_front, doc_rear - doc_front, node); + cur_pos = xml_buf + doc_len; + } + } + else { + cur_pos = doc_front; + } + + xml_free(end_tag1); + xml_free(end_tag2); + } + + xml_free(start_tag); + xml_free(name); + if(prefix) xml_free(prefix); + if(uri) xml_free(uri); + if(attr) xml_free(attr); + } + else { + if(root && !root->child && (strlen(cur_pos) > 0)) { + node = xml_new_text(cur_pos); + xml_add_child(root, node); + } + + cur_pos = xml_buf + doc_len; + } + } + else { + if(root && !root->child && (strlen(cur_pos) > 0)) { + node = xml_new_text(cur_pos); + xml_add_child(root, node); + } + + cur_pos = xml_buf + doc_len; + } + } + + xml_free(xml_buf); + + return root; +} + +/* Note: xml_parse_doc can handle attribute only for namespace */ +struct xml_node *xml_parse_doc(char *doc_buf, int doc_len, char *doc_prefix, char *doc_name, char *doc_uri) +{ + struct xml_node *root = NULL; + char *xml_buf, *start_tag, *end_tag, *empty_tag, *front, *rear; + + xml_buf = (char *) xml_malloc(doc_len + 1); + memcpy(xml_buf, doc_buf, doc_len); + xml_buf[doc_len] = '\0'; + + if(doc_prefix && doc_uri) { + start_tag = (char *) xml_malloc(2 * strlen(doc_prefix) + strlen(doc_name) + strlen(doc_uri) + 14); + sprintf(start_tag, "<%s:%s xmlns:%s=\"%s\">", doc_prefix, doc_name, doc_prefix, doc_uri); + empty_tag = (char *) xml_malloc(2 * strlen(doc_prefix) + strlen(doc_name) + strlen(doc_uri) + 15); + sprintf(empty_tag, "<%s:%s xmlns:%s=\"%s\"/>", doc_prefix, doc_name, doc_prefix, doc_uri); + + } + else if(doc_prefix) { + start_tag = (char *) xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 4); + sprintf(start_tag, "<%s:%s>", doc_prefix, doc_name); + empty_tag = (char *) xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 5); + sprintf(empty_tag, "<%s:%s/>", doc_prefix, doc_name); + } + else if(doc_uri) { + start_tag = (char *) xml_malloc(strlen(doc_name) + strlen(doc_uri) + 12); + sprintf(start_tag, "<%s xmlns=\"%s\">", doc_name, doc_uri); + empty_tag = (char *) xml_malloc(strlen(doc_name) + strlen(doc_uri) + 13); + sprintf(empty_tag, "<%s xmlns=\"%s\"/>", doc_name, doc_uri); + } + else { + start_tag = (char *) xml_malloc(strlen(doc_name) + 3); + sprintf(start_tag, "<%s>", doc_name); + empty_tag = (char *) xml_malloc(strlen(doc_name) + 4); + sprintf(empty_tag, "<%s/>", doc_name); + } + + if(doc_prefix) { + end_tag = (char *) xml_malloc(strlen(doc_prefix) + strlen(doc_name) + 5); + sprintf(end_tag, "", doc_prefix, doc_name); + } + else { + end_tag = (char *) xml_malloc(strlen(doc_name) + 4); + sprintf(end_tag, "", doc_name); + } + + //Root element with content + if((front = xml_strstr(xml_buf, start_tag)) != NULL) { + front += strlen(start_tag); + + if((rear = xml_strstr(front, end_tag)) != NULL) { + int xml_len = rear - front; + + root = xml_new_element(doc_prefix, doc_name, doc_uri); + _xml_parse_doc(front, xml_len, root); + } + } + //Root element without content + else if((front = xml_strstr(xml_buf, empty_tag)) != NULL) { + root = xml_new_element(doc_prefix, doc_name, doc_uri); + } + + xml_free(start_tag); + xml_free(end_tag); + xml_free(empty_tag); + xml_free(xml_buf); + + return root; +} + +struct xml_node *xml_parse(char *doc_buf, int doc_len) +{ + char *proc_inst, *comment, *pos, *prolog_end; + + /* Remove XML Prolog */ + pos = doc_buf; + while(pos < (doc_buf + doc_len)) { + if((proc_inst = xml_strstr(pos, "') + 1; + } + else { + proc_inst = pos; + break; + } + } + pos = doc_buf; + while(pos < (doc_buf + doc_len)) { + if((comment = xml_strstr(pos, "') + 1; + } + else { + comment = pos; + break; + } + } + if(proc_inst > comment) + prolog_end = proc_inst; + else + prolog_end = comment; + + return _xml_parse_doc(prolog_end, doc_buf + doc_len - prolog_end, NULL); +} + +static struct xml_node *xml_new_node(void) +{ + struct xml_node *node; + + node = (struct xml_node *) xml_malloc(sizeof(struct xml_node)); + memset(node, 0, sizeof(struct xml_node)); + + return node; +} + +static struct xml_node *_xml_new_element(char *prefix, char *name, char *uri, char *attr) +{ + struct xml_node *node; + + node = xml_new_node(); + node->name = (char *) xml_malloc(strlen(name) + 1); + strcpy(node->name, name); + + if(prefix) { + node->prefix = (char *) xml_malloc(strlen(prefix) + 1); + strcpy(node->prefix, prefix); + } + + if(uri) { + node->uri = (char *) xml_malloc(strlen(uri) + 1); + strcpy(node->uri, uri); + } + + if(attr) { + node->attr = (char *) xml_malloc(strlen(attr) + 1); + strcpy(node->attr, attr); + } + + return node; +} + +struct xml_node *xml_new_element(char *prefix, char *name, char *uri) +{ + struct xml_node *node; + char *attr = NULL; + + if(prefix && uri) { + attr = (char *) xml_malloc(strlen(prefix) + strlen(uri) + 10); + sprintf(attr, "xmlns:%s=\"%s\"", prefix, uri); + } + else if(uri) { + attr = (char *) xml_malloc(strlen(uri) + 9); + sprintf(attr, "xmlns=\"%s\"", uri); + } + + node = _xml_new_element(prefix, name, uri, attr); + + if(attr) + xml_free(attr); + + return node; +} + +struct xml_node *xml_new_text(char *text) +{ + struct xml_node *node; + char *text_buf; + + text_buf = (char *) xml_malloc(strlen(text) + 1); + strcpy(text_buf, text); + node = xml_new_node(); + node->text = text_buf; + + return node; +} + +int xml_is_element(struct xml_node *node) +{ + int ret = 0; + + if((node->name != NULL) && (node->text == NULL)) + ret = 1; + + return ret; +} + +int xml_is_text(struct xml_node *node) +{ + int ret = 0; + + if((node->name == NULL) && (node->text != NULL)) + ret = 1; + + return ret; +} + +static void _xml_copy_tree(struct xml_node *root, struct xml_node *parent) +{ + struct xml_node *copy = NULL; + + if(xml_is_text(root)) { + copy = xml_new_text(root->text); + } + else if(xml_is_element(root)) { + struct xml_node *child = root->child; + + copy = _xml_new_element(root->prefix, root->name, root->uri, root->attr); + + while(child) { + _xml_copy_tree(child, copy); + child = child->next; + } + } + + if(copy) + xml_add_child(parent, copy); +} + +struct xml_node* xml_copy_tree(struct xml_node *root) +{ + struct xml_node *copy = NULL; + + if(xml_is_text(root)) { + copy = xml_new_text(root->text); + } + else if(xml_is_element(root)) { + struct xml_node *child = root->child; + + copy = _xml_new_element(root->prefix, root->name, root->uri, root->attr); + + while(child) { + _xml_copy_tree(child, copy); + child = child->next; + } + } + + return copy; +} + +void xml_delete_tree(struct xml_node *root) +{ + if(root->name) + xml_free(root->name); + + if(root->text) + xml_free(root->text); + + if(root->prefix) + xml_free(root->prefix); + + if(root->uri) + xml_free(root->uri); + + if(root->attr) + xml_free(root->attr); + + while(root->child) + xml_delete_tree(root->child); + + if(root->prev) { + root->prev->next = root->next; + + if(root->next) + root->next->prev = root->prev; + } + else if(root->parent) { + root->parent->child = root->next; + + if(root->next) + root->next->prev = NULL; + } + + xml_free(root); +} + +void xml_add_child(struct xml_node *node, struct xml_node *child) +{ + if(xml_is_element(node)) { + if(node->child) { + struct xml_node *last_child = node->child; + + while(last_child->next != NULL) + last_child = last_child->next; + + last_child->next = child; + child->prev = last_child; + } + else { + node->child = child; + } + + child->parent = node; + } +} + +void xml_clear_child(struct xml_node *node) +{ + while(node->child) + xml_delete_tree(node->child); +} + +struct xml_node* xml_text_child(struct xml_node *node) +{ + struct xml_node *child = NULL; + + if(node->child) { + if(xml_is_text(node->child)) + child = node->child; + } + + return child; +} + +void xml_set_text(struct xml_node *node, char *text) +{ + if(xml_is_text(node)) { + char *text_buf = (char *) xml_malloc(strlen(text) + 1); + strcpy(text_buf, text); + xml_free(node->text); + node->text = text_buf; + } +} + +static void _xml_element_count(struct xml_node *root, char *name, int *count) +{ + if(xml_is_element(root)) { + struct xml_node *child = root->child; + + if(strcmp(root->name, name) == 0) { + (*count) ++; + } + + while(child) { + _xml_element_count(child, name, count); + child = child->next; + } + } +} + +static int xml_element_count(struct xml_node *root, char *name) +{ + int count = 0; + + _xml_element_count(root, name, &count); + + return count; +} + +static void _xml_find_element(struct xml_node *root, char *name, struct xml_node_set *node_set) +{ + if(xml_is_element(root)) { + struct xml_node *child = root->child; + + if(strcmp(root->name, name) == 0) { + node_set->node[node_set->count] = root; + node_set->count ++; + } + + while(child) { + _xml_find_element(child, name, node_set); + child = child->next; + } + } +} + +struct xml_node_set* xml_find_element(struct xml_node *root, char *name) +{ + struct xml_node_set *node_set = NULL; + int node_count; + + node_set = (struct xml_node_set *) xml_malloc(sizeof(struct xml_node_set)); + node_set->count = 0; + node_count = xml_element_count(root, name); + + if(node_count) + node_set->node = (struct xml_node **) xml_malloc(node_count * sizeof(struct xml_node *)); + else + node_set->node = NULL; + + _xml_find_element(root, name, node_set); + + return node_set; +} + +static void _xml_path_count(struct xml_node *root, char *path, int *count) +{ + if(xml_is_element(root)) { + char *front = NULL, *rear = NULL; + + if((front = strchr(path, '/')) != NULL) { + int prefix_len, name_len; + char *prefix, *name, *prefix_char; + int prefix_matched = 0, name_matched = 0; + + front ++; + prefix_char = strchr(front, ':'); + + if((rear = strchr(front, '/')) != NULL) { + if(prefix_char && (prefix_char < rear)) { + prefix_len = prefix_char - front; + prefix = (char *) xml_malloc(prefix_len + 1); + memcpy(prefix, front, prefix_len); + prefix[prefix_len] = '\0'; + + name_len = rear - (prefix_char + 1); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, prefix_char + 1, name_len); + name[name_len] = '\0'; + } + else { + prefix = NULL; + name_len = rear - front; + name = (char *) xml_malloc(name_len + 1); + memcpy(name, front, name_len); + name[name_len] = '\0'; + } + + if((!prefix && !root->prefix) || + (prefix && root->prefix && (strcmp(root->prefix, prefix) == 0))) + prefix_matched = 1; + else + prefix_matched = 0; + + if(strcmp(root->name, name) == 0) + name_matched = 1; + else + name_matched = 0; + + if(prefix_matched && name_matched) { + struct xml_node *child = root->child; + + while(child) { + _xml_path_count(child, rear, count); + child = child->next; + } + } + } + else { + if(prefix_char) { + prefix_len = prefix_char - front; + prefix = (char *) xml_malloc(prefix_len + 1); + memcpy(prefix, front, prefix_len); + prefix[prefix_len] = '\0'; + + name_len = strlen(path) - (prefix_char + 1 - path); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, prefix_char + 1, name_len); + name[name_len] = '\0'; + } + else { + prefix = NULL; + name_len = strlen(path) - (front - path); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, front, name_len); + name[name_len] = '\0'; + } + + if((!prefix && !root->prefix) || + (prefix && root->prefix && (strcmp(root->prefix, prefix) == 0))) + prefix_matched = 1; + else + prefix_matched = 0; + + if(strcmp(root->name, name) == 0) + name_matched = 1; + else + name_matched = 0; + + if(prefix_matched && name_matched) + (*count) ++; + } + + if(prefix) xml_free(prefix); + xml_free(name); + } + } +} + +static int xml_path_count(struct xml_node *root, char *path) +{ + int count = 0; + + _xml_path_count(root, path, &count); + + return count; +} + +static void _xml_find_path(struct xml_node *root, char *path, struct xml_node_set *node_set) +{ + if(xml_is_element(root)) { + char *front = NULL, *rear = NULL; + + if((front = strchr(path, '/')) != NULL) { + int prefix_len, name_len; + char *prefix, *name, *prefix_char; + int prefix_matched = 0, name_matched = 0; + + front ++; + prefix_char = strchr(front, ':'); + + if((rear = strchr(front, '/')) != NULL) { + if(prefix_char && (prefix_char < rear)) { + prefix_len = prefix_char - front; + prefix = (char *) xml_malloc(prefix_len + 1); + memcpy(prefix, front, prefix_len); + prefix[prefix_len] = '\0'; + + name_len = rear - (prefix_char + 1); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, prefix_char + 1, name_len); + name[name_len] = '\0'; + } + else { + prefix = NULL; + name_len = rear - front; + name = (char *) xml_malloc(name_len + 1); + memcpy(name, front, name_len); + name[name_len] = '\0'; + } + + if((!prefix && !root->prefix) || + (prefix && root->prefix && (strcmp(root->prefix, prefix) == 0))) + prefix_matched = 1; + else + prefix_matched = 0; + + if(strcmp(root->name, name) == 0) + name_matched = 1; + else + name_matched = 0; + + if(prefix_matched && name_matched) { + struct xml_node *child = root->child; + + while(child) { + _xml_find_path(child, rear, node_set); + child = child->next; + } + } + } + else { + if(prefix_char) { + prefix_len = prefix_char - front; + prefix = (char *) xml_malloc(prefix_len + 1); + memcpy(prefix, front, prefix_len); + prefix[prefix_len] = '\0'; + + name_len = strlen(path) - (prefix_char + 1 - path); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, prefix_char + 1, name_len); + name[name_len] = '\0'; + } + else { + prefix = NULL; + name_len = strlen(path) - (front - path); + name = (char *) xml_malloc(name_len + 1); + memcpy(name, front, name_len); + name[name_len] = '\0'; + } + + if((!prefix && !root->prefix) || + (prefix && root->prefix && (strcmp(root->prefix, prefix) == 0))) + prefix_matched = 1; + else + prefix_matched = 0; + + if(strcmp(root->name, name) == 0) + name_matched = 1; + else + name_matched = 0; + + if(prefix_matched && name_matched) { + node_set->node[node_set->count] = root; + node_set->count ++; + } + } + + if(prefix) xml_free(prefix); + xml_free(name); + } + } +} + +struct xml_node_set* xml_find_path(struct xml_node *root, char *path) +{ + struct xml_node_set *node_set = NULL; + int node_count; + + node_set = (struct xml_node_set *) xml_malloc(sizeof(struct xml_node_set)); + node_set->count = 0; + node_count = xml_path_count(root, path); + + if(node_count) + node_set->node = (struct xml_node **) xml_malloc(node_count * sizeof(struct xml_node *)); + else + node_set->node = NULL; + + _xml_find_path(root, path, node_set); + + return node_set; +} + +void xml_delete_set(struct xml_node_set *node_set) +{ + if(node_set->node) + xml_free(node_set->node); + + xml_free(node_set); +} + +static int xml_tree_size(struct xml_node *root, int level, int space) +{ + int size = 0; + int next_level = (level)?(level + 1):0; + + if(xml_is_text(root)) { + size += strlen(root->text); + } + else if(xml_is_element(root)) { + int start_size, end_size; + struct xml_node *child = root->child; + int is_element_child = 0; + + if(root->prefix && root->attr) + /* */ + start_size = strlen(root->prefix) + strlen(root->name) + strlen(root->attr) + 4; + else if(root->prefix) + /* */ + start_size = strlen(root->prefix) + strlen(root->name) + 3; + else if(root->attr) + /* */ + start_size = strlen(root->name) + strlen(root->attr) + 3; + else + /* */ + start_size = strlen(root->name) + 2; + + size += start_size; + + while(child) { + if(((is_element_child = xml_is_element(child)) == 1) && level) { + size ++; /* /n */ + size += (level * space); /* space */ + } + + size += xml_tree_size(child, next_level, space); + child = child->next; + } + + if(is_element_child && level) { + size ++; /* /n */ + size += ((level - 1) * space); /* space */ + } + + if(root->prefix) + /* */ + end_size = strlen(root->prefix) + strlen(root->name) + 4; + else + /*
*/ + end_size = strlen(root->name) + 3; + + size += end_size; + } + + return size; +} + +static void _xml_dump_tree(struct xml_node *root, char *xml_buf, int level, int space) +{ + int next_level = (level)?(level + 1):0; + + if(xml_is_text(root)) { + strcat(xml_buf, root->text); + } + else if(xml_is_element(root)) { + struct xml_node *child = root->child; + int is_element_child = 0; + + if(root->prefix && root->attr) { + strcat(xml_buf, "<"); + strcat(xml_buf, root->prefix); + strcat(xml_buf, ":"); + strcat(xml_buf, root->name); + strcat(xml_buf, " "); + strcat(xml_buf, root->attr); + strcat(xml_buf, ">"); + } + else if(root->prefix) { + strcat(xml_buf, "<"); + strcat(xml_buf, root->prefix); + strcat(xml_buf, ":"); + strcat(xml_buf, root->name); + strcat(xml_buf, ">"); + } + else if(root->attr) { + strcat(xml_buf, "<"); + strcat(xml_buf, root->name); + strcat(xml_buf, " "); + strcat(xml_buf, root->attr); + strcat(xml_buf, ">"); + } + else { + strcat(xml_buf, "<"); + strcat(xml_buf, root->name); + strcat(xml_buf, ">"); + } + + while(child) { + if(((is_element_child = xml_is_element(child)) == 1) && level) { + char space_buf[11]; + int i; + + strcat(xml_buf, "\n"); + memset(space_buf, ' ', sizeof(space_buf)); + space_buf[space] = '\0'; + + for(i = 0; i < level; i ++) + strcat(xml_buf, space_buf); + } + + _xml_dump_tree(child, xml_buf, next_level, space); + child = child->next; + } + + if(is_element_child && level) { + char space_buf[11]; + int i; + + strcat(xml_buf, "\n"); + memset(space_buf, ' ', sizeof(space_buf)); + space_buf[space] = '\0'; + + for(i = 0; i < (level - 1); i ++) + strcat(xml_buf, space_buf); + } + + if(root->prefix) { + strcat(xml_buf, "prefix); + strcat(xml_buf, ":"); + strcat(xml_buf, root->name); + strcat(xml_buf, ">"); + } + else { + strcat(xml_buf, "name); + strcat(xml_buf, ">"); + } + } +} + +char *xml_dump_tree(struct xml_node *root) +{ + int xml_size; + char *xml_buf; + + xml_size = xml_tree_size(root, 0, 0); + xml_buf = (char *) xml_malloc(xml_size + 1); + memset(xml_buf, 0, xml_size + 1); + _xml_dump_tree(root, xml_buf, 0, 0); + + return xml_buf; +} + +char *xml_dump_tree_ex(struct xml_node *root, char *prolog, int new_line, int space) +{ + int xml_size; + char *xml_buf; + + /* Max offset of 10 for each level */ + if(space > 10) + space = 10; + + xml_size = xml_tree_size(root, 1, space); + + if(prolog && new_line) { + xml_buf = (char *) xml_malloc(strlen(prolog) + xml_size + 2); + memset(xml_buf, 0, strlen(prolog) + xml_size + 2); + sprintf(xml_buf, "%s\n", prolog); + _xml_dump_tree(root, xml_buf + strlen(prolog), new_line, space); + } + else if(prolog) { + xml_buf = (char *) xml_malloc(strlen(prolog) + xml_size + 1); + memset(xml_buf, 0, strlen(prolog) + xml_size + 1); + strcpy(xml_buf, prolog); + _xml_dump_tree(root, xml_buf + strlen(prolog), new_line, space); + } + else { + xml_buf = (char *) xml_malloc(xml_size + 1); + memset(xml_buf, 0, xml_size + 1); + _xml_dump_tree(root, xml_buf, new_line, space); + } + + return xml_buf; +} + +void xml_set_attribute(struct xml_node *node, char *attr, char *value) +{ + char *ns_tag, *new_attr; + + if(node->prefix) { + ns_tag = (char *) xml_malloc(strlen("xmlns:") + strlen(node->prefix) + 1); + sprintf(ns_tag, "xmlns:%s", node->prefix); + + if(strcmp(ns_tag, attr) == 0) { + if(node->uri) xml_free(node->uri); + node->uri = (char *) xml_malloc(strlen(value) + 1); + strcpy(node->uri, value); + } + + xml_free(ns_tag); + } + else { + ns_tag = "xmlns"; + + if(strcmp(ns_tag, attr) == 0) { + if(node->uri) xml_free(node->uri); + node->uri = (char *) xml_malloc(strlen(value) + 1); + strcpy(node->uri, value); + } + } + + /* attr="value" or attr='value' */ + new_attr = (char *) xml_malloc(strlen(attr) + strlen(value) + 4); + + if(strchr(value, '\"')) + sprintf(new_attr, "%s=\'%s\'", attr, value); + else + sprintf(new_attr, "%s=\"%s\"", attr, value); + + if(node->attr) { + char *attr1, *attr2, *attr_pos, *all_attr, *attr_p1 = NULL, *attr_p2 = NULL; + int attr_existed = 0; + + attr1 = (char *) xml_malloc(strlen(attr) + 4); + sprintf(attr1, " %s=\'", attr); + attr2 = (char *) xml_malloc(strlen(attr) + 4); + sprintf(attr2, " %s=\"", attr); + + if(((attr_pos = xml_strstr(node->attr, attr1)) != NULL) || + (xml_strstr(node->attr, attr1 + 1) == node->attr)) { + attr_existed = 1; + + if(attr_pos) { + attr_p1 = str_strip(node->attr, attr_pos - node->attr); + attr_p2 = str_strip(strchr(attr_pos + strlen(attr1), '\'') + 1, + node->attr + strlen(node->attr) - (strchr(attr_pos + strlen(attr1), '\'') + 1)); + } + else { + attr_p1 = NULL; + attr_p2 = str_strip(strchr(node->attr + strlen(attr1) - 1, '\'') + 1, + node->attr + strlen(node->attr) - (strchr(node->attr + strlen(attr1) - 1, '\'') + 1)); + } + } + else if(((attr_pos = xml_strstr(node->attr, attr2)) != NULL) || + (xml_strstr(node->attr, attr2 + 1) == node->attr)) { + attr_existed = 1; + + if(attr_pos) { + attr_p1 = str_strip(node->attr, attr_pos - node->attr); + attr_p2 = str_strip(strchr(attr_pos + strlen(attr2), '\"') + 1, + node->attr + strlen(node->attr) - (strchr(attr_pos + strlen(attr2), '\"') + 1)); + } + else { + attr_p1 = NULL; + attr_p2 = str_strip(strchr(node->attr + strlen(attr2) - 1, '\"') + 1, + node->attr + strlen(node->attr) - (strchr(node->attr + strlen(attr2) - 1, '\"') + 1)); + } + } + + if(attr_p1 && attr_p2) { + all_attr = (char *) xml_malloc(strlen(attr_p1) + strlen(new_attr) + strlen(attr_p2) + 3); + sprintf(all_attr, "%s %s %s", attr_p1, new_attr, attr_p2); + } + else if(attr_p1) { + all_attr = (char *) xml_malloc(strlen(attr_p1) + strlen(new_attr) + 2); + sprintf(all_attr, "%s %s", attr_p1, new_attr); + } + else if(attr_p2) { + all_attr = (char *) xml_malloc(strlen(new_attr) + strlen(attr_p2) + 2); + sprintf(all_attr, "%s %s", new_attr, attr_p2); + } + else if(attr_existed) { + all_attr = (char *) xml_malloc(strlen(new_attr) + 1); + sprintf(all_attr, "%s", new_attr); + } + else { + all_attr = (char *) xml_malloc(strlen(node->attr) + strlen(new_attr) + 2); + sprintf(all_attr, "%s %s", node->attr, new_attr); + } + + xml_free(attr1); + xml_free(attr2); + if(attr_p1) xml_free(attr_p1); + if(attr_p2) xml_free(attr_p2); + xml_free(new_attr); + xml_free(node->attr); + node->attr = all_attr; + } + else { + node->attr = new_attr; + } +} + +char *xml_get_attribute(struct xml_node *node, char *attr) +{ + char *value = NULL; + + if(node->attr) { + /* attr=' or attr=" */ + char *value_front, *value_rear, *attr1, *attr2, *attr_pos; + int value_len; + + attr1 = (char *) xml_malloc(strlen(attr) + 4); + sprintf(attr1, " %s=\'", attr); + attr2 = (char *) xml_malloc(strlen(attr) + 4); + sprintf(attr2, " %s=\"", attr); + + if(((attr_pos = xml_strstr(node->attr, attr1)) != NULL) || + (xml_strstr(node->attr, attr1 + 1) == node->attr)) { + if(attr_pos) + value_front = attr_pos + strlen(attr1); + else + value_front = node->attr + strlen(attr1) - 1; + + value_rear = strchr(value_front, '\''); + value_len = value_rear - value_front; + value = (char *) xml_malloc(value_len + 1); + memcpy(value, value_front, value_len); + value[value_len] = '\0'; + } + else if(((attr_pos = xml_strstr(node->attr, attr2)) != NULL) || + (xml_strstr(node->attr, attr2 + 1) == node->attr)) { + if(attr_pos) + value_front = attr_pos + strlen(attr2); + else + value_front = node->attr + strlen(attr2) - 1; + + value_rear = strchr(value_front, '\"'); + value_len = value_rear - value_front; + value = (char *) xml_malloc(value_len + 1); + memcpy(value, value_front, value_len); + value[value_len] = '\0'; + } + + xml_free(attr1); + xml_free(attr2); + } + + return value; +} + diff --git a/USDK/component/common/utilities/xml.h b/USDK/component/common/utilities/xml.h new file mode 100644 index 0000000..433ccbf --- /dev/null +++ b/USDK/component/common/utilities/xml.h @@ -0,0 +1,43 @@ +#ifndef _XML_H_ +#define _XML_H_ + +struct xml_node { + char *name; + char *text; + char *prefix; + char *uri; + char *attr; + struct xml_node *parent; + struct xml_node *child; + struct xml_node *prev; + struct xml_node *next; +}; + +struct xml_node_set { + int count; + struct xml_node **node; +}; + +void xml_free(void *buf); +int xml_doc_name(char *doc_buf, int doc_len, char **doc_prefix, char **doc_name, char **doc_uri); +struct xml_node *xml_parse_doc(char *doc_buf, int doc_len, char *prefix, char *doc_name, char *uri); +struct xml_node *xml_parse(char *doc_buf, int doc_len); +struct xml_node *xml_new_element(char *prefix, char *name, char *uri); +struct xml_node *xml_new_text(char *text); +int xml_is_element(struct xml_node *node); +int xml_is_text(struct xml_node *node); +struct xml_node* xml_copy_tree(struct xml_node *root); +void xml_delete_tree(struct xml_node *root); +void xml_add_child(struct xml_node *node, struct xml_node *child); +void xml_clear_child(struct xml_node *node); +struct xml_node* xml_text_child(struct xml_node *node); +void xml_set_text(struct xml_node *node, char *text); +struct xml_node_set* xml_find_element(struct xml_node *root, char *name); +struct xml_node_set* xml_find_path(struct xml_node *root, char *path); +void xml_delete_set(struct xml_node_set *node_set); +char *xml_dump_tree(struct xml_node *root); +char *xml_dump_tree_ex(struct xml_node *root, char *prolog, int new_line, int space); +void xml_set_attribute(struct xml_node *node, char *attr, char *value); +char *xml_get_attribute(struct xml_node *node, char *attr); + +#endif diff --git a/USDK/component/common/video/v4l2/inc/media-device.h b/USDK/component/common/video/v4l2/inc/media-device.h new file mode 100644 index 0000000..ca5017c --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/media-device.h @@ -0,0 +1,105 @@ +/* + * Media device + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MEDIA_DEVICE_H +#define _MEDIA_DEVICE_H + +#if 0 +#include +#include +#include +#endif + +#include "v4l2-osdep.h" +#include "media-devnode.h" +#include "media-entity.h" + + +//struct device; + +/** + * struct media_device - Media device + * @dev: Parent device + * @devnode: Media device node + * @model: Device model name + * @serial: Device serial number (optional) + * @bus_info: Unique and stable device location identifier + * @hw_revision: Hardware device revision + * @driver_version: Device driver version + * @entity_id: ID of the next entity to be registered + * @entities: List of registered entities + * @lock: Entities list lock + * @graph_mutex: Entities graph operation lock + * @link_notify: Link state change notification callback + * + * This structure represents an abstract high-level media device. It allows easy + * access to entities and provides basic media device-level support. The + * structure can be allocated directly or embedded in a larger structure. + * + * The parent @dev is a physical device. It must be set before registering the + * media device. + * + * @model is a descriptive model name exported through sysfs. It doesn't have to + * be unique. + */ +struct media_device { + /* dev->driver_data points to this struct. */ + //struct device *dev; + struct media_devnode devnode; + + char model[32]; + char serial[40]; + char bus_info[32]; + u32 hw_revision; + u32 driver_version; + + u32 entity_id; + struct list_head entities; + + /* Protects the entities list */ + spinlock_t lock; + /* Serializes graph operations. */ + //struct mutex graph_mutex; + _Mutex graph_mutex; + + int (*link_notify)(struct media_link *link, u32 flags, unsigned int notification); +}; + +/* Supported link_notify @notification values. */ +#define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0 +#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 + +/* media_devnode to media_device */ +#define to_media_device(node) container_of(node, struct media_device, devnode) + +int media_device_register(struct media_device *mdev); +void media_device_unregister(struct media_device *mdev); + +int media_device_register_entity(struct media_device *mdev, + struct media_entity *entity); +void media_device_unregister_entity(struct media_entity *entity); + +/* Iterate over all entities. */ +#define media_device_for_each_entity(entity, mdev, type) \ + list_for_each_entry(entity, &(mdev)->entities, list, type) + +#endif diff --git a/USDK/component/common/video/v4l2/inc/media-devnode.h b/USDK/component/common/video/v4l2/inc/media-devnode.h new file mode 100644 index 0000000..cbbbe7b --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/media-devnode.h @@ -0,0 +1,104 @@ +/* + * Media device node + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * -- + * + * Common functions for media-related drivers to register and unregister media + * device nodes. + */ + +#ifndef _MEDIA_DEVNODE_H +#define _MEDIA_DEVNODE_H + +#if 0 +#include +#include +#include +#include +#endif + + +/* + * Flag to mark the media_devnode struct as registered. Drivers must not touch + * this flag directly, it will be set and cleared by media_devnode_register and + * media_devnode_unregister. + */ +#define MEDIA_FLAG_REGISTERED 0 + +struct media_file_operations { + //struct module *owner; +#if 0 + ssize_t (*read) (char __user *, size_t, loff_t *); + ssize_t (*write) (const char __user *, size_t, loff_t *); + unsigned int (*poll) (struct poll_table_struct *); +#endif + long (*ioctl) (unsigned int, unsigned long); + long (*compat_ioctl) (unsigned int, unsigned long); + int (*open) (); + int (*release) (); +}; + +/** + * struct media_devnode - Media device node + * @parent: parent device + * @minor: device node minor number + * @flags: flags, combination of the MEDIA_FLAG_* constants + * + * This structure represents a media-related device node. + * + * The @parent is a physical device. It must be set by core or device drivers + * before registering the node. + */ +struct media_devnode { + /* device ops */ + const struct media_file_operations *fops; + + /* sysfs */ +#if 0 + struct device dev; /* media device */ + struct cdev cdev; /* character device */ + struct device *parent; /* device parent */ +#endif + /* device info */ + int minor; + unsigned long flags; /* Use bitops to access flags */ + + /* callbacks */ + void (*release)(struct media_devnode *mdev); +}; + +/* dev to media_devnode */ +#define to_media_devnode(minor) container_of(minor, struct media_devnode, dev) + +int media_devnode_register(struct media_devnode *mdev); +void media_devnode_unregister(struct media_devnode *mdev); +#if 0 +static inline struct media_devnode *media_devnode_data() +{ + return private_data; +} +#endif +static inline int media_devnode_is_registered(struct media_devnode *mdev) +{ + return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); +} + +#endif /* _MEDIA_DEVNODE_H */ diff --git a/USDK/component/common/video/v4l2/inc/media-entity.h b/USDK/component/common/video/v4l2/inc/media-entity.h new file mode 100644 index 0000000..ccc3886 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/media-entity.h @@ -0,0 +1,164 @@ +/* + * Media entity + * + * Copyright (C) 2010 Nokia Corporation + * + * Contacts: Laurent Pinchart + * Sakari Ailus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MEDIA_ENTITY_H +#define _MEDIA_ENTITY_H + +#if 0 +#include +#include +#include +#endif +#include "v4l2-osdep.h" + + +struct media_pipeline { + int media_test; +}; + +struct media_link { + struct media_pad *source; /* Source pad */ + struct media_pad *sink; /* Sink pad */ + struct media_link *reverse; /* Link in the reverse direction */ + unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ +}; + +struct media_pad { + struct media_entity *entity; /* Entity this pad belongs to */ + u16 index; /* Pad index in the entity pads array */ + unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ +}; + +struct media_entity_operations { + int (*link_setup)(struct media_entity *entity, + const struct media_pad *local, + const struct media_pad *remote, u32 flags); + int (*link_validate)(struct media_link *link); +}; + +struct media_entity { + //struct LISlist; + struct media_device *parent; /* Media device this entity belongs to*/ + u32 id; /* Entity ID, unique in the parent media + * device context */ + const char *name; /* Entity name */ + u32 type; /* Entity type (MEDIA_ENT_T_*) */ + u32 revision; /* Entity revision, driver specific */ + unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */ + u32 group_id; /* Entity group ID */ + + u16 num_pads; /* Number of sink and source pads */ + u16 num_links; /* Number of existing links, both + * enabled and disabled */ + u16 num_backlinks; /* Number of backlinks */ + u16 max_links; /* Maximum number of links */ + + struct media_pad *pads; /* Pads array (num_pads elements) */ + struct media_link *links; /* Links array (max_links elements)*/ + + const struct media_entity_operations *ops; /* Entity operations */ + + /* Reference counts must never be negative, but are signed integers on + * purpose: a simple WARN_ON(<0) check can be used to detect reference + * count bugs that would make them negative. + */ + int stream_count; /* Stream count for the entity. */ + int use_count; /* Use count for the entity. */ + + struct media_pipeline *pipe; /* Pipeline this entity belongs to. */ + + union { + /* Node specifications */ + struct { + u32 major; + u32 minor; + } v4l; + struct { + u32 major; + u32 minor; + } fb; + struct { + u32 card; + u32 device; + u32 subdevice; + } alsa; + int dvb; + + /* Sub-device specifications */ + /* Nothing needed yet */ + } info; +}; +#if 0 +static inline u32 media_entity_type(struct media_entity *entity) +{ + return entity->type & MEDIA_ENT_TYPE_MASK; +} + +static inline u32 media_entity_subtype(struct media_entity *entity) +{ + return entity->type & MEDIA_ENT_SUBTYPE_MASK; +} + +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 +#define MEDIA_ENTITY_ENUM_MAX_ID 64 + +struct media_entity_graph { + struct { + struct media_entity *entity; + int link; + } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; + + DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); + int top; +}; + +int media_entity_init(struct media_entity *entity, u16 num_pads, + struct media_pad *pads, u16 extra_links); +void media_entity_cleanup(struct media_entity *entity); + +int media_entity_create_link(struct media_entity *source, u16 source_pad, + struct media_entity *sink, u16 sink_pad, u32 flags); +void __media_entity_remove_links(struct media_entity *entity); +void media_entity_remove_links(struct media_entity *entity); + +int __media_entity_setup_link(struct media_link *link, u32 flags); +int media_entity_setup_link(struct media_link *link, u32 flags); +struct media_link *media_entity_find_link(struct media_pad *source, + struct media_pad *sink); +struct media_pad *media_entity_remote_pad(struct media_pad *pad); + +struct media_entity *media_entity_get(struct media_entity *entity); +void media_entity_put(struct media_entity *entity); + +void media_entity_graph_walk_start(struct media_entity_graph *graph, + struct media_entity *entity); +struct media_entity * +media_entity_graph_walk_next(struct media_entity_graph *graph); +int media_entity_pipeline_start(struct media_entity *entity, + struct media_pipeline *pipe); +void media_entity_pipeline_stop(struct media_entity *entity); + +#define media_entity_call(entity, operation, args...) \ + (((entity)->ops && (entity)->ops->operation) ? \ + (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) +#endif +#endif diff --git a/USDK/component/common/video/v4l2/inc/uapi_v4l2-common.h b/USDK/component/common/video/v4l2/inc/uapi_v4l2-common.h new file mode 100644 index 0000000..4f0667e --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/uapi_v4l2-common.h @@ -0,0 +1,71 @@ +/* + * include/linux/v4l2-common.h + * + * Common V4L2 and V4L2 subdev definitions. + * + * Users are advised to #include this file either through videodev2.h + * (V4L2) or through v4l2-subdev.h (V4L2 subdev) rather than to refer + * to this file directly. + * + * Copyright (C) 2012 Nokia Corporation + * Contact: Sakari Ailus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __V4L2_COMMON__ +#define __V4L2_COMMON__ + +/* + * + * Selection interface definitions + * + */ + +/* Current cropping area */ +#define V4L2_SEL_TGT_CROP 0x0000 +/* Default cropping area */ +#define V4L2_SEL_TGT_CROP_DEFAULT 0x0001 +/* Cropping bounds */ +#define V4L2_SEL_TGT_CROP_BOUNDS 0x0002 +/* Current composing area */ +#define V4L2_SEL_TGT_COMPOSE 0x0100 +/* Default composing area */ +#define V4L2_SEL_TGT_COMPOSE_DEFAULT 0x0101 +/* Composing bounds */ +#define V4L2_SEL_TGT_COMPOSE_BOUNDS 0x0102 +/* Current composing area plus all padding pixels */ +#define V4L2_SEL_TGT_COMPOSE_PADDED 0x0103 + +/* Backward compatibility target definitions --- to be removed. */ +#define V4L2_SEL_TGT_CROP_ACTIVE V4L2_SEL_TGT_CROP +#define V4L2_SEL_TGT_COMPOSE_ACTIVE V4L2_SEL_TGT_COMPOSE +#define V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL V4L2_SEL_TGT_CROP +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL V4L2_SEL_TGT_COMPOSE +#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS V4L2_SEL_TGT_CROP_BOUNDS +#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS V4L2_SEL_TGT_COMPOSE_BOUNDS + +/* Selection flags */ +#define V4L2_SEL_FLAG_GE (1 << 0) +#define V4L2_SEL_FLAG_LE (1 << 1) +#define V4L2_SEL_FLAG_KEEP_CONFIG (1 << 2) + +/* Backward compatibility flag definitions --- to be removed. */ +#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE V4L2_SEL_FLAG_GE +#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE V4L2_SEL_FLAG_LE +#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG V4L2_SEL_FLAG_KEEP_CONFIG + +#endif /* __V4L2_COMMON__ */ diff --git a/USDK/component/common/video/v4l2/inc/uapi_videodev2.h b/USDK/component/common/video/v4l2/inc/uapi_videodev2.h new file mode 100644 index 0000000..ebdf807 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/uapi_videodev2.h @@ -0,0 +1,2225 @@ +/* + * Video for Linux Two header file + * + * Copyright (C) 1999-2012 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Header file for v4l or V4L2 drivers and applications + * with public API. + * All kernel-specific stuff were moved to media/v4l2-dev.h, so + * no #if __KERNEL tests are allowed here + * + * See http://linuxtv.org for more info + * + * Author: Bill Dirks + * Justin Schoeman + * Hans Verkuil + * et al. + */ +#ifndef _UAPI__LINUX_VIDEODEV2_H +#define _UAPI__LINUX_VIDEODEV2_H + +#ifndef __KERNEL__ +//#include +#endif + +/* TODO: may need to find some file to repalce */ +#if 0 +#include +#include +#include +#endif +#include "v4l2-osdep.h" +#include "v4l2-common.h" +#include "v4l2-controls.h" + +/*Add by Ian -- define v4l2_probe function type*/ +typedef void(*v4l2_probe_t)(void); + +/* + * Common stuff for both V4L1 and V4L2 + * Moved from videodev.h + */ +#define VIDEO_MAX_FRAME 6 +#define VIDEO_MAX_PLANES 1 + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a, b, c, d)\ + ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into + separate buffers */ + V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field + first and the top field is + transmitted first */ + V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field + first and the bottom field is + transmitted first */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_INTERLACED_TB ||\ + (field) == V4L2_FIELD_INTERLACED_BT ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6, + V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7, +#if 1 + /* Experimental */ + V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, +#endif + V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, + V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10, + /* Deprecated, do not use */ + V4L2_BUF_TYPE_PRIVATE = 0x80, +}; + +#define V4L2_TYPE_IS_MULTIPLANAR(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) + +#define V4L2_TYPE_IS_OUTPUT(type) \ + ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \ + || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \ + || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \ + || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2, + V4L2_TUNER_DIGITAL_TV = 3, +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3, + V4L2_MEMORY_DMABUF = 4, +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8, +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/** + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP + * + * @driver: name of the driver module (e.g. "bttv") + * @card: name of the card (e.g. "Hauppauge WinTV") + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) + * @version: KERNEL_VERSION + * @capabilities: capabilities of the physical device as a whole + * @device_caps: capabilities accessed via this particular device (node) + * @reserved: reserved fields for future extensions + */ +struct v4l2_capability { + __u8 driver[16]; + __u8 card[32]; + __u8 bus_info[32]; + __u32 version; + __u32 capabilities; + __u32 device_caps; + __u32 reserved[3]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */ +#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */ +#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ +#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ +#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ + +/* Is a video capture device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000 +/* Is a video output device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000 +/* Is a video mem-to-mem device that supports multiplanar formats */ +#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000 +/* Is a video mem-to-mem device */ +#define V4L2_CAP_VIDEO_M2M 0x00008000 + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ +#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format { + __u32 width; + __u32 height; + __u32 pixelformat; + __u32 field; /* enum v4l2_field */ + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + __u32 colorspace; /* enum v4l2_colorspace */ + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ + +/* RGB formats */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */ + +/* Grey formats */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ +#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */ +#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 Greyscale */ +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') /* 12 Greyscale */ +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */ + +/* Grey bit-packed formats */ +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') /* 10 Greyscale bit-packed */ + +/* Palette formats */ +#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */ + +/* Chrominance formats */ +#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ') /* 8 UV 4:4 */ + +/* Luminance+Chrominance formats */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ +#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */ +#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */ +#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */ +#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */ +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ +#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */ +#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1') /* 16 Y/CrCb 4:2:2 */ +#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ + +/* three non contiguous planes - Y, Cb, Cr */ +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */ + +/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') /* 8 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') /* 10 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ +#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */ +#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */ +#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */ + /* 10bit raw bayer a-law compressed to 8 bits */ +#define V4L2_PIX_FMT_SBGGR10ALAW8 v4l2_fourcc('a', 'B', 'A', '8') +#define V4L2_PIX_FMT_SGBRG10ALAW8 v4l2_fourcc('a', 'G', 'A', '8') +#define V4L2_PIX_FMT_SGRBG10ALAW8 v4l2_fourcc('a', 'g', 'A', '8') +#define V4L2_PIX_FMT_SRGGB10ALAW8 v4l2_fourcc('a', 'R', 'A', '8') + /* 10bit raw bayer DPCM compressed to 8 bits */ +#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8') +#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8') +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') +#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') + /* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 Multiplexed */ +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */ +#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */ +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */ +#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */ +#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */ +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG-4 part 2 ES */ +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') /* Xvid */ +#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') /* SMPTE 421M Annex G compliant stream */ +#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') /* SMPTE 421M Annex L compliant stream */ +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') /* cpia1 YUV */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */ +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */ +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */ +#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */ +#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */ +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */ +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */ +#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ +#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ +#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ +#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */ +#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') /* se401 janggu compressed rgb */ +#define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') /* S5C73M3 interleaved UYVY/JPEG */ +/* edit by Ian -- Patch for GEO */ +/* definition for MUX format */ +#ifndef V4L2_PIX_FMT_MUX +#define V4L2_PIX_FMT_MUX v4l2_fourcc('M', 'U', 'X', ' ') /* MUX stream */ +#endif + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc { + __u32 index; /* Format number */ + __u32 type; /* enum v4l2_buf_type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 +#define V4L2_FMT_FLAG_EMULATED 0x0002 + +#if 1 + /* Experimental Frame Size and frame rate enumeration */ +/* + * F R A M E S I Z E E N U M E R A T I O N + */ +enum v4l2_frmsizetypes { + V4L2_FRMSIZE_TYPE_DISCRETE = 1, + V4L2_FRMSIZE_TYPE_CONTINUOUS = 2, + V4L2_FRMSIZE_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmsize_discrete { + __u32 width; /* Frame width [pixel] */ + __u32 height; /* Frame height [pixel] */ +}; + +struct v4l2_frmsize_stepwise { + __u32 min_width; /* Minimum frame width [pixel] */ + __u32 max_width; /* Maximum frame width [pixel] */ + __u32 step_width; /* Frame width step size [pixel] */ + __u32 min_height; /* Minimum frame height [pixel] */ + __u32 max_height; /* Maximum frame height [pixel] */ + __u32 step_height; /* Frame height step size [pixel] */ +}; + +struct v4l2_frmsizeenum { + __u32 index; /* Frame size number */ + __u32 pixel_format; /* Pixel format */ + __u32 type; /* Frame size type the device supports. */ + + union { /* Frame size */ + struct v4l2_frmsize_discrete discrete; + struct v4l2_frmsize_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; + +/* + * F R A M E R A T E E N U M E R A T I O N + */ +enum v4l2_frmivaltypes { + V4L2_FRMIVAL_TYPE_DISCRETE = 1, + V4L2_FRMIVAL_TYPE_CONTINUOUS = 2, + V4L2_FRMIVAL_TYPE_STEPWISE = 3, +}; + +struct v4l2_frmival_stepwise { + struct v4l2_fract min; /* Minimum frame interval [s] */ + struct v4l2_fract max; /* Maximum frame interval [s] */ + struct v4l2_fract step; /* Frame interval step size [s] */ +}; + +struct v4l2_frmivalenum { + __u32 index; /* Frame format index */ + __u32 pixel_format; /* Pixel format */ + __u32 width; /* Frame width */ + __u32 height; /* Frame height */ + __u32 type; /* Frame interval type the device supports. */ + + union { /* Frame interval */ + struct v4l2_fract discrete; + struct v4l2_frmival_stepwise stepwise; + }; + + __u32 reserved[2]; /* Reserved space for future use */ +}; +#endif + +/* + * T I M E C O D E + */ +struct v4l2_timecode { + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + +struct v4l2_jpegcompression { + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Including less markers will make the + * resulting code smaller, but there will + * be fewer applications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * always use APP0 */ +}; + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers { + __u32 count; + __u32 type; /* enum v4l2_buf_type */ + __u32 memory; /* enum v4l2_memory */ + __u32 reserved[2]; +}; + +/** + * struct v4l2_plane - plane info for multi-planar buffers + * @bytesused: number of bytes occupied by data in the plane (payload) + * @length: size of this plane (NOT the payload) in bytes + * @mem_offset: when memory in the associated struct v4l2_buffer is + * V4L2_MEMORY_MMAP, equals the offset from the start of + * the device memory for this plane (or is a "cookie" that + * should be passed to mmap() called on the video node) + * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer + * pointing to this plane + * @fd: when memory is V4L2_MEMORY_DMABUF, a userspace file + * descriptor associated with this plane + * @data_offset: offset in the plane to the start of data; usually 0, + * unless there is a header in front of the data + * + * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer + * with two planes can have one plane for Y, and another for interleaved CbCr + * components. Each plane can reside in a separate memory buffer, or even in + * a completely separate memory node (e.g. in embedded devices). + */ +struct v4l2_plane { + __u32 bytesused; + __u32 length; + union { + __u32 mem_offset; + unsigned long userptr; + __s32 fd; + } m; + __u32 data_offset; + __u32 reserved[11]; +}; + +/** + * struct v4l2_buffer - video buffer info + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @bytesused: number of bytes occupied by data in the buffer (payload); + * unused (set to 0) for multiplanar buffers + * @flags: buffer informational flags + * @field: enum v4l2_field; field order of the image in the buffer + * @timestamp: frame timestamp + * @timecode: frame timecode + * @sequence: sequence count of this frame + * @memory: enum v4l2_memory; the method, in which the actual video data is + * passed + * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; + * offset from the start of the device memory for this plane, + * (or a "cookie" that should be passed to mmap() as offset) + * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; + * a userspace pointer pointing to this buffer + * @fd: for non-multiplanar buffers with memory == V4L2_MEMORY_DMABUF; + * a userspace file descriptor associated with this buffer + * @planes: for multiplanar buffers; userspace pointer to the array of plane + * info structs for this buffer + * @length: size in bytes of the buffer (NOT its payload) for single-plane + * buffers (when type != *_MPLANE); number of elements in the + * planes array for multi-plane buffers + * @input: input number from which the video data has has been captured + * + * Contains data exchanged by application and driver using one of the Streaming + * I/O methods. + */ +struct v4l2_buffer { + __u32 index; + __u32 type; + __u32 bytesused; + __u32 flags; + __u32 field; + //struct timeval timestamp; + __u32 timestamp; + __u32 timepadding; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + __u32 memory; + union { + __u32 offset; + unsigned long userptr; + struct v4l2_plane *planes; + __s32 fd; + } m; + __u32 length; + __u32 reserved2; + __u32 reserved; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +/* Buffer is ready, but the data contained within is corrupted. */ +#define V4L2_BUF_FLAG_ERROR 0x0040 +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ +#define V4L2_BUF_FLAG_PREPARED 0x0400 /* Buffer is prepared for queuing */ +/* Cache handling flags */ +#define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800 +#define V4L2_BUF_FLAG_NO_CACHE_CLEAN 0x1000 +/* Timestamp type */ +#define V4L2_BUF_FLAG_TIMESTAMP_MASK 0xe000 +#define V4L2_BUF_FLAG_TIMESTAMP_UNKNOWN 0x0000 +#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000 +#define V4L2_BUF_FLAG_TIMESTAMP_COPY 0x4000 + +/** + * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor + * + * @index: id number of the buffer + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * @fd: file descriptor associated with DMABUF (set by driver) + * + * Contains data used for exporting a video buffer as DMABUF file descriptor. + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF + * (identical to the cookie used to mmap() the buffer to userspace). All + * reserved fields must be set to zero. The field reserved0 is expected to + * become a structure 'type' allowing an alternative layout of the structure + * content. Therefore this field should not be used for any other extensions. + */ +struct v4l2_exportbuffer { + __u32 type; /* enum v4l2_buf_type */ + __u32 index; + __u32 plane; + __u32 flags; + __s32 fd; + __u32 reserved[11]; +}; + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer { + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void *base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010 +#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020 +#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040 +#define V4L2_FBUF_CAP_SRC_CHROMAKEY 0x0080 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 +#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008 +#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010 +#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020 +#define V4L2_FBUF_FLAG_SRC_CHROMAKEY 0x0040 + +struct v4l2_clip { + struct v4l2_rect c; + struct v4l2_clip __user *next; +}; + +struct v4l2_window { + struct v4l2_rect w; + __u32 field; /* enum v4l2_field */ + __u32 chromakey; + struct v4l2_clip __user *clips; + __u32 clipcount; + void __user *bitmap; + __u8 global_alpha; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm { + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; + +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm { + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap { + __u32 type; /* enum v4l2_buf_type */ + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + __u32 type; /* enum v4l2_buf_type */ + struct v4l2_rect c; +}; + +/** + * struct v4l2_selection - selection info + * @type: buffer type (do not use *_MPLANE types) + * @target: Selection target, used to choose one of possible rectangles; + * defined in v4l2-common.h; V4L2_SEL_TGT_* . + * @flags: constraints flags, defined in v4l2-common.h; V4L2_SEL_FLAG_*. + * @r: coordinates of selection window + * @reserved: for future use, rounds structure size to 64 bytes, set to zero + * + * Hardware may use multiple helper windows to process a video stream. + * The structure is used to exchange this selection areas between + * an application and a driver. + */ +struct v4l2_selection { + __u32 type; + __u32 target; + __u32 flags; + struct v4l2_rect r; + __u32 reserved[9]; +}; + + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef __u64 v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) /* BTSC */ +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) /* EIA-J */ +#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) +#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) /* FM A2 */ + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) +#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* FIXME: + Although std_id is 64 bits, there is an issue on PPC32 architecture that + makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding + this value to 32 bits. + As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), + it should work fine. However, if needed to add more than two standards, + v4l2-common.c should be fixed. + */ + +/* + * Some macros to merge video standards in order to make live easier for the + * drivers and V4L2 applications + */ + +/* + * "Common" NTSC/M - It should be noticed that V4L2_STD_NTSC_443 is + * Missing here. + */ +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP |\ + V4L2_STD_NTSC_M_KR) +/* Secam macros */ +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1) +/* All Secam Standards */ +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_DK |\ + V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +/* PAL macros */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +/* + * "Common" PAL - This macro is there to be compatible with the old + * V4L1 concept of "PAL": /BGDKHI. + * Several PAL standards are missing here: /M, /N and /Nc + */ +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +/* Chroma "agnostic" standards */ +#define V4L2_STD_B (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_SECAM_B) +#define V4L2_STD_G (V4L2_STD_PAL_G |\ + V4L2_STD_SECAM_G) +#define V4L2_STD_H (V4L2_STD_PAL_H |\ + V4L2_STD_SECAM_H) +#define V4L2_STD_L (V4L2_STD_SECAM_L |\ + V4L2_STD_SECAM_LC) +#define V4L2_STD_GH (V4L2_STD_G |\ + V4L2_STD_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK |\ + V4L2_STD_SECAM_DK) +#define V4L2_STD_BG (V4L2_STD_B |\ + V4L2_STD_G) +#define V4L2_STD_MN (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_NTSC) + +/* Standards where MTS/BTSC stereo could be found */ +#define V4L2_STD_MTS (V4L2_STD_NTSC_M |\ + V4L2_STD_PAL_M |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc) + +/* Standards for Countries with 60Hz Line frequency */ +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC |\ + V4L2_STD_NTSC_443) +/* Standards for Countries with 50Hz Line frequency */ +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\ + V4L2_STD_ATSC_16_VSB) +/* Macros with none and all analog standards */ +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard { + __u32 index; + //v4l2_std_id id; + __u64 id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + +/* + * D V B T T I M I N G S + */ + +/** struct v4l2_bt_timings - BT.656/BT.1120 timing data + * @width: total width of the active video in pixels + * @height: total height of the active video in lines + * @interlaced: Interlaced or progressive + * @polarities: Positive or negative polarities + * @pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @hfrontporch:Horizontal front porch in pixels + * @hsync: Horizontal Sync length in pixels + * @hbackporch: Horizontal back porch in pixels + * @vfrontporch:Vertical front porch in lines + * @vsync: Vertical Sync length in lines + * @vbackporch: Vertical back porch in lines + * @il_vfrontporch:Vertical front porch for the even field + * (aka field 2) of interlaced field formats + * @il_vsync: Vertical Sync length for the even field + * (aka field 2) of interlaced field formats + * @il_vbackporch:Vertical back porch for the even field + * (aka field 2) of interlaced field formats + * @standards: Standards the timing belongs to + * @flags: Flags + * @reserved: Reserved fields, must be zeroed. + * + * A note regarding vertical interlaced timings: height refers to the total + * height of the active video frame (= two fields). The blanking timings refer + * to the blanking of each field. So the height of the total frame is + * calculated as follows: + * + * tot_height = height + vfrontporch + vsync + vbackporch + + * il_vfrontporch + il_vsync + il_vbackporch + * + * The active height of each field is height / 2. + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_bt_timings { + __u32 width; + __u32 height; + __u32 interlaced; + __u32 polarities; + __u64 pixelclock; + __u32 hfrontporch; + __u32 hsync; + __u32 hbackporch; + __u32 vfrontporch; + __u32 vsync; + __u32 vbackporch; + __u32 il_vfrontporch; + __u32 il_vsync; + __u32 il_vbackporch; + __u32 standards; + __u32 flags; + __u32 reserved[14]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +/* Interlaced or progressive format */ +#define V4L2_DV_PROGRESSIVE 0 +#define V4L2_DV_INTERLACED 1 + +/* Polarities. If bit is not set, it is assumed to be negative polarity */ +#define V4L2_DV_VSYNC_POS_POL 0x00000001 +#define V4L2_DV_HSYNC_POS_POL 0x00000002 + +/* Timings standards */ +#define V4L2_DV_BT_STD_CEA861 (1 << 0) /* CEA-861 Digital TV Profile */ +#define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */ +#define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */ +#define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */ + +/* Flags */ + +/* CVT/GTF specific: timing uses reduced blanking (CVT) or the 'Secondary + GTF' curve (GTF). In both cases the horizontal and/or vertical blanking + intervals are reduced, allowing a higher resolution over the same + bandwidth. This is a read-only flag. */ +#define V4L2_DV_FL_REDUCED_BLANKING (1 << 0) +/* CEA-861 specific: set for CEA-861 formats with a framerate of a multiple + of six. These formats can be optionally played at 1 / 1.001 speed. + This is a read-only flag. */ +#define V4L2_DV_FL_CAN_REDUCE_FPS (1 << 1) +/* CEA-861 specific: only valid for video transmitters, the flag is cleared + by receivers. + If the framerate of the format is a multiple of six, then the pixelclock + used to set up the transmitter is divided by 1.001 to make it compatible + with 60 Hz based standards such as NTSC and PAL-M that use a framerate of + 29.97 Hz. Otherwise this flag is cleared. If the transmitter can't generate + such frequencies, then the flag will also be cleared. */ +#define V4L2_DV_FL_REDUCED_FPS (1 << 2) +/* Specific to interlaced formats: if set, then field 1 is really one half-line + longer and field 2 is really one half-line shorter, so each field has + exactly the same number of half-lines. Whether half-lines can be detected + or used depends on the hardware. */ +#define V4L2_DV_FL_HALF_LINE (1 << 3) + +/* A few useful defines to calculate the total blanking and frame sizes */ +#define V4L2_DV_BT_BLANKING_WIDTH(bt) \ + (bt->hfrontporch + bt->hsync + bt->hbackporch) +#define V4L2_DV_BT_FRAME_WIDTH(bt) \ + (bt->width + V4L2_DV_BT_BLANKING_WIDTH(bt)) +#define V4L2_DV_BT_BLANKING_HEIGHT(bt) \ + (bt->vfrontporch + bt->vsync + bt->vbackporch + \ + bt->il_vfrontporch + bt->il_vsync + bt->il_vbackporch) +#define V4L2_DV_BT_FRAME_HEIGHT(bt) \ + (bt->height + V4L2_DV_BT_BLANKING_HEIGHT(bt)) + +/** struct v4l2_dv_timings - DV timings + * @type: the type of the timings + * @bt: BT656/1120 timings + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_dv_timings { + __u32 type; + union { + struct v4l2_bt_timings bt; + __u32 reserved[32]; + }; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +/* Values for the type field */ +#define V4L2_DV_BT_656_1120 0 /* BT.656/1120 timing type */ + + +/** struct v4l2_enum_dv_timings - DV timings enumeration + * @index: enumeration index + * @reserved: must be zeroed + * @timings: the timings for the given index + */ +struct v4l2_enum_dv_timings { + __u32 index; + __u32 reserved[3]; + struct v4l2_dv_timings timings; +}; + +/** struct v4l2_bt_timings_cap - BT.656/BT.1120 timing capabilities + * @min_width: width in pixels + * @max_width: width in pixels + * @min_height: height in lines + * @max_height: height in lines + * @min_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @max_pixelclock: Pixel clock in HZ. Ex. 74.25MHz->74250000 + * @standards: Supported standards + * @capabilities: Supported capabilities + * @reserved: Must be zeroed + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_bt_timings_cap { + __u32 min_width; + __u32 max_width; + __u32 min_height; + __u32 max_height; + __u64 min_pixelclock; + __u64 max_pixelclock; + __u32 standards; + __u32 capabilities; + __u32 reserved[16]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +/* Supports interlaced formats */ +#define V4L2_DV_BT_CAP_INTERLACED (1 << 0) +/* Supports progressive formats */ +#define V4L2_DV_BT_CAP_PROGRESSIVE (1 << 1) +/* Supports CVT/GTF reduced blanking */ +#define V4L2_DV_BT_CAP_REDUCED_BLANKING (1 << 2) +/* Supports custom formats */ +#define V4L2_DV_BT_CAP_CUSTOM (1 << 3) + +/** struct v4l2_dv_timings_cap - DV timings capabilities + * @type: the type of the timings (same as in struct v4l2_dv_timings) + * @bt: the BT656/1120 timings capabilities + */ +struct v4l2_dv_timings_cap { + __u32 type; + __u32 reserved[3]; + union { + struct v4l2_bt_timings_cap bt; + __u32 raw_data[32]; + }; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input { + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* enum v4l2_tuner_type */ + //v4l2_std_id std; + __u64 std; + __u32 status; + __u32 capabilities; + __u32 reserved[3]; +}; + +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - sensor orientation */ +/* If sensor is mounted upside down set both bits */ +#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */ +#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */ + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* capabilities flags */ +#define V4L2_IN_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_IN_CAP_CUSTOM_TIMINGS V4L2_IN_CAP_DV_TIMINGS /* For compatibility */ +#define V4L2_IN_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output { + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + //v4l2_std_id std; + __u64 std; + __u32 capabilities; + __u32 reserved[3]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* capabilities flags */ +#define V4L2_OUT_CAP_DV_TIMINGS 0x00000002 /* Supports S_DV_TIMINGS */ +#define V4L2_OUT_CAP_CUSTOM_TIMINGS V4L2_OUT_CAP_DV_TIMINGS /* For compatibility */ +#define V4L2_OUT_CAP_STD 0x00000004 /* Supports S_STD */ + +/* + * C O N T R O L S + */ +struct v4l2_control { + __u32 id; + __s32 value; +}; + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + }; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +struct v4l2_ext_controls { + __u32 ctrl_class; + __u32 count; + __u32 error_idx; + __u32 reserved[2]; + struct v4l2_ext_control *controls; +}; + +#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) +#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000) + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4, + V4L2_CTRL_TYPE_INTEGER64 = 5, + V4L2_CTRL_TYPE_CTRL_CLASS = 6, + V4L2_CTRL_TYPE_STRING = 7, + V4L2_CTRL_TYPE_BITMASK = 8, + V4L2_CTRL_TYPE_INTEGER_MENU = 9, +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl { + __u32 id; + __u32 type; /* enum v4l2_ctrl_type */ + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_querymenu { + __u32 id; + __u32 index; + union { + __u8 name[32]; /* Whatever */ + __s64 value; + }; + __u32 reserved; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +#include "pack_end.h" +#endif + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 +#define V4L2_CTRL_FLAG_VOLATILE 0x0080 + +/* Query flag, to be ORed with the control ID */ +#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 + +/* User-class control IDs defined by V4L2 */ +#define V4L2_CID_MAX_CTRLS 1024 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + + +/* + * T U N I N G + */ +struct v4l2_tuner { + __u32 index; + __u8 name[32]; + __u32 type; /* enum v4l2_tuner_type */ + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_HWSEEK_BOUNDED 0x0004 +#define V4L2_TUNER_CAP_HWSEEK_WRAP 0x0008 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 +#define V4L2_TUNER_CAP_RDS 0x0080 +#define V4L2_TUNER_CAP_RDS_BLOCK_IO 0x0100 +#define V4L2_TUNER_CAP_RDS_CONTROLS 0x0200 +#define V4L2_TUNER_CAP_FREQ_BANDS 0x0400 +#define V4L2_TUNER_CAP_HWSEEK_PROG_LIM 0x0800 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 +#define V4L2_TUNER_SUB_RDS 0x0010 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 +#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004 + +struct v4l2_frequency { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 frequency; + __u32 reserved[8]; +}; + +#define V4L2_BAND_MODULATION_VSB (1 << 1) +#define V4L2_BAND_MODULATION_FM (1 << 2) +#define V4L2_BAND_MODULATION_AM (1 << 3) + +struct v4l2_frequency_band { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 index; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 modulation; + __u32 reserved[9]; +}; + +struct v4l2_hw_freq_seek { + __u32 tuner; + __u32 type; /* enum v4l2_tuner_type */ + __u32 seek_upward; + __u32 wrap_around; + __u32 spacing; + __u32 rangelow; + __u32 rangehigh; + __u32 reserved[5]; +}; + +/* + * R D S + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_rds_data { + __u8 lsb; + __u8 msb; + __u8 block; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define V4L2_RDS_BLOCK_MSK 0x7 +#define V4L2_RDS_BLOCK_A 0 +#define V4L2_RDS_BLOCK_B 1 +#define V4L2_RDS_BLOCK_C 2 +#define V4L2_RDS_BLOCK_D 3 +#define V4L2_RDS_BLOCK_C_ALT 4 +#define V4L2_RDS_BLOCK_INVALID 7 + +#define V4L2_RDS_BLOCK_CORRECTED 0x40 +#define V4L2_RDS_BLOCK_ERROR 0x80 + +/* + * A U D I O + */ +struct v4l2_audio { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout { + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * M P E G S E R V I C E S + * + * NOTE: EXPERIMENTAL API + */ +#if 1 +#define V4L2_ENC_IDX_FRAME_I (0) +#define V4L2_ENC_IDX_FRAME_P (1) +#define V4L2_ENC_IDX_FRAME_B (2) +#define V4L2_ENC_IDX_FRAME_MASK (0xf) + +struct v4l2_enc_idx_entry { + __u64 offset; + __u64 pts; + __u32 length; + __u32 flags; + __u32 reserved[2]; +}; + +#define V4L2_ENC_IDX_ENTRIES (64) +struct v4l2_enc_idx { + __u32 entries; + __u32 entries_cap; + __u32 reserved[4]; + struct v4l2_enc_idx_entry entry[V4L2_ENC_IDX_ENTRIES]; +}; + + +#define V4L2_ENC_CMD_START (0) +#define V4L2_ENC_CMD_STOP (1) +#define V4L2_ENC_CMD_PAUSE (2) +#define V4L2_ENC_CMD_RESUME (3) + +/* Flags for V4L2_ENC_CMD_STOP */ +#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 << 0) + +struct v4l2_encoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u32 data[8]; + } raw; + }; +}; + +/* Decoder commands */ +#define V4L2_DEC_CMD_START (0) +#define V4L2_DEC_CMD_STOP (1) +#define V4L2_DEC_CMD_PAUSE (2) +#define V4L2_DEC_CMD_RESUME (3) + +/* Flags for V4L2_DEC_CMD_START */ +#define V4L2_DEC_CMD_START_MUTE_AUDIO (1 << 0) + +/* Flags for V4L2_DEC_CMD_PAUSE */ +#define V4L2_DEC_CMD_PAUSE_TO_BLACK (1 << 0) + +/* Flags for V4L2_DEC_CMD_STOP */ +#define V4L2_DEC_CMD_STOP_TO_BLACK (1 << 0) +#define V4L2_DEC_CMD_STOP_IMMEDIATELY (1 << 1) + +/* Play format requirements (returned by the driver): */ + +/* The decoder has no special format requirements */ +#define V4L2_DEC_START_FMT_NONE (0) +/* The decoder requires full GOPs */ +#define V4L2_DEC_START_FMT_GOP (1) + +/* The structure must be zeroed before use by the application + This ensures it can be extended safely in the future. */ +struct v4l2_decoder_cmd { + __u32 cmd; + __u32 flags; + union { + struct { + __u64 pts; + } stop; + + struct { + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; + __u32 format; + } start; + + struct { + __u32 data[16]; + } raw; + }; +}; +#endif + + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +/* Raw VBI */ +struct v4l2_vbi_format { + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1 << 0) +#define V4L2_VBI_INTERLACED (1 << 1) + +/* Sliced VBI + * + * This implements is a proposal V4L2 API to allow SLICED VBI + * required for some hardware encoders. It should change without + * notice in the definitive implementation. + */ + +struct v4l2_sliced_vbi_format { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 io_size; + __u32 reserved[2]; /* must be zero */ +}; + +/* Teletext World System Teletext + (WST), defined on ITU-R BT.653-2 */ +#define V4L2_SLICED_TELETEXT_B (0x0001) +/* Video Program System, defined on ETS 300 231*/ +#define V4L2_SLICED_VPS (0x0400) +/* Closed Caption, defined on EIA-608 */ +#define V4L2_SLICED_CAPTION_525 (0x1000) +/* Wide Screen System, defined on ITU-R BT1119.1 */ +#define V4L2_SLICED_WSS_625 (0x4000) + +#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525) +#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625) + +struct v4l2_sliced_vbi_cap { + __u16 service_set; + /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field + service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field + (equals frame lines 313-336 for 625 line video + standards, 263-286 for 525 line standards) */ + __u16 service_lines[2][24]; + __u32 type; /* enum v4l2_buf_type */ + __u32 reserved[3]; /* must be 0 */ +}; + +struct v4l2_sliced_vbi_data { + __u32 id; + __u32 field; /* 0: first field, 1: second field */ + __u32 line; /* 1-23 */ + __u32 reserved; /* must be 0 */ + __u8 data[48]; +}; + +/* + * Sliced VBI data inserted into MPEG Streams + */ + +/* + * V4L2_MPEG_STREAM_VBI_FMT_IVTV: + * + * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an + * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI + * data + * + * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header + * definitions are not included here. See the MPEG-2 specifications for details + * on these headers. + */ + +/* Line type IDs */ +#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1) +#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4) +#define V4L2_MPEG_VBI_IVTV_WSS_625 (5) +#define V4L2_MPEG_VBI_IVTV_VPS (7) + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_mpeg_vbi_itv0_line { + __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */ + __u8 data[42]; /* Sliced VBI data for the line */ +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_mpeg_vbi_itv0 { + __le32 linemask[2]; /* Bitmasks of VBI service lines present */ + struct v4l2_mpeg_vbi_itv0_line line[35]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_mpeg_vbi_ITV0 { + struct v4l2_mpeg_vbi_itv0_line line[36]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0" +#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0" + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_mpeg_vbi_fmt_ivtv { + __u8 magic[4]; + union { + struct v4l2_mpeg_vbi_itv0 itv0; + struct v4l2_mpeg_vbi_ITV0 ITV0; + }; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/** + * struct v4l2_plane_pix_format - additional, per-plane format definition + * @sizeimage: maximum size in bytes required for data, for which + * this plane will be used + * @bytesperline: distance in bytes between the leftmost pixels in two + * adjacent lines + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_plane_pix_format { + __u32 sizeimage; + __u16 bytesperline; + __u16 reserved[7]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/** + * struct v4l2_pix_format_mplane - multiplanar format definition + * @width: image width in pixels + * @height: image height in pixels + * @pixelformat: little endian four character code (fourcc) + * @field: enum v4l2_field; field order (for interlaced video) + * @colorspace: enum v4l2_colorspace; supplemental to pixelformat + * @plane_fmt: per-plane information + * @num_planes: number of planes for this format + */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_pix_format_mplane { + __u32 width; + __u32 height; + __u32 pixelformat; + __u32 field; + __u32 colorspace; + + struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES]; + __u8 num_planes; + __u8 reserved[11]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/** + * struct v4l2_format - stream data format + * @type: enum v4l2_buf_type; type of the data stream + * @pix: definition of an image format + * @pix_mp: definition of a multiplanar image format + * @win: definition of an overlaid image + * @vbi: raw VBI capture or output parameters + * @sliced: sliced VBI capture or output parameters + * @raw_data: placeholder for future extensions and custom formats + */ +struct v4l2_format { + __u32 type; + union { + struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ + struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ + struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ + struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ + struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm { + __u32 type; /* enum v4l2_buf_type */ + union { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + +/* + * E V E N T S + */ + +#define V4L2_EVENT_ALL 0 +#define V4L2_EVENT_VSYNC 1 +#define V4L2_EVENT_EOS 2 +#define V4L2_EVENT_CTRL 3 +#define V4L2_EVENT_FRAME_SYNC 4 +#define V4L2_EVENT_PRIVATE_START 0x08000000 + +/* Payload for V4L2_EVENT_VSYNC */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_event_vsync { + /* Can be V4L2_FIELD_ANY, _NONE, _TOP or _BOTTOM */ + __u8 field; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/* Payload for V4L2_EVENT_CTRL */ +#define V4L2_EVENT_CTRL_CH_VALUE (1 << 0) +#define V4L2_EVENT_CTRL_CH_FLAGS (1 << 1) +#define V4L2_EVENT_CTRL_CH_RANGE (1 << 2) + +struct v4l2_event_ctrl { + __u32 changes; + __u32 type; + union { + __s32 value; + __s64 value64; + }; + __u32 flags; + __s32 minimum; + __s32 maximum; + __s32 step; + __s32 default_value; +}; + +struct v4l2_event_frame_sync { + __u32 frame_sequence; +}; + +struct v4l2_event { + __u32 type; + union { + struct v4l2_event_vsync vsync; + struct v4l2_event_ctrl ctrl; + struct v4l2_event_frame_sync frame_sync; + __u8 data[64]; + } u; + __u32 pending; + __u32 sequence; + //struct timespec timestamp; + __u32 timestamp; + __u32 id; + __u32 reserved[8]; +}; + +#define V4L2_EVENT_SUB_FL_SEND_INITIAL (1 << 0) +#define V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK (1 << 1) + +struct v4l2_event_subscription { + __u32 type; + __u32 id; + __u32 flags; + __u32 reserved[5]; +}; + +/* + * A D V A N C E D D E B U G G I N G + * + * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS! + * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY! + */ + +/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */ + +#define V4L2_CHIP_MATCH_BRIDGE 0 /* Match against chip ID on the bridge (0 for the bridge) */ +#define V4L2_CHIP_MATCH_SUBDEV 4 /* Match against subdev index */ + +/* The following four defines are no longer in use */ +#define V4L2_CHIP_MATCH_HOST V4L2_CHIP_MATCH_BRIDGE +#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */ +#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against ancillary AC97 chip */ + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_dbg_match { + __u32 type; /* Match type */ + union { /* Match this chip, meaning determined by type */ + __u32 addr; + char name[32]; + }; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_dbg_register { + struct v4l2_dbg_match match; + __u32 size; /* register size in bytes */ + __u64 reg; + __u64 val; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +#define V4L2_CHIP_FL_READABLE (1 << 0) +#define V4L2_CHIP_FL_WRITABLE (1 << 1) + +/* VIDIOC_DBG_G_CHIP_INFO */ +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_begin.h" +#endif +RTW_PACK_STRUCT_BEGIN +struct v4l2_dbg_chip_info { + struct v4l2_dbg_match match; + char name[32]; + __u32 flags; + __u32 reserved[32]; +} //__attribute__ ((packed)); +RTW_PACK_STRUCT_STRUCT; +RTW_PACK_STRUCT_END +#ifdef RTW_PACK_STRUCT_USE_INCLUDES +# include "pack_end.h" +#endif + +/** + * struct v4l2_create_buffers - VIDIOC_CREATE_BUFS argument + * @index: on return, index of the first created buffer + * @count: entry: number of requested buffers, + * return: number of created buffers + * @memory: enum v4l2_memory; buffer memory type + * @format: frame format, for which buffers are requested + * @reserved: future extensions + */ +struct v4l2_create_buffers { + __u32 index; + __u32 count; + __u32 memory; + struct v4l2_format format; + __u32 reserved[8]; +}; + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO('V', 1) +#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format) +#define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW('V', 14, int) +#define VIDIOC_QBUF _IOWR('V', 15, struct v4l2_buffer) +#define VIDIOC_EXPBUF _IOWR('V', 16, struct v4l2_exportbuffer) +#define VIDIOC_DQBUF _IOWR('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW('V', 18, int) +#define VIDIOC_STREAMOFF _IOW('V', 19, int) +#define VIDIOC_G_PARM _IOWR('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR('V', 38, int) +#define VIDIOC_S_INPUT _IOWR('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOWR('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */ +#define VIDIOC_S_PRIORITY _IOW('V', 68, __u32) /* enum v4l2_priority */ +#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct v4l2_sliced_vbi_cap) +#define VIDIOC_LOG_STATUS _IO('V', 70) +#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct v4l2_ext_controls) +#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct v4l2_ext_controls) +#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct v4l2_ext_controls) +#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct v4l2_frmsizeenum) +#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct v4l2_frmivalenum) +#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct v4l2_enc_idx) +#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct v4l2_encoder_cmd) +#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct v4l2_encoder_cmd) + +/* Experimental, meant for debugging, testing and internal use. + Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + You must be root to use these ioctls. Never use these in applications! */ +#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) +#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) + +#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) + +#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) +#define VIDIOC_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) +#define VIDIOC_DQEVENT _IOR('V', 89, struct v4l2_event) +#define VIDIOC_SUBSCRIBE_EVENT _IOW('V', 90, struct v4l2_event_subscription) +#define VIDIOC_UNSUBSCRIBE_EVENT _IOW('V', 91, struct v4l2_event_subscription) + +/* Experimental, the below two ioctls may change over the next couple of kernel + versions */ +#define VIDIOC_CREATE_BUFS _IOWR('V', 92, struct v4l2_create_buffers) +#define VIDIOC_PREPARE_BUF _IOWR('V', 93, struct v4l2_buffer) + +/* Experimental selection API */ +#define VIDIOC_G_SELECTION _IOWR('V', 94, struct v4l2_selection) +#define VIDIOC_S_SELECTION _IOWR('V', 95, struct v4l2_selection) + +/* Experimental, these two ioctls may change over the next couple of kernel + versions. */ +#define VIDIOC_DECODER_CMD _IOWR('V', 96, struct v4l2_decoder_cmd) +#define VIDIOC_TRY_DECODER_CMD _IOWR('V', 97, struct v4l2_decoder_cmd) + +/* Experimental, these three ioctls may change over the next couple of kernel + versions. */ +#define VIDIOC_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) +#define VIDIOC_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) +#define VIDIOC_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) + +/* Experimental, this ioctl may change over the next couple of kernel + versions. */ +#define VIDIOC_ENUM_FREQ_BANDS _IOWR('V', 101, struct v4l2_frequency_band) + +/* Experimental, meant for debugging, testing and internal use. + Never use these in applications! */ +#define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info) + +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + + +/*---------------------------------------------------imported from uapi_uvcvideo.h-------------------------------------*/ +/* + * Dynamic controls + */ + +/* Data types for UVC control data */ +#define UVC_CTRL_DATA_TYPE_RAW 0 +#define UVC_CTRL_DATA_TYPE_SIGNED 1 +#define UVC_CTRL_DATA_TYPE_UNSIGNED 2 +#define UVC_CTRL_DATA_TYPE_BOOLEAN 3 +#define UVC_CTRL_DATA_TYPE_ENUM 4 +#define UVC_CTRL_DATA_TYPE_BITMASK 5 + +/* Control flags */ +#define UVC_CTRL_FLAG_SET_CUR (1 << 0) +#define UVC_CTRL_FLAG_GET_CUR (1 << 1) +#define UVC_CTRL_FLAG_GET_MIN (1 << 2) +#define UVC_CTRL_FLAG_GET_MAX (1 << 3) +#define UVC_CTRL_FLAG_GET_RES (1 << 4) +#define UVC_CTRL_FLAG_GET_DEF (1 << 5) +/* Control should be saved at suspend and restored at resume. */ +#define UVC_CTRL_FLAG_RESTORE (1 << 6) +/* Control can be updated by the camera. */ +#define UVC_CTRL_FLAG_AUTO_UPDATE (1 << 7) + +#define UVC_CTRL_FLAG_GET_RANGE \ + (UVC_CTRL_FLAG_GET_CUR | UVC_CTRL_FLAG_GET_MIN | \ + UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \ + UVC_CTRL_FLAG_GET_DEF) + +struct uvc_xu_control_info { + __u8 entity[16]; + __u8 index; + __u8 selector; + __u16 size; + __u32 flags; +}; + +struct uvc_xu_control_mapping_old { + __u32 id; + __u8 name[32]; + __u8 entity[16]; + __u8 selector; + + __u8 size; + __u8 offset; + __u32 v4l2_type; + __u32 data_type; +}; + +struct uvc_xu_control { + __u8 unit; + __u8 selector; + __u16 size; + __u8 *data; +}; + +#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info) +#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old) +#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control) +#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control) + +struct uvc_menu_info { + __u32 value; + __u8 name[32]; +}; + +struct uvc_xu_control_mapping { + __u32 id; + __u8 name[32]; + __u8 entity[16]; + __u8 selector; + + __u8 size; + __u8 offset; + __u32 v4l2_type; + __u32 data_type; + + struct uvc_menu_info *menu_info; + __u32 menu_count; + + __u32 reserved[4]; +}; + +struct uvc_xu_control_query { + __u8 unit; + __u8 selector; + __u8 query; + __u16 size; + __u8 *data; +}; + +#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) +#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) +/*--------------------------------------------end of uapi_uvcvideo.h-----------------------------------------------------*/ + +#endif /* _UAPI__LINUX_VIDEODEV2_H */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-async.h b/USDK/component/common/video/v4l2/inc/v4l2-async.h new file mode 100644 index 0000000..d4acd1f --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-async.h @@ -0,0 +1,99 @@ +/* + * V4L2 asynchronous subdevice registration API + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef V4L2_ASYNC_H +#define V4L2_ASYNC_H +#if 0 +#include +#include +#endif +#include "v4l2-osdep.h" + + +//struct device; +//struct device_node; +struct v4l2_device; +struct v4l2_subdev; +struct v4l2_async_notifier; + +/* A random max subdevice number, used to allocate an array on stack */ +#define V4L2_MAX_SUBDEVS 128U + +enum v4l2_async_match_type { + V4L2_ASYNC_MATCH_CUSTOM, + V4L2_ASYNC_MATCH_DEVNAME, + V4L2_ASYNC_MATCH_I2C, + V4L2_ASYNC_MATCH_OF, +}; + +/** + * struct v4l2_async_subdev - sub-device descriptor, as known to a bridge + * @bus_type: subdevice bus type to select the appropriate matching method + * @match: union of per-bus type matching data sets + * @list: used to link struct v4l2_async_subdev objects, waiting to be + * probed, to a notifier->waiting list + */ +struct v4l2_async_subdev { + enum v4l2_async_match_type match_type; + union { + struct { + const struct device_node *node; + } of; + struct { + const char *name; + } device_name; + struct { + int adapter_id; + unsigned short address; + } i2c; + struct { + bool (*match)(const char *dev_init_name, struct v4l2_async_subdev *); + void *priv; + } custom; + } match; + + /* v4l2-async core private: not to be used by drivers */ + struct list_head list; +}; + +/** + * v4l2_async_notifier - v4l2_device notifier data + * @num_subdevs:number of subdevices + * @subdevs: array of pointers to subdevice descriptors + * @v4l2_dev: pointer to struct v4l2_device + * @waiting: list of struct v4l2_async_subdev, waiting for their drivers + * @done: list of struct v4l2_subdev, already probed + * @list: member in a global list of notifiers + * @bound: a subdevice driver has successfully probed one of subdevices + * @complete: all subdevices have been probed successfully + * @unbind: a subdevice is leaving + */ +struct v4l2_async_notifier { + unsigned int num_subdevs; + struct v4l2_async_subdev **subdevs; + struct v4l2_device *v4l2_dev; + struct list_head waiting; + struct list_head done; + struct list_head list; + int (*bound)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); + int (*complete)(struct v4l2_async_notifier *notifier); + void (*unbind)(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd); +}; + +int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev, + struct v4l2_async_notifier *notifier); +void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier); +int v4l2_async_register_subdev(struct v4l2_subdev *sd); +void v4l2_async_unregister_subdev(struct v4l2_subdev *sd); +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-clk.h b/USDK/component/common/video/v4l2/inc/v4l2-clk.h new file mode 100644 index 0000000..0b01e30 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-clk.h @@ -0,0 +1,59 @@ +/* + * V4L2 clock service + * + * Copyright (C) 2012-2013, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ATTENTION: This is a temporary API and it shall be replaced by the generic + * clock API, when the latter becomes widely available. + */ + +#ifndef MEDIA_V4L2_CLK_H +#define MEDIA_V4L2_CLK_H + +#if 0 +#include +#include +#include +#endif +#include "v4l2-osdep.h" + + +//struct module; +//struct device; + +struct v4l2_clk { + struct LIST_HEADER list; + const struct v4l2_clk_ops *ops; + const char *dev_id; + const char *id; + int enable; + //struct mutex lock; /* Protect the enable count */ + _Mutex lock; + atomic_t use_count; + void *priv; +}; + +struct v4l2_clk_ops { + //struct module *owner; + int (*enable)(struct v4l2_clk *clk); + void (*disable)(struct v4l2_clk *clk); + unsigned long (*get_rate)(struct v4l2_clk *clk); + int (*set_rate)(struct v4l2_clk *clk, unsigned long); +}; + +struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, + const char *dev_name, + const char *name, void *priv); +void v4l2_clk_unregister(struct v4l2_clk *clk); +struct v4l2_clk *v4l2_clk_get(const char *id); +void v4l2_clk_put(struct v4l2_clk *clk); +int v4l2_clk_enable(struct v4l2_clk *clk); +void v4l2_clk_disable(struct v4l2_clk *clk); +unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk); +int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate); + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-common.h b/USDK/component/common/video/v4l2/inc/v4l2-common.h new file mode 100644 index 0000000..f946f2f --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-common.h @@ -0,0 +1,210 @@ +/* + v4l2 common internal API header + + This header contains internal shared ioctl definitions for use by the + internal low-level v4l2 drivers. + Each ioctl begins with VIDIOC_INT_ to clearly mark that it is an internal + define, + + Copyright (C) 2005 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef V4L2_COMMON_H_ +#define V4L2_COMMON_H_ + +#include "v4l2-dev.h" + + +/* Common printk constucts for v4l-i2c drivers. These macros create a unique + prefix consisting of the driver name, the adapter number and the i2c + address. */ +#if 0 +#define v4l_printk(level, name, adapter, addr, fmt, arg...) \ + printk(level "%s %d-%04x: " fmt, name, i2c_adapter_id(adapter), addr , ## arg) + +#define v4l_client_printk(level, client, fmt, arg...) \ + v4l_printk(level, (client)->driver->driver.name, (client)->adapter, \ + (client)->addr, fmt , ## arg) + +#define v4l_err(client, fmt, arg...) \ + v4l_client_printk(KERN_ERR, client, fmt , ## arg) + +#define v4l_warn(client, fmt, arg...) \ + v4l_client_printk(KERN_WARNING, client, fmt , ## arg) + +#define v4l_info(client, fmt, arg...) \ + v4l_client_printk(KERN_INFO, client, fmt , ## arg) + +/* These three macros assume that the debug level is set with a module + parameter called 'debug'. */ +#define v4l_dbg(level, debug, client, fmt, arg...) \ + do { \ + if (debug >= (level)) \ + v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ + } while (0) +#endif +/* ------------------------------------------------------------------------- */ +#if 0 +/* These printk constructs can be used with v4l2_device and v4l2_subdev */ +#define v4l2_printk(level, dev, fmt, arg...) \ + printk(level "%s: " fmt, (dev)->name , ## arg) + +#define v4l2_err(dev, fmt, arg...) \ + v4l2_printk(KERN_ERR, dev, fmt , ## arg) + +#define v4l2_warn(dev, fmt, arg...) \ + v4l2_printk(KERN_WARNING, dev, fmt , ## arg) + +#define v4l2_info(dev, fmt, arg...) \ + v4l2_printk(KERN_INFO, dev, fmt , ## arg) + +/* These three macros assume that the debug level is set with a module + parameter called 'debug'. */ +#define v4l2_dbg(level, debug, dev, fmt, arg...) \ + do { \ + if (debug >= (level)) \ + v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \ + } while (0) +#endif +/* ------------------------------------------------------------------------- */ +//edit by Ian -- remove control helper functions +#if 0 +/* Control helper functions */ + +int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, + const char * const *menu_items); +const char *v4l2_ctrl_get_name(u32 id); +const char * const *v4l2_ctrl_get_menu(u32 id); +const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len); +int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def); +int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, + struct v4l2_queryctrl *qctrl, const char * const *menu_items); +#define V4L2_CTRL_MENU_IDS_END (0xffffffff) +int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids); +#endif +/* Note: ctrl_classes points to an array of u32 pointers. Each u32 array is a + 0-terminated array of control IDs. Each array must be sorted low to high + and belong to the same control class. The array of u32 pointers must also + be sorted, from low class IDs to high class IDs. */ +//u32 v4l2_ctrl_next(const u32 * const *ctrl_classes, u32 id); + +/* ------------------------------------------------------------------------- */ + +/* I2C Helper functions */ +#if 0 +struct i2c_driver; +struct i2c_adapter; +struct i2c_client; +struct i2c_device_id; +struct v4l2_device; +struct v4l2_subdev; +struct v4l2_subdev_ops; + + +/* Load an i2c module and return an initialized v4l2_subdev struct. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, + struct i2c_adapter *adapter, const char *client_type, + u8 addr, const unsigned short *probe_addrs); + +struct i2c_board_info; + +struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, + struct i2c_adapter *adapter, struct i2c_board_info *info, + const unsigned short *probe_addrs); + +/* Initialize a v4l2_subdev with data from an i2c_client struct */ +void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, + const struct v4l2_subdev_ops *ops); +/* Return i2c client address of v4l2_subdev. */ +unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd); + +enum v4l2_i2c_tuner_type { + ADDRS_RADIO, /* Radio tuner addresses */ + ADDRS_DEMOD, /* Demod tuner addresses */ + ADDRS_TV, /* TV tuner addresses */ + /* TV tuner addresses if demod is present, this excludes + addresses used by the demodulator from the list of + candidates. */ + ADDRS_TV_WITH_DEMOD, +}; +/* Return a list of I2C tuner addresses to probe. Use only if the tuner + addresses are unknown. */ +const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type); + +/* ------------------------------------------------------------------------- */ + +/* SPI Helper functions */ +#if defined(CONFIG_SPI) + +#include + +struct spi_device; + +/* Load an spi module and return an initialized v4l2_subdev struct. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, + struct spi_master *master, struct spi_board_info *info); + +/* Initialize a v4l2_subdev with data from an spi_device struct */ +void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi, + const struct v4l2_subdev_ops *ops); +#endif +#endif +/* ------------------------------------------------------------------------- */ +#if 0 +/* Note: these remaining ioctls/structs should be removed as well, but they are + still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and + v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup + is needed in those modules. */ + +/* s_config */ +struct v4l2_priv_tun_config { + int tuner; + void *priv; +}; +#define TUNER_SET_CONFIG _IOW('d', 92, struct v4l2_priv_tun_config) + +#define VIDIOC_INT_RESET _IOW ('d', 102, u32) + +struct v4l2_routing { + u32 input; + u32 output; +}; +#endif +/* ------------------------------------------------------------------------- */ + +/* Miscellaneous helper functions */ +#if 0 +void v4l_bound_align_image(u32*w, unsigned int wmin, + unsigned int wmax, unsigned int walign, + u32 *h, unsigned int hmin, + unsigned int hmax, unsigned int halign, + unsigned int salign); + +struct v4l2_discrete_probe { + const struct v4l2_frmsize_discrete *sizes; + int num_sizes; +}; + +const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( + const struct v4l2_discrete_probe *probe, + s32 width, s32 height); +#endif +//void v4l2_get_timestamp(struct timeval *tv); + +#endif /* V4L2_COMMON_H_ */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-controls.h b/USDK/component/common/video/v4l2/inc/v4l2-controls.h new file mode 100644 index 0000000..083bb5a --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-controls.h @@ -0,0 +1,885 @@ +/* + * Video for Linux Two controls header file + * + * Copyright (C) 1999-2012 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The contents of this header was split off from videodev2.h. All control + * definitions should be added to this header, which is included by + * videodev2.h. + */ + +#ifndef __LINUX_V4L2_CONTROLS_H +#define __LINUX_V4L2_CONTROLS_H + +/* Control classes */ +#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */ +#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */ +#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */ +#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator controls */ +#define V4L2_CTRL_CLASS_FLASH 0x009c0000 /* Camera flash controls */ +#define V4L2_CTRL_CLASS_JPEG 0x009d0000 /* JPEG-compression controls */ +#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009e0000 /* Image source controls */ +#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009f0000 /* Image processing controls */ +#define V4L2_CTRL_CLASS_DV 0x00a00000 /* Digital Video controls */ +#define V4L2_CTRL_CLASS_FM_RX 0x00a10000 /* FM Receiver controls */ + +/* User-class control IDs */ + +#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */ +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) + +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +enum v4l2_power_line_frequency { + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2, + V4L2_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; +#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) +#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) +#define V4L2_CID_COLORFX (V4L2_CID_BASE+31) +enum v4l2_colorfx { + V4L2_COLORFX_NONE = 0, + V4L2_COLORFX_BW = 1, + V4L2_COLORFX_SEPIA = 2, + V4L2_COLORFX_NEGATIVE = 3, + V4L2_COLORFX_EMBOSS = 4, + V4L2_COLORFX_SKETCH = 5, + V4L2_COLORFX_SKY_BLUE = 6, + V4L2_COLORFX_GRASS_GREEN = 7, + V4L2_COLORFX_SKIN_WHITEN = 8, + V4L2_COLORFX_VIVID = 9, + V4L2_COLORFX_AQUA = 10, + V4L2_COLORFX_ART_FREEZE = 11, + V4L2_COLORFX_SILHOUETTE = 12, + V4L2_COLORFX_SOLARIZATION = 13, + V4L2_COLORFX_ANTIQUE = 14, + V4L2_COLORFX_SET_CBCR = 15, +}; +#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) +#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33) + +#define V4L2_CID_ROTATE (V4L2_CID_BASE+34) +#define V4L2_CID_BG_COLOR (V4L2_CID_BASE+35) + +#define V4L2_CID_CHROMA_GAIN (V4L2_CID_BASE+36) + +#define V4L2_CID_ILLUMINATORS_1 (V4L2_CID_BASE+37) +#define V4L2_CID_ILLUMINATORS_2 (V4L2_CID_BASE+38) + +#define V4L2_CID_MIN_BUFFERS_FOR_CAPTURE (V4L2_CID_BASE+39) +#define V4L2_CID_MIN_BUFFERS_FOR_OUTPUT (V4L2_CID_BASE+40) + +#define V4L2_CID_ALPHA_COMPONENT (V4L2_CID_BASE+41) +#define V4L2_CID_COLORFX_CBCR (V4L2_CID_BASE+42) + +/* last CID + 1 */ +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+43) + +/* USER-class private control IDs */ + +/* The base for the meye driver controls. See linux/meye.h for the list + * of controls. We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_MEYE_BASE (V4L2_CID_USER_BASE + 0x1000) + +/* The base for the bttv driver controls. + * We reserve 32 controls for this driver. */ +#define V4L2_CID_USER_BTTV_BASE (V4L2_CID_USER_BASE + 0x1010) + + +/* The base for the s2255 driver controls. + * We reserve 16 controls for this driver. */ +#define V4L2_CID_USER_S2255_BASE (V4L2_CID_USER_BASE + 0x1030) + +/* The base for the si476x driver controls. See include/media/si476x.h for the list + * of controls. Total of 16 controls is reserved for this driver */ +#define V4L2_CID_USER_SI476X_BASE (V4L2_CID_USER_BASE + 0x1040) + +/* MPEG-class control IDs */ +/* The MPEG controls are applicable to all codec controls + * and the 'MPEG' part of the define is historical */ + +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) + +/* MPEG streams, specific to multiplexed streams */ +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +enum v4l2_mpeg_stream_type { + V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ + V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ +}; +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +enum v4l2_mpeg_stream_vbi_fmt { + V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ + V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ +}; + +/* MPEG audio controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +enum v4l2_mpeg_audio_sampling_freq { + V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +enum v4l2_mpeg_audio_encoding { + V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, +}; +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +enum v4l2_mpeg_audio_l1_bitrate { + V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, + V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2, + V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3, + V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4, + V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5, + V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6, + V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7, + V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8, + V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9, + V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10, + V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11, + V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, + V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +enum v4l2_mpeg_audio_l2_bitrate { + V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, + V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2, + V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3, + V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4, + V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5, + V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6, + V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7, + V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8, + V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9, + V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10, + V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11, + V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, + V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +enum v4l2_mpeg_audio_l3_bitrate { + V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, +}; +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +enum v4l2_mpeg_audio_mode { + V4L2_MPEG_AUDIO_MODE_STEREO = 0, + V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, + V4L2_MPEG_AUDIO_MODE_DUAL = 2, + V4L2_MPEG_AUDIO_MODE_MONO = 3, +}; +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +enum v4l2_mpeg_audio_mode_extension { + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, + V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, +}; +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +enum v4l2_mpeg_audio_emphasis { + V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, + V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, + V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, +}; +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +enum v4l2_mpeg_audio_crc { + V4L2_MPEG_AUDIO_CRC_NONE = 0, + V4L2_MPEG_AUDIO_CRC_CRC16 = 1, +}; +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK (V4L2_CID_MPEG_BASE+112) +enum v4l2_mpeg_audio_dec_playback { + V4L2_MPEG_AUDIO_DEC_PLAYBACK_AUTO = 0, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_STEREO = 1, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_LEFT = 2, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_RIGHT = 3, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_MONO = 4, + V4L2_MPEG_AUDIO_DEC_PLAYBACK_SWAPPED_STEREO = 5, +}; +#define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) + +/* MPEG video controls specific to multiplexed streams */ +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +enum v4l2_mpeg_video_encoding { + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, +}; +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +enum v4l2_mpeg_video_aspect { + V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, + V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, + V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, + V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, +}; +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +enum v4l2_mpeg_video_bitrate_mode { + V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, +}; +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) +#define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) +#define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) +#define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) +#define V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE (V4L2_CID_MPEG_BASE+215) +#define V4L2_CID_MPEG_VIDEO_HEADER_MODE (V4L2_CID_MPEG_BASE+216) +enum v4l2_mpeg_video_header_mode { + V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE = 0, + V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME = 1, + +}; +#define V4L2_CID_MPEG_VIDEO_MAX_REF_PIC (V4L2_CID_MPEG_BASE+217) +#define V4L2_CID_MPEG_VIDEO_MB_RC_ENABLE (V4L2_CID_MPEG_BASE+218) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES (V4L2_CID_MPEG_BASE+219) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB (V4L2_CID_MPEG_BASE+220) +#define V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE (V4L2_CID_MPEG_BASE+221) +enum v4l2_mpeg_video_multi_slice_mode { + V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE = 0, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB = 1, + V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VBV_SIZE (V4L2_CID_MPEG_BASE+222) +#define V4L2_CID_MPEG_VIDEO_DEC_PTS (V4L2_CID_MPEG_BASE+223) +#define V4L2_CID_MPEG_VIDEO_DEC_FRAME (V4L2_CID_MPEG_BASE+224) +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_BASE+225) +#define V4L2_CID_MPEG_VIDEO_REPEAT_SEQ_HEADER (V4L2_CID_MPEG_BASE+226) + +#define V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP (V4L2_CID_MPEG_BASE+300) +#define V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP (V4L2_CID_MPEG_BASE+301) +#define V4L2_CID_MPEG_VIDEO_H263_B_FRAME_QP (V4L2_CID_MPEG_BASE+302) +#define V4L2_CID_MPEG_VIDEO_H263_MIN_QP (V4L2_CID_MPEG_BASE+303) +#define V4L2_CID_MPEG_VIDEO_H263_MAX_QP (V4L2_CID_MPEG_BASE+304) +#define V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP (V4L2_CID_MPEG_BASE+350) +#define V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP (V4L2_CID_MPEG_BASE+351) +#define V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP (V4L2_CID_MPEG_BASE+352) +#define V4L2_CID_MPEG_VIDEO_H264_MIN_QP (V4L2_CID_MPEG_BASE+353) +#define V4L2_CID_MPEG_VIDEO_H264_MAX_QP (V4L2_CID_MPEG_BASE+354) +#define V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM (V4L2_CID_MPEG_BASE+355) +#define V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE (V4L2_CID_MPEG_BASE+356) +#define V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE (V4L2_CID_MPEG_BASE+357) +enum v4l2_mpeg_video_h264_entropy_mode { + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC = 0, + V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_I_PERIOD (V4L2_CID_MPEG_BASE+358) +#define V4L2_CID_MPEG_VIDEO_H264_LEVEL (V4L2_CID_MPEG_BASE+359) +enum v4l2_mpeg_video_h264_level { + V4L2_MPEG_VIDEO_H264_LEVEL_1_0 = 0, + V4L2_MPEG_VIDEO_H264_LEVEL_1B = 1, + V4L2_MPEG_VIDEO_H264_LEVEL_1_1 = 2, + V4L2_MPEG_VIDEO_H264_LEVEL_1_2 = 3, + V4L2_MPEG_VIDEO_H264_LEVEL_1_3 = 4, + V4L2_MPEG_VIDEO_H264_LEVEL_2_0 = 5, + V4L2_MPEG_VIDEO_H264_LEVEL_2_1 = 6, + V4L2_MPEG_VIDEO_H264_LEVEL_2_2 = 7, + V4L2_MPEG_VIDEO_H264_LEVEL_3_0 = 8, + V4L2_MPEG_VIDEO_H264_LEVEL_3_1 = 9, + V4L2_MPEG_VIDEO_H264_LEVEL_3_2 = 10, + V4L2_MPEG_VIDEO_H264_LEVEL_4_0 = 11, + V4L2_MPEG_VIDEO_H264_LEVEL_4_1 = 12, + V4L2_MPEG_VIDEO_H264_LEVEL_4_2 = 13, + V4L2_MPEG_VIDEO_H264_LEVEL_5_0 = 14, + V4L2_MPEG_VIDEO_H264_LEVEL_5_1 = 15, +}; +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA (V4L2_CID_MPEG_BASE+360) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA (V4L2_CID_MPEG_BASE+361) +#define V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE (V4L2_CID_MPEG_BASE+362) +enum v4l2_mpeg_video_h264_loop_filter_mode { + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED = 0, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED = 1, + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY = 2, +}; +#define V4L2_CID_MPEG_VIDEO_H264_PROFILE (V4L2_CID_MPEG_BASE+363) +enum v4l2_mpeg_video_h264_profile { + V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE = 0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE = 1, + V4L2_MPEG_VIDEO_H264_PROFILE_MAIN = 2, + V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED = 3, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH = 4, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10 = 5, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422 = 6, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE = 7, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA = 8, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA = 9, + V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA = 10, + V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA = 11, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE = 12, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH = 13, + V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA = 14, + V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH = 15, + V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH = 16, +}; +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT (V4L2_CID_MPEG_BASE+364) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH (V4L2_CID_MPEG_BASE+365) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE (V4L2_CID_MPEG_BASE+366) +#define V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC (V4L2_CID_MPEG_BASE+367) +enum v4l2_mpeg_video_h264_vui_sar_idc { + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED = 0, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1 = 1, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_12x11 = 2, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_10x11 = 3, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_16x11 = 4, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_40x33 = 5, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_24x11 = 6, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_20x11 = 7, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_32x11 = 8, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_80x33 = 9, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_18x11 = 10, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_15x11 = 11, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_64x33 = 12, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_160x99 = 13, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_4x3 = 14, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_3x2 = 15, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_2x1 = 16, + V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED = 17, +}; +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING (V4L2_CID_MPEG_BASE+368) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 (V4L2_CID_MPEG_BASE+369) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE (V4L2_CID_MPEG_BASE+370) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_CHECKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_BASE+371) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_BASE+372) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP (V4L2_CID_MPEG_BASE+373) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION (V4L2_CID_MPEG_BASE+374) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE (V4L2_CID_MPEG_BASE+375) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH (V4L2_CID_MPEG_BASE+376) +#define V4L2_CID_MPEG_VIDEO_H264_ASO (V4L2_CID_MPEG_BASE+377) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER (V4L2_CID_MPEG_BASE+378) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING (V4L2_CID_MPEG_BASE+379) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE (V4L2_CID_MPEG_BASE+380) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER (V4L2_CID_MPEG_BASE+381) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP (V4L2_CID_MPEG_BASE+382) +#define V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP (V4L2_CID_MPEG_BASE+400) +#define V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP (V4L2_CID_MPEG_BASE+401) +#define V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP (V4L2_CID_MPEG_BASE+402) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MIN_QP (V4L2_CID_MPEG_BASE+403) +#define V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP (V4L2_CID_MPEG_BASE+404) +#define V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL (V4L2_CID_MPEG_BASE+405) +enum v4l2_mpeg_video_mpeg4_level { + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0 = 0, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B = 1, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_1 = 2, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_2 = 3, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3 = 4, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_3B = 5, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_4 = 6, + V4L2_MPEG_VIDEO_MPEG4_LEVEL_5 = 7, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE (V4L2_CID_MPEG_BASE+406) +enum v4l2_mpeg_video_mpeg4_profile { + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE = 0, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE = 1, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_CORE = 2, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE_SCALABLE = 3, + V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY = 4, +}; +#define V4L2_CID_MPEG_VIDEO_MPEG4_QPEL (V4L2_CID_MPEG_BASE+407) + +/* Control IDs for VP8 streams + * Although VP8 is not part of MPEG we add these controls to the MPEG class + * as that class is already handling other video compression standards + */ +#define V4L2_CID_MPEG_VIDEO_VPX_NUM_PARTITIONS (V4L2_CID_MPEG_BASE+500) +enum v4l2_vp8_num_partitions { + V4L2_CID_MPEG_VIDEO_VPX_1_PARTITION = 0, + V4L2_CID_MPEG_VIDEO_VPX_2_PARTITIONS = 1, + V4L2_CID_MPEG_VIDEO_VPX_4_PARTITIONS = 2, + V4L2_CID_MPEG_VIDEO_VPX_8_PARTITIONS = 3, +}; +#define V4L2_CID_MPEG_VIDEO_VPX_IMD_DISABLE_4X4 (V4L2_CID_MPEG_BASE+501) +#define V4L2_CID_MPEG_VIDEO_VPX_NUM_REF_FRAMES (V4L2_CID_MPEG_BASE+502) +enum v4l2_vp8_num_ref_frames { + V4L2_CID_MPEG_VIDEO_VPX_1_REF_FRAME = 0, + V4L2_CID_MPEG_VIDEO_VPX_2_REF_FRAME = 1, + V4L2_CID_MPEG_VIDEO_VPX_3_REF_FRAME = 2, +}; +#define V4L2_CID_MPEG_VIDEO_VPX_FILTER_LEVEL (V4L2_CID_MPEG_BASE+503) +#define V4L2_CID_MPEG_VIDEO_VPX_FILTER_SHARPNESS (V4L2_CID_MPEG_BASE+504) +#define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_REF_PERIOD (V4L2_CID_MPEG_BASE+505) +#define V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_SEL (V4L2_CID_MPEG_BASE+506) +enum v4l2_vp8_golden_frame_sel { + V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_PREV = 0, + V4L2_CID_MPEG_VIDEO_VPX_GOLDEN_FRAME_USE_REF_PERIOD = 1, +}; + +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +enum v4l2_mpeg_cx2341x_video_median_filter_type { + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, +}; +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) + +/* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ +#define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) + +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY (V4L2_CID_MPEG_MFC51_BASE+0) +#define V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE (V4L2_CID_MPEG_MFC51_BASE+1) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE (V4L2_CID_MPEG_MFC51_BASE+2) +enum v4l2_mpeg_mfc51_video_frame_skip_mode { + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE (V4L2_CID_MPEG_MFC51_BASE+3) +enum v4l2_mpeg_mfc51_video_force_frame_type { + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_DISABLED = 0, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FORCE_FRAME_TYPE_NOT_CODED = 2, +}; +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING (V4L2_CID_MPEG_MFC51_BASE+4) +#define V4L2_CID_MPEG_MFC51_VIDEO_PADDING_YUV (V4L2_CID_MPEG_MFC51_BASE+5) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_FIXED_TARGET_BIT (V4L2_CID_MPEG_MFC51_BASE+6) +#define V4L2_CID_MPEG_MFC51_VIDEO_RC_REACTION_COEFF (V4L2_CID_MPEG_MFC51_BASE+7) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_ACTIVITY (V4L2_CID_MPEG_MFC51_BASE+50) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_DARK (V4L2_CID_MPEG_MFC51_BASE+51) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_SMOOTH (V4L2_CID_MPEG_MFC51_BASE+52) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_ADAPTIVE_RC_STATIC (V4L2_CID_MPEG_MFC51_BASE+53) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_NUM_REF_PIC_FOR_P (V4L2_CID_MPEG_MFC51_BASE+54) + + +/* Camera class control IDs */ + +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) + +#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) +enum v4l2_exposure_auto_type { + V4L2_EXPOSURE_AUTO = 0, + V4L2_EXPOSURE_MANUAL = 1, + V4L2_EXPOSURE_SHUTTER_PRIORITY = 2, + V4L2_EXPOSURE_APERTURE_PRIORITY = 3 +}; +#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2) +#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3) + +#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4) +#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5) +#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6) +#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7) + +#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8) +#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9) + +#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10) +#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) +#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) + +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + +#define V4L2_CID_IRIS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+17) +#define V4L2_CID_IRIS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+18) + +#define V4L2_CID_AUTO_EXPOSURE_BIAS (V4L2_CID_CAMERA_CLASS_BASE+19) + +#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE (V4L2_CID_CAMERA_CLASS_BASE+20) +enum v4l2_auto_n_preset_white_balance { + V4L2_WHITE_BALANCE_MANUAL = 0, + V4L2_WHITE_BALANCE_AUTO = 1, + V4L2_WHITE_BALANCE_INCANDESCENT = 2, + V4L2_WHITE_BALANCE_FLUORESCENT = 3, + V4L2_WHITE_BALANCE_FLUORESCENT_H = 4, + V4L2_WHITE_BALANCE_HORIZON = 5, + V4L2_WHITE_BALANCE_DAYLIGHT = 6, + V4L2_WHITE_BALANCE_FLASH = 7, + V4L2_WHITE_BALANCE_CLOUDY = 8, + V4L2_WHITE_BALANCE_SHADE = 9, +}; + +#define V4L2_CID_WIDE_DYNAMIC_RANGE (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_IMAGE_STABILIZATION (V4L2_CID_CAMERA_CLASS_BASE+22) + +#define V4L2_CID_ISO_SENSITIVITY (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_ISO_SENSITIVITY_AUTO (V4L2_CID_CAMERA_CLASS_BASE+24) +enum v4l2_iso_sensitivity_auto_type { + V4L2_ISO_SENSITIVITY_MANUAL = 0, + V4L2_ISO_SENSITIVITY_AUTO = 1, +}; + +#define V4L2_CID_EXPOSURE_METERING (V4L2_CID_CAMERA_CLASS_BASE+25) +enum v4l2_exposure_metering { + V4L2_EXPOSURE_METERING_AVERAGE = 0, + V4L2_EXPOSURE_METERING_CENTER_WEIGHTED = 1, + V4L2_EXPOSURE_METERING_SPOT = 2, + V4L2_EXPOSURE_METERING_MATRIX = 3, +}; + +#define V4L2_CID_SCENE_MODE (V4L2_CID_CAMERA_CLASS_BASE+26) +enum v4l2_scene_mode { + V4L2_SCENE_MODE_NONE = 0, + V4L2_SCENE_MODE_BACKLIGHT = 1, + V4L2_SCENE_MODE_BEACH_SNOW = 2, + V4L2_SCENE_MODE_CANDLE_LIGHT = 3, + V4L2_SCENE_MODE_DAWN_DUSK = 4, + V4L2_SCENE_MODE_FALL_COLORS = 5, + V4L2_SCENE_MODE_FIREWORKS = 6, + V4L2_SCENE_MODE_LANDSCAPE = 7, + V4L2_SCENE_MODE_NIGHT = 8, + V4L2_SCENE_MODE_PARTY_INDOOR = 9, + V4L2_SCENE_MODE_PORTRAIT = 10, + V4L2_SCENE_MODE_SPORTS = 11, + V4L2_SCENE_MODE_SUNSET = 12, + V4L2_SCENE_MODE_TEXT = 13, +}; + +#define V4L2_CID_3A_LOCK (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_LOCK_EXPOSURE (1 << 0) +#define V4L2_LOCK_WHITE_BALANCE (1 << 1) +#define V4L2_LOCK_FOCUS (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_START (V4L2_CID_CAMERA_CLASS_BASE+28) +#define V4L2_CID_AUTO_FOCUS_STOP (V4L2_CID_CAMERA_CLASS_BASE+29) +#define V4L2_CID_AUTO_FOCUS_STATUS (V4L2_CID_CAMERA_CLASS_BASE+30) +#define V4L2_AUTO_FOCUS_STATUS_IDLE (0 << 0) +#define V4L2_AUTO_FOCUS_STATUS_BUSY (1 << 0) +#define V4L2_AUTO_FOCUS_STATUS_REACHED (1 << 1) +#define V4L2_AUTO_FOCUS_STATUS_FAILED (1 << 2) + +#define V4L2_CID_AUTO_FOCUS_RANGE (V4L2_CID_CAMERA_CLASS_BASE+31) +enum v4l2_auto_focus_range { + V4L2_AUTO_FOCUS_RANGE_AUTO = 0, + V4L2_AUTO_FOCUS_RANGE_NORMAL = 1, + V4L2_AUTO_FOCUS_RANGE_MACRO = 2, + V4L2_AUTO_FOCUS_RANGE_INFINITY = 3, +}; + + +/* FM Modulator class control IDs */ + +#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900) +#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1) + +#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1) +#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2) +#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) +#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) +#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) + +#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64) +#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65) +#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66) + +#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80) +#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81) +#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82) +#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83) +#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84) + +#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96) +#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97) +#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98) + +#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112) +enum v4l2_preemphasis { + V4L2_PREEMPHASIS_DISABLED = 0, + V4L2_PREEMPHASIS_50_uS = 1, + V4L2_PREEMPHASIS_75_uS = 2, +}; +#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113) +#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114) + + +/* Flash and privacy (indicator) light controls */ + +#define V4L2_CID_FLASH_CLASS_BASE (V4L2_CTRL_CLASS_FLASH | 0x900) +#define V4L2_CID_FLASH_CLASS (V4L2_CTRL_CLASS_FLASH | 1) + +#define V4L2_CID_FLASH_LED_MODE (V4L2_CID_FLASH_CLASS_BASE + 1) +enum v4l2_flash_led_mode { + V4L2_FLASH_LED_MODE_NONE, + V4L2_FLASH_LED_MODE_FLASH, + V4L2_FLASH_LED_MODE_TORCH, +}; + +#define V4L2_CID_FLASH_STROBE_SOURCE (V4L2_CID_FLASH_CLASS_BASE + 2) +enum v4l2_flash_strobe_source { + V4L2_FLASH_STROBE_SOURCE_SOFTWARE, + V4L2_FLASH_STROBE_SOURCE_EXTERNAL, +}; + +#define V4L2_CID_FLASH_STROBE (V4L2_CID_FLASH_CLASS_BASE + 3) +#define V4L2_CID_FLASH_STROBE_STOP (V4L2_CID_FLASH_CLASS_BASE + 4) +#define V4L2_CID_FLASH_STROBE_STATUS (V4L2_CID_FLASH_CLASS_BASE + 5) + +#define V4L2_CID_FLASH_TIMEOUT (V4L2_CID_FLASH_CLASS_BASE + 6) +#define V4L2_CID_FLASH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 7) +#define V4L2_CID_FLASH_TORCH_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 8) +#define V4L2_CID_FLASH_INDICATOR_INTENSITY (V4L2_CID_FLASH_CLASS_BASE + 9) + +#define V4L2_CID_FLASH_FAULT (V4L2_CID_FLASH_CLASS_BASE + 10) +#define V4L2_FLASH_FAULT_OVER_VOLTAGE (1 << 0) +#define V4L2_FLASH_FAULT_TIMEOUT (1 << 1) +#define V4L2_FLASH_FAULT_OVER_TEMPERATURE (1 << 2) +#define V4L2_FLASH_FAULT_SHORT_CIRCUIT (1 << 3) +#define V4L2_FLASH_FAULT_OVER_CURRENT (1 << 4) +#define V4L2_FLASH_FAULT_INDICATOR (1 << 5) + +#define V4L2_CID_FLASH_CHARGE (V4L2_CID_FLASH_CLASS_BASE + 11) +#define V4L2_CID_FLASH_READY (V4L2_CID_FLASH_CLASS_BASE + 12) + + +/* JPEG-class control IDs */ + +#define V4L2_CID_JPEG_CLASS_BASE (V4L2_CTRL_CLASS_JPEG | 0x900) +#define V4L2_CID_JPEG_CLASS (V4L2_CTRL_CLASS_JPEG | 1) + +#define V4L2_CID_JPEG_CHROMA_SUBSAMPLING (V4L2_CID_JPEG_CLASS_BASE + 1) +enum v4l2_jpeg_chroma_subsampling { + V4L2_JPEG_CHROMA_SUBSAMPLING_444 = 0, + V4L2_JPEG_CHROMA_SUBSAMPLING_422 = 1, + V4L2_JPEG_CHROMA_SUBSAMPLING_420 = 2, + V4L2_JPEG_CHROMA_SUBSAMPLING_411 = 3, + V4L2_JPEG_CHROMA_SUBSAMPLING_410 = 4, + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY = 5, +}; +#define V4L2_CID_JPEG_RESTART_INTERVAL (V4L2_CID_JPEG_CLASS_BASE + 2) +#define V4L2_CID_JPEG_COMPRESSION_QUALITY (V4L2_CID_JPEG_CLASS_BASE + 3) + +#define V4L2_CID_JPEG_ACTIVE_MARKER (V4L2_CID_JPEG_CLASS_BASE + 4) +#define V4L2_JPEG_ACTIVE_MARKER_APP0 (1 << 0) +#define V4L2_JPEG_ACTIVE_MARKER_APP1 (1 << 1) +#define V4L2_JPEG_ACTIVE_MARKER_COM (1 << 16) +#define V4L2_JPEG_ACTIVE_MARKER_DQT (1 << 17) +#define V4L2_JPEG_ACTIVE_MARKER_DHT (1 << 18) + + +/* Image source controls */ +#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS (V4L2_CTRL_CLASS_IMAGE_SOURCE | 1) + +#define V4L2_CID_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1) +#define V4L2_CID_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2) +#define V4L2_CID_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3) + + +/* Image processing controls */ + +#define V4L2_CID_IMAGE_PROC_CLASS_BASE (V4L2_CTRL_CLASS_IMAGE_PROC | 0x900) +#define V4L2_CID_IMAGE_PROC_CLASS (V4L2_CTRL_CLASS_IMAGE_PROC | 1) + +#define V4L2_CID_LINK_FREQ (V4L2_CID_IMAGE_PROC_CLASS_BASE + 1) +#define V4L2_CID_PIXEL_RATE (V4L2_CID_IMAGE_PROC_CLASS_BASE + 2) +#define V4L2_CID_TEST_PATTERN (V4L2_CID_IMAGE_PROC_CLASS_BASE + 3) + + +/* DV-class control IDs defined by V4L2 */ +#define V4L2_CID_DV_CLASS_BASE (V4L2_CTRL_CLASS_DV | 0x900) +#define V4L2_CID_DV_CLASS (V4L2_CTRL_CLASS_DV | 1) + +#define V4L2_CID_DV_TX_HOTPLUG (V4L2_CID_DV_CLASS_BASE + 1) +#define V4L2_CID_DV_TX_RXSENSE (V4L2_CID_DV_CLASS_BASE + 2) +#define V4L2_CID_DV_TX_EDID_PRESENT (V4L2_CID_DV_CLASS_BASE + 3) +#define V4L2_CID_DV_TX_MODE (V4L2_CID_DV_CLASS_BASE + 4) +enum v4l2_dv_tx_mode { + V4L2_DV_TX_MODE_DVI_D = 0, + V4L2_DV_TX_MODE_HDMI = 1, +}; +#define V4L2_CID_DV_TX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 5) +enum v4l2_dv_rgb_range { + V4L2_DV_RGB_RANGE_AUTO = 0, + V4L2_DV_RGB_RANGE_LIMITED = 1, + V4L2_DV_RGB_RANGE_FULL = 2, +}; + +#define V4L2_CID_DV_RX_POWER_PRESENT (V4L2_CID_DV_CLASS_BASE + 100) +#define V4L2_CID_DV_RX_RGB_RANGE (V4L2_CID_DV_CLASS_BASE + 101) + +#define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900) +#define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1) + +#define V4L2_CID_TUNE_DEEMPHASIS (V4L2_CID_FM_RX_CLASS_BASE + 1) +enum v4l2_deemphasis { + V4L2_DEEMPHASIS_DISABLED = V4L2_PREEMPHASIS_DISABLED, + V4L2_DEEMPHASIS_50_uS = V4L2_PREEMPHASIS_50_uS, + V4L2_DEEMPHASIS_75_uS = V4L2_PREEMPHASIS_75_uS, +}; + +#define V4L2_CID_RDS_RECEPTION (V4L2_CID_FM_RX_CLASS_BASE + 2) + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-ctrls.h b/USDK/component/common/video/v4l2/inc/v4l2-ctrls.h new file mode 100644 index 0000000..4f7ad7f --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-ctrls.h @@ -0,0 +1,696 @@ +/* + V4L2 controls support header. + + Copyright (C) 2010 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L2_CTRLS_H +#define _V4L2_CTRLS_H +#if 0 +#include +#include +#endif +#include "v4l2-osdep.h" +#include "videodev2.h" + + +/* forward references */ +//struct file; +struct v4l2_ctrl_handler; +struct v4l2_ctrl_helper; +struct v4l2_ctrl; +struct video_device; +struct v4l2_subdev; +struct v4l2_subscribed_event; +struct v4l2_fh; +//struct poll_table_struct; + +/** struct v4l2_ctrl_ops - The control operations that the driver has to provide. + * @g_volatile_ctrl: Get a new value for this control. Generally only relevant + * for volatile (and usually read-only) controls such as a control + * that returns the current signal strength which changes + * continuously. + * If not set, then the currently cached value will be returned. + * @try_ctrl: Test whether the control's value is valid. Only relevant when + * the usual min/max/step checks are not sufficient. + * @s_ctrl: Actually set the new control value. s_ctrl is compulsory. The + * ctrl->handler->lock is held when these ops are called, so no + * one else can access controls owned by that handler. + */ +struct v4l2_ctrl_ops { + int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl); + int (*try_ctrl)(struct v4l2_ctrl *ctrl); + int (*s_ctrl)(struct v4l2_ctrl *ctrl); +}; + +typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); + +/** struct v4l2_ctrl - The control structure. + * @node: The list node. + * @ev_subs: The list of control event subscriptions. + * @handler: The handler that owns the control. + * @cluster: Point to start of cluster array. + * @ncontrols: Number of controls in cluster array. + * @done: Internal flag: set for each processed control. + * @is_new: Set when the user specified a new value for this control. It + * is also set when called from v4l2_ctrl_handler_setup. Drivers + * should never set this flag. + * @is_private: If set, then this control is private to its handler and it + * will not be added to any other handlers. Drivers can set + * this flag. + * @is_auto: If set, then this control selects whether the other cluster + * members are in 'automatic' mode or 'manual' mode. This is + * used for autogain/gain type clusters. Drivers should never + * set this flag directly. + * @has_volatiles: If set, then one or more members of the cluster are volatile. + * Drivers should never touch this flag. + * @call_notify: If set, then call the handler's notify function whenever the + * control's value changes. + * @manual_mode_value: If the is_auto flag is set, then this is the value + * of the auto control that determines if that control is in + * manual mode. So if the value of the auto control equals this + * value, then the whole cluster is in manual mode. Drivers should + * never set this flag directly. + * @ops: The control ops. + * @id: The control ID. + * @name: The control name. + * @type: The control type. + * @minimum: The control's minimum value. + * @maximum: The control's maximum value. + * @default_value: The control's default value. + * @step: The control's step value for non-menu controls. + * @menu_skip_mask: The control's skip mask for menu controls. This makes it + * easy to skip menu items that are not valid. If bit X is set, + * then menu item X is skipped. Of course, this only works for + * menus with <= 32 menu items. There are no menus that come + * close to that number, so this is OK. Should we ever need more, + * then this will have to be extended to a u64 or a bit array. + * @qmenu: A const char * array for all menu items. Array entries that are + * empty strings ("") correspond to non-existing menu items (this + * is in addition to the menu_skip_mask above). The last entry + * must be NULL. + * @flags: The control's flags. + * @cur: The control's current value. + * @val: The control's new s32 value. + * @val64: The control's new s64 value. + * @string: The control's new string value. + * @priv: The control's private pointer. For use by the driver. It is + * untouched by the control framework. Note that this pointer is + * not freed when the control is deleted. Should this be needed + * then a new internal bitfield can be added to tell the framework + * to free this pointer. + */ +struct v4l2_ctrl { + /* Administrative fields */ + struct list_head node; + struct list_head ev_subs; + struct v4l2_ctrl_handler *handler; + struct v4l2_ctrl **cluster; + unsigned ncontrols; + unsigned int done:1; + + unsigned int is_new:1; + unsigned int is_private:1; + unsigned int is_auto:1; + unsigned int has_volatiles:1; + unsigned int call_notify:1; + unsigned int manual_mode_value:8; + + const struct v4l2_ctrl_ops *ops; + u32 id; + const char *name; + enum v4l2_ctrl_type type; + s32 minimum, maximum, default_value; + union { + u32 step; + u32 menu_skip_mask; + }; + union { + const char * const *qmenu; + const s64 *qmenu_int; + }; + unsigned long flags; + union { + s32 val; + s64 val64; + char *string; + } cur; + union { + s32 val; + s64 val64; + char *string; + }; + void *priv; +}; + +/** struct v4l2_ctrl_ref - The control reference. + * @node: List node for the sorted list. + * @next: Single-link list node for the hash. + * @ctrl: The actual control information. + * @helper: Pointer to helper struct. Used internally in prepare_ext_ctrls(). + * + * Each control handler has a list of these refs. The list_head is used to + * keep a sorted-by-control-ID list of all controls, while the next pointer + * is used to link the control in the hash's bucket. + */ +struct v4l2_ctrl_ref { + struct list_head node; + struct v4l2_ctrl_ref *next; + struct v4l2_ctrl *ctrl; + struct v4l2_ctrl_helper *helper; +}; + +/** struct v4l2_ctrl_handler - The control handler keeps track of all the + * controls: both the controls owned by the handler and those inherited + * from other handlers. + * @_lock: Default for "lock". + * @lock: Lock to control access to this handler and its controls. + * May be replaced by the user right after init. + * @ctrls: The list of controls owned by this handler. + * @ctrl_refs: The list of control references. + * @cached: The last found control reference. It is common that the same + * control is needed multiple times, so this is a simple + * optimization. + * @buckets: Buckets for the hashing. Allows for quick control lookup. + * @notify: A notify callback that is called whenever the control changes value. + * Note that the handler's lock is held when the notify function + * is called! + * @notify_priv: Passed as argument to the v4l2_ctrl notify callback. + * @nr_of_buckets: Total number of buckets in the array. + * @error: The error code of the first failed control addition. + */ +struct v4l2_ctrl_handler { + //struct mutex _lock; + //struct mutex *lock; + _Mutex _lock; + _Mutex *lock; + struct list_head ctrls; + struct list_head ctrl_refs; + struct v4l2_ctrl_ref *cached; + struct v4l2_ctrl_ref **buckets; + v4l2_ctrl_notify_fnc notify; + void *notify_priv; + u16 nr_of_buckets; + int error; +}; + +/** struct v4l2_ctrl_config - Control configuration structure. + * @ops: The control ops. + * @id: The control ID. + * @name: The control name. + * @type: The control type. + * @min: The control's minimum value. + * @max: The control's maximum value. + * @step: The control's step value for non-menu controls. + * @def: The control's default value. + * @flags: The control's flags. + * @menu_skip_mask: The control's skip mask for menu controls. This makes it + * easy to skip menu items that are not valid. If bit X is set, + * then menu item X is skipped. Of course, this only works for + * menus with <= 32 menu items. There are no menus that come + * close to that number, so this is OK. Should we ever need more, + * then this will have to be extended to a u64 or a bit array. + * @qmenu: A const char * array for all menu items. Array entries that are + * empty strings ("") correspond to non-existing menu items (this + * is in addition to the menu_skip_mask above). The last entry + * must be NULL. + * @is_private: If set, then this control is private to its handler and it + * will not be added to any other handlers. + */ +struct v4l2_ctrl_config { + const struct v4l2_ctrl_ops *ops; + u32 id; + const char *name; + enum v4l2_ctrl_type type; + s32 min; + s32 max; + u32 step; + s32 def; + u32 flags; + u32 menu_skip_mask; + const char * const *qmenu; + const s64 *qmenu_int; + unsigned int is_private:1; +}; + +/** v4l2_ctrl_fill() - Fill in the control fields based on the control ID. + * + * This works for all standard V4L2 controls. + * For non-standard controls it will only fill in the given arguments + * and @name will be NULL. + * + * This function will overwrite the contents of @name, @type and @flags. + * The contents of @min, @max, @step and @def may be modified depending on + * the type. + * + * Do not use in drivers! It is used internally for backwards compatibility + * control handling only. Once all drivers are converted to use the new + * control framework this function will no longer be exported. + */ +void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, + s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags); + + +/** v4l2_ctrl_handler_init_class() - Initialize the control handler. + * @hdl: The control handler. + * @nr_of_controls_hint: A hint of how many controls this handler is + * expected to refer to. This is the total number, so including + * any inherited controls. It doesn't have to be precise, but if + * it is way off, then you either waste memory (too many buckets + * are allocated) or the control lookup becomes slower (not enough + * buckets are allocated, so there are more slow list lookups). + * It will always work, though. + * @key: Used by the lock validator if CONFIG_LOCKDEP is set. + * @name: Used by the lock validator if CONFIG_LOCKDEP is set. + * + * Returns an error if the buckets could not be allocated. This error will + * also be stored in @hdl->error. + * + * Never use this call directly, always use the v4l2_ctrl_handler_init + * macro that hides the @key and @name arguments. + */ +#if 0 +int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, + unsigned nr_of_controls_hint, + struct lock_class_key *key, const char *name); + +#ifdef CONFIG_LOCKDEP +#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint) \ +( \ + ({ \ + static struct lock_class_key _key; \ + v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint, \ + &_key, \ + KBUILD_BASENAME ":" \ + __stringify(__LINE__) ":" \ + "(" #hdl ")->_lock"); \ + }) \ +) +#else +#define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint) \ + v4l2_ctrl_handler_init_class(hdl, nr_of_controls_hint, NULL, NULL) +#endif +#endif + +/** v4l2_ctrl_handler_free() - Free all controls owned by the handler and free + * the control list. + * @hdl: The control handler. + * + * Does nothing if @hdl == NULL. + */ +void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl); + +/** v4l2_ctrl_handler_setup() - Call the s_ctrl op for all controls belonging + * to the handler to initialize the hardware to the current control values. + * @hdl: The control handler. + * + * Button controls will be skipped, as are read-only controls. + * + * If @hdl == NULL, then this just returns 0. + */ +int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl); + +/** v4l2_ctrl_handler_log_status() - Log all controls owned by the handler. + * @hdl: The control handler. + * @prefix: The prefix to use when logging the control values. If the + * prefix does not end with a space, then ": " will be added + * after the prefix. If @prefix == NULL, then no prefix will be + * used. + * + * For use with VIDIOC_LOG_STATUS. + * + * Does nothing if @hdl == NULL. + */ +void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl, + const char *prefix); + +/** v4l2_ctrl_new_custom() - Allocate and initialize a new custom V4L2 + * control. + * @hdl: The control handler. + * @cfg: The control's configuration data. + * @priv: The control's driver-specific private data. + * + * If the &v4l2_ctrl struct could not be allocated then NULL is returned + * and @hdl->error is set to the error code (if it wasn't set already). + */ +struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_config *cfg, void *priv); + +/** v4l2_ctrl_new_std() - Allocate and initialize a new standard V4L2 non-menu control. + * @hdl: The control handler. + * @ops: The control ops. + * @id: The control ID. + * @min: The control's minimum value. + * @max: The control's maximum value. + * @step: The control's step value + * @def: The control's default value. + * + * If the &v4l2_ctrl struct could not be allocated, or the control + * ID is not known, then NULL is returned and @hdl->error is set to the + * appropriate error code (if it wasn't set already). + * + * If @id refers to a menu control, then this function will return NULL. + * + * Use v4l2_ctrl_new_std_menu() when adding menu controls. + */ +struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s32 min, s32 max, u32 step, s32 def); + +/** v4l2_ctrl_new_std_menu() - Allocate and initialize a new standard V4L2 menu control. + * @hdl: The control handler. + * @ops: The control ops. + * @id: The control ID. + * @max: The control's maximum value. + * @mask: The control's skip mask for menu controls. This makes it + * easy to skip menu items that are not valid. If bit X is set, + * then menu item X is skipped. Of course, this only works for + * menus with <= 32 menu items. There are no menus that come + * close to that number, so this is OK. Should we ever need more, + * then this will have to be extended to a u64 or a bit array. + * @def: The control's default value. + * + * Same as v4l2_ctrl_new_std(), but @min is set to 0 and the @mask value + * determines which menu items are to be skipped. + * + * If @id refers to a non-menu control, then this function will return NULL. + */ +struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s32 max, s32 mask, s32 def); + +/** v4l2_ctrl_new_std_menu_items() - Create a new standard V4L2 menu control + * with driver specific menu. + * @hdl: The control handler. + * @ops: The control ops. + * @id: The control ID. + * @max: The control's maximum value. + * @mask: The control's skip mask for menu controls. This makes it + * easy to skip menu items that are not valid. If bit X is set, + * then menu item X is skipped. Of course, this only works for + * menus with <= 32 menu items. There are no menus that come + * close to that number, so this is OK. Should we ever need more, + * then this will have to be extended to a u64 or a bit array. + * @def: The control's default value. + * @qmenu: The new menu. + * + * Same as v4l2_ctrl_new_std_menu(), but @qmenu will be the driver specific + * menu of this control. + * + */ +struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, u32 id, s32 max, + s32 mask, s32 def, const char * const *qmenu); + +/** v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control. + * @hdl: The control handler. + * @ops: The control ops. + * @id: The control ID. + * @max: The control's maximum value. + * @def: The control's default value. + * @qmenu_int: The control's menu entries. + * + * Same as v4l2_ctrl_new_std_menu(), but @mask is set to 0 and it additionaly + * takes as an argument an array of integers determining the menu items. + * + * If @id refers to a non-integer-menu control, then this function will return NULL. + */ +struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s32 max, s32 def, const s64 *qmenu_int); + +/** v4l2_ctrl_add_ctrl() - Add a control from another handler to this handler. + * @hdl: The control handler. + * @ctrl: The control to add. + * + * It will return NULL if it was unable to add the control reference. + * If the control already belonged to the handler, then it will do + * nothing and just return @ctrl. + */ +struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl *ctrl); + +/** v4l2_ctrl_add_handler() - Add all controls from handler @add to + * handler @hdl. + * @hdl: The control handler. + * @add: The control handler whose controls you want to add to + * the @hdl control handler. + * @filter: This function will filter which controls should be added. + * + * Does nothing if either of the two handlers is a NULL pointer. + * If @filter is NULL, then all controls are added. Otherwise only those + * controls for which @filter returns true will be added. + * In case of an error @hdl->error will be set to the error code (if it + * wasn't set already). + */ +int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl, + struct v4l2_ctrl_handler *add, + bool (*filter)(const struct v4l2_ctrl *ctrl)); + +/** v4l2_ctrl_radio_filter() - Standard filter for radio controls. + * @ctrl: The control that is filtered. + * + * This will return true for any controls that are valid for radio device + * nodes. Those are all of the V4L2_CID_AUDIO_* user controls and all FM + * transmitter class controls. + * + * This function is to be used with v4l2_ctrl_add_handler(). + */ +bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl); + +/** v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging to that cluster. + * @ncontrols: The number of controls in this cluster. + * @controls: The cluster control array of size @ncontrols. + */ +void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls); + + +/** v4l2_ctrl_auto_cluster() - Mark all controls in the cluster as belonging to + * that cluster and set it up for autofoo/foo-type handling. + * @ncontrols: The number of controls in this cluster. + * @controls: The cluster control array of size @ncontrols. The first control + * must be the 'auto' control (e.g. autogain, autoexposure, etc.) + * @manual_val: The value for the first control in the cluster that equals the + * manual setting. + * @set_volatile: If true, then all controls except the first auto control will + * be volatile. + * + * Use for control groups where one control selects some automatic feature and + * the other controls are only active whenever the automatic feature is turned + * off (manual mode). Typical examples: autogain vs gain, auto-whitebalance vs + * red and blue balance, etc. + * + * The behavior of such controls is as follows: + * + * When the autofoo control is set to automatic, then any manual controls + * are set to inactive and any reads will call g_volatile_ctrl (if the control + * was marked volatile). + * + * When the autofoo control is set to manual, then any manual controls will + * be marked active, and any reads will just return the current value without + * going through g_volatile_ctrl. + * + * In addition, this function will set the V4L2_CTRL_FLAG_UPDATE flag + * on the autofoo control and V4L2_CTRL_FLAG_INACTIVE on the foo control(s) + * if autofoo is in auto mode. + */ +void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, + u8 manual_val, bool set_volatile); + + +/** v4l2_ctrl_find() - Find a control with the given ID. + * @hdl: The control handler. + * @id: The control ID to find. + * + * If @hdl == NULL this will return NULL as well. Will lock the handler so + * do not use from inside &v4l2_ctrl_ops. + */ +struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id); + +/** v4l2_ctrl_activate() - Make the control active or inactive. + * @ctrl: The control to (de)activate. + * @active: True if the control should become active. + * + * This sets or clears the V4L2_CTRL_FLAG_INACTIVE flag atomically. + * Does nothing if @ctrl == NULL. + * This will usually be called from within the s_ctrl op. + * The V4L2_EVENT_CTRL event will be generated afterwards. + * + * This function assumes that the control handler is locked. + */ +void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active); + +/** v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed. + * @ctrl: The control to (de)activate. + * @grabbed: True if the control should become grabbed. + * + * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically. + * Does nothing if @ctrl == NULL. + * The V4L2_EVENT_CTRL event will be generated afterwards. + * This will usually be called when starting or stopping streaming in the + * driver. + * + * This function assumes that the control handler is not locked and will + * take the lock itself. + */ +void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); + +/** v4l2_ctrl_modify_range() - Update the range of a control. + * @ctrl: The control to update. + * @min: The control's minimum value. + * @max: The control's maximum value. + * @step: The control's step value + * @def: The control's default value. + * + * Update the range of a control on the fly. This works for control types + * INTEGER, BOOLEAN, MENU, INTEGER MENU and BITMASK. For menu controls the + * @step value is interpreted as a menu_skip_mask. + * + * An error is returned if one of the range arguments is invalid for this + * control type. + * + * This function assumes that the control handler is not locked and will + * take the lock itself. + */ +int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, + s32 min, s32 max, u32 step, s32 def); + +/** v4l2_ctrl_lock() - Helper function to lock the handler + * associated with the control. + * @ctrl: The control to lock. + */ +static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) +{ + mutex_lock(ctrl->handler->lock); +} + +/** v4l2_ctrl_lock() - Helper function to unlock the handler + * associated with the control. + * @ctrl: The control to unlock. + */ +static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl) +{ + mutex_unlock(ctrl->handler->lock); +} + +/** v4l2_ctrl_notify() - Function to set a notify callback for a control. + * @ctrl: The control. + * @notify: The callback function. + * @priv: The callback private handle, passed as argument to the callback. + * + * This function sets a callback function for the control. If @ctrl is NULL, + * then it will do nothing. If @notify is NULL, then the notify callback will + * be removed. + * + * There can be only one notify. If another already exists, then a WARN_ON + * will be issued and the function will do nothing. + */ +void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv); + +/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver. + * @ctrl: The control. + * + * This returns the control's value safely by going through the control + * framework. This function will lock the control's handler, so it cannot be + * used from within the &v4l2_ctrl_ops functions. + * + * This function is for integer type controls only. + */ +s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl); + +/** v4l2_ctrl_s_ctrl() - Helper function to set the control's value from within a driver. + * @ctrl: The control. + * @val: The new value. + * + * This set the control's new value safely by going through the control + * framework. This function will lock the control's handler, so it cannot be + * used from within the &v4l2_ctrl_ops functions. + * + * This function is for integer type controls only. + */ +int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val); + +/** v4l2_ctrl_g_ctrl_int64() - Helper function to get a 64-bit control's value from within a driver. + * @ctrl: The control. + * + * This returns the control's value safely by going through the control + * framework. This function will lock the control's handler, so it cannot be + * used from within the &v4l2_ctrl_ops functions. + * + * This function is for 64-bit integer type controls only. + */ +s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl); + +/** v4l2_ctrl_s_ctrl_int64() - Helper function to set a 64-bit control's value from within a driver. + * @ctrl: The control. + * @val: The new value. + * + * This set the control's new value safely by going through the control + * framework. This function will lock the control's handler, so it cannot be + * used from within the &v4l2_ctrl_ops functions. + * + * This function is for 64-bit integer type controls only. + */ +int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val); + +/* Internal helper functions that deal with control events. */ +extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops; +void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new); +void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new); + +/* Can be used as a vidioc_log_status function that just dumps all controls + associated with the filehandle. */ +int v4l2_ctrl_log_status(void *fh); + +/* Can be used as a vidioc_subscribe_event function that just subscribes + control events. */ +int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); + +/* Can be used as a poll function that just polls for control events. */ +//unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait); + +/* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */ +int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc); +int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm); +int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl); +int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, + struct v4l2_control *ctrl); +int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c); +int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c); +int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, + struct v4l2_ext_controls *c); + +/* Helpers for subdevices. If the associated ctrl_handler == NULL then they + will all return -EINVAL. */ +int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc); +int v4l2_subdev_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); +int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs); +int v4l2_subdev_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs); +int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs); +int v4l2_subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); +int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); + +/* Can be used as a subscribe_event function that just subscribes control + events. */ +int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub); + +/* Log all controls owned by subdev's control handler. */ +int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd); + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-dev.h b/USDK/component/common/video/v4l2/inc/v4l2-dev.h new file mode 100644 index 0000000..417eaab --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-dev.h @@ -0,0 +1,273 @@ +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Moved from videodev2.h + * + * Some commonly needed functions for drivers (v4l2-common.o module) + */ +#ifndef _V4L2_DEV_H +#define _V4L2_DEV_H +#if 0 +#include +#include +#include +#include +#include +#endif +#include "v4l2-osdep.h" +#include "uapi_videodev2.h" +#include "media-entity.h" + + +#define VIDEO_MAJOR 81 + +#define VFL_TYPE_GRABBER 0 +#define VFL_TYPE_VBI 1 +#define VFL_TYPE_RADIO 2 +#define VFL_TYPE_SUBDEV 3 +#define VFL_TYPE_MAX 4 + +/* Is this a receiver, transmitter or mem-to-mem? */ +/* Ignored for VFL_TYPE_SUBDEV. */ +#define VFL_DIR_RX 0 +#define VFL_DIR_TX 1 +#define VFL_DIR_M2M 2 + +//struct v4l2_ioctl_callbacks; // can't find out from the kernel source code +struct video_device; +struct v4l2_device; +struct v4l2_ctrl_handler; +enum v4l2_priority; +/* Flag to mark the video_device struct as registered. + Drivers can clear this flag if they want to block all future + device access. It is cleared by video_unregister_device. */ +#define V4L2_FL_REGISTERED (0) +/* file->private_data points to struct v4l2_fh */ +#define V4L2_FL_USES_V4L2_FH (1) +/* Use the prio field of v4l2_fh for core priority checking */ +#define V4L2_FL_USE_FH_PRIO (2) + +/* Priority helper functions */ + +struct v4l2_prio_state { + atomic_t prios[4]; +}; + +/* +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, // l + V4L2_PRIORITY_BACKGROUND = 1, // I + V4L2_PRIORITY_INTERACTIVE = 2, // + V4L2_PRIORITY_RECORD = 3, // + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE, +}; +ɬvOFMultiple Opensާ@AiHdevicePɳQhthread }(i.e open()) +ݭnγouvhϤӾާ@󭫭nAϥΪuŧOAprios[4]N[@C +*/ + +void v4l2_prio_init(struct v4l2_prio_state *global); +int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, + enum v4l2_priority new); +void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); +void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local); +enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); +int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local); + + +struct v4l2_file_operations { + //struct module *owner; + //ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + //ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); + //unsigned int (*poll) (struct file *, struct poll_table_struct *); + long (*ioctl) (unsigned int, unsigned long); + long (*unlocked_ioctl) (unsigned int, unsigned long); +#ifdef CONFIG_COMPAT + long (*compat_ioctl32) (unsigned int, unsigned long); +#endif + //unsigned long (*get_unmapped_area) (struct file *, unsigned long, + // unsigned long, unsigned long, unsigned long); + int (*mmap) (); + int (*open) (); + int (*release) (); +}; + + + +/* + * Newer version of video_device, handled by videodev2.c + * This version moves redundant code from video device code to + * the common handler + */ + +struct video_device +{ +#if defined(CONFIG_MEDIA_CONTROLLER) + struct media_entity entity; +#endif + /* device ops */ + const struct v4l2_file_operations *fops; + + /* sysfs */ + //struct device dev; /* v4l device,this is mainlt for sysfs */ + unsigned long dev; /* replace to the reference count */ + void *dev_driver_data; + const char *init_name; /* initial name of the device */ + void (*dev_release)(); /* release call back in origonal dev */ + + //struct cdev *cdev; /* character device, which video device register */ + //struct file_operations *cdev_ops;/* file_operations in origonal cdev */ + + struct v4l2_device *v4l2_dev; /* v4l2_device parent */ + /* Only set parent if that can't be deduced from v4l2_dev */ + //struct device *dev_parent; /* device parent */ + + /* Control handler associated with this device node. May be NULL. + * look up v4l2_ctrls.h for more detail */ + struct v4l2_ctrl_handler *ctrl_handler; + + /* vb2_queue associated with this device node. May be NULL. */ + struct vb2_queue *queue; + + /* Priority state. If NULL, then v4l2_dev->prio will be used. */ + struct v4l2_prio_state *prio; + + /* device info */ + char name[32]; + int vfl_type; /* device type,usally assign the define VFL_TYPE_XXX value */ + int vfl_dir; /* receiver, transmitter or m2m,usally assign the define VFL_DIR_XXX value */ + /* 'minor' is set to -1 if the registration failed */ + int minor; + u16 num; /* record the registered video device node number */ + /* use bitops to set/clear/test flags,usally assign the define VFL_FL_XXX value */ + unsigned long flags; + /* attribute to differentiate multiple indices on one physical device */ + int index; + + /* V4L2 file handles */ + //spinlock_t fh_lock; /* Lock for all v4l2_fhs */ + _Lock fh_lock; + struct list_head fh_list; /* List of struct v4l2_fh */ + int debug; /* Activates debug level*/ + + /* Video standard vars (v4l2_std_id = u64)*/ + //v4l2_std_id tvnorms; /* Supported tv norms,usally assign the define VFL_STD_XXX value */ + u64 tvnorms; + + /* callbacks,this must non-NULL,in usually use the video_device_release()to replace of */ + void (*release)(struct video_device *vdev); + + /* ioctl callbacks,look up v4l2-ioctl.h for more detail */ + const struct v4l2_ioctl_ops *ioctl_ops; + //DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); /* unsigned long valid_ioctls[6] */ + unsigned long valid_ioctls[6]; + /* serialization lock */ + //DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE); /* unsigned long disable_locking[6] */ + unsigned long disable_locking[6]; + //struct mutex *lock; /* make serilized ioctl lock possible */ + _Mutex *lock; +}; + +/* todo need to modify */ +#if 0 +#define media_entity_to_video_device(__e) \ + container_of(__e, struct video_device, entity) + +/* dev to video-device */ +#define to_video_device(cd) container_of(cd, struct video_device, dev) +#endif + +int __video_register_device(struct video_device *vdev, int type, + int nr, int warn_if_nr_in_use/*, struct module *owner*/); + +/* Register video devices. Note that if video_register_device fails, + the release() callback of the video_device structure is *not* called, so + the caller is responsible for freeing any data. Usually that means that + you call video_device_release() on failure. */ +static inline int video_register_device(struct video_device *vdev, + int type, int nr) +{ + // type = VFL_TYPE_GRABBER, nr = -1, 1, "THIS_MODULE" + return __video_register_device(vdev, type, nr, 1/*, vdev->fops->owner*/); +} + +/* Same as video_register_device, but no warning is issued if the desired + device node number was already in use. */ +static inline int video_register_device_no_warn( + struct video_device *vdev, int type, int nr) +{ + return __video_register_device(vdev, type, nr, 0/*, vdev->fops->owner*/); +} + +/* Unregister video devices. Will do nothing if vdev == NULL or + video_is_registered() returns false. */ +void video_unregister_device(struct video_device *vdev); + +/* helper functions to alloc/release struct video_device, the + latter can also be used for video_device->release(). */ +struct video_device *video_device_alloc(void); + +/* this release function frees the vdev pointer */ +void video_device_release(struct video_device *vdev); + +/* this release function does nothing, use when the video_device is a + static global struct. Note that having a static video_device is + a dubious construction at best. */ +void video_device_release_empty(struct video_device *vdev); + +/* returns true if cmd is a known V4L2 ioctl */ +bool v4l2_is_known_ioctl(unsigned int cmd); + +/* mark that this command shouldn't use core locking */ +static inline void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd) +{ + #define BASE_VIDIOC_PRIVATE 192 + if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) + set_bit(_IOC_NR(cmd), vdev->disable_locking); +} + +/* Mark that this command isn't implemented. This must be called before + video_device_register. See also the comments in determine_valid_ioctls(). + This function allows drivers to provide just one v4l2_ioctl_ops struct, but + disable ioctls based on the specific card that is actually found. */ +static inline void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd) +{ + #define BASE_VIDIOC_PRIVATE 192 + if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE) + set_bit(_IOC_NR(cmd), vdev->valid_ioctls); +} + +/* helper functions to access driver private data. */ +static inline void *video_get_drvdata(struct video_device *vdev) +{ + //return dev_get_drvdata(&vdev->dev); + return (vdev->dev_driver_data); +} + +static inline void video_set_drvdata(struct video_device *vdev, void *data) +{ + //dev_set_drvdata(&vdev->dev, data); + vdev->dev_driver_data = data; +} + +struct video_device *video_devdata(); + +/* Combine video_get_drvdata and video_devdata as this is + used very often. */ +static inline void *video_drvdata() +{ + return video_get_drvdata(video_devdata()); +} + +static inline const char *video_device_node_name(struct video_device *vdev) +{ + //return dev_name(&vdev->dev); + return (vdev->init_name); +} + +static inline int video_is_registered(struct video_device *vdev) +{ + return test_bit(V4L2_FL_REGISTERED, &vdev->flags); +} + +#endif /* _V4L2_DEV_H */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-device.h b/USDK/component/common/video/v4l2/inc/v4l2-device.h new file mode 100644 index 0000000..9eb7560 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-device.h @@ -0,0 +1,216 @@ +/* + V4L2 device support header. + + Copyright (C) 2008 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L2_DEVICE_H +#define _V4L2_DEVICE_H + +#include "media-device.h" +#include "v4l2-subdev.h" +#include "v4l2-dev.h" + + + + +/* Each instance of a V4L2 device should create the v4l2_device struct, + either stand-alone or embedded in a larger struct. + + It allows easy access to sub-devices (see v4l2-subdev.h) and provides + basic V4L2 device-level support. + */ + +#define V4L2_DEVICE_NAME_SIZE (20 + 16) + +struct v4l2_ctrl_handler; + +struct v4l2_device { + /* dev->driver_data points to this struct. + Note: dev might be NULL if there is no parent device + as is the case with e.g. ISA devices. */ + //struct device *dev; + //void *dev; + void *dev_driver_data; +//edit by Ian + //unsigned long dev_ref_count; +#if defined(CONFIG_MEDIA_CONTROLLER) + struct media_device *mdev; +#endif + /* used to keep track of the registered subdevs */ + struct list_head subdevs; + /* lock this struct; can be used by the driver as well if this + struct is embedded into a larger struct. */ + //spinlock_t lock; + _Lock lock; + /* unique device name, by default the driver name + bus ID */ + char name[V4L2_DEVICE_NAME_SIZE]; + /* notify callback called by some sub-devices. */ + void (*notify)(struct v4l2_subdev *sd, unsigned int notification, void *arg); + /* The control handler. May be NULL. */ + struct v4l2_ctrl_handler *ctrl_handler; + /* Device's priority state */ + struct v4l2_prio_state prio; + /* BKL replacement mutex. Temporary solution only. */ + //struct mutex ioctl_lock; + _Mutex ioctl_lock; + /* Keep track of the references to this struct. */ + //struct kref ref; + unsigned long ref; + /* Release function that is called when the ref count goes to 0. */ + void (*release)(struct v4l2_device *v4l2_dev); +}; + +static inline void v4l2_device_get(struct v4l2_device *v4l2_dev) +{ + //kref_get(&v4l2_dev->ref); + atomic_inc((atomic_t *)&v4l2_dev->ref); +} + +int v4l2_device_put(struct v4l2_device *v4l2_dev); + +/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. + dev may be NULL in rare cases (ISA devices). In that case you + must fill in the v4l2_dev->name field before calling this function. */ +//int v4l2_device_register(struct v4l2_device *v4l2_dev); +int v4l2_device_register(void *dev_prive_date, struct v4l2_device *v4l2_dev); + +/* Optional function to initialize the name field of struct v4l2_device using + the driver name and a driver-global atomic_t instance. + This function will increment the instance counter and returns the instance + value used in the name. + + Example: + + static atomic_t drv_instance = ATOMIC_INIT(0); + + ... + + instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance); + + The first time this is called the name field will be set to foo0 and + this function returns 0. If the name ends with a digit (e.g. cx18), + then the name will be set to cx18-0 since cx180 looks really odd. */ +int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, + atomic_t *instance); + +/* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects. + Since the parent disappears this ensures that v4l2_dev doesn't have an + invalid parent pointer. */ +void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); + +/* Unregister all sub-devices and any other resources related to v4l2_dev. */ +void v4l2_device_unregister(struct v4l2_device *v4l2_dev); + +/* Register a subdev with a v4l2 device. While registered the subdev module + is marked as in-use. An error is returned if the module is no longer + loaded when you attempt to register it. */ +int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + struct v4l2_subdev *sd); +/* Unregister a subdev with a v4l2 device. Can also be called if the subdev + wasn't registered. In that case it will do nothing. */ +void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); + +/* Register device nodes for all subdev of the v4l2 device that are marked with + * the V4L2_SUBDEV_FL_HAS_DEVNODE flag. + */ +int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); + +/* Iterate over all subdevs. */ +#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ + list_for_each_entry(sd, &(v4l2_dev)->subdevs, list, struct v4l2_subdev) + +/* Call the specified callback for all subdevs matching the condition. + Ignore any errors. Note that you cannot add or delete a subdev + while walking the subdevs list. */ +#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ + do { \ + list_for_each_entry((sd), &(v4l2_dev)->subdevs, list, struct v4l2_subdev) \ + if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ + (sd)->ops->o->f((sd) , ##args); \ + } while (0) + +#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ + do { \ + struct v4l2_subdev *__sd; \ + \ + __v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o, \ + f , ##args); \ + } while (0) + +/* Call the specified callback for all subdevs matching the condition. + If the callback returns an error other than 0 or -ENOIOCTLCMD, then + return with that error code. Note that you cannot add or delete a + subdev while walking the subdevs list. */ +#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ +({ \ + long __err = 0; \ + \ + list_for_each_entry((sd), &(v4l2_dev)->subdevs, list, struct v4l2_subdev) { \ + if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ + __err = (sd)->ops->o->f((sd) , ##args); \ + if (__err && __err != -ENOIOCTLCMD) \ + break; \ + } \ + (__err == -ENOIOCTLCMD) ? 0 : __err; \ +}) + +#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ +({ \ + struct v4l2_subdev *__sd; \ + __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ + f , ##args); \ +}) + +/* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). Ignore any errors. Note that you cannot add or delete + a subdev while walking the subdevs list. */ +#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ + do { \ + struct v4l2_subdev *__sd; \ + \ + __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ + !(grpid) || __sd->grp_id == (grpid), o, f , \ + ##args); \ + } while (0) + +/* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). If the callback returns an error other than 0 or + -ENOIOCTLCMD, then return with that error code. Note that you cannot + add or delete a subdev while walking the subdevs list. */ +#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ +({ \ + struct v4l2_subdev *__sd; \ + __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ + !(grpid) || __sd->grp_id == (grpid), o, f , \ + ##args); \ +}) + +#define v4l2_device_has_op(v4l2_dev, o, f) \ +({ \ + struct v4l2_subdev *__sd; \ + bool __result = FALSE; \ + list_for_each_entry(__sd, &(v4l2_dev)->subdevs, list, struct v4l2_subdev) { \ + if (v4l2_subdev_has_op(__sd, o, f)) { \ + __result = true; \ + break; \ + } \ + } \ + __result; \ +}) + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-event.h b/USDK/component/common/video/v4l2/inc/v4l2-event.h new file mode 100644 index 0000000..0490131 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-event.h @@ -0,0 +1,139 @@ +/* + * v4l2-event.h + * + * V4L2 events. + * + * Copyright (C) 2009--2010 Nokia Corporation. + * + * Contact: Sakari Ailus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef V4L2_EVENT_H +#define V4L2_EVENT_H + +#if 0 +#include +#include +#endif +#include "v4l2-osdep.h" +#include "videodev2.h" + + +/* + * Overview: + * + * Events are subscribed per-filehandle. An event specification consists of a + * type and is optionally associated with an object identified through the + * 'id' field. So an event is uniquely identified by the (type, id) tuple. + * + * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event + * struct is added to that list, one for every subscribed event. + * + * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs. + * This array (ringbuffer, really) is used to store any events raised by the + * driver. The v4l2_kevent struct links into the 'available' list of the + * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first. + * + * Finally, if the event subscription is associated with a particular object + * such as a V4L2 control, then that object needs to know about that as well + * so that an event can be raised by that object. So the 'node' field can + * be used to link the v4l2_subscribed_event struct into a list of that + * object. + * + * So to summarize: + * + * struct v4l2_fh has two lists: one of the subscribed events, and one of the + * pending events. + * + * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of + * that particular type. + * + * If struct v4l2_subscribed_event is associated with a specific object, then + * that object will have an internal list of struct v4l2_subscribed_event so + * it knows who subscribed an event to that object. + */ + +struct v4l2_fh; +struct v4l2_subdev; +struct v4l2_subscribed_event; +struct video_device; + +/** struct v4l2_kevent - Internal kernel event struct. + * @list: List node for the v4l2_fh->available list. + * @sev: Pointer to parent v4l2_subscribed_event. + * @event: The event itself. + */ +struct v4l2_kevent { + struct list_head list; + struct v4l2_subscribed_event *sev; + struct v4l2_event event; +}; + +/** struct v4l2_subscribed_event_ops - Subscribed event operations. + * @add: Optional callback, called when a new listener is added + * @del: Optional callback, called when a listener stops listening + * @replace: Optional callback that can replace event 'old' with event 'new'. + * @merge: Optional callback that can merge event 'old' into event 'new'. + */ +struct v4l2_subscribed_event_ops { + int (*add)(struct v4l2_subscribed_event *sev, unsigned elems); + void (*del)(struct v4l2_subscribed_event *sev); + void (*replace)(struct v4l2_event *old, const struct v4l2_event *new); + void (*merge)(const struct v4l2_event *old, struct v4l2_event *new); +}; + +/** struct v4l2_subscribed_event - Internal struct representing a subscribed event. + * @list: List node for the v4l2_fh->subscribed list. + * @type: Event type. + * @id: Associated object ID (e.g. control ID). 0 if there isn't any. + * @flags: Copy of v4l2_event_subscription->flags. + * @fh: Filehandle that subscribed to this event. + * @node: List node that hooks into the object's event list (if there is one). + * @ops: v4l2_subscribed_event_ops + * @elems: The number of elements in the events array. + * @first: The index of the events containing the oldest available event. + * @in_use: The number of queued events. + * @events: An array of @elems events. + */ +struct v4l2_subscribed_event { + struct list_head list; + u32 type; + u32 id; + u32 flags; + struct v4l2_fh *fh; + struct list_head node; + const struct v4l2_subscribed_event_ops *ops; + unsigned elems; + unsigned first; + unsigned in_use; + struct v4l2_kevent events[]; +}; + +int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event, + int nonblocking); +void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev); +void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev); +int v4l2_event_pending(struct v4l2_fh *fh); +int v4l2_event_subscribe(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub, unsigned elems, + const struct v4l2_subscribed_event_ops *ops); +int v4l2_event_unsubscribe(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); +void v4l2_event_unsubscribe_all(struct v4l2_fh *fh); +int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub); +#endif /* V4L2_EVENT_H */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-fh.h b/USDK/component/common/video/v4l2/inc/v4l2-fh.h new file mode 100644 index 0000000..e3f8a21 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-fh.h @@ -0,0 +1,108 @@ +/* + * v4l2-fh.h + * + * V4L2 file handle. Store per file handle data for the V4L2 + * framework. Using file handles is optional for the drivers. + * + * Copyright (C) 2009--2010 Nokia Corporation. + * + * Contact: Sakari Ailus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef V4L2_FH_H +#define V4L2_FH_H + +//#include + +#include "v4l2-osdep.h" + +struct video_device; +struct v4l2_ctrl_handler; + +struct v4l2_fh { + struct list_head list; + struct video_device *vdev; + struct v4l2_ctrl_handler *ctrl_handler; + enum v4l2_priority prio; + + /* Events */ + //wait_queue_head_t wait; + _Sema wait; + struct list_head subscribed; /* Subscribed events */ + struct list_head available; /* Dequeueable event */ + unsigned int navailable; + u32 sequence; +}; + +/* + * Initialise the file handle. Parts of the V4L2 framework using the + * file handles should be initialised in this function. Must be called + * from driver's v4l2_file_operations->open() handler if the driver + * uses v4l2_fh. + */ +void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev); +/* + * Add the fh to the list of file handles on a video_device. The file + * handle must be initialised first. + */ +void v4l2_fh_add(struct v4l2_fh *fh); +/* + * Can be used as the open() op of v4l2_file_operations. + * It allocates a v4l2_fh and inits and adds it to the video_device associated + * with the file pointer. + */ +int v4l2_fh_open(); +/* + * Remove file handle from the list of file handles. Must be called in + * v4l2_file_operations->release() handler if the driver uses v4l2_fh. + * On error filp->private_data will be NULL, otherwise it will point to + * the v4l2_fh struct. + */ +void v4l2_fh_del(struct v4l2_fh *fh); +/* + * Release resources related to a file handle. Parts of the V4L2 + * framework using the v4l2_fh must release their resources here, too. + * Must be called in v4l2_file_operations->release() handler if the + * driver uses v4l2_fh. + */ +void v4l2_fh_exit(struct v4l2_fh *fh); +/* + * Can be used as the release() op of v4l2_file_operations. + * It deletes and exits the v4l2_fh associated with the file pointer and + * frees it. It will do nothing if filp->private_data (the pointer to the + * v4l2_fh struct) is NULL. This function always returns 0. + */ +int v4l2_fh_release(); +/* + * Returns 1 if this filehandle is the only filehandle opened for the + * associated video_device. If fh is NULL, then it returns 0. + */ +int v4l2_fh_is_singular(struct v4l2_fh *fh); +/* + * Helper function with struct file as argument. If filp->private_data is + * NULL, then it will return 0. + */ +extern void *replace_files[16]; +static inline int v4l2_fh_is_singular_file() +{ + //struct v4l2_fh *fh = replace_files[0]; + struct video_device *vdev = video_devdata(); + struct v4l2_fh *fh = replace_files[vdev->minor]; + return v4l2_fh_is_singular(fh); +} + +#endif /* V4L2_EVENT_H */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-int-device.h b/USDK/component/common/video/v4l2/inc/v4l2-int-device.h new file mode 100644 index 0000000..22e8b64 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-int-device.h @@ -0,0 +1,306 @@ +/* + * include/media/v4l2-int-device.h + * + * V4L2 internal ioctl interface. + * + * Copyright (C) 2007 Nokia Corporation. + * + * Contact: Sakari Ailus + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef V4L2_INT_DEVICE_H +#define V4L2_INT_DEVICE_H + +#include "v4l2-common.h" + + +#define V4L2NAMESIZE 32 + +/* + * + * The internal V4L2 device interface core. + * + */ + +enum v4l2_int_type { + v4l2_int_type_master = 1, + v4l2_int_type_slave +}; + +//struct module; + +struct v4l2_int_device; + +struct v4l2_int_master { + int (*attach)(struct v4l2_int_device *slave); + void (*detach)(struct v4l2_int_device *slave); +}; + +typedef int (v4l2_int_ioctl_func)(struct v4l2_int_device *); +typedef int (v4l2_int_ioctl_func_0)(struct v4l2_int_device *); +typedef int (v4l2_int_ioctl_func_1)(struct v4l2_int_device *, void *); + +struct v4l2_int_ioctl_desc { + int num; + v4l2_int_ioctl_func *func; +}; + +struct v4l2_int_slave { + /* Don't touch master. */ + struct v4l2_int_device *master; + + char attach_to[V4L2NAMESIZE]; + + int num_ioctls; + struct v4l2_int_ioctl_desc *ioctls; +}; + +struct v4l2_int_device { + /* Don't touch head. */ + struct LIST_HEADER head; + + //struct module *module; + + char name[V4L2NAMESIZE]; + + enum v4l2_int_type type; + union { + struct v4l2_int_master *master; + struct v4l2_int_slave *slave; + } u; + + void *priv; +}; + +void v4l2_int_device_try_attach_all(void); + +int v4l2_int_device_register(struct v4l2_int_device *d); +void v4l2_int_device_unregister(struct v4l2_int_device *d); + +int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd); +int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg); + +/* + * + * Types and definitions for IOCTL commands. + * + */ + +enum v4l2_power { + V4L2_POWER_OFF = 0, + V4L2_POWER_ON, + V4L2_POWER_STANDBY, +}; + +/* Slave interface type. */ +enum v4l2_if_type { + /* + * Parallel 8-, 10- or 12-bit interface, used by for example + * on certain image sensors. + */ + V4L2_IF_TYPE_BT656, +}; + +enum v4l2_if_type_bt656_mode { + /* + * Modes without Bt synchronisation codes. Separate + * synchronisation signal lines are used. + */ + V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT, + V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT, + V4L2_IF_TYPE_BT656_MODE_NOBT_12BIT, + /* + * Use Bt synchronisation codes. The vertical and horizontal + * synchronisation is done based on synchronisation codes. + */ + V4L2_IF_TYPE_BT656_MODE_BT_8BIT, + V4L2_IF_TYPE_BT656_MODE_BT_10BIT, +}; + +struct v4l2_if_type_bt656 { + /* + * 0: Frame begins when vsync is high. + * 1: Frame begins when vsync changes from low to high. + */ + unsigned frame_start_on_rising_vs:1; + /* Use Bt synchronisation codes for sync correction. */ + unsigned bt_sync_correct:1; + /* Swap every two adjacent image data elements. */ + unsigned swap:1; + /* Inverted latch clock polarity from slave. */ + unsigned latch_clk_inv:1; + /* Hs polarity. 0 is active high, 1 active low. */ + unsigned nobt_hs_inv:1; + /* Vs polarity. 0 is active high, 1 active low. */ + unsigned nobt_vs_inv:1; + enum v4l2_if_type_bt656_mode mode; + /* Minimum accepted bus clock for slave (in Hz). */ + u32 clock_min; + /* Maximum accepted bus clock for slave. */ + u32 clock_max; + /* + * Current wish of the slave. May only change in response to + * ioctls that affect image capture. + */ + u32 clock_curr; +}; + +struct v4l2_ifparm { + enum v4l2_if_type if_type; + union { + struct v4l2_if_type_bt656 bt656; + } u; +}; + +/* IOCTL command numbers. */ +enum v4l2_int_ioctl_num { + /* + * + * "Proper" V4L ioctls, as in struct video_device. + * + */ + vidioc_int_enum_fmt_cap_num = 1, + vidioc_int_g_fmt_cap_num, + vidioc_int_s_fmt_cap_num, + vidioc_int_try_fmt_cap_num, + vidioc_int_queryctrl_num, + vidioc_int_g_ctrl_num, + vidioc_int_s_ctrl_num, + vidioc_int_cropcap_num, + vidioc_int_g_crop_num, + vidioc_int_s_crop_num, + vidioc_int_g_parm_num, + vidioc_int_s_parm_num, + vidioc_int_querystd_num, + vidioc_int_s_std_num, + vidioc_int_s_video_routing_num, + + /* + * + * Strictly internal ioctls. + * + */ + /* Initialise the device when slave attaches to the master. */ + vidioc_int_dev_init_num = 1000, + /* Delinitialise the device at slave detach. */ + vidioc_int_dev_exit_num, + /* Set device power state. */ + vidioc_int_s_power_num, + /* + * Get slave private data, e.g. platform-specific slave + * configuration used by the master. + */ + vidioc_int_g_priv_num, + /* Get slave interface parameters. */ + vidioc_int_g_ifparm_num, + /* Does the slave need to be reset after VIDIOC_DQBUF? */ + vidioc_int_g_needs_reset_num, + vidioc_int_enum_framesizes_num, + vidioc_int_enum_frameintervals_num, + + /* + * + * VIDIOC_INT_* ioctls. + * + */ + /* VIDIOC_INT_RESET */ + vidioc_int_reset_num, + /* VIDIOC_INT_INIT */ + vidioc_int_init_num, + + /* + * + * Start of private ioctls. + * + */ + vidioc_int_priv_start_num = 2000, +}; + +/* + * + * IOCTL wrapper functions for better type checking. + * + */ + +#define V4L2_INT_WRAPPER_0(name) \ + static inline int vidioc_int_##name(struct v4l2_int_device *d) \ + { \ + return v4l2_int_ioctl_0(d, vidioc_int_##name##_num); \ + } \ + \ + static inline struct v4l2_int_ioctl_desc \ + vidioc_int_##name##_cb(int (*func) \ + (struct v4l2_int_device *)) \ + { \ + struct v4l2_int_ioctl_desc desc; \ + \ + desc.num = vidioc_int_##name##_num; \ + desc.func = (v4l2_int_ioctl_func *)func; \ + \ + return desc; \ + } + +#define V4L2_INT_WRAPPER_1(name, arg_type, asterisk) \ + static inline int vidioc_int_##name(struct v4l2_int_device *d, \ + arg_type asterisk arg) \ + { \ + return v4l2_int_ioctl_1(d, vidioc_int_##name##_num, \ + (void *)(unsigned long)arg); \ + } \ + \ + static inline struct v4l2_int_ioctl_desc \ + vidioc_int_##name##_cb(int (*func) \ + (struct v4l2_int_device *, \ + arg_type asterisk)) \ + { \ + struct v4l2_int_ioctl_desc desc; \ + \ + desc.num = vidioc_int_##name##_num; \ + desc.func = (v4l2_int_ioctl_func *)func; \ + \ + return desc; \ + } + +V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *); +V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *); +V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *); +V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *); +V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *); +V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *); +V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *); +V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *); +V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *); +V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *); +V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); +V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *); +V4L2_INT_WRAPPER_1(querystd, v4l2_std_id, *); +V4L2_INT_WRAPPER_1(s_std, v4l2_std_id, *); +V4L2_INT_WRAPPER_1(s_video_routing, struct v4l2_routing, *); + +V4L2_INT_WRAPPER_0(dev_init); +V4L2_INT_WRAPPER_0(dev_exit); +V4L2_INT_WRAPPER_1(s_power, enum v4l2_power, ); +V4L2_INT_WRAPPER_1(g_priv, void, *); +V4L2_INT_WRAPPER_1(g_ifparm, struct v4l2_ifparm, *); +V4L2_INT_WRAPPER_1(g_needs_reset, void, *); +V4L2_INT_WRAPPER_1(enum_framesizes, struct v4l2_frmsizeenum, *); +V4L2_INT_WRAPPER_1(enum_frameintervals, struct v4l2_frmivalenum, *); + +V4L2_INT_WRAPPER_0(reset); +V4L2_INT_WRAPPER_0(init); + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-ioctl.h b/USDK/component/common/video/v4l2/inc/v4l2-ioctl.h new file mode 100644 index 0000000..6674b27 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-ioctl.h @@ -0,0 +1,320 @@ +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Moved from videodev2.h + * + * Some commonly needed functions for drivers (v4l2-common.o module) + */ +#ifndef _V4L2_IOCTL_H +#define _V4L2_IOCTL_H + +#if 0 +#include +#include +#include +#include /* need __user */ +#endif +#include "v4l2-osdep.h" +#include "videodev2.h" + +struct v4l2_fh; + +struct v4l2_ioctl_ops { + /* ioctl callbacks */ + + /* VIDIOC_QUERYCAP handler */ + int (*vidioc_querycap)(void *fh, struct v4l2_capability *cap); + + /* Priority handling */ + int (*vidioc_g_priority) (void *fh, + enum v4l2_priority *p); + int (*vidioc_s_priority) (void *fh, + enum v4l2_priority p); + + /* VIDIOC_ENUM_FMT handlers */ + int (*vidioc_enum_fmt_vid_cap) (void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_overlay) (void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_out) (void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_cap_mplane)(void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_out_mplane)(void *fh, + struct v4l2_fmtdesc *f); + + /* VIDIOC_G_FMT handlers */ + int (*vidioc_g_fmt_vid_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sliced_vbi_cap)(void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sliced_vbi_out)(void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_cap_mplane)(void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out_mplane)(void *fh, + struct v4l2_format *f); + + /* VIDIOC_S_FMT handlers */ + int (*vidioc_s_fmt_vid_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sliced_vbi_cap)(void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sliced_vbi_out)(void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_cap_mplane)(void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out_mplane)(void *fh, + struct v4l2_format *f); + + /* VIDIOC_TRY_FMT handlers */ + int (*vidioc_try_fmt_vid_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out_overlay)(void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_cap) (void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_out) (void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sliced_vbi_cap)(void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sliced_vbi_out)(void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_cap_mplane)(void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out_mplane)(void *fh, + struct v4l2_format *f); + + /* Buffer handlers */ + int (*vidioc_reqbufs) (void *fh, struct v4l2_requestbuffers *b); + int (*vidioc_querybuf)(void *fh, struct v4l2_buffer *b); + int (*vidioc_qbuf) (void *fh, struct v4l2_buffer *b); + int (*vidioc_expbuf) (void *fh, + struct v4l2_exportbuffer *e); + int (*vidioc_dqbuf) (void *fh, struct v4l2_buffer *b); + + int (*vidioc_create_bufs)(void *fh, struct v4l2_create_buffers *b); + int (*vidioc_prepare_buf)(void *fh, struct v4l2_buffer *b); + + int (*vidioc_overlay) (void *fh, unsigned int i); + int (*vidioc_g_fbuf) (void *fh, + struct v4l2_framebuffer *a); + int (*vidioc_s_fbuf) (void *fh, + const struct v4l2_framebuffer *a); + + /* Stream on/off */ + int (*vidioc_streamon) (void *fh, enum v4l2_buf_type i); + int (*vidioc_streamoff)(void *fh, enum v4l2_buf_type i); + + /* Standard handling + ENUMSTD is handled by videodev.c + */ + int (*vidioc_g_std) (void *fh, v4l2_std_id *norm); + int (*vidioc_s_std) (void *fh, v4l2_std_id norm); + int (*vidioc_querystd) (void *fh, v4l2_std_id *a); + + /* Input handling */ + int (*vidioc_enum_input)(void *fh, + struct v4l2_input *inp); + int (*vidioc_g_input) (void *fh, unsigned int *i); + int (*vidioc_s_input) (void *fh, unsigned int i); + + /* Output handling */ + int (*vidioc_enum_output) (void *fh, + struct v4l2_output *a); + int (*vidioc_g_output) (void *fh, unsigned int *i); + int (*vidioc_s_output) (void *fh, unsigned int i); + + /* Control handling */ + int (*vidioc_queryctrl) (void *fh, + struct v4l2_queryctrl *a); + int (*vidioc_g_ctrl) (void *fh, + struct v4l2_control *a); + int (*vidioc_s_ctrl) (void *fh, + struct v4l2_control *a); + int (*vidioc_g_ext_ctrls) (void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_s_ext_ctrls) (void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_try_ext_ctrls) (void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_querymenu) (void *fh, + struct v4l2_querymenu *a); + + /* Audio ioctls */ + int (*vidioc_enumaudio) (void *fh, + struct v4l2_audio *a); + int (*vidioc_g_audio) (void *fh, + struct v4l2_audio *a); + int (*vidioc_s_audio) (void *fh, + const struct v4l2_audio *a); + + /* Audio out ioctls */ + int (*vidioc_enumaudout) (void *fh, + struct v4l2_audioout *a); + int (*vidioc_g_audout) (void *fh, + struct v4l2_audioout *a); + int (*vidioc_s_audout) (void *fh, + const struct v4l2_audioout *a); + int (*vidioc_g_modulator) (void *fh, + struct v4l2_modulator *a); + int (*vidioc_s_modulator) (void *fh, + const struct v4l2_modulator *a); + /* Crop ioctls */ + int (*vidioc_cropcap) (void *fh, + struct v4l2_cropcap *a); + int (*vidioc_g_crop) (void *fh, + struct v4l2_crop *a); + int (*vidioc_s_crop) (void *fh, + const struct v4l2_crop *a); + int (*vidioc_g_selection) (void *fh, + struct v4l2_selection *s); + int (*vidioc_s_selection) (void *fh, + struct v4l2_selection *s); + /* Compression ioctls */ + int (*vidioc_g_jpegcomp) (void *fh, + struct v4l2_jpegcompression *a); + int (*vidioc_s_jpegcomp) (void *fh, + const struct v4l2_jpegcompression *a); + int (*vidioc_g_enc_index) ( void *fh, + struct v4l2_enc_idx *a); + int (*vidioc_encoder_cmd) (void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_try_encoder_cmd) (void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_decoder_cmd) (void *fh, + struct v4l2_decoder_cmd *a); + int (*vidioc_try_decoder_cmd) (void *fh, + struct v4l2_decoder_cmd *a); + + /* Stream type-dependent parameter ioctls */ + int (*vidioc_g_parm) (void *fh, + struct v4l2_streamparm *a); + int (*vidioc_s_parm) (void *fh, + struct v4l2_streamparm *a); + + /* Tuner ioctls */ + int (*vidioc_g_tuner) (void *fh, + struct v4l2_tuner *a); + int (*vidioc_s_tuner) (void *fh, + const struct v4l2_tuner *a); + int (*vidioc_g_frequency) (void *fh, + struct v4l2_frequency *a); + int (*vidioc_s_frequency) (void *fh, + const struct v4l2_frequency *a); + int (*vidioc_enum_freq_bands) (void *fh, + struct v4l2_frequency_band *band); + + /* Sliced VBI cap */ + int (*vidioc_g_sliced_vbi_cap) (void *fh, + struct v4l2_sliced_vbi_cap *a); + + /* Log status ioctl */ + int (*vidioc_log_status) ( void *fh); + + int (*vidioc_s_hw_freq_seek) (void *fh, + const struct v4l2_hw_freq_seek *a); + + /* Debugging ioctls */ +#ifdef CONFIG_VIDEO_ADV_DEBUG + int (*vidioc_g_register) (void *fh, + struct v4l2_dbg_register *reg); + int (*vidioc_s_register) (void *fh, + const struct v4l2_dbg_register *reg); + + int (*vidioc_g_chip_info) (void *fh, + struct v4l2_dbg_chip_info *chip); +#endif + + int (*vidioc_enum_framesizes) (void *fh, + struct v4l2_frmsizeenum *fsize); + + int (*vidioc_enum_frameintervals) (void *fh, + struct v4l2_frmivalenum *fival); + + /* DV Timings IOCTLs */ + int (*vidioc_s_dv_timings) (void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_g_dv_timings) (void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_query_dv_timings) ( void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_enum_dv_timings) (void *fh, + struct v4l2_enum_dv_timings *timings); + int (*vidioc_dv_timings_cap) (void *fh, + struct v4l2_dv_timings_cap *cap); + + int (*vidioc_subscribe_event) (struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); + int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); + + /* For other private ioctls */ + long (*vidioc_default) (void *fh, + bool valid_prio, unsigned int cmd, void *arg); +}; + + +/* v4l debugging and diagnostics */ + +/* Debug bitmask flags to be used on V4L2 */ +#define V4L2_DEBUG_IOCTL 0x01 +#define V4L2_DEBUG_IOCTL_ARG 0x02 + +/* Video standard functions */ +extern const char *v4l2_norm_to_name(v4l2_std_id id); +extern void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); +extern int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, const char *name); +/* Prints the ioctl in a human-readable format. If prefix != NULL, + then do printk(KERN_DEBUG "%s: ", prefix) first. */ +extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd); + +/* Internal use only: get the mutex (if any) that we need to lock for the + given command. */ +struct video_device; +extern _Mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd); + +/* names for fancy debug output */ +extern const char *v4l2_field_names[]; +extern const char *v4l2_type_names[]; + +#ifdef CONFIG_COMPAT +/* 32 Bits compatibility layer for 64 bits processors */ +extern long v4l2_compat_ioctl32(unsigned int cmd, unsigned long arg); +#endif + +typedef long (*v4l2_kioctl)(unsigned int cmd, void *arg); + +/* Include support for obsoleted stuff */ +extern long video_usercopy(unsigned int cmd, unsigned long arg, v4l2_kioctl func); + +/* Standard handlers for V4L ioctl's */ +extern long video_ioctl2(unsigned int cmd, unsigned long arg); + +#endif /* _V4L2_IOCTL_H */ diff --git a/USDK/component/common/video/v4l2/inc/v4l2-mediabus.h b/USDK/component/common/video/v4l2/inc/v4l2-mediabus.h new file mode 100644 index 0000000..553728e --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-mediabus.h @@ -0,0 +1,112 @@ +/* + * Media Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef V4L2_MEDIABUS_H +#define V4L2_MEDIABUS_H + +#include "v4l2-mediabus.h" + + +/* Parallel flags */ +/* + * Can the client run in master or in slave mode. By "Master mode" an operation + * mode is meant, when the client (e.g., a camera sensor) is producing + * horizontal and vertical synchronisation. In "Slave mode" the host is + * providing these signals to the slave. + */ +#define V4L2_MBUS_MASTER (1 << 0) +#define V4L2_MBUS_SLAVE (1 << 1) +/* + * Signal polarity flags + * Note: in BT.656 mode HSYNC, FIELD, and VSYNC are unused + * V4L2_MBUS_[HV]SYNC* flags should be also used for specifying + * configuration of hardware that uses [HV]REF signals + */ +#define V4L2_MBUS_HSYNC_ACTIVE_HIGH (1 << 2) +#define V4L2_MBUS_HSYNC_ACTIVE_LOW (1 << 3) +#define V4L2_MBUS_VSYNC_ACTIVE_HIGH (1 << 4) +#define V4L2_MBUS_VSYNC_ACTIVE_LOW (1 << 5) +#define V4L2_MBUS_PCLK_SAMPLE_RISING (1 << 6) +#define V4L2_MBUS_PCLK_SAMPLE_FALLING (1 << 7) +#define V4L2_MBUS_DATA_ACTIVE_HIGH (1 << 8) +#define V4L2_MBUS_DATA_ACTIVE_LOW (1 << 9) +/* FIELD = 0/1 - Field1 (odd)/Field2 (even) */ +#define V4L2_MBUS_FIELD_EVEN_HIGH (1 << 10) +/* FIELD = 1/0 - Field1 (odd)/Field2 (even) */ +#define V4L2_MBUS_FIELD_EVEN_LOW (1 << 11) +/* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */ +#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH (1 << 12) +#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW (1 << 13) + +/* Serial flags */ +/* How many lanes the client can use */ +#define V4L2_MBUS_CSI2_1_LANE (1 << 0) +#define V4L2_MBUS_CSI2_2_LANE (1 << 1) +#define V4L2_MBUS_CSI2_3_LANE (1 << 2) +#define V4L2_MBUS_CSI2_4_LANE (1 << 3) +/* On which channels it can send video data */ +#define V4L2_MBUS_CSI2_CHANNEL_0 (1 << 4) +#define V4L2_MBUS_CSI2_CHANNEL_1 (1 << 5) +#define V4L2_MBUS_CSI2_CHANNEL_2 (1 << 6) +#define V4L2_MBUS_CSI2_CHANNEL_3 (1 << 7) +/* Does it support only continuous or also non-continuous clock mode */ +#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK (1 << 8) +#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK (1 << 9) + +#define V4L2_MBUS_CSI2_LANES (V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \ + V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE) +#define V4L2_MBUS_CSI2_CHANNELS (V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CHANNEL_1 | \ + V4L2_MBUS_CSI2_CHANNEL_2 | V4L2_MBUS_CSI2_CHANNEL_3) + +/** + * v4l2_mbus_type - media bus type + * @V4L2_MBUS_PARALLEL: parallel interface with hsync and vsync + * @V4L2_MBUS_BT656: parallel interface with embedded synchronisation, can + * also be used for BT.1120 + * @V4L2_MBUS_CSI2: MIPI CSI-2 serial interface + */ +enum v4l2_mbus_type { + V4L2_MBUS_PARALLEL, + V4L2_MBUS_BT656, + V4L2_MBUS_CSI2, +}; + +/** + * v4l2_mbus_config - media bus configuration + * @type: in: interface type + * @flags: in / out: configuration flags, depending on @type + */ +struct v4l2_mbus_config { + enum v4l2_mbus_type type; + unsigned int flags; +}; + +#if 0 +static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, + const struct v4l2_mbus_framefmt *mbus_fmt) +{ + pix_fmt->width = mbus_fmt->width; + pix_fmt->height = mbus_fmt->height; + pix_fmt->field = mbus_fmt->field; + pix_fmt->colorspace = mbus_fmt->colorspace; +} + +static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt, + const struct v4l2_pix_format *pix_fmt, + enum v4l2_mbus_pixelcode code) +{ + mbus_fmt->width = pix_fmt->width; + mbus_fmt->height = pix_fmt->height; + mbus_fmt->field = pix_fmt->field; + mbus_fmt->colorspace = pix_fmt->colorspace; + mbus_fmt->code = code; +} +#endif +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2-osdep.h b/USDK/component/common/video/v4l2/inc/v4l2-osdep.h new file mode 100644 index 0000000..581fd99 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-osdep.h @@ -0,0 +1,846 @@ +#ifndef _V4L2_OSDEP_H_ +#define _V4L2_OSDEP_H_ + +#include "platform/platform_stdlib.h" +#include "basic_types.h" +#include "osdep_api.h" +#include "usb_defs.h" +#include "errno.h" +//#include "hal_util.h" +#include "dlist.h" + +#define V4L2_LAYER_DEBUG 0 +#if V4L2_LAYER_DEBUG +#define V4L2_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#define V4L2_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#else +#define V4L2_PRINTF(fmt, args...) +#define V4L2_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args) +#endif + +/* misc items */ +#ifndef ssize_t +#define ssize_t SSIZE_T +#endif +#ifndef size_t +#define size_t SIZE_T +#endif + +#ifndef __user +#define __user +#endif + +#ifndef loff_t +#define loff_t long +#endif +#ifndef __u8 +#define __u8 u8 +#endif +#ifndef __u16 +#define __u16 u16 +#endif +#ifndef __u32 +#define __u32 u32 +#endif +#ifndef __u64 +#define __u64 u64 +#endif +#ifndef __s8 +#define __s8 s8 +#endif +#ifndef __s16 +#define __s16 s16 +#endif +#ifndef __s32 +#define __s32 s32 +#endif +#ifndef __s64 +#define __s64 s64 +#endif + +#ifndef spinlock_t +#define spinlock_t _Lock +#endif + +#ifndef gfp_t +#define gfp_t u32 +#endif + +#ifndef _atomic_spin_lock_irqsave +#define _atomic_spin_lock_irqsave(p, flags) SaveAndCli() +#endif +#ifndef _atomic_spin_unlock_irqrestore +#define _atomic_spin_unlock_irqrestore(p, flags) RestoreFlags() +#endif +#ifndef local_irq_save +#define local_irq_save(flags) SaveAndCli() +#endif +#ifndef local_irq_restore +#define local_irq_restore(flags) RestoreFlags() +#endif +#ifndef cris_atomic_save +#define cris_atomic_save(addr, flags) local_irq_save(flags) +#endif +#ifndef cris_atomic_restore +#define cris_atomic_restore(addr, flags) local_irq_restore(flags) +#endif + +/* + * abs() handles unsigned and signed longs, ints, shorts and chars. For all + * input types abs() returns a signed long. + * abs() should not be used for 64-bit types (s64, u64, long long) - use abs64() + * for those. + */ + +#ifndef abs +#define abs(x) ((x >= 0) ? (x) : (x * -1)) +#endif + +#ifndef min +#define min(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef max +#define max(x, y) ((x) > (y) ? (x) : (y)) +#endif +#ifndef min_t +#define min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + (__min1 < __min2) ? (__min1) : (__min2); }) +#endif +#ifndef max_t +#define max_t(type, x, y) ({ \ + type __max1 = (x); \ + type __max2 = (y); \ + (__max1 > __max2) ? (__max1) : (__max2); }) +#endif +#ifndef max_tt +#define max_tt(ret,type,x,y) do{ \ + type __max1 = (x); \ + type __max2 = (y); \ + ret = (__max1 > __max2) ? (__max1) : (__max2); }while(0) +#endif +#ifndef min_tt +#define min_tt(ret,type, x, y) do{ \ + type __min1 = (x); \ + type __min2 = (y); \ + ret = (__min1 < __min2) ? (__min1) : (__min2); }while(0) +#endif + + +/** +* container_of - cast a member of a structure out to the containing structure +* @p(ptr): the pointer to the member. +* @t(type): the type of the container struct this is embedded in. +* @m(member): the name of the member within the struct. +* +*/ +#ifndef container_of + #define container_of(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#endif + + /** + * list_next_entry - get the next element in list + * @pos: the type * to cursor + * @member: the name of the list_struct within the struct. + */ + +#define list_next_entry(pos, member, type) \ + list_entry((pos)->member.next, type, member) + + /** + * list_for_each_entry_continue - continue iteration over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + * + * Continue to iterate over list of given type, continuing after + * the current position. + */ + +#define list_for_each_entry_continue(pos, head, member, type) \ + for (pos = list_next_entry(pos, member, type); \ + &pos->member != (head); \ + pos = list_next_entry(pos, member, type)) + + +/* spin lock */ +#ifndef spin_lock_init + #define spin_lock_init(plock) RtlSpinlockInit((plock)) +#endif +#ifndef spin_lock_free + #define spin_lock_free(plock) RtlSpinlockFree((plock)) +#endif +#ifndef spin_lock + #define spin_lock(plock) RtlSpinlock((plock)) +#endif +#ifndef spin_unlock + #define spin_unlock(plock) RtlSpinunlock((plock)) +#endif + + +/* mutex */ +#ifndef Mutex + #define Mutex _Mutex +#endif +#ifndef mutex_init + #define mutex_init(pmutex) RtlMutexInit((pmutex)) +#endif +#ifndef mutex_lock + #define mutex_lock(pmutex) RtlDownSema((pmutex)) +#endif +#ifndef mutex_unlock + #define mutex_unlock(pmutex) RtlUpSema((pmutex)) +#endif +#ifndef mutex_destory + #define mutex_destory(pmutex) RtlMutexFree((pmutex)) +#endif + +/* semaphore */ +#ifndef Sema + #define Sema _Sema +#endif +#ifndef Sema_Init + #define Sema_Init(pmutex, pval) RtlInitSema(pmutex, pval) +#endif +#ifndef Sema_Free + #define Sema_Free(pmutex) RtlFreeSema(pmutex) +#endif +#ifndef Sema_Up + #define Sema_Up(pmutex) RtlUpSema(pmutex) +#endif +#ifndef Sema_Down + #define Sema_Down(pmutex) RtlDownSema(pmutex) +#endif +#ifndef Sema_Sown_WithTimeout + #define Sema_Down_WithTimeout(pmutex,ptimeout) RtlDownSemaWithTimeout(pmutex,ptimeout) // +#endif + +/* Atomic integer operations */ +#ifndef atomic_set + #define atomic_set(v, i) RTL_ATOMIC_SET((v), (i)) +#endif +#ifndef atomic_read + #define atomic_read(v) RTL_ATOMIC_READ((v)) +#endif +#ifndef atomic_add + #define atomic_add(v, i) RTL_ATOMIC_ADD((v), (i)) +#endif +#ifndef atomic_sub + #define atomic_sub(v, i) RTL_ATOMIC_SUB((v), (i)) +#endif +#ifndef atomic_inc + #define atomic_inc(v) RTL_ATOMIC_INC((v)) +#endif +#ifndef atomic_dec + #define atomic_dec(v) RTL_ATOMIC_DEC((v)) +#endif + + +// IOCTL ... +#ifndef _IOC_NRBITS +#define _IOC_NRBITS (8) +#endif +#ifndef _IOC_TYPEBITS +#define _IOC_TYPEBITS (8) +#endif +#ifndef _IOC_SIZEBITS +#define _IOC_SIZEBITS (14) +#endif +#ifndef _IOC_DIRBITS +#define _IOC_DIRBITS (2) +#endif +#ifndef _IOC_NRMASK +#define _IOC_NRMASK ((1 << _IOC_NRBITS) - 1) +#endif +#ifndef _IOC_TYPEMASK +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS) - 1) +#endif +#ifndef _IOC_SIZEMASK +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS) - 1) +#endif +#ifndef _IOC_DIRMASK +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS) - 1) +#endif +#ifndef _IOC_NRSHIFT +#define _IOC_NRSHIFT (0) +#endif +#ifndef _IOC_TYPESHIFT +#define _IOC_TYPESHIFT (_IOC_NRSHIFT + _IOC_NRBITS) +#endif +#ifndef _IOC_SIZESHIFT +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + _IOC_TYPEBITS) +#endif +#ifndef _IOC_DIRSHIFT +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + _IOC_SIZEBITS) +#endif + +/* + * Direction bits. + */ +#ifndef _IOC_NONE +#define _IOC_NONE (0U) +#endif +#ifndef _IOC_WRITE +#define _IOC_WRITE (1U) +#endif +#ifndef _IOC_READ +#define _IOC_READ (2U) +#endif + + +/* + * combine the four dirAtypeAnrAsize parameters to one cmd parameter + * + */ +#ifndef _IOC +#define _IOC(dir,type,nr,size) \ + (((dir) << _IOC_DIRSHIFT) | \ + ((type) << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) +#endif +/* + * used to create IOCTL cmd + */ +#ifndef _IO +#define _IO(type,nr) _IOC(_IOC_NONE,(type), (nr), 0) +#endif +#ifndef _IOR +#define _IOR(type,nr,size) _IOC(_IOC_READ,(type), (nr), sizeof(size)) +#endif +#ifndef _IOW +#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type), (nr), sizeof(size)) +#endif +#ifndef _IOWR +#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), sizeof(size)) +#endif +/* + * used to decode ioctl infoations.. + */ +#ifndef _IOC_DIR +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) +#endif +#ifndef _IOC_TYPE +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) +#endif +#ifndef _IOC_NR +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) +#endif +#ifndef _IOC_SIZE +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) +#endif +/* ...and for the drivers/sound files... */ +#ifndef IOC_IN +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) +#endif +#ifndef IOC_OUT +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) +#endif +#ifndef IOC_INOUT +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) +#endif +#ifndef IOCSIZE_MASK +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) +#endif +#ifndef IOCSIZE_SHIFT +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT) +#endif + +#ifndef DIV_ROUND_UP +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) +#endif +#ifndef BITS_PER_LONG +#define BITS_PER_LONG (32) +#endif +#ifndef BITS_PER_LONG_LONG +#define BITS_PER_LONG_LONG (32) +#endif +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif +#ifndef BIT_ULL +#define BIT_ULL(nr) (1ULL << (nr)) +#endif +#ifndef BIT_MASK +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#endif +#ifndef BIT_WORD +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) +#endif +#ifndef BIT_ULL_MASK +#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG)) +#endif +#ifndef BIT_ULL_WORD +#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) +#endif +#ifndef BITS_PER_BYTE +#define BITS_PER_BYTE (8) +#endif +#ifndef BITS_TO_LONGS +#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) +#endif + +/* __ffs to find out the first exist 1 offset, from bit 0 ~ 31 */ +#ifndef ffz +#define ffz(x) __ffs(~(x)) +#endif +/* __builtin_constant_p is gcc build-in function to check the parameter is const or not */ +#ifndef small_const_nbits +#define small_const_nbits(nbits) \ + (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG) +#endif +/** + * __ffs - find first bit in word. + * @word: The word to search + * + * Undefined if no bit exists, so code should check against 0 first. + */ +static inline unsigned long __ffs(unsigned long word) +{ + int num = 0; + +#if BITS_PER_LONG == 64 + if ((word & 0xffffffff) == 0) { + num += 32; + word >>= 32; + } +#endif + if ((word & 0xffff) == 0) { + num += 16; + word >>= 16; + } + if ((word & 0xff) == 0) { + num += 8; + word >>= 8; + } + if ((word & 0xf) == 0) { + num += 4; + word >>= 4; + } + if ((word & 0x3) == 0) { + num += 2; + word >>= 2; + } + if ((word & 0x1) == 0) + num += 1; + + return num; +} + +/** + * __fls - find last (most-significant) set bit in a long word + * @word: the word to search + * + * Undefined if no set bit exists, so code should check against 0 first. + */ +static inline unsigned long __fls(unsigned long word) +{ + int num = BITS_PER_LONG - 1; + + #if BITS_PER_LONG == 64 + if (!(word & (~0ul << 32))) { + num -= 32; + word <<= 32; + } + #endif + if (!(word & (~0ul << (BITS_PER_LONG-16)))) { + num -= 16; + word <<= 16; + } + if (!(word & (~0ul << (BITS_PER_LONG-8)))) { + num -= 8; + word <<= 8; + } + if (!(word & (~0ul << (BITS_PER_LONG-4)))) { + num -= 4; + word <<= 4; + } + if (!(word & (~0ul << (BITS_PER_LONG-2)))) { + num -= 2; + word <<= 2; + } + if (!(word & (~0ul << (BITS_PER_LONG-1)))) + num -= 1; + return num; +} + +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static inline int test_bit(int nr, const volatile unsigned long *addr) +{ + return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; +} + + + +/* +* Find the first cleared bit in a memory region. +*/ +static inline unsigned long find_first_zero_bit( + const unsigned long *addr, unsigned long size) +{ + const unsigned long *p = addr; + unsigned long result = 0; + unsigned long tmp; + + while (size & ~(BITS_PER_LONG-1)) { + if (~(tmp = *(p++))) + goto found; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; + } + if (!size) + return result; + + tmp = (*p) | (~0UL << size); + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. */ +found: + + return result + ffz(tmp); + //tmp = 0; + //return result; + +} + +static inline unsigned long find_next_zero_bit( + const unsigned long *addr,unsigned long size, unsigned long offset) +{ + const unsigned long *p = addr + BIT_WORD(offset); // offset_pVlonga}32? + unsigned long result = offset & ~(BITS_PER_LONG-1); // offsetOresult?4r? + unsigned long tmp; + + if (offset >= size) + return size; + size -= result; // ?32㭿?W + offset %= BITS_PER_LONG; // offset_32쪺ĤL + if (offset) { // offsetb@?long?u0W,b1-31줤[luther.gliethttp] + tmp = *(p++); + tmp |= ~0UL >> (BITS_PER_LONG - offset); // ?0-offset?uRW1. + if (size < BITS_PER_LONG) // 32bits + goto found_first; + if (~tmp) // DD0?t0 + goto found_middle; + size -= BITS_PER_LONG; // pGW~tmp_0,\??*p?u?321.[luther.gliethttp] + result += BITS_PER_LONG; + } + while (size & ~(BITS_PER_LONG-1)) { // nF,??,?offsetw??b4r?0W,U? + if (~(tmp = *(p++))) // 4r?ֳtd?.pG~tmpD0,??32?ut0?u,.[luther.gliethttp] + goto found_middle; + result += BITS_PER_LONG; // U@?4r?? + size -= BITS_PER_LONG; // ?4r??u + } + if (!size) // size_0,?size_4r?㭿?,䦸Ҧ?uw?d, + return result; // Ҧ?u?1,???0,result_size.[luther.gliethttp] + tmp = *p; // sizeO32㭿?,?ѤL?bit??d,???U?du@.[luther.gliethtp] + +found_first: + tmp |= ~0UL << size; // ?b0-size??u,size-31?ϥΪ?,ҥH?size-31m1. + if (tmp == ~0UL) /* Are any bits zero? */ // pGtmp1,\?N?1? + return result + size; /* Nope. */ // result+sizeN_??J??sizejp.[luther.gliethttp] +found_middle: + return result + ffz(tmp); // ?b32?u0-31??wsb0,?LOĤL.[luther.gliethttp] +} + +//int find_next_zero_bit(const void * p, int size, int offset); +//int find_first_bit(const unsigned long *p, unsigned size); +//int find_next_bit(const unsigned long *p, int size, int offset); +/** +* set_bit - Atomically set a bit in memory +* @nr: the bit to set +* @addr: the address to start counting from +* +* This function is atomic and may not be reordered. See __set_bit() +* if you do not require the atomic guarantees. +* +* Note: there are no guarantees that this function will not be reordered +* on non x86 architectures, so if you are writing portable code, +* make sure not to rely on its reordering guarantees. +* +* Note that @nr may be almost arbitrarily large; this function is not +* restricted to acting on a single-word quantity. +*/ +static inline void set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long flags; + + //taskENTER_CRITICAL(); + _atomic_spin_lock_irqsave(p, flags); + *p |= mask; + _atomic_spin_unlock_irqrestore(p, flags); + //taskEXIT_CRITICAL(); +} + +/** +* clear_bit - Clears a bit in memory +* @nr: Bit to clear +* @addr: Address to start counting from +* +* clear_bit() is atomic and may not be reordered. However, it does +* not contain a memory barrier, so if it is used for locking purposes, +* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() +* in order to ensure changes are visible on other processors. +*/ +static inline void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long flags; + + _atomic_spin_lock_irqsave(p, flags); + //taskENTER_CRITICAL(); + *p &= ~mask; + _atomic_spin_unlock_irqrestore(p, flags); + //taskEXIT_CRITICAL(); +} + +/** +* change_bit - Toggle a bit in memory +* @nr: Bit to change +* @addr: Address to start counting from +* +* change_bit() is atomic and may not be reordered. It may be +* reordered on other architectures than x86. +* Note that @nr may be almost arbitrarily large; this function is not +* restricted to acting on a single-word quantity. +*/ +static inline void change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long flags; + + //taskENTER_CRITICAL(); + _atomic_spin_lock_irqsave(p, flags); + *p ^= mask; + _atomic_spin_unlock_irqrestore(p, flags); + //taskEXIT_CRITICAL(); +} + +/** +* test_and_set_bit - Set a bit and return its old value +* @nr: Bit to set +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It may be reordered on other architectures than x86. +* It also implies a memory barrier. +*/ +static inline int test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + //unsigned long flags; + + //taskENTER_CRITICAL(); + + _atomic_spin_lock_irqsave(p, flags); + old = *p; + *p = old | mask; + _atomic_spin_unlock_irqrestore(p, flags); + //taskEXIT_CRITICAL(); + + return (old & mask) != 0; +} + +/** +* test_and_clear_bit - Clear a bit and return its old value +* @nr: Bit to clear +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It can be reorderdered on other architectures other than x86. +* It also implies a memory barrier. +*/ +static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + unsigned long flags; + + //taskENTER_CRITICAL(); + _atomic_spin_lock_irqsave(p, flags); + old = *p; + *p = old & ~mask; + _atomic_spin_unlock_irqrestore(p, flags); + //taskEXIT_CRITICAL(); + + return (old & mask) != 0; +} +/** +* test_and_change_bit - Change a bit and return its old value +* @nr: Bit to change +* @addr: Address to count from +* +* This operation is atomic and cannot be reordered. +* It also implies a memory barrier. +*/ +static inline int test_and_change_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old; + unsigned long flags; + + + _atomic_spin_lock_irqsave(p, flags); + old = *p; + *p = old ^ mask; + _atomic_spin_unlock_irqrestore(p, flags); + + + return (old & mask) != 0; +} + + +static inline int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ + int k; + int nr = BITS_TO_LONGS(bits); + unsigned long result = 0; + + for (k = 0; k < nr; k++) + result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); + return result != 0; +} + +static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, int nbits) +{ +// if (small_const_nbits(nbits)) +// return (*dst = *src1 & ~(*src2)) != 0; + return __bitmap_andnot(dst, src1, src2, nbits); +} + +static inline int atomic_inc_return(volatile atomic_t *v) +{ + unsigned long flags; + int retval; + cris_atomic_save(v, flags); + retval = ++(v->counter); + cris_atomic_restore(v, flags); + return retval; +} + +typedef __u16 __le16; +typedef __u16 __be16; +typedef __u32 __le32; +typedef __u32 __be32; +typedef __u64 __le64; +typedef __u64 __be64; +typedef __u16 __sum16; +typedef __u32 __wsum; + +#ifndef __GFP_WAIT +#define __GFP_WAIT (0x10u) +#endif +#ifndef __GFP_HIGH +#define __GFP_HIGH (0x20u) +#endif +#ifndef __GFP_IO +#define __GFP_IO (0x40u) +#endif +#ifndef __GFP_FS +#define __GFP_FS (0x80u) +#endif +#ifndef GFP_NOIO +#define GFP_NOIO (0x10u) +#endif +#ifndef __GFP_NOWARN +#define __GFP_NOWARN (0x200u) +#endif +#ifndef GFP_KERNEL +#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) +#endif + +#ifndef copy_from_user +#define copy_from_user(to, from, sz) _memcpy((to), (from), (sz)) +#endif +#ifndef copy_to_user +#define copy_to_user(to, from, sz) _memcpy((to), (from), (sz)) +#endif + +#if 0 /*comment since we are not using polling*/ +/* These are specified by iBCS2 */ +#ifndef POLLIN +#define POLLIN 0x0001 +#endif +#ifndef POLLPRI +#define POLLPRI 0x0002 +#endif +#ifndef POLLOUT +#define POLLOUT 0x0004 +#endif +#ifndef POLLERR +#define POLLERR 0x0008 +#endif +#ifndef POLLHUP +#define POLLHUP 0x0010 +#endif +#ifndef POLLNVAL +#define POLLNVAL 0x0020 +#endif +/* The rest seem to be more-or-less nonstandard. Check them! */ +#ifndef POLLRDNORM +#define POLLRDNORM 0x0040 +#endif +#ifndef POLLRDBAND +#define POLLRDBAND 0x0080 +#endif +#ifndef POLLWRNORM +#define POLLWRNORM 0x0100 +#endif +#ifndef POLLWRBAND +#define POLLWRBAND 0x0200 +#endif +#ifndef POLLMSG +#define POLLMSG 0x0400 +#endif +#ifndef POLLREMOVE +#define POLLREMOVE 0x1000 +#endif +#ifndef POLLRDHUP +#define POLLRDHUP 0x2000 +#endif +#ifndef POLLFREE +#define POLLFREE 0x4000 /* currently only for epoll */ +#endif +#ifndef POLL_BUSY_LOOP +#define POLL_BUSY_LOOP 0x8000 +#endif +#endif + +struct __wait_queue_head { + _Sema lock; + struct list_head task_list; +}; + +typedef struct __wait_queue_head wait_queue_head_t; + +static inline void __init_waitqueue_head(wait_queue_head_t *q) +{ + //spin_lock_init(&q->lock); + RtlInitSema(&q->lock,0); + INIT_LIST_HEAD(&q->task_list); +} +#ifndef init_waitqueue_head +#define init_waitqueue_head(q) \ +do { \ + __init_waitqueue_head((q)); \ +} while (0) +#endif +#ifndef DEFAULT_POLLMASK +#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) +#endif + +#endif /*_V4L2_OSDEP_H_*/ \ No newline at end of file diff --git a/USDK/component/common/video/v4l2/inc/v4l2-subdev.h b/USDK/component/common/video/v4l2/inc/v4l2-subdev.h new file mode 100644 index 0000000..7f4ac2f --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2-subdev.h @@ -0,0 +1,700 @@ +/* + V4L2 sub-device support header. + + Copyright (C) 2008 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L2_SUBDEV_H +#define _V4L2_SUBDEV_H + +#if 0 +#include +#endif + +#include "v4l2-subdev.h" +#include "media-entity.h" +#include "v4l2-async.h" +#include "v4l2-common.h" +#include "v4l2-dev.h" +#include "v4l2-fh.h" +#include "v4l2-mediabus.h" + + +/* generic v4l2_device notify callback notification values */ +#define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) +#define V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ 0x00000001 +#define V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED 0x00000002 +#define V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN 0x00000004 +#define V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN 0x00000008 + +#define V4L2_SUBDEV_IR_TX_NOTIFY _IOW('v', 1, u32) +#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ 0x00000001 + +struct v4l2_device; +struct v4l2_ctrl_handler; +struct v4l2_event_subscription; +struct v4l2_fh; +struct v4l2_subdev; +struct v4l2_subdev_fh; +//struct tuner_setup; +struct v4l2_mbus_frame_desc; + +/* decode_vbi_line */ +struct v4l2_decode_vbi_line { + u32 is_second_field; /* Set to 0 for the first (odd) field, + set to 1 for the second (even) field. */ + u8 *p; /* Pointer to the sliced VBI data from the decoder. + On exit points to the start of the payload. */ + u32 line; /* Line number of the sliced VBI data (1-23) */ + u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */ +}; + +/* Sub-devices are devices that are connected somehow to the main bridge + device. These devices are usually audio/video muxers/encoders/decoders or + sensors and webcam controllers. + + Usually these devices are controlled through an i2c bus, but other busses + may also be used. + + The v4l2_subdev struct provides a way of accessing these devices in a + generic manner. Most operations that these sub-devices support fall in + a few categories: core ops, audio ops, video ops and tuner ops. + + More categories can be added if needed, although this should remain a + limited set (no more than approx. 8 categories). + + Each category has its own set of ops that subdev drivers can implement. + + A subdev driver can leave the pointer to the category ops NULL if + it does not implement them (e.g. an audio subdev will generally not + implement the video category ops). The exception is the core category: + this must always be present. + + These ops are all used internally so it is no problem to change, remove + or add ops or move ops from one to another category. Currently these + ops are based on the original ioctls, but since ops are not limited to + one argument there is room for improvement here once all i2c subdev + drivers are converted to use these ops. + */ + +/* Core ops: it is highly recommended to implement at least these ops: + + log_status + g_register + s_register + + This provides basic debugging support. + + The ioctl ops is meant for generic ioctl-like commands. Depending on + the use-case it might be better to use subdev-specific ops (currently + not yet implemented) since ops provide proper type-checking. + */ + +/* Subdevice external IO pin configuration */ +#define V4L2_SUBDEV_IO_PIN_DISABLE (1 << 0) /* ENABLE assumed */ +#define V4L2_SUBDEV_IO_PIN_OUTPUT (1 << 1) +#define V4L2_SUBDEV_IO_PIN_INPUT (1 << 2) +#define V4L2_SUBDEV_IO_PIN_SET_VALUE (1 << 3) /* Set output value */ +#define V4L2_SUBDEV_IO_PIN_ACTIVE_LOW (1 << 4) /* ACTIVE HIGH assumed */ + +struct v4l2_subdev_io_pin_config { + u32 flags; /* V4L2_SUBDEV_IO_PIN_* flags for this pin's config */ + u8 pin; /* Chip external IO pin to configure */ + u8 function; /* Internal signal pad/function to route to IO pin */ + u8 value; /* Initial value for pin - e.g. GPIO output value */ + u8 strength; /* Pin drive strength */ +}; + +/* + s_io_pin_config: configure one or more chip I/O pins for chips that + multiplex different internal signal pads out to IO pins. This function + takes a pointer to an array of 'n' pin configuration entries, one for + each pin being configured. This function could be called at times + other than just subdevice initialization. + + init: initialize the sensor registers to some sort of reasonable default + values. Do not use for new drivers and should be removed in existing + drivers. + + load_fw: load firmware. + + reset: generic reset command. The argument selects which subsystems to + reset. Passing 0 will always reset the whole chip. Do not use for new + drivers without discussing this first on the linux-media mailinglist. + There should be no reason normally to reset a device. + + s_gpio: set GPIO pins. Very simple right now, might need to be extended with + a direction argument if needed. + + s_power: puts subdevice in power saving mode (on == 0) or normal operation + mode (on == 1). + + interrupt_service_routine: Called by the bridge chip's interrupt service + handler, when an interrupt status has be raised due to this subdev, + so that this subdev can handle the details. It may schedule work to be + performed later. It must not sleep. *Called from an IRQ context*. + */ +struct v4l2_subdev_core_ops { + int (*log_status)(struct v4l2_subdev *sd); + int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n, + struct v4l2_subdev_io_pin_config *pincfg); + int (*init)(struct v4l2_subdev *sd, u32 val); + int (*load_fw)(struct v4l2_subdev *sd); + int (*reset)(struct v4l2_subdev *sd, u32 val); + int (*s_gpio)(struct v4l2_subdev *sd, u32 val); + int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc); + int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); + int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); + int (*g_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); + int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); + int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls); + int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); + int (*g_std)(struct v4l2_subdev *sd, v4l2_std_id *norm); + int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm); + long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); +#ifdef CONFIG_VIDEO_ADV_DEBUG + int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); + int (*s_register)(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg); +#endif + int (*s_power)(struct v4l2_subdev *sd, int on); + int (*interrupt_service_routine)(struct v4l2_subdev *sd, + u32 status, bool *handled); + int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub); + int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, + struct v4l2_event_subscription *sub); +}; + +/* s_radio: v4l device was opened in radio mode. + + g_frequency: freq->type must be filled in. Normally done by video_ioctl2 + or the bridge driver. + + g_tuner: + s_tuner: vt->type must be filled in. Normally done by video_ioctl2 or the + bridge driver. + + s_type_addr: sets tuner type and its I2C addr. + + s_config: sets tda9887 specific stuff, like port1, port2 and qss + */ +struct v4l2_subdev_tuner_ops { + int (*s_radio)(struct v4l2_subdev *sd); + int (*s_frequency)(struct v4l2_subdev *sd, const struct v4l2_frequency *freq); + int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); + int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt); + int (*s_tuner)(struct v4l2_subdev *sd, const struct v4l2_tuner *vt); + int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm); + int (*s_modulator)(struct v4l2_subdev *sd, const struct v4l2_modulator *vm); + //edit by Ian + //int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type); + //int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config); +}; + +/* s_clock_freq: set the frequency (in Hz) of the audio clock output. + Used to slave an audio processor to the video decoder, ensuring that + audio and video remain synchronized. Usual values for the frequency + are 48000, 44100 or 32000 Hz. If the frequency is not supported, then + -EINVAL is returned. + + s_i2s_clock_freq: sets I2S speed in bps. This is used to provide a standard + way to select I2S clock used by driving digital audio streams at some + board designs. Usual values for the frequency are 1024000 and 2048000. + If the frequency is not supported, then -EINVAL is returned. + + s_routing: used to define the input and/or output pins of an audio chip, + and any additional configuration data. + Never attempt to use user-level input IDs (e.g. Composite, S-Video, + Tuner) at this level. An i2c device shouldn't know about whether an + input pin is connected to a Composite connector, become on another + board or platform it might be connected to something else entirely. + The calling driver is responsible for mapping a user-level input to + the right pins on the i2c device. + */ +struct v4l2_subdev_audio_ops { + int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq); + int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq); + int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); + int (*s_stream)(struct v4l2_subdev *sd, int enable); +}; + +/* Indicates the @length field specifies maximum data length. */ +#define V4L2_MBUS_FRAME_DESC_FL_LEN_MAX (1U << 0) +/* Indicates user defined data format, i.e. non standard frame format. */ +#define V4L2_MBUS_FRAME_DESC_FL_BLOB (1U << 1) + +/** + * struct v4l2_mbus_frame_desc_entry - media bus frame description structure + * @flags: V4L2_MBUS_FRAME_DESC_FL_* flags + * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set + * @length: number of octets per frame, valid for compressed or unspecified + * formats + */ +struct v4l2_mbus_frame_desc_entry { + u16 flags; + u32 pixelcode; + u32 length; +}; + +#define V4L2_FRAME_DESC_ENTRY_MAX 4 + +/** + * struct v4l2_mbus_frame_desc - media bus data frame description + * @entry: frame descriptors array + * @num_entries: number of entries in @entry array + */ +struct v4l2_mbus_frame_desc { + struct v4l2_mbus_frame_desc_entry entry[V4L2_FRAME_DESC_ENTRY_MAX]; + unsigned short num_entries; +}; + +/* + s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by + video input devices. + + g_std_output: get current standard for video OUTPUT devices. This is ignored + by video input devices. + + g_tvnorms_output: get v4l2_std_id with all standards supported by video + OUTPUT device. This is ignored by video input devices. + + s_crystal_freq: sets the frequency of the crystal used to generate the + clocks in Hz. An extra flags field allows device specific configuration + regarding clock frequency dividers, etc. If not used, then set flags + to 0. If the frequency is not supported, then -EINVAL is returned. + + g_input_status: get input status. Same as the status field in the v4l2_input + struct. + + s_routing: see s_routing in audio_ops, except this version is for video + devices. + + s_dv_timings(): Set custom dv timings in the sub device. This is used + when sub device is capable of setting detailed timing information + in the hardware to generate/detect the video signal. + + g_dv_timings(): Get custom dv timings in the sub device. + + enum_mbus_fmt: enumerate pixel formats, provided by a video data source + + g_mbus_fmt: get the current pixel format, provided by a video data source + + try_mbus_fmt: try to set a pixel format on a video data source + + s_mbus_fmt: set a pixel format on a video data source + + g_mbus_config: get supported mediabus configurations + + s_mbus_config: set a certain mediabus configuration. This operation is added + for compatibility with soc-camera drivers and should not be used by new + software. + + s_rx_buffer: set a host allocated memory buffer for the subdev. The subdev + can adjust @size to a lower value and must not write more data to the + buffer starting at @data than the original value of @size. + */ +struct v4l2_subdev_video_ops { + int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); + int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); + int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); + int (*g_std_output)(struct v4l2_subdev *sd, v4l2_std_id *std); + int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); + int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); + int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); + int (*s_stream)(struct v4l2_subdev *sd, int enable); + int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); + int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); + int (*s_crop)(struct v4l2_subdev *sd, const struct v4l2_crop *crop); + int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); + int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); +// edit by Ian +#if 0 + int (*g_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval); + int (*s_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval); +#endif + int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); + int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); + int (*s_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*g_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*enum_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_enum_dv_timings *timings); + int (*query_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*dv_timings_cap)(struct v4l2_subdev *sd, + struct v4l2_dv_timings_cap *cap); +#if 0 + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code); + int (*enum_mbus_fsizes)(struct v4l2_subdev *sd, + struct v4l2_frmsizeenum *fsize); + int (*g_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*try_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*s_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*g_mbus_config)(struct v4l2_subdev *sd, + struct v4l2_mbus_config *cfg); + int (*s_mbus_config)(struct v4l2_subdev *sd, + const struct v4l2_mbus_config *cfg); +#endif + int (*s_rx_buffer)(struct v4l2_subdev *sd, void *buf, + unsigned int *size); +}; + +/* + decode_vbi_line: video decoders that support sliced VBI need to implement + this ioctl. Field p of the v4l2_sliced_vbi_line struct is set to the + start of the VBI data that was generated by the decoder. The driver + then parses the sliced VBI data and sets the other fields in the + struct accordingly. The pointer p is updated to point to the start of + the payload which can be copied verbatim into the data field of the + v4l2_sliced_vbi_data struct. If no valid VBI data was found, then the + type field is set to 0 on return. + + s_vbi_data: used to generate VBI signals on a video signal. + v4l2_sliced_vbi_data is filled with the data packets that should be + output. Note that if you set the line field to 0, then that VBI signal + is disabled. If no valid VBI data was found, then the type field is + set to 0 on return. + + g_vbi_data: used to obtain the sliced VBI packet from a readback register. + Not all video decoders support this. If no data is available because + the readback register contains invalid or erroneous data -EIO is + returned. Note that you must fill in the 'id' member and the 'field' + member (to determine whether CC data from the first or second field + should be obtained). + + s_raw_fmt: setup the video encoder/decoder for raw VBI. + + g_sliced_fmt: retrieve the current sliced VBI settings. + + s_sliced_fmt: setup the sliced VBI settings. + */ +struct v4l2_subdev_vbi_ops { + int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line); + int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data); + int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data); + int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap); + int (*s_raw_fmt)(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt); + int (*g_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt); + int (*s_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt); +}; + +/** + * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations + * @g_skip_top_lines: number of lines at the top of the image to be skipped. + * This is needed for some sensors, which always corrupt + * several top lines of the output image, or which send their + * metadata in them. + * @g_skip_frames: number of frames to skip at stream start. This is needed for + * buggy sensors that generate faulty frames when they are + * turned on. + */ +struct v4l2_subdev_sensor_ops { + int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); + int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames); +}; + +/* + [rt]x_g_parameters: Get the current operating parameters and state of the + the IR receiver or transmitter. + + [rt]x_s_parameters: Set the current operating parameters and state of the + the IR receiver or transmitter. It is recommended to call + [rt]x_g_parameters first to fill out the current state, and only change + the fields that need to be changed. Upon return, the actual device + operating parameters and state will be returned. Note that hardware + limitations may prevent the actual settings from matching the requested + settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz + was requested. An exception is when the shutdown parameter is true. + The last used operational parameters will be returned, but the actual + state of the hardware be different to minimize power consumption and + processing when shutdown is true. + + rx_read: Reads received codes or pulse width data. + The semantics are similar to a non-blocking read() call. + + tx_write: Writes codes or pulse width data for transmission. + The semantics are similar to a non-blocking write() call. + */ + +enum v4l2_subdev_ir_mode { + V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* uses struct ir_raw_event records */ +}; + +struct v4l2_subdev_ir_parameters { + /* Either Rx or Tx */ + unsigned int bytes_per_data_element; /* of data in read or write call */ + enum v4l2_subdev_ir_mode mode; + + bool enable; + bool interrupt_enable; + bool shutdown; /* true: set hardware to low/no power, false: normal */ + + bool modulation; /* true: uses carrier, false: baseband */ + u32 max_pulse_width; /* ns, valid only for baseband signal */ + unsigned int carrier_freq; /* Hz, valid only for modulated signal*/ + unsigned int duty_cycle; /* percent, valid only for modulated signal*/ + bool invert_level; /* invert signal level */ + + /* Tx only */ + bool invert_carrier_sense; /* Send 0/space as a carrier burst */ + + /* Rx only */ + u32 noise_filter_min_width; /* ns, min time of a valid pulse */ + unsigned int carrier_range_lower; /* Hz, valid only for modulated sig */ + unsigned int carrier_range_upper; /* Hz, valid only for modulated sig */ + u32 resolution; /* ns */ +}; + +struct v4l2_subdev_ir_ops { + /* Receiver */ + int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num); + + int (*rx_g_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + int (*rx_s_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + + /* Transmitter */ + int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num); + + int (*tx_g_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + int (*tx_s_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); +}; + +/** + * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations + * @get_frame_desc: get the current low level media bus frame parameters. + * @get_frame_desc: set the low level media bus frame parameters, @fd array + * may be adjusted by the subdev driver to device capabilities. + */ +struct v4l2_subdev_pad_ops { + +#if 0 + int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_mbus_code_enum *code); + int (*enum_frame_size)(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_frame_size_enum *fse); + int (*enum_frame_interval)(struct v4l2_subdev *sd, + struct v4l2_subdev_fh *fh, + struct v4l2_subdev_frame_interval_enum *fie); + int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *format); + int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_format *format); + int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_crop *crop); + int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_crop *crop); + int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_selection *sel); + int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, + struct v4l2_subdev_selection *sel); + int (*get_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid); + int (*set_edid)(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid); +#ifdef CONFIG_MEDIA_CONTROLLER + int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt); +#endif /* CONFIG_MEDIA_CONTROLLER */ +#endif + int (*get_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd); + int (*set_frame_desc)(struct v4l2_subdev *sd, unsigned int pad, + struct v4l2_mbus_frame_desc *fd); +}; + +struct v4l2_subdev_ops { + const struct v4l2_subdev_core_ops *core; + const struct v4l2_subdev_tuner_ops *tuner; + const struct v4l2_subdev_audio_ops *audio; + const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_vbi_ops *vbi; + const struct v4l2_subdev_ir_ops *ir; + const struct v4l2_subdev_sensor_ops *sensor; + const struct v4l2_subdev_pad_ops *pad; +}; + +/* + * Internal ops. Never call this from drivers, only the v4l2 framework can call + * these ops. + * + * registered: called when this subdev is registered. When called the v4l2_dev + * field is set to the correct v4l2_device. + * + * unregistered: called when this subdev is unregistered. When called the + * v4l2_dev field is still set to the correct v4l2_device. + * + * open: called when the subdev device node is opened by an application. + * + * close: called when the subdev device node is closed. + */ +struct v4l2_subdev_internal_ops { + int (*registered)(struct v4l2_subdev *sd); + void (*unregistered)(struct v4l2_subdev *sd); + int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); + int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh); +}; + +#define V4L2_SUBDEV_NAME_SIZE 32 + +/* Set this flag if this subdev is a i2c device. */ +#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) +/* Set this flag if this subdev is a spi device. */ +#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) +/* Set this flag if this subdev needs a device node. */ +#define V4L2_SUBDEV_FL_HAS_DEVNODE (1U << 2) +/* Set this flag if this subdev generates events. */ +#define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3) + +/* Each instance of a subdev driver should create this struct, either + stand-alone or embedded in a larger struct. + */ +struct v4l2_subdev { +#if defined(CONFIG_MEDIA_CONTROLLER) + struct media_entity entity; +#endif + struct list_head list; + //struct module *owner; + u32 flags; + struct v4l2_device *v4l2_dev; + const struct v4l2_subdev_ops *ops; + /* Never call these internal ops from within a sub_dev driver! */ + const struct v4l2_subdev_internal_ops *internal_ops; + /* The control handler of this subdev. May be NULL. */ + struct v4l2_ctrl_handler *ctrl_handler; + /* name must be unique */ + char name[V4L2_SUBDEV_NAME_SIZE]; + /* can be used to group similar subdevs, value is driver-specific */ + u32 grp_id; + /* pointer to private data */ + void *dev_priv; + void *host_priv; + /* subdev device node */ + struct video_device *devnode; + /* pointer to the physical device, if any */ + //struct device *dev; + const char *dev_init_name; /* initial name of the device */ + void *dev_prive_date; + + /* Links this subdev to a global subdev_list or @notifier->done list. */ + struct list_head async_list; + /* Pointer to respective struct v4l2_async_subdev. */ + struct v4l2_async_subdev *asd; + /* Pointer to the managing notifier. */ + struct v4l2_async_notifier *notifier; +}; + +#define media_entity_to_v4l2_subdev(ent) \ + container_of(ent, struct v4l2_subdev, entity) +#define vdev_to_v4l2_subdev(vdev) \ + ((struct v4l2_subdev *)video_get_drvdata(vdev)) + +/* + * Used for storing subdev information per file handle + */ +struct v4l2_subdev_fh { + struct v4l2_fh vfh; +#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) + struct { + struct v4l2_mbus_framefmt try_fmt; + struct v4l2_rect try_crop; + struct v4l2_rect try_compose; + } *pad; +#endif +}; + +#define to_v4l2_subdev_fh(fh) \ + container_of(fh, struct v4l2_subdev_fh, vfh) + +#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) +#define __V4L2_SUBDEV_MK_GET_TRY(rtype, fun_name, field_name) \ + static inline struct rtype * \ + v4l2_subdev_get_try_##fun_name(struct v4l2_subdev_fh *fh, \ + unsigned int pad) \ + { \ + BUG_ON(unlikely(pad >= vdev_to_v4l2_subdev( \ + fh->vfh.vdev)->entity.num_pads)); \ + return &fh->pad[pad].field_name; \ + } + +__V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, format, try_fmt) +__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, crop, try_compose) +__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, compose, try_compose) +#endif + +extern const struct v4l2_file_operations v4l2_subdev_fops; + +static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) +{ + sd->dev_priv = p; +} + +static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) +{ + return sd->dev_priv; +} + +static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) +{ + sd->host_priv = p; +} + +static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd) +{ + return sd->host_priv; +} + +#ifdef CONFIG_MEDIA_CONTROLLER +int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt); +int v4l2_subdev_link_validate(struct media_link *link); +#endif /* CONFIG_MEDIA_CONTROLLER */ +void v4l2_subdev_init(struct v4l2_subdev *sd, + const struct v4l2_subdev_ops *ops); + +/* Call an ops of a v4l2_subdev, doing the right checks against + NULL pointers. + + Example: err = v4l2_subdev_call(sd, core, s_std, norm); + */ +#define v4l2_subdev_call(sd, o, f, args...) \ + (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \ + (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) + +/* Send a notification to v4l2_device. */ +#define v4l2_subdev_notify(sd, notification, arg) \ + ((!(sd) || !(sd)->v4l2_dev || !(sd)->v4l2_dev->notify) ? -ENODEV : \ + (sd)->v4l2_dev->notify((sd), (notification), (arg))) + +#define v4l2_subdev_has_op(sd, o, f) \ + ((sd)->ops->o && (sd)->ops->o->f) + +#endif diff --git a/USDK/component/common/video/v4l2/inc/v4l2_driver.h b/USDK/component/common/video/v4l2/inc/v4l2_driver.h new file mode 100644 index 0000000..dbe5a4c --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2_driver.h @@ -0,0 +1,9 @@ + +#ifndef V4L2_DRIVER_H +#define V4L2_DRIVER_H /*structure needed for video caputure*/ + +#include +#include "dlist.h" +#include "basic_types.h" + +#endif //V4L2_DRIVER_H \ No newline at end of file diff --git a/USDK/component/common/video/v4l2/inc/v4l2_intf.h b/USDK/component/common/video/v4l2/inc/v4l2_intf.h new file mode 100644 index 0000000..1d770ca --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/v4l2_intf.h @@ -0,0 +1,24 @@ +#ifndef _V4L2_INTF_H_ +#define _V4L2_INTF_H_ + +#define VIDEO_NUM_DEVICES 4//should be aligned with value in v4l2-dev.c + +typedef enum _streaming_state streaming_state; +enum _streaming_state { + STREAMING_OFF = 0, + STREAMING_ON = 1, + STREAMING_PAUSED = 2, + STREAMING_READY = 3, +}; + +long v4l_usr_ioctl(int fd, unsigned int cmd, void *arg); +int v4l_dev_open(); +void v4l_dev_release(); +void stop_capturing(); +int start_capturing(); +void uninit_v4l2_device (); +int init_v4l2_device (); +int v4l_set_param(u32 format_type, int *width, int *height, int *frame_rate, int *compression_ratio); +int v4l_getset_usb_ctrl(u8 bRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, void *data, int timeout, int set); +extern void spec_v4l2_probe(); +#endif diff --git a/USDK/component/common/video/v4l2/inc/videobuf2-core.h b/USDK/component/common/video/v4l2/inc/videobuf2-core.h new file mode 100644 index 0000000..c1db3d7 --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/videobuf2-core.h @@ -0,0 +1,522 @@ +/* + * videobuf2-core.h - V4L2 driver helper framework + * + * Copyright (C) 2010 Samsung Electronics + * + * Author: Pawel Osciak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ +#ifndef _MEDIA_VIDEOBUF2_CORE_H +#define _MEDIA_VIDEOBUF2_CORE_H +#if 0 +#include +#include +#include +#include +#include +#endif +#include "v4l2-osdep.h" +#include "videodev2.h" + + +typedef int _LOCK_T; +struct vb2_alloc_ctx; +struct vb2_fileio_data; + +/** + * struct vb2_mem_ops - memory handling/memory allocator operations + * @alloc: allocate video memory and, optionally, allocator private data, + * return NULL on failure or a pointer to allocator private, + * per-buffer data on success; the returned private structure + * will then be passed as buf_priv argument to other ops in this + * structure. Additional gfp_flags to use when allocating the + * are also passed to this operation. These flags are from the + * gfp_flags field of vb2_queue. + * @put: inform the allocator that the buffer will no longer be used; + * usually will result in the allocator freeing the buffer (if + * no other users of this buffer are present); the buf_priv + * argument is the allocator private per-buffer structure + * previously returned from the alloc callback + * @get_userptr: acquire userspace memory for a hardware operation; used for + * USERPTR memory types; vaddr is the address passed to the + * videobuf layer when queuing a video buffer of USERPTR type; + * should return an allocator private per-buffer structure + * associated with the buffer on success, NULL on failure; + * the returned private structure will then be passed as buf_priv + * argument to other ops in this structure + * @put_userptr: inform the allocator that a USERPTR buffer will no longer + * be used + * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation; + * used for DMABUF memory types; alloc_ctx is the alloc context + * dbuf is the shared dma_buf; returns NULL on failure; + * allocator private per-buffer structure on success; + * this needs to be used for further accesses to the buffer + * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF + * buffer is no longer used; the buf_priv argument is the + * allocator private per-buffer structure previously returned + * from the attach_dmabuf callback + * @map_dmabuf: request for access to the dmabuf from allocator; the allocator + * of dmabuf is informed that this driver is going to use the + * dmabuf + * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified + * that this driver is done using the dmabuf for now + * @prepare: called every time the buffer is passed from userspace to the + * driver, useful for cache synchronisation, optional + * @finish: called every time the buffer is passed back from the driver + * to the userspace, also optional + * @vaddr: return a kernel virtual address to a given memory buffer + * associated with the passed private structure or NULL if no + * such mapping exists + * @cookie: return allocator specific cookie for a given memory buffer + * associated with the passed private structure or NULL if not + * available + * @num_users: return the current number of users of a memory buffer; + * return 1 if the videobuf layer (or actually the driver using + * it) is the only user + * @mmap: setup a userspace mapping for a given memory buffer under + * the provided virtual memory region + * + * Required ops for USERPTR types: get_userptr, put_userptr. + * Required ops for MMAP types: alloc, put, num_users, mmap. + * Required ops for read/write access types: alloc, put, num_users, vaddr + * Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf, + * unmap_dmabuf. + */ +struct vb2_mem_ops { + void *(*alloc)(void *alloc_ctx, unsigned long size, gfp_t gfp_flags); + void (*put)(void *buf_priv); + struct dma_buf *(*get_dmabuf)(void *buf_priv); + + void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr, + unsigned long size, int write); + void (*put_userptr)(void *buf_priv); + + void (*prepare)(void *buf_priv); + void (*finish)(void *buf_priv); + + void *(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf, + unsigned long size, int write); + void (*detach_dmabuf)(void *buf_priv); + int (*map_dmabuf)(void *buf_priv); + void (*unmap_dmabuf)(void *buf_priv); + + void *(*vaddr)(void *buf_priv); + void *(*cookie)(void *buf_priv); + + unsigned int (*num_users)(void *buf_priv); + + int (*mmap)(void *buf_priv); +}; + +struct vb2_plane { + void *mem_priv; + struct dma_buf *dbuf; + unsigned int dbuf_mapped; +}; + +/** + * enum vb2_io_modes - queue access methods + * @VB2_MMAP: driver supports MMAP with streaming API + * @VB2_USERPTR: driver supports USERPTR with streaming API + * @VB2_READ: driver supports read() style access + * @VB2_WRITE: driver supports write() style access + * @VB2_DMABUF: driver supports DMABUF with streaming API + */ +enum vb2_io_modes { + VB2_MMAP = (1 << 0), + VB2_USERPTR = (1 << 1), + VB2_READ = (1 << 2), + VB2_WRITE = (1 << 3), + VB2_DMABUF = (1 << 4), +}; + +/** + * enum vb2_fileio_flags - flags for selecting a mode of the file io emulator, + * by default the 'streaming' style is used by the file io emulator + * @VB2_FILEIO_READ_ONCE: report EOF after reading the first buffer + * @VB2_FILEIO_WRITE_IMMEDIATELY: queue buffer after each write() call + */ +enum vb2_fileio_flags { + VB2_FILEIO_READ_ONCE = (1 << 0), + VB2_FILEIO_WRITE_IMMEDIATELY = (1 << 1), +}; + +/** + * enum vb2_buffer_state - current video buffer state + * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control + * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver + * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver + * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used + * in a hardware operation + * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but + * not yet dequeued to userspace + * @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer + * has ended with an error, which will be reported + * to the userspace when it is dequeued + */ +enum vb2_buffer_state { + VB2_BUF_STATE_DEQUEUED, + VB2_BUF_STATE_PREPARED, + VB2_BUF_STATE_QUEUED, + VB2_BUF_STATE_ACTIVE, + VB2_BUF_STATE_DONE, + VB2_BUF_STATE_ERROR, +}; + +struct vb2_queue; + +/** + * struct vb2_buffer - represents a video buffer + * @v4l2_buf: struct v4l2_buffer associated with this buffer; can + * be read by the driver and relevant entries can be + * changed by the driver in case of CAPTURE types + * (such as timestamp) + * @v4l2_planes: struct v4l2_planes associated with this buffer; can + * be read by the driver and relevant entries can be + * changed by the driver in case of CAPTURE types + * (such as bytesused); NOTE that even for single-planar + * types, the v4l2_planes[0] struct should be used + * instead of v4l2_buf for filling bytesused - drivers + * should use the vb2_set_plane_payload() function for that + * @vb2_queue: the queue to which this driver belongs + * @num_planes: number of planes in the buffer + * on an internal driver queue + * @state: current buffer state; do not change + * @queued_entry: entry on the queued buffers list, which holds all + * buffers queued from userspace + * @done_entry: entry on the list that stores all buffers ready to + * be dequeued to userspace + * @planes: private per-plane information; do not change + */ +struct vb2_buffer { + struct v4l2_buffer v4l2_buf; + struct v4l2_plane v4l2_planes[VIDEO_MAX_PLANES]; + + struct vb2_queue *vb2_queue; + + unsigned int num_planes; + +/* Private: internal use only */ + enum vb2_buffer_state state; + + struct list_head queued_entry; + struct list_head done_entry; + + struct vb2_plane planes[VIDEO_MAX_PLANES]; +}; + +/** + * struct vb2_ops - driver-specific callbacks + * + * @queue_setup: called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS + * handlers before memory allocation, or, if + * *num_planes != 0, after the allocation to verify a + * smaller number of buffers. Driver should return + * the required number of buffers in *num_buffers, the + * required number of planes per buffer in *num_planes; the + * size of each plane should be set in the sizes[] array + * and optional per-plane allocator specific context in the + * alloc_ctxs[] array. When called from VIDIOC_REQBUFS, + * fmt == NULL, the driver has to use the currently + * configured format and *num_buffers is the total number + * of buffers, that are being allocated. When called from + * VIDIOC_CREATE_BUFS, fmt != NULL and it describes the + * target frame format (if the format isn't valid the + * callback must return -EINVAL). In this case *num_buffers + * are being allocated additionally to q->num_buffers. + * @wait_prepare: release any locks taken while calling vb2 functions; + * it is called before an ioctl needs to wait for a new + * buffer to arrive; required to avoid a deadlock in + * blocking access type + * @wait_finish: reacquire all locks released in the previous callback; + * required to continue operation after sleeping while + * waiting for a new buffer to arrive + * @buf_init: called once after allocating a buffer (in MMAP case) + * or after acquiring a new USERPTR buffer; drivers may + * perform additional buffer-related initialization; + * initialization failure (return != 0) will prevent + * queue setup from completing successfully; optional + * @buf_prepare: called every time the buffer is queued from userspace + * and from the VIDIOC_PREPARE_BUF ioctl; drivers may + * perform any initialization required before each hardware + * operation in this callback; drivers that support + * VIDIOC_CREATE_BUFS must also validate the buffer size; + * if an error is returned, the buffer will not be queued + * in driver; optional + * @buf_finish: called before every dequeue of the buffer back to + * userspace; drivers may perform any operations required + * before userspace accesses the buffer; optional + * @buf_cleanup: called once before the buffer is freed; drivers may + * perform any additional cleanup; optional + * @start_streaming: called once to enter 'streaming' state; the driver may + * receive buffers with @buf_queue callback before + * @start_streaming is called; the driver gets the number + * of already queued buffers in count parameter; driver + * can return an error if hardware fails or not enough + * buffers has been queued, in such case all buffers that + * have been already given by the @buf_queue callback are + * invalidated. + * @stop_streaming: called when 'streaming' state must be disabled; driver + * should stop any DMA transactions or wait until they + * finish and give back all buffers it got from buf_queue() + * callback; may use vb2_wait_for_all_buffers() function + * @buf_queue: passes buffer vb to the driver; driver may start + * hardware operation on this buffer; driver should give + * the buffer back by calling vb2_buffer_done() function; + * it is allways called after calling STREAMON ioctl; + * might be called before start_streaming callback if user + * pre-queued buffers before calling STREAMON + */ +struct vb2_ops { + int (*queue_setup)(struct vb2_queue *q, const struct v4l2_format *fmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *alloc_ctxs[]); + + void (*wait_prepare)(struct vb2_queue *q); + void (*wait_finish)(struct vb2_queue *q); + + int (*buf_init)(struct vb2_buffer *vb); + //int (*buf_prepare)(struct vb2_buffer *vb); + int (*buf_prepare)(struct vb2_buffer *vb, unsigned int index); + int (*buf_finish)(struct vb2_buffer *vb); + void (*buf_cleanup)(struct vb2_buffer *vb); + + int (*start_streaming)(struct vb2_queue *q, unsigned int count); + int (*stop_streaming)(struct vb2_queue *q); + + void (*buf_queue)(struct vb2_buffer *vb); +}; + +struct v4l2_fh; + +/** + * struct vb2_queue - a videobuf queue + * + * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h + * @io_modes: supported io methods (see vb2_io_modes enum) + * @io_flags: additional io flags (see vb2_fileio_flags enum) + * @lock: pointer to a mutex that protects the vb2_queue struct. The + * driver can set this to a mutex to let the v4l2 core serialize + * the queuing ioctls. If the driver wants to handle locking + * itself, then this should be set to NULL. This lock is not used + * by the videobuf2 core API. + * @owner: The filehandle that 'owns' the buffers, i.e. the filehandle + * that called reqbufs, create_buffers or started fileio. + * This field is not used by the videobuf2 core API, but it allows + * drivers to easily associate an owner filehandle with the queue. + * @ops: driver-specific callbacks + * @mem_ops: memory allocator specific callbacks + * @drv_priv: driver private data + * @buf_struct_size: size of the driver-specific buffer structure; + * "0" indicates the driver doesn't want to use a custom buffer + * structure type, so sizeof(struct vb2_buffer) will is used + * @gfp_flags: additional gfp flags used when allocating the buffers. + * Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32 + * to force the buffer allocation to a specific memory zone. + * + * @memory: current memory type used + * @bufs: videobuf buffer structures + * @num_buffers: number of allocated/used buffers + * @queued_list: list of buffers currently queued from userspace + * @queued_count: number of buffers owned by the driver + * @done_list: list of buffers ready to be dequeued to userspace + * @done_lock: lock to protect done_list list + * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued + * @alloc_ctx: memory type/allocator-specific contexts for each plane + * @streaming: current streaming state + * @fileio: file io emulator internal data, used only if emulator is active + */ +struct vb2_queue { + enum v4l2_buf_type type; + unsigned int io_modes; + unsigned int io_flags; + //struct mutex *lock; + _Mutex *lock; + + struct v4l2_fh *owner; + + const struct vb2_ops *ops; + const struct vb2_mem_ops *mem_ops; + void *drv_priv; + unsigned int buf_struct_size; + u32 timestamp_type; + gfp_t gfp_flags; + +/* private: internal use only */ + enum v4l2_memory memory; + struct vb2_buffer *bufs[VIDEO_MAX_FRAME]; + unsigned int num_buffers; + + struct list_head queued_list; + + atomic_t queued_count; + struct list_head done_list; + //spinlock_t done_lock; + //_LOCK_T done_lock; + _Mutex done_lock; + //wait_queue_head_t done_wq; + _Sema done_wq; //counting semaphore + + void *alloc_ctx[VIDEO_MAX_PLANES]; + unsigned int plane_sizes[VIDEO_MAX_PLANES]; + + //unsigned int streaming:1; + + unsigned int streaming; + //unsigned int start_streaming_called;//added by Ian + + struct vb2_fileio_data *fileio; +}; + +void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no); +void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); + +void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); +int vb2_wait_for_all_buffers(struct vb2_queue *q); + +int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); +int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); + +int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); +int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); + +int vb2_queue_init(struct vb2_queue *q); + +void vb2_queue_release(struct vb2_queue *q); + +int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b); +int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb); +int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); + +int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type); +int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type); + +int vb2_mmap(struct vb2_queue *q); +#ifndef CONFIG_MMU +unsigned long vb2_get_unmapped_area(struct vb2_queue *q, + unsigned long addr, + unsigned long len, + unsigned long pgoff, + unsigned long flags); +#endif +#if 0 +unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait); +size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, + loff_t *ppos, int nonblock); +size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count, + loff_t *ppos, int nonblock); +#endif +/** + * vb2_is_streaming() - return streaming status of the queue + * @q: videobuf queue + */ +static inline bool vb2_is_streaming(struct vb2_queue *q) +{ + return q->streaming; +} + +/** + * vb2_is_busy() - return busy status of the queue + * @q: videobuf queue + * + * This function checks if queue has any buffers allocated. + */ +static inline bool vb2_is_busy(struct vb2_queue *q) +{ + return (q->num_buffers > 0); +} + +/** + * vb2_get_drv_priv() - return driver private data associated with the queue + * @q: videobuf queue + */ +static inline void *vb2_get_drv_priv(struct vb2_queue *q) +{ + return q->drv_priv; +} + +/** + * vb2_set_plane_payload() - set bytesused for the plane plane_no + * @vb: buffer for which plane payload should be set + * @plane_no: plane number for which payload should be set + * @size: payload in bytes + */ +static inline void vb2_set_plane_payload(struct vb2_buffer *vb, + unsigned int plane_no, unsigned long size) +{ + if (plane_no < vb->num_planes) + vb->v4l2_planes[plane_no].bytesused = size; +} + +/** + * vb2_get_plane_payload() - get bytesused for the plane plane_no + * @vb: buffer for which plane payload should be set + * @plane_no: plane number for which payload should be set + * @size: payload in bytes + */ +static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb, + unsigned int plane_no) +{ + if (plane_no < vb->num_planes) + return vb->v4l2_planes[plane_no].bytesused; + return 0; +} + +/** + * vb2_plane_size() - return plane size in bytes + * @vb: buffer for which plane size should be returned + * @plane_no: plane number for which size should be returned + */ +static inline unsigned long +vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no) +{ + if (plane_no < vb->num_planes) + return vb->v4l2_planes[plane_no].length; + return 0; +} + +/* + * The following functions are not part of the vb2 core API, but are simple + * helper functions that you can use in your struct v4l2_file_operations, + * struct v4l2_ioctl_ops and struct vb2_ops. They will serialize if vb2_queue->lock + * or video_device->lock is set, and they will set and test vb2_queue->owner + * to check if the calling filehandle is permitted to do the queuing operation. + */ + +/* struct v4l2_ioctl_ops helpers */ + +int vb2_ioctl_reqbufs(void *priv, struct v4l2_requestbuffers *p); +int vb2_ioctl_create_bufs(void *priv, struct v4l2_create_buffers *p); +int vb2_ioctl_prepare_buf(void *priv, struct v4l2_buffer *p); +int vb2_ioctl_querybuf(void *priv, struct v4l2_buffer *p); +int vb2_ioctl_qbuf(void *priv, struct v4l2_buffer *p); +int vb2_ioctl_dqbuf(void *priv, struct v4l2_buffer *p); +int vb2_ioctl_streamon(void *priv, enum v4l2_buf_type i); +int vb2_ioctl_streamoff(void *priv, enum v4l2_buf_type i); +int vb2_ioctl_expbuf(void *priv, struct v4l2_exportbuffer *p); + +/* struct v4l2_file_operations helpers */ + +int vb2_fop_mmap(); +int vb2_fop_release(); +#if 0 +ssize_t vb2_fop_write(struct file *file, char __user *buf, + size_t count, loff_t *ppos); +ssize_t vb2_fop_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos); +unsigned int vb2_fop_poll(struct file *file, poll_table *wait); +#endif +#ifndef CONFIG_MMU +unsigned long vb2_fop_get_unmapped_area(unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags); +#endif + +/* struct vb2_ops helpers, only use if vq->lock is non-NULL. */ + +void vb2_ops_wait_prepare(struct vb2_queue *vq); +void vb2_ops_wait_finish(struct vb2_queue *vq); + +#endif /* _MEDIA_VIDEOBUF2_CORE_H */ diff --git a/USDK/component/common/video/v4l2/inc/videobuf2-memops.h b/USDK/component/common/video/v4l2/inc/videobuf2-memops.h new file mode 100644 index 0000000..fd67fcf --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/videobuf2-memops.h @@ -0,0 +1,41 @@ +/* + * videobuf2-memops.h - generic memory handling routines for videobuf2 + * + * Copyright (C) 2010 Samsung Electronics + * + * Author: Pawel Osciak + * Marek Szyprowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef _MEDIA_VIDEOBUF2_MEMOPS_H +#define _MEDIA_VIDEOBUF2_MEMOPS_H + +#include "videobuf2-core.h" + + +/** + * vb2_vmarea_handler - common vma refcount tracking handler + * @refcount: pointer to refcount entry in the buffer + * @put: callback to function that decreases buffer refcount + * @arg: argument for @put callback + */ +struct vb2_vmarea_handler { + atomic_t *refcount; + void (*put)(void *arg); + void *arg; +}; + +extern const struct vm_operations_struct vb2_common_vm_ops; + +int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size, + struct vm_area_struct **res_vma, dma_addr_t *res_pa); + +struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma); +void vb2_put_vma(struct vm_area_struct *vma); + + +#endif diff --git a/USDK/component/common/video/v4l2/inc/videobuf2-vmalloc.h b/USDK/component/common/video/v4l2/inc/videobuf2-vmalloc.h new file mode 100644 index 0000000..3e13d0c --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/videobuf2-vmalloc.h @@ -0,0 +1,21 @@ +/* + * videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2 + * + * Copyright (C) 2010 Samsung Electronics + * + * Author: Pawel Osciak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H +#define _MEDIA_VIDEOBUF2_VMALLOC_H + +#include "videobuf2-core.h" + + +extern const struct vb2_mem_ops vb2_vmalloc_memops; + +#endif diff --git a/USDK/component/common/video/v4l2/inc/videodev2.h b/USDK/component/common/video/v4l2/inc/videodev2.h new file mode 100644 index 0000000..ab1123f --- /dev/null +++ b/USDK/component/common/video/v4l2/inc/videodev2.h @@ -0,0 +1,62 @@ +/* + * Video for Linux Two header file + * + * Copyright (C) 1999-2012 the contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Alternatively you can redistribute this file under the terms of the + * BSD license as stated below: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. The names of its contributors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Header file for v4l or V4L2 drivers and applications + * with public API. + * All kernel-specific stuff were moved to media/v4l2-dev.h, so + * no #if __KERNEL tests are allowed here + * + * See http://linuxtv.org for more info + * + * Author: Bill Dirks + * Justin Schoeman + * Hans Verkuil + * et al. + */ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H + +//#include /* need struct timeval */ +#include "uapi_videodev2.h" + +#endif /* __LINUX_VIDEODEV2_H */ diff --git a/USDK/component/os/freertos/cmsis_os.c b/USDK/component/os/freertos/cmsis_os.c new file mode 100644 index 0000000..f89830a --- /dev/null +++ b/USDK/component/os/freertos/cmsis_os.c @@ -0,0 +1,1402 @@ + + +#include "cmsis_os.h" +#include "diag.h" + +#define CMSIS_OS_ERR(fmt, args...) DBG_8195A("\n\r%s: " fmt, __FUNCTION__, ## args) + +extern void *_memset( void *s, int c, SIZE_T n ); +#define os_memset _memset + +#if configSignalManagementSupport // the older FreeRTOS version didn't support Signal Management functions +#if 0 +#define THREAD_SIGNAL_MAP_SIZE 32 +typedef struct thread_signal_map { + uint8_t is_in_use; + osThreadId thread_id; + EventGroupHandle_t signals; +} ThreadSignalEntity; + + +ThreadSignalEntity ThreadSignalMapTable[THREAD_SIGNAL_MAP_SIZE]={0}; +#endif + +typedef struct thread_signal_map { + osThreadId thread_id; + EventGroupHandle_t signals; + void *pnext; +} ThreadSignalRec, *pThreadSignalRec; + +ThreadSignalRec *pThreadSignalMapHead; +ThreadSignalRec *pThreadSignalMapTail; +#endif + +/* Convert from CMSIS type osPriority to FreeRTOS priority number */ +static unsigned portBASE_TYPE makeFreeRtosPriority (osPriority priority) +{ + unsigned portBASE_TYPE fpriority = tskIDLE_PRIORITY; + + if (priority != osPriorityError) { + fpriority += (priority - osPriorityIdle); + } + + return fpriority; +} + + +/* Convert from FreeRTOS priority number to CMSIS type osPriority */ +static osPriority makeCmsisPriority (unsigned portBASE_TYPE fpriority) +{ + osPriority priority = osPriorityError; + + if ((fpriority - tskIDLE_PRIORITY) <= (osPriorityRealtime - osPriorityIdle)) { + priority = (osPriority)((int)osPriorityIdle + (int)(fpriority - tskIDLE_PRIORITY)); + } + + return priority; +} + +/* pvvx! */ +static uint32_t __get_IPSR(void) +{ + uint32_t result; + + asm volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + +/* Determine whether we are in thread mode or handler mode. */ +static int inHandlerMode (void) +{ + return __get_IPSR() != 0; +} + +#if configSignalManagementSupport // the older FreeRTOS version didn't support Signal Management functions +static void add_thread_signal_map (osThreadId thread_id, EventGroupHandle_t signals) +{ + int dummy; +// uint32_t i; + ThreadSignalRec *prec_entity; + + if (inHandlerMode()) { + dummy = portSET_INTERRUPT_MASK_FROM_ISR(); + } + else { + vPortEnterCritical(); + } + + prec_entity = (ThreadSignalRec*) malloc(sizeof(ThreadSignalRec)); + + if (prec_entity != NULL) { + prec_entity->thread_id = thread_id; + prec_entity->signals = signals; + prec_entity->pnext = NULL; + if (pThreadSignalMapHead == NULL) { + pThreadSignalMapHead = prec_entity; + pThreadSignalMapTail = prec_entity; + } + else { + pThreadSignalMapTail->pnext = prec_entity; + pThreadSignalMapTail = prec_entity; + } + } + else { + CMSIS_OS_ERR("No Free Thread-Signal entity\n"); + } + +#if 0 + for (i=0;i= THREAD_SIGNAL_MAP_SIZE) { + // No free Thread-Signals map entity + CMSIS_OS_ERR("No Free Thread-Signal entity\n"); + } + +#endif + + if (inHandlerMode()) { + portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy); + } + else { + vPortExitCritical(); + } + +} + +static EventGroupHandle_t find_signal_by_thread (osThreadId thread_id) +{ + EventGroupHandle_t signals_hdl=NULL; +// uint32_t i; + int dummy; + ThreadSignalRec *prec_entity; + + if (inHandlerMode()) { + dummy = portSET_INTERRUPT_MASK_FROM_ISR(); + } + else { + vPortEnterCritical(); + } + + prec_entity = pThreadSignalMapHead; + while (prec_entity != NULL) { + if (prec_entity->thread_id == thread_id) { + signals_hdl = prec_entity->signals; + break; + } + else { + prec_entity = prec_entity->pnext; + } + } + +#if 0 + for (i=0;ithread_id == thread_id) { + signals_hdl = prec_entity->signals; + if (prec_entity == pThreadSignalMapHead) { + if (prec_entity->pnext != NULL) { + pThreadSignalMapHead = prec_entity->pnext; + } + else { + pThreadSignalMapHead = NULL; + pThreadSignalMapTail = NULL; + } + } + else if (prec_entity == pThreadSignalMapTail) { + pprev_entity->pnext = NULL; + pThreadSignalMapTail = pprev_entity; + } + else { + pprev_entity->pnext = prec_entity->pnext; + } + free((void *)prec_entity); + break; + } + else { + pprev_entity = prec_entity; + prec_entity = prec_entity->pnext; + } + } + +#if 0 + for (i=0;ipthread, + (const portCHAR *)thread_def->name, + (thread_def->stacksize/4), + argument, + makeFreeRtosPriority(thread_def->tpriority), + &handle); + if (pdPASS == result) { +#if configSignalManagementSupport + EventGroupHandle_t signals; + + signals = xEventGroupCreate(); + if (signals == NULL) { + /* The event group was not created because there was insufficient + FreeRTOS heap available. */ + CMSIS_OS_ERR("Create a EventGroup for a new thread failed\n"); + } + else + { + add_thread_signal_map(handle, signals); + } +#endif + } + else + { + CMSIS_OS_ERR("Create a new thread(%s) failed\r\n", thread_def->name); + } + + return handle; +} + + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void) +{ + return xTaskGetCurrentTaskHandle(); +} + + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id) +{ +#if configSignalManagementSupport + EventGroupHandle_t EventHandle; + + EventHandle = remove_thread_signal_map (thread_id); + if (EventHandle) { + vEventGroupDelete (EventHandle); + } +#endif + + vTaskDelete(thread_id); + + return osOK; +} + + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void) +{ + taskYIELD(); + + return osOK; +} + + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) +{ + vTaskPrioritySet(thread_id, makeFreeRtosPriority(priority)); + + return osOK; +} + + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id) +{ + return makeCmsisPriority(uxTaskPriorityGet(thread_id)); +} + + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay) +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec) +{ +#if INCLUDE_vTaskDelay + portTickType ticks = (millisec * configTICK_RATE_HZ) / 1000; + + vTaskDelay(ticks ? ticks : 1); /* Minimum delay = 1 tick */ + + return osOK; +#else + (void) millisec; + + return osErrorResource; +#endif +} + + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== + +static void _osTimerCallbackFreeRTOS (xTimerHandle handle) +{ + osTimerDef_t *timer = (osTimerDef_t *)(pvTimerGetTimerID(handle)); + + timer->ptimer(timer->custom->argument); +} + + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) +{ + timer_def->custom->argument = argument; + + return xTimerCreate((const portCHAR *)"", + 1, //Set later when timer is started + (type == osTimerPeriodic) ? pdTRUE : pdFALSE, + (void *)timer_def, + _osTimerCallbackFreeRTOS + ); +} + + + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) +{ + portBASE_TYPE taskWoken = pdFALSE; + osStatus result = osOK; + portTickType ticks = millisec / portTICK_RATE_MS; + if (ticks == 0) { + ticks = 1; + } + + if (inHandlerMode()) { + if (xTimerChangePeriodFromISR(timer_id, ticks, &taskWoken) == pdPASS) { + xTimerStartFromISR(timer_id, &taskWoken); + portEND_SWITCHING_ISR(taskWoken); + } + } + else { + //TODO: add timeout support + if (xTimerChangePeriod(timer_id, ticks, 0) != pdPASS) { + result = osErrorOS; + } + else { + if (xTimerStart(timer_id, 0) != pdPASS) { + result = osErrorOS; + } + } + } + + return result; +} + + + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id) +{ + portBASE_TYPE taskWoken = pdFALSE; + osStatus result = osOK; + + if (inHandlerMode()) { + xTimerStopFromISR(timer_id, &taskWoken); + portEND_SWITCHING_ISR(taskWoken); + } + else { + if (xTimerStop(timer_id, 0) != pdPASS) { //TODO: add timeout support + result = osErrorOS; + } + } + + return result; +} + + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id) +{ + osStatus result = osOK; + + /* try to delete the soft timer and wait max RTL_TIMER_API_MAX_BLOCK_TICKS + to send the delete command to the timer command queue */ + if (xTimerDelete(timer_id, portMAX_DELAY ) != pdPASS) { + result = osErrorOS; + } + + return result; +} + +// ==== Signal Management ==== +#if configSignalManagementSupport +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals) +{ + EventGroupHandle_t event_handle; + portBASE_TYPE taskWoken = pdFALSE; + portBASE_TYPE xResult; + EventBits_t uxBits_ret=0x80000000; +#ifdef CHECK_VALUE_OF_EVENT_GROUP + EventBits_t uxBits; +#endif + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + return 0x80000000; + } + + event_handle = find_signal_by_thread(thread_id); + if (event_handle) { + if (inHandlerMode()) { + uxBits_ret = xEventGroupGetBitsFromISR(event_handle); + xResult = xEventGroupSetBitsFromISR( + event_handle, /* The event group being updated. */ + signals, /* The bits being set. */ + &taskWoken ); + if( xResult != pdFAIL ) + { + portYIELD_FROM_ISR(taskWoken); + } + } + else { + uxBits_ret = xEventGroupGetBits(event_handle); +#ifdef CHECK_VALUE_OF_EVENT_GROUP + uxBits = +#endif + xEventGroupSetBits( + event_handle, /* The event group being updated. */ + signals );/* The bits being set. */ + } + } + + return uxBits_ret; +} + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals) +{ + EventGroupHandle_t event_handle; + //portBASE_TYPE taskWoken = pdFALSE; + EventBits_t uxBits_ret=0x80000000; +#ifdef CHECK_VALUE_OF_EVENT_GROUP + EventBits_t uxBits; +#endif + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + return 0x80000000; + } + + event_handle = find_signal_by_thread(thread_id); + if (event_handle) { + if (inHandlerMode()) { + uxBits_ret = xEventGroupGetBitsFromISR(event_handle); +#ifdef CHECK_VALUE_OF_EVENT_GROUP + uxBits = +#endif + xEventGroupClearBitsFromISR( + event_handle, /* The event group being updated. */ + signals);/* The bits being cleared. */ + } + else { + uxBits_ret = xEventGroupGetBits(event_handle); +#ifdef CHECK_VALUE_OF_EVENT_GROUP + uxBits = +#endif + xEventGroupClearBits( + event_handle, /* The event group being updated. */ + signals);/* The bits being cleared. */ + } + } + + return uxBits_ret; +} + + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +osEvent osSignalWait (int32_t signals, uint32_t millisec) +{ + TaskHandle_t thread_id; + EventGroupHandle_t event_handle; + EventBits_t uxBits=0x80000000; + osEvent ret; + uint32_t wait_ticks; + + if (signals & (0xFFFFFFFF << osFeature_Signals)) { + ret.status = osErrorValue; + ret.value.signals = 0; + return ret; + } + + thread_id = xTaskGetCurrentTaskHandle(); + event_handle = find_signal_by_thread(thread_id); + if (event_handle) { + if (signals == 0) { + // if signals is 0, then wait any signal + signals = (1 << osFeature_Signals) - 1; + } + + wait_ticks = millisec_to_ticks(millisec); + uxBits = xEventGroupWaitBits( + event_handle, /* The event group being tested. */ + signals, /* The bits within the event group to wait for. */ + pdTRUE, /* the signals should be cleared before returning. */ + pdFALSE, /* Don't wait for both bits, either bit will do. */ + wait_ticks );/* Wait for either bit to be set. */ + if (uxBits == 0) { + ret.status = millisec ? osEventTimeout : osOK; + ret.value.signals = 0; + } + else { + ret.status = osEventSignal; + ret.value.signals = uxBits; + } + } + + return ret; +} +#else +// The older FreeRTOS version didn't support Signal Management functions + +int32_t osSignalSet (osThreadId thread_id, int32_t signals) +{ + return 0; +} + +int32_t osSignalClear (osThreadId thread_id, int32_t signals) +{ + return 0; +} + +osEvent osSignalWait (int32_t signals, uint32_t millisec) +{ + osEvent ret; + + ret.status = osErrorOS; + return ret; +} + +#endif // end of "else of #if configSignalManagementSupport + +// ==== Mutex Management ==== + + +/// Create and Initialize a Mutex object +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) +{ + (void) mutex_def; + + return xSemaphoreCreateMutex(); +} + + + +/// Wait until a Mutex becomes available +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) +{ + portTickType ticks; + + + if (mutex_id == NULL) { + return osErrorParameter; + } + + if (inHandlerMode()) { + return osErrorISR; + } + + ticks = millisec_to_ticks(millisec); + + if (xSemaphoreTake(mutex_id, ticks) != pdTRUE) { + return osErrorOS; + } + + return osOK; +} + + + +/// Release a Mutex that was obtained by \ref osMutexWait +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id) +{ + osStatus result = osOK; + portBASE_TYPE taskWoken = pdFALSE; + + + if (inHandlerMode()) { + if (xSemaphoreGiveFromISR(mutex_id, &taskWoken) != pdTRUE) { + result = osErrorOS; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + if (xSemaphoreGive(mutex_id) != pdTRUE) { + result = osErrorOS; + } + } + + return result; +} + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id) +{ + if (!mutex_id) { + return osErrorValue; + } + + vSemaphoreDelete(mutex_id); + return osOK; +} + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Create and Initialize a Semaphore object used for managing resources +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) +{ + (void) semaphore_def; + osSemaphoreId sema; + + if (count == 1) { + vSemaphoreCreateBinary(sema); + return sema; + } + + return xSemaphoreCreateCounting(count, count); +} + + + +/// Wait until a Semaphore token becomes available +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphore. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) +{ + portTickType ticks; + + + if (semaphore_id == NULL) { + return osErrorParameter; + } + + ticks = millisec_to_ticks(millisec); + + if (inHandlerMode()) { + return osErrorISR; + } + + if (xSemaphoreTake(semaphore_id, ticks) != pdTRUE) { + return osErrorOS; + } + + return osOK; +} + + +/// Release a Semaphore token +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphore. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) +{ + osStatus result = osOK; + portBASE_TYPE taskWoken = pdFALSE; + + + if (inHandlerMode()) { + if (xSemaphoreGiveFromISR(semaphore_id, &taskWoken) != pdTRUE) { + result = osErrorOS; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + if (xSemaphoreGive(semaphore_id) != pdTRUE) { + result = osErrorOS; + } + } + + return result; +} + + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) +{ + if (!semaphore_id) { + return osErrorValue; + } + + vSemaphoreDelete(semaphore_id); + return osOK; +} + + +#endif // Semaphore available + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +#if 0 +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of objects (elements) in the memory pool. +/// \param type data type of a single object (element). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern osPoolDef_t os_pool_def_##name; +#else // define the object +#define osPoolDef(name, no, type) \ +osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL }; +#endif +#endif + +//TODO +//This is a primitive and inefficient wrapper around the existing FreeRTOS memory management. +//A better implementation will have to modify heap_x.c! + + +typedef struct os_pool_cb { + void *pool; + uint8_t *markers; + uint32_t pool_sz; + uint32_t item_sz; + uint32_t currentIndex; +} os_pool_cb_t; + +#if 0 +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name +#endif + +/// Create and Initialize a memory pool +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def) +{ + osPoolId thePool; + int itemSize = 4 * ((pool_def->item_sz + 3) / 4); + uint32_t i; + + /* First have to allocate memory for the pool control block. */ + thePool = pvPortMalloc(sizeof(os_pool_cb_t)); + if (thePool) { + thePool->pool_sz = pool_def->pool_sz; + thePool->item_sz = itemSize; + thePool->currentIndex = 0; + + /* Memory for markers */ + thePool->markers = pvPortMalloc(pool_def->pool_sz); + if (thePool->markers) { + /* Now allocate the pool itself. */ + thePool->pool = pvPortMalloc(pool_def->pool_sz * itemSize); + + if (thePool->pool) { + for (i = 0; i < pool_def->pool_sz; i++) { + thePool->markers[i] = 0; + } + } + else { + vPortFree(thePool->markers); + vPortFree(thePool); + thePool = NULL; + } + } + else { + vPortFree(thePool); + thePool = NULL; + } + } + + return thePool; +} + + +/// Allocate a memory block from a memory pool +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id) +{ + int dummy; + void *p = NULL; + uint32_t i; + uint32_t index; + + if (inHandlerMode()) { + dummy = portSET_INTERRUPT_MASK_FROM_ISR(); + } + else { + vPortEnterCritical(); + } + + for (i = 0; i < pool_id->pool_sz; i++) { + index = pool_id->currentIndex + i; + if (index >= pool_id->pool_sz) { + index = 0; + } + + if (pool_id->markers[index] == 0) { + pool_id->markers[index] = 1; + p = (void *)((uint32_t)(pool_id->pool) + (index * pool_id->item_sz)); + pool_id->currentIndex = index; + break; + } + } + + if (inHandlerMode()) { + portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy); + } + else { + vPortExitCritical(); + } + + return p; +} + + +/// Allocate a memory block from a memory pool and set memory block to zero +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id) +{ + void *p = osPoolAlloc(pool_id); + + os_memset(p, 0, pool_id->item_sz); + + return p; +} + + +/// Return an allocated memory block back to a specific memory pool +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block) +{ + int dummy; + uint32_t index; + + if (pool_id == NULL) { + return osErrorParameter; + } + + if (block == NULL) { + return osErrorParameter; + } + + if (block < pool_id->pool) { + return osErrorParameter; + } + + index = (uint32_t)block - (uint32_t)(pool_id->pool); + if (index % pool_id->item_sz) { + return osErrorParameter; + } + index = index / pool_id->item_sz; + if (index >= pool_id->pool_sz) { + return osErrorParameter; + } + + if (inHandlerMode()) { + dummy = portSET_INTERRUPT_MASK_FROM_ISR(); + } + else { + vPortEnterCritical(); + } + + pool_id->markers[index] = 0; + + if (inHandlerMode()) { + portCLEAR_INTERRUPT_MASK_FROM_ISR(dummy); + } + else { + vPortExitCritical(); + } + + return osOK; +} + + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) +{ + (void) thread_id; + + return xQueueCreate(queue_def->queue_sz, queue_def->item_sz); +} + + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) +{ + portBASE_TYPE taskWoken = pdFALSE; + portTickType ticks; + + if (inHandlerMode()) { + if (xQueueSendFromISR(queue_id, (const void *)info, &taskWoken) != pdTRUE) { + return osErrorOS; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + ticks = millisec_to_ticks(millisec); + + if (xQueueSend(queue_id, (const void *)info, ticks) != pdTRUE) { + return osErrorOS; + } + } + + return osOK; +} + + + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) +{ + portBASE_TYPE taskWoken = pdFALSE; + portTickType ticks; + osEvent retEvent; + + retEvent.def.message_id = queue_id; + if (inHandlerMode()) { + if (xQueueReceiveFromISR(queue_id, (void *)retEvent.value.p, &taskWoken) != pdTRUE) { + retEvent.status = osErrorOS; + return retEvent; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + ticks = millisec_to_ticks(millisec); + + if (xQueueReceive(queue_id, (void *)retEvent.value.p, ticks) != pdTRUE) { + retEvent.status = osErrorOS; + return retEvent; + } + } + + retEvent.status = osOK; + + return retEvent; +} + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + + +typedef struct os_mailQ_cb { + osMailQDef_t *queue_def; + xQueueHandle handle; + osPoolId pool; +} os_mailQ_cb_t; + + +/// Create and Initialize mail queue +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) +{ + (void) thread_id; + + osPoolDef_t pool_def = {queue_def->queue_sz, queue_def->item_sz}; + + + /* Create a mail queue control block */ + *(queue_def->cb) = pvPortMalloc(sizeof(struct os_mailQ_cb)); + if (*(queue_def->cb) == NULL) { + return NULL; + } + (*(queue_def->cb))->queue_def = (osMailQDef_t *)queue_def; + + /* Create a queue in FreeRTOS */ + (*(queue_def->cb))->handle = xQueueCreate(queue_def->queue_sz, sizeof(void *)); + if ((*(queue_def->cb))->handle == NULL) { + vPortFree(*(queue_def->cb)); + return NULL; + } + + /* Create a mail pool */ + (*(queue_def->cb))->pool = osPoolCreate(&pool_def); + if ((*(queue_def->cb))->pool == NULL) { + vQueueDelete((*(queue_def->cb))->handle); + vPortFree(*(queue_def->cb)); + return NULL; + } + + return *(queue_def->cb); +} + + + +/// Allocate a memory block from a mail +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec) +{ + (void) millisec; + void *p; + uint32_t retried=0; + + + if (queue_id == NULL) { + return NULL; + } + + do { + p = osPoolAlloc(queue_id->pool); + if (NULL == p) { + // sleep a while and then try again + if (millisec == osWaitForever) { + osDelay(2); + } + else { + if (!retried) { + osDelay(millisec); + retried = 1; + } + else { + break; + } + } + } + } while (NULL == p); + + + return p; +} + + + +/// Allocate a memory block from a mail and set memory block to zero +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can shall filled with mail or NULL in case error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) +{ +// uint32_t i; + void *p = osMailAlloc(queue_id, millisec); + + if (p) { + os_memset(p, 0, queue_id->queue_def->item_sz); + } + + return p; +} + + + +/// Put a mail to a queue +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail) +{ + portBASE_TYPE taskWoken; + portTickType ticks=1000/portTICK_RATE_MS; // No timeout is defined for this function, so we just wait 1 sec + + + if (queue_id == NULL) { + return osErrorParameter; + } + + taskWoken = pdFALSE; + + if (inHandlerMode()) { + if (xQueueSendFromISR(queue_id->handle, &mail, &taskWoken) != pdTRUE) { + return osErrorOS; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + if (xQueueSend(queue_id->handle, &mail, ticks) != pdTRUE) { //TODO where to get timeout value? + return osErrorOS; + } + } + + return osOK; +} + + + +/// Get a mail from a queue +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec) +{ + portBASE_TYPE taskWoken; + portTickType ticks; + osEvent event; + + event.def.mail_id = queue_id; + + if (queue_id == NULL) { + event.status = osErrorParameter; + return event; + } + + taskWoken = pdFALSE; + + ticks = millisec_to_ticks(millisec); + + if (inHandlerMode()) { + if (xQueueReceiveFromISR(queue_id->handle, &event.value.p, &taskWoken) == pdTRUE) { + /* We have mail */ + event.status = osEventMail; + } + else { + event.status = osOK; + } + portEND_SWITCHING_ISR(taskWoken); + } + else { + if (xQueueReceive(queue_id->handle, &event.value.p, ticks) == pdTRUE) { + /* We have mail */ + event.status = osEventMail; + } + else { + event.status = (ticks == 0) ? osOK : osEventTimeout; + } + } + + return event; +} + + + +/// Free a memory block from a mail +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail) +{ + if (queue_id == NULL) { + return osErrorParameter; + } + + osPoolFree(queue_id->pool, mail); + + return osOK; +} + + +void *calloc_freertos(size_t nelements, size_t elementSize) +{ + void *pbuf; + uint32_t size; + + size = nelements*elementSize; + pbuf = pvPortMalloc(size); + os_memset(pbuf, 0, size); + + return pbuf; +} +#endif // Mail Queues available + + diff --git a/USDK/component/os/freertos/cmsis_os.h b/USDK/component/os/freertos/cmsis_os.h new file mode 100644 index 0000000..93f78e3 --- /dev/null +++ b/USDK/component/os/freertos/cmsis_os.h @@ -0,0 +1,819 @@ +/* ---------------------------------------------------------------------- + * $Date: 5. February 2013 + * $Revision: V1.02 + * + * Project: CMSIS-RTOS API + * Title: cmsis_os.h template header file + * + * Version 0.02 + * Initial Proposal Phase + * Version 0.03 + * osKernelStart added, optional feature: main started as thread + * osSemaphores have standard behavior + * osTimerCreate does not start the timer, added osTimerStart + * osThreadPass is renamed to osThreadYield + * Version 1.01 + * Support for C++ interface + * - const attribute removed from the osXxxxDef_t typedef's + * - const attribute added to the osXxxxDef macros + * Added: osTimerDelete, osMutexDelete, osSemaphoreDelete + * Added: osKernelInitialize + * Version 1.02 + * Control functions for short timeouts in microsecond resolution: + * Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec + * Removed: osSignalGet + *---------------------------------------------------------------------------- + * + * Copyright (c) 2013 ARM LIMITED + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "queue.h" +#include "semphr.h" + + +#define FREERTOS_VERSION 0x00080001 // bits[31:16] main version, bits[15:0] sub-version + +#if FREERTOS_VERSION >= 0x00080000 +#define configSignalManagementSupport 1 +#else +#define configSignalManagementSupport 0 +#endif + +#if configSignalManagementSupport +#include "event_groups.h" +#endif + +/** +\page cmsis_os_h Header File Template: cmsis_os.h + +The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). +Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents +its implementation. + +The file cmsis_os.h contains: + - CMSIS-RTOS API function definitions + - struct definitions for parameters and return types + - status and priority values used by CMSIS-RTOS API functions + - macros for defining threads and other kernel objects + + +Name conventions and header file modifications + +All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. +Definitions that are prefixed \b os_ are not used in the application code but local to this header file. +All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. + +Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. +These definitions can be specific to the underlying RTOS kernel. + +Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer +compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. + + +Function calls from interrupt service routines + +The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): + - \ref osSignalSet + - \ref osSemaphoreRelease + - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree + - \ref osMessagePut, \ref osMessageGet + - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree + +Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called +from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. + +Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. +If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. + + +Define and reference object definitions + +With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file +that is used throughout a project as shown below: + +Header File +\code +#include // CMSIS RTOS header file + +// Thread definition +extern void thread_sample (void const *argument); // function prototype +osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); + +// Pool definition +osPoolDef(MyPool, 10, long); +\endcode + + +This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is +present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be +used throughout the whole project. + +Example +\code +#include "osObjects.h" // Definition of the CMSIS-RTOS objects +\endcode + +\code +#define osObjectExternal // Objects will be defined as external symbols +#include "osObjects.h" // Reference to the CMSIS-RTOS objects +\endcode + +*/ + +#ifndef _CMSIS_OS_H +#define _CMSIS_OS_H + +/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. +#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0]) + +/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. +#define osKernelSystemId "KERNEL V1.00" ///< RTOS identification string + +/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. +#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available +#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available +#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available +#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available +#define osFeature_Signals 8 ///< maximum number of Signal Flags available per thread +#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function +#define osFeature_Wait 1 ///< osWait function: 1=available, 0=not available +#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available + +//#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumeration, structures, defines ==== + +/// Priority used for thread control. +/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. +typedef enum { + osPriorityIdle = -3, ///< priority: idle (lowest) + osPriorityLow = -2, ///< priority: low + osPriorityBelowNormal = -1, ///< priority: below normal + osPriorityNormal = 0, ///< priority: normal (default) + osPriorityAboveNormal = +1, ///< priority: above normal + osPriorityHigh = +2, ///< priority: high + osPriorityRealtime = +3, ///< priority: realtime (highest) + osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority +} osPriority; + +/// Timeout value. +/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. +#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value + +/// Status code values returned by CMSIS-RTOS functions. +/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. +typedef enum { + osOK = 0, ///< function completed; no error or event occurred. + osEventSignal = 0x08, ///< function completed; signal event occurred. + osEventMessage = 0x10, ///< function completed; message event occurred. + osEventMail = 0x20, ///< function completed; mail event occurred. + osEventTimeout = 0x40, ///< function completed; timeout occurred. + osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object. + osErrorResource = 0x81, ///< resource not available: a specified resource was not available. + osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period. + osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines. + osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object. + osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority. + osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorValue = 0x86, ///< value of a parameter is out of range. + osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits. + os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization. +} osStatus; + + +/// Timer type value for the timer definition. +/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. +typedef enum { + osTimerOnce = 0, ///< one-shot timer + osTimerPeriodic = 1 ///< repeating timer +} os_timer_type; + +/// Entry point of a thread. +/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. +typedef void (*os_pthread) (void const *argument); + +/// Entry point of a timer call back function. +/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. +typedef void (*os_ptimer) (void const *argument); + +// >>> the following data type definitions may shall adapted towards a specific RTOS + +/// Thread ID identifies the thread (pointer to a thread control block). +/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. +typedef xTaskHandle osThreadId; + +/// Timer ID identifies the timer (pointer to a timer control block). +/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. +typedef xTimerHandle osTimerId; + +/// Mutex ID identifies the mutex (pointer to a mutex control block). +/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. +typedef xSemaphoreHandle osMutexId; + +/// Semaphore ID identifies the semaphore (pointer to a semaphore control block). +/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. +typedef xSemaphoreHandle osSemaphoreId; + +/// Pool ID identifies the memory pool (pointer to a memory pool control block). +/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_cb *osPoolId; + +/// Message ID identifies the message queue (pointer to a message queue control block). +/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. +typedef xQueueHandle osMessageQId; + +/// Mail ID identifies the mail queue (pointer to a mail queue control block). +/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_cb *osMailQId; + + +/// Thread Definition structure contains startup information of a thread. +/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. +typedef struct os_thread_def { + os_pthread pthread; ///< start address of thread function + osPriority tpriority; ///< initial thread priority + uint32_t instances; ///< maximum number of instances of that thread function + uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size + char * name; +} osThreadDef_t; + +/// Timer Definition structure contains timer parameters. +/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. +struct os_timer_custom { + void *argument; +}; + +typedef struct os_timer_def { + os_ptimer ptimer; ///< start address of a timer function + struct os_timer_custom *custom; +} osTimerDef_t; + +/// Mutex Definition structure contains setup information for a mutex. +/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mutex_def { + uint32_t dummy; ///< dummy value. +} osMutexDef_t; + +/// Semaphore Definition structure contains setup information for a semaphore. +/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. +typedef struct os_semaphore_def { + uint32_t dummy; ///< dummy value. +} osSemaphoreDef_t; + +/// Definition structure for memory block allocation +/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. +typedef struct os_pool_def { + uint32_t pool_sz; ///< number of items (elements) in the pool + uint32_t item_sz; ///< size of an item + void *pool; ///< pointer to memory for pool +} osPoolDef_t; + +/// Definition structure for message queue. +/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_messageQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + void *pool; ///< memory array for messages +} osMessageQDef_t; + +/// Definition structure for mail queue +/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. +typedef struct os_mailQ_def { + uint32_t queue_sz; ///< number of elements in the queue + uint32_t item_sz; ///< size of an item + struct os_mailQ_cb **cb; +} osMailQDef_t; + +/// Event structure contains detailed information about an event. +/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. +/// However the struct may be extended at the end. +typedef struct { + osStatus status; ///< status code: event or error information + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + union { + osMailQId mail_id; ///< mail id obtained by \ref osMailCreate + osMessageQId message_id; ///< message id obtained by \ref osMessageCreate + } def; ///< event definition +} osEvent; + + +// ==== Kernel Control Functions ==== + +/// Initialize the RTOS Kernel for creating objects. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. +osStatus osKernelInitialize (void); + +/// Start the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. +osStatus osKernelStart (void); + +/// Check if the RTOS kernel is already started. +/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. +/// \return 0 RTOS is not started, 1 RTOS is started. +int32_t osKernelRunning(void); + +#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available + +/// Get the RTOS kernel system timer counter +/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS. +/// \return RTOS kernel system timer as 32-bit value +uint32_t osKernelSysTick (void); + +/// The RTOS kernel system timer frequency in Hz +/// \note Reflects the system timer setting and is typically defined in a configuration file. +#define osKernelSysTickFrequency configTICK_RATE_HZ + +/// Convert a microseconds value to a RTOS kernel system timer value. +/// \param microsec time value in microseconds. +/// \return time value normalized to the \ref osKernelSysTickFrequency +#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000) + +#endif // System Timer available + +// ==== Thread Management ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name +#else // define the object +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz), #name } +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ +&os_thread_def_##name + +/// Create a thread and add it to Active Threads and set it to state READY. +/// \param[in] thread_def thread definition referenced with \ref osThread. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. +osThreadId osThreadGetId (void); + +/// Terminate execution of a thread and remove it from Active Threads. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. +osStatus osThreadTerminate (osThreadId thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. +osStatus osThreadYield (void); + +/// Change priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. +osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority); + +/// Get current priority of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \return current priority value of the thread function. +/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. +osPriority osThreadGetPriority (osThreadId thread_id); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] millisec time delay value +/// \return status code that indicates the execution status of the function. +osStatus osDelay (uint32_t millisec); + +#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available + +/// Wait for Signal, Message, Mail, or Timeout. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains signal, message, or mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. +osEvent osWait (uint32_t millisec); + +#endif // Generic Wait available + + +// ==== Timer Management Functions ==== +/// Define a Timer object. +/// \param name name of the timer object. +/// \param function name of the timer call back function. +/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osTimerDef(name, function) \ +extern const osTimerDef_t os_timer_def_##name; \ +extern struct os_timer_custom os_timer_custome_##name +#else // define the object +#define osTimerDef(name, function) \ +struct os_timer_custom os_timer_custom_##name; \ +const osTimerDef_t os_timer_def_##name = \ +{ (function), (&os_timer_custom_##name) } +#endif + +/// Access a Timer definition. +/// \param name name of the timer object. +/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osTimer(name) \ +&os_timer_def_##name + +/// Create a timer. +/// \param[in] timer_def timer object referenced with \ref osTimer. +/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer call back function. +/// \return timer ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \param[in] millisec time delay value of the timer. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. +osStatus osTimerStart (osTimerId timer_id, uint32_t millisec); + +/// Stop the timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. +osStatus osTimerStop (osTimerId timer_id); + +/// Delete a timer that was created by \ref osTimerCreate. +/// \param[in] timer_id timer ID obtained by \ref osTimerCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. +osStatus osTimerDelete (osTimerId timer_id); + + +// ==== Signal Management ==== + +/// Set the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that should be set. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. +int32_t osSignalSet (osThreadId thread_id, int32_t signals); + +/// Clear the specified Signal Flags of an active thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. +/// \param[in] signals specifies the signal flags of the thread that shall be cleared. +/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +int32_t osSignalClear (osThreadId thread_id, int32_t signals); + +/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. +/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event flag information or error code. +/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. +osEvent osSignalWait (int32_t signals, uint32_t millisec); + + +// ==== Mutex Management ==== + +/// Define a Mutex. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMutexDef(name) \ +extern const osMutexDef_t os_mutex_def_##name +#else // define the object +#define osMutexDef(name) \ +const osMutexDef_t os_mutex_def_##name = { 0 } +#endif + +/// Access a Mutex definition. +/// \param name name of the mutex object. +/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMutex(name) \ +&os_mutex_def_##name + +/// Create and Initialize a Mutex object. +/// \param[in] mutex_def mutex definition referenced with \ref osMutex. +/// \return mutex ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. +osMutexId osMutexCreate (const osMutexDef_t *mutex_def); + +/// Wait until a Mutex becomes available. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. +osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec); + +/// Release a Mutex that was obtained by \ref osMutexWait. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. +osStatus osMutexRelease (osMutexId mutex_id); + +/// Delete a Mutex that was created by \ref osMutexCreate. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. +osStatus osMutexDelete (osMutexId mutex_id); + + +// ==== Semaphore Management Functions ==== + +#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available + +/// Define a Semaphore object. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osSemaphoreDef(name) \ +extern const osSemaphoreDef_t os_semaphore_def_##name +#else // define the object +#define osSemaphoreDef(name) \ +const osSemaphoreDef_t os_semaphore_def_##name = { 0 } +#endif + +/// Access a Semaphore definition. +/// \param name name of the semaphore object. +/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osSemaphore(name) \ +&os_semaphore_def_##name + +/// Create and Initialize a Semaphore object used for managing resources. +/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore. +/// \param[in] count number of available resources. +/// \return semaphore ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count); + +/// Wait until a Semaphore token becomes available. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); + +/// Release a Semaphore token. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreRelease (osSemaphoreId semaphore_id); + +/// Delete a Semaphore that was created by \ref osSemaphoreCreate. +/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. +osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); + +#endif // Semaphore available + + +// ==== Memory Pool Management Functions ==== + +#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available + +/// \brief Define a Memory Pool. +/// \param name name of the memory pool. +/// \param no maximum number of blocks (objects) in the memory pool. +/// \param type data type of a single block (object). +/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osPoolDef(name, no, type) \ +extern const osPoolDef_t os_pool_def_##name +#else // define the object +#define osPoolDef(name, no, type) \ +const osPoolDef_t os_pool_def_##name = \ +{ (no), sizeof(type), NULL } +#endif + +/// \brief Access a Memory Pool definition. +/// \param name name of the memory pool +/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osPool(name) \ +&os_pool_def_##name + +/// Create and Initialize a memory pool. +/// \param[in] pool_def memory pool definition referenced with \ref osPool. +/// \return memory pool ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. +osPoolId osPoolCreate (const osPoolDef_t *pool_def); + +/// Allocate a memory block from a memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolAlloc (osPoolId pool_id); + +/// Allocate a memory block from a memory pool and set memory block to zero. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \return address of the allocated memory block or NULL in case of no memory available. +/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. +void *osPoolCAlloc (osPoolId pool_id); + +/// Return an allocated memory block back to a specific memory pool. +/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate. +/// \param[in] block address of the allocated memory block that is returned to the memory pool. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. +osStatus osPoolFree (osPoolId pool_id, void *block); + +#endif // Memory Pool Management available + + +// ==== Message Queue Management Functions ==== + +#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available + +/// \brief Create a Message Queue Definition. +/// \param name name of the queue. +/// \param queue_sz maximum number of messages in the queue. +/// \param type data type of a single message element (for debugger). +/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMessageQDef(name, queue_sz, type) \ +extern const osMessageQDef_t os_messageQ_def_##name +#else // define the object +#define osMessageQDef(name, queue_sz, type) \ +const osMessageQDef_t os_messageQ_def_##name = \ +{ (queue_sz), sizeof (type) } +#endif + +/// \brief Access a Message Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMessageQ(name) \ +&os_messageQ_def_##name + +/// Create and Initialize a Message Queue. +/// \param[in] queue_def queue definition referenced with \ref osMessageQ. +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return message queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); + +/// Put a Message to a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] info message information. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. +osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); + +/// Get a Message or Wait for a Message from a Queue. +/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out. +/// \return event information that includes status code. +/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. +osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); + +#endif // Message Queues available + + +// ==== Mail Queue Management Functions ==== + +#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available + +/// \brief Create a Mail Queue Definition. +/// \param name name of the queue +/// \param queue_sz maximum number of messages in queue +/// \param type data type of a single message element +/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osMailQDef(name, queue_sz, type) \ +extern struct os_mailQ_cb *os_mailQ_cb_##name; \ +extern const osMailQDef_t os_mailQ_def_##name; +#else // define the object +#define osMailQDef(name, queue_sz, type) \ +struct os_mailQ_cb *os_mailQ_cb_##name; \ +const osMailQDef_t os_mailQ_def_##name = \ +{ (queue_sz), sizeof (type), (&os_mailQ_cb_##name) } +#endif + +/// \brief Access a Mail Queue Definition. +/// \param name name of the queue +/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osMailQ(name) \ +&os_mailQ_def_##name + +/// Create and Initialize mail queue. +/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ +/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL. +/// \return mail queue ID for reference by other functions or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id); + +/// Allocate a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. +void *osMailAlloc (osMailQId queue_id, uint32_t millisec); + +/// Allocate a memory block from a mail and set memory block to zero. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return pointer to memory block that can be filled with mail or NULL in case of error. +/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. +void *osMailCAlloc (osMailQId queue_id, uint32_t millisec); + +/// Put a mail to a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. +osStatus osMailPut (osMailQId queue_id, void *mail); + +/// Get a mail from a queue. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] millisec timeout value or 0 in case of no time-out +/// \return event that contains mail information or error code. +/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. +osEvent osMailGet (osMailQId queue_id, uint32_t millisec); + +/// Free a memory block from a mail. +/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate. +/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet. +/// \return status code that indicates the execution status of the function. +/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. +osStatus osMailFree (osMailQId queue_id, void *mail); + +#endif // Mail Queues available + +//#undef malloc +#define malloc(size) pvPortMalloc(size) +//#undef free +#define free(pbuf) vPortFree(pbuf) + +extern void *calloc_freertos(size_t nelements, size_t elementSize); +#define calloc(nelements, elementSize) calloc_freertos(nelements, elementSize) + +#ifdef __cplusplus +} +#endif + +#endif // _CMSIS_OS_H diff --git a/USDK/component/os/freertos/freertos_pmu.c b/USDK/component/os/freertos/freertos_pmu.c new file mode 100644 index 0000000..ad81e00 --- /dev/null +++ b/USDK/component/os/freertos/freertos_pmu.c @@ -0,0 +1,298 @@ +/* +* SDK ver 3.5.2 ! +*/ +#include "FreeRTOS.h" + +#include "freertos_pmu.h" + +#include + +#include "platform_autoconf.h" +#include "sys_api.h" +#include "sleep_ex_api.h" +#include "gpio_api.h" +#include "us_ticker_api.h" + +#include "task.h" + +#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#endif + +uint32_t missing_tick = 0; + +#define FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS (0) + +static uint32_t wakelock = DEFAULT_WAKELOCK; +static uint32_t wakeup_event = DEFAULT_WAKEUP_EVENT; + +freertos_sleep_callback pre_sleep_callback[32] = {NULL}; +freertos_sleep_callback post_sleep_callback[32] = {NULL}; + +#if (configGENERATE_RUN_TIME_STATS == 1) +static u8 last_wakelock_state[32] = { + DEFAULT_WAKELOCK & 0x01, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static u32 last_acquire_wakelock_time[32] = {0}; +static u32 hold_wakelock_time[32] = {0}; +static u32 base_sys_time = 0; +static u32 sys_sleep_time = 0; +#endif + +#if defined(FREERTOS_PMU_TICKLESS_PLL_RESERVED) && (FREERTOS_PMU_TICKLESS_PLL_RESERVED==1) +unsigned char reserve_pll = 1; +#else +unsigned char reserve_pll = 0; +#endif + + +/* ++++++++ FreeRTOS macro implementation ++++++++ */ + +/* + * It is called in idle task. + * + * @return true : System is ready to check conditions that if it can enter sleep. + * false : System keep awake. + **/ +int freertos_ready_to_sleep() { + return wakelock == 0; +} + +/* + * It is called when freertos is going to sleep. + * At this moment, all sleep conditons are satisfied. All freertos' sleep pre-processing are done. + * + * @param expected_idle_time : The time that FreeRTOS expect to sleep. + * If we set this value to 0 then FreeRTOS will do nothing in its sleep function. + **/ +void freertos_pre_sleep_processing(unsigned int *expected_idle_time) { + +#ifdef CONFIG_SOC_PS_MODULE + + uint32_t i; + uint32_t stime; + uint32_t tick_before_sleep; + uint32_t tick_after_sleep; + uint32_t tick_passed; + uint32_t backup_systick_reg; + +#if (configGENERATE_RUN_TIME_STATS == 1) + uint32_t kernel_tick_before_sleep; + uint32_t kernel_tick_after_sleep; +#endif + + /* To disable freertos sleep function and use our sleep function, + * we can set original expected idle time to 0. */ + stime = *expected_idle_time; + *expected_idle_time = 0; + + for (i=0; i<32; i++) { + if ( pre_sleep_callback[i] != NULL) { + pre_sleep_callback[i]( stime ); + } + } + +#if (configGENERATE_RUN_TIME_STATS == 1) + kernel_tick_before_sleep = osKernelSysTick(); +#endif + + // Store gtimer timestamp before sleep + tick_before_sleep = us_ticker_read(); + +#if (FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS) + // config gpio on log uart tx for pull ctrl + HAL_GPIO_PIN gpio_log_uart_tx; + gpio_log_uart_tx.pin_name = gpio_set(PB_0); + gpio_log_uart_tx.pin_mode = DOUT_PUSH_PULL; + HAL_GPIO_Init(&gpio_log_uart_tx); + GpioFunctionChk(PB_0, ENABLE); + + sys_log_uart_off(); + HAL_GPIO_WritePin(&gpio_log_uart_tx, 1); // pull up log uart tx to avoid power lekage +#endif + + backup_systick_reg = portNVIC_SYSTICK_CURRENT_VALUE_REG; + +#ifdef CONFIG_SDR_EN + // sleep +#if defined(FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM) && (FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM!=0) + sleep_ex_selective(wakeup_event, stime, reserve_pll, IsSdrPowerOn()); +#else + sleep_ex_selective(wakeup_event, stime, reserve_pll, 0); +#endif +#else + sleep_ex_selective(wakeup_event, stime, reserve_pll, 0); +#endif // CONFIG_SDR_EN + + portNVIC_SYSTICK_CURRENT_VALUE_REG = backup_systick_reg; + +#if (FREERTOS_PMU_DISABLE_LOGUART_IN_TICKLESS) + sys_log_uart_off(); + sys_log_uart_on(); +#endif + + // update kernel tick by calculating passed tick from gtimer + { + // get current gtimer timestamp + tick_after_sleep = us_ticker_read(); + + // calculated passed time + if (tick_after_sleep > tick_before_sleep) { + tick_passed = tick_after_sleep - tick_before_sleep; + } else { + // overflow + tick_passed = (0xffffffff - tick_before_sleep) + tick_after_sleep; + } + + /* If there is a rapid interrupt (<1ms), it makes tick_passed less than 1ms. + * The tick_passed would be rounded and make OS can't step tick. + * We collect the rounded tick_passed into missing_tick and step tick properly. + * */ + tick_passed += missing_tick; + if (tick_passed > stime * 1000) { + missing_tick = tick_passed - stime * 1000; + tick_passed = stime * 1000; + } else { + missing_tick = tick_passed % 1000; + } + + // update kernel tick + vTaskStepTick( tick_passed/1000 ); + } + +#if (configGENERATE_RUN_TIME_STATS == 1) + kernel_tick_after_sleep = osKernelSysTick(); + sys_sleep_time += (kernel_tick_after_sleep - kernel_tick_before_sleep); +#endif + + for (i=0; i<32; i++) { + if ( post_sleep_callback[i] != NULL) { + post_sleep_callback[i]( stime ); + } + } + +#else + // If PS is not enabled, then use freertos sleep function +#endif +} + +void freertos_post_sleep_processing(unsigned int *expected_idle_time) { +#ifndef configSYSTICK_CLOCK_HZ + *expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) ); +#else + *expected_idle_time = 1 + ( portNVIC_SYSTICK_CURRENT_VALUE_REG / ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) ); +#endif +} +/* -------- FreeRTOS macro implementation -------- */ + +void acquire_wakelock(uint32_t lock_id) { + + wakelock |= lock_id; + +#if (configGENERATE_RUN_TIME_STATS == 1) + u32 i; + u32 current_timestamp = osKernelSysTick(); + for (i=0; i<32; i++) { + if ( (1< 0) { + sprintf(pcWriteBuffer, "%x\t\t%d\r\n", i, hold_wakelock_time[i]); + } + } + pcWriteBuffer += strlen( pcWriteBuffer ); + } + sprintf(pcWriteBuffer, "time passed: %d ms, system sleep %d ms\r\n", current_timestamp - base_sys_time, sys_sleep_time); +} + +void clean_wakelock_stat() { + u32 i; + base_sys_time = osKernelSysTick(); + for (i=0; i<32; i++) { + hold_wakelock_time[i] = 0; + if (last_wakelock_state[i] == 1) { + last_acquire_wakelock_time[i] = base_sys_time; + } + } + sys_sleep_time = 0; +} +#endif + +void add_wakeup_event(uint32_t event) { + wakeup_event |= event; +} + +void del_wakeup_event(uint32_t event) { + wakeup_event &= ~event; + // To fulfill tickless design, system timer is required to be wakeup event + wakeup_event |= SLEEP_WAKEUP_BY_STIMER; +} + +void register_sleep_callback_by_module( unsigned char is_pre_sleep, freertos_sleep_callback sleep_cb, uint32_t module ) { + u32 i; + for (i=0; i<32; i++) { + if ( module & BIT(i) ) { + if (is_pre_sleep) { + pre_sleep_callback[i] = sleep_cb; + } else { + post_sleep_callback[i] = sleep_cb; + } + } + } +} + +void register_pre_sleep_callback( freertos_sleep_callback pre_sleep_cb ) { + register_sleep_callback_by_module(1, pre_sleep_cb, 0x00008000); +} + +void register_post_sleep_callback( freertos_sleep_callback post_sleep_cb ) { + register_sleep_callback_by_module(0, post_sleep_cb, 0x00008000); +} + +void set_pll_reserved(unsigned char reserve) { + reserve_pll = reserve; +} diff --git a/USDK/component/os/freertos/freertos_pmu.h b/USDK/component/os/freertos/freertos_pmu.h new file mode 100644 index 0000000..f8bd482 --- /dev/null +++ b/USDK/component/os/freertos/freertos_pmu.h @@ -0,0 +1,149 @@ +#ifndef __FREERTOS_PMU_H_ +#define __FREERTOS_PMU_H_ + +#ifdef CONFIG_PLATFORM_8195A +#include "sleep_ex_api.h" +#endif + +#ifndef BIT +#define BIT(n) (1< +#include +#include +#include +//#include +#include +#include +#include +//#include +/********************* os depended utilities ********************/ + +#ifndef USE_MUTEX_FOR_SPINLOCK +#define USE_MUTEX_FOR_SPINLOCK 1 +#endif + +//----- ------------------------------------------------------------------ +// Misc Function +//----- ------------------------------------------------------------------ + +void save_and_cli() +{ + taskENTER_CRITICAL(); +} + +void restore_flags() +{ + taskEXIT_CRITICAL(); +} + +void cli() +{ + taskDISABLE_INTERRUPTS(); +} + +/* Not needed on 64bit architectures */ +static unsigned int __div64_32(u64 *n, unsigned int base) +{ + u64 rem = *n; + u64 b = base; + u64 res, d = 1; + unsigned int high = rem >> 32; + + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (u64) high << 32; + rem -= (u64) (high * base) << 32; + } + + while ((u64)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); + + *n = res; + return rem; +} + +/********************* os depended service ********************/ + +u8* _freertos_malloc(u32 sz) +{ + return pvPortMalloc(sz); +} + +u8* _freertos_zmalloc(u32 sz) +{ + u8 *pbuf = _freertos_malloc(sz); + + if (pbuf != NULL) + memset(pbuf, 0, sz); + + return pbuf; +} + +void _freertos_mfree(u8 *pbuf, u32 sz) +{ + vPortFree(pbuf); +} + +static void _freertos_memcpy(void* dst, void* src, u32 sz) +{ + memcpy(dst, src, sz); +} + +static int _freertos_memcmp(void *dst, void *src, u32 sz) +{ +//under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0 + if (!(memcmp(dst, src, sz))) + return 1; + + return 0; +} + +static void _freertos_memset(void *pbuf, int c, u32 sz) +{ + memset(pbuf, c, sz); +} + +static void _freertos_init_sema(_sema *sema, int init_val) +{ + *sema = xSemaphoreCreateCounting(0xffffffff, init_val); //Set max count 0xffffffff +} + +static void _freertos_free_sema(_sema *sema) +{ + if(*sema != NULL) + vSemaphoreDelete(*sema); + + *sema = NULL; +} + +static void _freertos_up_sema(_sema *sema) +{ + xSemaphoreGive(*sema); +} + +static void _freertos_up_sema_from_isr(_sema *sema) +{ + portBASE_TYPE taskWoken = pdFALSE; + xSemaphoreGiveFromISR(*sema, &taskWoken); + portEND_SWITCHING_ISR(taskWoken); +} + +static u32 _freertos_down_sema(_sema *sema, u32 timeout) +{ + if(timeout == RTW_MAX_DELAY) { + timeout = portMAX_DELAY; + } else { + timeout = rtw_ms_to_systime(timeout); + } + + if(xSemaphoreTake(*sema, timeout) != pdTRUE) { + return pdFALSE; + } + + return pdTRUE; +} + +static void _freertos_mutex_init(_mutex *pmutex) +{ + *pmutex = xSemaphoreCreateMutex(); +} + +static void _freertos_mutex_free(_mutex *pmutex) +{ + if(*pmutex != NULL) + vSemaphoreDelete(*pmutex); + + *pmutex = NULL; +} + +static void _freertos_mutex_get(_lock *plock) +{ + while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE) + DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock); +} + +static int _freertos_mutex_get_timeout(_lock *plock, u32 timeout_ms) +{ + if(xSemaphoreTake(*plock, timeout_ms / portTICK_RATE_MS) != pdTRUE){ + DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock); + return -1; + } + return 0; +} + +static void _freertos_mutex_put(_lock *plock) +{ + xSemaphoreGive(*plock); +} + +static void _freertos_enter_critical(_lock *plock, _irqL *pirqL) +{ + taskENTER_CRITICAL(); +} + +static void _freertos_exit_critical(_lock *plock, _irqL *pirqL) +{ + taskEXIT_CRITICAL(); +} + +static u32 uxSavedInterruptStatus = 0; +static void _freertos_enter_critical_from_isr(_lock *plock, _irqL *pirqL) +{ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); +} + +static void _freertos_exit_critical_from_isr(_lock *plock, _irqL *pirqL) +{ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); +} + +static int _freertos_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + int ret = 0; + + while(xSemaphoreTake(*pmutex, 60 * 1000 / portTICK_RATE_MS) != pdTRUE) + printf("\n\r[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, pmutex); + + return ret; +} + +static void _freertos_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ + xSemaphoreGive(*pmutex); +} + +static void _freertos_spinlock_init(_lock *plock) +{ +#if USE_MUTEX_FOR_SPINLOCK + *plock = xSemaphoreCreateMutex(); +#endif +} + +static void _freertos_spinlock_free(_lock *plock) +{ +#if USE_MUTEX_FOR_SPINLOCK + if(*plock != NULL) + vSemaphoreDelete(*plock); + + *plock = NULL; +#endif +} + +static void _freertos_spinlock(_lock *plock) +{ +#if USE_MUTEX_FOR_SPINLOCK + while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE) + DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock); +#endif +} + +static void _freertos_spinunlock(_lock *plock) +{ +#if USE_MUTEX_FOR_SPINLOCK + xSemaphoreGive(*plock); +#endif +} + +static void _freertos_spinlock_irqsave(_lock *plock, _irqL *irqL) +{ + taskENTER_CRITICAL(); +#if USE_MUTEX_FOR_SPINLOCK + while(xSemaphoreTake(*plock, 60 * 1000 / portTICK_RATE_MS) != pdTRUE) + DBG_ERR("[%s] %s(%p) failed, retry\n", pcTaskGetTaskName(NULL), __FUNCTION__, plock); +#endif +} + +static void _freertos_spinunlock_irqsave(_lock *plock, _irqL *irqL) +{ +#if USE_MUTEX_FOR_SPINLOCK + xSemaphoreGive(*plock); +#endif + taskEXIT_CRITICAL(); +} + +static int _freertos_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages ) +{ + if ( ( *queue = xQueueCreate( number_of_messages, message_size ) ) == NULL ) + { + return -1; + } + + return 0; +} + +static int _freertos_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ + if(timeout_ms == RTW_MAX_DELAY) { + timeout_ms = portMAX_DELAY; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + + if ( xQueueSendToBack( *queue, message, timeout_ms ) != pdPASS ) + { + return -1; + } + + return 0; +} + +static int _freertos_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ + if(timeout_ms == RTW_WAIT_FOREVER) { + timeout_ms = portMAX_DELAY; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + + if ( xQueueReceive( *queue, message, timeout_ms ) != pdPASS ) + { + return -1; + } + + return 0; +} + +static int _freertos_deinit_xqueue( _xqueue* queue ) +{ + int result = 0; + + if( uxQueueMessagesWaiting( queue ) ) + { + result = -1; + } + vQueueDelete( *queue ); + return result; +} + +static u32 _freertos_get_current_time(void) +{ + return xTaskGetTickCount(); //The count of ticks since vTaskStartScheduler was called. +} + +static u32 _freertos_systime_to_ms(u32 systime) +{ + return systime * portTICK_RATE_MS; +} + +static u32 _freertos_systime_to_sec(u32 systime) +{ + return systime / configTICK_RATE_HZ; +} + +static u32 _freertos_ms_to_systime(u32 ms) +{ + return ms / portTICK_RATE_MS; +} + +static u32 _freertos_sec_to_systime(u32 sec) +{ + return sec * configTICK_RATE_HZ; +} + +static void _freertos_msleep_os(int ms) +{ +#if defined(CONFIG_PLATFORM_8195A) + vTaskDelay(ms / portTICK_RATE_MS); +#elif defined(CONFIG_PLATFORM_8711B) + if (pmu_yield_os_check()) { + vTaskDelay(ms / portTICK_RATE_MS); + } else { + DelayMs(ms); + } +#endif +} + +static void _freertos_usleep_os(int us) +{ +#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F10X_XL) + // FreeRTOS does not provide us level delay. Use busy wait + WLAN_BSP_UsLoop(us); +#elif defined(CONFIG_PLATFORM_8195A) + //DBG_ERR("%s: Please Implement micro-second delay\n", __FUNCTION__); +#elif defined(CONFIG_PLATFORM_8711B) + DelayUs(us); +#else + #error "Please implement hardware dependent micro second level sleep here" +#endif +} + +static void _freertos_mdelay_os(int ms) +{ + vTaskDelay(ms / portTICK_RATE_MS); +} + +static void _freertos_udelay_os(int us) +{ +#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F10X_XL) + // FreeRTOS does not provide us level delay. Use busy wait + WLAN_BSP_UsLoop(us); +#elif defined(CONFIG_PLATFORM_8195A) + HalDelayUs(us); +#elif defined(CONFIG_PLATFORM_8711B) + DelayUs(us); +#else + #error "Please implement hardware dependent micro second level sleep here" +#endif +} + +static void _freertos_yield_os(void) +{ +#if defined(CONFIG_PLATFORM_8195A) + taskYIELD(); +#elif defined(CONFIG_PLATFORM_8711B) + if (pmu_yield_os_check()) { + taskYIELD(); + } else { + DelayMs(1); + } +#endif +} + +static void _freertos_ATOMIC_SET(ATOMIC_T *v, int i) +{ + atomic_set(v,i); +} + +static int _freertos_ATOMIC_READ(ATOMIC_T *v) +{ + return atomic_read(v); +} + +static void _freertos_ATOMIC_ADD(ATOMIC_T *v, int i) +{ + save_and_cli(); + v->counter += i; + restore_flags(); +} + +static void _freertos_ATOMIC_SUB(ATOMIC_T *v, int i) +{ + save_and_cli(); + v->counter -= i; + restore_flags(); +} + +static void _freertos_ATOMIC_INC(ATOMIC_T *v) +{ + _freertos_ATOMIC_ADD(v, 1); +} + +static void _freertos_ATOMIC_DEC(ATOMIC_T *v) +{ + _freertos_ATOMIC_SUB(v, 1); +} + +static int _freertos_ATOMIC_ADD_RETURN(ATOMIC_T *v, int i) +{ + int temp; + + save_and_cli(); + temp = v->counter; + temp += i; + v->counter = temp; + restore_flags(); + + return temp; +} + +static int _freertos_ATOMIC_SUB_RETURN(ATOMIC_T *v, int i) +{ + int temp; + + save_and_cli(); + temp = v->counter; + temp -= i; + v->counter = temp; + restore_flags(); + + return temp; +} + +static int _freertos_ATOMIC_INC_RETURN(ATOMIC_T *v) +{ + return _freertos_ATOMIC_ADD_RETURN(v, 1); +} + +static int _freertos_ATOMIC_DEC_RETURN(ATOMIC_T *v) +{ + return _freertos_ATOMIC_SUB_RETURN(v, 1); +} + +static u64 _freertos_modular64(u64 n, u64 base) +{ + unsigned int __base = (base); + unsigned int __rem; + + if (((n) >> 32) == 0) { + __rem = (unsigned int)(n) % __base; + (n) = (unsigned int)(n) / __base; + } + else + __rem = __div64_32(&(n), __base); + + return __rem; +} + +/* Refer to ecos bsd tcpip codes */ +static int _freertos_arc4random(void) +{ + u32 res = xTaskGetTickCount(); + static unsigned long seed = 0xDEADB00B; + +#if CONFIG_PLATFORM_8711B + if(random_seed){ + seed = random_seed; + random_seed = 0; + } +#endif + + seed = ((seed & 0x007F00FF) << 7) ^ + ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits + (res << 13) ^ (res >> 9); // using the clock too! + return (int)seed; +} + +static int _freertos_get_random_bytes(void *buf, size_t len) +{ +#if 1 //becuase of 4-byte align, we use the follow code style. + unsigned int ranbuf; + unsigned int *lp; + int i, count; + count = len / sizeof(unsigned int); + lp = (unsigned int *) buf; + + for(i = 0; i < count; i ++) { + lp[i] = _freertos_arc4random(); + len -= sizeof(unsigned int); + } + + if(len > 0) { + ranbuf = _freertos_arc4random(); + _freertos_memcpy(&lp[i], &ranbuf, len); + } + return 0; +#else + unsigned long ranbuf, *lp; + lp = (unsigned long *)buf; + while (len > 0) { + ranbuf = _freertos_arc4random(); + *lp++ = ranbuf; //this op need the pointer is 4Byte-align! + len -= sizeof(ranbuf); + } + return 0; +#endif +} + +static u32 _freertos_GetFreeHeapSize(void) +{ + return (u32)xPortGetFreeHeapSize(); +} +void *tcm_heap_malloc(int size); +static int _freertos_create_task(struct task_struct *ptask, const char *name, + u32 stack_size, u32 priority, thread_func_t func, void *thctx) +{ + thread_func_t task_func = NULL; + void *task_ctx = NULL; + int ret = 0; + + ptask->task_name = name; + ptask->blocked = 0; + ptask->callback_running = 0; + + _freertos_init_sema(&ptask->wakeup_sema, 0); + _freertos_init_sema(&ptask->terminate_sema, 0); + //rtw_init_queue(&wq->work_queue); + + if(func){ + task_func = func; + task_ctx = thctx; + } + //else{ + // task_func = freertos_wq_thread_handler; + // task_ctx = wq; + //} + + priority += tskIDLE_PRIORITY + PRIORITIE_OFFSET; + + if(rtw_if_wifi_thread(name) == 0){ + +#if CONFIG_USE_TCM_HEAP + void *stack_addr = tcm_heap_malloc(stack_size*sizeof(int)); + //void *stack_addr = rtw_malloc(stack_size*sizeof(int)); + if(stack_addr == NULL){ + DBG_INFO("Out of TCM heap in \"%s\" ", ptask->task_name); + } + ret = xTaskGenericCreate( + task_func, + (const char *)name, + stack_size, + task_ctx, + priority, + &ptask->task, + stack_addr, + NULL); +#else + ret = xTaskCreate( + task_func, + (const char *)name, + stack_size, + task_ctx, + priority, + &ptask->task); +#endif + } + else{ + ret = xTaskCreate( + task_func, + (const char *)name, + stack_size, + task_ctx, + priority, + &ptask->task); + + } + if(ret != pdPASS){ + DBG_ERR("Create Task \"%s\" Failed! ret=%d\n", ptask->task_name, ret); + } + + DBG_TRACE("Create Task \"%s\"\n", ptask->task_name); + return ret; +} + +static void _freertos_delete_task(struct task_struct *ptask) +{ + if (!ptask->task){ + DBG_ERR("_freertos_delete_task(): ptask is NULL!\n"); + return; + } + + ptask->blocked = 1; + + _freertos_up_sema(&ptask->wakeup_sema); + _freertos_down_sema(&ptask->terminate_sema, TIMER_MAX_DELAY); + + //rtw_deinit_queue(&wq->work_queue); + _freertos_free_sema(&ptask->wakeup_sema); + _freertos_free_sema(&ptask->terminate_sema); + + ptask->task = 0; + + DBG_TRACE("Delete Task \"%s\"\n", ptask->task_name); +} + +void _freertos_wakeup_task(struct task_struct *ptask) +{ + _freertos_up_sema(&ptask->wakeup_sema); +} + +static void _freertos_thread_enter(char *name) +{ + DBG_INFO("\n\rRTKTHREAD %s\n", name); +} + +static void _freertos_thread_exit(void) +{ + DBG_INFO("\n\rRTKTHREAD exit %s\n", __FUNCTION__); + vTaskDelete(NULL); +} + +_timerHandle _freertos_timerCreate( const signed char *pcTimerName, + osdepTickType xTimerPeriodInTicks, + u32 uxAutoReload, + void * pvTimerID, + TIMER_FUN pxCallbackFunction ) +{ + if(xTimerPeriodInTicks == TIMER_MAX_DELAY) { + xTimerPeriodInTicks = portMAX_DELAY; + } + return xTimerCreate((const char *)pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction); +} + +u32 _freertos_timerDelete( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + return (u32)xTimerDelete(xTimer, xBlockTime); +} + +u32 _freertos_timerIsTimerActive( _timerHandle xTimer ) +{ + return (u32)xTimerIsTimerActive(xTimer); +} + +u32 _freertos_timerStop( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + return (u32)xTimerStop(xTimer, xBlockTime); +} + +u32 _freertos_timerChangePeriod( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepTickType xBlockTime ) +{ + if(xNewPeriod == 0) + xNewPeriod += 1; + return (u32)xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime); +} +void *_freertos_timerGetID( _timerHandle xTimer ){ + + return pvTimerGetTimerID(xTimer); +} + +u32 _freertos_timerStart( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + return (u32)xTimerStart(xTimer, xBlockTime); +} + +u32 _freertos_timerStartFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + return (u32)xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken); +} + +u32 _freertos_timerStopFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + return (u32)xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken); +} + +u32 _freertos_timerResetFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + return (u32)xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken); +} + +u32 _freertos_timerChangePeriodFromISR( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + if(xNewPeriod == 0) + xNewPeriod += 1; + return (u32)xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken); +} + +u32 _freertos_timerReset( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + return (u32)xTimerReset(xTimer, xBlockTime); +} + +void _freertos_acquire_wakelock() +{ +#if defined(CONFIG_PLATFORM_8195A) + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + pmu_acquire_wakelock(PMU_WLAN_DEVICE); +#endif + +#elif defined(CONFIG_PLATFORM_8711B) + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + if (pmu_yield_os_check()) + pmu_acquire_wakelock(PMU_WLAN_DEVICE); +#endif + +#endif +} + +void _freertos_release_wakelock() +{ + +#if defined(CONFIG_PLATFORM_8195A) + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + pmu_release_wakelock(PMU_WLAN_DEVICE); +#endif + +#elif defined(CONFIG_PLATFORM_8711B) + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + if (pmu_yield_os_check()) + pmu_release_wakelock(PMU_WLAN_DEVICE); +#endif + +#endif +} + +void _freertos_wakelock_timeout(uint32_t timeout) +{ +#if defined(CONFIG_PLATFORM_8195A) + +#elif defined(CONFIG_PLATFORM_8711B) + if (pmu_yield_os_check()) + pmu_set_sysactive_time(PMU_WLAN_DEVICE, timeout); + else + DBG_INFO("can't aquire wake during suspend flow!!\n"); +#endif +} + +u8 _freertos_get_scheduler_state(void) +{ + u8 state = xTaskGetSchedulerState(); + switch(state){ + case taskSCHEDULER_NOT_STARTED: state = OS_SCHEDULER_NOT_STARTED; break; + case taskSCHEDULER_RUNNING: state = OS_SCHEDULER_RUNNING; break; + case taskSCHEDULER_SUSPENDED: state = OS_SCHEDULER_SUSPENDED; break; + } + return state; +} + + +const struct osdep_service_ops osdep_service = { + _freertos_malloc, //rtw_vmalloc + _freertos_zmalloc, //rtw_zvmalloc + _freertos_mfree, //rtw_vmfree + _freertos_malloc, //rtw_malloc + _freertos_zmalloc, //rtw_zmalloc + _freertos_mfree, //rtw_mfree + _freertos_memcpy, //rtw_memcpy + _freertos_memcmp, //rtw_memcmp + _freertos_memset, //rtw_memset + _freertos_init_sema, //rtw_init_sema + _freertos_free_sema, //rtw_free_sema + _freertos_up_sema, //rtw_up_sema + _freertos_up_sema_from_isr, //rtw_up_sema_from_isr + _freertos_down_sema, //rtw_down_sema + _freertos_mutex_init, //rtw_mutex_init + _freertos_mutex_free, //rtw_mutex_free + _freertos_mutex_get, //rtw_mutex_get + _freertos_mutex_get_timeout,//rtw_mutex_get_timeout + _freertos_mutex_put, //rtw_mutex_put + _freertos_enter_critical, //rtw_enter_critical + _freertos_exit_critical, //rtw_exit_critical + _freertos_enter_critical_from_isr, //rtw_enter_critical_from_isr + _freertos_exit_critical_from_isr, //rtw_exit_critical_from_isr + NULL, //rtw_enter_critical_bh + NULL, //rtw_exit_critical_bh + _freertos_enter_critical_mutex, //rtw_enter_critical_mutex + _freertos_exit_critical_mutex, //rtw_exit_critical_mutex + _freertos_spinlock_init, //rtw_spinlock_init + _freertos_spinlock_free, //rtw_spinlock_free + _freertos_spinlock, //rtw_spin_lock + _freertos_spinunlock, //rtw_spin_unlock + _freertos_spinlock_irqsave, //rtw_spinlock_irqsave + _freertos_spinunlock_irqsave, //rtw_spinunlock_irqsave + _freertos_init_xqueue, //rtw_init_xqueue + _freertos_push_to_xqueue, //rtw_push_to_xqueue + _freertos_pop_from_xqueue, //rtw_pop_from_xqueue + _freertos_deinit_xqueue, //rtw_deinit_xqueue + _freertos_get_current_time, //rtw_get_current_time + _freertos_systime_to_ms, //rtw_systime_to_ms + _freertos_systime_to_sec, //rtw_systime_to_sec + _freertos_ms_to_systime, //rtw_ms_to_systime + _freertos_sec_to_systime, //rtw_sec_to_systime + _freertos_msleep_os, //rtw_msleep_os + _freertos_usleep_os, //rtw_usleep_os + _freertos_mdelay_os, //rtw_mdelay_os + _freertos_udelay_os, //rtw_udelay_os + _freertos_yield_os, //rtw_yield_os + + _freertos_ATOMIC_SET, //ATOMIC_SET + _freertos_ATOMIC_READ, //ATOMIC_READ + _freertos_ATOMIC_ADD, //ATOMIC_ADD + _freertos_ATOMIC_SUB, //ATOMIC_SUB + _freertos_ATOMIC_INC, //ATOMIC_INC + _freertos_ATOMIC_DEC, //ATOMIC_DEC + _freertos_ATOMIC_ADD_RETURN, //ATOMIC_ADD_RETURN + _freertos_ATOMIC_SUB_RETURN, //ATOMIC_SUB_RETURN + _freertos_ATOMIC_INC_RETURN, //ATOMIC_INC_RETURN + _freertos_ATOMIC_DEC_RETURN, //ATOMIC_DEC_RETURN + + _freertos_modular64, //rtw_modular64 + _freertos_get_random_bytes, //rtw_get_random_bytes + _freertos_GetFreeHeapSize, //rtw_getFreeHeapSize + + _freertos_create_task, //rtw_create_task + _freertos_delete_task, //rtw_delete_task + _freertos_wakeup_task, //rtw_wakeup_task + + _freertos_thread_enter, //rtw_thread_enter + _freertos_thread_exit, //rtw_thread_exit + + _freertos_timerCreate, //rtw_timerCreate, + _freertos_timerDelete, //rtw_timerDelete, + _freertos_timerIsTimerActive, //rtw_timerIsTimerActive, + _freertos_timerStop, //rtw_timerStop, + _freertos_timerChangePeriod, //rtw_timerChangePeriod + _freertos_timerGetID, //rtw_timerGetID + _freertos_timerStart, //rtw_timerStart + _freertos_timerStartFromISR, //rtw_timerStartFromISR + _freertos_timerStopFromISR, //rtw_timerStopFromISR + _freertos_timerResetFromISR, //rtw_timerResetFromISR + _freertos_timerChangePeriodFromISR, //rtw_timerChangePeriodFromISR + _freertos_timerReset, //rtw_timerReset + + _freertos_acquire_wakelock, //rtw_acquire_wakelock + _freertos_release_wakelock, //rtw_release_wakelock + _freertos_wakelock_timeout, //rtw_wakelock_timeout + _freertos_get_scheduler_state //rtw_get_scheduler_state +}; diff --git a/USDK/component/os/freertos/freertos_service.h b/USDK/component/os/freertos/freertos_service.h new file mode 100644 index 0000000..9573cdc --- /dev/null +++ b/USDK/component/os/freertos/freertos_service.h @@ -0,0 +1,258 @@ +#ifndef _FREERTOS_SERVICE_H_ +#define _FREERTOS_SERVICE_H_ + +//----- ------------------------------------------------------------------ +// Include Files +//----- ------------------------------------------------------------------ +//#include "wireless.h" +#include "dlist.h" + +// -------------------------------------------- +// Platform dependent include file +// -------------------------------------------- +#if defined(CONFIG_PLATFORM_8195A) +#include "platform/platform_stdlib.h" +extern VOID RtlUdelayOS(u32 us); +#elif defined(CONFIG_PLATFORM_8711B) +#include "platform/platform_stdlib.h" +#else +// other MCU may use standard library +#include +#endif + + +#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) || defined(CONFIG_LX_HCI) +/* For SPI interface transfer and us delay implementation */ +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#include +#endif +#endif + + +// -------------------------------------------- +// Platform dependent type define +// -------------------------------------------- +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; +typedef unsigned long long u64; +typedef unsigned int uint; +typedef signed int sint; + +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif + +#define IN +#define OUT +#define VOID void +#define NDIS_OID uint +#define NDIS_STATUS uint +#ifndef PVOID +typedef void * PVOID; +#endif + +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef __kernel_size_t SIZE_T; +typedef __kernel_ssize_t SSIZE_T; + +#endif //CONFIG_PLATFORM_8195A + +#define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +// os types +typedef char osdepCHAR; +typedef float osdepFLOAT; +typedef double osdepDOUBLE; +typedef long osdepLONG; +typedef short osdepSHORT; +typedef unsigned long osdepSTACK_TYPE; +typedef long osdepBASE_TYPE; +typedef unsigned long osdepTickType; + +typedef void* _timerHandle; +typedef void* _sema; +typedef void* _mutex; +typedef void* _lock; +typedef void* _queueHandle; +typedef void* _xqueue; +typedef struct timer_list _timer; + +typedef struct sk_buff _pkt; +typedef unsigned char _buffer; + +#ifndef __LIST_H +#warning "DLIST_NOT_DEFINE!!!!!!" +struct list_head { + struct list_head *next, *prev; +}; +#endif + +struct __queue { + struct list_head queue; + _lock lock; +}; + +typedef struct __queue _queue; +typedef struct list_head _list; +typedef unsigned long _irqL; + +typedef void* _thread_hdl_; +typedef void thread_return; +typedef void* thread_context; + +#define ATOMIC_T atomic_t +#define HZ configTICK_RATE_HZ + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +/* emulate a modern version */ +#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 17) + +static __inline _list *get_next(_list *list) +{ + return list->next; +} + +static __inline _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr))) +//#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n)) +#define container_of(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#define TASK_PRORITY_LOW 1 +#define TASK_PRORITY_MIDDLE 2 +#define TASK_PRORITY_HIGH 3 +#define TASK_PRORITY_SUPER 4 + +#define TIMER_MAX_DELAY 0xFFFFFFFF + +void save_and_cli(void); +void restore_flags(void); +void cli(void); + +#ifndef mdelay +#define mdelay(t) ((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1)) +#endif + +#ifndef udelay +#define udelay(t) ((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1)) +#endif +//----- ------------------------------------------------------------------ +// Common Definition +//----- ------------------------------------------------------------------ + +#define __init +#define __exit +#define __devinit +#define __devexit + +#define KERN_ERR +#define KERN_INFO +#define KERN_NOTICE + +#undef GFP_KERNEL +#define GFP_KERNEL 1 +#define GFP_ATOMIC 1 + +#define SET_MODULE_OWNER(some_struct) do { } while (0) +#define SET_NETDEV_DEV(dev, obj) do { } while (0) +#define register_netdev(dev) (0) +#define unregister_netdev(dev) do { } while (0) +#define netif_queue_stopped(dev) (0) +#define netif_wake_queue(dev) do { } while (0) +#define printk printf + +#define DBG_ERR(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#if WLAN_INTF_DBG +#define DBG_TRACE(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#define DBG_INFO(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#else +#define DBG_TRACE(fmt, args...) +#define DBG_INFO(fmt, args...) +#endif +#define HALT() do { cli(); for(;;);} while(0) +#undef ASSERT +#define ASSERT(x) do { \ + if((x) == 0) \ + printf("\n\rAssert(" #x ") failed on line %d in file %s", __LINE__, __FILE__); \ + HALT(); \ + } while(0) + +#undef DBG_ASSERT +#define DBG_ASSERT(x, msg) do { \ + if((x) == 0) \ + printf("\n\r%s, Assert(" #x ") failed on line %d in file %s", msg, __LINE__, __FILE__); \ + } while(0) + +//----- ------------------------------------------------------------------ +// Atomic Operation +//----- ------------------------------------------------------------------ +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) // for 8195A, it is defined in ..system../basic_types.h +typedef struct { volatile int counter; } atomic_t; +#endif + + +/* + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#undef atomic_read +#define atomic_read(v) ((v)->counter) + +/* + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#undef atomic_set +#define atomic_set(v,i) ((v)->counter = (i)) + + /* + * These inlines deal with timer wrapping correctly. You are + * strongly encouraged to use them + * 1. Because people otherwise forget + * 2. Because if the timer wrap changes in future you wont have to + * alter your driver code. + * + * time_after(a,b) returns true if the time a is after time b. + * + * Do this with "<0" and ">=0" to only test the sign of the result. A + * good compiler would generate better code (and a really good compiler + * wouldn't care). Gcc is currently neither. + */ + #define time_after(a,b) ((long)(b) - (long)(a) < 0) + #define time_before(a,b) time_after(b,a) + + #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) + #define time_before_eq(a,b) time_after_eq(b,a) + + +extern void rtw_init_listhead(_list *list); +extern u32 rtw_is_list_empty(_list *phead); +extern void rtw_list_insert_head(_list *plist, _list *phead); +extern void rtw_list_insert_tail(_list *plist, _list *phead); +extern void rtw_list_delete(_list *plist); + +#if CONFIG_PLATFORM_8711B +extern u32 random_seed; +#endif + +#endif /* _FREERTOS_SERVICE_H_ */ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/BlockQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/BlockQ.c new file mode 100644 index 0000000..e6d56eb --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/BlockQ.c @@ -0,0 +1,346 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + * \page BlockQC blockQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + Reversed the priority and block times of the second two demo tasks so + they operate as per the description above. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V4.0.2 + + + The second set of tasks were created the wrong way around. This has been + corrected. +*/ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" +#include "print.h" + +#define blckqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + QueueHandle_t xQueue; /*< The queue to be used by the task. */ + TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static void vBlockingQueueProducer( void *pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static void vBlockingQueueConsumer( void *pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; +const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +const TickType_t xDontBlock = ( TickType_t ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueProducer( void *pvParameters ) +{ +unsigned short usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const char * const pcTaskStartMsg = "Blocking queue producer started.\r\n"; +const char * const pcTaskErrorMsg = "Could not post on blocking queue\r\n"; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xQueueSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueConsumer( void *pvParameters ) +{ +unsigned short usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const char * const pcTaskStartMsg = "Blocking queue consumer started.\r\n"; +const char * const pcTaskErrorMsg = "Incorrect value received on blocking queue.\r\n"; +short sErrorEverOccurred = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreBlockingQueuesStillRunning( void ) +{ +static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; +static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; +portBASE_TYPE xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/PollQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/PollQ.c new file mode 100644 index 0000000..6148a80 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/PollQ.c @@ -0,0 +1,258 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/** + * This is a very simple queue test. See the BlockQ. c documentation for a more + * comprehensive version. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + * + * \page PollQC pollQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "print.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) + +/* The task that posts the incrementing number onto the queue. */ +static void vPolledQueueProducer( void *pvParameters ); + +/* The task that empties the queue. */ +static void vPolledQueueConsumer( void *pvParameters ); + +/* Variables that are used to check that the tasks are still running with no errors. */ +static volatile short sPollingConsumerCount = 0, sPollingProducerCount = 0; +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +static QueueHandle_t xPolledQueue; +const unsigned portBASE_TYPE uxQueueSize = 10; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueProducer( void *pvParameters ) +{ +unsigned short usValue = 0, usLoop; +QueueHandle_t *pxQueue; +const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS; +const unsigned short usNumToProduce = 3; +const char * const pcTaskStartMsg = "Polled queue producer started.\r\n"; +const char * const pcTaskErrorMsg = "Could not post on polled queue.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( QueueHandle_t * ) pvParameters; + + for( ;; ) + { + for( usLoop = 0; usLoop < usNumToProduce; ++usLoop ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( TickType_t ) 0 ) != pdPASS ) + { + /* We should never find the queue full - this is an error. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + } + else + { + if( sError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + ++sPollingProducerCount; + } + + /* Update the value we are going to post next time around. */ + ++usValue; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueConsumer( void *pvParameters ) +{ +unsigned short usData, usExpectedValue = 0; +QueueHandle_t *pxQueue; +const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS; +const char * const pcTaskStartMsg = "Polled queue consumer started.\r\n"; +const char * const pcTaskErrorMsg = "Incorrect value received on polled queue.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( QueueHandle_t * ) pvParameters; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *pxQueue ) ) + { + if( xQueueReceive( *pxQueue, &usData, ( TickType_t ) 0 ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + /* Catch-up to the value we received so our next expected value + should again be correct. */ + usExpectedValue = usData; + } + else + { + if( sError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + ++sPollingConsumerCount; + } + } + ++usExpectedValue; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +portBASE_TYPE xArePollingQueuesStillRunning( void ) +{ +static short sLastPollingConsumerCount = 0, sLastPollingProducerCount = 0; +portBASE_TYPE xReturn; + + if( ( sLastPollingConsumerCount == sPollingConsumerCount ) || + ( sLastPollingProducerCount == sPollingProducerCount ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastPollingConsumerCount = sPollingConsumerCount; + sLastPollingProducerCount = sPollingProducerCount; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/comtest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/comtest.c new file mode 100644 index 0000000..92c1e5d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/comtest.c @@ -0,0 +1,384 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates two tasks that operate on an interrupt driven serial port. A loopback + * connector should be used so that everything that is transmitted is also received. + * The serial port does not use any flow control. On a standard 9way 'D' connector + * pins two and three should be connected together. + * + * The first task repeatedly sends a string to a queue, character at a time. The + * serial port interrupt will empty the queue and transmit the characters. The + * task blocks for a pseudo random period before resending the string. + * + * The second task blocks on a queue waiting for a character to be received. + * Characters received by the serial port interrupt routine are posted onto the + * queue - unblocking the task making it ready to execute. If this is then the + * highest priority task ready to run it will run immediately - with a context + * switch occurring at the end of the interrupt service routine. The task + * receiving characters is spawned with a higher priority than the task + * transmitting the characters. + * + * With the loop back connector in place, one task will transmit a string and the + * other will immediately receive it. The receiving task knows the string it + * expects to receive so can detect an error. + * + * This also creates a third task. This is used to test semaphore usage from an + * ISR and does nothing interesting. + * + * \page ComTestC comtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + The priority of the Rx task has been lowered. Received characters are + now processed (read from the queue) at the idle priority, allowing low + priority tasks to run evenly at times of a high communications overhead. + +Changes from V1.01: + + + The Tx task now waits a pseudo random time between transissions. + Previously a fixed period was used but this was not such a good test as + interrupts fired at regular intervals. + +Changes From V1.2.0: + + + Use vSerialPutString() instead of single character puts. + + Only stop the check variable incrementing after two consecutive errors. + +Changed from V1.2.5 + + + Made the Rx task 2 priorities higher than the Tx task. Previously it was + only 1. This is done to tie in better with the other demo application + tasks. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + + Slight modification to task priorities. + +*/ + + +/* Scheduler include files. */ +#include +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "print.h" + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x15e ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0xc8 ) + +#define comMAX_CONSECUTIVE_ERRORS ( 2 ) + +#define comSTACK_SIZE ( ( unsigned short ) 256 ) + +#define comRX_RELATIVE_PRIORITY ( 1 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort; + +/* The transmit function as described at the top of the file. */ +static void vComTxTask( void *pvParameters ); + +/* The receive function as described at the top of the file. */ +static void vComRxTask( void *pvParameters ); + +/* The semaphore test function as described at the top of the file. */ +static void vSemTestTask( void * pvParameters ); + +/* The string that is repeatedly transmitted. */ +const char * const pcMessageToExchange = "Send this message over and over again to check communications interrupts. " + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; + +/* Variables that are incremented on each cycle of each task. These are used to +check that both tasks are still executing. */ +volatile short sTxCount = 0, sRxCount = 0, sSemCount = 0; + +/* The handle to the semaphore test task. */ +static TaskHandle_t xSemTestTaskHandle = NULL; + +/*-----------------------------------------------------------*/ + +void vStartComTestTasks( unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate ) +{ +const unsigned portBASE_TYPE uxBufferLength = 255; + + /* Initialise the com port then spawn both tasks. */ + xPort = xSerialPortInit( ePort, eBaudRate, serNO_PARITY, serBITS_8, serSTOP_1, uxBufferLength ); + xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority, NULL ); + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority + comRX_RELATIVE_PRIORITY, NULL ); + xTaskCreate( vSemTestTask, "ISRSem", comSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xSemTestTaskHandle ); +} +/*-----------------------------------------------------------*/ + +static void vComTxTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "COM Tx task started.\r\n"; +TickType_t xTimeToWait; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Send the string to the serial port. */ + vSerialPutString( xPort, pcMessageToExchange, strlen( pcMessageToExchange ) ); + + /* We have posted all the characters in the string - increment the variable + used to check that this task is still running, then wait before re-sending + the string. */ + sTxCount++; + + xTimeToWait = xTaskGetTickCount(); + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vComRxTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "COM Rx task started.\r\n"; +const char * const pcTaskErrorMsg = "COM read error\r\n"; +const char * const pcTaskRestartMsg = "COM resynced\r\n"; +const char * const pcTaskTimeoutMsg = "COM Rx timed out\r\n"; +const TickType_t xBlockTime = ( TickType_t ) 0xffff / portTICK_PERIOD_MS; +const char *pcExpectedChar; +portBASE_TYPE xGotChar; +char cRxedChar; +short sResyncRequired, sConsecutiveErrors, sLatchedError; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The first expected character is the first character in the string. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + sConsecutiveErrors = 0; + sLatchedError = pdFALSE; + + for( ;; ) + { + /* Receive a message from the com port interrupt routine. If a message is + not yet available the call will block the task. */ + xGotChar = xSerialGetChar( xPort, &cRxedChar, xBlockTime ); + if( xGotChar == pdTRUE ) + { + if( sResyncRequired == pdTRUE ) + { + /* We got out of sequence and are waiting for the start of the next + transmission of the string. */ + if( cRxedChar == '\n' ) + { + /* This is the end of the message so we can start again - with + the first character in the string being the next thing we expect + to receive. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + + /* Queue a message for printing to say that we are going to try + again. */ + vPrintDisplayMessage( &pcTaskRestartMsg ); + + /* Stop incrementing the check variable, if consecutive errors occur. */ + sConsecutiveErrors++; + if( sConsecutiveErrors >= comMAX_CONSECUTIVE_ERRORS ) + { + sLatchedError = pdTRUE; + } + } + } + else + { + /* We have received a character, but is it the expected character? */ + if( cRxedChar != *pcExpectedChar ) + { + /* This was not the expected character so post a message for + printing to say that an error has occurred. We will then wait + to resynchronise. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sResyncRequired = pdTRUE; + } + else + { + /* This was the expected character so next time we will expect + the next character in the string. Wrap back to the beginning + of the string when the null terminator has been reached. */ + pcExpectedChar++; + if( *pcExpectedChar == '\0' ) + { + pcExpectedChar = pcMessageToExchange; + + /* We have got through the entire string without error. */ + sConsecutiveErrors = 0; + } + } + } + + /* Increment the count that is used to check that this task is still + running. This is only done if an error has never occurred. */ + if( sLatchedError == pdFALSE ) + { + sRxCount++; + } + } + else + { + vPrintDisplayMessage( &pcTaskTimeoutMsg ); + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vSemTestTask( void * pvParameters ) +{ +const char * const pcTaskStartMsg = "ISR Semaphore test started.\r\n"; +portBASE_TYPE xError = pdFALSE; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xSerialWaitForSemaphore( xPort ) ) + { + if( xError == pdFALSE ) + { + sSemCount++; + } + } + else + { + xError = pdTRUE; + } + } +} /*lint !e715 !e830 !e818 pvParameters not used but function prototype must be standard for task function. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreComTestTasksStillRunning( void ) +{ +static short sLastTxCount = 0, sLastRxCount = 0, sLastSemCount = 0; +portBASE_TYPE xReturn; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. */ + + if( ( sTxCount == sLastTxCount ) || ( sRxCount == sLastRxCount ) || ( sSemCount == sLastSemCount ) ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastTxCount = sTxCount; + sLastRxCount = sRxCount; + sLastSemCount = sSemCount; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vComTestUnsuspendTask( void ) +{ + /* The task that is suspended on the semaphore will be referenced from the + Suspended list as it is blocking indefinitely. This call just checks that + the kernel correctly detects this and does not attempt to unsuspend the + task. */ + xTaskResumeFromISR( xSemTestTaskHandle ); +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/death.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/death.c new file mode 100644 index 0000000..aaf4cff --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/death.c @@ -0,0 +1,241 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * four tasks. The original task is called the creator task, the four tasks it + * creates are called suicidal tasks. + * + * Two of the created suicidal tasks kill one other suicidal task before killing + * themselves - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" +#include "print.h" + +#define deathSTACK_SIZE ( ( unsigned short ) 512 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static void vCreateTasks( void *pvParameters ); + +/* The task function of the dynamically created tasks. */ +static void vSuicidalTask( void *pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile short sCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. */ +static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0; +static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5; + +/* Used to store a handle to the tasks that should be killed by a suicidal task, +before it kills itself. */ +TaskHandle_t xCreatedTask1, xCreatedTask2; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE *puxPriority; + + /* Create the Creator tasks - passing in as a parameter the priority at which + the suicidal tasks should be created. */ + puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) ); + *puxPriority = uxPriority; + + xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = uxTaskGetNumberOfTasks(); +} +/*-----------------------------------------------------------*/ + +static void vSuicidalTask( void *pvParameters ) +{ +portDOUBLE d1, d2; +TaskHandle_t xTaskToKill; +const TickType_t xDelay = ( TickType_t ) 500 / portTICK_PERIOD_MS; + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Tow created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( TaskHandle_t* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + d1 = 2.4; + d2 = 89.2; + d2 *= d1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( TickType_t ) 0 ); + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static void vCreateTasks( void *pvParameters ) +{ +const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +unsigned portBASE_TYPE uxPriority; +const char * const pcTaskStartMsg = "Create task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + uxPriority = *( unsigned portBASE_TYPE * ) pvParameters; + vPortFree( pvParameters ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL ); + + ++sCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +portBASE_TYPE xIsCreateTaskStillRunning( void ) +{ +static short sLastCreationCount = 0; +short sReturn = pdTRUE; +unsigned portBASE_TYPE uxTasksRunningNow; + + if( sLastCreationCount == sCreationCount ) + { + sReturn = pdFALSE; + } + + uxTasksRunningNow = uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + sReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + sReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return sReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/dynamic.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/dynamic.c new file mode 100644 index 0000000..294743d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/dynamic.c @@ -0,0 +1,616 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises it's priority above that of the controller task before each + * increment, lowering it again to it's original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of it's loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume (). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from it's suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + * + * The final set of two tasks implements a third test. This simply raises the + * priority of a task while the scheduler is suspended. Again this test was + * added to exercise parts of the code not covered by the first test. + * + * \page Priorities dynamic.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + + Added a second, simple test that uses the functions + vQueueReceiveWhenSuspendedTask() and vQueueSendWhenSuspendedTask(). + +Changes from V3.1.1 + + + Added a third simple test that uses the vTaskPrioritySet() function + while the scheduler is suspended. + + Modified the controller task slightly to test the calling of + vTaskResumeAll() while the scheduler is suspended. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" +#include "print.h" + +/* Function that implements the "limited count" task as described above. */ +static void vLimitedIncrementTask( void * pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static void vContinuousIncrementTask( void * pvParameters ); + +/* Function that implements the controller task as described above. */ +static void vCounterControlTask( void * pvParameters ); + +/* The simple test functions that check sending and receiving while the +scheduler is suspended. */ +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ); +static void vQueueSendWhenSuspendedTask( void *pvParameters ); + +/* The simple test functions that check raising and lowering of task priorities +while the scheduler is suspended. */ +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ); +static void prvChangePriorityHelperTask( void *pvParameters ); + + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME ( ( TickType_t ) 50 ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( unsigned long ) 0xff ) +#define priNO_BLOCK ( ( TickType_t ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle, xChangePriorityWhenSuspendedHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static unsigned long ulCounter; + +/* Variable used in a similar way by the test that checks the raising and +lowering of task priorities while the scheduler is suspended. */ +static unsigned long ulPrioritySetCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static unsigned short usCheckVariable = ( unsigned short ) 0; +static portBASE_TYPE xSuspendedQueueSendError = pdFALSE; +static portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE; +static portBASE_TYPE xPriorityRaiseWhenSuspendedError = pdFALSE; + +/* Queue used by the second test. */ +QueueHandle_t xSuspendedTestQueue; + +/*-----------------------------------------------------------*/ +/* + * Start the seven tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) ); + xTaskCreate( vContinuousIncrementTask, "CONT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_SEND", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RECV", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvChangePriorityWhenSuspendedTask, "1st_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL ); + xTaskCreate( prvChangePriorityHelperTask, "2nd_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle ); +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static void vLimitedIncrementTask( void * pvParameters ) +{ +unsigned long *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned long * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static void vContinuousIncrementTask( void * pvParameters ) +{ +unsigned long *pulCounter; +unsigned portBASE_TYPE uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned long * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise our priority above the controller task to ensure a context + switch does not occur while we are accessing this variable. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + ( *pulCounter )++; + vTaskPrioritySet( NULL, uxOurPriority ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static void vCounterControlTask( void * pvParameters ) +{ +unsigned long ulLastCounter; +short sLoops; +short sError = pdFALSE; +const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n"; +const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( unsigned long ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. */ + vTaskSuspend( xContinuousIncrementHandle ); + ulLastCounter = ulCounter; + vTaskResume( xContinuousIncrementHandle ); + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + } + xTaskResumeAll(); + } + + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared variable. */ + vTaskSuspend( xContinuousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( unsigned long ) 0; + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. + The scheduler suspension is not necessary but is included for test + purposes. */ + vTaskSuspendAll(); + vTaskResume( xLimitedIncrementHandle ); + xTaskResumeAll(); + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinuousIncrementHandle ); + } +} +/*-----------------------------------------------------------*/ + +static void vQueueSendWhenSuspendedTask( void *pvParameters ) +{ +static unsigned long ulValueToSend = ( unsigned long ) 0; +const char * const pcTaskStartMsg = "Queue send while suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Queue send while suspended failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + if( xSuspendedQueueSendError == pdFALSE ) + { + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ) +{ +static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue; +const char * const pcTaskStartMsg = "Queue receive while suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Queue receive while suspended failed.\r\n"; +portBASE_TYPE xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + if( xSuspendedQueueReceiveError == pdFALSE ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + } + xSuspendedQueueReceiveError = pdTRUE; + } + + ++ulExpectedValue; + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at 0 so we know what the counter should be + when we check it next. */ + ulPrioritySetCounter = ( unsigned long ) 0; + + /* Resume the helper task. At this time it has a priority lower than + ours so no context switch should occur. */ + vTaskResume( xChangePriorityWhenSuspendedHandle ); + + /* Check to ensure the task just resumed has not executed. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Now try raising the priority while the scheduler is suspended. */ + vTaskSuspendAll(); + { + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) ); + + /* Again, even though the helper task has a priority greater than + ours, it should not have executed yet because the scheduler is + suspended. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + } + xTaskResumeAll(); + + /* Now the scheduler has been resumed the helper task should + immediately preempt us and execute. When it executes it will increment + the ulPrioritySetCounter exactly once before suspending itself. + + We should now always find the counter set to 1. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 1 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Delay until we try this again. */ + vTaskDelay( priSLEEP_TIME * 2 ); + + /* Set the priority of the helper task back ready for the next + execution of this task. */ + vTaskSuspendAll(); + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY ); + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityHelperTask( void *pvParameters ) +{ + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This is the helper task for prvChangePriorityWhenSuspendedTask(). + It has it's priority raised and lowered. When it runs it simply + increments the counter then suspends itself again. This allows + prvChangePriorityWhenSuspendedTask() to know how many times it has + executed. */ + ulPrioritySetCounter++; + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static unsigned short usLastTaskCheck = ( unsigned short ) 0; +portBASE_TYPE xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xPriorityRaiseWhenSuspendedError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + return xReturn; +} + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/events.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/events.c new file mode 100644 index 0000000..307568e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/events.c @@ -0,0 +1,406 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * This file exercises the event mechanism whereby more than one task is + * blocked waiting for the same event. + * + * The demo creates five tasks - four 'event' tasks, and a controlling task. + * The event tasks have various different priorities and all block on reading + * the same queue. The controlling task writes data to the queue, then checks + * to see which of the event tasks read the data from the queue. The + * controlling task has the lowest priority of all the tasks so is guaranteed + * to always get preempted immediately upon writing to the queue. + * + * By selectively suspending and resuming the event tasks the controlling task + * can check that the highest priority task that is blocked on the queue is the + * task that reads the posted data from the queue. + * + * Two of the event tasks share the same priority. When neither of these tasks + * are suspended they should alternate - one reading one message from the queue, + * the other the next message, etc. + */ + +/* Standard includes. */ +#include +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "mevents.h" +#include "print.h" + +/* Demo specific constants. */ +#define evtSTACK_SIZE ( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE ) +#define evtNUM_TASKS ( 4 ) +#define evtQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 3 ) +#define evtNO_DELAY 0 + +/* Just indexes used to uniquely identify the tasks. Note that two tasks are +'highest' priority. */ +#define evtHIGHEST_PRIORITY_INDEX_2 3 +#define evtHIGHEST_PRIORITY_INDEX_1 2 +#define evtMEDIUM_PRIORITY_INDEX 1 +#define evtLOWEST_PRIORITY_INDEX 0 + +/* Each event task increments one of these counters each time it reads data +from the queue. */ +static volatile portBASE_TYPE xTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Each time the controlling task posts onto the queue it increments the +expected count of the task that it expected to read the data from the queue +(i.e. the task with the highest priority that should be blocked on the queue). + +xExpectedTaskCounters are incremented from the controlling task, and +xTaskCounters are incremented from the individual event tasks - therefore +comparing xTaskCounters to xExpectedTaskCounters shows whether or not the +correct task was unblocked by the post. */ +static portBASE_TYPE xExpectedTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Handles to the four event tasks. These are required to suspend and resume +the tasks. */ +static TaskHandle_t xCreatedTasks[ evtNUM_TASKS ]; + +/* The single queue onto which the controlling task posts, and the four event +tasks block. */ +static QueueHandle_t xQueue; + +/* Flag used to indicate whether or not an error has occurred at any time. +An error is either the queue being full when not expected, or an unexpected +task reading data from the queue. */ +static portBASE_TYPE xHealthStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* Function that implements the event task. This is created four times. */ +static void prvMultiEventTask( void *pvParameters ); + +/* Function that implements the controlling task. */ +static void prvEventControllerTask( void *pvParameters ); + +/* This is a utility function that posts data to the queue, then compares +xExpectedTaskCounters with xTaskCounters to ensure everything worked as +expected. + +The event tasks all have higher priorities the controlling task. Therefore +the controlling task will always get preempted between writhing to the queue +and checking the task counters. + +@param xExpectedTask The index to the task that the controlling task thinks + should be the highest priority task waiting for data, and + therefore the task that will unblock. + +@param xIncrement The number of items that should be written to the queue. +*/ +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ); + +/* This is just incremented each cycle of the controlling tasks function so +the main application can ensure the test is still running. */ +static portBASE_TYPE xCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartMultiEventTasks( void ) +{ + /* Create the queue to be used for all the communications. */ + xQueue = xQueueCreate( evtQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); + + /* Start the controlling task. This has the idle priority to ensure it is + always preempted by the event tasks. */ + xTaskCreate( prvEventControllerTask, "EvntCTRL", evtSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + + /* Start the four event tasks. Note that two have priority 3, one + priority 2 and the other priority 1. */ + xTaskCreate( prvMultiEventTask, "Event0", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 0 ] ), 1, &( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event1", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 1 ] ), 2, &( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event2", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 2 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ) ); + xTaskCreate( prvMultiEventTask, "Event3", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 3 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ) ); +} +/*-----------------------------------------------------------*/ + +static void prvMultiEventTask( void *pvParameters ) +{ +portBASE_TYPE *pxCounter; +unsigned portBASE_TYPE uxDummy; +const char * const pcTaskStartMsg = "Multi event task started.\r\n"; + + /* The variable this task will increment is passed in as a parameter. */ + pxCounter = ( portBASE_TYPE * ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Block on the queue. */ + if( xQueueReceive( xQueue, &uxDummy, portMAX_DELAY ) ) + { + /* We unblocked by reading the queue - so simply increment + the counter specific to this task instance. */ + ( *pxCounter )++; + } + else + { + xHealthStatus = pdFAIL; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvEventControllerTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "Multi event controller task started.\r\n"; +portBASE_TYPE xDummy = 0; + + /* Just to stop warnings. */ + ( void ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* All tasks are blocked on the queue. When a message is posted one of + the two tasks that share the highest priority should unblock to read + the queue. The next message written should unblock the other task with + the same high priority, and so on in order. No other task should + unblock to read data as they have lower priorities. */ + + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* For the rest of these tests we don't need the second 'highest' + priority task - so it is suspended. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + + + /* Now suspend the other highest priority task. The medium priority + task will then be the task with the highest priority that remains + blocked on the queue. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + /* This time, when we post onto the queue we will expect the medium + priority task to unblock and preempt us. */ + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + /* Now try resuming the highest priority task while the scheduler is + suspended. The task should start executing as soon as the scheduler + is resumed - therefore when we post to the queue again, the highest + priority task should again preempt us. */ + vTaskSuspendAll(); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now we are going to suspend the high and medium priority tasks. The + low priority task should then preempt us. Again the task suspension is + done with the whole scheduler suspended just for test purposes. */ + vTaskSuspendAll(); + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + /* Do the same basic test another few times - selectively suspending + and resuming tasks and each time calling prvCheckTaskCounters() passing + to the function the number of the task we expected to be unblocked by + the post. */ + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for even more test. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + xTaskResumeAll(); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now a slight change, first suspend all tasks. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* Now when we resume the low priority task and write to the queue 3 + times. We expect the low priority task to service the queue three + times. */ + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH ); + + /* Again suspend all tasks (only the low priority task is not suspended + already). */ + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* This time we are going to suspend the scheduler, resume the low + priority task, then resume the high priority task. In this state we + will write to the queue three times. When the scheduler is resumed + we expect the high priority task to service all three messages. */ + vTaskSuspendAll(); + { + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + xHealthStatus = pdFAIL; + } + } + + /* The queue should not have been serviced yet!. The scheduler + is still suspended. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + } + xTaskResumeAll(); + + /* We should have been preempted by resuming the scheduler - so by the + time we are running again we expect the high priority task to have + removed three items from the queue. */ + xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH; + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + + /* The medium priority and second high priority tasks are still + suspended. Make sure to resume them before starting again. */ + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + /* Just keep incrementing to show the task is still executing. */ + xCheckVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ) +{ +portBASE_TYPE xDummy = 0; + + /* Write to the queue the requested number of times. The data written is + not important. */ + for( xDummy = 0; xDummy < xIncrement; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + /* Did not expect to ever find the queue full. */ + xHealthStatus = pdFAIL; + } + } + + /* All the tasks blocked on the queue have a priority higher than the + controlling task. Writing to the queue will therefore have caused this + task to be preempted. By the time this line executes the event task will + have executed and incremented its counter. Increment the expected counter + to the same value. */ + ( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement; + + /* Check the actual counts and expected counts really are the same. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + /* The counters were not the same. This means a task we did not expect + to unblock actually did unblock. */ + xHealthStatus = pdFAIL; + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreMultiEventTasksStillRunning( void ) +{ +static portBASE_TYPE xPreviousCheckVariable = 0; + + /* Called externally to periodically check that this test is still + operational. */ + + if( xPreviousCheckVariable == xCheckVariable ) + { + xHealthStatus = pdFAIL; + } + + xPreviousCheckVariable = xCheckVariable; + + return xHealthStatus; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flash.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flash.c new file mode 100644 index 0000000..db94755 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flash.c @@ -0,0 +1,166 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/** + * Creates eight tasks, each of which flash an LED at a different rate. The first + * LED flashes every 125ms, the second every 250ms, the third every 375ms, etc. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + * The PC port uses the standard parallel port for outputs, the Flashlite 186 port + * uses IO port F. + * + * \page flashC flash.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" +#include "print.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE + +/* Structure used to pass parameters to the LED tasks. */ +typedef struct LED_PARAMETERS +{ + unsigned portBASE_TYPE uxLED; /*< The output the task should use. */ + TickType_t xFlashRate; /*< The rate at which the LED should flash. */ +} xLEDParameters; + +/* The task that is created eight times - each time with a different xLEDParaemtes +structure passed in as the parameter. */ +static void vLEDFlashTask( void *pvParameters ); + +/* String to print if USE_STDIO is defined. */ +const char * const pcTaskStartMsg = "LED flash task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE uxLEDTask; +xLEDParameters *pxLEDParameters; +const unsigned portBASE_TYPE uxNumOfLEDs = 8; +const TickType_t xFlashRate = 125; + + /* Create the eight tasks. */ + for( uxLEDTask = 0; uxLEDTask < uxNumOfLEDs; ++uxLEDTask ) + { + /* Create and complete the structure used to pass parameters to the next + created task. */ + pxLEDParameters = ( xLEDParameters * ) pvPortMalloc( sizeof( xLEDParameters ) ); + pxLEDParameters->uxLED = uxLEDTask; + pxLEDParameters->xFlashRate = ( xFlashRate + ( xFlashRate * ( TickType_t ) uxLEDTask ) ); + pxLEDParameters->xFlashRate /= portTICK_PERIOD_MS; + + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, ( void * ) pxLEDParameters, uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void vLEDFlashTask( void *pvParameters ) +{ +xLEDParameters *pxParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxParameters = ( xLEDParameters * ) pvParameters; + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + } +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flop.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flop.c new file mode 100644 index 0000000..c516ff6 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/flop.c @@ -0,0 +1,369 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * Creates eight tasks, each of which loops continuously performing an (emulated) + * floating point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + * + * \page FlopC flop.c + * \ingroup DemoFiles + *
+ */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE ( ( unsigned short ) 512 ) +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static void vCompetingMathTask1( void *pvParameters ); +static void vCompetingMathTask2( void *pvParameters ); +static void vCompetingMathTask3( void *pvParameters ); +static void vCompetingMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask1( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned short *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222; +const char * const pcTaskStartMsg = "Math task 1 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 1 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask2( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned short *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001; +const char * const pcTaskStartMsg = "Math task 2 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 2 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask3( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Math task 3 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 3 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5; + dTotal1 += ( portDOUBLE ) usPosition + 5.5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask4( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Math task 4 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 4 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123; + dTotal1 += ( portDOUBLE ) usPosition * 12.123; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/integer.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/integer.c new file mode 100644 index 0000000..8a16e04 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/integer.c @@ -0,0 +1,365 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * This does the same as flop. c, but uses variables of type long instead of + * type double. + * + * As with flop. c, the tasks created in this file are a good test of the + * scheduler context switch mechanism. The processor has to access 32bit + * variables in two or four chunks (depending on the processor). The low + * priority of these tasks means there is a high probability that a context + * switch will occur mid calculation. See the flop. c documentation for + * more information. + * + * \page IntegerC integer.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.1 + + + The constants used in the calculations are larger to ensure the + optimiser does not truncate them to 16 bits. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "integer.h" + +#define intgSTACK_SIZE ( ( unsigned short ) 256 ) +#define intgNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different calculation on four byte +variables. Each of the four is created twice. */ +static void vCompeteingIntMathTask1( void *pvParameters ); +static void vCompeteingIntMathTask2( void *pvParameters ); +static void vCompeteingIntMathTask3( void *pvParameters ); +static void vCompeteingIntMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will stop incrementing its check variable. */ +static volatile unsigned short usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask1( void *pvParameters ) +{ +long l1, l2, l3, l4; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const long lAnswer = ( ( long ) 74565L + ( long ) 1234567L ) * ( long ) -918L; +const char * const pcTaskStartMsg = "Integer math task 1 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 1 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + l1 = ( long ) 74565L; + l2 = ( long ) 1234567L; + l3 = ( long ) -918L; + + l4 = ( l1 + l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask2( void *pvParameters ) +{ +long l1, l2, l3, l4; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const long lAnswer = ( ( long ) -389000L / ( long ) 329999L ) * ( long ) -89L; +const char * const pcTaskStartMsg = "Integer math task 2 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 2 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + l1 = -389000L; + l2 = 329999L; + l3 = -89L; + + l4 = ( l1 / l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask3( void *pvParameters ) +{ +long *plArray, lTotal1, lTotal2; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = ( unsigned short ) 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Integer math task 3 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 3 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( long ) 0; + lTotal2 = ( long ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( long ) usPosition + ( long ) 5; + lTotal1 += ( long ) usPosition + ( long ) 5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask4( void *pvParameters ) +{ +long *plArray, lTotal1, lTotal2; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Integer math task 4 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 4 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( long ) 0; + lTotal2 = ( long ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( long ) usPosition * ( long ) 12; + lTotal1 += ( long ) usPosition * ( long ) 12; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreIntegerMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned short usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/print.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/print.c new file mode 100644 index 0000000..3d554a1 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/print.c @@ -0,0 +1,144 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Manages a queue of strings that are waiting to be displayed. This is used to + * ensure mutual exclusion of console output. + * + * A task wishing to display a message will call vPrintDisplayMessage (), with a + * pointer to the string as the parameter. The pointer is posted onto the + * xPrintQueue queue. + * + * The task spawned in main. c blocks on xPrintQueue. When a message becomes + * available it calls pcPrintGetNextMessage () to obtain a pointer to the next + * string, then uses the functions defined in the portable layer FileIO. c to + * display the message. + * + * NOTE: + * Using console IO can disrupt real time performance - depending on the port. + * Standard C IO routines are not designed for real time applications. While + * standard IO is useful for demonstration and debugging an alternative method + * should be used if you actually require console IO as part of your application. + * + * \page PrintC print.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "queue.h" + +/* Demo program include files. */ +#include "print.h" + +static QueueHandle_t xPrintQueue; + +/*-----------------------------------------------------------*/ + +void vPrintInitialise( void ) +{ +const unsigned portBASE_TYPE uxQueueSize = 20; + + /* Create the queue on which errors will be reported. */ + xPrintQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( char * ) ); +} +/*-----------------------------------------------------------*/ + +void vPrintDisplayMessage( const char * const * ppcMessageToSend ) +{ + #ifdef USE_STDIO + xQueueSend( xPrintQueue, ( void * ) ppcMessageToSend, ( TickType_t ) 0 ); + #else + /* Stop warnings. */ + ( void ) ppcMessageToSend; + #endif +} +/*-----------------------------------------------------------*/ + +const char *pcPrintGetNextMessage( TickType_t xPrintRate ) +{ +char *pcMessage; + + if( xQueueReceive( xPrintQueue, &pcMessage, xPrintRate ) == pdPASS ) + { + return pcMessage; + } + else + { + return NULL; + } +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/semtest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/semtest.c new file mode 100644 index 0000000..f874162 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Full/semtest.c @@ -0,0 +1,323 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + * \page SemTestC semtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.0: + + + The tasks that operate at the idle priority now use a lower expected + count than those running at a higher priority. This prevents the low + priority tasks from signaling an error because they have not been + scheduled enough time for each of them to count the shared variable to + the high value. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" +#include "print.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( TickType_t ) 10 ) + +/* The task function as described at the top of the file. */ +static void prvSemaphoreTest( void *pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + SemaphoreHandle_t xSemaphore; + volatile unsigned long *pulSharedVariable; + TickType_t xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile short sNextCheckVariable = 0; + +/* Strings to print if USE_STDIO is defined. */ +const char * const pcPollingSemaphoreTaskError = "Guarded shared variable in unexpected state.\r\n"; +const char * const pcSemaphoreTaskStart = "Guarded shared variable task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const TickType_t xBlockTime = ( TickType_t ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore ); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore ); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS; + + xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSemaphoreTest( void *pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile unsigned long *pulSharedVariable, ulExpectedValue; +unsigned long ulCounter; +short sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcSemaphoreTaskStart ); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( TickType_t ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + if( sError == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + } + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( TickType_t ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreSemaphoreTasksStillRunning( void ) +{ +static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +portBASE_TYPE xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlckQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlckQ.c new file mode 100644 index 0000000..a1d2cd0 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlckQ.c @@ -0,0 +1,332 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is a version of BlockQ.c that uses the alternative (Alt) API. + * + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "AltBlckQ.h" + +#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + QueueHandle_t xQueue; /*< The queue to be used by the task. */ + TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartAltBlockingQueueTasks( UBaseType_t uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5; +const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +const TickType_t xDontBlock = ( TickType_t ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueConsumer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueProducer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) +{ +uint16_t usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt blocking queue producer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueAltSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueAltReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreAltBlockingQueuesStillRunning( void ) +{ +static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +BaseType_t xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable to and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlock.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlock.c new file mode 100644 index 0000000..f19e3f4 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltBlock.c @@ -0,0 +1,549 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is a version of BlockTim.c that uses the light weight API. + * + * This file contains some test scenarios that ensure tasks do not exit queue + * send or receive functions prematurely. A description of the tests is + * included within the code. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "AltBlock.h" + +/* Task priorities. */ +#define bktPRIMARY_PRIORITY ( 3 ) +#define bktSECONDARY_PRIORITY ( 2 ) + +/* Task behaviour. */ +#define bktQUEUE_LENGTH ( 5 ) +#define bktSHORT_WAIT ( ( ( TickType_t ) 20 ) / portTICK_PERIOD_MS ) +#define bktPRIMARY_BLOCK_TIME ( 10 ) +#define bktALLOWABLE_MARGIN ( 12 ) +#define bktTIME_TO_BLOCK ( 175 ) +#define bktDONT_BLOCK ( ( TickType_t ) 0 ) +#define bktRUN_INDICATOR ( ( UBaseType_t ) 0x55 ) + +/* The queue on which the tasks block. */ +static QueueHandle_t xTestQueue; + +/* Handle to the secondary task is required by the primary task for calls +to vTaskSuspend/Resume(). */ +static TaskHandle_t xSecondary; + +/* Used to ensure that tasks are still executing without error. */ +static BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0; +static BaseType_t xErrorOccurred = pdFALSE; + +/* Provides a simple mechanism for the primary task to know when the +secondary task has executed. */ +static volatile UBaseType_t xRunIndicator; + +/* The two test tasks. Their behaviour is commented within the files. */ +static void vPrimaryBlockTimeTestTask( void *pvParameters ); +static void vSecondaryBlockTimeTestTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +void vCreateAltBlockTimeTasks( void ) +{ + /* Create the queue on which the two tasks block. */ + xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xTestQueue, "AltBlockQueue" ); + + + /* Create the two test tasks. */ + xTaskCreate( vPrimaryBlockTimeTestTask, "FBTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); + xTaskCreate( vSecondaryBlockTimeTestTask, "FBTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); +} +/*-----------------------------------------------------------*/ + +static void vPrimaryBlockTimeTestTask( void *pvParameters ) +{ +BaseType_t xItem, xData; +TickType_t xTimeWhenBlocking; +TickType_t xTimeToBlock, xBlockedTime; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt primary block time test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 + + Simple block time wakeup test on queue receives. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is empty. Attempt to read from the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + /* A critical section is used to minimise the jitter in the time + measurements. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueAltReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /********************************************************************* + Test 2 + + Simple block time wakeup test on queue sends. + + First fill the queue. It should be empty so all sends should pass. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is full. Attempt to write to the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = bktPRIMARY_BLOCK_TIME << xItem; + + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /********************************************************************* + Test 3 + + Wake the other task, it will block attempting to post to the queue. + When we read from the queue the other task will wake, but before it + can run we will post to the queue again. When the other task runs it + will find the queue still full, even though it was woken. It should + recognise that its block time has not expired and return to block for + the remains of its block time. + + Wake the other task so it blocks attempting to post to the already + full queue. */ + xRunIndicator = 0; + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + /* The other task has not yet executed. */ + vTaskDelay( bktSHORT_WAIT ); + } + /* Make sure the other task is blocked on the queue. */ + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we make space on the queue the other task should wake + but not execute as this task has higher priority. */ + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now fill the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + full ourselves, and the other task have set xRunIndicator. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + + /* Set the priority back down. */ + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /********************************************************************* + Test 4 + + As per test 3 - but with the send and receive the other way around. + The other task blocks attempting to read from the queue. + + Empty the queue. We should find that it is full. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Wake the other task so it blocks attempting to read from the + already empty queue. */ + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we place an item on the queue the other task should + wake but not execute as this task has higher priority. */ + if( xQueueAltSendToBack( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now empty the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + empty ourselves, and the other task would be suspended. */ + if( xQueueAltReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + + xPrimaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void vSecondaryBlockTimeTestTask( void *pvParameters ) +{ +TickType_t xTimeWhenBlocking, xBlockedTime; +BaseType_t xData; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt secondary block time test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 and 2 + + This task does does not participate in these tests. */ + vTaskSuspend( NULL ); + + /********************************************************************* + Test 3 + + The first thing we do is attempt to read from the queue. It should be + full so we block. Note the time before we block so we can check the + wake time is as per that expected. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xData = 0; + xRunIndicator = bktRUN_INDICATOR; + if( xQueueAltSendToBack( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we inside the send function? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as + soon as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Suspend ready for test 3. */ + xRunIndicator = bktRUN_INDICATOR; + vTaskSuspend( NULL ); + + /********************************************************************* + Test 4 + + As per test three, but with the send and receive reversed. */ + portENTER_CRITICAL(); + { + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xRunIndicator = bktRUN_INDICATOR; + if( xQueueAltReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + } + portEXIT_CRITICAL(); + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as soon + as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + xRunIndicator = bktRUN_INDICATOR; + + xSecondaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreAltBlockTimeTestTasksStillRunning( void ) +{ +static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; +BaseType_t xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xPrimaryCycles == xLastPrimaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xSecondaryCycles == xLastSecondaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastSecondaryCycleCount = xSecondaryCycles; + xLastPrimaryCycleCount = xPrimaryCycles; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltPollQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltPollQ.c new file mode 100644 index 0000000..57b7322 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltPollQ.c @@ -0,0 +1,275 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is a version of PollQ.c that uses the alternative (Alt) API. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than uint32_t. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "AltPollQ.h" + +#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE +#define pollqQUEUE_SIZE ( 10 ) +#define pollqPRODUCER_DELAY ( ( TickType_t ) 200 / portTICK_PERIOD_MS ) +#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) ) +#define pollqNO_DELAY ( ( TickType_t ) 0 ) +#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 ) +#define pollqINITIAL_VALUE ( ( BaseType_t ) 0 ) + +/* The task that posts the incrementing number onto the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters ); + +/* The task that empties the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters ); + +/* Variables that are used to check that the tasks are still running with no +errors. */ +static volatile BaseType_t xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE; + +/*-----------------------------------------------------------*/ + +void vStartAltPolledQueueTasks( UBaseType_t uxPriority ) +{ +static QueueHandle_t xPolledQueue; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xPolledQueue, "AltPollQueue" ); + + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueProducer, pvParameters ) +{ +uint16_t usValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE, xLoop; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt polling queue producer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + for( ;; ) + { + for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueAltSendToBack( *( ( QueueHandle_t * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS ) + { + /* We should never find the queue full so if we get here there + has been an error. */ + xError = pdTRUE; + } + else + { + if( xError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + portENTER_CRITICAL(); + xPollingProducerCount++; + portEXIT_CRITICAL(); + } + + /* Update the value we are going to post next time around. */ + usValue++; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( pollqPRODUCER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt blocking queue consumer task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) ) + { + if( xQueueAltReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + xError = pdTRUE; + + /* Catch-up to the value we received so our next expected + value should again be correct. */ + usExpectedValue = usData; + } + else + { + if( xError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + portENTER_CRITICAL(); + xPollingConsumerCount++; + portEXIT_CRITICAL(); + } + } + + /* Next time round we would expect the number to be one higher. */ + usExpectedValue++; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( pollqCONSUMER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +BaseType_t xAreAltPollingQueuesStillRunning( void ) +{ +BaseType_t xReturn; + + /* Check both the consumer and producer poll count to check they have both + been changed since out last trip round. We do not need a critical section + around the check variables as this is called from a higher priority than + the other tasks that access the same variables. */ + if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) || + ( xPollingProducerCount == pollqINITIAL_VALUE ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Set the check variables back down so we know if they have been + incremented the next time around. */ + xPollingConsumerCount = pollqINITIAL_VALUE; + xPollingProducerCount = pollqINITIAL_VALUE; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltQTest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltQTest.c new file mode 100644 index 0000000..188d3b0 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/AltQTest.c @@ -0,0 +1,587 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * This file implements the same demo and test as GenQTest.c, but uses the + * light weight API in place of the fully featured API. + * + * See the comments at the top of GenQTest.c for a description. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "AltQTest.h" + +#define genqQUEUE_LENGTH ( 5 ) +#define genqNO_BLOCK ( 0 ) + +#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) +#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * Tests the behaviour of the xQueueAltSendToFront() and xQueueAltSendToBack() + * macros by using both to fill a queue, then reading from the queue to + * check the resultant queue order is as expected. Queue data is also + * peeked. + */ +static void prvSendFrontAndBackTest( void *pvParameters ); + +/* + * The following three tasks are used to demonstrate the mutex behaviour. + * Each task is given a different priority to demonstrate the priority + * inheritance mechanism. + * + * The low priority task obtains a mutex. After this a high priority task + * attempts to obtain the same mutex, causing its priority to be inherited + * by the low priority task. The task with the inherited high priority then + * resumes a medium priority task to ensure it is not blocked by the medium + * priority task while it holds the inherited high priority. Once the mutex + * is returned the task with the inherited priority returns to its original + * low priority, and is therefore immediately preempted by first the high + * priority task and then the medium prioroity task before it can continue. + */ +static void prvLowPriorityMutexTask( void *pvParameters ); +static void prvMediumPriorityMutexTask( void *pvParameters ); +static void prvHighPriorityMutexTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static BaseType_t xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; +static volatile uint32_t ulLoopCounter2 = 0; + +/* The variable that is guarded by the mutex in the mutex demo tasks. */ +static volatile uint32_t ulGuardedVariable = 0; + +/* Handles used in the mutext test to suspend and resume the high and medium +priority mutex test tasks. */ +static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask; + +/*-----------------------------------------------------------*/ + +void vStartAltGenericQueueTasks( UBaseType_t uxPriority ) +{ +QueueHandle_t xQueue; +SemaphoreHandle_t xMutex; + + /* Create the queue that we are going to use for the + prvSendFrontAndBackTest demo. */ + xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, "Alt_Gen_Test_Queue" ); + + /* Create the demo task and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvSendFrontAndBackTest, "FGenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); + + /* Create the mutex used by the prvMutexTest task. */ + xMutex = xSemaphoreCreateMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Alt_Q_Mutex" ); + + /* Create the mutex demo tasks and pass it the mutex just created. We are + passing the mutex handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityMutexTask, "FMuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, "FMuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, "FMuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void *pvParameters ) +{ +uint32_t ulData, ulData2; +QueueHandle_t xQueue; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Alt queue SendToFront/SendToBack/Peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + xQueue = ( QueueHandle_t ) pvParameters; + + for( ;; ) + { + /* The queue is empty, so sending an item to the back of the queue + should have the same efect as sending it to the front of the queue. + + First send to the front and check everything is as expected. */ + xQueueAltSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + /* Then do the same, sending the data to the back, checking everything + is as expected. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + xQueueAltSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + + /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ + for( ulData = 2; ulData < 5; ulData++ ) + { + xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + } + + /* Now the order in the queue should be 2, 3, 4, with 2 being the first + thing to be read out. Now add 1 then 0 to the front of the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 3 ) + { + xErrorDetected = pdTRUE; + } + ulData = 1; + xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + ulData = 0; + xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + + /* Now the queue should be full, and when we read the data out we + should receive 0, 1, 2, 3, 4. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) + { + /* Try peeking the data first. */ + if( xQueueAltPeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + + + /* Now try receiving the data for real. The value should be the + same. Clobber the value first so we know we really received it. */ + ulData2 = ~ulData2; + if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + /* The queue should now be empty again. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /* Our queue is empty once more, add 10, 11 to the back. */ + ulData = 10; + if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + ulData = 11; + if( xQueueAltSendToBack( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 2 ) + { + xErrorDetected = pdTRUE; + } + + /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the + front. */ + for( ulData = 9; ulData >= 7; ulData-- ) + { + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } + + /* Now check that the queue is full, and that receiving data provides + the expected sequence of 7, 8, 9, 10, 11. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueAltSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) + { + if( xQueueAltReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Fast mutex with priority inheritance test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + ( void ) pvParameters; + + + for( ;; ) + { + /* Take the mutex. It should be available now. */ + if( xSemaphoreAltTake( xMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set our guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* Our priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + /* We should now have inherited the prioritoy of the high priority task, + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* We can attempt to set our priority to the test priority - between the + idle priority and the medium/high test priorities, but our actual + prioroity should remain at the high priority. */ + vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as our + inherited priority is above that of the medium priority task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the did run then it will have incremented our guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* When we give back the semaphore our priority should be disinherited + back to the priority to which we attempted to set ourselves. This means + that when the high priority task next blocks, the medium priority task + should execute and increment the guarded variable. When we next run + both the high and medium priority tasks will have been suspended again. */ + if( xSemaphoreAltGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Check that the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that our priority has been disinherited to + genqMUTEX_TEST_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Set our priority back to our original priority ready for the next + loop around this test. */ + vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); + + /* Just to show we are still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityMutexTask( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + /* The medium priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is increment the guarded + variable, this is so the low priority task knows that it has + executed. */ + ulGuardedVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters; + + ( void ) pvParameters; + + for( ;; ) + { + /* The high priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is attempt to obtain + the mutex. It should find the mutex is not available so a + block time is specified. */ + if( xSemaphoreAltTake( xMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When we eventually obtain the mutex we just give it back then + return to suspend ready for the next test. */ + if( xSemaphoreAltGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreAltGenericQueueTasksStillRunning( void ) +{ +static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; + + /* If the demo task is still running then we expect the loopcounters to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + if( ulLastLoopCounter2 == ulLoopCounter2 ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + ulLastLoopCounter2 = ulLoopCounter2; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return !xErrorDetected; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/BlockQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/BlockQ.c new file mode 100644 index 0000000..b8db390 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/BlockQ.c @@ -0,0 +1,324 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" + +#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + QueueHandle_t xQueue; /*< The queue to be used by the task. */ + TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( UBaseType_t uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5; +const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +const TickType_t xDontBlock = ( TickType_t ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueConsumer, "QConsB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) +{ +uint16_t usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + + #if configUSE_PREEMPTION == 0 + { + if( pxQueueParameters->xBlockTime == 0 ) + { + taskYIELD(); + } + } + #endif + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreBlockingQueuesStillRunning( void ) +{ +static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +BaseType_t xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable to and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/EventGroupsDemo.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/EventGroupsDemo.c new file mode 100644 index 0000000..64d7430 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/EventGroupsDemo.c @@ -0,0 +1,1074 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + + +/* +* This file contains fairly comprehensive checks on the behaviour of event +* groups. It is not intended to be a user friendly demonstration of the +* event groups API. +* +* NOTE: The tests implemented in this file are informal 'sanity' tests +* only and are not part of the module tests that make use of the +* mtCOVERAGE_TEST_MARKER macro within the event groups implementation. +*/ + + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "event_groups.h" + +/* Demo app includes. */ +#include "EventGroupsDemo.h" + +#if( INCLUDE_eTaskGetState != 1 ) + #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file. +#endif + +/* Priorities used by the tasks. */ +#define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Generic bit definitions. */ +#define ebBIT_0 ( 0x01UL ) +#define ebBIT_1 ( 0x02UL ) +#define ebBIT_2 ( 0x04UL ) +#define ebBIT_3 ( 0x08UL ) +#define ebBIT_4 ( 0x10UL ) +#define ebBIT_5 ( 0x20UL ) +#define ebBIT_6 ( 0x40UL ) +#define ebBIT_7 ( 0x80UL ) + +/* Combinations of bits used in the demo. */ +#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 ) +#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 ) + +/* Associate a bit to each task. These bits are used to identify all the tasks +that synchronise with the xEventGroupSync() function. */ +#define ebSET_BIT_TASK_SYNC_BIT ebBIT_0 +#define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1 +#define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2 +#define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3 +#define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT ) + +/* A block time of zero simply means "don't block". */ +#define ebDONT_BLOCK ( 0 ) + +/* A 5ms delay. */ +#define ebSHORT_DELAY ( 5 / portTICK_PERIOD_MS ) + +/* Used in the selective bits test which checks no, one or both tasks blocked on +event bits in a group are unblocked as appropriate as different bits get set. */ +#define ebSELECTIVE_BITS_1 0x03 +#define ebSELECTIVE_BITS_2 0x05 + +/*-----------------------------------------------------------*/ + +/* + * NOTE: The tests implemented in this function are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * The master test task. This task: + * + * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two + * tasks are blocked on different bits in an event group. The counterpart of + * this test is implemented by the prvSelectiveBitsTestSlaveFunction() + * function (which is called by the two tasks that block on the event group). + * + * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when + * just one task is blocked on various combinations of bits within an event + * group. The counterpart of this test is implemented within the 'test + * slave' task. + * + * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour. + */ +static void prvTestMasterTask( void *pvParameters ); + +/* + * A helper task that enables the 'test master' task to perform several + * behavioural tests. See the comments above the prvTestMasterTask() prototype + * above. + */ +static void prvTestSlaveTask( void *pvParameters ); + +/* + * The part of the test that is performed between the 'test master' task and the + * 'test slave' task to test the behaviour when the slave blocks on various + * event bit combinations. + */ +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ); + +/* + * The part of the test that uses all the tasks to test the task synchronisation + * behaviour. + */ +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ); + +/* + * Two instances of prvSyncTask() are created. They start by calling + * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is + * executing the prvSelectiveBitsTestMasterFunction() function. They then loop + * to test the task synchronisation (rendezvous) behaviour. + */ +static void prvSyncTask( void *pvParameters ); + +/* + * Functions used in a test that blocks two tasks on various different bits + * within an event group - then sets each bit in turn and checks that the + * correct tasks unblock at the correct times. + */ +static BaseType_t prvSelectiveBitsTestMasterFunction( void ); +static void prvSelectiveBitsTestSlaveFunction( void ); + +/*-----------------------------------------------------------*/ + +/* Variables that are incremented by the tasks on each cycle provided no errors +have been found. Used to detect an error or stall in the test cycling. */ +static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0; + +/* The event group used by all the task based tests. */ +static EventGroupHandle_t xEventGroup = NULL; + +/* The event group used by the interrupt based tests. */ +static EventGroupHandle_t xISREventGroup = NULL; + +/* Handles to the tasks that only take part in the synchronisation calls. */ +static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL; + +/*-----------------------------------------------------------*/ + +void vStartEventGroupTasks( void ) +{ +TaskHandle_t xTestSlaveTaskHandle; + + /* + * This file contains fairly comprehensive checks on the behaviour of event + * groups. It is not intended to be a user friendly demonstration of the + * event groups API. + * + * NOTE: The tests implemented in this file are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * Create the test tasks as described at the top of this file. + */ + xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle ); + xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL ); + xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 ); + xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 ); + + /* If the last task was created then the others will have been too. */ + configASSERT( xSyncTask2 ); + + /* Create the event group used by the ISR tests. The event group used by + the tasks is created by the tasks themselves. */ + xISREventGroup = xEventGroupCreate(); + configASSERT( xISREventGroup ); +} +/*-----------------------------------------------------------*/ + +static void prvTestMasterTask( void *pvParameters ) +{ +BaseType_t xError; + +/* The handle to the slave task is passed in as the task parameter. */ +TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + /* Create the event group used by the tasks ready for the initial tests. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that block two tasks on different combinations of bits, + then set each bit in turn and check the correct tasks unblock at the correct + times. */ + xError = prvSelectiveBitsTestMasterFunction(); + + for( ;; ) + { + /* Recreate the event group ready for the next cycle. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that check the behaviour when a single task is + blocked on various combinations of event bits. */ + xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle ); + + /* Perform the task synchronisation tests. */ + xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle ); + + /* Delete the event group. */ + vEventGroupDelete( xEventGroup ); + + /* Now all the other tasks should have completed and suspended + themselves ready for the next go around the loop. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Only increment the cycle variable if no errors have been detected. */ + if( xError == pdFALSE ) + { + ulTestMasterCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSyncTask( void *pvParameters ) +{ +EventBits_t uxSynchronisationBit, uxReturned; + + /* A few tests that check the behaviour when two tasks are blocked on + various different bits within an event group are performed before this task + enters its infinite loop to carry out its main demo function. */ + prvSelectiveBitsTestSlaveFunction(); + + /* The bit to use to indicate this task is at the synchronisation point is + passed in as the task parameter. */ + uxSynchronisationBit = ( EventBits_t ) pvParameters; + + for( ;; ) + { + /* Now this task takes part in a task synchronisation - sometimes known + as a 'rendezvous'. Its execution pattern is controlled by the 'test + master' task, which is responsible for taking this task out of the + Suspended state when it is time to test the synchronisation behaviour. + See: http://www.freertos.org/xEventGroupSync.html. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + point. The first time this is done the 'test master' task has a lower + priority than this task so this task will get to the sync point before + the set bits task. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ + ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A max delay was used, so this task should only exit the above + function call when the sync condition is met. Check this is the + case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Remove compiler warning if configASSERT() is not defined. */ + ( void ) uxReturned; + + /* Wait until the 'test master' task unsuspends this task again. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + point again. This time the 'test master' task has a higher priority + than this task so will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* Again a max delay was used, so this task should only exit the above + function call when the sync condition is met. Check this is the + case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Block on the event group again. This time the event group is going + to be deleted while this task is blocked on it so it is expected that 0 + be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + configASSERT( uxReturned == 0 ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTestSlaveTask( void *pvParameters ) +{ +EventBits_t uxReturned; +BaseType_t xError = pdFALSE; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************** + * Part 1: This section is the counterpart to the + * prvBitCombinationTestMasterFunction() function which is called by the + * test master task. + *********************************************************************** + + This task is controller by the 'test master' task (which is + implemented by prvTestMasterTask()). Suspend until resumed by the + 'test master' task. */ + vTaskSuspend( NULL ); + + /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get + set. Clear the bit on exit. */ + uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */ + ebBIT_1, /* The bit to wait for. */ + pdTRUE, /* Clear the bit on exit. */ + pdTRUE, /* Wait for all the bits (only one in this case anyway). */ + portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */ + + /* The 'test master' task set all the bits defined by ebCOMBINED_BITS, + only one of which was being waited for by this task. The return value + shows the state of the event bits when the task was unblocked, however + because the task was waiting for ebBIT_1 and 'clear on exit' was set to + the current state of the event bits will have ebBIT_1 clear. */ + if( uxReturned != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Now call xEventGroupWaitBits() again, this time waiting for all the + bits in ebCOMBINED_BITS to be set. This call should block until the + 'test master' task sets ebBIT_1 - which was the bit cleared in the call + to xEventGroupWaitBits() above. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdFALSE, /* Don't clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* Were all the bits set? */ + if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Suspend again to wait for the 'test master' task. */ + vTaskSuspend( NULL ); + + /* Now call xEventGroupWaitBits() again, again waiting for all the bits + in ebCOMBINED_BITS to be set, but this time clearing the bits when the + task is unblocked. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdTRUE, /* Clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* The 'test master' task set all the bits in the event group, so that + is the value that should have been returned. The bits defined by + ebCOMBINED_BITS will have been clear again in the current value though + as 'clear on exit' was set to pdTRUE. */ + if( uxReturned != ebALL_BITS ) + { + xError = pdTRUE; + } + + + + + + /********************************************************************** + * Part 2: This section is the counterpart to the + * prvPerformTaskSyncTests() function which is called by the + * test master task. + *********************************************************************** + + + Once again wait for the 'test master' task to unsuspend this task + when it is time for the next test. */ + vTaskSuspend( NULL ); + + /* Now peform a synchronisation with all the other tasks. At this point + the 'test master' task has the lowest priority so will get to the sync + point after all the other synchronising tasks. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */ + ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the synchronisation bits should be clear again. Read back + the current value of the bits within the event group to check that is + the case. Setting the bits to zero will return the bits previous value + then leave all the bits clear. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Check the bits are indeed 0 now by simply reading then. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + vTaskSuspend( NULL ); + + /* This time sync when the 'test master' task has the highest priority + at the point where it sets its sync bit - so this time the 'test master' + task will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Block on the event group again. This time the event group is going + to be deleted while this task is blocked on it, so it is expected that 0 + will be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + + if( uxReturned != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) +{ +EventBits_t uxBits; + + /* The three tasks that take part in the synchronisation (rendezvous) are + expected to be in the suspended state at the start of the test. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Try a synch with no other tasks involved. First set all the bits other + than this task's bit. */ + xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + + /* Then wait on just one bit - the bit that is being set. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + bits are set...check that is the case. In this case there is only one + sync bit anyway. */ + if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again, leaving all the other + bits set (as only one bit was being waited for). */ + if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ) + { + xError = pdTRUE; + } + + /* Clear all the bits to zero again. */ + xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + /* Unsuspend the other tasks then check they have executed up to the + synchronisation point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + bits are set...check that is the case. */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + + /* The other tasks should now all be suspended again, ready for the next + synchronisation. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + + /* Sync again - but this time set the last necessary bit as the + highest priority task, rather than the lowest priority task. Unsuspend + the other tasks then check they have executed up to the synchronisation + point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Raise the priority of this task above that of the other tasks. */ + vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 ); + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + + /* The other tasks should now all be in the ready state again, but not + executed yet as this task still has a higher relative priority. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eReady ) + { + xError = pdTRUE; + } + + + /* Reset the priority of this task back to its original value. */ + vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY ); + + /* Now all the other tasks should have reblocked on the event bits + to test the behaviour when the event bits are deleted. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) +{ +EventBits_t uxBits; + + /* Resume the other task. It will block, pending a single bit from + within ebCOMBINED_BITS. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked on the task. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only + blocked waiting for one of them. */ + xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS ); + + /* The 'test slave' task should now have executed, clearing ebBIT_1 (the + bit it was blocked on), then re-entered the Blocked state to wait for + all the other bits in ebCOMBINED_BITS to be set again. First check + ebBIT_1 is clear. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits other than ebBIT_1 - which is the bit that must be + set before the other task unblocks. */ + xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 ); + + /* Ensure all the expected bits are still set. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Now also set ebBIT_1, which should unblock the other task, which will + then suspend itself. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should not have cleared the bits - so all the bits + should still be set. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Clear ebBIT_1 again. */ + if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Resume the other task - which will wait on all the ebCOMBINED_BITS + again - this time clearing the bits when it is unblocked. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set the bit the other task is waiting for. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should have cleared the bits in ebCOMBINED_BITS. + Clear the remaining bits. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* Clear all bits ready for the sync with the other three tasks. The + value returned is the value prior to the bits being cleared. */ + if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* The bits should be clear now. */ + if( xEventGroupGetBits( xEventGroup ) != 0x00 ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static void prvSelectiveBitsTestSlaveFunction( void ) +{ +EventBits_t uxPendBits, uxReturned; + + /* Used in a test that blocks two tasks on various different bits within an + event group - then sets each bit in turn and checks that the correct tasks + unblock at the correct times. + + This function is called by two different tasks - each of which will use a + different bit. Check the task handle to see which task the function was + called by. */ + if( xTaskGetCurrentTaskHandle() == xSyncTask1 ) + { + uxPendBits = ebSELECTIVE_BITS_1; + } + else + { + uxPendBits = ebSELECTIVE_BITS_2; + } + + for( ;; ) + { + /* Wait until it is time to perform the next cycle of the test. The + task is unsuspended by the tests implemented in the + prvSelectiveBitsTestMasterFunction() function. */ + vTaskSuspend( NULL ); + uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY ); + + if( uxReturned == ( EventBits_t ) 0 ) + { + break; + } + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSelectiveBitsTestMasterFunction( void ) +{ +BaseType_t xError = pdFALSE; +EventBits_t uxBit; + + /* Used in a test that blocks two tasks on various different bits within an + event group - then sets each bit in turn and checks that the correct tasks + unblock at the correct times. The two other tasks (xSyncTask1 and + xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in + this test. + + Both other tasks should start in the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Test each bit in the byte individually. */ + for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 ) + { + /* Resume both tasks. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Now both tasks should be blocked on the event group. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set one bit. */ + xEventGroupSetBits( xEventGroup, uxBit ); + + /* Is the bit set in the first set of selective bits? If so the first + sync task should have unblocked and returned to the suspended state. */ + if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + } + + /* Same checks for the second sync task. */ + if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + } + } + + /* Ensure both tasks are blocked on the event group again, then delete the + event group so the other tasks leave this portion of the test. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Deleting the event group is the signal that the two other tasks should + leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main + part of their functionality. */ + vEventGroupDelete( xEventGroup ); + + return xError; +} +/*-----------------------------------------------------------*/ + +void vPeriodicEventGroupsProcessing( void ) +{ +static BaseType_t xCallCount = 0, xISRTestError = pdFALSE; +const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300; +const EventBits_t uxBitsToSet = 0x12U; +EventBits_t uxReturned; +BaseType_t xMessagePosted; + + /* Called periodically from the tick hook to exercise the "FromISR" + functions. */ + + xCallCount++; + + if( xCallCount == xSetBitCount ) + { + /* All the event bits should start clear. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + if( uxReturned != 0x00 ) + { + xISRTestError = pdTRUE; + } + else + { + /* Set the bits. This is called from the tick hook so it is not + necessary to use the last parameter to ensure a context switch + occurs immediately. */ + xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL ); + if( xMessagePosted != pdPASS ) + { + xISRTestError = pdTRUE; + } + } + } + else if( xCallCount == xGetBitsCount ) + { + /* Check the bits were set as expected. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + if( uxReturned != uxBitsToSet ) + { + xISRTestError = pdTRUE; + } + } + else if( xCallCount == xClearBitsCount ) + { + /* Clear the bits again. */ + uxReturned = xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet ); + + /* Check the message was posted. */ + if( uxReturned != pdPASS ) + { + xISRTestError = pdTRUE; + } + + /* Go back to the start. */ + xCallCount = 0; + + /* If no errors have been detected then increment the count of test + cycles. */ + if( xISRTestError == pdFALSE ) + { + ulISRCycles++; + } + } + else + { + /* Nothing else to do. */ + } +} + +/*-----------------------------------------------------------*/ +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreEventGroupTasksStillRunning( void ) +{ +static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0; +BaseType_t xStatus = pdPASS; + + /* Check the tasks are still cycling without finding any errors. */ + if( ulPreviousSetBitCycles == ulTestMasterCycles ) + { + xStatus = pdFAIL; + } + ulPreviousSetBitCycles = ulTestMasterCycles; + + if( ulPreviousWaitBitCycles == ulTestSlaveCycles ) + { + xStatus = pdFAIL; + } + ulPreviousWaitBitCycles = ulTestSlaveCycles; + + if( ulPreviousISRCycles == ulISRCycles ) + { + xStatus = pdFAIL; + } + ulPreviousISRCycles = ulISRCycles; + + return xStatus; +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/GenQTest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/GenQTest.c new file mode 100644 index 0000000..3da052a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/GenQTest.c @@ -0,0 +1,857 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - + * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and + * mutex behaviour. + * + * See the comments above the prvSendFrontAndBackTest() and + * prvLowPriorityMutexTask() prototypes below for more information. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "GenQTest.h" + +#define genqQUEUE_LENGTH ( 5 ) +#define genqNO_BLOCK ( 0 ) + +#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) +#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +#define genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ( 100 ) +/*-----------------------------------------------------------*/ + +/* + * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack() + * macros by using both to fill a queue, then reading from the queue to + * check the resultant queue order is as expected. Queue data is also + * peeked. + */ +static void prvSendFrontAndBackTest( void *pvParameters ); + +/* + * The following three tasks are used to demonstrate the mutex behaviour. + * Each task is given a different priority to demonstrate the priority + * inheritance mechanism. + * + * The low priority task obtains a mutex. After this a high priority task + * attempts to obtain the same mutex, causing its priority to be inherited + * by the low priority task. The task with the inherited high priority then + * resumes a medium priority task to ensure it is not blocked by the medium + * priority task while it holds the inherited high priority. Once the mutex + * is returned the task with the inherited priority returns to its original + * low priority, and is therefore immediately preempted by first the high + * priority task and then the medium prioroity task before it can continue. + */ +static void prvLowPriorityMutexTask( void *pvParameters ); +static void prvMediumPriorityMutexTask( void *pvParameters ); +static void prvHighPriorityMutexTask( void *pvParameters ); + +/* + * Exercises the priority inheritance when a task takes two mutexes, returning + * them in a different order to which they were taken. + */ +static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ); + +/* + * Exercises the priority inheritance when a task takes two mutexes, returning + * them in the same order in which they were taken. + */ +static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ); + +/* + * Task that receives an a mutex that is given from an interrupt - although + * generally mutexes should not be used given in interrupts (and definitely + * never taken in an interrupt) there are some circumstances when it may be + * desirable. NOTE: This function is not declared static to prevent compiler + * warnings being generated in demos where the function is declared but not + * used. + */ +void vInterruptMutexTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; +static volatile uint32_t ulLoopCounter2 = 0; + +/* The variable that is guarded by the mutex in the mutex demo tasks. */ +static volatile uint32_t ulGuardedVariable = 0; + +/* Handles used in the mutext test to suspend and resume the high and medium +priority mutex test tasks. */ +static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask; + +/* A mutex which is given from an interrupt - although generally mutexes should +not be used given in interrupts (and definitely never taken in an interrupt) +there are some circumstances when it may be desirable. */ +static SemaphoreHandle_t xISRMutex = NULL; + +/*-----------------------------------------------------------*/ + +void vStartGenericQueueTasks( UBaseType_t uxPriority ) +{ +QueueHandle_t xQueue; +SemaphoreHandle_t xMutex; + + xISRMutex = xSemaphoreCreateMutex(); + configASSERT( xISRMutex ); + + /* Create the queue that we are going to use for the + prvSendFrontAndBackTest demo. */ + xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, "Gen_Queue_Test" ); + + /* Create the demo task and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); + + /* Create the mutex used by the prvMutexTest task. */ + xMutex = xSemaphoreCreateMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutexes and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" ); + + /* Create the mutex demo tasks and pass it the mutex just created. We are + passing the mutex handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); + + /* Only when the windows simulator is being used - create the task that + receives a mutex from an interrupt. */ + #ifdef _WINDOWS_ + { + xTaskCreate( vInterruptMutexTask, "IntMu", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, NULL ); + } + #endif /* __WINDOWS__ */ +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void *pvParameters ) +{ +uint32_t ulData, ulData2; +QueueHandle_t xQueue; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + xQueue = ( QueueHandle_t ) pvParameters; + + for( ;; ) + { + /* The queue is empty, so sending an item to the back of the queue + should have the same efect as sending it to the front of the queue. + + First send to the front and check everything is as expected. */ + xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + /* Then do the same, sending the data to the back, checking everything + is as expected. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, genqNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + + /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ + for( ulData = 2; ulData < 5; ulData++ ) + { + xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + } + + /* Now the order in the queue should be 2, 3, 4, with 2 being the first + thing to be read out. Now add 1 then 0 to the front of the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 3 ) + { + xErrorDetected = pdTRUE; + } + ulData = 1; + xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + ulData = 0; + xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ); + + /* Now the queue should be full, and when we read the data out we + should receive 0, 1, 2, 3, 4. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) + { + /* Try peeking the data first. */ + if( xQueuePeek( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + + + /* Now try receiving the data for real. The value should be the + same. Clobber the value first so we know we really received it. */ + ulData2 = ~ulData2; + if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + /* The queue should now be empty again. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /* Our queue is empty once more, add 10, 11 to the back. */ + ulData = 10; + if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + ulData = 11; + if( xQueueSend( xQueue, &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 2 ) + { + xErrorDetected = pdTRUE; + } + + /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the + front. */ + for( ulData = 9; ulData >= 7; ulData-- ) + { + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } + + /* Now check that the queue is full, and that receiving data provides + the expected sequence of 7, 8, 9, 10, 11. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, genqNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) + { + if( xQueueReceive( xQueue, &ulData2, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ) +{ + /* Take the mutex. It should be available now. */ + if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set the guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* This task's priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Ensure the task is reporting its priority as blocked and not + suspended (as it would have done in versions up to V7.5.3). */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* The priority of the high priority task should now have been inherited + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Attempt to set the priority of this task to the test priority - + between the idle priority and the medium/high test priorities, but the + actual priority should remain at the high priority. */ + vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as the + inherited priority of this task is above that of the medium priority + task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the medium priority task did run then it will have incremented the + guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Take the local mutex too, so two mutexes are now held. */ + if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the semaphore is given back the priority of this task should not + yet be disinherited because the local mutex is still held. This is a + simplification to allow FreeRTOS to be integrated with middleware that + attempts to hold multiple mutexes without bloating the code with complex + algorithms. It is possible that the high priority mutex task will + execute as it shares a priority with this task. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The guarded variable is only incremented by the medium priority task, + which still should not have executed as this task should remain at the + higher priority, ensure this is the case. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now also give back the local mutex, taking the held count back to 0. + This time the priority of this task should be disinherited back to the + priority to which it was set while the mutex was held. This means + the medium priority task should execute and increment the guarded + variable. When this task next runs both the high and medium priority + tasks will have been suspended again. */ + if( xSemaphoreGive( xLocalMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that the priority of this task has been disinherited to + genqMUTEX_TEST_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Set the priority of this task back to its original value, ready for + the next loop around this test. */ + vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); +} +/*-----------------------------------------------------------*/ + +static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ) +{ + /* Take the mutex. It should be available now. */ + if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set the guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* This task's priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Ensure the task is reporting its priority as blocked and not + suspended (as it would have done in versions up to V7.5.3). */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* The priority of the high priority task should now have been inherited + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as the + inherited priority of this task is above that of the medium priority + task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the medium priority task did run then it will have incremented the + guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Take the local mutex too, so two mutexes are now held. */ + if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the local semaphore is given back the priority of this task should + not yet be disinherited because the shared mutex is still held. This is a + simplification to allow FreeRTOS to be integrated with middleware that + attempts to hold multiple mutexes without bloating the code with complex + algorithms. It is possible that the high priority mutex task will + execute as it shares a priority with this task. */ + if( xSemaphoreGive( xLocalMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The guarded variable is only incremented by the medium priority task, + which still should not have executed as this task should remain at the + higher priority, ensure this is the case. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now also give back the shared mutex, taking the held count back to 0. + This time the priority of this task should be disinherited back to the + priority at which it was created. This means the medium priority task + should execute and increment the guarded variable. When this task next runs + both the high and medium priority tasks will have been suspended again. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that the priority of this task has been disinherited to + genqMUTEX_LOW_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + /* The local mutex is used to check the 'mutexs held' count. */ + xLocalMutex = xSemaphoreCreateMutex(); + configASSERT( xLocalMutex ); + + for( ;; ) + { + /* The first tests exercise the priority inheritance when two mutexes + are taken then returned in a different order to which they were + taken. */ + prvTakeTwoMutexesReturnInDifferentOrder( xMutex, xLocalMutex ); + + /* Just to show this task is still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The second tests exercise the priority inheritance when two mutexes + are taken then returned in the same order in which they were taken. */ + prvTakeTwoMutexesReturnInSameOrder( xMutex, xLocalMutex ); + + /* Just to show this task is still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityMutexTask( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + /* The medium priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is increment the guarded + variable, this is so the low priority task knows that it has + executed. */ + ulGuardedVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters; + + for( ;; ) + { + /* The high priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is attempt to obtain + the mutex. It should find the mutex is not available so a + block time is specified. */ + if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the mutex is eventually obtained it is just given back before + returning to suspend ready for the next cycle. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* NOTE: This function is not declared static to prevent compiler warnings in +demos where the function is declared but not used. */ +void vInterruptMutexTask( void *pvParameters ) +{ +const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ); +volatile uint32_t ulLoops = 0; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Has to wait longer than the time between gives to make sure it + should definitely have received the mutex. */ + if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + else + { + ulLoops++; + } + } +} +/*-----------------------------------------------------------*/ + +void vMutexISRInteractionTest( void ) +{ +static TickType_t xLastGiveTime = 0; +TickType_t xTimeNow; + + xTimeNow = xTaskGetTickCountFromISR(); + if( ( xTimeNow - xLastGiveTime ) >= pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ) ) + { + configASSERT( xISRMutex ); + xSemaphoreGiveFromISR( xISRMutex, NULL ); + xLastGiveTime = xTimeNow; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreGenericQueueTasksStillRunning( void ) +{ +static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; + + /* If the demo task is still running then we expect the loop counters to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + if( ulLastLoopCounter2 == ulLoopCounter2 ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + ulLastLoopCounter2 = ulLoopCounter2; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return ( BaseType_t ) !xErrorDetected; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/IntQueue.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/IntQueue.c new file mode 100644 index 0000000..fcb7157 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/IntQueue.c @@ -0,0 +1,760 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This file defines one of the more complex set of demo/test tasks. They are + * designed to stress test the queue implementation though pseudo simultaneous + * multiple reads and multiple writes from both tasks of varying priority and + * interrupts. The interrupts are prioritised such to ensure that nesting + * occurs (for those ports that support it). + * + * The test ensures that, while being accessed from three tasks and two + * interrupts, all the data sent to the queues is also received from + * the same queue, and that no duplicate items are either sent or received. + * The tests also ensure that a low priority task is never able to successfully + * read from or write to a queue when a task of higher priority is attempting + * the same operation. + */ + +/* Standard includes. */ +#include + +/* SafeRTOS includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" + +/* Demo app includes. */ +#include "IntQueue.h" +#include "IntQueueTimer.h" + +#if( INCLUDE_eTaskGetState != 1 ) + #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file. +#endif + +/* Priorities used by test tasks. */ +#ifndef intqHIGHER_PRIORITY + #define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 2 ) +#endif +#define intqLOWER_PRIORITY ( tskIDLE_PRIORITY ) + +/* The number of values to send/receive before checking that all values were +processed as expected. */ +#define intqNUM_VALUES_TO_LOG ( 200 ) +#define intqSHORT_DELAY ( 140 ) + +/* The value by which the value being sent to or received from a queue should +increment past intqNUM_VALUES_TO_LOG before we check that all values have been +sent/received correctly. This is done to ensure that all tasks and interrupts +accessing the queue have completed their accesses with the +intqNUM_VALUES_TO_LOG range. */ +#define intqVALUE_OVERRUN ( 50 ) + +/* The delay used by the polling task. A short delay is used for code +coverage. */ +#define intqONE_TICK_DELAY ( 1 ) + +/* Each task and interrupt is given a unique identifier. This value is used to +identify which task sent or received each value. The identifier is also used +to distinguish between two tasks that are running the same task function. */ +#define intqHIGH_PRIORITY_TASK1 ( ( UBaseType_t ) 1 ) +#define intqHIGH_PRIORITY_TASK2 ( ( UBaseType_t ) 2 ) +#define intqLOW_PRIORITY_TASK ( ( UBaseType_t ) 3 ) +#define intqFIRST_INTERRUPT ( ( UBaseType_t ) 4 ) +#define intqSECOND_INTERRUPT ( ( UBaseType_t ) 5 ) +#define intqQUEUE_LENGTH ( ( UBaseType_t ) 10 ) + +/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received +from each queue by each task, otherwise an error is detected. */ +#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 ) + +/* Send the next value to the queue that is normally empty. This is called +from within the interrupts. */ +#define timerNORMALLY_EMPTY_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyEmptyQueue++; \ + xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ); \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Send the next value to the queue that is normally full. This is called +from within the interrupts. */ +#define timerNORMALLY_FULL_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyFullQueue++; \ + xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ); \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Receive a value from the normally empty queue. This is called from within +an interrupt. */ +#define timerNORMALLY_EMPTY_RX() \ + if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + prvQueueAccessLogError( __LINE__ ); \ + } \ + else \ + { \ + prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \ + } + +/* Receive a value from the normally full queue. This is called from within +an interrupt. */ +#define timerNORMALLY_FULL_RX() \ + if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \ + { \ + prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \ + } \ + + +/*-----------------------------------------------------------*/ + +/* The two queues used by the test. */ +static QueueHandle_t xNormallyEmptyQueue, xNormallyFullQueue; + +/* Variables used to detect a stall in one of the tasks. */ +static UBaseType_t uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0; + +/* Any unexpected behaviour sets xErrorStatus to fail and log the line that +caused the error in xErrorLine. */ +static BaseType_t xErrorStatus = pdPASS; +static volatile UBaseType_t xErrorLine = ( UBaseType_t ) 0; + +/* Used for sequencing between tasks. */ +static BaseType_t xWasSuspended = pdFALSE; + +/* The values that are sent to the queues. An incremented value is sent each +time to each queue. */ +volatile UBaseType_t uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0; + +/* A handle to some of the tasks is required so they can be suspended/resumed. */ +TaskHandle_t xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2; + +/* When a value is received in a queue the value is ticked off in the array +the array position of the value is set to a the identifier of the task or +interrupt that accessed the queue. This way missing or duplicate values can be +detected. */ +static uint8_t ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; +static uint8_t ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; + +/* The test tasks themselves. */ +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ); +static void prvLowerPriorityNormallyFullTask( void *pvParameters ); +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ); +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ); +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ); + +/* Used to mark the positions within the ucNormallyEmptyReceivedValues and +ucNormallyFullReceivedValues arrays, while checking for duplicates. */ +static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource ); +static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource ); + +/* Logs the line on which an error occurred. */ +static void prvQueueAccessLogError( UBaseType_t uxLine ); + +/*-----------------------------------------------------------*/ + +void vStartInterruptQueueTasks( void ) +{ + /* Start the test tasks. */ + xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 ); + xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 ); + xTaskCreate( prvLowerPriorityNormallyEmptyTask, "L1QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + xTaskCreate( prv1stHigherPriorityNormallyFullTask, "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 ); + xTaskCreate( prv2ndHigherPriorityNormallyFullTask, "H2QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 ); + xTaskCreate( prvLowerPriorityNormallyFullTask, "L2QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + + /* Create the queues that are accessed by multiple tasks and multiple + interrupts. */ + xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) ); + xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xNormallyFullQueue, "NormallyFull" ); + vQueueAddToRegistry( xNormallyEmptyQueue, "NormallyEmpty" ); +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyFullReceivedValues[ uxValue ] = ( uint8_t ) uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyEmptyReceivedValues[ uxValue ] = ( uint8_t ) uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueAccessLogError( UBaseType_t uxLine ) +{ + /* Latch the line number that caused the error. */ + xErrorLine = uxLine; + xErrorStatus = pdFAIL; +} +/*-----------------------------------------------------------*/ + +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ) +{ +UBaseType_t uxRxed, ux, uxTask1, uxTask2, uxInterrupts, uxErrorCount1 = 0, uxErrorCount2 = 0; + + /* The timer should not be started until after the scheduler has started. + More than one task is running this code so we check the parameter value + to determine which task should start the timer. */ + if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + vInitialiseTimerForIntQueueTest(); + } + + for( ;; ) + { + /* Block waiting to receive a value from the normally empty queue. + Interrupts will write to the queue so we should receive a value. */ + if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + /* Note which value was received so we can check all expected + values are received and no values are duplicated. */ + prvRecordValue_NormallyEmpty( uxRxed, ( UBaseType_t ) pvParameters ); + } + + /* Ensure the other task running this code gets a chance to execute. */ + taskYIELD(); + + if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + /* Have we received all the expected values? */ + if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + vTaskSuspend( xHighPriorityNormallyEmptyTask2 ); + + uxTask1 = 0; + uxTask2 = 0; + uxInterrupts = 0; + + /* Loop through the array, checking that both tasks have + placed values into the array, and that no values are missing. + Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyEmptyReceivedValues[ ux ] == 0 ) + { + /* A value is missing. */ + prvQueueAccessLogError( __LINE__ ); + } + else + { + if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK1 ) + { + /* Value was placed into the array by task 1. */ + uxTask1++; + } + else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK2 ) + { + /* Value was placed into the array by task 2. */ + uxTask2++; + } + else if( ucNormallyEmptyReceivedValues[ ux ] == intqSECOND_INTERRUPT ) + { + uxInterrupts++; + } + } + } + + if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 2 seemed to log any values. */ + uxErrorCount1++; + if( uxErrorCount1 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount1 = 0; + } + + if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 1 seemed to log any values. */ + uxErrorCount2++; + if( uxErrorCount2 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount2 = 0; + } + + if( uxInterrupts == 0 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Clear the array again, ready to start a new cycle. */ + memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) ); + + uxHighPriorityLoops1++; + uxValueForNormallyEmptyQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyEmptyTask2 ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ) +{ +UBaseType_t uxValue, uxRxed; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) != errQUEUE_EMPTY ) + { + /* A value should only be obtained when the high priority task is + suspended. */ + if( eTaskGetState( xHighPriorityNormallyEmptyTask1 ) != eSuspended ) + { + prvQueueAccessLogError( __LINE__ ); + } + + prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIORITY_TASK ); + + /* Wake the higher priority task again. */ + vTaskResume( xHighPriorityNormallyEmptyTask1 ); + uxLowPriorityLoops1++; + } + else + { + /* Raise our priority while we send so we can preempt the higher + priority task, and ensure we get the Tx value into the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + portENTER_CRITICAL(); + { + uxValueForNormallyEmptyQueue++; + uxValue = uxValueForNormallyEmptyQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValueToTx, ux, uxInterrupts; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS ) + { + /* intqHIGH_PRIORITY_TASK2 is never suspended so we would not + expect it to ever time out. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Allow the other task running this code to run. */ + taskYIELD(); + + /* Have all the expected values been sent to the queue? */ + if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + /* Make sure the other high priority task completes its send of + any values below intqNUM_VALUE_TO_LOG. */ + vTaskDelay( intqSHORT_DELAY ); + + vTaskSuspend( xHighPriorityNormallyFullTask2 ); + + if( xWasSuspended == pdTRUE ) + { + /* We would have expected the other high priority task to have + set this back to false by now. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Set the suspended flag so an error is not logged if the other + task recognises a time out when it is unsuspended. */ + xWasSuspended = pdTRUE; + + /* Check interrupts are also sending. */ + uxInterrupts = 0U; + + /* Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyFullReceivedValues[ ux ] == 0 ) + { + /* A value was missing. */ + prvQueueAccessLogError( __LINE__ ); + } + else if( ucNormallyFullReceivedValues[ ux ] == intqSECOND_INTERRUPT ) + { + uxInterrupts++; + } + } + + if( uxInterrupts == 0 ) + { + /* No writes from interrupts were found. Are interrupts + actually running? */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Reset the array ready for the next cycle. */ + memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) ); + + uxHighPriorityLoops2++; + uxValueForNormallyFullQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyFullTask2 ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValueToTx, ux; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS ) + { + if( xWasSuspended != pdTRUE ) + { + /* It is ok to time out if the task has been suspended. */ + prvQueueAccessLogError( __LINE__ ); + } + } + + xWasSuspended = pdFALSE; + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValue, uxTxed = 9999; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) != errQUEUE_FULL ) + { + /* Should only succeed when the higher priority task is suspended */ + if( eTaskGetState( xHighPriorityNormallyFullTask1 ) != eSuspended ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskResume( xHighPriorityNormallyFullTask1 ); + uxLowPriorityLoops2++; + } + else + { + /* Raise our priority while we receive so we can preempt the higher + priority task, and ensure we get the value from the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + prvRecordValue_NormallyFull( uxValue, intqLOW_PRIORITY_TASK ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xFirstTimerHandler( void ) +{ +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +UBaseType_t uxRxedValue; +static UBaseType_t uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( UBaseType_t ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + +BaseType_t xSecondTimerHandler( void ) +{ +UBaseType_t uxRxedValue; +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +static UBaseType_t uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( UBaseType_t ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + + timerNORMALLY_EMPTY_RX(); + timerNORMALLY_EMPTY_RX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + + +BaseType_t xAreIntQueueTasksStillRunning( void ) +{ +static UBaseType_t uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0; + + /* xErrorStatus can be set outside of this function. This function just + checks that all the tasks are still cycling. */ + + if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 ) + { + /* The high priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops1 = uxHighPriorityLoops1; + + if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 ) + { + /* The high priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops2 = uxHighPriorityLoops2; + + if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 ) + { + /* The low priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops1 = uxLowPriorityLoops1; + + if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 ) + { + /* The low priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops2 = uxLowPriorityLoops2; + + return xErrorStatus; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/PollQ.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/PollQ.c new file mode 100644 index 0000000..4782f61 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/PollQ.c @@ -0,0 +1,258 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This version of PollQ. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than uint32_t. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE +#define pollqQUEUE_SIZE ( 10 ) +#define pollqPRODUCER_DELAY ( ( TickType_t ) 200 / portTICK_PERIOD_MS ) +#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) ) +#define pollqNO_DELAY ( ( TickType_t ) 0 ) +#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 ) +#define pollqINITIAL_VALUE ( ( BaseType_t ) 0 ) + +/* The task that posts the incrementing number onto the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters ); + +/* The task that empties the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters ); + +/* Variables that are used to check that the tasks are still running with no +errors. */ +static volatile BaseType_t xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE; + +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( UBaseType_t uxPriority ) +{ +static QueueHandle_t xPolledQueue; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xPolledQueue, "Poll_Test_Queue" ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueProducer, pvParameters ) +{ +uint16_t usValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE, xLoop; + + for( ;; ) + { + for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSend( *( ( QueueHandle_t * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS ) + { + /* We should never find the queue full so if we get here there + has been an error. */ + xError = pdTRUE; + } + else + { + if( xError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + portENTER_CRITICAL(); + xPollingProducerCount++; + portEXIT_CRITICAL(); + } + + /* Update the value we are going to post next time around. */ + usValue++; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( pollqPRODUCER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) ) + { + if( xQueueReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + xError = pdTRUE; + + /* Catch-up to the value we received so our next expected + value should again be correct. */ + usExpectedValue = usData; + } + else + { + if( xError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + portENTER_CRITICAL(); + xPollingConsumerCount++; + portEXIT_CRITICAL(); + } + } + + /* Next time round we would expect the number to be one higher. */ + usExpectedValue++; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( pollqCONSUMER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +BaseType_t xArePollingQueuesStillRunning( void ) +{ +BaseType_t xReturn; + + /* Check both the consumer and producer poll count to check they have both + been changed since out last trip round. We do not need a critical section + around the check variables as this is called from a higher priority than + the other tasks that access the same variables. */ + if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) || + ( xPollingProducerCount == pollqINITIAL_VALUE ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Set the check variables back down so we know if they have been + incremented the next time around. */ + xPollingConsumerCount = pollqINITIAL_VALUE; + xPollingProducerCount = pollqINITIAL_VALUE; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QPeek.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QPeek.c new file mode 100644 index 0000000..4f4caa9 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QPeek.c @@ -0,0 +1,474 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the behaviour when data is peeked from a queue when there are + * multiple tasks blocked on the queue. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "QPeek.h" + +#define qpeekQUEUE_LENGTH ( 5 ) +#define qpeekNO_BLOCK ( 0 ) +#define qpeekSHORT_DELAY ( 10 ) + +#define qpeekLOW_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define qpeekMEDIUM_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define qpeekHIGH_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define qpeekHIGHEST_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * The following three tasks are used to demonstrate the peeking behaviour. + * Each task is given a different priority to demonstrate the order in which + * tasks are woken as data is peeked from a queue. + */ +static void prvLowPriorityPeekTask( void *pvParameters ); +static void prvMediumPriorityPeekTask( void *pvParameters ); +static void prvHighPriorityPeekTask( void *pvParameters ); +static void prvHighestPriorityPeekTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/* Counter that is incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; + +/* Handles to the test tasks. */ +TaskHandle_t xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask; +/*-----------------------------------------------------------*/ + +void vStartQueuePeekTasks( void ) +{ +QueueHandle_t xQueue; + + /* Create the queue that we are going to use for the test/demo. */ + xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( uint32_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, "QPeek_Test_Queue" ); + + /* Create the demo tasks and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityPeekTask, "PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityPeekTask, "PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask ); + xTaskCreate( prvHighPriorityPeekTask, "PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask ); + xTaskCreate( prvHighestPriorityPeekTask, "PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask ); +} +/*-----------------------------------------------------------*/ + +static void prvHighestPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + #ifdef USE_STDIO + { + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Queue peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + } + #endif + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the high priority task to execute. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we reach here the high and medium priority tasks should still + be blocked on the queue. We unblocked because the low priority task + wrote a value to the queue, which we should have peeked. Peeking the + data (rather than receiving it) will leave the data on the queue, so + the high priority task should then have also been unblocked, but not + yet executed. */ + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Now we are going to actually receive the data, so when the high + priority task runs it will find the queue empty and return to the + blocked state. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the value. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value - which should have been + the same value as was peeked. */ + xErrorDetected = pdTRUE; + } + + /* Now we will block again as the queue is once more empty. The low + priority task can then execute again. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the low priority task should have again written to the + queue. */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the high priority task to also peek the data. The high priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + + /* This time we are going to do the same as the above test, but the + high priority task is going to receive the data, rather than peek it. + This means that the medium priority task should never peek the value. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the medium priority task to execute. Both the high + and highest priority tasks will then be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the highest priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the medium priority task to also peek the data. The medium priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + /* This time we are going actually receive the value, so the medium + priority task will never peek the data - we removed it from the queue. */ + if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the low priority task to execute. The highest, high + and medium priority tasks will then all be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the high priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Just so we know the test is still running. */ + ulLoopCounter++; + + /* Now we can suspend ourselves so the low priority task can execute + again. */ + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Write some data to the queue. This should unblock the highest + priority task that is waiting to peek data from the queue. */ + ulValue = 0x11223344; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* By the time we get here the data should have been removed from + the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Write another value to the queue, again waking the highest priority + task that is blocked on the queue. */ + ulValue = 0x01234567; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* All the other tasks should now have successfully peeked the data. + The data is still in the queue so we should be able to receive it. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + } + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + + /* Unsuspend the other tasks so we can repeat the test - this time + however not all the other tasks will peek the data as the high + priority task is actually going to remove it from the queue. Send + to front is used just to be different. As the queue is empty it + makes no difference to the result. */ + vTaskResume( xMediumPriorityTask ); + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + ulValue = 0xaabbaabb; + if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* This time we should find that the queue is empty. The high priority + task actually removed the data rather than just peeking it. */ + if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + /* Unsuspend the highest and high priority tasks so we can go back + and repeat the whole thing. The medium priority task should not be + suspended as it was not able to peek the data in this last case. */ + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreQueuePeekTasksStillRunning( void ) +{ +static uint32_t ulLastLoopCounter = 0; + + /* If the demo task is still running then we expect the loopcounter to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return ( BaseType_t ) !xErrorDetected; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueOverwrite.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueOverwrite.c new file mode 100644 index 0000000..15ffb34 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueOverwrite.c @@ -0,0 +1,268 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Basic task to demonstrate the xQueueOverwrite() function. See the comments + * in the function itself. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "QueueOverwrite.h" + +/* A block time of 0 just means "don't block". */ +#define qoDONT_BLOCK 0 + +/* Number of times to overwrite the value in the queue. */ +#define qoLOOPS 5 + +/* The task that uses the queue. */ +static void prvQueueOverwriteTask( void *pvParameters ); + +/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided +prvQueueOverwriteTask() has not found any errors. */ +static uint32_t ulLoopCounter = 0; + +/* Set to pdFALSE if an error is discovered by the +vQueueOverwritePeriodicISRDemo() function. */ +static BaseType_t xISRTestStatus = pdPASS; + +/* The queue that is accessed from the ISR. The queue accessed by the task is +created inside the task itself. */ +static QueueHandle_t xISRQueue = NULL; + +/*-----------------------------------------------------------*/ + +void vStartQueueOverwriteTask( UBaseType_t uxPriority ) +{ +const UBaseType_t uxQueueLength = 1; + + /* Create the queue used by the ISR. xQueueOverwriteFromISR() should only + be used on queues that have a length of 1. */ + xISRQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) ); + + /* Create the test task. The queue used by the test task is created inside + the task itself. */ + xTaskCreate( prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueOverwriteTask( void *pvParameters ) +{ +QueueHandle_t xTaskQueue; +const UBaseType_t uxQueueLength = 1; +uint32_t ulValue, ulStatus = pdPASS, x; + + /* The parameter is not used. */ + ( void ) pvParameters; + + /* Create the queue. xQueueOverwrite() should only be used on queues that + have a length of 1. */ + xTaskQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) ); + configASSERT( xTaskQueue ); + + for( ;; ) + { + /* The queue is empty. Writing to the queue then reading from the queue + should return the item written. */ + ulValue = 10; + xQueueOverwrite( xTaskQueue, &ulValue ); + + ulValue = 0; + xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); + + if( ulValue != 10 ) + { + ulStatus = pdFAIL; + } + + /* Now try writing to the queue several times. Each time the value + in the queue should get overwritten. */ + for( x = 0; x < qoLOOPS; x++ ) + { + /* Write to the queue. */ + xQueueOverwrite( xTaskQueue, &x ); + + /* Check the value in the queue is that written, even though the + queue was not necessarily empty. */ + xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK ); + if( ulValue != x ) + { + ulStatus = pdFAIL; + } + + /* There should always be one item in the queue. */ + if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength ) + { + ulStatus = pdFAIL; + } + } + + /* Empty the queue again. */ + xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); + + if( uxQueueMessagesWaiting( xTaskQueue ) != 0 ) + { + ulStatus = pdFAIL; + } + + if( ulStatus != pdFAIL ) + { + /* Increment a counter to show this task is still running without + error. */ + ulLoopCounter++; + } + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xIsQueueOverwriteTaskStillRunning( void ) +{ +BaseType_t xReturn; + + if( xISRTestStatus != pdPASS ) + { + xReturn = pdFAIL; + } + else if( ulLoopCounter > 0 ) + { + xReturn = pdPASS; + } + else + { + /* The task has either stalled of discovered an error. */ + xReturn = pdFAIL; + } + + ulLoopCounter = 0; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vQueueOverwritePeriodicISRDemo( void ) +{ +static uint32_t ulCallCount = 0; +const uint32_t ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL; +uint32_t ulRx; + + /* This function should be called from an interrupt, such as the tick hook + function vApplicationTickHook(). */ + + configASSERT( xISRQueue ); + + switch( ulCallCount ) + { + case 0: + /* The queue is empty. Write ulTx1 to the queue. In this demo the + last parameter is not used because there are no tasks blocked on + this queue. */ + xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL ); + + /* Peek the queue to check it holds the expected value. */ + xQueuePeekFromISR( xISRQueue, &ulRx ); + if( ulRx != ulTx1 ) + { + xISRTestStatus = pdFAIL; + } + break; + + case 1: + /* The queue already holds ulTx1. Overwrite the value in the queue + with ulTx2. */ + xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL ); + break; + + case 2: + /* Read from the queue to empty the queue again. The value read + should be ulTx2. */ + xQueueReceiveFromISR( xISRQueue, &ulRx, NULL ); + + if( ulRx != ulTx2 ) + { + xISRTestStatus = pdFAIL; + } + break; + } + + /* Run the next case in the switch statement above next time this function + is called. */ + ulCallCount++; + + if( ulCallCount >= ulNumberOfSwitchCases ) + { + /* Go back to the start. */ + ulCallCount = 0; + } +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueSet.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueSet.c new file mode 100644 index 0000000..bc8f0e7 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/QueueSet.c @@ -0,0 +1,715 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Tests the use of queue sets. + * + * A receive task creates a number of queues and adds them to a queue set before + * blocking on the queue set receive. A transmit task and (optionally) an + * interrupt repeatedly unblocks the receive task by sending messages to the + * queues in a pseudo random order. The receive task removes the messages from + * the queues and flags an error if the received message does not match that + * expected. The task sends values in the range 0 to + * queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range + * queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX. + */ + + +/* Standard includes. */ +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "QueueSet.h" + +/* The number of queues that are created and added to the queue set. */ +#define queuesetNUM_QUEUES_IN_SET 3 + +/* The length of each created queue. */ +#define queuesetQUEUE_LENGTH 3 + +/* Block times used in this demo. A block time or 0 means "don't block". */ +#define queuesetSHORT_DELAY 200 +#define queuesetDONT_BLOCK 0 + +/* Messages are sent in incrementing order from both a task and an interrupt. +The task sends values in the range 0 to 0xfffe, and the interrupt sends values +in the range of 0xffff to ULONG_MAX. */ +#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL + +/* The priorities used in this demo. */ +#define queuesetLOW_PRIORITY ( tskIDLE_PRIORITY ) +#define queuesetMEDIUM_PRIORITY ( queuesetLOW_PRIORITY + 1 ) + +/* For test purposes the priority of the sending task is changed after every +queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */ +#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 2 ) + +/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */ +#define queuesetISR_TX_PERIOD ( 100UL ) + +/* A delay inserted when the Tx task changes its priority to be above the idle +task priority to ensure the idle priority tasks get some CPU time before the +next iteration of the queue set Tx task. */ +#define queuesetTX_LOOP_DELAY ( 200 / portTICK_PERIOD_MS ) + +/* The allowable maximum deviation between a received value and the expected +received value. A deviation will occur when data is received from a queue +inside an ISR in between a task receiving from a queue and the task checking +the received value. */ +#define queuesetALLOWABLE_RX_DEVIATION 3 + +/* Ignore values that are at the boundaries of allowable values to make the +testing of limits easier (don't have to deal with wrapping values). */ +#define queuesetIGNORED_BOUNDARY ( queuesetALLOWABLE_RX_DEVIATION * 2 ) + +typedef enum +{ + eEqualPriority = 0, /* Tx and Rx tasks have the same priority. */ + eTxHigherPriority, /* The priority of the Tx task is above that of the Rx task. */ + eTxLowerPriority /* The priority of the Tx task is below that of the Rx task. */ +} eRelativePriorities; + +/* + * The task that periodically sends to the queue set. + */ +static void prvQueueSetSendingTask( void *pvParameters ); + +/* + * The task that reads from the queue set. + */ +static void prvQueueSetReceivingTask( void *pvParameters ); + +/* + * Check the value received from a queue is the expected value. Some values + * originate from the send task, some values originate from the ISR, with the + * range of the value being used to distinguish between the two message + * sources. + */ +static void prvCheckReceivedValue( uint32_t ulReceived ); + +/* + * For purposes of test coverage, functions that read from and write to a + * queue set from an ISR respectively. + */ +static void prvReceiveFromQueueInSetFromISR( void ); +static void prvSendToQueueInSetFromISR( void ); + +/* + * Create the queues and add them to a queue set before resuming the Tx + * task. + */ +static void prvSetupTest( void ); + +/* + * Checks a value received from a queue falls within the range of expected + * values. + */ +static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived ); + +/* + * Increase test coverage by occasionally change the priorities of the two tasks + * relative to each other. */ +static void prvChangeRelativePriorities( void ); + +/* + * Local pseudo random number seed and return functions. Used to avoid calls + * to the standard library. + */ +static uint32_t prvRand( void ); +static void prvSRand( uint32_t ulSeed ); + +/*-----------------------------------------------------------*/ + +/* The queues that are added to the set. */ +static QueueHandle_t xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; + +/* Counts how many times each queue in the set is used to ensure all the +queues are used. */ +static uint32_t ulQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; + +/* The handle of the queue set to which the queues are added. */ +static QueueSetHandle_t xQueueSet; + +/* If the prvQueueSetReceivingTask() task has not detected any errors then +it increments ulCycleCounter on each iteration. +xAreQueueSetTasksStillRunning() returns pdPASS if the value of +ulCycleCounter has changed between consecutive calls, and pdFALSE if +ulCycleCounter has stopped incrementing (indicating an error condition). */ +static volatile uint32_t ulCycleCounter = 0UL; + +/* Set to pdFAIL if an error is detected by any queue set task. +ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */ +static volatile BaseType_t xQueueSetTasksStatus = pdPASS; + +/* Just a flag to let the function that writes to a queue from an ISR know that +the queues are setup and can be used. */ +static volatile BaseType_t xSetupComplete = pdFALSE; + +/* The value sent to the queue from the ISR is file scope so the +xAreQueeuSetTasksStillRunning() function can check it is incrementing as +expected. */ +static volatile uint32_t ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE; + +/* Used by the pseudo random number generator. */ +static uint32_t ulNextRand = 0; + +/* The task handles are stored so their priorities can be changed. */ +TaskHandle_t xQueueSetSendingTask, xQueueSetReceivingTask; + +/*-----------------------------------------------------------*/ + +void vStartQueueSetTasks( void ) +{ + /* Create the tasks. */ + xTaskCreate( prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask ); + xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask ); + + /* It is important that the sending task does not attempt to write to a + queue before the queue has been created. It is therefore placed into the + suspended state before the scheduler has started. It is resumed by the + receiving task after the receiving task has created the queues and added the + queues to the queue set. */ + vTaskSuspend( xQueueSetSendingTask ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreQueueSetTasksStillRunning( void ) +{ +static uint32_t ulLastCycleCounter, ulLastISRTxValue = 0; +static uint32_t ulLastQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; +BaseType_t xReturn = pdPASS, x; + + if( ulLastCycleCounter == ulCycleCounter ) + { + /* The cycle counter is no longer being incremented. Either one of the + tasks is stalled or an error has been detected. */ + xReturn = pdFAIL; + } + + ulLastCycleCounter = ulCycleCounter; + + /* Ensure that all the queues in the set have been used. This ensures the + test is working as intended and guards against the rand() in the Tx task + missing some values. */ + for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) + { + if( ulLastQueueUsedCounter[ x ] == ulQueueUsedCounter[ x ] ) + { + xReturn = pdFAIL; + } + + ulLastQueueUsedCounter[ x ] = ulQueueUsedCounter[ x ]; + } + + /* Check the global status flag. */ + if( xQueueSetTasksStatus != pdPASS ) + { + xReturn = pdFAIL; + } + + /* Check that the ISR is still sending values to the queues too. */ + if( ulISRTxValue == ulLastISRTxValue ) + { + xReturn = pdFAIL; + } + else + { + ulLastISRTxValue = ulISRTxValue; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvQueueSetSendingTask( void *pvParameters ) +{ +uint32_t ulTaskTxValue = 0, ulQueueToWriteTo; +QueueHandle_t xQueueInUse; + + /* Remove compiler warning about the unused parameter. */ + ( void ) pvParameters; + + /* Seed mini pseudo random number generator. */ + prvSRand( ( uint32_t ) &ulTaskTxValue ); + + for( ;; ) + { + /* Generate the index for the queue to which a value is to be sent. */ + ulQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET; + xQueueInUse = xQueues[ ulQueueToWriteTo ]; + + /* Note which index is being written to to ensure all the queues are + used. */ + ( ulQueueUsedCounter[ ulQueueToWriteTo ] )++; + + /* Send to the queue to unblock the task that is waiting for data to + arrive on a queue within the queue set to which this queue belongs. */ + if( xQueueSendToBack( xQueueInUse, &ulTaskTxValue, portMAX_DELAY ) != pdPASS ) + { + /* The send should always pass as an infinite block time was + used. */ + xQueueSetTasksStatus = pdFAIL; + } + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + ulTaskTxValue++; + + /* If the Tx value has reached the range used by the ISR then set it + back to 0. */ + if( ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE ) + { + ulTaskTxValue = 0; + } + + /* Increase test coverage by occasionally change the priorities of the + two tasks relative to each other. */ + prvChangeRelativePriorities(); + } +} +/*-----------------------------------------------------------*/ + +static void prvChangeRelativePriorities( void ) +{ +static UBaseType_t ulLoops = 0; +static eRelativePriorities ePriorities = eEqualPriority; + + /* Occasionally change the task priority relative to the priority of + the receiving task. */ + ulLoops++; + if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS ) + { + ulLoops = 0; + + switch( ePriorities ) + { + case eEqualPriority: + /* Both tasks are running with medium priority. Now lower the + priority of the receiving task so the Tx task has the higher + relative priority. */ + vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY ); + ePriorities = eTxHigherPriority; + break; + + case eTxHigherPriority: + /* The Tx task is running with a higher priority than the Rx + task. Switch the priorities around so the Rx task has the + higher relative priority. */ + vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY ); + vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY ); + ePriorities = eTxLowerPriority; + break; + + case eTxLowerPriority: + /* The Tx task is running with a lower priority than the Rx + task. Make the priorities equal again. */ + vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY ); + ePriorities = eEqualPriority; + + /* When both tasks are using a non-idle priority the queue set + tasks will starve idle priority tasks of execution time - so + relax a bit before the next iteration to minimise the impact. */ + vTaskDelay( queuesetTX_LOOP_DELAY ); + + break; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueSetReceivingTask( void *pvParameters ) +{ +uint32_t ulReceived; +QueueHandle_t xActivatedQueue; + + /* Remove compiler warnings. */ + ( void ) pvParameters; + + /* Create the queues and add them to the queue set before resuming the Tx + task. */ + prvSetupTest(); + + for( ;; ) + { + /* Wait for a message to arrive on one of the queues in the set. */ + xActivatedQueue = xQueueSelectFromSet( xQueueSet, portMAX_DELAY ); + configASSERT( xActivatedQueue ); + + if( xActivatedQueue == NULL ) + { + /* This should not happen as an infinite delay was used. */ + xQueueSetTasksStatus = pdFAIL; + } + else + { + /* Reading from the queue should pass with a zero block time as + this task will only run when something has been posted to a task + in the queue set. */ + if( xQueueReceive( xActivatedQueue, &ulReceived, queuesetDONT_BLOCK ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Ensure the value received was the value expected. This function + manipulates file scope data and is also called from an ISR, hence + the critical section. */ + taskENTER_CRITICAL(); + { + prvCheckReceivedValue( ulReceived ); + } + taskEXIT_CRITICAL(); + } + + if( xQueueSetTasksStatus == pdPASS ) + { + ulCycleCounter++; + } + } +} +/*-----------------------------------------------------------*/ + +void vQueueSetAccessQueueSetFromISR( void ) +{ +static uint32_t ulCallCount = 0; + + /* xSetupComplete is set to pdTRUE when the queues have been created and + are available for use. */ + if( xSetupComplete == pdTRUE ) + { + /* It is intended that this function is called from the tick hook + function, so each call is one tick period apart. */ + ulCallCount++; + if( ulCallCount > queuesetISR_TX_PERIOD ) + { + ulCallCount = 0; + + /* First attempt to read from the queue set. */ + prvReceiveFromQueueInSetFromISR(); + + /* Then write to the queue set. */ + prvSendToQueueInSetFromISR(); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckReceivedValue( uint32_t ulReceived ) +{ +static uint32_t ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE; + + /* Values are received in tasks and interrupts. It is likely that the + receiving task will sometimes get preempted by the receiving interrupt + between reading a value from the queue and calling this function. When + that happens, if the receiving interrupt calls this function the values + will get passed into this function slightly out of order. For that + reason the value passed in is tested against a small range of expected + values, rather than a single absolute value. To make the range testing + easier values in the range limits are ignored. */ + + /* If the received value is equal to or greater than + queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */ + if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE ) + { + /* The value was sent from the ISR. */ + if( ( ulReceived - queuesetINITIAL_ISR_TX_VALUE ) < queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the lower limit of the expected range. + Don't test it and expect to receive one higher next time. */ + } + else if( ( ULONG_MAX - ulReceived ) <= queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the higher limit of the expected range. + Don't test it and expect to wrap soon. */ + } + else + { + /* Check the value against its expected value range. */ + if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromISR ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + + configASSERT( xQueueSetTasksStatus ); + + /* It is expected to receive an incrementing number. */ + ulExpectedReceivedFromISR++; + if( ulExpectedReceivedFromISR == 0 ) + { + ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE; + } + } + else + { + /* The value was sent from the Tx task. */ + if( ulReceived < queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the lower limit of the expected range. + Don't test it, and expect to receive one higher next time. */ + } + else if( ( ( queuesetINITIAL_ISR_TX_VALUE - 1 ) - ulReceived ) <= queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the higher limit of the expected range. + Don't test it and expect to wrap soon. */ + } + else + { + /* Check the value against its expected value range. */ + if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromTask ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + + configASSERT( xQueueSetTasksStatus ); + + /* It is expected to receive an incrementing number. */ + ulExpectedReceivedFromTask++; + if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE ) + { + ulExpectedReceivedFromTask = 0; + } + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived ) +{ +BaseType_t xReturn = pdPASS; + + if( ulReceived > ulExpectedReceived ) + { + configASSERT( ( ulReceived - ulExpectedReceived ) <= queuesetALLOWABLE_RX_DEVIATION ); + if( ( ulReceived - ulExpectedReceived ) > queuesetALLOWABLE_RX_DEVIATION ) + { + xReturn = pdFALSE; + } + } + else + { + configASSERT( ( ulExpectedReceived - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION ); + if( ( ulExpectedReceived - ulReceived ) > queuesetALLOWABLE_RX_DEVIATION ) + { + xReturn = pdFALSE; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvReceiveFromQueueInSetFromISR( void ) +{ +QueueSetMemberHandle_t xActivatedQueue; +uint32_t ulReceived; + + /* See if any of the queues in the set contain data. */ + xActivatedQueue = xQueueSelectFromSetFromISR( xQueueSet ); + + if( xActivatedQueue != NULL ) + { + /* Reading from the queue for test purposes only. */ + if( xQueueReceiveFromISR( xActivatedQueue, &ulReceived, NULL ) != pdPASS ) + { + /* Data should have been available as the handle was returned from + xQueueSelectFromSetFromISR(). */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Ensure the value received was the value expected. */ + prvCheckReceivedValue( ulReceived ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSendToQueueInSetFromISR( void ) +{ +static BaseType_t xQueueToWriteTo = 0; + + if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulISRTxValue, NULL ) == pdPASS ) + { + ulISRTxValue++; + + /* If the Tx value has wrapped then set it back to its + initial value. */ + if( ulISRTxValue == 0UL ) + { + ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE; + } + + /* Use a different queue next time. */ + xQueueToWriteTo++; + if( xQueueToWriteTo >= queuesetNUM_QUEUES_IN_SET ) + { + xQueueToWriteTo = 0; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSetupTest( void ) +{ +BaseType_t x; +uint32_t ulValueToSend = 0; + + /* Ensure the queues are created and the queue set configured before the + sending task is unsuspended. + + First Create the queue set such that it will be able to hold a message for + every space in every queue in the set. */ + xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ); + + for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) + { + /* Create the queue and add it to the set. The queue is just holding + uint32_t value. */ + xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( uint32_t ) ); + configASSERT( xQueues[ x ] ); + if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + else + { + /* The queue has now been added to the queue set and cannot be added to + another. */ + if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + } + + /* Attempt to remove a queue from a queue set it does not belong + to (NULL being passed as the queue set in this case). */ + if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL ) + { + /* It is not possible to successfully remove a queue from a queue + set it does not belong to. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Attempt to remove a queue from the queue set it does belong to. */ + if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) + { + /* It should be possible to remove the queue from the queue set it + does belong to. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Add an item to the queue before attempting to add it back into the + set. */ + xQueueSend( xQueues[ 0 ], ( void * ) &ulValueToSend, 0 ); + if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdFAIL ) + { + /* Should not be able to add a non-empty queue to a set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Remove the item from the queue before adding the queue back into the + set so the dynamic tests can begin. */ + xQueueReceive( xQueues[ 0 ], &ulValueToSend, 0 ); + if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) + { + /* If the queue was successfully removed from the queue set then it + should be possible to add it back in again. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* The task that sends to the queues is not running yet, so attempting to + read from the queue set should fail. */ + if( xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY ) != NULL ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Resume the task that writes to the queues. */ + vTaskResume( xQueueSetSendingTask ); + + /* Let the ISR access the queues also. */ + xSetupComplete = pdTRUE; +} +/*-----------------------------------------------------------*/ + +static uint32_t prvRand( void ) +{ + ulNextRand = ( ulNextRand * 1103515245UL ) + 12345UL; + return ( ulNextRand / 65536UL ) % 32768UL; +} +/*-----------------------------------------------------------*/ + +static void prvSRand( uint32_t ulSeed ) +{ + ulNextRand = ulSeed; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/TimerDemo.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/TimerDemo.c new file mode 100644 index 0000000..68ece37 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/TimerDemo.c @@ -0,0 +1,1079 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the behaviour of timers. Some timers are created before the scheduler + * is started, and some after. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +/* Demo program include files. */ +#include "TimerDemo.h" + +#if ( configTIMER_TASK_PRIORITY < 1 ) + #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly. +#endif + +#define tmrdemoDONT_BLOCK ( ( TickType_t ) 0 ) +#define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( TickType_t ) 3 ) +#define trmdemoNUM_TIMER_RESETS ( ( uint8_t ) 10 ) + +/*-----------------------------------------------------------*/ + +/* The callback functions used by the timers. These each increment a counter +to indicate which timer has expired. The auto-reload timers that are used by +the test task (as opposed to being used from an ISR) all share the same +prvAutoReloadTimerCallback() callback function, and use the ID of the +pxExpiredTimer parameter passed into that function to know which counter to +increment. The other timers all have their own unique callback function and +simply increment their counters without using the callback function parameter. */ +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvTimerTestTask( void *pvParameters ); +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ); + +/* The test functions used by the timer test task. These manipulate the auto +reload and one shot timers in various ways, then delay, then inspect the timers +to ensure they have behaved as expected. */ +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ); +static void prvTest2_CheckTaskAndTimersInitialState( void ); +static void prvTest3_CheckAutoReloadExpireRates( void ); +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ); +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ); +static void prvTest6_CheckAutoReloadResetBehaviour( void ); +static void prvResetStartConditionsForNextIteration( void ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdFAIL should any unexpected behaviour be +detected in any of the demo tests. */ +static volatile BaseType_t xTestStatus = pdPASS; + +/* Counter that is incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; + +/* A set of auto reload timers - each of which use the same callback function. +The callback function uses the timer ID to index into, and then increment, a +counter in the ucAutoReloadTimerCounters[] array. The auto reload timers +referenced from xAutoReloadTimers[] are used by the prvTimerTestTask task. */ +static TimerHandle_t xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; +static uint8_t ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; + +/* The one shot timer is configured to use a callback function that increments +ucOneShotTimerCounter each time it gets called. */ +static TimerHandle_t xOneShotTimer = NULL; +static uint8_t ucOneShotTimerCounter = ( uint8_t ) 0; + +/* The ISR reload timer is controlled from the tick hook to exercise the timer +API functions that can be used from an ISR. It is configured to increment +ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISRAutoReloadTimer = NULL; +static uint8_t ucISRAutoReloadTimerCounter = ( uint8_t ) 0; + +/* The ISR one shot timer is controlled from the tick hook to exercise the timer +API functions that can be used from an ISR. It is configured to increment +ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISROneShotTimer = NULL; +static uint8_t ucISROneShotTimerCounter = ( uint8_t ) 0; + +/* The period of all the timers are a multiple of the base period. The base +period is configured by the parameter to vStartTimerDemoTask(). */ +static TickType_t xBasePeriod = 0; + +/*-----------------------------------------------------------*/ + +void vStartTimerDemoTask( TickType_t xBasePeriodIn ) +{ + /* Start with the timer and counter arrays clear - this is only necessary + where the compiler does not clear them automatically on start up. */ + memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) ); + memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) ); + + /* Store the period from which all the timer periods will be generated from + (multiples of). */ + xBasePeriod = xBasePeriodIn; + + /* Create a set of timers for use by this demo/test. */ + prvTest1_CreateTimersWithoutSchedulerRunning(); + + /* Create the task that will control and monitor the timers. This is + created at a lower priority than the timer service task to ensure, as + far as it is concerned, commands on timers are actioned immediately + (sending a command to the timer service task will unblock the timer service + task, which will then preempt this task). */ + if( xTestStatus != pdFAIL ) + { + xTaskCreate( prvTimerTestTask, "Tmr Tst", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTimerTestTask( void *pvParameters ) +{ + ( void ) pvParameters; + + /* Create a one-shot timer for use later on in this test. */ + xOneShotTimer = xTimerCreate( "Oneshot Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */ + pdFALSE, /* Don't auto-reload - hence a one shot timer. */ + ( void * ) 0, /* The timer identifier. In this case this is not used as the timer has its own callback. */ + prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */ + + if( xOneShotTimer == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + + /* Ensure all the timers are in their expected initial state. This + depends on the timer service task having a higher priority than this task. */ + prvTest2_CheckTaskAndTimersInitialState(); + + for( ;; ) + { + /* Check the auto reload timers expire at the expected/correct rates. */ + prvTest3_CheckAutoReloadExpireRates(); + + /* Check the auto reload timers can be stopped correctly, and correctly + report their state. */ + prvTest4_CheckAutoReloadTimersCanBeStopped(); + + /* Check the one shot timer only calls its callback once after it has been + started, and that it reports its state correctly. */ + prvTest5_CheckBasicOneShotTimerBehaviour(); + + /* Check timer reset behaviour. */ + prvTest6_CheckAutoReloadResetBehaviour(); + + /* Start the timers again to restart all the tests over again. */ + prvResetStartConditionsForNextIteration(); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the created task is still running and has not +detected any errors. */ +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ) +{ +static uint32_t ulLastLoopCounter = 0UL; +TickType_t xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax; +static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCycleFrequency; + + if( xLastCycleFrequency != xCycleFrequency ) + { + /* The cycle frequency has probably become much faster due to an error + elsewhere. Start counting Iterations again. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + xLastCycleFrequency = xCycleFrequency; + } + + /* Calculate the maximum number of times that it is permissible for this + function to be called without ulLoopCounter being incremented. This is + necessary because the tests in this file block for extended periods, and the + block period might be longer than the time between calls to this function. */ + xMaxBlockTimeUsedByTheseTests = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + xLoopCounterIncrementTimeMax = ( xMaxBlockTimeUsedByTheseTests / xCycleFrequency ) + 1; + + /* If the demo task is still running then the loop counter is expected to + have incremented every xLoopCounterIncrementTimeMax calls. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xIterationsWithoutCounterIncrement++; + if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax ) + { + /* The tests appear to be no longer running (stalled). */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else + { + /* ulLoopCounter changed, so the count of times this function was called + without a change can be reset to zero. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xTestStatus + to pdFAIL. */ + + return xTestStatus; +} +/*-----------------------------------------------------------*/ + +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ) +{ +UBaseType_t xTimer; + + for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ ) + { + /* As the timer queue is not yet full, it should be possible to both create + and start a timer. These timers are being started before the scheduler has + been started, so their block times should get set to zero within the timer + API itself. */ + xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ),/* The period for the timer. The plus 1 ensures a period of zero is not specified. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ + + configASSERT( strcmp( pcTimerGetTimerName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 ); + + if( xAutoReloadTimers[ xTimer ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + /* The scheduler has not yet started, so the block period of + portMAX_DELAY should just get set to zero in xTimerStart(). Also, + the timer queue is not yet full so xTimerStart() should return + pdPASS. */ + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + } + + /* The timers queue should now be full, so it should be possible to create + another timer, but not possible to start it (the timer queue will not get + drained until the scheduler has been started. */ + xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback executed when the timer expires. */ + + if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS ) + { + /* This time it would not be expected that the timer could be + started at this point. */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + /* Create the timers that are used from the tick interrupt to test the timer + API functions that can be called from an ISR. */ + xISRAutoReloadTimer = xTimerCreate( "ISR AR", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdTRUE, /* This is an auto reload timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */ + + xISROneShotTimer = xTimerCreate( "ISR OS", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdFALSE, /* This is a one shot timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */ + + if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest2_CheckTaskAndTimersInitialState( void ) +{ +uint8_t ucTimer; + + /* Ensure all the timers are in their expected initial state. This depends + on the timer service task having a higher priority than this task. + + auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active, + and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it + could not be started prior to the scheduler being started when it was + created). */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest3_CheckAutoReloadExpireRates( void ) +{ +uint8_t ucMaxAllowableValue, ucMinAllowableValue, ucTimer; +TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber; + + /* Check the auto reload timers expire at the expected rates. */ + + + /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow + all the auto reload timers to expire at least once. */ + xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + vTaskDelay( xBlockPeriod ); + + /* Check that all the auto reload timers have called their callback + function the expected number of times. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The expected number of expiries is equal to the block period divided + by the timer period. */ + xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod ); + xExpectedNumber = xBlockPeriod / xTimerPeriod; + + ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber ) ; + ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */ + + if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) || + ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue ) + ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ) +{ +uint8_t ucTimer; + + /* Check the auto reload timers can be stopped correctly, and correctly + report their state. */ + + /* Stop all the active timers. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been stopped yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the timer. This will appear to happen immediately to + this task because this task is running at a priority below the + timer service task. */ + xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + taskENTER_CRITICAL(); + { + /* The timer in array position configTIMER_QUEUE_LENGTH should not + be active. The critical section is used to ensure the timer does + not call its callback between the next line running and the array + being cleared back to zero, as that would mask an error condition. */ + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback count. */ + memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) ); + } + taskEXIT_CRITICAL(); + + /* The timers are now all inactive, so this time, after delaying, none + of the callback counters should have incremented. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( ucAutoReloadTimerCounters[ ucTimer ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + the check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ) +{ + /* Check the one shot timer only calls its callback once after it has been + started, and that it reports its state correctly. */ + + /* The one shot timer should not be active yet. */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Start the one shot timer and check that it reports its state correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Delay for three times as long as the one shot timer period, then check + to ensure it has only called its callback once, and is now not in the + active state. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( TickType_t ) 3 ); + + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + /* Reset the one shot timer callback count. */ + ucOneShotTimerCounter = ( uint8_t ) 0; + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest6_CheckAutoReloadResetBehaviour( void ) +{ +uint8_t ucTimer; + + /* Check timer reset behaviour. */ + + /* Restart the one shot timer and check it reports its status correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restart one of the auto reload timers and check that it reports its + status correctly. */ + xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ ) + { + /* Delay for half as long as the one shot timer period, then reset it. + It should never expire while this is done, so its callback count should + never increment. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 ); + + /* Check both running timers are still active, but have not called their + callback functions. */ + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Reset both running timers. */ + xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); + xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + the check task knows this task is still running. */ + ulLoopCounter++; + } + } + + /* Finally delay long enough for both running timers to expire. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + + /* The timers were not reset during the above delay period so should now + both have called their callback functions. */ + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* The one shot timer should no longer be active, while the auto reload + timer should still be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Stop the auto reload timer again. */ + xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback counts, ready for another iteration of these + tests. */ + ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( uint8_t ) 0; + ucOneShotTimerCounter = ( uint8_t ) 0; + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the check + task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvResetStartConditionsForNextIteration( void ) +{ +uint8_t ucTimer; + + /* Start the timers again to start all the tests over again. */ + + /* Start the timers again. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now start the timer. This will appear to happen immediately to + this task because this task is running at a priority below the timer + service task. */ + xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +void vTimerPeriodicISRTests( void ) +{ +static TickType_t uxTick = ( TickType_t ) -1; + +#if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) + /* The timer service task is not the highest priority task, so it cannot + be assumed that timings will be exact. Timers should never call their + callback before their expiry time, but a margin is permissible for calling + their callback after their expiry time. If exact timing is required then + configTIMER_TASK_PRIORITY must be set to ensure the timer service task + is the highest priority task in the system. + + This function is called from the tick hook. The tick hook is called + even when the scheduler is suspended. Therefore it is possible that the + uxTick count maintained in this function is temporarily ahead of the tick + count maintained by the kernel. When this is the case a message posted from + this function will assume a time stamp in advance of the real time stamp, + which can result in a timer being processed before this function expects it + to. For example, if the kernel's tick count was 100, and uxTick was 102, + then this function will not expect the timer to have expired until the + kernel's tick count is (102 + xBasePeriod), whereas in reality the timer + will expire when the kernel's tick count is (100 + xBasePeriod). For this + reason xMargin is used as an allowable margin for premature timer expiries + as well as late timer expiries. */ + const TickType_t xMargin = 6; +#else + #ifdef _WINDOWS_ + /* Windows is not real real time. */ + const TickType_t xMargin = 8; + #else + const TickType_t xMargin = 4; + #endif /* _WINDOWS_ */ +#endif + + + uxTick++; + + if( uxTick == 0 ) + { + /* The timers will have been created, but not started. Start them now + by setting their period. */ + ucISRAutoReloadTimerCounter = 0; + ucISROneShotTimerCounter = 0; + + /* It is possible that the timer task has not yet made room in the + timer queue. If the timers cannot be started then reset uxTick so + another attempt is made later. */ + uxTick = ( TickType_t ) -1; + + /* Try starting first timer. */ + if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* First timer was started, try starting the second timer. */ + if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* Both timers were started, so set the uxTick back to its + proper value. */ + uxTick = 0; + } + else + { + /* Second timer could not be started, so stop the first one + again. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + } + } + else if( uxTick == ( xBasePeriod - xMargin ) ) + { + /* Neither timer should have expired yet. */ + if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( xBasePeriod + xMargin ) ) + { + /* Both timers should now have expired once. The auto reload timer will + still be active, but the one shot timer should now have stopped. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped - however, at this time neither of the timers + should have expired again since the last test. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped. At this time the auto reload timer should have + expired again, but the one shot timer count should not have changed. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( TickType_t ) 2U ) ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped. Again though, at this time, neither timer call + back should have been called since the last test. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 3 * xBasePeriod ) ) + { + /* Start the one shot timer again. */ + xTimerStartFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer and one shot timer will be active. At + this time the auto reload timer should have expired again, but the one + shot timer count should not have changed yet. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the auto reload timer. The one shot timer was started + a few ticks ago. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) ) + { + /* The auto reload timer is now stopped, and the one shot timer is + active, but at this time neither timer should have expired since the + last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer is now stopped, and the one shot timer is + active. The one shot timer should have expired again, but the auto + reload timer should not have executed its callback. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 8 * xBasePeriod ) ) + { + /* The auto reload timer is now stopped, and the one shot timer has + already expired and then stopped itself. Both callback counters should + not have incremented since the last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now reset the one shot timer. */ + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer once again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one shot timer should have been running and this time it + should have expired. Check its callback count has been incremented. + The auto reload timer is still not running so should still have the same + count value. This time the one shot timer is not reset so should not + restart from its expiry period again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 15 * xBasePeriod ) ) + { + /* Neither timer should be running now. Check neither callback count + has incremented, then go back to the start to run these tests all + over again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + uxTick = ( TickType_t ) -1; + } +} +/*-----------------------------------------------------------*/ + +/*** Timer callback functions are defined below here. ***/ + +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ +uint32_t ulTimerID; + + ulTimerID = ( uint32_t ) pvTimerGetTimerID( pxExpiredTimer ); + if( ulTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) ) + { + ( ucAutoReloadTimerCounters[ ulTimerID ] )++; + } + else + { + /* The timer ID appears to be unexpected (invalid). */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + callback function. */ + ( void ) pxExpiredTimer; + + ucOneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + callback function. */ + ( void ) pxExpiredTimer; + + ucISRAutoReloadTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + callback function. */ + ( void ) pxExpiredTimer; + + ucISROneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/blocktim.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/blocktim.c new file mode 100644 index 0000000..2528317 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/blocktim.c @@ -0,0 +1,505 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This file contains some test scenarios that ensure tasks do not exit queue + * send or receive functions prematurely. A description of the tests is + * included within the code. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "blocktim.h" + +/* Task priorities. Allow these to be overridden. */ +#ifndef bktPRIMARY_PRIORITY + #define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) +#endif + +#ifndef bktSECONDARY_PRIORITY + #define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 ) +#endif + +/* Task behaviour. */ +#define bktQUEUE_LENGTH ( 5 ) +#define bktSHORT_WAIT ( ( ( TickType_t ) 20 ) / portTICK_PERIOD_MS ) +#define bktPRIMARY_BLOCK_TIME ( 10 ) +#define bktALLOWABLE_MARGIN ( 15 ) +#define bktTIME_TO_BLOCK ( 175 ) +#define bktDONT_BLOCK ( ( TickType_t ) 0 ) +#define bktRUN_INDICATOR ( ( UBaseType_t ) 0x55 ) + +/* The queue on which the tasks block. */ +static QueueHandle_t xTestQueue; + +/* Handle to the secondary task is required by the primary task for calls +to vTaskSuspend/Resume(). */ +static TaskHandle_t xSecondary; + +/* Used to ensure that tasks are still executing without error. */ +static volatile BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0; +static volatile BaseType_t xErrorOccurred = pdFALSE; + +/* Provides a simple mechanism for the primary task to know when the +secondary task has executed. */ +static volatile UBaseType_t xRunIndicator; + +/* The two test tasks. Their behaviour is commented within the files. */ +static void vPrimaryBlockTimeTestTask( void *pvParameters ); +static void vSecondaryBlockTimeTestTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +void vCreateBlockTimeTasks( void ) +{ + /* Create the queue on which the two tasks block. */ + xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" ); + + /* Create the two test tasks. */ + xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); + xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); +} +/*-----------------------------------------------------------*/ + +static void vPrimaryBlockTimeTestTask( void *pvParameters ) +{ +BaseType_t xItem, xData; +TickType_t xTimeWhenBlocking; +TickType_t xTimeToBlock, xBlockedTime; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 + + Simple block time wakeup test on queue receives. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is empty. Attempt to read from the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 2 + + Simple block time wakeup test on queue sends. + + First fill the queue. It should be empty so all sends should pass. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is full. Attempt to write to the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 3 + + Wake the other task, it will block attempting to post to the queue. + When we read from the queue the other task will wake, but before it + can run we will post to the queue again. When the other task runs it + will find the queue still full, even though it was woken. It should + recognise that its block time has not expired and return to block for + the remains of its block time. + + Wake the other task so it blocks attempting to post to the already + full queue. */ + xRunIndicator = 0; + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + /* The other task has not yet executed. */ + vTaskDelay( bktSHORT_WAIT ); + } + /* Make sure the other task is blocked on the queue. */ + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we make space on the queue the other task should wake + but not execute as this task has higher priority. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now fill the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + full ourselves, and the other task have set xRunIndicator. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + + /* Set the priority back down. */ + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + + /********************************************************************* + Test 4 + + As per test 3 - but with the send and receive the other way around. + The other task blocks attempting to read from the queue. + + Empty the queue. We should find that it is full. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Wake the other task so it blocks attempting to read from the + already empty queue. */ + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we place an item on the queue the other task should + wake but not execute as this task has higher priority. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now empty the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + empty ourselves, and the other task would be suspended. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + + xPrimaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void vSecondaryBlockTimeTestTask( void *pvParameters ) +{ +TickType_t xTimeWhenBlocking, xBlockedTime; +BaseType_t xData; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 1 and 2 + + This task does does not participate in these tests. */ + vTaskSuspend( NULL ); + + /********************************************************************* + Test 3 + + The first thing we do is attempt to read from the queue. It should be + full so we block. Note the time before we block so we can check the + wake time is as per that expected. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not sent + anything to the queue. */ + xData = 0; + xRunIndicator = bktRUN_INDICATOR; + if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we inside the send function? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as + soon as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Suspend ready for test 3. */ + xRunIndicator = bktRUN_INDICATOR; + vTaskSuspend( NULL ); + + /********************************************************************* + Test 4 + + As per test three, but with the send and receive reversed. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xRunIndicator = bktRUN_INDICATOR; + if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as soon + as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + xRunIndicator = bktRUN_INDICATOR; + + xSecondaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreBlockTimeTestTasksStillRunning( void ) +{ +static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; +BaseType_t xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xPrimaryCycles == xLastPrimaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xSecondaryCycles == xLastSecondaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastSecondaryCycleCount = xSecondaryCycles; + xLastPrimaryCycleCount = xPrimaryCycles; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest.c new file mode 100644 index 0000000..2a1542a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest.c @@ -0,0 +1,303 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * This version of comtest. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that operate on an interrupt driven serial port. A + * loopback connector should be used so that everything that is transmitted is + * also received. The serial port does not use any flow control. On a + * standard 9way 'D' connector pins two and three should be connected together. + * + * The first task posts a sequence of characters to the Tx queue, toggling an + * LED on each successful post. At the end of the sequence it sleeps for a + * pseudo-random period before resending the same sequence. + * + * The UART Tx end interrupt is enabled whenever data is available in the Tx + * queue. The Tx end ISR removes a single character from the Tx queue and + * passes it to the UART for transmission. + * + * The second task blocks on the Rx queue waiting for a character to become + * available. When the UART Rx end interrupt receives a character it places + * it in the Rx queue, waking the second task. The second task checks that the + * characters removed from the Rx queue form the same sequence as those posted + * to the Tx queue, and toggles an LED for each correct character. + * + * The receiving task is spawned with a higher priority than the transmitting + * task. The receiver will therefore wake every time a character is + * transmitted so neither the Tx or Rx queue should ever hold more than a few + * characters. + * + */ + +/* Scheduler include files. */ +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "partest.h" + +#define comSTACK_SIZE configMINIMAL_STACK_SIZE +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) +#define comTOTAL_PERMISSIBLE_ERRORS ( 2 ) + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 ) +#define comOFFSET_TIME ( ( TickType_t ) 3 ) + +/* We should find that each character can be queued for Tx immediately and we +don't have to block to send. */ +#define comNO_BLOCK ( ( TickType_t ) 0 ) + +/* The Rx task will block on the Rx queue for a long period. */ +#define comRX_BLOCK_TIME ( ( TickType_t ) 0xffff ) + +/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */ +#define comFIRST_BYTE ( 'A' ) +#define comLAST_BYTE ( 'X' ) + +#define comBUFFER_LEN ( ( UBaseType_t ) ( comLAST_BYTE - comFIRST_BYTE ) + ( UBaseType_t ) 1 ) +#define comINITIAL_RX_COUNT_VALUE ( 0 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The transmit task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters ); + +/* The receive task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters ); + +/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will +toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED +( uxBaseLED + comTX_LED_OFFSET ). */ +static UBaseType_t uxBaseLED = 0; + +/* Check variable used to ensure no error have occurred. The Rx task will +increment this variable after every successfully received sequence. If at any +time the sequence is incorrect the the variable will stop being incremented. */ +static volatile UBaseType_t uxRxLoops = comINITIAL_RX_COUNT_VALUE; + +/*-----------------------------------------------------------*/ + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ) +{ + /* Initialise the com port then spawn the Rx and Tx tasks. */ + uxBaseLED = uxLED; + xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN ); + + /* The Tx task is spawned with a lower priority than the Rx task. */ + xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( TaskHandle_t * ) NULL ); + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComTxTask, pvParameters ) +{ +char cByteToSend; +TickType_t xTimeToWait; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Simply transmit a sequence of characters from comFIRST_BYTE to + comLAST_BYTE. */ + for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ ) + { + if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS ) + { + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE ); + + /* We have posted all the characters in the string - wait before + re-sending. Wait a pseudo-random time as this will provide a better + test. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComRxTask, pvParameters ) +{ +signed char cExpectedByte, cByteRxed; +BaseType_t xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* We expect to receive the characters from comFIRST_BYTE to + comLAST_BYTE in an incrementing order. Loop to receive each byte. */ + for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ ) + { + /* Block on the queue that contains received bytes until a byte is + available. */ + if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) + { + /* Was this the byte we were expecting? If so, toggle the LED, + otherwise we are out on sync and should break out of the loop + until the expected character sequence is about to restart. */ + if( cByteRxed == cExpectedByte ) + { + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + else + { + xResyncRequired = pdTRUE; + break; /*lint !e960 Non-switch break allowed. */ + } + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); + + /* Did we break out of the loop because the characters were received in + an unexpected order? If so wait here until the character sequence is + about to restart. */ + if( xResyncRequired == pdTRUE ) + { + while( cByteRxed != comLAST_BYTE ) + { + /* Block until the next char is available. */ + xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ); + } + + /* Note that an error occurred which caused us to have to resync. + We use this to stop incrementing the loop counter so + sAreComTestTasksStillRunning() will return false - indicating an + error. */ + xErrorOccurred++; + + /* We have now resynced with the Tx task and can continue. */ + xResyncRequired = pdFALSE; + } + else + { + if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) + { + /* Increment the count of successful loops. As error + occurring (i.e. an unexpected character being received) will + prevent this counter being incremented for the rest of the + execution. Don't worry about mutual exclusion on this + variable - it doesn't really matter as we just want it + to change. */ + uxRxLoops++; + } + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +BaseType_t xAreComTestTasksStillRunning( void ) +{ +BaseType_t xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and we will return false. */ + if( uxRxLoops == comINITIAL_RX_COUNT_VALUE ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again we expect this to have been incremented. */ + uxRxLoops = comINITIAL_RX_COUNT_VALUE; + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest_strings.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest_strings.c new file mode 100644 index 0000000..0e84b12 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/comtest_strings.c @@ -0,0 +1,349 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Creates a task and a timer that operate on an interrupt driven serial port. + * This demo assumes that the characters transmitted on a port will also be + * received on the same port. Therefore, the UART must either be connected to + * an echo server, or the uart connector must have a loopback connector fitted. + * See http://www.serialporttool.com/CommEcho.htm for a suitable echo server + * for Windows hosts. + * + * The timer sends a string to the UART, toggles an LED, then resets itself by + * changing its own period. The period is calculated as a pseudo random number + * between comTX_MAX_BLOCK_TIME and comTX_MIN_BLOCK_TIME. + * + * The task blocks on an Rx queue waiting for a character to become available. + * Received characters are checked to ensure they match those transmitted by the + * Tx timer. An error is latched if characters are missing, incorrect, or + * arrive too slowly. + * + * How characters are actually transmitted and received is port specific. Demos + * that include this test/demo file will provide example drivers. The Tx timer + * executes in the context of the timer service (daemon) task, and must + * therefore never attempt to block. + * + */ + +/* Scheduler include files. */ +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +#ifndef configUSE_TIMERS + #error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h. +#endif + +#if configUSE_TIMERS != 1 + #error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h. +#endif + + +/* Demo program include files. */ +#include "serial.h" +#include "comtest_strings.h" +#include "partest.h" + +/* The size of the stack given to the Rx task. */ +#define comSTACK_SIZE configMINIMAL_STACK_SIZE + +/* See the comment above the declaraction of the uxBaseLED variable. */ +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) + +/* The Tx timer transmits the sequence of characters at a pseudo random +interval that is capped between comTX_MAX_BLOCK_TIME and +comTX_MIN_BLOCK_TIME. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 ) +#define comOFFSET_TIME ( ( TickType_t ) 3 ) + +/* States for the simple state machine implemented in the Rx task. */ +#define comtstWAITING_START_OF_STRING 0 +#define comtstWAITING_END_OF_STRING 1 + +/* A short delay in ticks - this delay is used to allow the Rx queue to fill up +a bit so more than one character can be processed at a time. This is relative +to comTX_MIN_BLOCK_TIME to ensure it is never longer than the shortest gap +between transmissions. It could be worked out more scientifically from the +baud rate being used. */ +#define comSHORT_DELAY ( comTX_MIN_BLOCK_TIME >> ( TickType_t ) 2 ) + +/* The string that is transmitted and received. */ +#define comTRANSACTED_STRING "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + +/* A block time of 0 simply means "don't block". */ +#define comtstDONT_BLOCK ( TickType_t ) 0 + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The callback function allocated to the transmit timer, as described in the +comments at the top of this file. */ +static void prvComTxTimerCallback( TimerHandle_t xTimer ); + +/* The receive task as described in the comments at the top of this file. */ +static void vComRxTask( void *pvParameters ); + +/* The Rx task will toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task +will toggle LED ( uxBaseLED + comTX_LED_OFFSET ). */ +static UBaseType_t uxBaseLED = 0; + +/* The Rx task toggles uxRxLoops on each successful iteration of its defined +function - provided no errors have ever been latched. If this variable stops +incrementing, then an error has occurred. */ +static volatile UBaseType_t uxRxLoops = 0UL; + +/* The timer used to periodically transmit the string. This is the timer that +has prvComTxTimerCallback allocated to it as its callback function. */ +static TimerHandle_t xTxTimer = NULL; + +/* The string length is held at file scope so the Tx timer does not need to +calculate it each time it executes. */ +static size_t xStringLength = 0U; + +/*-----------------------------------------------------------*/ + +void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ) +{ + /* Store values that are used at run time. */ + uxBaseLED = uxLED; + + /* Calculate the string length here, rather than each time the Tx timer + executes. */ + xStringLength = strlen( comTRANSACTED_STRING ); + + /* Include the null terminator in the string length as this is used to + detect the end of the string in the Rx task. */ + xStringLength++; + + /* Initialise the com port, then spawn the Rx task and create the Tx + timer. */ + xSerialPortInitMinimal( ulBaudRate, ( xStringLength * 2U ) ); + + /* Create the Rx task and the Tx timer. The timer is started from the + Rx task. */ + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); + xTxTimer = xTimerCreate( "TxTimer", comTX_MIN_BLOCK_TIME, pdFALSE, NULL, prvComTxTimerCallback ); + configASSERT( xTxTimer ); +} +/*-----------------------------------------------------------*/ + +static void prvComTxTimerCallback( TimerHandle_t xTimer ) +{ +TickType_t xTimeToWait; + + /* The parameter is not used in this case. */ + ( void ) xTimer; + + /* Send the string. How this is actually performed depends on the + sample driver provided with this demo. However - as this is a timer, + it executes in the context of the timer task and therefore must not + block. */ + vSerialPutString( xPort, comTRANSACTED_STRING, xStringLength ); + + /* Toggle an LED to give a visible indication that another transmission + has been performed. */ + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + + /* Wait a pseudo random time before sending the string again. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Ensure the time to wait is not greater than comTX_MAX_BLOCK_TIME. */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* Ensure the time to wait is not less than comTX_MIN_BLOCK_TIME. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + /* Reset the timer to run again xTimeToWait ticks from now. This function + is called from the context of the timer task, so the block time must not + be anything other than zero. */ + xTimerChangePeriod( xTxTimer, xTimeToWait, comtstDONT_BLOCK ); +} +/*-----------------------------------------------------------*/ + +static void vComRxTask( void *pvParameters ) +{ +BaseType_t xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE; +char *pcExpectedByte, cRxedChar; +const xComPortHandle xPort = NULL; + + /* The parameter is not used in this example. */ + ( void ) pvParameters; + + /* Start the Tx timer. This only needs to be started once, as it will + reset itself thereafter. */ + xTimerStart( xTxTimer, portMAX_DELAY ); + + /* The first expected Rx character is the first in the string that is + transmitted. */ + pcExpectedByte = comTRANSACTED_STRING; + + for( ;; ) + { + /* Wait for the next character. */ + if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE ) + { + /* A character definitely should have been received by now. As a + character was not received an error must have occurred (which might + just be that the loopback connector is not fitted). */ + xErrorOccurred = pdTRUE; + } + + switch( xState ) + { + case comtstWAITING_START_OF_STRING: + if( cRxedChar == *pcExpectedByte ) + { + /* The received character was the first character of the + string. Move to the next state to check each character + as it comes in until the entire string has been received. */ + xState = comtstWAITING_END_OF_STRING; + pcExpectedByte++; + + /* Block for a short period. This just allows the Rx queue + to contain more than one character, and therefore prevent + thrashing reads to the queue, and repetitive context + switches as each character is received. */ + vTaskDelay( comSHORT_DELAY ); + } + break; + + case comtstWAITING_END_OF_STRING: + if( cRxedChar == *pcExpectedByte ) + { + /* The received character was the expected character. Was + it the last character in the string - i.e. the null + terminator? */ + if( cRxedChar == 0x00 ) + { + /* The entire string has been received. If no errors + have been latched, then increment the loop counter to + show this task is still healthy. */ + if( xErrorOccurred == pdFALSE ) + { + uxRxLoops++; + + /* Toggle an LED to give a visible sign that a + complete string has been received. */ + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + + /* Go back to wait for the start of the next string. */ + pcExpectedByte = comTRANSACTED_STRING; + xState = comtstWAITING_START_OF_STRING; + } + else + { + /* Wait for the next character in the string. */ + pcExpectedByte++; + } + } + else + { + /* The character received was not that expected. */ + xErrorOccurred = pdTRUE; + } + break; + + default: + /* Should not get here. Stop the Rx loop counter from + incrementing to latch the error. */ + xErrorOccurred = pdTRUE; + break; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreComTestTasksStillRunning( void ) +{ +BaseType_t xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and false is returned. */ + if( uxRxLoops == 0UL ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again it should have been incremented again. */ + uxRxLoops = 0UL; + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/countsem.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/countsem.c new file mode 100644 index 0000000..aa33933 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/countsem.c @@ -0,0 +1,322 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Simple demonstration of the usage of counting semaphore. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "countsem.h" + +/* The maximum count value that the semaphore used for the demo can hold. */ +#define countMAX_COUNT_VALUE ( 200 ) + +/* Constants used to indicate whether or not the semaphore should have been +created with its maximum count value, or its minimum count value. These +numbers are used to ensure that the pointers passed in as the task parameters +are valid. */ +#define countSTART_AT_MAX_COUNT ( 0xaa ) +#define countSTART_AT_ZERO ( 0x55 ) + +/* Two tasks are created for the test. One uses a semaphore created with its +count value set to the maximum, and one with the count value set to zero. */ +#define countNUM_TEST_TASKS ( 2 ) +#define countDONT_BLOCK ( 0 ) + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +/* + * The demo task. This simply counts the semaphore up to its maximum value, + * the counts it back down again. The result of each semaphore 'give' and + * 'take' is inspected, with an error being flagged if it is found not to be + * the expected result. + */ +static void prvCountingSemaphoreTask( void *pvParameters ); + +/* + * Utility function to increment the semaphore count value up from zero to + * countMAX_COUNT_VALUE. + */ +static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ); + +/* + * Utility function to decrement the semaphore count value up from + * countMAX_COUNT_VALUE to zero. + */ +static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ); + +/*-----------------------------------------------------------*/ + +/* The structure that is passed into the task as the task parameter. */ +typedef struct COUNT_SEM_STRUCT +{ + /* The semaphore to be used for the demo. */ + SemaphoreHandle_t xSemaphore; + + /* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with + its count value set to its max count value, or countSTART_AT_ZERO if it + should have been created with its count value set to 0. */ + UBaseType_t uxExpectedStartCount; + + /* Incremented on each cycle of the demo task. Used to detect a stalled + task. */ + UBaseType_t uxLoopCounter; +} xCountSemStruct; + +/* Two structures are defined, one is passed to each test task. */ +static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ]; + +/*-----------------------------------------------------------*/ + +void vStartCountingSemaphoreTasks( void ) +{ + /* Create the semaphores that we are going to use for the test/demo. The + first should be created such that it starts at its maximum count value, + the second should be created such that it starts with a count value of zero. */ + xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE ); + xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT; + xParameters[ 0 ].uxLoopCounter = 0; + + xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 ); + xParameters[ 1 ].uxExpectedStartCount = 0; + xParameters[ 1 ].uxLoopCounter = 0; + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" ); + vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" ); + + + /* Were the semaphores created? */ + if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) ) + { + /* Create the demo tasks, passing in the semaphore to use as the parameter. */ + xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ) +{ +UBaseType_t ux; + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ) +{ +UBaseType_t ux; + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + if( xSemaphoreGive( xSemaphore ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvCountingSemaphoreTask( void *pvParameters ) +{ +xCountSemStruct *pxParameter; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Counting semaphore demo started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + /* The semaphore to be used was passed as the parameter. */ + pxParameter = ( xCountSemStruct * ) pvParameters; + + /* Did we expect to find the semaphore already at its max count value, or + at zero? */ + if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT ) + { + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } + + /* Now we expect the semaphore count to be 0, so this time there is an + error if we can take the semaphore. */ + if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + for( ;; ) + { + prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreCountingSemaphoreTasksStillRunning( void ) +{ +static UBaseType_t uxLastCount0 = 0, uxLastCount1 = 0; +BaseType_t xReturn = pdPASS; + + /* Return fail if any 'give' or 'take' did not result in the expected + behaviour. */ + if( xErrorDetected != pdFALSE ) + { + xReturn = pdFAIL; + } + + /* Return fail if either task is not still incrementing its loop counter. */ + if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount0 = xParameters[ 0 ].uxLoopCounter; + } + + if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount1 = xParameters[ 1 ].uxLoopCounter; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crflash.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crflash.c new file mode 100644 index 0000000..4507f1c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crflash.c @@ -0,0 +1,246 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This demo application file demonstrates the use of queues to pass data + * between co-routines. + * + * N represents the number of 'fixed delay' co-routines that are created and + * is set during initialisation. + * + * N 'fixed delay' co-routines are created that just block for a fixed + * period then post the number of an LED onto a queue. Each such co-routine + * uses a different block period. A single 'flash' co-routine is also created + * that blocks on the same queue, waiting for the number of the next LED it + * should flash. Upon receiving a number it simply toggle the instructed LED + * then blocks on the queue once more. In this manner each LED from LED 0 to + * LED N-1 is caused to flash at a different rate. + * + * The 'fixed delay' co-routines are created with co-routine priority 0. The + * flash co-routine is created with co-routine priority 1. This means that + * the queue should never contain more than a single item. This is because + * posting to the queue will unblock the 'flash' co-routine, and as this has + * a priority greater than the tasks posting to the queue it is guaranteed to + * have emptied the queue and blocked once again before the queue can contain + * any more date. An error is indicated if an attempt to post data to the + * queue fails - indicating that the queue is already full. + * + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "partest.h" +#include "crflash.h" + +/* The queue should only need to be of length 1. See the description at the +top of the file. */ +#define crfQUEUE_LENGTH 1 + +#define crfFIXED_DELAY_PRIORITY 0 +#define crfFLASH_PRIORITY 1 + +/* Only one flash co-routine is created so the index is not significant. */ +#define crfFLASH_INDEX 0 + +/* Don't allow more than crfMAX_FLASH_TASKS 'fixed delay' co-routines to be +created. */ +#define crfMAX_FLASH_TASKS 8 + +/* We don't want to block when posting to the queue. */ +#define crfPOSTING_BLOCK_TIME 0 + +/* + * The 'fixed delay' co-routine as described at the top of the file. + */ +static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + +/* + * The 'flash' co-routine as described at the top of the file. + */ +static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + +/* The queue used to pass data between the 'fixed delay' co-routines and the +'flash' co-routine. */ +static QueueHandle_t xFlashQueue; + +/* This will be set to pdFALSE if we detect an error. */ +static BaseType_t xCoRoutineFlashStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* + * See the header file for details. + */ +void vStartFlashCoRoutines( UBaseType_t uxNumberToCreate ) +{ +UBaseType_t uxIndex; + + if( uxNumberToCreate > crfMAX_FLASH_TASKS ) + { + uxNumberToCreate = crfMAX_FLASH_TASKS; + } + + /* Create the queue used to pass data between the co-routines. */ + xFlashQueue = xQueueCreate( crfQUEUE_LENGTH, sizeof( UBaseType_t ) ); + + if( xFlashQueue ) + { + /* Create uxNumberToCreate 'fixed delay' co-routines. */ + for( uxIndex = 0; uxIndex < uxNumberToCreate; uxIndex++ ) + { + xCoRoutineCreate( prvFixedDelayCoRoutine, crfFIXED_DELAY_PRIORITY, uxIndex ); + } + + /* Create the 'flash' co-routine. */ + xCoRoutineCreate( prvFlashCoRoutine, crfFLASH_PRIORITY, crfFLASH_INDEX ); + } +} +/*-----------------------------------------------------------*/ + +static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +/* Even though this is a co-routine the xResult variable does not need to be +static as we do not need it to maintain its state between blocks. */ +BaseType_t xResult; +/* The uxIndex parameter of the co-routine function is used as an index into +the xFlashRates array to obtain the delay period to use. */ +static const TickType_t xFlashRates[ crfMAX_FLASH_TASKS ] = { 150 / portTICK_PERIOD_MS, + 200 / portTICK_PERIOD_MS, + 250 / portTICK_PERIOD_MS, + 300 / portTICK_PERIOD_MS, + 350 / portTICK_PERIOD_MS, + 400 / portTICK_PERIOD_MS, + 450 / portTICK_PERIOD_MS, + 500 / portTICK_PERIOD_MS }; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + + for( ;; ) + { + /* Post our uxIndex value onto the queue. This is used as the LED to + flash. */ + crQUEUE_SEND( xHandle, xFlashQueue, ( void * ) &uxIndex, crfPOSTING_BLOCK_TIME, &xResult ); + + if( xResult != pdPASS ) + { + /* For the reasons stated at the top of the file we should always + find that we can post to the queue. If we could not then an error + has occurred. */ + xCoRoutineFlashStatus = pdFAIL; + } + + crDELAY( xHandle, xFlashRates[ uxIndex ] ); + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +/* Even though this is a co-routine the variable do not need to be +static as we do not need it to maintain their state between blocks. */ +BaseType_t xResult; +UBaseType_t uxLEDToFlash; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + ( void ) uxIndex; + + for( ;; ) + { + /* Block to wait for the number of the LED to flash. */ + crQUEUE_RECEIVE( xHandle, xFlashQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + + if( xResult != pdPASS ) + { + /* We would not expect to wake unless we received something. */ + xCoRoutineFlashStatus = pdFAIL; + } + else + { + /* We received the number of an LED to flash - flash it! */ + vParTestToggleLED( uxLEDToFlash ); + } + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreFlashCoRoutinesStillRunning( void ) +{ + /* Return pdPASS or pdFAIL depending on whether an error has been detected + or not. */ + return xCoRoutineFlashStatus; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crhook.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crhook.c new file mode 100644 index 0000000..1e3a18e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/crhook.c @@ -0,0 +1,270 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This demo file demonstrates how to send data between an ISR and a + * co-routine. A tick hook function is used to periodically pass data between + * the RTOS tick and a set of 'hook' co-routines. + * + * hookNUM_HOOK_CO_ROUTINES co-routines are created. Each co-routine blocks + * to wait for a character to be received on a queue from the tick ISR, checks + * to ensure the character received was that expected, then sends the number + * back to the tick ISR on a different queue. + * + * The tick ISR checks the numbers received back from the 'hook' co-routines + * matches the number previously sent. + * + * If at any time a queue function returns unexpectedly, or an incorrect value + * is received either by the tick hook or a co-routine then an error is + * latched. + * + * This demo relies on each 'hook' co-routine to execute between each + * hookTICK_CALLS_BEFORE_POST tick interrupts. This and the heavy use of + * queues from within an interrupt may result in an error being detected on + * slower targets simply due to timing. + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "crhook.h" + +/* The number of 'hook' co-routines that are to be created. */ +#define hookNUM_HOOK_CO_ROUTINES ( 4 ) + +/* The number of times the tick hook should be called before a character is +posted to the 'hook' co-routines. */ +#define hookTICK_CALLS_BEFORE_POST ( 500 ) + +/* There should never be more than one item in any queue at any time. */ +#define hookHOOK_QUEUE_LENGTH ( 1 ) + +/* Don't block when initially posting to the queue. */ +#define hookNO_BLOCK_TIME ( 0 ) + +/* The priority relative to other co-routines (rather than tasks) that the +'hook' co-routines should take. */ +#define mainHOOK_CR_PRIORITY ( 1 ) +/*-----------------------------------------------------------*/ + +/* + * The co-routine function itself. + */ +static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + + +/* + * The tick hook function. This receives a number from each 'hook' co-routine + * then sends a number to each co-routine. An error is flagged if a send or + * receive fails, or an unexpected number is received. + */ +void vApplicationTickHook( void ); + +/*-----------------------------------------------------------*/ + +/* Queues used to send data FROM a co-routine TO the tick hook function. +The hook functions received (Rx's) on these queues. One queue per +'hook' co-routine. */ +static QueueHandle_t xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Queues used to send data FROM the tick hook TO a co-routine function. +The hood function transmits (Tx's) on these queues. One queue per +'hook' co-routine. */ +static QueueHandle_t xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Set to true if an error is detected at any time. */ +static BaseType_t xCoRoutineErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartHookCoRoutines( void ) +{ +UBaseType_t uxIndex, uxValueToPost = 0; + + for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ ) + { + /* Create a queue to transmit to and receive from each 'hook' + co-routine. */ + xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) ); + xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) ); + + /* To start things off the tick hook function expects the queue it + uses to receive data to contain a value. */ + xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME ); + + /* Create the 'hook' co-routine itself. */ + xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex ); + } +} +/*-----------------------------------------------------------*/ + +static UBaseType_t uxCallCounter = 0, uxNumberToPost = 0; +void vApplicationTickHook( void ) +{ +UBaseType_t uxReceivedNumber; +BaseType_t xIndex, xCoRoutineWoken; + + /* Is it time to talk to the 'hook' co-routines again? */ + uxCallCounter++; + if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST ) + { + uxCallCounter = 0; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + xCoRoutineWoken = pdFALSE; + if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS ) + { + /* There is no reason why we would not expect the queue to + contain a value. */ + xCoRoutineErrorDetected = pdTRUE; + } + else + { + /* Each queue used to receive data from the 'hook' co-routines + should contain the number we last posted to the same co-routine. */ + if( uxReceivedNumber != uxNumberToPost ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Nothing should be blocked waiting to post to the queue. */ + if( xCoRoutineWoken != pdFALSE ) + { + xCoRoutineErrorDetected = pdTRUE; + } + } + } + + /* Start the next cycle by posting the next number onto each Tx queue. */ + uxNumberToPost++; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE ) + { + /* Posting to the queue should have woken the co-routine that + was blocked on the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +static UBaseType_t uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ]; +BaseType_t xResult; + + /* Each co-routine MUST start with a call to crSTART(); */ + crSTART( xHandle ); + + for( ;; ) + { + /* Wait to receive a value from the tick hook. */ + xResult = pdFAIL; + crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult ); + + /* There is no reason why we should not have received something on + the queue. */ + if( xResult != pdPASS ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Send the same number back to the idle hook so it can verify it. */ + xResult = pdFAIL; + crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult ); + if( xResult != pdPASS ) + { + /* There is no reason why we should not have been able to post to + the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + + /* Each co-routine MUST end with a call to crEND(). */ + crEND(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreHookCoRoutinesStillRunning( void ) +{ + if( xCoRoutineErrorDetected ) + { + return pdFALSE; + } + else + { + return pdTRUE; + } +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/death.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/death.c new file mode 100644 index 0000000..d567971 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/death.c @@ -0,0 +1,254 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * two tasks. The original task is called the creator task, the two tasks it + * creates are called suicidal tasks. + * + * One of the created suicidal tasks kill one other suicidal task before killing + * itself - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" + +#define deathSTACK_SIZE ( configMINIMAL_STACK_SIZE + 60 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static portTASK_FUNCTION_PROTO( vCreateTasks, pvParameters ); + +/* The task function of the dynamically created tasks. */ +static portTASK_FUNCTION_PROTO( vSuicidalTask, pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile uint16_t usCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. +*/ +static volatile UBaseType_t uxTasksRunningAtStart = 0; + +/* Tasks are deleted by the idle task. Under heavy load the idle task might +not get much processing time, so it would be legitimate for several tasks to +remain undeleted for a short period. */ +static const UBaseType_t uxMaxNumberOfExtraTasksRunning = 3; + +/* Used to store a handle to the task that should be killed by a suicidal task, +before it kills itself. */ +TaskHandle_t xCreatedTask; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( UBaseType_t uxPriority ) +{ +UBaseType_t *puxPriority; + + /* Create the Creator tasks - passing in as a parameter the priority at which + the suicidal tasks should be created. */ + puxPriority = ( UBaseType_t * ) pvPortMalloc( sizeof( UBaseType_t ) ); + *puxPriority = uxPriority; + + xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = ( UBaseType_t ) uxTaskGetNumberOfTasks(); + + /* FreeRTOS.org versions before V3.0 started the idle-task as the very + first task. The idle task was then already included in uxTasksRunningAtStart. + From FreeRTOS V3.0 on, the idle task is started when the scheduler is + started. Therefore the idle task is not yet accounted for. We correct + this by increasing uxTasksRunningAtStart by 1. */ + uxTasksRunningAtStart++; + + /* From FreeRTOS version 7.0.0 can optionally create a timer service task. + If this is done, then uxTasksRunningAtStart needs incrementing again as that + too is created when the scheduler is started. */ + #if configUSE_TIMERS == 1 + uxTasksRunningAtStart++; + #endif +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vSuicidalTask, pvParameters ) +{ +volatile long l1, l2; +TaskHandle_t xTaskToKill; +const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS; + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Two created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( TaskHandle_t* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + l1 = 2; + l2 = 89; + l2 *= l1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( TickType_t ) 0 ); + + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCreateTasks, pvParameters ) +{ +const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +UBaseType_t uxPriority; + + uxPriority = *( UBaseType_t * ) pvParameters; + vPortFree( pvParameters ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xCreatedTask = NULL; + + xTaskCreate( vSuicidalTask, "SUICID1", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xCreatedTask ); + xTaskCreate( vSuicidalTask, "SUICID2", configMINIMAL_STACK_SIZE, &xCreatedTask, uxPriority, NULL ); + + ++usCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +BaseType_t xIsCreateTaskStillRunning( void ) +{ +static uint16_t usLastCreationCount = 0xfff; +BaseType_t xReturn = pdTRUE; +static UBaseType_t uxTasksRunningNow; + + if( usLastCreationCount == usCreationCount ) + { + xReturn = pdFALSE; + } + else + { + usLastCreationCount = usCreationCount; + } + + uxTasksRunningNow = ( UBaseType_t ) uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + xReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + xReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/dynamic.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/dynamic.c new file mode 100644 index 0000000..29ef3ef --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/dynamic.c @@ -0,0 +1,511 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises its priority above that of the controller task before each + * increment, lowering it again to its original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of its loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume(). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from its suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" + +/* Function that implements the "limited count" task as described above. */ +static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters ); + +/* Function that implements the controller task as described above. */ +static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters ); + +static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters ); +static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters ); + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME ( ( TickType_t ) 128 / portTICK_PERIOD_MS ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( uint32_t ) 0xff ) +#define priNO_BLOCK ( ( TickType_t ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static volatile uint32_t ulCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static volatile uint16_t usCheckVariable = ( uint16_t ) 0; +static volatile BaseType_t xSuspendedQueueSendError = pdFALSE; +static volatile BaseType_t xSuspendedQueueReceiveError = pdFALSE; + +/* Queue used by the second test. */ +QueueHandle_t xSuspendedTestQueue; + +/* The value the queue receive task expects to receive next. This is file +scope so xAreDynamicPriorityTasksStillRunning() can ensure it is still +incrementing. */ +static uint32_t ulExpectedValue = ( uint32_t ) 0; + +/*-----------------------------------------------------------*/ +/* + * Start the three tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( uint32_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xSuspendedTestQueue, "Suspended_Test_Queue" ); + + xTaskCreate( vContinuousIncrementTask, "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters ) +{ +uint32_t *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( uint32_t * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters ) +{ +volatile uint32_t *pulCounter; +UBaseType_t uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( uint32_t * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise the priority above the controller task to ensure a context + switch does not occur while the variable is being accessed. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + { + configASSERT( ( uxTaskPriorityGet( NULL ) == ( uxOurPriority + 1 ) ) ); + ( *pulCounter )++; + } + vTaskPrioritySet( NULL, uxOurPriority ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + configASSERT( ( uxTaskPriorityGet( NULL ) == uxOurPriority ) ); + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static portTASK_FUNCTION( vCounterControlTask, pvParameters ) +{ +uint32_t ulLastCounter; +short sLoops; +short sError = pdFALSE; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( uint32_t ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. This is not really + needed as the other task raises its priority above this task's + priority. */ + vTaskSuspend( xContinuousIncrementHandle ); + { + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + ulLastCounter = ulCounter; + } + vTaskResume( xContinuousIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + } + } + xTaskResumeAll(); + } + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared + variable. */ + vTaskSuspend( xContinuousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( uint32_t ) 0; + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. */ + vTaskResume( xLimitedIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + /* This task should not run again until xLimitedIncrementHandle has + suspended itself. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinuousIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters ) +{ +static uint32_t ulValueToSend = ( uint32_t ) 0; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters ) +{ +uint32_t ulReceivedValue; +BaseType_t xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() != pdFALSE ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + + if( xSuspendedQueueReceiveError != pdTRUE ) + { + /* Only increment the variable if an error has not occurred. This + allows xAreDynamicPriorityTasksStillRunning() to check for stalled + tasks as well as explicit errors. */ + ++ulExpectedValue; + } + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +BaseType_t xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static uint16_t usLastTaskCheck = ( uint16_t ) 0; +static uint32_t ulLastExpectedValue = ( uint32_t ) 0U; +BaseType_t xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( ulExpectedValue == ulLastExpectedValue ) + { + /* The value being received by the queue receive task has not + incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + ulLastExpectedValue = ulExpectedValue; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash.c new file mode 100644 index 0000000..8689707 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash.c @@ -0,0 +1,157 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * This version of flash .c is for use on systems that have limited stack space + * and no display facilities. The complete version can be found in the + * Demo/Common/Full directory. + * + * Three tasks are created, each of which flash an LED at a different rate. The first + * LED flashes every 200ms, the second every 400ms, the third every 600ms. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE +#define ledNUMBER_OF_LEDS ( 3 ) +#define ledFLASH_RATE_BASE ( ( TickType_t ) 333 ) + +/* Variable used by the created tasks to calculate the LED number to use, and +the rate at which they should flash the LED. */ +static volatile UBaseType_t uxFlashTaskNumber = 0; + +/* The task that is created three times. */ +static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( UBaseType_t uxPriority ) +{ +BaseType_t xLEDTask; + + /* Create the three tasks. */ + for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask ) + { + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vLEDFlashTask, pvParameters ) +{ +TickType_t xFlashRate, xLastFlashTime; +UBaseType_t uxLED; + + /* The parameters are not used. */ + ( void ) pvParameters; + + /* Calculate the LED and flash rate. */ + portENTER_CRITICAL(); + { + /* See which of the eight LED's we should use. */ + uxLED = uxFlashTaskNumber; + + /* Update so the next task uses the next LED. */ + uxFlashTaskNumber++; + } + portEXIT_CRITICAL(); + + xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( TickType_t ) uxLED ); + xFlashRate /= portTICK_PERIOD_MS; + + /* We will turn the LED on and off again in the delay period, so each + delay is only half the total period. */ + xFlashRate /= ( TickType_t ) 2; + + /* We need to initialise xLastFlashTime prior to the first call to + vTaskDelayUntil(). */ + xLastFlashTime = xTaskGetTickCount(); + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + } +} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash_timer.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash_timer.c new file mode 100644 index 0000000..b54a866 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flash_timer.c @@ -0,0 +1,136 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Repeatedly toggles one or more LEDs using software timers - one timer per + * LED. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "timers.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash_timer.h" + +/* The toggle rates are all a multple of ledFLASH_RATE_BASE. */ +#define ledFLASH_RATE_BASE ( ( ( TickType_t ) 333 ) / portTICK_PERIOD_MS ) + +/* A block time of zero simple means "don't block". */ +#define ledDONT_BLOCK ( ( TickType_t ) 0 ) + +/*-----------------------------------------------------------*/ + +/* + * The callback function used by each LED flashing timer. All the timers use + * this function, and the timer ID is used within the function to determine + * which timer has actually expired. + */ +static void prvLEDTimerCallback( TimerHandle_t xTimer ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs ) +{ +UBaseType_t uxLEDTimer; +TimerHandle_t xTimer; + + /* Create and start the requested number of timers. */ + for( uxLEDTimer = 0; uxLEDTimer < uxNumberOfLEDs; ++uxLEDTimer ) + { + /* Create the timer. */ + xTimer = xTimerCreate( "Flasher", /* A text name, purely to help debugging. */ + ledFLASH_RATE_BASE * ( uxLEDTimer + 1 ),/* The timer period, which is a multiple of ledFLASH_RATE_BASE. */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) uxLEDTimer, /* The ID is used to identify the timer within the timer callback function, as each timer uses the same callback. */ + prvLEDTimerCallback /* Each timer uses the same callback. */ + ); + + /* If the timer was created successfully, attempt to start it. If the + scheduler has not yet been started then the timer command queue must + be long enough to hold each command sent to it until such time that the + scheduler is started. The timer command queue length is set by + configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h. */ + if( xTimer != NULL ) + { + xTimerStart( xTimer, ledDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLEDTimerCallback( TimerHandle_t xTimer ) +{ +BaseType_t xTimerID; + + /* The timer ID is used to identify the timer that has actually expired as + each timer uses the same callback. The ID is then also used as the number + of the LED that is to be toggled. */ + xTimerID = ( BaseType_t ) pvTimerGetTimerID( xTimer ); + vParTestToggleLED( xTimerID ); +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flop.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flop.c new file mode 100644 index 0000000..438cf02 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/flop.c @@ -0,0 +1,383 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates eight tasks, each of which loops continuously performing a floating + * point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle + * priority means that these tasks will get pre-empted any time another task is + * ready to run or a time slice occurs. More often than not the pre-emption + * will occur mid calculation, creating a good test of the schedulers context + * switch mechanism - a calculation producing an unexpected result could be a + * symptom of a corruption in the context of a task. + */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE configMINIMAL_STACK_SIZE +#define mathNUMBER_OF_TASKS ( 4 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will stop setting its check variable. */ +static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile uint16_t *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + dAnswer = ( d1 + d2 ) * d3; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile uint16_t *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + dAnswer = ( d1 / d2 ) * d3; + + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5; + dTotal1 += ( portDOUBLE ) xPosition + 5.5; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123; + dTotal1 += ( portDOUBLE ) xPosition * 12.123; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreMathsTaskStillRunning( void ) +{ +BaseType_t xReturn = pdPASS, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + have been set to pdPASS. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] != pdTRUE ) + { + /* The check has not been set so the associated task has either + stalled or detected an error. */ + xReturn = pdFAIL; + } + else + { + /* Reset the variable so it can be checked again the next time this + function is executed. */ + usTaskCheck[ xTask ] = pdFALSE; + } + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/integer.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/integer.c new file mode 100644 index 0000000..a276613 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/integer.c @@ -0,0 +1,201 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates one or more tasks that repeatedly perform a set of integer + * calculations. The result of each run-time calculation is compared to the + * known expected result - with a mismatch being indicative of an error in the + * context switch mechanism. + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "integer.h" + +/* The constants used in the calculation. */ +#define intgCONST1 ( ( long ) 123 ) +#define intgCONST2 ( ( long ) 234567 ) +#define intgCONST3 ( ( long ) -3 ) +#define intgCONST4 ( ( long ) 7 ) +#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 ) + +#define intgSTACK_SIZE configMINIMAL_STACK_SIZE + +/* As this is the minimal version, we will only create one task. */ +#define intgNUMBER_OF_TASKS ( 1 ) + +/* The task function. Repeatedly performs a 32 bit calculation, checking the +result against the expected result. If the result is incorrect then the +context switch must have caused some corruption. */ +static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters ); + +/* Variables that are set to true within the calculation task to indicate +that the task is still executing. The check task sets the variable back to +false, flagging an error if the variable is still false the next time it +is called. */ +static volatile BaseType_t xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( BaseType_t ) pdFALSE }; + +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( UBaseType_t uxPriority ) +{ +short sTask; + + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + xTaskCreate( vCompeteingIntMathTask, "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters ) +{ +/* These variables are all effectively set to constants so they are volatile to +ensure the compiler does not just get rid of them. */ +volatile long lValue; +short sError = pdFALSE; +volatile BaseType_t *pxTaskHasExecuted; + + /* Set a pointer to the variable we are going to set to true each + iteration. This is also a good test of the parameter passing mechanism + within each port. */ + pxTaskHasExecuted = ( volatile BaseType_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + /* Perform the calculation. This will store partial value in + registers, resulting in a good test of the context switch mechanism. */ + lValue = intgCONST1; + lValue += intgCONST2; + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + /* Finish off the calculation. */ + lValue *= intgCONST3; + lValue /= intgCONST4; + + /* If the calculation is found to be incorrect we stop setting the + TaskHasExecuted variable so the check task can see an error has + occurred. */ + if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */ + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* We have not encountered any errors, so set the flag that show + we are still executing. This will be periodically cleared by + the check task. */ + portENTER_CRITICAL(); + *pxTaskHasExecuted = pdTRUE; + portEXIT_CRITICAL(); + } + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreIntegerMathsTaskStillRunning( void ) +{ +BaseType_t xReturn = pdTRUE; +short sTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still being set to true. */ + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + if( xTaskCheck[ sTask ] == pdFALSE ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + /* Reset the check variable so we can tell if it has been set by + the next time around. */ + xTaskCheck[ sTask ] = pdFALSE; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/recmutex.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/recmutex.c new file mode 100644 index 0000000..69a6f9d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/recmutex.c @@ -0,0 +1,440 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + The tasks defined on this page demonstrate the use of recursive mutexes. + + For recursive mutex functionality the created mutex should be created using + xSemaphoreCreateRecursiveMutex(), then be manipulated + using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API + functions. + + This demo creates three tasks all of which access the same recursive mutex: + + prvRecursiveMutexControllingTask() has the highest priority so executes + first and grabs the mutex. It then performs some recursive accesses - + between each of which it sleeps for a short period to let the lower + priority tasks execute. When it has completed its demo functionality + it gives the mutex back before suspending itself. + + prvRecursiveMutexBlockingTask() attempts to access the mutex by performing + a blocking 'take'. The blocking task has a lower priority than the + controlling task so by the time it executes the mutex has already been + taken by the controlling task, causing the blocking task to block. It + does not unblock until the controlling task has given the mutex back, + and it does not actually run until the controlling task has suspended + itself (due to the relative priorities). When it eventually does obtain + the mutex all it does is give the mutex back prior to also suspending + itself. At this point both the controlling task and the blocking task are + suspended. + + prvRecursiveMutexPollingTask() runs at the idle priority. It spins round + a tight loop attempting to obtain the mutex with a non-blocking call. As + the lowest priority task it will not successfully obtain the mutex until + both the controlling and blocking tasks are suspended. Once it eventually + does obtain the mutex it first unsuspends both the controlling task and + blocking task prior to giving the mutex back - resulting in the polling + task temporarily inheriting the controlling tasks priority. +*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "recmutex.h" + +/* Priorities assigned to the three tasks. recmuCONTROLLING_TASK_PRIORITY can +be overridden by a definition in FreeRTOSConfig.h. */ +#ifndef recmuCONTROLLING_TASK_PRIORITY + #define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#endif +#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/* The recursive call depth. */ +#define recmuMAX_COUNT ( 10 ) + +/* Misc. */ +#define recmuSHORT_DELAY ( 20 / portTICK_PERIOD_MS ) +#define recmuNO_DELAY ( ( TickType_t ) 0 ) +#define recmuEIGHT_TICK_DELAY ( ( TickType_t ) 8 ) + +/* The three tasks as described at the top of this file. */ +static void prvRecursiveMutexControllingTask( void *pvParameters ); +static void prvRecursiveMutexBlockingTask( void *pvParameters ); +static void prvRecursiveMutexPollingTask( void *pvParameters ); + +/* The mutex used by the demo. */ +static SemaphoreHandle_t xMutex; + +/* Variables used to detect and latch errors. */ +static volatile BaseType_t xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE; +static volatile UBaseType_t uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0; + +/* Handles of the two higher priority tasks, required so they can be resumed +(unsuspended). */ +static TaskHandle_t xControllingTaskHandle, xBlockingTaskHandle; + +/*-----------------------------------------------------------*/ + +void vStartRecursiveMutexTasks( void ) +{ + /* Just creates the mutex and the three tasks. */ + + xMutex = xSemaphoreCreateRecursiveMutex(); + + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Recursive_Mutex" ); + + + if( xMutex != NULL ) + { + xTaskCreate( prvRecursiveMutexControllingTask, "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); + xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); + xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexControllingTask( void *pvParameters ) +{ +UBaseType_t ux; + + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Should not be able to 'give' the mutex, as we have not yet 'taken' + it. The first time through, the mutex will not have been used yet, + subsequent times through, at this point the mutex will be held by the + polling task. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* We should now be able to take the mutex as many times as + we like. + + The first time through the mutex will be immediately available, on + subsequent times through the mutex will be held by the polling task + at this point and this Take will cause the polling task to inherit + the priority of this task. In this case the block time must be + long enough to ensure the polling task will execute again before the + block time expires. If the block time does expire then the error + flag will be set here. */ + if( xSemaphoreTakeRecursive( xMutex, recmuEIGHT_TICK_DELAY ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute to ensure they either block + (where a block time is specified) or return an error (where no + block time is specified) as the mutex is held by this task. */ + vTaskDelay( recmuSHORT_DELAY ); + } + + /* For each time we took the mutex, give it back. */ + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute. */ + vTaskDelay( recmuSHORT_DELAY ); + + /* We should now be able to give the mutex as many times as we + took it. When the mutex is available again the Blocking task + should be unblocked but not run because it has a lower priority + than this task. The polling task should also not run at this point + as it too has a lower priority than this task. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Having given it back the same number of times as it was taken, we + should no longer be the mutex owner, so the next give should fail. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxControllingCycles++; + + /* Suspend ourselves so the blocking task can execute. */ + xControllingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xControllingIsSuspended = pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexBlockingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This task will run while the controlling task is blocked, and the + controlling task will block only once it has the mutex - therefore + this call should block until the controlling task has given up the + mutex, and not actually execute past this call until the controlling + task is suspended. portMAX_DELAY - 1 is used instead of portMAX_DELAY + to ensure the task's state is reported as Blocked and not Suspended in + a later call to configASSERT() (within the polling task). */ + if( xSemaphoreTakeRecursive( xMutex, ( portMAX_DELAY - 1 ) ) == pdPASS ) + { + if( xControllingIsSuspended != pdTRUE ) + { + /* Did not expect to execute until the controlling task was + suspended. */ + xErrorOccurred = pdTRUE; + } + else + { + /* Give the mutex back before suspending ourselves to allow + the polling task to obtain the mutex. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + xBlockingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xBlockingIsSuspended = pdFALSE; + } + } + else + { + /* We should not leave the xSemaphoreTakeRecursive() function + until the mutex was obtained. */ + xErrorOccurred = pdTRUE; + } + + /* The controlling and blocking tasks should be in lock step. */ + if( uxControllingCycles != ( uxBlockingCycles + 1 ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxBlockingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexPollingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Keep attempting to obtain the mutex. We should only obtain it when + the blocking task has suspended itself, which in turn should only + happen when the controlling task is also suspended. */ + if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS ) + { + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xControllingTaskHandle ) == eSuspended ); + configASSERT( eTaskGetState( xBlockingTaskHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Is the blocking task suspended? */ + if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + else + { + /* Keep count of the number of cycles this task has performed + so a stall can be detected. */ + uxPollingCycles++; + + /* We can resume the other tasks here even though they have a + higher priority than the polling task. When they execute they + will attempt to obtain the mutex but fail because the polling + task is still the mutex holder. The polling task (this task) + will then inherit the higher priority. The Blocking task will + block indefinitely when it attempts to obtain the mutex, the + Controlling task will only block for a fixed period and an + error will be latched if the polling task has not returned the + mutex by the time this fixed period has expired. */ + vTaskResume( xBlockingTaskHandle ); + vTaskResume( xControllingTaskHandle ); + + /* The other two tasks should now have executed and no longer + be suspended. */ + if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + + #if( INCLUDE_uxTaskPriorityGet == 1 ) + { + /* Check priority inherited. */ + configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY ); + } + #endif /* INCLUDE_uxTaskPriorityGet */ + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xControllingTaskHandle ) == eBlocked ); + configASSERT( eTaskGetState( xBlockingTaskHandle ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Release the mutex, disinheriting the higher priority again. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if( INCLUDE_uxTaskPriorityGet == 1 ) + { + /* Check priority disinherited. */ + configASSERT( uxTaskPriorityGet( NULL ) == recmuPOLLING_TASK_PRIORITY ); + } + #endif /* INCLUDE_uxTaskPriorityGet */ + } + } + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreRecursiveMutexTasksStillRunning( void ) +{ +BaseType_t xReturn; +static UBaseType_t uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0; + + /* Is the controlling task still cycling? */ + if( uxLastControllingCycles == uxControllingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastControllingCycles = uxControllingCycles; + } + + /* Is the blocking task still cycling? */ + if( uxLastBlockingCycles == uxBlockingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastBlockingCycles = uxBlockingCycles; + } + + /* Is the polling task still cycling? */ + if( uxLastPollingCycles == uxPollingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastPollingCycles = uxPollingCycles; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/semtest.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/semtest.c new file mode 100644 index 0000000..5e43e4a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/semtest.c @@ -0,0 +1,298 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( TickType_t ) 10 ) + +/* The task function as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + SemaphoreHandle_t xSemaphore; + volatile uint32_t *pulSharedVariable; + TickType_t xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile short sNextCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( UBaseType_t uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const TickType_t xBlockTime = ( TickType_t ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + pxFirstSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary(); + xSemaphoreGive( pxFirstSemaphoreParameters->xSemaphore ); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + pxSecondSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary(); + xSemaphoreGive( pxSecondSemaphoreParameters->xSemaphore ); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + pxSecondSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS; + + xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + } + } + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) pxFirstSemaphoreParameters->xSemaphore, "Counting_Sem_1" ); + vQueueAddToRegistry( ( QueueHandle_t ) pxSecondSemaphoreParameters->xSemaphore, "Counting_Sem_2" ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvSemaphoreTest, pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile uint32_t *pulSharedVariable, ulExpectedValue; +uint32_t ulCounter; +short sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( TickType_t ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( uint32_t ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( TickType_t ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreSemaphoreTasksStillRunning( void ) +{ +static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +BaseType_t xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/sp_flop.c b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/sp_flop.c new file mode 100644 index 0000000..44cdd6f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/Minimal/sp_flop.c @@ -0,0 +1,365 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates eight tasks, each of which loops continuously performing a floating + * point calculation - using single precision variables. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE configMINIMAL_STACK_SIZE +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +{ +volatile float f1, f2, f3, f4; +volatile uint16_t *pusTaskCheckVariable; +volatile float fAnswer; +short sError = pdFALSE; + + f1 = 123.4567F; + f2 = 2345.6789F; + f3 = -918.222F; + + fAnswer = ( f1 + f2 ) * f3; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + f1 = 123.4567F; + f2 = 2345.6789F; + f3 = -918.222F; + + f4 = ( f1 + f2 ) * f3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( f4 - fAnswer ) > 0.001F ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +{ +volatile float f1, f2, f3, f4; +volatile uint16_t *pusTaskCheckVariable; +volatile float fAnswer; +short sError = pdFALSE; + + f1 = -389.38F; + f2 = 32498.2F; + f3 = -2.0001F; + + fAnswer = ( f1 / f2 ) * f3; + + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + f1 = -389.38F; + f2 = 32498.2F; + f3 = -2.0001F; + + f4 = ( f1 / f2 ) * f3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( f4 - fAnswer ) > 0.001F ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +{ +volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + fTotal1 = 0.0F; + fTotal2 = 0.0F; + fPosition = 0.0F; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pfArray[ xPosition ] = fPosition + 5.5F; + fTotal1 += fPosition + 5.5F; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + fTotal2 += pfArray[ xPosition ]; + } + + fDifference = fTotal1 - fTotal2; + if( fabs( fDifference ) > 0.001F ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +{ +volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + fTotal1 = 0.0F; + fTotal2 = 0.0F; + fPosition = 0.0F; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pfArray[ xPosition ] = fPosition * 12.123F; + fTotal1 += fPosition * 12.123F; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + fTotal2 += pfArray[ xPosition ]; + } + + fDifference = fTotal1 - fTotal2; + if( fabs( fDifference ) > 0.001F ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static uint16_t usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; +BaseType_t xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlckQ.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlckQ.h new file mode 100644 index 0000000..5e5eb3f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlckQ.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef ALT_BLOCK_Q_H +#define ALT_BLOCK_Q_H + +void vStartAltBlockingQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreAltBlockingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlock.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlock.h new file mode 100644 index 0000000..7946734 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltBlock.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FAST_BLOCK_TIME_TEST_H +#define FAST_BLOCK_TIME_TEST_H + +void vCreateAltBlockTimeTasks( void ); +BaseType_t xAreAltBlockTimeTestTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltPollQ.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltPollQ.h new file mode 100644 index 0000000..ce6af62 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltPollQ.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef ALT_POLLED_Q_H +#define ALT_POLLED_Q_H + +void vStartAltPolledQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreAltPollingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltQTest.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltQTest.h new file mode 100644 index 0000000..cf50026 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/AltQTest.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FAST_GEN_Q_TEST_H +#define FAST_GEN_Q_TEST_H + +void vStartAltGenericQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreAltGenericQueueTasksStillRunning( void ); + +#endif /* GEN_Q_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/BlockQ.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/BlockQ.h new file mode 100644 index 0000000..7a6ea01 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/BlockQ.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef BLOCK_Q_H +#define BLOCK_Q_H + +void vStartBlockingQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreBlockingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/EventGroupsDemo.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/EventGroupsDemo.h new file mode 100644 index 0000000..1b5c49c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/EventGroupsDemo.h @@ -0,0 +1,82 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + + +/* + * This file contains fairly comprehensive checks on the behaviour of event + * groups. It is not intended to be a user friendly demonstration of the event + * groups API. + */ + +#ifndef EVENT_GROUPS_DEMO_H +#define EVENT_GROUPS_DEMO_H + +void vStartEventGroupTasks( void ); +BaseType_t xAreEventGroupTasksStillRunning( void ); +void vPeriodicEventGroupsProcessing( void ); + +#endif /* EVENT_GROUPS_DEMO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/GenQTest.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/GenQTest.h new file mode 100644 index 0000000..a832900 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/GenQTest.h @@ -0,0 +1,76 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef GEN_Q_TEST_H +#define GEN_Q_TEST_H + +void vStartGenericQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreGenericQueueTasksStillRunning( void ); +void vMutexISRInteractionTest( void ); + +#endif /* GEN_Q_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/IntQueue.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/IntQueue.h new file mode 100644 index 0000000..77fae82 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/IntQueue.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_ACCESS_TEST +#define QUEUE_ACCESS_TEST + +void vStartInterruptQueueTasks( void ); +BaseType_t xAreIntQueueTasksStillRunning( void ); +BaseType_t xFirstTimerHandler( void ); +BaseType_t xSecondTimerHandler( void ); + +#endif /* QUEUE_ACCESS_TEST */ + + + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/PollQ.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/PollQ.h new file mode 100644 index 0000000..5a6dc8e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/PollQ.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef POLLED_Q_H +#define POLLED_Q_H + +void vStartPolledQueueTasks( UBaseType_t uxPriority ); +BaseType_t xArePollingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QPeek.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QPeek.h new file mode 100644 index 0000000..b9b8525 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QPeek.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef Q_PEEK_TEST_H +#define Q_PEEK_TEST_H + +void vStartQueuePeekTasks( void ); +BaseType_t xAreQueuePeekTasksStillRunning( void ); + +#endif /* Q_PEEK_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueOverwrite.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueOverwrite.h new file mode 100644 index 0000000..1d79247 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueOverwrite.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_OVERWRITE_H +#define QUEUE_OVERWRITE_H + +void vStartQueueOverwriteTask( UBaseType_t uxPriority ); +BaseType_t xIsQueueOverwriteTaskStillRunning( void ); +void vQueueOverwritePeriodicISRDemo( void ); + +#endif /* QUEUE_OVERWRITE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueSet.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueSet.h new file mode 100644 index 0000000..16c4623 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/QueueSet.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_WAIT_MULTIPLE_H +#define QUEUE_WAIT_MULTIPLE_H + +void vStartQueueSetTasks( void ); +BaseType_t xAreQueueSetTasksStillRunning( void ); +void vQueueSetAccessQueueSetFromISR( void ); + +#endif /* QUEUE_WAIT_MULTIPLE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/TimerDemo.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/TimerDemo.h new file mode 100644 index 0000000..d005a64 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/TimerDemo.h @@ -0,0 +1,76 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef TIMER_DEMO_H +#define TIMER_DEMO_H + +void vStartTimerDemoTask( TickType_t xBaseFrequencyIn ); +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ); +void vTimerPeriodicISRTests( void ); + +#endif /* TIMER_DEMO_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/blocktim.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/blocktim.h new file mode 100644 index 0000000..fb56df4 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/blocktim.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef BLOCK_TIME_TEST_H +#define BLOCK_TIME_TEST_H + +void vCreateBlockTimeTasks( void ); +BaseType_t xAreBlockTimeTestTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest.h new file mode 100644 index 0000000..43d92c8 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +void vStartComTestTasks( UBaseType_t uxPriority, eCOMPort ePort, eBaud eBaudRate ); +BaseType_t xAreComTestTasksStillRunning( void ); +void vComTestUnsuspendTask( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest2.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest2.h new file mode 100644 index 0000000..43e9993 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest2.h @@ -0,0 +1,73 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest_strings.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest_strings.h new file mode 100644 index 0000000..0d72615 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/comtest_strings.h @@ -0,0 +1,73 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_STRINGS_H +#define COMTEST_STRINGS_H + +void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/countsem.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/countsem.h new file mode 100644 index 0000000..484a23a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/countsem.h @@ -0,0 +1,73 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COUNT_SEMAPHORE_TEST_H +#define COUNT_SEMAPHORE_TEST_H + +void vStartCountingSemaphoreTasks( void ); +BaseType_t xAreCountingSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crflash.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crflash.h new file mode 100644 index 0000000..3d51635 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crflash.h @@ -0,0 +1,85 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CRFLASH_LED_H +#define CRFLASH_LED_H + +/* + * Create the co-routines used to flash the LED's at different rates. + * + * @param uxPriority The number of 'fixed delay' co-routines to create. This + * also effects the number of LED's that will be utilised. For example, + * passing in 3 will cause LED's 0 to 2 to be utilised. + */ +void vStartFlashCoRoutines( UBaseType_t uxPriority ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +BaseType_t xAreFlashCoRoutinesStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crhook.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crhook.h new file mode 100644 index 0000000..d56ee65 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/crhook.h @@ -0,0 +1,81 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CRHOOK_H +#define CRHOOK_H + +/* + * Create the co-routines used to communicate wit the tick hook. + */ +void vStartHookCoRoutines( void ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +BaseType_t xAreHookCoRoutinesStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/death.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/death.h new file mode 100644 index 0000000..5d08038 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/death.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SUICIDE_TASK_H +#define SUICIDE_TASK_H + +void vCreateSuicidalTasks( UBaseType_t uxPriority ); +BaseType_t xIsCreateTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/dynamic.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/dynamic.h new file mode 100644 index 0000000..a923c20 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/dynamic.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef DYNAMIC_MANIPULATION_H +#define DYNAMIC_MANIPULATION_H + +void vStartDynamicPriorityTasks( void ); +BaseType_t xAreDynamicPriorityTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/fileIO.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/fileIO.h new file mode 100644 index 0000000..afcf005 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/fileIO.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FILE_IO_H +#define FILE_OI_H + +void vDisplayMessage( const char * const pcMessageToPrint ); +void vWriteMessageToDisk( const char * const pcMessage ); +void vWriteBufferToDisk( const char * const pcBuffer, uint32_t ulBufferLength ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash.h new file mode 100644 index 0000000..41ea2f6 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash.h @@ -0,0 +1,72 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLASH_LED_H +#define FLASH_LED_H + +void vStartLEDFlashTasks( UBaseType_t uxPriority ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash_timer.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash_timer.h new file mode 100644 index 0000000..2e7a230 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flash_timer.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLASH_TIMER_H +#define FLASH_TIMER_H + +/* + * Creates the LED flashing timers. xNumberOfLEDs specifies how many timers to + * create, with each timer toggling a different LED. The first LED to be + * toggled is LED 0, with subsequent LEDs following on in numerical order. Each + * timer uses the exact same callback function, with the timer ID being used + * within the callback function to determine which timer has actually expired + * (and therefore which LED to toggle). + */ +void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs ); + +#endif /* FLASH_TIMER_H */ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flop.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flop.h new file mode 100644 index 0000000..ef6fe64 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/flop.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLOP_TASKS_H +#define FLOP_TASKS_H + +void vStartMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreMathsTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/integer.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/integer.h new file mode 100644 index 0000000..8b0d960 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/integer.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INTEGER_TASKS_H +#define INTEGER_TASKS_H + +void vStartIntegerMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreIntegerMathsTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/mevents.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/mevents.h new file mode 100644 index 0000000..fed650e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/mevents.h @@ -0,0 +1,74 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef EVENTS_TEST_H +#define EVENTS_TEST_H + +void vStartMultiEventTasks( void ); +BaseType_t xAreMultiEventTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/partest.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/partest.h new file mode 100644 index 0000000..0886481 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/partest.h @@ -0,0 +1,76 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PARTEST_H +#define PARTEST_H + +#define partstDEFAULT_PORT_ADDRESS ( ( uint16_t ) 0x378 ) + +void vParTestInitialise( void ); +void vParTestSetLED( UBaseType_t uxLED, BaseType_t xValue ); +void vParTestToggleLED( UBaseType_t uxLED ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/print.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/print.h new file mode 100644 index 0000000..562b1e7 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/print.h @@ -0,0 +1,75 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PRINT_H +#define PRINT_H + +void vPrintInitialise( void ); +void vPrintDisplayMessage( const char * const * pcMessageToSend ); +const char *pcPrintGetNextMessage( TickType_t xPrintRate ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/recmutex.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/recmutex.h new file mode 100644 index 0000000..82eee1f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/recmutex.h @@ -0,0 +1,73 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef RECURSIVE_MUTEX_TEST_H +#define RECURSIVE_MUTEX_TEST_H + +void vStartRecursiveMutexTasks( void ); +BaseType_t xAreRecursiveMutexTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/semtest.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/semtest.h new file mode 100644 index 0000000..4c7ffb3 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/semtest.h @@ -0,0 +1,73 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SEMAPHORE_TEST_H +#define SEMAPHORE_TEST_H + +void vStartSemaphoreTasks( UBaseType_t uxPriority ); +BaseType_t xAreSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/serial.h b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/serial.h new file mode 100644 index 0000000..838ccd3 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Demo/Common/include/serial.h @@ -0,0 +1,136 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SERIAL_COMMS_H +#define SERIAL_COMMS_H + +typedef void * xComPortHandle; + +typedef enum +{ + serCOM1, + serCOM2, + serCOM3, + serCOM4, + serCOM5, + serCOM6, + serCOM7, + serCOM8 +} eCOMPort; + +typedef enum +{ + serNO_PARITY, + serODD_PARITY, + serEVEN_PARITY, + serMARK_PARITY, + serSPACE_PARITY +} eParity; + +typedef enum +{ + serSTOP_1, + serSTOP_2 +} eStopBits; + +typedef enum +{ + serBITS_5, + serBITS_6, + serBITS_7, + serBITS_8 +} eDataBits; + +typedef enum +{ + ser50, + ser75, + ser110, + ser134, + ser150, + ser200, + ser300, + ser600, + ser1200, + ser1800, + ser2400, + ser4800, + ser9600, + ser19200, + ser38400, + ser57600, + ser115200 +} eBaud; + +xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ); +xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength ); +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ); +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime ); +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime ); +portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); +void vSerialClose( xComPortHandle xPort ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/License/license.txt b/USDK/component/os/freertos/freertos_v8.1.2/License/license.txt new file mode 100644 index 0000000..be959bb --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/License/license.txt @@ -0,0 +1,394 @@ +The FreeRTOS source code is licensed by a *modified* GNU General Public +License (GPL). The modification is provided in the form of an exception. + +NOTE: The modification to the GPL is included to allow you to distribute a +combined work that includes FreeRTOS without being obliged to provide the source +code for proprietary components outside of the FreeRTOS kernel. + + + +---------------------------------------------------------------------------- + +The FreeRTOS GPL Exception Text: + +Any FreeRTOS source code, whether modified or in it's original release form, +or whether in whole or in part, can only be distributed by you under the terms +of the GNU General Public License plus this exception. An independent module is +a module which is not derived from or based on FreeRTOS. + +Clause 1: + +Linking FreeRTOS statically or dynamically with other modules is making a +combined work based on FreeRTOS. Thus, the terms and conditions of the GNU +General Public License cover the whole combination. + +As a special exception, the copyright holder of FreeRTOS gives you permission +to link FreeRTOS with independent modules that communicate with FreeRTOS +solely through the FreeRTOS API interface, regardless of the license terms of +these independent modules, and to copy and distribute the resulting combined +work under terms of your choice, provided that + + + Every copy of the combined work is accompanied by a written statement that + details to the recipient the version of FreeRTOS used and an offer by yourself + to provide the FreeRTOS source code (including any modifications you may have + made) should the recipient request it. + + + The combined work is not itself an RTOS, scheduler, kernel or related product. + + + The independent modules add significant and primary functionality to FreeRTOS + and do not merely extend the existing functionality already present in FreeRTOS. + +Clause 2: + +FreeRTOS may not be used for any competitive or comparative purpose, including the +publication of any form of run time or compile time metric, without the express +permission of Real Time Engineers Ltd. (this is the norm within the industry and +is intended to ensure information accuracy). + + +-------------------------------------------------------------------- + +The standard GPL exception text: + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License** as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/Makefile b/USDK/component/os/freertos/freertos_v8.1.2/Source/Makefile new file mode 100644 index 0000000..08c16c5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/Makefile @@ -0,0 +1,48 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +MODULE_IFLAGS = -I./include + + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = tasks.o list.o croutine.o queue.o timers.o event_groups.o +ifeq ($(CONFIG_RELEASE_BUILD),y) + OBJS = +else +endif + + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +#all: CORE_TARGETS COPY_RAM_OBJS +all: CORE_TARGETS COPY_RAM_OBJS + make -C portable/MemMang all + make -C portable/GCC/ARM_CM4F all + + + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + + +#*****************************************************************************# +# RULES TO CLEAN TARGETS # +#*****************************************************************************# +clean: + make -C portable/MemMang clean + make -C portable/GCC/ARM_CM4F clean + $(REMOVE) *.o + $(REMOVE) *.i + $(REMOVE) *.s + $(REMOVE) *.d + +-include $(DEPS) diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/croutine.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/croutine.c new file mode 100644 index 0000000..3c5bd6f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/croutine.c @@ -0,0 +1,386 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +CRCB_t * pxCurrentCoRoutine = NULL; +static UBaseType_t uxTopCoRoutineReadyPriority = 0; +static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) +{ +BaseType_t xReturn; +CRCB_t *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) +{ +TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +CRCB_t *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) +{ +CRCB_t *pxUnblockedCRCB; +BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/event_groups.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/event_groups.c new file mode 100644 index 0000000..caecbbb --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/event_groups.c @@ -0,0 +1,676 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + +#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available. +#endif + +#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 ) + #error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available. +#endif + +/* The following bit fields convey control information in a task's event list +item value. It is important they don't clash with the +taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if configUSE_16_BIT_TICKS == 1 + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#else + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#endif + +typedef struct xEventGroupDefinition +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ); + +/*-----------------------------------------------------------*/ + +EventGroupHandle_t xEventGroupCreate( void ) +{ +EventGroup_t *pxEventBits; + + pxEventBits = pvPortMalloc( sizeof( EventGroup_t ) ); + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); + } + + return ( EventGroupHandle_t ) pxEventBits; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t uxOriginalBitValue, uxReturn; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + the task unblocks, but some compilers mistakenly generate a + warning about uxReturn being returned without being set if the + assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + bits it was waiting for were set, it is possible that since it + unblocked another task has set the bits. If this is the case + then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn, uxControlBits = 0; +BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + itself, and that at least one bit is being requested. */ + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + } + else + { + /* The task is going to block to wait for its required bits to be + set. uxControlBits are used to remember the specified behaviour of + this call to xEventGroupWaitBits() - for use when the event bits + unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + some compilers mistakenly generate a warning about the variable + being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Prevent compiler warnings when trace macros are not used. */ + xTimeoutOccurred = pdFALSE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + itself. */ + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ +UBaseType_t uxSavedInterruptStatus; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +ListItem_t *pxListItem, *pxNext; +ListItem_t const *pxListEnd; +List_t *pxList; +EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + itself. */ + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + item before removing the task from the event list. The + eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + that is was unblocked due to its required bits matching, rather + than because it timed out. */ + ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + used here as the list item may have been removed from the event list + and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + vPortFree( pxEventBits ); + } + ( void ) xTaskResumeAll(); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from +an interrupt. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from +an interrupt. */ +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) +{ +BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if (configUSE_TRACE_FACILITY == 1) + + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/FreeRTOS.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/FreeRTOS.h new file mode 100644 index 0000000..f975a14 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/FreeRTOS.h @@ -0,0 +1,780 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +#include /* READ COMMENT ABOVE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _PLATFORM_AUTOCONFIG_H_ +#include "platform_autoconf.h" +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +//----------- +#if defined(CONFIG_PLATFORM_8195A) + #ifndef CONFIG_USE_TCM_HEAP + #define CONFIG_USE_TCM_HEAP 1 + #endif + #ifndef configUSE_STACK_TCM_HEAP + #define configUSE_STACK_TCM_HEAP 5 // min priority use tcm + #endif +#else + #undef configUSE_STACK_TCM_HEAP + #define configUSE_STACK_TCM_HEAP 0 +#endif +//----------- + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #error Missing definition: configUSE_CO_ROUTINES must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #error Missing definition: INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #error Missing definition: INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelete + #error Missing definition: INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskSuspend + #error Missing definition: INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #error Missing definition: INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef INCLUDE_vTaskDelay + #error Missing definition: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configMAX_PRIORITIES + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle + #define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_pcTaskGetTaskName + #define INCLUDE_pcTaskGetTaskName 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xEventGroupSetBitFromISR + #define INCLUDE_xEventGroupSetBitFromISR 0 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL() +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 1 + #endif + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef pvPortMallocAligned + #define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) ) +#endif + +#ifndef vPortFreeAligned + #define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree ) +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/StackMacros.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/StackMacros.h new file mode 100644 index 0000000..c7cfb28 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/StackMacros.h @@ -0,0 +1,180 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 0 ) + + /* FreeRTOSConfig.h is not set to check for stack overflows. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */ +/*-----------------------------------------------------------*/ + +#if( configCHECK_FOR_STACK_OVERFLOW == 1 ) + + /* FreeRTOSConfig.h is only set to use the first method of + overflow checking. */ + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() + +#endif +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#endif /* STACK_MACROS_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/croutine.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/croutine.h new file mode 100644 index 0000000..e9a86d0 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/croutine.h @@ -0,0 +1,758 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/event_groups.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/event_groups.h new file mode 100644 index 0000000..51e7ea2 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/event_groups.h @@ -0,0 +1,726 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +typedef void * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. This function cannot be called from an interrupt. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and 
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - 
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ); +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ); + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ); + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ); +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ); + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/list.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/list.h new file mode 100644 index 0000000..c08b11d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/list.h @@ -0,0 +1,403 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST_ITEM +{ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + configLIST_VOLATILE UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ); + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ); + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ); + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pvIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pvIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pvIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ); + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/mpu_wrappers.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/mpu_wrappers.h new file mode 100644 index 0000000..6777be5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/mpu_wrappers.h @@ -0,0 +1,153 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + #define xTaskGenericCreate MPU_xTaskGenericCreate + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define vTaskDelay MPU_vTaskDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define eTaskGetState MPU_eTaskGetState + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueAltGenericSend MPU_xQueueAltGenericSend + #define xQueueAltGenericReceive MPU_xQueueAltGenericReceive + #define xQueueGenericReceive MPU_xQueueGenericReceive + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define vQueueDelete MPU_vQueueDelete + #define xQueueGenericReset MPU_xQueueGenericReset + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueuePeekFromISR MPU_xQueuePeekFromISR + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + + #define pvPortMalloc MPU_pvPortMalloc + #define vPortFree MPU_vPortFree + #define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize + #define vPortInitialiseBlocks MPU_vPortInitialiseBlocks + + #if configQUEUE_REGISTRY_SIZE > 0 + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #endif + + /* Remove the privileged function macro. */ + #define PRIVILEGED_FUNCTION + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/portable.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/portable.h new file mode 100644 index 0000000..d48d6db --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/portable.h @@ -0,0 +1,425 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Include the macro file relevant to the port being used. +NOTE: The following definitions are *DEPRECATED* as it is preferred to instead +just add the path to the correct portmacro.h header file to the compiler's +include path. */ +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +/* Catch all to ensure portmacro.h is included in the build. Newer demos +have the path as part of the project options, rather than as relative from +the project location. If portENTER_CRITICAL() has not been defined then +portmacro.h has not yet been included - as every portmacro.h provides a +portENTER_CRITICAL() definition. Check the demo application for your demo +to find the path to the correct portmacro.h file. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007U ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +static void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ); + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/projdefs.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/projdefs.h new file mode 100644 index 0000000..9eccedf --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/projdefs.h @@ -0,0 +1,94 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. */ +#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) ( xTimeInMs ) * configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* Error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +#endif /* PROJDEFS_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/queue.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/queue.h new file mode 100644 index 0000000..a728a7c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/queue.h @@ -0,0 +1,1687 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +typedef void * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef void * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef void * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance. This allocates the storage required by the + * new queue and returns a handle for the queue. + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( uxQueueLength, uxItemSize, queueQUEUE_TYPE_BASE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void *pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericReceive(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   TickType_t	xTicksToWait
+									   BaseType_t	xJustPeek
+									);
+ * + * It is preferred that the macro xQueueReceive() be used rather than calling + * this function directly. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueueGenericReceive() will return immediately if the queue is empty and + * xTicksToWait is 0. + * + * @param xJustPeek When set to true, the item received from the queue is not + * actually removed from the queue - meaning a subsequent call to + * xQueueReceive() will return the same item. When set to false, the item + * being received from the queue is also removed from the queue. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + +/* + * xQueueAltGenericSend() is an alternative version of xQueueGenericSend(). + * Likewise xQueueAltGenericReceive() is an alternative version of + * xQueueGenericReceive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +BaseType_t xQueueAltGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ); +BaseType_t xQueueAltGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ); +#define xQueueAltSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) +#define xQueueAltSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueAltGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) +#define xQueueAltReceive( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) +#define xQueueAltPeek( xQueue, pvBuffer, xTicksToWait ) xQueueAltGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. pdPASS is returned if the + * queue is successfully reset. pdFAIL is returned if the queue could not be + * reset because there are tasks blocked on the queue waiting to either + * receive from the queue or send to the queue. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if configQUEUE_REGISTRY_SIZE > 0 + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the queue creation function, which is in turn called by + * any queue, semaphore or mutex creation function or macro. + */ +QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/semphr.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/semphr.h new file mode 100644 index 0000000..5275895 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/semphr.h @@ -0,0 +1,840 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Function that creates a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as nothing is actually stored - all that is important is whether the queue is + * empty or full (the binary semaphore is available or not). + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, but instead buried in a more complex
+			// call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) + + +/* + * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) + +/* + * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). + * + * The source code that implements the alternative (Alt) API is much + * simpler because it executes everything from within a critical section. + * This is the approach taken by many other RTOSes, but FreeRTOS.org has the + * preferred fully featured API too. The fully featured API has more + * complex code that takes longer to execute, but makes much less use of + * critical sections. Therefore the alternative API sacrifices interrupt + * responsiveness to gain execution speed, whereas the fully featured API + * sacrifices execution speed to ensure better interrupt responsiveness. + */ +#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to vSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Macro that implements a mutex semaphore by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros should not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Macro that implements a recursive mutex by using the existing queue + * mechanism. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros should not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See vSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex + * \ingroup Semaphores + */ +#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Macro that creates a counting semaphore by using the existing + * queue mechanism. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/stdint.readme b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/stdint.readme new file mode 100644 index 0000000..4414c29 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/stdint.readme @@ -0,0 +1,27 @@ + +#ifndef FREERTOS_STDINT +#define FREERTOS_STDINT + +/******************************************************************************* + * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions + * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be + * built using compilers that do not provide their own stdint.h definition. + * + * To use this file: + * + * 1) Copy this file into the directory that contains your FreeRTOSConfig.h + * header file, as that directory will already be in the compilers include + * path. + * + * 2) Rename the copied file stdint.h. + * + */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long int32_t; +typedef unsigned long uint32_t; + +#endif /* FREERTOS_STDINT */ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/task.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/task.h new file mode 100644 index 0000000..ca71024 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/task.h @@ -0,0 +1,1570 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V8.1.2" +#define tskKERNEL_VERSION_MAJOR 8 +#define tskKERNEL_VERSION_MINOR 1 +#define tskKERNEL_VERSION_BUILD 2 + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +typedef void * TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted /* The task being queried has been deleted, but its TCB has not yet been freed. */ +} eTaskState; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + uint16_t usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDelataRunTimeCounterOfPeroid;/* The delta run time counter in a sample peroid*/ +#endif + uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() + +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  uint16_t usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. INCLUDE_pcTaskGetTaskName must be + * set to 1 in FreeRTOSConfig.h for pcTaskGetTaskName() to be available. + * + * \defgroup pcTaskGetTaskName pcTaskGetTaskName + * \ingroup TaskUtils + */ +char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ); + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer )
+	{
+	TaskStatus_t *pxTaskStatusArray;
+	volatile UBaseType_t uxArraySize, x;
+	uint32_t ulTotalRunTime, ulStatsAsPercentage;
+
+		// Make sure the write buffer does not contain a string.
+		*pcWriteBuffer = 0x00;
+
+		// Take a snapshot of the number of tasks in case it changes while this
+		// function is executing.
+		uxArraySize = uxTaskGetNumberOfTasks();
+
+		// Allocate a TaskStatus_t structure for each task.  An array could be
+		// allocated statically at compile time.
+		pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
+
+		if( pxTaskStatusArray != NULL )
+		{
+			// Generate raw status information about each task.
+			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
+
+			// For percentage calculations.
+			ulTotalRunTime /= 100UL;
+
+			// Avoid divide by zero errors.
+			if( ulTotalRunTime > 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ); + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * xTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Generic version of the task creation function which is in turn called by the + * xTaskCreate() and xTaskCreateRestricted() macros. + */ +BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only avilable when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +void *pvTaskIncrementMutexHeldCount( void ); + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/include/timers.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/timers.h new file mode 100644 index 0000000..3949135 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/include/timers.h @@ -0,0 +1,1121 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint +e956 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +typedef void * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance. This allocates the storage required + * by the new timer, initialises the new timers internal state, and returns a + * handle by which the new timer can be referenced. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used within the callback function to identify which timer actually + * expired. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * xTimerGetTimerDaemonTaskHandle() is only available if + * INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * xTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ); + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ); + +/** + * const char * const pcTimerGetTimerName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetTimerName( TimerHandle_t xTimer ); /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/list.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/list.c new file mode 100644 index 0000000..701472a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/list.c @@ -0,0 +1,204 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t * const pxIndex = pxList->pxIndex; + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t *pxIterator; +const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Insert the new list item into the list, sorted in xItemValue order. + + If the list already contains a list item with the same item value then + the new list item should be placed after it. This ensures that TCB's which + are stored in ready lists (all of which have the same xItemValue value) + get an equal share of the CPU. However, if the xItemValue is the same as + the back marker the iteration loop below will not end. This means we need + to guard against this by checking the value first and modifying the + algorithm slightly if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are: + 1) Stack overflow - + see http://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M3 + parts where numerically high priority values denote low actual + interrupt priorities, which can seem counter intuitive. See + configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + See http://www.freertos.org/FAQHelp.html for more tips, and ensure + configASSERT() is defined! http://www.freertos.org/a00110.html#configASSERT + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + { + /* There is nothing to do here, we are just iterating to the + wanted insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list +item. */ +List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pvContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/Makefile b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/Makefile new file mode 100644 index 0000000..1d72f14 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/Makefile @@ -0,0 +1,33 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +MODULE_IFLAGS = + + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = port.o + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS COPY_RAM_OBJS + + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + +clean: + $(REMOVE) *.o + $(REMOVE) *.i + $(REMOVE) *.s + $(REMOVE) *.d + +-include $(DEPS) diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/port.c new file mode 100644 index 0000000..e873f85 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/port.c @@ -0,0 +1,752 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is +defined. The value should also ensure backward compatibility. +FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ +#ifndef configKERNEL_INTERRUPT_PRIORITY + #define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000UL ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case is messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; // Init set configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " orr r14, #0xd \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. */ + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __asm volatile( "dsb" ); + __asm volatile( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +__attribute__(( naked )) uint32_t ulPortSetInterruptMask( void ) +{ + __asm volatile \ + ( \ + " mrs r0, basepri \n" \ + " mov r1, %0 \n" \ + " msr basepri, r1 \n" \ + " bx lr \n" \ + :: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \ + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return 0; +} +/*-----------------------------------------------------------*/ + +__attribute__(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue ) +{ + __asm volatile \ + ( \ + " msr basepri, r0 \n" \ + " bx lr \n" \ + :::"r0" \ + ); + + /* Just to avoid compiler warnings. */ + ( void ) ulNewMaskValue; +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " \n" /* Restore the context, including the critical nesting count. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers. */ + " msr psp, r0 \n" + " isb \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING(xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING(xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ +#if configUSE_IDLE_HOOK +void vApplicationIdleHook( void ) +{ + /* Use the idle task to place the CPU into a low power mode. Greater power + saving could be achieved by not including any demo tasks that never block. */ +#ifdef CONFIG_WDG_ON_IDLE + WDGRefresh(); +#endif +} +#endif + +#if configCHECK_FOR_STACK_OVERFLOW +#include "diag.h" +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + /* This function will be called if a task overflows its stack, if + configCHECK_FOR_STACK_OVERFLOW != 0. It might be that the function + parameters have been corrupted, depending on the severity of the stack + overflow. When this is the case pxCurrentTCB can be inspected in the + debugger to find the offending task. */ + DiagPrintf("\n[%s] STACK OVERFLOW - TaskName(%s)\n", __FUNCTION__, pcTaskName); + for( ;; ); +} +#endif +/*-----------------------------------------------------------*/ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/portmacro.h new file mode 100644 index 0000000..8f51cfb --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3/portmacro.h @@ -0,0 +1,195 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/port.c new file mode 100644 index 0000000..1e1aa88 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/port.c @@ -0,0 +1,1246 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Constants required to access and manipulate the NVIC. */ +#define portNVIC_SYSTICK_CTRL ( ( volatile uint32_t * ) 0xe000e010 ) +#define portNVIC_SYSTICK_LOAD ( ( volatile uint32_t * ) 0xe000e014 ) +#define portNVIC_SYSPRI2 ( ( volatile uint32_t * ) 0xe000ed20 ) +#define portNVIC_SYSPRI1 ( ( volatile uint32_t * ) 0xe000ed1c ) +#define portNVIC_SYS_CTRL_STATE ( ( volatile uint32_t * ) 0xe000ed24 ) +#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) + +/* Constants required to access and manipulate the MPU. */ +#define portMPU_TYPE ( ( volatile uint32_t * ) 0xe000ed90 ) +#define portMPU_REGION_BASE_ADDRESS ( ( volatile uint32_t * ) 0xe000ed9C ) +#define portMPU_REGION_ATTRIBUTE ( ( volatile uint32_t * ) 0xe000edA0 ) +#define portMPU_CTRL ( ( volatile uint32_t * ) 0xe000ed94 ) +#define portEXPECTED_MPU_TYPE_VALUE ( 8UL << 8UL ) /* 8 regions, unified. */ +#define portMPU_ENABLE ( 0x01UL ) +#define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) +#define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) +#define portMPU_REGION_VALID ( 0x10UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) +#define portPERIPHERALS_START_ADDRESS 0x40000000UL +#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL + +/* Constants required to access and manipulate the SysTick. */ +#define portNVIC_SYSTICK_CLK ( 0x00000004UL ) +#define portNVIC_SYSTICK_INT ( 0x00000002UL ) +#define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) +#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) + +/* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_PC ( 6 ) + +/* Set the privilege level to user mode if xRunningPrivileged is false. */ +#define portRESET_PRIVILEGE( xRunningPrivileged ) if( xRunningPrivileged != pdTRUE ) __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0" :::"r0" ) + +/* Each task maintains its own interrupt status in the critical nesting +variable. Note this is not saved as part of the task context as context +switches can only occur when uxCriticalNesting is zero. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/* + * Configure a number of standard MPU regions that are used by all tasks. + */ +static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; + +/* + * Return the smallest MPU region size that a given number of bytes will fit + * into. The region size is returned as the value that should be programmed + * into the region attribute register for that region. + */ +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; + +/* + * Checks to see if being called from the context of an unprivileged task, and + * if so raises the privilege level and returns false - otherwise does nothing + * other than return true. + */ +static BaseType_t prvRaisePrivilege( void ) __attribute__(( naked )); + +/* + * Standard FreeRTOS exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; +void xPortSysTickHandler( void ) __attribute__ ((optimize("3"))) PRIVILEGED_FUNCTION; +void vPortSVCHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; + +/* + * Starts the scheduler by restoring the context of the first task to run. + */ +static void prvRestoreContextOfFirstTask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; + +/* + * C portion of the SVC handler. The SVC handler is split between an asm entry + * and a C wrapper for simplicity of coding and maintenance. + */ +static void prvSVCHandler( uint32_t *pulRegisters ) __attribute__(( noinline )) PRIVILEGED_FUNCTION; + +/* + * Prototypes for all the MPU wrappers. + */ +BaseType_t MPU_xTaskGenericCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask, StackType_t *puxStackBuffer, const MemoryRegion_t * const xRegions ); +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ); +void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ); +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ); +void MPU_vTaskDelay( TickType_t xTicksToDelay ); +UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t pxTask ); +void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ); +eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ); +void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ); +void MPU_vTaskResume( TaskHandle_t pxTaskToResume ); +void MPU_vTaskSuspendAll( void ); +BaseType_t MPU_xTaskResumeAll( void ); +TickType_t MPU_xTaskGetTickCount( void ); +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); +void MPU_vTaskList( char *pcWriteBuffer ); +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ); +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ); +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ); +BaseType_t MPU_xTaskGetSchedulerState( void ); +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ); +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ); +QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ); +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ); +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ); +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ); +BaseType_t MPU_xQueueGenericReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ); +QueueHandle_t MPU_xQueueCreateMutex( void ); +QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ); +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ); +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ); +BaseType_t MPU_xQueueAltGenericSend( QueueHandle_t pxQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ); +BaseType_t MPU_xQueueAltGenericReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ); +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, char *pcName ); +void MPU_vQueueDelete( QueueHandle_t xQueue ); +void *MPU_pvPortMalloc( size_t xSize ); +void MPU_vPortFree( void *pv ); +void MPU_vPortInitialiseBlocks( void ); +size_t MPU_xPortGetFreeHeapSize( void ); +QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ); +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ); +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ); +void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = 0; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + /* Assumes psp was in use. */ + __asm volatile + ( + #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + #else + " mrs r0, psp \n" + #endif + " b %0 \n" + ::"i"(prvSVCHandler):"r0" + ); +} +/*-----------------------------------------------------------*/ + +static void prvSVCHandler( uint32_t *pulParam ) +{ +uint8_t ucSVCNumber; + + /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and + xPSR. The first argument (r0) is pulParam[ 0 ]. */ + ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; + switch( ucSVCNumber ) + { + case portSVC_START_SCHEDULER : *(portNVIC_SYSPRI1) |= portNVIC_SVC_PRI; + prvRestoreContextOfFirstTask(); + break; + + case portSVC_YIELD : *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; + /* Barriers are normally not required + but do ensure the code is completely + within the specified behaviour for the + architecture. */ + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + break; + + case portSVC_RAISE_PRIVILEGE : __asm volatile + ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Set privilege bit. */ + " msr control, r1 \n" /* Write back new control value. */ + :::"r1" + ); + break; + + default : /* Unknown SVC call. */ + break; + } +} +/*-----------------------------------------------------------*/ + +static void prvRestoreContextOfFirstTask( void ) +{ + __asm volatile + ( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3, r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldr r14, =0xfffffffd \n" /* Load exec return code. */ + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See + http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); + + /* Make PendSV and SysTick the same priority as the kernel. */ + *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI; + *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI; + + /* Configure the regions in the MPU that are common to all tasks. */ + prvSetupMPU(); + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + prvSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + __asm volatile( " svc %0 \n" + :: "i" (portSVC_START_SCHEDULER) ); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " mrs r1, control \n" + " stmdb r0!, {r1, r4-r11} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3, r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " \n" + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ +uint32_t ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +static void prvSetupTimerInterrupt( void ) +{ + /* Configure SysTick to interrupt at the requested rate. */ + *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; +} +/*-----------------------------------------------------------*/ + +static void prvSetupMPU( void ) +{ +extern uint32_t __privileged_functions_end__[]; +extern uint32_t __FLASH_segment_start__[]; +extern uint32_t __FLASH_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; + + /* Check the expected MPU is present. */ + if( *portMPU_TYPE == portEXPECTED_MPU_TYPE_VALUE ) + { + /* First setup the entire flash for unprivileged read only access. */ + *portMPU_REGION_BASE_ADDRESS = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portUNPRIVILEGED_FLASH_REGION ); + + *portMPU_REGION_ATTRIBUTE = ( portMPU_REGION_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the first 16K for privileged only access (even though less + than 10K is actually being used). This is where the kernel code is + placed. */ + *portMPU_REGION_BASE_ADDRESS = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_FLASH_REGION ); + + *portMPU_REGION_ATTRIBUTE = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the privileged data RAM region. This is where the kernel data + is placed. */ + *portMPU_REGION_BASE_ADDRESS = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_RAM_REGION ); + + *portMPU_REGION_ATTRIBUTE = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* By default allow everything to access the general peripherals. The + system peripherals and registers are protected. */ + *portMPU_REGION_BASE_ADDRESS = ( portPERIPHERALS_START_ADDRESS ) | + ( portMPU_REGION_VALID ) | + ( portGENERAL_PERIPHERALS_REGION ); + + *portMPU_REGION_ATTRIBUTE = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | + ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | + ( portMPU_REGION_ENABLE ); + + /* Enable the memory fault exception. */ + *portNVIC_SYS_CTRL_STATE |= portNVIC_MEM_FAULT_ENABLE; + + /* Enable the MPU with the background region configured. */ + *portMPU_CTRL |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); + } +} +/*-----------------------------------------------------------*/ + +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) +{ +uint32_t ulRegionSize, ulReturnValue = 4; + + /* 32 is the smallest region size, 31 is the largest valid value for + ulReturnValue. */ + for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + into the the correct bit position of the attribute register. */ + return ( ulReturnValue << 1UL ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvRaisePrivilege( void ) +{ + __asm volatile + ( + " mrs r0, control \n" + " tst r0, #1 \n" /* Is the task running privileged? */ + " itte ne \n" + " movne r0, #0 \n" /* CONTROL[0]!=0, return false. */ + " svcne %0 \n" /* Switch to privileged. */ + " moveq r0, #1 \n" /* CONTROL[0]==0, return true. */ + " bx lr \n" + :: "i" (portSVC_RAISE_PRIVILEGE) : "r0" + ); + + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) +{ +extern uint32_t __SRAM_segment_start__[]; +extern uint32_t __SRAM_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; +int32_t lIndex; +uint32_t ul; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all RAM. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Re-instate the privileged only RAM region as xRegion[ 0 ] will have + just removed the privileged only parameters. */ + xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress = + ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + 1 ); + + xMPUSettings->xRegion[ 1 ].ulRegionAttribute = + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* Invalidate all other regions. */ + for( ul = 2; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + } + else + { + /* This function is called automatically when the task is created - in + which case the stack region parameters will be valid. At all other + times the stack parameters will not be valid and it is assumed that the + stack region has already been configured. */ + if( usStackDepth > 0 ) + { + /* Define the region that allows access to the stack. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) pxBottomOfStack ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); /* Region number. */ + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | /* Read and write. */ + ( prvGetMPURegionSizeSetting( ( uint32_t ) usStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( portMPU_REGION_ENABLE ); + } + + lIndex = 0; + + for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + { + /* Translate the generic region definition contained in + xRegions into the CM3 specific MPU settings that are then + stored in xMPUSettings. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = + ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + ul ); /* Region number. */ + + xMPUSettings->xRegion[ ul ].ulRegionAttribute = + ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | + ( xRegions[ lIndex ].ulParameters ) | + ( portMPU_REGION_ENABLE ); + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + + lIndex++; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskGenericCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask, StackType_t *puxStackBuffer, const MemoryRegion_t * const xRegions ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGenericCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, xRegions ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t pxTask ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + eTaskState eReturn; + + eReturn = eTaskGetState( pxTask ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGetIdleTaskHandle(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskSuspendAll(); + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskResumeAll( void ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskResumeAll(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) +{ +TickType_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) +{ +UBaseType_t uxReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskList( char *pcWriteBuffer ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TaskHookFunction_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) +{ +QueueHandle_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t pxQueue, void * const pvBuffer ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueuePeekFromISR( pxQueue, pvBuffer ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); +void * xReturn; + + xReturn = ( void * ) xQueueGetMutexHolder( xSemaphore ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + QueueHandle_t MPU_xQueueCreateMutex( void ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_COUNTING_SEMAPHORES == 1 + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) + { + QueueSetMemberHandle_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + BaseType_t MPU_xQueueAltGenericSend( QueueHandle_t pxQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = BaseType_t xQueueAltGenericSend( pxQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configUSE_ALTERNATIVE_API == 1 + BaseType_t MPU_xQueueAltGenericReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xQueueAltGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking ); + portRESET_PRIVILEGE( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, char *pcName ) + { + BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + portRESET_PRIVILEGE( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vQueueDelete( QueueHandle_t xQueue ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vQueueDelete( xQueue ); + + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void *MPU_pvPortMalloc( size_t xSize ) +{ +void *pvReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + portRESET_PRIVILEGE( xRunningPrivileged ); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vPortFree( void *pv ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vPortFree( pv ); + + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void MPU_vPortInitialiseBlocks( void ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + vPortInitialiseBlocks(); + + portRESET_PRIVILEGE( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xPortGetFreeHeapSize( void ) +{ +size_t xReturn; +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + portRESET_PRIVILEGE( xRunningPrivileged ); + + return xReturn; +} + +/* Functions that the application writer wants to execute in privileged mode +can be defined in application_defined_privileged_functions.h. The functions +must take the same format as those above whereby the privilege state on exit +equals the privilege state on entry. For example: + +void MPU_FunctionName( [parameters ] ) +{ +BaseType_t xRunningPrivileged = prvRaisePrivilege(); + + FunctionName( [parameters ] ); + + portRESET_PRIVILEGE( xRunningPrivileged ); +} +*/ + +#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/portmacro.h new file mode 100644 index 0000000..ee06be9 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -0,0 +1,218 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* MPU specific constants. */ +#define portUSING_MPU_WRAPPERS 1 +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* SVC numbers for various services. */ +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 + +/* Scheduler utilities. */ + +#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) ) +#define portYIELD_WITHIN_API() *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + +#define portNVIC_INT_CTRL ( ( volatile uint32_t *) 0xe000ed04 ) +#define portNVIC_PENDSVSET 0x10000000 +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + + +/* Critical section management. */ + +/* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ +#define portSET_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, %0 \n" \ + " msr basepri, r0 \n" \ + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY):"r0" \ + ) + +/* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. FAQ: Setting BASEPRI to 0 is not a bug. Please see + * http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html before disagreeing. + */ +#define portCLEAR_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, #0 \n" \ + " msr basepri, r0 \n" \ + :::"r0" \ + ) + +/* FAQ: Setting BASEPRI to 0 is not a bug. Please see +http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html before disagreeing. */ +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x + + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#define portNOP() + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/Makefile b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/Makefile new file mode 100644 index 0000000..1d72f14 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/Makefile @@ -0,0 +1,33 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +MODULE_IFLAGS = + + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = port.o + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS COPY_RAM_OBJS + + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + +clean: + $(REMOVE) *.o + $(REMOVE) *.i + $(REMOVE) *.s + $(REMOVE) *.d + +-include $(DEPS) diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/port.c new file mode 100644 index 0000000..90f07d2 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/port.c @@ -0,0 +1,784 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case is messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Function to enable the VFP. + */ + static void vPortEnableVFP( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. */ + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __asm volatile( "dsb" ); + __asm volatile( "isb" ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +__attribute__(( naked )) uint32_t ulPortSetInterruptMask( void ) +{ + __asm volatile \ + ( \ + " mrs r0, basepri \n" \ + " mov r1, %0 \n" \ + " msr basepri, r1 \n" \ + " bx lr \n" \ + :: "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "r0", "r1" \ + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return 0; +} +/*-----------------------------------------------------------*/ + +__attribute__(( naked )) void vPortClearInterruptMask( uint32_t ulNewMaskValue ) +{ + __asm volatile \ + ( \ + " msr basepri, r0 \n" \ + " bx lr \n" \ + :::"r0" \ + ); + + /* Just to avoid compiler warnings. */ + ( void ) ulNewMaskValue; +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " \n" + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3} \n" + " \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" + " \n" + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " isb \n" + " \n" + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ + #if WORKAROUND_PMU_CM001 == 1 + " push { r14 } \n" + " pop { pc } \n" + #endif + #endif + " \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..ea4a54d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -0,0 +1,196 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMaskValue ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/port.c new file mode 100644 index 0000000..6014eb6 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/port.c @@ -0,0 +1,655 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* IAR includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Platform includes */ +#include "platform_autoconf.h" + +#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 + #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is +defined. The value 255 should also ensure backward compatibility. +FreeRTOS.org versions prior to V4.3.0 did not include this definition. */ +#ifndef configKERNEL_INTERRUPT_PRIORITY + #define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortSysTickHandler( void ); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +extern void vPortStartFirstTask( void ); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + vPortStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __DSB(); + __ISB(); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __DSB(); + __ISB(); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_interrupt(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above __disable_interrupt() + call above. */ + __enable_interrupt(); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __DSB(); + __WFI(); + __ISB(); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above __disable_interrupt() + call above. */ + __enable_interrupt(); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__weak void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); +#ifdef CONFIG_SOC_PS_MODULE + // RTK modified: max system timer can sleep up to 8355ms, set it to 8000 + xMaximumPossibleSuppressedTicks = 8000; +#else // Below is original code. It can only sleep 100ms in 166MHz + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; +#endif + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ +void vApplicationIdleHook( void ) +{ + /* Use the idle task to place the CPU into a low power mode. Greater power + saving could be achieved by not including any demo tasks that never block. */ +} + +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + /* This function will be called if a task overflows its stack, if + configCHECK_FOR_STACK_OVERFLOW != 0. It might be that the function + parameters have been corrupted, depending on the severity of the stack + overflow. When this is the case pxCurrentTCB can be inspected in the + debugger to find the offending task. */ +// DiagPrintf("\n\r[%s] STACK OVERFLOW - TaskName(%s)\n\r", __FUNCTION__, pcTaskName); + for( ;; ); +} + +/*-----------------------------------------------------------*/ + + + + + + + + + + + + + + + + + + + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portasm.s b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portasm.s new file mode 100644 index 0000000..e98645c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portasm.s @@ -0,0 +1,155 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include + + RSEG CODE:CODE(2) + thumb + + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + PUBLIC xPortPendSVHandler + PUBLIC ulPortSetInterruptMask + PUBLIC vPortClearInterruptMask + PUBLIC vPortSVCHandler + PUBLIC vPortStartFirstTask + + + +/*-----------------------------------------------------------*/ + +xPortPendSVHandler: + mrs r0, psp + isb + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] + + stmdb r0!, {r4-r11} /* Save the remaining registers. */ + str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ + + stmdb sp!, {r3, r14} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + + ldr r1, [r3] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + ldmia r0!, {r4-r11} /* Pop the registers. */ + msr psp, r0 + isb + bx r14 + + +/*-----------------------------------------------------------*/ + +ulPortSetInterruptMask: + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortClearInterruptMask: + msr basepri, r0 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortSVCHandler: + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ + ldmia r0!, {r4-r11} + msr psp, r0 + isb + mov r0, #0 + msr basepri, r0 + orr r14, r14, #13 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortStartFirstTask + /* Use the NVIC offset register to locate the stack. */ + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 + /* Call SVC to start the first task, ensuring interrupts are enabled. */ + cpsie i + cpsie f + dsb + isb + svc 0 + + END diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portmacro.h new file mode 100644 index 0000000..df57a31 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM3/portmacro.h @@ -0,0 +1,210 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CONFIG_PLATFORM_8195A +// to prevent marco define use in standard header file +#define _NO_DEFINITIONS_IN_HEADER_FILES +#include +//#include "basic_types.h" +#include "hal_misc.h" +#if !defined(__IARSTDLIB__) +#ifndef memcmp +#define memcmp(dst, src, sz) _memcmp(dst, src, sz) +#endif +#ifndef memset +#define memset(dst, val, sz) _memset(dst, val, sz) +#endif +#ifndef memcpy +#define memcpy(dst, src, sz) _memcpy(dst, src, sz) +#endif +#endif +#endif +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04UL ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) ) + + /*-----------------------------------------------------------*/ + + #include + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMask ); + +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in +the source code because to do so would cause other compilers to generate +warnings. */ +#pragma diag_suppress=Pe191 +#pragma diag_suppress=Pa082 + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/port.c new file mode 100644 index 0000000..c746c30 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/port.c @@ -0,0 +1,659 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Compiler includes. */ +#include + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __ARMVFP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 + #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortSysTickHandler( void ); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +extern void vPortStartFirstTask( void ); + +/* + * Turn the VFP on. + */ +extern void vPortEnableVFP( void ); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + vPortStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __DSB(); + __ISB(); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __DSB(); + __ISB(); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_interrupt(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above __disable_interrupt() + call above. */ + __enable_interrupt(); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __DSB(); + __WFI(); + __ISB(); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above __disable_interrupt() + call above. */ + __enable_interrupt(); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__weak void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + /* This function will be called if a task overflows its stack, if + configCHECK_FOR_STACK_OVERFLOW != 0 */ + + printf("\n\r[%s] STACK OVERFLOW - TaskName(%s)\n\r", __FUNCTION__, pcTaskName); + for( ;; ); +} + + + + + + + + + + + + + + + + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portasm.s b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portasm.s new file mode 100644 index 0000000..d67bc5e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portasm.s @@ -0,0 +1,195 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include + + RSEG CODE:CODE(2) + thumb + + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + PUBLIC xPortPendSVHandler + PUBLIC ulPortSetInterruptMask + PUBLIC vPortClearInterruptMask + PUBLIC vPortSVCHandler + PUBLIC vPortStartFirstTask + PUBLIC vPortEnableVFP + + +/*-----------------------------------------------------------*/ + +xPortPendSVHandler: + mrs r0, psp + isb + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r2, [r3] + + /* Is the task using the FPU context? If so, push high vfp registers. */ + tst r14, #0x10 + it eq + vstmdbeq r0!, {s16-s31} + + /* Save the core registers. */ + stmdb r0!, {r4-r11, r14} + + /* Save the new top of stack into the first member of the TCB. */ + str r0, [r2] + + stmdb sp!, {r3} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3} + + /* The first item in pxCurrentTCB is the task top of stack. */ + ldr r1, [r3] + ldr r0, [r1] + + /* Pop the core registers. */ + ldmia r0!, {r4-r11, r14} + + /* Is the task using the FPU context? If so, pop the high vfp registers + too. */ + tst r14, #0x10 + it eq + vldmiaeq r0!, {s16-s31} + + msr psp, r0 + isb + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ + #if WORKAROUND_PMU_CM001 == 1 + push { r14 } + pop { pc } + #endif + #endif + + bx r14 + + +/*-----------------------------------------------------------*/ + +ulPortSetInterruptMask: + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortClearInterruptMask: + msr basepri, r0 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortSVCHandler: + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ + ldmia r0!, {r4-r11, r14} + msr psp, r0 + isb + mov r0, #0 + msr basepri, r0 + bx r14 + +/*-----------------------------------------------------------*/ + +vPortStartFirstTask + /* Use the NVIC offset register to locate the stack. */ + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 + /* Call SVC to start the first task. */ + cpsie i + cpsie f + dsb + isb + svc 0 + +/*-----------------------------------------------------------*/ + +vPortEnableVFP: + /* The FPU enable bits are in the CPACR. */ + ldr.w r0, =0xE000ED88 + ldr r1, [r0] + + /* Enable CP10 and CP11 coprocessors, then save back. */ + orr r1, r1, #( 0xf << 20 ) + str r1, [r0] + bx r14 + + + + END + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..24599a1 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/IAR/ARM_CM4F/portmacro.h @@ -0,0 +1,193 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #include + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __CLZ( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMask ); + +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask( x ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +/* Suppress warnings that are generated by the IAR tools, but cannot be fixed in +the source code because to do so would cause other compilers to generate +warnings. */ +#pragma diag_suppress=Pe191 +#pragma diag_suppress=Pa082 + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/Makefile b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/Makefile new file mode 100644 index 0000000..b0be4b9 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/Makefile @@ -0,0 +1,41 @@ + +include $(MAKE_INCLUDE_GEN) + +.PHONY: all clean + +MODULE_IFLAGS = -I../../include + + +#*****************************************************************************# +# Object FILE LIST # +#*****************************************************************************# +OBJS = heap_4.o +ifeq ($(CONFIG_RELEASE_BUILD),y) + OBJS = +else +endif + + +#*****************************************************************************# +# RULES TO GENERATE TARGETS # +#*****************************************************************************# + +# Define the Rules to build the core targets +all: CORE_TARGETS COPY_RAM_OBJS + + +#*****************************************************************************# +# GENERATE OBJECT FILE +#*****************************************************************************# +CORE_TARGETS: $(OBJS) + +-include $(DEPS) + +#*****************************************************************************# +# RULES TO CLEAN TARGETS # +#*****************************************************************************# +clean: + $(REMOVE) *.o + $(REMOVE) *.i + $(REMOVE) *.s + $(REMOVE) *.d \ No newline at end of file diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c new file mode 100644 index 0000000..65d4f37 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_1.c @@ -0,0 +1,170 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * The simplest possible implementation of pvPortMalloc(). Note that this + * implementation does NOT allow allocated memory to be freed again. + * + * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Allocate the memory for the heap. */ +static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +static size_t xNextFreeByte = ( size_t ) 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; +static uint8_t *pucAlignedHeap = NULL; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if portBYTE_ALIGNMENT != 1 + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + #endif + + vTaskSuspendAll(); + { + if( pucAlignedHeap == NULL ) + { + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); + } + + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = pucAlignedHeap + xNextFreeByte; + xNextFreeByte += xWantedSize; + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and + heap_4.c for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; + + /* Force an assert as it is invalid to call this function. */ + configASSERT( pv == NULL ); +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c new file mode 100644 index 0000000..a28a560 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_2.c @@ -0,0 +1,299 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block (and so will fragment memory). See heap_4.c for + * an equivalent that does combine adjacent blocks into single larger blocks. + * + * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* + * Initialises the heap structures before their first use. + */ +static void prvHeapInit( void ); + +/* Allocate the memory for the heap. */ +static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + + +static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +BlockLink_t *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +static BaseType_t xHeapHasBeenInitialised = pdFALSE; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the BlockLink_t structure + at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This unexpected casting is to keep some compilers from issuing + byte alignment warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; + + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* xEnd is used to mark the end of the list of free blocks. */ + xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; + xEnd.pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; +} +/*-----------------------------------------------------------*/ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c new file mode 100644 index 0000000..8b948bf --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_3.c @@ -0,0 +1,131 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Implementation of pvPortMalloc() and vPortFree() that relies on the + * compilers own malloc() and free() implementations. + * + * This file can only be used if the linker is configured to to generate + * a heap memory area. + * + * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn; + + vTaskSuspendAll(); + { + pvReturn = malloc( xWantedSize ); + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + if( pv ) + { + vTaskSuspendAll(); + { + free( pv ); + traceFREE( pv, 0 ); + } + ( void ) xTaskResumeAll(); + } +} + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c new file mode 100644 index 0000000..7af6b6a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_4.c @@ -0,0 +1,544 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize * 2 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Allocate the memory for the heap. */ +//TODO: remove section when combine BD and BF +#if ((defined CONFIG_PLATFORM_8195A) || (defined CONFIG_PLATFORM_8711B)) +#include "section_config.h" +SRAM_BF_DATA_SECTION +#endif + +static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( ( sizeof( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + configASSERT( ( ( ( uint32_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + configASSERT( ( ( ( uint32_t ) pvReturn ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void __vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ +/* Add by Alfa 2015/02/04 -----------------------------------*/ +static void (*ext_free)( void *p ) = NULL; +static uint32_t ext_upper = 0; +static uint32_t ext_lower = 0; +void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower ) +{ + ext_free = free; + ext_upper = upper; + ext_lower = lower; +} + +void vPortFree( void *pv ) +{ + if( ((uint32_t)pv >= ext_lower) && ((uint32_t)pv < ext_upper) ){ + // use external free function + if( ext_free ) ext_free( pv ); + }else + __vPortFree( pv ); +} + +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; +uint32_t ulAddress; +size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + ulAddress = ( uint32_t ) ucHeap; + + if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + ulAddress += ( portBYTE_ALIGNMENT - 1 ); + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + xTotalHeapSize -= ulAddress - ( uint32_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) ulAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalHeapSize; + ulAddress -= xHeapStructSize; + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = ( void * ) ulAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} + +void* pvPortReAlloc( void *pv, size_t xWantedSize ) +{ + BlockLink_t *pxLink; + + if( ((uint32_t)pv >= ext_lower) && ((uint32_t)pv < ext_upper) ){ + if( ext_free ) ext_free( pv ); + pv = NULL; + } + + unsigned char *puc = ( unsigned char * ) pv; + + if( pv ) + { + if( !xWantedSize ) + { + vPortFree( pv ); + return NULL; + } + + void *newArea = pvPortMalloc( xWantedSize ); + if( newArea ) + { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + int oldSize = (pxLink->xBlockSize & ~xBlockAllocatedBit) - xHeapStructSize; + int copySize = ( oldSize < xWantedSize ) ? oldSize : xWantedSize; + memcpy( newArea, pv, copySize ); + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + xFreeBytesRemaining += pxLink->xBlockSize; + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + xTaskResumeAll(); + return newArea; + } + } + else if( xWantedSize ) + return pvPortMalloc( xWantedSize ); + else + return NULL; + + return NULL; +} + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_5.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_5.c new file mode 100644 index 0000000..84cde2a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/MemMang/heap_5.c @@ -0,0 +1,652 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() that allows the heap to be defined + * across multiple non-contigous blocks and combines (coalescences) adjacent + * memory blocks as they are freed. + * + * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative + * implementations, and the memory management pages of http://www.FreeRTOS.org + * for more information. + * + * Usage notes: + * + * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). + * pvPortMalloc() will be called if any task objects (tasks, queues, event + * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be + * called before any other objects are defined. + * + * vPortDefineHeapRegions() takes a single parameter. The parameter is an array + * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as + * + * typedef struct HeapRegion + * { + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * } HeapRegion_t; + * + * The array is terminated using a NULL zero sized region definition, and the + * memory regions defined in the array ***must*** appear in address order from + * low address to high address. So the following is a valid example of how + * to use the function. + * + * HeapRegion_t xHeapRegions[] = + * { + * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 + * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 + * { NULL, 0 } << Terminates the array. + * }; + * + * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). + * + * Note 0x80000000 is the lower address so appears in the array first. + * + */ +#include +#include +#include "diag.h" +#include "platform_autoconf.h" +#include "hal_misc.h" + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + all the API functions to use the MPU wrappers. That should only be done when + task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( uxHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Define the linked list structure. This is used to link free blocks in order + of their memory address. */ +typedef struct A_BLOCK_LINK { + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory + block must by correctly byte aligned. */ +static const uint32_t uxHeapStructSize = ((sizeof(BlockLink_t) + + ( portBYTE_ALIGNMENT - 1)) & ~portBYTE_ALIGNMENT_MASK); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about + fragmentation. */ +static size_t xFreeBytesRemaining = 0; +static size_t xMinimumEverFreeBytesRemaining = 0; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize + member of an BlockLink_t structure is set then the block belongs to the + application. When the bit is free the block is still part of the free heap + space. */ +//static size_t xBlockAllocatedBit = 0; +/* Work out the position of the top bit in a size_t variable. */ +#define xBlockAllocatedBit (( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 )) + +/* Realtek test code start */ +//TODO: remove section when combine BD and BF +#if (defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)) +#include "section_config.h" +SRAM_HEAP_SECTION +#endif +unsigned char ucHeap[configTOTAL_HEAP_SIZE]; + +//extern void * __sdram_bss_end__; +//extern void * __ram_heap1_start__, __ram_heap1_end__, __ram_heap2_start__, __sdram_data_start__; + +extern HeapRegion_t xHeapRegions[]; + +#if 0 +#if defined(CONFIG_PLATFORM_8195A) +HeapRegion_t xHeapRegions[] = +{ + { (uint8_t*)0x10003000, 0x10006000 - 0x10003000}, // __ram_heap1_start__, __ram_heap1_end__ - __ram_heap1_start__ + { ucHeap, sizeof(ucHeap)}, // Defines a block from ucHeap +#ifdef CONFIG_SDR_EN + { (uint8_t*)&__sdram_bss_end__, 0x80000}, +#endif + { NULL, 0} // Terminates the array. +}; +#elif (defined CONFIG_PLATFORM_8711B) +HeapRegion_t xHeapRegions[] = +{ + { ucHeap, sizeof(ucHeap)}, // Defines a block from ucHeap + { NULL, 0} // Terminates the array. +}; +#else +#error NOT SUPPORT CHIP +#endif +#endif + +/*-----------------------------------------------------------*/ +/* + Dump xBlock list + */ +void dump_mem_block_list(void) { + if (pxEnd == NULL) + vPortDefineHeapRegions(xHeapRegions); +#if CONFIG_DEBUG_LOG > 1 +// if(pxEnd == NULL) vPortDefineHeapRegions( xHeapRegions ); // test code start + BlockLink_t *pxBlock = &xStart; + int count = 0; + DBG_8195A("RAM Free Heap Memory List:\n"); + for (pxBlock = pxBlock->pxNextFreeBlock; pxBlock->pxNextFreeBlock != NULL; + pxBlock = pxBlock->pxNextFreeBlock) { + DBG_8195A(" [%d]=%p, %d\n", ++count, pxBlock, pxBlock->xBlockSize); + } +#endif +} + +void *pvPortMalloc(size_t xWantedSize) { + BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; + void *pvReturn = NULL; + + /* Realtek test code start */ + if (pxEnd == NULL) + vPortDefineHeapRegions(xHeapRegions); + /* Realtek test code end */ + + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); + + vTaskSuspendAll(); + { + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if ((xWantedSize & xBlockAllocatedBit) == 0) { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if (xWantedSize > 0) { + xWantedSize += uxHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if ((xWantedSize & portBYTE_ALIGNMENT_MASK) != 0x00) { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT + - (xWantedSize & portBYTE_ALIGNMENT_MASK)); + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } + + if ((xWantedSize > 0) && (xWantedSize <= xFreeBytesRemaining)) { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while ((pxBlock->xBlockSize < xWantedSize) + && (pxBlock->pxNextFreeBlock != NULL)) { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if (pxBlock != pxEnd) { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = + (void *) (((uint8_t *) pxPreviousBlock->pxNextFreeBlock) + + uxHeapStructSize); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if ((pxBlock->xBlockSize - xWantedSize) + > heapMINIMUM_BLOCK_SIZE) { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = (void *) (((uint8_t *) pxBlock) + + xWantedSize); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize + - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList((pxNewBlockLink)); + } else { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if (xFreeBytesRemaining < xMinimumEverFreeBytesRemaining) { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } else { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } traceMALLOC( pvReturn, xWantedSize ); + } + (void) xTaskResumeAll(); + if (pvReturn == NULL) { + DBG_RAM_HEAP_WARN("ram_alloc(%d): freeSpace(%d)!\n", xWantedSize, + xFreeBytesRemaining); + } else { +// DBG_RAM_HEAP_INFO("ram_alloc:%p[%d]\n", pvReturn , xWantedSize); + } +#if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +#endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void __vPortFree(void *pv) { + uint8_t *puc = (uint8_t *) pv; + BlockLink_t *pxLink; + + if (pv != NULL) { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= uxHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = (void *) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if ((pxLink->xBlockSize & xBlockAllocatedBit) != 0) { + if (pxLink->pxNextFreeBlock == NULL) { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList(((BlockLink_t *) pxLink)); + } + (void) xTaskResumeAll(); + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } +// DBG_RAM_HEAP_INFO("ram_free:%p[%d]\n", pv , pxLink->xBlockSize); + } +} + +/*-----------------------------------------------------------*/ +/* Add by Alfa 2015/02/04 -----------------------------------*/ +static void (*ext_free)(void *p) = NULL; +//static +uint32_t ext_upper = 0; +//static +uint32_t ext_lower = 0; +void vPortSetExtFree(void (*free)(void *p), uint32_t upper, uint32_t lower) { + ext_free = free; + ext_upper = upper; + ext_lower = lower; +} + +void vPortFree(void *pv) { + if (((uint32_t) pv >= ext_lower) && ((uint32_t) pv < ext_upper)) { + // use external free function + if (ext_free) + ext_free(pv); + } else + __vPortFree(pv); +} + +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize(void) { + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize(void) { + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert) { + BlockLink_t *pxIterator; + uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for (pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; + pxIterator = pxIterator->pxNextFreeBlock) { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = (uint8_t *) pxIterator; + if ((puc + pxIterator->xBlockSize) == (uint8_t *) pxBlockToInsert) { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } else { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = (uint8_t *) pxBlockToInsert; + if ((puc + pxBlockToInsert->xBlockSize) + == (uint8_t *) pxIterator->pxNextFreeBlock) { + if (pxIterator->pxNextFreeBlock != pxEnd) { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += + pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = + pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } else { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } else { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if (pxIterator != pxBlockToInsert) { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } else { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void vPortDefineHeapRegions(const HeapRegion_t * const pxHeapRegions) { + BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; + uint8_t *pucAlignedHeap; + size_t xTotalRegionSize, xTotalHeapSize = 0; + BaseType_t xDefinedRegions = 0; + uint32_t ulAddress; + const HeapRegion_t *pxHeapRegion; + +#if defined(CONFIG_PLATFORM_8195A) + /* + xHeapRegions[0].pucStartAddress = (uint8_t*)&__ram_heap1_start__; + xHeapRegions[0].xSizeInBytes = (u32)&__ram_heap1_end__ - (u32)xHeapRegions[0].pucStartAddress; + xHeapRegions[1].pucStartAddress = &ucHeap; // (uint8_t*)&__ram_heap2_start__; + xHeapRegions[1].xSizeInBytes = (u32)0x10070000 - (u32)xHeapRegions[1].pucStartAddress; + xHeapRegions[2].pucStartAddress = (uint8_t*)&__sdram_data_start__; + xHeapRegions[2].xSizeInBytes = (u32)0x30200000 - (u32)xHeapRegions[2].pucStartAddress; + */ +#endif + /* Can only call once! */ + configASSERT( pxEnd == NULL ); + + pxHeapRegion = &(pxHeapRegions[xDefinedRegions]); + + uint8 chip_id = HalGetChipId(); + while (pxHeapRegion->xSizeInBytes > 0) { + if (pxHeapRegion->pucStartAddress + > 0x20000000 && chip_id >= CHIP_ID_8711AN && chip_id <= CHIP_ID_8711AF) { +// pxHeapRegion->pucStartAddress = 0; +// pxHeapRegion->xSizeInBytes = 0; +// DBG_8195A("ChipID: %p !\n", chip_id); + } else { +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("Init Heap Region: %p[%d]\n", pxHeapRegion->pucStartAddress, pxHeapRegion->xSizeInBytes); +#endif +#if CONFIG_DEBUG_LOG > 4 + rtl_memset(pxHeapRegion->pucStartAddress, 0, pxHeapRegion->xSizeInBytes); +#endif + xTotalRegionSize = pxHeapRegion->xSizeInBytes; + /* Ensure the heap region starts on a correctly aligned boundary. */ + ulAddress = (uint32_t) pxHeapRegion->pucStartAddress; + if ((ulAddress & portBYTE_ALIGNMENT_MASK) != 0) { + ulAddress += ( portBYTE_ALIGNMENT - 1); + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= ulAddress + - (uint32_t) pxHeapRegion->pucStartAddress; + } + + pucAlignedHeap = (uint8_t *) ulAddress; + + /* Set xStart if it has not already been set. */ + if (xDefinedRegions == 0) { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = (BlockLink_t *) pucAlignedHeap; + xStart.xBlockSize = (size_t) 0; + } else { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); + + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( ulAddress > ( uint32_t ) pxEnd ); + } + + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; + + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + ulAddress = ((uint32_t) pucAlignedHeap) + xTotalRegionSize; + ulAddress -= uxHeapStructSize; + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = (BlockLink_t *) ulAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = (BlockLink_t *) pucAlignedHeap; + pxFirstFreeBlockInRegion->xBlockSize = ulAddress + - (uint32_t) pxFirstFreeBlockInRegion; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if (pxPreviousFreeBlock != NULL) { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } + + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + } + /* Move onto the next HeapRegion_t structure. */ + xDefinedRegions++; + pxHeapRegion = &(pxHeapRegions[xDefinedRegions]); + } + + xMinimumEverFreeBytesRemaining = xTotalHeapSize; + xFreeBytesRemaining = xTotalHeapSize; + + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); + +} + +void* pvPortReAlloc(void *pv, size_t xWantedSize) { + BlockLink_t *pxLink; + + if (((uint32_t) pv >= ext_lower) && ((uint32_t) pv < ext_upper)) { + if (ext_free) + ext_free(pv); + pv = NULL; + } + + unsigned char *puc = (unsigned char *) pv; + + if (pv) { + if (!xWantedSize) { + vPortFree(pv); + return NULL; + } + + void *newArea = pvPortMalloc(xWantedSize); + if (newArea) { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= uxHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = (void *) puc; + + int oldSize = (pxLink->xBlockSize & ~xBlockAllocatedBit) - uxHeapStructSize; + int copySize = (oldSize < xWantedSize) ? oldSize : xWantedSize; + rtl_memcpy(newArea, pv, copySize); + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + xFreeBytesRemaining += pxLink->xBlockSize; + prvInsertBlockIntoFreeList(((BlockLink_t *) pxLink)); + } + xTaskResumeAll(); + return newArea; + } + } else if (xWantedSize) + return pvPortMalloc(xWantedSize); + else + return NULL; + + return NULL; +} + +extern _LONG_CALL_ROM_ void *_memset(void *s, int c, SIZE_T n); + +void *pvPortZalloc(size_t xWantedSize) { + void * prt = pvPortMalloc(xWantedSize); + if (prt) + _memset(prt, 0, xWantedSize); + return prt; +} + +/* + #ifdef ARDUINO_SDK + int vPortAddHeapRegion(uint8_t *addr, size_t size) + { + return 0; + } + #endif + */ diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/port.c new file mode 100644 index 0000000..ccd2511 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/port.c @@ -0,0 +1,724 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef configKERNEL_INTERRUPT_PRIORITY + #define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 + #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* The __weak attribute does not work as you might expect with the Keil tools +so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if +the application writer wants to provide their own implementation of +vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION +is defined. */ +#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION + #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) + +/* Constants used with memory barrier intrinsics. */ +#define portSY_FULL_READ_WRITE ( 15 ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvStartFirstTask( void ); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ + + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +__asm void vPortSVCHandler( void ) +{ + PRESERVE8 + + ldr r3, =pxCurrentTCB /* Restore the context. */ + ldr r1, [r3] /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + ldmia r0!, {r4-r11} /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + msr psp, r0 /* Restore the task stack pointer. */ + isb + mov r0, #0 + msr basepri, r0 + orr r14, #0xd + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm void prvStartFirstTask( void ) +{ + PRESERVE8 + + /* Use the NVIC offset register to locate the stack. */ + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 + /* Globally enable interrupts. */ + cpsie i + cpsie f + dsb + isb + /* Call SVC to start the first task. */ + svc 0 + nop + nop +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + prvStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __dsb( portSY_FULL_READ_WRITE ); + __isb( portSY_FULL_READ_WRITE ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __dsb( portSY_FULL_READ_WRITE ); + __isb( portSY_FULL_READ_WRITE ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +__asm void xPortPendSVHandler( void ) +{ + extern uxCriticalNesting; + extern pxCurrentTCB; + extern vTaskSwitchContext; + + PRESERVE8 + + mrs r0, psp + isb + + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] + + stmdb r0!, {r4-r11} /* Save the remaining registers. */ + str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ + + stmdb sp!, {r3, r14} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + + ldr r1, [r3] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + ldmia r0!, {r4-r11} /* Pop the registers and the critical nesting count. */ + msr psp, r0 + isb + bx r14 + nop +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_irq(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __dsb( portSY_FULL_READ_WRITE ); + __wfi(); + __isb( portSY_FULL_READ_WRITE ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ + +/*-----------------------------------------------------------*/ + +/* + * Setup the SysTick timer to generate the tick interrupts at the required + * frequency. + */ +#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 + + void vPortSetupTimerInterrupt( void ) + { + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); + } + +#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ +/*-----------------------------------------------------------*/ + +__asm uint32_t ulPortSetInterruptMask( void ) +{ + PRESERVE8 + + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm void vPortClearInterruptMask( uint32_t ulNewMask ) +{ + PRESERVE8 + + msr basepri, r0 + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm uint32_t vPortGetIPSR( void ) +{ + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + ulCurrentInterrupt = vPortGetIPSR(); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/portmacro.h new file mode 100644 index 0000000..1e97c3e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM3/portmacro.h @@ -0,0 +1,185 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMask ); +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Port specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) ) + +#endif /* taskRECORD_READY_PRIORITY */ +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/port.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/port.c new file mode 100644 index 0000000..939522b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/port.c @@ -0,0 +1,803 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __TARGET_FPU_VFP + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0 + #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* The __weak attribute does not work as you might expect with the Keil tools +so the configOVERRIDE_DEFAULT_TICK_CONFIGURATION constant must be set to 1 if +the application writer wants to provide their own implementation of +vPortSetupTimerInterrupt(). Ensure configOVERRIDE_DEFAULT_TICK_CONFIGURATION +is defined. */ +#ifndef configOVERRIDE_DEFAULT_TICK_CONFIGURATION + #define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 0 +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0x1FUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) + +/* Constants used with memory barrier intrinsics. */ +#define portSY_FULL_READ_WRITE ( 15 ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvStartFirstTask( void ); + +/* + * Functions defined in portasm.s to enable the VFP. + */ +static void prvEnableVFP( void ); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( uint8_t * ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +__asm void vPortSVCHandler( void ) +{ + PRESERVE8 + + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ + ldmia r0!, {r4-r11, r14} + msr psp, r0 + isb + mov r0, #0 + msr basepri, r0 + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm void prvStartFirstTask( void ) +{ + PRESERVE8 + + /* Use the NVIC offset register to locate the stack. */ + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 + /* Globally enable interrupts. */ + cpsie i + cpsie f + dsb + isb + /* Call SVC to start the first task. */ + svc 0 + nop + nop +} +/*-----------------------------------------------------------*/ + +__asm void prvEnableVFP( void ) +{ + PRESERVE8 + + /* The FPU enable bits are in the CPACR. */ + ldr.w r0, =0xE000ED88 + ldr r1, [r0] + + /* Enable CP10 and CP11 coprocessors, then save back. */ + orr r1, r1, #( 0xf << 20 ) + str r1, [r0] + bx r14 + nop +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + prvEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortYield( void ) +{ + /* Set a PendSV to request a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + + /* Barriers are normally not required but do ensure the code is completely + within the specified behaviour for the architecture. */ + __dsb( portSY_FULL_READ_WRITE ); + __isb( portSY_FULL_READ_WRITE ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + __dsb( portSY_FULL_READ_WRITE ); + __isb( portSY_FULL_READ_WRITE ); + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +__asm void xPortPendSVHandler( void ) +{ + extern uxCriticalNesting; + extern pxCurrentTCB; + extern vTaskSwitchContext; + + PRESERVE8 + + mrs r0, psp + isb + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r2, [r3] + + /* Is the task using the FPU context? If so, push high vfp registers. */ + tst r14, #0x10 + it eq + vstmdbeq r0!, {s16-s31} + + /* Save the core registers. */ + stmdb r0!, {r4-r11, r14} + + /* Save the new top of stack into the first member of the TCB. */ + str r0, [r2] + + stmdb sp!, {r3} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3} + + /* The first item in pxCurrentTCB is the task top of stack. */ + ldr r1, [r3] + ldr r0, [r1] + + /* Pop the core registers. */ + ldmia r0!, {r4-r11, r14} + + /* Is the task using the FPU context? If so, pop the high vfp registers + too. */ + tst r14, #0x10 + it eq + vldmiaeq r0!, {s16-s31} + + msr psp, r0 + isb + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */ + #if WORKAROUND_PMU_CM001 == 1 + push { r14 } + pop { pc } + nop + #endif + #endif + + bx r14 + nop +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __weak void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __disable_irq(); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __dsb( portSY_FULL_READ_WRITE ); + __wfi(); + __isb( portSY_FULL_READ_WRITE ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above __disable_irq() call + above. */ + __enable_irq(); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1 ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ + +/*-----------------------------------------------------------*/ + +/* + * Setup the SysTick timer to generate the tick interrupts at the required + * frequency. + */ +#if configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 + + void vPortSetupTimerInterrupt( void ) + { + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); + } + +#endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */ +/*-----------------------------------------------------------*/ + +__asm uint32_t ulPortSetInterruptMask( void ) +{ + PRESERVE8 + + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm void vPortClearInterruptMask( uint32_t ulNewMask ) +{ + PRESERVE8 + + msr basepri, r0 + bx r14 +} +/*-----------------------------------------------------------*/ + +__asm uint32_t vPortGetIPSR( void ) +{ + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + ulCurrentInterrupt = vPortGetIPSR(); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + /* This function will be called if a task overflows its stack, if + configCHECK_FOR_STACK_OVERFLOW != 0. It might be that the function + parameters have been corrupted, depending on the severity of the stack + overflow. When this is the case pxCurrentTCB can be inspected in the + debugger to find the offending task. */ + printf("\n\r[%s] STACK OVERFLOW - TaskName(%s)\n\r", __FUNCTION__, pcTaskName); + for( ;; ); +} diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/portmacro.h b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..91dfb7f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/portable/RVDS/ARM_CM4F/portmacro.h @@ -0,0 +1,186 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +extern void vPortYield( void ); +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portYIELD() vPortYield() +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern uint32_t ulPortSetInterruptMask( void ); +extern void vPortClearInterruptMask( uint32_t ulNewMask ); +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +#define portDISABLE_INTERRUPTS() ulPortSetInterruptMask() +#define portENABLE_INTERRUPTS() vPortClearInterruptMask( 0 ) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortClearInterruptMask(x) + +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Port specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Check the configuration. */ + #if 0//( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31 - __clz( ( uxReadyPriorities ) ) ) + +#endif /* taskRECORD_READY_PRIORITY */ +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/queue.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/queue.c new file mode 100644 index 0000000..9bc9b4a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/queue.c @@ -0,0 +1,2439 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* Constants used with the xRxLock and xTxLock structure members. */ +#define queueUNLOCKED ( ( BaseType_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( BaseType_t ) 0 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +Queue_t structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +pcTail pointer actually points to the mutex holder (if any). Map alternative +names to the pcHead and pcTail structure members to ensure the readability of +the code is maintained despite this dual use of two structure members. An +alternative implementation would be to use a union, but use of a union is +against the coding standard (although an exception to the standard has been +permitted where the dual use also significantly changes the type of the +structure member). */ +#define pxMutexHolder pcTail +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. + */ +typedef struct QueueDefinition +{ + int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ + int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */ + { + int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ + UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ + } u; + + List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ + UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile BaseType_t xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile BaseType_t xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t +name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char *pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + + /* The old xQueueRegistryItem name is maintained above then typedefed to the + new xQueueRegistryItem name below to enable the use of older kernel aware + debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + + /* The queue registry is simply an array of QueueRegistryItem_t structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->xRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->xTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) +{ +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize ); + pxQueue->xRxLock = queueUNLOCKED; + pxQueue->xTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) +{ +Queue_t *pxNewQueue; +size_t xQueueSizeInBytes; +QueueHandle_t xReturn = NULL; + + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + /* Allocate the new queue structure. */ + if( uxQueueLength > ( UBaseType_t ) 0 ) + { + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) ); + if( pxNewQueue != NULL ) + { + /* Create the list of pointers to queue items. The queue is one byte + longer than asked for to make wrap checking easier/faster. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + pxNewQueue->pcHead = ( int8_t * ) pvPortMalloc( xQueueSizeInBytes ); + if( pxNewQueue->pcHead != NULL ) + { + /* Initialise the queue members as described above where the + queue type is defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); + xReturn = pxNewQueue; + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + vPortFree( pxNewQueue ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + /* Allocate the new queue structure. */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) ); + if( pxNewQueue != NULL ) + { + /* Information required for priority inheritance. */ + pxNewQueue->pxMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* Queues used as a mutex no data is actually copied into or out + of the queue. */ + pxNewQueue->pcWriteTo = NULL; + pxNewQueue->u.pcReadFrom = NULL; + + /* Each mutex has a length of 1 (like a binary semaphore) and + an item size of 0 as nothing is actually copied into or out + of the mutex. */ + pxNewQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxNewQueue->uxLength = ( UBaseType_t ) 1U; + pxNewQueue->uxItemSize = ( UBaseType_t ) 0U; + pxNewQueue->xRxLock = queueUNLOCKED; + pxNewQueue->xTxLock = queueUNLOCKED; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif + + /* Ensure the event queues start with the correct state. */ + vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) ); + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + + configASSERT( pxNewQueue ); + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + void *pxReturn; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as TaskHandle_t is a typedef. */ + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.uxRecursiveCallCount )--; + + /* Have we unwound the call count? */ + if( pxMutex->u.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */ + { + ( pxMutex->u.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE ); + + /* pdPASS will only be returned if the mutex was successfully + obtained. The calling task may have entered the Blocked state + before reaching here. */ + if( xReturn == pdPASS ) + { + ( pxMutex->u.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_COUNTING_SEMAPHORES == 1 ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + configASSERT( xHandle ); + return xHandle; + } + +#endif /* configUSE_COUNTING_SEMAPHORES */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) +{ +BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be + the highest priority task wanting to access the queue. If + the head item in the queue is to be overwritten then it does + not matter if the queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes + and the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* Return to the original privilege level before exiting the + function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_ALTERNATIVE_API == 1 ) + + BaseType_t xQueueAltGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) + { + BaseType_t xEntryTimeSet = pdFALSE; + TimeOut_t xTimeOut; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + traceQUEUE_SEND( pxQueue ); + prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + taskEXIT_CRITICAL(); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } + taskEXIT_CRITICAL(); + } + } + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_ALTERNATIVE_API == 1 ) + + BaseType_t xQueueAltGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ) + { + BaseType_t xEntryTimeSet = pdFALSE; + TimeOut_t xTimeOut; + int8_t *pcOriginalReadPosition; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + for( ;; ) + { + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember our read position in case we are just peeking. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Data is actually being removed (not just peeked). */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = ( int8_t * ) xTaskGetCurrentTaskHandle(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* We are not removing the data, so reset our read + pointer. */ + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } + taskEXIT_CRITICAL(); + } + } + + +#endif /* configUSE_ALTERNATIVE_API */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + in the queue. Also don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + if( prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ) != pdFALSE ) + { + /* This is a special case that can only be executed if a task + holds multiple mutexes and then gives the mutexes back in an + order that is different to that in which they were taken. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( pxQueue->xTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + ++( pxQueue->xTxLock ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeeking ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there data in the queue now? To be running we must be + the highest priority task wanting to access the queue. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position in case the queue is only being + peeked. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Actually removing data, not just peeking. */ + --( pxQueue->uxMessagesWaiting ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) == pdTRUE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read + pointer. */ + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + --( pxQueue->uxMessagesWaiting ); + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( pxQueue->xRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + ++( pxQueue->xRxLock ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t *pxQueue; + + pxQueue = ( Queue_t * ) xQueue; + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + + traceQUEUE_DELETE( pxQueue ); + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + if( pxQueue->pcHead != NULL ) + { + vPortFree( pxQueue->pcHead ); + } + vPortFree( pxQueue ); +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) +{ +BaseType_t xReturn = pdFALSE; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); + pxQueue->pxMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + pxQueue->u.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --( pxQueue->uxMessagesWaiting ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + ++( pxQueue->uxMessagesWaiting ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + /* See if data was added to the queue while it was locked. */ + while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --( pxQueue->xTxLock ); + } + + pxQueue->xTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --( pxQueue->xRxLock ); + } + else + { + break; + } + } + + pxQueue->xRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; + + configASSERT( xQueue ); + if( ( ( Queue_t * ) xQueue )->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; + + configASSERT( xQueue ); + if( ( ( Queue_t * ) xQueue )->uxMessagesWaiting == ( ( Queue_t * ) xQueue )->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait ) + { + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + traceQUEUE_SEND( pxQueueSetContainer ); + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + + + + + + + + + + + + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/tasks.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/tasks.c new file mode 100644 index 0000000..2fde546 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/tasks.c @@ -0,0 +1,3776 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "StackMacros.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +/* Sanity check the configuration. */ +#if configUSE_TICKLESS_IDLE != 0 + #if INCLUDE_vTaskSuspend != 1 + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Defines the size, in words, of the stack allocated to the idle task. + */ +#define tskIDLE_STACK_SIZE configMINIMAL_STACK_SIZE + +#define RTL_PLACE_IDLE_STACK_IN_SRAM +#ifdef RTL_PLACE_IDLE_STACK_IN_SRAM + + /* 20151104 User may place heap in SDRAM and cause tickless hang because SDRAM is susupend and idle stack is in SDRAM. + * Fix it by place idle stack in SRAM. + */ +#if ((defined CONFIG_PLATFORM_8195A) || (defined CONFIG_PLATFORM_8711B)) + #include "section_config.h" + SRAM_BF_DATA_SECTION +#endif + static unsigned char ucIdleTaskHeap[ tskIDLE_STACK_SIZE * sizeof( StackType_t ) ]; + +#endif + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock +{ + volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xGenericListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t *pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( portSTACK_GROWTH > 0 ) + StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + uint32_t ulStartRunTimeCounterOfPeroid; /*< Stores the amount of time the task has spent in the Running state during a peroid start. */ + uint32_t ulEndRunTimeCounterOfPeroid; /*< Stores the amount of time the task has spent in the Running state when a peroid end */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name +below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/* + * Some kernel aware debuggers require the data the debugger needs access to to + * be global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. --------------------*/ +PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ + +#if ( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ + PRIVILEGED_DATA static volatile UBaseType_t uxTasksDeleted = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ + +#endif + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +#endif + +/* Other file private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U; +PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = portMAX_DELAY; + +/* Context switches are held pending while the scheduler is suspended. Also, +interrupts must not manipulate the xStateListItem of a TCB, or any of the +lists the xStateListItem can be referenced from, if the scheduler is suspended. +If an interrupt needs to unblock a task while the scheduler is suspended then it +moves the task's event list item into the xPendingReadyList, ready for the +kernel to move the task from the pending ready list into the real ready list +when the scheduler is unsuspended. The pending ready list itself can only be +accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ + PRIVILEGED_DATA static uint32_t ulDeltaTotalRunTime = 0UL; /*< Holds the delta total amount of execution time*/ +#endif + +/*lint +e956 */ + +/* Debugging and trace facilities private variables and macros. ------------*/ + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/*-----------------------------------------------------------*/ + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopReadyPriority ] ) ) ) \ + { \ + configASSERT( uxTopReadyPriority ); \ + --uxTopReadyPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + List_t *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) ) +/*-----------------------------------------------------------*/ + +/* + * Several functions take an TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority +of the task to which it belongs (coded to allow it to be held in reverse +priority order). However, it is occasionally borrowed for other purposes. It +is important its value is not updated due to a task priority change while it is +being used for another purpose. The following bit definition is used to inform +the scheduler that the value should not be changed - in which case it is the +responsibility of whichever module is using the value to ensure it gets set back +to its original value when it is released. */ +#if configUSE_16_BIT_TICKS == 1 + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#else + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#endif + +/* Callback function prototypes. --------------------------*/ +#if configCHECK_FOR_STACK_OVERFLOW > 0 + extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); +#endif + +#if configUSE_TICK_HOOK > 0 + extern void vApplicationTickHook( void ); +#endif + +/* File private functions. --------------------------------*/ + +/* + * Utility to ready a TCB for a given task. Mainly just copies the parameters + * into the TCB structure. + */ +static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) PRIVILEGED_FUNCTION; + +/* + * Allocates memory from the heap for a TCB and associated stack. Checks the + * allocation was successful. + */ +static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + StackType_t * const puxStackBuffer, + const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +BaseType_t xReturn; +TCB_t * pxNewTCB; + + configASSERT( pxTaskCode ); + configASSERT( ( ( uxPriority & ( ~portPRIVILEGE_BIT ) ) < configMAX_PRIORITIES ) ); + + /* Allocate the memory required by the TCB and stack for the new task, + checking that the allocation was successful. */ + pxNewTCB = prvAllocateTCBAndStack( usStackDepth, puxStackBuffer ); + + if( pxNewTCB != NULL ) + { + StackType_t *pxTopOfStack; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Calculate the top of stack address. This depends on whether the + stack grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as + required by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* If we want to use stack checking on architectures that use + a positive stack growth direction then we also need to store the + other extreme of the stack space. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( usStackDepth - 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Setup the newly allocated TCB with the initial state of the task. */ + prvInitialiseTCBVariables( pxNewTCB, pcName, uxPriority, xRegions, usStackDepth ); + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the TCB out - in an anonymous way. The calling function/ + task can use this as a handle to delete the task later if + required.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Ensure interrupts don't access the task lists while they are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + xReturn = pdPASS; + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + traceTASK_CREATE_FAILED(); + } + + if( xReturn == pdPASS ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list and place in the termination list. + This will stop the task from be scheduled. The idle task will check + the termination list and free up any memory allocated by the + scheduler for the TCB and stack. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xGenericListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxTasksDeleted; + + /* Increment the uxTaskNumberVariable also so kernel aware debuggers + can detect that the task lists need re-generating. */ + uxTaskNumber++; + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if it is the currently running task that has just + been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == 0 ); + + /* The pre-delete hook is primarily for the Windows simulator, + in which Windows specific clean up operations are performed, + after which it is not possible to yield away from this task - + hence xYieldPending is used to latch that a context switch is + required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + portYIELD_WITHIN_API(); + } + else + { + /* Reset the next expected unblock time in case it referred to + the task that has just been deleted. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL(); + + /* Remove the task from the ready list before adding it to the + blocked list as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is + no need to check, and the port reset macro can be called + directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded = pdFALSE; + + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == 0 ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is + no need to check, and the port reset macro can be called + directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t *pxStateList; + const TCB_t * const pxTCB = ( TCB_t * ) xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = ( List_t * ) listLIST_ITEM_CONTAINER( &( pxTCB->xGenericListItem ) ); + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. Is it genuinely suspended or is it block + indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + eReturn = eSuspended; + } + else + { + eReturn = eBlocked; + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( pxStateList == &xTasksWaitingTermination ) + { + /* The task being queried is referenced from the deleted + tasks list. */ + eReturn = eDeleted; + } + #endif + + else + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then we are changing the + priority of the calling function. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) + { + TCB_t *pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired == pdTRUE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + suspended list. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ); + } + taskEXIT_CRITICAL(); + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + if( xSchedulerRunning != pdFALSE ) + { + /* A task other than the currently running task was suspended, + reset the next expected unblock time in case it referred to the + task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = ( TCB_t * ) xTask; + + /* Accesses xPendingReadyList so must be called from a critical + section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + but will leave the lists in the correct state for the + next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Ready lists can be accessed so move the task from the + suspended list to the ready list directly. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + is held in the pending ready list until the scheduler is + unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ +BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + { +#ifdef RTL_PLACE_IDLE_STACK_IN_SRAM + // it's same function call as original FreeRTOS source except that it use stack in SRAM + xReturn = xTaskGenericCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle, (void *)&ucIdleTaskHeap, NULL); +#else + /* Create the idle task, storing its handle in xIdleTaskHandle so it can + be returned by the xTaskGetIdleTaskHandle() function. */ + xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ +#endif + } + #else + { +#ifdef RTL_PLACE_IDLE_STACK_IN_SRAM + // it's same function call as original FreeRTOS source except that it use stack in SRAM + xReturn = xTaskGenericCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL, (void *)&ucIdleTaskHeap, NULL ); +#else + /* Create the idle task without storing its handle. */ + xReturn = xTaskCreate( prvIdleTask, "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), NULL ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ +#endif + } + #endif /* INCLUDE_xTaskGetIdleTaskHandle */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to the task that will run first. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) 0U; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn ); + } +} +/*-----------------------------------------------------------*/ + +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + BaseType_t. Please read Richard Barry's reply in the following link to a + post in the FreeRTOS support forum before reporting this as a bug! - + http://goo.gl/wu4acr */ + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ +TCB_t *pxTCB; +BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If we have moved a task that has a priority higher than + the current task then we should yield. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does + not slip, and that any delayed tasks are resumed at the correct + time. */ + if( uxPendedTicks > ( UBaseType_t ) 0U ) + { + while( uxPendedTicks > ( UBaseType_t ) 0U ) + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedTicks; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldPending == pdTRUE ) + { + #if( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ +TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ +// taskENTER_CRITICAL(); + { + xTicks = xTickCount; + } +// taskEXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ +TickType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_pcTaskGetTaskName == 1 ) + + char *pcTaskGetTaskName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + TCB_t *pxTCB; + + /* If null is passed in here then the name of the calling task is being queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); + } + +#endif /* INCLUDE_pcTaskGetTaskName */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + ulDeltaTotalRunTime = 0; +#endif + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + task in the Blocked state. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task in the Suspended state. */ + uxTask += prvListTaskWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( const TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) + static void prvGenerateRunTimeOfPeroid(xList *pxList, portTickType tickTmp) + { + volatile tskTCB *pxNextTCB, *pxFirstTCB; + + /* Write the run time stats of all the TCB's in pxList into the buffer. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + /* Get next TCB in from the list. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + /* Record start&end run time counter. */ + if (tickTmp%(2*portCONFIGURE_STATS_PEROID_VALUE)) + pxNextTCB->ulStartRunTimeCounterOfPeroid = pxNextTCB->ulRunTimeCounter; + else + pxNextTCB->ulEndRunTimeCounterOfPeroid = pxNextTCB->ulRunTimeCounter; + + } while( pxNextTCB != pxFirstTCB ); + } + + static void prvGetRunTimeStatsOfPeroidForTasksInList(portTickType tickTmp) + { + unsigned portBASE_TYPE uxQueue; + + if (tickTmp%portCONFIGURE_STATS_PEROID_VALUE){ + return;//only portCONFIGURE_STATS_PEROID_VALUE + } + + uxQueue = configMAX_PRIORITIES; + + do + { + uxQueue--; + + if( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxQueue ] ) ) == pdFALSE ) + { + prvGenerateRunTimeOfPeroid(( xList * ) &( pxReadyTasksLists[ uxQueue ] ), tickTmp ); + } + }while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeOfPeroid(( xList * ) pxDelayedTaskList, tickTmp ); + } + + if( listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeOfPeroid(( xList * ) pxOverflowDelayedTaskList, tickTmp ); + } + +#if ( INCLUDE_vTaskDelete == 1 ) + { + if( listLIST_IS_EMPTY( &xTasksWaitingTermination ) == pdFALSE ) + { + prvGenerateRunTimeOfPeroid(&xTasksWaitingTermination, tickTmp ); + } + } +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + { + if( listLIST_IS_EMPTY( &xSuspendedTaskList ) == pdFALSE ) + { + prvGenerateRunTimeOfPeroid(&xSuspendedTaskList, tickTmp ); + } + } +#endif + } +#endif + +BaseType_t xTaskIncrementTick( void ) +{ +TCB_t * pxTCB; +TickType_t xItemValue; +BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + ++xTickCount; + + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + the queue in the order of their wake time - meaning once one task + has been found whose block time has not expired there is no need to + look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + to the maximum possible value so it is extremely + unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; + break; + } + else + { + /* The delayed list is not empty, get the value of the + item at the head of the delayed list. This is the time + at which the task at the head of the delayed list must + be removed from the Blocked state. */ + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + item value is the time at which the task at the head + of the blocked list must be removed from the Blocked + state - so record the item value in + xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + + /* Is the task waiting on an event also? If so remove + it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + only be performed if the unblocked task has a + priority that is equal to or higher than the + currently executing task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( UBaseType_t ) 0U ) + { + vApplicationTickHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + vApplicationTickHook(); + } + #endif + } + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + prvGetRunTimeStatsOfPeroidForTasksInList(xTickCount); + #endif + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + { + TCB_t *xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + xTCB->pxTaskTag = pxHookFunction; + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t *xTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = xTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + TCB_t *xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskFIRST_CHECK_FOR_STACK_OVERFLOW(); + taskSECOND_CHECK_FOR_STACK_OVERFLOW(); + + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); + traceTASK_SWITCHED_IN(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) +{ +TickType_t xTimeToWake; + + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. The queue that contains the event + list is locked, preventing simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* The task must be removed from from the ready list before it is added to + the blocked list as the same list item is used for both lists. Exclusive + access to the ready lists guaranteed because the scheduler is locked. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure the task is not woken by a timing event. It will + block indefinitely. */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + scheduler will handle it. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter, the scheduler + will handle it. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + #endif /* INCLUDE_vTaskSuspend */ +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) +{ +TickType_t xTimeToWake; + + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event groups implementation. */ + configASSERT( uxSchedulerSuspended != 0 ); + + /* Store the item value in the event list item. It is safe to access the + event list item here as interrupts won't access the event list item of a + task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + list. It is safe to access the event list here because it is part of an + event group implementation - and interrupts don't access event groups + directly (instead they access them indirectly by pending function calls to + the task level). */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* The task must be removed from the ready list before it is added to the + blocked list. Exclusive access can be assured to the ready list as the + scheduler is locked. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( xTicksToWait == portMAX_DELAY ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure it is not woken by a timing event. It will block + indefinitely. */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + kernel will manage it correctly. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter, the kernel + will manage it correctly. */ + xTimeToWake = xTickCount + xTicksToWait; + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + #endif /* INCLUDE_vTaskSuspend */ +} +/*-----------------------------------------------------------*/ + +#if configUSE_TIMERS == 1 + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, const TickType_t xTicksToWait ) + { + TickType_t xTimeToWake; + + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called from a critical section. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* We must remove this task from the ready list before adding it to the + blocked list as the same list item is used for both lists. This + function is called form a critical section. */ + if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Calculate the time at which the task should be woken if the event does + not occur. This may overflow but this doesn't matter. */ + xTimeToWake = xTickCount + xTicksToWait; + + traceTASK_DELAY_UNTIL(); + prvAddCurrentTaskToDelayedList( xTimeToWake ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + be removed as it is known to be the highest priority. Remove the TCB from + the delayed list, and add it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means exclusive access to the event list is guaranteed here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event flags implementation. */ + configASSERT( uxSchedulerSuspended != pdFALSE ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + event flags. */ + pxUnblockedTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxEventListItem ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( pxEventListItem ); + + /* Remove the task from the delayed list and add it to the ready list. The + scheduler is suspended so interrupts will not be accessing the ready + lists. */ + ( void ) uxListRemove( &( pxUnblockedTCB->xGenericListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + + #if ( INCLUDE_vTaskSuspend == 1 ) + /* If INCLUDE_vTaskSuspend is set to 1 and the block time specified is + the maximum block time then the task should block indefinitely, and + therefore never time out. */ + if( *pxTicksToWait == portMAX_DELAY ) + { + xReturn = pdFALSE; + } + else /* We are not blocking indefinitely, perform the checks below. */ + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which vTaskSetTimeout() + was called, but has also overflowed since vTaskSetTimeOut() was called. + It must have wrapped all the way around and gone past us again. This + passed since vTaskSetTimeout() was called. */ + xReturn = pdTRUE; + } + else if( ( xConstTickCount - pxTimeOut->xTimeOnEntering ) < *pxTicksToWait ) + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering ); + vTaskSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( TCB_t * ) xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) + { + TCB_t *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( TCB_t * ) xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* See if any tasks have been deleted. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + extern void vApplicationIdleHook( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE != 0 + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + #if configUSE_TIMERS == 0 + { + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + + /* If timers are not being used and all the tasks are in the + suspended list (which might mean they have an infinite block + time rather than actually being suspended) then it is safe to + turn all clocks off and just wait for external interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + } + + return eReturn; + } +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +UBaseType_t x; + + /* Store the task name in the TCB. */ + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxTCB->uxBasePriority = uxPriority; + pxTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxTCB->xGenericListItem ) ); + vListInitialiseItem( &( pxTCB->xEventListItem ) ); + + /* Set the pxTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xGenericListItem ), pxTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxTCB->xEventListItem ), pxTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTCB->ulRunTimeCounter = 0UL; + pxTCB->ulStartRunTimeCounterOfPeroid = 0UL; + pxTCB->ulEndRunTimeCounterOfPeroid = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, pxTCB->pxStack, usStackDepth ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + ( void ) xRegions; + ( void ) usStackDepth; + } + #endif /* portUSING_MPU_WRAPPERS */ + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ +} +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) + { + TCB_t *pxTCB; + + /* If null is passed in here then we are deleting ourselves. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + #if ( INCLUDE_vTaskDelete == 1 ) + { + BaseType_t xListIsEmpty; + + /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called + too often in the idle task. */ + while( uxTasksDeleted > ( UBaseType_t ) 0U ) + { + vTaskSuspendAll(); + { + xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); + } + ( void ) xTaskResumeAll(); + + if( xListIsEmpty == pdFALSE ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); + ( void ) uxListRemove( &( pxTCB->xGenericListItem ) ); + --uxCurrentNumberOfTasks; + --uxTasksDeleted; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #endif /* vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) +{ + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xGenericListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ +static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) +{ +TCB_t *pxNewTCB; + + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ +#if configUSE_STACK_TCM_HEAP + if(puxStackBuffer == NULL) { + pxNewTCB->pxStack = ( StackType_t * ) tcm_heap_malloc((( size_t ) usStackDepth) * sizeof(StackType_t)); + if(pxNewTCB->pxStack == NULL) pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc((( size_t ) usStackDepth) * sizeof(StackType_t)); + } + else pxNewTCB->pxStack = puxStackBuffer; +#else + pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocAligned( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ), puxStackBuffer ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ +#endif + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + else + { + /* Avoid dependency on memset() if it is not required. */ + #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + { + /* Just to help debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) usStackDepth * sizeof( StackType_t ) ); + } + #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */ + } + } + + return pxNewTCB; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) + { + volatile TCB_t *pxNextTCB, *pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + + /* Populate an TaskStatus_t structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of TaskStatus_t in task.h for the + meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + pxTaskStatusArray[ uxTask ].xHandle = ( TaskHandle_t ) pxNextTCB; + pxTaskStatusArray[ uxTask ].pcTaskName = ( const char * ) &( pxNextTCB->pcTaskName [ 0 ] ); + pxTaskStatusArray[ uxTask ].xTaskNumber = pxNextTCB->uxTCBNumber; + pxTaskStatusArray[ uxTask ].eCurrentState = eState; + pxTaskStatusArray[ uxTask ].uxCurrentPriority = pxNextTCB->uxPriority; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a chance + it is actually just blocked indefinitely - so really it should + be reported as being in the Blocked state. */ + if( eState == eSuspended ) + { + if( listLIST_ITEM_CONTAINER( &( pxNextTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatusArray[ uxTask ].eCurrentState = eBlocked; + } + } + } + #endif /* INCLUDE_vTaskSuspend */ + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatusArray[ uxTask ].uxBasePriority = pxNextTCB->uxBasePriority; + } + #else + { + pxTaskStatusArray[ uxTask ].uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatusArray[ uxTask ].ulRunTimeCounter = pxNextTCB->ulRunTimeCounter; + if (pxNextTCB->ulEndRunTimeCounterOfPeroid > pxNextTCB->ulStartRunTimeCounterOfPeroid) + pxTaskStatusArray[ uxTask ].ulDelataRunTimeCounterOfPeroid = pxNextTCB->ulEndRunTimeCounterOfPeroid - pxNextTCB->ulStartRunTimeCounterOfPeroid; + else + pxTaskStatusArray[ uxTask ].ulDelataRunTimeCounterOfPeroid = pxNextTCB->ulStartRunTimeCounterOfPeroid - pxNextTCB->ulEndRunTimeCounterOfPeroid; + ulDeltaTotalRunTime += pxTaskStatusArray[ uxTask ].ulDelataRunTimeCounterOfPeroid; + } + #else + { + pxTaskStatusArray[ uxTask ].ulRunTimeCounter = 0; + } + #endif + + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxEndOfStack ); + } + #else + { + pxTaskStatusArray[ uxTask ].usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxNextTCB->pxStack ); + } + #endif + + uxTask++; + + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( uint16_t ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up + to the task to free any memory allocated at the application level. */ + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + vPortFreeAligned( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ +TCB_t *pxTCB; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set + xNextTaskUnblockTime to the maximum possible value so it is + extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + ( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xGenericListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. */ + if( pxMutexHolder != NULL ) + { + if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + priority. Only reset the event list item value if the value is + not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need to + be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* Just inherit the priority. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* The holding task must be the running task to be able to give + the mutex back. Remove the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the new + ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + any other purpose if this task is running, and it must be + running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + prvAddTaskToReadyList( pxTCB ); + + /* Return true to indicate that a context switch is required. + This is only actually required in the corner case whereby + multiple mutexes were held and the mutexes were given back + in an order different to that in which they were taken. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + function so assert() if it is being called from an interrupt + context. Only API functions that end in "FromISR" can be used in an + interrupt. Only assert if the critical nesting count is 1 to + protect against recursive calls if the assert function also uses a + critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ +char * sprintf_pcTaskName(char * buf, char * name) +{ + int len = sprintf(buf, name); + if(len < configMAX_TASK_NAME_LEN) { + memset(buf + len, ' ', configMAX_TASK_NAME_LEN - len); + } + return buf + configMAX_TASK_NAME_LEN; +} + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) + + void vTaskList( char * pcWriteBuffer ) + { + TaskStatus_t *pxTaskStatusArray; + volatile UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = 0x00; + break; + } + pcWriteBuffer = sprintf_pcTaskName( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName); + + sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( pcWriteBuffer ); + } + + /* Free the array again. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) + + void vTaskGetRunTimeStats( char *pcWriteBuffer ) + { + TaskStatus_t *pxTaskStatusArray; + volatile UBaseType_t uxArraySize, x; + uint32_t ulTotalTime, ulStatsAsPercentage, ulDeltaRunTimeCounter; + + #if( configUSE_TRACE_FACILITY != 1 ) + { + #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). + } + #endif + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + printf("CPU total run time is %u\n", ulTotalTime); + printf("TaskName\tDeltaRunTime\tpercentage\n"); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0 ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ +#if 1 + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; +#else + ulStatsAsPercentage = (100*pxTaskStatusArray[ x ].ulDelataRunTimeCounterOfPeroid) / ulDeltaTotalRunTime; + /* just make run time counter looks like more precise*/ + if (100*(100*pxTaskStatusArray[ x ].ulDelataRunTimeCounterOfPeroid) % ulDeltaTotalRunTime >=50) + ulDeltaRunTimeCounter = portCONFIGURE_STATS_PEROID_VALUE*(ulStatsAsPercentage+1)/100; + else + ulDeltaRunTimeCounter = portCONFIGURE_STATS_PEROID_VALUE*ulStatsAsPercentage/100; +#endif + pcWriteBuffer = sprintf_pcTaskName( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName); + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { +#if 1 + sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); +#else + sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\n", ulDeltaRunTimeCounter, ulStatsAsPercentage ); +#endif + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 1 + sprintf( pcWriteBuffer, "\t%lu\t\t%u%%\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); +#else + sprintf( pcWriteBuffer, "\t%u\t\t%u%%\n", ( unsigned int ) ulDeltaRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); +#endif + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { +#if 1 + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); +#else + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\n", ulDeltaRunTimeCounter ); +#endif + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 1 + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); +#else + sprintf( pcWriteBuffer, "\t%u\t\t<1%%\n", ( unsigned int ) ulDeltaRunTimeCounter ); +#endif + } + #endif + } + + pcWriteBuffer += strlen( pcWriteBuffer ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ +TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void *pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ + +/*-----------------------------------------------------------*/ +void * vTaskGetCurrentTCB( void ) +{ + return (void*)pxCurrentTCB; +} + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + diff --git a/USDK/component/os/freertos/freertos_v8.1.2/Source/timers.c b/USDK/component/os/freertos/freertos_v8.1.2/Source/timers.c new file mode 100644 index 0000000..4744d60 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v8.1.2/Source/timers.c @@ -0,0 +1,936 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( TickType_t ) 0U + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl +{ + const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ + UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif +} xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t +name below to enable the use of older kernel aware debuggers. */ +typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. +Two types of message can be queued - messages that manipulate a software timer, +and messages that request the execution of a non-timer related callback. The +two message types are defined in two separate structures, xTimerParametersType +and xCallbackParametersType respectively. */ +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier +that is used to determine which message type is valid. */ +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access these lists. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; +PRIVILEGED_DATA static List_t *pxCurrentTimerList; +PRIVILEGED_DATA static List_t *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; + +// Added by Realtek to prevent timer thread blocked +#ifdef INCLUDE_xTimerGetTimerDaemonTaskHandle +#undef INCLUDE_xTimerGetTimerDaemonTaskHandle +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#endif + +#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + + PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +#endif + +/*lint +e956 */ + +/*-----------------------------------------------------------*/ + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +BaseType_t xTimerCreateTimerTask( void ) +{ +BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + { + /* Create the timer task, storing its handle in xTimerTaskHandle so + it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */ + xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, (( ( UBaseType_t ) configTIMER_TASK_PRIORITY + PRIORITIE_OFFSET) | portPRIVILEGE_BIT), &xTimerTaskHandle ); + } + #else + { + /* Create the timer task without storing its handle. */ + xReturn = xTaskCreate( prvTimerTask, "Tmr Svc", ( uint16_t ) configTIMER_TASK_STACK_DEPTH, NULL, (( ( UBaseType_t ) configTIMER_TASK_PRIORITY + PRIORITIE_OFFSET) | portPRIVILEGE_BIT ), NULL); + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +Timer_t *pxNewTimer; + + /* Allocate the timer structure. */ + if( xTimerPeriodInTicks == ( TickType_t ) 0U ) + { + pxNewTimer = NULL; + } + else + { + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->uxAutoReload = uxAutoReload; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + + traceTIMER_CREATE( pxNewTimer ); + } + else + { + traceTIMER_CREATE_FAILED(); + } + } + + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + return ( TimerHandle_t ) pxNewTimer; +} +/*-----------------------------------------------------------*/ +extern void * vTaskGetCurrentTCB( void ); +static void prvProcessCommands( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue ); + +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) +{ +BaseType_t xReturn = pdFAIL; +DaemonTaskMessage_t xMessage; + + // Added by Realtek to prevent timer thread blocked + if( ( vTaskGetCurrentTCB() == ( void * ) xTimerTaskHandle ) && ( ( xCommandID == tmrCOMMAND_STOP ) || ( xCommandID == tmrCOMMAND_CHANGE_PERIOD ) || ( xCommandID == tmrCOMMAND_DELETE ) ) ) + { + prvProcessCommands( xTimer, xCommandID, xOptionalValue ); + return pdPASS; + } + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 ) + + TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) + { + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; + } + +#endif +/*-----------------------------------------------------------*/ + +const char * pcTimerGetTimerName( TimerHandle_t xTimer ) +{ +Timer_t *pxTimer = ( Timer_t * ) xTimer; + + return pxTimer->pcTimerName; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) +{ +BaseType_t xResult; +Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + /* The timer is inserted into a list using a time relative to anything + other than the current time. It will therefore be inserted into the + correct list relative to the time this task thinks it is now. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static void prvTimerTask( void *pvParameters ) +{ +TickType_t xNextExpireTime; +BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, const BaseType_t xListWasEmpty ) +{ +TickType_t xTimeNow; +BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the block time + to expire. If a command arrived between the critical section being + exited and this yield then the yield will not cause the task + to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) +{ +TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) +{ +TickType_t xTimeNow; +PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) +{ +BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( xTimeNow - xCommandTime ) >= pxTimer->xTimerPeriodInTicks ) + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +DaemonTaskMessage_t xMessage; +Timer_t *pxTimer; +BaseType_t xTimerListsWereSwitched, xResult; +TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + case tmrCOMMAND_START_FROM_ISR : + case tmrCOMMAND_RESET : + case tmrCOMMAND_RESET_FROM_ISR : + case tmrCOMMAND_START_DONT_TRACE : + /* Start or restart a timer. */ + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) == pdTRUE ) + { + /* The timer expired before it was added to the active + timer list. Process it now. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + traceTIMER_EXPIRED( pxTimer ); + + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + break; + + case tmrCOMMAND_STOP : + case tmrCOMMAND_STOP_FROM_ISR : + /* The timer has already been removed from the active list. + There is nothing to do here. */ + break; + + case tmrCOMMAND_CHANGE_PERIOD : + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can be + longer or shorter than the old one. The command time is + therefore set to the current time, and as the period cannot be + zero the next expiry time can only be in the future, meaning + (unlike for the xTimerStart() case above) there is no fail case + that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + /* The timer has already been removed from the active list, + just free up the memory. */ + vPortFree( pxTimer ); + break; + + default : + /* Don't expect to get here. */ + break; + } + } + } +} + +// Added by Realtek to prevent timer thread blocked +static void prvProcessCommands( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue ) +{ +Timer_t *pxTimer = ( Timer_t * ) xTimer; +TickType_t xTimeNow = xTaskGetTickCount();; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + + switch( xCommandID ) + { + case tmrCOMMAND_STOP : + /* The timer has already been removed from the active list. + There is nothing to do here. */ + break; + + case tmrCOMMAND_CHANGE_PERIOD : + pxTimer->xTimerPeriodInTicks = xOptionalValue; + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + /* The timer has already been removed from the active list, + just free up the memory. */ + vPortFree( pxTimer ); + break; + + default : + /* Don't expect to get here. */ + break; + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( void ) +{ +TickType_t xNextExpireTime, xReloadTime; +List_t *pxTemp; +Timer_t *pxTimer; +BaseType_t xResult; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + configASSERT( xTimerQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) +{ +BaseType_t xTimerIsInActiveList; +Timer_t *pxTimer = ( Timer_t * ) xTimer; + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + /* Checking to see if it is in the NULL list in effect checks to see if + it is referenced from either the current or the overflow timer lists in + one go, but the logic has to be reversed, hence the '!'. */ + xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); + } + taskEXIT_CRITICAL(); + + return xTimerIsInActiveList; +} /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) +{ +Timer_t * const pxTimer = ( Timer_t * ) xTimer; + + return pxTimer->pvTimerID; +} +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/BlockQ.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/BlockQ.c new file mode 100644 index 0000000..d008659 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/BlockQ.c @@ -0,0 +1,350 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + * \page BlockQC blockQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + Reversed the priority and block times of the second two demo tasks so + they operate as per the description above. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V4.0.2 + + + The second set of tasks were created the wrong way around. This has been + corrected. +*/ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" +#include "print.h" + +#define blckqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) +#define blckqNUM_TASK_SETS ( 3 ) + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + QueueHandle_t xQueue; /*< The queue to be used by the task. */ + TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static void vBlockingQueueProducer( void *pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static void vBlockingQueueConsumer( void *pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; +const TickType_t xBlockTime = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +const TickType_t xDontBlock = ( TickType_t ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueProducer( void *pvParameters ) +{ +unsigned short usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const char * const pcTaskStartMsg = "Blocking queue producer started.\r\n"; +const char * const pcTaskErrorMsg = "Could not post on blocking queue\r\n"; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xQueueSendToBack( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + } + } +} +/*-----------------------------------------------------------*/ + +static void vBlockingQueueConsumer( void *pvParameters ) +{ +unsigned short usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +const char * const pcTaskStartMsg = "Blocking queue consumer started.\r\n"; +const char * const pcTaskErrorMsg = "Incorrect value received on blocking queue.\r\n"; +short sErrorEverOccurred = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + vPrintDisplayMessage( &pcTaskErrorMsg ); + + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreBlockingQueuesStillRunning( void ) +{ +static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; +static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( short ) 0, ( short ) 0, ( short ) 0 }; +portBASE_TYPE xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/PollQ.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/PollQ.c new file mode 100644 index 0000000..f8dd268 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/PollQ.c @@ -0,0 +1,262 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/** + * This is a very simple queue test. See the BlockQ. c documentation for a more + * comprehensive version. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + * + * \page PollQC pollQ.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "print.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) + +/* The task that posts the incrementing number onto the queue. */ +static void vPolledQueueProducer( void *pvParameters ); + +/* The task that empties the queue. */ +static void vPolledQueueConsumer( void *pvParameters ); + +/* Variables that are used to check that the tasks are still running with no errors. */ +static volatile short sPollingConsumerCount = 0, sPollingProducerCount = 0; +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( unsigned portBASE_TYPE uxPriority ) +{ +static QueueHandle_t xPolledQueue; +const unsigned portBASE_TYPE uxQueueSize = 10; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( unsigned short ) ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueProducer( void *pvParameters ) +{ +unsigned short usValue = 0, usLoop; +QueueHandle_t *pxQueue; +const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS; +const unsigned short usNumToProduce = 3; +const char * const pcTaskStartMsg = "Polled queue producer started.\r\n"; +const char * const pcTaskErrorMsg = "Could not post on polled queue.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( QueueHandle_t * ) pvParameters; + + for( ;; ) + { + for( usLoop = 0; usLoop < usNumToProduce; ++usLoop ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSendToBack( *pxQueue, ( void * ) &usValue, ( TickType_t ) 0 ) != pdPASS ) + { + /* We should never find the queue full - this is an error. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + } + else + { + if( sError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + ++sPollingProducerCount; + } + + /* Update the value we are going to post next time around. */ + ++usValue; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +static void vPolledQueueConsumer( void *pvParameters ) +{ +unsigned short usData, usExpectedValue = 0; +QueueHandle_t *pxQueue; +const TickType_t xDelay = ( TickType_t ) 200 / portTICK_PERIOD_MS; +const char * const pcTaskStartMsg = "Polled queue consumer started.\r\n"; +const char * const pcTaskErrorMsg = "Incorrect value received on polled queue.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The queue being used is passed in as the parameter. */ + pxQueue = ( QueueHandle_t * ) pvParameters; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *pxQueue ) ) + { + if( xQueueReceive( *pxQueue, &usData, ( TickType_t ) 0 ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sError = pdTRUE; + /* Catch-up to the value we received so our next expected value + should again be correct. */ + usExpectedValue = usData; + } + else + { + if( sError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + ++sPollingConsumerCount; + } + } + ++usExpectedValue; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( xDelay ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +portBASE_TYPE xArePollingQueuesStillRunning( void ) +{ +static short sLastPollingConsumerCount = 0, sLastPollingProducerCount = 0; +portBASE_TYPE xReturn; + + if( ( sLastPollingConsumerCount == sPollingConsumerCount ) || + ( sLastPollingProducerCount == sPollingProducerCount ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastPollingConsumerCount = sPollingConsumerCount; + sLastPollingProducerCount = sPollingProducerCount; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/comtest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/comtest.c new file mode 100644 index 0000000..47f9bdf --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/comtest.c @@ -0,0 +1,388 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates two tasks that operate on an interrupt driven serial port. A loopback + * connector should be used so that everything that is transmitted is also received. + * The serial port does not use any flow control. On a standard 9way 'D' connector + * pins two and three should be connected together. + * + * The first task repeatedly sends a string to a queue, character at a time. The + * serial port interrupt will empty the queue and transmit the characters. The + * task blocks for a pseudo random period before resending the string. + * + * The second task blocks on a queue waiting for a character to be received. + * Characters received by the serial port interrupt routine are posted onto the + * queue - unblocking the task making it ready to execute. If this is then the + * highest priority task ready to run it will run immediately - with a context + * switch occurring at the end of the interrupt service routine. The task + * receiving characters is spawned with a higher priority than the task + * transmitting the characters. + * + * With the loop back connector in place, one task will transmit a string and the + * other will immediately receive it. The receiving task knows the string it + * expects to receive so can detect an error. + * + * This also creates a third task. This is used to test semaphore usage from an + * ISR and does nothing interesting. + * + * \page ComTestC comtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.00: + + + The priority of the Rx task has been lowered. Received characters are + now processed (read from the queue) at the idle priority, allowing low + priority tasks to run evenly at times of a high communications overhead. + +Changes from V1.01: + + + The Tx task now waits a pseudo random time between transissions. + Previously a fixed period was used but this was not such a good test as + interrupts fired at regular intervals. + +Changes From V1.2.0: + + + Use vSerialPutString() instead of single character puts. + + Only stop the check variable incrementing after two consecutive errors. + +Changed from V1.2.5 + + + Made the Rx task 2 priorities higher than the Tx task. Previously it was + only 1. This is done to tie in better with the other demo application + tasks. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + + Slight modification to task priorities. + +*/ + + +/* Scheduler include files. */ +#include +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "print.h" + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x15e ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0xc8 ) + +#define comMAX_CONSECUTIVE_ERRORS ( 2 ) + +#define comSTACK_SIZE ( ( unsigned short ) 256 ) + +#define comRX_RELATIVE_PRIORITY ( 1 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort; + +/* The transmit function as described at the top of the file. */ +static void vComTxTask( void *pvParameters ); + +/* The receive function as described at the top of the file. */ +static void vComRxTask( void *pvParameters ); + +/* The semaphore test function as described at the top of the file. */ +static void vSemTestTask( void * pvParameters ); + +/* The string that is repeatedly transmitted. */ +const char * const pcMessageToExchange = "Send this message over and over again to check communications interrupts. " + "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n"; + +/* Variables that are incremented on each cycle of each task. These are used to +check that both tasks are still executing. */ +volatile short sTxCount = 0, sRxCount = 0, sSemCount = 0; + +/* The handle to the semaphore test task. */ +static TaskHandle_t xSemTestTaskHandle = NULL; + +/*-----------------------------------------------------------*/ + +void vStartComTestTasks( unsigned portBASE_TYPE uxPriority, eCOMPort ePort, eBaud eBaudRate ) +{ +const unsigned portBASE_TYPE uxBufferLength = 255; + + /* Initialise the com port then spawn both tasks. */ + xPort = xSerialPortInit( ePort, eBaudRate, serNO_PARITY, serBITS_8, serSTOP_1, uxBufferLength ); + xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority, NULL ); + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority + comRX_RELATIVE_PRIORITY, NULL ); + xTaskCreate( vSemTestTask, "ISRSem", comSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xSemTestTaskHandle ); +} +/*-----------------------------------------------------------*/ + +static void vComTxTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "COM Tx task started.\r\n"; +TickType_t xTimeToWait; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Send the string to the serial port. */ + vSerialPutString( xPort, pcMessageToExchange, strlen( pcMessageToExchange ) ); + + /* We have posted all the characters in the string - increment the variable + used to check that this task is still running, then wait before re-sending + the string. */ + sTxCount++; + + xTimeToWait = xTaskGetTickCount(); + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vComRxTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "COM Rx task started.\r\n"; +const char * const pcTaskErrorMsg = "COM read error\r\n"; +const char * const pcTaskRestartMsg = "COM resynced\r\n"; +const char * const pcTaskTimeoutMsg = "COM Rx timed out\r\n"; +const TickType_t xBlockTime = ( TickType_t ) 0xffff / portTICK_PERIOD_MS; +const char *pcExpectedChar; +portBASE_TYPE xGotChar; +char cRxedChar; +short sResyncRequired, sConsecutiveErrors, sLatchedError; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The first expected character is the first character in the string. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + sConsecutiveErrors = 0; + sLatchedError = pdFALSE; + + for( ;; ) + { + /* Receive a message from the com port interrupt routine. If a message is + not yet available the call will block the task. */ + xGotChar = xSerialGetChar( xPort, &cRxedChar, xBlockTime ); + if( xGotChar == pdTRUE ) + { + if( sResyncRequired == pdTRUE ) + { + /* We got out of sequence and are waiting for the start of the next + transmission of the string. */ + if( cRxedChar == '\n' ) + { + /* This is the end of the message so we can start again - with + the first character in the string being the next thing we expect + to receive. */ + pcExpectedChar = pcMessageToExchange; + sResyncRequired = pdFALSE; + + /* Queue a message for printing to say that we are going to try + again. */ + vPrintDisplayMessage( &pcTaskRestartMsg ); + + /* Stop incrementing the check variable, if consecutive errors occur. */ + sConsecutiveErrors++; + if( sConsecutiveErrors >= comMAX_CONSECUTIVE_ERRORS ) + { + sLatchedError = pdTRUE; + } + } + } + else + { + /* We have received a character, but is it the expected character? */ + if( cRxedChar != *pcExpectedChar ) + { + /* This was not the expected character so post a message for + printing to say that an error has occurred. We will then wait + to resynchronise. */ + vPrintDisplayMessage( &pcTaskErrorMsg ); + sResyncRequired = pdTRUE; + } + else + { + /* This was the expected character so next time we will expect + the next character in the string. Wrap back to the beginning + of the string when the null terminator has been reached. */ + pcExpectedChar++; + if( *pcExpectedChar == '\0' ) + { + pcExpectedChar = pcMessageToExchange; + + /* We have got through the entire string without error. */ + sConsecutiveErrors = 0; + } + } + } + + /* Increment the count that is used to check that this task is still + running. This is only done if an error has never occurred. */ + if( sLatchedError == pdFALSE ) + { + sRxCount++; + } + } + else + { + vPrintDisplayMessage( &pcTaskTimeoutMsg ); + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static void vSemTestTask( void * pvParameters ) +{ +const char * const pcTaskStartMsg = "ISR Semaphore test started.\r\n"; +portBASE_TYPE xError = pdFALSE; + + /* Stop warnings. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + if( xSerialWaitForSemaphore( xPort ) ) + { + if( xError == pdFALSE ) + { + sSemCount++; + } + } + else + { + xError = pdTRUE; + } + } +} /*lint !e715 !e830 !e818 pvParameters not used but function prototype must be standard for task function. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreComTestTasksStillRunning( void ) +{ +static short sLastTxCount = 0, sLastRxCount = 0, sLastSemCount = 0; +portBASE_TYPE xReturn; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. */ + + if( ( sTxCount == sLastTxCount ) || ( sRxCount == sLastRxCount ) || ( sSemCount == sLastSemCount ) ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + sLastTxCount = sTxCount; + sLastRxCount = sRxCount; + sLastSemCount = sSemCount; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vComTestUnsuspendTask( void ) +{ + /* The task that is suspended on the semaphore will be referenced from the + Suspended list as it is blocking indefinitely. This call just checks that + the kernel correctly detects this and does not attempt to unsuspend the + task. */ + xTaskResumeFromISR( xSemTestTaskHandle ); +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/death.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/death.c new file mode 100644 index 0000000..f1324aa --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/death.c @@ -0,0 +1,245 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * four tasks. The original task is called the creator task, the four tasks it + * creates are called suicidal tasks. + * + * Two of the created suicidal tasks kill one other suicidal task before killing + * themselves - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" +#include "print.h" + +#define deathSTACK_SIZE ( ( unsigned short ) 512 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static void vCreateTasks( void *pvParameters ); + +/* The task function of the dynamically created tasks. */ +static void vSuicidalTask( void *pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile short sCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. */ +static volatile unsigned portBASE_TYPE uxTasksRunningAtStart = 0; +static const unsigned portBASE_TYPE uxMaxNumberOfExtraTasksRunning = 5; + +/* Used to store a handle to the tasks that should be killed by a suicidal task, +before it kills itself. */ +TaskHandle_t xCreatedTask1, xCreatedTask2; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE *puxPriority; + + /* Create the Creator tasks - passing in as a parameter the priority at which + the suicidal tasks should be created. */ + puxPriority = ( unsigned portBASE_TYPE * ) pvPortMalloc( sizeof( unsigned portBASE_TYPE ) ); + *puxPriority = uxPriority; + + xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) puxPriority, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = uxTaskGetNumberOfTasks(); +} +/*-----------------------------------------------------------*/ + +static void vSuicidalTask( void *pvParameters ) +{ +portDOUBLE d1, d2; +TaskHandle_t xTaskToKill; +const TickType_t xDelay = ( TickType_t ) 500 / portTICK_PERIOD_MS; + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Tow created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( TaskHandle_t* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + d1 = 2.4; + d2 = 89.2; + d2 *= d1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( TickType_t ) 0 ); + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static void vCreateTasks( void *pvParameters ) +{ +const TickType_t xDelay = ( TickType_t ) 1000 / portTICK_PERIOD_MS; +unsigned portBASE_TYPE uxPriority; +const char * const pcTaskStartMsg = "Create task started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + uxPriority = *( unsigned portBASE_TYPE * ) pvParameters; + vPortFree( pvParameters ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask1 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask1, uxPriority, NULL ); + + xTaskCreate( vSuicidalTask, "SUICIDE1", deathSTACK_SIZE, NULL, uxPriority, &xCreatedTask2 ); + xTaskCreate( vSuicidalTask, "SUICIDE2", deathSTACK_SIZE, &xCreatedTask2, uxPriority, NULL ); + + ++sCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +portBASE_TYPE xIsCreateTaskStillRunning( void ) +{ +static short sLastCreationCount = 0; +short sReturn = pdTRUE; +unsigned portBASE_TYPE uxTasksRunningNow; + + if( sLastCreationCount == sCreationCount ) + { + sReturn = pdFALSE; + } + + uxTasksRunningNow = uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + sReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + sReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return sReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/dynamic.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/dynamic.c new file mode 100644 index 0000000..58818ae --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/dynamic.c @@ -0,0 +1,620 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises it's priority above that of the controller task before each + * increment, lowering it again to it's original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of it's loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume (). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from it's suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + * + * The final set of two tasks implements a third test. This simply raises the + * priority of a task while the scheduler is suspended. Again this test was + * added to exercise parts of the code not covered by the first test. + * + * \page Priorities dynamic.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + + Added a second, simple test that uses the functions + vQueueReceiveWhenSuspendedTask() and vQueueSendWhenSuspendedTask(). + +Changes from V3.1.1 + + + Added a third simple test that uses the vTaskPrioritySet() function + while the scheduler is suspended. + + Modified the controller task slightly to test the calling of + vTaskResumeAll() while the scheduler is suspended. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" +#include "print.h" + +/* Function that implements the "limited count" task as described above. */ +static void vLimitedIncrementTask( void * pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static void vContinuousIncrementTask( void * pvParameters ); + +/* Function that implements the controller task as described above. */ +static void vCounterControlTask( void * pvParameters ); + +/* The simple test functions that check sending and receiving while the +scheduler is suspended. */ +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ); +static void vQueueSendWhenSuspendedTask( void *pvParameters ); + +/* The simple test functions that check raising and lowering of task priorities +while the scheduler is suspended. */ +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ); +static void prvChangePriorityHelperTask( void *pvParameters ); + + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( ( unsigned short ) configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME ( ( TickType_t ) 50 ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( unsigned long ) 0xff ) +#define priNO_BLOCK ( ( TickType_t ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle, xChangePriorityWhenSuspendedHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static unsigned long ulCounter; + +/* Variable used in a similar way by the test that checks the raising and +lowering of task priorities while the scheduler is suspended. */ +static unsigned long ulPrioritySetCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static unsigned short usCheckVariable = ( unsigned short ) 0; +static portBASE_TYPE xSuspendedQueueSendError = pdFALSE; +static portBASE_TYPE xSuspendedQueueReceiveError = pdFALSE; +static portBASE_TYPE xPriorityRaiseWhenSuspendedError = pdFALSE; + +/* Queue used by the second test. */ +QueueHandle_t xSuspendedTestQueue; + +/*-----------------------------------------------------------*/ +/* + * Start the seven tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( unsigned long ) ); + xTaskCreate( vContinuousIncrementTask, "CONT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_SEND", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RECV", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvChangePriorityWhenSuspendedTask, "1st_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL ); + xTaskCreate( prvChangePriorityHelperTask, "2nd_P_CHANGE", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, &xChangePriorityWhenSuspendedHandle ); +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static void vLimitedIncrementTask( void * pvParameters ) +{ +unsigned long *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned long * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static void vContinuousIncrementTask( void * pvParameters ) +{ +unsigned long *pulCounter; +unsigned portBASE_TYPE uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( unsigned long * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise our priority above the controller task to ensure a context + switch does not occur while we are accessing this variable. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + ( *pulCounter )++; + vTaskPrioritySet( NULL, uxOurPriority ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static void vCounterControlTask( void * pvParameters ) +{ +unsigned long ulLastCounter; +short sLoops; +short sError = pdFALSE; +const char * const pcTaskStartMsg = "Priority manipulation tasks started.\r\n"; +const char * const pcTaskFailMsg = "Priority manipulation Task Failed\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( unsigned long ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. */ + vTaskSuspend( xContinuousIncrementHandle ); + ulLastCounter = ulCounter; + vTaskResume( xContinuousIncrementHandle ); + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + } + xTaskResumeAll(); + } + + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared variable. */ + vTaskSuspend( xContinuousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( unsigned long ) 0; + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. + The scheduler suspension is not necessary but is included for test + purposes. */ + vTaskSuspendAll(); + vTaskResume( xLimitedIncrementHandle ); + xTaskResumeAll(); + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinuousIncrementHandle ); + } +} +/*-----------------------------------------------------------*/ + +static void vQueueSendWhenSuspendedTask( void *pvParameters ) +{ +static unsigned long ulValueToSend = ( unsigned long ) 0; +const char * const pcTaskStartMsg = "Queue send while suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Queue send while suspended failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + if( xSuspendedQueueSendError == pdFALSE ) + { + xTaskResumeAll(); + vPrintDisplayMessage( &pcTaskFailMsg ); + vTaskSuspendAll(); + } + + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static void vQueueReceiveWhenSuspendedTask( void *pvParameters ) +{ +static unsigned long ulExpectedValue = ( unsigned long ) 0, ulReceivedValue; +const char * const pcTaskStartMsg = "Queue receive while suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Queue receive while suspended failed.\r\n"; +portBASE_TYPE xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + if( xSuspendedQueueReceiveError == pdFALSE ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + } + xSuspendedQueueReceiveError = pdTRUE; + } + + ++ulExpectedValue; + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityWhenSuspendedTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "Priority change when suspended task started.\r\n"; +const char * const pcTaskFailMsg = "Priority change when suspended task failed.\r\n"; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Start with the counter at 0 so we know what the counter should be + when we check it next. */ + ulPrioritySetCounter = ( unsigned long ) 0; + + /* Resume the helper task. At this time it has a priority lower than + ours so no context switch should occur. */ + vTaskResume( xChangePriorityWhenSuspendedHandle ); + + /* Check to ensure the task just resumed has not executed. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Now try raising the priority while the scheduler is suspended. */ + vTaskSuspendAll(); + { + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, ( configMAX_PRIORITIES - 1 ) ); + + /* Again, even though the helper task has a priority greater than + ours, it should not have executed yet because the scheduler is + suspended. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 0 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + } + xTaskResumeAll(); + + /* Now the scheduler has been resumed the helper task should + immediately preempt us and execute. When it executes it will increment + the ulPrioritySetCounter exactly once before suspending itself. + + We should now always find the counter set to 1. */ + portENTER_CRITICAL(); + { + if( ulPrioritySetCounter != ( unsigned long ) 1 ) + { + xPriorityRaiseWhenSuspendedError = pdTRUE; + vPrintDisplayMessage( &pcTaskFailMsg ); + } + } + portEXIT_CRITICAL(); + + /* Delay until we try this again. */ + vTaskDelay( priSLEEP_TIME * 2 ); + + /* Set the priority of the helper task back ready for the next + execution of this task. */ + vTaskSuspendAll(); + vTaskPrioritySet( xChangePriorityWhenSuspendedHandle, tskIDLE_PRIORITY ); + xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +static void prvChangePriorityHelperTask( void *pvParameters ) +{ + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This is the helper task for prvChangePriorityWhenSuspendedTask(). + It has it's priority raised and lowered. When it runs it simply + increments the counter then suspends itself again. This allows + prvChangePriorityWhenSuspendedTask() to know how many times it has + executed. */ + ulPrioritySetCounter++; + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +portBASE_TYPE xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static unsigned short usLastTaskCheck = ( unsigned short ) 0; +portBASE_TYPE xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xPriorityRaiseWhenSuspendedError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + return xReturn; +} + + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/events.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/events.c new file mode 100644 index 0000000..aad221b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/events.c @@ -0,0 +1,410 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * This file exercises the event mechanism whereby more than one task is + * blocked waiting for the same event. + * + * The demo creates five tasks - four 'event' tasks, and a controlling task. + * The event tasks have various different priorities and all block on reading + * the same queue. The controlling task writes data to the queue, then checks + * to see which of the event tasks read the data from the queue. The + * controlling task has the lowest priority of all the tasks so is guaranteed + * to always get preempted immediately upon writing to the queue. + * + * By selectively suspending and resuming the event tasks the controlling task + * can check that the highest priority task that is blocked on the queue is the + * task that reads the posted data from the queue. + * + * Two of the event tasks share the same priority. When neither of these tasks + * are suspended they should alternate - one reading one message from the queue, + * the other the next message, etc. + */ + +/* Standard includes. */ +#include +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "mevents.h" +#include "print.h" + +/* Demo specific constants. */ +#define evtSTACK_SIZE ( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE ) +#define evtNUM_TASKS ( 4 ) +#define evtQUEUE_LENGTH ( ( unsigned portBASE_TYPE ) 3 ) +#define evtNO_DELAY 0 + +/* Just indexes used to uniquely identify the tasks. Note that two tasks are +'highest' priority. */ +#define evtHIGHEST_PRIORITY_INDEX_2 3 +#define evtHIGHEST_PRIORITY_INDEX_1 2 +#define evtMEDIUM_PRIORITY_INDEX 1 +#define evtLOWEST_PRIORITY_INDEX 0 + +/* Each event task increments one of these counters each time it reads data +from the queue. */ +static volatile portBASE_TYPE xTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Each time the controlling task posts onto the queue it increments the +expected count of the task that it expected to read the data from the queue +(i.e. the task with the highest priority that should be blocked on the queue). + +xExpectedTaskCounters are incremented from the controlling task, and +xTaskCounters are incremented from the individual event tasks - therefore +comparing xTaskCounters to xExpectedTaskCounters shows whether or not the +correct task was unblocked by the post. */ +static portBASE_TYPE xExpectedTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 }; + +/* Handles to the four event tasks. These are required to suspend and resume +the tasks. */ +static TaskHandle_t xCreatedTasks[ evtNUM_TASKS ]; + +/* The single queue onto which the controlling task posts, and the four event +tasks block. */ +static QueueHandle_t xQueue; + +/* Flag used to indicate whether or not an error has occurred at any time. +An error is either the queue being full when not expected, or an unexpected +task reading data from the queue. */ +static portBASE_TYPE xHealthStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* Function that implements the event task. This is created four times. */ +static void prvMultiEventTask( void *pvParameters ); + +/* Function that implements the controlling task. */ +static void prvEventControllerTask( void *pvParameters ); + +/* This is a utility function that posts data to the queue, then compares +xExpectedTaskCounters with xTaskCounters to ensure everything worked as +expected. + +The event tasks all have higher priorities the controlling task. Therefore +the controlling task will always get preempted between writhing to the queue +and checking the task counters. + +@param xExpectedTask The index to the task that the controlling task thinks + should be the highest priority task waiting for data, and + therefore the task that will unblock. + +@param xIncrement The number of items that should be written to the queue. +*/ +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ); + +/* This is just incremented each cycle of the controlling tasks function so +the main application can ensure the test is still running. */ +static portBASE_TYPE xCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartMultiEventTasks( void ) +{ + /* Create the queue to be used for all the communications. */ + xQueue = xQueueCreate( evtQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) ); + + /* Start the controlling task. This has the idle priority to ensure it is + always preempted by the event tasks. */ + xTaskCreate( prvEventControllerTask, "EvntCTRL", evtSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + + /* Start the four event tasks. Note that two have priority 3, one + priority 2 and the other priority 1. */ + xTaskCreate( prvMultiEventTask, "Event0", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 0 ] ), 1, &( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event1", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 1 ] ), 2, &( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ) ); + xTaskCreate( prvMultiEventTask, "Event2", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 2 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ) ); + xTaskCreate( prvMultiEventTask, "Event3", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 3 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ) ); +} +/*-----------------------------------------------------------*/ + +static void prvMultiEventTask( void *pvParameters ) +{ +portBASE_TYPE *pxCounter; +unsigned portBASE_TYPE uxDummy; +const char * const pcTaskStartMsg = "Multi event task started.\r\n"; + + /* The variable this task will increment is passed in as a parameter. */ + pxCounter = ( portBASE_TYPE * ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* Block on the queue. */ + if( xQueueReceive( xQueue, &uxDummy, portMAX_DELAY ) ) + { + /* We unblocked by reading the queue - so simply increment + the counter specific to this task instance. */ + ( *pxCounter )++; + } + else + { + xHealthStatus = pdFAIL; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvEventControllerTask( void *pvParameters ) +{ +const char * const pcTaskStartMsg = "Multi event controller task started.\r\n"; +portBASE_TYPE xDummy = 0; + + /* Just to stop warnings. */ + ( void ) pvParameters; + + vPrintDisplayMessage( &pcTaskStartMsg ); + + for( ;; ) + { + /* All tasks are blocked on the queue. When a message is posted one of + the two tasks that share the highest priority should unblock to read + the queue. The next message written should unblock the other task with + the same high priority, and so on in order. No other task should + unblock to read data as they have lower priorities. */ + + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* For the rest of these tests we don't need the second 'highest' + priority task - so it is suspended. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + + + /* Now suspend the other highest priority task. The medium priority + task will then be the task with the highest priority that remains + blocked on the queue. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + /* This time, when we post onto the queue we will expect the medium + priority task to unblock and preempt us. */ + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + /* Now try resuming the highest priority task while the scheduler is + suspended. The task should start executing as soon as the scheduler + is resumed - therefore when we post to the queue again, the highest + priority task should again preempt us. */ + vTaskSuspendAll(); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now we are going to suspend the high and medium priority tasks. The + low priority task should then preempt us. Again the task suspension is + done with the whole scheduler suspended just for test purposes. */ + vTaskSuspendAll(); + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + /* Do the same basic test another few times - selectively suspending + and resuming tasks and each time calling prvCheckTaskCounters() passing + to the function the number of the task we expected to be unblocked by + the post. */ + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for test. */ + vTaskSuspendAll(); /* Just for even more test. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + xTaskResumeAll(); + xTaskResumeAll(); + xTaskResumeAll(); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 ); + + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 ); + + /* Now a slight change, first suspend all tasks. */ + vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* Now when we resume the low priority task and write to the queue 3 + times. We expect the low priority task to service the queue three + times. */ + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH ); + + /* Again suspend all tasks (only the low priority task is not suspended + already). */ + vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + + /* This time we are going to suspend the scheduler, resume the low + priority task, then resume the high priority task. In this state we + will write to the queue three times. When the scheduler is resumed + we expect the high priority task to service all three messages. */ + vTaskSuspendAll(); + { + vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ); + + for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + xHealthStatus = pdFAIL; + } + } + + /* The queue should not have been serviced yet!. The scheduler + is still suspended. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + } + xTaskResumeAll(); + + /* We should have been preempted by resuming the scheduler - so by the + time we are running again we expect the high priority task to have + removed three items from the queue. */ + xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH; + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + xHealthStatus = pdFAIL; + } + + /* The medium priority and second high priority tasks are still + suspended. Make sure to resume them before starting again. */ + vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ); + vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ); + + /* Just keep incrementing to show the task is still executing. */ + xCheckVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement ) +{ +portBASE_TYPE xDummy = 0; + + /* Write to the queue the requested number of times. The data written is + not important. */ + for( xDummy = 0; xDummy < xIncrement; xDummy++ ) + { + if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE ) + { + /* Did not expect to ever find the queue full. */ + xHealthStatus = pdFAIL; + } + } + + /* All the tasks blocked on the queue have a priority higher than the + controlling task. Writing to the queue will therefore have caused this + task to be preempted. By the time this line executes the event task will + have executed and incremented its counter. Increment the expected counter + to the same value. */ + ( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement; + + /* Check the actual counts and expected counts really are the same. */ + if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) ) + { + /* The counters were not the same. This means a task we did not expect + to unblock actually did unblock. */ + xHealthStatus = pdFAIL; + } +} +/*-----------------------------------------------------------*/ + +portBASE_TYPE xAreMultiEventTasksStillRunning( void ) +{ +static portBASE_TYPE xPreviousCheckVariable = 0; + + /* Called externally to periodically check that this test is still + operational. */ + + if( xPreviousCheckVariable == xCheckVariable ) + { + xHealthStatus = pdFAIL; + } + + xPreviousCheckVariable = xCheckVariable; + + return xHealthStatus; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flash.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flash.c new file mode 100644 index 0000000..f4763fa --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flash.c @@ -0,0 +1,170 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/** + * Creates eight tasks, each of which flash an LED at a different rate. The first + * LED flashes every 125ms, the second every 250ms, the third every 375ms, etc. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + * The PC port uses the standard parallel port for outputs, the Flashlite 186 port + * uses IO port F. + * + * \page flashC flash.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" +#include "print.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE + +/* Structure used to pass parameters to the LED tasks. */ +typedef struct LED_PARAMETERS +{ + unsigned portBASE_TYPE uxLED; /*< The output the task should use. */ + TickType_t xFlashRate; /*< The rate at which the LED should flash. */ +} xLEDParameters; + +/* The task that is created eight times - each time with a different xLEDParaemtes +structure passed in as the parameter. */ +static void vLEDFlashTask( void *pvParameters ); + +/* String to print if USE_STDIO is defined. */ +const char * const pcTaskStartMsg = "LED flash task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( unsigned portBASE_TYPE uxPriority ) +{ +unsigned portBASE_TYPE uxLEDTask; +xLEDParameters *pxLEDParameters; +const unsigned portBASE_TYPE uxNumOfLEDs = 8; +const TickType_t xFlashRate = 125; + + /* Create the eight tasks. */ + for( uxLEDTask = 0; uxLEDTask < uxNumOfLEDs; ++uxLEDTask ) + { + /* Create and complete the structure used to pass parameters to the next + created task. */ + pxLEDParameters = ( xLEDParameters * ) pvPortMalloc( sizeof( xLEDParameters ) ); + pxLEDParameters->uxLED = uxLEDTask; + pxLEDParameters->xFlashRate = ( xFlashRate + ( xFlashRate * ( TickType_t ) uxLEDTask ) ); + pxLEDParameters->xFlashRate /= portTICK_PERIOD_MS; + + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, ( void * ) pxLEDParameters, uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void vLEDFlashTask( void *pvParameters ) +{ +xLEDParameters *pxParameters; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + pxParameters = ( xLEDParameters * ) pvParameters; + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelay( pxParameters->xFlashRate / ( TickType_t ) 2 ); + vParTestToggleLED( pxParameters->uxLED ); + } +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flop.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flop.c new file mode 100644 index 0000000..4b1e56d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/flop.c @@ -0,0 +1,373 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * Creates eight tasks, each of which loops continuously performing an (emulated) + * floating point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + * + * \page FlopC flop.c + * \ingroup DemoFiles + *
+ */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE ( ( unsigned short ) 512 ) +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static void vCompetingMathTask1( void *pvParameters ); +static void vCompetingMathTask2( void *pvParameters ); +static void vCompetingMathTask3( void *pvParameters ); +static void vCompetingMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile unsigned short usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask1( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned short *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( 123.4567 + 2345.6789 ) * -918.222; +const char * const pcTaskStartMsg = "Math task 1 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 1 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask2( void *pvParameters ) +{ +portDOUBLE d1, d2, d3, d4; +volatile unsigned short *pusTaskCheckVariable; +const portDOUBLE dAnswer = ( -389.38 / 32498.2 ) * -2.0001; +const char * const pcTaskStartMsg = "Math task 2 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 2 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask3( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Math task 3 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 3 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition + 5.5; + dTotal1 += ( portDOUBLE ) usPosition + 5.5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompetingMathTask4( void *pvParameters ) +{ +portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Math task 4 started.\r\n"; +const char * const pcTaskFailMsg = "Math task 4 failed.\r\n"; +short sError = pdFALSE; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( ( size_t ) 250 * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + pdArray[ usPosition ] = ( portDOUBLE ) usPosition * 12.123; + dTotal1 += ( portDOUBLE ) usPosition * 12.123; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + dTotal2 += pdArray[ usPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned short usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/integer.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/integer.c new file mode 100644 index 0000000..dda5ac1 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/integer.c @@ -0,0 +1,369 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* +Changes from V1.2.3 + + + The created tasks now include calls to tskYIELD(), allowing them to be used + with the cooperative scheduler. +*/ + +/** + * This does the same as flop. c, but uses variables of type long instead of + * type double. + * + * As with flop. c, the tasks created in this file are a good test of the + * scheduler context switch mechanism. The processor has to access 32bit + * variables in two or four chunks (depending on the processor). The low + * priority of these tasks means there is a high probability that a context + * switch will occur mid calculation. See the flop. c documentation for + * more information. + * + * \page IntegerC integer.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.1 + + + The constants used in the calculations are larger to ensure the + optimiser does not truncate them to 16 bits. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "print.h" + +/* Demo program include files. */ +#include "integer.h" + +#define intgSTACK_SIZE ( ( unsigned short ) 256 ) +#define intgNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different calculation on four byte +variables. Each of the four is created twice. */ +static void vCompeteingIntMathTask1( void *pvParameters ); +static void vCompeteingIntMathTask2( void *pvParameters ); +static void vCompeteingIntMathTask3( void *pvParameters ); +static void vCompeteingIntMathTask4( void *pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will stop incrementing its check variable. */ +static volatile unsigned short usTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( unsigned portBASE_TYPE uxPriority ) +{ + xTaskCreate( vCompeteingIntMathTask1, "IntMath1", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath2", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath3", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath4", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask1, "IntMath5", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask2, "IntMath6", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask3, "IntMath7", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompeteingIntMathTask4, "IntMath8", intgSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask1( void *pvParameters ) +{ +long l1, l2, l3, l4; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const long lAnswer = ( ( long ) 74565L + ( long ) 1234567L ) * ( long ) -918L; +const char * const pcTaskStartMsg = "Integer math task 1 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 1 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + l1 = ( long ) 74565L; + l2 = ( long ) 1234567L; + l3 = ( long ) -918L; + + l4 = ( l1 + l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask2( void *pvParameters ) +{ +long l1, l2, l3, l4; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const long lAnswer = ( ( long ) -389000L / ( long ) 329999L ) * ( long ) -89L; +const char * const pcTaskStartMsg = "Integer math task 2 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 2 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + l1 = -389000L; + l2 = 329999L; + l3 = -89L; + + l4 = ( l1 / l2 ) * l3; + + taskYIELD(); + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( l4 != lAnswer ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask3( void *pvParameters ) +{ +long *plArray, lTotal1, lTotal2; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = ( unsigned short ) 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Integer math task 3 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 3 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( long ) 0; + lTotal2 = ( long ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( long ) usPosition + ( long ) 5; + lTotal1 += ( long ) usPosition + ( long ) 5; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static void vCompeteingIntMathTask4( void *pvParameters ) +{ +long *plArray, lTotal1, lTotal2; +short sError = pdFALSE; +volatile unsigned short *pusTaskCheckVariable; +const unsigned short usArraySize = 250; +unsigned short usPosition; +const char * const pcTaskStartMsg = "Integer math task 4 started.\r\n"; +const char * const pcTaskFailMsg = "Integer math task 4 failed.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( unsigned short * ) pvParameters; + + /* Create the array we are going to use for our check calculation. */ + plArray = ( long * ) pvPortMalloc( ( size_t ) 250 * sizeof( long ) ); + + /* Keep filling the array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + lTotal1 = ( long ) 0; + lTotal2 = ( long ) 0; + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + plArray[ usPosition ] = ( long ) usPosition * ( long ) 12; + lTotal1 += ( long ) usPosition * ( long ) 12; + } + + taskYIELD(); + + for( usPosition = 0; usPosition < usArraySize; usPosition++ ) + { + lTotal2 += plArray[ usPosition ]; + } + + + if( lTotal1 != lTotal2 ) + { + vPrintDisplayMessage( &pcTaskFailMsg ); + sError = pdTRUE; + } + + taskYIELD(); + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreIntegerMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static unsigned short usLastTaskCheck[ intgNUMBER_OF_TASKS ] = { ( unsigned short ) 0 }; +portBASE_TYPE xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < intgNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/print.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/print.c new file mode 100644 index 0000000..d79ad4a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/print.c @@ -0,0 +1,148 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Manages a queue of strings that are waiting to be displayed. This is used to + * ensure mutual exclusion of console output. + * + * A task wishing to display a message will call vPrintDisplayMessage (), with a + * pointer to the string as the parameter. The pointer is posted onto the + * xPrintQueue queue. + * + * The task spawned in main. c blocks on xPrintQueue. When a message becomes + * available it calls pcPrintGetNextMessage () to obtain a pointer to the next + * string, then uses the functions defined in the portable layer FileIO. c to + * display the message. + * + * NOTE: + * Using console IO can disrupt real time performance - depending on the port. + * Standard C IO routines are not designed for real time applications. While + * standard IO is useful for demonstration and debugging an alternative method + * should be used if you actually require console IO as part of your application. + * + * \page PrintC print.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "queue.h" + +/* Demo program include files. */ +#include "print.h" + +static QueueHandle_t xPrintQueue; + +/*-----------------------------------------------------------*/ + +void vPrintInitialise( void ) +{ +const unsigned portBASE_TYPE uxQueueSize = 20; + + /* Create the queue on which errors will be reported. */ + xPrintQueue = xQueueCreate( uxQueueSize, ( unsigned portBASE_TYPE ) sizeof( char * ) ); +} +/*-----------------------------------------------------------*/ + +void vPrintDisplayMessage( const char * const * ppcMessageToSend ) +{ + #ifdef USE_STDIO + xQueueSend( xPrintQueue, ( void * ) ppcMessageToSend, ( TickType_t ) 0 ); + #else + /* Stop warnings. */ + ( void ) ppcMessageToSend; + #endif +} +/*-----------------------------------------------------------*/ + +const char *pcPrintGetNextMessage( TickType_t xPrintRate ) +{ +char *pcMessage; + + if( xQueueReceive( xPrintQueue, &pcMessage, xPrintRate ) == pdPASS ) + { + return pcMessage; + } + else + { + return NULL; + } +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/semtest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/semtest.c new file mode 100644 index 0000000..36f6834 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Full/semtest.c @@ -0,0 +1,327 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + * \page SemTestC semtest.c + * \ingroup DemoFiles + *
+ */ + +/* +Changes from V1.2.0: + + + The tasks that operate at the idle priority now use a lower expected + count than those running at a higher priority. This prevents the low + priority tasks from signaling an error because they have not been + scheduled enough time for each of them to count the shared variable to + the high value. + +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than unsigned long. + +Changes from V2.1.1 + + + The stack size now uses configMINIMAL_STACK_SIZE. + + String constants made file scope to decrease stack depth on 8051 port. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" +#include "print.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( unsigned long ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( TickType_t ) 10 ) + +/* The task function as described at the top of the file. */ +static void prvSemaphoreTest( void *pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + SemaphoreHandle_t xSemaphore; + volatile unsigned long *pulSharedVariable; + TickType_t xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile short sNextCheckVariable = 0; + +/* Strings to print if USE_STDIO is defined. */ +const char * const pcPollingSemaphoreTaskError = "Guarded shared variable in unexpected state.\r\n"; +const char * const pcSemaphoreTaskStart = "Guarded shared variable task started.\r\n"; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( unsigned portBASE_TYPE uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const TickType_t xBlockTime = ( TickType_t ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + vSemaphoreCreateBinary( pxFirstSemaphoreParameters->xSemaphore ); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + vSemaphoreCreateBinary( pxSecondSemaphoreParameters->xSemaphore ); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + pxSecondSemaphoreParameters->pulSharedVariable = ( unsigned long * ) pvPortMalloc( sizeof( unsigned long ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS; + + xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSemaphoreTest( void *pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile unsigned long *pulSharedVariable, ulExpectedValue; +unsigned long ulCounter; +short sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcSemaphoreTaskStart ); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( TickType_t ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( unsigned long ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + if( sError == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + } + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + vPrintDisplayMessage( &pcPollingSemaphoreTaskError ); + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( TickType_t ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +portBASE_TYPE xAreSemaphoreTasksStillRunning( void ) +{ +static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +portBASE_TYPE xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/AbortDelay.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/AbortDelay.c new file mode 100644 index 0000000..def5e1d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/AbortDelay.c @@ -0,0 +1,681 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This file contains some test scenarios that ensure tasks respond correctly + * to xTaskAbortDelay() calls. + */ + +/* Standard includes. */ +#include "limits.h" + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#include "event_groups.h" + +/* Demo includes. */ +#include "AbortDelay.h" + +/* This file can only be used if the functionality it tests is included in the +build. Remove the whole file if this is not the case. */ +#if( INCLUDE_xTaskAbortDelay == 1 ) + +#if( INCLUDE_xTaskGetHandle != 1 ) + #error This test file uses the xTaskGetHandle() API function so INCLUDE_xTaskGetHandle must be set to 1 in FreeRTOSConfig.h. +#endif + +/* Task priorities. Allow these to be overridden. */ +#ifndef abtCONTROLLING_PRIORITY + #define abtCONTROLLING_PRIORITY ( configMAX_PRIORITIES - 3 ) +#endif + +#ifndef abtBLOCKING_PRIORITY + #define abtBLOCKING_PRIORITY ( configMAX_PRIORITIES - 2 ) +#endif + +/* The tests that are performed. */ +#define abtNOTIFY_WAIT_ABORTS 0 +#define abtNOTIFY_TAKE_ABORTS 1 +#define abtDELAY_ABORTS 2 +#define abtDELAY_UNTIL_ABORTS 3 +#define abtSEMAPHORE_TAKE_ABORTS 4 +#define abtEVENT_GROUP_ABORTS 5 +#define abtQUEUE_SEND_ABORTS 6 +#define abtMAX_TESTS 7 + +/*-----------------------------------------------------------*/ + +/* + * The two test tasks. The controlling task specifies which test to executed. + * More information is provided in the comments within the tasks. + */ +static void prvControllingTask( void *pvParameters ); +static void prvBlockingTask( void *pvParameters ); + +/* + * Test functions called by the blocking task. Each function follows the same + * pattern, but the way the task blocks is different in each case. + * + * In each function three blocking calls are made. The first and third + * blocking call is expected to time out, while the middle blocking call is + * expected to be aborted by the controlling task half way through the block + * time. + */ +static void prvTestAbortingTaskNotifyWait( void ); +static void prvTestAbortingTaskNotifyTake( void ); +static void prvTestAbortingTaskDelay( void ); +static void prvTestAbortingTaskDelayUntil( void ); +static void prvTestAbortingSemaphoreTake( void ); +static void prvTestAbortingEventGroupWait( void ); +static void prvTestAbortingQueueSend( void ); + +/* + * Checks the amount of time a task spent in the Blocked state is within the + * expected bounds. + */ +static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime ); + +/*-----------------------------------------------------------*/ + +/* Used to ensure that tasks are still executing without error. */ +static volatile BaseType_t xControllingCycles = 0, xBlockingCycles = 0; +static volatile BaseType_t xErrorOccurred = pdFALSE; + +/* Each task needs to know the other tasks handle so they can send signals to +each other. The handle is obtained from the task's name. */ +static const char *pcControllingTaskName = "AbtCtrl", *pcBlockingTaskName = "AbtBlk"; + +/* The maximum amount of time a task will block for. */ +const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 100 ); +const TickType_t xHalfMaxBlockTime = pdMS_TO_TICKS( 50 ); + +/* The actual block time is dependent on the priority of other tasks in the +system so the actual block time might be greater than that expected, but it +should be within an acceptable upper bound. */ +const TickType_t xAllowableMargin = pdMS_TO_TICKS( 7 ); + +/*-----------------------------------------------------------*/ + +void vCreateAbortDelayTasks( void ) +{ + /* Create the two test tasks described above. */ + xTaskCreate( prvControllingTask, pcControllingTaskName, configMINIMAL_STACK_SIZE, NULL, abtCONTROLLING_PRIORITY, NULL ); + xTaskCreate( prvBlockingTask, pcBlockingTaskName, configMINIMAL_STACK_SIZE, NULL, abtBLOCKING_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvControllingTask( void *pvParameters ) +{ +TaskHandle_t xBlockingTask; +uint32_t ulTestToPerform = abtNOTIFY_WAIT_ABORTS; +TickType_t xTimeAtStart; +const TickType_t xStartMargin = 2UL; + + /* Just to remove compiler warnings. */ + ( void ) pvParameters; + + xBlockingTask = xTaskGetHandle( pcBlockingTaskName ); + configASSERT( xBlockingTask ); + + for( ;; ) + { + /* Tell the secondary task to perform the next test. */ + xTimeAtStart = xTaskGetTickCount(); + xTaskNotify( xBlockingTask, ulTestToPerform, eSetValueWithOverwrite ); + + /* The secondary task has a higher priority, so will now be in the + Blocked state to wait for a maximum of xMaxBlockTime. It expects that + period to complete with a timeout. It will then block for + xMaxBlockTimeAgain, but this time it expects to the block time to abort + half way through. Block until it is time to send the abort to the + secondary task. xStartMargin is used because this task takes timing + from the beginning of the test, whereas the blocking task takes timing + from the entry into the Blocked state - and as the tasks run at + different priorities, there may be some discrepancy. Also, temporarily + raise the priority of the controlling task to that of the blocking + task to minimise discrepancies. */ + vTaskPrioritySet( NULL, abtBLOCKING_PRIORITY ); + vTaskDelay( xMaxBlockTime + xHalfMaxBlockTime + xStartMargin ); + xTaskAbortDelay( xBlockingTask ); + + /* Reset the priority to the normal controlling priority. */ + vTaskPrioritySet( NULL, abtCONTROLLING_PRIORITY ); + + /* Now wait to be notified that the secondary task has completed its + test. */ + ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + + /* Did the entire test run for the expected time, which is two full + block times plus the half block time caused by calling + xTaskAbortDelay()? */ + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, ( xMaxBlockTime + xMaxBlockTime + xHalfMaxBlockTime ) ); + + /* Move onto the next test. */ + ulTestToPerform++; + + if( ulTestToPerform >= abtMAX_TESTS ) + { + ulTestToPerform = 0; + } + + /* To indicate this task is still executing. */ + xControllingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvBlockingTask( void *pvParameters ) +{ +TaskHandle_t xControllingTask; +uint32_t ulNotificationValue; +const uint32_t ulMax = 0xffffffffUL; + + /* Just to remove compiler warnings. */ + ( void ) pvParameters; + + xControllingTask = xTaskGetHandle( pcControllingTaskName ); + configASSERT( xControllingTask ); + + for( ;; ) + { + /* Wait to be notified of the test that is to be performed next. */ + xTaskNotifyWait( 0, ulMax, &ulNotificationValue, portMAX_DELAY ); + + switch( ulNotificationValue ) + { + case abtNOTIFY_WAIT_ABORTS: + prvTestAbortingTaskNotifyWait(); + break; + + case abtNOTIFY_TAKE_ABORTS: + prvTestAbortingTaskNotifyTake(); + break; + + case abtDELAY_ABORTS: + prvTestAbortingTaskDelay(); + break; + + case abtDELAY_UNTIL_ABORTS: + prvTestAbortingTaskDelayUntil(); + break; + + case abtSEMAPHORE_TAKE_ABORTS: + prvTestAbortingSemaphoreTake(); + break; + + case abtEVENT_GROUP_ABORTS: + prvTestAbortingEventGroupWait(); + break; + + case abtQUEUE_SEND_ABORTS: + prvTestAbortingQueueSend(); + break; + + default: + /* Should not get here. */ + break; + } + + /* Let the primary task know the test is complete. */ + xTaskNotifyGive( xControllingTask ); + + /* To indicate this task is still executing. */ + xBlockingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingTaskDelayUntil( void ) +{ +TickType_t xTimeAtStart, xLastBlockTime; + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* Take a copy of the time as it is updated in the call to + vTaskDelayUntil() but its original value is needed to determine the actual + time spend in the Blocked state. */ + xLastBlockTime = xTimeAtStart; + + /* This first delay should just time out. */ + vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* This second delay should be aborted by the primary task half way + through. Again take a copy of the time as it is updated in the call to + vTaskDelayUntil() buts its original value is needed to determine the amount + of time actually spent in the Blocked state. */ + xTimeAtStart = xTaskGetTickCount(); + xLastBlockTime = xTimeAtStart; + vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* As with the other tests, the third block period should not time out. */ + xTimeAtStart = xTaskGetTickCount(); + xLastBlockTime = xTimeAtStart; + vTaskDelayUntil( &xLastBlockTime, xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingTaskDelay( void ) +{ +TickType_t xTimeAtStart; + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + vTaskDelay( xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + vTaskDelay( xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + vTaskDelay( xMaxBlockTime ); + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingTaskNotifyTake( void ) +{ +TickType_t xTimeAtStart; +uint32_t ulReturn; + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); + if( ulReturn != 0 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); + if( ulReturn != 0 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + ulReturn = ulTaskNotifyTake( pdFALSE, xMaxBlockTime ); + if( ulReturn != 0 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingEventGroupWait( void ) +{ +TickType_t xTimeAtStart; +EventGroupHandle_t xEventGroup; +EventBits_t xBitsToWaitFor = ( EventBits_t ) 0x01, xReturn; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + static StaticEventGroup_t xEventGroupBuffer; + + /* Create the event group. Statically allocated memory is used so the + creation cannot fail. */ + xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); + } + #else + { + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + } + #endif + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime ); + if( xReturn != 0x00 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime ); + if( xReturn != 0x00 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + xReturn = xEventGroupWaitBits( xEventGroup, xBitsToWaitFor, pdTRUE, pdTRUE, xMaxBlockTime ); + if( xReturn != 0x00 ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Not really necessary in this case, but for completeness. */ + vEventGroupDelete( xEventGroup ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingQueueSend( void ) +{ +TickType_t xTimeAtStart; +BaseType_t xReturn; +const UBaseType_t xQueueLength = ( UBaseType_t ) 1; +QueueHandle_t xQueue; +uint8_t ucItemToQueue; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + static StaticQueue_t xQueueBuffer; + static uint8_t ucQueueStorage[ sizeof( uint8_t ) ]; + + /* Create the queue. Statically allocated memory is used so the + creation cannot fail. */ + xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer ); + } + #else + { + xQueue = xQueueCreate( xQueueLength, sizeof( uint8_t ) ); + configASSERT( xQueue ); + } + #endif + + /* This function tests aborting when in the blocked state waiting to send, + so the queue must be full. There is only one space in the queue. */ + xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); + if( xReturn != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Not really necessary in this case, but for completeness. */ + vQueueDelete( xQueue ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingSemaphoreTake( void ) +{ +TickType_t xTimeAtStart; +BaseType_t xReturn; +SemaphoreHandle_t xSemaphore; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + static StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. Statically allocated memory is used so the + creation cannot fail. */ + xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); + } + #else + { + xSemaphore = xSemaphoreCreateBinary(); + } + #endif + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + xReturn = xSemaphoreTake( xSemaphore, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Not really necessary in this case, but for completeness. */ + vSemaphoreDelete( xSemaphore ); +} +/*-----------------------------------------------------------*/ + +static void prvTestAbortingTaskNotifyWait( void ) +{ +TickType_t xTimeAtStart; +BaseType_t xReturn; + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This first delay should just time out. */ + xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This second delay should be aborted by the primary task half way + through. */ + xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); + + /* Note the time before the delay so the length of the delay is known. */ + xTimeAtStart = xTaskGetTickCount(); + + /* This third delay should just time out again. */ + xReturn = xTaskNotifyWait( 0, 0, NULL, xMaxBlockTime ); + if( xReturn != pdFALSE ) + { + xErrorOccurred = pdTRUE; + } + prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); +} +/*-----------------------------------------------------------*/ + +static void prvCheckExpectedTimeIsWithinAnAcceptableMargin( TickType_t xStartTime, TickType_t xExpectedBlockTime ) +{ +TickType_t xTimeNow, xActualBlockTime; + + xTimeNow = xTaskGetTickCount(); + xActualBlockTime = xTimeNow - xStartTime; + + /* The actual block time should not be less than the expected block time. */ + if( xActualBlockTime < xExpectedBlockTime ) + { + xErrorOccurred = pdTRUE; + } + + /* The actual block time can be greater than the expected block time, as it + depends on the priority of the other tasks, but it should be within an + acceptable margin. */ + if( xActualBlockTime > ( xExpectedBlockTime + xAllowableMargin ) ) + { + xErrorOccurred = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreAbortDelayTestTasksStillRunning( void ) +{ +static BaseType_t xLastControllingCycleCount = 0, xLastBlockingCycleCount = 0; +BaseType_t xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xControllingCycles == xLastControllingCycleCount ) + { + xReturn = pdFAIL; + } + + if( xBlockingCycles == xLastBlockingCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastBlockingCycleCount = xBlockingCycles; + xLastControllingCycleCount = xControllingCycles; + + return xReturn; +} + +#endif /* INCLUDE_xTaskAbortDelay == 1 */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/BlockQ.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/BlockQ.c new file mode 100644 index 0000000..d701394 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/BlockQ.c @@ -0,0 +1,332 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates six tasks that operate on three queues as follows: + * + * The first two tasks send and receive an incrementing number to/from a queue. + * One task acts as a producer and the other as the consumer. The consumer is a + * higher priority than the producer and is set to block on queue reads. The queue + * only has space for one item - as soon as the producer posts a message on the + * queue the consumer will unblock, pre-empt the producer, and remove the item. + * + * The second two tasks work the other way around. Again the queue used only has + * enough space for one item. This time the consumer has a lower priority than the + * producer. The producer will try to post on the queue blocking when the queue is + * full. When the consumer wakes it will remove the item from the queue, causing + * the producer to unblock, pre-empt the consumer, and immediately re-fill the + * queue. + * + * The last two tasks use the same queue producer and consumer functions. This time the queue has + * enough space for lots of items and the tasks operate at the same priority. The + * producer will execute, placing items into the queue. The consumer will start + * executing when either the queue becomes full (causing the producer to block) or + * a context switch occurs (tasks of the same priority will time slice). + * + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "BlockQ.h" + +#define blckqSTACK_SIZE configMINIMAL_STACK_SIZE +#define blckqNUM_TASK_SETS ( 3 ) + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This example cannot be used if dynamic allocation is not allowed. +#endif + +/* Structure used to pass parameters to the blocking queue tasks. */ +typedef struct BLOCKING_QUEUE_PARAMETERS +{ + QueueHandle_t xQueue; /*< The queue to be used by the task. */ + TickType_t xBlockTime; /*< The block time to use on queue reads/writes. */ + volatile short *psCheckVariable; /*< Incremented on each successful cycle to check the task is still running. */ +} xBlockingQueueParameters; + +/* Task function that creates an incrementing number and posts it on a queue. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueProducer, pvParameters ); + +/* Task function that removes the incrementing number from a queue and checks that +it is the expected number. */ +static portTASK_FUNCTION_PROTO( vBlockingQueueConsumer, pvParameters ); + +/* Variables which are incremented each time an item is removed from a queue, and +found to be the expected value. +These are used to check that the tasks are still running. */ +static volatile short sBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/* Variable which are incremented each time an item is posted on a queue. These +are used to check that the tasks are still running. */ +static volatile short sBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartBlockingQueueTasks( UBaseType_t uxPriority ) +{ +xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; +xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; +xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; +const UBaseType_t uxQueueSize1 = 1, uxQueueSize5 = 5; +const TickType_t xBlockTime = pdMS_TO_TICKS( ( TickType_t ) 1000 ); +const TickType_t xDontBlock = ( TickType_t ) 0; + + /* Create the first two tasks as described at the top of the file. */ + + /* First create the structure used to pass parameters to the consumer tasks. */ + pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Create the queue used by the first two tasks to pass the incrementing number. + Pass a pointer to the queue in the parameter structure. */ + pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + + /* The consumer is created first so gets a block time as described above. */ + pxQueueParameters1->xBlockTime = xBlockTime; + + /* Pass in the variable that this task is going to increment so we can check it + is still running. */ + pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); + + /* Create the structure used to pass parameters to the producer task. */ + pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + + /* Pass the queue to this task also, using the parameter structure. */ + pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; + + /* The producer is not going to block - as soon as it posts the consumer will + wake and remove the item so the producer should always have room to post. */ + pxQueueParameters2->xBlockTime = xDontBlock; + + /* Pass in the variable that this task is going to increment so we can check + it is still running. */ + pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); + + + /* Note the producer has a lower priority than the consumer when the tasks are + spawned. */ + xTaskCreate( vBlockingQueueConsumer, "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); + + + + /* Create the second two tasks as described at the top of the file. This uses + the same mechanism but reverses the task priorities. */ + + pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters3->xBlockTime = xDontBlock; + pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); + + pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; + pxQueueParameters4->xBlockTime = xBlockTime; + pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); + + xTaskCreate( vBlockingQueueConsumer, "QConsB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueProducer, "QProdB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); + + + + /* Create the last two tasks as described above. The mechanism is again just + the same. This time both parameter structures are given a block time. */ + pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( UBaseType_t ) sizeof( uint16_t ) ); + pxQueueParameters5->xBlockTime = xBlockTime; + pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); + + pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); + pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; + pxQueueParameters6->xBlockTime = xBlockTime; + pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); + + xTaskCreate( vBlockingQueueProducer, "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vBlockingQueueConsumer, "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueProducer, pvParameters ) +{ +uint16_t usValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueSend( pxQueueParameters->xQueue, ( void * ) &usValue, pxQueueParameters->xBlockTime ) != pdPASS ) + { + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully posted a message, so increment the variable + used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the variable we are going to post next time round. The + consumer will expect the numbers to follow in numerical order. */ + ++usValue; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vBlockingQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = 0; +xBlockingQueueParameters *pxQueueParameters; +short sErrorEverOccurred = pdFALSE; + + pxQueueParameters = ( xBlockingQueueParameters * ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( pxQueueParameters->xQueue, &usData, pxQueueParameters->xBlockTime ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* Catch-up. */ + usExpectedValue = usData; + + sErrorEverOccurred = pdTRUE; + } + else + { + /* We have successfully received a message, so increment the + variable used to check we are still running. */ + if( sErrorEverOccurred == pdFALSE ) + { + ( *pxQueueParameters->psCheckVariable )++; + } + + /* Increment the value we expect to remove from the queue next time + round. */ + ++usExpectedValue; + } + + #if configUSE_PREEMPTION == 0 + { + if( pxQueueParameters->xBlockTime == 0 ) + { + taskYIELD(); + } + } + #endif + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreBlockingQueuesStillRunning( void ) +{ +static short sLastBlockingConsumerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +static short sLastBlockingProducerCount[ blckqNUM_TASK_SETS ] = { ( uint16_t ) 0, ( uint16_t ) 0, ( uint16_t ) 0 }; +BaseType_t xReturn = pdPASS, xTasks; + + /* Not too worried about mutual exclusion on these variables as they are 16 + bits and we are only reading them. We also only care to see if they have + changed or not. + + Loop through each check variable to and return pdFALSE if any are found not + to have changed since the last call. */ + + for( xTasks = 0; xTasks < blckqNUM_TASK_SETS; xTasks++ ) + { + if( sBlockingConsumerCount[ xTasks ] == sLastBlockingConsumerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingConsumerCount[ xTasks ] = sBlockingConsumerCount[ xTasks ]; + + + if( sBlockingProducerCount[ xTasks ] == sLastBlockingProducerCount[ xTasks ] ) + { + xReturn = pdFALSE; + } + sLastBlockingProducerCount[ xTasks ] = sBlockingProducerCount[ xTasks ]; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/EventGroupsDemo.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/EventGroupsDemo.c new file mode 100644 index 0000000..6f9cc61 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/EventGroupsDemo.c @@ -0,0 +1,1078 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + + +/* +* This file contains fairly comprehensive checks on the behaviour of event +* groups. It is not intended to be a user friendly demonstration of the +* event groups API. +* +* NOTE: The tests implemented in this file are informal 'sanity' tests +* only and are not part of the module tests that make use of the +* mtCOVERAGE_TEST_MARKER macro within the event groups implementation. +*/ + + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "event_groups.h" + +/* Demo app includes. */ +#include "EventGroupsDemo.h" + +#if( INCLUDE_eTaskGetState != 1 ) + #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file. +#endif + +/* Priorities used by the tasks. */ +#define ebSET_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY ) +#define ebWAIT_BIT_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* Generic bit definitions. */ +#define ebBIT_0 ( 0x01 ) +#define ebBIT_1 ( 0x02 ) +#define ebBIT_2 ( 0x04 ) +#define ebBIT_3 ( 0x08 ) +#define ebBIT_4 ( 0x10 ) +#define ebBIT_5 ( 0x20 ) +#define ebBIT_6 ( 0x40 ) +#define ebBIT_7 ( 0x80 ) + +/* Combinations of bits used in the demo. */ +#define ebCOMBINED_BITS ( ebBIT_1 | ebBIT_5 | ebBIT_7 ) +#define ebALL_BITS ( ebBIT_0 | ebBIT_1 | ebBIT_2 | ebBIT_3 | ebBIT_4 | ebBIT_5 | ebBIT_6 | ebBIT_7 ) + +/* Associate a bit to each task. These bits are used to identify all the tasks +that synchronise with the xEventGroupSync() function. */ +#define ebSET_BIT_TASK_SYNC_BIT ebBIT_0 +#define ebWAIT_BIT_TASK_SYNC_BIT ebBIT_1 +#define ebRENDESVOUS_TASK_1_SYNC_BIT ebBIT_2 +#define ebRENDESVOUS_TASK_2_SYNC_BIT ebBIT_3 +#define ebALL_SYNC_BITS ( ebSET_BIT_TASK_SYNC_BIT | ebWAIT_BIT_TASK_SYNC_BIT | ebRENDESVOUS_TASK_1_SYNC_BIT | ebRENDESVOUS_TASK_2_SYNC_BIT ) + +/* A block time of zero simply means "don't block". */ +#define ebDONT_BLOCK ( 0 ) + +/* A 5ms delay. */ +#define ebSHORT_DELAY pdMS_TO_TICKS( ( TickType_t ) 5 ) + +/* Used in the selective bits test which checks no, one or both tasks blocked on +event bits in a group are unblocked as appropriate as different bits get set. */ +#define ebSELECTIVE_BITS_1 0x03 +#define ebSELECTIVE_BITS_2 0x05 + +/*-----------------------------------------------------------*/ + +/* + * NOTE: The tests implemented in this function are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * The master test task. This task: + * + * 1) Calls prvSelectiveBitsTestMasterFunction() to test the behaviour when two + * tasks are blocked on different bits in an event group. The counterpart of + * this test is implemented by the prvSelectiveBitsTestSlaveFunction() + * function (which is called by the two tasks that block on the event group). + * + * 2) Calls prvBitCombinationTestMasterFunction() to test the behaviour when + * just one task is blocked on various combinations of bits within an event + * group. The counterpart of this test is implemented within the 'test + * slave' task. + * + * 3) Calls prvPerformTaskSyncTests() to test task synchronisation behaviour. + */ +static void prvTestMasterTask( void *pvParameters ); + +/* + * A helper task that enables the 'test master' task to perform several + * behavioural tests. See the comments above the prvTestMasterTask() prototype + * above. + */ +static void prvTestSlaveTask( void *pvParameters ); + +/* + * The part of the test that is performed between the 'test master' task and the + * 'test slave' task to test the behaviour when the slave blocks on various + * event bit combinations. + */ +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ); + +/* + * The part of the test that uses all the tasks to test the task synchronisation + * behaviour. + */ +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ); + +/* + * Two instances of prvSyncTask() are created. They start by calling + * prvSelectiveBitsTestSlaveFunction() to act as slaves when the test master is + * executing the prvSelectiveBitsTestMasterFunction() function. They then loop + * to test the task synchronisation (rendezvous) behaviour. + */ +static void prvSyncTask( void *pvParameters ); + +/* + * Functions used in a test that blocks two tasks on various different bits + * within an event group - then sets each bit in turn and checks that the + * correct tasks unblock at the correct times. + */ +static BaseType_t prvSelectiveBitsTestMasterFunction( void ); +static void prvSelectiveBitsTestSlaveFunction( void ); + +/*-----------------------------------------------------------*/ + +/* Variables that are incremented by the tasks on each cycle provided no errors +have been found. Used to detect an error or stall in the test cycling. */ +static volatile uint32_t ulTestMasterCycles = 0, ulTestSlaveCycles = 0, ulISRCycles = 0; + +/* The event group used by all the task based tests. */ +static EventGroupHandle_t xEventGroup = NULL; + +/* The event group used by the interrupt based tests. */ +static EventGroupHandle_t xISREventGroup = NULL; + +/* Handles to the tasks that only take part in the synchronisation calls. */ +static TaskHandle_t xSyncTask1 = NULL, xSyncTask2 = NULL; + +/*-----------------------------------------------------------*/ + +void vStartEventGroupTasks( void ) +{ +TaskHandle_t xTestSlaveTaskHandle; + + /* + * This file contains fairly comprehensive checks on the behaviour of event + * groups. It is not intended to be a user friendly demonstration of the + * event groups API. + * + * NOTE: The tests implemented in this file are informal 'sanity' tests + * only and are not part of the module tests that make use of the + * mtCOVERAGE_TEST_MARKER macro within the event groups implementation. + * + * Create the test tasks as described at the top of this file. + */ + xTaskCreate( prvTestSlaveTask, "WaitO", configMINIMAL_STACK_SIZE, NULL, ebWAIT_BIT_TASK_PRIORITY, &xTestSlaveTaskHandle ); + xTaskCreate( prvTestMasterTask, "SetB", configMINIMAL_STACK_SIZE, ( void * ) xTestSlaveTaskHandle, ebSET_BIT_TASK_PRIORITY, NULL ); + xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_1_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask1 ); + xTaskCreate( prvSyncTask, "Rndv", configMINIMAL_STACK_SIZE, ( void * ) ebRENDESVOUS_TASK_2_SYNC_BIT, ebWAIT_BIT_TASK_PRIORITY, &xSyncTask2 ); + + /* If the last task was created then the others will have been too. */ + configASSERT( xSyncTask2 ); + + /* Create the event group used by the ISR tests. The event group used by + the tasks is created by the tasks themselves. */ + xISREventGroup = xEventGroupCreate(); + configASSERT( xISREventGroup ); +} +/*-----------------------------------------------------------*/ + +static void prvTestMasterTask( void *pvParameters ) +{ +BaseType_t xError; + +/* The handle to the slave task is passed in as the task parameter. */ +TaskHandle_t xTestSlaveTaskHandle = ( TaskHandle_t ) pvParameters; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + /* Create the event group used by the tasks ready for the initial tests. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that block two tasks on different combinations of bits, + then set each bit in turn and check the correct tasks unblock at the correct + times. */ + xError = prvSelectiveBitsTestMasterFunction(); + + for( ;; ) + { + /* Recreate the event group ready for the next cycle. */ + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup ); + + /* Perform the tests that check the behaviour when a single task is + blocked on various combinations of event bits. */ + xError = prvBitCombinationTestMasterFunction( xError, xTestSlaveTaskHandle ); + + /* Perform the task synchronisation tests. */ + xError = prvPerformTaskSyncTests( xError, xTestSlaveTaskHandle ); + + /* Delete the event group. */ + vEventGroupDelete( xEventGroup ); + + /* Now all the other tasks should have completed and suspended + themselves ready for the next go around the loop. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Only increment the cycle variable if no errors have been detected. */ + if( xError == pdFALSE ) + { + ulTestMasterCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSyncTask( void *pvParameters ) +{ +EventBits_t uxSynchronisationBit, uxReturned; + + /* A few tests that check the behaviour when two tasks are blocked on + various different bits within an event group are performed before this task + enters its infinite loop to carry out its main demo function. */ + prvSelectiveBitsTestSlaveFunction(); + + /* The bit to use to indicate this task is at the synchronisation point is + passed in as the task parameter. */ + uxSynchronisationBit = ( EventBits_t ) pvParameters; + + for( ;; ) + { + /* Now this task takes part in a task synchronisation - sometimes known + as a 'rendezvous'. Its execution pattern is controlled by the 'test + master' task, which is responsible for taking this task out of the + Suspended state when it is time to test the synchronisation behaviour. + See: http://www.freertos.org/xEventGroupSync.html. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + point. The first time this is done the 'test master' task has a lower + priority than this task so this task will get to the sync point before + the set bits task. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + uxSynchronisationBit, /* The bit to set in the event group to indicate this task is at the sync point. */ + ebALL_SYNC_BITS,/* The bits to wait for - these bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY );/* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A max delay was used, so this task should only exit the above + function call when the sync condition is met. Check this is the + case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Remove compiler warning if configASSERT() is not defined. */ + ( void ) uxReturned; + + /* Wait until the 'test master' task unsuspends this task again. */ + vTaskSuspend( NULL ); + + /* Set the bit that indicates this task is at the synchronisation + point again. This time the 'test master' task has a higher priority + than this task so will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, uxSynchronisationBit, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* Again a max delay was used, so this task should only exit the above + function call when the sync condition is met. Check this is the + case. */ + configASSERT( ( uxReturned & ebALL_SYNC_BITS ) == ebALL_SYNC_BITS ); + + /* Block on the event group again. This time the event group is going + to be deleted while this task is blocked on it so it is expected that 0 + be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + configASSERT( uxReturned == 0 ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTestSlaveTask( void *pvParameters ) +{ +EventBits_t uxReturned; +BaseType_t xError = pdFALSE; + + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************** + * Part 1: This section is the counterpart to the + * prvBitCombinationTestMasterFunction() function which is called by the + * test master task. + *********************************************************************** + + This task is controller by the 'test master' task (which is + implemented by prvTestMasterTask()). Suspend until resumed by the + 'test master' task. */ + vTaskSuspend( NULL ); + + /* Wait indefinitely for one of the bits in ebCOMBINED_BITS to get + set. Clear the bit on exit. */ + uxReturned = xEventGroupWaitBits( xEventGroup, /* The event group that contains the event bits being queried. */ + ebBIT_1, /* The bit to wait for. */ + pdTRUE, /* Clear the bit on exit. */ + pdTRUE, /* Wait for all the bits (only one in this case anyway). */ + portMAX_DELAY ); /* Block indefinitely to wait for the condition to be met. */ + + /* The 'test master' task set all the bits defined by ebCOMBINED_BITS, + only one of which was being waited for by this task. The return value + shows the state of the event bits when the task was unblocked, however + because the task was waiting for ebBIT_1 and 'clear on exit' was set to + the current state of the event bits will have ebBIT_1 clear. */ + if( uxReturned != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Now call xEventGroupWaitBits() again, this time waiting for all the + bits in ebCOMBINED_BITS to be set. This call should block until the + 'test master' task sets ebBIT_1 - which was the bit cleared in the call + to xEventGroupWaitBits() above. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdFALSE, /* Don't clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* Were all the bits set? */ + if( ( uxReturned & ebCOMBINED_BITS ) != ebCOMBINED_BITS ) + { + xError = pdTRUE; + } + + /* Suspend again to wait for the 'test master' task. */ + vTaskSuspend( NULL ); + + /* Now call xEventGroupWaitBits() again, again waiting for all the bits + in ebCOMBINED_BITS to be set, but this time clearing the bits when the + task is unblocked. */ + uxReturned = xEventGroupWaitBits( xEventGroup, + ebCOMBINED_BITS, /* The bits being waited on. */ + pdTRUE, /* Clear the bits on exit. */ + pdTRUE, /* All the bits must be set to unblock. */ + portMAX_DELAY ); + + /* The 'test master' task set all the bits in the event group, so that + is the value that should have been returned. The bits defined by + ebCOMBINED_BITS will have been clear again in the current value though + as 'clear on exit' was set to pdTRUE. */ + if( uxReturned != ebALL_BITS ) + { + xError = pdTRUE; + } + + + + + + /********************************************************************** + * Part 2: This section is the counterpart to the + * prvPerformTaskSyncTests() function which is called by the + * test master task. + *********************************************************************** + + + Once again wait for the 'test master' task to unsuspend this task + when it is time for the next test. */ + vTaskSuspend( NULL ); + + /* Now peform a synchronisation with all the other tasks. At this point + the 'test master' task has the lowest priority so will get to the sync + point after all the other synchronising tasks. */ + uxReturned = xEventGroupSync( xEventGroup, /* The event group used for the sync. */ + ebWAIT_BIT_TASK_SYNC_BIT, /* The bit in the event group used to indicate this task is at the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for. These bits are set by the other tasks taking part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met before giving up. */ + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the synchronisation bits should be clear again. Read back + the current value of the bits within the event group to check that is + the case. Setting the bits to zero will return the bits previous value + then leave all the bits clear. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Check the bits are indeed 0 now by simply reading then. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + vTaskSuspend( NULL ); + + /* This time sync when the 'test master' task has the highest priority + at the point where it sets its sync bit - so this time the 'test master' + task will get to the sync point before this task. */ + uxReturned = xEventGroupSync( xEventGroup, ebWAIT_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxReturned & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != 0 ) + { + xError = pdTRUE; + } + + /* Block on the event group again. This time the event group is going + to be deleted while this task is blocked on it, so it is expected that 0 + will be returned. */ + uxReturned = xEventGroupWaitBits( xEventGroup, ebALL_SYNC_BITS, pdFALSE, pdTRUE, portMAX_DELAY ); + + if( uxReturned != 0 ) + { + xError = pdTRUE; + } + + if( xError == pdFALSE ) + { + /* This task is still cycling without finding an error. */ + ulTestSlaveCycles++; + } + + configASSERT( xError == pdFALSE ); + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvPerformTaskSyncTests( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) +{ +EventBits_t uxBits; + + /* The three tasks that take part in the synchronisation (rendezvous) are + expected to be in the suspended state at the start of the test. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Try a synch with no other tasks involved. First set all the bits other + than this task's bit. */ + xEventGroupSetBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + + /* Then wait on just one bit - the bit that is being set. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bits to wait for - in this case it is just waiting for itself. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + bits are set...check that is the case. In this case there is only one + sync bit anyway. */ + if( ( uxBits & ebSET_BIT_TASK_SYNC_BIT ) != ebSET_BIT_TASK_SYNC_BIT ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again, leaving all the other + bits set (as only one bit was being waited for). */ + if( xEventGroupGetBits( xEventGroup ) != ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ) + { + xError = pdTRUE; + } + + /* Clear all the bits to zero again. */ + xEventGroupClearBits( xEventGroup, ( ebALL_SYNC_BITS & ~ebSET_BIT_TASK_SYNC_BIT ) ); + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + /* Unsuspend the other tasks then check they have executed up to the + synchronisation point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, /* The event group used for the synchronisation. */ + ebSET_BIT_TASK_SYNC_BIT,/* The bit set by this task when it reaches the sync point. */ + ebALL_SYNC_BITS, /* The bits to wait for - these bits are set by the other tasks that take part in the sync. */ + portMAX_DELAY ); /* The maximum time to wait for the sync condition to be met. */ + + /* A sync with a max delay should only exit when all the synchronise + bits are set...check that is the case. */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + + /* The other tasks should now all be suspended again, ready for the next + synchronisation. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + + /* Sync again - but this time set the last necessary bit as the + highest priority task, rather than the lowest priority task. Unsuspend + the other tasks then check they have executed up to the synchronisation + point. */ + vTaskResume( xTestSlaveTaskHandle ); + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Raise the priority of this task above that of the other tasks. */ + vTaskPrioritySet( NULL, ebWAIT_BIT_TASK_PRIORITY + 1 ); + + /* Set this task's sync bit. */ + uxBits = xEventGroupSync( xEventGroup, ebSET_BIT_TASK_SYNC_BIT, ebALL_SYNC_BITS, portMAX_DELAY ); + + /* A sync with a max delay should only exit when all the synchronisation + bits are set... */ + if( ( uxBits & ebALL_SYNC_BITS ) != ebALL_SYNC_BITS ) + { + xError = pdTRUE; + } + + /* ...but now the sync bits should be clear again. */ + if( xEventGroupGetBits( xEventGroup ) != 0 ) + { + xError = pdTRUE; + } + + + /* The other tasks should now all be in the ready state again, but not + executed yet as this task still has a higher relative priority. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eReady ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eReady ) + { + xError = pdTRUE; + } + + + /* Reset the priority of this task back to its original value. */ + vTaskPrioritySet( NULL, ebSET_BIT_TASK_PRIORITY ); + + /* Now all the other tasks should have reblocked on the event bits + to test the behaviour when the event bits are deleted. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvBitCombinationTestMasterFunction( BaseType_t xError, TaskHandle_t xTestSlaveTaskHandle ) +{ +EventBits_t uxBits; + + /* Resume the other task. It will block, pending a single bit from + within ebCOMBINED_BITS. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked on the task. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits in ebCOMBINED_BITS - the 'test slave' task is only + blocked waiting for one of them. */ + xEventGroupSetBits( xEventGroup, ebCOMBINED_BITS ); + + /* The 'test slave' task should now have executed, clearing ebBIT_1 (the + bit it was blocked on), then re-entered the Blocked state to wait for + all the other bits in ebCOMBINED_BITS to be set again. First check + ebBIT_1 is clear. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebCOMBINED_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set all the bits other than ebBIT_1 - which is the bit that must be + set before the other task unblocks. */ + xEventGroupSetBits( xEventGroup, ebALL_BITS & ~ebBIT_1 ); + + /* Ensure all the expected bits are still set. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebBIT_1 ) ) + { + xError = pdTRUE; + } + + /* Ensure the other task is still in the blocked state. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Now also set ebBIT_1, which should unblock the other task, which will + then suspend itself. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should not have cleared the bits - so all the bits + should still be set. */ + if( xEventGroupSetBits( xEventGroup, 0x00 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Clear ebBIT_1 again. */ + if( xEventGroupClearBits( xEventGroup, ebBIT_1 ) != ebALL_BITS ) + { + xError = pdTRUE; + } + + /* Resume the other task - which will wait on all the ebCOMBINED_BITS + again - this time clearing the bits when it is unblocked. */ + vTaskResume( xTestSlaveTaskHandle ); + + /* Ensure the other task is blocked once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set the bit the other task is waiting for. */ + xEventGroupSetBits( xEventGroup, ebBIT_1 ); + + /* Ensure the other task is suspended once again. */ + if( eTaskGetState( xTestSlaveTaskHandle ) != eSuspended ) + { + xError = pdTRUE; + } + + /* The other task should have cleared the bits in ebCOMBINED_BITS. + Clear the remaining bits. */ + uxBits = xEventGroupWaitBits( xEventGroup, ebALL_BITS, pdFALSE, pdFALSE, ebDONT_BLOCK ); + + if( uxBits != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* Clear all bits ready for the sync with the other three tasks. The + value returned is the value prior to the bits being cleared. */ + if( xEventGroupClearBits( xEventGroup, ebALL_BITS ) != ( ebALL_BITS & ~ebCOMBINED_BITS ) ) + { + xError = pdTRUE; + } + + /* The bits should be clear now. */ + if( xEventGroupGetBits( xEventGroup ) != 0x00 ) + { + xError = pdTRUE; + } + + return xError; +} +/*-----------------------------------------------------------*/ + +static void prvSelectiveBitsTestSlaveFunction( void ) +{ +EventBits_t uxPendBits, uxReturned; + + /* Used in a test that blocks two tasks on various different bits within an + event group - then sets each bit in turn and checks that the correct tasks + unblock at the correct times. + + This function is called by two different tasks - each of which will use a + different bit. Check the task handle to see which task the function was + called by. */ + if( xTaskGetCurrentTaskHandle() == xSyncTask1 ) + { + uxPendBits = ebSELECTIVE_BITS_1; + } + else + { + uxPendBits = ebSELECTIVE_BITS_2; + } + + for( ;; ) + { + /* Wait until it is time to perform the next cycle of the test. The + task is unsuspended by the tests implemented in the + prvSelectiveBitsTestMasterFunction() function. */ + vTaskSuspend( NULL ); + uxReturned = xEventGroupWaitBits( xEventGroup, uxPendBits, pdTRUE, pdFALSE, portMAX_DELAY ); + + if( uxReturned == ( EventBits_t ) 0 ) + { + break; + } + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvSelectiveBitsTestMasterFunction( void ) +{ +BaseType_t xError = pdFALSE; +EventBits_t uxBit; + + /* Used in a test that blocks two tasks on various different bits within an + event group - then sets each bit in turn and checks that the correct tasks + unblock at the correct times. The two other tasks (xSyncTask1 and + xSyncTask2) call prvSelectiveBitsTestSlaveFunction() to perform their parts in + this test. + + Both other tasks should start in the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + + /* Test each bit in the byte individually. */ + for( uxBit = 0x01; uxBit < 0x100; uxBit <<= 1 ) + { + /* Resume both tasks. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Now both tasks should be blocked on the event group. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + + /* Set one bit. */ + xEventGroupSetBits( xEventGroup, uxBit ); + + /* Is the bit set in the first set of selective bits? If so the first + sync task should have unblocked and returned to the suspended state. */ + if( ( uxBit & ebSELECTIVE_BITS_1 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask1 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask1 ) != eSuspended ) + { + xError = pdTRUE; + } + } + + /* Same checks for the second sync task. */ + if( ( uxBit & ebSELECTIVE_BITS_2 ) == 0 ) + { + /* Task should not have unblocked. */ + if( eTaskGetState( xSyncTask2 ) != eBlocked ) + { + xError = pdTRUE; + } + } + else + { + /* Task should have unblocked and returned to the suspended state. */ + if( eTaskGetState( xSyncTask2 ) != eSuspended ) + { + xError = pdTRUE; + } + } + } + + /* Ensure both tasks are blocked on the event group again, then delete the + event group so the other tasks leave this portion of the test. */ + vTaskResume( xSyncTask1 ); + vTaskResume( xSyncTask2 ); + + /* Deleting the event group is the signal that the two other tasks should + leave the prvSelectiveBitsTestSlaveFunction() function and continue to the main + part of their functionality. */ + vEventGroupDelete( xEventGroup ); + + return xError; +} +/*-----------------------------------------------------------*/ + +void vPeriodicEventGroupsProcessing( void ) +{ +static BaseType_t xCallCount = 0, xISRTestError = pdFALSE; +const BaseType_t xSetBitCount = 100, xGetBitsCount = 200, xClearBitsCount = 300; +const EventBits_t uxBitsToSet = 0x12U; +EventBits_t uxReturned; +BaseType_t xMessagePosted; + + /* Called periodically from the tick hook to exercise the "FromISR" + functions. */ + + xCallCount++; + + if( xCallCount == xSetBitCount ) + { + /* All the event bits should start clear. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + if( uxReturned != 0x00 ) + { + xISRTestError = pdTRUE; + } + else + { + /* Set the bits. This is called from the tick hook so it is not + necessary to use the last parameter to ensure a context switch + occurs immediately. */ + xMessagePosted = xEventGroupSetBitsFromISR( xISREventGroup, uxBitsToSet, NULL ); + if( xMessagePosted != pdPASS ) + { + xISRTestError = pdTRUE; + } + } + } + else if( xCallCount == xGetBitsCount ) + { + /* Check the bits were set as expected. */ + uxReturned = xEventGroupGetBitsFromISR( xISREventGroup ); + if( uxReturned != uxBitsToSet ) + { + xISRTestError = pdTRUE; + } + } + else if( xCallCount == xClearBitsCount ) + { + /* Clear the bits again. */ + uxReturned = ( EventBits_t ) xEventGroupClearBitsFromISR( xISREventGroup, uxBitsToSet ); + + /* Check the message was posted. */ + if( uxReturned != pdPASS ) + { + xISRTestError = pdTRUE; + } + + /* Go back to the start. */ + xCallCount = 0; + + /* If no errors have been detected then increment the count of test + cycles. */ + if( xISRTestError == pdFALSE ) + { + ulISRCycles++; + } + } + else + { + /* Nothing else to do. */ + } +} + +/*-----------------------------------------------------------*/ +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreEventGroupTasksStillRunning( void ) +{ +static uint32_t ulPreviousWaitBitCycles = 0, ulPreviousSetBitCycles = 0, ulPreviousISRCycles = 0; +BaseType_t xStatus = pdPASS; + + /* Check the tasks are still cycling without finding any errors. */ + if( ulPreviousSetBitCycles == ulTestMasterCycles ) + { + xStatus = pdFAIL; + } + ulPreviousSetBitCycles = ulTestMasterCycles; + + if( ulPreviousWaitBitCycles == ulTestSlaveCycles ) + { + xStatus = pdFAIL; + } + ulPreviousWaitBitCycles = ulTestSlaveCycles; + + if( ulPreviousISRCycles == ulISRCycles ) + { + xStatus = pdFAIL; + } + ulPreviousISRCycles = ulISRCycles; + + return xStatus; +} + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/GenQTest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/GenQTest.c new file mode 100644 index 0000000..14ecc11 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/GenQTest.c @@ -0,0 +1,788 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the extra queue functionality introduced in FreeRTOS.org V4.5.0 - + * including xQueueSendToFront(), xQueueSendToBack(), xQueuePeek() and + * mutex behaviour. + * + * See the comments above the prvSendFrontAndBackTest() and + * prvLowPriorityMutexTask() prototypes below for more information. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "GenQTest.h" + +#define genqQUEUE_LENGTH ( 5 ) +#define intsemNO_BLOCK ( 0 ) + +#define genqMUTEX_LOW_PRIORITY ( tskIDLE_PRIORITY ) +#define genqMUTEX_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * Tests the behaviour of the xQueueSendToFront() and xQueueSendToBack() + * macros by using both to fill a queue, then reading from the queue to + * check the resultant queue order is as expected. Queue data is also + * peeked. + */ +static void prvSendFrontAndBackTest( void *pvParameters ); + +/* + * The following three tasks are used to demonstrate the mutex behaviour. + * Each task is given a different priority to demonstrate the priority + * inheritance mechanism. + * + * The low priority task obtains a mutex. After this a high priority task + * attempts to obtain the same mutex, causing its priority to be inherited + * by the low priority task. The task with the inherited high priority then + * resumes a medium priority task to ensure it is not blocked by the medium + * priority task while it holds the inherited high priority. Once the mutex + * is returned the task with the inherited priority returns to its original + * low priority, and is therefore immediately preempted by first the high + * priority task and then the medium priority task before it can continue. + */ +static void prvLowPriorityMutexTask( void *pvParameters ); +static void prvMediumPriorityMutexTask( void *pvParameters ); +static void prvHighPriorityMutexTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; +static volatile uint32_t ulLoopCounter2 = 0; + +/* The variable that is guarded by the mutex in the mutex demo tasks. */ +static volatile uint32_t ulGuardedVariable = 0; + +/* Handles used in the mutex test to suspend and resume the high and medium +priority mutex test tasks. */ +static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask; + +/*-----------------------------------------------------------*/ + +void vStartGenericQueueTasks( UBaseType_t uxPriority ) +{ +QueueHandle_t xQueue; +SemaphoreHandle_t xMutex; + + /* Create the queue that we are going to use for the + prvSendFrontAndBackTest demo. */ + xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xQueue != NULL ) + { + /* vQueueAddToRegistry() adds the queue to the queue registry, if one + is in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, "Gen_Queue_Test" ); + + /* Create the demo task and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvSendFrontAndBackTest, "GenQ", configMINIMAL_STACK_SIZE, ( void * ) xQueue, uxPriority, NULL ); + } + + /* Create the mutex used by the prvMutexTest task. */ + xMutex = xSemaphoreCreateMutex(); + + if( xMutex != NULL ) + { + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutexes and has no purpose if a kernel aware + debugger is not being used. The call to vQueueAddToRegistry() will be + removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not + defined or is defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Gen_Queue_Mutex" ); + + /* Create the mutex demo tasks and pass it the mutex just created. We + are passing the mutex handle by value so it does not matter that it is + declared on the stack here. */ + xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask ); + xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSendFrontAndBackTest( void *pvParameters ) +{ +uint32_t ulData, ulData2; +QueueHandle_t xQueue; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Queue SendToFront/SendToBack/Peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + xQueue = ( QueueHandle_t ) pvParameters; + + for( ;; ) + { + /* The queue is empty, so sending an item to the back of the queue + should have the same efect as sending it to the front of the queue. + + First send to the front and check everything is as expected. */ + xQueueSendToFront( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + /* Then do the same, sending the data to the back, checking everything + is as expected. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + xQueueSendToBack( xQueue, ( void * ) &ulLoopCounter, intsemNO_BLOCK ); + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueReceive( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* The data we sent to the queue should equal the data we just received + from the queue. */ + if( ulLoopCounter != ulData ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + + /* Place 2, 3, 4 into the queue, adding items to the back of the queue. */ + for( ulData = 2; ulData < 5; ulData++ ) + { + xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ); + } + + /* Now the order in the queue should be 2, 3, 4, with 2 being the first + thing to be read out. Now add 1 then 0 to the front of the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 3 ) + { + xErrorDetected = pdTRUE; + } + ulData = 1; + xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ); + ulData = 0; + xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ); + + /* Now the queue should be full, and when we read the data out we + should receive 0, 1, 2, 3, 4. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 0; ulData < genqQUEUE_LENGTH; ulData++ ) + { + /* Try peeking the data first. */ + if( xQueuePeek( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + + + /* Now try receiving the data for real. The value should be the + same. Clobber the value first so we know we really received it. */ + ulData2 = ~ulData2; + if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + /* The queue should now be empty again. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + + /* Our queue is empty once more, add 10, 11 to the back. */ + ulData = 10; + if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + ulData = 11; + if( xQueueSend( xQueue, &ulData, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 2 ) + { + xErrorDetected = pdTRUE; + } + + /* Now we should have 10, 11 in the queue. Add 7, 8, 9 to the + front. */ + for( ulData = 9; ulData >= 7; ulData-- ) + { + if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } + + /* Now check that the queue is full, and that receiving data provides + the expected sequence of 7, 8, 9, 10, 11. */ + if( uxQueueMessagesWaiting( xQueue ) != 5 ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToFront( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + if( xQueueSendToBack( xQueue, ( void * ) &ulData, intsemNO_BLOCK ) != errQUEUE_FULL ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the data we read out is in the expected order. */ + for( ulData = 7; ulData < ( 7 + genqQUEUE_LENGTH ); ulData++ ) + { + if( xQueueReceive( xQueue, &ulData2, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulData != ulData2 ) + { + xErrorDetected = pdTRUE; + } + } + + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ) +{ + /* Take the mutex. It should be available now. */ + if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set the guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* This task's priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Ensure the task is reporting its priority as blocked and not + suspended (as it would have done in versions up to V7.5.3). */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* The priority of the high priority task should now have been inherited + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Attempt to set the priority of this task to the test priority - + between the idle priority and the medium/high test priorities, but the + actual priority should remain at the high priority. */ + vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY ); + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as the + inherited priority of this task is above that of the medium priority + task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the medium priority task did run then it will have incremented the + guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Take the local mutex too, so two mutexes are now held. */ + if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the semaphore is given back the priority of this task should not + yet be disinherited because the local mutex is still held. This is a + simplification to allow FreeRTOS to be integrated with middleware that + attempts to hold multiple mutexes without bloating the code with complex + algorithms. It is possible that the high priority mutex task will + execute as it shares a priority with this task. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The guarded variable is only incremented by the medium priority task, + which still should not have executed as this task should remain at the + higher priority, ensure this is the case. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now also give back the local mutex, taking the held count back to 0. + This time the priority of this task should be disinherited back to the + priority to which it was set while the mutex was held. This means + the medium priority task should execute and increment the guarded + variable. When this task next runs both the high and medium priority + tasks will have been suspended again. */ + if( xSemaphoreGive( xLocalMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that the priority of this task has been disinherited to + genqMUTEX_TEST_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Set the priority of this task back to its original value, ready for + the next loop around this test. */ + vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY ); +} +/*-----------------------------------------------------------*/ + +static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex ) +{ + /* Take the mutex. It should be available now. */ + if( xSemaphoreTake( xMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Set the guarded variable to a known start value. */ + ulGuardedVariable = 0; + + /* This task's priority should be as per that assigned when the task was + created. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the high priority task. This will attempt to take the + mutex, and block when it finds it cannot obtain it. */ + vTaskResume( xHighPriorityMutexTask ); + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Ensure the task is reporting its priority as blocked and not + suspended (as it would have done in versions up to V7.5.3). */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* The priority of the high priority task should now have been inherited + as by now it will have attempted to get the mutex. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now unsuspend the medium priority task. This should not run as the + inherited priority of this task is above that of the medium priority + task. */ + vTaskResume( xMediumPriorityMutexTask ); + + /* If the medium priority task did run then it will have incremented the + guarded variable. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Take the local mutex too, so two mutexes are now held. */ + if( xSemaphoreTake( xLocalMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the local semaphore is given back the priority of this task should + not yet be disinherited because the shared mutex is still held. This is a + simplification to allow FreeRTOS to be integrated with middleware that + attempts to hold multiple mutexes without bloating the code with complex + algorithms. It is possible that the high priority mutex task will + execute as it shares a priority with this task. */ + if( xSemaphoreGive( xLocalMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The guarded variable is only incremented by the medium priority task, + which still should not have executed as this task should remain at the + higher priority, ensure this is the case. */ + if( ulGuardedVariable != 0 ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now also give back the shared mutex, taking the held count back to 0. + This time the priority of this task should be disinherited back to the + priority at which it was created. This means the medium priority task + should execute and increment the guarded variable. When this task next runs + both the high and medium priority tasks will have been suspended again. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* Check the guarded variable did indeed increment... */ + if( ulGuardedVariable != 1 ) + { + xErrorDetected = pdTRUE; + } + + /* ... and that the priority of this task has been disinherited to + genqMUTEX_LOW_PRIORITY. */ + if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Mutex with priority inheritance test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + /* The local mutex is used to check the 'mutexs held' count. */ + xLocalMutex = xSemaphoreCreateMutex(); + configASSERT( xLocalMutex ); + + for( ;; ) + { + /* The first tests exercise the priority inheritance when two mutexes + are taken then returned in a different order to which they were + taken. */ + prvTakeTwoMutexesReturnInDifferentOrder( xMutex, xLocalMutex ); + + /* Just to show this task is still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* The second tests exercise the priority inheritance when two mutexes + are taken then returned in the same order in which they were taken. */ + prvTakeTwoMutexesReturnInSameOrder( xMutex, xLocalMutex ); + + /* Just to show this task is still running. */ + ulLoopCounter2++; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityMutexTask( void *pvParameters ) +{ + ( void ) pvParameters; + + for( ;; ) + { + /* The medium priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is increment the guarded + variable, this is so the low priority task knows that it has + executed. */ + ulGuardedVariable++; + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityMutexTask( void *pvParameters ) +{ +SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters; + + for( ;; ) + { + /* The high priority task starts by suspending itself. The low + priority task will unsuspend this task when required. */ + vTaskSuspend( NULL ); + + /* When this task unsuspends all it does is attempt to obtain + the mutex. It should find the mutex is not available so a + block time is specified. */ + if( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* When the mutex is eventually obtained it is just given back before + returning to suspend ready for the next cycle. */ + if( xSemaphoreGive( xMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreGenericQueueTasksStillRunning( void ) +{ +static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0; + + /* If the demo task is still running then we expect the loop counters to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + if( ulLastLoopCounter2 == ulLoopCounter2 ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + ulLastLoopCounter2 = ulLoopCounter2; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return ( BaseType_t ) !xErrorDetected; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntQueue.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntQueue.c new file mode 100644 index 0000000..fe3e19b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntQueue.c @@ -0,0 +1,769 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This file defines one of the more complex set of demo/test tasks. They are + * designed to stress test the queue implementation though pseudo simultaneous + * multiple reads and multiple writes from both tasks of varying priority and + * interrupts. The interrupts are prioritised such to ensure that nesting + * occurs (for those ports that support it). + * + * The test ensures that, while being accessed from three tasks and two + * interrupts, all the data sent to the queues is also received from + * the same queue, and that no duplicate items are either sent or received. + * The tests also ensure that a low priority task is never able to successfully + * read from or write to a queue when a task of higher priority is attempting + * the same operation. + */ + +/* Standard includes. */ +#include + +/* SafeRTOS includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "task.h" + +/* Demo app includes. */ +#include "IntQueue.h" +#include "IntQueueTimer.h" + +#if( INCLUDE_eTaskGetState != 1 ) + #error INCLUDE_eTaskGetState must be set to 1 in FreeRTOSConfig.h to use this demo file. +#endif + +/* Priorities used by test tasks. */ +#ifndef intqHIGHER_PRIORITY + #define intqHIGHER_PRIORITY ( configMAX_PRIORITIES - 2 ) +#endif +#define intqLOWER_PRIORITY ( tskIDLE_PRIORITY ) + +/* The number of values to send/receive before checking that all values were +processed as expected. */ +#define intqNUM_VALUES_TO_LOG ( 200 ) +#define intqSHORT_DELAY ( 140 ) + +/* The value by which the value being sent to or received from a queue should +increment past intqNUM_VALUES_TO_LOG before we check that all values have been +sent/received correctly. This is done to ensure that all tasks and interrupts +accessing the queue have completed their accesses with the +intqNUM_VALUES_TO_LOG range. */ +#define intqVALUE_OVERRUN ( 50 ) + +/* The delay used by the polling task. A short delay is used for code +coverage. */ +#define intqONE_TICK_DELAY ( 1 ) + +/* Each task and interrupt is given a unique identifier. This value is used to +identify which task sent or received each value. The identifier is also used +to distinguish between two tasks that are running the same task function. */ +#define intqHIGH_PRIORITY_TASK1 ( ( UBaseType_t ) 1 ) +#define intqHIGH_PRIORITY_TASK2 ( ( UBaseType_t ) 2 ) +#define intqLOW_PRIORITY_TASK ( ( UBaseType_t ) 3 ) +#define intqFIRST_INTERRUPT ( ( UBaseType_t ) 4 ) +#define intqSECOND_INTERRUPT ( ( UBaseType_t ) 5 ) +#define intqQUEUE_LENGTH ( ( UBaseType_t ) 10 ) + +/* At least intqMIN_ACCEPTABLE_TASK_COUNT values should be sent to/received +from each queue by each task, otherwise an error is detected. */ +#define intqMIN_ACCEPTABLE_TASK_COUNT ( 5 ) + +/* Send the next value to the queue that is normally empty. This is called +from within the interrupts. */ +#define timerNORMALLY_EMPTY_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyEmptyQueue ) != pdTRUE ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyEmptyQueue++; \ + if( xQueueSendFromISR( xNormallyEmptyQueue, ( void * ) &uxValueForNormallyEmptyQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + uxValueForNormallyEmptyQueue--; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Send the next value to the queue that is normally full. This is called +from within the interrupts. */ +#define timerNORMALLY_FULL_TX() \ + if( xQueueIsQueueFullFromISR( xNormallyFullQueue ) != pdTRUE ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + uxValueForNormallyFullQueue++; \ + if( xQueueSendFromISR( xNormallyFullQueue, ( void * ) &uxValueForNormallyFullQueue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + uxValueForNormallyFullQueue--; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } \ + +/* Receive a value from the normally empty queue. This is called from within +an interrupt. */ +#define timerNORMALLY_EMPTY_RX() \ + if( xQueueReceiveFromISR( xNormallyEmptyQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) != pdPASS ) \ + { \ + prvQueueAccessLogError( __LINE__ ); \ + } \ + else \ + { \ + prvRecordValue_NormallyEmpty( uxRxedValue, intqSECOND_INTERRUPT ); \ + } + +/* Receive a value from the normally full queue. This is called from within +an interrupt. */ +#define timerNORMALLY_FULL_RX() \ + if( xQueueReceiveFromISR( xNormallyFullQueue, &uxRxedValue, &xHigherPriorityTaskWoken ) == pdPASS ) \ + { \ + prvRecordValue_NormallyFull( uxRxedValue, intqSECOND_INTERRUPT ); \ + } \ + + +/*-----------------------------------------------------------*/ + +/* The two queues used by the test. */ +static QueueHandle_t xNormallyEmptyQueue, xNormallyFullQueue; + +/* Variables used to detect a stall in one of the tasks. */ +static volatile UBaseType_t uxHighPriorityLoops1 = 0, uxHighPriorityLoops2 = 0, uxLowPriorityLoops1 = 0, uxLowPriorityLoops2 = 0; + +/* Any unexpected behaviour sets xErrorStatus to fail and log the line that +caused the error in xErrorLine. */ +static BaseType_t xErrorStatus = pdPASS; +static volatile UBaseType_t xErrorLine = ( UBaseType_t ) 0; + +/* Used for sequencing between tasks. */ +static BaseType_t xWasSuspended = pdFALSE; + +/* The values that are sent to the queues. An incremented value is sent each +time to each queue. */ +static volatile UBaseType_t uxValueForNormallyEmptyQueue = 0, uxValueForNormallyFullQueue = 0; + +/* A handle to some of the tasks is required so they can be suspended/resumed. */ +TaskHandle_t xHighPriorityNormallyEmptyTask1, xHighPriorityNormallyEmptyTask2, xHighPriorityNormallyFullTask1, xHighPriorityNormallyFullTask2; + +/* When a value is received in a queue the value is ticked off in the array +the array position of the value is set to a the identifier of the task or +interrupt that accessed the queue. This way missing or duplicate values can be +detected. */ +static uint8_t ucNormallyEmptyReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; +static uint8_t ucNormallyFullReceivedValues[ intqNUM_VALUES_TO_LOG ] = { 0 }; + +/* The test tasks themselves. */ +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ); +static void prvLowerPriorityNormallyFullTask( void *pvParameters ); +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ); +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ); +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ); + +/* Used to mark the positions within the ucNormallyEmptyReceivedValues and +ucNormallyFullReceivedValues arrays, while checking for duplicates. */ +static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource ); +static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource ); + +/* Logs the line on which an error occurred. */ +static void prvQueueAccessLogError( UBaseType_t uxLine ); + +/*-----------------------------------------------------------*/ + +void vStartInterruptQueueTasks( void ) +{ + /* Start the test tasks. */ + xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H1QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask1 ); + xTaskCreate( prvHigherPriorityNormallyEmptyTask, "H2QRx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyEmptyTask2 ); + xTaskCreate( prvLowerPriorityNormallyEmptyTask, "L1QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + xTaskCreate( prv1stHigherPriorityNormallyFullTask, "H1QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK1, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask1 ); + xTaskCreate( prv2ndHigherPriorityNormallyFullTask, "H2QTx", configMINIMAL_STACK_SIZE, ( void * ) intqHIGH_PRIORITY_TASK2, intqHIGHER_PRIORITY, &xHighPriorityNormallyFullTask2 ); + xTaskCreate( prvLowerPriorityNormallyFullTask, "L2QRx", configMINIMAL_STACK_SIZE, NULL, intqLOWER_PRIORITY, NULL ); + + /* Create the queues that are accessed by multiple tasks and multiple + interrupts. */ + xNormallyFullQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) ); + xNormallyEmptyQueue = xQueueCreate( intqQUEUE_LENGTH, ( UBaseType_t ) sizeof( UBaseType_t ) ); + + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xNormallyFullQueue, "NormallyFull" ); + vQueueAddToRegistry( xNormallyEmptyQueue, "NormallyEmpty" ); +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyFull( UBaseType_t uxValue, UBaseType_t uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyFullReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyFullReceivedValues[ uxValue ] = ( uint8_t ) uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecordValue_NormallyEmpty( UBaseType_t uxValue, UBaseType_t uxSource ) +{ + if( uxValue < intqNUM_VALUES_TO_LOG ) + { + /* We don't expect to receive the same value twice, so if the value + has already been marked as received an error has occurred. */ + if( ucNormallyEmptyReceivedValues[ uxValue ] != 0x00 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Log that this value has been received. */ + ucNormallyEmptyReceivedValues[ uxValue ] = ( uint8_t ) uxSource; + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueAccessLogError( UBaseType_t uxLine ) +{ + /* Latch the line number that caused the error. */ + xErrorLine = uxLine; + xErrorStatus = pdFAIL; +} +/*-----------------------------------------------------------*/ + +static void prvHigherPriorityNormallyEmptyTask( void *pvParameters ) +{ +UBaseType_t uxRxed, ux, uxTask1, uxTask2, uxInterrupts, uxErrorCount1 = 0, uxErrorCount2 = 0; + + /* The timer should not be started until after the scheduler has started. + More than one task is running this code so we check the parameter value + to determine which task should start the timer. */ + if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + vInitialiseTimerForIntQueueTest(); + } + + for( ;; ) + { + /* Block waiting to receive a value from the normally empty queue. + Interrupts will write to the queue so we should receive a value. */ + if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqSHORT_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + /* Note which value was received so we can check all expected + values are received and no values are duplicated. */ + prvRecordValue_NormallyEmpty( uxRxed, ( UBaseType_t ) pvParameters ); + } + + /* Ensure the other task running this code gets a chance to execute. */ + taskYIELD(); + + if( ( UBaseType_t ) pvParameters == intqHIGH_PRIORITY_TASK1 ) + { + /* Have we received all the expected values? */ + if( uxValueForNormallyEmptyQueue > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + vTaskSuspend( xHighPriorityNormallyEmptyTask2 ); + + uxTask1 = 0; + uxTask2 = 0; + uxInterrupts = 0; + + /* Loop through the array, checking that both tasks have + placed values into the array, and that no values are missing. + Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyEmptyReceivedValues[ ux ] == 0 ) + { + /* A value is missing. */ + prvQueueAccessLogError( __LINE__ ); + } + else + { + if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK1 ) + { + /* Value was placed into the array by task 1. */ + uxTask1++; + } + else if( ucNormallyEmptyReceivedValues[ ux ] == intqHIGH_PRIORITY_TASK2 ) + { + /* Value was placed into the array by task 2. */ + uxTask2++; + } + else if( ucNormallyEmptyReceivedValues[ ux ] == intqSECOND_INTERRUPT ) + { + uxInterrupts++; + } + } + } + + if( uxTask1 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 2 seemed to log any values. */ + uxErrorCount1++; + if( uxErrorCount1 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount1 = 0; + } + + if( uxTask2 < intqMIN_ACCEPTABLE_TASK_COUNT ) + { + /* Only task 1 seemed to log any values. */ + uxErrorCount2++; + if( uxErrorCount2 > 2 ) + { + prvQueueAccessLogError( __LINE__ ); + } + } + else + { + uxErrorCount2 = 0; + } + + if( uxInterrupts == 0 ) + { + prvQueueAccessLogError( __LINE__ ); + } + + /* Clear the array again, ready to start a new cycle. */ + memset( ucNormallyEmptyReceivedValues, 0x00, sizeof( ucNormallyEmptyReceivedValues ) ); + + uxHighPriorityLoops1++; + uxValueForNormallyEmptyQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyEmptyTask2 ); + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyEmptyTask( void *pvParameters ) +{ +UBaseType_t uxValue, uxRxed; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( xQueueReceive( xNormallyEmptyQueue, &uxRxed, intqONE_TICK_DELAY ) != errQUEUE_EMPTY ) + { + /* A value should only be obtained when the high priority task is + suspended. */ + if( eTaskGetState( xHighPriorityNormallyEmptyTask1 ) != eSuspended ) + { + prvQueueAccessLogError( __LINE__ ); + } + + prvRecordValue_NormallyEmpty( uxRxed, intqLOW_PRIORITY_TASK ); + + /* Wake the higher priority task again. */ + vTaskResume( xHighPriorityNormallyEmptyTask1 ); + uxLowPriorityLoops1++; + } + else + { + /* Raise our priority while we send so we can preempt the higher + priority task, and ensure we get the Tx value into the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + portENTER_CRITICAL(); + { + uxValueForNormallyEmptyQueue++; + uxValue = uxValueForNormallyEmptyQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyEmptyQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv1stHigherPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValueToTx, ux, uxInterrupts; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS ) + { + /* intqHIGH_PRIORITY_TASK2 is never suspended so we would not + expect it to ever time out. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Allow the other task running this code to run. */ + taskYIELD(); + + /* Have all the expected values been sent to the queue? */ + if( uxValueToTx > ( intqNUM_VALUES_TO_LOG + intqVALUE_OVERRUN ) ) + { + /* Make sure the other high priority task completes its send of + any values below intqNUM_VALUE_TO_LOG. */ + vTaskDelay( intqSHORT_DELAY ); + + vTaskSuspend( xHighPriorityNormallyFullTask2 ); + + if( xWasSuspended == pdTRUE ) + { + /* We would have expected the other high priority task to have + set this back to false by now. */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Set the suspended flag so an error is not logged if the other + task recognises a time out when it is unsuspended. */ + xWasSuspended = pdTRUE; + + /* Check interrupts are also sending. */ + uxInterrupts = 0U; + + /* Start at 1 as we expect position 0 to be unused. */ + for( ux = 1; ux < intqNUM_VALUES_TO_LOG; ux++ ) + { + if( ucNormallyFullReceivedValues[ ux ] == 0 ) + { + /* A value was missing. */ + prvQueueAccessLogError( __LINE__ ); + } + else if( ucNormallyFullReceivedValues[ ux ] == intqSECOND_INTERRUPT ) + { + uxInterrupts++; + } + } + + if( uxInterrupts == 0 ) + { + /* No writes from interrupts were found. Are interrupts + actually running? */ + prvQueueAccessLogError( __LINE__ ); + } + + /* Reset the array ready for the next cycle. */ + memset( ucNormallyFullReceivedValues, 0x00, sizeof( ucNormallyFullReceivedValues ) ); + + uxHighPriorityLoops2++; + uxValueForNormallyFullQueue = 0; + + /* Suspend ourselves, allowing the lower priority task to + actually receive something from the queue. Until now it + will have been prevented from doing so by the higher + priority tasks. The lower priority task will resume us + if it receives something. We will then resume the other + higher priority task. */ + vTaskSuspend( NULL ); + vTaskResume( xHighPriorityNormallyFullTask2 ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prv2ndHigherPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValueToTx, ux; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + /* Make sure the queue starts full or near full. >> 1 as there are two + high priority tasks. */ + for( ux = 0; ux < ( intqQUEUE_LENGTH >> 1 ); ux++ ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ); + } + + for( ;; ) + { + portENTER_CRITICAL(); + { + uxValueForNormallyFullQueue++; + uxValueToTx = uxValueForNormallyFullQueue; + } + portEXIT_CRITICAL(); + + if( xQueueSend( xNormallyFullQueue, &uxValueToTx, intqSHORT_DELAY ) != pdPASS ) + { + if( xWasSuspended != pdTRUE ) + { + /* It is ok to time out if the task has been suspended. */ + prvQueueAccessLogError( __LINE__ ); + } + } + + xWasSuspended = pdFALSE; + + taskYIELD(); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowerPriorityNormallyFullTask( void *pvParameters ) +{ +UBaseType_t uxValue, uxTxed = 9999; + + /* The parameters are not being used so avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + if( xQueueSend( xNormallyFullQueue, &uxTxed, intqONE_TICK_DELAY ) != errQUEUE_FULL ) + { + /* Should only succeed when the higher priority task is suspended */ + if( eTaskGetState( xHighPriorityNormallyFullTask1 ) != eSuspended ) + { + prvQueueAccessLogError( __LINE__ ); + } + + vTaskResume( xHighPriorityNormallyFullTask1 ); + uxLowPriorityLoops2++; + } + else + { + /* Raise our priority while we receive so we can preempt the higher + priority task, and ensure we get the value from the queue. */ + vTaskPrioritySet( NULL, intqHIGHER_PRIORITY + 1 ); + + if( xQueueReceive( xNormallyFullQueue, &uxValue, portMAX_DELAY ) != pdPASS ) + { + prvQueueAccessLogError( __LINE__ ); + } + else + { + prvRecordValue_NormallyFull( uxValue, intqLOW_PRIORITY_TASK ); + } + + vTaskPrioritySet( NULL, intqLOWER_PRIORITY ); + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xFirstTimerHandler( void ) +{ +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +UBaseType_t uxRxedValue; +static UBaseType_t uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( UBaseType_t ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_RX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + +BaseType_t xSecondTimerHandler( void ) +{ +UBaseType_t uxRxedValue; +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +static UBaseType_t uxNextOperation = 0; + + /* Called from a timer interrupt. Perform various read and write + accesses on the queues. */ + + uxNextOperation++; + + if( uxNextOperation & ( UBaseType_t ) 0x01 ) + { + timerNORMALLY_EMPTY_TX(); + timerNORMALLY_EMPTY_TX(); + + timerNORMALLY_EMPTY_RX(); + timerNORMALLY_EMPTY_RX(); + } + else + { + timerNORMALLY_FULL_RX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + timerNORMALLY_FULL_TX(); + } + + return xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + + +BaseType_t xAreIntQueueTasksStillRunning( void ) +{ +static UBaseType_t uxLastHighPriorityLoops1 = 0, uxLastHighPriorityLoops2 = 0, uxLastLowPriorityLoops1 = 0, uxLastLowPriorityLoops2 = 0; + + /* xErrorStatus can be set outside of this function. This function just + checks that all the tasks are still cycling. */ + + if( uxHighPriorityLoops1 == uxLastHighPriorityLoops1 ) + { + /* The high priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops1 = uxHighPriorityLoops1; + + if( uxHighPriorityLoops2 == uxLastHighPriorityLoops2 ) + { + /* The high priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastHighPriorityLoops2 = uxHighPriorityLoops2; + + if( uxLowPriorityLoops1 == uxLastLowPriorityLoops1 ) + { + /* The low priority 1 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops1 = uxLowPriorityLoops1; + + if( uxLowPriorityLoops2 == uxLastLowPriorityLoops2 ) + { + /* The low priority 2 task has stalled. */ + prvQueueAccessLogError( __LINE__ ); + } + + uxLastLowPriorityLoops2 = uxLowPriorityLoops2; + + return xErrorStatus; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntSemTest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntSemTest.c new file mode 100644 index 0000000..aca1282 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/IntSemTest.c @@ -0,0 +1,567 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Demonstrates and tests mutexes being used from an interrupt. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "IntSemTest.h" + +/*-----------------------------------------------------------*/ + +/* The priorities of the test tasks. */ +#define intsemMASTER_PRIORITY ( tskIDLE_PRIORITY ) +#define intsemSLAVE_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which the tick hook will give the mutex. */ +#define intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ( 100 ) + +/* A block time of 0 means 'don't block'. */ +#define intsemNO_BLOCK 0 + +/* The maximum count value for the counting semaphore given from an +interrupt. */ +#define intsemMAX_COUNT 3 + +/*-----------------------------------------------------------*/ + +/* + * The master is a task that receives a mutex that is given from an interrupt - + * although generally mutexes should not be used given in interrupts (and + * definitely never taken in an interrupt) there are some circumstances when it + * may be desirable. + * + * The slave task is just used by the master task to force priority inheritance + * on a mutex that is shared between the master and the slave - which is a + * separate mutex to that given by the interrupt. + */ +static void vInterruptMutexSlaveTask( void *pvParameters ); +static void vInterruptMutexMasterTask( void *pvParameters ); + +/* + * A test whereby the master takes the shared and interrupt mutexes in that + * order, then gives them back in the same order, ensuring the priority + * inheritance is behaving as expected at each step. + */ +static void prvTakeAndGiveInTheSameOrder( void ); + +/* + * A test whereby the master takes the shared and interrupt mutexes in that + * order, then gives them back in the opposite order to which they were taken, + * ensuring the priority inheritance is behaving as expected at each step. + */ +static void prvTakeAndGiveInTheOppositeOrder( void ); + +/* + * A simple task that interacts with an interrupt using a counting semaphore, + * primarily for code coverage purposes. + */ +static void vInterruptCountingSemaphoreTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/* Counters that are incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulMasterLoops = 0, ulCountingSemaphoreLoops = 0; + +/* Handles of the test tasks that must be accessed from other test tasks. */ +static TaskHandle_t xSlaveHandle; + +/* A mutex which is given from an interrupt - although generally mutexes should +not be used given in interrupts (and definitely never taken in an interrupt) +there are some circumstances when it may be desirable. */ +static SemaphoreHandle_t xISRMutex = NULL; + +/* A counting semaphore which is given from an interrupt. */ +static SemaphoreHandle_t xISRCountingSemaphore = NULL; + +/* A mutex which is shared between the master and slave tasks - the master +does both sharing of this mutex with the slave and receiving a mutex from the +interrupt. */ +static SemaphoreHandle_t xMasterSlaveMutex = NULL; + +/* Flag that allows the master task to control when the interrupt gives or does +not give the mutex. There is no mutual exclusion on this variable, but this is +only test code and it should be fine in the 32=bit test environment. */ +static BaseType_t xOkToGiveMutex = pdFALSE, xOkToGiveCountingSemaphore = pdFALSE; + +/* Used to coordinate timing between tasks and the interrupt. */ +const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ); + +/*-----------------------------------------------------------*/ + +void vStartInterruptSemaphoreTasks( void ) +{ + /* Create the semaphores that are given from an interrupt. */ + xISRMutex = xSemaphoreCreateMutex(); + configASSERT( xISRMutex ); + xISRCountingSemaphore = xSemaphoreCreateCounting( intsemMAX_COUNT, 0 ); + configASSERT( xISRCountingSemaphore ); + + /* Create the mutex that is shared between the master and slave tasks (the + master receives a mutex from an interrupt and shares a mutex with the + slave. */ + xMasterSlaveMutex = xSemaphoreCreateMutex(); + configASSERT( xMasterSlaveMutex ); + + /* Create the tasks that share mutexes between then and with interrupts. */ + xTaskCreate( vInterruptMutexSlaveTask, "IntMuS", configMINIMAL_STACK_SIZE, NULL, intsemSLAVE_PRIORITY, &xSlaveHandle ); + xTaskCreate( vInterruptMutexMasterTask, "IntMuM", configMINIMAL_STACK_SIZE, NULL, intsemMASTER_PRIORITY, NULL ); + + /* Create the task that blocks on the counting semaphore. */ + xTaskCreate( vInterruptCountingSemaphoreTask, "IntCnt", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); +} +/*-----------------------------------------------------------*/ + +static void vInterruptMutexMasterTask( void *pvParameters ) +{ + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + prvTakeAndGiveInTheSameOrder(); + + /* Ensure not to starve out other tests. */ + ulMasterLoops++; + vTaskDelay( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ); + + prvTakeAndGiveInTheOppositeOrder(); + + /* Ensure not to starve out other tests. */ + ulMasterLoops++; + vTaskDelay( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTakeAndGiveInTheSameOrder( void ) +{ + /* Ensure the slave is suspended, and that this task is running at the + lower priority as expected as the start conditions. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Take the semaphore that is shared with the slave. */ + if( xSemaphoreTake( xMasterSlaveMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* This task now has the mutex. Unsuspend the slave so it too + attempts to take the mutex. */ + vTaskResume( xSlaveHandle ); + + /* The slave has the higher priority so should now have executed and + blocked on the semaphore. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xSlaveHandle ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* This task should now have inherited the priority of the slave + task. */ + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now wait a little longer than the time between ISR gives to also + obtain the ISR mutex. */ + xOkToGiveMutex = pdTRUE; + if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + xOkToGiveMutex = pdFALSE; + + /* Attempting to take again immediately should fail as the mutex is + already held. */ + if( xSemaphoreTake( xISRMutex, intsemNO_BLOCK ) != pdFAIL ) + { + xErrorDetected = pdTRUE; + } + + /* Should still be at the priority of the slave task. */ + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Give back the ISR semaphore to ensure the priority is not + disinherited as the shared mutex (which the higher priority task is + attempting to obtain) is still held. */ + if( xSemaphoreGive( xISRMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Finally give back the shared mutex. This time the higher priority + task should run before this task runs again - so this task should have + disinherited the priority and the higher priority task should be in the + suspended state again. */ + if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Reset the mutex ready for the next round. */ + xQueueReset( xISRMutex ); +} +/*-----------------------------------------------------------*/ + +static void prvTakeAndGiveInTheOppositeOrder( void ) +{ + /* Ensure the slave is suspended, and that this task is running at the + lower priority as expected as the start conditions. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xSlaveHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Take the semaphore that is shared with the slave. */ + if( xSemaphoreTake( xMasterSlaveMutex, intsemNO_BLOCK ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* This task now has the mutex. Unsuspend the slave so it too + attempts to take the mutex. */ + vTaskResume( xSlaveHandle ); + + /* The slave has the higher priority so should now have executed and + blocked on the semaphore. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xSlaveHandle ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* This task should now have inherited the priority of the slave + task. */ + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Now wait a little longer than the time between ISR gives to also + obtain the ISR mutex. */ + xOkToGiveMutex = pdTRUE; + if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + xOkToGiveMutex = pdFALSE; + + /* Attempting to take again immediately should fail as the mutex is + already held. */ + if( xSemaphoreTake( xISRMutex, intsemNO_BLOCK ) != pdFAIL ) + { + xErrorDetected = pdTRUE; + } + + /* Should still be at the priority of the slave task. */ + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Give back the shared semaphore to ensure the priority is not disinherited + as the ISR mutex is still held. The higher priority slave task should run + before this task runs again. */ + if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* Should still be at the priority of the slave task as this task still + holds one semaphore (this is a simplification in the priority inheritance + mechanism. */ + if( uxTaskPriorityGet( NULL ) != intsemSLAVE_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Give back the ISR semaphore, which should result in the priority being + disinherited as it was the last mutex held. */ + if( xSemaphoreGive( xISRMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( uxTaskPriorityGet( NULL ) != intsemMASTER_PRIORITY ) + { + xErrorDetected = pdTRUE; + } + + /* Reset the mutex ready for the next round. */ + xQueueReset( xISRMutex ); +} +/*-----------------------------------------------------------*/ + +static void vInterruptMutexSlaveTask( void *pvParameters ) +{ + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This task starts by suspending itself so when it executes can be + controlled by the master task. */ + vTaskSuspend( NULL ); + + /* This task will execute when the master task already holds the mutex. + Attempting to take the mutex will place this task in the Blocked + state. */ + if( xSemaphoreTake( xMasterSlaveMutex, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( xSemaphoreGive( xMasterSlaveMutex ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +static void vInterruptCountingSemaphoreTask( void *pvParameters ) +{ +BaseType_t xCount; +const TickType_t xDelay = pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) * ( intsemMAX_COUNT + 1 ); + + ( void ) pvParameters; + + for( ;; ) + { + /* Expect to start with the counting semaphore empty. */ + if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Wait until it is expected that the interrupt will have filled the + counting semaphore. */ + xOkToGiveCountingSemaphore = pdTRUE; + vTaskDelay( xDelay ); + xOkToGiveCountingSemaphore = pdFALSE; + + /* Now it is expected that the counting semaphore is full. */ + if( uxQueueMessagesWaiting( ( QueueHandle_t ) xISRCountingSemaphore ) != intsemMAX_COUNT ) + { + xErrorDetected = pdTRUE; + } + + if( uxQueueSpacesAvailable( ( QueueHandle_t ) xISRCountingSemaphore ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + ulCountingSemaphoreLoops++; + + /* Expect to be able to take the counting semaphore intsemMAX_COUNT + times. A block time of 0 is used as the semaphore should already be + there. */ + xCount = 0; + while( xSemaphoreTake( xISRCountingSemaphore, 0 ) == pdPASS ) + { + xCount++; + } + + if( xCount != intsemMAX_COUNT ) + { + xErrorDetected = pdTRUE; + } + + /* Now raise the priority of this task so it runs immediately that the + semaphore is given from the interrupt. */ + vTaskPrioritySet( NULL, configMAX_PRIORITIES - 1 ); + + /* Block to wait for the semaphore to be given from the interrupt. */ + xOkToGiveCountingSemaphore = pdTRUE; + xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY ); + xSemaphoreTake( xISRCountingSemaphore, portMAX_DELAY ); + xOkToGiveCountingSemaphore = pdFALSE; + + /* Reset the priority so as not to disturbe other tests too much. */ + vTaskPrioritySet( NULL, tskIDLE_PRIORITY ); + + ulCountingSemaphoreLoops++; + } +} +/*-----------------------------------------------------------*/ + +void vInterruptSemaphorePeriodicTest( void ) +{ +static TickType_t xLastGiveTime = 0; +BaseType_t xHigherPriorityTaskWoken = pdFALSE; +TickType_t xTimeNow; + + /* No mutual exclusion on xOkToGiveMutex, but this is only test code (and + only executed on a 32-bit architecture) so ignore that in this case. */ + xTimeNow = xTaskGetTickCountFromISR(); + if( ( ( TickType_t ) ( xTimeNow - xLastGiveTime ) ) >= pdMS_TO_TICKS( intsemINTERRUPT_MUTEX_GIVE_PERIOD_MS ) ) + { + configASSERT( xISRMutex ); + if( xOkToGiveMutex != pdFALSE ) + { + /* Null is used as the second parameter in this give, and non-NULL + in the other gives for code coverage reasons. */ + xSemaphoreGiveFromISR( xISRMutex, NULL ); + + /* Second give attempt should fail. */ + configASSERT( xSemaphoreGiveFromISR( xISRMutex, &xHigherPriorityTaskWoken ) == pdFAIL ); + } + + if( xOkToGiveCountingSemaphore != pdFALSE ) + { + xSemaphoreGiveFromISR( xISRCountingSemaphore, &xHigherPriorityTaskWoken ); + } + xLastGiveTime = xTimeNow; + } + + /* Remove compiler warnings about the value being set but not used. */ + ( void ) xHigherPriorityTaskWoken; +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreInterruptSemaphoreTasksStillRunning( void ) +{ +static uint32_t ulLastMasterLoopCounter = 0, ulLastCountingSemaphoreLoops = 0; + + /* If the demo tasks are running then it is expected that the loop counters + will have changed since this function was last called. */ + if( ulLastMasterLoopCounter == ulMasterLoops ) + { + xErrorDetected = pdTRUE; + } + + ulLastMasterLoopCounter = ulMasterLoops; + + if( ulLastCountingSemaphoreLoops == ulCountingSemaphoreLoops ) + { + xErrorDetected = pdTRUE; + } + + ulLastCountingSemaphoreLoops = ulCountingSemaphoreLoops++; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return ( BaseType_t ) !xErrorDetected; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/PollQ.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/PollQ.c new file mode 100644 index 0000000..d03a2dd --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/PollQ.c @@ -0,0 +1,265 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This version of PollQ. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that communicate over a single queue. One task acts as a + * producer, the other a consumer. + * + * The producer loops for three iteration, posting an incrementing number onto the + * queue each cycle. It then delays for a fixed period before doing exactly the + * same again. + * + * The consumer loops emptying the queue. Each item removed from the queue is + * checked to ensure it contains the expected value. When the queue is empty it + * blocks for a fixed period, then does the same again. + * + * All queue access is performed without blocking. The consumer completely empties + * the queue each time it runs so the producer should never find the queue full. + * + * An error is flagged if the consumer obtains an unexpected value or the producer + * find the queue is full. + */ + +/* +Changes from V2.0.0 + + + Delay periods are now specified using variables and constants of + TickType_t rather than uint32_t. +*/ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "PollQ.h" + +#define pollqSTACK_SIZE configMINIMAL_STACK_SIZE +#define pollqQUEUE_SIZE ( 10 ) +#define pollqPRODUCER_DELAY ( pdMS_TO_TICKS( ( TickType_t ) 200 ) ) +#define pollqCONSUMER_DELAY ( pollqPRODUCER_DELAY - ( TickType_t ) ( 20 / portTICK_PERIOD_MS ) ) +#define pollqNO_DELAY ( ( TickType_t ) 0 ) +#define pollqVALUES_TO_PRODUCE ( ( BaseType_t ) 3 ) +#define pollqINITIAL_VALUE ( ( BaseType_t ) 0 ) + +/* The task that posts the incrementing number onto the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueProducer, pvParameters ); + +/* The task that empties the queue. */ +static portTASK_FUNCTION_PROTO( vPolledQueueConsumer, pvParameters ); + +/* Variables that are used to check that the tasks are still running with no +errors. */ +static volatile BaseType_t xPollingConsumerCount = pollqINITIAL_VALUE, xPollingProducerCount = pollqINITIAL_VALUE; + +/*-----------------------------------------------------------*/ + +void vStartPolledQueueTasks( UBaseType_t uxPriority ) +{ +static QueueHandle_t xPolledQueue; + + /* Create the queue used by the producer and consumer. */ + xPolledQueue = xQueueCreate( pollqQUEUE_SIZE, ( UBaseType_t ) sizeof( uint16_t ) ); + + if( xPolledQueue != NULL ) + { + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xPolledQueue, "Poll_Test_Queue" ); + + /* Spawn the producer and consumer. */ + xTaskCreate( vPolledQueueConsumer, "QConsNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( vPolledQueueProducer, "QProdNB", pollqSTACK_SIZE, ( void * ) &xPolledQueue, uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueProducer, pvParameters ) +{ +uint16_t usValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE, xLoop; + + for( ;; ) + { + for( xLoop = 0; xLoop < pollqVALUES_TO_PRODUCE; xLoop++ ) + { + /* Send an incrementing number on the queue without blocking. */ + if( xQueueSend( *( ( QueueHandle_t * ) pvParameters ), ( void * ) &usValue, pollqNO_DELAY ) != pdPASS ) + { + /* We should never find the queue full so if we get here there + has been an error. */ + xError = pdTRUE; + } + else + { + if( xError == pdFALSE ) + { + /* If an error has ever been recorded we stop incrementing the + check variable. */ + portENTER_CRITICAL(); + xPollingProducerCount++; + portEXIT_CRITICAL(); + } + + /* Update the value we are going to post next time around. */ + usValue++; + } + } + + /* Wait before we start posting again to ensure the consumer runs and + empties the queue. */ + vTaskDelay( pollqPRODUCER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vPolledQueueConsumer, pvParameters ) +{ +uint16_t usData, usExpectedValue = ( uint16_t ) 0; +BaseType_t xError = pdFALSE; + + for( ;; ) + { + /* Loop until the queue is empty. */ + while( uxQueueMessagesWaiting( *( ( QueueHandle_t * ) pvParameters ) ) ) + { + if( xQueueReceive( *( ( QueueHandle_t * ) pvParameters ), &usData, pollqNO_DELAY ) == pdPASS ) + { + if( usData != usExpectedValue ) + { + /* This is not what we expected to receive so an error has + occurred. */ + xError = pdTRUE; + + /* Catch-up to the value we received so our next expected + value should again be correct. */ + usExpectedValue = usData; + } + else + { + if( xError == pdFALSE ) + { + /* Only increment the check variable if no errors have + occurred. */ + portENTER_CRITICAL(); + xPollingConsumerCount++; + portEXIT_CRITICAL(); + } + } + + /* Next time round we would expect the number to be one higher. */ + usExpectedValue++; + } + } + + /* Now the queue is empty we block, allowing the producer to place more + items in the queue. */ + vTaskDelay( pollqCONSUMER_DELAY ); + } +} /*lint !e818 Function prototype must conform to API. */ +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running with no errors. */ +BaseType_t xArePollingQueuesStillRunning( void ) +{ +BaseType_t xReturn; + + /* Check both the consumer and producer poll count to check they have both + been changed since out last trip round. We do not need a critical section + around the check variables as this is called from a higher priority than + the other tasks that access the same variables. */ + if( ( xPollingConsumerCount == pollqINITIAL_VALUE ) || + ( xPollingProducerCount == pollqINITIAL_VALUE ) + ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Set the check variables back down so we know if they have been + incremented the next time around. */ + xPollingConsumerCount = pollqINITIAL_VALUE; + xPollingProducerCount = pollqINITIAL_VALUE; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QPeek.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QPeek.c new file mode 100644 index 0000000..49f0984 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QPeek.c @@ -0,0 +1,481 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the behaviour when data is peeked from a queue when there are + * multiple tasks blocked on the queue. + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "QPeek.h" + +#define qpeekQUEUE_LENGTH ( 5 ) +#define qpeekNO_BLOCK ( 0 ) +#define qpeekSHORT_DELAY ( 10 ) + +#define qpeekLOW_PRIORITY ( tskIDLE_PRIORITY + 0 ) +#define qpeekMEDIUM_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define qpeekHIGH_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define qpeekHIGHEST_PRIORITY ( tskIDLE_PRIORITY + 3 ) + +/*-----------------------------------------------------------*/ + +/* + * The following three tasks are used to demonstrate the peeking behaviour. + * Each task is given a different priority to demonstrate the order in which + * tasks are woken as data is peeked from a queue. + */ +static void prvLowPriorityPeekTask( void *pvParameters ); +static void prvMediumPriorityPeekTask( void *pvParameters ); +static void prvHighPriorityPeekTask( void *pvParameters ); +static void prvHighestPriorityPeekTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/* Counter that is incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; + +/* Handles to the test tasks. */ +TaskHandle_t xMediumPriorityTask, xHighPriorityTask, xHighestPriorityTask; +/*-----------------------------------------------------------*/ + +void vStartQueuePeekTasks( void ) +{ +QueueHandle_t xQueue; + + /* Create the queue that we are going to use for the test/demo. */ + xQueue = xQueueCreate( qpeekQUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xQueue != NULL ) + { + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xQueue, "QPeek_Test_Queue" ); + + /* Create the demo tasks and pass it the queue just created. We are + passing the queue handle by value so it does not matter that it is declared + on the stack here. */ + xTaskCreate( prvLowPriorityPeekTask, "PeekL", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekLOW_PRIORITY, NULL ); + xTaskCreate( prvMediumPriorityPeekTask, "PeekM", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekMEDIUM_PRIORITY, &xMediumPriorityTask ); + xTaskCreate( prvHighPriorityPeekTask, "PeekH1", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGH_PRIORITY, &xHighPriorityTask ); + xTaskCreate( prvHighestPriorityPeekTask, "PeekH2", configMINIMAL_STACK_SIZE, ( void * ) xQueue, qpeekHIGHEST_PRIORITY, &xHighestPriorityTask ); + } +} +/*-----------------------------------------------------------*/ + +static void prvHighestPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + #ifdef USE_STDIO + { + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Queue peek test started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + } + #endif + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the high priority task to execute. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we reach here the high and medium priority tasks should still + be blocked on the queue. We unblocked because the low priority task + wrote a value to the queue, which we should have peeked. Peeking the + data (rather than receiving it) will leave the data on the queue, so + the high priority task should then have also been unblocked, but not + yet executed. */ + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Now we are going to actually receive the data, so when the high + priority task runs it will find the queue empty and return to the + blocked state. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the value. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x11223344 ) + { + /* We did not receive the expected value - which should have been + the same value as was peeked. */ + xErrorDetected = pdTRUE; + } + + /* Now we will block again as the queue is once more empty. The low + priority task can then execute again. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the low priority task should have again written to the + queue. */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the high priority task to also peek the data. The high priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + + /* This time we are going to do the same as the above test, but the + high priority task is going to receive the data, rather than peek it. + This means that the medium priority task should never peek the value. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvHighPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the medium priority task to execute. Both the high + and highest priority tasks will then be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the highest priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* We only peeked the data, so suspending ourselves now should enable + the medium priority task to also peek the data. The medium priority task + will have been unblocked when we peeked the data as we left the data + in the queue. */ + vTaskSuspend( NULL ); + + + /* This time we are going actually receive the value, so the medium + priority task will never peek the data - we removed it from the queue. */ + if( xQueueReceive( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + xErrorDetected = pdTRUE; + } + + if( ulValue != 0xaabbaabb ) + { + xErrorDetected = pdTRUE; + } + + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvMediumPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Try peeking from the queue. The queue should be empty so we will + block, allowing the low priority task to execute. The highest, high + and medium priority tasks will then all be blocked on the queue. */ + if( xQueuePeek( xQueue, &ulValue, portMAX_DELAY ) != pdPASS ) + { + /* We expected to have received something by the time we unblock. */ + xErrorDetected = pdTRUE; + } + + /* When we get here the high priority task should have peeked the data + (unblocking this task) then suspended (allowing this task to also peek + the data). */ + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + xErrorDetected = pdTRUE; + } + + if( uxQueueMessagesWaiting( xQueue ) != 1 ) + { + /* The message should have been left on the queue. */ + xErrorDetected = pdTRUE; + } + + /* Just so we know the test is still running. */ + ulLoopCounter++; + + /* Now we can suspend ourselves so the low priority task can execute + again. */ + vTaskSuspend( NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvLowPriorityPeekTask( void *pvParameters ) +{ +QueueHandle_t xQueue = ( QueueHandle_t ) pvParameters; +uint32_t ulValue; + + for( ;; ) + { + /* Write some data to the queue. This should unblock the highest + priority task that is waiting to peek data from the queue. */ + ulValue = 0x11223344; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* By the time we get here the data should have been removed from + the queue. */ + if( uxQueueMessagesWaiting( xQueue ) != 0 ) + { + xErrorDetected = pdTRUE; + } + + /* Write another value to the queue, again waking the highest priority + task that is blocked on the queue. */ + ulValue = 0x01234567; + if( xQueueSendToBack( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* All the other tasks should now have successfully peeked the data. + The data is still in the queue so we should be able to receive it. */ + ulValue = 0; + if( xQueueReceive( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + if( ulValue != 0x01234567 ) + { + /* We did not receive the expected value. */ + } + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + + /* Unsuspend the other tasks so we can repeat the test - this time + however not all the other tasks will peek the data as the high + priority task is actually going to remove it from the queue. Send + to front is used just to be different. As the queue is empty it + makes no difference to the result. */ + vTaskResume( xMediumPriorityTask ); + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + ulValue = 0xaabbaabb; + if( xQueueSendToFront( xQueue, &ulValue, qpeekNO_BLOCK ) != pdPASS ) + { + /* We were expecting the queue to be empty so we should not of + had a problem writing to the queue. */ + xErrorDetected = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* This time we should find that the queue is empty. The high priority + task actually removed the data rather than just peeking it. */ + if( xQueuePeek( xQueue, &ulValue, qpeekNO_BLOCK ) != errQUEUE_EMPTY ) + { + /* We expected to receive the data. */ + xErrorDetected = pdTRUE; + } + + /* Unsuspend the highest and high priority tasks so we can go back + and repeat the whole thing. The medium priority task should not be + suspended as it was not able to peek the data in this last case. */ + vTaskResume( xHighPriorityTask ); + vTaskResume( xHighestPriorityTask ); + + /* Lets just delay a while as this is an intensive test as we don't + want to starve other tests of processing time. */ + vTaskDelay( qpeekSHORT_DELAY ); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreQueuePeekTasksStillRunning( void ) +{ +static uint32_t ulLastLoopCounter = 0; + + /* If the demo task is still running then we expect the loopcounter to + have incremented since this function was last called. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xErrorDetected = pdTRUE; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xErrorDetected + to true. */ + + return ( BaseType_t ) !xErrorDetected; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueOverwrite.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueOverwrite.c new file mode 100644 index 0000000..bfb875a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueOverwrite.c @@ -0,0 +1,272 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Basic task to demonstrate the xQueueOverwrite() function. See the comments + * in the function itself. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo program include files. */ +#include "QueueOverwrite.h" + +/* A block time of 0 just means "don't block". */ +#define qoDONT_BLOCK 0 + +/* Number of times to overwrite the value in the queue. */ +#define qoLOOPS 5 + +/* The task that uses the queue. */ +static void prvQueueOverwriteTask( void *pvParameters ); + +/* Variable that is incremented on each loop of prvQueueOverwriteTask() provided +prvQueueOverwriteTask() has not found any errors. */ +static uint32_t ulLoopCounter = 0; + +/* Set to pdFALSE if an error is discovered by the +vQueueOverwritePeriodicISRDemo() function. */ +static BaseType_t xISRTestStatus = pdPASS; + +/* The queue that is accessed from the ISR. The queue accessed by the task is +created inside the task itself. */ +static QueueHandle_t xISRQueue = NULL; + +/*-----------------------------------------------------------*/ + +void vStartQueueOverwriteTask( UBaseType_t uxPriority ) +{ +const UBaseType_t uxQueueLength = 1; + + /* Create the queue used by the ISR. xQueueOverwriteFromISR() should only + be used on queues that have a length of 1. */ + xISRQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) ); + + /* Create the test task. The queue used by the test task is created inside + the task itself. */ + xTaskCreate( prvQueueOverwriteTask, "QOver", configMINIMAL_STACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueOverwriteTask( void *pvParameters ) +{ +QueueHandle_t xTaskQueue; +const UBaseType_t uxQueueLength = 1; +uint32_t ulValue, ulStatus = pdPASS, x; + + /* The parameter is not used. */ + ( void ) pvParameters; + + /* Create the queue. xQueueOverwrite() should only be used on queues that + have a length of 1. */ + xTaskQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) ); + configASSERT( xTaskQueue ); + + for( ;; ) + { + /* The queue is empty. Writing to the queue then reading from the queue + should return the item written. */ + ulValue = 10; + xQueueOverwrite( xTaskQueue, &ulValue ); + + ulValue = 0; + xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); + + if( ulValue != 10 ) + { + ulStatus = pdFAIL; + } + + /* Now try writing to the queue several times. Each time the value + in the queue should get overwritten. */ + for( x = 0; x < qoLOOPS; x++ ) + { + /* Write to the queue. */ + xQueueOverwrite( xTaskQueue, &x ); + + /* Check the value in the queue is that written, even though the + queue was not necessarily empty. */ + xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK ); + if( ulValue != x ) + { + ulStatus = pdFAIL; + } + + /* There should always be one item in the queue. */ + if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength ) + { + ulStatus = pdFAIL; + } + } + + /* Empty the queue again. */ + xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); + + if( uxQueueMessagesWaiting( xTaskQueue ) != 0 ) + { + ulStatus = pdFAIL; + } + + if( ulStatus != pdFAIL ) + { + /* Increment a counter to show this task is still running without + error. */ + ulLoopCounter++; + } + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xIsQueueOverwriteTaskStillRunning( void ) +{ +BaseType_t xReturn; + + if( xISRTestStatus != pdPASS ) + { + xReturn = pdFAIL; + } + else if( ulLoopCounter > 0 ) + { + xReturn = pdPASS; + } + else + { + /* The task has either stalled of discovered an error. */ + xReturn = pdFAIL; + } + + ulLoopCounter = 0; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vQueueOverwritePeriodicISRDemo( void ) +{ +static uint32_t ulCallCount = 0; +const uint32_t ulTx1 = 10UL, ulTx2 = 20UL, ulNumberOfSwitchCases = 3UL; +uint32_t ulRx; + + /* This function should be called from an interrupt, such as the tick hook + function vApplicationTickHook(). */ + + configASSERT( xISRQueue ); + + switch( ulCallCount ) + { + case 0: + /* The queue is empty. Write ulTx1 to the queue. In this demo the + last parameter is not used because there are no tasks blocked on + this queue. */ + xQueueOverwriteFromISR( xISRQueue, &ulTx1, NULL ); + + /* Peek the queue to check it holds the expected value. */ + xQueuePeekFromISR( xISRQueue, &ulRx ); + if( ulRx != ulTx1 ) + { + xISRTestStatus = pdFAIL; + } + break; + + case 1: + /* The queue already holds ulTx1. Overwrite the value in the queue + with ulTx2. */ + xQueueOverwriteFromISR( xISRQueue, &ulTx2, NULL ); + break; + + case 2: + /* Read from the queue to empty the queue again. The value read + should be ulTx2. */ + xQueueReceiveFromISR( xISRQueue, &ulRx, NULL ); + + if( ulRx != ulTx2 ) + { + xISRTestStatus = pdFAIL; + } + break; + } + + /* Run the next case in the switch statement above next time this function + is called. */ + ulCallCount++; + + if( ulCallCount >= ulNumberOfSwitchCases ) + { + /* Go back to the start. */ + ulCallCount = 0; + } +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSet.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSet.c new file mode 100644 index 0000000..75aeb0d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSet.c @@ -0,0 +1,738 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Tests the use of queue sets. + * + * A receive task creates a number of queues and adds them to a queue set before + * blocking on the queue set receive. A transmit task and (optionally) an + * interrupt repeatedly unblocks the receive task by sending messages to the + * queues in a pseudo random order. The receive task removes the messages from + * the queues and flags an error if the received message does not match that + * expected. The task sends values in the range 0 to + * queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range + * queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX. + */ + + +/* Standard includes. */ +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "QueueSet.h" + +/* The number of queues that are created and added to the queue set. */ +#define queuesetNUM_QUEUES_IN_SET 3 + +/* The length of each created queue. */ +#define queuesetQUEUE_LENGTH 3 + +/* Block times used in this demo. A block time or 0 means "don't block". */ +#define queuesetSHORT_DELAY 200 +#define queuesetDONT_BLOCK 0 + +/* Messages are sent in incrementing order from both a task and an interrupt. +The task sends values in the range 0 to 0xfffe, and the interrupt sends values +in the range of 0xffff to ULONG_MAX. */ +#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL + +/* The priorities used in this demo. */ +#define queuesetLOW_PRIORITY ( tskIDLE_PRIORITY ) +#define queuesetMEDIUM_PRIORITY ( queuesetLOW_PRIORITY + 1 ) + +/* For test purposes the priority of the sending task is changed after every +queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */ +#define queuesetPRIORITY_CHANGE_LOOPS ( ( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ) * 2 ) + +/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */ +#define queuesetISR_TX_PERIOD ( 100UL ) + +/* A delay inserted when the Tx task changes its priority to be above the idle +task priority to ensure the idle priority tasks get some CPU time before the +next iteration of the queue set Tx task. */ +#define queuesetTX_LOOP_DELAY pdMS_TO_TICKS( ( TickType_t ) 200 ) + +/* The allowable maximum deviation between a received value and the expected +received value. A deviation will occur when data is received from a queue +inside an ISR in between a task receiving from a queue and the task checking +the received value. */ +#define queuesetALLOWABLE_RX_DEVIATION 3 + +/* Ignore values that are at the boundaries of allowable values to make the +testing of limits easier (don't have to deal with wrapping values). */ +#define queuesetIGNORED_BOUNDARY ( queuesetALLOWABLE_RX_DEVIATION * 2 ) + +typedef enum +{ + eEqualPriority = 0, /* Tx and Rx tasks have the same priority. */ + eTxHigherPriority, /* The priority of the Tx task is above that of the Rx task. */ + eTxLowerPriority /* The priority of the Tx task is below that of the Rx task. */ +} eRelativePriorities; + +/* + * The task that periodically sends to the queue set. + */ +static void prvQueueSetSendingTask( void *pvParameters ); + +/* + * The task that reads from the queue set. + */ +static void prvQueueSetReceivingTask( void *pvParameters ); + +/* + * Check the value received from a queue is the expected value. Some values + * originate from the send task, some values originate from the ISR, with the + * range of the value being used to distinguish between the two message + * sources. + */ +static void prvCheckReceivedValue( uint32_t ulReceived ); + +/* + * For purposes of test coverage, functions that read from and write to a + * queue set from an ISR respectively. + */ +static void prvReceiveFromQueueInSetFromISR( void ); +static void prvSendToQueueInSetFromISR( void ); + +/* + * Create the queues and add them to a queue set before resuming the Tx + * task. + */ +static void prvSetupTest( void ); + +/* + * Checks a value received from a queue falls within the range of expected + * values. + */ +static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived ); + +/* + * Increase test coverage by occasionally change the priorities of the two tasks + * relative to each other. */ +static void prvChangeRelativePriorities( void ); + +/* + * Local pseudo random number seed and return functions. Used to avoid calls + * to the standard library. + */ +static size_t prvRand( void ); +static void prvSRand( size_t uxSeed ); + +/*-----------------------------------------------------------*/ + +/* The queues that are added to the set. */ +static QueueHandle_t xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; + +/* Counts how many times each queue in the set is used to ensure all the +queues are used. */ +static uint32_t ulQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; + +/* The handle of the queue set to which the queues are added. */ +static QueueSetHandle_t xQueueSet; + +/* If the prvQueueSetReceivingTask() task has not detected any errors then +it increments ulCycleCounter on each iteration. +xAreQueueSetTasksStillRunning() returns pdPASS if the value of +ulCycleCounter has changed between consecutive calls, and pdFALSE if +ulCycleCounter has stopped incrementing (indicating an error condition). */ +static volatile uint32_t ulCycleCounter = 0UL; + +/* Set to pdFAIL if an error is detected by any queue set task. +ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */ +static volatile BaseType_t xQueueSetTasksStatus = pdPASS; + +/* Just a flag to let the function that writes to a queue from an ISR know that +the queues are setup and can be used. */ +static volatile BaseType_t xSetupComplete = pdFALSE; + +/* The value sent to the queue from the ISR is file scope so the +xAreQueeuSetTasksStillRunning() function can check it is incrementing as +expected. */ +static volatile uint32_t ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE; + +/* Used by the pseudo random number generator. */ +static size_t uxNextRand = 0; + +/* The task handles are stored so their priorities can be changed. */ +TaskHandle_t xQueueSetSendingTask, xQueueSetReceivingTask; + +/*-----------------------------------------------------------*/ + +void vStartQueueSetTasks( void ) +{ + /* Create the tasks. */ + xTaskCreate( prvQueueSetSendingTask, "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask ); + + if( xQueueSetSendingTask != NULL ) + { + xTaskCreate( prvQueueSetReceivingTask, "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, &xQueueSetReceivingTask ); + + /* It is important that the sending task does not attempt to write to a + queue before the queue has been created. It is therefore placed into + the suspended state before the scheduler has started. It is resumed by + the receiving task after the receiving task has created the queues and + added the queues to the queue set. */ + vTaskSuspend( xQueueSetSendingTask ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreQueueSetTasksStillRunning( void ) +{ +static uint32_t ulLastCycleCounter, ulLastISRTxValue = 0; +static uint32_t ulLastQueueUsedCounter[ queuesetNUM_QUEUES_IN_SET ] = { 0 }; +BaseType_t xReturn = pdPASS, x; + + if( ulLastCycleCounter == ulCycleCounter ) + { + /* The cycle counter is no longer being incremented. Either one of the + tasks is stalled or an error has been detected. */ + xReturn = pdFAIL; + } + + ulLastCycleCounter = ulCycleCounter; + + /* Ensure that all the queues in the set have been used. This ensures the + test is working as intended and guards against the rand() in the Tx task + missing some values. */ + for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) + { + if( ulLastQueueUsedCounter[ x ] == ulQueueUsedCounter[ x ] ) + { + xReturn = pdFAIL; + } + + ulLastQueueUsedCounter[ x ] = ulQueueUsedCounter[ x ]; + } + + /* Check the global status flag. */ + if( xQueueSetTasksStatus != pdPASS ) + { + xReturn = pdFAIL; + } + + /* Check that the ISR is still sending values to the queues too. */ + if( ulISRTxValue == ulLastISRTxValue ) + { + xReturn = pdFAIL; + } + else + { + ulLastISRTxValue = ulISRTxValue; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvQueueSetSendingTask( void *pvParameters ) +{ +uint32_t ulTaskTxValue = 0; +size_t uxQueueToWriteTo; +QueueHandle_t xQueueInUse; + + /* Remove compiler warning about the unused parameter. */ + ( void ) pvParameters; + + /* Seed mini pseudo random number generator. */ + prvSRand( ( size_t ) &ulTaskTxValue ); + + for( ;; ) + { + /* Generate the index for the queue to which a value is to be sent. */ + uxQueueToWriteTo = prvRand() % queuesetNUM_QUEUES_IN_SET; + xQueueInUse = xQueues[ uxQueueToWriteTo ]; + + /* Note which index is being written to to ensure all the queues are + used. */ + ( ulQueueUsedCounter[ uxQueueToWriteTo ] )++; + + /* Send to the queue to unblock the task that is waiting for data to + arrive on a queue within the queue set to which this queue belongs. */ + if( xQueueSendToBack( xQueueInUse, &ulTaskTxValue, portMAX_DELAY ) != pdPASS ) + { + /* The send should always pass as an infinite block time was + used. */ + xQueueSetTasksStatus = pdFAIL; + } + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + ulTaskTxValue++; + + /* If the Tx value has reached the range used by the ISR then set it + back to 0. */ + if( ulTaskTxValue == queuesetINITIAL_ISR_TX_VALUE ) + { + ulTaskTxValue = 0; + } + + /* Increase test coverage by occasionally change the priorities of the + two tasks relative to each other. */ + prvChangeRelativePriorities(); + } +} +/*-----------------------------------------------------------*/ + +static void prvChangeRelativePriorities( void ) +{ +static UBaseType_t ulLoops = 0; +static eRelativePriorities ePriorities = eEqualPriority; + + /* Occasionally change the task priority relative to the priority of + the receiving task. */ + ulLoops++; + if( ulLoops >= queuesetPRIORITY_CHANGE_LOOPS ) + { + ulLoops = 0; + + switch( ePriorities ) + { + case eEqualPriority: + /* Both tasks are running with medium priority. Now lower the + priority of the receiving task so the Tx task has the higher + relative priority. */ + vTaskPrioritySet( xQueueSetReceivingTask, queuesetLOW_PRIORITY ); + ePriorities = eTxHigherPriority; + break; + + case eTxHigherPriority: + /* The Tx task is running with a higher priority than the Rx + task. Switch the priorities around so the Rx task has the + higher relative priority. */ + vTaskPrioritySet( xQueueSetReceivingTask, queuesetMEDIUM_PRIORITY ); + vTaskPrioritySet( xQueueSetSendingTask, queuesetLOW_PRIORITY ); + ePriorities = eTxLowerPriority; + break; + + case eTxLowerPriority: + /* The Tx task is running with a lower priority than the Rx + task. Make the priorities equal again. */ + vTaskPrioritySet( xQueueSetSendingTask, queuesetMEDIUM_PRIORITY ); + ePriorities = eEqualPriority; + + /* When both tasks are using a non-idle priority the queue set + tasks will starve idle priority tasks of execution time - so + relax a bit before the next iteration to minimise the impact. */ + vTaskDelay( queuesetTX_LOOP_DELAY ); + + break; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueSetReceivingTask( void *pvParameters ) +{ +uint32_t ulReceived; +QueueHandle_t xActivatedQueue; +TickType_t xBlockTime; + + /* Remove compiler warnings. */ + ( void ) pvParameters; + + /* Create the queues and add them to the queue set before resuming the Tx + task. */ + prvSetupTest(); + + for( ;; ) + { + /* For test coverage reasons, the block time is dependent on the + priority of this task - which changes during the test. When the task + is at the idle priority it polls the queue set. */ + if( uxTaskPriorityGet( NULL ) == tskIDLE_PRIORITY ) + { + xBlockTime = 0; + } + else + { + xBlockTime = portMAX_DELAY; + } + + /* Wait for a message to arrive on one of the queues in the set. */ + xActivatedQueue = xQueueSelectFromSet( xQueueSet, portMAX_DELAY ); + + if( xActivatedQueue == NULL ) + { + if( xBlockTime != 0 ) + { + /* This should not happen as an infinite delay was used. */ + xQueueSetTasksStatus = pdFAIL; + } + } + else + { + /* Reading from the queue should pass with a zero block time as + this task will only run when something has been posted to a task + in the queue set. */ + if( xQueueReceive( xActivatedQueue, &ulReceived, queuesetDONT_BLOCK ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Ensure the value received was the value expected. This function + manipulates file scope data and is also called from an ISR, hence + the critical section. */ + taskENTER_CRITICAL(); + { + prvCheckReceivedValue( ulReceived ); + } + taskEXIT_CRITICAL(); + + if( xQueueSetTasksStatus == pdPASS ) + { + ulCycleCounter++; + } + } + } +} +/*-----------------------------------------------------------*/ + +void vQueueSetAccessQueueSetFromISR( void ) +{ +static uint32_t ulCallCount = 0; + + /* xSetupComplete is set to pdTRUE when the queues have been created and + are available for use. */ + if( xSetupComplete == pdTRUE ) + { + /* It is intended that this function is called from the tick hook + function, so each call is one tick period apart. */ + ulCallCount++; + if( ulCallCount > queuesetISR_TX_PERIOD ) + { + ulCallCount = 0; + + /* First attempt to read from the queue set. */ + prvReceiveFromQueueInSetFromISR(); + + /* Then write to the queue set. */ + prvSendToQueueInSetFromISR(); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckReceivedValue( uint32_t ulReceived ) +{ +static uint32_t ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE; + + /* Values are received in tasks and interrupts. It is likely that the + receiving task will sometimes get preempted by the receiving interrupt + between reading a value from the queue and calling this function. When + that happens, if the receiving interrupt calls this function the values + will get passed into this function slightly out of order. For that + reason the value passed in is tested against a small range of expected + values, rather than a single absolute value. To make the range testing + easier values in the range limits are ignored. */ + + /* If the received value is equal to or greater than + queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */ + if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE ) + { + /* The value was sent from the ISR. */ + if( ( ulReceived - queuesetINITIAL_ISR_TX_VALUE ) < queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the lower limit of the expected range. + Don't test it and expect to receive one higher next time. */ + } + else if( ( ULONG_MAX - ulReceived ) <= queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the higher limit of the expected range. + Don't test it and expect to wrap soon. */ + } + else + { + /* Check the value against its expected value range. */ + if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromISR ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + + configASSERT( xQueueSetTasksStatus ); + + /* It is expected to receive an incrementing number. */ + ulExpectedReceivedFromISR++; + if( ulExpectedReceivedFromISR == 0 ) + { + ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE; + } + } + else + { + /* The value was sent from the Tx task. */ + if( ulReceived < queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the lower limit of the expected range. + Don't test it, and expect to receive one higher next time. */ + } + else if( ( ( queuesetINITIAL_ISR_TX_VALUE - 1 ) - ulReceived ) <= queuesetIGNORED_BOUNDARY ) + { + /* The value received is at the higher limit of the expected range. + Don't test it and expect to wrap soon. */ + } + else + { + /* Check the value against its expected value range. */ + if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromTask ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + + configASSERT( xQueueSetTasksStatus ); + + /* It is expected to receive an incrementing number. */ + ulExpectedReceivedFromTask++; + if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE ) + { + ulExpectedReceivedFromTask = 0; + } + } +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvCheckReceivedValueWithinExpectedRange( uint32_t ulReceived, uint32_t ulExpectedReceived ) +{ +BaseType_t xReturn = pdPASS; + + if( ulReceived > ulExpectedReceived ) + { + configASSERT( ( ulReceived - ulExpectedReceived ) <= queuesetALLOWABLE_RX_DEVIATION ); + if( ( ulReceived - ulExpectedReceived ) > queuesetALLOWABLE_RX_DEVIATION ) + { + xReturn = pdFALSE; + } + } + else + { + configASSERT( ( ulExpectedReceived - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION ); + if( ( ulExpectedReceived - ulReceived ) > queuesetALLOWABLE_RX_DEVIATION ) + { + xReturn = pdFALSE; + } + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvReceiveFromQueueInSetFromISR( void ) +{ +QueueSetMemberHandle_t xActivatedQueue; +uint32_t ulReceived; + + /* See if any of the queues in the set contain data. */ + xActivatedQueue = xQueueSelectFromSetFromISR( xQueueSet ); + + if( xActivatedQueue != NULL ) + { + /* Reading from the queue for test purposes only. */ + if( xQueueReceiveFromISR( xActivatedQueue, &ulReceived, NULL ) != pdPASS ) + { + /* Data should have been available as the handle was returned from + xQueueSelectFromSetFromISR(). */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Ensure the value received was the value expected. */ + prvCheckReceivedValue( ulReceived ); + } +} +/*-----------------------------------------------------------*/ + +static void prvSendToQueueInSetFromISR( void ) +{ +static BaseType_t xQueueToWriteTo = 0; + + if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulISRTxValue, NULL ) == pdPASS ) + { + ulISRTxValue++; + + /* If the Tx value has wrapped then set it back to its initial value. */ + if( ulISRTxValue == 0UL ) + { + ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE; + } + + /* Use a different queue next time. */ + xQueueToWriteTo++; + if( xQueueToWriteTo >= queuesetNUM_QUEUES_IN_SET ) + { + xQueueToWriteTo = 0; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSetupTest( void ) +{ +BaseType_t x; +uint32_t ulValueToSend = 0; + + /* Ensure the queues are created and the queue set configured before the + sending task is unsuspended. + + First Create the queue set such that it will be able to hold a message for + every space in every queue in the set. */ + xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ); + + for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) + { + /* Create the queue and add it to the set. The queue is just holding + uint32_t value. */ + xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( uint32_t ) ); + configASSERT( xQueues[ x ] ); + if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS ) + { + xQueueSetTasksStatus = pdFAIL; + } + else + { + /* The queue has now been added to the queue set and cannot be added to + another. */ + if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL ) + { + xQueueSetTasksStatus = pdFAIL; + } + } + } + + /* Attempt to remove a queue from a queue set it does not belong + to (NULL being passed as the queue set in this case). */ + if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL ) + { + /* It is not possible to successfully remove a queue from a queue + set it does not belong to. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Attempt to remove a queue from the queue set it does belong to. */ + if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) + { + /* It should be possible to remove the queue from the queue set it + does belong to. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Add an item to the queue before attempting to add it back into the + set. */ + xQueueSend( xQueues[ 0 ], ( void * ) &ulValueToSend, 0 ); + if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdFAIL ) + { + /* Should not be able to add a non-empty queue to a set. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* Remove the item from the queue before adding the queue back into the + set so the dynamic tests can begin. */ + xQueueReceive( xQueues[ 0 ], &ulValueToSend, 0 ); + if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) + { + /* If the queue was successfully removed from the queue set then it + should be possible to add it back in again. */ + xQueueSetTasksStatus = pdFAIL; + } + + /* The task that sends to the queues is not running yet, so attempting to + read from the queue set should fail. */ + if( xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY ) != NULL ) + { + xQueueSetTasksStatus = pdFAIL; + } + + /* Resume the task that writes to the queues. */ + vTaskResume( xQueueSetSendingTask ); + + /* Let the ISR access the queues also. */ + xSetupComplete = pdTRUE; +} +/*-----------------------------------------------------------*/ + +static size_t prvRand( void ) +{ + uxNextRand = ( uxNextRand * ( size_t ) 1103515245 ) + ( size_t ) 12345; + return ( uxNextRand / ( size_t ) 65536 ) % ( size_t ) 32768; +} +/*-----------------------------------------------------------*/ + +static void prvSRand( size_t uxSeed ) +{ + uxNextRand = uxSeed; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSetPolling.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSetPolling.c new file mode 100644 index 0000000..db3644d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/QueueSetPolling.c @@ -0,0 +1,221 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Tests the use of queue sets. + * + * A receive task creates a number of queues and adds them to a queue set before + * blocking on the queue set receive. A transmit task and (optionally) an + * interrupt repeatedly unblocks the receive task by sending messages to the + * queues in a pseudo random order. The receive task removes the messages from + * the queues and flags an error if the received message does not match that + * expected. The task sends values in the range 0 to + * queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range + * queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX. + */ + + +/* Standard includes. */ +#include +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "QueueSetPolling.h" + +/* The length of each created queue. */ +#define setpollQUEUE_LENGTH 10 + +/* Block times used in this demo. A block time or 0 means "don't block". */ +#define setpollDONT_BLOCK 0 + +/* The ISR sends to the queue every setpollISR_TX_PERIOD ticks. */ +#define queuesetISR_TX_PERIOD ( 50UL ) + +/* + * The task that reads from the queue set. + */ +static void prvQueueSetReceivingTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The queue that is added to the set. */ +static QueueHandle_t xQueue = NULL; + +/* The handle of the queue set to which the queue is added. */ +static QueueSetHandle_t xQueueSet = NULL; + +/* Set to pdFAIL if an error is detected by any queue set task. +ulCycleCounter will only be incremented if xQueueSetTasksSatus equals pdPASS. */ +static volatile BaseType_t xQueueSetPollStatus = pdPASS; + +/* Counter used to ensure the task is still running. */ +static uint32_t ulCycleCounter = 0; + +/*-----------------------------------------------------------*/ + +void vStartQueueSetPollingTask( void ) +{ + /* Create the queue that is added to the set, the set, and add the queue to + the set. */ + xQueue = xQueueCreate( setpollQUEUE_LENGTH, sizeof( uint32_t ) ); + xQueueSet = xQueueCreateSet( setpollQUEUE_LENGTH ); + + if( ( xQueue != NULL ) && ( xQueueSet != NULL ) ) + { + xQueueAddToSet( xQueue, xQueueSet ); + + /* Create the task. */ + xTaskCreate( prvQueueSetReceivingTask, "SetPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueSetReceivingTask( void *pvParameters ) +{ +uint32_t ulReceived, ulExpected = 0; +QueueHandle_t xActivatedQueue; + + /* Remove compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Is a message waiting? A block time is not used to ensure the queue + set is polled while it is being written to from an interrupt. */ + xActivatedQueue = xQueueSelectFromSet( xQueueSet, setpollDONT_BLOCK ); + + if( xActivatedQueue != NULL ) + { + /* Reading from the queue should pass with a zero block time as + this task will only run when something has been posted to a task + in the queue set. */ + if( xQueueReceive( xActivatedQueue, &ulReceived, setpollDONT_BLOCK ) != pdPASS ) + { + xQueueSetPollStatus = pdFAIL; + } + + if( ulReceived == ulExpected ) + { + ulExpected++; + } + else + { + xQueueSetPollStatus = pdFAIL; + } + + if( xQueueSetPollStatus == pdPASS ) + { + ulCycleCounter++; + } + } + } +} +/*-----------------------------------------------------------*/ + +void vQueueSetPollingInterruptAccess( void ) +{ +static uint32_t ulCallCount = 0, ulValueToSend = 0; + + /* It is intended that this function is called from the tick hook + function, so each call is one tick period apart. */ + ulCallCount++; + if( ulCallCount > queuesetISR_TX_PERIOD ) + { + ulCallCount = 0; + + if( xQueueSendFromISR( xQueue, ( void * ) &ulValueToSend, NULL ) == pdPASS ) + { + /* Send the next value next time. */ + ulValueToSend++; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreQueueSetPollTasksStillRunning( void ) +{ +static uint32_t ulLastCycleCounter = 0; + + if( ulLastCycleCounter == ulCycleCounter ) + { + xQueueSetPollStatus = pdFAIL; + } + + ulLastCycleCounter = ulCycleCounter; + + return xQueueSetPollStatus; +} +/*-----------------------------------------------------------*/ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/StaticAllocation.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/StaticAllocation.c new file mode 100644 index 0000000..2a111e4 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/StaticAllocation.c @@ -0,0 +1,1148 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Demonstrates how to create FreeRTOS objects using pre-allocated memory, + * rather than the normal dynamically allocated memory, and tests objects being + * created and deleted with both statically allocated memory and dynamically + * allocated memory. + * + * See http://www.FreeRTOS.org/Static_Vs_Dynamic_Memory_Allocation.html + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "semphr.h" +#include "event_groups.h" +#include "timers.h" + +/* Demo program include files. */ +#include "StaticAllocation.h" + +/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + +/* The priority at which the task that performs the tests is created. */ +#define staticTASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) + +/* The length of the queue, in items, not bytes, used in the queue static +allocation tests. */ +#define staticQUEUE_LENGTH_IN_ITEMS ( 5 ) + +/* A block time of 0 simply means "don't block". */ +#define staticDONT_BLOCK ( ( TickType_t ) 0 ) + +/* Binary semaphores have a maximum count of 1. */ +#define staticBINARY_SEMAPHORE_MAX_COUNT ( 1 ) + +/* The size of the stack used by the task that runs the tests. */ +#define staticCREATOR_TASK_STACK_SIZE ( configMINIMAL_STACK_SIZE * 2 ) + +/* The number of times the software timer will execute before stopping itself. */ +#define staticMAX_TIMER_CALLBACK_EXECUTIONS ( 5 ) + + +/*-----------------------------------------------------------*/ + +/* + * The task that repeatedly creates and deletes statically allocated tasks, and + * other RTOS objects. + */ +static void prvStaticallyAllocatedCreator( void *pvParameters ); + +/* + * The callback function used by the software timer that is repeatedly created + * and deleted using both static and dynamically allocated memory. + */ +static void prvTimerCallback( TimerHandle_t xExpiredTimer ); + +/* + * A task that is created and deleted multiple times, using both statically and + * dynamically allocated stack and TCB. + */ +static void prvStaticallyAllocatedTask( void *pvParameters ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete tasks using both statically and dynamically allocated TCBs and stacks. + */ +static void prvCreateAndDeleteStaticallyAllocatedTasks( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete event groups using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete queues using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedQueues( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete binary semaphores using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete software timers using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedTimers( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete mutexes using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete counting semaphores using both statically and dynamically allocated + * RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ); + +/* + * A function that demonstrates and tests the API functions that create and + * delete recursive mutexes using both statically and dynamically allocated RAM. + */ +static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ); + +/* + * Utility function to create pseudo random numbers. + */ +static UBaseType_t prvRand( void ); + +/* + * The task that creates and deletes other tasks has to delay occasionally to + * ensure lower priority tasks are not starved of processing time. A pseudo + * random delay time is used just to add a little bit of randomisation into the + * execution pattern. prvGetNextDelayTime() generates the pseudo random delay. + */ +static TickType_t prvGetNextDelayTime( void ); + +/* + * Checks the basic operation of a queue after it has been created. + */ +static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ); + +/* + * Checks the basic operation of a recursive mutex after it has been created. + */ +static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ); + +/* + * Checks the basic operation of a binary semaphore after it has been created. + */ +static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount ); + +/* + * Checks the basic operation of an event group after it has been created. + */ +static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ); + +/*-----------------------------------------------------------*/ + +/* StaticTask_t is a publicly accessible structure that has the same size and +alignment requirements as the real TCB structure. It is provided as a mechanism +for applications to know the size of the TCB (which is dependent on the +architecture and configuration file settings) without breaking the strict data +hiding policy by exposing the real TCB. This StaticTask_t variable is passed +into the xTaskCreateStatic() function that creates the +prvStaticallyAllocatedCreator() task, and will hold the TCB of the created +tasks. */ +static StaticTask_t xCreatorTaskTCBBuffer; + +/* This is the stack that will be used by the prvStaticallyAllocatedCreator() +task, which is itself created using statically allocated buffers (so without any +dynamic memory allocation). */ +static StackType_t uxCreatorTaskStackBuffer[ staticCREATOR_TASK_STACK_SIZE ]; + +/* Used by the pseudo random number generating function. */ +static uint32_t ulNextRand = 0; + +/* Used so a check task can ensure this test is still executing, and not +stalled. */ +static volatile UBaseType_t uxCycleCounter = 0; + +/* A variable that gets set to pdTRUE if an error is detected. */ +static volatile BaseType_t xErrorOccurred = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartStaticallyAllocatedTasks( void ) +{ + /* Create a single task, which then repeatedly creates and deletes the other + RTOS objects using both statically and dynamically allocated RAM. */ + xTaskCreateStatic( prvStaticallyAllocatedCreator, /* The function that implements the task being created. */ + "StatCreate", /* Text name for the task - not used by the RTOS, its just to assist debugging. */ + staticCREATOR_TASK_STACK_SIZE, /* Size of the buffer passed in as the stack - in words, not bytes! */ + NULL, /* Parameter passed into the task - not used in this case. */ + staticTASK_PRIORITY, /* Priority of the task. */ + &( uxCreatorTaskStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ + &xCreatorTaskTCBBuffer ); /* The variable that will hold the task's TCB. */ +} +/*-----------------------------------------------------------*/ + +static void prvStaticallyAllocatedCreator( void *pvParameters ) +{ + /* Avoid compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Loop, running functions that create and delete the various RTOS + objects that can be optionally created using either static or dynamic + memory allocation. */ + prvCreateAndDeleteStaticallyAllocatedTasks(); + prvCreateAndDeleteStaticallyAllocatedQueues(); + + /* Delay to ensure lower priority tasks get CPU time, and increment the + cycle counter so a 'check' task can determine that this task is still + executing. */ + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedBinarySemaphores(); + prvCreateAndDeleteStaticallyAllocatedCountingSemaphores(); + + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedMutexes(); + prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes(); + + vTaskDelay( prvGetNextDelayTime() ); + uxCycleCounter++; + + prvCreateAndDeleteStaticallyAllocatedEventGroups(); + prvCreateAndDeleteStaticallyAllocatedTimers(); + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedCountingSemaphores( void ) +{ +SemaphoreHandle_t xSemaphore; +const UBaseType_t uxMaxCount = ( UBaseType_t ) 10; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size +and alignment requirements as the real semaphore structure. It is provided as a +mechanism for applications to know the size of the semaphore (which is dependent +on the architecture and configuration file settings) without breaking the strict +data hiding policy by exposing the real semaphore internals. This +StaticSemaphore_t variable is passed into the xSemaphoreCreateCountingStatic() +function calls within this function. NOTE: In most usage scenarios now it is +faster and more memory efficient to use a direct to task notification instead of +a counting semaphore. http://www.freertos.org/RTOS-task-notifications.html */ +StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateCountingStatic() has one more + parameter than the usual xSemaphoreCreateCounting() function. The parameter + is a pointer to the pre-allocated StaticSemaphore_t structure, which will + hold information on the semaphore in an anonymous way. If the pointer is + passed as NULL then the structure will be allocated dynamically, just as + when xSemaphoreCreateCounting() is called. */ + xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, 0, &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Now do the same but using dynamically allocated buffers to ensure the + delete functions are working correctly in both the static and dynamic + allocation cases. */ + xSemaphore = xSemaphoreCreateCounting( uxMaxCount, 0 ); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedSemaphore( xSemaphore, uxMaxCount ); + vSemaphoreDelete( xSemaphore ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedRecursiveMutexes( void ) +{ +SemaphoreHandle_t xSemaphore; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size +and alignment requirements as the real semaphore structure. It is provided as a +mechanism for applications to know the size of the semaphore (which is dependent +on the architecture and configuration file settings) without breaking the strict +data hiding policy by exposing the real semaphore internals. This +StaticSemaphore_t variable is passed into the +xSemaphoreCreateRecursiveMutexStatic() function calls within this function. */ +StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateRecursiveMutexStatic() has one + more parameter than the usual xSemaphoreCreateRecursiveMutex() function. + The parameter is a pointer to the pre-allocated StaticSemaphore_t structure, + which will hold information on the semaphore in an anonymous way. If the + pointer is passed as NULL then the structure will be allocated dynamically, + just as when xSemaphoreCreateRecursiveMutex() is called. */ + xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid + recursive semaphore. */ + prvSanityCheckCreatedRecursiveMutex( xSemaphore ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using dynamically allocated buffers to ensure the delete + functions are working correctly in both the static and dynamic memory + allocation cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateRecursiveMutex(); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedRecursiveMutex( xSemaphore ); + vSemaphoreDelete( xSemaphore ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedQueues( void ) +{ +QueueHandle_t xQueue; + +/* StaticQueue_t is a publicly accessible structure that has the same size and +alignment requirements as the real queue structure. It is provided as a +mechanism for applications to know the size of the queue (which is dependent on +the architecture and configuration file settings) without breaking the strict +data hiding policy by exposing the real queue internals. This StaticQueue_t +variable is passed into the xQueueCreateStatic() function calls within this +function. */ +static StaticQueue_t xStaticQueue; + +/* The queue storage area must be large enough to hold the maximum number of +items it is possible for the queue to hold at any one time, which equals the +queue length (in items, not bytes) multiplied by the size of each item. In this +case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See +http://www.freertos.org/Embedded-RTOS-Queues.html */ +static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ]; + + /* Create the queue. xQueueCreateStatic() has two more parameters than the + usual xQueueCreate() function. The first new parameter is a pointer to the + pre-allocated queue storage area. The second new parameter is a pointer to + the StaticQueue_t structure that will hold the queue state information in + an anonymous way. If the two pointers are passed as NULL then the data + will be allocated dynamically as if xQueueCreate() had been called. */ + xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ + sizeof( uint64_t ), /* The size of each item. */ + ucQueueStorageArea, /* The buffer used to hold items within the queue. */ + &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */ + + /* The queue handle should equal the static queue structure passed into the + xQueueCreateStatic() function. */ + configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue ); + + /* Ensure the queue passes a few sanity checks as a valid queue. */ + prvSanityCheckCreatedQueue( xQueue ); + + /* Delete the queue again so the buffers can be reused. */ + vQueueDelete( xQueue ); + + /* Now do the same using a dynamically allocated queue to ensure the delete + function is working correctly in both the static and dynamic memory + allocation cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ + sizeof( uint64_t ) ); /* The size of each item. */ + + /* The queue handle should equal the static queue structure passed into the + xQueueCreateStatic() function. */ + configASSERT( xQueue != NULL ); + + /* Ensure the queue passes a few sanity checks as a valid queue. */ + prvSanityCheckCreatedQueue( xQueue ); + + /* Delete the queue again so the buffers can be reused. */ + vQueueDelete( xQueue ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedMutexes( void ) +{ +SemaphoreHandle_t xSemaphore; +BaseType_t xReturned; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size +and alignment requirements as the real semaphore structure. It is provided as a +mechanism for applications to know the size of the semaphore (which is dependent +on the architecture and configuration file settings) without breaking the strict +data hiding policy by exposing the real semaphore internals. This +StaticSemaphore_t variable is passed into the xSemaphoreCreateMutexStatic() +function calls within this function. */ +StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateMutexStatic() has one more + parameter than the usual xSemaphoreCreateMutex() function. The parameter + is a pointer to the pre-allocated StaticSemaphore_t structure, which will + hold information on the semaphore in an anonymous way. If the pointer is + passed as NULL then the structure will be allocated dynamically, just as + when xSemaphoreCreateMutex() is called. */ + xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + into the xSemaphoreCreateMutexStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Take the mutex so the mutex is in the state expected by the + prvSanityCheckCreatedSemaphore() function. */ + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using a dynamically allocated mutex to ensure the delete + function is working correctly in both the static and dynamic allocation + cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateMutex(); + + /* The semaphore handle should equal the static semaphore structure + passed into the xSemaphoreCreateMutexStatic() function. */ + configASSERT( xSemaphore != NULL ); + + /* Take the mutex so the mutex is in the state expected by the + prvSanityCheckCreatedSemaphore() function. */ + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedBinarySemaphores( void ) +{ +SemaphoreHandle_t xSemaphore; + +/* StaticSemaphore_t is a publicly accessible structure that has the same size +and alignment requirements as the real semaphore structure. It is provided as a +mechanism for applications to know the size of the semaphore (which is dependent +on the architecture and configuration file settings) without breaking the strict +data hiding policy by exposing the real semaphore internals. This +StaticSemaphore_t variable is passed into the xSemaphoreCreateBinaryStatic() +function calls within this function. NOTE: In most usage scenarios now it is +faster and more memory efficient to use a direct to task notification instead of +a binary semaphore. http://www.freertos.org/RTOS-task-notifications.html */ +StaticSemaphore_t xSemaphoreBuffer; + + /* Create the semaphore. xSemaphoreCreateBinaryStatic() has one more + parameter than the usual xSemaphoreCreateBinary() function. The parameter + is a pointer to the pre-allocated StaticSemaphore_t structure, which will + hold information on the semaphore in an anonymous way. If the pointer is + passed as NULL then the structure will be allocated dynamically, just as + when xSemaphoreCreateBinary() is called. */ + xSemaphore = xSemaphoreCreateBinaryStatic( &xSemaphoreBuffer ); + + /* The semaphore handle should equal the static semaphore structure passed + into the xSemaphoreCreateBinaryStatic() function. */ + configASSERT( xSemaphore == ( SemaphoreHandle_t ) &xSemaphoreBuffer ); + + /* Ensure the semaphore passes a few sanity checks as a valid semaphore. */ + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + + /* Delete the semaphore again so the buffers can be reused. */ + vSemaphoreDelete( xSemaphore ); + + /* Now do the same using a dynamically allocated semaphore to check the + delete function is working correctly in both the static and dynamic + allocation cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xSemaphore = xSemaphoreCreateBinary(); + configASSERT( xSemaphore != NULL ); + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + vSemaphoreDelete( xSemaphore ); + } + #endif + + /* There isn't a static version of the old and deprecated + vSemaphoreCreateBinary() macro (because its deprecated!), but check it is + still functioning correctly. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + vSemaphoreCreateBinary( xSemaphore ); + + /* The macro starts with the binary semaphore available, but the test + function expects it to be unavailable. */ + if( xSemaphoreTake( xSemaphore, staticDONT_BLOCK ) == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + prvSanityCheckCreatedSemaphore( xSemaphore, staticBINARY_SEMAPHORE_MAX_COUNT ); + vSemaphoreDelete( xSemaphore ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvTimerCallback( TimerHandle_t xExpiredTimer ) +{ +UBaseType_t *puxVariableToIncrement; +BaseType_t xReturned; + + /* The timer callback just demonstrates it is executing by incrementing a + variable - the address of which is passed into the timer as its ID. Obtain + the address of the variable to increment. */ + puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + + /* Increment the variable to show the timer callback has executed. */ + ( *puxVariableToIncrement )++; + + /* If this callback has executed the required number of times, stop the + timer. */ + if( *puxVariableToIncrement == staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + /* This is called from a timer callback so must not block. See + http://www.FreeRTOS.org/FreeRTOS-timers-xTimerStop.html */ + xReturned = xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedTimers( void ) +{ +TimerHandle_t xTimer; +UBaseType_t uxVariableToIncrement; +const TickType_t xTimerPeriod = pdMS_TO_TICKS( 20 ); +BaseType_t xReturned; + +/* StaticTimer_t is a publicly accessible structure that has the same size +and alignment requirements as the real timer structure. It is provided as a +mechanism for applications to know the size of the timer structure (which is +dependent on the architecture and configuration file settings) without breaking +the strict data hiding policy by exposing the real timer internals. This +StaticTimer_t variable is passed into the xTimerCreateStatic() function calls +within this function. */ +StaticTimer_t xTimerBuffer; + + /* Create the software time. xTimerCreateStatic() has an extra parameter + than the normal xTimerCreate() API function. The parameter is a pointer to + the StaticTimer_t structure that will hold the software timer structure. If + the parameter is passed as NULL then the structure will be allocated + dynamically, just as if xTimerCreate() had been called. */ + xTimer = xTimerCreateStatic( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ + xTimerPeriod, /* The period of the timer in ticks. */ + pdTRUE, /* This is an auto-reload timer. */ + ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ + prvTimerCallback, /* The function to execute when the timer expires. */ + &xTimerBuffer ); /* The buffer that will hold the software timer structure. */ + + /* The timer handle should equal the static timer structure passed into the + xTimerCreateStatic() function. */ + configASSERT( xTimer == ( TimerHandle_t ) &xTimerBuffer ); + + /* Set the variable to 0, wait for a few timer periods to expire, then check + the timer callback has incremented the variable to the expected value. */ + uxVariableToIncrement = 0; + + /* This is a low priority so a block time should not be needed. */ + xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); + + /* By now the timer should have expired staticMAX_TIMER_CALLBACK_EXECUTIONS + times, and then stopped itself. */ + if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + xErrorOccurred = pdTRUE; + } + + /* Finished with the timer, delete it. */ + xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); + + /* Again, as this is a low priority task it is expected that the timer + command will have been sent even without a block time being used. */ + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Just to show the check task that this task is still executing. */ + uxCycleCounter++; + + /* Now do the same using a dynamically allocated software timer to ensure + the delete function is working correctly in both the static and dynamic + allocation cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xTimer = xTimerCreate( "T1", /* Text name for the task. Helps debugging only. Not used by FreeRTOS. */ + xTimerPeriod, /* The period of the timer in ticks. */ + pdTRUE, /* This is an auto-reload timer. */ + ( void * ) &uxVariableToIncrement, /* The variable incremented by the test is passed into the timer callback using the timer ID. */ + prvTimerCallback ); /* The function to execute when the timer expires. */ + + configASSERT( xTimer != NULL ); + + uxVariableToIncrement = 0; + xReturned = xTimerStart( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + vTaskDelay( xTimerPeriod * staticMAX_TIMER_CALLBACK_EXECUTIONS ); + + if( uxVariableToIncrement != staticMAX_TIMER_CALLBACK_EXECUTIONS ) + { + xErrorOccurred = pdTRUE; + } + + xReturned = xTimerDelete( xTimer, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedEventGroups( void ) +{ +EventGroupHandle_t xEventGroup; + +/* StaticEventGroup_t is a publicly accessible structure that has the same size +and alignment requirements as the real event group structure. It is provided as +a mechanism for applications to know the size of the event group (which is +dependent on the architecture and configuration file settings) without breaking +the strict data hiding policy by exposing the real event group internals. This +StaticEventGroup_t variable is passed into the xSemaphoreCreateEventGroupStatic() +function calls within this function. */ +StaticEventGroup_t xEventGroupBuffer; + + /* Create the event group. xEventGroupCreateStatic() has an extra parameter + than the normal xEventGroupCreate() API function. The parameter is a + pointer to the StaticEventGroup_t structure that will hold the event group + structure. If the parameter is passed as NULL then the structure will be + allocated dynamically, just as if xEventGroupCreate() had been called. */ + xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer ); + + /* The event group handle should equal the static event group structure + passed into the xEventGroupCreateStatic() function. */ + configASSERT( xEventGroup == ( EventGroupHandle_t ) &xEventGroupBuffer ); + + /* Ensure the event group passes a few sanity checks as a valid event + group. */ + prvSanityCheckCreatedEventGroup( xEventGroup ); + + /* Delete the event group again so the buffers can be reused. */ + vEventGroupDelete( xEventGroup ); + + /* Now do the same using a dynamically allocated event group to ensure the + delete function is working correctly in both the static and dynamic + allocation cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + xEventGroup = xEventGroupCreate(); + configASSERT( xEventGroup != NULL ); + prvSanityCheckCreatedEventGroup( xEventGroup ); + vEventGroupDelete( xEventGroup ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvCreateAndDeleteStaticallyAllocatedTasks( void ) +{ +TaskHandle_t xCreatedTask; + +/* The variable that will hold the TCB of tasks created by this function. See +the comments above the declaration of the xCreatorTaskTCBBuffer variable for +more information. */ +StaticTask_t xTCBBuffer; + +/* This buffer that will be used as the stack of tasks created by this function. +See the comments above the declaration of the uxCreatorTaskStackBuffer[] array +above for more information. */ +static StackType_t uxStackBuffer[ configMINIMAL_STACK_SIZE ]; + + /* Create the task. xTaskCreateStatic() has two more parameters than + the usual xTaskCreate() function. The first new parameter is a pointer to + the pre-allocated stack. The second new parameter is a pointer to the + StaticTask_t structure that will hold the task's TCB. If both pointers are + passed as NULL then the respective object will be allocated dynamically as + if xTaskCreate() had been called. */ + xCreatedTask = xTaskCreateStatic( + prvStaticallyAllocatedTask, /* Function that implements the task. */ + "Static", /* Human readable name for the task. */ + configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ + NULL, /* Parameter to pass into the task. */ + uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ + &( uxStackBuffer[ 0 ] ), /* The buffer to use as the task's stack. */ + &xTCBBuffer ); /* The variable that will hold that task's TCB. */ + + /* Check the task was created correctly, then delete the task. */ + if( xCreatedTask == NULL ) + { + xErrorOccurred = pdTRUE; + } + else if( eTaskGetState( xCreatedTask ) != eSuspended ) + { + /* The created task had a higher priority so should have executed and + suspended itself by now. */ + xErrorOccurred = pdTRUE; + } + else + { + vTaskDelete( xCreatedTask ); + } + + /* Now do the same using a dynamically allocated task to ensure the delete + function is working correctly in both the static and dynamic allocation + cases. */ + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + BaseType_t xReturned; + + xReturned = xTaskCreate( + prvStaticallyAllocatedTask, /* Function that implements the task - the same function is used but is actually dynamically allocated this time. */ + "Static", /* Human readable name for the task. */ + configMINIMAL_STACK_SIZE, /* Task's stack size, in words (not bytes!). */ + NULL, /* Parameter to pass into the task. */ + uxTaskPriorityGet( NULL ) + 1, /* The priority of the task. */ + &xCreatedTask ); /* Handle of the task being created. */ + + if( eTaskGetState( xCreatedTask ) != eSuspended ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( xReturned == pdPASS ); + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + vTaskDelete( xCreatedTask ); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvStaticallyAllocatedTask( void *pvParameters ) +{ + ( void ) pvParameters; + + /* The created task just suspends itself to wait to get deleted. The task + that creates this task checks this task is in the expected Suspended state + before deleting it. */ + vTaskSuspend( NULL ); +} +/*-----------------------------------------------------------*/ + +static UBaseType_t prvRand( void ) +{ +const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL; + + /* Utility function to generate a pseudo random number. */ + ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement; + return( ( ulNextRand >> 16UL ) & 0x7fffUL ); +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextDelayTime( void ) +{ +TickType_t xNextDelay; +const TickType_t xMaxDelay = pdMS_TO_TICKS( ( TickType_t ) 150 ); +const TickType_t xMinDelay = pdMS_TO_TICKS( ( TickType_t ) 75 ); +const TickType_t xTinyDelay = pdMS_TO_TICKS( ( TickType_t ) 2 ); + + /* Generate the next delay time. This is kept within a narrow band so as + not to disturb the timing of other tests - but does add in some pseudo + randomisation into the tests. */ + do + { + xNextDelay = prvRand() % xMaxDelay; + + /* Just in case this loop is executed lots of times. */ + vTaskDelay( xTinyDelay ); + + } while ( xNextDelay < xMinDelay ); + + return xNextDelay; +} +/*-----------------------------------------------------------*/ + +static void prvSanityCheckCreatedEventGroup( EventGroupHandle_t xEventGroup ) +{ +EventBits_t xEventBits; +const EventBits_t xFirstTestBits = ( EventBits_t ) 0xaa, xSecondTestBits = ( EventBits_t ) 0x55; + + /* The event group should not have any bits set yet. */ + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != ( EventBits_t ) 0 ) + { + xErrorOccurred = pdTRUE; + } + + /* Some some bits, then read them back to check they are as expected. */ + xEventGroupSetBits( xEventGroup, xFirstTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != xFirstTestBits ) + { + xErrorOccurred = pdTRUE; + } + + xEventGroupSetBits( xEventGroup, xSecondTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != ( xFirstTestBits | xSecondTestBits ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Finally try clearing some bits too and check that operation proceeds as + expected. */ + xEventGroupClearBits( xEventGroup, xFirstTestBits ); + + xEventBits = xEventGroupGetBits( xEventGroup ); + + if( xEventBits != xSecondTestBits ) + { + xErrorOccurred = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvSanityCheckCreatedSemaphore( SemaphoreHandle_t xSemaphore, UBaseType_t uxMaxCount ) +{ +BaseType_t xReturned; +UBaseType_t x; +const TickType_t xShortBlockTime = pdMS_TO_TICKS( 10 ); +TickType_t xTickCount; + + /* The binary semaphore should start 'empty', so a call to xSemaphoreTake() + should fail. */ + xTickCount = xTaskGetTickCount(); + xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); + + if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) + { + /* Did not block on the semaphore as long as expected. */ + xErrorOccurred = pdTRUE; + } + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + /* Should be possible to 'give' the semaphore up to a maximum of uxMaxCount + times. */ + for( x = 0; x < uxMaxCount; x++ ) + { + xReturned = xSemaphoreGive( xSemaphore ); + + if( xReturned == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Giving the semaphore again should fail, as it is 'full'. */ + xReturned = xSemaphoreGive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( uxSemaphoreGetCount( xSemaphore ) == uxMaxCount ); + + /* Should now be possible to 'take' the semaphore up to a maximum of + uxMaxCount times without blocking. */ + for( x = 0; x < uxMaxCount; x++ ) + { + xReturned = xSemaphoreTake( xSemaphore, staticDONT_BLOCK ); + + if( xReturned == pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Back to the starting condition, where the semaphore should not be + available. */ + xTickCount = xTaskGetTickCount(); + xReturned = xSemaphoreTake( xSemaphore, xShortBlockTime ); + + if( ( ( TickType_t ) ( xTaskGetTickCount() - xTickCount ) ) < xShortBlockTime ) + { + /* Did not block on the semaphore as long as expected. */ + xErrorOccurred = pdTRUE; + } + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvSanityCheckCreatedQueue( QueueHandle_t xQueue ) +{ +uint64_t ull, ullRead; +BaseType_t xReturned, xLoop; + + /* This test is done twice to ensure the queue storage area wraps. */ + for( xLoop = 0; xLoop < 2; xLoop++ ) + { + /* A very basic test that the queue can be written to and read from as + expected. First the queue should be empty. */ + xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); + if( xReturned != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* Now it should be possible to write to the queue staticQUEUE_LENGTH_IN_ITEMS + times. */ + for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) + { + xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Should not now be possible to write to the queue again. */ + xReturned = xQueueSend( xQueue, &ull, staticDONT_BLOCK ); + if( xReturned != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* Now read back from the queue to ensure the data read back matches that + written. */ + for( ull = 0; ull < staticQUEUE_LENGTH_IN_ITEMS; ull++ ) + { + xReturned = xQueueReceive( xQueue, &ullRead, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( ullRead != ull ) + { + xErrorOccurred = pdTRUE; + } + } + + /* The queue should be empty again. */ + xReturned = xQueueReceive( xQueue, &ull, staticDONT_BLOCK ); + if( xReturned != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSanityCheckCreatedRecursiveMutex( SemaphoreHandle_t xSemaphore ) +{ +const BaseType_t xLoops = 5; +BaseType_t x, xReturned; + + /* A very basic test that the recursive semaphore behaved like a recursive + semaphore. First the semaphore should not be able to be given, as it has not + yet been taken. */ + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } + + /* Now it should be possible to take the mutex a number of times. */ + for( x = 0; x < xLoops; x++ ) + { + xReturned = xSemaphoreTakeRecursive( xSemaphore, staticDONT_BLOCK ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Should be possible to give the semaphore the same number of times as it + was given in the loop above. */ + for( x = 0; x < xLoops; x++ ) + { + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* No more gives should be possible though. */ + xReturned = xSemaphoreGiveRecursive( xSemaphore ); + + if( xReturned != pdFAIL ) + { + xErrorOccurred = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreStaticAllocationTasksStillRunning( void ) +{ +static UBaseType_t uxLastCycleCounter = 0; +BaseType_t xReturn; + + if( uxCycleCounter == uxLastCycleCounter ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastCycleCounter = uxCycleCounter; + } + + if( xErrorOccurred != pdFALSE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdPASS; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +/* Exclude the entire file if configSUPPORT_STATIC_ALLOCATION is 0. */ +#endif /* configSUPPORT_STATIC_ALLOCATION == 1 */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TaskNotify.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TaskNotify.c new file mode 100644 index 0000000..43edcc5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TaskNotify.c @@ -0,0 +1,603 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the behaviour of direct task notifications. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +/* Demo program include files. */ +#include "TaskNotify.h" + +#define notifyTASK_PRIORITY ( tskIDLE_PRIORITY ) +#define notifyUINT32_MAX ( ( uint32_t ) 0xffffffff ) +/*-----------------------------------------------------------*/ + +/* + * Implementation of the task that gets notified. + */ +static void prvNotifiedTask( void *pvParameters ); + +/* + * Performs a few initial tests that can be done prior to creating the second + * task. + */ +static void prvSingleTaskTests( void ); + +/* + * Software timer callback function from which xTaskNotify() is called. + */ +static void prvNotifyingTimer( TimerHandle_t xTimer ); + +/* + * Utility function to create pseudo random numbers. + */ +static UBaseType_t prvRand( void ); + +/*-----------------------------------------------------------*/ + +/* Used to latch errors during the test's execution. */ +static BaseType_t xErrorStatus = pdPASS; + +/* Used to ensure the task has not stalled. */ +static volatile uint32_t ulNotifyCycleCount = 0; + +/* The handle of the task that receives the notifications. */ +static TaskHandle_t xTaskToNotify = NULL; + +/* Used to count the notifications sent to the task from a software timer and +the number of notifications received by the task from the software timer. The +two should stay synchronised. */ +static uint32_t ulTimerNotificationsReceived = 0UL, ulTimerNotificationsSent = 0UL; + +/* The timer used to notify the task. */ +static TimerHandle_t xTimer = NULL; + +/* Used by the pseudo random number generating function. */ +static size_t uxNextRand = 0; + +/*-----------------------------------------------------------*/ + +void vStartTaskNotifyTask( void ) +{ + /* Create the task that performs some tests by itself, then loops around + being notified by both a software timer and an interrupt. */ + xTaskCreate( prvNotifiedTask, "Notified", configMINIMAL_STACK_SIZE, NULL, notifyTASK_PRIORITY, &xTaskToNotify ); + + /* Pseudo seed the random number generator. */ + uxNextRand = ( size_t ) prvRand; +} +/*-----------------------------------------------------------*/ + +static void prvSingleTaskTests( void ) +{ +const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL ); +BaseType_t xReturned; +uint32_t ulNotifiedValue, ulLoop, ulNotifyingValue, ulPreviousValue, ulExpectedValue; +TickType_t xTimeOnEntering; +const uint32_t ulFirstNotifiedConst = 100001UL, ulSecondNotifiedValueConst = 5555UL, ulMaxLoops = 5UL; +const uint32_t ulBit0 = 0x01UL, ulBit1 = 0x02UL; + + /* ------------------------------------------------------------------------- + Check blocking when there are no notifications. */ + xTimeOnEntering = xTaskGetTickCount(); + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait ); + + /* Should have blocked for the entire block time. */ + if( ( xTaskGetTickCount() - xTimeOnEntering ) < xTicksToWait ) + { + xErrorStatus = pdFAIL; + } + configASSERT( xReturned == pdFAIL ); + configASSERT( ulNotifiedValue == 0UL ); + + + + + /* ------------------------------------------------------------------------- + Check no blocking when notifications are pending. First notify itself - + this would not be a normal thing to do and is done here for test purposes + only. */ + xReturned = xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue ); + + /* Even through the 'without overwrite' action was used the update should + have been successful. */ + configASSERT( xReturned == pdPASS ); + + /* No bits should have been pending previously. */ + configASSERT( ulPreviousValue == 0 ); + + /* The task should now have a notification pending, and so not time out. */ + xTimeOnEntering = xTaskGetTickCount(); + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, xTicksToWait ); + + if( ( xTaskGetTickCount() - xTimeOnEntering ) >= xTicksToWait ) + { + xErrorStatus = pdFAIL; + } + + /* The task should have been notified, and the notified value should + be equal to ulFirstNotifiedConst. */ + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ulFirstNotifiedConst ); + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + + + + + + /*-------------------------------------------------------------------------- + Check the non-overwriting functionality. The notification is done twice + using two different notification values. The action says don't overwrite so + only the first notification should pass and the value read back should also + be that used with the first notification. */ + xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite ); + configASSERT( xReturned == pdPASS ); + + xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithoutOverwrite ); + configASSERT( xReturned == pdFAIL ); + + /* Waiting for the notification should now return immediately so a block + time of zero is used. */ + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ulFirstNotifiedConst ); + + + + + + /*-------------------------------------------------------------------------- + Do the same again, only this time use the overwriting version. This time + both notifications should pass, and the value written the second time should + overwrite the value written the first time, and so be the value that is read + back. */ + xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithOverwrite ); + configASSERT( xReturned == pdPASS ); + xReturned = xTaskNotify( xTaskToNotify, ulSecondNotifiedValueConst, eSetValueWithOverwrite ); + configASSERT( xReturned == pdPASS ); + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); + + + + + /*-------------------------------------------------------------------------- + Check notifications with no action pass without updating the value. Even + though ulFirstNotifiedConst is used as the value the value read back should + remain at ulSecondNotifiedConst. */ + xReturned = xTaskNotify( xTaskToNotify, ulFirstNotifiedConst, eNoAction ); + configASSERT( xReturned == pdPASS ); + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( ulNotifiedValue == ulSecondNotifiedValueConst ); + + + + + /*-------------------------------------------------------------------------- + Check incrementing values. Send ulMaxLoop increment notifications, then + ensure the received value is as expected - which should be + ulSecondNotificationValueConst plus how ever many times to loop iterated. */ + for( ulLoop = 0; ulLoop < ulMaxLoops; ulLoop++ ) + { + xReturned = xTaskNotify( xTaskToNotify, 0, eIncrement ); + configASSERT( xReturned == pdPASS ); + } + + xReturned = xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ( ulSecondNotifiedValueConst + ulMaxLoops ) ); + + /* Should not be any notifications pending now. */ + xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdFAIL ); + + + + + /*-------------------------------------------------------------------------- + Check all bits can be set by notifying the task with one additional bit set + on each notification, and exiting the loop when all the bits are found to be + set. As there are 32-bits the loop should execute 32 times before all the + bits are found to be set. */ + ulNotifyingValue = 0x01; + ulLoop = 0; + + /* Start with all bits clear. */ + xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + + do + { + /* Set the next bit in the task's notified value. */ + xTaskNotify( xTaskToNotify, ulNotifyingValue, eSetBits ); + + /* Wait for the notified value - which of course will already be + available. Don't clear the bits on entry or exit as this loop is exited + when all the bits are set. */ + xReturned = xTaskNotifyWait( 0, 0, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + + ulLoop++; + + /* Use the next bit on the next iteration around this loop. */ + ulNotifyingValue <<= 1UL; + + } while ( ulNotifiedValue != notifyUINT32_MAX ); + + /* As a 32-bit value was used the loop should have executed 32 times before + all the bits were set. */ + configASSERT( ulLoop == 32 ); + + + + + /*-------------------------------------------------------------------------- + Check bits are cleared on entry but not on exit when a notification fails + to arrive before timing out - both with and without a timeout value. Wait + for the notification again - but this time it is not given by anything and + should return pdFAIL. The parameters are set to clear bit zero on entry and + bit one on exit. As no notification was received only the bit cleared on + entry should actually get cleared. */ + xReturned = xTaskNotifyWait( ulBit0, ulBit1, &ulNotifiedValue, xTicksToWait ); + configASSERT( xReturned == pdFAIL ); + + /* Notify the task with no action so as not to update the bits even though + notifyUINT32_MAX is used as the notification value. */ + xTaskNotify( xTaskToNotify, notifyUINT32_MAX, eNoAction ); + + /* Reading back the value should should find bit 0 is clear, as this was + cleared on entry, but bit 1 is not clear as it will not have been cleared on + exit as no notification was received. */ + xReturned = xTaskNotifyWait( 0x00UL, 0x00UL, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdPASS ); + configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~ulBit0 ) ); + + + + + + /*-------------------------------------------------------------------------- + Now try clearing the bit on exit. For that to happen a notification must be + received, so the task is notified first. */ + xTaskNotify( xTaskToNotify, 0, eNoAction ); + xTaskNotifyWait( 0x00, ulBit1, &ulNotifiedValue, 0 ); + + /* However as the bit is cleared on exit, after the returned notification + value is set, the returned notification value should not have the bit + cleared... */ + configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~ulBit0 ) ); + + /* ...but reading the value back again should find that the bit was indeed + cleared internally. The returned value should be pdFAIL however as nothing + has notified the task in the mean time. */ + xReturned = xTaskNotifyWait( 0x00, 0x00, &ulNotifiedValue, 0 ); + configASSERT( xReturned == pdFAIL ); + configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~( ulBit0 | ulBit1 ) ) ); + + + + + /*-------------------------------------------------------------------------- + Now try querying the previus value while notifying a task. */ + xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue ); + configASSERT( ulNotifiedValue == ( notifyUINT32_MAX & ~( ulBit0 | ulBit1 ) ) ); + + /* Clear all bits. */ + xTaskNotifyWait( 0x00, notifyUINT32_MAX, &ulNotifiedValue, 0 ); + xTaskNotifyAndQuery( xTaskToNotify, 0x00, eSetBits, &ulPreviousValue ); + configASSERT( ulPreviousValue == 0 ); + + ulExpectedValue = 0; + for( ulLoop = 0x01; ulLoop < 0x80UL; ulLoop <<= 1UL ) + { + /* Set the next bit up, and expect to receive the last bits set (so + the previous value will not yet have the bit being set this time + around). */ + xTaskNotifyAndQuery( xTaskToNotify, ulLoop, eSetBits, &ulPreviousValue ); + configASSERT( ulExpectedValue == ulPreviousValue ); + ulExpectedValue |= ulLoop; + } + + + + /* ------------------------------------------------------------------------- + Clear the previous notifications. */ + xTaskNotifyWait( notifyUINT32_MAX, 0, &ulNotifiedValue, 0 ); + + /* The task should not have any notifications pending, so an attempt to clear + the notification state should fail. */ + configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE ); + + /* Get the task to notify itself. This is not a normal thing to do, and is + only done here for test purposes. */ + xTaskNotifyAndQuery( xTaskToNotify, ulFirstNotifiedConst, eSetValueWithoutOverwrite, &ulPreviousValue ); + + /* Now the notification state should be eNotified, so it should now be + possible to clear the notification state. */ + configASSERT( xTaskNotifyStateClear( NULL ) == pdTRUE ); + configASSERT( xTaskNotifyStateClear( NULL ) == pdFALSE ); + + + + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + + /* Leave all bits cleared. */ + xTaskNotifyWait( notifyUINT32_MAX, 0, NULL, 0 ); +} +/*-----------------------------------------------------------*/ + +static void prvNotifyingTimer( TimerHandle_t xNotUsed ) +{ + ( void ) xNotUsed; + + xTaskNotifyGive( xTaskToNotify ); + + /* This value is also incremented from an interrupt. */ + taskENTER_CRITICAL(); + { + ulTimerNotificationsSent++; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static void prvNotifiedTask( void *pvParameters ) +{ +const TickType_t xMaxPeriod = pdMS_TO_TICKS( 90 ), xMinPeriod = pdMS_TO_TICKS( 10 ), xDontBlock = 0; +TickType_t xPeriod; +const uint32_t ulCyclesToRaisePriority = 50UL; + + /* Remove compiler warnings about unused parameters. */ + ( void ) pvParameters; + + /* Run a few tests that can be done from a single task before entering the + main loop. */ + prvSingleTaskTests(); + + /* Create the software timer that is used to send notifications to this + task. Notifications are also received from an interrupt. */ + xTimer = xTimerCreate( "Notifier", xMaxPeriod, pdFALSE, NULL, prvNotifyingTimer ); + + for( ;; ) + { + /* Start the timer again with a different period. Sometimes the period + will be higher than the tasks block time, sometimes it will be lower + than the tasks block time. */ + xPeriod = prvRand() % xMaxPeriod; + if( xPeriod < xMinPeriod ) + { + xPeriod = xMinPeriod; + } + + /* Change the timer period and start the timer. */ + xTimerChangePeriod( xTimer, xPeriod, portMAX_DELAY ); + + /* Block waiting for the notification again with a different period. + Sometimes the period will be higher than the tasks block time, sometimes + it will be lower than the tasks block time. */ + xPeriod = prvRand() % xMaxPeriod; + if( xPeriod < xMinPeriod ) + { + xPeriod = xMinPeriod; + } + + /* Block to wait for a notification but without clearing the + notification count, so only add one to the count of received + notifications as any other notifications will remain pending. */ + if( ulTaskNotifyTake( pdFALSE, xPeriod ) != 0 ) + { + ulTimerNotificationsReceived++; + } + + + /* Take a notification without clearing again, but this time without a + block time specified. */ + if( ulTaskNotifyTake( pdFALSE, xDontBlock ) != 0 ) + { + ulTimerNotificationsReceived++; + } + + /* Wait for the next notification from the timer, clearing all + notifications if one is received, so this time adding the total number + of notifications that were pending as none will be left pending after + the function call. */ + ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, xPeriod ); + + /* Occasionally raise the priority of the task being notified to test + the path where the task is notified from an ISR and becomes the highest + priority ready state task, but the pxHigherPriorityTaskWoken parameter + is NULL (which it is in the tick hook that sends notifications to this + task. */ + if( ( ulNotifyCycleCount % ulCyclesToRaisePriority ) == 0 ) + { + vTaskPrioritySet( xTaskToNotify, configMAX_PRIORITIES - 1 ); + + /* Wait for the next notification again, clearing all notifications if + one is received, but this time blocking indefinitely. */ + ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + + /* Reset the priority. */ + vTaskPrioritySet( xTaskToNotify, notifyTASK_PRIORITY ); + } + else + { + /* Wait for the next notification again, clearing all notifications if + one is received, but this time blocking indefinitely. */ + ulTimerNotificationsReceived += ulTaskNotifyTake( pdTRUE, portMAX_DELAY ); + } + + /* Incremented to show the task is still running. */ + ulNotifyCycleCount++; + } +} +/*-----------------------------------------------------------*/ + +void xNotifyTaskFromISR( void ) +{ +static BaseType_t xCallCount = 0, xAPIToUse = 0; +const BaseType_t xCallInterval = pdMS_TO_TICKS( 50 ); +uint32_t ulPreviousValue; +const uint32_t ulUnexpectedValue = 0xff; + + /* The task performs some tests before starting the timer that gives the + notification from this interrupt. If the timer has not been created yet + then the initial tests have not yet completed and the notification should + not be sent. */ + if( xTimer != NULL ) + { + xCallCount++; + + if( xCallCount >= xCallInterval ) + { + /* It is time to 'give' the notification again. */ + xCallCount = 0; + + /* Test using both vTaskNotifyGiveFromISR(), xTaskNotifyFromISR() + and xTaskNotifyAndQueryFromISR(). */ + switch( xAPIToUse ) + { + case 0: vTaskNotifyGiveFromISR( xTaskToNotify, NULL ); + xAPIToUse++; + break; + + case 1: xTaskNotifyFromISR( xTaskToNotify, 0, eIncrement, NULL ); + xAPIToUse++; + break; + + case 2: ulPreviousValue = ulUnexpectedValue; + xTaskNotifyAndQueryFromISR( xTaskToNotify, 0, eIncrement, &ulPreviousValue, NULL ); + configASSERT( ulPreviousValue != ulUnexpectedValue ); + xAPIToUse = 0; + break; + + default:/* Should never get here!. */ + break; + } + + ulTimerNotificationsSent++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check the created tasks are still running and have not +detected any errors. */ +BaseType_t xAreTaskNotificationTasksStillRunning( void ) +{ +static uint32_t ulLastNotifyCycleCount = 0; +const uint32_t ulMaxSendReceiveDeviation = 5UL; + + /* Check the cycle count is still incrementing to ensure the task is still + actually running. */ + if( ulLastNotifyCycleCount == ulNotifyCycleCount ) + { + xErrorStatus = pdFAIL; + } + else + { + ulLastNotifyCycleCount = ulNotifyCycleCount; + } + + /* Check the count of 'takes' from the software timer is keeping track with + the amount of 'gives'. */ + if( ulTimerNotificationsSent > ulTimerNotificationsReceived ) + { + if( ( ulTimerNotificationsSent - ulTimerNotificationsReceived ) > ulMaxSendReceiveDeviation ) + { + xErrorStatus = pdFAIL; + } + } + + return xErrorStatus; +} +/*-----------------------------------------------------------*/ + +static UBaseType_t prvRand( void ) +{ +const size_t uxMultiplier = ( size_t ) 0x015a4e35, uxIncrement = ( size_t ) 1; + + /* Utility function to generate a pseudo random number. */ + uxNextRand = ( uxMultiplier * uxNextRand ) + uxIncrement; + return( ( uxNextRand >> 16 ) & ( ( size_t ) 0x7fff ) ); +} +/*-----------------------------------------------------------*/ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TimerDemo.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TimerDemo.c new file mode 100644 index 0000000..3175868 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/TimerDemo.c @@ -0,0 +1,1108 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Tests the behaviour of timers. Some timers are created before the scheduler + * is started, and some after. + */ + +/* Standard includes. */ +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +/* Demo program include files. */ +#include "TimerDemo.h" + +#if ( configTIMER_TASK_PRIORITY < 1 ) + #error configTIMER_TASK_PRIORITY must be set to at least 1 for this test/demo to function correctly. +#endif + +#define tmrdemoDONT_BLOCK ( ( TickType_t ) 0 ) +#define tmrdemoONE_SHOT_TIMER_PERIOD ( xBasePeriod * ( TickType_t ) 3 ) +#define trmdemoNUM_TIMER_RESETS ( ( uint8_t ) 10 ) + +/*-----------------------------------------------------------*/ + +/* The callback functions used by the timers. These each increment a counter +to indicate which timer has expired. The auto-reload timers that are used by +the test task (as opposed to being used from an ISR) all share the same +prvAutoReloadTimerCallback() callback function, and use the ID of the +pxExpiredTimer parameter passed into that function to know which counter to +increment. The other timers all have their own unique callback function and +simply increment their counters without using the callback function parameter. */ +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvTimerTestTask( void *pvParameters ); +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ); +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ); + +/* The test functions used by the timer test task. These manipulate the auto +reload and one shot timers in various ways, then delay, then inspect the timers +to ensure they have behaved as expected. */ +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ); +static void prvTest2_CheckTaskAndTimersInitialState( void ); +static void prvTest3_CheckAutoReloadExpireRates( void ); +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ); +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ); +static void prvTest6_CheckAutoReloadResetBehaviour( void ); +static void prvResetStartConditionsForNextIteration( void ); + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdFAIL should any unexpected behaviour be +detected in any of the demo tests. */ +static volatile BaseType_t xTestStatus = pdPASS; + +/* Counter that is incremented on each cycle of a test. This is used to +detect a stalled task - a test that is no longer running. */ +static volatile uint32_t ulLoopCounter = 0; + +/* A set of auto reload timers - each of which use the same callback function. +The callback function uses the timer ID to index into, and then increment, a +counter in the ucAutoReloadTimerCounters[] array. The auto reload timers +referenced from xAutoReloadTimers[] are used by the prvTimerTestTask task. */ +static TimerHandle_t xAutoReloadTimers[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; +static uint8_t ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH + 1 ] = { 0 }; + +/* The one shot timer is configured to use a callback function that increments +ucOneShotTimerCounter each time it gets called. */ +static TimerHandle_t xOneShotTimer = NULL; +static uint8_t ucOneShotTimerCounter = ( uint8_t ) 0; + +/* The ISR reload timer is controlled from the tick hook to exercise the timer +API functions that can be used from an ISR. It is configured to increment +ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISRAutoReloadTimer = NULL; +static uint8_t ucISRAutoReloadTimerCounter = ( uint8_t ) 0; + +/* The ISR one shot timer is controlled from the tick hook to exercise the timer +API functions that can be used from an ISR. It is configured to increment +ucISRReloadTimerCounter each time its callback function is executed. */ +static TimerHandle_t xISROneShotTimer = NULL; +static uint8_t ucISROneShotTimerCounter = ( uint8_t ) 0; + +/* The period of all the timers are a multiple of the base period. The base +period is configured by the parameter to vStartTimerDemoTask(). */ +static TickType_t xBasePeriod = 0; + +/*-----------------------------------------------------------*/ + +void vStartTimerDemoTask( TickType_t xBasePeriodIn ) +{ + /* Start with the timer and counter arrays clear - this is only necessary + where the compiler does not clear them automatically on start up. */ + memset( ucAutoReloadTimerCounters, 0x00, sizeof( ucAutoReloadTimerCounters ) ); + memset( xAutoReloadTimers, 0x00, sizeof( xAutoReloadTimers ) ); + + /* Store the period from which all the timer periods will be generated from + (multiples of). */ + xBasePeriod = xBasePeriodIn; + + /* Create a set of timers for use by this demo/test. */ + prvTest1_CreateTimersWithoutSchedulerRunning(); + + /* Create the task that will control and monitor the timers. This is + created at a lower priority than the timer service task to ensure, as + far as it is concerned, commands on timers are actioned immediately + (sending a command to the timer service task will unblock the timer service + task, which will then preempt this task). */ + if( xTestStatus != pdFAIL ) + { + xTaskCreate( prvTimerTestTask, "Tmr Tst", configMINIMAL_STACK_SIZE, NULL, configTIMER_TASK_PRIORITY - 1, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTimerTestTask( void *pvParameters ) +{ + ( void ) pvParameters; + + /* Create a one-shot timer for use later on in this test. */ + xOneShotTimer = xTimerCreate( "Oneshot Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + tmrdemoONE_SHOT_TIMER_PERIOD, /* The period for the timer. */ + pdFALSE, /* Don't auto-reload - hence a one shot timer. */ + ( void * ) 0, /* The timer identifier. Initialise to 0, then increment each time it is called. */ + prvOneShotTimerCallback ); /* The callback to be called when the timer expires. */ + + if( xOneShotTimer == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + + /* Ensure all the timers are in their expected initial state. This + depends on the timer service task having a higher priority than this task. */ + prvTest2_CheckTaskAndTimersInitialState(); + + for( ;; ) + { + /* Check the auto reload timers expire at the expected/correct rates. */ + prvTest3_CheckAutoReloadExpireRates(); + + /* Check the auto reload timers can be stopped correctly, and correctly + report their state. */ + prvTest4_CheckAutoReloadTimersCanBeStopped(); + + /* Check the one shot timer only calls its callback once after it has been + started, and that it reports its state correctly. */ + prvTest5_CheckBasicOneShotTimerBehaviour(); + + /* Check timer reset behaviour. */ + prvTest6_CheckAutoReloadResetBehaviour(); + + /* Start the timers again to restart all the tests over again. */ + prvResetStartConditionsForNextIteration(); + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the created task is still running and has not +detected any errors. */ +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ) +{ +static uint32_t ulLastLoopCounter = 0UL; +TickType_t xMaxBlockTimeUsedByTheseTests, xLoopCounterIncrementTimeMax; +static TickType_t xIterationsWithoutCounterIncrement = ( TickType_t ) 0, xLastCycleFrequency; + + if( xLastCycleFrequency != xCycleFrequency ) + { + /* The cycle frequency has probably become much faster due to an error + elsewhere. Start counting Iterations again. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + xLastCycleFrequency = xCycleFrequency; + } + + /* Calculate the maximum number of times that it is permissible for this + function to be called without ulLoopCounter being incremented. This is + necessary because the tests in this file block for extended periods, and the + block period might be longer than the time between calls to this function. */ + xMaxBlockTimeUsedByTheseTests = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + xLoopCounterIncrementTimeMax = ( xMaxBlockTimeUsedByTheseTests / xCycleFrequency ) + 1; + + /* If the demo task is still running then the loop counter is expected to + have incremented every xLoopCounterIncrementTimeMax calls. */ + if( ulLastLoopCounter == ulLoopCounter ) + { + xIterationsWithoutCounterIncrement++; + if( xIterationsWithoutCounterIncrement > xLoopCounterIncrementTimeMax ) + { + /* The tests appear to be no longer running (stalled). */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else + { + /* ulLoopCounter changed, so the count of times this function was called + without a change can be reset to zero. */ + xIterationsWithoutCounterIncrement = ( TickType_t ) 0; + } + + ulLastLoopCounter = ulLoopCounter; + + /* Errors detected in the task itself will have latched xTestStatus + to pdFAIL. */ + + return xTestStatus; +} +/*-----------------------------------------------------------*/ + +static void prvTest1_CreateTimersWithoutSchedulerRunning( void ) +{ +TickType_t xTimer; + + for( xTimer = 0; xTimer < configTIMER_QUEUE_LENGTH; xTimer++ ) + { + /* As the timer queue is not yet full, it should be possible to both + create and start a timer. These timers are being started before the + scheduler has been started, so their block times should get set to zero + within the timer API itself. */ + xAutoReloadTimers[ xTimer ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( ( xTimer + ( TickType_t ) 1 ) * xBasePeriod ),/* The period for the timer. The plus 1 ensures a period of zero is not specified. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback to be called when the timer expires. */ + + if( xAutoReloadTimers[ xTimer ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + configASSERT( strcmp( pcTimerGetName( xAutoReloadTimers[ xTimer ] ), "FR Timer" ) == 0 ); + + /* The scheduler has not yet started, so the block period of + portMAX_DELAY should just get set to zero in xTimerStart(). Also, + the timer queue is not yet full so xTimerStart() should return + pdPASS. */ + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) != pdPASS ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + } + + /* The timers queue should now be full, so it should be possible to create + another timer, but not possible to start it (the timer queue will not get + drained until the scheduler has been started. */ + xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] = xTimerCreate( "FR Timer", /* Text name to facilitate debugging. The kernel does not use this itself. */ + ( configTIMER_QUEUE_LENGTH * xBasePeriod ), /* The period for the timer. */ + pdTRUE, /* Auto-reload is set to true. */ + ( void * ) xTimer, /* An identifier for the timer as all the auto reload timers use the same callback. */ + prvAutoReloadTimerCallback ); /* The callback executed when the timer expires. */ + + if( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] == NULL ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + if( xTimerStart( xAutoReloadTimers[ xTimer ], portMAX_DELAY ) == pdPASS ) + { + /* This time it would not be expected that the timer could be + started at this point. */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + /* Create the timers that are used from the tick interrupt to test the timer + API functions that can be called from an ISR. */ + xISRAutoReloadTimer = xTimerCreate( "ISR AR", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdTRUE, /* This is an auto reload timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISRAutoReloadTimerCallback ); /* The callback that is executed when the timer expires. */ + + xISROneShotTimer = xTimerCreate( "ISR OS", /* The text name given to the timer. */ + 0xffff, /* The timer is not given a period yet - this will be done from the tick hook, but a period of 0 is invalid. */ + pdFALSE, /* This is a one shot timer. */ + ( void * ) NULL, /* The identifier is not required. */ + prvISROneShotTimerCallback ); /* The callback that is executed when the timer expires. */ + + if( ( xISRAutoReloadTimer == NULL ) || ( xISROneShotTimer == NULL ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest2_CheckTaskAndTimersInitialState( void ) +{ +uint8_t ucTimer; + + /* Ensure all the timers are in their expected initial state. This depends + on the timer service task having a higher priority than this task. + + auto reload timers 0 to ( configTIMER_QUEUE_LENGTH - 1 ) should now be active, + and auto reload timer configTIMER_QUEUE_LENGTH should not yet be active (it + could not be started prior to the scheduler being started when it was + created). */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvTest3_CheckAutoReloadExpireRates( void ) +{ +uint8_t ucMaxAllowableValue, ucMinAllowableValue, ucTimer; +TickType_t xBlockPeriod, xTimerPeriod, xExpectedNumber; +UBaseType_t uxOriginalPriority; + + /* Check the auto reload timers expire at the expected rates. Do this at a + high priority for maximum accuracy. This is ok as most of the time is spent + in the Blocked state. */ + uxOriginalPriority = uxTaskPriorityGet( NULL ); + vTaskPrioritySet( NULL, ( configMAX_PRIORITIES - 1 ) ); + + /* Delaying for configTIMER_QUEUE_LENGTH * xBasePeriod ticks should allow + all the auto reload timers to expire at least once. */ + xBlockPeriod = ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod; + vTaskDelay( xBlockPeriod ); + + /* Check that all the auto reload timers have called their callback + function the expected number of times. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The expected number of expiries is equal to the block period divided + by the timer period. */ + xTimerPeriod = ( ( ( TickType_t ) ucTimer + ( TickType_t ) 1 ) * xBasePeriod ); + xExpectedNumber = xBlockPeriod / xTimerPeriod; + + ucMaxAllowableValue = ( ( uint8_t ) xExpectedNumber ) ; + ucMinAllowableValue = ( uint8_t ) ( ( uint8_t ) xExpectedNumber - ( uint8_t ) 1 ); /* Weird casting to try and please all compilers. */ + + if( ( ucAutoReloadTimerCounters[ ucTimer ] < ucMinAllowableValue ) || + ( ucAutoReloadTimerCounters[ ucTimer ] > ucMaxAllowableValue ) + ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + /* Return to the original priority. */ + vTaskPrioritySet( NULL, uxOriginalPriority ); + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest4_CheckAutoReloadTimersCanBeStopped( void ) +{ +uint8_t ucTimer; + + /* Check the auto reload timers can be stopped correctly, and correctly + report their state. */ + + /* Stop all the active timers. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been stopped yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the timer. This will appear to happen immediately to + this task because this task is running at a priority below the + timer service task. */ + xTimerStop( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be inactive. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + taskENTER_CRITICAL(); + { + /* The timer in array position configTIMER_QUEUE_LENGTH should not + be active. The critical section is used to ensure the timer does + not call its callback between the next line running and the array + being cleared back to zero, as that would mask an error condition. */ + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback count. */ + memset( ( void * ) ucAutoReloadTimerCounters, 0, sizeof( ucAutoReloadTimerCounters ) ); + } + taskEXIT_CRITICAL(); + + /* The timers are now all inactive, so this time, after delaying, none + of the callback counters should have incremented. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + if( ucAutoReloadTimerCounters[ ucTimer ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + the check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest5_CheckBasicOneShotTimerBehaviour( void ) +{ + /* Check the one shot timer only calls its callback once after it has been + started, and that it reports its state correctly. */ + + /* The one shot timer should not be active yet. */ + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Start the one shot timer and check that it reports its state correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Delay for three times as long as the one shot timer period, then check + to ensure it has only called its callback once, and is now not in the + active state. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD * ( TickType_t ) 3 ); + + if( xTimerIsTimerActive( xOneShotTimer ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + else + { + /* Reset the one shot timer callback count. */ + ucOneShotTimerCounter = ( uint8_t ) 0; + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvTest6_CheckAutoReloadResetBehaviour( void ) +{ +uint8_t ucTimer; + + /* Check timer reset behaviour. */ + + /* Restart the one shot timer and check it reports its status correctly. */ + xTimerStart( xOneShotTimer, tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Restart one of the auto reload timers and check that it reports its + status correctly. */ + xTimerStart( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + for( ucTimer = 0; ucTimer < trmdemoNUM_TIMER_RESETS; ucTimer++ ) + { + /* Delay for half as long as the one shot timer period, then reset it. + It should never expire while this is done, so its callback count should + never increment. */ + vTaskDelay( tmrdemoONE_SHOT_TIMER_PERIOD / 2 ); + + /* Check both running timers are still active, but have not called their + callback functions. */ + if( xTimerIsTimerActive( xOneShotTimer ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucOneShotTimerCounter != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] != ( uint8_t ) 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Reset both running timers. */ + xTimerReset( xOneShotTimer, tmrdemoDONT_BLOCK ); + xTimerReset( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so + the check task knows this task is still running. */ + ulLoopCounter++; + } + } + + /* Finally delay long enough for both running timers to expire. */ + vTaskDelay( ( ( TickType_t ) configTIMER_QUEUE_LENGTH ) * xBasePeriod ); + + /* The timers were not reset during the above delay period so should now + both have called their callback functions. */ + if( ucOneShotTimerCounter != ( uint8_t ) 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] == 0 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* The one shot timer should no longer be active, while the auto reload + timer should still be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( xTimerIsTimerActive( xOneShotTimer ) == pdTRUE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Stop the auto reload timer again. */ + xTimerStop( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ], tmrdemoDONT_BLOCK ); + + if( xTimerIsTimerActive( xAutoReloadTimers[ configTIMER_QUEUE_LENGTH - 1 ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Clear the timer callback counts, ready for another iteration of these + tests. */ + ucAutoReloadTimerCounters[ configTIMER_QUEUE_LENGTH - 1 ] = ( uint8_t ) 0; + ucOneShotTimerCounter = ( uint8_t ) 0; + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the check + task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +static void prvResetStartConditionsForNextIteration( void ) +{ +uint8_t ucTimer; + + /* Start the timers again to start all the tests over again. */ + + /* Start the timers again. */ + for( ucTimer = 0; ucTimer < ( uint8_t ) configTIMER_QUEUE_LENGTH; ucTimer++ ) + { + /* The timer has not been started yet! */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) != pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now start the timer. This will appear to happen immediately to + this task because this task is running at a priority below the timer + service task. */ + xTimerStart( xAutoReloadTimers[ ucTimer ], tmrdemoDONT_BLOCK ); + + /* The timer should now be active. */ + if( xTimerIsTimerActive( xAutoReloadTimers[ ucTimer ] ) == pdFALSE ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + + if( xTestStatus == pdPASS ) + { + /* No errors have been reported so increment the loop counter so the + check task knows this task is still running. */ + ulLoopCounter++; + } +} +/*-----------------------------------------------------------*/ + +void vTimerPeriodicISRTests( void ) +{ +static TickType_t uxTick = ( TickType_t ) -1; + +#if( configTIMER_TASK_PRIORITY != ( configMAX_PRIORITIES - 1 ) ) + /* The timer service task is not the highest priority task, so it cannot + be assumed that timings will be exact. Timers should never call their + callback before their expiry time, but a margin is permissible for calling + their callback after their expiry time. If exact timing is required then + configTIMER_TASK_PRIORITY must be set to ensure the timer service task + is the highest priority task in the system. + + This function is called from the tick hook. The tick hook is called + even when the scheduler is suspended. Therefore it is possible that the + uxTick count maintained in this function is temporarily ahead of the tick + count maintained by the kernel. When this is the case a message posted from + this function will assume a time stamp in advance of the real time stamp, + which can result in a timer being processed before this function expects it + to. For example, if the kernel's tick count was 100, and uxTick was 102, + then this function will not expect the timer to have expired until the + kernel's tick count is (102 + xBasePeriod), whereas in reality the timer + will expire when the kernel's tick count is (100 + xBasePeriod). For this + reason xMargin is used as an allowable margin for premature timer expiries + as well as late timer expiries. */ + #ifdef _WINDOWS_ + /* Windows is not real real time. */ + const TickType_t xMargin = 20; + #else + const TickType_t xMargin = 6; + #endif /* _WINDOWS_ */ +#else + #ifdef _WINDOWS_ + /* Windows is not real real time. */ + const TickType_t xMargin = 20; + #else + const TickType_t xMargin = 4; + #endif /* _WINDOWS_ */ +#endif + + + uxTick++; + + if( uxTick == 0 ) + { + /* The timers will have been created, but not started. Start them now + by setting their period. */ + ucISRAutoReloadTimerCounter = 0; + ucISROneShotTimerCounter = 0; + + /* It is possible that the timer task has not yet made room in the + timer queue. If the timers cannot be started then reset uxTick so + another attempt is made later. */ + uxTick = ( TickType_t ) -1; + + /* Try starting first timer. */ + if( xTimerChangePeriodFromISR( xISRAutoReloadTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* First timer was started, try starting the second timer. */ + if( xTimerChangePeriodFromISR( xISROneShotTimer, xBasePeriod, NULL ) == pdPASS ) + { + /* Both timers were started, so set the uxTick back to its + proper value. */ + uxTick = 0; + } + else + { + /* Second timer could not be started, so stop the first one + again. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + } + } + else if( uxTick == ( xBasePeriod - xMargin ) ) + { + /* Neither timer should have expired yet. */ + if( ( ucISRAutoReloadTimerCounter != 0 ) || ( ucISROneShotTimerCounter != 0 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( xBasePeriod + xMargin ) ) + { + /* Both timers should now have expired once. The auto reload timer will + still be active, but the one shot timer should now have stopped. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) - xMargin ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped - however, at this time neither of the timers + should have expired again since the last test. */ + if( ( ucISRAutoReloadTimerCounter != 1 ) || ( ucISROneShotTimerCounter != 1 ) ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped. At this time the auto reload timer should have + expired again, but the one shot timer count should not have changed. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 2 * xBasePeriod ) + ( xBasePeriod >> ( TickType_t ) 2U ) ) ) + { + /* The auto reload timer will still be active, but the one shot timer + should now have stopped. Again though, at this time, neither timer call + back should have been called since the last test. */ + if( ucISRAutoReloadTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 3 * xBasePeriod ) ) + { + /* Start the one shot timer again. */ + xTimerStartFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 3 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer and one shot timer will be active. At + this time the auto reload timer should have expired again, but the one + shot timer count should not have changed yet. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now stop the auto reload timer. The one shot timer was started + a few ticks ago. */ + xTimerStopFromISR( xISRAutoReloadTimer, NULL ); + } + else if( uxTick == ( 4 * ( xBasePeriod - xMargin ) ) ) + { + /* The auto reload timer is now stopped, and the one shot timer is + active, but at this time neither timer should have expired since the + last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 1 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( ( 4 * xBasePeriod ) + xMargin ) ) + { + /* The auto reload timer is now stopped, and the one shot timer is + active. The one shot timer should have expired again, but the auto + reload timer should not have executed its callback. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 8 * xBasePeriod ) ) + { + /* The auto reload timer is now stopped, and the one shot timer has + already expired and then stopped itself. Both callback counters should + not have incremented since the last test. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + /* Now reset the one shot timer. */ + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 9 * xBasePeriod ) - xMargin ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 10 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 11 * xBasePeriod ) - ( 3 * xMargin ) ) ) + { + /* Only the one shot timer should be running, but it should not have + expired since the last test. Check the callback counters have not + incremented, then reset the one shot timer once again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 2 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + xTimerResetFromISR( xISROneShotTimer, NULL ); + } + else if( uxTick == ( ( 12 * xBasePeriod ) - ( 2 * xMargin ) ) ) + { + /* Only the one shot timer should have been running and this time it + should have expired. Check its callback count has been incremented. + The auto reload timer is still not running so should still have the same + count value. This time the one shot timer is not reset so should not + restart from its expiry period again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + } + else if( uxTick == ( 15 * xBasePeriod ) ) + { + /* Neither timer should be running now. Check neither callback count + has incremented, then go back to the start to run these tests all + over again. */ + if( ucISRAutoReloadTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + if( ucISROneShotTimerCounter != 3 ) + { + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } + + uxTick = ( TickType_t ) -1; + } +} +/*-----------------------------------------------------------*/ + +/*** Timer callback functions are defined below here. ***/ + +static void prvAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ +size_t uxTimerID; + + uxTimerID = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); + if( uxTimerID <= ( configTIMER_QUEUE_LENGTH + 1 ) ) + { + ( ucAutoReloadTimerCounters[ uxTimerID ] )++; + } + else + { + /* The timer ID appears to be unexpected (invalid). */ + xTestStatus = pdFAIL; + configASSERT( xTestStatus ); + } +} +/*-----------------------------------------------------------*/ + +static void prvOneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ +/* A count is kept of the number of times this callback function is executed. +The count is stored as the timer's ID. This is only done to test the +vTimerSetTimerID() function. */ +static size_t uxCallCount = 0; +size_t uxLastCallCount; + + /* Obtain the timer's ID, which should be a count of the number of times + this callback function has been executed. */ + uxLastCallCount = ( size_t ) pvTimerGetTimerID( pxExpiredTimer ); + configASSERT( uxLastCallCount == uxCallCount ); + + /* Increment the call count, then save it back as the timer's ID. This is + only done to test the vTimerSetTimerID() API function. */ + uxLastCallCount++; + vTimerSetTimerID( pxExpiredTimer, ( void * ) uxLastCallCount ); + uxCallCount++; + + ucOneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISRAutoReloadTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + callback function. */ + ( void ) pxExpiredTimer; + + ucISRAutoReloadTimerCounter++; +} +/*-----------------------------------------------------------*/ + +static void prvISROneShotTimerCallback( TimerHandle_t pxExpiredTimer ) +{ + /* The parameter is not used in this case as only one timer uses this + callback function. */ + ( void ) pxExpiredTimer; + + ucISROneShotTimerCounter++; +} +/*-----------------------------------------------------------*/ + + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/blocktim.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/blocktim.c new file mode 100644 index 0000000..52a2110 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/blocktim.c @@ -0,0 +1,582 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This file contains some test scenarios that ensure tasks do not exit queue + * send or receive functions prematurely. A description of the tests is + * included within the code. + */ + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Demo includes. */ +#include "blocktim.h" + +/* Task priorities. Allow these to be overridden. */ +#ifndef bktPRIMARY_PRIORITY + #define bktPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) +#endif + +#ifndef bktSECONDARY_PRIORITY + #define bktSECONDARY_PRIORITY ( configMAX_PRIORITIES - 4 ) +#endif + +/* Task behaviour. */ +#define bktQUEUE_LENGTH ( 5 ) +#define bktSHORT_WAIT pdMS_TO_TICKS( ( TickType_t ) 20 ) +#define bktPRIMARY_BLOCK_TIME ( 10 ) +#define bktALLOWABLE_MARGIN ( 15 ) +#define bktTIME_TO_BLOCK ( 175 ) +#define bktDONT_BLOCK ( ( TickType_t ) 0 ) +#define bktRUN_INDICATOR ( ( UBaseType_t ) 0x55 ) + +/* In case the demo does not have software timers enabled, as this file uses +the configTIMER_TASK_PRIORITY setting. */ +#ifndef configTIMER_TASK_PRIORITY + #define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#endif + +/*-----------------------------------------------------------*/ + +/* + * The two test tasks. Their behaviour is commented within the functions. + */ +static void vPrimaryBlockTimeTestTask( void *pvParameters ); +static void vSecondaryBlockTimeTestTask( void *pvParameters ); + +/* + * Very basic tests to verify the block times are as expected. + */ +static void prvBasicDelayTests( void ); + +/*-----------------------------------------------------------*/ + +/* The queue on which the tasks block. */ +static QueueHandle_t xTestQueue; + +/* Handle to the secondary task is required by the primary task for calls +to vTaskSuspend/Resume(). */ +static TaskHandle_t xSecondary; + +/* Used to ensure that tasks are still executing without error. */ +static volatile BaseType_t xPrimaryCycles = 0, xSecondaryCycles = 0; +static volatile BaseType_t xErrorOccurred = pdFALSE; + +/* Provides a simple mechanism for the primary task to know when the +secondary task has executed. */ +static volatile UBaseType_t xRunIndicator; + +/*-----------------------------------------------------------*/ + +void vCreateBlockTimeTasks( void ) +{ + /* Create the queue on which the two tasks block. */ + xTestQueue = xQueueCreate( bktQUEUE_LENGTH, sizeof( BaseType_t ) ); + + if( xTestQueue != NULL ) + { + /* vQueueAddToRegistry() adds the queue to the queue registry, if one + is in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware + debugger is not being used. The call to vQueueAddToRegistry() will be + removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not + defined or is defined to be less than 1. */ + vQueueAddToRegistry( xTestQueue, "Block_Time_Queue" ); + + /* Create the two test tasks. */ + xTaskCreate( vPrimaryBlockTimeTestTask, "BTest1", configMINIMAL_STACK_SIZE, NULL, bktPRIMARY_PRIORITY, NULL ); + xTaskCreate( vSecondaryBlockTimeTestTask, "BTest2", configMINIMAL_STACK_SIZE, NULL, bktSECONDARY_PRIORITY, &xSecondary ); + } +} +/*-----------------------------------------------------------*/ + +static void vPrimaryBlockTimeTestTask( void *pvParameters ) +{ +BaseType_t xItem, xData; +TickType_t xTimeWhenBlocking; +TickType_t xTimeToBlock, xBlockedTime; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 0 + + Basic vTaskDelay() and vTaskDelayUntil() tests. */ + prvBasicDelayTests(); + + + /********************************************************************* + Test 1 + + Simple block time wakeup test on queue receives. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is empty. Attempt to read from the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueReceive( xTestQueue, &xData, xTimeToBlock ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 2 + + Simple block time wakeup test on queue sends. + + First fill the queue. It should be empty so all sends should pass. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* The queue is full. Attempt to write to the queue using a block + time. When we wake, ensure the delta in time is as expected. */ + xTimeToBlock = ( TickType_t ) ( bktPRIMARY_BLOCK_TIME << xItem ); + + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after xTimeToBlock having not received + anything on the queue. */ + if( xQueueSend( xTestQueue, &xItem, xTimeToBlock ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we blocked for? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + if( xBlockedTime < xTimeToBlock ) + { + /* Should not have blocked for less than we requested. */ + xErrorOccurred = pdTRUE; + } + + if( xBlockedTime > ( xTimeToBlock + bktALLOWABLE_MARGIN ) ) + { + /* Should not have blocked for longer than we requested, + although we would not necessarily run as soon as we were + unblocked so a margin is allowed. */ + xErrorOccurred = pdTRUE; + } + } + + /********************************************************************* + Test 3 + + Wake the other task, it will block attempting to post to the queue. + When we read from the queue the other task will wake, but before it + can run we will post to the queue again. When the other task runs it + will find the queue still full, even though it was woken. It should + recognise that its block time has not expired and return to block for + the remains of its block time. + + Wake the other task so it blocks attempting to post to the already + full queue. */ + xRunIndicator = 0; + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + /* The other task has not yet executed. */ + vTaskDelay( bktSHORT_WAIT ); + } + /* Make sure the other task is blocked on the queue. */ + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we make space on the queue the other task should wake + but not execute as this task has higher priority. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now fill the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + full ourselves, and the other task have set xRunIndicator. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + + /* Set the priority back down. */ + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + + /********************************************************************* + Test 4 + + As per test 3 - but with the send and receive the other way around. + The other task blocks attempting to read from the queue. + + Empty the queue. We should find that it is full. */ + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + } + + /* Wake the other task so it blocks attempting to read from the + already empty queue. */ + vTaskResume( xSecondary ); + + /* We need to wait a little to ensure the other task executes. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + xRunIndicator = 0; + + for( xItem = 0; xItem < bktQUEUE_LENGTH; xItem++ ) + { + /* Now when we place an item on the queue the other task should + wake but not execute as this task has higher priority. */ + if( xQueueSend( xTestQueue, &xItem, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Now empty the queue again before the other task gets a chance to + execute. If the other task had executed we would find the queue + empty ourselves, and the other task would be suspended. */ + if( xQueueReceive( xTestQueue, &xData, bktDONT_BLOCK ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed. */ + xErrorOccurred = pdTRUE; + } + + /* Raise the priority of the other task so it executes and blocks + on the queue again. */ + vTaskPrioritySet( xSecondary, bktPRIMARY_PRIORITY + 2 ); + + /* The other task should now have re-blocked without exiting the + queue function. */ + if( xRunIndicator == bktRUN_INDICATOR ) + { + /* The other task should not have executed outside of the + queue function. */ + xErrorOccurred = pdTRUE; + } + vTaskPrioritySet( xSecondary, bktSECONDARY_PRIORITY ); + } + + /* Let the other task timeout. When it unblockes it will check that it + unblocked at the correct time, then suspend itself. */ + while( xRunIndicator != bktRUN_INDICATOR ) + { + vTaskDelay( bktSHORT_WAIT ); + } + vTaskDelay( bktSHORT_WAIT ); + + xPrimaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void vSecondaryBlockTimeTestTask( void *pvParameters ) +{ +TickType_t xTimeWhenBlocking, xBlockedTime; +BaseType_t xData; + + ( void ) pvParameters; + + for( ;; ) + { + /********************************************************************* + Test 0, 1 and 2 + + This task does not participate in these tests. */ + vTaskSuspend( NULL ); + + /********************************************************************* + Test 3 + + The first thing we do is attempt to read from the queue. It should be + full so we block. Note the time before we block so we can check the + wake time is as per that expected. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not sent anything to + the queue. */ + xData = 0; + xRunIndicator = bktRUN_INDICATOR; + if( xQueueSend( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_FULL ) + { + xErrorOccurred = pdTRUE; + } + + /* How long were we inside the send function? */ + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as + soon as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Suspend ready for test 3. */ + xRunIndicator = bktRUN_INDICATOR; + vTaskSuspend( NULL ); + + /********************************************************************* + Test 4 + + As per test three, but with the send and receive reversed. */ + xTimeWhenBlocking = xTaskGetTickCount(); + + /* We should unblock after bktTIME_TO_BLOCK having not received + anything on the queue. */ + xRunIndicator = bktRUN_INDICATOR; + if( xQueueReceive( xTestQueue, &xData, bktTIME_TO_BLOCK ) != errQUEUE_EMPTY ) + { + xErrorOccurred = pdTRUE; + } + + xBlockedTime = xTaskGetTickCount() - xTimeWhenBlocking; + + /* We should not have blocked for less time than bktTIME_TO_BLOCK. */ + if( xBlockedTime < bktTIME_TO_BLOCK ) + { + xErrorOccurred = pdTRUE; + } + + /* We should of not blocked for much longer than bktALLOWABLE_MARGIN + either. A margin is permitted as we would not necessarily run as soon + as we unblocked. */ + if( xBlockedTime > ( bktTIME_TO_BLOCK + bktALLOWABLE_MARGIN ) ) + { + xErrorOccurred = pdTRUE; + } + + xRunIndicator = bktRUN_INDICATOR; + + xSecondaryCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvBasicDelayTests( void ) +{ +TickType_t xPreTime, xPostTime, x, xLastUnblockTime, xExpectedUnblockTime; +const TickType_t xPeriod = 75, xCycles = 5, xAllowableMargin = ( bktALLOWABLE_MARGIN >> 1 ); + + /* Temporarily increase priority so the timing is more accurate, but not so + high as to disrupt the timer tests. */ + vTaskPrioritySet( NULL, configTIMER_TASK_PRIORITY - 1 ); + + /* Crude check to too that vTaskDelay() blocks for the expected period. */ + xPreTime = xTaskGetTickCount(); + vTaskDelay( bktTIME_TO_BLOCK ); + xPostTime = xTaskGetTickCount(); + + /* The priority is higher, so the allowable margin is halved when compared + to the other tests in this file. */ + if( ( xPostTime - xPreTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Now crude tests to check the vTaskDelayUntil() functionality. */ + xPostTime = xTaskGetTickCount(); + xLastUnblockTime = xPostTime; + + for( x = 0; x < xCycles; x++ ) + { + /* Calculate the next expected unblock time from the time taken before + this loop was entered. */ + xExpectedUnblockTime = xPostTime + ( x * xPeriod ); + + vTaskDelayUntil( &xLastUnblockTime, xPeriod ); + + if( ( xTaskGetTickCount() - xExpectedUnblockTime ) > ( bktTIME_TO_BLOCK + xAllowableMargin ) ) + { + xErrorOccurred = pdTRUE; + } + + xPrimaryCycles++; + } + + /* Reset to the original task priority ready for the other tests. */ + vTaskPrioritySet( NULL, bktPRIMARY_PRIORITY ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreBlockTimeTestTasksStillRunning( void ) +{ +static BaseType_t xLastPrimaryCycleCount = 0, xLastSecondaryCycleCount = 0; +BaseType_t xReturn = pdPASS; + + /* Have both tasks performed at least one cycle since this function was + last called? */ + if( xPrimaryCycles == xLastPrimaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xSecondaryCycles == xLastSecondaryCycleCount ) + { + xReturn = pdFAIL; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + + xLastSecondaryCycleCount = xSecondaryCycles; + xLastPrimaryCycleCount = xPrimaryCycles; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest.c new file mode 100644 index 0000000..16cf02a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest.c @@ -0,0 +1,307 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * This version of comtest. c is for use on systems that have limited stack + * space and no display facilities. The complete version can be found in + * the Demo/Common/Full directory. + * + * Creates two tasks that operate on an interrupt driven serial port. A + * loopback connector should be used so that everything that is transmitted is + * also received. The serial port does not use any flow control. On a + * standard 9way 'D' connector pins two and three should be connected together. + * + * The first task posts a sequence of characters to the Tx queue, toggling an + * LED on each successful post. At the end of the sequence it sleeps for a + * pseudo-random period before resending the same sequence. + * + * The UART Tx end interrupt is enabled whenever data is available in the Tx + * queue. The Tx end ISR removes a single character from the Tx queue and + * passes it to the UART for transmission. + * + * The second task blocks on the Rx queue waiting for a character to become + * available. When the UART Rx end interrupt receives a character it places + * it in the Rx queue, waking the second task. The second task checks that the + * characters removed from the Rx queue form the same sequence as those posted + * to the Tx queue, and toggles an LED for each correct character. + * + * The receiving task is spawned with a higher priority than the transmitting + * task. The receiver will therefore wake every time a character is + * transmitted so neither the Tx or Rx queue should ever hold more than a few + * characters. + * + */ + +/* Scheduler include files. */ +#include +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "serial.h" +#include "comtest.h" +#include "partest.h" + +#define comSTACK_SIZE configMINIMAL_STACK_SIZE +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) +#define comTOTAL_PERMISSIBLE_ERRORS ( 2 ) + +/* The Tx task will transmit the sequence of characters at a pseudo random +interval. This is the maximum and minimum block time between sends. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 ) +#define comOFFSET_TIME ( ( TickType_t ) 3 ) + +/* We should find that each character can be queued for Tx immediately and we +don't have to block to send. */ +#define comNO_BLOCK ( ( TickType_t ) 0 ) + +/* The Rx task will block on the Rx queue for a long period. */ +#define comRX_BLOCK_TIME ( ( TickType_t ) 0xffff ) + +/* The sequence transmitted is from comFIRST_BYTE to and including comLAST_BYTE. */ +#define comFIRST_BYTE ( 'A' ) +#define comLAST_BYTE ( 'X' ) + +#define comBUFFER_LEN ( ( UBaseType_t ) ( comLAST_BYTE - comFIRST_BYTE ) + ( UBaseType_t ) 1 ) +#define comINITIAL_RX_COUNT_VALUE ( 0 ) + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The transmit task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComTxTask, pvParameters ); + +/* The receive task as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( vComRxTask, pvParameters ); + +/* The LED that should be toggled by the Rx and Tx tasks. The Rx task will +toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task will toggle LED +( uxBaseLED + comTX_LED_OFFSET ). */ +static UBaseType_t uxBaseLED = 0; + +/* Check variable used to ensure no error have occurred. The Rx task will +increment this variable after every successfully received sequence. If at any +time the sequence is incorrect the the variable will stop being incremented. */ +static volatile UBaseType_t uxRxLoops = comINITIAL_RX_COUNT_VALUE; + +/*-----------------------------------------------------------*/ + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ) +{ + /* Initialise the com port then spawn the Rx and Tx tasks. */ + uxBaseLED = uxLED; + xSerialPortInitMinimal( ulBaudRate, comBUFFER_LEN ); + + /* The Tx task is spawned with a lower priority than the Rx task. */ + xTaskCreate( vComTxTask, "COMTx", comSTACK_SIZE, NULL, uxPriority - 1, ( TaskHandle_t * ) NULL ); + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComTxTask, pvParameters ) +{ +char cByteToSend; +TickType_t xTimeToWait; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Simply transmit a sequence of characters from comFIRST_BYTE to + comLAST_BYTE. */ + for( cByteToSend = comFIRST_BYTE; cByteToSend <= comLAST_BYTE; cByteToSend++ ) + { + if( xSerialPutChar( xPort, cByteToSend, comNO_BLOCK ) == pdPASS ) + { + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comTX_LED_OFFSET, pdFALSE ); + + /* We have posted all the characters in the string - wait before + re-sending. Wait a pseudo-random time as this will provide a better + test. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Make sure we don't wait too long... */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* ...but we do want to wait. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + vTaskDelay( xTimeToWait ); + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vComRxTask, pvParameters ) +{ +signed char cExpectedByte, cByteRxed; +BaseType_t xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE; + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + for( ;; ) + { + /* We expect to receive the characters from comFIRST_BYTE to + comLAST_BYTE in an incrementing order. Loop to receive each byte. */ + for( cExpectedByte = comFIRST_BYTE; cExpectedByte <= comLAST_BYTE; cExpectedByte++ ) + { + /* Block on the queue that contains received bytes until a byte is + available. */ + if( xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ) ) + { + /* Was this the byte we were expecting? If so, toggle the LED, + otherwise we are out on sync and should break out of the loop + until the expected character sequence is about to restart. */ + if( cByteRxed == cExpectedByte ) + { + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + else + { + xResyncRequired = pdTRUE; + break; /*lint !e960 Non-switch break allowed. */ + } + } + } + + /* Turn the LED off while we are not doing anything. */ + vParTestSetLED( uxBaseLED + comRX_LED_OFFSET, pdFALSE ); + + /* Did we break out of the loop because the characters were received in + an unexpected order? If so wait here until the character sequence is + about to restart. */ + if( xResyncRequired == pdTRUE ) + { + while( cByteRxed != comLAST_BYTE ) + { + /* Block until the next char is available. */ + xSerialGetChar( xPort, &cByteRxed, comRX_BLOCK_TIME ); + } + + /* Note that an error occurred which caused us to have to resync. + We use this to stop incrementing the loop counter so + sAreComTestTasksStillRunning() will return false - indicating an + error. */ + xErrorOccurred++; + + /* We have now resynced with the Tx task and can continue. */ + xResyncRequired = pdFALSE; + } + else + { + if( xErrorOccurred < comTOTAL_PERMISSIBLE_ERRORS ) + { + /* Increment the count of successful loops. As error + occurring (i.e. an unexpected character being received) will + prevent this counter being incremented for the rest of the + execution. Don't worry about mutual exclusion on this + variable - it doesn't really matter as we just want it + to change. */ + uxRxLoops++; + } + } + } +} /*lint !e715 !e818 pvParameters is required for a task function even if it is not referenced. */ +/*-----------------------------------------------------------*/ + +BaseType_t xAreComTestTasksStillRunning( void ) +{ +BaseType_t xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and we will return false. */ + if( uxRxLoops == comINITIAL_RX_COUNT_VALUE ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again we expect this to have been incremented. */ + uxRxLoops = comINITIAL_RX_COUNT_VALUE; + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest_strings.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest_strings.c new file mode 100644 index 0000000..7ca5f3a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/comtest_strings.c @@ -0,0 +1,353 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Creates a task and a timer that operate on an interrupt driven serial port. + * This demo assumes that the characters transmitted on a port will also be + * received on the same port. Therefore, the UART must either be connected to + * an echo server, or the uart connector must have a loopback connector fitted. + * See http://www.serialporttool.com/CommEcho.htm for a suitable echo server + * for Windows hosts. + * + * The timer sends a string to the UART, toggles an LED, then resets itself by + * changing its own period. The period is calculated as a pseudo random number + * between comTX_MAX_BLOCK_TIME and comTX_MIN_BLOCK_TIME. + * + * The task blocks on an Rx queue waiting for a character to become available. + * Received characters are checked to ensure they match those transmitted by the + * Tx timer. An error is latched if characters are missing, incorrect, or + * arrive too slowly. + * + * How characters are actually transmitted and received is port specific. Demos + * that include this test/demo file will provide example drivers. The Tx timer + * executes in the context of the timer service (daemon) task, and must + * therefore never attempt to block. + * + */ + +/* Scheduler include files. */ +#include +#include +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" + +#ifndef configUSE_TIMERS + #error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h. +#endif + +#if configUSE_TIMERS != 1 + #error This demo uses timers. configUSE_TIMERS must be set to 1 in FreeRTOSConfig.h. +#endif + + +/* Demo program include files. */ +#include "serial.h" +#include "comtest_strings.h" +#include "partest.h" + +/* The size of the stack given to the Rx task. */ +#define comSTACK_SIZE configMINIMAL_STACK_SIZE + +/* See the comment above the declaraction of the uxBaseLED variable. */ +#define comTX_LED_OFFSET ( 0 ) +#define comRX_LED_OFFSET ( 1 ) + +/* The Tx timer transmits the sequence of characters at a pseudo random +interval that is capped between comTX_MAX_BLOCK_TIME and +comTX_MIN_BLOCK_TIME. */ +#define comTX_MAX_BLOCK_TIME ( ( TickType_t ) 0x96 ) +#define comTX_MIN_BLOCK_TIME ( ( TickType_t ) 0x32 ) +#define comOFFSET_TIME ( ( TickType_t ) 3 ) + +/* States for the simple state machine implemented in the Rx task. */ +#define comtstWAITING_START_OF_STRING 0 +#define comtstWAITING_END_OF_STRING 1 + +/* A short delay in ticks - this delay is used to allow the Rx queue to fill up +a bit so more than one character can be processed at a time. This is relative +to comTX_MIN_BLOCK_TIME to ensure it is never longer than the shortest gap +between transmissions. It could be worked out more scientifically from the +baud rate being used. */ +#define comSHORT_DELAY ( comTX_MIN_BLOCK_TIME >> ( TickType_t ) 2 ) + +/* The string that is transmitted and received. */ +#define comTRANSACTED_STRING "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + +/* A block time of 0 simply means "don't block". */ +#define comtstDONT_BLOCK ( TickType_t ) 0 + +/* Handle to the com port used by both tasks. */ +static xComPortHandle xPort = NULL; + +/* The callback function allocated to the transmit timer, as described in the +comments at the top of this file. */ +static void prvComTxTimerCallback( TimerHandle_t xTimer ); + +/* The receive task as described in the comments at the top of this file. */ +static void vComRxTask( void *pvParameters ); + +/* The Rx task will toggle LED ( uxBaseLED + comRX_LED_OFFSET). The Tx task +will toggle LED ( uxBaseLED + comTX_LED_OFFSET ). */ +static UBaseType_t uxBaseLED = 0; + +/* The Rx task toggles uxRxLoops on each successful iteration of its defined +function - provided no errors have ever been latched. If this variable stops +incrementing, then an error has occurred. */ +static volatile UBaseType_t uxRxLoops = 0UL; + +/* The timer used to periodically transmit the string. This is the timer that +has prvComTxTimerCallback allocated to it as its callback function. */ +static TimerHandle_t xTxTimer = NULL; + +/* The string length is held at file scope so the Tx timer does not need to +calculate it each time it executes. */ +static size_t xStringLength = 0U; + +/*-----------------------------------------------------------*/ + +void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ) +{ + /* Store values that are used at run time. */ + uxBaseLED = uxLED; + + /* Calculate the string length here, rather than each time the Tx timer + executes. */ + xStringLength = strlen( comTRANSACTED_STRING ); + + /* Include the null terminator in the string length as this is used to + detect the end of the string in the Rx task. */ + xStringLength++; + + /* Initialise the com port, then spawn the Rx task and create the Tx + timer. */ + xSerialPortInitMinimal( ulBaudRate, ( xStringLength * 2U ) ); + + /* Create the Rx task and the Tx timer. The timer is started from the + Rx task. */ + xTaskCreate( vComRxTask, "COMRx", comSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); + xTxTimer = xTimerCreate( "TxTimer", comTX_MIN_BLOCK_TIME, pdFALSE, NULL, prvComTxTimerCallback ); + configASSERT( xTxTimer ); +} +/*-----------------------------------------------------------*/ + +static void prvComTxTimerCallback( TimerHandle_t xTimer ) +{ +TickType_t xTimeToWait; + + /* The parameter is not used in this case. */ + ( void ) xTimer; + + /* Send the string. How this is actually performed depends on the + sample driver provided with this demo. However - as this is a timer, + it executes in the context of the timer task and therefore must not + block. */ + vSerialPutString( xPort, comTRANSACTED_STRING, xStringLength ); + + /* Toggle an LED to give a visible indication that another transmission + has been performed. */ + vParTestToggleLED( uxBaseLED + comTX_LED_OFFSET ); + + /* Wait a pseudo random time before sending the string again. */ + xTimeToWait = xTaskGetTickCount() + comOFFSET_TIME; + + /* Ensure the time to wait is not greater than comTX_MAX_BLOCK_TIME. */ + xTimeToWait %= comTX_MAX_BLOCK_TIME; + + /* Ensure the time to wait is not less than comTX_MIN_BLOCK_TIME. */ + if( xTimeToWait < comTX_MIN_BLOCK_TIME ) + { + xTimeToWait = comTX_MIN_BLOCK_TIME; + } + + /* Reset the timer to run again xTimeToWait ticks from now. This function + is called from the context of the timer task, so the block time must not + be anything other than zero. */ + xTimerChangePeriod( xTxTimer, xTimeToWait, comtstDONT_BLOCK ); +} +/*-----------------------------------------------------------*/ + +static void vComRxTask( void *pvParameters ) +{ +BaseType_t xState = comtstWAITING_START_OF_STRING, xErrorOccurred = pdFALSE; +char *pcExpectedByte, cRxedChar; +const xComPortHandle xPort = NULL; + + /* The parameter is not used in this example. */ + ( void ) pvParameters; + + /* Start the Tx timer. This only needs to be started once, as it will + reset itself thereafter. */ + xTimerStart( xTxTimer, portMAX_DELAY ); + + /* The first expected Rx character is the first in the string that is + transmitted. */ + pcExpectedByte = comTRANSACTED_STRING; + + for( ;; ) + { + /* Wait for the next character. */ + if( xSerialGetChar( xPort, &cRxedChar, ( comTX_MAX_BLOCK_TIME * 2 ) ) == pdFALSE ) + { + /* A character definitely should have been received by now. As a + character was not received an error must have occurred (which might + just be that the loopback connector is not fitted). */ + xErrorOccurred = pdTRUE; + } + + switch( xState ) + { + case comtstWAITING_START_OF_STRING: + if( cRxedChar == *pcExpectedByte ) + { + /* The received character was the first character of the + string. Move to the next state to check each character + as it comes in until the entire string has been received. */ + xState = comtstWAITING_END_OF_STRING; + pcExpectedByte++; + + /* Block for a short period. This just allows the Rx queue + to contain more than one character, and therefore prevent + thrashing reads to the queue, and repetitive context + switches as each character is received. */ + vTaskDelay( comSHORT_DELAY ); + } + break; + + case comtstWAITING_END_OF_STRING: + if( cRxedChar == *pcExpectedByte ) + { + /* The received character was the expected character. Was + it the last character in the string - i.e. the null + terminator? */ + if( cRxedChar == 0x00 ) + { + /* The entire string has been received. If no errors + have been latched, then increment the loop counter to + show this task is still healthy. */ + if( xErrorOccurred == pdFALSE ) + { + uxRxLoops++; + + /* Toggle an LED to give a visible sign that a + complete string has been received. */ + vParTestToggleLED( uxBaseLED + comRX_LED_OFFSET ); + } + + /* Go back to wait for the start of the next string. */ + pcExpectedByte = comTRANSACTED_STRING; + xState = comtstWAITING_START_OF_STRING; + } + else + { + /* Wait for the next character in the string. */ + pcExpectedByte++; + } + } + else + { + /* The character received was not that expected. */ + xErrorOccurred = pdTRUE; + } + break; + + default: + /* Should not get here. Stop the Rx loop counter from + incrementing to latch the error. */ + xErrorOccurred = pdTRUE; + break; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreComTestTasksStillRunning( void ) +{ +BaseType_t xReturn; + + /* If the count of successful reception loops has not changed than at + some time an error occurred (i.e. a character was received out of sequence) + and false is returned. */ + if( uxRxLoops == 0UL ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + /* Reset the count of successful Rx loops. When this function is called + again it should have been incremented again. */ + uxRxLoops = 0UL; + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/countsem.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/countsem.c new file mode 100644 index 0000000..5607e62 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/countsem.c @@ -0,0 +1,330 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +/* + * Simple demonstration of the usage of counting semaphore. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo program include files. */ +#include "countsem.h" + +/* The maximum count value that the semaphore used for the demo can hold. */ +#define countMAX_COUNT_VALUE ( 200 ) + +/* Constants used to indicate whether or not the semaphore should have been +created with its maximum count value, or its minimum count value. These +numbers are used to ensure that the pointers passed in as the task parameters +are valid. */ +#define countSTART_AT_MAX_COUNT ( 0xaa ) +#define countSTART_AT_ZERO ( 0x55 ) + +/* Two tasks are created for the test. One uses a semaphore created with its +count value set to the maximum, and one with the count value set to zero. */ +#define countNUM_TEST_TASKS ( 2 ) +#define countDONT_BLOCK ( 0 ) + +/*-----------------------------------------------------------*/ + +/* Flag that will be latched to pdTRUE should any unexpected behaviour be +detected in any of the tasks. */ +static volatile BaseType_t xErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +/* + * The demo task. This simply counts the semaphore up to its maximum value, + * the counts it back down again. The result of each semaphore 'give' and + * 'take' is inspected, with an error being flagged if it is found not to be + * the expected result. + */ +static void prvCountingSemaphoreTask( void *pvParameters ); + +/* + * Utility function to increment the semaphore count value up from zero to + * countMAX_COUNT_VALUE. + */ +static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ); + +/* + * Utility function to decrement the semaphore count value up from + * countMAX_COUNT_VALUE to zero. + */ +static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ); + +/*-----------------------------------------------------------*/ + +/* The structure that is passed into the task as the task parameter. */ +typedef struct COUNT_SEM_STRUCT +{ + /* The semaphore to be used for the demo. */ + SemaphoreHandle_t xSemaphore; + + /* Set to countSTART_AT_MAX_COUNT if the semaphore should be created with + its count value set to its max count value, or countSTART_AT_ZERO if it + should have been created with its count value set to 0. */ + UBaseType_t uxExpectedStartCount; + + /* Incremented on each cycle of the demo task. Used to detect a stalled + task. */ + UBaseType_t uxLoopCounter; +} xCountSemStruct; + +/* Two structures are defined, one is passed to each test task. */ +static volatile xCountSemStruct xParameters[ countNUM_TEST_TASKS ]; + +/*-----------------------------------------------------------*/ + +void vStartCountingSemaphoreTasks( void ) +{ + /* Create the semaphores that we are going to use for the test/demo. The + first should be created such that it starts at its maximum count value, + the second should be created such that it starts with a count value of zero. */ + xParameters[ 0 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, countMAX_COUNT_VALUE ); + xParameters[ 0 ].uxExpectedStartCount = countSTART_AT_MAX_COUNT; + xParameters[ 0 ].uxLoopCounter = 0; + + xParameters[ 1 ].xSemaphore = xSemaphoreCreateCounting( countMAX_COUNT_VALUE, 0 ); + xParameters[ 1 ].uxExpectedStartCount = 0; + xParameters[ 1 ].uxLoopCounter = 0; + + /* Were the semaphores created? */ + if( ( xParameters[ 0 ].xSemaphore != NULL ) || ( xParameters[ 1 ].xSemaphore != NULL ) ) + { + /* vQueueAddToRegistry() adds the semaphore to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware + debugger is not being used. The call to vQueueAddToRegistry() will be + removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not + defined or is defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 0 ].xSemaphore, "Counting_Sem_1" ); + vQueueAddToRegistry( ( QueueHandle_t ) xParameters[ 1 ].xSemaphore, "Counting_Sem_2" ); + + /* Create the demo tasks, passing in the semaphore to use as the parameter. */ + xTaskCreate( prvCountingSemaphoreTask, "CNT1", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 0 ] ), tskIDLE_PRIORITY, NULL ); + xTaskCreate( prvCountingSemaphoreTask, "CNT2", configMINIMAL_STACK_SIZE, ( void * ) &( xParameters[ 1 ] ), tskIDLE_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvDecrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ) +{ +UBaseType_t ux; + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'take' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + configASSERT( uxSemaphoreGetCount( xSemaphore ) == ( countMAX_COUNT_VALUE - ux ) ); + + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + configASSERT( uxSemaphoreGetCount( xSemaphore ) == 0 ); + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvIncrementSemaphoreCount( SemaphoreHandle_t xSemaphore, UBaseType_t *puxLoopCounter ) +{ +UBaseType_t ux; + + /* If the semaphore count is zero then we should not be able to 'take' + the semaphore. */ + if( xSemaphoreTake( xSemaphore, countDONT_BLOCK ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + /* We should be able to 'give' the semaphore countMAX_COUNT_VALUE times. */ + for( ux = 0; ux < countMAX_COUNT_VALUE; ux++ ) + { + configASSERT( uxSemaphoreGetCount( xSemaphore ) == ux ); + + if( xSemaphoreGive( xSemaphore ) != pdPASS ) + { + /* We expected to be able to take the semaphore. */ + xErrorDetected = pdTRUE; + } + + ( *puxLoopCounter )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the semaphore count is at its maximum then we should not be able to + 'give' the semaphore. */ + if( xSemaphoreGive( xSemaphore ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +static void prvCountingSemaphoreTask( void *pvParameters ) +{ +xCountSemStruct *pxParameter; + + #ifdef USE_STDIO + void vPrintDisplayMessage( const char * const * ppcMessageToSend ); + + const char * const pcTaskStartMsg = "Counting semaphore demo started.\r\n"; + + /* Queue a message for printing to say the task has started. */ + vPrintDisplayMessage( &pcTaskStartMsg ); + #endif + + /* The semaphore to be used was passed as the parameter. */ + pxParameter = ( xCountSemStruct * ) pvParameters; + + /* Did we expect to find the semaphore already at its max count value, or + at zero? */ + if( pxParameter->uxExpectedStartCount == countSTART_AT_MAX_COUNT ) + { + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } + + /* Now we expect the semaphore count to be 0, so this time there is an + error if we can take the semaphore. */ + if( xSemaphoreTake( pxParameter->xSemaphore, 0 ) == pdPASS ) + { + xErrorDetected = pdTRUE; + } + + for( ;; ) + { + prvIncrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + prvDecrementSemaphoreCount( pxParameter->xSemaphore, &( pxParameter->uxLoopCounter ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreCountingSemaphoreTasksStillRunning( void ) +{ +static UBaseType_t uxLastCount0 = 0, uxLastCount1 = 0; +BaseType_t xReturn = pdPASS; + + /* Return fail if any 'give' or 'take' did not result in the expected + behaviour. */ + if( xErrorDetected != pdFALSE ) + { + xReturn = pdFAIL; + } + + /* Return fail if either task is not still incrementing its loop counter. */ + if( uxLastCount0 == xParameters[ 0 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount0 = xParameters[ 0 ].uxLoopCounter; + } + + if( uxLastCount1 == xParameters[ 1 ].uxLoopCounter ) + { + xReturn = pdFAIL; + } + else + { + uxLastCount1 = xParameters[ 1 ].uxLoopCounter; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crflash.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crflash.c new file mode 100644 index 0000000..c10c4ef --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crflash.c @@ -0,0 +1,250 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This demo application file demonstrates the use of queues to pass data + * between co-routines. + * + * N represents the number of 'fixed delay' co-routines that are created and + * is set during initialisation. + * + * N 'fixed delay' co-routines are created that just block for a fixed + * period then post the number of an LED onto a queue. Each such co-routine + * uses a different block period. A single 'flash' co-routine is also created + * that blocks on the same queue, waiting for the number of the next LED it + * should flash. Upon receiving a number it simply toggle the instructed LED + * then blocks on the queue once more. In this manner each LED from LED 0 to + * LED N-1 is caused to flash at a different rate. + * + * The 'fixed delay' co-routines are created with co-routine priority 0. The + * flash co-routine is created with co-routine priority 1. This means that + * the queue should never contain more than a single item. This is because + * posting to the queue will unblock the 'flash' co-routine, and as this has + * a priority greater than the tasks posting to the queue it is guaranteed to + * have emptied the queue and blocked once again before the queue can contain + * any more date. An error is indicated if an attempt to post data to the + * queue fails - indicating that the queue is already full. + * + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "partest.h" +#include "crflash.h" + +/* The queue should only need to be of length 1. See the description at the +top of the file. */ +#define crfQUEUE_LENGTH 1 + +#define crfFIXED_DELAY_PRIORITY 0 +#define crfFLASH_PRIORITY 1 + +/* Only one flash co-routine is created so the index is not significant. */ +#define crfFLASH_INDEX 0 + +/* Don't allow more than crfMAX_FLASH_TASKS 'fixed delay' co-routines to be +created. */ +#define crfMAX_FLASH_TASKS 8 + +/* We don't want to block when posting to the queue. */ +#define crfPOSTING_BLOCK_TIME 0 + +/* + * The 'fixed delay' co-routine as described at the top of the file. + */ +static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + +/* + * The 'flash' co-routine as described at the top of the file. + */ +static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + +/* The queue used to pass data between the 'fixed delay' co-routines and the +'flash' co-routine. */ +static QueueHandle_t xFlashQueue; + +/* This will be set to pdFALSE if we detect an error. */ +static BaseType_t xCoRoutineFlashStatus = pdPASS; + +/*-----------------------------------------------------------*/ + +/* + * See the header file for details. + */ +void vStartFlashCoRoutines( UBaseType_t uxNumberToCreate ) +{ +UBaseType_t uxIndex; + + if( uxNumberToCreate > crfMAX_FLASH_TASKS ) + { + uxNumberToCreate = crfMAX_FLASH_TASKS; + } + + /* Create the queue used to pass data between the co-routines. */ + xFlashQueue = xQueueCreate( crfQUEUE_LENGTH, sizeof( UBaseType_t ) ); + + if( xFlashQueue ) + { + /* Create uxNumberToCreate 'fixed delay' co-routines. */ + for( uxIndex = 0; uxIndex < uxNumberToCreate; uxIndex++ ) + { + xCoRoutineCreate( prvFixedDelayCoRoutine, crfFIXED_DELAY_PRIORITY, uxIndex ); + } + + /* Create the 'flash' co-routine. */ + xCoRoutineCreate( prvFlashCoRoutine, crfFLASH_PRIORITY, crfFLASH_INDEX ); + } +} +/*-----------------------------------------------------------*/ + +static void prvFixedDelayCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +/* Even though this is a co-routine the xResult variable does not need to be +static as we do not need it to maintain its state between blocks. */ +BaseType_t xResult; +/* The uxIndex parameter of the co-routine function is used as an index into +the xFlashRates array to obtain the delay period to use. */ +static const TickType_t xFlashRates[ crfMAX_FLASH_TASKS ] = { 150 / portTICK_PERIOD_MS, + 200 / portTICK_PERIOD_MS, + 250 / portTICK_PERIOD_MS, + 300 / portTICK_PERIOD_MS, + 350 / portTICK_PERIOD_MS, + 400 / portTICK_PERIOD_MS, + 450 / portTICK_PERIOD_MS, + 500 / portTICK_PERIOD_MS }; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + + for( ;; ) + { + /* Post our uxIndex value onto the queue. This is used as the LED to + flash. */ + crQUEUE_SEND( xHandle, xFlashQueue, ( void * ) &uxIndex, crfPOSTING_BLOCK_TIME, &xResult ); + + if( xResult != pdPASS ) + { + /* For the reasons stated at the top of the file we should always + find that we can post to the queue. If we could not then an error + has occurred. */ + xCoRoutineFlashStatus = pdFAIL; + } + + crDELAY( xHandle, xFlashRates[ uxIndex ] ); + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +static void prvFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +/* Even though this is a co-routine the variable do not need to be +static as we do not need it to maintain their state between blocks. */ +BaseType_t xResult; +UBaseType_t uxLEDToFlash; + + /* Co-routines MUST start with a call to crSTART. */ + crSTART( xHandle ); + ( void ) uxIndex; + + for( ;; ) + { + /* Block to wait for the number of the LED to flash. */ + crQUEUE_RECEIVE( xHandle, xFlashQueue, &uxLEDToFlash, portMAX_DELAY, &xResult ); + + if( xResult != pdPASS ) + { + /* We would not expect to wake unless we received something. */ + xCoRoutineFlashStatus = pdFAIL; + } + else + { + /* We received the number of an LED to flash - flash it! */ + vParTestToggleLED( uxLEDToFlash ); + } + } + + /* Co-routines MUST end with a call to crEND. */ + crEND(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreFlashCoRoutinesStillRunning( void ) +{ + /* Return pdPASS or pdFAIL depending on whether an error has been detected + or not. */ + return xCoRoutineFlashStatus; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crhook.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crhook.c new file mode 100644 index 0000000..71e6174 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/crhook.c @@ -0,0 +1,274 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This demo file demonstrates how to send data between an ISR and a + * co-routine. A tick hook function is used to periodically pass data between + * the RTOS tick and a set of 'hook' co-routines. + * + * hookNUM_HOOK_CO_ROUTINES co-routines are created. Each co-routine blocks + * to wait for a character to be received on a queue from the tick ISR, checks + * to ensure the character received was that expected, then sends the number + * back to the tick ISR on a different queue. + * + * The tick ISR checks the numbers received back from the 'hook' co-routines + * matches the number previously sent. + * + * If at any time a queue function returns unexpectedly, or an incorrect value + * is received either by the tick hook or a co-routine then an error is + * latched. + * + * This demo relies on each 'hook' co-routine to execute between each + * hookTICK_CALLS_BEFORE_POST tick interrupts. This and the heavy use of + * queues from within an interrupt may result in an error being detected on + * slower targets simply due to timing. + */ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "croutine.h" +#include "queue.h" + +/* Demo application includes. */ +#include "crhook.h" + +/* The number of 'hook' co-routines that are to be created. */ +#define hookNUM_HOOK_CO_ROUTINES ( 4 ) + +/* The number of times the tick hook should be called before a character is +posted to the 'hook' co-routines. */ +#define hookTICK_CALLS_BEFORE_POST ( 500 ) + +/* There should never be more than one item in any queue at any time. */ +#define hookHOOK_QUEUE_LENGTH ( 1 ) + +/* Don't block when initially posting to the queue. */ +#define hookNO_BLOCK_TIME ( 0 ) + +/* The priority relative to other co-routines (rather than tasks) that the +'hook' co-routines should take. */ +#define mainHOOK_CR_PRIORITY ( 1 ) +/*-----------------------------------------------------------*/ + +/* + * The co-routine function itself. + */ +static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ); + + +/* + * The tick hook function. This receives a number from each 'hook' co-routine + * then sends a number to each co-routine. An error is flagged if a send or + * receive fails, or an unexpected number is received. + */ +void vApplicationTickHook( void ); + +/*-----------------------------------------------------------*/ + +/* Queues used to send data FROM a co-routine TO the tick hook function. +The hook functions received (Rx's) on these queues. One queue per +'hook' co-routine. */ +static QueueHandle_t xHookRxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Queues used to send data FROM the tick hook TO a co-routine function. +The hood function transmits (Tx's) on these queues. One queue per +'hook' co-routine. */ +static QueueHandle_t xHookTxQueues[ hookNUM_HOOK_CO_ROUTINES ]; + +/* Set to true if an error is detected at any time. */ +static BaseType_t xCoRoutineErrorDetected = pdFALSE; + +/*-----------------------------------------------------------*/ + +void vStartHookCoRoutines( void ) +{ +UBaseType_t uxIndex, uxValueToPost = 0; + + for( uxIndex = 0; uxIndex < hookNUM_HOOK_CO_ROUTINES; uxIndex++ ) + { + /* Create a queue to transmit to and receive from each 'hook' + co-routine. */ + xHookRxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) ); + xHookTxQueues[ uxIndex ] = xQueueCreate( hookHOOK_QUEUE_LENGTH, sizeof( UBaseType_t ) ); + + /* To start things off the tick hook function expects the queue it + uses to receive data to contain a value. */ + xQueueSend( xHookRxQueues[ uxIndex ], &uxValueToPost, hookNO_BLOCK_TIME ); + + /* Create the 'hook' co-routine itself. */ + xCoRoutineCreate( prvHookCoRoutine, mainHOOK_CR_PRIORITY, uxIndex ); + } +} +/*-----------------------------------------------------------*/ + +static UBaseType_t uxCallCounter = 0, uxNumberToPost = 0; +void vApplicationTickHook( void ) +{ +UBaseType_t uxReceivedNumber; +BaseType_t xIndex, xCoRoutineWoken; + + /* Is it time to talk to the 'hook' co-routines again? */ + uxCallCounter++; + if( uxCallCounter >= hookTICK_CALLS_BEFORE_POST ) + { + uxCallCounter = 0; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + xCoRoutineWoken = pdFALSE; + if( crQUEUE_RECEIVE_FROM_ISR( xHookRxQueues[ xIndex ], &uxReceivedNumber, &xCoRoutineWoken ) != pdPASS ) + { + /* There is no reason why we would not expect the queue to + contain a value. */ + xCoRoutineErrorDetected = pdTRUE; + } + else + { + /* Each queue used to receive data from the 'hook' co-routines + should contain the number we last posted to the same co-routine. */ + if( uxReceivedNumber != uxNumberToPost ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Nothing should be blocked waiting to post to the queue. */ + if( xCoRoutineWoken != pdFALSE ) + { + xCoRoutineErrorDetected = pdTRUE; + } + } + } + + /* Start the next cycle by posting the next number onto each Tx queue. */ + uxNumberToPost++; + + for( xIndex = 0; xIndex < hookNUM_HOOK_CO_ROUTINES; xIndex++ ) + { + if( crQUEUE_SEND_FROM_ISR( xHookTxQueues[ xIndex ], &uxNumberToPost, pdFALSE ) != pdTRUE ) + { + /* Posting to the queue should have woken the co-routine that + was blocked on the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvHookCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex ) +{ +static UBaseType_t uxReceivedValue[ hookNUM_HOOK_CO_ROUTINES ]; +BaseType_t xResult; + + /* Each co-routine MUST start with a call to crSTART(); */ + crSTART( xHandle ); + + for( ;; ) + { + /* Wait to receive a value from the tick hook. */ + xResult = pdFAIL; + crQUEUE_RECEIVE( xHandle, xHookTxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), portMAX_DELAY, &xResult ); + + /* There is no reason why we should not have received something on + the queue. */ + if( xResult != pdPASS ) + { + xCoRoutineErrorDetected = pdTRUE; + } + + /* Send the same number back to the idle hook so it can verify it. */ + xResult = pdFAIL; + crQUEUE_SEND( xHandle, xHookRxQueues[ uxIndex ], &( uxReceivedValue[ uxIndex ] ), hookNO_BLOCK_TIME, &xResult ); + if( xResult != pdPASS ) + { + /* There is no reason why we should not have been able to post to + the queue. */ + xCoRoutineErrorDetected = pdTRUE; + } + } + + /* Each co-routine MUST end with a call to crEND(). */ + crEND(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xAreHookCoRoutinesStillRunning( void ) +{ + if( xCoRoutineErrorDetected ) + { + return pdFALSE; + } + else + { + return pdTRUE; + } +} + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/death.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/death.c new file mode 100644 index 0000000..37164c1 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/death.c @@ -0,0 +1,257 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Create a single persistent task which periodically dynamically creates another + * two tasks. The original task is called the creator task, the two tasks it + * creates are called suicidal tasks. + * + * One of the created suicidal tasks kill one other suicidal task before killing + * itself - leaving just the original task remaining. + * + * The creator task must be spawned after all of the other demo application tasks + * as it keeps a check on the number of tasks under the scheduler control. The + * number of tasks it expects to see running should never be greater than the + * number of tasks that were in existence when the creator task was spawned, plus + * one set of four suicidal tasks. If this number is exceeded an error is flagged. + * + * \page DeathC death.c + * \ingroup DemoFiles + *
+ */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "death.h" + +#define deathSTACK_SIZE ( configMINIMAL_STACK_SIZE + 60 ) + +/* The task originally created which is responsible for periodically dynamically +creating another four tasks. */ +static portTASK_FUNCTION_PROTO( vCreateTasks, pvParameters ); + +/* The task function of the dynamically created tasks. */ +static portTASK_FUNCTION_PROTO( vSuicidalTask, pvParameters ); + +/* A variable which is incremented every time the dynamic tasks are created. This +is used to check that the task is still running. */ +static volatile uint16_t usCreationCount = 0; + +/* Used to store the number of tasks that were originally running so the creator +task can tell if any of the suicidal tasks have failed to die. +*/ +static volatile UBaseType_t uxTasksRunningAtStart = 0; + +/* When a task deletes itself, it stack and TCB are cleaned up by the Idle task. +Under heavy load the idle task might not get much processing time, so it would +be legitimate for several tasks to remain undeleted for a short period. There +may also be a few other unexpected tasks if, for example, the tasks that test +static allocation are also being used. */ +static const UBaseType_t uxMaxNumberOfExtraTasksRunning = 3; + +/* Used to store a handle to the task that should be killed by a suicidal task, +before it kills itself. */ +TaskHandle_t xCreatedTask; + +/*-----------------------------------------------------------*/ + +void vCreateSuicidalTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( vCreateTasks, "CREATOR", deathSTACK_SIZE, ( void * ) NULL, uxPriority, NULL ); + + /* Record the number of tasks that are running now so we know if any of the + suicidal tasks have failed to be killed. */ + uxTasksRunningAtStart = ( UBaseType_t ) uxTaskGetNumberOfTasks(); + + /* FreeRTOS.org versions before V3.0 started the idle-task as the very + first task. The idle task was then already included in uxTasksRunningAtStart. + From FreeRTOS V3.0 on, the idle task is started when the scheduler is + started. Therefore the idle task is not yet accounted for. We correct + this by increasing uxTasksRunningAtStart by 1. */ + uxTasksRunningAtStart++; + + /* From FreeRTOS version 7.0.0 can optionally create a timer service task. + If this is done, then uxTasksRunningAtStart needs incrementing again as that + too is created when the scheduler is started. */ + #if configUSE_TIMERS == 1 + { + uxTasksRunningAtStart++; + } + #endif +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vSuicidalTask, pvParameters ) +{ +volatile long l1, l2; +TaskHandle_t xTaskToKill; +const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 200 ); + + if( pvParameters != NULL ) + { + /* This task is periodically created four times. Two created tasks are + passed a handle to the other task so it can kill it before killing itself. + The other task is passed in null. */ + xTaskToKill = *( TaskHandle_t* )pvParameters; + } + else + { + xTaskToKill = NULL; + } + + for( ;; ) + { + /* Do something random just to use some stack and registers. */ + l1 = 2; + l2 = 89; + l2 *= l1; + vTaskDelay( xDelay ); + + if( xTaskToKill != NULL ) + { + /* Make sure the other task has a go before we delete it. */ + vTaskDelay( ( TickType_t ) 0 ); + + /* Kill the other task that was created by vCreateTasks(). */ + vTaskDelete( xTaskToKill ); + + /* Kill ourselves. */ + vTaskDelete( NULL ); + } + } +}/*lint !e818 !e550 Function prototype must be as per standard for task functions. */ +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCreateTasks, pvParameters ) +{ +const TickType_t xDelay = pdMS_TO_TICKS( ( TickType_t ) 1000 ); +UBaseType_t uxPriority; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + uxPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Just loop round, delaying then creating the four suicidal tasks. */ + vTaskDelay( xDelay ); + + xCreatedTask = NULL; + + xTaskCreate( vSuicidalTask, "SUICID1", configMINIMAL_STACK_SIZE, NULL, uxPriority, &xCreatedTask ); + xTaskCreate( vSuicidalTask, "SUICID2", configMINIMAL_STACK_SIZE, &xCreatedTask, uxPriority, NULL ); + + ++usCreationCount; + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that the creator task is still running and that there +are not any more than four extra tasks. */ +BaseType_t xIsCreateTaskStillRunning( void ) +{ +static uint16_t usLastCreationCount = 0xfff; +BaseType_t xReturn = pdTRUE; +static UBaseType_t uxTasksRunningNow; + + if( usLastCreationCount == usCreationCount ) + { + xReturn = pdFALSE; + } + else + { + usLastCreationCount = usCreationCount; + } + + uxTasksRunningNow = ( UBaseType_t ) uxTaskGetNumberOfTasks(); + + if( uxTasksRunningNow < uxTasksRunningAtStart ) + { + xReturn = pdFALSE; + } + else if( ( uxTasksRunningNow - uxTasksRunningAtStart ) > uxMaxNumberOfExtraTasksRunning ) + { + xReturn = pdFALSE; + } + else + { + /* Everything is okay. */ + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/dynamic.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/dynamic.c new file mode 100644 index 0000000..30d485b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/dynamic.c @@ -0,0 +1,518 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * The first test creates three tasks - two counter tasks (one continuous count + * and one limited count) and one controller. A "count" variable is shared + * between all three tasks. The two counter tasks should never be in a "ready" + * state at the same time. The controller task runs at the same priority as + * the continuous count task, and at a lower priority than the limited count + * task. + * + * One counter task loops indefinitely, incrementing the shared count variable + * on each iteration. To ensure it has exclusive access to the variable it + * raises its priority above that of the controller task before each + * increment, lowering it again to its original priority before starting the + * next iteration. + * + * The other counter task increments the shared count variable on each + * iteration of its loop until the count has reached a limit of 0xff - at + * which point it suspends itself. It will not start a new loop until the + * controller task has made it "ready" again by calling vTaskResume(). + * This second counter task operates at a higher priority than controller + * task so does not need to worry about mutual exclusion of the counter + * variable. + * + * The controller task is in two sections. The first section controls and + * monitors the continuous count task. When this section is operational the + * limited count task is suspended. Likewise, the second section controls + * and monitors the limited count task. When this section is operational the + * continuous count task is suspended. + * + * In the first section the controller task first takes a copy of the shared + * count variable. To ensure mutual exclusion on the count variable it + * suspends the continuous count task, resuming it again when the copy has been + * taken. The controller task then sleeps for a fixed period - during which + * the continuous count task will execute and increment the shared variable. + * When the controller task wakes it checks that the continuous count task + * has executed by comparing the copy of the shared variable with its current + * value. This time, to ensure mutual exclusion, the scheduler itself is + * suspended with a call to vTaskSuspendAll (). This is for demonstration + * purposes only and is not a recommended technique due to its inefficiency. + * + * After a fixed number of iterations the controller task suspends the + * continuous count task, and moves on to its second section. + * + * At the start of the second section the shared variable is cleared to zero. + * The limited count task is then woken from its suspension by a call to + * vTaskResume (). As this counter task operates at a higher priority than + * the controller task the controller task should not run again until the + * shared variable has been counted up to the limited value causing the counter + * task to suspend itself. The next line after vTaskResume () is therefore + * a check on the shared variable to ensure everything is as expected. + * + * + * The second test consists of a couple of very simple tasks that post onto a + * queue while the scheduler is suspended. This test was added to test parts + * of the scheduler not exercised by the first test. + * + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "dynamic.h" + +/* Function that implements the "limited count" task as described above. */ +static portTASK_FUNCTION_PROTO( vLimitedIncrementTask, pvParameters ); + +/* Function that implements the "continuous count" task as described above. */ +static portTASK_FUNCTION_PROTO( vContinuousIncrementTask, pvParameters ); + +/* Function that implements the controller task as described above. */ +static portTASK_FUNCTION_PROTO( vCounterControlTask, pvParameters ); + +static portTASK_FUNCTION_PROTO( vQueueReceiveWhenSuspendedTask, pvParameters ); +static portTASK_FUNCTION_PROTO( vQueueSendWhenSuspendedTask, pvParameters ); + +/* Demo task specific constants. */ +#define priSTACK_SIZE ( configMINIMAL_STACK_SIZE ) +#define priSLEEP_TIME pdMS_TO_TICKS( 128 ) +#define priLOOPS ( 5 ) +#define priMAX_COUNT ( ( uint32_t ) 0xff ) +#define priNO_BLOCK ( ( TickType_t ) 0 ) +#define priSUSPENDED_QUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* Handles to the two counter tasks. These could be passed in as parameters +to the controller task to prevent them having to be file scope. */ +static TaskHandle_t xContinuousIncrementHandle, xLimitedIncrementHandle; + +/* The shared counter variable. This is passed in as a parameter to the two +counter variables for demonstration purposes. */ +static volatile uint32_t ulCounter; + +/* Variables used to check that the tasks are still operating without error. +Each complete iteration of the controller task increments this variable +provided no errors have been found. The variable maintaining the same value +is therefore indication of an error. */ +static volatile uint16_t usCheckVariable = ( uint16_t ) 0; +static volatile BaseType_t xSuspendedQueueSendError = pdFALSE; +static volatile BaseType_t xSuspendedQueueReceiveError = pdFALSE; + +/* Queue used by the second test. */ +QueueHandle_t xSuspendedTestQueue; + +/* The value the queue receive task expects to receive next. This is file +scope so xAreDynamicPriorityTasksStillRunning() can ensure it is still +incrementing. */ +static uint32_t ulExpectedValue = ( uint32_t ) 0; + +/*-----------------------------------------------------------*/ +/* + * Start the three tasks as described at the top of the file. + * Note that the limited count task is given a higher priority. + */ +void vStartDynamicPriorityTasks( void ) +{ + xSuspendedTestQueue = xQueueCreate( priSUSPENDED_QUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xSuspendedTestQueue != NULL ) + { + /* vQueueAddToRegistry() adds the queue to the queue registry, if one is + in use. The queue registry is provided as a means for kernel aware + debuggers to locate queues and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( xSuspendedTestQueue, "Suspended_Test_Queue" ); + + xTaskCreate( vContinuousIncrementTask, "CNT_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY, &xContinuousIncrementHandle ); + xTaskCreate( vLimitedIncrementTask, "LIM_INC", priSTACK_SIZE, ( void * ) &ulCounter, tskIDLE_PRIORITY + 1, &xLimitedIncrementHandle ); + xTaskCreate( vCounterControlTask, "C_CTRL", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueSendWhenSuspendedTask, "SUSP_TX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vQueueReceiveWhenSuspendedTask, "SUSP_RX", priSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +/* + * Just loops around incrementing the shared variable until the limit has been + * reached. Once the limit has been reached it suspends itself. + */ +static portTASK_FUNCTION( vLimitedIncrementTask, pvParameters ) +{ +uint32_t *pulCounter; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( uint32_t * ) pvParameters; + + /* This will run before the control task, so the first thing it does is + suspend - the control task will resume it when ready. */ + vTaskSuspend( NULL ); + + for( ;; ) + { + /* Just count up to a value then suspend. */ + ( *pulCounter )++; + + if( *pulCounter >= priMAX_COUNT ) + { + vTaskSuspend( NULL ); + } + } +} +/*-----------------------------------------------------------*/ + +/* + * Just keep counting the shared variable up. The control task will suspend + * this task when it wants. + */ +static portTASK_FUNCTION( vContinuousIncrementTask, pvParameters ) +{ +volatile uint32_t *pulCounter; +UBaseType_t uxOurPriority; + + /* Take a pointer to the shared variable from the parameters passed into + the task. */ + pulCounter = ( uint32_t * ) pvParameters; + + /* Query our priority so we can raise it when exclusive access to the + shared variable is required. */ + uxOurPriority = uxTaskPriorityGet( NULL ); + + for( ;; ) + { + /* Raise the priority above the controller task to ensure a context + switch does not occur while the variable is being accessed. */ + vTaskPrioritySet( NULL, uxOurPriority + 1 ); + { + configASSERT( ( uxTaskPriorityGet( NULL ) == ( uxOurPriority + 1 ) ) ); + ( *pulCounter )++; + } + vTaskPrioritySet( NULL, uxOurPriority ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + configASSERT( ( uxTaskPriorityGet( NULL ) == uxOurPriority ) ); + } +} +/*-----------------------------------------------------------*/ + +/* + * Controller task as described above. + */ +static portTASK_FUNCTION( vCounterControlTask, pvParameters ) +{ +uint32_t ulLastCounter; +short sLoops; +short sError = pdFALSE; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Start with the counter at zero. */ + ulCounter = ( uint32_t ) 0; + + /* First section : */ + + /* Check the continuous count task is running. */ + for( sLoops = 0; sLoops < priLOOPS; sLoops++ ) + { + /* Suspend the continuous count task so we can take a mirror of the + shared variable without risk of corruption. This is not really + needed as the other task raises its priority above this task's + priority. */ + vTaskSuspend( xContinuousIncrementHandle ); + { + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + ulLastCounter = ulCounter; + } + vTaskResume( xContinuousIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xContinuousIncrementHandle ) == eReady ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Now delay to ensure the other task has processor time. */ + vTaskDelay( priSLEEP_TIME ); + + /* Check the shared variable again. This time to ensure mutual + exclusion the whole scheduler will be locked. This is just for + demo purposes! */ + vTaskSuspendAll(); + { + if( ulLastCounter == ulCounter ) + { + /* The shared variable has not changed. There is a problem + with the continuous count task so flag an error. */ + sError = pdTRUE; + } + } + xTaskResumeAll(); + } + + /* Second section: */ + + /* Suspend the continuous counter task so it stops accessing the shared + variable. */ + vTaskSuspend( xContinuousIncrementHandle ); + + /* Reset the variable. */ + ulCounter = ( uint32_t ) 0; + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Resume the limited count task which has a higher priority than us. + We should therefore not return from this call until the limited count + task has suspended itself with a known value in the counter variable. */ + vTaskResume( xLimitedIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + /* This task should not run again until xLimitedIncrementHandle has + suspended itself. */ + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xLimitedIncrementHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Does the counter variable have the expected value? */ + if( ulCounter != priMAX_COUNT ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If no errors have occurred then increment the check variable. */ + portENTER_CRITICAL(); + usCheckVariable++; + portEXIT_CRITICAL(); + } + + /* Resume the continuous count task and do it all again. */ + vTaskResume( xContinuousIncrementHandle ); + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueSendWhenSuspendedTask, pvParameters ) +{ +static uint32_t ulValueToSend = ( uint32_t ) 0; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + vTaskSuspendAll(); + { + /* We must not block while the scheduler is suspended! */ + if( xQueueSend( xSuspendedTestQueue, ( void * ) &ulValueToSend, priNO_BLOCK ) != pdTRUE ) + { + xSuspendedQueueSendError = pdTRUE; + } + } + xTaskResumeAll(); + + vTaskDelay( priSLEEP_TIME ); + + ++ulValueToSend; + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vQueueReceiveWhenSuspendedTask, pvParameters ) +{ +uint32_t ulReceivedValue; +BaseType_t xGotValue; + + /* Just to stop warning messages. */ + ( void ) pvParameters; + + for( ;; ) + { + do + { + /* Suspending the scheduler here is fairly pointless and + undesirable for a normal application. It is done here purely + to test the scheduler. The inner xTaskResumeAll() should + never return pdTRUE as the scheduler is still locked by the + outer call. */ + vTaskSuspendAll(); + { + vTaskSuspendAll(); + { + xGotValue = xQueueReceive( xSuspendedTestQueue, ( void * ) &ulReceivedValue, priNO_BLOCK ); + } + if( xTaskResumeAll() != pdFALSE ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + } + xTaskResumeAll(); + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + } while( xGotValue == pdFALSE ); + + if( ulReceivedValue != ulExpectedValue ) + { + xSuspendedQueueReceiveError = pdTRUE; + } + + if( xSuspendedQueueReceiveError != pdTRUE ) + { + /* Only increment the variable if an error has not occurred. This + allows xAreDynamicPriorityTasksStillRunning() to check for stalled + tasks as well as explicit errors. */ + ++ulExpectedValue; + } + } +} +/*-----------------------------------------------------------*/ + +/* Called to check that all the created tasks are still running without error. */ +BaseType_t xAreDynamicPriorityTasksStillRunning( void ) +{ +/* Keep a history of the check variables so we know if it has been incremented +since the last call. */ +static uint16_t usLastTaskCheck = ( uint16_t ) 0; +static uint32_t ulLastExpectedValue = ( uint32_t ) 0U; +BaseType_t xReturn = pdTRUE; + + /* Check the tasks are still running by ensuring the check variable + is still incrementing. */ + + if( usCheckVariable == usLastTaskCheck ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( ulExpectedValue == ulLastExpectedValue ) + { + /* The value being received by the queue receive task has not + incremented so an error exists. */ + xReturn = pdFALSE; + } + + if( xSuspendedQueueSendError == pdTRUE ) + { + xReturn = pdFALSE; + } + + if( xSuspendedQueueReceiveError == pdTRUE ) + { + xReturn = pdFALSE; + } + + usLastTaskCheck = usCheckVariable; + ulLastExpectedValue = ulExpectedValue; + + return xReturn; +} diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash.c new file mode 100644 index 0000000..6bab476 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash.c @@ -0,0 +1,161 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * This version of flash .c is for use on systems that have limited stack space + * and no display facilities. The complete version can be found in the + * Demo/Common/Full directory. + * + * Three tasks are created, each of which flash an LED at a different rate. The first + * LED flashes every 200ms, the second every 400ms, the third every 600ms. + * + * The LED flash tasks provide instant visual feedback. They show that the scheduler + * is still operational. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash.h" + +#define ledSTACK_SIZE configMINIMAL_STACK_SIZE +#define ledNUMBER_OF_LEDS ( 3 ) +#define ledFLASH_RATE_BASE ( ( TickType_t ) 333 ) + +/* Variable used by the created tasks to calculate the LED number to use, and +the rate at which they should flash the LED. */ +static volatile UBaseType_t uxFlashTaskNumber = 0; + +/* The task that is created three times. */ +static portTASK_FUNCTION_PROTO( vLEDFlashTask, pvParameters ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTasks( UBaseType_t uxPriority ) +{ +BaseType_t xLEDTask; + + /* Create the three tasks. */ + for( xLEDTask = 0; xLEDTask < ledNUMBER_OF_LEDS; ++xLEDTask ) + { + /* Spawn the task. */ + xTaskCreate( vLEDFlashTask, "LEDx", ledSTACK_SIZE, NULL, uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vLEDFlashTask, pvParameters ) +{ +TickType_t xFlashRate, xLastFlashTime; +UBaseType_t uxLED; + + /* The parameters are not used. */ + ( void ) pvParameters; + + /* Calculate the LED and flash rate. */ + portENTER_CRITICAL(); + { + /* See which of the eight LED's we should use. */ + uxLED = uxFlashTaskNumber; + + /* Update so the next task uses the next LED. */ + uxFlashTaskNumber++; + } + portEXIT_CRITICAL(); + + xFlashRate = ledFLASH_RATE_BASE + ( ledFLASH_RATE_BASE * ( TickType_t ) uxLED ); + xFlashRate /= portTICK_PERIOD_MS; + + /* We will turn the LED on and off again in the delay period, so each + delay is only half the total period. */ + xFlashRate /= ( TickType_t ) 2; + + /* We need to initialise xLastFlashTime prior to the first call to + vTaskDelayUntil(). */ + xLastFlashTime = xTaskGetTickCount(); + + for(;;) + { + /* Delay for half the flash period then turn the LED on. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + + /* Delay for half the flash period then turn the LED off. */ + vTaskDelayUntil( &xLastFlashTime, xFlashRate ); + vParTestToggleLED( uxLED ); + } +} /*lint !e715 !e818 !e830 Function definition must be standard for task creation. */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash_timer.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash_timer.c new file mode 100644 index 0000000..1de24ec --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flash_timer.c @@ -0,0 +1,140 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/** + * Repeatedly toggles one or more LEDs using software timers - one timer per + * LED. + */ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "timers.h" + +/* Demo program include files. */ +#include "partest.h" +#include "flash_timer.h" + +/* The toggle rates are all a multple of ledFLASH_RATE_BASE. */ +#define ledFLASH_RATE_BASE ( ( ( TickType_t ) 333 ) / portTICK_PERIOD_MS ) + +/* A block time of zero simple means "don't block". */ +#define ledDONT_BLOCK ( ( TickType_t ) 0 ) + +/*-----------------------------------------------------------*/ + +/* + * The callback function used by each LED flashing timer. All the timers use + * this function, and the timer ID is used within the function to determine + * which timer has actually expired. + */ +static void prvLEDTimerCallback( TimerHandle_t xTimer ); + +/*-----------------------------------------------------------*/ + +void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs ) +{ +UBaseType_t uxLEDTimer; +TimerHandle_t xTimer; + + /* Create and start the requested number of timers. */ + for( uxLEDTimer = 0; uxLEDTimer < uxNumberOfLEDs; ++uxLEDTimer ) + { + /* Create the timer. */ + xTimer = xTimerCreate( "Flasher", /* A text name, purely to help debugging. */ + ledFLASH_RATE_BASE * ( uxLEDTimer + 1 ),/* The timer period, which is a multiple of ledFLASH_RATE_BASE. */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) uxLEDTimer, /* The ID is used to identify the timer within the timer callback function, as each timer uses the same callback. */ + prvLEDTimerCallback /* Each timer uses the same callback. */ + ); + + /* If the timer was created successfully, attempt to start it. If the + scheduler has not yet been started then the timer command queue must + be long enough to hold each command sent to it until such time that the + scheduler is started. The timer command queue length is set by + configTIMER_QUEUE_LENGTH in FreeRTOSConfig.h. */ + if( xTimer != NULL ) + { + xTimerStart( xTimer, ledDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + +static void prvLEDTimerCallback( TimerHandle_t xTimer ) +{ +BaseType_t xTimerID; + + /* The timer ID is used to identify the timer that has actually expired as + each timer uses the same callback. The ID is then also used as the number + of the LED that is to be toggled. */ + xTimerID = ( BaseType_t ) pvTimerGetTimerID( xTimer ); + vParTestToggleLED( xTimerID ); +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flop.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flop.c new file mode 100644 index 0000000..587b87a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/flop.c @@ -0,0 +1,391 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates eight tasks, each of which loops continuously performing a floating + * point calculation. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle + * priority means that these tasks will get pre-empted any time another task is + * ready to run or a time slice occurs. More often than not the pre-emption + * will occur mid calculation, creating a good test of the schedulers context + * switch mechanism - a calculation producing an unexpected result could be a + * symptom of a corruption in the context of a task. + */ + +/* Standard includes. */ +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "flop.h" + +#ifndef mathSTACK_SIZE + #define mathSTACK_SIZE configMINIMAL_STACK_SIZE +#endif + +#define mathNUMBER_OF_TASKS ( 4 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will stop setting its check variable. */ +static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile uint16_t *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + dAnswer = ( d1 + d2 ) * d3; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + d1 = 123.4567; + d2 = 2345.6789; + d3 = -918.222; + + d4 = ( d1 + d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +{ +volatile portDOUBLE d1, d2, d3, d4; +volatile uint16_t *pusTaskCheckVariable; +volatile portDOUBLE dAnswer; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + dAnswer = ( d1 / d2 ) * d3; + + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + d1 = -389.38; + d2 = 32498.2; + d3 = -2.0001; + + d4 = ( d1 / d2 ) * d3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( d4 - dAnswer ) > 0.001 ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition + 5.5; + dTotal1 += ( portDOUBLE ) xPosition + 5.5; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +{ +volatile portDOUBLE *pdArray, dTotal1, dTotal2, dDifference; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* Some ports require that tasks that use a hardware floating point unit + tell the kernel that they require a floating point context before any + floating point instructions are executed. */ + portTASK_USES_FLOATING_POINT(); + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pdArray = ( portDOUBLE * ) pvPortMalloc( xArraySize * sizeof( portDOUBLE ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + dTotal1 = 0.0; + dTotal2 = 0.0; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pdArray[ xPosition ] = ( portDOUBLE ) xPosition * 12.123; + dTotal1 += ( portDOUBLE ) xPosition * 12.123; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + dTotal2 += pdArray[ xPosition ]; + } + + dDifference = dTotal1 - dTotal2; + if( fabs( dDifference ) > 0.001 ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct then set set the check + variable. The check variable will get set to pdFALSE each time + xAreMathsTaskStillRunning() is executed. */ + ( *pusTaskCheckVariable ) = pdTRUE; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreMathsTaskStillRunning( void ) +{ +BaseType_t xReturn = pdPASS, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + have been set to pdPASS. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] != pdTRUE ) + { + /* The check has not been set so the associated task has either + stalled or detected an error. */ + xReturn = pdFAIL; + } + else + { + /* Reset the variable so it can be checked again the next time this + function is executed. */ + usTaskCheck[ xTask ] = pdFALSE; + } + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/integer.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/integer.c new file mode 100644 index 0000000..1077619 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/integer.c @@ -0,0 +1,205 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates one or more tasks that repeatedly perform a set of integer + * calculations. The result of each run-time calculation is compared to the + * known expected result - with a mismatch being indicative of an error in the + * context switch mechanism. + */ + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "integer.h" + +/* The constants used in the calculation. */ +#define intgCONST1 ( ( long ) 123 ) +#define intgCONST2 ( ( long ) 234567 ) +#define intgCONST3 ( ( long ) -3 ) +#define intgCONST4 ( ( long ) 7 ) +#define intgEXPECTED_ANSWER ( ( ( intgCONST1 + intgCONST2 ) * intgCONST3 ) / intgCONST4 ) + +#define intgSTACK_SIZE configMINIMAL_STACK_SIZE + +/* As this is the minimal version, we will only create one task. */ +#define intgNUMBER_OF_TASKS ( 1 ) + +/* The task function. Repeatedly performs a 32 bit calculation, checking the +result against the expected result. If the result is incorrect then the +context switch must have caused some corruption. */ +static portTASK_FUNCTION_PROTO( vCompeteingIntMathTask, pvParameters ); + +/* Variables that are set to true within the calculation task to indicate +that the task is still executing. The check task sets the variable back to +false, flagging an error if the variable is still false the next time it +is called. */ +static volatile BaseType_t xTaskCheck[ intgNUMBER_OF_TASKS ] = { ( BaseType_t ) pdFALSE }; + +/*-----------------------------------------------------------*/ + +void vStartIntegerMathTasks( UBaseType_t uxPriority ) +{ +short sTask; + + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + xTaskCreate( vCompeteingIntMathTask, "IntMath", intgSTACK_SIZE, ( void * ) &( xTaskCheck[ sTask ] ), uxPriority, ( TaskHandle_t * ) NULL ); + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompeteingIntMathTask, pvParameters ) +{ +/* These variables are all effectively set to constants so they are volatile to +ensure the compiler does not just get rid of them. */ +volatile long lValue; +short sError = pdFALSE; +volatile BaseType_t *pxTaskHasExecuted; + + /* Set a pointer to the variable we are going to set to true each + iteration. This is also a good test of the parameter passing mechanism + within each port. */ + pxTaskHasExecuted = ( volatile BaseType_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + /* Perform the calculation. This will store partial value in + registers, resulting in a good test of the context switch mechanism. */ + lValue = intgCONST1; + lValue += intgCONST2; + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + + /* Finish off the calculation. */ + lValue *= intgCONST3; + lValue /= intgCONST4; + + /* If the calculation is found to be incorrect we stop setting the + TaskHasExecuted variable so the check task can see an error has + occurred. */ + if( lValue != intgEXPECTED_ANSWER ) /*lint !e774 volatile used to prevent this being optimised out. */ + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* We have not encountered any errors, so set the flag that show + we are still executing. This will be periodically cleared by + the check task. */ + portENTER_CRITICAL(); + *pxTaskHasExecuted = pdTRUE; + portEXIT_CRITICAL(); + } + + /* Yield in case cooperative scheduling is being used. */ + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreIntegerMathsTaskStillRunning( void ) +{ +BaseType_t xReturn = pdTRUE; +short sTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still being set to true. */ + for( sTask = 0; sTask < intgNUMBER_OF_TASKS; sTask++ ) + { + if( xTaskCheck[ sTask ] == pdFALSE ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + /* Reset the check variable so we can tell if it has been set by + the next time around. */ + xTaskCheck[ sTask ] = pdFALSE; + } + + return xReturn; +} + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/readme.txt b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/readme.txt new file mode 100644 index 0000000..48668dc --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/readme.txt @@ -0,0 +1,2 @@ +This directory contains the implementation of the "common demo tasks". These +are test tasks and demo tasks that are used by nearly all the demo applications. \ No newline at end of file diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/recmutex.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/recmutex.c new file mode 100644 index 0000000..84e1e84 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/recmutex.c @@ -0,0 +1,454 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + The tasks defined on this page demonstrate the use of recursive mutexes. + + For recursive mutex functionality the created mutex should be created using + xSemaphoreCreateRecursiveMutex(), then be manipulated + using the xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() API + functions. + + This demo creates three tasks all of which access the same recursive mutex: + + prvRecursiveMutexControllingTask() has the highest priority so executes + first and grabs the mutex. It then performs some recursive accesses - + between each of which it sleeps for a short period to let the lower + priority tasks execute. When it has completed its demo functionality + it gives the mutex back before suspending itself. + + prvRecursiveMutexBlockingTask() attempts to access the mutex by performing + a blocking 'take'. The blocking task has a lower priority than the + controlling task so by the time it executes the mutex has already been + taken by the controlling task, causing the blocking task to block. It + does not unblock until the controlling task has given the mutex back, + and it does not actually run until the controlling task has suspended + itself (due to the relative priorities). When it eventually does obtain + the mutex all it does is give the mutex back prior to also suspending + itself. At this point both the controlling task and the blocking task are + suspended. + + prvRecursiveMutexPollingTask() runs at the idle priority. It spins round + a tight loop attempting to obtain the mutex with a non-blocking call. As + the lowest priority task it will not successfully obtain the mutex until + both the controlling and blocking tasks are suspended. Once it eventually + does obtain the mutex it first unsuspends both the controlling task and + blocking task prior to giving the mutex back - resulting in the polling + task temporarily inheriting the controlling tasks priority. +*/ + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "recmutex.h" + +/* Priorities assigned to the three tasks. recmuCONTROLLING_TASK_PRIORITY can +be overridden by a definition in FreeRTOSConfig.h. */ +#ifndef recmuCONTROLLING_TASK_PRIORITY + #define recmuCONTROLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#endif +#define recmuBLOCKING_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define recmuPOLLING_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/* The recursive call depth. */ +#define recmuMAX_COUNT ( 10 ) + +/* Misc. */ +#define recmuSHORT_DELAY ( pdMS_TO_TICKS( 20 ) ) +#define recmuNO_DELAY ( ( TickType_t ) 0 ) +#define recmu15ms_DELAY ( pdMS_TO_TICKS( 15 ) ) + +/* The three tasks as described at the top of this file. */ +static void prvRecursiveMutexControllingTask( void *pvParameters ); +static void prvRecursiveMutexBlockingTask( void *pvParameters ); +static void prvRecursiveMutexPollingTask( void *pvParameters ); + +/* The mutex used by the demo. */ +static SemaphoreHandle_t xMutex; + +/* Variables used to detect and latch errors. */ +static volatile BaseType_t xErrorOccurred = pdFALSE, xControllingIsSuspended = pdFALSE, xBlockingIsSuspended = pdFALSE; +static volatile UBaseType_t uxControllingCycles = 0, uxBlockingCycles = 0, uxPollingCycles = 0; + +/* Handles of the two higher priority tasks, required so they can be resumed +(unsuspended). */ +static TaskHandle_t xControllingTaskHandle, xBlockingTaskHandle; + +/*-----------------------------------------------------------*/ + +void vStartRecursiveMutexTasks( void ) +{ + /* Just creates the mutex and the three tasks. */ + + xMutex = xSemaphoreCreateRecursiveMutex(); + + if( xMutex != NULL ) + { + /* vQueueAddToRegistry() adds the mutex to the registry, if one is + in use. The registry is provided as a means for kernel aware + debuggers to locate mutex and has no purpose if a kernel aware debugger + is not being used. The call to vQueueAddToRegistry() will be removed + by the pre-processor if configQUEUE_REGISTRY_SIZE is not defined or is + defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) xMutex, "Recursive_Mutex" ); + + xTaskCreate( prvRecursiveMutexControllingTask, "Rec1", configMINIMAL_STACK_SIZE, NULL, recmuCONTROLLING_TASK_PRIORITY, &xControllingTaskHandle ); + xTaskCreate( prvRecursiveMutexBlockingTask, "Rec2", configMINIMAL_STACK_SIZE, NULL, recmuBLOCKING_TASK_PRIORITY, &xBlockingTaskHandle ); + xTaskCreate( prvRecursiveMutexPollingTask, "Rec3", configMINIMAL_STACK_SIZE, NULL, recmuPOLLING_TASK_PRIORITY, NULL ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexControllingTask( void *pvParameters ) +{ +UBaseType_t ux; + + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Should not be able to 'give' the mutex, as we have not yet 'taken' + it. The first time through, the mutex will not have been used yet, + subsequent times through, at this point the mutex will be held by the + polling task. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* We should now be able to take the mutex as many times as + we like. + + The first time through the mutex will be immediately available, on + subsequent times through the mutex will be held by the polling task + at this point and this Take will cause the polling task to inherit + the priority of this task. In this case the block time must be + long enough to ensure the polling task will execute again before the + block time expires. If the block time does expire then the error + flag will be set here. */ + if( xSemaphoreTakeRecursive( xMutex, recmu15ms_DELAY ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute to ensure they either block + (where a block time is specified) or return an error (where no + block time is specified) as the mutex is held by this task. */ + vTaskDelay( recmuSHORT_DELAY ); + } + + /* For each time we took the mutex, give it back. */ + for( ux = 0; ux < recmuMAX_COUNT; ux++ ) + { + /* Ensure the other task attempting to access the mutex (and the + other demo tasks) are able to execute. */ + vTaskDelay( recmuSHORT_DELAY ); + + /* We should now be able to give the mutex as many times as we + took it. When the mutex is available again the Blocking task + should be unblocked but not run because it has a lower priority + than this task. The polling task should also not run at this point + as it too has a lower priority than this task. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + } + + /* Having given it back the same number of times as it was taken, we + should no longer be the mutex owner, so the next give should fail. */ + if( xSemaphoreGiveRecursive( xMutex ) == pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxControllingCycles++; + + /* Suspend ourselves so the blocking task can execute. */ + xControllingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xControllingIsSuspended = pdFALSE; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexBlockingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* This task will run while the controlling task is blocked, and the + controlling task will block only once it has the mutex - therefore + this call should block until the controlling task has given up the + mutex, and not actually execute past this call until the controlling + task is suspended. portMAX_DELAY - 1 is used instead of portMAX_DELAY + to ensure the task's state is reported as Blocked and not Suspended in + a later call to configASSERT() (within the polling task). */ + if( xSemaphoreTakeRecursive( xMutex, ( portMAX_DELAY - 1 ) ) == pdPASS ) + { + if( xControllingIsSuspended != pdTRUE ) + { + /* Did not expect to execute until the controlling task was + suspended. */ + xErrorOccurred = pdTRUE; + } + else + { + /* Give the mutex back before suspending ourselves to allow + the polling task to obtain the mutex. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + xBlockingIsSuspended = pdTRUE; + vTaskSuspend( NULL ); + xBlockingIsSuspended = pdFALSE; + } + } + else + { + /* We should not leave the xSemaphoreTakeRecursive() function + until the mutex was obtained. */ + xErrorOccurred = pdTRUE; + } + + /* The controlling and blocking tasks should be in lock step. */ + if( uxControllingCycles != ( uxBlockingCycles + 1 ) ) + { + xErrorOccurred = pdTRUE; + } + + /* Keep count of the number of cycles this task has performed so a + stall can be detected. */ + uxBlockingCycles++; + } +} +/*-----------------------------------------------------------*/ + +static void prvRecursiveMutexPollingTask( void *pvParameters ) +{ + /* Just to remove compiler warning. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Keep attempting to obtain the mutex. We should only obtain it when + the blocking task has suspended itself, which in turn should only + happen when the controlling task is also suspended. */ + if( xSemaphoreTakeRecursive( xMutex, recmuNO_DELAY ) == pdPASS ) + { + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xControllingTaskHandle ) == eSuspended ); + configASSERT( eTaskGetState( xBlockingTaskHandle ) == eSuspended ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Is the blocking task suspended? */ + if( ( xBlockingIsSuspended != pdTRUE ) || ( xControllingIsSuspended != pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + else + { + /* Keep count of the number of cycles this task has performed + so a stall can be detected. */ + uxPollingCycles++; + + /* We can resume the other tasks here even though they have a + higher priority than the polling task. When they execute they + will attempt to obtain the mutex but fail because the polling + task is still the mutex holder. The polling task (this task) + will then inherit the higher priority. The Blocking task will + block indefinitely when it attempts to obtain the mutex, the + Controlling task will only block for a fixed period and an + error will be latched if the polling task has not returned the + mutex by the time this fixed period has expired. */ + vTaskResume( xBlockingTaskHandle ); + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + vTaskResume( xControllingTaskHandle ); + #if( configUSE_PREEMPTION == 0 ) + taskYIELD(); + #endif + + /* The other two tasks should now have executed and no longer + be suspended. */ + if( ( xBlockingIsSuspended == pdTRUE ) || ( xControllingIsSuspended == pdTRUE ) ) + { + xErrorOccurred = pdTRUE; + } + + #if( INCLUDE_uxTaskPriorityGet == 1 ) + { + /* Check priority inherited. */ + configASSERT( uxTaskPriorityGet( NULL ) == recmuCONTROLLING_TASK_PRIORITY ); + } + #endif /* INCLUDE_uxTaskPriorityGet */ + + #if( INCLUDE_eTaskGetState == 1 ) + { + configASSERT( eTaskGetState( xControllingTaskHandle ) == eBlocked ); + configASSERT( eTaskGetState( xBlockingTaskHandle ) == eBlocked ); + } + #endif /* INCLUDE_eTaskGetState */ + + /* Release the mutex, disinheriting the higher priority again. */ + if( xSemaphoreGiveRecursive( xMutex ) != pdPASS ) + { + xErrorOccurred = pdTRUE; + } + + #if( INCLUDE_uxTaskPriorityGet == 1 ) + { + /* Check priority disinherited. */ + configASSERT( uxTaskPriorityGet( NULL ) == recmuPOLLING_TASK_PRIORITY ); + } + #endif /* INCLUDE_uxTaskPriorityGet */ + } + } + + #if configUSE_PREEMPTION == 0 + { + taskYIELD(); + } + #endif + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreRecursiveMutexTasksStillRunning( void ) +{ +BaseType_t xReturn; +static UBaseType_t uxLastControllingCycles = 0, uxLastBlockingCycles = 0, uxLastPollingCycles = 0; + + /* Is the controlling task still cycling? */ + if( uxLastControllingCycles == uxControllingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastControllingCycles = uxControllingCycles; + } + + /* Is the blocking task still cycling? */ + if( uxLastBlockingCycles == uxBlockingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastBlockingCycles = uxBlockingCycles; + } + + /* Is the polling task still cycling? */ + if( uxLastPollingCycles == uxPollingCycles ) + { + xErrorOccurred = pdTRUE; + } + else + { + uxLastPollingCycles = uxPollingCycles; + } + + if( xErrorOccurred == pdTRUE ) + { + xReturn = pdFAIL; + } + else + { + xReturn = pdPASS; + } + + return xReturn; +} + + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/semtest.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/semtest.c new file mode 100644 index 0000000..e5fbdfe --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/semtest.c @@ -0,0 +1,311 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates two sets of two tasks. The tasks within a set share a variable, access + * to which is guarded by a semaphore. + * + * Each task starts by attempting to obtain the semaphore. On obtaining a + * semaphore a task checks to ensure that the guarded variable has an expected + * value. It then clears the variable to zero before counting it back up to the + * expected value in increments of 1. After each increment the variable is checked + * to ensure it contains the value to which it was just set. When the starting + * value is again reached the task releases the semaphore giving the other task in + * the set a chance to do exactly the same thing. The starting value is high + * enough to ensure that a tick is likely to occur during the incrementing loop. + * + * An error is flagged if at any time during the process a shared variable is + * found to have a value other than that expected. Such an occurrence would + * suggest an error in the mutual exclusion mechanism by which access to the + * variable is restricted. + * + * The first set of two tasks poll their semaphore. The second set use blocking + * calls. + * + */ + + +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Demo app include files. */ +#include "semtest.h" + +/* The value to which the shared variables are counted. */ +#define semtstBLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xfff ) +#define semtstNON_BLOCKING_EXPECTED_VALUE ( ( uint32_t ) 0xff ) + +#define semtstSTACK_SIZE configMINIMAL_STACK_SIZE + +#define semtstNUM_TASKS ( 4 ) + +#define semtstDELAY_FACTOR ( ( TickType_t ) 10 ) + +/* The task function as described at the top of the file. */ +static portTASK_FUNCTION_PROTO( prvSemaphoreTest, pvParameters ); + +/* Structure used to pass parameters to each task. */ +typedef struct SEMAPHORE_PARAMETERS +{ + SemaphoreHandle_t xSemaphore; + volatile uint32_t *pulSharedVariable; + TickType_t xBlockTime; +} xSemaphoreParameters; + +/* Variables used to check that all the tasks are still running without errors. */ +static volatile short sCheckVariables[ semtstNUM_TASKS ] = { 0 }; +static volatile short sNextCheckVariable = 0; + +/*-----------------------------------------------------------*/ + +void vStartSemaphoreTasks( UBaseType_t uxPriority ) +{ +xSemaphoreParameters *pxFirstSemaphoreParameters, *pxSecondSemaphoreParameters; +const TickType_t xBlockTime = ( TickType_t ) 100; + + /* Create the structure used to pass parameters to the first two tasks. */ + pxFirstSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + + if( pxFirstSemaphoreParameters != NULL ) + { + /* Create the semaphore used by the first two tasks. */ + pxFirstSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary(); + + if( pxFirstSemaphoreParameters->xSemaphore != NULL ) + { + xSemaphoreGive( pxFirstSemaphoreParameters->xSemaphore ); + + /* Create the variable which is to be shared by the first two tasks. */ + pxFirstSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) ); + + /* Initialise the share variable to the value the tasks expect. */ + *( pxFirstSemaphoreParameters->pulSharedVariable ) = semtstNON_BLOCKING_EXPECTED_VALUE; + + /* The first two tasks do not block on semaphore calls. */ + pxFirstSemaphoreParameters->xBlockTime = ( TickType_t ) 0; + + /* Spawn the first two tasks. As they poll they operate at the idle priority. */ + xTaskCreate( prvSemaphoreTest, "PolSEM1", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "PolSEM2", semtstSTACK_SIZE, ( void * ) pxFirstSemaphoreParameters, tskIDLE_PRIORITY, ( TaskHandle_t * ) NULL ); + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one + is in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware + debugger is not being used. The call to vQueueAddToRegistry() will + be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not + defined or is defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) pxFirstSemaphoreParameters->xSemaphore, "Counting_Sem_1" ); + } + } + + /* Do exactly the same to create the second set of tasks, only this time + provide a block time for the semaphore calls. */ + pxSecondSemaphoreParameters = ( xSemaphoreParameters * ) pvPortMalloc( sizeof( xSemaphoreParameters ) ); + if( pxSecondSemaphoreParameters != NULL ) + { + pxSecondSemaphoreParameters->xSemaphore = xSemaphoreCreateBinary(); + + if( pxSecondSemaphoreParameters->xSemaphore != NULL ) + { + xSemaphoreGive( pxSecondSemaphoreParameters->xSemaphore ); + + pxSecondSemaphoreParameters->pulSharedVariable = ( uint32_t * ) pvPortMalloc( sizeof( uint32_t ) ); + *( pxSecondSemaphoreParameters->pulSharedVariable ) = semtstBLOCKING_EXPECTED_VALUE; + pxSecondSemaphoreParameters->xBlockTime = xBlockTime / portTICK_PERIOD_MS; + + xTaskCreate( prvSemaphoreTest, "BlkSEM1", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + xTaskCreate( prvSemaphoreTest, "BlkSEM2", semtstSTACK_SIZE, ( void * ) pxSecondSemaphoreParameters, uxPriority, ( TaskHandle_t * ) NULL ); + + /* vQueueAddToRegistry() adds the semaphore to the registry, if one + is in use. The registry is provided as a means for kernel aware + debuggers to locate semaphores and has no purpose if a kernel aware + debugger is not being used. The call to vQueueAddToRegistry() will + be removed by the pre-processor if configQUEUE_REGISTRY_SIZE is not + defined or is defined to be less than 1. */ + vQueueAddToRegistry( ( QueueHandle_t ) pxSecondSemaphoreParameters->xSemaphore, "Counting_Sem_2" ); + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvSemaphoreTest, pvParameters ) +{ +xSemaphoreParameters *pxParameters; +volatile uint32_t *pulSharedVariable, ulExpectedValue; +uint32_t ulCounter; +short sError = pdFALSE, sCheckVariableToUse; + + /* See which check variable to use. sNextCheckVariable is not semaphore + protected! */ + portENTER_CRITICAL(); + sCheckVariableToUse = sNextCheckVariable; + sNextCheckVariable++; + portEXIT_CRITICAL(); + + /* A structure is passed in as the parameter. This contains the shared + variable being guarded. */ + pxParameters = ( xSemaphoreParameters * ) pvParameters; + pulSharedVariable = pxParameters->pulSharedVariable; + + /* If we are blocking we use a much higher count to ensure loads of context + switches occur during the count. */ + if( pxParameters->xBlockTime > ( TickType_t ) 0 ) + { + ulExpectedValue = semtstBLOCKING_EXPECTED_VALUE; + } + else + { + ulExpectedValue = semtstNON_BLOCKING_EXPECTED_VALUE; + } + + for( ;; ) + { + /* Try to obtain the semaphore. */ + if( xSemaphoreTake( pxParameters->xSemaphore, pxParameters->xBlockTime ) == pdPASS ) + { + /* We have the semaphore and so expect any other tasks using the + shared variable to have left it in the state we expect to find + it. */ + if( *pulSharedVariable != ulExpectedValue ) + { + sError = pdTRUE; + } + + /* Clear the variable, then count it back up to the expected value + before releasing the semaphore. Would expect a context switch or + two during this time. */ + for( ulCounter = ( uint32_t ) 0; ulCounter <= ulExpectedValue; ulCounter++ ) + { + *pulSharedVariable = ulCounter; + if( *pulSharedVariable != ulCounter ) + { + sError = pdTRUE; + } + } + + /* Release the semaphore, and if no errors have occurred increment the check + variable. */ + if( xSemaphoreGive( pxParameters->xSemaphore ) == pdFALSE ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + if( sCheckVariableToUse < semtstNUM_TASKS ) + { + ( sCheckVariables[ sCheckVariableToUse ] )++; + } + } + + /* If we have a block time then we are running at a priority higher + than the idle priority. This task takes a long time to complete + a cycle (deliberately so to test the guarding) so will be starving + out lower priority tasks. Block for some time to allow give lower + priority tasks some processor time. */ + vTaskDelay( pxParameters->xBlockTime * semtstDELAY_FACTOR ); + } + else + { + if( pxParameters->xBlockTime == ( TickType_t ) 0 ) + { + /* We have not got the semaphore yet, so no point using the + processor. We are not blocking when attempting to obtain the + semaphore. */ + taskYIELD(); + } + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreSemaphoreTasksStillRunning( void ) +{ +static short sLastCheckVariables[ semtstNUM_TASKS ] = { 0 }; +BaseType_t xTask, xReturn = pdTRUE; + + for( xTask = 0; xTask < semtstNUM_TASKS; xTask++ ) + { + if( sLastCheckVariables[ xTask ] == sCheckVariables[ xTask ] ) + { + xReturn = pdFALSE; + } + + sLastCheckVariables[ xTask ] = sCheckVariables[ xTask ]; + } + + return xReturn; +} + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/sp_flop.c b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/sp_flop.c new file mode 100644 index 0000000..8356b91 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/Minimal/sp_flop.c @@ -0,0 +1,369 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Creates eight tasks, each of which loops continuously performing a floating + * point calculation - using single precision variables. + * + * All the tasks run at the idle priority and never block or yield. This causes + * all eight tasks to time slice with the idle task. Running at the idle priority + * means that these tasks will get pre-empted any time another task is ready to run + * or a time slice occurs. More often than not the pre-emption will occur mid + * calculation, creating a good test of the schedulers context switch mechanism - a + * calculation producing an unexpected result could be a symptom of a corruption in + * the context of a task. + */ + +#include +#include + +/* Scheduler include files. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Demo program include files. */ +#include "flop.h" + +#define mathSTACK_SIZE configMINIMAL_STACK_SIZE +#define mathNUMBER_OF_TASKS ( 8 ) + +/* Four tasks, each of which performs a different floating point calculation. +Each of the four is created twice. */ +static portTASK_FUNCTION_PROTO( vCompetingMathTask1, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask2, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask3, pvParameters ); +static portTASK_FUNCTION_PROTO( vCompetingMathTask4, pvParameters ); + +/* These variables are used to check that all the tasks are still running. If a +task gets a calculation wrong it will +stop incrementing its check variable. */ +static volatile uint16_t usTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; + +/*-----------------------------------------------------------*/ + +void vStartMathTasks( UBaseType_t uxPriority ) +{ + xTaskCreate( vCompetingMathTask1, "Math1", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 0 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math2", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 1 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math3", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 2 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math4", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 3 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask1, "Math5", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 4 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask2, "Math6", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 5 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask3, "Math7", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 6 ] ), uxPriority, NULL ); + xTaskCreate( vCompetingMathTask4, "Math8", mathSTACK_SIZE, ( void * ) &( usTaskCheck[ 7 ] ), uxPriority, NULL ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask1, pvParameters ) +{ +volatile float f1, f2, f3, f4; +volatile uint16_t *pusTaskCheckVariable; +volatile float fAnswer; +short sError = pdFALSE; + + f1 = 123.4567F; + f2 = 2345.6789F; + f3 = -918.222F; + + fAnswer = ( f1 + f2 ) * f3; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for(;;) + { + f1 = 123.4567F; + f2 = 2345.6789F; + f3 = -918.222F; + + f4 = ( f1 + f2 ) * f3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( f4 - fAnswer ) > 0.001F ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask2, pvParameters ) +{ +volatile float f1, f2, f3, f4; +volatile uint16_t *pusTaskCheckVariable; +volatile float fAnswer; +short sError = pdFALSE; + + f1 = -389.38F; + f2 = 32498.2F; + f3 = -2.0001F; + + fAnswer = ( f1 / f2 ) * f3; + + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + /* Keep performing a calculation and checking the result against a constant. */ + for( ;; ) + { + f1 = -389.38F; + f2 = 32498.2F; + f3 = -2.0001F; + + f4 = ( f1 / f2 ) * f3; + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + /* If the calculation does not match the expected constant, stop the + increment of the check variable. */ + if( fabs( f4 - fAnswer ) > 0.001F ) + { + sError = pdTRUE; + } + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know + this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask3, pvParameters ) +{ +volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + fTotal1 = 0.0F; + fTotal2 = 0.0F; + fPosition = 0.0F; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pfArray[ xPosition ] = fPosition + 5.5F; + fTotal1 += fPosition + 5.5F; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + fTotal2 += pfArray[ xPosition ]; + } + + fDifference = fTotal1 - fTotal2; + if( fabs( fDifference ) > 0.001F ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( vCompetingMathTask4, pvParameters ) +{ +volatile float *pfArray, fTotal1, fTotal2, fDifference, fPosition; +volatile uint16_t *pusTaskCheckVariable; +const size_t xArraySize = 10; +size_t xPosition; +short sError = pdFALSE; + + /* The variable this task increments to show it is still running is passed in + as the parameter. */ + pusTaskCheckVariable = ( uint16_t * ) pvParameters; + + pfArray = ( float * ) pvPortMalloc( xArraySize * sizeof( float ) ); + + /* Keep filling an array, keeping a running total of the values placed in the + array. Then run through the array adding up all the values. If the two totals + do not match, stop the check variable from incrementing. */ + for( ;; ) + { + fTotal1 = 0.0F; + fTotal2 = 0.0F; + fPosition = 0.0F; + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + pfArray[ xPosition ] = fPosition * 12.123F; + fTotal1 += fPosition * 12.123F; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + for( xPosition = 0; xPosition < xArraySize; xPosition++ ) + { + fTotal2 += pfArray[ xPosition ]; + } + + fDifference = fTotal1 - fTotal2; + if( fabs( fDifference ) > 0.001F ) + { + sError = pdTRUE; + } + + #if configUSE_PREEMPTION == 0 + taskYIELD(); + #endif + + if( sError == pdFALSE ) + { + /* If the calculation has always been correct, increment the check + variable so we know this task is still running okay. */ + ( *pusTaskCheckVariable )++; + } + } +} +/*-----------------------------------------------------------*/ + +/* This is called to check that all the created tasks are still running. */ +BaseType_t xAreMathsTaskStillRunning( void ) +{ +/* Keep a history of the check variables so we know if they have been incremented +since the last call. */ +static uint16_t usLastTaskCheck[ mathNUMBER_OF_TASKS ] = { ( uint16_t ) 0 }; +BaseType_t xReturn = pdTRUE, xTask; + + /* Check the maths tasks are still running by ensuring their check variables + are still incrementing. */ + for( xTask = 0; xTask < mathNUMBER_OF_TASKS; xTask++ ) + { + if( usTaskCheck[ xTask ] == usLastTaskCheck[ xTask ] ) + { + /* The check has not incremented so an error exists. */ + xReturn = pdFALSE; + } + + usLastTaskCheck[ xTask ] = usTaskCheck[ xTask ]; + } + + return xReturn; +} + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/ReadMe.txt b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/ReadMe.txt new file mode 100644 index 0000000..769b122 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/ReadMe.txt @@ -0,0 +1,14 @@ +Contains the files that are not specific to any one demo, but are instead used +by all the demo applications. + +Most of the directories are now obsolete, and only maintained for backward +compatibility. The directories in active use are: + ++ Minimal - this contains the implementation of what are referred to as the +"Standard Demo Tasks". These are used by all the demo applications. Their only +purpose is to demonstrate the FreeRTOS API and test the FreeRTOS features. The +directory is called 'Minimal' as it contains a minimal implementation of files +contained in the 'Full' directory - but the 'Full' directory is no longer used. + ++ include - contains header files for the C source files located in the Minimal +directory. \ No newline at end of file diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/AbortDelay.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/AbortDelay.h new file mode 100644 index 0000000..b650c84 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/AbortDelay.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef ABORT_DELAY_H +#define ABORT_DELAY_H + +void vCreateAbortDelayTasks( void ); +BaseType_t xAreAbortDelayTestTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/BlockQ.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/BlockQ.h new file mode 100644 index 0000000..417882a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/BlockQ.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef BLOCK_Q_H +#define BLOCK_Q_H + +void vStartBlockingQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreBlockingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/EventGroupsDemo.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/EventGroupsDemo.h new file mode 100644 index 0000000..7b729d0 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/EventGroupsDemo.h @@ -0,0 +1,86 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + + +/* + * This file contains fairly comprehensive checks on the behaviour of event + * groups. It is not intended to be a user friendly demonstration of the event + * groups API. + */ + +#ifndef EVENT_GROUPS_DEMO_H +#define EVENT_GROUPS_DEMO_H + +void vStartEventGroupTasks( void ); +BaseType_t xAreEventGroupTasksStillRunning( void ); +void vPeriodicEventGroupsProcessing( void ); + +#endif /* EVENT_GROUPS_DEMO_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/GenQTest.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/GenQTest.h new file mode 100644 index 0000000..dfbbb0d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/GenQTest.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef GEN_Q_TEST_H +#define GEN_Q_TEST_H + +void vStartGenericQueueTasks( UBaseType_t uxPriority ); +BaseType_t xAreGenericQueueTasksStillRunning( void ); +void vMutexISRInteractionTest( void ); + +#endif /* GEN_Q_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntQueue.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntQueue.h new file mode 100644 index 0000000..8b2cc3e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntQueue.h @@ -0,0 +1,84 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_ACCESS_TEST +#define QUEUE_ACCESS_TEST + +void vStartInterruptQueueTasks( void ); +BaseType_t xAreIntQueueTasksStillRunning( void ); +BaseType_t xFirstTimerHandler( void ); +BaseType_t xSecondTimerHandler( void ); + +#endif /* QUEUE_ACCESS_TEST */ + + + + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntSemTest.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntSemTest.h new file mode 100644 index 0000000..94316e9 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/IntSemTest.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INT_SEM_TEST_H +#define INT_SEM_TEST_H + +void vStartInterruptSemaphoreTasks( void ); +BaseType_t xAreInterruptSemaphoreTasksStillRunning( void ); +void vInterruptSemaphorePeriodicTest( void ); + +#endif /* INT_SEM_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/PollQ.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/PollQ.h new file mode 100644 index 0000000..ab2844d --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/PollQ.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef POLLED_Q_H +#define POLLED_Q_H + +void vStartPolledQueueTasks( UBaseType_t uxPriority ); +BaseType_t xArePollingQueuesStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QPeek.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QPeek.h new file mode 100644 index 0000000..64087b6 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QPeek.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef Q_PEEK_TEST_H +#define Q_PEEK_TEST_H + +void vStartQueuePeekTasks( void ); +BaseType_t xAreQueuePeekTasksStillRunning( void ); + +#endif /* Q_PEEK_TEST_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueOverwrite.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueOverwrite.h new file mode 100644 index 0000000..a87ec7e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueOverwrite.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_OVERWRITE_H +#define QUEUE_OVERWRITE_H + +void vStartQueueOverwriteTask( UBaseType_t uxPriority ); +BaseType_t xIsQueueOverwriteTaskStillRunning( void ); +void vQueueOverwritePeriodicISRDemo( void ); + +#endif /* QUEUE_OVERWRITE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSet.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSet.h new file mode 100644 index 0000000..92cbc19 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSet.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_WAIT_MULTIPLE_H +#define QUEUE_WAIT_MULTIPLE_H + +void vStartQueueSetTasks( void ); +BaseType_t xAreQueueSetTasksStillRunning( void ); +void vQueueSetAccessQueueSetFromISR( void ); + +#endif /* QUEUE_WAIT_MULTIPLE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSetPolling.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSetPolling.h new file mode 100644 index 0000000..b11d5b5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/QueueSetPolling.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef QUEUE_SET_POLLING_H +#define QUEUE_SET_POLLING_H + +void vStartQueueSetPollingTask( void ); +BaseType_t xAreQueueSetPollTasksStillRunning( void ); +void vQueueSetPollingInterruptAccess( void ); + +#endif /* QUEUE_SET_POLLING_H */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/StaticAllocation.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/StaticAllocation.h new file mode 100644 index 0000000..b8f8d8f --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/StaticAllocation.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef STATIC_ALLOCATION_H +#define STATIC_ALLOCATION_H + +void vStartStaticallyAllocatedTasks( void ); +BaseType_t xAreStaticAllocationTasksStillRunning( void ); + +#endif /* STATIC_ALLOCATION_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TaskNotify.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TaskNotify.h new file mode 100644 index 0000000..7865d99 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TaskNotify.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef TASK_NOTIFY_H +#define TASK_NOTIFY_H + +void vStartTaskNotifyTask( void ); +BaseType_t xAreTaskNotificationTasksStillRunning( void ); +void xNotifyTaskFromISR( void ); + +#endif /* TASK_NOTIFY_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TimerDemo.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TimerDemo.h new file mode 100644 index 0000000..00ee5a2 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/TimerDemo.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef TIMER_DEMO_H +#define TIMER_DEMO_H + +void vStartTimerDemoTask( TickType_t xBaseFrequencyIn ); +BaseType_t xAreTimerDemoTasksStillRunning( TickType_t xCycleFrequency ); +void vTimerPeriodicISRTests( void ); + +#endif /* TIMER_DEMO_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/blocktim.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/blocktim.h new file mode 100644 index 0000000..181ea19 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/blocktim.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef BLOCK_TIME_TEST_H +#define BLOCK_TIME_TEST_H + +void vCreateBlockTimeTasks( void ); +BaseType_t xAreBlockTimeTestTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest.h new file mode 100644 index 0000000..31af7be --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +void vStartComTestTasks( UBaseType_t uxPriority, eCOMPort ePort, eBaud eBaudRate ); +BaseType_t xAreComTestTasksStillRunning( void ); +void vComTestUnsuspendTask( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest2.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest2.h new file mode 100644 index 0000000..972c177 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest2.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_H +#define COMTEST_H + +void vAltStartComTestTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest_strings.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest_strings.h new file mode 100644 index 0000000..1fc61dc --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/comtest_strings.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COMTEST_STRINGS_H +#define COMTEST_STRINGS_H + +void vStartComTestStringsTasks( UBaseType_t uxPriority, uint32_t ulBaudRate, UBaseType_t uxLED ); +BaseType_t xAreComTestTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/countsem.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/countsem.h new file mode 100644 index 0000000..fb38b4c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/countsem.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef COUNT_SEMAPHORE_TEST_H +#define COUNT_SEMAPHORE_TEST_H + +void vStartCountingSemaphoreTasks( void ); +BaseType_t xAreCountingSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crflash.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crflash.h new file mode 100644 index 0000000..9b384bf --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crflash.h @@ -0,0 +1,89 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CRFLASH_LED_H +#define CRFLASH_LED_H + +/* + * Create the co-routines used to flash the LED's at different rates. + * + * @param uxPriority The number of 'fixed delay' co-routines to create. This + * also effects the number of LED's that will be utilised. For example, + * passing in 3 will cause LED's 0 to 2 to be utilised. + */ +void vStartFlashCoRoutines( UBaseType_t uxPriority ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +BaseType_t xAreFlashCoRoutinesStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crhook.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crhook.h new file mode 100644 index 0000000..293f4b5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/crhook.h @@ -0,0 +1,85 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CRHOOK_H +#define CRHOOK_H + +/* + * Create the co-routines used to communicate wit the tick hook. + */ +void vStartHookCoRoutines( void ); + +/* + * Return pdPASS or pdFAIL depending on whether an error has been detected + * or not. + */ +BaseType_t xAreHookCoRoutinesStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/death.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/death.h new file mode 100644 index 0000000..a3c2463 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/death.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SUICIDE_TASK_H +#define SUICIDE_TASK_H + +void vCreateSuicidalTasks( UBaseType_t uxPriority ); +BaseType_t xIsCreateTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/dynamic.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/dynamic.h new file mode 100644 index 0000000..405f0ad --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/dynamic.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef DYNAMIC_MANIPULATION_H +#define DYNAMIC_MANIPULATION_H + +void vStartDynamicPriorityTasks( void ); +BaseType_t xAreDynamicPriorityTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/fileIO.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/fileIO.h new file mode 100644 index 0000000..616f279 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/fileIO.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FILE_IO_H +#define FILE_IO_H + +void vDisplayMessage( const char * const pcMessageToPrint ); +void vWriteMessageToDisk( const char * const pcMessage ); +void vWriteBufferToDisk( const char * const pcBuffer, uint32_t ulBufferLength ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash.h new file mode 100644 index 0000000..5930023 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash.h @@ -0,0 +1,76 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLASH_LED_H +#define FLASH_LED_H + +void vStartLEDFlashTasks( UBaseType_t uxPriority ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash_timer.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash_timer.h new file mode 100644 index 0000000..9b062cd --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flash_timer.h @@ -0,0 +1,83 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLASH_TIMER_H +#define FLASH_TIMER_H + +/* + * Creates the LED flashing timers. xNumberOfLEDs specifies how many timers to + * create, with each timer toggling a different LED. The first LED to be + * toggled is LED 0, with subsequent LEDs following on in numerical order. Each + * timer uses the exact same callback function, with the timer ID being used + * within the callback function to determine which timer has actually expired + * (and therefore which LED to toggle). + */ +void vStartLEDFlashTimers( UBaseType_t uxNumberOfLEDs ); + +#endif /* FLASH_TIMER_H */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flop.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flop.h new file mode 100644 index 0000000..86c425c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/flop.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef FLOP_TASKS_H +#define FLOP_TASKS_H + +void vStartMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreMathsTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/integer.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/integer.h new file mode 100644 index 0000000..0289854 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/integer.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INTEGER_TASKS_H +#define INTEGER_TASKS_H + +void vStartIntegerMathTasks( UBaseType_t uxPriority ); +BaseType_t xAreIntegerMathsTaskStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/mevents.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/mevents.h new file mode 100644 index 0000000..467f631 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/mevents.h @@ -0,0 +1,78 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef EVENTS_TEST_H +#define EVENTS_TEST_H + +void vStartMultiEventTasks( void ); +BaseType_t xAreMultiEventTasksStillRunning( void ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/partest.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/partest.h new file mode 100644 index 0000000..ecfa519 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/partest.h @@ -0,0 +1,80 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PARTEST_H +#define PARTEST_H + +#define partstDEFAULT_PORT_ADDRESS ( ( uint16_t ) 0x378 ) + +void vParTestInitialise( void ); +void vParTestSetLED( UBaseType_t uxLED, BaseType_t xValue ); +void vParTestToggleLED( UBaseType_t uxLED ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/print.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/print.h new file mode 100644 index 0000000..2e325d5 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/print.h @@ -0,0 +1,79 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PRINT_H +#define PRINT_H + +void vPrintInitialise( void ); +void vPrintDisplayMessage( const char * const * pcMessageToSend ); +const char *pcPrintGetNextMessage( TickType_t xPrintRate ); + +#endif + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/recmutex.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/recmutex.h new file mode 100644 index 0000000..880e3d8 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/recmutex.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef RECURSIVE_MUTEX_TEST_H +#define RECURSIVE_MUTEX_TEST_H + +void vStartRecursiveMutexTasks( void ); +BaseType_t xAreRecursiveMutexTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/semtest.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/semtest.h new file mode 100644 index 0000000..515a352 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/semtest.h @@ -0,0 +1,77 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SEMAPHORE_TEST_H +#define SEMAPHORE_TEST_H + +void vStartSemaphoreTasks( UBaseType_t uxPriority ); +BaseType_t xAreSemaphoreTasksStillRunning( void ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/serial.h b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/serial.h new file mode 100644 index 0000000..bc3a729 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Demo/Common/include/serial.h @@ -0,0 +1,140 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SERIAL_COMMS_H +#define SERIAL_COMMS_H + +typedef void * xComPortHandle; + +typedef enum +{ + serCOM1, + serCOM2, + serCOM3, + serCOM4, + serCOM5, + serCOM6, + serCOM7, + serCOM8 +} eCOMPort; + +typedef enum +{ + serNO_PARITY, + serODD_PARITY, + serEVEN_PARITY, + serMARK_PARITY, + serSPACE_PARITY +} eParity; + +typedef enum +{ + serSTOP_1, + serSTOP_2 +} eStopBits; + +typedef enum +{ + serBITS_5, + serBITS_6, + serBITS_7, + serBITS_8 +} eDataBits; + +typedef enum +{ + ser50, + ser75, + ser110, + ser134, + ser150, + ser200, + ser300, + ser600, + ser1200, + ser1800, + ser2400, + ser4800, + ser9600, + ser19200, + ser38400, + ser57600, + ser115200 +} eBaud; + +xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ); +xComPortHandle xSerialPortInit( eCOMPort ePort, eBaud eWantedBaud, eParity eWantedParity, eDataBits eWantedDataBits, eStopBits eWantedStopBits, unsigned portBASE_TYPE uxBufferLength ); +void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength ); +signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime ); +signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime ); +portBASE_TYPE xSerialWaitForSemaphore( xComPortHandle xPort ); +void vSerialClose( xComPortHandle xPort ); + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/License/license.txt b/USDK/component/os/freertos/freertos_v9.0.0/License/license.txt new file mode 100644 index 0000000..5d243b8 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/License/license.txt @@ -0,0 +1,399 @@ +The FreeRTOS open source license covers the FreeRTOS source files, +which are located in the /FreeRTOS/Source directory of the official FreeRTOS +download. It also covers most of the source files in the demo application +projects, which are located in the /FreeRTOS/Demo directory of the official +FreeRTOS download. The demo projects may also include third party software that +is not part of FreeRTOS and is licensed separately to FreeRTOS. Examples of +third party software includes header files provided by chip or tools vendors, +linker scripts, peripheral drivers, etc. All the software in subdirectories of +the /FreeRTOS directory is either open source or distributed with permission, +and is free for use. For the avoidance of doubt, refer to the comments at the +top of each source file. + +---------------------------------------------------------------------------- + +NOTE: The modification to the GPL is included to allow you to distribute a +combined work that includes FreeRTOS without being obliged to provide the source +code for proprietary components. + +---------------------------------------------------------------------------- + +Applying to FreeRTOS V8.2.3 up to the latest version, the FreeRTOS GPL Exception +Text follows: + +Any FreeRTOS *source code*, whether modified or in it's original release form, +or whether in whole or in part, can only be distributed by you under the terms +of the GNU General Public License plus this exception. An independent module is +a module which is not derived from or based on FreeRTOS. + +Clause 1: + +Linking FreeRTOS with other modules is making a combined work based on FreeRTOS. +Thus, the terms and conditions of the GNU General Public License V2 cover the +whole combination. + +As a special exception, the copyright holders of FreeRTOS give you permission to +link FreeRTOS with independent modules to produce a statically linked +executable, regardless of the license terms of these independent modules, and to +copy and distribute the resulting executable under terms of your choice, +provided that you also meet, for each linked independent module, the terms and +conditions of the license of that module. An independent module is a module +which is not derived from or based on FreeRTOS. + +Clause 2: + +FreeRTOS may not be used for any competitive or comparative purpose, including +the publication of any form of run time or compile time metric, without the +express permission of Real Time Engineers Ltd. (this is the norm within the +industry and is intended to ensure information accuracy). + + + +-------------------------------------------------------------------- + + + +The standard GPL V2 text: + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License** as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/croutine.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/croutine.c new file mode 100644 index 0000000..993e09b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/croutine.c @@ -0,0 +1,395 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +CRCB_t * pxCurrentCoRoutine = NULL; +static UBaseType_t uxTopCoRoutineReadyPriority = 0; +static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) +{ +BaseType_t xReturn; +CRCB_t *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) +{ +TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +CRCB_t *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pvContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) +{ +CRCB_t *pxUnblockedCRCB; +BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + +#endif /* configUSE_CO_ROUTINES == 0 */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/event_groups.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/event_groups.c new file mode 100644 index 0000000..b8df5fd --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/event_groups.c @@ -0,0 +1,752 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + +/* The following bit fields convey control information in a task's event list +item value. It is important they don't clash with the +taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if configUSE_16_BIT_TICKS == 1 + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#else + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#endif + +typedef struct xEventGroupDefinition +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) + { + EventGroup_t *pxEventBits; + + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); + + /* The user has provided a statically allocated event group - use it. */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + this event group was created statically in case the event group + is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); + } + + return ( EventGroupHandle_t ) pxEventBits; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) + { + EventGroup_t *pxEventBits; + + /* Allocate the event group. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note this + event group was allocated statically in case the event group is + later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); + } + + return ( EventGroupHandle_t ) pxEventBits; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t uxOriginalBitValue, uxReturn; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + the task unblocks, but some compilers mistakenly generate a + warning about uxReturn being returned without being set if the + assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + bits it was waiting for were set, it is possible that since it + unblocked another task has set the bits. If this is the case + then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn, uxControlBits = 0; +BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + } + else + { + /* The task is going to block to wait for its required bits to be + set. uxControlBits are used to remember the specified behaviour of + this call to xEventGroupWaitBits() - for use when the event bits + unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + some compilers mistakenly generate a warning about the variable + being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Prevent compiler warnings when trace macros are not used. */ + xTimeoutOccurred = pdFALSE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ +UBaseType_t uxSavedInterruptStatus; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +ListItem_t *pxListItem, *pxNext; +ListItem_t const *pxListEnd; +List_t *pxList; +EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + item before removing the task from the event list. The + eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + that is was unblocked due to its required bits matching, rather + than because it timed out. */ + ( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + used here as the list item may have been removed from the event list + and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; +const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + ( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + it again. */ + vPortFree( pxEventBits ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + ( void ) xTaskResumeAll(); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from +an interrupt. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from +an interrupt. */ +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) +{ +BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if (configUSE_TRACE_FACILITY == 1) + + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup; + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/FreeRTOS.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/FreeRTOS.h new file mode 100644 index 0000000..06e4d97 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/FreeRTOS.h @@ -0,0 +1,1081 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +#include /* READ COMMENT ABOVE. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _PLATFORM_AUTOCONFIG_H_ +#include "platform_autoconf.h" +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +//----------- +#if defined(CONFIG_PLATFORM_8195A) + #ifndef CONFIG_USE_TCM_HEAP + #define CONFIG_USE_TCM_HEAP 1 + #endif + #ifndef configUSE_STACK_TCM_HEAP + #define configUSE_STACK_TCM_HEAP 5 // priority + #endif +#else + #undef configUSE_STACK_TCM_HEAP + #define configUSE_STACK_TCM_HEAP 0 +#endif +//----------- + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + #include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configMAX_PRIORITIES + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #if( INCLUDE_vTaskSuspend != 1 ) + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or + portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + /* The tick type can be read atomically, so critical sections used when the + tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 4 ]; +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + TickType_t xDummy1; + void *pvDummy2[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + UBaseType_t uxDummy1; + void *pvDummy2; + StaticMiniListItem_t xDummy3; +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( portSTACK_GROWTH > 0 ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; + #endif + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t uxDummy20; + #endif + +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + UBaseType_t uxDummy4; + void *pvDummy5[ 2 ]; + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy6; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy7; + #endif + +} StaticTimer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/StackMacros.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/StackMacros.h new file mode 100644 index 0000000..13c6b82 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/StackMacros.h @@ -0,0 +1,171 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/croutine.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/croutine.h new file mode 100644 index 0000000..4f003a0 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/croutine.h @@ -0,0 +1,762 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/deprecated_definitions.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/deprecated_definitions.h new file mode 100644 index 0000000..4ea816c --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/deprecated_definitions.h @@ -0,0 +1,321 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/event_groups.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/event_groups.h new file mode 100644 index 0000000..7331c91 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/event_groups.h @@ -0,0 +1,797 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +typedef void * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
+	// StaticEventGroup_t is a publicly accessible structure that has the same
+	// size and alignment requirements as the real event group structure.  It is
+	// provided as a mechanism for applications to know the size of the event
+	// group (which is dependent on the architecture and configuration file
+	// settings) without breaking the strict data hiding policy by exposing the
+	// real event group internals.  This StaticEventGroup_t variable is passed
+	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
+	// the event group's data structures
+	StaticEventGroup_t xEventGroupBuffer;
+
+	// Create the event group without dynamically allocating any memory.
+	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+   
+ */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/list.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/list.h new file mode 100644 index 0000000..a080d27 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/list.h @@ -0,0 +1,453 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H + #error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + + /* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + + /* Define macros that will assert if one of the structure members does not + contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_prototypes.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_prototypes.h new file mode 100644 index 0000000..8f7500b --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_prototypes.h @@ -0,0 +1,177 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API function. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ); +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ); +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ); +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ); +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ); +void MPU_vTaskDelay( const TickType_t xTicksToDelay ); +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ); +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ); +UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t xTask ); +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ); +void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ); +void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ); +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ); +void MPU_vTaskResume( TaskHandle_t xTaskToResume ); +void MPU_vTaskStartScheduler( void ); +void MPU_vTaskSuspendAll( void ); +BaseType_t MPU_xTaskResumeAll( void ); +TickType_t MPU_xTaskGetTickCount( void ); +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ); +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ); +TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ); +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ); +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ); +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ); +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ); +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ); +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ); +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ); +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ); +void MPU_vTaskList( char * pcWriteBuffer ); +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ); +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ); +BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ); +uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ); +BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ); +BaseType_t MPU_xTaskIncrementTick( void ); +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ); +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ); +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ); +void MPU_vTaskMissedYield( void ); +BaseType_t MPU_xTaskGetSchedulerState( void ); + +/* MPU versions of queue.h API function. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ); +BaseType_t MPU_xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ); +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ); +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ); +void MPU_vQueueDelete( QueueHandle_t xQueue ); +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ); +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ); +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ); +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ); +void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ); +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ); +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ); +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ); +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ); +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ); +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ); +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ); +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ); +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ); +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ); +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ); +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ); +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ); +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ); + +/* MPU versions of timers.h API function. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ); +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ); +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ); +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ); +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ); +BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ); +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ); +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ); +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ); +BaseType_t MPU_xTimerCreateTimerTask( void ); +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ); + +/* MPU versions of event_group.h API function. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ); +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ); +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ); +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ); +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ); +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ); +UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ); + +#endif /* MPU_PROTOTYPES_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_wrappers.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_wrappers.h new file mode 100644 index 0000000..78f5a9a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/mpu_wrappers.h @@ -0,0 +1,201 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + /* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + + /* Map standard tasks.h API functions to the MPU equivalents. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelay MPU_vTaskDelay + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define xTaskGetHandle MPU_xTaskGetHandle + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskNotifyWait MPU_xTaskNotifyWait + #define ulTaskNotifyTake MPU_ulTaskNotifyTake + #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + /* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueGenericReceive MPU_xQueueGenericReceive + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueGenericReset MPU_xQueueGenericReset + + #if( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif + + /* Map standard timer.h API functions to the MPU equivalents. */ + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall + #define pcTimerGetName MPU_pcTimerGetName + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #define xTimerGenericCommand MPU_xTimerGenericCommand + + /* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + #define vEventGroupDelete MPU_vEventGroupDelete + + /* Remove the privileged function macro. */ + #define PRIVILEGED_FUNCTION + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/portable.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/portable.h new file mode 100644 index 0000000..376b13e --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/portable.h @@ -0,0 +1,207 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; +#else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +static void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/projdefs.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/projdefs.h new file mode 100644 index 0000000..0b63fd8 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/projdefs.h @@ -0,0 +1,161 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +#endif /* PROJDEFS_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/queue.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/queue.h new file mode 100644 index 0000000..30be360 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/queue.h @@ -0,0 +1,1798 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +typedef void * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef void * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef void * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void *pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueuePeek( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdTRUE ) + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * This is a macro that calls the xQueueGenericReceive() function. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +#define xQueueReceive( xQueue, pvBuffer, xTicksToWait ) xQueueGenericReceive( ( xQueue ), ( pvBuffer ), ( xTicksToWait ), pdFALSE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericReceive(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   TickType_t	xTicksToWait
+									   BaseType_t	xJustPeek
+									);
+ * + * It is preferred that the macro xQueueReceive() be used rather than calling + * this function directly. + * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueueGenericReceive() will return immediately if the queue is empty and + * xTicksToWait is 0. + * + * @param xJustPeek When set to true, the item received from the queue is not + * actually removed from the queue - meaning a subsequent call to + * xQueueReceive() will return the same item. When set to false, the item + * being received from the queue is also removed from the queue. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueGenericReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeek ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/semphr.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/semphr.h new file mode 100644 index 0000000..a674b02 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/semphr.h @@ -0,0 +1,1171 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, but instead buried in a more complex
+			// call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = vSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/stdint.readme b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/stdint.readme new file mode 100644 index 0000000..4414c29 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/stdint.readme @@ -0,0 +1,27 @@ + +#ifndef FREERTOS_STDINT +#define FREERTOS_STDINT + +/******************************************************************************* + * THIS IS NOT A FULL stdint.h IMPLEMENTATION - It only contains the definitions + * necessary to build the FreeRTOS code. It is provided to allow FreeRTOS to be + * built using compilers that do not provide their own stdint.h definition. + * + * To use this file: + * + * 1) Copy this file into the directory that contains your FreeRTOSConfig.h + * header file, as that directory will already be in the compilers include + * path. + * + * 2) Rename the copied file stdint.h. + * + */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef long int32_t; +typedef unsigned long uint32_t; + +#endif /* FREERTOS_STDINT */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/task.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/task.h new file mode 100644 index 0000000..8d39a20 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/task.h @@ -0,0 +1,2294 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V9.0.0" +#define tskKERNEL_VERSION_MAJOR 9 +#define tskKERNEL_VERSION_MINOR 0 +#define tskKERNEL_VERSION_BUILD 0 + +//----------------------------------------------------- add +#ifndef CONFIG_USE_TCM_HEAP + #if defined(CONFIG_PLATFORM_8195A) + #define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */ + #else + #define CONFIG_USE_TCM_HEAP 0 + #endif +#endif +//------------------------------------------------- end add + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +typedef void * TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + uint16_t usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  uint16_t usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#ifdef CONFIG_USE_TCM_HEAP +BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + StackType_t * const puxStackBuffer, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; +#define xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ) xTaskGenericCreate( ( pvTaskCode ), ( pcName ), ( usStackDepth ), ( pvParameters ), ( uxPriority ), ( pxCreatedTask ), ( NULL ), ( NULL ) ) +#else + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif // CONFIG_USE_TCM_HEAP +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer + * are NULL then the task will not be created and + * errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) +#ifdef CONFIG_USE_TCM_HEAP +#define xTaskCreateRestricted( x, pxCreatedTask ) xTaskGenericCreate( ((x)->pvTaskCode), ((x)->pcName), ((x)->usStackDepth), ((x)->pvParameters), ((x)->uxPriority), (pxCreatedTask), ((x)->puxStackBuffer), ((x)->xRegions) ) +#else + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif // CONFIG_USE_TCM_HEAP +#endif + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask );
+ * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+    // Obtain the handle of a task from its name.
+    xHandle = xTaskGetHandle( "Task_Name" );
+
+    // Check the handle is not NULL.
+    configASSERT( xHandle );
+
+    // Use the handle to obtain further information about the task.
+    vTaskGetInfo( xHandle,
+                  &xTaskDetails,
+                  pdTRUE, // Include the high water mark in xTaskDetails.
+                  eInvalid ); // Include the task state in xTaskDetails.
+ }
+   
+ * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + + /* Each task contains an array of pointers that is dimensioned by the + configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + kernel does not use the pointers itself, so the application writer can use + the pointers for any purpose they wish. The following two functions are + used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer )
+	{
+	TaskStatus_t *pxTaskStatusArray;
+	volatile UBaseType_t uxArraySize, x;
+	uint32_t ulTotalRunTime, ulStatsAsPercentage;
+
+		// Make sure the write buffer does not contain a string.
+		*pcWriteBuffer = 0x00;
+
+		// Take a snapshot of the number of tasks in case it changes while this
+		// function is executing.
+		uxArraySize = uxTaskGetNumberOfTasks();
+
+		// Allocate a TaskStatus_t structure for each task.  An array could be
+		// allocated statically at compile time.
+		pxTaskStatusArray = pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
+
+		if( pxTaskStatusArray != NULL )
+		{
+			// Generate raw status information about each task.
+			uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
+
+			// For percentage calculations.
+			ulTotalRunTime /= 100UL;
+
+			// Avoid divide by zero errors.
+			if( ulTotalRunTime > 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer );
+ * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object.  Examples of such
+ * objects are queues, semaphores, mutexes and event groups.  Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value.  In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified.  The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task.  If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited.  How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * 
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/xTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * xTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only avilable when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +void *pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_TASK_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/include/timers.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/timers.h new file mode 100644 index 0000000..798c955 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/include/timers.h @@ -0,0 +1,1314 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint +e537 */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +typedef void * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/list.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/list.c new file mode 100644 index 0000000..5e207c1 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/list.c @@ -0,0 +1,240 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; + + /* Write known values into the list if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); + listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pvContainer = NULL; + + /* Write known values into the list item if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t * const pxIndex = pxList->pxIndex; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t *pxIterator; +const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert the new list item into the list, sorted in xItemValue order. + + If the list already contains a list item with the same item value then the + new list item should be placed after it. This ensures that TCB's which are + stored in ready lists (all of which have the same xItemValue value) get a + share of the CPU. However, if the xItemValue is the same as the back marker + the iteration loop below will not end. Therefore the value is checked + first, and the algorithm slightly modified if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are + listed below. In addition see http://www.freertos.org/FAQHelp.html for + more tips, and ensure configASSERT() is defined! + http://www.freertos.org/a00110.html#configASSERT + + 1) Stack overflow - + see http://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M + parts where numerically high priority values denote low actual + interrupt priorities, which can seem counter intuitive. See + http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition + of configMAX_SYSCALL_INTERRUPT_PRIORITY on + http://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + { + /* There is nothing to do here, just iterating to the wanted + insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pvContainer = ( void * ) pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list +item. */ +List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pvContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/Common/mpu_wrappers.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/Common/mpu_wrappers.c new file mode 100644 index 0000000..16c0863 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/Common/mpu_wrappers.c @@ -0,0 +1,1140 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* + * Checks to see if being called from the context of an unprivileged task, and + * if so raises the privilege level and returns false - otherwise does nothing + * other than return true. + */ +extern BaseType_t xPortRaisePrivilege( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestricted( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskAbortDelay( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( TaskHandle_t pxTask ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + eTaskState eReturn; + + eReturn = eTaskGetState( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspendAll(); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskResumeAll( void ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskResumeAll(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) +{ +TickType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) +{ +UBaseType_t uxReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) +{ +char *pcReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTaskGetName( xTaskToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetHandle( pcNameToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + void MPU_vTaskList( char *pcWriteBuffer ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TaskHookFunction_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + vPortResetPrivilege( xRunningPrivileged ); + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetTimeOutState( pxTimeOut ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGenericNotify( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) + { + uint32_t ulReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + ulReturn = ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return ulReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyStateClear( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueSpacesAvailable( xQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait, BaseType_t xJustPeeking ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t pxQueue, void * const pvBuffer ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueuePeekFromISR( pxQueue, pvBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +void* MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +void * xReturn; + + xReturn = ( void * ) xQueueGetMutexHolder( xSemaphore ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutex( ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) + { + QueueSetMemberHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueUnregisterQueue( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + const char *MPU_pcQueueGetName( QueueHandle_t xQueue ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + const char *pcReturn; + + pcReturn = pcQueueGetName( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vQueueDelete( QueueHandle_t xQueue ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueDelete( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + void *MPU_pvPortMalloc( size_t xSize ) + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + void MPU_vPortFree( void *pv ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortFree( pv ); + + vPortResetPrivilege( xRunningPrivileged ); + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void MPU_vPortInitialiseBlocks( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortInitialiseBlocks(); + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xPortGetFreeHeapSize( void ) +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxTimerBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void *MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) + { + void * pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTimerGetTimerID( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetTimerID( xTimer, pvNewID ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerIsTimerActive( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetTimerDaemonTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerPendFunctionCall( xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) + { + const char * pcReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTimerGetName( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetPeriod( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetExpiryTime( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreate( void ) + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreate(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vEventGroupDelete( xEventGroup ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + + + + + +/* Functions that the application writer wants to execute in privileged mode +can be defined in application_defined_privileged_functions.h. The functions +must take the same format as those above whereby the privilege state on exit +equals the privilege state on entry. For example: + +void MPU_FunctionName( [parameters ] ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + FunctionName( [parameters ] ); + + vPortResetPrivilege( xRunningPrivileged ); +} +*/ + +#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" +#endif diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/port.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/port.c new file mode 100644 index 0000000..7389102 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/port.c @@ -0,0 +1,715 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is +defined. The value should also ensure backward compatibility. +FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ +#ifndef configKERNEL_INTERRUPT_PRIORITY + #define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000UL ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case it messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " orr r14, #0xd \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. */ + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " stmdb r0!, {r4-r11} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " \n" /* Restore the context, including the critical nesting count. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11} \n" /* Pop the registers. */ + " msr psp, r0 \n" + " isb \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ); + __asm volatile( "dsb" ); //-rt812 + __asm volatile( "isb" ); //-rt812 + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ +/*-----------------------------------------------------------*/ +#if configUSE_IDLE_HOOK +void vApplicationIdleHook( void ) +{ + /* Use the idle task to place the CPU into a low power mode. Greater power + saving could be achieved by not including any demo tasks that never block. */ +#ifdef CONFIG_WDG_ON_IDLE + WDGRefresh(); +#endif +} +#endif + +#if configCHECK_FOR_STACK_OVERFLOW +#include "diag.h" +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + /* This function will be called if a task overflows its stack, if + configCHECK_FOR_STACK_OVERFLOW != 0. It might be that the function + parameters have been corrupted, depending on the severity of the stack + overflow. When this is the case pxCurrentTCB can be inspected in the + debugger to find the offending task. */ + DiagPrintf("\nSTACK OVERFLOW - TaskName(%s)\n", pcTaskName); + for( ;; ); +} +#endif +/*-----------------------------------------------------------*/ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/portmacro.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/portmacro.h new file mode 100644 index 0000000..d44fc92 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3/portmacro.h @@ -0,0 +1,284 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +#define portYIELD() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); +} +/*-----------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/port.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/port.c new file mode 100644 index 0000000..b21c889 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/port.c @@ -0,0 +1,771 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Constants required to access and manipulate the NVIC. */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSPRI1_REG ( * ( ( volatile uint32_t * ) 0xe000ed1c ) ) +#define portNVIC_SYS_CTRL_STATE_REG ( * ( ( volatile uint32_t * ) 0xe000ed24 ) ) +#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) + +/* Constants required to access and manipulate the MPU. */ +#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_REGION_BASE_ADDRESS_REG ( * ( ( volatile uint32_t * ) 0xe000ed9C ) ) +#define portMPU_REGION_ATTRIBUTE_REG ( * ( ( volatile uint32_t * ) 0xe000edA0 ) ) +#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portEXPECTED_MPU_TYPE_VALUE ( 8UL << 8UL ) /* 8 regions, unified. */ +#define portMPU_ENABLE ( 0x01UL ) +#define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) +#define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) +#define portMPU_REGION_VALID ( 0x10UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) +#define portPERIPHERALS_START_ADDRESS 0x40000000UL +#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL + +/* Constants required to access and manipulate the SysTick. */ +#define portNVIC_SYSTICK_CLK ( 0x00000004UL ) +#define portNVIC_SYSTICK_INT ( 0x00000002UL ) +#define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) +#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_PC ( 6 ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Each task maintains its own interrupt status in the critical nesting +variable. Note this is not saved as part of the task context as context +switches can only occur when uxCriticalNesting is zero. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/* + * Configure a number of standard MPU regions that are used by all tasks. + */ +static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; + +/* + * Return the smallest MPU region size that a given number of bytes will fit + * into. The region size is returned as the value that should be programmed + * into the region attribute register for that region. + */ +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; + +/* + * Checks to see if being called from the context of an unprivileged task, and + * if so raises the privilege level and returns false - otherwise does nothing + * other than return true. + */ +BaseType_t xPortRaisePrivilege( void ) __attribute__(( naked )); + +/* + * Standard FreeRTOS exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; +void xPortSysTickHandler( void ) __attribute__ ((optimize("3"))) PRIVILEGED_FUNCTION; +void vPortSVCHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; + +/* + * Starts the scheduler by restoring the context of the first task to run. + */ +static void prvRestoreContextOfFirstTask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; + +/* + * C portion of the SVC handler. The SVC handler is split between an asm entry + * and a C wrapper for simplicity of coding and maintenance. + */ +static void prvSVCHandler( uint32_t *pulRegisters ) __attribute__(( noinline )) PRIVILEGED_FUNCTION; + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = 0; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + /* Assumes psp was in use. */ + __asm volatile + ( + #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + #else + " mrs r0, psp \n" + #endif + " b %0 \n" + ::"i"(prvSVCHandler):"r0" + ); +} +/*-----------------------------------------------------------*/ + +static void prvSVCHandler( uint32_t *pulParam ) +{ +uint8_t ucSVCNumber; + + /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and + xPSR. The first argument (r0) is pulParam[ 0 ]. */ + ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; + switch( ucSVCNumber ) + { + case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI; + prvRestoreContextOfFirstTask(); + break; + + case portSVC_YIELD : portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + /* Barriers are normally not required + but do ensure the code is completely + within the specified behaviour for the + architecture. */ + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + break; + + case portSVC_RAISE_PRIVILEGE : __asm volatile + ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Set privilege bit. */ + " msr control, r1 \n" /* Write back new control value. */ + :::"r1" + ); + break; + + default : /* Unknown SVC call. */ + break; + } +} +/*-----------------------------------------------------------*/ + +static void prvRestoreContextOfFirstTask( void ) +{ + __asm volatile + ( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3, r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldr r14, =0xfffffffd \n" /* Load exec return code. */ + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See + http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the same priority as the kernel, and the SVC + handler higher priority so it can be used to exit a critical section (where + lower priorities are masked). */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Configure the regions in the MPU that are common to all tasks. */ + prvSetupMPU(); + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + prvSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Start the first task. */ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc %0 \n" /* System call to start first task. */ + " nop \n" + :: "i" (portSVC_START_SCHEDULER) ); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " mrs r1, control \n" + " stmdb r0!, {r1, r4-r11} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3, r4-r11} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " \n" + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ +uint32_t ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +static void prvSetupTimerInterrupt( void ) +{ + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; +} +/*-----------------------------------------------------------*/ + +static void prvSetupMPU( void ) +{ +extern uint32_t __privileged_functions_end__[]; +extern uint32_t __FLASH_segment_start__[]; +extern uint32_t __FLASH_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; + + /* Check the expected MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* First setup the entire flash for unprivileged read only access. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portUNPRIVILEGED_FLASH_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the first 16K for privileged only access (even though less + than 10K is actually being used). This is where the kernel code is + placed. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_FLASH_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the privileged data RAM region. This is where the kernel data + is placed. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_RAM_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* By default allow everything to access the general peripherals. The + system peripherals and registers are protected. */ + portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | + ( portMPU_REGION_VALID ) | + ( portGENERAL_PERIPHERALS_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | + ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | + ( portMPU_REGION_ENABLE ); + + /* Enable the memory fault exception. */ + portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; + + /* Enable the MPU with the background region configured. */ + portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); + } +} +/*-----------------------------------------------------------*/ + +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) +{ +uint32_t ulRegionSize, ulReturnValue = 4; + + /* 32 is the smallest region size, 31 is the largest valid value for + ulReturnValue. */ + for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + into the the correct bit position of the attribute register. */ + return ( ulReturnValue << 1UL ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortRaisePrivilege( void ) +{ + __asm volatile + ( + " mrs r0, control \n" + " tst r0, #1 \n" /* Is the task running privileged? */ + " itte ne \n" + " movne r0, #0 \n" /* CONTROL[0]!=0, return false. */ + " svcne %0 \n" /* Switch to privileged. */ + " moveq r0, #1 \n" /* CONTROL[0]==0, return true. */ + " bx lr \n" + :: "i" (portSVC_RAISE_PRIVILEGE) : "r0" + ); + + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) +{ +extern uint32_t __SRAM_segment_start__[]; +extern uint32_t __SRAM_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; +int32_t lIndex; +uint32_t ul; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all RAM. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Re-instate the privileged only RAM region as xRegion[ 0 ] will have + just removed the privileged only parameters. */ + xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress = + ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + 1 ); + + xMPUSettings->xRegion[ 1 ].ulRegionAttribute = + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* Invalidate all other regions. */ + for( ul = 2; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + } + else + { + /* This function is called automatically when the task is created - in + which case the stack region parameters will be valid. At all other + times the stack parameters will not be valid and it is assumed that the + stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + /* Define the region that allows access to the stack. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) pxBottomOfStack ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); /* Region number. */ + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | /* Read and write. */ + ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( portMPU_REGION_ENABLE ); + } + + lIndex = 0; + + for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + { + /* Translate the generic region definition contained in + xRegions into the CM3 specific MPU settings that are then + stored in xMPUSettings. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = + ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + ul ); /* Region number. */ + + xMPUSettings->xRegion[ ul ].ulRegionAttribute = + ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | + ( xRegions[ lIndex ].ulParameters ) | + ( portMPU_REGION_ENABLE ); + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + + lIndex++; + } + } +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ +/*-----------------------------------------------------------*/ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/portmacro.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/portmacro.h new file mode 100644 index 0000000..15ca256 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM3_MPU/portmacro.h @@ -0,0 +1,332 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* MPU specific constants. */ +#define portUSING_MPU_WRAPPERS 1 +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* SVC numbers for various services. */ +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 + +/* Scheduler utilities. */ + +#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) ) +#define portYIELD_WITHIN_API() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +/* Set the privilege level to user mode if xRunningPrivileged is false. */ +portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) +{ + if( xRunningPrivileged != pdTRUE ) + { + __asm volatile ( " mrs r0, control \n" \ + " orr r0, #1 \n" \ + " msr control, r0 \n" \ + :::"r0" ); + } +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); +} +/*-----------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/port.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/port.c new file mode 100644 index 0000000..7a0d7e8 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/port.c @@ -0,0 +1,763 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#ifndef configSYSTICK_CLOCK_HZ + #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ + /* Ensure the SysTick is clocked at the same frequency as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 1UL << 2UL ) +#else + /* The way the SysTick is clocked is not modified in case it is not the same + as the core. */ + #define portNVIC_SYSTICK_CLK_BIT ( 0 ) +#endif + +/* Constants required to manipulate the core. Registers first... */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_INT_BIT ( 1UL << 1UL ) +#define portNVIC_SYSTICK_ENABLE_BIT ( 1UL << 0UL ) +#define portNVIC_SYSTICK_COUNT_FLAG_BIT ( 1UL << 16UL ) +#define portNVIC_PENDSVCLEAR_BIT ( 1UL << 27UL ) +#define portNVIC_PEND_SYSTICK_CLEAR_BIT ( 1UL << 25UL ) + +/* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 +r0p1 port. */ +#define portCPUID ( * ( ( volatile uint32_t * ) 0xE000ed00 ) ) +#define portCORTEX_M7_r0p1_ID ( 0x410FC271UL ) +#define portCORTEX_M7_r0p0_ID ( 0x410FC270UL ) + +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ +#define portVECTACTIVE_MASK ( 0xFFUL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) + +/* The systick is a 24-bit counter. */ +#define portMAX_24_BIT_NUMBER ( 0xffffffUL ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* A fiddle factor to estimate the number of SysTick counts that would have +occurred while the SysTick counter is stopped during tickless idle +calculations. */ +#define portMISSED_COUNTS_FACTOR ( 45UL ) + +/* Let the user override the pre-loading of the initial LR with the address of +prvTaskExitError() in case it messes up unwinding of the stack in the +debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. The implementation in this + * file is weak to allow application writers to change the timer used to + * generate the tick interrupt. + */ +void vPortSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +static void prvPortStartFirstTask( void ) __attribute__ (( naked )); + +/* + * Function to enable the VFP. + */ +static void vPortEnableVFP( void ) __attribute__ (( naked )); + +/* + * Used to catch tasks that attempt to return from their implementing function. + */ +static void prvTaskExitError( void ); + +/*-----------------------------------------------------------*/ + +/* + * The number of SysTick increments that make up one tick period. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulTimerCountsForOneTick = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * 24 bit resolution of the SysTick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the SysTick is stopped (low + * power functionality only. + */ +#if configUSE_TICKLESS_IDLE == 1 + static uint32_t ulStoppedTimerCompensation = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack--; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +static void prvTaskExitError( void ) +{ + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT( uxCriticalNesting == ~0UL ); + portDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + __asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldmia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " isb \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +static void prvPortStartFirstTask( void ) +{ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + + /* This port can be used on all revisions of the Cortex-M7 core other than + the r0p1 parts. r0p1 parts should use the port from the + /source/portable/GCC/ARM_CM7/r0p1 directory. */ + configASSERT( portCPUID != portCORTEX_M7_r0p1_ID ); + configASSERT( portCPUID != portCORTEX_M7_r0p0_ID ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the lowest priority interrupts. */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + vPortSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + prvPortStartFirstTask(); + + /* Should never get here as the tasks will now be executing! Call the task + exit error function to prevent compiler warnings about a static function + not being called in the case that the application writer overrides this + functionality by defining configTASK_RETURN_ADDRESS. */ + prvTaskExitError(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); + } +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " isb \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ + " \n" + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3} \n" + " \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" + " \n" + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " isb \n" + " \n" + #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ + #if WORKAROUND_PMU_CM001 == 1 + " push { r14 } \n" + " pop { pc } \n" + #endif + #endif + " \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* A context switch is required. Context switching is performed in + the PendSV interrupt. Pend the PendSV interrupt. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +#if configUSE_TICKLESS_IDLE == 1 + + __attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ) + { + uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL; + TickType_t xModifiableIdleTime; + + /* Make sure the SysTick reload value does not overflow the counter. */ + if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ) + { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the SysTick momentarily. The time the SysTick is stopped for + is accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; + + /* Calculate the reload value required to wait xExpectedIdleTime + tick periods. -1 is used because this code will execute part way + through one of the tick periods. */ + ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) ); + if( ulReloadValue > ulStoppedTimerCompensation ) + { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + method as that will mask interrupts that should exit sleep mode. */ + __asm volatile( "cpsid i" ); + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + /* If a context switch is pending or a task is waiting for the scheduler + to be unsuspended then abandon the low power entry. */ + if( eTaskConfirmSleepModeStatus() == eAbortSleep ) + { + /* Restart from whatever is left in the count register to complete + this tick period. */ + portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Reset the reload register to the value required for normal tick + periods. */ + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + } + else + { + /* Set the new reload value. */ + portNVIC_SYSTICK_LOAD_REG = ulReloadValue; + + /* Clear the SysTick count flag and set the count value back to + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + + /* Restart SysTick. */ + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + set its parameter to 0 to indicate that its implementation contains + its own wait for interrupt or wait for event instruction, and so wfi + should not be executed again. However, the original expected idle + time variable must remain unmodified, so a copy is taken. */ + xModifiableIdleTime = xExpectedIdleTime; + configPRE_SLEEP_PROCESSING( xModifiableIdleTime ); + if( xModifiableIdleTime > 0 ) + { + __asm volatile( "dsb" ); + __asm volatile( "wfi" ); + __asm volatile( "isb" ); + } + configPOST_SLEEP_PROCESSING( xExpectedIdleTime ); + + /* Stop SysTick. Again, the time the SysTick is stopped for is + accounted for as best it can be, but using the tickless mode will + inevitably result in some tiny drift of the time maintained by the + kernel with respect to calendar time. */ + ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG; + portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT ); + + /* Re-enable interrupts - see comments above the cpsid instruction() + above. */ + __asm volatile( "cpsie i" ); + + if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ) + { + uint32_t ulCalculatedLoadValue; + + /* The tick interrupt has already executed, and the SysTick + count reloaded with ulReloadValue. Reset the + portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick + period. */ + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG ); + + /* Don't allow a tiny value, or values that have somehow + underflowed because the post sleep hook did something + that took too long. */ + if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ) + { + ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ); + } + + portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue; + + /* The tick interrupt handler will already have pended the tick + processing in the kernel. As the pending tick will be + processed as soon as this function exits, the tick value + maintained by the tick is stepped forward by one less than the + time spent waiting. */ + ulCompleteTickPeriods = xExpectedIdleTime - 1UL; + } + else + { + /* Something other than the tick interrupt ended the sleep. + Work out how long the sleep lasted rounded to complete tick + periods (not the ulReload value which accounted for part + ticks). */ + ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG; + + /* How many complete tick periods passed while the processor + was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick; + + /* The reload value is set to whatever fraction of a single tick + period remains. */ + portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements; + } + + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. */ + portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; + portENTER_CRITICAL(); + { + portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; + vTaskStepTick( ulCompleteTickPeriods ); + portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL; + } + portEXIT_CRITICAL(); + } + } + +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +__attribute__(( weak )) void vPortSetupTimerInterrupt( void ) +{ + /* Calculate the constants required to configure the tick interrupt. */ + #if configUSE_TICKLESS_IDLE == 1 + { + ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ); + xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick; + ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ ); + } + #endif /* configUSE_TICKLESS_IDLE */ + + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/portmacro.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/portmacro.h new file mode 100644 index 0000000..d44fc92 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4F/portmacro.h @@ -0,0 +1,284 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* Scheduler utilities. */ +#define portYIELD() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD() +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Tickless idle/low power functionality. */ +#ifndef portSUPPRESS_TICKS_AND_SLEEP + extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime ); + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime ) +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); +} +/*-----------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/port.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/port.c new file mode 100644 index 0000000..63f4191 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/port.c @@ -0,0 +1,819 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM3 port. + *----------------------------------------------------------*/ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "queue.h" +#include "event_groups.h" +#include "mpu_prototypes.h" + +#ifndef __VFP_FP__ + #error This port can only be used when the project options are configured to enable hardware floating point support. +#endif + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Constants required to access and manipulate the NVIC. */ +#define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) ) +#define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) ) +#define portNVIC_SYSPRI2_REG ( * ( ( volatile uint32_t * ) 0xe000ed20 ) ) +#define portNVIC_SYSPRI1_REG ( * ( ( volatile uint32_t * ) 0xe000ed1c ) ) +#define portNVIC_SYS_CTRL_STATE_REG ( * ( ( volatile uint32_t * ) 0xe000ed24 ) ) +#define portNVIC_MEM_FAULT_ENABLE ( 1UL << 16UL ) + +/* Constants required to access and manipulate the MPU. */ +#define portMPU_TYPE_REG ( * ( ( volatile uint32_t * ) 0xe000ed90 ) ) +#define portMPU_REGION_BASE_ADDRESS_REG ( * ( ( volatile uint32_t * ) 0xe000ed9C ) ) +#define portMPU_REGION_ATTRIBUTE_REG ( * ( ( volatile uint32_t * ) 0xe000edA0 ) ) +#define portMPU_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed94 ) ) +#define portEXPECTED_MPU_TYPE_VALUE ( 8UL << 8UL ) /* 8 regions, unified. */ +#define portMPU_ENABLE ( 0x01UL ) +#define portMPU_BACKGROUND_ENABLE ( 1UL << 2UL ) +#define portPRIVILEGED_EXECUTION_START_ADDRESS ( 0UL ) +#define portMPU_REGION_VALID ( 0x10UL ) +#define portMPU_REGION_ENABLE ( 0x01UL ) +#define portPERIPHERALS_START_ADDRESS 0x40000000UL +#define portPERIPHERALS_END_ADDRESS 0x5FFFFFFFUL + +/* Constants required to access and manipulate the SysTick. */ +#define portNVIC_SYSTICK_CLK ( 0x00000004UL ) +#define portNVIC_SYSTICK_INT ( 0x00000002UL ) +#define portNVIC_SYSTICK_ENABLE ( 0x00000001UL ) +#define portNVIC_PENDSV_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL ) +#define portNVIC_SYSTICK_PRI ( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL ) +#define portNVIC_SVC_PRI ( ( ( uint32_t ) configMAX_SYSCALL_INTERRUPT_PRIORITY - 1UL ) << 24UL ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34UL ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000UL ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffdUL ) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED ( 0x03 ) +#define portINITIAL_CONTROL_IF_PRIVILEGED ( 0x02 ) + +/* Constants required to check the validity of an interrupt priority. */ +#define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) +#define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) +#define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) +#define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) +#define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) +#define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) +#define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) +#define portPRIGROUP_SHIFT ( 8UL ) + +/* Offsets in the stack to the parameters when inside the SVC handler. */ +#define portOFFSET_TO_PC ( 6 ) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Each task maintains its own interrupt status in the critical nesting +variable. Note this is not saved as part of the task context as context +switches can only occur when uxCriticalNesting is zero. */ +static UBaseType_t uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION; + +/* + * Configure a number of standard MPU regions that are used by all tasks. + */ +static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; + +/* + * Return the smallest MPU region size that a given number of bytes will fit + * into. The region size is returned as the value that should be programmed + * into the region attribute register for that region. + */ +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) PRIVILEGED_FUNCTION; + +/* + * Checks to see if being called from the context of an unprivileged task, and + * if so raises the privilege level and returns false - otherwise does nothing + * other than return true. + */ +BaseType_t xPortRaisePrivilege( void ) __attribute__(( naked )); + +/* + * Standard FreeRTOS exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; +void xPortSysTickHandler( void ) __attribute__ ((optimize("3"))) PRIVILEGED_FUNCTION; +void vPortSVCHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION; + +/* + * Starts the scheduler by restoring the context of the first task to run. + */ +static void prvRestoreContextOfFirstTask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION; + +/* + * C portion of the SVC handler. The SVC handler is split between an asm entry + * and a C wrapper for simplicity of coding and maintenance. + */ +static void prvSVCHandler( uint32_t *pulRegisters ) __attribute__(( noinline )) PRIVILEGED_FUNCTION; + +/* + * Function to enable the VFP. + */ + static void vPortEnableVFP( void ) __attribute__ (( naked )); + +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if ( configASSERT_DEFINED == 1 ) + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( ( StackType_t ) pxCode ) & portSTART_ADDRESS_MASK; /* PC */ + pxTopOfStack--; + *pxTopOfStack = 0; /* LR */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ + + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + if( xRunPrivileged == pdTRUE ) + { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } + else + { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +void vPortSVCHandler( void ) +{ + /* Assumes psp was in use. */ + __asm volatile + ( + #ifndef USE_PROCESS_STACK /* Code should not be required if a main() is using the process stack. */ + " tst lr, #4 \n" + " ite eq \n" + " mrseq r0, msp \n" + " mrsne r0, psp \n" + #else + " mrs r0, psp \n" + #endif + " b %0 \n" + ::"i"(prvSVCHandler):"r0" + ); +} +/*-----------------------------------------------------------*/ + +static void prvSVCHandler( uint32_t *pulParam ) +{ +uint8_t ucSVCNumber; + + /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and + xPSR. The first argument (r0) is pulParam[ 0 ]. */ + ucSVCNumber = ( ( uint8_t * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ]; + switch( ucSVCNumber ) + { + case portSVC_START_SCHEDULER : portNVIC_SYSPRI1_REG |= portNVIC_SVC_PRI; + prvRestoreContextOfFirstTask(); + break; + + case portSVC_YIELD : portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + /* Barriers are normally not required + but do ensure the code is completely + within the specified behaviour for the + architecture. */ + __asm volatile( "dsb" ); + __asm volatile( "isb" ); + + break; + + case portSVC_RAISE_PRIVILEGE : __asm volatile + ( + " mrs r1, control \n" /* Obtain current control value. */ + " bic r1, #1 \n" /* Set privilege bit. */ + " msr control, r1 \n" /* Write back new control value. */ + :::"r1" + ); + break; + + default : /* Unknown SVC call. */ + break; + } +} +/*-----------------------------------------------------------*/ + +static void prvRestoreContextOfFirstTask( void ) +{ + __asm volatile + ( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " mov r0, #0 \n" + " msr basepri, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +BaseType_t xPortStartScheduler( void ) +{ + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. See + http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); + + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ + + /* Make PendSV and SysTick the same priority as the kernel, and the SVC + handler higher priority so it can be used to exit a critical section (where + lower priorities are masked). */ + portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; + portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; + + /* Configure the regions in the MPU that are common to all tasks. */ + prvSetupMPU(); + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + prvSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + uxCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + __asm volatile( + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ + " ldr r0, [r0] \n" + " ldr r0, [r0] \n" + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ + " cpsie i \n" /* Globally enable interrupts. */ + " cpsie f \n" + " dsb \n" + " isb \n" + " svc %0 \n" /* System call to start first task. */ + " nop \n" + :: "i" (portSVC_START_SCHEDULER) ); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* Not implemented in ports where there is nothing to return to. + Artificially force an assert. */ + configASSERT( uxCriticalNesting == 1000UL ); +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + portDISABLE_INTERRUPTS(); + uxCriticalNesting++; + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + configASSERT( uxCriticalNesting ); + uxCriticalNesting--; + if( uxCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +void xPortPendSVHandler( void ) +{ + /* This is a naked function. */ + + __asm volatile + ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + " \n" + " mrs r1, control \n" + " stmdb r0!, {r1, r4-r11, r14} \n" /* Save the remaining registers. */ + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " \n" + " stmdb sp!, {r3} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " dsb \n" + " isb \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3} \n" + " \n" /* Restore the context. */ + " ldr r1, [r3] \n" + " ldr r0, [r1] \n" /* The first item in the TCB is the task top of stack. */ + " add r1, r1, #4 \n" /* Move onto the second item in the TCB... */ + " ldr r2, =0xe000ed9c \n" /* Region Base Address register. */ + " ldmia r1!, {r4-r11} \n" /* Read 4 sets of MPU registers. */ + " stmia r2!, {r4-r11} \n" /* Write 4 sets of MPU registers. */ + " ldmia r0!, {r3-r11, r14} \n" /* Pop the registers that are not automatically saved on exception entry. */ + " msr control, r3 \n" + " \n" + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" + " \n" + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 4 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( void ) +{ +uint32_t ulDummy; + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Increment the RTOS tick. */ + if( xTaskIncrementTick() != pdFALSE ) + { + /* Pend a context switch. */ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +static void prvSetupTimerInterrupt( void ) +{ + /* Configure SysTick to interrupt at the requested rate. */ + portNVIC_SYSTICK_LOAD_REG = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vPortEnableVFP( void ) +{ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +} +/*-----------------------------------------------------------*/ + +static void prvSetupMPU( void ) +{ +extern uint32_t __privileged_functions_end__[]; +extern uint32_t __FLASH_segment_start__[]; +extern uint32_t __FLASH_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; + + /* Check the expected MPU is present. */ + if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) + { + /* First setup the entire flash for unprivileged read only access. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portUNPRIVILEGED_FLASH_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __FLASH_segment_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the first 16K for privileged only access (even though less + than 10K is actually being used). This is where the kernel code is + placed. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __FLASH_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_FLASH_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_ONLY ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_functions_end__ - ( uint32_t ) __FLASH_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Setup the privileged data RAM region. This is where the kernel data + is placed. */ + portMPU_REGION_BASE_ADDRESS_REG = ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portPRIVILEGED_RAM_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* By default allow everything to access the general peripherals. The + system peripherals and registers are protected. */ + portMPU_REGION_BASE_ADDRESS_REG = ( portPERIPHERALS_START_ADDRESS ) | + ( portMPU_REGION_VALID ) | + ( portGENERAL_PERIPHERALS_REGION ); + + portMPU_REGION_ATTRIBUTE_REG = ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) | + ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) | + ( portMPU_REGION_ENABLE ); + + /* Enable the memory fault exception. */ + portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE; + + /* Enable the MPU with the background region configured. */ + portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE ); + } +} +/*-----------------------------------------------------------*/ + +static uint32_t prvGetMPURegionSizeSetting( uint32_t ulActualSizeInBytes ) +{ +uint32_t ulRegionSize, ulReturnValue = 4; + + /* 32 is the smallest region size, 31 is the largest valid value for + ulReturnValue. */ + for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) ) + { + if( ulActualSizeInBytes <= ulRegionSize ) + { + break; + } + else + { + ulReturnValue++; + } + } + + /* Shift the code by one before returning so it can be written directly + into the the correct bit position of the attribute register. */ + return ( ulReturnValue << 1UL ); +} +/*-----------------------------------------------------------*/ + +BaseType_t xPortRaisePrivilege( void ) +{ + __asm volatile + ( + " mrs r0, control \n" + " tst r0, #1 \n" /* Is the task running privileged? */ + " itte ne \n" + " movne r0, #0 \n" /* CONTROL[0]!=0, return false. */ + " svcne %0 \n" /* Switch to privileged. */ + " moveq r0, #1 \n" /* CONTROL[0]==0, return true. */ + " bx lr \n" + :: "i" (portSVC_RAISE_PRIVILEGE) : "r0" + ); + + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) +{ +extern uint32_t __SRAM_segment_start__[]; +extern uint32_t __SRAM_segment_end__[]; +extern uint32_t __privileged_data_start__[]; +extern uint32_t __privileged_data_end__[]; +int32_t lIndex; +uint32_t ul; + + if( xRegions == NULL ) + { + /* No MPU regions are specified so allow access to all RAM. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) __SRAM_segment_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( prvGetMPURegionSizeSetting( ( uint32_t ) __SRAM_segment_end__ - ( uint32_t ) __SRAM_segment_start__ ) ) | + ( portMPU_REGION_ENABLE ); + + /* Re-instate the privileged only RAM region as xRegion[ 0 ] will have + just removed the privileged only parameters. */ + xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress = + ( ( uint32_t ) __privileged_data_start__ ) | /* Base address. */ + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + 1 ); + + xMPUSettings->xRegion[ 1 ].ulRegionAttribute = + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + prvGetMPURegionSizeSetting( ( uint32_t ) __privileged_data_end__ - ( uint32_t ) __privileged_data_start__ ) | + ( portMPU_REGION_ENABLE ); + + /* Invalidate all other regions. */ + for( ul = 2; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + } + else + { + /* This function is called automatically when the task is created - in + which case the stack region parameters will be valid. At all other + times the stack parameters will not be valid and it is assumed that the + stack region has already been configured. */ + if( ulStackDepth > 0 ) + { + /* Define the region that allows access to the stack. */ + xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress = + ( ( uint32_t ) pxBottomOfStack ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION ); /* Region number. */ + + xMPUSettings->xRegion[ 0 ].ulRegionAttribute = + ( portMPU_REGION_READ_WRITE ) | /* Read and write. */ + ( prvGetMPURegionSizeSetting( ulStackDepth * ( uint32_t ) sizeof( StackType_t ) ) ) | + ( portMPU_REGION_CACHEABLE_BUFFERABLE ) | + ( portMPU_REGION_ENABLE ); + } + + lIndex = 0; + + for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ ) + { + if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL ) + { + /* Translate the generic region definition contained in + xRegions into the CM3 specific MPU settings that are then + stored in xMPUSettings. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = + ( ( uint32_t ) xRegions[ lIndex ].pvBaseAddress ) | + ( portMPU_REGION_VALID ) | + ( portSTACK_REGION + ul ); /* Region number. */ + + xMPUSettings->xRegion[ ul ].ulRegionAttribute = + ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) | + ( xRegions[ lIndex ].ulParameters ) | + ( portMPU_REGION_ENABLE ); + } + else + { + /* Invalidate the region. */ + xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID; + xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL; + } + + lIndex++; + } + } +} +/*-----------------------------------------------------------*/ + +#if( configASSERT_DEFINED == 1 ) + + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ +/*-----------------------------------------------------------*/ + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/portmacro.h b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/portmacro.h new file mode 100644 index 0000000..15ca256 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/GCC/ARM_CM4_MPU/portmacro.h @@ -0,0 +1,332 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL + + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif +/*-----------------------------------------------------------*/ + +/* MPU specific constants. */ +#define portUSING_MPU_WRAPPERS 1 +#define portPRIVILEGE_BIT ( 0x80000000UL ) + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + +/* SVC numbers for various services. */ +#define portSVC_START_SCHEDULER 0 +#define portSVC_YIELD 1 +#define portSVC_RAISE_PRIVILEGE 2 + +/* Scheduler utilities. */ + +#define portYIELD() __asm volatile ( " SVC %0 \n" :: "i" (portSVC_YIELD) ) +#define portYIELD_WITHIN_API() \ +{ \ + /* Set a PendSV to request a context switch. */ \ + portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ + \ + /* Barriers are normally not required but do ensure the code is completely \ + within the specified behaviour for the architecture. */ \ + __asm volatile( "dsb" ); \ + __asm volatile( "isb" ); \ +} + +#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) ) +#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET +#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) +/*-----------------------------------------------------------*/ + +/* Critical section management. */ +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); +#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) +#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() +#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() + +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. These are +not necessary for to use this port. They are defined so the common demo files +(which build with all the ports) will build. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimisations. */ +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#endif + +#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + + /* Generic helper function. */ + __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +#ifdef configASSERT + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#endif + +/* portNOP() is not required by this port. */ +#define portNOP() + +#define portINLINE __inline + +#ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) +#endif + +/* Set the privilege level to user mode if xRunningPrivileged is false. */ +portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) +{ + if( xRunningPrivileged != pdTRUE ) + { + __asm volatile ( " mrs r0, control \n" \ + " orr r0, #1 \n" \ + " msr control, r0 \n" \ + :::"r0" ); + } +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) +{ +uint32_t ulCurrentInterrupt; +BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortRaiseBASEPRI( void ) +{ +uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); +} + +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) +{ +uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, %1 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; +} +/*-----------------------------------------------------------*/ + +portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) +{ + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); +} +/*-----------------------------------------------------------*/ + + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_5.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_5.c new file mode 100644 index 0000000..ce94c50 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/portable/MemMang/heap_5.c @@ -0,0 +1,651 @@ +/* + FreeRTOS V8.1.2 - Copyright (C) 2014 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that has become a de facto standard. * + * * + * Help yourself get started quickly and support the FreeRTOS * + * project by purchasing a FreeRTOS tutorial book, reference * + * manual, or both from: http://www.FreeRTOS.org/Documentation * + * * + * Thank you! * + * * + *************************************************************************** + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available from the following + link: http://www.freertos.org/a00114.html + + 1 tab == 4 spaces! + + *************************************************************************** + * * + * Having a problem? Start by reading the FAQ "My application does * + * not run, what could be wrong?" * + * * + * http://www.FreeRTOS.org/FAQHelp.html * + * * + *************************************************************************** + + http://www.FreeRTOS.org - Documentation, books, training, latest versions, + license and Real Time Engineers Ltd. contact details. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High + Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() that allows the heap to be defined + * across multiple non-contigous blocks and combines (coalescences) adjacent + * memory blocks as they are freed. + * + * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative + * implementations, and the memory management pages of http://www.FreeRTOS.org + * for more information. + * + * Usage notes: + * + * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). + * pvPortMalloc() will be called if any task objects (tasks, queues, event + * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be + * called before any other objects are defined. + * + * vPortDefineHeapRegions() takes a single parameter. The parameter is an array + * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as + * + * typedef struct HeapRegion + * { + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * } HeapRegion_t; + * + * The array is terminated using a NULL zero sized region definition, and the + * memory regions defined in the array ***must*** appear in address order from + * low address to high address. So the following is a valid example of how + * to use the function. + * + * HeapRegion_t xHeapRegions[] = + * { + * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 + * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 + * { NULL, 0 } << Terminates the array. + * }; + * + * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). + * + * Note 0x80000000 is the lower address so appears in the array first. + * + */ +#include +#include +#include "diag.h" +#include "platform_autoconf.h" +#include "hal_misc.h" + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + all the API functions to use the MPU wrappers. That should only be done when + task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( uxHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Define the linked list structure. This is used to link free blocks in order + of their memory address. */ +typedef struct A_BLOCK_LINK { + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory + block must by correctly byte aligned. */ +static const uint32_t uxHeapStructSize = ((sizeof(BlockLink_t) + + ( portBYTE_ALIGNMENT - 1)) & ~portBYTE_ALIGNMENT_MASK); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about + fragmentation. */ +static size_t xFreeBytesRemaining = 0; +static size_t xMinimumEverFreeBytesRemaining = 0; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize + member of an BlockLink_t structure is set then the block belongs to the + application. When the bit is free the block is still part of the free heap + space. */ +//static size_t xBlockAllocatedBit = 0; +/* Work out the position of the top bit in a size_t variable. */ +#define xBlockAllocatedBit (( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 )) + +/* Realtek test code start */ +//TODO: remove section when combine BD and BF +#if (defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)) +#include "section_config.h" +SRAM_HEAP_SECTION +#endif +unsigned char ucHeap[configTOTAL_HEAP_SIZE]; + +//extern void * __sdram_bss_end__; +//extern void * __ram_heap1_start__, __ram_heap1_end__, __ram_heap2_start__, __sdram_data_start__; + +extern HeapRegion_t xHeapRegions[]; + +#if 0 +#if defined(CONFIG_PLATFORM_8195A) +HeapRegion_t xHeapRegions[] = +{ + { (uint8_t*)0x10003000, 0x10006000 - 0x10003000}, // __ram_heap1_start__, __ram_heap1_end__ - __ram_heap1_start__ + { ucHeap, sizeof(ucHeap)}, // Defines a block from ucHeap +#ifdef CONFIG_SDR_EN + { (uint8_t*)&__sdram_bss_end__, 0x80000}, +#endif + { NULL, 0} // Terminates the array. +}; +#elif (defined CONFIG_PLATFORM_8711B) +HeapRegion_t xHeapRegions[] = +{ + { ucHeap, sizeof(ucHeap)}, // Defines a block from ucHeap + { NULL, 0} // Terminates the array. +}; +#else +#error NOT SUPPORT CHIP +#endif +#endif + +/*-----------------------------------------------------------*/ +/* + Dump xBlock list + */ +void dump_mem_block_list(void) { + if (pxEnd == NULL) + vPortDefineHeapRegions(xHeapRegions); +#if CONFIG_DEBUG_LOG > 1 +// if(pxEnd == NULL) vPortDefineHeapRegions( xHeapRegions ); // test code start + BlockLink_t *pxBlock = &xStart; + int count = 0; + DBG_8195A("RAM Free Heap Memory List:\n"); + for (pxBlock = pxBlock->pxNextFreeBlock; pxBlock->pxNextFreeBlock != NULL; + pxBlock = pxBlock->pxNextFreeBlock) { + DBG_8195A(" [%d]=%p, %d\n", ++count, pxBlock, pxBlock->xBlockSize); + } +#endif +} + +void *pvPortMalloc(size_t xWantedSize) { + BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; + void *pvReturn = NULL; + + /* Realtek test code start */ + if (pxEnd == NULL) + vPortDefineHeapRegions(xHeapRegions); + /* Realtek test code end */ + + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); + + vTaskSuspendAll(); + { + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if ((xWantedSize & xBlockAllocatedBit) == 0) { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if (xWantedSize > 0) { + xWantedSize += uxHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if ((xWantedSize & portBYTE_ALIGNMENT_MASK) != 0x00) { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT + - (xWantedSize & portBYTE_ALIGNMENT_MASK)); + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } + + if ((xWantedSize > 0) && (xWantedSize <= xFreeBytesRemaining)) { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while ((pxBlock->xBlockSize < xWantedSize) + && (pxBlock->pxNextFreeBlock != NULL)) { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if (pxBlock != pxEnd) { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = + (void *) (((uint8_t *) pxPreviousBlock->pxNextFreeBlock) + + uxHeapStructSize); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if ((pxBlock->xBlockSize - xWantedSize) + > heapMINIMUM_BLOCK_SIZE) { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = (void *) (((uint8_t *) pxBlock) + + xWantedSize); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize + - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList((pxNewBlockLink)); + } else { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if (xFreeBytesRemaining < xMinimumEverFreeBytesRemaining) { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } else { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } traceMALLOC( pvReturn, xWantedSize ); + } + (void) xTaskResumeAll(); + if (pvReturn == NULL) { + DBG_RAM_HEAP_WARN("ram_alloc(%d): freeSpace(%d)!\n", xWantedSize, + xFreeBytesRemaining); + } else { +// DBG_RAM_HEAP_INFO("ram_alloc:%p[%d]\n", pvReturn , xWantedSize); + } +#if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +#endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void __vPortFree(void *pv) { + uint8_t *puc = (uint8_t *) pv; + BlockLink_t *pxLink; + + if (pv != NULL) { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= uxHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = (void *) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if ((pxLink->xBlockSize & xBlockAllocatedBit) != 0) { + if (pxLink->pxNextFreeBlock == NULL) { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList(((BlockLink_t *) pxLink)); + } + (void) xTaskResumeAll(); + } else { + mtCOVERAGE_TEST_MARKER(); + } + } else { + mtCOVERAGE_TEST_MARKER(); + } +// DBG_RAM_HEAP_INFO("ram_free:%p[%d]\n", pv , pxLink->xBlockSize); + } +} + +/*-----------------------------------------------------------*/ +/* Add by Alfa 2015/02/04 -----------------------------------*/ +static void (*ext_free)(void *p) = NULL; +//static +uint32_t ext_upper = 0; +//static +uint32_t ext_lower = 0; +void vPortSetExtFree(void (*free)(void *p), uint32_t upper, uint32_t lower) { + ext_free = free; + ext_upper = upper; + ext_lower = lower; +} + +void vPortFree(void *pv) { + if (((uint32_t) pv >= ext_lower) && ((uint32_t) pv < ext_upper)) { + // use external free function + if (ext_free) + ext_free(pv); + } else + __vPortFree(pv); +} + +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize(void) { + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize(void) { + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList(BlockLink_t *pxBlockToInsert) { + BlockLink_t *pxIterator; + uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for (pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; + pxIterator = pxIterator->pxNextFreeBlock) { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = (uint8_t *) pxIterator; + if ((puc + pxIterator->xBlockSize) == (uint8_t *) pxBlockToInsert) { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } else { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = (uint8_t *) pxBlockToInsert; + if ((puc + pxBlockToInsert->xBlockSize) + == (uint8_t *) pxIterator->pxNextFreeBlock) { + if (pxIterator->pxNextFreeBlock != pxEnd) { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += + pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = + pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } else { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } else { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if (pxIterator != pxBlockToInsert) { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } else { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ +static void vPortDefineHeapRegions(const HeapRegion_t * const pxHeapRegions) { + BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; + uint8_t *pucAlignedHeap; + size_t xTotalRegionSize, xTotalHeapSize = 0; + BaseType_t xDefinedRegions = 0; + uint32_t ulAddress; + const HeapRegion_t *pxHeapRegion; + +#if defined(CONFIG_PLATFORM_8195A) + /* + xHeapRegions[0].pucStartAddress = (uint8_t*)&__ram_heap1_start__; + xHeapRegions[0].xSizeInBytes = (u32)&__ram_heap1_end__ - (u32)xHeapRegions[0].pucStartAddress; + xHeapRegions[1].pucStartAddress = &ucHeap; // (uint8_t*)&__ram_heap2_start__; + xHeapRegions[1].xSizeInBytes = (u32)0x10070000 - (u32)xHeapRegions[1].pucStartAddress; + xHeapRegions[2].pucStartAddress = (uint8_t*)&__sdram_data_start__; + xHeapRegions[2].xSizeInBytes = (u32)0x30200000 - (u32)xHeapRegions[2].pucStartAddress; + */ +#endif + /* Can only call once! */ + configASSERT( pxEnd == NULL ); + + pxHeapRegion = &(pxHeapRegions[xDefinedRegions]); + + uint8 chip_id = HalGetChipId(); + while (pxHeapRegion->xSizeInBytes > 0) { + if (pxHeapRegion->pucStartAddress + > 0x20000000 && chip_id >= CHIP_ID_8711AN && chip_id <= CHIP_ID_8711AF) { +// pxHeapRegion->pucStartAddress = 0; +// pxHeapRegion->xSizeInBytes = 0; +// DBG_8195A("ChipID: %p !\n", chip_id); + } else { +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("Init Heap Region: %p[%d]\n", pxHeapRegion->pucStartAddress, pxHeapRegion->xSizeInBytes); +#endif +#if CONFIG_DEBUG_LOG > 4 + rtl_memset(pxHeapRegion->pucStartAddress, 0, pxHeapRegion->xSizeInBytes); +#endif + xTotalRegionSize = pxHeapRegion->xSizeInBytes; + /* Ensure the heap region starts on a correctly aligned boundary. */ + ulAddress = (uint32_t) pxHeapRegion->pucStartAddress; + if ((ulAddress & portBYTE_ALIGNMENT_MASK) != 0) { + ulAddress += ( portBYTE_ALIGNMENT - 1); + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= ulAddress + - (uint32_t) pxHeapRegion->pucStartAddress; + } + + pucAlignedHeap = (uint8_t *) ulAddress; + + /* Set xStart if it has not already been set. */ + if (xDefinedRegions == 0) { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = (BlockLink_t *) pucAlignedHeap; + xStart.xBlockSize = (size_t) 0; + } else { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); + + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( ulAddress > ( uint32_t ) pxEnd ); + } + + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; + + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + ulAddress = ((uint32_t) pucAlignedHeap) + xTotalRegionSize; + ulAddress -= uxHeapStructSize; + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = (BlockLink_t *) ulAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = (BlockLink_t *) pucAlignedHeap; + pxFirstFreeBlockInRegion->xBlockSize = ulAddress + - (uint32_t) pxFirstFreeBlockInRegion; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if (pxPreviousFreeBlock != NULL) { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } + + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + } + /* Move onto the next HeapRegion_t structure. */ + xDefinedRegions++; + pxHeapRegion = &(pxHeapRegions[xDefinedRegions]); + } + + xMinimumEverFreeBytesRemaining = xTotalHeapSize; + xFreeBytesRemaining = xTotalHeapSize; + + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); + +} + +void* pvPortReAlloc(void *pv, size_t xWantedSize) { + BlockLink_t *pxLink; + + if (((uint32_t) pv >= ext_lower) && ((uint32_t) pv < ext_upper)) { + if (ext_free) + ext_free(pv); + pv = NULL; + } + + unsigned char *puc = (unsigned char *) pv; + + if (pv) { + if (!xWantedSize) { + vPortFree(pv); + return NULL; + } + + void *newArea = pvPortMalloc(xWantedSize); + if (newArea) { + /* The memory being freed will have an xBlockLink structure immediately + before it. */ + puc -= uxHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = (void *) puc; + + int oldSize = (pxLink->xBlockSize & ~xBlockAllocatedBit) - uxHeapStructSize; + int copySize = (oldSize < xWantedSize) ? oldSize : xWantedSize; + rtl_memcpy(newArea, pv, copySize); + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + xFreeBytesRemaining += pxLink->xBlockSize; + prvInsertBlockIntoFreeList(((BlockLink_t *) pxLink)); + } + xTaskResumeAll(); + return newArea; + } + } else if (xWantedSize) + return pvPortMalloc(xWantedSize); + else + return NULL; + + return NULL; +} + +extern _LONG_CALL_ROM_ void *_memset(void *s, int c, SIZE_T n); + +void *pvPortZalloc(size_t xWantedSize) { + void * prt = pvPortMalloc(xWantedSize); + if (prt) + _memset(prt, 0, xWantedSize); + return prt; +} + +/* + #ifdef ARDUINO_SDK + int vPortAddHeapRegion(uint8_t *addr, size_t size) + { + return 0; + } + #endif + */ diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/queue.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/queue.c new file mode 100644 index 0000000..3659ecd --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/queue.c @@ -0,0 +1,2567 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( int8_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +Queue_t structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +pcTail pointer actually points to the mutex holder (if any). Map alternative +names to the pcHead and pcTail structure members to ensure the readability of +the code is maintained despite this dual use of two structure members. An +alternative implementation would be to use a union, but use of a union is +against the coding standard (although an exception to the standard has been +permitted where the dual use also significantly changes the type of the +structure member). */ +#define pxMutexHolder pcTail +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. See the following link for the + * rationale: http://www.freertos.org/Embedded-RTOS-Queues.html + */ +typedef struct QueueDefinition +{ + int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ + int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */ + { + int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ + UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ + } u; + + List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ + UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t +name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char *pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + + /* The old xQueueRegistryItem name is maintained above then typedefed to the + new xQueueRegistryItem name below to enable the use of older kernel aware + debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + + /* The queue registry is simply an array of QueueRegistryItem_t structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) +{ +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize ); + pxQueue->cRxLock = queueUNLOCKED; + pxQueue->cTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + /* The StaticQueue_t structure and the queue storage area must be + supplied. */ + configASSERT( pxStaticQueue != NULL ); + + /* A queue storage area should be provided if the item size is not 0, and + should not be provided if the item size is 0. */ + configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); + configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticQueue_t or StaticSemaphore_t equals the size of + the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + configASSERT( xSize == sizeof( Queue_t ) ); + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + The address of a statically allocated storage area was also passed in + but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewQueue != NULL ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + note this queue was allocated statically in case the queue is + later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + size_t xQueueSizeInBytes; + uint8_t *pucQueueStorage; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* There is not going to be a queue storage area. */ + xQueueSizeInBytes = ( size_t ) 0; + } + else + { + /* Allocate enough space to hold the maximum number of items that + can be in the queue at any time. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + storage area. */ + pucQueueStorage = ( ( uint8_t * ) pxNewQueue ) + sizeof( Queue_t ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + note this task was created dynamically in case it is later + deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) +{ + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* No RAM was allocated for the queue storage area, but PC head cannot + be set to NULL because NULL is used as a key to say the queue is used as + a mutex. Therefore just set pcHead to point to the queue as a benign + value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; + } + else + { + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; + } + + /* Initialise the queue members as described where the queue type is + defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static void prvInitialiseMutex( Queue_t *pxNewQueue ) + { + if( pxNewQueue != NULL ) + { + /* The queue create function will set all the queue structure members + correctly for a generic queue, but this function is creating a + mutex. Overwrite those members that need to be set differently - + in particular the information required for priority inheritance. */ + pxNewQueue->pxMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* In case this is a recursive mutex. */ + pxNewQueue->u.uxRecursiveCallCount = 0; + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + pxNewQueue = ( Queue_t * ) xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( pxNewQueue ); + + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + Queue_t *pxNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + pxNewQueue = ( Queue_t * ) xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( pxNewQueue ); + + return pxNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + void* xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + void *pxReturn; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( void * ) ( ( Queue_t * ) xSemaphore )->pxMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then pxMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Not a redundant cast as TaskHandle_t is a typedef. */ + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if pxMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.uxRecursiveCallCount )--; + + /* Has the recursive call count unwound to 0? */ + if( pxMutex->u.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->pxMutexHolder == ( void * ) xTaskGetCurrentTaskHandle() ) /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */ + { + ( pxMutex->u.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueGenericReceive( pxMutex, NULL, xTicksToWait, pdFALSE ); + + /* pdPASS will only be returned if the mutex was successfully + obtained. The calling task may have entered the Blocked state + before reaching here. */ + if( xReturn != pdFAIL ) + { + ( pxMutex->u.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) +{ +BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be the + highest priority task wanting to access the queue. If the head item + in the queue is to be overwritten then it does not matter if the + queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes + and the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + in the queue. Also don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a + semaphore or mutex. That means prvCopyDataToQueue() cannot result + in a task disinheriting a priority and prvCopyDataToQueue() can be + called here even though the disinherit function does not check if + the scheduler is suspended before accessing the ready lists. */ + ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* Similar to xQueueGenericSendFromISR() but used with semaphores where the + item size is 0. Don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + + configASSERT( pxQueue ); + + /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() + if the item size is not 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Normally a mutex would not be given from an interrupt, especially if + there is a mutex holder, as priority inheritance makes no sense for an + interrupts, only tasks. */ + configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->pxMutexHolder != NULL ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* When the queue is used to implement a semaphore no data is ever + moved through the queue but it is still valid to see if the queue 'has + space'. */ + if( uxMessagesWaiting < pxQueue->uxLength ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* A task can only have an inherited priority if it is a mutex + holder - and if there is a mutex holder then the mutex cannot be + given from an ISR. As this is the ISR version of the function it + can be assumed there is no mutex holder and no need to determine if + priority disinheritance is needed. Simply increase the count of + messages (semaphores) available. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1; + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The semaphore is a member of a queue set, and + posting to the queue set caused a higher priority + task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait, const BaseType_t xJustPeeking ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + /* This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position in case the queue is only being + peeked. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + + if( xJustPeeking == pdFALSE ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Actually removing data, not just peeking. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1; + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read + pointer. */ + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + vTaskPriorityInherit( ( void * ) pxQueue->pxMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Cannot block in an ISR, so check there is data available. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + const int8_t cRxLock = pxQueue->cRxLock; + + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1; + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( cRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t *pxQueue; + + pxQueue = ( Queue_t * ) xQueue; + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ +Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + configASSERT( pxQueue ); + traceQUEUE_DELETE( pxQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + again. */ + vPortFree( pxQueue ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else + { + /* The queue must have been statically allocated, so is not going to be + deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) +{ +BaseType_t xReturn = pdFALSE; +UBaseType_t uxMessagesWaiting; + + /* This function is called from a critical section. */ + + uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder ); + pxQueue->pxMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; + if( pxQueue->pcWriteTo >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + pxQueue->u.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.pcReadFrom = ( pxQueue->pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --uxMessagesWaiting; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + int8_t cTxLock = pxQueue->cTxLock; + + /* See if data was added to the queue while it was locked. */ + while( cTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get + added to the pending ready list as the scheduler is still + suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that + a context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --cTxLock; + } + + pxQueue->cTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + int8_t cRxLock = pxQueue->cRxLock; + + while( cRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --cRxLock; + } + else + { + break; + } + } + + pxQueue->cRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; + + configASSERT( xQueue ); + if( ( ( Queue_t * ) xQueue )->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; + + configASSERT( xQueue ); + if( ( ( Queue_t * ) xQueue )->uxMessagesWaiting == ( ( Queue_t * ) xQueue )->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) + { + pxQueue->u.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char *pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + const char *pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + /* Note there is nothing here to protect against another task adding or + removing entries from the registry while it is being searched. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + pcReturn = xQueueRegistry[ ux ].pcQueueName; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return pcReturn; + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + + /* Set the handle to NULL to ensure the same queue handle cannot + appear in the registry twice if it is added, removed, then + added again. */ + xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + Queue_t * const pxQueue = ( Queue_t * ) xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueGenericReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait, pdFALSE ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + const int8_t cTxLock = pxQueueSetContainer->cTxLock; + + traceQUEUE_SEND( pxQueueSetContainer ); + + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + + if( cTxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxQueueSetContainer->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + + + + + + + + + + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/tasks.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/tasks.c new file mode 100644 index 0000000..7f21f6a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/tasks.c @@ -0,0 +1,4932 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "StackMacros.h" + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + +/* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting +functions but without including stdio.h here. */ +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* Values that can be assigned to the ucNotifyState member of the TCB. */ +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using +dynamically allocated RAM, in which case when any task is deleted it is known +that both the task's stack and TCB need to be freed. Sometimes the +FreeRTOSConfig.h settings only allow a task to be created using statically +allocated RAM, in which case when any task is deleted it is known that neither +the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h +settings allow a task to be created using either statically or dynamically +allocated RAM, in which case a member of the TCB is used to record whether the +stack and/or TCB were allocated statically or dynamically, so when a task is +deleted the RAM that was allocated dynamically is freed again and no attempt is +made to free the RAM that was allocated statically. +tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a +task to be created using either statically or dynamically allocated RAM. Note +that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with +a statically allocated stack and a dynamically allocated TCB. */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) ) +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/* + * Some kernel aware debuggers require the data the debugger needs access to be + * global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + List_t *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +/*-----------------------------------------------------------*/ + +/* + * Several functions take an TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? ( TCB_t * ) pxCurrentTCB : ( TCB_t * ) ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority +of the task to which it belongs (coded to allow it to be held in reverse +priority order). However, it is occasionally borrowed for other purposes. It +is important its value is not updated due to a task priority change while it is +being used for another purpose. The following bit definition is used to inform +the scheduler that the value should not be changed - in which case it is the +responsibility of whichever module is using the value to ensure it gets set back +to its original value when it is released. */ +#if( configUSE_16_BIT_TICKS == 1 ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#else + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock +{ + volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t *pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( portSTACK_GROWTH > 0 ) + StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue; + volatile uint8_t ucNotifyState; + #endif + + /* See the comments above the definition of + tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name +below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. --------------------*/ +PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ +PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ +PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ +PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ + +#if( INCLUDE_vTaskDelete == 1 ) + + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ + PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) + + PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ + +#endif + +/* Other file private variables. --------------------------------*/ +PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) 0U; +PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; +PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +/* Context switches are held pending while the scheduler is suspended. Also, +interrupts must not manipulate the xStateListItem of a TCB, or any of the +lists the xStateListItem can be referenced from, if the scheduler is suspended. +If an interrupt needs to unblock a task while the scheduler is suspended then it +moves the task's event list item into the xPendingReadyList, ready for the +kernel to move the task from the pending ready list into the real ready list +when the scheduler is unsuspended. The pending ready list itself can only be +accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ + +#endif + +/*lint +e956 */ + +/*-----------------------------------------------------------*/ + +/* Callback function prototypes. --------------------------*/ +#if( configCHECK_FOR_STACK_OVERFLOW > 0 ) + extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); +#endif + +#if( configUSE_TICK_HOOK > 0 ) + extern void vApplicationTickHook( void ); +#endif + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); +#endif + +/* File private functions. --------------------------------*/ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +#if ( INCLUDE_vTaskSuspend == 1 ) + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; +#endif /* INCLUDE_vTaskSuspend */ + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Searches pxList for a task with name pcNameToQuery - returning a handle to + * the task if it is found, or NULL if the task is not found. + */ +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ); + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + /* + * Helper function used to pad task names with spaces when printing out + * human readable tables of task information. + */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB +#if( portUSING_MPU_WRAPPERS == 1 ) + , const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#else + ) +#endif + + PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + TCB_t *pxNewTCB; + TaskHandle_t xReturn; + + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) + { + /* The memory used for the task's TCB and stack are passed into this + function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB +#if( portUSING_MPU_WRAPPERS == 1 ) + , NULL +#endif + ); + prvAddNewTaskToReadyList( pxNewTCB ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( portUSING_MPU_WRAPPERS == 1 ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + /* Tasks can be created statically or dynamically, so note + this task had a statically allocated stack in case it is + later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) +#ifdef CONFIG_USE_TCM_HEAP + BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + StackType_t * const puxStackBuffer, + const MemoryRegion_t * const xRegions ) //lint !e971 Unqualified char types are allowed for strings and single characters only. + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t *pxStack = puxStackBuffer; +#if configUSE_STACK_TCM_HEAP + if(pxStack == NULL +#if 0 // configUSE_STACK_TCM_HEAP > 1 + && uxPriority >= configUSE_STACK_TCM_HEAP +#endif + ) + + pxStack = ( StackType_t * ) tcm_heap_malloc((( size_t ) usStackDepth) * sizeof(StackType_t)); + if(pxStack == NULL) pxStack = ( StackType_t * ) pvPortMalloc((( size_t ) usStackDepth) * sizeof(StackType_t)); +#else + /* Allocate space for the stack used by the task being created. */ + pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ +#endif + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB +#if( portUSING_MPU_WRAPPERS == 1 ) + , xRegions ); +#else + ); + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; +#endif + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } +#else // CONFIG_USE_TCM_HEAP + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint16_t usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t *pxStack; + + /* Allocate space for the stack used by the task being created. */ + pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e961 MISRA exception as the casts are only redundant for some paths. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB +#if( portUSING_MPU_WRAPPERS == 1 ) + , NULL +#endif + ); + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } +#endif // CONFIG_USE_TCM_HEAP +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB +#if( portUSING_MPU_WRAPPERS == 1 ) + , const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#else + ) +#endif +{ +StackType_t *pxTopOfStack; +UBaseType_t x; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) ) */ + + /* Calculate the top of stack address. This depends on whether the stack + grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as required + by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + pxNewTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxNewTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxNewTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxNewTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ +// ( void ) xRegions; + } + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + { + for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) + { + pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + } + } + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + pxNewTCB->ulNotifiedValue = 0; + pxNewTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + } + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + pxNewTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portUSING_MPU_WRAPPERS */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( ( void * ) pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) +{ + /* Ensure interrupts don't access the task lists while the lists are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Increment the uxTaskNumber also so kernel aware debuggers can + detect that the task lists need re-generating. This is done before + portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will + not return. */ + uxTaskNumber++; + + if( pxTCB == pxCurrentTCB ) + { + /* A task is deleting itself. This cannot complete within the + task itself, as a context switch to another task is required. + Place the task in the termination list. The idle task will + check the termination list and free up any memory allocated by + the scheduler for the TCB and stack of the deleted task. */ + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxDeletedTasksWaitingCleanUp; + + /* The pre-delete hook is primarily for the Windows simulator, + in which Windows specific clean up operations are performed, + after which it is not possible to yield away from this task - + hence xYieldPending is used to latch that a context switch is + required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + } + else + { + --uxCurrentNumberOfTasks; + prvDeleteTCB( pxTCB ); + + /* Reset the next expected unblock time in case it referred to + the task that has just been deleted. */ + prvResetNextTaskUnblockTime(); + } + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if it is the currently running task that has just + been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL( xTimeToWake ); + + /* prvAddCurrentTaskToDelayedList() needs the block time, not + the time to wake, so subtract the current tick count. */ + prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + BaseType_t xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == 0 ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t *pxStateList; + const TCB_t * const pxTCB = ( TCB_t * ) xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = ( List_t * ) listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedTaskList ) || ( pxStateList == pxOverflowDelayedTaskList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. Is it genuinely suspended or is it block + indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + eReturn = eSuspended; + } + else + { + eReturn = eBlocked; + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) + { + /* The task being queried is referenced from the deleted + tasks list, or it is not referenced from any lists at + all. */ + eReturn = eDeleted; + } + #endif + + else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the that + called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGetFromISR( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + UBaseType_t uxReturn, uxSavedInterruptState; + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* If null is passed in here then it is the priority of the calling + task that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) + { + TCB_t *pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + nothing more than change it's priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before adding + it to it's new ready list. As we are in a critical section we + can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired != pdFALSE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + suspended list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = ( TCB_t * ) xTask; + + /* Accesses xPendingReadyList so must be called from a critical + section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* As we are in a critical section we can access the ready + lists even if the scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* We may have just resumed a higher priority task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + but will leave the lists in the correct state for the + next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Ready lists can be accessed so move the task from the + suspended list to the ready list directly. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + is held in the pending ready list until the scheduler is + unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ +BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxIdleTaskTCBBuffer = NULL; + StackType_t *pxIdleTaskStackBuffer = NULL; + uint32_t ulIdleTaskStackSize; + + /* The Idle task is created using user provided RAM - obtain the + address of the RAM then create the idle task. */ + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, + "IDLE", + ulIdleTaskStackSize, + ( void * ) NULL, + ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + + if( xIdleTaskHandle != NULL ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + #else + { + /* The Idle task is being created using dynamically allocated RAM. */ + xReturn = xTaskCreate( prvIdleTask, + "IDLE", configMINIMAL_STACK_SIZE, + ( void * ) NULL, + ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), + &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to the task that will run first. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + xNextTaskUnblockTime = portMAX_DELAY; + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) 0U; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); + } + + /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, + meaning xIdleTaskHandle is not used anywhere else. */ + ( void ) xIdleTaskHandle; +} +/*-----------------------------------------------------------*/ + +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + vPortEndScheduler(); +} +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + BaseType_t. Please read Richard Barry's reply in the following link to a + post in the FreeRTOS support forum before reporting this as a bug! - + http://goo.gl/wu4acr */ + ++uxSchedulerSuspended; +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + + /* uxHigherPriorityReadyTasks takes care of the case where + configUSE_PREEMPTION is 0, so there may be tasks above the idle priority + task that are in the Ready state, even though the idle task is + running. */ + #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + { + if( uxTopReadyPriority > tskIDLE_PRIORITY ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #else + { + const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; + + /* When port optimised task selection is used the uxTopReadyPriority + variable is used as a bit map. If bits other than the least + significant bit are set then there are tasks that have a priority + above the idle priority that are in the Ready state. This takes + care of the case where the co-operative scheduler is in use. */ + if( uxTopReadyPriority > uxLeastSignificantBit ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #endif + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else if( uxHigherPriorityReadyTasks != pdFALSE ) + { + /* There are tasks in the Ready state that have a priority above the + idle priority. This path can only be reached if + configUSE_PREEMPTION is 0. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ +TCB_t *pxTCB = NULL; +BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If the moved task has a priority higher than the current + task then a yield must be performed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxTCB != NULL ) + { + /* A task was unblocked while the scheduler was suspended, + which may have prevented the next unblock time from being + re-calculated, in which case re-calculate it now. Mainly + important for low power tickless implementations, where + this can prevent an unnecessary exit from low power + state. */ + prvResetNextTaskUnblockTime(); + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does + not slip, and that any delayed tasks are resumed at the correct + time. */ + { + UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */ + + if( uxPendedCounts > ( UBaseType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedCounts; + } while( uxPendedCounts > ( UBaseType_t ) 0U ); + + uxPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xYieldPending != pdFALSE ) + { + #if( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ +TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ +// portTICK_TYPE_ENTER_CRITICAL(); + { + xTicks = xTickCount; + } +// portTICK_TYPE_EXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ +TickType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +TCB_t *pxTCB; + + /* If null is passed in here then the name of the calling task is being + queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) + { + TCB_t *pxNextTCB, *pxFirstTCB, *pxReturn = NULL; + UBaseType_t x; + char cNextChar; + + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + + /* Check each character in the name looking for a match or + mismatch. */ + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cNextChar = pxNextTCB->pcTaskName[ x ]; + + if( cNextChar != pcNameToQuery[ x ] ) + { + /* Characters didn't match. */ + break; + } + else if( cNextChar == 0x00 ) + { + /* Both strings terminated, a match must have been + found. */ + pxReturn = pxNextTCB; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t uxQueue = configMAX_PRIORITIES; + TCB_t* pxTCB; + + /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ + configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); + + vTaskSuspendAll(); + { + /* Search the ready lists. */ + do + { + uxQueue--; + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + + if( pxTCB != NULL ) + { + /* Found the handle. */ + break; + } + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + } + + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the suspended list. */ + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + } + } + #endif + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the deleted list. */ + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + } + } + #endif + } + ( void ) xTaskResumeAll(); + + return ( TaskHandle_t ) pxTCB; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + task in the Blocked state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task in the Suspended state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( const TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) + { + TCB_t *pxTCB = ( TCB_t * ) xTask; + BaseType_t xReturn = pdFALSE; + + configASSERT( pxTCB ); + + vTaskSuspendAll(); + { + /* A task can only be prematurely removed from the Blocked state if + it is actually in the Blocked state. */ + if( eTaskGetState( xTask ) == eBlocked ) + { + /* Remove the reference to the task from the blocked list. An + interrupt won't touch the xStateListItem because the + scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove it from + the event list too. Interrupts can touch the event list item, + even though the scheduler is suspended, so a critical section + is used. */ + taskENTER_CRITICAL(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + pxTCB->ucDelayAborted = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Place the unblocked task into the appropriate ready list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only be + performed if the unblocked task has a priority that is + equal to or higher than the currently executing task. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Pend the yield to be performed when the scheduler + is unsuspended. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xTaskResumeAll(); + + return xReturn; + } + +#endif /* INCLUDE_xTaskAbortDelay */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskIncrementTick( void ) +{ +TCB_t * pxTCB; +TickType_t xItemValue; +BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount + 1; + + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + xTickCount = xConstTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + the queue in the order of their wake time - meaning once one task + has been found whose block time has not expired there is no need to + look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + to the maximum possible value so it is extremely + unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + break; + } + else + { + /* The delayed list is not empty, get the value of the + item at the head of the delayed list. This is the time + at which the task at the head of the delayed list must + be removed from the Blocked state. */ + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + item value is the time at which the task at the head + of the blocked list must be removed from the Blocked + state - so record the item value in + xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove + it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + only be performed if the unblocked task has a + priority that is equal to or higher than the + currently executing task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( UBaseType_t ) 0U ) + { + vApplicationTickHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { + vApplicationTickHook(); + } + #endif + } + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + { + TCB_t *xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + xTCB->pxTaskTag = pxHookFunction; + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t *xTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then we are setting our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = xTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + TCB_t *xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = ( TCB_t * ) xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskCHECK_FOR_STACK_OVERFLOW(); + + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); + traceTASK_SWITCHED_IN(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. The queue that contains the event + list is locked, preventing simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event groups implementation. */ + configASSERT( uxSchedulerSuspended != 0 ); + + /* Store the item value in the event list item. It is safe to access the + event list item here as interrupts won't access the event list item of a + task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + list. It is safe to access the event list here because it is part of an + event group implementation - and interrupts don't access event groups + directly (instead they access them indirectly by pending function calls to + the task level). */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called with the scheduler suspended. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* If the task should block indefinitely then set the block time to a + value that will be recognised as an indefinite delay inside the + prvAddCurrentTaskToDelayedList() function. */ + if( xWaitIndefinitely != pdFALSE ) + { + xTicksToWait = portMAX_DELAY; + } + + traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + be removed as it is known to be the highest priority. Remove the TCB from + the delayed list, and add it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means exclusive access to the event list is guaranteed here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + might be set to the blocked task's time out time. If the task is + unblocked for a reason other than a timeout xNextTaskUnblockTime is + normally left unchanged, because it is automatically reset to a new + value when the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter sleep mode + at the earliest possible time - so reset xNextTaskUnblockTime here to + ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event flags implementation. */ + configASSERT( uxSchedulerSuspended != pdFALSE ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + event flags. */ + pxUnblockedTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxEventListItem ); + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( pxEventListItem ); + + /* Remove the task from the delayed list and add it to the ready list. The + scheduler is suspended so interrupts will not be accessing the ready + lists. */ + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has + a higher priority than the calling task. This allows + the calling task to know if it should force a context + switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + if( pxCurrentTCB->ucDelayAborted != pdFALSE ) + { + /* The delay was aborted, which is not the same as a time out, + but has the same result. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + xReturn = pdTRUE; + } + else + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + if( *pxTicksToWait == portMAX_DELAY ) + { + /* If INCLUDE_vTaskSuspend is set to 1 and the block time + specified is the maximum block time then the task should block + indefinitely, and therefore never time out. */ + xReturn = pdFALSE; + } + else + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which + vTaskSetTimeout() was called, but has also overflowed since + vTaskSetTimeOut() was called. It must have wrapped all the way + around and gone past again. This passed since vTaskSetTimeout() + was called. */ + xReturn = pdTRUE; + } + else if( ( ( TickType_t ) ( xConstTickCount - pxTimeOut->xTimeOnEntering ) ) < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= ( xConstTickCount - pxTimeOut->xTimeOnEntering ); + vTaskSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( TCB_t * ) xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) + { + TCB_t *pxTCB; + + if( xTask != NULL ) + { + pxTCB = ( TCB_t * ) xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE + SCHEDULER IS STARTED. **/ + + for( ;; ) + { + /* See if any tasks have deleted themselves - if so then the idle task + is responsible for freeing the deleted task's TCB and stack. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + extern void vApplicationIdleHook( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + vApplicationIdleHook(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE != 0 ) + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + /* If all the tasks are in the suspended list (which might mean they + have an infinite block time rather than actually being suspended) + then it is safe to turn all clocks off and just wait for external + interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return eReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + } + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void *pvReturn = NULL; + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) + { + TCB_t *pxTCB; + + /* If null is passed in here then we are modifying the MPU settings of + the calling task. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + + /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + BaseType_t xListIsEmpty; + + /* ucTasksDeleted is used to prevent vTaskSuspendAll() being called + too often in the idle task. */ + while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) + { + vTaskSuspendAll(); + { + xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination ); + } + ( void ) xTaskResumeAll(); + + if( xListIsEmpty == pdFALSE ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + --uxCurrentNumberOfTasks; + --uxDeletedTasksWaitingCleanUp; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #endif /* INCLUDE_vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + + void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) + { + TCB_t *pxTCB; + + /* xTask is NULL then get the state of the calling task. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; + pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName [ 0 ] ); + pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; + pxTaskStatus->pxStackBase = pxTCB->pxStack; + pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a chance it is + actually just blocked indefinitely - so really it should be reported as + being in the Blocked state. */ + if( pxTaskStatus->eCurrentState == eSuspended ) + { + vTaskSuspendAll(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatus->eCurrentState = eBlocked; + } + } + xTaskResumeAll(); + } + } + #endif /* INCLUDE_vTaskSuspend */ + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; + } + #else + { + pxTaskStatus->uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatus->ulRunTimeCounter = 0; + } + #endif + + /* Obtaining the task state is a little fiddly, so is only done if the value + of eState passed into this function is eInvalid - otherwise the state is + just set to whatever is passed in. */ + if( eState != eInvalid ) + { + pxTaskStatus->eCurrentState = eState; + } + else + { + pxTaskStatus->eCurrentState = eTaskGetState( xTask ); + } + + /* Obtaining the stack space takes some time, so the xGetFreeStackSpace + parameter is provided to allow it to be skipped. */ + if( xGetFreeStackSpace != pdFALSE ) + { + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); + } + #else + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); + } + #endif + } + else + { + pxTaskStatus->usStackHighWaterMark = 0; + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) + { + volatile TCB_t *pxNextTCB, *pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + + /* Populate an TaskStatus_t structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of TaskStatus_t in task.h for the + meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + uxTask++; + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) + + static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( uint16_t ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up + to the task to free any memory allocated at the application level. */ + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) + { + /* The task can only have been allocated dynamically - free both + the stack and TCB. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 ) + { + /* The task could have been allocated statically or dynamically, so + check what was statically allocated before trying to free the + memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) + { + /* Both the stack and TCB were allocated dynamically, so both + must be freed. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ) + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ +TCB_t *pxTCB; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set xNextTaskUnblockTime to + the maximum possible value so it is extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + ( pxTCB ) = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. */ + if( pxMutexHolder != NULL ) + { + /* If the holder of the mutex has a priority below the priority of + the task attempting to obtain the mutex then it will temporarily + inherit the priority of the task attempting to obtain the mutex. */ + if( pxTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + priority. Only reset the event list item value if the value is + not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need + to be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* Just inherit the priority. */ + pxTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = ( TCB_t * ) pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + /* A task can only have an inherited priority if it holds the mutex. + If the mutex is held by a task then it cannot be given from an + interrupt, and if a mutex is given by the holding task then it must + be the running state task. */ + configASSERT( pxTCB == pxCurrentTCB ); + + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + /* Has the holder of the mutex inherited the priority of another + task? */ + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* A task can only have an inherited priority if it holds + the mutex. If the mutex is held by a task then it cannot be + given from an interrupt, and if a mutex is given by the + holding task then it must be the running state task. Remove + the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the + new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + any other purpose if this task is running, and it must be + running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + prvAddTaskToReadyList( pxTCB ); + + /* Return true to indicate that a context switch is required. + This is only actually required in the corner case whereby + multiple mutexes were held and the mutexes were given back + in an order different to that in which they were taken. + If a context switch did not occur when the first mutex was + returned, even if a task was waiting on it, then a context + switch should occur when the last mutex is returned whether + a task is waiting on it or not. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + function so assert() if it is being called from an interrupt + context. Only API functions that end in "FromISR" can be used in an + interrupt. Only assert if the critical nesting count is 1 to + protect against recursive calls if the assert function also uses a + critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) + { + size_t x; + + /* Start by copying the entire string. */ + strcpy( pcBuffer, pcTaskName ); + + /* Pad the end of the string with spaces to ensure columns line up when + printed out. */ + for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + { + pcBuffer[ x ] = ' '; + } + + /* Terminate. */ + pcBuffer[ x ] = 0x00; + + /* Return the new end of string. */ + return &( pcBuffer[ x ] ); + } + +#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + void vTaskList( char * pcWriteBuffer ) + { + TaskStatus_t *pxTaskStatusArray; + volatile UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! if + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = 0x00; + break; + } + + /* Write the task name to the string, padding with spaces so it + can be printed in tabular form more easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + /* Write the rest of the string. */ + sprintf( pcWriteBuffer, "\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( pcWriteBuffer ); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + void vTaskGetRunTimeStats( char *pcWriteBuffer ) + { + TaskStatus_t *pxTaskStatusArray; + volatile UBaseType_t uxArraySize, x; + uint32_t ulTotalTime, ulStatsAsPercentage; + + #if( configUSE_TRACE_FACILITY != 1 ) + { + #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). + } + #endif + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! If + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + printf("CPU total run time is %u\n", ulTotalTime); + printf("TaskName\tDeltaRunTime\tpercentage\n"); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0 ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + + /* Write the task name to the string, padding with + spaces so it can be printed in tabular form more + easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( pcWriteBuffer, "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ + sprintf( pcWriteBuffer, "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #endif + } + + pcWriteBuffer += strlen( pcWriteBuffer ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ +TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void *pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) + { + uint32_t ulReturn; + + taskENTER_CRITICAL(); + { + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue == 0UL ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_TAKE_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_TAKE(); + ulReturn = pxCurrentTCB->ulNotifiedValue; + + if( ulReturn != 0UL ) + { + if( xClearCountOnExit != pdFALSE ) + { + pxCurrentTCB->ulNotifiedValue = 0UL; + } + else + { + pxCurrentTCB->ulNotifiedValue = ulReturn - 1; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + set by the notifying task or interrupt. This can be used to + clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry; + + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_WAIT_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_WAIT(); + + if( pulNotificationValue != NULL ) + { + /* Output the current notification value, which may or may not + have changed. */ + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue; + } + + /* If ucNotifyValue is set then either the task never entered the + blocked state (because a notification was already pending) or the + task unblocked because of a notification. Otherwise the task + unblocked because of a timeout. */ + if( pxCurrentTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + /* A notification was not received. */ + xReturn = pdFALSE; + } + else + { + /* A notification was already pending or a notification was + received while the task was waiting. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit; + xReturn = pdTRUE; + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) + { + TCB_t * pxTCB; + BaseType_t xReturn = pdPASS; + uint8_t ucOriginalNotifyState; + + configASSERT( xTaskToNotify ); + pxTCB = ( TCB_t * ) xTaskToNotify; + + taskENTER_CRITICAL(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction: + /* The task is being notified without its notify value being + updated. */ + break; + } + + traceTASK_NOTIFY(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + xNextTaskUnblockTime might be set to the blocked task's time + out time. If the task is unblocked for a reason other than + a timeout xNextTaskUnblockTime is normally left unchanged, + because it will automatically get reset to a new value when + the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter + sleep mode at the earliest possible time - so reset + xNextTaskUnblockTime here to ensure it is updated at the + earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + BaseType_t xReturn = pdPASS; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = ( TCB_t * ) xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction : + /* The task is being notified without its notify value being + updated. */ + break; + } + + traceTASK_NOTIFY_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter to an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = ( TCB_t * ) xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + /* 'Giving' is equivalent to incrementing a count in a counting + semaphore. */ + ( pxTCB->ulNotifiedValue )++; + + traceTASK_NOTIFY_GIVE_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter in an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ + +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + BaseType_t xReturn; + + /* If null is passed in here then it is the calling task that is having + its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) + { + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + + +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) +{ +TickType_t xTimeToWake; +const TickType_t xConstTickCount = xTickCount; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + /* About to enter a delayed list, so ensure the ucDelayAborted flag is + reset to pdFALSE so it can be detected as having been set to pdTRUE + when the task leaves the Blocked state. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Remove the task from the ready list before adding it to the blocked list + as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure it is not woken by a timing event. It will block + indefinitely. */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + kernel will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow + list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list + is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the + head of the list of blocked tasks then xNextTaskUnblockTime + needs to be updated too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the kernel + will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ + ( void ) xCanBlockIndefinitely; + } + #endif /* INCLUDE_vTaskSuspend */ +} + + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/Source/timers.c b/USDK/component/os/freertos/freertos_v9.0.0/Source/timers.c new file mode 100644 index 0000000..d4a821a --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/Source/timers.c @@ -0,0 +1,1092 @@ +/* + FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e961 and e750 are suppressed as a MISRA exception justified because the +MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the +header files above, but not in this file, in order to generate the correct +privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( TickType_t ) 0U + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl +{ + const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ + UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*<< Set to pdTRUE if the timer was created statically so no attempt is made to free the memory again if the timer is later deleted. */ + #endif +} xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t +name below to enable the use of older kernel aware debuggers. */ +typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. +Two types of message can be queued - messages that manipulate a software timer, +and messages that request the execution of a non-timer related callback. The +two message types are defined in two separate structures, xTimerParametersType +and xCallbackParametersType respectively. */ +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier +that is used to determine which message type is valid. */ +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + +/*lint -e956 A manual analysis and inspection has been used to determine which +static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access these lists. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; +PRIVILEGED_DATA static List_t *pxCurrentTimerList; +PRIVILEGED_DATA static List_t *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; +PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +/*lint +e956 */ + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + /* If static allocation is supported then the application must provide the + following callback function - which enables the application to optionally + provide the memory that will be used by the timer task as the task's stack + and TCB. */ + extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + +#endif + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * Called after a Timer_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTimer( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +/*-----------------------------------------------------------*/ + +BaseType_t xTimerCreateTimerTask( void ) +{ +BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxTimerTaskTCBBuffer = NULL; + StackType_t *pxTimerTaskStackBuffer = NULL; + uint32_t ulTimerTaskStackSize; + + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + "Tmr Svc", + ulTimerTaskStackSize, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + pxTimerTaskStackBuffer, + pxTimerTaskTCBBuffer ); + + if( xTimerTaskHandle != NULL ) + { + xReturn = pdPASS; + } + } + #else + { + xReturn = xTaskCreate( prvTimerTask, + "Tmr Svc", + configTIMER_TASK_STACK_DEPTH, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + &xTimerTaskHandle ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreate( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + Timer_t *pxNewTimer; + + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); + + if( pxNewTimer != NULL ) + { + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Timers can be created statically or dynamically, so note this + timer was created dynamically in case the timer is later + deleted. */ + pxNewTimer->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + Timer_t *pxNewTimer; + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTimer_t equals the size of the real timer + structures. */ + volatile size_t xSize = sizeof( StaticTimer_t ); + configASSERT( xSize == sizeof( Timer_t ) ); + } + #endif /* configASSERT_DEFINED */ + + /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ + configASSERT( pxTimerBuffer ); + pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewTimer != NULL ) + { + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Timers can be created statically or dynamically so note this + timer was created statically in case it is later deleted. */ + pxNewTimer->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTimer( const char * const pcTimerName, + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function + parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->uxAutoReload = uxAutoReload; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + traceTIMER_CREATE( pxNewTimer ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) +{ +BaseType_t xReturn = pdFAIL; +DaemonTaskMessage_t xMessage; + + configASSERT( xTimer ); + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = ( Timer_t * ) xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) +{ + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) +{ +Timer_t *pxTimer = ( Timer_t * ) xTimer; + + configASSERT( xTimer ); + return pxTimer->xTimerPeriodInTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) +{ +Timer_t * pxTimer = ( Timer_t * ) xTimer; +TickType_t xReturn; + + configASSERT( xTimer ); + xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +Timer_t *pxTimer = ( Timer_t * ) xTimer; + + configASSERT( xTimer ); + return pxTimer->pcTimerName; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) +{ +BaseType_t xResult; +Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + /* The timer is inserted into a list using a time relative to anything + other than the current time. It will therefore be inserted into the + correct list relative to the time this task thinks it is now. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static void prvTimerTask( void *pvParameters ) +{ +TickType_t xNextExpireTime; +BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + { + extern void vApplicationDaemonTaskStartupHook( void ); + + /* Allow the application writer to execute some code in the context of + this task at the point the task starts executing. This is useful if the + application includes initialisation code that would benefit from + executing after the scheduler has been started. */ + vApplicationDaemonTaskStartupHook(); + } + #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) +{ +TickType_t xTimeNow; +BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + if( xListWasEmpty != pdFALSE ) + { + /* The current timer list is empty - is the overflow list + also empty? */ + xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); + } + + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the + block time to expire. If a command arrived between the + critical section being exited and this yield then the yield + will not cause the task to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) +{ +TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) +{ +TickType_t xTimeNow; +PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) +{ +BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +DaemonTaskMessage_t xMessage; +Timer_t *pxTimer; +BaseType_t xTimerListsWereSwitched, xResult; +TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + case tmrCOMMAND_START_FROM_ISR : + case tmrCOMMAND_RESET : + case tmrCOMMAND_RESET_FROM_ISR : + case tmrCOMMAND_START_DONT_TRACE : + /* Start or restart a timer. */ + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + timer list. Process it now. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + traceTIMER_EXPIRED( pxTimer ); + + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + break; + + case tmrCOMMAND_STOP : + case tmrCOMMAND_STOP_FROM_ISR : + /* The timer has already been removed from the active list. + There is nothing to do here. */ + break; + + case tmrCOMMAND_CHANGE_PERIOD : + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + be longer or shorter than the old one. The command time is + therefore set to the current time, and as the period cannot + be zero the next expiry time can only be in the future, + meaning (unlike for the xTimerStart() case above) there is + no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + /* The timer has already been removed from the active list, + just free up the memory if the memory was dynamically + allocated. */ + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The timer can only have been allocated dynamically - + free it again. */ + vPortFree( pxTimer ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The timer could have been allocated statically or + dynamically, so check before attempting to free the + memory. */ + if( pxTimer->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxTimer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default : + /* Don't expect to get here. */ + break; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( void ) +{ +TickType_t xNextExpireTime, xReloadTime; +List_t *pxTemp; +Timer_t *pxTimer; +BaseType_t xResult; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + + if( pxTimer->uxAutoReload == ( UBaseType_t ) pdTRUE ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The timer queue is allocated statically in case + configSUPPORT_DYNAMIC_ALLOCATION is 0. */ + static StaticQueue_t xStaticTimerQueue; + static uint8_t ucStaticTimerQueueStorage[ configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; + + xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); + } + #else + { + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + } + #endif + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) +{ +BaseType_t xTimerIsInActiveList; +Timer_t *pxTimer = ( Timer_t * ) xTimer; + + configASSERT( xTimer ); + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + /* Checking to see if it is in the NULL list in effect checks to see if + it is referenced from either the current or the overflow timer lists in + one go, but the logic has to be reversed, hence the '!'. */ + xTimerIsInActiveList = ( BaseType_t ) !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) ); + } + taskEXIT_CRITICAL(); + + return xTimerIsInActiveList; +} /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) +{ +Timer_t * const pxTimer = ( Timer_t * ) xTimer; +void *pvReturn; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pvReturn = pxTimer->pvTimerID; + } + taskEXIT_CRITICAL(); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) +{ +Timer_t * const pxTimer = ( Timer_t * ) xTimer; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pxTimer->pvTimerID = pvNewID; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* This function can only be called after a timer has been created or + after the scheduler has been started because, until then, the timer + queue does not exist. */ + configASSERT( xTimerQueue ); + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ + + + diff --git a/USDK/component/os/freertos/freertos_v9.0.0/links_to_doc_pages_for_the_demo_projects.url b/USDK/component/os/freertos/freertos_v9.0.0/links_to_doc_pages_for_the_demo_projects.url new file mode 100644 index 0000000..cfd5526 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/links_to_doc_pages_for_the_demo_projects.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.freertos.org/a00090.html +IDList= diff --git a/USDK/component/os/freertos/freertos_v9.0.0/readme.txt b/USDK/component/os/freertos/freertos_v9.0.0/readme.txt new file mode 100644 index 0000000..7fa63a7 --- /dev/null +++ b/USDK/component/os/freertos/freertos_v9.0.0/readme.txt @@ -0,0 +1,21 @@ +Directories: + ++ The FreeRTOS/Source directory contains the FreeRTOS source code, and contains + its own readme file. + ++ The FreeRTOS/Demo directory contains a demo application for every official +FreeRTOS port, and contains its own readme file. + ++ See http://www.freertos.org/a00017.html for full details of the directory + structure and information on locating the files you require. + +The easiest way to use FreeRTOS is to start with one of the pre-configured demo +application projects (found in the FreeRTOS/Demo directory). That way you will +have the correct FreeRTOS source files included, and the correct include paths +configured. Once a demo application is building and executing you can remove +the demo application file, and start to add in your own application source +files. + +See also - +http://www.freertos.org/FreeRTOS-quick-start-guide.html +http://www.freertos.org/FAQHelp.html diff --git a/USDK/component/os/os_dep/device_lock.c b/USDK/component/os/os_dep/device_lock.c new file mode 100644 index 0000000..b76516d --- /dev/null +++ b/USDK/component/os/os_dep/device_lock.c @@ -0,0 +1,64 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "osdep_service.h" +#include "device_lock.h" + +//------------------------------------------------------ +#define DEVICE_MUTEX_IS_INIT(device) (mutex_init & (1< +#include +#include "os_support.h" +//#include "diag.h" + + + +#if 0 +#define __init +#define __exit +#define __devinit +#define __devexit +#endif +#define RTL_HZ 100 + +#define SemaInit(sem, value) vSemaphoreCreateBinary(sem) +#define SemaPost(sem) xSemaphoreGive(sem) +#define SemaWait(sem, block_time) xSemaphoreTake(sem, block_time) +//#define printk DiagPrintf + +#define SpinLockInit(lock) do { } while (0) +#define SpinLock(x) do { } while (0) +#define SpinUnlock(x) do { } while (0) +#define SpinLockBh(x) do { } while (0) +#define SpinUnlockBh(x) do { } while (0) +#ifdef PLATFORM_FREERTOS +#define RestoreFlags() portEXIT_CRITICAL() +#define SaveAndCli() portENTER_CRITICAL() +#define SpinLockIrqSave(lock, flags) SaveAndCli() +#define SpinUnlockIrqRestore(l, f) RestoreFlags() +#else +#define RestoreFlags(x) portENABLE_INTERRUPTS() +#define SaveAndCli(x) portDISABLE_INTERRUPTS() +#define SpinLockIrqSave(lock, flags) SaveAndCli(flags) +#define SpinUnlockIrqRestore(l, f) RestoreFlags(f) +#endif + + +//#define RtlKmalloc(size, flag) pvPortMallocAligned(size, 0) +#define RtlKmalloc(size, flag) pvPortMalloc(size) +#define RtlKfree(pv) vPortFreeAligned(pv) + + + +#ifdef CONFIG_TIMER_MODULE +#define __Delay(t) HalDelayUs(t) +#else +static __inline__ u32 __Delay(u32 us) +{ + DBG_8195A("No Delay: please enable hardware Timer\n"); +} +#endif + + +#define Mdelay(t) __Delay(t*1000) +#define Udelay(t) __Delay(t) + + +#define ASSERT(_bool_) do { } while (0) + +//#define panic_printk DiagPrintf +//#define sprintf DiagPrintf +//#define diag_sprintf DiagPrintf + + +//1TODO: Need check again; the below just for compile ok ; chris + +/* + * ATOMIC_READ - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +//#define AtomicRead(v) ((*v)) + +static __inline__ u32 +AtomicRead( + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + u32 Temp; + + SaveAndCli(); + Temp = v->counter; + RestoreFlags(); + + return Temp; + +#else + u32 Temp, Flags; + + SaveAndCli(Flags); + Temp = v->counter; + RestoreFlags(Flags); + + return Temp; +#endif +} + +/* + * ATOMIC_SET - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +//#define AtomicSet(v,i) ((v)->counter = (i)) + +static __inline__ VOID +AtomicSet( + IN u32 i, + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + SaveAndCli(); + v->counter = i; + RestoreFlags(); +#else + u32 Flags; + + SaveAndCli(Flags); + v->counter = i; + RestoreFlags(Flags); +#endif +} + +/* + * The MIPS I implementation is only atomic with respect to + * interrupts. R3000 based multiprocessor machines are rare anyway ... + * + * AtomicAdd - add integer to atomic variable + * @i: integer value to add + * @v: pointer of type atomic_t + * + * Atomically adds @i to @v. Note that the guaranteed useful range + * of an atomic_t is only 24 bits. + */ +static __inline__ VOID +AtomicAdd( + IN u32 i, + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + SaveAndCli(); + v->counter += i; + RestoreFlags(); +#else + u32 Flags; + + SaveAndCli(Flags); + v->counter += i; + RestoreFlags(Flags); +#endif +} + +/* + * AtomicSub - subtract the atomic variable + * @i: integer value to subtract + * @v: pointer of type atomic_t + * + * Atomically subtracts @i from @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +static __inline__ void +AtomicSub( + IN u32 i, + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + SaveAndCli(); + v->counter -= i; + RestoreFlags(); +#else + u32 Flags; + + SaveAndCli(Flags); + v->counter -= i; + RestoreFlags(Flags); +#endif +} + +static __inline__ u32 +AtomicAddReturn( + IN u32 i, + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + u32 Temp; + + SaveAndCli(); + Temp = v->counter; + Temp += i; + v->counter = Temp; + RestoreFlags(); + + return Temp; + +#else + u32 Temp, Flags; + + SaveAndCli(Flags); + Temp = v->counter; + Temp += i; + v->counter = Temp; + RestoreFlags(Flags); + + return Temp; +#endif +} + +static __inline__ u32 +AtomicSubReturn( + IN u32 i, + IN atomic_t * v +) +{ +#ifdef PLATFORM_FREERTOS + u32 Temp; + + SaveAndCli(); + Temp = v->counter; + Temp -= i; + v->counter = Temp; + RestoreFlags(); + + return Temp; + +#else + + u32 Temp, Flags; + + SaveAndCli(Flags); + Temp = v->counter; + Temp -= i; + v->counter = Temp; + RestoreFlags(Flags); + + return Temp; +#endif +} + +/* + * ATOMIC_INC - increment atomic variable + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define AtomicInc(v) AtomicAdd(1,(v)) + +#define AtomicIncReturn(v) AtomicAddReturn(1,(v)) + +/* + * ATOMIC_DEC - decrement and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define AtomicDec(v) AtomicSub(1,(v)) + +#define AtomicDecReturn(v) AtomicSubReturn(1,(v)) + +/* + * ATOMIC_DEC_AND_TEST - decrement by 1 and test + * @v: pointer of type atomic_t + * + * Atomically decrements @v by 1 and + * returns true if the result is 0, or false for all other + * cases. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define AtomicDecAndTest(v) (AtomicSubReturn(1, (v)) == 0) + +/* Not needed on 64bit architectures */ +static __inline__ u32 +__Div64_32( + IN __uint64_t *n, + IN u32 base +) +{ + __uint64_t rem = *n; + __uint64_t b = base; + __uint64_t res, d = 1; + u32 high = rem >> 32; + + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (__uint64_t) high << 32; + rem -= (__uint64_t) (high*base) << 32; + } + + while ((__int64_t)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); + + *n = res; + return rem; +} + +#define DO_DIV(n,base) ({ \ + unsigned int __base = (base); \ + unsigned int __rem; \ + (void)(((typeof((n)) *)0) == ((__uint64_t *)0)); \ + if (((n) >> 32) == 0) { \ + __rem = (unsigned int)(n) % __base; \ + (n) = (unsigned int)(n) / __base; \ + } else \ + __rem = __Div64_32(&(n), __base); \ + __rem; \ + }) + +#endif /* __SYS_SUPPORT_H__ */ diff --git a/USDK/component/os/os_dep/include/osdep_service.h b/USDK/component/os/os_dep/include/osdep_service.h new file mode 100644 index 0000000..c36faa7 --- /dev/null +++ b/USDK/component/os/os_dep/include/osdep_service.h @@ -0,0 +1,1354 @@ +//----------------------------------------------------------------------------// +/** + ****************************************************************************** + * @file osdep_service.h + * @author + * @version + * @brief This file provides the OS dependent API. + ****************************************************************************** + * @attention + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + * + * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved. + ****************************************************************************** + */ + +#ifndef __OSDEP_SERVICE_H_ +#define __OSDEP_SERVICE_H_ + +/** @addtogroup RTOS + * @{ + */ + +/*************************** OS dep feature enable *******************************/ + +/****************************************************** + * Macros + ******************************************************/ + +#define CONFIG_LITTLE_ENDIAN + +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#define CONFIG_PLATFORM_AMEBA_X +#endif + +#if defined(CONFIG_PLATFORM_8195A) + #define CONFIG_USE_TCM_HEAP 1 /* USE TCM HEAP */ + #define USE_MUTEX_FOR_SPINLOCK 1 +#endif + +#if defined(CONFIG_PLATFORM_AMEBA_X) + #define CONFIG_MEM_MONITOR MEM_MONITOR_SIMPLE +#else + #define CONFIG_MEM_MONITOR MEM_MONITOR_LEAK +#endif + +/* Define compilor specific symbol */ + +/*************************** inline functions *******************************/ +#if defined ( __ICCARM__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition //In dialect C99, inline means that a function's definition is provided + //only for inlining, and that there is another definition + //(without inline) somewhere else in the program. + //That means that this program is incomplete, because if + //add isn't inlined (for example, when compiling without optimization), + //then main will have an unresolved reference to that other definition. + + // Do not inline function is the function body is defined .c file and this + // function will be called somewhere else, otherwise there is compile error +#elif defined ( __CC_ARM ) +#define __inline__ __inline //__linine__ is not supported in keil compilor, use __inline instead +#define inline __inline +#define __inline_definition // for dialect C99 +#elif defined ( __GNUC__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition inline +#endif + +#include +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#include "platform_autoconf.h" +#else //for 8189FM/8189FTV add by frankie_li 20160408 +#ifndef SUCCESS +#define SUCCESS 0 +#endif +#ifndef FAIL +#define FAIL (-1) +#endif +#ifndef _SUCCESS +#define _SUCCESS 1 +#endif +#ifndef _FAIL +#define _FAIL 0 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef TRUE + #define TRUE (!FALSE) +#endif + +#define _TRUE TRUE +#define _FALSE FALSE + +#endif + +#if defined( PLATFORM_FREERTOS) +#include "freertos_service.h" +#elif defined( PLATFORM_ECOS) +#include "ecos/ecos_service.h" +#endif + +#define RTW_MAX_DELAY 0xFFFFFFFF +#define RTW_WAIT_FOREVER 0xFFFFFFFF + +/****************************************************** + * Constants + ******************************************************/ +/** + * @brief Definitions returned by xTaskGetSchedulerState(). + */ + +#define OS_SCHEDULER_NOT_STARTED 0 +#define OS_SCHEDULER_RUNNING 1 +#define OS_SCHEDULER_SUSPENDED 2 + +/****************************************************** + * Structures + ******************************************************/ +struct timer_list { + _timerHandle timer_hdl; + unsigned long data; + void (*function)(void *); +}; + +/****************************************************** + * Type Definitions + ******************************************************/ +typedef thread_return (*thread_func_t)(thread_context context); +typedef void (*TIMER_FUN)(void *context); +typedef int (*event_handler_t)(char *buf, int buf_len, int flags, void *user_data); + +#define CONFIG_THREAD_COMM_SEMA +struct task_struct { + const char *task_name; + _thread_hdl_ task; /* I: workqueue thread */ + +#ifdef CONFIG_THREAD_COMM_SIGNAL + const char *name; /* I: workqueue thread name */ + u32 queue_num; /* total signal num */ + u32 cur_queue_num; /* cur signal num should < queue_num */ +#elif defined(CONFIG_THREAD_COMM_SEMA) + _sema wakeup_sema; + _sema terminate_sema; +// _queue work_queue; //TODO +#endif + u32 blocked; + u32 callback_running; +}; + +typedef struct { + _xqueue event_queue; + struct task_struct thread; +}rtw_worker_thread_t; + +typedef struct +{ + event_handler_t function; + char *buf; + int buf_len; + int flags; + void *user_data; +} rtw_event_message_t; + +struct worker_timer_entry { + struct list_head list; + _timerHandle timer_hdl; + rtw_event_message_t message; + rtw_worker_thread_t *worker_thread; + u32 timeout; +}; + +#ifdef CONFIG_THREAD_COMM_SIGNAL +struct work_struct; +typedef void (*work_func_t)(void *context); +struct work_struct { + _list list; + u32 data; + work_func_t func; + void *context; + struct task_struct *used_wq; +}; + +struct delayed_work { + struct work_struct work; + struct timer_list timer; +}; +#endif + + +#ifdef CONFIG_MEM_MONITOR + +/*************************** Memory Monitor *******************************/ +#define MEM_MONITOR_SIMPLE 0x1 +#define MEM_MONITOR_LEAK 0x2 + +#define MEM_MONITOR_FLAG_WIFI_DRV 0x1 +#define MEM_MONITOR_FLAG_WPAS 0x2 +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK +struct mem_entry { + struct list_head list; + int size; + void *ptr; +}; +#endif + +/** + * @brief This function initializes a memory table. + * @param[in] pmem_table: The pointer to the memory table. + * @param[in] used_num: The number of mem_entry kept in monitor which will be set to 0. + * @return None + */ +void init_mem_monitor(_list *pmem_table, int *used_num); + +/** + * @brief This function deinitializes a memory table. + * @param[in] pmem_table: The pointer to the memory table. + * @param[in] used_num: The number of mem_entry kept in monitor. + * @return None + */ +void deinit_mem_monitor(_list *pmem_table, int *used_num); + +/** + * @brief This function alloc mem_entry to the memory table. + * @param[in] pmem_table: The pointer to the memory table to be added. + * @param[in] ptr: The pointer to the position to be added. + * @param[in] size: The size of added memory. + * @param[in] used_num: The number of mem_entry kept in monitor which will add 1 after. + * @param[in] flag: MEM_MONITOR_FLAG_WPAS/MEM_MONITOR_FLAG_WIFI_DRV + * @return None + */ +void add_mem_usage(_list *pmem_table, void *ptr, int size, int *used_num, int flag); + +/** + * @brief This function frees memory from the memory table. + * @param[in] pmem_table: The pointer to the memory table + * @param[in] ptr: The pointer to the position to be free. + * @param[in] used_num: The number of mem_entry kept in monitor. + * @param[in] flag: MEM_MONITOR_FLAG_WPAS/MEM_MONITOR_FLAG_WIFI_DRV + * @return None + */ +void del_mem_usage(_list *pmem_table, void *ptr, int *used_num, int flag); + +/** + * @brief This function get the memory usage of a memory table. + * @param[in] pmem_table: The pointer to the memory table. + * @return The size of the memory used + */ +int get_mem_usage(_list *pmem_table); +/*************************** End Memory Monitor *******************************/ +#endif + + +/*************************** Memory Management *******************************/ +u8* _rtw_vmalloc(u32 sz); +u8* _rtw_zvmalloc(u32 sz); +void _rtw_vmfree(u8 *pbuf, u32 sz); +u8* _rtw_zmalloc(u32 sz); +u8* _rtw_malloc(u32 sz); +void _rtw_mfree(u8 *pbuf, u32 sz); +#ifdef CONFIG_MEM_MONITOR + +/** + * @brief This function allocates the virtually contiguous memory. + * @param[in] sz: The size of memory to be allocated. + * @return The pointer to the beginning of the memory + */ +u8* rtw_vmalloc(u32 sz); + +/** + * @brief This function allocates the virtually contiguous memory + * and the values of the memory are setted to 0. + * @param[in] sz: The size of memory to be allocated. + * @return The pointer to the beginning of the memory + */ +u8* rtw_zvmalloc(u32 sz); + +/** + * @brief This function frees the virtually contiguous memory. + * @param[in] pbuf: The pointer to the beginning of the memory to be free + * @param[in] sz: The size of memory allocated. + * @return None + */ +void rtw_vmfree(u8 *pbuf, u32 sz); + +/** + * @brief This function allocates the memory + * and the values of the memory are setted to 0. + * @param[in] sz: The size of memory to be allocated. + * @return The pointer to the beginning of the memory + */ +u8* rtw_zmalloc(u32 sz); + +/** + * @brief This function allocates the memory. + * @param[in] sz: The size of memory to be allocated. + * @return The pointer to the beginning of the memory + */ +u8* rtw_malloc(u32 sz); + +/** + * @brief This function frees the virtually contiguous memory. + * @param[in] pbuf: The pointer to the beginning of the memory to be free + * @param[in] sz: The size of memory allocated. + * @return None + */ +void rtw_mfree(u8 *pbuf, u32 sz); +#else +#define rtw_vmalloc _rtw_vmalloc +#define rtw_zvmalloc _rtw_zvmalloc +#define rtw_vmfree _rtw_vmfree +#define rtw_zmalloc _rtw_zmalloc +#define rtw_malloc _rtw_malloc +#define rtw_mfree _rtw_mfree +#endif +#define rtw_free(buf) rtw_mfree((u8 *)buf, 0) + +/** + * @brief This function allocates a 2 dimensional array memory. + * @param[in] h: The height of the 2D array. + * @param[in] w: The width of the 2D array. + * @param[in] size: The size of the each charactor in array. + * @return the pointer to the beginning of the block + */ +void* rtw_malloc2d(int h, int w, int size); + +/** + * @brief This function deallocates the block of memory previously allocated to make it available again. + * @param[in] pbuf: Pointer to a memory block previously allocated. + * @param[in] h: The height of the 2D array. + * @param[in] w: The width of the 2D array. + * @param[in] size: The size of the each charactor in array. + * @return None + */ +void rtw_mfree2d(void *pbuf, int h, int w, int size); + +/** + * @brief This function copies the values of "sz" bytes from the location pointed to by "src" + * directly to the memory block pointed to by "des". + * @param[in] dst: Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*. + * @param[in] src: Pointer to the source of data to be copied, type-casted to a pointer of type void*. + * @param[in] sz: Size of memory to copy. + * @return None + */ +void rtw_memcpy(void* dst, void* src, u32 sz); + +/** + * @brief This function compares the first "sz" bytes of the block of memory pointed by "dst" + * to the first "sz" bytes pointed by "src". + * @param[in] dst: Pointer to block of memory to be compared. + * @param[in] src: pointer to block of memory to compare. + * @param[in] sz: Size of memory to compare. + * @return <0: The first byte that does not match in both memory blocks has a lower value in dst than in src. + * @return 0: The contents of both memory blocks are equal. + * @return <0: The first byte that does not match in both memory blocks has a greater value in dst than in src. + */ +int rtw_memcmp(void *dst, void *src, u32 sz); + +/** + * @brief This function sets the first "sz" bytes of the block of memory pointed by "pbuf" to the specified "c". + * @param[in] pbuf: Pointer to the block of memory to fill. + * @param[in] c: Value to be set. + * @param[in] sz: Size of memory to be set to the value "c". + * @return None + */ +void rtw_memset(void *pbuf, int c, u32 sz); +/*************************** End Memory Management *******************************/ + +/*************************** List *******************************/ + +/** + * @brief This function initializes the head of the list. + * @param[in] list: Pointer to the list to be initialized. + * @return None + */ +void rtw_init_listhead(_list *list); + +/** + * @brief This function tests whether a list is empty. + * @param[in] phead: Pointer to the list to test. + * @return _TRUE/_FALSE + */ +u32 rtw_is_list_empty(_list *phead); + +/** + * @brief This function adds a new entry after "phead" for the list. + * @param[in] plist: Pointer to the list to be added. + * @param[in] phead: List head to add it after. + * @return None + */ +void rtw_list_insert_head(_list *plist, _list *phead); + +/** + * @brief This function adds a new entry before "phead" for the list. + * @param[in] plist: Pointer to the list to be added. + * @param[in] phead: List head to add it before. + * @return None + */ +void rtw_list_insert_tail(_list *plist, _list *phead); + +/** + * @brief This function deletes entry from list and reinitialize it. + * @param[in] plist: The element to delete from the list. + * @return None + * @note Caller must check if the list is empty before calling rtw_list_delete + */ +void rtw_list_delete(_list *plist); +/*************************** End List *******************************/ + + +/*************************** Semaphores *******************************/ +/** + * @brief This function initializes the unnamed semaphore referred to by "sema" to the value "init_val". + * @param[in] sema: Pointer to the semaphore handle to be initialized. + * @param[in] init_val: Initial value for semaphore. + * @return None + */ +void rtw_init_sema(_sema *sema, int init_val); + +/** + * @brief This function deletes the semaphore. + * @param[in] sema: The semaphore to be deleted. + * @return None + */ +void rtw_free_sema(_sema *sema); + +/** + * @brief This function releases the semaphore. + * This macro must not be used from an ISR. + * @param[in] sema: The semaphore to be released. + * @return None + */ +void rtw_up_sema(_sema *sema); + +/** + * @brief This function releases the semaphore. + * This macro can be used from an ISR. + * @param[in] sema: The semaphore to be released. + * @return None + */ +void rtw_up_sema_from_isr(_sema *sema); + +/** + * @brief This function acquires the semaphore. If no more tasks are allowed to acquire the semaphore, + * calling this function will put the task to sleep until the semaphore is up. + * @param[in] sema: The semaphore to be acquired. + * @return pdTRUE: The semaphore was obtained. + * @return pdFALSE: Obtain the semaphore failed. + */ +u32 rtw_down_sema(_sema *sema); + +/** + * @brief This function acquires the semaphore. If no more tasks are allowed to acquire the semaphore, + * calling this function will put the task to sleep until the semaphore is up. + * @param[in] sema: The semaphore to be acquired. + * @param[in] timeout: The time in ms to wait for the semaphore to become available. + * @return pdTRUE: The semaphore was obtained. + * @return pdFALSE: Timeout without the semaphore becoming available. + */ +u32 rtw_down_timeout_sema(_sema *sema, u32 timeout); +/*************************** End Semaphores *******************************/ + +/*************************** Mutexes *******************************/ +/** + * @brief This function implements a mutex semaphore by using the existing queue mechanism. + * @param[in] pmutex: Pointer to the created mutex semaphore. + * @return None + */ +void rtw_mutex_init(_mutex *pmutex); + +/** + * @brief This function deletes the mutex semaphore. + * @param[in] pmutex: Pointer to the mutex semaphore to be deleted. + * @return None + */ +void rtw_mutex_free(_mutex *pmutex); + +/** + * @brief This function releases a mutex semaphore. + * @param[in] pmutex: Pointer to the mutex semaphore to be released. + * @return None + */ +void rtw_mutex_put(_mutex *pmutex); + +/** + * @brief This function obtains a mutex semaphore. + * @param[in] pmutex: Pointer to the mutex semaphore being taken - obtained when + * the mutex semaphore was created. + * @return None + */ +void rtw_mutex_get(_mutex *pmutex); + +/** + * @brief This function obtains a mutex semaphore with a timeout setting. + * @param[in] pmutex: Pointer to the mutex semaphore being taken - obtained when + * the mutex semaphore was created. + * @param[in] timeout: The time in ms to wait for the semaphore to become available. + * @return 0: The semaphore was obtained. + * @return -1: Timeout without the semaphore becoming available. + */ +int rtw_mutex_get_timeout(_mutex *pmutex, u32 timeout_ms); +/*************************** End Mutexes *******************************/ + +/*************************** SchedulerControl *******************************/ +/** + * @brief This function marks the start of a critical code region. + * Preemptive context switches cannot occur when in a critical region. + * @param[in] plock: Pointer to the spin lock semaphore. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + * @note: This may alter the stack (depending on the portable implementation) + * so must be used with care! + */ +void rtw_enter_critical(_lock *plock, _irqL *pirqL); + +/** + * @brief This function marks end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * @param[in] plock: Pointer to the spin lock semaphore. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + * @note: This may alter the stack (depending on the portable implementation) + * so must be used with care! + */ +void rtw_exit_critical(_lock *plock, _irqL *pirqL); + +/** + * @brief This function marks the start of a critical code region from isr. + * @param[in] plock: Pointer to the spin lock semaphore. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +void rtw_enter_critical_from_isr(_lock *plock, _irqL *pirqL); + +/** + * @brief This function marks the end of a critical code region from isr. + * @param[in] plock: Pointer to the spin lock semaphore. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +void rtw_exit_critical_from_isr(_lock *plock, _irqL *pirqL); + +/** + * @brief This function obtains a spin lock semaphore. + * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when + * the mutex semaphore was created. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +void rtw_enter_critical_bh(_lock *plock, _irqL *pirqL); + +/** + * @brief This function releases a spin lock semaphore. + * @param[in] plock: Pointer to the spin lock semaphore to be released. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +void rtw_exit_critical_bh(_lock *plock, _irqL *pirqL); + +/** + * @brief This function obtains a semaphore. + * @param[in] pmutex: The handle to the mutex semaphore to be obtained. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +int rtw_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL); + +/** + * @brief This function releases a semaphore. + * @param[in] pmutex: The handle to the mutex semaphore to be released. + * @param[in] pirqL: Pointer to the IRQ. + * @return None + */ +void rtw_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL); +/*************************** End SchedulerControl *******************************/ + +/*************************** Semaphores *******************************/ + +/** + * @brief This function implements a spin lock semaphore by using the existing queue mechanism. + * @param[in] plock: Pointer to the created spin lock semaphore. + * @return None + */ +void rtw_spinlock_init(_lock *plock); + +/** + * @brief This function deletes the spin lock semaphore. + * @param[in] pmutex: Pointer to the spin lock semaphore to be deleted. + * @return None + */ +void rtw_spinlock_free(_lock *plock); + +/** + * @brief This function obtains a spin lock semaphore. + * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when + * the mutex semaphore was created. + * @return None + */ +void rtw_spin_lock(_lock *plock); + +/** + * @brief This function releases a spin lock semaphore. + * @param[in] plock: Pointer to the spin lock semaphore to be released. + * @return None + */ +void rtw_spin_unlock(_lock *plock); + +/** + * @brief This function marks the start of a critical code region and + * obtains a spin lock semaphore. + * @param[in] plock: Pointer to the spin lock semaphore being taken - obtained when + * the mutex semaphore was created. + * @param[in] irqL: Pointer to the IRQ. + * @return None + */ +void rtw_spinlock_irqsave(_lock *plock, _irqL *irqL); + +/** + * @brief This function releases a spin lock semaphore and + marks the end of a critical code region. + * @param[in] plock: Pointer to the spin lock semaphore to be released. + * @param[in] irqL: Pointer to the IRQ. + * @return None + */ +void rtw_spinunlock_irqsave(_lock *plock, _irqL *irqL); +/*************************** End Semaphores *******************************/ + +/*************************** Queues *******************************/ + +/** + * @brief This function creates a new queue instance. + * @param[in] queue: The handle to the newly created queue. + * @param[in] name: The name of the queue + * @param[in] message_size: The number of bytes each message in the queue will require. + * @param[in] number_of_messages: The maximum number of messages that kthe queue can contain. + * @return 0: Creating queue success + * @return -1: Creating queue fail + */ +int rtw_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages ); + +/** + * @brief This function posts a message to the back of a queue. + * The message is queued by copy, not by reference. + * @param[in] queue: The handle to the queue on which the message is to be posted. + * @param[in] message: The pointer to the message that is to be placed on the queue. + * @param[in] timeout_ms: The maximum amout of time the task should block waiting for + the space to become available on the queue, should it already be full. + The time is defined in ms. + * @return 0: The message was successfully posted. + * @return -1: The message was not posted. + */ +int rtw_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms ); + +/** + * @brief This function receives a message from a queue. + * The message is recieved by copy so a buffer adequate size must be provided. + * @param[in] queue: The handle to the queue from which the message is to be received. + * @param[in] message: The pointer to the buffer into which the received message will be copied. + * @param[in] timeout_ms: The maximum amout of time the task should block waiting for a message to + * receive should the queue be empty at the time of the call. + The time is defined in ms. + * @return 0: A message was successfully received from the queue. + * @return -1: No message was received from the queue. + */ +int rtw_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms ); + +/** + * @brief Delete a queue - freeing all the memory allocated for storing of messages placed on the queue. + * @param[in] queue: The handle to the queue to be deleted. + * @return 0: The queue was successfully deleted. + * @return -1: The queue was not empty so cannot be deleted. + */ +int rtw_deinit_xqueue( _xqueue* queue ); + +/** + * @brief This function creates a new queue instance. + * @param[in] pqueue: The handle to the newly created queue. + * @return None + */ +void rtw_init_queue(_queue *pqueue); +void rtw_deinit_queue(_queue *pqueue); +u32 rtw_is_queue_empty(_queue *pqueue); + +/** + * @brief This function tests whether the queue is empty. + * @param[in] pqueue: The handle to the queue to be tested. + * @return None + */ +u32 rtw_queue_empty(_queue *pqueue); + +/** + * @brief This function tests whether the "pelement" is at the "queue". + * @param[in] queue: The pointer to the queue that to be tested. + * @param[in] pelement: The element that to be tested. + * @return _TRUE/_FALSE + */ +u32 rtw_end_of_queue_search(_list *queue, _list *pelement); +_list* rtw_get_queue_head(_queue *queue); +/*************************** End Queues *******************************/ + +/*************************** Time Management *******************************/ + +/** + * @brief Get the count of ticks since the vTaskStartScheduler was called. + * @return The count of ticks since the vTaskStartScheduler was called. + */ +u32 rtw_get_current_time(void); + +/** + * @brief Convert system time to milliseconds. + * @param[in] systime: The system time to be converted. + * @return : The milliseconds that converted by the system time. + */ +u32 rtw_systime_to_ms(u32 systime); + +/** + * @brief Convert system time to seconds. + * @param[in] systime: The system time to be converted. + * @return : The seconds that converted by the system time. + */ +u32 rtw_systime_to_sec(u32 systime); + +/** + * @brief Convert milliseconds to system time. + * @param[in] systime: The milliseconds to be converted. + * @return : The system time that converted by the milliseconds. + */ +u32 rtw_ms_to_systime(u32 ms); + +/** + * @brief Convert seconds to system time. + * @param[in] systime: The seconds to be converted. + * @return : The system time that converted by the seconds. + */ +u32 rtw_sec_to_systime(u32 sec); + +/** + * @brief Get the passing time from the "start" in milliseconds. + * @param[in] start: The start time which is in system time format. + * @return : The passing time from "start" in milliseconds. + */ +s32 rtw_get_passing_time_ms(u32 start); + +/** + * @brief Get the interval time from the "start" to "end" in milliseconds. + * @param[in] start: The start time which is in system time format. + * @param[in] end: The end time which is in system time format. + * @return : The interval time from "start" to "end" in milliseconds. + */ +s32 rtw_get_time_interval_ms(u32 start, u32 end); +/*************************** End Time Management *******************************/ + +/** + * @brief This function suspends execution of the calling thread for "ms" milliseconds. + * @param[in] ms: The time that the function sleep in milliseconds + * @return None +*/ +void rtw_msleep_os(int ms); + +/** + * @brief This function suspends execution of the calling thread for "us" microseconds. + * @param[in] ms: The time that the function sleep in microseconds + * @return None +*/ +void rtw_usleep_os(int us); + +/** + * @brief This function converts the initial portion of the string to integer. + * @param[in] s: The pointer to the string to be converted. + * @return The converted value. +*/ +u32 rtw_atoi(u8* s); + +/** + * @brief This function delays a task for the giving time in milliseconds. + * @param[in] ms: The amount of time, in milliseconds, that the calling task should block. + * @return None +*/ +void rtw_mdelay_os(int ms); + +/** + * @brief This function delays a task for the giving time in microseconds. + * @param[in] ms: The amount of time, in microseconds, that the calling task should block. + * @return None +*/ +void rtw_udelay_os(int us); + +/** + * @brief This function for forcing a context switch. + * @return None +*/ +void rtw_yield_os(void); + +/*************************** ATOMIC Integer *******************************/ + +/** + * @brief This function atomically sets the value of the variable. + * @param[in] v: Pointer of type atomic_t that to be set value. + * @param[in] i: Required value. + * @return None + * @note The guaranteed useful range of an atomic_t is only 24 bits. +*/ +void ATOMIC_SET(ATOMIC_T *v, int i); + +/** + * @brief This function atomically reads the value of the variable. + * @param[in] v: Pointer of type atomic_t that to be read. + * @return The value of the variable. + * @note The guaranteed useful range of an atomic_t is only 24 bits. +*/ +int ATOMIC_READ(ATOMIC_T *v); + +/** + * @brief This function adds "i" to the contained "v". + * @param[in] v: Pointer of type atomic_t. + * @param[in] i: value to add. + * @return None +*/ +void ATOMIC_ADD(ATOMIC_T *v, int i); + +/** + * @brief This function subtracts "i" from th econtained "v". + * @param[in] v: Pointer of type atomic_t. + * @param[in] i: value to subtract. + * @return None +*/ +void ATOMIC_SUB(ATOMIC_T *v, int i); + +/** + * @brief This function adds 1 to the contained "v". + * @param[in] v: Pointer of type atomic_t. + * @return None +*/ +void ATOMIC_INC(ATOMIC_T *v); + +/** + * @brief This function subtracts 1 from th econtained "v". + * @param[in] v: Pointer of type atomic_t. + * @return None +*/ +void ATOMIC_DEC(ATOMIC_T *v); + +/** + * @brief This function adds "i" to the contained "v" and returns the result. + * @param[in] v: Pointer of type atomic_t. + * @param[in] i: value to add. + * @return None +*/ +int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i); + +/** + * @brief This function subtracts "i" from th econtained "v" and returns the result. + * @param[in] v: Pointer of type atomic_t. + * @param[in] i: value to subtract. + * @return None +*/ +int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i); + +/** + * @brief This function adds 1 to the contained "v" and returns the result. + * @param[in] v: Pointer of type atomic_t. + * @return None +*/ +int ATOMIC_INC_RETURN(ATOMIC_T *v); + +/** + * @brief This function subtracts 1 from th econtained "v" and returns the result. + * @param[in] v: Pointer of type atomic_t. + * @return None +*/ +int ATOMIC_DEC_RETURN(ATOMIC_T *v); + +/** + * @brief This function subtracts 1 from th econtained "v" and test if the result equals 0. + * @param[in] v: Pointer of type atomic_t. + * @return 0: The result after subtracting 1 is 0 + * @return -1: The result after subtracting 1 is not 0 +*/ +int ATOMIC_DEC_AND_TEST(ATOMIC_T *v); +/*************************** End ATOMIC *******************************/ + +u64 rtw_modular64(u64 x, u64 y); + +/** + * @brief This function generates random bytes. + * @param[in] dst: The pointer to the buffer to store the random bytes. + * @param[in] size: The size of the random bytes. + * @return 0 +*/ +int rtw_get_random_bytes(void* dst, u32 size); + +/** + * @brief This function gets the available heap size. + * @return The value of the available heap size. +*/ +u32 rtw_getFreeHeapSize(void); + +void flush_signals_thread(void); + +/** + * @brief This function indicates that the WLAN needs to stay on which means cannot go into power saving mode. + * @return None + * @note Defining configUSE_WAKELOCK_PMU 1 in "FreeRTOSConfig.h" needs to be done before compiling, + * or this API won't be effective. + */ +void rtw_acquire_wakelock(void); + +/** + * @brief This function indicates that the WLAN does not need to stay on which means can go into power saving mode. + * @return None + * @note Defining configUSE_WAKELOCK_PMU 1 in "FreeRTOSConfig.h" needs to be done before compiling, + * or this API won't be effective. + */ +void rtw_release_wakelock(void); +void rtw_wakelock_timeout(u32 timeout); + +/*********************************** Thread related *****************************************/ + +/** + * @brief This function creates a new task and adds it to the list of tasks that are ready to run. + * @param[in] task: The task stucture which will store the task related infomation. + * @param[in] name: A descriptive name for the task. + * @param[in] stack_size: The size of the task stack specified as the variables the stack can hold. + * @param[in] priority: The priority at which the task should run. + * @param[in] func: The task entry function. + * @param[in] thctx: The pointer that will be used as the parameter for the task being created. + * @return pdPASS: The task was successfully created and added to a ready list. + * @return other error code defined in the file errors.h. + * @note For the task name, please do not use "rtw_little_wifi_mcu_thread", "rtw_check_in_req_state_thread", + "rtw_TDMA_change_state_thread", "xmit_thread", "recv_thread", "rtw_recv_tasklet", "rtw_xmit_tasklet", + "rtw_interrupt_thread", "cmd_thread", "usb_init", "MSC_BULK_CMD" and "MSC_BULK_DATA". + */ +int rtw_create_task(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx); + +/** + * @brief This function deletes a task. + * @param[in] task: The task stucture which will be deleted. + * @return None + */ +void rtw_delete_task(struct task_struct * task); + +/** + * @brief This function wake up a task. + * @param[in] task: The task stucture which will be waked up. + * @return None + */ +void rtw_wakeup_task(struct task_struct *task); + +/** + * @brief This function creates a new worker thread. + * @param[in] worker_thread: The pointer to the worker thread stucture. + * @param[in] priority: The priority of the thread. + * @param[in] stack_size: The size of the thread stack specified as the variables the stack can hold. + * @param[in] event_queue_size: The queue size of events. + * @return SUCCESS/FAIL. + */ +int rtw_create_worker_thread( rtw_worker_thread_t* worker_thread, u8 priority, u32 stack_size, u32 event_queue_size ); + +/** + * @brief This function deletes a worker thread. + * @param[in] worker_thread: The pointer to the worker thread stucture to be deleted. + * @return SUCCESS/FAIL. + */ +int rtw_delete_worker_thread( rtw_worker_thread_t* worker_thread ); + +#if 0 //TODO +void rtw_init_delayed_work(struct delayed_work *dwork, work_func_t func, const char *name); +void rtw_deinit_delayed_work(struct delayed_work *dwork); +int rtw_queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, u32 delay, void* context); +BOOLEAN rtw_cancel_delayed_work(struct delayed_work *dwork); +#endif + +/** + * @brief This function prints the name of the thread in DBG_INFO. + * @param[in] name: The name of the thread. + * @return None + */ +void rtw_thread_enter(char *name); + +/** + * @brief This function exits the calling thread. + * @return None + */ +void rtw_thread_exit(void); + +/** + * @brief This function gets the scheduler state of the calling thread. + * @return OS_SCHEDULER_NOT_STARTED + * @return OS_SCHEDULER_RUNNING + * @return OS_SCHEDULER_SUSPENDED + */ +u8 rtw_get_scheduler_state(void); + +/*************************** End Threads *******************************/ +#ifdef PLATFORM_LINUX +#define rtw_warn_on(condition) WARN_ON(condition) +#else +#define rtw_warn_on(condition) do {} while (0) +#endif + +/*************************** Timers *******************************/ + +/** + * @brief This function creates a new software timer instance. + * @param[in] pcTimerName: A text name that is assigned to the timer. + * @param[in] xTimerPeriodInTicks: The timer period which is defined in tick periods. + * @param[in] uxAutoReload: If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * @param[in] pvTimerID: An identifier that is assigned to the timer being created. + * @param[in] pxCallbackFunction: The function to call when the timer expires. + * @return If the timer is successfully create then a handle to the newly + * created timer is returned. If the timer cannot be created, then 0 is returned. + */ +_timerHandle rtw_timerCreate( const signed char *pcTimerName, + osdepTickType xTimerPeriodInTicks, + u32 uxAutoReload, + void * pvTimerID, + TIMER_FUN pxCallbackFunction ); + +/** + * @brief This function deletes a timer that was previously created using rtw_timerCreate. + * @param[in] xTimer: The handle of the timer being deleted. + * @param[in] xBlockTime: Specifies th etime, in ticks, that the calling task should be held in the Blocked + * State to wait for the delete command to be successfully sent to the timer command queue, + * should the queue already be full when rtw_timerDelete was called. + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. + */ +u32 rtw_timerDelete( _timerHandle xTimer, osdepTickType xBlockTime ); + +/** + * @brief This function queries a timer to see if it is active or dormant. + * @param[in] xTimer: The timer being queried. + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * @note A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + */ +u32 rtw_timerIsTimerActive( _timerHandle xTimer ); + +/** + * @brief This function stops a timer that was previously started. + * @param[in] xTimer: The handle of the timer being stopped. + * @param[in] xBlockTime: Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * rtw_timerStop() was called. + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. + */ +u32 rtw_timerStop( _timerHandle xTimer, osdepTickType xBlockTime ); + +/** + * @brief This function changes the period of a timer that was previously created. + * @param[in] xTimer: The handle of the timer that is having its period changed. + * @param[in] xNewPeriod: The new period for xTimer. + * @param[in] xBlockTime: Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when rtw_timerChangePeriod() was called. + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. + */ +u32 rtw_timerChangePeriod( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepTickType xBlockTime ); + +void *rtw_timerGetID( _timerHandle xTimer ); + +u32 rtw_timerStart( _timerHandle xTimer, osdepTickType xBlockTime ); + +u32 rtw_timerStartFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + +u32 rtw_timerStopFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + +u32 rtw_timerResetFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + +u32 rtw_timerChangePeriodFromISR( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + +u32 rtw_timerReset( _timerHandle xTimer, + osdepTickType xBlockTime ); + + +/*************************** End Timers *******************************/ +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr))) + +#define time_after(a,b) ((long)(b) - (long)(a) < 0) +#define time_before(a,b) time_after(b,a) +#define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) +#define time_before_eq(a,b) time_after_eq(b,a) + +#define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) +#define RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) + +__inline static u32 _RND4(u32 sz) +{ + u32 val; + + val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; + + return val; +} + +__inline static u32 _RND8(u32 sz) +{ + u32 val; + + val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; + + return val; +} + +__inline static u32 _RND128(u32 sz) +{ + u32 val; + + val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; + + return val; +} + +__inline static u32 _RND256(u32 sz) +{ + u32 val; + + val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; + + return val; +} + +__inline static u32 _RND512(u32 sz) +{ + u32 val; + + val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; + + return val; +} + +__inline static u32 bitshift(u32 bitmask) +{ + u32 i; + + for (i = 0; i <= 31; i++) + if (((bitmask>>i) & 0x1) == 1) break; + + return i; +} + +/* Macros for handling unaligned memory accesses */ + +#define RTW_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1])) +#define RTW_PUT_BE16(a, val) \ + do { \ + (a)[0] = ((u16) (val)) >> 8; \ + (a)[1] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0])) +#define RTW_PUT_LE16(a, val) \ + do { \ + (a)[1] = ((u16) (val)) >> 8; \ + (a)[0] = ((u16) (val)) & 0xff; \ + } while (0) + +#define RTW_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \ + ((u32) (a)[2])) +#define RTW_PUT_BE24(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[2] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \ + (((u32) (a)[2]) << 8) | ((u32) (a)[3])) +#define RTW_PUT_BE32(a, val) \ + do { \ + (a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[3] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \ + (((u32) (a)[1]) << 8) | ((u32) (a)[0])) +#define RTW_PUT_LE32(a, val) \ + do { \ + (a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \ + (a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \ + (a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \ + (a)[0] = (u8) (((u32) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \ + (((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \ + (((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \ + (((u64) (a)[6]) << 8) | ((u64) (a)[7])) +#define RTW_PUT_BE64(a, val) \ + do { \ + (a)[0] = (u8) (((u64) (val)) >> 56); \ + (a)[1] = (u8) (((u64) (val)) >> 48); \ + (a)[2] = (u8) (((u64) (val)) >> 40); \ + (a)[3] = (u8) (((u64) (val)) >> 32); \ + (a)[4] = (u8) (((u64) (val)) >> 24); \ + (a)[5] = (u8) (((u64) (val)) >> 16); \ + (a)[6] = (u8) (((u64) (val)) >> 8); \ + (a)[7] = (u8) (((u64) (val)) & 0xff); \ + } while (0) + +#define RTW_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \ + (((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \ + (((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \ + (((u64) (a)[1]) << 8) | ((u64) (a)[0])) + +struct osdep_service_ops { + u8* (*rtw_vmalloc)(u32 sz); + u8* (*rtw_zvmalloc)(u32 sz); + void (*rtw_vmfree)(u8 *pbuf, u32 sz); + u8* (*rtw_malloc)(u32 sz); + u8* (*rtw_zmalloc)(u32 sz); + void (*rtw_mfree)(u8 *pbuf, u32 sz); + void (*rtw_memcpy)(void* dst, void* src, u32 sz); + int (*rtw_memcmp)(void *dst, void *src, u32 sz); + void (*rtw_memset)(void *pbuf, int c, u32 sz); + void (*rtw_init_sema)(_sema *sema, int init_val); + void (*rtw_free_sema)(_sema *sema); + void (*rtw_up_sema)(_sema *sema); + void (*rtw_up_sema_from_isr)(_sema *sema); + u32 (*rtw_down_timeout_sema)(_sema *sema, u32 timeout); + void (*rtw_mutex_init)(_mutex *pmutex); + void (*rtw_mutex_free)(_mutex *pmutex); + void (*rtw_mutex_get)(_mutex *pmutex); + int (*rtw_mutex_get_timeout)(_mutex *pmutex, u32 timeout_ms); + void (*rtw_mutex_put)(_mutex *pmutex); + void (*rtw_enter_critical)(_lock *plock, _irqL *pirqL); + void (*rtw_exit_critical)(_lock *plock, _irqL *pirqL); + void (*rtw_enter_critical_from_isr)(_lock *plock, _irqL *pirqL); + void (*rtw_exit_critical_from_isr)(_lock *plock, _irqL *pirqL); + void (*rtw_enter_critical_bh)(_lock *plock, _irqL *pirqL); + void (*rtw_exit_critical_bh)(_lock *plock, _irqL *pirqL); + int (*rtw_enter_critical_mutex)(_mutex *pmutex, _irqL *pirqL); + void (*rtw_exit_critical_mutex)(_mutex *pmutex, _irqL *pirqL); + void (*rtw_spinlock_init)(_lock *plock); + void (*rtw_spinlock_free)(_lock *plock); + void (*rtw_spin_lock)(_lock *plock); + void (*rtw_spin_unlock)(_lock *plock); + void (*rtw_spinlock_irqsave)(_lock *plock, _irqL *irqL); + void (*rtw_spinunlock_irqsave)(_lock *plock, _irqL *irqL); + int (*rtw_init_xqueue)( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages ); + int (*rtw_push_to_xqueue)( _xqueue* queue, void* message, u32 timeout_ms ); + int (*rtw_pop_from_xqueue)( _xqueue* queue, void* message, u32 timeout_ms ); + int (*rtw_deinit_xqueue)( _xqueue* queue ); + u32 (*rtw_get_current_time)(void); + u32 (*rtw_systime_to_ms)(u32 systime); + u32 (*rtw_systime_to_sec)(u32 systime); + u32 (*rtw_ms_to_systime)(u32 ms); + u32 (*rtw_sec_to_systime)(u32 sec); + void (*rtw_msleep_os)(int ms); + void (*rtw_usleep_os)(int us); + void (*rtw_mdelay_os)(int ms); + void (*rtw_udelay_os)(int us); + void (*rtw_yield_os)(void); + void (*ATOMIC_SET)(ATOMIC_T *v, int i); + int (*ATOMIC_READ)(ATOMIC_T *v); + void (*ATOMIC_ADD)(ATOMIC_T *v, int i); + void (*ATOMIC_SUB)(ATOMIC_T *v, int i); + void (*ATOMIC_INC)(ATOMIC_T *v); + void (*ATOMIC_DEC)(ATOMIC_T *v); + int (*ATOMIC_ADD_RETURN)(ATOMIC_T *v, int i); + int (*ATOMIC_SUB_RETURN)(ATOMIC_T *v, int i); + int (*ATOMIC_INC_RETURN)(ATOMIC_T *v); + int (*ATOMIC_DEC_RETURN)(ATOMIC_T *v); + u64 (*rtw_modular64)(u64 x, u64 y); + int (*rtw_get_random_bytes)(void* dst, u32 size); + u32 (*rtw_getFreeHeapSize)(void); + int (*rtw_create_task)(struct task_struct *task, const char *name, u32 stack_size, u32 priority, thread_func_t func, void *thctx); + void (*rtw_delete_task)(struct task_struct *task); + void (*rtw_wakeup_task)(struct task_struct *task); + +#if 0 //TODO + void (*rtw_init_delayed_work)(struct delayed_work *dwork, work_func_t func, const char *name); + void (*rtw_deinit_delayed_work)(struct delayed_work *dwork); + int (*rtw_queue_delayed_work)(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay, void* context); + BOOLEAN (*rtw_cancel_delayed_work)(struct delayed_work *dwork); +#endif + void (*rtw_thread_enter)(char *name); + void (*rtw_thread_exit)(void); + _timerHandle (*rtw_timerCreate)( const signed char *pcTimerName, + osdepTickType xTimerPeriodInTicks, + u32 uxAutoReload, + void * pvTimerID, + TIMER_FUN pxCallbackFunction ); + u32 (*rtw_timerDelete)( _timerHandle xTimer, + osdepTickType xBlockTime ); + u32 (*rtw_timerIsTimerActive)( _timerHandle xTimer ); + u32 (*rtw_timerStop)( _timerHandle xTimer, + osdepTickType xBlockTime ); + u32 (*rtw_timerChangePeriod)( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepTickType xBlockTime ); + void* (*rtw_timerGetID)( _timerHandle xTimer ); + u32 (*rtw_timerStart)( _timerHandle xTimer, + osdepTickType xBlockTime ); + u32 (*rtw_timerStartFromISR)( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + + u32 (*rtw_timerStopFromISR)( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + + u32 (*rtw_timerResetFromISR)( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + + u32 (*rtw_timerChangePeriodFromISR)( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ); + + u32 (*rtw_timerReset)( _timerHandle xTimer, + osdepTickType xBlockTime ); + + void (*rtw_acquire_wakelock)(void); + void (*rtw_release_wakelock)(void); + void (*rtw_wakelock_timeout)(u32 timeoutMs); + u8 (*rtw_get_scheduler_state)(void); +}; + +/*\@}*/ + +#endif //#ifndef __OSDEP_SERVICE_H_ +//----------------------------------------------------------------------------// diff --git a/USDK/component/os/os_dep/include/tcm_heap.h b/USDK/component/os/os_dep/include/tcm_heap.h new file mode 100644 index 0000000..61065b3 --- /dev/null +++ b/USDK/component/os/os_dep/include/tcm_heap.h @@ -0,0 +1,74 @@ +#ifndef STRUCT_HEAP_H +#define STRUCT_HEAP_H + +//#include +#include +#include + + + +#define TCM_HEAP_SIZE (42*1024) // min size + +// MAX_BACKUP_SIZE in hal_soc_ps_monitor = 129*4, 0x1FFFFFFC - 129*4 = 0x1FFFFD18 ! +#define tcm_heap_size ((0x20000000 - (u32)&tcm_heap - 768 + sizeof(heap_buf_t) - 1)/sizeof(heap_buf_t))*sizeof(heap_buf_t) + +/* NOTE: struct size must be a 2's power! */ +typedef struct _MemChunk +{ + struct _MemChunk *next; + int size; +} MemChunk; + +typedef MemChunk heap_buf_t; + +/// A heap +typedef struct Heap +{ + struct _MemChunk *FreeList; ///< Head of the free list +} Heap; + +/** + * Utility macro to allocate a heap of size \a size. + * + * \param name Variable name for the heap. + * \param size Heap size in bytes. + */ +#define HEAP_DEFINE_BUF(name, size) \ + heap_buf_t name[((size) + sizeof(heap_buf_t) - 1) / sizeof(heap_buf_t)] + +/// Initialize \a heap within the buffer pointed by \a memory which is of \a size bytes +void tcm_heap_init(void); + +/// Allocate a chunk of memory of \a size bytes from the heap +// void *tcm_heap_allocmem(int size); + +/// Free a chunk of memory of \a size bytes from the heap +// void tcm_heap_freemem(void *mem, int size); + +int tcm_heap_freeSpace(void); + +#define HNEW(heap, type) \ + (type*)tcm_heap_allocmem(heap, sizeof(type)) + +#define HNEWVEC(heap, type, nelem) \ + (type*)tcm_heap_allocmem(heap, sizeof(type) * (nelem)) + +#define HDELETE(heap, type, mem) \ + tcm_heap_freemem(heap, mem, sizeof(type)) + +#define HDELETEVEC(heap, type, nelem, mem) \ + tcm_heap_freemem(heap, mem, sizeof(type) * (nelem)) + +extern HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE); + +/** + * \name Compatibility interface with C standard library + * \{ + */ +void *tcm_heap_malloc(int size); +void *tcm_heap_calloc(int size); +void tcm_heap_free(void * mem); +void tcm_heap_dump(void); +/** \} */ + +#endif /* STRUCT_HEAP_H */ diff --git a/USDK/component/os/os_dep/osdep_service.c b/USDK/component/os/os_dep/osdep_service.c new file mode 100644 index 0000000..683ff23 --- /dev/null +++ b/USDK/component/os/os_dep/osdep_service.c @@ -0,0 +1,1308 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + ******************************************************************************/ + +#include +#define OSDEP_DBG(x, ...) do {} while(0) + +extern struct osdep_service_ops osdep_service; + +#ifdef CONFIG_LITTLE_ENDIAN +u16 +_htons(u16 n) +{ + return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); +} + +u16 +_ntohs(u16 n) +{ + return _htons(n); +} + +u32 +_htonl(u32 n) +{ + return ((n & 0xff) << 24) | + ((n & 0xff00) << 8) | + ((n & 0xff0000UL) >> 8) | + ((n & 0xff000000UL) >> 24); +} + +u32 +_ntohl(u32 n) +{ + return _htonl(n); +} + +#endif /* CONFIG_LITTLE_ENDIAN */ +/* +* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE +* @return: one of RTW_STATUS_CODE +*/ +int RTW_STATUS_CODE(int error_code) +{ + if(error_code >= 0) + return _SUCCESS; + + return _FAIL; +} + +u32 rtw_atoi(u8* s) +{ + int num=0,flag=0; + int i; + + for(i=0;i<=strlen((char *)s);i++) + { + if(s[i] >= '0' && s[i] <= '9') + num = num * 10 + s[i] -'0'; + else if(s[0] == '-' && i==0) + flag =1; + else + break; + } + + if(flag == 1) + num = num * -1; + + return(num); +} +void *tcm_heap_malloc(int size); +void *tcm_heap_calloc(int size); +u8* _rtw_vmalloc(u32 sz) +{ + u8 *pbuf = NULL; +#if CONFIG_USE_TCM_HEAP + pbuf = tcm_heap_malloc(sz); +#endif + if(pbuf==NULL){ + if(osdep_service.rtw_vmalloc) { + pbuf = osdep_service.rtw_vmalloc(sz); + } else + OSDEP_DBG("Not implement osdep service: rtw_vmalloc"); + } + return pbuf; +} + +u8* _rtw_zvmalloc(u32 sz) +{ + u8 *pbuf = NULL; +#if CONFIG_USE_TCM_HEAP + pbuf = tcm_heap_calloc(sz); +#endif + if(pbuf==NULL){ + if(osdep_service.rtw_zvmalloc) { + pbuf = osdep_service.rtw_zvmalloc(sz); + } else + OSDEP_DBG("Not implement osdep service: rtw_zvmalloc"); + } + return pbuf; +} + +void _rtw_vmfree(u8 *pbuf, u32 sz) +{ + +#if CONFIG_USE_TCM_HEAP + if( (u32)pbuf > 0x1FFF0000 && (u32)pbuf < 0x20000000 ) + tcm_heap_free(pbuf); + else +#endif + { + if(osdep_service.rtw_vmfree) { + osdep_service.rtw_vmfree(pbuf, sz); + } else + OSDEP_DBG("Not implement osdep service: rtw_vmfree"); + } +} + +u8* _rtw_malloc(u32 sz) +{ + if(osdep_service.rtw_malloc) { + u8 *pbuf = osdep_service.rtw_malloc(sz); + return pbuf; + } else + OSDEP_DBG("Not implement osdep service: rtw_malloc"); + + return NULL; +} + +u8* _rtw_zmalloc(u32 sz) +{ + if(osdep_service.rtw_zmalloc) { + u8 *pbuf = osdep_service.rtw_zmalloc(sz); + return pbuf; + } else + OSDEP_DBG("Not implement osdep service: rtw_zmalloc"); + + return NULL; +} + +void _rtw_mfree(u8 *pbuf, u32 sz) +{ + if(osdep_service.rtw_mfree) { + osdep_service.rtw_mfree(pbuf, sz); + } else + OSDEP_DBG("Not implement osdep service: rtw_mfree"); +} + +#ifdef CONFIG_MEM_MONITOR +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK +_list mem_table; +int mem_used_num; +#endif +int min_free_heap_size; + +void init_mem_monitor(_list *pmem_table, int *used_num) +{ +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + rtw_init_listhead(pmem_table); + *used_num = 0; +#endif + min_free_heap_size = rtw_getFreeHeapSize(); +} + +void deinit_mem_monitor(_list *pmem_table, int *used_num) +{ +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + _list *plist; + struct mem_entry *mem_entry; + + if(*used_num > 0) + DBG_ERR("Have %d mem_entry kept in monitor", *used_num); + else + DBG_INFO("No mem_entry kept in monitor"); + + save_and_cli(); + + while (rtw_end_of_queue_search(pmem_table, get_next(pmem_table)) == _FALSE) { + plist = get_next(pmem_table); + mem_entry = LIST_CONTAINOR(plist, struct mem_entry, list); + + DBG_ERR("Not release memory at %p with size of %d", mem_entry->ptr, mem_entry->size); + + rtw_list_delete(plist); + _rtw_mfree((u8 *) mem_entry, sizeof(struct mem_entry)); + } + + restore_flags(); +#endif +} + +void add_mem_usage(_list *pmem_table, void *ptr, int size, int *used_num, int flag) +{ + int free_heap_size = rtw_getFreeHeapSize(); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + struct mem_entry *mem_entry; +#endif + if(ptr == NULL) { + DBG_ERR("Catch a mem alloc fail with size of %d, current heap free size = %d", size, free_heap_size); + return; + } + else{ + if(flag == MEM_MONITOR_FLAG_WPAS) + DBG_INFO("Alloc memory at %p with size of %d", ptr, size); + else + DBG_INFO("Alloc memory at %p with size of %d", ptr, size); + } +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + mem_entry = (struct mem_entry *) _rtw_malloc(sizeof(struct mem_entry)); + + if(mem_entry == NULL) { + DBG_ERR("Fail to alloc mem_entry"); + return; + } + + memset(mem_entry, 0, sizeof(struct mem_entry)); + mem_entry->ptr = ptr; + mem_entry->size = size; + + save_and_cli(); + rtw_list_insert_head(&mem_entry->list, pmem_table); + restore_flags(); + + *used_num ++; +#endif + if(min_free_heap_size > free_heap_size) + min_free_heap_size = free_heap_size; +} + +void del_mem_usage(_list *pmem_table, void *ptr, int *used_num, int flag) +{ +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + _list *plist; + struct mem_entry *mem_entry = NULL; + + if(ptr == NULL) + return; + + if(flag == MEM_MONITOR_FLAG_WPAS) + DBG_INFO("Free memory at %p", ptr); + else + DBG_INFO("Free memory at %p", ptr); + + save_and_cli(); + + plist = get_next(pmem_table); + while ((rtw_end_of_queue_search(pmem_table, plist)) == _FALSE) + { + mem_entry = LIST_CONTAINOR(plist, struct mem_entry, list); + if(mem_entry->ptr == ptr) { + rtw_list_delete(plist); + break; + } + plist = get_next(plist); + } + + restore_flags(); + + if(plist == pmem_table) + DBG_ERR("Fail to find the mem_entry in mem table"); + else { + *used_num --; + _rtw_mfree((u8 *) mem_entry, sizeof(struct mem_entry)); + } +#endif +} + +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK +int get_mem_usage(_list *pmem_table) +{ + _list *plist; + struct mem_entry *mem_entry; + int mem_usage = 0; + int entry_num = 0; + + save_and_cli(); + + if((plist = get_next(pmem_table)) == NULL) { + DBG_ERR("No mem table available\n"); + restore_flags(); + return 0; + } + + while (rtw_end_of_queue_search(pmem_table, plist) == _FALSE) { + entry_num ++; + mem_entry = LIST_CONTAINOR(plist, struct mem_entry, list); + mem_usage += mem_entry->size; + + DBG_INFO("size of mem_entry(%d)=%d\n", entry_num, mem_entry->size); + plist = get_next(plist); + } + + restore_flags(); + + DBG_INFO("Get %d mem_entry\n", entry_num); + + return mem_usage; +} +#endif + + +u8* rtw_vmalloc(u32 sz) +{ + u8 *pbuf = _rtw_vmalloc(sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + add_mem_usage(&mem_table, pbuf, sz, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif + return pbuf; +} + +u8* rtw_zvmalloc(u32 sz) +{ + u8 *pbuf = _rtw_zvmalloc(sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + add_mem_usage(&mem_table, pbuf, sz, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif + return pbuf; +} + +void rtw_vmfree(u8 *pbuf, u32 sz) +{ + _rtw_vmfree(pbuf, sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + del_mem_usage(&mem_table, pbuf, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + del_mem_usage(NULL, pbuf, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif +} + +u8* rtw_malloc(u32 sz) +{ + u8 *pbuf = _rtw_malloc(sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + add_mem_usage(&mem_table, pbuf, sz, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif + return pbuf; +} + +u8* rtw_zmalloc(u32 sz) +{ + u8 *pbuf = _rtw_zmalloc(sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + add_mem_usage(&mem_table, pbuf, sz, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif + return pbuf; +} + +void rtw_mfree(u8 *pbuf, u32 sz) +{ + _rtw_mfree(pbuf, sz); +#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK + del_mem_usage(&mem_table, pbuf, &mem_used_num, MEM_MONITOR_FLAG_WIFI_DRV); +#else + del_mem_usage(NULL, pbuf, NULL, MEM_MONITOR_FLAG_WIFI_DRV); +#endif +} +#endif + +void* rtw_malloc2d(int h, int w, int size) +{ + int j; + + void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size ); + if(a == NULL) + { + OSDEP_DBG("%s: alloc memory fail!\n", __FUNCTION__); + return NULL; + } + + for( j=0; jqueue)); + rtw_spinlock_init(&(pqueue->lock)); +} + +u32 rtw_queue_empty(_queue *pqueue) +{ + return (rtw_is_list_empty(&(pqueue->queue))); +} + + +u32 rtw_end_of_queue_search(_list *head, _list *plist) +{ + if (head == plist) + return _TRUE; + else + return _FALSE; +} + +#if 1 +void rtw_spinlock_init(_lock *plock) +{ + if(osdep_service.rtw_spinlock_init) + osdep_service.rtw_spinlock_init(plock); + else + OSDEP_DBG("Not implement osdep service: rtw_spinlock_init"); +} + +void rtw_spinlock_free(_lock *plock) +{ + if(osdep_service.rtw_spinlock_free) + osdep_service.rtw_spinlock_free(plock); + else + OSDEP_DBG("Not implement osdep service: rtw_spinlock_free"); +} + +void rtw_spin_lock(_lock *plock) +{ + if(osdep_service.rtw_spin_lock) + osdep_service.rtw_spin_lock(plock); + else + OSDEP_DBG("Not implement osdep service: rtw_spin_lock"); +} + +void rtw_spin_unlock(_lock *plock) +{ + if(osdep_service.rtw_spin_unlock) + osdep_service.rtw_spin_unlock(plock); + else + OSDEP_DBG("Not implement osdep service: rtw_spin_unlock"); +} + +void rtw_spinlock_irqsave(_lock *plock, _irqL *irqL) +{ + if(osdep_service.rtw_spinlock_irqsave) + osdep_service.rtw_spinlock_irqsave(plock, irqL); + else + OSDEP_DBG("Not implement osdep service: rtw_spinlock_irqsave"); +} + +void rtw_spinunlock_irqsave(_lock *plock, _irqL *irqL) +{ + if(osdep_service.rtw_spinunlock_irqsave) + osdep_service.rtw_spinunlock_irqsave(plock, irqL); + else + OSDEP_DBG("Not implement osdep service: rtw_spinunlock_irqsave"); +} +#endif + +int rtw_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages ) +{ + if(osdep_service.rtw_init_xqueue) + return (int)osdep_service.rtw_init_xqueue(queue, name, message_size, number_of_messages); + else + OSDEP_DBG("Not implement osdep service: rtw_init_xqueue"); + + return FAIL; +} + +int rtw_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ + if(osdep_service.rtw_push_to_xqueue) + return (int)osdep_service.rtw_push_to_xqueue(queue, message, timeout_ms); + else + OSDEP_DBG("Not implement osdep service: rtw_push_to_xqueue"); + + return FAIL; +} + +int rtw_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ + if(osdep_service.rtw_pop_from_xqueue) + return (int)osdep_service.rtw_pop_from_xqueue(queue, message, timeout_ms); + else + OSDEP_DBG("Not implement osdep service: rtw_pop_from_xqueue"); + + return FAIL; +} + +int rtw_deinit_xqueue( _xqueue* queue ) +{ + if(osdep_service.rtw_deinit_xqueue) + return (int)osdep_service.rtw_deinit_xqueue(queue); + else + OSDEP_DBG("Not implement osdep service: rtw_deinit_xqueue"); + + return FAIL; +} + +#if 0 +void rtw_init_queue(_queue *pqueue) +{ + rtw_init_listhead(&(pqueue->queue)); + rtw_mutex_init(&(pqueue->lock)); +} + +void rtw_deinit_queue(_queue *pqueue) +{ + rtw_mutex_free(&(pqueue->lock)); +} + +u32 rtw_is_queue_empty(_queue *pqueue) +{ + return (rtw_is_list_empty(&(pqueue->queue))); +} + +u32 rtw_end_of_queue_search(_list *head, _list *plist) +{ + if (head == plist) + return _TRUE; + + return _FALSE; +} + +_list *rtw_get_queue_head(_queue *queue) +{ + return (&(queue->queue)); +} +#endif + +u32 rtw_get_current_time(void) +{ + if(osdep_service.rtw_get_current_time) + return osdep_service.rtw_get_current_time(); + else + OSDEP_DBG("Not implement osdep service: rtw_get_current_time"); + + return 0; +} + +u32 rtw_systime_to_ms(u32 systime) +{ + if(osdep_service.rtw_systime_to_ms) + return osdep_service.rtw_systime_to_ms(systime); + else + OSDEP_DBG("Not implement osdep service: rtw_systime_to_ms"); + + return 0; +} + +u32 rtw_systime_to_sec(u32 systime) +{ + if(osdep_service.rtw_systime_to_sec) + return osdep_service.rtw_systime_to_sec(systime); + else + OSDEP_DBG("Not implement osdep service: rtw_systime_to_sec"); + + return 0; +} + +u32 rtw_ms_to_systime(u32 ms) +{ + if(osdep_service.rtw_ms_to_systime) + return osdep_service.rtw_ms_to_systime(ms); + else + OSDEP_DBG("Not implement osdep service: rtw_ms_to_systime"); + + return 0; +} + +u32 rtw_sec_to_systime(u32 sec) +{ + if(osdep_service.rtw_sec_to_systime) + return osdep_service.rtw_sec_to_systime(sec); + else + OSDEP_DBG("Not implement osdep service: rtw_sec_to_systime"); + + return 0; +} + +// the input parameter start use the same unit as returned by rtw_get_current_time +s32 rtw_get_passing_time_ms(u32 start) +{ + return rtw_systime_to_ms(rtw_get_current_time() - start); +} + +s32 rtw_get_time_interval_ms(u32 start, u32 end) +{ + return rtw_systime_to_ms(end - start); +} + +void rtw_msleep_os(int ms) +{ + if(osdep_service.rtw_msleep_os) + osdep_service.rtw_msleep_os(ms); + else + OSDEP_DBG("Not implement osdep service: rtw_msleep_os"); +} + +void rtw_usleep_os(int us) +{ + if(osdep_service.rtw_usleep_os) + osdep_service.rtw_usleep_os(us); + else + OSDEP_DBG("Not implement osdep service: rtw_usleep_os"); +} + +void rtw_mdelay_os(int ms) +{ + if(osdep_service.rtw_mdelay_os) + osdep_service.rtw_mdelay_os(ms); + else + OSDEP_DBG("Not implement osdep service: rtw_mdelay_os"); +} + +void rtw_udelay_os(int us) +{ + if(osdep_service.rtw_udelay_os) + osdep_service.rtw_udelay_os(us); + else + OSDEP_DBG("Not implement osdep service: rtw_udelay_os"); +} + +void rtw_yield_os(void) +{ + if(osdep_service.rtw_yield_os) + osdep_service.rtw_yield_os(); + else + OSDEP_DBG("Not implement osdep service: rtw_yield_os"); +} + +void ATOMIC_SET(ATOMIC_T *v, int i) +{ + if(osdep_service.ATOMIC_SET) + osdep_service.ATOMIC_SET(v, i); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_SET"); +} + +int ATOMIC_READ(ATOMIC_T *v) +{ + if(osdep_service.ATOMIC_READ) + return osdep_service.ATOMIC_READ(v); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_READ"); + + return 0; +} + +void ATOMIC_ADD(ATOMIC_T *v, int i) +{ + if(osdep_service.ATOMIC_ADD) + osdep_service.ATOMIC_ADD(v, i); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_ADD"); +} + +void ATOMIC_SUB(ATOMIC_T *v, int i) +{ + if(osdep_service.ATOMIC_SUB) + osdep_service.ATOMIC_SUB(v, i); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_SUB"); +} + +void ATOMIC_INC(ATOMIC_T *v) +{ + if(osdep_service.ATOMIC_INC) + osdep_service.ATOMIC_INC(v); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_INC"); +} + +void ATOMIC_DEC(ATOMIC_T *v) +{ + if(osdep_service.ATOMIC_DEC) + osdep_service.ATOMIC_DEC(v); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_DEC"); +} + +int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i) +{ + if(osdep_service.ATOMIC_ADD_RETURN) + return osdep_service.ATOMIC_ADD_RETURN(v, i); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_ADD_RETURN"); + + return 0; +} + +int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i) +{ + if(osdep_service.ATOMIC_SUB_RETURN) + return osdep_service.ATOMIC_SUB_RETURN(v, i); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_SUB_RETURN"); + + return 0; +} + +int ATOMIC_INC_RETURN(ATOMIC_T *v) +{ + if(osdep_service.ATOMIC_INC_RETURN) + return osdep_service.ATOMIC_INC_RETURN(v); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_INC_RETURN"); + + return 0; +} + +int ATOMIC_DEC_RETURN(ATOMIC_T *v) +{ + if(osdep_service.ATOMIC_DEC_RETURN) + return osdep_service.ATOMIC_DEC_RETURN(v); + else + OSDEP_DBG("Not implement osdep service: ATOMIC_DEC_RETURN"); + + return 0; +} + +int ATOMIC_DEC_AND_TEST(ATOMIC_T *v) +{ + return ATOMIC_DEC_RETURN(v) == 0; +} + +u64 rtw_modular64(u64 x, u64 y) +{ + if(osdep_service.rtw_modular64) + return osdep_service.rtw_modular64(x, y); + else + OSDEP_DBG("Not implement osdep service: rtw_modular64"); + + return 0; +} + +int rtw_get_random_bytes(void* dst, u32 size) +{ + if(osdep_service.rtw_get_random_bytes) + return osdep_service.rtw_get_random_bytes(dst, size); + else + OSDEP_DBG("Not implement osdep service: rtw_get_random_bytes"); + + return 0; +} + +u32 rtw_getFreeHeapSize(void) +{ + if(osdep_service.rtw_getFreeHeapSize) + return osdep_service.rtw_getFreeHeapSize(); + else + OSDEP_DBG("Not implement osdep service: rtw_getFreeHeapSize"); + + return 0; +} + +int rtw_netif_queue_stopped(void *pnetdev) +{ + return 0; +} + +void rtw_netif_wake_queue(void *pnetdev) +{ +} + +void rtw_netif_start_queue(void *pnetdev) +{ +} + +void rtw_netif_stop_queue(void *pnetdev) +{ +} + +void flush_signals_thread(void) +{ +} + +void rtw_acquire_wakelock(void) +{ + if (osdep_service.rtw_acquire_wakelock) + osdep_service.rtw_acquire_wakelock(); + else + OSDEP_DBG("Not implement osdep service: rtw_acquire_wakelock"); +} + +void rtw_release_wakelock(void) +{ + if (osdep_service.rtw_release_wakelock) + osdep_service.rtw_release_wakelock(); + else + OSDEP_DBG("Not implement osdep service: rtw_release_wakelock"); +} + +void rtw_wakelock_timeout(u32 timeoutms) +{ + if (osdep_service.rtw_wakelock_timeout) + osdep_service.rtw_wakelock_timeout(timeoutms); + else + OSDEP_DBG("Not implement osdep service: rtw_wakelock_timeout"); +} + +int rtw_create_task(struct task_struct *task, const char *name, + u32 stack_size, u32 priority, thread_func_t func, void *thctx) +{ + if(osdep_service.rtw_create_task) + return osdep_service.rtw_create_task(task, name, stack_size, priority, func, thctx); + else + OSDEP_DBG("Not implement osdep service: rtw_create_task"); + return 1; +} +void rtw_delete_task(struct task_struct *task) +{ + if(osdep_service.rtw_delete_task) + osdep_service.rtw_delete_task(task); + else + OSDEP_DBG("Not implement osdep service: rtw_delete_task"); + + return; +} +void rtw_wakeup_task(struct task_struct *task) +{ + if(osdep_service.rtw_wakeup_task) + osdep_service.rtw_wakeup_task(task); + else + OSDEP_DBG("Not implement osdep service: rtw_wakeup_task"); + + return; +} + +static void worker_thread_main( void *arg ) +{ + rtw_worker_thread_t* worker_thread = (rtw_worker_thread_t*) arg; + + while ( 1 ) + { + rtw_event_message_t message; + + if ( rtw_pop_from_xqueue( &worker_thread->event_queue, &message, RTW_WAIT_FOREVER ) == SUCCESS ) + { + message.function(message.buf, message.buf_len, message.flags, message.user_data); + if(message.buf){ + //printf("\n!!!!!Free %p(%d)\n", message.buf, message.buf_len); + _rtw_mfree(message.buf, message.buf_len); + } + } + } +} + +int rtw_create_worker_thread( rtw_worker_thread_t* worker_thread, u8 priority, u32 stack_size, u32 event_queue_size ) +{ + if(NULL == worker_thread) + return FAIL; + + memset( worker_thread, 0, sizeof( *worker_thread ) ); + + if ( rtw_init_xqueue( &worker_thread->event_queue, "worker queue", sizeof(rtw_event_message_t), event_queue_size ) != SUCCESS ) + { + return FAIL; + } + + if ( !rtw_create_task( &worker_thread->thread, "worker thread", stack_size, priority, worker_thread_main, (void*) worker_thread ) ) + { + rtw_deinit_xqueue( &worker_thread->event_queue ); + return FAIL; + } + + return SUCCESS; +} + +int rtw_delete_worker_thread( rtw_worker_thread_t* worker_thread ) +{ + if(NULL == worker_thread) + return FAIL; + + rtw_deinit_xqueue( &worker_thread->event_queue ); + + rtw_delete_task(&worker_thread->thread); + + return SUCCESS; +} + +_timerHandle rtw_timerCreate( const signed char *pcTimerName, + osdepTickType xTimerPeriodInTicks, + u32 uxAutoReload, + void * pvTimerID, + TIMER_FUN pxCallbackFunction ) +{ + if(osdep_service.rtw_timerCreate) + return osdep_service.rtw_timerCreate(pcTimerName, xTimerPeriodInTicks, uxAutoReload, + pvTimerID, pxCallbackFunction); + else + OSDEP_DBG("Not implement osdep service: rtw_timerCreate"); + + return 0; +} + +u32 rtw_timerDelete( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + if(osdep_service.rtw_timerDelete) + return osdep_service.rtw_timerDelete( xTimer, xBlockTime ); + else + OSDEP_DBG("Not implement osdep service: rtw_timerDelete"); + + return 0; +} + +u32 rtw_timerIsTimerActive( _timerHandle xTimer ) +{ + if(osdep_service.rtw_timerIsTimerActive) + return osdep_service.rtw_timerIsTimerActive(xTimer); + else + OSDEP_DBG("Not implement osdep service: rtw_timerIsTimerActive"); + + return 0; +} + +u32 rtw_timerStop( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + if(osdep_service.rtw_timerStop) + return osdep_service.rtw_timerStop(xTimer, xBlockTime); + else + OSDEP_DBG("Not implement osdep service: rtw_timerStop"); + + return 0; +} + +u32 rtw_timerChangePeriod( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepTickType xBlockTime ) +{ + if(osdep_service.rtw_timerChangePeriod) + return osdep_service.rtw_timerChangePeriod(xTimer, xNewPeriod, xBlockTime); + else + OSDEP_DBG("Not implement osdep service: rtw_timerChangePeriod"); + + return 0; +} + +void *rtw_timerGetID( _timerHandle xTimer ) +{ + if(osdep_service.rtw_timerGetID) + return osdep_service.rtw_timerGetID(xTimer); + else + OSDEP_DBG("Not implement osdep service: rtw_timerGetID"); + + return NULL; +} + +u32 rtw_timerStart( _timerHandle xTimer, osdepTickType xBlockTime ) +{ + if(osdep_service.rtw_timerStart) + return osdep_service.rtw_timerStart(xTimer, xBlockTime); + else + OSDEP_DBG("Not implement osdep service: rtw_timerStart"); + + return 0; +} + +u32 rtw_timerStartFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + if(osdep_service.rtw_timerStartFromISR) + return osdep_service.rtw_timerStartFromISR(xTimer, pxHigherPriorityTaskWoken); + else + OSDEP_DBG("Not implement osdep service: rtw_timerStartFromISR"); + + return 0; +} + +u32 rtw_timerStopFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + if(osdep_service.rtw_timerStopFromISR) + return osdep_service.rtw_timerStopFromISR(xTimer, pxHigherPriorityTaskWoken); + else + OSDEP_DBG("Not implement osdep service: rtw_timerStopFromISR"); + + return 0; +} + +u32 rtw_timerResetFromISR( _timerHandle xTimer, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + if(osdep_service.rtw_timerResetFromISR) + return osdep_service.rtw_timerResetFromISR(xTimer, pxHigherPriorityTaskWoken); + else + OSDEP_DBG("Not implement osdep service: rtw_timerResetFromISR"); + + return 0; +} + +u32 rtw_timerChangePeriodFromISR( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepBASE_TYPE *pxHigherPriorityTaskWoken ) +{ + if(osdep_service.rtw_timerChangePeriodFromISR) + return osdep_service.rtw_timerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken); + else + OSDEP_DBG("Not implement osdep service: rtw_timerChangePeriodFromISR"); + + return 0; +} + +u32 rtw_timerReset( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ + if(osdep_service.rtw_timerReset) + return osdep_service.rtw_timerReset(xTimer, xBlockTime); + else + OSDEP_DBG("Not implement osdep service: rtw_timerReset"); + + return 0; +} + + +#if 0 //TODO +void rtw_init_delayed_work(struct delayed_work *dwork, work_func_t func, const char *name) +{ + if(osdep_service.rtw_init_delayed_work) + osdep_service.rtw_init_delayed_work(dwork, func, name); + else + OSDEP_DBG("Not implement osdep service: rtw_init_delayed_work"); + + return; +} + +void rtw_deinit_delayed_work(struct delayed_work *dwork) +{ + if(osdep_service.rtw_deinit_delayed_work) + osdep_service.rtw_deinit_delayed_work(dwork); + else + OSDEP_DBG("Not implement osdep service: rtw_deinit_delayed_work"); + + return; +} + +int rtw_queue_delayed_work(struct workqueue_struct *wq, + struct delayed_work *dwork, u32 delay, void* context) +{ + if(osdep_service.rtw_queue_delayed_work) + osdep_service.rtw_queue_delayed_work(wq, dwork, delay, context); + else + OSDEP_DBG("Not implement osdep service: rtw_queue_delayed_work"); + + return; +} + +BOOLEAN rtw_cancel_delayed_work(struct delayed_work *dwork) +{ + if(osdep_service.rtw_cancel_delayed_work) + osdep_service.rtw_cancel_delayed_work(dwork); + else + OSDEP_DBG("Not implement osdep service: rtw_cancel_delayed_work"); + + return; +} +#endif +void rtw_thread_enter(char *name) +{ + if(osdep_service.rtw_thread_enter) + osdep_service.rtw_thread_enter(name); + else + OSDEP_DBG("Not implement osdep service: rtw_thread_enter"); +} + +void rtw_thread_exit() +{ + if(osdep_service.rtw_thread_exit) + osdep_service.rtw_thread_exit(); + else + OSDEP_DBG("Not implement osdep service: rtw_thread_exit"); +} + +u8 rtw_get_scheduler_state() +{ + // OS_SCHEDULER_NOT_STARTED 0 + // OS_SCHEDULER_RUNNING 1 + // OS_SCHEDULER_SUSPENDED 2 + // OS_SCHEDULER_UNREACHABLE 3 + if(osdep_service.rtw_get_scheduler_state) + return osdep_service.rtw_get_scheduler_state(); + else{ + OSDEP_DBG("Not implement osdep service: rtw_get_scheduler_state"); + return 3; + } +} diff --git a/USDK/component/os/os_dep/tcm_heap.c b/USDK/component/os/os_dep/tcm_heap.c new file mode 100644 index 0000000..d51556d --- /dev/null +++ b/USDK/component/os/os_dep/tcm_heap.c @@ -0,0 +1,347 @@ +//#include +#include "tcm_heap.h" + +#include // memset() + +#include + +//#define _DEBUG + +#if CONFIG_USE_TCM_HEAP +#define FREE_FILL_CODE 0xDEAD +#define ALLOC_FILL_CODE 0xBEEF + +#define ROUND_UP2(x, pad) (((x) + ((pad) - 1)) & ~((pad) - 1)) + +//static +struct Heap g_tcm_heap; + +#if defined (__ICCARM__) +#pragma location=".tcm.heap" +#else +__attribute__((section(".tcm.heap"))) +#endif +HEAP_DEFINE_BUF(tcm_heap, TCM_HEAP_SIZE); +//unsigned char tcm_heap[TCM_HEAP_SIZE]; + +static int g_heap_inited = 0; +static _lock tcm_lock; + +extern void vPortSetExtFree( void (*free)( void *p ), uint32_t upper, uint32_t lower ); + +void tcm_heap_init(void) +{ + //#ifdef _DEBUG + //memset(memory, FREE_FILL_CODE, size); + //#endif + + //ASSERT2(((int)memory % alignof(heap_buf_t)) == 0, + //"memory buffer is unaligned, please use the HEAP_DEFINE_BUF() macro to declare heap buffers!\n"); + + /* Initialize heap with a single big chunk */ + g_tcm_heap.FreeList = (MemChunk *)&tcm_heap; + g_tcm_heap.FreeList->next = NULL; +// g_tcm_heap.FreeList->size = sizeof(tcm_heap); + g_tcm_heap.FreeList->size = tcm_heap_size; // ((0x20000000 - (u32)&tcm_heap - 520 + sizeof(heap_buf_t) - 1)/sizeof(heap_buf_t))*sizeof(heap_buf_t); + + g_heap_inited = 1; + rtw_spinlock_init(&tcm_lock); + +#if PLATFORM_FREERTOS + // let RTOS know how to free memory if using as task stack + vPortSetExtFree(tcm_heap_free, 0x20000000, 0x1fff0000); +#endif +} + +void tcm_heap_dump(void) +{ +#if CONFIG_DEBUG_LOG > 1 + if(!g_heap_inited) tcm_heap_init(); + MemChunk *chunk, *prev; + struct Heap* h = &g_tcm_heap; + int count = 0; + int free_mem; + + DBG_8195A("TCM Free Heap Memory List:\n"); + for (chunk = h->FreeList; chunk; chunk = chunk->next) { + DBG_8195A(" [%d]=%p, %d\n", ++count, chunk, chunk->size); + } + +/* + for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList; + chunk; + prev = chunk, chunk = chunk->next) + { + DBG_8195A(" [%d]=%p, %d\n", ++count, chunk, chunk->size); + } +*/ +#endif +} + +static void *tcm_heap_allocmem(int size) +{ + MemChunk *chunk, *prev; + struct Heap* h = &g_tcm_heap; + _irqL irqL; + + rtw_enter_critical(&tcm_lock, &irqL); + + if(!g_heap_inited) tcm_heap_init(); + + /* Round size up to the allocation granularity */ + size = ROUND_UP2(size, sizeof(MemChunk)); + + /* Handle allocations of 0 bytes */ + if (!size) + size = sizeof(MemChunk); + + /* Walk on the free list looking for any chunk big enough to + * fit the requested block size. + */ + for (prev = (MemChunk *)&h->FreeList, chunk = h->FreeList; + chunk; + prev = chunk, chunk = chunk->next) + { + if (chunk->size >= size) + { + if (chunk->size == size) + { + /* Just remove this chunk from the free list */ + prev->next = chunk->next; + } + else + { + /* Allocate from the END of an existing chunk */ + chunk->size -= size; + chunk = (MemChunk *)((uint8_t *)chunk + chunk->size); + } +#ifdef _DEBUG + memset(chunk, ALLOC_FILL_CODE, size); +#endif + + rtw_exit_critical(&tcm_lock, &irqL); + DBG_TCM_HEAP_INFO("tcm_alloc:%p[%d]\n", chunk, size); + return (void *)chunk; + } + } + rtw_exit_critical(&tcm_lock, &irqL); + DBG_TCM_HEAP_WARN("tcm_alloc(%d) - freeSpace(%d)!\n", size, tcm_heap_freeSpace()); + return NULL; /* fail */ +} + +static void tcm_heap_freemem(void *mem, int size) +{ + MemChunk *prev; + //ASSERT(mem); + struct Heap* h = &g_tcm_heap; + _irqL irqL; + + rtw_enter_critical(&tcm_lock, &irqL); + +// if(!g_heap_inited) tcm_heap_init(); + +#ifdef _DEBUG + memset(mem, FREE_FILL_CODE, size); +#endif + + /* Round size up to the allocation granularity */ + size = ROUND_UP2(size, sizeof(MemChunk)); + + /* Handle allocations of 0 bytes */ + if (!size) + size = sizeof(MemChunk); + + /* Special cases: first chunk in the free list or memory completely full */ + //ASSERT((uint8_t*)mem != (uint8_t*)h->FreeList); + if (((uint8_t *)mem) < ((uint8_t *)h->FreeList) || !h->FreeList) + { + /* Insert memory block before the current free list head */ + prev = (MemChunk *)mem; + prev->next = h->FreeList; + prev->size = size; + h->FreeList = prev; + } + else /* Normal case: not the first chunk in the free list */ + { + /* + * Walk on the free list. Stop at the insertion point (when mem + * is between prev and prev->next) + */ + prev = h->FreeList; + while (prev->next < (MemChunk *)mem && prev->next) + prev = prev->next; + + /* Make sure mem is not *within* prev */ + //ASSERT((uint8_t*)mem >= (uint8_t*)prev + prev->size); + + /* Should it be merged with previous block? */ + if (((uint8_t *)prev) + prev->size == ((uint8_t *)mem)) + { + /* Yes */ + prev->size += size; + } + else /* not merged with previous chunk */ + { + MemChunk *curr = (MemChunk*)mem; + + /* insert it after the previous node + * and move the 'prev' pointer forward + * for the following operations + */ + curr->next = prev->next; + curr->size = size; + prev->next = curr; + + /* Adjust for the following test */ + prev = curr; + } + } + + /* Also merge with next chunk? */ + if (((uint8_t *)prev) + prev->size == ((uint8_t *)prev->next)) + { + prev->size += prev->next->size; + prev->next = prev->next->next; + + /* There should be only one merge opportunity, becuase we always merge on free */ + //ASSERT((uint8_t*)prev + prev->size != (uint8_t*)prev->next); + } + + rtw_exit_critical(&tcm_lock, &irqL); + DBG_TCM_HEAP_INFO("tcm_free:%p[%d]\n", mem, size); +} + +int tcm_heap_freeSpace(void) +{ + int free_mem = 0; + struct Heap* h = &g_tcm_heap; + _irqL irqL; + MemChunk *chunk; + + rtw_enter_critical(&tcm_lock, &irqL); + + if(!g_heap_inited) tcm_heap_init(); + + for (chunk = h->FreeList; chunk; chunk = chunk->next) + free_mem += chunk->size; + + rtw_exit_critical(&tcm_lock, &irqL); + return free_mem; +} + + +/** + * Standard malloc interface + */ +void *tcm_heap_malloc(int size) +{ + int *mem; + + size += sizeof(int); + if ((mem = (int*)tcm_heap_allocmem(size))){ + *mem++ = size; + } + + return mem; +} + +/** + * Standard calloc interface + */ +void *tcm_heap_calloc(int size) +{ + void *mem; + + if ((mem = tcm_heap_malloc(size))) + memset(mem, 0, size); + + return mem; +} + +/** + * Free a block of memory, determining its size automatically. + * + * \param h Heap from which the block was allocated. + * \param mem Pointer to a block of memory previously allocated with + * either heap_malloc() or heap_calloc(). + * + * \note If \a mem is a NULL pointer, no operation is performed. + * + * \note Freeing the same memory block twice has undefined behavior. + * + * \note This function works like the ANSI C free(). + */ +void tcm_heap_free(void *mem) +{ + int *_mem = (int *)mem; + + if (_mem) + { + --_mem; + tcm_heap_freemem(_mem, *_mem); + } +} + +#if 0 +//----------- Tests ------------- +static void alloc_test(int size, int test_len) +{ + //Simple test + uint8_t *a[100]; + int i, j; + + for (i = 0; i < test_len; i++) + { + a[i] = tcm_heap_allocmem(size); + //ASSERT(a[i]); + for (j = 0; j < size; j++) + a[i][j] = i; + } + + //ASSERT(heap_freeSpace(&h) == HEAP_SIZE - test_len * ROUND_UP2(size, sizeof(MemChunk))); + + for (i = 0; i < test_len; i++) + { + for (j = 0; j < size; j++) + { + DBG_8195A("a[%d][%d] = %d\n", i, j, a[i][j]); + //ASSERT(a[i][j] == i); + } + tcm_heap_freemem(a[i], size); + } + //ASSERT(heap_freeSpace(&h) == HEAP_SIZE); +} + +#define ALLOC_SIZE 256 +#define ALLOC_SIZE2 1024 +#define TEST_LEN 20 +#define TEST_LEN2 10 +#define HEAP_SIZE 59*1024 +int tcm_heap_testRun(void) +{ + alloc_test(ALLOC_SIZE, TEST_LEN); + alloc_test(ALLOC_SIZE2, TEST_LEN2); + /* Try to allocate the whole heap */ + uint8_t *b = tcm_heap_allocmem(HEAP_SIZE); + int i, j; + //ASSERT(b); + //ASSERT(heap_freeSpace(&h) == 0); + + //ASSERT(!heap_allocmem(&h, HEAP_SIZE)); + + for (j = 0; j < HEAP_SIZE; j++) + b[j] = j; + + for (j = 0; j < HEAP_SIZE; j++) + { + DBG_8195A("b[%d] = %d\n", j, j); + //ASSERT(b[j] == (j & 0xff)); + } + tcm_heap_freemem(b, HEAP_SIZE); + //ASSERT(heap_freeSpace(&h) == HEAP_SIZE); + + return 0; +} +#endif // tests + +#endif diff --git a/USDK/component/os/rtx/rtx_service.c b/USDK/component/os/rtx/rtx_service.c new file mode 100644 index 0000000..0518205 --- /dev/null +++ b/USDK/component/os/rtx/rtx_service.c @@ -0,0 +1,1109 @@ +/* RTX includes */ +#include "osdep_service.h" +#include "tcm_heap.h" +#include +//#include //malloc(), free() +//#include //memcpy(), memcmp(), memset() +#include "platform_stdlib.h" +//#include +//#include +/********************* os depended utilities ********************/ + +#ifndef USE_MUTEX_FOR_SPINLOCK +#define USE_MUTEX_FOR_SPINLOCK 1 +#endif + +#define USE_HEAP_INFO 0 + +#define OS_TICK 1000 +#define OS_TICK_RATE_MS (1000/OS_TICK) + +//----------------------------------------------------------------------- +// Private Variables +//----------------------------------------------------------------------- +static unsigned long CriticalNesting = 0; + +//----------------------------------------------------------------------- +// Misc Function +//----------------------------------------------------------------------- +int osdep_print = 0; +#define _func_enter_ do{\ + if(osdep_print)\ + printf("enter %s\r\n", __FUNCTION__);\ + }while(0) +#define _func_exit_ do{\ + if(osdep_print)\ + printf("exit %s\r\n", __FUNCTION__);\ + }while(0) + +void save_and_cli() +{ +_func_enter_; + __disable_irq(); +_func_exit_; +} + +void restore_flags() +{ +_func_enter_; + __enable_irq(); +_func_exit_; +} + +void cli() +{ +_func_enter_; + __disable_irq(); +_func_exit_; +} + +/* Not needed on 64bit architectures */ +static unsigned int __div64_32(u64 *n, unsigned int base) +{ + u64 rem = *n; + u64 b = base; + u64 res, d = 1; + unsigned int high = rem >> 32; +_func_enter_; + /* Reduce the thing a bit first */ + res = 0; + if (high >= base) { + high /= base; + res = (u64) high << 32; + rem -= (u64) (high * base) << 32; + } + + while ((u64)b > 0 && b < rem) { + b = b+b; + d = d+d; + } + + do { + if (rem >= b) { + rem -= b; + res += d; + } + b >>= 1; + d >>= 1; + } while (d); +_func_exit_; + *n = res; + return rem; +} + +/********************* os depended service ********************/ +#if USE_HEAP_INFO +static uint32_t osFreeBytesRemaining=0x400; +#endif +static void _rtx_memset(void *pbuf, int c, u32 sz); +u8* _rtx_malloc(u32 sz) +{ +_func_enter_; + void *p = NULL; + p = malloc(sz); + if(p != NULL){ +#if USE_HEAP_INFO + osFreeBytesRemaining-=sz; +#endif + } +_func_exit_; + return p; +} + +u8* _rtx_zmalloc(u32 sz) +{ +_func_enter_; + u8 *pbuf = _rtx_malloc(sz); + + if (pbuf != NULL){ +#if USE_HEAP_INFO + osFreeBytesRemaining-=sz; +#endif + _rtx_memset(pbuf, 0, sz); + } +_func_exit_; + return pbuf; +} + +static void (*ext_free)( void *p ) = NULL; +static uint32_t ext_upper = 0; +static uint32_t ext_lower = 0; +void rtw_set_mfree_ext( void (*free)( void *p ), uint32_t upper, uint32_t lower ) +{ + ext_free = free; + ext_upper = upper; + ext_lower = lower; +} + +void _rtx_mfree(u8 *pbuf, u32 sz) +{ +_func_enter_; + if( ((uint32_t)pbuf >= ext_lower) && ((uint32_t)pbuf < ext_upper) ){ + if(ext_free) + ext_free(pbuf); + }else{ + free(pbuf); + } +#if USE_HEAP_INFO + osFreeBytesRemaining+=sz; +#endif +} + +static void _rtx_memcpy(void* dst, void* src, u32 sz) +{ +_func_enter_; + memcpy(dst, src, sz); +_func_exit_; +} + +static int _rtx_memcmp(void *dst, void *src, u32 sz) +{ +_func_enter_; +//under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0 + if (!(memcmp(dst, src, sz))) + return _SUCCESS; +_func_exit_; + return _FAIL; +} + +static void _rtx_memset(void *pbuf, int c, u32 sz) +{ +_func_enter_; + memset(pbuf, c, sz); +_func_exit_; +} + +static void _rtx_init_sema(_sema *sem, int init_val) +{ +_func_enter_; + rtx_sema_t *p_sem = (rtx_sema_t *)_rtx_zmalloc(sizeof(rtx_sema_t)); + if(p_sem == NULL){ + goto err_exit; + } +#ifdef CMSIS_OS_RTX + p_sem->def.semaphore = p_sem->data; +#endif + *sem = (_sema)p_sem; + p_sem->id = osSemaphoreCreate(&p_sem->def, init_val); + if (p_sem->id == NULL){ + goto err_exit; + } +_func_exit_; + return; +err_exit: + DBG_ERR("error"); + if(p_sem) + _rtx_mfree((u8 *)p_sem, sizeof(rtx_sema_t)); + *sem = NULL; + return; +} + +static void _rtx_free_sema(_sema *sema) +{ +_func_enter_; + if(*sema){ + rtx_sema_t *p_sem = (rtx_sema_t *)(*sema); + osSemaphoreDelete(p_sem->id); + if(p_sem) + _rtx_mfree((u8 *)p_sem, sizeof(rtx_sema_t)); + *sema = NULL; + }else + DBG_ERR("NULL pointer get"); +_func_exit_; +} + +static void _rtx_up_sema(_sema *sema) +{ + if(*sema){ + rtx_sema_t *p_sem = (rtx_sema_t *)(*sema); + osStatus status = osSemaphoreRelease(p_sem->id); + if ( status != osOK){ + DBG_ERR("error %d", status); + } + }else + DBG_ERR("NULL pointer get"); +_func_exit_; +} + +static void _rtx_up_sema_from_isr(_sema *sema) +{ +_func_enter_; + if(*sema){ + rtx_sema_t *p_sem = (rtx_sema_t *)*sema; + osStatus status = osSemaphoreRelease(p_sem->id); + if (status != osOK){ + DBG_ERR("error %d", status); + } + }else + DBG_ERR("NULL pointer get"); +_func_exit_; +} + +static u32 _rtx_down_sema(_sema *sema, u32 timeout_ms) +{ + if(*sema){ + rtx_sema_t *p_sem = (rtx_sema_t *)*sema; + if(timeout_ms == RTW_MAX_DELAY) { + timeout_ms = osWaitForever; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + + if (osSemaphoreWait(p_sem->id, (timeout_ms != 0)?(timeout_ms):(osWaitForever)) >= 0) + return _TRUE; + } + return _FALSE; +} + +static void _rtx_mutex_init(_mutex *mutex) +{ +_func_enter_; + rtx_mutex_t *p_mut = (rtx_mutex_t *)_rtx_zmalloc(sizeof(rtx_mutex_t)); + if(p_mut == NULL) + goto err_exit; +#ifdef CMSIS_OS_RTX + p_mut->def.mutex = (void *)p_mut->data; +#endif + *mutex = (_mutex)p_mut; + p_mut->id = osMutexCreate(&p_mut->def); + if (p_mut->id == NULL) + goto err_exit; +_func_exit_; + return; +err_exit: + DBG_ERR("error"); + if(p_mut) + _rtx_mfree((u8 *)p_mut, sizeof(rtx_mutex_t)); + *mutex = NULL; + return; +} + +static void _rtx_mutex_free(_mutex *pmutex) +{ +_func_enter_; + if(*pmutex){ + rtx_mutex_t *p_mut = (rtx_mutex_t *)(*pmutex); + osMutexDelete(p_mut->id); + if(p_mut) + _rtx_mfree((u8 *)p_mut, sizeof(rtx_mutex_t)); + } +_func_exit_; +} + +static void _rtx_mutex_get(_mutex *pmutex) +{ +_func_enter_; + if(*pmutex){ + rtx_mutex_t *p_mut = (rtx_mutex_t *)(*pmutex); + if (osMutexWait(p_mut->id, 60 * 1000 / OS_TICK_RATE_MS) != osOK) + DBG_ERR("%s(%p) failed, retry\n", __FUNCTION__, p_mut); + } +_func_exit_; +} + +static int _rtx_mutex_get_timeout(_mutex *pmutex, u32 timeout_ms) +{ +_func_enter_; + if(*pmutex){ + rtx_mutex_t *p_mut = (rtx_mutex_t *)(*pmutex); + if(timeout_ms == RTW_MAX_DELAY) { + timeout_ms = osWaitForever; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + if(osMutexWait(p_mut->id, timeout_ms / OS_TICK_RATE_MS) == osOK){ + return _SUCCESS; + } + } +_func_exit_; + DBG_ERR("%s(%p) failed, retry\n", __FUNCTION__, pmutex); + return _FAIL; +} + +static void _rtx_mutex_put(_mutex *pmutex) +{ +_func_enter_; + if(*pmutex){ + rtx_mutex_t *p_mut = (rtx_mutex_t *)(*pmutex); + if (osMutexRelease(p_mut->id) != osOK) + DBG_ERR("\r\ninternal counter of mutex is 0 or calling task is not the owner of the mutex"); + } +_func_exit_; +} + +static void _rtx_enter_critical(_lock *plock, _irqL *pirqL) +{ +_func_enter_; + CriticalNesting++; + if(CriticalNesting == 1){ + rt_tsk_lock();//tsk_lock & tsk_unlock should not be called nested + } +_func_exit_; +} + +void mbed_die(void){ + DBG_ERR(" %p die here", osThreadGetId()); + __disable_irq(); + while(1); +} + +static void _rtx_exit_critical(_lock *plock, _irqL *pirqL) +{ +_func_enter_; + if(CriticalNesting == 0){ + DBG_ERR("die here"); + HALT(); + } + CriticalNesting--; + if(CriticalNesting == 0){ + rt_tsk_unlock(); + } +_func_exit_; +} + +static void _rtx_enter_critical_from_isr(_lock *plock, _irqL *pirqL) +{ +_func_enter_; + __disable_irq(); +_func_exit_; +} + +static void _rtx_exit_critical_from_isr(_lock *plock, _irqL *pirqL) +{ +_func_enter_; + __enable_irq(); +_func_exit_; +} + +static int _rtx_enter_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ +_func_enter_; + while(_rtx_mutex_get_timeout(pmutex, 60 * 1000 / OS_TICK_RATE_MS) != _SUCCESS) + DBG_ERR("\n\r[%p] %s(%p) failed, retry\n", osThreadGetId(), __FUNCTION__, pmutex); +_func_exit_; + return _SUCCESS; +} + +static void _rtx_exit_critical_mutex(_mutex *pmutex, _irqL *pirqL) +{ +_func_enter_; + _rtx_mutex_put(pmutex); +_func_exit_; +} + +static void _rtx_spinlock_init(_lock *plock) +{ +_func_enter_; +#if USE_MUTEX_FOR_SPINLOCK + _rtx_mutex_init(plock); +#endif +_func_exit_; +} + +static void _rtx_spinlock_free(_lock *plock) +{ +_func_enter_; +#if USE_MUTEX_FOR_SPINLOCK + if(plock != NULL){ + _rtx_mutex_free(plock); + } +#endif +_func_exit_; +} + +static void _rtx_spinlock(_lock *plock) +{ +_func_enter_; +#if USE_MUTEX_FOR_SPINLOCK + _rtx_mutex_get(plock); +#endif +_func_exit_; +} + +static void _rtx_spinunlock(_lock *plock) +{ +_func_enter_; +#if USE_MUTEX_FOR_SPINLOCK + _rtx_mutex_put(plock); +#endif +_func_exit_; +} + +static void _rtx_spinlock_irqsave(_lock *plock, _irqL *irqL) +{ +_func_enter_; + _rtx_enter_critical(plock, irqL); +#if USE_MUTEX_FOR_SPINLOCK + _rtx_spinlock(plock); +#endif +_func_exit_; +} + +static void _rtx_spinunlock_irqsave(_lock *plock, _irqL *irqL) +{ +_func_enter_; +#if USE_MUTEX_FOR_SPINLOCK + _rtx_spinunlock(plock); +#endif + _rtx_exit_critical(plock, irqL); +_func_exit_; +} + +static int _rtx_init_xqueue( _xqueue* queue, const char* name, u32 message_size, u32 number_of_messages ) +{ +_func_enter_; + rtx_mbox_t *mbox = (rtx_mbox_t *)_rtx_zmalloc(sizeof(rtx_mbox_t)); + if (mbox == NULL ){ + goto err_exit; + } +#ifdef CMSIS_OS_RTX + mbox->os_mailQ_q = (uint32_t)_rtx_zmalloc((4+number_of_messages)*sizeof(uint32_t)); + mbox->os_mailQ_m = (uint32_t)_rtx_zmalloc((3 + (message_size+3)/4)*number_of_messages); + if((mbox->os_mailQ_q == 0) || (mbox->os_mailQ_m == 0)) + goto err_exit; + mbox->os_mailQ_p[0] = (void *)mbox->os_mailQ_q; + mbox->os_mailQ_p[1] = (void *)mbox->os_mailQ_m; + mbox->def.pool = mbox->os_mailQ_p; + mbox->def.queue_sz = number_of_messages; + mbox->def.item_sz = message_size; +#endif + *queue = (_xqueue)mbox; + mbox->id = osMailCreate(&mbox->def, NULL); + if(mbox->id == NULL) + goto err_exit; +_func_exit_; + return _SUCCESS; +err_exit: + DBG_ERR("%s error\r\n", __FUNCTION__); + if(mbox){ + if(mbox->os_mailQ_q) + _rtx_mfree((u8 *)mbox->os_mailQ_q, ((4+number_of_messages)*sizeof(uint32_t))); + if(mbox->os_mailQ_m) + _rtx_mfree((u8 *)mbox->os_mailQ_m, ((3 + (message_size+3)/4)*number_of_messages)); + _rtx_mfree((u8 *)mbox, sizeof(rtx_mbox_t)); + *queue = NULL; + } + return _FAIL; +} + +static int _rtx_push_to_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ +_func_enter_; + void *mptr; + rtx_mbox_t *mbox; + if(timeout_ms == RTW_MAX_DELAY) { + timeout_ms = osWaitForever; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + + if (*queue != NULL){ + mbox = (rtx_mbox_t *)(*queue); + mptr = osMailAlloc(mbox->id, timeout_ms); // Allocate memory + _rtx_memcpy(mptr, message, mbox->def.item_sz); + if(osMailPut(mbox->id, mptr) != osOK ){ + DBG_ERR("%s error\n", __FUNCTION__); + return _FAIL; + } + } +_func_exit_; + return _SUCCESS; +} + +static int _rtx_pop_from_xqueue( _xqueue* queue, void* message, u32 timeout_ms ) +{ +_func_enter_; + if(timeout_ms == RTW_WAIT_FOREVER) { + timeout_ms = osWaitForever; + } else { + timeout_ms = rtw_ms_to_systime(timeout_ms); + } + if (*queue != NULL){ + rtx_mbox_t *mbox = (rtx_mbox_t *)(*queue); + osEvent evt; + evt = osMailGet(mbox->id, timeout_ms ); + if (evt.status == osEventMail) { + _rtx_memcpy(message, evt.value.p, mbox->def.item_sz); + osMailFree(mbox->id, evt.value.p); +_func_exit_; + return _SUCCESS; + } + } + DBG_ERR("[%p] %s error", osThreadGetId(), __FUNCTION__); + return _FAIL; +} + +static int _rtx_deinit_xqueue( _xqueue* queue ) +{ +_func_enter_; + if(*queue != NULL){ + rtx_mbox_t *mbox = (rtx_mbox_t *)(*queue); + + if(mbox->os_mailQ_q) + _rtx_mfree((u8 *)mbox->os_mailQ_q, ((4+mbox->def.queue_sz)*sizeof(uint32_t))); + if(mbox->os_mailQ_m) + _rtx_mfree((u8 *)mbox->os_mailQ_m, ((3 + (mbox->def.item_sz+3)/4)*mbox->def.queue_sz)); + _rtx_mfree((u8 *)mbox, sizeof(rtx_mbox_t)); + *queue = NULL; + } +_func_exit_; + return 0; +} + +static u32 _rtx_get_current_time(void) +{ +_func_enter_; + return rt_time_get(); +_func_exit_; +} + +static u32 _rtx_systime_to_ms(u32 systime) +{ + return systime * OS_TICK_RATE_MS; +} + +static u32 _rtx_systime_to_sec(u32 systime) +{ + return systime / OS_TICK; +} + +static u32 _rtx_ms_to_systime(u32 ms) +{ + return ms / OS_TICK_RATE_MS; +} + +static u32 _rtx_sec_to_systime(u32 sec) +{ + return sec * OS_TICK; +} + +static void _rtx_msleep_os(int ms) +{ +_func_enter_; + osDelay(ms); +_func_exit_; +} + +static void _rtx_usleep_os(int us) +{ +_func_enter_; +#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F10X_XL) + // FreeRTOS does not provide us level delay. Use busy wait + WLAN_BSP_UsLoop(us); +#elif defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + //DBG_ERR("%s: Please Implement micro-second delay\n", __FUNCTION__); + HalDelayUs(us); +#else +// #error "Please implement hardware dependent micro second level sleep here" +#endif +_func_exit_; +} + +static void _rtx_mdelay_os(int ms) +{ +_func_enter_; + osDelay(ms); +_func_exit_; +} + +static void _rtx_udelay_os(int us) +{ +_func_enter_; +#if defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32F10X_XL) + // FreeRTOS does not provide us level delay. Use busy wait + WLAN_BSP_UsLoop(us); +#elif defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) + //RtlUdelayOS(us); + HalDelayUs(us); +#else +// #error "Please implement hardware dependent micro second level sleep here" +#endif +_func_exit_; +} + +static void _rtx_yield_os(void) +{ +_func_enter_; + osThreadYield(); +_func_exit_; +} + +static void _rtx_ATOMIC_SET(ATOMIC_T *v, int i) +{ + atomic_set(v,i); +} + +static int _rtx_ATOMIC_READ(ATOMIC_T *v) +{ + return atomic_read(v); +} + +static void _rtx_ATOMIC_ADD(ATOMIC_T *v, int i) +{ + save_and_cli(); + v->counter += i; + restore_flags(); +} + +static void _rtx_ATOMIC_SUB(ATOMIC_T *v, int i) +{ + save_and_cli(); + v->counter -= i; + restore_flags(); +} + +static void _rtx_ATOMIC_INC(ATOMIC_T *v) +{ + save_and_cli(); + v->counter++; + restore_flags(); +} + +static void _rtx_ATOMIC_DEC(ATOMIC_T *v) +{ + save_and_cli(); + v->counter--; + restore_flags(); +} + +static int _rtx_ATOMIC_ADD_RETURN(ATOMIC_T *v, int i) +{ + int temp; + + save_and_cli(); + temp = v->counter; + temp += i; + v->counter = temp; + restore_flags(); + + return temp; +} + +static int _rtx_ATOMIC_SUB_RETURN(ATOMIC_T *v, int i) +{ + int temp; + + save_and_cli(); + temp = v->counter; + temp -= i; + v->counter = temp; + restore_flags(); + + return temp; +} + +static int _rtx_ATOMIC_INC_RETURN(ATOMIC_T *v) +{ + return _rtx_ATOMIC_ADD_RETURN(v, 1); +} + +static int _rtx_ATOMIC_DEC_RETURN(ATOMIC_T *v) +{ + return _rtx_ATOMIC_SUB_RETURN(v, 1); +} + +static u64 _rtx_modular64(u64 n, u64 base) +{ + unsigned int __base = (base); + unsigned int __rem; +_func_enter_; + if (((n) >> 32) == 0) { + __rem = (unsigned int)(n) % __base; + (n) = (unsigned int)(n) / __base; + } + else + __rem = __div64_32(&(n), __base); +_func_exit_; + return __rem; +} + +/* Refer to ecos bsd tcpip codes */ +static int _rtx_arc4random(void) +{ +_func_enter_; + u32 res = _rtx_get_current_time(); + static unsigned long seed = 0xDEADB00B; + seed = ((seed & 0x007F00FF) << 7) ^ + ((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits + (res << 13) ^ (res >> 9); // using the clock too! +_func_exit_; + return (int)seed; +} + +static int _rtx_get_random_bytes(void *buf, u32 len) +{ +#if 1 //becuase of 4-byte align, we use the follow code style. + unsigned int ranbuf; + unsigned int *lp; + int i, count; + count = len / sizeof(unsigned int); + lp = (unsigned int *) buf; +_func_enter_; + for(i = 0; i < count; i ++) { + lp[i] = _rtx_arc4random(); + len -= sizeof(unsigned int); + } + + if(len > 0) { + ranbuf = _rtx_arc4random(); + _rtx_memcpy(&lp[i], &ranbuf, len); + } +_func_exit_; + return 0; +#else + unsigned long ranbuf, *lp; + lp = (unsigned long *)buf; + while (len > 0) { + ranbuf = _rtx_arc4random(); + *lp++ = ranbuf; //this op need the pointer is 4Byte-align! + len -= sizeof(ranbuf); + } + return 0; +#endif +} + +static u32 _rtx_GetFreeHeapSize(void) +{ +#if USE_HEAP_INFO + return osFreeBytesRemaining; +#else + return 0; +#endif +} + + +//#if CONFIG_USE_TCM_HEAP +//void *tcm_heap_malloc(int size); +//#endif +static int _rtx_create_task(struct task_struct *ptask, const char *name, + u32 stack_size, u32 priority, thread_func_t func, void *thctx) +{ +_func_enter_; + rtx_thread_data_t *thread_hdl = NULL; + u32 stacksize = stack_size * 4; //sizeof(DWORD) + if(!func) + goto err_exit; + thread_hdl = (rtx_thread_data_t *)_rtx_zmalloc(sizeof(rtx_thread_data_t)); + if(thread_hdl == NULL) + goto err_exit; +#ifdef CMSIS_OS_RTX +#ifndef __MBED_CMSIS_RTOS_CA9 + thread_hdl->def.stack_pointer = (void *)_rtx_malloc(stacksize); + if(thread_hdl->def.stack_pointer == NULL) + goto err_exit; +#endif + if(priority > osPriorityRealtime){ + DBG_ERR("[%s]priority is higher than osPriorityRealtime", name); + priority = osPriorityRealtime; + } + thread_hdl->def.pthread = (os_pthread)func; + thread_hdl->def.tpriority = (osPriority)priority; + thread_hdl->def.stacksize = stacksize; +#endif + ptask->task = (_thread_hdl_)thread_hdl; + ptask->task_name = name; + ptask->blocked = 0; + ptask->callback_running = 0; + + _rtx_init_sema(&ptask->wakeup_sema, 0); + _rtx_init_sema(&ptask->terminate_sema, 0); + //rtw_init_queue(&wq->work_queue); + + thread_hdl->id = osThreadCreate(&thread_hdl->def, thctx); + if(thread_hdl->id == NULL) + goto err_exit; + return _SUCCESS; +err_exit: + if(thread_hdl){ + _rtx_free_sema(&ptask->wakeup_sema); + _rtx_free_sema(&ptask->terminate_sema); + _rtx_memset((u8 *)ptask, 0, sizeof(*ptask)); +#ifndef __MBED_CMSIS_RTOS_CA9 + if(thread_hdl->def.stack_pointer) + _rtx_mfree((void *)thread_hdl->def.stack_pointer, thread_hdl->def.stacksize); +#endif + _rtx_mfree((u8 *)thread_hdl, sizeof(rtx_thread_data_t)); + } + DBG_ERR("Create Task \"%s\" Failed! \n", ptask->task_name); + return _FAIL; +} + +static void _rtx_delete_task(struct task_struct *ptask) +{ +_func_enter_; + rtx_thread_data_t *thread_hdl = (rtx_thread_data_t *)ptask->task; + if (!thread_hdl){ + DBG_ERR("_rtx_delete_task(): ptask is NULL!\n"); + return; + } + + ptask->blocked = 1; + + _rtx_up_sema(&ptask->wakeup_sema); + _rtx_down_sema(&ptask->terminate_sema, TIMER_MAX_DELAY); + + osThreadTerminate(thread_hdl->id); +#ifndef __MBED_CMSIS_RTOS_CA9 + if(thread_hdl->def.stack_pointer) + _rtx_mfree((void *)thread_hdl->def.stack_pointer, thread_hdl->def.stacksize); +#endif + _rtx_mfree((u8 *)thread_hdl, sizeof(rtx_thread_data_t)); + + //rtw_deinit_queue(&wq->work_queue); + _rtx_free_sema(&ptask->wakeup_sema); + _rtx_free_sema(&ptask->terminate_sema); + + ptask->task = NULL; + + DBG_TRACE("Delete Task \"%s\"\n", ptask->task_name); +_func_exit_; +} + +void _rtx_wakeup_task(struct task_struct *ptask) +{ +_func_enter_; + if(ptask) + _rtx_up_sema(&ptask->wakeup_sema); +_func_exit_; +} + +static void _rtx_thread_enter(char *name) +{ +_func_enter_; + DBG_INFO("\n\rRTKTHREAD %s\n", name); +_func_exit_; +} + +static void _rtx_thread_exit(void) +{ +_func_enter_; + osThreadId id = osThreadGetId(); + osThreadTerminate(id); +_func_exit_; +} + +/***************************************************** +************timer data block, defined in rt_CMSIS.c********* + +// Timer definitions +#define osTimerInvalid 0 +#define osTimerStopped 1 +#define osTimerRunning 2 + +// Timer structures + +typedef struct os_timer_cb_ { // Timer Control Block + struct os_timer_cb_ *next; // Pointer to next active Timer, (u8 *)data[0:3] + uint8_t state; // Timer State, (u8 *)data[4] + uint8_t type; // Timer Type (Periodic/One-shot), (u8 *)data[5] + uint16_t reserved; // Reserved, (u8 *)data[6:7] + uint16_t tcnt; // Timer Delay Count, (u8 *)data[8:9] + uint16_t icnt; // Timer Initial Count, (u8 *)data[10:11] + void *arg; // Timer Function Argument, (u8 *)data[12:15] + osTimerDef_t *timer; // Pointer to Timer definition, (u8 *)data[16:19] +} os_timer_cb; +*****************************************************/ +_timerHandle _rtx_timerCreate( const signed char *pcTimerName, + osdepTickType xTimerPeriodInTicks, + u32 uxAutoReload, + void * pvTimerID, + TIMER_FUN pxCallbackFunction ) +{ +_func_enter_; + rtx_tmr_t *tmr = (rtx_tmr_t *)_rtx_zmalloc(sizeof(rtx_tmr_t)); + os_timer_type type = (uxAutoReload == _TRUE)?osTimerPeriodic:osTimerOnce; + if(tmr == NULL) + goto err_exit; +#ifdef CMSIS_OS_RTX + tmr->def.ptimer = (os_ptimer)pxCallbackFunction; + tmr->def.timer = (void *)tmr->data; +#endif + if(pvTimerID == NULL) + pvTimerID = (void *)tmr; + tmr->id = osTimerCreate(&tmr->def, type, pvTimerID); + if(tmr->id == NULL) + goto err_exit; +_func_exit_; + return (_timerHandle)tmr; +err_exit: + DBG_ERR("error"); + if(tmr) + _rtx_mfree((u8 *)tmr, sizeof(rtx_tmr_t)); + return NULL; +} + +u32 _rtx_timerDelete( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ +_func_enter_; + rtx_tmr_t *tmr = (rtx_tmr_t *) xTimer; + osStatus status = osTimerDelete(tmr->id); + _rtx_mfree((u8 *)tmr, sizeof(rtx_tmr_t)); + if(status != osOK){ + DBG_ERR("error %d", status); + return _FAIL; + } +_func_exit_; + return _SUCCESS; +} + +u32 _rtx_timerIsTimerActive( _timerHandle xTimer ) +{ +_func_enter_; + rtx_tmr_t *tmr = (rtx_tmr_t *) xTimer; + u8 *data = (u8 *)tmr->data; +_func_exit_; + switch(data[4]){ + case 2U: + return _TRUE; + default: + return _FALSE; + } +} + +u32 _rtx_timerStop( _timerHandle xTimer, + osdepTickType xBlockTime ) +{ +_func_enter_; + rtx_tmr_t *tmr = (rtx_tmr_t *) xTimer; + osStatus status = osTimerStop(tmr->id); +_func_exit_; + if(status == osOK) + return _SUCCESS; + + DBG_ERR("error %d\n", status); + return _FAIL; +} + +u32 _rtx_timerChangePeriod( _timerHandle xTimer, + osdepTickType xNewPeriod, + osdepTickType xBlockTime ) +{ +_func_enter_; + rtx_tmr_t *tmr = (rtx_tmr_t *) xTimer; + osStatus ret; + + if(xNewPeriod == 0) + xNewPeriod += 1; + xNewPeriod = _rtx_systime_to_ms(xNewPeriod); + ret = osTimerStart(tmr->id, xNewPeriod); +_func_exit_; + if(ret == osOK) + return _SUCCESS; + + DBG_ERR("%s error\n", __FUNCTION__); + return _FAIL; +} + +//void _rtx_acquire_wakelock() +//{ +//#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +// acquire_wakelock(WAKELOCK_WLAN); +//#endif +//} + +//void _rtx_release_wakelock() +//{ +//#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +// release_wakelock(WAKELOCK_WLAN); +//#endif +//} + +u8 _rtx_get_scheduler_state(void) +{ +_func_enter_; + int32_t state = osKernelRunning(); + u8 state_out = OS_SCHEDULER_NOT_STARTED; + switch(state){ + case 1: state = OS_SCHEDULER_RUNNING; break; + case 0: state = OS_SCHEDULER_SUSPENDED; break; + default: break; + } +_func_exit_; + return state_out; +} + +const struct osdep_service_ops osdep_service = { + _rtx_malloc, //rtw_vmalloc + _rtx_zmalloc, //rtw_zvmalloc + _rtx_mfree, //rtw_vmfree + _rtx_malloc, //rtw_malloc + _rtx_zmalloc, //rtw_zmalloc + _rtx_mfree, //rtw_mfree + _rtx_memcpy, //rtw_memcpy + _rtx_memcmp, //rtw_memcmp + _rtx_memset, //rtw_memset + _rtx_init_sema, //rtw_init_sema + _rtx_free_sema, //rtw_free_sema + _rtx_up_sema, //rtw_up_sema + _rtx_up_sema_from_isr,//rtw_up_sema_from_isr + _rtx_down_sema, //rtw_down_sema + _rtx_mutex_init, //rtw_mutex_init + _rtx_mutex_free, //rtw_mutex_free + _rtx_mutex_get, //rtw_mutex_get + _rtx_mutex_get_timeout, //rtw_mutex_get_timeout + _rtx_mutex_put, //rtw_mutex_put + _rtx_enter_critical, //rtw_enter_critical + _rtx_exit_critical, //rtw_exit_critical + _rtx_enter_critical_from_isr, //rtw_enter_critical_from_isr + _rtx_exit_critical_from_isr, //rtw_exit_critical_from_isr + NULL, //rtw_enter_critical_bh + NULL, //rtw_exit_critical_bh + _rtx_enter_critical_mutex, //rtw_enter_critical_mutex + _rtx_exit_critical_mutex, //rtw_exit_critical_mutex + _rtx_spinlock_init, //rtw_spinlock_init + _rtx_spinlock_free, //rtw_spinlock_free + _rtx_spinlock, //rtw_spin_lock + _rtx_spinunlock, //rtw_spin_unlock + _rtx_spinlock_irqsave, //rtw_spinlock_irqsave + _rtx_spinunlock_irqsave, //rtw_spinunlock_irqsave + _rtx_init_xqueue,//rtw_init_xqueue + _rtx_push_to_xqueue,//rtw_push_to_xqueue + _rtx_pop_from_xqueue,//rtw_pop_from_xqueue + _rtx_deinit_xqueue,//rtw_deinit_xqueue + _rtx_get_current_time, //rtw_get_current_time + _rtx_systime_to_ms, //rtw_systime_to_ms + _rtx_systime_to_sec, //rtw_systime_to_sec + _rtx_ms_to_systime, //rtw_ms_to_systime + _rtx_sec_to_systime, //rtw_sec_to_systime + _rtx_msleep_os, //rtw_msleep_os + _rtx_usleep_os, //rtw_usleep_os + _rtx_mdelay_os, //rtw_mdelay_os + _rtx_udelay_os, //rtw_udelay_os + _rtx_yield_os, //rtw_yield_os + + _rtx_ATOMIC_SET, //ATOMIC_SET + _rtx_ATOMIC_READ, //ATOMIC_READ + _rtx_ATOMIC_ADD, //ATOMIC_ADD + _rtx_ATOMIC_SUB, //ATOMIC_SUB + _rtx_ATOMIC_INC, //ATOMIC_INC + _rtx_ATOMIC_DEC, //ATOMIC_DEC + _rtx_ATOMIC_ADD_RETURN, //ATOMIC_ADD_RETURN + _rtx_ATOMIC_SUB_RETURN, //ATOMIC_SUB_RETURN + _rtx_ATOMIC_INC_RETURN, //ATOMIC_INC_RETURN + _rtx_ATOMIC_DEC_RETURN, //ATOMIC_DEC_RETURN + + _rtx_modular64, //rtw_modular64 + _rtx_get_random_bytes, //rtw_get_random_bytes + _rtx_GetFreeHeapSize, //rtw_getFreeHeapSize + + _rtx_create_task, //rtw_create_task + _rtx_delete_task, //rtw_delete_task + _rtx_wakeup_task, //rtw_wakeup_task + + _rtx_thread_enter, //rtw_thread_enter + _rtx_thread_exit, //rtw_thread_exit + + _rtx_timerCreate, //rtw_timerCreate, + _rtx_timerDelete, //rtw_timerDelete, + _rtx_timerIsTimerActive, //rtw_timerIsTimerActive, + _rtx_timerStop, //rtw_timerStop, + _rtx_timerChangePeriod, //rtw_timerChangePeriod + + NULL, // rtw_acquire_wakelock + NULL, // rtw_release_wakelock + NULL, //rtw_wakelock_timeout + + _rtx_get_scheduler_state // rtw_get_scheduler_state +}; + diff --git a/USDK/component/os/rtx/rtx_service.h b/USDK/component/os/rtx/rtx_service.h new file mode 100644 index 0000000..4396aea --- /dev/null +++ b/USDK/component/os/rtx/rtx_service.h @@ -0,0 +1,309 @@ +#ifndef _RTX_SERVICE_H_ +#define _RTX_SERVICE_H_ + +//----------------------------------------------------------------------- +// Include Files +//----------------------------------------------------------------------- +#include "wireless.h" +#include "dlist.h" +#include +#include +#include "RTX_Config.h" +#include +#include +#include + +// -------------------------------------------- +// Platform dependent include file +// -------------------------------------------- +#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +//#include "platform_stdlib.h" +//#include "basic_types.h" +#include +#else +// other MCU may use standard library +#include +#endif + + +#if (defined CONFIG_GSPI_HCI || defined CONFIG_SDIO_HCI) || defined(CONFIG_LX_HCI) +/* For SPI interface transfer and us delay implementation */ +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +#include +#endif +#endif + + +// -------------------------------------------- +// Platform dependent type define +// -------------------------------------------- +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; +typedef unsigned long long u64; +typedef unsigned int uint; +typedef signed int sint; + +#ifndef bool +typedef int bool; +#define true 1 +#define false 0 +#endif + +#define IN +#define OUT +#define VOID void +#define NDIS_OID uint +#define NDIS_STATUS uint +#ifndef PVOID +typedef void * PVOID; +#endif + +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef __kernel_size_t SIZE_T; +typedef __kernel_ssize_t SSIZE_T; + +#endif //CONFIG_PLATFORM_8195A + +// === SEMAPHORE === +typedef struct { + osSemaphoreId id; + osSemaphoreDef_t def; +#ifdef CMSIS_OS_RTX + uint32_t data[2]; +#endif +} rtx_sema_t; + +// === THREAD === +typedef struct { + osThreadId id; + osThreadDef_t def; +} rtx_thread_data_t; + +// === MUTEX === +typedef struct { + osMutexId id; + osMutexDef_t def; +#ifdef CMSIS_OS_RTX +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) + int32_t data[4]; +#else + int32_t data[3]; +#endif +#endif +} rtx_mutex_t; + +// === MAIL BOX === +#define RTX_MB_SIZE 8 + +typedef struct { + osMessageQId id; + osMessageQDef_t def; +#ifdef CMSIS_OS_RTX + uint32_t queue; /* The (queue_size+4)*sizeof(uint32_t) is required for RTX OS_MCB overhead. */ +#endif +} rtx_mqueue_t; + +typedef struct { + osMailQId id; + osMailQDef_t def; +#ifdef CMSIS_OS_RTX + uint32_t os_mailQ_q; /* memory block, (4+queue_size)*sizeof(uint32_t)*/ + uint32_t os_mailQ_m; /* memory block, (3 + (item_size+3)/4)*queue_size*/ + void * os_mailQ_p[2]; +#endif +} rtx_mbox_t; + +typedef struct{ + osTimerId id; + osTimerDef_t def; +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) + uint32_t data[5]; +#else + uint32_t data[6]; +#endif +}rtx_tmr_t; + +#define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +// os types +typedef char osdepCHAR; +typedef float osdepFLOAT; +typedef double osdepDOUBLE; +typedef long osdepLONG; +typedef short osdepSHORT; +typedef unsigned long osdepSTACK_TYPE; +typedef long osdepBASE_TYPE; +typedef unsigned long osdepTickType; + +typedef void * _timerHandle; +typedef void * _sema; +typedef void * _mutex; +typedef void * _lock; +typedef void * _queueHandle; +typedef void * _xqueue; +typedef struct timer_list _timer; + +typedef struct sk_buff _pkt; +typedef unsigned char _buffer; + +#ifndef __LIST_H +#warning "DLIST_NOT_DEFINE!!!!!!" +struct list_head { + struct list_head *next, *prev; +}; +#endif + +struct __queue { + struct list_head queue; + _lock lock; +}; + +typedef struct __queue _queue; +typedef struct list_head _list; +typedef unsigned long _irqL; + +typedef void* _thread_hdl_; +typedef void thread_return; +typedef void* thread_context; + +#define ATOMIC_T atomic_t +#define HZ configTICK_RATE_HZ + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +/* emulate a modern version */ +#define LINUX_VERSION_CODE KERNEL_VERSION(2, 6, 17) + +static __inline _list *get_next(_list *list) +{ + return list->next; +} + +static __inline _list *get_list_head(_queue *queue) +{ + return (&(queue->queue)); +} + +#define LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)((char *)&((type *)ptr)->member - (char *)ptr))) +//#define container_of(p,t,n) (t*)((p)-&(((t*)0)->n)) +#define container_of(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#define TASK_PRORITY_LOW osPriorityAboveNormal//osPriorityNormal +#define TASK_PRORITY_MIDDLE osPriorityHigh//osPriorityAboveNormal +#define TASK_PRORITY_HIGH osPriorityRealtime//osPriorityHigh +#define TASK_PRORITY_SUPER osPriorityRealtime +#define TASK_PRORITY_IDEL osPriorityIdle + + +#define TIMER_MAX_DELAY 0xFFFFFFFF +void save_and_cli(void); +void restore_flags(void); +void cli(void); + +//----- ------------------------------------------------------------------ +// Common Definition +//----- ------------------------------------------------------------------ + +#define __init +#define __exit +#define __devinit +#define __devexit + +#define KERN_ERR +#define KERN_INFO +#define KERN_NOTICE + +#define GFP_KERNEL 1 +#define GFP_ATOMIC 1 + +#define SET_MODULE_OWNER(some_struct) do { } while (0) +#define SET_NETDEV_DEV(dev, obj) do { } while (0) +#define register_netdev(dev) (0) +#define unregister_netdev(dev) do { } while (0) +#define netif_queue_stopped(dev) (0) +#define netif_wake_queue(dev) do { } while (0) +#define printk printf + +#define DBG_ERR(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#if WLAN_INTF_DBG +#define DBG_TRACE(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#define DBG_INFO(fmt, args...) printf("\n\r[%s] " fmt, __FUNCTION__, ## args) +#else +#define DBG_TRACE(fmt, args...) +#define DBG_INFO(fmt, args...) +#endif +#define HALT() do { cli(); for(;;);} while(0) +#define ASSERT(x) do { \ + if((x) == 0) \ + printf("\n\rAssert(" #x ") failed on line %d in file %s", __LINE__, __FILE__); \ + HALT(); \ + } while(0) + +#undef DBG_ASSERT +#define DBG_ASSERT(x, msg) do { \ + if((x) == 0) \ + printf("\n\r%s, Assert(" #x ") failed on line %d in file %s", msg, __LINE__, __FILE__); \ + } while(0) + +//----- ------------------------------------------------------------------ +// Atomic Operation +//----- ------------------------------------------------------------------ +#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B) // for 8195A, it is defined in ..system../basic_types.h +typedef struct { volatile int counter; } atomic_t; +#endif + + +/* + * atomic_read - read atomic variable + * @v: pointer of type atomic_t + * + * Atomically reads the value of @v. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_read(v) ((v)->counter) + +/* + * atomic_set - set atomic variable + * @v: pointer of type atomic_t + * @i: required value + * + * Atomically sets the value of @v to @i. Note that the guaranteed + * useful range of an atomic_t is only 24 bits. + */ +#define atomic_set(v,i) ((v)->counter = (i)) + + /* + * These inlines deal with timer wrapping correctly. You are + * strongly encouraged to use them + * 1. Because people otherwise forget + * 2. Because if the timer wrap changes in future you wont have to + * alter your driver code. + * + * time_after(a,b) returns true if the time a is after time b. + * + * Do this with "<0" and ">=0" to only test the sign of the result. A + * good compiler would generate better code (and a really good compiler + * wouldn't care). Gcc is currently neither. + */ + #define time_after(a,b) ((long)(b) - (long)(a) < 0) + #define time_before(a,b) time_after(b,a) + + #define time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) + #define time_before_eq(a,b) time_after_eq(b,a) + + +extern void rtw_init_listhead(_list *list); +extern u32 rtw_is_list_empty(_list *phead); +extern void rtw_list_insert_head(_list *plist, _list *phead); +extern void rtw_list_insert_tail(_list *plist, _list *phead); +extern void rtw_list_delete(_list *plist); +#define vPortExitCritical save_and_cli +#endif /* _RTX_SERVICE_H_ */ + diff --git a/USDK/component/soc/realtek/8195a/cmsis/core_cm3.h b/USDK/component/soc/realtek/8195a/cmsis/core_cm3.h new file mode 100644 index 0000000..64db5c7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/core_cm3.h @@ -0,0 +1,1661 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x20) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03) /*!< Cortex-M Core */ + + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI__VFP_SUPPORT____ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +//#include /* rlx basic types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +//#include "hal_irqn.h" + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200 + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29 /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200)) + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + + +/** \brief Set Vector Table Offset + + + The function sets Vector Table Offset register. + + \param [in] TableAddress Vector table address. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetVectorTable(uint32_t TableAddress) +{ + SCB->VTOR = TableAddress; +} + + +/** \brief Set Vector Table Offset + + + The function sets Vector Table Offset register. + + \param [in] TableAddress Vector table address. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetCCR(void) +{ + uint32_t reg_value; + + reg_value = SCB->CCR; + reg_value |= SCB_CCR_DIV_0_TRP_Msk | SCB_CCR_UNALIGN_TRP_Msk; + SCB->CCR = reg_value; +} + + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = ticks - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/USDK/component/soc/realtek/8195a/cmsis/core_cmFunc.h b/USDK/component/soc/realtek/8195a/cmsis/core_cmFunc.h new file mode 100644 index 0000000..21cce31 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/core_cmFunc.h @@ -0,0 +1,636 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.20 + * @date 25. February 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +// #include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/USDK/component/soc/realtek/8195a/cmsis/core_cmInstr.h b/USDK/component/soc/realtek/8195a/cmsis/core_cmInstr.h new file mode 100644 index 0000000..9bf01e6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/core_cmInstr.h @@ -0,0 +1,688 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.20 + * @date 05. March 2013 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2009 - 2013 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +// #include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constrant "l" + * Otherwise, use general registers, specified by constrant "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + uint32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32 - op2)); +} + + +/** \brief Breakpoint + + This function causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/Descript.ion b/USDK/component/soc/realtek/8195a/cmsis/device/Descript.ion new file mode 100644 index 0000000..30da8cf --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/Descript.ion @@ -0,0 +1 @@ +app_start.c + diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/app_start.c b/USDK/component/soc/realtek/8195a/cmsis/device/app_start.c new file mode 100644 index 0000000..07ff402 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/app_start.c @@ -0,0 +1,265 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +//#include "build_info.h" +#include "rtl8195a.h" +#ifdef PLATFORM_FREERTOS +#include "FreeRTOS.h" +#include "task.h" +#include "platform_stdlib.h" +// #include "rtl_lib.h" +#endif + +#if defined (CONFIG_USB_EN) && defined(CONFIG_USB_HOST_ONLY) + extern void _usb_init(void); +#endif + +#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL) +extern VOID HalSdioInit(VOID); +#endif + +#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK) +extern void init_rom_wlan_ram_map(void); +extern VOID wlan_network(VOID); +#endif + +//3 Monitor App Function +extern VOID RtlConsolInitRam(u32 Boot, u32 TBLSz, VOID *pTBL); +#ifndef CONFIG_KERNEL +extern VOID RtlConsolTaskRom(VOID *Data); +#endif + +#ifndef CONFIG_WITHOUT_MONITOR +extern COMMAND_TABLE UartLogRamCmdTable[]; +extern u32 GetRamCmdNum(VOID); +extern VOID UartLogIrqHandleRam(VOID * Data); +#endif + +#ifdef CONFIG_APP_DEMO +#define MAIN_APP_DEFAULT_STACK_SIZE 2048 +#define MAIN_APP_DEFAULT_PRIORITY (tskIDLE_PRIORITY + 1) +#endif + +#ifdef CONFIG_MBED_ENABLED +extern void __libc_fini_array (void); +extern void __libc_init_array (void); +extern void SVC_Handler (void); +extern void PendSV_Handler (void); +extern void SysTick_Handler (void); +#endif + +#ifndef CONFIG_WITHOUT_MONITOR +static +VOID +ReRegisterPlatformLogUart( + VOID +) +{ + IRQ_HANDLE UartIrqHandle; + + //4 Register Log Uart Callback function + UartIrqHandle.Data = (u32)NULL;//(u32)&UartAdapter; + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) UartLogIrqHandleRam; + UartIrqHandle.Priority = 5; + + + //4 Register Isr handle + InterruptUnRegister(&UartIrqHandle); + InterruptRegister(&UartIrqHandle); +#if !TASK_SCHEDULER_DISABLED + RtlConsolInitRam((u32)RAM_STAGE,(u32)GetRamCmdNum(),(VOID*)&UartLogRamCmdTable); +#else + //RtlConsolInit(ROM_STAGE,GetRomCmdNum(),(VOID*)&UartLogRomCmdTable);// executing boot seq., + //pUartLogCtl->TaskRdy = 1; + RtlConsolInitRam((u32)ROM_STAGE,(u32)GetRamCmdNum(),(VOID*)&UartLogRamCmdTable); +#endif +} +#endif // end of "#ifndef CONFIG_WITHOUT_MONITOR" + + +VOID ShowRamBuildInfo(VOID) +{ + /* + DBG_8195A("=========================================================\n\n"); + //DBG_8195A("Build Time: "UTS_VERSION"\n"); + DBG_8195A("Build Time: "RTL8195AFW_COMPILE_TIME"\n"); + DBG_8195A("Build Author: "RTL8195AFW_COMPILE_BY"\n"); + DBG_8195A("Build Host: "RTL8195AFW_COMPILE_HOST"\n"); + DBG_8195A("Build ToolChain Version: "RTL195AFW_COMPILER"\n\n"); + DBG_8195A("=========================================================\n"); + */ +} + +#if 1 //def CONFIG_APP_DEMO +#include "rtl8195a.h" +//#include "device.h" +//#include "gpio_api.h" // mbed +typedef struct _UART_LOG_BUF_ { + u8 BufCount; //record the input cmd char number. + u8 UARTLogBuf[127]; //record the input command. +} UART_LOG_BUF, *PUART_LOG_BUF; + +//MON_RAM_BSS_SECTION +typedef struct _UART_LOG_CTL_ { + u8 NewIdx; //+0 + u8 SeeIdx; //+1 + u8 RevdNo; //+2 + u8 EscSTS; //+3 + u8 ExecuteCmd; //+4 + u8 ExecuteEsc; //+5 + u8 BootRdy; //+6 + u8 Resvd; //+7 + PUART_LOG_BUF pTmpLogBuf; + VOID *pfINPUT; + PCOMMAND_TABLE pCmdTbl; + u32 CmdTblSz; + + u32 CRSTS; + + u8 (*pHistoryBuf)[127]; + + u32 TaskRdy; + u32 Sema; +} UART_LOG_CTL, *PUART_LOG_CTL; + +extern volatile UART_LOG_CTL *pUartLogCtl; + +_WEAK int main(void) +{ + HalPinCtrlRtl8195A(JTAG, 0, 1); + + DiagPrintf("\r\nRTL Console ROM: Start - press key 'Up', Help '?'\r\n"); + while(pUartLogCtl->ExecuteEsc != 1); + pUartLogCtl->RevdNo = 0; + pUartLogCtl->BootRdy = 1; + DiagPrintf("\r"); + while(1) { + while(pUartLogCtl->ExecuteCmd != 1 ); + UartLogCmdExecute(pUartLogCtl); + DiagPrintf("\r"); + pUartLogCtl->ExecuteCmd = 0; + } + + return 0; +} +#else +//default main +_WEAK int main(void) +{ + // Init SDIO +#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL) + HalSdioInit(); +#endif + +#ifndef CONFIG_WITHOUT_MONITOR + ReRegisterPlatformLogUart(); +#endif + +#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK) + wlan_network(); +#else + +#if defined (CONFIG_USB_EN) && defined(CONFIG_USB_HOST_ONLY) + _usb_init(); +#endif + +#endif // end of else of "#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK)" + + //3 4)Enable Schedule +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + #ifdef PLATFORM_FREERTOS + vTaskStartScheduler(); + #endif +#else + RtlConsolTaskRom(NULL); +#endif + return 0; +} +#endif // end of #if CONFIG_APP_DEMO + +__weak void __low_level_init(void) +{ + // weak function +} + +#if defined ( __ICCARM__ ) +#pragma section="SDRAM.bss" +#pragma section="SDRAM.bss" +#endif +// The Main App entry point +void _AppStart(void) +{ +#ifdef CONFIG_MBED_ENABLED + InterruptForOSInit((VOID*)SVC_Handler, + (VOID*)PendSV_Handler, + (VOID*)SysTick_Handler); + __asm ( + "ldr r0, =SystemInit\n" + "blx r0\n" + "ldr r0, =_start\n" + "bx r0\n" + ); + + for(;;); +#else + // It's Not Mbed BSP +#ifdef CONFIG_KERNEL +#endif + + // Disable debug info log of spiflash + DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_); + +#ifdef CONFIG_APP_DEMO +#ifdef PLATFORM_FREERTOS + xTaskCreate( (TaskFunction_t)main, "MAIN_APP__TASK", (MAIN_APP_DEFAULT_STACK_SIZE/4), (void *)NULL, MAIN_APP_DEFAULT_PRIORITY, NULL); + vTaskStartScheduler(); +#endif + +#else + + __low_level_init(); +#if defined ( __ICCARM__ ) + // __iar_data_init3 replaced by __iar_cstart_call_ctors, just do c++ constructor, + __iar_cstart_call_ctors(NULL); +#ifdef CONFIG_SDR_EN + // clear SDRAM bss + u8* __sdram_bss_start__ = (u8*)__section_begin("SDRAM.bss"); + u8* __sdram_bss_end__ = (u8*)__section_end("SDRAM.bss"); + //DiagPrintf("clean sdram bss %8x to %8x\n\r", __sdram_bss_start__, __sdram_bss_end__); + if((int)__sdram_bss_end__-(int)__sdram_bss_start__ > 0) + memset(__sdram_bss_start__, 0, (int)__sdram_bss_end__-(int)__sdram_bss_start__); +#endif +#elif defined ( __GNUC__ ) +#ifdef CONFIG_SDR_EN + // clear SDRAM bss + extern u8 __sdram_bss_start__[]; + extern u8 __sdram_bss_end__[]; + //DiagPrintf("clean sdram bss %8x to %8x\n\r", __sdram_bss_start__, __sdram_bss_end__); + if((int)__sdram_bss_end__-(int)__sdram_bss_start__ > 0) + memset(__sdram_bss_start__, 0, (int)__sdram_bss_end__-(int)__sdram_bss_start__); +#endif +#else + #error !!!!!!NOT Support this compiler!!!!!! +#endif + // force SP align to 8 byte not 4 byte (initial SP is 4 byte align) + __asm( + "mov r0, sp\n" + "bic r0, r0, #7\n" + "mov sp, r0\n" + ); + + main(); +#if defined ( __ICCARM__ ) + // for compile issue, If user never call this function, Liking fail + __iar_data_init3(); +#endif +#endif // end of #if CONFIG_APP_DEMO + +#endif // end of else of "#ifdef CONFIG_MBED_ENABLED" +} diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/cmsis.h b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis.h new file mode 100644 index 0000000..420fd53 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis.h @@ -0,0 +1,38 @@ +/* mbed Microcontroller Library + * A generic CMSIS include header + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_H +#define MBED_CMSIS_H + +#include "rtl8195a.h" +#include "cmsis_nvic.h" + +#endif diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c new file mode 100644 index 0000000..e89187b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.c @@ -0,0 +1,55 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#include "cmsis_nvic.h" + +#define NVIC_RAM_VECTOR_ADDRESS (0x10000000) // Vectors positioned at start of RAM +#define NVIC_ROM_VECTOR_ADDRESS (0x00000000) // Initial vector position at start of ROM + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) { + uint32_t *vectors = (uint32_t *)SCB->VTOR; + uint32_t i; + + // Copy and switch to dynamic vectors if the first time called + if (SCB->VTOR != NVIC_RAM_VECTOR_ADDRESS) { + uint32_t *old_vectors = vectors; + vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS; + for (i=0; iVTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS; + } + vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + +uint32_t NVIC_GetVector(IRQn_Type IRQn) { + uint32_t *vectors = (uint32_t*)SCB->VTOR; + return vectors[IRQn + NVIC_USER_IRQ_OFFSET]; +} diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.h b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.h new file mode 100644 index 0000000..ca0b5b9 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/cmsis_nvic.h @@ -0,0 +1,54 @@ +/* mbed Microcontroller Library + * CMSIS-style functionality to support dynamic vectors + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +// CORE: 64 vectors = 64 bytes from 0x00 to 0x3F +// MCU Peripherals: 85 vectors = 340 bytes from 0x40 to ... +// Total: 128 vectors = 512 bytes (0x200) to be reserved in RAM +#define NVIC_NUM_VECTORS 128 +#define NVIC_USER_IRQ_OFFSET 64 + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/diag.h b/USDK/component/soc/realtek/8195a/cmsis/device/diag.h new file mode 100644 index 0000000..b81c084 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/diag.h @@ -0,0 +1,888 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _DIAG_H_ +#define _DIAG_H_ + +#include "basic_types.h" +#include "platform_autoconf.h" + +#include /* for size_t */ + +extern u32 ConfigDebugErr; +extern u32 ConfigDebugInfo; +extern u32 ConfigDebugWarn; + +extern u32 CfgSysDebugErr; +extern u32 CfgSysDebugInfo; +extern u32 CfgSysDebugWarn; + +#define DBG_ERR_MSG_ON(x) (ConfigDebugErr |= (x)) +#define DBG_WARN_MSG_ON(x) (ConfigDebugWarn |= (x)) +#define DBG_INFO_MSG_ON(x) (ConfigDebugInfo |= (x)) + +#define DBG_ERR_MSG_OFF(x) (ConfigDebugErr &= ~(x)) +#define DBG_WARN_MSG_OFF(x) (ConfigDebugWarn &= ~(x)) +#define DBG_INFO_MSG_OFF(x) (ConfigDebugInfo &= ~(x)) + +// Define debug group +#define _DBG_BOOT_ 0x00000001 +#define _DBG_GDMA_ 0x00000002 +#define _DBG_GPIO_ 0x00000004 +#define _DBG_TIMER_ 0x00000008 +#define _DBG_I2C_ 0x00000010 +#define _DBG_I2S_ 0x00000020 +#define _DBG_MII_ 0x00000040 +#define _DBG_NFC_ 0x00000080 +#define _DBG_PCM_ 0x00000100 +#define _DBG_PWM_ 0x00000200 +#define _DBG_SDIO_ 0x00000400 +#define _DBG_SSI_ 0x00000800 +#define _DBG_SPI_FLASH_ 0x00001000 +#define _DBG_SDR_ 0x00002000 +#define _DBG_UART_ 0x00004000 +#define _DBG_USB_OTG_ 0x00008000 +#define _DBG_USB_CORE_ 0x00010000 +#define _DBG_CRYPTO_ 0x00020000 +#define _DBG_ADC_ 0x00040000 +#define _DBG_DAC_ 0x00080000 +#define _DBG_TCM_HEAP_ 0x00100000 +#define _DBG_RAM_HEAP_ 0x00200000 +#define _DBG_FEEP_ 0x00400000 + +#define _DBG_MISC_ 0x40000000 +#define _DBG_FAULT_ 0x80000000 + +typedef enum _SYSTEM_DBG_DEFINE_ { + _SYSDBG_MISC_ = 1<<0, + _SYSDBG_MAILBOX_ = 1<<1, + _SYSDBG_TIMER_ = 1<<2 + +} SYSTEM_DBG; + +extern +_LONG_CALL_ROM_ u32 +DiagPrintf( + IN const char *fmt, ... +); + +u32 +DiagSPrintf( + IN u8 *buf, + IN const char *fmt, ... +); + +int +prvDiagPrintf( + IN const char *fmt, ... +); + +int +prvDiagSPrintf( + IN char *buf, + IN const char *fmt, ... +); + +extern char print_off; + +#if CONFIG_DEBUG_LOG > 3 +#define debug_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define info_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define warning_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define error_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#elif CONFIG_DEBUG_LOG > 2 +#define debug_printf(fmt, ...) +#define info_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define warning_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define error_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#elif CONFIG_DEBUG_LOG > 1 +#define debug_printf(fmt, ...) +#define info_printf(fmt, ...) +#define warning_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#define error_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#elif CONFIG_DEBUG_LOG > 0 +#define debug_printf(fmt, ...) +#define info_printf(fmt, ...) +#define warning_printf(fmt, ...) +#define error_printf(fmt, ...) rtl_printf(fmt, ##__VA_ARGS__) +#else +#define debug_printf(fmt, ...) +#define info_printf(fmt, ...) +#define warning_printf(fmt, ...) +#define error_printf(fmt, ...) +#endif + +#define _DbgDump DiagPrintf + +#define DRIVER_PREFIX "RTL8195A[Driver]: " +#define HAL_PREFIX "RTL8195A[HAL]: " +#define DMA_PREFIX "RTL8195A[DMA]: " +#define SDIO_PREFIX "RTL8195A[SDIO]" +#define MBOX_PREFIX "[OS-MBOX]" +#define TIMER_PREFIX "[OS-TMR]" + +#define BOOT_ERR_PREFIX "[BOOT Err]" +#define BOOT_WARN_PREFIX "[BOOT Wrn]" +#define BOOT_INFO_PREFIX "[BOOT Inf]" + +#define GDMA_ERR_PREFIX "[GDMA Err]" +#define GDMA_WARN_PREFIX "[GDMA Wrn]" +#define GDMA_INFO_PREFIX "[GDMA Inf]" + +#define GPIO_ERR_PREFIX "[GPIO Err]" +#define GPIO_WARN_PREFIX "[GPIO Wrn]" +#define GPIO_INFO_PREFIX "[GPIO Inf]" + +#define TIMER_ERR_PREFIX "[TIMR Err]" +#define TIMER_WARN_PREFIX "[TIMR Wrn]" +#define TIMER_INFO_PREFIX "[TIMR Inf]" + +#define I2C_ERR_PREFIX "[I2C Err]" +#define I2C_WARN_PREFIX "[I2C Wrn]" +#define I2C_INFO_PREFIX "[I2C Inf]" + +#define I2S_ERR_PREFIX "[I2S Err]" +#define I2S_WARN_PREFIX "[I2S Wrn]" +#define I2S_INFO_PREFIX "[I2S Inf]" + +#define MII_ERR_PREFIX "[MII Err]" +#define MII_WARN_PREFIX "[MII Wrn]" +#define MII_INFO_PREFIX "[MII Inf]" + +#define NFC_ERR_PREFIX "[NFC Err]" +#define NFC_WARN_PREFIX "[NFC Wrn]" +#define NFC_INFO_PREFIX "[NFC Inf]" + +#define PCM_ERR_PREFIX "[PCM Err]" +#define PCM_WARN_PREFIX "[PCM Wrn]" +#define PCM_INFO_PREFIX "[PCM Inf]" + +#define PWM_ERR_PREFIX "[PWM Err]" +#define PWM_WARN_PREFIX "[PWM Wrn]" +#define PWM_INFO_PREFIX "[PWM Inf]" + +#define SSI_ERR_PREFIX "[SSI Err]" +#define SSI_WARN_PREFIX "[SSI Wrn]" +#define SSI_INFO_PREFIX "[SSI Inf]" + +#define SDIO_ERR_PREFIX "[SDIO Err]" +#define SDIO_WARN_PREFIX "[SDIO Wrn]" +#define SDIO_INFO_PREFIX "[SDIO Inf]" + +#define SPIF_ERR_PREFIX "[SPIF Err]" +#define SPIF_WARN_PREFIX "[SPIF Wrn]" +#define SPIF_INFO_PREFIX "[SPIF Inf]" + +#define SDR_ERR_PREFIX "[SDR Err]" +#define SDR_WARN_PREFIX "[SDR Wrn]" +#define SDR_INFO_PREFIX "[SDR Inf]" + +#define UART_ERR_PREFIX "[UART Err]" +#define UART_WARN_PREFIX "[UART Wrn]" +#define UART_INFO_PREFIX "[UART Inf]" + +#define USB_ERR_PREFIX "[USB Err]" +#define USB_WARN_PREFIX "[USB Wrn]" +#define USB_INFO_PREFIX "[USB Inf]" + +#define IPSEC_ERR_PREFIX "[CRYP Err]" +#define IPSEC_WARN_PREFIX "[CRYP Wrn]" +#define IPSEC_INFO_PREFIX "[CRYP Inf]" + +#define ADC_ERR_PREFIX "[ADC Err]" +#define ADC_WARN_PREFIX "[ADC Wrn]" +#define ADC_INFO_PREFIX "[ADC Inf]" + +#define DAC_ERR_PREFIX "[DAC Err]" +#define DAC_WARN_PREFIX "[DAC Wrn]" +#define DAC_INFO_PREFIX "[DAC Inf]" + +#define MISC_ERR_PREFIX "[MISC Err]" +#define MISC_WARN_PREFIX "[MISC Wrn]" +#define MISC_INFO_PREFIX "[MISC Inf]" + +#define OTG_ERR_PREFIX "[OTG Err]" +#define OTG_WARN_PREFIX "[OTG Wrn]" +#define OTG_INFO_PREFIX "[OTG Inf]" + +#define HEAP_ERR_PREFIX "[HEAP Err]" +#define HEAP_WARN_PREFIX "[HEAP Wrn]" +#define HEAP_INFO_PREFIX "[HEAP Inf]" + +#define FEEP_ERR_PREFIX "[FEEP Err]" +#define FEEP_WARN_PREFIX "[FEEP Wrn]" +#define FEEP_INFO_PREFIX "[FEEP Inf]" + +#define OTG_PREFIX "RTL8195A[OTG]: " +#define OTG_PREFIX_LVL "RTL8195A[OTG_LVL_%2x]: " + +#ifdef CONFIG_DEBUG_LOG + #if CONFIG_DEBUG_LOG > 2 + #define CONFIG_DEBUG_ERROR 1 + #define CONFIG_DEBUG_WARN 1 + #define CONFIG_DEBUG_INFO 1 + #elif CONFIG_DEBUG_LOG > 1 + #define CONFIG_DEBUG_ERROR 1 + #define CONFIG_DEBUG_WARN 1 + #elif CONFIG_DEBUG_LOG > 0 + #define CONFIG_DEBUG_ERROR 1 + #endif +#endif + +#ifndef likely +#define likely(x) (x) +#define unlikely(x) (x) +#endif + + +#if CONFIG_DEBUG_ERROR // if Build-In Debug Error Message + +#define DBG_BOOT_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_BOOT_)) \ + _DbgDump(BOOT_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GDMA_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_GDMA_)) \ + _DbgDump(GDMA_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GPIO_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_GPIO_)) \ + _DbgDump(GPIO_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_TIMER_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_TIMER_)) \ + _DbgDump(TIMER_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2C_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_I2C_)) \ + _DbgDump(I2C_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2S_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_I2S_)) \ + _DbgDump(I2S_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_MII_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_MII_)) \ + _DbgDump(MII_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_NFC_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_NFC_)) \ + _DbgDump(NFC_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PCM_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_PCM_)) \ + _DbgDump(PCM_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PWM_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_PWM_)) \ + _DbgDump(PWM_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SSI_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_SSI_)) \ + _DbgDump(SSI_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDIO_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_SDIO_)) \ + _DbgDump(SDIO_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SPIF_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_SPI_FLASH_)) \ + _DbgDump(SPIF_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDR_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_SDR_)) \ + _DbgDump(SDR_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_UART_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_UART_)) \ + _DbgDump(UART_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_USBOTG_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_USB_OTG_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#define DBG_USBCOR_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_USB_CORE_)) \ + _DbgDump(USB_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_CRYPTO_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_CRYPTO_)) \ + _DbgDump(IPSEC_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_ADC_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_ADC_)) \ + _DbgDump(ADC_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_DAC_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_DAC_)) \ + _DbgDump(DAC_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_MBOX_ERR(...) do {\ + if (likely(CfgSysDebugErr & _SYSDBG_MAILBOX_)) \ + _DbgDump(MBOX_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_TIMER_ERR(...) do {\ + if (likely(CfgSysDebugErr & _SYSDBG_TIMER_)) \ + _DbgDump(TIMER_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_8195A_OTG(...) do{\ + if (unlikely(ConfigDebugInfo & _DBG_USB_OTG_)) \ + _DbgDump(OTG_PREFIX __VA_ARGS__);\ + }while(0) + +#define DBG_8195A_OTG_INFO(...) do{\ + if (unlikely(ConfigDebugInfo & _DBG_USB_OTG_)) \ + _DbgDump(OTG_PREFIX __VA_ARGS__);\ + }while(0) + +#define DBG_8195A_OTG_WARN(...) do{\ + if (unlikely(ConfigDebugWarn & _DBG_USB_OTG_)) \ + _DbgDump(OTG_PREFIX __VA_ARGS__);\ + }while(0) + +#define DBG_8195A_OTG_ERR(...) do{\ + if (unlikely(ConfigDebugErr & _DBG_USB_OTG_)) \ + _DbgDump(OTG_PREFIX __VA_ARGS__);\ + }while(0) + +#define DBG_8195A_OTG_LVL(LVL,...) do{\ + if (unlikely(ConfigDebugInfo & _DBG_USB_OTG_)){ \ + _DbgDump(OTG_PREFIX_LVL,LVL);\ + _DbgDump(__VA_ARGS__);\ + }\ +}while(0) + +#define DBG_TCM_HEAP_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_TCM_HEAP_)){ \ + _DbgDump(HEAP_ERR_PREFIX ANSI_COLOR_RED);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_RAM_HEAP_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_RAM_HEAP_)){ \ + _DbgDump(HEAP_ERR_PREFIX ANSI_COLOR_RED);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_MISC_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_MISC_)) \ + _DbgDump(MISC_ERR_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_FEEP_ERR(...) do {\ + if (likely(ConfigDebugErr & _DBG_FEEP_)) \ + _DbgDump(FEEP_ERR_PREFIX __VA_ARGS__);\ +}while(0) + + +#else // else of "#if CONFIG_DEBUG_ERROR" + +#define DBG_BOOT_ERR(...) +#define DBG_GDMA_ERR(...) +#define DBG_GPIO_ERR(...) +#define DBG_TIMER_ERR(...) +#define DBG_I2C_ERR(...) +#define DBG_I2S_ERR(...) +#define DBG_MII_ERR(...) +#define DBG_NFC_ERR(...) +#define DBG_PCM_ERR(...) +#define DBG_PWM_ERR(...) +#define DBG_SSI_ERR(...) +#define DBG_SDIO_ERR(...) +#define DBG_SPIF_ERR(...) +#define DBG_SDR_ERR(...) +#define DBG_UART_ERR(...) +#define DBG_USBOTG_ERR(...) +#define DBG_USBCOR_ERR(...) +#define DBG_CRYPTO_ERR(...) +#define DBG_ADC_ERR(...) +#define DBG_DAC_ERR(...) + +#define MSG_MBOX_ERR(...) +#define MSG_TIMER_ERR(...) +#define DBG_8195A_OTG(...) +#define DBG_8195A_OTG_LVL(LVL,...) +#define DBG_8195A_OTG_INFO(...) +#define DBG_8195A_OTG_WARN(...) +#define DBG_8195A_OTG_ERR(...) + +#define DBG_TCM_HEAP_ERR(...) +#define DBG_RAM_HEAP_ERR(...) +#define DBG_FEEP_ERR(...) +#define DBG_MISC_ERR(...) + +#endif // end of else of "#if CONFIG_DEBUG_ERROR" + +// ============================================================= + +#if CONFIG_DEBUG_WARN // if Build-In Debug Warring Message + +#define DBG_BOOT_WARN(...) do {\ + if (unlikely(ConfigDebugWarn& _DBG_BOOT_)) \ + _DbgDump(BOOT_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GDMA_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_GDMA_)) \ + _DbgDump(GDMA_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GPIO_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_GPIO_)) \ + _DbgDump(GPIO_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_TIMER_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_TIMER_)) \ + _DbgDump(TIMER_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2C_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_I2C_)) \ + _DbgDump(I2C_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2S_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_I2S_)) \ + _DbgDump(I2S_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_MII_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_MII_)) \ + _DbgDump(MII_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_NFC_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_NFC_)) \ + _DbgDump(NFC_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PCM_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_PCM_)) \ + _DbgDump(PCM_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PWM_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_PWM_)) \ + _DbgDump(PWM_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SSI_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_SSI_)) \ + _DbgDump(SSI_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDIO_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_SDIO_)) \ + _DbgDump(SDIO_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SPIF_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_SPI_FLASH_)) \ + _DbgDump(SPIF_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDR_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_SDR_)) \ + _DbgDump(SDR_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_UART_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_UART_)) \ + _DbgDump(UART_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_USBOTG_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_USB_OTG_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#define DBG_USBCOR_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_USB_CORE_)) \ + _DbgDump(USB_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_CRYPTO_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_CRYPTO_)) \ + _DbgDump(IPSEC_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_ADC_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_ADC_)) \ + _DbgDump(ADC_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_DAC_WARN(...) do {\ + if (unlikely(ConfigDebugWarn & _DBG_DAC_)) \ + _DbgDump(DAC_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_MBOX_WARN(...) do {\ + if (unlikely(CfgSysDebugWarn& _SYSDBG_MAILBOX_)) \ + _DbgDump(MBOX_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_TIMER_WARN(...) do {\ + if (unlikely(CfgSysDebugWarn & _SYSDBG_TIMER_)) \ + _DbgDump(TIMER_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_TCM_HEAP_WARN(...) do {\ + if (likely(ConfigDebugWarn & _DBG_TCM_HEAP_)){ \ + _DbgDump(HEAP_WARN_PREFIX ANSI_COLOR_MAGENTA);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_RAM_HEAP_WARN(...) do {\ + if (likely(ConfigDebugWarn & _DBG_RAM_HEAP_)){ \ + _DbgDump(HEAP_WARN_PREFIX ANSI_COLOR_MAGENTA);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_FEEP_WARN(...) do {\ + if (likely(ConfigDebugWarn & _DBG_FEEP_)) \ + _DbgDump(FEEP_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_MISC_WARN(...) do {\ + if (likely(ConfigDebugWarn & _DBG_MISC_)) \ + _DbgDump(MISC_WARN_PREFIX __VA_ARGS__);\ +}while(0) + +#else // else of "#if CONFIG_DEBUG_WARN" + +#define DBG_BOOT_WARN(...) +#define DBG_GDMA_WARN(...) +#define DBG_GPIO_WARN(...) +#define DBG_TIMER_WARN(...) +#define DBG_I2C_WARN(...) +#define DBG_I2S_WARN(...) +#define DBG_MII_WARN(...) +#define DBG_NFC_WARN(...) +#define DBG_PCM_WARN(...) +#define DBG_PWM_WARN(...) +#define DBG_SSI_WARN(...) +#define DBG_SDIO_WARN(...) +#define DBG_SPIF_WARN(...) +#define DBG_SDR_WARN(...) +#define DBG_UART_WARN(...) +#define DBG_USBOTG_WARN(...) +#define DBG_USBCOR_WARN(...) +#define DBG_CRYPTO_WARN(...) +#define DBG_ADC_WARN(...) +#define DBG_DAC_WARN(...) +#define DBG_TCM_HEAP_WARN(...) +#define DBG_RAM_HEAP_WARN(...) +#define DBG_FEEP_WARN(...) +#define DBG_MISC_WARN(...) + +#define MSG_MBOX_WARN(...) +#define MSG_TIMER_WARN(...) + +#endif // end of else of "#if CONFIG_DEBUG_WARN" + +// ============================================================= + +#if CONFIG_DEBUG_INFO // if Build-In Debug Information Message + +#define DBG_BOOT_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_BOOT_)) \ + _DbgDump(BOOT_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GDMA_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_GDMA_)) \ + _DbgDump(GDMA_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_GPIO_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_GPIO_)) \ + _DbgDump(GPIO_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_TIMER_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_TIMER_)) \ + _DbgDump(TIMER_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2C_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_I2C_)) \ + _DbgDump(I2C_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_I2S_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_I2S_)) \ + _DbgDump(I2S_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_MII_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_MII_)) \ + _DbgDump(MII_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_NFC_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_NFC_)) \ + _DbgDump(NFC_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PCM_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_PCM_)) \ + _DbgDump(PCM_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_PWM_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_PWM_)) \ + _DbgDump(PWM_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SSI_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_SSI_)) \ + _DbgDump(SSI_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDIO_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_SDIO_)) \ + _DbgDump(SDIO_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SPIF_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_SPI_FLASH_)) \ + _DbgDump(SPIF_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_SDR_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_SDR_)) \ + _DbgDump(SDR_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_UART_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_UART_)) \ + _DbgDump(UART_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_USBOTG_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_USB_OTG_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#define DBG_USBCOR_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_USB_CORE_)) \ + _DbgDump(USB_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_CRYPTO_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_CRYPTO_)) \ + _DbgDump(IPSEC_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_ADC_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_ADC_)) \ + _DbgDump(ADC_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_DAC_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_DAC_)) \ + _DbgDump(DAC_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_MBOX_INFO(...) do {\ + if (unlikely(CfgSysDebugInfo & _SYSDBG_MAILBOX_)) \ + _DbgDump(MBOX_PREFIX __VA_ARGS__);\ +}while(0) + +#define MSG_TIMER_INFO(...) do {\ + if (unlikely(CfgSysDebugInfo & _SYSDBG_TIMER_)) \ + _DbgDump(TIMER_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_TCM_HEAP_INFO(...) do {\ + if (likely(ConfigDebugInfo & _DBG_TCM_HEAP_)){\ + _DbgDump(HEAP_INFO_PREFIX ANSI_COLOR_BLUE);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_RAM_HEAP_INFO(...) do {\ + if (likely(ConfigDebugInfo & _DBG_RAM_HEAP_)){ \ + _DbgDump(HEAP_INFO_PREFIX ANSI_COLOR_BLUE);\ + _DbgDump(__VA_ARGS__ );\ + _DbgDump(ANSI_COLOR_RESET);}\ +}while(0) + +#define DBG_FEEP_INFO(...) do {\ + if (unlikely(ConfigDebugInfo & _DBG_FEEP_)) \ + _DbgDump(FEEP_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_MISC_INFO(...) do {\ + if (likely(ConfigDebugInfo & _DBG_MISC_)) \ + _DbgDump(MISC_INFO_PREFIX __VA_ARGS__);\ +}while(0) + +#else // else of "#if CONFIG_DEBUG_INFO" + +#define DBG_BOOT_INFO(...) +#define DBG_GDMA_INFO(...) +#define DBG_GPIO_INFO(...) +#define DBG_TIMER_INFO(...) +#define DBG_I2C_INFO(...) +#define DBG_I2S_INFO(...) +#define DBG_MII_INFO(...) +#define DBG_NFC_INFO(...) +#define DBG_PCM_INFO(...) +#define DBG_PWM_INFO(...) +#define DBG_SSI_INFO(...) +#define DBG_SDIO_INFO(...) +#define DBG_SPIF_INFO(...) +#define DBG_SDR_INFO(...) +#define DBG_UART_INFO(...) +#define DBG_USBOTG_INFO(...) +#define DBG_USBCOR_INFO(...) +#define DBG_CRYPTO_INFO(...) +#define DBG_ADC_INFO(...) +#define DBG_DAC_INFO(...) +#define DBG_RAM_HEAP_INFO(...) +#define DBG_TCM_HEAP_INFO(...) +#define DBG_FEEP_INFO(...) +#define DBG_MISC_INFO(...) + +#define MSG_MBOX_INFO(...) +#define MSG_TIMER_INFO(...) + +#endif // end of else of "#if CONFIG_DEBUG_INFO" + +// ============================================================= + +#ifdef CONFIG_DEBUG_LOG + +#define DBG_8195A_DRIVER(...) do {\ + if (unlikely(ConfigDebugErr & (_DBG_I2S_|_DBG_PCM_|_DBG_TIMER_))) \ + _DbgDump(DRIVER_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_8195A_HAL(...) do {\ + if (unlikely(ConfigDebugErr & (_DBG_SDR_|_DBG_MISC_))) \ + _DbgDump(HAL_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_8195A_DMA(...) do {\ + if (unlikely(ConfigDebugErr & _DBG_GDMA_)) \ + _DbgDump(DMA_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_8195A_SDIO(...) do {\ + if (unlikely(ConfigDebugErr & _DBG_SDIO_)) \ + _DbgDump(SDIO_PREFIX __VA_ARGS__);\ +}while(0) + +#define DBG_8195A(...) do {\ + if (unlikely(ConfigDebugErr & _DBG_MISC_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#define MONITOR_LOG(...) do {\ + if (unlikely(ConfigDebugErr & _DBG_MISC_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#define DBG_ERROR_LOG(...) do {\ + if (unlikely(ConfigDebugErr & _DBG_FAULT_)) \ + _DbgDump( __VA_ARGS__);\ +}while(0) + +#ifdef __GNUC__ +#define DBG_ASSERT(x) do {\ + if (unlikely(!(x))) \ + _DbgDump("Assertion: %s:%s, %d\n", __FILE__, __func__, __LINE__);\ + }while(0) +#endif + +#ifdef __ICCARM__ +#define DBG_ASSERT(x) do {\ + if (unlikely(!(x))) \ + _DbgDump("Assertion: %s:%s, %d\n", __FILE__, __func__, __LINE__);\ + }while(0) +#endif + +#else // #ifdef CONFIG_DEBUG_LOG + +#define DBG_8195A_DRIVER(...) +#define DBG_8195A_HAL(...) +#define DBG_8195A_DMA(...) +#define DBG_8195A_SDIO(...) +#define DBG_8195A(...) +#define MONITOR_LOG(...) +#define DBG_ERROR_LOG(...) +#define DBG_ASSERT(...) + +#endif // #ifdef CONFIG_DEBUG_LOG + +// ============================================================= + +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#define IDENT_ONE_SPACE " " +#define IDENT_TWO_SPACE " " +#define IDENT_FOUR_SPACE " " +#define IDENT_SIX_SPACE " " +#define IDENT_EIGHT_SPACE " " + +// ============================================================= + +#ifdef CONFIG_DEBUG_LOG +typedef enum _DBG_CFG_TYPE_ { + DBG_CFG_ERR=0, + DBG_CFG_WARN=1, + DBG_CFG_INFO=2 +} DBG_CFG_TYPE; + +typedef struct _DBG_CFG_CMD_ { + u8 cmd_name[16]; + u32 cmd_type; +} DBG_CFG_CMD, *PDBG_CFG_CMD; +#endif // #ifdef CONFIG_DEBUG_LOG + +typedef enum _CONSOLE_OP_STAGE_ { + ROM_STAGE = 0, + RAM_STAGE = 1 +}CONSOLE_OP_STAGE; + +#endif //_DIAG_H_ diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/rand.h b/USDK/component/soc/realtek/8195a/cmsis/device/rand.h new file mode 100644 index 0000000..47ac51e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/rand.h @@ -0,0 +1,15 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +u32 +Rand ( + VOID +); + + diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/rtl_stdlib.h b/USDK/component/soc/realtek/8195a/cmsis/device/rtl_stdlib.h new file mode 100644 index 0000000..aa54e7c --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/rtl_stdlib.h @@ -0,0 +1,41 @@ +/* + * Routines for standard lib access + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL_STDLIB_H_ +#define _RTL_STDLIB_H_ +#if 0 +#include +#include +#include + +// +// string operation +// +#define strlen(str) prvStrLen((const u8*)str) +#define strcmp(str1, str2) prvStrCmp((const u8*)str1, (const u8*)str2) +//#define sscanf(src, format...) //TODO: Strtoul(src,0,16) / Strtoul(src,0,10) +#define strtok(str, delim) prvStrTok(str, delim) +#define strcpy(dst, src) prvStrCpy((u8 *)dst, (const u8*)src) +#define atoi(str) prvAtoi(str) +#define strstr(str1, str2) prvStrStr(str1, str2) + +// +// standard i/o +// +#define snprintf DiagSnPrintf +#define sprintf prvDiagSPrintf +#define printf prvDiagPrintf + +// +// memory management +// +#define malloc pvPortMalloc +#define free vPortFree +#endif +#endif //_RTL_STDLIB_H_ diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/rtl_utility.h b/USDK/component/soc/realtek/8195a/cmsis/device/rtl_utility.h new file mode 100644 index 0000000..6fa22ff --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/rtl_utility.h @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __RTL_UTILITY_H_ +#define __RTL_UTILITY_H_ + +VOID RtlMemcpy(VOID* dec, VOID* sour, u32 sz); +u32 RtlMemcmp(VOID *dst, VOID *src, u32 sz); +VOID RtlMemset(VOID *pbuf, u32 c, u32 sz); + +s8 * +RtlStrncpy( + IN s8 *dest, + IN const s8 *src, + IN SIZE_T count +); + +s8 * +RtlStrcpy( + IN s8 *dest, + IN const s8 *src +); + + +SIZE_T +RtlStrlen( + IN const s8 *s +); + + +SIZE_T +RtlStrnlen( + IN const s8 *s, + IN SIZE_T count +); + + +int +RtlStrcmp( + IN const s8 *cs, + IN const s8 *ct + +); + +int +RtlStrncmp( + IN const s8 *cs, + IN const s8 *ct, + IN SIZE_T count +); + +#endif + + diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/strproc.h b/USDK/component/soc/realtek/8195a/cmsis/device/strproc.h new file mode 100644 index 0000000..49c66f6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/strproc.h @@ -0,0 +1,105 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _STRPROC_H_ +#define _STRPROC_H_ + +#include /* for size_t */ +#include + +#ifndef isprint +#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',') +#endif + + +extern _LONG_CALL_ROM_ char *_strncpy(char *dest, const char *src, size_t count); +extern _LONG_CALL_ROM_ char *_strcpy(char *dest, const char *src); +extern _LONG_CALL_ROM_ size_t _strlen(const char *s); +extern _LONG_CALL_ROM_ size_t _strnlen(const char *s, size_t count); +extern _LONG_CALL_ROM_ int _strcmp(const char *cs, const char *ct); +extern _LONG_CALL_ROM_ int _strncmp(const char *cs, const char *ct, size_t count); +extern _LONG_CALL_ROM_ int _sscanf(const char *buf, const char *fmt, ...); +extern _LONG_CALL_ROM_ char *_strsep(char **s, const char *ct); +extern _LONG_CALL_ROM_ char *skip_spaces(const char *str); +extern _LONG_CALL_ROM_ int skip_atoi(const char **s); +extern _LONG_CALL_ROM_ int _vsscanf(const char *buf, const char *fmt, va_list args); +extern _LONG_CALL_ROM_ unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); +extern _LONG_CALL_ROM_ long simple_strtol(const char *cp, char **endp, unsigned int base); +extern _LONG_CALL_ROM_ long long simple_strtoll(const char *cp, char **endp, unsigned int base); +extern _LONG_CALL_ROM_ unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base); +extern _LONG_CALL_ROM_ const char *_parse_integer_fixup_radix(const char *s, unsigned int *base); +extern _LONG_CALL_ROM_ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p); +extern _LONG_CALL_ROM_ u64 div_u64(u64 dividend, u32 divisor); +extern _LONG_CALL_ROM_ s64 div_s64(s64 dividend, s32 divisor); +extern _LONG_CALL_ROM_ u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder); +extern _LONG_CALL_ROM_ s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder); +extern _LONG_CALL_ROM_ char *_strpbrk(const char *cs, const char *ct); +extern _LONG_CALL_ROM_ char *_strchr(const char *s, int c); + + +extern _LONG_CALL_ROM_ VOID +prvStrCpy( + IN u8 *pDES, + IN const u8 *pSRC +); + +extern _LONG_CALL_ROM_ u32 +prvStrLen( + IN const u8 *pSRC +); + +extern _LONG_CALL_ROM_ u8 +prvStrCmp( + IN const u8 *string1, + IN const u8 *string2 +); + +extern _LONG_CALL_ROM_ u8* +StrUpr( + IN u8 *string +); + +extern _LONG_CALL_ROM_ int prvAtoi( + IN const char * s +); + +extern _LONG_CALL_ROM_ const char * prvStrStr( + IN const char * str1, + IN const char * str2 +); + +#ifndef __GNUC__ +/* + * Fast implementation of tolower() for internal usage. Do not use in your + * code. + */ +static inline char _tolower(const char c) +{ + return c | 0x20; +} +#endif + +/* Fast check for octal digit */ +static inline int isodigit(const char c) +{ + return c >= '0' && c <= '7'; +} +#ifndef strtoul +#define strtoul(str, endp, base) simple_strtoul(str, endp, base) +#endif +#ifndef strtol +#define strtol(str, endp, base) simple_strtol(str, endp, base) +#endif + +#endif diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.c b/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.c new file mode 100644 index 0000000..7921dc1 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.c @@ -0,0 +1,142 @@ +/**************************************************************************//** + * @file system_ARMCM3.c + * @brief CMSIS Device System Source File for + * ARMCM3 Device Series + * @version V1.08 + * @date 23. November 2012 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#include "platform_autoconf.h" +#include "basic_types.h" +#include "rtl8195a.h" +#include "rtl_bios_data.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ +#define __HSI ( 8000000UL) +#define __XTAL ( 5000000UL) /* Oscillator frequency */ + +//#define __SYSTEM_CLOCK (5*__XTAL) +//#define __SYSTEM_CLOCK (200000000UL/6*5) // PLATFORM_CLOCK in platform_autoconf.h ! // + +//extern u32 HalGetCpuClk(VOID); + +#ifdef CONFIG_CHIP_A_CUT +const u32 SysCpkClkTbl[]= { + 200000000, + 100000000, + 50000000, + 25000000, + 12500000, + 4000000 +}; +#endif + +//extern unsigned int rand_x = 12345; +/* +u32 Rand2(void) +{ + static unsigned int y = 362436; + static unsigned int z = 521288629; + static unsigned int c = 7654321; + + unsigned long long t, a= 698769069; + + rand_x = 69069 * rand_x + 12345; + y ^= (y << 13); y ^= (y >> 17); y ^= (y << 5); + t = a * z + c; c = (t >> 32); z = t; + + return rand_x + y + z; +} +*/ +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = PLATFORM_CLOCK; // __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/ + + +u32 +SystemGetCpuClk(void) +{ +#ifdef CONFIG_CHIP_A_CUT + + u32 CpuType = 0, CpuClk = 0, FreqDown = 0; + + CpuType = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70)) >> 4); + FreqDown = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) & BIT17; + + CpuClk = SysCpkClkTbl[CpuType]; + + if ( !FreqDown ) { + if ( CpuClk > 4000000 ){ + CpuClk = (CpuClk*5/6); + } + } + + return CpuClk; +#else + return HalGetCpuClk(); +#endif +} + +/*---------------------------------------------------------------------------- + Clock functions + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ +{ +// SystemCoreClock = __SYSTEM_CLOCK; + + SystemCoreClock = SystemGetCpuClk(); +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System. + */ +void SystemInit (void) +{ + // TODO: Hardware initial +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + + //SystemCoreClock = __SYSTEM_CLOCK; + //SystemCoreClock = HalGetCpuClk(); + SystemCoreClockUpdate(); +} diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.h b/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.h new file mode 100644 index 0000000..b4c1a44 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/system_8195a.h @@ -0,0 +1,77 @@ +/**************************************************************************//** + * @file system_ARMCM3.h + * @brief CMSIS Device System Header File for + * ARMCM3 Device Series + * @version V1.08 + * @date 23. November 2012 + * + * @note + * + ******************************************************************************/ +/* Copyright (c) 2011 - 2012 ARM LIMITED + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + - Neither the name of ARM nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + * + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ---------------------------------------------------------------------------*/ + + +#ifndef _SYSTEM_8195A_H +#define _SYSTEM_8195A_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); +extern u32 SystemGetCpuClk(void); +extern _LONG_CALL_ u32 Rand2(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_8195A_H */ diff --git a/USDK/component/soc/realtek/8195a/cmsis/device/va_list.h b/USDK/component/soc/realtek/8195a/cmsis/device/va_list.h new file mode 100644 index 0000000..d3a1dd1 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/cmsis/device/va_list.h @@ -0,0 +1,37 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _VA_LIST_H_ +#define _VA_LIST_H_ + +#include "platform_autoconf.h" +#include "basic_types.h" + +#ifndef va_arg //this part is adapted from linux (Linux/include/acpi/platform/acenv.h) + +typedef s32 acpi_native_int;//this definition is in (Linux/include/acpi/actypes.h) + +#ifndef _VALIST +#define _VALIST + typedef char *va_list; +#endif /* _VALIST */ + +/* Storage alignment properties */ +#define _AUPBND (sizeof (acpi_native_int) - 1) +#define _ADNBND (sizeof (acpi_native_int) - 1) + +/* Variable argument list macro definitions */ +#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) +#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) +#define va_end(ap) (ap = (va_list) NULL) +#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND)))) + +#endif /* va_arg */ + +#endif //_VA_LIST_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/bitband_io.h b/USDK/component/soc/realtek/8195a/fwlib/bitband_io.h new file mode 100644 index 0000000..3fb4c60 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/bitband_io.h @@ -0,0 +1,146 @@ +#ifndef _BITBAND_IO_H_ +#define _BITBAND_IO_H_ + +#include "hal_platform.h" +#include "hal_api.h" +#include "hal_gpio.h" +#include "rtl8195a_gpio.h" + +#define BITBAND_SRAM_REF 0x10000000 +#define BITBAND_SRAM_BASE 0x12000000 +#define BITBAND_SRAM(a,b) (BITBAND_SRAM_BASE + (a-BITBAND_SRAM_REF)*32 + (b*4)) // Convert SRAM address + +/* + * in hal_platform.h +#define BITBAND_REG_BASE 0x40001000 + */ + +/* + * in rtl8195a_gpio.h + * +#define BITBAND_PORTA_DR 0x00 // data register +#define BITBAND_PORTA_DDR 0x04 // data direction +#define BITBAND_PORTA_CTRL 0x08 // data source control, we should keep it as default: data source from software + +#define BITBAND_PORTB_DR 0x0c // data register +#define BITBAND_PORTB_DDR 0x10 // data direction +#define BITBAND_PORTB_CTRL 0x14 // data source control, we should keep it as default: data source from software + +#define BITBAND_PORTC_DR 0x18 // data register +#define BITBAND_PORTC_DDR 0x1c // data direction +#define BITBAND_PORTC_CTRL 0x20 // data source control, we should keep it as default: data source from software + +#define BITBAND_EXT_PORTA 0x50 // GPIO IN read or OUT read back +#define BITBAND_EXT_PORTB 0x54 // GPIO IN read or OUT read back +#define BITBAND_EXT_PORTC 0x58 // GPIO IN read or OUT read back +*/ + +#define BITBAND_PERI_REF 0x40000000 +#define BITBAND_PERI_BASE 0x42000000 +#define BITBAND_PERI(a,b) (BITBAND_PERI_BASE + (a-BITBAND_PERI_REF)*32 + (b*4)) // Convert PERI address +#define ucBITBAND_PERI(a,b) *((volatile unsigned char *)BITBAND_PERI(a,b)) +#define uiBITBAND_PERI(a,b) *((volatile unsigned int *)BITBAND_PERI(a,b)) + +#define BITBAND_A0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,0) //Port = 0, bit = 0, A0 +#define BITBAND_A1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,1) //Port = 0, bit = 1, A1 +#define BITBAND_A2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,0) //Port = 1, bit = 0, A2 +#define BITBAND_A3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,1) //Port = 1, bit = 1, A3 +#define BITBAND_A4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,2) //Port = 1, bit = 2, A4 +#define BITBAND_A5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,3) //Port = 1, bit = 3, A5 +#define BITBAND_A6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,4) //Port = 1, bit = 4, A6 +#define BITBAND_A7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,5) //Port = 1, bit = 5, A7 + +#define BITBAND_B0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,6) //Port = 1, bit = 6, B0 +#define BITBAND_B1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,7) //Port = 1, bit = 7, B1 +#define BITBAND_B2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,8) //Port = 1, bit = 8, B2 +#define BITBAND_B3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,2) //Port = 0, bit = 2, B3 +#define BITBAND_B4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,3) //Port = 0, bit = 3, B4 +#define BITBAND_B5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,9) //Port = 1, bit = 9, B5 +#define BITBAND_B6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,4) //Port = 0, bit = 4, B6 +#define BITBAND_B7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,5) //Port = 0, bit = 5, B7 + +#define BITBAND_C0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,10) //Port = 1, bit = 10, C0 +#define BITBAND_C1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,6) //Port = 0, bit = 6, C1 +#define BITBAND_C2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,11) //Port = 1, bit = 11, C2 +#define BITBAND_C3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,7) //Port = 0, bit = 7, C3 +#define BITBAND_C4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,8) //Port = 0, bit = 8, C4 +#define BITBAND_C5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,9) //Port = 0, bit = 9, C5 +#define BITBAND_C6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,10) //Port = 0, bit = 10, C6 +#define BITBAND_C7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,11) //Port = 0, bit = 11, C7 +#define BITBAND_C8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,12) //Port = 0, bit = 12, C8 +#define BITBAND_C9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,13) //Port = 0, bit = 13, C9 + +#define BITBAND_D0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,12) //Port = 1, bit = 12, D0 +#define BITBAND_D1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,14) //Port = 0, bit = 14, D1 +#define BITBAND_D2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,13) //Port = 1, bit = 13, D2 +#define BITBAND_D3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,15) //Port = 0, bit = 15, D3 +#define BITBAND_D4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,16) //Port = 0, bit = 16, D4 +#define BITBAND_D5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,17) //Port = 0, bit = 17, D5 +#define BITBAND_D6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,18) //Port = 0, bit = 18, D6 +#define BITBAND_D7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,19) //Port = 0, bit = 19, D7 +#define BITBAND_D8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,14) //Port = 1, bit = 14, D8 +#define BITBAND_D9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,20) //Port = 0, bit = 20, D9 + +#define BITBAND_E0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,15) //Port = 2, bit = 15, E0 +#define BITBAND_E1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,21) //Port = 0, bit = 21, E1 +#define BITBAND_E2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,22) //Port = 0, bit = 22, E2 +#define BITBAND_E3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,23) //Port = 0, bit = 23, E3 +#define BITBAND_E4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,16) //Port = 1, bit = 16, E4 +#define BITBAND_E5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,24) //Port = 0, bit = 24, E5 +#define BITBAND_E6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,25) //Port = 0, bit = 25, E6 +#define BITBAND_E7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,26) //Port = 0, bit = 26, E7 +#define BITBAND_E8 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,27) //Port = 0, bit = 27, E8 +#define BITBAND_E9 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,17) //Port = 1, bit = 17, E9 +#define BITBAND_E10 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,18) //Port = 1, bit = 17, E10 + +#define BITBAND_F0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,19) //Port = 1, bit = 19, F0 +#define BITBAND_F1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,20) //Port = 1, bit = 20, F1 +#define BITBAND_F2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,21) //Port = 1, bit = 21, F2 +#define BITBAND_F3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,22) //Port = 1, bit = 22, F3 +#define BITBAND_F4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,23) //Port = 1, bit = 23, F4 +#define BITBAND_F5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,24) //Port = 1, bit = 24, F5 + +#define BITBAND_G0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,25) //Port = 1, bit = 25, G0 +#define BITBAND_G1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,26) //Port = 1, bit = 26, G1 +#define BITBAND_G2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,27) //Port = 1, bit = 27, G2 +#define BITBAND_G3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,28) //Port = 0, bit = 28, G3 +#define BITBAND_G4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,28) //Port = 1, bit = 28, G4 +#define BITBAND_G5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,29) //Port = 1, bit = 29, G5 +#define BITBAND_G6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,30) //Port = 1, bit = 30, G6 +#define BITBAND_G7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTB_DR,31) //Port = 1, bit = 31, G7 + +#define BITBAND_H0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,0) //Port = 2, bit = 0, H0 +#define BITBAND_H1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,29) //Port = 0, bit = 29, H1 +#define BITBAND_H2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,1) //Port = 2, bit = 1, H2 +#define BITBAND_H3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,30) //Port = 0, bit = 30, H3 +#define BITBAND_H4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,2) //Port = 2, bit = 2, H4 +#define BITBAND_H5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,31) //Port = 0, bit = 31, H5 +#define BITBAND_H6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,3) //Port = 2, bit = 3, H6 +#define BITBAND_H7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTA_DR,4) //Port = 2, bit = 4, H7 + +#define BITBAND_I0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,5) //Port = 2, bit = 5, I0 +#define BITBAND_I1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,6) //Port = 2, bit = 6, I1 +#define BITBAND_I2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,7) //Port = 2, bit = 7, I2 +#define BITBAND_I3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,8) //Port = 2, bit = 8, I3 +#define BITBAND_I4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,9) //Port = 2, bit = 9, I4 +#define BITBAND_I5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,10) //Port = 2, bit = 10, I5 +#define BITBAND_I6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,11) //Port = 2, bit = 11, I6 +#define BITBAND_I7 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,12) //Port = 2, bit = 12, I7 + +#define BITBAND_J0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,13) //Port = 2, bit = 13, J0 +#define BITBAND_J1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,14) //Port = 2, bit = 14, J1 +#define BITBAND_J2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,15) //Port = 2, bit = 15, J2 +#define BITBAND_J3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,16) //Port = 2, bit = 16, J3 +#define BITBAND_J4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,17) //Port = 2, bit = 17, J4 +#define BITBAND_J5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,18) //Port = 2, bit = 18, J5 +#define BITBAND_J6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,19) //Port = 2, bit = 19, J6 + +#define BITBAND_K0 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,20) //Port = 2, bit = 20, K0 +#define BITBAND_K1 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,21) //Port = 2, bit = 21, K1 +#define BITBAND_K2 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,22) //Port = 2, bit = 22, K2 +#define BITBAND_K3 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,23) //Port = 2, bit = 23, K3 +#define BITBAND_K4 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,24) //Port = 2, bit = 24, K4 +#define BITBAND_K5 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,25) //Port = 2, bit = 25, K5 +#define BITBAND_K6 ucBITBAND_PERI(GPIO_REG_BASE+GPIO_PORTC_DR,26) //Port = 2, bit = 26, K6 + +#endif // _BITBAND_IO_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_adc.h b/USDK/component/soc/realtek/8195a/fwlib/hal_adc.h new file mode 100644 index 0000000..fbea89e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_adc.h @@ -0,0 +1,318 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_ADC_H_ +#define _HAL_ADC_H_ + +#include "rtl8195a.h" +#include "rtl8195a_adc.h" +#include "hal_gdma.h" + +//================ ADC Configuration ========================= +#define ADC_INTR_OP_TYPE 1 +#define ADC_DMA_OP_TYPE 1 + +// ADC SAL management macros +#define SAL_ADC_USER_CB_NUM (sizeof(SAL_ADC_USER_CB) / sizeof(PSAL_ADC_USERCB_ADPT)) + +// ADC used module. +// Please set the ADC module flag to 1 to enable the related +#define ADC0_USED 1 +#define ADC1_USED 1 +#define ADC2_USED 1 +#define ADC3_USED 1 + + +//================ Debug MSG Definition ======================= +#define ADC_PREFIX "RTL8195A[adc]: " +#define ADC_PREFIX_LVL " [ADC_DBG]: " + +typedef enum _ADC_DBG_LVL_ { + HAL_ADC_LVL = 0x01, + SAL_ADC_LVL = 0x02, + VERI_ADC_LVL = 0x04, +}ADC_DBG_LVL,*PADC_DBG_LVL; + +#ifdef CONFIG_DEBUG_LOG_ADC_HAL + + #define DBG_8195A_ADC(...) do{ \ + _DbgDump(ADC_PREFIX __VA_ARGS__);\ + }while(0) + + + #define ADCDBGLVL 0xFF + #define DBG_8195A_ADC_LVL(LVL,...) do{\ + if (LVL&ADCDBGLVL){\ + _DbgDump(ADC_PREFIX_LVL __VA_ARGS__);\ + }\ + }while(0) +#else + #define DBG_ADC_LOG_PERD 100 + #define DBG_8195A_ADC(...) + #define DBG_8195A_ADC_LVL(...) +#endif + + +//================ ADC HAL Related Enumeration ================== +// ADC Module Selection +typedef enum _ADC_MODULE_SEL_ { + ADC0_SEL = 0x0, + ADC1_SEL = 0x1, + ADC2_SEL = 0x2, + ADC3_SEL = 0x3, +}ADC_MODULE_SEL,*PADC_MODULE_SEL; + +// ADC module status +typedef enum _ADC_MODULE_STATUS_ { + ADC_DISABLE = 0x0, + ADC_ENABLE = 0x1, +}ADC_MODULE_STATUS, *PADC_MODULE_STATUS; + +// ADC Data Endian +typedef enum _ADC_DATA_ENDIAN_ { + ADC_DATA_ENDIAN_LITTLE = 0x0, + ADC_DATA_ENDIAN_BIG = 0x1, +}ADC_DATA_ENDIAN,*PADC_DATA_ENDIAN; + +// ADC Debug Select +typedef enum _ADC_DEBUG_SEL_ { + ADC_DBG_SEL_DISABLE = 0x0, + ADC_DBG_SEL_ENABLE = 0x1, +}ADC_DEBUG_SEL,*PADC_DEBUG_SEL; + +typedef enum _ADC_COMPARE_SET_ { + ADC_COMP_SMALLER_THAN = 0x0, + ADC_COMP_GREATER_THAN = 0x1, +}ADC_COMPARE_SET, *PADC_COMPARE_SET; + +// ADC feature status +typedef enum _ADC_FEATURE_STATUS_{ + ADC_FEATURE_DISABLED = 0, + ADC_FEATURE_ENABLED = 1, +}ADC_FEATURE_STATUS,*PADC_FEATURE_STATUS; + +// ADC operation type +typedef enum _ADC_OP_TYPE_ { + ADC_RDREG_TYPE = 0x0, + ADC_DMA_TYPE = 0x1, + ADC_INTR_TYPE = 0x2, +}ADC_OP_TYPE, *PADC_OP_TYPE; + +// ADC device status +typedef enum _ADC_DEVICE_STATUS_ { + ADC_STS_UNINITIAL = 0x00, + ADC_STS_INITIALIZED = 0x01, + ADC_STS_IDLE = 0x02, + + ADC_STS_TX_READY = 0x03, + ADC_STS_TX_ING = 0x04, + + ADC_STS_RX_READY = 0x05, + ADC_STS_RX_ING = 0x06, + + ADC_STS_ERROR = 0x07, + ADC_STS_FULL = 0x08, +}ADC_DEVICE_STATUS, *PADC_DEVICE_STATUS; + +// ADC error type +typedef enum _ADC_ERR_TYPE_ { + ADC_ERR_FIFO_RD_ERROR = 0x40, //ADC FIFO read error +}ADC_ERR_TYPE, *PADC_ERR_TYPE; + +// ADC initial status +typedef enum _ADC_INITAIL_STATUS_ { + ADC0_INITED = 0x1, + ADC1_INITED = 0x2, + ADC2_INITED = 0x4, + ADC3_INITED = 0x8, +}ADC_INITAIL_STATUS, *PADC_INITAIL_STATUS; + + +//================ ADC HAL Data Structure ====================== +// ADC HAL initial data structure +typedef struct _HAL_ADC_INIT_DAT_ { + u8 ADCIdx; //ADC index used + u8 ADCEn; //ADC module enable + u8 ADCEndian; //ADC endian selection, + //but actually it's for 32-bit ADC data swap control + //1'b0: no swap, + //1'b1: swap the upper 16-bit and the lower 16-bit + u8 ADCBurstSz; //ADC DMA operation threshold + + u8 ADCCompOnly; //ADC compare mode only enable (without FIFO enable) + u8 ADCOneShotEn; //ADC one-shot mode enable + u8 ADCOverWREn; //ADC overwrite mode enable + u8 ADCOneShotTD; //ADC one shot mode threshold + + u16 ADCCompCtrl; //ADC compare mode control, + //1'b0:less than the compare threshold + //1'b1:greater than the compare threshod + u16 ADCCompTD; //ADC compare mode threshold + + u8 ADCDataRate; //ADC down sample data rate, + u8 ADCAudioEn; //ADC audio mode enable + u8 ADCEnManul; //ADC enable manually + u8 ADCDbgSel; + + u32 RSVD0; + + u32 *ADCData; //ADC data pointer + u32 ADCPWCtrl; //ADC0 power control + u32 ADCIntrMSK; //ADC Interrupt Mask + u32 ADCAnaParAd3; //ADC analog parameter 3 + u32 ADCInInput; //ADC Input is internal? +}HAL_ADC_INIT_DAT,*PHAL_ADC_INIT_DAT; + +// ADC HAL Operations +typedef struct _HAL_ADC_OP_ { + RTK_STATUS (*HalADCInit) (VOID *Data); //HAL ADC initialization + RTK_STATUS (*HalADCDeInit) (VOID *Data); //HAL ADC de-initialization + RTK_STATUS (*HalADCEnable) (VOID *Data); //HAL ADC de-initialization + u32 (*HalADCReceive) (VOID *Data); //HAL ADC receive + RTK_STATUS (*HalADCIntrCtrl) (VOID *Data); //HAL ADC interrupt control + u32 (*HalADCReadReg) (VOID *Data, u8 ADCReg);//HAL ADC read register +}HAL_ADC_OP, *PHAL_ADC_OP; + +// ADC user callback adapter +typedef struct _SAL_ADC_USERCB_ADPT_ { + VOID (*USERCB) (VOID *Data); + u32 USERData; +}SAL_ADC_USERCB_ADPT, *PSAL_ADC_USERCB_ADPT; + +// ADC user callback structure +typedef struct _SAL_ADC_USER_CB_ { + PSAL_ADC_USERCB_ADPT pTXCB; //ADC Transmit Callback + PSAL_ADC_USERCB_ADPT pTXCCB; //ADC Transmit Complete Callback + PSAL_ADC_USERCB_ADPT pRXCB; //ADC Receive Callback + PSAL_ADC_USERCB_ADPT pRXCCB; //ADC Receive Complete Callback + PSAL_ADC_USERCB_ADPT pRDREQCB; //ADC Read Request Callback + PSAL_ADC_USERCB_ADPT pERRCB; //ADC Error Callback + PSAL_ADC_USERCB_ADPT pDMATXCB; //ADC DMA Transmit Callback + PSAL_ADC_USERCB_ADPT pDMATXCCB; //ADC DMA Transmit Complete Callback + PSAL_ADC_USERCB_ADPT pDMARXCB; //ADC DMA Receive Callback + PSAL_ADC_USERCB_ADPT pDMARXCCB; //ADC DMA Receive Complete Callback +}SAL_ADC_USER_CB, *PSAL_ADC_USER_CB; + +// ADC Transmit Buffer +typedef struct _SAL_ADC_TRANSFER_BUF_ { + u32 DataLen; //ADC Transmfer Length + u32 *pDataBuf; //ADC Transfer Buffer Pointer + u32 RSVD; // +}SAL_ADC_TRANSFER_BUF,*PSAL_ADC_TRANSFER_BUF; + +typedef struct _SAL_ADC_DMA_USER_DEF_ { + + u8 TxDatSrcWdth; + u8 TxDatDstWdth; + u8 TxDatSrcBstSz; + u8 TxDatDstBstSz; + + u8 TxChNo; + u8 LlpCtrl; + u16 RSVD0; + + u32 MaxMultiBlk; + u32 pLlix; + u32 pBlockSizeList; +}SAL_ADC_DMA_USER_DEF, *PSAL_ADC_DMA_USER_DEF; + +// Software API Level ADC Handler +typedef struct _SAL_ADC_HND_ { + u8 DevNum; //ADC device number + u8 PinMux; //ADC pin mux seletion + u8 OpType; //ADC operation type selection + volatile u8 DevSts; //ADC device status + + u32 ADCExd; //ADC extended options: + //bit 0: example + //bit 31~bit 1: Reserved + u32 ErrType; // + u32 TimeOut; //ADC IO Timeout count + + PHAL_ADC_INIT_DAT pInitDat; //Pointer to ADC initial data struct + PSAL_ADC_TRANSFER_BUF pRXBuf; //Pointer to ADC TX buffer + PSAL_ADC_USER_CB pUserCB; //Pointer to ADC User Callback +}SAL_ADC_HND, *PSAL_ADC_HND; + +// ADC SAL handle private +typedef struct _SAL_ADC_HND_PRIV_ { + VOID **ppSalADCHnd; //Pointer to SAL_ADC_HND pointer + SAL_ADC_HND SalADCHndPriv; //Private SAL_ADC_HND +}SAL_ADC_HND_PRIV, *PSAL_ADC_HND_PRIV; + +//ADC SAL management adapter +typedef struct _SAL_ADC_MNGT_ADPT_ { + PSAL_ADC_HND_PRIV pSalHndPriv; //Pointer to SAL_ADC_HND + PHAL_ADC_INIT_DAT pHalInitDat; //Pointer to HAL ADC initial data( HAL_ADC_INIT_DAT ) + PHAL_ADC_OP pHalOp; //Pointer to HAL ADC operation( HAL_ADC_OP ) + VOID (*pHalOpInit)(VOID*);//Pointer to HAL ADC initialize function + + PIRQ_HANDLE pIrqHnd; //Pointer to IRQ handler in SAL layer( IRQ_HANDLE ) + VOID (*pSalIrqFunc)(VOID*); //Used for SAL ADC interrupt function + + PSAL_ADC_DMA_USER_DEF pDMAConf; //Pointer to DAC User Define DMA config + PHAL_GDMA_ADAPTER pHalGdmaAdp; + PHAL_GDMA_OP pHalGdmaOp; + PIRQ_HANDLE pIrqGdmaHnd; + VOID (*pHalGdmaOpInit)(VOID*); //Pointer to HAL DAC initialize function + PSAL_ADC_USER_CB pUserCB; //Pointer to SAL user callbacks (SAL_ADC_USER_CB ) + VOID (*pSalDMAIrqFunc)(VOID*); //Used for SAL DAC interrupt function +}SAL_ADC_MNGT_ADPT, *PSAL_ADC_MNGT_ADPT; + + +//================ ADC HAL Function Prototype =================== +// ADC HAL inline function +// For checking I2C input index valid or not +static inline RTK_STATUS +RtkADCIdxChk( + IN u8 ADCIdx +) +{ +#if !ADC0_USED + if (ADCIdx == ADC0_SEL) + return _EXIT_FAILURE; +#endif + +#if !ADC1_USED + if (ADCIdx == ADC1_SEL) + return _EXIT_FAILURE; +#endif + +#if !ADC2_USED + if (ADCIdx == ADC2_SEL) + return _EXIT_FAILURE; +#endif + +#if !ADC3_USED + if (ADCIdx == ADC3_SEL) + return _EXIT_FAILURE; +#endif + ADCIdx++; //for compile warning. + return _EXIT_SUCCESS; +} + +VOID HalADCOpInit(IN VOID *Data); +PSAL_ADC_HND RtkADCGetSalHnd(IN u8 DACIdx); +RTK_STATUS RtkADCFreeSalHnd(IN PSAL_ADC_HND pSalADCHND); +RTK_STATUS RtkADCLoadDefault(IN VOID *Data); +RTK_STATUS RtkADCInit(IN VOID *Data); +RTK_STATUS RtkADCDeInit(IN VOID *Data); +//RTK_STATUS RtkADCReceive(IN VOID *Data); +u32 RtkADCReceive(IN VOID *Data); +u32 RtkADCReceiveBuf(IN VOID *Data,IN u32 *pBuf); +u32 RtkADCRxManualRotate(IN VOID *Data,IN u32 *pBuf); + +PSAL_ADC_MNGT_ADPT RtkADCGetMngtAdpt(IN u8 ADCIdx); +RTK_STATUS RtkADCFreeMngtAdpt(IN PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt); +VOID ADCISRHandle(IN VOID *Data); +VOID ADCGDMAISRHandle(IN VOID *Data); +HAL_Status RtkADCDisablePS(IN VOID *Data); +HAL_Status RtkADCEnablePS(IN VOID *Data); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_api.h b/USDK/component/soc/realtek/8195a/fwlib/hal_api.h new file mode 100644 index 0000000..c50b6e7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_api.h @@ -0,0 +1,126 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#ifndef _HAL_API_H_ +#define _HAL_API_H_ + +#include "basic_types.h" +#include "hal_irqn.h" + +#define HAL_READ32(base, addr) \ + rtk_le32_to_cpu(*((volatile u32*)(base + addr))) + +#define HAL_WRITE32(base, addr, value32) \ + ((*((volatile u32*)(base + addr))) = rtk_cpu_to_le32(value32)) + + +#define HAL_READ16(base, addr) \ + rtk_le16_to_cpu(*((volatile u16*)(base + addr))) + +#define HAL_WRITE16(base, addr, value) \ + ((*((volatile u16*)(base + addr))) = rtk_cpu_to_le16(value)) + + +#define HAL_READ8(base, addr) \ + (*((volatile u8*)(base + addr))) + +#define HAL_WRITE8(base, addr, value) \ + ((*((volatile u8*)(base + addr))) = value) + +#if 0 +// These "extern _LONG_CALL_" function declaration are for RAM code building only +// For ROM code building, thses code should be marked off +extern _LONG_CALL_ u8 +HalPinCtrlRtl8195A( + IN u32 Function, + IN u32 PinLocation, + IN BOOL Operation + ); + +extern _LONG_CALL_ VOID +HalSerialPutcRtl8195a( + IN u8 c + ); + +extern _LONG_CALL_ u8 +HalSerialGetcRtl8195a( + IN BOOL PullMode + ); + +extern _LONG_CALL_ u32 +HalSerialGetIsrEnRegRtl8195a(VOID); + +extern _LONG_CALL_ VOID +HalSerialSetIrqEnRegRtl8195a ( + IN u32 SetValue + ); + +extern _LONG_CALL_ VOID +VectorTableInitForOSRtl8195A( + IN VOID *PortSVC, + IN VOID *PortPendSVH, + IN VOID *PortSysTick + ); + +extern _LONG_CALL_ BOOL +VectorIrqRegisterRtl8195A( + IN PIRQ_HANDLE pIrqHandle + ); + +extern _LONG_CALL_ BOOL +VectorIrqUnRegisterRtl8195A( + IN PIRQ_HANDLE pIrqHandle + ); + +extern _LONG_CALL_ VOID +VectorIrqEnRtl8195A( + IN PIRQ_HANDLE pIrqHandle + ); + +extern _LONG_CALL_ VOID +VectorIrqDisRtl8195A( + IN PIRQ_HANDLE pIrqHandle + ); +#endif + +extern BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode); +extern VOID InitWDGIRQ(VOID); + +#define PinCtrl HalPinCtrlRtl8195A + +#define DiagPutChar HalSerialPutcRtl8195a +#define DiagGetChar HalSerialGetcRtl8195a +#define DiagGetIsrEnReg HalSerialGetIsrEnRegRtl8195a +#define DiagSetIsrEnReg HalSerialSetIrqEnRegRtl8195a + +#define InterruptForOSInit VectorTableInitForOSRtl8195A +#define InterruptRegister VectorIrqRegisterRtl8195A +#define InterruptUnRegister VectorIrqUnRegisterRtl8195A + +#define InterruptEn VectorIrqEnRtl8195A +#define InterruptDis VectorIrqDisRtl8195A + +#define SpicFlashInit SpicFlashInitRtl8195A +#define Calibration32k En32KCalibration +#define WDGInit InitWDGIRQ + +typedef enum _HAL_Status +{ + HAL_OK = 0x00, + HAL_BUSY = 0x01, + HAL_TIMEOUT = 0x02, + HAL_ERR_PARA = 0x03, // error with invaild parameters + HAL_ERR_MEM = 0x04, // error with memory allocation failed + HAL_ERR_HW = 0x05, // error with hardware error + + HAL_ERR_UNKNOWN = 0xee // unknown error + +} HAL_Status; + + +#endif //_HAL_API_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_common.h b/USDK/component/soc/realtek/8195a/fwlib/hal_common.h new file mode 100644 index 0000000..113c1a1 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_common.h @@ -0,0 +1,17 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_COMMON_H_ +#define _HAL_COMMON_H_ + +//================= Function Prototype START =================== +HAL_Status HalCommonInit(void); +//================= Function Prototype END =================== + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_crypto.h b/USDK/component/soc/realtek/8195a/fwlib/hal_crypto.h new file mode 100644 index 0000000..fe76e2d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_crypto.h @@ -0,0 +1,214 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef __HAL_CRYPTO_H__ +#define __HAL_CRYPTO_H__ + + +#include "hal_api.h" +#include "basic_types.h" + + +#define CRYPTO_MAX_MSG_LENGTH 16000 +#define CRYPTO_MD5_DIGEST_LENGTH 16 +#define CRYPTO_SHA1_DIGEST_LENGTH 20 +#define CRYPTO_SHA2_DIGEST_LENGTH 32 + + +typedef enum _SHA2_TYPE_ { + SHA2_NONE = 0, + SHA2_224 = 224/8, + SHA2_256 = 256/8, + SHA2_384 = 384/8, + SHA2_512 = 512/8 +} SHA2_TYPE; + + +#define _ERRNO_CRYPTO_DESC_NUM_SET_OutRange -2 +#define _ERRNO_CRYPTO_BURST_NUM_SET_OutRange -3 +#define _ERRNO_CRYPTO_NULL_POINTER -4 +#define _ERRNO_CRYPTO_ENGINE_NOT_INIT -5 +#define _ERRNO_CRYPTO_ADDR_NOT_4Byte_Aligned -6 +#define _ERRNO_CRYPTO_KEY_OutRange -7 +#define _ERRNO_CRYPTO_MSG_OutRange -8 +#define _ERRNO_CRYPTO_IV_OutRange -9 +#define _ERRNO_CRYPTO_AUTH_TYPE_NOT_MATCH -10 +#define _ERRNO_CRYPTO_CIPHER_TYPE_NOT_MATCH -11 +#define _ERRNO_CRYPTO_KEY_IV_LEN_DIFF -12 +#define _ERRNO_CRYPTO_AES_MSGLEN_NOT_16Byte_Aligned -13 + + + +// +// External API Functions +// + + +// Crypto Engine +extern int rtl_cryptoEngine_init(void); +extern void rtl_cryptoEngine_info(void); + + + +// +// Authentication +// + +// md5 + +extern int rtl_crypto_md5(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + +extern int rtl_crypto_md5_init(void); +extern int rtl_crypto_md5_process(IN const u8* message, const IN u32 msglen, OUT u8* pDigest); + + +// sha1 +extern int rtl_crypto_sha1(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + +extern int rtl_crypto_sha1_init(void); +extern int rtl_crypto_sha1_process(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + +// sha2 + +extern int rtl_crypto_sha2(IN const SHA2_TYPE sha2type, + IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + +extern int rtl_crypto_sha2_init(IN const SHA2_TYPE sha2type); +extern int rtl_crypto_sha2_process(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + + +// HMAC-md5 +extern int rtl_crypto_hmac_md5(IN const u8* message, IN const u32 msglen, + IN const u8* key, IN const u32 keylen, OUT u8* pDigest); + +extern int rtl_crypto_hmac_md5_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_hmac_md5_process(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + + +// HMAC-sha1 +extern int rtl_crypto_hmac_sha1(IN const u8* message, IN const u32 msglen, + IN const u8* key, IN const u32 keylen, OUT u8* pDigest); + +extern int rtl_crypto_hmac_sha1_init(IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_hmac_sha1_process(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + + +// HMAC-sha2 +extern int rtl_crypto_hmac_sha2(IN const SHA2_TYPE sha2type, IN const u8* message, IN const u32 msglen, + IN const u8* key, IN const u32 keylen, OUT u8* pDigest); + +extern int rtl_crypto_hmac_sha2_init(IN const SHA2_TYPE sha2type, IN const u8* key, IN const u32 keylen); +extern int rtl_crypto_hmac_sha2_process(IN const u8* message, IN const u32 msglen, OUT u8* pDigest); + + +// +// Cipher Functions +// + +// AES - CBC + +extern int rtl_crypto_aes_cbc_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_aes_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_aes_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// AES - ECB + +extern int rtl_crypto_aes_ecb_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_aes_ecb_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_aes_ecb_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// AES - CTR + +extern int rtl_crypto_aes_ctr_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_aes_ctr_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_aes_ctr_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// 3DES - CBC + +extern int rtl_crypto_3des_cbc_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_3des_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_3des_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// 3DES - ECB + +extern int rtl_crypto_3des_ecb_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_3des_ecb_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_3des_ecb_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// DES - CBC + +extern int rtl_crypto_des_cbc_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_des_cbc_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_des_cbc_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// DES - ECB + +extern int rtl_crypto_des_ecb_init(IN const u8* key, IN const u32 keylen); + +extern int rtl_crypto_des_ecb_encrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + +extern int rtl_crypto_des_ecb_decrypt( + IN const u8* message, IN const u32 msglen, + IN const u8* iv, IN const u32 ivlen, OUT u8* pResult); + + +// +// C functions in ROM +// + +extern int rtl_memcmpb(const u8 *dst, const u8 *src, int bytes); +extern int rtl_memcpyb(u8 *dst, const u8 *src, int bytes); + +#endif /* __HAL_CRYPTO_H__ */ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_dac.h b/USDK/component/soc/realtek/8195a/fwlib/hal_dac.h new file mode 100644 index 0000000..c4bd1d1 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_dac.h @@ -0,0 +1,313 @@ +//====================================================== +// Routines to access hardware +// +// Copyright (c) 2013 Realtek Semiconductor Corp. +// +// This module is a confidential and proprietary property of RealTek and +// possession or use of this module requires written permission of RealTek. +//====================================================== +#ifndef _HAL_DAC_H_ +#define _HAL_DAC_H_ + +#include "rtl8195a.h" +#include "rtl8195a_dac.h" +#include "hal_api.h" +#include "hal_gdma.h" + +//================ DAC Configuration ========================= +#define DAC_INTR_OP_TYPE 1 +#define DAC_DMA_OP_TYPE 1 + +// DAC SAL management macros +#define SAL_DAC_USER_CB_NUM (sizeof(SAL_DAC_USER_CB) / sizeof(PSAL_DAC_USERCB_ADPT)) + +// DAC SAL used module. +// Please set the DAC module flag to 1 to enable the related DAC module functions. +#define DAC0_USED 1 +#define DAC1_USED 1 + + +//================ Debug MSG Definition ======================= +#define DAC_PREFIX "RTL8195A[dac]: " +#define DAC_PREFIX_LVL " [DAC_DBG]: " + +typedef enum _DAC_DBG_LVL_ { + HAL_DAC_LVL = 0x00, + SAL_DAC_LVL = 0x02, + VERI_DAC_LVL = 0x04, +}DAC_DBG_LVL,*PDAC_DBG_LVL; + +#if CONFIG_DEBUG_LOG > 0 +#ifdef CONFIG_DEBUG_LOG_DAC_HAL + + #define DBG_8195A_DAC(...) do{ \ + _DbgDump(DAC_PREFIX __VA_ARGS__);\ + }while(0) + + + #define DACDBGLVL 0xFF + #define DBG_8195A_DAC_LVL(LVL,...) do{\ + if (LVL&DACDBGLVL){\ + _DbgDump(DAC_PREFIX_LVL __VA_ARGS__);\ + }\ + }while(0) +#else + #define DBG_DAC_LOG_PERD 100 + #define DBG_8195A_DAC(...) + #define DBG_8195A_DAC_LVL(...) +#endif +#endif + + +//================ DAC HAL Related Enumeration ================== +// DAC Module Selection +typedef enum _DAC_MODULE_SEL_ { + DAC0_SEL = 0x0, + DAC1_SEL = 0x1, +}DAC_MODULE_SEL,*PDAC_MODULE_SEL; + +// DAC module status +typedef enum _DAC_MODULE_STATUS_ { + DAC_DISABLE = 0x0, + DAC_ENABLE = 0x1, +}DAC_MODULE_STATUS, *PDAC_MODULE_STATUS; + +// DAC Data Rate +typedef enum _DAC_DATA_RATE_ { + DAC_DATA_RATE_10K = 0x0, + DAC_DATA_RATE_250K = 0x1, +}DAC_DATA_RATE,*PDAC_DATA_RATE; + +// DAC Data Endian +typedef enum _DAC_DATA_ENDIAN_ { + DAC_DATA_ENDIAN_LITTLE = 0x0, + DAC_DATA_ENDIAN_BIG = 0x1, +}DAC_DATA_ENDIAN,*PDAC_DATA_ENDIAN; + +// DAC Debug Select +typedef enum _DAC_DEBUG_SEL_ { + DAC_DBG_SEL_DISABLE = 0x0, + DAC_DBG_SEL_ENABLE = 0x1, +}DAC_DEBUG_SEL,*PDAC_DEBUG_SEL; + +// DAC Dsc Debug Select +typedef enum _DAC_DSC_DEBUG_SEL_ { + DAC_DSC_DBG_SEL_DISABLE = 0x0, + DAC_DSC_DBG_SEL_ENABLE = 0x1, +}DAC_DSC_DEBUG_SEL,*PDAC_DSC_DEBUG_SEL; + + +// DAC Bypass Dsc Debug Select +typedef enum _DAC_BYPASS_DSC_SEL_ { + DAC_BYPASS_DSC_SEL_DISABLE = 0x0, + DAC_BYPASS_DSC_SEL_ENABLE = 0x1, +}DAC_BYPASS_DSC_SEL,*PDAC_BYPASS_DSC_SEL; + +// DAC feature status +typedef enum _DAC_FEATURE_STATUS_{ + DAC_FEATURE_DISABLED = 0, + DAC_FEATURE_ENABLED = 1, +}DAC_FEATURE_STATUS,*PDAC_FEATURE_STATUS; + +// DAC operation type +typedef enum _DAC_OP_TYPE_ { + DAC_POLL_TYPE = 0x0, + DAC_DMA_TYPE = 0x1, + DAC_INTR_TYPE = 0x2, +}DAC_OP_TYPE, *PDAC_OP_TYPE; + +// DAC device status +typedef enum _DAC_Device_STATUS_ { + DAC_STS_UNINITIAL = 0x00, + DAC_STS_INITIALIZED = 0x01, + DAC_STS_IDLE = 0x02, + + DAC_STS_TX_READY = 0x03, + DAC_STS_TX_ING = 0x04, + + DAC_STS_RX_READY = 0x05, + DAC_STS_RX_ING = 0x06, + + DAC_STS_ERROR = 0x07, +}DAC_Device_STATUS, *PDAC_Device_STATUS; + +//DAC device error type +typedef enum _DAC_ERR_TYPE_ { + DAC_ERR_FIFO_OVER = 0x04, //DAC FIFO overflow. + DAC_ERR_FIFO_STOP = 0x08, //DAC FIFO is completely empty, and it will be stopped automatically. + DAC_ERR_FIFO_WRFAIL = 0x10, //When DAC is NOT enabled, a write operation attempts to access DAC register. + DAC_ERR_FIFO_DSC_OVER0 = 0x20, + DAC_ERR_FIFO_DSC_OVER1 = 0x40, +}DAC_ERR_TYPE, *PDAC_ERR_TYPE; + +// DAC data input method +typedef enum _DAC_INPUT_TYPE_{ + DAC_INPUT_SINGLE_WR = 0x1, //DAC input by using single register write + DAC_INPUT_DMA_ONEBLK = 0x2, //DAC input by using single DMA block + DAC_INPUT_DMA_LLP = 0x3, //DAC input by using DMA linked list mode +}DAC_INPUT_TYPE,*PDAC_INPUT_TYPE; + + + + +//====================================================== +// DAC HAL initial data structure +typedef struct _HAL_DAC_INIT_DAT_ { + u8 DACIdx; //DAC index used + u8 DACEn; //DAC module enable + u8 DACDataRate; //DAC data rate, 1'b0:10KHz, 1'b1:250KHz + u8 DACEndian; //DAC endian selection, + //but actually it's for 32-bit DAC data swap control + //1'b0: no swap, + //1'b1: swap the upper 16-bit and the lower 16-bit + u8 DACFilterSet; //DAC filter settle + u8 DACBurstSz; //DAC burst size + u8 DACDbgSel; //DAC debug sel + u8 DACDscDbgSel; //DAC debug dsc sel + + u8 DACBPDsc; //DAC bypass delta sigma for loopback + u8 DACDeltaSig; //DAC bypass value of delta sigma + u16 RSVD1; + + + + u32 *DACData; //DAC data pointer + u32 DACPWCtrl; //DAC0 and DAC1 power control + u32 DACAnaCtrl0; //DAC anapar_da control 0 + u32 DACAnaCtrl1; //DAC anapar_da control 1 + u32 DACIntrMSK; //DAC Interrupt Mask +}HAL_DAC_INIT_DAT,*PHAL_DAC_INIT_DAT; + +// DAC HAL Operations +typedef struct _HAL_DAC_OP_ { + RTK_STATUS (*HalDACInit) (VOID *Data); //HAL DAC initialization + RTK_STATUS (*HalDACDeInit) (VOID *Data); //HAL DAC de-initialization + RTK_STATUS (*HalDACEnable) (VOID *Data); //HAL DAC de-initialization + u8 (*HalDACSend) (VOID *Data); //HAL DAC receive + RTK_STATUS (*HalDACIntrCtrl) (VOID *Data); //HAL DAC interrupt control + u32 (*HalDACReadReg) (VOID *Data, u8 DACReg);//HAL DAC read register +}HAL_DAC_OP, *PHAL_DAC_OP; + +// DAC user callback adapter +typedef struct _SAL_DAC_USERCB_ADPT_ { + VOID (*USERCB) (VOID *Data); + u32 USERData; +}SAL_DAC_USERCB_ADPT, *PSAL_DAC_USERCB_ADPT; + +// DAC user callback structure +typedef struct _SAL_DAC_USER_CB_ { + PSAL_DAC_USERCB_ADPT pTXCB; //DAC Transmit Callback + PSAL_DAC_USERCB_ADPT pTXCCB; //DAC Transmit Complete Callback + PSAL_DAC_USERCB_ADPT pRXCB; //DAC Receive Callback + PSAL_DAC_USERCB_ADPT pRXCCB; //DAC Receive Complete Callback + PSAL_DAC_USERCB_ADPT pRDREQCB; //DAC Read Request Callback + PSAL_DAC_USERCB_ADPT pERRCB; //DAC Error Callback + PSAL_DAC_USERCB_ADPT pDMATXCB; //DAC DMA Transmit Callback + PSAL_DAC_USERCB_ADPT pDMATXCCB; //DAC DMA Transmit Complete Callback + PSAL_DAC_USERCB_ADPT pDMARXCB; //DAC DMA Receive Callback + PSAL_DAC_USERCB_ADPT pDMARXCCB; //DAC DMA Receive Complete Callback +}SAL_DAC_USER_CB, *PSAL_DAC_USER_CB; + +// DAC Transmit Buffer +typedef struct _SAL_DAC_TRANSFER_BUF_ { + u32 DataLen; //DAC Transmfer Length + u32 *pDataBuf; //DAC Transfer Buffer Pointer + u32 RSVD; // +}SAL_DAC_TRANSFER_BUF,*PSAL_DAC_TRANSFER_BUF; + +typedef struct _SAL_DAC_DMA_USER_DEF_ { + + u8 TxDatSrcWdth; + u8 TxDatDstWdth; + u8 TxDatSrcBstSz; + u8 TxDatDstBstSz; + + u8 TxChNo; + u8 LlpCtrl; + u16 RSVD0; + + u32 MaxMultiBlk; + u32 pLlix; + u32 pBlockSizeList; +}SAL_DAC_DMA_USER_DEF, *PSAL_DAC_DMA_USER_DEF; + +// Software API Level DAC Handler +typedef struct _SAL_DAC_HND_ { + u8 DevNum; //DAC device number + u8 PinMux; //DAC pin mux seletion + u8 OpType; //DAC operation type selection + volatile u8 DevSts; //DAC device status + + u8 DACInType; //DAC input type + u8 RSVD0; + u16 RSVD1; + + u32 DACExd; //DAC extended options: + //bit 0: example + //bit 31~bit 1: Reserved + u32 ErrType; // + u32 TimeOut; //DAC IO Timeout count + + PHAL_DAC_INIT_DAT pInitDat; //Pointer to DAC initial data struct + PSAL_DAC_TRANSFER_BUF pTXBuf; //Pointer to DAC TX buffer + PSAL_DAC_USER_CB pUserCB; //Pointer to DAC User Callback + PSAL_DAC_DMA_USER_DEF pDMAConf; //Pointer to DAC User Define DMA Config +}SAL_DAC_HND, *PSAL_DAC_HND; + +// DAC SAL handle private +typedef struct _SAL_DAC_HND_PRIV_ { + VOID **ppSalDACHnd; //Pointer to SAL_DAC_HND pointer + SAL_DAC_HND SalDACHndPriv; //Private SAL_DAC_HND +}SAL_DAC_HND_PRIV, *PSAL_DAC_HND_PRIV; + +//DAC SAL management adapter +typedef struct _SAL_DAC_MNGT_ADPT_ { + PSAL_DAC_HND_PRIV pSalHndPriv; //Pointer to SAL_DAC_HND + PHAL_DAC_INIT_DAT pHalInitDat; //Pointer to HAL DAC initial data( HAL_I2C_INIT_DAT ) + PHAL_DAC_OP pHalOp; //Pointer to HAL DAC operation( HAL_DAC_OP ) + VOID (*pHalOpInit)(VOID*); //Pointer to HAL DAC initialize function + PIRQ_HANDLE pIrqHnd; //Pointer to IRQ handler in SAL layer( IRQ_HANDLE ) + PSAL_DAC_USER_CB pUserCB; //Pointer to SAL user callbacks (SAL_DAC_USER_CB ) + VOID (*pSalIrqFunc)(VOID*); //Used for SAL DAC interrupt function + + PSAL_DAC_DMA_USER_DEF pDMAConf; //Pointer to DAC User Define DMA config + PHAL_GDMA_ADAPTER pHalGdmaAdp; + PHAL_GDMA_OP pHalGdmaOp; + VOID (*pHalGdmaOpInit)(VOID*); //Pointer to HAL DAC initialize function + PIRQ_HANDLE pIrqGdmaHnd; + VOID (*pSalDMAIrqFunc)(VOID*); //Used for SAL DAC interrupt function +}SAL_DAC_MNGT_ADPT, *PSAL_DAC_MNGT_ADPT; + + +//================ DAC HAL Function Prototype =================== +// DAC HAL inline function +// For checking DAC input index valid or not +static inline RTK_STATUS +RtkDACIdxChk( + IN u8 DACIdx +) +{ +#if !DAC0_USED + if (DACIdx == DAC0_SEL) + return _EXIT_FAILURE; +#endif + +#if !DAC1_USED + if (DACIdx == DAC1_SEL) + return _EXIT_FAILURE; +#endif + + return _EXIT_SUCCESS; +} + +VOID HalDACOpInit(IN VOID *Data); +RTK_STATUS RtkDACLoadDefault(IN VOID *Data); +RTK_STATUS RtkDACInit(IN VOID *Data); +RTK_STATUS RtkDACDeInit(IN VOID *Data); +RTK_STATUS RtkDACSend(IN VOID *Data); +PSAL_DAC_HND RtkDACGetSalHnd(IN u8 DACIdx); +RTK_STATUS RtkDACFreeSalHnd(IN PSAL_DAC_HND pSalDACHND); +PSAL_DAC_MNGT_ADPT RtkDACGetMngtAdpt(IN u8 DACIdx); +RTK_STATUS RtkDACFreeMngtAdpt(IN PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_diag.h b/USDK/component/soc/realtek/8195a/fwlib/hal_diag.h new file mode 100644 index 0000000..3594b89 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_diag.h @@ -0,0 +1,110 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_DIAG_H_ +#define _HAL_DIAG_H_ + + +//Register offset +#define UART_REV_BUF_OFF 0x00 +#define UART_TRAN_HOLD_OFF 0x00 +#define UART_DLH_OFF 0x04 +#define UART_DLL_OFF 0x00 +#define UART_INTERRUPT_EN_REG_OFF 0x04 +#define UART_INTERRUPT_IDEN_REG_OFF 0x08 +#define UART_FIFO_CTL_REG_OFF 0x08 +#define UART_LINE_CTL_REG_OFF 0x0c +#define UART_MODEM_CTL_REG_OFF 0x10 +#define UART_LINE_STATUS_REG_OFF 0x14 +#define UART_MODEM_STATUS_REG_OFF 0x18 +#define UART_FIFO_ACCESS_REG_OFF 0x70 +#define UART_STATUS_REG_OFF 0x7c +#define UART_TFL_OFF 0x80 +#define UART_RFL_OFF 0x84 + + +//Buad rate +#define UART_BAUD_RATE_2400 2400 +#define UART_BAUD_RATE_4800 4800 +#define UART_BAUD_RATE_9600 9600 +#define UART_BAUD_RATE_19200 19200 +#define UART_BAUD_RATE_38400 38400 +#define UART_BAUD_RATE_57600 57600 +#define UART_BAUD_RATE_115200 115200 +#define UART_BAUD_RATE_921600 921600 +#define UART_BAUD_RATE_1152000 1152000 + +#define UART_PARITY_ENABLE 0x08 +#define UART_PARITY_DISABLE 0 + +#define UART_DATA_LEN_5BIT 0x0 +#define UART_DATA_LEN_6BIT 0x1 +#define UART_DATA_LEN_7BIT 0x2 +#define UART_DATA_LEN_8BIT 0x3 + +#define UART_STOP_1BIT 0x0 +#define UART_STOP_2BIT 0x4 + +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE UART_BAUD_RATE_38400 +#endif + +#define HAL_UART_READ32(addr) HAL_READ32(LOG_UART_REG_BASE, addr) +#define HAL_UART_WRITE32(addr, value) HAL_WRITE32(LOG_UART_REG_BASE, addr, value) +#define HAL_UART_READ16(addr) HAL_READ16(LOG_UART_REG_BASE, addr) +#define HAL_UART_WRITE16(addr, value) HAL_WRITE16(LOG_UART_REG_BASE, addr, value) +#define HAL_UART_READ8(addr) HAL_READ8(LOG_UART_REG_BASE, addr) +#define HAL_UART_WRITE8(addr, value) HAL_WRITE8(LOG_UART_REG_BASE, addr, value) + +typedef struct _LOG_UART_ADAPTER_ { + u32 BaudRate; + u32 FIFOControl; + u32 IntEnReg; + u8 Parity; + u8 Stop; + u8 DataLength; +}LOG_UART_ADAPTER, *PLOG_UART_ADAPTER; + +typedef struct _COMMAND_TABLE_ { + const u8* cmd; + u16 ArgvCnt; + u32 (*func)(u16 argc, u8* argv[]); + const u8* msg; +}COMMAND_TABLE, *PCOMMAND_TABLE; + +//VOID +//HalLogUartHandle(void); + + +extern _LONG_CALL_ROM_ u32 +HalLogUartInit( + IN LOG_UART_ADAPTER UartAdapter + ); + + +extern _LONG_CALL_ROM_ VOID +HalSerialPutcRtl8195a( + IN u8 c + ); + +extern _LONG_CALL_ROM_ u8 +HalSerialGetcRtl8195a( + IN BOOL PullMode + ); + +extern _LONG_CALL_ROM_ u32 +HalSerialGetIsrEnRegRtl8195a(VOID); + +extern _LONG_CALL_ROM_ VOID +HalSerialSetIrqEnRegRtl8195a ( + IN u32 SetValue +); + + +#endif//_HAL_DIAG_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_efuse.h b/USDK/component/soc/realtek/8195a/fwlib/hal_efuse.h new file mode 100644 index 0000000..7e9b168 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_efuse.h @@ -0,0 +1,39 @@ +/* + * Routines to access hardware + * hal_efuse.h + */ + +#ifndef _HAL_EFUSE_H_ +#define _HAL_EFUSE_H_ + +_LONG_CALL_ROM_ extern VOID HalEFUSEPowerSwitch8195AROM(IN u8 bWrite, IN u8 PwrState, IN u8 L25OutVoltage); +_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteReadROM(IN u32 CtrlSetting, IN u16 Addr, OUT u8 *Data, IN u8 L25OutVoltage); +_LONG_CALL_ROM_ extern u32 HALEFUSEOneByteWriteROM(IN u32 CtrlSetting, IN u16 Addr, IN u8 Data, IN u8 L25OutVoltage); + +int HALOTPOneByteReadRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, OUT unsigned char *Data, IN unsigned char L25OutVoltage); +int HALOTPOneByteWriteRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char Data, IN unsigned char L25OutVoltage); +int HALEFUSEOneByteReadRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char *Data, IN unsigned char L25OutVoltage); +int HALEFUSEOneByteWriteRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char Data, IN unsigned char L25OutVoltage); + + +void ReadEfuseContant(IN unsigned char UserCode, OUT unsigned char *pContant); +void ReadEfuseContant1(OUT unsigned char *pContant); +void ReadEfuseContant2(OUT unsigned char *pContant); +void ReadEfuseContant3(OUT unsigned char *pContant); +int GetRemainingEfuseLength(void); + +int WriteEfuseContant(IN unsigned char UserCode, IN unsigned char CodeWordNum, IN unsigned char WordEnable, unsigned char *pContant); +int WriteEfuseContant1(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant); +int WriteEfuseContant2(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant); +int WriteEfuseContant3(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant); + +void ReadEOTPContant(IN unsigned char *pContant); +void WriteEOTPContant(OUT unsigned char *pContant); +void HALJtagOff(void); + +#define EFUSERead8 HALEFUSEOneByteReadRAM +#define EFUSEWrite8 HALEFUSEOneByteWriteRAM + +#define L25EOUTVOLTAGE 7 +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_gdma.h b/USDK/component/soc/realtek/8195a/fwlib/hal_gdma.h new file mode 100644 index 0000000..6807363 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_gdma.h @@ -0,0 +1,141 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_GDMA_H_ +#define _HAL_GDMA_H_ + +#include "rtl8195a_gdma.h" + +typedef struct _GDMA_CH_LLI_ELE_ { + u32 Sarx; + u32 Darx; + u32 Llpx; + u32 CtlxLow; + u32 CtlxUp; + u32 Temp; +}GDMA_CH_LLI_ELE, *PGDMA_CH_LLI_ELE; +#if 1 +#if 0 +typedef struct _GDMA_CH_LLI_ { + PGDMA_CH_LLI_ELE pLliEle; + PGDMA_CH_LLI pNextLli; +}GDMA_CH_LLI, *PGDMA_CH_LLI; + +typedef struct _BLOCK_SIZE_LIST_ { + u32 BlockSize; + PBLOCK_SIZE_LIST pNextBlockSiz; +}BLOCK_SIZE_LIST, *PBLOCK_SIZE_LIST; +#else +struct GDMA_CH_LLI { + PGDMA_CH_LLI_ELE pLliEle; + struct GDMA_CH_LLI *pNextLli; +}; + +struct BLOCK_SIZE_LIST { + u32 BlockSize; + struct BLOCK_SIZE_LIST *pNextBlockSiz; +}; + +#endif + +#endif +typedef struct _HAL_GDMA_ADAPTER_ { + u32 ChSar; + u32 ChDar; + GDMA_CHANNEL_NUM ChEn; + GDMA_CTL_REG GdmaCtl; + GDMA_CFG_REG GdmaCfg; + u32 PacketLen; + u32 BlockLen; + u32 MuliBlockCunt; + u32 MaxMuliBlock; + struct GDMA_CH_LLI *pLlix; + struct BLOCK_SIZE_LIST *pBlockSizeList; + + PGDMA_CH_LLI_ELE pLli; + u32 NextPlli; + u8 TestItem; + u8 ChNum; + u8 GdmaIndex; + u8 IsrCtrl:1; + u8 GdmaOnOff:1; + u8 Llpctrl:1; + u8 Lli0:1; + u8 Rsvd4to7:4; + u8 GdmaIsrType; +}HAL_GDMA_ADAPTER, *PHAL_GDMA_ADAPTER; + +typedef struct _HAL_GDMA_CHNL_ { + u8 GdmaIndx; + u8 GdmaChnl; + u8 IrqNum; + u8 Reserved; +}HAL_GDMA_CHNL, *PHAL_GDMA_CHNL; + +typedef struct _HAL_GDMA_BLOCK_ { + u32 SrcAddr; + u32 DstAddr; + u32 BlockLength; + u32 SrcOffset; + u32 DstOffset; +}HAL_GDMA_BLOCK, *PHAL_GDMA_BLOCK; + +typedef struct _HAL_GDMA_OP_ { + VOID (*HalGdmaOnOff)(VOID *Data); + BOOL (*HalGdamChInit)(VOID *Data); + BOOL (*HalGdmaChSeting)(VOID *Data); + BOOL (*HalGdmaChBlockSeting)(VOID *Data); + VOID (*HalGdmaChDis)(VOID *Data); + VOID (*HalGdmaChEn)(VOID *Data); + VOID (*HalGdmaChIsrEnAndDis) (VOID *Data); + u8 (*HalGdmaChIsrClean)(VOID *Data); + VOID (*HalGdmaChCleanAutoSrc)(VOID *Data); + VOID (*HalGdmaChCleanAutoDst)(VOID *Data); +}HAL_GDMA_OP, *PHAL_GDMA_OP; + +typedef struct _HAL_GDMA_OBJ_ { + HAL_GDMA_ADAPTER HalGdmaAdapter; + IRQ_HANDLE GdmaIrqHandle; + volatile GDMA_CH_LLI_ELE GdmaChLli[16]; + struct GDMA_CH_LLI Lli[16]; + struct BLOCK_SIZE_LIST BlockSizeList[16]; + u8 Busy; // is transfering + u8 BlockNum; +} HAL_GDMA_OBJ, *PHAL_GDMA_OBJ; + +VOID HalGdmaOpInit(IN VOID *Data); +VOID HalGdmaOn(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaOff(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +BOOL HalGdmaChInit(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChDis(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChEn(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +BOOL HalGdmaChSeting(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +BOOL HalGdmaChBlockSeting(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChIsrEn(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChIsrDis(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +u8 HalGdmaChIsrClean(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChCleanAutoSrc(PHAL_GDMA_ADAPTER pHalGdmaAdapter); +VOID HalGdmaChCleanAutoDst(PHAL_GDMA_ADAPTER pHalGdmaAdapter); + +extern HAL_Status HalGdmaChnlRegister (u8 GdmaIdx, u8 ChnlNum); +extern VOID HalGdmaChnlUnRegister (u8 GdmaIdx, u8 ChnlNum); +extern PHAL_GDMA_CHNL HalGdmaChnlAlloc (HAL_GDMA_CHNL *pChnlOption); +extern VOID HalGdmaChnlFree (HAL_GDMA_CHNL *pChnl); +extern BOOL HalGdmaMemCpyInit(PHAL_GDMA_OBJ pHalGdmaObj); +extern VOID HalGdmaMemCpyDeInit(PHAL_GDMA_OBJ pHalGdmaObj); +extern VOID* HalGdmaMemCpy(PHAL_GDMA_OBJ pHalGdmaObj, void* pDest, void* pSrc, u32 len); +extern VOID HalGdmaMemAggr(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock); +extern BOOL HalGdmaMemCpyAggrInit(PHAL_GDMA_OBJ pHalGdmaObj); + +extern const HAL_GDMA_OP _HalGdmaOp; +extern const HAL_GDMA_CHNL GDMA_Chnl_Option[]; +extern const HAL_GDMA_CHNL GDMA_Multi_Block_Chnl_Option[]; +extern const u16 HalGdmaChnlEn[6]; + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_gpio.h b/USDK/component/soc/realtek/8195a/fwlib/hal_gpio.h new file mode 100644 index 0000000..684f775 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_gpio.h @@ -0,0 +1,250 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_GPIO_H_ +#define _HAL_GPIO_H_ + +#define HAL_GPIO_PIN_INT_MODE 0x80 + +typedef enum { + _PORT_A = 0, + _PORT_B = 1, + _PORT_C = 2, + _PORT_D = 3, + _PORT_E = 4, + _PORT_F = 5, + _PORT_G = 6, + _PORT_H = 7, + _PORT_I = 8, + _PORT_J = 9, + _PORT_K = 10, + + _PORT_MAX +} HAL_GPIO_PORT_NAME; + +typedef enum { + _PA_0 = (_PORT_A<<4|0), + _PA_1 = (_PORT_A<<4|1), + _PA_2 = (_PORT_A<<4|2), + _PA_3 = (_PORT_A<<4|3), + _PA_4 = (_PORT_A<<4|4), + _PA_5 = (_PORT_A<<4|5), + _PA_6 = (_PORT_A<<4|6), + _PA_7 = (_PORT_A<<4|7), + + _PB_0 = (_PORT_B<<4|0), + _PB_1 = (_PORT_B<<4|1), + _PB_2 = (_PORT_B<<4|2), + _PB_3 = (_PORT_B<<4|3), + _PB_4 = (_PORT_B<<4|4), + _PB_5 = (_PORT_B<<4|5), + _PB_6 = (_PORT_B<<4|6), + _PB_7 = (_PORT_B<<4|7), + + _PC_0 = (_PORT_C<<4|0), + _PC_1 = (_PORT_C<<4|1), + _PC_2 = (_PORT_C<<4|2), + _PC_3 = (_PORT_C<<4|3), + _PC_4 = (_PORT_C<<4|4), + _PC_5 = (_PORT_C<<4|5), + _PC_6 = (_PORT_C<<4|6), + _PC_7 = (_PORT_C<<4|7), + _PC_8 = (_PORT_C<<4|8), + _PC_9 = (_PORT_C<<4|9), + + _PD_0 = (_PORT_D<<4|0), + _PD_1 = (_PORT_D<<4|1), + _PD_2 = (_PORT_D<<4|2), + _PD_3 = (_PORT_D<<4|3), + _PD_4 = (_PORT_D<<4|4), + _PD_5 = (_PORT_D<<4|5), + _PD_6 = (_PORT_D<<4|6), + _PD_7 = (_PORT_D<<4|7), + _PD_8 = (_PORT_D<<4|8), + _PD_9 = (_PORT_D<<4|9), + + _PE_0 = (_PORT_E<<4|0), + _PE_1 = (_PORT_E<<4|1), + _PE_2 = (_PORT_E<<4|2), + _PE_3 = (_PORT_E<<4|3), + _PE_4 = (_PORT_E<<4|4), + _PE_5 = (_PORT_E<<4|5), + _PE_6 = (_PORT_E<<4|6), + _PE_7 = (_PORT_E<<4|7), + _PE_8 = (_PORT_E<<4|8), + _PE_9 = (_PORT_E<<4|9), + _PE_A = (_PORT_E<<4|10), + + _PF_0 = (_PORT_F<<4|0), + _PF_1 = (_PORT_F<<4|1), + _PF_2 = (_PORT_F<<4|2), + _PF_3 = (_PORT_F<<4|3), + _PF_4 = (_PORT_F<<4|4), + _PF_5 = (_PORT_F<<4|5), +// _PF_6 = (_PORT_F<<4|6), +// _PF_7 = (_PORT_F<<4|7), + + _PG_0 = (_PORT_G<<4|0), + _PG_1 = (_PORT_G<<4|1), + _PG_2 = (_PORT_G<<4|2), + _PG_3 = (_PORT_G<<4|3), + _PG_4 = (_PORT_G<<4|4), + _PG_5 = (_PORT_G<<4|5), + _PG_6 = (_PORT_G<<4|6), + _PG_7 = (_PORT_G<<4|7), + + _PH_0 = (_PORT_H<<4|0), + _PH_1 = (_PORT_H<<4|1), + _PH_2 = (_PORT_H<<4|2), + _PH_3 = (_PORT_H<<4|3), + _PH_4 = (_PORT_H<<4|4), + _PH_5 = (_PORT_H<<4|5), + _PH_6 = (_PORT_H<<4|6), + _PH_7 = (_PORT_H<<4|7), + + _PI_0 = (_PORT_I<<4|0), + _PI_1 = (_PORT_I<<4|1), + _PI_2 = (_PORT_I<<4|2), + _PI_3 = (_PORT_I<<4|3), + _PI_4 = (_PORT_I<<4|4), + _PI_5 = (_PORT_I<<4|5), + _PI_6 = (_PORT_I<<4|6), + _PI_7 = (_PORT_I<<4|7), + + _PJ_0 = (_PORT_J<<4|0), + _PJ_1 = (_PORT_J<<4|1), + _PJ_2 = (_PORT_J<<4|2), + _PJ_3 = (_PORT_J<<4|3), + _PJ_4 = (_PORT_J<<4|4), + _PJ_5 = (_PORT_J<<4|5), + _PJ_6 = (_PORT_J<<4|6), +// _PJ_7 = (_PORT_J<<4|7), + + _PK_0 = (_PORT_K<<4|0), + _PK_1 = (_PORT_K<<4|1), + _PK_2 = (_PORT_K<<4|2), + _PK_3 = (_PORT_K<<4|3), + _PK_4 = (_PORT_K<<4|4), + _PK_5 = (_PORT_K<<4|5), + _PK_6 = (_PORT_K<<4|6), +// _PK_7 = (_PORT_K<<4|7), + + // Not connected + _PIN_NC = (int)0xFFFFFFFF +} HAL_PIN_NAME; + +typedef enum +{ + GPIO_PIN_LOW = 0, + GPIO_PIN_HIGH = 1, + GPIO_PIN_ERR = 2 // read Pin error +} HAL_GPIO_PIN_STATE; + +typedef enum { + DIN_PULL_NONE = 0, //floating or high impedance ? + DIN_PULL_LOW = 1, + DIN_PULL_HIGH = 2, + + DOUT_PUSH_PULL = 3, + DOUT_OPEN_DRAIN = 4, + + INT_LOW = (5|HAL_GPIO_PIN_INT_MODE), // Interrupt Low level trigger + INT_HIGH = (6|HAL_GPIO_PIN_INT_MODE), // Interrupt High level trigger + INT_FALLING = (7|HAL_GPIO_PIN_INT_MODE), // Interrupt Falling edge trigger + INT_RISING = (8|HAL_GPIO_PIN_INT_MODE) // Interrupt Rising edge trigger +} HAL_GPIO_PIN_MODE; + +enum { + GPIO_PORT_A = 0, + GPIO_PORT_B = 1, + GPIO_PORT_C = 2, + GPIO_PORT_D = 3 +}; + +typedef enum { + hal_PullNone = 0, + hal_PullUp = 1, + hal_PullDown = 2, + hal_OpenDrain = 3, + hal_PullDefault = hal_PullNone +} HAL_PinMode; + +typedef struct _HAL_GPIO_PORT_ { + u32 out_data; // to write the GPIO port + u32 in_data; // to read the GPIO port + u32 dir; // config each pin direction +}HAL_GPIO_PORT, *PHAL_GPIO_PORT; + +#define HAL_GPIO_PIN_NAME(port,pin) (((port)<<5)|(pin)) +#define HAL_GPIO_GET_PORT_BY_NAME(x) ((x>>5) & 0x03) +#define HAL_GPIO_GET_PIN_BY_NAME(x) (x & 0x1f) + +typedef struct _HAL_GPIO_PIN_ { + HAL_GPIO_PIN_MODE pin_mode; + u32 pin_name; // Pin: [7:5]: port number, [4:0]: pin number +}HAL_GPIO_PIN, *PHAL_GPIO_PIN; + +typedef struct _HAL_GPIO_OP_ { +#if defined(__ICCARM__) + void* dummy; +#endif +}HAL_GPIO_OP, *PHAL_GPIO_OP; + +typedef void (*GPIO_IRQ_FUN)(VOID *Data, u32 Id); +typedef void (*GPIO_USER_IRQ_FUN)(u32 Id); + +typedef struct _HAL_GPIO_ADAPTER_ { + IRQ_HANDLE IrqHandle; // GPIO HAL IRQ Handle + GPIO_USER_IRQ_FUN UserIrqHandler; // GPIO IRQ Handler + GPIO_IRQ_FUN PortA_IrqHandler[32]; // The interrupt handler triggered by Port A[x] + VOID *PortA_IrqData[32]; + VOID (*EnterCritical)(void); + VOID (*ExitCritical)(void); + u32 Local_Gpio_Dir[3]; // to record direction setting: 0- IN, 1- Out + u8 Gpio_Func_En; // Is GPIO HW function enabled ? + u8 Locked; +}HAL_GPIO_ADAPTER, *PHAL_GPIO_ADAPTER; + +u32 +HAL_GPIO_GetPinName( + u32 chip_pin +); + +VOID +HAL_GPIO_PullCtrl( + u32 pin, + u32 mode +); + +VOID +HAL_GPIO_Init( + HAL_GPIO_PIN *GPIO_Pin +); + +VOID +HAL_GPIO_DeInit( + HAL_GPIO_PIN *GPIO_Pin +); + +VOID +HAL_GPIO_Irq_Init( + HAL_GPIO_PIN *GPIO_Pin +); + +VOID +HAL_GPIO_IP_DeInit( + VOID +); + + + +extern u16 GPIOState[_PORT_MAX]; // побитно 16 бит для каждого порта (A..K), бит=номер задействованного пина в порту на периферию. + +#endif // end of "#define _HAL_GPIO_H_" + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_i2c.h b/USDK/component/soc/realtek/8195a/fwlib/hal_i2c.h new file mode 100644 index 0000000..5659f77 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_i2c.h @@ -0,0 +1,594 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_I2C_H_ //#ifndef _HAL_I2C_H_ +#define _HAL_I2C_H_ + +#include "rtl8195a_i2c.h" +#include "hal_gdma.h" + +//================= I2C CONFIGURATION START ================== +// I2C SAL User Configuration Flags + +// I2C SAL operation types +#define I2C_POLL_OP_TYPE 1 //1 +#define I2C_INTR_OP_TYPE 1 //1 +#define I2C_DMA_OP_TYPE 1 //1 + +// I2C supports user register address +#define I2C_USER_REG_ADDR 1 //I2C User specific register address by using + //the first I2C data as the register + //address + +// I2C SAL used module. Please set the I2C module flag to 1 to enable the related +// I2C module functions. +#define I2C0_USED 1 +#define I2C1_USED 1 +#define I2C2_USED 1 +#define I2C3_USED 1 +//================= I2C CONFIGURATION END =================== + + +//================= I2C HAL START ========================== +// I2C debug output +#define I2C_PREFIX "RTL8195A[i2c]: " +#define I2C_PREFIX_LVL " [i2c_DBG]: " + +typedef enum _I2C_DBG_LVL_ { + HAL_I2C_LVL = 0x01, + SAL_I2C_LVL = 0x02, + VERI_I2C_LVL = 0x03, +}I2C_DBG_LVL,*PI2C_DBG_LVL; + +#if CONFIG_DEBUG_LOG > 0 +#ifdef CONFIG_DEBUG_LOG_I2C_HAL +#define DBG_I2C_LOG_PERD 100 + + #define I2CDBGLVL 0xFF + #define DBG_8195A_I2C(...) do{ \ + _DbgDump(I2C_PREFIX __VA_ARGS__);\ + }while(0) + + #define DBG_8195A_I2C_LVL(LVL,...) do{\ + if (LVL&I2CDBGLVL){\ + _DbgDump(I2C_PREFIX_LVL __VA_ARGS__);\ + }\ + }while(0) +#else + #define DBG_I2C_LOG_PERD 100 + #define DBG_8195A_I2C(...) + #define DBG_8195A_I2C_LVL(...) +#endif +#else + #define DBG_I2C_LOG_PERD 100 + #define DBG_8195A_I2C(...) + #define DBG_8195A_I2C_LVL(...) +#endif + +#define I2C_MTR_RTY_CNT 1024 +//====================================================== +// I2C HAL related enumeration +// I2C Module Selection +typedef enum _I2C_MODULE_SEL_ { + I2C0_SEL = 0x0, + I2C1_SEL = 0x1, + I2C2_SEL = 0x2, + I2C3_SEL = 0x3, +}I2C_MODULE_SEL,*PI2C_MODULE_SEL; + +// I2C HAL initial data structure +typedef struct _HAL_I2C_INIT_DAT_ { + u8 I2CIdx; //I2C index used + u8 I2CEn; //I2C module enable + u8 I2CMaster; //Master or Slave mode + u8 I2CAddrMod; //I2C addressing mode(7-bit, 10-bit) + + u8 I2CSpdMod; //I2C speed mode(Standard, Fast, High) + u8 I2CSetup; //I2C SDA setup time + u8 I2CRXTL; //I2C RX FIFO Threshold + u8 I2CTXTL; //I2C TX FIFO Threshold + + u8 I2CBusLd; //I2C bus load (pf) for high speed mode + u8 I2CReSTR; //I2C restart support + u8 I2CGC; //I2C general support + u8 I2CStartB; //I2C start byte support + + u8 I2CSlvNoAck; //I2C slave no ack support + u8 I2CDMACtrl; //I2C DMA feature support + u8 I2CCmd; //I2C Command + u8 I2CDataLen; //I2C Data Length + + u8 I2CSlvAckGC; //I2C slave acks to General Call + u8 I2CStop; //I2C issues STOP bit or not + u16 RSVD0; //Bit0: used to control HalI2CMassSendRtl8195a_Patch sending + // RESTART or not by upper layer SW. + + u8 *I2CRWData; //I2C Read/Write data pointer + + u16 I2CIntrMSK; //I2C Interrupt Mask + u16 I2CIntrClr; //I2C Interrupt register to clear + + u16 I2CAckAddr; //I2C target address in I2C Master mode, + //ack address in I2C Slave mode + u16 I2CSdaHd; //I2C SDA hold time + + u32 I2CClk; //I2C bus clock (in kHz) + + u8 I2CTxDMARqLv; //I2C TX DMA Empty Level + u8 I2CRxDMARqLv; //I2C RX DMA Full Level + u16 RSVD1; //Reserved +}HAL_I2C_INIT_DAT,*PHAL_I2C_INIT_DAT; + +// I2C HAL Operations +typedef struct _HAL_I2C_OP_ { + HAL_Status (*HalI2CInit) (VOID *Data); //HAL I2C initialization + HAL_Status (*HalI2CDeInit) (VOID *Data); //HAL I2C de-initialization + HAL_Status (*HalI2CSend) (VOID *Data); //HAL I2C send + u8 (*HalI2CReceive) (VOID *Data); //HAL I2C receive + HAL_Status (*HalI2CEnable) (VOID *Data); //HAL I2C enable module + HAL_Status (*HalI2CIntrCtrl) (VOID *Data); //HAL I2C interrupt control + u32 (*HalI2CReadReg) (VOID *Data, u8 I2CReg);//HAL I2C read register + HAL_Status (*HalI2CWriteReg) (VOID *Data, u8 I2CReg, u32 RegVal);//HAL I2C write register + HAL_Status (*HalI2CSetCLK) (VOID *Data); //HAL I2C set bus clock + HAL_Status (*HalI2CMassSend) (VOID *Data); //HAL I2C mass send + HAL_Status (*HalI2CClrIntr) (VOID *Data); //HAL I2C clear interrupts + HAL_Status (*HalI2CClrAllIntr) (VOID *Data); //HAL I2C clear all interrupts + HAL_Status (*HalI2CDMACtrl) (VOID *Data); //HAL I2C DMA control +}HAL_I2C_OP, *PHAL_I2C_OP; +//================= I2C HAL END =========================== + + +//================= I2C SAL START ========================== +//I2C SAL Macros + +//====================================================== +// I2C SAL related enumerations +// I2C Extend Features +typedef enum _I2C_EXD_SUPPORT_{ + I2C_EXD_RESTART = 0x1, //BIT_0, RESTART bit + I2C_EXD_GENCALL = 0x2, //BIT_1, Master generates General Call. All "send" operations generate General Call addresss + I2C_EXD_STARTB = 0x4, //BIT_2, Using START BYTE, instead of START Bit + I2C_EXD_SLVNOACK = 0x8, //BIT_3, Slave no ack to master + I2C_EXD_BUS400PF = 0x10, //BIT_4, I2C bus loading is 400pf + I2C_EXD_SLVACKGC = 0x20, //BIT_5, Slave acks to a General Call + I2C_EXD_USER_REG = 0x40, //BIT_6, Using User Register Address + I2C_EXD_USER_TWOB = 0x80, //BIT_7, User Register Address is 2-byte + I2C_EXD_MTR_ADDR_RTY= 0x100, //BIT_8, Master retries to send start condition and Slave address when the slave doesn't ack + // the address. + I2C_EXD_MTR_ADDR_UPD= 0x200, //BIT_9, Master dynamically updates slave address + I2C_EXD_MTR_HOLD_BUS= 0x400, //BIT_10, Master doesn't generate STOP when the FIFO is empty. This would make Master hold + // the bus. +}I2C_EXD_SUPPORT,*PI2C_EXD_SUPPORT; + +// I2C operation type +typedef enum _I2C_OP_TYPE_ { + I2C_POLL_TYPE = 0x0, + I2C_DMA_TYPE = 0x1, + I2C_INTR_TYPE = 0x2, +}I2C_OP_TYPE, *PI2C_OP_TYPE; + +// I2C pinmux selection +typedef enum _I2C_PINMUX_ { + I2C_PIN_S0 = 0x0, + I2C_PIN_S1 = 0x1, + I2C_PIN_S2 = 0x2, + I2C_PIN_S3 = 0x3, //Only valid for I2C0 and I2C3 +}I2C_PINMUX, *PI2C_PINMUX; + +// I2C module status +typedef enum _I2C_MODULE_STATUS_ { + I2C_DISABLE = 0x0, + I2C_ENABLE = 0x1, +}I2C_MODULE_STATUS, *PI2C_MODULE_STATUS; + +// I2C device status +typedef enum _I2C_Device_STATUS_ { + I2C_STS_UNINITIAL = 0x00, + I2C_STS_INITIALIZED = 0x01, + I2C_STS_IDLE = 0x02, + + I2C_STS_TX_READY = 0x03, + I2C_STS_TX_ING = 0x04, + + I2C_STS_RX_READY = 0x05, + I2C_STS_RX_ING = 0x06, + + I2C_STS_ERROR = 0x10, + I2C_STS_TIMEOUT = 0x11, +}I2C_Device_STATUS, *PI2C_Device_STATUS; + +// I2C feature status +typedef enum _I2C_FEATURE_STATUS_{ + I2C_FEATURE_DISABLED = 0, + I2C_FEATURE_ENABLED = 1, +}I2C_FEATURE_STATUS,*PI2C_FEATURE_STATUS; + +// I2C device mode +typedef enum _I2C_DEV_MODE_ { + I2C_SLAVE_MODE = 0x0, + I2C_MASTER_MODE = 0x1, +}I2C_DEV_MODE, *PI2C_DEV_MODE; + +// I2C Bus Transmit/Receive +typedef enum _I2C_DIRECTION_ { + I2C_ONLY_TX = 0x1, + I2C_ONLY_RX = 0x2, + I2C_TXRX = 0x3, +}I2C_DIRECTION, *PI2C_DIRECTION; + +//I2C DMA module number +typedef enum _I2C_DMA_MODULE_SEL_ { + I2C_DMA_MODULE_0 = 0x0, + I2C_DMA_MODULE_1 = 0x1 +}I2C_DMA_MODULE_SEL, *PI2C_DMA_MODULE_SEL; + +// I2C0 DMA peripheral number +typedef enum _I2C0_DMA_PERI_NUM_ { + I2C0_DMA_TX_NUM = 0x8, + I2C0_DMA_RX_NUM = 0x9, +}I2C0_DMA_PERI_NUM,*PI2C0_DMA_PERI_NUM; + +// I2C1 DMA peripheral number +typedef enum _I2C1_DMA_PERI_NUM_ { + I2C1_DMA_TX_NUM = 0xA, + I2C1_DMA_RX_NUM = 0xB, +}I2C1_DMA_PERI_NUM,*PI2C1_DMA_PERI_NUM; + +// I2C0 DMA module used +typedef enum _I2C0_DMA_MODULE_ { + I2C0_DMA0 = 0x0, + I2C0_DMA1 = 0x1, +}I2C0_DMA_MODULE,*PI2C0_DMA_MODULE; + +// I2C0 DMA module used +typedef enum _I2C1_DMA_MODULE_ { + I2C1_DMA0 = 0x0, + I2C1_DMA1 = 0x1, +}I2C1_DMA_MODULE,*PI2C1_DMA_MODULE; + +// I2C command type +typedef enum _I2C_COMMAND_TYPE_ { + I2C_WRITE_CMD = 0x0, + I2C_READ_CMD = 0x1, +}I2C_COMMAND_TYPE,*PI2C_COMMAND_TYPE; + +// I2C STOP BIT +typedef enum _I2C_STOP_TYPE_ { + I2C_STOP_DIS = 0x0, + I2C_STOP_EN = 0x1, +}I2C_STOP_TYPE, *PI2C_STOP_TYPE; + +// I2C error type +typedef enum _I2C_ERR_TYPE_ { + I2C_ERR_RX_UNDER = 0x01, //I2C RX FIFO Underflow + I2C_ERR_RX_OVER = 0x02, //I2C RX FIFO Overflow + I2C_ERR_TX_OVER = 0x04, //I2C TX FIFO Overflow + I2C_ERR_TX_ABRT = 0x08, //I2C TX terminated + I2C_ERR_SLV_TX_NACK = 0x10, //I2C slave transmission terminated by master NACK, + //but there are data in slave TX FIFO + I2C_ERR_MST_A_NACK = 0x12, + I2C_ERR_MST_D_NACK = 0x13, + I2C_ERR_USER_REG_TO = 0x20, + + I2C_ERR_RX_CMD_TO = 0x21, + I2C_ERR_RX_FF_TO = 0x22, + I2C_ERR_TX_CMD_TO = 0x23, + I2C_ERR_TX_FF_TO = 0x24, + + I2C_ERR_TX_ADD_TO = 0x25, + I2C_ERR_RX_ADD_TO = 0x26, +}I2C_ERR_TYPE, *PI2C_ERR_TYPE; + +// I2C Time Out type +typedef enum _I2C_TIMEOUT_TYPE_ { + I2C_TIMEOOUT_DISABLE = 0x00, + I2C_TIMEOOUT_ENDLESS = 0xFFFFFFFF, +}I2C_TIMEOUT_TYPE, *PI2C_TIMEOUT_TYPE; + +//====================================================== +// SAL I2C related data structures +// I2C user callback adapter +typedef struct _SAL_I2C_USERCB_ADPT_ { + VOID (*USERCB) (VOID *Data); + u32 USERData; +}SAL_I2C_USERCB_ADPT, *PSAL_I2C_USERCB_ADPT; + +// I2C user callback structure +typedef struct _SAL_I2C_USER_CB_ { + PSAL_I2C_USERCB_ADPT pTXCB; //I2C Transmit Callback + PSAL_I2C_USERCB_ADPT pTXCCB; //I2C Transmit Complete Callback + PSAL_I2C_USERCB_ADPT pRXCB; //I2C Receive Callback + PSAL_I2C_USERCB_ADPT pRXCCB; //I2C Receive Complete Callback + PSAL_I2C_USERCB_ADPT pRDREQCB; //I2C Read Request Callback + PSAL_I2C_USERCB_ADPT pERRCB; //I2C Error Callback + PSAL_I2C_USERCB_ADPT pDMATXCB; //I2C DMA Transmit Callback + PSAL_I2C_USERCB_ADPT pDMATXCCB; //I2C DMA Transmit Complete Callback + PSAL_I2C_USERCB_ADPT pDMARXCB; //I2C DMA Receive Callback + PSAL_I2C_USERCB_ADPT pDMARXCCB; //I2C DMA Receive Complete Callback + PSAL_I2C_USERCB_ADPT pGENCALLCB; //I2C General Call Callback +}SAL_I2C_USER_CB, *PSAL_I2C_USER_CB; + +// I2C Transmit Buffer +typedef struct _SAL_I2C_TRANSFER_BUF_ { + u16 DataLen; //I2C Transmfer Length + u16 TargetAddr; //I2C Target Address. It's only valid in Master Mode. + u32 RegAddr; //I2C Register Address. It's only valid in Master Mode. + u32 RSVD; // + u8 *pDataBuf; //I2C Transfer Buffer Pointer +}SAL_I2C_TRANSFER_BUF,*PSAL_I2C_TRANSFER_BUF; + +typedef struct _SAL_I2C_DMA_USER_DEF_ { + u8 TxDatSrcWdth; + u8 TxDatDstWdth; + u8 TxDatSrcBstSz; + u8 TxDatDstBstSz; + u8 TxChNo; + u8 RSVD0; + u16 RSVD1; + u8 RxDatSrcWdth; + u8 RxDatDstWdth; + u8 RxDatSrcBstSz; + u8 RxDatDstBstSz; + u8 RxChNo; + u8 RSVD2; + u16 RSVD3; +}SAL_I2C_DMA_USER_DEF, *PSAL_I2C_DMA_USER_DEF; + +// RTK I2C OP +typedef struct _RTK_I2C_OP_ { + HAL_Status (*Init) (VOID *Data); + HAL_Status (*DeInit) (VOID *Data); + HAL_Status (*Send) (VOID *Data); + HAL_Status (*Receive) (VOID *Data); + HAL_Status (*IoCtrl) (VOID *Data); + HAL_Status (*PowerCtrl) (VOID *Data); +}RTK_I2C_OP, *PRTK_I2C_OP; + +// Software API Level I2C Handler +typedef struct _SAL_I2C_HND_ { + u8 DevNum; //I2C device number + u8 PinMux; //I2C pin mux seletion + u8 OpType; //I2C operation type selection + volatile u8 DevSts; //I2C device status + + u8 I2CMaster; //I2C Master or Slave mode + u8 I2CAddrMod; //I2C 7-bit or 10-bit mode + u8 I2CSpdMod; //I2C SS/ FS/ HS speed mode + u8 I2CAckAddr; //I2C target address in Master + //mode or ack address in Slave + //mode + + u16 I2CClk; //I2C bus clock + u8 MasterRead; //I2C Master Read Supported, + //An Address will be sent before + //read data back. + + u8 I2CDmaSel; //I2C DMA module select + // 0 for DMA0, + // 1 for DMA1 + u8 I2CTxDMARqLv; //I2C TX DMA Empty Level + u8 I2CRxDMARqLv; //I2C RX DMA Full Level + u16 RSVD0; //Reserved + + u32 AddRtyTimeOut; //I2C TimeOut Value for master send address retry + //(Originally Reserved.) + + u32 I2CExd; //I2C extended options: + //bit 0: I2C RESTART supported, + // 0 for NOT supported, + // 1 for supported + //bit 1: I2C General Call supported + // 0 for NOT supported, + // 1 for supported + //bit 2: I2C START Byte supported + // 0 for NOT supported, + // 1 for supported + //bit 3: I2C Slave-No-Ack + // supported + // 0 for NOT supported, + // 1 for supported + //bit 4: I2C bus loading, + // 0 for 100pf, + // 1 for 400pf + //bit 5: I2C slave ack to General + // Call + //bit 6: I2C User register address + //bit 7: I2C 2-Byte User register + // address + //bit 8: I2C slave address no ack retry, + // It's only for Master mode, + // when slave doesn't ack the + // address + //bit 31~bit 8: Reserved + u32 ErrType; // + u32 TimeOut; //I2C IO Timeout count, in ms + + PHAL_I2C_INIT_DAT pInitDat; //Pointer to I2C initial data struct + PSAL_I2C_TRANSFER_BUF pTXBuf; //Pointer to I2C TX buffer + PSAL_I2C_TRANSFER_BUF pRXBuf; //Pointer to I2C RX buffer + PSAL_I2C_USER_CB pUserCB; //Pointer to I2C User Callback + PSAL_I2C_DMA_USER_DEF pDMAConf; //Pointer to I2C User Define DMA config +}SAL_I2C_HND, *PSAL_I2C_HND; + + + +//====================================================== +// I2C SAL Function Prototypes + +// For checking I2C input index valid or not +static inline HAL_Status +RtkI2CIdxChk( + IN u8 I2CIdx +) +{ + if (I2CIdx > I2C3_SEL) + return HAL_ERR_UNKNOWN; + + return HAL_OK; +} +#if 0 +//For checking I2C operation type valid or not +static inline HAL_Status +RtkI2COpTypeChk( + IN VOID *Data +) +{ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + + if (pSalI2CHND->OpType == I2C_POLL_TYPE) + return HAL_ERR_UNKNOWN; + + if (pSalI2CHND->OpType == I2C_DMA_TYPE) + return HAL_ERR_UNKNOWN; + + if (pSalI2CHND->OpType == I2C_INTR_TYPE) + return HAL_ERR_UNKNOWN; + + pSalI2CHND = pSalI2CHND; + + return HAL_OK; +} +#endif +//For checking I2C DMA available or not +static inline HAL_Status +RtkI2CDMAChk( + IN VOID *Data +) +{ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + + if (pSalI2CHND->OpType == I2C_DMA_TYPE) { + if (pSalI2CHND->DevNum >= I2C2_SEL) + return HAL_ERR_UNKNOWN; + } + else { + return HAL_ERR_UNKNOWN; + } + + return HAL_OK; +} + +//For checking I2C DMA available or not +static inline HAL_Status +RtkI2CDMAInitChk( + IN VOID *Data +) +{ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + + if (pSalI2CHND->OpType != I2C_DMA_TYPE) { + return HAL_ERR_UNKNOWN; + } + else { + return HAL_OK; + } + +} + +//====================================================== +//SAL I2C management function prototype +_LONG_CALL_ROM_ HAL_Status RtkI2CLoadDefault(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CInit(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CDeInit(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CSend(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CReceive(IN VOID *Data); +_LONG_CALL_ROM_ VOID RtkSalI2COpInit(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CSendUserAddr(IN VOID *Data,IN u8 MtrWr); +_LONG_CALL_ROM_ HAL_Status RtkI2CIoCtrl(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status RtkI2CPowerCtrl(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CInitForPS(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CDeInitForPS(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CDisablePS(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CEnablePS(IN VOID *Data); +//================= I2C SAL END =========================== + + +//================= I2C SAL MANAGEMENT START ================= +// I2C SAL management macros +#define SAL_USER_CB_NUM (sizeof(SAL_I2C_USER_CB) / sizeof(PSAL_I2C_USERCB_ADPT)) + +//====================================================== +// I2C SAL management data structures +// I2C SAL handle private +typedef struct _SAL_I2C_HND_PRIV_ { + VOID **ppSalI2CHnd; //Pointer to SAL_I2C_HND pointer + SAL_I2C_HND SalI2CHndPriv; //Private SAL_I2C_HND +}SAL_I2C_HND_PRIV, *PSAL_I2C_HND_PRIV; + +//I2C SAL management adapter +typedef struct _SAL_I2C_MNGT_ADPT_ { + PSAL_I2C_HND_PRIV pSalHndPriv; //Pointer to SAL_I2C_HND + PHAL_I2C_INIT_DAT pHalInitDat; //Pointer to HAL I2C initial data( HAL_I2C_INIT_DAT ) + PHAL_I2C_OP pHalOp; //Pointer to HAL I2C operation( HAL_I2C_OP ) + VOID (*pHalOpInit)(VOID*); //Pointer to HAL I2C initialize function + PIRQ_HANDLE pIrqHnd; //Pointer to IRQ handler in SAL layer( IRQ_HANDLE ) + PSAL_I2C_USER_CB pUserCB; //Pointer to SAL user callbacks (SAL_I2C_USER_CB ) + volatile u32 MstRDCmdCnt; //Used for Master Read command count + volatile u32 InnerTimeOut; //Used for SAL internal timeout count + VOID (*pSalIrqFunc)(VOID*); //Used for SAL I2C interrupt function + + PSAL_I2C_DMA_USER_DEF pDMAConf; //Pointer to I2C User Define DMA config + PHAL_GDMA_ADAPTER pHalTxGdmaAdp; //Pointer to HAL_GDMA_ADAPTER + PHAL_GDMA_ADAPTER pHalRxGdmaAdp; //Pointer to HAL_GDMA_ADAPTER + PHAL_GDMA_OP pHalGdmaOp; //Pointer to HAL_GDMA_OP + VOID (*pHalGdmaOpInit)(VOID*); //Pointer to HAL I2C initialize function + PIRQ_HANDLE pIrqTxGdmaHnd; //Pointer to IRQ handler for Tx GDMA + PIRQ_HANDLE pIrqRxGdmaHnd; //Pointer to IRQ handler for Rx GDMA + VOID (*pSalDMATxIrqFunc)(VOID*); //Used for SAL I2C interrupt function + VOID (*pSalDMARxIrqFunc)(VOID*); //Used for SAL I2C interrupt function + u32 RSVD; //Reserved +}SAL_I2C_MNGT_ADPT, *PSAL_I2C_MNGT_ADPT; + +//====================================================== +//SAL I2C management function prototype +PSAL_I2C_MNGT_ADPT RtkI2CGetMngtAdpt(IN u8 I2CIdx); +HAL_Status RtkI2CFreeMngtAdpt(IN PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt); +PSAL_I2C_HND RtkI2CGetSalHnd(IN u8 I2CIdx); +HAL_Status RtkI2CFreeSalHnd(IN PSAL_I2C_HND pSalI2CHND); +u32 RtkSalI2CSts(IN VOID *Data); + +extern _LONG_CALL_ VOID I2CISRHandle(IN VOID *Data); +extern _LONG_CALL_ VOID I2CTXGDMAISRHandle(IN VOID *Data); +extern _LONG_CALL_ VOID I2CRXGDMAISRHandle(IN VOID *Data); +extern HAL_Status I2CIsTimeout (IN u32 StartCount, IN u32 TimeoutCnt); +extern HAL_TIMER_OP HalTimerOp; +//====================================================== +// Function Prototypes +_LONG_CALL_ VOID HalI2COpInit(IN VOID *Data); +//================= I2C SAL MANAGEMENT END ================== + +//================= Rtl8195a I2C V02 function prototype ============ +_LONG_CALL_ VOID HalI2COpInitV02(IN VOID *Data); +_LONG_CALL_ VOID I2CISRHandleV02(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CSendV02(IN VOID *Data); +_LONG_CALL_ HAL_Status RtkI2CReceiveV02(IN VOID *Data); +_LONG_CALL_ VOID RtkSalI2COpInitV02(IN VOID *Data); +//================= Rtl8195a I2C V02 function prototype END========== + +//================= Rtl8195a I2C V04 function prototype ============ +_LONG_CALL_ VOID HalI2COpInit_V04(IN VOID *Data); +_LONG_CALL_ VOID I2CISRHandle_V04(IN VOID *Data); +//================= Rtl8195a I2C V04 function prototype END========== + +//====================================================== +//SAL I2C patch function prototype +HAL_Status RtkI2CSend_Patch(IN VOID *Data); +HAL_Status RtkI2CReceive_Patch(IN VOID *Data); +VOID HalI2COpInit_Patch(IN VOID *Data); +VOID I2CISRHandle_Patch(IN VOID *Data); + +#ifndef CONFIG_RELEASE_BUILD_LIBRARIES +#define RtkI2CSend RtkI2CSend_Patch +#define RtkI2CReceive RtkI2CReceive_Patch +#endif +HAL_Status RtkI2CSend_Patch(IN VOID *Data); +HAL_Status RtkI2CReceive_Patch(IN VOID *Data); +//================= I2C SAL END =========================== + +#endif //#ifndef _HAL_I2C_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_i2s.h b/USDK/component/soc/realtek/8195a/fwlib/hal_i2s.h new file mode 100644 index 0000000..066b689 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_i2s.h @@ -0,0 +1,347 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_I2S_H_ +#define _HAL_I2S_H_ + +#include "rtl8195a_i2s.h" + +/* User Define Flags */ + +#define I2S_MAX_ID 1 // valid I2S index 0 ~ I2S_MAX_ID + +/**********************************************************************/ +/* I2S HAL initial data structure */ +typedef struct _HAL_I2S_INIT_DAT_ { + u8 I2SIdx; /*I2S index used*/ + u8 I2SEn; /*I2S module enable tx/rx/tx+rx*/ + u8 I2SMaster; /*I2S Master or Slave mode*/ + u8 I2SWordLen; /*I2S Word length 16 or 24bits*/ + + u8 I2SChNum; /*I2S Channel number mono or stereo*/ + u8 I2SPageNum; /*I2S Page Number 2~4*/ + u16 I2SPageSize; /*I2S page Size 1~4096 word*/ + + u8 *I2STxData; /*I2S Tx data pointer*/ + + u8 *I2SRxData; /*I2S Rx data pointer*/ + + u32 I2STxIntrMSK; /*I2S Tx Interrupt Mask*/ + u32 I2STxIntrClr; /*I2S Tx Interrupt register to clear */ + + u32 I2SRxIntrMSK; /*I2S Rx Interrupt Mask*/ + u32 I2SRxIntrClr; /*I2S Rx Interrupt register to clear*/ + + u16 I2STxIdx; /*I2S TX page index */ + u16 I2SRxIdx; /*I2S RX page index */ + + u16 I2SHWTxIdx; /*I2S HW TX page index */ + u16 I2SHWRxIdx; /*I2S HW RX page index */ + + + u16 I2SRate; /*I2S sample rate*/ + u8 I2STRxAct; /*I2S tx rx act*/ +}HAL_I2S_INIT_DAT, *PHAL_I2S_INIT_DAT; + +/**********************************************************************/ +/* I2S Data Structures */ +/* I2S Module Selection */ +typedef enum _I2S_MODULE_SEL_ { + I2S0_SEL = 0x0, + I2S1_SEL = 0x1, +}I2S_MODULE_SEL,*PI2S_MODULE_SEL; +/* +typedef struct _HAL_I2S_ADAPTER_ { + u32 Enable:1; + I2S_CTL_REG I2sCtl; + I2S_SETTING_REG I2sSetting; + u32 abc; + u8 I2sIndex; +}HAL_I2S_ADAPTER, *PHAL_I2S_ADAPTER; +*/ +/* I2S HAL Operations */ +typedef struct _HAL_I2S_OP_ { + RTK_STATUS (*HalI2SInit) (VOID *Data); + RTK_STATUS (*HalI2SDeInit) (VOID *Data); + RTK_STATUS (*HalI2STx) (VOID *Data, u8 *pBuff); + RTK_STATUS (*HalI2SRx) (VOID *Data, u8 *pBuff); + RTK_STATUS (*HalI2SEnable) (VOID *Data); + RTK_STATUS (*HalI2SIntrCtrl) (VOID *Data); + u32 (*HalI2SReadReg) (VOID *Data, u8 I2SReg); + RTK_STATUS (*HalI2SSetRate) (VOID *Data); + RTK_STATUS (*HalI2SSetWordLen) (VOID *Data); + RTK_STATUS (*HalI2SSetChNum) (VOID *Data); + RTK_STATUS (*HalI2SSetPageNum) (VOID *Data); + RTK_STATUS (*HalI2SSetPageSize) (VOID *Data); + + RTK_STATUS (*HalI2SClrIntr) (VOID *Data); + RTK_STATUS (*HalI2SClrAllIntr) (VOID *Data); + RTK_STATUS (*HalI2SDMACtrl) (VOID *Data); +/* + VOID (*HalI2sOnOff)(VOID *Data); + BOOL (*HalI2sInit)(VOID *Data); + BOOL (*HalI2sSetting)(VOID *Data); + BOOL (*HalI2sEn)(VOID *Data); + BOOL (*HalI2sIsrEnAndDis) (VOID *Data); + BOOL (*HalI2sDumpReg)(VOID *Data); + BOOL (*HalI2s)(VOID *Data); +*/ +}HAL_I2S_OP, *PHAL_I2S_OP; + + +/**********************************************************************/ + +/* I2S Pinmux Selection */ +#if 0 +typedef enum _I2S0_PINMUX_ { + I2S0_TO_S0 = 0x0, + I2S0_TO_S1 = 0x1, + I2S0_TO_S2 = 0x2, +}I2S0_PINMUX, *PI2S0_PINMUX; + +typedef enum _I2S1_PINMUX_ { + I2S1_TO_S0 = 0x0, + I2S1_TO_S1 = 0x1, +}I2S1_PINMUX, *PI2S1_PINMUX; +#endif + +typedef enum _I2S_PINMUX_ { + I2S_S0 = 0, + I2S_S1 = 1, + I2S_S2 = 2, + I2S_S3 = 3 +}I2S_PINMUX, *PI2S_PINMUX; + + +/* I2S Module Status */ +typedef enum _I2S_MODULE_STATUS_ { + I2S_DISABLE = 0x0, + I2S_ENABLE = 0x1, +}I2S_MODULE_STATUS, *PI2S_MODULE_STATUS; + + +/* I2S Device Status */ +typedef enum _I2S_Device_STATUS_ { + I2S_STS_UNINITIAL = 0x00, + I2S_STS_INITIALIZED = 0x01, + I2S_STS_IDLE = 0x02, + + I2S_STS_TX_READY = 0x03, + I2S_STS_TX_ING = 0x04, + + I2S_STS_RX_READY = 0x05, + I2S_STS_RX_ING = 0x06, + + I2S_STS_TRX_READY = 0x07, + I2S_STS_TRX_ING = 0x08, + + I2S_STS_ERROR = 0x09, +}I2S_Device_STATUS, *PI2S_Device_STATUS; + + +/* I2S Feature Status */ +typedef enum _I2S_FEATURE_STATUS_{ + I2S_FEATURE_DISABLED = 0, + I2S_FEATURE_ENABLED = 1, +}I2S_FEATURE_STATUS,*PI2S_FEATURE_STATUS; + +/* I2S Device Mode */ +typedef enum _I2S_DEV_MODE_ { + I2S_MASTER_MODE = 0x0, + I2S_SLAVE_MODE = 0x1 +}I2S_DEV_MODE, *PI2S_DEV_MODE; + +/* I2S Word Length */ +typedef enum _I2S_WORD_LEN_ { + I2S_WL_16 = 0x0, + I2S_WL_24 = 0x1, +}I2S_WORD_LEN, *PI2S_WORD_LEN; + +/* I2S Bus Transmit/Receive */ +typedef enum _I2S_DIRECTION_ { + I2S_ONLY_RX = 0x0, + I2S_ONLY_TX = 0x1, + I2S_TXRX = 0x2 +}I2S_DIRECTION, *PI2S_DIRECTION; + +/* I2S Channel number */ +typedef enum _I2S_CH_NUM_ { + I2S_CH_STEREO = 0x0, + I2S_CH_RSVD = 0x1, + I2S_CH_MONO = 0x2 +}I2S_CH_NUM, *PI2S_CH_NUM; + +/* I2S Page number */ +typedef enum _I2S_PAGE_NUM_ { + I2S_1PAGE = 0x0, + I2S_2PAGE = 0x1, + I2S_3PAGE = 0x2, + I2S_4PAGE = 0x3 +}I2S_PAGE_NUM, *PI2S_PAGE_NUM; + +/* I2S Sample rate*/ +typedef enum _I2S_SAMPLE_RATE_ { + I2S_SR_8KHZ = 0x00, // /12 + I2S_SR_16KHZ = 0x01, // /6 + I2S_SR_24KHZ = 0x02, // /4 + I2S_SR_32KHZ = 0x03, // /3 + I2S_SR_48KHZ = 0x05, // /2 + I2S_SR_96KHZ = 0x06, // x1, base 96kHz + I2S_SR_7p35KHZ = 0x10, + I2S_SR_11p02KHZ = 0x11, + I2S_SR_22p05KHZ = 0x12, + I2S_SR_29p4KHZ = 0x13, + I2S_SR_44p1KHZ = 0x15, + I2S_SR_88p2KHZ = 0x16 // x1, base 88200Hz +}I2S_SAMPLE_RATE, *PI2S_SAMPLE_RATE; + +/* I2S TX interrupt mask/status */ +typedef enum _I2S_TX_IMR_ { + I2S_TX_INT_PAGE0_OK = (1<<0), + I2S_TX_INT_PAGE1_OK = (1<<1), + I2S_TX_INT_PAGE2_OK = (1<<2), + I2S_TX_INT_PAGE3_OK = (1<<3), + I2S_TX_INT_FULL = (1<<4), + I2S_TX_INT_EMPTY = (1<<5) +} I2S_TX_IMR, *PI2S_TX_IMR; + +/* I2S RX interrupt mask/status */ +typedef enum _I2S_RX_IMR_ { + I2S_RX_INT_PAGE0_OK = (1<<0), + I2S_RX_INT_PAGE1_OK = (1<<1), + I2S_RX_INT_PAGE2_OK = (1<<2), + I2S_RX_INT_PAGE3_OK = (1<<3), + I2S_RX_INT_EMPTY = (1<<4), + I2S_RX_INT_FULL = (1<<5) +} I2S_RX_IMR, *PI2S_RX_IMR; + +/* I2S User Callbacks */ +typedef struct _SAL_I2S_USER_CB_{ + VOID (*TXCB) (VOID *Data); + VOID (*TXCCB) (VOID *Data); + VOID (*RXCB) (VOID *Data); + VOID (*RXCCB) (VOID *Data); + VOID (*RDREQCB) (VOID *Data); + VOID (*ERRCB) (VOID *Data); + VOID (*GENCALLCB) (VOID *Data); +}SAL_I2S_USER_CB,*PSAL_I2S_USER_CB; + +typedef struct _I2S_USER_CB_{ + VOID (*TxCCB)(uint32_t id, char *pbuf); + u32 TxCBId; + VOID (*RxCCB)(uint32_t id, char *pbuf); + u32 RxCBId; +}I2S_USER_CB,*PI2S_USER_CB; + +/* Software API Level I2S Handler */ +typedef struct _HAL_I2S_ADAPTER_{ + u8 DevNum; //I2S device number + u8 PinMux; //I2S pin mux seletion + u8 RSVD0; //Reserved + volatile u8 DevSts; //I2S device status + + u32 RSVD2; //Reserved + u32 I2SExd; //I2S extended options: + //bit 0: I2C RESTART supported, + // 0 for NOT supported, + // 1 for supported + //bit 1: I2C General Call supported + // 0 for NOT supported, + // 1 for supported + //bit 2: I2C START Byte supported + // 0 for NOT supported, + // 1 for supported + //bit 3: I2C Slave-No-Ack + // supported + // 0 for NOT supported, + // 1 for supported + //bit 4: I2C bus loading, + // 0 for 100pf, + // 1 for 400pf + //bit 5: I2C slave ack to General + // Call + //bit 6: I2C User register address + //bit 7: I2C 2-Byte User register + // address + //bit 31~bit 8: Reserved + u32 ErrType; // + u32 TimeOut; //I2S IO Timeout count + + PHAL_I2S_INIT_DAT pInitDat; //Pointer to I2S initial data struct + I2S_USER_CB UserCB; //Pointer to I2S User Callback + IRQ_HANDLE IrqHandle; // Irq Handler + + u32* TxPageList[4]; // The Tx DAM buffer: pointer of each page + u32* RxPageList[4]; // The Tx DAM buffer: pointer of each page +}HAL_I2S_ADAPTER, *PHAL_I2S_ADAPTER; + +typedef struct _HAL_I2S_DEF_SETTING_{ + u8 I2SMaster; // Master or Slave mode + u8 DevSts; //I2S device status + u8 I2SChNum; //I2S Channel number mono or stereo + u8 I2SPageNum; //I2S Page number 2~4 + u8 I2STRxAct; //I2S tx rx act, tx only or rx only or tx+rx + u8 I2SWordLen; //I2S Word length 16bit or 24bit + u16 I2SPageSize; //I2S Page size 1~4096 word + + u16 I2SRate; //I2S sample rate 8k ~ 96khz + + u32 I2STxIntrMSK; /*I2S Tx Interrupt Mask*/ + u32 I2SRxIntrMSK; /*I2S Rx Interrupt Mask*/ +}HAL_I2S_DEF_SETTING, *PHAL_I2S_DEF_SETTING; + + + +/**********************************************************************/ +HAL_Status +RtkI2SLoadDefault(IN VOID *Adapter, IN VOID *Setting); + +HAL_Status +RtkI2SInit(IN VOID *Data); + +HAL_Status +RtkI2SDeInit(IN VOID *Data); + +HAL_Status +RtkI2SEnable(IN VOID *Data); + +HAL_Status +RtkI2SDisable(IN VOID *Data); + +extern HAL_Status +HalI2SInit( IN VOID *Data); + +extern VOID +HalI2SDeInit( IN VOID *Data); + +extern HAL_Status +HalI2SDisable( IN VOID *Data); + +extern HAL_Status +HalI2SEnable( IN VOID *Data); + + + + +/**********************************************************************/ + + +VOID I2S0ISRHandle(VOID *Data); +VOID I2S1ISRHandle(VOID *Data); + + +/**********************************************************************/ + +VOID HalI2SOpInit( + IN VOID *Data +); + + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_irqn.h b/USDK/component/soc/realtek/8195a/fwlib/hal_irqn.h new file mode 100644 index 0000000..ac1ff95 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_irqn.h @@ -0,0 +1,112 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_IRQN_H_ +#define _HAL_IRQN_H_ + +#define PERIPHERAL_IRQ_BASE_NUM 64 + +typedef enum _IRQn_Type_ { +#if 0 +/****** Cortex-M3 Processor Exceptions Numbers ********/ + NON_MASKABLE_INT_IRQ = -14, + HARD_FAULT_IRQ = -13, + MEM_MANAGE_FAULT_IRQ = -12, + BUS_FAULT_IRQ = -11, + USAGE_FAULT_IRQ = -10, + SVCALL_IRQ = -5, + DEBUG_MONITOR_IRQ = -4, + PENDSVC_IRQ = -2, + SYSTICK_IRQ = -1, +#else +/****** Cortex-M3 Processor Exceptions Numbers ********/ + NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */ + MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */ + BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */ + SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */ + SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */ +#endif +/****** RTL8195A Specific Interrupt Numbers ************/ + SYSTEM_ON_IRQ = 0, + WDG_IRQ = 1, + TIMER0_IRQ = 2, + TIMER1_IRQ = 3, + I2C3_IRQ = 4, + TIMER2_7_IRQ = 5, + SPI0_IRQ = 6, + GPIO_IRQ = 7, + UART0_IRQ = 8, + SPI_FLASH_IRQ = 9, + USB_OTG_IRQ = 10, + SDIO_HOST_IRQ = 11, + SDIO_DEVICE_IRQ = 12, + I2S0_PCM0_IRQ = 13, + I2S1_PCM1_IRQ = 14, + WL_DMA_IRQ = 15, + WL_PROTOCOL_IRQ = 16, + CRYPTO_IRQ = 17, + GMAC_IRQ = 18, + PERIPHERAL_IRQ = 19, + GDMA0_CHANNEL0_IRQ = 20, + GDMA0_CHANNEL1_IRQ = 21, + GDMA0_CHANNEL2_IRQ = 22, + GDMA0_CHANNEL3_IRQ = 23, + GDMA0_CHANNEL4_IRQ = 24, + GDMA0_CHANNEL5_IRQ = 25, + GDMA1_CHANNEL0_IRQ = 26, + GDMA1_CHANNEL1_IRQ = 27, + GDMA1_CHANNEL2_IRQ = 28, + GDMA1_CHANNEL3_IRQ = 29, + GDMA1_CHANNEL4_IRQ = 30, + GDMA1_CHANNEL5_IRQ = 31, + +/****** RTL8195A Peripheral Interrupt Numbers ************/ + I2C0_IRQ = 64,// 0 + 64, + I2C1_IRQ = 65,// 1 + 64, + I2C2_IRQ = 66,// 2 + 64, + SPI1_IRQ = 72,// 8 + 64, + SPI2_IRQ = 73,// 9 + 64, + UART1_IRQ = 80,// 16 + 64, + UART2_IRQ = 81,// 17 + 64, + UART_LOG_IRQ = 88,// 24 + 64, + ADC_IRQ = 89,// 25 + 64, + DAC0_IRQ = 91,// 27 + 64, + DAC1_IRQ = 92,// 28 + 64, + //RXI300_IRQ = 93// 29 + 64 + LP_EXTENSION_IRQ = 93,// 29+64 + + PTA_TRX_IRQ = 95,// 31+64 + RXI300_IRQ = 96,// 0+32 + 64 + NFC_IRQ = 97 // 1+32+64 +} IRQn_Type, *PIRQn_Type; + + +typedef VOID (*HAL_VECTOR_FUN) (VOID); + +typedef enum _VECTOR_TABLE_TYPE_{ + DEDECATED_VECTRO_TABLE, + PERIPHERAL_VECTOR_TABLE +}VECTOR_TABLE_TYPE, *PVECTOR_TABLE_TYPE; + + +typedef void (*IRQ_FUN)(VOID *Data); + +typedef struct _IRQ_HANDLE_ { + IRQ_FUN IrqFun; + IRQn_Type IrqNum; + u32 Data; + u32 Priority; +}IRQ_HANDLE, *PIRQ_HANDLE; + + +#endif //_HAL_IRQN_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_log_uart.h b/USDK/component/soc/realtek/8195a/fwlib/hal_log_uart.h new file mode 100644 index 0000000..63e770b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_log_uart.h @@ -0,0 +1,151 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_LOG_UART_H_ +#define _HAL_LOG_UART_H_ + +#include "hal_diag.h" + +#define LOG_UART_WAIT_FOREVER 0xffffffff + +// Define Line Control Register Bits +typedef enum { + LCR_DLS_5B = 0, // Data Length: 5 bits + LCR_DLS_6B = BIT(0), // Data Length: 6 bits + LCR_DLS_7B = BIT(1), // Data Length: 7 bits + LCR_DLS_8B = (BIT(1)|BIT(0)), // Data Length: 7 bits + + LCR_STOP_1B = 0, // Number of stop bits: 1 + LCR_STOP_2B = BIT(2), // Number of stop bits: 1.5(data len=5) or 2 + + LCR_PARITY_NONE = 0, // Parity Enable: 0 + LCR_PARITY_ODD = BIT(3), // Parity Enable: 1, Even Parity: 0 + LCR_PARITY_EVEN = (BIT(4)|BIT(3)), // Parity Enable: 1, Even Parity: 1 + + LCR_BC = BIT(6), // Break Control Bit + LCR_DLAB = BIT(7) // Divisor Latch Access Bit +} LOG_UART_LINE_CTRL; + +// define Log UART Interrupt Indication ID +/* +IIR[3:0]: +0000 = modem status +0001 = no interrupt pending +0010 = THR empty +0100 = received data available +0110 = receiver line status +0111 = busy detect +1100 = character timeout +*/ +typedef enum { + IIR_MODEM_STATUS = 0, // Clear to send or data set ready or ring indicator or data carrier detect. + IIR_NO_PENDING = 1, + IIR_THR_EMPTY = 2, // TX FIFO level lower than threshold or FIFO empty + IIR_RX_RDY = 4, // RX data ready + IIR_RX_LINE_STATUS = 6, // Overrun/parity/framing errors or break interrupt + IIR_BUSY = 7, + IIR_CHAR_TIMEOUT = 12 // timeout: Rx dara ready but no read +} LOG_UART_INT_ID; + +// Define Interrupt Enable Bit +typedef enum { + IER_ERBFI = BIT(0), // Enable Received Data Available Interrupt + IER_ETBEI = BIT(1), // Enable Transmit Holding Register Empty Interrupt + IER_ELSI = BIT(2), // Enable Receiver Line Status Interrupt + IER_EDSSI = BIT(3), // Enable Modem Status Interrupt + IER_PTIME = BIT(7) // Programmable THRE Interrupt Mode Enable +} LOG_UART_INT_EN; + +// Define Line Status Bit +typedef enum { + LSR_DR = BIT(0), // Data Ready bit + LSR_OE = BIT(1), // Overrun error bit + LSR_PE = BIT(2), // Parity Error bit + LSR_FE = BIT(3), // Framing Error bit + LSR_BI = BIT(4), // Break Interrupt bit + LSR_THRE = BIT(5), // Transmit Holding Register Empty bit(IER_PTIME=0) + LSR_FIFOF = BIT(5), // Transmit FIFO Full bit(IER_PTIME=1) + LSR_TEMT = BIT(6), // Transmitter Empty bit + LSR_RFE = BIT(7) // Receiver FIFO Error bit +} LOG_UART_LINE_STATUS; + +enum { + LOG_UART_RST_TX_FIFO = 0x01, + LOG_UART_RST_RX_FIFO = 0x02 +}; + +#define LOG_UART_TX_FIFO_DEPTH 16 +#define LOG_UART_RX_FIFO_DEPTH 16 + +// Define FIFO Control Register Bits +typedef enum { + FCR_FIFO_EN = BIT(0), // FIFO Enable. + FCR_RST_RX = BIT(1), // RCVR FIFO Reset, self clear + FCR_RST_TX = BIT(2), // XMIT FIFO Reset, self clear + FCR_TX_TRIG_EMP = 0, // TX Empty Trigger: FIFO empty + FCR_TX_TRIG_2CH = BIT(4), // TX Empty Trigger: 2 characters in the FIFO + FCR_TX_TRIG_QF = BIT(5), // TX Empty Trigger: FIFO 1/4 full + FCR_TX_TRIG_HF = (BIT(5)|BIT(4)), // TX Empty Trigger: FIFO 1/2 full + FCR_TX_TRIG_MASK = (BIT(5)|BIT(4)), // TX Empty Trigger Bit Mask + FCR_RX_TRIG_1CH = 0, // RCVR Trigger: 1 character in the FIFO + FCR_RX_TRIG_QF = BIT(6), // RCVR Trigger: FIFO 1/4 full + FCR_RX_TRIG_HF = BIT(7), // RCVR Trigger: FIFO 1/2 full + FCR_RX_TRIG_AF = (BIT(7)|BIT(6)), // RCVR Trigger: FIFO 2 less than full + FCR_RX_TRIG_MASK = (BIT(7)|BIT(6)) // RCVR Trigger bits Mask +} LOG_UART_FIFO_CTRL; + +typedef struct _HAL_LOG_UART_ADAPTER_ { + u32 BaudRate; //00 + u32 FIFOControl; //+04 + u32 IntEnReg; //+08 + u8 Parity; //+0c + u8 Stop; //+0d + u8 DataLength; //+0e + + u8 LineStatus; //+0f + volatile u32 TxCount; //+10 how many byte to TX + volatile u32 RxCount; //+14 how many bytes to RX + volatile u8 *pTxBuf; //+18 + volatile u8 *pRxBuf; //+1c + u8 *pTxStartAddr; //+20 + u8 *pRxStartAddr; //+24 + + IRQ_HANDLE IrqHandle; //+28 + VOID (*LineStatusCallback)(VOID *para, u8 status); //+38 User Line Status interrupt callback + VOID (*TxCompCallback)(VOID *para); //+3c User Tx complete callback + VOID (*RxCompCallback)(VOID *para); //+40 User Rx complete callback + VOID *LineStatusCbPara; //+44 the argument for LineStatusCallback + VOID *TxCompCbPara; //+48 the argument for TxCompCallback + VOID *RxCompCbPara; //+4c the argument for RxCompCallback + + void (*api_irq_handler)(u32 id, LOG_UART_INT_ID event); //+0x50 + u32 api_irq_id; //+0x54 +}HAL_LOG_UART_ADAPTER, *PHAL_LOG_UART_ADAPTER; + +VOID HalLogUartIrqHandle(VOID * Data); +VOID HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartSetIntEn(HAL_LOG_UART_ADAPTER *pUartAdapter); +u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter); +u32 HalLogUartRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pRxData, u32 Length, u32 TimeoutMS); +u32 HalLogUartSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length, u32 TimeoutMS); +HAL_Status HalLogUartIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length); +HAL_Status HalLogUartIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pRxData, u32 Length); +VOID HalLogUartAbortIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartAbortIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter); +HAL_Status HalLogUartRstFIFO(HAL_LOG_UART_ADAPTER *pUartAdapter, u8 RstCtrl); +VOID HalLogUartEnable(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartDisable(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartWaitTxFifoEmpty(VOID); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_mii.h b/USDK/component/soc/realtek/8195a/fwlib/hal_mii.h new file mode 100644 index 0000000..b2b5f66 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_mii.h @@ -0,0 +1,191 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_MII_H_ +#define _HAL_MII_H_ + +#include "rtl8195a_mii.h" + + +/** + * LOG Configurations + */ + +#define NOLOG + +#define LOG_TAG "NoTag" +#define LOG_INFO_HEADER "I" +#define LOG_DEBUG_HEADER "D" +#define LOG_ERROR_HEADER "E" +#define LOG_TEST_HEADER "T" + +#define IDENT_TWO_SPACE " " +#define IDENT_FOUR_SPACE " " + +#define LOG_INFO(...) do {\ + DiagPrintf("\r"LOG_INFO_HEADER"/"LOG_TAG": " __VA_ARGS__);\ +}while(0) + +#define LOG_DEBUG(...) do {\ + DiagPrintf("\r"LOG_DEBUG_HEADER"/"LOG_TAG": " __VA_ARGS__);\ +}while(0) + +#define LOG_ERROR(...) do {\ + DiagPrintf("\r"LOG_ERROR_HEADER"/"LOG_TAG": " __VA_ARGS__);\ +}while(0) + +#ifdef NOLOG + #define LOGI + #define LOGD + #define LOGE + #define LOGI2 + #define LOGD2 + #define LOGE2 + #define LOGI4 + #define LOGD4 + #define LOGE4 +#else + #define LOGI LOG_INFO + #define LOGD LOG_DEBUG + #define LOGE LOG_ERROR + #define LOGI2(...) LOG_INFO(IDENT_TWO_SPACE __VA_ARGS__) + #define LOGD2(...) LOG_DEBUG(IDENT_TWO_SPACE __VA_ARGS__) + #define LOGE2(...) LOG_ERROR(IDENT_TWO_SPACE __VA_ARGS__) + #define LOGI4(...) LOG_INFO(IDENT_FOUR_SPACE __VA_ARGS__) + #define LOGD4(...) LOG_DEBUG(IDENT_FOUR_SPACE __VA_ARGS__) + #define LOGE4(...) LOG_ERROR(IDENT_FOUR_SPACE __VA_ARGS__) +#endif + +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#define DBG_ENTRANCE LOGI(ANSI_COLOR_GREEN "=> %s() <%s>\n" ANSI_COLOR_RESET, \ + __func__, __FILE__) + + +// GMAC MII Configurations +#ifdef LOG_TAG +#undef LOG_TAG +#define LOG_TAG "MII" +#endif + + +typedef enum { + ETH_TXDONE, + ETH_RXDONE, + ETH_LINKUP, + ETH_LINKDOWN +}EthernetEventType; + +typedef struct _HAL_ETHER_ADAPTER_{ + IRQ_HANDLE IrqHandle; + u32 InterruptMask; + u8 tx_desc_num; + u8 rx_desc_num; + volatile u8 *TxDescAddr; + volatile u8 *RxDescAddr; + volatile u8 *pTxPktBuf; + volatile u8 *pRxPktBuf; + VOID (*CallBack)(u32 Event, u32 Data); +}HAL_ETHER_ADAPTER, *PHAL_ETHER_ADAPTER; + + + +extern s32 +HalMiiInit( + IN VOID +); + +extern VOID +HalMiiDeInit( + IN VOID +); + +extern s32 +HalMiiWriteData( + IN const char *Data, + IN u32 Size +); + +extern u32 +HalMiiSendPacket( + IN VOID +); + +extern u32 +HalMiiReceivePacket( + IN VOID +); + +extern u32 +HalMiiReadData( + IN u8 *Data, + IN u32 Size +); + +extern VOID +HalMiiGetMacAddress( + IN u8 *Addr +); + +extern u32 +HalMiiGetLinkStatus( + IN VOID +); + +extern VOID +HalMiiForceLink( + IN s32 Speed, + IN s32 Duplex +); + + +#ifdef CONFIG_MII_VERIFY + +typedef struct _HAL_MII_ADAPTER_ { + u32 InterruptMask; + PPHY_MODE_INFO pPhyModeInfo; +}HAL_MII_ADAPTER, *PHAL_MII_ADAPTER; + +typedef struct _HAL_MII_OP_ { + BOOL (*HalMiiGmacInit)(VOID *Data); + BOOL (*HalMiiGmacReset)(VOID *Data); + BOOL (*HalMiiGmacEnablePhyMode)(VOID *Data); + u32 (*HalMiiGmacXmit)(VOID *Data); + VOID (*HalMiiGmacCleanTxRing)(VOID *Data); + VOID (*HalMiiGmacFillTxInfo)(VOID *Data); + VOID (*HalMiiGmacFillRxInfo)(VOID *Data); + VOID (*HalMiiGmacTx)(VOID *Data); + VOID (*HalMiiGmacRx)(VOID *Data); + VOID (*HalMiiGmacSetDefaultEthIoCmd)(VOID *Data); + VOID (*HalMiiGmacInitIrq)(VOID *Data); + u32 (*HalMiiGmacGetInterruptStatus)(VOID); + VOID (*HalMiiGmacClearInterruptStatus)(u32 IsrStatus); +}HAL_MII_OP, *PHAL_MII_OP; + +VOID HalMiiOpInit(IN VOID *Data); + +typedef struct _MII_ADAPTER_ { + PHAL_MII_OP pHalMiiOp; + PHAL_MII_ADAPTER pHalMiiAdapter; + PTX_INFO pTx_Info; + PRX_INFO pRx_Info; + VOID* TxBuffer; + VOID* RxBuffer; +}MII_ADAPTER, *PMII_ADAPTER; + +#endif // #ifdef CONFIG_MII_VERIFY + +#endif // #ifndef _HAL_MII_H_ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_misc.h b/USDK/component/soc/realtek/8195a/fwlib/hal_misc.h new file mode 100644 index 0000000..040cd5d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_misc.h @@ -0,0 +1,56 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _MISC_H_ +#define _MISC_H_ + +#include + +#define CHIP_ID_8711AM 0xFF +#define CHIP_ID_8195AM 0xFE +#define CHIP_ID_8711AF 0xFD +#define CHIP_ID_8710AF 0xFC +#define CHIP_ID_8711AN 0xFB +#define CHIP_ID_8710AM 0xFA + +enum _HAL_RESET_REASON{ + REASON_DEFAULT_RST = 0, /**< normal startup by power on */ + REASON_WDT_RST, /**< hardware watch dog reset */ + REASON_EXCEPTION_RST, /**< exception reset, GPIO status won't change */ + REASON_SOFT_WDT_RST, /**< software watch dog reset, GPIO status won't change */ + REASON_SOFT_RESTART, /**< software restart ,system_restart , GPIO status won't change */ + REASON_DEEP_SLEEP_AWAKE, /**< wake up from deep-sleep */ + REASON_EXT_SYS_RST /**< external system reset */ +}; +typedef u32 HAL_RESET_REASON; + +#ifdef CONFIG_TIMER_MODULE +extern _LONG_CALL_ unsigned int HalDelayUs(unsigned int us); +#endif + +extern _LONG_CALL_ unsigned int HalGetCpuClk(VOID); +extern _LONG_CALL_ unsigned char HalGetRomInfo(VOID); +extern u8 HalGetChipId(void); + +extern _LONG_CALL_ROM_ void *_memset( void *s, int c, SIZE_T n ); +extern _LONG_CALL_ROM_ void *_memcpy( void *s1, const void *s2, SIZE_T n ); +#if defined(CONFIG_RELEASE_BUILD_LIBRARIES) && (!defined(E_CUT_ROM_DOMAIN)) +// we built A/B/C cut ROM Lib with this wrong declaration, we need to keep the same for compatible +extern _LONG_CALL_ROM_ int *_memcmp( const void *av, const void *bv, SIZE_T len ); +#else +extern _LONG_CALL_ROM_ int _memcmp( const void *av, const void *bv, SIZE_T len ); +#endif +extern _LONG_CALL_ROM_ SIZE_T _strlen(const char *s); +extern _LONG_CALL_ROM_ int _strcmp(const char *cs, const char *ct); + +VOID HalSetResetCause(IN HAL_RESET_REASON reason); +HAL_RESET_REASON HalGetResetCause(VOID); + + +#endif //_MISC_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_nfc.h b/USDK/component/soc/realtek/8195a/fwlib/hal_nfc.h new file mode 100644 index 0000000..b73dada --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_nfc.h @@ -0,0 +1,22 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_NFC_H_ +#define _HAL_NFC_H_ + +#include "rtl8195a_nfc.h" + + +VOID HalNFCOpInit( + IN VOID *Data +); + + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_pcm.h b/USDK/component/soc/realtek/8195a/fwlib/hal_pcm.h new file mode 100644 index 0000000..fa34432 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_pcm.h @@ -0,0 +1,104 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_PCM_H_ +#define _HAL_PCM_H_ + +#include "rtl8195a_pcm.h" +/* +typedef struct _GDMA_CH_LLI_ELE_ { + u32 Sarx; + u32 Darx; + u32 Llpx; + u32 CtlxLow; + u32 CtlxUp; + u32 Temp; +}GDMA_CH_LLI_ELE, *PGDMA_CH_LLI_ELE; +#if 1 +#if 0 +typedef struct _GDMA_CH_LLI_ { + PGDMA_CH_LLI_ELE pLliEle; + PGDMA_CH_LLI pNextLli; +}GDMA_CH_LLI, *PGDMA_CH_LLI; + +typedef struct _BLOCK_SIZE_LIST_ { + u32 BlockSize; + PBLOCK_SIZE_LIST pNextBlockSiz; +}BLOCK_SIZE_LIST, *PBLOCK_SIZE_LIST; +#else +struct GDMA_CH_LLI { + PGDMA_CH_LLI_ELE pLliEle; + struct GDMA_CH_LLI *pNextLli; +}; + +struct BLOCK_SIZE_LIST { + u32 BlockSize; + struct BLOCK_SIZE_LIST *pNextBlockSiz; +}; + +#endif + +#endif +typedef struct _HAL_GDMA_ADAPTER_ { + u32 ChSar; + u32 ChDar; + GDMA_CHANNEL_NUM ChEn; + GDMA_CTL_REG GdmaCtl; + GDMA_CFG_REG GdmaCfg; + u32 PacketLen; + u32 BlockLen; + u32 MuliBlockCunt; + u32 MaxMuliBlock; + struct GDMA_CH_LLI *pLlix; + struct BLOCK_SIZE_LIST *pBlockSizeList; + + PGDMA_CH_LLI_ELE pLli; + u32 NextPlli; + u8 TestItem; + u8 ChNum; + u8 GdmaIndex; + u8 IsrCtrl:1; + u8 GdmaOnOff:1; + u8 Llpctrl:1; + u8 Lli0:1; + u8 Rsvd4to7:4; + u8 GdmaIsrType; +}HAL_GDMA_ADAPTER, *PHAL_GDMA_ADAPTER; + +*/ + +typedef struct _HAL_PCM_ADAPTER_ { + u32 Enable:1; + PCM_CTL_REG PcmCtl; + PCM_CHCNR03_REG PcmChCNR03; + PCM_TSR03_REG PcmTSR03; + PCM_BSIZE03_REG PcmBSize03; + u32 abc; + u8 PcmIndex; + u8 PcmCh; +}HAL_PCM_ADAPTER, *PHAL_PCM_ADAPTER; + + +typedef struct _HAL_PCM_OP_ { + VOID (*HalPcmOnOff)(VOID *Data); + BOOL (*HalPcmInit)(VOID *Data); + BOOL (*HalPcmSetting)(VOID *Data); + BOOL (*HalPcmEn)(VOID *Data); + BOOL (*HalPcmIsrEnAndDis) (VOID *Data); + BOOL (*HalPcmDumpReg)(VOID *Data); + BOOL (*HalPcm)(VOID *Data); +}HAL_PCM_OP, *PHAL_PCM_OP; + + +VOID HalPcmOpInit( + IN VOID *Data +); + + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_peri_on.h b/USDK/component/soc/realtek/8195a/fwlib/hal_peri_on.h new file mode 100644 index 0000000..abcbdd0 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_peri_on.h @@ -0,0 +1,451 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_PERI_ON_H_ +#define _HAL_PERI_ON_H_ + +#define MASK_ALLON 0xFFFFFFFF + +#define HAL_PERI_ON_READ32(addr) HAL_READ32(PERI_ON_BASE, addr) +#define HAL_PERI_ON_WRITE32(addr, value) HAL_WRITE32(PERI_ON_BASE, addr, value) +#define HAL_PERI_ON_READ16(addr) HAL_READ16(PERI_ON_BASE, addr) +#define HAL_PERI_ON_WRITE16(addr, value) HAL_WRITE16(PERI_ON_BASE, addr, value) +#define HAL_PERI_ON_READ8(addr) HAL_READ8(PERI_ON_BASE, addr) +#define HAL_PERI_ON_WRITE8(addr, value) HAL_WRITE8(PERI_ON_BASE, addr, value) +#define HAL_PERL_ON_FUNC_CTRL(addr,value,ctrl) \ + HAL_PERI_ON_WRITE32(addr, ((HAL_PERI_ON_READ32(addr) & (~value))|((MASK_ALLON - ctrl + 1) & value))) +#define HAL_PERL_ON_PIN_SEL(addr,mask,value) \ + HAL_PERI_ON_WRITE32(addr, ((HAL_PERI_ON_READ32(addr) & (~mask)) | value)) + +//40 REG_SYS_REGU_CTRL0 +#define LDO25M_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SYS_REGU_CTRL0, BIT_SYS_REGU_LDO25M_EN, ctrl) + +//A0 SYS_DEBUG_CTRL +#define DEBUG_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SYS_DEBUG_CTRL, BIT_SYS_DBG_PIN_EN, ctrl) + +//A4 SYS_PINMUX_CTRL +#define SIC_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SYS_PINMUX_CTRL, BIT_SIC_PIN_EN, ctrl) +#define EEPROM_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SYS_PINMUX_CTRL, BIT_EEPROM_PIN_EN, ctrl) + + +//210 SOV_FUNC_EN +#define LXBUS_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_LXBUS_EN, ctrl) +#define FLASH_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SPI_FLASH_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_FLASH_EN, ctrl);} + +#define MEM_CTRL_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SDR_SDRAM_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_MEM_CTRL_EN, ctrl);} + +#define LOC_UART_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(LOG_UART_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_LOG_UART_EN, ctrl);} + +#define GDMA0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(GDMA0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_GDMA0_EN, ctrl);} + +#define GDMA1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(GDMA1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_GDMA1_EN, ctrl);} + +#define GTIMER_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(TIMER_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_GTIMER_EN, ctrl);} + +#define SECURITY_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(CRYPTO_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_FUNC_EN, BIT_SOC_SECURITY_ENGINE_EN, ctrl);} + +//214 SOC_HCI_COM_FUNC_EN +#define SDIOD_ON_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SDIO_DEVICE_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_SDIOD_ON_EN, ctrl);} + +#define SDIOD_OFF_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SDIO_DEVICE_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_SDIOD_OFF_EN, ctrl);} + +#define SDIOH_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SDIO_HOST_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_SDIOH_EN, ctrl);} + +#define SDIO_ON_RST_MASK(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_SDIOD_ON_RST_MUX, ctrl) +#define OTG_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(USB_OTG_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_OTG_EN, ctrl);} + +#define OTG_RST_MASK(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_OTG_RST_MUX, ctrl) +#define MII_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(MII_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_MII_EN, ctrl);} + +#define MII_MUX_SEL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_SM_SEL, ctrl) +#define WL_MACON_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(WIFI_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_HCI_COM_FUNC_EN, BIT_SOC_HCI_WL_MACON_EN, ctrl);} + +//218 SOC_PERI_FUNC0_EN +#define UART0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_UART0_EN, ctrl);} + +#define UART1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_UART1_EN, ctrl);} + +#define UART2_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART2_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_UART2_EN, ctrl);} + +#define SPI0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SPI0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_SPI0_EN, ctrl);} + +#define SPI1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SPI1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_SPI1_EN, ctrl);} + +#define SPI2_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(SPI2_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_SPI2_EN, ctrl);} + +#define I2C0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2C0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2C0_EN, ctrl);} + +#define I2C1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2C1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2C1_EN, ctrl);} + +#define I2C2_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2C2_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2C2_EN, ctrl);} + +#define I2C3_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2C3_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2C3_EN, ctrl);} + +#define I2S0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2S0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2S0_EN, ctrl);} + +#define I2S1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(I2S1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_I2S1_EN, ctrl);} + +#define PCM0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(PCM0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_PCM0_EN, ctrl);} + +#define PCM1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(PCM1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC0_EN, BIT_PERI_PCM1_EN, ctrl);} + +//21C SOC_PERI_FUNC1_EN +#define ADC0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(ADC_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC1_EN, BIT_PERI_ADC0_EN, ctrl);} + +#define DAC0_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(DAC_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC1_EN, BIT_PERI_DAC0_EN, ctrl);} + +#define DAC1_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(DAC_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC1_EN, BIT_PERI_DAC1_EN, ctrl);} + +#define GPIO_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(GPIO_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_FUNC1_EN, BIT_PERI_GPIO_EN, ctrl);} + +//220 SOC_PERI_BD_FUNC0_EN +#define UART0_BD_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART0_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_BD_FUNC0_EN, BIT_PERI_UART0_BD_EN, ctrl);} + +#define UART1_BD_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART1_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_BD_FUNC0_EN, BIT_PERI_UART1_BD_EN, ctrl);} + +#define UART2_BD_FCTRL(ctrl) { \ + if (!ctrl) { \ + HAL_READ32(UART2_REG_BASE,0);\ + }\ + HAL_PERL_ON_FUNC_CTRL(REG_SOC_PERI_BD_FUNC0_EN, BIT_PERI_UART2_BD_EN, ctrl);} + +//230 PESOC_CLK_CTRL +#define ACTCK_CPU_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_CKE_PLFM, ctrl) +#define ACTCK_TRACE_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_TRACE_EN, ctrl) +#define SLPCK_TRACE_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_TRACE_EN, ctrl) +#define ACTCK_VENDOR_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_VENDOR_REG_EN, ctrl) +#define SLPCK_VENDOR_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_VENDOR_REG_EN, ctrl) +#define ACTCK_FLASH_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_FLASH_EN, ctrl) +#define SLPCK_FLASH_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_FLASH_EN, ctrl) +#define ACTCK_SDR_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_SDR_EN, ctrl) +#define SLPCK_SDR_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_SDR_EN, ctrl) +#define ACTCK_LOG_UART_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_LOG_UART_EN, ctrl) +#define SLPCK_LOG_UART_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_LOG_UART_EN, ctrl) +#define ACTCK_TIMER_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_TIMER_EN, ctrl) +#define SLPCK_TIMER_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_TIMER_EN, ctrl) +#define ACTCK_GDMA0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_GDMA0_EN, ctrl) +#define SLPCK_GDMA0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_GDMA0_EN, ctrl) +#define ACTCK_GDMA1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_GDMA1_EN, ctrl) +#define SLPCK_GDMA1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_GDMA1_EN, ctrl) +#define ACTCK_GPIO_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_GPIO_EN, ctrl) +#define SLPCK_GPIO_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_GPIO_EN, ctrl) +#define ACTCK_BTCMD_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_ACTCK_BTCMD_EN, ctrl) +#define SLPCK_BTCMD_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_CLK_CTRL, BIT_SOC_SLPCK_BTCMD_EN, ctrl) + +//234 PESOC_PERI_CLK_CTRL0 +#define ACTCK_UART0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_UART0_EN, ctrl) +#define SLPCK_UART0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_UART0_EN, ctrl) +#define ACTCK_UART1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_UART1_EN, ctrl) +#define SLPCK_UART1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_UART1_EN, ctrl) +#define ACTCK_UART2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_UART2_EN, ctrl) +#define SLPCK_UART2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_UART2_EN, ctrl) +#define ACTCK_SPI0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_SPI0_EN, ctrl) +#define SLPCK_SPI0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_SPI0_EN, ctrl) +#define ACTCK_SPI1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_SPI1_EN, ctrl) +#define SLPCK_SPI1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_SPI1_EN, ctrl) +#define ACTCK_SPI2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_ACTCK_SPI2_EN, ctrl) +#define SLPCK_SPI2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL0, BIT_SOC_SLPCK_SPI2_EN, ctrl) + +//238 PESOC_PERI_CLK_CTRL1 +#define ACTCK_I2C0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_I2C0_EN, ctrl) +#define SLPCK_I2C0_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_I2C0_EN, ctrl) +#define ACTCK_I2C1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_I2C1_EN, ctrl) +#define SLPCK_I2C1_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_I2C1_EN, ctrl) +#define ACTCK_I2C2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_I2C2_EN, ctrl) +#define SLPCK_I2C2_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_I2C2_EN, ctrl) +#define ACTCK_I2C3_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_I2C3_EN, ctrl) +#define SLPCK_I2C3_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_I2C3_EN, ctrl) +#define ACTCK_I2S_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_I2S_EN, ctrl) +#define SLPCK_I2S_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_I2S_EN, ctrl) +#define ACTCK_PCM_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_PCM_EN, ctrl) +#define SLPCK_PCM_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_PCM_EN, ctrl) +#define ACTCK_ADC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_ADC_EN, ctrl) +#define SLPCK_ADC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_ADC_EN, ctrl) +#define ACTCK_DAC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_ACTCK_DAC_EN, ctrl) +#define SLPCK_DAC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CLK_CTRL1, BIT_SOC_SLPCK_DAC_EN, ctrl) + +//240 PESOC_HCI_CLK_CTRL0 +#define ACTCK_SDIOD_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_ACTCK_SDIO_DEV_EN, ctrl) +#define SLPCK_SDIOD_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_SLPCK_SDIO_DEV_EN, ctrl) +#define ACTCK_SDIOH_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_ACTCK_SDIO_HST_EN, ctrl) +#define SLPCK_SDIOH_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_SLPCK_SDIO_HST_EN, ctrl) +#define ACTCK_OTG_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_ACTCK_OTG_EN, ctrl) +#define SLPCK_OTG_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_SLPCK_OTG_EN, ctrl) +#define ACTCK_MII_MPHY_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_ACTCK_MII_MPHY_EN, ctrl) +#define SLPCK_MII_MPHY_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_HCI_CLK_CTRL0, BIT_SOC_SLPCK_MII_MPHY_EN, ctrl) + +//244 PESOC_COM_CLK_CTRL1 +#define ACTCK_WL_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_ACTCK_WL_EN, ctrl) +#define SLPCK_WL_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_SLPCK_WL_EN, ctrl) +#define ACTCK_SEC_ENG_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_ACTCK_SECURITY_ENG_EN, ctrl) +#define SLPCK_SEC_ENG_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_SLPCK_SECURITY_ENG_EN, ctrl) +#define ACTCK_NFC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_ACTCK_NFC_EN, ctrl) +#define SLPCK_NFC_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_SLPCK_NFC_EN, ctrl) +#define NFC_CAL_CCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_COM_CLK_CTRL1, BIT_SOC_NFC_CAL_EN, ctrl) + +//250 REG_PERI_CLK_SEL +#define TRACE_CLK_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_CLK_SEL, (BIT_MASK_PESOC_TRACE_CK_SEL << BIT_SHIFT_PESOC_TRACE_CK_SEL), BIT_PESOC_TRACE_CK_SEL(num)) +#define FLASH_CLK_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_CLK_SEL, (BIT_MASK_PESOC_FLASH_CK_SEL << BIT_SHIFT_PESOC_FLASH_CK_SEL), BIT_PESOC_FLASH_CK_SEL(num)) +#define SDR_CLK_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_CLK_SEL, (BIT_MASK_PESOC_SDR_CK_SEL << BIT_SHIFT_PESOC_SDR_CK_SEL), BIT_PESOC_SDR_CK_SEL(num)) +#define I2C_SCLK_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_CLK_SEL, (BIT_MASK_PESOC_PERI_SCLK_SEL << BIT_SHIFT_PESOC_PERI_SCLK_SEL), BIT_PESOC_PERI_SCLK_SEL(num)) + +//270 REG_OSC32K_CTRL +#define OSC32K_CKGEN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_OSC32K_CTRL, BIT_32K_POW_CKGEN_EN, ctrl) + +//280 REG_UART_MUX_CTRL +#define UART0_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_UART_MUX_CTRL, BIT_UART0_PIN_EN, ctrl) +#define UART0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_UART_MUX_CTRL, (BIT_MASK_UART0_PIN_SEL << BIT_SHIFT_UART0_PIN_SEL), BIT_UART0_PIN_SEL(num)) +#define UART1_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_UART_MUX_CTRL, BIT_UART1_PIN_EN, ctrl) +#define UART1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_UART_MUX_CTRL, (BIT_MASK_UART1_PIN_SEL << BIT_SHIFT_UART1_PIN_SEL), BIT_UART1_PIN_SEL(num)) +#define UART2_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_UART_MUX_CTRL, BIT_UART2_PIN_EN, ctrl) +#define UART2_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_UART_MUX_CTRL, (BIT_MASK_UART2_PIN_SEL << BIT_SHIFT_UART2_PIN_SEL), BIT_UART2_PIN_SEL(num)) + +//284 REG_SPI_MUX_CTRL +#define SPI0_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SPI_MUX_CTRL, BIT_SPI0_PIN_EN, ctrl) +#define SPI0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_SPI_MUX_CTRL, (BIT_MASK_SPI0_PIN_SEL << BIT_SHIFT_SPI0_PIN_SEL), BIT_SPI0_PIN_SEL(num)) +#define SPI1_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SPI_MUX_CTRL, BIT_SPI1_PIN_EN, ctrl) +#define SPI1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_SPI_MUX_CTRL, (BIT_MASK_SPI1_PIN_SEL << BIT_SHIFT_SPI1_PIN_SEL), BIT_SPI1_PIN_SEL(num)) +#define SPI2_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SPI_MUX_CTRL, BIT_SPI2_PIN_EN, ctrl) +#define SPI2_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_SPI_MUX_CTRL, (BIT_MASK_SPI2_PIN_SEL << BIT_SHIFT_SPI2_PIN_SEL), BIT_SPI2_PIN_SEL(num)) +#define SPI0_MULTI_CS_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_SPI_MUX_CTRL, BIT_SPI0_MULTI_CS_EN, ctrl) + +//288 REG_I2C_MUX_CTRL +#define I2C0_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2C_MUX_CTRL, BIT_I2C0_PIN_EN, ctrl) +#define I2C0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2C_MUX_CTRL, (BIT_MASK_I2C0_PIN_SEL << BIT_SHIFT_I2C0_PIN_SEL), BIT_I2C0_PIN_SEL(num)) +#define I2C1_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2C_MUX_CTRL, BIT_I2C1_PIN_EN, ctrl) +#define I2C1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2C_MUX_CTRL, (BIT_MASK_I2C1_PIN_SEL << BIT_SHIFT_I2C1_PIN_SEL), BIT_I2C1_PIN_SEL(num)) +#define I2C2_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2C_MUX_CTRL, BIT_I2C2_PIN_EN, ctrl) +#define I2C2_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2C_MUX_CTRL, (BIT_MASK_I2C2_PIN_SEL << BIT_SHIFT_I2C2_PIN_SEL), BIT_I2C2_PIN_SEL(num)) +#define I2C3_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2C_MUX_CTRL, BIT_I2C3_PIN_EN, ctrl) +#define I2C3_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2C_MUX_CTRL, (BIT_MASK_I2C3_PIN_SEL << BIT_SHIFT_I2C3_PIN_SEL), BIT_I2C3_PIN_SEL(num)) + +//28C REG_I2S_MUX_CTRL +#define I2S0_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_I2S0_PIN_EN, ctrl) +#define I2S0_MCK_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_I2S0_MCK_EN, ctrl) +#define I2S0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2S_MUX_CTRL, (BIT_MASK_I2S0_PIN_SEL << BIT_SHIFT_I2S0_PIN_SEL), BIT_I2S0_PIN_SEL(num)) +#define I2S1_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_I2S1_PIN_EN, ctrl) +#define I2S1_MCK_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_I2S1_MCK_EN, ctrl) +#define I2S1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2S_MUX_CTRL, (BIT_MASK_I2S1_PIN_SEL << BIT_SHIFT_I2S1_PIN_SEL), BIT_I2S1_PIN_SEL(num)) +#define PCM0_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_PCM0_PIN_EN, ctrl) +#define PCM0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2S_MUX_CTRL, (BIT_MASK_PCM0_PIN_SEL << BIT_SHIFT_PCM0_PIN_SEL), BIT_PCM0_PIN_SEL(num)) +#define PCM1_PIN_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_I2S_MUX_CTRL, BIT_PCM1_PIN_EN, ctrl) +#define PCM1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_I2S_MUX_CTRL, (BIT_MASK_PCM1_PIN_SEL << BIT_SHIFT_PCM1_PIN_SEL), BIT_PCM1_PIN_SEL(num)) + +//2A0 HCI_PINMUX_CTRL +#define SDIOD_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_HCI_PINMUX_CTRL, BIT_HCI_SDIOD_PIN_EN, ctrl) +#define SDIOH_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_HCI_PINMUX_CTRL, BIT_HCI_SDIOH_PIN_EN, ctrl) +#define MII_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_HCI_PINMUX_CTRL, BIT_HCI_MII_PIN_EN, ctrl) + +//2A4 WL_PINMUX_CTRL +#define LED_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_WL_LED_PIN_EN, ctrl) +#define LED_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_WL_PINMUX_CTRL, (BIT_MASK_WL_LED_PIN_SEL << BIT_SHIFT_WL_LED_PIN_SEL), BIT_WL_LED_PIN_SEL(num)) +#define ANT0_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_WL_ANT0_PIN_EN, ctrl) +#define ANT1_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_WL_ANT1_PIN_EN, ctrl) +#define BTCOEX_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_WL_BTCOEX_PIN_EN, ctrl) +#define BTCMD_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_WL_BTCMD_PIN_EN, ctrl) +#define NFC_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_WL_PINMUX_CTRL, BIT_NFC_PIN_EN, ctrl) + +//2AC PWM_PINMUX_CTRL +#define PWM0_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_PWM0_PIN_EN, ctrl) +#define PWM0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_PWM0_PIN_SEL << BIT_SHIFT_PWM0_PIN_SEL), BIT_PWM0_PIN_SEL(num)) +#define PWM1_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_PWM1_PIN_EN, ctrl) +#define PWM1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_PWM1_PIN_SEL << BIT_SHIFT_PWM1_PIN_SEL), BIT_PWM1_PIN_SEL(num)) +#define PWM2_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_PWM2_PIN_EN, ctrl) +#define PWM2_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_PWM2_PIN_SEL << BIT_SHIFT_PWM2_PIN_SEL), BIT_PWM2_PIN_SEL(num)) +#define PWM3_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_PWM3_PIN_EN, ctrl) +#define PWM3_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_PWM3_PIN_SEL << BIT_SHIFT_PWM3_PIN_SEL), BIT_PWM3_PIN_SEL(num)) +#define ETE0_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_ETE0_PIN_EN, ctrl) +#define ETE0_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_ETE0_PIN_SEL << BIT_SHIFT_ETE0_PIN_SEL), BIT_ETE0_PIN_SEL(num)) +#define ETE1_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_ETE1_PIN_EN, ctrl) +#define ETE1_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_ETE1_PIN_SEL << BIT_SHIFT_ETE1_PIN_SEL), BIT_ETE1_PIN_SEL(num)) +#define ETE2_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_ETE2_PIN_EN, ctrl) +#define ETE2_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_ETE2_PIN_SEL << BIT_SHIFT_ETE2_PIN_SEL), BIT_ETE2_PIN_SEL(num)) +#define ETE3_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PWM_PINMUX_CTRL, BIT_ETE3_PIN_EN, ctrl) +#define ETE3_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PWM_PINMUX_CTRL, (BIT_MASK_ETE3_PIN_SEL << BIT_SHIFT_ETE3_PIN_SEL), BIT_ETE3_PIN_SEL(num)) + +//2C0 CPU_PERIPHERAL_CTRL +#define SPI_FLASH_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_CPU_PERIPHERAL_CTRL, BIT_SPI_FLSH_PIN_EN, ctrl) +#define SPI_FLASH_PIN_SEL(num) HAL_PERL_ON_PIN_SEL(REG_CPU_PERIPHERAL_CTRL, (BIT_MASK_SPI_FLSH_PIN_SEL << BIT_SHIFT_SPI_FLSH_PIN_SEL), BIT_SPI_FLSH_PIN_SEL(num)) +#define SDR_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_CPU_PERIPHERAL_CTRL, BIT_SDR_PIN_EN, ctrl) +#define TRACE_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_CPU_PERIPHERAL_CTRL, BIT_TRACE_PIN_EN, ctrl) +#define LOG_UART_PIN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_CPU_PERIPHERAL_CTRL, BIT_LOG_UART_PIN_EN, ctrl) +#define LOG_UART_IR_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_CPU_PERIPHERAL_CTRL, BIT_LOG_UART_IR_EN, ctrl) + +//300 REG_PESOC_MEM_CTRL +#define SDR_DDL_FCTRL(ctrl) HAL_PERL_ON_PIN_SEL(REG_PESOC_MEM_CTRL, (BIT_MASK_PESOC_SDR_DDL_CTRL << BIT_SHIFT_PESOC_SDR_DDL_CTRL), BIT_PESOC_SDR_DDL_CTRL(ctrl)) +#define FLASH_DDL_FCTRL(ctrl) HAL_PERL_ON_PIN_SEL(REG_PESOC_MEM_CTRL, (BIT_MASK_PESOC_FLASH_DDL_CTRL << BIT_SHIFT_PESOC_FLASH_DDL_CTRL), BIT_PESOC_FLASH_DDL_CTRL(ctrl)) + +//304 REG_PESOC_SOC_CTRL +#define SRAM_MUX_CFG(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_SOC_CTRL, (BIT_MASK_PESOC_SRAM_MUX_CFG << BIT_SHIFT_PESOC_SRAM_MUX_CFG), BIT_PESOC_SRAM_MUX_CFG(num)) +#define LX_WL_SWAP_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_LX_WL_SWAP_SEL, ctrl) +#define LX_MST_SWAP_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_LX_MST_SWAP_SEL, ctrl) +#define LX_SLV_SWAP_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_LX_SLV_SWAP_SEL, ctrl) +#define MII_LX_WRAPPER_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_MII_LX_WRAPPER_EN, ctrl) +#define MII_LX_MST_SWAP_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_MII_LX_MST_SWAP_SEL, ctrl) +#define MII_LX_SLV_SWAP_CTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_SOC_CTRL, BIT_PESOC_MII_LX_SLV_SWAP_SEL, ctrl) +#define GDMA_CFG(num) HAL_PERL_ON_PIN_SEL(REG_PESOC_SOC_CTRL, (BIT_MASK_PESOC_GDMA_CFG << BIT_SHIFT_PESOC_GDMA_CFG), BIT_PESOC_GDMA_CFG(num)) + +//308 PESOC_PERI_CTRL +#define SPI_RN_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PESOC_PERI_CTRL, BIT_SOC_FUNC_SPI_RN, ctrl) + +//320 GPIO_SHTDN_CTRL +#define GPIO_GPA_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPA_SHTDN_N, ctrl) +#define GPIO_GPB_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPB_SHTDN_N, ctrl) +#define GPIO_GPC_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPC_SHTDN_N, ctrl) +#define GPIO_GPD_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPD_SHTDN_N, ctrl) +#define GPIO_GPE_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPE_SHTDN_N, ctrl) +#define GPIO_GPF_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPF_SHTDN_N, ctrl) +#define GPIO_GPG_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPG_SHTDN_N, ctrl) +#define GPIO_GPH_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPH_SHTDN_N, ctrl) +#define GPIO_GPI_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPI_SHTDN_N, ctrl) +#define GPIO_GPJ_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPJ_SHTDN_N, ctrl) +#define GPIO_GPK_SHTDN_N_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_GPIO_SHTDN_CTRL, BIT_GPIO_GPK_SHTDN_N, ctrl) + +//374 +#define EGTIM_FCTRL(ctrl) HAL_PERL_ON_FUNC_CTRL(REG_PERI_EGTIM_CTRL, BIT_PERI_EGTIM_EN, ctrl) +#define EGTIM_RSIG_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PERI_EGTIM_CTRL, (BIT_MASK_PERI_EGTIM_REF_SIG_SEL << BIT_SHIFT_PERI_EGTIM_REF_SIG_SEL), BIT_PERI_EGTIM_REF_SIG_SEL(num)) +#define EGTIME_PIN_G0_OPT_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PERI_EGTIM_CTRL, (BIT_MASK_PERI_EGTIM_PIN_GROUP0_OPT_SEL << BIT_SHIFT_PERI_EGTIM_PIN_GROUP0_OPT_SEL), BIT_PERI_EGTIM_PIN_GROUP0_OPT_SEL(num)) +#define EGTIME_PIN_G1_OPT_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PERI_EGTIM_CTRL, (BIT_MASK_PERI_EGTIM_PIN_GROUP1_OPT_SEL << BIT_SHIFT_PERI_EGTIM_PIN_GROUP1_OPT_SEL), BIT_PERI_EGTIM_PIN_GROUP1_OPT_SEL(num)) +#define EGTIME_PIN_G2_OPT_SEL(num) HAL_PERL_ON_PIN_SEL(REG_PERI_EGTIM_CTRL, (BIT_MASK_PERI_EGTIM_PIN_GROUP2_OPT_SEL << BIT_SHIFT_PERI_EGTIM_PIN_GROUP2_OPT_SEL), BIT_PERI_EGTIM_PIN_GROUP2_OPT_SEL(num)) + + +#endif //_HAL_PERI_ON_H_ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_pinmux.h b/USDK/component/soc/realtek/8195a/fwlib/hal_pinmux.h new file mode 100644 index 0000000..57ee284 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_pinmux.h @@ -0,0 +1,75 @@ +#ifndef _HAL_PINMUX_ +#define _HAL_PINMUX_ + + +//Function Index +#define UART0 0 +#define UART1 1 +#define UART2 2 +#define SPI0 8 +#define SPI1 9 +#define SPI2 10 +#define SPI0_MCS 15 +#define I2C0 16 +#define I2C1 17 +#define I2C2 18 +#define I2C3 19 +#define I2S0 24 +#define I2S1 25 +#define PCM0 28 +#define PCM1 29 +#define ADC0 32 +#define DAC0 36 +#define DAC1 37 +#define SDIOD 64 +#define SDIOH 65 +#define USBOTG 66 +#define MII 88 +#define WL_LED 96 +#define WL_ANT0 104 +#define WL_ANT1 105 +#define WL_BTCOEX 108 +#define WL_BTCMD 109 +#define NFC 112 +#define PWM0 160 +#define PWM1 161 +#define PWM2 162 +#define PWM3 163 +#define ETE0 164 +#define ETE1 165 +#define ETE2 166 +#define ETE3 167 +#define EGTIM 168 +#define SPI_FLASH 196 +#define SDR 200 +#define JTAG 216 +#define TRACE 217 +#define LOG_UART 220 +#define LOG_UART_IR 221 +#define SIC 224 +#define EEPROM 225 +#define DEBUG 226 + +//Location Index(Pin Mux Selection) +#define S0 0 +#define S1 1 +#define S2 2 +#define S3 3 + +_LONG_CALL_ u8 +HalPinCtrlRtl8195A( + IN u32 Function, + IN u32 PinLocation, + IN BOOL Operation); + +u8 GpioFunctionChk( + IN u32 chip_pin, + IN u8 Operation); + +u8 +FunctionChk( + IN u32 Function, + IN u32 PinLocation +); + +#endif //_HAL_PINMUX_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_platform.h b/USDK/component/soc/realtek/8195a/fwlib/hal_platform.h new file mode 100644 index 0000000..61b37a8 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_platform.h @@ -0,0 +1,102 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_PLATFORM_ +#define _HAL_PLATFORM_ + +#define ROMVERSION 0x03 +#define ROMINFORMATION (ROMVERSION) + +#define SYSTEM_CLK PLATFORM_CLOCK + +#define PERIPHERAL_IRQ_STATUS 0x04 +#define PERIPHERAL_IRQ_MODE 0x08 +#define PERIPHERAL_IRQ_EN 0x0C +#define LP_PERI_EXT_IRQ_STATUS 0x24 +#define LP_PERI_EXT_IRQ_MODE 0x28 +#define LP_PERI_EXT_IRQ_EN 0x2C + +#define PERIPHERAL_IRQ_ALL_LEVEL 0 + +#define TIMER_CLK 32*1000 + +#define SDR_SDRAM_BASE 0x30000000 +#define SYSTEM_CTRL_BASE 0x40000000 +#define PERI_ON_BASE 0x40000000 +#define SPI_FLASH_BASE 0x98000000 + +//3 Peripheral IP Base Address + +#define GPIO_REG_BASE 0x40001000 +#define TIMER_REG_BASE 0x40002000 +#define VENDOR_REG_BASE 0x40002800 +#define NFC_INTERFACE_BASE 0x40002400 +#define LOG_UART_REG_BASE 0x40003000 +#define I2C2_REG_BASE 0x40003400 +#define I2C3_REG_BASE 0x40003800 +#define SDR_CTRL_BASE 0x40005000 +#define SPI_FLASH_CTRL_BASE 0x40006000 +#define ADC_REG_BASE 0x40010000 +#define DAC_REG_BASE 0x40011000 +#define UART0_REG_BASE 0x40040000 +#define UART1_REG_BASE 0x40040400 +#define UART2_REG_BASE 0x40040800 +#define SPI0_REG_BASE 0x40042000 +#define SPI1_REG_BASE 0x40042400 +#define SPI2_REG_BASE 0x40042800 +#define I2C0_REG_BASE 0x40044000 +#define I2C1_REG_BASE 0x40044400 +#define SDIO_DEVICE_REG_BASE 0x40050000 +#define MII_REG_BASE 0x40050000 +#define SDIO_HOST_REG_BASE 0x40058000 +#define GDMA0_REG_BASE 0x40060000 +#define GDMA1_REG_BASE 0x40061000 +#define I2S0_REG_BASE 0x40062000 +#define I2S1_REG_BASE 0x40063000 +#define PCM0_REG_BASE 0x40064000 +#define PCM1_REG_BASE 0x40065000 +#define CRYPTO_REG_BASE 0x40070000 +#define WIFI_REG_BASE 0x40080000 +#define USB_OTG_REG_BASE 0x400C0000 + +#define GDMA1_REG_OFF 0x1000 +#define I2S1_REG_OFF 0x1000 +#define PCM1_REG_OFF 0x1000 +#define SSI_REG_OFF 0x400 +#define RUART_REG_OFF 0x400 + +#define CPU_CLK_TYPE_NO 6 + +enum _BOOT_TYPE_ { + BOOT_FROM_FLASH = 0, + BOOT_FROM_SDIO = 1, + BOOT_FROM_USB = 2, + BOOT_FROM_RSVD = 3, +}; + +enum _EFUSE_CPU_CLK_ { + #if 1 + CLK_200M = 0, + CLK_100M = 1, + CLK_50M = 2, + CLK_25M = 3, + CLK_12_5M = 4, + CLK_4M = 5, + #else + CLK_25M = 0, + CLK_200M = 1, + CLK_100M = 2, + CLK_50M = 3, + CLK_12_5M = 4, + CLK_4M = 5, + #endif +}; + + +#endif //_HAL_PLATFORM_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_pwm.h b/USDK/component/soc/realtek/8195a/fwlib/hal_pwm.h new file mode 100644 index 0000000..6876975 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_pwm.h @@ -0,0 +1,60 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_PWM_H_ +#define _HAL_PWM_H_ + +#include "basic_types.h" + +#define MAX_PWM_CTRL_PIN 4 +// the minimum tick time for G-timer is 61 us (clock source = 32768Hz, reload value=1 and reload takes extra 1T) +//#define GTIMER_TICK_US 31 // micro-second, 1000000/32768 ~= 30.5 +#define MIN_GTIMER_TIMEOUT 61 // in micro-sec, use this value to set the g-timer to generate tick for PWM. 61=(1000000/32768)*2 +#define PWM_GTIMER_TICK_TIME 61 // in micro-sec, use this value to set the g-timer to generate tick for PWM. 61=(1000000/32768)*2 + +typedef struct _HAL_PWM_ADAPTER_ { + u8 pwm_id; // the PWM ID, 0~3 + u8 sel; // PWM Pin selection, 0~3 + u8 gtimer_id; // using G-Timer ID, there are 7 G-timer, but we prefer to use timer 3~6 + u8 enable; // is enabled +// u32 timer_value; // the G-Timer auto-reload value, source clock is 32768Hz, reload will takes extra 1 tick. To set the time of a tick of PWM + u32 tick_time; // the tick time for the G-timer + u32 period; // the period of a PWM control cycle, in PWM tick + u32 pulsewidth; // the pulse width in a period of a PWM control cycle, in PWM tick. To control the ratio +// float duty_ratio; // the dyty ratio = pulswidth/period +}HAL_PWM_ADAPTER, *PHAL_PWM_ADAPTER; + + +extern HAL_Status +HAL_Pwm_Init( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 pwm_id, + u32 sel +); + +extern void +HAL_Pwm_Enable( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern void +HAL_Pwm_Disable( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern void +HAL_Pwm_SetDuty( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 period, + u32 pulse_width +); + + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_sdio.h b/USDK/component/soc/realtek/8195a/fwlib/hal_sdio.h new file mode 100644 index 0000000..86d607b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_sdio.h @@ -0,0 +1,273 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_SDIO_H_ +#define _HAL_SDIO_H_ + +#include "rtl8195a_sdio.h" + +#if SDIO_API_DEFINED +#include "spdio_api.h" +#endif + +#if !SDIO_BOOT_DRIVER +#include "mailbox.h" +#endif +#define PURE_SDIO_INIC 0 // is a pure SDIO iNIC device or a SDIO iNIC + peripheral device + +#if SDIO_BOOT_DRIVER +typedef struct _HAL_SDIO_ADAPTER_ { + u8 *pTXBDAddr; /* The TX_BD start address */ + PSDIO_TX_BD pTXBDAddrAligned; /* The TX_BD start address, it must be 4-bytes aligned */ + PSDIO_TX_BD_HANDLE pTXBDHdl; /* point to the allocated memory for TX_BD Handle array */ + u16 TXBDWPtr; /* The SDIO TX(Host->Device) BD local write index, different with HW maintained write Index. */ + u16 TXBDRPtr; /* The SDIO TX(Host->Device) BD read index */ + u16 TXBDRPtrReg; /* The SDIO TX(Host->Device) BD read index has been write to HW register */ + u16 reserve1; + + u8 *pRXBDAddr; /* The RX_BD start address */ + PSDIO_RX_BD pRXBDAddrAligned; /* The RX_BD start address, it must be 8-bytes aligned */ + PSDIO_RX_BD_HANDLE pRXBDHdl; /* point to the allocated memory for RX_BD Handle array */ + u16 RXBDWPtr; /* The SDIO RX(Device->Host) BD write index */ + u16 RXBDRPtr; /* The SDIO RX(Device->Host) BD local read index, different with HW maintained Read Index. */ + u16 IntMask; /* The Interrupt Mask */ + u16 IntStatus; /* The Interrupt Status */ + u32 Events; /* The Event to the SDIO Task */ + + u32 EventSema; /* Semaphore for SDIO events, use to wakeup the SDIO task */ + u8 CCPWM; /* the value write to register CCPWM, which will sync to Host HCPWM */ + u8 reserve2; + u16 CCPWM2; /* the value write to register CCPWM2, which will sync to Host HCPWM2 */ + + s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize); /* to hook the WLan driver TX callback function to handle a Packet TX */ + VOID *pTxCb_Adapter; /* a pointer will be used to call the TX Callback function, + which is from the TX CallBack function register */ + s8 (*pTxCallback_Backup)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize); // Use to back up the registered TX Callback function, for MP/Normal mode switch + VOID *pTxCb_Adapter_Backup; // Backup the pTxCb_Adapter, for MP/Normal mode switch + _LIST FreeTxPktList; /* The list to queue free Tx packets handler */ + _LIST RxPktList; /* The list to queue RX packets */ + _LIST FreeRxPktList; /* The list to queue free Rx packets handler */ + SDIO_TX_PACKET *pTxPktHandler; /* to store allocated TX Packet handler memory address */ + SDIO_RX_PACKET *pRxPktHandler; /* to store allocated RX Packet handler memory address */ + u32 RxInQCnt; /* The packet count for Rx In Queue */ + u32 MemAllocCnt; // Memory allocated count, for debug only + u32 MAllocFailedCnt; // MemAlloc Failed count, for debugging + +// VOID *pHalOp; /* point to HAL operation function table */ +} HAL_SDIO_ADAPTER, *PHAL_SDIO_ADAPTER; + +extern BOOL SDIO_Device_Init_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev +); +extern VOID SDIO_Device_DeInit_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev +); +extern VOID SDIO_Send_C2H_IOMsg_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 *C2HMsg +); +extern u8 SDIO_Send_C2H_PktMsg_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *C2HMsg, + IN u16 MsgLen +); +extern VOID SDIO_Register_Tx_Callback_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize), + IN VOID *pAdapter +); +extern s8 SDIO_Rx_Callback_Rom( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN VOID *pData, + IN u16 Offset, + IN u16 Length, + IN u8 CmdType +); + +#else // else of "#if SDIO_BOOT_DRIVER" +typedef struct _HAL_SDIO_ADAPTER_ { +// u8 *pTxBuff; /* point to the SDIO TX Buffer */ +// u8 *pTxBuffAligned; /* point to the SDIO TX Buffer with 4-bytes aligned */ +// u32 TXFifoRPtr; /* The SDIO TX(Host->Device) FIFO buffer read pointer */ +#if SDIO_API_DEFINED + VOID *spdio_priv; /*Data from User*/ +#endif + u8 *pTXBDAddr; /* The TX_BD start address */ + PSDIO_TX_BD pTXBDAddrAligned; /* The TX_BD start address, it must be 4-bytes aligned */ + PSDIO_TX_BD_HANDLE pTXBDHdl; /* point to the allocated memory for TX_BD Handle array */ + u16 TXBDWPtr; /* The SDIO TX(Host->Device) BD local write index, different with HW maintained write Index. */ + u16 TXBDRPtr; /* The SDIO TX(Host->Device) BD read index */ + u16 TXBDRPtrReg; /* The SDIO TX(Host->Device) BD read index has been write to HW register */ + + u8 *pRXBDAddr; /* The RX_BD start address */ + PSDIO_RX_BD pRXBDAddrAligned; /* The RX_BD start address, it must be 8-bytes aligned */ + PSDIO_RX_BD_HANDLE pRXBDHdl; /* point to the allocated memory for RX_BD Handle array */ + u16 RXBDWPtr; /* The SDIO RX(Device->Host) BD write index */ + u16 RXBDRPtr; /* The SDIO RX(Device->Host) BD local read index, different with HW maintained Read Index. */ + u16 IntMask; /* The Interrupt Mask */ + u16 IntStatus; /* The Interrupt Status */ + u32 Events; /* The Event to the SDIO Task */ + + u8 CCPWM; /* the value write to register CCPWM, which will sync to Host HCPWM */ + u8 reserve1; + u16 CCPWM2; /* the value write to register CCPWM2, which will sync to Host HCPWM2 */ + u8 CRPWM; /* sync from Host HRPWM */ + u8 reserve2; + u16 CRPWM2; /* sync from Host HRPWM2 */ + +#if !TASK_SCHEDULER_DISABLED + _Sema TxSema; /* Semaphore for SDIO TX, use to wakeup the SDIO TX task */ + _Sema RxSema; /* Semaphore for SDIO RX, use to wakeup the SDIO RX task */ +#else + u32 EventSema; /* Semaphore for SDIO events, use to wakeup the SDIO task */ +#endif + s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); /* to hook the WLan driver TX callback function to handle a Packet TX */ + VOID *pTxCb_Adapter; /* a pointer will be used to call the TX Callback function, + which is from the TX CallBack function register */ +#if SDIO_API_DEFINED + s8 (*Rx_Done_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); /* to hook RX done callback function to release packet */ + VOID *pRxDoneCb_Adapter; /* a pointer will be used to call the RX Done Callback function, + which is from the TX CallBack function register */ +#endif + s8 (*pTxCallback_Backup)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 type); // Use to back up the registered TX Callback function, for MP/Normal mode switch + VOID *pTxCb_Adapter_Backup; // Backup the pTxCb_Adapter, for MP/Normal mode switch +#if SDIO_DEBUG + _LIST FreeTxPktList; /* The list to queue free Tx packets handler */ + SDIO_TX_PACKET *pTxPktHandler; /* to store allocated TX Packet handler memory address */ +#endif + _LIST RxPktList; /* The list to queue RX packets */ + _LIST FreeRxPktList; /* The list to queue free Rx packets handler */ +// _LIST RecyclePktList; /* The list to queue packets handler to be recycled */ + SDIO_RX_PACKET *pRxPktHandler; /* to store allocated RX Packet handler memory address */ + _Mutex RxMutex; /* The Mutex to protect RxPktList */ + u32 RxInQCnt; /* The packet count for Rx In Queue */ +#if SDIO_DEBUG + _Mutex StatisticMutex; /* The Mutex to protect Statistic data */ + u32 MemAllocCnt; // Memory allocated count, for debug only + u32 MAllocFailedCnt; // MemAlloc Failed count, for debugging +#endif + VOID *pHalOp; /* point to HAL operation function table */ + RTL_MAILBOX *pMBox; /* the Mail box for other driver module can send message to SDIO driver */ + +#ifdef PLATFORM_FREERTOS + xTaskHandle xSDIOTxTaskHandle; /* The handle of the SDIO Task for TX, can be used to delte the task */ + xTaskHandle xSDIORxTaskHandle; /* The handle of the SDIO Task speical for RX, can be used to delte the task */ +#endif + u8 RxFifoBusy; /* is the RX BD fetch hardware busy */ + +#if SDIO_MP_MODE +#if !TASK_SCHEDULER_DISABLED + u32 MP_Events; /* The Event to the SDIO Task */ + _Sema MP_EventSema; /* Semaphore for SDIO events, use to wakeup the SDIO task */ + RTL_MAILBOX *pMP_MBox; /* the Mail box for communication with other driver module */ +#ifdef PLATFORM_FREERTOS + xTaskHandle MP_TaskHandle; /* The handle of the MP loopback Task, can be used to delte the task */ +#endif // end of "#ifdef PLATFORM_FREERTOS" +#endif // end of "#if !TASK_SCHEDULER_DISABLED" + // for MP mode + RTL_TIMER *pPeriodTimer; /* a timer to calculate throughput periodically */ + u8 MP_ModeEn; /* is in MP mode */ + u8 MP_LoopBackEn; /* is loop-back enabled */ + u8 MP_ContinueTx; /* is continue TX test enabled */ + u8 MP_ContinueRx; /* is continue RX test enabled */ + u8 MP_ContinueRxMode; /* continue RX test mode: static RX Buf, Dyna-Allocate RX Buf, Pre-Allocate RX Buf */ + u8 MP_CRxInfinite; /* is non-stop SDIO RX, no packet count limit */ + u16 MP_CRxSize; /* SDIO RX test packet size */ + u8 *pMP_CRxBuf; // the buffer for continye RX test + u32 MP_CRxPktCnt; /* SDIO RX test packet count */ + u32 MP_CRxPktPendingCnt; /* SDIO RX test packet pening count */ + u32 MP_TxPktCnt; /* SDIO TX packet count */ + u32 MP_RxPktCnt; /* SDIO RX packet count */ + u32 MP_TxByteCnt; /* SDIO TX Byte count */ + u32 MP_RxByteCnt; /* SDIO RX Byte count */ + u32 MP_TxDropCnt; /* SDIO TX Drop packet count */ + u32 MP_RxDropCnt; /* SDIO RX Drop packet count */ + + u32 MP_TxPktCntInPeriod; /* SDIO TX packet count in a period */ + u32 MP_RxPktCntInPeriod; /* SDIO RX packet count in a period */ + u32 MP_TxByteCntInPeriod; /* SDIO TX Byte count in a period */ + u32 MP_RxByteCntInPeriod; /* SDIO RX Byte count in a period */ + + u32 MP_TxAvgTPWin[SDIO_AVG_TP_WIN_SIZE]; /* a window of SDIO TX byte count history, for average throughput calculation */ + u32 MP_RxAvgTPWin[SDIO_AVG_TP_WIN_SIZE]; /* a window of SDIO RX byte count history, for average throughput calculation */ + u32 MP_TxAvgTPWinSum; /* The sum of all byte-count in the window */ + u32 MP_RxAvgTPWinSum; /* The sum of all byte-count in the window */ + u8 OldestTxAvgWinIdx; /* the index of the oldest TX byte count log */ + u8 TxAvgWinCnt; /* the number of log in the Window */ + u8 OldestRxAvgWinIdx; /* the index of the oldest RX byte count log */ + u8 RxAvgWinCnt; /* the number of log in the Window */ + + _LIST MP_RxPktList; /* The list to queue RX packets, for MP loopback test */ +#endif // end of '#if SDIO_MP_MODE' +} HAL_SDIO_ADAPTER, *PHAL_SDIO_ADAPTER; +#endif // end of "#else of "#if SDIO_BOOT_DRIVER"" + + +typedef struct _HAL_SDIO_OP_ { + BOOL (*HalSdioDevInit)(PHAL_SDIO_ADAPTER pSDIODev); + VOID (*HalSdioDevDeInit)(PHAL_SDIO_ADAPTER pSDIODev); + VOID (*HalSdioSendC2HIOMsg)(PHAL_SDIO_ADAPTER pSDIODev, u32 *C2HMsg); + u8 (*HalSdioSendC2HPktMsg)(PHAL_SDIO_ADAPTER pSDIODev, u8 *C2HMsg, u16 MsgLen); + VOID (*HalSdioRegTxCallback)(PHAL_SDIO_ADAPTER pSDIODev,s8 (*CallbackFun)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type), VOID *pAdapter); + s8 (*HalSdioRxCallback)(PHAL_SDIO_ADAPTER pSDIODev, VOID *pData, u16 Offset, u16 PktSize, u8 CmdType); +#if SDIO_API_DEFINED + VOID (*HalSdioRegRxDoneCallback)(PHAL_SDIO_ADAPTER pSDIODev,s8 (*CallbackFun)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type), VOID *pAdapter); +#endif +#if SDIO_MP_MODE + VOID (*HalSdioDevMPApp)(PHAL_SDIO_ADAPTER pSDIODev, u16 argc, u8 *argv[]); +#endif +}HAL_SDIO_OP, *PHAL_SDIO_OP; + + +extern BOOL SDIO_Device_Init( + IN PHAL_SDIO_ADAPTER pSDIODev +); +extern VOID SDIO_Device_DeInit( + IN PHAL_SDIO_ADAPTER pSDIODev +); +extern VOID SDIO_Send_C2H_IOMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 *C2HMsg +); +extern u8 SDIO_Send_C2H_PktMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *C2HMsg, + IN u16 MsgLen +); +extern VOID SDIO_Register_Tx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN s8 (*Tx_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type), + IN VOID *pAdapter +); +#if SDIO_API_DEFINED +extern VOID SDIO_Register_Rx_Done_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN s8 (*Rx_Done_Callback)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize, u8 Type), + IN VOID *pAdapter +); +#endif +extern s8 SDIO_Rx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN VOID *pData, + IN u16 Offset, + IN u16 Length, + IN u8 CmdType +); +#if SDIO_MP_MODE +extern VOID SDIO_DeviceMPApp( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u16 argc, + IN u8 *argv[] +); +#endif + +extern PHAL_SDIO_ADAPTER pgSDIODev; +extern VOID HalSdioInit(VOID); +extern VOID HalSdioDeInit(VOID); +#endif // #ifndef _HAL_SDIO_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_sdio_host.h b/USDK/component/soc/realtek/8195a/fwlib/hal_sdio_host.h new file mode 100644 index 0000000..c6dc0ae --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_sdio_host.h @@ -0,0 +1,105 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_SDIO_HOST_H_ +#define _HAL_SDIO_HOST_H_ + + +#include "rtl8195a_sdio_host.h" + + +#define SDIO_HOST_WAIT_FOREVER 0xFFFFFFFF + + +typedef struct _HAL_SDIO_HOST_OP_ { + HAL_Status (*HalSdioHostInitHost) (VOID *Data); + HAL_Status (*HalSdioHostInitCard) (VOID *Data); + HAL_Status (*HalSdioHostDeInit) (VOID *Data); + HAL_Status (*HalSdioHostRegIrq) (VOID *Data); + HAL_Status (*HalSdioHostReadBlocksDma) (VOID *Data, u64 ReadAddr, u32 BlockCnt); + HAL_Status (*HalSdioHostWriteBlocksDma) (VOID *Data, u64 WriteAddr, u32 BlockCnt); + HAL_Status (*HalSdioHostStopTransfer) (VOID *Data); + HAL_Status (*HalSdioHostGetCardStatus) (VOID *Data); + HAL_Status (*HalSdioHostGetSdStatus) (VOID *Data); + HAL_Status (*HalSdioHostChangeSdClock) (VOID *Data, u8 Frequency); + HAL_Status (*HalSdioHostErase) (VOID *Data, u64 StartAddr, u64 EndAddr); + HAL_Status (*HalSdioHostGetWriteProtect) (VOID *Data); + HAL_Status (*HalSdioHostSetWriteProtect) (VOID *Data, u8 Setting); +}HAL_SDIO_HOST_OP, *PHAL_SDIO_HOST_OP; + +// SDIO error type +typedef enum _SDIO_ERR_TYPE_ { + SDIO_ERR_DAT_CRC = 0x01, + SDIO_ERR_CMD_TIMEOUT = 0x02, +}SDIO_ERR_TYPE; + +typedef enum _SDIO_XFER_TYPE_{ + SDIO_XFER_NOR = 0x00, // normal + SDIO_XFER_R = 0x01, // read and write block + SDIO_XFER_W = 0x02, // read and write block +}SDIO_XFER_TYPE; + +typedef struct _HAL_SDIO_HOST_ADAPTER_{ + IRQ_HANDLE IrqHandle; //+0..6(u32) Irq Handler + ADMA2_DESC_FMT *AdmaDescTbl; //+7(u32) + u32 Response[4]; //+8..11(u32) + u32 CardOCR; //+12 + u32 CardStatus; //+13 + u32 IsWriteProtect; //+14 + u8 SdStatus[SD_STATUS_LEN]; //+15.. + u8 Csd[CSD_REG_LEN]; //+31 + volatile u8 CmdCompleteFlg; + volatile u8 XferCompleteFlg; + volatile u8 ErrIntFlg; + volatile u8 CardCurState; + u8 IsSdhc; + u8 CurrSdClk; //+133? + u16 RCA; + u16 SdSpecVer; + SDIO_ERR_TYPE errType; + SDIO_XFER_TYPE XferType; + VOID (*XferCompCallback)(VOID *pAdapter); + VOID *XferCompCbPara; + VOID (*ErrorCallback)(VOID *pAdapter); + VOID *ErrorCbPara; + VOID (*CardInsertCallBack)(VOID *pAdapter); + VOID *CardInsertCbPara; + VOID (*CardRemoveCallBack)(VOID *pAdapter); + VOID *CardRemoveCbPara; +}HAL_SDIO_HOST_ADAPTER, *PHAL_SDIO_HOST_ADAPTER; + +extern HAL_SDIO_HOST_ADAPTER SdioHostAdapter; + +extern HAL_Status +HalSdioHostInit( + IN VOID *Data +); + +extern HAL_Status +HalSdioHostDeInit( + IN VOID *Data +); + +extern HAL_Status +HalSdioHostEnable( + IN VOID *Data +); + +extern HAL_Status +HalSdioHostDisable( + IN VOID *Data +); + +extern VOID +HalSdioHostOpInit( + IN VOID *Data +); + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_sdr_controller.h b/USDK/component/soc/realtek/8195a/fwlib/hal_sdr_controller.h new file mode 100644 index 0000000..89c99bc --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_sdr_controller.h @@ -0,0 +1,191 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_SDR_CONTROLLER_H_ +#define _HAL_SDR_CONTROLLER_H_ + +#if 1 //def CONFIG_SDR_EN + +typedef enum _DRAM_TYPE_ { + DRAM_DDR_1 = 1, + DRAM_DDR_2 = 2, + DRAM_DDR_3 = 3, + DRAM_DDR_4 = 4, + DRAM_SDR = 8 +}DRAM_TYPE; + +typedef enum _DRAM_COLADDR_WTH_ { + DRAM_COLADDR_8B = 0, + DRAM_COLADDR_9B = 1, + DRAM_COLADDR_10B = 2, + DRAM_COLADDR_11B = 3, + DRAM_COLADDR_12B = 4, + DRAM_COLADDR_13B = 5, + DRAM_COLADDR_14B = 6, + DRAM_COLADDR_15B = 7, + DRAM_COLADDR_16B = 8 +}DRAM_COLADDR_WTH; + +typedef enum _DRAM_BANK_SIZE_ { + DRAM_BANK_2 = 0, + DRAM_BANK_4 = 1, + DRAM_BANK_8 = 2 +}DRAM_BANK_SIZE; + +typedef enum _DRAM_DQ_WIDTH_ { + DRAM_DQ_16 = 0, + DRAM_DQ_32 = 1, + DRAM_HALF_DQ32 = 2 +}DRAM_DQ_WIDTH; + +typedef enum _MODE0_BST_LEN_ { + BST_LEN_4 = 0, + BST_LEN_FLY = 1, + BST_LEN_8 = 2 +}MODE0_BST_LEN; + +typedef enum _MODE0_BST_TYPE_ { + SENQUENTIAL = 0, + INTERLEAVE = 1 +}MODE0_BST_TYPE; + +typedef enum _DFI_RATIO_TYPE_ { + DFI_RATIO_1 = 0, // DFI= 1:1, or SDR + DFI_RATIO_2 = 1, + DFI_RATIO_4 = 2 +}DFI_RATIO_TYPE; + +typedef struct _DRAM_INFO_ { + DRAM_TYPE DeviceType; + DRAM_COLADDR_WTH ColAddrWth; + DRAM_BANK_SIZE Bank; + DRAM_DQ_WIDTH DqWidth; +}DRAM_INFO; + +typedef struct _DRAM_MODE_REG_INFO_ { + MODE0_BST_LEN BstLen; + MODE0_BST_TYPE BstType; + //enum mode0_cas rd_cas; + u32 Mode0Cas; + u32 Mode0Wr; + u32 Mode1DllEnN; + u32 Mode1AllLat; + u32 Mode2Cwl; +}DRAM_MODE_REG_INFO; + +typedef struct _DRAM_TIMING_INFO_ { + u32 TrfcPs; + u32 TrefiPs; + u32 WrMaxTck; + u32 TrcdPs; + u32 TrpPs; + u32 TrasPs; + u32 TrrdTck; + u32 TwrPs; + u32 TwtrTck; + //u32 TrtpPs; + u32 TmrdTck; + u32 TrtpTck; + u32 TccdTck; + u32 TrcPs; +}DRAM_TIMING_INFO; + + +typedef struct _DRAM_DEVICE_INFO_ { + DRAM_INFO *Dev; + DRAM_MODE_REG_INFO *ModeReg; + DRAM_TIMING_INFO *Timing; + u32 DdrPeriodPs; + DFI_RATIO_TYPE *DfiRate; +} DRAM_DEVICE_INFO, *PDRAM_DEVICE_INFO; + + +//====================================================== +//DRAM Info +#ifdef CONFIG_FPGA + #define DRAM_INFO_TYPE DRAM_SDR + #define DRAM_INFO_COL_ADDR_WTH DRAM_COLADDR_9B + #define DRAM_INFO_BANK_SZ DRAM_BANK_4 + #define DRAM_INFO_DQ_WTH DRAM_DQ_16 +#else + #define DRAM_INFO_TYPE DRAM_SDR + #define DRAM_INFO_COL_ADDR_WTH DRAM_COLADDR_8B + #define DRAM_INFO_BANK_SZ DRAM_BANK_2 + #define DRAM_INFO_DQ_WTH DRAM_DQ_16 +#endif + +//====================================================== +//DRAM Timing +#ifdef CONFIG_SDR_100MHZ +#define DRAM_TIMING_TCK 10000 //ps +#endif +#ifdef CONFIG_SDR_50MHZ +#define DRAM_TIMING_TCK 20000 //ps +#endif +#ifdef CONFIG_SDR_25MHZ +#define DRAM_TIMING_TCK 40000 //ps +#endif +#ifdef CONFIG_SDR_12_5MHZ +#define DRAM_TIMING_TCK 80000 //ps +#endif + +#if 1 +#define DRAM_TIMING_TREF 64000 //us +#define DRAM_ROW_NUM 8192 //depends on row bit number + +#define DRAM_TIMING_TRFC 60000 //ps +#define DRAM_TIMING_TREFI ((u32)((DRAM_TIMING_TREF*1000)/DRAM_ROW_NUM)*1000) //ps +#define DRAM_TIMING_TWRMAXTCK 2 //tck +#define DRAM_TIMING_TRCD 15000 //ps +#define DRAM_TIMING_TRP 15000 //ps +#define DRAM_TIMING_TRAS 42000 //ps +#define DRAM_TIMING_TRRD 2 //tck +#define DRAM_TIMING_TWR ((u32)(DRAM_TIMING_TCK*2)) +#define DRAM_TIMING_TWTR 0 //tck +#define DRAM_TIMING_TMRD 2 //tck +#define DRAM_TIMING_TRTP 0 //tck +#define DRAM_TIMING_TCCD 1 //tck +#define DRAM_TIMING_TRC 60000 //ps +#else + +#define DRAM_TIMING_TREF 66000 //us +#define DRAM_ROW_NUM 8192 //depends on row bit number + +#define DRAM_TIMING_TRFC 66000 //ps +#define DRAM_TIMING_TREFI 63999800 +#define DRAM_TIMING_TWRMAXTCK 2 //tck +#define DRAM_TIMING_TRCD 15000 //ps +#define DRAM_TIMING_TRP 15000 //ps +#define DRAM_TIMING_TRAS 37000 //ps +#define DRAM_TIMING_TRRD 2 //tck +#define DRAM_TIMING_TWR 7000 +#define DRAM_TIMING_TWTR 0 //tck +#define DRAM_TIMING_TMRD 2 //tck +#define DRAM_TIMING_TRTP 0 //tck +#define DRAM_TIMING_TCCD 1 //tck +#define DRAM_TIMING_TRC 60000 //ps +#endif + +#define HAL_SDR_WRITE32(addr, value32) HAL_WRITE32(SDR_CTRL_BASE, addr, value32) +#define HAL_SDR_WRITE16(addr, value16) HAL_WRITE16(SDR_CTRL_BASE, addr, value16) +#define HAL_SDR_WRITE8(addr, value8) HAL_WRITE8(SDR_CTRL_BASE, addr, value8) +#define HAL_SDR_READ32(addr) HAL_READ32(SDR_CTRL_BASE, addr) +#define HAL_SDR_READ16(addr) HAL_READ16(SDR_CTRL_BASE, addr) +#define HAL_SDR_READ8(addr) HAL_READ8(SDR_CTRL_BASE, addr) + +#define HAL_SDRAM_WRITE32(addr, value32) HAL_WRITE32(SDR_SDRAM_BASE, addr, value32) +#define HAL_SDRAM_WRITE16(addr, value16) HAL_WRITE16(SDR_SDRAM_BASE, addr, value16) +#define HAL_SDRAM_WRITE8(addr, value8) HAL_WRITE8(SDR_SDRAM_BASE, addr, value8) +#define HAL_SDRAM_READ32(addr) HAL_READ32(SDR_SDRAM_BASE, addr) +#define HAL_SDRAM_READ16(addr) HAL_READ16(SDR_SDRAM_BASE, addr) +#define HAL_SDRAM_READ8(addr) HAL_READ8(SDR_SDRAM_BASE, addr) + +#endif // CONFIG_SDR_EN +//extern unsigned int rand_x; +#endif // end of "#ifndef _HAL_SDR_CONTROLLER_H_" diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_soc_ps_monitor.h b/USDK/component/soc/realtek/8195a/fwlib/hal_soc_ps_monitor.h new file mode 100644 index 0000000..e495587 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_soc_ps_monitor.h @@ -0,0 +1,279 @@ +#ifndef _HAL_SOCPWR_ +#define _HAL_SOCPWR_ + + +#define MAX_BACKUP_SIZE 129 +#define MAXFUNC 10 +#define FSTREG 0xFF + +#define REG_VDR_ANACK_CAL_CTRL 0xA0 + +#define PS_MASK 0xFFFFFFFF + +//pwr state +#define HWACT 0 +#define HWCG 1 +#define HWINACT 2 +#define UNDEF 3 +#define ALLMET 0xff + +//SLP +#define SLP_STIMER BIT0 +#define SLP_GTIMER BIT1 +#define SLP_GPIO BIT2 +#define SLP_WL BIT3 +#define SLP_NFC BIT4 +#define SLP_SDIO BIT5 +#define SLP_USB BIT6 +#define SLP_TIMER33 BIT7 + +//DSTBY +#define DSTBY_STIMER BIT0 +#define DSTBY_NFC BIT1 +#define DSTBY_TIMER33 BIT2 +#define DSTBY_GPIO BIT3 + +//DS wake event +#define DS_TIMER33 BIT0 +#define DS_GPIO BIT1 + +enum power_state_idx{ + ACT = 0, + WFE, + WFI, + SNOOZE, + SLPCG, + SLPPG, + DSTBY, + DSLP, + INACT, + MAXSTATE +}; + +enum clk_idx{ + ANACK = 0, + A33CK = 1, +}; + + +typedef struct _power_state_{ + u8 FuncIdx; + u8 PowerState; +}POWER_STATE, *pPOWER_STATE; + +typedef struct _reg_power_state_{ + u8 FuncIdx; + u8 PwrState; +}REG_POWER_STATE, *pPREG_POWER_STATE; + +#if 0 +typedef struct _power_state_{ + u8 FuncIdx; + u8 PowerState; + u32 ReqDuration; + u32 RegCount; + u32 RemainDuration; +}POWER_STATE, *pPOWER_STATE; + +typedef struct _reg_power_state_{ + u8 FuncIdx; + u8 PwrState; + u32 ReqDuration; + //u8 StateIdx; +}REG_POWER_STATE, *pPREG_POWER_STATE; +#endif + +typedef struct _power_mgn_{ + u8 ActFuncCount; + POWER_STATE PwrState[MAXFUNC]; + u8 CurrentState; + u8 SDREn; + u32 MSPbackup[MAX_BACKUP_SIZE]; + u32 CPURegbackup[25]; + u32 CPUPSP; + u32 WakeEventFlag; + BOOL SleepFlag; + //u32 CPUReg[13]; + //u32 MSBackUp[128]; +}Power_Mgn, *pPower_Mgn; + +typedef struct _SYS_ADAPTER_ { + u8 function; +}SYS_ADAPTER, *PSYS_ADAPTER; + +extern Power_Mgn PwrAdapter; + +u8 ChangeSoCPwrState( + IN u8 RequestState, + IN u32 ReqCount +); + +VOID PrintCPU(VOID); +void WakeFromSLPPG(void); +VOID SOCPSTestApp(VOID *Data); + + +__inline static VOID +CPURegBackUp( + VOID +) +{ +#if defined (__ICCARM__) + // TODO: IAR has different way using assembly +#elif defined (__GNUC__) + //backup cpu reg + #if 0 + asm volatile + ( + "PUSH {PSR, PC, LR, R12,R3,R2,R1,R0}\n" + ); + #endif + #if 0 + asm volatile + ( + "PUSH {r0,r1,r2,r3,r4}\n" + ); + #endif + + asm volatile + ( + + "MOV %0, r0\n" + :"=r"(PwrAdapter.CPURegbackup[0]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r1\n" + :"=r"(PwrAdapter.CPURegbackup[1]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r2\n" + :"=r"(PwrAdapter.CPURegbackup[2]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r3\n" + :"=r"(PwrAdapter.CPURegbackup[3]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r4\n" + :"=r"(PwrAdapter.CPURegbackup[4]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r5\n" + :"=r"(PwrAdapter.CPURegbackup[5]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r6\n" + :"=r"(PwrAdapter.CPURegbackup[6]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r7\n" + :"=r"(PwrAdapter.CPURegbackup[7]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r8\n" + :"=r"(PwrAdapter.CPURegbackup[8]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r9\n" + :"=r"(PwrAdapter.CPURegbackup[9]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r10\n" + :"=r"(PwrAdapter.CPURegbackup[10]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r11\n" + :"=r"(PwrAdapter.CPURegbackup[11]) + ::"memory" + ); + asm volatile + ( + "MOV %0, r12\n" + :"=r"(PwrAdapter.CPURegbackup[12]) + ::"memory" + ); + + asm volatile + ( + "MOV %0, r13\n" + :"=r"(PwrAdapter.CPURegbackup[13]) + ::"memory" + ); + asm volatile + ( + //"MOV %0, r14\n" + "LDR %0, =SLPPG_WAKEUP_POINT\n" + "ADD %0, #1\n" + :"=r"(PwrAdapter.CPURegbackup[14]) + ::"memory" + ); + asm volatile + ( + "LDR %0, =SLPPG_WAKEUP_POINT\n" + "ADD %0, #1\n" + :"=r"(PwrAdapter.CPURegbackup[15]) + ::"memory" + ); + asm volatile + ( + "MRS %0, PSR\n" + :"=r"(PwrAdapter.CPURegbackup[16]) + ::"memory" + ); + +#if 1 + asm volatile + ( + "mov %0, r13\n" + "MOV %1, PC\n" + "MRS %2, CONTROL\n" + "MRS %3, PSP\n" + "MRS %4, MSP\n" + :"=r"(PwrAdapter.CPURegbackup[24]),"=r"(PwrAdapter.CPURegbackup[23]),"=r"(PwrAdapter.CPURegbackup[22]),"=r"(PwrAdapter.CPURegbackup[21]),"=r"(PwrAdapter.CPURegbackup[20]) + ::"memory" + ); +#endif + #ifdef CONFIG_SOC_PS_VERIFY + PrintCPU(); + #endif //#ifdef CONFIG_SOC_PS_VERIFY +#endif //#elif defined (__GNUC__) +} + +extern VOID RegPowerState(REG_POWER_STATE RegPwrState); +extern VOID QueryRegPwrState( IN u8 FuncIdx, OUT u8* RegState, OUT u8* HwState); + + +#endif //_HAL_SOCPWR_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_spi_flash.h b/USDK/component/soc/realtek/8195a/fwlib/hal_spi_flash.h new file mode 100644 index 0000000..abb4b26 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_spi_flash.h @@ -0,0 +1,359 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _HAL_SPIFLASH__ +#define _HAL_SPIFLASH__ +//====================================================== +// Header files + +#define SPIC_CALIBRATION_IN_NVM 1 // if store the SPIC calibration data in the NVM +#ifndef CONFIG_IMAGE_SEPARATE // Store SPIC Calibration only for seprated image +#undef SPIC_CALIBRATION_IN_NVM +#define SPIC_CALIBRATION_IN_NVM 0 +#endif + +//====================================================== +// Definition +#define HAL_SPI_WRITE32(addr, value32) HAL_WRITE32(SPI_FLASH_CTRL_BASE, addr, value32) +#define HAL_SPI_WRITE16(addr, value16) HAL_WRITE16(SPI_FLASH_CTRL_BASE, addr, value16) +#define HAL_SPI_WRITE8(addr, value8) HAL_WRITE8(SPI_FLASH_CTRL_BASE, addr, value8) +#define HAL_SPI_READ32(addr) HAL_READ32(SPI_FLASH_CTRL_BASE, addr) +#define HAL_SPI_READ16(addr) HAL_READ16(SPI_FLASH_CTRL_BASE, addr) +#define HAL_SPI_READ8(addr) HAL_READ8(SPI_FLASH_CTRL_BASE, addr) + +typedef struct _SPIC_PARA_MODE_ { + u8 Valid :1; // valid + u8 CpuClk :3; // CPU clock + u8 BitMode :2; // Bit mode + u8 Reserved :2; // reserved +} SPIC_PARA_MODE, *PSPIC_PARA_MODE; + +typedef struct _SPIC_INIT_PARA_ { + u8 BaudRate; + u8 RdDummyCyle; + u8 DelayLine; + union { + u8 Rsvd; + u8 Valid; + SPIC_PARA_MODE Mode; + }; +#if defined(E_CUT_ROM_DOMAIN) || (!defined(CONFIG_RELEASE_BUILD_LIBRARIES)) + u8 id[3]; + u8 flashtype; +#endif +}SPIC_INIT_PARA, *PSPIC_INIT_PARA; + + +enum _SPIC_BIT_MODE_ { + SpicOneBitMode = 0, + SpicDualBitMode = 1, + SpicQuadBitMode = 2, + SpicMaxMode = 3 +}; + +//====================================================== +// Flash type used +#define FLASH_OTHERS 0 +#define FLASH_MXIC 1 +#define FLASH_MXIC_4IO 2 +#define FLASH_WINBOND 3 +#define FLASH_MICRON 4 +#define FLASH_EON 5 + +//#define FLASH_MXIC_MX25L4006E 0 +//#define FLASH_MXIC_MX25L8073E 1 +//#define FLASH_MICRON_N25Q512A 1 +// The below parts are based on the flash characteristics +//====== Flash Command Definition ====== +//#if FLASH_MICRON_N25Q512A + +/*Common command*/ +#define FLASH_CMD_WREN 0x06 //write enable +#define FLASH_CMD_WRDI 0x04 //write disable +#define FLASH_CMD_WRSR 0x01 //write status register +#define FLASH_CMD_RDID 0x9F //read idenfication +#define FLASH_CMD_RDSR 0x05 //read status register +#define FLASH_CMD_RDSFDP 0x5A //Read SFDP +#define FLASH_CMD_READ 0x03 //read data +#define FLASH_CMD_FREAD 0x0B //fast read data +#define FLASH_CMD_PP 0x02 //Page Program +#define FLASH_CMD_DREAD 0x3B //Double Output Mode command 1-1-2 +#define FLASH_CMD_2READ 0xBB // 2 x I/O read command 1-2-2 +#define FLASH_CMD_QREAD 0x6B // 1I / 4O read command 1-1-4 +#define FLASH_CMD_4READ 0xEB // 4 x I/O read command 1-4-4 +#define FLASH_CMD_DPP 0xA2 // 1-1-2 +#define FLASH_CMD_2PP 0xD2 // 1-2-2 +#define FLASH_CMD_QPP 0x32 // 1-1-4 +#define FLASH_CMD_4PP 0x38 //quad page program 1-4-4 +#define FLASH_CMD_SE 0x20 //Sector Erase +#define FLASH_CMD_BE 0xD8 //Block Erase(or 0x52) +#define FLASH_CMD_CE 0xC7 //Chip Erase(or 0xC7) +#define FLASH_CMD_DP 0xB9 //Deep Power Down +#define FLASH_CMD_RDP 0xAB //Release from Deep Power-Down + +/*Micron Special command*/ +#define FLASH_CMD_DE 0xC4 // DIE ERASE +#define FLASH_CMD_4PP2 0x12 // 4-BYTE PAGE PROGRAM +#define FLASH_CMD_RFSR 0x70 // READ FLAG STATUS REGISTER +#define FLASH_CMD_CFSR 0x50 // CLEAR FLAG STATUS REGISTER +#define FLASH_CMD_RNCR 0xB5 // READ NONVOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_WNCR 0xB1 // WRITE NONVOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_RVCR 0x85 // READ VOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_WVCR 0x81 // WRITE VOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_REVCR 0x65 // READ ENHANCED VOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_WEVCR 0x61 // WRITE ENHANCED VOLATILE CONFIGURATION REGISTER +#define FLASH_CMD_REAR 0xC8 // READ EXTENDED ADDRESS REGISTER +#define FLASH_CMD_WEAR 0xC5 // WRITE EXTENDED ADDRESS REGISTER +#define FLASH_CMD_ENQUAD 0x35 // ENTER QUAD +#define FLASH_CMD_EXQUAD 0xF5 // EXIT QUAD +#define FLASH_CMD_ROTPA 0x4B // READ OTP ARRAY +#define FLASH_CMD_POTPA 0x42 // PROGRAM OTP ARRAY + +/*MXIC Special command*/ +#define FLASH_CMD_RDCR 0x15 //read configurate register +#define FLASH_CMD_REMS2 0xEF // read ID for 2x I/O mode +#define FLASH_CMD_REMS4 0xDF // read ID for 4x I/O mode +#define FLASH_CMD_ENSO 0xB1 // enter secured OTP +#define FLASH_CMD_EXSO 0xC1 // exit secured OTP +#define FLASH_CMD_RDSCUR 0x2B // read security register +#define FLASH_CMD_WRSCUR 0x2F // write security register + +/* EON Special command*/ +#define FLASH_CMD_EOTPM 0x3A // Enter OTP Mode (3Ah) + +//#endif +#if 0 +#if FLASH_MXIC_MX25L4006E + #define FLASH_CMD_WREN 0x06 //write enable + #define FLASH_CMD_WRDI 0x04 //write disable + #define FLASH_CMD_WRSR 0x01 //write status register + #define FLASH_CMD_RDID 0x9F //read idenfication + #define FLASH_CMD_RDSR 0x05 //read status register + #define FLASH_CMD_READ 0x03 //read data + #define FLASH_CMD_FREAD 0x0B //fast read data + #define FLASH_CMD_RDSFDP 0x5A //Read SFDP + #define FLASH_CMD_RES 0xAB //Read Electronic ID + #define FLASH_CMD_REMS 0x90 //Read Electronic Manufacturer & Device ID + #define FLASH_CMD_DREAD 0x3B //Double Output Mode command + #define FLASH_CMD_SE 0x20 //Sector Erase + #define FLASH_CMD_BE 0xD8 //Block Erase(or 0x52) + #define FLASH_CMD_CE 0x60 //Chip Erase(or 0xC7) + #define FLASH_CMD_PP 0x02 //Page Program + #define FLASH_CMD_DP 0xB9 //Deep Power Down + #define FLASH_CMD_RDP 0xAB //Release from Deep Power-Down + #define FLASH_CMD_RDCR 0x15 //read configurate register + #define FLASH_CMD_2READ 0xBB // 2 x I/O read command + #define FLASH_CMD_4READ 0xEB // 4 x I/O read command + #define FLASH_CMD_QREAD 0x6B // 1I / 4O read command + #define FLASH_CMD_4PP 0x38 //quad page program + #define FLASH_CMD_FF 0xFF //Release Read Enhanced + #define FLASH_CMD_REMS2 0xEF // read ID for 2x I/O mode + #define FLASH_CMD_REMS4 0xDF // read ID for 4x I/O mode + #define FLASH_CMD_ENSO 0xB1 // enter secured OTP + #define FLASH_CMD_EXSO 0xC1 // exit secured OTP + #define FLASH_CMD_RDSCUR 0x2B // read security register + #define FLASH_CMD_WRSCUR 0x2F // write security register +#elif FLASH_MXIC_MX25L8073E + #define FLASH_CMD_WREN 0x06 //write enable + #define FLASH_CMD_WRDI 0x04 //write disable + #define FLASH_CMD_WRSR 0x01 //write status register + #define FLASH_CMD_RDID 0x9F //read idenfication + #define FLASH_CMD_RDSR 0x05 //read status register + #define FLASH_CMD_READ 0x03 //read data + #define FLASH_CMD_FREAD 0x0B //fast read data + #define FLASH_CMD_RDSFDP 0x5A //Read SFDP + #define FLASH_CMD_RES 0xAB //Read Electronic ID + #define FLASH_CMD_REMS 0x90 //Read Electronic Manufacturer & Device ID + #define FLASH_CMD_DREAD 0x3B //Double Output Mode command + #define FLASH_CMD_SE 0x20 //Sector Erase + #define FLASH_CMD_BE 0x52 //Block Erase + #define FLASH_CMD_CE 0x60 //Chip Erase(or 0xC7) + #define FLASH_CMD_PP 0x02 //Page Program + #define FLASH_CMD_DP 0xB9 //Deep Power Down + #define FLASH_CMD_RDP 0xAB //Release from Deep Power-Down + #define FLASH_CMD_2READ 0xBB // 2 x I/O read command + #define FLASH_CMD_4READ 0xEB // 4 x I/O read command + #define FLASH_CMD_QREAD 0x6B // 1I / 4O read command + #define FLASH_CMD_4PP 0x38 //quad page program + #define FLASH_CMD_FF 0xFF //Release Read Enhanced + #define FLASH_CMD_REMS2 0xEF // read ID for 2x I/O mode + #define FLASH_CMD_REMS4 0xDF // read ID for 4x I/O mode + #define FLASH_CMD_ENSO 0xB1 // enter secured OTP + #define FLASH_CMD_EXSO 0xC1 // exit secured OTP + #define FLASH_CMD_RDSCUR 0x2B // read security register + #define FLASH_CMD_WRSCUR 0x2F // write security register +#else + #define FLASH_CMD_WREN 0x06 //write enable + #define FLASH_CMD_WRDI 0x04 //write disable + #define FLASH_CMD_WRSR 0x01 //write status register + #define FLASH_CMD_RDID 0x9F //read idenfication + #define FLASH_CMD_RDSR 0x05 //read status register + #define FLASH_CMD_READ 0x03 //read data + #define FLASH_CMD_FREAD 0x0B //fast read data + #define FLASH_CMD_RDSFDP 0x5A //Read SFDP + #define FLASH_CMD_RES 0xAB //Read Electronic ID + #define FLASH_CMD_REMS 0x90 //Read Electronic Manufacturer & Device ID + #define FLASH_CMD_DREAD 0x3B //Double Output Mode command + #define FLASH_CMD_SE 0x20 //Sector Erase + #define FLASH_CMD_BE 0x52 //Block Erase + #define FLASH_CMD_CE 0x60 //Chip Erase(or 0xC7) + #define FLASH_CMD_PP 0x02 //Page Program + #define FLASH_CMD_DP 0xB9 //Deep Power Down + #define FLASH_CMD_RDP 0xAB //Release from Deep Power-Down + #define FLASH_CMD_2READ 0xBB // 2 x I/O read command + #define FLASH_CMD_4READ 0xEB // 4 x I/O read command + #define FLASH_CMD_QREAD 0x6B // 1I / 4O read command + #define FLASH_CMD_4PP 0x38 //quad page program + #define FLASH_CMD_FF 0xFF //Release Read Enhanced + #define FLASH_CMD_REMS2 0xEF // read ID for 2x I/O mode + #define FLASH_CMD_REMS4 0xDF // read ID for 4x I/O mode + #define FLASH_CMD_ENSO 0xB1 // enter secured OTP + #define FLASH_CMD_EXSO 0xC1 // exit secured OTP + #define FLASH_CMD_RDSCUR 0x2B // read security register + #define FLASH_CMD_WRSCUR 0x2F // write security register +#endif //#if FLASH_MXIC_MX25L4006E +#endif +// ============================ + +// ===== Flash Parameter Definition ===== +//#if FLASH_MICRON_N25Q512A +#if 0 +#define FLASH_RD_2IO_EN 1 +#define FLASH_RD_2O_EN 1 +#define FLASH_RD_4IO_EN 1 +#define FLASH_RD_4O_EN 1 +#define FLASH_WR_2IO_EN 1 +#define FLASH_WR_2O_EN 1 +#define FLASH_WR_4IO_EN 1 +#define FLASH_WR_4O_EN 1 +#endif +#define FLASH_DM_CYCLE_2O 0x08 // 1-1-2 +#define FLASH_DM_CYCLE_2IO 0x04 // 1-2-2 +#define FLASH_DM_CYCLE_4O 0x08 // 1-1-4 +#define FLASH_DM_CYCLE_4IO 0x08 // 1-4-4 +#define FLASH_VLD_DUAL_CMDS (BIT_WR_BLOCKING | BIT_RD_DUAL_I)// 1-1-2 +#define FLASH_VLD_QUAD_CMDS (BIT_WR_BLOCKING | BIT_RD_QUAD_IO)// 1-4-4 +#define FLASH_VLD_QUAD_CMDS2 (BIT_WR_BLOCKING | BIT_RD_QUAD_O)// 1-1-4 + + +//#endif + +#if 0 +#if FLASH_MXIC_MX25L4006E +#define FLASH_RD_2IO_EN 1 +#define FLASH_RD_2O_EN 0 +#define FLASH_RD_4IO_EN 1 +#define FLASH_RD_4O_EN 0 +#define FLASH_WR_2IO_EN 1 +#define FLASH_WR_2O_EN 0 +#define FLASH_WR_4IO_EN 1 +#define FLASH_WR_4O_EN 0 +#define FLASH_DM_CYCLE_2O 0x04 // 1-1-2 +#define FLASH_DM_CYCLE_2IO 0x08 // 1-2-2 +#define FLASH_DM_CYCLE_4O 0x04 // 1-1-4 +#define FLASH_DM_CYCLE_4IO 0x08 // 1-4-4 +#define FLASH_VLD_DUAL_CMDS (BIT_WR_BLOCKING | BIT_WR_DUAL_II | BIT_RD_DUAL_IO) +#define FLASH_VLD_QUAD_CMDS (BIT_WR_BLOCKING | BIT_WR_QUAD_II | BIT_RD_QUAD_IO) + +#elif FLASH_MXIC_MX25L8073E //This flash model is just for prototype, if you want to use it, + //the code MUST be rechecked according to the flash spec. + #define FLASH_RD_2IO_EN 1 + #define FLASH_RD_2O_EN 0 + #define FLASH_RD_4IO_EN 1 + #define FLASH_RD_4O_EN 0 + #define FLASH_WR_2IO_EN 1 + #define FLASH_WR_2O_EN 0 + #define FLASH_WR_4IO_EN 1 + #define FLASH_WR_4O_EN 0 + + #define FLASH_DM_CYCLE_2O 0x08 + #define FLASH_DM_CYCLE_2IO 0x04 + #define FLASH_DM_CYCLE_4O 0x08 + #define FLASH_DM_CYCLE_4IO 0x04 + + #define FLASH_VLD_DUAL_CMDS (BIT_WR_BLOCKING | BIT_RD_DUAL_IO) + #define FLASH_VLD_QUAD_CMDS (BIT_WR_BLOCKING | BIT_WR_QUAD_II | BIT_RD_QUAD_IO) +#else + #define FLASH_RD_2IO_EN 1 + #define FLASH_RD_2O_EN 0 + #define FLASH_RD_4IO_EN 1 + #define FLASH_RD_4O_EN 0 + #define FLASH_WR_2IO_EN 1 + #define FLASH_WR_2O_EN 0 + #define FLASH_WR_4IO_EN 1 + #define FLASH_WR_4O_EN 0 + + #define FLASH_DM_CYCLE_2O 0x08 + #define FLASH_DM_CYCLE_2IO 0x04 + #define FLASH_DM_CYCLE_4O 0x08 + #define FLASH_DM_CYCLE_4IO 0x04 + + #define FLASH_VLD_DUAL_CMDS (BIT_WR_BLOCKING | BIT_RD_DUAL_IO) + #define FLASH_VLD_QUAD_CMDS (BIT_WR_BLOCKING | BIT_WR_QUAD_II | BIT_RD_QUAD_IO) +#endif +#endif +#if 0 +//====================================================== +// Function prototype +BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode); + +_LONG_CALL_ +extern VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); + +// spi-flash controller initialization +_LONG_CALL_ +extern VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode); + +// wait sr[0] = 0, wait transmission done +_LONG_CALL_ +extern VOID SpicWaitBusyDoneRtl8195A(VOID); + +// wait spi-flash status register[0] = 0 +//_LONG_CALL_ +//extern VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); +#endif + +//====================================================== +// ROM Function prototype +_LONG_CALL_ VOID SpiFlashAppV02(IN VOID *Data); +_LONG_CALL_ROM_ VOID SpicInitRtl8195AV02(IN u8 InitBaudRate,IN u8 SpicBitMode); + +_LONG_CALL_ROM_ VOID SpicEraseFlashRtl8195AV02(VOID); + +_LONG_CALL_ROM_ VOID SpicLoadInitParaFromClockRtl8195AV02(IN u8 CpuClkMode,IN u8 BaudRate,IN PSPIC_INIT_PARA pSpicInitPara); + + +VOID SpicBlockEraseFlashRtl8195A(IN u32 Address); +VOID SpicSectorEraseFlashRtl8195A(IN u32 Address); +VOID SpicDieEraseFlashRtl8195A(IN u32 Address); +VOID SpicWriteProtectFlashRtl8195A(IN u32 Protect); +VOID SpicWaitWipDoneRefinedRtl8195A(IN SPIC_INIT_PARA SpicInitPara); +VOID SpicWaitOperationDoneRtl8195A(IN SPIC_INIT_PARA SpicInitPara); +VOID SpicRxCmdRefinedRtl8195A(IN u8 cmd,IN SPIC_INIT_PARA SpicInitPara); +u8 SpicGetFlashStatusRefinedRtl8195A(IN SPIC_INIT_PARA SpicInitPara); +VOID SpicInitRefinedRtl8195A(IN u8 InitBaudRate, IN u8 SpicBitMode); +u32 SpicWaitWipRtl8195A(VOID); // IN SPIC_INIT_PARA SpicInitPara); +u32 SpicOneBitCalibrationRtl8195A(IN u8 SysCpuClk); +VOID SpicDisableRtl8195A(VOID); +VOID SpicDeepPowerDownFlashRtl8195A(VOID); +VOID SpicUserProgramRtl8195A(IN u8 * data, IN SPIC_INIT_PARA SpicInitPara, IN u32 addr, IN u32 * LengthInfo); +VOID SpicUserReadRtl8195A(IN u32 Length, IN u32 addr, IN u8 * data, IN u8 BitMode); +VOID SpicUserReadFourByteRtl8195A(IN u32 Length, IN u32 addr, IN u32 * data, IN u8 BitMode); +VOID SpicReadIDRtl8195A(VOID); +VOID SpicSetFlashStatusRefinedRtl8195A(IN u32 data, IN SPIC_INIT_PARA SpicInitPara); +VOID SpicSetExtendAddrRtl8195A(IN u32 data, IN SPIC_INIT_PARA SpicInitPara); +u8 SpicGetExtendAddrRtl8195A(IN SPIC_INIT_PARA SpicInitPara); +#if SPIC_CALIBRATION_IN_NVM +VOID SpicNVMCalLoad(u8 BitMode, u8 CpuClk); +VOID SpicNVMCalLoadAll(void); +VOID SpicNVMCalStore(u8 BitMode, u8 CpuClk); +#endif // #if SPIC_CALIBRATION_IN_NVM + +#endif //_HAL_SPIFLASH__ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_ssi.h b/USDK/component/soc/realtek/8195a/fwlib/hal_ssi.h new file mode 100644 index 0000000..64d13cf --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_ssi.h @@ -0,0 +1,336 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_SSI_H_ +#define _HAL_SSI_H_ + +#include "rtl8195a_ssi.h" + +/** + * LOG Configurations + */ + +extern u32 SSI_DBG_CONFIG; +extern uint8_t SPI0_IS_AS_SLAVE; + + +#define SSI_DBG_ENTRANCE(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_ENTRANCE)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE ANSI_COLOR_GREEN __VA_ARGS__ ANSI_COLOR_RESET); \ +}while(0) + +#define SSI_DBG_INIT(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INIT)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INIT_V(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INIT_V)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INIT_VV(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INIT_VV)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_PINMUX(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_PINMUX)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_ENDIS(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_ENDIS)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INT(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INT)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INT_V(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INT_V)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INT_HNDLR(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INT_HNDLR)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INT_READ(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INT_READ)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_INT_WRITE(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_INT_WRITE)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_STATUS(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_STATUS)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_FIFO(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_FIFO)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_READ(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_READ)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_WRITE(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_WRITE)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +#define SSI_DBG_SLV_CTRL(...) do {\ + if (unlikely(SSI_DBG_CONFIG & DBG_TYPE_SLV_CTRL)) \ + DBG_SSI_INFO(IDENT_FOUR_SPACE __VA_ARGS__); \ +}while(0) + +typedef enum _SSI_DBG_TYPE_LIST_ { + DBG_TYPE_ENTRANCE = 1 << 0, + DBG_TYPE_INIT = 1 << 1, + DBG_TYPE_INIT_V = 1 << 2, + DBG_TYPE_INIT_VV = 1 << 3, + DBG_TYPE_PINMUX = 1 << 4, + DBG_TYPE_ENDIS = 1 << 5, + DBG_TYPE_INT = 1 << 6, + DBG_TYPE_INT_V = 1 << 7, + DBG_TYPE_INT_HNDLR = 1 << 8, + DBG_TYPE_INT_READ = 1 << 9, + DBG_TYPE_INT_WRITE = 1 << 10, + DBG_TYPE_STATUS = 1 << 11, + DBG_TYPE_FIFO = 1 << 12, + DBG_TYPE_READ = 1 << 13, + DBG_TYPE_WRITE = 1 << 14, + DBG_TYPE_SLV_CTRL = 1 << 15 +} SSI_DBG_TYPE_LIST, *PSSI_DBG_TYPE_LIST; + + typedef struct _SSI_DMA_CONFIG_ { + VOID *pHalGdmaOp; + VOID *pTxHalGdmaAdapter; + VOID *pRxHalGdmaAdapter; + u8 RxDmaBurstSize; + u8 TxDmaBurstSize; + u8 RxDmaEnable; + u8 TxDmaEnable; + IRQ_HANDLE RxGdmaIrqHandle; + IRQ_HANDLE TxGdmaIrqHandle; +}SSI_DMA_CONFIG, *PSSI_DMA_CONFIG; + +#ifdef CONFIG_GDMA_EN +typedef struct _HAL_SSI_DMA_MULTIBLK_ { + volatile GDMA_CH_LLI_ELE GdmaChLli[16]; + struct GDMA_CH_LLI Lli[16]; + struct BLOCK_SIZE_LIST BlockSizeList[16]; +}SSI_DMA_MULTIBLK, *PSSI_DMA_MULTIBLK; +#endif +/** + * DesignWare SSI Configurations + */ +typedef struct _HAL_SSI_ADAPTOR_ { + SSI_DMA_CONFIG DmaConfig; + IRQ_HANDLE IrqHandle; + // + VOID (*RxCompCallback)(VOID *Para); + VOID *RxCompCbPara; + VOID *RxData; + VOID (*TxCompCallback)(VOID *Para); + VOID *TxCompCbPara; + VOID *TxData; + u32 DmaRxDataLevel; + u32 DmaTxDataLevel; + u32 InterruptPriority; + u32 RxLength; + u32 RxLengthRemainder; + u32 RxThresholdLevel; + u32 TxLength; + u32 TxThresholdLevel; + u32 SlaveSelectEnable; + // + u16 ClockDivider; + u16 DataFrameNumber; + // + u8 ControlFrameSize; + u8 DataFrameFormat; + u8 DataFrameSize; + u8 DmaControl; + u8 Index; + u8 InterruptMask; + u8 MicrowireDirection; + u8 MicrowireHandshaking; + u8 MicrowireTransferMode; + u8 PinmuxSelect; + u8 Role; + u8 SclkPhase; + u8 SclkPolarity; + u8 SlaveOutputEnable; + u8 TransferMode; + u8 TransferMechanism; + + // Extend + u8 Reserve; + u8 HaveTxChannel; + u8 HaveRxChannel; + u8 DefaultRxThresholdLevel; + #ifdef CONFIG_GDMA_EN + SSI_DMA_MULTIBLK DmaTxMultiBlk, DmaRxMultiBlk; + #endif + u32 ReservedDummy; + VOID (*TxIdleCallback)(VOID *Para); + VOID *TxIdleCbPara; +}HAL_SSI_ADAPTOR, *PHAL_SSI_ADAPTOR; + +typedef struct _HAL_SSI_OP_{ + HAL_Status (*HalSsiPinmuxEnable)(VOID *Adaptor); + HAL_Status (*HalSsiPinmuxDisable)(VOID *Adaptor); + HAL_Status (*HalSsiEnable)(VOID *Adaptor); + HAL_Status (*HalSsiDisable)(VOID *Adaptor); + HAL_Status (*HalSsiInit)(VOID *Adaptor); + HAL_Status (*HalSsiSetSclkPolarity)(VOID *Adaptor); + HAL_Status (*HalSsiSetSclkPhase)(VOID *Adaptor); + HAL_Status (*HalSsiWrite)(VOID *Adaptor, u32 value); + HAL_Status (*HalSsiLoadSetting)(VOID *Adaptor, VOID *Setting); + HAL_Status (*HalSsiSetInterruptMask)(VOID *Adaptor); + HAL_Status (*HalSsiSetDeviceRole)(VOID *Adaptor, u32 Role); + HAL_Status (*HalSsiInterruptEnable)(VOID *Adaptor); + HAL_Status (*HalSsiInterruptDisable)(VOID *Adaptor); + HAL_Status (*HalSsiReadInterrupt)(VOID *Adaptor, VOID *RxData, u32 Length); + HAL_Status (*HalSsiSetRxFifoThresholdLevel)(VOID *Adaptor); + HAL_Status (*HalSsiSetTxFifoThresholdLevel)(VOID *Adaptor); + HAL_Status (*HalSsiWriteInterrupt)(VOID *Adaptor, u8 *TxData, u32 Length); + HAL_Status (*HalSsiSetSlaveEnableRegister)(VOID *Adaptor, u32 SlaveIndex); + u32 (*HalSsiBusy)(VOID *Adaptor); + u32 (*HalSsiReadable)(VOID *Adaptor); + u32 (*HalSsiWriteable)(VOID *Adaptor); + u32 (*HalSsiGetInterruptMask)(VOID *Adaptor); + u32 (*HalSsiGetRxFifoLevel)(VOID *Adaptor); + u32 (*HalSsiGetTxFifoLevel)(VOID *Adaptor); + u32 (*HalSsiGetStatus)(VOID *Adaptor); + u32 (*HalSsiGetInterruptStatus)(VOID *Adaptor); + u32 (*HalSsiRead)(VOID *Adaptor); + u32 (*HalSsiGetRawInterruptStatus)(VOID *Adaptor); + u32 (*HalSsiGetSlaveEnableRegister)(VOID *Adaptor); +}HAL_SSI_OP, *PHAL_SSI_OP; + +typedef struct _DW_SSI_DEFAULT_SETTING_ { + VOID (*RxCompCallback)(VOID *Para); + VOID *RxCompCbPara; + VOID *RxData; + VOID (*TxCompCallback)(VOID *Para); + VOID *TxCompCbPara; + VOID *TxData; + u32 DmaRxDataLevel; + u32 DmaTxDataLevel; + u32 InterruptPriority; + u32 RxLength; + u32 RxLengthRemainder; + u32 RxThresholdLevel; + u32 TxLength; + u32 TxThresholdLevel; + u32 SlaveSelectEnable; + // + u16 ClockDivider; + u16 DataFrameNumber; + // + u8 ControlFrameSize; + u8 DataFrameFormat; + u8 DataFrameSize; + u8 DmaControl; + //u8 Index; + u8 InterruptMask; + u8 MicrowireDirection; + u8 MicrowireHandshaking; + u8 MicrowireTransferMode; + //u8 PinmuxSelect; + //u8 Role; + u8 SclkPhase; + u8 SclkPolarity; + u8 SlaveOutputEnable; + u8 TransferMode; + u8 TransferMechanism; +} DW_SSI_DEFAULT_SETTING, *PDW_SSI_DEFAULT_SETTING; + + +struct spi_s { + HAL_SSI_ADAPTOR spi_adp; + HAL_SSI_OP spi_op; + u32 irq_handler; + u32 irq_id; + u32 dma_en; + u32 state; + u8 sclk; +#ifdef CONFIG_GDMA_EN + HAL_GDMA_ADAPTER spi_gdma_adp_tx; + HAL_GDMA_ADAPTER spi_gdma_adp_rx; +#endif + u32 bus_tx_done_handler; + u32 bus_tx_done_irq_id; +}; + +VOID HalSsiOpInit(VOID *Adaptor); +static __inline__ VOID HalSsiSetSclk( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter, + IN u32 ClkRate) +{ + HalSsiSetSclkRtl8195a((VOID*)pHalSsiAdapter, ClkRate); +} + +HAL_Status HalSsiInit(VOID * Data); +HAL_Status HalSsiDeInit(VOID * Data); +HAL_Status HalSsiEnable(VOID * Data); +HAL_Status HalSsiDisable(VOID * Data); +HAL_Status HalSsiEnterCritical(VOID * Data); +HAL_Status HalSsiExitCritical(VOID * Data); +HAL_Status HalSsiTimeout(u32 StartCount, u32 TimeoutCnt); +HAL_Status HalSsiStopRecv(VOID * Data); +HAL_Status HalSsiSetFormat(VOID * Data); +#ifdef CONFIG_GDMA_EN +HAL_Status HalSsiTxGdmaInit(PHAL_SSI_OP pHalSsiOp, PHAL_SSI_ADAPTOR pHalSsiAdapter); +VOID HalSsiTxGdmaDeInit(PHAL_SSI_ADAPTOR pHalSsiAdapter); +HAL_Status HalSsiRxGdmaInit(PHAL_SSI_OP pHalSsiOp, PHAL_SSI_ADAPTOR pHalSsiAdapter); +VOID HalSsiRxGdmaDeInit(PHAL_SSI_ADAPTOR pHalSsiAdapter); +HAL_Status HalSsiRxMultiBlkChnl(PHAL_SSI_ADAPTOR pHalSsiAdapter); +HAL_Status HalSsiDmaRecv(VOID * Adapter, u8 * pRxData, u32 Length); +HAL_Status HalSsiDmaSend(VOID *Adapter, u8 *pTxData, u32 Length); + +static __inline__ VOID +HalSsiDmaInit( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + #if CONFIG_CHIP_E_CUT + HalSsiDmaInitRtl8195a_V04((void *)pHalSsiAdapter); + #else + HalSsiDmaInitRtl8195a((void *)pHalSsiAdapter); + #endif +} +/* +static __inline__ HAL_Status HalSsiDmaSend(VOID *Adapter, u8 *pTxData, u32 Length) +{ + return (HalSsiDmaSendRtl8195a(Adapter, pTxData, Length)); +} + +static __inline__ HAL_Status HalSsiDmaRecv(VOID *Adapter, u8 *pRxData, u32 Length) +{ + return (HalSsiDmaRecvRtl8195a(Adapter, pRxData, Length)); +} +*/ + +#endif // end of "#ifdef CONFIG_GDMA_EN" + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_timer.h b/USDK/component/soc/realtek/8195a/fwlib/hal_timer.h new file mode 100644 index 0000000..750b346 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_timer.h @@ -0,0 +1,96 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_TIMER_H_ +#define _HAL_TIMER_H_ +#include "basic_types.h" +#include "hal_platform.h" +#include "rtl8195a_timer.h" + +#define GTIMER_CLK_HZ (32768) +#define GTIMER_TICK_US (1000000/GTIMER_CLK_HZ) + +typedef enum _TIMER_MODE_ { + FREE_RUN_MODE = 0, + USER_DEFINED = 1 +}TIMER_MODE, *PTIMER_MODE; + + +typedef struct _TIMER_ADAPTER_ { + + u32 TimerLoadValueUs; //+00 + u32 TimerIrqPriority; //+04 + TIMER_MODE TimerMode; //+08 + IRQ_HANDLE IrqHandle; //+0c + u8 TimerId; //+1c? + u8 IrqDis; //+1d? + +}TIMER_ADAPTER, *PTIMER_ADAPTER; + + +typedef struct _HAL_TIMER_OP_ { + u32 (*HalGetTimerId)(u32 *TimerId); //+00 + BOOL (*HalTimerInit)(VOID *Data); //+04 + u32 (*HalTimerReadCount)(u32 TimerId); //+08 + VOID (*HalTimerIrqClear)(u32 TimerId); //+0c + VOID (*HalTimerDis)(u32 TimerId); //+10 + VOID (*HalTimerEn)(u32 TimerId); //+14 + VOID (*HalTimerDumpReg)(u32 TimerId); //+18 +}HAL_TIMER_OP, *PHAL_TIMER_OP; + +#ifdef CONFIG_TIMER_MODULE +// This variable declared in ROM code +extern HAL_TIMER_OP HalTimerOp; +#endif + +VOID HalTimerOpInit_Patch( + IN VOID *Data +); + + +//====================================================== +// ROM Function prototype +_LONG_CALL_ VOID HalTimerOpInitV02(IN VOID *Data); + +#ifndef CONFIG_RELEASE_BUILD_LIBRARIES +#define HalTimerOpInit HalTimerOpInit_Patch +#endif + +#ifdef CONFIG_RELEASE_BUILD_LIBRARIES +void HalTimerOpInit( + void *Data +); + +HAL_Status +HalTimerInit( + void *Data +); + +void +HalTimerEnable( + uint32_t TimerId +); + +void +HalTimerDisable( + uint32_t TimerId +); + +void +HalTimerReLoad( + uint32_t TimerId, + uint32_t LoadUs +); + +void +HalTimerDeInit( + void *Data +); +#endif // #ifdef CONFIG_RELEASE_BUILD_LIBRARIES +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_uart.h b/USDK/component/soc/realtek/8195a/fwlib/hal_uart.h new file mode 100644 index 0000000..06f6c3b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_uart.h @@ -0,0 +1,257 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_UART_H_ +#define _HAL_UART_H_ + +#include "rtl8195a_uart.h" + +/** + * RUART Configurations + */ +#define UART_WAIT_FOREVER 0xffffffff + +#define UART_DMA_MBLK_NUM 16 // maximum block number for each DMA transfer, it must <= 16 +#define UART_DMA_BLOCK_SIZE 4092 // the block size of multiple block DMA, it cann0t over 4095 + +typedef struct _HAL_UART_DMA_MULTIBLK_ { + volatile GDMA_CH_LLI_ELE GdmaChLli[UART_DMA_MBLK_NUM]; + struct GDMA_CH_LLI Lli[UART_DMA_MBLK_NUM]; + struct BLOCK_SIZE_LIST BlockSizeList[UART_DMA_MBLK_NUM]; +}UART_DMA_MULTIBLK, *PUART_DMA_MULTIBLK; + +typedef struct _UART_DMA_CONFIG_ { + u8 TxDmaEnable; + u8 RxDmaEnable; + u8 TxDmaBurstSize; + u8 RxDmaBurstSize; + VOID *pHalGdmaOp; + VOID *pTxHalGdmaAdapter; + VOID *pRxHalGdmaAdapter; + IRQ_HANDLE TxGdmaIrqHandle; + IRQ_HANDLE RxGdmaIrqHandle; +#if defined(E_CUT_ROM_DOMAIN) || (!defined(CONFIG_RELEASE_BUILD_LIBRARIES)) + UART_DMA_MULTIBLK *pTxDmaBlkList; // point to multi-block list + UART_DMA_MULTIBLK *pRxDmaBlkList; // point to multi-block list + u8 TxDmaMBChnl; // is using DMA multiple block channel + u8 RxDmaMBChnl; // is using DMA multiple block channel +#endif +}UART_DMA_CONFIG, *PUART_DMA_CONFIG; + +typedef struct _HAL_RUART_ADAPTER_ { + u32 BaudRate; + u32 FlowControl; + u32 FifoControl; + u32 Interrupts; + u32 TxCount; // how many byte to TX + u32 RxCount; // how many bytes to RX + u8 *pTxBuf; + u8 *pRxBuf; + HAL_UART_State State; // UART state + u8 Status; // Transfer Status + u8 Locked; // is UART locked for operation + u8 UartIndex; + u8 WordLen; // word length select: 0 -> 7 bits, 1 -> 8 bits + u8 StopBit; // word length select: 0 -> 1 stop bit, 1 -> 2 stop bit + u8 Parity; // parity check enable + u8 ParityType; // parity check type + u8 StickParity; + u8 ModemStatus; // the modem status + u8 DmaEnable; + u8 TestCaseNumber; + u8 PinmuxSelect; + BOOL PullMode; + IRQ_HANDLE IrqHandle; + PUART_DMA_CONFIG DmaConfig; + VOID (*ModemStatusInd)(VOID *pAdapter); // modem status indication interrupt handler + VOID (*TxTDCallback)(VOID *pAdapter); // User Tx Done callback function + VOID (*RxDRCallback)(VOID *pAdapter); // User Rx Data ready callback function + VOID (*TxCompCallback)(VOID *para); // User Tx complete callback function + VOID (*RxCompCallback)(VOID *para); // User Rx complete callback function + VOID *TxTDCbPara; // the pointer agrument for TxTDCallback + VOID *RxDRCbPara; // the pointer agrument for RxDRCallback + VOID *TxCompCbPara; // the pointer argument for TxCompCbPara + VOID *RxCompCbPara; // the pointer argument for RxCompCallback + VOID (*EnterCritical)(void); + VOID (*ExitCritical)(void); + +#if defined(E_CUT_ROM_DOMAIN) || (!defined(CONFIG_RELEASE_BUILD_LIBRARIES)) + //1 New member only can be added below: members above must be fixed for ROM code + u32 *pDefaultBaudRateTbl; // point to the table of pre-defined baud rate + u8 *pDefaultOvsrRTbl; // point to the table of OVSR for pre-defined baud rate + u16 *pDefaultDivTbl; // point to the table of DIV for pre-defined baud rate + u8 *pDefOvsrAdjBitTbl_10; // point to the table of OVSR-Adj bits for 10 bits + u8 *pDefOvsrAdjBitTbl_9; // point to the table of OVSR-Adj bits for 9 bits + u8 *pDefOvsrAdjBitTbl_8; // point to the table of OVSR-Adj bits for 8 bits + u16 *pDefOvsrAdjTbl_10; // point to the table of OVSR-Adj for pre-defined baud rate + u16 *pDefOvsrAdjTbl_9; // point to the table of OVSR-Adj for pre-defined baud rate + u16 *pDefOvsrAdjTbl_8; // point to the table of OVSR-Adj for pre-defined baud rate + PUART_DMA_MULTIBLK pTxDMAMBlk; // point to the Link List Table of the DMA Multiple Block + PUART_DMA_MULTIBLK pRxDMAMBlk; // point to the Link List Table of the DMA Multiple Block + u32 BaudRateUsing; // Current using Baud-Rate + u8 WordLenUsing; // Current using Word Length + u8 ParityUsing; // Current using Parity check + u8 RTSCtrl; // Software RTS Control + +#if 0//CONFIG_CHIP_E_CUT + u8 TxState; + u8 RxState; + u32 TxInitSize; // how many byte to TX at atart + u32 RxInitSize; // how many bytes to RX at start + + VOID (*RuartEnterCritical)(VOID *para); // enter critical: disable UART interrupt + VOID (*RuartExitCritical)(VOID *para); // exit critical: re-enable UART interrupt + VOID (*TaskYield)(VOID *para); // User Task Yield: do a context switch while waitting + VOID *TaskYieldPara; // the agrument (pointer) for TaskYield +#endif // #if CONFIG_CHIP_E_CUT +#endif +}HAL_RUART_ADAPTER, *PHAL_RUART_ADAPTER; + +typedef struct _HAL_RUART_OP_ { + VOID (*HalRuartAdapterLoadDef)(VOID *pAdp, u8 UartIdx); // Load UART adapter default setting + VOID (*HalRuartTxGdmaLoadDef)(VOID *pAdp, VOID *pCfg); // Load TX GDMA default setting + VOID (*HalRuartRxGdmaLoadDef)(VOID *pAdp, VOID *pCfg); // Load RX GDMA default setting + HAL_Status (*HalRuartResetRxFifo)(VOID *Data); + HAL_Status (*HalRuartInit)(VOID *Data); + VOID (*HalRuartDeInit)(VOID *Data); + HAL_Status (*HalRuartPutC)(VOID *Data, u8 TxData); + u32 (*HalRuartSend)(VOID *Data, u8 *pTxData, u32 Length, u32 Timeout); + HAL_Status (*HalRuartIntSend)(VOID *Data, u8 *pTxData, u32 Length); + HAL_Status (*HalRuartDmaSend)(VOID *Data, u8 *pTxData, u32 Length); + HAL_Status (*HalRuartStopSend)(VOID *Data); + HAL_Status (*HalRuartGetC)(VOID *Data, u8 *pRxByte); + u32 (*HalRuartRecv)(VOID *Data, u8 *pRxData, u32 Length, u32 Timeout); + HAL_Status (*HalRuartIntRecv)(VOID *Data, u8 *pRxData, u32 Length); + HAL_Status (*HalRuartDmaRecv)(VOID *Data, u8 *pRxData, u32 Length); + HAL_Status (*HalRuartStopRecv)(VOID *Data); + u8 (*HalRuartGetIMR)(VOID *Data); + VOID (*HalRuartSetIMR)(VOID *Data); + u32 (*HalRuartGetDebugValue)(VOID *Data, u32 DbgSel); + VOID (*HalRuartDmaInit)(VOID *Data); + VOID (*HalRuartRTSCtrl)(VOID *Data, BOOLEAN RtsCtrl); + VOID (*HalRuartRegIrq)(VOID *Data); + VOID (*HalRuartIntEnable)(VOID *Data); + VOID (*HalRuartIntDisable)(VOID *Data); +}HAL_RUART_OP, *PHAL_RUART_OP; + +typedef struct _RUART_DATA_ { + PHAL_RUART_ADAPTER pHalRuartAdapter; + BOOL PullMode; + u8 BinaryData; + u8 SendBuffer; + u8 RecvBuffer; +}RUART_DATA, *PRUART_DATA; + +typedef struct _RUART_ADAPTER_ { + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter; + PUART_DMA_CONFIG pHalRuartDmaCfg; +}RUART_ADAPTER, *PRUART_ADAPTER; + +extern VOID +HalRuartOpInit( + IN VOID *Data +); + +extern HAL_Status +HalRuartTxGdmaInit( + PHAL_RUART_ADAPTER pHalRuartAdapter, + PUART_DMA_CONFIG pUartGdmaConfig, + u8 IsMultiBlk +); + +extern VOID +HalRuartTxGdmaDeInit( + PUART_DMA_CONFIG pUartGdmaConfig +); + +extern HAL_Status +HalRuartRxGdmaInit( + PHAL_RUART_ADAPTER pHalRuartAdapter, + PUART_DMA_CONFIG pUartGdmaConfig, + u8 IsMultiBlk +); + +extern VOID +HalRuartRxGdmaDeInit( + PUART_DMA_CONFIG pUartGdmaConfig +); + +extern HAL_Status +HalRuartResetTxFifo( + VOID *Data +); + +extern HAL_Status HalRuartResetTRxFifo(IN VOID *Data); + +extern HAL_Status +HalRuartResetRxFifo( + IN VOID *Data +); + +extern HAL_Status +HalRuartSetBaudRate( + IN VOID *Data +); + +extern HAL_Status +HalRuartInit( + IN VOID *Data +); + +extern VOID +HalRuartDeInit( + IN VOID *Data +); + +extern HAL_Status +HalRuartDisable( + IN VOID *Data +); + +extern HAL_Status +HalRuartEnable( + IN VOID *Data +); + +HAL_Status +HalRuartFlowCtrl( + IN VOID *Data +); + +VOID +HalRuartEnterCritical( + IN VOID *Data +); + +VOID +HalRuartExitCritical( + IN VOID *Data +); + +HAL_Status +HalRuartDmaSend( + IN VOID *Data, + IN u8 *pTxBuf, + IN u32 Length +); + +HAL_Status +HalRuartDmaRecv( + IN VOID *Data, + IN u8 *pRxBuf, + IN u32 Length +); + +extern const HAL_RUART_OP _HalRuartOp; +extern HAL_Status RuartLock (PHAL_RUART_ADAPTER pHalRuartAdapter); +extern VOID RuartUnLock (PHAL_RUART_ADAPTER pHalRuartAdapter); + +#endif + diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_usb.h b/USDK/component/soc/realtek/8195a/fwlib/hal_usb.h new file mode 100644 index 0000000..3de8fa2 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_usb.h @@ -0,0 +1,15 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_USB_H_ +#define _HAL_USB_H_ + +#include "rtl8195a_usb.h" + +#endif //_HAL_USB_H_ \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_util.h b/USDK/component/soc/realtek/8195a/fwlib/hal_util.h new file mode 100644 index 0000000..612ac0e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_util.h @@ -0,0 +1,252 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#ifndef _HAL_UTIL_H_ +#define _HAL_UTIL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ +struct LIST_HEADER { + struct LIST_HEADER *Next, *Prev; +}; + +typedef struct LIST_HEADER _LIST; + +//#define RTL_LIST_HEAD_INIT(name) { &(name), &(name) } + +#define RTL_INIT_LIST_HEAD(ptr) do { \ + (ptr)->Next = (ptr); (ptr)->Prev = (ptr); \ +} while (0) + + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ + static __inline__ VOID + __List_Add( + IN struct LIST_HEADER * New, + IN struct LIST_HEADER * Prev, + IN struct LIST_HEADER * Next +) +{ + Next->Prev = New; + New->Next = Next; + New->Prev = Prev; + Prev->Next = New; +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ + static __inline__ VOID + __List_Del( + IN struct LIST_HEADER * Prev, + IN struct LIST_HEADER * Next + ) +{ + Next->Prev = Prev; + Prev->Next = Next; +} + +/** + * ListDel - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static __inline__ VOID +ListDel( + IN struct LIST_HEADER *Entry +) +{ + __List_Del(Entry->Prev, Entry->Next); +} + +/** + * ListDelInit - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline__ VOID +ListDelInit( + IN struct LIST_HEADER *Entry +) +{ + __List_Del(Entry->Prev, Entry->Next); + RTL_INIT_LIST_HEAD(Entry); + +} + +/** + * ListEmpty - tests whether a list is empty + * @head: the list to test. + */ +static __inline__ u32 +ListEmpty( + IN struct LIST_HEADER *Head +) +{ + return Head->Next == Head; +} + +/** + * ListSplice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static __inline__ VOID +ListSplice( + IN struct LIST_HEADER *List, + IN struct LIST_HEADER *Head +) +{ + struct LIST_HEADER *First = List->Next; + + if (First != List) { + struct LIST_HEADER *Last = List->Prev; + struct LIST_HEADER *At = Head->Next; + + First->Prev = Head; + Head->Next = First; + + Last->Next = At; + At->Prev = Last; + } +} + +static __inline__ VOID +ListAdd( + IN struct LIST_HEADER *New, + IN struct LIST_HEADER *head +) +{ + __List_Add(New, head, head->Next); +} + + +static __inline__ VOID +ListAddTail( + IN struct LIST_HEADER *New, + IN struct LIST_HEADER *head +) +{ + __List_Add(New, head->Prev, head); +} + +static __inline VOID +RtlInitListhead( + IN _LIST *list +) +{ + RTL_INIT_LIST_HEAD(list); +} + + +/* +For the following list_xxx operations, +caller must guarantee the atomic context. +Otherwise, there will be racing condition. +*/ +static __inline u32 +RtlIsListEmpty( + IN _LIST *phead +) +{ + + if (ListEmpty(phead)) + return _TRUE; + else + return _FALSE; + +} + +static __inline VOID +RtlListInsertHead( + IN _LIST *plist, + IN _LIST *phead +) +{ + ListAdd(plist, phead); +} + +static __inline VOID +RtlListInsertTail( + IN _LIST *plist, + IN _LIST *phead +) +{ + ListAddTail(plist, phead); +} + + +static __inline _LIST +*RtlListGetNext( + IN _LIST *plist +) +{ + return plist->Next; +} + +static __inline VOID +RtlListDelete( + IN _LIST *plist +) +{ + ListDelInit(plist); +} + +#define RTL_LIST_CONTAINOR(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) + +#ifndef CONTAINER_OF +#define CONTAINER_OF(ptr, type, member) \ + ((type *)((char *)(ptr)-(SIZE_T)(&((type *)0)->member))) +#endif +#if 0 +#define list_entry(ptr, type, member) \ + CONTAINER_OF(ptr, type, member) + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->Next, type, member) + +#define list_next_entry(pos, member, type) \ + list_entry((pos)->member.Next, type, member) + +#define list_for_each_entry(pos, head, member, type) \ + for (pos = list_first_entry(head, type, member); \ + &pos->member != (head); \ + pos = list_next_entry(pos, member, type)) +#define list_for_each(pos, head) \ + for (pos = (head)->Next; pos != (head); pos = pos->Next) +#endif + +#ifndef BIT + #define BIT(x) ( 1 << (x)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif //_HAL_UTIL_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/hal_vector_table.h b/USDK/component/soc/realtek/8195a/fwlib/hal_vector_table.h new file mode 100644 index 0000000..e1eb2fb --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/hal_vector_table.h @@ -0,0 +1,53 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _HAL_VECTOR_TABLE_H_ +#define _HAL_VECTOR_TABLE_H_ + + + + +extern _LONG_CALL_ROM_ VOID +VectorTableInitRtl8195A( + IN u32 StackP +); + +extern _LONG_CALL_ROM_ VOID +VectorTableInitForOSRtl8195A( + IN VOID *PortSVC, + IN VOID *PortPendSVH, + IN VOID *PortSysTick +); + +extern _LONG_CALL_ROM_ BOOL +VectorIrqRegisterRtl8195A( + IN PIRQ_HANDLE pIrqHandle +); + +extern _LONG_CALL_ROM_ BOOL +VectorIrqUnRegisterRtl8195A( + IN PIRQ_HANDLE pIrqHandle +); + + +extern _LONG_CALL_ROM_ VOID +VectorIrqEnRtl8195A( + IN PIRQ_HANDLE pIrqHandle +); + +extern _LONG_CALL_ROM_ VOID +VectorIrqDisRtl8195A( + IN PIRQ_HANDLE pIrqHandle +); + + +extern _LONG_CALL_ROM_ VOID +HalPeripheralIntrHandle(VOID); +#endif //_HAL_VECTOR_TABLE_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c new file mode 100644 index 0000000..be37a3f --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/fw_loader_main.c @@ -0,0 +1,130 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "build_info.h" +#include "PinNames.h" +#include "serial_api.h" + +extern void serial_init (serial_t *obj, PinName tx, PinName rx); +extern void serial_free (serial_t *obj); +extern void serial_baud (serial_t *obj, int baudrate); +extern void serial_format (serial_t *obj, int data_bits, SerialParity parity, int stop_bits); +extern int main(void); + +void iar_data_init_fw_loader(void); +void fw_loader_main(void);// __attribute__ ((weak)); + +#pragma section=".image2.start.table1" +#pragma section=".fwloader_ram.bss" + +FW_LOADER_START_RAM_FUN_SECTION +RAM_START_FUNCTION gFWLoaderEntryFun0 = {fw_loader_main}; + +u8* __image4_entry_func__; +u8* __image4_validate_code__; +u8* __fwloader_bss_start__; +u8* __fwloader_bss_end__; + +FW_LOADER_VALID_PATTEN_SECTION const u8 RAM_FW_LOADER_VALID_PATTEN[20] = { + 'R', 'T', 'K', 'W', 'i', 'n', 0x0, 0xff, + (FW_VERSION&0xff), ((FW_VERSION >> 8)&0xff), + (FW_SUBVERSION&0xff), ((FW_SUBVERSION >> 8)&0xff), + (FW_CHIP_ID&0xff), ((FW_CHIP_ID >> 8)&0xff), + (FW_CHIP_VER), + (FW_BUS_TYPE), + (FW_INFO_RSV1), + (FW_INFO_RSV2), + (FW_INFO_RSV3), + (FW_INFO_RSV4) +}; +/** + * @brief Main program. + * @param None + * @retval None + */ +void fw_loader_main(void) +{ +#if defined ( __ICCARM__ ) + iar_data_init_fw_loader(); +#endif + u32 Image2Len, Image2Addr, ImageIndex, SpicBitMode, SpicImageIndex; + u32 Image2LoadAddr = 0x13000; + DBG_8195A("===== Enter FW Loader Image ====\n"); + + +#ifdef BOOTLOADER + main(); +#endif + +IGMAE4: + PRAM_START_FUNCTION Image4EntryFun=(PRAM_START_FUNCTION)__image4_entry_func__; + + Image2Len = HAL_READ32(SPI_FLASH_BASE, Image2LoadAddr); + Image2Addr = HAL_READ32(SPI_FLASH_BASE, (Image2LoadAddr+0x4)); + + DBG_8195A("Flash FW Loader:Addr 0x%x, Len %d, Load to SRAM 0x%x\n", Image2LoadAddr, Image2Len, Image2Addr); + + SpicImageIndex = 0; + for (ImageIndex = 0x10 + Image2LoadAddr; ImageIndex < (Image2Len + Image2LoadAddr + 0x10); ImageIndex = ImageIndex + 4) { + HAL_WRITE32(Image2Addr, SpicImageIndex, + HAL_READ32(SPI_FLASH_BASE, ImageIndex)); + + SpicImageIndex += 4; + } + + + +#ifdef CONFIG_SDR_EN + u32 Image3LoadAddr; + u32 Image3Len; + u32 Image3Addr; + + Image3LoadAddr = Image2LoadAddr + Image2Len+0x10; + Image3Len = HAL_READ32(SPI_FLASH_BASE, Image3LoadAddr); + Image3Addr = HAL_READ32(SPI_FLASH_BASE, Image3LoadAddr + 0x4); + + if( (Image3Len==0xFFFFFFFF) || (Image3Len==0) || (Image3Addr!=0x30000000)){ + DBG_8195A("No Image3\n\r"); + }else{ + DBG_8195A("Image3 length: 0x%x, Image3 Addr: 0x%x\n",Image3Len, Image3Addr); + SpicImageIndex = 0; + + for (ImageIndex = 0x10 + Image3LoadAddr; + ImageIndex < (Image3Len + Image3LoadAddr + 0x10); + ImageIndex = ImageIndex + 4) { + HAL_WRITE32(Image3Addr, SpicImageIndex, + HAL_READ32(SPI_FLASH_BASE, ImageIndex)); + + SpicImageIndex += 4; + } + } +#endif + //3 3) Jump to image 4 + DBG_8195A("InfraStart: %p, Img2 Sign %s \n", __image4_entry_func__, (char*)__image4_validate_code__); + if (_strcmp((char *)__image4_validate_code__, "RTKWin")) { + while (1) { + DBG_8195A("Invalid Image4 Signature\n"); + RtlConsolRom(1000);//each delay is 100us + } + } + +#ifdef BOOTLOADER + deinit_platform_bootloader(); +#endif + Image4EntryFun->RamStartFun(); +} + +void iar_data_init_fw_loader(void) +{ + __image4_entry_func__ = (u8*)__section_begin(".image2.start.table1"); + __image4_validate_code__ = __image4_entry_func__+4;//(u8*)__section_begin(".image2.start.table2"); + __fwloader_bss_start__ = (u8*)__section_begin(".fwloader_ram.bss"); + __fwloader_bss_end__ = (u8*)__section_end(".fwloader_ram.bss"); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c new file mode 100644 index 0000000..7c8906b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/hal_misc_v0.c @@ -0,0 +1,359 @@ +#include "rtl8195a.h" + +typedef struct _UART_LOG_BUF_ { + u8 BufCount; //record the input cmd char number. + u8 UARTLogBuf[127]; //record the input command. +} UART_LOG_BUF, *PUART_LOG_BUF; + + + + +typedef struct _UART_LOG_CTL_ { + u8 NewIdx; + u8 SeeIdx; + u8 RevdNo; + u8 EscSTS; + u8 ExecuteCmd; + u8 ExecuteEsc; + u8 BootRdy; + u8 Resvd; + PUART_LOG_BUF pTmpLogBuf; + VOID *pfINPUT; + PCOMMAND_TABLE pCmdTbl; + u32 CmdTblSz; + + u32 CRSTS; + + u8 (*pHistoryBuf)[127]; + + u32 TaskRdy; + u32 Sema; +} UART_LOG_CTL, *PUART_LOG_CTL; + + volatile UART_LOG_CTL UartLogCtl; + + volatile UART_LOG_CTL *pUartLogCtl; + + u8 *ArgvArray[10]; + + UART_LOG_BUF UartLogBuf; + + + u8 UartLogHistoryBuf[5][127]; + +extern VOID +SpicLoadInitParaFromClockRtl8195A +( + IN u8 CpuClkMode, + IN u8 BaudRate, + IN PSPIC_INIT_PARA pSpicInitPara +); + +VOID +PatchSpicInitRtl8195A +( + IN u8 InitBaudRate, + IN u8 SpicBitMode +) +{ + + u32 Value32; + SPIC_INIT_PARA SpicInitPara; + +#ifdef CONFIG_FPGA + SpicInitPara.BaudRate = 1;//FPGASpicInitPara.BaudRate; + SpicInitPara.RdDummyCyle = 1;//FPGASpicInitPara.RdDummyCyle; + SpicInitPara.DelayLine = 0;//FPGASpicInitPara.DelayLine; +#else + u8 CpuClk; + CpuClk = (((u8)(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70))) >> 4); + SpicLoadInitParaFromClockRtl8195A(CpuClk, InitBaudRate, &SpicInitPara); +#endif + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + HAL_SPI_WRITE32(REG_SPIC_BAUDR, BIT_SCKDV(InitBaudRate)); + + HAL_SPI_WRITE32(REG_SPIC_SER, BIT_SER); + + Value32 = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, + ((Value32 & 0xFFFF0000) | BIT_RD_DUMMY_LENGTH(SpicInitPara.RdDummyCyle))); + + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_MEM_CTRL, + ((HAL_READ32(PERI_ON_BASE, REG_PESOC_MEM_CTRL)&0xFFFFFF00)| + SpicInitPara.DelayLine)); + + HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(4)); + + switch (SpicBitMode) { + case SpicOneBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3))))); + break; + + case SpicDualBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) | + (BIT_ADDR_CH(1)|BIT_DATA_CH(1)))); + + break; + + case SpicQuadBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) | + (BIT_ADDR_CH(2)|BIT_DATA_CH(2)))); + break; + + } + + // Enable SPI_FLASH User Mode +// HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); +} + + +#include "hal_timer.h" +extern BOOL +HalTimerInitRtl8195a( + IN VOID *Data +); + +VOID +PatchHalInitPlatformTimer( +VOID +) +{ + TIMER_ADAPTER TimerAdapter; + + OSC32K_CKGEN_CTRL(ON); + GTIMER_FCTRL(ON); + ACTCK_TIMER_CCTRL(ON); + SLPCK_TIMER_CCTRL(ON); + + TimerAdapter.IrqDis = ON; +// TimerAdapter.IrqHandle = (IRQ_FUN)NULL; + TimerAdapter.TimerId = 1; + TimerAdapter.TimerIrqPriority = 0; + TimerAdapter.TimerLoadValueUs = 0; + TimerAdapter.TimerMode = FREE_RUN_MODE; + + HalTimerInitRtl8195a((VOID*) &TimerAdapter); + +} + +#define UART_BAUD_RATE_2400 2400 +#define UART_BAUD_RATE_4800 4800 +#define UART_BAUD_RATE_9600 9600 +#define UART_BAUD_RATE_19200 19200 +#define UART_BAUD_RATE_38400 38400 +#define UART_BAUD_RATE_57600 57600 +#define UART_BAUD_RATE_115200 115200 +#define UART_BAUD_RATE_921600 921600 +#define UART_BAUD_RATE_1152000 1152000 + +#define UART_PARITY_ENABLE 0x08 +#define UART_PARITY_DISABLE 0 + +#define UART_DATA_LEN_5BIT 0x0 +#define UART_DATA_LEN_6BIT 0x1 +#define UART_DATA_LEN_7BIT 0x2 +#define UART_DATA_LEN_8BIT 0x3 + +#define UART_STOP_1BIT 0x0 +#define UART_STOP_2BIT 0x4 + + +extern u32 +HalLogUartInit( + IN LOG_UART_ADAPTER UartAdapter +); + +extern u32 +HalGetCpuClk( + VOID +); + +const u32 StartupCpkClkTbl[]= { + 200000000, + 100000000, + 50000000, + 25000000, + 12500000, + 4000000 +}; + + +u32 +StartupHalGetCpuClk( + VOID +) +{ + u32 CpuType = 0, CpuClk = 0, FreqDown = 0; + + CpuType = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70)) >> 4); + FreqDown = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) & BIT17; + + CpuClk = StartupCpkClkTbl[CpuType]; + + if ( !FreqDown ) { + if ( CpuClk > 4000000 ){ + CpuClk = (CpuClk*5/6); + } + } + + return CpuClk; +} + +u32 +PatchHalLogUartInit( + IN LOG_UART_ADAPTER UartAdapter +) +{ + u32 SetData; + u32 Divisor; + u32 Dlh; + u32 Dll; + u32 SysClock; + + /* + Interrupt enable Register + 7: THRE Interrupt Mode Enable + 2: Enable Receiver Line Status Interrupt + 1: Enable Transmit Holding Register Empty Interrupt + 0: Enable Received Data Available Interrupt + */ + // disable all interrupts + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, 0); + + /* + Line Control Register + 7: DLAB, enable reading and writing DLL and DLH register, and must be cleared after + initial baud rate setup + 3: PEN, parity enable/disable + 2: STOP, stop bit + 1:0 DLS, data length + */ + + // set DLAB bit to 1 + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 0x80); + + // set up buad rate division + +#ifdef CONFIG_FPGA + SysClock = SYSTEM_CLK; + Divisor = (SysClock / (16 * (UartAdapter.BaudRate))); +#else + { + u32 SampleRate,Remaind; + + //SysClock = (HalGetCpuClk()>>2); + SysClock = (StartupHalGetCpuClk()>>2); + + SampleRate = (16 * (UartAdapter.BaudRate)); + + Divisor= SysClock/SampleRate; + + Remaind = ((SysClock*10)/SampleRate) - (Divisor*10); + + if (Remaind>4) { + Divisor++; + } + } +#endif + + + Dll = Divisor & 0xff; + Dlh = (Divisor & 0xff00)>>8; + HAL_UART_WRITE32(UART_DLL_OFF, Dll); + HAL_UART_WRITE32(UART_DLH_OFF, Dlh); + + // clear DLAB bit + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 0); + + // set data format + SetData = UartAdapter.Parity | UartAdapter.Stop | UartAdapter.DataLength; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, SetData); + + /* FIFO Control Register + 7:6 level of receive data available interrupt + 5:4 level of TX empty trigger + 2 XMIT FIFO reset + 1 RCVR FIFO reset + 0 FIFO enable/disable + */ + // FIFO setting, enable FIFO and set trigger level (2 less than full when receive + // and empty when transfer + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, UartAdapter.FIFOControl); + + /* + Interrupt Enable Register + 7: THRE Interrupt Mode enable + 2: Enable Receiver Line status Interrupt + 1: Enable Transmit Holding register empty INT32 + 0: Enable received data available interrupt + */ + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, UartAdapter.IntEnReg); + + if (UartAdapter.IntEnReg) { + // Enable Peripheral_IRQ Setting for Log_Uart + HAL_WRITE32(VENDOR_REG_BASE, PERIPHERAL_IRQ_EN, 0x1000000); + + // Enable ARM Cortex-M3 IRQ + NVIC_SetPriorityGrouping(0x3); + NVIC_SetPriority(PERIPHERAL_IRQ, 14); + NVIC_EnableIRQ(PERIPHERAL_IRQ); + } + + + return 0; +} + +u32 log_uart_irq(VOID *Data) +{ + return 0; +} + +VOID +PatchHalInitPlatformLogUart( + VOID +) +{ + IRQ_HANDLE UartIrqHandle; + LOG_UART_ADAPTER UartAdapter; + + //4 Release log uart reset and clock + LOC_UART_FCTRL(OFF); + LOC_UART_FCTRL(ON); + ACTCK_LOG_UART_CCTRL(ON); + + PinCtrl(LOG_UART,S0,ON); + + //4 Register Log Uart Callback function + UartIrqHandle.Data = (u32)NULL;//(u32)&UartAdapter; + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) log_uart_irq;//UartLogIrqHandleRam; + UartIrqHandle.Priority = 0; + + //4 Inital Log uart + UartAdapter.BaudRate = DEFAULT_BAUDRATE; + UartAdapter.DataLength = UART_DATA_LEN_8BIT; + UartAdapter.FIFOControl = 0xC1; + UartAdapter.IntEnReg = 0x00; + UartAdapter.Parity = UART_PARITY_DISABLE; + UartAdapter.Stop = UART_STOP_1BIT; + + //4 Initial Log Uart + PatchHalLogUartInit(UartAdapter); + + //4 Register Isr handle + InterruptRegister(&UartIrqHandle); + + UartAdapter.IntEnReg = 0x05; + + //4 Initial Log Uart for Interrupt + PatchHalLogUartInit(UartAdapter); + + //4 initial uart log parameters before any uartlog operation + //RtlConsolInit(ROM_STAGE,GetRomCmdNum(),(VOID*)&UartLogRomCmdTable);// executing boot seq., +} \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c new file mode 100644 index 0000000..46babb2 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/low_level_io.c @@ -0,0 +1,82 @@ +/* + decompiled low_level_io.o +*/ +#include ...... +//------------------------------------------------------------------------- +// Function declarations +void mode_init(); +void HalSerialPutcRtl8195a(int c, int a2, char a3); +signed int DiagPrintf(const char *fmt, ...); +void log_uart_enable_printf(); +void log_uart_disable_printf(); +//------------------------------------------------------------------------- +// Data declarations +uint32_t backupWarn; +uint32_t backupErr; +uint32_t backupInfo; +int disablePrintf; +// extern _UNKNOWN use_mode; +// extern _UNKNOWN ConfigDebugErr; +// extern _UNKNOWN ConfigDebugInfo; +// extern _UNKNOWN ConfigDebugWarn; + +//----- +void mode_init() +{ + use_mode = 1; +} + +//----- +void HalSerialPutcRtl8195a(int c) +{ + signed int v3; // r3@2 + + if ( disablePrintf != 1 ) + { + v3 = 6540; + do + { + if ( !--v3 ) + break; + a3 = v40003014; + } + while ( !(v40003014 & 0x60) ); + if ( c == 10 ) a3 = 13; + v40003000 = c; + if ( c == 10 ) v40003000 = a3; + } +} + +//----- +signed int DiagPrintf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + if ( disablePrintf != 1 ) + VSprintf(0, fmt, va); + return 1; +} + +//----- +void log_uart_enable_printf() +{ + disablePrintf = 0; + ConfigDebugErr = backupErr; + ConfigDebugInfo = backupInfo; + ConfigDebugWarn = backupWarn; +} + +//----- +void log_uart_disable_printf() +{ + disablePrintf = 1; + backupErr = ConfigDebugErr; + backupInfo = ConfigDebugInfo; + backupWarn = ConfigDebugWarn; + ConfigDebugErr = 0; + ConfigDebugInfo = 0; + ConfigDebugWarn = 0; +} + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_bios_data.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_bios_data.c new file mode 100644 index 0000000..e9bb21b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_bios_data.c @@ -0,0 +1,175 @@ +/* + * rtl_bios_data.c + * + * Created on: 12/02/2017 + * Author: pvvx + * + * This variables declared in ROM code! + * Variables use fixed addresses! + * (see *.ld script) + */ + +#include "rtl_bios_data.h" +extern void * UartLogRomCmdTable; +/* ROM + startup.c */ +RAM_DEDECATED_VECTOR_TABLE_SECTION IRQ_FUN NewVectorTable[64]; // 10000000 +RAM_USER_IRQ_FUN_TABLE_SECTION IRQ_FUN UserIrqFunTable[64]; // 10000100 +RAM_USER_IRQ_DATA_TABLE_SECTION u32 UserIrqDataTable[64]; // 10000200 +/* ROM + ... */ +HAL_RAM_BSS_SECTION PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; // 10000354 +/* ROM + hal_ssi.h */ +HAL_RAM_BSS_SECTION u32 SSI_DBG_CONFIG; // 10000350 +/* ROM + hal_timer.h & .. */ +HAL_RAM_BSS_SECTION u32 gTimerRecord; // 1000034C +HAL_RAM_BSS_SECTION u16 GPIOState[11]; // 10000334 +HAL_RAM_BSS_SECTION HAL_TIMER_OP HalTimerOp; // 10000318 +/* ROM + diag.h */ +HAL_RAM_BSS_SECTION u32 ConfigDebugErr; // 10000314 +HAL_RAM_BSS_SECTION u32 ConfigDebugInfo; // 10000310 +HAL_RAM_BSS_SECTION u32 ConfigDebugWarn; // 1000030C +HAL_RAM_BSS_SECTION u32 CfgSysDebugErr; // 10000308 +HAL_RAM_BSS_SECTION u32 CfgSysDebugInfo; // 10000304 +HAL_RAM_BSS_SECTION u32 CfgSysDebugWarn; // 10000300 +/* ROM + rtl8195a_timer.c */ +SECTION_RAM_TIMER2TO7_VECTOR_TABLE IRQ_FUN Timer2To7VectorTable[MAX_TIMER_VECTOR_TABLE_NUM]; // 10000358 Timer2To7VectorTable[6] ! +/* ROM + Rand() */ +INFRA_RAM_BSS_SECTION u32 _rand_z4, _rand_z3, _rand_z2, _rand_z1, _rand_first; // 10000370.. +/* ROM + RTL_CONSOL */ +MON_RAM_BSS_SECTION u8 *ArgvArray[MAX_ARGV]; // 100006AC *ArgvArray[10] ! +MON_RAM_BSS_SECTION u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; // 10000430 UartLogHistoryBuf[5][127] ! +MON_RAM_BSS_SECTION volatile UART_LOG_CTL UartLogCtl; // 10000408 +/* = { + .NewIdx = 0, + .SeeIdx = 0, + .RevdNo = UART_LOG_HISTORY_LEN, + .EscSTS = 0, + .ExecuteCmd = 0, + .ExecuteEsc = 0, + .BootRdy = 0, + .Resvd = 0, + .pTmpLogBuf = &UartLogBuf, + .pfINPUT = (void*) &DiagPrintf, + .pCmdTbl = (PCOMMAND_TABLE) &UartLogRomCmdTable, + .CmdTblSz = 6, + .CRSTS = 0, + .pHistoryBuf = &UartLogHistoryBuf, + .TaskRdy = 0 +// .Sema +}; */ +MON_RAM_BSS_SECTION UART_LOG_BUF UartLogBuf; // 10000388 +MON_RAM_BSS_SECTION volatile UART_LOG_CTL *pUartLogCtl = &UartLogCtl; // 10000384 +/* ROM + LIB C */ +LIBC_RAM_BSS_SECTION int __rtl_errno; // 10000bc4 __rtl_sread_v1_00(), __rtl_write_v1_00(), __rtl_lseek_v1_00(), __rtl_close_v1_00(), __rtl_sbrk_v1_00().. +LIBC_RAM_BSS_SECTION struct mallinfo __rtl_malloc_current_mallinfo; // 10000b9c __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION u32 __rtl_malloc_max_total_mem; // 10000b98 __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION u32 __rtl_malloc_max_sbrked_mem; // 10000b94 __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION u8 * __rtl_malloc_sbrk_base; // 10000b90 __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION u32 __rtl_malloc_top_pad; // 10000b8c __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION u32 __rtl_malloc_trim_threshold; // 10000b88 __rom_mallocr_init_v1_00() +LIBC_RAM_BSS_SECTION struct malloc_chunk *__rtl_malloc_av_[258]; // 0x10000780 __rom_mallocr_init_v1_00(), _rtl_free_r_v1_00().. +LIBC_RAM_BSS_SECTION __attribute__((aligned(0x10))) struct _rom_libgloss_ram_map rom_libgloss_ram_map; // 10000760 + +// 10000BA0..10000BC0: 9 x dw __rom_mallocr_init_v1_00() + +/* ROM: ROM_odm_FalseAlarmCounterStatistics() + .. */ +#define _WLAN_RAM_MAP_SECTION __attribute__((__section__(".ram.rom.wlanmap"))) +_WLAN_RAM_MAP_SECTION CFO_TRACKING DM_CfoTrack; // 10000738 +_WLAN_RAM_MAP_SECTION ROM_INFO ROMInfo; // 10000720 +_WLAN_RAM_MAP_SECTION __attribute__((aligned(0x10))) FALSE_ALARM_STATISTICS FalseAlmCnt; // 100006E0 +WLAN_RAM_MAP_SECTION struct _rom_wlan_ram_map rom_wlan_ram_map; // 100006D4 + +#ifndef PRESENT_IMAGE1 +/* IMAGE1 HEAD */ +START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__; +/* +START_RAM_FUN_A_SECTION RAM_START_FUNCTION gRamStartFun; // 10000bc8 = { PreProcessForVendor + 1 }; +START_RAM_FUN_B_SECTION RAM_START_FUNCTION gRamPatchWAKE; // 10000bcc = { RtlBootToSram + 1 }; +START_RAM_FUN_C_SECTION RAM_START_FUNCTION gRamPatchFun0; // 10000bd0 = { RtlBootToSram + 1 }; +START_RAM_FUN_D_SECTION RAM_START_FUNCTION gRamPatchFun1; // 10000bd4 = { RtlBootToSram + 1 }; +START_RAM_FUN_E_SECTION RAM_START_FUNCTION gRamPatchFun2; // 10000bd8 = { RtlBootToSram + 1 }; +*/ +#endif + +IMAGE1_VALID_PATTEN_SECTION uint8 RAM_IMG1_VALID_PATTEN[8] = IMG1_VALID_PATTEN_INIT(); // 10000bdc + +//#ifdef NOT_USE_LIBROM_A + +/* ROM + hal_sdr_controller.c */ +//HAL_FLASH_DATA_SECTION +//SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // SpicInitParaAllClk[3][6] ! + +/* ROM + hal_sdr_controller.c */ +HAL_CUT_B_RAM_DATA_SECTION DRAM_INFO SdrDramDev = DRAM_INFO_INIT(); // 10001c4c +HAL_CUT_B_RAM_DATA_SECTION DRAM_MODE_REG_INFO SdrDramModeReg = DRAM_MODE_REG_INFO_INIT(); // 10001c30 +HAL_CUT_B_RAM_DATA_SECTION DRAM_TIMING_INFO SdrDramTiming = DRAM_TIMING_INFO_INIT(); // 10001bfc +HAL_CUT_B_RAM_DATA_SECTION DRAM_DEVICE_INFO SdrDramInfo = DRAM_DEVICE_INFO_INIT(); // 10001be8 +HAL_CUT_B_RAM_DATA_SECTION u32 AvaWds[2][REC_NUM]; // 10000be8 + +/* ROM + hal_sdr_controller.c: Sdr_Rand2() */ +HAL_CUT_B_RAM_DATA_SECTION u32 rand_x = 123456789; // 10000be4 + +#define RTL_REENT_INIT(var) \ + { 0, \ + &(var).__sf[0], \ + &(var).__sf[1], \ + &(var).__sf[2], \ + 0, \ + "", \ + 0, \ + 0x0437DC, \ + 0, \ + _NULL, \ + _NULL, \ + 0, \ + _NULL, \ + _NULL, \ + 0, \ + _NULL, \ + { \ + { \ + 0, \ + _NULL, \ + "", \ + {0, 0, 0, 0, 0, 0, 0, 0, 0}, \ + 0, \ + 1, \ + { \ + {_RAND48_SEED_0, _RAND48_SEED_1, _RAND48_SEED_2}, \ + {_RAND48_MULT_0, _RAND48_MULT_1, _RAND48_MULT_2}, \ + _RAND48_ADD \ + }, \ + {0, {0}}, \ + {0, {0}}, \ + {0, {0}}, \ + "", \ + "", \ + 0, \ + {0, {0}}, \ + {0, {0}}, \ + {0, {0}}, \ + {0, {0}}, \ + {0, {0}} \ + } \ + }, \ + _REENT_INIT_ATEXIT \ + _NULL, \ + {_NULL, 0, _NULL} \ + } +// ROM: _rtl_impure_ptr + impure_reent in lib_rom.a ".hal.ram.data" +__attribute__((section(".libc.reent"))) struct _reent impure_reent = RTL_REENT_INIT(impure_reent); // 10001c60 +__attribute__((section(".libc.reent"))) struct _reent * _rtl_impure_ptr = { &impure_reent }; // 10001c68 + +/* ROM ? */ +__attribute__((__section__(".rom.unc.data"))) u32 _rom_unc_data[9]; // 100020e8 + +/* ROM + hal_sdr_controller.c: Sdr_Rand2() */ +__attribute__((__section__(".sdr.rand2.data"))) u32 _sdr_rnd2_c = 7654321, _sdr_rnd2_z = 521288629, _sdr_rnd2_y = 362436; +// 100020BC, 100020B8, 100020B4 + +HAL_GPIO_ADAPTER PINMUX_RAM_DATA_SECTION gBoot_Gpio_Adapter; // 100020C0 [300=0x12c] +//SPIC_INIT_PARA HAL_FLASH_DATA_SECTION SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // 100021ec [144=0x90] + +#ifndef PRESENT_IMAGE2 +IMAGE2_START_RAM_FUN_SECTION RAM_START_FUNCTION gImage2EntryFun0; //= { InfraStart + 1 }; +#endif +IMAGE2_VALID_PATTEN_SECTION _RAM_IMG2_VALID_PATTEN RAM_IMG2_VALID_PATTEN = RAM_IMG2_VALID_PATTEN_INIT(); diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot.c new file mode 100644 index 0000000..1fcfab6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot.c @@ -0,0 +1,642 @@ +/* + * BootLoader Ver 0.2 + * Created on: 12/02/2017 + * Author: pvvx + */ + +#include "platform_autoconf.h" +#include "rtl_bios_data.h" +#include "diag.h" +#include "rtl8195a/rtl8195a_sys_on.h" + +#include "hal_spi_flash.h" + +//------------------------------------------------------------------------- +// Data declarations +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE 38400 +#endif + +/* 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000? Hz, + 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000? Hz */ +#define DEFAULT_BOOT_CLK_CPU 1 // Warning! If Start CLK > 100 MHz -> Errors SPIC function in Ameba SDK! + +#ifdef DEFAULT_BOOT_CLK_CPU +#if DEFAULT_BOOT_CLK_CPU < 6 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 0 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE DEFAULT_BOOT_CLK_CPU +#else +#define DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 1 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE (DEFAULT_BOOT_CLK_CPU-6) +#endif +#endif // DEFAULT_BOOT_CLK_CPU + +#define BOOT_RAM_TEXT_SECTION // __attribute__((section(".boot.text"))) + +//------------------------------------------------------------------------- +typedef struct _seg_header { + uint32 size; + uint32 ldaddr; +} IMGSEGHEAD, *PIMGSEGHEAD; + +typedef struct _img2_header { + IMGSEGHEAD seg; + uint32 sign[2]; + void (*startfunc)(void); + uint8 rtkwin[7]; + uint8 ver[13]; + uint8 name[32]; +} IMG2HEAD, *PIMG2HEAD; + +#ifndef FLASH_SECTOR_SIZE +#define FLASH_SECTOR_SIZE 4096 +#endif +//------------------------------------------------------------------------- +// Function declarations +LOCAL void RtlBootToFlash(void); // image1 +LOCAL void RtlBoot1ToSram(void); // image1 +LOCAL void RtlBoot2ToSram(void); // image1 +LOCAL void RtlBoot3ToSram(void); // image1 +LOCAL void RtlBoot4ToSram(void); // image1 + +extern _LONG_CALL_ VOID HalCpuClkConfig(unsigned char CpuType); +extern _LONG_CALL_ VOID VectorTableInitRtl8195A(u32 StackP); +extern _LONG_CALL_ VOID HalInitPlatformLogUartV02(VOID); +extern _LONG_CALL_ VOID HalInitPlatformTimerV02(VOID); +//extern _LONG_CALL_ VOID DramInit_rom(IN DRAM_DEVICE_INFO *DramInfo); +//extern _LONG_CALL_ u32 SdrCalibration_rom(VOID); +extern _LONG_CALL_ int SdrControllerInit_rom(PDRAM_DEVICE_INFO pDramInfo); +extern _LONG_CALL_ u32 SpicCmpDataForCalibrationRtl8195A(void); // compare read_data and golden_data +//extern _LONG_CALL_ VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); // wait spi-flash status register[0] = 0 +//extern _LONG_CALL_ VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); +//extern _LONG_CALL_ VOID RtlConsolInit(IN u32 Boot, IN u32 TBLSz, IN VOID *pTBL); + +//#pragma arm section code = ".boot.text"; +//#pragma arm section rodata = ".boot.rodata", rwdata = ".boot.data", zidata = ".boot.bss"; + +typedef void (*START_FUNC)(void); + +//------------------------------------------------------------------------- +/* Start table: */ +START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__ = { + RtlBootToFlash + 1, // StartFun(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) + RtlBoot1ToSram + 1, // PatchWAKE(), Run if ( v40000210 & 0x20000000 ) + RtlBoot2ToSram + 1, // PatchFun0(), Run if ( v40000210 & 0x10000000 ) + RtlBoot3ToSram + 1, // PatchFun1(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) + RtlBoot4ToSram + 1 };// PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) +//------------------------------------------------------------------------- +/* Set Debug Flags */ +LOCAL void BOOT_RAM_TEXT_SECTION SetDebugFlgs() { +#if CONFIG_DEBUG_LOG > 3 + CfgSysDebugWarn = -1; + CfgSysDebugInfo = -1; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = -1; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 1 + CfgSysDebugWarn = -1; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 0 +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#else +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; +// CfgSysDebugErr = 0; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; +// ConfigDebugErr = 0; +#endif +} + +/* JTAG On */ +LOCAL void BOOT_RAM_TEXT_SECTION JtagOn(void) { + ACTCK_VENDOR_CCTRL(ON); + SLPCK_VENDOR_CCTRL(ON); + HalPinCtrlRtl8195A(JTAG, 0, 1); +} + +/* GetChipId() */ +LOCAL uint8 INFRA_START_SECTION _Get_ChipId() { + uint8 ChipId = CHIP_ID_8710AF; + if (HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xF8, + &ChipId, L25EOUTVOLTAGE) != 1) + DBG_8195A("Get Chip ID Failed\r"); + return ChipId; +} + +/* + * 16 bytes FIFO ... 16*11/38400 = 0.004583 sec + * (0.005/5)*166666666 = 166666.666 Tcpu + */ +LOCAL void INFRA_START_SECTION loguart_wait_tx_fifo_empty(void) { + if (HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_LOG_UART_EN) { + int x = 16384; + while ((!(HAL_READ8(LOG_UART_REG_BASE, 0x14) & BIT6)) && x--) + ; // иначе глючит LogUART, если переключение CLK приходится на вывод символов ! + } +} + +extern SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // 100021ec [144=0x90] +LOCAL uint32 InitTabParaAllClk[3 * CPU_CLK_TYPE_NO] = { + // SIO + 0x01310102, // 72t/byte + 0x03310101, // 0201 - 40t, 0101 - 39t, 0102 - 72t, 0103 - 104t + 0x05310001, // 39t + 0x07310001, + 0x09310001, + 0x0B310001, + // DIO + 0x11311301, // BaudRate = 1, RdDummyCyle = 19, DelayLine = 63, DIO + 0x13311201, // 1201 - 36t + 0x15311101, // 1101 - 35t + 0x17311101, + 0x19311101, + 0x1B311101 + // QIO +/* MXIC Flash only DIO! + 0x21311301, // BaudRate = 1, RdDummyCyle = 19, DelayLine = 63, DIO + 0x23311201, // 1201 - 36t + 0x25311101, // 1101 - 35t + 0x27311101, + 0x29311101, + 0x2B311101 +*/ +}; + +struct spic_table_flash_type { + uint8 cmd[12]; + uint8 strlr2; + uint8 fbaud; + uint8 addrlen; + uint8 fsize; + uint32 contrl; + uint16 validcmd[3]; + uint8 manufacturerid; + uint8 memorytype; +}; + +//PSPIC_INIT_PARA pSpicInitPara; + +struct spic_table_flash_type spic_table_flash = { + { // for FLASH MX25L8006E/1606E + FLASH_CMD_FREAD, // REG_SPIC_READ_FAST_SINGLE 0x400060E0 0x0B + FLASH_CMD_DREAD, // REG_SPIC_READ_DUAL_DATA 0x400060E4 0x3B + FLASH_CMD_DREAD, // REG_SPIC_READ_DUAL_ADDR_DATA 0x400060E8 0x3B ? + FLASH_CMD_QREAD, // REG_SPIC_READ_QUAD_DATA 0x400060EC 0x6B + FLASH_CMD_4READ, // REG_SPIC_READ_QUAD_ADDR_DATA 0x400060F0 0xEB ? + FLASH_CMD_PP, // REG_SPIC_WRITE_SIGNLE 0x400060F4 0x02 + FLASH_CMD_DPP, // REG_SPIC_WRITE_DUAL_DATA 0x400060F8 0xA2 + FLASH_CMD_DPP, // REG_SPIC_WRITE_DUAL_ADDR_DATA 0x400060FC 0xA2 ? + FLASH_CMD_QPP, // REG_SPIC_WRITE_QUAD_DATA 0x40006100 0x32 + FLASH_CMD_4PP, // REG_SPIC_WRITE_QUAD_ADDR_DATA 0x40006104 0x38 + FLASH_CMD_WREN, // REG_SPIC_WRITE_ENABLE 0x40006108 0x06 + FLASH_CMD_RDSR // REG_SPIC_READ_STATUS 0x4000610C 0x05 + }, + BIT_FIFO_ENTRY(5) | BIT_SO_DUM, // REG_SPIC_CTRLR2 0x40006110 0x51 + BIT_FSCKDV(1), // REG_SPIC_FBAUDR 0x40006114 0x01 + BIT_ADDR_PHASE_LENGTH(3), // REG_SPIC_ADDR_LENGTH 0x40006118 0x03 + BIT_FLASE_SIZE(0x0F), // REG_SPIC_FLASE_SIZE 0x40006124 0x0E ? + BIT_CS_H_WR_DUM_LEN(2)| BIT_AUTO_ADDR__LENGTH(3) | BIT_RD_DUMMY_LENGTH(0x0), // REG_SPIC_AUTO_LENGTH 0x4000611C 0x20030001 ? + { + BIT_WR_BLOCKING, // REG_SPIC_VALID_CMD 0x40006120 0x200 SpicOneBitMode + BIT_WR_BLOCKING | BIT_RD_DUAL_I, // REG_SPIC_VALID_CMD 0x40006120 0x202 SpicDualBitMode + BIT_WR_BLOCKING | BIT_RD_DUAL_I, // REG_SPIC_VALID_CMD 0x40006120 0x202 SpicDualBitMode +// BIT_WR_BLOCKING | BIT_RD_QUAD_O, // REG_SPIC_VALID_CMD 0x40006120 0x208 SpicQuadBitMode MXIC not QIO + }, + 0xC2, 0x20 // MX25L8006/MX25L1606 +}; + +LOCAL int BOOT_RAM_TEXT_SECTION SetSpicBitMode(uint8 BitMode) { + PSPIC_INIT_PARA pspic = &SpicInitParaAllClk[BitMode][((HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) >> 4) & 7)]; + if(pspic->Mode.Valid) { + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, spic_table_flash.validcmd[pspic->Mode.BitMode]); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) & 0xFFFF0000) | pspic->RdDummyCyle); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, pspic->BaudRate); + FLASH_DDL_FCTRL(pspic->DelayLine); // SPI_DLY_CTRL_ADDR [7:0] + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + } + SPI_FLASH_PIN_FCTRL(ON); + // Test Read Pattern + if(!SpicCmpDataForCalibrationRtl8195A()) { + FLASH_DDL_FCTRL(0x31); // SPI_DLY_CTRL_ADDR [7:0] + for(uint8 BaudRate = 1; BaudRate < 4; BaudRate++) { + for(uint8 RdDummyCyle = 0; RdDummyCyle < 63; RdDummyCyle++) { + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) & 0xFFFF0000) | RdDummyCyle); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, BaudRate); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); +// HAL_SPI_WRITE32(REG_SPIC_FLUSH_FIFO, 1); + if(SpicCmpDataForCalibrationRtl8195A()) { + DiagPrintf("Spic reinit %d:%d\n", BaudRate, RdDummyCyle); + pspic->BaudRate = BaudRate; + pspic->RdDummyCyle = RdDummyCyle; + pspic->DelayLine = 0x31; + pspic->Mode.Valid = 1; + return 1; + }; + }; + }; + return 0; + }; + return 1; +} + +void BOOT_RAM_TEXT_SECTION InitSpicFlashType(struct spic_table_flash_type *ptable_flash) { + u8 * ptrb = &ptable_flash->cmd; + volatile u32 * ptrreg = (volatile u32 *)(SPI_FLASH_CTRL_BASE + REG_SPIC_READ_FAST_SINGLE);// 0x400060E0 + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); // Disable SPI_FLASH User Mode + do { + *ptrreg++ = *ptrb++; + } while(ptrb < (u8 *)(&ptable_flash->fsize)); + ptrreg[0] = ptable_flash->contrl; + ptrreg[1] = ptable_flash->validcmd[SpicOneBitMode]; + ptrreg[2] = ptable_flash->fsize; + HAL_SPI_WRITE32(REG_SPIC_SER, BIT_SER); +} + +LOCAL int BOOT_RAM_TEXT_SECTION InitSpic(uint8 SpicBitMode) { + _memset(SpicInitParaAllClk, 0, sizeof(SpicInitParaAllClk)); + uint32 * ptr = InitTabParaAllClk; + uint8 x; + for(x = 0; x < SpicMaxMode; x++) { + *(uint32 *)&SpicInitParaAllClk[SpicOneBitMode][x].BaudRate = ptr[0]; + *(uint32 *)&SpicInitParaAllClk[SpicDualBitMode][x].BaudRate = ptr[CPU_CLK_TYPE_NO]; + *(uint32 *)&SpicInitParaAllClk[SpicQuadBitMode][x].BaudRate = ptr[CPU_CLK_TYPE_NO]; // MXIC not QIO + ptr++; + } + ACTCK_FLASH_CCTRL(1); + SLPCK_FLASH_CCTRL(1); + HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); + InitSpicFlashType(&spic_table_flash); + return SetSpicBitMode(SpicBitMode); +} + + +/* SYSPlatformInit */ +LOCAL void INFRA_START_SECTION SYSPlatformInit(void) { + __asm__ __volatile__ ("cpsid f\n"); + JtagOn(); + SetDebugFlgs(); + //----- SYS Init + HAL_SYS_CTRL_WRITE32(REG_SYS_EFUSE_SYSCFG0, + (HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG0) & (~(BIT_MASK_SYS_EEROM_LDO_PAR_07_04 << BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04))) | BIT_SYS_EEROM_LDO_PAR_07_04(6)); // & 0xF0FFFFFF | 0x6000000 + HAL_SYS_CTRL_WRITE32(REG_SYS_XTAL_CTRL1, + (HAL_SYS_CTRL_READ32(REG_SYS_XTAL_CTRL1) & (~(BIT_MASK_SYS_XTAL_DRV_RF1 << BIT_SHIFT_SYS_XTAL_DRV_RF1))) | BIT_SYS_XTAL_DRV_RF1(1)); // & 0xFFFFFFE7 | 8; + //----- SDIO_Device_Off + HAL_PERI_ON_WRITE32(REG_PESOC_HCI_CLK_CTRL0, + HAL_PERI_ON_READ32(REG_PESOC_HCI_CLK_CTRL0) & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_PERI_ON_WRITE32(REG_SOC_HCI_COM_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_HCI_COM_FUNC_EN) & (~(BIT_SOC_HCI_SDIOD_ON_EN | BIT_SOC_HCI_SDIOD_OFF_EN))); + HAL_PERI_ON_WRITE32(REG_HCI_PINMUX_CTRL, + HAL_PERI_ON_READ32(REG_HCI_PINMUX_CTRL) & (~(BIT_HCI_SDIOD_PIN_EN))); + //----- GPIO Adapter + extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter; + _memset(&gBoot_Gpio_Adapter, 0, sizeof(gBoot_Gpio_Adapter)); + _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; +#ifdef DEFAULT_BOOT_CLK_CPU + //----- CLK CPU + loguart_wait_tx_fifo_empty(); // иначе глючит LogUART, если переключение CLK приходится на вывод символов ! +#if DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 + // 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000 Hz + HalCpuClkConfig(DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE); + *((int *)(SYSTEM_CTRL_BASE+REG_SYS_SYSPLL_CTRL1)) |= (1<<17);// REG_SYS_SYSPLL_CTRL1 |= BIT_SYS_SYSPLL_DIV5_3 +#else + // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz + *((int *) (SYSTEM_CTRL_BASE + REG_SYS_SYSPLL_CTRL1)) &= ~(1 << 17); // REG_SYS_SYSPLL_CTRL1 &= ~BIT_SYS_SYSPLL_DIV5_3 + HalCpuClkConfig(DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE); +#endif // CPU_CLOCK_SEL_DIV5_3 +#endif // DEFAULT_CLK_CPU + //----- System + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + HalInitPlatformLogUartV02(); // Show ""... :( + HalInitPlatformTimerV02(); + __asm__ __volatile__ ("cpsie f\n"); +} + +/*------------------------------------------------------------------------------------- + Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) + --------------------------------------------------------------------------------------*/ +LOCAL unsigned int BOOT_RAM_TEXT_SECTION flashcpy(unsigned int faddr, + void *dist, unsigned int size) { + union { + unsigned char uc[4]; + unsigned int ud; + } tmp; + if (faddr < SPI_FLASH_BASE) + faddr += SPI_FLASH_BASE; + unsigned char * pd = (unsigned char *) dist; + unsigned int *p = (unsigned int *) ((unsigned int) faddr & (~3)); + unsigned int xlen = (unsigned int) faddr & 3; + unsigned int len = size; + + if (xlen) { + tmp.ud = *p++; + while (len) { + len--; + *pd++ = tmp.uc[xlen++]; + if (xlen & 4) + break; + }; + }; + xlen = len >> 2; + while (xlen) { + tmp.ud = *p++; + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + }; + if (len & 3) { + tmp.ud = *p; + pd[0] = tmp.uc[0]; + if (len & 2) { + pd[1] = tmp.uc[1]; + if (len & 1) { + pd[2] = tmp.uc[2]; + }; + }; + }; + return size; +} + +typedef enum { + SEG_ID_ERR, + SEG_ID_SRAM, + SEG_ID_TCM, + SEG_ID_SDRAM, + SEG_ID_SOC, + SEG_ID_FLASH, + SEG_ID_CPU, + SEG_ID_ROM, + SEG_ID_MAX +} _SEG_ID; + +LOCAL const char * const txt_tab_seg[] = { + "UNK", // 0 + "SRAM", // 1 + "TCM", // 2 + "SDRAM", // 3 + "SOC", // 4 + "FLASH", // 5 + "CPU", // 6 + "ROM" // 7 + }; + +LOCAL const uint32 tab_seg_def[] = { 0x10000000, 0x10070000, 0x1fff0000, + 0x20000000, 0x30000000, 0x30200000, 0x40000000, 0x40800000, 0x98000000, + 0xA0000000, 0xE0000000, 0xE0010000, 0x00000000, 0x00050000 }; + +LOCAL uint32 BOOT_RAM_TEXT_SECTION get_seg_id(uint32 addr, int32 size) { + uint32 ret = SEG_ID_ERR; + uint32 * ptr = &tab_seg_def; + if (size > 0) { + do { + ret++; + if (addr >= ptr[0] && addr + size <= ptr[1]) { + return ret; + }; + ptr += 2; + } while (ret < SEG_ID_MAX); + }; + return 0; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_img2_head(uint32 faddr, PIMG2HEAD hdr) { + flashcpy(faddr, hdr, sizeof(IMG2HEAD)); + uint32 ret = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (hdr->sign[1] == IMG_SIGN2_RUN) { + if (hdr->sign[0] == IMG_SIGN1_RUN) { + ret |= 1 << 9; + } else if (hdr->sign[0] == IMG_SIGN1_SWP) { + ret |= 1 << 8; + }; + } + if (*(u32 *) (&hdr->rtkwin) == IMG2_SIGN_DW1_TXT) { + ret |= 1 << 10; + }; + return ret; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_segs(uint32 faddr, PIMG2HEAD hdr, + uint8 flgload) { + uint32 fnextaddr = faddr; + uint8 segnum = 0; + while (1) { + uint32 seg_id = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (flgload + && (seg_id == SEG_ID_SRAM || seg_id == SEG_ID_TCM + || seg_id == SEG_ID_SDRAM)) { +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("Load Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", + segnum, faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, + hdr->seg.size); +#endif + fnextaddr += flashcpy(fnextaddr, hdr->seg.ldaddr, hdr->seg.size); + } else if (seg_id) { +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("Skip Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", segnum, + faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, hdr->seg.size); +#endif + fnextaddr += hdr->seg.size; + } else { + break; + } + fnextaddr += flashcpy(fnextaddr, &hdr->seg, sizeof(IMGSEGHEAD)); + segnum++; + } + return fnextaddr; +} + +/*------------------------------------------------------------------------------------- + * 0 - default image (config data + 0), 1 - image N1, 2 - image N2, ... + --------------------------------------------------------------------------------------*/ +LOCAL int BOOT_RAM_TEXT_SECTION loadUserImges(int imgnum) { + IMG2HEAD hdr; + int imagenum = 1; + uint32 faddr = 0xb000; // start image2 in flash + DBG_8195A("Selected Image %d.\n", imgnum); + + while (1) { + faddr = (faddr + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + uint32 img_id = load_img2_head(faddr, &hdr); + if ((img_id >> 8) > 4 || (uint8) img_id != 0) { + faddr = load_segs(faddr + 0x10, &hdr.seg, imagenum == imgnum); + if (imagenum == imgnum) { +// DBG_8195A("Image%d: %s\n", imgnum, hdr.name); + break; + } + imagenum++; + } else if (imagenum) { + DBG_8195A("No Image%d! Trying Image0...\n", imgnum); + // пробуем загрузить image по умолчанию, по записи в секторе установок + flashcpy(FLASH_SYSTEM_DATA_ADDR, &faddr, sizeof(faddr)); + if (faddr < 0x8000000) + faddr += SPI_FLASH_BASE; + if (get_seg_id(faddr, 0x100) == SEG_ID_FLASH) { + imagenum = 0; + imgnum = 0; + } else { + DBG_8195A("No Image0!\n"); + imagenum = -1; + break; + }; + } else { + imagenum = -1; + break; + } + }; + return imagenum; +} + +//----- IsForceLoadDefaultImg2 +LOCAL uint8 BOOT_RAM_TEXT_SECTION IsForceLoadDefaultImg2(void) { + uint8 gpio_pin[4]; + HAL_GPIO_PIN GPIO_Pin; + HAL_GPIO_PIN_STATE flg; + int result = 0; + flashcpy(FLASH_SYSTEM_DATA_ADDR + 0x08, &gpio_pin, sizeof(gpio_pin)); // config data + 8 +// _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; + for (int i = 1; i; i--) { + uint8 x = gpio_pin[i]; + result <<= 1; + if (x != 0xff) { + GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(x & 0x7F); + if (x & 0x80) { + GPIO_Pin.pin_mode = DIN_PULL_LOW; + flg = GPIO_PIN_HIGH; + } else { + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + flg = GPIO_PIN_LOW; + } + HAL_GPIO_Init_8195a(&GPIO_Pin); + if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == flg) { + result |= 1; + } + HAL_GPIO_DeInit_8195a(&GPIO_Pin); + } + } +// _pHAL_Gpio_Adapter->IrqHandle.IrqFun = NULL; + return result; +} + +/* RTL Console ROM */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlConsolRam(void) { +// DiagPrintf("\r\nRTL Console ROM\r\n"); +// RtlConsolInit(ROM_STAGE, (u32) 6, (void*) &UartLogRomCmdTable); + pUartLogCtl->RevdNo = UART_LOG_HISTORY_LEN; + pUartLogCtl->BootRdy = 1; + pUartLogCtl->pTmpLogBuf->UARTLogBuf[0] = '?'; + pUartLogCtl->pTmpLogBuf->BufCount = 1; + pUartLogCtl->ExecuteCmd = 1; + RtlConsolTaskRom(pUartLogCtl); +} + +/* Enter Image 1.5 */ +LOCAL void BOOT_RAM_TEXT_SECTION EnterImage15(int flg) { + + if (flg) + _memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + + SYSPlatformInit(); + + if (!flg) + DBG_8195A("\r===== Enter FLASH-Boot ====\n"); + else + DBG_8195A("\r===== Enter SRAM-Boot %d ====\n", flg); +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("CPU CLK: %d Hz, SOC FUNC EN: %p\r\n", HalGetCpuClk(), + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN)); +#endif + uint8 ChipId = _Get_ChipId(); + if (ChipId < CHIP_ID_8195AM) { + //----- SDRAM Off + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); // Flag SDRAM Off + } else { + //----- SDRAM On + LDO25M_CTRL(ON); + HAL_SYS_CTRL_WRITE32(REG_SYS_REGU_CTRL0, + (HAL_SYS_CTRL_READ32(REG_SYS_REGU_CTRL0) & 0xfffff) | BIT_SYS_REGU_LDO25M_ADJ(0x0e)); + SDR_PIN_FCTRL(ON); + }; + if (!InitSpic(SpicDualBitMode)) { + DBG_8195A("Spic Init Error!\n"); + RtlConsolRam(); + }; + if ((HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT(21)) == 0) { // уже загружена? +// extern DRAM_DEVICE_INFO SdrDramInfo_rom; // 50 MHz + if (!SdrControllerInit_rom(&SdrDramInfo)) { // 100 MHz + DBG_8195A("SDR Controller Init fail!\n"); + RtlConsolRam(); + } +#if 0 // Test SDRAM + else { + uint32 *ptr = SDR_SDRAM_BASE; + uint32 tt = 0x55AA55AA; + for (int i = 0; i < 512 * 1024; i++) { + ptr[i] = tt++; + }; + tt = 0x55AA55AA; + for (int i = 0; i < 512 * 1024; i++) { + if (ptr[i] != tt) { + DBG_8195A("SDR err %p %p != %p!\n", &ptr[i], ptr[i], tt); + RtlConsolRam(); + } + tt++; + }; + DBG_8195A("SDR tst end\n"); + }; +#endif // test + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); + }; + + if (!flg) + loadUserImges(IsForceLoadDefaultImg2() + 1); + + if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_8195A("Invalid Image Signature!\n"); + RtlConsolRam(); + } + + DBG_8195A("Img Sign: %s, Go @ 0x%08x\r\n", &__image2_validate_code__, + __image2_entry_func__); + __image2_entry_func__(); +} + +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot1ToSram(void) { + EnterImage15(1); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot2ToSram(void) { + EnterImage15(2); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot3ToSram(void) { + EnterImage15(3); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot4ToSram(void) { + EnterImage15(4); +} + +LOCAL void BOOT_RAM_TEXT_SECTION RtlBootToFlash(void) { + EnterImage15(0); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c new file mode 100644 index 0000000..a0648e8 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_min.c @@ -0,0 +1,387 @@ +/* + * (SRAM) Debug BootLoader + * Created on: 12/02/2017 + * Author: pvvx + */ + +#include "platform_autoconf.h" +#include "rtl_bios_data.h" +#include "diag.h" +#include "rtl8195a/rtl8195a_sys_on.h" + +//------------------------------------------------------------------------- +// Data declarations +//extern u32 STACK_TOP; +//extern volatile UART_LOG_CTL * pUartLogCtl; +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE UART_BAUD_RATE_38400 +#endif + +#define BOOT_RAM_TEXT_SECTION // __attribute__((section(".boot.text"))) +//#define BOOT_RAM_RODATA_SECTION __attribute__((section(".boot.rodata"))) +//#define BOOT_RAM_DATA_SECTION __attribute__((section(".boot.data"))) +//#define BOOT_RAM_BSS_SECTION __attribute__((section(".boot.bss"))) + +//------------------------------------------------------------------------- +typedef struct _seg_header { + uint32 size; + uint32 ldaddr; +} IMGSEGHEAD, *PIMGSEGHEAD; + +typedef struct _img2_header { + IMGSEGHEAD seg; + uint32 sign[2]; + void (*startfunc)(void); + uint8 rtkwin[7]; + uint8 ver[13]; + uint8 name[32]; +} IMG2HEAD, *PIMG2HEAD; + +#ifndef FLASH_SECTOR_SIZE +#define FLASH_SECTOR_SIZE 4096 +#endif +//------------------------------------------------------------------------- +// Function declarations +LOCAL void RtlBootToFlash(void); // image1 +LOCAL void RtlBootToSram(void); // image1 +LOCAL void EnterImage15(void); // image1 +LOCAL void JtagOn(void); // image1 + +extern _LONG_CALL_ VOID HalCpuClkConfig(unsigned char CpuType); +extern _LONG_CALL_ VOID VectorTableInitRtl8195A(u32 StackP); +extern _LONG_CALL_ VOID HalInitPlatformLogUartV02(VOID); +extern _LONG_CALL_ VOID HalInitPlatformTimerV02(VOID); + +//#pragma arm section code = ".boot.text"; +//#pragma arm section rodata = ".boot.rodata", rwdata = ".boot.data", zidata = ".boot.bss"; + +typedef void (*START_FUNC)(void); + +/* Start table: */ +START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__ = { + RtlBootToFlash + 1, // StartFun(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) + RtlBootToSram + 1, // PatchWAKE(), Run if ( v40000210 & 0x20000000 ) + RtlBootToSram + 1, // PatchFun0(), Run if ( v40000210 & 0x10000000 ) + RtlBootToSram + 1,// PatchFun1(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) + RtlBootToFlash + 1 };// PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) +// EnterImage15 + 1}; // PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) + +/* Set Debug Flags */ +LOCAL void BOOT_RAM_TEXT_SECTION SetDebugFlgs() { +#if CONFIG_DEBUG_LOG > 3 + CfgSysDebugWarn = -1; + CfgSysDebugInfo = -1; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = -1; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 1 + CfgSysDebugWarn = -1; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 0 +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#else +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; +// CfgSysDebugErr = 0; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; +// ConfigDebugErr = 0; +#endif +} + +/* RTL Console ROM */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlConsolRam(void) { +// DiagPrintf("\r\nRTL Console ROM\r\n"); + pUartLogCtl->pTmpLogBuf->UARTLogBuf[0] = '?'; + pUartLogCtl->pTmpLogBuf->BufCount = 1; + pUartLogCtl->ExecuteCmd = 1; + RtlConsolTaskRom(pUartLogCtl); +} + +/* JTAG On */ +LOCAL void BOOT_RAM_TEXT_SECTION JtagOn(void) { + ACTCK_VENDOR_CCTRL(ON); + SLPCK_VENDOR_CCTRL(ON); + HalPinCtrlRtl8195A(JTAG, 0, 1); +} + +/* Enter Image 1.5 */ +LOCAL void BOOT_RAM_TEXT_SECTION EnterImage15(void) { + SetDebugFlgs(); + DBG_8195A( + "\n===== Enter SRAM-Boot ====\nImg Sign: %s, Go @ 0x%08x\r\n", + &__image2_validate_code__, __image2_entry_func__); +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("CPU CLK: %d Hz, SOC FUNC EN: %p\r\n", HalGetCpuClk(), + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN)); +#endif + if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image Signature!\n"); + RtlConsolRam(); + } + __image2_entry_func__(); +} + +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBootToSram(void) { + JtagOn(); /* JTAG On */ + _memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + __asm__ __volatile__ ("cpsid f\n"); + HAL_SYS_CTRL_WRITE32(REG_SYS_SYSPLL_CTRL1, + HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) & ( ~BIT_SYS_SYSPLL_DIV5_3)); + HalCpuClkConfig(2); // 41.666666 MHz +// HAL_SYS_CTRL_WRITE32(REG_SYS_SYSPLL_CTRL1, HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) | BIT_SYS_SYSPLL_DIV5_3); // 50.000 MHz + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + HalInitPlatformLogUartV02(); + HalInitPlatformTimerV02(); + __asm__ __volatile__ ("cpsie f\n"); + // SdrPowerOff(); + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); + + SpicInitRtl8195AV02(1, 0); // StartupSpicBaudRate InitBaudRate 1, SpicBitMode 1 StartupSpicBitMode + EnterImage15(); +} + +/*------------------------------------------------------------------------------------- + Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) + --------------------------------------------------------------------------------------*/ +LOCAL unsigned int BOOT_RAM_TEXT_SECTION flashcpy(unsigned int faddr, + void *dist, unsigned int size) { + union { + unsigned char uc[4]; + unsigned int ud; + } tmp; + if (faddr < SPI_FLASH_BASE) + faddr += SPI_FLASH_BASE; + unsigned char * pd = (unsigned char *) dist; + unsigned int *p = (unsigned int *) ((unsigned int) faddr & (~3)); + unsigned int xlen = (unsigned int) faddr & 3; + unsigned int len = size; + + if (xlen) { + tmp.ud = *p++; + while (len) { + len--; + *pd++ = tmp.uc[xlen++]; + if (xlen & 4) + break; + }; + }; + xlen = len >> 2; + while (xlen) { + tmp.ud = *p++; + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + }; + if (len & 3) { + tmp.ud = *p; + pd[0] = tmp.uc[0]; + if (len & 2) { + pd[1] = tmp.uc[1]; + if (len & 1) { + pd[2] = tmp.uc[2]; + }; + }; + }; + return size; +} + +enum { + SEG_ID_ERR, + SEG_ID_SRAM, + SEG_ID_TCM, + SEG_ID_SDRAM, + SEG_ID_SOC, + SEG_ID_FLASH, + SEG_ID_CPU, + SEG_ID_ROM, + SEG_ID_MAX +} SEG_ID; + +LOCAL const char * const txt_tab_seg[] = { + "UNK", // 0 + "SRAM", // 1 + "TCM", // 2 + "SDRAM", // 3 + "SOC", // 4 + "FLASH", // 5 + "CPU", // 6 + "ROM" // 7 + }; + +LOCAL const uint32 tab_seg_def[] = { 0x10000000, 0x10070000, 0x1fff0000, + 0x20000000, 0x30000000, 0x30200000, 0x40000000, 0x40800000, 0x98000000, + 0xA0000000, 0xE0000000, 0xE0010000, 0x00000000, 0x00050000 }; + +LOCAL uint32 BOOT_RAM_TEXT_SECTION get_seg_id(uint32 addr, int32 size) { + uint32 ret = SEG_ID_ERR; + uint32 * ptr = &tab_seg_def; + if (size > 0) { + do { + ret++; + if (addr >= ptr[0] && addr + size <= ptr[1]) { + return ret; + }; + ptr += 2; + } while (ret < SEG_ID_MAX); + }; + return 0; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_img2_head(uint32 faddr, PIMG2HEAD hdr) { + flashcpy(faddr, hdr, sizeof(IMG2HEAD)); + uint32 ret = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (hdr->sign[1] == IMG_SIGN2_RUN) { + if (hdr->sign[0] == IMG_SIGN1_RUN) { + ret |= 1 << 9; + } else if (hdr->sign[0] == IMG_SIGN1_SWP) { + ret |= 1 << 8; + }; + } + if (*(u32 *) (&hdr->rtkwin) == IMG2_SIGN_DW1_TXT) { + ret |= 1 << 10; + }; + return ret; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_segs(uint32 faddr, PIMG2HEAD hdr, + uint8 flgload) { + uint32 fnextaddr = faddr; + uint8 segnum = 0; + while (1) { + uint32 seg_id = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (flgload && (seg_id == SEG_ID_SRAM || seg_id == SEG_ID_TCM)) { +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("Load Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", + segnum, faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, + hdr->seg.size); +#endif + fnextaddr += flashcpy(fnextaddr, hdr->seg.ldaddr, hdr->seg.size); + } else if (seg_id) { +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("Skip Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", segnum, + faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, hdr->seg.size); +#endif + fnextaddr += hdr->seg.size; + } else { + break; + } + fnextaddr += flashcpy(fnextaddr, &hdr->seg, sizeof(IMGSEGHEAD)); + segnum++; + } + return fnextaddr; +} + +/*------------------------------------------------------------------------------------- + * 0 - default image (config data + 0), 1 - image N1, 2 - image N2, ... + --------------------------------------------------------------------------------------*/ +LOCAL int BOOT_RAM_TEXT_SECTION loadUserImges(int imgnum) { + IMG2HEAD hdr; + int imagenum = 1; + uint32 faddr = 0xb000; // start image2 in flash + DBG_8195A("Selected Image %d.\n", imgnum); + + while (1) { + faddr = (faddr + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + uint32 img_id = load_img2_head(faddr, &hdr); + if ((img_id >> 8) > 4 || (uint8) img_id != 0) { + faddr = load_segs(faddr + 0x10, &hdr.seg, imagenum == imgnum); + if (imagenum == imgnum) { +// DBG_8195A("Image%d: %s\n", imgnum, hdr.name); + break; + } + imagenum++; + } else if (imagenum) { + DBG_8195A("No Image%d! Trying Image0...\n", imgnum); + // пробуем загрузить image по умолчанию, по записи в секторе установок + flashcpy(FLASH_SYSTEM_DATA_ADDR, &faddr, sizeof(faddr)); + if (faddr < 0x8000000) + faddr += SPI_FLASH_BASE; + if (get_seg_id(faddr, 0x100) == SEG_ID_FLASH) { + imagenum = 0; + imgnum = 0; + } else { + DBG_8195A("No Image0!\n"); + imagenum = -1; + break; + }; + } else { + imagenum = -1; + break; + } + }; + return imagenum; +} +; + +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; +extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter; +//----- IsForceLoadDefaultImg2 +LOCAL uint8 BOOT_RAM_TEXT_SECTION IsForceLoadDefaultImg2(void) { + uint8 gpio_pin[4]; + HAL_GPIO_PIN GPIO_Pin; + HAL_GPIO_PIN_STATE flg; + int result = 0; + flashcpy(FLASH_SYSTEM_DATA_ADDR + 0x08, &gpio_pin, sizeof(gpio_pin)); // config data + 8 + _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; + for (int i = 1; i; i--) { + uint8 x = gpio_pin[i]; + result <<= 1; + if (x != 0xff) { + GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(x & 0x7F); + if (x & 0x80) { + GPIO_Pin.pin_mode = DIN_PULL_LOW; + flg = GPIO_PIN_HIGH; + } else { + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + flg = GPIO_PIN_LOW; + } + HAL_GPIO_Init_8195a(&GPIO_Pin); + if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == flg) { + result |= 1; + } + HAL_GPIO_DeInit_8195a(&GPIO_Pin); + } + } + _pHAL_Gpio_Adapter->IrqHandle.IrqFun = NULL; + return result; +} + +LOCAL void BOOT_RAM_TEXT_SECTION RtlBootToFlash(void) { + + JtagOn(); /* JTAG On */ + SetDebugFlgs(); + DBG_8195A("===== Enter FLASH-Boot ====\n"); + if (HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (1 << BIT_SOC_FLASH_EN)) { + SPI_FLASH_PIN_FCTRL(ON); + /* + if(!SpicCmpDataForCalibrationRtl8195A()) { + DBG_8195A("ReInit Spic DIO...\n"); + SpicInitRtl8195AV02(1, SpicDualBitMode); + } + */ + loadUserImges(IsForceLoadDefaultImg2() + 1); + }; + if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_8195A("Invalid Image Signature!\n"); + RtlConsolRam(); + } else + DBG_8195A("Go @ 0x%08x\r\n", __image2_entry_func__); + __image2_entry_func__(); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c new file mode 100644 index 0000000..6fa9091 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_ram.c @@ -0,0 +1,127 @@ +/* + * (SRAM) Debug BootLoader + * Created on: 12/02/2017 + * Author: pvvx + */ + +#include "platform_autoconf.h" +#include "rtl_bios_data.h" +#include "diag.h" +#include "rtl8195a/rtl8195a_sys_on.h" + +//------------------------------------------------------------------------- +// Data declarations +//extern u32 STACK_TOP; +//extern volatile UART_LOG_CTL * pUartLogCtl; + +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE UART_BAUD_RATE_38400 +#endif + +#define BOOT_RAM_TEXT_SECTION // __attribute__((section(".boot.text"))) +//#define BOOT_RAM_RODATA_SECTION __attribute__((section(".boot.rodata"))) +//#define BOOT_RAM_DATA_SECTION __attribute__((section(".boot.data"))) +//#define BOOT_RAM_BSS_SECTION __attribute__((section(".boot.bss"))) + +//------------------------------------------------------------------------- +// Function declarations +LOCAL void RtlBootToSram(void); // image1 +LOCAL void EnterImage15(void); // image1 +LOCAL void JtagOn(void); // image1 + +extern _LONG_CALL_ VOID HalCpuClkConfig(unsigned char CpuType); +extern _LONG_CALL_ VOID VectorTableInitRtl8195A(u32 StackP); +extern _LONG_CALL_ VOID HalInitPlatformLogUartV02(VOID); +extern _LONG_CALL_ VOID HalInitPlatformTimerV02(VOID); + +//#pragma arm section code = ".boot.text"; +//#pragma arm section rodata = ".boot.rodata", rwdata = ".boot.data", zidata = ".boot.bss"; + +typedef void (*START_FUNC)(void); + +/* Start table: */ +START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__ = { + RtlBootToSram + 1, // StartFun(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) + RtlBootToSram + 1, // PatchWAKE(), Run if ( v40000210 & 0x20000000 ) + RtlBootToSram + 1, //- PatchFun0(), Run if ( v40000210 & 0x10000000 ) + RtlBootToSram + 1, //+ PatchFun1(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) + EnterImage15 + 1}; // PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) + +/* Set Debug Flags */ +LOCAL void BOOT_RAM_TEXT_SECTION SetDebugFlgs() { +#if CONFIG_DEBUG_LOG > 3 + CfgSysDebugWarn = -1; + CfgSysDebugInfo = -1; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = -1; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 1 + CfgSysDebugWarn = -1; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 0 +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#else +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; +// CfgSysDebugErr = 0; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; +// ConfigDebugErr = 0; +#endif +} + +/* RTL Console ROM */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlConsolRam(void) { +// DiagPrintf("\r\nRTL Console ROM\r\n"); + pUartLogCtl->pTmpLogBuf->UARTLogBuf[0] = '?'; + pUartLogCtl->pTmpLogBuf->BufCount = 1; + pUartLogCtl->ExecuteCmd = 1; + RtlConsolTaskRom(pUartLogCtl); +} + +/* JTAG On */ +LOCAL void BOOT_RAM_TEXT_SECTION JtagOn(void) { + ACTCK_VENDOR_CCTRL(ON); + SLPCK_VENDOR_CCTRL(ON); + HalPinCtrlRtl8195A(JTAG, 0, 1); +} + +/* Enter Image 1.5 */ +LOCAL void BOOT_RAM_TEXT_SECTION EnterImage15(void) { + SetDebugFlgs(); + DBG_8195A("\rCPU CLK: %d Hz, SOC FUNC EN: %p\r\n", HalGetCpuClk(), HAL_PERI_ON_READ32(REG_SOC_FUNC_EN)); + DBG_8195A("==!== Enter Image 1.5 ====\nImg2 Sign: %s, InfaStart @ 0x%08x\r\n", + &__image2_validate_code__, __image2_entry_func__); + if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image2 Signature!\n"); + RtlConsolRam(); + } + __image2_entry_func__(); +} + +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBootToSram(void) { + JtagOn(); /* JTAG On */ + _memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + __asm__ __volatile__ ("cpsid f\n"); + HAL_SYS_CTRL_WRITE32(REG_SYS_SYSPLL_CTRL1, HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) & ( ~BIT_SYS_SYSPLL_DIV5_3)); + HalCpuClkConfig(2); // 41.666666 MHz +// HAL_SYS_CTRL_WRITE32(REG_SYS_SYSPLL_CTRL1, HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) | BIT_SYS_SYSPLL_DIV5_3); // 50.000 MHz + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + HalInitPlatformLogUartV02(); + HalInitPlatformTimerV02(); + __asm__ __volatile__ ("cpsie f\n"); + SpicInitRtl8195AV02(1, 0); // StartupSpicBaudRate InitBaudRate 1, SpicBitMode 1 StartupSpicBitMode +// HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & 0x1FFFFF); // Clear debug flags + EnterImage15(); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c new file mode 100644 index 0000000..bd9527a --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot_tst.c @@ -0,0 +1,696 @@ +/* + * BootLoader + * Created on: 12/02/2017 + * Author: pvvx + */ + +#include "platform_autoconf.h" +#include "rtl_bios_data.h" +#include "diag.h" +#include "rtl8195a/rtl8195a_sys_on.h" + +#include "hal_spi_flash.h" + +//------------------------------------------------------------------------- +// Data declarations + +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE UART_BAUD_RATE_38400 +#endif + +/* 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000? Hz, + 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000? Hz */ +#define DEFAULT_BOOT_CLK_CPU 8 // Warning! If Start CLK > 100 MHz -> Errors SPIC function in Ameba SDK! + +#ifdef DEFAULT_BOOT_CLK_CPU +#if DEFAULT_BOOT_CLK_CPU < 6 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 0 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE DEFAULT_BOOT_CLK_CPU +#else +#define DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 1 +#define DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE (DEFAULT_BOOT_CLK_CPU-6) +#endif +#endif // DEFAULT_BOOT_CLK_CPU + +#define BOOT_RAM_TEXT_SECTION // __attribute__((section(".boot.text"))) +//#define BOOT_RAM_RODATA_SECTION __attribute__((section(".boot.rodata"))) +//#define BOOT_RAM_DATA_SECTION __attribute__((section(".boot.data"))) +//#define BOOT_RAM_BSS_SECTION __attribute__((section(".boot.bss"))) + +//extern u32 STACK_TOP; +//extern volatile UART_LOG_CTL * pUartLogCtl; +extern void * UartLogRomCmdTable; + +//------------------------------------------------------------------------- +typedef struct _seg_header { + uint32 size; + uint32 ldaddr; +} IMGSEGHEAD, *PIMGSEGHEAD; + +typedef struct _img2_header { + IMGSEGHEAD seg; + uint32 sign[2]; + void (*startfunc)(void); + uint8 rtkwin[7]; + uint8 ver[13]; + uint8 name[32]; +} IMG2HEAD, *PIMG2HEAD; + +#ifndef FLASH_SECTOR_SIZE +#define FLASH_SECTOR_SIZE 4096 +#endif +//------------------------------------------------------------------------- +// Function declarations +LOCAL void RtlBootToFlash(void); // image1 +LOCAL void RtlBoot1ToSram(void); // image1 +LOCAL void RtlBoot2ToSram(void); // image1 +LOCAL void RtlBoot3ToSram(void); // image1 +LOCAL void RtlBoot4ToSram(void); // image1 +//LOCAL void EnterImage15(void); // image1 +//LOCAL void JtagOn(void); // image1 + +extern _LONG_CALL_ VOID HalCpuClkConfig(unsigned char CpuType); +extern _LONG_CALL_ VOID VectorTableInitRtl8195A(u32 StackP); +extern _LONG_CALL_ VOID HalInitPlatformLogUartV02(VOID); +extern _LONG_CALL_ VOID HalInitPlatformTimerV02(VOID); +//extern _LONG_CALL_ VOID DramInit_rom(IN DRAM_DEVICE_INFO *DramInfo); +//extern _LONG_CALL_ u32 SdrCalibration_rom(VOID); +extern _LONG_CALL_ int SdrControllerInit_rom(PDRAM_DEVICE_INFO pDramInfo); +extern _LONG_CALL_ u32 SpicCmpDataForCalibrationRtl8195A(void); // compare read_data and golden_data +extern _LONG_CALL_ VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); // wait spi-flash status register[0] = 0 +extern _LONG_CALL_ VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); +extern _LONG_CALL_ VOID RtlConsolInit(IN u32 Boot, IN u32 TBLSz, IN VOID *pTBL); + +//#pragma arm section code = ".boot.text"; +//#pragma arm section rodata = ".boot.rodata", rwdata = ".boot.data", zidata = ".boot.bss"; + +typedef void (*START_FUNC)(void); + +//------------------------------------------------------------------------- +/* Start table: */ +START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__ = { + RtlBootToFlash + 1, // StartFun(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x80000000 ) + RtlBoot1ToSram + 1, // PatchWAKE(), Run if ( v40000210 & 0x20000000 ) + RtlBoot2ToSram + 1, // PatchFun0(), Run if ( v40000210 & 0x10000000 ) + RtlBoot3ToSram + 1, // PatchFun1(), Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) + RtlBoot4ToSram + 1 };// PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) +//test RtlBootToFlash + 1 };// PatchFun2(), Run for Init console, if ( v40000210 & 0x4000000 ) + +//------------------------------------------------------------------------- +/* Set Debug Flags */ +LOCAL void BOOT_RAM_TEXT_SECTION SetDebugFlgs() { +#if CONFIG_DEBUG_LOG > 3 + CfgSysDebugWarn = -1; + CfgSysDebugInfo = -1; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = -1; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 1 + CfgSysDebugWarn = -1; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; + ConfigDebugWarn = -1; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#elif CONFIG_DEBUG_LOG > 0 +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; + CfgSysDebugErr = -1; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; + ConfigDebugErr = -1; +#else +// CfgSysDebugWarn = 0; +// CfgSysDebugInfo = 0; +// CfgSysDebugErr = 0; +// ConfigDebugWarn = 0; +// ConfigDebugInfo = 0; +// ConfigDebugErr = 0; +#endif +} + +/* JTAG On */ +LOCAL void BOOT_RAM_TEXT_SECTION JtagOn(void) { + ACTCK_VENDOR_CCTRL(ON); + SLPCK_VENDOR_CCTRL(ON); + HalPinCtrlRtl8195A(JTAG, 0, 1); +} + +/* GetChipId() */ +LOCAL uint8 INFRA_START_SECTION _Get_ChipId() { + uint8 ChipId = CHIP_ID_8710AF; + if (HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xF8, + &ChipId, L25EOUTVOLTAGE) != 1) + DBG_8195A("Get Chip ID Failed\r"); + return ChipId; +} + +/* + * 16 bytes FIFO ... 16*11/38400 = 0.004583 sec + * (0.005/5)*166666666 = 166666.666 Tcpu + */ +LOCAL void INFRA_START_SECTION loguart_wait_tx_fifo_empty(void) { + if (HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_LOG_UART_EN) { + int x = 16384; + while ((!(HAL_READ8(LOG_UART_REG_BASE, 0x14) & BIT6)) && x--) + ; // иначе глючит LogUART, если переключение CLK приходится на вывод символов ! + } +} + +extern SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // 100021ec [144=0x90] +LOCAL uint32 InitTabParaAllClk[3 * CPU_CLK_TYPE_NO] = { + 0x01310102, // BaudRate = 2, RdDummyCyle = 2, DelayLine = 63, SIO + 0x03310101, // 0201 - 40t, 0101 - 39t, 0102 - 72t, 0103 - 104t + 0x05310001, // 39t + 0x07310001, + 0x09310001, + 0x0B310001, + + 0x11311301, // BaudRate = 1, RdDummyCyle = 19, DelayLine = 63, DIO + 0x13311201, // 1201 - 36t + 0x15311101, // 1101 - 35t + 0x17311101, + 0x19311101, + 0x1B311101, + + 0x21311301, // BaudRate = 1, RdDummyCyle = 19, DelayLine = 63, DIO + 0x23311201, // 1201 - 36t + 0x25311101, // 1101 - 35t + 0x27311101, + 0x29311101, + 0x2B311101, +}; + +struct spic_table_flash_type { + uint8 cmd[12]; + uint8 strlr2; + uint8 fbaud; + uint8 addrlen; + uint8 fsize; + uint32 contrl; + uint16 validcmd[3]; + uint8 manufacturerid; + uint8 memorytype; +}; + +//PSPIC_INIT_PARA pSpicInitPara; + +struct spic_table_flash_type spic_table_flash = { + { // for FLASH MX25L8006E/1606E + FLASH_CMD_FREAD, // REG_SPIC_READ_FAST_SINGLE 0x400060E0 0x0B + FLASH_CMD_DREAD, // REG_SPIC_READ_DUAL_DATA 0x400060E4 0x3B + FLASH_CMD_DREAD, // REG_SPIC_READ_DUAL_ADDR_DATA 0x400060E8 0x3B ? + FLASH_CMD_QREAD, // REG_SPIC_READ_QUAD_DATA 0x400060EC 0x6B + FLASH_CMD_4READ, // REG_SPIC_READ_QUAD_ADDR_DATA 0x400060F0 0xEB ? + FLASH_CMD_PP, // REG_SPIC_WRITE_SIGNLE 0x400060F4 0x02 + FLASH_CMD_DPP, // REG_SPIC_WRITE_DUAL_DATA 0x400060F8 0xA2 + FLASH_CMD_DPP, // REG_SPIC_WRITE_DUAL_ADDR_DATA 0x400060FC 0xA2 ? + FLASH_CMD_QPP, // REG_SPIC_WRITE_QUAD_DATA 0x40006100 0x32 + FLASH_CMD_4PP, // REG_SPIC_WRITE_QUAD_ADDR_DATA 0x40006104 0x38 + FLASH_CMD_WREN, // REG_SPIC_WRITE_ENABLE 0x40006108 0x06 + FLASH_CMD_RDSR // REG_SPIC_READ_STATUS 0x4000610C 0x05 + }, + BIT_FIFO_ENTRY(5) | BIT_SO_DUM, // REG_SPIC_CTRLR2 0x40006110 0x51 + BIT_FSCKDV(1), // REG_SPIC_FBAUDR 0x40006114 0x01 + BIT_ADDR_PHASE_LENGTH(3), // REG_SPIC_ADDR_LENGTH 0x40006118 0x03 + BIT_FLASE_SIZE(0x0F), // REG_SPIC_FLASE_SIZE 0x40006124 0x0E ? + BIT_CS_H_WR_DUM_LEN(2)| BIT_AUTO_ADDR__LENGTH(3) | BIT_RD_DUMMY_LENGTH(0x0), // REG_SPIC_AUTO_LENGTH 0x4000611C 0x20030001 ? + { + BIT_WR_BLOCKING, // REG_SPIC_VALID_CMD 0x40006120 0x200 SpicOneBitMode + BIT_WR_BLOCKING | BIT_RD_DUAL_I, // REG_SPIC_VALID_CMD 0x40006120 0x200 SpicOneBitMode + BIT_WR_BLOCKING | BIT_RD_QUAD_O, // REG_SPIC_VALID_CMD 0x40006120 0x200 SpicOneBitMode + }, + 0xC2, 0x20 // MX25L8006/MX25L1606 +}; + +LOCAL void BOOT_RAM_TEXT_SECTION InitSpicBdRDCDL(PSPIC_INIT_PARA pspic) { + // Disable SPI_FLASH User Mode +// HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + DBG_8195A("%p = %p, %p\n", 0x40006000+REG_SPIC_AUTO_LENGTH, HAL_SPI_READ32(REG_SPIC_BAUDR), pspic->RdDummyCyle); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, (HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH) & 0xFFFF0000) | pspic->RdDummyCyle); +// DBG_8195A("%p = %p, %p\n", 0x40006000+REG_SPIC_SER, HAL_SPI_READ32(REG_SPIC_SER), BIT_SER); +// HAL_SPI_WRITE32(REG_SPIC_SER, BIT_SER); + + FLASH_DDL_FCTRL(pspic->DelayLine); // SPI_DLY_CTRL_ADDR [7:0] + +// DBG_8195A("%p = %p, %p\n", 0x40006000 + REG_SPIC_CTRLR1, HAL_SPI_READ32(REG_SPIC_CTRLR1), BIT_NDF(4)); +// HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(4)); + + + uint32 regval = HAL_SPI_READ32(REG_SPIC_CTRLR0) + & (~(BIT_CMD_CH(3) | BIT_DATA_CH(3) | BIT_ADDR_CH(3))); + + if(pspic->Mode.BitMode == SpicDualBitMode) { + regval |= BIT_ADDR_CH(1) | BIT_DATA_CH(1); + } + else if(pspic->Mode.BitMode == SpicQuadBitMode) { + regval |= BIT_ADDR_CH(2) | BIT_DATA_CH(2); + } + DBG_8195A("%p = %p, %p\n", 0x40006000+REG_SPIC_CTRLR0, HAL_SPI_READ32(REG_SPIC_CTRLR0), regval); + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, regval); + + + DBG_8195A("%p = %p, %p\n", 0x40006000+REG_SPIC_VALID_CMD, HAL_SPI_READ32(REG_SPIC_VALID_CMD), spic_table_flash.validcmd[pspic->Mode.BitMode]); + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, spic_table_flash.validcmd[pspic->Mode.BitMode]); + + DBG_8195A("%p = %p, %p\n", 0x40006000+REG_SPIC_BAUDR, HAL_SPI_READ32(REG_SPIC_BAUDR), pspic->BaudRate); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, pspic->BaudRate); // & 0x00000FFF)); + + // Enable SPI_FLASH User Mode +// HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); +// SpicWaitWipDoneRtl8195A(SpicInitParaAllClk[1][0]); +} + +void BOOT_RAM_TEXT_SECTION InitSpicFlashType(struct spic_table_flash_type *ptable_flash) { + u8 * ptrb = &ptable_flash->cmd; + volatile u32 * ptrreg = (volatile u32 *)(SPI_FLASH_CTRL_BASE + REG_SPIC_READ_FAST_SINGLE);// 0x400060E0 + do { + DBG_8195A("%p = %p, %p\n", ptrreg, *ptrreg, *ptrb); + *ptrreg++ = *ptrb++; + } while(ptrb < (u8 *)(&ptable_flash->fsize)); + DBG_8195A("%p = %p, %p\n", ptrreg, *ptrreg, ptable_flash->contrl); + ptrreg[0] = ptable_flash->contrl; + DBG_8195A("%p = %p, %p\n", &ptrreg[1], ptrreg[1], ptable_flash->validcmd[SpicOneBitMode]); + ptrreg[1] = ptable_flash->validcmd[SpicOneBitMode]; + DBG_8195A("%p = %p, %p\n", &ptrreg[2], ptrreg[2], ptable_flash->fsize); + ptrreg[2] = ptable_flash->fsize; +} + +LOCAL int BOOT_RAM_TEXT_SECTION InitSpic(uint8 SpicBitMode) { +#if 0 +// *(uint32 *)(&SpicInitParaAllClk[0][0].BaudRate) = 0x1311301; // patch + SpicInitRtl8195AV02(CPU_CLK_TYPE_NO - 1 - ((HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) >> 4) & 7), + SpicDualBitMode); +#else +// SpicInitRtl8195AV02(1, SpicDualBitMode); // SpicOneBitMode); // 5-168, 4-136, 3-104, 2-72, 1- +// InitSpicBdRDCDL(&SpicInitParaAllClk[1][0]); +// SpicLoadInitParaFromClockRtl8195A(0, 1, &SpicInitParaAllClk[1][0]); +#endif + + _memset(SpicInitParaAllClk, 0, sizeof(SpicInitParaAllClk)); + uint32 * ptr = InitTabParaAllClk; + uint8 x; + for(x = 0; x < SpicMaxMode; x++) { + *(uint32 *)&SpicInitParaAllClk[SpicOneBitMode][x].BaudRate = ptr[0]; + *(uint32 *)&SpicInitParaAllClk[SpicDualBitMode][x].BaudRate = ptr[CPU_CLK_TYPE_NO]; + *(uint32 *)&SpicInitParaAllClk[SpicQuadBitMode][x].BaudRate = ptr[CPU_CLK_TYPE_NO + CPU_CLK_TYPE_NO]; + ptr++; + } + ACTCK_FLASH_CCTRL(1); + SLPCK_FLASH_CCTRL(1); + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); + InitSpicFlashType(&spic_table_flash); + InitSpicBdRDCDL(&SpicInitParaAllClk[SpicBitMode][((HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) >> 4) & 7)]); +#if 0 // 72 + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, 0x20030002); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, 2); + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, BIT_WR_BLOCKING); +#else // 36 +// HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, 0x20030013); +// HAL_SPI_WRITE32(REG_SPIC_BAUDR, 1); +// HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, BIT_WR_BLOCKING | BIT_RD_DUAL_I); +#endif + HAL_SPI_WRITE32(REG_SPIC_SER, BIT_SER); + SPI_FLASH_PIN_FCTRL(ON); + + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + + +// if(!SpicCmpDataForCalibrationRtl8195A()) { + for(int i = 1; i < 4; i++) { + for(int x = 0; x < 63; x++) { + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, 0x20030000 + x); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, i); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + FLASH_DDL_FCTRL(49); // SPI_DLY_CTRL_ADDR [7:0] +// HAL_SPI_WRITE32(REG_SPIC_FLUSH_FIFO, 1); + if(SpicCmpDataForCalibrationRtl8195A()) { + DiagPrintf("Spic init %d:%d:49\n", i, x); + return 1; + }; + }; + }; + return 0; +// }; +// return 1; +} + + +/* SYSPlatformInit */ +LOCAL void INFRA_START_SECTION SYSPlatformInit(void) { + __asm__ __volatile__ ("cpsid f\n"); + JtagOn(); + SetDebugFlgs(); + //----- SYS Init + HAL_SYS_CTRL_WRITE32(REG_SYS_EFUSE_SYSCFG0, + (HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG0) & (~(BIT_MASK_SYS_EEROM_LDO_PAR_07_04 << BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04))) | BIT_SYS_EEROM_LDO_PAR_07_04(6)); // & 0xF0FFFFFF | 0x6000000 + HAL_SYS_CTRL_WRITE32(REG_SYS_XTAL_CTRL1, + (HAL_SYS_CTRL_READ32(REG_SYS_XTAL_CTRL1) & (~(BIT_MASK_SYS_XTAL_DRV_RF1 << BIT_SHIFT_SYS_XTAL_DRV_RF1))) | BIT_SYS_XTAL_DRV_RF1(1)); // & 0xFFFFFFE7 | 8; + //----- SDIO_Device_Off + HAL_PERI_ON_WRITE32(REG_PESOC_HCI_CLK_CTRL0, + HAL_PERI_ON_READ32(REG_PESOC_HCI_CLK_CTRL0) & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_PERI_ON_WRITE32(REG_SOC_HCI_COM_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_HCI_COM_FUNC_EN) & (~(BIT_SOC_HCI_SDIOD_ON_EN | BIT_SOC_HCI_SDIOD_OFF_EN))); + HAL_PERI_ON_WRITE32(REG_HCI_PINMUX_CTRL, + HAL_PERI_ON_READ32(REG_HCI_PINMUX_CTRL) & (~(BIT_HCI_SDIOD_PIN_EN))); + //----- GPIO Adapter + extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter; + _memset(&gBoot_Gpio_Adapter, 0, sizeof(gBoot_Gpio_Adapter)); + _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; +#ifdef DEFAULT_BOOT_CLK_CPU + //----- CLK CPU + loguart_wait_tx_fifo_empty(); // иначе глючит LogUART, если переключение CLK приходится на вывод символов ! +#if DEFAULT_BOOT_CPU_CLOCK_SEL_DIV5_3 + // 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000 Hz + HalCpuClkConfig(DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE); + *((int *)(SYSTEM_CTRL_BASE+REG_SYS_SYSPLL_CTRL1)) |= (1<<17);// REG_SYS_SYSPLL_CTRL1 |= BIT_SYS_SYSPLL_DIV5_3 +#else + // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz + *((int *) (SYSTEM_CTRL_BASE + REG_SYS_SYSPLL_CTRL1)) &= ~(1 << 17); // REG_SYS_SYSPLL_CTRL1 &= ~BIT_SYS_SYSPLL_DIV5_3 + HalCpuClkConfig(DEFAULT_BOOT_CPU_CLOCK_SEL_VALUE); +#endif // CPU_CLOCK_SEL_DIV5_3 +#endif // DEFAULT_CLK_CPU + //----- System + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + HalInitPlatformLogUartV02(); // Show ""... :( + HalInitPlatformTimerV02(); + __asm__ __volatile__ ("cpsie f\n"); +} + +/*------------------------------------------------------------------------------------- + Копирует данные из области align(4) (flash, registers, ...) в область align(1) (ram) + --------------------------------------------------------------------------------------*/ +LOCAL unsigned int BOOT_RAM_TEXT_SECTION flashcpy(unsigned int faddr, + void *dist, unsigned int size) { + union { + unsigned char uc[4]; + unsigned int ud; + } tmp; + if (faddr < SPI_FLASH_BASE) + faddr += SPI_FLASH_BASE; + unsigned char * pd = (unsigned char *) dist; + unsigned int *p = (unsigned int *) ((unsigned int) faddr & (~3)); + unsigned int xlen = (unsigned int) faddr & 3; + unsigned int len = size; + + if (xlen) { + tmp.ud = *p++; + while (len) { + len--; + *pd++ = tmp.uc[xlen++]; + if (xlen & 4) + break; + }; + }; + xlen = len >> 2; + while (xlen) { + tmp.ud = *p++; + *pd++ = tmp.uc[0]; + *pd++ = tmp.uc[1]; + *pd++ = tmp.uc[2]; + *pd++ = tmp.uc[3]; + xlen--; + }; + if (len & 3) { + tmp.ud = *p; + pd[0] = tmp.uc[0]; + if (len & 2) { + pd[1] = tmp.uc[1]; + if (len & 1) { + pd[2] = tmp.uc[2]; + }; + }; + }; + return size; +} + +enum { + SEG_ID_ERR, + SEG_ID_SRAM, + SEG_ID_TCM, + SEG_ID_SDRAM, + SEG_ID_SOC, + SEG_ID_FLASH, + SEG_ID_CPU, + SEG_ID_ROM, + SEG_ID_MAX +} SEG_ID; + +LOCAL const char * const txt_tab_seg[] = { + "UNK", // 0 + "SRAM", // 1 + "TCM", // 2 + "SDRAM", // 3 + "SOC", // 4 + "FLASH", // 5 + "CPU", // 6 + "ROM" // 7 + }; + +LOCAL const uint32 tab_seg_def[] = { 0x10000000, 0x10070000, 0x1fff0000, + 0x20000000, 0x30000000, 0x30200000, 0x40000000, 0x40800000, 0x98000000, + 0xA0000000, 0xE0000000, 0xE0010000, 0x00000000, 0x00050000 }; + +LOCAL uint32 BOOT_RAM_TEXT_SECTION get_seg_id(uint32 addr, int32 size) { + uint32 ret = SEG_ID_ERR; + uint32 * ptr = &tab_seg_def; + if (size > 0) { + do { + ret++; + if (addr >= ptr[0] && addr + size <= ptr[1]) { + return ret; + }; + ptr += 2; + } while (ret < SEG_ID_MAX); + }; + return 0; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_img2_head(uint32 faddr, PIMG2HEAD hdr) { + flashcpy(faddr, hdr, sizeof(IMG2HEAD)); + uint32 ret = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (hdr->sign[1] == IMG_SIGN2_RUN) { + if (hdr->sign[0] == IMG_SIGN1_RUN) { + ret |= 1 << 9; + } else if (hdr->sign[0] == IMG_SIGN1_SWP) { + ret |= 1 << 8; + }; + } + if (*(u32 *) (&hdr->rtkwin) == IMG2_SIGN_DW1_TXT) { + ret |= 1 << 10; + }; + return ret; +} + +LOCAL uint32 BOOT_RAM_TEXT_SECTION load_segs(uint32 faddr, PIMG2HEAD hdr, + uint8 flgload) { + uint32 fnextaddr = faddr; + uint8 segnum = 0; + while (1) { + uint32 seg_id = get_seg_id(hdr->seg.ldaddr, hdr->seg.size); + if (flgload + && (seg_id == SEG_ID_SRAM || seg_id == SEG_ID_TCM + || seg_id == SEG_ID_SDRAM)) { +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("Load Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", + segnum, faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, + hdr->seg.size); +#endif + fnextaddr += flashcpy(fnextaddr, hdr->seg.ldaddr, hdr->seg.size); + } else if (seg_id) { +#if CONFIG_DEBUG_LOG > 2 + DBG_8195A("Skip Flash seg%d: 0x%08x -> %s: 0x%08x, size: %d\n", segnum, + faddr, txt_tab_seg[seg_id], hdr->seg.ldaddr, hdr->seg.size); +#endif + fnextaddr += hdr->seg.size; + } else { + break; + } + fnextaddr += flashcpy(fnextaddr, &hdr->seg, sizeof(IMGSEGHEAD)); + segnum++; + } + return fnextaddr; +} + +/*------------------------------------------------------------------------------------- + * 0 - default image (config data + 0), 1 - image N1, 2 - image N2, ... + --------------------------------------------------------------------------------------*/ +LOCAL int BOOT_RAM_TEXT_SECTION loadUserImges(int imgnum) { + IMG2HEAD hdr; + int imagenum = 1; + uint32 faddr = 0xb000; // start image2 in flash + DBG_8195A("Selected Image %d.\n", imgnum); + + while (1) { + faddr = (faddr + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + uint32 img_id = load_img2_head(faddr, &hdr); + if ((img_id >> 8) > 4 || (uint8) img_id != 0) { + faddr = load_segs(faddr + 0x10, &hdr.seg, imagenum == imgnum); + if (imagenum == imgnum) { +// DBG_8195A("Image%d: %s\n", imgnum, hdr.name); + break; + } + imagenum++; + } else if (imagenum) { + DBG_8195A("No Image%d! Trying Image0...\n", imgnum); + // пробуем загрузить image по умолчанию, по записи в секторе установок + flashcpy(FLASH_SYSTEM_DATA_ADDR, &faddr, sizeof(faddr)); + if (faddr < 0x8000000) + faddr += SPI_FLASH_BASE; + if (get_seg_id(faddr, 0x100) == SEG_ID_FLASH) { + imagenum = 0; + imgnum = 0; + } else { + DBG_8195A("No Image0!\n"); + imagenum = -1; + break; + }; + } else { + imagenum = -1; + break; + } + }; + return imagenum; +} + +//----- IsForceLoadDefaultImg2 +LOCAL uint8 BOOT_RAM_TEXT_SECTION IsForceLoadDefaultImg2(void) { + uint8 gpio_pin[4]; + HAL_GPIO_PIN GPIO_Pin; + HAL_GPIO_PIN_STATE flg; + int result = 0; + flashcpy(FLASH_SYSTEM_DATA_ADDR + 0x08, &gpio_pin, sizeof(gpio_pin)); // config data + 8 +// _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; + for (int i = 1; i; i--) { + uint8 x = gpio_pin[i]; + result <<= 1; + if (x != 0xff) { + GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(x & 0x7F); + if (x & 0x80) { + GPIO_Pin.pin_mode = DIN_PULL_LOW; + flg = GPIO_PIN_HIGH; + } else { + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + flg = GPIO_PIN_LOW; + } + HAL_GPIO_Init_8195a(&GPIO_Pin); + if (HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == flg) { + result |= 1; + } + HAL_GPIO_DeInit_8195a(&GPIO_Pin); + } + } +// _pHAL_Gpio_Adapter->IrqHandle.IrqFun = NULL; + return result; +} +/* RTL Console ROM */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlConsolRam(void) { +// DiagPrintf("\r\nRTL Console ROM\r\n"); +// RtlConsolInit(ROM_STAGE, (u32) 6, (void*) &UartLogRomCmdTable); + pUartLogCtl->RevdNo = UART_LOG_HISTORY_LEN; + pUartLogCtl->BootRdy = 1; + pUartLogCtl->pTmpLogBuf->UARTLogBuf[0] = '?'; + pUartLogCtl->pTmpLogBuf->BufCount = 1; + pUartLogCtl->ExecuteCmd = 1; + RtlConsolTaskRom(pUartLogCtl); +} + +/* Enter Image 1.5 */ +LOCAL void BOOT_RAM_TEXT_SECTION EnterImage15(int flg) { + + if (flg) + _memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + + SYSPlatformInit(); + + if (!flg) + DBG_8195A("\r===== Enter FLASH-Boot ====\n"); + else + DBG_8195A("\r===== Enter SRAM-Boot %d ====\n", flg); + +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("CPU CLK: %d Hz, SOC FUNC EN: %p\r\n", HalGetCpuClk(), + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN)); +#endif + uint8 ChipId = _Get_ChipId(); + if (ChipId < CHIP_ID_8195AM) { + //----- SDRAM Off + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); // Flag SDRAM Off + } else { + //----- SDRAM On + LDO25M_CTRL(ON); + HAL_SYS_CTRL_WRITE32(REG_SYS_REGU_CTRL0, + (HAL_SYS_CTRL_READ32(REG_SYS_REGU_CTRL0) & 0xfffff) | BIT_SYS_REGU_LDO25M_ADJ(0x0e)); + SDR_PIN_FCTRL(ON); + }; + InitSpic(SpicDualBitMode); // SpicOneBitMode) + if (!SpicCmpDataForCalibrationRtl8195A()) { + DBG_8195A("Error Init Spic DIO!\n"); + RtlConsolRam(); + } + if ((HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT(21)) == 0) { // уже загружена? +// extern DRAM_DEVICE_INFO SdrDramInfo_rom; // 50 MHz + if (!SdrControllerInit_rom(&SdrDramInfo)) { // 100 MHz + DBG_8195A("SDR Controller Init fail!\n"); + RtlConsolRam(); + } +#if 0 // Test SDRAM + else { + uint32 *ptr = SDR_SDRAM_BASE; + uint32 tt = 0x55AA55AA; + for (int i = 0; i < 512 * 1024; i++) { + ptr[i] = tt++; + }; + tt = 0x55AA55AA; + for (int i = 0; i < 512 * 1024; i++) { + if (ptr[i] != tt) { + DBG_8195A("SDR err %p %p != %p!\n", &ptr[i], ptr[i], tt); + RtlConsolRam(); + } + tt++; + }; + DBG_8195A("SDR tst end\n"); + }; +#endif // test + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); + }; + if (!flg) + loadUserImges(IsForceLoadDefaultImg2() + 1); + if (_strcmp((const char *) &__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image Signature!\n"); + RtlConsolRam(); + } + DBG_8195A("Img Sign: %s, Go @ 0x%08x\r\n", &__image2_validate_code__, + __image2_entry_func__); + __image2_entry_func__(); +} + +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot1ToSram(void) { + EnterImage15(1); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot2ToSram(void) { + EnterImage15(2); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot3ToSram(void) { + EnterImage15(3); +} +/* RtlBootToSram */ +LOCAL void BOOT_RAM_TEXT_SECTION RtlBoot4ToSram(void) { + EnterImage15(4); +} + +LOCAL void BOOT_RAM_TEXT_SECTION RtlBootToFlash(void) { + EnterImage15(0); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup.c new file mode 100644 index 0000000..209310d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup.c @@ -0,0 +1,207 @@ +/* + * StartUp SDK + * Created on: 02/03/2017 + * Author: pvvx + */ + +#include "rtl8195a.h" +#include "diag.h" +#include "hal_spi_flash.h" +#include "hal_api.h" +#include "hal_platform.h" +#include "diag.h" +#include "hal_diag.h" +#include "rtl8195a_uart.h" +#include "rtl8195a/rtl8195a_peri_on.h" +#include "hal_peri_on.h" +#include "rtl_bios_data.h" +#include "wifi_conf.h" +#include "rtl_consol.h" + +//------------------------------------------------------------------------- +// Function declarations +void InfraStart(void); +//extern void HalWdgIntrHandle(void); +extern void xPortPendSVHandler(void); +extern void xPortSysTickHandler(void); +extern void vPortSVCHandler(void); +extern void rtl_libc_init(void); +//extern void ShowRamBuildInfo(void); // app_start.c: VOID ShowRamBuildInfo(VOID) +//void HalNMIHandler_Patch(void); +void SDIO_Device_Off(void); +//void VectorTableOverrideRtl8195A(u32 StackP); +void SYSPlatformInit(void); + +//------------------------------------------------------------------------- +// Data declarations +extern u8 __bss_start__, __bss_end__; +extern const unsigned char cus_sig[32]; // images name +//extern HAL_TIMER_OP HalTimerOp; + +IMAGE2_START_RAM_FUN_SECTION RAM_START_FUNCTION gImage2EntryFun0 = + { InfraStart + 1 }; + +/* +//----- HalNMIHandler_Patch +void HalNMIHandler_Patch(void) { + DBG_8195A_HAL("%s:NMI Error!\n", __func__); + if ( HAL_READ32(VENDOR_REG_BASE, 0) < 0) + HalWdgIntrHandle(); // ROM: HalWdgIntrHandle = 0x3485; +} +*/ + +/* + * 16 bytes FIFO ... 16*11/38400 = 0.004583 sec + * (0.005/5)*166666666 = 166666.666 + */ +LOCAL void INFRA_START_SECTION loguart_wait_tx_fifo_empty(void) { + int x = 16384; + while((!(HAL_READ8(LOG_UART_REG_BASE, 0x14) & BIT6)) && x--); +} + +//----- SDIO_Device_Off +void INFRA_START_SECTION SDIO_Device_Off(void) { + HAL_PERI_ON_WRITE32(REG_PESOC_HCI_CLK_CTRL0, + HAL_PERI_ON_READ32(REG_PESOC_HCI_CLK_CTRL0) + & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_PERI_ON_WRITE32(REG_SOC_HCI_COM_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_HCI_COM_FUNC_EN) + & (~(BIT_SOC_HCI_SDIOD_ON_EN | BIT_SOC_HCI_SDIOD_OFF_EN))); + HAL_PERI_ON_WRITE32(REG_HCI_PINMUX_CTRL, + HAL_PERI_ON_READ32(REG_HCI_PINMUX_CTRL) + & (~(BIT_HCI_SDIOD_PIN_EN))); +} + +//----- SYSPlatformInit +void INFRA_START_SECTION SYSPlatformInit(void) { + HAL_SYS_CTRL_WRITE32(REG_SYS_EFUSE_SYSCFG0, + (HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG0) + & (~(BIT_MASK_SYS_EEROM_LDO_PAR_07_04 << BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04))) + | BIT_SYS_EEROM_LDO_PAR_07_04(6)); // & 0xF0FFFFFF | 0x6000000 + HAL_SYS_CTRL_WRITE32(REG_SYS_XTAL_CTRL1, + (HAL_SYS_CTRL_READ32(REG_SYS_XTAL_CTRL1) + & (~(BIT_MASK_SYS_XTAL_DRV_RF1 << BIT_SHIFT_SYS_XTAL_DRV_RF1))) + | BIT_SYS_XTAL_DRV_RF1(1)); // & 0xFFFFFFE7 | 8; +} + +// weak __low_level_init function! +__weak void __low_level_init(void) { +} + +// weak main function! +__weak int main(void) { + DiagPrintf("\r\nRTL Console ROM: Start - press key 'Up', Help '?'\r\n"); + while (pUartLogCtl->ExecuteEsc != 1); + pUartLogCtl->RevdNo = 0; + pUartLogCtl->BootRdy = 1; + DiagPrintf("\r"); + while (1) { + while (pUartLogCtl->ExecuteCmd != 1); + UartLogCmdExecute(pUartLogCtl); + DiagPrintf("\r"); + pUartLogCtl->ExecuteCmd = 0; + } + return 0; +} + +//----- InfraStart +void INFRA_START_SECTION InfraStart(void) { +// NewVectorTable[2] = HalNMIHandler_Patch; + DBG_8195A("===== Enter Image: %s ====\n", cus_sig); +// ShowRamBuildInfo(); // app_start.c: VOID ShowRamBuildInfo(VOID) + memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__); + rtl_libc_init(); // ROM Lib C init (rtl_printf!) +// SYSPlatformInit(); +// SDIO_Device_Off(); + //- Должно быть в boot +extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter; + memset(&gBoot_Gpio_Adapter, 0, sizeof(gBoot_Gpio_Adapter)); + _pHAL_Gpio_Adapter = &gBoot_Gpio_Adapter; + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + loguart_wait_tx_fifo_empty(); // иначе глючит LogUART, если переключение CLK приходится на вывод символов ! +#if 1 // if set CLK CPU + if(HalGetCpuClk() != PLATFORM_CLOCK) { + //----- CLK CPU +#if CPU_CLOCK_SEL_DIV5_3 + // 6 - 200000000 Hz, 7 - 10000000 Hz, 8 - 50000000 Hz, 9 - 25000000 Hz, 10 - 12500000 Hz, 11 - 4000000 Hz + HalCpuClkConfig(CPU_CLOCK_SEL_VALUE); + *((int *)(SYSTEM_CTRL_BASE+REG_SYS_SYSPLL_CTRL1)) |= (1<<17);// REG_SYS_SYSPLL_CTRL1 |= BIT_SYS_SYSPLL_DIV5_3 +#else + // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz + *((int *) (SYSTEM_CTRL_BASE + REG_SYS_SYSPLL_CTRL1)) &= ~(1 << 17); // REG_SYS_SYSPLL_CTRL1 &= ~BIT_SYS_SYSPLL_DIV5_3 + HalCpuClkConfig(CPU_CLOCK_SEL_VALUE); +#endif // CPU_CLOCK_SEL_DIV5_3 + }; +#endif + PSHalInitPlatformLogUart(); // HalInitPlatformLogUartV02(); // Show ""... :( + HalReInitPlatformTimer(); // HalInitPlatformTimerV02(); HalTimerOpInit_Patch((VOID*) (&HalTimerOp)); + SystemCoreClockUpdate(); + En32KCalibration(); + + //---- Spic +// _memset(SpicInitParaAllClk, 0, sizeof(SpicInitParaAllClk)); + *(uint32 *)(&SpicInitParaAllClk[0][0].BaudRate) = 0x01310202; // patch + *(uint32 *)(&SpicInitParaAllClk[1][0].BaudRate) = 0x11311301; // patch +// *(uint32 *)(&SpicInitParaAllClk[2][0].BaudRate) = 0x21311301; // patch + SPI_FLASH_PIN_FCTRL(ON); +/* +// uint8 SpicBaudRate = CPU_CLK_TYPE_NO - 1 - ((HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) >> 4) & 7); + uint8 SpicBaudRate = 3; // HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) >> 4) & 7; + DBG_8195A("SpicBaudRate = %d\n", SpicBaudRate); + SpicInitRtl8195AV02(SpicBaudRate, SpicDualBitMode); + if(!SpicCmpDataForCalibrationRtl8195A()) { + DBG_8195A("ReInit Spic to SIO...\n"); + SpicInitRtl8195AV02(SpicBaudRate, SpicOneBitMode); + if(!SpicCmpDataForCalibrationRtl8195A()) { + DBG_8195A("Error Init Spic!\n"); + }; + }; +*/ +// SpicFlashInitRtl8195A(SpicDualBitMode); // SpicReadIDRtl8195A(); SpicDualBitMode + //---- SDRAM + uint8 ChipId = HalGetChipId(); + if (ChipId >= CHIP_ID_8195AM) { +#ifdef CONFIG_SDR_EN + if((HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT(21)) == 0) { // уже загружена? + SdrCtrlInit(); + if(SdrControllerInit()) { + DBG_8195A("SDR Controller Init fail!\n"); + }; + }; +#endif + // clear SDRAM bss + extern uint8 __sdram_bss_start__[]; + extern uint8 __sdram_bss_end__[]; + if((uint32)__sdram_bss_end__-(uint32)__sdram_bss_start__ > 0) + memset(__sdram_bss_start__, 0, (uint32)__sdram_bss_end__-(uint32)__sdram_bss_start__); + } + else + { + //----- SDRAM Off + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); // Flag SDRAM Off + }; + //----- Close Flash + SPI_FLASH_PIN_FCTRL(OFF); + + InitSoCPM(); + VectorTableInitForOSRtl8195A(&vPortSVCHandler, &xPortPendSVHandler, + &xPortSysTickHandler); + +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("\rSet CPU CLK: %d Hz, SOC FUNC EN: %p\r\n", HalGetCpuClk(), HAL_PERI_ON_READ32(REG_SOC_FUNC_EN)); +#endif + + // force SP align to 8 byte not 4 byte (initial SP is 4 byte align) + __asm( + "mov r0, sp\n" + "bic r0, r0, #7\n" + "mov sp, r0\n" + ); + + __low_level_init(); + + main(); +} + diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c new file mode 100644 index 0000000..54c48c1 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/startup_old.c @@ -0,0 +1,827 @@ +/* + * BootLoader + * startup.o sdk-ameba-rtl8710af-v3.5a_without_NDA_GCC_V1.0.0 + * pvvx 2016 + */ + +#include "rtl8195a.h" +#include "diag.h" +#include "hal_spi_flash.h" +#include "hal_api.h" +#include "hal_platform.h" +#include "diag.h" +#include "hal_diag.h" +#include "rtl8195a_uart.h" +#include "rtl8195a/rtl8195a_peri_on.h" +#include "hal_peri_on.h" +#include "wifi_conf.h" +#include "rtl_consol.h" + +#ifndef USE_SRC_ONLY_BOOT +#define USE_SRC_ONLY_BOOT 0 +#endif + +#if USE_SRC_ONLY_BOOT +#define rtl_memset _memset +#define rtl_strcmp _strcmp +#define rtl_memcpy _memcpy +#endif + +#define VREG32(addr) (*((volatile u32*)(addr))) + +typedef void (*START_FUNC)(void); + +#ifndef DEFAULT_BAUDRATE +#define DEFAULT_BAUDRATE UART_BAUD_RATE_38400 +#endif + +#define StartupSpicBitMode SpicDualBitMode // SpicOneBitMode +#define StartupSpicBaudRate 0 + +//------------------------------------------------------------------------- +// Function declarations +void PreProcessForVendor(void); // image1 +void RtlBootToSram(void); // image1 +u32 StartupHalLogUartInit(u32 uart_irq); // image1 +void StartupHalInitPlatformLogUart(void); // image1 +int IsForceLoadDefaultImg2(void); // image1 +void StartupHalSpicInit(int InitBaudRate); // image1 +int _GetChipId(void); // image1 +void RtlConsolRam(void); // image1 +extern VOID UartLogIrqHandle(VOID * Data); // in ROM +extern int RtlConsolRom(int); // in ROM +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; +extern VOID SpicUserReadRtl8195A(IN u32 Length, IN u32 addr, IN u8 * data, + IN u8 BitMode); +#if !USE_SRC_ONLY_BOOT +void InfraStart(void); +extern void HalWdgIntrHandle(void); +extern int wifi_off(void); // in wifi_conf.c +extern void xPortPendSVHandler(void); +extern void xPortSysTickHandler(void); +extern void vPortSVCHandler(void); +extern void ShowRamBuildInfo(void); // app_start.c: VOID ShowRamBuildInfo(VOID) +void HalNMIHandler_Patch(void); +void SDIO_Device_Off(void); +void VectorTableOverrideRtl8195A(u32 StackP); +void SYSPlatformInit(void); +void HalHardFaultHandler_Patch_c(u32 HardDefaultArg); +void __HalReInitPlatformLogUart(void); +void _ReloadImg(void); +void _ReloadImg_user_define(void); +void _CPUResetHandler(void); +void _CPUReset(void); +void HalHardFaultHandler_user_define(u32 HardDefaultArg); +#endif + +//------------------------------------------------------------------------- +// Data declarations +extern START_FUNC __image2_entry_func__; +extern u8 __image2_validate_code__; +extern u8 __image1_bss_start__, __image1_bss_end__; +extern u8 __rom_bss_start__, __rom_bss_end__; +//extern u32 STACK_TOP; +#define STACK_TOP 0x1FFFFFFC + +#if !USE_SRC_ONLY_BOOT +extern u32 * NewVectorTable; // LD: NewVectorTable = 0x10000000; +extern u8 __bss_start__, __bss_end__; +#endif + +//extern volatile UART_LOG_CTL * pUartLogCtl; +extern int UartLogCmdExecute(volatile u8 *); +/* +typedef struct __RAM_IMG2_VALID_PATTEN__ { + char rtkwin[7]; + u8 x[13]; +} _RAM_IMG2_VALID_PATTEN, *_PRAM_IMG2_VALID_PATTEN; +*/ +const uint8_t IMAGE1_VALID_PATTEN_SECTION RAM_IMG1_VALID_PATTEN[8] = + { 0x23, 0x79, 0x16, 0x88, 0xff, 0xff, 0xff, 0xff }; + +PRAM_FUNCTION_START_TABLE __attribute__((section(".data.pRamStartFun"))) pRamStartFun = + (PRAM_FUNCTION_START_TABLE) 0x10000BC8; + +#include + +struct _reent __attribute__((section(".libc.reent"))) impure_reent = _REENT_INIT(impure_reent); +//struct _reent * __attribute__((section(".libc.reent"))) _rtl_impure_ptr = { &impure_data }; +//struct _reent * __attribute__((at(0x1098))) __attribute__((section(".libc.reent"))) _rtl_impure_ptr = { &impure_data }; +struct _reent * __attribute__((at(0x10001c60))) __attribute__((section(".libc.reent"))) _rtl_impure_ptr = { &impure_reent }; + +/* ROM */ +MON_RAM_BSS_SECTION + volatile UART_LOG_CTL *pUartLogCtl; + +MON_RAM_BSS_SECTION + UART_LOG_BUF UartLogBuf; + +MON_RAM_BSS_SECTION + volatile UART_LOG_CTL UartLogCtl; + +MON_RAM_BSS_SECTION + u8 *ArgvArray[MAX_ARGV]; // *ArgvArray[10] ! + +MON_RAM_BSS_SECTION + u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; // UartLogHistoryBuf[5][127] ! + + +RAM_START_FUNCTION START_RAM_FUN_A_SECTION gRamStartFun = + { PreProcessForVendor + 1 }; +RAM_START_FUNCTION START_RAM_FUN_B_SECTION gRamPatchWAKE = + { RtlBootToSram + 1 }; +RAM_START_FUNCTION START_RAM_FUN_C_SECTION gRamPatchFun0 = + { RtlBootToSram + 1 }; +RAM_START_FUNCTION START_RAM_FUN_D_SECTION gRamPatchFun1 = + { RtlBootToSram + 1 }; +RAM_START_FUNCTION START_RAM_FUN_E_SECTION gRamPatchFun2 = + { RtlBootToSram + 1 }; + +#if !USE_SRC_ONLY_BOOT +RAM_START_FUNCTION IMAGE2_START_RAM_FUN_SECTION gImage2EntryFun0 = + { InfraStart + 1 }; +#else +RAM_START_FUNCTION IMAGE2_START_RAM_FUN_SECTION gImage2EntryFun0 = + { 0x100 }; +#endif // !USE_SRC_ONLY_BOOT +_RAM_IMG2_VALID_PATTEN IMAGE2_VALID_PATTEN_SECTION RAM_IMG2_VALID_PATTEN = + { { IMG2_SIGN_TXT }, { 0xff, 0, 1, 1, 0, 0x95, 0x81, 1, 1, 0, 0, 0, 0 } }; // "RTKWin" + +HAL_GPIO_ADAPTER PINMUX_RAM_DATA_SECTION gBoot_Gpio_Adapter; + +#pragma arm section code = ".hal.ram.text" +#pragma arm section rodata = ".hal.ram.rodata", rwdata = ".hal.ram.data", zidata = ".hal.ram.bss" + +#if !USE_SRC_ONLY_BOOT +//----- HalNMIHandler_Patch +void HalNMIHandler_Patch(void) { + DBG_8195A_HAL("RTL8195A[HAL]: %s:NMI Error!\n", __func__); + if ( HAL_READ32(VENDOR_REG_BASE, 0) < 0) + HalWdgIntrHandle(); // ROM: HalWdgIntrHandle = 0x3485; +} +#endif // !USE_SRC_ONLY_BOOT + + +void __attribute__((section(".hal.ram.text"))) SetDebugFlgs() { +#if CONFIG_DEBUG_LOG > 2 + ConfigDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = -1; +#elif CONFIG_DEBUG_LOG > 1 + ConfigDebugErr = -1; + ConfigDebugWarn = -1; + ConfigDebugInfo = 0; +#elif CONFIG_DEBUG_LOG > 0 + ConfigDebugErr = -1; + ConfigDebugWarn = 0; + ConfigDebugInfo = 0; +#else + ConfigDebugErr = 0; + ConfigDebugWarn = 0; + ConfigDebugInfo = 0; +#endif +} + +void __attribute__((section(".hal.ram.text"))) InitSpic(void) +{ + VREG32(0x40006000) = 0x01000300; + VREG32(0x40006004) = 0x1; + VREG32(0x400060E0) = 0x0B; + VREG32(0x400060E4) = 0x3B; + VREG32(0x400060E8) = 0x3B; + VREG32(0x400060EC) = 0x6B; + VREG32(0x400060F0) = 0xEB; + VREG32(0x400060F4) = 0x02; + VREG32(0x400060F8) = 0xA2; + VREG32(0x400060FC) = 0xA2; + VREG32(0x40006100) = 0x32; + VREG32(0x40006104) = 0x38; + VREG32(0x40006108) = 0x06; + VREG32(0x4000610C) = 0x05; + VREG32(0x40006110) = 0x51; + VREG32(0x40006114) = 0x01; + VREG32(0x40006118) = 0x03; + VREG32(0x4000611C) = 0x20030013; + VREG32(0x40006120) = 0x202; + VREG32(0x40006124) = 0x0E; +} + +//----- StartupHalLogUartInit +u32 __attribute__((section(".hal.ram.text"))) StartupHalLogUartInit(u32 uart_irq) { + HAL_UART_WRITE32(UART_DLH_OFF, 0); + + u32 SysClock = (HalGetCpuClk() >> 2); + u32 SampleRate = (16 * DEFAULT_BAUDRATE); + u32 Divisor = SysClock / SampleRate; + u32 Remaind = ((SysClock * 10) / SampleRate) - (Divisor * 10); + if (Remaind > 4) Divisor++; + // set DLAB bit to 1 +// HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, 0); + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, RUART_LINE_CTL_REG_DLAB_ENABLE); + HAL_UART_WRITE32(UART_DLL_OFF, Divisor & 0xff); + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 3); + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, FIFO_CTL_DEFAULT_WITH_FIFO); + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, uart_irq); + if (uart_irq) { + // Enable Peripheral_IRQ Setting for Log_Uart + HAL_WRITE32(VENDOR_REG_BASE, PERIPHERAL_IRQ_EN, 0x1000000); + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, + (HAL_READ32(0xE000ED00, 0x0C) & 0x0F8FF) | 0x5FA0300); + HAL_WRITE8(0xE000E100, 0x313, 0xE0); // HAL_WRITE8(0xE000E100, 0x313, 0xE0); + HAL_WRITE32(0xE000E100, 0, 0x80000); // NVIC enable external interrupt[?] ? + } + return 0; +} + +//----- StartupHalInitPlatformLogUart +void __attribute__((section(".hal.ram.text"))) StartupHalInitPlatformLogUart( + void) { + HAL_UART_READ32(UART_REV_BUF_OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (~(BIT_SOC_LOG_UART_EN))); // 40000210 &= 0xFFFFEFFF; // ~(1<<12) + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_LOG_UART_EN); // 40000210 |= 0x1000u; + ACTCK_LOG_UART_CCTRL(ON); // 40000230 |= 0x1000u; + StartupHalLogUartInit(IER_ERBFI | IER_ELSI); +} + +void __attribute__((section(".hal.ram.text"))) RtlConsolRam(void) +{ +// __asm__ __volatile__ ("cpsid f\n"); +// HalCpuClkConfig(0); // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz +// ConfigDebugErr = -1; +// VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC); +// HalInitPlatformLogUartV02(); +// HalReInitPlatformLogUartV02(); +// HalInitPlatformTimerV02(); + __asm__ __volatile__ ("cpsie f\n"); + + DiagPrintf("\r\nRTL Console ROM: Start - press 'ESC' key, Help '?'\r\n"); + while(!pUartLogCtl->ExecuteEsc); + pUartLogCtl->EscSTS = 0; + pUartLogCtl->BootRdy = 1; + DiagPrintf("\r"); + while(1) { + while(!pUartLogCtl->ExecuteCmd); + UartLogCmdExecute(pUartLogCtl); + DiagPrintf("\r"); + pUartLogCtl->ExecuteCmd = 0; + } +} + +//----- RtlBootToSram +void __attribute__((section(".hal.ram.text"))) RtlBootToSram(void) { + TIMER_ADAPTER tim_adapter; + /* JTAG On */ + ACTCK_VENDOR_CCTRL(ON); + SLPCK_VENDOR_CCTRL(ON); + HalPinCtrlRtl8195A(JTAG, 0, 1); + + memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + + /* Flash & LogUart On */ + HAL_PERI_ON_WRITE32(REG_GPIO_SHTDN_CTRL, 0x7FF); + SPI_FLASH_PIN_FCTRL(ON); + HAL_PERI_ON_WRITE32(REG_CPU_PERIPHERAL_CTRL, + HAL_PERI_ON_READ32(REG_CPU_PERIPHERAL_CTRL) | BIT_SPI_FLSH_PIN_EN); // 400002C0 |= 0x1u; + HAL_PERI_ON_WRITE32(REG_CPU_PERIPHERAL_CTRL, + HAL_PERI_ON_READ32(REG_CPU_PERIPHERAL_CTRL) | BIT_LOG_UART_PIN_EN); // 400002C0 |= 0x100000u; + + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_FLASH_EN); // 40000210 |= 0x10u; + ACTCK_FLASH_CCTRL(ON); + SLPCK_FLASH_CCTRL(ON); + HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); + + SpicNVMCalLoadAll(); + + HAL_SYS_CTRL_WRITE32(REG_SYS_CLK_CTRL1, + HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL1) & 0x8F); // VREG32(0x40000014) &= 0x8F; + + SetDebugFlgs(); + + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (~(BIT_SOC_LOG_UART_EN))); // 40000210 &= 0xFFFFEFFF; // ~(1<<12) + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_LOG_UART_EN); // 40000210 |= 0x1000u; + + ACTCK_LOG_UART_CCTRL(ON); +// SLPCK_LOG_UART_CCTRL(ON); + + tim_adapter.IrqHandle.IrqFun = &UartLogIrqHandle; + tim_adapter.IrqHandle.IrqNum = UART_LOG_IRQ; + tim_adapter.IrqHandle.Data = 0; + tim_adapter.IrqHandle.Priority = 5; + + StartupHalLogUartInit(0); + VectorIrqRegisterRtl8195A(&tim_adapter.IrqHandle); + StartupHalLogUartInit(IER_ERBFI | IER_ELSI); + + HAL_PERI_ON_WRITE32(REG_PON_ISO_CTRL, 3); // VREG32(0x40000204) = 3; + HAL_PERI_ON_WRITE32(REG_OSC32K_CTRL, + HAL_PERI_ON_READ32(REG_OSC32K_CTRL) | BIT_32K_POW_CKGEN_EN); // VREG32(0x40000270) |= 1u; + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_GTIMER_EN); // VREG32(0x40000210) |= 0x10000u; + + ACTCK_TIMER_CCTRL(ON); + SLPCK_TIMER_CCTRL(ON); + + tim_adapter.TimerIrqPriority = 0; + tim_adapter.TimerLoadValueUs = 0; + tim_adapter.TimerMode = FREE_RUN_MODE; + tim_adapter.IrqDis = 1; + tim_adapter.TimerId = 1; + HalTimerInitRtl8195a((PTIMER_ADAPTER) &tim_adapter); + + SpicInitRtl8195A(1, StartupSpicBitMode); // StartupSpicBaudRate InitBaudRate 1, SpicBitMode 1 StartupSpicBitMode + SpicFlashInitRtl8195A(StartupSpicBitMode); // SpicBitMode 1 StartupSpicBitMode + DBG_8195A("==*== Enter Image 1.5 ====\nImg2 Sign: %s, InfaStart @ 0x%08x\n", + &__image2_validate_code__, __image2_entry_func__); + if (strcmp((const char * )&__image2_validate_code__, IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image2 Signature!\n"); + RtlConsolRam(); + } +// InitSpic(); + __image2_entry_func__(); +} + +//----- SYSCpuClkConfig +void __attribute__((section(".hal.ram.text"))) SYSCpuClkConfig(int ChipID, int SysCpuClk) { + int flg = 0; + DBG_SPIF_INFO("SYSCpuClkConfig(0x%x)\n", SysCpuClk); + if(HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_FLASH_EN) { + SpicWaitWipRtl8195A(); //_SpicWaitWipDoneRefinedRtl8195A(); ??? + flg = 1; + } +// if (ChipID == CHIP_ID_8710AF && (!SysCpuClk)) SysCpuClk = 1; + HalCpuClkConfig(SysCpuClk); + HalDelayUs(1000); + StartupHalInitPlatformLogUart(); + if (flg) { + SpicOneBitCalibrationRtl8195A(SysCpuClk); // extern u32 SpicOneBitCalibrationRtl8195A(IN u8 SysCpuClk); +/* + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, + (HAL_SPI_READ32(REG_SPIC_VALID_CMD)|(FLASH_VLD_DUAL_CMDS))); */ + SpicCalibrationRtl8195A(StartupSpicBitMode, 0); + } +} + +//----- IsForceLoadDefaultImg2 +int __attribute__((section(".hal.ram.text"))) IsForceLoadDefaultImg2(void) { + u8 gpio_pin[4]; + HAL_GPIO_PIN GPIO_Pin; + HAL_GPIO_PIN_STATE flg; + int result = 0; + + *((u32 *) &gpio_pin) = HAL_READ32(SPI_FLASH_BASE, FLASH_SYSTEM_DATA_ADDR + 0x08); // config data + 8 + _pHAL_Gpio_Adapter = (int) &gBoot_Gpio_Adapter; + for(int i = 0; i < 2; i++) { + u8 x = gpio_pin[i]; + if (x != 0xff) { + GPIO_Pin.pin_name = HAL_GPIO_GetIPPinName_8195a(x & 0x7F); + if (x & 0x80) { + GPIO_Pin.pin_mode = DIN_PULL_LOW; + flg = GPIO_PIN_HIGH; + } else { + GPIO_Pin.pin_mode = DIN_PULL_HIGH; + flg = GPIO_PIN_LOW; + } + HAL_GPIO_Init_8195a(&GPIO_Pin); + result |= HAL_GPIO_ReadPin_8195a(&GPIO_Pin) == flg; + HAL_GPIO_DeInit_8195a(&GPIO_Pin); + } + } + _pHAL_Gpio_Adapter->IrqHandle.IrqFun = NULL; + return result; +} + +//----- GetChipId +int __attribute__((section(".hal.ram.text"))) _GetChipId() { + u8 chip_id = CHIP_ID_8195AM; + if (HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xF8, + &chip_id, L25EOUTVOLTAGE) != 1) + DBG_MISC_INFO("Get Chip ID Failed\r"); + return chip_id; +} + +//----- StartupHalSpicInit +void __attribute__((section(".hal.ram.text"))) StartupHalSpicInit( + int InitBaudRate) { + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT4); // HAL_SYS_CTRL_READ32 + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, + HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_FLASH_EN | BIT_SOC_SLPCK_FLASH_EN); + HalPinCtrlRtl8195A(SPI_FLASH, + ((HAL_SYS_CTRL_READ32(REG_SYS_SYSTEM_CFG1) & 0xF0000000) + == 0x30000000), 1); + SpicInitRtl8195A(InitBaudRate, StartupSpicBitMode); +} + + +void __attribute__((section(".hal.ram.text"))) flashcpy(u32 raddr, u32 faddr, s32 size) { + while(size > 0) { + HAL_WRITE32(0, raddr, HAL_READ32(SPI_FLASH_BASE, faddr)); + raddr+=4; + faddr+=4; + size-=4; + } +} +//----- PreProcessForVendor +void __attribute__((section(".hal.ram.text"))) PreProcessForVendor(void) { + START_FUNC entry_func; + u32 run_image; + u32 Image2Addr = *(u32 *)(0x1006FFFC); + u32 v16 = 0, v17; +#if 0 + u8 efuse0xD3_data; + HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xD3, + &efuse0xD3_data, L25EOUTVOLTAGE); + if (efuse0xD3_data & 1) +#endif + HalPinCtrlRtl8195A(JTAG, 0, 1); + SetDebugFlgs(); + int chip_id = _GetChipId(); + int flash_enable = HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_FLASH_EN; // v6 = ... + int spic_init = 0; +/// InitSpic(); + if (flash_enable) { + entry_func = &__image2_entry_func__; + spic_init = 1; + } else { + entry_func = (START_FUNC) Image2Addr; + if (chip_id != CHIP_ID_8711AN) { // 0xFB + StartupHalSpicInit(StartupSpicBaudRate); // BaudRate 1 + spic_init = 1; + } + } + DBG_8195A("BOOT from Flash: %s\n", (flash_enable) ? "YES" : "NO"); + memset(&__image1_bss_start__, 0, + &__image1_bss_end__ - &__image1_bss_start__); + HalDelayUs(1000); + int sdr_enable = 0; + +#ifdef CONFIG_SDR_EN + if (chip_id > CHIP_ID_8711AF || chip_id == CHIP_ID_8710AM) { + SdrCtrlInit(); + sdr_enable = 1; + } + else { + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); + } +#else +// SdrPowerOff(); + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT(21)); +#endif + + if (spic_init) SpicNVMCalLoadAll(); + SYSCpuClkConfig(chip_id, 0); + StartupHalInitPlatformLogUart(); // double !? + __asm__ __volatile__ ("cpsie f\n"); + DBG_8195A("===== Enter Image 1 ====\n"); + if (spic_init) { + SpicReadIDRtl8195A(); + SpicFlashInitRtl8195A(StartupSpicBitMode); // SpicBitMode 1 + } +#ifdef CONFIG_SDR_EN + if (sdr_enable) SdrControllerInit(); +#endif + if (flash_enable) { + + u32 img1size = (*(u16 *) (SPI_FLASH_BASE + 0x18)) << 10; // size in 1024 bytes + if (img1size == 0 || img1size >= 0x3FFFC00) + img1size = *(u32 *) (SPI_FLASH_BASE + 0x10) + 32; + u32 * prdflash = (u32 *) (img1size + SPI_FLASH_BASE + 8); + u32 sign1 = *prdflash++; + u32 sign2 = *prdflash; + { + v16 = -1; + v17 = -1; + if (sign2 == IMG_SIGN2_RUN) { + if (sign1 == IMG_SIGN1_RUN) { + v16 = img1size; + v17 = -1; + } else if (sign1 == IMG_SIGN1_SWP) { + v17 = img1size; + v16 = -1; + } + } + u32 OTA_addr = *(u32 *) (SPI_FLASH_BASE + FLASH_SYSTEM_DATA_ADDR); // config sector data + if (OTA_addr != -1) { + u32 image2size = *(u32 *) (img1size + SPI_FLASH_BASE); + if (OTA_addr >= (img1size + image2size) + && !(OTA_addr & 0xFFF)) { + prdflash = (u32 *) (OTA_addr + SPI_FLASH_BASE + 8); + sign1 = *prdflash++; + sign2 = *prdflash; + if (sign2 == IMG_SIGN2_RUN) { + if (sign1 == IMG_SIGN1_RUN) v16 = OTA_addr; + else if (sign1 == IMG_SIGN1_SWP) v17 = OTA_addr; + } +LABEL_41: if (IsForceLoadDefaultImg2()) { + if (v17 != -1) run_image = v17; + else { + run_image = v16; + if (run_image == -1) { + DiagPrintf("Fatal: no fw\n"); + RtlConsolRam(); + } + } + } else { + if (v16 != -1) run_image = v16; + else { + run_image = v17; + if (run_image == -1) { + DiagPrintf("Fatal: no fw\n"); + RtlConsolRam(); + } + } + } + u8 * pstr; + if (run_image == v17) + pstr = "load OLD fw %d\n"; + else { + if (run_image != v16) { +LABEL_55: prdflash = run_image + SPI_FLASH_BASE; + u32 img_size = *prdflash++; + u32 Image2Addr = *prdflash; + DBG_8195A("Flash Image2: Addr 0x%x, Len %d, Load to SRAM 0x%x\n", run_image, img_size, Image2Addr); // debug! + flashcpy(Image2Addr, run_image+16, img_size); +// SpicUserReadFourByteRtl8195A(img_size, run_image + 16, Image2Addr, StartupSpicBitMode); // SpicDualBitMode + prdflash = run_image + img_size + SPI_FLASH_BASE + 16; + u32 sdram_image_size = *prdflash++; // +0x10 + u32 sdram_load_addr = *prdflash; // +0x14 + DBG_8195A("Image3 length: 0x%x, Image3 Addr: 0x%x\n", + sdram_image_size, sdram_load_addr); + if ((sdram_image_size - 1) <= 0xFFFFFFFD + && *((u32 *)(sdram_load_addr)) == SDR_SDRAM_BASE) { // sdram_load_addr + if (!sdr_enable) { + DBG_MISC_ERR("FW/HW conflict. No DRAM on board.\n"); + RtlConsolRam(); + } + DBG_8195A("Image3 length: 0x%x, Image3 Addr: 0x%x\n", + sdram_image_size, sdram_load_addr); +// SpicUserReadRtl8195A(sdram_image_size, run_image + img_size + 32, SDR_SDRAM_BASE, StartupSpicBitMode); + } else DBG_8195A("No Image3\n"); + + entry_func = *(u32 *)Image2Addr; + DBG_8195A("Img2 Sign: %s, InfaStart @ 0x%08x \n", + (const char * )(Image2Addr + 4), + entry_func); // *(u32 *)Image2Addr); + if (strcmp((const char * )(Image2Addr + 4), + IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image2 Signature\n"); + RtlConsolRam(); + } +#if 0 + DBG_8195A("CLK CPU: %d Hz\n", HalGetCpuClk()); + RtlConsolRam(); +#else +#endif + (void) (entry_func)(); + return; + } + pstr = "load NEW fw %d\n"; + } // if (run_image == v17) else + DiagPrintf(pstr, ((run_image - OTA_addr) <= 0)); + goto LABEL_55; + } + DBG_MISC_ERR("OTA addr 0x%x INVALID\n", OTA_addr); + } + OTA_addr = -1; + goto LABEL_41; + } + } // if (flash_enable) + if (strcmp((const char * )(Image2Addr + 4), IMG2_SIGN_TXT)) { + DBG_MISC_ERR("Invalid Image2 Signature\n", 2 * ConfigDebugErr); + RtlConsolRam(); + } + (void) (entry_func)(); +} + +#if !USE_SRC_ONLY_BOOT +//----- HalHardFaultHandler_Patch_c +void HalHardFaultHandler_Patch_c(u32 HardDefaultArg) { + u32 v1; + int v2; + int v3; + + v1 = HardDefaultArg; + if ((VREG32(0xE000ED28) & 0x82) + && (unsigned int) (VREG32(0xE000ED38) - 0x40080000) < 0x40000) { + DBG_8195A("\n."); + v2 = *(u32 *) (v1 + 24); + if ((*(u16 *) v2 & 0xF800) <= 0xE000) v3 = v2 + 2; + else v3 = v2 + 4; + *(u32 *) (v1 + 24) = v3; + } else { + HalHardFaultHandler_user_define(HardDefaultArg); + HalHardFaultHandler(v1); // ROM: HalHardFaultHandler = 0x911; + } +} + +//----- VectorTableOverrideRtl8195A +void __attribute__((section(".infra.ram.start"))) VectorTableOverrideRtl8195A(u32 StackP) { + NewVectorTable[2] = HalNMIHandler_Patch; +} + +//----- SYSPlatformInit +void __attribute__((section(".infra.ram.start"))) SYSPlatformInit(void) { + HAL_SYS_CTRL_WRITE32(REG_SYS_EFUSE_SYSCFG0, + (HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_SYSCFG0) & (~(BIT_MASK_SYS_EEROM_LDO_PAR_07_04 << BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04))) | BIT_SYS_EEROM_LDO_PAR_07_04(6)); // & 0xF0FFFFFF | 0x6000000 + HAL_SYS_CTRL_WRITE32(REG_SYS_XTAL_CTRL1, + (HAL_SYS_CTRL_READ32(REG_SYS_XTAL_CTRL1) & (~(BIT_MASK_SYS_XTAL_DRV_RF1 << BIT_SHIFT_SYS_XTAL_DRV_RF1))) | BIT_SYS_XTAL_DRV_RF1(1)); // & 0xFFFFFFE7 | 8; +} + +//----- InfraStart +void __attribute__((section(".infra.ram.start"))) InfraStart(void) { + NewVectorTable[2] = HalNMIHandler_Patch; + HAL_SYS_CTRL_WRITE32(REG_SYS_CLK_CTRL0, + HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL0) | BIT4); + if (HalCommonInit() != HAL_OK) DBG_8195A("Hal Common Init Failed.\n"); + DBG_8195A("===== Enter Image 2 ====\n"); + ShowRamBuildInfo(); // app_start.c: VOID ShowRamBuildInfo(VOID) + memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__); + int flsh = (HAL_SYS_CTRL_READ32(REG_SYS_CLK_CTRL0) + >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & 1; + if (flsh) { + SpicNVMCalLoadAll(); + SpicReadIDRtl8195A(); + } + SystemCoreClockUpdate(); + SYSPlatformInit(); + En32KCalibration(); + InitSoCPM(); + SDIO_Device_Off(); + VectorTableInitForOSRtl8195A(&vPortSVCHandler, &xPortPendSVHandler, &xPortSysTickHandler); + if (flsh) SpicDisableRtl8195A(); + _AppStart(); +} + +//----- SDIO_Device_Off +void SDIO_Device_Off(void) { + HAL_PERI_ON_WRITE32(REG_PESOC_HCI_CLK_CTRL0, + HAL_PERI_ON_READ32(REG_PESOC_HCI_CLK_CTRL0) & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_PERI_ON_WRITE32(REG_SOC_HCI_COM_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_HCI_COM_FUNC_EN) & (~(BIT_SOC_HCI_SDIOD_ON_EN | BIT_SOC_HCI_SDIOD_OFF_EN))); + HAL_PERI_ON_WRITE32(REG_HCI_PINMUX_CTRL, + HAL_PERI_ON_READ32(REG_HCI_PINMUX_CTRL) & (~(BIT_HCI_SDIOD_PIN_EN))); +} + +//----- __HalReInitPlatformLogUart +void __HalReInitPlatformLogUart(void) { + LOG_UART_ADAPTER UartAdapter; + UartAdapter.BaudRate = DEFAULT_BAUDRATE; + HalLogUartInit(UartAdapter); +} + +void _ReloadImg_user_define(void) { + +} + +//----- ReloadImg +void _ReloadImg(void) { + u32 img1size; + u32 img1addr; + unsigned int i; + u32 img2addr; + u32 img_addr1; + u32 img_addr2; + u32 ota_addr; + const char * pstr; + + img1size = *(u32 *) (SPI_FLASH_BASE + 0x10); + img1addr = *(u32 *) (SPI_FLASH_BASE + 0x14); + DBG_8195A("Image1 length: 0x%x, Image Addr: 0x%x\n", img1size, + img1addr); + for (i = 32; i < img1size + 32; i += 4) + *(u32 *) (img1addr - 32 + i) = *(u32 *) (i + SPI_FLASH_BASE); + img2addr = *(u16 *) (SPI_FLASH_BASE + 0x16) << 10; + if (!(img2addr)) img2addr = img1size + 32; + u32 * prdflash = (u32 *) (img1size + SPI_FLASH_BASE + 8); + u32 sign1 = *prdflash++; // v4 = *(u32 *)(img2addr + SPI_FLASH_BASE + 8); + u32 sign2 = *prdflash; // v5 = *(u32 *)(img2addr + SPI_FLASH_BASE + 12); + if (sign1 == IMG_SIGN1_RUN) { + if (sign2 == IMG_SIGN2_RUN) { + img_addr1 = img2addr; +LABEL_11: img_addr2 = -1; + goto LABEL_16; + } +LABEL_14: img_addr1 = -1; + goto LABEL_11; + } + if (sign1 != IMG_SIGN1_SWP || sign2 != IMG_SIGN2_RUN) goto LABEL_14; + img_addr2 = img2addr; + img_addr1 = -1; +LABEL_16: ota_addr = *(u32 *) (SPI_FLASH_BASE + 0x9000); + if (ota_addr == -1) { +LABEL_21: ota_addr = -1; + goto LABEL_22; + } + if (ota_addr < (img2addr + *(u32 *) (img2addr + SPI_FLASH_BASE)) + || (ota_addr & 0xFFF)) { + DBG_MISC_ERR("OTA addr 0x%x INVALID\n"); + goto LABEL_21; + } + prdflash = (u32 *) (ota_addr + SPI_FLASH_BASE + 8); + sign1 = *prdflash++; // v9 = *(u32 *)(ota_addr + SPI_FLASH_BASE + 8); + sign2 = *prdflash; // v11 = *(u32 *)(ota_addr + SPI_FLASH_BASE + 12); + if (sign1 == IMG_SIGN1_RUN) { + sign1 = IMG_SIGN2_RUN; + if (sign2 == IMG_SIGN2_RUN) { + img_addr1 = ota_addr; + goto LABEL_33; + } + goto LABEL_22; + } + if (sign1 != IMG_SIGN1_SWP || (sign1 = IMG_SIGN2_RUN, sign2 != IMG_SIGN2_RUN)) { +LABEL_22: if (img_addr1 == -1) { + if (img_addr2 == -1) { + DBG_MISC_ERR("Fatal:no fw\n", ota_addr, + 2 * ConfigDebugErr); + RtlConsolRam(); + } + img_addr1 = img_addr2; +LABEL_28: pstr = "load OLD fw %d\n"; + if (ConfigDebugErr & _DBG_MISC_) { +LABEL_36: DiagPrintf(pstr, + ((unsigned int) (img_addr1 - ota_addr) <= 0)); + } + goto IMG2_LOAD_START; + } + goto LABEL_33; + } + if (img_addr1 == -1) { + img_addr1 = *(u32 *) (SPI_FLASH_BASE + 0x9000); // ota_addr + goto LABEL_28; + } + img_addr2 = *(u32 *) (SPI_FLASH_BASE + 0x9000); +LABEL_33: if (img_addr1 == img_addr2) + goto LABEL_28; + if (ConfigDebugErr & _DBG_MISC_) // DBG_8195A + { + pstr = "load NEW fw %d\n"; + goto LABEL_36; + } + u32 v13; +IMG2_LOAD_START: + v13 = *(u32 *) (img_addr1 + SPI_FLASH_BASE + 4); + u32 v15 = *(u32 *) (img_addr1 + SPI_FLASH_BASE) + img_addr1; + for (i = img_addr1 + 16;; i += 4) { + if (i >= (unsigned int) (v15 + 16)) break; + *(u32 *) (v13 - 16 - img_addr1 + i) = *(u32 *) (i + SPI_FLASH_BASE); + } + u32 v16 = *(u32 *) (v15 + SPI_FLASH_BASE); + if ((unsigned int) (v16 - 1) <= 0xFFFFFFFD + && *(u32 *) (v15 + SPI_FLASH_BASE + 0x14) == 0x30000000) { + DBG_8195A("Image3 length: 0x%x, Image3 Addr: 0x%x\n", + *(u32 *)(v15 + SPI_FLASH_BASE + 0x10)); + for (i = v15 + 32; i < (v16 + v15 + 32); i += 4) + *(u32 *) (0x2FFFFFE0 - v15 + i) = *(u32 *) (i + SPI_FLASH_BASE); + } else + DBG_8195A("No Image3\n"); + _ReloadImg_user_define(); +} + +//----- CPUResetHandler +void _CPUResetHandler(void) { + memset(&__rom_bss_start__, 0, &__rom_bss_end__ - &__rom_bss_start__); + + ConfigDebugErr = -1; + + HalCpuClkConfig(0); + VectorTableInitRtl8195A(STACK_TOP); // 0x1FFFFFFC + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT23); + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT_SOC_FLASH_EN); + HAL_PERI_ON_WRITE32(REG_SOC_PERI_BD_FUNC0_EN, + HAL_PERI_ON_READ32(REG_SOC_PERI_BD_FUNC0_EN) | BIT8 | BIT9); + HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); + HalTimerOpInit_Patch(&HalTimerOp); + HalDelayUs(1000); + __HalReInitPlatformLogUart(); + _ReloadImg(); + InfraStart(); +} +//----- CPUReset +void _CPUReset(void) // __noreturn +{ + wifi_off(); + pRamStartFun->RamPatchFun1 = _CPUResetHandler; + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & BIT27); + HAL_WRITE32(0xE000ED00, 0x0C, 0x5FA0003); // + while (1); +} + +void HalHardFaultHandler_user_define(u32 HardDefaultArg) { + +} +#endif // !USE_SRC_ONLY_BOOT diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/Rtl8195a_otg_zero.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/Rtl8195a_otg_zero.h new file mode 100644 index 0000000..ef24f40 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/Rtl8195a_otg_zero.h @@ -0,0 +1,35 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef RTL8195A_OTG_ZERO_H +#define RTL8195A_OTG_ZERO_H + +#include "usb_ch9.h" +#include "usb_gadget.h" + +struct zero_dev { + //ModifiedByJD spinlock_t lock; + struct usb_gadget *gadget; + struct usb_request *req; /* for control responses */ + + /* when configured, we have one of two configs: + * - source data (in to host) and sink it (out from host) + * - or loop it back (out from host back in to host) + */ + u8 config; + struct usb_ep *in_ep, *out_ep, *status_ep;//ModifiedByJD + + const struct usb_endpoint_descriptor + *in, *out, *status; //ModifiedByJD + /* autoresume timer */ + //ModifiedByJD struct timer_list resume; +}; + + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/cdc.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/cdc.h new file mode 100644 index 0000000..a374ff9 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/cdc.h @@ -0,0 +1,211 @@ + +//#include "../otg/osk/sys-support.h" //ModifiedByJD + +/* + * USB Communications Device Class (CDC) definitions + * + * CDC says how to talk to lots of different types of network adapters, + * notably ethernet adapters and various modems. It's used mostly with + * firmware based USB peripherals. + */ + +#define USB_CDC_SUBCLASS_ACM 0x02 +#define USB_CDC_SUBCLASS_ETHERNET 0x06 +#define USB_CDC_SUBCLASS_WHCM 0x08 +#define USB_CDC_SUBCLASS_DMM 0x09 +#define USB_CDC_SUBCLASS_MDLM 0x0a +#define USB_CDC_SUBCLASS_OBEX 0x0b + +#define USB_CDC_PROTO_NONE 0 + +#define USB_CDC_ACM_PROTO_AT_V25TER 1 +#define USB_CDC_ACM_PROTO_AT_PCCA101 2 +#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE 3 +#define USB_CDC_ACM_PROTO_AT_GSM 4 +#define USB_CDC_ACM_PROTO_AT_3G 5 +#define USB_CDC_ACM_PROTO_AT_CDMA 6 +#define USB_CDC_ACM_PROTO_VENDOR 0xff + +/*-------------------------------------------------------------------------*/ +//#define UPACKED __attribute__ ((packed)) +#define UPACKED +/* + * Class-Specific descriptors ... there are a couple dozen of them + */ + +#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ +#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ +#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ +#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ +#define USB_CDC_COUNTRY_TYPE 0x07 +#define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ +#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ +#define USB_CDC_WHCM_TYPE 0x11 +#define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ +#define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ +#define USB_CDC_DMM_TYPE 0x14 +#define USB_CDC_OBEX_TYPE 0x15 + +//ModifiedByJD (>>>) modify the data type to useable ones. +/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ +struct usb_cdc_header_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u16 bcdCDC; +} UPACKED; + +/* "Call Management Descriptor" from CDC spec 5.2.3.2 */ +struct usb_cdc_call_mgmt_descriptor { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bmCapabilities; +#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01 +#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02 + + u8 bDataInterface; +} UPACKED; + +/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */ +struct usb_cdc_acm_descriptor { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bmCapabilities; +} UPACKED; + +/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ +struct usb_cdc_union_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bMasterInterface0; + u8 bSlaveInterface0; + /* ... and there could be other slave interfaces */ +} UPACKED; + +/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ +struct usb_cdc_network_terminal_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 bEntityId; + u8 iName; + u8 bChannelIndex; + u8 bPhysicalInterface; +} UPACKED; + +/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */ +struct usb_cdc_ether_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u8 iMACAddress; + u32 bmEthernetStatistics; + u16 wMaxSegmentSize; + u16 wNumberMCFilters; + u8 bNumberPowerFilters; +} UPACKED; + +/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */ +struct usb_cdc_mdlm_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + u16 bcdVersion; + u8 bGUID[16]; +}UPACKED; + +/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */ +struct usb_cdc_mdlm_detail_desc { + u8 bLength; + u8 bDescriptorType; + u8 bDescriptorSubType; + + /* type is associated with mdlm_desc.bGUID */ + u8 bGuidDescriptorType; + u8 bDetailData[0]; +} UPACKED; + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Control Requests (6.2) + * + * section 3.6.2.1 table 4 has the ACM profile, for modems. + * section 3.8.2 table 10 has the ethernet profile. + * + * Microsoft's RNDIS stack for Ethernet is a vendor-specific CDC ACM variant, + * heavily dependent on the encapsulated (proprietary) command mechanism. + */ + +#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +#define USB_CDC_REQ_GET_LINE_CODING 0x21 +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +#define USB_CDC_REQ_SEND_BREAK 0x23 +#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 +#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 +#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 + +/* Line Coding Structure from CDC spec 6.2.13 */ +struct usb_cdc_line_coding { + u32 dwDTERate; + u8 bCharFormat; +#define USB_CDC_1_STOP_BITS 0 +#define USB_CDC_1_5_STOP_BITS 1 +#define USB_CDC_2_STOP_BITS 2 + + u8 bParityType; +#define USB_CDC_NO_PARITY 0 +#define USB_CDC_ODD_PARITY 1 +#define USB_CDC_EVEN_PARITY 2 +#define USB_CDC_MARK_PARITY 3 +#define USB_CDC_SPACE_PARITY 4 + + u8 bDataBits; +} UPACKED; + +/* table 62; bits in multicast filter */ +#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0) +#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ +#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2) +#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3) +#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ + + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Notifications (6.3) sent by interrupt transfers + * + * section 3.8.2 table 11 of the CDC spec lists Ethernet notifications + * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS + * RNDIS also defines its own bit-incompatible notifications + */ + +#define USB_CDC_NOTIFY_NETWORK_CONNECTION 0x00 +#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_CDC_NOTIFY_SPEED_CHANGE 0x2a + +struct usb_cdc_notification { + u8 bmRequestType; + u8 bNotificationType; + u16 wValue; + u16 wIndex; + u16 wLength; +}UPACKED; +//ModifiedByJD (<<<) + diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_list.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_list.h new file mode 100644 index 0000000..89cc325 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_list.h @@ -0,0 +1,594 @@ +/* $OpenBSD: queue.h,v 1.26 2004/05/04 16:59:32 grange Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _DWC_LIST_H_ +#define _DWC_LIST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * This file defines linked list operations. It is derived from BSD with + * only the MACRO names being prefixed with DWC_. This is because a few of + * these names conflict with those on Linux. For documentation on use, see the + * inline comments in the source code. The original license for this source + * code applies and is preserved in the dwc_list.h source file. + */ + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * Double-linked List. + */ + +typedef struct dwc_list_link { + struct dwc_list_link *next; + struct dwc_list_link *prev; +} dwc_list_link_t; + +#define DWC_LIST_INIT(link) do { \ + (link)->next = (link); \ + (link)->prev = (link); \ +} while (0) + +#define DWC_LIST_FIRST(link) ((link)->next) +#define DWC_LIST_LAST(link) ((link)->prev) +#define DWC_LIST_END(link) (link) +#define DWC_LIST_NEXT(link) ((link)->next) +#define DWC_LIST_PREV(link) ((link)->prev) +#define DWC_LIST_EMPTY(link) \ + (DWC_LIST_FIRST(link) == DWC_LIST_END(link)) +#define DWC_LIST_ENTRY(link, type, field) \ + (type *)((uint8_t *)(link) - (size_t)(&((type *)0)->field)) + +#if 0 +#define DWC_LIST_INSERT_HEAD(list, link) do { \ + (link)->next = (list)->next; \ + (link)->prev = (list); \ + (list)->next->prev = (link); \ + (list)->next = (link); \ +} while (0) + +#define DWC_LIST_INSERT_TAIL(list, link) do { \ + (link)->next = (list); \ + (link)->prev = (list)->prev; \ + (list)->prev->next = (link); \ + (list)->prev = (link); \ +} while (0) +#else +#define DWC_LIST_INSERT_HEAD(list, link) do { \ + dwc_list_link_t *__next__ = (list)->next; \ + __next__->prev = (link); \ + (link)->next = __next__; \ + (link)->prev = (list); \ + (list)->next = (link); \ +} while (0) + +#define DWC_LIST_INSERT_TAIL(list, link) do { \ + dwc_list_link_t *__prev__ = (list)->prev; \ + (list)->prev = (link); \ + (link)->next = (list); \ + (link)->prev = __prev__; \ + __prev__->next = (link); \ +} while (0) +#endif + +#if 0 +static inline void __list_add(struct list_head *new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +static inline void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +static inline void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +static inline void __list_del(struct list_head * prev, struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +static inline void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + entry->next = LIST_POISON1; + entry->prev = LIST_POISON2; +} +#endif + +#define DWC_LIST_REMOVE(link) do { \ + (link)->next->prev = (link)->prev; \ + (link)->prev->next = (link)->next; \ +} while (0) + +#define DWC_LIST_REMOVE_INIT(link) do { \ + DWC_LIST_REMOVE(link); \ + DWC_LIST_INIT(link); \ +} while (0) + +#define DWC_LIST_MOVE_HEAD(list, link) do { \ + DWC_LIST_REMOVE(link); \ + DWC_LIST_INSERT_HEAD(list, link); \ +} while (0) + +#define DWC_LIST_MOVE_TAIL(list, link) do { \ + DWC_LIST_REMOVE(link); \ + DWC_LIST_INSERT_TAIL(list, link); \ +} while (0) + +#define DWC_LIST_FOREACH(var, list) \ + for((var) = DWC_LIST_FIRST(list); \ + (var) != DWC_LIST_END(list); \ + (var) = DWC_LIST_NEXT(var)) + +#define DWC_LIST_FOREACH_SAFE(var, var2, list) \ + for((var) = DWC_LIST_FIRST(list), (var2) = DWC_LIST_NEXT(var); \ + (var) != DWC_LIST_END(list); \ + (var) = (var2), (var2) = DWC_LIST_NEXT(var2)) + +#define DWC_LIST_FOREACH_REVERSE(var, list) \ + for((var) = DWC_LIST_LAST(list); \ + (var) != DWC_LIST_END(list); \ + (var) = DWC_LIST_PREV(var)) + +/* + * Singly-linked List definitions. + */ +#define DWC_SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define DWC_SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define DWC_SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List access methods. + */ +#define DWC_SLIST_FIRST(head) ((head)->slh_first) +#define DWC_SLIST_END(head) NULL +#define DWC_SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define DWC_SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define DWC_SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +#define DWC_SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != SLIST_END(head); \ + (varp) = &SLIST_NEXT((var), field)) + +/* + * Singly-linked List functions. + */ +#define DWC_SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define DWC_SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define DWC_SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define DWC_SLIST_REMOVE_NEXT(head, elm, field) do { \ + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \ +} while (0) + +#define DWC_SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define DWC_SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while( curelm->field.sle_next != (elm) ) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (0) + +/* + * Simple queue definitions. + */ +#define DWC_SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define DWC_SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define DWC_SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define DWC_SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define DWC_SIMPLEQ_END(head) NULL +#define DWC_SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define DWC_SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define DWC_SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +/* + * Simple queue functions. + */ +#define DWC_SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define DWC_SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define DWC_SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define DWC_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define DWC_SIMPLEQ_REMOVE_HEAD(head, field) do { \ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define DWC_TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define DWC_TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define DWC_TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define DWC_TAILQ_FIRST(head) ((head)->tqh_first) +#define DWC_TAILQ_END(head) NULL +#define DWC_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define DWC_TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define DWC_TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define DWC_TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define DWC_TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define DWC_TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +/* + * Tail queue functions. + */ +#define DWC_TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define DWC_TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define DWC_TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define DWC_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define DWC_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define DWC_TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#define DWC_TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define DWC_CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define DWC_CIRCLEQ_HEAD_INITIALIZER(head) \ + { DWC_CIRCLEQ_END(&head), DWC_CIRCLEQ_END(&head) } + +#define DWC_CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define DWC_CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define DWC_CIRCLEQ_LAST(head) ((head)->cqh_last) +#define DWC_CIRCLEQ_END(head) ((void *)(head)) +#define DWC_CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define DWC_CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define DWC_CIRCLEQ_EMPTY(head) \ + (DWC_CIRCLEQ_FIRST(head) == DWC_CIRCLEQ_END(head)) + +#define DWC_CIRCLEQ_EMPTY_ENTRY(elm, field) (((elm)->field.cqe_next == NULL) && ((elm)->field.cqe_prev == NULL)) + +#define DWC_CIRCLEQ_FOREACH(var, head, field) \ + for((var) = DWC_CIRCLEQ_FIRST(head); \ + (var) != DWC_CIRCLEQ_END(head); \ + (var) = DWC_CIRCLEQ_NEXT(var, field)) + +#define DWC_CIRCLEQ_FOREACH_SAFE(var, var2, head, field) \ + for((var) = DWC_CIRCLEQ_FIRST(head), var2 = DWC_CIRCLEQ_NEXT(var, field); \ + (var) != DWC_CIRCLEQ_END(head); \ + (var) = var2, var2 = DWC_CIRCLEQ_NEXT(var, field)) + +#define DWC_CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = DWC_CIRCLEQ_LAST(head); \ + (var) != DWC_CIRCLEQ_END(head); \ + (var) = DWC_CIRCLEQ_PREV(var, field)) + +/* + * Circular queue functions. + */ +#define DWC_CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = DWC_CIRCLEQ_END(head); \ + (head)->cqh_last = DWC_CIRCLEQ_END(head); \ +} while (0) + +#define DWC_CIRCLEQ_INIT_ENTRY(elm, field) do { \ + (elm)->field.cqe_next = NULL; \ + (elm)->field.cqe_prev = NULL; \ +} while (0) + +#define DWC_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define DWC_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define DWC_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = DWC_CIRCLEQ_END(head); \ + if ((head)->cqh_last == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define DWC_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = DWC_CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define DWC_CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == DWC_CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#define DWC_CIRCLEQ_REMOVE_INIT(head, elm, field) do { \ + DWC_CIRCLEQ_REMOVE(head, elm, field); \ + DWC_CIRCLEQ_INIT_ENTRY(elm, field); \ +} while (0) + +#define DWC_CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + DWC_CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + DWC_CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ +} while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* _DWC_LIST_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_os.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_os.h new file mode 100644 index 0000000..cc56efc --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_os.h @@ -0,0 +1,1102 @@ +/* ========================================================================= + * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_os.h $ + * $Revision: #14 $ + * $Date: 2010/11/04 $ + * $Change: 1621695 $ + * + * Synopsys Portability Library Software and documentation + * (hereinafter, "Software") is an Unsupported proprietary work of + * Synopsys, Inc. unless otherwise expressly agreed to in writing + * between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product + * under any End User Software License Agreement or Agreement for + * Licensed Product with Synopsys or any supplement thereto. You are + * permitted to use and redistribute this Software in source and binary + * forms, with or without modification, provided that redistributions + * of source code must retain this notice. You may not view, use, + * disclose, copy or distribute this file or any information contained + * herein except pursuant to this license grant from Synopsys. If you + * do not agree with this notice, including the disclaimer below, then + * you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" + * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL + * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================= */ +#ifndef _DWC_OS_H_ +#define _DWC_OS_H_ + +#include "basic_types.h" +#include +//#include "va_list.h" +#include + +#include "diag.h" +#include "dwc_otg_dbg.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern +_LONG_CALL_ u32 +DiagPrintf( + IN const char *fmt, ... +); + + +/** @file + * + * DWC portability library, low level os-wrapper functions + * + */ + +/* These basic types need to be defined by some OS header file or custom header + * file for your specific target architecture. + * + * uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t + * + * Any custom or alternate header file must be added and enabled here. + */ +#if 0//8195A_PORTING +#else +#define DWC_OS_PORTING 1 +#endif + +#include "errno.h" + +/** @name Primitive Types and Values */ + +/** We define a boolean type for consistency. Can be either YES or NO */ +typedef uint8_t dwc_bool_t; +#define YES 1 +#define NO 0 + +/** Compile Flag Definition */ +#define __OTG_LITTLE_ENDIAN +#undef DWC_CRYPTOLIB +#undef DWC_DEBUG_REGS +#undef DWC_DEBUG_MEMORY +#undef DWC_UTFLIB +#undef CONFIG_DEBUG_MUTEXES +#define DWC_WITH_WLAN_OSDEP 1 + + +#ifdef DWC_OS_PORTING + +/** @name Error Codes */ +#define DWC_E_INVALID EINVAL +#define DWC_E_NO_MEMORY ENOMEM +#define DWC_E_NO_DEVICE ENODEV +#define DWC_E_NOT_SUPPORTED EOPNOTSUPP +#define DWC_E_TIMEOUT ETIMEDOUT +#define DWC_E_BUSY EBUSY +#define DWC_E_AGAIN EAGAIN +#define DWC_E_RESTART ERESTART +#define DWC_E_ABORT ECONNABORTED +#define DWC_E_SHUTDOWN ESHUTDOWN +#define DWC_E_NO_DATA ENODATA +#define DWC_E_DISCONNECT ECONNRESET +#define DWC_E_UNKNOWN EINVAL +#define DWC_E_NO_STREAM_RES ENOSR +#define DWC_E_COMMUNICATION ECOMM +#define DWC_E_OVERFLOW EOVERFLOW +#define DWC_E_PROTOCOL EPROTO +#define DWC_E_IN_PROGRESS EINPROGRESS +#define DWC_E_PIPE EPIPE +#define DWC_E_IO EIO +#define DWC_E_NO_SPACE ENOSPC + +#else + +/** @name Error Codes */ +#define DWC_E_INVALID 1001 +#define DWC_E_NO_MEMORY 1002 +#define DWC_E_NO_DEVICE 1003 +#define DWC_E_NOT_SUPPORTED 1004 +#define DWC_E_TIMEOUT 1005 +#define DWC_E_BUSY 1006 +#define DWC_E_AGAIN 1007 +#define DWC_E_RESTART 1008 +#define DWC_E_ABORT 1009 +#define DWC_E_SHUTDOWN 1010 +#define DWC_E_NO_DATA 1011 +#define DWC_E_DISCONNECT 2000 +#define DWC_E_UNKNOWN 3000 +#define DWC_E_NO_STREAM_RES 4001 +#define DWC_E_COMMUNICATION 4002 +#define DWC_E_OVERFLOW 4003 +#define DWC_E_PROTOCOL 4004 +#define DWC_E_IN_PROGRESS 4005 +#define DWC_E_PIPE 4006 +#define DWC_E_IO 4007 +#define DWC_E_NO_SPACE 4008 + +#endif + + +/** @name Tracing/Logging Functions + * + * These function provide the capability to add tracing, debugging, and error + * messages, as well exceptions as assertions. The WUDEV uses these + * extensively. These could be logged to the main console, the serial port, an + * internal buffer, etc. These functions could also be no-op if they are too + * expensive on your system. By default undefining the DEBUG macro already + * no-ops some of these functions. */ + +/** Returns non-zero if in interrupt context. */ +extern _LONG_CALL_ dwc_bool_t DWC_IN_IRQ(void); +#define dwc_in_irq DWC_IN_IRQ + +/** Returns "IRQ" if DWC_IN_IRQ is true. */ +extern _LONG_CALL_ char *dwc_irq(void); + +/** Returns non-zero if in bottom-half context. */ +extern _LONG_CALL_ dwc_bool_t DWC_IN_BH(void); +#define dwc_in_bh DWC_IN_BH + +/** Returns "BH" if DWC_IN_BH is true. */ +extern _LONG_CALL_ char *dwc_bh(void); + +/** + * A vprintf() clone. Just call vprintf if you've got it. + */ +#if 0 +extern void DWC_VPRINTF(char *format, va_list args); +#define dwc_vprintf DWC_VPRINTF +#endif +/** + * A vsnprintf() clone. Just call vprintf if you've got it. + */ +extern _LONG_CALL_ int DWC_VSNPRINTF(char *str, int size, char *format, va_list args); +#define dwc_vsnprintf DWC_VSNPRINTF + +/** + * printf() clone. Just call printf if you've go it. + */ +#ifdef OTGDEBUG +#define DWC_PRINTF(format...) do{ DBG_8195A_OTG(format); }while(0) +#else +#define DWC_PRINTF(format...) +#endif + +//extern void DWC_PRINTF(char *format, ...) +/* This provides compiler level static checking of the parameters if you're + * using GCC. */ +#if 0 +#ifdef __GNUC__ + __attribute__ ((format(printf, 1, 2))); +#else + ; +#endif +#endif +#define dwc_printf DWC_PRINTF + +/** + * sprintf() clone. Just call sprintf if you've got it. + */ +extern _LONG_CALL_ int DWC_SPRINTF(char *string, char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(prvDiagPrintf, 2, 3))); +#else + ; +#endif +#define dwc_sprintf DWC_SPRINTF + +/** + * snprintf() clone. Just call snprintf if you've got it. + */ +extern _LONG_CALL_ int DWC_SNPRINTF(char *string, int size, char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(prvDiagPrintf, 3, 4))); +#else + ; +#endif +#define dwc_snprintf DWC_SNPRINTF + +/** + * Prints a WARNING message. On systems that don't differentiate between + * warnings and regular log messages, just print it. Indicates that something + * may be wrong with the driver. Works like printf(). + * + * Use the DWC_WARN macro to call this function. + */ +extern _LONG_CALL_ void __DWC_WARN(char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(prvDiagPrintf, 1, 2))); +#else + ; +#endif + +/** + * Prints an error message. On systems that don't differentiate between errors + * and regular log messages, just print it. Indicates that something went wrong + * with the driver. Works like printf(). + * + * Use the DWC_ERROR macro to call this function. + */ +extern _LONG_CALL_ void __DWC_ERROR(char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(prvDiagPrintf, 1, 2))); +#else + ; +#endif + +/** + * Prints an exception error message and takes some user-defined action such as + * print out a backtrace or trigger a breakpoint. Indicates that something went + * abnormally wrong with the driver such as programmer error, or other + * exceptional condition. It should not be ignored so even on systems without + * printing capability, some action should be taken to notify the developer of + * it. Works like printf(). + */ +extern _LONG_CALL_ void DWC_EXCEPTION(char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(prvDiagPrintf, 1, 2))); +#else + ; +#endif +#define dwc_exception DWC_EXCEPTION + +#ifdef OTGDEBUG +/** + * Prints out a debug message. Used for logging/trace messages. + * + * Use the DWC_DEBUG macro to call this function + */ +extern _LONG_CALL_ void __DWC_DEBUG(char *format, ...); +#if 0 +#ifdef __GNUC__ + __attribute__ ((format(printf, 1, 2))); +#else + ; +#endif +#endif +#else +#define __DWC_DEBUG(...) +#endif + +/** + * Prints out a Debug message. + */ +#define DWC_DEBUG(fmt, args...) DBG_8195A_OTG("\n\rDWC_DEBUG:" fmt, ## args) +#define dwc_debug DWC_DEBUG +/** + * Prints out an informative message. + */ +#define DWC_INFO(_format, _args...) DBG_8195A_OTG_INFO("INFO:%s: " _format "\n", \ + dwc_irq(), ## _args) +#define dwc_info DWC_INFO +/** + * Prints out a warning message. + */ +#define DWC_WARN(_format, _args...) DBG_8195A_OTG_WARN("WARN:%s: " _format "\n", \ + dwc_irq(), ## _args) +#define dwc_warn DWC_WARN +/** + * Prints out an error message. + */ +#define DWC_ERROR(_format, _args...) DBG_8195A_OTG_ERR("ERROR:%s: " _format "\n", \ + dwc_irq(), ## _args) + +#define dwc_error DWC_ERROR + +#define DWC_PROTO_ERROR(_format, _args...) DBG_8195A_OTG_ERR("ERROR:%s: " _format "\n", \ + dwc_irq(), ## _args) +#define dwc_proto_error DWC_PROTO_ERROR + +#ifdef OTGDEBUG +/** Prints out a exception error message if the _expr expression fails. Disabled + * if DEBUG is not enabled. */ +#define DWC_ASSERT(_expr, _format, _args...) do { \ + if (!(_expr)) { DBG_8195A_OTG("%s: " _format "\n", dwc_irq(), \ + ## _args); } \ + } while (0) +#else +#define DWC_ASSERT(_x...) +#endif +#define dwc_assert DWC_ASSERT + + +/** @name Byte Ordering + * The following functions are for conversions between processor's byte ordering + * and specific ordering you want. + */ + +/** Converts 32 bit data in CPU byte ordering to little endian. */ +extern _LONG_CALL_ uint32_t DWC_CPU_TO_LE32(uint32_t *p); +#define dwc_cpu_to_le32 DWC_CPU_TO_LE32 + +/** Converts 32 bit data in CPU byte orderint to big endian. */ +extern _LONG_CALL_ uint32_t DWC_CPU_TO_BE32(uint32_t *p); +#define dwc_cpu_to_be32 DWC_CPU_TO_BE32 + +/** Converts 32 bit little endian data to CPU byte ordering. */ +extern _LONG_CALL_ uint32_t DWC_LE32_TO_CPU(uint32_t *p); +#define dwc_le32_to_cpu DWC_LE32_TO_CPU + +/** Converts 32 bit big endian data to CPU byte ordering. */ +extern _LONG_CALL_ uint32_t DWC_BE32_TO_CPU(uint32_t *p); +#define dwc_be32_to_cpu DWC_BE32_TO_CPU + +/** Converts 16 bit data in CPU byte ordering to little endian. */ +extern _LONG_CALL_ uint16_t DWC_CPU_TO_LE16(uint16_t *p); +#define dwc_cpu_to_le16 DWC_CPU_TO_LE16 + +/** Converts 16 bit data in CPU byte orderint to big endian. */ +extern _LONG_CALL_ uint16_t DWC_CPU_TO_BE16(uint16_t *p); +#define dwc_cpu_to_be16 DWC_CPU_TO_BE16 + +/** Converts 16 bit little endian data to CPU byte ordering. */ +extern _LONG_CALL_ uint16_t DWC_LE16_TO_CPU(uint16_t *p); +#define dwc_le16_to_cpu DWC_LE16_TO_CPU + +/** Converts 16 bit bi endian data to CPU byte ordering. */ +extern _LONG_CALL_ uint16_t DWC_BE16_TO_CPU(uint16_t *p); +#define dwc_be16_to_cpu DWC_BE16_TO_CPU + + +/** @name Register Read/Write + * + * The following six functions should be implemented to read/write registers of + * 32-bit and 64-bit sizes. All modules use this to read/write register values. + * The reg value is a pointer to the register calculated from the void *base + * variable passed into the driver when it is started. */ + + +/** @cond */ + +/** @name Some convenience MACROS used internally. Define DWC_DEBUG_REGS to log the + * register writes. */ + +#ifdef DWC_OS_PORTING + +# ifdef DWC_DEBUG_REGS +XXXX +#define dwc_define_read_write_reg_n(_reg,_container_type) \ +static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \ + return DWC_READ_REG32(&container->regs->_reg[num]); \ +} \ +static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \ + DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \ + &(((uint32_t*)container->regs->_reg)[num]), data); \ + DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \ +} + +#define dwc_define_read_write_reg(_reg,_container_type) \ +static inline uint32_t dwc_read_##_reg(_container_type *container) { \ + return DWC_READ_REG32(&container->regs->_reg); \ +} \ +static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \ + DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \ + DWC_WRITE_REG32(&container->regs->_reg, data); \ +} + +# else /* DWC_DEBUG_REGS */ + +#define dwc_define_read_write_reg_n(_reg,_container_type) \ +static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \ + return DWC_READ_REG32(&container->regs->_reg[num]); \ +} \ +static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \ + DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \ +} + +#define dwc_define_read_write_reg(_reg,_container_type) \ +static inline uint32_t dwc_read_##_reg(_container_type *container) { \ + return DWC_READ_REG32(&container->regs->_reg); \ +} \ +static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \ + DWC_WRITE_REG32(&container->regs->_reg, data); \ +} + +# endif /* DWC_DEBUG_REGS */ + +#endif /* DWC_OS_PORTING */ + + +/** @endcond */ + + +#ifdef DWC_CRYPTOLIB +XXX +/** @name Crypto Functions + * + * These are the low-level cryptographic functions used by the driver. */ + +/** Perform AES CBC */ +extern _LONG_CALL_ int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out); +#define dwc_aes_cbc DWC_AES_CBC + +/** Fill the provided buffer with random bytes. These should be cryptographic grade random numbers. */ +extern _LONG_CALL_ void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length); +#define dwc_random_bytes DWC_RANDOM_BYTES + +/** Perform the SHA-256 hash function */ +extern _LONG_CALL_ int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out); +#define dwc_sha256 DWC_SHA256 + +/** Calculated the HMAC-SHA256 */ +extern _LONG_CALL_ int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t *out); +#define dwc_hmac_sha256 DWC_HMAC_SHA256 + +#endif /* DWC_CRYPTOLIB */ + + +/** @name Memory Allocation + * + * These function provide access to memory allocation. There are only 2 DMA + * functions and 3 Regular memory functions that need to be implemented. None + * of the memory debugging routines need to be implemented. The allocation + * routines all ZERO the contents of the memory. + * + * Defining DWC_DEBUG_MEMORY turns on memory debugging and statistic gathering. + * This checks for memory leaks, keeping track of alloc/free pairs. It also + * keeps track of how much memory the driver is using at any given time. */ + +#define DWC_PAGE_SIZE 4096 +#define DWC_PAGE_OFFSET(addr) (((uint32_t)addr) & 0xfff) +#define DWC_PAGE_ALIGNED(addr) ((((uint32_t)addr) & 0xfff) == 0) + +#define DWC_INVALID_DMA_ADDR 0x0 + +#ifdef DWC_OS_PORTING +/** Type for a DMA address */ +typedef dma_addr_t dwc_dma_t; +#endif + +#if 0//defined(DWC_FREEBSD) || defined(DWC_NETBSD) +typedef bus_addr_t dwc_dma_t; +#endif + +#if 0//def DWC_FREEBSD +typedef struct dwc_dmactx { + struct device *dev; + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; + bus_addr_t dma_paddr; + void *dma_vaddr; +} dwc_dmactx_t; +#endif + +#if 0//def DWC_NETBSD +typedef struct dwc_dmactx { + struct device *dev; + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; + bus_dma_segment_t segs[1]; + int nsegs; + bus_addr_t dma_paddr; + void *dma_vaddr; +} dwc_dmactx_t; +#endif + +/* @todo these functions will be added in the future */ +#if 0 +/** + * Creates a DMA pool from which you can allocate DMA buffers. Buffers + * allocated from this pool will be guaranteed to meet the size, alignment, and + * boundary requirements specified. + * + * @param[in] size Specifies the size of the buffers that will be allocated from + * this pool. + * @param[in] align Specifies the byte alignment requirements of the buffers + * allocated from this pool. Must be a power of 2. + * @param[in] boundary Specifies the N-byte boundary that buffers allocated from + * this pool must not cross. + * + * @returns A pointer to an internal opaque structure which is not to be + * accessed outside of these library functions. Use this handle to specify + * which pools to allocate/free DMA buffers from and also to destroy the pool, + * when you are done with it. + */ +extern dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, uint32_t align, uint32_t boundary); + +/** + * Destroy a DMA pool. All buffers allocated from that pool must be freed first. + */ +extern void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool); + +/** + * Allocate a buffer from the specified DMA pool and zeros its contents. + */ +extern void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr); + +/** + * Free a previously allocated buffer from the DMA pool. + */ +extern void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr); +#endif + +/** Allocates a DMA capable buffer and zeroes its contents. */ +extern _LONG_CALL_ void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr); + +/** Allocates a DMA capable buffer and zeroes its contents in atomic contest */ +extern _LONG_CALL_ void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr); + +/** Frees a previously allocated buffer. */ +extern _LONG_CALL_ void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr); + +/** Allocates a block of memory and zeroes its contents. */ +extern _LONG_CALL_ void *__DWC_ALLOC(void *mem_ctx, uint32_t size); + +/** Allocates a block of memory and zeroes its contents, in an atomic manner + * which can be used inside interrupt context. The size should be sufficiently + * small, a few KB at most, such that failures are not likely to occur. Can just call + * __DWC_ALLOC if it is atomic. */ +extern _LONG_CALL_ void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size); + +/** Frees a previously allocated buffer. */ +extern _LONG_CALL_ void __DWC_FREE(void *mem_ctx, void *addr); + +#ifndef DWC_DEBUG_MEMORY + +#define DWC_ALLOC(_size_) __DWC_ALLOC(NULL, _size_) +#define DWC_ALLOC_ATOMIC(_size_) __DWC_ALLOC_ATOMIC(NULL, _size_) +#define DWC_FREE(_addr_) __DWC_FREE(NULL, _addr_) + +#ifdef DWC_OS_PORTING +#define DWC_DMA_ALLOC(_size_,_dma_) __DWC_DMA_ALLOC(NULL, _size_, _dma_) +#define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) __DWC_DMA_ALLOC_ATOMIC(NULL, _size_,_dma_) +#define DWC_DMA_FREE(_size_,_virt_,_dma_) __DWC_DMA_FREE(NULL, _size_, _virt_, _dma_) +#endif + +#if defined(DWC_FREEBSD) || defined(DWC_NETBSD) +XXX +#define DWC_DMA_ALLOC __DWC_DMA_ALLOC +#define DWC_DMA_FREE __DWC_DMA_FREE +#endif + +#else /* DWC_DEBUG_MEMORY */ +XXX +extern void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line); +extern void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func, int line); +extern void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line); +extern void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr, + char const *func, int line); +extern void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr, + char const *func, int line); +extern void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr, + dwc_dma_t dma_addr, char const *func, int line); + +extern int dwc_memory_debug_start(void *mem_ctx); +extern void dwc_memory_debug_stop(void); +extern void dwc_memory_debug_report(void); + +#endif /* DWC_DEBUG_MEMORY */ + +#define dwc_alloc(_ctx_,_size_) DWC_ALLOC(_size_) +#define dwc_alloc_atomic(_ctx_,_size_) DWC_ALLOC_ATOMIC(_size_) +#define dwc_free(_ctx_,_addr_) DWC_FREE(_addr_) + +#ifdef DWC_OS_PORTING +/* Linux doesn't need any extra parameters for DMA buffer allocation, so we + * just throw away the DMA context parameter. + */ +#define dwc_dma_alloc(_ctx_,_size_,_dma_) DWC_DMA_ALLOC(_size_, _dma_) +#define dwc_dma_alloc_atomic(_ctx_,_size_,_dma_) DWC_DMA_ALLOC_ATOMIC(_size_, _dma_) +#define dwc_dma_free(_ctx_,_size_,_virt_,_dma_) DWC_DMA_FREE(_size_, _virt_, _dma_) +#endif + +#if 0//defined(DWC_FREEBSD) || defined(DWC_NETBSD) +/** BSD needs several extra parameters for DMA buffer allocation, so we pass + * them in using the DMA context parameter. + */ +#define dwc_dma_alloc DWC_DMA_ALLOC +#define dwc_dma_free DWC_DMA_FREE +#endif + + +/** @name Memory and String Processing */ + +/** memset() clone */ +extern _LONG_CALL_ void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size); +#define dwc_memset DWC_MEMSET + +/** memcpy() clone */ +extern _LONG_CALL_ void *DWC_MEMCPY(void *dest, void const *src, uint32_t size); +#define dwc_memcpy DWC_MEMCPY + +/** memmove() clone */ +extern _LONG_CALL_ void *DWC_MEMMOVE(void *dest, void *src, uint32_t size); +#define dwc_memmove DWC_MEMMOVE + +/** memcmp() clone */ +extern _LONG_CALL_ int DWC_MEMCMP(void *m1, void *m2, uint32_t size); +#define dwc_memcmp DWC_MEMCMP + +/** strcmp() clone */ +extern _LONG_CALL_ int DWC_STRCMP(void *s1, void *s2); +#define dwc_strcmp DWC_STRCMP + +/** strncmp() clone */ +extern _LONG_CALL_ int DWC_STRNCMP(void *s1, void *s2, uint32_t size); +#define dwc_strncmp DWC_STRNCMP + +/** strlen() clone, for NULL terminated ASCII strings */ +extern _LONG_CALL_ int DWC_STRLEN(char const *str); +#define dwc_strlen DWC_STRLEN + +/** strcpy() clone, for NULL terminated ASCII strings */ +extern _LONG_CALL_ char *DWC_STRCPY(char *to, const char *from); +#define dwc_strcpy DWC_STRCPY + +/** strdup() clone. If you wish to use memory allocation debugging, this + * implementation of strdup should use the DWC_* memory routines instead of + * calling a predefined strdup. Otherwise the memory allocated by this routine + * will not be seen by the debugging routines. */ +extern _LONG_CALL_ char *DWC_STRDUP(char const *str); +#define dwc_strdup(_ctx_,_str_) DWC_STRDUP(_str_) + +/** NOT an atoi() clone. Read the description carefully. Returns an integer + * converted from the string str in base 10 unless the string begins with a "0x" + * in which case it is base 16. String must be a NULL terminated sequence of + * ASCII characters and may optionally begin with whitespace, a + or -, and a + * "0x" prefix if base 16. The remaining characters must be valid digits for + * the number and end with a NULL character. If any invalid characters are + * encountered or it returns with a negative error code and the results of the + * conversion are undefined. On sucess it returns 0. Overflow conditions are + * undefined. An example implementation using atoi() can be referenced from the + * Linux implementation. */ +extern _LONG_CALL_ int DWC_ATOI(const char *str, int32_t *value); +#define dwc_atoi DWC_ATOI + +/** Same as above but for unsigned. */ +extern _LONG_CALL_ int DWC_ATOUI(const char *str, uint32_t *value); +#define dwc_atoui DWC_ATOUI + +#ifdef DWC_UTFLIB +XXX +/** This routine returns a UTF16LE unicode encoded string from a UTF8 string. */ +extern int DWC_UTF8_TO_UTF16LE(uint8_t const *utf8string, uint16_t *utf16string, unsigned len); +#define dwc_utf8_to_utf16le DWC_UTF8_TO_UTF16LE +#endif + + +/** @name Wait queues + * + * Wait queues provide a means of synchronizing between threads or processes. A + * process can block on a waitq if some condition is not true, waiting for it to + * become true. When the waitq is triggered all waiting process will get + * unblocked and the condition will be check again. Waitqs should be triggered + * every time a condition can potentially change.*/ +//struct dwc_waitq; + +/** Type for a waitq */ +//typedef struct dwc_waitq dwc_waitq_t; + +/** The type of waitq condition callback function. This is called every time + * condition is evaluated. */ +//typedef int (*dwc_waitq_condition_t)(void *data); + +/** Allocate a waitq */ +//extern dwc_waitq_t *DWC_WAITQ_ALLOC(void); +//#define dwc_waitq_alloc(_ctx_) DWC_WAITQ_ALLOC() + +/** Free a waitq */ +//extern void DWC_WAITQ_FREE(dwc_waitq_t *wq); +//#define dwc_waitq_free DWC_WAITQ_FREE + +/** Check the condition and if it is false, block on the waitq. When unblocked, check the + * condition again. The function returns when the condition becomes true. The return value + * is 0 on condition true, DWC_WAITQ_ABORTED on abort or killed, or DWC_WAITQ_UNKNOWN on error. */ +//extern int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data); +//#define dwc_waitq_wait DWC_WAITQ_WAIT + +/** Check the condition and if it is false, block on the waitq. When unblocked, + * check the condition again. The function returns when the condition become + * true or the timeout has passed. The return value is 0 on condition true or + * DWC_TIMED_OUT on timeout, or DWC_WAITQ_ABORTED, or DWC_WAITQ_UNKNOWN on + * error. */ +//extern int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, +// void *data, int32_t msecs); +//#define dwc_waitq_wait_timeout DWC_WAITQ_WAIT_TIMEOUT + +/** Trigger a waitq, unblocking all processes. This should be called whenever a condition + * has potentially changed. */ +//extern void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq); +//#define dwc_waitq_trigger DWC_WAITQ_TRIGGER + +/** Unblock all processes waiting on the waitq with an ABORTED result. */ +//extern void DWC_WAITQ_ABORT(dwc_waitq_t *wq); +//#define dwc_waitq_abort DWC_WAITQ_ABORT + + +/** @name Threads + * + * A thread must be explicitly stopped. It must check DWC_THREAD_SHOULD_STOP + * whenever it is woken up, and then return. The DWC_THREAD_STOP function + * returns the value from the thread. + */ + +/** @name Work queues + * + * Workqs are used to queue a callback function to be called at some later time, + * in another thread. */ +//struct dwc_workq; + +/** Type for a workq */ +typedef struct dwc_workq dwc_workq_t; + +/** The type of the callback function to be called. */ +//typedef void (*dwc_work_callback_t)(void *data); + +/** Allocate a workq */ +//extern dwc_workq_t *DWC_WORKQ_ALLOC(char *name); +//#define dwc_workq_alloc(_ctx_,_name_) DWC_WORKQ_ALLOC(_name_) + +/** Free a workq. All work must be completed before being freed. */ +//extern void DWC_WORKQ_FREE(dwc_workq_t *workq); +//#define dwc_workq_free DWC_WORKQ_FREE + +/** Schedule a callback on the workq, passing in data. The function will be + * scheduled at some later time. */ +//extern void DWC_WORKQ_SCHEDULE(dwc_workq_t *workq, dwc_work_callback_t cb, +// void *data, char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(printf, 4, 5))); +#else + ; +#endif +//#define dwc_workq_schedule DWC_WORKQ_SCHEDULE + +/** Schedule a callback on the workq, that will be called until at least + * given number miliseconds have passed. */ +//extern void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *workq, dwc_work_callback_t cb, +// void *data, uint32_t time, char *format, ...) +#if 0//def __GNUC__ + __attribute__ ((format(printf, 5, 6))); +#else + ; +#endif +//#define dwc_workq_schedule_delayed DWC_WORKQ_SCHEDULE_DELAYED + +/** The number of processes in the workq */ +//extern int DWC_WORKQ_PENDING(dwc_workq_t *workq); +//#define dwc_workq_pending DWC_WORKQ_PENDING + +/** Blocks until all the work in the workq is complete or timed out. Returns < + * 0 on timeout. */ +//extern int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout); +//#define dwc_workq_wait_work_done DWC_WORKQ_WAIT_WORK_DONE + + + + +/** @name Tasklets + * + */ + +//struct dwc_tasklet; + +/** Type for a tasklet */ +typedef struct dwc_tasklet dwc_tasklet_t; + +/** The type of the callback function to be called */ +//typedef void (*dwc_tasklet_callback_t)(void *data); + +/** Allocates a tasklet */ +//extern dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data); +//#define dwc_task_alloc(_ctx_,_name_,_cb_,_data_) DWC_TASK_ALLOC(_name_, _cb_, _data_) + +/** Frees a tasklet */ +//extern void DWC_TASK_FREE(dwc_tasklet_t *task); +//#define dwc_task_free DWC_TASK_FREE + +/** Schedules a tasklet to run */ +//extern void DWC_TASK_SCHEDULE(dwc_tasklet_t *task); +//#define dwc_task_schedule DWC_TASK_SCHEDULE + + +/** @name Timer + * + * Callbacks must be small and atomic. + */ +struct dwc_timer; + +/** Type for a timer */ +typedef struct dwc_timer dwc_timer_t; + +/** The type of the callback function to be called */ +typedef void (*dwc_timer_callback_t)(void *data); + +/** Allocates a timer */ +extern _LONG_CALL_ dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data); +#define dwc_timer_alloc(_ctx_,_name_,_cb_,_data_) DWC_TIMER_ALLOC(_name_,_cb_,_data_) + +/** Frees a timer */ +extern _LONG_CALL_ void DWC_TIMER_FREE(dwc_timer_t *timer); +#define dwc_timer_free DWC_TIMER_FREE + +/** Schedules the timer to run at time ms from now. And will repeat at every + * repeat_interval msec therafter + * + * Modifies a timer that is still awaiting execution to a new expiration time. + * The mod_time is added to the old time. */ +extern _LONG_CALL_ void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time); +#define dwc_timer_schedule DWC_TIMER_SCHEDULE + +/** Disables the timer from execution. */ +extern _LONG_CALL_ void DWC_TIMER_CANCEL(dwc_timer_t *timer); +#define dwc_timer_cancel DWC_TIMER_CANCEL + + +/** @name Spinlocks + * + * These locks are used when the work between the lock/unlock is atomic and + * short. Interrupts are also disabled during the lock/unlock and thus they are + * suitable to lock between interrupt/non-interrupt context. They also lock + * between processes if you have multiple CPUs or Preemption. If you don't have + * multiple CPUS or Preemption, then the you can simply implement the + * DWC_SPINLOCK and DWC_SPINUNLOCK to disable and enable interrupts. Because + * the work between the lock/unlock is atomic, the process context will never + * change, and so you never have to lock between processes. */ + +struct dwc_spinlock; + +/** Type for a spinlock */ +typedef struct dwc_spinlock dwc_spinlock_t; + +/** Type for the 'flags' argument to spinlock funtions */ +typedef unsigned long dwc_irqflags_t; + +/** Returns an initialized lock variable. This function should allocate and + * initialize the OS-specific data structure used for locking. This data + * structure is to be used for the DWC_LOCK and DWC_UNLOCK functions and should + * be freed by the DWC_FREE_LOCK when it is no longer used. */ +extern _LONG_CALL_ dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void); +#define dwc_spinlock_alloc(_ctx_) DWC_SPINLOCK_ALLOC() + +/** Frees an initialized lock variable. */ +extern _LONG_CALL_ void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock); +#define dwc_spinlock_free(_ctx_,_lock_) DWC_SPINLOCK_FREE(_lock_) + +/** Disables interrupts and blocks until it acquires the lock. + * + * @param lock Pointer to the spinlock. + * @param flags Unsigned long for irq flags storage. + */ +extern _LONG_CALL_ void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags); +#define dwc_spinlock_irqsave DWC_SPINLOCK_IRQSAVE + +/** Re-enables the interrupt and releases the lock. + * + * @param lock Pointer to the spinlock. + * @param flags Unsigned long for irq flags storage. Must be the same as was + * passed into DWC_LOCK. + */ +extern _LONG_CALL_ void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags); +#define dwc_spinunlock_irqrestore DWC_SPINUNLOCK_IRQRESTORE + +/** Blocks until it acquires the lock. + * + * @param lock Pointer to the spinlock. + */ +extern _LONG_CALL_ void DWC_SPINLOCK(dwc_spinlock_t *lock); +#define dwc_spinlock DWC_SPINLOCK + +/** Releases the lock. + * + * @param lock Pointer to the spinlock. + */ +extern _LONG_CALL_ void DWC_SPINUNLOCK(dwc_spinlock_t *lock); +#define dwc_spinunlock DWC_SPINUNLOCK + + +/** @name Mutexes + * + * Unlike spinlocks Mutexes lock only between processes and the work between the + * lock/unlock CAN block, therefore it CANNOT be called from interrupt context. + */ + +struct dwc_mutex; + +/** Type for a mutex */ +typedef struct dwc_mutex dwc_mutex_t; + +/* For Linux Mutex Debugging make it inline because the debugging routines use + * the symbol to determine recursive locking. This makes it falsely think + * recursive locking occurs. */ +#if defined(DWC_OS_PORTING) && defined(CONFIG_DEBUG_MUTEXES) +#define DWC_MUTEX_ALLOC_LINUX_DEBUG(__mutexp) ({ \ + __mutexp = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex)); \ + mutex_init((struct mutex *)__mutexp); \ +}) +#endif + +/** Allocate a mutex */ +extern _LONG_CALL_ dwc_mutex_t *DWC_MUTEX_ALLOC(void); +#define dwc_mutex_alloc(_ctx_) DWC_MUTEX_ALLOC() + +/* For memory leak debugging when using Linux Mutex Debugging */ +#if defined(DWC_OS_PORTING) && defined(CONFIG_DEBUG_MUTEXES) +XXX +#define DWC_MUTEX_FREE(__mutexp) do { \ + mutex_destroy((struct mutex *)__mutexp); \ + DWC_FREE(__mutexp); \ +} while(0) +#else +/** Free a mutex */ +extern _LONG_CALL_ void DWC_MUTEX_FREE(dwc_mutex_t *mutex); +#define dwc_mutex_free(_ctx_,_mutex_) DWC_MUTEX_FREE(_mutex_) +#endif + +/** Lock a mutex */ +extern _LONG_CALL_ void DWC_MUTEX_LOCK(dwc_mutex_t *mutex); +#define dwc_mutex_lock DWC_MUTEX_LOCK + +/** Non-blocking lock returns 1 on successful lock. */ +extern _LONG_CALL_ int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex); +#define dwc_mutex_trylock DWC_MUTEX_TRYLOCK + +/** Unlock a mutex */ +extern _LONG_CALL_ void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex); +#define dwc_mutex_unlock DWC_MUTEX_UNLOCK + + +/** @name Time */ + +/** Microsecond delay. + * + * @param usecs Microseconds to delay. + */ +extern _LONG_CALL_ void DWC_UDELAY(uint32_t usecs); +#define dwc_udelay DWC_UDELAY + +/** Millisecond delay. + * + * @param msecs Milliseconds to delay. + */ +extern _LONG_CALL_ void DWC_MDELAY(uint32_t msecs); +#define dwc_mdelay DWC_MDELAY + +/** Non-busy waiting. + * Sleeps for specified number of milliseconds. + * + * @param msecs Milliseconds to sleep. + */ +extern _LONG_CALL_ void DWC_MSLEEP(uint32_t msecs); +#define dwc_msleep DWC_MSLEEP + +extern _LONG_CALL_ void DWC_ENTER_CRITICAL(VOID); +extern _LONG_CALL_ void DWC_EXIT_CRITICAL(VOID); + +/** + * Returns number of milliseconds since boot. + */ +//extern uint32_t DWC_TIME(void); +//#define dwc_time DWC_TIME + + + + +/* @mainpage DWC Portability and Common Library + * + * This is the documentation for the DWC Portability and Common Library. + * + * @section intro Introduction + * + * The DWC Portability library consists of wrapper calls and data structures to + * all low-level functions which are typically provided by the OS. The WUDEV + * driver uses only these functions. In order to port the WUDEV driver, only + * the functions in this library need to be re-implemented, with the same + * behavior as documented here. + * + * The Common library consists of higher level functions, which rely only on + * calling the functions from the DWC Portability library. These common + * routines are shared across modules. Some of the common libraries need to be + * used directly by the driver programmer when porting WUDEV. Such as the + * parameter and notification libraries. + * + * @section low Portability Library OS Wrapper Functions + * + * Any function starting with DWC and in all CAPS is a low-level OS-wrapper that + * needs to be implemented when porting, for example DWC_MUTEX_ALLOC(). All of + * these functions are included in the dwc_os.h file. + * + * There are many functions here covering a wide array of OS services. Please + * see dwc_os.h for details, and implementation notes for each function. + * + * @section common Common Library Functions + * + * Any function starting with dwc and in all lowercase is a common library + * routine. These functions have a portable implementation and do not need to + * be reimplemented when porting. The common routines can be used by any + * driver, and some must be used by the end user to control the drivers. For + * example, you must use the Parameter common library in order to set the + * parameters in the WUDEV module. + * + * The common libraries consist of the following: + * + * - Connection Contexts - Used internally and can be used by end-user. See dwc_cc.h + * - Parameters - Used internally and can be used by end-user. See dwc_params.h + * - Notifications - Used internally and can be used by end-user. See dwc_notifier.h + * - Lists - Used internally and can be used by end-user. See dwc_list.h + * - Memory Debugging - Used internally and can be used by end-user. See dwc_os.h + * - Modpow - Used internally only. See dwc_modpow.h + * - DH - Used internally only. See dwc_dh.h + * - Crypto - Used internally only. See dwc_crypto.h + * + * + * @section prereq Prerequistes For dwc_os.h + * @subsection types Data Types + * + * The dwc_os.h file assumes that several low-level data types are pre defined for the + * compilation environment. These data types are: + * + * - uint8_t - unsigned 8-bit data type + * - int8_t - signed 8-bit data type + * - uint16_t - unsigned 16-bit data type + * - int16_t - signed 16-bit data type + * - uint32_t - unsigned 32-bit data type + * - int32_t - signed 32-bit data type + * - uint64_t - unsigned 64-bit data type + * - int64_t - signed 64-bit data type + * + * Ensure that these are defined before using dwc_os.h. The easiest way to do + * that is to modify the top of the file to include the appropriate header. + * This is already done for the Linux environment. If the DWC_OS_PORTING macro is + * defined, the correct header will be added. A standard header is + * also used for environments where standard C headers are available. + * + * @subsection stdarg Variable Arguments + * + * Variable arguments are provided by a standard C header . it is + * available in Both the Linux and ANSI C enviornment. An equivalent must be + * provided in your enviornment in order to use dwc_os.h with the debug and + * tracing message functionality. + * + * @subsection thread Threading + * + * WUDEV Core must be run on an operating system that provides for multiple + * threads/processes. Threading can be implemented in many ways, even in + * embedded systems without an operating system. At the bare minimum, the + * system should be able to start any number of processes at any time to handle + * special work. It need not be a pre-emptive system. Process context can + * change upon a call to a blocking function. The hardware interrupt context + * that calls the module's ISR() function must be differentiable from process + * context, even if your processes are impemented via a hardware interrupt. + * Further locking mechanism between process must exist (or be implemented), and + * process context must have a way to disable interrupts for a period of time to + * lock them out. If all of this exists, the functions in dwc_os.h related to + * threading should be able to be implemented with the defined behavior. + * + */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _DWC_OS_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_adp.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_adp.h new file mode 100644 index 0000000..eafa399 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_adp.h @@ -0,0 +1,82 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_adp.h $ + * $Revision: #8 $ + * $Date: 2013/04/09 $ + * $Change: 2201932 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#ifndef __DWC_OTG_ADP_H__ +#define __DWC_OTG_ADP_H__ + +/** + * @file + * + * This file contains the Attach Detect Protocol interfaces and defines + * (functions) and structures for Linux. + * + */ + +#define DWC_OTG_ADP_UNATTACHED 0 +#define DWC_OTG_ADP_ATTACHED 1 +#define DWC_OTG_ADP_UNKOWN 2 +#define HOST_RTIM_THRESHOLD 5 +#define DEVICE_RTIM_THRESHOLD 3 + +typedef struct dwc_otg_adp { + uint32_t adp_started; + uint32_t initial_probe; + int32_t probe_timer_values[2]; + uint32_t probe_enabled; + uint32_t sense_enabled; + dwc_timer_t *sense_timer; + uint32_t sense_timer_started; + dwc_timer_t *vbuson_timer; + uint32_t vbuson_timer_started; + uint32_t attached; + uint32_t probe_counter; + uint32_t gpwrdn; +} dwc_otg_adp_t; + +/** + * Attach Detect Protocol functions + */ + +extern void dwc_otg_adp_write_reg(dwc_otg_core_if_t * core_if, uint32_t value); +extern uint32_t dwc_otg_adp_read_reg(dwc_otg_core_if_t * core_if); +extern uint32_t dwc_otg_adp_probe_start(dwc_otg_core_if_t * core_if); +extern uint32_t dwc_otg_adp_sense_start(dwc_otg_core_if_t * core_if); +extern uint32_t dwc_otg_adp_probe_stop(dwc_otg_core_if_t * core_if); +extern uint32_t dwc_otg_adp_sense_stop(dwc_otg_core_if_t * core_if); +extern void dwc_otg_adp_start(dwc_otg_core_if_t * core_if, uint8_t is_host); +extern void dwc_otg_adp_init(dwc_otg_core_if_t * core_if); +extern void dwc_otg_adp_remove(dwc_otg_core_if_t * core_if); +extern int32_t dwc_otg_adp_handle_intr(dwc_otg_core_if_t * core_if); +extern int32_t dwc_otg_adp_handle_srp_intr(dwc_otg_core_if_t * core_if); + +#endif //__DWC_OTG_ADP_H__ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_attr.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_attr.h new file mode 100644 index 0000000..6e62146 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_attr.h @@ -0,0 +1,86 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_attr.h $ + * $Revision: #13 $ + * $Date: 2010/06/21 $ + * $Change: 1532021 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#if !defined(__DWC_OTG_ATTR_H__) +#define __DWC_OTG_ATTR_H__ +#if 0 +/** @file + * This file contains the interface to the Linux device attributes. + */ +extern struct device_attribute dev_attr_regoffset; +extern struct device_attribute dev_attr_regvalue; + +extern struct device_attribute dev_attr_mode; +extern struct device_attribute dev_attr_hnpcapable; +extern struct device_attribute dev_attr_srpcapable; +extern struct device_attribute dev_attr_hnp; +extern struct device_attribute dev_attr_srp; +extern struct device_attribute dev_attr_buspower; +extern struct device_attribute dev_attr_bussuspend; +extern struct device_attribute dev_attr_mode_ch_tim_en; +extern struct device_attribute dev_attr_fr_interval; +extern struct device_attribute dev_attr_busconnected; +extern struct device_attribute dev_attr_gotgctl; +extern struct device_attribute dev_attr_gusbcfg; +extern struct device_attribute dev_attr_grxfsiz; +extern struct device_attribute dev_attr_gnptxfsiz; +extern struct device_attribute dev_attr_gpvndctl; +extern struct device_attribute dev_attr_ggpio; +extern struct device_attribute dev_attr_guid; +extern struct device_attribute dev_attr_gsnpsid; +extern struct device_attribute dev_attr_devspeed; +extern struct device_attribute dev_attr_enumspeed; +extern struct device_attribute dev_attr_hptxfsiz; +extern struct device_attribute dev_attr_hprt0; +#ifdef CONFIG_USB_DWC_OTG_LPM +extern struct device_attribute dev_attr_lpm_response; +extern struct device_attribute devi_attr_sleep_status; +#endif + +void dwc_otg_attr_create( +#ifdef LM_INTERFACE + struct lm_device *dev +#elif PCI_INTERFACE + struct pci_dev *dev +#endif + ); + +void dwc_otg_attr_remove( +#ifdef LM_INTERFACE + struct lm_device *dev +#elif PCI_INTERFACE + struct pci_dev *dev +#endif + ); +#endif +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_cil.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_cil.h new file mode 100644 index 0000000..eccb3a9 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_cil.h @@ -0,0 +1,1343 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.h $ + * $Revision: #128 $ + * $Date: 2013/05/16 $ + * $Change: 2231774 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#if !defined(__DWC_CIL_H__) +#define __DWC_CIL_H__ + +#include "dwc_list.h" +#include "dwc_otg_dbg.h" +#include "dwc_otg_regs.h" + +#include "dwc_otg_core_if.h" +#include "dwc_otg_adp.h" +#include "rtl8195a_otg.h" +/** + * @file + * This file contains the interface to the Core Interface Layer. + */ +//#define DWC_DEVICE_ONLY 0 + +#ifdef DWC_UTE_CFI + +#define MAX_DMA_DESCS_PER_EP 256 + +/** + * Enumeration for the data buffer mode + */ +typedef enum _data_buffer_mode { + BM_STANDARD = 0, /* data buffer is in normal mode */ + BM_SG = 1, /* data buffer uses the scatter/gather mode */ + BM_CONCAT = 2, /* data buffer uses the concatenation mode */ + BM_CIRCULAR = 3, /* data buffer uses the circular DMA mode */ + BM_ALIGN = 4 /* data buffer is in buffer alignment mode */ +} data_buffer_mode_e; +#endif //DWC_UTE_CFI + +/** Macros defined for DWC OTG HW Release version */ + +#define OTG_CORE_REV_2_60a 0x4F54260A +#define OTG_CORE_REV_2_71a 0x4F54271A +#define OTG_CORE_REV_2_72a 0x4F54272A +#define OTG_CORE_REV_2_80a 0x4F54280A +#define OTG_CORE_REV_2_81a 0x4F54281A +#define OTG_CORE_REV_2_90a 0x4F54290A +#define OTG_CORE_REV_2_91a 0x4F54291A +#define OTG_CORE_REV_2_92a 0x4F54292A +#define OTG_CORE_REV_2_93a 0x4F54293A +#define OTG_CORE_REV_2_94a 0x4F54294A +#define OTG_CORE_REV_3_00a 0x4F54300A +#define OTG_CORE_REV_3_10a 0x4F54310A + +/** + * Information for each ISOC packet. + */ +typedef struct iso_pkt_info { + uint32_t offset; + uint32_t length; + int32_t status; +} iso_pkt_info_t; + +/** + * The dwc_ep structure represents the state of a single + * endpoint when acting in device mode. It contains the data items + * needed for an endpoint to be activated and transfer packets. + */ +typedef struct dwc_ep { + /** EP number used for register address lookup */ + uint8_t num; + /** EP direction 0 = OUT */ + unsigned is_in:1; + /** EP active. */ + unsigned active:1; + + /** + * Periodic Tx FIFO # for IN EPs For INTR EP set to 0 to use non-periodic + * Tx FIFO. If dedicated Tx FIFOs are enabled Tx FIFO # FOR IN EPs*/ + unsigned tx_fifo_num:4; + /** EP type: 0 - Control, 1 - ISOC, 2 - BULK, 3 - INTR */ + unsigned type:2; +#define DWC_OTG_EP_TYPE_CONTROL 0 +#define DWC_OTG_EP_TYPE_ISOC 1 +#define DWC_OTG_EP_TYPE_BULK 2 +#define DWC_OTG_EP_TYPE_INTR 3 + + /** DATA start PID for INTR and BULK EP */ + unsigned data_pid_start:1; + /** Frame (even/odd) for ISOC EP */ + unsigned even_odd_frame:1; + /** Max Packet bytes */ + unsigned maxpacket:11; + + /** Max Transfer size */ + uint32_t maxxfer; + + /** @name Transfer state */ + /** @{ */ + + /** + * Pointer to the beginning of the transfer buffer -- do not modify + * during transfer. + */ + dwc_dma_t dma_addr; + + dwc_dma_t dma_desc_addr; + dwc_otg_dev_dma_desc_t *desc_addr; + + /* Additional desc chain for ISO transfers */ + dwc_dma_t dma_desc_addr1; + dwc_otg_dev_dma_desc_t *desc_addr1; + /* Flag indicating which one of two ISO desc chains currently is in use */ + uint8_t use_add_buf; + + uint8_t *start_xfer_buff; + /** pointer to the transfer buffer */ + uint8_t *xfer_buff; + /** Number of bytes to transfer */ + unsigned xfer_len:19; + /** Number of bytes transferred. */ + unsigned xfer_count:19; + /** Sent ZLP */ + unsigned sent_zlp:1; + /** Total len for control transfer */ + unsigned total_len:19; + + /** stall clear flag */ + unsigned stall_clear_flag:1; + + /** SETUP pkt cnt rollover flag for EP0 out*/ + unsigned stp_rollover; + +#ifdef DWC_UTE_CFI + /* The buffer mode */ + data_buffer_mode_e buff_mode; + + /* The chain of DMA descriptors. + * MAX_DMA_DESCS_PER_EP will be allocated for each active EP. + */ + dwc_otg_dma_desc_t *descs; + + /* The DMA address of the descriptors chain start */ + dma_addr_t descs_dma_addr; + /** This variable stores the length of the last enqueued request */ + uint32_t cfi_req_len; +#endif //DWC_UTE_CFI + +/** Max DMA Descriptor count for any EP */ +#define MAX_DMA_DESC_CNT 256 + /** Allocated DMA Desc count */ + uint32_t desc_cnt; + + /** First ISO Desc in use in the first chain*/ + uint32_t iso_desc_first; + /** Last ISO Desc in use in the second chain */ + uint32_t iso_desc_second; + /** Flag indicated that iso transfers were started */ + uint8_t iso_transfer_started; + + /** bInterval */ + uint32_t bInterval; + /** Next frame num to setup next ISOC transfer */ + uint32_t frame_num; + /** Indicates SOF number overrun in DSTS */ + uint8_t frm_overrun; + +#ifdef DWC_UTE_PER_IO + /** Next frame num for which will be setup DMA Desc */ + uint32_t xiso_frame_num; + /** bInterval */ + uint32_t xiso_bInterval; + /** Count of currently active transfers - shall be either 0 or 1 */ + int xiso_active_xfers; + int xiso_queued_xfers; +#endif +#ifdef DWC_EN_ISOC + /** + * Variables specific for ISOC EPs + * + */ + /** DMA addresses of ISOC buffers */ + dwc_dma_t dma_addr0; + dwc_dma_t dma_addr1; + + dwc_dma_t iso_dma_desc_addr; + dwc_otg_dev_dma_desc_t *iso_desc_addr; + + /** pointer to the transfer buffers */ + uint8_t *xfer_buff0; + uint8_t *xfer_buff1; + + /** number of ISOC Buffer is processing */ + uint32_t proc_buf_num; + /** Interval of ISOC Buffer processing */ + uint32_t buf_proc_intrvl; + /** Data size for regular frame */ + uint32_t data_per_frame; + + /* todo - pattern data support is to be implemented in the future */ + /** Data size for pattern frame */ + uint32_t data_pattern_frame; + /** Frame number of pattern data */ + uint32_t sync_frame; + + /** bInterval */ + uint32_t bInterval; + /** ISO Packet number per frame */ + uint32_t pkt_per_frm; + /** Next frame num for which will be setup DMA Desc */ + uint32_t next_frame; + /** Number of packets per buffer processing */ + uint32_t pkt_cnt; + /** Info for all isoc packets */ + iso_pkt_info_t *pkt_info; + /** current pkt number */ + uint32_t cur_pkt; + /** current pkt number */ + uint8_t *cur_pkt_addr; + /** current pkt number */ + uint32_t cur_pkt_dma_addr; +#endif /* DWC_EN_ISOC */ + +/** @} */ +} dwc_ep_t; + +/* + * Reasons for halting a host channel. + */ +typedef enum dwc_otg_halt_status { + DWC_OTG_HC_XFER_NO_HALT_STATUS, + DWC_OTG_HC_XFER_COMPLETE, + DWC_OTG_HC_XFER_URB_COMPLETE, + DWC_OTG_HC_XFER_ACK, + DWC_OTG_HC_XFER_NAK, + DWC_OTG_HC_XFER_NYET, + DWC_OTG_HC_XFER_STALL, + DWC_OTG_HC_XFER_XACT_ERR, + DWC_OTG_HC_XFER_FRAME_OVERRUN, + DWC_OTG_HC_XFER_BABBLE_ERR, + DWC_OTG_HC_XFER_DATA_TOGGLE_ERR, + DWC_OTG_HC_XFER_AHB_ERR, + DWC_OTG_HC_XFER_PERIODIC_INCOMPLETE, + DWC_OTG_HC_XFER_URB_DEQUEUE +} dwc_otg_halt_status_e; + +/** + * Host channel descriptor. This structure represents the state of a single + * host channel when acting in host mode. It contains the data items needed to + * transfer packets to an endpoint via a host channel. + */ +typedef struct dwc_hc { + /** Host channel number used for register address lookup */ + uint8_t hc_num; + + /** Device to access */ + unsigned dev_addr:7; + + /** EP to access */ + unsigned ep_num:4; + + /** EP direction. 0: OUT, 1: IN */ + unsigned ep_is_in:1; + + /** + * EP speed. + * One of the following values: + * - DWC_OTG_EP_SPEED_LOW + * - DWC_OTG_EP_SPEED_FULL + * - DWC_OTG_EP_SPEED_HIGH + */ + unsigned speed:2; +#define DWC_OTG_EP_SPEED_LOW 0 +#define DWC_OTG_EP_SPEED_FULL 1 +#define DWC_OTG_EP_SPEED_HIGH 2 + + /** + * Endpoint type. + * One of the following values: + * - DWC_OTG_EP_TYPE_CONTROL: 0 + * - DWC_OTG_EP_TYPE_ISOC: 1 + * - DWC_OTG_EP_TYPE_BULK: 2 + * - DWC_OTG_EP_TYPE_INTR: 3 + */ + unsigned ep_type:2; + + /** Max packet size in bytes */ + unsigned max_packet:11; + + /** + * PID for initial transaction. + * 0: DATA0,
+ * 1: DATA2,
+ * 2: DATA1,
+ * 3: MDATA (non-Control EP), + * SETUP (Control EP) + */ + unsigned data_pid_start:2; +#define DWC_OTG_HC_PID_DATA0 0 +#define DWC_OTG_HC_PID_DATA2 1 +#define DWC_OTG_HC_PID_DATA1 2 +#define DWC_OTG_HC_PID_MDATA 3 +#define DWC_OTG_HC_PID_SETUP 3 + + /** Number of periodic transactions per (micro)frame */ + unsigned multi_count:2; + + /** @name Transfer State */ + /** @{ */ + + /** Pointer to the current transfer buffer position. */ + uint8_t *xfer_buff; + /** + * In Buffer DMA mode this buffer will be used + * if xfer_buff is not DWORD aligned. + */ + dwc_dma_t align_buff; + /** Total number of bytes to transfer. */ + uint32_t xfer_len; + /** Number of bytes transferred so far. */ + uint32_t xfer_count; + /** Packet count at start of transfer.*/ + uint16_t start_pkt_count; + + /** + * Flag to indicate whether the transfer has been started. Set to 1 if + * it has been started, 0 otherwise. + */ + uint8_t xfer_started; + + /** + * Set to 1 to indicate that a PING request should be issued on this + * channel. If 0, process normally. + */ + uint8_t do_ping; + + /** + * Set to 1 to indicate that the error count for this transaction is + * non-zero. Set to 0 if the error count is 0. + */ + uint8_t error_state; + + /** + * Set to 1 to indicate that this channel should be halted the next + * time a request is queued for the channel. This is necessary in + * slave mode if no request queue space is available when an attempt + * is made to halt the channel. + */ + uint8_t halt_on_queue; + + /** + * Set to 1 if the host channel has been halted, but the core is not + * finished flushing queued requests. Otherwise 0. + */ + uint8_t halt_pending; + + /** + * Reason for halting the host channel. + */ + dwc_otg_halt_status_e halt_status; + + /* + * Split settings for the host channel + */ + uint8_t do_split; /**< Enable split for the channel */ + uint8_t complete_split; /**< Enable complete split */ + uint8_t hub_addr; /**< Address of high speed hub */ + + uint8_t port_addr; /**< Port of the low/full speed device */ + /** Split transaction position + * One of the following values: + * - DWC_HCSPLIT_XACTPOS_MID + * - DWC_HCSPLIT_XACTPOS_BEGIN + * - DWC_HCSPLIT_XACTPOS_END + * - DWC_HCSPLIT_XACTPOS_ALL */ + uint8_t xact_pos; + + /** Set when the host channel does a short read. */ + uint8_t short_read; + + /** + * Number of requests issued for this channel since it was assigned to + * the current transfer (not counting PINGs). + */ + uint8_t requests; + + /** + * Queue Head for the transfer being processed by this channel. + */ + struct dwc_otg_qh *qh; + + /** @} */ + + /** Entry in list of host channels. */ + DWC_CIRCLEQ_ENTRY(dwc_hc) hc_list_entry; + + /** @name Descriptor DMA support */ + /** @{ */ + + /** Number of Transfer Descriptors */ + uint16_t ntd; + + /** Descriptor List DMA address */ + dwc_dma_t desc_list_addr; + + /** Scheduling micro-frame bitmap. */ + uint8_t schinfo; + + /** @} */ +} dwc_hc_t; + +/** + * The following parameters may be specified when starting the module. These + * parameters define how the DWC_otg controller should be configured. + */ +typedef struct dwc_otg_core_params { + int32_t opt; + + /** + * Specifies the OTG capabilities. The driver will automatically + * detect the value for this parameter if none is specified. + * 0 - HNP and SRP capable (default) + * 1 - SRP Only capable + * 2 - No HNP/SRP capable + */ + int32_t otg_cap; + + /** + * Specifies whether to use slave or DMA mode for accessing the data + * FIFOs. The driver will automatically detect the value for this + * parameter if none is specified. + * 0 - Slave + * 1 - DMA (default, if available) + */ + int32_t dma_enable; + + /** + * When DMA mode is enabled specifies whether to use address DMA or DMA + * Descriptor mode for accessing the data FIFOs in device mode. The driver + * will automatically detect the value for this if none is specified. + * 0 - address DMA + * 1 - DMA Descriptor(default, if available) + */ + int32_t dma_desc_enable; + /** The DMA Burst size (applicable only for External DMA + * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32) + */ + int32_t dma_burst_size; /* Translate this to GAHBCFG values */ + + /** + * Specifies the maximum speed of operation in host and device mode. + * The actual speed depends on the speed of the attached device and + * the value of phy_type. The actual speed depends on the speed of the + * attached device. + * 0 - High Speed (default) + * 1 - Full Speed + */ + int32_t speed; + /** Specifies whether low power mode is supported when attached + * to a Full Speed or Low Speed device in host mode. + * 0 - Don't support low power mode (default) + * 1 - Support low power mode + */ + int32_t host_support_fs_ls_low_power; + + /** Specifies the PHY clock rate in low power mode when connected to a + * Low Speed device in host mode. This parameter is applicable only if + * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS + * then defaults to 6 MHZ otherwise 48 MHZ. + * + * 0 - 48 MHz + * 1 - 6 MHz + */ + int32_t host_ls_low_power_phy_clk; + + /** + * 0 - Use cC FIFO size parameters + * 1 - Allow dynamic FIFO sizing (default) + */ + int32_t enable_dynamic_fifo; + + /** Total number of 4-byte words in the data FIFO memory. This + * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic + * Tx FIFOs. + * 32 to 32768 (default 8192) + * Note: The total FIFO memory depth in the FPGA configuration is 8192. + */ + int32_t data_fifo_size; + + /** Number of 4-byte words in the Rx FIFO in device mode when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1064) + */ + int32_t dev_rx_fifo_size; + + /** Number of 4-byte words in the non-periodic Tx FIFO in device mode + * when dynamic FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ + int32_t dev_nperio_tx_fifo_size; + + /** Number of 4-byte words in each of the periodic Tx FIFOs in device + * mode when dynamic FIFO sizing is enabled. + * 4 to 768 (default 256) + */ + uint32_t dev_perio_tx_fifo_size[MAX_PERIO_FIFOS]; + + /** Number of 4-byte words in the Rx FIFO in host mode when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ + int32_t host_rx_fifo_size; + + /** Number of 4-byte words in the non-periodic Tx FIFO in host mode + * when Dynamic FIFO sizing is enabled in the core. + * 16 to 32768 (default 1024) + */ + int32_t host_nperio_tx_fifo_size; + + /** Number of 4-byte words in the host periodic Tx FIFO when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ + int32_t host_perio_tx_fifo_size; + + /** The maximum transfer size supported in bytes. + * 2047 to 65,535 (default 65,535) + */ + int32_t max_transfer_size; + + /** The maximum number of packets in a transfer. + * 15 to 511 (default 511) + */ + int32_t max_packet_count; + + /** The number of host channel registers to use. + * 1 to 16 (default 12) + * Note: The FPGA configuration supports a maximum of 12 host channels. + */ + int32_t host_channels; + + /** The number of endpoints in addition to EP0 available for device + * mode operations. + * 1 to 15 (default 6 IN and OUT) + * Note: The FPGA configuration supports a maximum of 6 IN and OUT + * endpoints in addition to EP0. + */ + int32_t dev_endpoints; + + /** + * Specifies the type of PHY interface to use. By default, the driver + * will automatically detect the phy_type. + * + * 0 - Full Speed PHY + * 1 - UTMI+ (default) + * 2 - ULPI + */ + int32_t phy_type; + + /** + * Specifies the UTMI+ Data Width. This parameter is + * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI + * PHY_TYPE, this parameter indicates the data width between + * the MAC and the ULPI Wrapper.) Also, this parameter is + * applicable only if the OTG_HSPHY_WIDTH cC parameter was set + * to "8 and 16 bits", meaning that the core has been + * configured to work at either data path width. + * + * 8 or 16 bits (default 16) + */ + int32_t phy_utmi_width; + + /** + * Specifies whether the ULPI operates at double or single + * data rate. This parameter is only applicable if PHY_TYPE is + * ULPI. + * + * 0 - single data rate ULPI interface with 8 bit wide data + * bus (default) + * 1 - double data rate ULPI interface with 4 bit wide data + * bus + */ + int32_t phy_ulpi_ddr; + + /** + * Specifies whether to use the internal or external supply to + * drive the vbus with a ULPI phy. + */ + int32_t phy_ulpi_ext_vbus; + + /** + * Specifies whether to use the I2Cinterface for full speed PHY. This + * parameter is only applicable if PHY_TYPE is FS. + * 0 - No (default) + * 1 - Yes + */ + int32_t i2c_enable; + + int32_t ulpi_fs_ls; + + int32_t ts_dline; + + /** + * Specifies whether dedicated transmit FIFOs are + * enabled for non periodic IN endpoints in device mode + * 0 - No + * 1 - Yes + */ + int32_t en_multiple_tx_fifo; + + /** Number of 4-byte words in each of the Tx FIFOs in device + * mode when dynamic FIFO sizing is enabled. + * 4 to 768 (default 256) + */ + uint32_t dev_tx_fifo_size[MAX_TX_FIFOS]; + + /** Thresholding enable flag- + * bit 0 - enable non-ISO Tx thresholding + * bit 1 - enable ISO Tx thresholding + * bit 2 - enable Rx thresholding + */ + uint32_t thr_ctl; + + /** Thresholding length for Tx + * FIFOs in 32 bit DWORDs + */ + uint32_t tx_thr_length; + + /** Thresholding length for Rx + * FIFOs in 32 bit DWORDs + */ + uint32_t rx_thr_length; + + /** + * Specifies whether LPM (Link Power Management) support is enabled + */ + int32_t lpm_enable; + + /** + * Specifies whether LPM Errata (Link Power Management) support is enabled + */ + int32_t besl_enable; + + /** + * Specifies the baseline besl value + */ + int32_t baseline_besl; + + /** + * Specifies the deep besl value + */ + int32_t deep_besl; + /** Per Transfer Interrupt + * mode enable flag + * 1 - Enabled + * 0 - Disabled + */ + int32_t pti_enable; + + /** Multi Processor Interrupt + * mode enable flag + * 1 - Enabled + * 0 - Disabled + */ + int32_t mpi_enable; + + /** IS_USB Capability + * 1 - Enabled + * 0 - Disabled + */ + int32_t ic_usb_cap; + + /** AHB Threshold Ratio + * 2'b00 AHB Threshold = MAC Threshold + * 2'b01 AHB Threshold = 1/2 MAC Threshold + * 2'b10 AHB Threshold = 1/4 MAC Threshold + * 2'b11 AHB Threshold = 1/8 MAC Threshold + */ + int32_t ahb_thr_ratio; + + /** ADP Support + * 1 - Enabled + * 0 - Disabled + */ + int32_t adp_supp_enable; + + /** HFIR Reload Control + * 0 - The HFIR cannot be reloaded dynamically. + * 1 - Allow dynamic reloading of the HFIR register during runtime. + */ + int32_t reload_ctl; + + /** DCFG: Enable device Out NAK + * 0 - The core does not set NAK after Bulk Out transfer complete. + * 1 - The core sets NAK after Bulk OUT transfer complete. + */ + int32_t dev_out_nak; + + /** DCFG: Enable Continue on BNA + * After receiving BNA interrupt the core disables the endpoint,when the + * endpoint is re-enabled by the application the core starts processing + * 0 - from the DOEPDMA descriptor + * 1 - from the descriptor which received the BNA. + */ + int32_t cont_on_bna; + + /** GAHBCFG: AHB Single Support + * This bit when programmed supports SINGLE transfers for remainder + * data in a transfer for DMA mode of operation. + * 0 - in this case the remainder data will be sent using INCR burst size. + * 1 - in this case the remainder data will be sent using SINGLE burst size. + */ + int32_t ahb_single; + + /** Core Power down mode + * 0 - No Power Down is enabled + * 1 - Reserved + * 2 - Complete Power Down (Hibernation) + */ + int32_t power_down; + + /** OTG revision supported + * 0 - OTG 1.3 revision + * 1 - OTG 2.0 revision + */ + int32_t otg_ver; + +} dwc_otg_core_params_t; + +#ifdef OTGDEBUG +struct dwc_otg_core_if; +typedef struct hc_xfer_info { + struct dwc_otg_core_if *core_if; + dwc_hc_t *hc; +} hc_xfer_info_t; +#endif + +typedef struct ep_xfer_info { + struct dwc_otg_core_if *core_if; + dwc_ep_t *ep; + uint8_t state; +} ep_xfer_info_t; +/* + * Device States + */ +typedef enum dwc_otg_lx_state { + /** On state */ + DWC_OTG_L0, + /** LPM sleep state*/ + DWC_OTG_L1, + /** USB suspend state*/ + DWC_OTG_L2, + /** Off state*/ + DWC_OTG_L3 +} dwc_otg_lx_state_e; + +struct dwc_otg_global_regs_backup { + uint32_t gotgctl_local; + uint32_t gintmsk_local; + uint32_t gahbcfg_local; + uint32_t gusbcfg_local; + uint32_t grxfsiz_local; + uint32_t gnptxfsiz_local; +#ifdef CONFIG_USB_DWC_OTG_LPM + uint32_t glpmcfg_local; +#endif + uint32_t gi2cctl_local; + uint32_t hptxfsiz_local; + uint32_t pcgcctl_local; + uint32_t gdfifocfg_local; + uint32_t dtxfsiz_local[MAX_EPS_CHANNELS]; + uint32_t gpwrdn_local; + uint32_t xhib_pcgcctl; + uint32_t xhib_gpwrdn; +}; + +struct dwc_otg_host_regs_backup { + uint32_t hcfg_local; + uint32_t haintmsk_local; + uint32_t hcintmsk_local[MAX_EPS_CHANNELS]; + uint32_t hprt0_local; + uint32_t hfir_local; +}; + +struct dwc_otg_dev_regs_backup { + uint32_t dcfg; + uint32_t dctl; + uint32_t daintmsk; + uint32_t diepmsk; + uint32_t doepmsk; + uint32_t diepctl[MAX_EPS_CHANNELS]; + uint32_t dieptsiz[MAX_EPS_CHANNELS]; + uint32_t diepdma[MAX_EPS_CHANNELS]; +}; +/** + * The dwc_otg_core_if structure contains information needed to manage + * the DWC_otg controller acting in either host or device mode. It + * represents the programming view of the controller as a whole. + */ +struct dwc_otg_core_if { + /** Parameters that define how the core should be configured.*/ + dwc_otg_core_params_t *core_params; + + /** Core Global registers starting at offset 000h. */ + dwc_otg_core_global_regs_t *core_global_regs; + + /** Device-specific information */ + dwc_otg_dev_if_t *dev_if; + /** Host-specific information */ + dwc_otg_host_if_t *host_if; + + /** Value from SNPSID register */ + uint32_t snpsid; + + /* + * Set to 1 if the core PHY interface bits in USBCFG have been + * initialized. + */ + uint8_t phy_init_done; + + /* + * SRP Success flag, set by srp success interrupt in FS I2C mode + */ + uint8_t srp_success; + uint8_t srp_timer_started; + /** Timer for SRP. If it expires before SRP is successful + * clear the SRP. */ + dwc_timer_t *srp_timer; + +#ifdef DWC_DEV_SRPCAP + /* This timer is needed to power on the hibernated host core if SRP is not + * initiated on connected SRP capable device for limited period of time + */ + uint8_t pwron_timer_started; + dwc_timer_t *pwron_timer; +#endif + /* Common configuration information */ + /** Power and Clock Gating Control Register */ + volatile uint32_t *pcgcctl; +#define DWC_OTG_PCGCCTL_OFFSET 0xE00 + + /** Push/pop addresses for endpoints or host channels.*/ + uint32_t *data_fifo[MAX_EPS_CHANNELS]; +#define DWC_OTG_DATA_FIFO_OFFSET 0x1000 +#define DWC_OTG_DATA_FIFO_SIZE 0x1000 + + /** Total RAM for FIFOs (Bytes) */ + uint16_t total_fifo_size; + /** Size of Rx FIFO (Bytes) */ + uint16_t rx_fifo_size; + /** Size of Non-periodic Tx FIFO (Bytes) */ + uint16_t nperio_tx_fifo_size; + + /** 1 if DMA is enabled, 0 otherwise. */ + uint8_t dma_enable; + + /** 1 if DMA descriptor is enabled, 0 otherwise. */ + uint8_t dma_desc_enable; + + /** 1 if PTI Enhancement mode is enabled, 0 otherwise. */ + uint8_t pti_enh_enable; + + /** 1 if MPI Enhancement mode is enabled, 0 otherwise. */ + uint8_t multiproc_int_enable; + + /** 1 if dedicated Tx FIFOs are enabled, 0 otherwise. */ + uint8_t en_multiple_tx_fifo; + + /** Set to 1 if multiple packets of a high-bandwidth transfer is in + * process of being queued */ + uint8_t queuing_high_bandwidth; + + /** Hardware Configuration -- stored here for convenience.*/ + hwcfg1_data_t hwcfg1; + hwcfg2_data_t hwcfg2; + hwcfg3_data_t hwcfg3; + hwcfg4_data_t hwcfg4; + fifosize_data_t hptxfsiz; + + /** Host and Device Configuration -- stored here for convenience.*/ + hcfg_data_t hcfg; + dcfg_data_t dcfg; + + /** The operational State, during transations + * (a_host>>a_peripherial and b_device=>b_host) this may not + * match the core but allows the software to determine + * transitions. + */ + uint8_t op_state; + + /** Test mode for PET testing */ + uint8_t test_mode; + + /** + * Set to 1 if the HCD needs to be restarted on a session request + * interrupt. This is required if no connector ID status change has + * occurred since the HCD was last disconnected. + */ + uint8_t restart_hcd_on_session_req; + + /** HCD callbacks */ + /** A-Device is a_host */ +#define A_HOST (1) + /** A-Device is a_suspend */ +#define A_SUSPEND (2) + /** A-Device is a_peripherial */ +#define A_PERIPHERAL (3) + /** B-Device is operating as a Peripheral. */ +#define B_PERIPHERAL (4) + /** B-Device is operating as a Host. */ +#define B_HOST (5) + + /** HCD callbacks */ + struct dwc_otg_cil_callbacks *hcd_cb; + /** PCD callbacks */ + struct dwc_otg_cil_callbacks *pcd_cb; + + /** Device mode Periodic Tx FIFO Mask */ + uint32_t p_tx_msk; + /** Device mode Periodic Tx FIFO Mask */ + uint32_t tx_msk; + + /** Workqueue object used for handling several interrupts */ + dwc_workq_t *wq_otg; + + /** Timer object used for handling "Wakeup Detected" Interrupt */ + dwc_timer_t *wkp_timer; + /** This arrays used for debug purposes for DEV OUT NAK enhancement */ + uint32_t start_doeptsiz_val[MAX_EPS_CHANNELS]; + ep_xfer_info_t ep_xfer_info[MAX_EPS_CHANNELS]; + dwc_timer_t *ep_xfer_timer[MAX_EPS_CHANNELS]; +#ifdef OTGDEBUG + uint32_t start_hcchar_val[MAX_EPS_CHANNELS]; + + hc_xfer_info_t hc_xfer_info[MAX_EPS_CHANNELS]; + dwc_timer_t *hc_xfer_timer[MAX_EPS_CHANNELS]; + + uint32_t hfnum_7_samples; + uint64_t hfnum_7_frrem_accum; + uint32_t hfnum_0_samples; + uint64_t hfnum_0_frrem_accum; + uint32_t hfnum_other_samples; + uint64_t hfnum_other_frrem_accum; +#endif + +#ifdef DWC_UTE_CFI + uint16_t pwron_rxfsiz; + uint16_t pwron_gnptxfsiz; + uint16_t pwron_txfsiz[15]; + + uint16_t init_rxfsiz; + uint16_t init_gnptxfsiz; + uint16_t init_txfsiz[15]; +#endif + + /** Lx state of device */ + dwc_otg_lx_state_e lx_state; + + /** Saved Core Global registers */ + struct dwc_otg_global_regs_backup *gr_backup; + /** Saved Host registers */ + struct dwc_otg_host_regs_backup *hr_backup; + /** Saved Device registers */ + struct dwc_otg_dev_regs_backup *dr_backup; + + /** Power Down Enable */ + uint32_t power_down; + + /** ADP support Enable */ + uint32_t adp_enable; + + /** ADP structure object */ + dwc_otg_adp_t adp; + + /** hibernation/suspend flag */ + int hibernation_suspend; + + /** Device mode extended hibernation flag */ + int xhib; + + /** OTG revision supported */ + uint32_t otg_ver; + + /** OTG status flag used for HNP polling */ + uint8_t otg_sts; + + /** Pointer to either hcd->lock or pcd->lock */ + dwc_spinlock_t *lock; + + /** Start predict NextEP based on Learning Queue if equal 1, + * also used as counter of disabled NP IN EP's */ + uint8_t start_predict; + + /** NextEp sequence, including EP0: nextep_seq[] = EP if non-periodic and + * active, 0xff otherwise */ + uint8_t nextep_seq[MAX_EPS_CHANNELS]; + + /** Index of fisrt EP in nextep_seq array which should be re-enabled **/ + uint8_t first_in_nextep_seq; + + /** Frame number while entering to ISR - needed for ISOCs **/ + uint32_t frame_num; + + /** Flag to not perform ADP probing if IDSTS event happened */ + uint8_t stop_adpprb; + +}; + +#ifdef OTGDEBUG +/* + * This function is called when transfer is timed out. + */ +extern _LONG_CALL_ void hc_xfer_timeout(void *ptr); +#endif + +/* + * This function is called when transfer is timed out on endpoint. + */ +extern _LONG_CALL_ void ep_xfer_timeout(void *ptr); + +/* + * The following functions are functions for works + * using during handling some interrupts + */ +extern _LONG_CALL_ void w_conn_id_status_change(void *p); + +extern _LONG_CALL_ void w_wakeup_detected(void *p); + +/** Saves global register values into system memory. */ +extern _LONG_CALL_ int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if); +/** Saves device register values into system memory. */ +extern _LONG_CALL_ int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if); +/** Saves host register values into system memory. */ +extern _LONG_CALL_ int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if); +/** Restore global register values. */ +extern _LONG_CALL_ int dwc_otg_restore_global_regs(dwc_otg_core_if_t * core_if); +/** Restore host register values. */ +extern _LONG_CALL_ int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset); +/** Restore device register values. */ +extern _LONG_CALL_ int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, + int rem_wakeup); +extern _LONG_CALL_ int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, + int is_host); + +extern _LONG_CALL_ int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if, + int restore_mode, int reset); +extern _LONG_CALL_ int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if, + int rem_wakeup, int reset); + +/* + * The following functions support initialization of the CIL driver component + * and the DWC_otg controller. + */ +extern _LONG_CALL_ void dwc_otg_core_host_init(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_core_dev_init(dwc_otg_core_if_t * _core_if); + +/** @name Device CIL Functions + * The following functions support managing the DWC_otg controller in device + * mode. + */ +/**@{*/ +extern _LONG_CALL_ void dwc_otg_wakeup(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_read_setup_packet(dwc_otg_core_if_t * _core_if, + uint32_t * _dest); +extern _LONG_CALL_ uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_ep0_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_activate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_deactivate(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_write_packet(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep, int _dma); +extern _LONG_CALL_ void dwc_otg_ep_set_stall(dwc_otg_core_if_t * _core_if, dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * _core_if, + dwc_ep_t * _ep); +extern _LONG_CALL_ void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * _core_if); + +#ifdef DWC_EN_ISOC +extern _LONG_CALL_ void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if, + dwc_ep_t * ep); +extern _LONG_CALL_ void dwc_otg_iso_ep_start_buf_transfer(dwc_otg_core_if_t * core_if, + dwc_ep_t * ep); +#endif /* DWC_EN_ISOC */ +/**@}*/ + +/** @name Host CIL Functions + * The following functions support managing the DWC_otg controller in host + * mode. + */ +/**@{*/ +extern _LONG_CALL_ void dwc_otg_hc_init(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); +extern _LONG_CALL_ void dwc_otg_hc_halt(dwc_otg_core_if_t * _core_if, + dwc_hc_t * _hc, dwc_otg_halt_status_e _halt_status); +extern _LONG_CALL_ void dwc_otg_hc_cleanup(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); +extern _LONG_CALL_ void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * _core_if, + dwc_hc_t * _hc); +extern _LONG_CALL_ int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * _core_if, + dwc_hc_t * _hc); +extern _LONG_CALL_ void dwc_otg_hc_do_ping(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc); +extern _LONG_CALL_ void dwc_otg_hc_write_packet(dwc_otg_core_if_t * _core_if, + dwc_hc_t * _hc); +extern _LONG_CALL_ void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * _core_if); + +extern _LONG_CALL_ void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, + dwc_hc_t * hc); + +extern _LONG_CALL_ uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ int dwc_otg_check_haps_status(dwc_otg_core_if_t * core_if); + +/* Macro used to clear one channel interrupt */ +#define clear_hc_int(_hc_regs_, _intr_) \ +do { \ + hcint_data_t hcint_clear = {.d32 = 0}; \ + hcint_clear.b._intr_ = 1; \ + DWC_WRITE_REG32(&(_hc_regs_)->hcint, hcint_clear.d32); \ +} while (0) + +/* + * Macro used to disable one channel interrupt. Channel interrupts are + * disabled when the channel is halted or released by the interrupt handler. + * There is no need to handle further interrupts of that type until the + * channel is re-assigned. In fact, subsequent handling may cause crashes + * because the channel structures are cleaned up when the channel is released. + */ +#define disable_hc_int(_hc_regs_, _intr_) \ +do { \ + hcintmsk_data_t hcintmsk = {.d32 = 0}; \ + hcintmsk.b._intr_ = 1; \ + DWC_MODIFY_REG32(&(_hc_regs_)->hcintmsk, hcintmsk.d32, 0); \ +} while (0) + +/** + * This function Reads HPRT0 in preparation to modify. It keeps the + * WC bits 0 so that if they are read as 1, they won't clear when you + * write it back +*/ + +extern _LONG_CALL_ uint32_t dwc_otg_read_hprt0(dwc_otg_core_if_t * _core_if); + +/**@}*/ + +/** @name Common CIL Functions + * The following functions support managing the DWC_otg controller in either + * device or host mode. + */ +/**@{*/ + +extern _LONG_CALL_ void dwc_otg_read_packet(dwc_otg_core_if_t * core_if, + uint8_t * dest, uint16_t bytes); + +extern _LONG_CALL_ void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * _core_if, const int _num); +extern _LONG_CALL_ void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_core_reset(dwc_otg_core_if_t * _core_if); + +/** + * This function returns the Core Interrupt register. + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_core_intr(dwc_otg_core_if_t * core_if); + +/** + * This function returns the OTG Interrupt register. + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_otg_intr(dwc_otg_core_if_t * core_if); + +/** + * This function reads the Device All Endpoints Interrupt register and + * returns the IN endpoint interrupt bits. + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_dev_all_in_ep_intr(dwc_otg_core_if_t * + core_if); +/** + * This function reads the Device All Endpoints Interrupt register and + * returns the OUT endpoint interrupt bits. + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_dev_all_out_ep_intr(dwc_otg_core_if_t * + core_if); + +/** + * This function returns the Device IN EP Interrupt register + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_dev_in_ep_intr(dwc_otg_core_if_t * core_if, + dwc_ep_t * ep); +/** + * This function returns the Device OUT EP Interrupt register + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_dev_out_ep_intr(dwc_otg_core_if_t * + _core_if, dwc_ep_t * _ep); +/** + * This function returns the Host All Channel Interrupt register + */ +extern _LONG_CALL_ uint32_t dwc_otg_read_host_all_channels_intr(dwc_otg_core_if_t * + _core_if); + +extern _LONG_CALL_ uint32_t dwc_otg_read_host_channel_intr(dwc_otg_core_if_t * + _core_if, dwc_hc_t * _hc); + +/** + * This function returns the mode of the operation, host or device. + * + * @return 0 - Device Mode, 1 - Host Mode + */ +extern _LONG_CALL_ uint32_t dwc_otg_mode(dwc_otg_core_if_t * _core_if); + +/**@}*/ + +/** + * DWC_otg CIL callback structure. This structure allows the HCD and + * PCD to register functions used for starting and stopping the PCD + * and HCD for role change on for a DRD. + */ +typedef struct dwc_otg_cil_callbacks { + /** Start function for role change */ + int (*start) (void *_p); + /** Stop Function for role change */ + int (*stop) (void *_p); + /** Disconnect Function for role change */ + int (*disconnect) (void *_p); + /** Resume/Remote wakeup Function */ + int (*resume_wakeup) (void *_p); + /** Suspend function */ + int (*suspend) (void *_p); + /** Session Start (SRP) */ + int (*session_start) (void *_p); +#ifdef CONFIG_USB_DWC_OTG_LPM + /** Sleep (switch to L0 state) */ + int (*sleep) (void *_p); +#endif + /** Pointer passed to start() and stop() */ + void *p; +} dwc_otg_cil_callbacks_t; + +extern _LONG_CALL_ void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * _core_if, + dwc_otg_cil_callbacks_t * _cb, + void *_p); +extern _LONG_CALL_ void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * _core_if, + dwc_otg_cil_callbacks_t * _cb, + void *_p); + +extern _LONG_CALL_ void dwc_otg_initiate_srp(void * core_if); + +////////////////////////////////////////////////////////////////////// +/** Start the HCD. Helper function for using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_start(dwc_otg_core_if_t * core_if); + +/** Stop the HCD. Helper function for using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_stop(dwc_otg_core_if_t * core_if); + +/** Disconnect the HCD. Helper function for using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_disconnect(dwc_otg_core_if_t * core_if); + +/** Inform the HCD the a New Session has begun. Helper function for + * using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_session_start(dwc_otg_core_if_t * core_if); + +#ifdef CONFIG_USB_DWC_OTG_LPM +/** + * Inform the HCD about LPM sleep. + * Helper function for using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_sleep(dwc_otg_core_if_t * core_if); +#endif + +/** Resume the HCD. Helper function for using the HCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_hcd_resume(dwc_otg_core_if_t * core_if); + +/** Start the PCD. Helper function for using the PCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_pcd_start(dwc_otg_core_if_t * core_if); + +/** Stop the PCD. Helper function for using the PCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_pcd_stop(dwc_otg_core_if_t * core_if); + +/** Suspend the PCD. Helper function for using the PCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_pcd_suspend(dwc_otg_core_if_t * core_if); + +/** Resume the PCD. Helper function for using the PCD callbacks. + * + * @param core_if Programming view of DWC_otg controller. + */ +extern _LONG_CALL_ void cil_pcd_resume(dwc_otg_core_if_t * core_if); + +////////////////////////////////////////////////////////////////////// + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_common.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_common.h new file mode 100644 index 0000000..934afc7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_common.h @@ -0,0 +1,82 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "basic_types.h" +#include +//#include "va_list.h" +#include + +#include "diag.h" +#include "dwc_otg_dbg.h" +#include "dwc_os.h" + + +typedef struct _RAM_OTG_FUNCTION_TABLE_ { + VOID* (*RamMemSet) (void *dest, int byte, SIZE_T size); + VOID* (*RamMemCpy) (void *dest, void const *src, SIZE_T size); + int (*RamMemCmp) (void const*m1, void const *m2, SIZE_T size); + int (*RamStrnCmp) (const char *s1, const char *s2, SIZE_T size); + int (*RamStrCmp) (const char *s1, const char *s2); + SIZE_T (*RamStrLen) (char const *str); + char* (*RamStrCpy) (char *to, char const *from); + char* (*RamStrDup) (char const *str); + int (*RamAtoi) (const char *str, int32_t *value); + int (*RamAtoui) (const char *str, uint32_t *value); + int (*RamVsnPrintf) (char *str, int size, const char *format, ...); + u32 (*RamSPrintf) (u8 *buf, const char *fmt, ...); + int (*RamSnPrintf) (char *dst, int count, const char * src, ...); + u8* (*RamZmalloc) (u32 sz); + u8* (*RamZmallocAtomic) (u32 sz); + VOID (*RamMfree) (u8 *pbuf, u32 sz); + dwc_spinlock_t* (*RamSpinlockAlloc) (void); + VOID (*RamSpinlockFree) (dwc_spinlock_t *lock); + VOID (*RamSpinlock) (dwc_spinlock_t *lock); + VOID (*RamSpinUnlock) (dwc_spinlock_t *lock); + VOID (*RamSpinIrqSave) (dwc_spinlock_t *lock, dwc_irqflags_t *flags); + VOID (*RamSpinIrqRestore) (dwc_spinlock_t *lock, dwc_irqflags_t flags); + dwc_mutex_t*(*RamMutexAlloc) (void); + VOID (*RamMutexFree) (dwc_mutex_t *mutex); + VOID (*RamMutexLock) (dwc_mutex_t *mutex); + int (*RamMutexTryLock) (dwc_mutex_t *mutex); + VOID (*RamMutexUnLock) (dwc_mutex_t *mutex); + uint32_t(*RamUDelay) (uint32_t usecs); + void (*RamMSleep) (uint32_t msecs); + VOID (*timer_callback) (unsigned long data); + dwc_timer_t *(*RamTimerAlloc) (char *name, dwc_timer_callback_t cb, void *data); + VOID (*RamTimerFree) (dwc_timer_t *timer); + VOID (*RamTimerSche) (dwc_timer_t *timer, uint32_t time_ms); + VOID (*RamTimerCancel) (dwc_timer_t *timer); + VOID (*RamEnterCritical) (void); + VOID (*RamExitCritical) (void); +}RAM_OTG_FUNCTION_TABLE, *PRAM_OTG_FUNCTION_TABLE; + + + +// Global Variable +extern RAM_OTG_FUNCTION_TABLE gRamOTGFunTbl; + +// Funtion Prototype +// ROM +_LONG_CALL_ void dwc_otg_wrapper_reset(IN VOID); +_LONG_CALL_ void dwc_otg_wrapper_init_boot(IN VOID); +_LONG_CALL_ void dwc_otg_power_init(IN VOID); + +_LONG_CALL_ VOID RtlInitListhead_Otg(IN _LIST *list); +_LONG_CALL_ u32 RtlIsListEmpty_Otg(IN _LIST *phead); +_LONG_CALL_ VOID RtlListInsertHead_Otg(IN _LIST *plist,IN _LIST *phead); +_LONG_CALL_ VOID RtlListInsertTail_Otg(IN _LIST *plist,IN _LIST *phead); +_LONG_CALL_ _LIST *RtlListGetNext_Otg(IN _LIST *plist); +_LONG_CALL_ VOID RtlListDelete_Otg(IN _LIST *plist); + +extern _LONG_CALL_ char *DWC_STRDUP_ROM(char const *str); +extern _LONG_CALL_ int DWC_ATOI_ROM(const char *str, int32_t *value); +extern _LONG_CALL_ int DWC_ATOUI_ROM(const char *str, uint32_t *value); +// RAM +extern void dwc_otg_wrapper_init(IN VOID); + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_core_if.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_core_if.h new file mode 100644 index 0000000..1589dfb --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_core_if.h @@ -0,0 +1,746 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_core_if.h $ + * $Revision: #15 $ + * $Date: 2012/12/10 $ + * $Change: 2123206 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ +#if !defined(__DWC_CORE_IF_H__) +#define __DWC_CORE_IF_H__ + +#include "dwc_os.h" + +/** @file + * This file defines DWC_OTG Core API + */ + +struct dwc_otg_core_if; +typedef struct dwc_otg_core_if dwc_otg_core_if_t; + +/** Maximum number of Periodic FIFOs */ +#define MAX_PERIO_FIFOS 15 +/** Maximum number of Periodic FIFOs */ +#define MAX_TX_FIFOS 15 + +/** Maximum number of Endpoints/HostChannels */ +#define MAX_EPS_CHANNELS 8 + +extern _LONG_CALL_ dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * _reg_base_addr, int mode); +extern _LONG_CALL_ void dwc_otg_core_init(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_cil_remove(dwc_otg_core_if_t * _core_if); + +extern _LONG_CALL_ void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * _core_if); + +extern _LONG_CALL_ uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if); + +extern _LONG_CALL_ uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if); + +/** This function should be called on every hardware interrupt. */ +extern _LONG_CALL_ int32_t dwc_otg_handle_common_intr(void *otg_dev); + +/** @name OTG Core Parameters */ +/** @{ */ + +/** + * Specifies the OTG capabilities. The driver will automatically + * detect the value for this parameter if none is specified. + * 0 - HNP and SRP capable (default) + * 1 - SRP Only capable + * 2 - No HNP/SRP capable + */ +extern _LONG_CALL_ int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if); +#define DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE 0 +#define DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE 1 +#define DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE 2 +#define dwc_param_otg_cap_default DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE + +extern _LONG_CALL_ int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if); +#define dwc_param_opt_default 1 + +/** + * Specifies whether to use slave or DMA mode for accessing the data + * FIFOs. The driver will automatically detect the value for this + * parameter if none is specified. + * 0 - Slave + * 1 - DMA (default, if available) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_dma_enable_default 1 + +/** + * When DMA mode is enabled specifies whether to use + * address DMA or DMA Descritor mode for accessing the data + * FIFOs in device mode. The driver will automatically detect + * the value for this parameter if none is specified. + * 0 - address DMA + * 1 - DMA Descriptor(default, if available) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_dma_desc_enable_default 1 + +/** The DMA Burst size (applicable only for External DMA + * Mode). 1, 4, 8 16, 32, 64, 128, 256 (default 32) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if); +#define dwc_param_dma_burst_size_default 32 + +/** + * Specifies the maximum speed of operation in host and device mode. + * The actual speed depends on the speed of the attached device and + * the value of phy_type. The actual speed depends on the speed of the + * attached device. + * 0 - High Speed (default) + * 1 - Full Speed + */ +extern _LONG_CALL_ int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if); +#define dwc_param_speed_default 0 +#define DWC_SPEED_PARAM_HIGH 0 +#define DWC_SPEED_PARAM_FULL 1 + +/** Specifies whether low power mode is supported when attached + * to a Full Speed or Low Speed device in host mode. + * 0 - Don't support low power mode (default) + * 1 - Support low power mode + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * + core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t + * core_if); +#define dwc_param_host_support_fs_ls_low_power_default 0 + +/** Specifies the PHY clock rate in low power mode when connected to a + * Low Speed device in host mode. This parameter is applicable only if + * HOST_SUPPORT_FS_LS_LOW_POWER is enabled. If PHY_TYPE is set to FS + * then defaults to 6 MHZ otherwise 48 MHZ. + * + * 0 - 48 MHz + * 1 - 6 MHz + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * + core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * + core_if); +#define dwc_param_host_ls_low_power_phy_clk_default 0 +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ 0 +#define DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ 1 + +/** + * 0 - Use cC FIFO size parameters + * 1 - Allow dynamic FIFO sizing (default) + */ +extern _LONG_CALL_ int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * + core_if); +#define dwc_param_enable_dynamic_fifo_default 1 + +/** Total number of 4-byte words in the data FIFO memory. This + * memory includes the Rx FIFO, non-periodic Tx FIFO, and periodic + * Tx FIFOs. + * 32 to 32768 (default 8192) + * Note: The total FIFO memory depth in the FPGA configuration is 8192. + */ +extern _LONG_CALL_ int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if); +#define dwc_param_data_fifo_size_default 8192 + +/** Number of 4-byte words in the Rx FIFO in device mode when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1064) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if); +#define dwc_param_dev_rx_fifo_size_default 1064 + +/** Number of 4-byte words in the non-periodic Tx FIFO in device mode + * when dynamic FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * + core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * + core_if); +#define dwc_param_dev_nperio_tx_fifo_size_default 1024 + +/** Number of 4-byte words in each of the periodic Tx FIFOs in device + * mode when dynamic FIFO sizing is enabled. + * 4 to 768 (default 256) + */ +extern _LONG_CALL_ int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if, + int32_t val, int fifo_num); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * + core_if, int fifo_num); +#define dwc_param_dev_perio_tx_fifo_size_default 256 + +/** Number of 4-byte words in the Rx FIFO in host mode when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if); +#define dwc_param_host_rx_fifo_size_default 1024 + +/** Number of 4-byte words in the non-periodic Tx FIFO in host mode + * when Dynamic FIFO sizing is enabled in the core. + * 16 to 32768 (default 1024) + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * + core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * + core_if); +#define dwc_param_host_nperio_tx_fifo_size_default 1024 + +/** Number of 4-byte words in the host periodic Tx FIFO when dynamic + * FIFO sizing is enabled. + * 16 to 32768 (default 1024) + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * + core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * + core_if); +#define dwc_param_host_perio_tx_fifo_size_default 1024 + +/** The maximum transfer size supported in bytes. + * 2047 to 65,535 (default 65,535) + */ +extern _LONG_CALL_ int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if); +#define dwc_param_max_transfer_size_default 65535 + +/** The maximum number of packets in a transfer. + * 15 to 511 (default 511) + */ +extern _LONG_CALL_ int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if); +#define dwc_param_max_packet_count_default 511 + +/** The number of host channel registers to use. + * 1 to 16 (default 12) + * Note: The FPGA configuration supports a maximum of 12 host channels. + */ +extern _LONG_CALL_ int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if); +#define dwc_param_host_channels_default 12 + +/** The number of endpoints in addition to EP0 available for device + * mode operations. + * 1 to 15 (default 6 IN and OUT) + * Note: The FPGA configuration supports a maximum of 6 IN and OUT + * endpoints in addition to EP0. + */ +extern _LONG_CALL_ int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if); +#define dwc_param_dev_endpoints_default 6 + +/** + * Specifies the type of PHY interface to use. By default, the driver + * will automatically detect the phy_type. + * + * 0 - Full Speed PHY + * 1 - UTMI+ (default) + * 2 - ULPI + */ +extern _LONG_CALL_ int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if); +#define DWC_PHY_TYPE_PARAM_FS 0 +#define DWC_PHY_TYPE_PARAM_UTMI 1 +#define DWC_PHY_TYPE_PARAM_ULPI 2 +#define dwc_param_phy_type_default DWC_PHY_TYPE_PARAM_UTMI + +/** + * Specifies the UTMI+ Data Width. This parameter is + * applicable for a PHY_TYPE of UTMI+ or ULPI. (For a ULPI + * PHY_TYPE, this parameter indicates the data width between + * the MAC and the ULPI Wrapper.) Also, this parameter is + * applicable only if the OTG_HSPHY_WIDTH cC parameter was set + * to "8 and 16 bits", meaning that the core has been + * configured to work at either data path width. + * + * 8 or 16 bits (default 16) + */ +extern _LONG_CALL_ int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if); +#define dwc_param_phy_utmi_width_default 16 + +/** + * Specifies whether the ULPI operates at double or single + * data rate. This parameter is only applicable if PHY_TYPE is + * ULPI. + * + * 0 - single data rate ULPI interface with 8 bit wide data + * bus (default) + * 1 - double data rate ULPI interface with 4 bit wide data + * bus + */ +extern _LONG_CALL_ int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if); +#define dwc_param_phy_ulpi_ddr_default 0 + +/** + * Specifies whether to use the internal or external supply to + * drive the vbus with a ULPI phy. + */ +extern _LONG_CALL_ int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if); +#define DWC_PHY_ULPI_INTERNAL_VBUS 0 +#define DWC_PHY_ULPI_EXTERNAL_VBUS 1 +#define dwc_param_phy_ulpi_ext_vbus_default DWC_PHY_ULPI_INTERNAL_VBUS + +/** + * Specifies whether to use the I2Cinterface for full speed PHY. This + * parameter is only applicable if PHY_TYPE is FS. + * 0 - No (default) + * 1 - Yes + */ +extern _LONG_CALL_ int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_i2c_enable_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if); +#define dwc_param_ulpi_fs_ls_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if); +#define dwc_param_ts_dline_default 0 + +/** + * Specifies whether dedicated transmit FIFOs are + * enabled for non periodic IN endpoints in device mode + * 0 - No + * 1 - Yes + */ +extern _LONG_CALL_ int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * + core_if); +#define dwc_param_en_multiple_tx_fifo_default 1 + +/** Number of 4-byte words in each of the Tx FIFOs in device + * mode when dynamic FIFO sizing is enabled. + * 4 to 768 (default 256) + */ +//extern int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, +// int fifo_num, int32_t val); +extern _LONG_CALL_ int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val, + int fifo_num); + +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, + int fifo_num); +#define dwc_param_dev_tx_fifo_size_default 256 + +/** Thresholding enable flag- + * bit 0 - enable non-ISO Tx thresholding + * bit 1 - enable ISO Tx thresholding + * bit 2 - enable Rx thresholding + */ +extern _LONG_CALL_ int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_thr_ctl(dwc_otg_core_if_t * core_if, int fifo_num); +#define dwc_param_thr_ctl_default 0 + +/** Thresholding length for Tx + * FIFOs in 32 bit DWORDs + */ +extern _LONG_CALL_ int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_tx_thr_length(dwc_otg_core_if_t * core_if); +#define dwc_param_tx_thr_length_default 64 + +/** Thresholding length for Rx + * FIFOs in 32 bit DWORDs + */ +extern _LONG_CALL_ int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_rx_thr_length(dwc_otg_core_if_t * core_if); +#define dwc_param_rx_thr_length_default 64 + +/** + * Specifies whether LPM (Link Power Management) support is enabled + */ +extern _LONG_CALL_ int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_lpm_enable_default 1 + +/** + * Specifies whether LPM Errata (Link Power Management) support is enabled + */ +extern _LONG_CALL_ int dwc_otg_set_param_besl_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_besl_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_besl_enable_default 0 + +/** + * Specifies baseline_besl default value + */ +extern _LONG_CALL_ int dwc_otg_set_param_baseline_besl(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_baseline_besl(dwc_otg_core_if_t * core_if); +#define dwc_param_baseline_besl_default 0 + +/** + * Specifies deep_besl default value + */ +extern _LONG_CALL_ int dwc_otg_set_param_deep_besl(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_deep_besl(dwc_otg_core_if_t * core_if); +#define dwc_param_deep_besl_default 15 + +/** + * Specifies whether PTI enhancement is enabled + */ +extern _LONG_CALL_ int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_pti_enable_default 0 + +/** + * Specifies whether MPI enhancement is enabled + */ +extern _LONG_CALL_ int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_mpi_enable_default 0 + +/** + * Specifies whether ADP capability is enabled + */ +extern _LONG_CALL_ int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if); +#define dwc_param_adp_enable_default 0 + +/** + * Specifies whether IC_USB capability is enabled + */ + +extern _LONG_CALL_ int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if); +#define dwc_param_ic_usb_cap_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if); +#define dwc_param_ahb_thr_ratio_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if); +#define dwc_param_power_down_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if); +#define dwc_param_reload_ctl_default 0 + +extern int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if); +#define dwc_param_dev_out_nak_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if); +#define dwc_param_cont_on_bna_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, + int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if); +#define dwc_param_ahb_single_default 0 + +extern _LONG_CALL_ int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val); +extern _LONG_CALL_ int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if); +#define dwc_param_otg_ver_default 0 + +/** @} */ + +/** @name Access to registers and bit-fields */ + +/** + * Dump core registers and SPRAM + */ +extern _LONG_CALL_ void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_dump_spram(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_dump_host_registers(dwc_otg_core_if_t * _core_if); +extern _LONG_CALL_ void dwc_otg_dump_global_registers(dwc_otg_core_if_t * _core_if); + +/** + * Get host negotiation status. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if); + +/** + * Get srp status + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if); + +/** + * Set hnpreq bit in the GOTGCTL register. + */ +extern _LONG_CALL_ void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get Content of SNPSID register. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if); + +/** + * Get current mode. + * Returns 0 if in device mode, and 1 if in host mode. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if); + +/** + * Get value of hnpcapable field in the GUSBCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if); +/** + * Set value of hnpcapable field in the GUSBCFG register + */ +extern _LONG_CALL_ void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of srpcapable field in the GUSBCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if); +/** + * Set value of srpcapable field in the GUSBCFG register + */ +extern _LONG_CALL_ void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of devspeed field in the DCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if); +/** + * Set value of devspeed field in the DCFG register + */ +extern void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get the value of busconnected field from the HPRT0 register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if); + +/** + * Gets the device enumeration Speed. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if); + +/** + * Get value of prtpwr field from the HPRT0 register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if); + +/** + * Get value of flag indicating core state - hibernated or not + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if); + +/** + * Set value of prtpwr field from the HPRT0 register + */ +extern _LONG_CALL_ void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of prtsusp field from the HPRT0 regsiter + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if); +/** + * Set value of prtpwr field from the HPRT0 register + */ +extern _LONG_CALL_ void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of ModeChTimEn field from the HCFG regsiter + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if); +/** + * Set value of ModeChTimEn field from the HCFG regsiter + */ +extern _LONG_CALL_ void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of Fram Interval field from the HFIR regsiter + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if); +/** + * Set value of Frame Interval field from the HFIR regsiter + */ +extern _LONG_CALL_ void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Set value of prtres field from the HPRT0 register + *FIXME Remove? + */ +extern _LONG_CALL_ void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of rmtwkupsig bit in DCTL register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if); + +/** + * Get value of besl_reject bit in DCTL register + */ + +extern _LONG_CALL_ uint32_t dwc_otg_get_beslreject(dwc_otg_core_if_t * core_if); + +/** + * Set value of besl_reject bit in DCTL register + */ + +extern _LONG_CALL_ void dwc_otg_set_beslreject(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of prt_sleep_sts field from the GLPMCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if); + +/** + * Get value of rem_wkup_en field from the GLPMCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if); + +/** + * Get value of appl_resp field from the GLPMCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if); +/** + * Set value of appl_resp field from the GLPMCFG register + */ +extern _LONG_CALL_ void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of hsic_connect field from the GLPMCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if); +/** + * Set value of hsic_connect field from the GLPMCFG register + */ +extern _LONG_CALL_ void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * Get value of inv_sel_hsic field from the GLPMCFG register. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if); +/** + * Set value of inv_sel_hsic field from the GLPMFG register. + */ +extern _LONG_CALL_ void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val); +/** + * Set value of hird_thresh field from the GLPMFG register. + */ +extern _LONG_CALL_ void dwc_otg_set_hirdthresh(dwc_otg_core_if_t * core_if, uint32_t val); +/** + * Get value of hird_thresh field from the GLPMFG register. + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hirdthresh(dwc_otg_core_if_t * core_if); + + +/* + * Some functions for accessing registers + */ + +/** + * GOTGCTL register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GUSBCFG register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GRXFSIZ register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GNPTXFSIZ register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val); + +extern _LONG_CALL_ uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GGPIO register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GUID register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * HPRT0 register + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if); +extern _LONG_CALL_ void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val); + +/** + * GHPTXFSIZE + */ +extern _LONG_CALL_ uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if); + +/** @} */ + +#endif /* __DWC_CORE_IF_H__ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_dbg.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_dbg.h new file mode 100644 index 0000000..69cf3c3 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_dbg.h @@ -0,0 +1,114 @@ +/* ========================================================================== + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#ifndef __DWC_OTG_DBG_H__ +#define __DWC_OTG_DBG_H__ +#include "section_config.h" + +//#define OTGDEBUG 1 +#define VERBOSE 1 + +/** @file + * This file defines debug levels. + * Debugging support vanishes in non-debug builds. + */ + +/** + * The Debug Level bit-mask variable. + */ +extern uint32_t g_dbg_lvl; +/** + * Set the Debug Level variable. + */ +extern _LONG_CALL_ uint32_t SET_DEBUG_LEVEL(const uint32_t new); + +/** When debug level has the DBG_CIL bit set, display CIL Debug messages. */ +#define DBG_CIL (0x2) +/** When debug level has the DBG_CILV bit set, display CIL Verbose debug + * messages */ +#define DBG_CILV (0x20) +/** When debug level has the DBG_PCD bit set, display PCD (Device) debug + * messages */ +#define DBG_PCD (0x4) +/** When debug level has the DBG_PCDV set, display PCD (Device) Verbose debug + * messages */ +#define DBG_PCDV (0x40) +/** When debug level has the DBG_HCD bit set, display Host debug messages */ +#define DBG_HCD (0x8) +/** When debug level has the DBG_HCDV bit set, display Verbose Host debug + * messages */ +#define DBG_HCDV (0x80) +/** When debug level has the DBG_HCD_URB bit set, display enqueued URBs in host + * mode. */ +#define DBG_HCD_URB (0x800) + +/** When debug level has any bit set, display debug messages */ +#define DBG_ANY (0xFF) + +/** All debug messages off */ +#define DBG_OFF 0 + +/** Prefix string for DWC_DEBUG print macros. */ +#define USB_DWC "DWC_otg: " + +/** + * Print a debug message when the Global debug level variable contains + * the bit defined in lvl. + * + * @param[in] lvl - Debug level, use one of the DBG_ constants above. + * @param[in] x - like printf + * + * Example:

+ * + * DWC_DEBUGPL( DBG_ANY, "%s(%p)\n", __func__, _reg_base_addr); + * + *
+ * results in:
+ * + * usb-DWC_otg: dwc_otg_cil_init(ca867000) + * + */ +#ifdef OTGDEBUG + +//# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)__DWC_DEBUG(USB_DWC x ); }while(0) +# define DWC_DEBUGPL(lvl, x...) do{ if ((lvl)&g_dbg_lvl)DBG_8195A_OTG(x); }while(0) + +# define DWC_DEBUGP(x...) DWC_DEBUGPL(DBG_ANY, x ) + +# define CHK_DEBUG_LEVEL(level) ((level) & g_dbg_lvl) + +#else + +# define DWC_DEBUGPL(lvl, x...) do{}while(0) +# define DWC_DEBUGP(x...) + +# define CHK_DEBUG_LEVEL(level) (0) + +#endif /*DEBUG*/ +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_driver.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_driver.h new file mode 100644 index 0000000..6469d0d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_driver.h @@ -0,0 +1,124 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_driver.h $ + * $Revision: #19 $ + * $Date: 2010/11/15 $ + * $Change: 1627671 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#ifndef __DWC_OTG_DRIVER_H__ +#define __DWC_OTG_DRIVER_H__ + +/** @file + * This file contains the interface to the Linux driver. + */ +//#include "dwc_otg_os_dep.h" +#include "dwc_otg_core_if.h" +#include "osdep_service.h" + +/* Type declarations */ +struct dwc_otg_pcd; +struct dwc_otg_hcd; + +/** + * This structure is a wrapper that encapsulates the driver components used to + * manage a single DWC_otg controller. + */ +typedef struct dwc_otg_device { + /** Structure containing OS-dependent stuff. KEEP THIS STRUCT AT THE + * VERY BEGINNING OF THE DEVICE STRUCT. OSes such as FreeBSD and NetBSD + * require this. */ + //struct os_dependent os_dep; + /** Base address returned from ioremap() */ + void *base; + uint32_t reg_offset; + /** Pointer to the core interface structure. */ + dwc_otg_core_if_t *core_if; + + /** Pointer to the PCD structure. */ + struct dwc_otg_pcd *pcd; + + /** Pointer to the HCD structure. */ + struct dwc_otg_hcd *hcd; + + /** Flag to indicate whether the common IRQ handler is installed. */ + uint8_t common_irq_installed; + +} dwc_otg_device_t; + +/*We must clear S3C24XX_EINTPEND external interrupt register + * because after clearing in this register trigerred IRQ from + * H/W core in kernel interrupt can be occured again before OTG + * handlers clear all IRQ sources of Core registers because of + * timing latencies and Low Level IRQ Type. + */ +#ifdef CONFIG_MACH_IPMATE +#define S3C2410X_CLEAR_EINTPEND() \ +do { \ + __raw_writel(1UL << 11,S3C24XX_EINTPEND); \ +} while (0) +#else +#define S3C2410X_CLEAR_EINTPEND() do { } while (0) +#endif + + +typedef struct USB_OTG_DRV_ADP { + dwc_otg_device_t *otgdev; + IRQ_HANDLE *pIrqHnd; +#if !TASK_SCHEDULER_DISABLED +#if defined(DWC_WITH_WLAN_OSDEP) + _sema Sema; +#else + _Sema Sema; +#endif +#else + u32 Sema; +#endif +#if !TASK_SCHEDULER_DISABLED +#if defined(DWC_WITH_WLAN_OSDEP) + struct task_struct OTGTask; +#else + xTaskHandle OTGTask; +#endif +#else + u32 OTGTask; +#endif + +}USB_OTG_DRV_ADP,*PUSB_OTG_DRV_ADP; + + + +typedef struct _DWC_OTG_ADAPTER_ { + u32 temp0; + dwc_otg_device_t *otgdev; + u8 TestItem; +}DWC_OTG_ADAPTER, *PDWC_OTG_ADAPTER; +void dwc_otg_disable_irq(IN VOID); +void dwc_otg_enable_irq(IN VOID); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd.h new file mode 100644 index 0000000..b85eebd --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd.h @@ -0,0 +1,743 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd.h $ + * $Revision: #58 $ + * $Date: 2011/09/15 $ + * $Change: 1846647 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ +#if 1//ndef DWC_DEVICE_ONLY +#ifndef __DWC_HCD_H__ +#define __DWC_HCD_H__ + +//#include "dwc_otg_os_dep.h" +#include "usb.h" +#include "dwc_otg_hcd_if.h" +#include "dwc_otg_core_if.h" +#include "dwc_list.h" +#include "dwc_otg_cil.h" +#undef DWC_HS_ELECT_TST +/** + * @file + * + * This file contains the structures, constants, and interfaces for + * the Host Contoller Driver (HCD). + * + * The Host Controller Driver (HCD) is responsible for translating requests + * from the USB Driver into the appropriate actions on the DWC_otg controller. + * It isolates the USBD from the specifics of the controller by providing an + * API to the USBD. + */ + +struct dwc_otg_hcd_pipe_info { + uint8_t dev_addr; + uint8_t ep_num; + uint8_t pipe_type; + uint8_t pipe_dir; + uint16_t mps; +}; + +struct dwc_otg_hcd_iso_packet_desc { + uint32_t offset; + uint32_t length; + uint32_t actual_length; + uint32_t status; +}; + +struct dwc_otg_qtd; + +struct dwc_otg_hcd_urb { + void *priv; + struct dwc_otg_qtd *qtd; + void *buf; + dwc_dma_t dma; + void *setup_packet; + dwc_dma_t setup_dma; + uint32_t length; + uint32_t actual_length; + uint32_t status; + uint32_t error_count; + uint32_t packet_count; + uint32_t flags; + uint16_t interval; + struct dwc_otg_hcd_pipe_info pipe_info; + struct dwc_otg_hcd_iso_packet_desc iso_descs[0]; +}; + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_get_ep_num(struct dwc_otg_hcd_pipe_info *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_get_pipe_type(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint16_t dwc_otg_hcd_get_mps(struct dwc_otg_hcd_pipe_info *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_get_dev_addr(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_isoc(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_int(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_bulk(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_control(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_in(struct dwc_otg_hcd_pipe_info *pipe); + +extern _LONG_CALL_ +uint8_t dwc_otg_hcd_is_pipe_out(struct dwc_otg_hcd_pipe_info + *pipe); + +extern _LONG_CALL_ +void dwc_otg_hcd_fill_pipe(struct dwc_otg_hcd_pipe_info *pipe, + uint8_t devaddr, uint8_t ep_num, + uint8_t pipe_type, uint8_t pipe_dir, + uint16_t mps); + +/** + * Phases for control transfers. + */ +typedef enum dwc_otg_control_phase { + DWC_OTG_CONTROL_SETUP, + DWC_OTG_CONTROL_DATA, + DWC_OTG_CONTROL_STATUS +} dwc_otg_control_phase_e; + +/** Transaction types. */ +typedef enum dwc_otg_transaction_type { + DWC_OTG_TRANSACTION_NONE, + DWC_OTG_TRANSACTION_PERIODIC, + DWC_OTG_TRANSACTION_NON_PERIODIC, + DWC_OTG_TRANSACTION_ALL +} dwc_otg_transaction_type_e; + +struct dwc_otg_qh; + +/** + * A Queue Transfer Descriptor (QTD) holds the state of a bulk, control, + * interrupt, or isochronous transfer. A single QTD is created for each URB + * (of one of these types) submitted to the HCD. The transfer associated with + * a QTD may require one or multiple transactions. + * + * A QTD is linked to a Queue Head, which is entered in either the + * non-periodic or periodic schedule for execution. When a QTD is chosen for + * execution, some or all of its transactions may be executed. After + * execution, the state of the QTD is updated. The QTD may be retired if all + * its transactions are complete or if an error occurred. Otherwise, it + * remains in the schedule so more transactions can be executed later. + */ +typedef struct dwc_otg_qtd { + /** + * Determines the PID of the next data packet for the data phase of + * control transfers. Ignored for other transfer types.
+ * One of the following values: + * - DWC_OTG_HC_PID_DATA0 + * - DWC_OTG_HC_PID_DATA1 + */ + uint8_t data_toggle; + + /** Current phase for control transfers (Setup, Data, or Status). */ + dwc_otg_control_phase_e control_phase; + + /** Keep track of the current split type + * for FS/LS endpoints on a HS Hub */ + uint8_t complete_split; + + /** How many bytes transferred during SSPLIT OUT */ + uint32_t ssplit_out_xfer_count; + + /** + * Holds the number of bus errors that have occurred for a transaction + * within this transfer. + */ + uint8_t error_count; + + /** + * Index of the next frame descriptor for an isochronous transfer. A + * frame descriptor describes the buffer position and length of the + * data to be transferred in the next scheduled (micro)frame of an + * isochronous transfer. It also holds status for that transaction. + * The frame index starts at 0. + */ + uint16_t isoc_frame_index; + + /** Position of the ISOC split on full/low speed */ + uint8_t isoc_split_pos; + + /** Position of the ISOC split in the buffer for the current frame */ + uint16_t isoc_split_offset; + + /** URB for this transfer */ + struct dwc_otg_hcd_urb *urb; + + struct dwc_otg_qh *qh; + + /** This list of QTDs */ + DWC_CIRCLEQ_ENTRY(dwc_otg_qtd) qtd_list_entry; + + /** Indicates if this QTD is currently processed by HW. */ + uint8_t in_process; + + /** Number of DMA descriptors for this QTD */ + uint8_t n_desc; + + /** + * Last activated frame(packet) index. + * Used in Descriptor DMA mode only. + */ + uint16_t isoc_frame_index_last; + +} dwc_otg_qtd_t; + +DWC_CIRCLEQ_HEAD(dwc_otg_qtd_list, dwc_otg_qtd); + +/** + * A Queue Head (QH) holds the static characteristics of an endpoint and + * maintains a list of transfers (QTDs) for that endpoint. A QH structure may + * be entered in either the non-periodic or periodic schedule. + */ +typedef struct dwc_otg_qh { + /** + * Endpoint type. + * One of the following values: + * - UE_CONTROL + * - UE_BULK + * - UE_INTERRUPT + * - UE_ISOCHRONOUS + */ + uint8_t ep_type; + uint8_t ep_is_in; + + /** wMaxPacketSize Field of Endpoint Descriptor. */ + uint16_t maxp; + + /** + * Device speed. + * One of the following values: + * - DWC_OTG_EP_SPEED_LOW + * - DWC_OTG_EP_SPEED_FULL + * - DWC_OTG_EP_SPEED_HIGH + */ + uint8_t dev_speed; + + /** + * Determines the PID of the next data packet for non-control + * transfers. Ignored for control transfers.
+ * One of the following values: + * - DWC_OTG_HC_PID_DATA0 + * - DWC_OTG_HC_PID_DATA1 + */ + uint8_t data_toggle; + + /** Ping state if 1. */ + uint8_t ping_state; + + /** + * List of QTDs for this QH. + */ + struct dwc_otg_qtd_list qtd_list; + + /** Host channel currently processing transfers for this QH. */ + struct dwc_hc *channel; + + /** Full/low speed endpoint on high-speed hub requires split. */ + uint8_t do_split; + + /** @name Periodic schedule information */ + /** @{ */ + + /** Bandwidth in microseconds per (micro)frame. */ + uint16_t usecs; + + /** Interval between transfers in (micro)frames. */ + uint16_t interval; + + /** + * (micro)frame to initialize a periodic transfer. The transfer + * executes in the following (micro)frame. + */ + uint16_t sched_frame; + + /** (micro)frame at which last start split was initialized. */ + uint16_t start_split_frame; + + /** @} */ + + /** + * Used instead of original buffer if + * it(physical address) is not dword-aligned. + */ + uint8_t *dw_align_buf; + dwc_dma_t dw_align_buf_dma; + + /** Entry for QH in either the periodic or non-periodic schedule. */ + dwc_list_link_t qh_list_entry; + + /** @name Descriptor DMA support */ + /** @{ */ + + /** Descriptor List. */ + dwc_otg_host_dma_desc_t *desc_list; + + /** Descriptor List physical address. */ + dwc_dma_t desc_list_dma; + + /** + * Xfer Bytes array. + * Each element corresponds to a descriptor and indicates + * original XferSize size value for the descriptor. + */ + uint32_t *n_bytes; + + /** Actual number of transfer descriptors in a list. */ + uint16_t ntd; + + /** First activated isochronous transfer descriptor index. */ + uint8_t td_first; + /** Last activated isochronous transfer descriptor index. */ + uint8_t td_last; + + /** @} */ + +} dwc_otg_qh_t; + +DWC_CIRCLEQ_HEAD(hc_list, dwc_hc); + +/** + * This structure holds the state of the HCD, including the non-periodic and + * periodic schedules. + */ +struct dwc_otg_hcd { + /** The DWC otg device pointer */ + struct dwc_otg_device *otg_dev; + /** DWC OTG Core Interface Layer */ + dwc_otg_core_if_t *core_if; + + /** Function HCD driver callbacks */ + struct dwc_otg_hcd_function_ops *fops; + + /** Internal DWC HCD Flags */ + volatile union dwc_otg_hcd_internal_flags { + uint32_t d32; + struct { + unsigned port_connect_status_change:1; + unsigned port_connect_status:1; + unsigned port_reset_change:1; + unsigned port_enable_change:1; + unsigned port_suspend_change:1; + unsigned port_over_current_change:1; + unsigned port_l1_change:1; + unsigned reserved:26; + } b; + } flags; + + /** + * Inactive items in the non-periodic schedule. This is a list of + * Queue Heads. Transfers associated with these Queue Heads are not + * currently assigned to a host channel. + */ + dwc_list_link_t non_periodic_sched_inactive; + + /** + * Active items in the non-periodic schedule. This is a list of + * Queue Heads. Transfers associated with these Queue Heads are + * currently assigned to a host channel. + */ + dwc_list_link_t non_periodic_sched_active; + + /** + * Pointer to the next Queue Head to process in the active + * non-periodic schedule. + */ + dwc_list_link_t *non_periodic_qh_ptr; + + /** + * Inactive items in the periodic schedule. This is a list of QHs for + * periodic transfers that are _not_ scheduled for the next frame. + * Each QH in the list has an interval counter that determines when it + * needs to be scheduled for execution. This scheduling mechanism + * allows only a simple calculation for periodic bandwidth used (i.e. + * must assume that all periodic transfers may need to execute in the + * same frame). However, it greatly simplifies scheduling and should + * be sufficient for the vast majority of OTG hosts, which need to + * connect to a small number of peripherals at one time. + * + * Items move from this list to periodic_sched_ready when the QH + * interval counter is 0 at SOF. + */ + dwc_list_link_t periodic_sched_inactive; + + /** + * List of periodic QHs that are ready for execution in the next + * frame, but have not yet been assigned to host channels. + * + * Items move from this list to periodic_sched_assigned as host + * channels become available during the current frame. + */ + dwc_list_link_t periodic_sched_ready; + + /** + * List of periodic QHs to be executed in the next frame that are + * assigned to host channels. + * + * Items move from this list to periodic_sched_queued as the + * transactions for the QH are queued to the DWC_otg controller. + */ + dwc_list_link_t periodic_sched_assigned; + + /** + * List of periodic QHs that have been queued for execution. + * + * Items move from this list to either periodic_sched_inactive or + * periodic_sched_ready when the channel associated with the transfer + * is released. If the interval for the QH is 1, the item moves to + * periodic_sched_ready because it must be rescheduled for the next + * frame. Otherwise, the item moves to periodic_sched_inactive. + */ + dwc_list_link_t periodic_sched_queued; + + /** + * Total bandwidth claimed so far for periodic transfers. This value + * is in microseconds per (micro)frame. The assumption is that all + * periodic transfers may occur in the same (micro)frame. + */ + uint16_t periodic_usecs; + + /** + * Frame number read from the core at SOF. The value ranges from 0 to + * DWC_HFNUM_MAX_FRNUM. + */ + uint16_t frame_number; + + /** + * Count of periodic QHs, if using several eps. For SOF enable/disable. + */ + uint16_t periodic_qh_count; + + /** + * Free host channels in the controller. This is a list of + * dwc_hc_t items. + */ + struct hc_list free_hc_list; + /** + * Number of host channels assigned to periodic transfers. Currently + * assuming that there is a dedicated host channel for each periodic + * transaction and at least one host channel available for + * non-periodic transactions. + */ + int periodic_channels; + + /** + * Number of host channels assigned to non-periodic transfers. + */ + int non_periodic_channels; + + /** + * Array of pointers to the host channel descriptors. Allows accessing + * a host channel descriptor given the host channel number. This is + * useful in interrupt handlers. + */ + struct dwc_hc *hc_ptr_array[MAX_EPS_CHANNELS]; + + /** + * Buffer to use for any data received during the status phase of a + * control transfer. Normally no data is transferred during the status + * phase. This buffer is used as a bit bucket. + */ + uint8_t *status_buf; + + /** + * DMA address for status_buf. + */ + dma_addr_t status_buf_dma; +#define DWC_OTG_HCD_STATUS_BUF_SIZE 64 + + /** + * Connection timer. An OTG host must display a message if the device + * does not connect. Started when the VBus power is turned on via + * sysfs attribute "buspower". + */ + dwc_timer_t *conn_timer; + + /* Tasket to do a reset */ + //dwc_tasklet_t *reset_tasklet; + + /* */ + dwc_spinlock_t *lock; + + /** + * Private data that could be used by OS wrapper. + */ + void *priv; + + uint8_t otg_port; + + /** Frame List */ + uint32_t *frame_list; + + /** Frame List DMA address */ + dma_addr_t frame_list_dma; + +#ifdef OTGDEBUG + uint32_t frrem_samples; + uint64_t frrem_accum; + + uint32_t hfnum_7_samples_a; + uint64_t hfnum_7_frrem_accum_a; + uint32_t hfnum_0_samples_a; + uint64_t hfnum_0_frrem_accum_a; + uint32_t hfnum_other_samples_a; + uint64_t hfnum_other_frrem_accum_a; + + uint32_t hfnum_7_samples_b; + uint64_t hfnum_7_frrem_accum_b; + uint32_t hfnum_0_samples_b; + uint64_t hfnum_0_frrem_accum_b; + uint32_t hfnum_other_samples_b; + uint64_t hfnum_other_frrem_accum_b; +#endif +}; + +/** @name Transaction Execution Functions */ +/** @{ */ +extern _LONG_CALL_ dwc_otg_transaction_type_e dwc_otg_hcd_select_transactions(dwc_otg_hcd_t + * hcd); +extern _LONG_CALL_ void dwc_otg_hcd_queue_transactions(dwc_otg_hcd_t * hcd, + dwc_otg_transaction_type_e tr_type); + +/** @} */ + +/** @name Interrupt Handler Functions */ +/** @{ */ +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_sof_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_rx_status_q_level_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_np_tx_fifo_empty_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_perio_tx_fifo_empty_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_incomplete_periodic_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_port_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_conn_id_status_change_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_disconnect_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_hc_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_hc_n_intr(dwc_otg_hcd_t * dwc_otg_hcd, + uint32_t num); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_session_req_intr(dwc_otg_hcd_t * dwc_otg_hcd); +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_wakeup_detected_intr(dwc_otg_hcd_t * + dwc_otg_hcd); +/** @} */ + +/** @name Schedule Queue Functions */ +/** @{ */ + +/* Implemented in dwc_otg_hcd_queue.c */ +extern _LONG_CALL_ dwc_otg_qh_t *dwc_otg_hcd_qh_create(dwc_otg_hcd_t * hcd, + dwc_otg_hcd_urb_t * urb, int atomic_alloc); +extern _LONG_CALL_ void dwc_otg_hcd_qh_free(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ int dwc_otg_hcd_qh_add(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ void dwc_otg_hcd_qh_remove(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh, + int sched_csplit); + +/** Remove and free a QH */ +extern _LONG_CALL_ +void dwc_otg_hcd_qh_remove_and_free(dwc_otg_hcd_t * hcd, + dwc_otg_qh_t * qh); + +/** Allocates memory for a QH structure. + * @return Returns the memory allocate or NULL on error. */ +extern _LONG_CALL_ +dwc_otg_qh_t *dwc_otg_hcd_qh_alloc(int atomic_alloc); + +extern _LONG_CALL_ dwc_otg_qtd_t *dwc_otg_hcd_qtd_create(dwc_otg_hcd_urb_t * urb, + int atomic_alloc); +extern _LONG_CALL_ void dwc_otg_hcd_qtd_init(dwc_otg_qtd_t * qtd, dwc_otg_hcd_urb_t * urb); +extern _LONG_CALL_ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t * qtd, dwc_otg_hcd_t * dwc_otg_hcd, + dwc_otg_qh_t ** qh, int atomic_alloc); + +/** Allocates memory for a QTD structure. + * @return Returns the memory allocate or NULL on error. */ +extern _LONG_CALL_ +dwc_otg_qtd_t *dwc_otg_hcd_qtd_alloc(int atomic_alloc); + +/** Frees the memory for a QTD structure. QTD should already be removed from + * list. + * @param qtd QTD to free.*/ +extern _LONG_CALL_ +void dwc_otg_hcd_qtd_free(dwc_otg_qtd_t * qtd); + +/** Removes a QTD from list. + * @param hcd HCD instance. + * @param qtd QTD to remove from list. + * @param qh QTD belongs to. + */ +extern _LONG_CALL_ +void dwc_otg_hcd_qtd_remove(dwc_otg_hcd_t * hcd, + dwc_otg_qtd_t * qtd, + dwc_otg_qh_t * qh); + +/** Remove and free a QTD + * Need to disable IRQ and hold hcd lock while calling this function out of + * interrupt servicing chain */ +extern _LONG_CALL_ +void dwc_otg_hcd_qtd_remove_and_free(dwc_otg_hcd_t * hcd, + dwc_otg_qtd_t * qtd, + dwc_otg_qh_t * qh); + +/** @} */ + +/** @name Descriptor DMA Supporting Functions */ +/** @{ */ + +extern _LONG_CALL_ void dwc_otg_hcd_start_xfer_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ void dwc_otg_hcd_complete_xfer_ddma(dwc_otg_hcd_t * hcd, + dwc_hc_t * hc, + dwc_otg_hc_regs_t * hc_regs, + dwc_otg_halt_status_e halt_status); + +extern _LONG_CALL_ int dwc_otg_hcd_qh_init_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ void dwc_otg_hcd_qh_free_ddma(dwc_otg_hcd_t * hcd, dwc_otg_qh_t * qh); +extern _LONG_CALL_ void reset_tasklet_func(void *data); + +/** @} */ + +/** @name Internal Functions */ +/** @{ */ +extern _LONG_CALL_ dwc_otg_qh_t *dwc_urb_to_qh(dwc_otg_hcd_urb_t * urb); +/** @} */ + +#ifdef CONFIG_USB_DWC_OTG_LPM +extern _LONG_CALL_ int dwc_otg_hcd_get_hc_for_lpm_tran(dwc_otg_hcd_t * hcd, + uint8_t devaddr); +extern _LONG_CALL_ void dwc_otg_hcd_free_hc_from_lpm(dwc_otg_hcd_t * hcd); +#endif + +/** Gets the QH that contains the list_head */ +#define dwc_list_to_qh(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qh_t, qh_list_entry) + +/** Gets the QTD that contains the list_head */ +#define dwc_list_to_qtd(_list_head_ptr_) container_of(_list_head_ptr_, dwc_otg_qtd_t, qtd_list_entry) + +/** Check if QH is non-periodic */ +#define dwc_qh_is_non_per(_qh_ptr_) ((_qh_ptr_->ep_type == UE_BULK) || \ + (_qh_ptr_->ep_type == UE_CONTROL)) + +/** High bandwidth multiplier as encoded in highspeed endpoint descriptors */ +#define dwc_hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) + +/** Packet size for any kind of endpoint descriptor */ +#define dwc_max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) + +/** + * Returns true if _frame1 is less than or equal to _frame2. The comparison is + * done modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the + * frame number when the max frame number is reached. + */ +extern _LONG_CALL_ +int dwc_frame_num_le(uint16_t frame1, uint16_t frame2); + +/** + * Returns true if _frame1 is greater than _frame2. The comparison is done + * modulo DWC_HFNUM_MAX_FRNUM. This accounts for the rollover of the frame + * number when the max frame number is reached. + */ +extern _LONG_CALL_ +int dwc_frame_num_gt(uint16_t frame1, uint16_t frame2); + +/** + * Increments _frame by the amount specified by _inc. The addition is done + * modulo DWC_HFNUM_MAX_FRNUM. Returns the incremented value. + */ +extern _LONG_CALL_ +uint16_t dwc_frame_num_inc(uint16_t frame, uint16_t inc); + +extern _LONG_CALL_ +uint16_t dwc_full_frame_num(uint16_t frame); + +extern _LONG_CALL_ +uint16_t dwc_micro_frame_num(uint16_t frame); + +extern _LONG_CALL_ void dwc_otg_hcd_save_data_toggle(dwc_hc_t * hc, + dwc_otg_hc_regs_t * hc_regs, + dwc_otg_qtd_t * qtd); + +extern _LONG_CALL_ void dwc_hcd_data_init(void); +#ifdef OTGDEBUG +/** + * Macro to sample the remaining PHY clocks left in the current frame. This + * may be used during debugging to determine the average time it takes to + * execute sections of code. There are two possible sample points, "a" and + * "b", so the _letter argument must be one of these values. + * + * To dump the average sample times, read the "hcd_frrem" sysfs attribute. For + * example, "cat /sys/devices/lm0/hcd_frrem". + */ +#define dwc_sample_frrem(_hcd, _qh, _letter) \ +{ \ + hfnum_data_t hfnum; \ + dwc_otg_qtd_t *qtd; \ + qtd = list_entry(_qh->qtd_list.next, dwc_otg_qtd_t, qtd_list_entry); \ + if (usb_pipeint(qtd->urb->pipe) && _qh->start_split_frame != 0 && !qtd->complete_split) { \ + hfnum.d32 = DWC_READ_REG32(&_hcd->core_if->host_if->host_global_regs->hfnum); \ + switch (hfnum.b.frnum & 0x7) { \ + case 7: \ + _hcd->hfnum_7_samples_##_letter++; \ + _hcd->hfnum_7_frrem_accum_##_letter += hfnum.b.frrem; \ + break; \ + case 0: \ + _hcd->hfnum_0_samples_##_letter++; \ + _hcd->hfnum_0_frrem_accum_##_letter += hfnum.b.frrem; \ + break; \ + default: \ + _hcd->hfnum_other_samples_##_letter++; \ + _hcd->hfnum_other_frrem_accum_##_letter += hfnum.b.frrem; \ + break; \ + } \ + } \ +} +#else +#define dwc_sample_frrem(_hcd, _qh, _letter) +#endif +#endif +#endif /* DWC_DEVICE_ONLY */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd_if.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd_if.h new file mode 100644 index 0000000..60502df --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_hcd_if.h @@ -0,0 +1,412 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_hcd_if.h $ + * $Revision: #12 $ + * $Date: 2011/10/26 $ + * $Change: 1873028 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ +#if 1//ndef DWC_DEVICE_ONLY +#ifndef __DWC_HCD_IF_H__ +#define __DWC_HCD_IF_H__ + +#include "dwc_otg_core_if.h" + +/** @file + * This file defines DWC_OTG HCD Core API. + */ + +struct dwc_otg_hcd; +typedef struct dwc_otg_hcd dwc_otg_hcd_t; + +struct dwc_otg_hcd_urb; +typedef struct dwc_otg_hcd_urb dwc_otg_hcd_urb_t; + +/** @name HCD Function Driver Callbacks */ +/** @{ */ + +/** This function is called whenever core switches to host mode. */ +typedef int (*dwc_otg_hcd_start_cb_t) (dwc_otg_hcd_t * hcd); + +/** This function is called when device has been disconnected */ +typedef int (*dwc_otg_hcd_disconnect_cb_t) (dwc_otg_hcd_t * hcd); + +/** Wrapper provides this function to HCD to core, so it can get hub information to which device is connected */ +typedef int (*dwc_otg_hcd_hub_info_from_urb_cb_t) (dwc_otg_hcd_t * hcd, + void *urb_handle, + uint32_t * hub_addr, + uint32_t * port_addr); +/** Via this function HCD core gets device speed */ +typedef int (*dwc_otg_hcd_speed_from_urb_cb_t) (dwc_otg_hcd_t * hcd, + void *urb_handle); + +/** This function is called when urb is completed */ +typedef int (*dwc_otg_hcd_complete_urb_cb_t) (dwc_otg_hcd_t * hcd, + void *urb_handle, + dwc_otg_hcd_urb_t * dwc_otg_urb, + int32_t status); + +/** Via this function HCD core gets b_hnp_enable parameter */ +typedef int (*dwc_otg_hcd_get_b_hnp_enable) (dwc_otg_hcd_t * hcd); + +struct dwc_otg_hcd_function_ops { + dwc_otg_hcd_start_cb_t start; + dwc_otg_hcd_disconnect_cb_t disconnect; + dwc_otg_hcd_hub_info_from_urb_cb_t hub_info; + dwc_otg_hcd_speed_from_urb_cb_t speed; + dwc_otg_hcd_complete_urb_cb_t complete; + dwc_otg_hcd_get_b_hnp_enable get_b_hnp_enable; +}; +/** @} */ + +/** @name HCD Core API */ +/** @{ */ +/** This function allocates dwc_otg_hcd structure and returns pointer on it. */ +extern _LONG_CALL_ dwc_otg_hcd_t *dwc_otg_hcd_alloc_hcd(void); + +/** This function should be called to initiate HCD Core. + * + * @param hcd The HCD + * @param core_if The DWC_OTG Core + * + * Returns -DWC_E_NO_MEMORY if no enough memory. + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if); + +/** Frees HCD + * + * @param hcd The HCD + */ +extern _LONG_CALL_ void dwc_otg_hcd_remove(dwc_otg_hcd_t * hcd); + +/** This function should be called on every hardware interrupt. + * + * @param dwc_otg_hcd The HCD + * + * Returns non zero if interrupt is handled + * Return 0 if interrupt is not handled + */ +extern _LONG_CALL_ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd); + +/** + * Returns private data set by + * dwc_otg_hcd_set_priv_data function. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ void *dwc_otg_hcd_get_priv_data(dwc_otg_hcd_t * hcd); + +/** + * Set private data. + * + * @param hcd The HCD + * @param priv_data pointer to be stored in private data + */ +extern _LONG_CALL_ void dwc_otg_hcd_set_priv_data(dwc_otg_hcd_t * hcd, void *priv_data); + +/** + * This function initializes the HCD Core. + * + * @param hcd The HCD + * @param fops The Function Driver Operations data structure containing pointers to all callbacks. + * + * Returns -DWC_E_NO_DEVICE if Core is currently is in device mode. + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_hcd_start(dwc_otg_hcd_t * hcd, + struct dwc_otg_hcd_function_ops *fops); + +/** + * Halts the DWC_otg host mode operations in a clean manner. USB transfers are + * stopped. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ void dwc_otg_hcd_stop(dwc_otg_hcd_t * hcd); + +/** + * Handles hub class-specific requests. + * + * @param dwc_otg_hcd The HCD + * @param typeReq Request Type + * @param wValue wValue from control request + * @param wIndex wIndex from control request + * @param buf data buffer + * @param wLength data buffer length + * + * Returns -DWC_E_INVALID if invalid argument is passed + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_hcd_hub_control(dwc_otg_hcd_t * dwc_otg_hcd, + uint16_t typeReq, uint16_t wValue, + uint16_t wIndex, uint8_t * buf, + uint16_t wLength); + +/** + * Returns otg port number. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_otg_port(dwc_otg_hcd_t * hcd); + +/** + * Returns OTG version - either 1.3 or 2.0. + * + * @param core_if The core_if structure pointer + */ +extern _LONG_CALL_ uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if); + +/** + * Returns 1 if currently core is acting as B host, and 0 otherwise. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_is_b_host(dwc_otg_hcd_t * hcd); + +/** + * Returns current frame number. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ int dwc_otg_hcd_get_frame_number(dwc_otg_hcd_t * hcd); + +/** + * Dumps hcd state. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ void dwc_otg_hcd_dump_state(dwc_otg_hcd_t * hcd); + +/** + * Dump the average frame remaining at SOF. This can be used to + * determine average interrupt latency. Frame remaining is also shown for + * start transfer and two additional sample points. + * Currently this function is not implemented. + * + * @param hcd The HCD + */ +extern _LONG_CALL_ void dwc_otg_hcd_dump_frrem(dwc_otg_hcd_t * hcd); + +/** + * Sends LPM transaction to the local device. + * + * @param hcd The HCD + * @param devaddr Device Address + * @param hird Host initiated resume duration + * @param bRemoteWake Value of bRemoteWake field in LPM transaction + * + * Returns negative value if sending LPM transaction was not succeeded. + * Returns 0 on success. + */ +extern _LONG_CALL_ int dwc_otg_hcd_send_lpm(dwc_otg_hcd_t * hcd, uint8_t devaddr, + uint8_t hird, uint8_t bRemoteWake); + +/* URB interface */ + +/** + * Allocates memory for dwc_otg_hcd_urb structure. + * Allocated memory should be freed by call of DWC_FREE. + * + * @param hcd The HCD + * @param iso_desc_count Count of ISOC descriptors + * @param atomic_alloc Specefies whether to perform atomic allocation. + */ +extern _LONG_CALL_ dwc_otg_hcd_urb_t *dwc_otg_hcd_urb_alloc(dwc_otg_hcd_t * hcd, + int iso_desc_count, + int atomic_alloc); + +/** + * Set pipe information in URB. + * + * @param hcd_urb DWC_OTG URB + * @param devaddr Device Address + * @param ep_num Endpoint Number + * @param ep_type Endpoint Type + * @param ep_dir Endpoint Direction + * @param mps Max Packet Size + */ +extern _LONG_CALL_ void dwc_otg_hcd_urb_set_pipeinfo(dwc_otg_hcd_urb_t * hcd_urb, + uint8_t devaddr, uint8_t ep_num, + uint8_t ep_type, uint8_t ep_dir, + uint16_t mps); + +/* Transfer flags */ +#define URB_GIVEBACK_ASAP 0x1 +#define URB_SEND_ZERO_PACKET 0x2 + +/** + * Sets dwc_otg_hcd_urb parameters. + * + * @param urb DWC_OTG URB allocated by dwc_otg_hcd_urb_alloc function. + * @param urb_handle Unique handle for request, this will be passed back + * to function driver in completion callback. + * @param buf The buffer for the data + * @param dma The DMA buffer for the data + * @param buflen Transfer length + * @param sp Buffer for setup data + * @param sp_dma DMA address of setup data buffer + * @param flags Transfer flags + * @param interval Polling interval for interrupt or isochronous transfers. + */ +extern _LONG_CALL_ void dwc_otg_hcd_urb_set_params(dwc_otg_hcd_urb_t * urb, + void *urb_handle, void *buf, + dwc_dma_t dma, uint32_t buflen, void *sp, + dwc_dma_t sp_dma, uint32_t flags, + uint16_t interval); + +/** Gets status from dwc_otg_hcd_urb + * + * @param dwc_otg_urb DWC_OTG URB + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_urb_get_status(dwc_otg_hcd_urb_t * dwc_otg_urb); + +/** Gets actual length from dwc_otg_hcd_urb + * + * @param dwc_otg_urb DWC_OTG URB + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_urb_get_actual_length(dwc_otg_hcd_urb_t * + dwc_otg_urb); + +/** Gets error count from dwc_otg_hcd_urb. Only for ISOC URBs + * + * @param dwc_otg_urb DWC_OTG URB + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_urb_get_error_count(dwc_otg_hcd_urb_t * + dwc_otg_urb); + +/** Set ISOC descriptor offset and length + * + * @param dwc_otg_urb DWC_OTG URB + * @param desc_num ISOC descriptor number + * @param offset Offset from beginig of buffer. + * @param length Transaction length + */ +extern _LONG_CALL_ void dwc_otg_hcd_urb_set_iso_desc_params(dwc_otg_hcd_urb_t * dwc_otg_urb, + int desc_num, uint32_t offset, + uint32_t length); + +/** Get status of ISOC descriptor, specified by desc_num + * + * @param dwc_otg_urb DWC_OTG URB + * @param desc_num ISOC descriptor number + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_urb_get_iso_desc_status(dwc_otg_hcd_urb_t * + dwc_otg_urb, int desc_num); + +/** Get actual length of ISOC descriptor, specified by desc_num + * + * @param dwc_otg_urb DWC_OTG URB + * @param desc_num ISOC descriptor number + */ +extern _LONG_CALL_ uint32_t dwc_otg_hcd_urb_get_iso_desc_actual_length(dwc_otg_hcd_urb_t * + dwc_otg_urb, + int desc_num); + +/** Queue URB. After transfer is completes, the complete callback will be called with the URB status + * + * @param dwc_otg_hcd The HCD + * @param dwc_otg_urb DWC_OTG URB + * @param ep_handle Out parameter for returning endpoint handle + * @param atomic_alloc Flag to do atomic allocation if needed + * + * Returns -DWC_E_NO_DEVICE if no device is connected. + * Returns -DWC_E_NO_MEMORY if there is no enough memory. + * Returns 0 on success. + */ +extern _LONG_CALL_ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t * dwc_otg_hcd, + dwc_otg_hcd_urb_t * dwc_otg_urb, + void **ep_handle, int atomic_alloc); + +/** De-queue the specified URB + * + * @param dwc_otg_hcd The HCD + * @param dwc_otg_urb DWC_OTG URB + */ +extern _LONG_CALL_ int dwc_otg_hcd_urb_dequeue(dwc_otg_hcd_t * dwc_otg_hcd, + dwc_otg_hcd_urb_t * dwc_otg_urb); + +/** Frees resources in the DWC_otg controller related to a given endpoint. + * Any URBs for the endpoint must already be dequeued. + * + * @param hcd The HCD + * @param ep_handle Endpoint handle, returned by dwc_otg_hcd_urb_enqueue function + * @param retry Number of retries if there are queued transfers. + * + * Returns -DWC_E_INVALID if invalid arguments are passed. + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_hcd_endpoint_disable(dwc_otg_hcd_t * hcd, void *ep_handle, + int retry); + +/* Resets the data toggle in qh structure. This function can be called from + * usb_clear_halt routine. + * + * @param hcd The HCD + * @param ep_handle Endpoint handle, returned by dwc_otg_hcd_urb_enqueue function + * + * Returns -DWC_E_INVALID if invalid arguments are passed. + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_hcd_endpoint_reset(dwc_otg_hcd_t * hcd, void *ep_handle); + +/** Returns 1 if status of specified port is changed and 0 otherwise. + * + * @param hcd The HCD + * @param port Port number + */ +extern _LONG_CALL_ int dwc_otg_hcd_is_status_changed(dwc_otg_hcd_t * hcd, int port); + +/** Call this function to check if bandwidth was allocated for specified endpoint. + * Only for ISOC and INTERRUPT endpoints. + * + * @param hcd The HCD + * @param ep_handle Endpoint handle + */ +extern _LONG_CALL_ int dwc_otg_hcd_is_bandwidth_allocated(dwc_otg_hcd_t * hcd, + void *ep_handle); + +/** Call this function to check if bandwidth was freed for specified endpoint. + * + * @param hcd The HCD + * @param ep_handle Endpoint handle + */ +extern _LONG_CALL_ int dwc_otg_hcd_is_bandwidth_freed(dwc_otg_hcd_t * hcd, void *ep_handle); + +/** Returns bandwidth allocated for specified endpoint in microseconds. + * Only for ISOC and INTERRUPT endpoints. + * + * @param hcd The HCD + * @param ep_handle Endpoint handle + */ +extern _LONG_CALL_ uint8_t dwc_otg_hcd_get_ep_bandwidth(dwc_otg_hcd_t * hcd, + void *ep_handle); + +/** @} */ + +#endif /* __DWC_HCD_IF_H__ */ +#endif /* DWC_DEVICE_ONLY */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_os_dep.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_os_dep.h new file mode 100644 index 0000000..4c23670 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_os_dep.h @@ -0,0 +1,5 @@ +#ifndef _DWC_OS_DEP_H_ +#define _DWC_OS_DEP_H_ +#include "errno.h" + +#endif /* _DWC_OS_DEP_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd.h new file mode 100644 index 0000000..226ed87 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd.h @@ -0,0 +1,271 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd.h $ + * $Revision: #49 $ + * $Date: 2013/05/16 $ + * $Change: 2231774 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ +#if 1//ndef DWC_HOST_ONLY +#if !defined(__DWC_PCD_H__) +#define __DWC_PCD_H__ + +#include "dwc_otg_os_dep.h" +#include "usb.h" +#include "dwc_otg_cil.h" +#include "dwc_otg_pcd_if.h" +struct cfiobject; + +/** + * @file + * + * This file contains the structures, constants, and interfaces for + * the Perpherial Contoller Driver (PCD). + * + * The Peripheral Controller Driver (PCD) for Linux will implement the + * Gadget API, so that the existing Gadget drivers can be used. For + * the Mass Storage Function driver the File-backed USB Storage Gadget + * (FBS) driver will be used. The FBS driver supports the + * Control-Bulk (CB), Control-Bulk-Interrupt (CBI), and Bulk-Only + * transports. + * + */ + +/** Invalid DMA Address */ +#define DWC_DMA_ADDR_INVALID (~(dwc_dma_t)0) + +/** Max Transfer size for any EP */ +#define DDMA_MAX_TRANSFER_SIZE 65535 + +/** + * Get the pointer to the core_if from the pcd pointer. + */ +#define GET_CORE_IF( _pcd ) (_pcd->core_if) + +/** + * States of EP0. + */ +typedef enum ep0_state { + EP0_DISCONNECT, /* no host */ + EP0_IDLE, + EP0_IN_DATA_PHASE, + EP0_OUT_DATA_PHASE, + EP0_IN_STATUS_PHASE, + EP0_OUT_STATUS_PHASE, + EP0_STALL, +} ep0state_e; + +/** Fordward declaration.*/ +struct dwc_otg_pcd; + +/** DWC_otg iso request structure. + * + */ +typedef struct usb_iso_request dwc_otg_pcd_iso_request_t; + +#ifdef DWC_UTE_PER_IO +XXX +/** + * This shall be the exact analogy of the same type structure defined in the + * usb_gadget.h. Each descriptor contains + */ +struct dwc_iso_pkt_desc_port { + uint32_t offset; + uint32_t length; /* expected length */ + uint32_t actual_length; + uint32_t status; +}; + +struct dwc_iso_xreq_port { + /** transfer/submission flag */ + uint32_t tr_sub_flags; + /** Start the request ASAP */ +#define DWC_EREQ_TF_ASAP 0x00000002 + /** Just enqueue the request w/o initiating a transfer */ +#define DWC_EREQ_TF_ENQUEUE 0x00000004 + + /** + * count of ISO packets attached to this request - shall + * not exceed the pio_alloc_pkt_count + */ + uint32_t pio_pkt_count; + /** count of ISO packets allocated for this request */ + uint32_t pio_alloc_pkt_count; + /** number of ISO packet errors */ + uint32_t error_count; + /** reserved for future extension */ + uint32_t res; + /** Will be allocated and freed in the UTE gadget and based on the CFC value */ + struct dwc_iso_pkt_desc_port *per_io_frame_descs; +}; +#endif +/** DWC_otg request structure. + * This structure is a list of requests. + */ +typedef struct dwc_otg_pcd_request { + void *priv; + void *buf; + dwc_dma_t dma; + uint32_t length; + uint32_t actual; + unsigned sent_zlp:1; + /** + * Used instead of original buffer if + * it(physical address) is not dword-aligned. + **/ + uint8_t *dw_align_buf; + dwc_dma_t dw_align_buf_dma; + + DWC_CIRCLEQ_ENTRY(dwc_otg_pcd_request) queue_entry; +#ifdef DWC_UTE_PER_IO + struct dwc_iso_xreq_port ext_req; + //void *priv_ereq_nport; /* */ +#endif +} dwc_otg_pcd_request_t; + +DWC_CIRCLEQ_HEAD(req_list, dwc_otg_pcd_request); + +/** PCD EP structure. + * This structure describes an EP, there is an array of EPs in the PCD + * structure. + */ +typedef struct dwc_otg_pcd_ep { + /** USB EP Descriptor */ + const usb_endpoint_descriptor_t *desc; + + /** queue of dwc_otg_pcd_requests. */ + struct req_list queue; + unsigned stopped:1; + unsigned disabling:1; + unsigned dma:1; + unsigned queue_sof:1; + +#ifdef DWC_EN_ISOC + /** ISOC req handle passed */ + void *iso_req_handle; +#endif //_EN_ISOC_ + + /** DWC_otg ep data. */ + dwc_ep_t dwc_ep; + + /** Pointer to PCD */ + struct dwc_otg_pcd *pcd; + + void *priv; +} dwc_otg_pcd_ep_t; + +/** DWC_otg PCD Structure. + * This structure encapsulates the data for the dwc_otg PCD. + */ +struct dwc_otg_pcd { + const struct dwc_otg_pcd_function_ops *fops; + /** The DWC otg device pointer */ + struct dwc_otg_device *otg_dev; + /** Core Interface */ + dwc_otg_core_if_t *core_if; + /** State of EP0 */ + ep0state_e ep0state; + /** EP0 Request is pending */ + unsigned ep0_pending:1; + /** Indicates when SET CONFIGURATION Request is in process */ + unsigned request_config:1; + /** The state of the Remote Wakeup Enable. */ + unsigned remote_wakeup_enable:1; + /** The state of the B-Device HNP Enable. */ + unsigned b_hnp_enable:1; + /** The state of A-Device HNP Support. */ + unsigned a_hnp_support:1; + /** The state of the A-Device Alt HNP support. */ + unsigned a_alt_hnp_support:1; + /** Count of pending Requests */ + unsigned request_pending; + + /** SETUP packet for EP0 + * This structure is allocated as a DMA buffer on PCD initialization + * with enough space for up to 3 setup packets. + */ + union { + usb_device_request_t req; + uint32_t d32[2]; + } *setup_pkt; + + dwc_dma_t setup_pkt_dma_handle; + + /* Additional buffer and flag for CTRL_WR premature case */ + uint8_t *backup_buf; + unsigned data_terminated; + + /** 2-byte dma buffer used to return status from GET_STATUS */ + uint16_t *status_buf; + dwc_dma_t status_buf_dma_handle; + + /** EP0 */ + dwc_otg_pcd_ep_t ep0; + + /** Array of IN EPs. */ + dwc_otg_pcd_ep_t in_ep[MAX_EPS_CHANNELS - 1]; + /** Array of OUT EPs. */ + dwc_otg_pcd_ep_t out_ep[MAX_EPS_CHANNELS - 1]; + /** number of valid EPs in the above array. */ +// unsigned num_eps : 4; + dwc_spinlock_t *lock; + + /** Tasklet to defer starting of TEST mode transmissions until + * Status Phase has been completed. + */ + dwc_tasklet_t *test_mode_tasklet; + + /** Tasklet to delay starting of xfer in DMA mode */ + dwc_tasklet_t *start_xfer_tasklet; + + /** The test mode to enter when the tasklet is executed. */ + unsigned test_mode; + /** The cfi_api structure that implements most of the CFI API + * and OTG specific core configuration functionality + */ +#ifdef DWC_UTE_CFI + struct cfiobject *cfi; +#endif + +}; + +//FIXME this functions should be static, and this prototypes should be removed +extern _LONG_CALL_ void dwc_otg_request_nuke(dwc_otg_pcd_ep_t * ep); +extern _LONG_CALL_ void dwc_otg_request_done(dwc_otg_pcd_ep_t * ep, + dwc_otg_pcd_request_t * req, int32_t status); + +_LONG_CALL_ void dwc_otg_iso_buffer_done(dwc_otg_pcd_t * pcd, dwc_otg_pcd_ep_t * ep, + void *req_handle); +extern _LONG_CALL_ void dwc_otg_pcd_start_iso_ddma(dwc_otg_core_if_t * core_if, + dwc_otg_pcd_ep_t * ep); + +extern _LONG_CALL_ void do_test_mode(void *data); + +extern _LONG_CALL_ void dwc_pcd_data_init(VOID); + +#endif +#endif /* DWC_HOST_ONLY */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd_if.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd_if.h new file mode 100644 index 0000000..25f34f6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_pcd_if.h @@ -0,0 +1,367 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_pcd_if.h $ + * $Revision: #13 $ + * $Date: 2012/12/12 $ + * $Change: 2125019 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ +#if 1//ndef DWC_HOST_ONLY + +#if !defined(__DWC_PCD_IF_H__) +#define __DWC_PCD_IF_H__ + +//#include "dwc_os.h" +#include "dwc_otg_core_if.h" + +/** @file + * This file defines DWC_OTG PCD Core API. + */ + +struct dwc_otg_pcd; +typedef struct dwc_otg_pcd dwc_otg_pcd_t; + +/** Maxpacket size for EP0 */ +#define MAX_EP0_SIZE 64 +/** Maxpacket size for any EP */ +#define MAX_PACKET_SIZE 2048 + +/** @name Function Driver Callbacks */ +/** @{ */ + +/** This function will be called whenever a previously queued request has + * completed. The status value will be set to -DWC_E_SHUTDOWN to indicated a + * failed or aborted transfer, or -DWC_E_RESTART to indicate the device was reset, + * or -DWC_E_TIMEOUT to indicate it timed out, or -DWC_E_INVALID to indicate invalid + * parameters. */ +typedef int (*dwc_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, + void *req_handle, int32_t status, + uint32_t actual); +/** + * This function will be called whenever a previousle queued ISOC request has + * completed. Count of ISOC packets could be read using dwc_otg_pcd_get_iso_packet_count + * function. + * The status of each ISOC packet could be read using dwc_otg_pcd_get_iso_packet_* + * functions. + */ +typedef int (*dwc_isoc_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, + void *req_handle, int proc_buf_num); +/** This function should handle any SETUP request that cannot be handled by the + * PCD Core. This includes most GET_DESCRIPTORs, SET_CONFIGS, Any + * class-specific requests, etc. The function must non-blocking. + * + * Returns 0 on success. + * Returns -DWC_E_NOT_SUPPORTED if the request is not supported. + * Returns -DWC_E_INVALID if the setup request had invalid parameters or bytes. + * Returns -DWC_E_SHUTDOWN on any other error. */ +typedef int (*dwc_setup_cb_t) (dwc_otg_pcd_t * pcd, uint8_t * bytes); +/** This is called whenever the device has been disconnected. The function + * driver should take appropriate action to clean up all pending requests in the + * PCD Core, remove all endpoints (except ep0), and initialize back to reset + * state. */ +typedef int (*dwc_disconnect_cb_t) (dwc_otg_pcd_t * pcd); +/** This function is called when device has been connected. */ +typedef int (*dwc_connect_cb_t) (dwc_otg_pcd_t * pcd, int speed); +/** This function is called when device has been suspended */ +typedef int (*dwc_suspend_cb_t) (dwc_otg_pcd_t * pcd); +/** This function is called when device has received LPM tokens, i.e. + * device has been sent to sleep state. */ +typedef int (*dwc_sleep_cb_t) (dwc_otg_pcd_t * pcd); +/** This function is called when device has been resumed + * from suspend(L2) or L1 sleep state. */ +typedef int (*dwc_resume_cb_t) (dwc_otg_pcd_t * pcd); +/** This function is called whenever hnp params has been changed. + * User can call get_b_hnp_enable, get_a_hnp_support, get_a_alt_hnp_support functions + * to get hnp parameters. */ +typedef int (*dwc_hnp_params_changed_cb_t) (dwc_otg_pcd_t * pcd); +/** This function is called whenever USB RESET is detected. */ +typedef int (*dwc_reset_cb_t) (dwc_otg_pcd_t * pcd); + +typedef int (*cfi_setup_cb_t) (dwc_otg_pcd_t * pcd, void *ctrl_req_bytes); + +/** + * + * @param ep_handle Void pointer to the usb_ep structure + * @param ereq_port Pointer to the extended request structure created in the + * portable part. + */ +typedef int (*xiso_completion_cb_t) (dwc_otg_pcd_t * pcd, void *ep_handle, + void *req_handle, int32_t status, + void *ereq_port); +/** Function Driver Ops Data Structure */ +struct dwc_otg_pcd_function_ops { + dwc_connect_cb_t connect; + dwc_disconnect_cb_t disconnect; + dwc_setup_cb_t setup; + dwc_completion_cb_t complete; + dwc_isoc_completion_cb_t isoc_complete; + dwc_suspend_cb_t suspend; + dwc_sleep_cb_t sleep; + dwc_resume_cb_t resume; + dwc_reset_cb_t reset; + dwc_hnp_params_changed_cb_t hnp_changed; + cfi_setup_cb_t cfi_setup; +#ifdef DWC_UTE_PER_IO + xiso_completion_cb_t xisoc_complete; +#endif +}; +/** @} */ + +/** @name Function Driver Functions */ +/** @{ */ + +/** Call this function to get pointer on dwc_otg_pcd_t, + * this pointer will be used for all PCD API functions. + * + * @param core_if The DWC_OTG Core + */ +extern _LONG_CALL_ dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if); + +/** Frees PCD allocated by dwc_otg_pcd_init + * + * @param pcd The PCD + */ +extern _LONG_CALL_ void dwc_otg_pcd_remove(dwc_otg_pcd_t * pcd); + +/** Call this to bind the function driver to the PCD Core. + * + * @param pcd Pointer on dwc_otg_pcd_t returned by dwc_otg_pcd_init function. + * @param fops The Function Driver Ops data structure containing pointers to all callbacks. + */ +extern _LONG_CALL_ void dwc_otg_pcd_start(dwc_otg_pcd_t * pcd, + const struct dwc_otg_pcd_function_ops *fops); + +/** Enables an endpoint for use. This function enables an endpoint in + * the PCD. The endpoint is described by the ep_desc which has the + * same format as a USB ep descriptor. The ep_handle parameter is used to refer + * to the endpoint from other API functions and in callbacks. Normally this + * should be called after a SET_CONFIGURATION/SET_INTERFACE to configure the + * core for that interface. + * + * Returns -DWC_E_INVALID if invalid parameters were passed. + * Returns -DWC_E_SHUTDOWN if any other error ocurred. + * Returns 0 on success. + * + * @param pcd The PCD + * @param ep_desc Endpoint descriptor + * @param ep_handle Handle on endpoint, that will be used to identify endpoint. + */ +extern _LONG_CALL_ int dwc_otg_pcd_ep_enable(dwc_otg_pcd_t * pcd, + const uint8_t * ep_desc, void *ep_handle); + +/** Disable the endpoint referenced by ep_handle. + * + * Returns -DWC_E_INVALID if invalid parameters were passed. + * Returns -DWC_E_SHUTDOWN if any other error occurred. + * Returns 0 on success. */ +extern _LONG_CALL_ int dwc_otg_pcd_ep_disable(dwc_otg_pcd_t * pcd, void *ep_handle); + +/** Queue a data transfer request on the endpoint referenced by ep_handle. + * After the transfer is completes, the complete callback will be called with + * the request status. + * + * @param pcd The PCD + * @param ep_handle The handle of the endpoint + * @param buf The buffer for the data + * @param dma_buf The DMA buffer for the data + * @param buflen The length of the data transfer + * @param zero Specifies whether to send zero length last packet. + * @param req_handle Set this handle to any value to use to reference this + * request in the ep_dequeue function or from the complete callback + * @param atomic_alloc If driver need to perform atomic allocations + * for internal data structures. + * + * Returns -DWC_E_INVALID if invalid parameters were passed. + * Returns -DWC_E_SHUTDOWN if any other error ocurred. + * Returns 0 on success. */ +extern _LONG_CALL_ int dwc_otg_pcd_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, + uint8_t * buf, dwc_dma_t dma_buf, + uint32_t buflen, int zero, void *req_handle, + int atomic_alloc); +#ifdef DWC_UTE_PER_IO +XXXX +/** + * + * @param ereq_nonport Pointer to the extended request part of the + * usb_request structure defined in usb_gadget.h file. + */ +extern int dwc_otg_pcd_xiso_ep_queue(dwc_otg_pcd_t * pcd, void *ep_handle, + uint8_t * buf, dwc_dma_t dma_buf, + uint32_t buflen, int zero, + void *req_handle, int atomic_alloc, + void *ereq_nonport); + +#endif + +/** De-queue the specified data transfer that has not yet completed. + * + * Returns -DWC_E_INVALID if invalid parameters were passed. + * Returns -DWC_E_SHUTDOWN if any other error ocurred. + * Returns 0 on success. */ +extern _LONG_CALL_ int dwc_otg_pcd_ep_dequeue(dwc_otg_pcd_t * pcd, void *ep_handle, + void *req_handle); + +/** Halt (STALL) an endpoint or clear it. + * + * Returns -DWC_E_INVALID if invalid parameters were passed. + * Returns -DWC_E_SHUTDOWN if any other error ocurred. + * Returns -DWC_E_AGAIN if the STALL cannot be sent and must be tried again later + * Returns 0 on success. */ +extern _LONG_CALL_ int dwc_otg_pcd_ep_halt(dwc_otg_pcd_t * pcd, void *ep_handle, int value); + +/** This function should be called on every hardware interrupt */ +extern _LONG_CALL_ int32_t dwc_otg_pcd_handle_intr(dwc_otg_pcd_t * pcd); + +/** This function returns current frame number */ +extern _LONG_CALL_ int dwc_otg_pcd_get_frame_number(dwc_otg_pcd_t * pcd); + +/** + * Start isochronous transfers on the endpoint referenced by ep_handle. + * For isochronous transfers duble buffering is used. + * After processing each of buffers comlete callback will be called with + * status for each transaction. + * + * @param pcd The PCD + * @param ep_handle The handle of the endpoint + * @param buf0 The virtual address of first data buffer + * @param buf1 The virtual address of second data buffer + * @param dma0 The DMA address of first data buffer + * @param dma1 The DMA address of second data buffer + * @param sync_frame Data pattern frame number + * @param dp_frame Data size for pattern frame + * @param data_per_frame Data size for regular frame + * @param start_frame Frame number to start transfers, if -1 then start transfers ASAP. + * @param buf_proc_intrvl Interval of ISOC Buffer processing + * @param req_handle Handle of ISOC request + * @param atomic_alloc Specefies whether to perform atomic allocation for + * internal data structures. + * + * Returns -DWC_E_NO_MEMORY if there is no enough memory. + * Returns -DWC_E_INVALID if incorrect arguments are passed to the function. + * Returns -DW_E_SHUTDOWN for any other error. + * Returns 0 on success + */ +extern _LONG_CALL_ int dwc_otg_pcd_iso_ep_start(dwc_otg_pcd_t * pcd, void *ep_handle, + uint8_t * buf0, uint8_t * buf1, + dwc_dma_t dma0, dwc_dma_t dma1, + int sync_frame, int dp_frame, + int data_per_frame, int start_frame, + int buf_proc_intrvl, void *req_handle, + int atomic_alloc); + +/** Stop ISOC transfers on endpoint referenced by ep_handle. + * + * @param pcd The PCD + * @param ep_handle The handle of the endpoint + * @param req_handle Handle of ISOC request + * + * Returns -DWC_E_INVALID if incorrect arguments are passed to the function + * Returns 0 on success + */ +_LONG_CALL_ int dwc_otg_pcd_iso_ep_stop(dwc_otg_pcd_t * pcd, void *ep_handle, + void *req_handle); + +/** Get ISOC packet status. + * + * @param pcd The PCD + * @param ep_handle The handle of the endpoint + * @param iso_req_handle Isochronoush request handle + * @param packet Number of packet + * @param status Out parameter for returning status + * @param actual Out parameter for returning actual length + * @param offset Out parameter for returning offset + * + */ +extern _LONG_CALL_ void dwc_otg_pcd_get_iso_packet_params(dwc_otg_pcd_t * pcd, + void *ep_handle, + void *iso_req_handle, int packet, + int *status, int *actual, + int *offset); + +/** Get ISOC packet count. + * + * @param pcd The PCD + * @param ep_handle The handle of the endpoint + * @param iso_req_handle + */ +extern _LONG_CALL_ int dwc_otg_pcd_get_iso_packet_count(dwc_otg_pcd_t * pcd, + void *ep_handle, + void *iso_req_handle); + +/** This function starts the SRP Protocol if no session is in progress. If + * a session is already in progress, but the device is suspended, + * remote wakeup signaling is started. + */ +extern _LONG_CALL_ int dwc_otg_pcd_wakeup(dwc_otg_pcd_t * pcd); + +/** This function returns 1 if LPM support is enabled, and 0 otherwise. */ +extern _LONG_CALL_ int dwc_otg_pcd_is_lpm_enabled(dwc_otg_pcd_t * pcd); + +/** This function returns 1 if LPM Errata support is enabled, and 0 otherwise. */ +extern _LONG_CALL_ int dwc_otg_pcd_is_besl_enabled(dwc_otg_pcd_t * pcd); + +/** This function returns baseline_besl module parametr. */ +extern _LONG_CALL_ int dwc_otg_pcd_get_param_baseline_besl(dwc_otg_pcd_t * pcd); + +/** This function returns deep_besl module parametr. */ +extern _LONG_CALL_ int dwc_otg_pcd_get_param_deep_besl(dwc_otg_pcd_t * pcd); + +/** This function returns 1 if remote wakeup is allowed and 0, otherwise. */ +extern _LONG_CALL_ int dwc_otg_pcd_get_rmwkup_enable(dwc_otg_pcd_t * pcd); + +/** Initiate SRP */ +extern _LONG_CALL_ void dwc_otg_pcd_initiate_srp(dwc_otg_pcd_t * pcd); + +/** Starts remote wakeup signaling. */ +extern _LONG_CALL_ void dwc_otg_pcd_remote_wakeup(dwc_otg_pcd_t * pcd, int set); + +/** Starts micorsecond soft disconnect. */ +extern _LONG_CALL_ void dwc_otg_pcd_disconnect_us(dwc_otg_pcd_t * pcd, int no_of_usecs); +/** This function returns whether device is dualspeed.*/ +extern _LONG_CALL_ uint32_t dwc_otg_pcd_is_dualspeed(dwc_otg_pcd_t * pcd); + +/** This function returns whether device is otg. */ +extern _LONG_CALL_ uint32_t dwc_otg_pcd_is_otg(dwc_otg_pcd_t * pcd); + +/** These functions allow to get hnp parameters */ +extern _LONG_CALL_ uint32_t get_b_hnp_enable(dwc_otg_pcd_t * pcd); +extern _LONG_CALL_ uint32_t get_a_hnp_support(dwc_otg_pcd_t * pcd); +extern _LONG_CALL_ uint32_t get_a_alt_hnp_support(dwc_otg_pcd_t * pcd); + +/** CFI specific Interface functions */ +/** Allocate a cfi buffer */ +extern _LONG_CALL_ uint8_t *cfiw_ep_alloc_buffer(dwc_otg_pcd_t * pcd, void *pep, + dwc_dma_t * addr, size_t buflen, + int flags); + +/******************************************************************************/ + +/** @} */ + +#endif /* __DWC_PCD_IF_H__ */ + +#endif /* DWC_HOST_ONLY */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_regs.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_regs.h new file mode 100644 index 0000000..1d01cd7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/dwc_otg_regs.h @@ -0,0 +1,2560 @@ +/* ========================================================================== + * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_regs.h $ + * $Revision: #99 $ + * $Date: 2012/12/10 $ + * $Change: 2123206 $ + * + * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, + * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless + * otherwise expressly agreed to in writing between Synopsys and you. + * + * The Software IS NOT an item of Licensed Software or Licensed Product under + * any End User Software License Agreement or Agreement for Licensed Product + * with Synopsys or any supplement thereto. You are permitted to use and + * redistribute this Software in source and binary forms, with or without + * modification, provided that redistributions of source code must retain this + * notice. You may not view, use, disclose, copy or distribute this file or + * any information contained herein except pursuant to this license grant from + * Synopsys. If you do not agree with this notice, including the disclaimer + * below, then you are not authorized to use the Software. + * + * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * ========================================================================== */ + +#ifndef __DWC_OTG_REGS_H__ +#define __DWC_OTG_REGS_H__ + +#include "dwc_otg_core_if.h" + + + + +/** + * @file + * + * This file contains the data structures for accessing the DWC_otg core registers. + * + * The application interfaces with the HS OTG core by reading from and + * writing to the Control and Status Register (CSR) space through the + * AHB Slave interface. These registers are 32 bits wide, and the + * addresses are 32-bit-block aligned. + * CSRs are classified as follows: + * - Core Global Registers + * - Device Mode Registers + * - Device Global Registers + * - Device Endpoint Specific Registers + * - Host Mode Registers + * - Host Global Registers + * - Host Port CSRs + * - Host Channel Specific Registers + * + * Only the Core Global registers can be accessed in both Device and + * Host modes. When the HS OTG core is operating in one mode, either + * Device or Host, the application must not access registers from the + * other mode. When the core switches from one mode to another, the + * registers in the new mode of operation must be reprogrammed as they + * would be after a power-on reset. + */ + +/****************************************************************************/ +/** DWC_otg Core registers . + * The dwc_otg_core_global_regs structure defines the size + * and relative field offsets for the Core Global registers. + */ +typedef struct dwc_otg_core_global_regs { + /** OTG Control and Status Register. Offset: 000h */ + volatile uint32_t gotgctl; + /** OTG Interrupt Register. Offset: 004h */ + volatile uint32_t gotgint; + /**Core AHB Configuration Register. Offset: 008h */ + volatile uint32_t gahbcfg; + +#define DWC_GLBINTRMASK 0x0001 +#define DWC_DMAENABLE 0x0020 +#define DWC_NPTXEMPTYLVL_EMPTY 0x0080 +#define DWC_NPTXEMPTYLVL_HALFEMPTY 0x0000 +#define DWC_PTXEMPTYLVL_EMPTY 0x0100 +#define DWC_PTXEMPTYLVL_HALFEMPTY 0x0000 + + /**Core USB Configuration Register. Offset: 00Ch */ + volatile uint32_t gusbcfg; + /**Core Reset Register. Offset: 010h */ + volatile uint32_t grstctl; + /**Core Interrupt Register. Offset: 014h */ + volatile uint32_t gintsts; + /**Core Interrupt Mask Register. Offset: 018h */ + volatile uint32_t gintmsk; + /**Receive Status Queue Read Register (Read Only). Offset: 01Ch */ + volatile uint32_t grxstsr; + /**Receive Status Queue Read & POP Register (Read Only). Offset: 020h*/ + volatile uint32_t grxstsp; + /**Receive FIFO Size Register. Offset: 024h */ + volatile uint32_t grxfsiz; + /**Non Periodic Transmit FIFO Size Register. Offset: 028h */ + volatile uint32_t gnptxfsiz; + /**Non Periodic Transmit FIFO/Queue Status Register (Read + * Only). Offset: 02Ch */ + volatile uint32_t gnptxsts; + /**I2C Access Register. Offset: 030h */ + volatile uint32_t gi2cctl; + /**PHY Vendor Control Register. Offset: 034h */ + volatile uint32_t gpvndctl; + /**General Purpose Input/Output Register. Offset: 038h */ + volatile uint32_t ggpio; + /**User ID Register. Offset: 03Ch */ + volatile uint32_t guid; + /**Synopsys ID Register (Read Only). Offset: 040h */ + volatile uint32_t gsnpsid; + /**User HW Config1 Register (Read Only). Offset: 044h */ + volatile uint32_t ghwcfg1; + /**User HW Config2 Register (Read Only). Offset: 048h */ + volatile uint32_t ghwcfg2; +#define DWC_SLAVE_ONLY_ARCH 0 +#define DWC_EXT_DMA_ARCH 1 +#define DWC_INT_DMA_ARCH 2 + +#define DWC_MODE_HNP_SRP_CAPABLE 0 +#define DWC_MODE_SRP_ONLY_CAPABLE 1 +#define DWC_MODE_NO_HNP_SRP_CAPABLE 2 +#define DWC_MODE_SRP_CAPABLE_DEVICE 3 +#define DWC_MODE_NO_SRP_CAPABLE_DEVICE 4 +#define DWC_MODE_SRP_CAPABLE_HOST 5 +#define DWC_MODE_NO_SRP_CAPABLE_HOST 6 + + /**User HW Config3 Register (Read Only). Offset: 04Ch */ + volatile uint32_t ghwcfg3; + /**User HW Config4 Register (Read Only). Offset: 050h*/ + volatile uint32_t ghwcfg4; + /** Core LPM Configuration register Offset: 054h*/ + volatile uint32_t glpmcfg; + /** Global PowerDn Register Offset: 058h */ + volatile uint32_t gpwrdn; + /** Global DFIFO SW Config Register Offset: 05Ch */ + volatile uint32_t gdfifocfg; + /** ADP Control Register Offset: 060h */ + volatile uint32_t adpctl; + /** Reserved Offset: 064h-0FFh */ + volatile uint32_t reserved39[39]; + /** Host Periodic Transmit FIFO Size Register. Offset: 100h */ + volatile uint32_t hptxfsiz; + /** Device Periodic Transmit FIFO#n Register if dedicated fifos are disabled, + otherwise Device Transmit FIFO#n Register. + * Offset: 104h + (FIFO_Number-1)*04h, 1 <= FIFO Number <= 15 (1<=n<=15). */ + volatile uint32_t dtxfsiz[15]; +} dwc_otg_core_global_regs_t; + +/** + * This union represents the bit fields of the Core OTG Control + * and Status Register (GOTGCTL). Set the bits using the bit + * fields then write the d32 value to the register. + */ +typedef union gotgctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned sesreqscs:1; + unsigned sesreq:1; + unsigned vbvalidoven:1; + unsigned vbvalidovval:1; + unsigned avalidoven:1; + unsigned avalidovval:1; + unsigned bvalidoven:1; + unsigned bvalidovval:1; + unsigned hstnegscs:1; + unsigned hnpreq:1; + unsigned hstsethnpen:1; + unsigned devhnpen:1; + unsigned reserved12_15:4; + unsigned conidsts:1; + unsigned dbnctime:1; + unsigned asesvld:1; + unsigned bsesvld:1; + unsigned otgver:1; + unsigned reserved1:1; + unsigned multvalidbc:5; + unsigned chirpen:1; + unsigned reserved28_31:4; + } b; +} gotgctl_data_t; + +/** + * This union represents the bit fields of the Core OTG Interrupt Register + * (GOTGINT). Set/clear the bits using the bit fields then write the d32 + * value to the register. + */ +typedef union gotgint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Current Mode */ + unsigned reserved0_1:2; + + /** Session End Detected */ + unsigned sesenddet:1; + + unsigned reserved3_7:5; + + /** Session Request Success Status Change */ + unsigned sesreqsucstschng:1; + /** Host Negotiation Success Status Change */ + unsigned hstnegsucstschng:1; + + unsigned reserved10_16:7; + + /** Host Negotiation Detected */ + unsigned hstnegdet:1; + /** A-Device Timeout Change */ + unsigned adevtoutchng:1; + /** Debounce Done */ + unsigned debdone:1; + /** Multi-Valued input changed */ + unsigned mvic:1; + + unsigned reserved31_21:11; + + } b; +} gotgint_data_t; + +/** + * This union represents the bit fields of the Core AHB Configuration + * Register (GAHBCFG). Set/clear the bits using the bit fields then + * write the d32 value to the register. + */ +typedef union gahbcfg_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned glblintrmsk:1; +#define DWC_GAHBCFG_GLBINT_ENABLE 1 + + unsigned hburstlen:4; +#define DWC_GAHBCFG_INT_DMA_BURST_SINGLE 0 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR 1 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR4 3 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR8 5 +#define DWC_GAHBCFG_INT_DMA_BURST_INCR16 7 + + unsigned dmaenable:1; +#define DWC_GAHBCFG_DMAENABLE 1 + unsigned reserved:1; + unsigned nptxfemplvl_txfemplvl:1; + unsigned ptxfemplvl:1; +#define DWC_GAHBCFG_TXFEMPTYLVL_EMPTY 1 +#define DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0 + unsigned reserved9_20:12; + unsigned remmemsupp:1; + unsigned notialldmawrit:1; + unsigned ahbsingle:1; + unsigned reserved24_31:8; + } b; +} gahbcfg_data_t; + +/** + * This union represents the bit fields of the Core USB Configuration + * Register (GUSBCFG). Set the bits using the bit fields then write + * the d32 value to the register. + */ +typedef union gusbcfg_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned toutcal:3; + unsigned phyif:1; + unsigned ulpi_utmi_sel:1; + unsigned fsintf:1; + unsigned physel:1; + unsigned ddrsel:1; + unsigned srpcap:1; + unsigned hnpcap:1; + unsigned usbtrdtim:4; + unsigned reserved1:1; + unsigned phylpwrclksel:1; + unsigned otgutmifssel:1; + unsigned ulpi_fsls:1; + unsigned ulpi_auto_res:1; + unsigned ulpi_clk_sus_m:1; + unsigned ulpi_ext_vbus_drv:1; + unsigned ulpi_int_vbus_indicator:1; + unsigned term_sel_dl_pulse:1; + unsigned indicator_complement:1; + unsigned indicator_pass_through:1; + unsigned ulpi_int_prot_dis:1; + unsigned ic_usb_cap:1; + unsigned ic_traffic_pull_remove:1; + unsigned tx_end_delay:1; + unsigned force_host_mode:1; + unsigned force_dev_mode:1; + unsigned reserved31:1; + } b; +} gusbcfg_data_t; + +/** + * This union represents the bit fields of the Core Reset Register + * (GRSTCTL). Set/clear the bits using the bit fields then write the + * d32 value to the register. + */ +typedef union grstctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Core Soft Reset (CSftRst) (Device and Host) + * + * The application can flush the control logic in the + * entire core using this bit. This bit resets the + * pipelines in the AHB Clock domain as well as the + * PHY Clock domain. + * + * The state machines are reset to an IDLE state, the + * control bits in the CSRs are cleared, all the + * transmit FIFOs and the receive FIFO are flushed. + * + * The status mask bits that control the generation of + * the interrupt, are cleared, to clear the + * interrupt. The interrupt status bits are not + * cleared, so the application can get the status of + * any events that occurred in the core after it has + * set this bit. + * + * Any transactions on the AHB are terminated as soon + * as possible following the protocol. Any + * transactions on the USB are terminated immediately. + * + * The configuration settings in the CSRs are + * unchanged, so the software doesn't have to + * reprogram these registers (Device + * Configuration/Host Configuration/Core System + * Configuration/Core PHY Configuration). + * + * The application can write to this bit, any time it + * wants to reset the core. This is a self clearing + * bit and the core clears this bit after all the + * necessary logic is reset in the core, which may + * take several clocks, depending on the current state + * of the core. + */ + unsigned csftrst:1; + /** Hclk Soft Reset + * + * The application uses this bit to reset the control logic in + * the AHB clock domain. Only AHB clock domain pipelines are + * reset. + */ + unsigned hsftrst:1; + /** Host Frame Counter Reset (Host Only)
+ * + * The application can reset the (micro)frame number + * counter inside the core, using this bit. When the + * (micro)frame counter is reset, the subsequent SOF + * sent out by the core, will have a (micro)frame + * number of 0. + */ + unsigned hstfrm:1; + /** In Token Sequence Learning Queue Flush + * (INTknQFlsh) (Device Only) + */ + unsigned intknqflsh:1; + /** RxFIFO Flush (RxFFlsh) (Device and Host) + * + * The application can flush the entire Receive FIFO + * using this bit. The application must first + * ensure that the core is not in the middle of a + * transaction. The application should write into + * this bit, only after making sure that neither the + * DMA engine is reading from the RxFIFO nor the MAC + * is writing the data in to the FIFO. The + * application should wait until the bit is cleared + * before performing any other operations. This bit + * will takes 8 clocks (slowest of PHY or AHB clock) + * to clear. + */ + unsigned rxfflsh:1; + /** TxFIFO Flush (TxFFlsh) (Device and Host). + * + * This bit is used to selectively flush a single or + * all transmit FIFOs. The application must first + * ensure that the core is not in the middle of a + * transaction. The application should write into + * this bit, only after making sure that neither the + * DMA engine is writing into the TxFIFO nor the MAC + * is reading the data out of the FIFO. The + * application should wait until the core clears this + * bit, before performing any operations. This bit + * will takes 8 clocks (slowest of PHY or AHB clock) + * to clear. + */ + unsigned txfflsh:1; + + /** TxFIFO Number (TxFNum) (Device and Host). + * + * This is the FIFO number which needs to be flushed, + * using the TxFIFO Flush bit. This field should not + * be changed until the TxFIFO Flush bit is cleared by + * the core. + * - 0x0 : Non Periodic TxFIFO Flush + * - 0x1 : Periodic TxFIFO #1 Flush in device mode + * or Periodic TxFIFO in host mode + * - 0x2 : Periodic TxFIFO #2 Flush in device mode. + * - ... + * - 0xF : Periodic TxFIFO #15 Flush in device mode + * - 0x10: Flush all the Transmit NonPeriodic and + * Transmit Periodic FIFOs in the core + */ + unsigned txfnum:5; + /** Reserved */ + unsigned reserved11_29:19; + /** DMA Request Signal. Indicated DMA request is in + * probress. Used for debug purpose. */ + unsigned dmareq:1; + /** AHB Master Idle. Indicates the AHB Master State + * Machine is in IDLE condition. */ + unsigned ahbidle:1; + } b; +} grstctl_t; + +/** + * This union represents the bit fields of the Core Interrupt Mask + * Register (GINTMSK). Set/clear the bits using the bit fields then + * write the d32 value to the register. + */ +typedef union gintmsk_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned reserved0:1; + unsigned modemismatch:1; + unsigned otgintr:1; + unsigned sofintr:1; + unsigned rxstsqlvl:1; + unsigned nptxfempty:1; + unsigned ginnakeff:1; + unsigned goutnakeff:1; + unsigned ulpickint:1; + unsigned i2cintr:1; + unsigned erlysuspend:1; + unsigned usbsuspend:1; + unsigned usbreset:1; + unsigned enumdone:1; + unsigned isooutdrop:1; + unsigned eopframe:1; + unsigned restoredone:1; + unsigned epmismatch:1; + unsigned inepintr:1; + unsigned outepintr:1; + unsigned incomplisoin:1; + unsigned incomplisoout:1; + unsigned fetsusp:1; + unsigned resetdet:1; + unsigned portintr:1; + unsigned hcintr:1; + unsigned ptxfempty:1; + unsigned lpmtranrcvd:1; + unsigned conidstschng:1; + unsigned disconnect:1; + unsigned sessreqintr:1; + unsigned wkupintr:1; + } b; +} gintmsk_data_t; +/** + * This union represents the bit fields of the Core Interrupt Register + * (GINTSTS). Set/clear the bits using the bit fields then write the + * d32 value to the register. + */ +typedef union gintsts_data { + /** raw register data */ + uint32_t d32; +#define DWC_SOF_INTR_MASK 0x0008 + /** register bits */ + struct { +#define DWC_HOST_MODE 1 + unsigned curmode:1; + unsigned modemismatch:1; + unsigned otgintr:1; + unsigned sofintr:1; + unsigned rxstsqlvl:1; + unsigned nptxfempty:1; + unsigned ginnakeff:1; + unsigned goutnakeff:1; + unsigned ulpickint:1; + unsigned i2cintr:1; + unsigned erlysuspend:1; + unsigned usbsuspend:1; + unsigned usbreset:1; + unsigned enumdone:1; + unsigned isooutdrop:1; + unsigned eopframe:1; + unsigned restoredone:1; + unsigned epmismatch:1; + unsigned inepint:1; + unsigned outepintr:1; + unsigned incomplisoin:1; + unsigned incomplisoout:1; + unsigned fetsusp:1; + unsigned resetdet:1; + unsigned portintr:1; + unsigned hcintr:1; + unsigned ptxfempty:1; + unsigned lpmtranrcvd:1; + unsigned conidstschng:1; + unsigned disconnect:1; + unsigned sessreqintr:1; + unsigned wkupintr:1; + } b; +} gintsts_data_t; + +/** + * This union represents the bit fields in the Device Receive Status Read and + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 + * element then read out the bits using the bit elements. + */ +typedef union device_grxsts_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned epnum:4; + unsigned bcnt:11; + unsigned dpid:2; + +#define DWC_STS_DATA_UPDT 0x2 // OUT Data Packet +#define DWC_STS_XFER_COMP 0x3 // OUT Data Transfer Complete + +#define DWC_DSTS_GOUT_NAK 0x1 // Global OUT NAK +#define DWC_DSTS_SETUP_COMP 0x4 // Setup Phase Complete +#define DWC_DSTS_SETUP_UPDT 0x6 // SETUP Packet + unsigned pktsts:4; + unsigned fn:4; + unsigned reserved25_31:7; + } b; +} device_grxsts_data_t; + +/** + * This union represents the bit fields in the Host Receive Status Read and + * Pop Registers (GRXSTSR, GRXSTSP) Read the register into the d32 + * element then read out the bits using the bit elements. + */ +typedef union host_grxsts_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned chnum:4; + unsigned bcnt:11; + unsigned dpid:2; + + unsigned pktsts:4; +#define DWC_GRXSTS_PKTSTS_IN 0x2 +#define DWC_GRXSTS_PKTSTS_IN_XFER_COMP 0x3 +#define DWC_GRXSTS_PKTSTS_DATA_TOGGLE_ERR 0x5 +#define DWC_GRXSTS_PKTSTS_CH_HALTED 0x7 + + unsigned reserved21_31:11; + } b; +} host_grxsts_data_t; + +/** + * This union represents the bit fields in the FIFO Size Registers (HPTXFSIZ, + * GNPTXFSIZ, DPTXFSIZn, DIEPTXFn). Read the register into the d32 element + * then read out the bits using the bit elements. + */ +typedef union fifosize_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned startaddr:16; + unsigned depth:16; + } b; +} fifosize_data_t; + +/** + * This union represents the bit fields in the Non-Periodic Transmit + * FIFO/Queue Status Register (GNPTXSTS). Read the register into the + * d32 element then read out the bits using the bit + * elements. + */ +typedef union gnptxsts_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned nptxfspcavail:16; + unsigned nptxqspcavail:8; + /** Top of the Non-Periodic Transmit Request Queue + * - bit 24 - Terminate (Last entry for the selected + * channel/EP) + * - bits 26:25 - Token Type + * - 2'b00 - IN/OUT + * - 2'b01 - Zero Length OUT + * - 2'b10 - PING/Complete Split + * - 2'b11 - Channel Halt + * - bits 30:27 - Channel/EP Number + */ + unsigned nptxqtop_terminate:1; + unsigned nptxqtop_token:2; + unsigned nptxqtop_chnep:4; + unsigned reserved:1; + } b; +} gnptxsts_data_t; + +/** + * This union represents the bit fields in the Transmit + * FIFO Status Register (DTXFSTS). Read the register into the + * d32 element then read out the bits using the bit + * elements. + */ +typedef union dtxfsts_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned txfspcavail:16; + unsigned reserved:16; + } b; +} dtxfsts_data_t; + +/** + * This union represents the bit fields in the I2C Control Register + * (I2CCTL). Read the register into the d32 element then read out the + * bits using the bit elements. + */ +typedef union gi2cctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned rwdata:8; + unsigned regaddr:8; + unsigned addr:7; + unsigned i2cen:1; + unsigned ack:1; + unsigned i2csuspctl:1; + unsigned i2cdevaddr:2; + unsigned i2cdatse0:1; + unsigned reserved:1; + unsigned rw:1; + unsigned bsydne:1; + } b; +} gi2cctl_data_t; + +/** + * This union represents the bit fields in the PHY Vendor Control Register + * (GPVNDCTL). Read the register into the d32 element then read out the + * bits using the bit elements. + */ +typedef union gpvndctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned regdata:8; + unsigned vctrl:8; + unsigned regaddr16_21:6; + unsigned regwr:1; + unsigned reserved23_24:2; + unsigned newregreq:1; + unsigned vstsbsy:1; + unsigned vstsdone:1; + unsigned reserved28_30:3; + unsigned disulpidrvr:1; + } b; +} gpvndctl_data_t; + +/** + * This union represents the bit fields in the General Purpose + * Input/Output Register (GGPIO). + * Read the register into the d32 element then read out the + * bits using the bit elements. + */ +typedef union ggpio_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned gpi:16; + unsigned gpo:16; + } b; +} ggpio_data_t; + +/** + * This union represents the bit fields in the User ID Register + * (GUID). Read the register into the d32 element then read out the + * bits using the bit elements. + */ +typedef union guid_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned rwdata:32; + } b; +} guid_data_t; + +/** + * This union represents the bit fields in the Synopsys ID Register + * (GSNPSID). Read the register into the d32 element then read out the + * bits using the bit elements. + */ +typedef union gsnpsid_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned rwdata:32; + } b; +} gsnpsid_data_t; + +/** + * This union represents the bit fields in the User HW Config1 + * Register. Read the register into the d32 element then read + * out the bits using the bit elements. + */ +typedef union hwcfg1_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned ep_dir0:2; + unsigned ep_dir1:2; + unsigned ep_dir2:2; + unsigned ep_dir3:2; + unsigned ep_dir4:2; + unsigned ep_dir5:2; + unsigned ep_dir6:2; + unsigned ep_dir7:2; + unsigned ep_dir8:2; + unsigned ep_dir9:2; + unsigned ep_dir10:2; + unsigned ep_dir11:2; + unsigned ep_dir12:2; + unsigned ep_dir13:2; + unsigned ep_dir14:2; + unsigned ep_dir15:2; + } b; +} hwcfg1_data_t; + +/** + * This union represents the bit fields in the User HW Config2 + * Register. Read the register into the d32 element then read + * out the bits using the bit elements. + */ +typedef union hwcfg2_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /* GHWCFG2 */ + unsigned op_mode:3; +#define DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG 0 +#define DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG 1 +#define DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG 2 +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3 +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4 +#define DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST 5 +#define DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6 + + unsigned architecture:2; + unsigned point2point:1; + unsigned hs_phy_type:2; +#define DWC_HWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0 +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI 1 +#define DWC_HWCFG2_HS_PHY_TYPE_ULPI 2 +#define DWC_HWCFG2_HS_PHY_TYPE_UTMI_ULPI 3 + + unsigned fs_phy_type:2; + unsigned num_dev_ep:4; + unsigned num_host_chan:4; + unsigned perio_ep_supported:1; + unsigned dynamic_fifo:1; + unsigned multi_proc_int:1; + unsigned reserved21:1; + unsigned nonperio_tx_q_depth:2; + unsigned host_perio_tx_q_depth:2; + unsigned dev_token_q_depth:5; + unsigned otg_enable_ic_usb:1; + } b; +} hwcfg2_data_t; + +/** + * This union represents the bit fields in the User HW Config3 + * Register. Read the register into the d32 element then read + * out the bits using the bit elements. + */ +typedef union hwcfg3_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /* GHWCFG3 */ + unsigned xfer_size_cntr_width:4; + unsigned packet_size_cntr_width:3; + unsigned otg_func:1; + unsigned i2c:1; + unsigned vendor_ctrl_if:1; + unsigned optional_features:1; + unsigned synch_reset_type:1; + unsigned adp_supp:1; + unsigned otg_enable_hsic:1; + unsigned bc_support:1; + unsigned otg_lpm_en:1; + unsigned dfifo_depth:16; + } b; +} hwcfg3_data_t; + +/** + * This union represents the bit fields in the User HW Config4 + * Register. Read the register into the d32 element then read + * out the bits using the bit elements. + */ +typedef union hwcfg4_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned num_dev_perio_in_ep:4; + unsigned power_optimiz:1; + unsigned min_ahb_freq:1; + unsigned hiber:1; + unsigned xhiber:1; + unsigned reserved:6; + unsigned utmi_phy_data_width:2; + unsigned num_dev_mode_ctrl_ep:4; + unsigned iddig_filt_en:1; + unsigned vbus_valid_filt_en:1; + unsigned a_valid_filt_en:1; + unsigned b_valid_filt_en:1; + unsigned session_end_filt_en:1; + unsigned ded_fifo_en:1; + unsigned num_in_eps:4; + unsigned desc_dma:1; + unsigned desc_dma_dyn:1; + } b; +} hwcfg4_data_t; + +/** + * This union represents the bit fields of the Core LPM Configuration + * Register (GLPMCFG). Set the bits using bit fields then write + * the d32 value to the register. + */ +typedef union glpmctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** LPM-Capable (LPMCap) (Device and Host) + * The application uses this bit to control + * the DWC_otg core LPM capabilities. + */ + unsigned lpm_cap_en:1; + /** LPM response programmed by application (AppL1Res) (Device) + * Handshake response to LPM token pre-programmed + * by device application software. + */ + unsigned appl_resp:1; + /** Host Initiated Resume Duration (HIRD) (Device and Host) + * In Host mode this field indicates the value of HIRD + * to be sent in an LPM transaction. + * In Device mode this field is updated with the + * Received LPM Token HIRD bmAttribute + * when an ACK/NYET/STALL response is sent + * to an LPM transaction. + */ + unsigned hird:4; + /** RemoteWakeEnable (bRemoteWake) (Device and Host) + * In Host mode this bit indicates the value of remote + * wake up to be sent in wIndex field of LPM transaction. + * In Device mode this field is updated with the + * Received LPM Token bRemoteWake bmAttribute + * when an ACK/NYET/STALL response is sent + * to an LPM transaction. + */ + unsigned rem_wkup_en:1; + /** Enable utmi_sleep_n (EnblSlpM) (Device and Host) + * The application uses this bit to control + * the utmi_sleep_n assertion to the PHY when in L1 state. + */ + unsigned en_utmi_sleep:1; + /** HIRD Threshold (HIRD_Thres) (Device and Host) + */ + unsigned hird_thres:5; + /** LPM Response (CoreL1Res) (Device and Host) + * In Host mode this bit contains handsake response to + * LPM transaction. + * In Device mode the response of the core to + * LPM transaction received is reflected in these two bits. + - 0x0 : ERROR (No handshake response) + - 0x1 : STALL + - 0x2 : NYET + - 0x3 : ACK + */ + unsigned lpm_resp:2; + /** Port Sleep Status (SlpSts) (Device and Host) + * This bit is set as long as a Sleep condition + * is present on the USB bus. + */ + unsigned prt_sleep_sts:1; + /** Sleep State Resume OK (L1ResumeOK) (Device and Host) + * Indicates that the application or host + * can start resume from Sleep state. + */ + unsigned sleep_state_resumeok:1; + /** LPM channel Index (LPM_Chnl_Indx) (Host) + * The channel number on which the LPM transaction + * has to be applied while sending + * an LPM transaction to the local device. + */ + unsigned lpm_chan_index:4; + /** LPM Retry Count (LPM_Retry_Cnt) (Host) + * Number host retries that would be performed + * if the device response was not valid response. + */ + unsigned retry_count:3; + /** Send LPM Transaction (SndLPM) (Host) + * When set by application software, + * an LPM transaction containing two tokens + * is sent. + */ + unsigned send_lpm:1; + /** LPM Retry status (LPM_RetryCnt_Sts) (Host) + * Number of LPM Host Retries still remaining + * to be transmitted for the current LPM sequence + */ + unsigned retry_count_sts:3; + /** Enable Best Effort Service Latency (BESL) (Device and Host) + * This bit enables the BESL features as defined in the LPM errata + */ + unsigned en_besl:1; + + unsigned reserved29:1; + /** In host mode once this bit is set, the host + * configures to drive the HSIC Idle state on the bus. + * It then waits for the device to initiate the Connect sequence. + * In device mode once this bit is set, the device waits for + * the HSIC Idle line state on the bus. Upon receving the Idle + * line state, it initiates the HSIC Connect sequence. + */ + unsigned hsic_connect:1; + /** This bit overrides and functionally inverts + * the if_select_hsic input port signal. + */ + unsigned inv_sel_hsic:1; + } b; +} glpmcfg_data_t; + +/** + * This union represents the bit fields of the Core ADP Timer, Control and + * Status Register (ADPTIMCTLSTS). Set the bits using bit fields then write + * the d32 value to the register. + */ +typedef union adpctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Probe Discharge (PRB_DSCHG) + * These bits set the times for TADP_DSCHG. + * These bits are defined as follows: + * 2'b00 - 4 msec + * 2'b01 - 8 msec + * 2'b10 - 16 msec + * 2'b11 - 32 msec + */ + unsigned prb_dschg:2; + /** Probe Delta (PRB_DELTA) + * These bits set the resolution for RTIM value. + * The bits are defined in units of 32 kHz clock cycles as follows: + * 2'b00 - 1 cycles + * 2'b01 - 2 cycles + * 2'b10 - 3 cycles + * 2'b11 - 4 cycles + * For example if this value is chosen to 2'b01, it means that RTIM + * increments for every 3(three) 32Khz clock cycles. + */ + unsigned prb_delta:2; + /** Probe Period (PRB_PER) + * These bits sets the TADP_PRD as shown in Figure 4 as follows: + * 2'b00 - 0.625 to 0.925 sec (typical 0.775 sec) + * 2'b01 - 1.25 to 1.85 sec (typical 1.55 sec) + * 2'b10 - 1.9 to 2.6 sec (typical 2.275 sec) + * 2'b11 - Reserved + */ + unsigned prb_per:2; + /** These bits capture the latest time it took for VBUS to ramp from + * VADP_SINK to VADP_PRB. + * 0x000 - 1 cycles + * 0x001 - 2 cycles + * 0x002 - 3 cycles + * etc + * 0x7FF - 2048 cycles + * A time of 1024 cycles at 32 kHz corresponds to a time of 32 msec. + */ + unsigned rtim:11; + /** Enable Probe (EnaPrb) + * When programmed to 1'b1, the core performs a probe operation. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned enaprb:1; + /** Enable Sense (EnaSns) + * When programmed to 1'b1, the core performs a Sense operation. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned enasns:1; + /** ADP Reset (ADPRes) + * When set, ADP controller is reset. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adpres:1; + /** ADP Enable (ADPEn) + * When set, the core performs either ADP probing or sensing + * based on EnaPrb or EnaSns. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adpen:1; + /** ADP Probe Interrupt (ADP_PRB_INT) + * When this bit is set, it means that the VBUS + * voltage is greater than VADP_PRB or VADP_PRB is reached. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_prb_int:1; + /** + * ADP Sense Interrupt (ADP_SNS_INT) + * When this bit is set, it means that the VBUS voltage is greater than + * VADP_SNS value or VADP_SNS is reached. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_sns_int:1; + /** ADP Tomeout Interrupt (ADP_TMOUT_INT) + * This bit is relevant only for an ADP probe. + * When this bit is set, it means that the ramp time has + * completed ie ADPCTL.RTIM has reached its terminal value + * of 0x7FF. This is a debug feature that allows software + * to read the ramp time after each cycle. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_tmout_int:1; + /** ADP Probe Interrupt Mask (ADP_PRB_INT_MSK) + * When this bit is set, it unmasks the interrupt due to ADP_PRB_INT. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_prb_int_msk:1; + /** ADP Sense Interrupt Mask (ADP_SNS_INT_MSK) + * When this bit is set, it unmasks the interrupt due to ADP_SNS_INT. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_sns_int_msk:1; + /** ADP Timoeout Interrupt Mask (ADP_TMOUT_MSK) + * When this bit is set, it unmasks the interrupt due to ADP_TMOUT_INT. + * This bit is valid only if OTG_Ver = 1'b1. + */ + unsigned adp_tmout_int_msk:1; + /** Access Request + * 2'b00 - Read/Write Valid (updated by the core) + * 2'b01 - Read + * 2'b00 - Write + * 2'b00 - Reserved + */ + unsigned ar:2; + /** Reserved */ + unsigned reserved29_31:3; + } b; +} adpctl_data_t; + +//////////////////////////////////////////// +// Device Registers +/** + * Device Global Registers. Offsets 800h-BFFh + * + * The following structures define the size and relative field offsets + * for the Device Mode Registers. + * + * These registers are visible only in Device mode and must not be + * accessed in Host mode, as the results are unknown. + */ +typedef struct dwc_otg_dev_global_regs { + /** Device Configuration Register. Offset 800h */ + volatile uint32_t dcfg; + /** Device Control Register. Offset: 804h */ + volatile uint32_t dctl; + /** Device Status Register (Read Only). Offset: 808h */ + volatile uint32_t dsts; + /** Reserved. Offset: 80Ch */ + uint32_t unused; + /** Device IN Endpoint Common Interrupt Mask + * Register. Offset: 810h */ + volatile uint32_t diepmsk; + /** Device OUT Endpoint Common Interrupt Mask + * Register. Offset: 814h */ + volatile uint32_t doepmsk; + /** Device All Endpoints Interrupt Register. Offset: 818h */ + volatile uint32_t daint; + /** Device All Endpoints Interrupt Mask Register. Offset: + * 81Ch */ + volatile uint32_t daintmsk; + /** Device IN Token Queue Read Register-1 (Read Only). + * Offset: 820h */ + volatile uint32_t dtknqr1; + /** Device IN Token Queue Read Register-2 (Read Only). + * Offset: 824h */ + volatile uint32_t dtknqr2; + /** Device VBUS discharge Register. Offset: 828h */ + volatile uint32_t dvbusdis; + /** Device VBUS Pulse Register. Offset: 82Ch */ + volatile uint32_t dvbuspulse; + /** Device IN Token Queue Read Register-3 (Read Only). / + * Device Thresholding control register (Read/Write) + * Offset: 830h */ + volatile uint32_t dtknqr3_dthrctl; + /** Device IN Token Queue Read Register-4 (Read Only). / + * Device IN EPs empty Inr. Mask Register (Read/Write) + * Offset: 834h */ + volatile uint32_t dtknqr4_fifoemptymsk; + /** Device Each Endpoint Interrupt Register (Read Only). / + * Offset: 838h */ + volatile uint32_t deachint; + /** Device Each Endpoint Interrupt mask Register (Read/Write). / + * Offset: 83Ch */ + volatile uint32_t deachintmsk; + /** Device Each In Endpoint Interrupt mask Register (Read/Write). / + * Offset: 840h */ + volatile uint32_t diepeachintmsk[MAX_EPS_CHANNELS]; + /** Device Each Out Endpoint Interrupt mask Register (Read/Write). / + * Offset: 880h */ + volatile uint32_t doepeachintmsk[MAX_EPS_CHANNELS]; +} dwc_otg_device_global_regs_t; + +/** + * This union represents the bit fields in the Device Configuration + * Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. Write the + * d32 member to the dcfg register. + */ +typedef union dcfg_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Device Speed */ + unsigned devspd:2; + /** Non Zero Length Status OUT Handshake */ + unsigned nzstsouthshk:1; +#define DWC_DCFG_SEND_STALL 1 + + unsigned ena32khzs:1; + /** Device Addresses */ + unsigned devaddr:7; + /** Periodic Frame Interval */ + unsigned perfrint:2; +#define DWC_DCFG_FRAME_INTERVAL_80 0 +#define DWC_DCFG_FRAME_INTERVAL_85 1 +#define DWC_DCFG_FRAME_INTERVAL_90 2 +#define DWC_DCFG_FRAME_INTERVAL_95 3 + + /** Enable Device OUT NAK for bulk in DDMA mode */ + unsigned endevoutnak:1; + + unsigned reserved14_17:4; + /** In Endpoint Mis-match count */ + unsigned epmscnt:5; + /** Enable Descriptor DMA in Device mode */ + unsigned descdma:1; + unsigned perschintvl:2; + unsigned resvalid:6; + } b; +} dcfg_data_t; + +/** + * This union represents the bit fields in the Device Control + * Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union dctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Remote Wakeup */ + unsigned rmtwkupsig:1; + /** Soft Disconnect */ + unsigned sftdiscon:1; + /** Global Non-Periodic IN NAK Status */ + unsigned gnpinnaksts:1; + /** Global OUT NAK Status */ + unsigned goutnaksts:1; + /** Test Control */ + unsigned tstctl:3; + /** Set Global Non-Periodic IN NAK */ + unsigned sgnpinnak:1; + /** Clear Global Non-Periodic IN NAK */ + unsigned cgnpinnak:1; + /** Set Global OUT NAK */ + unsigned sgoutnak:1; + /** Clear Global OUT NAK */ + unsigned cgoutnak:1; + /** Power-On Programming Done */ + unsigned pwronprgdone:1; + /** Reserved */ + unsigned reserved:1; + /** Global Multi Count */ + unsigned gmc:2; + /** Ignore Frame Number for ISOC EPs */ + unsigned ifrmnum:1; + /** NAK on Babble */ + unsigned nakonbble:1; + /** Enable Continue on BNA */ + unsigned encontonbna:1; + /** Enable deep sleep besl reject feature*/ + unsigned besl_reject:1; + + unsigned reserved17_31:13; + } b; +} dctl_data_t; + +/** + * This union represents the bit fields in the Device Status + * Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union dsts_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Suspend Status */ + unsigned suspsts:1; + /** Enumerated Speed */ + unsigned enumspd:2; +#define DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0 +#define DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1 +#define DWC_DSTS_ENUMSPD_LS_PHY_6MHZ 2 +#define DWC_DSTS_ENUMSPD_FS_PHY_48MHZ 3 + /** Erratic Error */ + unsigned errticerr:1; + unsigned reserved4_7:4; + /** Frame or Microframe Number of the received SOF */ + unsigned soffn:14; + unsigned reserved22_31:10; + } b; +} dsts_data_t; + +/** + * This union represents the bit fields in the Device IN EP Interrupt + * Register and the Device IN EP Common Mask Register. + * + * - Read the register into the d32 member then set/clear the + * bits using the bit elements. + */ +typedef union diepint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Transfer complete mask */ + unsigned xfercompl:1; + /** Endpoint disable mask */ + unsigned epdisabled:1; + /** AHB Error mask */ + unsigned ahberr:1; + /** TimeOUT Handshake mask (non-ISOC EPs) */ + unsigned timeout:1; + /** IN Token received with TxF Empty mask */ + unsigned intktxfemp:1; + /** IN Token Received with EP mismatch mask */ + unsigned intknepmis:1; + /** IN Endpoint NAK Effective mask */ + unsigned inepnakeff:1; + /** Reserved */ + unsigned emptyintr:1; + + unsigned txfifoundrn:1; + + /** BNA Interrupt mask */ + unsigned bna:1; + + unsigned reserved10_12:3; + /** BNA Interrupt mask */ + unsigned nak:1; + + unsigned reserved14_31:18; + } b; +} diepint_data_t; + +/** + * This union represents the bit fields in the Device IN EP + * Common/Dedicated Interrupt Mask Register. + */ +typedef union diepint_data diepmsk_data_t; + +/** + * This union represents the bit fields in the Device OUT EP Interrupt + * Registerand Device OUT EP Common Interrupt Mask Register. + * + * - Read the register into the d32 member then set/clear the + * bits using the bit elements. + */ +typedef union doepint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Transfer complete */ + unsigned xfercompl:1; + /** Endpoint disable */ + unsigned epdisabled:1; + /** AHB Error */ + unsigned ahberr:1; + /** Setup Phase Done (contorl EPs) */ + unsigned setup:1; + /** OUT Token Received when Endpoint Disabled */ + unsigned outtknepdis:1; + + unsigned stsphsercvd:1; + /** Back-to-Back SETUP Packets Received */ + unsigned back2backsetup:1; + + unsigned reserved7:1; + /** OUT packet Error */ + unsigned outpkterr:1; + /** BNA Interrupt */ + unsigned bna:1; + + unsigned reserved10:1; + /** Packet Drop Status */ + unsigned pktdrpsts:1; + /** Babble Interrupt */ + unsigned babble:1; + /** NAK Interrupt */ + unsigned nak:1; + /** NYET Interrupt */ + unsigned nyet:1; + /** Bit indicating setup packet received */ + unsigned sr:1; + + unsigned reserved16_31:16; + } b; +} doepint_data_t; + +/** + * This union represents the bit fields in the Device OUT EP + * Common/Dedicated Interrupt Mask Register. + */ +typedef union doepint_data doepmsk_data_t; + +/** + * This union represents the bit fields in the Device All EP Interrupt + * and Mask Registers. + * - Read the register into the d32 member then set/clear the + * bits using the bit elements. + */ +typedef union daint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** IN Endpoint bits */ + unsigned in:16; + /** OUT Endpoint bits */ + unsigned out:16; + } ep; + struct { + /** IN Endpoint bits */ + unsigned inep0:1; + unsigned inep1:1; + unsigned inep2:1; + unsigned inep3:1; + unsigned inep4:1; + unsigned inep5:1; + unsigned inep6:1; + unsigned inep7:1; + unsigned inep8:1; + unsigned inep9:1; + unsigned inep10:1; + unsigned inep11:1; + unsigned inep12:1; + unsigned inep13:1; + unsigned inep14:1; + unsigned inep15:1; + /** OUT Endpoint bits */ + unsigned outep0:1; + unsigned outep1:1; + unsigned outep2:1; + unsigned outep3:1; + unsigned outep4:1; + unsigned outep5:1; + unsigned outep6:1; + unsigned outep7:1; + unsigned outep8:1; + unsigned outep9:1; + unsigned outep10:1; + unsigned outep11:1; + unsigned outep12:1; + unsigned outep13:1; + unsigned outep14:1; + unsigned outep15:1; + } b; +} daint_data_t; + +/** + * This union represents the bit fields in the Device IN Token Queue + * Read Registers. + * - Read the register into the d32 member. + * - READ-ONLY Register + */ +typedef union dtknq1_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** In Token Queue Write Pointer */ + unsigned intknwptr:5; + /** Reserved */ + unsigned reserved05_06:2; + /** write pointer has wrapped. */ + unsigned wrap_bit:1; + /** EP Numbers of IN Tokens 0 ... 4 */ + unsigned epnums0_5:24; + } b; +} dtknq1_data_t; + +/** + * This union represents Threshold control Register + * - Read and write the register into the d32 member. + * - READ-WRITABLE Register + */ +typedef union dthrctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** non ISO Tx Thr. Enable */ + unsigned non_iso_thr_en:1; + /** ISO Tx Thr. Enable */ + unsigned iso_thr_en:1; + /** Tx Thr. Length */ + unsigned tx_thr_len:9; + /** AHB Threshold ratio */ + unsigned ahb_thr_ratio:2; + /** Reserved */ + unsigned reserved13_15:3; + /** Rx Thr. Enable */ + unsigned rx_thr_en:1; + /** Rx Thr. Length */ + unsigned rx_thr_len:9; + unsigned reserved26:1; + /** Arbiter Parking Enable*/ + unsigned arbprken:1; + /** Reserved */ + unsigned reserved28_31:4; + } b; +} dthrctl_data_t; + +/** + * Device Logical IN Endpoint-Specific Registers. Offsets + * 900h-AFCh + * + * There will be one set of endpoint registers per logical endpoint + * implemented. + * + * These registers are visible only in Device mode and must not be + * accessed in Host mode, as the results are unknown. + */ +typedef struct dwc_otg_dev_in_ep_regs { + /** Device IN Endpoint Control Register. Offset:900h + + * (ep_num * 20h) + 00h */ + volatile uint32_t diepctl; + /** Reserved. Offset:900h + (ep_num * 20h) + 04h */ + uint32_t reserved04; + /** Device IN Endpoint Interrupt Register. Offset:900h + + * (ep_num * 20h) + 08h */ + volatile uint32_t diepint; + /** Reserved. Offset:900h + (ep_num * 20h) + 0Ch */ + uint32_t reserved0C; + /** Device IN Endpoint Transfer Size + * Register. Offset:900h + (ep_num * 20h) + 10h */ + volatile uint32_t dieptsiz; + /** Device IN Endpoint DMA Address Register. Offset:900h + + * (ep_num * 20h) + 14h */ + volatile uint32_t diepdma; + /** Device IN Endpoint Transmit FIFO Status Register. Offset:900h + + * (ep_num * 20h) + 18h */ + volatile uint32_t dtxfsts; + /** Device IN Endpoint DMA Buffer Register. Offset:900h + + * (ep_num * 20h) + 1Ch */ + volatile uint32_t diepdmab; +} dwc_otg_dev_in_ep_regs_t; + +/** + * Device Logical OUT Endpoint-Specific Registers. Offsets: + * B00h-CFCh + * + * There will be one set of endpoint registers per logical endpoint + * implemented. + * + * These registers are visible only in Device mode and must not be + * accessed in Host mode, as the results are unknown. + */ +typedef struct dwc_otg_dev_out_ep_regs { + /** Device OUT Endpoint Control Register. Offset:B00h + + * (ep_num * 20h) + 00h */ + volatile uint32_t doepctl; + /** Reserved. Offset:B00h + (ep_num * 20h) + 04h */ + uint32_t reserved04; + /** Device OUT Endpoint Interrupt Register. Offset:B00h + + * (ep_num * 20h) + 08h */ + volatile uint32_t doepint; + /** Reserved. Offset:B00h + (ep_num * 20h) + 0Ch */ + uint32_t reserved0C; + /** Device OUT Endpoint Transfer Size Register. Offset: + * B00h + (ep_num * 20h) + 10h */ + volatile uint32_t doeptsiz; + /** Device OUT Endpoint DMA Address Register. Offset:B00h + * + (ep_num * 20h) + 14h */ + volatile uint32_t doepdma; + /** Reserved. Offset:B00h + * (ep_num * 20h) + 18h */ + uint32_t unused; + /** Device OUT Endpoint DMA Buffer Register. Offset:B00h + * + (ep_num * 20h) + 1Ch */ + uint32_t doepdmab; +} dwc_otg_dev_out_ep_regs_t; + +/** + * This union represents the bit fields in the Device EP Control + * Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union depctl_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Maximum Packet Size + * IN/OUT EPn + * IN/OUT EP0 - 2 bits + * 2'b00: 64 Bytes + * 2'b01: 32 + * 2'b10: 16 + * 2'b11: 8 */ + unsigned mps:11; +#define DWC_DEP0CTL_MPS_64 0 +#define DWC_DEP0CTL_MPS_32 1 +#define DWC_DEP0CTL_MPS_16 2 +#define DWC_DEP0CTL_MPS_8 3 + + /** Next Endpoint + * IN EPn/IN EP0 + * OUT EPn/OUT EP0 - reserved */ + unsigned nextep:4; + + /** USB Active Endpoint */ + unsigned usbactep:1; + + /** Endpoint DPID (INTR/Bulk IN and OUT endpoints) + * This field contains the PID of the packet going to + * be received or transmitted on this endpoint. The + * application should program the PID of the first + * packet going to be received or transmitted on this + * endpoint , after the endpoint is + * activated. Application use the SetD1PID and + * SetD0PID fields of this register to program either + * D0 or D1 PID. + * + * The encoding for this field is + * - 0: D0 + * - 1: D1 + */ + unsigned dpid:1; + + /** NAK Status */ + unsigned naksts:1; + + /** Endpoint Type + * 2'b00: Control + * 2'b01: Isochronous + * 2'b10: Bulk + * 2'b11: Interrupt */ + unsigned eptype:2; + + /** Snoop Mode + * OUT EPn/OUT EP0 + * IN EPn/IN EP0 - reserved */ + unsigned snp:1; + + /** Stall Handshake */ + unsigned stall:1; + + /** Tx Fifo Number + * IN EPn/IN EP0 + * OUT EPn/OUT EP0 - reserved */ + unsigned txfnum:4; + + /** Clear NAK */ + unsigned cnak:1; + /** Set NAK */ + unsigned snak:1; + /** Set DATA0 PID (INTR/Bulk IN and OUT endpoints) + * Writing to this field sets the Endpoint DPID (DPID) + * field in this register to DATA0. Set Even + * (micro)frame (SetEvenFr) (ISO IN and OUT Endpoints) + * Writing to this field sets the Even/Odd + * (micro)frame (EO_FrNum) field to even (micro) + * frame. + */ + unsigned setd0pid:1; + /** Set DATA1 PID (INTR/Bulk IN and OUT endpoints) + * Writing to this field sets the Endpoint DPID (DPID) + * field in this register to DATA1 Set Odd + * (micro)frame (SetOddFr) (ISO IN and OUT Endpoints) + * Writing to this field sets the Even/Odd + * (micro)frame (EO_FrNum) field to odd (micro) frame. + */ + unsigned setd1pid:1; + + /** Endpoint Disable */ + unsigned epdis:1; + /** Endpoint Enable */ + unsigned epena:1; + } b; +} depctl_data_t; + +/** + * This union represents the bit fields in the Device EP Transfer + * Size Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union deptsiz_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Transfer size */ + unsigned xfersize:19; +/** Max packet count for EP (pow(2,10)-1) */ +#define MAX_PKT_CNT 1023 + /** Packet Count */ + unsigned pktcnt:10; + /** Multi Count - Periodic IN endpoints */ + unsigned mc:2; + unsigned reserved:1; + } b; +} deptsiz_data_t; + +/** + * This union represents the bit fields in the Device EP 0 Transfer + * Size Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union deptsiz0_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Transfer size */ + unsigned xfersize:7; + /** Reserved */ + unsigned reserved7_18:12; + /** Packet Count */ + unsigned pktcnt:2; + /** Reserved */ + unsigned reserved21_28:8; + /**Setup Packet Count (DOEPTSIZ0 Only) */ + unsigned supcnt:2; + unsigned reserved31; + } b; +} deptsiz0_data_t; + +///////////////////////////////////////////////// +// DMA Descriptor Specific Structures +// + +/** Buffer status definitions */ + +#define BS_HOST_READY 0x0 +#define BS_DMA_BUSY 0x1 +#define BS_DMA_DONE 0x2 +#define BS_HOST_BUSY 0x3 + +/** Receive/Transmit status definitions */ + +#define RTS_SUCCESS 0x0 +#define RTS_BUFFLUSH 0x1 +#define RTS_RESERVED 0x2 +#define RTS_BUFERR 0x3 + +/** + * This union represents the bit fields in the DMA Descriptor + * status quadlet. Read the quadlet into the d32 member then + * set/clear the bits using the bit, b_iso_out and + * b_iso_in elements. + */ +typedef union dev_dma_desc_sts { + /** raw register data */ + uint32_t d32; + /** quadlet bits */ + struct { + /** Received number of bytes */ + unsigned bytes:16; + /** NAK bit - only for OUT EPs */ + unsigned nak:1; + unsigned reserved17_22:6; + /** Multiple Transfer - only for OUT EPs */ + unsigned mtrf:1; + /** Setup Packet received - only for OUT EPs */ + unsigned sr:1; + /** Interrupt On Complete */ + unsigned ioc:1; + /** Short Packet */ + unsigned sp:1; + /** Last */ + unsigned l:1; + /** Receive Status */ + unsigned sts:2; + /** Buffer Status */ + unsigned bs:2; + } b; + +//#ifdef DWC_EN_ISOC + /** iso out quadlet bits */ + struct { + /** Received number of bytes */ + unsigned rxbytes:11; + + unsigned reserved11:1; + /** Frame Number */ + unsigned framenum:11; + /** Received ISO Data PID */ + unsigned pid:2; + /** Interrupt On Complete */ + unsigned ioc:1; + /** Short Packet */ + unsigned sp:1; + /** Last */ + unsigned l:1; + /** Receive Status */ + unsigned rxsts:2; + /** Buffer Status */ + unsigned bs:2; + } b_iso_out; + + /** iso in quadlet bits */ + struct { + /** Transmited number of bytes */ + unsigned txbytes:12; + /** Frame Number */ + unsigned framenum:11; + /** Transmited ISO Data PID */ + unsigned pid:2; + /** Interrupt On Complete */ + unsigned ioc:1; + /** Short Packet */ + unsigned sp:1; + /** Last */ + unsigned l:1; + /** Transmit Status */ + unsigned txsts:2; + /** Buffer Status */ + unsigned bs:2; + } b_iso_in; +//#endif /* DWC_EN_ISOC */ +} dev_dma_desc_sts_t; + +/** + * DMA Descriptor structure + * + * DMA Descriptor structure contains two quadlets: + * Status quadlet and Data buffer pointer. + */ +typedef struct dwc_otg_dev_dma_desc { + /** DMA Descriptor status quadlet */ + dev_dma_desc_sts_t status; + /** DMA Descriptor data buffer pointer */ + uint32_t buf; +} dwc_otg_dev_dma_desc_t; + +/** + * The dwc_otg_dev_if structure contains information needed to manage + * the DWC_otg controller acting in device mode. It represents the + * programming view of the device-specific aspects of the controller. + */ +typedef struct dwc_otg_dev_if { + /** Pointer to device Global registers. + * Device Global Registers starting at offset 800h + */ + dwc_otg_device_global_regs_t *dev_global_regs; +#define DWC_DEV_GLOBAL_REG_OFFSET 0x800 + + /** + * Device Logical IN Endpoint-Specific Registers 900h-AFCh + */ + dwc_otg_dev_in_ep_regs_t *in_ep_regs[MAX_EPS_CHANNELS]; +#define DWC_DEV_IN_EP_REG_OFFSET 0x900 +#define DWC_EP_REG_OFFSET 0x20 + + /** Device Logical OUT Endpoint-Specific Registers B00h-CFCh */ + dwc_otg_dev_out_ep_regs_t *out_ep_regs[MAX_EPS_CHANNELS]; +#define DWC_DEV_OUT_EP_REG_OFFSET 0xB00 + + /* Device configuration information */ + uint8_t speed; /**< Device Speed 0: Unknown, 1: LS, 2:FS, 3: HS */ + uint8_t num_in_eps; /**< Number # of Tx EP range: 0-15 exept ep0 */ + uint8_t num_out_eps; /**< Number # of Rx EP range: 0-15 exept ep 0*/ + + /** Size of periodic FIFOs (Bytes) */ + uint16_t perio_tx_fifo_size[MAX_PERIO_FIFOS]; + + /** Size of Tx FIFOs (Bytes) */ + uint16_t tx_fifo_size[MAX_TX_FIFOS]; + + /** Thresholding enable flags and length varaiables **/ + uint16_t rx_thr_en; + uint16_t iso_tx_thr_en; + uint16_t non_iso_tx_thr_en; + + uint16_t rx_thr_length; + uint16_t tx_thr_length; + + /** + * Pointers to the DMA Descriptors for EP0 Control + * transfers (virtual and physical) + */ + + /** 2 descriptors for SETUP packets */ + dwc_dma_t dma_setup_desc_addr[2]; + dwc_otg_dev_dma_desc_t *setup_desc_addr[2]; + + /** Pointer to Descriptor with latest SETUP packet */ + dwc_otg_dev_dma_desc_t *psetup; + + /** Index of current SETUP handler descriptor */ + uint32_t setup_desc_index; + + /** Descriptor for Data In or Status In phases */ + dwc_dma_t dma_in_desc_addr; + dwc_otg_dev_dma_desc_t *in_desc_addr; + + /** Descriptor for Data Out or Status Out phases */ + dwc_dma_t dma_out_desc_addr; + dwc_otg_dev_dma_desc_t *out_desc_addr; + + /** Setup Packet Detected - if set clear NAK when queueing */ + uint32_t spd; + /** Isoc ep pointer on which incomplete happens */ + void *isoc_ep; + +} dwc_otg_dev_if_t; + +///////////////////////////////////////////////// +// Host Mode Register Structures +// +/** + * The Host Global Registers structure defines the size and relative + * field offsets for the Host Mode Global Registers. Host Global + * Registers offsets 400h-7FFh. +*/ +typedef struct dwc_otg_host_global_regs { + /** Host Configuration Register. Offset: 400h */ + volatile uint32_t hcfg; + /** Host Frame Interval Register. Offset: 404h */ + volatile uint32_t hfir; + /** Host Frame Number / Frame Remaining Register. Offset: 408h */ + volatile uint32_t hfnum; + /** Reserved. Offset: 40Ch */ + uint32_t reserved40C; + /** Host Periodic Transmit FIFO/ Queue Status Register. Offset: 410h */ + volatile uint32_t hptxsts; + /** Host All Channels Interrupt Register. Offset: 414h */ + volatile uint32_t haint; + /** Host All Channels Interrupt Mask Register. Offset: 418h */ + volatile uint32_t haintmsk; + /** Host Frame List Base Address Register . Offset: 41Ch */ + volatile uint32_t hflbaddr; +} dwc_otg_host_global_regs_t; + +/** + * This union represents the bit fields in the Host Configuration Register. + * Read the register into the d32 member then set/clear the bits using + * the bit elements. Write the d32 member to the hcfg register. + */ +typedef union hcfg_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** FS/LS Phy Clock Select */ + unsigned fslspclksel:2; +#define DWC_HCFG_30_60_MHZ 0 +#define DWC_HCFG_48_MHZ 1 +#define DWC_HCFG_6_MHZ 2 + + /** FS/LS Only Support */ + unsigned fslssupp:1; + unsigned reserved3_6:4; + /** Enable 32-KHz Suspend Mode */ + unsigned ena32khzs:1; + /** Resume Validation Periiod */ + unsigned resvalid:8; + unsigned reserved16_22:7; + /** Enable Scatter/gather DMA in Host mode */ + unsigned descdma:1; + /** Frame List Entries */ + unsigned frlisten:2; + /** Enable Periodic Scheduling */ + unsigned perschedena:1; + unsigned reserved27_30:4; + unsigned modechtimen:1; + } b; +} hcfg_data_t; + +/** + * This union represents the bit fields in the Host Frame Remaing/Number + * Register. + */ +typedef union hfir_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + unsigned frint:16; + unsigned hfirrldctrl:1; + unsigned reserved:15; + } b; +} hfir_data_t; + +/** + * This union represents the bit fields in the Host Frame Remaing/Number + * Register. + */ +typedef union hfnum_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + unsigned frnum:16; +#define DWC_HFNUM_MAX_FRNUM 0x3FFF + unsigned frrem:16; + } b; +} hfnum_data_t; + +typedef union hptxsts_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + unsigned ptxfspcavail:16; + unsigned ptxqspcavail:8; + /** Top of the Periodic Transmit Request Queue + * - bit 24 - Terminate (last entry for the selected channel) + * - bits 26:25 - Token Type + * - 2'b00 - Zero length + * - 2'b01 - Ping + * - 2'b10 - Disable + * - bits 30:27 - Channel Number + * - bit 31 - Odd/even microframe + */ + unsigned ptxqtop_terminate:1; + unsigned ptxqtop_token:2; + unsigned ptxqtop_chnum:4; + unsigned ptxqtop_odd:1; + } b; +} hptxsts_data_t; + +/** + * This union represents the bit fields in the Host Port Control and Status + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. Write the d32 member to the + * hprt0 register. + */ +typedef union hprt0_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned prtconnsts:1; + unsigned prtconndet:1; + unsigned prtena:1; + unsigned prtenchng:1; + unsigned prtovrcurract:1; + unsigned prtovrcurrchng:1; + unsigned prtres:1; + unsigned prtsusp:1; + unsigned prtrst:1; + unsigned reserved9:1; + unsigned prtlnsts:2; + unsigned prtpwr:1; + unsigned prttstctl:4; + unsigned prtspd:2; +#define DWC_HPRT0_PRTSPD_HIGH_SPEED 0 +#define DWC_HPRT0_PRTSPD_FULL_SPEED 1 +#define DWC_HPRT0_PRTSPD_LOW_SPEED 2 + unsigned reserved19_31:13; + } b; +} hprt0_data_t; + +/** + * This union represents the bit fields in the Host All Interrupt + * Register. + */ +typedef union haint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned ch0:1; + unsigned ch1:1; + unsigned ch2:1; + unsigned ch3:1; + unsigned ch4:1; + unsigned ch5:1; + unsigned ch6:1; + unsigned ch7:1; + unsigned ch8:1; + unsigned ch9:1; + unsigned ch10:1; + unsigned ch11:1; + unsigned ch12:1; + unsigned ch13:1; + unsigned ch14:1; + unsigned ch15:1; + unsigned reserved:16; + } b; + + struct { + unsigned chint:16; + unsigned reserved:16; + } b2; +} haint_data_t; + +/** + * This union represents the bit fields in the Host All Interrupt + * Register. + */ +typedef union haintmsk_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned ch0:1; + unsigned ch1:1; + unsigned ch2:1; + unsigned ch3:1; + unsigned ch4:1; + unsigned ch5:1; + unsigned ch6:1; + unsigned ch7:1; + unsigned ch8:1; + unsigned ch9:1; + unsigned ch10:1; + unsigned ch11:1; + unsigned ch12:1; + unsigned ch13:1; + unsigned ch14:1; + unsigned ch15:1; + unsigned reserved:16; + } b; + + struct { + unsigned chint:16; + unsigned reserved:16; + } b2; +} haintmsk_data_t; + +/** + * Host Channel Specific Registers. 500h-5FCh + */ +typedef struct dwc_otg_hc_regs { + /** Host Channel 0 Characteristic Register. Offset: 500h + (chan_num * 20h) + 00h */ + volatile uint32_t hcchar; + /** Host Channel 0 Split Control Register. Offset: 500h + (chan_num * 20h) + 04h */ + volatile uint32_t hcsplt; + /** Host Channel 0 Interrupt Register. Offset: 500h + (chan_num * 20h) + 08h */ + volatile uint32_t hcint; + /** Host Channel 0 Interrupt Mask Register. Offset: 500h + (chan_num * 20h) + 0Ch */ + volatile uint32_t hcintmsk; + /** Host Channel 0 Transfer Size Register. Offset: 500h + (chan_num * 20h) + 10h */ + volatile uint32_t hctsiz; + /** Host Channel 0 DMA Address Register. Offset: 500h + (chan_num * 20h) + 14h */ + volatile uint32_t hcdma; + volatile uint32_t reserved; + /** Host Channel 0 DMA Buffer Address Register. Offset: 500h + (chan_num * 20h) + 1Ch */ + volatile uint32_t hcdmab; +} dwc_otg_hc_regs_t; + +/** + * This union represents the bit fields in the Host Channel Characteristics + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. Write the d32 member to the + * hcchar register. + */ +typedef union hcchar_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** Maximum packet size in bytes */ + unsigned mps:11; + + /** Endpoint number */ + unsigned epnum:4; + + /** 0: OUT, 1: IN */ + unsigned epdir:1; + + unsigned reserved:1; + + /** 0: Full/high speed device, 1: Low speed device */ + unsigned lspddev:1; + + /** 0: Control, 1: Isoc, 2: Bulk, 3: Intr */ + unsigned eptype:2; + + /** Packets per frame for periodic transfers. 0 is reserved. */ + unsigned multicnt:2; + + /** Device address */ + unsigned devaddr:7; + + /** + * Frame to transmit periodic transaction. + * 0: even, 1: odd + */ + unsigned oddfrm:1; + + /** Channel disable */ + unsigned chdis:1; + + /** Channel enable */ + unsigned chen:1; + } b; +} hcchar_data_t; + +typedef union hcsplt_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** Port Address */ + unsigned prtaddr:7; + + /** Hub Address */ + unsigned hubaddr:7; + + /** Transaction Position */ + unsigned xactpos:2; +#define DWC_HCSPLIT_XACTPOS_MID 0 +#define DWC_HCSPLIT_XACTPOS_END 1 +#define DWC_HCSPLIT_XACTPOS_BEGIN 2 +#define DWC_HCSPLIT_XACTPOS_ALL 3 + + /** Do Complete Split */ + unsigned compsplt:1; + + /** Reserved */ + unsigned reserved:14; + + /** Split Enble */ + unsigned spltena:1; + } b; +} hcsplt_data_t; + +/** + * This union represents the bit fields in the Host All Interrupt + * Register. + */ +typedef union hcint_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** Transfer Complete */ + unsigned xfercomp:1; + /** Channel Halted */ + unsigned chhltd:1; + /** AHB Error */ + unsigned ahberr:1; + /** STALL Response Received */ + unsigned stall:1; + /** NAK Response Received */ + unsigned nak:1; + /** ACK Response Received */ + unsigned ack:1; + /** NYET Response Received */ + unsigned nyet:1; + /** Transaction Err */ + unsigned xacterr:1; + /** Babble Error */ + unsigned bblerr:1; + /** Frame Overrun */ + unsigned frmovrun:1; + /** Data Toggle Error */ + unsigned datatglerr:1; + /** Buffer Not Available (only for DDMA mode) */ + unsigned bna:1; + /** Exessive transaction error (only for DDMA mode) */ + unsigned xcs_xact:1; + /** Frame List Rollover interrupt */ + unsigned frm_list_roll:1; + /** Reserved */ + unsigned reserved14_31:18; + } b; +} hcint_data_t; + +/** + * This union represents the bit fields in the Host Channel Interrupt Mask + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. Write the d32 member to the + * hcintmsk register. + */ +typedef union hcintmsk_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + unsigned xfercompl:1; + unsigned chhltd:1; + unsigned ahberr:1; + unsigned stall:1; + unsigned nak:1; + unsigned ack:1; + unsigned nyet:1; + unsigned xacterr:1; + unsigned bblerr:1; + unsigned frmovrun:1; + unsigned datatglerr:1; + unsigned bna:1; + unsigned xcs_xact:1; + unsigned frm_list_roll:1; + unsigned reserved14_31:18; + } b; +} hcintmsk_data_t; + +/** + * This union represents the bit fields in the Host Channel Transfer Size + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. Write the d32 member to the + * hcchar register. + */ + +typedef union hctsiz_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** Total transfer size in bytes */ + unsigned xfersize:19; + + /** Data packets to transfer */ + unsigned pktcnt:10; + + /** + * Packet ID for next data packet + * 0: DATA0 + * 1: DATA2 + * 2: DATA1 + * 3: MDATA (non-Control), SETUP (Control) + */ + unsigned pid:2; +#define DWC_HCTSIZ_DATA0 0 +#define DWC_HCTSIZ_DATA1 2 +#define DWC_HCTSIZ_DATA2 1 +#define DWC_HCTSIZ_MDATA 3 +#define DWC_HCTSIZ_SETUP 3 + + /** Do PING protocol when 1 */ + unsigned dopng:1; + } b; + + /** register bits */ + struct { + /** Scheduling information */ + unsigned schinfo:8; + + /** Number of transfer descriptors. + * Max value: + * 64 in general, + * 256 only for HS isochronous endpoint. + */ + unsigned ntd:8; + + /** Data packets to transfer */ + unsigned reserved16_28:13; + + /** + * Packet ID for next data packet + * 0: DATA0 + * 1: DATA2 + * 2: DATA1 + * 3: MDATA (non-Control) + */ + unsigned pid:2; + + /** Do PING protocol when 1 */ + unsigned dopng:1; + } b_ddma; +} hctsiz_data_t; + +/** + * This union represents the bit fields in the Host DMA Address + * Register used in Descriptor DMA mode. + */ +typedef union hcdma_data { + /** raw register data */ + uint32_t d32; + /** register bits */ + struct { + unsigned reserved0_2:3; + /** Current Transfer Descriptor. Not used for ISOC */ + unsigned ctd:8; + /** Start Address of Descriptor List */ + unsigned dma_addr:21; + } b; +} hcdma_data_t; + +/** + * This union represents the bit fields in the DMA Descriptor + * status quadlet for host mode. Read the quadlet into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union host_dma_desc_sts { + /** raw register data */ + uint32_t d32; + /** quadlet bits */ + + /* for non-isochronous */ + struct { + /** Number of bytes */ + unsigned n_bytes:17; + /** QTD offset to jump when Short Packet received - only for IN EPs */ + unsigned qtd_offset:6; + /** + * Set to request the core to jump to alternate QTD if + * Short Packet received - only for IN EPs + */ + unsigned a_qtd:1; + /** + * Setup Packet bit. When set indicates that buffer contains + * setup packet. + */ + unsigned sup:1; + /** Interrupt On Complete */ + unsigned ioc:1; + /** End of List */ + unsigned eol:1; + unsigned reserved27:1; + /** Rx/Tx Status */ + unsigned sts:2; +#define DMA_DESC_STS_PKTERR 1 + unsigned reserved30:1; + /** Active Bit */ + unsigned a:1; + } b; + /* for isochronous */ + struct { + /** Number of bytes */ + unsigned n_bytes:12; + unsigned reserved12_24:13; + /** Interrupt On Complete */ + unsigned ioc:1; + unsigned reserved26_27:2; + /** Rx/Tx Status */ + unsigned sts:2; + unsigned reserved30:1; + /** Active Bit */ + unsigned a:1; + } b_isoc; +} host_dma_desc_sts_t; + +#define MAX_DMA_DESC_SIZE 131071 +#define MAX_DMA_DESC_NUM_GENERIC 64 +#define MAX_DMA_DESC_NUM_HS_ISOC 256 +#define MAX_FRLIST_EN_NUM 64 +/** + * Host-mode DMA Descriptor structure + * + * DMA Descriptor structure contains two quadlets: + * Status quadlet and Data buffer pointer. + */ +typedef struct dwc_otg_host_dma_desc { + /** DMA Descriptor status quadlet */ + host_dma_desc_sts_t status; + /** DMA Descriptor data buffer pointer */ + uint32_t buf; +} dwc_otg_host_dma_desc_t; + +/** OTG Host Interface Structure. + * + * The OTG Host Interface Structure structure contains information + * needed to manage the DWC_otg controller acting in host mode. It + * represents the programming view of the host-specific aspects of the + * controller. + */ +typedef struct dwc_otg_host_if { + /** Host Global Registers starting at offset 400h.*/ + dwc_otg_host_global_regs_t *host_global_regs; +#define DWC_OTG_HOST_GLOBAL_REG_OFFSET 0x400 + + /** Host Port 0 Control and Status Register */ + volatile uint32_t *hprt0; +#define DWC_OTG_HOST_PORT_REGS_OFFSET 0x440 + + /** Host Channel Specific Registers at offsets 500h-5FCh. */ + dwc_otg_hc_regs_t *hc_regs[MAX_EPS_CHANNELS]; +#define DWC_OTG_HOST_CHAN_REGS_OFFSET 0x500 +#define DWC_OTG_CHAN_REGS_OFFSET 0x20 + + /* Host configuration information */ + /** Number of Host Channels (range: 1-16) */ + uint8_t num_host_channels; + /** Periodic EPs supported (0: no, 1: yes) */ + uint8_t perio_eps_supported; + /** Periodic Tx FIFO Size (Only 1 host periodic Tx FIFO) */ + uint16_t perio_tx_fifo_size; + +} dwc_otg_host_if_t; + +/** + * This union represents the bit fields in the Power and Clock Gating Control + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. + */ +typedef union pcgcctl_data { + /** raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** Stop Pclk */ + unsigned stoppclk:1; + /** Gate Hclk */ + unsigned gatehclk:1; + /** Power Clamp */ + unsigned pwrclmp:1; + /** Reset Power Down Modules */ + unsigned rstpdwnmodule:1; + /** Reserved */ + unsigned reserved:1; + /** Enable Sleep Clock Gating (Enbl_L1Gating) */ + unsigned enbl_sleep_gating:1; + /** PHY In Sleep (PhySleep) */ + unsigned phy_in_sleep:1; + /** Deep Sleep*/ + unsigned deep_sleep:1; + unsigned resetaftsusp:1; + unsigned restoremode:1; + unsigned enbl_extnd_hiber:1; + unsigned extnd_hiber_pwrclmp:1; + unsigned extnd_hiber_switch:1; + unsigned ess_reg_restored:1; + unsigned prt_clk_sel:2; + unsigned port_power:1; + unsigned max_xcvrselect:2; + unsigned max_termsel:1; + unsigned mac_dev_addr:7; + unsigned p2hd_dev_enum_spd:2; + unsigned p2hd_prt_spd:2; + unsigned if_dev_mode:1; + } b; +} pcgcctl_data_t; + +/** + * This union represents the bit fields in the Global Data FIFO Software + * Configuration Register. Read the register into the d32 member then + * set/clear the bits using the bit elements. + */ +typedef union gdfifocfg_data { + /* raw register data */ + uint32_t d32; + /** register bits */ + struct { + /** OTG Data FIFO depth */ + unsigned gdfifocfg:16; + /** Start address of EP info controller */ + unsigned epinfobase:16; + } b; +} gdfifocfg_data_t; + +/** + * This union represents the bit fields in the Global Power Down Register + * Register. Read the register into the d32 member then set/clear the + * bits using the bit elements. + */ +typedef union gpwrdn_data { + /* raw register data */ + uint32_t d32; + + /** register bits */ + struct { + /** PMU Interrupt Select */ + unsigned pmuintsel:1; + /** PMU Active */ + unsigned pmuactv:1; + /** Restore */ + unsigned restore:1; + /** Power Down Clamp */ + unsigned pwrdnclmp:1; + /** Power Down Reset */ + unsigned pwrdnrstn:1; + /** Power Down Switch */ + unsigned pwrdnswtch:1; + /** Disable VBUS */ + unsigned dis_vbus:1; + /** Line State Change */ + unsigned lnstschng:1; + /** Line state change mask */ + unsigned lnstchng_msk:1; + /** Reset Detected */ + unsigned rst_det:1; + /** Reset Detect mask */ + unsigned rst_det_msk:1; + /** Disconnect Detected */ + unsigned disconn_det:1; + /** Disconnect Detect mask */ + unsigned disconn_det_msk:1; + /** Connect Detected*/ + unsigned connect_det:1; + /** Connect Detected Mask*/ + unsigned connect_det_msk:1; + /** SRP Detected */ + unsigned srp_det:1; + /** SRP Detect mask */ + unsigned srp_det_msk:1; + /** Status Change Interrupt */ + unsigned sts_chngint:1; + /** Status Change Interrupt Mask */ + unsigned sts_chngint_msk:1; + /** Line State */ + unsigned linestate:2; + /** Indicates current mode(status of IDDIG signal) */ + unsigned idsts:1; + /** B Session Valid signal status*/ + unsigned bsessvld:1; + /** ADP Event Detected */ + unsigned adp_int:1; + /** Multi Valued ID pin */ + unsigned mult_val_id_bc:5; + /** Reserved 24_31 */ + unsigned reserved29_31:3; + } b; +} gpwrdn_data_t; + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/errno.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/errno.h new file mode 100644 index 0000000..2fbccce --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/errno.h @@ -0,0 +1,149 @@ +#ifndef _GENERIC_ERRNO_H +#define _GENERIC_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#define ERFKILL 132 /* Operation not possible due to RF-kill */ + +#define EHWPOISON 133 /* Memory page has hardware error */ + + +#define ENOTSUPP 524 /* Operation is not supported */ + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hal_otg.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hal_otg.h new file mode 100644 index 0000000..5c0f669 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hal_otg.h @@ -0,0 +1,21 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _HAL_OTG_H_ +#define _HAL_OTG_H_ + +#include "rtl8195a_otg.h" +#include "dwc_otg_regs.h" + + + + + + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hcd.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hcd.h new file mode 100644 index 0000000..d261441 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/hcd.h @@ -0,0 +1,164 @@ +#ifndef _HCD_H_ +#define _HCD_H_ + + +struct hc_driver { + const char *description; /* "ehci-hcd" etc */ +const char *product_desc; /* product/vendor string */ +size_t hcd_priv_size; /* size of private data */ + +/* irq handler */ +//irqreturn_t (*irq) (struct usb_hcd *hcd); + +int flags; +#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ +#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ +#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ +#define HCD_USB11 0x0010 /* USB 1.1 */ +#define HCD_USB2 0x0020 /* USB 2.0 */ +#define HCD_USB3 0x0040 /* USB 3.0 */ +#define HCD_MASK 0x0070 + + /* called to init HCD and root hub */ + int (*reset) (struct usb_hcd *hcd); + int (*start) (struct usb_hcd *hcd); + + /* NOTE: these suspend/resume calls relate to the HC as + * a whole, not just the root hub; they're for PCI bus glue. + */ + /* called after suspending the hub, before entering D3 etc */ +// int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup); + + /* called after entering D0 (etc), before resuming the hub */ +// int (*pci_resume)(struct usb_hcd *hcd, bool hibernated); + + /* cleanly make HCD stop writing memory and doing I/O */ + void (*stop) (struct usb_hcd *hcd); + + /* shutdown HCD */ + // void (*shutdown) (struct usb_hcd *hcd); + + /* return current frame number */ + int (*get_frame_number) (struct usb_hcd *hcd); + + /* manage i/o requests, device state */ + int (*urb_enqueue)(struct usb_hcd *hcd, + struct urb *urb);//, gfp_t mem_flags); + int (*urb_dequeue)(struct usb_hcd *hcd, + struct urb *urb, int status); + + /* + * (optional) these hooks allow an HCD to override the default DMA + * mapping and unmapping routines. In general, they shouldn't be + * necessary unless the host controller has special DMA requirements, + * such as alignment contraints. If these are not specified, the + * general usb_hcd_(un)?map_urb_for_dma functions will be used instead + * (and it may be a good idea to call these functions in your HCD + * implementation) + */ + #if 0 + int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb, + gfp_t mem_flags); + void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb); + #endif + /* hw synch, freeing endpoint resources that urb_dequeue can't */ + void (*endpoint_disable)(struct usb_hcd *hcd, + struct usb_host_endpoint *ep); + + /* (optional) reset any endpoint state such as sequence number + and current window */ + void (*endpoint_reset)(struct usb_hcd *hcd, + struct usb_host_endpoint *ep); + + /* root hub support */ + int (*hub_status_data) (struct usb_hcd *hcd, char *buf); + int (*hub_control) (struct usb_hcd *hcd, + u16 typeReq, u16 wValue, u16 wIndex, + char *buf, u16 wLength); + #if 0 + int (*bus_suspend)(struct usb_hcd *); + int (*bus_resume)(struct usb_hcd *); + int (*start_port_reset)(struct usb_hcd *, unsigned port_num); + + /* force handover of high-speed port to full-speed companion */ + void (*relinquish_port)(struct usb_hcd *, int); + /* has a port been handed over to a companion? */ + int (*port_handed_over)(struct usb_hcd *, int); + + /* CLEAR_TT_BUFFER completion callback */ + void (*clear_tt_buffer_complete)(struct usb_hcd *, + struct usb_host_endpoint *); + + /* xHCI specific functions */ + /* Called by usb_alloc_dev to alloc HC device structures */ + int (*alloc_dev)(struct usb_hcd *, struct usb_device *); + /* Called by usb_disconnect to free HC device structures */ + void (*free_dev)(struct usb_hcd *, struct usb_device *); + /* Change a group of bulk endpoints to support multiple stream IDs */ + int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint **eps, unsigned int num_eps, + unsigned int num_streams, gfp_t mem_flags); + /* Reverts a group of bulk endpoints back to not using stream IDs. + * Can fail if we run out of memory. + */ + int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev, + struct usb_host_endpoint **eps, unsigned int num_eps, + gfp_t mem_flags); + + /* Bandwidth computation functions */ + /* Note that add_endpoint() can only be called once per endpoint before + * check_bandwidth() or reset_bandwidth() must be called. + * drop_endpoint() can only be called once per endpoint also. + * A call to xhci_drop_endpoint() followed by a call to + * xhci_add_endpoint() will add the endpoint to the schedule with + * possibly new parameters denoted by a different endpoint descriptor + * in usb_host_endpoint. A call to xhci_add_endpoint() followed by a + * call to xhci_drop_endpoint() is not allowed. + */ + /* Allocate endpoint resources and add them to a new schedule */ + int (*add_endpoint)(struct usb_hcd *, struct usb_device *, + struct usb_host_endpoint *); + /* Drop an endpoint from a new schedule */ + int (*drop_endpoint)(struct usb_hcd *, struct usb_device *, + struct usb_host_endpoint *); + /* Check that a new hardware configuration, set using + * endpoint_enable and endpoint_disable, does not exceed bus + * bandwidth. This must be called before any set configuration + * or set interface requests are sent to the device. + */ + int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); + /* Reset the device schedule to the last known good schedule, + * which was set from a previous successful call to + * check_bandwidth(). This reverts any add_endpoint() and + * drop_endpoint() calls since that last successful call. + * Used for when a check_bandwidth() call fails due to resource + * or bandwidth constraints. + */ + void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); + /* Returns the hardware-chosen device address */ + int (*address_device)(struct usb_hcd *, struct usb_device *udev); + /* Notifies the HCD after a hub descriptor is fetched. + * Will block. + */ + int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags); + int (*reset_device)(struct usb_hcd *, struct usb_device *); + /* Notifies the HCD after a device is connected and its + * address is set + */ + int (*update_device)(struct usb_hcd *, struct usb_device *); + int (*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int); + /* USB 3.0 Link Power Management */ + /* Returns the USB3 hub-encoded value for the U1/U2 timeout. */ + int (*enable_usb3_lpm_timeout)(struct usb_hcd *, + struct usb_device *, enum usb3_link_state state); + /* The xHCI host controller can still fail the command to + * disable the LPM timeouts, so this can return an error code. + */ + int (*disable_usb3_lpm_timeout)(struct usb_hcd *, + struct usb_device *, enum usb3_link_state state); + int (*find_raw_port_number)(struct usb_hcd *, int); + #endif +}; + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/rtl8195a_otg.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/rtl8195a_otg.h new file mode 100644 index 0000000..2d9c884 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/rtl8195a_otg.h @@ -0,0 +1,134 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_OTG_H_ +#define _RTL8195A_OTG_H_ + +#include "rtl8195a.h" +#define OTG_FAST_INIT 1 + +#define HAL_OTG_READ32(addr) HAL_READ32(USB_OTG_REG_BASE, (u32)addr) +#define HAL_OTG_WRITE32(addr, value) HAL_WRITE32(USB_OTG_REG_BASE, (u32)addr, value) + +#define HAL_OTG_MODIFY32(addr, clrmsk, setmsk) HAL_WRITE32(USB_OTG_REG_BASE,(u32)addr,\ + ((HAL_READ32(USB_OTG_REG_BASE, (u32)addr) & (~clrmsk)) | setmsk)) + +#define DWC_READ_REG32(_reg_) HAL_OTG_READ32((u32)_reg_) +#define DWC_WRITE_REG32(_reg_, _val_) HAL_OTG_WRITE32((u32)_reg_,_val_) +#define DWC_MODIFY_REG32(_reg_,_cmsk_,_smsk_) HAL_OTG_MODIFY32((u32)_reg_,_cmsk_,_smsk_) + + +//This part is added for RTK power sequence + +//3 SYS_ON reg + +//#define REG_SYS_FUNC_EN 0x08 +#define BIT_SHIFT_SOC_SYSPEON_EN 4 +#define BIT_MASK_SOC_SYSPEON_EN 0x1 +#define BIT_SOC_SYSPEON_EN_OTG(x)(((x) & BIT_MASK_SOC_SYSPEON_EN) << BIT_SHIFT_SOC_SYSPEON_EN) +#define BIT_INVC_SOC_SYSPEON_EN (~(BIT_MASK_SOC_SYSPEON_EN << BIT_SHIFT_SOC_SYSPEON_EN)) + + +//3 Peri_ON reg +#define REG_OTG_PWCSEQ_OFFSET_OTG 0x40000000 +#define REG_OTG_PWCSEQ_PWC_OTG 0x200 +#define REG_OTG_PWCSEQ_ISO_OTG 0x204 +#define REG_SOC_HCI_COM_FUNC_EN_OTG 0x214 +#define REG_PESOC_HCI_CLK_CTRL0_OTG 0x240 + +//#define REG_PON_ISO_CTRL 0x204 + + +#define REG_OTG_PWCSEQ_IP_OFF 0x30004 //This is in OTG IP +#define REG_OTG_PS_INTR_STS 0x30008 //This is in OTG IP +#define REG_OTG_PS_INTR_MSK 0x3000C //This is in OTG IP + + +//4 REG_OTG_PWCSEQ_PWC +#define BIT_SHIFT_PWC_USBD_EN 0 +#define BIT_MASK_PWC_USBD_EN 0x1 +#define BIT_PWC_USBD_EN(x)(((x) & BIT_MASK_PWC_USBD_EN) << BIT_SHIFT_PWC_USBD_EN) +#define BIT_INVC_PWC_USBD_EN (~(BIT_MASK_PWC_USBD_EN << BIT_SHIFT_PWC_USBD_EN)) + +#define BIT_SHIFT_PWC_UPLV_EN 1 +#define BIT_MASK_PWC_UPLV_EN 0x1 +#define BIT_PWC_UPLV_EN(x)(((x) & BIT_MASK_PWC_UPLV_EN) << BIT_SHIFT_PWC_UPLV_EN) +#define BIT_INVC_PWC_UPLV_EN (~(BIT_MASK_PWC_UPLV_EN << BIT_SHIFT_PWC_UPLV_EN)) + +#define BIT_SHIFT_PWC_UPHV_EN 2 +#define BIT_MASK_PWC_UPHV_EN 0x1 +#define BIT_PWC_UPHV_EN(x)(((x) & BIT_MASK_PWC_UPHV_EN) << BIT_SHIFT_PWC_UPHV_EN) +#define BIT_INVC_PWC_UPHV_EN (~(BIT_MASK_PWC_UPHV_EN << BIT_SHIFT_PWC_UPHV_EN)) + +//4 REG_OTG_PWCSEQ_ISO +#define BIT_SHIFT_ISO_USBD_EN 0 +#define BIT_MASK_ISO_USBD_EN 0x1 +#define BIT_ISO_USBD_EN(x)(((x) & BIT_MASK_ISO_USBD_EN) << BIT_SHIFT_ISO_USBD_EN) +#define BIT_INVC_ISO_USBD_EN (~(BIT_MASK_ISO_USBD_EN << BIT_SHIFT_ISO_USBD_EN)) + +#define BIT_SHIFT_ISO_USBA_EN 1 +#define BIT_MASK_ISO_USBA_EN 0x1 +#define BIT_ISO_USBA_EN(x)(((x) & BIT_MASK_ISO_USBA_EN) << BIT_SHIFT_ISO_USBA_EN) +#define BIT_INVC_ISO_USBA_EN (~(BIT_MASK_ISO_USBA_EN << BIT_SHIFT_ISO_USBA_EN)) + +//4 REG_SOC_HCI_COM_FUNC_EN +#define BIT_SHIFT_SOC_HCI_OTG_EN 4 +#define BIT_MASK_SOC_HCI_OTG_EN 0x1 +#define BIT_SOC_HCI_OTG_EN_OTG(x)(((x) & BIT_MASK_SOC_HCI_OTG_EN) << BIT_SHIFT_SOC_HCI_OTG_EN) +#define BIT_INVC_SOC_HCI_OTG_EN (~(BIT_MASK_SOC_HCI_OTG_EN << BIT_SHIFT_SOC_HCI_OTG_EN)) + +//4 REG_PESOC_HCI_CLK_CTRL0 +#define BIT_SHIFT_SOC_ACTCK_OTG_EN 4 +#define BIT_MASK_SOC_ACTCK_OTG_EN 0x1 +#define BIT_SOC_ACTCK_OTG_EN_OTG(x)(((x) & BIT_MASK_SOC_ACTCK_OTG_EN) << BIT_SHIFT_SOC_ACTCK_OTG_EN) +#define BIT_INVC_SOC_ACTCK_OTG_EN (~(BIT_MASK_SOC_ACTCK_OTG_EN << BIT_SHIFT_SOC_ACTCK_OTG_EN)) + + +//4 REG_OTG_PWCSEQ_OTG +#define BIT_SHIFT_USBOTG_PS_EN 0 +#define BIT_MASK_USBOTG_PS_EN 0x1 +#define BIT_USBOTG_PS_EN(x)(((x) & BIT_MASK_USBOTG_PS_EN) << BIT_SHIFT_USBOTG_PS_EN) +#define BIT_INVC_USBOTG_PS_EN (~(BIT_MASK_USBOTG_PS_EN << BIT_SHIFT_USBOTG_PS_EN)) + +#define BIT_SHIFT_USBOTG_DIS_SUSB 1 +#define BIT_MASK_USBOTG_DIS_SUSB 0x1 +#define BIT_USBOTG_DIS_SUSB(x)(((x) & BIT_MASK_USBOTG_DIS_SUSB) << BIT_SHIFT_USBOTG_DIS_SUSB) +#define BIT_INVC_USBOTG_DIS_SUSB (~(BIT_MASK_USBOTG_DIS_SUSB << BIT_SHIFT_USBOTG_DIS_SUSB)) + +#define BIT_SHIFT_USBOTG_SUSBM 4 +#define BIT_MASK_USBOTG_SUSBM 0x1 +#define BIT_USBOTG_SUSBM(x)(((x) & BIT_MASK_USBOTG_SUSBM) << BIT_SHIFT_USBOTG_SUSBM) +#define BIT_INVC_USBOTG_SUSBM (~(BIT_MASK_USBOTG_SUSBM << BIT_SHIFT_USBOTG_SUSBM)) + +#define BIT_SHIFT_UPLL_CKRDY 5 +#define BIT_MASK_UPLL_CKRDY 0x1 +#define BIT_UPLL_CKRDY(x)(((x) & BIT_MASK_UPLL_CKRDY) << BIT_SHIFT_UPLL_CKRDY) +#define BIT_INVC_UPLL_CKRDY (~(BIT_MASK_UPLL_CKRDY << BIT_SHIFT_UPLL_CKRDY)) + +#define BIT_SHIFT_USB_LS 6 +#define BIT_MASK_USB_LS 0x3 +#define BIT_USB_LS(x)(((x) & BIT_MASK_USB_LS) << BIT_SHIFT_USB_LS) +#define BIT_INVC_USB_LS (~(BIT_MASK_USB_LS << BIT_SHIFT_USB_LS)) + +#define BIT_SHIFT_USBOTG_EN 8 +#define BIT_MASK_USBOTG_EN 0x1 +#define BIT_USBOTG_EN(x)(((x) & BIT_MASK_USBOTG_EN) << BIT_SHIFT_USBOTG_EN) +#define BIT_INVC_USBOTG_EN (~(BIT_MASK_USBOTG_EN << BIT_SHIFT_USBOTG_EN)) + +#define BIT_SHIFT_USBPHY_EN 9 +#define BIT_MASK_USBPHY_EN 0x1 +#define BIT_USBPHY_EN(x)(((x) & BIT_MASK_USBPHY_EN) << BIT_SHIFT_USBPHY_EN) +#define BIT_INVC_USBPHY_EN (~(BIT_MASK_USBPHY_EN << BIT_SHIFT_USBPHY_EN)) + +#define BIT_SHIFT_USB_GT_LS_EN 10 +#define BIT_MASK_USB_GT_LS_EN 0x1 +#define BIT_USB_GT_LS_EN(x)(((x) & BIT_MASK_USB_GT_LS_EN) << BIT_SHIFT_USB_GT_LS_EN) +#define BIT_INVC_USB_GT_LS_EN (~(BIT_MASK_USB_GT_LS_EN << BIT_SHIFT_USB_GT_LS_EN)) + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb.h new file mode 100644 index 0000000..4a13afd --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb.h @@ -0,0 +1,2170 @@ +/* + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Modified by Synopsys, Inc, 12/12/2007 */ + + +#ifndef _USB_H_ +#define _USB_H_ +#include "basic_types.h" +#include "dwc_os.h" +#if defined(DWC_WITH_WLAN_OSDEP) +#include "osdep_service.h" +#else +#include "osdep_api.h" +#include "rtl8195a.h" +#endif +#include "hal_util.h" + +#include "errno.h" +#include "diag.h" +#include "usb_ch9.h" +#include "usb_defs.h" + +#define USB_FAST_HUB_ENUM 1 +/* + * The USB records contain some unaligned little-endian word + * components. The U[SG]ETW macros take care of both the alignment + * and endian problem and should always be used to access non-byte + * values. + */ +typedef u8 uByte; +typedef u8 uWord[2]; +typedef u8 uDWord[4]; + +#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) +#define UCONSTW(x) { (x) & 0xff, ((x) >> 8) & 0xff } +#define UCONSTDW(x) { (x) & 0xff, ((x) >> 8) & 0xff, \ + ((x) >> 16) & 0xff, ((x) >> 24) & 0xff } + +#if 1 +#define UGETW(w) ((w)[0] | ((w)[1] << 8)) +#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) +#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) +#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \ + (w)[1] = (u_int8_t)((v) >> 8), \ + (w)[2] = (u_int8_t)((v) >> 16), \ + (w)[3] = (u_int8_t)((v) >> 24)) +#else +/* + * On little-endian machines that can handle unanliged accesses + * (e.g. i386) these macros can be replaced by the following. + */ +#define UGETW(w) (*(u_int16_t *)(w)) +#define USETW(w,v) (*(u_int16_t *)(w) = (v)) +#define UGETDW(w) (*(u_int32_t *)(w)) +#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) +#endif + +/* + * Macros for accessing UAS IU fields, which are big-endian + */ +#define IUSETW2(w,h,l) ((w)[0] = (u_int8_t)(h), (w)[1] = (u_int8_t)(l)) +#define IUCONSTW(x) { ((x) >> 8) & 0xff, (x) & 0xff } +#define IUCONSTDW(x) { ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \ + ((x) >> 8) & 0xff, (x) & 0xff } +#define IUGETW(w) (((w)[0] << 8) | (w)[1]) +#define IUSETW(w,v) ((w)[0] = (u_int8_t)((v) >> 8), (w)[1] = (u_int8_t)(v)) +#define IUGETDW(w) (((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3]) +#define IUSETDW(w,v) ((w)[0] = (u_int8_t)((v) >> 24), \ + (w)[1] = (u_int8_t)((v) >> 16), \ + (w)[2] = (u_int8_t)((v) >> 8), \ + (w)[3] = (u_int8_t)(v)) + +//#define UPACKED __attribute__((__packed__)) +#define UPACKED +typedef struct { + uByte bmRequestType; + uByte bRequest; + uWord wValue; + uWord wIndex; + uWord wLength; +} UPACKED usb_device_request_t; + +#define UT_GET_DIR(a) ((a) & 0x80) +#define UT_WRITE 0x00 +#define UT_READ 0x80 + +#define UT_GET_TYPE(a) ((a) & 0x60) +#define UT_STANDARD 0x00 +#define UT_CLASS 0x20 +#define UT_VENDOR 0x40 + +#define UT_GET_RECIPIENT(a) ((a) & 0x1f) +#define UT_DEVICE 0x00 +#define UT_INTERFACE 0x01 +#define UT_ENDPOINT 0x02 +#define UT_OTHER 0x03 + +#define UT_READ_DEVICE (UT_READ | UT_STANDARD | UT_DEVICE) +#define UT_READ_INTERFACE (UT_READ | UT_STANDARD | UT_INTERFACE) +#define UT_READ_ENDPOINT (UT_READ | UT_STANDARD | UT_ENDPOINT) +#define UT_WRITE_DEVICE (UT_WRITE | UT_STANDARD | UT_DEVICE) +#define UT_WRITE_INTERFACE (UT_WRITE | UT_STANDARD | UT_INTERFACE) +#define UT_WRITE_ENDPOINT (UT_WRITE | UT_STANDARD | UT_ENDPOINT) +#define UT_READ_CLASS_DEVICE (UT_READ | UT_CLASS | UT_DEVICE) +#define UT_READ_CLASS_INTERFACE (UT_READ | UT_CLASS | UT_INTERFACE) +#define UT_READ_CLASS_OTHER (UT_READ | UT_CLASS | UT_OTHER) +#define UT_READ_CLASS_ENDPOINT (UT_READ | UT_CLASS | UT_ENDPOINT) +#define UT_WRITE_CLASS_DEVICE (UT_WRITE | UT_CLASS | UT_DEVICE) +#define UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE) +#define UT_WRITE_CLASS_OTHER (UT_WRITE | UT_CLASS | UT_OTHER) +#define UT_WRITE_CLASS_ENDPOINT (UT_WRITE | UT_CLASS | UT_ENDPOINT) +#define UT_READ_VENDOR_DEVICE (UT_READ | UT_VENDOR | UT_DEVICE) +#define UT_READ_VENDOR_INTERFACE (UT_READ | UT_VENDOR | UT_INTERFACE) +#define UT_READ_VENDOR_OTHER (UT_READ | UT_VENDOR | UT_OTHER) +#define UT_READ_VENDOR_ENDPOINT (UT_READ | UT_VENDOR | UT_ENDPOINT) +#define UT_WRITE_VENDOR_DEVICE (UT_WRITE | UT_VENDOR | UT_DEVICE) +#define UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE) +#define UT_WRITE_VENDOR_OTHER (UT_WRITE | UT_VENDOR | UT_OTHER) +#define UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT) + +/* Requests */ +#define UR_GET_STATUS 0x00 +#define USTAT_STANDARD_STATUS 0x00 +#define WUSTAT_WUSB_FEATURE 0x01 +#define WUSTAT_CHANNEL_INFO 0x02 +#define WUSTAT_RECEIVED_DATA 0x03 +#define WUSTAT_MAS_AVAILABILITY 0x04 +#define WUSTAT_CURRENT_TRANSMIT_POWER 0x05 +#define UR_CLEAR_FEATURE 0x01 +#define UR_SET_FEATURE 0x03 +#define UR_SET_AND_TEST_FEATURE 0x0c +#define UR_SET_ADDRESS 0x05 +#define UR_GET_DESCRIPTOR 0x06 +#define UDESC_DEVICE 0x01 +#define UDESC_CONFIG 0x02 +#define UDESC_STRING 0x03 +#define UDESC_INTERFACE 0x04 +#define UDESC_ENDPOINT 0x05 +#define UDESC_SS_USB_COMPANION 0x30 +#define UDESC_DEVICE_QUALIFIER 0x06 +#define UDESC_OTHER_SPEED_CONFIGURATION 0x07 +#define UDESC_INTERFACE_POWER 0x08 +#define UDESC_OTG 0x09 +#define WUDESC_SECURITY 0x0c +#define WUDESC_KEY 0x0d +#define WUD_GET_KEY_INDEX(_wValue_) ((_wValue_) & 0xf) +#define WUD_GET_KEY_TYPE(_wValue_) (((_wValue_) & 0x30) >> 4) +#define WUD_KEY_TYPE_ASSOC 0x01 +#define WUD_KEY_TYPE_GTK 0x02 +#define WUD_GET_KEY_ORIGIN(_wValue_) (((_wValue_) & 0x40) >> 6) +#define WUD_KEY_ORIGIN_HOST 0x00 +#define WUD_KEY_ORIGIN_DEVICE 0x01 +#define WUDESC_ENCRYPTION_TYPE 0x0e +#define WUDESC_BOS 0x0f +#define WUDESC_DEVICE_CAPABILITY 0x10 +#define WUDESC_WIRELESS_ENDPOINT_COMPANION 0x11 +#define UDESC_BOS 0x0f +#define UDESC_DEVICE_CAPABILITY 0x10 +#define UDESC_CS_DEVICE 0x21 /* class specific */ +#define UDESC_CS_CONFIG 0x22 +#define UDESC_CS_STRING 0x23 +#define UDESC_CS_INTERFACE 0x24 +#define UDESC_CS_ENDPOINT 0x25 +#define UDESC_HUB 0x29 +#define UR_SET_DESCRIPTOR 0x07 +#define UR_GET_CONFIG 0x08 +#define UR_SET_CONFIG 0x09 +#define UR_GET_INTERFACE 0x0a +#define UR_SET_INTERFACE 0x0b +#define UR_SYNCH_FRAME 0x0c +#define WUR_SET_ENCRYPTION 0x0d +#define WUR_GET_ENCRYPTION 0x0e +#define WUR_SET_HANDSHAKE 0x0f +#define WUR_GET_HANDSHAKE 0x10 +#define WUR_SET_CONNECTION 0x11 +#define WUR_SET_SECURITY_DATA 0x12 +#define WUR_GET_SECURITY_DATA 0x13 +#define WUR_SET_WUSB_DATA 0x14 +#define WUDATA_DRPIE_INFO 0x01 +#define WUDATA_TRANSMIT_DATA 0x02 +#define WUDATA_TRANSMIT_PARAMS 0x03 +#define WUDATA_RECEIVE_PARAMS 0x04 +#define WUDATA_TRANSMIT_POWER 0x05 +#define WUR_LOOPBACK_DATA_WRITE 0x15 +#define WUR_LOOPBACK_DATA_READ 0x16 +#define WUR_SET_INTERFACE_DS 0x17 + +/* Feature numbers */ +#define UF_ENDPOINT_HALT 0 +#define UF_DEVICE_REMOTE_WAKEUP 1 +#define UF_TEST_MODE 2 +#define UF_DEVICE_B_HNP_ENABLE 3 +#define UF_DEVICE_A_HNP_SUPPORT 4 +#define UF_DEVICE_A_ALT_HNP_SUPPORT 5 +#define WUF_WUSB 3 +#define WUF_TX_DRPIE 0x0 +#define WUF_DEV_XMIT_PACKET 0x1 +#define WUF_COUNT_PACKETS 0x2 +#define WUF_CAPTURE_PACKETS 0x3 +#define UF_FUNCTION_SUSPEND 0 +#define UF_U1_ENABLE 48 +#define UF_U2_ENABLE 49 +#define UF_LTM_ENABLE 50 + +/* Class requests from the USB 2.0 hub spec, table 11-15 */ +#define UCR_CLEAR_HUB_FEATURE (0x2000 | UR_CLEAR_FEATURE) +#define UCR_CLEAR_PORT_FEATURE (0x2300 | UR_CLEAR_FEATURE) +#define UCR_GET_HUB_DESCRIPTOR (0xa000 | UR_GET_DESCRIPTOR) +#define UCR_GET_HUB_STATUS (0xa000 | UR_GET_STATUS) +#define UCR_GET_PORT_STATUS (0xa300 | UR_GET_STATUS) +#define UCR_SET_HUB_FEATURE (0x2000 | UR_SET_FEATURE) +#define UCR_SET_PORT_FEATURE (0x2300 | UR_SET_FEATURE) +#define UCR_SET_AND_TEST_PORT_FEATURE (0xa300 | UR_SET_AND_TEST_FEATURE) + + + + + + + + +#define USB_MAX_STRING_LEN 128 +#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ + +/* Hub specific request */ +#define UR_GET_BUS_STATE 0x02 +#define UR_CLEAR_TT_BUFFER 0x08 +#define UR_RESET_TT 0x09 +#define UR_GET_TT_STATE 0x0a +#define UR_STOP_TT 0x0b + +/* Hub features */ +#define UHF_C_HUB_LOCAL_POWER 0 +#define UHF_C_HUB_OVER_CURRENT 1 +#define UHF_PORT_CONNECTION 0 +#define UHF_PORT_ENABLE 1 +#define UHF_PORT_SUSPEND 2 +#define UHF_PORT_OVER_CURRENT 3 +#define UHF_PORT_RESET 4 +#define UHF_PORT_L1 5 +#define UHF_PORT_POWER 8 +#define UHF_PORT_LOW_SPEED 9 +#define UHF_PORT_HIGH_SPEED 10 +#define UHF_C_PORT_CONNECTION 16 +#define UHF_C_PORT_ENABLE 17 +#define UHF_C_PORT_SUSPEND 18 +#define UHF_C_PORT_OVER_CURRENT 19 +#define UHF_C_PORT_RESET 20 +#define UHF_C_PORT_L1 23 +#define UHF_PORT_TEST 21 +#define UHF_PORT_INDICATOR 22 + + + + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uWord bcdUSB; + uByte bDeviceClass; + uByte bDeviceSubClass; + uByte bDeviceProtocol; + uByte bMaxPacketSize0; + uByte bNumConfigurations; + uByte bReserved; +} UPACKED usb_device_qualifier_t; +#define USB_DEVICE_QUALIFIER_SIZE 10 + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uByte bmAttributes; +#define UOTG_SRP 0x01 +#define UOTG_HNP 0x02 +} UPACKED usb_otg_descriptor_t; + +/* OTG feature selectors */ +#define UOTG_B_HNP_ENABLE 3 +#define UOTG_A_HNP_SUPPORT 4 +#define UOTG_A_ALT_HNP_SUPPORT 5 + +typedef struct { + uWord wStatus; +/* Device status flags */ +#define UDS_SELF_POWERED 0x0001 +#define UDS_REMOTE_WAKEUP 0x0002 +/* Endpoint status flags */ +#define UES_HALT 0x0001 +} UPACKED usb_status_t; + +typedef struct { + uWord wHubStatus; +#define UHS_LOCAL_POWER 0x0001 +#define UHS_OVER_CURRENT 0x0002 + uWord wHubChange; +} UPACKED usb_hub_status_t; + +typedef struct { + uWord wPortStatus; +#define UPS_CURRENT_CONNECT_STATUS 0x0001 +#define UPS_PORT_ENABLED 0x0002 +#define UPS_SUSPEND 0x0004 +#define UPS_OVERCURRENT_INDICATOR 0x0008 +#define UPS_RESET 0x0010 +#define UPS_PORT_POWER 0x0100 +#define UPS_LOW_SPEED 0x0200 +#define UPS_HIGH_SPEED 0x0400 +#define UPS_PORT_TEST 0x0800 +#define UPS_PORT_INDICATOR 0x1000 + uWord wPortChange; +#define UPS_C_CONNECT_STATUS 0x0001 +#define UPS_C_PORT_ENABLED 0x0002 +#define UPS_C_SUSPEND 0x0004 +#define UPS_C_OVERCURRENT_INDICATOR 0x0008 +#define UPS_C_PORT_RESET 0x0010 +} UPACKED usb_port_status_t; + + +/* Device class codes */ +#define UDCLASS_IN_INTERFACE 0x00 +#define UDCLASS_COMM 0x02 +#define UDCLASS_HUB 0x09 +#define UDSUBCLASS_HUB 0x00 +#define UDPROTO_FSHUB 0x00 +#define UDPROTO_HSHUBSTT 0x01 +#define UDPROTO_HSHUBMTT 0x02 +#define UDCLASS_DIAGNOSTIC 0xdc +#define UDCLASS_WIRELESS 0xe0 +#define UDSUBCLASS_RF 0x01 +#define UDPROTO_BLUETOOTH 0x01 +#define UDCLASS_VENDOR 0xff + +/* Interface class codes */ +#define UICLASS_UNSPEC 0x00 + +#define UICLASS_AUDIO 0x01 +#define UISUBCLASS_AUDIOCONTROL 1 +#define UISUBCLASS_AUDIOSTREAM 2 +#define UISUBCLASS_MIDISTREAM 3 + +#define UICLASS_CDC 0x02 /* communication */ +#define UISUBCLASS_DIRECT_LINE_CONTROL_MODEL 1 +#define UISUBCLASS_ABSTRACT_CONTROL_MODEL 2 +#define UISUBCLASS_TELEPHONE_CONTROL_MODEL 3 +#define UISUBCLASS_MULTICHANNEL_CONTROL_MODEL 4 +#define UISUBCLASS_CAPI_CONTROLMODEL 5 +#define UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6 +#define UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7 +#define UIPROTO_CDC_AT 1 + +#define UICLASS_HID 0x03 +#define UISUBCLASS_BOOT 1 +#define UIPROTO_BOOT_KEYBOARD 1 + +#define UICLASS_PHYSICAL 0x05 + +#define UICLASS_IMAGE 0x06 + +#define UICLASS_PRINTER 0x07 +#define UISUBCLASS_PRINTER 1 +#define UIPROTO_PRINTER_UNI 1 +#define UIPROTO_PRINTER_BI 2 +#define UIPROTO_PRINTER_1284 3 + +#define UICLASS_MASS 0x08 +#define UISUBCLASS_RBC 1 +#define UISUBCLASS_SFF8020I 2 +#define UISUBCLASS_QIC157 3 +#define UISUBCLASS_UFI 4 +#define UISUBCLASS_SFF8070I 5 +#define UISUBCLASS_SCSI 6 +#define UIPROTO_MASS_CBI_I 0 +#define UIPROTO_MASS_CBI 1 +#define UIPROTO_MASS_BBB_OLD 2 /* Not in the spec anymore */ +#define UIPROTO_MASS_BBB 80 /* 'P' for the Iomega Zip drive */ + +#define UICLASS_HUB 0x09 +#define UISUBCLASS_HUB 0 +#define UIPROTO_FSHUB 0 +#define UIPROTO_HSHUBSTT 0 /* Yes, same as previous */ +#define UIPROTO_HSHUBMTT 1 + +#define UICLASS_CDC_DATA 0x0a +#define UISUBCLASS_DATA 0 +#define UIPROTO_DATA_ISDNBRI 0x30 /* Physical iface */ +#define UIPROTO_DATA_HDLC 0x31 /* HDLC */ +#define UIPROTO_DATA_TRANSPARENT 0x32 /* Transparent */ +#define UIPROTO_DATA_Q921M 0x50 /* Management for Q921 */ +#define UIPROTO_DATA_Q921 0x51 /* Data for Q921 */ +#define UIPROTO_DATA_Q921TM 0x52 /* TEI multiplexer for Q921 */ +#define UIPROTO_DATA_V42BIS 0x90 /* Data compression */ +#define UIPROTO_DATA_Q931 0x91 /* Euro-ISDN */ +#define UIPROTO_DATA_V120 0x92 /* V.24 rate adaption */ +#define UIPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */ +#define UIPROTO_DATA_HOST_BASED 0xfd /* Host based driver */ +#define UIPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/ +#define UIPROTO_DATA_VENDOR 0xff /* Vendor specific */ + +#define UICLASS_SMARTCARD 0x0b + +/*#define UICLASS_FIRM_UPD 0x0c*/ + +#define UICLASS_SECURITY 0x0d + +#define UICLASS_DIAGNOSTIC 0xdc + +#define UICLASS_WIRELESS 0xe0 +#define UISUBCLASS_RF 0x01 +#define UIPROTO_BLUETOOTH 0x01 + +#define UICLASS_APPL_SPEC 0xfe +#define UISUBCLASS_FIRMWARE_DOWNLOAD 1 +#define UISUBCLASS_IRDA 2 +#define UIPROTO_IRDA 0 + +#define UICLASS_VENDOR 0xff + +#define USB_HUB_MAX_DEPTH 5 + +/* + * Minimum time a device needs to be powered down to go through + * a power cycle. XXX Are these time in the spec? + */ +#define USB_POWER_DOWN_TIME 200 /* ms */ +#define USB_PORT_POWER_DOWN_TIME 100 /* ms */ + +#if 0 +/* These are the values from the spec. */ +#define USB_PORT_RESET_DELAY 10 /* ms */ +#define USB_PORT_ROOT_RESET_DELAY 50 /* ms */ +#define USB_PORT_RESET_RECOVERY 10 /* ms */ +#define USB_PORT_POWERUP_DELAY 100 /* ms */ +#define USB_SET_ADDRESS_SETTLE 2 /* ms */ +#define USB_RESUME_DELAY (20*5) /* ms */ +#define USB_RESUME_WAIT 10 /* ms */ +#define USB_RESUME_RECOVERY 10 /* ms */ +#define USB_EXTRA_POWER_UP_TIME 0 /* ms */ +#else +/* Allow for marginal (i.e. non-conforming) devices. */ +#define USB_PORT_RESET_DELAY 50 /* ms */ +#define USB_PORT_ROOT_RESET_DELAY 250 /* ms */ +#define USB_PORT_RESET_RECOVERY 250 /* ms */ +#define USB_PORT_POWERUP_DELAY 300 /* ms */ +#define USB_SET_ADDRESS_SETTLE 10 /* ms */ +#define USB_RESUME_DELAY (50*5) /* ms */ +#define USB_RESUME_WAIT 50 /* ms */ +#define USB_RESUME_RECOVERY 50 /* ms */ +#define USB_EXTRA_POWER_UP_TIME 20 /* ms */ +#endif + +#define USB_MIN_POWER 100 /* mA */ +#define USB_MAX_POWER 500 /* mA */ + +#define USB_BUS_RESET_DELAY 100 /* ms XXX?*/ + +#define USB_UNCONFIG_NO 0 +#define USB_UNCONFIG_INDEX (-1) + +/*** ioctl() related stuff ***/ + +struct usb_ctl_request { + int ucr_addr; + usb_device_request_t ucr_request; + void *ucr_data; + int ucr_flags; +#define USBD_SHORT_XFER_OK 0x04 /* allow short reads */ + int ucr_actlen; /* actual length transferred */ +}; + +struct usb_alt_interface { + int uai_config_index; + int uai_interface_index; + int uai_alt_no; +}; + +#define USB_CURRENT_CONFIG_INDEX (-1) +#define USB_CURRENT_ALT_INDEX (-1) + + + +struct usb_full_desc { + int ufd_config_index; + u16 ufd_size; + u8 *ufd_data; +}; + + +struct usb_ctl_report_desc { + int ucrd_size; + u8 ucrd_data[1024]; /* filled data size will vary */ +}; + +typedef struct { u32 cookie; } usb_event_cookie_t; + +#define USB_MAX_DEVNAMES 4 +#define USB_MAX_DEVNAMELEN 16 +struct usb_device_info { + u8 udi_bus; + u8 udi_addr; /* device address */ + usb_event_cookie_t udi_cookie; + char udi_product[USB_MAX_STRING_LEN]; + char udi_vendor[USB_MAX_STRING_LEN]; + char udi_release[8]; + u16 udi_productNo; + u16 udi_vendorNo; + u16 udi_releaseNo; + u8 udi_class; + u8 udi_subclass; + u8 udi_protocol; + u8 udi_config; + u8 udi_speed; +#if 0 +#define USB_SPEED_UNKNOWN 0 +#define USB_SPEED_LOW 1 +#define USB_SPEED_FULL 2 +#define USB_SPEED_HIGH 3 +#define USB_SPEED_VARIABLE 4 +#define USB_SPEED_SUPER 5 +#endif + int udi_power; /* power consumption in mA, 0 if selfpowered */ + int udi_nports; + char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; + u8 udi_ports[16];/* hub only: addresses of devices on ports */ +#define USB_PORT_ENABLED 0xff +#define USB_PORT_SUSPENDED 0xfe +#define USB_PORT_POWERED 0xfd +#define USB_PORT_DISABLED 0xfc +}; + +struct usb_ctl_report { + int ucr_report; + u8 ucr_data[1024]; /* filled data size will vary */ +}; + +struct usb_device_stats { + u32 uds_requests[4]; /* indexed by transfer type UE_* */ +}; + +#define WUSB_MIN_IE 0x80 +#define WUSB_WCTA_IE 0x80 +#define WUSB_WCONNECTACK_IE 0x81 +#define WUSB_WHOSTINFO_IE 0x82 +#define WUHI_GET_CA(_bmAttributes_) ((_bmAttributes_) & 0x3) +#define WUHI_CA_RECONN 0x00 +#define WUHI_CA_LIMITED 0x01 +#define WUHI_CA_ALL 0x03 +#define WUHI_GET_MLSI(_bmAttributes_) (((_bmAttributes_) & 0x38) >> 3) +#define WUSB_WCHCHANGEANNOUNCE_IE 0x83 +#define WUSB_WDEV_DISCONNECT_IE 0x84 +#define WUSB_WHOST_DISCONNECT_IE 0x85 +#define WUSB_WRELEASE_CHANNEL_IE 0x86 +#define WUSB_WWORK_IE 0x87 +#define WUSB_WCHANNEL_STOP_IE 0x88 +#define WUSB_WDEV_KEEPALIVE_IE 0x89 +#define WUSB_WISOCH_DISCARD_IE 0x8A +#define WUSB_WRESETDEVICE_IE 0x8B +#define WUSB_WXMIT_PACKET_ADJUST_IE 0x8C +#define WUSB_MAX_IE 0x8C + +/* Device Notification Types */ + +#define WUSB_DN_MIN 0x01 +#define WUSB_DN_CONNECT 0x01 +# define WUSB_DA_OLDCONN 0x00 +# define WUSB_DA_NEWCONN 0x01 +# define WUSB_DA_SELF_BEACON 0x02 +# define WUSB_DA_DIR_BEACON 0x04 +# define WUSB_DA_NO_BEACON 0x06 +#define WUSB_DN_DISCONNECT 0x02 +#define WUSB_DN_EPRDY 0x03 +#define WUSB_DN_MASAVAILCHANGED 0x04 +#define WUSB_DN_REMOTEWAKEUP 0x05 +#define WUSB_DN_SLEEP 0x06 +#define WUSB_DN_ALIVE 0x07 +#define WUSB_DN_MAX 0x07 + + +/* WUSB Handshake Data. Used during the SET/GET HANDSHAKE requests */ +typedef struct wusb_hndshk_data { + uByte bMessageNumber; + uByte bStatus; + uByte tTKID[3]; + uByte bReserved; + uByte CDID[16]; + uByte Nonce[16]; + uByte MIC[8]; +} UPACKED wusb_hndshk_data_t; +#define WUSB_HANDSHAKE_LEN_FOR_MIC 38 + +/* WUSB Connection Context */ +typedef struct wusb_conn_context { + uByte CHID [16]; + uByte CDID [16]; + uByte CK [16]; +} UPACKED wusb_conn_context_t; + +/* WUSB Security Descriptor */ +typedef struct wusb_security_desc { + uByte bLength; + uByte bDescriptorType; + uWord wTotalLength; + uByte bNumEncryptionTypes; +} UPACKED wusb_security_desc_t; + +/* WUSB Encryption Type Descriptor */ +typedef struct wusb_encrypt_type_desc { + uByte bLength; + uByte bDescriptorType; + + uByte bEncryptionType; +#define WUETD_UNSECURE 0 +#define WUETD_WIRED 1 +#define WUETD_CCM_1 2 +#define WUETD_RSA_1 3 + + uByte bEncryptionValue; + uByte bAuthKeyIndex; +} UPACKED wusb_encrypt_type_desc_t; + +/* WUSB Key Descriptor */ +typedef struct wusb_key_desc { + uByte bLength; + uByte bDescriptorType; + uByte tTKID[3]; + uByte bReserved; + uByte KeyData[1]; /* variable length */ +} UPACKED wusb_key_desc_t; + +/* WUSB BOS Descriptor (Binary device Object Store) */ +typedef struct wusb_bos_desc { + uByte bLength; + uByte bDescriptorType; + uWord wTotalLength; + uByte bNumDeviceCaps; +} UPACKED wusb_bos_desc_t; + +#define USB_DEVICE_CAPABILITY_20_EXTENSION 0x02 +typedef struct usb_dev_cap_20_ext_desc { + uByte bLength; + uByte bDescriptorType; + uByte bDevCapabilityType; +#define USB_20_EXT_LPM 0x02 + uDWord bmAttributes; +} UPACKED usb_dev_cap_20_ext_desc_t; + +#define USB_DEVICE_CAPABILITY_SS_USB 0x03 +typedef struct usb_dev_cap_ss_usb { + uByte bLength; + uByte bDescriptorType; + uByte bDevCapabilityType; +#define USB_DC_SS_USB_LTM_CAPABLE 0x02 + uByte bmAttributes; +#define USB_DC_SS_USB_SPEED_SUPPORT_LOW 0x01 +#define USB_DC_SS_USB_SPEED_SUPPORT_FULL 0x02 +#define USB_DC_SS_USB_SPEED_SUPPORT_HIGH 0x04 +#define USB_DC_SS_USB_SPEED_SUPPORT_SS 0x08 + uWord wSpeedsSupported; + uByte bFunctionalitySupport; + uByte bU1DevExitLat; + uWord wU2DevExitLat; +} UPACKED usb_dev_cap_ss_usb_t; + +#define USB_DEVICE_CAPABILITY_CONTAINER_ID 0x04 +typedef struct usb_dev_cap_container_id { + uByte bLength; + uByte bDescriptorType; + uByte bDevCapabilityType; + uByte bReserved; + uByte containerID[16]; +} UPACKED usb_dev_cap_container_id_t; + +/* Device Capability Type Codes */ +#define WUSB_DEVICE_CAPABILITY_WIRELESS_USB 0x01 + +/* Device Capability Descriptor */ +typedef struct wusb_dev_cap_desc { + uByte bLength; + uByte bDescriptorType; + uByte bDevCapabilityType; + uByte caps[1]; /* Variable length */ +} UPACKED wusb_dev_cap_desc_t; + +/* Device Capability Descriptor */ +typedef struct wusb_dev_cap_uwb_desc { + uByte bLength; + uByte bDescriptorType; + uByte bDevCapabilityType; + uByte bmAttributes; + uWord wPHYRates; /* Bitmap */ + uByte bmTFITXPowerInfo; + uByte bmFFITXPowerInfo; + uWord bmBandGroup; + uByte bReserved; +} UPACKED wusb_dev_cap_uwb_desc_t; + +/* Wireless USB Endpoint Companion Descriptor */ +typedef struct wusb_endpoint_companion_desc { + uByte bLength; + uByte bDescriptorType; + uByte bMaxBurst; + uByte bMaxSequence; + uWord wMaxStreamDelay; + uWord wOverTheAirPacketSize; + uByte bOverTheAirInterval; + uByte bmCompAttributes; +} UPACKED wusb_endpoint_companion_desc_t; + +/* Wireless USB Numeric Association M1 Data Structure */ +typedef struct wusb_m1_data { + uByte version; + uWord langId; + uByte deviceFriendlyNameLength; + uByte sha_256_m3[32]; + uByte deviceFriendlyName[256]; +} UPACKED wusb_m1_data_t; + +typedef struct wusb_m2_data { + uByte version; + uWord langId; + uByte hostFriendlyNameLength; + uByte pkh[384]; + uByte hostFriendlyName[256]; +} UPACKED wusb_m2_data_t; + +typedef struct wusb_m3_data { + uByte pkd[384]; + uByte nd; +} UPACKED wusb_m3_data_t; + +typedef struct wusb_m4_data { + uDWord _attributeTypeIdAndLength_1; + uWord associationTypeId; + + uDWord _attributeTypeIdAndLength_2; + uWord associationSubTypeId; + + uDWord _attributeTypeIdAndLength_3; + uDWord length; + + uDWord _attributeTypeIdAndLength_4; + uDWord associationStatus; + + uDWord _attributeTypeIdAndLength_5; + uByte chid[16]; + + uDWord _attributeTypeIdAndLength_6; + uByte cdid[16]; + + uDWord _attributeTypeIdAndLength_7; + uByte bandGroups[2]; +} UPACKED wusb_m4_data_t; + + + +/* Original Host */ +/* USB directions */ +#define USB_DIR_OUT 0 +#define USB_DIR_IN 0x80 + +/* Endpoints */ +#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_XFER_CONTROL 0 +#define USB_ENDPOINT_XFER_ISOC 1 +#define USB_ENDPOINT_XFER_BULK 2 +#define USB_ENDPOINT_XFER_INT 3 + +#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ + + + + + +#if 1 +#define UGETW(w) ((w)[0] | ((w)[1] << 8)) +#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) +#define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) +#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \ + (w)[1] = (u_int8_t)((v) >> 8), \ + (w)[2] = (u_int8_t)((v) >> 16), \ + (w)[3] = (u_int8_t)((v) >> 24)) +#else +/* + * On little-endian machines that can handle unanliged accesses + * (e.g. i386) these macros can be replaced by the following. + */ +#define UGETW(w) (*(u_int16_t *)(w)) +#define USETW(w,v) (*(u_int16_t *)(w) = (v)) +#define UGETDW(w) (*(u_int32_t *)(w)) +#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) +#endif + +//#define UPACKED __attribute__((__packed__)) + + + + + + +/* Everything is aribtrary */ +#define USB_ALTSETTINGALLOC 4 +#define USB_MAXALTSETTING 128 /* Hard limit */ + +#define USB_MAX_DEVICE 3 // at least 2: 1 for the root hub device, 1 for usb device +#define USB_MAXCONFIG 8 +#define USB_MAXINTERFACES 8 +#define USB_MAXENDPOINTS 16 +#define USB_MAXCHILDREN 8 /* This is arbitrary */ +#define USB_MAX_HUB 2 + +#define USB_MAXIADS (USB_MAXINTERFACES/2) + +#define USB_CNTL_TIMEOUT 5000 /* 100ms timeout */ + + + + +/* Requests */ +#define UR_GET_STATUS 0x00 +#define USTAT_STANDARD_STATUS 0x00 +#define WUSTAT_WUSB_FEATURE 0x01 +#define WUSTAT_CHANNEL_INFO 0x02 +#define WUSTAT_RECEIVED_DATA 0x03 +#define WUSTAT_MAS_AVAILABILITY 0x04 +#define WUSTAT_CURRENT_TRANSMIT_POWER 0x05 +#define UR_CLEAR_FEATURE 0x01 +#define UR_SET_FEATURE 0x03 +#define UR_SET_AND_TEST_FEATURE 0x0c +#define UR_SET_ADDRESS 0x05 +#define UR_GET_DESCRIPTOR 0x06 +#define UDESC_DEVICE 0x01 +#define UDESC_CONFIG 0x02 +#define UDESC_STRING 0x03 +#define UDESC_INTERFACE 0x04 +#define UDESC_ENDPOINT 0x05 +#define UDESC_SS_USB_COMPANION 0x30 +#define UDESC_DEVICE_QUALIFIER 0x06 +#define UDESC_OTHER_SPEED_CONFIGURATION 0x07 +#define UDESC_INTERFACE_POWER 0x08 +#define UDESC_OTG 0x09 +#define WUDESC_SECURITY 0x0c +#define WUDESC_KEY 0x0d +#define WUD_GET_KEY_INDEX(_wValue_) ((_wValue_) & 0xf) +#define WUD_GET_KEY_TYPE(_wValue_) (((_wValue_) & 0x30) >> 4) +#define WUD_KEY_TYPE_ASSOC 0x01 +#define WUD_KEY_TYPE_GTK 0x02 +#define WUD_GET_KEY_ORIGIN(_wValue_) (((_wValue_) & 0x40) >> 6) +#define WUD_KEY_ORIGIN_HOST 0x00 +#define WUD_KEY_ORIGIN_DEVICE 0x01 +#define WUDESC_ENCRYPTION_TYPE 0x0e +#define WUDESC_BOS 0x0f +#define WUDESC_DEVICE_CAPABILITY 0x10 +#define WUDESC_WIRELESS_ENDPOINT_COMPANION 0x11 +#define UDESC_BOS 0x0f +#define UDESC_DEVICE_CAPABILITY 0x10 +#define UDESC_CS_DEVICE 0x21 /* class specific */ +#define UDESC_CS_CONFIG 0x22 +#define UDESC_CS_STRING 0x23 +#define UDESC_CS_INTERFACE 0x24 +#define UDESC_CS_ENDPOINT 0x25 +#define UDESC_HUB 0x29 +#define UR_SET_DESCRIPTOR 0x07 +#define UR_GET_CONFIG 0x08 +#define UR_SET_CONFIG 0x09 +#define UR_GET_INTERFACE 0x0a +#define UR_SET_INTERFACE 0x0b +#define UR_SYNCH_FRAME 0x0c +#define WUR_SET_ENCRYPTION 0x0d +#define WUR_GET_ENCRYPTION 0x0e +#define WUR_SET_HANDSHAKE 0x0f +#define WUR_GET_HANDSHAKE 0x10 +#define WUR_SET_CONNECTION 0x11 +#define WUR_SET_SECURITY_DATA 0x12 +#define WUR_GET_SECURITY_DATA 0x13 +#define WUR_SET_WUSB_DATA 0x14 +#define WUDATA_DRPIE_INFO 0x01 +#define WUDATA_TRANSMIT_DATA 0x02 +#define WUDATA_TRANSMIT_PARAMS 0x03 +#define WUDATA_RECEIVE_PARAMS 0x04 +#define WUDATA_TRANSMIT_POWER 0x05 +#define WUR_LOOPBACK_DATA_WRITE 0x15 +#define WUR_LOOPBACK_DATA_READ 0x16 +#define WUR_SET_INTERFACE_DS 0x17 + + +/* Hub features */ +#define UHF_C_HUB_LOCAL_POWER 0 +#define UHF_C_HUB_OVER_CURRENT 1 +#define UHF_PORT_CONNECTION 0 +#define UHF_PORT_ENABLE 1 +#define UHF_PORT_SUSPEND 2 +#define UHF_PORT_OVER_CURRENT 3 +#define UHF_PORT_RESET 4 +#define UHF_PORT_L1 5 +#define UHF_PORT_POWER 8 +#define UHF_PORT_LOW_SPEED 9 +#define UHF_PORT_HIGH_SPEED 10 +#define UHF_C_PORT_CONNECTION 16 +#define UHF_C_PORT_ENABLE 17 +#define UHF_C_PORT_SUSPEND 18 +#define UHF_C_PORT_OVER_CURRENT 19 +#define UHF_C_PORT_RESET 20 +#define UHF_C_PORT_L1 23 +#define UHF_PORT_TEST 21 +#define UHF_PORT_INDICATOR 22 + + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uByte bDescriptorSubtype; +} UPACKED usb_descriptor_t; + +typedef struct { + uByte bLength; + uByte bDescriptorType; +} UPACKED usb_descriptor_header_t; + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uWord bcdUSB; +#define UD_USB_2_0 0x0200 +#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0) + uByte bDeviceClass; + uByte bDeviceSubClass; + uByte bDeviceProtocol; + uByte bMaxPacketSize; + /* The fields below are not part of the initial descriptor. */ + uWord idVendor; + uWord idProduct; + uWord bcdDevice; + uByte iManufacturer; + uByte iProduct; + uByte iSerialNumber; + uByte bNumConfigurations; +} UPACKED usb_device_descriptor_t; + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uWord wTotalLength; + uByte bNumInterface; + uByte bConfigurationValue; + uByte iConfiguration; +#define UC_ATT_ONE (1 << 7) /* must be set */ +#define UC_ATT_SELFPOWER (1 << 6) /* self powered */ +#define UC_ATT_WAKEUP (1 << 5) /* can wakeup */ +#define UC_ATT_BATTERY (1 << 4) /* battery powered */ + uByte bmAttributes; +#define UC_BUS_POWERED 0x80 +#define UC_SELF_POWERED 0x40 +#define UC_REMOTE_WAKEUP 0x20 + uByte bMaxPower; /* max current in 2 mA units */ +#define UC_POWER_FACTOR 2 +} UPACKED usb_config_descriptor_t; +#define USB_CONFIG_DESCRIPTOR_SIZE 9 + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uByte bInterfaceNumber; + uByte bAlternateSetting; + uByte bNumEndpoints; + uByte bInterfaceClass; + uByte bInterfaceSubClass; + uByte bInterfaceProtocol; + uByte iInterface; +} UPACKED usb_interface_descriptor_t; +#define USB_INTERFACE_DESCRIPTOR_SIZE 9 + + + +/* String descriptor */ + + +/* device request (setup) */ +struct devrequest { + unsigned char requesttype; + unsigned char request; + unsigned short value; + unsigned short index; + unsigned short length; +} UPACKED; + +/* All standard descriptors have these 2 fields in common */ + + +/* Device descriptor */ + + +/* Endpoint descriptor */ + + +/* Interface descriptor */ + + +/* Configuration descriptor information.. */ + + +/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */ + +enum { + /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ + PACKET_SIZE_8 = 0, + PACKET_SIZE_16 = 1, + PACKET_SIZE_32 = 2, + PACKET_SIZE_64 = 3, +}; + + + + +struct usb_host_endpoint { + struct usb_endpoint_descriptor desc; +#if defined(DWC_WITH_WLAN_OSDEP) + _list urb_list; +#else + _LIST urb_list; +#endif + void *hcpriv; + unsigned char *extra; /* Extra descriptors */ + int extralen; + int enabled; +}; + +/* host-side wrapper for one interface setting's parsed descriptors */ +struct usb_host_interface { + struct usb_interface_descriptor desc; + + int extralen; + unsigned char *extra; /* Extra descriptors */ + + /* array of desc.bNumEndpoint endpoints associated with this + * interface setting. these will be in no particular order. + */ + struct usb_host_endpoint *endpoint; + + char *string; /* iInterface string, if present */ +}; + +struct usb_interface { + /* array of alternate settings for this interface, + * stored in no particular order */ + struct usb_host_interface *altsetting; + + struct usb_host_interface *cur_altsetting; /* the currently + * active alternate setting */ + unsigned num_altsetting; /* number of alternate settings */ + + /* If there is an interface association descriptor then it will list + * the associated interfaces */ + struct usb_interface_assoc_descriptor *intf_assoc; + +// int minor; /* minor number this interface is +// * bound to */ + unsigned ep_devs_created:1; /* endpoint "devices" exist */ + unsigned unregistering:1; /* unregistration is in progress */ + unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ + unsigned reset_running:1; + unsigned resetting_device:1; /* true: bandwidth alloc after reset */ + + void *dev_prive_data;/* interface specific device info i.e struct v4l2_device pointer */ + + void *driver; + void *drv_priv; // functional driver priv data + void *usb_dev; +}; +#define to_usb_interface(d) container_of(d, struct usb_interface, usb_dev) + +struct usb_interface_cache { + unsigned num_altsetting; /* number of alternate settings */ + + /* variable-length array of alternate settings for this interface, + * stored in no particular order */ + struct usb_host_interface altsetting[0]; +}; + +struct usb_host_config { + struct usb_config_descriptor desc; + + char *string; /* iConfiguration string, if present */ + + /* List of any Interface Association Descriptors in this + * configuration. */ + struct usb_interface_assoc_descriptor *intf_assoc[USB_MAXIADS]; + + /* the interfaces associated with this configuration, + * stored in no particular order */ + struct usb_interface *interface[USB_MAXINTERFACES]; + + /* Interface information available even when this is not the + * active configuration */ + struct usb_interface_cache *intf_cache[USB_MAXINTERFACES]; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + + + +struct usb_device { + int devnum; + u32 route; + enum usb_device_state state; + enum usb_device_speed speed; + + unsigned int toggle[2]; + + struct usb_device *parent; + struct usb_device *children[USB_MAXCHILDREN]; + void *hcd; + struct usb_host_endpoint ep0; + + struct usb_device_descriptor descriptor; + struct usb_host_config *config; + + struct usb_host_config *actconfig; + struct usb_host_endpoint *ep_in[16]; + struct usb_host_endpoint *ep_out[16]; + int configno; /* selected config number */ + + char **rawdescriptors; + unsigned int rawdeslen[USB_MAXCONFIG]; + +// unsigned short bus_mA; + u8 portnum; + u8 level; + + unsigned can_submit:1; + unsigned persist_enabled:1; + unsigned have_langid:1; + unsigned authorized:1; + unsigned authenticated:1; + int string_langid; + + /* static strings from the device */ +// char *product; +// char *manufacturer; +// char *serial; + + int maxchild; + + u32 quirks; + atomic_t urbnum; + +// unsigned long active_duration; + + char mf[32]; /* manufacturer */ + char prod[32]; /* product */ + char serial[32]; /* serial number */ +#if defined(DWC_WITH_WLAN_OSDEP) + _mutex Mutex; +#else + _Mutex Mutex; +#endif +}; + +/* + * urb->transfer_flags: + * + * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb(). + */ +#define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ +#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame + * ignored */ +#define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ +#define URB_NO_FSBR 0x0020 /* UHCI-specific */ +#define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ +#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt + * needed */ +#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */ + +/* The following flags are used internally by usbcore and HCDs */ +#define URB_DIR_IN 0x0200 /* Transfer from device to host */ +#define URB_DIR_OUT 0 +#define URB_DIR_MASK URB_DIR_IN + +#define URB_DMA_MAP_SINGLE 0x00010000 /* Non-scatter-gather mapping */ +#define URB_DMA_MAP_PAGE 0x00020000 /* HCD-unsupported S-G */ +#define URB_DMA_MAP_SG 0x00040000 /* HCD-supported S-G */ +#define URB_MAP_LOCAL 0x00080000 /* HCD-local-memory mapping */ +#define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */ +#define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */ +#define URB_DMA_SG_COMBINED 0x00400000 /* S-G entries were combined */ +#define URB_ALIGNED_TEMP_BUFFER 0x00800000 /* Temp buffer was alloc'd */ + +struct usb_iso_packet_descriptor { + unsigned int offset; + unsigned int length; /* expected length */ + unsigned int actual_length; + int status; +}; + +struct urb; + +typedef void (*usb_complete_t)(struct urb *); + +struct urb { + /* private: usb core and host controller only fields in the urb */ + void *hcpriv; /* private data for host controller */ + atomic_t use_count; /* concurrent submissions counter */ + atomic_t reject; /* submissions will fail */ + int unlinked; /* unlink error code */ + + /* public: documented fields in the urb that can be used by drivers */ +#if defined(DWC_WITH_WLAN_OSDEP) + _list urb_list; /* list head for use by the urb's + + * current owner */ +// _list anchor_list; /* the URB may be anchored */ +#else + _LIST urb_list; /* list head for use by the urb's + * current owner */ +// _LIST anchor_list; /* the URB may be anchored */ +#endif +// struct usb_anchor *anchor; + struct usb_device *dev; /* (in) pointer to associated device */ + struct usb_host_endpoint *ep; /* (internal) pointer to endpoint */ + unsigned int pipe; /* (in) pipe information */ + unsigned int stream_id; /* (in) stream ID */ + int status; /* (return) non-ISO status */ + unsigned int transfer_flags; /* (in) URB_SHORT_NOT_OK | ...*/ + void *transfer_buffer; /* (in) associated data buffer */ + dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */ + u32 transfer_buffer_length; /* (in) data buffer length */ + u32 actual_length; /* (return) actual transfer length */ + unsigned char *setup_packet; /* (in) setup packet (control only) */ + + int start_frame; /* (modify) start frame (ISO) */ + int number_of_packets; /* (in) number of ISO packets */ + int interval; /* (modify) transfer interval + * (INT/ISO) */ + int error_count; /* (return) number of ISO errors */ + void *context; /* (in) context for completion */ +#if defined(DWC_WITH_WLAN_OSDEP) + _mutex Mutex; // mutext for atomic or link-list operation +#else + _Mutex Mutex; // mutext for atomic or link-list operation +#endif + usb_complete_t complete; /* (in) completion routine */ + unsigned int iso_packets; + struct usb_iso_packet_descriptor iso_frame_desc[0]; + /* (in) ISO ONLY */ +}; + +struct usb_hcd { + + /* + * housekeeping + */ + void *rhdev; /* self usb_dev */ + const char *product_desc; /* product/vendor string */ + int speed; /* Speed for this roothub. + * May be different from + * hcd->driver->flags & HCD_MASK + */ + + struct urb *status_urb; /* the current status urb */ + + /* + * hardware info/state + */ + + + + /* Flags that need to be manipulated atomically because they can + * change while the host controller is running. Always use + * set_bit() or clear_bit() to change their values. + */ + unsigned long flags; + + /* Flags that get set only during HCD registration or removal. */ + unsigned rh_registered:1;/* is root hub registered? */ + unsigned rh_pollable:1; /* may we poll the root hub? */ + unsigned msix_enabled:1; /* driver has MSI-X enabled? */ + + /* The next flag is a stopgap, to be removed when all the HCDs + * support the new root-hub polling mechanism. */ + unsigned uses_new_polling:1; + unsigned authorized_default:1; + unsigned has_tt:1; /* Integrated TT in root hub */ + + + /* bandwidth_mutex should be taken before adding or removing + * any new bus bandwidth constraints: + * 1. Before adding a configuration for a new device. + * 2. Before removing the configuration to put the device into + * the addressed state. + * 3. Before selecting a different configuration. + * 4. Before selecting an alternate interface setting. + * + * bandwidth_mutex should be dropped after a successful control message + * to the device, or resetting the bandwidth after a failed attempt. + */ +#if defined(DWC_WITH_WLAN_OSDEP) + _mutex bandwidth_mutex; +#else + _Mutex bandwidth_mutex; +#endif + + int state; + + int devnum_next; /* Next open device number in + * round-robin allocation */ +#if defined(DWC_WITH_WLAN_OSDEP) + _mutex hcd_urb_list_lock; + _mutex hcd_urb_unlink_lock; + _mutex hcd_root_hub_lock; // mutext for atomic or link-list operation +#else + _Mutex hcd_urb_list_lock; + _Mutex hcd_urb_unlink_lock; + _Mutex hcd_root_hub_lock; // mutext for atomic or link-list operation +#endif + + /* The HC driver's private data is stored at the end of + * this structure. + */ +#ifdef __ICCARM__ + #pragma pack(64) + unsigned long hcd_priv[0]; +#elif defined (__GNUC__) + unsigned long hcd_priv[0]; + __attribute__ ((aligned(sizeof(s64)))); +#endif +}; + + +#define le16_to_cpu rtk_le16_to_cpu +#define cpu_to_le16 rtk_cpu_to_le16 + +#if 0 +/* + * Calling this entity a "pipe" is glorifying it. A USB pipe + * is something embarrassingly simple: it basically consists + * of the following information: + * - device number (7 bits) + * - endpoint number (4 bits) + * - current Data0/1 state (1 bit) + * - direction (1 bit) + * - speed (2 bits) + * - max packet size (2 bits: 8, 16, 32 or 64) + * - pipe type (2 bits: control, interrupt, bulk, isochronous) + * + * That's 18 bits. Really. Nothing more. And the USB people have + * documented these eighteen bits as some kind of glorious + * virtual data structure. + * + * Let's not fall in that trap. We'll just encode it as a simple + * unsigned int. The encoding is: + * + * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64) + * - direction: bit 7 (0 = Host-to-Device [Out], + * (1 = Device-to-Host [In]) + * - device: bits 8-14 + * - endpoint: bits 15-18 + * - Data0/1: bit 19 + * - speed: bit 26 (0 = Full, 1 = Low Speed, 2 = High) + * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, + * 10 = control, 11 = bulk) + * + * Why? Because it's arbitrary, and whatever encoding we select is really + * up to us. This one happens to share a lot of bit positions with the UHCI + * specification, so that much of the uhci driver can just mask the bits + * appropriately. + */ +/* Create various pipes... */ +#define create_pipe(dev,endpoint) \ + (((dev)->devnum << 8) | (endpoint << 15) | \ + ((dev)->speed << 26) | (dev)->maxpacketsize) +#define default_pipe(dev) ((dev)->speed << 26) + +#define usb_sndctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvctrlpipe(dev, endpoint) ((PIPE_CONTROL << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvisocpipe(dev, endpoint) ((PIPE_ISOCHRONOUS << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvbulkpipe(dev, endpoint) ((PIPE_BULK << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_sndintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ + create_pipe(dev, endpoint)) +#define usb_rcvintpipe(dev, endpoint) ((PIPE_INTERRUPT << 30) | \ + create_pipe(dev, endpoint) | \ + USB_DIR_IN) +#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | \ + default_pipe(dev)) +#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | \ + default_pipe(dev) | \ + USB_DIR_IN) + +/* The D0/D1 toggle bits */ +#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1) +#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep)) +#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = \ + ((dev)->toggle[out] & \ + ~(1 << ep)) | ((bit) << ep)) + +/* Endpoint halt control/status */ +#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1) +#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep))) +#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep))) +#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep))) + +#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : \ + USB_PID_OUT) + +#define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1) +#define usb_pipein(pipe) (((pipe) >> 7) & 1) +#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f) +#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff) +#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf) +#define usb_pipedata(pipe) (((pipe) >> 19) & 1) +#define usb_pipespeed(pipe) (((pipe) >> 26) & 3) +#define usb_pipeslow(pipe) (usb_pipespeed(pipe) == USB_SPEED_LOW) +#define usb_pipetype(pipe) (((pipe) >> 30) & 3) +#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) +#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT) +#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) +#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) + +#else +/* ----------------------------------------------------------------------- */ + +/* + * For various legacy reasons, Linux has a small cookie that's paired with + * a struct usb_device to identify an endpoint queue. Queue characteristics + * are defined by the endpoint's descriptor. This cookie is called a "pipe", + * an unsigned int encoded as: + * + * - direction: bit 7 (0 = Host-to-Device [Out], + * 1 = Device-to-Host [In] ... + * like endpoint bEndpointAddress) + * - device address: bits 8-14 ... bit positions known to uhci-hcd + * - endpoint: bits 15-18 ... bit positions known to uhci-hcd + * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, + * 10 = control, 11 = bulk) + * + * Given the device address and endpoint descriptor, pipes are redundant. + */ + +/* NOTE: these are not the standard USB_ENDPOINT_XFER_* values!! */ +/* (yet ... they're the values used by usbfs) */ + +#define usb_pipein(pipe) (((pipe) & USB_DIR_IN) >> 7) +#define usb_pipeout(pipe) (!usb_pipein(pipe)) + +#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f) +#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf) + +#define usb_pipetype(pipe) (((pipe) >> 30) & 3) +#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS) +#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT) +#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL) +#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK) + +static inline unsigned int __create_pipe(struct usb_device *dev, + unsigned int endpoint) +{ + return (dev->devnum << 8) | (endpoint << 15); +} + +#define usb_sndaddr0pipe() (PIPE_CONTROL << 30) +#define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) + +/* Create various pipes... */ +#define usb_sndctrlpipe(dev, endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint)) +#define usb_rcvctrlpipe(dev, endpoint) \ + ((PIPE_CONTROL << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) +#define usb_sndisocpipe(dev, endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint)) +#define usb_rcvisocpipe(dev, endpoint) \ + ((PIPE_ISOCHRONOUS << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) +#define usb_sndbulkpipe(dev, endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev, endpoint)) +#define usb_rcvbulkpipe(dev, endpoint) \ + ((PIPE_BULK << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) +#define usb_sndintpipe(dev, endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint)) +#define usb_rcvintpipe(dev, endpoint) \ + ((PIPE_INTERRUPT << 30) | __create_pipe(dev, endpoint) | USB_DIR_IN) + +static inline struct usb_host_endpoint * +usb_pipe_endpoint(struct usb_device *dev, unsigned int pipe) +{ + struct usb_host_endpoint **eps; + eps = usb_pipein(pipe) ? dev->ep_in : dev->ep_out; + return eps[usb_pipeendpoint(pipe)]; +} + +/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ +#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) +#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) +#define usb_settoggle(dev, ep, out, bit) \ + ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ + ((bit) << (ep))) +#endif + +/************************************************************************* + * Hub Stuff + */ +struct usb_port_status { + unsigned short wPortStatus; + unsigned short wPortChange; +} UPACKED; + +struct usb_hub_status { + unsigned short wHubStatus; + unsigned short wHubChange; +}UPACKED; + + +/* Hub descriptor */ +struct usb_hub_descriptor { + unsigned char bLength; + unsigned char bDescriptorType; + unsigned char bNbrPorts; + unsigned short wHubCharacteristics; + unsigned char bPwrOn2PwrGood; + unsigned char bHubContrCurrent; + unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8]; + unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8]; + /* DeviceRemovable and PortPwrCtrlMask want to be variable-length + bitmaps that hold max 255 entries. (bit0 is ignored) */ +}UPACKED; + + +struct usb_hub_device { + struct usb_device *pusb_dev; + struct usb_hub_descriptor desc; +}; + +/*-------------------------------------------------------------------------*/ + +/** + * usb_endpoint_num - get the endpoint's number + * @epd: endpoint to be checked + * + * Returns @epd's number: 0 to 15. + */ +static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) +{ + return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +} + +/** + * usb_endpoint_type - get the endpoint's transfer type + * @epd: endpoint to be checked + * + * Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according + * to @epd's transfer type. + */ +static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd) +{ + return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; +} + +/** + * usb_endpoint_dir_in - check if the endpoint has IN direction + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type IN, otherwise it returns false. + */ +static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN); +} + +/** + * usb_endpoint_dir_out - check if the endpoint has OUT direction + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type OUT, otherwise it returns false. + */ +static inline int usb_endpoint_dir_out( + const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); +} + +#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) + +/** + * usb_endpoint_xfer_bulk - check if the endpoint has bulk transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type bulk, otherwise it returns false. + */ +static inline int usb_endpoint_xfer_bulk( + const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK); +} + +/** + * usb_endpoint_xfer_control - check if the endpoint has control transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type control, otherwise it returns false. + */ +static inline int usb_endpoint_xfer_control( + const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL); +} + +/** + * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type interrupt, otherwise it returns + * false. + */ +static inline int usb_endpoint_xfer_int( + const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT); +} + +/** + * usb_endpoint_xfer_isoc - check if the endpoint has isochronous transfer type + * @epd: endpoint to be checked + * + * Returns true if the endpoint is of type isochronous, otherwise it returns + * false. + */ +static inline int usb_endpoint_xfer_isoc( + const struct usb_endpoint_descriptor *epd) +{ + return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC); +} + +/** + * usb_endpoint_is_bulk_in - check if the endpoint is bulk IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has bulk transfer type and IN direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_bulk_in( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_in(epd); +} + +/** + * usb_endpoint_is_bulk_out - check if the endpoint is bulk OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has bulk transfer type and OUT direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_bulk_out( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_bulk(epd) && usb_endpoint_dir_out(epd); +} + +/** + * usb_endpoint_is_int_in - check if the endpoint is interrupt IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has interrupt transfer type and IN direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_int_in( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd); +} + +/** + * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has interrupt transfer type and OUT direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_int_out( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd); +} + +/** + * usb_endpoint_is_isoc_in - check if the endpoint is isochronous IN + * @epd: endpoint to be checked + * + * Returns true if the endpoint has isochronous transfer type and IN direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_isoc_in( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_in(epd); +} + +/** + * usb_endpoint_is_isoc_out - check if the endpoint is isochronous OUT + * @epd: endpoint to be checked + * + * Returns true if the endpoint has isochronous transfer type and OUT direction, + * otherwise it returns false. + */ +static inline int usb_endpoint_is_isoc_out( + const struct usb_endpoint_descriptor *epd) +{ + return usb_endpoint_xfer_isoc(epd) && usb_endpoint_dir_out(epd); +} + +/** + * usb_endpoint_maxp - get endpoint's max packet size + * @epd: endpoint to be checked + * + * Returns @epd's max packet + */ +static inline int usb_endpoint_maxp(const struct usb_endpoint_descriptor *epd) +{ + return rtk_le16_to_cpu(epd->wMaxPacketSize); +} + +/** + * usb_urb_dir_in - check if an URB describes an IN transfer + * @urb: URB to be checked + * + * Returns 1 if @urb describes an IN transfer (device-to-host), + * otherwise 0. + */ +static inline int usb_urb_dir_in(struct urb *urb) +{ + return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_IN; +} + +/** + * usb_urb_dir_out - check if an URB describes an OUT transfer + * @urb: URB to be checked + * + * Returns 1 if @urb describes an OUT transfer (host-to-device), + * otherwise 0. + */ +static inline int usb_urb_dir_out(struct urb *urb) +{ + return (urb->transfer_flags & URB_DIR_MASK) == URB_DIR_OUT; +} + +/** + * usb_get_dev - increments the reference count of the usb device structure + * @dev: the device being referenced + * + * Each live reference to a device should be refcounted. + * + * Drivers for USB interfaces should normally record such references in + * their probe() methods, when they bind to an interface, and release + * them by calling usb_put_dev(), in their disconnect() methods. + * + * A pointer to the device with the incremented reference counter is returned. + */ +static inline void *usb_get_dev(struct usb_device *dev) +{ + return dev; +} + +/** + * usb_put_dev - release a use of the usb device structure + * @dev: device that's been disconnected + * + * Must be called when a user of a device is finished with it. When the last + * user of the device calls this function, the memory of the device is freed. + */ +static inline void usb_put_dev(struct usb_device *dev) +{ +} + +/** + * usb_get_intf - increments the reference count of the usb interface structure + * @intf: the interface being referenced + * + * Each live reference to a interface must be refcounted. + * + * Drivers for USB interfaces should normally record such references in + * their probe() methods, when they bind to an interface, and release + * them by calling usb_put_intf(), in their disconnect() methods. + * + * A pointer to the interface with the incremented reference counter is + * returned. + */ +static inline void *usb_get_intf(struct usb_interface *intf) +{ + return intf; +} + +/** + * usb_put_intf - release a use of the usb interface structure + * @intf: interface that's been decremented + * + * Must be called when a user of an interface is finished with it. When the + * last user of the interface calls this function, the memory of the interface + * is freed. + */ +static inline void usb_put_intf(struct usb_interface *intf) +{ +} + +static inline void *usb_get_intfdata(struct usb_interface *intf) +{ + return (intf->drv_priv); +} + +static inline void usb_set_intfdata(struct usb_interface *intf, void *data) +{ + intf->drv_priv = data; +} + +static inline struct usb_device *interface_to_usbdev(struct usb_interface *intf) +{ + return intf->usb_dev; +} + +static inline struct usb_driver *interface_to_usbdri(struct usb_interface *intf) +{ + return intf->driver; +} + +/*-------------------------------------------------------------------------*/ + +/*=====================================================*/ + + +#ifdef DWC_HOST_ONLY +typedef struct { + uByte bLength; + uByte bDescriptorType; + uByte bEndpointAddress; +#define UE_GET_DIR(a) ((a) & 0x80) +#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7)) +#define UE_DIR_IN 0x01 +#define UE_DIR_OUT 0x00 +#define UE_ADDR 0x0f +#define UE_GET_ADDR(a) ((a) & UE_ADDR) + uByte bmAttributes; +#define UE_XFERTYPE 0x03 +#define UE_CONTROL 0x00 +#define UE_ISOCHRONOUS 0x01 +#define UE_BULK 0x02 +#define UE_INTERRUPT 0x03 +#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE) +#if 0 +#define UE_ISO_TYPE 0x0c +#define UE_ISO_ASYNC 0x04 +#define UE_ISO_ADAPT 0x08 +#define UE_ISO_SYNC 0x0c +#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE) +#endif + uWord wMaxPacketSize; + uByte bInterval; +} usb_endpoint_descriptor_t;//UPACKED usb_endpoint_descriptor_t; +#define USB_ENDPOINT_DESCRIPTOR_SIZE 7 +#endif +#ifdef DWC_DEVICE_ONLY +typedef struct { + uByte bLength; + uByte bDescriptorType; + uByte bEndpointAddress; +#define UE_GET_DIR(a) ((a) & 0x80) +#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7)) +#define UE_DIR_IN 0x80 +#define UE_DIR_OUT 0x00 +#define UE_ADDR 0x0f +#define UE_GET_ADDR(a) ((a) & UE_ADDR) + uByte bmAttributes; +#define UE_XFERTYPE 0x03 +#define UE_CONTROL 0x00 +#define UE_ISOCHRONOUS 0x01 +#define UE_BULK 0x02 +#define UE_INTERRUPT 0x03 +#define UE_GET_XFERTYPE(a) ((a) & UE_XFERTYPE) +#define UE_ISO_TYPE 0x0c +#define UE_ISO_ASYNC 0x04 +#define UE_ISO_ADAPT 0x08 +#define UE_ISO_SYNC 0x0c +#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE) + uWord wMaxPacketSize; + uByte bInterval; +} UPACKED usb_endpoint_descriptor_t; +#endif + +typedef struct ss_endpoint_companion_descriptor { + uByte bLength; + uByte bDescriptorType; + uByte bMaxBurst; +#define USSE_GET_MAX_STREAMS(a) ((a) & 0x1f) +#define USSE_SET_MAX_STREAMS(a, b) ((a) | ((b) & 0x1f)) +#define USSE_GET_MAX_PACKET_NUM(a) ((a) & 0x03) +#define USSE_SET_MAX_PACKET_NUM(a, b) ((a) | ((b) & 0x03)) + uByte bmAttributes; + uWord wBytesPerInterval; +} UPACKED ss_endpoint_companion_descriptor_t; +#define USB_SS_ENDPOINT_COMPANION_DESCRIPTOR_SIZE 6 + +typedef struct { + uByte bLength; + uByte bDescriptorType; + uWord bString[127]; +} UPACKED usb_string_descriptor_t; +#define USB_MAX_STRING_LEN 128 +#define USB_LANGUAGE_TABLE 0 /* # of the string language id table */ + + +/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ + +/* USB_DT_OTG (from OTG 1.0a supplement) */ + +/* from usb_otg_descriptor.bmAttributes */ +#define USB_OTG_SRP (1 << 0) +#define USB_OTG_HNP (1 << 1) /* swap host/device roles */ + + +extern void _usb_init(void); +extern void _usb_deinit(void); +extern int wait_usb_ready(void); +extern void usb_disable_asynch(int disable); +extern unsigned short usb_maxpacket(struct usb_device *udev, int pipe, int is_out); +extern int usb_set_interface(struct usb_device *dev, int interface, int alternate); +extern int usb_set_configuration(struct usb_device *dev, int configuration); + +extern int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); +extern int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); +extern int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, + unsigned char id, void *buf, int size); +extern int usb_get_class_descriptor(struct usb_device *dev, int ifnum, + unsigned char type, unsigned char id, void *buf, int size); +extern int usb_string(struct usb_device *dev, int index, char *buf, int size); + +extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status); +extern struct usb_hcd *usb_create_hcd(unsigned int priv_size); +extern int usb_add_hcd(struct usb_hcd *hcd); + +extern struct urb *usb_alloc_urb(int iso_packets); +extern void usb_free_urb(struct urb *urb); +extern void usb_kill_urb(struct urb *urb); +extern void usb_fill_control_urb(struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + unsigned char *setup_packet, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete_fn, + void *context); +extern void usb_fill_bulk_urb(struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete_fn, + void *context); +extern void usb_fill_int_urb(struct urb *urb, + struct usb_device *dev, + unsigned int pipe, + void *transfer_buffer, + int buffer_length, + usb_complete_t complete_fn, + void *context, + int interval); +extern int usb_submit_urb(struct urb *urb); + +extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr); +extern void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, + bool reset_hardware); +extern void usb_enable_interface(struct usb_device *dev, + struct usb_interface *intf, bool reset_eps); + +extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, u8 request, + u8 requesttype, u16 value, u16 index, void *data, + u16 size, int timeout); +extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, int timeout); +extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, int timeout); +extern int usb_get_descriptor(struct usb_device *dev, unsigned char type, + unsigned char index, void *buf, int size); +extern int usb_get_device_descriptor(struct usb_device *dev, unsigned int size); +extern int usb_clear_halt(struct usb_device *dev, int pipe); +#if defined(DWC_WITH_WLAN_OSDEP) +extern _sema CtrlUrbCompSema; /* Semaphore for for Control URB Complete waiting */ +extern _sema UrbKillSema; /* Semaphore for for URB Kill waiting */ +#else +extern _Sema CtrlUrbCompSema; /* Semaphore for for Control URB Complete waiting */ +extern _Sema UrbKillSema; /* Semaphore for for URB Kill waiting */ +#endif +typedef unsigned long kernel_ulong_t; + +struct usb_device_id { + /* which fields to match against? */ + u16 match_flags; + + /* Used for product specific matches; range is inclusive */ + u16 idVendor; + u16 idProduct; + u16 bcdDevice_lo; + u16 bcdDevice_hi; + + /* Used for device class matches */ + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + + /* Used for interface class matches */ + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + + /* Used for vendor-specific interface matches */ + u8 bInterfaceNumber; + + /* not matched against */ +#ifdef __ICCARM__ + #pragma pack(64) + kernel_ulong_t driver_info; +#elif defined (__GNUC__) + kernel_ulong_t driver_info; + __attribute__((aligned(sizeof(kernel_ulong_t)))); +#endif +}; + +/* Some useful macros to use to create struct usb_device_id */ +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400 + +#define USB_DEVICE_ID_MATCH_DEVICE \ + (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT) +#define USB_DEVICE_ID_MATCH_DEV_RANGE \ + (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI) +#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION \ + (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE) +#define USB_DEVICE_ID_MATCH_DEV_INFO \ + (USB_DEVICE_ID_MATCH_DEV_CLASS | \ + USB_DEVICE_ID_MATCH_DEV_SUBCLASS | \ + USB_DEVICE_ID_MATCH_DEV_PROTOCOL) +#define USB_DEVICE_ID_MATCH_INT_INFO \ + (USB_DEVICE_ID_MATCH_INT_CLASS | \ + USB_DEVICE_ID_MATCH_INT_SUBCLASS | \ + USB_DEVICE_ID_MATCH_INT_PROTOCOL) +/** + * USB_DEVICE - macro used to describe a specific usb device + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * + * This macro is used to create a struct usb_device_id that matches a + * specific device. + */ +#define USB_DEVICE(vend, prod) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ + .idVendor = (vend), \ + .idProduct = (prod) + +/** + * USB_DEVICE_VER - describe a specific usb device with a version range + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @lo: the bcdDevice_lo value + * @hi: the bcdDevice_hi value + * + * This macro is used to create a struct usb_device_id that matches a + * specific device, with a version range. + */ +#define USB_DEVICE_VER(vend, prod, lo, hi) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bcdDevice_lo = (lo), \ + .bcdDevice_hi = (hi) + +/** + * USB_INTERFACE_INFO - macro used to describe a class of usb interfaces + * @cl: bInterfaceClass value + * @sc: bInterfaceSubClass value + * @pr: bInterfaceProtocol value + * + * This macro is used to create a struct usb_device_id that matches a + * specific class of interfaces. + */ +#define USB_INTERFACE_INFO(cl, sc, pr) \ + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \ + .bInterfaceClass = (cl), \ + .bInterfaceSubClass = (sc), \ + .bInterfaceProtocol = (pr) + +typedef enum{ + USB_INIT_NONE = -1, + USB_INIT_OK = 0, + USB_INIT_FAIL = 1, + USB_NOT_ATTACHED = 2 +}_usb_init_s; + +struct usb_driver { + const char *name; + + int (*probe) (struct usb_interface *intf); + + void (*disconnect) (struct usb_interface *intf); + + int (*resume) (struct usb_interface *intf); + int (*reset_resume)(struct usb_interface *intf); + + int (*pre_reset)(struct usb_interface *intf); + int (*post_reset)(struct usb_interface *intf); + + const struct usb_device_id *id_table; +}; + +int usb_register_class_driver(struct usb_driver *driver); +#endif /* _USB_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ch9.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ch9.h new file mode 100644 index 0000000..26535e5 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ch9.h @@ -0,0 +1,563 @@ +/* + * This file holds USB constants and structures that are needed for USB + * device APIs. These are used by the USB device model, which is defined + * in chapter 9 of the USB 2.0 specification. Linux has several APIs in C + * that need these: + * + * - the master/host side Linux-USB kernel driver API; + * - the "usbfs" user space API; and + * - the Linux "gadget" slave/device/peripheral side driver API. + * + * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems + * act either as a USB master/host or as a USB slave/device. That means + * the master and slave side APIs benefit from working well together. + * + * There's also "Wireless USB", using low power short range radios for + * peripheral interconnection but otherwise building on the USB framework. + */ + + +#ifndef _USB_CH9_H_ +#define _USB_CH9_H_ + +#include "basic_types.h" +//#include /* __u8 etc */ +//#include "../otg/osk/sys-support.h" + +/*-------------------------------------------------------------------------*/ + +/* CONTROL REQUEST SUPPORT */ + +/* + * USB directions + * + * This bit flag is used in endpoint descriptors' bEndpointAddress field. + * It's also one of three fields in control requests bRequestType. + */ +//#define USB_DIR_OUT 0 /* to device */ +//#define USB_DIR_IN 0x80 /* to host */ + +/* + * USB types, the second of three bRequestType fields + */ +#define USB_TYPE_MASK (0x03 << 5) +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +/* + * USB recipients, the third of three bRequestType fields + */ +#define USB_RECIP_MASK 0x1f +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 +/* From Wireless USB 1.0 */ +#define USB_RECIP_PORT 0x04 +#define USB_RECIP_RPIPE 0x05 + +/* + * Standard requests, for the bRequest field of a SETUP packet. + * + * These are qualified by the bRequestType field, so that for example + * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved + * by a GET_STATUS request. + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */ +#define USB_REQ_GET_ENCRYPTION 0x0E +#define USB_REQ_RPIPE_ABORT 0x0E +#define USB_REQ_SET_HANDSHAKE 0x0F +#define USB_REQ_RPIPE_RESET 0x0F +#define USB_REQ_GET_HANDSHAKE 0x10 +#define USB_REQ_SET_CONNECTION 0x11 +#define USB_REQ_SET_SECURITY_DATA 0x12 +#define USB_REQ_GET_SECURITY_DATA 0x13 +#define USB_REQ_SET_WUSB_DATA 0x14 +#define USB_REQ_LOOPBACK_DATA_WRITE 0x15 +#define USB_REQ_LOOPBACK_DATA_READ 0x16 +#define USB_REQ_SET_INTERFACE_DS 0x17 + +/* + * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and + * are read as a bit array returned by USB_REQ_GET_STATUS. (So there + * are at most sixteen features of each type.) + */ +#define USB_DEVICE_SELF_POWERED 0 /* (read only) */ +#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */ +#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */ +#define USB_DEVICE_BATTERY 2 /* (wireless) */ +#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */ +#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/ +#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */ +#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */ +#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */ + +#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ + + +/** + * struct usb_ctrlrequest - SETUP data for a USB device control request + * @bRequestType: matches the USB bmRequestType field + * @bRequest: matches the USB bRequest field + * @wValue: matches the USB wValue field (le16 byte order) + * @wIndex: matches the USB wIndex field (le16 byte order) + * @wLength: matches the USB wLength field (le16 byte order) + * + * This structure is used to send control requests to a USB device. It matches + * the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the + * USB spec for a fuller description of the different fields, and what they are + * used for. + * + * Note that the driver for any interface can issue control requests. + * For most devices, interfaces don't coordinate with each other, so + * such requests may be made at any time. + */ +struct usb_ctrlrequest { + u8 bRequestType; + u8 bRequest; + u16 wValue; + u16 wIndex; + u16 wLength; +}; + +/*-------------------------------------------------------------------------*/ + +/* + * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or + * (rarely) accepted by SET_DESCRIPTOR. + * + * Note that all multi-byte values here are encoded in little endian + * byte order "on the wire". But when exposed through Linux-USB APIs, + * they've been converted to cpu byte order. + */ + +/* + * Descriptor types ... USB 2.0 spec table 9.5 + */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE_QUALIFIER 0x06 +#define USB_DT_OTHER_SPEED_CONFIG 0x07 +#define USB_DT_INTERFACE_POWER 0x08 +/* these are from a minor usb 2.0 revision (ECN) */ +#define USB_DT_OTG 0x09 +#define USB_DT_DEBUG 0x0a +#define USB_DT_INTERFACE_ASSOCIATION 0x0b +/* these are from the Wireless USB spec */ +#define USB_DT_SECURITY 0x0c +#define USB_DT_KEY 0x0d +#define USB_DT_ENCRYPTION_TYPE 0x0e +#define USB_DT_BOS 0x0f +#define USB_DT_DEVICE_CAPABILITY 0x10 +#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 +#define USB_DT_WIRE_ADAPTER 0x21 +#define USB_DT_RPIPE 0x22 + +/* conventional codes for class-specific descriptors */ +#define USB_DT_CS_DEVICE 0x21 +#define USB_DT_CS_CONFIG 0x22 +#define USB_DT_CS_STRING 0x23 +#define USB_DT_CS_INTERFACE 0x24 +#define USB_DT_CS_ENDPOINT 0x25 + +/* All standard descriptors have these 2 fields at the beginning */ +struct usb_descriptor_header { + u8 bLength; + u8 bDescriptorType; +}; + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE: Device descriptor */ +struct usb_device_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u16 idVendor; + u16 idProduct; + u16 bcdDevice; + u8 iManufacturer; + u8 iProduct; + u8 iSerialNumber; + u8 bNumConfigurations; +}; + +#define USB_DT_DEVICE_SIZE 18 + + +/* + * Device and/or Interface Class codes + * as found in bDeviceClass or bInterfaceClass + * and defined by www.usb.org documents + */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PHYSICAL 5 +#define USB_CLASS_STILL_IMAGE 6 +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_CDC_DATA 0x0a +#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ +#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ +#define USB_CLASS_VIDEO 0x0e +#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 +#define USB_CLASS_APP_SPEC 0xfe +#define USB_CLASS_VENDOR_SPEC 0xff + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_CONFIG: Configuration descriptor information. + * + * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the + * descriptor type is different. Highspeed-capable devices can look + * different depending on what speed they're currently running. Only + * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG + * descriptors. + */ +struct usb_config_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 wTotalLength; + u8 bNumInterfaces; + u8 bConfigurationValue; + u8 iConfiguration; + u8 bmAttributes; + u8 bMaxPower; +}; + +#define USB_DT_CONFIG_SIZE 9 + +/* from config descriptor bmAttributes */ +#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ +#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ +#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ +#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_STRING: String descriptor */ +struct usb_string_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 wData[1]; /* UTF-16LE encoded */ +}; + +/* note that "string" zero is special, it holds language codes that + * the device supports, not Unicode characters. + */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_INTERFACE: Interface descriptor */ +struct usb_interface_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 bInterfaceNumber; + u8 bAlternateSetting; + u8 bNumEndpoints; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + u8 bInterfaceProtocol; + u8 iInterface; +}; + +#define USB_DT_INTERFACE_SIZE 9 + +/*-------------------------------------------------------------------------*/ + +/* Endpoint descriptor */ +struct usb_endpoint_descriptor { + u8 bLength; + u8 bDescriptorType; + u8 bEndpointAddress; + u8 bmAttributes; + u16 wMaxPacketSize; + u8 bInterval; + u8 bRefresh; + u8 bSynchAddress; + + unsigned char *extra; /* Extra descriptors */ + int extralen; +}; + +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ + + +/* + * Endpoints + */ +#if 0 +#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_XFER_CONTROL 0 +#define USB_ENDPOINT_XFER_ISOC 1 +#define USB_ENDPOINT_XFER_BULK 2 +#define USB_ENDPOINT_XFER_INT 3 +#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 +#endif + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ +struct usb_qualifier_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 bcdUSB; + u8 bDeviceClass; + u8 bDeviceSubClass; + u8 bDeviceProtocol; + u8 bMaxPacketSize0; + u8 bNumConfigurations; + u8 bRESERVED; +}; + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_OTG (from OTG 1.0a supplement) */ +struct usb_otg_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 bmAttributes; /* support for HNP, SRP, etc */ +}; + +/* from usb_otg_descriptor.bmAttributes */ +#define USB_OTG_SRP (1 << 0) +#define USB_OTG_HNP (1 << 1) /* swap host/device roles */ + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */ +struct usb_debug_descriptor { + u8 bLength; + u8 bDescriptorType; + + /* bulk endpoints with 8 byte maxpacket */ + u8 bDebugInEndpoint; + u8 bDebugOutEndpoint; +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */ +struct usb_interface_assoc_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 bFirstInterface; + u8 bInterfaceCount; + u8 bFunctionClass; + u8 bFunctionSubClass; + u8 bFunctionProtocol; + u8 iFunction; +}; + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_SECURITY: group of wireless security descriptors, including + * encryption types available for setting up a CC/association. + */ +struct usb_security_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 wTotalLength; + u8 bNumEncryptionTypes; +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys + * may be retrieved. + */ +struct usb_key_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 tTKID[3]; + u8 bReserved; + u8 bKeyData[0]; +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */ +struct usb_encryption_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 bEncryptionType; +#define USB_ENC_TYPE_UNSECURE 0 +#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */ +#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */ +#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ + u8 bEncryptionValue; /* use in SET_ENCRYPTION */ + u8 bAuthKeyIndex; +}; + + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_BOS: group of wireless capabilities */ +struct usb_bos_descriptor { + u8 bLength; + u8 bDescriptorType; + + u16 wTotalLength; + u8 bNumDeviceCaps; +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */ +struct usb_dev_cap_header { + u8 bLength; + u8 bDescriptorType; + u8 bDevCapabilityType; +}; + +#define USB_CAP_TYPE_WIRELESS_USB 1 + +struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ + u8 bLength; + u8 bDescriptorType; + u8 bDevCapabilityType; + + u8 bmAttributes; +#define USB_WIRELESS_P2P_DRD (1 << 1) +#define USB_WIRELESS_BEACON_MASK (3 << 2) +#define USB_WIRELESS_BEACON_SELF (1 << 2) +#define USB_WIRELESS_BEACON_DIRECTED (2 << 2) +#define USB_WIRELESS_BEACON_NONE (3 << 2) + u16 wPHYRates; /* bit rates, Mbps */ +#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */ +#define USB_WIRELESS_PHY_80 (1 << 1) +#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */ +#define USB_WIRELESS_PHY_160 (1 << 3) +#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */ +#define USB_WIRELESS_PHY_320 (1 << 5) +#define USB_WIRELESS_PHY_400 (1 << 6) +#define USB_WIRELESS_PHY_480 (1 << 7) + u8 bmTFITXPowerInfo; /* TFI power levels */ + u8 bmFFITXPowerInfo; /* FFI power levels */ + u16 bmBandGroup; + u8 bReserved; +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with + * each endpoint descriptor for a wireless device + */ +struct usb_wireless_ep_comp_descriptor { + u8 bLength; + u8 bDescriptorType; + + u8 bMaxBurst; + u8 bMaxSequence; + u16 wMaxStreamDelay; + u16 wOverTheAirPacketSize; + u8 bOverTheAirInterval; + u8 bmCompAttributes; +#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */ +#define USB_ENDPOINT_SWITCH_NO 0 +#define USB_ENDPOINT_SWITCH_SWITCH 1 +#define USB_ENDPOINT_SWITCH_SCALE 2 +}; + +/*-------------------------------------------------------------------------*/ + +/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless + * host and a device for connection set up, mutual authentication, and + * exchanging short lived session keys. The handshake depends on a CC. + */ +struct usb_handshake { + u8 bMessageNumber; + u8 bStatus; + u8 tTKID[3]; + u8 bReserved; + u8 CDID[16]; + u8 nonce[16]; + u8 MIC[8]; +}; + + +/*-------------------------------------------------------------------------*/ + +/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC). + * A CC may also be set up using non-wireless secure channels (including + * wired USB!), and some devices may support CCs with multiple hosts. + */ +struct usb_connection_context { + u8 CHID[16]; /* persistent host id */ + u8 CDID[16]; /* device id (unique w/in host context) */ + u8 CK[16]; /* connection key */ +}; + +/*-------------------------------------------------------------------------*/ + +#if 1 + + + + +enum usb_device_state { + /* NOTATTACHED isn't in the USB spec, and this state acts + * the same as ATTACHED ... but it's clearer this way. + */ + USB_STATE_NOTATTACHED = 0, + + /* chapter 9 and authentication (wireless) device states */ + USB_STATE_ATTACHED, + USB_STATE_POWERED, /* wired */ + USB_STATE_UNAUTHENTICATED, /* auth */ + USB_STATE_RECONNECTING, /* auth */ + USB_STATE_DEFAULT, /* limited function */ + USB_STATE_ADDRESS, + USB_STATE_CONFIGURED, /* most functions */ + + USB_STATE_SUSPENDED + + /* NOTE: there are actually four different SUSPENDED + * states, returning to POWERED, DEFAULT, ADDRESS, or + * CONFIGURED respectively when SOF tokens flow again. + */ +}; +#endif +#endif /* __LINUX_USB_CH9_H */ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_defs.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_defs.h new file mode 100644 index 0000000..d57bc9f --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_defs.h @@ -0,0 +1,378 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Note: Part of this code has been derived from linux + * + */ +#ifndef _USB_DEFS_H_ +#define _USB_DEFS_H_ +/* USB constants */ + +/* Device and/or Interface Class codes */ +#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ +#define USB_CLASS_AUDIO 1 +#define USB_CLASS_COMM 2 +#define USB_CLASS_HID 3 +#define USB_CLASS_PHYSICAL 5 +#define USB_CLASS_STILL_IMAGE 6 + +#define USB_CLASS_PRINTER 7 +#define USB_CLASS_MASS_STORAGE 8 +#define USB_CLASS_HUB 9 +#define USB_CLASS_CDC_DATA 0x0a + +#define USB_CLASS_DATA 10 +#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ +#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ +#define USB_CLASS_VIDEO 0x0e +#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 +#define USB_CLASS_APP_SPEC 0xfe + +#define USB_CLASS_VENDOR_SPEC 0xff + +/* some HID sub classes */ +#define USB_SUB_HID_NONE 0 +#define USB_SUB_HID_BOOT 1 + +/* some UID Protocols */ +#define USB_PROT_HID_NONE 0 +#define USB_PROT_HID_KEYBOARD 1 +#define USB_PROT_HID_MOUSE 2 + + +/* Sub STORAGE Classes */ +#define US_SC_RBC 1 /* Typically, flash devices */ +#define US_SC_8020 2 /* CD-ROM */ +#define US_SC_QIC 3 /* QIC-157 Tapes */ +#define US_SC_UFI 4 /* Floppy */ +#define US_SC_8070 5 /* Removable media */ +#define US_SC_SCSI 6 /* Transparent */ +#define US_SC_MIN US_SC_RBC +#define US_SC_MAX US_SC_SCSI + +/* STORAGE Protocols */ +#define US_PR_CB 1 /* Control/Bulk w/o interrupt */ +#define US_PR_CBI 0 /* Control/Bulk/Interrupt */ +#define US_PR_BULK 0x50 /* bulk only */ + +/* USB types */ +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +/* USB recipients */ +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + + +#define USB_DT_CS_DEVICE 0x21 +#define USB_DT_CS_CONFIG 0x22 +#define USB_DT_CS_STRING 0x23 +#define USB_DT_CS_INTERFACE 0x24 +#define USB_DT_CS_ENDPOINT 0x25 + + +/* USB directions */ +#define USB_DIR_OUT 0 /* to device */ +#define USB_DIR_IN 0x80 /* to host */ + +#if 0 +enum usb_device_speed { + USB_SPEED_UNKNOWN = 0, /* enumerating */ + USB_SPEED_LOW, + USB_SPEED_FULL, /* usb 1.1 */ + USB_SPEED_HIGH, /* usb 2.0 */ +}; +#else +enum usb_device_speed { + USB_SPEED_UNKNOWN = 0, /* enumerating */ + USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ + USB_SPEED_HIGH, /* usb 2.0 */ + USB_SPEED_VARIABLE, /* wireless (usb 2.5) */ +}; + +#endif +/* Descriptor types */ +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 +#define USB_DT_DEVICE_QUALIFIER 0x06 +#define USB_DT_OTHER_SPEED_CONFIG 0x07 +#define USB_DT_INTERFACE_POWER 0x08 +/* these are from a minor usb 2.0 revision (ECN) */ +#define USB_DT_OTG 0x09 +#define USB_DT_DEBUG 0x0a +#define USB_DT_INTERFACE_ASSOCIATION 0x0b +/* these are from the Wireless USB spec */ +#define USB_DT_SECURITY 0x0c +#define USB_DT_KEY 0x0d +#define USB_DT_ENCRYPTION_TYPE 0x0e +#define USB_DT_BOS 0x0f +#define USB_DT_DEVICE_CAPABILITY 0x10 +#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 +#define USB_DT_WIRE_ADAPTER 0x21 +#define USB_DT_RPIPE 0x22 + +//#define USB_DT_INTERFACE_ASSOCIATION 0x0b + +#define USB_DT_HID (USB_TYPE_CLASS | 0x01) +#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02) +#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) +#define USB_DT_HUB (USB_TYPE_CLASS | 0x09) + +/* Descriptor sizes per descriptor type */ +#define USB_DT_DEVICE_SIZE 18 +#define USB_DT_CONFIG_SIZE 9 +#define USB_DT_INTERFACE_SIZE 9 +#define USB_DT_ENDPOINT_SIZE 7 +#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ +#define USB_DT_HUB_NONVAR_SIZE 7 +#define USB_DT_HID_SIZE 9 + +/* Endpoints */ +#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ +#define USB_ENDPOINT_DIR_MASK 0x80 + +#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ +#define USB_ENDPOINT_XFER_CONTROL 0 +#define USB_ENDPOINT_XFER_ISOC 1 +#define USB_ENDPOINT_XFER_BULK 2 +#define USB_ENDPOINT_XFER_INT 3 + +#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ + +/* USB Packet IDs (PIDs) */ +#define USB_PID_UNDEF_0 0xf0 +#define USB_PID_OUT 0xe1 +#define USB_PID_ACK 0xd2 +#define USB_PID_DATA0 0xc3 +#define USB_PID_UNDEF_4 0xb4 +#define USB_PID_SOF 0xa5 +#define USB_PID_UNDEF_6 0x96 +#define USB_PID_UNDEF_7 0x87 +#define USB_PID_UNDEF_8 0x78 +#define USB_PID_IN 0x69 +#define USB_PID_NAK 0x5a +#define USB_PID_DATA1 0x4b +#define USB_PID_PREAMBLE 0x3c +#define USB_PID_SETUP 0x2d +#define USB_PID_STALL 0x1e +#define USB_PID_UNDEF_F 0x0f + +/* Standard requests */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +/* HID requests */ +#define USB_REQ_GET_REPORT 0x01 +#define USB_REQ_GET_IDLE 0x02 +#define USB_REQ_GET_PROTOCOL 0x03 +#define USB_REQ_SET_REPORT 0x09 +#define USB_REQ_SET_IDLE 0x0A +#define USB_REQ_SET_PROTOCOL 0x0B + + +/* "pipe" definitions */ + +#define PIPE_ISOCHRONOUS 0 +#define PIPE_INTERRUPT 1 +#define PIPE_CONTROL 2 +#define PIPE_BULK 3 +#define PIPE_DEVEP_MASK 0x0007ff00 + +#define USB_ISOCHRONOUS 0 +#define USB_INTERRUPT 1 +#define USB_CONTROL 2 +#define USB_BULK 3 + +/* USB-status codes: */ +#define USB_ST_ACTIVE 0x1 /* TD is active */ +#define USB_ST_STALLED 0x2 /* TD is stalled */ +#define USB_ST_BUF_ERR 0x4 /* buffer error */ +#define USB_ST_BABBLE_DET 0x8 /* Babble detected */ +#define USB_ST_NAK_REC 0x10 /* NAK Received*/ +#define USB_ST_CRC_ERR 0x20 /* CRC/timeout Error */ +#define USB_ST_BIT_ERR 0x40 /* Bitstuff error */ +#define USB_ST_NOT_PROC 0x80000000L /* Not yet processed */ + + +/************************************************************************* + * Hub defines + */ + +/* + * Hub request types + */ + +#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE) +#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER) + +/* + * Hub Class feature numbers + */ +#define C_HUB_LOCAL_POWER 0 +#define C_HUB_OVER_CURRENT 1 + +/* + * Port feature numbers + */ +#define USB_PORT_FEAT_CONNECTION 0 +#define USB_PORT_FEAT_ENABLE 1 +#define USB_PORT_FEAT_SUSPEND 2 +#define USB_PORT_FEAT_OVER_CURRENT 3 +#define USB_PORT_FEAT_RESET 4 +#define USB_PORT_FEAT_POWER 8 +#define USB_PORT_FEAT_LOWSPEED 9 +#define USB_PORT_FEAT_HIGHSPEED 10 +#define USB_PORT_FEAT_C_CONNECTION 16 +#define USB_PORT_FEAT_C_ENABLE 17 +#define USB_PORT_FEAT_C_SUSPEND 18 +#define USB_PORT_FEAT_C_OVER_CURRENT 19 +#define USB_PORT_FEAT_C_RESET 20 + +/* wPortStatus bits */ +#define USB_PORT_STAT_CONNECTION 0x0001 +#define USB_PORT_STAT_ENABLE 0x0002 +#define USB_PORT_STAT_SUSPEND 0x0004 +#define USB_PORT_STAT_OVERCURRENT 0x0008 +#define USB_PORT_STAT_RESET 0x0010 +#define USB_PORT_STAT_POWER 0x0100 +#define USB_PORT_STAT_LOW_SPEED 0x0200 +#define USB_PORT_STAT_HIGH_SPEED 0x0400 /* support for EHCI */ +#define USB_PORT_STAT_SPEED \ + (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED) + +/* wPortChange bits */ +#define USB_PORT_STAT_C_CONNECTION 0x0001 +#define USB_PORT_STAT_C_ENABLE 0x0002 +#define USB_PORT_STAT_C_SUSPEND 0x0004 +#define USB_PORT_STAT_C_OVERCURRENT 0x0008 +#define USB_PORT_STAT_C_RESET 0x0010 + +/* wHubCharacteristics (masks) */ +#define HUB_CHAR_LPSM 0x0003 +#define HUB_CHAR_COMPOUND 0x0004 +#define HUB_CHAR_OCPM 0x0018 + +/* + *Hub Status & Hub Change bit masks + */ +#define HUB_STATUS_LOCAL_POWER 0x0001 +#define HUB_STATUS_OVERCURRENT 0x0002 + +#define HUB_CHANGE_LOCAL_POWER 0x0001 +#define HUB_CHANGE_OVERCURRENT 0x0002 + +/* Struct USB_HCD defination */ +// for flags +#define HCD_FLAG_HW_ACCESSIBLE 0 /* at full power */ +#define HCD_FLAG_POLL_RH 2 /* poll for rh status? */ +#define HCD_FLAG_POLL_PENDING 3 /* status has changed? */ +#define HCD_FLAG_WAKEUP_PENDING 4 /* root hub is resuming? */ +#define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ +#define HCD_FLAG_DEAD 6 /* controller has died? */ + +/* The flags can be tested using these macros; they are likely to + * be slightly faster than test_bit(). + */ +#define HCD_HW_ACCESSIBLE(hcd) ((hcd)->flags & (1U << HCD_FLAG_HW_ACCESSIBLE)) +#define HCD_POLL_RH(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_RH)) +#define HCD_POLL_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING)) +#define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) +#define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) +#define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) + +// for state +#define __ACTIVE 0x01 +#define __SUSPEND 0x04 +#define __TRANSIENT 0x80 + +#define HC_STATE_HALT 0 +#define HC_STATE_RUNNING (__ACTIVE) +#define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE) +#define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT) +#define HC_STATE_SUSPENDED (__SUSPEND) + +#define HC_IS_RUNNING(state) ((state) & __ACTIVE) +#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND) + +/* + * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and + * are read as a bit array returned by USB_REQ_GET_STATUS. (So there + * are at most sixteen features of each type.) Hubs may also support a + * new USB_REQ_TEST_AND_SET_FEATURE to put ports into L1 suspend. + */ +#define USB_DEVICE_SELF_POWERED 0 /* (read only) */ +#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */ +#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */ +#define USB_DEVICE_BATTERY 2 /* (wireless) */ +#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */ +#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/ +#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */ +#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */ +#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */ + +/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */ +#define DeviceRequest \ + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) +#define DeviceOutRequest \ + ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) + +#define InterfaceRequest \ + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + +#define EndpointRequest \ + ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) +#define EndpointOutRequest \ + ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) + +/* class requests from the USB 2.0 hub spec, table 11-15 */ +/* GetBusState and SetHubDescriptor are optional, omitted */ +#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) +#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) +#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) +#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS) +#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS) +#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE) +#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE) + +/* from config descriptor bmAttributes */ +#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ +#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ +#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ +#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */ + +#endif /*_USB_DEFS_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_gadget.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_gadget.h new file mode 100644 index 0000000..9843131 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_gadget.h @@ -0,0 +1,937 @@ +/* + * + * + * We call the USB code inside a Linux-based peripheral device a "gadget" + * driver, except for the hardware-specific bus glue. One USB host can + * master many USB gadgets, but the gadgets are only slaved to one host. + * + * + * (C) Copyright 2002-2004 by David Brownell + * All Rights Reserved. + * + * This software is licensed under the GNU GPL version 2. + */ + +#ifndef __USB_GADGET_H +#define __USB_GADGET_H + +//#include "xlinux.h" + +//#ifdef __KERNEL__ +#include "osdep_api.h" +#include "usb_ch9.h" + +#if 1//defined(CONFIG_RTL_ULINKER) +#include "usb_ulinker.h" +#endif + +#include "usb.h" +#include "dwc_list.h" +typedef unsigned int gfp_t; + +//struct usb_ep; +/** + * struct usb_ep - device side representation of USB endpoint + * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk" + * @ops: Function pointers used to access hardware-specific operations. + * @ep_list:the gadget's ep_list holds all of its endpoints + * @maxpacket:The maximum packet size used on this endpoint. The initial + * value can sometimes be reduced (hardware allowing), according to + * the endpoint descriptor used to configure the endpoint. + * @driver_data:for use by the gadget driver. all other fields are + * read-only to gadget drivers. + * + * the bus controller driver lists all the general purpose endpoints in + * gadget->ep_list. the control endpoint (gadget->ep0) is not in that list, + * and is accessed only in response to a driver setup() callback. + */ +struct usb_ep { + void *driver_data; + + const char *name; + const struct usb_ep_ops *ops; + //_LIST ep_list;//ModifiedByJD + dwc_list_link_t ep_list;// by jimmy + unsigned maxpacket:16; + const struct usb_endpoint_descriptor *desc; +}; + +struct usb_request; + +typedef void (*usb_req_complete_t)(struct usb_ep *, struct usb_request *); + + +/** + * struct usb_request - describes one i/o request + * @buf: Buffer used for data. Always provide this; some controllers + * only use PIO, or don't use DMA for some endpoints. + * @dma: DMA address corresponding to 'buf'. If you don't set this + * field, and the usb controller needs one, it is responsible + * for mapping and unmapping the buffer. + * @length: Length of that data + * @no_interrupt: If true, hints that no completion irq is needed. + * Helpful sometimes with deep request queues that are handled + * directly by DMA controllers. + * @zero: If true, when writing data, makes the last packet be "short" + * by adding a zero length packet as needed; + * @short_not_ok: When reading data, makes short packets be + * treated as errors (queue stops advancing till cleanup). + * @complete: Function called when request completes, so this request and + * its buffer may be re-used. + * Reads terminate with a short packet, or when the buffer fills, + * whichever comes first. When writes terminate, some data bytes + * will usually still be in flight (often in a hardware fifo). + * Errors (for reads or writes) stop the queue from advancing + * until the completion function returns, so that any transfers + * invalidated by the error may first be dequeued. + * @context: For use by the completion callback + * @list: For use by the gadget driver. + * @status: Reports completion code, zero or a negative errno. + * Normally, faults block the transfer queue from advancing until + * the completion callback returns. + * Code "-ESHUTDOWN" indicates completion caused by device disconnect, + * or when the driver disabled the endpoint. + * @actual: Reports bytes transferred to/from the buffer. For reads (OUT + * transfers) this may be less than the requested length. If the + * short_not_ok flag is set, short reads are treated as errors + * even when status otherwise indicates successful completion. + * Note that for writes (IN transfers) some data bytes may still + * reside in a device-side FIFO when the request is reported as + * complete. + * + * These are allocated/freed through the endpoint they're used with. The + * hardware's driver can add extra per-request data to the memory it returns, + * which often avoids separate memory allocations (potential failures), + * later when the request is queued. + * + * Request flags affect request handling, such as whether a zero length + * packet is written (the "zero" flag), whether a short read should be + * treated as an error (blocking request queue advance, the "short_not_ok" + * flag), or hinting that an interrupt is not required (the "no_interrupt" + * flag, for use with deep request queues). + * + * Bulk endpoints can use any size buffers, and can also be used for interrupt + * transfers. interrupt-only endpoints can be much less functional. + */ + // NOTE this is analagous to 'struct urb' on the host side, + // except that it's thinner and promotes more pre-allocation. + +struct usb_request { + void *buf; + unsigned length; + dma_addr_t dma; + + unsigned no_interrupt:1; + unsigned zero:1; + unsigned short_not_ok:1; + + usb_req_complete_t complete; + void *context; + //_LIST list;//ModifiedByJD + dwc_list_link_t list;// by jimmy + int status; + unsigned actual; +}; + +/*-------------------------------------------------------------------------*/ + +/* endpoint-specific parts of the api to the usb controller hardware. + * unlike the urb model, (de)multiplexing layers are not required. + * (so this api could slash overhead if used on the host side...) + * + * note that device side usb controllers commonly differ in how many + * endpoints they support, as well as their capabilities. + */ +struct usb_ep_ops { + int (*enable) (struct usb_ep *ep, + const struct usb_endpoint_descriptor *desc); + int (*disable) (struct usb_ep *ep); + + struct usb_request *(*alloc_request) (struct usb_ep *ep, + gfp_t gfp_flags); + void (*free_request) (struct usb_ep *ep, struct usb_request *req); + + void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes, + dma_addr_t *dma, gfp_t gfp_flags); + void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma, + unsigned bytes); + // NOTE: on 2.6, drivers may also use dma_map() and + // dma_sync_single_*() to directly manage dma overhead. + + int (*queue) (struct usb_ep *ep, struct usb_request *req, + gfp_t gfp_flags); + int (*dequeue) (struct usb_ep *ep, struct usb_request *req); + + int (*set_halt) (struct usb_ep *ep, int value); + int (*fifo_status) (struct usb_ep *ep); + void (*fifo_flush) (struct usb_ep *ep); +}; + +/*-------------------------------------------------------------------------*/ + +/** + * usb_ep_enable - configure endpoint, making it usable + * @ep:the endpoint being configured. may not be the endpoint named "ep0". + * drivers discover endpoints through the ep_list of a usb_gadget. + * @desc:descriptor for desired behavior. caller guarantees this pointer + * remains valid until the endpoint is disabled; the data byte order + * is little-endian (usb-standard). + * + * when configurations are set, or when interface settings change, the driver + * will enable or disable the relevant endpoints. while it is enabled, an + * endpoint may be used for i/o until the driver receives a disconnect() from + * the host or until the endpoint is disabled. + * + * the ep0 implementation (which calls this routine) must ensure that the + * hardware capabilities of each endpoint match the descriptor provided + * for it. for example, an endpoint named "ep2in-bulk" would be usable + * for interrupt transfers as well as bulk, but it likely couldn't be used + * for iso transfers or for endpoint 14. some endpoints are fully + * configurable, with more generic names like "ep-a". (remember that for + * USB, "in" means "towards the USB master".) + * + * returns zero, or a negative error code. + */ +extern _LONG_CALL_ +int usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc); + +/** + * usb_ep_disable - endpoint is no longer usable + * @ep:the endpoint being unconfigured. may not be the endpoint named "ep0". + * + * no other task may be using this endpoint when this is called. + * any pending and uncompleted requests will complete with status + * indicating disconnect (-ESHUTDOWN) before this call returns. + * gadget drivers must call usb_ep_enable() again before queueing + * requests to the endpoint. + * + * returns zero, or a negative error code. + */ +extern _LONG_CALL_ +int usb_ep_disable (struct usb_ep *ep); + +/** + * usb_ep_alloc_request - allocate a request object to use with this endpoint + * @ep:the endpoint to be used with with the request + * @gfp_flags:GFP_* flags to use + * + * Request objects must be allocated with this call, since they normally + * need controller-specific setup and may even need endpoint-specific + * resources such as allocation of DMA descriptors. + * Requests may be submitted with usb_ep_queue(), and receive a single + * completion callback. Free requests with usb_ep_free_request(), when + * they are no longer needed. + * + * Returns the request, or null if one could not be allocated. + */ +extern _LONG_CALL_ struct usb_request * +usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags); + +/** + * usb_ep_free_request - frees a request object + * @ep:the endpoint associated with the request + * @req:the request being freed + * + * Reverses the effect of usb_ep_alloc_request(). + * Caller guarantees the request is not queued, and that it will + * no longer be requeued (or otherwise used). + */ +extern _LONG_CALL_ void +usb_ep_free_request (struct usb_ep *ep, struct usb_request *req); +#if 0 +/** + * usb_ep_alloc_buffer - allocate an I/O buffer + * @ep:the endpoint associated with the buffer + * @len:length of the desired buffer + * @dma:pointer to the buffer's DMA address; must be valid + * @gfp_flags:GFP_* flags to use + * + * Returns a new buffer, or null if one could not be allocated. + * The buffer is suitably aligned for dma, if that endpoint uses DMA, + * and the caller won't have to care about dma-inconsistency + * or any hidden "bounce buffer" mechanism. No additional per-request + * DMA mapping will be required for such buffers. + * Free it later with usb_ep_free_buffer(). + * + * You don't need to use this call to allocate I/O buffers unless you + * want to make sure drivers don't incur costs for such "bounce buffer" + * copies or per-request DMA mappings. + */ +static inline void * +usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma, + gfp_t gfp_flags) +{ + return ep->ops->alloc_buffer (ep, len, dma, gfp_flags); +} + +/** + * usb_ep_free_buffer - frees an i/o buffer + * @ep:the endpoint associated with the buffer + * @buf:CPU view address of the buffer + * @dma:the buffer's DMA address + * @len:length of the buffer + * + * reverses the effect of usb_ep_alloc_buffer(). + * caller guarantees the buffer will no longer be accessed + */ +static inline void +usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len) +{ + ep->ops->free_buffer (ep, buf, dma, len); +} +#endif +/** + * usb_ep_queue - queues (submits) an I/O request to an endpoint. + * @ep:the endpoint associated with the request + * @req:the request being submitted + * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't + * pre-allocate all necessary memory with the request. + * + * This tells the device controller to perform the specified request through + * that endpoint (reading or writing a buffer). When the request completes, + * including being canceled by usb_ep_dequeue(), the request's completion + * routine is called to return the request to the driver. Any endpoint + * (except control endpoints like ep0) may have more than one transfer + * request queued; they complete in FIFO order. Once a gadget driver + * submits a request, that request may not be examined or modified until it + * is given back to that driver through the completion callback. + * + * Each request is turned into one or more packets. The controller driver + * never merges adjacent requests into the same packet. OUT transfers + * will sometimes use data that's already buffered in the hardware. + * Drivers can rely on the fact that the first byte of the request's buffer + * always corresponds to the first byte of some USB packet, for both + * IN and OUT transfers. + * + * Bulk endpoints can queue any amount of data; the transfer is packetized + * automatically. The last packet will be short if the request doesn't fill it + * out completely. Zero length packets (ZLPs) should be avoided in portable + * protocols since not all usb hardware can successfully handle zero length + * packets. (ZLPs may be explicitly written, and may be implicitly written if + * the request 'zero' flag is set.) Bulk endpoints may also be used + * for interrupt transfers; but the reverse is not true, and some endpoints + * won't support every interrupt transfer. (Such as 768 byte packets.) + * + * Interrupt-only endpoints are less functional than bulk endpoints, for + * example by not supporting queueing or not handling buffers that are + * larger than the endpoint's maxpacket size. They may also treat data + * toggle differently. + * + * Control endpoints ... after getting a setup() callback, the driver queues + * one response (even if it would be zero length). That enables the + * status ack, after transfering data as specified in the response. Setup + * functions may return negative error codes to generate protocol stalls. + * (Note that some USB device controllers disallow protocol stall responses + * in some cases.) When control responses are deferred (the response is + * written after the setup callback returns), then usb_ep_set_halt() may be + * used on ep0 to trigger protocol stalls. + * + * For periodic endpoints, like interrupt or isochronous ones, the usb host + * arranges to poll once per interval, and the gadget driver usually will + * have queued some data to transfer at that time. + * + * Returns zero, or a negative error code. Endpoints that are not enabled + * report errors; errors will also be + * reported when the usb peripheral is disconnected. + */ +extern _LONG_CALL_ int +usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags); + +/** + * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint + * @ep:the endpoint associated with the request + * @req:the request being canceled + * + * if the request is still active on the endpoint, it is dequeued and its + * completion routine is called (with status -ECONNRESET); else a negative + * error code is returned. + * + * note that some hardware can't clear out write fifos (to unlink the request + * at the head of the queue) except as part of disconnecting from usb. such + * restrictions prevent drivers from supporting configuration changes, + * even to configuration zero (a "chapter 9" requirement). + */ +extern _LONG_CALL_ int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req); + +/** + * usb_ep_set_halt - sets the endpoint halt feature. + * @ep: the non-isochronous endpoint being stalled + * + * Use this to stall an endpoint, perhaps as an error report. + * Except for control endpoints, + * the endpoint stays halted (will not stream any data) until the host + * clears this feature; drivers may need to empty the endpoint's request + * queue first, to make sure no inappropriate transfers happen. + * + * Note that while an endpoint CLEAR_FEATURE will be invisible to the + * gadget driver, a SET_INTERFACE will not be. To reset endpoints for the + * current altsetting, see usb_ep_clear_halt(). When switching altsettings, + * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints. + * + * Returns zero, or a negative error code. On success, this call sets + * underlying hardware state that blocks data transfers. + * Attempts to halt IN endpoints will fail (returning -EAGAIN) if any + * transfer requests are still queued, or if the controller hardware + * (usually a FIFO) still holds bytes that the host hasn't collected. + */ +extern _LONG_CALL_ int usb_ep_set_halt (struct usb_ep *ep); + +/** + * usb_ep_clear_halt - clears endpoint halt, and resets toggle + * @ep:the bulk or interrupt endpoint being reset + * + * Use this when responding to the standard usb "set interface" request, + * for endpoints that aren't reconfigured, after clearing any other state + * in the endpoint's i/o queue. + * + * Returns zero, or a negative error code. On success, this call clears + * the underlying hardware state reflecting endpoint halt and data toggle. + * Note that some hardware can't support this request (like pxa2xx_udc), + * and accordingly can't correctly implement interface altsettings. + */ +extern _LONG_CALL_ int usb_ep_clear_halt (struct usb_ep *ep); + +#if 0 +/** + * usb_ep_fifo_status - returns number of bytes in fifo, or error + * @ep: the endpoint whose fifo status is being checked. + * + * FIFO endpoints may have "unclaimed data" in them in certain cases, + * such as after aborted transfers. Hosts may not have collected all + * the IN data written by the gadget driver (and reported by a request + * completion). The gadget driver may not have collected all the data + * written OUT to it by the host. Drivers that need precise handling for + * fault reporting or recovery may need to use this call. + * + * This returns the number of such bytes in the fifo, or a negative + * errno if the endpoint doesn't use a FIFO or doesn't support such + * precise handling. + */ +static inline int +usb_ep_fifo_status (struct usb_ep *ep) +{ + if (ep->ops->fifo_status) + return ep->ops->fifo_status (ep); + else + return -EOPNOTSUPP; +} + +/** + * usb_ep_fifo_flush - flushes contents of a fifo + * @ep: the endpoint whose fifo is being flushed. + * + * This call may be used to flush the "unclaimed data" that may exist in + * an endpoint fifo after abnormal transaction terminations. The call + * must never be used except when endpoint is not being used for any + * protocol translation. + */ +static inline void +usb_ep_fifo_flush (struct usb_ep *ep) +{ + if (ep->ops->fifo_flush) + ep->ops->fifo_flush (ep); +} +#endif + +/*-------------------------------------------------------------------------*/ +/** + * struct usb_gadget - represents a usb slave device + * @ops: Function pointers used to access hardware-specific operations. + * @ep0: Endpoint zero, used when reading or writing responses to + * driver setup() requests + * @ep_list: List of other endpoints supported by the device. + * @speed: Speed of current connection to USB host. + * @is_dualspeed: True if the controller supports both high and full speed + * operation. If it does, the gadget driver must also support both. + * @is_otg: True if the USB device port uses a Mini-AB jack, so that the + * gadget driver must provide a USB OTG descriptor. + * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable + * is in the Mini-AB jack, and HNP has been used to switch roles + * so that the "A" device currently acts as A-Peripheral, not A-Host. + * @a_hnp_support: OTG device feature flag, indicating that the A-Host + * supports HNP at this port. + * @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host + * only supports HNP on a different root port. + * @b_hnp_enable: OTG device feature flag, indicating that the A-Host + * enabled HNP support. + * @name: Identifies the controller hardware type. Used in diagnostics + * and sometimes configuration. + * @dev: Driver model state for this abstract device. + * + * Gadgets have a mostly-portable "gadget driver" implementing device + * functions, handling all usb configurations and interfaces. Gadget + * drivers talk to hardware-specific code indirectly, through ops vectors. + * That insulates the gadget driver from hardware details, and packages + * the hardware endpoints through generic i/o queues. The "usb_gadget" + * and "usb_ep" interfaces provide that insulation from the hardware. + * + * Except for the driver data, all fields in this structure are + * read-only to the gadget driver. That driver data is part of the + * "driver model" infrastructure in 2.6 (and later) kernels, and for + * earlier systems is grouped in a similar structure that's not known + * to the rest of the kernel. + * + * Values of the three OTG device feature flags are updated before the + * setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before + * driver suspend() calls. They are valid only when is_otg, and when the + * device is acting as a B-Peripheral (so is_a_peripheral is false). + */ +#include"rtl8195a_otg_zero.h" +struct usb_gadget { + /* readonly to gadget driver */ + const struct usb_gadget_ops *ops; + struct usb_ep *ep0; +// _LIST ep_list; /* of usb_ep */ //ModifiedByJD + dwc_list_link_t ep_list; // by jimmy + + enum usb_device_speed speed; + enum usb_device_speed max_speed; + enum usb_device_state state; + unsigned is_dualspeed:1; + unsigned is_otg:1; + unsigned is_a_peripheral:1; + unsigned b_hnp_enable:1; + unsigned a_hnp_support:1; + unsigned a_alt_hnp_support:1; + const char *name; + void *driver_data; + void *device; +}; + + + + +//struct usb_gadget; + +/* the rest of the api to the controller hardware: device operations, + * which don't involve endpoints (or i/o). + */ +struct usb_gadget_ops { + int (*get_frame)(struct usb_gadget *); + int (*wakeup)(struct usb_gadget *); + int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); + int (*vbus_session) (struct usb_gadget *, int is_active); + int (*vbus_draw) (struct usb_gadget *, unsigned mA); + int (*pullup) (struct usb_gadget *, int is_on); + int (*ioctl)(struct usb_gadget *, + unsigned code, unsigned long param); +}; + + +#if 0 //wei add +static inline void * +dev_get_drvdata (struct device *dev) +{ + return dev->driver_data; +} + +static inline void +dev_set_drvdata (struct device *dev, void *data) +{ + dev->driver_data = data; +} +#endif +#if 0 +static inline void set_gadget_data (struct usb_gadget *gadget, void *data) + { dev_set_drvdata (gadget->dev, data); } +// { gadget->dev->driver_data = data; } +static inline void *get_gadget_data (struct usb_gadget *gadget) + { return dev_get_drvdata (gadget->dev); } +// { return gadget->dev->driver_data;} +#endif + +/* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ +#define gadget_for_each_ep(tmp,gadget) \ + list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) + +#if 0 +/** + * usb_gadget_frame_number - returns the current frame number + * @gadget: controller that reports the frame number + * + * Returns the usb frame number, normally eleven bits from a SOF packet, + * or negative errno if this device doesn't support this capability. + */ +static inline int usb_gadget_frame_number (struct usb_gadget *gadget) +{ + return gadget->ops->get_frame(gadget); +} + +/** + * usb_gadget_wakeup - tries to wake up the host connected to this gadget + * @gadget: controller used to wake up the host + * + * Returns zero on success, else negative error code if the hardware + * doesn't support such attempts, or its support has not been enabled + * by the usb host. Drivers must return device descriptors that report + * their ability to support this, or hosts won't enable it. + * + * This may also try to use SRP to wake the host and start enumeration, + * even if OTG isn't otherwise in use. OTG devices may also start + * remote wakeup even when hosts don't explicitly enable it. + */ +static inline int usb_gadget_wakeup (struct usb_gadget *gadget) +{ + if (!gadget->ops->wakeup) + return -EOPNOTSUPP; + return gadget->ops->wakeup (gadget); +} + +/** + * usb_gadget_set_selfpowered - sets the device selfpowered feature. + * @gadget:the device being declared as self-powered + * + * this affects the device status reported by the hardware driver + * to reflect that it now has a local power supply. + * + * returns zero on success, else negative errno. + */ +static inline int +usb_gadget_set_selfpowered (struct usb_gadget *gadget) +{ +xprintf("%s %s[%d]\n",__FILE__,__FUNCTION__,__LINE__); + if (!gadget->ops->set_selfpowered) + return -EOPNOTSUPP; + return gadget->ops->set_selfpowered (gadget, 1); +} + +/** + * usb_gadget_clear_selfpowered - clear the device selfpowered feature. + * @gadget:the device being declared as bus-powered + * + * this affects the device status reported by the hardware driver. + * some hardware may not support bus-powered operation, in which + * case this feature's value can never change. + * + * returns zero on success, else negative errno. + */ +static inline int +usb_gadget_clear_selfpowered (struct usb_gadget *gadget) +{ + if (!gadget->ops->set_selfpowered) + return -EOPNOTSUPP; + return gadget->ops->set_selfpowered (gadget, 0); +} + +/** + * usb_gadget_vbus_connect - Notify controller that VBUS is powered + * @gadget:The device which now has VBUS power. + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session starting. Common responses include + * resuming the controller, activating the D+ (or D-) pullup to let the + * host detect that a USB device is attached, and starting to draw power + * (8mA or possibly more, especially after SET_CONFIGURATION). + * + * Returns zero on success, else negative errno. + */ +static inline int +usb_gadget_vbus_connect(struct usb_gadget *gadget) +{ + if (!gadget->ops->vbus_session) + return -EOPNOTSUPP; + return gadget->ops->vbus_session (gadget, 1); +} +#endif +/** + * usb_gadget_vbus_draw - constrain controller's VBUS power usage + * @gadget:The device whose VBUS usage is being described + * @mA:How much current to draw, in milliAmperes. This should be twice + * the value listed in the configuration descriptor bMaxPower field. + * + * This call is used by gadget drivers during SET_CONFIGURATION calls, + * reporting how much power the device may consume. For example, this + * could affect how quickly batteries are recharged. + * + * Returns zero on success, else negative errno. + */ +extern _LONG_CALL_ int +usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA); +#if 0 +/** + * usb_gadget_vbus_disconnect - notify controller about VBUS session end + * @gadget:the device whose VBUS supply is being described + * + * This call is used by a driver for an external transceiver (or GPIO) + * that detects a VBUS power session ending. Common responses include + * reversing everything done in usb_gadget_vbus_connect(). + * + * Returns zero on success, else negative errno. + */ +static inline int +usb_gadget_vbus_disconnect(struct usb_gadget *gadget) +{ + if (!gadget->ops->vbus_session) + return -EOPNOTSUPP; + return gadget->ops->vbus_session (gadget, 0); +} + +/** + * usb_gadget_connect - software-controlled connect to USB host + * @gadget:the peripheral being connected + * + * Enables the D+ (or potentially D-) pullup. The host will start + * enumerating this gadget when the pullup is active and a VBUS session + * is active (the link is powered). This pullup is always enabled unless + * usb_gadget_disconnect() has been used to disable it. + * + * Returns zero on success, else negative errno. + */ +static inline int +usb_gadget_connect (struct usb_gadget *gadget) +{ + if (!gadget->ops->pullup) + return -EOPNOTSUPP; + return gadget->ops->pullup (gadget, 1); +} + +/** + * usb_gadget_disconnect - software-controlled disconnect from USB host + * @gadget:the peripheral being disconnected + * + * Disables the D+ (or potentially D-) pullup, which the host may see + * as a disconnect (when a VBUS session is active). Not all systems + * support software pullup controls. + * + * This routine may be used during the gadget driver bind() call to prevent + * the peripheral from ever being visible to the USB host, unless later + * usb_gadget_connect() is called. For example, user mode components may + * need to be activated before the system can talk to hosts. + * + * Returns zero on success, else negative errno. + */ +static inline int +usb_gadget_disconnect (struct usb_gadget *gadget) +{ + if (!gadget->ops->pullup) + return -EOPNOTSUPP; + return gadget->ops->pullup (gadget, 0); +} + +#endif + +/*-------------------------------------------------------------------------*/ + +/** + * struct usb_gadget_driver - driver for usb 'slave' devices + * @function: String describing the gadget's function + * @speed: Highest speed the driver handles. + * @bind: Invoked when the driver is bound to a gadget, usually + * after registering the driver. + * At that point, ep0 is fully initialized, and ep_list holds + * the currently-available endpoints. + * Called in a context that permits sleeping. + * @setup: Invoked for ep0 control requests that aren't handled by + * the hardware level driver. Most calls must be handled by + * the gadget driver, including descriptor and configuration + * management. The 16 bit members of the setup data are in + * USB byte order. Called in_interrupt; this may not sleep. Driver + * queues a response to ep0, or returns negative to stall. + * @disconnect: Invoked after all transfers have been stopped, + * when the host is disconnected. May be called in_interrupt; this + * may not sleep. Some devices can't detect disconnect, so this might + * not be called except as part of controller shutdown. + * @unbind: Invoked when the driver is unbound from a gadget, + * usually from rmmod (after a disconnect is reported). + * Called in a context that permits sleeping. + * @suspend: Invoked on USB suspend. May be called in_interrupt. + * @resume: Invoked on USB resume. May be called in_interrupt. + * @driver: Driver model state for this driver. + * + * Devices are disabled till a gadget driver successfully bind()s, which + * means the driver will handle setup() requests needed to enumerate (and + * meet "chapter 9" requirements) then do some useful work. + * + * If gadget->is_otg is true, the gadget driver must provide an OTG + * descriptor during enumeration, or else fail the bind() call. In such + * cases, no USB traffic may flow until both bind() returns without + * having called usb_gadget_disconnect(), and the USB host stack has + * initialized. + * + * Drivers use hardware-specific knowledge to configure the usb hardware. + * endpoint addressing is only one of several hardware characteristics that + * are in descriptors the ep0 implementation returns from setup() calls. + * + * Except for ep0 implementation, most driver code shouldn't need change to + * run on top of different usb controllers. It'll use endpoints set up by + * that ep0 implementation. + * + * The usb controller driver handles a few standard usb requests. Those + * include set_address, and feature flags for devices, interfaces, and + * endpoints (the get_status, set_feature, and clear_feature requests). + * + * Accordingly, the driver's setup() callback must always implement all + * get_descriptor requests, returning at least a device descriptor and + * a configuration descriptor. Drivers must make sure the endpoint + * descriptors match any hardware constraints. Some hardware also constrains + * other descriptors. (The pxa250 allows only configurations 1, 2, or 3). + * + * The driver's setup() callback must also implement set_configuration, + * and should also implement set_interface, get_configuration, and + * get_interface. Setting a configuration (or interface) is where + * endpoints should be activated or (config 0) shut down. + * + * (Note that only the default control endpoint is supported. Neither + * hosts nor devices generally support control traffic except to ep0.) + * + * Most devices will ignore USB suspend/resume operations, and so will + * not provide those callbacks. However, some may need to change modes + * when the host is not longer directing those activities. For example, + * local controls (buttons, dials, etc) may need to be re-enabled since + * the (remote) host can't do that any longer; or an error state might + * be cleared, to make the device behave identically whether or not + * power is maintained. + */ +struct usb_gadget_driver { + char *function; + enum usb_device_speed max_speed; + int (*bind)(struct usb_gadget *, + struct usb_gadget_driver *); + void (*unbind)(struct usb_gadget *); + int (*setup)(struct usb_gadget *, const struct usb_ctrlrequest *); + //CommentedByJD int (*setup)(dwc_otg_pcd_t *, const struct usb_ctrlrequest *);//ModifiedByJD + void (*disconnect)(struct usb_gadget *); + void (*suspend)(struct usb_gadget *); + void (*resume)(struct usb_gadget *); + + // FIXME support safe rmmod +// struct device_driver *driver; + void * driver; +}; + +#include "dwc_otg_pcd_if.h" + +struct gadget_wrapper { + dwc_otg_pcd_t *pcd; + + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + + struct usb_ep ep0; + struct usb_ep in_ep[16]; + struct usb_ep out_ep[16]; + +}; + + + +/*-------------------------------------------------------------------------*/ + +/* driver modules register and unregister, as usual. + * these calls must be made in a context that can sleep. + * + * these will usually be implemented directly by the hardware-dependent + * usb bus interface driver, which will only support a single driver. + */ + +/** + * usb_gadget_register_driver - register a gadget driver + * @driver:the driver being registered + * + * Call this in your gadget driver's module initialization function, + * to tell the underlying usb controller driver about your driver. + * The driver's bind() function will be called to bind it to a + * gadget before this registration call returns. It's expected that + * the bind() functions will be in init sections. + * This function must be called in a context that can sleep. + */ +extern _LONG_CALL_ int usb_gadget_register_driver (struct usb_gadget_driver *driver); + +/** + * usb_gadget_unregister_driver - unregister a gadget driver + * @driver:the driver being unregistered + * + * Call this in your gadget driver's module cleanup function, + * to tell the underlying usb controller that your driver is + * going away. If the controller is connected to a USB host, + * it will first disconnect(). The driver is also requested + * to unbind() and clean up any device state, before this procedure + * finally returns. It's expected that the unbind() functions + * will in in exit sections, so may not be linked in some kernels. + * This function must be called in a context that can sleep. + */ +extern _LONG_CALL_ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver); + +/** + * usb_free_descriptors - free descriptors returned by usb_copy_descriptors() + * @v: vector of descriptors + */ +extern _LONG_CALL_ void usb_free_descriptors(struct usb_descriptor_header **v); + +/*-------------------------------------------------------------------------*/ + +/* utility to simplify dealing with string descriptors */ + +/** + * struct usb_string - wraps a C string and its USB id + * @id:the (nonzero) ID for this string + * @s:the string, in UTF-8 encoding + * + * If you're using usb_gadget_get_string(), use this to wrap a string + * together with its ID. + */ +struct usb_string { + u8 id; + const char *s; +}; + +/** + * struct usb_gadget_strings - a set of USB strings in a given language + * @language:identifies the strings' language (0x0409 for en-us) + * @strings:array of strings with their ids + * + * If you're using usb_gadget_get_string(), use this to wrap all the + * strings for a given language. + */ +struct usb_gadget_strings { + u16 language; /* 0x0409 for en-us */ + struct usb_string *strings; +}; + + +/** + * gadget_is_dualspeed - return true iff the hardware handles high speed + * @g: controller that might support both high and full speeds + */ +extern _LONG_CALL_ int gadget_is_dualspeed(struct usb_gadget *g); +#if 0 +/** + * gadget_is_superspeed() - return true if the hardware handles superspeed + * @g: controller that might support superspeed + */ +static inline int gadget_is_superspeed(struct usb_gadget *g) +{ + return g->max_speed >= USB_SPEED_SUPER; +} +#endif +/* put descriptor for string with that id into buf (buflen >= 256) */ +extern _LONG_CALL_ int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf); + +/*-------------------------------------------------------------------------*/ + +/* utility to simplify managing config descriptors */ + +/* write vector of descriptors into buffer */ +extern _LONG_CALL_ int usb_descriptor_fillbuf(void *, unsigned, + const struct usb_descriptor_header **); + +/* build config descriptor from single descriptor vector */ +extern _LONG_CALL_ int usb_gadget_config_buf(const struct usb_config_descriptor *config, + void *buf, unsigned buflen, const struct usb_descriptor_header **desc); + +/*-------------------------------------------------------------------------*/ + +extern _LONG_CALL_ void set_gadget_data(struct usb_gadget *gadget, void *data); +extern _LONG_CALL_ void *get_gadget_data(struct usb_gadget *gadget); + + +/* utility wrapping a simple endpoint selection policy */ +#if 1 +extern _LONG_CALL_ struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, + struct usb_endpoint_descriptor *);// ULINKER_DEVINIT; + +extern _LONG_CALL_ void usb_ep_autoconfig_reset (struct usb_gadget *);// ULINKER_DEVINIT; +#endif +//#endif /* __KERNEL__ */ + +#endif /* __LINUX_USB_GADGET_H */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_otg_inc/errno.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_otg_inc/errno.h new file mode 100644 index 0000000..2fbccce --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_otg_inc/errno.h @@ -0,0 +1,149 @@ +#ifndef _GENERIC_ERRNO_H +#define _GENERIC_ERRNO_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#define ERFKILL 132 /* Operation not possible due to RF-kill */ + +#define EHWPOISON 133 /* Memory page has hardware error */ + + +#define ENOTSUPP 524 /* Operation is not supported */ + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ulinker.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ulinker.h new file mode 100644 index 0000000..afcfeaf --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include/usb_ulinker.h @@ -0,0 +1,74 @@ +#ifndef __LINUX_USB_ULINKER_H +#define __LINUX_USB_ULINKER_H + +//#include "linux/autoconf.h" + +//#ifndef CONFIG_RTL_ULINKER_CUSTOMIZATION +#if 1//ModifiedByJD +#define ULINKER_ETHER_VID 0x0BDA +#define ULINKER_ETHER_PID 0x8195 +#define ULINKER_MANUFACTURER "Realtek Semicoonductor Corp." + +#define ULINKER_WINTOOLS_GUID "1CACC490-055C-4035-A026-1DAB0BDA8196" +#define ULINKER_WINTOOLS_DISPLAY_NAME "Realtek RTL8196EU Universal Linker" +#define ULINKER_WINTOOLS_CONTACT "nicfae@realtek.com.tw" +#define ULINKER_WINTOOLS_DISPLAY_VERSION "v1.0.0.0" +#define ULINKER_WINTOOLS_HELP_LINK "http://www.realtek.com.tw" +#define ULINKER_WINTOOLS_PUBLISHER ULINKER_MANUFACTURER +#define ULINKER_WINTOOLS_TARGET_DIR ULINKER_WINTOOLS_DISPLAY_NAME +#else +#define ULINKER_ETHER_VID CONFIG_RTL_ULINKER_VID +#define ULINKER_ETHER_PID CONFIG_RTL_ULINKER_PID +#define ULINKER_STORAGE_VID CONFIG_RTL_ULINKER_VID_S +#define ULINKER_STORAGE_PID CONFIG_RTL_ULINKER_PID_S +#define ULINKER_MANUFACTURER CONFIG_RTL_ULINKER_MANUFACTURE + +#define ULINKER_WINTOOLS_GUID CONFIG_RTL_ULINKER_WINTOOLS_GUID +#define ULINKER_WINTOOLS_DISPLAY_NAME CONFIG_RTL_ULINKER_WINTOOLS_DISPLAY_NAME +#define ULINKER_WINTOOLS_CONTACT CONFIG_RTL_ULINKER_WINTOOLS_CONTACT +#define ULINKER_WINTOOLS_DISPLAY_VERSION CONFIG_RTL_ULINKER_WINTOOLS_DISPLAY_VERSION +#define ULINKER_WINTOOLS_HELP_LINK CONFIG_RTL_ULINKER_WINTOOLS_HELP_LINK +#define ULINKER_WINTOOLS_PUBLISHER ULINKER_MANUFACTURER +#define ULINKER_WINTOOLS_TARGET_DIR ULINKER_WINTOOLS_DISPLAY_NAME +#endif + +//------------------------------------------------ +// if you don't have a specific PID for storage, don't change following define of storage mode. +// +// begin: don't change +#ifndef ULINKER_STORAGE_VID +#define ULINKER_STORAGE_VID 0x0BDA +#define ULINKER_STORAGE_PID 0x8197 +#endif + +#define ULINKER_STORAGE_VID_STR "USB Ether " +#define ULINKER_STORAGE_PID_DISK_STR "Driver DISC" +#define ULINKER_STORAGE_PID_CDROM_STR "Driver CDROM" + +#define ULINKER_WINTOOLS_DRIVER_PATH "Driver" +// end: don't change +//------------------------------------------------ + + +//---------------------------------------------------------------------- +#if defined(CONFIG_RTL_ULINKER) + +#define ULINKER_DEVINIT +#define ULINKER_DEVINITDATA +#define ULINKER_DEVINITCONST +#define ULINKER_DEVEXIT +#define ULINKER_DEVEXITDATA +#define ULINKER_DEVEXITCONST + +#else + +#define ULINKER_DEVINIT __devinit +#define ULINKER_DEVINITDATA __devinitdata +#define ULINKER_DEVINITCONST __devinitconst +#define ULINKER_DEVEXIT __devexit +#define ULINKER_DEVEXITDATA __devexitdata +#define ULINKER_DEVEXITCONST __devexitconst + +#endif + +#endif /* __LINUX_USB_ULINKER_H */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom/rom_wlan_ram_map.h b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom/rom_wlan_ram_map.h new file mode 100644 index 0000000..2944d18 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom/rom_wlan_ram_map.h @@ -0,0 +1,9 @@ +#ifndef ROM_WLAN_RAM_MAP_H +#define ROM_WLAN_RAM_MAP_H + +struct _rom_wlan_ram_map { + unsigned char * (*rtw_malloc)(unsigned int sz); + void (*rtw_mfree)(unsigned char *pbuf, unsigned int sz); +}; + +#endif /* ROM_WLAN_RAM_MAP_H */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a.h new file mode 100644 index 0000000..91c6dc3 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a.h @@ -0,0 +1,205 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + */ +#ifndef _HAL_8195A_H_ +#define _HAL_8195A_H_ + +#include "platform_autoconf.h" +#include "basic_types.h" +#include "section_config.h" +#include "rtl8195a_sys_on.h" +#include "rtl8195a_peri_on.h" +#include "hal_platform.h" +#include "hal_pinmux.h" +#include "hal_api.h" +#include "hal_peri_on.h" +#include "hal_misc.h" +#include "hal_irqn.h" +#include "hal_vector_table.h" +#include "hal_diag.h" +#include "hal_spi_flash.h" +#include "rtl8195a_spi_flash.h" +#include "hal_timer.h" +#include "hal_util.h" +#include "hal_efuse.h" +#include "hal_soc_ps_monitor.h" +#include "diag.h" +#include "hal_common.h" +#include "hal_soc_ps_monitor.h" + +/* ---------------------------------------------------------------------------- + -- Cortex M3 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M0 Core Configuration + * @{ + */ + +#define __CM3_REV 0x0200 /**< Core revision r0p0 */ +#define __MPU_PRESENT 1 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 4 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 1 /**< Vendor specific implementation of SysTickConfig is defined */ + +#include "core_cm3.h" + +#ifdef CONFIG_TIMER_EN +#include "hal_timer.h" +#endif + +#ifdef CONFIG_GDMA_EN +#include "hal_gdma.h" +#include "rtl8195a_gdma.h" +#endif + +#ifdef CONFIG_GPIO_EN +#include "hal_gpio.h" +#include "rtl8195a_gpio.h" +#endif + +#ifdef CONFIG_SPI_COM_EN +#include "hal_ssi.h" +#include "rtl8195a_ssi.h" +#endif + +#ifdef CONFIG_UART_EN +#include "hal_uart.h" +#include "rtl8195a_uart.h" +#endif + +#ifdef CONFIG_I2C_EN +#include "hal_i2c.h" +#include "rtl8195a_i2c.h" +#endif + +#ifdef CONFIG_PCM_EN +#include "hal_pcm.h" +#include "rtl8195a_pcm.h" +#endif + +#ifdef CONFIG_PWM_EN +#include "hal_pwm.h" +#include "rtl8195a_pwm.h" +#endif + +#ifdef CONFIG_I2S_EN +#include "hal_i2s.h" +#include "rtl8195a_i2s.h" +#endif + +#ifdef CONFIG_DAC_EN +#include "hal_dac.h" +#include "rtl8195a_dac.h" +#endif + +#ifdef CONFIG_ADC_EN +#include "hal_adc.h" +#include "rtl8195a_adc.h" +#endif + +#ifdef CONFIG_SDR_EN +#endif + +#ifdef CONFIG_SPIC_EN +#endif + +#ifdef CONFIG_SDIO_DEVICE_EN +#include "hal_sdio.h" +#endif + +#ifdef CONFIG_NFC_EN +#include "hal_nfc.h" +#include "rtl8195a_nfc.h" +#endif + +#ifdef CONFIG_WDG +#include "rtl8195a_wdt.h" +#endif + +#ifdef CONFIG_USB_EN +#include "hal_usb.h" +#include "rtl8195a_usb.h" +#endif + +#include "hal_log_uart.h" + +#ifdef CONFIG_MII_EN +#include "hal_mii.h" +#include "rtl8195a_mii.h" +#endif + +// firmware information, located at the header of Image2 +#define FW_VERSION (0x0100) +#define FW_SUBVERSION (0x0001) +#define FW_CHIP_ID (0x8195) +#define FW_CHIP_VER (0x01) +#define FW_BUS_TYPE (0x01) // the iNIC firmware type: USB/SDIO +#define FW_INFO_RSV1 (0x00) // the firmware information reserved +#define FW_INFO_RSV2 (0x00) // the firmware information reserved +#define FW_INFO_RSV3 (0x00) // the firmware information reserved +#define FW_INFO_RSV4 (0x00) // the firmware information reserved + +#define FLASH_RESERVED_DATA_BASE 0x8000 // reserve 32K for Image1 +#define FLASH_SYSTEM_DATA_ADDR 0x9000 // reserve 32K+4K for Image1 + Reserved data +// Flash Map for Calibration data +#define FLASH_CAL_DATA_BASE 0xA000 +#define FLASH_CAL_DATA_ADDR(_offset) (FLASH_CAL_DATA_BASE + _offset) +#define FLASH_CAL_DATA_SIZE 0x1000 +#define FLASH_SECTOR_SIZE 0x1000 +// SPIC Calibration Data +#define FLASH_SPIC_PARA_OFFSET 0x80 +#define FLASH_SPIC_PARA_BASE (FLASH_SYSTEM_DATA_ADDR+FLASH_SPIC_PARA_OFFSET) +// SDRC Calibration Data +#define FLASH_SDRC_PARA_OFFSET 0x180 +#define FLASH_SDRC_PARA_BASE (FLASH_SYSTEM_DATA_ADDR+FLASH_SDRC_PARA_OFFSET) +// ADC Calibration Data +#define FLASH_ADC_PARA_OFFSET 0x200 +#define FLASH_ADC_PARA_BASE (FLASH_SYSTEM_DATA_ADDR+FLASH_ADC_PARA_OFFSET) + +#define IMG_SIGN_RUN "81958711" +#define IMG_SIGN_SWP "01958711" +#define IMG_SIGN1_RUN 0x35393138 // "8195" +#define IMG_SIGN1_SWP 0x35393130 // "0195" +#define IMG_SIGN2_RUN 0x31313738 // "8711" +#define IMG_SIGN2_SWP IMG_SIGN2_RUN // "8711" +#define IMG2_SIGN_TXT "RTKWin" +#define IMG2_SIGN_DW1_TXT 0x574b5452 // "RTKW" +#define IMG2_SIGN_SW2_TXT 0x6e69 // "in" + +typedef struct _RAM_FUNCTION_START_TABLE_ { + VOID (*RamStartFun) (VOID); // Run for Init console, Run if ( v40000210 & 0x4000000 ) + VOID (*RamWakeupFun) (VOID); // Run if ( v40000210 & 0x20000000 ) + VOID (*RamPatchFun0) (VOID); // Run if ( v40000210 & 0x10000000 ) + VOID (*RamPatchFun1) (VOID); // Run if ( v400001F4 & 0x8000000 ) && ( v40000210 & 0x8000000 ) + VOID (*RamPatchFun2) (VOID); // Run for Init console, if ( v40000210 & 0x4000000 ) +}RAM_FUNCTION_START_TABLE, *PRAM_FUNCTION_START_TABLE; +// START_RAM_FUN_SECTION RAM_FUNCTION_START_TABLE __ram_start_table_start__ = +// {RamStartFun + 1, RamWakeupFun + 1, RamPatchFun0 + 1, RamPatchFun1 + 1, RamPatchFun2 + 1 }; + +#define IMG1_VALID_PATTEN_INIT() { 0x23, 0x79, 0x16, 0x88, 0xff, 0xff, 0xff, 0xff } +// IMAGE1_VALID_PATTEN_SECTION uint8 RAM_IMG1_VALID_PATTEN[8] = IMG1_VALID_PATTEN_INIT(); + +typedef struct _RAM_START_FUNCTION_ { + VOID (*RamStartFun) (VOID); +}RAM_START_FUNCTION, *PRAM_START_FUNCTION; +// IMAGE2_START_RAM_FUN_SECTION RAM_START_FUNCTION gImage2EntryFun0 = { InfraStart + 1 }; + +typedef struct __RAM_IMG2_VALID_PATTEN__ { + char rtkwin[7]; + u8 x[13]; +} _RAM_IMG2_VALID_PATTEN, *_PRAM_IMG2_VALID_PATTEN; + +// IMAGE2_VALID_PATTEN_SECTION _RAM_IMG2_VALID_PATTEN RAM_IMG2_VALID_PATTEN = RAM_IMG2_VALID_PATTEN_INIT(); +#define RAM_IMG2_VALID_PATTEN_INIT() { \ + { IMG2_SIGN_TXT }, { 0xff, \ + (FW_VERSION&0xff), ((FW_VERSION >> 8)&0xff), \ + (FW_SUBVERSION&0xff), ((FW_SUBVERSION >> 8)&0xff), \ + (FW_CHIP_ID&0xff), ((FW_CHIP_ID >> 8)&0xff), \ + (FW_CHIP_VER), (FW_BUS_TYPE), \ + (FW_INFO_RSV1), (FW_INFO_RSV2), (FW_INFO_RSV3), (FW_INFO_RSV4)}} + + +#endif //_HAL_8195A_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_adc.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_adc.h new file mode 100644 index 0000000..48240b0 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_adc.h @@ -0,0 +1,350 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_ADC_H_ +#define _RTL8195A_ADC_H_ + + +//================ Register Bit Field ========================== +//2 REG_ADC_FIFO_READ + +#define BIT_SHIFT_ADC_FIFO_RO 0 +#define BIT_MASK_ADC_FIFO_RO 0xffffffffL +#define BIT_ADC_FIFO_RO(x) (((x) & BIT_MASK_ADC_FIFO_RO) << BIT_SHIFT_ADC_FIFO_RO) +#define BIT_CTRL_ADC_FIFO_RO(x) (((x) & BIT_MASK_ADC_FIFO_RO) << BIT_SHIFT_ADC_FIFO_RO) +#define BIT_GET_ADC_FIFO_RO(x) (((x) >> BIT_SHIFT_ADC_FIFO_RO) & BIT_MASK_ADC_FIFO_RO) + + +//2 REG_ADC_CONTROL + +#define BIT_SHIFT_ADC_DBG_SEL 24 +#define BIT_MASK_ADC_DBG_SEL 0x7 +#define BIT_ADC_DBG_SEL(x) (((x) & BIT_MASK_ADC_DBG_SEL) << BIT_SHIFT_ADC_DBG_SEL) +#define BIT_CTRL_ADC_DBG_SEL(x) (((x) & BIT_MASK_ADC_DBG_SEL) << BIT_SHIFT_ADC_DBG_SEL) +#define BIT_GET_ADC_DBG_SEL(x) (((x) >> BIT_SHIFT_ADC_DBG_SEL) & BIT_MASK_ADC_DBG_SEL) + + +#define BIT_SHIFT_ADC_THRESHOLD 16 +#define BIT_MASK_ADC_THRESHOLD 0x3f +#define BIT_ADC_THRESHOLD(x) (((x) & BIT_MASK_ADC_THRESHOLD) << BIT_SHIFT_ADC_THRESHOLD) +#define BIT_CTRL_ADC_THRESHOLD(x) (((x) & BIT_MASK_ADC_THRESHOLD) << BIT_SHIFT_ADC_THRESHOLD) +#define BIT_GET_ADC_THRESHOLD(x) (((x) >> BIT_SHIFT_ADC_THRESHOLD) & BIT_MASK_ADC_THRESHOLD) + + +#define BIT_SHIFT_ADC_BURST_SIZE 8 +#define BIT_MASK_ADC_BURST_SIZE 0x1f +#define BIT_ADC_BURST_SIZE(x) (((x) & BIT_MASK_ADC_BURST_SIZE) << BIT_SHIFT_ADC_BURST_SIZE) +#define BIT_CTRL_ADC_BURST_SIZE(x) (((x) & BIT_MASK_ADC_BURST_SIZE) << BIT_SHIFT_ADC_BURST_SIZE) +#define BIT_GET_ADC_BURST_SIZE(x) (((x) >> BIT_SHIFT_ADC_BURST_SIZE) & BIT_MASK_ADC_BURST_SIZE) + +#define BIT_ADC_ENDIAN BIT(3) +#define BIT_SHIFT_ADC_ENDIAN 3 +#define BIT_MASK_ADC_ENDIAN 0x1 +#define BIT_CTRL_ADC_ENDIAN(x) (((x) & BIT_MASK_ADC_ENDIAN) << BIT_SHIFT_ADC_ENDIAN) + +#define BIT_ADC_OVERWRITE BIT(2) +#define BIT_SHIFT_ADC_OVERWRITE 2 +#define BIT_MASK_ADC_OVERWRITE 0x1 +#define BIT_CTRL_ADC_OVERWRITE(x) (((x) & BIT_MASK_ADC_OVERWRITE) << BIT_SHIFT_ADC_OVERWRITE) + +#define BIT_ADC_ONESHOT BIT(1) +#define BIT_SHIFT_ADC_ONESHOT 1 +#define BIT_MASK_ADC_ONESHOT 0x1 +#define BIT_CTRL_ADC_ONESHOT(x) (((x) & BIT_MASK_ADC_ONESHOT) << BIT_SHIFT_ADC_ONESHOT) + +#define BIT_ADC_COMP_ONLY BIT(0) +#define BIT_SHIFT_ADC_COMP_ONLY 0 +#define BIT_MASK_ADC_COMP_ONLY 0x1 +#define BIT_CTRL_ADC_COMP_ONLY(x) (((x) & BIT_MASK_ADC_COMP_ONLY) << BIT_SHIFT_ADC_COMP_ONLY) + + +//2 REG_ADC_INTR_EN +#define BIT_ADC_AWAKE_CPU_EN BIT(7) +#define BIT_SHIFT_ADC_AWAKE_CPU_EN 7 +#define BIT_MASK_ADC_AWAKE_CPU_EN 0x1 +#define BIT_CTRL_ADC_AWAKE_CPU_EN(x) (((x) & BIT_MASK_ADC_AWAKE_CPU_EN) << BIT_SHIFT_ADC_AWAKE_CPU_EN) + +#define BIT_ADC_FIFO_RD_ERROR_EN BIT(6) +#define BIT_SHIFT_ADC_FIFO_RD_ERROR_EN 6 +#define BIT_MASK_ADC_FIFO_RD_ERROR_EN 0x1 +#define BIT_CTRL_ADC_FIFO_RD_ERROR_EN(x) (((x) & BIT_MASK_ADC_FIFO_RD_ERROR_EN) << BIT_SHIFT_ADC_FIFO_RD_ERROR_EN) + +#define BIT_ADC_FIFO_RD_REQ_EN BIT(5) +#define BIT_SHIFT_ADC_FIFO_RD_REQ_EN 5 +#define BIT_MASK_ADC_FIFO_RD_REQ_EN 0x1 +#define BIT_CTRL_ADC_FIFO_RD_REQ_EN(x) (((x) & BIT_MASK_ADC_FIFO_RD_REQ_EN) << BIT_SHIFT_ADC_FIFO_RD_REQ_EN) + +#define BIT_ADC_FIFO_FULL_EN BIT(4) +#define BIT_SHIFT_ADC_FIFO_FULL_EN 4 +#define BIT_MASK_ADC_FIFO_FULL_EN 0x1 +#define BIT_CTRL_ADC_FIFO_FULL_EN(x) (((x) & BIT_MASK_ADC_FIFO_FULL_EN) << BIT_SHIFT_ADC_FIFO_FULL_EN) + +#define BIT_ADC_COMP_3_EN BIT(3) +#define BIT_SHIFT_ADC_COMP_3_EN 3 +#define BIT_MASK_ADC_COMP_3_EN 0x1 +#define BIT_CTRL_ADC_COMP_3_EN(x) (((x) & BIT_MASK_ADC_COMP_3_EN) << BIT_SHIFT_ADC_COMP_3_EN) + +#define BIT_ADC_COMP_2_EN BIT(2) +#define BIT_SHIFT_ADC_COMP_2_EN 2 +#define BIT_MASK_ADC_COMP_2_EN 0x1 +#define BIT_CTRL_ADC_COMP_2_EN(x) (((x) & BIT_MASK_ADC_COMP_2_EN) << BIT_SHIFT_ADC_COMP_2_EN) + +#define BIT_ADC_COMP_1_EN BIT(1) +#define BIT_SHIFT_ADC_COMP_1_EN 1 +#define BIT_MASK_ADC_COMP_1_EN 0x1 +#define BIT_CTRL_ADC_COMP_1_EN(x) (((x) & BIT_MASK_ADC_COMP_1_EN) << BIT_SHIFT_ADC_COMP_1_EN) + +#define BIT_ADC_COMP_0_EN BIT(0) +#define BIT_SHIFT_ADC_COMP_0_EN 0 +#define BIT_MASK_ADC_COMP_0_EN 0x1 +#define BIT_CTRL_ADC_COMP_0_EN(x) (((x) & BIT_MASK_ADC_COMP_0_EN) << BIT_SHIFT_ADC_COMP_0_EN) + + +//2 REG_ADC_INTR_STS +#define BIT_ADC_FIFO_THRESHOLD BIT(7) +#define BIT_SHIFT_ADC_FIFO_THRESHOLD 7 +#define BIT_MASK_ADC_FIFO_THRESHOLD 0x1 +#define BIT_CTRL_ADC_FIFO_THRESHOLD(x) (((x) & BIT_MASK_ADC_FIFO_THRESHOLD) << BIT_SHIFT_ADC_FIFO_THRESHOLD) + +#define BIT_ADC_FIFO_RD_ERROR_ST BIT(6) +#define BIT_SHIFT_ADC_FIFO_RD_ERROR_ST 6 +#define BIT_MASK_ADC_FIFO_RD_ERROR_ST 0x1 +#define BIT_CTRL_ADC_FIFO_RD_ERROR_ST(x) (((x) & BIT_MASK_ADC_FIFO_RD_ERROR_ST) << BIT_SHIFT_ADC_FIFO_RD_ERROR_ST) + +#define BIT_ADC_FIFO_RD_REQ_ST BIT(5) +#define BIT_SHIFT_ADC_FIFO_RD_REQ_ST 5 +#define BIT_MASK_ADC_FIFO_RD_REQ_ST 0x1 +#define BIT_CTRL_ADC_FIFO_RD_REQ_ST(x) (((x) & BIT_MASK_ADC_FIFO_RD_REQ_ST) << BIT_SHIFT_ADC_FIFO_RD_REQ_ST) + +#define BIT_ADC_FIFO_FULL_ST BIT(4) +#define BIT_SHIFT_ADC_FIFO_FULL_ST 4 +#define BIT_MASK_ADC_FIFO_FULL_ST 0x1 +#define BIT_CTRL_ADC_FIFO_FULL_ST(x) (((x) & BIT_MASK_ADC_FIFO_FULL_ST) << BIT_SHIFT_ADC_FIFO_FULL_ST) + +#define BIT_ADC_COMP_3_ST BIT(3) +#define BIT_SHIFT_ADC_COMP_3_ST 3 +#define BIT_MASK_ADC_COMP_3_ST 0x1 +#define BIT_CTRL_ADC_COMP_3_ST(x) (((x) & BIT_MASK_ADC_COMP_3_ST) << BIT_SHIFT_ADC_COMP_3_ST) + +#define BIT_ADC_COMP_2_ST BIT(2) +#define BIT_SHIFT_ADC_COMP_2_ST 2 +#define BIT_MASK_ADC_COMP_2_ST 0x1 +#define BIT_CTRL_ADC_COMP_2_ST(x) (((x) & BIT_MASK_ADC_COMP_2_ST) << BIT_SHIFT_ADC_COMP_2_ST) + +#define BIT_ADC_COMP_1_ST BIT(1) +#define BIT_SHIFT_ADC_COMP_1_ST 1 +#define BIT_MASK_ADC_COMP_1_ST 0x1 +#define BIT_CTRL_ADC_COMP_1_ST(x) (((x) & BIT_MASK_ADC_COMP_1_ST) << BIT_SHIFT_ADC_COMP_1_ST) + +#define BIT_ADC_COMP_0_ST BIT(0) +#define BIT_SHIFT_ADC_COMP_0_ST 0 +#define BIT_MASK_ADC_COMP_0_ST 0x1 +#define BIT_CTRL_ADC_COMP_0_ST(x) (((x) & BIT_MASK_ADC_COMP_0_ST) << BIT_SHIFT_ADC_COMP_0_ST) + + +//2 REG_ADC_COMP_VALUE_L + +#define BIT_SHIFT_ADC_COMP_TH_1 16 +#define BIT_MASK_ADC_COMP_TH_1 0xffff +#define BIT_ADC_COMP_TH_1(x) (((x) & BIT_MASK_ADC_COMP_TH_1) << BIT_SHIFT_ADC_COMP_TH_1) +#define BIT_CTRL_ADC_COMP_TH_1(x) (((x) & BIT_MASK_ADC_COMP_TH_1) << BIT_SHIFT_ADC_COMP_TH_1) +#define BIT_GET_ADC_COMP_TH_1(x) (((x) >> BIT_SHIFT_ADC_COMP_TH_1) & BIT_MASK_ADC_COMP_TH_1) + + +#define BIT_SHIFT_ADC_COMP_TH_0 0 +#define BIT_MASK_ADC_COMP_TH_0 0xffff +#define BIT_ADC_COMP_TH_0(x) (((x) & BIT_MASK_ADC_COMP_TH_0) << BIT_SHIFT_ADC_COMP_TH_0) +#define BIT_CTRL_ADC_COMP_TH_0(x) (((x) & BIT_MASK_ADC_COMP_TH_0) << BIT_SHIFT_ADC_COMP_TH_0) +#define BIT_GET_ADC_COMP_TH_0(x) (((x) >> BIT_SHIFT_ADC_COMP_TH_0) & BIT_MASK_ADC_COMP_TH_0) + + +//2 REG_ADC_COMP_VALUE_H + +#define BIT_SHIFT_ADC_COMP_TH_3 16 +#define BIT_MASK_ADC_COMP_TH_3 0xffff +#define BIT_ADC_COMP_TH_3(x) (((x) & BIT_MASK_ADC_COMP_TH_3) << BIT_SHIFT_ADC_COMP_TH_3) +#define BIT_CTRL_ADC_COMP_TH_3(x) (((x) & BIT_MASK_ADC_COMP_TH_3) << BIT_SHIFT_ADC_COMP_TH_3) +#define BIT_GET_ADC_COMP_TH_3(x) (((x) >> BIT_SHIFT_ADC_COMP_TH_3) & BIT_MASK_ADC_COMP_TH_3) + + +#define BIT_SHIFT_ADC_COMP_TH_2 0 +#define BIT_MASK_ADC_COMP_TH_2 0xffff +#define BIT_ADC_COMP_TH_2(x) (((x) & BIT_MASK_ADC_COMP_TH_2) << BIT_SHIFT_ADC_COMP_TH_2) +#define BIT_CTRL_ADC_COMP_TH_2(x) (((x) & BIT_MASK_ADC_COMP_TH_2) << BIT_SHIFT_ADC_COMP_TH_2) +#define BIT_GET_ADC_COMP_TH_2(x) (((x) >> BIT_SHIFT_ADC_COMP_TH_2) & BIT_MASK_ADC_COMP_TH_2) + + +//2 REG_ADC_COMP_SET + +#define BIT_SHIFT_ADC_GREATER_THAN 0 +#define BIT_MASK_ADC_GREATER_THAN 0xf +#define BIT_ADC_GREATER_THAN(x) (((x) & BIT_MASK_ADC_GREATER_THAN) << BIT_SHIFT_ADC_GREATER_THAN) +#define BIT_CTRL_ADC_GREATER_THAN(x) (((x) & BIT_MASK_ADC_GREATER_THAN) << BIT_SHIFT_ADC_GREATER_THAN) +#define BIT_GET_ADC_GREATER_THAN(x) (((x) >> BIT_SHIFT_ADC_GREATER_THAN) & BIT_MASK_ADC_GREATER_THAN) + + +//2 REG_ADC_POWER + +#define BIT_SHIFT_ADC_PWR_CUT_CNTR 16 +#define BIT_MASK_ADC_PWR_CUT_CNTR 0xff +#define BIT_ADC_PWR_CUT_CNTR(x) (((x) & BIT_MASK_ADC_PWR_CUT_CNTR) << BIT_SHIFT_ADC_PWR_CUT_CNTR) +#define BIT_CTRL_ADC_PWR_CUT_CNTR(x) (((x) & BIT_MASK_ADC_PWR_CUT_CNTR) << BIT_SHIFT_ADC_PWR_CUT_CNTR) +#define BIT_GET_ADC_PWR_CUT_CNTR(x) (((x) >> BIT_SHIFT_ADC_PWR_CUT_CNTR) & BIT_MASK_ADC_PWR_CUT_CNTR) + +#define BIT_ADC_FIFO_ON_ST BIT(11) +#define BIT_SHIFT_ADC_FIFO_ON_ST 11 +#define BIT_MASK_ADC_FIFO_ON_ST 0x1 +#define BIT_CTRL_ADC_FIFO_ON_ST(x) (((x) & BIT_MASK_ADC_FIFO_ON_ST) << BIT_SHIFT_ADC_FIFO_ON_ST) + +#define BIT_ADC_ISO_ON_ST BIT(10) +#define BIT_SHIFT_ADC_ISO_ON_ST 10 +#define BIT_MASK_ADC_ISO_ON_ST 0x1 +#define BIT_CTRL_ADC_ISO_ON_ST(x) (((x) & BIT_MASK_ADC_ISO_ON_ST) << BIT_SHIFT_ADC_ISO_ON_ST) + +#define BIT_ADC_PWR33_ON_ST BIT(9) +#define BIT_SHIFT_ADC_PWR33_ON_ST 9 +#define BIT_MASK_ADC_PWR33_ON_ST 0x1 +#define BIT_CTRL_ADC_PWR33_ON_ST(x) (((x) & BIT_MASK_ADC_PWR33_ON_ST) << BIT_SHIFT_ADC_PWR33_ON_ST) + +#define BIT_ADC_PWR12_ON_ST BIT(8) +#define BIT_SHIFT_ADC_PWR12_ON_ST 8 +#define BIT_MASK_ADC_PWR12_ON_ST 0x1 +#define BIT_CTRL_ADC_PWR12_ON_ST(x) (((x) & BIT_MASK_ADC_PWR12_ON_ST) << BIT_SHIFT_ADC_PWR12_ON_ST) + +#define BIT_ADC_ISO_MANUAL BIT(3) +#define BIT_SHIFT_ADC_ISO_MANUAL 3 +#define BIT_MASK_ADC_ISO_MANUAL 0x1 +#define BIT_CTRL_ADC_ISO_MANUAL(x) (((x) & BIT_MASK_ADC_ISO_MANUAL) << BIT_SHIFT_ADC_ISO_MANUAL) + +#define BIT_ADC_PWR33_MANUAL BIT(2) +#define BIT_SHIFT_ADC_PWR33_MANUAL 2 +#define BIT_MASK_ADC_PWR33_MANUAL 0x1 +#define BIT_CTRL_ADC_PWR33_MANUAL(x) (((x) & BIT_MASK_ADC_PWR33_MANUAL) << BIT_SHIFT_ADC_PWR33_MANUAL) + +#define BIT_ADC_PWR12_MANUAL BIT(1) +#define BIT_SHIFT_ADC_PWR12_MANUAL 1 +#define BIT_MASK_ADC_PWR12_MANUAL 0x1 +#define BIT_CTRL_ADC_PWR12_MANUAL(x) (((x) & BIT_MASK_ADC_PWR12_MANUAL) << BIT_SHIFT_ADC_PWR12_MANUAL) + +#define BIT_ADC_PWR_AUTO BIT(0) +#define BIT_SHIFT_ADC_PWR_AUTO 0 +#define BIT_MASK_ADC_PWR_AUTO 0x1 +#define BIT_CTRL_ADC_PWR_AUTO(x) (((x) & BIT_MASK_ADC_PWR_AUTO) << BIT_SHIFT_ADC_PWR_AUTO) + + +//2 REG_ADC_ANAPAR_AD0 + +#define BIT_SHIFT_ADC_ANAPAR_AD0 2 +#define BIT_MASK_ADC_ANAPAR_AD0 0x3fffffff +#define BIT_ADC_ANAPAR_AD0(x) (((x) & BIT_MASK_ADC_ANAPAR_AD0) << BIT_SHIFT_ADC_ANAPAR_AD0) +#define BIT_CTRL_ADC_ANAPAR_AD0(x) (((x) & BIT_MASK_ADC_ANAPAR_AD0) << BIT_SHIFT_ADC_ANAPAR_AD0) +#define BIT_GET_ADC_ANAPAR_AD0(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD0) & BIT_MASK_ADC_ANAPAR_AD0) + +#define BIT_ADC_AUDIO_EN BIT(1) +#define BIT_SHIFT_ADC_AUDIO_EN 1 +#define BIT_MASK_ADC_AUDIO_EN 0x1 +#define BIT_CTRL_ADC_AUDIO_EN(x) (((x) & BIT_MASK_ADC_AUDIO_EN) << BIT_SHIFT_ADC_AUDIO_EN) + +#define BIT_ADC_EN_MANUAL BIT(0) +#define BIT_SHIFT_ADC_EN_MANUAL 0 +#define BIT_MASK_ADC_EN_MANUAL 0x1 +#define BIT_CTRL_ADC_EN_MANUAL(x) (((x) & BIT_MASK_ADC_EN_MANUAL) << BIT_SHIFT_ADC_EN_MANUAL) + + +//2 REG_ADC_ANAPAR_AD1 + +#define BIT_SHIFT_ADC_ANAPAR_AD1 0 +#define BIT_MASK_ADC_ANAPAR_AD1 0xffffffffL +#define BIT_ADC_ANAPAR_AD1(x) (((x) & BIT_MASK_ADC_ANAPAR_AD1) << BIT_SHIFT_ADC_ANAPAR_AD1) +#define BIT_CTRL_ADC_ANAPAR_AD1(x) (((x) & BIT_MASK_ADC_ANAPAR_AD1) << BIT_SHIFT_ADC_ANAPAR_AD1) +#define BIT_GET_ADC_ANAPAR_AD1(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD1) & BIT_MASK_ADC_ANAPAR_AD1) + + +//2 REG_ADC_ANAPAR_AD2 + +#define BIT_SHIFT_ADC_ANAPAR_AD2 0 +#define BIT_MASK_ADC_ANAPAR_AD2 0xffffffffL +#define BIT_ADC_ANAPAR_AD2(x) (((x) & BIT_MASK_ADC_ANAPAR_AD2) << BIT_SHIFT_ADC_ANAPAR_AD2) +#define BIT_CTRL_ADC_ANAPAR_AD2(x) (((x) & BIT_MASK_ADC_ANAPAR_AD2) << BIT_SHIFT_ADC_ANAPAR_AD2) +#define BIT_GET_ADC_ANAPAR_AD2(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD2) & BIT_MASK_ADC_ANAPAR_AD2) + + +//2 REG_ADC_ANAPAR_AD3 + +#define BIT_SHIFT_ADC_ANAPAR_AD3 0 +#define BIT_MASK_ADC_ANAPAR_AD3 0xffffffffL +#define BIT_ADC_ANAPAR_AD3(x) (((x) & BIT_MASK_ADC_ANAPAR_AD3) << BIT_SHIFT_ADC_ANAPAR_AD3) +#define BIT_CTRL_ADC_ANAPAR_AD3(x) (((x) & BIT_MASK_ADC_ANAPAR_AD3) << BIT_SHIFT_ADC_ANAPAR_AD3) +#define BIT_GET_ADC_ANAPAR_AD3(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD3) & BIT_MASK_ADC_ANAPAR_AD3) + + +//2 REG_ADC_ANAPAR_AD4 + +#define BIT_SHIFT_ADC_ANAPAR_AD4 0 +#define BIT_MASK_ADC_ANAPAR_AD4 0xffffffffL +#define BIT_ADC_ANAPAR_AD4(x) (((x) & BIT_MASK_ADC_ANAPAR_AD4) << BIT_SHIFT_ADC_ANAPAR_AD4) +#define BIT_CTRL_ADC_ANAPAR_AD4(x) (((x) & BIT_MASK_ADC_ANAPAR_AD4) << BIT_SHIFT_ADC_ANAPAR_AD4) +#define BIT_GET_ADC_ANAPAR_AD4(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD4) & BIT_MASK_ADC_ANAPAR_AD4) + + +//2 REG_ADC_ANAPAR_AD5 + +#define BIT_SHIFT_ADC_ANAPAR_AD5 0 +#define BIT_MASK_ADC_ANAPAR_AD5 0xffffffffL +#define BIT_ADC_ANAPAR_AD5(x) (((x) & BIT_MASK_ADC_ANAPAR_AD5) << BIT_SHIFT_ADC_ANAPAR_AD5) +#define BIT_CTRL_ADC_ANAPAR_AD5(x) (((x) & BIT_MASK_ADC_ANAPAR_AD5) << BIT_SHIFT_ADC_ANAPAR_AD5) +#define BIT_GET_ADC_ANAPAR_AD5(x) (((x) >> BIT_SHIFT_ADC_ANAPAR_AD5) & BIT_MASK_ADC_ANAPAR_AD5) + + +//2 REG_ADC_CALI_DATA + +#define BIT_SHIFT_ADC_CALI_DATA_6 16 +#define BIT_MASK_ADC_CALI_DATA_6 0xffff +#define BIT_ADC_CALI_DATA_6(x) (((x) & BIT_MASK_ADC_CALI_DATA_6) << BIT_SHIFT_ADC_CALI_DATA_6) +#define BIT_CTRL_ADC_CALI_DATA_6(x) (((x) & BIT_MASK_ADC_CALI_DATA_6) << BIT_SHIFT_ADC_CALI_DATA_6) +#define BIT_GET_ADC_CALI_DATA_6(x) (((x) >> BIT_SHIFT_ADC_CALI_DATA_6) & BIT_MASK_ADC_CALI_DATA_6) + + +#define BIT_SHIFT_ADC_CALI_DATA_0 0 +#define BIT_MASK_ADC_CALI_DATA_0 0xffff +#define BIT_ADC_CALI_DATA_0(x) (((x) & BIT_MASK_ADC_CALI_DATA_0) << BIT_SHIFT_ADC_CALI_DATA_0) +#define BIT_CTRL_ADC_CALI_DATA_0(x) (((x) & BIT_MASK_ADC_CALI_DATA_0) << BIT_SHIFT_ADC_CALI_DATA_0) +#define BIT_GET_ADC_CALI_DATA_0(x) (((x) >> BIT_SHIFT_ADC_CALI_DATA_0) & BIT_MASK_ADC_CALI_DATA_0) + +//================ Register Reg Field ========================= +#define REG_ADC_FIFO_READ 0x0000 +#define REG_ADC_CONTROL 0x0004 +#define REG_ADC_INTR_EN 0x0008 +#define REG_ADC_INTR_STS 0x000C +#define REG_ADC_COMP_VALUE_L 0x0010 +#define REG_ADC_COMP_VALUE_H 0x0014 +#define REG_ADC_COMP_SET 0x0018 +#define REG_ADC_POWER 0x001C +#define REG_ADC_ANAPAR_AD0 0x0020 +#define REG_ADC_ANAPAR_AD1 0x0024 +#define REG_ADC_ANAPAR_AD2 0x0028 +#define REG_ADC_ANAPAR_AD3 0x002C +#define REG_ADC_ANAPAR_AD4 0x0030 +#define REG_ADC_ANAPAR_AD5 0x0034 +#define REG_ADC_CALI_DATA 0x0038 + +//================ ADC HAL related enumeration ================== + +//================ ADC Function Prototypes ===================== +#define HAL_ADC_WRITE32(addr, value) HAL_WRITE32(ADC_REG_BASE,addr,value) +#define HAL_ADC_READ32(addr) HAL_READ32(ADC_REG_BASE,addr) + +RTK_STATUS HalADCInit8195a(IN VOID *Data); +RTK_STATUS HalADCDeInit8195a(IN VOID *Data); +RTK_STATUS HalADCEnableRtl8195a(IN VOID *Data); +RTK_STATUS HalADCIntrCtrl8195a(IN VOID *Data); +u32 HalADCReceiveRtl8195a(IN VOID *Data); +u32 HalADCReadRegRtl8195a(IN VOID *Data,IN u8 I2CReg); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_dac.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_dac.h new file mode 100644 index 0000000..c3a9861 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_dac.h @@ -0,0 +1,294 @@ +#ifndef _RTL8195A_DAC_H_ +#define _RTL8195A_DAC_H_ + +//================ Register Bit Field ========================== +//2 REG_DAC0_FIFO_WR + +#define BIT_SHIFT_DAC0_FIFO_WO 0 +#define BIT_MASK_DAC0_FIFO_WO 0xffffffffL +#define BIT_DAC0_FIFO_WO(x) (((x) & BIT_MASK_DAC0_FIFO_WO) << BIT_SHIFT_DAC0_FIFO_WO) +#define BIT_CTRL_DAC0_FIFO_WO(x) (((x) & BIT_MASK_DAC0_FIFO_WO) << BIT_SHIFT_DAC0_FIFO_WO) +#define BIT_GET_DAC0_FIFO_WO(x) (((x) >> BIT_SHIFT_DAC0_FIFO_WO) & BIT_MASK_DAC0_FIFO_WO) + + +//2 REG_DAC_CTRL + +#define BIT_SHIFT_DAC_DELTA_SIGMA 25 +#define BIT_MASK_DAC_DELTA_SIGMA 0x7 +#define BIT_DAC_DELTA_SIGMA(x) (((x) & BIT_MASK_DAC_DELTA_SIGMA) << BIT_SHIFT_DAC_DELTA_SIGMA) +#define BIT_CTRL_DAC_DELTA_SIGMA(x) (((x) & BIT_MASK_DAC_DELTA_SIGMA) << BIT_SHIFT_DAC_DELTA_SIGMA) +#define BIT_GET_DAC_DELTA_SIGMA(x) (((x) >> BIT_SHIFT_DAC_DELTA_SIGMA) & BIT_MASK_DAC_DELTA_SIGMA) + +#define BIT_DAC_BYPASS_DSC BIT(24) +#define BIT_SHIFT_DAC_BYPASS_DSC 24 +#define BIT_MASK_DAC_BYPASS_DSC 0x1 +#define BIT_CTRL_DAC_BYPASS_DSC(x) (((x) & BIT_MASK_DAC_BYPASS_DSC) << BIT_SHIFT_DAC_BYPASS_DSC) + + +#define BIT_SHIFT_DAC_DSC_DBG_SEL 19 +#define BIT_MASK_DAC_DSC_DBG_SEL 0x3 +#define BIT_DAC_DSC_DBG_SEL(x) (((x) & BIT_MASK_DAC_DSC_DBG_SEL) << BIT_SHIFT_DAC_DSC_DBG_SEL) +#define BIT_CTRL_DAC_DSC_DBG_SEL(x) (((x) & BIT_MASK_DAC_DSC_DBG_SEL) << BIT_SHIFT_DAC_DSC_DBG_SEL) +#define BIT_GET_DAC_DSC_DBG_SEL(x) (((x) >> BIT_SHIFT_DAC_DSC_DBG_SEL) & BIT_MASK_DAC_DSC_DBG_SEL) + + +#define BIT_SHIFT_DAC_DBG_SEL 16 +#define BIT_MASK_DAC_DBG_SEL 0x7 +#define BIT_DAC_DBG_SEL(x) (((x) & BIT_MASK_DAC_DBG_SEL) << BIT_SHIFT_DAC_DBG_SEL) +#define BIT_CTRL_DAC_DBG_SEL(x) (((x) & BIT_MASK_DAC_DBG_SEL) << BIT_SHIFT_DAC_DBG_SEL) +#define BIT_GET_DAC_DBG_SEL(x) (((x) >> BIT_SHIFT_DAC_DBG_SEL) & BIT_MASK_DAC_DBG_SEL) + + +#define BIT_SHIFT_DAC_BURST_SIZE 8 +#define BIT_MASK_DAC_BURST_SIZE 0xf +#define BIT_DAC_BURST_SIZE(x) (((x) & BIT_MASK_DAC_BURST_SIZE) << BIT_SHIFT_DAC_BURST_SIZE) +#define BIT_CTRL_DAC_BURST_SIZE(x) (((x) & BIT_MASK_DAC_BURST_SIZE) << BIT_SHIFT_DAC_BURST_SIZE) +#define BIT_GET_DAC_BURST_SIZE(x) (((x) >> BIT_SHIFT_DAC_BURST_SIZE) & BIT_MASK_DAC_BURST_SIZE) + +#define BIT_DAC_FILTER_SETTLE BIT(4) +#define BIT_SHIFT_DAC_FILTER_SETTLE 4 +#define BIT_MASK_DAC_FILTER_SETTLE 0x1 +#define BIT_CTRL_DAC_FILTER_SETTLE(x) (((x) & BIT_MASK_DAC_FILTER_SETTLE) << BIT_SHIFT_DAC_FILTER_SETTLE) + +#define BIT_DAC_OV_OPTION BIT(3) +#define BIT_SHIFT_DAC_OV_OPTION 3 +#define BIT_MASK_DAC_OV_OPTION 0x1 +#define BIT_CTRL_DAC_OV_OPTION(x) (((x) & BIT_MASK_DAC_OV_OPTION) << BIT_SHIFT_DAC_OV_OPTION) + +#define BIT_DAC_ENDIAN BIT(2) +#define BIT_SHIFT_DAC_ENDIAN 2 +#define BIT_MASK_DAC_ENDIAN 0x1 +#define BIT_CTRL_DAC_ENDIAN(x) (((x) & BIT_MASK_DAC_ENDIAN) << BIT_SHIFT_DAC_ENDIAN) + +#define BIT_DAC_SPEED BIT(1) +#define BIT_SHIFT_DAC_SPEED 1 +#define BIT_MASK_DAC_SPEED 0x1 +#define BIT_CTRL_DAC_SPEED(x) (((x) & BIT_MASK_DAC_SPEED) << BIT_SHIFT_DAC_SPEED) + +#define BIT_DAC_FIFO_EN BIT(0) +#define BIT_SHIFT_DAC_FIFO_EN 0 +#define BIT_MASK_DAC_FIFO_EN 0x1 +#define BIT_CTRL_DAC_FIFO_EN(x) (((x) & BIT_MASK_DAC_FIFO_EN) << BIT_SHIFT_DAC_FIFO_EN) + + +//2 REG_DAC_INTR_CTRL +#define BIT_DAC_DSC_OVERFLOW1_EN BIT(6) +#define BIT_SHIFT_DAC_DSC_OVERFLOW1_EN 6 +#define BIT_MASK_DAC_DSC_OVERFLOW1_EN 0x1 +#define BIT_CTRL_DAC_DSC_OVERFLOW1_EN(x) (((x) & BIT_MASK_DAC_DSC_OVERFLOW1_EN) << BIT_SHIFT_DAC_DSC_OVERFLOW1_EN) + +#define BIT_DAC_DSC_OVERFLOW0_EN BIT(5) +#define BIT_SHIFT_DAC_DSC_OVERFLOW0_EN 5 +#define BIT_MASK_DAC_DSC_OVERFLOW0_EN 0x1 +#define BIT_CTRL_DAC_DSC_OVERFLOW0_EN(x) (((x) & BIT_MASK_DAC_DSC_OVERFLOW0_EN) << BIT_SHIFT_DAC_DSC_OVERFLOW0_EN) + +#define BIT_DAC__WRITE_ERROR_EN BIT(4) +#define BIT_SHIFT_DAC__WRITE_ERROR_EN 4 +#define BIT_MASK_DAC__WRITE_ERROR_EN 0x1 +#define BIT_CTRL_DAC__WRITE_ERROR_EN(x) (((x) & BIT_MASK_DAC__WRITE_ERROR_EN) << BIT_SHIFT_DAC__WRITE_ERROR_EN) + +#define BIT_DAC_FIFO_STOP_EN BIT(3) +#define BIT_SHIFT_DAC_FIFO_STOP_EN 3 +#define BIT_MASK_DAC_FIFO_STOP_EN 0x1 +#define BIT_CTRL_DAC_FIFO_STOP_EN(x) (((x) & BIT_MASK_DAC_FIFO_STOP_EN) << BIT_SHIFT_DAC_FIFO_STOP_EN) + +#define BIT_DAC_FIFO_OVERFLOW_EN BIT(2) +#define BIT_SHIFT_DAC_FIFO_OVERFLOW_EN 2 +#define BIT_MASK_DAC_FIFO_OVERFLOW_EN 0x1 +#define BIT_CTRL_DAC_FIFO_OVERFLOW_EN(x) (((x) & BIT_MASK_DAC_FIFO_OVERFLOW_EN) << BIT_SHIFT_DAC_FIFO_OVERFLOW_EN) + +#define BIT_DAC_FIFO_WR_REQ_EN BIT(1) +#define BIT_SHIFT_DAC_FIFO_WR_REQ_EN 1 +#define BIT_MASK_DAC_FIFO_WR_REQ_EN 0x1 +#define BIT_CTRL_DAC_FIFO_WR_REQ_EN(x) (((x) & BIT_MASK_DAC_FIFO_WR_REQ_EN) << BIT_SHIFT_DAC_FIFO_WR_REQ_EN) + +#define BIT_DAC_FIFO_FULL_EN BIT(0) +#define BIT_SHIFT_DAC_FIFO_FULL_EN 0 +#define BIT_MASK_DAC_FIFO_FULL_EN 0x1 +#define BIT_CTRL_DAC_FIFO_FULL_EN(x) (((x) & BIT_MASK_DAC_FIFO_FULL_EN) << BIT_SHIFT_DAC_FIFO_FULL_EN) + + +//2 REG_DAC_INTR_STS +#define BIT_DAC_DSC_OVERFLOW1_ST BIT(6) +#define BIT_SHIFT_DAC_DSC_OVERFLOW1_ST 6 +#define BIT_MASK_DAC_DSC_OVERFLOW1_ST 0x1 +#define BIT_CTRL_DAC_DSC_OVERFLOW1_ST(x) (((x) & BIT_MASK_DAC_DSC_OVERFLOW1_ST) << BIT_SHIFT_DAC_DSC_OVERFLOW1_ST) + +#define BIT_DAC_DSC_OVERFLOW0_ST BIT(5) +#define BIT_SHIFT_DAC_DSC_OVERFLOW0_ST 5 +#define BIT_MASK_DAC_DSC_OVERFLOW0_ST 0x1 +#define BIT_CTRL_DAC_DSC_OVERFLOW0_ST(x) (((x) & BIT_MASK_DAC_DSC_OVERFLOW0_ST) << BIT_SHIFT_DAC_DSC_OVERFLOW0_ST) + +#define BIT_DAC__WRITE_ERROR_ST BIT(4) +#define BIT_SHIFT_DAC__WRITE_ERROR_ST 4 +#define BIT_MASK_DAC__WRITE_ERROR_ST 0x1 +#define BIT_CTRL_DAC__WRITE_ERROR_ST(x) (((x) & BIT_MASK_DAC__WRITE_ERROR_ST) << BIT_SHIFT_DAC__WRITE_ERROR_ST) + +#define BIT_DAC_FIFO_STOP_ST BIT(3) +#define BIT_SHIFT_DAC_FIFO_STOP_ST 3 +#define BIT_MASK_DAC_FIFO_STOP_ST 0x1 +#define BIT_CTRL_DAC_FIFO_STOP_ST(x) (((x) & BIT_MASK_DAC_FIFO_STOP_ST) << BIT_SHIFT_DAC_FIFO_STOP_ST) + +#define BIT_DAC_FIFO_OVERFLOW_ST BIT(2) +#define BIT_SHIFT_DAC_FIFO_OVERFLOW_ST 2 +#define BIT_MASK_DAC_FIFO_OVERFLOW_ST 0x1 +#define BIT_CTRL_DAC_FIFO_OVERFLOW_ST(x) (((x) & BIT_MASK_DAC_FIFO_OVERFLOW_ST) << BIT_SHIFT_DAC_FIFO_OVERFLOW_ST) + +#define BIT_DAC_FIFO_WR_REQ_ST BIT(1) +#define BIT_SHIFT_DAC_FIFO_WR_REQ_ST 1 +#define BIT_MASK_DAC_FIFO_WR_REQ_ST 0x1 +#define BIT_CTRL_DAC_FIFO_WR_REQ_ST(x) (((x) & BIT_MASK_DAC_FIFO_WR_REQ_ST) << BIT_SHIFT_DAC_FIFO_WR_REQ_ST) + +#define BIT_DAC_FIFO_FULL_ST BIT(0) +#define BIT_SHIFT_DAC_FIFO_FULL_ST 0 +#define BIT_MASK_DAC_FIFO_FULL_ST 0x1 +#define BIT_CTRL_DAC_FIFO_FULL_ST(x) (((x) & BIT_MASK_DAC_FIFO_FULL_ST) << BIT_SHIFT_DAC_FIFO_FULL_ST) + + +//2 REG_DAC_PWR_CTRL + +#define BIT_SHIFT_DAC_PWR_CUT_CNTR 16 +#define BIT_MASK_DAC_PWR_CUT_CNTR 0xff +#define BIT_DAC_PWR_CUT_CNTR(x) (((x) & BIT_MASK_DAC_PWR_CUT_CNTR) << BIT_SHIFT_DAC_PWR_CUT_CNTR) +#define BIT_CTRL_DAC_PWR_CUT_CNTR(x) (((x) & BIT_MASK_DAC_PWR_CUT_CNTR) << BIT_SHIFT_DAC_PWR_CUT_CNTR) +#define BIT_GET_DAC_PWR_CUT_CNTR(x) (((x) >> BIT_SHIFT_DAC_PWR_CUT_CNTR) & BIT_MASK_DAC_PWR_CUT_CNTR) + +#define BIT_ST_DAC_FIFO_ON BIT(11) +#define BIT_SHIFT_ST_DAC_FIFO_ON 11 +#define BIT_MASK_ST_DAC_FIFO_ON 0x1 +#define BIT_CTRL_ST_DAC_FIFO_ON(x) (((x) & BIT_MASK_ST_DAC_FIFO_ON) << BIT_SHIFT_ST_DAC_FIFO_ON) + +#define BIT_ST_DAC_ISO_ON BIT(10) +#define BIT_SHIFT_ST_DAC_ISO_ON 10 +#define BIT_MASK_ST_DAC_ISO_ON 0x1 +#define BIT_CTRL_ST_DAC_ISO_ON(x) (((x) & BIT_MASK_ST_DAC_ISO_ON) << BIT_SHIFT_ST_DAC_ISO_ON) + +#define BIT_ST_DAC_PWR33_ON BIT(9) +#define BIT_SHIFT_ST_DAC_PWR33_ON 9 +#define BIT_MASK_ST_DAC_PWR33_ON 0x1 +#define BIT_CTRL_ST_DAC_PWR33_ON(x) (((x) & BIT_MASK_ST_DAC_PWR33_ON) << BIT_SHIFT_ST_DAC_PWR33_ON) + +#define BIT_ST_DAC_PWR12_ON BIT(8) +#define BIT_SHIFT_ST_DAC_PWR12_ON 8 +#define BIT_MASK_ST_DAC_PWR12_ON 0x1 +#define BIT_CTRL_ST_DAC_PWR12_ON(x) (((x) & BIT_MASK_ST_DAC_PWR12_ON) << BIT_SHIFT_ST_DAC_PWR12_ON) + +#define BIT_DAC_ISO_MANU BIT(3) +#define BIT_SHIFT_DAC_ISO_MANU 3 +#define BIT_MASK_DAC_ISO_MANU 0x1 +#define BIT_CTRL_DAC_ISO_MANU(x) (((x) & BIT_MASK_DAC_ISO_MANU) << BIT_SHIFT_DAC_ISO_MANU) + +#define BIT_DAC_PWR33_MANU BIT(2) +#define BIT_SHIFT_DAC_PWR33_MANU 2 +#define BIT_MASK_DAC_PWR33_MANU 0x1 +#define BIT_CTRL_DAC_PWR33_MANU(x) (((x) & BIT_MASK_DAC_PWR33_MANU) << BIT_SHIFT_DAC_PWR33_MANU) + +#define BIT_DAC_PWR12_MANU BIT(1) +#define BIT_SHIFT_DAC_PWR12_MANU 1 +#define BIT_MASK_DAC_PWR12_MANU 0x1 +#define BIT_CTRL_DAC_PWR12_MANU(x) (((x) & BIT_MASK_DAC_PWR12_MANU) << BIT_SHIFT_DAC_PWR12_MANU) + +#define BIT_DAC_PWR_AUTO BIT(0) +#define BIT_SHIFT_DAC_PWR_AUTO 0 +#define BIT_MASK_DAC_PWR_AUTO 0x1 +#define BIT_CTRL_DAC_PWR_AUTO(x) (((x) & BIT_MASK_DAC_PWR_AUTO) << BIT_SHIFT_DAC_PWR_AUTO) + + +//2 REG_DAC_ANAPAR_DA0 + +#define BIT_SHIFT_PWR_ALL_CNTR 12 +#define BIT_MASK_PWR_ALL_CNTR 0xfffff +#define BIT_PWR_ALL_CNTR(x) (((x) & BIT_MASK_PWR_ALL_CNTR) << BIT_SHIFT_PWR_ALL_CNTR) +#define BIT_CTRL_PWR_ALL_CNTR(x) (((x) & BIT_MASK_PWR_ALL_CNTR) << BIT_SHIFT_PWR_ALL_CNTR) +#define BIT_GET_PWR_ALL_CNTR(x) (((x) >> BIT_SHIFT_PWR_ALL_CNTR) & BIT_MASK_PWR_ALL_CNTR) + + +#define BIT_SHIFT_PWR_FUP_CNTR 0 +#define BIT_MASK_PWR_FUP_CNTR 0xfff +#define BIT_PWR_FUP_CNTR(x) (((x) & BIT_MASK_PWR_FUP_CNTR) << BIT_SHIFT_PWR_FUP_CNTR) +#define BIT_CTRL_PWR_FUP_CNTR(x) (((x) & BIT_MASK_PWR_FUP_CNTR) << BIT_SHIFT_PWR_FUP_CNTR) +#define BIT_GET_PWR_FUP_CNTR(x) (((x) >> BIT_SHIFT_PWR_FUP_CNTR) & BIT_MASK_PWR_FUP_CNTR) + + +//2 REG_DAC_ANAPAR_DA1 +#define BIT_FUP_EN BIT(31) +#define BIT_SHIFT_FUP_EN 31 +#define BIT_MASK_FUP_EN 0x1 +#define BIT_CTRL_FUP_EN(x) (((x) & BIT_MASK_FUP_EN) << BIT_SHIFT_FUP_EN) + + +#define BIT_SHIFT_ANAPAR_DA 8 +#define BIT_MASK_ANAPAR_DA 0x7fffff +#define BIT_ANAPAR_DA(x) (((x) & BIT_MASK_ANAPAR_DA) << BIT_SHIFT_ANAPAR_DA) +#define BIT_CTRL_ANAPAR_DA(x) (((x) & BIT_MASK_ANAPAR_DA) << BIT_SHIFT_ANAPAR_DA) +#define BIT_GET_ANAPAR_DA(x) (((x) >> BIT_SHIFT_ANAPAR_DA) & BIT_MASK_ANAPAR_DA) + +#define BIT_D_POW_DACVREF BIT(7) +#define BIT_SHIFT_D_POW_DACVREF 7 +#define BIT_MASK_D_POW_DACVREF 0x1 +#define BIT_CTRL_D_POW_DACVREF(x) (((x) & BIT_MASK_D_POW_DACVREF) << BIT_SHIFT_D_POW_DACVREF) + +#define BIT_D_POW_VREF2 BIT(6) +#define BIT_SHIFT_D_POW_VREF2 6 +#define BIT_MASK_D_POW_VREF2 0x1 +#define BIT_CTRL_D_POW_VREF2(x) (((x) & BIT_MASK_D_POW_VREF2) << BIT_SHIFT_D_POW_VREF2) + +#define BIT_D_POW_MBIAS BIT(5) +#define BIT_SHIFT_D_POW_MBIAS 5 +#define BIT_MASK_D_POW_MBIAS 0x1 +#define BIT_CTRL_D_POW_MBIAS(x) (((x) & BIT_MASK_D_POW_MBIAS) << BIT_SHIFT_D_POW_MBIAS) + +#define BIT_D_POW_DIV4 BIT(4) +#define BIT_SHIFT_D_POW_DIV4 4 +#define BIT_MASK_D_POW_DIV4 0x1 +#define BIT_CTRL_D_POW_DIV4(x) (((x) & BIT_MASK_D_POW_DIV4) << BIT_SHIFT_D_POW_DIV4) + +#define BIT_D_POW_DF1SE_R BIT(3) +#define BIT_SHIFT_D_POW_DF1SE_R 3 +#define BIT_MASK_D_POW_DF1SE_R 0x1 +#define BIT_CTRL_D_POW_DF1SE_R(x) (((x) & BIT_MASK_D_POW_DF1SE_R) << BIT_SHIFT_D_POW_DF1SE_R) + +#define BIT_D_POW_DF2SE_L BIT(2) +#define BIT_SHIFT_D_POW_DF2SE_L 2 +#define BIT_MASK_D_POW_DF2SE_L 0x1 +#define BIT_CTRL_D_POW_DF2SE_L(x) (((x) & BIT_MASK_D_POW_DF2SE_L) << BIT_SHIFT_D_POW_DF2SE_L) + +#define BIT_D_POW_DAC_R BIT(1) +#define BIT_SHIFT_D_POW_DAC_R 1 +#define BIT_MASK_D_POW_DAC_R 0x1 +#define BIT_CTRL_D_POW_DAC_R(x) (((x) & BIT_MASK_D_POW_DAC_R) << BIT_SHIFT_D_POW_DAC_R) + +#define BIT_D_POW_DAC_L BIT(0) +#define BIT_SHIFT_D_POW_DAC_L 0 +#define BIT_MASK_D_POW_DAC_L 0x1 +#define BIT_CTRL_D_POW_DAC_L(x) (((x) & BIT_MASK_D_POW_DAC_L) << BIT_SHIFT_D_POW_DAC_L) + + +//================ Register Reg Field ========================= +#define REG_DAC0_FIFO_WR 0x0000 +#define REG_DAC_CTRL 0x0004 +#define REG_DAC_INTR_CTRL 0x0008 +#define REG_DAC_INTR_STS 0x000C +#define REG_DAC_PWR_CTRL 0x0010 +#define REG_DAC_ANAPAR_DA0 0x0014 +#define REG_DAC_ANAPAR_DA1 0x0018 + + +//================ DAC HAL related enumeration ================== + + +//================ DAC HAL Macro =========================== +#define HAL_DAC_WRITE32(dacidx, addr, value) HAL_WRITE32(DAC_REG_BASE+dacidx*0x800 \ + ,addr,value) +#define HAL_DAC_READ32(dacidx, addr) HAL_READ32(DAC_REG_BASE+dacidx*0x800,addr) + + +//================ DAC Function Prototypes ===================== +RTK_STATUS HalDACInit8195a(IN VOID *Data); +RTK_STATUS HalDACDeInit8195a(IN VOID *Data); +RTK_STATUS HalDACEnableRtl8195a(IN VOID *Data); +RTK_STATUS HalDACIntrCtrl8195a(IN VOID *Data); +u8 HalDACSendRtl8195a(IN VOID *Data); +u32 HalDACReadRegRtl8195a(IN VOID *Data,IN u8 I2CReg); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gdma.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gdma.h new file mode 100644 index 0000000..b384942 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gdma.h @@ -0,0 +1,528 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_GDMA_H_ +#define _RTL8195A_GDMA_H_ + +// Define GDMA Handshake interface with peripheral, 0 -> GDMA0, 1-> GDMA1 +// Set this Hnadshake interface map to register REG_PESOC_SOC_CTRL +#define GDMA_HANDSHAKE_UART0_TX 0 +#define GDMA_HANDSHAKE_UART0_RX 1 +#define GDMA_HANDSHAKE_UART1_TX 2 +#define GDMA_HANDSHAKE_UART1_RX 3 +#define GDMA_HANDSHAKE_UART2_TX 14 // Only on GDMA 0, hardware fixed +#define GDMA_HANDSHAKE_UART2_RX 14 // Only on GDMA 1, hardware fixed + +#define GDMA_HANDSHAKE_SSI0_TX 4 +#define GDMA_HANDSHAKE_SSI0_RX 5 +#define GDMA_HANDSHAKE_SSI1_TX 6 +#define GDMA_HANDSHAKE_SSI1_RX 7 +#define GDMA_HANDSHAKE_SSI2_TX 15 // Only on GDMA 0, hardware fixed +#define GDMA_HANDSHAKE_SSI2_RX 15 // Only on GDMA 1, hardware fixed + +#define GDMA_HANDSHAKE_I2C0_TX 8 +#define GDMA_HANDSHAKE_I2C0_RX 9 +#define GDMA_HANDSHAKE_I2C1_TX 10 +#define GDMA_HANDSHAKE_I2C1_RX 11 + +#define GDMA_HANDSHAKE_ADC 12 +#define GDMA_HANDSHAKE_DAC0 13 // Only on GDMA 0, hardware fixed +#define GDMA_HANDSHAKE_DAC1 13 // Only on GDMA 1, hardware fixed + +#define HAL_GDMAX_READ32(GdmaIndex, addr) \ + HAL_READ32(GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF), addr) +#define HAL_GDMAX_WRITE32(GdmaIndex, addr, value) \ + HAL_WRITE32((GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF)), addr, value) +#define HAL_GDMAX_READ16(GdmaIndex, addr) \ + HAL_READ16(GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF), addr) +#define HAL_GDMAX_WRITE16(GdmaIndex, addr, value) \ + HAL_WRITE16(GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF), addr, value) +#define HAL_GDMAX_READ8(GdmaIndex, addr) \ + HAL_READ8(GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF), addr) +#define HAL_GDMAX_WRITE8(GdmaIndex, addr, value) \ + HAL_WRITE8(GDMA0_REG_BASE+ (GdmaIndex*GDMA1_REG_OFF), addr, value) + + +#define GDMA_CH_MAX 0x06 + +#define REG_GDMA_CH_OFF 0x058 +#define REG_GDMA_CH_SAR 0x000 +#define REG_GDMA_CH_DAR 0x008 +#define REG_GDMA_CH_LLP 0x010 +#define REG_GDMA_CH_CTL 0x018 +#define REG_GDMA_CH_SSTAT 0x020 +#define REG_GDMA_CH_DSTAT 0x028 +#define REG_GDMA_CH_SSTATAR 0x030 +#define REG_GDMA_CH_DSTATAR 0x038 +#define REG_GDMA_CH_CFG 0x040 +#define REG_GDMA_CH_SGR 0x048 +#define REG_GDMA_CH_DSR 0x050 + +#define MAX_DMA_BLOCK_SIZE 4092 + +//3 Interrupt Registers +#define REG_GDMA_RAW_INT_BASE 0x2C0 +#define REG_GDMA_RAW_INT_TFR 0x2C0 +#define REG_GDMA_RAW_INT_BLOCK 0x2c8 +#define REG_GDMA_RAW_INT_SRC_TRAN 0x2D0 +#define REG_GDMA_RAW_INT_DST_TRAN 0x2D8 +#define REG_GDMA_RAW_INT_ERR 0x2E0 + +#define REG_GDMA_STATUS_INT_BASE 0x2E8 +#define REG_GDMA_STATUS_INT_TFR 0x2E8 +#define REG_GDMA_STATUS_INT_BLOCK 0x2F0 +#define REG_GDMA_STATUS_INT_SRC_TRAN 0x2F8 +#define REG_GDMA_STATUS_INT_DST_TRAN 0x300 +#define REG_GDMA_STATUS_INT_ERR 0x308 + +#define REG_GDMA_MASK_INT_BASE 0x310 +#define REG_GDMA_MASK_INT_TFR 0x310 +#define REG_GDMA_MASK_INT_BLOCK 0x318 +#define REG_GDMA_MASK_INT_SRC_TRAN 0x320 +#define REG_GDMA_MASK_INT_DST_TRAN 0x328 +#define REG_GDMA_MASK_INT_INT_ERR 0x330 + +#define REG_GDMA_CLEAR_INT_BASE 0x338 +#define REG_GDMA_CLEAR_INT_TFR 0x338 +#define REG_GDMA_CLEAR_INT_BLOCK 0x340 +#define REG_GDMA_CLEAR_INT_SRC_TRAN 0x348 +#define REG_GDMA_CLEAR_INT_DST_TRAN 0x350 +#define REG_GDMA_CLEAR_INT_ERR 0x358 +#define REG_GDMA_STATUS_INT 0x360 + +//3 Software handshaking Registers +#define REG_GDMA_REQ_SRC 0x368 +#define REG_GDMA_REQ_DST 0x370 +#define REG_GDMA_REQ_SGL_REQ 0x378 +#define REG_GDMA_REQ_DST_REQ 0x380 +#define REG_GDMA_REQ_LST_SRC 0x388 +#define REG_GDMA_REQ_LST_DST 0x390 + +//3 Miscellaneous Registers +#define REG_GDMA_DMAC_CFG 0x398 +#define REG_GDMA_CH_EN 0x3A0 +#define REG_GDMA_DMA_ID 0x3A8 +#define REG_GDMA_DMA_TEST 0x3B0 +#define REG_GDMA_DMA_COM_PARAMS6 0x3C8 +#define REG_GDMA_DMA_COM_PARAMS5 0x3D0 +#define REG_GDMA_DMA_COM_PARAMS4 0x3D8 +#define REG_GDMA_DMA_COM_PARAMS3 0x3E0 +#define REG_GDMA_DMA_COM_PARAMS2 0x3E8 +#define REG_GDMA_DMA_COM_PARAMS1 0x3F0 +#define REG_GDMA_DMA_COM_PARAMS0 0x3F8 + +//3 CTL Register Bit Control +#define BIT_SHIFT_CTLX_LO_INT_EN 0 +#define BIT_MASK_CTLX_LO_INT_EN 0x1 +#define BIT_CTLX_LO_INT_EN(x)(((x) & BIT_MASK_CTLX_LO_INT_EN) << BIT_SHIFT_CTLX_LO_INT_EN) +#define BIT_INVC_CTLX_LO_INT_EN (~(BIT_MASK_CTLX_LO_INT_EN << BIT_SHIFT_CTLX_LO_INT_EN)) + +#define BIT_SHIFT_CTLX_LO_DST_TR_WIDTH 1 +#define BIT_MASK_CTLX_LO_DST_TR_WIDTH 0x7 +#define BIT_CTLX_LO_DST_TR_WIDTH(x) (((x) & BIT_MASK_CTLX_LO_DST_TR_WIDTH) << BIT_SHIFT_CTLX_LO_DST_TR_WIDTH) +#define BIT_INVC_CTLX_LO_DST_TR_WIDTH (~(BIT_MASK_CTLX_LO_DST_TR_WIDTH << BIT_SHIFT_CTLX_LO_DST_TR_WIDTH)) + +#define BIT_SHIFT_CTLX_LO_SRC_TR_WIDTH 4 +#define BIT_MASK_CTLX_LO_SRC_TR_WIDTH 0x7 +#define BIT_CTLX_LO_SRC_TR_WIDTH(x) (((x) & BIT_MASK_CTLX_LO_SRC_TR_WIDTH) << BIT_SHIFT_CTLX_LO_SRC_TR_WIDTH) +#define BIT_INVC_CTLX_LO_SRC_TR_WIDTH (~(BIT_MASK_CTLX_LO_SRC_TR_WIDTH << BIT_SHIFT_CTLX_LO_SRC_TR_WIDTH)) + +#define BIT_SHIFT_CTLX_LO_DINC 7 +#define BIT_MASK_CTLX_LO_DINC 0x3 +#define BIT_CTLX_LO_DINC(x)(((x) & BIT_MASK_CTLX_LO_DINC) << BIT_SHIFT_CTLX_LO_DINC) +#define BIT_INVC_CTLX_LO_DINC (~(BIT_MASK_CTLX_LO_DINC << BIT_SHIFT_CTLX_LO_DINC)) + +#define BIT_SHIFT_CTLX_LO_SINC 9 +#define BIT_MASK_CTLX_LO_SINC 0x3 +#define BIT_CTLX_LO_SINC(x)(((x) & BIT_MASK_CTLX_LO_SINC) << BIT_SHIFT_CTLX_LO_SINC) +#define BIT_INVC_CTLX_LO_SINC (~(BIT_MASK_CTLX_LO_SINC << BIT_SHIFT_CTLX_LO_SINC)) + +#define BIT_SHIFT_CTLX_LO_DEST_MSIZE 11 +#define BIT_MASK_CTLX_LO_DEST_MSIZE 0x7 +#define BIT_CTLX_LO_DEST_MSIZE(x)(((x) & BIT_MASK_CTLX_LO_DEST_MSIZE) << BIT_SHIFT_CTLX_LO_DEST_MSIZE) +#define BIT_INVC_CTLX_LO_DEST_MSIZE (~(BIT_MASK_CTLX_LO_DEST_MSIZE << BIT_SHIFT_CTLX_LO_DEST_MSIZE)) + +#define BIT_SHIFT_CTLX_LO_SRC_MSIZE 14 +#define BIT_MASK_CTLX_LO_SRC_MSIZE 0x7 +#define BIT_CTLX_LO_SRC_MSIZE(x)(((x) & BIT_MASK_CTLX_LO_SRC_MSIZE) << BIT_SHIFT_CTLX_LO_SRC_MSIZE) +#define BIT_INVC_CTLX_LO_SRC_MSIZE (~(BIT_MASK_CTLX_LO_SRC_MSIZE << BIT_SHIFT_CTLX_LO_SRC_MSIZE)) + + +#define BIT_SHIFT_CTLX_LO_SRC_GATHER_EN 17 +#define BIT_MASK_CTLX_LO_SRC_GATHER_EN 0x1 +#define BIT_CTLX_LO_SRC_GATHER_EN(x)(((x) & BIT_MASK_CTLX_LO_SRC_GATHER_EN) << BIT_SHIFT_CTLX_LO_SRC_GATHER_EN) +#define BIT_INVC_CTLX_LO_SRC_GATHER_EN (~(BIT_MASK_CTLX_LO_SRC_GATHER_EN << BIT_SHIFT_CTLX_LO_SRC_GATHER_EN)) + + +#define BIT_SHIFT_CTLX_LO_DST_SCATTER_EN 18 +#define BIT_MASK_CTLX_LO_DST_SCATTER_EN 0x1 +#define BIT_CTLX_LO_DST_SCATTER_EN(x)(((x) & BIT_MASK_CTLX_LO_DST_SCATTER_EN) << BIT_SHIFT_CTLX_LO_DST_SCATTER_EN) +#define BIT_INVC_CTLX_LO_DST_SCATTER_EN (~(BIT_MASK_CTLX_LO_DST_SCATTER_EN << BIT_SHIFT_CTLX_LO_DST_SCATTER_EN)) + + +#define BIT_SHIFT_CTLX_LO_TT_FC 20 +#define BIT_MASK_CTLX_LO_TT_FC 0x7 +#define BIT_CTLX_LO_TT_FC(x)(((x) & BIT_MASK_CTLX_LO_TT_FC) << BIT_SHIFT_CTLX_LO_TT_FC) +#define BIT_INVC_CTLX_LO_TT_FC (~(BIT_MASK_CTLX_LO_TT_FC << BIT_SHIFT_CTLX_LO_TT_FC)) + + +#define BIT_SHIFT_CTLX_LO_DMS 23 +#define BIT_MASK_CTLX_LO_DMS 0x3 +#define BIT_CTLX_LO_DMS(x)(((x) & BIT_MASK_CTLX_LO_DMS) << BIT_MASK_CTLX_LO_DMS) +#define BIT_INVC_CTLX_LO_DMS (~(BIT_MASK_CTLX_LO_DMS << BIT_SHIFT_CTLX_LO_DMS)) + + +#define BIT_SHIFT_CTLX_LO_SMS 25 +#define BIT_MASK_CTLX_LO_SMS 0x3 +#define BIT_CTLX_LO_SMS(x)(((x) & BIT_MASK_CTLX_LO_SMS) << BIT_SHIFT_CTLX_LO_SMS) +#define BIT_INVC_CTLX_LO_SMS (~(BIT_MASK_CTLX_LO_SMS << BIT_SHIFT_CTLX_LO_SMS)) + + +#define BIT_SHIFT_CTLX_LO_LLP_DST_EN 27 +#define BIT_MASK_CTLX_LO_LLP_DST_EN 0x1 +#define BIT_CTLX_LO_LLP_DST_EN(x)(((x) & BIT_MASK_CTLX_LO_LLP_DST_EN) << BIT_SHIFT_CTLX_LO_LLP_DST_EN) +#define BIT_INVC_CTLX_LO_LLP_DST_EN (~(BIT_MASK_CTLX_LO_LLP_DST_EN << BIT_SHIFT_CTLX_LO_LLP_DST_EN)) + +#define BIT_SHIFT_CTLX_LO_LLP_SRC_EN 28 +#define BIT_MASK_CTLX_LO_LLP_SRC_EN 0x1 +#define BIT_CTLX_LO_LLP_SRC_EN(x)(((x) & BIT_MASK_CTLX_LO_LLP_SRC_EN) << BIT_SHIFT_CTLX_LO_LLP_SRC_EN) +#define BIT_INVC_CTLX_LO_LLP_SRC_EN (~(BIT_MASK_CTLX_LO_LLP_SRC_EN << BIT_SHIFT_CTLX_LO_LLP_SRC_EN)) + + +#define BIT_SHIFT_CTLX_UP_BLOCK_BS 0 +#define BIT_MASK_CTLX_UP_BLOCK_BS 0xFFF +#define BIT_CTLX_UP_BLOCK_BS(x)(((x) & BIT_MASK_CTLX_UP_BLOCK_BS) << BIT_SHIFT_CTLX_UP_BLOCK_BS) +#define BIT_INVC_CTLX_UP_BLOCK_BS (~(BIT_MASK_CTLX_UP_BLOCK_BS << BIT_SHIFT_CTLX_UP_BLOCK_BS)) + + +#define BIT_SHIFT_CTLX_UP_DONE 12 +#define BIT_MASK_CTLX_UP_DONE 0x1 +#define BIT_CTLX_UP_DONE(x)(((x) & BIT_MASK_CTLX_UP_DONE) << BIT_SHIFT_CTLX_UP_DONE) +#define BIT_INVC_CTLX_UP_DONE (~(BIT_MASK_CTLX_UP_DONE << BIT_SHIFT_CTLX_UP_DONE)) + + +//3 CFG Register Bit Control +#define BIT_SHIFT_CFGX_LO_CH_PRIOR 5 +#define BIT_MASK_CFGX_LO_CH_PRIOR 0x7 +#define BIT_CFGX_LO_CH_PRIOR(x)(((x) & BIT_MASK_CFGX_LO_CH_PRIOR) << BIT_SHIFT_CFGX_LO_CH_PRIOR) +#define BIT_INVC_CFGX_LO_CH_PRIOR (~(BIT_MASK_CFGX_LO_CH_PRIOR << BIT_SHIFT_CFGX_LO_CH_PRIOR)) + + +#define BIT_SHIFT_CFGX_LO_CH_SUSP 8 +#define BIT_MASK_CFGX_LO_CH_SUSP 0x1 +#define BIT_CFGX_LO_CH_SUSP(x)(((x) & BIT_MASK_CFGX_LO_CH_SUSP) << BIT_SHIFT_CFGX_LO_CH_SUSP) +#define BIT_INVC_CFGX_LO_CH_SUSP (~(BIT_MASK_CFGX_LO_CH_SUSP << BIT_SHIFT_CFGX_LO_CH_SUSP)) + + +#define BIT_SHIFT_CFGX_LO_FIFO_EMPTY 9 +#define BIT_MASK_CFGX_LO_FIFO_EMPTY 0x1 +#define BIT_CFGX_LO_FIFO_EMPTY(x)(((x) & BIT_MASK_CFGX_LO_FIFO_EMPTY) << BIT_SHIFT_CFGX_LO_FIFO_EMPTY) +#define BIT_INVC_CFGX_LO_FIFO_EMPTY (~(BIT_MASK_CFGX_LO_FIFO_EMPTY << BIT_SHIFT_CFGX_LO_FIFO_EMPTY)) + + +#define BIT_SHIFT_CFGX_LO_HS_SEL_DST 10 +#define BIT_MASK_CFGX_LO_HS_SEL_DST 0x1 +#define BIT_CFGX_LO_HS_SEL_DST(x)(((x) & BIT_MASK_CFGX_LO_HS_SEL_DST) << BIT_SHIFT_CFGX_LO_HS_SEL_DST) +#define BIT_INVC_CFGX_LO_HS_SEL_DST (~(BIT_MASK_CFGX_LO_HS_SEL_DST << BIT_SHIFT_CFGX_LO_HS_SEL_DST)) + +#define BIT_SHIFT_CFGX_LO_HS_SEL_SRC 11 +#define BIT_MASK_CFGX_LO_HS_SEL_SRC 0x1 +#define BIT_CFGX_LO_HS_SEL_SRC(x)(((x) & BIT_MASK_CFGX_LO_HS_SEL_SRC) << BIT_SHIFT_CFGX_LO_HS_SEL_SRC) +#define BIT_INVC_CFGX_LO_HS_SEL_SRC (~(BIT_MASK_CFGX_LO_HS_SEL_SRC << BIT_SHIFT_CFGX_LO_HS_SEL_SRC)) + +#define BIT_SHIFT_CFGX_LO_LOCK_CH_L 12 +#define BIT_MASK_CFGX_LO_LOCK_CH_L 0x3 +#define BIT_CFGX_LO_LOCK_CH_L(x)(((x) & BIT_MASK_CFGX_LO_LOCK_CH_L) << BIT_SHIFT_CFGX_LO_LOCK_CH_L) +#define BIT_INVC_CFGX_LO_LOCK_CH_L (~(BIT_MASK_CFGX_LO_LOCK_CH_L << BIT_SHIFT_CFGX_LO_LOCK_CH_L)) + +#define BIT_SHIFT_CFGX_LO_LOCK_B_L 14 +#define BIT_MASK_CFGX_LO_LOCK_B_L 0x3 +#define BIT_CFGX_LO_LOCK_B_L(x)(((x) & BIT_MASK_CFGX_LO_LOCK_B_L) << BIT_SHIFT_CFGX_LO_LOCK_B_L) +#define BIT_INVC_CFGX_LO_LOCK_B_L (~(BIT_MASK_CFGX_LO_LOCK_B_L << BIT_SHIFT_CFGX_LO_LOCK_B_L)) + +#define BIT_SHIFT_CFGX_LO_LOCK_CH 16 +#define BIT_MASK_CFGX_LO_LOCK_CH 0x1 +#define BIT_CFGX_LO_LOCK_CH(x)(((x) & BIT_MASK_CFGX_LO_LOCK_CH) << BIT_SHIFT_CFGX_LO_LOCK_CH) +#define BIT_INVC_CFGX_LO_LOCK_CH (~(BIT_MASK_CFGX_LO_LOCK_CH << BIT_SHIFT_CFGX_LO_LOCK_CH)) + +#define BIT_SHIFT_CFGX_LO_LOCK_B 17 +#define BIT_MASK_CFGX_LO_LOCK_B 0x1 +#define BIT_CFGX_LO_LOCK_B(x)(((x) & BIT_MASK_CFGX_LO_LOCK_B) << BIT_SHIFT_CFGX_LO_LOCK_B) +#define BIT_INVC_CFGX_LO_LOCK_B (~(BIT_MASK_CFGX_LO_LOCK_B << BIT_SHIFT_CFGX_LO_LOCK_B)) + +#define BIT_SHIFT_CFGX_LO_DST_HS_POL 18 +#define BIT_MASK_CFGX_LO_DST_HS_POL 0x1 +#define BIT_CFGX_LO_DST_HS_POL(x)(((x) & BIT_MASK_CFGX_LO_DST_HS_POL) << BIT_SHIFT_CFGX_LO_DST_HS_POL) +#define BIT_INVC_CFGX_LO_DST_HS_POL (~(BIT_MASK_CFGX_LO_DST_HS_POL << BIT_SHIFT_CFGX_LO_DST_HS_POL)) + +#define BIT_SHIFT_CFGX_LO_SRC_HS_POL 19 +#define BIT_MASK_CFGX_LO_SRC_HS_POL 0x1 +#define BIT_CFGX_LO_SRC_HS_POL(x)(((x) & BIT_MASK_CFGX_LO_SRC_HS_POL) << BIT_SHIFT_CFGX_LO_SRC_HS_POL) +#define BIT_INVC_CFGX_LO_SRC_HS_POL (~(BIT_MASK_CFGX_LO_SRC_HS_POL << BIT_SHIFT_CFGX_LO_SRC_HS_POL)) + +#define BIT_SHIFT_CFGX_LO_MAX_ABRST 20 +#define BIT_MASK_CFGX_LO_MAX_ABRST 0x3FF +#define BIT_CFGX_LO_MAX_ABRST(x)(((x) & BIT_MASK_CFGX_LO_MAX_ABRST) << BIT_SHIFT_CFGX_LO_MAX_ABRST) +#define BIT_INVC_CFGX_LO_MAX_ABRST (~(BIT_MASK_CFGX_LO_MAX_ABRST << BIT_SHIFT_CFGX_LO_MAX_ABRST)) + +#define BIT_SHIFT_CFGX_LO_RELOAD_SRC 30 +#define BIT_MASK_CFGX_LO_RELOAD_SRC 0x1 +#define BIT_CFGX_LO_RELOAD_SRC(x)(((x) & BIT_MASK_CFGX_LO_RELOAD_SRC) << BIT_SHIFT_CFGX_LO_RELOAD_SRC) +#define BIT_INVC_CFGX_LO_RELOAD_SRC (~(BIT_MASK_CFGX_LO_RELOAD_SRC << BIT_SHIFT_CFGX_LO_RELOAD_SRC)) + +#define BIT_SHIFT_CFGX_LO_RELOAD_DST 31 +#define BIT_MASK_CFGX_LO_RELOAD_DST 0x1 +#define BIT_CFGX_LO_RELOAD_DST(x)(((x) & BIT_MASK_CFGX_LO_RELOAD_DST) << BIT_SHIFT_CFGX_LO_RELOAD_DST) +#define BIT_INVC_CFGX_LO_RELOAD_DST (~(BIT_MASK_CFGX_LO_RELOAD_DST << BIT_SHIFT_CFGX_LO_RELOAD_DST)) + +#define BIT_SHIFT_CFGX_UP_FCMODE 0 +#define BIT_MASK_CFGX_UP_FCMODE 0x1 +#define BIT_CFGX_UP_FCMODE(x)(((x) & BIT_MASK_CFGX_UP_FCMODE) << BIT_SHIFT_CFGX_UP_FCMODE) +#define BIT_INVC_CFGX_UP_FCMODE (~(BIT_MASK_CFGX_UP_FCMODE << BIT_SHIFT_CFGX_UP_FCMODE)) + +#define BIT_SHIFT_CFGX_UP_FIFO_MODE 1 +#define BIT_MASK_CFGX_UP_FIFO_MODE 0x1 +#define BIT_CFGX_UP_FIFO_MODE(x)(((x) & BIT_MASK_CFGX_UP_FIFO_MODE) << BIT_SHIFT_CFGX_UP_FIFO_MODE) +#define BIT_INVC_CFGX_UP_FIFO_MODE (~(BIT_MASK_CFGX_UP_FIFO_MODE << BIT_SHIFT_CFGX_UP_FIFO_MODE)) + +#define BIT_SHIFT_CFGX_UP_PROTCTL 2 +#define BIT_MASK_CFGX_UP_PROTCTL 0x7 +#define BIT_CFGX_UP_PROTCTL(x)(((x) & BIT_MASK_CFGX_UP_PROTCTL) << BIT_SHIFT_CFGX_UP_PROTCTL) +#define BIT_INVC_CFGX_UP_PROTCTL (~(BIT_MASK_CFGX_UP_PROTCTL << BIT_SHIFT_CFGX_UP_PROTCTL)) + +#define BIT_SHIFT_CFGX_UP_DS_UPD_EN 5 +#define BIT_MASK_CFGX_UP_DS_UPD_EN 0x1 +#define BIT_CFGX_UP_DS_UPD_EN(x)(((x) & BIT_MASK_CFGX_UP_DS_UPD_EN) << BIT_SHIFT_CFGX_UP_DS_UPD_EN) +#define BIT_INVC_CFGX_UP_DS_UPD_EN (~(BIT_MASK_CFGX_UP_DS_UPD_EN << BIT_SHIFT_CFGX_UP_DS_UPD_EN)) + +#define BIT_SHIFT_CFGX_UP_SS_UPD_EN 6 +#define BIT_MASK_CFGX_UP_SS_UPD_EN 0x1 +#define BIT_CFGX_UP_SS_UPD_EN(x)(((x) & BIT_MASK_CFGX_UP_SS_UPD_EN) << BIT_SHIFT_CFGX_UP_SS_UPD_EN) +#define BIT_INVC_CFGX_UP_SS_UPD_EN (~(BIT_MASK_CFGX_UP_SS_UPD_EN << BIT_SHIFT_CFGX_UP_SS_UPD_EN)) + +#define BIT_SHIFT_CFGX_UP_SRC_PER 7 +#define BIT_MASK_CFGX_UP_SRC_PER 0xF +#define BIT_CFGX_UP_SRC_PER(x)(((x) & BIT_MASK_CFGX_UP_SRC_PER) << BIT_SHIFT_CFGX_UP_SRC_PER) +#define BIT_INVC_CFGX_UP_SRC_PER (~(BIT_MASK_CFGX_UP_SRC_PER << BIT_SHIFT_CFGX_UP_SRC_PER)) + +#define BIT_SHIFT_CFGX_UP_DEST_PER 11 +#define BIT_MASK_CFGX_UP_DEST_PER 0xF +#define BIT_CFGX_UP_DEST_PER(x)(((x) & BIT_MASK_CFGX_UP_DEST_PER) << BIT_SHIFT_CFGX_UP_DEST_PER) +#define BIT_INVC_CFGX_UP_DEST_PER (~(BIT_MASK_CFGX_UP_DEST_PER << BIT_SHIFT_CFGX_UP_DEST_PER)) + +typedef enum _GDMA_CHANNEL_NUM_ { + GdmaNoCh = 0x0000, + GdmaCh0 = 0x0101, + GdmaCh1 = 0x0202, + GdmaCh2 = 0x0404, + GdmaCh3 = 0x0808, + GdmaCh4 = 0x1010, + GdmaCh5 = 0x2020, + GdmaCh6 = 0x4040, + GdmaCh7 = 0x8080, + GdmaAllCh = 0xffff +}GDMA_CHANNEL_NUM, *PGDMA_CHANNEL_NUM; + + +//3 CTL register struct + +typedef enum _GDMA_CTL_TT_FC_TYPE_ { + TTFCMemToMem = 0x00, + TTFCMemToPeri = 0x01, + TTFCPeriToMem = 0x02 +}GDMA_CTL_TT_FC_TYPE, *PGDMA_CTL_TT_FC_TYPE; + +//Max type = Bus Width +typedef enum _GDMA_CTL_TR_WIDTH_ { + TrWidthOneByte = 0x00, + TrWidthTwoBytes = 0x01, + TrWidthFourBytes = 0x02 +}GDMA_CTL_TR_WIDTH, *PGDMA_CTL_TR_WIDTH; + +typedef enum _GDMA_CTL_MSIZE_ { + MsizeOne = 0x00, + MsizeFour = 0x01, + MsizeEight = 0x02 +}GDMA_CTL_MSIZE, *PGDMA_CTL_MSIZE; + +typedef enum _GDMA_INC_TYPE_ { + IncType = 0x00, + DecType = 0x01, + NoChange = 0x02 +}GDMA_INC_TYPE, *PGDMA_INC_TYPE; + + +typedef struct _GDMA_CTL_REG_ { + GDMA_CTL_TT_FC_TYPE TtFc; + GDMA_CTL_TR_WIDTH DstTrWidth; + GDMA_CTL_TR_WIDTH SrcTrWidth; + GDMA_INC_TYPE Dinc; + GDMA_INC_TYPE Sinc; + GDMA_CTL_MSIZE DestMsize; + GDMA_CTL_MSIZE SrcMsize; + + u8 IntEn :1; // Bit 0 + u8 SrcGatherEn :1; // Bit 1 + u8 DstScatterEn :1; // Bit 2 + u8 LlpDstEn :1; // Bit 3 + u8 LlpSrcEn :1; // Bit 4 + u8 Done :1; // Bit 5 + u8 Rsvd6To7 :2; //Bit 6 -7 + u16 BlockSize; + +}GDMA_CTL_REG, *PGDMA_CTL_REG; + + +//3 CFG Register Structure + +typedef enum _GDMA_CH_PRIORITY_ { + Prior0 = 0, + Prior1 = 1, + Prior2 = 2, + Prior3 = 3, + Prior4 = 4, + Prior5 = 5, + Prior6 = 6, + Prior7 = 7 +}GDMA_CH_PRIORITY, *PGDMA_CH_PRIORITY; + +typedef enum _GDMA_LOCK_LEVEL_ { + OverComplDmaTransfer = 0x00, + OverComplDmaBlockTransfer = 0x01, + OverComplDmaTransation = 0x02 +}GDMA_LOCK_LEVEL, *PGDMA_LOCK_LEVEL; + + +typedef struct _GDMA_CFG_REG_ { + GDMA_CH_PRIORITY ChPrior; + GDMA_LOCK_LEVEL LockBL; + GDMA_LOCK_LEVEL LockChL; + u16 MaxAbrst; + u8 SrcPer; + u8 DestPer; + u16 ChSusp :1; //Bit 0 + u16 FifoEmpty :1; //Bit 1 + u16 HsSelDst :1; //Bit 2 + u16 HsSelSrc :1; //Bit 3 + u16 LockCh :1; //Bit 4 + u16 LockB :1; //Bit 5 + u16 DstHsPol :1; //Bit 6 + u16 SrcHsPol :1; //Bit 7 + u16 ReloadSrc :1; //Bit 8 + u16 ReloadDst :1; //Bit 9 + u16 FifoMode :1; //Bit 10 + u16 DsUpdEn :1; //Bit 11 + u16 SsUpdEn :1; //Bit 12 + u16 Rsvd13To15 :3; +}GDMA_CFG_REG, *PGDMA_CFG_REG; + +typedef enum _GDMA_ISR_TYPE_ { + TransferType = 0x1, + BlockType = 0x2, + SrcTransferType = 0x4, + DstTransferType = 0x8, + ErrType = 0x10 +}GDMA_ISR_TYPE, *PGDMA_ISR_TYPE; + + +VOID +HalGdmaOnOffRtl8195a ( + IN VOID *Data +); + +BOOL +HalGdamChInitRtl8195a( + IN VOID *Data +); + +BOOL +HalGdmaChSetingRtl8195a( + IN VOID *Data +); + +BOOL +HalGdmaChBlockSetingRtl8195a( + IN VOID *Data +); + +BOOL +HalGdmaChBlockSetingRtl8195a_Patch( + IN VOID *Data +); + +VOID +HalGdmaChDisRtl8195a ( + IN VOID *Data +); + +VOID +HalGdmaChEnRtl8195a ( + IN VOID *Data +); + +VOID +HalGdmaChIsrEnAndDisRtl8195a ( + IN VOID *Data +); + +u8 +HalGdmaChIsrCleanRtl8195a ( + IN VOID *Data +); + +VOID +HalGdmaChCleanAutoSrcRtl8195a ( + IN VOID *Data +); + +VOID +HalGdmaChCleanAutoDstRtl8195a ( + IN VOID *Data +); + +u32 +HalGdmaQueryDArRtl8195a( + IN VOID *Data +); + +u32 +HalGdmaQuerySArRtl8195a( + IN VOID *Data +); + +BOOL +HalGdmaQueryChEnRtl8195a ( + IN VOID *Data +); + +#ifdef CONFIG_CHIP_E_CUT +_LONG_CALL_ BOOL +HalGdmaChBlockSetingRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ u32 +HalGdmaQueryDArRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ u32 +HalGdmaQuerySArRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ BOOL +HalGdmaQueryChEnRtl8195a_V04 ( + IN VOID *Data +); + +#endif // #ifdef CONFIG_CHIP_E_CUT + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gpio.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gpio.h new file mode 100644 index 0000000..30f25fa --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gpio.h @@ -0,0 +1,398 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_GPIO_H_ +#define _RTL8195A_GPIO_H_ + +#include "hal_api.h" +#include "hal_gpio.h" + +#define GPIO_PORTA_DR 0x00 // data register +#define GPIO_PORTA_DDR 0x04 // data direction +#define GPIO_PORTA_CTRL 0x08 // data source control, we should keep it as default: data source from software + +#define GPIO_PORTB_DR 0x0c // data register +#define GPIO_PORTB_DDR 0x10 // data direction +#define GPIO_PORTB_CTRL 0x14 // data source control, we should keep it as default: data source from software + +#define GPIO_PORTC_DR 0x18 // data register +#define GPIO_PORTC_DDR 0x1c // data direction +#define GPIO_PORTC_CTRL 0x20 // data source control, we should keep it as default: data source from software + +//1 Only the PORTA can be configured to generate interrupts +#define GPIO_INT_EN 0x30 // Interrupt enable register +#define GPIO_INT_MASK 0x34 // Interrupt mask +#define GPIO_INT_TYPE 0x38 // Interrupt type(level/edge) register +#define GPIO_INT_POLARITY 0x3C // Interrupt polarity(Active low/high) register +#define GPIO_INT_STATUS 0x40 // Interrupt status +#define GPIO_INT_RAWSTATUS 0x44 // Interrupt status without mask +#define GPIO_DEBOUNCE 0x48 // Interrupt signal debounce +#define GPIO_PORTA_EOI 0x4c // Clear interrupt + +#define GPIO_EXT_PORTA 0x50 // GPIO IN read or OUT read back +#define GPIO_EXT_PORTB 0x54 // GPIO IN read or OUT read back +#define GPIO_EXT_PORTC 0x58 // GPIO IN read or OUT read back + +#define GPIO_INT_SYNC 0x60 // Is level-sensitive interrupt being sync sith PCLK + +enum { + HAL_GPIO_HIGHZ = 0, + HAL_GPIO_PULL_LOW = 1, + HAL_GPIO_PULL_HIGH = 2 +}; + +typedef enum +{ + GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */ + GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */ + GPIO_Mode_INT = 0x02, /*!< GPIO Interrupt Mode */ + GPIO_Mode_MAX = 0x03, +}GPIOMode_TypeDef; + +/** + * @brief GPIO Configuration PullUp PullDown enumeration + */ +typedef enum +{ + GPIO_PuPd_NOPULL = 0x00, /*!< GPIO Interrnal HIGHZ */ + GPIO_PuPd_DOWN = 0x01, /*!< GPIO Interrnal Pull DOWN */ + GPIO_PuPd_UP = 0x02, /*!< GPIO Interrnal Pull UP */ +}GPIOPuPd_TypeDef; + +/** + * @brief Setting interrupt's trigger type + * + * Setting interrupt's trigger type + */ +typedef enum +{ + GPIO_INT_Trigger_LEVEL = 0x0, /**< This interrupt is level trigger */ + GPIO_INT_Trigger_EDGE = 0x1, /**< This interrupt is edge trigger */ +}GPIOIT_LevelType; + +/** + * @brief Setting interrupt active mode + * + * Setting interrupt active mode + */ +typedef enum +{ + GPIO_INT_POLARITY_ACTIVE_LOW = 0x0, /**< Setting interrupt to low active: falling edge or low level */ + GPIO_INT_POLARITY_ACTIVE_HIGH = 0x1, /**< Setting interrupt to high active: rising edge or high level */ +}GPIOIT_PolarityType; + +/** + * @brief Enable/Disable interrupt debounce mode + * + * Enable/Disable interrupt debounce mode + */ +typedef enum +{ + GPIO_INT_DEBOUNCE_DISABLE = 0x0, /**< Disable interrupt debounce */ + GPIO_INT_DEBOUNCE_ENABLE = 0x1, /**< Enable interrupt debounce */ +}GPIOIT_DebounceType; + + +typedef struct { + GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins. */ + GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins. */ + GPIOIT_LevelType GPIO_ITTrigger; /**< Interrupt mode is level or edge trigger */ + GPIOIT_PolarityType GPIO_ITPolarity; /**< Interrupt mode is high or low active trigger */ + GPIOIT_DebounceType GPIO_ITDebounce; /**< Enable or disable de-bounce for interrupt */ + u32 GPIO_Pin; // Pin: [7:5]: port number, [4:0]: pin number +}GPIO_InitTypeDef; + +//====================================================== +// ROM Function prototype +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; +#ifndef CONFIG_RELEASE_BUILD_LIBRARIES +static __inline HAL_Status +GPIO_Lock ( + VOID +) +{ + HAL_Status Status; + + if (_pHAL_Gpio_Adapter->EnterCritical) { + _pHAL_Gpio_Adapter->EnterCritical(); + } + + if(_pHAL_Gpio_Adapter->Locked) { + Status = HAL_BUSY; + } + else { + _pHAL_Gpio_Adapter->Locked = 1; + Status = HAL_OK; + } + + if (_pHAL_Gpio_Adapter->ExitCritical) { + _pHAL_Gpio_Adapter->ExitCritical(); + } + + return Status; +} + + +static __inline VOID +GPIO_UnLock ( + VOID +) +{ + if (_pHAL_Gpio_Adapter->EnterCritical) { + _pHAL_Gpio_Adapter->EnterCritical(); + } + + _pHAL_Gpio_Adapter->Locked = 0; + + if (_pHAL_Gpio_Adapter->ExitCritical) { + _pHAL_Gpio_Adapter->ExitCritical(); + } +} +#endif // #ifndef CONFIG_RELEASE_BUILD_LIBRARIES + +_LONG_CALL_ extern u32 +HAL_GPIO_IrqHandler_8195a( + IN VOID *pData +); + +_LONG_CALL_ extern u32 +HAL_GPIO_MbedIrqHandler_8195a( + IN VOID *pData +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_IntCtrl_8195a( + HAL_GPIO_PIN *GPIO_Pin, + u32 En +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_Init_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_DeInit_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_GPIO_PIN_STATE +HAL_GPIO_ReadPin_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_WritePin_8195a( + HAL_GPIO_PIN *GPIO_Pin, + HAL_GPIO_PIN_STATE Pin_State +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_RegIrq_8195a( + IN PIRQ_HANDLE pIrqHandle +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_UnRegIrq_8195a( + IN PIRQ_HANDLE pIrqHandle +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_UserRegIrq_8195a( + HAL_GPIO_PIN *GPIO_Pin, + VOID *IrqHandler, + VOID *IrqData +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_UserUnRegIrq_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_MaskIrq_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_UnMaskIrq_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_IntDebounce_8195a( + HAL_GPIO_PIN *GPIO_Pin, + u8 Enable +); + +_LONG_CALL_ u32 +HAL_GPIO_GetIPPinName_8195a( + u32 chip_pin +); + +_LONG_CALL_ HAL_Status +HAL_GPIO_PullCtrl_8195a( + u32 chip_pin, + u8 pull_type +); + +_LONG_CALL_ u32 +GPIO_GetChipPinName_8195a( + u32 port, + u32 pin +); + +_LONG_CALL_ VOID +GPIO_PullCtrl_8195a( + u32 chip_pin, + u8 pull_type +); + +_LONG_CALL_ VOID +GPIO_Int_SetType_8195a( + u8 pin_num, + u8 int_mode +); + + +_LONG_CALL_ HAL_Status HAL_GPIO_IntCtrl_8195aV02(HAL_GPIO_PIN *GPIO_Pin, u32 En); +_LONG_CALL_ u32 GPIO_Int_Clear_8195aV02(u32 irq_clr); + +HAL_Status +HAL_GPIO_ClearISR_8195a( + HAL_GPIO_PIN *GPIO_Pin +); + + +/********** HAL In-Line Functions **********/ + +/** + * @brief Reads the specified input port pin. + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval The input port pin current status(High or Low). + */ +static __inline s32 +HAL_GPIO_ReadPin( + HAL_GPIO_PIN *GPIO_Pin +) +{ + return (s32)HAL_GPIO_ReadPin_8195a(GPIO_Pin); +} + +/** + * @brief Write the specified output port pin. + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @param Pin_State: The state going to be set to the assigned GPIO pin. + * + * @retval None + */ +static __inline VOID +HAL_GPIO_WritePin( + HAL_GPIO_PIN *GPIO_Pin, + u32 Value +) +{ + HAL_GPIO_WritePin_8195a(GPIO_Pin, (HAL_GPIO_PIN_STATE)Value); +} + +/** + * @brief To register a user interrupt handler for a specified pin + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @param IrqHandler: The IRQ handler to be assigned to the specified pin + * + * @param IrqData: The pointer will be pass the the IRQ handler + * + * @retval None + */ +static __inline VOID +HAL_GPIO_UserRegIrq( + HAL_GPIO_PIN *GPIO_Pin, + VOID *IrqHandler, + VOID *IrqData +) +{ + HAL_GPIO_UserRegIrq_8195a(GPIO_Pin, IrqHandler, IrqData); +} + +/** + * @brief To un-register a user interrupt handler for a specified pin + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval None + */ +static __inline VOID +HAL_GPIO_UserUnRegIrq( + HAL_GPIO_PIN *GPIO_Pin +) +{ + HAL_GPIO_UserUnRegIrq_8195a(GPIO_Pin); +} + + +/** + * @brief Enable/Disable GPIO interrupt + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin initialization. + * + * @param En: Enable (1) or Disable (0) + * + * @retval HAL_Status + */ +static __inline VOID +HAL_GPIO_IntCtrl( + HAL_GPIO_PIN *GPIO_Pin, + u32 En +) +{ + HAL_GPIO_IntCtrl_8195a(GPIO_Pin, En); +} + +/** + * @brief Mask the interrupt of a specified pin + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval None + */ +static __inline VOID +HAL_GPIO_MaskIrq( + HAL_GPIO_PIN *GPIO_Pin +) +{ + HAL_GPIO_MaskIrq_8195a(GPIO_Pin); +} + + +/** + * @brief UnMask the interrupt of a specified pin + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval None + */ +static __inline VOID +HAL_GPIO_UnMaskIrq( + HAL_GPIO_PIN *GPIO_Pin +) +{ + HAL_GPIO_ClearISR_8195a(GPIO_Pin); + HAL_GPIO_UnMaskIrq_8195a(GPIO_Pin); +} + + +#endif // end of "#define _RTL8195A_GPIO_H_" + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gspi.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gspi.h new file mode 100644 index 0000000..a76db49 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_gspi.h @@ -0,0 +1,404 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + *******************************************************************************/ + +#ifndef __RTL8195A_GSPI_H__ +#define __RTL8195A_GSPI_H__ + +#define SPI_LOCAL_DOMAIN 0x0 +#define SPI_TXFIFO_DOMAIN 0xc +#define SPI_RXFIFO_DOMAIN 0x1f + +//IO Bus domain address mapping +#define DEFUALT_OFFSET 0x0 +#define SPI_LOCAL_OFFSET 0x10250000 +#define SPI_TX_FIFO_OFFSET 0x10310000 +#define SPI_RX_FIFO_OFFSET 0x10340000 + +#define SPI_LOCAL_DEVICE_ID 0 +#define SPI_TXQ_FIFO_DEVICE_ID 3 +#define SPI_RXQ_FIFO_DEVICE_ID 7 +#define SPI_UNDEFINED_DEVICE_ID (-1) + + +//SPI Local registers +#define SPI_REG_INT_CTRL 0x0004 // 4 bytes, SPI INT Control +#define SPI_REG_INT_TIMEOUT 0x0006 // 2 bytes, SPI 32us INT timout +#define SPI_REG_HIMR 0x0014 // 4 bytes, SPI Host Interrupt Mask +#define SPI_REG_HISR 0x0018 // 4 bytes, SPI Host Interrupt Service Routine +#define SPI_REG_RX0_REQ_LEN 0x001C // 4 bytes, RXDMA Request Length +#define SPI_REG_FREE_TX_SPACE 0x0020 // 4 bytes, Free Tx Buffer Page +#define SPI_REG_TX_SEQNUM 0x0024 // 1 byte, TX Sequence Number Definition +#define SPI_REG_HCPWM 0x0038 // 1 byte, HCI Current Power Mode +#define SPI_REG_HCPWM2 0x003A // 2 bytes, HCI Current Power Mode 2 +#define SPI_REG_AVAI_PATH_L 0x0040 // 4 bytes, SPI TX Available Low Size reg +#define SPI_REG_AVAI_PATH_H 0x0044 // 4 bytes, SPI TX Available High Size reg +#define SPI_REG_RX_AGG_CTL 0x0048 // 4 bytes, SPI RX AGG control +#define SPI_REG_H2C_MSG 0x004C // 4 bytes, SPI_REG_H2C_MSG +#define SPI_REG_C2H_MSG 0x0050 // 4 bytes, SPI_REG_C2H_MSG +#define SPI_REG_HRPWM 0x0080 // 1 byte, SPI_REG_HRPWM +#define SPI_REG_HPS_CLKR 0x0084 // 1 byte, not uesd +#define SPI_REG_CPU_IND 0x0087 // 1 byte, firmware indication to host +#define SPI_REG_32K_TRANS_CTL 0x0088 // 1 byte, 32K transparent control, BIT0 EN32K_TRANS +#define SPI_REG_32K_IDLE_TIME 0x008B // 1 byte, 32K idle time, +#define SPI_REG_DELY_LINE_SEL 0x008C // 1 byte, Delay line selection, +#define SPI_REG_SPI_CFG 0x00F0 // 1 byte, SPI configuration, + +#define LOCAL_REG_FREE_TX_SPACE (SPI_LOCAL_OFFSET | SPI_REG_FREE_TX_SPACE) + +// Register SPI_REG_CPU_IND +#define SPI_CPU_RDY_IND (BIT0) + + +/************************************************/ +// SPI_REG_HISR: SDIO Host Interrupt Service Routine +#define SPI_HISR_RX_REQUEST (BIT0) +#define SPI_HISR_AVAL_INT (BIT1) +#define SPI_HISR_TXPKT_OVER_BUFF (BIT2) +#define SPI_HISR_TX_AGG_SIZE_MISMATCH (BIT3) +#define SPI_HISR_TXBD_OVF (BIT4) +//BIT5~16 not used +#define SPI_HISR_C2H_MSG_INT (BIT17) +#define SPI_HISR_CPWM1_INT (BIT18) +#define SPI_HISR_CPWM2_INT (BIT19) +//BIT20~31 not used +#define SPI_HISR_CPU_NOT_RDY (BIT22) + + +#define MASK_SPI_HISR_CLEAR (SPI_HISR_RX_REQUEST |\ + SPI_HISR_AVAL_INT |\ + SPI_HISR_TXPKT_OVER_BUFF |\ + SPI_HISR_TX_AGG_SIZE_MISMATCH |\ + SPI_HISR_TXBD_OVF |\ + SPI_HISR_C2H_MSG_INT |\ + SPI_HISR_CPWM1_INT |\ + SPI_HISR_CPWM2_INT) + +// RTL8195A SPI Host Interrupt Mask Register +#define SPI_HIMR_RX_REQUEST_MSK (BIT0) +#define SPI_HIMR_AVAL_MSK (BIT1) +#define SPI_HIMR_TXPKT_SIZE_OVER_BUFF_MSK (BIT2) +#define SPI_HIMR_AGG_SIZE_MISMATCH_MSK (BIT3) +#define SPI_HIMR_TXBD_OVF_MSK (BIT4) +//BIT5~16 not used +#define SPI_HIMR_C2H_MSG_INT_MSK (BIT17) +#define SPI_HIMR_CPWM1_INT_MSK (BIT18) +#define SPI_HIMR_CPWM2_INT_MSK (BIT19) +//BIT20~31 not used +#define SPI_HIMR_DISABLED 0 + +// Register SPI_REG_HCPWM +#define SPI_HCPWM_WLAN_TRX (BIT1) + + +enum{ + SPI_LITTLE_ENDIAN = 2, + SPI_BIG_ENDIAN = 0 +}; +enum{ + SPI_WORD_LEN_16 = 0, + SPI_WORD_LEN_32 = 1 +}; + +typedef enum{ + SPI_LITTLE_ENDIAN_16 = SPI_LITTLE_ENDIAN|SPI_WORD_LEN_16, + SPI_LITTLE_ENDIAN_32 = SPI_LITTLE_ENDIAN|SPI_WORD_LEN_32, // default configure + SPI_BIG_ENDIAN_16 = SPI_BIG_ENDIAN|SPI_WORD_LEN_16, + SPI_BIG_ENDIAN_32 = SPI_BIG_ENDIAN|SPI_WORD_LEN_32 +}_gspi_conf_t; + +#define GSPI_CMD_LEN 4 +#define GSPI_STATUS_LEN 8 + + +#define FILL_SPI_CMD(byte_en, addr, domain_id, fun, write_flag) ((byte_en & 0xff) | ((addr & 0xffff) << 8) \ + | ((domain_id & 0x1f) << 24) | ((fun & 0x3) << 29) | ((write_flag & 0x1) << 31)) + + +#define GET_STATUS_HISR(status) ((((*(u32*)status)) & 0x3) |((((*(u32*)status) >> 2) & 0x7) << 17)) +#define GET_STATUS_FREE_TX(status) ((((*(u32*)status) >> 5) & 0x7ffffff) << 2) +#define GET_STATUS_RXQ_REQ_LEN(status) (((*(u32*)((u8 *)status + 4))) & 0xffffff) +#define GET_STATUS_TX_SEQ(status) (((*(u32*)((u8 *)status + 4)) >> 24) & 0xff) + +#define GSPI_CMD_TX 0x83 // +#define GSPI_CMD_RX 0X82 + +// define transmit packat type +#define GPSI_TX_PACKET_802_3 (0x83) +#define GSPI_TX_PACKET_802_11 (0x81) +#define GSPI_TX_H2C_CMD (0x11) +#define GSPI_TX_MEM_READ (0x51) +#define GSPI_TX_MEM_WRITE (0x53) +#define GSPI_TX_MEM_SET (0x55) +#define GSPI_TX_FM_FREETOGO (0x61) + +//define receive packet type +#define GSPI_RX_PACKET_802_3 (0x82) +#define GSPI_RX_PACKET_802_11 (0x80) +#define GSPI_RX_C2H_CMD (0x10) +#define GSPI_RX_MEM_READ (0x50) +#define GSPI_RX_MEM_WRITE (0x52) +#define GSPI_RX_MEM_SET (0x54) +#define GSPI_RX_FM_FREETOGO (0x60) + + +typedef struct _GSPI_TX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 rsvd1; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} GSPI_TX_DESC, *PGSPI_TX_DESC; + +typedef struct _GSPI_RX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:6; // bit[29:24] + u32 icv:1; // bit[30], ICV error + u32 crc:1; // bit[31], CRC error +#else + u32 crc:1; // bit[31], CRC error + u32 icv:1; // bit[30], ICV error + u32 rsvd0:6; // bit[29:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 rsvd2; + + // u4Byte 3 + u32 rsvd3; + + // u4Byte 4 + u32 rsvd4; + + // u4Byte 5 + u32 rsvd5; +} GSPI_RX_DESC, *PGSPI_RX_DESC; + +#define SIZE_TX_DESC (sizeof(GSPI_TX_DESC)) +#define SIZE_RX_DESC (sizeof(GSPI_RX_DESC)) + +// For memory read command +typedef struct _GSPI_DESC_MR{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} GSPI_DESC_MR, *PGSPI_DESC_MR; + +// For memory write reply command +typedef struct _GSPI_DESC_MW{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 reply:1; // bit[8], request to send a reply message + u32 rsvd0:23; +#else + u32 rsvd0:23; + u32 reply:1; // bit[8], request to send a reply message + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} GSPI_DESC_MW, *PGSPI_DESC_MW; + +// For memory set command +typedef struct _GSPI_DESC_MS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 data:8; // bit[8:15], the value to be written to the memory + u32 reply:1; // bit[16], request to send a reply message + u32 rsvd0:15; +#else + u32 rsvd0:15; + u32 reply:1; // bit[16], request to send a reply message + u32 data:8; // bit[8:15], the value to be written to the memory + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} GSPI_DESC_MS, *PGSPI_DESC_MS; +// TX Desc for Jump to Start command +typedef struct _GSPI_DESC_JS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_fun; // the pointer of the startup function + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} GSPI_DESC_JS, *PGSPI_DESC_JS; + + +// CCPWM2 bit map definition for Firmware download +#define GSPI_INIT_DONE (BIT0) +#define GSPI_MEM_WR_DONE (BIT1) +#define GSPI_MEM_RD_DONE (BIT2) +#define GSPI_MEM_ST_DONE (BIT3) +#define GSPI_CPWM2_TOGGLE (BIT15) + +// Register REG_SPDIO_CPU_IND +#define GPSI_SYSTEM_TRX_RDY_IND (BIT0) + +#endif //__GSPI_REG_H__ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2c.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2c.h new file mode 100644 index 0000000..bf6190f --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2c.h @@ -0,0 +1,860 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_I2C_H_ +#define _RTL8195A_I2C_H_ + +#include "hal_api.h" + +//================ Register Bit Field ================== +//2 REG_DW_I2C_IC_CON +#define BIT_IC_CON_IC_SLAVE_DISABLE BIT(6) +#define BIT_SHIFT_IC_CON_IC_SLAVE_DISABLE 6 +#define BIT_MASK_IC_CON_IC_SLAVE_DISABLE 0x1 +#define BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(x) (((x) & BIT_MASK_IC_CON_IC_SLAVE_DISABLE) << BIT_SHIFT_IC_CON_IC_SLAVE_DISABLE) + +#define BIT_IC_CON_IC_RESTART_EN BIT(5) +#define BIT_SHIFT_IC_CON_IC_RESTART_EN 5 +#define BIT_MASK_IC_CON_IC_RESTART_EN 0x1 +#define BIT_CTRL_IC_CON_IC_RESTART_EN(x) (((x) & BIT_MASK_IC_CON_IC_RESTART_EN) << BIT_SHIFT_IC_CON_IC_RESTART_EN) + +#define BIT_IC_CON_IC_10BITADDR_MASTER BIT(4) +#define BIT_SHIFT_IC_CON_IC_10BITADDR_MASTER 4 +#define BIT_MASK_IC_CON_IC_10BITADDR_MASTER 0x1 +#define BIT_CTRL_IC_CON_IC_10BITADDR_MASTER(x) (((x) & BIT_MASK_IC_CON_IC_10BITADDR_MASTER) << BIT_SHIFT_IC_CON_IC_10BITADDR_MASTER) + +#define BIT_IC_CON_IC_10BITADDR_SLAVE BIT(3) +#define BIT_SHIFT_IC_CON_IC_10BITADDR_SLAVE 3 +#define BIT_MASK_IC_CON_IC_10BITADDR_SLAVE 0x1 +#define BIT_CTRL_IC_CON_IC_10BITADDR_SLAVE(x) (((x) & BIT_MASK_IC_CON_IC_10BITADDR_SLAVE) << BIT_SHIFT_IC_CON_IC_10BITADDR_SLAVE) + + +#define BIT_SHIFT_IC_CON_SPEED 1 +#define BIT_MASK_IC_CON_SPEED 0x3 +#define BIT_IC_CON_SPEED(x) (((x) & BIT_MASK_IC_CON_SPEED) << BIT_SHIFT_IC_CON_SPEED) +#define BIT_CTRL_IC_CON_SPEED(x) (((x) & BIT_MASK_IC_CON_SPEED) << BIT_SHIFT_IC_CON_SPEED) +#define BIT_GET_IC_CON_SPEED(x) (((x) >> BIT_SHIFT_IC_CON_SPEED) & BIT_MASK_IC_CON_SPEED) + +#define BIT_IC_CON_MASTER_MODE BIT(0) +#define BIT_SHIFT_IC_CON_MASTER_MODE 0 +#define BIT_MASK_IC_CON_MASTER_MODE 0x1 +#define BIT_CTRL_IC_CON_MASTER_MODE(x) (((x) & BIT_MASK_IC_CON_MASTER_MODE) << BIT_SHIFT_IC_CON_MASTER_MODE) + + +//2 REG_DW_I2C_IC_TAR +#define BIT_IC_TAR_IC_10BITADDR_MASTER BIT(12) +#define BIT_SHIFT_IC_TAR_IC_10BITADDR_MASTER 12 +#define BIT_MASK_IC_TAR_IC_10BITADDR_MASTER 0x1 +#define BIT_CTRL_IC_TAR_IC_10BITADDR_MASTER(x) (((x) & BIT_MASK_IC_TAR_IC_10BITADDR_MASTER) << BIT_SHIFT_IC_TAR_IC_10BITADDR_MASTER) + +#define BIT_IC_TAR_SPECIAL BIT(11) +#define BIT_SHIFT_IC_TAR_SPECIAL 11 +#define BIT_MASK_IC_TAR_SPECIAL 0x1 +#define BIT_CTRL_IC_TAR_SPECIAL(x) (((x) & BIT_MASK_IC_TAR_SPECIAL) << BIT_SHIFT_IC_TAR_SPECIAL) + +#define BIT_IC_TAR_GC_OR_START BIT(10) +#define BIT_SHIFT_IC_TAR_GC_OR_START 10 +#define BIT_MASK_IC_TAR_GC_OR_START 0x1 +#define BIT_CTRL_IC_TAR_GC_OR_START(x) (((x) & BIT_MASK_IC_TAR_GC_OR_START) << BIT_SHIFT_IC_TAR_GC_OR_START) + + +#define BIT_SHIFT_IC_TAR 0 +#define BIT_MASK_IC_TAR 0x3ff +#define BIT_IC_TAR(x) (((x) & BIT_MASK_IC_TAR) << BIT_SHIFT_IC_TAR) +#define BIT_CTRL_IC_TAR(x) (((x) & BIT_MASK_IC_TAR) << BIT_SHIFT_IC_TAR) +#define BIT_GET_IC_TAR(x) (((x) >> BIT_SHIFT_IC_TAR) & BIT_MASK_IC_TAR) + + +//2 REG_DW_I2C_IC_SAR + +#define BIT_SHIFT_IC_SAR 0 +#define BIT_MASK_IC_SAR 0x3ff +#define BIT_IC_SAR(x) (((x) & BIT_MASK_IC_SAR) << BIT_SHIFT_IC_SAR) +#define BIT_CTRL_IC_SAR(x) (((x) & BIT_MASK_IC_SAR) << BIT_SHIFT_IC_SAR) +#define BIT_GET_IC_SAR(x) (((x) >> BIT_SHIFT_IC_SAR) & BIT_MASK_IC_SAR) + + +//2 REG_DW_I2C_IC_HS_MADDR + +#define BIT_SHIFT_IC_HS_MADDR 0 +#define BIT_MASK_IC_HS_MADDR 0x7 +#define BIT_IC_HS_MADDR(x) (((x) & BIT_MASK_IC_HS_MADDR) << BIT_SHIFT_IC_HS_MADDR) +#define BIT_CTRL_IC_HS_MADDR(x) (((x) & BIT_MASK_IC_HS_MADDR) << BIT_SHIFT_IC_HS_MADDR) +#define BIT_GET_IC_HS_MADDR(x) (((x) >> BIT_SHIFT_IC_HS_MADDR) & BIT_MASK_IC_HS_MADDR) + + +//2 REG_DW_I2C_IC_DATA_CMD +#define BIT_IC_DATA_CMD_RESTART BIT(10) +#define BIT_SHIFT_IC_DATA_CMD_RESTART 10 +#define BIT_MASK_IC_DATA_CMD_RESTART 0x1 +#define BIT_CTRL_IC_DATA_CMD_RESTART(x) (((x) & BIT_MASK_IC_DATA_CMD_RESTART) << BIT_SHIFT_IC_DATA_CMD_RESTART) + +#define BIT_IC_DATA_CMD_STOP BIT(9) +#define BIT_SHIFT_IC_DATA_CMD_STOP 9 +#define BIT_MASK_IC_DATA_CMD_STOP 0x1 +#define BIT_CTRL_IC_DATA_CMD_STOP(x) (((x) & BIT_MASK_IC_DATA_CMD_STOP) << BIT_SHIFT_IC_DATA_CMD_STOP) + +#define BIT_IC_DATA_CMD_CMD BIT(8) +#define BIT_SHIFT_IC_DATA_CMD_CMD 8 +#define BIT_MASK_IC_DATA_CMD_CMD 0x1 +#define BIT_CTRL_IC_DATA_CMD_CMD(x) (((x) & BIT_MASK_IC_DATA_CMD_CMD) << BIT_SHIFT_IC_DATA_CMD_CMD) + + +#define BIT_SHIFT_IC_DATA_CMD_DAT 0 +#define BIT_MASK_IC_DATA_CMD_DAT 0xff +#define BIT_IC_DATA_CMD_DAT(x) (((x) & BIT_MASK_IC_DATA_CMD_DAT) << BIT_SHIFT_IC_DATA_CMD_DAT) +#define BIT_CTRL_IC_DATA_CMD_DAT(x) (((x) & BIT_MASK_IC_DATA_CMD_DAT) << BIT_SHIFT_IC_DATA_CMD_DAT) +#define BIT_GET_IC_DATA_CMD_DAT(x) (((x) >> BIT_SHIFT_IC_DATA_CMD_DAT) & BIT_MASK_IC_DATA_CMD_DAT) + + +//2 REG_DW_I2C_IC_SS_SCL_HCNT + +#define BIT_SHIFT_IC_SS_SCL_HCNT 0 +#define BIT_MASK_IC_SS_SCL_HCNT 0xffff +#define BIT_IC_SS_SCL_HCNT(x) (((x) & BIT_MASK_IC_SS_SCL_HCNT) << BIT_SHIFT_IC_SS_SCL_HCNT) +#define BIT_CTRL_IC_SS_SCL_HCNT(x) (((x) & BIT_MASK_IC_SS_SCL_HCNT) << BIT_SHIFT_IC_SS_SCL_HCNT) +#define BIT_GET_IC_SS_SCL_HCNT(x) (((x) >> BIT_SHIFT_IC_SS_SCL_HCNT) & BIT_MASK_IC_SS_SCL_HCNT) + + +//2 REG_DW_I2C_IC_SS_SCL_LCNT + +#define BIT_SHIFT_IC_SS_SCL_LCNT 0 +#define BIT_MASK_IC_SS_SCL_LCNT 0xffff +#define BIT_IC_SS_SCL_LCNT(x) (((x) & BIT_MASK_IC_SS_SCL_LCNT) << BIT_SHIFT_IC_SS_SCL_LCNT) +#define BIT_CTRL_IC_SS_SCL_LCNT(x) (((x) & BIT_MASK_IC_SS_SCL_LCNT) << BIT_SHIFT_IC_SS_SCL_LCNT) +#define BIT_GET_IC_SS_SCL_LCNT(x) (((x) >> BIT_SHIFT_IC_SS_SCL_LCNT) & BIT_MASK_IC_SS_SCL_LCNT) + + +//2 REG_DW_I2C_IC_FS_SCL_HCNT + +#define BIT_SHIFT_IC_FS_SCL_HCNT 0 +#define BIT_MASK_IC_FS_SCL_HCNT 0xffff +#define BIT_IC_FS_SCL_HCNT(x) (((x) & BIT_MASK_IC_FS_SCL_HCNT) << BIT_SHIFT_IC_FS_SCL_HCNT) +#define BIT_CTRL_IC_FS_SCL_HCNT(x) (((x) & BIT_MASK_IC_FS_SCL_HCNT) << BIT_SHIFT_IC_FS_SCL_HCNT) +#define BIT_GET_IC_FS_SCL_HCNT(x) (((x) >> BIT_SHIFT_IC_FS_SCL_HCNT) & BIT_MASK_IC_FS_SCL_HCNT) + + +//2 REG_DW_I2C_IC_FS_SCL_LCNT + +#define BIT_SHIFT_IC_FS_SCL_LCNT 0 +#define BIT_MASK_IC_FS_SCL_LCNT 0xffff +#define BIT_IC_FS_SCL_LCNT(x) (((x) & BIT_MASK_IC_FS_SCL_LCNT) << BIT_SHIFT_IC_FS_SCL_LCNT) +#define BIT_CTRL_IC_FS_SCL_LCNT(x) (((x) & BIT_MASK_IC_FS_SCL_LCNT) << BIT_SHIFT_IC_FS_SCL_LCNT) +#define BIT_GET_IC_FS_SCL_LCNT(x) (((x) >> BIT_SHIFT_IC_FS_SCL_LCNT) & BIT_MASK_IC_FS_SCL_LCNT) + + +//2 REG_DW_I2C_IC_HS_SCL_HCNT + +#define BIT_SHIFT_IC_HS_SCL_HCNT 0 +#define BIT_MASK_IC_HS_SCL_HCNT 0xffff +#define BIT_IC_HS_SCL_HCNT(x) (((x) & BIT_MASK_IC_HS_SCL_HCNT) << BIT_SHIFT_IC_HS_SCL_HCNT) +#define BIT_CTRL_IC_HS_SCL_HCNT(x) (((x) & BIT_MASK_IC_HS_SCL_HCNT) << BIT_SHIFT_IC_HS_SCL_HCNT) +#define BIT_GET_IC_HS_SCL_HCNT(x) (((x) >> BIT_SHIFT_IC_HS_SCL_HCNT) & BIT_MASK_IC_HS_SCL_HCNT) + + +//2 REG_DW_I2C_IC_HS_SCL_LCNT + +#define BIT_SHIFT_IC_HS_SCL_LCNT 0 +#define BIT_MASK_IC_HS_SCL_LCNT 0xffff +#define BIT_IC_HS_SCL_LCNT(x) (((x) & BIT_MASK_IC_HS_SCL_LCNT) << BIT_SHIFT_IC_HS_SCL_LCNT) +#define BIT_CTRL_IC_HS_SCL_LCNT(x) (((x) & BIT_MASK_IC_HS_SCL_LCNT) << BIT_SHIFT_IC_HS_SCL_LCNT) +#define BIT_GET_IC_HS_SCL_LCNT(x) (((x) >> BIT_SHIFT_IC_HS_SCL_LCNT) & BIT_MASK_IC_HS_SCL_LCNT) + + +//2 REG_DW_I2C_IC_INTR_STAT +#define BIT_IC_INTR_STAT_R_GEN_CALL BIT(11) +#define BIT_SHIFT_IC_INTR_STAT_R_GEN_CALL 11 +#define BIT_MASK_IC_INTR_STAT_R_GEN_CALL 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_GEN_CALL(x) (((x) & BIT_MASK_IC_INTR_STAT_R_GEN_CALL) << BIT_SHIFT_IC_INTR_STAT_R_GEN_CALL) + +#define BIT_IC_INTR_STAT_R_START_DET BIT(10) +#define BIT_SHIFT_IC_INTR_STAT_R_START_DET 10 +#define BIT_MASK_IC_INTR_STAT_R_START_DET 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_START_DET(x) (((x) & BIT_MASK_IC_INTR_STAT_R_START_DET) << BIT_SHIFT_IC_INTR_STAT_R_START_DET) + +#define BIT_IC_INTR_STAT_R_STOP_DET BIT(9) +#define BIT_SHIFT_IC_INTR_STAT_R_STOP_DET 9 +#define BIT_MASK_IC_INTR_STAT_R_STOP_DET 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_STOP_DET(x) (((x) & BIT_MASK_IC_INTR_STAT_R_STOP_DET) << BIT_SHIFT_IC_INTR_STAT_R_STOP_DET) + +#define BIT_IC_INTR_STAT_R_ACTIVITY BIT(8) +#define BIT_SHIFT_IC_INTR_STAT_R_ACTIVITY 8 +#define BIT_MASK_IC_INTR_STAT_R_ACTIVITY 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_ACTIVITY(x) (((x) & BIT_MASK_IC_INTR_STAT_R_ACTIVITY) << BIT_SHIFT_IC_INTR_STAT_R_ACTIVITY) + +#define BIT_IC_INTR_STAT_R_RX_DONE BIT(7) +#define BIT_SHIFT_IC_INTR_STAT_R_RX_DONE 7 +#define BIT_MASK_IC_INTR_STAT_R_RX_DONE 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_RX_DONE(x) (((x) & BIT_MASK_IC_INTR_STAT_R_RX_DONE) << BIT_SHIFT_IC_INTR_STAT_R_RX_DONE) + +#define BIT_IC_INTR_STAT_R_TX_ABRT BIT(6) +#define BIT_SHIFT_IC_INTR_STAT_R_TX_ABRT 6 +#define BIT_MASK_IC_INTR_STAT_R_TX_ABRT 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_TX_ABRT(x) (((x) & BIT_MASK_IC_INTR_STAT_R_TX_ABRT) << BIT_SHIFT_IC_INTR_STAT_R_TX_ABRT) + +#define BIT_IC_INTR_STAT_R_RD_REQ BIT(5) +#define BIT_SHIFT_IC_INTR_STAT_R_RD_REQ 5 +#define BIT_MASK_IC_INTR_STAT_R_RD_REQ 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_RD_REQ(x) (((x) & BIT_MASK_IC_INTR_STAT_R_RD_REQ) << BIT_SHIFT_IC_INTR_STAT_R_RD_REQ) + +#define BIT_IC_INTR_STAT_R_TX_EMPTY BIT(4) +#define BIT_SHIFT_IC_INTR_STAT_R_TX_EMPTY 4 +#define BIT_MASK_IC_INTR_STAT_R_TX_EMPTY 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_TX_EMPTY(x) (((x) & BIT_MASK_IC_INTR_STAT_R_TX_EMPTY) << BIT_SHIFT_IC_INTR_STAT_R_TX_EMPTY) + +#define BIT_IC_INTR_STAT_R_TX_OVER BIT(3) +#define BIT_SHIFT_IC_INTR_STAT_R_TX_OVER 3 +#define BIT_MASK_IC_INTR_STAT_R_TX_OVER 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_TX_OVER(x) (((x) & BIT_MASK_IC_INTR_STAT_R_TX_OVER) << BIT_SHIFT_IC_INTR_STAT_R_TX_OVER) + +#define BIT_IC_INTR_STAT_R_RX_FULL BIT(2) +#define BIT_SHIFT_IC_INTR_STAT_R_RX_FULL 2 +#define BIT_MASK_IC_INTR_STAT_R_RX_FULL 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_RX_FULL(x) (((x) & BIT_MASK_IC_INTR_STAT_R_RX_FULL) << BIT_SHIFT_IC_INTR_STAT_R_RX_FULL) + +#define BIT_IC_INTR_STAT_R_RX_OVER BIT(1) +#define BIT_SHIFT_IC_INTR_STAT_R_RX_OVER 1 +#define BIT_MASK_IC_INTR_STAT_R_RX_OVER 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_RX_OVER(x) (((x) & BIT_MASK_IC_INTR_STAT_R_RX_OVER) << BIT_SHIFT_IC_INTR_STAT_R_RX_OVER) + +#define BIT_IC_INTR_STAT_R_RX_UNDER BIT(0) +#define BIT_SHIFT_IC_INTR_STAT_R_RX_UNDER 0 +#define BIT_MASK_IC_INTR_STAT_R_RX_UNDER 0x1 +#define BIT_CTRL_IC_INTR_STAT_R_RX_UNDER(x) (((x) & BIT_MASK_IC_INTR_STAT_R_RX_UNDER) << BIT_SHIFT_IC_INTR_STAT_R_RX_UNDER) + + +//2 REG_DW_I2C_IC_INTR_MASK +#define BIT_IC_INTR_MASK_M_GEN_CALL BIT(11) +#define BIT_SHIFT_IC_INTR_MASK_M_GEN_CALL 11 +#define BIT_MASK_IC_INTR_MASK_M_GEN_CALL 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_GEN_CALL(x) (((x) & BIT_MASK_IC_INTR_MASK_M_GEN_CALL) << BIT_SHIFT_IC_INTR_MASK_M_GEN_CALL) + +#define BIT_IC_INTR_MASK_M_START_DET BIT(10) +#define BIT_SHIFT_IC_INTR_MASK_M_START_DET 10 +#define BIT_MASK_IC_INTR_MASK_M_START_DET 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_START_DET(x) (((x) & BIT_MASK_IC_INTR_MASK_M_START_DET) << BIT_SHIFT_IC_INTR_MASK_M_START_DET) + +#define BIT_IC_INTR_MASK_M_STOP_DET BIT(9) +#define BIT_SHIFT_IC_INTR_MASK_M_STOP_DET 9 +#define BIT_MASK_IC_INTR_MASK_M_STOP_DET 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_STOP_DET(x) (((x) & BIT_MASK_IC_INTR_MASK_M_STOP_DET) << BIT_SHIFT_IC_INTR_MASK_M_STOP_DET) + +#define BIT_IC_INTR_MASK_M_ACTIVITY BIT(8) +#define BIT_SHIFT_IC_INTR_MASK_M_ACTIVITY 8 +#define BIT_MASK_IC_INTR_MASK_M_ACTIVITY 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_ACTIVITY(x) (((x) & BIT_MASK_IC_INTR_MASK_M_ACTIVITY) << BIT_SHIFT_IC_INTR_MASK_M_ACTIVITY) + +#define BIT_IC_INTR_MASK_M_RX_DONE BIT(7) +#define BIT_SHIFT_IC_INTR_MASK_M_RX_DONE 7 +#define BIT_MASK_IC_INTR_MASK_M_RX_DONE 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_RX_DONE(x) (((x) & BIT_MASK_IC_INTR_MASK_M_RX_DONE) << BIT_SHIFT_IC_INTR_MASK_M_RX_DONE) + +#define BIT_IC_INTR_MASK_M_TX_ABRT BIT(6) +#define BIT_SHIFT_IC_INTR_MASK_M_TX_ABRT 6 +#define BIT_MASK_IC_INTR_MASK_M_TX_ABRT 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_TX_ABRT(x) (((x) & BIT_MASK_IC_INTR_MASK_M_TX_ABRT) << BIT_SHIFT_IC_INTR_MASK_M_TX_ABRT) + +#define BIT_IC_INTR_MASK_M_RD_REQ BIT(5) +#define BIT_SHIFT_IC_INTR_MASK_M_RD_REQ 5 +#define BIT_MASK_IC_INTR_MASK_M_RD_REQ 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_RD_REQ(x) (((x) & BIT_MASK_IC_INTR_MASK_M_RD_REQ) << BIT_SHIFT_IC_INTR_MASK_M_RD_REQ) + +#define BIT_IC_INTR_MASK_M_TX_EMPTY BIT(4) +#define BIT_SHIFT_IC_INTR_MASK_M_TX_EMPTY 4 +#define BIT_MASK_IC_INTR_MASK_M_TX_EMPTY 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_TX_EMPTY(x) (((x) & BIT_MASK_IC_INTR_MASK_M_TX_EMPTY) << BIT_SHIFT_IC_INTR_MASK_M_TX_EMPTY) + +#define BIT_IC_INTR_MASK_M_TX_OVER BIT(3) +#define BIT_SHIFT_IC_INTR_MASK_M_TX_OVER 3 +#define BIT_MASK_IC_INTR_MASK_M_TX_OVER 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_TX_OVER(x) (((x) & BIT_MASK_IC_INTR_MASK_M_TX_OVER) << BIT_SHIFT_IC_INTR_MASK_M_TX_OVER) + +#define BIT_IC_INTR_MASK_M_RX_FULL BIT(2) +#define BIT_SHIFT_IC_INTR_MASK_M_RX_FULL 2 +#define BIT_MASK_IC_INTR_MASK_M_RX_FULL 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_RX_FULL(x) (((x) & BIT_MASK_IC_INTR_MASK_M_RX_FULL) << BIT_SHIFT_IC_INTR_MASK_M_RX_FULL) + +#define BIT_IC_INTR_MASK_M_RX_OVER BIT(1) +#define BIT_SHIFT_IC_INTR_MASK_M_RX_OVER 1 +#define BIT_MASK_IC_INTR_MASK_M_RX_OVER 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_RX_OVER(x) (((x) & BIT_MASK_IC_INTR_MASK_M_RX_OVER) << BIT_SHIFT_IC_INTR_MASK_M_RX_OVER) + +#define BIT_IC_INTR_MASK_M_RX_UNDER BIT(0) +#define BIT_SHIFT_IC_INTR_MASK_M_RX_UNDER 0 +#define BIT_MASK_IC_INTR_MASK_M_RX_UNDER 0x1 +#define BIT_CTRL_IC_INTR_MASK_M_RX_UNDER(x) (((x) & BIT_MASK_IC_INTR_MASK_M_RX_UNDER) << BIT_SHIFT_IC_INTR_MASK_M_RX_UNDER) + + +//2 REG_DW_I2C_IC_RAW_INTR_STAT +#define BIT_IC_RAW_INTR_STAT_GEN_CALL BIT(11) +#define BIT_SHIFT_IC_RAW_INTR_STAT_GEN_CALL 11 +#define BIT_MASK_IC_RAW_INTR_STAT_GEN_CALL 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_GEN_CALL(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_GEN_CALL) << BIT_SHIFT_IC_RAW_INTR_STAT_GEN_CALL) + +#define BIT_IC_RAW_INTR_STAT_START_DET BIT(10) +#define BIT_SHIFT_IC_RAW_INTR_STAT_START_DET 10 +#define BIT_MASK_IC_RAW_INTR_STAT_START_DET 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_START_DET(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_START_DET) << BIT_SHIFT_IC_RAW_INTR_STAT_START_DET) + +#define BIT_IC_RAW_INTR_STAT_STOP_DET BIT(9) +#define BIT_SHIFT_IC_RAW_INTR_STAT_STOP_DET 9 +#define BIT_MASK_IC_RAW_INTR_STAT_STOP_DET 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_STOP_DET(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_STOP_DET) << BIT_SHIFT_IC_RAW_INTR_STAT_STOP_DET) + +#define BIT_IC_RAW_INTR_STAT_ACTIVITY BIT(8) +#define BIT_SHIFT_IC_RAW_INTR_STAT_ACTIVITY 8 +#define BIT_MASK_IC_RAW_INTR_STAT_ACTIVITY 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_ACTIVITY(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_ACTIVITY) << BIT_SHIFT_IC_RAW_INTR_STAT_ACTIVITY) + +#define BIT_IC_RAW_INTR_STAT_RX_DONE BIT(7) +#define BIT_SHIFT_IC_RAW_INTR_STAT_RX_DONE 7 +#define BIT_MASK_IC_RAW_INTR_STAT_RX_DONE 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_RX_DONE(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_RX_DONE) << BIT_SHIFT_IC_RAW_INTR_STAT_RX_DONE) + +#define BIT_IC_RAW_INTR_STAT_TX_ABRT BIT(6) +#define BIT_SHIFT_IC_RAW_INTR_STAT_TX_ABRT 6 +#define BIT_MASK_IC_RAW_INTR_STAT_TX_ABRT 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_TX_ABRT(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_TX_ABRT) << BIT_SHIFT_IC_RAW_INTR_STAT_TX_ABRT) + +#define BIT_IC_RAW_INTR_STAT_RD_REQ BIT(5) +#define BIT_SHIFT_IC_RAW_INTR_STAT_RD_REQ 5 +#define BIT_MASK_IC_RAW_INTR_STAT_RD_REQ 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_RD_REQ(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_RD_REQ) << BIT_SHIFT_IC_RAW_INTR_STAT_RD_REQ) + +#define BIT_IC_RAW_INTR_STAT_TX_EMPTY BIT(4) +#define BIT_SHIFT_IC_RAW_INTR_STAT_TX_EMPTY 4 +#define BIT_MASK_IC_RAW_INTR_STAT_TX_EMPTY 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_TX_EMPTY(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_TX_EMPTY) << BIT_SHIFT_IC_RAW_INTR_STAT_TX_EMPTY) + +#define BIT_IC_RAW_INTR_STAT_TX_OVER BIT(3) +#define BIT_SHIFT_IC_RAW_INTR_STAT_TX_OVER 3 +#define BIT_MASK_IC_RAW_INTR_STAT_TX_OVER 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_TX_OVER(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_TX_OVER) << BIT_SHIFT_IC_RAW_INTR_STAT_TX_OVER) + +#define BIT_IC_RAW_INTR_STAT_RX_FULL BIT(2) +#define BIT_SHIFT_IC_RAW_INTR_STAT_RX_FULL 2 +#define BIT_MASK_IC_RAW_INTR_STAT_RX_FULL 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_RX_FULL(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_RX_FULL) << BIT_SHIFT_IC_RAW_INTR_STAT_RX_FULL) + +#define BIT_IC_RAW_INTR_STAT_RX_OVER BIT(1) +#define BIT_SHIFT_IC_RAW_INTR_STAT_RX_OVER 1 +#define BIT_MASK_IC_RAW_INTR_STAT_RX_OVER 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_RX_OVER(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_RX_OVER) << BIT_SHIFT_IC_RAW_INTR_STAT_RX_OVER) + +#define BIT_IC_RAW_INTR_STAT_RX_UNDER BIT(0) +#define BIT_SHIFT_IC_RAW_INTR_STAT_RX_UNDER 0 +#define BIT_MASK_IC_RAW_INTR_STAT_RX_UNDER 0x1 +#define BIT_CTRL_IC_RAW_INTR_STAT_RX_UNDER(x) (((x) & BIT_MASK_IC_RAW_INTR_STAT_RX_UNDER) << BIT_SHIFT_IC_RAW_INTR_STAT_RX_UNDER) + + +//2 REG_DW_I2C_IC_RX_TL + +#define BIT_SHIFT_IC_RX_TL 0 +#define BIT_MASK_IC_RX_TL 0xff +#define BIT_IC_RX_TL(x) (((x) & BIT_MASK_IC_RX_TL) << BIT_SHIFT_IC_RX_TL) +#define BIT_CTRL_IC_RX_TL(x) (((x) & BIT_MASK_IC_RX_TL) << BIT_SHIFT_IC_RX_TL) +#define BIT_GET_IC_RX_TL(x) (((x) >> BIT_SHIFT_IC_RX_TL) & BIT_MASK_IC_RX_TL) + + +//2 REG_DW_I2C_IC_TX_TL + +#define BIT_SHIFT_IC_TX_TL 0 +#define BIT_MASK_IC_TX_TL 0xff +#define BIT_IC_TX_TL(x) (((x) & BIT_MASK_IC_TX_TL) << BIT_SHIFT_IC_TX_TL) +#define BIT_CTRL_IC_TX_TL(x) (((x) & BIT_MASK_IC_TX_TL) << BIT_SHIFT_IC_TX_TL) +#define BIT_GET_IC_TX_TL(x) (((x) >> BIT_SHIFT_IC_TX_TL) & BIT_MASK_IC_TX_TL) + + +//2 REG_DW_I2C_IC_CLR_INTR +#define BIT_IC_CLR_INTR BIT(0) +#define BIT_SHIFT_IC_CLR_INTR 0 +#define BIT_MASK_IC_CLR_INTR 0x1 +#define BIT_CTRL_IC_CLR_INTR(x) (((x) & BIT_MASK_IC_CLR_INTR) << BIT_SHIFT_IC_CLR_INTR) + + +//2 REG_DW_I2C_IC_CLR_RX_UNDER +#define BIT_IC_CLR_RX_UNDER BIT(0) +#define BIT_SHIFT_IC_CLR_RX_UNDER 0 +#define BIT_MASK_IC_CLR_RX_UNDER 0x1 +#define BIT_CTRL_IC_CLR_RX_UNDER(x) (((x) & BIT_MASK_IC_CLR_RX_UNDER) << BIT_SHIFT_IC_CLR_RX_UNDER) + + +//2 REG_DW_I2C_IC_CLR_RX_OVER +#define BIT_IC_CLR_RX_OVER BIT(0) +#define BIT_SHIFT_IC_CLR_RX_OVER 0 +#define BIT_MASK_IC_CLR_RX_OVER 0x1 +#define BIT_CTRL_IC_CLR_RX_OVER(x) (((x) & BIT_MASK_IC_CLR_RX_OVER) << BIT_SHIFT_IC_CLR_RX_OVER) + + +//2 REG_DW_I2C_IC_CLR_TX_OVER +#define BIT_IC_CLR_TX_OVER BIT(0) +#define BIT_SHIFT_IC_CLR_TX_OVER 0 +#define BIT_MASK_IC_CLR_TX_OVER 0x1 +#define BIT_CTRL_IC_CLR_TX_OVER(x) (((x) & BIT_MASK_IC_CLR_TX_OVER) << BIT_SHIFT_IC_CLR_TX_OVER) + + +//2 REG_DW_I2C_IC_CLR_RD_REQ +#define BIT_IC_CLR_RD_REQ BIT(0) +#define BIT_SHIFT_IC_CLR_RD_REQ 0 +#define BIT_MASK_IC_CLR_RD_REQ 0x1 +#define BIT_CTRL_IC_CLR_RD_REQ(x) (((x) & BIT_MASK_IC_CLR_RD_REQ) << BIT_SHIFT_IC_CLR_RD_REQ) + + +//2 REG_DW_I2C_IC_CLR_TX_ABRT +#define BIT_CLR_RD_REQ BIT(0) +#define BIT_SHIFT_CLR_RD_REQ 0 +#define BIT_MASK_CLR_RD_REQ 0x1 +#define BIT_CTRL_CLR_RD_REQ(x) (((x) & BIT_MASK_CLR_RD_REQ) << BIT_SHIFT_CLR_RD_REQ) + + +//2 REG_DW_I2C_IC_CLR_RX_DONE +#define BIT_IC_CLR_RX_DONE BIT(0) +#define BIT_SHIFT_IC_CLR_RX_DONE 0 +#define BIT_MASK_IC_CLR_RX_DONE 0x1 +#define BIT_CTRL_IC_CLR_RX_DONE(x) (((x) & BIT_MASK_IC_CLR_RX_DONE) << BIT_SHIFT_IC_CLR_RX_DONE) + + +//2 REG_DW_I2C_IC_CLR_ACTIVITY +#define BIT_IC_CLR_ACTIVITY BIT(0) +#define BIT_SHIFT_IC_CLR_ACTIVITY 0 +#define BIT_MASK_IC_CLR_ACTIVITY 0x1 +#define BIT_CTRL_IC_CLR_ACTIVITY(x) (((x) & BIT_MASK_IC_CLR_ACTIVITY) << BIT_SHIFT_IC_CLR_ACTIVITY) + + +//2 REG_DW_I2C_IC_CLR_STOP_DET +#define BIT_IC_CLR_STOP_DET BIT(0) +#define BIT_SHIFT_IC_CLR_STOP_DET 0 +#define BIT_MASK_IC_CLR_STOP_DET 0x1 +#define BIT_CTRL_IC_CLR_STOP_DET(x) (((x) & BIT_MASK_IC_CLR_STOP_DET) << BIT_SHIFT_IC_CLR_STOP_DET) + + +//2 REG_DW_I2C_IC_CLR_START_DET +#define BIT_IC_CLR_START_DET BIT(0) +#define BIT_SHIFT_IC_CLR_START_DET 0 +#define BIT_MASK_IC_CLR_START_DET 0x1 +#define BIT_CTRL_IC_CLR_START_DET(x) (((x) & BIT_MASK_IC_CLR_START_DET) << BIT_SHIFT_IC_CLR_START_DET) + + +//2 REG_DW_I2C_IC_CLR_GEN_CALL +#define BIT_IC_CLR_GEN_CALL BIT(0) +#define BIT_SHIFT_IC_CLR_GEN_CALL 0 +#define BIT_MASK_IC_CLR_GEN_CALL 0x1 +#define BIT_CTRL_IC_CLR_GEN_CALL(x) (((x) & BIT_MASK_IC_CLR_GEN_CALL) << BIT_SHIFT_IC_CLR_GEN_CALL) + + +//2 REG_DW_I2C_IC_ENABLE +#define BIT_IC_ENABLE BIT(0) +#define BIT_SHIFT_IC_ENABLE 0 +#define BIT_MASK_IC_ENABLE 0x1 +#define BIT_CTRL_IC_ENABLE(x) (((x) & BIT_MASK_IC_ENABLE) << BIT_SHIFT_IC_ENABLE) + + +//2 REG_DW_I2C_IC_STATUS +#define BIT_IC_STATUS_SLV_ACTIVITY BIT(6) +#define BIT_SHIFT_IC_STATUS_SLV_ACTIVITY 6 +#define BIT_MASK_IC_STATUS_SLV_ACTIVITY 0x1 +#define BIT_CTRL_IC_STATUS_SLV_ACTIVITY(x) (((x) & BIT_MASK_IC_STATUS_SLV_ACTIVITY) << BIT_SHIFT_IC_STATUS_SLV_ACTIVITY) + +#define BIT_IC_STATUS_MST_ACTIVITY BIT(5) +#define BIT_SHIFT_IC_STATUS_MST_ACTIVITY 5 +#define BIT_MASK_IC_STATUS_MST_ACTIVITY 0x1 +#define BIT_CTRL_IC_STATUS_MST_ACTIVITY(x) (((x) & BIT_MASK_IC_STATUS_MST_ACTIVITY) << BIT_SHIFT_IC_STATUS_MST_ACTIVITY) + +#define BIT_IC_STATUS_RFF BIT(4) +#define BIT_SHIFT_IC_STATUS_RFF 4 +#define BIT_MASK_IC_STATUS_RFF 0x1 +#define BIT_CTRL_IC_STATUS_RFF(x) (((x) & BIT_MASK_IC_STATUS_RFF) << BIT_SHIFT_IC_STATUS_RFF) + +#define BIT_IC_STATUS_RFNE BIT(3) +#define BIT_SHIFT_IC_STATUS_RFNE 3 +#define BIT_MASK_IC_STATUS_RFNE 0x1 +#define BIT_CTRL_IC_STATUS_RFNE(x) (((x) & BIT_MASK_IC_STATUS_RFNE) << BIT_SHIFT_IC_STATUS_RFNE) + +#define BIT_IC_STATUS_TFE BIT(2) +#define BIT_SHIFT_IC_STATUS_TFE 2 +#define BIT_MASK_IC_STATUS_TFE 0x1 +#define BIT_CTRL_IC_STATUS_TFE(x) (((x) & BIT_MASK_IC_STATUS_TFE) << BIT_SHIFT_IC_STATUS_TFE) + +#define BIT_IC_STATUS_TFNF BIT(1) +#define BIT_SHIFT_IC_STATUS_TFNF 1 +#define BIT_MASK_IC_STATUS_TFNF 0x1 +#define BIT_CTRL_IC_STATUS_TFNF(x) (((x) & BIT_MASK_IC_STATUS_TFNF) << BIT_SHIFT_IC_STATUS_TFNF) + +#define BIT_IC_STATUS_ACTIVITY BIT(0) +#define BIT_SHIFT_IC_STATUS_ACTIVITY 0 +#define BIT_MASK_IC_STATUS_ACTIVITY 0x1 +#define BIT_CTRL_IC_STATUS_ACTIVITY(x) (((x) & BIT_MASK_IC_STATUS_ACTIVITY) << BIT_SHIFT_IC_STATUS_ACTIVITY) + + +//2 REG_DW_I2C_IC_TXFLR + +#define BIT_SHIFT_IC_TXFLR 0 +#define BIT_MASK_IC_TXFLR 0x3f +#define BIT_IC_TXFLR(x) (((x) & BIT_MASK_IC_TXFLR) << BIT_SHIFT_IC_TXFLR) +#define BIT_CTRL_IC_TXFLR(x) (((x) & BIT_MASK_IC_TXFLR) << BIT_SHIFT_IC_TXFLR) +#define BIT_GET_IC_TXFLR(x) (((x) >> BIT_SHIFT_IC_TXFLR) & BIT_MASK_IC_TXFLR) + + +//2 REG_DW_I2C_IC_RXFLR + +#define BIT_SHIFT_IC_RXFLR 0 +#define BIT_MASK_IC_RXFLR 0x1f +#define BIT_IC_RXFLR(x) (((x) & BIT_MASK_IC_RXFLR) << BIT_SHIFT_IC_RXFLR) +#define BIT_CTRL_IC_RXFLR(x) (((x) & BIT_MASK_IC_RXFLR) << BIT_SHIFT_IC_RXFLR) +#define BIT_GET_IC_RXFLR(x) (((x) >> BIT_SHIFT_IC_RXFLR) & BIT_MASK_IC_RXFLR) + + +//2 REG_DW_I2C_IC_SDA_HOLD + +#define BIT_SHIFT_IC_SDA_HOLD 0 +#define BIT_MASK_IC_SDA_HOLD 0xffff +#define BIT_IC_SDA_HOLD(x) (((x) & BIT_MASK_IC_SDA_HOLD) << BIT_SHIFT_IC_SDA_HOLD) +#define BIT_CTRL_IC_SDA_HOLD(x) (((x) & BIT_MASK_IC_SDA_HOLD) << BIT_SHIFT_IC_SDA_HOLD) +#define BIT_GET_IC_SDA_HOLD(x) (((x) >> BIT_SHIFT_IC_SDA_HOLD) & BIT_MASK_IC_SDA_HOLD) + + +//2 REG_DW_I2C_IC_TX_ABRT_SOURCE +#define BIT_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX BIT(15) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX 15 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLVRD_INTX) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST BIT(14) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST 14 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLV_ARBLOST) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO BIT(13) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO 13 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SLVFLUSH_TXFIFO) + +#define BIT_IC_TX_ABRT_SOURCE_ARB_LOST BIT(12) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ARB_LOST 12 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ARB_LOST 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ARB_LOST(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ARB_LOST) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ARB_LOST) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS BIT(11) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS 11 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_MASTER_DIS) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT BIT(10) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT 10 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10B_RD_NORSTRT) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT BIT(9) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT 9 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT BIT(8) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT 8 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_HS_NORSTRT) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET BIT(7) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET 7 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_SBYTE_ACKDET) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET BIT(6) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET 6 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_HS_ACKDET) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ BIT(5) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ 5 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_GCALL_READ) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK BIT(4) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK 4 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_GCALL_NOACK) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK BIT(3) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK 3 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK BIT(2) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK 2 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK BIT(1) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK 1 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK) + +#define BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK BIT(0) +#define BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK 0 +#define BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK 0x1 +#define BIT_CTRL_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK(x) (((x) & BIT_MASK_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK) << BIT_SHIFT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK) + + +//2 REG_DW_I2C_IC_SLV_DATA_NACK_ONLY +#define BIT_IC_SLV_DATA_NACK_ONLY BIT(0) +#define BIT_SHIFT_IC_SLV_DATA_NACK_ONLY 0 +#define BIT_MASK_IC_SLV_DATA_NACK_ONLY 0x1 +#define BIT_CTRL_IC_SLV_DATA_NACK_ONLY(x) (((x) & BIT_MASK_IC_SLV_DATA_NACK_ONLY) << BIT_SHIFT_IC_SLV_DATA_NACK_ONLY) + + +//2 REG_DW_I2C_IC_DMA_CR +#define BIT_IC_DMA_CR_TDMAE BIT(1) +#define BIT_SHIFT_IC_DMA_CR_TDMAE 1 +#define BIT_MASK_IC_DMA_CR_TDMAE 0x1 +#define BIT_CTRL_IC_DMA_CR_TDMAE(x) (((x) & BIT_MASK_IC_DMA_CR_TDMAE) << BIT_SHIFT_IC_DMA_CR_TDMAE) + +#define BIT_IC_DMA_CR_RDMAE BIT(0) +#define BIT_SHIFT_IC_DMA_CR_RDMAE 0 +#define BIT_MASK_IC_DMA_CR_RDMAE 0x1 +#define BIT_CTRL_IC_DMA_CR_RDMAE(x) (((x) & BIT_MASK_IC_DMA_CR_RDMAE) << BIT_SHIFT_IC_DMA_CR_RDMAE) + + +//2 REG_DW_I2C_IC_DMA_TDLR + +#define BIT_SHIFT_IC_DMA_TDLR_DMATDL 0 +#define BIT_MASK_IC_DMA_TDLR_DMATDL 0x1f +#define BIT_IC_DMA_TDLR_DMATDL(x) (((x) & BIT_MASK_IC_DMA_TDLR_DMATDL) << BIT_SHIFT_IC_DMA_TDLR_DMATDL) +#define BIT_CTRL_IC_DMA_TDLR_DMATDL(x) (((x) & BIT_MASK_IC_DMA_TDLR_DMATDL) << BIT_SHIFT_IC_DMA_TDLR_DMATDL) +#define BIT_GET_IC_DMA_TDLR_DMATDL(x) (((x) >> BIT_SHIFT_IC_DMA_TDLR_DMATDL) & BIT_MASK_IC_DMA_TDLR_DMATDL) + + +//2 REG_DW_I2C_IC_DMA_RDLR + +#define BIT_SHIFT_IC_DMA_RDLR_DMARDL 0 +#define BIT_MASK_IC_DMA_RDLR_DMARDL 0xf +#define BIT_IC_DMA_RDLR_DMARDL(x) (((x) & BIT_MASK_IC_DMA_RDLR_DMARDL) << BIT_SHIFT_IC_DMA_RDLR_DMARDL) +#define BIT_CTRL_IC_DMA_RDLR_DMARDL(x) (((x) & BIT_MASK_IC_DMA_RDLR_DMARDL) << BIT_SHIFT_IC_DMA_RDLR_DMARDL) +#define BIT_GET_IC_DMA_RDLR_DMARDL(x) (((x) >> BIT_SHIFT_IC_DMA_RDLR_DMARDL) & BIT_MASK_IC_DMA_RDLR_DMARDL) + + +//2 REG_DW_I2C_IC_SDA_SETUP + +#define BIT_SHIFT_IC_SDA_SETUP 0 +#define BIT_MASK_IC_SDA_SETUP 0xff +#define BIT_IC_SDA_SETUP(x) (((x) & BIT_MASK_IC_SDA_SETUP) << BIT_SHIFT_IC_SDA_SETUP) +#define BIT_CTRL_IC_SDA_SETUP(x) (((x) & BIT_MASK_IC_SDA_SETUP) << BIT_SHIFT_IC_SDA_SETUP) +#define BIT_GET_IC_SDA_SETUP(x) (((x) >> BIT_SHIFT_IC_SDA_SETUP) & BIT_MASK_IC_SDA_SETUP) + + +//2 REG_DW_I2C_IC_ACK_GENERAL_CALL +#define BIT_IC_ACK_GENERAL_CALL BIT(0) +#define BIT_SHIFT_IC_ACK_GENERAL_CALL 0 +#define BIT_MASK_IC_ACK_GENERAL_CALL 0x1 +#define BIT_CTRL_IC_ACK_GENERAL_CALL(x) (((x) & BIT_MASK_IC_ACK_GENERAL_CALL) << BIT_SHIFT_IC_ACK_GENERAL_CALL) + + +//2 REG_DW_I2C_IC_ENABLE_STATUS +#define BIT_IC_ENABLE_STATUS_SLV_RX_DATA_LOST BIT(2) +#define BIT_SHIFT_IC_ENABLE_STATUS_SLV_RX_DATA_LOST 2 +#define BIT_MASK_IC_ENABLE_STATUS_SLV_RX_DATA_LOST 0x1 +#define BIT_CTRL_IC_ENABLE_STATUS_SLV_RX_DATA_LOST(x) (((x) & BIT_MASK_IC_ENABLE_STATUS_SLV_RX_DATA_LOST) << BIT_SHIFT_IC_ENABLE_STATUS_SLV_RX_DATA_LOST) + +#define BIT_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY BIT(1) +#define BIT_SHIFT_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY 1 +#define BIT_MASK_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY 0x1 +#define BIT_CTRL_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY(x) (((x) & BIT_MASK_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY) << BIT_SHIFT_IC_ENABLE_STATUS_SLV_DISABLED_WHILE_BUSY) + +#define BIT_IC_ENABLE_STATUS_IC_EN BIT(0) +#define BIT_SHIFT_IC_ENABLE_STATUS_IC_EN 0 +#define BIT_MASK_IC_ENABLE_STATUS_IC_EN 0x1 +#define BIT_CTRL_IC_ENABLE_STATUS_IC_EN(x) (((x) & BIT_MASK_IC_ENABLE_STATUS_IC_EN) << BIT_SHIFT_IC_ENABLE_STATUS_IC_EN) + + +//2 REG_DW_I2C_IC_COMP_PARAM_1 + +#define BIT_SHIFT_IC_COMP_PARAM_1_TX_BUFFER_DEPTH 16 +#define BIT_MASK_IC_COMP_PARAM_1_TX_BUFFER_DEPTH 0xff +#define BIT_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) << BIT_SHIFT_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) +#define BIT_CTRL_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) << BIT_SHIFT_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) +#define BIT_GET_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) (((x) >> BIT_SHIFT_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) & BIT_MASK_IC_COMP_PARAM_1_TX_BUFFER_DEPTH) + + +#define BIT_SHIFT_IC_COMP_PARAM_1_RX_BUFFER_DEPTH 8 +#define BIT_MASK_IC_COMP_PARAM_1_RX_BUFFER_DEPTH 0xff +#define BIT_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) << BIT_SHIFT_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) +#define BIT_CTRL_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) << BIT_SHIFT_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) +#define BIT_GET_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) (((x) >> BIT_SHIFT_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) & BIT_MASK_IC_COMP_PARAM_1_RX_BUFFER_DEPTH) + +#define BIT_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS BIT(7) +#define BIT_SHIFT_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS 7 +#define BIT_MASK_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS 0x1 +#define BIT_CTRL_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS) << BIT_SHIFT_IC_COMP_PARAM_1_ADD_ENCODED_PARAMS) + +#define BIT_IC_COMP_PARAM_1_HAS_DMA BIT(6) +#define BIT_SHIFT_IC_COMP_PARAM_1_HAS_DMA 6 +#define BIT_MASK_IC_COMP_PARAM_1_HAS_DMA 0x1 +#define BIT_CTRL_IC_COMP_PARAM_1_HAS_DMA(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_HAS_DMA) << BIT_SHIFT_IC_COMP_PARAM_1_HAS_DMA) + +#define BIT_IC_COMP_PARAM_1_INTR_IO BIT(5) +#define BIT_SHIFT_IC_COMP_PARAM_1_INTR_IO 5 +#define BIT_MASK_IC_COMP_PARAM_1_INTR_IO 0x1 +#define BIT_CTRL_IC_COMP_PARAM_1_INTR_IO(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_INTR_IO) << BIT_SHIFT_IC_COMP_PARAM_1_INTR_IO) + +#define BIT_IC_COMP_PARAM_1_HC_COUNT_VALUES BIT(4) +#define BIT_SHIFT_IC_COMP_PARAM_1_HC_COUNT_VALUES 4 +#define BIT_MASK_IC_COMP_PARAM_1_HC_COUNT_VALUES 0x1 +#define BIT_CTRL_IC_COMP_PARAM_1_HC_COUNT_VALUES(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_HC_COUNT_VALUES) << BIT_SHIFT_IC_COMP_PARAM_1_HC_COUNT_VALUES) + + +#define BIT_SHIFT_IC_COMP_PARAM_1_MAX_SPEED_MODE 2 +#define BIT_MASK_IC_COMP_PARAM_1_MAX_SPEED_MODE 0x3 +#define BIT_IC_COMP_PARAM_1_MAX_SPEED_MODE(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_MAX_SPEED_MODE) << BIT_SHIFT_IC_COMP_PARAM_1_MAX_SPEED_MODE) +#define BIT_CTRL_IC_COMP_PARAM_1_MAX_SPEED_MODE(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_MAX_SPEED_MODE) << BIT_SHIFT_IC_COMP_PARAM_1_MAX_SPEED_MODE) +#define BIT_GET_IC_COMP_PARAM_1_MAX_SPEED_MODE(x) (((x) >> BIT_SHIFT_IC_COMP_PARAM_1_MAX_SPEED_MODE) & BIT_MASK_IC_COMP_PARAM_1_MAX_SPEED_MODE) + + +#define BIT_SHIFT_IC_COMP_PARAM_1_APB_DATA_WIDTH 0 +#define BIT_MASK_IC_COMP_PARAM_1_APB_DATA_WIDTH 0x3 +#define BIT_IC_COMP_PARAM_1_APB_DATA_WIDTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_APB_DATA_WIDTH) << BIT_SHIFT_IC_COMP_PARAM_1_APB_DATA_WIDTH) +#define BIT_CTRL_IC_COMP_PARAM_1_APB_DATA_WIDTH(x) (((x) & BIT_MASK_IC_COMP_PARAM_1_APB_DATA_WIDTH) << BIT_SHIFT_IC_COMP_PARAM_1_APB_DATA_WIDTH) +#define BIT_GET_IC_COMP_PARAM_1_APB_DATA_WIDTH(x) (((x) >> BIT_SHIFT_IC_COMP_PARAM_1_APB_DATA_WIDTH) & BIT_MASK_IC_COMP_PARAM_1_APB_DATA_WIDTH) + + +//2 REG_DW_I2C_IC_COMP_VERSION + +#define BIT_SHIFT_IC_COMP_VERSION 0 +#define BIT_MASK_IC_COMP_VERSION 0xffffffffL +#define BIT_IC_COMP_VERSION(x) (((x) & BIT_MASK_IC_COMP_VERSION) << BIT_SHIFT_IC_COMP_VERSION) +#define BIT_CTRL_IC_COMP_VERSION(x) (((x) & BIT_MASK_IC_COMP_VERSION) << BIT_SHIFT_IC_COMP_VERSION) +#define BIT_GET_IC_COMP_VERSION(x) (((x) >> BIT_SHIFT_IC_COMP_VERSION) & BIT_MASK_IC_COMP_VERSION) + + +//2 REG_DW_I2C_IC_COMP_TYPE + +#define BIT_SHIFT_IC_COMP_TYPE 0 +#define BIT_MASK_IC_COMP_TYPE 0xffffffffL +#define BIT_IC_COMP_TYPE(x) (((x) & BIT_MASK_IC_COMP_TYPE) << BIT_SHIFT_IC_COMP_TYPE) +#define BIT_CTRL_IC_COMP_TYPE(x) (((x) & BIT_MASK_IC_COMP_TYPE) << BIT_SHIFT_IC_COMP_TYPE) +#define BIT_GET_IC_COMP_TYPE(x) (((x) >> BIT_SHIFT_IC_COMP_TYPE) & BIT_MASK_IC_COMP_TYPE) + +//======================== Register Address Definition ======================== +#define REG_DW_I2C_IC_CON 0x0000 // Control Register +#define REG_DW_I2C_IC_TAR 0x0004 // Master Target Address +#define REG_DW_I2C_IC_SAR 0x0008 // Slave Address +#define REG_DW_I2C_IC_HS_MADDR 0x000C // High Speed Master ID +#define REG_DW_I2C_IC_DATA_CMD 0x0010 // Data Buffer and Command +#define REG_DW_I2C_IC_SS_SCL_HCNT 0x0014 // Standard Speed Clock SCL High Count +#define REG_DW_I2C_IC_SS_SCL_LCNT 0x0018 // Standard Speed Clock SCL Low Count +#define REG_DW_I2C_IC_FS_SCL_HCNT 0x001C // Fast Speed Clock SCL High Count +#define REG_DW_I2C_IC_FS_SCL_LCNT 0x0020 // Fast Speed I2C Clock SCL Low Count +#define REG_DW_I2C_IC_HS_SCL_HCNT 0x0024 // High Speed I2C Clock SCL High Count +#define REG_DW_I2C_IC_HS_SCL_LCNT 0x0028 // High Speed I2C Clock SCL Low Count +#define REG_DW_I2C_IC_INTR_STAT 0x002C // Interrupt Status +#define REG_DW_I2C_IC_INTR_MASK 0x0030 // Interrupt Mask +#define REG_DW_I2C_IC_RAW_INTR_STAT 0x0034 // Raw Interrupt Status +#define REG_DW_I2C_IC_RX_TL 0x0038 // Receive FIFO Threshold Level +#define REG_DW_I2C_IC_TX_TL 0x003C // Transmit FIFO Threshold Level +#define REG_DW_I2C_IC_CLR_INTR 0x0040 // Clear Combined and Individual Interrupt +#define REG_DW_I2C_IC_CLR_RX_UNDER 0x0044 // Clear RX_UNDER Interrupt +#define REG_DW_I2C_IC_CLR_RX_OVER 0x0048 // Clear RX_OVER Interrupt +#define REG_DW_I2C_IC_CLR_TX_OVER 0x004C // Clear TX_OVER Interrupt +#define REG_DW_I2C_IC_CLR_RD_REQ 0x0050 // Clear RD_REQ Interrupt +#define REG_DW_I2C_IC_CLR_TX_ABRT 0x0054 // Clear TX_ABRT Interrupt +#define REG_DW_I2C_IC_CLR_RX_DONE 0x0058 // Clear RX_DONE Interrupt +#define REG_DW_I2C_IC_CLR_ACTIVITY 0x005C // Clear ACTIVITY Interrupt +#define REG_DW_I2C_IC_CLR_STOP_DET 0x0060 // Clear STOP_DET Interrupt +#define REG_DW_I2C_IC_CLR_START_DET 0x0064 // Clear START_DET Interrupt +#define REG_DW_I2C_IC_CLR_GEN_CALL 0x0068 // Clear GEN_CALL Interrupt +#define REG_DW_I2C_IC_ENABLE 0x006C // Enable +#define REG_DW_I2C_IC_STATUS 0x0070 // Status +#define REG_DW_I2C_IC_TXFLR 0x0074 // Transmit FIFO Level +#define REG_DW_I2C_IC_RXFLR 0x0078 // Receive FIFO Level +#define REG_DW_I2C_IC_SDA_HOLD 0x007C // SDA Hold +#define REG_DW_I2C_IC_TX_ABRT_SOURCE 0x0080 // Transmit Abort Source +#define REG_DW_I2C_IC_SLV_DATA_NACK_ONLY 0x0084 // +#define REG_DW_I2C_IC_DMA_CR 0x0088 // +#define REG_DW_I2C_IC_DMA_TDLR 0x008C // DMA Transmit Data Level Register +#define REG_DW_I2C_IC_DMA_RDLR 0x0090 // I2C Receive Data Level Register +#define REG_DW_I2C_IC_SDA_SETUP 0x0094 // SDA Setup +#define REG_DW_I2C_IC_ACK_GENERAL_CALL 0x0098 // General Call Ack +#define REG_DW_I2C_IC_ENABLE_STATUS 0x009C // Enable Status +#define REG_DW_I2C_IC_COMP_PARAM_1 0x00F4 // Configuration Parameters +#define REG_DW_I2C_IC_COMP_VERSION 0x00F8 // Component Version +#define REG_DW_I2C_IC_COMP_TYPE 0x00FC // Component Type + +//====================================================== +// I2C related enumeration +// I2C Address Mode +typedef enum _I2C_ADDR_MODE_ { + I2C_ADDR_7BIT = 0, + I2C_ADDR_10BIT = 1, +}I2C_ADDR_MODE,*PI2C_ADDR_MODE; + +// I2C Speed Mode +typedef enum _I2C_SPD_MODE_ { + I2C_SS_MODE = 1, + I2C_FS_MODE = 2, + I2C_HS_MODE = 3, +}I2C_SPD_MODE,*PI2C_SPD_MODE; + +//I2C Timing Parameters +#define I2C_SS_MIN_SCL_HTIME 4000 //the unit is ns. +#define I2C_SS_MIN_SCL_LTIME 4700 //the unit is ns. + +#define I2C_FS_MIN_SCL_HTIME 600 //the unit is ns. +#define I2C_FS_MIN_SCL_LTIME 1300 //the unit is ns. + +#define I2C_HS_MIN_SCL_HTIME_100 60 //the unit is ns, with bus loading = 100pf +#define I2C_HS_MIN_SCL_LTIME_100 120 //the unit is ns., with bus loading = 100pf + +#define I2C_HS_MIN_SCL_HTIME_400 160 //the unit is ns, with bus loading = 400pf +#define I2C_HS_MIN_SCL_LTIME_400 320 //the unit is ns., with bus loading = 400pf + + +//====================================================== +//I2C Essential functions and macros +_LONG_CALL_ROM_ VOID HalI2CWrite32(IN u8 I2CIdx, IN u8 I2CReg, IN u32 I2CVal); +_LONG_CALL_ROM_ u32 HalI2CRead32(IN u8 I2CIdx, IN u8 I2CReg); + +#define HAL_I2C_WRITE32(I2CIdx, addr, value) HalI2CWrite32(I2CIdx,addr,value) +#define HAL_I2C_READ32(I2CIdx, addr) HalI2CRead32(I2CIdx,addr) + +// Rtl8195a I2C function prototypes +_LONG_CALL_ HAL_Status HalI2CEnableRtl8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CInit8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CDeInit8195a(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status HalI2CSetCLKRtl8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CMassSendRtl8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CSendRtl8195a(IN VOID *Data); +_LONG_CALL_ u8 HalI2CReceiveRtl8195a(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status HalI2CIntrCtrl8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CClrIntrRtl8195a(IN VOID *Data); +_LONG_CALL_ROM_ HAL_Status HalI2CClrAllIntrRtl8195a(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CDMACtrl8195a(IN VOID *Data); +_LONG_CALL_ u32 HalI2CReadRegRtl8195a(IN VOID *Data, IN u8 I2CReg); +_LONG_CALL_ HAL_Status HalI2CWriteRegRtl8195a(IN VOID *Data, IN u8 I2CReg, IN u32 RegVal); + +//Rtl8195a I2C V02 function prototype +_LONG_CALL_ HAL_Status HalI2CSendRtl8195aV02(IN VOID *Data); +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) +_LONG_CALL_ HAL_Status HalI2CSetCLKRtl8195aV02(IN VOID *Data); +#elif defined(CONFIG_CHIP_E_CUT) +_LONG_CALL_ROM_ HAL_Status HalI2CSetCLKRtl8195aV02(IN VOID *Data); +#endif +//Rtl8195a I2C V02 function prototype END + +//Rtl8195a I2C V04 function prototype +_LONG_CALL_ HAL_Status HalI2CSendRtl8195a_V04(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CMassSendRtl8195a_V04(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CInit8195a_V04(IN VOID *Data); +_LONG_CALL_ HAL_Status HalI2CSetCLKRtl8195a_V04(IN VOID *Data); +//Rtl8195a I2C V04 function prototype END + +HAL_Status HalI2CInit8195a_Patch(IN VOID *Data); +HAL_Status HalI2CSendRtl8195a_Patch(IN VOID *Data); +HAL_Status HalI2CSetCLKRtl8195a_Patch(IN VOID *Data); +HAL_Status HalI2CMassSendRtl8195a_Patch(IN VOID *Data); +HAL_Status HalI2CEnableRtl8195a_Patch(IN VOID *Data); + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2s.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2s.h new file mode 100644 index 0000000..d466f9a --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_i2s.h @@ -0,0 +1,723 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_I2S_H_ +#define _RTL8195A_I2S_H_ + + +//=============== Register Bit Field Definition ==================== +// REG_I2S_CONTROL +#define BIT_CTLX_I2S_EN BIT(0) +#define BIT_SHIFT_CTLX_I2S_EN 0 +#define BIT_MASK_CTLX_I2S_EN 0x1 +#define BIT_CTRL_CTLX_I2S_EN(x) (((x) & BIT_MASK_CTLX_I2S_EN) << BIT_SHIFT_CTLX_I2S_EN) + +#define BIT_SHIFT_CTLX_I2S_TRX_ACT 1 +#define BIT_MASK_CTLX_I2S_TRX_ACT 0x3 +#define BIT_CTRL_CTLX_I2S_TRX_ACT(x) (((x) & BIT_MASK_CTLX_I2S_TRX_ACT) << BIT_SHIFT_CTLX_I2S_TRX_ACT) +#define BIT_GET_CTLX_I2S_TRX_ACT(x) (((x) >> BIT_SHIFT_CTLX_I2S_TRX_ACT) & BIT_MASK_CTLX_I2S_TRX_ACT) + +#define BIT_SHIFT_CTLX_I2S_CH_NUM 3 +#define BIT_MASK_CTLX_I2S_CH_NUM 0x3 +#define BIT_CTRL_CTLX_I2S_CH_NUM(x) (((x) & BIT_MASK_CTLX_I2S_CH_NUM) << BIT_SHIFT_CTLX_I2S_CH_NUM) +#define BIT_GET_CTLX_I2S_CH_NUM(x) (((x) >> BIT_SHIFT_CTLX_I2S_CH_NUM) & BIT_MASK_CTLX_I2S_CH_NUM) +//pvvx? +#define BIT_CTLX_I2S_EDGE_SW 5 +#define BIT_MASK_CTLX_EDGE_SW 0x1 +#define BIT_CTLX_EDGE_SW(x) (((x) & BIT_MASK_CTLX_EDGE_SW) << BIT_SHIFT_CTLX_EDGE_SW) +#define BIT_INV_CTLX_EDGE_SW (~(BIT_MASK_CTLX_EDGE_SW << BIT_SHIFT_CTLX_EDGE_SW)) + +#define BIT_CTLX_I2S_WL BIT(6) +#define BIT_SHIFT_CTLX_I2S_WL 6 +#define BIT_MASK_CTLX_I2S_WL 0x1 +#define BIT_CTRL_CTLX_I2S_WL(x) (((x) & BIT_MASK_CTLX_I2S_WL) << BIT_SHIFT_CTLX_I2S_WL) +//pvvx? +#define BIT_CTLX_I2S_LOOP_BACK 7 +#define BIT_MASK_CTLX_LOOP_BACK 0x1 +#define BIT_CTLX_LOOP_BACK(x) (((x) & BIT_MASK_CTLX_LOOP_BACK) << BIT_CTLX_I2S_LOOP_BACK) +#define BIT_INV_CTLX_LOOP_BACK (~(BIT_MASK_CTLX_LOOP_BACK << BIT_CTLX_I2S_LOOP_BACK)) +//pvvx? +#define BIT_CTLX_I2S_FORMAT 8 +#define BIT_MASK_CTLX_FORMAT 0x3 +#define BIT_CTLX_FORMAT(x) (((x) & BIT_MASK_CTLX_FORMAT) << BIT_CTLX_I2S_FORMAT) +#define BIT_INV_CTLX_FORMAT (~(BIT_MASK_CTLX_FORMAT << BIT_CTLX_I2S_FORMAT)) + +#define BIT_CTLX_I2S_LRSWAP BIT(10) +#define BIT_SHIFT_CTLX_I2S_LRSWAP 10 +#define BIT_MASK_CTLX_I2S_LRSWAP 0x1 +#define BIT_CTRL_CTLX_I2S_LRSWAP(x) (((x) & BIT_MASK_CTLX_I2S_LRSWAP) << BIT_SHIFT_CTLX_I2S_LRSWAP) + +#define BIT_CTLX_I2S_SCK_INV BIT(11) +#define BIT_SHIFT_CTLX_I2S_SCK_INV 11 +#define BIT_MASK_CTLX_I2S_SCK_INV 0x1 +#define BIT_CTRL_CTLX_I2S_SCK_INV(x) (((x) & BIT_MASK_CTLX_I2S_SCK_INV) << BIT_SHIFT_CTLX_I2S_SCK_INV) + +#define BIT_CTLX_I2S_ENDIAN_SWAP BIT(12) +#define BIT_SHIFT_CTLX_I2S_ENDIAN_SWAP 12 +#define BIT_MASK_CTLX_I2S_ENDIAN_SWAP 0x1 +#define BIT_CTRL_CTLX_I2S_ENDIAN_SWAP(x) (((x) & BIT_MASK_CTLX_I2S_ENDIAN_SWAP) << BIT_SHIFT_CTLX_I2S_ENDIAN_SWAP) + +#define BIT_CTLX_I2S_SLAVE_MODE BIT(29) +#define BIT_SHIFT_CTLX_I2S_SLAVE_MODE 29 +#define BIT_MASK_CTLX_I2S_SLAVE_MODE 0x1 +#define BIT_CTRL_CTLX_I2S_SLAVE_MODE(x) (((x) & BIT_MASK_CTLX_I2S_SLAVE_MODE) << BIT_SHIFT_CTLX_I2S_SLAVE_MODE) + +#define BIT_CTLX_I2S_CLK_SRC BIT(30) +#define BIT_SHIFT_CTLX_I2S_CLK_SRC 30 +#define BIT_MASK_CTLX_I2S_CLK_SRC 0x1 +#define BIT_CTRL_CTLX_I2S_CLK_SRC(x) (((x) & BIT_MASK_CTLX_I2S_CLK_SRC) << BIT_SHIFT_CTLX_I2S_CLK_SRC) + +#define BIT_CTLX_I2S_SW_RSTN BIT(31) +#define BIT_SHIFT_CTLX_I2S_SW_RSTN 31 +#define BIT_MASK_CTLX_I2S_SW_RSTN 0x1 +#define BIT_CTRL_CTLX_I2S_SW_RSTN(x) (((x) & BIT_MASK_CTLX_I2S_SW_RSTN) << BIT_SHIFT_CTLX_I2S_SW_RSTN) + +// REG_I2S_SETTING +#define BIT_SHIFT_SETTING_I2S_PAGE_SZ 0 +#define BIT_MASK_SETTING_I2S_PAGE_SZ 0xFFF +#define BIT_CTRL_SETTING_I2S_PAGE_SZ(x) (((x) & BIT_MASK_SETTING_I2S_PAGE_SZ) << BIT_SHIFT_SETTING_I2S_PAGE_SZ) +#define BIT_GET_SETTING_I2S_PAGE_SZ(x) (((x) >> BIT_SHIFT_SETTING_I2S_PAGE_SZ) & BIT_MASK_SETTING_I2S_PAGE_SZ) + +#define BIT_SHIFT_SETTING_I2S_PAGE_NUM 12 +#define BIT_MASK_SETTING_I2S_PAGE_NUM 0x3 +#define BIT_CTRL_SETTING_I2S_PAGE_NUM(x) (((x) & BIT_MASK_SETTING_I2S_PAGE_NUM) << BIT_SHIFT_SETTING_I2S_PAGE_NUM) +#define BIT_GET_SETTING_I2S_PAGE_NUM(x) (((x) >> BIT_SHIFT_SETTING_I2S_PAGE_NUM) & BIT_MASK_SETTING_I2S_PAGE_NUM) + +#define BIT_SHIFT_SETTING_I2S_SAMPLE_RATE 14 +#define BIT_MASK_SETTING_I2S_SAMPLE_RATE 0x7 +#define BIT_CTRL_SETTING_I2S_SAMPLE_RATE(x) (((x) & BIT_MASK_SETTING_I2S_SAMPLE_RATE) << BIT_SHIFT_SETTING_I2S_SAMPLE_RATE) +#define BIT_GET_SETTING_I2S_SAMPLE_RATE(x) (((x) >> BIT_SHIFT_SETTING_I2S_SAMPLE_RATE) & BIT_MASK_SETTING_I2S_SAMPLE_RATE) + +// i2s trx page own bit +#define BIT_PAGE_I2S_OWN_BIT BIT(31) +#define BIT_SHIFT_PAGE_I2S_OWN_BIT 31 +#define BIT_MASK_PAGE_I2S_OWN_BIT 0x1 +#define BIT_CTRL_PAGE_I2S_OWN_BIT(x) (((x) & BIT_MASK_PAGE_I2S_OWN_BIT) << BIT_SHIFT_PAGE_I2S_OWN_BIT) + +//=============== Register Address Definition ==================== +#define REG_I2S_PAGE_OWN_OFF 0x004 + +#define REG_I2S_CTL 0x000 +#define REG_I2S_TX_PAGE_PTR 0x004 +#define REG_I2S_RX_PAGE_PTR 0x008 +#define REG_I2S_SETTING 0x00C + +#define REG_I2S_TX_MASK_INT 0x010 +#define REG_I2S_TX_STATUS_INT 0x014 +#define REG_I2S_RX_MASK_INT 0x018 +#define REG_I2S_RX_STATUS_INT 0x01c + +#define REG_I2S_TX_PAGE0_OWN 0x020 +#define REG_I2S_TX_PAGE1_OWN 0x024 +#define REG_I2S_TX_PAGE2_OWN 0x028 +#define REG_I2S_TX_PAGE3_OWN 0x02C +#define REG_I2S_RX_PAGE0_OWN 0x030 +#define REG_I2S_RX_PAGE1_OWN 0x034 +#define REG_I2S_RX_PAGE2_OWN 0x038 +#define REG_I2S_RX_PAGE3_OWN 0x03C + +/*I2S Essential Functions and Macros*/ +VOID +HalI2SWrite32( + IN u8 I2SIdx, + IN u8 I2SReg, + IN u32 I2SVal +); + +u32 +HalI2SRead32( + IN u8 I2SIdx, + IN u8 I2SReg +); + +/* +#define HAL_I2SX_READ32(I2sIndex, addr) \ + HAL_READ32(I2S0_REG_BASE+ (I2sIndex*I2S1_REG_OFF), addr) +#define HAL_I2SX_WRITE32(I2sIndex, addr, value) \ + HAL_WRITE32((I2S0_REG_BASE+ (I2sIndex*I2S1_REG_OFF)), addr, value) +*/ + +#define HAL_I2S_WRITE32(I2SIdx, addr, value) HalI2SWrite32(I2SIdx,addr,value) +#define HAL_I2S_READ32(I2SIdx, addr) HalI2SRead32(I2SIdx,addr) + +/* I2S debug output*/ +#define I2S_PREFIX "RTL8195A[i2s]: " +#define I2S_PREFIX_LVL " [i2s_DBG]: " + +typedef enum _I2S_DBG_LVL_ { + HAL_I2S_LVL = 0x01, + SAL_I2S_LVL = 0x02, + VERI_I2S_LVL = 0x03, +}I2S_DBG_LVL,*PI2S_DBG_LVL; + +#if CONFIG_DEBUG_LOG > 0 +#ifdef CONFIG_DEBUG_LOG_I2S_HAL + + #define DBG_8195A_I2S(...) do{ \ + _DbgDump(I2S_PREFIX __VA_ARGS__);\ + }while(0) + + + #define I2SDBGLVL 0xFF + #define DBG_8195A_I2S_LVL(LVL,...) do{\ + if (LVL&I2SDBGLVL){\ + _DbgDump(I2S_PREFIX_LVL __VA_ARGS__);\ + }\ + }while(0) +#else + #define DBG_I2S_LOG_PERD 100 + #define DBG_8195A_I2S(...) + #define DBG_8195A_I2S_LVL(...) +#endif +#else + #define DBG_I2S_LOG_PERD 100 + #define DBG_8195A_I2S(...) + #define DBG_8195A_I2S_LVL(...) +#endif + +/* +#define REG_I2S_PAGE_OWN_OFF 0x004 +#define REG_I2S_CTL 0x000 +#define REG_I2S_TX_PAGE_PTR 0x004 +#define REG_I2S_RX_PAGE_PTR 0x008 +#define REG_I2S_SETTING 0x00C + +#define REG_I2S_TX_MASK_INT 0x010 +#define REG_I2S_TX_STATUS_INT 0x014 +#define REG_I2S_RX_MASK_INT 0x018 +#define REG_I2S_RX_STATUS_INT 0x01c + + + +#define REG_I2S_TX_PAGE0_OWN 0x020 +#define REG_I2S_TX_PAGE1_OWN 0x024 +#define REG_I2S_TX_PAGE2_OWN 0x028 +#define REG_I2S_TX_PAGE3_OWN 0x02C +#define REG_I2S_RX_PAGE0_OWN 0x030 +#define REG_I2S_RX_PAGE1_OWN 0x034 +#define REG_I2S_RX_PAGE2_OWN 0x038 +#define REG_I2S_RX_PAGE3_OWN 0x03C +*/ +/* template +#define BIT_SHIFT_CTLX_ 7 +#define BIT_MASK_CTLX_ 0x1 +#define BIT_CTLX_(x) (((x) & BIT_MASK_CTLX_) << BIT_SHIFT_CTLX_) +#define BIT_INV_CTLX_ (~(BIT_MASK_CTLX_ << BIT_SHIFT_CTLX_)) +*//* +#define BIT_SHIFT_CTLX_IIS_EN 0 +#define BIT_MASK_CTLX_IIS_EN 0x1 +#define BIT_CTLX_IIS_EN(x) (((x) & BIT_MASK_CTLX_IIS_EN) << BIT_SHIFT_CTLX_IIS_EN) +#define BIT_INV_CTLX_IIS_EN (~(BIT_MASK_CTLX_IIS_EN << BIT_SHIFT_CTLX_IIS_EN)) + +#define BIT_SHIFT_CTLX_TRX 1 +#define BIT_MASK_CTLX_TRX 0x3 +#define BIT_CTLX_TRX(x) (((x) & BIT_MASK_CTLX_TRX) << BIT_SHIFT_CTLX_TRX) +#define BIT_INV_CTLX_TRX (~(BIT_MASK_CTLX_TRX << BIT_SHIFT_CTLX_TRX)) + +#define BIT_SHIFT_CTLX_CH_NUM 3 +#define BIT_MASK_CTLX_CH_NUM 0x3 +#define BIT_CTLX_CH_NUM(x) (((x) & BIT_MASK_CTLX_CH_NUM) << BIT_SHIFT_CTLX_CH_NUM) +#define BIT_INV_CTLX_CH_NUM (~(BIT_MASK_CTLX_CH_NUM << BIT_SHIFT_CTLX_CH_NUM)) + +#define BIT_SHIFT_CTLX_EDGE_SW 5 +#define BIT_MASK_CTLX_EDGE_SW 0x1 +#define BIT_CTLX_EDGE_SW(x) (((x) & BIT_MASK_CTLX_EDGE_SW) << BIT_SHIFT_CTLX_EDGE_SW) +#define BIT_INV_CTLX_EDGE_SW (~(BIT_MASK_CTLX_EDGE_SW << BIT_SHIFT_CTLX_EDGE_SW)) + +#define BIT_SHIFT_CTLX_WL 6 +#define BIT_MASK_CTLX_WL 0x1 +#define BIT_CTLX_WL(x) (((x) & BIT_MASK_CTLX_WL) << BIT_SHIFT_CTLX_WL) +#define BIT_INV_CTLX_WL (~(BIT_MASK_CTLX_WL << BIT_SHIFT_CTLX_WL)) + +#define BIT_SHIFT_CTLX_LOOP_BACK 7 +#define BIT_MASK_CTLX_LOOP_BACK 0x1 +#define BIT_CTLX_LOOP_BACK(x) (((x) & BIT_MASK_CTLX_LOOP_BACK) << BIT_SHIFT_CTLX_LOOP_BACK) +#define BIT_INV_CTLX_LOOP_BACK (~(BIT_MASK_CTLX_LOOP_BACK << BIT_SHIFT_CTLX_LOOP_BACK)) + +#define BIT_SHIFT_CTLX_FORMAT 8 +#define BIT_MASK_CTLX_FORMAT 0x3 +#define BIT_CTLX_FORMAT(x) (((x) & BIT_MASK_CTLX_FORMAT) << BIT_SHIFT_CTLX_FORMAT) +#define BIT_INV_CTLX_FORMAT (~(BIT_MASK_CTLX_FORMAT << BIT_SHIFT_CTLX_FORMAT)) + +#define BIT_SHIFT_CTLX_LRSWAP 10 +#define BIT_MASK_CTLX_LRSWAP 0x1 +#define BIT_CTLX_LRSWAP(x) (((x) & BIT_MASK_CTLX_LRSWAP) << BIT_SHIFT_CTLX_LRSWAP) +#define BIT_INV_CTLX_LRSWAP (~(BIT_MASK_CTLX_LRSWAP << BIT_SHIFT_CTLX_LRSWAP)) + +#define BIT_SHIFT_CTLX_SCK_INV 11 +#define BIT_MASK_CTLX_SCK_INV 0x1 +#define BIT_CTLX_SCK_INV(x) (((x) & BIT_MASK_CTLX_SCK_INV) << BIT_SHIFT_CTLX_SCK_INV) +#define BIT_INV_CTLX_SCK_INV (~(BIT_MASK_CTLX_SCK_INV << BIT_SHIFT_CTLX_SCK_INV)) + +#define BIT_SHIFT_CTLX_ENDIAN_SWAP 12 +#define BIT_MASK_CTLX_ENDIAN_SWAP 0x1 +#define BIT_CTLX_ENDIAN_SWAP(x) (((x) & BIT_MASK_CTLX_ENDIAN_SWAP) << BIT_SHIFT_CTLX_ENDIAN_SWAP) +#define BIT_INV_CTLX_ENDIAN_SWAP (~(BIT_MASK_CTLX_ENDIAN_SWAP << BIT_SHIFT_CTLX_ENDIAN_SWAP)) + +#define BIT_SHIFT_CTLX_DEBUG_SWITCH 15 +#define BIT_MASK_CTLX_DEBUG_SWITCH 0x3 +#define BIT_CTLX_DEBUG_SWITCH(x) (((x) & BIT_MASK_CTLX_DEBUG_SWITCH) << BIT_SHIFT_CTLX_DEBUG_SWITCH) +#define BIT_INV_CTLX_DEBUG_SWITCH (~(BIT_MASK_CTLX_DEBUG_SWITCH << BIT_SHIFT_CTLX_DEBUG_SWITCH)) + +#define BIT_SHIFT_CTLX_SLAVE_SEL 29 +#define BIT_MASK_CTLX_SLAVE_SEL 0x1 +#define BIT_CTLX_SLAVE_SEL(x) (((x) & BIT_MASK_CTLX_SLAVE_SEL) << BIT_SHIFT_CTLX_SLAVE_SEL) +#define BIT_INV_CTLX_SLAVE_SEL (~(BIT_MASK_CTLX_SLAVE_SEL << BIT_SHIFT_CTLX_SLAVE_SEL)) + +#define BIT_SHIFT_CTLX_CLK_SRC 30 +#define BIT_MASK_CTLX_CLK_SRC 0x1 +#define BIT_CTLX_CLK_SRC(x) (((x) & BIT_MASK_CTLX_CLK_SRC) << BIT_SHIFT_CTLX_CLK_SRC) +#define BIT_INV_CTLX_CLK_SRC (~(BIT_MASK_CTLX_CLK_SRC << BIT_SHIFT_CTLX_CLK_SRC)) + +#define BIT_SHIFT_CTLX_SW_RSTN 31 +#define BIT_MASK_CTLX_SW_RSTN 0x1 +#define BIT_CTLX_SW_RSTN(x) (((x) & BIT_MASK_CTLX_SW_RSTN) << BIT_SHIFT_CTLX_SW_RSTN) +#define BIT_INV_CTLX_SW_RSTN (~(BIT_MASK_CTLX_SW_RSTN << BIT_SHIFT_CTLX_SW_RSTN)) + + +#define BIT_SHIFT_SETTING_PAGE_SZ 0 +#define BIT_MASK_SETTING_PAGE_SZ 0xFFF +#define BIT_SETTING_PAGE_SZ(x) (((x) & BIT_MASK_SETTING_PAGE_SZ) << BIT_SHIFT_SETTING_PAGE_SZ) +#define BIT_INV_SETTING_PAGE_SZ (~(BIT_MASK_SETTING_PAGE_SZ << BIT_SHIFT_SETTING_PAGE_SZ)) + +#define BIT_SHIFT_SETTING_PAGE_NUM 12 +#define BIT_MASK_SETTING_PAGE_NUM 0x3 +#define BIT_SETTING_PAGE_NUM(x) (((x) & BIT_MASK_SETTING_PAGE_NUM) << BIT_SHIFT_SETTING_PAGE_NUM) +#define BIT_INV_SETTING_PAGE_NUM (~(BIT_MASK_SETTING_PAGE_NUM << BIT_SHIFT_SETTING_PAGE_NUM)) + +#define BIT_SHIFT_SETTING_SAMPLE_RATE 14 +#define BIT_MASK_SETTING_SAMPLE_RATE 0x7 +#define BIT_SETTING_SAMPLE_RATE(x) (((x) & BIT_MASK_SETTING_SAMPLE_RATE) << BIT_SHIFT_SETTING_SAMPLE_RATE) +#define BIT_INV_SETTING_SAMPLE_RATE (~(BIT_MASK_SETTING_SAMPLE_RATE << BIT_SHIFT_SETTING_SAMPLE_RATE)) +*/ + +typedef enum _I2S_CTL_FORMAT { + FormatI2s = 0x00, + FormatLeftJustified = 0x01, + FormatRightJustified = 0x02 +}I2S_CTL_FORMAT, *PI2S_CTL_FORMAT; + +typedef enum _I2S_CTL_CHNUM { + ChannelStereo = 0x00, + Channel5p1 = 0x01, + ChannelMono = 0x02 +}I2S_CTL_CHNUM, *PI2S_CTL_CHNUM; + +typedef enum _I2S_CTL_TRX_ACT { + RxOnly = 0x00, + TxOnly = 0x01, + TXRX = 0x02 +}I2S_CTL_TRX_ACT, *PI2S_CTL_TRX_ACT; +/* +typedef struct _I2S_CTL_REG_ { + I2S_CTL_FORMAT Format; + I2S_CTL_CHNUM ChNum; + I2S_CTL_TRX_ACT TrxAct; + + u32 I2s_En :1; // Bit 0 + u32 Rsvd1to4 :4; // Bit 1-4 is TrxAct, ChNum + u32 EdgeSw :1; // Bit 5 Edge switch + u32 WordLength :1; // Bit 6 + u32 LoopBack :1; // Bit 7 + u32 Rsvd8to9 :2; // Bit 8-9 is Format + u32 DacLrSwap :1; // Bit 10 + u32 SckInv :1; // Bit 11 + u32 EndianSwap :1; // Bit 12 + u32 Rsvd13to14 :2; // Bit 11-14 + u32 DebugSwitch :2; // Bit 15-16 + u32 Rsvd17to28 :12; // Bit 17-28 + u32 SlaveMode :1; // Bit 29 + u32 SR44p1KHz :1; // Bit 30 + u32 SwRstn :1; // Bit 31 +} I2S_CTL_REG, *PI2S_CTL_REG; +*/ +typedef enum _I2S_SETTING_PAGE_NUM { + I2s1Page = 0x00, + I2s2Page = 0x01, + I2s3Page = 0x02, + I2s4Page = 0x03 +}I2S_SETTING_PAGE_NUM, *PI2S_SETTING_PAGE_NUM; + +//sampling rate +typedef enum _I2S_SETTING_SR { + I2sSR8K = 0x00, + I2sSR16K = 0x01, + I2sSR24K = 0x02, + I2sSR32K = 0x03, + I2sSR48K = 0x05, + I2sSR44p1K = 0x15, + I2sSR96K = 0x06, + I2sSR88p2K = 0x16 +}I2S_SETTING_SR, *PI2S_SETTING_SR; +/* +typedef struct _I2S_SETTING_REG_ { + I2S_SETTING_PAGE_NUM PageNum; + I2S_SETTING_SR SampleRate; + + u32 PageSize:12; // Bit 0-11 +}I2S_SETTING_REG, *PI2S_SETTING_REG; + +typedef enum _I2S_TX_ISR { + I2sTxP0OK = 0x01, + I2sTxP1OK = 0x02, + I2sTxP2OK = 0x04, + I2sTxP3OK = 0x08, + I2sTxPageUn = 0x10, + I2sTxFifoEmpty = 0x20 +}I2S_TX_ISR, *PI2S_TX_ISR; + +typedef enum _I2S_RX_ISR { + I2sRxP0OK = 0x01, + I2sRxP1OK = 0x02, + I2sRxP2OK = 0x04, + I2sRxP3OK = 0x08, + I2sRxPageUn = 0x10, + I2sRxFifoFull = 0x20 +}I2S_RX_ISR, *PI2S_RX_ISR; +*/ + +/* Hal I2S function prototype*/ +RTK_STATUS +HalI2SInitRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SInitRtl8195a_Patch( + IN VOID *Data +); + +RTK_STATUS +HalI2SDeInitRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2STxRtl8195a( + IN VOID *Data, + IN u8 *pBuff +); + +RTK_STATUS +HalI2SRxRtl8195a( + IN VOID *Data, + OUT u8 *pBuff +); + +RTK_STATUS +HalI2SEnableRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SIntrCtrlRtl8195a( + IN VOID *Data +); + +u32 +HalI2SReadRegRtl8195a( + IN VOID *Data, + IN u8 I2SReg +); + +RTK_STATUS +HalI2SSetRateRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetWordLenRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetChNumRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetPageNumRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetPageSizeRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetDirectionRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SSetDMABufRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SClrIntrRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SClrAllIntrRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SDMACtrlRtl8195a( + IN VOID *Data +); + +u8 +HalI2SGetTxPageRtl8195a( + IN VOID *Data +); + +u8 +HalI2SGetRxPageRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SPageSendRtl8195a( + IN VOID *Data, + IN u8 PageIdx +); + +RTK_STATUS +HalI2SPageRecvRtl8195a( + IN VOID *Data +); + +RTK_STATUS +HalI2SClearAllOwnBitRtl8195a( + IN VOID *Data +); + +#ifdef CONFIG_CHIP_E_CUT +_LONG_CALL_ RTK_STATUS +HalI2SInitRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetRateRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetWordLenRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetChNumRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetPageNumRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetPageSizeRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetDirectionRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SSetDMABufRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ u8 +HalI2SGetTxPageRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ u8 +HalI2SGetRxPageRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SPageSendRtl8195a_V04( + IN VOID *Data, + IN u8 PageIdx +); + +_LONG_CALL_ RTK_STATUS +HalI2SPageRecvRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ RTK_STATUS +HalI2SClearAllOwnBitRtl8195a_V04( + IN VOID *Data +); + +#endif // #ifdef CONFIG_CHIP_E_CUT + +// HAL functions Wrapper +static __inline VOID +HalI2SSetRate( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetRateRtl8195a(Data); +#else + HalI2SSetRateRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetWordLen( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetWordLenRtl8195a(Data); +#else + HalI2SSetWordLenRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetChNum( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetChNumRtl8195a(Data); +#else + HalI2SSetChNumRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetPageNum( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetPageNumRtl8195a(Data); +#else + HalI2SSetPageNumRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetPageSize( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetPageSizeRtl8195a(Data); +#else + HalI2SSetPageSizeRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetDirection( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetDirectionRtl8195a(Data); +#else + HalI2SSetDirectionRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SSetDMABuf( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SSetDMABufRtl8195a(Data); +#else + HalI2SSetDMABufRtl8195a_V04(Data); +#endif +} + +static __inline u8 +HalI2SGetTxPage( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + return HalI2SGetTxPageRtl8195a(Data); +#else + return HalI2SGetTxPageRtl8195a_V04(Data); +#endif +} + +static __inline u8 +HalI2SGetRxPage( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + return HalI2SGetRxPageRtl8195a(Data); +#else + return HalI2SGetRxPageRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SPageSend( + IN VOID *Data, + IN u8 PageIdx +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SPageSendRtl8195a(Data, PageIdx); +#else + HalI2SPageSendRtl8195a_V04(Data, PageIdx); +#endif +} + +static __inline VOID +HalI2SPageRecv( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SPageRecvRtl8195a(Data); +#else + HalI2SPageRecvRtl8195a_V04(Data); +#endif +} + +static __inline VOID +HalI2SClearAllOwnBit( + IN VOID *Data +) +{ +#ifndef CONFIG_CHIP_E_CUT + HalI2SClearAllOwnBitRtl8195a(Data); +#else + HalI2SClearAllOwnBitRtl8195a_V04(Data); +#endif +} + +#endif /* _RTL8195A_I2S_H_ */ + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_mii.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_mii.h new file mode 100644 index 0000000..c243523 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_mii.h @@ -0,0 +1,675 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_MII_H_ +#define _RTL8195A_MII_H_ + +#include "basic_types.h" +#include "hal_api.h" + + + +#define MII_TX_DESC_NO 8 +#define MII_RX_DESC_NO 8 +#define MII_BUF_SIZE 1536 +#define MAX_FRAME_SIZE 1514 + + +#define HAL_MII_READ32(addr) HAL_READ32(MII_REG_BASE, addr) +#define HAL_MII_WRITE32(addr, value) HAL_WRITE32(MII_REG_BASE, addr, value) +#define HAL_MII_READ16(addr) HAL_READ16(MII_REG_BASE, addr) +#define HAL_MII_WRITE16(addr, value) HAL_WRITE16(MII_REG_BASE, addr, value) +#define HAL_MII_READ8(addr) HAL_READ8(MII_REG_BASE, addr) +#define HAL_MII_WRITE8(addr, value) HAL_WRITE8(MII_REG_BASE, addr, value) + +/* =============== MAC Register Offset Definition =============== */ +#define REG_MII_IDR0 0x0000 +#define REG_MII_IDR4 0x0004 +#define REG_MII_COM 0x0038 +#define REG_MII_ISRIMR 0x003C +#define REG_MII_TC 0x0040 +#define REG_MII_RC 0x0044 +#define REG_MII_MS 0x0058 +#define REG_MII_MIIA 0x005C + +#define REG_MII_TXFDP1 0x1300 +#define REG_MII_RXFDP1 0x13F0 +#define REG_MII_ETNRXCPU1 0x1430 +#define REG_MII_IOCMD 0x1434 +#define REG_MII_IOCMD1 0x1438 + +/* =============== MAC Register BIT Definition =============== */ +/* Command Register (0x38) */ +#define COM_RST BIT0 +#define COM_RXCHKSUM BIT1 +#define COM_RXJUMBO BIT3 + +/* Interrupt Status & Interrupt Mask Register (0x3C & 0x3E) */ +#define ISR_RXOK BIT0 +#define ISR_RER_RUNT BIT2 +#define ISR_RER_OVF BIT4 +#define ISR_RDU BIT5 +#define ISR_TXOK BIT6 +#define ISR_TER BIT7 +#define ISR_LINKCHG BIT8 +#define ISR_TDU BIT9 +#define ISR_CLR_ALL 0x0000FFFF +#define IMR_RXOK BIT16 +#define IMR_RER_RUNT BIT18 +#define IMR_RER_OVF BIT20 +#define IMR_RDU BIT21 +#define IMR_TXOK BIT22 +#define IMR_TER BIT23 +#define IMR_LINKCHG BIT24 +#define IMR_TDU BIT25 + +/* Transmit Configuration Register (0x40) */ +#define TC_TX_NOPADDING BIT0 +#define TC_NORMAL_MODE 0 +#define TC_LBK_R2T 1 +#define TC_LBK_T2R 3 +#define TC_LBK_MASK 0x00000300 // bit[9:8] +#define TC_IFG_TIME 3 // 9.6 us for 10Mbps, 960 ns for 100Mbps +#define TC_IFG_MASK 0x00001C00 // bit[12:10] + +/* Receive Configuration Register (0x44) */ +#define RC_AAP BIT0 +#define RC_APM BIT1 +#define RC_AM BIT2 +#define RC_AB BIT3 +#define RC_AR BIT4 +#define RC_AER BIT5 + +/* Media Status Register (0x58) */ +#define MS_LINKB BIT26 + +/* MII Access Register (0x5C) */ +#define MIIA_FLAG BIT31 // 1: Write, 0: Read +#define MIIA_PHY_ADDR_MASK 0x7C000000 // bit[30:26] +#define MIIA_PHY_REG_ADDR_MASK 0x001F0000 // bit[20:16] + +/* IO Command Register (0x1434) */ +#define IOCMD_TXFN1ST BIT0 +#define IOCMD_TE BIT4 +#define IOCMD_RE BIT5 +#define IOCMD_RXFTH_1024 0 +#define IOCMD_RXFTH_128 1 +#define IOCMD_RXFTH_256 2 +#define IOCMD_RXFTH_512 3 +#define IOCMD_RXFTH_MASK 0x00001800 // bit[12:11] +#define IOCMD_TXFTH_128 0 +#define IOCMD_TXFTH_256 1 +#define IOCMD_TXFTH_512 2 +#define IOCMD_TXFTH_1024 3 +#define IOCMD_TXFTH_MASK 0x00180000 // bit[20:19] +#define IOCMD_SHORT_DES_FMT BIT30 + +/* IO Command1 Register (0x1438) */ +#define IOCMD1_RXRING1 BIT16 +#define IOCMD1_EN_1GB BIT24 +#define IOCMD1_DSC_FMT_EXTRA 0x3 // 011 +#define IOCMD1_DSCFMTEXTRA_MASK 0x70000000 // bit[30:28] + +/* =============== PHY (RTL8201F) Register Bit Definition =============== */ +#define PHY_ADDRESS 0x1 // 5 bits +#define PHY_REG0_ADDR 0x0 // 5 bits +#define PHY_REG1_ADDR 0x1 // 5 bits + +/* Register 0 */ +#define PHY_SPEED_MSB BIT6 +#define PHY_DUPLEX_MODE BIT8 +#define PHY_RESTART_NWAY BIT9 +#define PHY_NWAY_EN BIT12 +#define PHY_SPEED_LSB BIT13 +#define PHY_SW_RESET BIT15 + +/* Register 1 */ +#define PHY_LINK_STATUS BIT2 +#define PHY_NWAY_COMPLETE BIT5 + +/* =============== Tx/Rx Descriptor Bit Definition =============== */ +#define TX_DESC_OWN BIT31 +#define TX_DESC_EOR BIT30 +#define TX_DESC_FS BIT29 +#define TX_DESC_LS BIT28 +#define TX_DESC_CRC BIT23 +#define TX_DESC_DATA_LEN_MASK 0x1FFFF // bit[16:0] +#define TX_DESC_VLAN_INTACT 0 +#define TX_DESC_VLAN_INSERT 1 +#define TX_DESC_VLAN_REMOVE 2 +#define TX_DESC_VLAN_REMARKING 3 +#define TX_DESC_VLAN_ACT_MASK 0x06000000 +#define C_VLAN_HDR 0x8100279F +#define S_VLAN_HDR 0x88A8279F +#define TX_DESC_VLAN_TAG_MASK 0x0000FFFF + +#define RX_DESC_OWN BIT31 +#define RX_DESC_EOR BIT30 +#define RX_DESC_PKT_TYPE_MASK 0x001E0000 // bit[20:17] +#define RX_DESC_DATA_LEN_MASK 0xFFF // bit[11:0] + + +typedef struct _TX_DESC_FMT_ +{ + u32 dw1; // offset 0 + u32 addr; // offset 4 + u32 dw2; // offset 8 + u32 dw3; // offset 12 + u32 dw4; // offset 16 +}TX_DESC_FMT, *PTX_DESC_FMT; + +typedef struct _RX_DESC_FMT_ +{ + u32 dw1; // offset 0 + u32 addr; // offset 4 + u32 dw2; // offset 8 + u32 dw3; // offset 12 +}RX_DESC_FMT, *PRX_DESC_FMT; + + + +VOID +HalMiiInitIrqRtl8195a( + IN VOID *Data +); + +s32 +HalMiiInitRtl8195a( + IN VOID +); + +VOID +HalMiiDeInitRtl8195a( + IN VOID +); + +s32 +HalMiiWriteDataRtl8195a( + IN const char *Data, + IN u32 Size +); + +u32 +HalMiiSendPacketRtl8195a( + IN VOID +); + +u32 +HalMiiReceivePacketRtl8195a( + IN VOID +); + +u32 +HalMiiReadDataRtl8195a( + IN u8 *Data, + IN u32 Size +); + +VOID +HalMiiGetMacAddressRtl8195a( + IN u8 *Addr +); + +u32 +HalMiiGetLinkStatusRtl8195a( + IN VOID +); + +VOID +HalMiiForceLinkRtl8195a( + IN s32 Speed, + IN s32 Duplex +); + + + +#ifdef CONFIG_MII_VERIFY + +/* Ethernet Module registers */ +#define REG_RTL_MII_IDR0 0x0000 // Table 2 IDR0 (Offset 0000h-0003h, R/W) +#define REG_RTL_MII_IDR4 0x0004 // Table 3 IDR4 (Offset 0004h-0007h, R/W) +#define REG_RTL_MII_MAR0 0x0008 // Table 4 MAR0 (Offset 0008h-000bh, R/W) +#define REG_RTL_MII_MAR4 0x000C // Table 5 MAR4 (Offset 000ch-000fh, R/W) +#define REG_RTL_MII_CR 0x0038 // Table 21 Command Register (COM_REG, Offset 0038-003Bh, R/W) +#define REG_RTL_MII_IMRISR 0x003C // Table 22 + Table 23 +#define REG_RTL_MII_TCR 0x0040 // Table 24 Transmit Configuration Register (TC_REG, Offset 0040h-0043h, R/W) +#define REG_RTL_MII_RCR 0x0044 // Table 25 Receive Configuration Register (RC_REG, Offset 0044h-0047h, R/W) +#define REG_RTL_MII_CTCR 0x0048 // Table 26 CPU Tag Control Register (CPUTAG_REG, Offset 0048h-004bh, R/W) +#define REG_RTL_MII_CONFIG 0x004C // Table 27 Configuration Register (CONFIG_REG, Offset 004ch-004fh, R/W) +#define REG_RTL_MII_CTCR1 0x0050 // Table 28 CPUTAG1 Register (CPUTAG1_REG, Offset 0050h-0053h, R/W) +#define REG_RTL_MII_MSR 0x0058 // Table 29 Media Status Register (MS_reg: Offset 0058h ??005bh, R/W) +#define REG_RTL_MII_MIIAR 0x005C // Table 30 MII Access Register (MIIA_REG, Offset 005c-005fh, R/W) +#define REG_RTL_MII_VR 0x0064 // Table 32 VLAN Register (VLAN_REG, Offset 0064-0067h, R/W) +#define REG_RTL_MII_IMR0 0x00D0 // Table 50 IMR0_REG (IMR0_REG, Offset D0h-D3h) +#define REG_RTL_MII_IMR1 0x00D4 // Table 51 IMR1_REG (IMR1_REG, Offset d4h-d7h) +#define REG_RTL_MII_ISR1 0x00D8 // Table 52 ISR1 Register (ISR1_REG, Offset D8h-DBh) +#define REG_RTL_MII_INTR 0x00DC // Table 53 Interrupt routing register (INTR_REG, Offset DCh-DFh) +#define REG_RTL_MII_CCR 0x00E4 // Table xx Clock Control Register (CLKCTL_REG, Offset E4h-E7h) + +/* CPU Interface registers */ +#define REG_RTL_MII_TXFDP1 0x1300 // Table 55 TxFDP1 register (TXFDP1_REG, offset 1300h-1303h) +#define REG_RTL_MII_TXCDO1 0x1304 // Table 56 TxCDO1 register (TXCDO1_REG, offset 1304h-1305h) +#define REG_RTL_MII_TXFDP2 0x1310 // Table 57 TxFDP2 register (TXFDP2_REG, offset 1310h-1313h) +#define REG_RTL_MII_TXCDO2 0x1314 // Table 58 TxCDO2 register (TXCDO2_REG, offset 1314h-1315h) +#define REG_RTL_MII_TXFDP3 0x1320 // Table 59 TxFDP3 register (TXFDP3_REG, offset 1320h-1323h) +#define REG_RTL_MII_TXCDO3 0x1324 // Table 60 TxCDO3 register (TXCDO3_REG, offset 1324h-1325h) +#define REG_RTL_MII_TXFDP4 0x1330 // Table 61 TxFDP4 register (TXFDP4_REG, offset 1330h-1333h) +#define REG_RTL_MII_TXCDO4 0x1334 // Table 62 TxCDO4 register (TXCDO4_REG, offset 1334h-1335h) +#define REG_RTL_MII_TXFDP5 0x1340 // Table 63 TxFDP5 register (TXFDP5_REG, offset 1340h-1343h) +#define REG_RTL_MII_TXCDO5 0x1344 // Table 64 TxCDO5 register (TXCDO5_REG, offset 1344h-1345h) +#define REG_RTL_MII_RXFDP2 0x1390 // Table 66 RxFDP2 register (RXFDP#_REG, offset 1390h-1393h) +#define REG_RTL_MII_RXFDP1 0x13F0 // Table 71 RxFDP1 register (RXFDP1_REG, offset 13F0h-13F3h) +#define REG_RTL_MII_RXRS1 0x13F6 // Table 73 Rx Ring Size1 register (RX_RS1_REG, offset 13F6h-13F7h) + +#define REG_RTL_MII_RX_PSE1 0x142C // Table 77 Rx_Pse_Des_Thres_1_h (RX_PSE1_REG, Offset 142ch) +#define REG_RTL_MII_ETNRXCPU1 0x1430 // Table 79 EhtrntRxCPU_Des_Num1 (ETNRXCPU1_REG, Offset 1430h-1433h) +#define REG_RTL_MII_IOCMD 0x1434 // Table 80 Ethernet_IO_CMD (ETN_IO_CMD_REG, Offset 1434h-1437h) +#define REG_RTL_MII_IOCMD1 0x1438 // Table 81 Ethernet_IO_CMD1 (IO_CMD1_REG: Offset 1438h-143bh) + + +#define CMD_CONFIG 0x00081000 + +//2014-04-29 yclin (disable [27] r_en_precise_dma) +// #define CMD1_CONFIG 0x39000000 +#define CMD1_CONFIG 0x31000000 + +// #define MAX_RX_DESC_SIZE 6 +#define MAX_RX_DESC_SIZE 1 +#define MAX_TX_DESC_SIZE 5 + +// 0058h +#define BIT_SHIFT_MSR_FORCE_SPEED_SELECT 16 +#define BIT_MASK_MSR_FORCE_SPEED_SELECT 0x3 +#define BIT_MSR_FORCE_SPEED_SELECT(x)(((x) & BIT_MASK_MSR_FORCE_SPEED_SELECT) << BIT_SHIFT_MSR_FORCE_SPEED_SELECT) +#define BIT_INVC_MSR_FORCE_SPEED_SELECT (~(BIT_MASK_MSR_FORCE_SPEED_SELECT << BIT_SHIFT_MSR_FORCE_SPEED_SELECT)) + +#define BIT_SHIFT_MSR_FORCE_SPEED_MODE_ENABLE 10 +#define BIT_MASK_MSR_FORCE_SPEED_MODE_ENABLE 0x1 +#define BIT_MSR_FORCE_SPEED_MODE_ENABLE(x)(((x) & BIT_MASK_MSR_FORCE_SPEED_MODE_ENABLE) << BIT_SHIFT_MSR_FORCE_SPEED_MODE_ENABLE) +#define BIT_INVC_MSR_FORCE_SPEED_MODE_ENABLE (~(BIT_MASK_MSR_FORCE_SPEED_MODE_ENABLE << BIT_SHIFT_MSR_FORCE_SPEED_MODE_ENABLE)) + +// 1434h +#define BIT_SHIFT_IOCMD_RXENABLE 5 +#define BIT_MASK_IOCMD_RXENABLE 0x1 +#define BIT_IOCMD_RXENABLE(x)(((x) & BIT_MASK_IOCMD_RXENABLE) << BIT_SHIFT_IOCMD_RXENABLE) +#define BIT_INVC_IOCMD_RXENABLE (~(BIT_MASK_IOCMD_RXENABLE << BIT_SHIFT_IOCMD_RXENABLE)) + +#define BIT_SHIFT_IOCMD_TXENABLE 4 +#define BIT_MASK_IOCMD_TXENABLE 0x1 +#define BIT_IOCMD_TXENABLE(x)(((x) & BIT_MASK_IOCMD_TXENABLE) << BIT_SHIFT_IOCMD_TXENABLE) +#define BIT_INVC_IOCMD_TXENABLE (~(BIT_MASK_IOCMD_TXENABLE << BIT_SHIFT_IOCMD_TXENABLE)) + +#define BIT_SHIFT_IOCMD_FIRST_DMATX_ENABLE 0 +#define BIT_MASK_IOCMD_FIRST_DMATX_ENABLE 0x1 +#define BIT_IOCMD_FIRST_DMATX_ENABLE(x)(((x) & BIT_MASK_IOCMD_FIRST_DMATX_ENABLE) << BIT_SHIFT_IOCMD_FIRST_DMATX_ENABLE) +#define BIT_INVC_IOCMD_FIRST_DMATX_ENABLE (~(BIT_MASK_IOCMD_FIRST_DMATX_ENABLE << BIT_SHIFT_IOCMD_FIRST_DMATX_ENABLE)) + +// 1438h +#define BIT_SHIFT_IOCMD1_FIRST_DMARX_ENABLE 16 +#define BIT_MASK_IOCMD1_FIRST_DMARX_ENABLE 0x1 +#define BIT_IOCMD1_FIRST_DMARX_ENABLE(x)(((x) & BIT_MASK_IOCMD1_FIRST_DMARX_ENABLE) << BIT_SHIFT_IOCMD1_FIRST_DMARX_ENABLE) +#define BIT_INVC_IOCMD1_FIRST_DMARX_ENABLE (~(BIT_MASK_IOCMD1_FIRST_DMARX_ENABLE << BIT_SHIFT_IOCMD1_FIRST_DMARX_ENABLE)) + + +/** + * 1.4.1.7 Tx command descriptor used in RL6266 + * 5 dobule words + */ +typedef struct _TX_INFO_ { + union { + struct { + u32 own:1; //31 + u32 eor:1; //30 + u32 fs:1; //29 + u32 ls:1; //28 + u32 ipcs:1; //27 + u32 l4cs:1; //26 + u32 keep:1; //25 + u32 blu:1; //24 + u32 crc:1; //23 + u32 vsel:1; //22 + u32 dislrn:1; //21 + u32 cputag_ipcs:1; //20 + u32 cputag_l4cs:1; //19 + u32 cputag_psel:1; //18 + u32 rsvd:1; //17 + u32 data_length:17; //0~16 + } bit; + u32 dw; //double word + } opts1; + + u32 addr; + + union { + struct { + u32 cputag:1; //31 + u32 aspri:1; //30 + u32 cputag_pri:3; //27~29 + u32 tx_vlan_action:2; //25~26 + u32 tx_pppoe_action:2; //23~24 + u32 tx_pppoe_idx:3; //20~22 + u32 efid:1; //19 + u32 enhance_fid:3; //16~18 + u32 vidl:8; // 8~15 + u32 prio:3; // 5~7 + u32 cfi:1; // 4 + u32 vidh:4; // 0~3 + } bit; + u32 dw; //double word + } opts2; + + union { + struct { + u32 extspa:3; //29~31 + u32 tx_portmask:6; //23~28 + u32 tx_dst_stream_id:7; //16~22 + u32 rsvd:14; // 2~15 + u32 l34keep:1; // 1 + u32 ptp:1; // 0 + } bit; + u32 dw; //double word + } opts3; + + union { + struct { + u32 lgsen:1; //31 + u32 lgmss:11; //20~30 + u32 rsvd:20; // 0~19 + } bit; + u32 dw; //double word + } opts4; + +} TX_INFO, *PTX_INFO; + +typedef struct _RX_INFO_ { + union{ + struct{ + u32 own:1; //31 + u32 eor:1; //30 + u32 fs:1; //29 + u32 ls:1; //28 + u32 crcerr:1; //27 + u32 ipv4csf:1; //26 + u32 l4csf:1; //25 + u32 rcdf:1; //24 + u32 ipfrag:1; //23 + u32 pppoetag:1; //22 + u32 rwt:1; //21 + u32 pkttype:4; //20-17 + u32 l3routing:1; //16 + u32 origformat:1; //15 + u32 pctrl:1; //14 +#ifdef CONFIG_RG_JUMBO_FRAME + u32 data_length:14; //13~0 +#else + u32 rsvd:2; //13~12 + u32 data_length:12; //11~0 +#endif + }bit; + u32 dw; //double word + }opts1; + + u32 addr; + + union{ + struct{ + u32 cputag:1; //31 + u32 ptp_in_cpu_tag_exist:1; //30 + u32 svlan_tag_exist:1; //29 + u32 rsvd_2:2; //27~28 + u32 pon_stream_id:7; //20~26 + u32 rsvd_1:3; //17~19 + u32 ctagva:1; //16 + u32 cvlan_tag:16; //15~0 + }bit; + u32 dw; //double word + }opts2; + + union{ + struct{ + u32 src_port_num:5; //27~31 + u32 dst_port_mask:6; //21~26 + u32 reason:8; //13~20 + u32 internal_priority:3; //10~12 + u32 ext_port_ttl_1:5; //5~9 + u32 rsvd:5; //4~0 + }bit; + u32 dw; //double word + }opts3; +} RX_INFO, *PRX_INFO; + +/** + * GMAC_STATUS_REGS + */ +// TX/RX Descriptor Common +#define BIT_SHIFT_GMAC_DESCOWN 31 +#define BIT_MASK_GMAC_DESCOWN 0x1 +#define BIT_GMAC_DESCOWN(x)(((x) & BIT_MASK_GMAC_DESCOWN) << BIT_SHIFT_GMAC_DESCOWN) +#define BIT_INVC_GMAC_DESCOWN (~(BIT_MASK_GMAC_DESCOWN << BIT_SHIFT_GMAC_DESCOWN)) + +#define BIT_SHIFT_GMAC_RINGEND 30 +#define BIT_MASK_GMAC_RINGEND 0x1 +#define BIT_GMAC_RINGEND(x)(((x) & BIT_MASK_GMAC_RINGEND) << BIT_SHIFT_GMAC_RINGEND) +#define BIT_INVC_GMAC_RINGEND (~(BIT_MASK_GMAC_RINGEND << BIT_SHIFT_GMAC_RINGEND)) + +#define BIT_SHIFT_GMAC_FIRSTFRAG 29 +#define BIT_MASK_GMAC_FIRSTFRAG 0x1 +#define BIT_GMAC_FIRSTFRAG(x)(((x) & BIT_MASK_GMAC_FIRSTFRAG) << BIT_SHIFT_GMAC_FIRSTFRAG) +#define BIT_INVC_GMAC_FIRSTFRAG (~(BIT_MASK_GMAC_FIRSTFRAG << BIT_SHIFT_GMAC_FIRSTFRAG)) + +#define BIT_SHIFT_GMAC_LASTFRAG 28 +#define BIT_MASK_GMAC_LASTFRAG 0x1 +#define BIT_GMAC_LASTFRAG(x)(((x) & BIT_MASK_GMAC_LASTFRAG) << BIT_SHIFT_GMAC_LASTFRAG) +#define BIT_INVC_GMAC_LASTFRAG (~(BIT_MASK_GMAC_LASTFRAG << BIT_SHIFT_GMAC_LASTFRAG)) + +// TX Descriptor opts1 +#define BIT_SHIFT_GMAC_IPCS 27 +#define BIT_MASK_GMAC_IPCS 0x1 +#define BIT_GMAC_IPCS(x)(((x) & BIT_MASK_GMAC_IPCS) << BIT_SHIFT_GMAC_IPCS) +#define BIT_INVC_GMAC_IPCS (~(BIT_MASK_GMAC_IPCS << BIT_SHIFT_GMAC_IPCS)) + +#define BIT_SHIFT_GMAC_L4CS 26 +#define BIT_MASK_GMAC_L4CS 0x1 +#define BIT_GMAC_L4CS(x)(((x) & BIT_MASK_GMAC_L4CS) << BIT_SHIFT_GMAC_L4CS) +#define BIT_INVC_GMAC_L4CS (~(BIT_MASK_GMAC_L4CS << BIT_SHIFT_GMAC_L4CS)) + +#define BIT_SHIFT_GMAC_KEEP 25 +#define BIT_MASK_GMAC_KEEP 0x1 +#define BIT_GMAC_KEEP(x)(((x) & BIT_MASK_GMAC_KEEP) << BIT_SHIFT_GMAC_KEEP) +#define BIT_INVC_GMAC_KEEP (~(BIT_MASK_GMAC_KEEP << BIT_SHIFT_GMAC_KEEP)) + +#define BIT_SHIFT_GMAC_BLU 24 +#define BIT_MASK_GMAC_BLU 0x1 +#define BIT_GMAC_BLU(x)(((x) & BIT_MASK_GMAC_BLU) << BIT_SHIFT_GMAC_BLU) +#define BIT_INVC_GMAC_BLU (~(BIT_MASK_GMAC_BLU << BIT_SHIFT_GMAC_BLU)) + +#define BIT_SHIFT_GMAC_TXCRC 23 +#define BIT_MASK_GMAC_TXCRC 0x1 +#define BIT_GMAC_TXCRC(x)(((x) & BIT_MASK_GMAC_TXCRC) << BIT_SHIFT_GMAC_TXCRC) +#define BIT_INVC_GMAC_TXCRC (~(BIT_MASK_GMAC_TXCRC << BIT_SHIFT_GMAC_TXCRC)) + +#define BIT_SHIFT_GMAC_VSEL 22 +#define BIT_MASK_GMAC_VSEL 0x1 +#define BIT_GMAC_VSEL(x)(((x) & BIT_MASK_GMAC_VSEL) << BIT_SHIFT_GMAC_VSEL) +#define BIT_INVC_GMAC_VSEL (~(BIT_MASK_GMAC_VSEL << BIT_SHIFT_GMAC_VSEL)) + +#define BIT_SHIFT_GMAC_DISLRN 21 +#define BIT_MASK_GMAC_DISLRN 0x1 +#define BIT_GMAC_DISLRN(x)(((x) & BIT_MASK_GMAC_DISLRN) << BIT_SHIFT_GMAC_DISLRN) +#define BIT_INVC_GMAC_DISLRN (~(BIT_MASK_GMAC_DISLRN << BIT_SHIFT_GMAC_DISLRN)) + +#define BIT_SHIFT_GMAC_CPUTAG_IPCS 20 +#define BIT_MASK_GMAC_CPUTAG_IPCS 0x1 +#define BIT_GMAC_CPUTAG_IPCS(x)(((x) & BIT_MASK_GMAC_CPUTAG_IPCS) << BIT_SHIFT_GMAC_CPUTAG_IPCS) +#define BIT_INVC_GMAC_CPUTAG_IPCS (~(BIT_MASK_GMAC_CPUTAG_IPCS << BIT_SHIFT_GMAC_CPUTAG_IPCS)) + +#define BIT_SHIFT_GMAC_CPUTAG_L4CS 19 +#define BIT_MASK_GMAC_CPUTAG_L4CS 0x1 +#define BIT_GMAC_CPUTAG_L4CS(x)(((x) & BIT_MASK_GMAC_CPUTAG_L4CS) << BIT_SHIFT_GMAC_CPUTAG_L4CS) +#define BIT_INVC_GMAC_CPUTAG_L4CS (~(BIT_MASK_GMAC_CPUTAG_L4CS << BIT_SHIFT_GMAC_CPUTAG_L4CS)) + +#define BIT_SHIFT_GMAC_CPUTAG_PSEL 18 +#define BIT_MASK_GMAC_CPUTAG_PSEL 0x1 +#define BIT_GMAC_CPUTAG_PSEL(x)(((x) & BIT_MASK_GMAC_CPUTAG_PSEL) << BIT_SHIFT_GMAC_CPUTAG_PSEL) +#define BIT_INVC_GMAC_CPUTAG_PSEL (~(BIT_MASK_GMAC_CPUTAG_PSEL << BIT_SHIFT_GMAC_CPUTAG_PSEL)) + + +typedef struct _PHY_MODE_INFO_ { + u8 PhyAddress; + u8 PhyMode; + u8 PhyInterface; +} PHY_MODE_INFO, *PPHY_MODE_INFO; + +typedef enum _PHY_MODE_SWITCH_ { + PHY_MODE_DISABLE = 0, + PHY_MODE_ENABLE = 1 +} PHY_MODE_SWITCH, *PPHY_MODE_SWITCH; + +typedef enum _PHY_INTERFACE_SELECT_ { + PHY_INTERFACE_ONE_WORKS = 0, + PHY_INTERFACE_ZERO_WORKS = 1 +} PHY_INTERFACE_SELECT, *PPHY_INTERFACE_SELECT; + +typedef enum _GMAC_MSR_FORCE_SPEED_ { + FORCE_SPD_100M = 0, + FORCE_SPD_10M = 1, + FORCE_SPD_GIGA = 2, + NO_FORCE_SPD = 3 +}GMAC_MSR_FORCE_SPEED, *PGMAC_MSR_FORCE_SPEED; + +typedef enum _GMAC_INTERRUPT_MASK_ { + GMAC_IMR_ROK = BIT16, + GMAC_IMR_CNT_WRAP = BIT17, + GMAC_IMR_RER_RUNT = BIT18, + // BIT19 Reserved + GMAC_IMR_RER_OVF = BIT20, + GMAC_IMR_RDU = BIT21, + GMAC_IMR_TOK_TI = BIT22, + GMAC_IMR_TER = BIT23, + GMAC_IMR_LINKCHG = BIT24, + GMAC_IMR_TDU = BIT25, + GMAC_IMR_SWINT = BIT26, + GMAC_IMR_RDU2 = BIT27, + GMAC_IMR_RDU3 = BIT28, + GMAC_IMR_RDU4 = BIT29, + GMAC_IMR_RDU5 = BIT30, + GMAC_IMR_RDU6 = BIT31, +} GMAC_INTERRUPT_MASK, *PGMAC_INTERRUPT_MASK; + +typedef enum _GMAC_INTERRUPT_STATUS_ { + GMAC_ISR_ROK = BIT0, + GMAC_ISR_CNT_WRAP = BIT1, + GMAC_ISR_RER_RUNT = BIT2, + // BIT3 Reserved + GMAC_ISR_RER_OVF = BIT4, + GMAC_ISR_RDU = BIT5, + GMAC_ISR_TOK_TI = BIT6, + GMAC_ISR_TER = BIT7, + GMAC_ISR_LINKCHG = BIT8, + GMAC_ISR_TDU = BIT9, + GMAC_ISR_SWINT = BIT10, + GMAC_ISR_RDU2 = BIT11, + GMAC_ISR_RDU3 = BIT12, + GMAC_ISR_RDU4 = BIT13, + GMAC_ISR_RDU5 = BIT14, + GMAC_ISR_RDU6 = BIT15, +} GMAC_INTERRUPT_STATUS, *PGMAC_INTERRUPT_STATUS; + +typedef enum _GMAC_TX_VLAN_ACTION_ { + INTACT = 0, + INSERT_VLAN_HDR = 1, + REMOVE_VLAN_HDR = 2, + REMARKING_VID = 3 +}GMAC_TX_VLAN_ACTION, *PGMAC_TX_VLAN_ACTION; + +typedef enum _GMAC_RX_PACKET_TYPE_ { + TYPE_ETHERNET = 0, + TYPE_IPV4 = 1, + TYPE_IPV4_PPTP = 2, + TYPE_IPV4_ICMP = 3, + TYPE_IPV4_IGMP = 4, + TYPE_IPV4_TCP = 5, + TYPE_IPV4_UDP = 6, + TYPE_IPV6 = 7, + TYPE_ICMPV6 = 8, + TYPE_IPV6_TCP = 9, + TYPE_IPV6_UDP = 10 +}GMAC_RX_PACKET_TYPE, *PGMAC_RX_PACKET_TYPE; + + + +BOOL +HalMiiGmacInitRtl8195a( + IN VOID *Data + ); + +BOOL +HalMiiGmacResetRtl8195a( + IN VOID *Data + ); + +BOOL +HalMiiGmacEnablePhyModeRtl8195a( + IN VOID *Data + ); + +u32 +HalMiiGmacXmitRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacCleanTxRingRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacFillTxInfoRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacFillRxInfoRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacTxRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacRxRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacSetDefaultEthIoCmdRtl8195a( + IN VOID *Data + ); + +VOID +HalMiiGmacInitIrqRtl8195a( + IN VOID *Data + ); + +u32 +HalMiiGmacGetInterruptStatusRtl8195a( + VOID + ); + +VOID +HalMiiGmacClearInterruptStatusRtl8195a( + u32 IsrStatus + ); +#endif // #ifdef CONFIG_MII_VERIFY + +#endif // #ifndef _RTL8195A_MII_H_ + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_nfc.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_nfc.h new file mode 100644 index 0000000..3b58167 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_nfc.h @@ -0,0 +1,155 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_NFC_H_ +#define _RTL8195A_NFC_H_ + +#include "hal_api.h" +//#include "osdep_api.h" +#ifdef CONFIG_NFC_VERIFY +#include "../test/nfc/rtl8195a_nfc_test.h" +#endif + +#if CONFIG_NFC_NORMAL +//===================== Register Bit Field Definition ===================== +// TODO: +//===================== Register Address Definition ===================== +//TODO: +//#include "osdep_api.h" +#define N2A_Q_LENGTH 10 +#define N2ARLENGTH 4 +//#define NFCTAGLENGTH 36 // maximum 36*4=144 bytes +#define NFCTAG_BASE 0x7F000 +#define NFCTAG_PAGESIZE 256 +#define NFCTAG_MAXPAGEIDX 16//(4*(1024/NFCTAG_PAGESIZE)) +#define A2NWCLENGTH 4 + +#define FLASHAPPLENGTH 31 +#define FLASHAPP_BASE 0x7E000 +#define FLASH_PAGESIZE 128 +#define FLASH_MAXPAGEIDX 32//(4*(1024/FLASH_PAGESIZE)) + +typedef struct _A2N_CATCH_W_ { + //u8 Vaild; + u8 A2NCatchRPage; + u32 A2NCatchWData[A2NWCLENGTH]; +}A2N_CATCH_W_QUEUE, *PA2N_CATCH_W_QUEUE; + +typedef struct _A2N_MAILBOX_Q_ { + u8 Length; + u8 Response; + u32 Content[A2NWCLENGTH+1]; +}A2N_MAILBOX_Q,*PA2N_MAILBOX_Q; + +typedef struct _N2A_CATCH_R_ { + u8 Vaild; + u8 N2ACatchRPage; + u32 N2ACatchRData[N2ARLENGTH]; +}N2A_CATCH_R_QUEUE, *PN2A_CATCH_R_QUEUE; + + +typedef struct _N2A_R_ { + u8 Vaild; + u8 N2ARPage; +}N2A_R_QUEUE, *PN2A_R_QUEUE; + +typedef struct _N2A_W_ { + u8 Vaild; + u8 N2AWPage; + u32 N2AWData; +}N2A_W_QUEUE, *PN2A_W_QUEUE; + +typedef struct _NFC_ADAPTER_ { + u8 Function; + u32 NFCIsr; + u8 N2ABoxOpen; + u8 A2NSeq; + //u8 NFCTagFlashWIdx; + //u8 NFCTagFlashRIdx; +// u32 NFCTag[NFCTAGLENGTH]; +#if !TASK_SCHEDULER_DISABLED + void * VeriSema; +#else + u32 VeriSema; +#endif +#ifdef PLATFORM_FREERTOS + void * NFCTask; +#else + u32 NFCTask; +#endif +#ifdef CONFIG_NFC_VERIFY + //N2A Write Tag + u8 N2AWQRIdx; + u8 N2AWQWIdx; + N2A_W_QUEUE N2AWQ[N2A_Q_LENGTH]; + //N2A Read Tag + u8 N2ARQRIdx; + u8 N2ARQWIdx; + N2A_R_QUEUE N2ARQ[N2A_Q_LENGTH]; + //N2A Read Catch + u8 N2ARCRIdx; + u8 N2ARCWIdx; + N2A_CATCH_R_QUEUE N2ACatchR[N2A_Q_LENGTH]; +#endif + //A2N Write Catch + //u8 A2NWCRIdx; + //u8 A2NWCWIdx; + //A2N_CATCH_W_QUEUE A2NCatchW[N2A_Q_LENGTH]; + + //A2N Write mailbox queue + u8 A2NWMailBox; + u8 A2NWQRIdx; + u8 A2NWQWIdx; + A2N_MAILBOX_Q A2NMAILQ[N2A_Q_LENGTH]; + + u8 TaskStop; + void *nfc_obj; +}NFC_ADAPTER, *PNFC_ADAPTER; + +typedef enum _N2A_CMD_ { + TAG_READ = 0, + TAG_WRITE = 1, + CATCH_READ_DATA = 2, + NFC_R_PRESENT = 4, + N2A_MAILBOX_STATE = 5, + EXT_CLK_REQ = 6, + MAX_N2ACMD +} N2A_CMD, *PN2A_CMD; + +typedef enum _A2N_CMD_ { + TAG_READ_DATA = 0, + CATCH_READ = 2, + CATCH_WRITE = 3, + A2N_MAILBOX_STATE = 4, + CONFIRM_N2A_BOX_STATE = 5, + EXT_CLK_RSP = 6, + MAX_A2NCMD +} A2N_CMD, *PA2N_CMD; + +// Callback event defination +typedef enum _NFC_HAL_EVENT_ { + NFC_HAL_READER_PRESENT = (1<<0), + NFC_HAL_READ = (1<<1), + NFC_HAL_WRITE = (1<<2), + NFC_HAL_ERR = (1<<3), + NFC_HAL_CACHE_RD = (1<<4) +}NFC_CB_EVENT, *PNFC_CB_EVENT; + +VOID A2NWriteCatch(IN VOID *pNFCAdapte, IN u8 N2AWPage, + IN u8 Length, IN u32 *WData); +VOID A2NReadCatch(IN VOID *pNFCAdapte, IN u8 A2NRPage); +VOID HalNFCDmemInit(IN u32 *pTagData, IN u32 TagLen); +VOID HalNFCInit(PNFC_ADAPTER pNFCAdp); +VOID HalNFCDeinit(PNFC_ADAPTER pNFCAdp); +VOID HalNFCFwDownload(VOID); +u32 HalNFCDbgRead32(IN u32 Addr); +VOID HalNFCDbgWrite32(IN u32 Addr, IN u32 Data); +#endif //CONFIG_NFC_NORMAL +#endif // #ifndef _RTL8195A_NFC_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pcm.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pcm.h new file mode 100644 index 0000000..c2bd793 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pcm.h @@ -0,0 +1,449 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_PCM_H_ +#define _RTL8195A_PCM_H_ + +#include "basic_types.h" +#include "hal_api.h" + +#define HAL_PCMX_READ32(PcmIndex, addr) \ + HAL_READ32(PCM0_REG_BASE+ (PcmIndex*PCM1_REG_OFF), addr) +#define HAL_PCMX_WRITE32(PcmIndex, addr, value) \ + HAL_WRITE32((PCM0_REG_BASE+ (PcmIndex*PCM1_REG_OFF)), addr, value) + +#define REG_PCM_TRXBSA_OFF 0x004 +#define REG_PCM_CTL 0x000 +#define REG_PCM_CHCNR03 0x004 +#define REG_PCM_TSR03 0x008 +#define REG_PCM_BSIZE03 0x00C + +#define REG_PCM_CH0TXBSA 0x010 +#define REG_PCM_CH1TXBSA 0x014 +#define REG_PCM_CH2TXBSA 0x018 +#define REG_PCM_CH3TXBSA 0x01c +#define REG_PCM_CH0RXBSA 0x020 +#define REG_PCM_CH1RXBSA 0x024 +#define REG_PCM_CH2RXBSA 0x028 +#define REG_PCM_CH3RXBSA 0x02c + +#define REG_PCM_IMR03 0x030 +#define REG_PCM_ISR03 0x034 + +#define REG_PCM_CHCNR47 0x038 +#define REG_PCM_TSR47 0x03c +#define REG_PCM_BSIZE47 0x040 +#define REG_PCM_CH4TXBSA 0x044 +#define REG_PCM_CH5TXBSA 0x048 +#define REG_PCM_CH6TXBSA 0x04c +#define REG_PCM_CH7TXBSA 0x050 +#define REG_PCM_CH4RXBSA 0x054 +#define REG_PCM_CH5RXBSA 0x058 +#define REG_PCM_CH6RXBSA 0x05c +#define REG_PCM_CH7RXBSA 0x060 + +#define REG_PCM_IMR47 0x064 +#define REG_PCM_ISR47 0x068 + +#define REG_PCM_CHCNR811 0x06c +#define REG_PCM_TSR811 0x070 +#define REG_PCM_BSIZE811 0x074 +#define REG_PCM_CH8TXBSA 0x078 +#define REG_PCM_CH9TXBSA 0x07c +#define REG_PCM_CH10TXBSA 0x080 +#define REG_PCM_CH11TXBSA 0x084 +#define REG_PCM_CH8RXBSA 0x088 +#define REG_PCM_CH9RXBSA 0x08c +#define REG_PCM_CH10RXBSA 0x090 +#define REG_PCM_CH11RXBSA 0x094 + +#define REG_PCM_IMR811 0x098 +#define REG_PCM_ISR811 0x09c + +#define REG_PCM_CHCNR1215 0x0a0 +#define REG_PCM_TSR1215 0x0a4 +#define REG_PCM_BSIZE1215 0x0a8 +#define REG_PCM_CH12TXBSA 0x0ac +#define REG_PCM_CH13TXBSA 0x0b0 +#define REG_PCM_CH14TXBSA 0x0b4 +#define REG_PCM_CH15TXBSA 0x0b8 +#define REG_PCM_CH12RXBSA 0x0bc +#define REG_PCM_CH13RXBSA 0x0c0 +#define REG_PCM_CH14RXBSA 0x0c4 +#define REG_PCM_CH15RXBSA 0x0c8 + +#define REG_PCM_IMR1215 0x0cc +#define REG_PCM_ISR1215 0x0d0 + +#define REG_PCM_INTMAP 0x0d4 +#define REG_PCM_WTSR03 0x0d8 +#define REG_PCM_WTSR47 0x0dc + +#define REG_PCM_RX_BUFOW 0x0e0 + +/* template +#define BIT_SHIFT_CTLX_ 7 +#define BIT_MASK_CTLX_ 0x1 +#define BIT_CTLX_(x) (((x) & BIT_MASK_CTLX_) << BIT_SHIFT_CTLX_) +#define BIT_INV_CTLX_ (~(BIT_MASK_CTLX_ << BIT_SHIFT_CTLX_)) +*/ +#define BIT_SHIFT_CTLX_SLAVE_SEL 8 +#define BIT_MASK_CTLX_SLAVE_SEL 0x1 +#define BIT_CTLX_SLAVE_SEL(x) (((x) & BIT_MASK_CTLX_SLAVE_SEL) << BIT_SHIFT_CTLX_SLAVE_SEL) +#define BIT_INV_CTLX_SLAVE_SEL (~(BIT_MASK_CTLX_SLAVE_SEL << BIT_SHIFT_CTLX_SLAVE_SEL)) + +#define BIT_SHIFT_CTLX_FSINV 9 +#define BIT_MASK_CTLX_FSINV 0x1 +#define BIT_CTLX_FSINV(x) (((x) & BIT_MASK_CTLX_FSINV) << BIT_SHIFT_CTLX_FSINV) +#define BIT_INV_CTLX_FSINV (~(BIT_MASK_CTLX_FSINV << BIT_SHIFT_CTLX_FSINV)) + +#define BIT_SHIFT_CTLX_PCM_EN 12 +#define BIT_MASK_CTLX_PCM_EN 0x1 +#define BIT_CTLX_PCM_EN(x) (((x) & BIT_MASK_CTLX_PCM_EN) << BIT_SHIFT_CTLX_PCM_EN) +#define BIT_INV_CTLX_PCM_EN (~(BIT_MASK_CTLX_PCM_EN << BIT_SHIFT_CTLX_PCM_EN)) + +#define BIT_SHIFT_CTLX_LINEARMODE 13 +#define BIT_MASK_CTLX_LINEARMODE 0x1 +#define BIT_CTLX_LINEARMODE(x) (((x) & BIT_MASK_CTLX_LINEARMODE) << BIT_SHIFT_CTLX_LINEARMODE) +#define BIT_INV_CTLX_LINEARMODE (~(BIT_MASK_CTLX_LINEARMODE << BIT_SHIFT_CTLX_LINEARMODE)) + +#define BIT_SHIFT_CTLX_LOOP_BACK 14 +#define BIT_MASK_CTLX_LOOP_BACK 0x1 +#define BIT_CTLX_LOOP_BACK(x) (((x) & BIT_MASK_CTLX_LOOP_BACK) << BIT_SHIFT_CTLX_LOOP_BACK) +#define BIT_INV_CTLX_LOOP_BACK (~(BIT_MASK_CTLX_LOOP_BACK << BIT_SHIFT_CTLX_LOOP_BACK)) + +#define BIT_SHIFT_CTLX_ENDIAN_SWAP 17 +#define BIT_MASK_CTLX_ENDIAN_SWAP 0x1 +#define BIT_CTLX_ENDIAN_SWAP(x) (((x) & BIT_MASK_CTLX_ENDIAN_SWAP) << BIT_SHIFT_CTLX_ENDIAN_SWAP) +#define BIT_INV_CTLX_ENDIAN_SWAP (~(BIT_MASK_CTLX_ENDIAN_SWAP << BIT_SHIFT_CTLX_ENDIAN_SWAP)) + +#define BIT_SHIFT_CHCNR03_CH0RE 24 +#define BIT_MASK_CHCNR03_CH0RE 0x1 +#define BIT_CHCNR03_CH0RE(x) (((x) & BIT_MASK_CHCNR03_CH0RE) << BIT_SHIFT_CHCNR03_CH0RE) +#define BIT_INV_CHCNR03_CH0RE (~(BIT_MASK_CHCNR03_CH0RE << BIT_SHIFT_CHCNR03_CH0RE)) + +#define BIT_SHIFT_CHCNR03_CH0TE 25 +#define BIT_MASK_CHCNR03_CH0TE 0x1 +#define BIT_CHCNR03_CH0TE(x) (((x) & BIT_MASK_CHCNR03_CH0TE) << BIT_SHIFT_CHCNR03_CH0TE) +#define BIT_INV_CHCNR03_CH0TE (~(BIT_MASK_CHCNR03_CH0TE << BIT_SHIFT_CHCNR03_CH0TE)) + +#define BIT_SHIFT_CHCNR03_CH1RE 16 +#define BIT_MASK_CHCNR03_CH1RE 0x1 +#define BIT_CHCNR03_CH1RE(x) (((x) & BIT_MASK_CHCNR03_CH1RE) << BIT_SHIFT_CHCNR03_CH1RE) +#define BIT_INV_CHCNR03_CH1RE (~(BIT_MASK_CHCNR03_CH1RE << BIT_SHIFT_CHCNR03_CH1RE)) + +#define BIT_SHIFT_CHCNR03_CH1TE 17 +#define BIT_MASK_CHCNR03_CH1TE 0x1 +#define BIT_CHCNR03_CH1TE(x) (((x) & BIT_MASK_CHCNR03_CH1TE) << BIT_SHIFT_CHCNR03_CH1TE) +#define BIT_INV_CHCNR03_CH1TE (~(BIT_MASK_CHCNR03_CH1TE << BIT_SHIFT_CHCNR03_CH1TE)) + +#define BIT_SHIFT_CHCNR03_CH2RE 8 +#define BIT_MASK_CHCNR03_CH2RE 0x1 +#define BIT_CHCNR03_CH2RE(x) (((x) & BIT_MASK_CHCNR03_CH2RE) << BIT_SHIFT_CHCNR03_CH2RE) +#define BIT_INV_CHCNR03_CH2RE (~(BIT_MASK_CHCNR03_CH2RE << BIT_SHIFT_CHCNR03_CH2RE)) + +#define BIT_SHIFT_CHCNR03_CH2TE 9 +#define BIT_MASK_CHCNR03_CH2TE 0x1 +#define BIT_CHCNR03_CH2TE(x) (((x) & BIT_MASK_CHCNR03_CH2TE) << BIT_SHIFT_CHCNR03_CH2TE) +#define BIT_INV_CHCNR03_CH2TE (~(BIT_MASK_CHCNR03_CH2TE << BIT_SHIFT_CHCNR03_CH2TE)) + +#define BIT_SHIFT_CHCNR03_CH3RE 0 +#define BIT_MASK_CHCNR03_CH3RE 0x1 +#define BIT_CHCNR03_CH3RE(x) (((x) & BIT_MASK_CHCNR03_CH3RE) << BIT_SHIFT_CHCNR03_CH3RE) +#define BIT_INV_CHCNR03_CH3RE (~(BIT_MASK_CHCNR03_CH3RE << BIT_SHIFT_CHCNR03_CH3RE)) + +#define BIT_SHIFT_CHCNR03_CH3TE 1 +#define BIT_MASK_CHCNR03_CH3TE 0x1 +#define BIT_CHCNR03_CH3TE(x) (((x) & BIT_MASK_CHCNR03_CH3TE) << BIT_SHIFT_CHCNR03_CH3TE) +#define BIT_INV_CHCNR03_CH3TE (~(BIT_MASK_CHCNR03_CH3TE << BIT_SHIFT_CHCNR03_CH3TE)) + +#define BIT_SHIFT_CHCNR03_CH0MUA 26 +#define BIT_MASK_CHCNR03_CH0MUA 0x1 +#define BIT_CHCNR03_CH0MUA(x) (((x) & BIT_MASK_CHCNR03_CH0MUA) << BIT_SHIFT_CHCNR03_CH0MUA) +#define BIT_INV_CHCNR03_CH0MUA (~(BIT_MASK_CHCNR03_CH0MUA << BIT_SHIFT_CHCNR03_CH0MUA)) + +#define BIT_SHIFT_CHCNR03_CH0BAND 27 +#define BIT_MASK_CHCNR03_CH0BAND 0x1 +#define BIT_CHCNR03_CH0BAND(x) (((x) & BIT_MASK_CHCNR03_CH0BAND) << BIT_SHIFT_CHCNR03_CH0BAND) +#define BIT_INV_CHCNR03_CH0BAND (~(BIT_MASK_CHCNR03_CH0BAND << BIT_SHIFT_CHCNR03_CH0BAND)) + +#define BIT_SHIFT_TSR03_CH0TSA 24 +#define BIT_MASK_TSR03_CH0TSA 0x1F +#define BIT_TSR03_CH0TSA(x) (((x) & BIT_MASK_TSR03_CH0TSA) << BIT_SHIFT_TSR03_CH0TSA) +#define BIT_INV_TSR03_CH0TSA (~(BIT_MASK_TSR03_CH0TSA << BIT_SHIFT_TSR03_CH0TSA)) + +#define BIT_SHIFT_BSIZE03_CH0BSIZE 24 +#define BIT_MASK_BSIZE03_CH0BSIZE 0xFF +#define BIT_BSIZE03_CH0BSIZE(x) (((x) & BIT_MASK_BSIZE03_CH0BSIZE) << BIT_SHIFT_BSIZE03_CH0BSIZE) +#define BIT_INV_BSIZE03_CH0BSIZE (~(BIT_MASK_BSIZE03_CH0BSIZE << BIT_SHIFT_BSIZE03_CH0BSIZE)) + +typedef struct _PCM_CTL_REG_ { + u32 FCNT :8; // Bit 0-7 + u32 SlaveMode :1; // Bit 8 + u32 FsInv :1; // Bit 9 + u32 Rsvd10to11 :1; // Bit 10-11 + u32 Pcm_En :1; // Bit 12 + u32 LinearMode :1; // Bit 13 + u32 LoopBack :1; // Bit 14 + u32 Rsvd15to16 :2; // Bit 15-16 + u32 EndianSwap :1; // Bit 17 + u32 Rsvd18to31 :14; // Bit 18-31 +} PCM_CTL_REG, *PPCM_CTL_REG; + + + +typedef struct _PCM_CHCNR03_REG_ { + u32 CH3RE :1; // Bit 0 + u32 CH3TE :1; // Bit 1 + u32 CH3MuA :1; // Bit 2 + u32 CH3Band :1; // Bit 3 + u32 CH3SlicSel:4; // Bit 4-7 + u32 CH2RE :1; // Bit 8 + u32 CH2TE :1; // Bit 9 + u32 CH2MuA :1; // Bit 10 + u32 CH2Band :1; // Bit 11 + u32 CH2SlicSel:4; // Bit 12-15 + u32 CH1RE :1; // Bit 16 + u32 CH1TE :1; // Bit 17 + u32 CH1MuA :1; // Bit 18 + u32 CH1Band :1; // Bit 19 + u32 CH1SlicSel:4; // Bit 20-23 + u32 CH0RE :1; // Bit 24 + u32 CH0TE :1; // Bit 25 + u32 CH0MuA :1; // Bit 26 + u32 CH0Band :1; // Bit 27 + u32 CH0SlicSel:4; // Bit 28-31 +}PCM_CHCNR03_REG, *PPCM_CHCNR03_REG; + +typedef struct _PCM_TSR03_REG_ { + u32 CH3TSA :5; // Bit 0-4 + u32 Rsvd5to7 :3; // Bit 5-7 + u32 CH2TSA :5; // Bit 8-12 + u32 Rsvd13to15:3; // Bit 13-15 + u32 CH1TSA :5; // Bit 16-20 + u32 Rsvd21to23:3; // Bit 21-23 + u32 CH0TSA :5; // Bit 24-28 + u32 Rsvd29to31:3; // Bit 29-31 +}PCM_TSR03_REG, *PPCM_TSR03_REG; + +typedef struct _PCM_BSIZE03_REG_ { + u32 CH3BSize :8; // Bit 0-7 + u32 CH2BSize :8; // Bit 8-15 + u32 CH1BSize :8; // Bit 16-23 + u32 CH0BSize :8; // Bit 24-31 +}PCM_BSIZE03_REG, *PPCM_BSIZE03_REG; + +typedef struct _PCM_ISR03_REG_ { + u32 CH3RXP1UA :1; // Bit 0 + u32 CH3RXP0UA :1; // Bit 1 + u32 CH3TXP1UA :1; // Bit 2 + u32 CH3TXP0UA :1; // Bit 3 + u32 CH3RXP1IP :1; // Bit 4 + u32 CH3RXP0IP :1; // Bit 5 + u32 CH3TXP1IP :1; // Bit 6 + u32 CH3TXP0IP :1; // Bit 7 + u32 CH2RXP1UA :1; // Bit 8 + u32 CH2RXP0UA :1; // Bit 9 + u32 CH2TXP1UA :1; // Bit 10 + u32 CH2TXP0UA :1; // Bit 11 + u32 CH2RXP1IP :1; // Bit 12 + u32 CH2RXP0IP :1; // Bit 13 + u32 CH2TXP1IP :1; // Bit 14 + u32 CH2TXP0IP :1; // Bit 15 + u32 CH1RXP1UA :1; // Bit 16 + u32 CH1RXP0UA :1; // Bit 17 + u32 CH1TXP1UA :1; // Bit 18 + u32 CH1TXP0UA :1; // Bit 19 + u32 CH1RXP1IP :1; // Bit 20 + u32 CH1RXP0IP :1; // Bit 21 + u32 CH1TXP1IP :1; // Bit 22 + u32 CH1TXP0IP :1; // Bit 23 + u32 CH0RXP1UA :1; // Bit 24 + u32 CH0RXP0UA :1; // Bit 25 + u32 CH0TXP1UA :1; // Bit 26 + u32 CH0TXP0UA :1; // Bit 27 + u32 CH0RXP1IP :1; // Bit 28 + u32 CH0RXP0IP :1; // Bit 29 + u32 CH0TXP1IP :1; // Bit 30 + u32 CH0TXP0IP :1; // Bit 31 +}PCM_ISR03_REG, *PPCM_ISR03_REG; + +typedef enum _PCM_ISR015 { + PcmCh3P1RBU = 0x00000001, //ch0-3 + PcmCh3P0RBU = 0x00000002, + PcmCh3P1TBU = 0x00000004, + PcmCh3P0TBU = 0x00000008, + PcmCh3P1ROK = 0x00000010, + PcmCh3P0ROK = 0x00000020, + PcmCh3P1TOK = 0x00000040, + PcmCh3P0TOK = 0x00000080, + PcmCh2P1RBU = 0x00000100, + PcmCh2P0RBU = 0x00000200, + PcmCh2P1TBU = 0x00000400, + PcmCh2P0TBU = 0x00000800, + PcmCh2P1ROK = 0x00001000, + PcmCh2P0ROK = 0x00002000, + PcmCh2P1TOK = 0x00004000, + PcmCh2P0TOK = 0x00008000, + PcmCh1P1RBU = 0x00010000, + PcmCh1P0RBU = 0x00020000, + PcmCh1P1TBU = 0x00040000, + PcmCh1P0TBU = 0x00080000, + PcmCh1P1ROK = 0x00100000, + PcmCh1P0ROK = 0x00200000, + PcmCh1P1TOK = 0x00400000, + PcmCh1P0TOK = 0x00800000, + PcmCh0P1RBU = 0x01000000, + PcmCh0P0RBU = 0x02000000, + PcmCh0P1TBU = 0x04000000, + PcmCh0P0TBU = 0x08000000, + PcmCh0P1ROK = 0x10000000, + PcmCh0P0ROK = 0x20000000, + PcmCh0P1TOK = 0x40000000, + PcmCh0P0TOK = 0x80000000, + + PcmCh7P1RBU = 0x00000001, //ch4-7 + PcmCh7P0RBU = 0x00000002, + PcmCh7P1TBU = 0x00000004, + PcmCh7P0TBU = 0x00000008, + PcmCh7P1ROK = 0x00000010, + PcmCh7P0ROK = 0x00000020, + PcmCh7P1TOK = 0x00000040, + PcmCh7P0TOK = 0x00000080, + PcmCh6P1RBU = 0x00000100, + PcmCh6P0RBU = 0x00000200, + PcmCh6P1TBU = 0x00000400, + PcmCh6P0TBU = 0x00000800, + PcmCh6P1ROK = 0x00001000, + PcmCh6P0ROK = 0x00002000, + PcmCh6P1TOK = 0x00004000, + PcmCh6P0TOK = 0x00008000, + PcmCh5P1RBU = 0x00010000, + PcmCh5P0RBU = 0x00020000, + PcmCh5P1TBU = 0x00040000, + PcmCh5P0TBU = 0x00080000, + PcmCh5P1ROK = 0x00100000, + PcmCh5P0ROK = 0x00200000, + PcmCh5P1TOK = 0x00400000, + PcmCh5P0TOK = 0x00800000, + PcmCh4P1RBU = 0x01000000, + PcmCh4P0RBU = 0x02000000, + PcmCh4P1TBU = 0x04000000, + PcmCh4P0TBU = 0x08000000, + PcmCh4P1ROK = 0x10000000, + PcmCh4P0ROK = 0x20000000, + PcmCh4P1TOK = 0x40000000, + PcmCh4P0TOK = 0x80000000, + + PcmCh11P1RBU = 0x00000001, //ch8-11 + PcmCh11P0RBU = 0x00000002, + PcmCh11P1TBU = 0x00000004, + PcmCh11P0TBU = 0x00000008, + PcmCh11P1ROK = 0x00000010, + PcmCh11P0ROK = 0x00000020, + PcmCh11P1TOK = 0x00000040, + PcmCh11P0TOK = 0x00000080, + PcmCh10P1RBU = 0x00000100, + PcmCh10P0RBU = 0x00000200, + PcmCh10P1TBU = 0x00000400, + PcmCh10P0TBU = 0x00000800, + PcmCh10P1ROK = 0x00001000, + PcmCh10P0ROK = 0x00002000, + PcmCh10P1TOK = 0x00004000, + PcmCh10P0TOK = 0x00008000, + PcmCh9P1RBU = 0x00010000, + PcmCh9P0RBU = 0x00020000, + PcmCh9P1TBU = 0x00040000, + PcmCh9P0TBU = 0x00080000, + PcmCh9P1ROK = 0x00100000, + PcmCh9P0ROK = 0x00200000, + PcmCh9P1TOK = 0x00400000, + PcmCh9P0TOK = 0x00800000, + PcmCh8P1RBU = 0x01000000, + PcmCh8P0RBU = 0x02000000, + PcmCh8P1TBU = 0x04000000, + PcmCh8P0TBU = 0x08000000, + PcmCh8P1ROK = 0x10000000, + PcmCh8P0ROK = 0x20000000, + PcmCh8P1TOK = 0x40000000, + PcmCh8P0TOK = 0x80000000, + + PcmCh15P1RBU = 0x00000001, //ch12-15 + PcmCh15P0RBU = 0x00000002, + PcmCh15P1TBU = 0x00000004, + PcmCh15P0TBU = 0x00000008, + PcmCh15P1ROK = 0x00000010, + PcmCh15P0ROK = 0x00000020, + PcmCh15P1TOK = 0x00000040, + PcmCh15P0TOK = 0x00000080, + PcmCh14P1RBU = 0x00000100, + PcmCh14P0RBU = 0x00000200, + PcmCh14P1TBU = 0x00000400, + PcmCh14P0TBU = 0x00000800, + PcmCh14P1ROK = 0x00001000, + PcmCh14P0ROK = 0x00002000, + PcmCh14P1TOK = 0x00004000, + PcmCh14P0TOK = 0x00008000, + PcmCh13P1RBU = 0x00010000, + PcmCh13P0RBU = 0x00020000, + PcmCh13P1TBU = 0x00040000, + PcmCh13P0TBU = 0x00080000, + PcmCh13P1ROK = 0x00100000, + PcmCh13P0ROK = 0x00200000, + PcmCh13P1TOK = 0x00400000, + PcmCh13P0TOK = 0x00800000, + PcmCh12P1RBU = 0x01000000, + PcmCh12P0RBU = 0x02000000, + PcmCh12P1TBU = 0x04000000, + PcmCh12P0TBU = 0x08000000, + PcmCh12P1ROK = 0x10000000, + PcmCh12P0ROK = 0x20000000, + PcmCh12P1TOK = 0x40000000, + PcmCh12P0TOK = 0x80000000 +}PCM_ISR015, *PPCM_ISR015; + +VOID +HalPcmOnOffRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmInitRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmSettingRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmEnRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmIsrEnAndDisRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmDumpRegRtl8195a( + IN VOID *Data +); + +BOOL +HalPcmRtl8195a( + IN VOID *Data +); + +#endif /* _RTL8195A_PCM_H_ */ + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_peri_on.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_peri_on.h new file mode 100644 index 0000000..ac2ad51 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_peri_on.h @@ -0,0 +1,1252 @@ +#ifndef __INC_RTL8195A_PERI_ON_H +#define __INC_RTL8195A_PERI_ON_H + +#define CPU_OPT_WIDTH 0x1F + +//2 REG_NOT_VALID + +//2 REG_PEON_PWR_CTRL +#define BIT_SOC_UAHV_EN BIT(2) +#define BIT_SOC_UALV_EN BIT(1) +#define BIT_SOC_USBD_EN BIT(0) + +//2 REG_PON_ISO_CTRL + +//2 REG_NOT_VALID +#define BIT_ISO_OSC32K_EN BIT(4) +//#define BIT_ISO_USBA_EN BIT(1) +//#define BIT_ISO_USBD_EN BIT(0) + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SOC_FUNC_EN +// BIT(21) SDRAM +#define BIT_SOC_SECURITY_ENGINE_EN BIT(20) +#define BIT_SOC_GTIMER_EN BIT(16) +#define BIT_SOC_GDMA1_EN BIT(14) +#define BIT_SOC_GDMA0_EN BIT(13) +#define BIT_SOC_LOG_UART_EN BIT(12) +#define BIT_SOC_CPU_EN BIT(8) +#define BIT_SOC_MEM_CTRL_EN BIT(6) +#define BIT_SOC_FLASH_EN BIT(4) +#define BIT_SOC_LXBUS_EN BIT(2) +#define BIT_SOC_OCP_EN BIT(1) +#define BIT_SOC_FUN_EN BIT(0) + +//2 REG_SOC_HCI_COM_FUNC_EN +#define BIT_SOC_HCI_WL_MACON_EN BIT(16) +#define BIT_SOC_HCI_SM_SEL BIT(13) +#define BIT_SOC_HCI_MII_EN BIT(12) +#define BIT_SOC_HCI_OTG_RST_MUX BIT(5) +#define BIT_SOC_HCI_OTG_EN BIT(4) +#define BIT_SOC_HCI_SDIOD_ON_RST_MUX BIT(3) +#define BIT_SOC_HCI_SDIOH_EN BIT(2) +#define BIT_SOC_HCI_SDIOD_OFF_EN BIT(1) +#define BIT_SOC_HCI_SDIOD_ON_EN BIT(0) + +//2 REG_SOC_PERI_FUNC0_EN +#define BIT_PERI_PCM1_EN BIT(29) +#define BIT_PERI_PCM0_EN BIT(28) +#define BIT_PERI_I2S1_EN BIT(25) +#define BIT_PERI_I2S0_EN BIT(24) +#define BIT_PERI_I2C3_EN BIT(19) +#define BIT_PERI_I2C2_EN BIT(18) +#define BIT_PERI_I2C1_EN BIT(17) +#define BIT_PERI_I2C0_EN BIT(16) +#define BIT_PERI_SPI2_EN BIT(10) +#define BIT_PERI_SPI1_EN BIT(9) +#define BIT_PERI_SPI0_EN BIT(8) +#define BIT_PERI_UART2_EN BIT(2) +#define BIT_PERI_UART1_EN BIT(1) +#define BIT_PERI_UART0_EN BIT(0) + +//2 REG_SOC_PERI_FUNC1_EN +#define BIT_PERI_GPIO_EN BIT(8) +#define BIT_PERI_DAC1_EN BIT(5) +#define BIT_PERI_DAC0_EN BIT(4) +#define BIT_PERI_ADC0_EN BIT(0) + +//2 REG_SOC_PERI_BD_FUNC0_EN +#define BIT_PERI_UART2_BD_EN BIT(2) +#define BIT_PERI_UART1_BD_EN BIT(1) +#define BIT_PERI_UART0_BD_EN BIT(0) + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_PESOC_CLK_CTRL +#define BIT_SOC_SLPCK_BTCMD_EN BIT(29) +#define BIT_SOC_ACTCK_BTCMD_EN BIT(28) +#define BIT_SOC_SLPCK_GPIO_EN BIT(25) +#define BIT_SOC_ACTCK_GPIO_EN BIT(24) +#define BIT_SOC_SLPCK_GDMA1_EN BIT(19) +#define BIT_SOC_ACTCK_GDMA1_EN BIT(18) +#define BIT_SOC_SLPCK_GDMA0_EN BIT(17) +#define BIT_SOC_ACTCK_GDMA0_EN BIT(16) +#define BIT_SOC_SLPCK_TIMER_EN BIT(15) +#define BIT_SOC_ACTCK_TIMER_EN BIT(14) +#define BIT_SOC_SLPCK_LOG_UART_EN BIT(13) +#define BIT_SOC_ACTCK_LOG_UART_EN BIT(12) +#define BIT_SOC_SLPCK_SDR_EN BIT(11) +#define BIT_SOC_ACTCK_SDR_EN BIT(10) +#define BIT_SOC_SLPCK_FLASH_EN BIT(9) +#define BIT_SOC_ACTCK_FLASH_EN BIT(8) +#define BIT_SOC_SLPCK_VENDOR_REG_EN BIT(7) +#define BIT_SOC_ACTCK_VENDOR_REG_EN BIT(6) +#define BIT_SOC_SLPCK_TRACE_EN BIT(5) +#define BIT_SOC_ACTCK_TRACE_EN BIT(4) +#define BIT_SOC_CKE_PLFM BIT(2) +#define BIT_SOC_CKE_OCP BIT(0) + +//2 REG_PESOC_PERI_CLK_CTRL0 +#define BIT_SOC_SLPCK_SPI2_EN BIT(21) +#define BIT_SOC_ACTCK_SPI2_EN BIT(20) +#define BIT_SOC_SLPCK_SPI1_EN BIT(19) +#define BIT_SOC_ACTCK_SPI1_EN BIT(18) +#define BIT_SOC_SLPCK_SPI0_EN BIT(17) +#define BIT_SOC_ACTCK_SPI0_EN BIT(16) +#define BIT_SOC_SLPCK_UART2_EN BIT(5) +#define BIT_SOC_ACTCK_UART2_EN BIT(4) +#define BIT_SOC_SLPCK_UART1_EN BIT(3) +#define BIT_SOC_ACTCK_UART1_EN BIT(2) +#define BIT_SOC_SLPCK_UART0_EN BIT(1) +#define BIT_SOC_ACTCK_UART0_EN BIT(0) + +//2 REG_PESOC_PERI_CLK_CTRL1 +#define BIT_SOC_SLPCK_DAC_EN BIT(29) +#define BIT_SOC_ACTCK_DAC_EN BIT(28) +#define BIT_SOC_SLPCK_ADC_EN BIT(25) +#define BIT_SOC_ACTCK_ADC_EN BIT(24) +#define BIT_SOC_SLPCK_PCM_EN BIT(21) +#define BIT_SOC_ACTCK_PCM_EN BIT(20) +#define BIT_SOC_SLPCK_I2S_EN BIT(17) +#define BIT_SOC_ACTCK_I2S_EN BIT(16) +#define BIT_SOC_SLPCK_I2C3_EN BIT(7) +#define BIT_SOC_ACTCK_I2C3_EN BIT(6) +#define BIT_SOC_SLPCK_I2C2_EN BIT(5) +#define BIT_SOC_ACTCK_I2C2_EN BIT(4) +#define BIT_SOC_SLPCK_I2C1_EN BIT(3) +#define BIT_SOC_ACTCK_I2C1_EN BIT(2) +#define BIT_SOC_SLPCK_I2C0_EN BIT(1) +#define BIT_SOC_ACTCK_I2C0_EN BIT(0) + +//2 REG_PESOC_CLK_CTRL3 + +//2 REG_PESOC_HCI_CLK_CTRL0 +#define BIT_SOC_SLPCK_MII_MPHY_EN BIT(25) +#define BIT_SOC_ACTCK_MII_MPHY_EN BIT(24) +#define BIT_SOC_SLPCK_OTG_EN BIT(5) +#define BIT_SOC_ACTCK_OTG_EN BIT(4) +#define BIT_SOC_SLPCK_SDIO_HST_EN BIT(3) +#define BIT_SOC_ACTCK_SDIO_HST_EN BIT(2) +#define BIT_SOC_SLPCK_SDIO_DEV_EN BIT(1) +#define BIT_SOC_ACTCK_SDIO_DEV_EN BIT(0) + +//2 REG_PESOC_COM_CLK_CTRL1 +#define BIT_SOC_NFC_CAL_EN BIT(18) +#define BIT_SOC_SLPCK_NFC_EN BIT(17) +#define BIT_SOC_ACTCK_NFC_EN BIT(16) +#define BIT_SOC_SLPCK_SECURITY_ENG_EN BIT(5) +#define BIT_SOC_ACTCK_SECURITY_ENG_EN BIT(4) +#define BIT_SOC_SLPCK_WL_EN BIT(1) +#define BIT_SOC_ACTCK_WL_EN BIT(0) + +//2 REG_PESOC_HW_ENG_CLK_CTRL + +//2 REG_RSVD + +//2 REG_PESOC_CLK_SEL +#define BIT_PESOC_SPI1_SCLK_SEL BIT(18) + +#define BIT_SHIFT_PESOC_PERI_SCLK_SEL 16 +#define BIT_MASK_PESOC_PERI_SCLK_SEL 0x3 // 0 - CLK, 1 - CLK/2, 2 - CLK/4, 3 - CLK/8 +#define BIT_PESOC_PERI_SCLK_SEL(x) (((x) & BIT_MASK_PESOC_PERI_SCLK_SEL) << BIT_SHIFT_PESOC_PERI_SCLK_SEL) + + +#define BIT_SHIFT_PESOC_SDR_CK_SEL 10 +#define BIT_MASK_PESOC_SDR_CK_SEL 0x3 +#define BIT_PESOC_SDR_CK_SEL(x) (((x) & BIT_MASK_PESOC_SDR_CK_SEL) << BIT_SHIFT_PESOC_SDR_CK_SEL) + + +#define BIT_SHIFT_PESOC_FLASH_CK_SEL 8 +#define BIT_MASK_PESOC_FLASH_CK_SEL 0x3 +#define BIT_PESOC_FLASH_CK_SEL(x) (((x) & BIT_MASK_PESOC_FLASH_CK_SEL) << BIT_SHIFT_PESOC_FLASH_CK_SEL) + + +#define BIT_SHIFT_PESOC_TRACE_CK_SEL 4 +#define BIT_MASK_PESOC_TRACE_CK_SEL 0x3 +#define BIT_PESOC_TRACE_CK_SEL(x) (((x) & BIT_MASK_PESOC_TRACE_CK_SEL) << BIT_SHIFT_PESOC_TRACE_CK_SEL) + + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_SYS_ANACK_CAL_CTRL +#define BIT_SYS_ANACK_CAL_CMD BIT(15) +#define BIT_SYS_ANACK_CAL_SEL BIT(14) + +#define BIT_SHIFT_SYS_ANACK_CAL_RPT 0 +#define BIT_MASK_SYS_ANACK_CAL_RPT 0x3fff +#define BIT_SYS_ANACK_CAL_RPT(x) (((x) & BIT_MASK_SYS_ANACK_CAL_RPT) << BIT_SHIFT_SYS_ANACK_CAL_RPT) + + +//2 REG_OSC32K_CTRL + +#define BIT_SHIFT_32K_BIAS_CURRENT 16 +#define BIT_MASK_32K_BIAS_CURRENT 0xffff +#define BIT_32K_BIAS_CURRENT(x) (((x) & BIT_MASK_32K_BIAS_CURRENT) << BIT_SHIFT_32K_BIAS_CURRENT) + + +#define BIT_SHIFT_32K_RESISTOR_COM 2 +#define BIT_MASK_32K_RESISTOR_COM 0x3 +#define BIT_32K_RESISTOR_COM(x) (((x) & BIT_MASK_32K_RESISTOR_COM) << BIT_SHIFT_32K_RESISTOR_COM) + +#define BIT_32K_DBG_SEL BIT(1) +#define BIT_32K_POW_CKGEN_EN BIT(0) + +//2 REG_OSC32K_REG_CTRL0 +#define BIT_32K_REG_INDIRT_CMD BIT(23) + +#define BIT_SHIFT_32K_REG_INDIRT_ADDR 16 +#define BIT_MASK_32K_REG_INDIRT_ADDR 0x3f +#define BIT_32K_REG_INDIRT_ADDR(x) (((x) & BIT_MASK_32K_REG_INDIRT_ADDR) << BIT_SHIFT_32K_REG_INDIRT_ADDR) + + +#define BIT_SHIFT_32K_REG_INDIRT_WDATA 0 +#define BIT_MASK_32K_REG_INDIRT_WDATA 0xffff +#define BIT_32K_REG_INDIRT_WDATA(x) (((x) & BIT_MASK_32K_REG_INDIRT_WDATA) << BIT_SHIFT_32K_REG_INDIRT_WDATA) + + +//2 REG_OSC32K_REG_CTRL1 + +#define BIT_SHIFT_32K_REG_INDIRT_RDATA 0 +#define BIT_MASK_32K_REG_INDIRT_RDATA 0xffff +#define BIT_32K_REG_INDIRT_RDATA(x) (((x) & BIT_MASK_32K_REG_INDIRT_RDATA) << BIT_SHIFT_32K_REG_INDIRT_RDATA) + + +//2 REG_THERMAL_METER_CTRL + +#define BIT_SHIFT_TEMP_VALUE 24 +#define BIT_MASK_TEMP_VALUE 0x3f +#define BIT_TEMP_VALUE(x) (((x) & BIT_MASK_TEMP_VALUE) << BIT_SHIFT_TEMP_VALUE) + + +#define BIT_SHIFT_TEMP_DELTA 16 +#define BIT_MASK_TEMP_DELTA 0x3f +#define BIT_TEMP_DELTA(x) (((x) & BIT_MASK_TEMP_DELTA) << BIT_SHIFT_TEMP_DELTA) + +#define BIT_THERMAL_METER_EN BIT(15) +#define BIT_THERMAL_METER_VALID BIT(14) + +#define BIT_SHIFT_THERMAL_METER_TIMER 0 +#define BIT_MASK_THERMAL_METER_TIMER 0xfff +#define BIT_THERMAL_METER_TIMER(x) (((x) & BIT_MASK_THERMAL_METER_TIMER) << BIT_SHIFT_THERMAL_METER_TIMER) + + +//2 REG_UART_MUX_CTRL + +#define BIT_SHIFT_UART2_PIN_SEL 9 +#define BIT_MASK_UART2_PIN_SEL 0x7 +#define BIT_UART2_PIN_SEL(x) (((x) & BIT_MASK_UART2_PIN_SEL) << BIT_SHIFT_UART2_PIN_SEL) + +#define BIT_UART2_PIN_EN BIT(8) + +#define BIT_SHIFT_UART1_PIN_SEL 5 +#define BIT_MASK_UART1_PIN_SEL 0x7 +#define BIT_UART1_PIN_SEL(x) (((x) & BIT_MASK_UART1_PIN_SEL) << BIT_SHIFT_UART1_PIN_SEL) + +#define BIT_UART1_PIN_EN BIT(4) + +#define BIT_SHIFT_UART0_PIN_SEL 1 +#define BIT_MASK_UART0_PIN_SEL 0x7 +#define BIT_UART0_PIN_SEL(x) (((x) & BIT_MASK_UART0_PIN_SEL) << BIT_SHIFT_UART0_PIN_SEL) + +#define BIT_UART0_PIN_EN BIT(0) + +//2 REG_SPI_MUX_CTRL +#define BIT_SPI0_MULTI_CS_EN BIT(28) + +#define BIT_SHIFT_SPI2_PIN_SEL 9 +#define BIT_MASK_SPI2_PIN_SEL 0x7 +#define BIT_SPI2_PIN_SEL(x) (((x) & BIT_MASK_SPI2_PIN_SEL) << BIT_SHIFT_SPI2_PIN_SEL) + +#define BIT_SPI2_PIN_EN BIT(8) + +#define BIT_SHIFT_SPI1_PIN_SEL 5 +#define BIT_MASK_SPI1_PIN_SEL 0x7 +#define BIT_SPI1_PIN_SEL(x) (((x) & BIT_MASK_SPI1_PIN_SEL) << BIT_SHIFT_SPI1_PIN_SEL) + +#define BIT_SPI1_PIN_EN BIT(4) + +#define BIT_SHIFT_SPI0_PIN_SEL 1 +#define BIT_MASK_SPI0_PIN_SEL 0x7 +#define BIT_SPI0_PIN_SEL(x) (((x) & BIT_MASK_SPI0_PIN_SEL) << BIT_SHIFT_SPI0_PIN_SEL) + +#define BIT_SPI0_PIN_EN BIT(0) + +//2 REG_I2C_MUX_CTRL + +#define BIT_SHIFT_I2C3_PIN_SEL 13 +#define BIT_MASK_I2C3_PIN_SEL 0x7 +#define BIT_I2C3_PIN_SEL(x) (((x) & BIT_MASK_I2C3_PIN_SEL) << BIT_SHIFT_I2C3_PIN_SEL) + +#define BIT_I2C3_PIN_EN BIT(12) + +#define BIT_SHIFT_I2C2_PIN_SEL 9 +#define BIT_MASK_I2C2_PIN_SEL 0x7 +#define BIT_I2C2_PIN_SEL(x) (((x) & BIT_MASK_I2C2_PIN_SEL) << BIT_SHIFT_I2C2_PIN_SEL) + +#define BIT_I2C2_PIN_EN BIT(8) + +#define BIT_SHIFT_I2C1_PIN_SEL 5 +#define BIT_MASK_I2C1_PIN_SEL 0x7 +#define BIT_I2C1_PIN_SEL(x) (((x) & BIT_MASK_I2C1_PIN_SEL) << BIT_SHIFT_I2C1_PIN_SEL) + +#define BIT_I2C1_PIN_EN BIT(4) + +#define BIT_SHIFT_I2C0_PIN_SEL 1 +#define BIT_MASK_I2C0_PIN_SEL 0x7 +#define BIT_I2C0_PIN_SEL(x) (((x) & BIT_MASK_I2C0_PIN_SEL) << BIT_SHIFT_I2C0_PIN_SEL) + +#define BIT_I2C0_PIN_EN BIT(0) + +//2 REG_I2S_MUX_CTRL/ REG_PCM_MUX_CTRL + +//2 REG_NOT_VALID + +#define BIT_SHIFT_PCM1_PIN_SEL 21 +#define BIT_MASK_PCM1_PIN_SEL 0x7 +#define BIT_PCM1_PIN_SEL(x) (((x) & BIT_MASK_PCM1_PIN_SEL) << BIT_SHIFT_PCM1_PIN_SEL) + +#define BIT_PCM1_PIN_EN BIT(20) + +#define BIT_SHIFT_PCM0_PIN_SEL 17 +#define BIT_MASK_PCM0_PIN_SEL 0x7 +#define BIT_PCM0_PIN_SEL(x) (((x) & BIT_MASK_PCM0_PIN_SEL) << BIT_SHIFT_PCM0_PIN_SEL) + +#define BIT_PCM0_PIN_EN BIT(16) + +//2 REG_NOT_VALID + +#define BIT_SHIFT_I2S1_PIN_SEL 6 +#define BIT_MASK_I2S1_PIN_SEL 0x3 +#define BIT_I2S1_PIN_SEL(x) (((x) & BIT_MASK_I2S1_PIN_SEL) << BIT_SHIFT_I2S1_PIN_SEL) + +#define BIT_I2S1_MCK_EN BIT(5) +#define BIT_I2S1_PIN_EN BIT(4) + +#define BIT_SHIFT_I2S0_PIN_SEL 2 +#define BIT_MASK_I2S0_PIN_SEL 0x3 +#define BIT_I2S0_PIN_SEL(x) (((x) & BIT_MASK_I2S0_PIN_SEL) << BIT_SHIFT_I2S0_PIN_SEL) + +#define BIT_I2S0_MCK_EN BIT(1) +#define BIT_I2S0_PIN_EN BIT(0) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_HCI_PINMUX_CTRL +#define BIT_HCI_MII_PIN_EN BIT(24) +#define BIT_HCI_SDIOH_PIN_EN BIT(1) +#define BIT_HCI_SDIOD_PIN_EN BIT(0) + +//2 REG_WL_PINMUX_CTRL +#define BIT_NFC_PIN_EN BIT(16) +#define BIT_WL_BTCMD_PIN_EN BIT(13) +#define BIT_WL_BTCOEX_PIN_EN BIT(12) +#define BIT_WL_ANT1_PIN_EN BIT(9) +#define BIT_WL_ANT0_PIN_EN BIT(8) + +#define BIT_SHIFT_WL_LED_PIN_SEL 1 +#define BIT_MASK_WL_LED_PIN_SEL 0x3 +#define BIT_WL_LED_PIN_SEL(x) (((x) & BIT_MASK_WL_LED_PIN_SEL) << BIT_SHIFT_WL_LED_PIN_SEL) + +#define BIT_WL_LED_PIN_EN BIT(0) + +//2 REG_BT_PINMUX_CTRL + +//2 REG_PWM_PINMUX_CTRL + +#define BIT_SHIFT_ETE3_PIN_SEL 29 +#define BIT_MASK_ETE3_PIN_SEL 0x3 +#define BIT_ETE3_PIN_SEL(x) (((x) & BIT_MASK_ETE3_PIN_SEL) << BIT_SHIFT_ETE3_PIN_SEL) + +#define BIT_ETE3_PIN_EN BIT(28) + +#define BIT_SHIFT_ETE2_PIN_SEL 25 +#define BIT_MASK_ETE2_PIN_SEL 0x3 +#define BIT_ETE2_PIN_SEL(x) (((x) & BIT_MASK_ETE2_PIN_SEL) << BIT_SHIFT_ETE2_PIN_SEL) + +#define BIT_ETE2_PIN_EN BIT(24) + +#define BIT_SHIFT_ETE1_PIN_SEL 21 +#define BIT_MASK_ETE1_PIN_SEL 0x3 +#define BIT_ETE1_PIN_SEL(x) (((x) & BIT_MASK_ETE1_PIN_SEL) << BIT_SHIFT_ETE1_PIN_SEL) + +#define BIT_ETE1_PIN_EN BIT(20) + +#define BIT_SHIFT_ETE0_PIN_SEL 17 +#define BIT_MASK_ETE0_PIN_SEL 0x3 +#define BIT_ETE0_PIN_SEL(x) (((x) & BIT_MASK_ETE0_PIN_SEL) << BIT_SHIFT_ETE0_PIN_SEL) + +#define BIT_ETE0_PIN_EN BIT(16) + +#define BIT_SHIFT_PWM3_PIN_SEL 13 +#define BIT_MASK_PWM3_PIN_SEL 0x3 +#define BIT_PWM3_PIN_SEL(x) (((x) & BIT_MASK_PWM3_PIN_SEL) << BIT_SHIFT_PWM3_PIN_SEL) + +#define BIT_PWM3_PIN_EN BIT(12) + +#define BIT_SHIFT_PWM2_PIN_SEL 9 +#define BIT_MASK_PWM2_PIN_SEL 0x3 +#define BIT_PWM2_PIN_SEL(x) (((x) & BIT_MASK_PWM2_PIN_SEL) << BIT_SHIFT_PWM2_PIN_SEL) + +#define BIT_PWM2_PIN_EN BIT(8) + +#define BIT_SHIFT_PWM1_PIN_SEL 5 +#define BIT_MASK_PWM1_PIN_SEL 0x3 +#define BIT_PWM1_PIN_SEL(x) (((x) & BIT_MASK_PWM1_PIN_SEL) << BIT_SHIFT_PWM1_PIN_SEL) + +#define BIT_PWM1_PIN_EN BIT(4) + +#define BIT_SHIFT_PWM0_PIN_SEL 1 +#define BIT_MASK_PWM0_PIN_SEL 0x3 +#define BIT_PWM0_PIN_SEL(x) (((x) & BIT_MASK_PWM0_PIN_SEL) << BIT_SHIFT_PWM0_PIN_SEL) + +#define BIT_PWM0_PIN_EN BIT(0) + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_CPU_PERIPHERAL_CTRL + +#define BIT_SHIFT_LOG_UART_PIN_SEL 22 +#define BIT_MASK_LOG_UART_PIN_SEL 0x3 +#define BIT_LOG_UART_PIN_SEL(x) (((x) & BIT_MASK_LOG_UART_PIN_SEL) << BIT_SHIFT_LOG_UART_PIN_SEL) + +#define BIT_LOG_UART_IR_EN BIT(21) +#define BIT_LOG_UART_PIN_EN BIT(20) +#define BIT_TRACE_PIN_EN BIT(17) +#define BIT_SDR_PIN_EN BIT(4) + +#define BIT_SHIFT_SPI_FLSH_PIN_SEL 1 +#define BIT_MASK_SPI_FLSH_PIN_SEL 0x3 +#define BIT_SPI_FLSH_PIN_SEL(x) (((x) & BIT_MASK_SPI_FLSH_PIN_SEL) << BIT_SHIFT_SPI_FLSH_PIN_SEL) + +#define BIT_SPI_FLSH_PIN_EN BIT(0) + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_HCI_CTRL_STATUS_0 + +//2 REG_HCI_CTRL_STATUS_1 + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_PESOC_MEM_CTRL + +#define BIT_SHIFT_PESOC_SDR_DDL_CTRL 16 +#define BIT_MASK_PESOC_SDR_DDL_CTRL 0xff +#define BIT_PESOC_SDR_DDL_CTRL(x) (((x) & BIT_MASK_PESOC_SDR_DDL_CTRL) << BIT_SHIFT_PESOC_SDR_DDL_CTRL) + + +#define BIT_SHIFT_PESOC_FLASH_DDL_CTRL 0 +#define BIT_MASK_PESOC_FLASH_DDL_CTRL 0xff +#define BIT_PESOC_FLASH_DDL_CTRL(x) (((x) & BIT_MASK_PESOC_FLASH_DDL_CTRL) << BIT_SHIFT_PESOC_FLASH_DDL_CTRL) + + +//2 REG_PESOC_SOC_CTRL + +#define BIT_SHIFT_PESOC_GDMA_CFG 16 +#define BIT_MASK_PESOC_GDMA_CFG 0x1fff +#define BIT_PESOC_GDMA_CFG(x) (((x) & BIT_MASK_PESOC_GDMA_CFG) << BIT_SHIFT_PESOC_GDMA_CFG) + +#define BIT_PESOC_MII_LX_SLV_SWAP_SEL BIT(13) +#define BIT_PESOC_MII_LX_MST_SWAP_SEL BIT(12) +#define BIT_PESOC_MII_LX_WRAPPER_EN BIT(11) +#define BIT_PESOC_LX_SLV_SWAP_SEL BIT(10) +#define BIT_PESOC_LX_MST_SWAP_SEL BIT(9) +#define BIT_PESOC_LX_WL_SWAP_SEL BIT(8) + +#define BIT_SHIFT_PESOC_SRAM_MUX_CFG 0 +#define BIT_MASK_PESOC_SRAM_MUX_CFG 0x7 +#define BIT_PESOC_SRAM_MUX_CFG(x) (((x) & BIT_MASK_PESOC_SRAM_MUX_CFG) << BIT_SHIFT_PESOC_SRAM_MUX_CFG) + + +//2 REG_PESOC_PERI_CTRL +#define BIT_SOC_FUNC_SPI_RN BIT(8) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_FW_CTRL_INT0 BIT(24) + +//2 REG_NOT_VALID + +//2 REG_GPIO_SHTDN_CTRL +#define BIT_GPIO_GPK_SHTDN_N BIT(10) +#define BIT_GPIO_GPJ_SHTDN_N BIT(9) +#define BIT_GPIO_GPI_SHTDN_N BIT(8) +#define BIT_GPIO_GPH_SHTDN_N BIT(7) +#define BIT_GPIO_GPG_SHTDN_N BIT(6) +#define BIT_GPIO_GPF_SHTDN_N BIT(5) +#define BIT_GPIO_GPE_SHTDN_N BIT(4) +#define BIT_GPIO_GPD_SHTDN_N BIT(3) +#define BIT_GPIO_GPC_SHTDN_N BIT(2) +#define BIT_GPIO_GPB_SHTDN_N BIT(1) +#define BIT_GPIO_GPA_SHTDN_N BIT(0) + +//2 REG_GPIO_DRIVING_CTRL +#define BIT_GPIO_GPK_DRV_SEL BIT(20) +#define BIT_GPIO_GPJ_DRV_SEL BIT(18) +#define BIT_GPIO_GPI_DRV_SEL BIT(16) +#define BIT_GPIO_GPH_DRV_SEL BIT(14) +#define BIT_GPIO_GPG_DRV_SEL BIT(12) +#define BIT_GPIO_GPF_DRV_SEL BIT(10) +#define BIT_GPIO_GPE_DRV_SEL BIT(8) +#define BIT_GPIO_GPD_DRV_SEL BIT(6) +#define BIT_GPIO_GPC_DRV_SEL BIT(4) +#define BIT_GPIO_GPB_DRV_SEL BIT(2) +#define BIT_GPIO_GPA_DRV_SEL BIT(0) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_GPIO_PULL_CTRL0 + +#define BIT_SHIFT_GPIO_GPB7_PULL_CTRL 30 +#define BIT_MASK_GPIO_GPB7_PULL_CTRL 0x3 +#define BIT_GPIO_GPB7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB7_PULL_CTRL) << BIT_SHIFT_GPIO_GPB7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB6_PULL_CTRL 28 +#define BIT_MASK_GPIO_GPB6_PULL_CTRL 0x3 +#define BIT_GPIO_GPB6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB6_PULL_CTRL) << BIT_SHIFT_GPIO_GPB6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB5_PULL_CTRL 26 +#define BIT_MASK_GPIO_GPB5_PULL_CTRL 0x3 +#define BIT_GPIO_GPB5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB5_PULL_CTRL) << BIT_SHIFT_GPIO_GPB5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB4_PULL_CTRL 24 +#define BIT_MASK_GPIO_GPB4_PULL_CTRL 0x3 +#define BIT_GPIO_GPB4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB4_PULL_CTRL) << BIT_SHIFT_GPIO_GPB4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB3_PULL_CTRL 22 +#define BIT_MASK_GPIO_GPB3_PULL_CTRL 0x3 +#define BIT_GPIO_GPB3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB3_PULL_CTRL) << BIT_SHIFT_GPIO_GPB3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB2_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPB2_PULL_CTRL 0x3 +#define BIT_GPIO_GPB2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB2_PULL_CTRL) << BIT_SHIFT_GPIO_GPB2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB1_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPB1_PULL_CTRL 0x3 +#define BIT_GPIO_GPB1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB1_PULL_CTRL) << BIT_SHIFT_GPIO_GPB1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPB0_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPB0_PULL_CTRL 0x3 +#define BIT_GPIO_GPB0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPB0_PULL_CTRL) << BIT_SHIFT_GPIO_GPB0_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA7_PULL_CTRL 14 +#define BIT_MASK_GPIO_GPA7_PULL_CTRL 0x3 +#define BIT_GPIO_GPA7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA7_PULL_CTRL) << BIT_SHIFT_GPIO_GPA7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA6_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPA6_PULL_CTRL 0x3 +#define BIT_GPIO_GPA6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA6_PULL_CTRL) << BIT_SHIFT_GPIO_GPA6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPA5_PULL_CTRL 0x3 +#define BIT_GPIO_GPA5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA5_PULL_CTRL) << BIT_SHIFT_GPIO_GPA5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPA4_PULL_CTRL 0x3 +#define BIT_GPIO_GPA4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA4_PULL_CTRL) << BIT_SHIFT_GPIO_GPA4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPA3_PULL_CTRL 0x3 +#define BIT_GPIO_GPA3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA3_PULL_CTRL) << BIT_SHIFT_GPIO_GPA3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPA2_PULL_CTRL 0x3 +#define BIT_GPIO_GPA2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA2_PULL_CTRL) << BIT_SHIFT_GPIO_GPA2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPA1_PULL_CTRL 0x3 +#define BIT_GPIO_GPA1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA1_PULL_CTRL) << BIT_SHIFT_GPIO_GPA1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPA0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPA0_PULL_CTRL 0x3 +#define BIT_GPIO_GPA0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPA0_PULL_CTRL) << BIT_SHIFT_GPIO_GPA0_PULL_CTRL) + + +//2 REG_GPIO_PULL_CTRL1 + +#define BIT_SHIFT_GPIO_GPD7_PULL_CTRL 29 +#define BIT_MASK_GPIO_GPD7_PULL_CTRL 0x7 +#define BIT_GPIO_GPD7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD7_PULL_CTRL) << BIT_SHIFT_GPIO_GPD7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD6_PULL_CTRL 28 +#define BIT_MASK_GPIO_GPD6_PULL_CTRL 0x3 +#define BIT_GPIO_GPD6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD6_PULL_CTRL) << BIT_SHIFT_GPIO_GPD6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD5_PULL_CTRL 26 +#define BIT_MASK_GPIO_GPD5_PULL_CTRL 0x3 +#define BIT_GPIO_GPD5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD5_PULL_CTRL) << BIT_SHIFT_GPIO_GPD5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD4_PULL_CTRL 24 +#define BIT_MASK_GPIO_GPD4_PULL_CTRL 0x3 +#define BIT_GPIO_GPD4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD4_PULL_CTRL) << BIT_SHIFT_GPIO_GPD4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD3_PULL_CTRL 22 +#define BIT_MASK_GPIO_GPD3_PULL_CTRL 0x3 +#define BIT_GPIO_GPD3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD3_PULL_CTRL) << BIT_SHIFT_GPIO_GPD3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD2_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPD2_PULL_CTRL 0x3 +#define BIT_GPIO_GPD2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD2_PULL_CTRL) << BIT_SHIFT_GPIO_GPD2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD1_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPD1_PULL_CTRL 0x3 +#define BIT_GPIO_GPD1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD1_PULL_CTRL) << BIT_SHIFT_GPIO_GPD1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD0_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPD0_PULL_CTRL 0x3 +#define BIT_GPIO_GPD0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD0_PULL_CTRL) << BIT_SHIFT_GPIO_GPD0_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC7_PULL_CTRL 14 +#define BIT_MASK_GPIO_GPC7_PULL_CTRL 0x3 +#define BIT_GPIO_GPC7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC7_PULL_CTRL) << BIT_SHIFT_GPIO_GPC7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC6_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPC6_PULL_CTRL 0x3 +#define BIT_GPIO_GPC6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC6_PULL_CTRL) << BIT_SHIFT_GPIO_GPC6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPC5_PULL_CTRL 0x3 +#define BIT_GPIO_GPC5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC5_PULL_CTRL) << BIT_SHIFT_GPIO_GPC5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPC4_PULL_CTRL 0x3 +#define BIT_GPIO_GPC4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC4_PULL_CTRL) << BIT_SHIFT_GPIO_GPC4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPC3_PULL_CTRL 0x3 +#define BIT_GPIO_GPC3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC3_PULL_CTRL) << BIT_SHIFT_GPIO_GPC3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPC2_PULL_CTRL 0x3 +#define BIT_GPIO_GPC2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC2_PULL_CTRL) << BIT_SHIFT_GPIO_GPC2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPC1_PULL_CTRL 0x3 +#define BIT_GPIO_GPC1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC1_PULL_CTRL) << BIT_SHIFT_GPIO_GPC1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPC0_PULL_CTRL 0x3 +#define BIT_GPIO_GPC0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC0_PULL_CTRL) << BIT_SHIFT_GPIO_GPC0_PULL_CTRL) + + +//2 REG_GPIO_PULL_CTRL2 + +#define BIT_SHIFT_GPIO_GPF5_PULL_CTRL 26 +#define BIT_MASK_GPIO_GPF5_PULL_CTRL 0x3 +#define BIT_GPIO_GPF5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF5_PULL_CTRL) << BIT_SHIFT_GPIO_GPF5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPF4_PULL_CTRL 24 +#define BIT_MASK_GPIO_GPF4_PULL_CTRL 0x3 +#define BIT_GPIO_GPF4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF4_PULL_CTRL) << BIT_SHIFT_GPIO_GPF4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPF3_PULL_CTRL 22 +#define BIT_MASK_GPIO_GPF3_PULL_CTRL 0x3 +#define BIT_GPIO_GPF3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF3_PULL_CTRL) << BIT_SHIFT_GPIO_GPF3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPF2_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPF2_PULL_CTRL 0x3 +#define BIT_GPIO_GPF2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF2_PULL_CTRL) << BIT_SHIFT_GPIO_GPF2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPF1_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPF1_PULL_CTRL 0x3 +#define BIT_GPIO_GPF1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF1_PULL_CTRL) << BIT_SHIFT_GPIO_GPF1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPF0_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPF0_PULL_CTRL 0x3 +#define BIT_GPIO_GPF0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPF0_PULL_CTRL) << BIT_SHIFT_GPIO_GPF0_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE7_PULL_CTRL 14 +#define BIT_MASK_GPIO_GPE7_PULL_CTRL 0x3 +#define BIT_GPIO_GPE7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE7_PULL_CTRL) << BIT_SHIFT_GPIO_GPE7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE6_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPE6_PULL_CTRL 0x3 +#define BIT_GPIO_GPE6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE6_PULL_CTRL) << BIT_SHIFT_GPIO_GPE6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPE5_PULL_CTRL 0x3 +#define BIT_GPIO_GPE5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE5_PULL_CTRL) << BIT_SHIFT_GPIO_GPE5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPE4_PULL_CTRL 0x3 +#define BIT_GPIO_GPE4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE4_PULL_CTRL) << BIT_SHIFT_GPIO_GPE4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPE3_PULL_CTRL 0x3 +#define BIT_GPIO_GPE3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE3_PULL_CTRL) << BIT_SHIFT_GPIO_GPE3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPE2_PULL_CTRL 0x3 +#define BIT_GPIO_GPE2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE2_PULL_CTRL) << BIT_SHIFT_GPIO_GPE2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPE1_PULL_CTRL 0x3 +#define BIT_GPIO_GPE1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE1_PULL_CTRL) << BIT_SHIFT_GPIO_GPE1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPE0_PULL_CTRL 0x3 +#define BIT_GPIO_GPE0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE0_PULL_CTRL) << BIT_SHIFT_GPIO_GPE0_PULL_CTRL) + + +//2 REG_NOT_VALID + +#define BIT_SHIFT_GPIO_GPH7_PULL_CTRL 30 +#define BIT_MASK_GPIO_GPH7_PULL_CTRL 0x3 +#define BIT_GPIO_GPH7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH7_PULL_CTRL) << BIT_SHIFT_GPIO_GPH7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH6_PULL_CTRL 28 +#define BIT_MASK_GPIO_GPH6_PULL_CTRL 0x3 +#define BIT_GPIO_GPH6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH6_PULL_CTRL) << BIT_SHIFT_GPIO_GPH6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH5_PULL_CTRL 26 +#define BIT_MASK_GPIO_GPH5_PULL_CTRL 0x3 +#define BIT_GPIO_GPH5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH5_PULL_CTRL) << BIT_SHIFT_GPIO_GPH5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH4_PULL_CTRL 24 +#define BIT_MASK_GPIO_GPH4_PULL_CTRL 0x3 +#define BIT_GPIO_GPH4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH4_PULL_CTRL) << BIT_SHIFT_GPIO_GPH4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH3_PULL_CTRL 22 +#define BIT_MASK_GPIO_GPH3_PULL_CTRL 0x3 +#define BIT_GPIO_GPH3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH3_PULL_CTRL) << BIT_SHIFT_GPIO_GPH3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH2_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPH2_PULL_CTRL 0x3 +#define BIT_GPIO_GPH2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH2_PULL_CTRL) << BIT_SHIFT_GPIO_GPH2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH1_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPH1_PULL_CTRL 0x3 +#define BIT_GPIO_GPH1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH1_PULL_CTRL) << BIT_SHIFT_GPIO_GPH1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPH0_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPH0_PULL_CTRL 0x3 +#define BIT_GPIO_GPH0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPH0_PULL_CTRL) << BIT_SHIFT_GPIO_GPH0_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG7_PULL_CTRL 14 +#define BIT_MASK_GPIO_GPG7_PULL_CTRL 0x3 +#define BIT_GPIO_GPG7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG7_PULL_CTRL) << BIT_SHIFT_GPIO_GPG7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG6_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPG6_PULL_CTRL 0x3 +#define BIT_GPIO_GPG6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG6_PULL_CTRL) << BIT_SHIFT_GPIO_GPG6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPG5_PULL_CTRL 0x3 +#define BIT_GPIO_GPG5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG5_PULL_CTRL) << BIT_SHIFT_GPIO_GPG5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPG4_PULL_CTRL 0x3 +#define BIT_GPIO_GPG4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG4_PULL_CTRL) << BIT_SHIFT_GPIO_GPG4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPG3_PULL_CTRL 0x3 +#define BIT_GPIO_GPG3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG3_PULL_CTRL) << BIT_SHIFT_GPIO_GPG3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPG2_PULL_CTRL 0x3 +#define BIT_GPIO_GPG2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG2_PULL_CTRL) << BIT_SHIFT_GPIO_GPG2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPG1_PULL_CTRL 0x3 +#define BIT_GPIO_GPG1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG1_PULL_CTRL) << BIT_SHIFT_GPIO_GPG1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPG0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPG0_PULL_CTRL 0x3 +#define BIT_GPIO_GPG0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPG0_PULL_CTRL) << BIT_SHIFT_GPIO_GPG0_PULL_CTRL) + + +//2 REG_GPIO_PULL_CTRL4 + +#define BIT_SHIFT_GPIO_GPJ6_PULL_CTRL 28 +#define BIT_MASK_GPIO_GPJ6_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ6_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ5_PULL_CTRL 26 +#define BIT_MASK_GPIO_GPJ5_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ5_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ4_PULL_CTRL 24 +#define BIT_MASK_GPIO_GPJ4_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ4_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ3_PULL_CTRL 22 +#define BIT_MASK_GPIO_GPJ3_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ3_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ2_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPJ2_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ2_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ1_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPJ1_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ1_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPJ0_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPJ0_PULL_CTRL 0x3 +#define BIT_GPIO_GPJ0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPJ0_PULL_CTRL) << BIT_SHIFT_GPIO_GPJ0_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI7_PULL_CTRL 14 +#define BIT_MASK_GPIO_GPI7_PULL_CTRL 0x3 +#define BIT_GPIO_GPI7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI7_PULL_CTRL) << BIT_SHIFT_GPIO_GPI7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI6_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPI6_PULL_CTRL 0x3 +#define BIT_GPIO_GPI6_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI6_PULL_CTRL) << BIT_SHIFT_GPIO_GPI6_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPI5_PULL_CTRL 0x3 +#define BIT_GPIO_GPI5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI5_PULL_CTRL) << BIT_SHIFT_GPIO_GPI5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPI4_PULL_CTRL 0x3 +#define BIT_GPIO_GPI4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI4_PULL_CTRL) << BIT_SHIFT_GPIO_GPI4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPI3_PULL_CTRL 0x3 +#define BIT_GPIO_GPI3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI3_PULL_CTRL) << BIT_SHIFT_GPIO_GPI3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPI2_PULL_CTRL 0x3 +#define BIT_GPIO_GPI2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI2_PULL_CTRL) << BIT_SHIFT_GPIO_GPI2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPI1_PULL_CTRL 0x3 +#define BIT_GPIO_GPI1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI1_PULL_CTRL) << BIT_SHIFT_GPIO_GPI1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPI0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPI0_PULL_CTRL 0x3 +#define BIT_GPIO_GPI0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPI0_PULL_CTRL) << BIT_SHIFT_GPIO_GPI0_PULL_CTRL) + + +//2 REG_GPIO_PULL_CTRL5 + +#define BIT_SHIFT_GPIO_GPEA_PULL_CTRL 20 +#define BIT_MASK_GPIO_GPEA_PULL_CTRL 0x3 +#define BIT_GPIO_GPEA_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPEA_PULL_CTRL) << BIT_SHIFT_GPIO_GPEA_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE9_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPE9_PULL_CTRL 0x3 +#define BIT_GPIO_GPE9_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE9_PULL_CTRL) << BIT_SHIFT_GPIO_GPE9_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPE8_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPE8_PULL_CTRL 0x3 +#define BIT_GPIO_GPE8_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPE8_PULL_CTRL) << BIT_SHIFT_GPIO_GPE8_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK7_PULL_CTRL 12 +#define BIT_MASK_GPIO_GPK7_PULL_CTRL 0x3 +#define BIT_GPIO_GPK7_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK7_PULL_CTRL) << BIT_SHIFT_GPIO_GPK7_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK5_PULL_CTRL 10 +#define BIT_MASK_GPIO_GPK5_PULL_CTRL 0x3 +#define BIT_GPIO_GPK5_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK5_PULL_CTRL) << BIT_SHIFT_GPIO_GPK5_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK4_PULL_CTRL 8 +#define BIT_MASK_GPIO_GPK4_PULL_CTRL 0x3 +#define BIT_GPIO_GPK4_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK4_PULL_CTRL) << BIT_SHIFT_GPIO_GPK4_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK3_PULL_CTRL 6 +#define BIT_MASK_GPIO_GPK3_PULL_CTRL 0x3 +#define BIT_GPIO_GPK3_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK3_PULL_CTRL) << BIT_SHIFT_GPIO_GPK3_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK2_PULL_CTRL 4 +#define BIT_MASK_GPIO_GPK2_PULL_CTRL 0x3 +#define BIT_GPIO_GPK2_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK2_PULL_CTRL) << BIT_SHIFT_GPIO_GPK2_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK1_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPK1_PULL_CTRL 0x3 +#define BIT_GPIO_GPK1_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK1_PULL_CTRL) << BIT_SHIFT_GPIO_GPK1_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPK0_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPK0_PULL_CTRL 0x3 +#define BIT_GPIO_GPK0_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPK0_PULL_CTRL) << BIT_SHIFT_GPIO_GPK0_PULL_CTRL) + + +//2 REG_GPIO_PULL_CTRL6 + +#define BIT_SHIFT_GPIO_GPD9_PULL_CTRL 18 +#define BIT_MASK_GPIO_GPD9_PULL_CTRL 0x3 +#define BIT_GPIO_GPD9_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD9_PULL_CTRL) << BIT_SHIFT_GPIO_GPD9_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPD8_PULL_CTRL 16 +#define BIT_MASK_GPIO_GPD8_PULL_CTRL 0x3 +#define BIT_GPIO_GPD8_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPD8_PULL_CTRL) << BIT_SHIFT_GPIO_GPD8_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC9_PULL_CTRL 2 +#define BIT_MASK_GPIO_GPC9_PULL_CTRL 0x3 +#define BIT_GPIO_GPC9_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC9_PULL_CTRL) << BIT_SHIFT_GPIO_GPC9_PULL_CTRL) + + +#define BIT_SHIFT_GPIO_GPC8_PULL_CTRL 0 +#define BIT_MASK_GPIO_GPC8_PULL_CTRL 0x3 +#define BIT_GPIO_GPC8_PULL_CTRL(x) (((x) & BIT_MASK_GPIO_GPC8_PULL_CTRL) << BIT_SHIFT_GPIO_GPC8_PULL_CTRL) + + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_PERI_PWM0_CTRL +#define BIT_PERI_PWM0_EN BIT(31) + +#define BIT_SHIFT_PERI_PWM0_GT_SEL 24 +#define BIT_MASK_PERI_PWM0_GT_SEL 0xf +#define BIT_PERI_PWM0_GT_SEL(x) (((x) & BIT_MASK_PERI_PWM0_GT_SEL) << BIT_SHIFT_PERI_PWM0_GT_SEL) + + +#define BIT_SHIFT_PERI_PWM0_DUTY 12 +#define BIT_MASK_PERI_PWM0_DUTY 0x3ff +#define BIT_PERI_PWM0_DUTY(x) (((x) & BIT_MASK_PERI_PWM0_DUTY) << BIT_SHIFT_PERI_PWM0_DUTY) + + +#define BIT_SHIFT_PERI_PWM0_PERIOD 0 +#define BIT_MASK_PERI_PWM0_PERIOD 0x3ff +#define BIT_PERI_PWM0_PERIOD(x) (((x) & BIT_MASK_PERI_PWM0_PERIOD) << BIT_SHIFT_PERI_PWM0_PERIOD) + + +//2 REG_PERI_PWM1_CTRL +#define BIT_PERI_PWM1_EN BIT(31) + +#define BIT_SHIFT_PERI_PWM1_GT_SEL 24 +#define BIT_MASK_PERI_PWM1_GT_SEL 0xf +#define BIT_PERI_PWM1_GT_SEL(x) (((x) & BIT_MASK_PERI_PWM1_GT_SEL) << BIT_SHIFT_PERI_PWM1_GT_SEL) + + +#define BIT_SHIFT_PERI_PWM1_DUTY 12 +#define BIT_MASK_PERI_PWM1_DUTY 0x3ff +#define BIT_PERI_PWM1_DUTY(x) (((x) & BIT_MASK_PERI_PWM1_DUTY) << BIT_SHIFT_PERI_PWM1_DUTY) + + +#define BIT_SHIFT_PERI_PWM1_PERIOD 0 +#define BIT_MASK_PERI_PWM1_PERIOD 0x3ff +#define BIT_PERI_PWM1_PERIOD(x) (((x) & BIT_MASK_PERI_PWM1_PERIOD) << BIT_SHIFT_PERI_PWM1_PERIOD) + + +//2 REG_PERI_PWM2_CTRL +#define BIT_PERI_PWM2_EN BIT(31) + +#define BIT_SHIFT_PERI_PWM2_GT_SEL 24 +#define BIT_MASK_PERI_PWM2_GT_SEL 0xf +#define BIT_PERI_PWM2_GT_SEL(x) (((x) & BIT_MASK_PERI_PWM2_GT_SEL) << BIT_SHIFT_PERI_PWM2_GT_SEL) + + +#define BIT_SHIFT_PERI_PWM2_DUTY 12 +#define BIT_MASK_PERI_PWM2_DUTY 0x3ff +#define BIT_PERI_PWM2_DUTY(x) (((x) & BIT_MASK_PERI_PWM2_DUTY) << BIT_SHIFT_PERI_PWM2_DUTY) + + +#define BIT_SHIFT_PERI_PWM2_PERIOD 0 +#define BIT_MASK_PERI_PWM2_PERIOD 0x3ff +#define BIT_PERI_PWM2_PERIOD(x) (((x) & BIT_MASK_PERI_PWM2_PERIOD) << BIT_SHIFT_PERI_PWM2_PERIOD) + + +//2 REG_PERI_PWM3_CTRL +#define BIT_PERI_PWM3_EN BIT(31) + +#define BIT_SHIFT_PERI_PWM3_GT_SEL 24 +#define BIT_MASK_PERI_PWM3_GT_SEL 0xf +#define BIT_PERI_PWM3_GT_SEL(x) (((x) & BIT_MASK_PERI_PWM3_GT_SEL) << BIT_SHIFT_PERI_PWM3_GT_SEL) + + +#define BIT_SHIFT_PERI_PWM3_DUTY 12 +#define BIT_MASK_PERI_PWM3_DUTY 0x3ff +#define BIT_PERI_PWM3_DUTY(x) (((x) & BIT_MASK_PERI_PWM3_DUTY) << BIT_SHIFT_PERI_PWM3_DUTY) + + +#define BIT_SHIFT_PERI_PWM3_PERIOD 0 +#define BIT_MASK_PERI_PWM3_PERIOD 0x3ff +#define BIT_PERI_PWM3_PERIOD(x) (((x) & BIT_MASK_PERI_PWM3_PERIOD) << BIT_SHIFT_PERI_PWM3_PERIOD) + + +//2 REG_PERI_TIM_EVT_CTRL +#define BIT_PERI_GT_EVT3_EN BIT(31) + +#define BIT_SHIFT_PERI_GT_EVT3_SRC_SEL 28 +#define BIT_MASK_PERI_GT_EVT3_SRC_SEL 0x7 +#define BIT_PERI_GT_EVT3_SRC_SEL(x) (((x) & BIT_MASK_PERI_GT_EVT3_SRC_SEL) << BIT_SHIFT_PERI_GT_EVT3_SRC_SEL) + + +#define BIT_SHIFT_PERI_GT_EVT3_PULSE_DUR 24 +#define BIT_MASK_PERI_GT_EVT3_PULSE_DUR 0xf +#define BIT_PERI_GT_EVT3_PULSE_DUR(x) (((x) & BIT_MASK_PERI_GT_EVT3_PULSE_DUR) << BIT_SHIFT_PERI_GT_EVT3_PULSE_DUR) + +#define BIT_PERI_GT_EVT2_EN BIT(23) + +#define BIT_SHIFT_PERI_GT_EVT2_SRC_SEL 20 +#define BIT_MASK_PERI_GT_EVT2_SRC_SEL 0x7 +#define BIT_PERI_GT_EVT2_SRC_SEL(x) (((x) & BIT_MASK_PERI_GT_EVT2_SRC_SEL) << BIT_SHIFT_PERI_GT_EVT2_SRC_SEL) + + +#define BIT_SHIFT_PERI_GT_EVT2_PULSE_DUR 16 +#define BIT_MASK_PERI_GT_EVT2_PULSE_DUR 0xf +#define BIT_PERI_GT_EVT2_PULSE_DUR(x) (((x) & BIT_MASK_PERI_GT_EVT2_PULSE_DUR) << BIT_SHIFT_PERI_GT_EVT2_PULSE_DUR) + +#define BIT_PERI_GT_EVT1_EN BIT(15) + +#define BIT_SHIFT_PERI_GT_EVT1_SRC_SEL 12 +#define BIT_MASK_PERI_GT_EVT1_SRC_SEL 0x7 +#define BIT_PERI_GT_EVT1_SRC_SEL(x) (((x) & BIT_MASK_PERI_GT_EVT1_SRC_SEL) << BIT_SHIFT_PERI_GT_EVT1_SRC_SEL) + + +#define BIT_SHIFT_PERI_GT_EVT1_PULSE_DUR 8 +#define BIT_MASK_PERI_GT_EVT1_PULSE_DUR 0xf +#define BIT_PERI_GT_EVT1_PULSE_DUR(x) (((x) & BIT_MASK_PERI_GT_EVT1_PULSE_DUR) << BIT_SHIFT_PERI_GT_EVT1_PULSE_DUR) + +#define BIT_PERI_GT_EVT0_EN BIT(7) + +#define BIT_SHIFT_PERI_GT_EVT0_SRC_SEL 4 +#define BIT_MASK_PERI_GT_EVT0_SRC_SEL 0x7 +#define BIT_PERI_GT_EVT0_SRC_SEL(x) (((x) & BIT_MASK_PERI_GT_EVT0_SRC_SEL) << BIT_SHIFT_PERI_GT_EVT0_SRC_SEL) + + +#define BIT_SHIFT_PERI_GT_EVT0_PULSE_DUR 0 +#define BIT_MASK_PERI_GT_EVT0_PULSE_DUR 0xf +#define BIT_PERI_GT_EVT0_PULSE_DUR(x) (((x) & BIT_MASK_PERI_GT_EVT0_PULSE_DUR) << BIT_SHIFT_PERI_GT_EVT0_PULSE_DUR) + + +//2 REG_PERI_EGTIM_CTRL + +#define BIT_SHIFT_PERI_EGTIM_PIN_GROUP2_OPT_SEL 12 +#define BIT_MASK_PERI_EGTIM_PIN_GROUP2_OPT_SEL 0x3 +#define BIT_PERI_EGTIM_PIN_GROUP2_OPT_SEL(x) (((x) & BIT_MASK_PERI_EGTIM_PIN_GROUP2_OPT_SEL) << BIT_SHIFT_PERI_EGTIM_PIN_GROUP2_OPT_SEL) + + +#define BIT_SHIFT_PERI_EGTIM_PIN_GROUP1_OPT_SEL 10 +#define BIT_MASK_PERI_EGTIM_PIN_GROUP1_OPT_SEL 0x3 +#define BIT_PERI_EGTIM_PIN_GROUP1_OPT_SEL(x) (((x) & BIT_MASK_PERI_EGTIM_PIN_GROUP1_OPT_SEL) << BIT_SHIFT_PERI_EGTIM_PIN_GROUP1_OPT_SEL) + + +#define BIT_SHIFT_PERI_EGTIM_PIN_GROUP0_OPT_SEL 8 +#define BIT_MASK_PERI_EGTIM_PIN_GROUP0_OPT_SEL 0x3 +#define BIT_PERI_EGTIM_PIN_GROUP0_OPT_SEL(x) (((x) & BIT_MASK_PERI_EGTIM_PIN_GROUP0_OPT_SEL) << BIT_SHIFT_PERI_EGTIM_PIN_GROUP0_OPT_SEL) + + +//2 REG_NOT_VALID + +#define BIT_SHIFT_PERI_EGTIM_REF_SIG_SEL 4 +#define BIT_MASK_PERI_EGTIM_REF_SIG_SEL 0x3 +#define BIT_PERI_EGTIM_REF_SIG_SEL(x) (((x) & BIT_MASK_PERI_EGTIM_REF_SIG_SEL) << BIT_SHIFT_PERI_EGTIM_REF_SIG_SEL) + +#define BIT_PERI_EGTIM_EN BIT(0) + +//2 REG_NOT_VALID + +//2 REG_PEON_CFG + +//2 REG_PEON_STATUS +#define BIT_PEON_SDIO_ALDN BIT(0) + + +//========== Register Address Definition ==================// +#define REG_PEON_PWR_CTRL 0x0200 +#define REG_PON_ISO_CTRL 0x0204 +#define REG_SOC_FUNC_EN 0x0210 +#define REG_SOC_HCI_COM_FUNC_EN 0x0214 +#define REG_SOC_PERI_FUNC0_EN 0x0218 +#define REG_SOC_PERI_FUNC1_EN 0x021C +#define REG_SOC_PERI_BD_FUNC0_EN 0x0220 +#define REG_PESOC_CLK_CTRL 0x0230 +#define REG_PESOC_PERI_CLK_CTRL0 0x0234 +#define REG_PESOC_PERI_CLK_CTRL1 0x0238 +#define REG_PESOC_CLK_CTRL3 0x023C +#define REG_PESOC_HCI_CLK_CTRL0 0x0240 +#define REG_PESOC_COM_CLK_CTRL1 0x0244 +#define REG_PESOC_HW_ENG_CLK_CTRL 0x0248 +#define REG_PESOC_CLK_SEL 0x0250 +#define REG_SYS_ANACK_CAL_CTRL 0x026C +#define REG_OSC32K_CTRL 0x0270 +#define REG_OSC32K_REG_CTRL0 0x0274 +#define REG_OSC32K_REG_CTRL1 0x0278 +#define REG_THERMAL_METER_CTRL 0x027C +#define REG_UART_MUX_CTRL 0x0280 +#define REG_SPI_MUX_CTRL 0x0284 +#define REG_I2C_MUX_CTRL 0x0288 +#define REG_I2S_MUX_CTRL 0x028C +#define REG_HCI_PINMUX_CTRL 0x02A0 +#define REG_WL_PINMUX_CTRL 0x02A4 +#define REG_BT_PINMUX_CTRL 0x02A8 +#define REG_PWM_PINMUX_CTRL 0x02AC +#define REG_CPU_PERIPHERAL_CTRL 0x02C0 +#define REG_HCI_CTRL_STATUS_0 0x02E0 +#define REG_HCI_CTRL_STATUS_1 0x02E4 +#define REG_PESOC_MEM_CTRL 0x0300 +#define REG_PESOC_SOC_CTRL 0x0304 +#define REG_PESOC_PERI_CTRL 0x0308 +#define REG_GPIO_SHTDN_CTRL 0x0320 +#define REG_GPIO_DRIVING_CTRL 0x0324 +#define REG_GPIO_PULL_CTRL0 0x0330 +#define REG_GPIO_PULL_CTRL1 0x0334 +#define REG_GPIO_PULL_CTRL2 0x0338 +#define REG_GPIO_PULL_CTRL3 0x033C +#define REG_GPIO_PULL_CTRL4 0x0340 +#define REG_GPIO_PULL_CTRL5 0x0344 +#define REG_GPIO_PULL_CTRL6 0x0348 +#define REG_PERI_PWM0_CTRL 0x0360 +#define REG_PERI_PWM1_CTRL 0x0364 +#define REG_PERI_PWM2_CTRL 0x0368 +#define REG_PERI_PWM3_CTRL 0x036C +#define REG_PERI_TIM_EVT_CTRL 0x0370 +#define REG_PERI_EGTIM_CTRL 0x0374 +#define REG_PEON_CFG 0x03F0 +#define REG_PEON_STATUS 0x03F4 + + +#endif // end of "#ifndef __INC_RTL8195A_PERI_ON_H" diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pwm.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pwm.h new file mode 100644 index 0000000..b675c24 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_pwm.h @@ -0,0 +1,62 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_PWM_H_ +#define _RTL8195A_PWM_H_ +#include "basic_types.h" + +extern void +HAL_Pwm_SetDuty_8195a( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 period, + u32 pulse_width +); + +extern HAL_Status +HAL_Pwm_Init_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern void +HAL_Pwm_Enable_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern void +HAL_Pwm_Disable_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +); + + +#ifdef CONFIG_CHIP_E_CUT +extern _LONG_CALL_ void +HAL_Pwm_SetDuty_8195a_V04( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 period, + u32 pulse_width +); + +extern _LONG_CALL_ HAL_Status +HAL_Pwm_Init_8195a_V04( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern _LONG_CALL_ void +HAL_Pwm_Enable_8195a_V04( + HAL_PWM_ADAPTER *pPwmAdapt +); + +extern _LONG_CALL_ void +HAL_Pwm_Disable_8195a_V04( + HAL_PWM_ADAPTER *pPwmAdapt +); +#endif + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio.h new file mode 100644 index 0000000..500fe7c --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio.h @@ -0,0 +1,1033 @@ + /* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_SDIO_H_ +#define _RTL8195A_SDIO_H_ + +#include "hal_api.h" +#include "hal_util.h" +#if defined(CONFIG_SDIO_BOOT_SIM) || defined(CONFIG_SDIO_BOOT_ROM) +#define SDIO_BOOT_DRIVER 1 // is this SDIO driver works for booting +#else +#include "osdep_api.h" +#define SDIO_BOOT_DRIVER 0 // is this SDIO driver works for booting +#endif + +#if defined(__IAR_SYSTEMS_ICC__) //for IAR SDK +#include "platform_opts.h" +#endif + +#ifndef CONFIG_INIC_EN +#define CONFIG_INIC_EN 0 +#endif +#if CONFIG_INIC_EN +#define CONFIG_INIC_SKB_TX 1 //use SKB for trx to improve the throughput +#define CONFIG_INIC_SKB_RX 1 +#endif + +#if defined(__IAR_SYSTEMS_ICC__) && (CONFIG_INIC_EN == 0)//for IAR SDK + #define SDIO_API_DEFINED 1 +#else + #define SDIO_API_DEFINED 0 +#endif + +#ifndef PRIORITIE_OFFSET //PRIORITIE_OFFSET in FreeRTOSConfig.h +#define PRIORITIE_OFFSET 0 +#endif + +#define SDIO_DEBUG 0 +#define SDIO_MP_MODE 0 // if includes MP mode function +#define SDIO_MAX_WAIT_RX_DMA 100 // Wait RX DMA done +#define SDIO_RX_PKT_SIZE_OVER_16K 0 /* is support SDIO RX packet size > 16K. if true, + a big packet will be transmited via multiple RX_BD */ +#define SDIO_MAILBOX_SIZE 10 // the maximum number of message block can be stored in this mailbox +#define SDIO_PERIODICAL_TIMER_INTERVAL 2000 // in ms, the interval of SDIO periodical timer +#define SDIO_AVG_TP_WIN_SIZE 20 // the number of entry to log the byte count for every periodical timer statistic, to calculate throughput + +#define HAL_SDIO_READ32(addr) HAL_READ32(SDIO_DEVICE_REG_BASE, addr) +#define HAL_SDIO_WRITE32(addr, value) HAL_WRITE32(SDIO_DEVICE_REG_BASE, addr, value) +#define HAL_SDIO_READ16(addr) HAL_READ16(SDIO_DEVICE_REG_BASE, addr) +#define HAL_SDIO_WRITE16(addr, value) HAL_WRITE16(SDIO_DEVICE_REG_BASE, addr, value) +#define HAL_SDIO_READ8(addr) HAL_READ8(SDIO_DEVICE_REG_BASE, addr) +#define HAL_SDIO_WRITE8(addr, value) HAL_WRITE8(SDIO_DEVICE_REG_BASE, addr, value) + +/***** Register Address *****/ +#define REG_SPDIO_TXBD_ADDR 0xA0 // 4 Bytes +#define REG_SPDIO_TXBD_SIZE 0xA4 // 4 Bytes +#define REG_SPDIO_TXBD_WPTR 0xA8 // 2 Bytes +#define REG_SPDIO_TXBD_RPTR 0xAC // 2 Bytes +#define REG_SPDIO_RXBD_ADDR 0xB0 // 4 Bytes +#define REG_SPDIO_RXBD_SIZE 0xB4 // 2 Bytes +#define REG_SPDIO_RXBD_C2H_WPTR 0xB6 // 2 Bytes +#define REG_SPDIO_RXBD_C2H_RPTR 0xB8 // 2 Bytes +#define REG_SPDIO_HCI_RX_REQ 0xBA // 1 Byte +#define REG_SPDIO_CPU_RST_DMA 0xBB // 1 Byte +#define REG_SPDIO_RX_REQ_ADDR 0xBC // 2 Bytes +#define REG_SPDIO_CPU_INT_MASK 0xC0 // 2 Bytes +#define REG_SPDIO_CPU_INT_STAS 0xC2 // 2 Bytes +#define REG_SPDIO_CCPWM 0xC4 // 1 Byts +#define REG_SPDIO_CPU_IND 0xC5 // 1 Byte +#define REG_SPDIO_CCPWM2 0xC6 // 2 Bytes +#define REG_SPDIO_CPU_H2C_MSG 0xC8 // 4 Bytes +#define REG_SPDIO_CPU_C2H_MSG 0xCC // 4 Bytes +#define REG_SPDIO_CRPWM 0xD0 // 1 Bytes +#define REG_SPDIO_CRPWM2 0xD2 // 2 Bytes +#define REG_SPDIO_AHB_DMA_CTRL 0xD4 // 4 Bytes +#define REG_SPDIO_RXBD_CNT 0xD8 // 4 Bytes +#define REG_SPDIO_TX_BUF_UNIT_SZ 0xD9 // 1 Bytes +#define REG_SPDIO_RX_BD_FREE_CNT 0xDA // 2 Bytes +#define REG_SPDIO_CPU_H2C_MSG_EXT 0xDC // 4 Bytes +#define REG_SPDIO_CPU_C2H_MSG_EXT 0xE0 // 4 Bytes + +// Register REG_SPDIO_CPU_RST_DMA +#define BIT_CPU_RST_SDIO_DMA BIT(7) + +// Register REG_SPDIO_CPU_INT_MASK, REG_SPDIO_CPU_INT_STAS +#define BIT_TXFIFO_H2C_OVF BIT(0) +#define BIT_H2C_BUS_RES_FAIL BIT(1) +#define BIT_H2C_DMA_OK BIT(2) +#define BIT_C2H_DMA_OK BIT(3) +#define BIT_H2C_MSG_INT BIT(4) +#define BIT_RPWM1_INT BIT(5) +#define BIT_RPWM2_INT BIT(6) +#define BIT_SDIO_RST_CMD_INT BIT(7) +#define BIT_RXBD_FLAG_ERR_INT BIT(8) +#define BIT_RX_BD_AVAI_INT BIT(9) +#define BIT_HOST_WAKE_CPU_INT BIT(10) + +// Register REG_SPDIO_CPU_IND +#define BIT_SYSTEM_TRX_RDY_IND BIT(0) + +// Register REG_SPDIO_HCI_RX_REQ +#define BIT_HCI_RX_REQ BIT(0) + +/* Register for SOC_HCI_COM_FUN_EN */ +#define BIT_SOC_HCI_SDIOD_OFF_EN BIT(1) // SDIO Function Block on Power_Off domain +#define BIT_SOC_HCI_SDIOD_ON_EN BIT(0) // SDIO Function Block on Power_On domain + +/* Register REG_PESOC_HCI_CLK_CTRL0 */ +#define BIT_SOC_SLPCK_SDIO_HST_EN BIT(3) // SDIO_HST clock enable when CPU sleep command +#define BIT_SOC_ACTCK_SDIO_HST_EN BIT(2) // SDIO_HST clock enable in CPU run mode +#define BIT_SOC_SLPCK_SDIO_DEV_EN BIT(1) // SDIO_DEV clock enable when CPU sleep command +#define BIT_SOC_ACTCK_SDIO_DEV_EN BIT(0) // SDIO_DEV clock enable in CPU run mode + +/***** Structer for each Register *****/ +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) +// Little Endian +// Register REG_SPDIO_HCI_RX_REQ @ 0xBA +typedef struct _SPDIO_HCI_RX_REQ { + u8 HCI_RX_REQ:1; /* bit[0], CPU trigger this bit to enable SDIO IP RX transfer by fetch BD info */ + u8 Reserved:7; /* bit[7:1], Reserved */ +} SPDIO_HCI_RX_REQ, *PSPDIO_HCI_RX_REQ; + +// Register REG_SPDIO_CPU_RST_DMA @ 0xBB +typedef struct _SPDIO_CPU_RST_DMA { + u8 Reserved:7; /* bit[6:0], Reserved */ + u8 CPU_RST_SDIO:1; /* bit[7], CPU set this bit to reset SDIO DMA */ +} SPDIO_CPU_RST_DMA, *PSPDIO_CPU_RST_DMA; + +// Register REG_SPDIO_CPU_INT_MASK @ 0xC0 +typedef struct _SPDIO_CPU_INT_MASK { + u16 TXFIFO_H2C_OVF:1; /* bit[0], set 0 to mask TXFIFO_H2C_OVF_INT */ + u16 H2C_BUS_RES_FAIL:1; /* bit[1], set 0 to mask H2C_BUS_RES_FAIL_INT */ + u16 H2C_DMA_OK:1; /* bit[2], set 0 to mask H2C_DMA_OK_INT */ + u16 C2H_DMA_OK:1; /* bit[3], set 0 to mask C2H_DMA_OK_INT */ + u16 H2C_MSG_INT:1; /* bit[4], set 0 to mask H2C_MSG_INT_INT */ + u16 RPWM_INT:1; /* bit[5], set 0 to mask RPWM_INT */ + u16 RPWM2_INT:1; /* bit[6], set 0 to mask RPWM2_INT */ + u16 SDIO_RST_CMD_INT:1; /* bit[7], set 0 to mask SDIO_RST_CMD_INT */ + u16 BD_FLAG_ERR_INT:1; /* bit[8], set 0 to mask BD_FLAG_ERR_INT */ + u16 Reserved:7; /* bit[15:9], Reserved */ +} SPDIO_CPU_INT_MASK, *PSPDIO_CPU_INT_MASK; + +// Register REG_SPDIO_CPU_INT_STATUS @ 0xC2 +typedef struct _SPDIO_CPU_INT_STAS { + u16 TXFIFO_H2C_OVF:1; /* bit[0], set 0 to mask TXFIFO_H2C_OVF_INT */ + u16 H2C_BUS_RES_FAIL:1; /* bit[1], set 0 to mask H2C_BUS_RES_FAIL_INT */ + u16 H2C_DMA_OK:1; /* bit[2], set 0 to mask H2C_DMA_OK_INT */ + u16 C2H_DMA_OK:1; /* bit[3], set 0 to mask C2H_DMA_OK_INT */ + u16 H2C_MSG_INT:1; /* bit[4], set 0 to mask H2C_MSG_INT_INT */ + u16 RPWM_INT:1; /* bit[5], set 0 to mask RPWM_INT */ + u16 RPWM2_INT:1; /* bit[6], set 0 to mask RPWM2_INT */ + u16 SDIO_RST_CMD_INT:1; /* bit[7], set 0 to mask SDIO_RST_CMD_INT */ + u16 BD_FLAG_ERR_INT:1; /* bit[8], set 0 to mask BD_FLAG_ERR_INT */ + u16 Reserved:7; /* bit[15:9], Reserved */ +} SPDIO_CPU_INT_STAS, *PSPDIO_CPU_INT_STAS; + +// Register REG_SPDIO_CCPWM @ 0xC4 +typedef struct _SPDIO_CCPWM { + u8 :1; /* bit[0] */ + u8 WLAN_TRX:1; /* bit[1], 0: WLAN Off; 1: WLAN On */ + u8 RPS_ST:1; /* bit[2], 0/1: AP Register Sleep/Active state */ + u8 WWLAN:1; /* bit[3], 0/1: "Wake on WLAN"/"Normal" state */ + u8 Reserved:3; /* bit[6:4], Reserved */ + u8 TOGGLING:1; /* bit[7], issue interrupt when 0->1 or 1->0 */ +} SPDIO_CCPWM, *PSPDIO_CCPWM; + +// Register REG_SPDIO_CPU_IND @ 0xC5 +typedef struct _SPDIO_CPU_IND { + u8 SYS_TRX_RDY:1; /* bit[0], To indicate the Host system that CPU is ready for TRX + , to be sync to 0x87[0] */ + u8 Reserved:7; /* bit[7:1], Reserved */ +} SPDIO_CPU_IND, *PSPDIO_CPU_IND; + +// Register REG_SPDIO_CPU_H2C_MSG @ 0xC8 +typedef struct _SPDIO_CPU_H2C_MSG { + u32 CPU_H2C_MSG:30; /* bit[30:0], Host CPU to FW message, sync from REG_SDIO_H2C_MSG */ + u32 Reserved:1; /* bit[31], Reserved */ +} SPDIO_CPU_H2C_MSG, *PSPDIO_CPU_H2C_MSG; + +// Register REG_SPDIO_CPU_C2H_MSG @ 0xCC +typedef struct _SPDIO_CPU_C2H_MSG { + u32 CPU_C2H_MSG:30; /* bit[30:0], FW to Host CPU message, sync to REG_SDIO_C2H_MSG */ + u32 Reserved:1; /* bit[31], Reserved */ +} SPDIO_CPU_C2H_MSG, *PSPDIO_CPU_C2H_MSG; + +// Register REG_SPDIO_CRPWM @ 0xD0 +typedef struct _SPDIO_CRPWM { + u8 :1; /* bit[0] */ + u8 WLAN_TRX:1; /* bit[1], 0: WLAN Off; 1: WLAN On */ + u8 RPS_ST:1; /* bit[2], 0/1: AP Register Sleep/Active state */ + u8 WWLAN:1; /* bit[3], 0/1: "Wake on WLAN"/"Normal" state */ + u8 Reserved:3; /* bit[6:4], Reserved */ + u8 TOGGLING:1; /* bit[7], issue interrupt when 0->1 or 1->0 */ +} SPDIO_CRPWM, *PSPDIO_CRPWM; + +// Register REG_SPDIO_AHB_DMA_CTRL @ 0xD4 +typedef struct _SPDIO_AHB_DMA_CTRL { + u32 TXFF_WLEVEL:7; /* bit[6:0], SPDIO TX FIFO water level */ + u32 :1; /* bit[7] */ + u32 RXFF_WLEVEL:7; /* bit[14:8], SPDIO RX FIFO water level */ + u32 :1; /* bit[15] */ + u32 AHB_DMA_CS:4; /* bit[19:16], AHB DMA state */ + u32 :1; /* bit[20] */ + u32 AHB_MASTER_RDY:1; /* bit[21], AHB Master Hready signal */ + u32 AHB_DMA_TRANS:2; /* bit[23:22], AHB DMA Trans value, for debugging */ + u32 AHB_BUSY_WAIT_CNT:4; /* bit[27:24], timeout for AHB controller to wait busy */ + u32 AHB_BURST_TYPE:3; /* bit[30:28], AHB burst type */ + u32 DISPATCH_TXAGG:1; /* bit[31], Enable to dispatch aggregated TX packet */ +} SPDIO_AHB_DMA_CTRL, *PSPDIO_AHB_DMA_CTRL; + +#else /* else of '#if LITTLE_ENDIAN' */ +// Big Endian +typedef struct _SPDIO_HCI_RX_REQ { + u8 Reserved:7; /* bit[7:1], Reserved */ + u8 HCI_RX_REQ:1; /* bit[0], CPU trigger this bit to enable SDIO IP RX transfer by fetch BD info */ +} SPDIO_HCI_RX_REQ, *PSPDIO_HCI_RX_REQ; + +// Register REG_SPDIO_CPU_RST_DMA @ 0xBB +typedef struct _SPDIO_CPU_RST_DMA { + u8 CPU_RST_SDIO:1; /* bit[7], CPU set this bit to reset SDIO DMA */ + u8 Reserved:7; /* bit[6:0], Reserved */ +} SPDIO_CPU_RST_DMA, *PSPDIO_CPU_RST_DMA; + +// Register REG_SPDIO_CPU_INT_MASK @ 0xC0 +typedef struct _SPDIO_CPU_INT_MASK { + u16 Reserved:7; /* bit[15:9], Reserved */ + u16 BD_FLAG_ERR_INT:1; /* bit[8], set 0 to mask BD_FLAG_ERR_INT */ + u16 SDIO_RST_CMD_INT:1; /* bit[7], set 0 to mask SDIO_RST_CMD_INT */ + u16 RPWM2_INT:1; /* bit[6], set 0 to mask RPWM2_INT */ + u16 RPWM_INT:1; /* bit[5], set 0 to mask RPWM_INT */ + u16 H2C_MSG_INT:1; /* bit[4], set 0 to mask H2C_MSG_INT_INT */ + u16 C2H_DMA_OK:1; /* bit[3], set 0 to mask C2H_DMA_OK_INT */ + u16 H2C_DMA_OK:1; /* bit[2], set 0 to mask H2C_DMA_OK_INT */ + u16 H2C_BUS_RES_FAIL:1; /* bit[1], set 0 to mask H2C_BUS_RES_FAIL_INT */ + u16 TXFIFO_H2C_OVF:1; /* bit[0], set 0 to mask TXFIFO_H2C_OVF_INT */ +} SPDIO_CPU_INT_MASK, *PSPDIO_CPU_INT_MASK; + +// Register REG_SPDIO_CPU_INT_STAS @ 0xC2 +typedef struct _SPDIO_CPU_INT_STAS { + u16 Reserved:7; /* bit[15:9], Reserved */ + u16 BD_FLAG_ERR_INT:1; /* bit[8], set 0 to mask BD_FLAG_ERR_INT */ + u16 SDIO_RST_CMD_INT:1; /* bit[7], set 0 to mask SDIO_RST_CMD_INT */ + u16 RPWM2_INT:1; /* bit[6], set 0 to mask RPWM2_INT */ + u16 RPWM_INT:1; /* bit[5], set 0 to mask RPWM_INT */ + u16 H2C_MSG_INT:1; /* bit[4], set 0 to mask H2C_MSG_INT_INT */ + u16 C2H_DMA_OK:1; /* bit[3], set 0 to mask C2H_DMA_OK_INT */ + u16 H2C_DMA_OK:1; /* bit[2], set 0 to mask H2C_DMA_OK_INT */ + u16 H2C_BUS_RES_FAIL:1; /* bit[1], set 0 to mask H2C_BUS_RES_FAIL_INT */ + u16 TXFIFO_H2C_OVF:1; /* bit[0], set 0 to mask TXFIFO_H2C_OVF_INT */ +} SPDIO_CPU_INT_STAS, *PSPDIO_CPU_INT_STAS; + +// Register REG_SPDIO_CCPWM @ 0xC4 +typedef struct _SPDIO_CCPWM { + u8 TOGGLING:1; /* bit[7], issue interrupt when 0->1 or 1->0 */ + u8 Reserved:3; /* bit[6:4], Reserved */ + u8 WWLAN:1; /* bit[3], 0/1: "Wake on WLAN"/"Normal" state */ + u8 RPS_ST:1; /* bit[2], 0/1: AP Register Sleep/Active state */ + u8 WLAN_TRX:1; /* bit[1], 0: WLAN Off; 1: WLAN On */ + u8 :1; /* bit[0] */ +} SPDIO_CCPWM, *PSPDIO_CCPWM; + +// Register REG_SPDIO_CPU_IND @ 0xC5 +typedef struct _SPDIO_CPU_IND { + u8 Reserved:7; /* bit[7:1], Reserved */ + u8 SYS_TRX_RDY:1; /* bit[0], To indicate the Host system that CPU is ready for TRX + , to be sync to 0x87[0] */ +} SPDIO_CPU_IND, *PSPDIO_CPU_IND; + +// Register REG_SPDIO_CPU_H2C_MSG @ 0xC8 +typedef struct _SPDIO_CPU_H2C_MSG { + u32 Reserved:1; /* bit[31], Reserved */ + u32 CPU_H2C_MSG:30; /* bit[30:0], Host CPU to FW message */ +} SPDIO_CPU_H2C_MSG, *PSPDIO_CPU_H2C_MSG; + +// Register REG_SPDIO_CPU_C2H_MSG @ 0xCC +typedef struct _SPDIO_CPU_C2H_MSG { + u32 Reserved:1; /* bit[31], Reserved */ + u32 CPU_C2H_MSG:30; /* bit[30:0], FW to Host CPU message, sync to REG_SDIO_C2H_MSG */ +} SPDIO_CPU_C2H_MSG, *PSPDIO_CPU_C2H_MSG; + +// Register REG_SPDIO_CRPWM @ 0xD0 +typedef struct _SPDIO_CRPWM { + u8 TOGGLING:1; /* bit[7], issue interrupt when 0->1 or 1->0 */ + u8 Reserved:3; /* bit[6:4], Reserved */ + u8 WWLAN:1; /* bit[3], 0/1: "Wake on WLAN"/"Normal" state */ + u8 RPS_ST:1; /* bit[2], 0/1: AP Register Sleep/Active state */ + u8 WLAN_TRX:1; /* bit[1], 0: WLAN Off; 1: WLAN On */ + u8 :1; /* bit[0] */ +} SPDIO_CRPWM, *PSPDIO_CRPWM; + +// Register REG_SPDIO_AHB_DMA_CTRL @ 0xD4 +typedef struct _SPDIO_AHB_DMA_CTRL { + u32 DISPATCH_TXAGG:1; /* bit[31], Enable to dispatch aggregated TX packet */ + u32 AHB_BURST_TYPE:3; /* bit[30:28], AHB burst type */ + u32 AHB_BUSY_WAIT_CNT:4; /* bit[27:24], timeout for AHB controller to wait busy */ + u32 AHB_DMA_TRANS:2; /* bit[23:22], AHB DMA Trans value, for debugging */ + u32 AHB_MASTER_RDY:1; /* bit[21], AHB Master Hready signal */ + u32 :1; /* bit[20] */ + u32 AHB_DMA_CS:4; /* bit[19:16], AHB DMA state */ + u32 :1; /* bit[15] */ + u32 RXFF_WLEVEL:7; /* bit[14:8], SPDIO RX FIFO water level */ + u32 :1; /* bit[7] */ + u32 TXFF_WLEVEL:7; /* bit[6:0], SPDIO TX FIFO water level */ +} SPDIO_AHB_DMA_CTRL, *PSPDIO_AHB_DMA_CTRL; + +#endif /* end of '#if LITTLE_ENDIAN' */ + + +//#define TX_FIFO_ADDR 0x0000 +//#define TX_FIFO_SIZE 0x8000 + +//TX BD setting +#if SDIO_BOOT_DRIVER +// for build ROM library +#define SDIO_TX_BD_NUM 2 // Number of TX BD +#define SDIO_TX_BD_BUF_SIZE (2048+32) // the size of a TX BD pointed buffer, WLan header = 26 bytes +#define SDIO_TX_PKT_NUM 10 // Number of TX packet handler + +//RX BD setting +#define RX_BD_FREE_TH 4 // trigger the interrupt when free RX BD over this threshold + +#define MAX_RX_BD_BUF_SIZE 16380 // the Maximum size for a RX_BD point to, make it 4-bytes aligned + +#define SDIO_RX_PKT_NUM 3 // Number of RX packet handler +//#define SDIO_RX_BD_NUM 10 // Number of RX BD, to make 32K of bus aggregation, it needs 22 RX_BD at least +#define SDIO_RX_BD_NUM (SDIO_RX_PKT_NUM*2) // Number of RX BD, to make 32K of bus aggregation, it needs 22 RX_BD at least +#define SDIO_RX_BD_BUF_SIZE (2048+24) // the size of a RX BD pointed buffer, sizeof(RX Desc) = 26 bytes +#define MIN_RX_BD_SEND_PKT 2 /* the minum needed RX_BD to send a Packet to Host, we need 2: + one for RX_Desc, the other for payload */ + +// CCPWM2 bit map definition for Firmware download +#define SDIO_INIT_DONE (BIT0) +#define SDIO_MEM_WR_DONE (BIT1) +#define SDIO_MEM_RD_DONE (BIT2) +#define SDIO_MEM_ST_DONE (BIT3) + +#define SDIO_CPWM2_TOGGLE (BIT15) + +#else +#if CONFIG_INIC_EN +//TX BD setting +#define SDIO_TX_BD_NUM 16 // Number of TX BD +#define SDIO_TX_BD_BUF_SIZE 1540 //1514+24 +//#define SDIO_TX_PKT_NUM 1 // not used + +//RX BD setting +#define RX_BD_FREE_TH 5 // trigger the interrupt when free RX BD over this threshold +#define SDIO_RX_BD_BUF_SIZE 1540 //1514+24 +#define MAX_RX_BD_BUF_SIZE 16380 // the Maximum size for a RX_BD point to, make it 4-bytes aligned +#define SDIO_RX_PKT_NUM 16 // Number of RX packet handler +#define MIN_RX_BD_SEND_PKT 2 /* the minum needed RX_BD to send a Packet to Host, we need 2: + one for RX_Desc, the other for payload */ +#define SDIO_RX_BD_NUM (SDIO_RX_PKT_NUM*MIN_RX_BD_SEND_PKT) /*Number of RX BD, + to make 32K of bus aggregation, it needs 22 RX_BD at least*/ +#else +#define SDIO_TX_BD_NUM 24 // Number of TX BD +#define SDIO_TX_BD_BUF_SIZE (2048+32) // the size of a TX BD pointed buffer, WLan header = 26 bytes +#define SDIO_TX_PKT_NUM 128 // Number of TX packet handler + +//RX BD setting +#define RX_BD_FREE_TH 5 // trigger the interrupt when free RX BD over this threshold + +#define SDIO_RX_BD_BUF_SIZE 2048 +#define MAX_RX_BD_BUF_SIZE 16380 // the Maximum size for a RX_BD point to, make it 4-bytes aligned + +//#define SDIO_TX_FIFO_SIZE (1024*64) // 64K +#define SDIO_RX_BD_NUM 24 // Number of RX BD, to make 32K of bus aggregation, it needs 22 RX_BD at least +#define SDIO_RX_PKT_NUM 128 // Number of RX packet handler +#define MIN_RX_BD_SEND_PKT 2 /* the minum needed RX_BD to send a Packet to Host, we need 2: + one for RX_Desc, the other for payload */ +#endif +#endif + +#define SDIO_IRQ_PRIORITY 10 + +/* SDIO Events */ +#define SDIO_EVENT_IRQ BIT(0) // Interrupt triggered +#define SDIO_EVENT_RX_PKT_RDY BIT(1) // A new SDIO packet ready +#define SDIO_EVENT_C2H_DMA_DONE BIT(2) // Interrupt of C2H DMA done triggered +#define SDIO_EVENT_DUMP BIT(3) // SDIO status dump periodically Enable +#define SDIO_EVENT_TXBD_REFILL BIT(4) // To refill TX BD buffer +#define SDIO_EVENT_EXIT BIT(28) // Request to exit the SDIO task +#define SDIO_EVENT_MP_STOPPED BIT(29) // The SDIO task is stopped +#define SDIO_EVENT_TX_STOPPED BIT(30) // The SDIO task is stopped +#define SDIO_EVENT_RX_STOPPED BIT(31) // The SDIO task is stopped + +#define SDIO_TASK_PRIORITY 1 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest) +#define SDIO_MP_TASK_PRIORITY 2 // it can be 0(lowest) ~ configMAX_PRIORITIES-1(highest) +//#if SDIO_TASK_PRIORITY > (configMAX_PRIORITIES - 1) +#if SDIO_TASK_PRIORITY > (4 - 1) +#error "SDIO Task Priority Should be 0~(configMAX_PRIORITIES-1)" +#endif + +//#define TX_RX_PACKET_SIZE 0x144 + +typedef struct _SDIO_TX_BD_ { + u32 Address; /* The TX buffer physical address, it must be 4-bytes aligned */ +}SDIO_TX_BD, *PSDIO_TX_BD; + +#define TX_BD_STRUCTURE_SIZE (sizeof(SDIO_TX_BD)) + + +/* The RX Buffer Descriptor format */ + +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) +typedef struct _SDIO_RX_BD_ { + u32 BuffSize:14; /* bit[13:0], RX Buffer Size, Maximum 16384-1 */ + u32 LS:1; /* bit[14], is the Last Segment ? */ + u32 FS:1; /* bit[15], is the First Segment ? */ + u32 Seq:16; /* bit[31:16], The sequence number, it's no use for now */ + u32 PhyAddr; /* The RX buffer physical address, it must be 4-bytes aligned */ +} SDIO_RX_BD, *PSDIO_RX_BD; +#else +typedef struct _SDIO_RX_BD_ { + u32 Seq:16; /* bit[31:16], The sequence number, be used for ?? */ + u32 FS:1; /* bit[15], is the First Segment ? */ + u32 LS:1; /* bit[14], is the Last Segment ? */ + u32 BuffSize:14; /* bit[13:0], RX Buffer Size, Maximum 16384 */ + u32 PhyAddr; /* The RX buffer physical address, it must be 4-bytes aligned */ +} SDIO_RX_BD, *PSDIO_RX_BD; +#endif +#define RX_BD_STRUCTURE_SIZE (sizeof(SDIO_RX_BD)) + +// TODO: This data structer just for test, we should modify it for the normal driver +typedef struct _SDIO_TX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 rsvd1; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_TX_DESC, *PSDIO_TX_DESC; + +// TX Desc for Memory Write command +typedef struct _SDIO_TX_DESC_MW{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 reply:1; // bit[8], request to send a reply message + u32 rsvd0:23; +#else + u32 rsvd0:23; + u32 reply:1; // bit[8], request to send a reply message + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_TX_DESC_MW, *PSDIO_TX_DESC_MW; + +// TX Desc for Memory Read command +typedef struct _SDIO_TX_DESC_MR{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 read_len:16; // bit[15:0], the length to read + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 read_len:16; // bit[15:0], the length to read +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_TX_DESC_MR, *PSDIO_TX_DESC_MR; + +// TX Desc for Memory Set command +typedef struct _SDIO_TX_DESC_MS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 data:8; // bit[8:15], the value to be written to the memory + u32 reply:1; // bit[16], request to send a reply message + u32 rsvd0:15; +#else + u32 rsvd0:15; + u32 reply:1; // bit[16], request to send a reply message + u32 data:8; // bit[8:15], the value to be written to the memory + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_TX_DESC_MS, *PSDIO_TX_DESC_MS; + +// TX Desc for Jump to Start command +typedef struct _SDIO_TX_DESC_JS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_fun; // the pointer of the startup function + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_TX_DESC_JS, *PSDIO_TX_DESC_JS; + + +#define SIZE_TX_DESC (sizeof(SDIO_TX_DESC)) +// define the TX BD buffer size with unite of 64 byets +/* Be carefull!! the setting of hardware's TX BD buffer size may exceed the real size of + the TX BD buffer size, and then it may cause the hardware DMA write the buffer overflow */ +#define SDIO_TX_BUF_SZ_UNIT 64 +#define SDIO_TX_BD_BUF_USIZE ((((SDIO_TX_BD_BUF_SIZE+sizeof(SDIO_TX_DESC)-1)/SDIO_TX_BUF_SZ_UNIT)+1)&0xff) + +typedef struct _SDIO_TX_BD_BUFFER_ { + SDIO_TX_DESC TX_Desc; + u8 TX_Buffer[SDIO_TX_BD_BUF_SIZE]; +}SDIO_TX_BD_BUFFER, *PSDIO_TX_BD_BUFFER; + + +// TODO: This data structer just for test, we should modify it for the normal driver +typedef struct _SDIO_RX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:6; // bit[29:24] + u32 icv:1; // bit[30], ICV error + u32 crc:1; // bit[31], CRC error +#else + u32 crc:1; // bit[31], CRC error + u32 icv:1; // bit[30], ICV error + u32 rsvd0:6; // bit[29:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 rsvd2; + + // u4Byte 3 + u32 rsvd3; + + // u4Byte 4 + u32 rsvd4; + + // u4Byte 5 + u32 rsvd5; +} SDIO_RX_DESC, *PSDIO_RX_DESC; + +// For memory read command +typedef struct _SDIO_RX_DESC_MR{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_RX_DESC_MR, *PSDIO_RX_DESC_MR; + +// For memory write reply command +typedef struct _SDIO_RX_DESC_MW{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the type of this packet + u32 result:8; // bit[23:16], the result of memory write command + u32 rsvd2:8; // bit[31:24] +#else + u32 rsvd2:8; // bit[31:24] + u32 result:8; // bit[23:16], the result of memory write command + u32 write_len:16; // bit[15:0], the type of this packet +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_RX_DESC_MW, *PSDIO_RX_DESC_MW; + +// For memory set reply command +typedef struct _SDIO_RX_DESC_MS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the type of this packet + u32 result:8; // bit[23:16], the result of memory write command + u32 rsvd2:8; // bit[31:24] +#else + u32 rsvd2:8; // bit[31:24] + u32 result:8; // bit[23:16], the result of memory write command + u32 write_len:16; // bit[15:0], the type of this packet +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} SDIO_RX_DESC_MS, *PSDIO_RX_DESC_MS; + +#define SIZE_RX_DESC (sizeof(SDIO_RX_DESC)) + +typedef struct _SDIO_RX_BD_BUFFER_ { + SDIO_RX_DESC RX_Desc; + u8 RX_Buffer[SDIO_RX_BD_BUF_SIZE]; +}SDIO_RX_BD_BUFFER, *PSDIO_RX_BD_BUFFER; + + +/* The data structer for a packet fordwarding to the WLan driver to transmit it */ +// TODO: This data structer just for test, we may need modify it for the normal driver +typedef struct _SDIO_TX_PACKET_ { + u8 *pHeader; // Point to the 1st byte of the packets + u16 PktSize; // the size (bytes) of this packet + _LIST list; // the link list to chain packets + u8 isDyna; // is Dynamic allocated +} SDIO_TX_PACKET, *PSDIO_TX_PACKET; + +/* the data structer to bind a TX_BD with a TX Packet */ +typedef struct _SDIO_TX_BD_HANDLE_ { + SDIO_TX_BD *pTXBD; // Point to the TX_BD buffer +#if SDIO_API_DEFINED + VOID *priv; +#else +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX + struct sk_buff *skb; +#endif +#endif +#endif + SDIO_TX_PACKET *pPkt; // point to the Tx Packet + u8 isPktEnd; // For a packet over 1 BD , this flag to indicate is this BD contains a packet end + u8 isFree; // is this TX BD free +} SDIO_TX_BD_HANDLE, *PSDIO_TX_BD_HANDLE; + +/* The data structer for a packet which from the WLan driver to send to the Host */ +// TODO: This data structer just for test, we may need modify it for the normal driver + +#if SDIO_BOOT_DRIVER +typedef struct _SDIO_RX_PACKET_ { +// SDIO_RX_DESC RxDesc; // The RX Descriptor for this packet, to be send to Host ahead this packet + u8 *pData; // point to the head of payload of this packet + u16 Offset; // the offset from the pData to the payload buffer + _LIST list; // the link list to chain packets + u8 PktBuf[SDIO_RX_BD_BUF_SIZE]; // the Rx_Desc + payload data buffer, the first 24 bytes is reserved for RX_DESC +} SDIO_RX_PACKET, *PSDIO_RX_PACKET; +#else +typedef struct _SDIO_RX_PACKET_ { + SDIO_RX_DESC RxDesc; // The RX Descriptor for this packet, to be send to Host ahead this packet +#if SDIO_API_DEFINED + VOID *priv; +#else +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_RX + struct sk_buff *skb; +#endif +#endif +#endif + u8 *pData; // point to the head of payload of this packet + u16 Offset; // the offset from the pData to the payload buffer + _LIST list; // the link list to chain packets + u8 isDyna; // is Dynamic allocated +} SDIO_RX_PACKET, *PSDIO_RX_PACKET; +#endif + +/* the data structer to bind a RX_BD with a RX Packet */ +typedef struct _SDIO_RX_BD_HANDLE_ { + SDIO_RX_BD *pRXBD; // Point to the RX_BD buffer + SDIO_RX_PACKET *pPkt; // point to the Rx Packet + u8 isPktEnd; // For a packet over 1 BD , this flag to indicate is this BD contains a packet end + u8 isFree; // is this RX BD free (DMA done and its RX packet has been freed) +} SDIO_RX_BD_HANDLE, *PSDIO_RX_BD_HANDLE; + +#if SDIO_MP_MODE +typedef struct _SDIO_MP_CMD_ { + u8 cmd_name[16]; + u32 cmd_type; +} SDIO_MP_CMD, *PSDIO_MP_CMD; + +typedef enum _SDIO_MP_CMD_TYPE_{ + SDIO_MP_START=1, + SDIO_MP_STOP=2, + SDIO_MP_LOOPBACK=3, + SDIO_MP_STATUS=4, + SDIO_MP_READ_REG8=5, + SDIO_MP_READ_REG16=6, + SDIO_MP_READ_REG32=7, + SDIO_MP_WRITE_REG8=8, + SDIO_MP_WRITE_REG16=9, + SDIO_MP_WRITE_REG32=10, + SDIO_MP_WAKEUP=11, // wakeup the SDIO task manually, for debugging + SDIO_MP_DUMP=12, // start/stop to dump the SDIO status periodically + SDIO_MP_CTX=13, // setup continue TX test + SDIO_MP_CRX=14, // setup continue RX test + SDIO_MP_CRX_DA=15, // setup continue RX with dynamic allocate RX Buf test + SDIO_MP_CRX_STOP=16, // setup continue RX test + SDIO_MP_DBG_MSG=17, // Debug message On/Off + +}SDIO_MP_CMD_TYPE; + +typedef enum _SDIO_CRX_MODE_{ + SDIO_CRX_STATIC_BUF = 1, + SDIO_CRX_DYNA_BUF = 2, +} SDIO_CRX_MODE; + +typedef struct _SDIO_MP_RX_PACKET_ { + _LIST list; // this member MUST be the 1st one, the link list to chain packets + u8 *pData; // point to the head of payload of this packet + u16 Offset; // the offset from the pData to the payload + u16 DataLen; // the data length of this packet +} SDIO_MP_RX_PACKET, *PSDIO_MP_RX_PACKET; + +#endif // end of '#if SDIO_MP_MODE' + +#define SDIO_CMD_TX_ETH 0x83 // request to TX a 802.3 packet +#define SDIO_CMD_TX_WLN 0x81 // request to TX a 802.11 packet +#define SDIO_CMD_H2C 0x11 // H2C(host to device) command packet +#define SDIO_CMD_MEMRD 0x51 // request to read a block of memory data +#define SDIO_CMD_MEMWR 0x53 // request to write a block of memory +#define SDIO_CMD_MEMST 0x55 // request to set a block of memory with a value +#define SDIO_CMD_STARTUP 0x61 // request to jump to the start up function + +#define SDIO_CMD_RX_ETH 0x82 // indicate a RX 802.3 packet +#define SDIO_CMD_RX_WLN 0x80 // indicate a RX 802.11 packet +#define SDIO_CMD_C2H 0x10 // C2H(device to host) command packet +#define SDIO_CMD_MEMRD_RSP 0x50 // response to memory block read command +#define SDIO_CMD_MEMWR_RSP 0x52 // response to memory write command +#define SDIO_CMD_MEMST_RSP 0x54 // response to memory set command +#define SDIO_CMD_STARTED 0x60 // indicate the program has jumped to the given function + +enum SDIO_RPWM2_BITS { + RPWM2_ACT_BIT = BIT0, // Active + RPWM2_SLEEP_BIT = 0, // Sleep + RPWM2_DSTANDBY_BIT = BIT1, // Deep Standby + RPWM2_PG_BIT = 0, // Power Gated + RPWM2_FBOOT_BIT = BIT2, // fast reboot + RPWM2_NBOOT_BIT = 0, // normal reboot + RPWM2_WKPIN_A5_BIT = BIT3, // enable GPIO A5 wakeup + RPWM2_WKPIN_C7_BIT = BIT4, // enable GPIO C7 wakeup + RPWM2_WKPIN_D5_BIT = BIT5, // enable GPIO D5 wakeup + RPWM2_WKPIN_E3_BIT = BIT6, // enable GPIO E3 wakeup + RPWM2_PIN_A5_LV_BIT = BIT7, // GPIO A5 wakeup level + RPWM2_PIN_C7_LV_BIT = BIT8, // GPIO C7 wakeup level + RPWM2_PIN_D5_LV_BIT = BIT9, // GPIO D5 wakeup level + RPWM2_PIN_E3_LV_BIT = BIT10, // GPIO E3 wakeup level + RPWM2_CG_BIT = BIT11, // Clock Gated + RPWM2_ACK_BIT = BIT14, // Acknowledge + RPWM2_TOGGLE_BIT = BIT15, // Toggle bit +}; + +enum SDIO_CPWM2_BITS { + CPWM2_ACT_BIT = BIT0, // Active + CPWM2_DSTANDBY_BIT = BIT1, // Deep Standby + CPWM2_FBOOT_BIT = BIT2, // fast reboot + CPWM2_INIC_FW_RDY_BIT = BIT3, // is the iNIC FW(1) or Boot FW(0) + + CPWM2_TOGGLE_BIT = BIT15, // Toggle bit +}; + +#ifdef CONFIG_SDIO_DEVICE_VERIFY + +#define TX_BD_STRUCTURE_NUM 10 +#define RX_BD_STRUCTURE_NUM 10 +#define TX_BD_BUFFER_SIZE 0x1000//0x2000//0x800 +#define RX_BD_BUFFER_SIZE 0x400//0x800 + +#define SDIO_RAM_ADDR_BASE 0x20080000 +#define SDIO_BUFFER_HEAD(addr) SDIO_RAM_ADDR_BASE + addr +#define HAL_SDIO_BUFFER_READ8(addr) HAL_READ8(SDIO_RAM_ADDR_BASE, addr) +#define HAL_SDIO_BUFFER_READ32(addr) HAL_READ32(SDIO_RAM_ADDR_BASE, addr) +#define HAL_SDIO_BUFFER_WRITE32(addr, value) HAL_WRITE32(SDIO_RAM_ADDR_BASE, addr, value) + +//#define RX_BD_ADDR 0x8000 +//#define RX_BUFFER_ADDR 0x8050 + +typedef enum _SDIO_TEST_FUNC_ { + SDIO_TEST_INIT, // 0 + SDIO_TEST_INT_ON, // 1 + SDIO_TEST_INT_OFF, // 2 + SDIO_HCI_RX_REQ, // 3 + SDIO_RESET_TXFIFIO, // 4 + SDIO_CPU_RST_DMA, // 5 + SDIO_CPU_CLR_INT_REG, // 6 + SDIO_TIMER_TEST, // 7 + SDIO_TEST_DEBUG, // 8 + SDIO_TEST, // 9 + SDIO_HELP = 0xff +}SDIO_TEST_FUNC, *PSDIO_TEST_FUNC; + +typedef struct _SDIO_TEST_ADAPTER_ { + u32 TXWritePtr; + u32 TXReadPtr; + u16 RXWritePtr; + u16 RXReadPtr; + u16 IntMask; + u16 IntStatus; +} SDIO_TEST_ADAPTER, *PSDIO_TEST_ADAPTER; + + +VOID +MovePKTToRX( + IN u32 Source, IN u32 Destination, IN u32 PKTSize +); + +BOOL +PacketProcess( + IN SDIO_TEST_ADAPTER *pDevStatus +); + +VOID +SdioDeviceIrqHandleFunc( + IN VOID *DATA +); + +VOID +SdioDeviceTestApp( + IN u32 Data +); + +VOID +InitRXBD(VOID); + +VOID +InitTXFIFO(VOID); + +VOID +IrqRegister(VOID); + +#endif // end of "#ifdef CONFIG_SDIO_DEVICE_VERIFY" + +#endif /* #ifndef _RTL8195A_SDIO_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio_host.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio_host.h new file mode 100644 index 0000000..7b3039e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdio_host.h @@ -0,0 +1,809 @@ + /* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_SDIO_HOST_H_ +#define _RTL8195A_SDIO_HOST_H_ + +#include "hal_api.h" +#include "osdep_api.h" + + + +#define HAL_SDIO_HOST_READ32(addr) HAL_READ32(SDIO_HOST_REG_BASE, addr) +#define HAL_SDIO_HOST_WRITE32(addr, value) HAL_WRITE32(SDIO_HOST_REG_BASE, addr, value) +#define HAL_SDIO_HOST_READ16(addr) HAL_READ16(SDIO_HOST_REG_BASE, addr) +#define HAL_SDIO_HOST_WRITE16(addr, value) HAL_WRITE16(SDIO_HOST_REG_BASE, addr, value) +#define HAL_SDIO_HOST_READ8(addr) HAL_READ8(SDIO_HOST_REG_BASE, addr) +#define HAL_SDIO_HOST_WRITE8(addr, value) HAL_WRITE8(SDIO_HOST_REG_BASE, addr, value) + +/* =============== Register Offset Definition =============== */ +#define REG_SDIO_HOST_SDMA_SYS_ADDR 0x00 // 4byte +#define REG_SDIO_HOST_BLK_SIZE 0x04 // 2byte +#define REG_SDIO_HOST_BLK_CNT 0x06 // 2byte +#define REG_SDIO_HOST_ARG 0x08 // 4byte +#define REG_SDIO_HOST_XFER_MODE 0x0C // 2byte +#define REG_SDIO_HOST_CMD 0x0E // 2byte +#define REG_SDIO_HOST_RSP0 0x10 // 4byte +#define REG_SDIO_HOST_RSP2 0x14 // 4byte +#define REG_SDIO_HOST_RSP4 0x18 // 4byte +#define REG_SDIO_HOST_RSP6 0x1C // 4byte +#define REG_SDIO_HOST_BUF_DATA_PORT 0x20 // 4byte +#define REG_SDIO_HOST_PRESENT_STATE 0x24 // 4byte +#define REG_SDIO_HOST_HOST_CTRL 0x28 // 1byte +#define REG_SDIO_HOST_PWR_CTRL 0x29 // 1byte +#define REG_SDIO_HOST_BLK_GAP_CTRL 0x2A // 1byte +#define REG_SDIO_HOST_WAKEUP_CTRL 0x2B // 1byte +#define REG_SDIO_HOST_CLK_CTRL 0x2C // 2byte +#define REG_SDIO_HOST_TIMEOUT_CTRL 0x2E // 1byte +#define REG_SDIO_HOST_SW_RESET 0x2F // 1byte +#define REG_SDIO_HOST_NORMAL_INT_STATUS 0x30 // 2byte +#define REG_SDIO_HOST_ERROR_INT_STATUS 0x32 // 2byte +#define REG_SDIO_HOST_NORMAL_INT_STATUS_EN 0x34 // 2byte +#define REG_SDIO_HOST_ERROR_INT_STATUS_EN 0x36 // 2byte +#define REG_SDIO_HOST_NORMAL_INT_SIG_EN 0x38 // 2byte +#define REG_SDIO_HOST_ERROR_INT_SIG_EN 0x3A // 2byte +#define REG_SDIO_HOST_CAPABILITIES 0x40 // 8byte +#define REG_SDIO_HOST_ADMA_SYS_ADDR 0x58 // 8byte +/* =============================================== */ + +/* Block Count Register (0x06) */ +#define BLK_CNT_REG_MAX 0xFFFF // 65535 blocks + +/* Transfer Mode Register (0x0C) */ +#define XFER_MODE_DMA_EN BIT0 +#define XFER_MODE_BLK_CNT_EN BIT1 +#define XFER_MODE_AUTO_CMD12_EN BIT2 +#define XFER_MODE_DATA_XFER_DIR BIT4 +#define XFER_MODE_MULT_SINGLE_BLK BIT5 + +/* Present State Register (0x24) */ +#define PRES_STATE_CMD_INHIBIT_CMD BIT0 +#define PRES_STATE_CMD_INHIBIT_DAT BIT1 +#define PRES_STATE_DAT_LINE_ACTIVE BIT2 +#define PRES_STATE_CARD_INSERTED BIT16 +#define PRES_STATE_DAT0_SIGNAL_LEVEL BIT20 + +/* Power Control Register (0x29) */ +#define PWR_CTRL_SD_BUS_PWR BIT0 + +/* Clock Control Register (0x2C) */ +#define CLK_CTRL_INTERAL_CLK_EN BIT0 +#define CLK_CTRL_INTERAL_CLK_STABLE BIT1 +#define CLK_CTRL_SD_CLK_EN BIT2 + +/* Software Reset Register (0x2F) */ +#define SW_RESET_FOR_ALL BIT0 +#define SW_RESET_FOR_CMD BIT1 +#define SW_RESET_FOR_DAT BIT2 + +/* Normal Interrupt Status (0x30) */ +#define NOR_INT_STAT_CMD_COMP BIT0 +#define NOR_INT_STAT_XFER_COMP BIT1 +#define NOR_INT_STAT_BLK_GAP_EVENT BIT2 +#define NOR_INT_STAT_DMA_INT BIT3 +#define NOR_INT_STAT_BUF_WR_RDY BIT4 +#define NOR_INT_STAT_BUF_RD_RDY BIT5 +#define NOR_INT_STAT_CARD_INSERT BIT6 +#define NOR_INT_STAT_CARD_REMOVAL BIT7 +#define NOR_INT_STAT_CARD_INT BIT8 +#define NOR_INT_STAT_ERR_INT BIT15 + +/* Error Interrupt Status (0x32) */ +#define ERR_INT_STAT_CMD_TIMEOUT BIT0 +#define ERR_INT_STAT_CMD_CRC BIT1 +#define ERR_INT_STAT_CMD_END_BIT BIT2 +#define ERR_INT_STAT_CMD_IDX BIT3 +#define ERR_INT_STAT_DATA_TIMEOUT BIT4 +#define ERR_INT_STAT_DATA_CRC BIT5 +#define ERR_INT_STAT_DATA_END_BIT BIT6 +#define ERR_INT_STAT_CUR_LIMIT BIT7 +#define ERR_INT_STAT_AUTO_CMD12 BIT8 +#define ERR_INT_STAT_ADMA BIT9 + +/* Normal Interrupt Status Enable (0x34) */ +#define NOR_INT_STAT_EN_CMD_COMP BIT0 +#define NOR_INT_STAT_EN_XFER_COMP BIT1 +#define NOR_INT_STAT_EN_BLK_GAP_EVENT BIT2 +#define NOR_INT_STAT_EN_DMA_INT BIT3 +#define NOR_INT_STAT_EN_BUF_WR_RDY BIT4 +#define NOR_INT_STAT_EN_BUF_RD_RDY BIT5 +#define NOR_INT_STAT_EN_CARD_INSERT BIT6 +#define NOR_INT_STAT_EN_CARD_REMOVAL BIT7 +#define NOR_INT_STAT_EN_CARD_INT BIT8 + +/* Error Interrupt Status Enable (0x36) */ +#define ERR_INT_STAT_EN_CMD_TIMEOUT BIT0 +#define ERR_INT_STAT_EN_CMD_CRC BIT1 +#define ERR_INT_STAT_EN_CMD_END_BIT BIT2 +#define ERR_INT_STAT_EN_CMD_IDX BIT3 +#define ERR_INT_STAT_EN_DATA_TIMEOUT BIT4 +#define ERR_INT_STAT_EN_DATA_CRC BIT5 +#define ERR_INT_STAT_EN_DATA_END_BIT BIT6 +#define ERR_INT_STAT_EN_CUR_LIMIT BIT7 +#define ERR_INT_STAT_EN_AUTO_CMD BIT8 +#define ERR_INT_STAT_EN_ADMA BIT9 + +/* Normal Interrupt Signal Enable (0x38) */ +#define NOR_INT_SIG_EN_CMD_COMP BIT0 +#define NOR_INT_SIG_EN_XFER_COMP BIT1 +#define NOR_INT_SIG_EN_BLK_GAP_EVENT BIT2 +#define NOR_INT_SIG_EN_DMA_INT BIT3 +#define NOR_INT_SIG_EN_BUF_WR_RDY BIT4 +#define NOR_INT_SIG_EN_BUF_RD_RDY BIT5 +#define NOR_INT_SIG_EN_CARD_INSERT BIT6 +#define NOR_INT_SIG_EN_CARD_REMOVAL BIT7 +#define NOR_INT_SIG_EN_CARD_INT BIT8 + +/* Error Interrupt Signal Enable (0x3A) */ +#define ERR_INT_SIG_EN_CMD_TIMEOUT BIT0 +#define ERR_INT_SIG_EN_CMD_CRC BIT1 +#define ERR_INT_SIG_EN_CMD_END_BIT BIT2 +#define ERR_INT_SIG_EN_CMD_IDX BIT3 +#define ERR_INT_SIG_EN_DATA_TIMEOUT BIT4 +#define ERR_INT_SIG_EN_DATA_CRC BIT5 +#define ERR_INT_SIG_EN_DATA_END_BIT BIT6 +#define ERR_INT_SIG_EN_CUR_LIMIT BIT7 +#define ERR_INT_SIG_EN_AUTO_CMD BIT8 +#define ERR_INT_SIG_EN_ADMA BIT9 + +/* Capabilities Register (0x40) */ +#define CAPA_TIMEOUT_CLK_UNIT BIT7 +#define CAPA_ADMA2_SUPPORT BIT19 +#define CAPA_HIGH_SPEED_SUPPORT BIT21 +#define CAPA_VOLT_SUPPORT_33V BIT24 +#define CAPA_VOLT_SUPPORT_30V BIT25 +#define CAPA_VOLT_SUPPORT_18V BIT26 + +#define DATA_BLK_LEN 512 +#define SCR_REG_LEN 8 // 64 bits +#define SWITCH_FN_STATUS_LEN 64 // 512 bits +#define SD_STATUS_LEN 64 // 512 bits +#define CSD_REG_LEN 16 // 128 bits + +/* Switch Function (CMD6) Group */ +#define SWITCH_FN_GRP1_DEFAULT BIT0 +#define SWITCH_FN_GRP1_HIGH_SPEED BIT1 +#define SWITCH_FN_GRP2_DEFAULT BIT0 +#define SWITCH_FN_GRP2_FOR_EC BIT1 +#define SWITCH_FN_GRP2_VENDOR_SPECIFIC BIT14 + +/* Operating Condition (ACMD41) */ +#define ACMD41_POLL_INTERVAL 10000 // 10 ms +#define ACMD41_INIT_TIMEOUT 1000000 // 1 sec + +/* Card Status (R1) */ +#define R1_APP_CMD BIT5 +#define R1_WP_VIOLATION BIT26 + +/* Error Interrupt Recovery */ +#define HAL_SDH_RECOVERED 0x10 + + +/* 0x0C */ +typedef enum +{ + WRITE_OP = 0, + READ_OP = 1 +}DATA_OPERATION; + +/* 0x0E */ +typedef enum +{ + CMD_GO_IDLE_STATE = 0, + CMD_ALL_SEND_CID = 2, + CMD_SEND_RELATIVE_ADDR = 3, + CMD_SET_DSR = 4, + CMD_SWITCH_FUNC = 6, + CMD_SELECT_DESELECT_CARD = 7, + CMD_SEND_IF_COND = 8, + CMD_SEND_CSD = 9, + CMD_SEND_CID = 10, + CMD_VOLTAGE_SWITCH = 11, + CMD_STOP_TRANSMISSION = 12, + CMD_SEND_STATUS = 13, + CMD_GO_INACTIVE_STATE = 15, + CMD_SET_BLOCKLEN = 16, + CMD_READ_SINGLE_BLOCK = 17, + CMD_READ_MULTIPLE_BLOCK = 18, + CMD_SET_BLOCK_COUNT = 23, + CMD_WRITE_BLOCK = 24, + CMD_WRITE_MULTIPLE_BLOCK = 25, + CMD_PROGRAM_CSD = 27, + CMD_ERASE_WR_BLK_START = 32, + CMD_ERASE_WR_BLK_END = 33, + CMD_ERASE = 38, + CMD_SD_SEND_OP_COND = 41, + CMD_LOCK_UNLOCK = 42, + CMD_SEND_SCR = 51, + CMD_APP_CMD = 55 +}CMD_IDX; + +typedef enum +{ + NORMAL, // 00b + SUSPEND, // 01b + RESUME, // 10b + ABORT // 11b +}CMD_TYPE; + +typedef enum +{ + NO_DATA, // 00b + WITH_DATA // 01b +}DATA_PRESENT_SEL; + +typedef enum +{ + NO_RSP, // 00b + RSP_LEN_136, // 01b + RSP_LEN_48, // 10b + RSP_LEN_48_CHK_BUSY // 11b +}RSP_TYPE; + +/* 0x28 */ +typedef enum +{ + SDMA, // 00b + RESERVED, // 01b + ADMA2_32BIT, // 10b + ADMA2_64BIT // 11b +}HOST_DMA_SELECT; + +typedef enum +{ + MODE_1_BIT = 0, + MODE_4_BIT = 1 +}HOST_DATA_WIDTH; + +/* 0x29 */ +typedef enum +{ + VOLT_33V = 7,// 111b + VOLT_30V = 6,// 110b + VOLT_18V = 5 // 101b +}HOST_SD_BUS_VOLT; + +/* 0x2C */ +typedef enum +{ + BASE_CLK = 0x00, // 41.6 MHz + BASE_CLK_DIVIDED_BY_2 = 0x01, // 20.8 MHz + BASE_CLK_DIVIDED_BY_4 = 0x02, // 10.4 MHz + BASE_CLK_DIVIDED_BY_8 = 0x04, // 5.2 MHZ + BASE_CLK_DIVIDED_BY_16 = 0x08, // 2.6 MHz + BASE_CLK_DIVIDED_BY_32 = 0x10, // 1.3 MHz + BASE_CLK_DIVIDED_BY_64 = 0x20, // 650 kHz + BASE_CLK_DIVIDED_BY_128 = 0x40, // 325 kHz + BASE_CLK_DIVIDED_BY_256 = 0x80 // 162 kHz +}SD_CLK_DIVISOR; + +typedef enum +{ + SD_CLK_162KHZ, + SD_CLK_325KHZ, + SD_CLK_650KHZ, + SD_CLK_1_3MHZ, + SD_CLK_2_6MHZ, + SD_CLK_5_2MHZ, + SD_CLK_10_4MHZ, + SD_CLK_20_8MHZ, + SD_CLK_41_6MHZ +}SD_CLK_FREQUENCY; + +/* Card Status Register */ +typedef enum +{ + IDLE, // 0 + READY, // 1 + IDENTIFICATION, // 2 + STAND_BY, // 3 + TRANSFER, // 4 + SENDING_DATA, // 5 + RECEIVE_DATA, // 6 + PROGRAMMING, // 7 + DISCONNECT, // 8 + UNKNOWN = 0xFF +}CURRENT_STATE; + +/* OCR Register */ +typedef enum +{ + VDD_27_28 = BIT15, + VDD_28_29 = BIT16, + VDD_29_30 = BIT17, + VDD_30_31 = BIT18, + VDD_31_32 = BIT19, + VDD_32_33 = BIT20, + VDD_33_34 = BIT21, + VDD_34_35 = BIT22, + VDD_35_36 = BIT23, + CARD_CAPA_STATUS = BIT30, + CARD_PWR_UP_STATUS = BIT31 +}OCR_VOLTAGE_PROFILE; + +/* SCR Register */ +typedef enum +{ + SD_VER_10 = 0, + SD_VER_110 = 1, + SD_VER_200 = 2 +}PHYSICAL_LAYER_SPEC_VER; + +/* CSD Register */ +typedef enum +{ + CLEAR_WRITE_PROTECT = 0, + SET_WRITE_PROTECT = 1 +}TEMPORARY_WRITE_PROTECT_STATUS; + +/* Switch Function (CMD6) Status Data Structure Version */ +typedef enum +{ + BUSY_STATUS_UNDEFINED = 0, // bits [511:376] are defined + BUSY_STATUS_DEFINED = 1 // bits [511:272] are defined +}SWITCH_FN_STATUS_DATA_STRUCTURE_VER; + +/* Switch Function (CMD6) Busy Status */ +typedef enum +{ + READY_STATUS = 0, + BUSY_STATUS = 1 +}SWITCH_FN_BUSY_STATUS; + +/* Switch Function (CMD6) Mode */ +typedef enum +{ + CHECK_FN = 0x0, + SWITCH_FN = 0x1 +}SWITCH_FN_MODE; + +/* Switch Function (CMD6) Group 1 */ +typedef enum +{ + FN1_DEFAULT = 0x0, + FN1_HIGH_SPEED = 0x1, + FN1_KEEP_CURRENT = 0xF +}SWITCH_FN_GROUP_1; + +/* Switch Function (CMD6) Group 2 */ +typedef enum +{ + FN2_DEFAULT = 0x0, + FN2_FOR_EC = 0x1, + FN2_VENDOR_SPECIFIC = 0xE, + FN2_KEEP_CURRENT = 0xF +}SWITCH_FN_GROUP_2; + +typedef enum +{ + DESEL_CARD = 0, + SEL_CARD = 1 +}CARD_SELECTION; + +typedef enum +{ + SDSC_ONLY = 0, + SDHC_SUPPORT = 1 +}HOST_CAPACITY_SUPPORT; + +typedef enum +{ + BUS_1_BIT = 0, + BUS_4_BIT = 2 +}DATA_BUS_WIDTH; + + +typedef struct _ADMA2_ATTRIB_ +{ + u16 Valid:1; + u16 End:1; + u16 Int:1; + u16 Rsvd1:1; + u16 Act1:1; + u16 Act2:1; + u16 Rsvd2:10; +}ADMA2_ATTRIB, *PADMA2_ATTRIB; + +typedef struct _ADMA2_DESC_FMT_ +{ + ADMA2_ATTRIB Attrib1; + u16 Len1; + u32 Addr1; + /* Link to next descriptor (if needed) */ + ADMA2_ATTRIB Attrib2; + u16 Len2; + u32 Addr2; +}ADMA2_DESC_FMT, *PADMA2_DESC_FMT; + +/* 0x0E */ +typedef struct _SDIO_HOST_CMD_FMT_ +{ + u16 RespType:2; + u16 Rsvd0:1; + u16 CmdCrcChkEn:1; + u16 CmdIdxChkEn:1; + u16 DataPresent:1; + u16 CmdType:2; + u16 CmdIdx:6; + u16 Rsvd1:2; +}SDIO_HOST_CMD_FMT, *PSDIO_HOST_CMD_FMT; + +typedef struct _SDIO_HOST_CMD_ +{ + SDIO_HOST_CMD_FMT CmdFmt; + u32 Arg; +}SDIO_HOST_CMD, *PSDIO_HOST_CMD; + + +HAL_Status +HalSdioHostInitHostRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostInitCardRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostDeInitRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostEnableRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostDisableRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostIrqInitRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostReadBlocksDmaRtl8195a( + IN VOID *Data, + IN u64 ReadAddr, + IN u32 BlockCnt +); + +HAL_Status +HalSdioHostWriteBlocksDmaRtl8195a( + IN VOID *Data, + IN u64 WriteAddr, + IN u32 BlockCnt +); + +HAL_Status +HalSdioHostStopTransferRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostGetCardStatusRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostGetSdStatusRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostChangeSdClockRtl8195a( + IN VOID *Data, + IN u8 Frequency +); + +HAL_Status +HalSdioHostEraseRtl8195a( + IN VOID *Data, + IN u64 StartAddr, + IN u64 EndAddr +); + +HAL_Status +HalSdioHostGetWriteProtectRtl8195a( + IN VOID *Data +); + +HAL_Status +HalSdioHostSetWriteProtectRtl8195a( + IN VOID *Data, + IN u8 Setting +); + + +#ifdef CONFIG_SDIO_HOST_VERIFY + +#define HAL_MMC_HOST_READ32(addr) HAL_READ32(SDIO_HOST_REG_BASE, addr) +#define HAL_MMC_HOST_WRITE32(addr, value) HAL_WRITE32(SDIO_HOST_REG_BASE, addr, value) +#define HAL_MMC_HOST_READ16(addr) HAL_READ16(SDIO_HOST_REG_BASE, addr) +#define HAL_MMC_HOST_WRITE16(addr, value) HAL_WRITE16(SDIO_HOST_REG_BASE, addr, value) +#define HAL_MMC_HOST_READ8(addr) HAL_READ8(SDIO_HOST_REG_BASE, addr) +#define HAL_MMC_HOST_WRITE8(addr, value) HAL_WRITE8(SDIO_HOST_REG_BASE, addr, value) + +/* RTL8195A Register */ +// REG_SOC_HCI_COM_FUNC_EN (0x214) +#define SD_DEVICE_IP_ON_BLK BIT0 +#define SD_DEVICE_IP_OFF_BLK BIT1 +#define SD_HOST_IP_BLK BIT2 + +// REG_PESOC_HCI_CLK_CTRL0 (0x240) +#define SD_HOST_CLKEN_IN_CPU_RUN_MODE BIT2 + +// REG_HCI_PINMUX_CTRL (0x2A0) +#define SD_DEVICE_MODE_PINMUX_EN BIT0 +#define SD_HOST_MODE_PINMUX_EN BIT1 + +// 0x40059000 +#define SD_HOST_CARD_DETECT_CIRCUIT BIT10 + + + +/* SD Host Register */ +#define REG_SDMA_SYS_ADDR_ARG 0x00 // 4byte +#define REG_BLOCK_SIZE 0x04 // 2byte +#define REG_BLOCK_COUNT 0x06 // 2byte +#define REG_ARGUMENT1 0x08 // 4byte +#define REG_TRANSFER_MODE 0x0C // 2byte +#define REG_COMMAND 0x0E // 2byte +#define REG_RESPONSE0 0x10 // 4byte +#define REG_RESPONSE2 0x14 // 4byte +#define REG_RESPONSE4 0x18 // 4byte +#define REG_RESPONSE6 0x1C // 4byte +#define REG_BUFFER_DATA_PORT 0x20 // 4byte +#define REG_PRESENT_STATE 0x24 // 4byte +#define REG_HOST_CONTROL1 0x28 // 1byte +#define REG_POWER_CONTROL 0x29 // 1byte +#define REG_BLOCK_GAP_CONTROL 0x2A // 1byte +#define REG_WAKEUP_CONTROL 0x2B // 1byte +#define REG_CLOCK_CONTROL 0x2C // 2byte +#define REG_TIMEOUT_CONTROL 0x2E // 1byte +#define REG_SW_RESET 0x2F // 1byte +#define REG_NORMAL_INT_STATUS 0x30 // 2byte +#define REG_ERROR_INT_STATUS 0x32 // 2byte +#define REG_NORMAL_INT_STATUS_ENABLE 0x34 // 2byte +#define REG_ERROR_INT_STATUS_ENABLE 0x36 // 2byte +#define REG_NORMAL_INT_SIGNAL_ENABLE 0x38 // 2byte +#define REG_ERROR_INT_SIGNAL_ENABLE 0x3A // 2byte +#define REG_CAPABILITIES 0x40 // 8byte +#define REG_ADMA_ADDRESS 0x58 // 8byte + +// Transfer Mode (0x0C) +#define BIT_DMA_EN BIT0 +#define BIT_BLK_CNT_EN BIT1 +#define BIT_AUTO_CMD12_EN BIT2 +#define BIT_AUTO_CMD23_EN BIT3 +#define BIT_READ_TRANS BIT4 +#define BIT_MULTI_BLK BIT5 + +// Present State (0x24) +#define BIT_CMD_INHIBIT_CMD BIT0 +#define BIT_CMD_INHIBIT_DAT BIT1 +#define BIT_CARD_INSERTED BIT16 +#define BIT_WRITE_PROTECT_SWITCH_PIN BIT19 + +// Power Control (0x29) +#define BIT_POWER_33 0xE +#define BIT_POWER_30 0xC +#define BIT_POWER_18 0xA + +// Clock Control (0x2C) +#define BIT_INTERNAL_CLK_EN BIT0 +#define BIT_INTERNAL_CLK_STABLE BIT1 +#define BIT_SD_CLK_EN BIT2 + +// Software Reset (0x2F) +#define BIT_SW_RESET_ALL BIT0 +#define BIT_SW_RESET_CMD_LINE BIT1 +#define BIT_SW_RESET_DAT_LINE BIT2 + +// Norma Interrupt Status (0x30) +#define BIT_COMMAND_COMPLETE BIT0 +#define BIT_TRANSFER_COMPLETE BIT1 +#define BIT_BLOCK_GAP_EVENT BIT2 +#define BIT_DMA_INT BIT3 +#define BIT_BUFFER_WRITE_RDY BIT4 +#define BIT_BUFFER_READ_RDY BIT5 +#define BIT_CARD_INSERTION BIT6 +#define BIT_CARD_REMOVAL BIT7 +#define BIT_CARD_INT BIT8 +#define BIT_ERROR_INT BIT15 + +// Error Interrupt Status (0x32) +#define BIT_DATA_TIME_OUT_ERROR BIT4 +#define BIT_DATA_CRC_ERROR BIT5 +#define BIT_ADMA_ERROR BIT9 + +// Capabilities (0x40) +#define BIT_VDD_33 BIT24 +#define BIT_VDD_30 BIT25 +#define BIT_VDD_18 BIT26 + + +#define ENABLE 1 +#define DISABLE 0 + +#define ADMA_DESC_NUM 50 + +#define BUFFER_UNIT_SIZE 512 + +typedef enum _MMC_HOST_TEST_FUNC_ { + MMC_HOST_TEST_HW_INIT, // 0 + MMC_HOST_TEST_CARD_INIT, // 1 + MMC_HOST_TEST_SEND_CMD, // 2 + MMC_HOST_TEST_DEBUG, // 3 + MMC_HOST_TEST_SW_RESET, // 4 + MMC_HOST_TEST_READ_SINGLE, // 5 + MMC_HOST_TEST_WRITE_SINGLE, // 6 + MMC_HOST_TEST_READ_MULTI, // 7 + MMC_HOST_TEST_WRITE_MULTI, // 8 + MMC_HOST_TEST_SINGLE_LONGRUN, // 9 + MMC_HOST_TEST_MULTI_LONGRUN, // 10 + MMC_HOST_TEST_CARD_DETECTION, // 11 + MMC_HOST_TEST_WRITE_PROTECT, // 12 + MMC_HOST_TEST_REGISTER_RW, // 13 + SD_HOST_HAL_API_VERIFY = 20, + SD_HOST_ERASE_TEST = 21, + SD_HOST_WP_TEST = 22, + SD_HOST_MB_TEST = 23, + SD_HOST_ADMA_MAX_TEST = 24 +}MMC_HOST_TEST_FUNC; + +typedef enum _RESPONSE_TYPE_ { + No_Response, // 00b + Response_136, // 01b + Response_48, // 10b + Response_48_Busy // 11b +}RESPONSE_TYPE; + +typedef enum _COMMAND_TYPE_ { + Normal, // 00b + Suspend, // 01b + Resume, // 10b + Abort // 11b +}COMMAND_TYPE; + +typedef enum _DATA_PRESENT_ { + No_Data_Present, // 00b + Data_Present, // 01b +}DATA_PRESENT; + +typedef enum _SUPPLY_VOLTAGE_ { + MMC_VDD_27_28 = BIT15, + MMC_VDD_28_29 = BIT16, + MMC_VDD_29_30 = BIT17, + MMC_VDD_30_31 = BIT18, + MMC_VDD_31_32 = BIT19, + MMC_VDD_32_33 = BIT20, + MMC_VDD_33_34 = BIT21, + MMC_VDD_34_35 = BIT22, + MMC_VDD_35_36 = BIT23, +}SUPPLY_VOLTAGE; + +typedef enum _COMMAND_INDEX_ { + GO_IDLE_STATE = 0, + ALL_SEND_CID = 2, + SEND_RELATIVE_ADDR = 3, + SET_BUS_WIDTH = 6, + SELECT_CARD = 7, + SEND_IF_COND = 8, + SEND_CSD = 9, + STOP_TRANSMISSION = 12, + SEND_STATUS = 13, + READ_SINGLE_BLOCK = 17, + READ_MULTIPLE_BLOCK = 18, + WRITE_BLOCK = 24, + WRITE_MULTIPLE_BLOCK = 25, + SD_SEND_OP_COND = 41, + APP_CMD = 55, +}COMMAND_INDEX; + +typedef enum _TRANSFER_CONFIG_ { + Read_Data = 0, + Write_Data = 1, + Single_Block = 0, + Multiple_Block = 1, +}TRANSFER_CONFIG; + +typedef enum _ERROR_STATUS_ { + General_Error, // 0 + CRC_Error, // 1 + TIME_OUT_ERROR, // 2 + CRC_Error_NeedCMD12, // 3 + Transfer_OK // 4 +}ERROR_STATUS; + +typedef enum _CARD_CURRENT_STATE_ { + IDLE_STATE, + READY_STATE, + IDENT_STATE, + STBY_STATE, + TRAN_STATE, + DATA_STATE, + RCV_STATE, + PRG_STATE, + DIS_STATE, + UNKNOWN_STATE +}CARD_CURRENT_STATE; + +typedef struct _COMMAND_FORMAT_ +{ + u16 Resp_Type:2; + u16 Rsvd0:1; + u16 CMD_CRC_Chk:1; + u16 CMD_Idx_Chk:1; + u16 Data_Present:1; + u16 CMD_Type:2; + u16 CMD_Idx:6; + u16 Rsvd1:2; +}COMMAND_FORMAT, *PCOMMAND_FPRMAT; + +typedef struct _MMC_COMMAND +{ + COMMAND_FORMAT Cmd_Format; + u32 Arg; +}MMC_COMMAND; + +typedef struct _MMC_HOST_ +{ + u32 OCR_Avail; + u32 Resp[4]; + u32 CID[4]; + u32 RCA; +}MMC_HOST, *PMMC_HOST; + +typedef struct _ADMA_ATTR_ +{ + u16 Valid:1; + u16 End:1; + u16 Int:1; + u16 Rsvd1:1; + u16 Act1:1; + u16 Act2:1; + u16 Rsvd2:10; +}ADMA_ATTR, *PADMA_ATTR; +// 24 bytes +typedef struct _ADMA_DESC_TABLE_ +{ + // 1st buffer desc + ADMA_ATTR Attribute1; + u16 Length1; + u32 Address1; + // 2nd buffer desc + ADMA_ATTR Attribute2; + u16 Length2; + u32 Address2; + // 3rd buffer desc + ADMA_ATTR Attribute3; + u16 Length3; + u32 Address3; +}ADMA_DESC_TABLE, *PADMA_DESC_TABLE; +// 1024 bytes +typedef struct _ADMA_BUFFER_ +{ + u8 Data1[512]; /* 1st buffer */ + u8 Data2[512]; /* 2nd buffer */ +}ADMA_BUFFER, *PADMA_BUFFER; + + +VOID +SdHostTestApp( + IN u8 *argv[] +); +#endif // end of "#ifdef CONFIG_SDIO_HOST_VERIFY" + +#endif /* #ifndef _RTL8195A_SDIO_HOST_H_ */ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdr.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdr.h new file mode 100644 index 0000000..05a13fa --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sdr.h @@ -0,0 +1,379 @@ +#ifndef _RTL8195A_SDR_H +#define _RTL8195A_SDR_H + +#define MS_0_CTRL_BASE BSP_MS_I_DRAMC_0_BASE +#define MS_0_CTRL_PHY_BASE (BSP_MS_I_DRAMC_0_BASE) +#define MS_0_WRAP_BASE (MS_0_CTRL_BASE + 0x200) + +#define MS_1_CTRL_BASE BSP_MS_I_DRAMC_1_BASE +#define MS_1_CTRL_PHY_BASE (BSP_MS_I_DRAMC_1_BASE) +#define MS_1_WRAP_BASE (MS_1_CTRL_BASE + 0x200) + +#define MS_PCTL_CCR_OFFSET 0x000 +#define MS_PCTL_DCR_OFFSET 0x004 +#define MS_PCTL_IOCR_OFFSET 0x008 +#define MS_PCTL_CSR_OFFSET 0x00c +#define MS_PCTL_DRR_OFFSET 0x010 +#define MS_PCTL_TPR0_OFFSET 0x014 +#define MS_PCTL_TPR1_OFFSET 0x018 +#define MS_PCTL_TPR2_OFFSET 0x01c +#define MS_PCTL_MR_OFFSET 0x020 +#define MS_PCTL_EMR1_OFFSET 0x024 +#define MS_PCTL_EMR2_OFFSET 0x028 +#define MS_PCTL_EMR3_OFFSET 0x02c +#define MS_PCTL_CSR2_OFFSET 0x030 +#define MS_PCTL_SRST_OFFSET 0x034 +#define MS_PCTL_DTR2_OFFSET 0x038 +#define MS_PCTL_DTR3_OFFSET 0x03c +#define MS_PCTL_GDLLCR_OFFSET 0x040 +#define MS_PCTL_DLLCR0_OFFSET 0x044 +#define MS_PCTL_DLLCR1_OFFSET 0x048 +#define MS_PCTL_DLLCR2_OFFSET 0x04c +#define MS_PCTL_DLLCR3_OFFSET 0x050 +#define MS_PCTL_DLLCR4_OFFSET 0x054 +#define MS_PCTL_DLLCR5_OFFSET 0x058 +#define MS_PCTL_DLLCR6_OFFSET 0x05c +#define MS_PCTL_DLLCR7_OFFSET 0x060 +#define MS_PCTL_DLLCR8_OFFSET 0x064 +#define MS_PCTL_DQTR0_OFFSET 0x068 +#define MS_PCTL_DQTR1_OFFSET 0x06c +#define MS_PCTL_DQTR2_OFFSET 0x070 +#define MS_PCTL_DQTR3_OFFSET 0x074 +#define MS_PCTL_DQTR4_OFFSET 0x078 +#define MS_PCTL_DQTR5_OFFSET 0x07c +#define MS_PCTL_DQTR6_OFFSET 0x080 +#define MS_PCTL_DQTR7_OFFSET 0x084 +#define MS_PCTL_DQSTR_OFFSET 0x088 +#define MS_PCTL_DQSBTR_OFFSET 0x08c +#define MS_PCTL_ODTCR_OFFSET 0x090 +#define MS_PCTL_DTR0_OFFSET 0x094 +#define MS_PCTL_DTR1_OFFSET 0x098 +#define MS_PCTL_DTAR_OFFSET 0x09c +#define MS_PCTL_ZQCR0_OFFSET 0x0a0 +#define MS_PCTL_ZQCR1_OFFSET 0x0a4 +#define MS_PCTL_ZQSR_OFFSET 0x0a8 +#define MS_PCTL_RSLR0_OFFSET 0x0ac +#define MS_PCTL_RSLR1_OFFSET 0x0b0 +#define MS_PCTL_RSLR2_OFFSET 0x0b4 +#define MS_PCTL_RSLR3_OFFSET 0x0b8 +#define MS_PCTL_RDGR0_OFFSET 0x0bc +#define MS_PCTL_RDGR1_OFFSET 0x0c0 +#define MS_PCTL_RDGR2_OFFSET 0x0c4 +#define MS_PCTL_RDGR3_OFFSET 0x0c8 +#define MS_PCTL_MXSL_OFFSET 0x0cc + +#define MS_PCTL_BCR_OFFSET 0x0d0 +#define MS_PCTL_BALR0_OFFSET 0x0d4 +#define MS_PCTL_BALR1_OFFSET 0x0d8 +#define MS_PCTL_BDR0_OFFSET 0x0dc +#define MS_PCTL_BDR1_OFFSET 0x0e0 +#define MS_PCTL_BBR_OFFSET 0x0e4 +#define MS_PCTL_BSR_OFFSET 0x0e8 +#define MS_PCTL_BYR_OFFSET 0x0ec +#define MS_PCTL_BFA_OFFSET 0x0f0 +#define MS_PCTL_IDR_OFFSET 0x0f8 +#define MS_PCTL_ERR_OFFSET 0x0fc + +#define MS_WRAP_SCR_OFFSET 0x224 +#define MS_WRAP_QCR_OFFSET 0x230 +#define MS_WRAP_PCR_OFFSET 0x234 +#define MS_WRAP_QTR0_OFFSET 0x240 +#define MS_WRAP_QTR1_OFFSET 0x244 +#define MS_WRAP_QTR2_OFFSET 0x248 +#define MS_WRAP_QTR3_OFFSET 0x24c +#define MS_WRAP_QTR4_OFFSET 0x250 +#define MS_WRAP_QTR5_OFFSET 0x254 +#define MS_WRAP_QTR6_OFFSET 0x258 +#define MS_WRAP_QTR7_OFFSET 0x25c +#define MS_WRAP_QTR8_OFFSET 0x260 +#define MS_WRAP_QTR9_OFFSET 0x264 +#define MS_WRAP_QTR10_OFFSET 0x268 +#define MS_WRAP_QTR11_OFFSET 0x26c +#define MS_WRAP_QTR12_OFFSET 0x270 +#define MS_WRAP_QTR13_OFFSET 0x274 +#define MS_WRAP_QTR14_OFFSET 0x278 +#define MS_WRAP_QTR15_OFFSET 0x27c + +#define MS_PHY_DLY0 0x100 +#define MS_PHY_DLY1_RST 0x104 +#define MS_PHY_DLY_CLK 0x108 +#define MS_PHY_DLY_ST 0x10c +#define MS_PHY_DLY_NUM 0x100 + +#define PCTL_CCR_INIT_BFO 0 +#define PCTL_CCR_INIT_BFW 1 +#define PCTL_CCR_DTT_BFO 1 +#define PCTL_CCR_DTT_BFW 1 +#define PCTL_CCR_BTT_BFO 2 +#define PCTL_CCR_BTT_BFW 1 +#define PCTL_CCR_DPIT_BFO 3 +#define PCTL_CCR_DPIT_BFW 1 +#define PCTL_CCR_FLUSH_FIFO_BFO 8 +#define PCTL_CCR_FLUSH_FIFO_BFW 1 + +#define PCTL_DCR_DDR3_BFO 0 +#define PCTL_DCR_DDR3_BFW 1 +#define PCTL_DCR_SDR_BFO 1 +#define PCTL_DCR_SDR_BFW 1 +#define PCTL_DCR_DQ32_BFO 4 +#define PCTL_DCR_DQ32_BFW 1 +#define PCTL_DCR_DFI_RATE_BFO 8 +#define PCTL_DCR_DFI_RATE_BFW 3 + +#define PCTL_IOCR_RD_PIPE_BFO 8 +#define PCTL_IOCR_RD_PIPE_BFW 4 +#define PCTL_IOCR_TPHY_WD_BFO 12 +#define PCTL_IOCR_TPHY_WD_BFW 5 +#define PCTL_IOCR_TPHY_WL_BFO 17 +#define PCTL_IOCR_TPHY_WL_BFW 3 +#define PCTL_IOCR_TPHY_RD_EN_BFO 20 +#define PCTL_IOCR_TPHY_RD_EN_BFW 5 + +#define PCTL_CSR_MEM_IDLE_BFO 8 +#define PCTL_CSR_MEM_IDLE_BFW 1 +#define PCTL_CSR_DT_IDLE_BFO 9 +#define PCTL_CSR_DT_IDLE_BFW 1 +#define PCTL_CSR_BIST_IDLE_BFO 10 +#define PCTL_CSR_BIST_IDLE_BFW 1 +#define PCTL_CSR_DT_FAIL_BFO 11 +#define PCTL_CSR_DT_FAIL_BFW 1 +#define PCTL_CSR_BT_FAIL_BFO 12 +#define PCTL_CSR_BT_FAIL_BFW 1 + +#define PCTL_DRR_TRFC_BFO 0 +#define PCTL_DRR_TRFC_BFW 7 +#define PCTL_DRR_TREF_BFO 8 +#define PCTL_DRR_TREF_BFW 24 +#define PCTL_DRR_REF_NUM_BFO 24 +#define PCTL_DRR_REF_NUM_BFW 4 +#define PCTL_DRR_REF_DIS_BFO 28 +#define PCTL_DRR_REF_DIS_BFW 1 + +#define PCTL_TPR0_TRP_BFO 0 +#define PCTL_TPR0_TRP_BFW 4 +#define PCTL_TPR0_TRAS_BFO 4 +#define PCTL_TPR0_TRAS_BFW 5 +#define PCTL_TPR0_TWR_BFO 9 +#define PCTL_TPR0_TWR_BFW 4 +#define PCTL_TPR0_TRTP_BFO 13 +#define PCTL_TPR0_TRTP_BFW 3 + +#define PCTL_TPR1_TRRD_BFO 0 +#define PCTL_TPR1_TRRD_BFW 4 +#define PCTL_TPR1_TRC_BFO 4 +#define PCTL_TPR1_TRC_BFW 6 +#define PCTL_TPR1_TRCD_BFO 10 +#define PCTL_TPR1_TRCD_BFW 4 +#define PCTL_TPR1_TCCD_BFO 14 +#define PCTL_TPR1_TCCD_BFW 3 +#define PCTL_TPR1_TWTR_BFO 17 +#define PCTL_TPR1_TWTR_BFW 3 +#define PCTL_TPR1_TRTW_BFO 20 +#define PCTL_TPR1_TRTW_BFW 4 + +#define PCTL_TPR2_INIT_REF_NUM_BFO 0 +#define PCTL_TPR2_INIT_REF_NUM_BFW 4 +#define PCTL_TPR2_INIT_NS_EN_BFO 4 +#define PCTL_TPR2_INIT_NS_EN_BFW 1 +#define PCTL_TPR2_TMRD_BFO 5 +#define PCTL_TPR2_TMRD_BFW 2 + +#define PCTL_MR_BL_BFO 0 +#define PCTL_MR_BL_BFW 3 +#define PCTL_MR_BT_BFO 3 +#define PCTL_MR_BT_BFW 1 +#define PCTL_MR_CAS_BFO 4 +#define PCTL_MR_CAS_BFW 3 +#define PCTL_MR_OP_BFO 8 +#define PCTL_MR_OP_BFW 12 + +#define PCTL_EMR1_ADDLAT_BFO 3 +#define PCTL_EMR1_ADDLAT_BFW 3 + +#define PCTL_CMD_DPIN_RSTN_BFO 0 +#define PCTL_CMD_DPIN_RSTN_BFW 1 +#define PCTL_CMD_DPIN_CKE_BFO 1 +#define PCTL_CMD_DPIN_CKE_BFW 1 +#define PCTL_CMD_DPIN_ODT_BFO 2 +#define PCTL_CMD_DPIN_ODT_BFW 1 + +#define PCTL_BCR_STOP_BFO 0 +#define PCTL_BCR_STOP_BFW 1 +#define PCTL_BCR_CMP_BFO 1 +#define PCTL_BCR_CMP_BFW 1 +#define PCTL_BCR_LOOP_BFO 2 +#define PCTL_BCR_LOOP_BFW 1 +#define PCTL_BCR_DIS_MASK_BFO 3 +#define PCTL_BCR_DIS_MASK_BFW 1 +#define PCTL_BCR_AT_STOP_BFO 4 +#define PCTL_BCR_AT_STOP_BFW 1 +#define PCTL_BCR_FLUSH_CMD_BFO 8 +#define PCTL_BCR_FLUSH_CMD_BFW 1 +#define PCTL_BCR_FLUSH_WD_BFO 9 +#define PCTL_BCR_FLUSH_WD_BFW 1 +#define PCTL_BCR_FLUSH_RGD_BFO 10 +#define PCTL_BCR_FLUSH_RGD_BFW 1 +#define PCTL_BCR_FLUSH_RD_BFO 11 +#define PCTL_BCR_FLUSH_RD_BFW 1 +#define PCTL_BCR_FLUSH_RD_EXPC_BFO 16 +#define PCTL_BCR_FLUSH_RD_EXPC_BFW 14 + +#define PCTL_BST_ERR_FST_TH_BFO 0 +#define PCTL_BST_ERR_FST_TH_BFW 12 +#define PCTL_BST_ERR_CNT_BFO 16 +#define PCTL_BST_ERR_CNT_BFW 14 + +#define PCTL_BSRAM0_CMD_LEVEL_BFO 0 +#define PCTL_BSRAM0_CMD_LEVEL_BFW 12 +#define PCTL_BSRAM0_WD_LEVEL_BFO 16 +#define PCTL_BSRAM0_WD_LEVEL_BFW 14 + +#define PCTL_BSRAM1_RG_LEVEL_BFO 0 +#define PCTL_BSRAM1_RG_LEVEL_BFW 14 +#define PCTL_BSRAM1_RD_LEVEL_BFO 16 +#define PCTL_BSRAM1_RD_LEVEL_BFW 14 + +#define WRAP_MISC_PAGE_SIZE_BFO 0 +#define WRAP_MISC_PAGE_SIZE_BFW 4 +#define WRAP_MISC_BANK_SIZE_BFO 4 +#define WRAP_MISC_BANK_SIZE_BFW 2 +#define WRAP_MISC_BST_SIZE_BFO 6 +#define WRAP_MISC_BST_SIZE_BFW 2 +#define WRAP_MISC_DDR_PARAL_BFO 8 +#define WRAP_MISC_DDR_PARAL_BFW 1 + +struct ms_rxi310_portmap { + volatile unsigned int ccr; /* 0x000 */ + volatile unsigned int dcr; /* 0x004 */ + volatile unsigned int iocr; /* 0x008 */ + volatile unsigned int csr; /* 0x00c */ + volatile unsigned int drr; /* 0x010 */ + volatile unsigned int tpr0; /* 0x014 */ + volatile unsigned int tpr1; /* 0x018 */ + volatile unsigned int tpr2; /* 0x01c */ + volatile unsigned int mr; /* 0x020 */ + volatile unsigned int emr1; /* 0x024 */ + volatile unsigned int emr2; /* 0x028 */ + volatile unsigned int emr3; /* 0x02c */ + volatile unsigned int cdpin; /* 0x030 */ + volatile unsigned int tdpin; /* 0x034 */ + volatile unsigned int dtr2; /* 0x038 */ + volatile unsigned int dtr3; /* 0x03c */ + volatile unsigned int gdllcr; /* 0x040 */ + volatile unsigned int dllcr0; /* 0x044 */ + volatile unsigned int dllcr1; /* 0x048 */ + volatile unsigned int dllcr2; /* 0x04c */ + volatile unsigned int dllcr3; /* 0x050 */ + volatile unsigned int dllcr4; /* 0x054 */ + volatile unsigned int dllcr5; /* 0x058 */ + volatile unsigned int dllcr6; /* 0x05c */ + volatile unsigned int dllcr7; /* 0x060 */ + volatile unsigned int dllcr8; /* 0x064 */ + volatile unsigned int dqtr0; /* 0x068 */ + volatile unsigned int dqtr1; /* 0x06c */ + volatile unsigned int dqtr2; /* 0x070 */ + volatile unsigned int dqtr3; /* 0x074 */ + volatile unsigned int dqtr4; /* 0x078 */ + volatile unsigned int dqtr5; /* 0x07c */ + volatile unsigned int dqtr6; /* 0x080 */ + volatile unsigned int dqtr7; /* 0x084 */ + volatile unsigned int dqstr; /* 0x088 */ + volatile unsigned int dqsbtr; /* 0x08c */ + volatile unsigned int odtcr; /* 0x090 */ + volatile unsigned int dtr0; /* 0x094 */ + volatile unsigned int dtr1; /* 0x098 */ + volatile unsigned int dtar; /* 0x09c */ + volatile unsigned int zqcr0; /* 0x0a0 */ + volatile unsigned int zqcr1; /* 0x0a4 */ + volatile unsigned int zqsr; /* 0x0a8 */ + volatile unsigned int rslr0; /* 0x0ac */ + volatile unsigned int rslr1; /* 0x0b0 */ + volatile unsigned int rslr2; /* 0x0b4 */ + volatile unsigned int rslr3; /* 0x0b8 */ + volatile unsigned int rdgr0; /* 0x0bc */ + volatile unsigned int rdgr1; /* 0x0c0 */ + volatile unsigned int rdgr2; /* 0x0c4 */ + volatile unsigned int rdgr3; /* 0x0c8 */ + volatile unsigned int mxsl; /* 0x0cc */ + volatile unsigned int bcr; /* 0x0d0 */ + volatile unsigned int bst; /* 0x0d4 */ + volatile unsigned int bsram0; /* 0x0d8 */ + volatile unsigned int bsram1; /* 0x0dc */ + volatile unsigned int bdr1; /* 0x0e0 */ + volatile unsigned int bbr; /* 0x0e4 */ + volatile unsigned int bsr; /* 0x0e8 */ + volatile unsigned int byr; /* 0x0ec */ + volatile unsigned int bfa; /* 0x0f0 */ + volatile unsigned int pctl_svn; /* 0x0f4 */ + volatile unsigned int pctl_idr; /* 0x0f8 */ + volatile unsigned int err; /* 0x0fc */ + + // SDR_PHY CONTROL REGISTER + volatile unsigned int phy_dly0; /* 0x100 */ + volatile unsigned int phy_dly1_rst; /* 0x104 */ + volatile unsigned int phy_dly_clk; /* 0x108 */ + volatile unsigned int phy_dly_st; /* 0x10c */ + volatile unsigned int phy_dly_num; /* 0x110 */ + volatile unsigned int reserved0[68]; + + // WRAP CONTROL REGISTER + volatile unsigned int misc; /* 0x224 */ + volatile unsigned int cq_ver; /* 0x228 */ + volatile unsigned int cq_mon; /* 0x22c */ + volatile unsigned int wq_ver; /* 0x230 */ + volatile unsigned int wq_mon; /* 0x234 */ + volatile unsigned int rq_ver; /* 0x240 */ + volatile unsigned int rq_mon; /* 0x244 */ + volatile unsigned int reserved1[22]; + volatile unsigned int wwrap_idr; /* 0x2a0 */ + volatile unsigned int wrap_svn; /* 0x2a4 */ + +}; //ms_rxi310_portmap + +#define QFIFO_CMD_BANK_BFO (35 - QFIFO_CMD_WRRD_BFO) // [38:35] +#define QFIFO_CMD_BANK_BFW 4 +#define QFIFO_CMD_PAGE_BFO (20 - QFIFO_CMD_WRRD_BFO) // [34:20] +#define QFIFO_CMD_PAGE_BFW 15 +#define QFIFO_CMD_COLU_BFO (7 - QFIFO_CMD_WRRD_BFO) // [19: 7] +#define QFIFO_CMD_COLU_BFW 13 // [19: 7] +#define QFIFO_BST_LEN_BFO (3 - QFIFO_CMD_WRRD_BFO) // [6:3] +#define QFIFO_BST_LEN_BFW 4 // [6:3] +#define QFIFO_CMD_WRRD_BFO 2 // [2], remove bit[1:0] +#define QFIFO_CMD_WRRD_BFW 1 // [2], remove bit[1:0] + +//====================================================// + +#define REG_SDR_CCR 0x00 +#define REG_SDR_DCR 0x04 +#define REG_SDR_IOCR 0x08 +#define REG_SDR_CSR 0x0C +#define REG_SDR_DRR 0x10 +#define REG_SDR_TPR0 0x14 +#define REG_SDR_TPR1 0x18 +#define REG_SDR_TPR2 0x1C +#define REG_SDR_MR 0x20 +#define REG_SDR_EMR1 0x24 +#define REG_SDR_EMR2 0x28 +#define REG_SDR_EMR3 0x2C +#define REG_SDR_CMD_DPIN 0x30 +#define REG_SDR_TIE_DPIN 0x34 +#define REG_SDR_BCR 0xD0 +#define REG_SDR_BST 0xD4 +#define REG_SDR_BSRAM0 0xD8 +#define REG_SDR_BSRAM1 0xDC +#define REG_SDR_PCTL_SVN_ID 0xF4 +#define REG_SDR_PCTL_IDR 0xF8 +#define REG_SDR_DLY0 0x100 + +#define REG_SDR_DLY1 0x104 +#define REG_SDR_DCM_RST 0x104 + +#define REG_SDR_DLY_CLK_PHA 0x108 +#define REG_SDR_DLY_ST 0x10C + +#define REG_SDR_MISC 0x224 +#define REG_SDR_OCP_WRAP_IDR 0x2A0 +#define REG_SDR_OCP_WRAP_VERSION 0x2A4 + + +#endif // end of "#ifndef _RTL8195A_SDR_H" diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_spi_flash.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_spi_flash.h new file mode 100644 index 0000000..99e4631 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_spi_flash.h @@ -0,0 +1,1143 @@ +#ifndef _RTL8195A_SPI_FLASH_H +#define _RTL8195A_SPI_FLASH_H + +#define CPU_OPT_WIDTH 0x1F + +//2 REG_NOT_VALID + +//2 REG_SPIC_CTRLR0 + +#define BIT_SHIFT_CK_MTIMES 23 +#define BIT_MASK_CK_MTIMES 0x1f +#define BIT_CK_MTIMES(x) (((x) & BIT_MASK_CK_MTIMES) << BIT_SHIFT_CK_MTIMES) +#define BIT_CTRL_CK_MTIMES(x) (((x) & BIT_MASK_CK_MTIMES) << BIT_SHIFT_CK_MTIMES) +#define BIT_GET_CK_MTIMES(x) (((x) >> BIT_SHIFT_CK_MTIMES) & BIT_MASK_CK_MTIMES) + +#define BIT_FAST_RD BIT(22) +#define BIT_SHIFT_FAST_RD 22 +#define BIT_MASK_FAST_RD 0x1 +#define BIT_CTRL_FAST_RD(x) (((x) & BIT_MASK_FAST_RD) << BIT_SHIFT_FAST_RD) + + +#define BIT_SHIFT_CMD_CH 20 +#define BIT_MASK_CMD_CH 0x3 +#define BIT_CMD_CH(x) (((x) & BIT_MASK_CMD_CH) << BIT_SHIFT_CMD_CH) +#define BIT_CTRL_CMD_CH(x) (((x) & BIT_MASK_CMD_CH) << BIT_SHIFT_CMD_CH) +#define BIT_GET_CMD_CH(x) (((x) >> BIT_SHIFT_CMD_CH) & BIT_MASK_CMD_CH) + + +#define BIT_SHIFT_DATA_CH 18 +#define BIT_MASK_DATA_CH 0x3 +#define BIT_DATA_CH(x) (((x) & BIT_MASK_DATA_CH) << BIT_SHIFT_DATA_CH) +#define BIT_CTRL_DATA_CH(x) (((x) & BIT_MASK_DATA_CH) << BIT_SHIFT_DATA_CH) +#define BIT_GET_DATA_CH(x) (((x) >> BIT_SHIFT_DATA_CH) & BIT_MASK_DATA_CH) + + +#define BIT_SHIFT_ADDR_CH 16 +#define BIT_MASK_ADDR_CH 0x3 +#define BIT_ADDR_CH(x) (((x) & BIT_MASK_ADDR_CH) << BIT_SHIFT_ADDR_CH) +#define BIT_CTRL_ADDR_CH(x) (((x) & BIT_MASK_ADDR_CH) << BIT_SHIFT_ADDR_CH) +#define BIT_GET_ADDR_CH(x) (((x) >> BIT_SHIFT_ADDR_CH) & BIT_MASK_ADDR_CH) + + +#define BIT_SHIFT_TMOD 8 +#define BIT_MASK_TMOD 0x3 +#define BIT_TMOD(x) (((x) & BIT_MASK_TMOD) << BIT_SHIFT_TMOD) +#define BIT_CTRL_TMOD(x) (((x) & BIT_MASK_TMOD) << BIT_SHIFT_TMOD) +#define BIT_GET_TMOD(x) (((x) >> BIT_SHIFT_TMOD) & BIT_MASK_TMOD) + +#define BIT_SCPOL BIT(7) +#define BIT_SHIFT_SCPOL 7 +#define BIT_MASK_SCPOL 0x1 +#define BIT_CTRL_SCPOL(x) (((x) & BIT_MASK_SCPOL) << BIT_SHIFT_SCPOL) + +#define BIT_SCPH BIT(6) +#define BIT_SHIFT_SCPH 6 +#define BIT_MASK_SCPH 0x1 +#define BIT_CTRL_SCPH(x) (((x) & BIT_MASK_SCPH) << BIT_SHIFT_SCPH) + +//2 REG_SPIC_CTRLR1 + +#define BIT_SHIFT_NDF 0 +#define BIT_MASK_NDF 0xfff +#define BIT_NDF(x) (((x) & BIT_MASK_NDF) << BIT_SHIFT_NDF) +#define BIT_CTRL_NDF(x) (((x) & BIT_MASK_NDF) << BIT_SHIFT_NDF) +#define BIT_GET_NDF(x) (((x) >> BIT_SHIFT_NDF) & BIT_MASK_NDF) + + +//2 REG_SPIC_SSIENR +#define BIT_ATCK_CMD BIT(1) +#define BIT_SHIFT_ATCK_CMD 1 +#define BIT_MASK_ATCK_CMD 0x1 +#define BIT_CTRL_ATCK_CMD(x) (((x) & BIT_MASK_ATCK_CMD) << BIT_SHIFT_ATCK_CMD) + +#define BIT_SPIC_EN BIT(0) +#define BIT_SHIFT_SPIC_EN 0 +#define BIT_MASK_SPIC_EN 0x1 +#define BIT_CTRL_SPIC_EN(x) (((x) & BIT_MASK_SPIC_EN) << BIT_SHIFT_SPIC_EN) + +//2 REG_SPIC_MWCR + +//2 REG_SPIC_SER +#define BIT_SER BIT(0) +#define BIT_SHIFT_SER 0 +#define BIT_MASK_SER 0x1 +#define BIT_CTRL_SER(x) (((x) & BIT_MASK_SER) << BIT_SHIFT_SER) + +//2 REG_SPIC_BAUDR + +#define BIT_SHIFT_SCKDV 0 +#define BIT_MASK_SCKDV 0xffff +#define BIT_SCKDV(x) (((x) & BIT_MASK_SCKDV) << BIT_SHIFT_SCKDV) +#define BIT_CTRL_SCKDV(x) (((x) & BIT_MASK_SCKDV) << BIT_SHIFT_SCKDV) +#define BIT_GET_SCKDV(x) (((x) >> BIT_SHIFT_SCKDV) & BIT_MASK_SCKDV) + + +//2 REG_SPIC_TXFTLR + +#define BIT_SHIFT_TFT 0 +#define BIT_MASK_TFT 0x1f +#define BIT_TFT(x) (((x) & BIT_MASK_TFT) << BIT_SHIFT_TFT) +#define BIT_CTRL_TFT(x) (((x) & BIT_MASK_TFT) << BIT_SHIFT_TFT) +#define BIT_GET_TFT(x) (((x) >> BIT_SHIFT_TFT) & BIT_MASK_TFT) + + +//2 REG_SPIC_RXFTLR + +#define BIT_SHIFT_RFT 0 +#define BIT_MASK_RFT 0x1f +#define BIT_RFT(x) (((x) & BIT_MASK_RFT) << BIT_SHIFT_RFT) +#define BIT_CTRL_RFT(x) (((x) & BIT_MASK_RFT) << BIT_SHIFT_RFT) +#define BIT_GET_RFT(x) (((x) >> BIT_SHIFT_RFT) & BIT_MASK_RFT) + + +//2 REG_SPIC_TXFLR + +#define BIT_SHIFT_TXFL 0 +#define BIT_MASK_TXFL 0x3f +#define BIT_TXFL(x) (((x) & BIT_MASK_TXFL) << BIT_SHIFT_TXFL) +#define BIT_CTRL_TXFL(x) (((x) & BIT_MASK_TXFL) << BIT_SHIFT_TXFL) +#define BIT_GET_TXFL(x) (((x) >> BIT_SHIFT_TXFL) & BIT_MASK_TXFL) + + +//2 REG_SPIC_RXFLR + +#define BIT_SHIFT_RXFL 0 +#define BIT_MASK_RXFL 0x3f +#define BIT_RXFL(x) (((x) & BIT_MASK_RXFL) << BIT_SHIFT_RXFL) +#define BIT_CTRL_RXFL(x) (((x) & BIT_MASK_RXFL) << BIT_SHIFT_RXFL) +#define BIT_GET_RXFL(x) (((x) >> BIT_SHIFT_RXFL) & BIT_MASK_RXFL) + + +//2 REG_SPIC_SR +#define BIT_TXE BIT(5) +#define BIT_SHIFT_TXE 5 +#define BIT_MASK_TXE 0x1 +#define BIT_CTRL_TXE(x) (((x) & BIT_MASK_TXE) << BIT_SHIFT_TXE) + +#define BIT_RFF BIT(4) +#define BIT_SHIFT_RFF 4 +#define BIT_MASK_RFF 0x1 +#define BIT_CTRL_RFF(x) (((x) & BIT_MASK_RFF) << BIT_SHIFT_RFF) + +#define BIT_RFNE BIT(3) +#define BIT_SHIFT_RFNE 3 +#define BIT_MASK_RFNE 0x1 +#define BIT_CTRL_RFNE(x) (((x) & BIT_MASK_RFNE) << BIT_SHIFT_RFNE) + +#define BIT_TFE BIT(2) +#define BIT_SHIFT_TFE 2 +#define BIT_MASK_TFE 0x1 +#define BIT_CTRL_TFE(x) (((x) & BIT_MASK_TFE) << BIT_SHIFT_TFE) + +#define BIT_TFNF BIT(1) +#define BIT_SHIFT_TFNF 1 +#define BIT_MASK_TFNF 0x1 +#define BIT_CTRL_TFNF(x) (((x) & BIT_MASK_TFNF) << BIT_SHIFT_TFNF) + +#define BIT_BUSY BIT(0) +#define BIT_SHIFT_BUSY 0 +#define BIT_MASK_BUSY 0x1 +#define BIT_CTRL_BUSY(x) (((x) & BIT_MASK_BUSY) << BIT_SHIFT_BUSY) + +//2 REG_SPIC_IMR +#define BIT_TXSIM BIT(9) +#define BIT_SHIFT_TXSIM 9 +#define BIT_MASK_TXSIM 0x1 +#define BIT_CTRL_TXSIM(x) (((x) & BIT_MASK_TXSIM) << BIT_SHIFT_TXSIM) + +#define BIT_ACEIM BIT(8) +#define BIT_SHIFT_ACEIM 8 +#define BIT_MASK_ACEIM 0x1 +#define BIT_CTRL_ACEIM(x) (((x) & BIT_MASK_ACEIM) << BIT_SHIFT_ACEIM) + +#define BIT_BYEIM BIT(7) +#define BIT_SHIFT_BYEIM 7 +#define BIT_MASK_BYEIM 0x1 +#define BIT_CTRL_BYEIM(x) (((x) & BIT_MASK_BYEIM) << BIT_SHIFT_BYEIM) + +#define BIT_WBEIM BIT(6) +#define BIT_SHIFT_WBEIM 6 +#define BIT_MASK_WBEIM 0x1 +#define BIT_CTRL_WBEIM(x) (((x) & BIT_MASK_WBEIM) << BIT_SHIFT_WBEIM) + +#define BIT_FSEIM BIT(5) +#define BIT_SHIFT_FSEIM 5 +#define BIT_MASK_FSEIM 0x1 +#define BIT_CTRL_FSEIM(x) (((x) & BIT_MASK_FSEIM) << BIT_SHIFT_FSEIM) + +#define BIT_RXFIM BIT(4) +#define BIT_SHIFT_RXFIM 4 +#define BIT_MASK_RXFIM 0x1 +#define BIT_CTRL_RXFIM(x) (((x) & BIT_MASK_RXFIM) << BIT_SHIFT_RXFIM) + +#define BIT_RXOIM BIT(3) +#define BIT_SHIFT_RXOIM 3 +#define BIT_MASK_RXOIM 0x1 +#define BIT_CTRL_RXOIM(x) (((x) & BIT_MASK_RXOIM) << BIT_SHIFT_RXOIM) + +#define BIT_RXUIM BIT(2) +#define BIT_SHIFT_RXUIM 2 +#define BIT_MASK_RXUIM 0x1 +#define BIT_CTRL_RXUIM(x) (((x) & BIT_MASK_RXUIM) << BIT_SHIFT_RXUIM) + +#define BIT_TXOIM BIT(1) +#define BIT_SHIFT_TXOIM 1 +#define BIT_MASK_TXOIM 0x1 +#define BIT_CTRL_TXOIM(x) (((x) & BIT_MASK_TXOIM) << BIT_SHIFT_TXOIM) + +#define BIT_TXEIM BIT(0) +#define BIT_SHIFT_TXEIM 0 +#define BIT_MASK_TXEIM 0x1 +#define BIT_CTRL_TXEIM(x) (((x) & BIT_MASK_TXEIM) << BIT_SHIFT_TXEIM) + +//2 REG_SPIC_ISR +#define BIT_TXSIS BIT(9) +#define BIT_SHIFT_TXSIS 9 +#define BIT_MASK_TXSIS 0x1 +#define BIT_CTRL_TXSIS(x) (((x) & BIT_MASK_TXSIS) << BIT_SHIFT_TXSIS) + +#define BIT_ACEIS BIT(8) +#define BIT_SHIFT_ACEIS 8 +#define BIT_MASK_ACEIS 0x1 +#define BIT_CTRL_ACEIS(x) (((x) & BIT_MASK_ACEIS) << BIT_SHIFT_ACEIS) + +#define BIT_BYEIS BIT(7) +#define BIT_SHIFT_BYEIS 7 +#define BIT_MASK_BYEIS 0x1 +#define BIT_CTRL_BYEIS(x) (((x) & BIT_MASK_BYEIS) << BIT_SHIFT_BYEIS) + +#define BIT_WBEIS BIT(6) +#define BIT_SHIFT_WBEIS 6 +#define BIT_MASK_WBEIS 0x1 +#define BIT_CTRL_WBEIS(x) (((x) & BIT_MASK_WBEIS) << BIT_SHIFT_WBEIS) + +#define BIT_FSEIS BIT(5) +#define BIT_SHIFT_FSEIS 5 +#define BIT_MASK_FSEIS 0x1 +#define BIT_CTRL_FSEIS(x) (((x) & BIT_MASK_FSEIS) << BIT_SHIFT_FSEIS) + +#define BIT_RXFIS BIT(4) +#define BIT_SHIFT_RXFIS 4 +#define BIT_MASK_RXFIS 0x1 +#define BIT_CTRL_RXFIS(x) (((x) & BIT_MASK_RXFIS) << BIT_SHIFT_RXFIS) + +#define BIT_RXOIS BIT(3) +#define BIT_SHIFT_RXOIS 3 +#define BIT_MASK_RXOIS 0x1 +#define BIT_CTRL_RXOIS(x) (((x) & BIT_MASK_RXOIS) << BIT_SHIFT_RXOIS) + +#define BIT_RXUIS BIT(2) +#define BIT_SHIFT_RXUIS 2 +#define BIT_MASK_RXUIS 0x1 +#define BIT_CTRL_RXUIS(x) (((x) & BIT_MASK_RXUIS) << BIT_SHIFT_RXUIS) + +#define BIT_TXOIS BIT(1) +#define BIT_SHIFT_TXOIS 1 +#define BIT_MASK_TXOIS 0x1 +#define BIT_CTRL_TXOIS(x) (((x) & BIT_MASK_TXOIS) << BIT_SHIFT_TXOIS) + +#define BIT_TXEIS BIT(0) +#define BIT_SHIFT_TXEIS 0 +#define BIT_MASK_TXEIS 0x1 +#define BIT_CTRL_TXEIS(x) (((x) & BIT_MASK_TXEIS) << BIT_SHIFT_TXEIS) + +//2 REG_SPIC_RISR +#define BIT_ACEIR BIT(8) +#define BIT_SHIFT_ACEIR 8 +#define BIT_MASK_ACEIR 0x1 +#define BIT_CTRL_ACEIR(x) (((x) & BIT_MASK_ACEIR) << BIT_SHIFT_ACEIR) + +#define BIT_BYEIR BIT(7) +#define BIT_SHIFT_BYEIR 7 +#define BIT_MASK_BYEIR 0x1 +#define BIT_CTRL_BYEIR(x) (((x) & BIT_MASK_BYEIR) << BIT_SHIFT_BYEIR) + +#define BIT_WBEIR BIT(6) +#define BIT_SHIFT_WBEIR 6 +#define BIT_MASK_WBEIR 0x1 +#define BIT_CTRL_WBEIR(x) (((x) & BIT_MASK_WBEIR) << BIT_SHIFT_WBEIR) + +#define BIT_FSEIR BIT(5) +#define BIT_SHIFT_FSEIR 5 +#define BIT_MASK_FSEIR 0x1 +#define BIT_CTRL_FSEIR(x) (((x) & BIT_MASK_FSEIR) << BIT_SHIFT_FSEIR) + +#define BIT_RXFIR BIT(4) +#define BIT_SHIFT_RXFIR 4 +#define BIT_MASK_RXFIR 0x1 +#define BIT_CTRL_RXFIR(x) (((x) & BIT_MASK_RXFIR) << BIT_SHIFT_RXFIR) + +#define BIT_RXOIR BIT(3) +#define BIT_SHIFT_RXOIR 3 +#define BIT_MASK_RXOIR 0x1 +#define BIT_CTRL_RXOIR(x) (((x) & BIT_MASK_RXOIR) << BIT_SHIFT_RXOIR) + +#define BIT_RXUIR BIT(2) +#define BIT_SHIFT_RXUIR 2 +#define BIT_MASK_RXUIR 0x1 +#define BIT_CTRL_RXUIR(x) (((x) & BIT_MASK_RXUIR) << BIT_SHIFT_RXUIR) + +#define BIT_TXOIR BIT(1) +#define BIT_SHIFT_TXOIR 1 +#define BIT_MASK_TXOIR 0x1 +#define BIT_CTRL_TXOIR(x) (((x) & BIT_MASK_TXOIR) << BIT_SHIFT_TXOIR) + +#define BIT_TXEIR BIT(0) +#define BIT_SHIFT_TXEIR 0 +#define BIT_MASK_TXEIR 0x1 +#define BIT_CTRL_TXEIR(x) (((x) & BIT_MASK_TXEIR) << BIT_SHIFT_TXEIR) + +//2 REG_SPIC_TXOICR +#define BIT_TXOICR BIT(0) +#define BIT_SHIFT_TXOICR 0 +#define BIT_MASK_TXOICR 0x1 +#define BIT_CTRL_TXOICR(x) (((x) & BIT_MASK_TXOICR) << BIT_SHIFT_TXOICR) + +//2 REG_SPIC_RXOICR +#define BIT_RXOCIR BIT(0) +#define BIT_SHIFT_RXOCIR 0 +#define BIT_MASK_RXOCIR 0x1 +#define BIT_CTRL_RXOCIR(x) (((x) & BIT_MASK_RXOCIR) << BIT_SHIFT_RXOCIR) + +//2 REG_SPC_RXUICR +#define BIT_RXUICR BIT(0) +#define BIT_SHIFT_RXUICR 0 +#define BIT_MASK_RXUICR 0x1 +#define BIT_CTRL_RXUICR(x) (((x) & BIT_MASK_RXUICR) << BIT_SHIFT_RXUICR) + +//2 REG_SPIC_MSTICR +#define BIT_MSTICR BIT(0) +#define BIT_SHIFT_MSTICR 0 +#define BIT_MASK_MSTICR 0x1 +#define BIT_CTRL_MSTICR(x) (((x) & BIT_MASK_MSTICR) << BIT_SHIFT_MSTICR) + +//2 REG_SPIC_ICR + +#define BIT_SHIFT_ICR 0 +#define BIT_MASK_ICR 0xff +#define BIT_ICR(x) (((x) & BIT_MASK_ICR) << BIT_SHIFT_ICR) +#define BIT_CTRL_ICR(x) (((x) & BIT_MASK_ICR) << BIT_SHIFT_ICR) +#define BIT_GET_ICR(x) (((x) >> BIT_SHIFT_ICR) & BIT_MASK_ICR) + + +//2 REG_SPIC_DMACR + +//2 REG_SPIC_DMATDLR0 + +//2 REG_SPIC_DMATDLR1 + +//2 REG_SPIC_IDR + +#define BIT_SHIFT_IDCODE 0 +#define BIT_MASK_IDCODE 0xffffffffL +#define BIT_IDCODE(x) (((x) & BIT_MASK_IDCODE) << BIT_SHIFT_IDCODE) +#define BIT_CTRL_IDCODE(x) (((x) & BIT_MASK_IDCODE) << BIT_SHIFT_IDCODE) +#define BIT_GET_IDCODE(x) (((x) >> BIT_SHIFT_IDCODE) & BIT_MASK_IDCODE) + + +//2 REG_SPIC_VERSION + +#define BIT_SHIFT_SPIC_VERSION 0 +#define BIT_MASK_SPIC_VERSION 0xffffffffL +#define BIT_SPIC_VERSION(x) (((x) & BIT_MASK_SPIC_VERSION) << BIT_SHIFT_SPIC_VERSION) +#define BIT_CTRL_SPIC_VERSION(x) (((x) & BIT_MASK_SPIC_VERSION) << BIT_SHIFT_SPIC_VERSION) +#define BIT_GET_SPIC_VERSION(x) (((x) >> BIT_SHIFT_SPIC_VERSION) & BIT_MASK_SPIC_VERSION) + + +//2 REG_SPIC_DR0 + +#define BIT_SHIFT_DR0 0 +#define BIT_MASK_DR0 0xffffffffL +#define BIT_DR0(x) (((x) & BIT_MASK_DR0) << BIT_SHIFT_DR0) +#define BIT_CTRL_DR0(x) (((x) & BIT_MASK_DR0) << BIT_SHIFT_DR0) +#define BIT_GET_DR0(x) (((x) >> BIT_SHIFT_DR0) & BIT_MASK_DR0) + + +//2 REG_SPIC_DR1 + +#define BIT_SHIFT_DR1 0 +#define BIT_MASK_DR1 0xffffffffL +#define BIT_DR1(x) (((x) & BIT_MASK_DR1) << BIT_SHIFT_DR1) +#define BIT_CTRL_DR1(x) (((x) & BIT_MASK_DR1) << BIT_SHIFT_DR1) +#define BIT_GET_DR1(x) (((x) >> BIT_SHIFT_DR1) & BIT_MASK_DR1) + + +//2 REG_SPIC_DR2 + +#define BIT_SHIFT_DR2 0 +#define BIT_MASK_DR2 0xffffffffL +#define BIT_DR2(x) (((x) & BIT_MASK_DR2) << BIT_SHIFT_DR2) +#define BIT_CTRL_DR2(x) (((x) & BIT_MASK_DR2) << BIT_SHIFT_DR2) +#define BIT_GET_DR2(x) (((x) >> BIT_SHIFT_DR2) & BIT_MASK_DR2) + + +//2 REG_SPIC_DR3 + +#define BIT_SHIFT_DR3 0 +#define BIT_MASK_DR3 0xffffffffL +#define BIT_DR3(x) (((x) & BIT_MASK_DR3) << BIT_SHIFT_DR3) +#define BIT_CTRL_DR3(x) (((x) & BIT_MASK_DR3) << BIT_SHIFT_DR3) +#define BIT_GET_DR3(x) (((x) >> BIT_SHIFT_DR3) & BIT_MASK_DR3) + + +//2 REG_SPIC_DR4 + +#define BIT_SHIFT_DR4 0 +#define BIT_MASK_DR4 0xffffffffL +#define BIT_DR4(x) (((x) & BIT_MASK_DR4) << BIT_SHIFT_DR4) +#define BIT_CTRL_DR4(x) (((x) & BIT_MASK_DR4) << BIT_SHIFT_DR4) +#define BIT_GET_DR4(x) (((x) >> BIT_SHIFT_DR4) & BIT_MASK_DR4) + + +//2 REG_SPIC_DR5 + +#define BIT_SHIFT_DR5 0 +#define BIT_MASK_DR5 0xffffffffL +#define BIT_DR5(x) (((x) & BIT_MASK_DR5) << BIT_SHIFT_DR5) +#define BIT_CTRL_DR5(x) (((x) & BIT_MASK_DR5) << BIT_SHIFT_DR5) +#define BIT_GET_DR5(x) (((x) >> BIT_SHIFT_DR5) & BIT_MASK_DR5) + + +//2 REG_SPIC_DR6 + +#define BIT_SHIFT_DR6 0 +#define BIT_MASK_DR6 0xffffffffL +#define BIT_DR6(x) (((x) & BIT_MASK_DR6) << BIT_SHIFT_DR6) +#define BIT_CTRL_DR6(x) (((x) & BIT_MASK_DR6) << BIT_SHIFT_DR6) +#define BIT_GET_DR6(x) (((x) >> BIT_SHIFT_DR6) & BIT_MASK_DR6) + + +//2 REG_SPIC_DR7 + +#define BIT_SHIFT_DR7 0 +#define BIT_MASK_DR7 0xffffffffL +#define BIT_DR7(x) (((x) & BIT_MASK_DR7) << BIT_SHIFT_DR7) +#define BIT_CTRL_DR7(x) (((x) & BIT_MASK_DR7) << BIT_SHIFT_DR7) +#define BIT_GET_DR7(x) (((x) >> BIT_SHIFT_DR7) & BIT_MASK_DR7) + + +//2 REG_SPIC_DR8 + +#define BIT_SHIFT_DR8 0 +#define BIT_MASK_DR8 0xffffffffL +#define BIT_DR8(x) (((x) & BIT_MASK_DR8) << BIT_SHIFT_DR8) +#define BIT_CTRL_DR8(x) (((x) & BIT_MASK_DR8) << BIT_SHIFT_DR8) +#define BIT_GET_DR8(x) (((x) >> BIT_SHIFT_DR8) & BIT_MASK_DR8) + + +//2 REG_SPIC_DR9 + +#define BIT_SHIFT_DR9 0 +#define BIT_MASK_DR9 0xffffffffL +#define BIT_DR9(x) (((x) & BIT_MASK_DR9) << BIT_SHIFT_DR9) +#define BIT_CTRL_DR9(x) (((x) & BIT_MASK_DR9) << BIT_SHIFT_DR9) +#define BIT_GET_DR9(x) (((x) >> BIT_SHIFT_DR9) & BIT_MASK_DR9) + + +//2 REG_SPIC_DR10 + +#define BIT_SHIFT_DR10 0 +#define BIT_MASK_DR10 0xffffffffL +#define BIT_DR10(x) (((x) & BIT_MASK_DR10) << BIT_SHIFT_DR10) +#define BIT_CTRL_DR10(x) (((x) & BIT_MASK_DR10) << BIT_SHIFT_DR10) +#define BIT_GET_DR10(x) (((x) >> BIT_SHIFT_DR10) & BIT_MASK_DR10) + + +//2 REG_SPIC_DR11 + +#define BIT_SHIFT_DR11 0 +#define BIT_MASK_DR11 0xffffffffL +#define BIT_DR11(x) (((x) & BIT_MASK_DR11) << BIT_SHIFT_DR11) +#define BIT_CTRL_DR11(x) (((x) & BIT_MASK_DR11) << BIT_SHIFT_DR11) +#define BIT_GET_DR11(x) (((x) >> BIT_SHIFT_DR11) & BIT_MASK_DR11) + + +//2 REG_SPIC_DR12 + +#define BIT_SHIFT_DR12 0 +#define BIT_MASK_DR12 0xffffffffL +#define BIT_DR12(x) (((x) & BIT_MASK_DR12) << BIT_SHIFT_DR12) +#define BIT_CTRL_DR12(x) (((x) & BIT_MASK_DR12) << BIT_SHIFT_DR12) +#define BIT_GET_DR12(x) (((x) >> BIT_SHIFT_DR12) & BIT_MASK_DR12) + + +//2 REG_SPIC_DR13 + +#define BIT_SHIFT_DR13 0 +#define BIT_MASK_DR13 0xffffffffL +#define BIT_DR13(x) (((x) & BIT_MASK_DR13) << BIT_SHIFT_DR13) +#define BIT_CTRL_DR13(x) (((x) & BIT_MASK_DR13) << BIT_SHIFT_DR13) +#define BIT_GET_DR13(x) (((x) >> BIT_SHIFT_DR13) & BIT_MASK_DR13) + + +//2 REG_SPIC_DR14 + +#define BIT_SHIFT_DR14 0 +#define BIT_MASK_DR14 0xffffffffL +#define BIT_DR14(x) (((x) & BIT_MASK_DR14) << BIT_SHIFT_DR14) +#define BIT_CTRL_DR14(x) (((x) & BIT_MASK_DR14) << BIT_SHIFT_DR14) +#define BIT_GET_DR14(x) (((x) >> BIT_SHIFT_DR14) & BIT_MASK_DR14) + + +//2 REG_SPIC_DR15 + +#define BIT_SHIFT_DR15 0 +#define BIT_MASK_DR15 0xffffffffL +#define BIT_DR15(x) (((x) & BIT_MASK_DR15) << BIT_SHIFT_DR15) +#define BIT_CTRL_DR15(x) (((x) & BIT_MASK_DR15) << BIT_SHIFT_DR15) +#define BIT_GET_DR15(x) (((x) >> BIT_SHIFT_DR15) & BIT_MASK_DR15) + + +//2 REG_SPIC_DR16 + +#define BIT_SHIFT_DR16 0 +#define BIT_MASK_DR16 0xffffffffL +#define BIT_DR16(x) (((x) & BIT_MASK_DR16) << BIT_SHIFT_DR16) +#define BIT_CTRL_DR16(x) (((x) & BIT_MASK_DR16) << BIT_SHIFT_DR16) +#define BIT_GET_DR16(x) (((x) >> BIT_SHIFT_DR16) & BIT_MASK_DR16) + + +//2 REG_SPIC_DR17 + +#define BIT_SHIFT_DR17 0 +#define BIT_MASK_DR17 0xffffffffL +#define BIT_DR17(x) (((x) & BIT_MASK_DR17) << BIT_SHIFT_DR17) +#define BIT_CTRL_DR17(x) (((x) & BIT_MASK_DR17) << BIT_SHIFT_DR17) +#define BIT_GET_DR17(x) (((x) >> BIT_SHIFT_DR17) & BIT_MASK_DR17) + + +//2 REG_SPIC_DR18 + +#define BIT_SHIFT_DR18 0 +#define BIT_MASK_DR18 0xffffffffL +#define BIT_DR18(x) (((x) & BIT_MASK_DR18) << BIT_SHIFT_DR18) +#define BIT_CTRL_DR18(x) (((x) & BIT_MASK_DR18) << BIT_SHIFT_DR18) +#define BIT_GET_DR18(x) (((x) >> BIT_SHIFT_DR18) & BIT_MASK_DR18) + + +//2 REG_SPIC_DR19 + +#define BIT_SHIFT_DR19 0 +#define BIT_MASK_DR19 0xffffffffL +#define BIT_DR19(x) (((x) & BIT_MASK_DR19) << BIT_SHIFT_DR19) +#define BIT_CTRL_DR19(x) (((x) & BIT_MASK_DR19) << BIT_SHIFT_DR19) +#define BIT_GET_DR19(x) (((x) >> BIT_SHIFT_DR19) & BIT_MASK_DR19) + + +//2 REG_SPIC_DR20 + +#define BIT_SHIFT_DR20 0 +#define BIT_MASK_DR20 0xffffffffL +#define BIT_DR20(x) (((x) & BIT_MASK_DR20) << BIT_SHIFT_DR20) +#define BIT_CTRL_DR20(x) (((x) & BIT_MASK_DR20) << BIT_SHIFT_DR20) +#define BIT_GET_DR20(x) (((x) >> BIT_SHIFT_DR20) & BIT_MASK_DR20) + + +//2 REG_SPIC_DR21 + +#define BIT_SHIFT_DR21 0 +#define BIT_MASK_DR21 0xffffffffL +#define BIT_DR21(x) (((x) & BIT_MASK_DR21) << BIT_SHIFT_DR21) +#define BIT_CTRL_DR21(x) (((x) & BIT_MASK_DR21) << BIT_SHIFT_DR21) +#define BIT_GET_DR21(x) (((x) >> BIT_SHIFT_DR21) & BIT_MASK_DR21) + + +//2 REG_SPIC_DR22 + +#define BIT_SHIFT_DR22 0 +#define BIT_MASK_DR22 0xffffffffL +#define BIT_DR22(x) (((x) & BIT_MASK_DR22) << BIT_SHIFT_DR22) +#define BIT_CTRL_DR22(x) (((x) & BIT_MASK_DR22) << BIT_SHIFT_DR22) +#define BIT_GET_DR22(x) (((x) >> BIT_SHIFT_DR22) & BIT_MASK_DR22) + + +//2 REG_SPIC_DR23 + +#define BIT_SHIFT_DR23 0 +#define BIT_MASK_DR23 0xffffffffL +#define BIT_DR23(x) (((x) & BIT_MASK_DR23) << BIT_SHIFT_DR23) +#define BIT_CTRL_DR23(x) (((x) & BIT_MASK_DR23) << BIT_SHIFT_DR23) +#define BIT_GET_DR23(x) (((x) >> BIT_SHIFT_DR23) & BIT_MASK_DR23) + + +//2 REG_SPIC_DR24 + +#define BIT_SHIFT_DR24 0 +#define BIT_MASK_DR24 0xffffffffL +#define BIT_DR24(x) (((x) & BIT_MASK_DR24) << BIT_SHIFT_DR24) +#define BIT_CTRL_DR24(x) (((x) & BIT_MASK_DR24) << BIT_SHIFT_DR24) +#define BIT_GET_DR24(x) (((x) >> BIT_SHIFT_DR24) & BIT_MASK_DR24) + + +//2 REG_SPIC_DR25 + +#define BIT_SHIFT_DR25 0 +#define BIT_MASK_DR25 0xffffffffL +#define BIT_DR25(x) (((x) & BIT_MASK_DR25) << BIT_SHIFT_DR25) +#define BIT_CTRL_DR25(x) (((x) & BIT_MASK_DR25) << BIT_SHIFT_DR25) +#define BIT_GET_DR25(x) (((x) >> BIT_SHIFT_DR25) & BIT_MASK_DR25) + + +//2 REG_SPIC_DR26 + +#define BIT_SHIFT_DR26 0 +#define BIT_MASK_DR26 0xffffffffL +#define BIT_DR26(x) (((x) & BIT_MASK_DR26) << BIT_SHIFT_DR26) +#define BIT_CTRL_DR26(x) (((x) & BIT_MASK_DR26) << BIT_SHIFT_DR26) +#define BIT_GET_DR26(x) (((x) >> BIT_SHIFT_DR26) & BIT_MASK_DR26) + + +//2 REG_SPIC_DR27 + +#define BIT_SHIFT_DR27 0 +#define BIT_MASK_DR27 0xffffffffL +#define BIT_DR27(x) (((x) & BIT_MASK_DR27) << BIT_SHIFT_DR27) +#define BIT_CTRL_DR27(x) (((x) & BIT_MASK_DR27) << BIT_SHIFT_DR27) +#define BIT_GET_DR27(x) (((x) >> BIT_SHIFT_DR27) & BIT_MASK_DR27) + + +//2 REG_SPIC_DR28 + +#define BIT_SHIFT_DR28 0 +#define BIT_MASK_DR28 0xffffffffL +#define BIT_DR28(x) (((x) & BIT_MASK_DR28) << BIT_SHIFT_DR28) +#define BIT_CTRL_DR28(x) (((x) & BIT_MASK_DR28) << BIT_SHIFT_DR28) +#define BIT_GET_DR28(x) (((x) >> BIT_SHIFT_DR28) & BIT_MASK_DR28) + + +//2 REG_SPIC_DR29 + +#define BIT_SHIFT_DR29 0 +#define BIT_MASK_DR29 0xffffffffL +#define BIT_DR29(x) (((x) & BIT_MASK_DR29) << BIT_SHIFT_DR29) +#define BIT_CTRL_DR29(x) (((x) & BIT_MASK_DR29) << BIT_SHIFT_DR29) +#define BIT_GET_DR29(x) (((x) >> BIT_SHIFT_DR29) & BIT_MASK_DR29) + + +//2 REG_SPIC_DR30 + +#define BIT_SHIFT_DR30 0 +#define BIT_MASK_DR30 0xffffffffL +#define BIT_DR30(x) (((x) & BIT_MASK_DR30) << BIT_SHIFT_DR30) +#define BIT_CTRL_DR30(x) (((x) & BIT_MASK_DR30) << BIT_SHIFT_DR30) +#define BIT_GET_DR30(x) (((x) >> BIT_SHIFT_DR30) & BIT_MASK_DR30) + + +//2 REG_SPIC_DR31 + +#define BIT_SHIFT_DR31 0 +#define BIT_MASK_DR31 0xffffffffL +#define BIT_DR31(x) (((x) & BIT_MASK_DR31) << BIT_SHIFT_DR31) +#define BIT_CTRL_DR31(x) (((x) & BIT_MASK_DR31) << BIT_SHIFT_DR31) +#define BIT_GET_DR31(x) (((x) >> BIT_SHIFT_DR31) & BIT_MASK_DR31) + + +//2 REG_SPIC_READ_FAST_SINGLE + +#define BIT_SHIFT_FRD_CMD 0 +#define BIT_MASK_FRD_CMD 0xff +#define BIT_FRD_CMD(x) (((x) & BIT_MASK_FRD_CMD) << BIT_SHIFT_FRD_CMD) +#define BIT_CTRL_FRD_CMD(x) (((x) & BIT_MASK_FRD_CMD) << BIT_SHIFT_FRD_CMD) +#define BIT_GET_FRD_CMD(x) (((x) >> BIT_SHIFT_FRD_CMD) & BIT_MASK_FRD_CMD) + + +//2 REG_SPIC_READ_DUAL_DATA + +#define BIT_SHIFT_RD_DUAL_O_CMD 0 +#define BIT_MASK_RD_DUAL_O_CMD 0xff +#define BIT_RD_DUAL_O_CMD(x) (((x) & BIT_MASK_RD_DUAL_O_CMD) << BIT_SHIFT_RD_DUAL_O_CMD) +#define BIT_CTRL_RD_DUAL_O_CMD(x) (((x) & BIT_MASK_RD_DUAL_O_CMD) << BIT_SHIFT_RD_DUAL_O_CMD) +#define BIT_GET_RD_DUAL_O_CMD(x) (((x) >> BIT_SHIFT_RD_DUAL_O_CMD) & BIT_MASK_RD_DUAL_O_CMD) + + +//2 REG_SPIC_READ_DUAL_ADDR_DATA + +#define BIT_SHIFT_RD_DUAL_IO_CMD 0 +#define BIT_MASK_RD_DUAL_IO_CMD 0xff +#define BIT_RD_DUAL_IO_CMD(x) (((x) & BIT_MASK_RD_DUAL_IO_CMD) << BIT_SHIFT_RD_DUAL_IO_CMD) +#define BIT_CTRL_RD_DUAL_IO_CMD(x) (((x) & BIT_MASK_RD_DUAL_IO_CMD) << BIT_SHIFT_RD_DUAL_IO_CMD) +#define BIT_GET_RD_DUAL_IO_CMD(x) (((x) >> BIT_SHIFT_RD_DUAL_IO_CMD) & BIT_MASK_RD_DUAL_IO_CMD) + + +//2 REG_SPIC_READ_QUAD_DATA + +#define BIT_SHIFT_RD_QUAD_O_CMD 0 +#define BIT_MASK_RD_QUAD_O_CMD 0xff +#define BIT_RD_QUAD_O_CMD(x) (((x) & BIT_MASK_RD_QUAD_O_CMD) << BIT_SHIFT_RD_QUAD_O_CMD) +#define BIT_CTRL_RD_QUAD_O_CMD(x) (((x) & BIT_MASK_RD_QUAD_O_CMD) << BIT_SHIFT_RD_QUAD_O_CMD) +#define BIT_GET_RD_QUAD_O_CMD(x) (((x) >> BIT_SHIFT_RD_QUAD_O_CMD) & BIT_MASK_RD_QUAD_O_CMD) + + +//2 REG_SPIC_READ_QUAD_ADDR_DATA + +#define BIT_SHIFT_RD_QUAD_IO_CMD 0 +#define BIT_MASK_RD_QUAD_IO_CMD 0xff +#define BIT_RD_QUAD_IO_CMD(x) (((x) & BIT_MASK_RD_QUAD_IO_CMD) << BIT_SHIFT_RD_QUAD_IO_CMD) +#define BIT_CTRL_RD_QUAD_IO_CMD(x) (((x) & BIT_MASK_RD_QUAD_IO_CMD) << BIT_SHIFT_RD_QUAD_IO_CMD) +#define BIT_GET_RD_QUAD_IO_CMD(x) (((x) >> BIT_SHIFT_RD_QUAD_IO_CMD) & BIT_MASK_RD_QUAD_IO_CMD) + + +//2 REG_SPIC_WRITE_SIGNLE + +#define BIT_SHIFT_WR_CMD 0 +#define BIT_MASK_WR_CMD 0xff +#define BIT_WR_CMD(x) (((x) & BIT_MASK_WR_CMD) << BIT_SHIFT_WR_CMD) +#define BIT_CTRL_WR_CMD(x) (((x) & BIT_MASK_WR_CMD) << BIT_SHIFT_WR_CMD) +#define BIT_GET_WR_CMD(x) (((x) >> BIT_SHIFT_WR_CMD) & BIT_MASK_WR_CMD) + + +//2 REG_SPIC_WRITE_DUAL_DATA + +#define BIT_SHIFT_WR_DUAL_I_CMD 0 +#define BIT_MASK_WR_DUAL_I_CMD 0xff +#define BIT_WR_DUAL_I_CMD(x) (((x) & BIT_MASK_WR_DUAL_I_CMD) << BIT_SHIFT_WR_DUAL_I_CMD) +#define BIT_CTRL_WR_DUAL_I_CMD(x) (((x) & BIT_MASK_WR_DUAL_I_CMD) << BIT_SHIFT_WR_DUAL_I_CMD) +#define BIT_GET_WR_DUAL_I_CMD(x) (((x) >> BIT_SHIFT_WR_DUAL_I_CMD) & BIT_MASK_WR_DUAL_I_CMD) + + +//2 REG_SPIC_WRITE_DUAL_ADDR_DATA + +#define BIT_SHIFT_WR_DUAL_II_CMD 0 +#define BIT_MASK_WR_DUAL_II_CMD 0xff +#define BIT_WR_DUAL_II_CMD(x) (((x) & BIT_MASK_WR_DUAL_II_CMD) << BIT_SHIFT_WR_DUAL_II_CMD) +#define BIT_CTRL_WR_DUAL_II_CMD(x) (((x) & BIT_MASK_WR_DUAL_II_CMD) << BIT_SHIFT_WR_DUAL_II_CMD) +#define BIT_GET_WR_DUAL_II_CMD(x) (((x) >> BIT_SHIFT_WR_DUAL_II_CMD) & BIT_MASK_WR_DUAL_II_CMD) + + +//2 REG_SPIC_WRITE_QUAD_DATA + +#define BIT_SHIFT_WR_QUAD_I_CMD 0 +#define BIT_MASK_WR_QUAD_I_CMD 0xff +#define BIT_WR_QUAD_I_CMD(x) (((x) & BIT_MASK_WR_QUAD_I_CMD) << BIT_SHIFT_WR_QUAD_I_CMD) +#define BIT_CTRL_WR_QUAD_I_CMD(x) (((x) & BIT_MASK_WR_QUAD_I_CMD) << BIT_SHIFT_WR_QUAD_I_CMD) +#define BIT_GET_WR_QUAD_I_CMD(x) (((x) >> BIT_SHIFT_WR_QUAD_I_CMD) & BIT_MASK_WR_QUAD_I_CMD) + + +//2 REG_SPIC_WRITE_QUAD_ADDR_DATA + +#define BIT_SHIFT_WR_QUAD_II_CMD 0 +#define BIT_MASK_WR_QUAD_II_CMD 0xff +#define BIT_WR_QUAD_II_CMD(x) (((x) & BIT_MASK_WR_QUAD_II_CMD) << BIT_SHIFT_WR_QUAD_II_CMD) +#define BIT_CTRL_WR_QUAD_II_CMD(x) (((x) & BIT_MASK_WR_QUAD_II_CMD) << BIT_SHIFT_WR_QUAD_II_CMD) +#define BIT_GET_WR_QUAD_II_CMD(x) (((x) >> BIT_SHIFT_WR_QUAD_II_CMD) & BIT_MASK_WR_QUAD_II_CMD) + + +//2 REG_SPIC_WRITE_ENABLE + +#define BIT_SHIFT_WR_EN_CMD 0 +#define BIT_MASK_WR_EN_CMD 0xff +#define BIT_WR_EN_CMD(x) (((x) & BIT_MASK_WR_EN_CMD) << BIT_SHIFT_WR_EN_CMD) +#define BIT_CTRL_WR_EN_CMD(x) (((x) & BIT_MASK_WR_EN_CMD) << BIT_SHIFT_WR_EN_CMD) +#define BIT_GET_WR_EN_CMD(x) (((x) >> BIT_SHIFT_WR_EN_CMD) & BIT_MASK_WR_EN_CMD) + + +//2 REG_SPIC_READ_STATUS + +#define BIT_SHIFT_RD_ST_CMD 0 +#define BIT_MASK_RD_ST_CMD 0xff +#define BIT_RD_ST_CMD(x) (((x) & BIT_MASK_RD_ST_CMD) << BIT_SHIFT_RD_ST_CMD) +#define BIT_CTRL_RD_ST_CMD(x) (((x) & BIT_MASK_RD_ST_CMD) << BIT_SHIFT_RD_ST_CMD) +#define BIT_GET_RD_ST_CMD(x) (((x) >> BIT_SHIFT_RD_ST_CMD) & BIT_MASK_RD_ST_CMD) + + +//2 REG_SPIC_CTRLR2 + +#define BIT_SHIFT_FIFO_ENTRY 4 +#define BIT_MASK_FIFO_ENTRY 0xf +#define BIT_FIFO_ENTRY(x) (((x) & BIT_MASK_FIFO_ENTRY) << BIT_SHIFT_FIFO_ENTRY) +#define BIT_CTRL_FIFO_ENTRY(x) (((x) & BIT_MASK_FIFO_ENTRY) << BIT_SHIFT_FIFO_ENTRY) +#define BIT_GET_FIFO_ENTRY(x) (((x) >> BIT_SHIFT_FIFO_ENTRY) & BIT_MASK_FIFO_ENTRY) + +#define BIT_WR_SEQ BIT(3) +#define BIT_SHIFT_WR_SEQ 3 +#define BIT_MASK_WR_SEQ 0x1 +#define BIT_CTRL_WR_SEQ(x) (((x) & BIT_MASK_WR_SEQ) << BIT_SHIFT_WR_SEQ) + +#define BIT_WPN_DNUM BIT(2) +#define BIT_SHIFT_WPN_DNUM 2 +#define BIT_MASK_WPN_DNUM 0x1 +#define BIT_CTRL_WPN_DNUM(x) (((x) & BIT_MASK_WPN_DNUM) << BIT_SHIFT_WPN_DNUM) + +#define BIT_WPN_SET BIT(1) +#define BIT_SHIFT_WPN_SET 1 +#define BIT_MASK_WPN_SET 0x1 +#define BIT_CTRL_WPN_SET(x) (((x) & BIT_MASK_WPN_SET) << BIT_SHIFT_WPN_SET) + +#define BIT_SO_DUM BIT(0) +#define BIT_SHIFT_SO_DUM 0 +#define BIT_MASK_SO_DUM 0x1 +#define BIT_CTRL_SO_DUM(x) (((x) & BIT_MASK_SO_DUM) << BIT_SHIFT_SO_DUM) + +//2 REG_SPIC_FBAUDR + +#define BIT_SHIFT_FSCKDV 0 +#define BIT_MASK_FSCKDV 0xfff +#define BIT_FSCKDV(x) (((x) & BIT_MASK_FSCKDV) << BIT_SHIFT_FSCKDV) +#define BIT_CTRL_FSCKDV(x) (((x) & BIT_MASK_FSCKDV) << BIT_SHIFT_FSCKDV) +#define BIT_GET_FSCKDV(x) (((x) >> BIT_SHIFT_FSCKDV) & BIT_MASK_FSCKDV) + + +//2 REG_SPIC_ADDR_LENGTH + +#define BIT_SHIFT_ADDR_PHASE_LENGTH 0 +#define BIT_MASK_ADDR_PHASE_LENGTH 0x3 +#define BIT_ADDR_PHASE_LENGTH(x) (((x) & BIT_MASK_ADDR_PHASE_LENGTH) << BIT_SHIFT_ADDR_PHASE_LENGTH) +#define BIT_CTRL_ADDR_PHASE_LENGTH(x) (((x) & BIT_MASK_ADDR_PHASE_LENGTH) << BIT_SHIFT_ADDR_PHASE_LENGTH) +#define BIT_GET_ADDR_PHASE_LENGTH(x) (((x) >> BIT_SHIFT_ADDR_PHASE_LENGTH) & BIT_MASK_ADDR_PHASE_LENGTH) + + +//2 REG_SPIC_AUTO_LENGTH + +#define BIT_SHIFT_CS_H_WR_DUM_LEN 28 +#define BIT_MASK_CS_H_WR_DUM_LEN 0xf +#define BIT_CS_H_WR_DUM_LEN(x) (((x) & BIT_MASK_CS_H_WR_DUM_LEN) << BIT_SHIFT_CS_H_WR_DUM_LEN) +#define BIT_CTRL_CS_H_WR_DUM_LEN(x) (((x) & BIT_MASK_CS_H_WR_DUM_LEN) << BIT_SHIFT_CS_H_WR_DUM_LEN) +#define BIT_GET_CS_H_WR_DUM_LEN(x) (((x) >> BIT_SHIFT_CS_H_WR_DUM_LEN) & BIT_MASK_CS_H_WR_DUM_LEN) + + +#define BIT_SHIFT_CS_H_RD_DUM_LEN 26 +#define BIT_MASK_CS_H_RD_DUM_LEN 0x3 +#define BIT_CS_H_RD_DUM_LEN(x) (((x) & BIT_MASK_CS_H_RD_DUM_LEN) << BIT_SHIFT_CS_H_RD_DUM_LEN) +#define BIT_CTRL_CS_H_RD_DUM_LEN(x) (((x) & BIT_MASK_CS_H_RD_DUM_LEN) << BIT_SHIFT_CS_H_RD_DUM_LEN) +#define BIT_GET_CS_H_RD_DUM_LEN(x) (((x) >> BIT_SHIFT_CS_H_RD_DUM_LEN) & BIT_MASK_CS_H_RD_DUM_LEN) + + +#define BIT_SHIFT_AUTO_DUM_LEN 18 +#define BIT_MASK_AUTO_DUM_LEN 0xff +#define BIT_AUTO_DUM_LEN(x) (((x) & BIT_MASK_AUTO_DUM_LEN) << BIT_SHIFT_AUTO_DUM_LEN) +#define BIT_CTRL_AUTO_DUM_LEN(x) (((x) & BIT_MASK_AUTO_DUM_LEN) << BIT_SHIFT_AUTO_DUM_LEN) +#define BIT_GET_AUTO_DUM_LEN(x) (((x) >> BIT_SHIFT_AUTO_DUM_LEN) & BIT_MASK_AUTO_DUM_LEN) + + +#define BIT_SHIFT_AUTO_ADDR__LENGTH 16 +#define BIT_MASK_AUTO_ADDR__LENGTH 0x3 +#define BIT_AUTO_ADDR__LENGTH(x) (((x) & BIT_MASK_AUTO_ADDR__LENGTH) << BIT_SHIFT_AUTO_ADDR__LENGTH) +#define BIT_CTRL_AUTO_ADDR__LENGTH(x) (((x) & BIT_MASK_AUTO_ADDR__LENGTH) << BIT_SHIFT_AUTO_ADDR__LENGTH) +#define BIT_GET_AUTO_ADDR__LENGTH(x) (((x) >> BIT_SHIFT_AUTO_ADDR__LENGTH) & BIT_MASK_AUTO_ADDR__LENGTH) + + +#define BIT_SHIFT_RD_DUMMY_LENGTH 0 +#define BIT_MASK_RD_DUMMY_LENGTH 0xffff +#define BIT_RD_DUMMY_LENGTH(x) (((x) & BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH) +#define BIT_CTRL_RD_DUMMY_LENGTH(x) (((x) & BIT_MASK_RD_DUMMY_LENGTH) << BIT_SHIFT_RD_DUMMY_LENGTH) +#define BIT_GET_RD_DUMMY_LENGTH(x) (((x) >> BIT_SHIFT_RD_DUMMY_LENGTH) & BIT_MASK_RD_DUMMY_LENGTH) + + +//2 REG_SPIC_VALID_CMD +#define BIT_WR_BLOCKING BIT(9) +#define BIT_SHIFT_WR_BLOCKING 9 +#define BIT_MASK_WR_BLOCKING 0x1 +#define BIT_CTRL_WR_BLOCKING(x) (((x) & BIT_MASK_WR_BLOCKING) << BIT_SHIFT_WR_BLOCKING) + +#define BIT_WR_QUAD_II BIT(8) +#define BIT_SHIFT_WR_QUAD_II 8 +#define BIT_MASK_WR_QUAD_II 0x1 +#define BIT_CTRL_WR_QUAD_II(x) (((x) & BIT_MASK_WR_QUAD_II) << BIT_SHIFT_WR_QUAD_II) + +#define BIT_WR_QUAD_I BIT(7) +#define BIT_SHIFT_WR_QUAD_I 7 +#define BIT_MASK_WR_QUAD_I 0x1 +#define BIT_CTRL_WR_QUAD_I(x) (((x) & BIT_MASK_WR_QUAD_I) << BIT_SHIFT_WR_QUAD_I) + +#define BIT_WR_DUAL_II BIT(6) +#define BIT_SHIFT_WR_DUAL_II 6 +#define BIT_MASK_WR_DUAL_II 0x1 +#define BIT_CTRL_WR_DUAL_II(x) (((x) & BIT_MASK_WR_DUAL_II) << BIT_SHIFT_WR_DUAL_II) + +#define BIT_WR_DUAL_I BIT(5) +#define BIT_SHIFT_WR_DUAL_I 5 +#define BIT_MASK_WR_DUAL_I 0x1 +#define BIT_CTRL_WR_DUAL_I(x) (((x) & BIT_MASK_WR_DUAL_I) << BIT_SHIFT_WR_DUAL_I) + +#define BIT_RD_QUAD_IO BIT(4) +#define BIT_SHIFT_RD_QUAD_IO 4 +#define BIT_MASK_RD_QUAD_IO 0x1 +#define BIT_CTRL_RD_QUAD_IO(x) (((x) & BIT_MASK_RD_QUAD_IO) << BIT_SHIFT_RD_QUAD_IO) + +#define BIT_RD_QUAD_O BIT(3) +#define BIT_SHIFT_RD_QUAD_O 3 +#define BIT_MASK_RD_QUAD_O 0x1 +#define BIT_CTRL_RD_QUAD_O(x) (((x) & BIT_MASK_RD_QUAD_O) << BIT_SHIFT_RD_QUAD_O) + +#define BIT_RD_DUAL_IO BIT(2) +#define BIT_SHIFT_RD_DUAL_IO 2 +#define BIT_MASK_RD_DUAL_IO 0x1 +#define BIT_CTRL_RD_DUAL_IO(x) (((x) & BIT_MASK_RD_DUAL_IO) << BIT_SHIFT_RD_DUAL_IO) + +#define BIT_RD_DUAL_I BIT(1) +#define BIT_SHIFT_RD_DUAL_I 1 +#define BIT_MASK_RD_DUAL_I 0x1 +#define BIT_CTRL_RD_DUAL_I(x) (((x) & BIT_MASK_RD_DUAL_I) << BIT_SHIFT_RD_DUAL_I) + +#define BIT_FRD_SINGEL BIT(0) +#define BIT_SHIFT_FRD_SINGEL 0 +#define BIT_MASK_FRD_SINGEL 0x1 +#define BIT_CTRL_FRD_SINGEL(x) (((x) & BIT_MASK_FRD_SINGEL) << BIT_SHIFT_FRD_SINGEL) + +//2 REG_SPIC_FLASE_SIZE + +#define BIT_SHIFT_FLASE_SIZE 0 +#define BIT_MASK_FLASE_SIZE 0xf +#define BIT_FLASE_SIZE(x) (((x) & BIT_MASK_FLASE_SIZE) << BIT_SHIFT_FLASE_SIZE) +#define BIT_CTRL_FLASE_SIZE(x) (((x) & BIT_MASK_FLASE_SIZE) << BIT_SHIFT_FLASE_SIZE) +#define BIT_GET_FLASE_SIZE(x) (((x) >> BIT_SHIFT_FLASE_SIZE) & BIT_MASK_FLASE_SIZE) + + +//2 REG_SPIC_FLUSH_FIFO +#define BIT_FLUSH_FIFO BIT(0) +#define BIT_SHIFT_FLUSH_FIFO 0 +#define BIT_MASK_FLUSH_FIFO 0x1 +#define BIT_CTRL_FLUSH_FIFO(x) (((x) & BIT_MASK_FLUSH_FIFO) << BIT_SHIFT_FLUSH_FIFO) + +//=================== Register Address Definition ============================// +#define REG_SPIC_CTRLR0 0x0000 //O 0x1040300 +#define REG_SPIC_CTRLR1 0x0004 //O 0x10 +#define REG_SPIC_SSIENR 0x0008 //O 0 +#define REG_SPIC_MWCR 0x000C // 0 +#define REG_SPIC_SER 0x0010 //O 1 +#define REG_SPIC_BAUDR 0x0014 //O 1 +#define REG_SPIC_TXFTLR 0x0018 // 0 +#define REG_SPIC_RXFTLR 0x001C //O 0x1F +#define REG_SPIC_TXFLR 0x0020 //O 0 +#define REG_SPIC_RXFLR 0x0024 // 0 +#define REG_SPIC_SR 0x0028 // 6 +#define REG_SPIC_IMR 0x002C //O 0x1FF +#define REG_SPIC_ISR 0x0030 // 4 +#define REG_SPIC_RISR 0x0034 // 4 +#define REG_SPIC_TXOICR 0x0038 // 0 +#define REG_SPIC_RXOICR 0x003C // 0 +#define REG_SPC_RXUICR 0x0040 // 0 +#define REG_SPIC_MSTICR 0x0044 // 0 +#define REG_SPIC_ICR 0x0048 // 0 +#define REG_SPIC_DMACR 0x004C // 0 +#define REG_SPIC_DMATDLR0 0x0050 // 0 +#define REG_SPIC_DMATDLR1 0x0054 // 0 +#define REG_SPIC_IDR 0x0058 // 0x10001 +#define REG_SPIC_VERSION 0x005C // 0x40470603 +#define REG_SPIC_DR0 0x0060 +#define REG_SPIC_DR1 0x0064 +#define REG_SPIC_DR2 0x0068 +#define REG_SPIC_DR3 0x006C +#define REG_SPIC_DR4 0x0070 +#define REG_SPIC_DR5 0x0074 +#define REG_SPIC_DR6 0x0078 +#define REG_SPIC_DR7 0x007C +#define REG_SPIC_DR8 0x0080 +#define REG_SPIC_DR9 0x0084 +#define REG_SPIC_DR10 0x0088 +#define REG_SPIC_DR11 0x008C +#define REG_SPIC_DR12 0x0090 +#define REG_SPIC_DR13 0x0094 +#define REG_SPIC_DR14 0x0098 +#define REG_SPIC_DR15 0x009C +#define REG_SPIC_DR16 0x00A0 +#define REG_SPIC_DR17 0x00A4 +#define REG_SPIC_DR18 0x00A8 +#define REG_SPIC_DR19 0x00AC +#define REG_SPIC_DR20 0x00B0 +#define REG_SPIC_DR21 0x00B4 +#define REG_SPIC_DR22 0x00B8 +#define REG_SPIC_DR23 0x00BC +#define REG_SPIC_DR24 0x00C0 +#define REG_SPIC_DR25 0x00C4 +#define REG_SPIC_DR26 0x00C8 +#define REG_SPIC_DR27 0x00CC +#define REG_SPIC_DR28 0x00D0 +#define REG_SPIC_DR29 0x00D4 +#define REG_SPIC_DR30 0x00D8 +#define REG_SPIC_DR31 0x00DC // MXIC (DeviceID: FC, Flash Size: 1048576 bytes, FlashID: C22014/1, SpicMode: DIO) +#define REG_SPIC_READ_FAST_SINGLE 0x00E0 //O 0x0B +#define REG_SPIC_READ_DUAL_DATA 0x00E4 //O 0x3B +#define REG_SPIC_READ_DUAL_ADDR_DATA 0x00E8 //O 0x3B +#define REG_SPIC_READ_QUAD_DATA 0x00EC //O 0x6B +#define REG_SPIC_READ_QUAD_ADDR_DATA 0x00F0 //O 0xEB +#define REG_SPIC_WRITE_SIGNLE 0x00F4 //O 0x02 +#define REG_SPIC_WRITE_DUAL_DATA 0x00F8 //O 0xA2 +#define REG_SPIC_WRITE_DUAL_ADDR_DATA 0x00FC//O 0xA2 +#define REG_SPIC_WRITE_QUAD_DATA 0x0100 //O 0x32 +#define REG_SPIC_WRITE_QUAD_ADDR_DATA 0x0104//O 0x38 +#define REG_SPIC_WRITE_ENABLE 0x0108 //O 0x06 +#define REG_SPIC_READ_STATUS 0x010C //O 0x05 +#define REG_SPIC_CTRLR2 0x0110 //O 0x51 +#define REG_SPIC_FBAUDR 0x0114 //O 0x1 +#define REG_SPIC_ADDR_LENGTH 0x0118 //O 0x3 +#define REG_SPIC_AUTO_LENGTH 0x011C //O 0x20030011/0x20030021 +#define REG_SPIC_VALID_CMD 0x0120 //O 0x202 +#define REG_SPIC_FLASE_SIZE 0x0124 //O 0x0E +#define REG_SPIC_FLUSH_FIFO 0x0128 //O 0 + +VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode); // spi-flash controller initialization +VOID SpicRxCmdRtl8195A(u8 cmd); // recieve command +VOID SpicTxCmdRtl8195A(u8 cmd, SPIC_INIT_PARA SpicInitPara); // transfer command +u8 SpicGetFlashStatusRtl8195A(SPIC_INIT_PARA SpicInitPara); // RDSR, read spi-flash status register +VOID SpicSetFlashStatusRtl8195A(u32 data, SPIC_INIT_PARA SpicInitPara); // WRSR, write spi-flash status register +VOID SpicWaitBusyDoneRtl8195A(VOID); // wait sr[0] = 0, wait transmission done +VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); // wait spi-flash status register[0] = 0 +VOID SpicEraseFlashRtl8195A(VOID); // CE, flash chip erase +u32 SpicCmpDataForCalibrationRtl8195A(VOID); // compare read_data and golden_data +VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); + +#if 1//CONFIG_CHIP_E_CUT + +VOID +SpicTxCmdWithDataRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 cmd, + IN u8 DataPhaseLen, + IN u8* pData +); + +VOID +SpicTxFlashInstRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 cmd, + IN u8 DataPhaseLen, + IN u8* pData +); + +VOID +SpicDeepPowerDownFlashRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara +); + +VOID +SpicBlockEraseFlashRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u32 Address +); + +VOID +SpicSectorEraseFlashRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u32 Address +); + +VOID +SpicWriteProtectFlashRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u32 Protect +); + +BOOLEAN +SpicFlashInitRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 SpicBitMode +); + +u32 +SpicCalibrationRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 SpicBitMode, + IN u32 DefRdDummyCycle +); + +VOID +SpicConfigAutoModeRtl8195A_V04( + IN u8 SpicBitMode +); + +VOID +SpicWaitWipDoneRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara +); + +VOID +SpicRxCmdRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 cmd +); + +u8 +SpicGetFlashStatusRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara +); + +VOID +SpicInitRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 InitBaudRate, + IN u8 SpicBitMode +); + +VOID +SpicEraseFlashRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara +); + +VOID +SpicSetFlashStatusRefinedRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u32 data +); + +u32 +SpicWaitWipRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara +); + +u32 +SpicOneBitCalibrationRtl8195A_V04( + IN SPIC_INIT_PARA *pSpicInitPara, + IN u8 SysCpuClk +); + +VOID +SpicLoadInitParaFromClockRtl8195A_V04( + IN u8 CpuClkMode, + IN u8 BaudRate, + IN PSPIC_INIT_PARA pSpicInitPara +) ; + +u8 +SpicGetFlashFlagRtl8195A_V04(IN SPIC_INIT_PARA * pSpicInitPara); + +VOID +SpicWaitOperationDoneRtl8195A_V04(IN SPIC_INIT_PARA * pSpicInitPara); + +VOID +SpicUserProgramRtl8195A_V04(IN u8 * data, IN SPIC_INIT_PARA SpicInitPara, IN u32 addr, IN u32 * LengthInfo); + +VOID +SpicUserReadRtl8195A_V04(IN u32 Length, IN u32 addr, IN u8 * data); + +VOID +SpicUserReadFourByteRtl8195A_V04(IN u32 Length, IN u32 addr, IN u32 * data, IN u8 BitMode); + +VOID +SpicSetExtendAddrRtl8195A_V04(IN u32 data, IN SPIC_INIT_PARA * pSpicInitPara); + +u8 +SpicGetExtendAddrRtl8195A_V04(IN SPIC_INIT_PARA * pSpicInitPara); + +VOID +SpicReadIDRtl8195A_V04(VOID); + +VOID +SpicDieEraseFlashRtl8195A_V04(IN SPIC_INIT_PARA * pSpicInitPara, IN u32 Address); + +u8 +SpicGetConfigRegRtl8195A_V04(IN SPIC_INIT_PARA * pSpicInitPara); +#endif // #if CONFIG_CHIP_E_CUT + +#endif // end of "#ifndef _RTL8195A_SPI_FLASH_H" diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_ssi.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_ssi.h new file mode 100644 index 0000000..2e4bcc3 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_ssi.h @@ -0,0 +1,530 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_SSI_H_ +#define _RTL8195A_SSI_H_ + +#define SSI_DUMMY_DATA 0x00 // for master mode, we need to push a Dummy data to TX FIFO for read + +#define SSI_CLK_SPI1 (PLATFORM_CLOCK/2) +#define SSI_CLK_SPI0_2 (PLATFORM_CLOCK/4) + +/* Parameters of DW_apb_ssi for RTL8195A */ +#define SSI_TX_FIFO_DEPTH 64 +#define TX_ABW 6 // 1-8, log2(SSI_TX_FIFO_DEPTH) +#define SSI_RX_FIFO_DEPTH 64 +#define RX_ABW 6 // 1-8, log2(SSI_RX_FIFO_DEPTH) + +#define SSI0_REG_BASE 0x40042000 +#define SSI1_REG_BASE 0x40042400 +#define SSI2_REG_BASE 0x40042800 + +/* Memory Map of DW_apb_ssi */ +#define REG_DW_SSI_CTRLR0 0x00 // 16 bits +#define REG_DW_SSI_CTRLR1 0x04 // 16 bits +#define REG_DW_SSI_SSIENR 0x08 // 1 bit +#define REG_DW_SSI_MWCR 0x0C // 3 bits +#define REG_DW_SSI_SER 0x10 // +#define REG_DW_SSI_BAUDR 0x14 // 16 bits +#define REG_DW_SSI_TXFTLR 0x18 // TX_ABW +#define REG_DW_SSI_RXFTLR 0x1C // RX_ABW +#define REG_DW_SSI_TXFLR 0x20 // +#define REG_DW_SSI_RXFLR 0x24 // +#define REG_DW_SSI_SR 0x28 // 7 bits +#define REG_DW_SSI_IMR 0x2C // +#define REG_DW_SSI_ISR 0x30 // 6 bits +#define REG_DW_SSI_RISR 0x34 // 6 bits +#define REG_DW_SSI_TXOICR 0x38 // 1 bits +#define REG_DW_SSI_RXOICR 0x3C // 1 bits +#define REG_DW_SSI_RXUICR 0x40 // 1 bits +#define REG_DW_SSI_MSTICR 0x44 // 1 bits +#define REG_DW_SSI_ICR 0x48 // 1 bits +#define REG_DW_SSI_DMACR 0x4C // 2 bits +#define REG_DW_SSI_DMATDLR 0x50 // TX_ABW +#define REG_DW_SSI_DMARDLR 0x54 // RX_ABW +#define REG_DW_SSI_IDR 0x58 // 32 bits +#define REG_DW_SSI_COMP_VERSION 0x5C // 32 bits +#define REG_DW_SSI_DR 0x60 // 16 bits 0x60-0xEC +#define REG_DW_SSI_RX_SAMPLE_DLY 0xF0 // 8 bits +#define REG_DW_SSI_RSVD_0 0xF4 // 32 bits +#define REG_DW_SSI_RSVD_1 0xF8 // 32 bits +#define REG_DW_SSI_RSVD_2 0xFC // 32 bits + +// CTRLR0 0x00 // 16 bits, 6.2.1 +// DFS Reset Value: 0x7 +#define BIT_SHIFT_CTRLR0_DFS 0 +#define BIT_MASK_CTRLR0_DFS 0xF +#define BIT_CTRLR0_DFS(x)(((x) & BIT_MASK_CTRLR0_DFS) << BIT_SHIFT_CTRLR0_DFS) +#define BIT_INVC_CTRLR0_DFS (~(BIT_MASK_CTRLR0_DFS << BIT_SHIFT_CTRLR0_DFS)) + +#define BIT_SHIFT_CTRLR0_FRF 4 +#define BIT_MASK_CTRLR0_FRF 0x3 +#define BIT_CTRLR0_FRF(x)(((x) & BIT_MASK_CTRLR0_FRF) << BIT_SHIFT_CTRLR0_FRF) +#define BIT_INVC_CTRLR0_FRF (~(BIT_MASK_CTRLR0_FRF << BIT_SHIFT_CTRLR0_FRF)) + +#define BIT_SHIFT_CTRLR0_SCPH 6 +#define BIT_MASK_CTRLR0_SCPH 0x1 +#define BIT_CTRLR0_SCPH(x)(((x) & BIT_MASK_CTRLR0_SCPH) << BIT_SHIFT_CTRLR0_SCPH) +#define BIT_INVC_CTRLR0_SCPH (~(BIT_MASK_CTRLR0_SCPH << BIT_SHIFT_CTRLR0_SCPH)) + +#define BIT_SHIFT_CTRLR0_SCPOL 7 +#define BIT_MASK_CTRLR0_SCPOL 0x1 +#define BIT_CTRLR0_SCPOL(x)(((x) & BIT_MASK_CTRLR0_SCPOL) << BIT_SHIFT_CTRLR0_SCPOL) +#define BIT_INVC_CTRLR0_SCPOL (~(BIT_MASK_CTRLR0_SCPOL << BIT_SHIFT_CTRLR0_SCPOL)) + +#define BIT_SHIFT_CTRLR0_TMOD 8 +#define BIT_MASK_CTRLR0_TMOD 0x3 +#define BIT_CTRLR0_TMOD(x)(((x) & BIT_MASK_CTRLR0_TMOD) << BIT_SHIFT_CTRLR0_TMOD) +#define BIT_INVC_CTRLR0_TMOD (~(BIT_MASK_CTRLR0_TMOD << BIT_SHIFT_CTRLR0_TMOD)) + +#define BIT_SHIFT_CTRLR0_SLV_OE 10 +#define BIT_MASK_CTRLR0_SLV_OE 0x1 +#define BIT_CTRLR0_SLV_OE(x)(((x) & BIT_MASK_CTRLR0_SLV_OE) << BIT_SHIFT_CTRLR0_SLV_OE) +#define BIT_INVC_CTRLR0_SLV_OE (~(BIT_MASK_CTRLR0_SLV_OE << BIT_SHIFT_CTRLR0_SLV_OE)) + +#define BIT_SHIFT_CTRLR0_SRL 11 +#define BIT_MASK_CTRLR0_SRL 0x1 +#define BIT_CTRLR0_SRL(x)(((x) & BIT_MASK_CTRLR0_SRL) << BIT_SHIFT_CTRLR0_SRL) +#define BIT_INVC_CTRLR0_SRL (~(BIT_MASK_CTRLR0_SRL << BIT_SHIFT_CTRLR0_SRL)) + +#define BIT_SHIFT_CTRLR0_CFS 12 +#define BIT_MASK_CTRLR0_CFS 0xF +#define BIT_CTRLR0_CFS(x)(((x) & BIT_MASK_CTRLR0_CFS) << BIT_SHIFT_CTRLR0_CFS) +#define BIT_INVC_CTRLR0_CFS (~(BIT_MASK_CTRLR0_CFS << BIT_SHIFT_CTRLR0_CFS)) + +// CTRLR1 0x04 // 16 bits +#define BIT_SHIFT_CTRLR1_NDF 0 +#define BIT_MASK_CTRLR1_NDF 0xFFFF +#define BIT_CTRLR1_NDF(x)(((x) & BIT_MASK_CTRLR1_NDF) << BIT_SHIFT_CTRLR1_NDF) +#define BIT_INVC_CTRLR1_NDF (~(BIT_MASK_CTRLR1_NDF << BIT_SHIFT_CTRLR1_NDF)) + +// SSIENR 0x08 // 1 bit +#define BIT_SHIFT_SSIENR_SSI_EN 0 +#define BIT_MASK_SSIENR_SSI_EN 0x1 +#define BIT_SSIENR_SSI_EN(x)(((x) & BIT_MASK_SSIENR_SSI_EN) << BIT_SHIFT_SSIENR_SSI_EN) +#define BIT_INVC_SSIENR_SSI_EN (~(BIT_MASK_SSIENR_SSI_EN << BIT_SHIFT_SSIENR_SSI_EN)) + +// MWCR 0x0c // 3 bits +#define BIT_SHIFT_MWCR_MWMOD 0 +#define BIT_MASK_MWCR_MWMOD 0x1 +#define BIT_MWCR_MWMOD(x)(((x) & BIT_MASK_MWCR_MWMOD) << BIT_SHIFT_MWCR_MWMOD) +#define BIT_INVC_MWCR_MWMOD (~(BIT_MASK_MWCR_MWMOD << BIT_SHIFT_MWCR_MWMOD)) + +#define BIT_SHIFT_MWCR_MDD 1 +#define BIT_MASK_MWCR_MDD 0x1 +#define BIT_MWCR_MDD(x)(((x) & BIT_MASK_MWCR_MDD) << BIT_SHIFT_MWCR_MDD) +#define BIT_INVC_MWCR_MDD (~(BIT_MASK_MWCR_MDD << BIT_SHIFT_MWCR_MDD)) + +#define BIT_SHIFT_MWCR_MHS 2 +#define BIT_MASK_MWCR_MHS 0x1 +#define BIT_MWCR_MHS(x)(((x) & BIT_MASK_MWCR_MHS) << BIT_SHIFT_MWCR_MHS) +#define BIT_INVC_MWCR_MHS (~(BIT_MASK_MWCR_MHS << BIT_SHIFT_MWCR_MHS)) + +// SER 0x10 // Variable Length +#define BIT_SHIFT_SER_SER 0 +#define BIT_MASK_SER_SER 0xFF +#define BIT_SER_SER(x)(((x) & BIT_MASK_SER_SER) << BIT_SHIFT_SER_SER) +#define BIT_INVC_SER_SER (~(BIT_MASK_SER_SER << BIT_SHIFT_SER_SER)) + +// BAUDR 0x14 // 16 bits +#define BIT_SHIFT_BAUDR_SCKDV 0 +#define BIT_MASK_BAUDR_SCKDV 0xFFFF +#define BIT_BAUDR_SCKDV(x)(((x) & BIT_MASK_BAUDR_SCKDV) << BIT_SHIFT_BAUDR_SCKDV) +#define BIT_INVC_BAUDR_SCKDV (~(BIT_MASK_BAUDR_SCKDV << BIT_SHIFT_BAUDR_SCKDV)) + +// TXFLTR 0x18 // Variable Length +#define BIT_SHIFT_TXFTLR_TFT 0 +#define BIT_MASK_TXFTLR_TFT 0x3F // (TX_ABW-1):0 +#define BIT_TXFTLR_TFT(x)(((x) & BIT_MASK_TXFTLR_TFT) << BIT_SHIFT_TXFTLR_TFT) +#define BIT_INVC_TXFTLR_TFT (~(BIT_MASK_TXFTLR_TFT << BIT_SHIFT_TXFTLR_TFT)) + +// RXFLTR 0x1c // Variable Length +#define BIT_SHIFT_RXFTLR_RFT 0 +#define BIT_MASK_RXFTLR_RFT 0x3F // (RX_ABW-1):0 +#define BIT_RXFTLR_RFT(x)(((x) & BIT_MASK_RXFTLR_RFT) << BIT_SHIFT_RXFTLR_RFT) +#define BIT_INVC_RXFTLR_RFT (~(BIT_MASK_RXFTLR_RFT << BIT_SHIFT_RXFTLR_RFT)) + +// TXFLR 0x20 // see [READ ONLY] +#define BIT_MASK_TXFLR_TXTFL 0x7F // (TX_ABW):0 + +// RXFLR 0x24 // see [READ ONLY] +#define BIT_MASK_RXFLR_RXTFL 0x7F // (RX_ABW):0 + +// SR 0x28 // 7 bits [READ ONLY] +#define BIT_SR_BUSY BIT0 +#define BIT_SR_TFNF BIT1 +#define BIT_SR_TFE BIT2 +#define BIT_SR_RFNE BIT3 +#define BIT_SR_RFF BIT4 +#define BIT_SR_TXE BIT5 +#define BIT_SR_DCOL BIT6 + +// IMR 0x2c // see +#define BIT_SHIFT_IMR_TXEIM 0 +#define BIT_MASK_IMR_TXEIM 0x1 +// #define BIT_IMR_TXEIM(x)(((x) & BIT_MASK_IMR_TXEIM) << BIT_SHIFT_IMR_TXEIM) +#define BIT_INVC_IMR_TXEIM (~(BIT_MASK_IMR_TXEIM << BIT_SHIFT_IMR_TXEIM)) + +#define BIT_SHIFT_IMR_TXOIM 1 +#define BIT_MASK_IMR_TXOIM 0x1 +// #define BIT_IMR_TXOIM(x)(((x) & BIT_MASK_IMR_TXOIM) << BIT_SHIFT_IMR_TXOIM) +#define BIT_INVC_IMR_TXOIM (~(BIT_MASK_IMR_TXOIM << BIT_SHIFT_IMR_TXOIM)) + +#define BIT_SHIFT_IMR_RXUIM 2 +#define BIT_MASK_IMR_RXUIM 0x1 +// #define BIT_IMR_RXUIM(x)(((x) & BIT_MASK_IMR_RXUIM) << BIT_SHIFT_IMR_RXUIM) +#define BIT_INVC_IMR_RXUIM (~(BIT_MASK_IMR_RXUIM << BIT_SHIFT_IMR_RXUIM)) + +#define BIT_SHIFT_IMR_RXOIM 3 +#define BIT_MASK_IMR_RXOIM 0x1 +// #define BIT_IMR_RXOIM(x)(((x) & BIT_MASK_IMR_RXOIM) << BIT_SHIFT_IMR_RXOIM) +#define BIT_INVC_IMR_RXOIM (~(BIT_MASK_IMR_RXOIM << BIT_SHIFT_IMR_RXOIM)) + +#define BIT_SHIFT_IMR_RXFIM 4 +#define BIT_MASK_IMR_RXFIM 0x1 +// #define BIT_IMR_RXFIM(x)(((x) & BIT_MASK_IMR_RXFIM) << BIT_SHIFT_IMR_RXFIM) +#define BIT_INVC_IMR_RXFIM (~(BIT_MASK_IMR_RXFIM << BIT_SHIFT_IMR_RXFIM)) + +#define BIT_SHIFT_IMR_MSTIM 5 +#define BIT_MASK_IMR_MSTIM 0x1 +// #define BIT_IMR_MSTIM(x)(((x) & BIT_MASK_IMR_MSTIM) << BIT_SHIFT_IMR_MSTIM) +#define BIT_INVC_IMR_MSTIM (~(BIT_MASK_IMR_MSTIM << BIT_SHIFT_IMR_MSTIM)) + +#define BIT_IMR_TXEIM BIT0 +#define BIT_IMR_TXOIM BIT1 +#define BIT_IMR_RXUIM BIT2 +#define BIT_IMR_RXOIM BIT3 +#define BIT_IMR_RXFIM BIT4 +#define BIT_IMR_MSTIM BIT5 + +// ISR 0x30 // 6 bits [READ ONLY] +#define BIT_ISR_TXEIS BIT0 +#define BIT_ISR_TXOIS BIT1 +#define BIT_ISR_RXUIS BIT2 +#define BIT_ISR_RXOIS BIT3 +#define BIT_ISR_RXFIS BIT4 +#define BIT_ISR_MSTIS BIT5 + +// RISR 0x34 // 6 bits [READ ONLY] +#define BIT_RISR_TXEIR BIT0 +#define BIT_RISR_TXOIR BIT1 +#define BIT_RISR_RXUIR BIT2 +#define BIT_RISR_RXOIR BIT3 +#define BIT_RISR_RXFIR BIT4 +#define BIT_RISR_MSTIR BIT5 + +// TXOICR 0x38 // 1 bits [READ ONLY] +// RXOICR 0x3c // 1 bits [READ ONLY] +// RXUICR 0x40 // 1 bits [READ ONLY] +// MSTICR 0x44 // 1 bits [READ ONLY] +// ICR 0x48 // 1 bits [READ ONLY] + +// DMACR 0x4c // 2 bits +#define BIT_SHIFT_DMACR_RDMAE 0 +#define BIT_MASK_DMACR_RDMAE 0x1 +#define BIT_DMACR_RDMAE(x)(((x) & BIT_MASK_DMACR_RDMAE) << BIT_SHIFT_DMACR_RDMAE) +#define BIT_INVC_DMACR_RDMAE (~(BIT_MASK_DMACR_RDMAE << BIT_SHIFT_DMACR_RDMAE)) + +#define BIT_SHIFT_DMACR_TDMAE 1 +#define BIT_MASK_DMACR_TDMAE 0x1 +#define BIT_DMACR_TDMAE(x)(((x) & BIT_MASK_DMACR_TDMAE) << BIT_SHIFT_DMACR_TDMAE) +#define BIT_INVC_DMACR_TDMAE (~(BIT_MASK_DMACR_TDMAE << BIT_SHIFT_DMACR_TDMAE)) + +// DMATDLR 0x50 +#define BIT_SHIFT_DMATDLR_DMATDL 0 +#define BIT_MASK_DMATDLR_DMATDL 0x3F // (TX_ABW-1):0 +#define BIT_DMATDLR_DMATDL(x)(((x) & BIT_MASK_DMATDLR_DMATDL) << BIT_SHIFT_DMATDLR_DMATDL) +#define BIT_INVC_DMATDLR_DMATDL (~(BIT_MASK_DMATDLR_DMATDL << BIT_SHIFT_DMATDLR_DMATDL)) + +// DMARDLR 0x54 +#define BIT_SHIFT_DMARDLR_DMARDL 0 +#define BIT_MASK_DMARDLR_DMARDL 0x3F // (RX_ABW-1):0 +#define BIT_DMARDLR_DMARDL(x)(((x) & BIT_MASK_DMARDLR_DMARDL) << BIT_SHIFT_DMARDLR_DMARDL) +#define BIT_INVC_DMARDLR_DMARDL (~(BIT_MASK_DMARDLR_DMARDL << BIT_SHIFT_DMARDLR_DMARDL)) + +// IDR 0x58 // 32 bits [READ ONLY] +// COMP_VERSION 0x5c // 32 bits [READ ONLY] + +// DR 0x60 // 16 bits 0x60-0xEC +#define BIT_SHIFT_DR_DR 0 +#define BIT_MASK_DR_DR 0xFFFF +#define BIT_DR_DR(x)(((x) & BIT_MASK_DR_DR) << BIT_SHIFT_DR_DR) +#define BIT_INVC_DR_DR (~(BIT_MASK_DR_DR << BIT_SHIFT_DR_DR)) + +// RX_SAMPLE_DLY 0xF0 // 8 bits +#define BIT_SHIFT_RX_SAMPLE_DLY_RSD 0 +#define BIT_MASK_RX_SAMPLE_DLY_RSD 0xFFFF +#define BIT_RX_SAMPLE_DLY_RSD(x)(((x) & BIT_MASK_RX_SAMPLE_DLY_RSD) << BIT_SHIFT_RX_SAMPLE_DLY_RSD) +#define BIT_INVC_RX_SAMPLE_DLY_RSD (~(BIT_MASK_RX_SAMPLE_DLY_RSD << BIT_SHIFT_RX_SAMPLE_DLY_RSD)) + +// RSVD_0 0xF4 // 32 bits +// RSVD_1 0xF8 // 32 bits +// RSVD_2 0xFC // 32 bits + +// SSI0 Pinmux +#define BIT_SHIFT_SSI0_PIN_EN 0 +#define BIT_MASK_SSI0_PIN_EN 0x1 +#define BIT_SSI0_PIN_EN(x)(((x) & BIT_MASK_SSI0_PIN_EN) << BIT_SHIFT_SSI0_PIN_EN) +#define BIT_INVC_SSI0_PIN_EN (~(BIT_MASK_SSI0_PIN_EN << BIT_SHIFT_SSI0_PIN_EN)) + +#define BIT_SHIFT_SSI0_PIN_SEL 1 +#define BIT_MASK_SSI0_PIN_SEL 0x7 +#define BIT_SSI0_PIN_SEL(x)(((x) & BIT_MASK_SSI0_PIN_SEL) << BIT_SHIFT_SSI0_PIN_SEL) +#define BIT_INVC_SSI0_PIN_SEL (~(BIT_MASK_SSI0_PIN_SEL << BIT_SHIFT_SSI0_PIN_SEL)) + +// SSI1 Pinmux +#define BIT_SHIFT_SSI1_PIN_EN 4 +#define BIT_MASK_SSI1_PIN_EN 0x1 +#define BIT_SSI1_PIN_EN(x)(((x) & BIT_MASK_SSI1_PIN_EN) << BIT_SHIFT_SSI1_PIN_EN) +#define BIT_INVC_SSI1_PIN_EN (~(BIT_MASK_SSI1_PIN_EN << BIT_SHIFT_SSI1_PIN_EN)) + +#define BIT_SHIFT_SSI1_PIN_SEL 5 +#define BIT_MASK_SSI1_PIN_SEL 0x7 +#define BIT_SSI1_PIN_SEL(x)(((x) & BIT_MASK_SSI1_PIN_SEL) << BIT_SHIFT_SSI1_PIN_SEL) +#define BIT_INVC_SSI1_PIN_SEL (~(BIT_MASK_SSI1_PIN_SEL << BIT_SHIFT_SSI1_PIN_SEL)) + +// SSI2 Pinmux +#define BIT_SHIFT_SSI2_PIN_EN 8 +#define BIT_MASK_SSI2_PIN_EN 0x1 +#define BIT_SSI2_PIN_EN(x)(((x) & BIT_MASK_SSI2_PIN_EN) << BIT_SHIFT_SSI2_PIN_EN) +#define BIT_INVC_SSI2_PIN_EN (~(BIT_MASK_SSI2_PIN_EN << BIT_SHIFT_SSI2_PIN_EN)) + +#define BIT_SHIFT_SSI2_PIN_SEL 9 +#define BIT_MASK_SSI2_PIN_SEL 0x7 +#define BIT_SSI2_PIN_SEL(x)(((x) & BIT_MASK_SSI2_PIN_SEL) << BIT_SHIFT_SSI2_PIN_SEL) +#define BIT_INVC_SSI2_PIN_SEL (~(BIT_MASK_SSI2_PIN_SEL << BIT_SHIFT_SSI2_PIN_SEL)) + +// SSI0 Multiple Chip Selection (Pinmux Select is controlled by BIT_SSI0_PIN_SEL) +#define BIT_SHIFT_SSI0_MULTI_CS_EN 28 +#define BIT_MASK_SSI0_MULTI_CS_EN 0x1 +#define BIT_SSI0_MULTI_CS_EN(x)(((x) & BIT_MASK_SSI0_MULTI_CS_EN) << BIT_SHIFT_SSI0_MULTI_CS_EN) +#define BIT_INVC_SSI0_MULTI_CS_EN (~(BIT_MASK_SSI0_MULTI_CS_EN << BIT_SHIFT_SSI0_MULTI_CS_EN)) + + +#define HAL_SSI_READ32(SsiIndex, addr) \ + HAL_READ32(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr) +#define HAL_SSI_WRITE32(SsiIndex, addr, value) \ + HAL_WRITE32(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr, value) +#define HAL_SSI_READ16(SsiIndex, addr) \ + HAL_READ16(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr) +#define HAL_SSI_WRITE16(SsiIndex, addr, value) \ + HAL_WRITE16(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr, value) +#define HAL_SSI_READ8(SsiIndex, addr) \ + HAL_READ8(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr) +#define HAL_SSI_WRITE8(SsiIndex, addr, value) \ + HAL_WRITE8(SPI0_REG_BASE+ (SsiIndex*SSI_REG_OFF), addr, value) + + +// SSI Pinmux Select +typedef enum _SSI0_PINMUX_SELECT_ { + SSI0_MUX_TO_GPIOE = S0, + SSI0_MUX_TO_GPIOC = S1 +}SSI0_PINMUX_SELECT, *PSSI0_PINMUX_SELECT; + +typedef enum _SSI1_PINMUX_SELECT_ { + SSI1_MUX_TO_GPIOA = S0, + SSI1_MUX_TO_GPIOB = S1, + SSI1_MUX_TO_GPIOD = S2 +}SSI1_PINMUX_SELECT, *PSSI1_PINMUX_SELECT; + +typedef enum _SSI2_PINMUX_SELECT_ { + SSI2_MUX_TO_GPIOG = S0, + SSI2_MUX_TO_GPIOE = S1, + SSI2_MUX_TO_GPIOD = S2 +}SSI2_PINMUX_SELECT, *PSSI2_PINMUX_SELECT; + +typedef enum _SSI0_MULTI_CS_PINMUX_SELECT_ { + SSI0_CS_MUX_TO_GPIOE = S0, + SSI0_CS_MUX_TO_GPIOC = S1 +}SSI0_MULTI_CS_PINMUX_SELECT, *PSSI0_MULTI_CS_PINMUX_SELECT; + +typedef enum _SSI_CTRLR0_TMOD_ { + TMOD_TR = 0, + TMOD_TO = 1, + TMOD_RO = 2, + TMOD_EEPROM_R = 3 +}SSI_CTRLR0_TMOD, *PSSI_CTRLR0_TMOD; + +typedef enum _SSI_CTRLR0_SCPOL_ { + SCPOL_INACTIVE_IS_LOW = 0, + SCPOL_INACTIVE_IS_HIGH = 1 +}SSI_CTRLR0_SCPOL, *PSSI_CTRLR0_SCPOL; + +typedef enum _SSI_CTRLR0_SCPH_ { + SCPH_TOGGLES_IN_MIDDLE = 0, + SCPH_TOGGLES_AT_START = 1 +}SSI_CTRLR0_SCPH, *PSSI_CTRLR0_SCPH; + +typedef enum _SSI_CTRLR0_DFS_ { + DFS_4_BITS = 3, + DFS_5_BITS = 4, + DFS_6_BITS = 5, + DFS_7_BITS = 6, + DFS_8_BITS = 7, + DFS_9_BITS = 8, + DFS_10_BITS = 9, + DFS_11_BITS = 10, + DFS_12_BITS = 11, + DFS_13_BITS = 12, + DFS_14_BITS = 13, + DFS_15_BITS = 14, + DFS_16_BITS = 15, +}SSI_CTRLR0_DFS, *PSSI_CTRLR0_DFS; + +typedef enum _SSI_CTRLR0_CFS_ { + CFS_1_BIT = 0, + CFS_2_BITS = 1, + CFS_3_BITS = 2, + CFS_4_BITS = 3, + CFS_5_BITS = 4, + CFS_6_BITS = 5, + CFS_7_BITS = 6, + CFS_8_BITS = 7, + CFS_9_BITS = 8, + CFS_10_BITS = 9, + CFS_11_BITS = 10, + CFS_12_BITS = 11, + CFS_13_BITS = 12, + CFS_14_BITS = 13, + CFS_15_BITS = 14, + CFS_16_BITS = 15 +}SSI_CTRLR0_CFS, *PSSI_CTRLR0_CFS; + +typedef enum _SSI_CTRLR0_SLV_OE_ { + SLV_TXD_ENABLE = 0, + SLV_TXD_DISABLE = 1 +}SSI_CTRLR0_SLV_OE, *PSSI_CTRLR0_SLV_OE; + +typedef enum _SSI_ROLE_SELECT_ { + SSI_SLAVE = 0, + SSI_MASTER = 1 +}SSI_ROLE_SELECT, *PSSI_ROLE_SELECT; + +typedef enum _SSI_FRAME_FORMAT_ { + FRF_MOTOROLA_SPI = 0, + FRF_TI_SSP = 1, + FRF_NS_MICROWIRE = 2, + FRF_RSVD = 3 +}SSI_FRAME_FORMAT, *PSSI_FRAME_FORMAT; + +typedef enum _SSI_DMACR_ENABLE_ { + SSI_NODMA = 0, + SSI_RXDMA_ENABLE = 1, + SSI_TXDMA_ENABLE = 2, + SSI_TRDMA_ENABLE = 3 +}SSI_DMACR_ENABLE, *PSSI_DMACR_ENABLE; + +typedef enum _SSI_MWCR_HANDSHAKE_ { + MW_HANDSHAKE_DISABLE = 0, + MW_HANDSHAKE_ENABLE = 1 +}SSI_MWCR_HANDSHAKE, *PSSI_MWCR_HANDSHAKE; + +typedef enum _SSI_MWCR_DIRECTION_ { + MW_DIRECTION_SLAVE_TO_MASTER = 0, + MW_DIRECTION_MASTER_TO_SLAVE = 1 +}SSI_MWCR_DIRECTION, *PSSI_MWCR_DIRECTION; + +typedef enum _SSI_MWCR_TMOD_ { + MW_TMOD_NONSEQUENTIAL = 0, + MW_TMOD_SEQUENTIAL = 1 +}SSI_MWCR_TMOD, *PSSI_MWCR_TMOD; + +typedef enum _SSI_DATA_TRANSFER_MECHANISM_ { + SSI_DTM_BASIC, + SSI_DTM_INTERRUPT, + SSI_DTM_DMA +}SSI_DATA_TRANSFER_MECHANISM, *PSSI_DATA_TRANSFER_MECHANISM; + + +_LONG_CALL_ HAL_Status HalSsiPinmuxEnableRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ HAL_Status HalSsiEnableRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ HAL_Status HalSsiDisableRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiInitRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiSetSclkPolarityRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiSetSclkPhaseRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiWriteRtl8195a(VOID *Adaptor, u32 value); +_LONG_CALL_ HAL_Status HalSsiLoadSettingRtl8195a(VOID *Adaptor, VOID *Setting); +_LONG_CALL_ROM_ HAL_Status HalSsiSetInterruptMaskRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiSetDeviceRoleRtl8195a(VOID *Adaptor, u32 Role); +_LONG_CALL_ HAL_Status HalSsiInterruptEnableRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiInterruptDisableRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiReadInterruptRtl8195a(VOID *Adaptor, VOID *RxData, u32 Length); +_LONG_CALL_ROM_ HAL_Status HalSsiSetRxFifoThresholdLevelRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiSetTxFifoThresholdLevelRtl8195a(VOID *Adaptor); +_LONG_CALL_ HAL_Status HalSsiWriteInterruptRtl8195a(VOID *Adaptor, VOID *TxData, u32 Length); +_LONG_CALL_ROM_ HAL_Status HalSsiSetSlaveEnableRegisterRtl8195a(VOID *Adaptor, u32 SlaveIndex); +_LONG_CALL_ROM_ u32 HalSsiBusyRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiWriteableRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiReadableRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiGetInterruptMaskRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiGetRxFifoLevelRtl8195a(VOID *Adaptor); +_LONG_CALL_ u32 HalSsiGetTxFifoLevelRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiGetStatusRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiGetInterruptStatusRtl8195a(VOID *Adaptor); +_LONG_CALL_ u32 HalSsiReadRtl8195a(VOID *Adaptor); +_LONG_CALL_ u32 HalSsiGetRawInterruptStatusRtl8195a(VOID *Adaptor); +_LONG_CALL_ROM_ u32 HalSsiGetSlaveEnableRegisterRtl8195a(VOID *Adaptor); + +_LONG_CALL_ROM_ VOID _SsiReadInterrupt(VOID *Adaptor); +_LONG_CALL_ROM_ VOID _SsiWriteInterrupt(VOID *Adaptor); +_LONG_CALL_ u32 _SsiIrqHandle(VOID *Adaptor); + +// ROM code patch +VOID _SsiReadInterruptRtl8195a(VOID *Adapter); +VOID _SsiWriteInterruptRtl8195a(VOID *Adapter); +HAL_Status HalSsiInitRtl8195a_Patch(VOID *Adaptor); +HAL_Status HalSsiPinmuxEnableRtl8195a_Patch(VOID *Adaptor); +HAL_Status HalSsiPinmuxDisableRtl8195a(VOID *Adaptor); +HAL_Status HalSsiDeInitRtl8195a(VOID * Adapter); +HAL_Status HalSsiClockOffRtl8195a(VOID * Adapter); +HAL_Status HalSsiClockOnRtl8195a(VOID * Adapter); +VOID HalSsiSetSclkRtl8195a(VOID *Adapter, u32 ClkRate); +HAL_Status HalSsiIntReadRtl8195a(VOID *Adapter, VOID *RxData, u32 Length); +HAL_Status HalSsiIntWriteRtl8195a(VOID *Adapter, u8 *pTxData, u32 Length); +VOID HalSsiTxFIFOThresholdRtl8195a(VOID *Adaptor, u32 txftl); +HAL_Status HalSsiEnterCriticalRtl8195a(VOID * Data); +HAL_Status HalSsiExitCriticalRtl8195a(VOID * Data); +HAL_Status HalSsiIsTimeoutRtl8195a(u32 StartCount, u32 TimeoutCnt); +HAL_Status HalSsiStopRecvRtl8195a(VOID * Data); + +#if CONFIG_CHIP_E_CUT +HAL_Status HalSsiPinmuxEnableRtl8195a_V04(VOID *Adaptor); +HAL_Status HalSsiPinmuxDisableRtl8195a_V04(VOID * Adaptor); +VOID _SsiReadInterruptRtl8195a_V04(VOID *Adapter); +VOID _SsiWriteInterruptRtl8195a_V04(VOID *Adapter); +HAL_Status HalSsiInitRtl8195a_V04(VOID *Adaptor); +HAL_Status HalSsiSetFormatRtl8195a_V04(VOID * Adaptor); +HAL_Status HalSsiDeInitRtl8195a_V04(VOID *Adapter); +HAL_Status HalSsiIntReadRtl8195a_V04(VOID *Adapter, VOID *RxData, u32 Length); +HAL_Status HalSsiIntWriteRtl8195a_V04(VOID *Adapter, u8 *pTxData, u32 Length); +HAL_Status HalSsiClockOffRtl8195a_V04(VOID * Adapter); +HAL_Status HalSsiClockOnRtl8195a_V04(VOID * Adapter); +VOID HalSsiSetSclkRtl8195a_V04(VOID *Adapter, u32 ClkRate); +VOID HalSsiTxGdmaLoadDefRtl8195a_V04(IN VOID * Adapter); +VOID HalSsiRxGdmaLoadDefRtl8195a_V04(IN VOID * Adapter); +VOID HalSsiDmaInitRtl8195a_V04(VOID *Adapter); +HAL_Status HalSsiDmaSendRtl8195a_V04(IN VOID * Adapter, IN u8 * pTxData, IN u32 Length); +HAL_Status HalSsiDmaRecvRtl8195a_V04(IN VOID * Adapter, IN u8 * pRxData, IN u32 Length); +HAL_Status HalSsiDmaSendMultiBlockRtl8195a_V04(VOID * Adapter, u8 * pTxData, u32 Length); +HAL_Status HalSsiDmaRecvMultiBlockRtl8195a_V04(VOID * Adapter, u8 * pRxData, u32 Length); + +#endif + +#ifdef CONFIG_GDMA_EN +VOID HalSsiTxGdmaLoadDefRtl8195a(VOID *Adapter); +VOID HalSsiRxGdmaLoadDefRtl8195a(VOID *Adapter); +VOID HalSsiDmaInitRtl8195a(VOID *Adapter); +HAL_Status HalSsiDmaSendRtl8195a(VOID *Adapter, u8 *pTxData, u32 Length); +HAL_Status HalSsiDmaRecvRtl8195a(VOID *Adapter, u8 *pRxData, u32 Length); +HAL_Status HalSsiDmaSendMultiBlockRtl8195a(VOID * Adapter, u8 * pRxData, u32 Length); +HAL_Status HalSsiDmaRecvMultiBlockRtl8195a(VOID * Adapter, u8 * pRxData, u32 Length); + +#endif // end of "#ifdef CONFIG_GDMA_EN" + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sys_on.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sys_on.h new file mode 100644 index 0000000..236c0bc --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_sys_on.h @@ -0,0 +1,1099 @@ +#ifndef __INC_RTL8195A_SYS_ON_BIT_H +#define __INC_RTL8195A_SYS_ON_BIT_H + +#define HAL_SYS_CTRL_READ32(addr) HAL_READ32(SYSTEM_CTRL_BASE, addr) +#define HAL_SYS_CTRL_WRITE32(addr, value) HAL_WRITE32(SYSTEM_CTRL_BASE, addr, value) + +#define CPU_OPT_WIDTH 0x1F + +//2 REG_NOT_VALID + +//2 REG_SYS_PWR_CTRL + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SYS_PWR_SOC_EN BIT(2) +#define BIT_SYS_PWR_RET_MEM_EN BIT(1) +#define BIT_SYS_PWR_PEON_EN BIT(0) + +//2 REG_SYS_ISO_CTRL + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SYS_ISO_SYSPLL BIT(7) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SYS_ISO_SOC BIT(2) +#define BIT_SYS_ISO_RET_MEM BIT(1) +#define BIT_SYS_ISO_PEON BIT(0) + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SYS_FUNC_EN +#define BIT_SYS_AMACRO_EN BIT(31) +#define BIT_SYS_PWRON_TRAP_SHTDN_N BIT(30) +#define BIT_SYS_FEN_SIC_MST BIT(25) +#define BIT_SYS_FEN_SIC BIT(24) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SOC_SYSPEON_EN BIT(4) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SYS_FEN_EELDR BIT(0) + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SYS_CLK_CTRL0 + +//2 REG_NOT_VALID +#define BIT_SOC_OCP_IOBUS_CK_EN BIT(2) +#define BIT_SYSON_CK_EELDR_EN BIT(1) +#define BIT_SYSON_CK_SYSREG_EN BIT(0) + +//2 REG_SYS_CLK_CTRL1 + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +#define BIT_SHIFT_PESOC_OCP_CPU_CK_SEL 4 +#define BIT_MASK_PESOC_OCP_CPU_CK_SEL 0x7 +#define BIT_PESOC_OCP_CPU_CK_SEL(x) (((x) & BIT_MASK_PESOC_OCP_CPU_CK_SEL) << BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) + + +//2 REG_NOT_VALID +#define BIT_PESOC_EELDR_CK_SEL BIT(0) + +//2 REG_SYS_SWR_CTRL3 + +//2 REG_RSV_CTRL + +//2 REG_RF_CTRL + +//2 REG_SYS_EFUSE_SYSCFG0 + +#define BIT_SHIFT_SYS_EEROM_SWR_PAR_05_00 24 +#define BIT_MASK_SYS_EEROM_SWR_PAR_05_00 0x3f +#define BIT_SYS_EEROM_SWR_PAR_05_00(x) (((x) & BIT_MASK_SYS_EEROM_SWR_PAR_05_00) << BIT_SHIFT_SYS_EEROM_SWR_PAR_05_00) + + +#define BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04 20 +#define BIT_MASK_SYS_EEROM_LDO_PAR_07_04 0xf +#define BIT_SYS_EEROM_LDO_PAR_07_04(x) (((x) & BIT_MASK_SYS_EEROM_LDO_PAR_07_04) << BIT_SHIFT_SYS_EEROM_LDO_PAR_07_04) + +#define BIT_SYS_CHIPPDN_EN BIT(17) +#define BIT_SYS_EEROM_B12V_EN BIT(16) + +#define BIT_SHIFT_SYS_EEROM_VID1 8 +#define BIT_MASK_SYS_EEROM_VID1 0xff +#define BIT_SYS_EEROM_VID1(x) (((x) & BIT_MASK_SYS_EEROM_VID1) << BIT_SHIFT_SYS_EEROM_VID1) + + +#define BIT_SHIFT_SYS_EEROM_VID0 0 +#define BIT_MASK_SYS_EEROM_VID0 0xff +#define BIT_SYS_EEROM_VID0(x) (((x) & BIT_MASK_SYS_EEROM_VID0) << BIT_SHIFT_SYS_EEROM_VID0) + + +//2 REG_SYS_EFUSE_SYSCFG1 + +#define BIT_SHIFT_SYS_PDSPL_STL 24 +#define BIT_MASK_SYS_PDSPL_STL 0x3 +#define BIT_SYS_PDSPL_STL(x) (((x) & BIT_MASK_SYS_PDSPL_STL) << BIT_SHIFT_SYS_PDSPL_STL) + + +#define BIT_SHIFT_SYS_PDSOC_STL 22 +#define BIT_MASK_SYS_PDSOC_STL 0x3 +#define BIT_SYS_PDSOC_STL(x) (((x) & BIT_MASK_SYS_PDSOC_STL) << BIT_SHIFT_SYS_PDSOC_STL) + + +#define BIT_SHIFT_SYS_PDPON_STL 20 +#define BIT_MASK_SYS_PDPON_STL 0x3 +#define BIT_SYS_PDPON_STL(x) (((x) & BIT_MASK_SYS_PDPON_STL) << BIT_SHIFT_SYS_PDPON_STL) + + +#define BIT_SHIFT_SYS_SWREG_XRT 18 +#define BIT_MASK_SYS_SWREG_XRT 0x3 +#define BIT_SYS_SWREG_XRT(x) (((x) & BIT_MASK_SYS_SWREG_XRT) << BIT_SHIFT_SYS_SWREG_XRT) + + +#define BIT_SHIFT_SYS_SWSLC_STL 16 +#define BIT_MASK_SYS_SWSLC_STL 0x3 +#define BIT_SYS_SWSLC_STL(x) (((x) & BIT_MASK_SYS_SWSLC_STL) << BIT_SHIFT_SYS_SWSLC_STL) + + +#define BIT_SHIFT_SYS_EEROM_SWR_PAR_46_45 14 +#define BIT_MASK_SYS_EEROM_SWR_PAR_46_45 0x3 +#define BIT_SYS_EEROM_SWR_PAR_46_45(x) (((x) & BIT_MASK_SYS_EEROM_SWR_PAR_46_45) << BIT_SHIFT_SYS_EEROM_SWR_PAR_46_45) + + +#define BIT_SHIFT_SYS_EEROM_SWR_PAR_40_39 12 +#define BIT_MASK_SYS_EEROM_SWR_PAR_40_39 0x3 +#define BIT_SYS_EEROM_SWR_PAR_40_39(x) (((x) & BIT_MASK_SYS_EEROM_SWR_PAR_40_39) << BIT_SHIFT_SYS_EEROM_SWR_PAR_40_39) + + +#define BIT_SHIFT_SYS_EEROM_SWR_PAR_33_26 4 +#define BIT_MASK_SYS_EEROM_SWR_PAR_33_26 0xff +#define BIT_SYS_EEROM_SWR_PAR_33_26(x) (((x) & BIT_MASK_SYS_EEROM_SWR_PAR_33_26) << BIT_SHIFT_SYS_EEROM_SWR_PAR_33_26) + + +#define BIT_SHIFT_SYS_EEROM_SWSLD_VOL 0 +#define BIT_MASK_SYS_EEROM_SWSLD_VOL 0x7 +#define BIT_SYS_EEROM_SWSLD_VOL(x) (((x) & BIT_MASK_SYS_EEROM_SWSLD_VOL) << BIT_SHIFT_SYS_EEROM_SWSLD_VOL) + + +//2 REG_SYS_EFUSE_SYSCFG2 + +#define BIT_SHIFT_SYS_EERROM_ANAPAR_SPLL_24_15 21 +#define BIT_MASK_SYS_EERROM_ANAPAR_SPLL_24_15 0x3ff +#define BIT_SYS_EERROM_ANAPAR_SPLL_24_15(x) (((x) & BIT_MASK_SYS_EERROM_ANAPAR_SPLL_24_15) << BIT_SHIFT_SYS_EERROM_ANAPAR_SPLL_24_15) + + +#define BIT_SHIFT_SYS_EEROM_ANAPAR_SPLL_05_02 16 +#define BIT_MASK_SYS_EEROM_ANAPAR_SPLL_05_02 0xf +#define BIT_SYS_EEROM_ANAPAR_SPLL_05_02(x) (((x) & BIT_MASK_SYS_EEROM_ANAPAR_SPLL_05_02) << BIT_SHIFT_SYS_EEROM_ANAPAR_SPLL_05_02) + + +#define BIT_SHIFT_SYS_EEROM_XTAL_STEL_SEL 12 +#define BIT_MASK_SYS_EEROM_XTAL_STEL_SEL 0x3 +#define BIT_SYS_EEROM_XTAL_STEL_SEL(x) (((x) & BIT_MASK_SYS_EEROM_XTAL_STEL_SEL) << BIT_SHIFT_SYS_EEROM_XTAL_STEL_SEL) + + +#define BIT_SHIFT_SYS_EEROM_XTAL_FREQ_SEL 8 +#define BIT_MASK_SYS_EEROM_XTAL_FREQ_SEL 0xf +#define BIT_SYS_EEROM_XTAL_FREQ_SEL(x) (((x) & BIT_MASK_SYS_EEROM_XTAL_FREQ_SEL) << BIT_SHIFT_SYS_EEROM_XTAL_FREQ_SEL) + + +//2 REG_SYS_EFUSE_SYSCFG3 + +#define BIT_SHIFT_SYS_DBG_PINGP_EN 28 +#define BIT_MASK_SYS_DBG_PINGP_EN 0xf +#define BIT_SYS_DBG_PINGP_EN(x) (((x) & BIT_MASK_SYS_DBG_PINGP_EN) << BIT_SHIFT_SYS_DBG_PINGP_EN) + + +#define BIT_SHIFT_SYS_DBG_SEL 16 +#define BIT_MASK_SYS_DBG_SEL 0xfff +#define BIT_SYS_DBG_SEL(x) (((x) & BIT_MASK_SYS_DBG_SEL) << BIT_SHIFT_SYS_DBG_SEL) + + +#define BIT_SHIFT_SYS_DBGBY3_LOC_SEL 14 +#define BIT_MASK_SYS_DBGBY3_LOC_SEL 0x3 +#define BIT_SYS_DBGBY3_LOC_SEL(x) (((x) & BIT_MASK_SYS_DBGBY3_LOC_SEL) << BIT_SHIFT_SYS_DBGBY3_LOC_SEL) + + +#define BIT_SHIFT_SYS_DBGBY2_LOC_SEL 12 +#define BIT_MASK_SYS_DBGBY2_LOC_SEL 0x3 +#define BIT_SYS_DBGBY2_LOC_SEL(x) (((x) & BIT_MASK_SYS_DBGBY2_LOC_SEL) << BIT_SHIFT_SYS_DBGBY2_LOC_SEL) + + +#define BIT_SHIFT_SYS_DBGBY1_LOC_SEL 10 +#define BIT_MASK_SYS_DBGBY1_LOC_SEL 0x3 +#define BIT_SYS_DBGBY1_LOC_SEL(x) (((x) & BIT_MASK_SYS_DBGBY1_LOC_SEL) << BIT_SHIFT_SYS_DBGBY1_LOC_SEL) + + +#define BIT_SHIFT_SYS_DBGBY0_LOC_SEL 8 +#define BIT_MASK_SYS_DBGBY0_LOC_SEL 0x3 +#define BIT_SYS_DBGBY0_LOC_SEL(x) (((x) & BIT_MASK_SYS_DBGBY0_LOC_SEL) << BIT_SHIFT_SYS_DBGBY0_LOC_SEL) + +#define BIT_SYS_EEROM_ANAPAR_SPLL_49 BIT(3) + +#define BIT_SHIFT_SYS_EEROM_ANAPAR_SPLL_27_25 0 +#define BIT_MASK_SYS_EEROM_ANAPAR_SPLL_27_25 0x7 +#define BIT_SYS_EEROM_ANAPAR_SPLL_27_25(x) (((x) & BIT_MASK_SYS_EEROM_ANAPAR_SPLL_27_25) << BIT_SHIFT_SYS_EEROM_ANAPAR_SPLL_27_25) + + +//2 REG_SYS_EFUSE_SYSCFG4 + +#define BIT_SHIFT_SYS_GPIOA_E2 1 +#define BIT_MASK_SYS_GPIOA_E2 0x7 +#define BIT_SYS_GPIOA_E2(x) (((x) & BIT_MASK_SYS_GPIOA_E2) << BIT_SHIFT_SYS_GPIOA_E2) + +#define BIT_SYS_GPIOA_H3L1 BIT(0) + +//2 REG_SYS_EFUSE_SYSCFG5 + +//2 REG_NOT_VALID + +//2 REG_SYS_EFUSE_SYSCFG6 + +#define BIT_SHIFT_SYS_SPIC_INIT_BAUD_RATE_SEL 26 +#define BIT_MASK_SYS_SPIC_INIT_BAUD_RATE_SEL 0x3 +#define BIT_SYS_SPIC_INIT_BAUD_RATE_SEL(x) (((x) & BIT_MASK_SYS_SPIC_INIT_BAUD_RATE_SEL) << BIT_SHIFT_SYS_SPIC_INIT_BAUD_RATE_SEL) + + +#define BIT_SHIFT_SYS_CPU_CLK_SEL 24 +#define BIT_MASK_SYS_CPU_CLK_SEL 0x3 +#define BIT_SYS_CPU_CLK_SEL(x) (((x) & BIT_MASK_SYS_CPU_CLK_SEL) << BIT_SHIFT_SYS_CPU_CLK_SEL) + + +//2 REG_SYS_EFUSE_SYSCFG7 +#define BIT_SYS_MEM_RMV_SIGN BIT(31) +#define BIT_SYS_MEM_RMV_1PRF1 BIT(29) +#define BIT_SYS_MEM_RMV_1PRF0 BIT(28) +#define BIT_SYS_MEM_RMV_1PSR BIT(27) +#define BIT_SYS_MEM_RMV_1PHSR BIT(26) +#define BIT_SYS_MEM_RMV_ROM BIT(25) + +#define BIT_SHIFT_SYS_MEM_RME_CPU 22 +#define BIT_MASK_SYS_MEM_RME_CPU 0x7 +#define BIT_SYS_MEM_RME_CPU(x) (((x) & BIT_MASK_SYS_MEM_RME_CPU) << BIT_SHIFT_SYS_MEM_RME_CPU) + + +#define BIT_SHIFT_SYS_MEM_RME_WLAN 19 +#define BIT_MASK_SYS_MEM_RME_WLAN 0x7 +#define BIT_SYS_MEM_RME_WLAN(x) (((x) & BIT_MASK_SYS_MEM_RME_WLAN) << BIT_SHIFT_SYS_MEM_RME_WLAN) + +#define BIT_SYS_MEM_RME_USB BIT(18) +#define BIT_SYS_MEM_RME_SDIO BIT(17) + +//2 REG_SYS_REGU_CTRL0 + +#define BIT_SHIFT_SYS_REGU_LDO25M_ADJ 20 +#define BIT_MASK_SYS_REGU_LDO25M_ADJ 0xf +#define BIT_SYS_REGU_LDO25M_ADJ(x) (((x) & BIT_MASK_SYS_REGU_LDO25M_ADJ) << BIT_SHIFT_SYS_REGU_LDO25M_ADJ) + +#define BIT_SYS_REGU_ANACK_4M_EN BIT(19) +#define BIT_SYS_REGU_ANACK_4M_SEL BIT(18) +#define BIT_SYS_REGU_PC_EF_EN BIT(17) +#define BIT_SYS_REGU_LDOH12_SLP_EN BIT(16) + +#define BIT_SHIFT_SYS_REGU_LDOH12_ADJ 12 +#define BIT_MASK_SYS_REGU_LDOH12_ADJ 0xf +#define BIT_SYS_REGU_LDOH12_ADJ(x) (((x) & BIT_MASK_SYS_REGU_LDOH12_ADJ) << BIT_SHIFT_SYS_REGU_LDOH12_ADJ) + + +#define BIT_SHIFT_SYS_REGU_LDO25E_ADJ 8 +#define BIT_MASK_SYS_REGU_LDO25E_ADJ 0xf +#define BIT_SYS_REGU_LDO25E_ADJ(x) (((x) & BIT_MASK_SYS_REGU_LDO25E_ADJ) << BIT_SHIFT_SYS_REGU_LDO25E_ADJ) + +#define BIT_SYS_REGU_DSLEPM_EN BIT(7) +#define BIT_SYS_REGU_PC_33V_EN BIT(3) +#define BIT_SYS_REGU_PC_EF25_EN BIT(2) +#define BIT_SYS_REGU_LDO25M_EN BIT(1) +#define BIT_SYS_REGU_LDO25E_EN BIT(0) + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SYS_SWR_CTRL0 + +#define BIT_SHIFT_SYS_SWR12_COMP_R2 30 +#define BIT_MASK_SYS_SWR12_COMP_R2 0x3 +#define BIT_SYS_SWR12_COMP_R2(x) (((x) & BIT_MASK_SYS_SWR12_COMP_R2) << BIT_SHIFT_SYS_SWR12_COMP_R2) + + +#define BIT_SHIFT_SYS_SWR12_COMP_R1 28 +#define BIT_MASK_SYS_SWR12_COMP_R1 0x3 +#define BIT_SYS_SWR12_COMP_R1(x) (((x) & BIT_MASK_SYS_SWR12_COMP_R1) << BIT_SHIFT_SYS_SWR12_COMP_R1) + + +#define BIT_SHIFT_SYS_SWR12_COMP_C3 26 +#define BIT_MASK_SYS_SWR12_COMP_C3 0x3 +#define BIT_SYS_SWR12_COMP_C3(x) (((x) & BIT_MASK_SYS_SWR12_COMP_C3) << BIT_SHIFT_SYS_SWR12_COMP_C3) + + +#define BIT_SHIFT_SYS_SWR12_COMP_C2 24 +#define BIT_MASK_SYS_SWR12_COMP_C2 0x3 +#define BIT_SYS_SWR12_COMP_C2(x) (((x) & BIT_MASK_SYS_SWR12_COMP_C2) << BIT_SHIFT_SYS_SWR12_COMP_C2) + + +#define BIT_SHIFT_SYS_SWR12_COMP_C1 22 +#define BIT_MASK_SYS_SWR12_COMP_C1 0x3 +#define BIT_SYS_SWR12_COMP_C1(x) (((x) & BIT_MASK_SYS_SWR12_COMP_C1) << BIT_SHIFT_SYS_SWR12_COMP_C1) + +#define BIT_SYS_SWR12_COMP_TYPE_L BIT(21) +#define BIT_SYS_SWR12_FPWM_MD BIT(20) + +#define BIT_SHIFT_SYS_SPSLDO_VOL 17 +#define BIT_MASK_SYS_SPSLDO_VOL 0x7 +#define BIT_SYS_SPSLDO_VOL(x) (((x) & BIT_MASK_SYS_SPSLDO_VOL) << BIT_SHIFT_SYS_SPSLDO_VOL) + + +#define BIT_SHIFT_SYS_SWR12_IN 14 +#define BIT_MASK_SYS_SWR12_IN 0x7 +#define BIT_SYS_SWR12_IN(x) (((x) & BIT_MASK_SYS_SWR12_IN) << BIT_SHIFT_SYS_SWR12_IN) + + +#define BIT_SHIFT_SYS_SWR12_STD 12 +#define BIT_MASK_SYS_SWR12_STD 0x3 +#define BIT_SYS_SWR12_STD(x) (((x) & BIT_MASK_SYS_SWR12_STD) << BIT_SHIFT_SYS_SWR12_STD) + + +#define BIT_SHIFT_SYS_SWR12_VOL 8 +#define BIT_MASK_SYS_SWR12_VOL 0xf +#define BIT_SYS_SWR12_VOL(x) (((x) & BIT_MASK_SYS_SWR12_VOL) << BIT_SHIFT_SYS_SWR12_VOL) + + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID +#define BIT_SYS_SWR_EN BIT(1) +#define BIT_SYS_SWR_LDO_EN BIT(0) + +//2 REG_SYS_SWR_CTRL1 +#define BIT_SYS_SW12_PFM_SEL BIT(25) +#define BIT_SYS_SW12_AUTO_ZCD_L BIT(24) +#define BIT_SYS_SW12_AUTO_MODE BIT(23) +#define BIT_SYS_SW12_LDOF_L BIT(22) +#define BIT_SYS_SW12_OCPS_L BIT(21) + +#define BIT_SHIFT_SYS_SW12_TBOX 17 +#define BIT_MASK_SYS_SW12_TBOX 0x3 +#define BIT_SYS_SW12_TBOX(x) (((x) & BIT_MASK_SYS_SW12_TBOX) << BIT_SHIFT_SYS_SW12_TBOX) + + +#define BIT_SHIFT_SYS_SW12_NONOVRLAP_DLY 15 +#define BIT_MASK_SYS_SW12_NONOVRLAP_DLY 0x3 +#define BIT_SYS_SW12_NONOVRLAP_DLY(x) (((x) & BIT_MASK_SYS_SW12_NONOVRLAP_DLY) << BIT_SHIFT_SYS_SW12_NONOVRLAP_DLY) + +#define BIT_SYS_SW12_CLAMP_DUTY BIT(14) +#define BIT_SYS_SWR12_BYPASS_SSR BIT(13) +#define BIT_SYS_SWR12_ZCDOUT_EN BIT(12) +#define BIT_SYS_SWR12_POW_ZCD BIT(11) +#define BIT_SYS_SW12_AREN BIT(10) + +#define BIT_SHIFT_SYS_SWR12_OCP_CUR 7 +#define BIT_MASK_SYS_SWR12_OCP_CUR 0x7 +#define BIT_SYS_SWR12_OCP_CUR(x) (((x) & BIT_MASK_SYS_SWR12_OCP_CUR) << BIT_SHIFT_SYS_SWR12_OCP_CUR) + +#define BIT_SYS_SWR12_OCP_EN BIT(6) + +#define BIT_SHIFT_SYS_SWR12_SAWTOOTH_CF_L 4 +#define BIT_MASK_SYS_SWR12_SAWTOOTH_CF_L 0x3 +#define BIT_SYS_SWR12_SAWTOOTH_CF_L(x) (((x) & BIT_MASK_SYS_SWR12_SAWTOOTH_CF_L) << BIT_SHIFT_SYS_SWR12_SAWTOOTH_CF_L) + + +#define BIT_SHIFT_SYS_SWR12_SAWTOOTH_CFC_L 2 +#define BIT_MASK_SYS_SWR12_SAWTOOTH_CFC_L 0x3 +#define BIT_SYS_SWR12_SAWTOOTH_CFC_L(x) (((x) & BIT_MASK_SYS_SWR12_SAWTOOTH_CFC_L) << BIT_SHIFT_SYS_SWR12_SAWTOOTH_CFC_L) + + +#define BIT_SHIFT_SYS_SWR12_COMP_R3 0 +#define BIT_MASK_SYS_SWR12_COMP_R3 0x3 +#define BIT_SYS_SWR12_COMP_R3(x) (((x) & BIT_MASK_SYS_SWR12_COMP_R3) << BIT_SHIFT_SYS_SWR12_COMP_R3) + + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_SYS_XTAL_CTRL0 +#define BIT_SYS_XTAL_XQSEL BIT(31) +#define BIT_SYS_XTAL_XQSEL_RF BIT(30) + +#define BIT_SHIFT_SYS_XTAL_SC_XO 24 +#define BIT_MASK_SYS_XTAL_SC_XO 0x3f +#define BIT_SYS_XTAL_SC_XO(x) (((x) & BIT_MASK_SYS_XTAL_SC_XO) << BIT_SHIFT_SYS_XTAL_SC_XO) + + +#define BIT_SHIFT_SYS_XTAL_SC_XI 18 +#define BIT_MASK_SYS_XTAL_SC_XI 0x3f +#define BIT_SYS_XTAL_SC_XI(x) (((x) & BIT_MASK_SYS_XTAL_SC_XI) << BIT_SHIFT_SYS_XTAL_SC_XI) + + +#define BIT_SHIFT_SYS_XTAL_GMN 13 +#define BIT_MASK_SYS_XTAL_GMN 0x1f +#define BIT_SYS_XTAL_GMN(x) (((x) & BIT_MASK_SYS_XTAL_GMN) << BIT_SHIFT_SYS_XTAL_GMN) + + +#define BIT_SHIFT_SYS_XTAL_GMP 8 +#define BIT_MASK_SYS_XTAL_GMP 0x1f +#define BIT_SYS_XTAL_GMP(x) (((x) & BIT_MASK_SYS_XTAL_GMP) << BIT_SHIFT_SYS_XTAL_GMP) + +#define BIT_SYS_XTAL_EN BIT(1) +#define BIT_SYS_XTAL_BGMB_EN BIT(0) + +//2 REG_SYS_XTAL_CTRL1 + +#define BIT_SHIFT_SYS_XTAL_COUNTER_MUX 25 +#define BIT_MASK_SYS_XTAL_COUNTER_MUX 0x3 +#define BIT_SYS_XTAL_COUNTER_MUX(x) (((x) & BIT_MASK_SYS_XTAL_COUNTER_MUX) << BIT_SHIFT_SYS_XTAL_COUNTER_MUX) + +#define BIT_SYS_XTAL_DELAY_SYSPLL BIT(24) +#define BIT_SYS_XTAL_DELAY_USB BIT(23) +#define BIT_SYS_XTAL_DELAY_WLAFE BIT(22) +#define BIT_SYS_XTAL_AGPIO_SEL BIT(21) + +#define BIT_SHIFT_SYS_XTAL_DRV_AGPIO 19 +#define BIT_MASK_SYS_XTAL_DRV_AGPIO 0x3 +#define BIT_SYS_XTAL_DRV_AGPIO(x) (((x) & BIT_MASK_SYS_XTAL_DRV_AGPIO) << BIT_SHIFT_SYS_XTAL_DRV_AGPIO) + + +#define BIT_SHIFT_SYS_XTAL_AGPIO 16 +#define BIT_MASK_SYS_XTAL_AGPIO 0x7 +#define BIT_SYS_XTAL_AGPIO(x) (((x) & BIT_MASK_SYS_XTAL_AGPIO) << BIT_SHIFT_SYS_XTAL_AGPIO) + + +#define BIT_SHIFT_SYS_XTAL_DRV_SYSPLL 14 +#define BIT_MASK_SYS_XTAL_DRV_SYSPLL 0x3 +#define BIT_SYS_XTAL_DRV_SYSPLL(x) (((x) & BIT_MASK_SYS_XTAL_DRV_SYSPLL) << BIT_SHIFT_SYS_XTAL_DRV_SYSPLL) + +#define BIT_SYS_XTAL_GATE_SYSPLL BIT(13) + +#define BIT_SHIFT_SYS_XTAL_DRV_USB 11 +#define BIT_MASK_SYS_XTAL_DRV_USB 0x3 +#define BIT_SYS_XTAL_DRV_USB(x) (((x) & BIT_MASK_SYS_XTAL_DRV_USB) << BIT_SHIFT_SYS_XTAL_DRV_USB) + +#define BIT_SYS_XTAL_GATE_USB BIT(10) + +#define BIT_SHIFT_SYS_XTAL_DRV_WLAFE 8 +#define BIT_MASK_SYS_XTAL_DRV_WLAFE 0x3 +#define BIT_SYS_XTAL_DRV_WLAFE(x) (((x) & BIT_MASK_SYS_XTAL_DRV_WLAFE) << BIT_SHIFT_SYS_XTAL_DRV_WLAFE) + +#define BIT_SYS_XTAL_GATE_WLAFE BIT(7) + +#define BIT_SHIFT_SYS_XTAL_DRV_RF2 5 +#define BIT_MASK_SYS_XTAL_DRV_RF2 0x3 +#define BIT_SYS_XTAL_DRV_RF2(x) (((x) & BIT_MASK_SYS_XTAL_DRV_RF2) << BIT_SHIFT_SYS_XTAL_DRV_RF2) + +#define BIT_SYS_XTAL_GATE_RF2 BIT(4) + +#define BIT_SHIFT_SYS_XTAL_DRV_RF1 3 +#define BIT_MASK_SYS_XTAL_DRV_RF1 0x3 +#define BIT_SYS_XTAL_DRV_RF1(x) (((x) & BIT_MASK_SYS_XTAL_DRV_RF1) << BIT_SHIFT_SYS_XTAL_DRV_RF1) + +#define BIT_SYS_XTAL_GATE_RF1 BIT(1) + +#define BIT_SHIFT_SYS_XTAL_LDO 0 +#define BIT_MASK_SYS_XTAL_LDO 0x3 +#define BIT_SYS_XTAL_LDO(x) (((x) & BIT_MASK_SYS_XTAL_LDO) << BIT_SHIFT_SYS_XTAL_LDO) + + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_SYS_SYSPLL_CTRL0 + +#define BIT_SHIFT_SYS_SYSPLL_LPF_R3 29 +#define BIT_MASK_SYS_SYSPLL_LPF_R3 0x7 +#define BIT_SYS_SYSPLL_LPF_R3(x) (((x) & BIT_MASK_SYS_SYSPLL_LPF_R3) << BIT_SHIFT_SYS_SYSPLL_LPF_R3) + + +#define BIT_SHIFT_SYS_SYSPLL_LPF_CS 27 +#define BIT_MASK_SYS_SYSPLL_LPF_CS 0x3 +#define BIT_SYS_SYSPLL_LPF_CS(x) (((x) & BIT_MASK_SYS_SYSPLL_LPF_CS) << BIT_SHIFT_SYS_SYSPLL_LPF_CS) + + +#define BIT_SHIFT_SYS_SYSPLL_LPF_CP 25 +#define BIT_MASK_SYS_SYSPLL_LPF_CP 0x3 +#define BIT_SYS_SYSPLL_LPF_CP(x) (((x) & BIT_MASK_SYS_SYSPLL_LPF_CP) << BIT_SHIFT_SYS_SYSPLL_LPF_CP) + + +#define BIT_SHIFT_SYS_SYSPLL_LPF_C3 23 +#define BIT_MASK_SYS_SYSPLL_LPF_C3 0x3 +#define BIT_SYS_SYSPLL_LPF_C3(x) (((x) & BIT_MASK_SYS_SYSPLL_LPF_C3) << BIT_SHIFT_SYS_SYSPLL_LPF_C3) + +#define BIT_SYS_SYSPLL_WDOG_ENB BIT(22) +#define BIT_SYS_SYSPLL_CKTST_EN BIT(21) + +#define BIT_SHIFT_SYS_SYSPLL_MONCK_SEL 18 +#define BIT_MASK_SYS_SYSPLL_MONCK_SEL 0x7 +#define BIT_SYS_SYSPLL_MONCK_SEL(x) (((x) & BIT_MASK_SYS_SYSPLL_MONCK_SEL) << BIT_SHIFT_SYS_SYSPLL_MONCK_SEL) + + +#define BIT_SHIFT_SYS_SYSPLL_CP_IOFFSET 13 +#define BIT_MASK_SYS_SYSPLL_CP_IOFFSET 0x1f +#define BIT_SYS_SYSPLL_CP_IOFFSET(x) (((x) & BIT_MASK_SYS_SYSPLL_CP_IOFFSET) << BIT_SHIFT_SYS_SYSPLL_CP_IOFFSET) + +#define BIT_SYS_SYSPLL_CP_IDOUBLE BIT(12) + +#define BIT_SHIFT_SYS_SYSPLL_CP_BIAS 9 +#define BIT_MASK_SYS_SYSPLL_CP_BIAS 0x7 +#define BIT_SYS_SYSPLL_CP_BIAS(x) (((x) & BIT_MASK_SYS_SYSPLL_CP_BIAS) << BIT_SHIFT_SYS_SYSPLL_CP_BIAS) + +#define BIT_SYS_SYSPLL_FREF_EDGE BIT(8) +#define BIT_SYS_SYSPLL_EN BIT(1) +#define BIT_SYS_SYSPLL_LVPC_EN BIT(0) + +//2 REG_SYS_SYSPLL_CTRL1 +#define BIT_SYS_SYSPLL_DIV5_3 BIT(17) +#define BIT_SYS_SYSPLL_CK500K_SEL BIT(15) +#define BIT_SYS_SYSPLL_CK200M_EN BIT(14) +#define BIT_SYS_SYSPLL_CKSDR_EN BIT(13) + +#define BIT_SHIFT_SYS_SYSPLL_CKSDR_DIV 11 +#define BIT_MASK_SYS_SYSPLL_CKSDR_DIV 0x3 +#define BIT_SYS_SYSPLL_CKSDR_DIV(x) (((x) & BIT_MASK_SYS_SYSPLL_CKSDR_DIV) << BIT_SHIFT_SYS_SYSPLL_CKSDR_DIV) + +#define BIT_SYS_SYSPLL_CK24P576_EN BIT(9) +#define BIT_SYS_SYSPLL_CK22P5792_EN BIT(8) +#define BIT_SYS_SYSPLL_CK_PS_EN BIT(6) + +#define BIT_SHIFT_SYS_SYSPLL_CK_PS_SEL 3 +#define BIT_MASK_SYS_SYSPLL_CK_PS_SEL 0x7 +#define BIT_SYS_SYSPLL_CK_PS_SEL(x) (((x) & BIT_MASK_SYS_SYSPLL_CK_PS_SEL) << BIT_SHIFT_SYS_SYSPLL_CK_PS_SEL) + + +#define BIT_SHIFT_SYS_SYSPLL_LPF_RS 0 +#define BIT_MASK_SYS_SYSPLL_LPF_RS 0x7 +#define BIT_SYS_SYSPLL_LPF_RS(x) (((x) & BIT_MASK_SYS_SYSPLL_LPF_RS) << BIT_SHIFT_SYS_SYSPLL_LPF_RS) + + +//2 REG_SYS_SYSPLL_CTRL2 + +#define BIT_SHIFT_XTAL_DRV_RF_LATCH 0 +#define BIT_MASK_XTAL_DRV_RF_LATCH 0xffffffffL +#define BIT_XTAL_DRV_RF_LATCH(x) (((x) & BIT_MASK_XTAL_DRV_RF_LATCH) << BIT_SHIFT_XTAL_DRV_RF_LATCH) + +// BIT25 - To release DAC delta sigma clock gating + +//2 REG_RSVD + +//2 REG_RSVD + +#define BIT_SHIFT_PESOC_CPU_OCP_CK_SEL 0 +#define BIT_MASK_PESOC_CPU_OCP_CK_SEL 0x7 +#define BIT_PESOC_CPU_OCP_CK_SEL(x) (((x) & BIT_MASK_PESOC_CPU_OCP_CK_SEL) << BIT_SHIFT_PESOC_CPU_OCP_CK_SEL) + + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_ + +//2 REG_SYS_ANA_TIM_CTRL + +#define BIT_SHIFT_SYS_ANACK_TU_TIME 16 +#define BIT_MASK_SYS_ANACK_TU_TIME 0x3f +#define BIT_SYS_ANACK_TU_TIME(x) (((x) & BIT_MASK_SYS_ANACK_TU_TIME) << BIT_SHIFT_SYS_ANACK_TU_TIME) + +#define BIT_SYS_DSBYCNT_EN BIT(15) + +#define BIT_SHIFT_SYS_DSTDY_TIM_SCAL 8 +#define BIT_MASK_SYS_DSTDY_TIM_SCAL 0xf +#define BIT_SYS_DSTDY_TIM_SCAL(x) (((x) & BIT_MASK_SYS_DSTDY_TIM_SCAL) << BIT_SHIFT_SYS_DSTDY_TIM_SCAL) + + +#define BIT_SHIFT_SYS_DSTBY_TIM_PERIOD 0 +#define BIT_MASK_SYS_DSTBY_TIM_PERIOD 0xff +#define BIT_SYS_DSTBY_TIM_PERIOD(x) (((x) & BIT_MASK_SYS_DSTBY_TIM_PERIOD) << BIT_SHIFT_SYS_DSTBY_TIM_PERIOD) + + +//2 REG_SYS_DSLP_TIM_CTRL + +#define BIT_SHIFT_SYS_REGU_ASIF_EN 24 +#define BIT_MASK_SYS_REGU_ASIF_EN 0xff +#define BIT_SYS_REGU_ASIF_EN(x) (((x) & BIT_MASK_SYS_REGU_ASIF_EN) << BIT_SHIFT_SYS_REGU_ASIF_EN) + + +#define BIT_SHIFT_SYS_REGU_ASIF_THP_DA 20 +#define BIT_MASK_SYS_REGU_ASIF_THP_DA 0x3 +#define BIT_SYS_REGU_ASIF_THP_DA(x) (((x) & BIT_MASK_SYS_REGU_ASIF_THP_DA) << BIT_SHIFT_SYS_REGU_ASIF_THP_DA) + + +#define BIT_SHIFT_SYS_REGU_ASIF_TPD_CK 18 +#define BIT_MASK_SYS_REGU_ASIF_TPD_CK 0x3 +#define BIT_SYS_REGU_ASIF_TPD_CK(x) (((x) & BIT_MASK_SYS_REGU_ASIF_TPD_CK) << BIT_SHIFT_SYS_REGU_ASIF_TPD_CK) + + +#define BIT_SHIFT_SYS_REGU_ASIF_TSP_DA 16 +#define BIT_MASK_SYS_REGU_ASIF_TSP_DA 0x3 +#define BIT_SYS_REGU_ASIF_TSP_DA(x) (((x) & BIT_MASK_SYS_REGU_ASIF_TSP_DA) << BIT_SHIFT_SYS_REGU_ASIF_TSP_DA) + +#define BIT_SYS_REGU_ASIF_POLL BIT(15) +#define BIT_SYS_REGU_ASIF_MODE BIT(14) +#define BIT_SYS_REGU_ASIF_WE BIT(12) + +#define BIT_SHIFT_SYS_REGU_ASIF_AD 8 +#define BIT_MASK_SYS_REGU_ASIF_AD 0xf +#define BIT_SYS_REGU_ASIF_AD(x) (((x) & BIT_MASK_SYS_REGU_ASIF_AD) << BIT_SHIFT_SYS_REGU_ASIF_AD) + + +#define BIT_SHIFT_SYS_REGU_ASIF_WD 0 +#define BIT_MASK_SYS_REGU_ASIF_WD 0xff +#define BIT_SYS_REGU_ASIF_WD(x) (((x) & BIT_MASK_SYS_REGU_ASIF_WD) << BIT_SHIFT_SYS_REGU_ASIF_WD) + + +//2 REG_SYS_DSLP_TIM_CAL_CTRL +#define BIT_SYS_DSLP_TIM_EN BIT(24) + +#define BIT_SHIFT_SYS_DSLP_TIM_PERIOD 0 +#define BIT_MASK_SYS_DSLP_TIM_PERIOD 0x7fffff +#define BIT_SYS_DSLP_TIM_PERIOD(x) (((x) & BIT_MASK_SYS_DSLP_TIM_PERIOD) << BIT_SHIFT_SYS_DSLP_TIM_PERIOD) + + +//2 REG_RSVD + +//2 REG_SYS_DEBUG_CTRL +#define BIT_SYS_DBG_PIN_EN BIT(0) + +//2 REG_SYS_PINMUX_CTRL +#define BIT_EEPROM_PIN_EN BIT(4) +#define BIT_SIC_PIN_EN BIT(0) + +//2 REG_SYS_GPIO_DSTBY_WAKE_CTRL0 +#define BIT_SYS_GPIOE3_WEVENT_STS BIT(27) +#define BIT_SYS_GPIOD5_WEVENT_STS BIT(26) +#define BIT_SYS_GPIOC7_WEVENT_STS BIT(25) +#define BIT_SYS_GPIOA5_WEVENT_STS BIT(24) +#define BIT_SYS_GPIO_GPE3_PULL_CTRL_EN BIT(19) +#define BIT_SYS_GPIO_GPD5_PULL_CTRL_EN BIT(18) +#define BIT_SYS_GPIO_GPC7_PULL_CTRL_EN BIT(17) +#define BIT_SYS_GPIO_GPA5_PULL_CTRL_EN BIT(16) +#define BIT_SYS_GPIOE3_WINT_MODE BIT(11) +#define BIT_SYS_GPIOD5_WINT_MODE BIT(10) +#define BIT_SYS_GPIOC7_WINT_MODE BIT(9) +#define BIT_SYS_GPIOA5_WINT_MODE BIT(8) +#define BIT_SYS_GPIOE3_PIN_EN BIT(3) +#define BIT_SYS_GPIOD5_PIN_EN BIT(2) +#define BIT_SYS_GPIOC7_PIN_EN BIT(1) +#define BIT_SYS_GPIOA5_PIN_EN BIT(0) + +//2 REG_SYS_GPIO_DSTBY_WAKE_CTRL1 +#define BIT_SYS_GPIOE3_SHTDN_N BIT(19) +#define BIT_SYS_GPIOD5_SHTDN_N BIT(18) +#define BIT_SYS_GPIOC7_SHTDN_N BIT(17) +#define BIT_SYS_GPIOA5_SHTDN_N BIT(16) + +#define BIT_SHIFT_SYS_WINT_DEBOUNCE_TIM_SCAL 8 +#define BIT_MASK_SYS_WINT_DEBOUNCE_TIM_SCAL 0x3 +#define BIT_SYS_WINT_DEBOUNCE_TIM_SCAL(x) (((x) & BIT_MASK_SYS_WINT_DEBOUNCE_TIM_SCAL) << BIT_SHIFT_SYS_WINT_DEBOUNCE_TIM_SCAL) + +#define BIT_SYS_GPIOE3_WINT_DEBOUNCE_EN BIT(3) +#define BIT_SYS_GPIOD5_WINT_DEBOUNCE_EN BIT(2) +#define BIT_SYS_GPIOC7_WINT_DEBOUNCE_EN BIT(1) +#define BIT_SYS_GPIOA5_WINT_DEBOUNCE_EN BIT(0) + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SYS_DEBUG_REG + +#define BIT_SHIFT_SYS_DBG_VALUE 0 +#define BIT_MASK_SYS_DBG_VALUE 0xffffffffL +#define BIT_SYS_DBG_VALUE(x) (((x) & BIT_MASK_SYS_DBG_VALUE) << BIT_SHIFT_SYS_DBG_VALUE) + + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_SYS_EEPROM_CTRL0 + +#define BIT_SHIFT_EFUSE_UNLOCK 24 +#define BIT_MASK_EFUSE_UNLOCK 0xff +#define BIT_EFUSE_UNLOCK(x) (((x) & BIT_MASK_EFUSE_UNLOCK) << BIT_SHIFT_EFUSE_UNLOCK) + + +//2 REG_NOT_VALID +#define BIT_SYS_EFUSE_LDALL BIT(16) + +#define BIT_SHIFT_SYS_EEPROM_VPDIDX 8 +#define BIT_MASK_SYS_EEPROM_VPDIDX 0xff +#define BIT_SYS_EEPROM_VPDIDX(x) (((x) & BIT_MASK_SYS_EEPROM_VPDIDX) << BIT_SHIFT_SYS_EEPROM_VPDIDX) + + +#define BIT_SHIFT_SYS_EEPROM_MD 6 +#define BIT_MASK_SYS_EEPROM_MD 0x3 +#define BIT_SYS_EEPROM_MD(x) (((x) & BIT_MASK_SYS_EEPROM_MD) << BIT_SHIFT_SYS_EEPROM_MD) + +#define BIT_SYS_AUTOLOAD_SUS BIT(5) +#define BIT_SYS_EEPROM_SEL BIT(4) +#define BIT_SYS_EEPROM_EECS BIT(3) +#define BIT_SYS_EEPROM_EESK BIT(2) +#define BIT_SYS_EEPROM_EEDI BIT(1) +#define BIT_SYS_EEPROM_EEDO BIT(0) + +//2 REG_SYS_EEPROM_CTRL1 + +#define BIT_SHIFT_SYS_EEPROM_VPD 0 +#define BIT_MASK_SYS_EEPROM_VPD 0xffffffffL +#define BIT_SYS_EEPROM_VPD(x) (((x) & BIT_MASK_SYS_EEPROM_VPD) << BIT_SHIFT_SYS_EEPROM_VPD) + + +//2 REG_SYS_EFUSE_CTRL +#define BIT_SYS_EF_RWFLAG BIT(31) + +#define BIT_SHIFT_SYS_EF_PGPD 28 +#define BIT_MASK_SYS_EF_PGPD 0x7 +#define BIT_SYS_EF_PGPD(x) (((x) & BIT_MASK_SYS_EF_PGPD) << BIT_SHIFT_SYS_EF_PGPD) + + +#define BIT_SHIFT_SYS_EF_RDT 24 +#define BIT_MASK_SYS_EF_RDT 0xf +#define BIT_SYS_EF_RDT(x) (((x) & BIT_MASK_SYS_EF_RDT) << BIT_SHIFT_SYS_EF_RDT) + + +#define BIT_SHIFT_SYS_EF_PGTS 20 +#define BIT_MASK_SYS_EF_PGTS 0xf +#define BIT_SYS_EF_PGTS(x) (((x) & BIT_MASK_SYS_EF_PGTS) << BIT_SHIFT_SYS_EF_PGTS) + +#define BIT_SYS_EF_PDWN BIT(19) +#define BIT_SYS_EF_ALDEN BIT(18) + +#define BIT_SHIFT_SYS_EF_ADDR 8 +#define BIT_MASK_SYS_EF_ADDR 0x3ff +#define BIT_SYS_EF_ADDR(x) (((x) & BIT_MASK_SYS_EF_ADDR) << BIT_SHIFT_SYS_EF_ADDR) + + +#define BIT_SHIFT_SYS_EF_DATA 0 +#define BIT_MASK_SYS_EF_DATA 0xff +#define BIT_SYS_EF_DATA(x) (((x) & BIT_MASK_SYS_EF_DATA) << BIT_SHIFT_SYS_EF_DATA) + + +//2 REG_SYS_EFUSE_TEST +#define BIT_SYS_EF_CRES_SEL BIT(26) + +#define BIT_SHIFT_SYS_EF_SCAN_START 16 +#define BIT_MASK_SYS_EF_SCAN_START 0x1ff +#define BIT_SYS_EF_SCAN_START(x) (((x) & BIT_MASK_SYS_EF_SCAN_START) << BIT_SHIFT_SYS_EF_SCAN_START) + + +#define BIT_SHIFT_SYS_EF_SCAN_END 12 +#define BIT_MASK_SYS_EF_SCAN_END 0xf +#define BIT_SYS_EF_SCAN_END(x) (((x) & BIT_MASK_SYS_EF_SCAN_END) << BIT_SHIFT_SYS_EF_SCAN_END) + +#define BIT_SYS_EF_FORCE_PGMEN BIT(11) + +#define BIT_SHIFT_SYS_EF_CELL_SEL 8 +#define BIT_MASK_SYS_EF_CELL_SEL 0x3 +#define BIT_SYS_EF_CELL_SEL(x) (((x) & BIT_MASK_SYS_EF_CELL_SEL) << BIT_SHIFT_SYS_EF_CELL_SEL) + +#define BIT_SYS_EF_TRPT BIT(7) + +#define BIT_SHIFT_SYS_EF_SCAN_TTHD 0 +#define BIT_MASK_SYS_EF_SCAN_TTHD 0x7f +#define BIT_SYS_EF_SCAN_TTHD(x) (((x) & BIT_MASK_SYS_EF_SCAN_TTHD) << BIT_SHIFT_SYS_EF_SCAN_TTHD) + + +//2 REG_SYS_DSTBY_INFO0 + +//2 REG_NOT_VALID + +//2 REG_SYS_DSTBY_INFO1 + +//2 REG_SYS_DSTBY_INFO2 + +//2 REG_NOT_VALID + +//2 REG_SYS_DSTBY_INFO3 + +//2 REG_SYS_SLP_WAKE_EVENT_MSK0 +#define BIT_SYSON_WEVT_GPIO_DSTBY_MSK BIT(29) +#define BIT_SYSON_WEVT_A33_MSK BIT(28) +#define BIT_SYSON_WEVT_ADC_MSK BIT(26) +#define BIT_SYSON_WEVT_I2C_MSK BIT(24) +#define BIT_SYSON_WEVT_SPI_MSK BIT(22) +#define BIT_SYSON_WEVT_UART_MSK BIT(20) +#define BIT_SYSON_WEVT_USB_MSK BIT(16) +#define BIT_SYSON_WEVT_SDIO_MSK BIT(14) +#define BIT_SYSON_WEVT_NFC_MSK BIT(9) +#define BIT_SYSON_WEVT_WLAN_MSK BIT(8) +#define BIT_SYSON_WEVT_GPIO_MSK BIT(4) +#define BIT_SYSON_WEVT_CHIP_EN_MSK BIT(3) +#define BIT_SYSON_WEVT_OVER_CURRENT_MSK BIT(2) +#define BIT_SYSON_WEVT_GTIM_MSK BIT(1) +#define BIT_SYSON_WEVT_SYSTIM_MSK BIT(0) + +//2 REG_SYS_SLP_WAKE_EVENT_MSK1 + +//2 REG_SYS_SLP_WAKE_EVENT_STATUS0 +#define BIT_SYSON_WEVT_GPIO_DSTBY_STS BIT(29) +#define BIT_SYSON_WEVT_A33_STS BIT(28) +#define BIT_SYSON_WEVT_ADC_STS BIT(26) +#define BIT_SYSON_WEVT_I2C_STS BIT(24) +#define BIT_SYSON_WEVT_SPI_STS BIT(22) +#define BIT_SYSON_WEVT_UART_STS BIT(20) +#define BIT_SYSON_WEVT_USB_STS BIT(16) +#define BIT_SYSON_WEVT_SDIO_STS BIT(14) +#define BIT_SYSON_WEVT_NFC_STS BIT(9) +#define BIT_SYSON_WEVT_WLAN_STS BIT(8) +#define BIT_SYSON_WEVT_GPIO_STS BIT(4) +#define BIT_SYSON_WEVT_CHIP_EN_STS BIT(3) +#define BIT_SYSON_WEVT_OVER_CURRENT_STS BIT(2) +#define BIT_SYSON_WEVT_GTIM_STS BIT(1) +#define BIT_SYSON_WEVT_SYSTIM_STS BIT(0) + +//2 REG_SYS_SLP_WAKE_EVENT_STATUS1 + +//2 REG_SYS_SNF_WAKE_EVENT_MSK0 + +#define BIT_SHIFT_SYS_WKPERI_IMR0 1 +#define BIT_MASK_SYS_WKPERI_IMR0 0x7fffffffL +#define BIT_SYS_WKPERI_IMR0(x) (((x) & BIT_MASK_SYS_WKPERI_IMR0) << BIT_SHIFT_SYS_WKPERI_IMR0) + +#define BIT_SYSON_SNFEVT_ADC_MSK BIT(0) + +//2 REG_SYS_SNF_WAKE_EVENT_STATUS + +#define BIT_SHIFT_SYS_WKPERI_ISR0 1 +#define BIT_MASK_SYS_WKPERI_ISR0 0x7fffffffL +#define BIT_SYS_WKPERI_ISR0(x) (((x) & BIT_MASK_SYS_WKPERI_ISR0) << BIT_SHIFT_SYS_WKPERI_ISR0) + +#define BIT_SYSON_SNFEVT_ADC_STS BIT(0) + +//2 REG_SYS_PWRMGT_CTRL +#define BIT_SYSON_REGU_DSLP BIT(7) + +//2 REG_NOT_VALID +#define BIT_SYSON_PM_CMD_SLP BIT(2) +#define BIT_SYSON_PM_CMD_DSTBY BIT(1) +#define BIT_SYSON_PM_CMD_DSLP BIT(0) + +//2 REG_RSVD + +//2 REG_SYS_PWRMGT_OPTION +#define BIT_SYSON_PMOPT_NORM_SYSCLK_SEL BIT(30) +#define BIT_SYSON_PMOPT_NORM_SYSPLL_EN BIT(29) +#define BIT_SYSON_PMOPT_NORM_XTAL_EN BIT(28) +#define BIT_SYSON_PMOPT_NORM_EN_SOC BIT(27) +#define BIT_SYSON_PMOPT_NORM_EN_PWM BIT(26) +#define BIT_SYSON_PMOPT_NORM_EN_SWR BIT(25) +#define BIT_SYSON_PMOPT_NORM_LPLDO_SEL BIT(24) +#define BIT_SYSON_PMOPT_SNZ_SYSCLK_SEL BIT(22) +#define BIT_SYSON_PMOPT_SNZ_SYSPLL_EN BIT(21) +#define BIT_SYSON_PMOPT_SNZ_XTAL_EN BIT(20) +#define BIT_SYSON_PMOPT_SNZ_EN_SOC BIT(19) +#define BIT_SYSON_PMOPT_SNZ_EN_PWM BIT(18) +#define BIT_SYSON_PMOPT_SNZ_EN_SWR BIT(17) +#define BIT_SYSON_PMOPT_SNZ_LPLDO_SEL BIT(16) +#define BIT_SYSON_PMOPT_SLP_SYSCLK_SEL BIT(14) +#define BIT_SYSON_PMOPT_SLP_SYSPLL_EN BIT(13) +#define BIT_SYSON_PMOPT_SLP_XTAL_EN BIT(12) +#define BIT_SYSON_PMOPT_SLP_EN_SOC BIT(11) +#define BIT_SYSON_PMOPT_SLP_EN_PWM BIT(10) +#define BIT_SYSON_PMOPT_SLP_EN_SWR BIT(9) +#define BIT_SYSON_PMOPT_SLP_LPLDO_SEL BIT(8) +#define BIT_SYSON_PMOPT_DSTBY_SYSCLK_SEL BIT(6) +#define BIT_SYSON_PMOPT_DSTBY_SYSPLL_EN BIT(5) +#define BIT_SYSON_PMOPT_DSTBY_XTAL_EN BIT(4) +#define BIT_SYSON_PMOPT_DSTBY_EN_SOC BIT(3) +#define BIT_SYSON_PMOPT_DSTBY_EN_PWM BIT(2) +#define BIT_SYSON_PMOPT_DSTBY_EN_SWR BIT(1) +#define BIT_SYSON_PMOPT_DSTBY_LPLDO_SEL BIT(0) + +//2 REG_SYS_PWRMGT_OPTION_EXT +#define BIT_SYSON_PMOPT_SLP_ANACK_SEL BIT(2) +#define BIT_SYSON_PMOPT_SLP_ANACK_EN BIT(1) +#define BIT_SYSON_PMOPT_SLP_SWR_ADJ BIT(0) + +//2 REG_SYS_DSLP_WEVENT +#define BIT_SYSON_DSLP_GPIO BIT(2) +#define BIT_SYSON_DSLP_NFC BIT(1) +#define BIT_SYSON_DSLP_WTIMER33 BIT(0) + +//2 REG_SYS_PERI_MONITOR +#define BIT_SYSON_ISO33_NFC BIT(0) + +//2 REG_SYS_SYSTEM_CFG0 +#define BIT_SYSCFG_BD_PKG_SEL BIT(31) + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +#define BIT_SHIFT_VENDOR_ID 8 +#define BIT_MASK_VENDOR_ID 0xf +#define BIT_VENDOR_ID(x) (((x) & BIT_MASK_VENDOR_ID) << BIT_SHIFT_VENDOR_ID) + + +#define BIT_SHIFT_CHIP_VER 4 +#define BIT_MASK_CHIP_VER 0xf +#define BIT_CHIP_VER(x) (((x) & BIT_MASK_CHIP_VER) << BIT_SHIFT_CHIP_VER) + + +#define BIT_SHIFT_RF_RL_ID 0 +#define BIT_MASK_RF_RL_ID 0xf +#define BIT_RF_RL_ID(x) (((x) & BIT_MASK_RF_RL_ID) << BIT_SHIFT_RF_RL_ID) + + +//2 REG_SYS_SYSTEM_CFG1 + +#define BIT_SHIFT_SYSCFG_TRP_ICFG 28 +#define BIT_MASK_SYSCFG_TRP_ICFG 0xf +#define BIT_SYSCFG_TRP_ICFG(x) (((x) & BIT_MASK_SYSCFG_TRP_ICFG) << BIT_SHIFT_SYSCFG_TRP_ICFG) + +#define BIT_SYSCFG_TRP_BOOT_SEL_ BIT(27) +#define BIT_SysCFG_TRP_SPSLDO_SEL BIT(26) +#define BIT_V15_VLD BIT(16) +#define BIT_SYS_SYSPLL_CLK_RDY BIT(9) +#define BIT_SYS_XCLK_VLD BIT(8) +#define BIT_SYSCFG_ALDN_STS BIT(0) + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + +//2 REG_RSVD + +//2 REG_NOT_VALID + +//2 REG_NOT_VALID + + +//================= Register Address Definition =====================// +#define REG_SYS_PWR_CTRL 0x0000 +#define REG_SYS_ISO_CTRL 0x0002 +#define REG_SYS_FUNC_EN 0x0008 +#define REG_SYS_CLK_CTRL0 0x0010 +#define REG_SYS_CLK_CTRL1 0x0014 +#define REG_SYS_EFUSE_SYSCFG0 0x0020 +#define REG_SYS_EFUSE_SYSCFG1 0x0024 +#define REG_SYS_EFUSE_SYSCFG2 0x0028 +#define REG_SYS_EFUSE_SYSCFG3 0x002C +#define REG_SYS_EFUSE_SYSCFG4 0x0030 +#define REG_SYS_EFUSE_SYSCFG5 0x0034 +#define REG_SYS_EFUSE_SYSCFG6 0x0038 +#define REG_SYS_EFUSE_SYSCFG7 0x003C +#define REG_SYS_REGU_CTRL0 0x0040 +#define REG_SYS_SWR_CTRL0 0x0048 +#define REG_SYS_SWR_CTRL1 0x004C +#define REG_SYS_XTAL_CTRL0 0x0060 +#define REG_SYS_XTAL_CTRL1 0x0064 +#define REG_SYS_SYSPLL_CTRL0 0x0070 +#define REG_SYS_SYSPLL_CTRL1 0x0074 +#define REG_SYS_SYSPLL_CTRL2 0x0078 +#define REG_SYS_ANA_TIM_CTRL 0x0090 +#define REG_SYS_DSLP_TIM_CTRL 0x0094 +#define REG_SYS_DSLP_TIM_CAL_CTRL 0x0098 +#define REG_SYS_DEBUG_CTRL 0x00A0 +#define REG_SYS_PINMUX_CTRL 0x00A4 +#define REG_SYS_GPIO_DSTBY_WAKE_CTRL0 0x00A8 +#define REG_SYS_GPIO_DSTBY_WAKE_CTRL1 0x00AC +#define REG_SYS_DEBUG_REG 0x00BC +#define REG_SYS_EEPROM_CTRL0 0x00E0 +#define REG_SYS_EEPROM_CTRL1 0x00E4 +#define REG_SYS_EFUSE_CTRL 0x00E8 +#define REG_SYS_EFUSE_TEST 0x00EC +#define REG_SYS_DSTBY_INFO0 0x00F0 +#define REG_SYS_DSTBY_INFO1 0x00F4 +#define REG_SYS_DSTBY_INFO2 0x00F8 +#define REG_SYS_DSTBY_INFO3 0x00FC +#define REG_SYS_SLP_WAKE_EVENT_MSK0 0x0100 +#define REG_SYS_SLP_WAKE_EVENT_MSK1 0x0104 +#define REG_SYS_SLP_WAKE_EVENT_STATUS0 0x0108 +#define REG_SYS_SLP_WAKE_EVENT_STATUS1 0x010C +#define REG_SYS_SNF_WAKE_EVENT_MSK0 0x0110 +#define REG_SYS_SNF_WAKE_EVENT_STATUS 0x0114 +#define REG_SYS_PWRMGT_CTRL 0x0118 +#define REG_SYS_PWRMGT_OPTION 0x0120 +#define REG_SYS_PWRMGT_OPTION_EXT 0x0124 +#define REG_SYS_DSLP_WEVENT 0x0130 +#define REG_SYS_PERI_MONITOR 0x0134 +#define REG_SYS_SYSTEM_CFG0 0x01F0 +#define REG_SYS_SYSTEM_CFG1 0x01F4 +#define REG_SYS_SYSTEM_CFG2 0x01F8 + + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_timer.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_timer.h new file mode 100644 index 0000000..5424a74 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_timer.h @@ -0,0 +1,257 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_TIMER_H_ +#define _RTL8195A_TIMER_H_ + + +#define TIMER_TICK_US 31 + +#define TIMER_LOAD_COUNT_OFF 0x00 +#define TIMER_CURRENT_VAL_OFF 0x04 +#define TIMER_CTL_REG_OFF 0x08 +#define TIMER_EOI_OFF 0x0c +#define TIMER_INT_STATUS_OFF 0x10 +#define TIMER_INTERVAL 0x14 +#define TIMERS_INT_STATUS_OFF 0xa0 +#define TIMERS_EOI_OFF 0xa4 +#define TIMERS_RAW_INT_STATUS_OFF 0xa8 +#define TIMERS_COMP_VER_OFF 0xac + +#define MAX_TIMER_VECTOR_TABLE_NUM 6 + +#define HAL_TIMER_READ32(addr) (*((volatile u32*)(TIMER_REG_BASE + addr)))//HAL_READ32(TIMER_REG_BASE, addr) +#define HAL_TIMER_WRITE32(addr, value) ((*((volatile u32*)(TIMER_REG_BASE + addr))) = value)//HAL_WRITE32(TIMER_REG_BASE, addr, value) +#define HAL_TIMER_READ16(addr) (*((volatile u16*)(TIMER_REG_BASE + addr)))//HAL_READ16(TIMER_REG_BASE, addr) +#define HAL_TIMER_WRITE16(addr, value) ((*((volatile u16*)(TIMER_REG_BASE + addr))) = value)//HAL_WRITE16(TIMER_REG_BASE, addr, value) +#define HAL_TIMER_READ8(addr) (*((volatile u8*)(TIMER_REG_BASE + addr)))//HAL_READ8(TIMER_REG_BASE, addr) +#define HAL_TIMER_WRITE8(addr, value) ((*((volatile u8*)(TIMER_REG_BASE + addr))) = value)//HAL_WRITE8(TIMER_REG_BASE, addr, value) + +_LONG_CALL_ u32 +HalGetTimerIdRtl8195a( + IN u32 *TimerID +); + +_LONG_CALL_ BOOL +HalTimerInitRtl8195a( + IN VOID *Data +); + +_LONG_CALL_ u32 +HalTimerReadCountRtl8195a( + IN u32 TimerId +); + +_LONG_CALL_ VOID +HalTimerIrqClearRtl8195a( + IN u32 TimerId +); + +_LONG_CALL_ VOID +HalTimerDisRtl8195a( + IN u32 TimerId +); + +_LONG_CALL_ VOID +HalTimerEnRtl8195a( + IN u32 TimerId +); + +_LONG_CALL_ VOID +HalTimerDumpRegRtl8195a( + IN u32 TimerId +); + +// ROM Code patch +HAL_Status +HalTimerInitRtl8195a_Patch( + IN VOID *Data +); + +u32 +HalTimerReadCountRtl8195a_Patch( + IN u32 TimerId +); + +VOID +HalTimerReLoadRtl8195a_Patch( + IN u32 TimerId, + IN u32 LoadUs +); + +u32 +HalTimerReadCountRtl8195a_Patch( + IN u32 TimerId +); + +VOID +HalTimerIrqEnRtl8195a( + IN u32 TimerId +); + +VOID +HalTimerIrqDisRtl8195a( + IN u32 TimerId +); + +VOID +HalTimerClearIsrRtl8195a( + IN u32 TimerId +); + +VOID +HalTimerEnRtl8195a_Patch( + IN u32 TimerId +); + +VOID +HalTimerDisRtl8195a_Patch( + IN u32 TimerId +); + +VOID +HalTimerDeInitRtl8195a_Patch( + IN VOID *Data +); + +#if defined(CONFIG_CHIP_C_CUT) || defined(CONFIG_CHIP_E_CUT) + +__weak _LONG_CALL_ +VOID +HalTimerIrq2To7HandleV02( + IN VOID *Data +); + +__weak _LONG_CALL_ROM_ +HAL_Status +HalTimerIrqRegisterRtl8195aV02( + IN VOID *Data +); + +__weak _LONG_CALL_ +HAL_Status +HalTimerInitRtl8195aV02( + IN VOID *Data +); + +__weak _LONG_CALL_ +u32 +HalTimerReadCountRtl8195aV02( + IN u32 TimerId +); + +__weak _LONG_CALL_ +VOID +HalTimerReLoadRtl8195aV02( + IN u32 TimerId, + IN u32 LoadUs +); + +__weak _LONG_CALL_ROM_ +HAL_Status +HalTimerIrqUnRegisterRtl8195aV02( + IN VOID *Data +); + +__weak _LONG_CALL_ +VOID +HalTimerDeInitRtl8195aV02( + IN VOID *Data +); + +#endif // end of "#ifdef CONFIG_CHIP_C_CUT" + +#ifdef CONFIG_CHIP_E_CUT +_LONG_CALL_ VOID +HalTimerReLoadRtl8195a_V04( + IN u32 TimerId, + IN u32 LoadUs +); + +_LONG_CALL_ HAL_Status +HalTimerInitRtl8195a_V04( + IN VOID *Data +); +#endif // #ifdef CONFIG_CHIP_E_CUT + +// HAL functions wrapper +#ifndef CONFIG_RELEASE_BUILD_LIBRARIES +static __inline HAL_Status +HalTimerInit( + IN VOID *Data +) +{ +#ifdef CONFIG_CHIP_E_CUT + return (HalTimerInitRtl8195a_V04(Data)); +#else + return (HalTimerInitRtl8195a_Patch(Data)); +#endif +} + +static __inline VOID +HalTimerEnable( + IN u32 TimerId +) +{ + HalTimerIrqEnRtl8195a(TimerId); + HalTimerEnRtl8195a_Patch(TimerId); +} + +static __inline VOID +HalTimerDisable( + IN u32 TimerId +) +{ + HalTimerDisRtl8195a_Patch(TimerId); +} + +static __inline VOID +HalTimerClearIsr( + IN u32 TimerId +) +{ + HalTimerClearIsrRtl8195a(TimerId); +} + +static __inline VOID +HalTimerReLoad( + IN u32 TimerId, + IN u32 LoadUs +) +{ +#ifdef CONFIG_CHIP_E_CUT + HalTimerReLoadRtl8195a_V04(TimerId, LoadUs); +#else + HalTimerReLoadRtl8195a_Patch(TimerId, LoadUs); +#endif +} + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +static __inline VOID +HalTimerDeInit( + IN VOID *Data +) +{ + HalTimerDeInitRtl8195a_Patch(Data); +} + +#else + +static __inline VOID +HalTimerDeInit( + IN VOID *Data +) +{ + HalTimerDeInitRtl8195aV02(Data); +} + +#endif // end of "#ifndef CONFIG_CHIP_C_CUT" +#endif // #ifndef CONFIG_RELEASE_BUILD_LIBRARIES +#endif //_RTL8195A_TIMER_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_uart.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_uart.h new file mode 100644 index 0000000..6a5f25b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_uart.h @@ -0,0 +1,716 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#ifndef _RTL8195A_UART_H_ +#define _RTL8195A_UART_H_ + +#define MAX_UART_INDEX 2 + +#define RUART_DLL_OFF 0x00 +#define RUART_DLM_OFF 0x04 //RW, DLAB = 1 +#define RUART_INTERRUPT_EN_REG_OFF 0x04 //RW, DLAB = 0 +// Define Interrupt Enable Bit +typedef enum { + RU_IER_ERBFI = BIT0, // Enable Received Data Available Interrupt + RU_IER_ETBEI = BIT1, // Enable Transmit Holding Register Empty Interrupt + RU_IER_ELSI = BIT2, // Enable Receiver Line Status Interrupt + RU_IER_EDSSI = BIT3, // Enable Modem Status Interrupt + RU_IER_PTIME = BIT7 // Programmable THRE Interrupt Mode Enable +} RUART_INT_EN; +#define RUART_IER_ERBI BIT0 //BIT0, Enable Received Data Available Interrupt (rx trigger) +#define RUART_IER_ETBEI BIT1 //BIT1, Enable Transmitter FIFO Empty Interrupt (tx fifo empty) +#define RUART_IER_ELSI BIT2 //BIT2, Enable Receiver Line Status Interrupt (receiver line status) +#define RUART_IER_EDSSI BIT3 //BIT3, Enable Modem Status Interrupt (modem status transition) +#define RUART_IER_PTIME BIT7 //*BIT7 PTIME, Programmable THRE Interrupt Mode Enable + +#define RUART_INT_ID_REG_OFF 0x08 //[R] +// define Log UART Interrupt Indication ID +/* +IIR[3:0]: +0000 = modem status +0001 = no interrupt pending +0010 = THR empty +0100 = received data available +0110 = receiver line status +0111 = busy detect +1100 = character timeout +*/ +typedef enum { + RU_IIR_MODEM_STATUS = 0, //Clear to send or data set ready or ring indicator or data carrier detect. + RU_IIR_NO_PENDING = 1, + RU_IIR_THR_EMPTY = 2, // TX FIFO level lower than threshold or FIFO empty + RU_IIR_RX_RDY = 4, // RX data ready + RU_IIR_RX_LINE_STATUS = 6, // Overrun/parity/framing errors or break interrupt + RU_IIR_BUSY = 7, + RU_IIR_CHAR_TIMEOUT = 12 // timeout: Rx data ready but no read +} RUART_INT_ID; +#define RUART_IIR_INT_PEND 0x01 +#define RUART_IIR_INT_ID (0x07<<1) //011(3), 010(2), 110(6), 001(1), 000(0) + +#define RUART_FIFO_CTL_REG_OFF 0x08 //[W] +// Define FIFO Control Register Bits +typedef enum { + RU_FCR_FIFO_EN = BIT0, // FIFO Enable. + RU_FCR_RST_RX = BIT1, // RCVR FIFO Reset, self clear + RU_FCR_RST_TX = BIT2, // XMIT FIFO Reset, self clear + RU_FCR_TX_TRIG_EMP = 0, // TX Empty Trigger: FIFO empty + RU_FCR_TX_TRIG_2CH = BIT4, // TX Empty Trigger: 2 characters in the FIFO + RU_FCR_TX_TRIG_QF = BIT5, // TX Empty Trigger: FIFO 1/4 full + RU_FCR_TX_TRIG_HF = (BIT5|BIT4), // TX Empty Trigger: FIFO 1/2 full + RU_FCR_TX_TRIG_MASK = (BIT5|BIT4), // TX Empty Trigger Bit Mask + RU_FCR_RX_TRIG_1CH = 0, // RCVR Trigger: 1 character in the FIFO + RU_FCR_RX_TRIG_QF = BIT6, // RCVR Trigger: FIFO 1/4 full + RU_FCR_RX_TRIG_HF = BIT7, // RCVR Trigger: FIFO 1/2 full + RU_FCR_RX_TRIG_AF = (BIT7|BIT6), // RCVR Trigger: FIFO 2 less than full + RU_FCR_RX_TRIG_MASK = (BIT7|BIT6) // RCVR Trigger bits Mask +} RUART_FIFO_CTRL; +#define RUART_FIFO_CTL_REG_FIFO_ENABLE BIT0 //BIT0, FIFO Enable +#define RUART_FIFO_CTL_REG_CLEAR_RXFIFO BIT1 //BIT1, Write 1 clear +#define RUART_FIFO_CTL_REG_CLEAR_TXFIFO BIT2 //BIT2, Write 1 clear +#define RUART_FIFO_CTL_REG_DMA_ENABLE BIT3 //BIT3 DMAM, DMA Mode +#define RUART_FIFO_CTL_REG_TET (0x03<<4) //BIT4..5 TET, TX Empty Trigger: 00 = FIFO empty, 01 = 2 characters in the FIFO, 10 = FIFO 1/4 full, 11 = FIFO 1/2 full +#define RUART_FIFO_CTL_REG_RT (0x03<<6) //BIT6..7 RT, RCVR Trigger: 00 = FIFO empty, 01 = 2 characters in the FIFO, 10 = FIFO 1/4 full, 11 = FIFO 1/2 full +#define FIFO_CTL_DEFAULT_WITH_FIFO_DMA 0xC9 +#define FIFO_CTL_DEFAULT_WITH_FIFO 0xC1 + +#define RUART_MODEM_CTL_REG_OFF 0x10 +#define RUART_MCR_DTR BIT0 //BIT0, Data Terminal Ready (DTR) +#define RUART_MCR_RTS BIT1 //*BIT1 Request to Send (RTS) +#define RUART_MCR_OUT1 BIT2 //*BIT2 User designated Output 1 (OUT1) +#define RUART_MCR_OUT2 BIT3 //*BIT3 User designated Output 2 (OUT2) +#define RUART_MCR_LOOPBACK BIT4 //*BIT4, LoopBack Bit (LOOPBACK) +#define RUART_MCL_AUTOFLOW_ENABLE BIT5 //BIT5, 0x20 + + +#define RUART_LINE_CTL_REG_OFF 0x0C +// Define Line Control Register Bits +typedef enum { + RU_LCR_DLS_5B = 0, // Data Length: 5 bits + RU_LCR_DLS_6B = BIT0, // Data Length: 6 bits + RU_LCR_DLS_7B = BIT1, // Data Length: 7 bits + RU_LCR_DLS_8B = (BIT1|BIT0), // Data Length: 7 bits + + RU_LCR_STOP_1B = 0, // Number of stop bits: 1 + RU_LCR_STOP_2B = BIT2, // Number of stop bits: 1.5(data len=5) or 2 + + RU_LCR_PARITY_NONE = 0, // Parity Enable: 0 + RU_LCR_PARITY_ODD = BIT3, // Parity Enable: 1, Even Parity: 0 + RU_LCR_PARITY_EVEN = (BIT4|BIT3), // Parity Enable: 1, Even Parity: 1 + + RU_LCR_BC = BIT6, // Break Control Bit + RU_LCR_DLAB = BIT7 // Divisor Latch Access Bit +} RUART_LINE_CTRL; +//*BIT6 Break Control Bit (BC) +//*BIT4 Even Parity Select (EPS) +//*BIT3 Parity Enable (PEN) +//*BIT2 Number of stop bits (STOP) +//*BIT1..0 Data Length Select (DLS) +#define RUART_LINE_CTL_REG_DLAB_ENABLE BIT7 //BIT7, 0x80 + +#define RUART_LINE_STATUS_REG_OFF 0x14 +// Define Line Status Bit +typedef enum { + RU_LSR_DR = BIT0, // Data Ready bit + RU_LSR_OE = BIT1, // Overrun error bit + RU_LSR_PE = BIT2, // Parity Error bit + RU_LSR_FE = BIT3, // Framing Error bit + RU_LSR_BI = BIT4, // Break Interrupt bit + RU_LSR_THRE = BIT5, // Transmit Holding Register Empty bit(IER_PTIME=0) + RU_LSR_FIFOF = BIT5, // Transmit FIFO Full bit(IER_PTIME=1) + RU_LSR_TEMT = BIT6, // Transmitter Empty bit + RU_LSR_RFE = BIT7 // Receiver FIFO Error bit +} RUART_LINE_STATUS; +#define RUART_LINE_STATUS_REG_DR BIT0 //BIT0, Data Ready indicator +#define RUART_LINE_STATUS_ERR_OVERRUN BIT1 //BIT1, Over Run +#define RUART_LINE_STATUS_ERR_PARITY BIT2 //BIT2, Parity error +#define RUART_LINE_STATUS_ERR_FRAMING BIT3 //BIT3, Framing error +#define RUART_LINE_STATUS_ERR_BREAK BIT4 //BIT4, Break interrupt error +#define RUART_LINE_STATUS_REG_THRE BIT5 //BIT5, 0x20, Transmit Holding Register Empty Interrupt enable +#define RUART_LINE_STATUS_REG_TEMT BIT6 //BIT6, 0x40, Transmitter Empty indicator(bit) +#define RUART_LINE_STATUS_ERR_RXFIFO BIT7 //BIT7, RX FIFO error +#define RUART_LINE_STATUS_ERR (RUART_LINE_STATUS_ERR_OVERRUN|RUART_LINE_STATUS_ERR_PARITY| \ + RUART_LINE_STATUS_ERR_FRAMING|RUART_LINE_STATUS_ERR_BREAK| \ + RUART_LINE_STATUS_ERR_RXFIFO) //Line status error + +#define RUART_MODEM_STATUS_REG_OFF 0x18 //Modem Status Register +//* BIT7 Data Carrier Detect (DCD) +//* BIT6 Ring Indicator (RI) +//* BIT5 Data Set Ready (DSR) +//* BIT4 Clear to Send (CTS) +//* BIT3 Delta Data Carrier Detect (DDCD) +//* BIT2 Trailing Edge of Ring Indicator (TERI) +//* BIT1 Delta Data Set Ready (DDSR) +//* BIT0 Delta Clear to Send (DCTS) +#define RUART_SCRATCH_PAD_REG_OFF 0x1C //Scratch Pad Register +#define RUART_SP_REG_RXBREAK_INT_STATUS BIT7 //BIT7, 0x80, Write 1 clear +#define RUART_SP_REG_DBG_SEL (0x0F<<8) //[11:8], Debug port selection +#define RUART_SP_REG_XFACTOR_ADJ (0x7FF<<16) //[26:16] + +#define RUART_STS_REG_OFF 0x20 +#define RUART_STS_REG_RESET_RCV BIT3 //BIT3, 0x08, Reset Uart Receiver +#define RUART_STS_REG_XFACTOR 0xF<<4 + +#define RUART_REV_BUF_REG_OFF 0x24 //Receiver Buffer Register +#define RUART_TRAN_HOLD_REG_OFF 0x24 //Transmitter Holding Register + +#define RUART_MISC_CTL_REG_OFF 0x28 +#define RUART_TXDMA_BURSTSIZE_MASK 0xF8 //7:3 +#define RUART_RXDMA_BURSTSIZE_MASK 0x1F00 //12:8 + +#define RUART_DEBUG_REG_OFF 0x3C + +// RUART_LINE_CTL_REG_OFF (0x0C) +#define BIT_SHIFT_LCR_WLS 0 // word length select: 0: 7 bits, 1: 8bits +#define BIT_MASK_LCR_WLS_8BITS 0x1 +#define BIT_LCR_WLS(x)(((x) & BIT_MASK_LCR_WLS_8BITS) << BIT_SHIFT_LCR_WLS) +#define BIT_CLR_LCR_WLS (~(BIT_MASK_LCR_WLS_8BITS << BIT_SHIFT_LCR_WLS)) + +#define BIT_SHIFT_LCR_STB 2 // Stop bit select: 0: no stop bit, 1: 1 stop bit +#define BIT_MASK_LCR_STB_EN 0x1 +#define BIT_LCR_STB_EN(x)(((x) & BIT_MASK_LCR_STB_EN) << BIT_SHIFT_LCR_STB) +#define BIT_INVC_LCR_STB_EN (~(BIT_MASK_LCR_STB_EN << BIT_SHIFT_LCR_STB)) + +#define BIT_SHIFT_LCR_PARITY_EN 3 +#define BIT_MASK_LCR_PARITY_EN 0x1 +#define BIT_LCR_PARITY_EN(x)(((x) & BIT_MASK_LCR_PARITY_EN) << BIT_SHIFT_LCR_PARITY_EN) +#define BIT_INVC_LCR_PARITY_EN (~(BIT_MASK_LCR_PARITY_EN << BIT_SHIFT_LCR_PARITY_EN)) + +#define BIT_SHIFT_LCR_PARITY_TYPE 4 +#define BIT_MASK_LCR_PARITY_TYPE 0x1 +#define BIT_LCR_PARITY_TYPE(x)(((x) & BIT_MASK_LCR_PARITY_TYPE) << BIT_SHIFT_LCR_PARITY_TYPE) +#define BIT_INVC_LCR_PARITY_TYPE (~(BIT_MASK_LCR_PARITY_TYPE << BIT_SHIFT_LCR_PARITY_TYPE)) + +#define BIT_SHIFT_LCR_STICK_PARITY_EN 5 +#define BIT_MASK_LCR_STICK_PARITY_EN 0x1 +#define BIT_LCR_STICK_PARITY_EN(x)(((x) & BIT_MASK_LCR_STICK_PARITY_EN) << BIT_SHIFT_LCR_STICK_PARITY_EN) +#define BIT_INVC_LCR_STICK_PARITY_EN (~(BIT_MASK_LCR_STICK_PARITY_EN << BIT_SHIFT_LCR_STICK_PARITY_EN)) + +#define BIT_SHIFT_LCR_BREAK_CTRL 6 +#define BIT_MASK_LCR_BREAK_CTRL 0x1 +#define BIT_UART_LCR_BREAK_CTRL ((BIT_MASK_LCR_BREAK_CTRL) << BIT_SHIFT_LCR_BREAK_CTRL) + +#define RUART_BAUD_RATE_2400 2400 +#define RUART_BAUD_RATE_4800 4800 +#define RUART_BAUD_RATE_9600 9600 +#define RUART_BAUD_RATE_19200 19200 +#define RUART_BAUD_RATE_38400 38400 +#define RUART_BAUD_RATE_57600 57600 +#define RUART_BAUD_RATE_115200 115200 +#define RUART_BAUD_RATE_921600 921600 +#define RUART_BAUD_RATE_1152000 1152000 + +#define HAL_RUART_READ32(UartIndex, addr) \ + HAL_READ32(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr) +#define HAL_RUART_WRITE32(UartIndex, addr, value) \ + HAL_WRITE32(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr, value) +#define HAL_RUART_READ16(UartIndex, addr) \ + HAL_READ16(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr) +#define HAL_RUART_WRITE16(UartIndex, addr, value) \ + HAL_WRITE16(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr, value) +#define HAL_RUART_READ8(UartIndex, addr) \ + HAL_READ8(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr) +#define HAL_RUART_WRITE8(UartIndex, addr, value) \ + HAL_WRITE8(UART0_REG_BASE+ (UartIndex*RUART_REG_OFF), addr, value) + +#define UART_OVSR_POOL_MIN 1000 +#define UART_OVSR_POOL_MAX 2090 +#define DIVISOR_RESOLUTION 10 +#define JITTER_LIMIT 100 +#define UART_SCLK ((HAL_SYS_CTRL_READ32(REG_SYS_SYSPLL_CTRL1) & (1<<17))? (100000000) : (200000000*5/12)) + +typedef struct _RUART_SPEED_SETTING_ { + u32 BaudRate; + u32 Ovsr; + u32 Div; + u32 Ovsr_adj; +#if defined(E_CUT_ROM_DOMAIN) || (!defined(CONFIG_RELEASE_BUILD_LIBRARIES)) + u8 Ovsr_adj_max_bits; // 9: No parity, 10: with Parity + u8 Ovsr_adj_bits; + u16 *Ovsr_adj_map; + u32 max_err; // 10 ~ 100: 30 + u32 Ovsr_min; // 10 ~ 20: 1000 + u32 Ovsr_max; // 10 ~ 20: 2000 + u32 divisor_resolution; // 1 ~ 20: 10 + u32 jitter_lim; // 50 ~ 100: 100 + u32 sclk; // 83.33333 MHz +#endif +}RUART_SPEED_SETTING, *PRUART_SPEED_SETTING; + +typedef enum _UART_RXFIFO_TRIGGER_LEVEL_ { + OneByte = 0x00, // 1 + FourBytes = 0x01, // 4 + EightBytes = 0x10, // 8 + FourteenBytes = 0x11 // 14 +}UART_RXFIFO_TRIGGER_LEVEL, *PUART_RXFIFO_TRIGGER_LEVEL; + +typedef enum _RUART0_PINMUX_SELECT_ { + RUART0_MUX_TO_GPIOC = S0, + RUART0_MUX_TO_GPIOE = S1, + RUART0_MUX_TO_GPIOA = S2 +}RUART0_PINMUX_SELECT, *PRUART0_PINMUX_SELECT; + +typedef enum _RUART1_PINMUX_SELECT_ { + RUART1_MUX_TO_GPIOD = S0, + RUART1_MUX_TO_GPIOE = S1, + RUART1_MUX_TO_GPIOB = S2 +}RUART1_PINMUX_SELECT, *PRUART1_PINMUX_SELECT; + +typedef enum _RUART2_PINMUX_SELECT_ { + RUART2_MUX_TO_GPIOA = S0, + RUART2_MUX_TO_GPIOC = S1, + RUART2_MUX_TO_GPIOD = S2 +}RUART2_PINMUX_SELECT, *PRUART2_PINMUX_SELECT; + +typedef enum _RUART_FLOW_CONTROL_ { + AUTOFLOW_DISABLE = 0, + AUTOFLOW_ENABLE = 1 +}RUART_FLOW_CONTROL, *PRUART_FLOW_CONTROL; + +typedef enum _RUART_WORD_LEN_SEL_ { + RUART_WLS_7BITS = 0, + RUART_WLS_8BITS = 1 +}RUART_WORD_LEN_SEL, *PRUART_WORD_LEN_SEL; + +typedef enum _RUART_STOP_BITS_ { + RUART_STOP_BIT_1 = 0, + RUART_STOP_BIT_2 = 1 +}RUART_STOP_BITS, *PRUART_STOP_BITS; + +typedef enum _RUART_PARITY_CONTROL_ { + RUART_PARITY_DISABLE = 0, + RUART_PARITY_ENABLE = 1 +}RUART_PARITY_CONTROL, *PRUART_PARITY_CONTROL; + +typedef enum _RUART_PARITY_TYPE_ { + RUART_ODD_PARITY = 0, + RUART_EVEN_PARITY = 1 +}RUART_PARITY_TYPE, *PRUART_PARITY_TYPE; + +typedef enum _RUART_STICK_PARITY_CONTROL_ { + RUART_STICK_PARITY_DISABLE = 0, + RUART_STICK_PARITY_ENABLE = 1 +}RUART_STICK_PARITY_CONTROL, *PRUART_STICK_PARITY_CONTROL; + +typedef enum _UART_INT_ID_ { + ModemStatus = 0, + TxFifoEmpty = 1, + ReceiverDataAvailable = 2, + ReceivLineStatus = 3, + TimeoutIndication = 6 +}UART_INT_ID, *PUART_INT_ID; + +typedef enum _HAL_UART_State_ +{ + HAL_UART_STATE_NULL = 0x00, // UART hardware not been initial yet + HAL_UART_STATE_READY = 0x10, // UART is initialed, ready to use + HAL_UART_STATE_BUSY = 0x20, // UART hardware is busy on configuration + HAL_UART_STATE_BUSY_TX = 0x21, // UART is buzy on TX + HAL_UART_STATE_BUSY_RX = 0x22, // UART is busy on RX + HAL_UART_STATE_BUSY_TX_RX = 0x23, // UART is busy on TX an RX + HAL_UART_STATE_TIMEOUT = 0x30, // Transfer timeout + HAL_UART_STATE_ERROR = 0x40 // UART Error +}HAL_UART_State, *PHAL_UART_State; + +typedef enum _HAL_UART_Status_ +{ + HAL_UART_STATUS_OK = 0x00, // Transfer OK + HAL_UART_STATUS_TIMEOUT = 0x01, // Transfer Timeout + HAL_UART_STATUS_ERR_OVERRUN = 0x02, // RX Over run + HAL_UART_STATUS_ERR_PARITY = 0x04, // Parity error + HAL_UART_STATUS_ERR_FRAM = 0x08, // Framing Error + HAL_UART_STATUS_ERR_BREAK = 0x10, // Break Interrupt + HAL_UART_STATUS_ERR_PARA = 0x20, // Parameter error + HAL_UART_STATUS_ERR_RXFIFO = 0x80, // RX FIFO error +}HAL_UART_Status, *PHAL_UART_Status; + +u32 +HalRuartGetDebugValueRtl8195a( + IN VOID* Data, + IN u32 DbgSel + ); + +#if 0 +u32 +FindElementIndex( + u32 Element, + u32* Array + ); +#endif + +VOID +RuartResetRxFifoRtl8195a( + IN u8 UartIndex + ); +#if 0 +VOID +RuartBusDomainEnableRtl8195a( + IN u8 UartIndex + ); +#endif + +HAL_Status +HalRuartResetRxFifoRtl8195a( + IN VOID *Data + ); + +HAL_Status +HalRuartInitRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartDeInitRtl8195a( + IN VOID *Data ///< RUART Adapter + ); + +HAL_Status +HalRuartPutCRtl8195a( + IN VOID *Data, + IN u8 TxData + ); + +u32 +HalRuartSendRtl8195a( + IN VOID *Data, + IN u8 *pTxData, + IN u32 Length, + IN u32 Timeout + ); + +HAL_Status +HalRuartIntSendRtl8195a( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send + ); + +HAL_Status +HalRuartDmaSendRtl8195a( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +); + +HAL_Status +HalRuartStopSendRtl8195a( + IN VOID *Data // PHAL_RUART_ADAPTER +); + +HAL_Status +HalRuartGetCRtl8195a( + IN VOID *Data, + OUT u8 *pRxByte + ); + +u32 +HalRuartRecvRtl8195a( + IN VOID *Data, + IN u8 *pRxData, + IN u32 Length, + IN u32 Timeout + ); + +HAL_Status +HalRuartIntRecvRtl8195a( + IN VOID *Data, ///< RUART Adapter + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length + ); + +HAL_Status +HalRuartDmaRecvRtl8195a( + IN VOID *Data, ///< RUART Adapter + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length + ); + +HAL_Status +HalRuartStopRecvRtl8195a( + IN VOID *Data // PHAL_RUART_ADAPTER +); + +u8 +HalRuartGetIMRRtl8195a( + IN VOID *Data + ); + +_LONG_CALL_ROM_ VOID +HalRuartSetIMRRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartDmaInitRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartRTSCtrlRtl8195a( + IN VOID *Data, + IN BOOLEAN RtsCtrl + ); + +VOID +HalRuartRegIrqRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartIntEnableRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartIntDisableRtl8195a( + IN VOID *Data + ); + +VOID +HalRuartAdapterLoadDefRtl8195a( + IN VOID *pAdp, + IN u8 UartIdx +); + +VOID +HalRuartTxGdmaLoadDefRtl8195a( + IN VOID *pAdp, + IN VOID *pCfg +); + +VOID +HalRuartRxGdmaLoadDefRtl8195a( + IN VOID *pAdp, + IN VOID *pCfg +); + +_LONG_CALL_ HAL_Status HalRuartIntSendRtl8195aV02( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +); + +_LONG_CALL_ HAL_Status +HalRuartIntRecvRtl8195aV02( + IN VOID *Data, ///< RUART Adapter + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length +); + +_LONG_CALL_ s32 +FindElementIndex_v02( + u32 Element, ///< RUART Baudrate + u32* Array, ///< Pre-defined Baudrate Array + u32 ElementNo +); + +_LONG_CALL_ HAL_Status HalRuartInitRtl8195a_v02(IN VOID *Data); + +// New added function 2015/04/20 +HAL_Status +HalRuartResetTxFifoRtl8195a( + IN VOID *Data ///< RUART Adapter + ); + +HAL_Status +HalRuartResetRxFifoRtl8195a_Patch( + IN VOID *Data ///< RUART Adapter +); + +HAL_Status +HalRuartResetTRxFifoRtl8195a( + IN VOID *Data ///< RUART Adapter +); + +HAL_Status +HalRuartSetBaudRateRtl8195a( + IN VOID *Data + ); + +HAL_Status +HalRuartEnableRtl8195a( + IN VOID *Data +); + +HAL_Status +HalRuartDisableRtl8195a( + IN VOID *Data +); + +HAL_Status +HalRuartFlowCtrlRtl8195a( + IN VOID *Data +); + +u32 +_UartTxDmaIrqHandle_Patch( + IN VOID *Data +); + +u32 +_UartRxDmaIrqHandle_Patch( + IN VOID *Data +); + +HAL_Status +HalRuartDmaSendRtl8195a_Patch( + IN VOID *Data, + IN u8 *pTxData, + IN u32 Length +); + +HAL_Status +HalRuartDmaRecvRtl8195a_Patch( + IN VOID *Data, + IN u8 *pRxData, + IN u32 Length +); + +HAL_Status +HalRuartMultiBlkDmaSendRtl8195a( + IN VOID *Data, + IN u8 *pTxData, + IN u32 Length +); + +HAL_Status +HalRuartMultiBlkDmaRecvRtl8195a( + IN VOID *Data, + IN u8 *pRxData, + IN u32 Length +); + +HAL_Status +RuartIsTimeout ( + u32 StartCount, + u32 TimeoutCnt +); + +HAL_Status +HalRuartStopRecvRtl8195a_Patch( + IN VOID *Data +); + +HAL_Status +HalRuartStopSendRtl8195a_Patch( + IN VOID *Data +); + +VOID +HalRuartEnterCriticalRtl8195a( + IN VOID *Data +); + +VOID +HalRuartExitCriticalRtl8195a( + IN VOID *Data +); + +#if CONFIG_CHIP_E_CUT +_LONG_CALL_ HAL_Status +HalRuartResetTxFifoRtl8195a_V04( + IN VOID *Data ///< RUART Adapter +); + +_LONG_CALL_ HAL_Status +HalRuartResetRxFifoRtl8195a_V04( + IN VOID *Data ///< RUART Adapter +); + +_LONG_CALL_ HAL_Status +HalRuartResetTRxFifoRtl8195a_V04( + IN VOID *Data ///< RUART Adapter +); + +_LONG_CALL_ HAL_Status +HalRuartSetBaudRateRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ HAL_Status +HalRuartInitRtl8195a_V04( + IN VOID *Data ///< RUART Adapter +); + +_LONG_CALL_ HAL_Status +HalRuartEnableRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ HAL_Status +HalRuartDisableRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ HAL_Status +HalRuartFlowCtrlRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ u32 +_UartTxDmaIrqHandle_V04( + IN VOID *Data +); + +_LONG_CALL_ u32 +_UartRxDmaIrqHandle_V04( + IN VOID *Data +); + +_LONG_CALL_ HAL_Status +HalRuartDmaSendRtl8195a_V04( + IN VOID *Data, + IN u8 *pTxData, + IN u32 Length +); + +_LONG_CALL_ HAL_Status +HalRuartDmaRecvRtl8195a_V04( + IN VOID *Data, + IN u8 *pRxData, + IN u32 Length +); + +_LONG_CALL_ HAL_Status +HalRuartMultiBlkDmaSendRtl8195a_V04( + IN VOID *Data, + IN u8 *pTxData, + IN u32 Length +); + +_LONG_CALL_ HAL_Status +HalRuartMultiBlkDmaRecvRtl8195a_V04( + IN VOID *Data, + IN u8 *pRxData, + IN u32 Length +); + +_LONG_CALL_ HAL_Status +HalRuartStopRecvRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ HAL_Status +HalRuartStopSendRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ VOID +HalRuartEnterCriticalRtl8195a_V04( + IN VOID *Data +); + +_LONG_CALL_ VOID +HalRuartExitCriticalRtl8195a_V04( + IN VOID *Data +); + +#endif // #if CONFIG_CHIP_E_CUT + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_usb.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_usb.h new file mode 100644 index 0000000..58f682e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_usb.h @@ -0,0 +1,432 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_USB_H_ +#define _RTL8195A_USB_H_ + + +// common command for USB +#define USB_CMD_TX_ETH 0x83 // request to TX a 802.3 packet +#define USB_CMD_TX_WLN 0x81 // request to TX a 802.11 packet +#define USB_CMD_H2C 0x11 // H2C(host to device) command packet +#define USB_CMD_MEMRD 0x51 // request to read a block of memory data +#define USB_CMD_MEMWR 0x53 // request to write a block of memory +#define USB_CMD_MEMST 0x55 // request to set a block of memory with a value +#define USB_CMD_STARTUP 0x61 // request to jump to the start up function + +#define USB_CMD_RX_ETH 0x82 // indicate a RX 802.3 packet +#define USB_CMD_RX_WLN 0x80 // indicate a RX 802.11 packet +#define USB_CMD_C2H 0x10 // C2H(device to host) command packet +#define USB_CMD_MEMRD_RSP 0x50 // response to memory block read command +#define USB_CMD_MEMWR_RSP 0x52 // response to memory write command +#define USB_CMD_MEMST_RSP 0x54 // response to memory set command +#define USB_CMD_STARTED 0x60 // indicate the program has jumped to the given function + + +// TODO: This data structer just for test, we should modify it for the normal driver +typedef struct _USB_TX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 rsvd1; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC, *PUSB_TX_DESC; + +#define SIZE_USB_TX_DESC sizeof(USB_TX_DESC) + +// TX Desc for Memory Write command +typedef struct _USB_TX_DESC_MW{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 reply:1; // bit[8], request to send a reply message + u32 rsvd0:23; +#else + u32 rsvd0:23; + u32 reply:1; // bit[8], request to send a reply message + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC_MW, *PUSB_TX_DESC_MW; + +// TX Desc for Memory Read command +typedef struct _USB_TX_DESC_MR{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 read_len:16; // bit[15:0], the length to read + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 read_len:16; // bit[15:0], the length to read +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC_MR, *PUSB_TX_DESC_MR; + +// TX Desc for Memory Set command +typedef struct _USB_TX_DESC_MS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 data:8; // bit[8:15], the value to be written to the memory + u32 reply:1; // bit[16], request to send a reply message + u32 rsvd0:15; +#else + u32 rsvd0:15; + u32 reply:1; // bit[16], request to send a reply message + u32 data:8; // bit[8:15], the value to be written to the memory + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_addr; // memory write start address + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the length to write + u32 rsvd2:16; // bit[31:16] +#else + u32 rsvd2:16; // bit[31:16] + u32 write_len:16; // bit[15:0], the length to write +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC_MS, *PUSB_TX_DESC_MS; + +// TX Desc for Jump to Start command +typedef struct _USB_TX_DESC_JS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 txpktsize:16; // bit[15:0] + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number +#else + u32 bus_agg_num:8; // bit[31:24], the bus aggregation number + u32 offset:8; // bit[23:16], store the sizeof(SDIO_TX_DESC) + u32 txpktsize:16; // bit[15:0] +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the packet type + u32 rsvd0:24; +#else + u32 rsvd0:24; + u32 type:8; // bit[7:0], the packet type +#endif + + // u4Byte 2 + u32 start_fun; // the pointer of the startup function + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_TX_DESC_JS, *PUSB_TX_DESC_JS; + +typedef struct _USB_RX_DESC{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:6; // bit[29:24] + u32 icv:1; // bit[30], ICV error + u32 crc:1; // bit[31], CRC error +#else + u32 crc:1; // bit[31], CRC error + u32 icv:1; // bit[30], ICV error + u32 rsvd0:6; // bit[29:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 rsvd2; + + // u4Byte 3 + u32 rsvd3; + + // u4Byte 4 + u32 rsvd4; + + // u4Byte 5 + u32 rsvd5; +} USB_RX_DESC, *PUSB_RX_DESC; + + +// For memory read command +typedef struct _USB_RX_DESC_MR{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 + u32 rsvd2; + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_RX_DESC_MR, *PUSB_RX_DESC_MR; + +// For memory write reply command +typedef struct _USB_RX_DESC_MW{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the type of this packet + u32 result:8; // bit[23:16], the result of memory write command + u32 rsvd2:8; // bit[31:24] +#else + u32 rsvd2:8; // bit[31:24] + u32 result:8; // bit[23:16], the result of memory write command + u32 write_len:16; // bit[15:0], the type of this packet +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_RX_DESC_MW, *PUSB_RX_DESC_MW; + +// For memory set reply command +typedef struct _USB_RX_DESC_MS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 start_addr; + + // u4Byte 3 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 write_len:16; // bit[15:0], the type of this packet + u32 result:8; // bit[23:16], the result of memory write command + u32 rsvd2:8; // bit[31:24] +#else + u32 rsvd2:8; // bit[31:24] + u32 result:8; // bit[23:16], the result of memory write command + u32 write_len:16; // bit[15:0], the type of this packet +#endif + + // u4Byte 4 + u32 rsvd3; + + // u4Byte 5 + u32 rsvd4; +} USB_RX_DESC_MS, *PUSB_RX_DESC_MS; + +// For firmware ready reply command +typedef struct _USB_RX_DESC_FS{ + // u4Byte 0 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 pkt_len:16; // bit[15:0], the packet size + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 rsvd0:8; // bit[31:24] +#else + u32 rsvd0:8; // bit[31:24] + u32 offset:8; // bit[23:16], the offset from the packet start to the buf start, also means the size of RX Desc + u32 pkt_len:16; // bit[15:0], the packet size +#endif + + // u4Byte 1 +#if (SYSTEM_ENDIAN==PLATFORM_LITTLE_ENDIAN) + u32 type:8; // bit[7:0], the type of this packet + u32 rsvd1:24; // bit[31:8] +#else + u32 rsvd1:24; // bit[31:8] + u32 type:8; // bit[7:0], the type of this packet +#endif + + // u4Byte 2 + u32 rsvd2; + + // u4Byte 3 + u32 rsvd3; + + // u4Byte 4 + u32 rsvd4; + + // u4Byte 5 + u32 rsvd5; +} USB_RX_DESC_FS, *PUSB_RX_DESC_FS; + + +#define SIZE_USB_RX_DESC sizeof(USB_RX_DESC) + +#endif // #ifndef _RTL8195A_USB_H_ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_wdt.h b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_wdt.h new file mode 100644 index 0000000..edbedd2 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/rtl8195a_wdt.h @@ -0,0 +1,86 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTL8195A_WDT_H_ +#define _RTL8195A_WDT_H_ + +#define WDGTIMERELY (10*1024) //us + +typedef struct _WDG_REG_ { + u16 WdgScalar; + u8 WdgEnByte; + u8 WdgClear:1; + u8 WdgCunLimit:4; + u8 Rsvd:1; + u8 WdgMode:1; + u8 WdgToISR:1; +}WDG_REG, *PWDG_REG; + +typedef struct _WDG_ADAPTER_ { + + WDG_REG Ctrl; + IRQ_HANDLE IrqHandle; + TIMER_ADAPTER WdgGTimer; + VOID (*UserCallback)(u32 callback_id); // User callback function + u32 callback_id; +}WDG_ADAPTER, *PWDG_ADAPTER; + +typedef enum _WDG_CNTLMT_ { + CNT1H = 0, + CNT3H = 1, + CNT7H = 2, + CNTFH = 3, + CNT1FH = 4, + CNT3FH = 5, + CNT7FH = 6, + CNTFFH = 7, + CNT1FFH = 8, + CNT3FFH = 9, + CNT7FFH = 10, + CNTFFFH = 11 +}WDG_CNTLMT, *PWDG_CNTLMT; + + +typedef enum _WDG_MODE_ { + INT_MODE = 0, + RESET_MODE = 1 +}WDG_MODE, *PWDG_MODE; + +extern VOID +WDGInitial( + IN u32 Period +); + +extern VOID +WDGIrqInitial( + VOID +); + +extern VOID +WDGIrqInitial( + VOID +); + +extern VOID +WDGStop( + VOID +); + +extern VOID +WDGRefresh( + VOID +); + +extern VOID +WDGIrqCallBackReg( + IN VOID *CallBack, + IN u32 Id +); + +#endif //_RTL8195A_WDT_H_ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_adc.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_adc.c new file mode 100644 index 0000000..4c1d3a7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_adc.c @@ -0,0 +1,389 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "platform_autoconf.h" +#include "diag.h" +#include "rtl8195a_adc.h" +#include "hal_adc.h" + +#ifdef CONFIG_ADC_EN +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CInit8195a +// +// Description: +// To initialize I2C module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalADCInit8195a( + IN VOID *Data +) +{ + PHAL_ADC_INIT_DAT pHalAdcInitData = (PHAL_ADC_INIT_DAT)Data; + u32 AdcTempDat; + u8 AdcTempIdx = pHalAdcInitData->ADCIdx; + + /* Enable ADC power cut */ +/* + AdcTempDat = HAL_ADC_READ32(REG_ADC_POWER); + AdcTempDat |= BIT_ADC_PWR_AUTO; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); +*/ + + /* ADC Control register set-up*/ + AdcTempDat = 0; + AdcTempDat |= (BIT_CTRL_ADC_COMP_ONLY(pHalAdcInitData->ADCCompOnly) | + BIT_CTRL_ADC_ONESHOT(pHalAdcInitData->ADCOneShotEn) | + BIT_CTRL_ADC_OVERWRITE(pHalAdcInitData->ADCOverWREn) | + BIT_CTRL_ADC_ENDIAN(pHalAdcInitData->ADCEndian) | + BIT_CTRL_ADC_BURST_SIZE(pHalAdcInitData->ADCBurstSz) | + BIT_CTRL_ADC_THRESHOLD(pHalAdcInitData->ADCOneShotTD) | + BIT_CTRL_ADC_DBG_SEL(pHalAdcInitData->ADCDbgSel)); + HAL_ADC_WRITE32(REG_ADC_CONTROL,AdcTempDat); + + DBG_8195A_ADC_LVL(HAL_ADC_LVL,"REG_ADC_CONTROL:%x\n", HAL_ADC_READ32(REG_ADC_CONTROL)); + + /* ADC compare value and compare method setting*/ + switch (AdcTempIdx) { + case ADC0_SEL: + AdcTempDat = HAL_ADC_READ32(REG_ADC_COMP_VALUE_L); + AdcTempDat &= ~(BIT_ADC_COMP_TH_0(0xFFFF)); + AdcTempDat |= BIT_CTRL_ADC_COMP_TH_0(pHalAdcInitData->ADCCompTD); + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_L, AdcTempDat); + break; + + case ADC1_SEL: + AdcTempDat = HAL_ADC_READ32(REG_ADC_COMP_VALUE_L); + AdcTempDat &= ~(BIT_ADC_COMP_TH_1(0xFFFF)); + AdcTempDat |= BIT_CTRL_ADC_COMP_TH_1(pHalAdcInitData->ADCCompTD); + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_L, AdcTempDat); + break; + + case ADC2_SEL: + AdcTempDat = HAL_ADC_READ32(REG_ADC_COMP_VALUE_H); + AdcTempDat &= ~(BIT_ADC_COMP_TH_2(0xFFFF)); + AdcTempDat |= BIT_CTRL_ADC_COMP_TH_2(pHalAdcInitData->ADCCompTD); + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_H, AdcTempDat); + break; + + case ADC3_SEL: + AdcTempDat = HAL_ADC_READ32(REG_ADC_COMP_VALUE_H); + AdcTempDat &= ~(BIT_ADC_COMP_TH_3(0xFFFF)); + AdcTempDat |= BIT_CTRL_ADC_COMP_TH_3(pHalAdcInitData->ADCCompTD); + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_H, AdcTempDat); + break; + default: + return _EXIT_FAILURE; + } + + /* ADC compare mode setting */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_COMP_SET); + AdcTempDat &= (~(0x01 << pHalAdcInitData->ADCIdx)); + AdcTempDat |= (BIT_CTRL_ADC_COMP_0_EN(pHalAdcInitData->ADCCompCtrl) << + pHalAdcInitData->ADCIdx); + HAL_ADC_WRITE32(REG_ADC_COMP_SET, AdcTempDat); + + /* ADC audio mode set-up */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + AdcTempDat &= ~(BIT_ADC_AUDIO_EN); + AdcTempDat |= BIT_CTRL_ADC_AUDIO_EN(pHalAdcInitData->ADCAudioEn); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + + /* ADC enable manually setting */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + AdcTempDat &= ~(BIT_ADC_EN_MANUAL); + AdcTempDat |= BIT_CTRL_ADC_EN_MANUAL(pHalAdcInitData->ADCEnManul); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + + + /* ADC analog parameter 0 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("AD0:%x\n", AdcTempDat); + //AdcTempDat |= (BIT0); + if (pHalAdcInitData->ADCInInput == 1){ + AdcTempDat &= (~BIT14); + } + else { + AdcTempDat |= (BIT14); + } + AdcTempDat &= (~(BIT3|BIT2)); + + /* Adjust VCM for C-Cut*/ +#ifdef CONFIG_CHIP_C_CUT + AdcTempDat |= (BIT22); +#endif + + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("AD0:%x\n", AdcTempDat); + + /* ADC analog parameter 1 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + AdcTempDat &= (~BIT1); + AdcTempDat |= (BIT2|BIT0); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("AD1:%x\n", AdcTempDat); + + /* ADC analog parameter 2 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD2); + DBG_ADC_INFO("AD2:%x\n", AdcTempDat); + AdcTempDat = 0x67884400; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD2, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD2); + DBG_ADC_INFO("AD2:%x\n", AdcTempDat); + + /* ADC analog parameter 3 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD3); + DBG_ADC_INFO("AD3:%x\n", AdcTempDat); + AdcTempDat = 0x77780039; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD3, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD3); + DBG_ADC_INFO("AD3:%x\n", AdcTempDat); + + /* ADC analog parameter 4 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD4); + DBG_ADC_INFO("AD4:%x\n", AdcTempDat); + AdcTempDat = 0x0004d501; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD4, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD4); + DBG_ADC_INFO("AD4:%x\n", AdcTempDat); + + /* ADC analog parameter 5 */ + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD5); + DBG_ADC_INFO("AD5:%x\n", AdcTempDat); + AdcTempDat = 0x1E010800; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD5, AdcTempDat); + AdcTempDat = HAL_ADC_READ32(REG_ADC_ANAPAR_AD5); + DBG_ADC_INFO("AD5:%x\n", AdcTempDat); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CInit8195a +// +// Description: +// To initialize I2C module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalADCDeInit8195a( + IN VOID *Data +) +{ + u32 AdcTempDat; + + AdcTempDat = HAL_ADC_READ32(REG_ADC_POWER); + AdcTempDat &= ~(BIT_ADC_PWR_AUTO); + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CIntrCtrl8195a +// +// Description: +// Modify the I2C interrupt mask according to the given value +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the de-initialization succeeded. +// _EXIT_FAILURE if the de-initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalADCEnableRtl8195a( + IN VOID *Data +){ + //PHAL_ADC_INIT_DAT pHalAdcInitData = (PHAL_ADC_INIT_DAT)Data; + u32 AdcTempDat; + DBG_ADC_INFO("HalADCEnableRtl8195a\n"); + + AdcTempDat = HAL_ADC_READ32(REG_ADC_POWER); + + AdcTempDat &= (~BIT_ADC_PWR_AUTO); + AdcTempDat |= 0x02; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + AdcTempDat |= 0x04; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + AdcTempDat &= (~0x08); + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_POWER); + DBG_ADC_INFO("HalADCEnableRtl8195a, power reg:%x\n",AdcTempDat); + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CIntrCtrl8195a +// +// Description: +// Modify the I2C interrupt mask according to the given value +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the de-initialization succeeded. +// _EXIT_FAILURE if the de-initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalADCIntrCtrl8195a( + IN VOID *Data +){ + PHAL_ADC_INIT_DAT pHalAdcInitData = (PHAL_ADC_INIT_DAT)Data; + + HAL_ADC_WRITE32(REG_ADC_INTR_EN, pHalAdcInitData->ADCIntrMSK); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CReceiveRtl8195a +// +// Description: +// Directly read one data byte a I2C data fifo. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The first data fifo content. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +u32 +HalADCReceiveRtl8195a( + IN VOID *Data +){ + u32 AdcTempDat; + + AdcTempDat = HAL_ADC_READ32(REG_ADC_FIFO_READ); + + return (AdcTempDat); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CReadRegRtl8195a +// +// Description: +// Directly read a I2C register according to the register offset. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// [in] I2CReg - +// The I2C register offset. +// +// Return: +// The register content in u32 format. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +u32 +HalADCReadRegRtl8195a( + IN VOID *Data, + IN u8 I2CReg +){ + u32 AdcTempDat; + + AdcTempDat = HAL_ADC_READ32(I2CReg); + return (AdcTempDat); +} + +#endif // CONFIG_ADC_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_dac.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_dac.c new file mode 100644 index 0000000..a9bc7a7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_dac.c @@ -0,0 +1,269 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_dac.h" +#include "hal_dac.h" + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalDACInit8195a +// +// Description: +// To initialize DAC module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The DAC parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-15. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalDACInit8195a( + IN VOID *Data +){ + PHAL_DAC_INIT_DAT pHalDacInitData = (PHAL_DAC_INIT_DAT)Data; + u32 DacTempDat; + u8 DacTempIdx = pHalDacInitData->DACIdx; + + /* Enable DAC power cut */ + DacTempDat = HAL_DAC_READ32(0, REG_DAC_PWR_CTRL); + DacTempDat |= BIT_DAC_PWR_AUTO; + + HAL_DAC_WRITE32(0, REG_DAC_PWR_CTRL, DacTempDat); + + /* Disable DAC module first */ + HAL_DAC_WRITE32(DacTempIdx, REG_DAC_CTRL, 0); + + /* Setup DAC module */ + DacTempDat = 0; + DacTempDat |= (BIT_CTRL_DAC_SPEED(pHalDacInitData->DACDataRate) | + BIT_CTRL_DAC_ENDIAN(pHalDacInitData->DACEndian) | + BIT_CTRL_DAC_FILTER_SETTLE(pHalDacInitData->DACFilterSet) | + BIT_CTRL_DAC_BURST_SIZE(pHalDacInitData->DACBurstSz) | + BIT_CTRL_DAC_DBG_SEL(pHalDacInitData->DACDbgSel) | + BIT_CTRL_DAC_DSC_DBG_SEL(pHalDacInitData->DACDscDbgSel) | + BIT_CTRL_DAC_BYPASS_DSC(pHalDacInitData->DACBPDsc) | + BIT_CTRL_DAC_DELTA_SIGMA(pHalDacInitData->DACDeltaSig)); + + HAL_DAC_WRITE32(DacTempIdx, REG_DAC_CTRL, DacTempDat); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CInit8195a +// +// Description: +// To initialize I2C module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalDACDeInit8195a( + IN VOID *Data +){ + PHAL_DAC_INIT_DAT pHalDacInitData = (PHAL_DAC_INIT_DAT)Data; + u32 DacTempDat; + + DacTempDat = HAL_DAC_READ32(pHalDacInitData->DACIdx, REG_DAC_CTRL); + DacTempDat &= (~BIT_DAC_FIFO_EN); + HAL_DAC_WRITE32(pHalDacInitData->DACIdx, REG_DAC_CTRL ,DacTempDat); + + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CIntrCtrl8195a +// +// Description: +// Modify the I2C interrupt mask according to the given value +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the de-initialization succeeded. +// _EXIT_FAILURE if the de-initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalDACEnableRtl8195a( + IN VOID *Data +){ + PHAL_DAC_INIT_DAT pHalDacInitData = (PHAL_DAC_INIT_DAT)Data; + u32 DacTempDat; + u8 DacTempIdx = pHalDacInitData->DACIdx; + + DacTempDat = HAL_DAC_READ32(DacTempIdx, REG_DAC_CTRL); + DacTempDat &= (~BIT_DAC_FIFO_EN); + + DacTempDat |= BIT_CTRL_DAC_FIFO_EN(pHalDacInitData->DACEn); + HAL_DAC_WRITE32(DacTempIdx, REG_DAC_CTRL, DacTempDat); + + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CIntrCtrl8195a +// +// Description: +// Modify the I2C interrupt mask according to the given value +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the de-initialization succeeded. +// _EXIT_FAILURE if the de-initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +HalDACIntrCtrl8195a( + IN VOID *Data +){ + PHAL_DAC_INIT_DAT pHalDacInitData = (PHAL_DAC_INIT_DAT)Data; + + HAL_DAC_WRITE32(pHalDacInitData->DACIdx, REG_DAC_INTR_CTRL, pHalDacInitData->DACIntrMSK); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CReceiveRtl8195a +// +// Description: +// Directly read one data byte a I2C data fifo. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The first data fifo content. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +u8 +HalDACSendRtl8195a( + IN VOID *Data +){ + + + return (0); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalDACReadRegRtl8195a +// +// Description: +// +// +// Arguments: +// [in] VOID *Data - +// The DAC parameter data struct. +// [in] I2CReg - +// The DAC register offset. +// +// Return: +// The DAC register content in u32 format. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-15. +// +//--------------------------------------------------------------------------------------------------- +u32 +HalDACReadRegRtl8195a( + IN VOID *Data, + IN u8 I2CReg +){ + PHAL_DAC_INIT_DAT pHalDacInitData = (PHAL_DAC_INIT_DAT)Data; + + //DBG_8195A_DAC("dac read reg idx:%x\n",pHalDacInitData->DACIdx); + //DBG_8195A_DAC("dac read reg offset:%x\n",I2CReg); + + return (u32)HAL_DAC_READ32(pHalDacInitData->DACIdx, I2CReg); +} + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gdma.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gdma.c new file mode 100644 index 0000000..5400456 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gdma.c @@ -0,0 +1,295 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_gdma.h" +#include "hal_gdma.h" + +#ifdef CONFIG_GDMA_EN + +#ifndef CONFIG_CHIP_E_CUT +BOOL +HalGdmaChBlockSetingRtl8195a_Patch( + IN VOID *Data +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + PGDMA_CH_LLI_ELE pLliEle; + struct GDMA_CH_LLI *pGdmaChLli; + struct BLOCK_SIZE_LIST *pGdmaChBkLi; + u32 MultiBlockCount = pHalGdmaAdapter->MaxMuliBlock; + u32 CtlxLow, CtlxUp, CfgxLow, CfgxUp; + u8 GdmaIndex = pHalGdmaAdapter->GdmaIndex; + u8 ChNum = pHalGdmaAdapter->ChNum; + u32 ChEn = pHalGdmaAdapter->ChEn; + u8 GdmaChIsrBitmap = (ChEn & 0xFF); + u8 PendingIsrIndex; + + + pLliEle = pHalGdmaAdapter->pLlix->pLliEle; + pGdmaChLli = pHalGdmaAdapter->pLlix->pNextLli; + pGdmaChBkLi = pHalGdmaAdapter->pBlockSizeList; + + + //4 1) Check chanel is avaliable + if (HAL_GDMAX_READ32(GdmaIndex, REG_GDMA_CH_EN) & ChEn) { + //4 Disable Channel + DBG_GDMA_WARN("Channel had used; Disable Channel!\n"); + + HalGdmaChDisRtl8195a(Data); + + } + + //4 2) Check if there are the pending isr; TFR, Block, Src Tran, Dst Tran, Error + for (PendingIsrIndex=0; PendingIsrIndex<5;PendingIsrIndex++) { + + u32 PendRaw, PendStstus; + PendRaw = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_RAW_INT_BASE + PendingIsrIndex*8)); + PendStstus = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_STATUS_INT_BASE + PendingIsrIndex*8)); + + if ((PendRaw & GdmaChIsrBitmap) || (PendStstus & GdmaChIsrBitmap)) { + //4 Clear Pending Isr + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CLEAR_INT_BASE + PendingIsrIndex*8), + (PendStstus & (GdmaChIsrBitmap)) + ); + + } + } + + //4 Fill in SARx register + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_SAR + ChNum*REG_GDMA_CH_OFF), + (pHalGdmaAdapter->ChSar) + ); + + + //4 Fill in DARx register + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_DAR + ChNum*REG_GDMA_CH_OFF), + (pHalGdmaAdapter->ChDar) + ); + + + + //4 3) Process CTLx + CtlxLow = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_CTL + ChNum*REG_GDMA_CH_OFF)); + + //4 Clear Config low register bits + CtlxLow &= (BIT_INVC_CTLX_LO_INT_EN & + BIT_INVC_CTLX_LO_DST_TR_WIDTH & + BIT_INVC_CTLX_LO_SRC_TR_WIDTH & + BIT_INVC_CTLX_LO_DINC & + BIT_INVC_CTLX_LO_SINC & + BIT_INVC_CTLX_LO_DEST_MSIZE & + BIT_INVC_CTLX_LO_SRC_MSIZE & + BIT_INVC_CTLX_LO_TT_FC & + BIT_INVC_CTLX_LO_LLP_DST_EN & + BIT_INVC_CTLX_LO_LLP_SRC_EN); + + CtlxUp = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_CTL + ChNum*REG_GDMA_CH_OFF + 4)); + + //4 Clear Config upper register bits + CtlxUp &= (BIT_INVC_CTLX_UP_BLOCK_BS & + BIT_INVC_CTLX_UP_DONE); + + + CtlxLow = BIT_CTLX_LO_INT_EN(pHalGdmaAdapter->GdmaCtl.IntEn) | + BIT_CTLX_LO_DST_TR_WIDTH(pHalGdmaAdapter->GdmaCtl.DstTrWidth) | + BIT_CTLX_LO_SRC_TR_WIDTH(pHalGdmaAdapter->GdmaCtl.SrcTrWidth) | + BIT_CTLX_LO_DINC(pHalGdmaAdapter->GdmaCtl.Dinc) | + BIT_CTLX_LO_SINC(pHalGdmaAdapter->GdmaCtl.Sinc) | + BIT_CTLX_LO_DEST_MSIZE(pHalGdmaAdapter->GdmaCtl.DestMsize) | + BIT_CTLX_LO_SRC_MSIZE(pHalGdmaAdapter->GdmaCtl.SrcMsize) | + BIT_CTLX_LO_TT_FC(pHalGdmaAdapter->GdmaCtl.TtFc) | + BIT_CTLX_LO_LLP_DST_EN(pHalGdmaAdapter->GdmaCtl.LlpDstEn) | + BIT_CTLX_LO_LLP_SRC_EN(pHalGdmaAdapter->GdmaCtl.LlpSrcEn) | + CtlxLow; + + CtlxUp = BIT_CTLX_UP_BLOCK_BS(pGdmaChBkLi->BlockSize) | + BIT_CTLX_UP_DONE(pHalGdmaAdapter->GdmaCtl.Done) | + CtlxUp; + + //4 Fill in CTLx register + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_CTL + ChNum*REG_GDMA_CH_OFF), + CtlxLow + ); + + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_CTL + ChNum*REG_GDMA_CH_OFF +4), + CtlxUp + ); + + //4 4) Program CFGx + + CfgxLow = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_CFG + ChNum*REG_GDMA_CH_OFF)); + + CfgxLow &= (BIT_INVC_CFGX_LO_CH_PRIOR & + BIT_INVC_CFGX_LO_CH_SUSP & + BIT_INVC_CFGX_LO_HS_SEL_DST & + BIT_INVC_CFGX_LO_HS_SEL_SRC & + BIT_INVC_CFGX_LO_LOCK_CH_L & + BIT_INVC_CFGX_LO_LOCK_B_L & + BIT_INVC_CFGX_LO_LOCK_CH & + BIT_INVC_CFGX_LO_LOCK_B & + BIT_INVC_CFGX_LO_RELOAD_SRC & + BIT_INVC_CFGX_LO_RELOAD_DST); + + CfgxUp = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_CFG + ChNum*REG_GDMA_CH_OFF + 4)); + + CfgxUp &= (BIT_INVC_CFGX_UP_FIFO_MODE & + BIT_INVC_CFGX_UP_DS_UPD_EN & + BIT_INVC_CFGX_UP_SS_UPD_EN & + BIT_INVC_CFGX_UP_SRC_PER & + BIT_INVC_CFGX_UP_DEST_PER); + + CfgxLow = BIT_CFGX_LO_CH_PRIOR(pHalGdmaAdapter->GdmaCfg.ChPrior) | + BIT_CFGX_LO_CH_SUSP(pHalGdmaAdapter->GdmaCfg.ChSusp) | + BIT_CFGX_LO_HS_SEL_DST(pHalGdmaAdapter->GdmaCfg.HsSelDst) | + BIT_CFGX_LO_HS_SEL_SRC(pHalGdmaAdapter->GdmaCfg.HsSelSrc) | + BIT_CFGX_LO_LOCK_CH_L(pHalGdmaAdapter->GdmaCfg.LockChL) | + BIT_CFGX_LO_LOCK_B_L(pHalGdmaAdapter->GdmaCfg.LockBL) | + BIT_CFGX_LO_LOCK_CH(pHalGdmaAdapter->GdmaCfg.LockCh) | + BIT_CFGX_LO_LOCK_B(pHalGdmaAdapter->GdmaCfg.LockB) | + BIT_CFGX_LO_RELOAD_SRC(pHalGdmaAdapter->GdmaCfg.ReloadSrc) | + BIT_CFGX_LO_RELOAD_DST(pHalGdmaAdapter->GdmaCfg.ReloadDst) | + CfgxLow; + + CfgxUp = BIT_CFGX_UP_FIFO_MODE(pHalGdmaAdapter->GdmaCfg.FifoMode) | + BIT_CFGX_UP_DS_UPD_EN(pHalGdmaAdapter->GdmaCfg.DsUpdEn) | + BIT_CFGX_UP_SS_UPD_EN(pHalGdmaAdapter->GdmaCfg.SsUpdEn) | + BIT_CFGX_UP_SRC_PER(pHalGdmaAdapter->GdmaCfg.SrcPer) | + BIT_CFGX_UP_DEST_PER(pHalGdmaAdapter->GdmaCfg.DestPer) | + CfgxUp; + + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_CFG + ChNum*REG_GDMA_CH_OFF), + CfgxLow + ); + + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_CFG + ChNum*REG_GDMA_CH_OFF +4), + CfgxUp + ); + + + + //4 Check 4 Bytes Alignment + if ((u32)(pLliEle) & 0x3) { + DBG_GDMA_WARN("LLi Addr: 0x%x not 4 bytes alignment!\n", + pHalGdmaAdapter->pLli); + return _FALSE; + } + + HAL_GDMAX_WRITE32(GdmaIndex, + (REG_GDMA_CH_LLP + ChNum*REG_GDMA_CH_OFF), + pLliEle + ); + + //4 Update the first llp0 + pLliEle->CtlxLow = CtlxLow; + pLliEle->CtlxUp = CtlxUp; + pLliEle->Llpx = (u32)pGdmaChLli->pLliEle; + DBG_GDMA_INFO("Block Count %d\n", MultiBlockCount); + + pGdmaChBkLi = pGdmaChBkLi->pNextBlockSiz; + + while (MultiBlockCount > 1) { + MultiBlockCount--; + DBG_GDMA_INFO("Block Count %d\n", MultiBlockCount); + pLliEle = pGdmaChLli->pLliEle; + + if (NULL == pLliEle) { + DBG_GDMA_ERR("pLliEle Null Point!\n"); + return _FALSE; + } + + //4 Clear the last element llp enable bit + if (1 == MultiBlockCount) { + if (((pHalGdmaAdapter->Rsvd4to7) & 0x01) == 1){ + CtlxLow &= (BIT_INVC_CTLX_LO_LLP_DST_EN & + BIT_INVC_CTLX_LO_LLP_SRC_EN); + } + } + //4 Update block size for transfer + CtlxUp &= (BIT_INVC_CTLX_UP_BLOCK_BS); + CtlxUp |= BIT_CTLX_UP_BLOCK_BS(pGdmaChBkLi->BlockSize); + + //4 Update tje Lli and Block size list point to next llp + pGdmaChLli = pGdmaChLli->pNextLli; + pGdmaChBkLi = pGdmaChBkLi->pNextBlockSiz; + + //4 Updatethe Llpx context + pLliEle->CtlxLow = CtlxLow; + pLliEle->CtlxUp = CtlxUp; + pLliEle->Llpx = (u32)(pGdmaChLli->pLliEle); + + } + + return _TRUE; +} + +u32 +HalGdmaQueryDArRtl8195a( + IN VOID *Data +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + u8 GdmaIndex = pHalGdmaAdapter->GdmaIndex; + u8 ChNum = pHalGdmaAdapter->ChNum; + u32 dar; + + dar = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_DAR + ChNum*REG_GDMA_CH_OFF)); + + return dar; +} + +u32 +HalGdmaQuerySArRtl8195a( + IN VOID *Data +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + u8 GdmaIndex = pHalGdmaAdapter->GdmaIndex; + u8 ChNum = pHalGdmaAdapter->ChNum; + u32 dar; + + dar = HAL_GDMAX_READ32(GdmaIndex, + (REG_GDMA_CH_SAR + ChNum*REG_GDMA_CH_OFF)); + + return dar; +} + +BOOL +HalGdmaQueryChEnRtl8195a ( + IN VOID *Data +) +{ + + PHAL_GDMA_ADAPTER pHalGdmaAdapter = Data; + + if (HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, REG_GDMA_CH_EN) & (pHalGdmaAdapter->ChEn)) { + return 1; + } else { + return 0; + } +} + +#endif +#endif // CONFIG_GDMA_EN + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gpio.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gpio.c new file mode 100644 index 0000000..eb89fe4 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gpio.c @@ -0,0 +1,56 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "hal_gpio.h" +#include "rtl8195a_gpio.h" +#include "gpio_irq_api.h" + +#ifdef CONFIG_GPIO_EN + +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; + +/** + * @brief Clear the pending interrupt of a specified pin + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval None + */ +HAL_Status +HAL_GPIO_ClearISR_8195a( + HAL_GPIO_PIN *GPIO_Pin +) +{ + u8 port_num; + u8 pin_num; + HAL_GPIO_PIN_MODE pin_mode; + + port_num = HAL_GPIO_GET_PORT_BY_NAME(GPIO_Pin->pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(GPIO_Pin->pin_name); + pin_mode = GPIO_Pin->pin_mode; + + if ((pin_mode & HAL_GPIO_PIN_INT_MODE)==0 || (port_num != GPIO_PORT_A)) { + DBG_GPIO_WARN("HAL_GPIO_ClearISR_8195a: This pin(%x:%x) is'nt an interrupt pin\n", GPIO_Pin->pin_name, GPIO_Pin->pin_mode); + return HAL_ERR_PARA; + } + + if (GPIO_Lock() != HAL_OK) { + return HAL_BUSY; + } + + // Clear pending interrupt before unmask it + HAL_WRITE32(GPIO_REG_BASE, GPIO_PORTA_EOI, (1<I2CIdx; + u8 *pDat = pHalI2CInitData->I2CRWData; + u8 I2CCmd = pHalI2CInitData->I2CCmd; + u8 I2CStop = pHalI2CInitData->I2CStop; + u8 I2CReSTR= pHalI2CInitData->I2CReSTR; + + DBG_I2C_INFO("HalI2CSendRtl8195a\n"); + DBG_I2C_INFO("I2C Index: %x\n",I2CIdx); + + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DATA_CMD, + *(pDat) | + BIT_CTRL_IC_DATA_CMD_RESTART(I2CReSTR)| + BIT_CTRL_IC_DATA_CMD_CMD(I2CCmd) | + BIT_CTRL_IC_DATA_CMD_STOP(I2CStop)); + + return (HAL_OK); +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CInit8195a +// +// Description: +// To initialize I2C module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +HAL_Status +HalI2CMassSendRtl8195a_Patch( + IN VOID *Data +){ + PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data; + + u8 I2CIdx = pHalI2CInitData->I2CIdx; + u8 I2CCmd = pHalI2CInitData->I2CCmd; + u8 I2CDatLen = pHalI2CInitData->I2CDataLen; + u8 *pDat = pHalI2CInitData->I2CRWData; + u8 I2CStopSet = pHalI2CInitData->I2CStop; + u8 I2CSTP; + u8 I2CReSRT = 0; + u8 DatCnt = 0; + + /* Send I2C data one by one. The STOP bit is only used for the last byte.*/ + for (DatCnt = 0; DatCnt < I2CDatLen; DatCnt++) + { + I2CSTP = 0; + if ((DatCnt == (I2CDatLen - 1)) && (I2CStopSet != 0)) { + I2CSTP = 1; + } + + if ((DatCnt == 0) && ((pHalI2CInitData->RSVD0 & BIT0) != 0)) { + I2CReSRT = 1; + } + else { + I2CReSRT = 0; + } + + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DATA_CMD, + *(pDat+DatCnt) | + BIT_CTRL_IC_DATA_CMD_CMD(I2CCmd) | + BIT_CTRL_IC_DATA_CMD_RESTART(I2CReSRT) | + BIT_CTRL_IC_DATA_CMD_STOP(I2CSTP)); + } + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CInit8195a +// +// Description: +// To initialize I2C module by using the given data. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the DeInit process. +// _EXIT_SUCCESS if the initialization succeeded. +// _EXIT_FAILURE if the initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +HAL_Status +HalI2CInit8195a_Patch( + IN VOID *Data +) +{ + PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data; + + u8 Master; + u8 I2CIdx; + u8 SpdMd; + u8 AddrMd; + u8 ReSTR; + u8 StartByte; + u8 Specical; + u8 GC; + u16 I2CAckAddr; + u16 SdaHd; + u8 SdaSetup; + u8 RXTL; + u8 TXTL; + u8 SlvNoAck; + u32 INTRMsk; + u8 TxDMARqLv; + u8 RxDMARqLv; + u32 I2CTmp; + + /* Get the I2C parameters*/ + I2CIdx = pHalI2CInitData->I2CIdx; + SpdMd = pHalI2CInitData->I2CSpdMod; + AddrMd = pHalI2CInitData->I2CAddrMod; + I2CAckAddr = pHalI2CInitData->I2CAckAddr; + Master = pHalI2CInitData->I2CMaster; + SdaHd = pHalI2CInitData->I2CSdaHd; + SdaSetup = pHalI2CInitData->I2CSetup; + + ReSTR = pHalI2CInitData->I2CReSTR; + GC = pHalI2CInitData->I2CGC; + StartByte = pHalI2CInitData->I2CStartB; + SlvNoAck = pHalI2CInitData->I2CSlvNoAck; + + RXTL = pHalI2CInitData->I2CRXTL; + TXTL = pHalI2CInitData->I2CTXTL; + + TxDMARqLv = pHalI2CInitData->I2CTxDMARqLv; + RxDMARqLv = pHalI2CInitData->I2CRxDMARqLv; + + /* Disable the IC first */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_ENABLE,BIT_CTRL_IC_ENABLE(0)); + + /* Master case*/ + if (Master) { + /*RESTART MUST be set in these condition in Master mode. + But it might be NOT compatible in old slaves.*/ + if ((AddrMd == I2C_ADDR_10BIT) || (SpdMd == I2C_HS_MODE)) + ReSTR = 1; + + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_CON, + (BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(1) | + BIT_CTRL_IC_CON_IC_RESTART_EN(ReSTR) | + BIT_CTRL_IC_CON_IC_10BITADDR_MASTER(AddrMd) | + BIT_CTRL_IC_CON_SPEED(SpdMd) | + BIT_CTRL_IC_CON_MASTER_MODE(Master))); + + DBG_I2C_INFO("Init master, IC_CON%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_CON, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON)); + + + /* To set target addr.*/ + Specical = 0; + if ((GC!=0) || (StartByte!=0)) + Specical = 1; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_TAR, + (BIT_CTRL_IC_TAR_IC_10BITADDR_MASTER(AddrMd) | + BIT_CTRL_IC_TAR_SPECIAL(Specical) | + BIT_CTRL_IC_TAR_GC_OR_START(StartByte) | + BIT_CTRL_IC_TAR(I2CAckAddr))); + + /* To Set I2C clock*/ + HalI2CSetCLKRtl8195a_Patch(pHalI2CInitData); + + + DBG_I2C_INFO("Init master, IC_TAR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_TAR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_TAR)); + + } /*if (Master)*/ + else { + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_CON, + BIT_CTRL_IC_CON_IC_10BITADDR_SLAVE(AddrMd) | + BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(Master) | + BIT_CTRL_IC_CON_SPEED(SpdMd)| + BIT_CTRL_IC_CON_MASTER_MODE(Master)); + + DBG_I2C_INFO("Init slave, IC_CON%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_CON, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON)); + + + /* To set slave addr. */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SAR,BIT_CTRL_IC_SAR(I2CAckAddr)); + + DBG_I2C_INFO("Init slave, IC_SAR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_SAR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SAR)); + + + /* To set slave no ack */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SLV_DATA_NACK_ONLY,BIT_CTRL_IC_SLV_DATA_NACK_ONLY(SlvNoAck)); + + /* Set ack general call. */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_ACK_GENERAL_CALL,BIT_CTRL_IC_ACK_GENERAL_CALL(pHalI2CInitData->I2CSlvAckGC)); + + + + DBG_I2C_INFO("Init slave, I2C_IC_ACK_GC%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_ACK_GENERAL_CALL, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_ACK_GENERAL_CALL)); + + /* to set SDA hold time */ + //HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd)); + //4 + /* to set SDA setup time */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_SETUP,BIT_CTRL_IC_SDA_SETUP(SdaSetup)); + } + + /* to set SDA hold time */ + INTRMsk = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_CON); + if (BIT_GET_IC_CON_SPEED(INTRMsk) == I2C_SS_MODE) { + I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT); + } else if (BIT_GET_IC_CON_SPEED(INTRMsk) == I2C_FS_MODE) { + I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT); + } else { + I2CTmp = HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT); + } + + if (Master) { + if (SdaHd > (I2CTmp -2)) { + I2CTmp = I2CTmp -2; + if (I2CTmp < 1) { + I2CTmp = 1 + 1; + } + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(I2CTmp)); + } else { + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd)); + } + } else { + if (SdaHd > (I2CTmp -2)) { + I2CTmp = I2CTmp -2; + if (I2CTmp < 7) { + I2CTmp = 7 + 1; + } + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(I2CTmp)); + } else { + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD,BIT_CTRL_IC_SDA_HOLD(SdaHd)); + } + } + //DBG_8195A("SDA:%x\n", HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SDA_HOLD)); + + /* To set TX_Empty Level */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_TX_TL,TXTL); + + /* To set RX_Full Level */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_RX_TL,RXTL); + + /* To set TX/RX FIFO level */ + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DMA_TDLR,TxDMARqLv); + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_DMA_RDLR,RxDMARqLv); + + + DBG_I2C_INFO("Init i2c dev, I2C_IC_DMA_TDLR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_DMA_TDLR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_DMA_TDLR)); + DBG_I2C_INFO("Init i2c dev, I2C_IC_DMA_RDLR%d[%2x]: %x\n", I2CIdx, REG_DW_I2C_IC_DMA_RDLR, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_DMA_RDLR)); + + + /*I2C Clear all interrupts first*/ + HalI2CClrAllIntrRtl8195a(pHalI2CInitData); + + /*I2C Disable all interrupts first*/ + INTRMsk = pHalI2CInitData->I2CIntrMSK; + pHalI2CInitData->I2CIntrMSK = 0; + HalI2CIntrCtrl8195a(pHalI2CInitData); + pHalI2CInitData->I2CIntrMSK = INTRMsk; + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// HalI2CSetCLKRtl8195a +// +// Description: +// To set I2C bus clock rate. +// +// Arguments: +// [in] VOID *Data - +// The I2C parameter data struct. +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the de-initialization succeeded. +// _EXIT_FAILURE if the de-initialization failed. +// +// Note: +// None +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-02-18. +// +//--------------------------------------------------------------------------------------------------- +HAL_Status +HalI2CSetCLKRtl8195a_Patch( + IN VOID *Data +) +{ + PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data; + u8 SpdMd = pHalI2CInitData->I2CSpdMod; + u32 I2CClk = pHalI2CInitData->I2CClk; + u8 I2CIdx = pHalI2CInitData->I2CIdx; + u32 ICHLcnt; + u32 ICHtime; + u32 ICLtime; + + /* Get the IC-Clk setting first for the following process*/ +#ifdef CONFIG_FPGA + u32 IcClk = SYSTEM_CLK/1000000; +#else + u32 IcClk; + u32 ClkSELTmp = 0; + u32 CpuClkTmp = 0; + + #if defined(CONFIG_CHIP_A_CUT) + CpuClkTmp = StartupHalGetCpuClk(); + #elif (defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT)) + CpuClkTmp = HalGetCpuClk(); + #endif + + DBG_I2C_INFO("%s, CPU Clk:%x\n",__func__, CpuClkTmp); + + ClkSELTmp = HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_SEL); + ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3))); + HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp); + IcClk = (CpuClkTmp/1000000)>>1; + +#if 0 + if ((I2CClk > 0) && (I2CClk <= 400)) { + ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3))); + HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp); + IcClk = ClkSELTmp/1000000; /*actually it's 12.5MHz*/ + } + else { + ClkSELTmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3))); + HAL_WRITE32(PERI_ON_BASE,REG_PESOC_CLK_SEL,ClkSELTmp); + IcClk = 100; + } +#endif +#endif + + switch (SpdMd) + { + case I2C_SS_MODE: + { + ICHtime = ((1000000/I2CClk)*I2C_SS_MIN_SCL_HTIME)/(I2C_SS_MIN_SCL_HTIME+I2C_SS_MIN_SCL_LTIME); + ICLtime = ((1000000/I2CClk)*I2C_SS_MIN_SCL_LTIME)/(I2C_SS_MIN_SCL_HTIME+I2C_SS_MIN_SCL_LTIME); + + ICHLcnt = (ICHtime * IcClk)/1000; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_SS_SCL_HCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_SS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT)); + + + ICHLcnt = (ICLtime * IcClk)/1000; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_SS_SCL_LCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_SS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT)); + + break; + } + + case I2C_FS_MODE: + { + ICHtime = ((1000000/I2CClk)*I2C_FS_MIN_SCL_HTIME)/(I2C_FS_MIN_SCL_HTIME+I2C_FS_MIN_SCL_LTIME); + ICLtime = ((1000000/I2CClk)*I2C_FS_MIN_SCL_LTIME)/(I2C_FS_MIN_SCL_HTIME+I2C_FS_MIN_SCL_LTIME); + + ICHLcnt = (ICHtime * IcClk)/1000; + if (ICHLcnt>4)/*this part is according to the fine-tune result*/ + ICHLcnt -= 4; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_FS_SCL_HCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_FS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT)); + + + ICHLcnt = (ICLtime * IcClk)/1000; + if (ICHLcnt>3)/*this part is according to the fine-tune result*/ + ICHLcnt -= 3; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_FS_SCL_LCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_FS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT)); + + break; + } + + case I2C_HS_MODE: + { + ICHLcnt = 400; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_HCNT,ICHLcnt); + + ICHLcnt = 470; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_SS_SCL_LCNT,ICHLcnt); + + ICHLcnt = 60; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_HCNT,ICHLcnt); + + ICHLcnt = 130; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_FS_SCL_LCNT,ICHLcnt); + + ICHtime = ((1000000/I2CClk)*I2C_HS_MIN_SCL_HTIME_100)/(I2C_HS_MIN_SCL_HTIME_100+I2C_HS_MIN_SCL_LTIME_100); + ICLtime = ((1000000/I2CClk)*I2C_HS_MIN_SCL_LTIME_100)/(I2C_HS_MIN_SCL_HTIME_100+I2C_HS_MIN_SCL_LTIME_100); + + + DBG_I2C_INFO("ICHtime:%x\n",ICHtime); + DBG_I2C_INFO("ICLtime:%x\n",ICLtime); + + + ICHLcnt = (ICHtime * IcClk)/1000; + if (ICHLcnt>8)/*this part is according to the fine-tune result*/ + ICHLcnt -= 3; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_HS_SCL_HCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_HS_SCL_HCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_HS_SCL_HCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_HCNT)); + + + ICHLcnt = (ICLtime * IcClk)/1000; + if (ICHLcnt>6)/*this part is according to the fine-tune result*/ + ICHLcnt -= 6; + HAL_I2C_WRITE32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT,ICHLcnt); + + + DBG_I2C_INFO("IC_HS_SCL_LCNT%d[%2x]: %x\n", I2CIdx, + REG_DW_I2C_IC_HS_SCL_LCNT, HAL_I2C_READ32(I2CIdx,REG_DW_I2C_IC_HS_SCL_LCNT)); + + + break; + } + + default: + break; + } + + return HAL_OK; +} + +HAL_Status +HalI2CEnableRtl8195a_Patch( + IN VOID *Data +){ + PHAL_I2C_INIT_DAT pHalI2CInitData = (PHAL_I2C_INIT_DAT)Data; + u8 I2CIdx = pHalI2CInitData->I2CIdx; + u8 I2CICEn = pHalI2CInitData->I2CEn; + u32 I2CTimeoutCount; + u32 I2CStartCount; + /* Enable I2C module */ + HAL_I2C_WRITE32(I2CIdx, REG_DW_I2C_IC_ENABLE, BIT_CTRL_IC_ENABLE(I2CICEn)); + + I2CTimeoutCount = ((10000/pHalI2CInitData->I2CClk) /TIMER_TICK_US) +1; + I2CStartCount = HalTimerOp.HalTimerReadCount(1); + + if (!I2CICEn) { + while (HAL_I2C_READ32(I2CIdx, REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN) { + if (HAL_TIMEOUT == I2CIsTimeout(I2CStartCount, I2CTimeoutCount)) { + return HAL_TIMEOUT; + } + } + } else { + while (!(HAL_I2C_READ32(I2CIdx, REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN)) { + if (HAL_TIMEOUT == I2CIsTimeout(I2CStartCount, I2CTimeoutCount)) { + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} +#endif + +#endif // CONFIG_I2C_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2s.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2s.c new file mode 100644 index 0000000..8417fe9 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2s.c @@ -0,0 +1,398 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_i2s.h" +#include "hal_i2s.h" + +#ifdef CONFIG_I2S_EN + +extern void * +_memset( void *s, int c, SIZE_T n ); + +RTK_STATUS +HalI2SInitRtl8195a_Patch( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + + u8 I2SIdx; + //u8 I2SEn; + u8 I2SMaster; + u8 I2SWordLen; + u8 I2SChNum; + u8 I2SPageNum; + u16 I2SPageSize; + u16 I2SRate; + u32 I2STxIntrMSK; + u32 I2SRxIntrMSK; + u8 I2STRxAct; + u8 *I2STxData; + u8 *I2SRxData; + + u32 Tmp; + + I2SIdx = pHalI2SInitData->I2SIdx; + //I2SEn = pHalI2SInitData->I2SEn; + I2SMaster = pHalI2SInitData->I2SMaster; + I2SWordLen = pHalI2SInitData->I2SWordLen; + I2SChNum = pHalI2SInitData->I2SChNum; + I2SPageNum = pHalI2SInitData->I2SPageNum; + I2SPageSize = pHalI2SInitData->I2SPageSize; + I2SRate = pHalI2SInitData->I2SRate; + I2STRxAct = pHalI2SInitData->I2STRxAct; + I2STxData = pHalI2SInitData->I2STxData; + I2SRxData = pHalI2SInitData->I2SRxData; + + + /* Disable the I2S first, and reset to default */ + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, BIT_CTRL_CTLX_I2S_EN(0) | + BIT_CTRL_CTLX_I2S_SW_RSTN(1)); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, BIT_CTRL_CTLX_I2S_EN(0) | + BIT_CTRL_CTLX_I2S_SW_RSTN(0)); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, BIT_CTRL_CTLX_I2S_EN(0) | + BIT_CTRL_CTLX_I2S_SW_RSTN(1)); + + Tmp = HAL_I2S_READ32(I2SIdx, REG_I2S_CTL); + Tmp |= BIT_CTRL_CTLX_I2S_ENDIAN_SWAP(1); + + if (I2SRate & 0x10) + { + Tmp |= BIT_CTRL_CTLX_I2S_CLK_SRC(1); + } + + Tmp |= (BIT_CTRL_CTLX_I2S_WL(I2SWordLen) | BIT_CTRL_CTLX_I2S_CH_NUM(I2SChNum) | + BIT_CTRL_CTLX_I2S_SLAVE_MODE(I2SMaster) | BIT_CTRL_CTLX_I2S_TRX_ACT(I2STRxAct)); + /* set 44.1khz clock source, word length, channel number, master or slave, trx act */ + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, Tmp); + + Tmp = BIT_CTRL_SETTING_I2S_PAGE_SZ(I2SPageSize) | BIT_CTRL_SETTING_I2S_PAGE_NUM(I2SPageNum) | + BIT_CTRL_SETTING_I2S_SAMPLE_RATE(I2SRate); + /* set page size, page number, sample rate */ + HAL_I2S_WRITE32(I2SIdx, REG_I2S_SETTING, Tmp); + + /* need tx rx buffer? need rx page own bit */ + if (I2STxData != NULL) { + HAL_I2S_WRITE32(I2SIdx, REG_I2S_TX_PAGE_PTR, (u32)I2STxData); + } + + if (I2SRxData != NULL) { + HAL_I2S_WRITE32(I2SIdx, REG_I2S_RX_PAGE_PTR, (u32)I2SRxData); + } + + pHalI2SInitData->I2STxIdx = 0; + pHalI2SInitData->I2SRxIdx = 0; + pHalI2SInitData->I2SHWTxIdx = 0; + pHalI2SInitData->I2SHWRxIdx = 0; + /* I2S Clear all interrupts first */ + HalI2SClrAllIntrRtl8195a(pHalI2SInitData); + + /* I2S Disable all interrupts first */ + I2STxIntrMSK = pHalI2SInitData->I2STxIntrMSK; + I2SRxIntrMSK = pHalI2SInitData->I2SRxIntrMSK; + pHalI2SInitData->I2STxIntrMSK = 0; + pHalI2SInitData->I2SRxIntrMSK = 0; + HalI2SIntrCtrlRtl8195a(pHalI2SInitData); + pHalI2SInitData->I2STxIntrMSK = I2STxIntrMSK; + pHalI2SInitData->I2SRxIntrMSK = I2SRxIntrMSK; + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetRateRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_CTL); + reg_value &= ~(BIT_MASK_CTLX_I2S_CLK_SRC << BIT_SHIFT_CTLX_I2S_CLK_SRC); + if (pHalI2SInitData->I2SRate & 0x10) + { + reg_value |= BIT_CTRL_CTLX_I2S_CLK_SRC(1); + } + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, reg_value); + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_SETTING); + reg_value &= ~(BIT_MASK_SETTING_I2S_SAMPLE_RATE << BIT_SHIFT_SETTING_I2S_SAMPLE_RATE); + reg_value |= BIT_CTRL_SETTING_I2S_SAMPLE_RATE(pHalI2SInitData->I2SRate); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_SETTING, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetWordLenRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_CTL); + reg_value &= ~(BIT_MASK_CTLX_I2S_WL << BIT_SHIFT_CTLX_I2S_WL); + reg_value |= BIT_CTRL_CTLX_I2S_WL(pHalI2SInitData->I2SWordLen); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetChNumRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_CTL); + reg_value &= ~(BIT_MASK_CTLX_I2S_CH_NUM << BIT_SHIFT_CTLX_I2S_CH_NUM); + reg_value |= BIT_CTRL_CTLX_I2S_CH_NUM(pHalI2SInitData->I2SChNum); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetPageNumRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_SETTING); + reg_value &= ~(BIT_MASK_SETTING_I2S_PAGE_NUM << BIT_SHIFT_SETTING_I2S_PAGE_NUM); + reg_value |= BIT_CTRL_SETTING_I2S_PAGE_NUM(pHalI2SInitData->I2SPageNum); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_SETTING, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetPageSizeRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_SETTING); + reg_value &= ~(BIT_MASK_SETTING_I2S_PAGE_SZ << BIT_SHIFT_SETTING_I2S_PAGE_SZ); + reg_value |= BIT_CTRL_SETTING_I2S_PAGE_SZ(pHalI2SInitData->I2SPageSize); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_SETTING, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetDirectionRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_CTL); + reg_value &= ~(BIT_MASK_CTLX_I2S_TRX_ACT << BIT_SHIFT_CTLX_I2S_TRX_ACT); + reg_value |= BIT_CTRL_CTLX_I2S_TRX_ACT(pHalI2SInitData->I2STRxAct); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_CTL, reg_value); + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SSetDMABufRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 reg_value; + u32 page_num; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg_value = HAL_I2S_READ32(I2SIdx, REG_I2S_SETTING); + reg_value &= ~(BIT_MASK_SETTING_I2S_PAGE_SZ << BIT_SHIFT_SETTING_I2S_PAGE_SZ); + reg_value &= ~(BIT_MASK_SETTING_I2S_PAGE_NUM << BIT_SHIFT_SETTING_I2S_PAGE_NUM); + reg_value |= BIT_CTRL_SETTING_I2S_PAGE_SZ(pHalI2SInitData->I2SPageSize); + reg_value |= BIT_CTRL_SETTING_I2S_PAGE_NUM(pHalI2SInitData->I2SPageNum); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_SETTING, reg_value); + + page_num = pHalI2SInitData->I2SPageNum + 1; + if (pHalI2SInitData->I2STxData) { + HAL_I2S_WRITE32(I2SIdx, REG_I2S_TX_PAGE_PTR, (uint32_t)pHalI2SInitData->I2STxData); + pHalI2SInitData->I2STxIntrMSK = (1<I2STxIntrMSK = 0; + } + + if (pHalI2SInitData->I2SRxData) { + HAL_I2S_WRITE32(I2SIdx, REG_I2S_RX_PAGE_PTR, (uint32_t)pHalI2SInitData->I2SRxData); + pHalI2SInitData->I2SRxIntrMSK = (1<I2SRxIntrMSK = 0; + + } + + // According to the page number to modify the ISR mask + HalI2SIntrCtrlRtl8195a(pHalI2SInitData); + + return _EXIT_SUCCESS; +} + +u8 +HalI2SGetTxPageRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + + u8 I2SIdx; + u16 I2STxIdx = pHalI2SInitData->I2STxIdx; + u32 reg; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg = HAL_I2S_READ32(I2SIdx, REG_I2S_TX_PAGE0_OWN+(I2STxIdx<<2)); + if ((reg & (1<<31)) == 0) { + return I2STxIdx; + } else { + return 0xFF; + } +} + +u8 +HalI2SGetRxPageRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + + u8 I2SIdx; + u16 I2SRxIdx = pHalI2SInitData->I2SRxIdx; + u32 reg; + + I2SIdx = pHalI2SInitData->I2SIdx; + + reg = HAL_I2S_READ32(I2SIdx, REG_I2S_RX_PAGE0_OWN+(I2SRxIdx << 2)); + if ((reg & (1<<31)) == 0) { + return I2SRxIdx; + } else { + return 0xFF; + } +} + +RTK_STATUS +HalI2SPageSendRtl8195a( + IN VOID *Data, + IN u8 PageIdx +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u16 I2STxIdx = pHalI2SInitData->I2STxIdx; + u8 I2SPageNum = pHalI2SInitData->I2SPageNum; + u8 I2SIdx; + + if (I2STxIdx != PageIdx) { + DBG_I2S_ERR("HalI2SPageSendRtl8195a: UnExpected Page Index. TxPage=%d, Expected:%d\r\n", + PageIdx, I2STxIdx); + } + + I2SIdx = pHalI2SInitData->I2SIdx; + + HAL_I2S_WRITE32(I2SIdx, REG_I2S_TX_PAGE0_OWN + 4 * PageIdx, BIT_PAGE_I2S_OWN_BIT); + I2STxIdx = PageIdx + 1; + if (I2STxIdx > I2SPageNum) { + I2STxIdx = 0; + } + pHalI2SInitData->I2STxIdx = I2STxIdx; + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SPageRecvRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u16 I2SRxIdx = pHalI2SInitData->I2SRxIdx; + u8 I2SPageNum = pHalI2SInitData->I2SPageNum; + u32 reg; + u8 I2SIdx; + + I2SIdx = pHalI2SInitData->I2SIdx; + reg = HAL_I2S_READ32(I2SIdx, REG_I2S_RX_PAGE0_OWN+(I2SRxIdx << 2)); + if ((reg & (1<<31)) != 0) { + DBG_I2S_ERR("HalI2SPageRecvRtl8195a: No Idle Rx Page\r\n"); + return _EXIT_FAILURE; + } + + HAL_I2S_WRITE32(I2SIdx, REG_I2S_RX_PAGE0_OWN+(I2SRxIdx<<2), 1<<31); + I2SRxIdx += 1; + if (I2SRxIdx > I2SPageNum) { + I2SRxIdx = 0; + } + pHalI2SInitData->I2SRxIdx = I2SRxIdx; + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SClearAllOwnBitRtl8195a( + IN VOID *Data +) +{ + PHAL_I2S_INIT_DAT pHalI2SInitData = (PHAL_I2S_INIT_DAT)Data; + u8 I2SIdx; + u32 i; + + I2SIdx = pHalI2SInitData->I2SIdx; + + for (i=0;i<4;i++) { + HAL_I2S_WRITE32(I2SIdx, REG_I2S_TX_PAGE0_OWN+(i<<2), 0); + HAL_I2S_WRITE32(I2SIdx, REG_I2S_RX_PAGE0_OWN+(i<<2), 0); + } + + return _EXIT_SUCCESS; +} + +RTK_STATUS +HalI2SDMACtrlRtl8195a( + IN VOID *Data +) +{ + + return _EXIT_SUCCESS; +} + +#endif // CONFIG_I2S_EN + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_mii.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_mii.c new file mode 100644 index 0000000..dc4af97 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_mii.c @@ -0,0 +1,1082 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "rtl8195a_mii.h" +#include "hal_mii.h" +#include "osdep_api.h" +//#include "hal_gdma.h" + +#ifdef CONFIG_MII_EN + +volatile u8 *pTxDataBuf = NULL; +volatile u8 *pRxDataBuf = NULL; + +#if 0 +volatile TX_DESC_FMT TxDesc[MII_TX_DESC_NO]; +volatile RX_DESC_FMT RxDesc[MII_RX_DESC_NO]; +volatile u32 TxDescIdx = 0; +volatile u32 TxBufIdx = 0; +volatile u32 RxDescIdx = 0; +volatile u32 RxBufIdx = 0; +volatile u8 isTxDone = 0; +volatile u8 isRxDone = 0; +volatile u32 CurrDataLen = 0; +volatile u32 ReadDescIdx = 0; +volatile u32 ReadBufIdx = 0; +volatile u32 CurrSentSize = 0; +volatile u32 CurrReceivedSize = 0; +#endif + +// by jimmy + +volatile PTX_DESC_FMT TxDesc; +volatile PRX_DESC_FMT RxDesc; + +volatile u8 TxDescWrPtr = 0; +volatile u8 RxDescRdPtr = 0; + +volatile u32 CurrDataLen = 0; +#if 0 +HAL_GDMA_OBJ gdmaObj; +u8 isGdmaAllocated; +volatile u8 isDmaDone; +#endif +extern HAL_ETHER_ADAPTER HalEtherAdp; + + + +VOID Mii_ISR( + IN VOID *Data +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER) Data; + volatile u32 RegValue = HAL_MII_READ32(REG_MII_ISRIMR); + + + if((RegValue & ISR_RXOK) && ((pEthAdapter->InterruptMask) & IMR_RXOK)) + { + /* Disable interrupt and enbale again when the rx descriptor ring is empty */ + pEthAdapter->InterruptMask &= (~IMR_RXOK); + + if(pEthAdapter->CallBack != NULL) + { + pEthAdapter->CallBack(ETH_RXDONE, 0); // receive size is meanless here + } + } + + if((RegValue & ISR_RER_OVF) && ((pEthAdapter->InterruptMask) & IMR_RER_OVF)) + { + DBG_MII_WARN("ISR_RER_OVF 0x%08X \n", RegValue); + + /* Ignore this interrupt, rx thread will clean the OWN bit */ + pEthAdapter->InterruptMask &= (~ISR_RER_OVF); + } + + if((RegValue & ISR_TXOK) && ((pEthAdapter->InterruptMask) & IMR_TXOK)) + { + /* Disable TxOK interrupt */ + pEthAdapter->InterruptMask &= (~IMR_TXOK); + /* User callback function */ + if(pEthAdapter->CallBack != NULL) + { + pEthAdapter->CallBack(ETH_TXDONE, 0); + } + } + + if((RegValue & ISR_LINKCHG) && ((pEthAdapter->InterruptMask) & IMR_LINKCHG)) + { + if(pEthAdapter->CallBack != NULL) + { + if(HAL_MII_READ32(REG_MII_MS) & MS_LINKB) + { + pEthAdapter->CallBack(ETH_LINKDOWN, 0); + } + else + { + pEthAdapter->CallBack(ETH_LINKUP, 0); + } + } + } + + HAL_MII_WRITE32(REG_MII_ISRIMR, (pEthAdapter->InterruptMask) | ISR_CLR_ALL); +} + + +u16 +HalMiiRwPhyRegRtl8195a(u8 Operation, u8 Address, u16 Data) +{ + u32 tmp; + + + tmp = (Operation << 31) | ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((Address << 16) & MIIA_PHY_REG_ADDR_MASK) | Data; + HAL_MII_WRITE32(REG_MII_MIIA, tmp); + HalDelayUs(1000); + + if(Operation) + { + /* Wait for write operation is completed */ + do { + }while(HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG); + + return 0; + } + else + { + /* Wait for read operation is completed */ + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + return (u16)(HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF); + } +} + + +VOID +HalMiiInitIrqRtl8195a( + IN VOID *Data +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER) Data; + PIRQ_HANDLE pMiiIrqHandle = &(pEthAdapter->IrqHandle); + + + if(pEthAdapter == NULL) + DBG_MII_ERR("pEthAdapter is NULL!\n"); + + pMiiIrqHandle->Data = (u32) pEthAdapter; + pMiiIrqHandle->IrqNum = GMAC_IRQ; + pMiiIrqHandle->IrqFun = (IRQ_FUN) Mii_ISR; + pMiiIrqHandle->Priority = 6; + InterruptRegister(pMiiIrqHandle); + InterruptEn(pMiiIrqHandle); +} + + +static VOID +HalMiiDeInitIrqRtl8195a( + IN VOID *Data +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER) Data; + IRQ_HANDLE MiiIrqHandle; + + + if(pEthAdapter == NULL) + DBG_8195A("pEthAdapter is NULL!\n"); + + /* Clear all interrupt status */ + HAL_MII_WRITE32(REG_MII_ISRIMR, ISR_CLR_ALL); + + MiiIrqHandle.Data = (u32) pEthAdapter; + MiiIrqHandle.IrqNum = GMAC_IRQ; + MiiIrqHandle.IrqFun = (IRQ_FUN) Mii_ISR; + MiiIrqHandle.Priority = 6; + InterruptDis(&MiiIrqHandle); + InterruptUnRegister(&MiiIrqHandle); +} + +#if 0 +void Mii_DmaDone_ISR(u32 id) +{ + isDmaDone = 1; +} +#endif + +s32 +HalMiiInitRtl8195a( + IN VOID +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER)&HalEtherAdp; + u32 regVal = 0; + u8 macAddr[6]; + u32 i = 0; + u16 ret; + + + if((!(pEthAdapter->tx_desc_num)) || (!(pEthAdapter->rx_desc_num))) + { + DBG_MII_ERR("Invalid Tx/Rx descriptor number!\n"); + return -1; + } + DBG_MII_INFO("Tx/Rx: %d/%d\n", pEthAdapter->tx_desc_num, pEthAdapter->rx_desc_num); + + regVal = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PINMUX_CTRL); + regVal &= ~(BIT_EEPROM_PIN_EN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PINMUX_CTRL, regVal); + + regVal = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PINMUX_CTRL); + regVal &= ~(BIT_SIC_PIN_EN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PINMUX_CTRL, regVal); + + SPI_FLASH_PIN_FCTRL(OFF); + + ACTCK_GPIO_CCTRL(ON); + SLPCK_GPIO_CCTRL(ON); + HAL_PERI_ON_WRITE32(REG_GPIO_SHTDN_CTRL, 0x7FF); + GPIO_FCTRL(ON); + + /* 1. enable MII Pinmux & disable SDIO Host/Device mode Pinmux */ + regVal = HAL_READ32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL); + regVal |= BIT24; + regVal &= ~(BIT0 | BIT1); // Important! + HAL_WRITE32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL, regVal); + + /* 2. enable MII IP block (214, 12) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN); + regVal |= BIT12; + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, regVal); + + /* 3. Lexra2AHB Function Enable (304, 11) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_PESOC_SOC_CTRL); + regVal |= BIT11; + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_SOC_CTRL, regVal); + + /* 4. enable MII bus clock (240, 24|25) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0); + regVal |= (BIT24 | BIT25); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, regVal); + + /* 5. */ + regVal = HAL_READ32(SYSTEM_CTRL_BASE, 0x74) & 0xFFFFC7FF; + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x74, (regVal | 0x00003000)); + + /* 6. AHB mux: select MII (214, 13) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN); + regVal |= BIT13; + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, regVal); + + /* 7. Vendor Register Clock Enable (230, 6|7) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_CTRL); + regVal |= (BIT6 | BIT7); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_CLK_CTRL, regVal); + + /* 8. Enable GMAC Lexra Timeout (090, 16|17|18) */ + regVal = HAL_READ32(VENDOR_REG_BASE, 0x0090); + regVal |= (BIT16 | BIT17 | BIT18); + HAL_WRITE32(VENDOR_REG_BASE, 0x0090, regVal); + + /* 9. Endian Swap Control (304, 12|13) */ + regVal = HAL_READ32(PERI_ON_BASE, REG_PESOC_SOC_CTRL); + regVal |= (BIT12 | BIT13); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_SOC_CTRL, regVal); + + HAL_MII_WRITE32(REG_MII_COM, (HAL_MII_READ32(REG_MII_COM) | COM_RST)); + + /* Tx settings */ + HAL_MII_WRITE32(REG_MII_TC, ((TC_IFG_TIME << 10) & TC_IFG_MASK) | ((TC_NORMAL_MODE << 8) & TC_LBK_MASK)); // Normal mode + + /* Rx settings */ + HalMiiGetMacAddressRtl8195a(macAddr); + HAL_MII_WRITE32(REG_MII_IDR0, (macAddr[0] << 24) | (macAddr[1] << 16) | (macAddr[2] << 8) | macAddr[3]); + HAL_MII_WRITE32(REG_MII_IDR4, (macAddr[4] << 24) | (macAddr[5] << 16)); + + HAL_MII_WRITE32(REG_MII_RC, RC_AER | RC_AR | RC_AB | RC_AM | RC_APM | RC_AAP); // Accept error/runt/broadcast/multicast, etc. + HAL_MII_WRITE32(REG_MII_COM, (HAL_MII_READ32(REG_MII_COM) | COM_RXJUMBO)); // Support jumbo packet receiving + HAL_MII_WRITE32(REG_MII_ETNRXCPU1, 0x01010100); + + TxDesc = (PTX_DESC_FMT)(pEthAdapter->TxDescAddr); + RxDesc = (PRX_DESC_FMT)(pEthAdapter->RxDescAddr); + if((TxDesc == NULL) || (RxDesc == NULL)) + { + DBG_MII_ERR("Invalid Tx/Rx descriptor address!\n"); + return -1; + } + + HAL_MII_WRITE32(REG_MII_TXFDP1, (u32)TxDesc); + HAL_MII_WRITE32(REG_MII_RXFDP1, (u32)RxDesc); + HAL_MII_WRITE32(REG_MII_IOCMD1, ((IOCMD1_DSC_FMT_EXTRA << 28) & IOCMD1_DSCFMTEXTRA_MASK) | + IOCMD1_EN_1GB); // Extra desc. format = 011, support 1GB addressing + HAL_MII_WRITE32(REG_MII_IOCMD, IOCMD_SHORT_DES_FMT | + ((IOCMD_TXFTH_256 << 19) & IOCMD_TXFTH_MASK) | + ((IOCMD_RXFTH_256 << 11) & IOCMD_RXFTH_MASK) | + IOCMD_TE); // short desc. format = 1, Tx & Rx FIFO threshold = 256 bytes, enable MII Tx + + /* Reset PHY */ + ret = HalMiiRwPhyRegRtl8195a(1, 0, PHY_SW_RESET); + while(1) + { + /* Check the reset status */ + ret = HalMiiRwPhyRegRtl8195a(0, 0, 0); + if(!(ret & PHY_SW_RESET)) + break; + } + /* Auto-Negotiation */ + HalMiiForceLinkRtl8195a(-1, -1); + + HalMiiInitIrqRtl8195a((VOID*)(&HalEtherAdp)); + HAL_WRITE32(0xE000E100, 0x0, 0x00040000); // enable external interrupt[18] (GMAC) + /* ISR & IMR */ + HalEtherAdp.InterruptMask = IMR_LINKCHG | IMR_TXOK | IMR_RER_OVF | IMR_RXOK | ISR_CLR_ALL; + HAL_MII_WRITE32(REG_MII_ISRIMR, HalEtherAdp.InterruptMask); + #if 0 + /* Init GDMA */ + gdmaObj.GdmaIrqHandle.IrqFun = (IRQ_FUN)Mii_DmaDone_ISR; + gdmaObj.GdmaIrqHandle.Data = (u32)(&gdmaObj); + isGdmaAllocated = HalGdmaMemCpyInit(&gdmaObj); + #endif + + pTxDataBuf = pEthAdapter->pTxPktBuf; + pRxDataBuf = pEthAdapter->pRxPktBuf; + if((pTxDataBuf == NULL) || (pRxDataBuf == NULL)) + { + DBG_MII_ERR("Invalid Tx/Rx packet buffer address!\n"); + return -1; + } + + /* Fill Tx descriptors */ + for(i = 0; i < (pEthAdapter->tx_desc_num); i++) + { + if(i == ((pEthAdapter->tx_desc_num) - 1)) + TxDesc[i].dw1 = TX_DESC_EOR; + TxDesc[i].addr = (u32)(pTxDataBuf + (i * MII_BUF_SIZE)); + TxDesc[i].dw2 = ((TX_DESC_VLAN_REMOVE << 25) & TX_DESC_VLAN_ACT_MASK) | (C_VLAN_HDR & TX_DESC_VLAN_TAG_MASK); + TxDesc[i].dw3 = 0; + TxDesc[i].dw4 = 0; + } + /* Fill Rx descriptors */ + for(i = 0; i < (pEthAdapter->rx_desc_num); i++) + { + if(i == ((pEthAdapter->rx_desc_num) - 1)) + RxDesc[i].dw1 = RX_DESC_OWN | RX_DESC_EOR | MII_BUF_SIZE; + else + RxDesc[i].dw1 = RX_DESC_OWN | MII_BUF_SIZE; + RxDesc[i].addr = (u32)(pRxDataBuf + (i * MII_BUF_SIZE)); + RxDesc[i].dw2 = 0; + RxDesc[i].dw3 = 0; + } + + #if 0 + // Reset flag + TxDescIdx = 0; + TxBufIdx = 0; + isTxDone = 0; + CurrDataLen = 0; + CurrSentSize = 0; + + RxDescIdx = 0; + RxBufIdx = 0; + isRxDone = 0; + + CurrReceivedSize = 0; + ReadBufIdx = 0; + #endif + HAL_MII_WRITE32(REG_MII_IOCMD, (HAL_MII_READ32(REG_MII_IOCMD) | IOCMD_RE)); // enable MII Rx + HalDelayUs(1000); + + DBG_8195A("Initialization is finished...\n"); + + return 0; +} + + +VOID +HalMiiDeInitRtl8195a( + IN VOID +) +{ + #if 0 + if (isGdmaAllocated) + HalGdmaMemCpyDeInit(&gdmaObj); + #endif + HalMiiDeInitIrqRtl8195a((VOID*)(&HalEtherAdp)); + HAL_WRITE32(0xE000E100, 0x0, (HAL_READ32(0xE000E100, 0x0) & (~BIT18))); // disable external interrupt[18] (GMAC) + + ACTCK_MII_MPHY_CCTRL(OFF); + SLPCK_MII_MPHY_CCTRL(OFF); + PinCtrl(MII, 0, OFF); + MII_FCTRL(OFF); +} + + +s32 +HalMiiWriteDataRtl8195a( + IN const char *Data, + IN u32 Size +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER)&HalEtherAdp ; + + + if((Data == NULL) || (Size == 0) || (Size > MAX_FRAME_SIZE)) + { + DBG_MII_ERR("Invalid parameter!\n"); + return -1; + } + + /* Check if current Tx descriptor is available */ + u8 tx_serach_idx = TxDescWrPtr; + if((((volatile u32)TxDesc[tx_serach_idx].dw1) & TX_DESC_OWN) == 0) + { + #if 1 + _memcpy((void*)(TxDesc[tx_serach_idx].addr), Data, Size); + #else + isDmaDone = 0; + HalGdmaMemCpy(&gdmaObj, (void*)(TxDesc[tx_serach_idx].addr), (void*)Data, Size); + while (isDmaDone == 0); + #endif + + TxDesc[tx_serach_idx].dw1 &= TX_DESC_EOR; // keep the EOR bit + TxDesc[tx_serach_idx].dw1 |= TX_DESC_OWN | TX_DESC_FS | TX_DESC_LS | TX_DESC_CRC | Size; + TxDesc[tx_serach_idx].dw2 = ((TX_DESC_VLAN_REMOVE << 25) & TX_DESC_VLAN_ACT_MASK) | (C_VLAN_HDR & TX_DESC_VLAN_TAG_MASK); + CurrDataLen += Size; + } + else + { + /* Enable TxOK interrupt */ + HalEtherAdp.InterruptMask |= IMR_TXOK; + HAL_MII_WRITE32(REG_MII_ISRIMR, HalEtherAdp.InterruptMask); + /* Enable Tx ring1 */ + HAL_MII_WRITE32(REG_MII_IOCMD, (HAL_MII_READ32(REG_MII_IOCMD) | IOCMD_TXFN1ST)); + DBG_MII_WARN("Tx ring full\n"); + + /* Upper layer will re-transmit this packet */ + return 0; + } + + /* Check if reach to the end of the ring */ + if(tx_serach_idx == ((pEthAdapter->tx_desc_num) - 1)) + TxDescWrPtr = 0; + else + TxDescWrPtr++; + + + return Size; +} + + +u32 +HalMiiSendPacketRtl8195a( + IN VOID +) +{ + u32 size = CurrDataLen; + + + /* Enable TxOK interrupt */ + HalEtherAdp.InterruptMask |= IMR_TXOK; + HAL_MII_WRITE32(REG_MII_ISRIMR, HalEtherAdp.InterruptMask); + /* Enable Tx ring1 */ + HAL_MII_WRITE32(REG_MII_IOCMD, (HAL_MII_READ32(REG_MII_IOCMD) | IOCMD_TXFN1ST)); + CurrDataLen = 0; + + + return size; +} + + +u32 +HalMiiReceivePacketRtl8195a( + IN VOID +) +{ + u8 rx_serach_idx = RxDescRdPtr; + u32 rx_len = 0; + + + /* Check if Rx descriptor is available */ + if((((volatile u32)RxDesc[rx_serach_idx].dw1) & RX_DESC_OWN) == 0) + { + rx_len = (RxDesc[rx_serach_idx].dw1) & RX_DESC_DATA_LEN_MASK; + } + else + { + /* Enable interrupt again */ + DBG_MII_INFO("RX ring empty\n\r"); + HalEtherAdp.InterruptMask |= (IMR_RXOK | ISR_RER_OVF); + HAL_MII_WRITE32(REG_MII_ISRIMR, HalEtherAdp.InterruptMask); + return 0; + } + + return rx_len; +} + + +u32 +HalMiiReadDataRtl8195a( + IN u8 *Data, + IN u32 Size +) +{ + PHAL_ETHER_ADAPTER pEthAdapter = (PHAL_ETHER_ADAPTER)&HalEtherAdp; + u32 read_idx = RxDescRdPtr; + + + if((Data == NULL) || (Size == 0) || (Size > 1518)) + { + DBG_MII_ERR("Wrong params\n"); + return 0; + } + + #if 1 + _memcpy((void*)Data, (void*)(RxDesc[read_idx].addr + 2), Size); + #else + isDmaDone = 0; + HalGdmaMemCpy(&gdmaObj, (void*)Data, (void*)(RxDesc[read_idx].addr + 2), Size); + while (isDmaDone == 0); + #endif + + RxDesc[read_idx].dw1 &= RX_DESC_EOR; // keep the EOR bit + RxDesc[read_idx].dw1 |= (RX_DESC_OWN | MII_BUF_SIZE); + //RxDesc[read_idx].addr = (u32)(pRxDataBuf + (read_idx * MII_BUF_SIZE)); + RxDesc[read_idx].dw2 = 0; + RxDesc[read_idx].dw3 = 0; + + /* Update the read pointer */ + if(read_idx == ((pEthAdapter->rx_desc_num) - 1)) + RxDescRdPtr = 0; + else + RxDescRdPtr++; + + + return Size; +} + + +VOID +HalMiiGetMacAddressRtl8195a( + IN u8 *Addr +) +{ + u8 *ptr; + +// To do: Get info. from Flash or Efuse + ptr = Addr; + *(ptr) = 0x12; + *(ptr+1) = 0x34; + *(ptr+2) = 0x56; + *(ptr+3) = 0x78; + *(ptr+4) = 0x9A; + *(ptr+5) = 0xBC; +} + + +u32 +HalMiiGetLinkStatusRtl8195a( + IN VOID +) +{ + u32 ret; + + + if(HAL_MII_READ32(REG_MII_MS) & MS_LINKB) + ret = 0; // Link down + else + ret = 1; // Link up + + return ret; +} + + +#if 0 +VOID +HalMiiForceLinkRtl8195a( + IN s32 Speed, + IN s32 Duplex +) +{ + u32 regVal = 0; + u16 ret; + + #if 0 + /* Reset PHY */ + HAL_MII_WRITE32(REG_MII_MIIA, MIIA_FLAG | + ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | + ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK) | + PHY_SW_RESET); + HalDelayUs(1000); + do { + }while(HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG); + + while(1) + { + /* Check reset status */ + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + regVal = HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF; + if(!(regVal & PHY_SW_RESET)) + break; + } + DBG_MII_INFO("PHY reset is completed...\n"); + #endif + /* Switch to Page 0 */ + ret = HalMiiRwPhyRegRtl8195a(1, 31, 0); + + if(((Speed == 1) && (Duplex == 1)) || ((Speed == 1) && (Duplex == 0)) || ((Speed == 0) && (Duplex == 1)) || ((Speed == 0) && (Duplex == 0))) + { + /* Disable Auto-negotiation */ + HAL_MII_WRITE32(REG_MII_MIIA, MIIA_FLAG | + ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | + ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK) | + 0x0000); + HalDelayUs(1000); + do { + }while(HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG); + + /* Manual settings */ + HAL_MII_WRITE32(REG_MII_MIIA, MIIA_FLAG | + ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | + ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK) | + (((Speed << 13) & PHY_SPEED_LSB) | ((Duplex << 8) & PHY_DUPLEX_MODE))); + HalDelayUs(1000); + do { + }while(HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG); + } + else + { + #if 1 + /* Reset PHY */ + HAL_MII_WRITE32(REG_MII_MIIA, MIIA_FLAG | + ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | + ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK) | + PHY_SW_RESET); + HalDelayUs(1000); + do { + }while(HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG); + + while(1) + { + /* Check reset status */ + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + regVal = HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF; + if(!(regVal & PHY_SW_RESET)) + break; + } + DBG_MII_INFO("PHY reset is completed...\n"); + #endif + while(1) + { + /* Check Auto-negotiation process status */ + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG1_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + regVal = HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF; + if(regVal & PHY_NWAY_COMPLETE) + break; + } + DBG_MII_INFO("Auto-negotiation is completed...\n"); + } + + /* Wait until link is up */ + while(1) + { + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG1_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + HalDelayUs(1000); + + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG1_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + regVal = HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF; + if(regVal & PHY_LINK_STATUS) + break; + } + + /* Get link info. */ + HAL_MII_WRITE32(REG_MII_MIIA, ((PHY_ADDRESS << 26) & MIIA_PHY_ADDR_MASK) | ((PHY_REG0_ADDR << 16) & MIIA_PHY_REG_ADDR_MASK)); + HalDelayUs(1000); + do { + }while((HAL_MII_READ32(REG_MII_MIIA) & MIIA_FLAG) == 0); + + regVal = HAL_MII_READ32(REG_MII_MIIA) & 0xFFFF; + + if((!(regVal & PHY_SPEED_MSB)) && (regVal & PHY_SPEED_LSB)) + { + if(regVal & PHY_DUPLEX_MODE) + DBG_8195A("Link status: 100 Mb/s, Full duplex\n"); + else + DBG_8195A("Link status: 100 Mb/s, Half duplex\n"); + } + else if((!(regVal & PHY_SPEED_MSB)) && (!(regVal & PHY_SPEED_LSB))) + { + if(regVal & PHY_DUPLEX_MODE) + DBG_8195A("Link status: 10 Mb/s, Full duplex\n"); + else + DBG_8195A("Link status: 10 Mb/s, Half duplex\n"); + } + + HalDelayUs(4000000); +} +#else +VOID +HalMiiForceLinkRtl8195a( + IN s32 Speed, + IN s32 Duplex +) +{ + u16 ret; + + + /* Switch to Page 0 */ + ret = HalMiiRwPhyRegRtl8195a(1, 31, 0); + + if(((Speed == 1) && (Duplex == 1)) || ((Speed == 1) && (Duplex == 0)) || ((Speed == 0) && (Duplex == 1)) || ((Speed == 0) && (Duplex == 0))) + { + /* Disable Auto-negotiation */ + ret = HalMiiRwPhyRegRtl8195a(1, 0, 0x0); + /* Manual settings */ + ret = HalMiiRwPhyRegRtl8195a(1, 0, (((Speed << 13) & PHY_SPEED_LSB) | ((Duplex << 8) & PHY_DUPLEX_MODE))); + } + else + { + /* Restart Auto-negotiation */ + ret = HalMiiRwPhyRegRtl8195a(1, 0, PHY_NWAY_EN | PHY_RESTART_NWAY); + while(1) + { + /* Check the reset status */ + ret = HalMiiRwPhyRegRtl8195a(0, 0, 0); + if(!(ret & PHY_RESTART_NWAY)) + break; + } + + /* Check Auto-negotiation process status */ + while(1) + { + ret = HalMiiRwPhyRegRtl8195a(0, 1, 0); + if(ret & PHY_NWAY_COMPLETE) + break; + } + DBG_MII_INFO("Auto-negotiation is completed...\n"); + } + + /* Wait until link is up */ + while(1) + { + ret = HalMiiRwPhyRegRtl8195a(0, 1, 0); + HalDelayUs(1000); + ret = HalMiiRwPhyRegRtl8195a(0, 1, 0); + if(ret & PHY_LINK_STATUS) + break; + } + + /* Get link info. */ + ret = HalMiiRwPhyRegRtl8195a(0, 0, 0); + if((!(ret & PHY_SPEED_MSB)) && (ret & PHY_SPEED_LSB)) + { + if(ret & PHY_DUPLEX_MODE) + DBG_8195A("Link status: 100 Mb/s, Full duplex\n"); + else + DBG_8195A("Link status: 100 Mb/s, Half duplex\n"); + } + else if((!(ret & PHY_SPEED_MSB)) && (!(ret & PHY_SPEED_LSB))) + { + if(ret & PHY_DUPLEX_MODE) + DBG_8195A("Link status: 10 Mb/s, Full duplex\n"); + else + DBG_8195A("Link status: 10 Mb/s, Half duplex\n"); + } + + HalDelayUs(4000000); +} +#endif + + +#ifdef CONFIG_MII_VERIFY +VOID MiiIrqHandle (IN VOID *Data); + +VOID MiiIrqHandle (IN VOID *Data) { + u32 RegValue = HalMiiGmacGetInterruptStatusRtl8195a(); + extern volatile u8 isRxOK; + extern volatile u8 isTxOK; + extern volatile u8 RxIntCnt; + + +// DBG_8195A("ISR = 0x%08X\n", RegValue); + if(RegValue & GMAC_ISR_ROK) { + HalMiiGmacClearInterruptStatusRtl8195a(0x00410001); + isRxOK = 1; + RxIntCnt++; + } + + if(RegValue & GMAC_ISR_TOK_TI) { + HalMiiGmacClearInterruptStatusRtl8195a(0x00410040); + isTxOK = 1; + } +} + + +/** + * MII Initialize. + * + * MII Initialize. + * + * Initialization Steps: + * I. Rtl8195A Board Configurations: + * 1. MII Function Enable & AHB mux + * + * @return runtime status value. + */ +BOOL +HalMiiGmacInitRtl8195a( + IN VOID *Data + ) +{ + u32 RegValue; + + + /* 1. enable MII Pinmux & disable SDIO Host/Device mode Pinmux */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL); + RegValue |= BIT24; + RegValue &= ~(BIT0 | BIT1); // Important! + HAL_WRITE32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL, RegValue); + + /* 2. enable MII IP block (214, 12) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN); + RegValue |= BIT12; + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, RegValue); + + /* 3. Lexra2AHB Function Enable (304, 11) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_PESOC_SOC_CTRL); + RegValue |= BIT11; + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_SOC_CTRL, RegValue); + + /* 4. enable MII bus clock (240, 24|25) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0); + RegValue |= (BIT24 | BIT25); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, RegValue); + + /* 5. */ + RegValue = HAL_READ32(SYSTEM_CTRL_BASE, 0x74) & 0xFFFFC7FF; + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x74, (RegValue | 0x00003000)); + + /* 6. AHB mux: select MII (214, 13) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN); + RegValue |= BIT13; + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, RegValue); + + /* 7. Vendor Register Clock Enable (230, 6|7) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_CTRL); + RegValue |= (BIT6 | BIT7); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_CLK_CTRL, RegValue); + + /* 8. Enable GMAC Lexra Timeout (090, 16|17|18) */ + RegValue = HAL_READ32(VENDOR_REG_BASE, 0x0090); + RegValue |= (BIT16 | BIT17 | BIT18); + HAL_WRITE32(VENDOR_REG_BASE, 0x0090, RegValue); + + /* 9. Endian Swap Control (304, 12|13) */ + RegValue = HAL_READ32(PERI_ON_BASE, REG_PESOC_SOC_CTRL); + RegValue |= (BIT12 | BIT13); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_SOC_CTRL, RegValue); + + return _TRUE; +} + + +BOOL +HalMiiGmacResetRtl8195a( + IN VOID *Data + ) +{ + HAL_MII_WRITE32(REG_RTL_MII_CR, (HAL_MII_READ32(REG_RTL_MII_CR) | BIT0)); + + return _TRUE; +} + + +BOOL +HalMiiGmacEnablePhyModeRtl8195a( + IN VOID *Data + ) +{ + return _TRUE; +} + + +u32 +HalMiiGmacXmitRtl8195a( + IN VOID *Data + ) +{ + return 0; +} + + +VOID +HalMiiGmacCleanTxRingRtl8195a( + IN VOID *Data + ) +{ +} + + +VOID +HalMiiGmacFillTxInfoRtl8195a( + IN VOID *Data + ) +{ + PMII_ADAPTER pMiiAdapter = (PMII_ADAPTER) Data; + PTX_INFO pTx_Info = pMiiAdapter->pTx_Info; + VOID* TxBuffer = pMiiAdapter->TxBuffer; + + + pTx_Info->opts1.dw = 0xBC8001FE; + /* pTx_Info->opts1.dw = 0xBC800080; // size: 128 */ + + pTx_Info->addr = (u32)TxBuffer; + pTx_Info->opts2.dw = 0x0400279F; + pTx_Info->opts3.dw = 0x00000000; + /* pTx_Info->opts4.dw = 0x57800000; */ + pTx_Info->opts4.dw = 0x1FE00000; + + HAL_MII_WRITE32(REG_RTL_MII_TXFDP1, pTx_Info); +} + + +VOID +HalMiiGmacFillRxInfoRtl8195a( + IN VOID *Data + ) +{ + PMII_ADAPTER pMiiAdapter = (PMII_ADAPTER) Data; + PRX_INFO pRx_Info = pMiiAdapter->pRx_Info; + VOID* RxBuffer = pMiiAdapter->RxBuffer; + + + /* pRx_Info->opts1.dw = 0x80000200; //Data Length: 4095(FFF), 512(200) */ + pRx_Info->opts1.dw = 0x800001FC; //Data Length: 4095(FFF), 512(200) + /* pRx_Info->opts1.dw = 0x8000007F; */ + + pRx_Info->addr = (u32)RxBuffer; + pRx_Info->opts2.dw = 0x00000000; + pRx_Info->opts3.dw = 0x00000000; + + HAL_MII_WRITE32(REG_RTL_MII_RXFDP1, pRx_Info); +} + + +VOID +HalMiiGmacTxRtl8195a( + IN VOID *Data + ) +{ + u32 RegValue; + + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD); + RegValue |= BIT_IOCMD_TXENABLE(1); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD, RegValue); + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD); + RegValue |= BIT_IOCMD_FIRST_DMATX_ENABLE(1); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD, RegValue); +} + + +VOID +HalMiiGmacRxRtl8195a( + IN VOID *Data + ) +{ + u32 RegValue; + + + RegValue = HAL_MII_READ32(REG_RTL_MII_TCR); + + HAL_MII_WRITE32(REG_RTL_MII_TCR, 0x00000D00); // loopback R2T mode + + RegValue = HAL_MII_READ32(REG_RTL_MII_RCR); + HAL_MII_WRITE32(REG_RTL_MII_RCR, 0x0000007F); + + RegValue = HAL_MII_READ32(REG_RTL_MII_ETNRXCPU1); + HAL_MII_WRITE32(REG_RTL_MII_ETNRXCPU1, 0x1F0A0F00); + + RegValue = HAL_MII_READ32(REG_RTL_MII_RX_PSE1); + HAL_MII_WRITE32(REG_RTL_MII_RX_PSE1, 0x00000022); + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD1); + RegValue |= BIT_IOCMD1_FIRST_DMARX_ENABLE(1); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD1, RegValue); + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD); + RegValue |= BIT_IOCMD_RXENABLE(1); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD, RegValue); +} + + +VOID +HalMiiGmacSetDefaultEthIoCmdRtl8195a( + IN VOID *Data + ) +{ + u32 RegValue; + + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD, CMD_CONFIG); + + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD1); + HAL_MII_WRITE32(REG_RTL_MII_IOCMD1, CMD1_CONFIG); + + //2014-04-29 yclin (disable 0x40051438[27] r_en_precise_dma) { + RegValue = HAL_MII_READ32(REG_RTL_MII_IOCMD1); + RegValue = RegValue & 0xF7FFFFFF; + HAL_MII_WRITE32(REG_RTL_MII_IOCMD1, RegValue); + // } +} + + +VOID +HalMiiGmacInitIrqRtl8195a( + IN VOID *Data + ) +{ + IRQ_HANDLE MiiIrqHandle_Master; + PMII_ADAPTER pMiiAdapter = (PMII_ADAPTER) Data; + + + MiiIrqHandle_Master.Data = (u32) (pMiiAdapter); + MiiIrqHandle_Master.IrqNum = GMAC_IRQ; + MiiIrqHandle_Master.IrqFun = (IRQ_FUN) MiiIrqHandle; + MiiIrqHandle_Master.Priority = 10; + InterruptRegister(&MiiIrqHandle_Master); + InterruptEn(&MiiIrqHandle_Master); +} + + +u32 +HalMiiGmacGetInterruptStatusRtl8195a( + VOID + ) +{ + u32 RegValue; + + + RegValue = HAL_MII_READ32(REG_RTL_MII_IMRISR); + + return RegValue; +} + + +VOID +HalMiiGmacClearInterruptStatusRtl8195a( + u32 IsrStatus + ) +{ + HAL_MII_WRITE32(REG_RTL_MII_IMRISR, IsrStatus); +} +#endif // #ifdef CONFIG_MII_VERIFY + + +#endif // #ifdef CONFIG_MII_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_nfc.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_nfc.c new file mode 100644 index 0000000..d375226 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_nfc.c @@ -0,0 +1,2023 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" + +#ifdef CONFIG_NFC_EN +//#include "autoconf.h" +//#include "diag.h" +//#include "hal_peri_on.h" +#include "rtl8195a_nfc.h" +#include "osdep_api.h" +//#include "hal_nfc.h" +//#include "rtl8195a_peri_on.h" +//#include "rtl8195a_sys_on.h" +//#include "hal_platform.h" + +#ifdef CONFIG_NFC_NORMAL + +extern void nfc_tagwrite_callback(PNFC_ADAPTER pNFCAdp, uint32_t page, uint32_t wr_data); +extern void nfc_event_callback(PNFC_ADAPTER pNFCAdp, uint32_t event); +extern void nfc_tagread_callback(PNFC_ADAPTER pNFCAdp, uint32_t page); +extern void nfc_cache_read_callback(PNFC_ADAPTER pNFCAdp, uint32_t start_pg, uint32_t *pbuf); + +extern VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); +extern VOID SpicSectorEraseFlashRtl8195A(u32 Address); +extern VOID SpicWaitBusyDoneRtl8195A(VOID); +extern VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); + + +VOID WriteA2NMailbox(IN VOID *pNFCAdapte); +VOID A2NWriteInQueue(IN VOID *pNFCAdapte, IN VOID *pBuff); +VOID A2NWriteDeQueue(IN VOID *pNFCAdapte); +VOID N2AReadTag(IN VOID *pNFCAdapte, IN u8 N2ARPage); +u32 HalNFCRead32(IN u32 Addr); +VOID HalNFCWrite32(IN u32 Addr, IN u32 Data); +VOID N2AWriteTag(IN VOID *pNFCAdapte, IN u8 N2AWPage); +VOID N2AReadCatch(IN VOID *pNFCAdapte, IN u8 N2ACatchRPage); +VOID NFCReaderPresent(IN VOID *pNFCAdapte, IN u8 State); +VOID N2AMailboxState(IN VOID *pNFCAdapte, IN u8 State, IN u8 Seq); +VOID NFC25MClkReq(IN VOID *pNFCAdapte, IN u8 OP, IN u8 Seq); + +//v1.3 150824 +u8 NFCFWIMEM[]={ +0x01, 0x10, 0x00, 0x65, 0x00, 0x68, 0xA8, 0xB9, 0x00, 0x65, 0x40, 0xF0, 0x20, 0x69, 0x89, 0xB9, +0x00, 0x65, 0x13, 0xF7, 0x20, 0x6A, 0x80, 0xF0, 0x08, 0x4A, 0x7E, 0xF0, 0x2D, 0x68, 0x7E, 0xF0, +0x0C, 0x48, 0x00, 0xDA, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x13, 0xF7, 0x20, 0x6A, +0x08, 0x4A, 0x00, 0x9A, 0x00, 0x65, 0x00, 0xF0, 0x20, 0x69, 0xFF, 0xF4, 0x1F, 0x49, 0x2C, 0xE8, +0x00, 0xDA, 0x00, 0x65, 0x13, 0xF7, 0x20, 0x6A, 0x80, 0xF0, 0x04, 0x4A, 0x00, 0x68, 0x00, 0xDA, +0x00, 0x65, 0x13, 0xF7, 0x20, 0x6A, 0x80, 0xF0, 0x00, 0x4A, 0x02, 0xF0, 0x20, 0x68, 0xFF, 0x48, +0x00, 0xDA, 0x00, 0x65, 0x10, 0xF0, 0x20, 0x68, 0x00, 0xF4, 0x01, 0x48, 0x00, 0xE8, 0x00, 0x65, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xDF, 0xF7, 0x04, 0x63, 0x0E, 0xD2, 0x0D, 0xD3, 0x0C, 0xD0, 0x0B, 0xD1, 0x0A, 0xD4, 0x09, 0xD5, +0x08, 0xD6, 0x07, 0xD7, 0x58, 0x67, 0x06, 0xD2, 0x05, 0x62, 0x8D, 0xB8, 0xAE, 0xB8, 0xC8, 0xB8, +0xEC, 0xB8, 0x00, 0x18, 0x28, 0x01, 0x00, 0x65, 0x00, 0x6A, 0xAA, 0xB9, 0x06, 0x92, 0x1A, 0x65, +0x05, 0x92, 0xFA, 0x65, 0x0E, 0x92, 0x0D, 0x93, 0x0C, 0x90, 0x0B, 0x91, 0x0A, 0x94, 0x09, 0x95, +0x08, 0x96, 0x07, 0x97, 0x20, 0xF0, 0x1C, 0x63, 0x00, 0xBA, 0x00, 0x65, 0x00, 0xF0, 0x20, 0x6A, +0xFF, 0x4A, 0x60, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x13, 0xF7, 0x20, 0x6A, 0x50, 0x4A, 0x00, 0x9A, 0x00, 0x65, 0x10, 0xF0, 0x20, 0x69, 0xFF, 0x49, +0x2C, 0xE8, 0x00, 0xDA, 0x00, 0x65, 0x34, 0xB8, 0x00, 0xF4, 0x00, 0x68, 0x2D, 0xE8, 0x90, 0xB9, +0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x14, 0xB8, 0x00, 0xF4, 0x00, 0x69, 0x2C, 0xE8, 0xFB, 0x20, +0x00, 0x65, 0x10, 0xF0, 0x20, 0x68, 0x20, 0xF4, 0x1F, 0x48, 0x00, 0xE8, 0x00, 0x65, 0x10, 0xF0, +0x30, 0x6A, 0x00, 0xF3, 0x00, 0x4A, 0x10, 0xF0, 0x30, 0x6B, 0xE0, 0xF6, 0x10, 0x4B, 0x00, 0x68, +0x00, 0xDA, 0x01, 0xDA, 0x02, 0xDA, 0x03, 0xDA, 0x10, 0x4A, 0x63, 0xEA, 0xF9, 0x61, 0x00, 0x65, +0x10, 0xF0, 0x30, 0x68, 0x20, 0xF3, 0x00, 0x48, 0xB8, 0x65, 0x00, 0x65, 0x10, 0xF0, 0x30, 0x68, +0x20, 0xF6, 0x08, 0x48, 0xB8, 0x65, 0x00, 0x68, 0xA8, 0xB9, 0x0C, 0xB8, 0x00, 0x65, 0x1F, 0xF7, +0x01, 0x69, 0x2D, 0xE8, 0xDF, 0xF7, 0x20, 0x69, 0xFF, 0x49, 0x2C, 0xE8, 0x88, 0xB9, 0x00, 0x65, +0x10, 0xF0, 0x20, 0x68, 0x40, 0xF5, 0x05, 0x48, 0x00, 0xE8, 0x00, 0x65, 0x20, 0xBA, 0x00, 0x65, +0xF9, 0x63, 0x0D, 0x62, 0x0C, 0xD1, 0x04, 0x01, 0x8A, 0xD9, 0xAB, 0xD9, 0xCC, 0xD9, 0xED, 0xD9, +0x6A, 0x99, 0x1F, 0xF7, 0x00, 0x6A, 0x6C, 0xEA, 0x43, 0x32, 0x45, 0xD9, 0x6D, 0x99, 0x1F, 0xF7, +0x00, 0x6A, 0x6C, 0xEA, 0x43, 0x32, 0x44, 0xD9, 0x6A, 0x99, 0x7C, 0x6A, 0x6C, 0xEA, 0x4B, 0x32, +0x43, 0xD9, 0x64, 0x99, 0x45, 0x99, 0x83, 0x67, 0xA2, 0x67, 0x00, 0x18, 0x3A, 0x01, 0xB9, 0x65, +0x09, 0x97, 0x08, 0x91, 0x05, 0x63, 0x00, 0xEF, 0xFB, 0x63, 0x09, 0x62, 0x08, 0xD1, 0x04, 0x01, +0x86, 0xD9, 0xA7, 0xD9, 0x66, 0x99, 0x47, 0x99, 0x6C, 0xEA, 0x43, 0xD9, 0x63, 0x99, 0x80, 0x6A, +0x6C, 0xEA, 0x02, 0x22, 0x00, 0x18, 0x5B, 0x03, 0x63, 0x99, 0x40, 0x6A, 0x6C, 0xEA, 0x02, 0x22, +0x00, 0x18, 0x20, 0x04, 0x63, 0x99, 0x20, 0x6A, 0x6C, 0xEA, 0x02, 0x22, 0x00, 0x18, 0x27, 0x04, +0x63, 0x99, 0x10, 0x6A, 0x6C, 0xEA, 0x02, 0x22, 0x00, 0x18, 0x94, 0x03, 0x63, 0x99, 0x08, 0x6A, +0x6C, 0xEA, 0x02, 0x22, 0x00, 0x18, 0xA8, 0x04, 0xB9, 0x65, 0x05, 0x97, 0x04, 0x91, 0x03, 0x63, +0x00, 0xEF, 0x00, 0x65, 0xFA, 0x63, 0x0B, 0x62, 0x0A, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x68, 0x9A, 0x63, 0xD9, 0xA0, 0xF0, 0x08, 0x4A, 0x42, 0xAA, +0x48, 0xC9, 0x20, 0x6A, 0x49, 0xC1, 0x00, 0x6A, 0x48, 0xC1, 0x00, 0x18, 0x6B, 0x01, 0x60, 0x6C, +0x00, 0x18, 0x01, 0x03, 0x00, 0x18, 0x87, 0x01, 0x00, 0x18, 0x77, 0x01, 0x00, 0x18, 0x9B, 0x01, +0x00, 0x18, 0x63, 0x01, 0x0A, 0x6C, 0x00, 0x18, 0x84, 0x07, 0xFF, 0x17, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x50, 0x9A, 0x00, 0x6B, +0x60, 0xCA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x54, 0x9A, 0x00, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x58, 0x9A, 0x00, 0xF4, +0x00, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x01, 0x6B, 0x40, 0xF6, +0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x5C, 0x9A, 0x04, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x40, 0x9A, 0x04, 0x6B, +0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x44, 0x9A, 0x01, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x48, 0x9A, 0x07, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x4C, 0x9A, 0xFF, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x50, 0x9A, 0x00, 0x6B, +0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFB, 0x63, 0x09, 0x62, +0x08, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x50, 0x9A, +0x01, 0x6B, 0x6E, 0xEA, 0x04, 0x2A, 0x06, 0x6C, 0x01, 0x6D, 0x00, 0x18, 0xDC, 0x0E, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x54, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, +0x60, 0x33, 0xC0, 0xF0, 0x78, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF0, 0x5C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xE0, 0xF0, 0x40, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF0, 0x5C, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x7E, 0x6A, 0x6D, 0xEA, +0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x62, 0x99, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x48, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x00, 0xF2, 0x01, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x4C, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x48, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, +0x00, 0xF4, 0x03, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x50, 0x9A, 0x6C, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x48, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, 0x00, 0xF4, +0x02, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xE0, 0xF0, 0x54, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xE0, 0xF0, 0x48, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x27, 0x10, 0x00, 0x6A, +0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, 0x64, 0x5A, 0x58, 0x67, +0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x58, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x5C, 0x9A, +0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, +0x5C, 0x9A, 0x6E, 0xEA, 0x08, 0x22, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x0A, 0x5A, +0x58, 0x67, 0xD5, 0x2A, 0x01, 0x10, 0x00, 0x65, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF0, 0x5C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF1, 0x40, 0x9A, 0x6C, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF0, 0x5C, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF0, 0x54, 0x9A, 0xE4, 0xF1, 0x17, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x44, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x00, 0xF1, 0x68, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, +0x5C, 0x9A, 0x24, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, +0x4C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x02, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, +0x62, 0x99, 0x0A, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF1, 0x4C, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF1, 0x50, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x40, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x54, 0x9A, 0x40, 0x9A, 0x42, 0xD9, +0x62, 0x99, 0x0C, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF1, 0x54, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF1, 0x58, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF1, 0x40, 0x9A, 0x6C, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF1, 0x58, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF1, 0x5C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x40, 0x9A, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x44, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x62, 0x99, +0x04, 0xF0, 0x01, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x48, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0xE0, 0xF3, +0x11, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x30, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x5C, 0x9A, 0x62, 0x99, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x4C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, +0x62, 0x99, 0x20, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0x6A, 0x6D, 0xEA, +0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x4C, 0x9A, 0x62, 0x99, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x80, 0xF7, 0x00, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, 0x01, 0xF0, +0x00, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, +0x44, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, 0x01, 0xF0, 0x01, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, +0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x62, 0x99, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x50, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x10, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x03, 0x6A, +0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x50, 0x9A, +0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, 0x10, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x62, 0x99, 0x11, 0x6A, +0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, +0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, +0x54, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0xE0, 0xF1, 0x11, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, +0x42, 0xD9, 0x62, 0x99, 0x70, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF1, 0x54, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF1, 0x58, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x5C, 0x9A, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x40, 0x9A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF1, 0x58, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x44, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, +0x10, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0x01, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x44, 0x9A, 0x62, 0x99, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x48, 0x9A, 0x40, 0x9A, 0x42, 0xD9, +0x62, 0x99, 0xE0, 0xF1, 0x01, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x62, 0x99, 0xA0, 0x6A, +0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x48, 0x9A, +0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, +0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x7F, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, 0x44, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, +0x10, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF0, +0x44, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, +0x4C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x07, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x4C, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x50, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x04, 0x2A, +0x06, 0x6C, 0x00, 0x6D, 0x00, 0x18, 0xDC, 0x0E, 0xB9, 0x65, 0x05, 0x97, 0x04, 0x91, 0x03, 0x63, +0x00, 0xEF, 0x00, 0x65, 0xFC, 0x63, 0x07, 0xD1, 0x3D, 0x67, 0x44, 0x67, 0x20, 0xF0, 0x40, 0xC1, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x50, 0x9A, 0x00, 0x6B, 0x60, 0xDA, +0x82, 0x6A, 0x44, 0xD9, 0x64, 0x99, 0xFF, 0x6A, 0x6C, 0xEA, 0x42, 0xD9, 0x64, 0x99, 0x1F, 0xF7, +0x00, 0x6A, 0x6C, 0xEA, 0x42, 0x32, 0x43, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF1, 0x54, 0x9A, 0x80, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF1, 0x58, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF1, 0x50, 0x9A, 0x63, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF1, 0x54, 0x9A, 0x03, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x07, 0x91, 0x04, 0x63, 0x20, 0xE8, +0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x00, 0x6A, 0x41, 0xC1, 0x26, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x5C, 0x9A, 0x40, 0x9A, 0x62, 0x67, 0x01, 0x6A, 0x4C, 0xEB, +0xFF, 0x6A, 0x6C, 0xEA, 0x0C, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, +0x58, 0x9A, 0x40, 0x9A, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x13, 0x10, 0x00, 0x6A, +0x40, 0xC1, 0x03, 0x10, 0x40, 0xA1, 0x01, 0x4A, 0x40, 0xC1, 0x40, 0xA1, 0x0A, 0x5A, 0x58, 0x67, +0xF9, 0x2A, 0x41, 0xA1, 0x01, 0x4A, 0x41, 0xC1, 0x41, 0xA1, 0x64, 0x5A, 0x58, 0x67, 0xD6, 0x2A, +0x01, 0x6A, 0x4B, 0xEA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, +0x3D, 0x67, 0x44, 0x67, 0x50, 0xC1, 0x00, 0x6A, 0x41, 0xC9, 0x2C, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x5C, 0x9A, 0x60, 0x9A, 0x20, 0x6A, 0x6C, 0xEA, 0x14, 0x22, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF1, 0x58, 0x9A, 0x70, 0xA1, 0x60, 0xDA, +0x00, 0x6A, 0x40, 0xC9, 0x03, 0x10, 0x40, 0xA9, 0x01, 0x4A, 0x40, 0xC9, 0x40, 0x89, 0x00, 0x52, +0x58, 0x67, 0xF9, 0x22, 0x00, 0x6A, 0x15, 0x10, 0x00, 0x6A, 0x40, 0xC9, 0x03, 0x10, 0x40, 0xA9, +0x01, 0x4A, 0x40, 0xC9, 0x40, 0xA9, 0xE0, 0xF3, 0x08, 0x5A, 0x58, 0x67, 0xF8, 0x2A, 0x41, 0xA9, +0x01, 0x4A, 0x41, 0xC9, 0x41, 0xA9, 0x02, 0xF0, 0x00, 0x5A, 0x58, 0x67, 0xCF, 0x2A, 0x01, 0x6A, +0x4B, 0xEA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFD, 0x63, 0x05, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x40, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x42, 0x99, 0x01, 0x6B, 0x6E, 0xEA, 0x20, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xA0, 0xF0, 0x5C, 0x9A, 0x04, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF1, 0x44, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x12, 0xF0, 0x01, 0x6B, 0x40, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xA0, 0xF0, 0x5C, 0x9A, 0x03, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF1, 0x48, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x42, 0x99, 0x01, 0x6B, 0x6E, 0xEA, +0x33, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x4C, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x50, 0x9A, 0x40, 0x9A, +0x40, 0xD9, 0x60, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x54, 0x9A, +0x6D, 0xEA, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x50, 0x9A, +0x60, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x44, 0x9A, +0x2E, 0xF5, 0x10, 0x5A, 0x58, 0x67, 0x08, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF0, 0x40, 0x9A, 0x03, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, +0xF8, 0x63, 0x0F, 0x62, 0x0E, 0xD1, 0x04, 0x01, 0x00, 0xF3, 0x00, 0x6A, 0x49, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x40, 0xD9, 0x47, 0x41, 0x1D, 0x4A, +0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x58, 0x9A, 0x40, 0x9A, +0x47, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x58, 0x9A, 0x00, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x58, 0x9A, 0x40, 0x9A, +0x48, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x5C, 0x9A, 0x40, 0x9A, +0x46, 0xD9, 0x66, 0x99, 0x80, 0x6A, 0x6D, 0xEA, 0x46, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF1, 0x5C, 0x9A, 0x66, 0x99, 0x60, 0xDA, 0x68, 0x99, 0x01, 0xF0, 0x00, 0x6A, +0x6C, 0xEA, 0x1B, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x40, 0x9A, +0x88, 0x99, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x20, 0xF1, 0x68, 0x9B, 0x6D, 0xE4, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x44, 0x9A, 0x40, 0x9A, +0x46, 0xD9, 0x66, 0x99, 0x0F, 0x6A, 0x6C, 0xEA, 0x44, 0xD9, 0x68, 0x99, 0x00, 0xF4, 0x00, 0x6A, +0x6C, 0xEA, 0x80, 0xF0, 0x1F, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, +0x44, 0x9A, 0x40, 0x9A, 0x46, 0xD9, 0x66, 0x99, 0x40, 0x6A, 0x6C, 0xEA, 0x80, 0xF0, 0x0D, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x48, 0x9A, 0x40, 0x9A, 0x49, 0xD9, +0x42, 0x99, 0x60, 0xA2, 0x20, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x46, 0xC1, 0x46, 0xA1, 0x56, 0x32, +0x46, 0xC1, 0x42, 0x99, 0x02, 0x4A, 0x40, 0xA2, 0x45, 0xC1, 0x46, 0xA1, 0x7B, 0x22, 0x42, 0x99, +0x02, 0x4A, 0x40, 0xA2, 0x45, 0xC1, 0x42, 0x99, 0x40, 0xA2, 0x62, 0x67, 0x1F, 0x6A, 0x6C, 0xEA, +0x02, 0x6B, 0x4E, 0xEB, 0x2F, 0x23, 0x03, 0x52, 0x78, 0x67, 0x02, 0x23, 0x20, 0x22, 0x6A, 0x10, +0x03, 0x6B, 0x4E, 0xEB, 0x31, 0x23, 0x04, 0x6B, 0x6E, 0xEA, 0x64, 0x2A, 0x42, 0x99, 0x02, 0x4A, +0x40, 0xA2, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0xC0, 0xF6, +0x6C, 0xC2, 0x42, 0x99, 0x02, 0x4A, 0x40, 0xA2, 0x01, 0x6B, 0x6E, 0xEA, 0x50, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, 0xC0, 0xF6, 0x6C, 0xC2, 0x4B, 0x10, 0x42, 0x99, +0x01, 0x4A, 0x40, 0xA2, 0x62, 0x67, 0x45, 0xA1, 0x00, 0x6C, 0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, +0xDC, 0x0E, 0x40, 0x10, 0x42, 0x99, 0x01, 0x4A, 0x40, 0xA2, 0x62, 0x67, 0x45, 0xA1, 0x02, 0x6C, +0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, 0xDC, 0x0E, 0x46, 0xA1, 0x05, 0x6B, 0x6E, 0xEA, 0x1C, 0x2A, +0x45, 0xA1, 0x26, 0x5A, 0x58, 0x67, 0x2D, 0x22, 0x00, 0x6A, 0x45, 0xD9, 0x11, 0x10, 0x65, 0xA1, +0x45, 0x99, 0x49, 0xE3, 0x48, 0x32, 0x60, 0x99, 0x49, 0xE3, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, +0x60, 0x33, 0x80, 0xF1, 0x68, 0x9B, 0x60, 0x9B, 0x60, 0xDA, 0x45, 0x99, 0x01, 0x4A, 0x45, 0xD9, +0x45, 0x99, 0x04, 0x5A, 0x58, 0x67, 0xEB, 0x2A, 0x46, 0xA1, 0x02, 0x6B, 0x6E, 0xEA, 0x12, 0x2A, +0x45, 0xA1, 0x48, 0x32, 0x60, 0x99, 0x49, 0xE3, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x80, 0xF1, 0x68, 0x9B, 0x60, 0x9B, 0x60, 0xDA, 0x05, 0x10, 0x00, 0x65, 0x03, 0x10, 0x00, 0x65, +0x01, 0x10, 0x00, 0x65, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF1, 0x58, 0x9A, +0x68, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x58, 0x9A, +0x67, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x0B, 0x97, 0x0A, 0x91, 0x06, 0x63, 0x00, 0xEF, 0x00, 0x65, +0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, +0x4C, 0x9A, 0x40, 0x9A, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0xFD, 0x63, 0x05, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x50, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x02, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, +0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x54, 0x9A, 0x40, 0x9A, 0x40, 0xD9, +0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, +0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x54, 0x9A, +0x80, 0x99, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x80, 0xF1, 0x74, 0x9B, 0x8C, 0xEB, +0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, +0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, +0x58, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, +0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF1, 0x5C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x02, 0x6B, 0x64, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xA0, 0xF0, 0x50, 0x9A, 0x00, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x54, 0xA2, 0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x74, 0xC2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, 0x58, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, +0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, +0x62, 0x99, 0x01, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF1, 0x58, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, +0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x4C, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, +0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, 0x4C, 0x9A, 0x82, 0x99, 0x02, 0x6B, +0x6B, 0xEB, 0x8C, 0xEB, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, +0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF1, 0x50, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, +0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x05, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x62, 0x99, +0x01, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF1, +0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, 0x00, 0x65, +0xFD, 0x63, 0x05, 0xD1, 0x3D, 0x67, 0x00, 0x6A, 0x4E, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x40, 0x9A, 0x40, 0xAA, 0x46, 0xC9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x40, 0x9A, 0x00, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x44, 0x9A, 0x40, 0xAA, 0x45, 0xC9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x44, 0x9A, 0x65, 0xA9, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF6, 0x0C, 0x4A, 0x50, 0xA2, 0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x70, 0xC2, 0x65, 0xA9, 0x08, 0x6A, 0x6C, 0xEA, +0x43, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x04, 0x6B, 0x60, 0xF6, +0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF1, 0x48, 0x9A, 0x01, 0x6B, +0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x52, 0xA2, +0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, +0x0C, 0x4A, 0x72, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, +0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF1, +0x4C, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF1, 0x54, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0x65, 0xA9, 0x01, 0x6A, 0x4C, 0xEB, 0xFF, 0x6A, +0x6C, 0xEA, 0xE0, 0xF0, 0x0B, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, +0x0C, 0x4A, 0x51, 0xA2, 0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x71, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x4C, 0x9A, 0x60, 0xAA, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x63, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, 0x62, 0x67, 0x1F, 0xF7, 0x00, 0x6A, 0x6C, 0xEA, +0x27, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, +0x42, 0x33, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEB, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x69, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, 0xFF, 0x6B, 0x6C, 0xEA, 0x10, 0xF0, 0x10, 0x6B, +0x60, 0x33, 0x60, 0x33, 0x60, 0xF6, 0x0C, 0x4B, 0x43, 0xCB, 0x01, 0x6A, 0x4E, 0xC1, 0x0A, 0x10, +0x00, 0x6A, 0x4E, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, +0x00, 0x6B, 0x69, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, +0x43, 0xAA, 0x0B, 0x5A, 0x58, 0x67, 0x3F, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF1, 0x48, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF1, 0x40, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x60, 0xF6, 0x0C, 0x4B, +0x63, 0xAB, 0x83, 0x67, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xA0, 0xF1, 0x70, 0x9B, +0x6D, 0xE4, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, +0x00, 0x6B, 0x63, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, 0x6B, 0xEB, +0x80, 0xF6, 0x68, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, +0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x50, 0x9A, +0x01, 0x6B, 0x60, 0xCA, 0x43, 0x10, 0x00, 0x6A, 0x4F, 0xC1, 0x0F, 0x10, 0x4F, 0xA1, 0x48, 0x32, +0x61, 0x99, 0x49, 0xE3, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xA0, 0xF1, 0x74, 0x9B, +0x60, 0x9B, 0x60, 0xDA, 0x4F, 0xA1, 0x01, 0x4A, 0x4F, 0xC1, 0x8F, 0xA1, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, 0x62, 0x67, 0x4E, 0xA1, 0x49, 0xE3, +0x03, 0x4A, 0x00, 0x52, 0x78, 0x67, 0x01, 0x23, 0x03, 0x4A, 0x4B, 0x32, 0x42, 0xEC, 0x58, 0x67, +0xDD, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x68, 0xA2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x73, 0xC2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF1, 0x48, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x03, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x65, 0xA9, 0x02, 0x6A, +0x6C, 0xEA, 0x11, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, +0x4C, 0xA2, 0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF6, 0x0C, 0x4A, 0x6C, 0xC2, 0x65, 0xA9, 0x04, 0x6A, 0x6C, 0xEA, 0x11, 0x22, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x4D, 0xA2, 0x61, 0x42, 0xFF, 0x6A, +0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x6D, 0xC2, +0x65, 0xA9, 0x00, 0xF2, 0x00, 0x6A, 0x6C, 0xEA, 0x11, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x4F, 0xA2, 0x61, 0x42, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x6F, 0xC2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF1, 0x40, 0x9A, 0x66, 0xA9, 0x60, 0xCA, 0xB9, 0x65, 0x05, 0x91, +0x03, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x82, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF1, 0x58, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF0, 0x5C, 0x9A, 0x03, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, +0x01, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x82, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF1, 0x5C, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF0, 0x40, 0x9A, 0x03, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, +0x01, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xA0, 0xF0, 0x5C, 0x9A, 0x04, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, +0x20, 0xE8, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF0, 0x40, 0x9A, 0x04, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, +0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x84, 0xD9, 0xA5, 0xD9, 0xC6, 0xD9, +0x64, 0x99, 0x46, 0x99, 0x49, 0xE3, 0x40, 0xD9, 0x0A, 0x10, 0x44, 0x99, 0x65, 0x99, 0x60, 0xA3, +0x60, 0xC2, 0x44, 0x99, 0x01, 0x4A, 0x44, 0xD9, 0x45, 0x99, 0x01, 0x4A, 0x45, 0xD9, 0x65, 0x99, +0x40, 0x99, 0x43, 0xEB, 0x58, 0x67, 0xF1, 0x2A, 0x44, 0x99, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, +0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x84, 0xD9, 0xA5, 0xD9, 0x64, 0x99, +0x45, 0x99, 0x49, 0xE3, 0x40, 0xD9, 0x06, 0x10, 0x44, 0x99, 0x00, 0x6B, 0x60, 0xC2, 0x44, 0x99, +0x01, 0x4A, 0x44, 0xD9, 0x64, 0x99, 0x40, 0x99, 0x43, 0xEB, 0x58, 0x67, 0xF5, 0x2A, 0x44, 0x99, +0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x84, 0xD9, +0xA5, 0xD9, 0xC6, 0xD9, 0x00, 0x6A, 0x40, 0xD9, 0x0F, 0x10, 0x64, 0x99, 0x40, 0x99, 0x49, 0xE3, +0x60, 0xA2, 0x85, 0x99, 0x40, 0x99, 0x49, 0xE4, 0x40, 0xA2, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, +0x09, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x60, 0x99, 0x46, 0x99, 0x43, 0xEB, 0x58, 0x67, +0xEC, 0x2A, 0x01, 0x6A, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x44, 0x67, 0xA3, 0xD9, 0x48, 0xC1, 0x43, 0x99, 0x60, 0xAA, 0xFF, 0x6A, 0x4C, 0xEB, +0x48, 0xA1, 0x6E, 0xEA, 0x48, 0xC1, 0x48, 0xA1, 0x50, 0x32, 0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, +0x63, 0x33, 0x48, 0x81, 0x6E, 0xEA, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x48, 0xC1, +0x43, 0x99, 0x40, 0xAA, 0x42, 0x33, 0xFF, 0xF7, 0x1F, 0x6A, 0x6C, 0xEA, 0x40, 0x33, 0x60, 0x33, +0x63, 0x33, 0x63, 0x33, 0x48, 0xA1, 0x40, 0x32, 0x40, 0x32, 0x40, 0x32, 0x43, 0x32, 0x43, 0x32, +0x6E, 0xEA, 0x40, 0x33, 0x60, 0x33, 0x63, 0x33, 0x63, 0x33, 0x48, 0xA1, 0x4C, 0x32, 0x40, 0x32, +0x40, 0x32, 0x43, 0x32, 0x43, 0x32, 0x6E, 0xEA, 0x40, 0x33, 0x60, 0x33, 0x63, 0x33, 0x63, 0x33, +0x48, 0xA1, 0x52, 0x34, 0xFF, 0x6A, 0x8C, 0xEA, 0x6E, 0xEA, 0x40, 0x33, 0x60, 0x33, 0x63, 0x33, +0x63, 0x33, 0xFF, 0xF7, 0x1F, 0x6A, 0x4C, 0xEB, 0x43, 0x99, 0x60, 0xCA, 0x43, 0x99, 0x40, 0xAA, +0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0xFC, 0x63, 0x07, 0x62, 0x06, 0xD1, 0x04, 0x01, +0x84, 0xD9, 0xA5, 0xD9, 0xC6, 0xD9, 0xE7, 0xD9, 0x44, 0x99, 0x01, 0x6B, 0x4E, 0xEB, 0x04, 0x23, +0x02, 0x6B, 0x6E, 0xEA, 0x05, 0x22, 0x32, 0x10, 0x6C, 0xF3, 0x03, 0x6A, 0x41, 0xC9, 0x04, 0x10, +0x01, 0x6A, 0x4B, 0xEA, 0x41, 0xC9, 0x00, 0x65, 0x45, 0x99, 0x40, 0x82, 0x40, 0xC1, 0x45, 0x99, +0x01, 0x4A, 0x45, 0xD9, 0x60, 0xA1, 0x42, 0x41, 0x83, 0x67, 0xA2, 0x67, 0x00, 0x18, 0xDF, 0x05, +0x46, 0x99, 0xFF, 0x4A, 0x46, 0xD9, 0x46, 0x99, 0xEF, 0x2A, 0x44, 0x99, 0x02, 0x6B, 0x6E, 0xEA, +0x06, 0x2A, 0x41, 0xA9, 0x4F, 0xEB, 0xFF, 0xF7, 0x1F, 0x6A, 0x6C, 0xEA, 0x41, 0xC9, 0x61, 0xA9, +0xFF, 0x6A, 0x4C, 0xEB, 0x47, 0x99, 0x60, 0xC2, 0x41, 0xA9, 0x42, 0x33, 0xFF, 0xF7, 0x1F, 0x6A, +0x4C, 0xEB, 0xFF, 0x6A, 0x4C, 0xEB, 0x48, 0x99, 0x60, 0xC2, 0x00, 0x65, 0xB9, 0x65, 0x03, 0x97, +0x02, 0x91, 0x02, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFB, 0x63, 0x09, 0x62, 0x08, 0xD1, 0x06, 0x01, +0x84, 0xD9, 0x65, 0x67, 0x46, 0x67, 0x74, 0xC1, 0x58, 0xC1, 0x58, 0xA1, 0x01, 0x6B, 0x6E, 0xEA, +0x0B, 0x2A, 0xA4, 0x99, 0x74, 0xA1, 0x43, 0x41, 0x84, 0x41, 0x04, 0xD4, 0x01, 0x6C, 0xC3, 0x67, +0xE2, 0x67, 0x00, 0x18, 0x06, 0x06, 0x0A, 0x10, 0xA4, 0x99, 0x74, 0xA1, 0x43, 0x41, 0x84, 0x41, +0x04, 0xD4, 0x02, 0x6C, 0xC3, 0x67, 0xE2, 0x67, 0x00, 0x18, 0x06, 0x06, 0x43, 0xA1, 0x40, 0xC9, +0x40, 0xA9, 0x40, 0x32, 0x40, 0xC9, 0x44, 0xA1, 0x62, 0x67, 0x40, 0xA9, 0x6D, 0xEA, 0x40, 0xC9, +0x40, 0xA9, 0xB9, 0x65, 0x03, 0x97, 0x02, 0x91, 0x02, 0x63, 0x00, 0xEF, 0xFD, 0x63, 0x05, 0xD1, +0x3D, 0x67, 0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFD, 0x63, 0x05, 0xD1, +0x3D, 0x67, 0x86, 0xD9, 0x46, 0x99, 0x40, 0xD9, 0x40, 0x99, 0x77, 0xF0, 0x24, 0x6B, 0x4D, 0xE3, +0x40, 0x9B, 0x62, 0xD9, 0x41, 0xD9, 0x41, 0x99, 0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, +0xFD, 0x63, 0x05, 0xD1, 0x3D, 0x67, 0x86, 0xD9, 0xA7, 0xD9, 0x46, 0x99, 0x40, 0xD9, 0x47, 0x99, +0x41, 0xD9, 0x41, 0x99, 0x60, 0x99, 0x77, 0xF0, 0x24, 0x6A, 0x69, 0xE2, 0x40, 0xDA, 0x42, 0xD9, +0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, 0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x44, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x64, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF1, 0x40, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x64, 0x9B, +0x60, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x02, 0x6B, +0x64, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x00, 0x6B, +0x61, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x40, 0x9A, 0x00, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x44, 0x9A, 0x08, 0x6B, +0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x48, 0x9A, 0xA7, 0xF7, +0x07, 0x6B, 0x6B, 0xEB, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF0, 0x64, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, +0x6C, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x61, 0xA2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6D, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x62, 0xA2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6E, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x63, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x6F, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, +0x04, 0x4A, 0x64, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, +0x70, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x65, 0xA2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x71, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x66, 0xA2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x72, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x67, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x73, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, +0x04, 0x4A, 0x68, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, +0x74, 0xC2, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, +0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, +0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, +0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x48, 0x9A, +0x87, 0xF7, 0x07, 0x6B, 0x6B, 0xEB, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, 0x08, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x40, 0x9A, 0x02, 0x6B, 0x60, 0xCA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x44, 0x6B, 0x60, 0xDA, 0xB9, 0x65, +0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x48, 0x9A, 0x87, 0xF7, 0x07, 0x6B, +0x6B, 0xEB, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, +0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x54, 0x9A, 0x08, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x48, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF3, 0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x40, 0x9A, 0x01, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, +0x20, 0xE8, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x48, 0x9A, 0x87, 0xF7, 0x07, 0x6B, 0x6B, 0xEB, 0x60, 0xCA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, +0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, 0x08, 0x6B, +0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x01, 0x6B, +0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, +0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, +0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, +0x40, 0x9A, 0x01, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, +0x44, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0x00, 0x65, +0xF8, 0x63, 0x0F, 0x62, 0x0E, 0xD1, 0x04, 0x01, 0x44, 0x67, 0x20, 0xF0, 0x50, 0xC1, 0x00, 0x6A, +0x5C, 0xC1, 0x00, 0x6A, 0x43, 0xD9, 0x00, 0x6A, 0x42, 0xD9, 0x00, 0x6A, 0x44, 0xC1, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x48, 0x9A, 0x40, 0x9A, 0x46, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x48, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x40, 0xF2, 0x6C, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, +0x48, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x40, 0xF2, 0x70, 0x9B, 0x60, 0xDA, +0x00, 0x6A, 0x51, 0xC9, 0x03, 0x10, 0x51, 0xA9, 0x01, 0x4A, 0x51, 0xC9, 0x51, 0xA9, 0x0A, 0x5A, +0x58, 0x67, 0xF9, 0x2A, 0x00, 0x18, 0x73, 0x06, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF2, 0x54, 0x9A, 0xFF, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF2, 0x58, 0x9A, 0x01, 0x6B, 0x60, 0xCA, 0x01, 0x10, 0x00, 0x65, 0x00, 0x18, 0xF9, 0x08, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x40, 0x9A, 0x45, 0xD9, +0x45, 0x99, 0x22, 0xF2, 0x14, 0x6B, 0x6E, 0xEA, 0x01, 0x5A, 0x58, 0x67, 0x62, 0x67, 0xFF, 0x6A, +0x4C, 0xEB, 0x45, 0x99, 0x22, 0xF2, 0x15, 0x6C, 0x8E, 0xEA, 0x01, 0x5A, 0x58, 0x67, 0x82, 0x67, +0xFF, 0x6A, 0x8C, 0xEA, 0x4D, 0xEB, 0xFF, 0x6A, 0x6C, 0xEA, 0x62, 0x67, 0x45, 0x99, 0x22, 0xF2, +0x16, 0x6C, 0x8E, 0xEA, 0x01, 0x5A, 0x58, 0x67, 0x6D, 0xEA, 0x2D, 0x22, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x40, 0x9A, 0x40, 0x9A, 0x44, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x40, 0x9A, 0x64, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x44, 0x9A, 0x80, 0xF4, 0x00, 0x6B, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x48, 0x9A, 0x40, 0x9A, 0x44, 0xD9, 0x64, 0x99, +0x80, 0x6A, 0x6D, 0xEA, 0x44, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, +0x48, 0x9A, 0x64, 0x99, 0x60, 0xDA, 0x45, 0x99, 0x02, 0xF1, 0x11, 0x6B, 0x6E, 0xEA, 0x12, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF1, 0x04, 0x4A, 0x82, 0x67, 0x00, 0x18, +0xCB, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x24, 0xF2, +0x02, 0x6B, 0x60, 0xDA, 0x45, 0x99, 0x26, 0xF3, 0x12, 0x6C, 0x8E, 0xEA, 0x39, 0x2A, 0x00, 0x6A, +0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x4D, 0xA2, +0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF6, 0x0C, 0x4A, 0x53, 0xA2, 0x65, 0x99, 0x6D, 0xEA, 0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, +0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, +0x65, 0x99, 0x6D, 0xEA, 0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x54, 0xA2, 0x65, 0x99, 0x6D, 0xEA, 0x45, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x65, 0x99, 0x60, 0xDA, +0x45, 0x99, 0x26, 0xF3, 0x13, 0x6B, 0x6E, 0xEA, 0x0C, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x60, 0x99, 0x60, 0x9B, 0x60, 0xDA, 0x40, 0x99, 0x04, 0x4A, +0x40, 0xD9, 0x45, 0x99, 0x26, 0xF3, 0x14, 0x6C, 0x8E, 0xEA, 0x39, 0x2A, 0x00, 0x6A, 0x45, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x51, 0xA2, 0x45, 0xD9, +0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, +0x0C, 0x4A, 0x52, 0xA2, 0x65, 0x99, 0x6D, 0xEA, 0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x50, 0xA2, 0x65, 0x99, +0x6D, 0xEA, 0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x4C, 0xA2, 0x65, 0x99, 0x6D, 0xEA, 0x45, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x65, 0x99, 0x60, 0xDA, 0x45, 0x99, +0x26, 0xF3, 0x15, 0x6B, 0x6E, 0xEA, 0x0D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF2, 0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF6, 0x74, 0x9B, +0x60, 0xDA, 0x45, 0x99, 0x26, 0xF3, 0x16, 0x6C, 0x8E, 0xEA, 0x0D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0xE0, 0xF6, 0x6C, 0x9B, 0x60, 0xDA, 0x45, 0x99, 0x26, 0xF3, 0x17, 0x6B, 0x6E, 0xEA, 0x0D, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, +0x60, 0x33, 0x60, 0x33, 0xC0, 0xF6, 0x70, 0x9B, 0x60, 0xDA, 0x45, 0x99, 0x26, 0xF3, 0x18, 0x6C, +0x8E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, 0x00, 0xF3, +0x68, 0xDA, 0x45, 0x99, 0x26, 0xF3, 0x19, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x02, 0x6B, 0x00, 0xF3, 0x68, 0xDA, 0x45, 0x99, 0x46, 0xF3, 0x00, 0x6C, +0x8E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0x00, 0xF3, +0x68, 0xDA, 0x45, 0x99, 0x46, 0xF3, 0x01, 0x6B, 0x6E, 0xEA, 0x0D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x00, 0xF3, 0x68, 0x9B, 0x60, 0xDA, 0x45, 0x99, 0x22, 0xF2, 0x14, 0x6C, 0x8E, 0xEA, 0x2E, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0xAA, 0xF5, 0x0A, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x48, 0x9A, 0x10, 0xF0, +0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x60, 0xF2, 0x6C, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x50, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x60, 0xF2, 0x74, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, +0x58, 0x9A, 0x00, 0xF2, 0x00, 0x6B, 0x60, 0xDA, 0x00, 0x18, 0x27, 0x01, 0x45, 0x99, 0x22, 0xF2, +0x15, 0x6B, 0x6E, 0xEA, 0x37, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, +0x5C, 0x9A, 0x93, 0xF1, 0x19, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF2, 0x5C, 0x9A, 0xAF, 0xF3, 0x1C, 0x6B, 0x6B, 0xEB, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x40, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x50, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0x60, 0xF2, 0x74, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, +0x48, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x80, 0xF2, 0x60, 0x9B, 0x60, 0xDA, +0x00, 0x18, 0x27, 0x01, 0x45, 0x99, 0x22, 0xF2, 0x16, 0x6C, 0x8E, 0xEA, 0x2F, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x93, 0xF1, 0x19, 0x6B, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x50, 0x9A, 0x10, 0xF0, 0x10, 0x6B, +0x60, 0x33, 0x60, 0x33, 0x60, 0xF2, 0x74, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF2, 0x48, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x80, 0xF2, +0x64, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF2, 0x5C, 0x9A, +0xAF, 0xF3, 0x1C, 0x6B, 0x6B, 0xEB, 0x60, 0xDA, 0x00, 0x18, 0x27, 0x01, 0x45, 0x99, 0x24, 0xF2, +0x16, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, +0xC0, 0xF6, 0x70, 0xDA, 0x45, 0x99, 0x24, 0xF2, 0x15, 0x6C, 0x8E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x02, 0x6B, 0xC0, 0xF6, 0x70, 0xDA, 0x45, 0x99, 0x24, 0xF2, +0x14, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x03, 0x6B, +0xC0, 0xF6, 0x70, 0xDA, 0x45, 0x99, 0x44, 0xF2, 0x00, 0x6C, 0x8E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, 0x00, 0xF3, 0x6C, 0xDA, 0x45, 0x99, 0x44, 0xF2, +0x01, 0x6B, 0x6E, 0xEA, 0x0D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, +0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x6C, 0x9B, 0x60, 0xDA, +0x45, 0x99, 0x44, 0xF2, 0x02, 0x6C, 0x8E, 0xEA, 0x0E, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF6, +0x14, 0x4B, 0x64, 0xAB, 0x60, 0xDA, 0x45, 0x99, 0x44, 0xF2, 0x03, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x01, 0x6B, 0x00, 0xF3, 0x70, 0xDA, 0x45, 0x99, +0x44, 0xF2, 0x04, 0x6C, 0x8E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0x6B, 0x00, 0xF3, 0x70, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, +0x4C, 0x9A, 0x12, 0xF0, 0x03, 0x6B, 0x6E, 0xEA, 0x7F, 0xF5, 0x1F, 0x2A, 0x00, 0x18, 0x07, 0x0A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, +0x75, 0x15, 0x00, 0x65, 0xFB, 0x63, 0x09, 0x62, 0x08, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x48, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0x6A, +0x6C, 0xEA, 0x71, 0x22, 0x00, 0x6A, 0x40, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xE0, 0xF6, 0x4C, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF6, +0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF6, 0x6C, 0x9A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x4C, 0x9A, 0x63, 0xEA, 0x58, 0x67, 0x5C, 0x22, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0xE0, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x50, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x04, 0x2A, +0x04, 0x6C, 0x00, 0x6D, 0x00, 0x18, 0xDC, 0x0E, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x02, 0x6B, 0x64, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x50, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x09, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x22, 0xF2, 0x16, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x50, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x09, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x22, 0xF2, 0x15, 0x6B, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x50, 0x9A, 0x03, 0x6B, 0x6E, 0xEA, +0x13, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x5C, 0x9A, 0x22, 0xF2, +0x14, 0x6B, 0x60, 0xDA, 0x09, 0x10, 0x01, 0x6A, 0x40, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0x6B, 0xE0, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x44, 0xAA, 0x02, 0x6B, 0x6E, 0xEA, 0xE0, 0xF0, 0x0B, 0x2A, 0x40, 0xA1, +0x01, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x41, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x61, 0xDA, 0x08, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x00, 0x6B, 0x61, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x41, 0x9A, 0x11, 0x5A, 0x58, 0x67, 0xE0, 0xF0, 0x12, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x00, 0x6B, 0x61, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x02, 0x6A, +0x4B, 0xEA, 0x6C, 0xEA, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, +0x41, 0xD9, 0x41, 0x99, 0x0A, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, +0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x0A, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x00, 0x6A, +0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x32, 0x5A, 0x58, 0x67, +0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x82, 0x99, +0x01, 0x6B, 0x8D, 0xEB, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, +0x41, 0xD9, 0x41, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF2, 0x54, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, +0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x54, 0x9A, 0x07, 0x6B, 0x60, 0xDA, 0x00, 0x6A, +0x41, 0xD9, 0x11, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x58, 0x9A, +0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x01, 0x6A, 0x4C, 0xEB, 0xFF, 0x6A, 0x6C, 0xEA, 0x0E, 0x2A, +0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x61, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF2, 0x5C, 0x9A, 0x43, 0xEB, 0x58, 0x67, 0xE5, 0x2A, 0x01, 0x10, 0x00, 0x65, 0x00, 0x18, +0xD3, 0x09, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x01, 0x6B, +0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, +0x42, 0xD9, 0x62, 0x99, 0x01, 0x6A, 0x6D, 0xEA, 0x42, 0xD9, 0x00, 0x6A, 0x41, 0xD9, 0x03, 0x10, +0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x0A, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x62, 0x99, 0x60, 0xDA, 0x00, 0x6A, +0x41, 0xD9, 0x03, 0x10, 0x41, 0x99, 0x01, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x0A, 0x5A, 0x58, 0x67, +0xF9, 0x2A, 0x2E, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x4C, 0x9A, +0x27, 0x22, 0x01, 0x10, 0x00, 0x65, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, +0x48, 0x9A, 0x40, 0x9A, 0x42, 0xD9, 0x62, 0x99, 0x10, 0x6A, 0x6C, 0xEA, 0x18, 0x22, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x4C, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF3, 0x4C, 0x9A, 0x02, 0xF0, 0x01, 0x5A, 0x58, 0x67, 0xDC, 0x2A, 0x01, 0x10, 0x00, 0x65, +0xB9, 0x65, 0x05, 0x97, 0x04, 0x91, 0x03, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFC, 0x63, 0x07, 0x62, +0x06, 0xD1, 0x04, 0x01, 0x00, 0x6A, 0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, +0x40, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x40, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xA0, 0xF2, 0x60, 0x9B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x50, 0x9A, 0x01, 0x6B, +0x6E, 0xEA, 0x16, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, +0x44, 0xAA, 0x02, 0x6B, 0x6E, 0xEA, 0x0C, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x01, 0x6B, 0x64, 0xCA, 0x04, 0x6C, 0x00, 0x6D, 0x00, 0x18, 0xDC, 0x0E, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x01, 0x6B, 0x64, 0xCA, +0xB9, 0x65, 0x03, 0x97, 0x02, 0x91, 0x02, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFF, 0x63, 0x01, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x02, 0x6B, +0x64, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x40, 0x9A, 0x00, 0x6B, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, +0x74, 0xDA, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xFC, 0x63, 0x07, 0x62, +0x06, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x54, 0x9A, +0x1C, 0xF0, 0x00, 0x4A, 0x0E, 0x5A, 0x78, 0x67, 0x20, 0xF1, 0x00, 0x23, 0x48, 0x33, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF1, 0x0C, 0x4A, 0x49, 0xE3, 0x40, 0x9A, 0x00, 0xEA, +0x00, 0x18, 0x60, 0x0D, 0x44, 0xC1, 0x44, 0xA1, 0x01, 0x6B, 0x6E, 0xEA, 0x00, 0xF1, 0x10, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x01, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, +0x08, 0x11, 0x00, 0x18, 0xA4, 0x0A, 0x44, 0xC1, 0x44, 0xA1, 0x02, 0x2A, 0x00, 0x6A, 0x02, 0x11, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x05, 0x6B, 0x60, 0xCA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x01, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, +0xF0, 0x10, 0x01, 0x6C, 0x00, 0x18, 0xB4, 0x0A, 0x44, 0xC1, 0x44, 0xA1, 0x0A, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, +0xE1, 0x10, 0x44, 0xA1, 0x01, 0x6B, 0x6E, 0xEA, 0x0A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x04, 0xF0, 0x01, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0xD3, 0x10, 0x44, 0xA1, +0x02, 0x6B, 0x6E, 0xEA, 0x0A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, +0x0C, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0xC5, 0x10, 0x44, 0xA1, 0x07, 0x6B, 0x6E, 0xEA, +0x0A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x03, 0x6B, 0xC0, 0xF6, +0x74, 0xDA, 0x00, 0x6A, 0xB7, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, +0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0xAD, 0x10, 0x02, 0x6C, 0x00, 0x18, 0xA1, 0x0B, +0x44, 0xC1, 0x44, 0xA1, 0x0A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, +0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0x9D, 0x10, 0x44, 0xA1, 0x01, 0x6B, 0x6E, 0xEA, +0x0A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x03, 0x6B, 0xC0, 0xF6, +0x74, 0xDA, 0x00, 0x6A, 0x8F, 0x10, 0x44, 0xA1, 0x02, 0x6B, 0x6E, 0xEA, 0x12, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x0C, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x07, 0x6B, 0x60, 0xCA, 0x00, 0x6A, +0x79, 0x10, 0x44, 0xA1, 0x07, 0x6B, 0x6E, 0xEA, 0x12, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x04, 0xF0, 0x0C, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x07, 0x6B, 0x60, 0xCA, 0x00, 0x6A, 0x63, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, +0x59, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x4B, 0xA2, +0x12, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, +0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x05, 0x6B, +0x60, 0xCA, 0x00, 0x6A, 0x3F, 0x10, 0x00, 0x18, 0x40, 0x0D, 0x44, 0xC1, 0x44, 0xA1, 0x03, 0x6B, +0x6E, 0xEA, 0x12, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, +0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x0D, 0x6B, +0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0x26, 0x10, 0x44, 0xA1, 0x12, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x04, 0xF0, 0x00, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x58, 0x9A, 0x05, 0x6B, 0x60, 0xCA, 0x00, 0x6A, 0x12, 0x10, +0x44, 0xA1, 0x02, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x04, 0xF0, 0x0C, 0x6B, 0xC0, 0xF6, 0x74, 0xDA, 0x00, 0x6A, 0x04, 0x10, 0x00, 0x6A, 0x02, 0x10, +0x00, 0x65, 0x00, 0x10, 0xB9, 0x65, 0x03, 0x97, 0x02, 0x91, 0x02, 0x63, 0x00, 0xEF, 0x00, 0x65, +0xFD, 0x63, 0x05, 0x62, 0x04, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x48, 0xA2, 0x26, 0x6B, 0x6E, 0xEA, 0x02, 0x2A, 0x00, 0x18, 0xD3, 0x06, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x48, 0xA2, 0x52, 0x6B, 0x6E, 0xEA, 0x02, 0x2A, +0x00, 0x18, 0xD3, 0x06, 0x01, 0x6A, 0xB9, 0x65, 0x01, 0x97, 0x00, 0x91, 0x01, 0x63, 0x00, 0xEF, +0xFA, 0x63, 0x0B, 0x62, 0x0A, 0xD1, 0x04, 0x01, 0x44, 0x67, 0x20, 0xF0, 0x40, 0xC1, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x40, 0xC1, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x48, 0xA2, 0x93, 0x6B, 0x6E, 0xEA, 0xA0, 0xF1, 0x14, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x70, 0x6C, +0x8E, 0xEA, 0x05, 0x2A, 0x00, 0x6C, 0x00, 0x18, 0xC2, 0x0C, 0x07, 0x6A, 0xA6, 0x11, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x20, 0x5A, 0x58, 0x67, +0x02, 0x22, 0x00, 0x6A, 0x9A, 0x11, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x41, 0xA2, 0x68, 0x5A, 0x58, 0x67, 0x02, 0x2A, 0x00, 0x6A, 0x8E, 0x11, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x20, 0x6B, 0x6E, 0xEA, +0x4D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x78, 0x6B, 0x6B, 0xEB, 0x80, 0xF6, +0x68, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6C, 0xA2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x61, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6D, 0xA2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x62, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6E, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x08, 0x4A, 0x63, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x6F, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x64, 0xC2, 0x40, 0xA1, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x80, 0xF6, 0x08, 0x4B, +0x83, 0x67, 0xA2, 0x67, 0x00, 0x18, 0x4F, 0x0C, 0x01, 0x6A, 0x37, 0x11, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x48, 0xA2, 0x30, 0x6C, 0x8E, 0xEA, 0x0E, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x04, 0x2A, 0x00, 0x18, +0xAA, 0x0D, 0x02, 0x6A, 0x22, 0x11, 0x00, 0x6A, 0x20, 0x11, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x62, 0x67, 0x0F, 0x6A, 0x6C, 0xEA, 0x16, 0x22, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x52, 0x33, +0xFF, 0x6A, 0x6C, 0xEA, 0x62, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, +0x0C, 0x4A, 0x43, 0xAA, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0xFF, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x62, 0x67, 0x0F, 0x6A, 0x4C, 0xEB, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x49, 0xA2, 0x6E, 0xEA, +0x02, 0x22, 0x00, 0x6A, 0xEA, 0x10, 0x40, 0xA1, 0xE0, 0x4A, 0x53, 0x32, 0x43, 0xC1, 0x00, 0x6A, +0x42, 0xC1, 0x2C, 0x10, 0x42, 0xA1, 0x0F, 0x2A, 0x42, 0xA1, 0x62, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, 0x40, 0xA2, 0x88, 0x6B, 0x6E, 0xEA, +0x1A, 0x22, 0x00, 0x6A, 0xD2, 0x10, 0x42, 0xA1, 0x62, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, 0x60, 0xA2, 0x42, 0xA1, 0x8F, 0x42, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x49, 0xE4, 0x4C, 0xA2, 0x6E, 0xEA, +0x02, 0x22, 0x00, 0x6A, 0xBA, 0x10, 0x42, 0xA1, 0x01, 0x4A, 0x42, 0xC1, 0x62, 0xA1, 0x43, 0xA1, +0x43, 0xEB, 0x58, 0x67, 0xCF, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x61, 0xA2, 0x0F, 0x6A, 0x6C, 0xEA, 0x48, 0xC1, 0x48, 0xA1, 0x40, 0x22, 0x48, 0xA1, +0x08, 0x6B, 0x4B, 0xE3, 0x48, 0xC1, 0x43, 0xA1, 0x14, 0x2A, 0x48, 0xA1, 0x88, 0x6B, 0x83, 0x67, +0x84, 0xEA, 0x44, 0x67, 0x4A, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x42, 0xA2, 0x62, 0x67, 0x48, 0xA1, 0x83, 0x67, 0x84, 0xEA, 0x44, 0x67, 0x49, 0xC1, +0x20, 0x10, 0x43, 0xA1, 0x6F, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x49, 0xE3, 0x4C, 0xA2, 0x62, 0x67, 0x48, 0xA1, 0x83, 0x67, 0x84, 0xEA, 0x44, 0x67, +0x4A, 0xC1, 0x43, 0xA1, 0x62, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x49, 0xE3, 0x40, 0xA2, 0x62, 0x67, 0x48, 0xA1, 0x83, 0x67, 0x84, 0xEA, 0x44, 0x67, +0x49, 0xC1, 0x6A, 0xA1, 0x49, 0xA1, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x66, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6F, 0xA2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x64, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6E, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x08, 0x4A, 0x63, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x6D, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x62, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x6C, 0xA2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x61, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x78, 0x6B, 0x6B, 0xEB, 0x80, 0xF6, 0x68, 0xC2, 0x00, 0x6A, +0x42, 0xC1, 0x12, 0x10, 0x42, 0xA1, 0x83, 0xA1, 0x62, 0xA1, 0x71, 0xE4, 0x10, 0xF0, 0x10, 0x6B, +0x60, 0x33, 0x60, 0x33, 0x80, 0xF6, 0x08, 0x4B, 0x6D, 0xE4, 0x60, 0xA3, 0x91, 0x67, 0x49, 0xE4, +0x70, 0xC2, 0x42, 0xA1, 0x01, 0x4A, 0x42, 0xC1, 0x62, 0xA1, 0x43, 0xA1, 0x05, 0x6C, 0x4B, 0xE4, +0x42, 0xEB, 0x58, 0x67, 0xE7, 0x2A, 0x40, 0xA1, 0x67, 0x41, 0x09, 0x4B, 0x83, 0x67, 0xA2, 0x67, +0x00, 0x18, 0x4F, 0x0C, 0x01, 0x6A, 0x01, 0x10, 0x00, 0x6A, 0xB9, 0x65, 0x07, 0x97, 0x06, 0x91, +0x04, 0x63, 0x00, 0xEF, 0xFA, 0x63, 0x0B, 0x62, 0x0A, 0xD1, 0x04, 0x01, 0x44, 0x67, 0x20, 0xF0, +0x40, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, +0x40, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x48, 0xA2, 0x95, 0x6B, +0x6E, 0xEA, 0x20, 0xF1, 0x1D, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x41, 0xA2, 0x70, 0x6C, 0x8E, 0xEA, 0x05, 0x2A, 0x01, 0x6C, 0x00, 0x18, 0xC2, 0x0C, +0x07, 0x6A, 0x2F, 0x11, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x41, 0xA2, 0x20, 0x6B, 0x6E, 0xEA, 0x52, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x70, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x68, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x71, 0xA2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x61, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x72, 0xA2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x62, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x73, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x08, 0x4A, 0x63, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, +0x14, 0x4A, 0x74, 0xA2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x64, 0xC2, 0x40, 0xA1, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x80, 0xF6, 0x08, 0x4B, +0x83, 0x67, 0xA2, 0x67, 0x00, 0x18, 0x4F, 0x0C, 0x01, 0x6A, 0xD3, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x48, 0xA2, 0x30, 0x6C, 0x8E, 0xEA, 0x0E, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x04, 0x2A, 0x00, 0x18, +0xAA, 0x0D, 0x02, 0x6A, 0xBE, 0x10, 0x00, 0x6A, 0xBC, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x62, 0x67, 0x01, 0x6A, 0x4C, 0xEB, 0xFF, 0x6A, +0x6C, 0xEA, 0x16, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x41, 0xA2, 0x52, 0x33, 0xFF, 0x6A, 0x6C, 0xEA, 0x62, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, 0x43, 0xAA, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x99, 0x10, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x62, 0x67, +0x0F, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x0C, 0x4A, +0x49, 0xA2, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x84, 0x10, 0x40, 0xA1, 0xE0, 0x4A, 0x53, 0x32, +0x42, 0xC1, 0x00, 0x6A, 0x41, 0xC1, 0x1B, 0x10, 0x41, 0xA1, 0x62, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, 0x60, 0xA2, 0x41, 0xA1, 0x84, 0x42, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x49, 0xE4, 0x4C, 0xA2, +0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x65, 0x10, 0x41, 0xA1, 0x01, 0x4A, 0x41, 0xC1, 0x61, 0xA1, +0x42, 0xA1, 0x43, 0xEB, 0x58, 0x67, 0xE0, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x08, 0x4A, 0x61, 0xA2, 0x0F, 0x6A, 0x6C, 0xEA, 0x45, 0xC1, 0x45, 0xA1, 0x2A, 0x22, +0x45, 0xA1, 0x08, 0x6B, 0x4B, 0xE3, 0x45, 0xC1, 0x42, 0xA1, 0x64, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x49, 0xE3, 0x4C, 0xA2, 0x62, 0x67, 0x45, 0xA1, +0x83, 0x67, 0x84, 0xEA, 0x44, 0x67, 0x44, 0xC1, 0x42, 0xA1, 0x62, 0x42, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, 0x40, 0xA2, 0x62, 0x67, 0x45, 0xA1, +0x83, 0x67, 0x84, 0xEA, 0x44, 0x67, 0x43, 0xC1, 0x64, 0xA1, 0x43, 0xA1, 0x6E, 0xEA, 0x02, 0x22, +0x00, 0x6A, 0x27, 0x10, 0x00, 0x6A, 0x41, 0xC1, 0x13, 0x10, 0x41, 0xA1, 0x62, 0xA1, 0x84, 0x43, +0x61, 0xA1, 0x71, 0xE4, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF6, 0x14, 0x4B, +0x6D, 0xE4, 0x6C, 0xA3, 0x91, 0x67, 0x49, 0xE4, 0x68, 0xC2, 0x41, 0xA1, 0x01, 0x4A, 0x41, 0xC1, +0x61, 0xA1, 0x42, 0xA1, 0x05, 0x6C, 0x4B, 0xE4, 0x42, 0xEB, 0x58, 0x67, 0xE6, 0x2A, 0x40, 0xA1, +0x67, 0x41, 0x01, 0x4B, 0x83, 0x67, 0xA2, 0x67, 0x00, 0x18, 0x4F, 0x0C, 0x01, 0x6A, 0x01, 0x10, +0x00, 0x6A, 0xB9, 0x65, 0x07, 0x97, 0x06, 0x91, 0x04, 0x63, 0x00, 0xEF, 0xFA, 0x63, 0x0B, 0xD1, +0x3D, 0x67, 0x8C, 0xD9, 0x45, 0x67, 0x20, 0xF0, 0x54, 0xC1, 0x00, 0x6A, 0x46, 0xC9, 0x00, 0x6A, +0x41, 0xD9, 0x4C, 0x99, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, +0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x54, 0x9A, 0x08, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x20, 0xF0, 0x74, 0xA1, 0x0F, 0x6A, 0x6C, 0xEA, +0x20, 0x22, 0x20, 0xF0, 0x54, 0xA1, 0x0F, 0x6B, 0x6C, 0xEA, 0x08, 0x6B, 0x4B, 0xE3, 0x46, 0xC9, +0x46, 0xA9, 0x40, 0x32, 0x46, 0xC9, 0x20, 0xF0, 0x54, 0xA1, 0xE0, 0x4A, 0x53, 0x33, 0xFF, 0xF7, +0x1F, 0x6A, 0x6C, 0xEA, 0x66, 0xA9, 0x4F, 0xE3, 0xFF, 0xF7, 0x1F, 0x6A, 0x6C, 0xEA, 0x04, 0x4A, +0x46, 0xC9, 0x66, 0xA9, 0xFF, 0x6A, 0x6C, 0xEA, 0x45, 0xC9, 0x45, 0xA9, 0x01, 0x4A, 0x45, 0xC9, +0x10, 0x10, 0x20, 0xF0, 0x54, 0xA1, 0xE0, 0x4A, 0x53, 0x33, 0xFF, 0xF7, 0x1F, 0x6A, 0x6C, 0xEA, +0x66, 0xA9, 0x4F, 0xE3, 0xFF, 0xF7, 0x1F, 0x6A, 0x6C, 0xEA, 0x05, 0x4A, 0x46, 0xC9, 0x46, 0xA9, +0x45, 0xC9, 0x46, 0xA9, 0x05, 0x6B, 0x6E, 0xEA, 0x09, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, 0x08, 0x6B, 0x60, 0xC2, 0x08, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, 0x48, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x40, 0x9A, 0x66, 0xA9, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, +0x45, 0xA9, 0x05, 0x5A, 0x58, 0x67, 0x0A, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF2, 0x44, 0x9A, 0x60, 0x99, 0x60, 0x9B, 0x60, 0xDA, 0x13, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x60, 0x99, 0x60, 0x9B, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x60, 0x99, 0x04, 0x4B, 0x60, 0x9B, +0x60, 0xDA, 0x00, 0x6A, 0x44, 0xD9, 0x0D, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF6, 0x4C, 0x9A, 0x12, 0xF0, 0x04, 0x6B, 0x6E, 0xEA, 0x09, 0x22, 0x44, 0x99, 0x01, 0x4A, +0x44, 0xD9, 0x44, 0x99, 0xE5, 0xF7, 0x1F, 0x5A, 0x58, 0x67, 0xEE, 0x2A, 0x01, 0x10, 0x00, 0x65, +0xB9, 0x65, 0x0B, 0x91, 0x06, 0x63, 0x20, 0xE8, 0xFC, 0x63, 0x07, 0x62, 0x06, 0xD1, 0x04, 0x01, +0x44, 0x67, 0x50, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, +0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x54, 0x9A, 0x04, 0xF0, +0x01, 0x6B, 0x6E, 0xEA, 0x26, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, +0x08, 0x4A, 0x42, 0xA2, 0x88, 0x6B, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x3F, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x62, 0x67, 0x80, 0xF6, 0x0B, 0x4B, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xE0, 0xF6, 0x00, 0x4A, 0x83, 0x67, 0xA2, 0x67, 0x03, 0x6E, 0x00, 0x18, +0xCE, 0x05, 0x01, 0x6B, 0x6E, 0xEA, 0x02, 0x22, 0x00, 0x6A, 0x28, 0x10, 0x00, 0x6C, 0x00, 0x18, +0xF6, 0x0C, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x54, 0x9A, 0x04, 0xF0, +0x03, 0x6B, 0x6E, 0xEA, 0x1A, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x62, 0x67, +0x80, 0xF6, 0x0A, 0x4B, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF6, 0x04, 0x4A, +0x83, 0x67, 0xA2, 0x67, 0x04, 0x6E, 0x00, 0x18, 0xCE, 0x05, 0x01, 0x6B, 0x6E, 0xEA, 0x02, 0x22, +0x00, 0x6A, 0x04, 0x10, 0x01, 0x6C, 0x00, 0x18, 0xF6, 0x0C, 0x00, 0x10, 0xB9, 0x65, 0x03, 0x97, +0x02, 0x91, 0x02, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x44, 0x67, +0x50, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, +0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, +0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, +0x07, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, +0x08, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, +0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x40, 0xF2, 0x40, 0x9A, 0x01, 0x6B, 0x60, 0xCA, 0x50, 0xA1, 0x09, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x04, 0x6B, 0x60, 0xDA, 0x08, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0x00, 0x6A, +0x40, 0xD9, 0x0D, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x4C, 0x9A, +0x12, 0xF0, 0x04, 0x6B, 0x6E, 0xEA, 0x0E, 0x22, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x60, 0x99, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x44, 0x9A, 0x63, 0xEA, 0x58, 0x67, +0xE9, 0x22, 0x01, 0x10, 0x00, 0x65, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0x00, 0x65, +0xFF, 0x63, 0x01, 0xD1, 0x3D, 0x67, 0xB9, 0x65, 0x01, 0x91, 0x01, 0x63, 0x20, 0xE8, 0x00, 0x65, +0xFD, 0x63, 0x05, 0x62, 0x04, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x48, 0xA2, 0x50, 0x6B, 0x4E, 0xEB, 0x11, 0x23, 0x51, 0x52, 0x78, 0x67, 0x07, 0x23, +0x1A, 0x6B, 0x4E, 0xEB, 0x23, 0x23, 0x30, 0x6B, 0x6E, 0xEA, 0x18, 0x22, 0x23, 0x10, 0x60, 0x6B, +0x4E, 0xEB, 0x18, 0x23, 0xA2, 0x6B, 0x6E, 0xEA, 0x0D, 0x22, 0x1C, 0x10, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x02, 0x22, 0x00, 0x6A, 0x13, 0x10, +0x03, 0x6A, 0x11, 0x10, 0x00, 0x18, 0x6C, 0x0D, 0x01, 0x6A, 0x0D, 0x10, 0x00, 0x18, 0xAA, 0x0D, +0x02, 0x6A, 0x09, 0x10, 0x00, 0x18, 0x0E, 0x07, 0x04, 0x6A, 0x05, 0x10, 0x00, 0x18, 0x49, 0x07, +0x04, 0x6A, 0x01, 0x10, 0x00, 0x6A, 0xB9, 0x65, 0x01, 0x97, 0x00, 0x91, 0x01, 0x63, 0x00, 0xEF, +0xFD, 0x63, 0x05, 0x62, 0x04, 0xD1, 0x04, 0x01, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF6, 0x48, 0xA2, 0x52, 0x6B, 0x6E, 0xEA, 0x04, 0x2A, 0x00, 0x18, 0xD3, 0x06, 0x01, 0x6A, +0x01, 0x10, 0x00, 0x6A, 0xB9, 0x65, 0x01, 0x97, 0x00, 0x91, 0x01, 0x63, 0x00, 0xEF, 0x00, 0x65, +0xFB, 0x63, 0x09, 0x62, 0x08, 0xD1, 0x04, 0x01, 0x00, 0x6A, 0x42, 0xC1, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x42, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x41, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x4A, 0xA2, 0x40, 0xC1, 0x41, 0xA1, 0x2A, 0x5A, 0x58, 0x67, +0x01, 0x6B, 0x6E, 0xEA, 0x62, 0x67, 0xFF, 0x6A, 0x4C, 0xEB, 0x41, 0xA1, 0x02, 0x5A, 0x58, 0x67, +0x82, 0x67, 0xFF, 0x6A, 0x8C, 0xEA, 0x4D, 0xEB, 0xFF, 0x6A, 0x6C, 0xEA, 0x05, 0x22, 0x00, 0x6C, +0x00, 0x18, 0x03, 0x0E, 0x00, 0x6A, 0x42, 0x10, 0x42, 0xA1, 0x28, 0x22, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x48, 0x32, 0x44, 0xC1, 0x00, 0x6A, +0x43, 0xC1, 0x18, 0x10, 0x64, 0xA1, 0x43, 0xA1, 0x51, 0xE3, 0x43, 0xA1, 0x62, 0x42, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, 0x60, 0xA2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x49, 0xE4, 0x60, 0xC2, 0x43, 0xA1, +0x01, 0x4A, 0x43, 0xC1, 0x43, 0xA1, 0x04, 0x5A, 0x58, 0x67, 0xE4, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x50, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x0B, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x01, 0x6C, 0xA2, 0x67, +0x00, 0x18, 0xDC, 0x0E, 0x0A, 0x6C, 0x00, 0x18, 0x03, 0x0E, 0x01, 0x6A, 0xB9, 0x65, 0x05, 0x97, +0x04, 0x91, 0x03, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFB, 0x63, 0x09, 0x62, 0x08, 0xD1, 0x04, 0x01, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x41, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x50, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x4C, 0x9A, 0x00, 0xF4, 0x07, 0x6B, 0x60, 0xCA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x54, 0x9A, 0x08, 0x6B, 0x60, 0xC2, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x2A, 0x5A, +0x58, 0x67, 0x07, 0x2A, 0x00, 0x6C, 0x00, 0x18, 0x03, 0x0E, 0x00, 0x6A, 0x62, 0x67, 0x43, 0x67, +0x6F, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, +0x48, 0x32, 0x61, 0x99, 0x49, 0xE3, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF3, 0x48, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x40, 0x9A, 0x10, 0x6B, 0x60, 0xCA, 0x00, 0x6A, 0x48, 0xC1, +0x0F, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x68, 0xA1, +0x68, 0x33, 0x81, 0x99, 0x6D, 0xE4, 0x60, 0x9B, 0x60, 0xDA, 0x48, 0xA1, 0x01, 0x4A, 0x48, 0xC1, +0x48, 0xA1, 0x04, 0x5A, 0x58, 0x67, 0xED, 0x2A, 0x00, 0x6A, 0x40, 0xD9, 0x0D, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x4C, 0x9A, 0x12, 0xF0, 0x04, 0x6B, 0x6E, 0xEA, +0x0E, 0x22, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x60, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0xA0, 0xF2, 0x44, 0x9A, 0x63, 0xEA, 0x58, 0x67, 0xE9, 0x22, 0x01, 0x10, 0x00, 0x65, +0xB9, 0x65, 0x05, 0x97, 0x04, 0x91, 0x03, 0x63, 0x00, 0xEF, 0x00, 0x65, 0xFE, 0x63, 0x03, 0xD1, +0x3D, 0x67, 0x44, 0x67, 0x50, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x50, 0x9A, 0x01, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, +0x4C, 0x9A, 0x00, 0xF4, 0x05, 0x6B, 0x60, 0xCA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x20, 0xF2, 0x54, 0x9A, 0x00, 0x6B, 0x60, 0xC2, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x12, 0xF0, 0x06, 0x6B, 0x60, 0xF6, 0x6C, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF3, 0x48, 0x9A, 0x01, 0x6B, 0x6E, 0xEA, 0x08, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x1B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF3, 0x48, 0x9A, 0x02, 0x6B, 0x6E, 0xEA, 0x10, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x5C, 0x9A, 0x02, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x20, 0xF2, 0x58, 0x9A, 0x0B, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x40, 0x9A, 0x00, 0xF4, 0x00, 0x6B, 0x60, 0xCA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x40, 0xF2, 0x44, 0x9A, 0x70, 0xA1, 0x60, 0xDA, 0x00, 0x6A, +0x40, 0xD9, 0x0D, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x60, 0xF6, 0x4C, 0x9A, +0x12, 0xF0, 0x04, 0x6B, 0x6E, 0xEA, 0x09, 0x22, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, +0xE5, 0xF7, 0x1F, 0x5A, 0x58, 0x67, 0xEE, 0x2A, 0x01, 0x10, 0x00, 0x65, 0xB9, 0x65, 0x03, 0x91, +0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x41, 0xD9, 0x61, 0x99, 0x02, 0x6A, 0x4B, 0xEA, +0x6C, 0xEA, 0x41, 0xD9, 0x00, 0x6A, 0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, +0x40, 0x99, 0x0A, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF2, 0x50, 0x9A, 0x61, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, +0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x48, 0x9A, 0x40, 0x9A, 0x41, 0xD9, 0x00, 0x6A, 0x40, 0xD9, +0x03, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, +0x61, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x4C, 0x9A, 0x6D, 0xEA, +0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x48, 0x9A, 0x61, 0x99, +0x60, 0xDA, 0x00, 0x6A, 0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, 0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, +0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x61, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF2, 0x50, 0x9A, 0x6C, 0xEA, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xA0, 0xF2, 0x48, 0x9A, 0x61, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x40, 0xD9, 0x03, 0x10, 0x40, 0x99, +0x01, 0x4A, 0x40, 0xD9, 0x40, 0x99, 0x32, 0x5A, 0x58, 0x67, 0xF9, 0x2A, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x54, 0x9A, 0x40, 0x9A, 0x41, 0xD9, 0x61, 0x99, 0x01, 0x6A, +0x6D, 0xEA, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x54, 0x9A, +0x61, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, +0x40, 0x9A, 0x41, 0xD9, 0x61, 0x99, 0x01, 0x6A, 0x6D, 0xEA, 0x41, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x61, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x03, 0x91, +0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x40, 0xD9, 0x60, 0x99, 0x02, 0x6A, 0x4B, 0xEA, +0x6C, 0xEA, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, +0x60, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, +0x3D, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, +0x40, 0xD9, 0x60, 0x99, 0x03, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x60, 0x99, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x58, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0xA0, 0xF2, 0x7C, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, +0x54, 0x9A, 0x40, 0x9A, 0x40, 0xD9, 0x60, 0x99, 0x02, 0x6A, 0x6D, 0xEA, 0x40, 0xD9, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x54, 0x9A, 0x60, 0x99, 0x60, 0xDA, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xA0, 0xF2, 0x58, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, +0x60, 0x33, 0xC0, 0xF2, 0x60, 0x9B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x40, 0xD9, 0x60, 0x99, 0x02, 0x6A, 0x6D, 0xEA, 0x40, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x60, 0x99, 0x60, 0xDA, +0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, 0xFE, 0x63, 0x03, 0xD1, 0x3D, 0x67, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x40, 0xD9, 0x60, 0x99, +0x03, 0x6A, 0x4B, 0xEA, 0x6C, 0xEA, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x80, 0xF2, 0x50, 0x9A, 0x60, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x03, 0x91, 0x02, 0x63, 0x20, 0xE8, +0xFC, 0x63, 0x07, 0xD1, 0x3D, 0x67, 0x64, 0x67, 0x45, 0x67, 0x20, 0xF0, 0x60, 0xC1, 0x20, 0xF0, +0x44, 0xC1, 0x00, 0x6A, 0x43, 0xD9, 0x00, 0x6A, 0x48, 0xC1, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF2, 0x44, 0x9A, 0x40, 0x9A, 0x40, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x60, 0xF2, 0x44, 0x9A, 0x00, 0x6B, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF0, 0x04, 0x4A, 0x41, 0xD9, 0x48, 0xA1, 0x45, 0xD9, 0x20, 0xF0, 0x40, 0xA1, +0x04, 0x6B, 0x6E, 0xEA, 0x20, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x54, 0xA2, 0x62, 0x67, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, +0x44, 0xAA, 0x6E, 0xEA, 0x60, 0xF1, 0x0F, 0x22, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF6, 0x14, 0x4A, 0x64, 0xAA, 0xFF, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF3, 0x74, 0xC2, 0x20, 0xF0, 0x40, 0xA1, 0x07, 0x5A, 0x78, 0x67, 0x40, 0xF1, +0x07, 0x23, 0x48, 0x33, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF2, 0x04, 0x4A, +0x49, 0xE3, 0x40, 0x9A, 0x00, 0xEA, 0x20, 0xF0, 0x44, 0xA1, 0x45, 0xD9, 0x45, 0x99, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF5, 0x00, 0x4A, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xC0, 0xF2, 0x44, 0x9A, 0x65, 0x99, 0x60, 0xDA, 0x00, 0x6A, 0x44, 0xD9, 0x12, 0x10, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x44, 0x9A, 0x20, 0xF0, 0x84, 0xA1, 0x64, 0x99, +0x6D, 0xE4, 0x68, 0x33, 0x81, 0x99, 0x6D, 0xE4, 0x60, 0x9B, 0x60, 0xDA, 0x44, 0x99, 0x01, 0x4A, +0x44, 0xD9, 0x44, 0x99, 0x04, 0x5A, 0x58, 0x67, 0xEA, 0x2A, 0x12, 0x11, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x41, 0xA2, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x40, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, +0x40, 0x32, 0x00, 0xF3, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x40, 0x9A, 0x80, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0x6B, 0x00, 0xF3, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, +0x44, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x60, 0x9B, 0x60, 0x34, +0x65, 0x99, 0x60, 0x33, 0x60, 0x33, 0x6D, 0xE4, 0x41, 0x4B, 0x60, 0xDA, 0x00, 0x6A, 0x45, 0xD9, +0x00, 0x6A, 0x44, 0xD9, 0x14, 0x10, 0x45, 0x99, 0x40, 0x32, 0x45, 0xD9, 0x05, 0x6B, 0x44, 0x99, +0x4F, 0xE3, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x80, 0xF6, 0x08, 0x4A, 0x49, 0xE3, +0x40, 0xA2, 0x65, 0x99, 0x49, 0xE3, 0x45, 0xD9, 0x44, 0x99, 0x01, 0x4A, 0x44, 0xD9, 0x44, 0x99, +0x04, 0x5A, 0x58, 0x67, 0xE8, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, +0x44, 0x9A, 0x65, 0x99, 0x60, 0xDA, 0xB4, 0x10, 0x20, 0xF0, 0x44, 0xA1, 0x45, 0xD9, 0x45, 0x99, +0x40, 0x32, 0x40, 0x32, 0x45, 0xD9, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, +0x44, 0x9A, 0x85, 0x99, 0x00, 0xF2, 0x02, 0x6B, 0x8D, 0xEB, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x44, 0x9A, 0x20, 0xF0, 0x64, 0xA1, 0x68, 0x33, 0x81, 0x99, +0x6D, 0xE4, 0x60, 0x9B, 0x60, 0xDA, 0x94, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x00, 0xF3, 0x40, 0x9A, 0x61, 0x42, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x40, 0x9A, 0x80, 0x6B, +0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0x00, 0xF3, +0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF6, 0x14, 0x4A, 0x44, 0xAA, +0x01, 0x6B, 0x6E, 0xEA, 0x16, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, +0x44, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x60, 0x9B, 0x60, 0x34, +0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF2, 0x68, 0x9B, 0x6D, 0xE4, 0x60, 0xDA, +0x57, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x44, 0x9A, 0x10, 0xF0, +0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x60, 0x9B, 0x60, 0x33, 0x24, 0x4B, 0x60, 0xDA, +0x47, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x40, 0x9A, 0x61, 0x42, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x60, 0xDA, 0x10, 0xF0, 0x10, 0x6A, +0x40, 0x32, 0x40, 0x32, 0x00, 0xF3, 0x40, 0x9A, 0x80, 0x6B, 0x6E, 0xEA, 0x07, 0x2A, 0x10, 0xF0, +0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0x00, 0x6B, 0x00, 0xF3, 0x60, 0xDA, 0x20, 0xF0, 0x44, 0xA1, +0x01, 0x6B, 0x6E, 0xEA, 0x16, 0x2A, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, +0x44, 0x9A, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x60, 0x9B, 0x60, 0x34, +0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF2, 0x6C, 0x9B, 0x6D, 0xE4, 0x60, 0xDA, +0x0F, 0x10, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x44, 0x9A, 0x10, 0xF0, +0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0x00, 0xF3, 0x60, 0x9B, 0x60, 0x33, 0x26, 0x4B, 0x60, 0xDA, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x50, 0x9A, 0x40, 0x9A, 0x45, 0xD9, +0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xC0, 0xF2, 0x50, 0x9A, 0x85, 0x99, 0x01, 0x6B, +0x8D, 0xEB, 0x60, 0xDA, 0x01, 0x10, 0x00, 0x65, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0x60, 0xF2, 0x44, 0x9A, 0x60, 0x99, 0x60, 0xDA, 0xB9, 0x65, 0x07, 0x91, 0x04, 0x63, 0x20, 0xE8, +0xFD, 0x63, 0x05, 0xD1, 0x3D, 0x67, 0x86, 0xD9, 0xA7, 0xD9, 0x00, 0x6A, 0x41, 0xD9, 0x41, 0x99, +0x42, 0xD9, 0x46, 0x99, 0x43, 0xD9, 0x34, 0x10, 0x41, 0xA1, 0x30, 0x5A, 0x58, 0x67, 0x08, 0x2A, +0x41, 0xA1, 0x3A, 0x5A, 0x58, 0x67, 0x04, 0x22, 0x41, 0xA1, 0xD0, 0x4A, 0x40, 0xC1, 0x1A, 0x10, +0x41, 0xA1, 0x61, 0x5A, 0x58, 0x67, 0x08, 0x2A, 0x41, 0xA1, 0x67, 0x5A, 0x58, 0x67, 0x04, 0x22, +0x41, 0xA1, 0xA9, 0x4A, 0x40, 0xC1, 0x0E, 0x10, 0x41, 0xA1, 0x41, 0x5A, 0x58, 0x67, 0x08, 0x2A, +0x41, 0xA1, 0x47, 0x5A, 0x58, 0x67, 0x04, 0x22, 0x41, 0xA1, 0xC9, 0x4A, 0x40, 0xC1, 0x02, 0x10, +0x00, 0x6A, 0x1F, 0x10, 0x41, 0x99, 0x50, 0x33, 0x40, 0xA1, 0x49, 0xE3, 0x42, 0xD9, 0x62, 0x99, +0x41, 0x99, 0x43, 0xEB, 0x58, 0x67, 0x02, 0x22, 0x00, 0x6A, 0x13, 0x10, 0x42, 0x99, 0x41, 0xD9, +0x43, 0x99, 0x40, 0xA2, 0x41, 0xC1, 0x00, 0x6A, 0x61, 0xA1, 0x01, 0x23, 0x01, 0x6A, 0xFF, 0x6B, +0x6C, 0xEA, 0x63, 0x99, 0x01, 0x4B, 0x63, 0xD9, 0xBF, 0x2A, 0x47, 0x99, 0x61, 0x99, 0x60, 0xDA, +0x01, 0x6A, 0xB9, 0x65, 0x05, 0x91, 0x03, 0x63, 0x20, 0xE8, 0x00, 0x65, 0xF3, 0x63, 0x19, 0x62, +0x18, 0xD1, 0x04, 0x01, 0x96, 0xD9, 0xB7, 0xD9, 0xD8, 0xD9, 0x56, 0x99, 0x4B, 0xD9, 0xB5, 0x11, +0x57, 0x99, 0x40, 0x82, 0x25, 0x6B, 0x6E, 0xEA, 0x10, 0x22, 0x56, 0x99, 0x08, 0x22, 0x57, 0x99, +0x60, 0x82, 0x4B, 0x99, 0x60, 0xC2, 0x4B, 0x99, 0x01, 0x4A, 0x4B, 0xD9, 0xA3, 0x11, 0x57, 0x99, +0x40, 0x82, 0x82, 0x67, 0x00, 0x18, 0x3B, 0x03, 0x9D, 0x11, 0x57, 0x99, 0x01, 0x4A, 0x57, 0xD9, +0x57, 0x99, 0x40, 0x82, 0x73, 0x6B, 0x6E, 0xEA, 0x1D, 0x2A, 0x58, 0x99, 0x40, 0x9A, 0x4C, 0xD9, +0x58, 0x99, 0x04, 0x4A, 0x58, 0xD9, 0x12, 0x10, 0x56, 0x99, 0x08, 0x22, 0x4C, 0x99, 0x60, 0x82, +0x4B, 0x99, 0x60, 0xC2, 0x4B, 0x99, 0x01, 0x4A, 0x4B, 0xD9, 0x05, 0x10, 0x4C, 0x99, 0x40, 0x82, +0x82, 0x67, 0x00, 0x18, 0x3B, 0x03, 0x4C, 0x99, 0x01, 0x4A, 0x4C, 0xD9, 0x4C, 0x99, 0x40, 0x82, +0xEB, 0x2A, 0x78, 0x11, 0x47, 0x41, 0x2D, 0x4A, 0x4A, 0xD9, 0x00, 0x6A, 0x49, 0xD9, 0x04, 0x6A, +0x48, 0xD9, 0x57, 0x99, 0x40, 0x82, 0x23, 0x6B, 0x6E, 0xEA, 0x05, 0x2A, 0x01, 0x6A, 0x49, 0xD9, +0x57, 0x99, 0x01, 0x4A, 0x57, 0xD9, 0x57, 0x99, 0x40, 0x82, 0x68, 0x6B, 0x6E, 0xEA, 0x05, 0x2A, +0x0C, 0x6A, 0x48, 0xD9, 0x57, 0x99, 0x01, 0x4A, 0x57, 0xD9, 0x57, 0x99, 0x40, 0x82, 0x68, 0x6B, +0x6E, 0xEA, 0x05, 0x2A, 0x04, 0x6A, 0x48, 0xD9, 0x57, 0x99, 0x01, 0x4A, 0x57, 0xD9, 0x57, 0x99, +0x60, 0x82, 0x20, 0x6A, 0x6D, 0xEA, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x78, 0x6B, +0x6E, 0xEA, 0x4F, 0x2A, 0x58, 0x99, 0x47, 0xD9, 0x47, 0x99, 0x40, 0x9A, 0x46, 0xD9, 0x47, 0x99, +0x04, 0x4A, 0x47, 0xD9, 0x57, 0x99, 0x60, 0x82, 0xFF, 0x6A, 0x6C, 0xEA, 0x62, 0x67, 0x20, 0x6A, +0x6C, 0xEA, 0x45, 0xD9, 0x47, 0x99, 0x58, 0xD9, 0x49, 0x99, 0x36, 0x22, 0x4A, 0x99, 0x30, 0x6B, +0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x45, 0x99, 0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, +0x63, 0x33, 0x58, 0x6A, 0x6D, 0xEA, 0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, 0x63, 0x33, 0x4A, 0x99, +0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x1F, 0x10, 0x66, 0x99, 0x48, 0x99, 0x67, 0xEA, +0x0F, 0x6A, 0x4C, 0xEB, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, 0xE0, 0xF2, 0x00, 0x4A, +0x49, 0xE3, 0x60, 0x82, 0x45, 0x99, 0x00, 0xF6, 0x40, 0x32, 0x00, 0xF6, 0x43, 0x32, 0x6D, 0xEA, +0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, 0x63, 0x33, 0x4A, 0x99, 0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, +0x4A, 0xD9, 0x48, 0x99, 0xFC, 0x4A, 0x48, 0xD9, 0x48, 0x99, 0x00, 0x52, 0x58, 0x67, 0xDD, 0x22, +0xDE, 0x10, 0x57, 0x99, 0x40, 0x82, 0x64, 0x6B, 0x6E, 0xEA, 0x62, 0x2A, 0x58, 0x99, 0x40, 0x9A, +0x44, 0xD9, 0x58, 0x99, 0x04, 0x4A, 0x58, 0xD9, 0x44, 0x99, 0x00, 0x52, 0x58, 0x67, 0x09, 0x22, +0x4A, 0x99, 0x2D, 0x6B, 0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x44, 0x99, 0x4B, 0xEA, +0x44, 0xD9, 0x4A, 0x99, 0x4C, 0xD9, 0x64, 0x99, 0x10, 0xF0, 0x10, 0x6A, 0x40, 0x32, 0x40, 0x32, +0xE0, 0xF2, 0x54, 0x9A, 0x58, 0xEB, 0x10, 0xEA, 0x4B, 0x34, 0xC0, 0xF7, 0x63, 0x32, 0x4B, 0xE4, +0x44, 0x32, 0x48, 0x34, 0x89, 0xE2, 0x4B, 0xE3, 0xFF, 0x6B, 0x6C, 0xEA, 0x67, 0x42, 0x29, 0x4B, +0xFF, 0x6A, 0x6C, 0xEA, 0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, 0x63, 0x33, 0x4A, 0x99, 0x60, 0xC2, +0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x44, 0x99, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, +0xE0, 0xF2, 0x74, 0x9B, 0x78, 0xEA, 0x10, 0xEB, 0x6B, 0x33, 0xC0, 0xF7, 0x43, 0x32, 0x4B, 0xE3, +0x44, 0xD9, 0x44, 0x99, 0xD0, 0x2A, 0x4A, 0x99, 0x43, 0xD9, 0x11, 0x10, 0x43, 0x99, 0x40, 0x82, +0x44, 0xD9, 0x4C, 0x99, 0x60, 0x82, 0x43, 0x99, 0x60, 0xC2, 0x44, 0x99, 0x00, 0xF6, 0x40, 0x33, +0x00, 0xF6, 0x63, 0x33, 0x4C, 0x99, 0x60, 0xC2, 0x4C, 0x99, 0x01, 0x4A, 0x4C, 0xD9, 0x43, 0x99, +0xFF, 0x4A, 0x43, 0xD9, 0x63, 0x99, 0x4C, 0x99, 0x63, 0xEA, 0x58, 0x67, 0xE7, 0x2A, 0x77, 0x10, +0x57, 0x99, 0x40, 0x82, 0x40, 0x6B, 0x6E, 0xEA, 0x2C, 0x2A, 0x58, 0x99, 0x41, 0xD9, 0x41, 0x99, +0x40, 0x9A, 0x52, 0xD9, 0x41, 0x99, 0x04, 0x4A, 0x41, 0xD9, 0x41, 0x99, 0x58, 0xD9, 0x47, 0x41, +0x41, 0x4A, 0x42, 0xD9, 0x13, 0x10, 0x42, 0x99, 0x40, 0xA2, 0x8A, 0x99, 0x10, 0xF0, 0x10, 0x6B, +0x60, 0x33, 0x60, 0x33, 0xC0, 0xF2, 0x14, 0x4B, 0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, 0xD6, 0x10, +0x6A, 0x99, 0x49, 0xE3, 0x4A, 0xD9, 0x42, 0x99, 0x01, 0x4A, 0x42, 0xD9, 0x47, 0x41, 0x41, 0x4A, +0x64, 0x42, 0x42, 0x99, 0x63, 0xEA, 0x58, 0x67, 0xE6, 0x2A, 0x4A, 0x99, 0xFF, 0x4A, 0x4A, 0xD9, +0x46, 0x10, 0x57, 0x99, 0x40, 0x82, 0x21, 0x6B, 0x6E, 0xEA, 0x26, 0x2A, 0x58, 0x99, 0x40, 0x9A, +0x4C, 0xD9, 0x58, 0x99, 0x04, 0x4A, 0x58, 0xD9, 0x4C, 0x99, 0x06, 0x4A, 0x40, 0xD9, 0x13, 0x10, +0x4C, 0x99, 0x40, 0x82, 0x8A, 0x99, 0x10, 0xF0, 0x10, 0x6B, 0x60, 0x33, 0x60, 0x33, 0xC0, 0xF2, +0x18, 0x4B, 0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, 0xD6, 0x10, 0x6A, 0x99, 0x49, 0xE3, 0x4A, 0xD9, +0x4C, 0x99, 0x01, 0x4A, 0x4C, 0xD9, 0x6C, 0x99, 0x40, 0x99, 0x43, 0xEB, 0x58, 0x67, 0xE8, 0x2A, +0x4A, 0x99, 0xFF, 0x4A, 0x4A, 0xD9, 0x1B, 0x10, 0x57, 0x99, 0x40, 0x82, 0x63, 0x6B, 0x6E, 0xEA, +0x0F, 0x2A, 0x58, 0x99, 0x40, 0x9A, 0x00, 0xF6, 0x40, 0x33, 0x00, 0xF6, 0x63, 0x33, 0x4A, 0x99, +0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x58, 0x99, 0x04, 0x4A, 0x58, 0xD9, 0x07, 0x10, +0x57, 0x99, 0x60, 0x82, 0x4A, 0x99, 0x60, 0xC2, 0x4A, 0x99, 0x01, 0x4A, 0x4A, 0xD9, 0x47, 0x41, +0x2D, 0x4A, 0x4C, 0xD9, 0x12, 0x10, 0x56, 0x99, 0x08, 0x22, 0x4C, 0x99, 0x60, 0x82, 0x4B, 0x99, +0x60, 0xC2, 0x4B, 0x99, 0x01, 0x4A, 0x4B, 0xD9, 0x05, 0x10, 0x4C, 0x99, 0x40, 0x82, 0x82, 0x67, +0x00, 0x18, 0x3B, 0x03, 0x4C, 0x99, 0x01, 0x4A, 0x4C, 0xD9, 0x6C, 0x99, 0x4A, 0x99, 0x43, 0xEB, +0x58, 0x67, 0xE9, 0x2A, 0x57, 0x99, 0x01, 0x4A, 0x57, 0xD9, 0x57, 0x99, 0x40, 0x82, 0x5F, 0xF6, +0x07, 0x2A, 0x56, 0x99, 0x03, 0x22, 0x4B, 0x99, 0x00, 0x6B, 0x60, 0xC2, 0x6B, 0x99, 0x56, 0x99, +0x4B, 0xE3, 0xB9, 0x65, 0x15, 0x97, 0x14, 0x91, 0x0B, 0x63, 0x00, 0xEF, 0xFD, 0x63, 0x05, 0x62, +0x04, 0xD1, 0x04, 0x01, 0xA3, 0xD9, 0xC4, 0xD9, 0xE5, 0xD9, 0x82, 0xD9, 0x62, 0x99, 0x47, 0x41, +0x01, 0x4A, 0x04, 0x4A, 0x00, 0x6C, 0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, 0xE3, 0x0F, 0xB9, 0x65, +0x01, 0x97, 0x00, 0x91, 0x01, 0x63, 0x00, 0xEF, 0xFD, 0x63, 0x05, 0x62, 0x04, 0xD1, 0x04, 0x01, +0x82, 0xD9, 0xC4, 0xD9, 0xE5, 0xD9, 0xA3, 0xD9, 0x63, 0x99, 0x47, 0x41, 0x05, 0x4A, 0x04, 0x4A, +0x82, 0x99, 0xA3, 0x67, 0xC2, 0x67, 0x00, 0x18, 0xE3, 0x0F, 0xB9, 0x65, 0x01, 0x97, 0x00, 0x91, +0x01, 0x63, 0x00, 0xEF, +}; + + +u8 NFCFWDMEM[]={ +0x13, 0x24, 0x08, 0x15, +0x58, 0x53, 0x9B, 0x18, 0x22, 0xB6, 0x28, 0x80, 0x3C, 0x48, 0x00, 0x00, 0xE1, 0x11, 0x12, 0x00, +0x01, 0x03, 0xA0, 0x10, 0x44, 0x03, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x20, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, 0x21, 0x22, 0x00, 0x00, 0x00, +0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, +0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x56, 0x15, 0x08, 0x24, 0x01, 0x03, 0x00, 0x00, +0x18, 0x00, 0x00, 0x93, 0x14, 0x00, 0x00, 0x9F, 0x84, 0x00, 0x00, 0x9F, 0x08, 0x10, 0x00, 0x90, +0x1C, 0x10, 0x00, 0x90, 0x60, 0x20, 0x00, 0x90, 0x48, 0x20, 0x00, 0x90, 0x04, 0x20, 0x00, 0x90, +0x00, 0x20, 0x00, 0x90, 0x54, 0x00, 0x00, 0x94, 0xFF, 0xFF, 0x0F, 0x00, 0x1C, 0x04, 0x00, 0x94, +0x00, 0x00, 0x01, 0x00, 0x50, 0x00, 0x00, 0x94, 0x74, 0x00, 0x00, 0x94, 0x00, 0x00, 0x04, 0x20, +0xFF, 0xFF, 0xF7, 0xBF, 0x00, 0x00, 0x08, 0x40, 0x70, 0x01, 0x00, 0x94, 0xA0, 0x20, 0x20, 0x00, +0xFF, 0xFF, 0xFE, 0xFF, 0x58, 0x00, 0x00, 0x94, 0xFF, 0xAF, 0x0E, 0x00, 0x5C, 0x00, 0x00, 0x94, +0x60, 0x00, 0x00, 0x94, 0x0C, 0x00, 0x00, 0x94, 0x08, 0x08, 0x00, 0x94, 0x6C, 0x00, 0x00, 0x94, +0xFF, 0xFF, 0x03, 0xFC, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x20, 0x28, 0x07, 0x00, 0x94, +0x04, 0x04, 0x00, 0x94, 0x70, 0x00, 0x00, 0x94, 0x20, 0x07, 0x00, 0x94, 0xFF, 0xFF, 0xFF, 0xE0, +0x00, 0x00, 0x00, 0x0A, 0x24, 0x07, 0x00, 0x94, 0x38, 0x07, 0x00, 0x94, 0x28, 0x00, 0x00, 0x94, +0x04, 0x00, 0x00, 0x90, 0x0C, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x90, 0x14, 0x00, 0x00, 0x90, +0x10, 0x10, 0x00, 0x90, 0x0C, 0x10, 0x00, 0x90, 0x24, 0x10, 0x00, 0x90, 0x20, 0x10, 0x00, 0x90, +0x54, 0x00, 0x00, 0x9F, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x9F, 0x0C, 0x00, 0x00, 0x9F, +0xFC, 0x00, 0x00, 0x9F, 0x64, 0x00, 0x00, 0x9F, 0x60, 0x00, 0x00, 0x9F, 0x7C, 0x00, 0x00, 0x90, +0x2C, 0x00, 0x00, 0x94, 0xFF, 0xFF, 0xFF, 0xFE, 0x20, 0x01, 0x00, 0x94, 0x24, 0x01, 0x00, 0x94, +0x22, 0x00, 0x00, 0x93, 0x20, 0x00, 0x00, 0x93, 0x10, 0x00, 0x00, 0x93, 0x0A, 0x00, 0x00, 0x93, +0x00, 0x00, 0x00, 0x30, 0x0C, 0x00, 0x00, 0x93, 0x00, 0x10, 0x00, 0x90, 0x14, 0x10, 0x00, 0x90, +0xC4, 0x01, 0x64, 0xB8, 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x73, 0x28, 0x00, 0x80, +0xA3, 0x28, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, 0x2B, 0x29, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, +0x7D, 0x2A, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, +0x7D, 0x2A, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, 0x7D, 0x2A, 0x00, 0x80, 0xD3, 0x29, 0x00, 0x80, +0x51, 0x28, 0x00, 0x80, 0x27, 0x3C, 0x00, 0x80, 0x7D, 0x3C, 0x00, 0x80, 0x39, 0x3D, 0x00, 0x80, +0xA1, 0x3E, 0x00, 0x80, 0x79, 0x3D, 0x00, 0x80, 0xA1, 0x3E, 0x00, 0x80, 0x13, 0x3E, 0x00, 0x80, +0x14, 0x00, 0x00, 0x9F, 0x12, 0x00, 0x00, 0x93, 0x14, 0x00, 0x00, 0x93, 0x16, 0x00, 0x00, 0x93, +0x10, 0x00, 0x00, 0x93, 0x26, 0x00, 0x00, 0x93, 0x5C, 0x00, 0x00, 0x94, 0x0C, 0x00, 0x00, 0x94, +0x08, 0x00, 0x00, 0x93, 0x0C, 0x00, 0x00, 0x93, 0x20, 0x00, 0x00, 0x9F, 0x00, 0x00, 0x34, 0x12, +0x01, 0x00, 0x34, 0x12, 0x22, 0x00, 0x00, 0x93, 0x18, 0x00, 0x00, 0x93, 0xFC, 0x00, 0x00, 0x9F, +0x80, 0x00, 0x00, 0x9F, 0x84, 0x00, 0x00, 0x9F, 0x0C, 0x00, 0x00, 0x9F, 0x03, 0x01, 0xD0, 0x00, +0x50, 0x00, 0x00, 0x9F, 0xF2, 0x00, 0x00, 0xA0, 0x08, 0x00, 0x00, 0x9F, 0x10, 0x00, 0x00, 0x9F, +0x02, 0x01, 0x70, 0x00, 0x01, 0x01, 0x70, 0x00, 0x24, 0x01, 0x00, 0x94, 0x00, 0x00, 0x20, 0x00, +0x2C, 0x00, 0x00, 0x94, 0x28, 0x00, 0x00, 0x94, 0x68, 0x01, 0x00, 0x94, 0x00, 0x00, 0x01, 0x00, +0x00, 0x00, 0x00, 0x01, 0xFE, 0xFF, 0x02, 0x00, 0x6C, 0x00, 0x00, 0x94, 0x00, 0x00, 0x02, 0x00, +0xFF, 0xFF, 0xFD, 0xFF, 0x20, 0x01, 0x00, 0x94, 0x70, 0x00, 0x00, 0x94, 0x00, 0xD0, 0x80, 0x3D, +0x00, 0x90, 0x80, 0x3D, 0x58, 0x00, 0x00, 0x9F, 0x24, 0x00, 0x01, 0x00, 0x26, 0x00, 0x01, 0x00, +0x68, 0x00, 0x00, 0x9F, 0x25, 0x64, 0x2E, 0x00, 0x25, 0x68, 0x68, 0x58, 0x3A, 0x00, 0x00, 0x00, +0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, +0x00, 0x00, 0x00, 0x00, 0x67, 0x66, 0x66, 0x66, +}; + + +//NFC_ADAPTER NFCAdapter; +IRQ_FUN LpPeriIrqFunTable[32]; +u32 LpPeriIrqDataTable[32]; + +VOID +WriteA2NMailbox( + IN VOID *pNFCAdapte +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER) pNFCAdapte; + u8 i = 0; + u32 RegTemp; + + if (!(pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQRIdx].Response)) { + pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQRIdx].Content[0] = + (pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQRIdx].Content[0]|(pNFCAdp->A2NSeq << 8)); + pNFCAdp->A2NSeq++; + } + + for(i = 0; i < pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQRIdx].Length; i++) { + HalDelayUs(30); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x10, pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQRIdx].Content[i]); + } + + HalDelayUs(30); + RegTemp = HAL_READ32(NFC_INTERFACE_BASE,0x24)|BIT1; + HAL_WRITE32(NFC_INTERFACE_BASE, 0x24, RegTemp); + + RegTemp = (HAL_READ32(NFC_INTERFACE_BASE,0x24)&(~BIT1)); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x24, RegTemp); +} + +VOID +A2NWriteInQueue( + IN VOID *pNFCAdapte, + IN VOID *pBuff +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER) pNFCAdapte; + PA2N_MAILBOX_Q pA2NWData = (PA2N_MAILBOX_Q) pBuff; + u8 Idx; + + //Q full handle + if ((pNFCAdp->A2NWQWIdx == (pNFCAdp->A2NWQRIdx - 1))|| + ((pNFCAdp->A2NWQRIdx == 0)&&(pNFCAdp->A2NWQWIdx == N2A_Q_LENGTH - 1))){ + + DBG_8195A("A2N write Mailbox Queue full!\n"); + } + + for (Idx = 0; Idx < pA2NWData->Length; Idx++) { + pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQWIdx].Content[Idx] = pA2NWData->Content[Idx]; + } + + pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQWIdx].Length = pA2NWData->Length; + pNFCAdp->A2NMAILQ[pNFCAdp->A2NWQWIdx].Response = pA2NWData->Response; + pNFCAdp->A2NWQWIdx++; + + if (pNFCAdp->A2NWQWIdx == N2A_Q_LENGTH){ + pNFCAdp->A2NWQWIdx = 0; + } + + //check qu and enable task + if (pNFCAdp->A2NWQWIdx != pNFCAdp->A2NWQRIdx){ + pNFCAdp->A2NWMailBox = TRUE; + RtlUpSema(&(pNFCAdp->VeriSema)); + } + + + #if 0 + { + u8 i = 0; + u8 j = 0; + DBG_8195A("A2N idx = 0x%x \n", pNFCAdp->A2NWMailBox); + DBG_8195A("A2N write R idx = 0x%x \n", pNFCAdp->A2NWQRIdx); + DBG_8195A("A2N write W idx = 0x%x \n", pNFCAdp->A2NWQWIdx); + + for(i = 0;iA2NWQWIdx;i++) { + + DBG_8195A("A2N write queue %d, length = 0x%x \n", i, pNFCAdp->A2NMAILQ[i].Length); + DBG_8195A("A2N write queue %d, response = 0x%x \n", i, pNFCAdp->A2NMAILQ[i].Response); + for(j = 0;j < 5; j++) { + DBG_8195A("A2N write queue %d, data = 0x%x \n", i, pNFCAdp->A2NMAILQ[i].Content[j]); + } + } + } + #endif +} + +VOID +A2NWriteDeQueue( + IN VOID *pNFCAdapte +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER) pNFCAdapte; + u32 TimeIdx = 0; + + while(((HAL_READ32(NFC_INTERFACE_BASE, 0x14)>>1) & 0xf)!= 0){ + DBG_8195A("A2N Mailbox W MISC 0x%08x\n", ((HAL_READ32(NFC_INTERFACE_BASE, 0x14)>>1) & 0xf)); + HalDelayUs(30); + TimeIdx++; + if (TimeIdx > 10000){ + + DBG_8195A("A2N Mailbox write timeout\n"); + + //check qu and enable task + if (pNFCAdp->A2NWQWIdx != pNFCAdp->A2NWQRIdx){ + pNFCAdp->A2NWMailBox = TRUE; + RtlUpSema(&(pNFCAdp->VeriSema)); + } + return; + } + }; + + WriteA2NMailbox(pNFCAdapte); + + pNFCAdp->A2NWQRIdx++; + if (pNFCAdp->A2NWQRIdx == N2A_Q_LENGTH) { + pNFCAdp->A2NWQRIdx = 0; + } + + //check qu and enable task + if (pNFCAdp->A2NWQWIdx != pNFCAdp->A2NWQRIdx){ + pNFCAdp->A2NWMailBox = TRUE; + RtlUpSema(&(pNFCAdp->VeriSema)); + } + else { + pNFCAdp->A2NWMailBox = FALSE; + } +} + + +//cmd 0 +VOID +N2AReadTag( + IN VOID *pNFCAdapte, + IN u8 N2ARPage +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + + nfc_tagread_callback (pNFCAdp, N2ARPage); +} + +VOID +A2NWriteCatch( + IN VOID *pNFCAdapte, + IN u8 N2AWPage, + IN u8 Length, + IN u32 *WData +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + u8 Idx; + A2N_MAILBOX_Q DataTemp; + + DataTemp.Length = Length+1; + DataTemp.Response = 0; + DataTemp.Content[0] = (CATCH_WRITE|(DataTemp.Length<<5)|(N2AWPage<<16)); + for (Idx = 0; Idx < Length; Idx++) { + DataTemp.Content[Idx+1] = WData[Idx]; + } + A2NWriteInQueue(pNFCAdp, &DataTemp); +} + + +VOID +A2NReadCatch( + IN VOID *pNFCAdapte, + IN u8 A2NRPage +) +{ + A2N_MAILBOX_Q DataTemp; + + DataTemp.Length = 1; + DataTemp.Response = 0; + DataTemp.Content[0] = (CATCH_READ|(DataTemp.Length<<5)|(A2NRPage<<16)); + + A2NWriteInQueue((PNFC_ADAPTER)pNFCAdapte, &DataTemp); +} + + +//cmd 1 +VOID +N2AWriteTag( + IN VOID *pNFCAdapte, + IN u8 N2AWPage +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + u32 wr_data; + + wr_data = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + nfc_tagwrite_callback(pNFCAdp, N2AWPage, wr_data); +} + + +//cmd 3 +VOID +N2AReadCatch( + IN VOID *pNFCAdapte, + IN u8 N2ACatchRPage +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + u32 TagBuf[4]; + + TagBuf[0] = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + TagBuf[1] = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + TagBuf[2] = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + TagBuf[3] = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + + nfc_cache_read_callback(pNFCAdp, N2ACatchRPage, TagBuf); +} + +//cmd 4 +VOID +NFCReaderPresent( + IN VOID *pNFCAdapte, + IN u8 State +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + + if (State) { + DBG_8195A("NFC Reader Present\n"); + + //call app + nfc_event_callback(pNFCAdp, NFC_HAL_READER_PRESENT); + } +} + + +//cmd 5 +VOID +N2AMailboxState( + IN VOID *pNFCAdapte, + IN u8 State, + IN u8 Seq +) +{ + A2N_MAILBOX_Q MailData; + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + + pNFCAdp->N2ABoxOpen = State; + DBG_8195A("N2A Mailbox State = %d\n", pNFCAdp->N2ABoxOpen); + + if (State) { + MailData.Length = 1; + MailData.Response = 1; + MailData.Content[0] = (CONFIRM_N2A_BOX_STATE)|(0x1<<5)|((Seq|BIT7)<<8)|(ON<<16); + //WriteA2NMailbox(1, &MailData, 1); + A2NWriteInQueue(pNFCAdp, &MailData); + } +} + + +//cmd 6 +VOID +NFC25MClkReq( + IN VOID *pNFCAdapte, + IN u8 OP, + IN u8 Seq +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + A2N_MAILBOX_Q MailData; + u32 RegTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1); + if (OP) { + RegTemp = ((RegTemp & 0xFFFFC7FF)|(BIT_SYS_SYSPLL_CKSDR_EN|BIT_SYS_SYSPLL_CKSDR_DIV(2))); + } + else { + RegTemp = RegTemp & 0xFFFFC7FF; + } + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, RegTemp); + + //write mailbox + MailData.Length = 1; + MailData.Response = 1; + MailData.Content[0] = (EXT_CLK_RSP)|(0x1<<5)|((Seq|BIT7)<<8)|(ON<<16); + //WriteA2NMailbox(pNFCAdp, &MailData); + A2NWriteInQueue(pNFCAdp, &MailData); +} + +VOID +NFCRoutine( + IN VOID *pNFCAdapte +) +{ + u32 N2ARData, N2AMISC; + u8 N2ARB2; + u8 Seq; + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + + //N2A MEM DATA + if (pNFCAdp->NFCIsr & (BIT0|BIT6)) { + pNFCAdp->NFCIsr &= ~(BIT6|BIT0); + + N2AMISC = ((HAL_READ32(NFC_INTERFACE_BASE, 0x1c)>>1)&0xf); + //DBG_8195A("NFC 0x1C = 0x%x \n", N2AMISC); + while (N2AMISC != 0){ + + N2ARData = HAL_READ32(NFC_INTERFACE_BASE, 0x18); + N2ARB2 = ((u8)(N2ARData>>16)); + Seq = (u8)(N2ARData>>8); + //DBG_8195A("NFC 0x18 = 0x%x \n", N2ARData); + + switch(N2ARData & 0x1F) { + case TAG_READ: + //get data + N2AReadTag(pNFCAdapte, N2ARB2); + //call app + + break; + case TAG_WRITE: + //get data + N2AWriteTag(pNFCAdapte, N2ARB2); + //call app + + break; + case CATCH_READ_DATA: + //get data + N2AReadCatch(pNFCAdapte, N2ARB2); + //call app + + break; + case NFC_R_PRESENT: + NFCReaderPresent(pNFCAdapte, N2ARB2); + break; + case N2A_MAILBOX_STATE: + N2AMailboxState(pNFCAdapte, N2ARB2, Seq); + break; + case EXT_CLK_REQ: + NFC25MClkReq(pNFCAdapte, N2ARB2, Seq); + break; + default: + break; + } + + N2AMISC = ((HAL_READ32(NFC_INTERFACE_BASE, 0x1c)>>1)&0xf); + } + } + + if(pNFCAdp->A2NWMailBox){ + A2NWriteDeQueue(pNFCAdp); + } + //enable int + //A2NWRITE32(0x68, 0xff00); +} + + +VOID +NFCTaskHandle( + IN VOID *pNFCAdapte +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + + #if !TASK_SCHEDULER_DISABLED//#if !TASK_SCHEDULER_DISABLED(>>) + for (;;)//start of for(;;) + { + //4 waiting for start command + RtlDownSema(&(pNFCAdp->VeriSema)); + + if (pNFCAdp->TaskStop) { + break; // task stopping, break the for loop + } + NFCRoutine(pNFCAdapte); + + }//end of for(;;) + + pNFCAdp->TaskStop = 0; +#if ( INCLUDE_vTaskDelete == 1 ) + vTaskDelete(NULL); +#endif + #endif +} + +VOID +LPIrqHandle( + IN VOID *pNFCAdapte +) +{ + u32 LpIrqStatus, CheckIndex, ExactIrqStatus, TableIndex; + + //DBG_8195A("Enter ISR\n"); + + LpIrqStatus = HAL_READ32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_STATUS); + + //Save exact IRQ status + ExactIrqStatus = LpIrqStatus & + HAL_READ32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_EN); + + //Check exact IRQ function + for(CheckIndex = 0;CheckIndex<32;CheckIndex++) { + if (ExactIrqStatus & BIT_(CheckIndex)) { + TableIndex = CheckIndex; + LpPeriIrqFunTable[TableIndex]((VOID *)(LpPeriIrqDataTable[TableIndex])); + } + } + + //Clear sub-rout IRQ + HAL_WRITE32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_STATUS, LpIrqStatus); + +} + +VOID +NFCIrqHandle( + IN VOID *pNFCAdapte +) +{ + PNFC_ADAPTER pNFCAdp = (PNFC_ADAPTER)pNFCAdapte; + u32 ISR = HalNFCRead32(0x68); + pNFCAdp->NFCIsr = (((u8)((ISR&0xbf00)>>8))&((u8)ISR)); + //DBG_8195A("A2N 0x68 = 0x%x\n", ISR); + + //stop int + //ISR = ISR&0xff; + + HalNFCWrite32(0x68, ISR); + + //DBG_8195A("After clean ISR A2N 0x68 = 0x%x\n", A2NREAD32(0x68)); + RtlUpSema(&(pNFCAdp->VeriSema)); +} + +VOID HalNFCDmemInit( + IN u32 *pTagData, + IN u32 TagLen +) +{ + if (pTagData == NULL) { + return; + } + + u32 pgidx, dmemidx; + for (pgidx = 0, dmemidx = 4; pgidx> 0); + NFCFWDMEM[dmemidx++] = (u8)((pTagData[pgidx] & 0x0000FF00) >> 8); + NFCFWDMEM[dmemidx++] = (u8)((pTagData[pgidx] & 0x00FF0000) >> 16); + NFCFWDMEM[dmemidx++] = (u8)((pTagData[pgidx] & 0xFF000000) >> 24); + } +} + +VOID +HalNFCInit( + PNFC_ADAPTER pNFCAdp +) +{ + u32 Rtemp = 0; + + _memset(pNFCAdp, 0, sizeof(NFC_ADAPTER)); + + //Enable NFC clk 0x244[17:16] = 3 + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_PESOC_COM_CLK_CTRL1)|0x00030000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_COM_CLK_CTRL1, Rtemp); + + //Enable A33 interface + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //Enabel NFC and release IOS33_Ameba + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009401); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //polling ISO33_NFC 0x134 [0] = 0 + while ( (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PERI_MONITOR)&BIT0) != 0 ){}; + + //DBG_8195A("NFC Initialization Finish\n"); + + //CLK 25M + { + u32 RegTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1); + + RegTemp = ((RegTemp & 0xFFFFC7FF)|(BIT_SYS_SYSPLL_CKSDR_EN|BIT_SYS_SYSPLL_CKSDR_DIV(2))); + //RegTemp = ((RegTemp & 0xFFFFC7FF)|BIT13|BIT12); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, RegTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x244, HAL_READ32(SYSTEM_CTRL_BASE, 0x244)|BIT18); + } + + + //Init INT + { + IRQ_HANDLE NfcHandle; + NfcHandle.Data = (u32) (pNFCAdp); + NfcHandle.IrqNum = LP_EXTENSION_IRQ;//NFC_IRQ; + NfcHandle.IrqFun = (IRQ_FUN) LPIrqHandle; + NfcHandle.Priority = 13; + + InterruptRegister(&NfcHandle); + InterruptEn(&NfcHandle); + + LpPeriIrqFunTable[1] = (IRQ_FUN)((u32)NFCIrqHandle | 0x1); + + LpPeriIrqDataTable[1] = (u32)(pNFCAdp); + //level trigger + HAL_WRITE32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_MODE,0); + //enable imr + HAL_WRITE32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_EN, + (HAL_READ32(VENDOR_REG_BASE, LP_PERI_EXT_IRQ_EN) | BIT1)); + HalNFCWrite32(0x68, 0xBF00); + //enable mailbox + HalNFCWrite32(0xfc, 0x2243); + + } + + #if !TASK_SCHEDULER_DISABLED + { + s32 NFCTmpSts; + //create task + RtlInitSema(&(pNFCAdp->VeriSema),0); + NFCTmpSts = xTaskCreate( NFCTaskHandle, (const char *)"NFC_TASK", + ((1024*4)/sizeof(portBASE_TYPE)), (void *)pNFCAdp, 1, &(pNFCAdp->NFCTask)); + if (pdTRUE != NFCTmpSts ) { + DBG_NFC_ERR("HalNFCInit: Create Task Err(%d)!\n", NFCTmpSts); + } + } + #endif + +} + +VOID +HalNFCDeinit( + PNFC_ADAPTER pNFCAdp +) +{ + u32 i; + u32 Rtemp = 0; + + pNFCAdp->TaskStop = 1; + RtlUpSema(&(pNFCAdp->VeriSema)); + // wait sometime for the task be stooped + for(i=0;i<1000;i++) { + if (pNFCAdp->TaskStop == 0) { + break; + } + else { + RtlMsleepOS(100); + } + } + //4 free the task semaphore + RtlFreeSema(&(pNFCAdp->VeriSema)); + _memset(pNFCAdp, 0, sizeof(NFC_ADAPTER)); + + //4 Disable NFC clk + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_PESOC_COM_CLK_CTRL1)&0xFFFCFFFF; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_COM_CLK_CTRL1, Rtemp); + + //4 Enable A33 interface + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009404); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); +} + + +u32 +HalNFCRead32( + IN u32 Addr +) +{ + u32 Rtemp = 0; + u32 Idxtemp = 0; + + //full addr + HAL_WRITE32(NFC_INTERFACE_BASE, 0x0, (0x1f000000+Addr)); + //R_cmd + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, 0x2f); + + while(1) { + if( (HAL_READ32(NFC_INTERFACE_BASE, 0x4)&BIT7) == 0 ){ + Idxtemp++; + if((Idxtemp)%10000 == 0) { + DBG_8195A("Idxtemp: 0x%x\n", Idxtemp); + } + if (Idxtemp > 0x0fffff) { + DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\r\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + DBG_8195A("Read FAIL!\r\n"); + return 0; + } + } + else { + //DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, BIT7); + Rtemp = HAL_READ32(NFC_INTERFACE_BASE, 0xc); + break; + } + } + + return Rtemp; +} + +VOID +HalNFCWrite32( + IN u32 Addr, + IN u32 Data +) +{ + u32 Idxtemp = 0; + + //full addr + HAL_WRITE32(NFC_INTERFACE_BASE, 0x0, 0x1f000000+Addr); + //full data + HAL_WRITE32(NFC_INTERFACE_BASE, 0x8, Data); + //W_cmd + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, 0x1f); + + //polling 0x4[7]=1 + while(1) { + if( (HAL_READ32(NFC_INTERFACE_BASE, 0x4)&BIT7) == 0 ){ + Idxtemp++; + if((Idxtemp)%10000 == 0) { + DBG_8195A("Idxtemp: 0x%x\n", Idxtemp); + } + if (Idxtemp > 0x0fffff) { + DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\r\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + DBG_8195A("write FAIL!\r\n"); + return; + } + } + else { + //DBG_8195A("A2N_OCP_MISC_W_IN_WHILE: 0x%x\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, BIT7); + break; + } + } +} + +VOID +HalNFCFwFullMEM( + IN VOID *Data, + IN u32 NFCFwLength +) +{ + u32 *NFCFW; + NFCFW = (u32*) Data; + u32 Idx, NFCFwTemp, RTemp; + u8 Temp = (NFCFwLength%4); + u32 IdxTemp = ((NFCFwLength-Temp)/4); + u8 MEMTemp = 0; +// u8 MEMCnt = 0; + + u32 FWChkSum = 0; + + HalNFCWrite32(0x4C, 0x0); + + //write fw to MEM + for (Idx = 0; Idx < IdxTemp; Idx++ ) { + + NFCFwTemp = *(NFCFW+Idx); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x10, NFCFwTemp); + + //cal chksum + FWChkSum ^= NFCFwTemp; + MEMTemp++; + HalDelayUs(1); + + if (MEMTemp == 8) { + + MEMTemp = 0; + + //check mem empty + while(1){ + + RTemp = HAL_READ32(NFC_INTERFACE_BASE, 0x14); +// MEMCnt = (((u8)(RTemp & 0x1e)) >> 1); + + if ( RTemp & BIT6) { + break; + } + else { + } + } + } + } + + HalDelayUs(200); + + while(1){ + RTemp = HAL_READ32(NFC_INTERFACE_BASE, 0x14); + if ( RTemp & BIT6) { + break; + } + else { + } + } + + //write chksum + HAL_WRITE32(NFC_INTERFACE_BASE, 0x10, FWChkSum); + + while(1){ + RTemp = HAL_READ32(NFC_INTERFACE_BASE, 0x14); + if ( RTemp & BIT6) { + break; + } + else { + } + } +} + + +VOID +HalNFCFwDownload( + VOID +) +{ + u32 Rtemp = 0; + + //switch free run clock from 500K to 80M + HalNFCWrite32(0x88, 0xf06cf06c); + + //2 Download NFC FW + //3 Download IMEM + //setting fw download + HalNFCWrite32(0x48, 0x1); + + //reset NFC CPU + HalNFCWrite32(0x20, 0x1234FFFF); + + //switch IMEM + HAL_WRITE32(NFC_INTERFACE_BASE, 0x14, 0); + + //write fw to MEM + HalNFCFwFullMEM(NFCFWIMEM,sizeof(NFCFWIMEM)); + HalDelayUs(100); + + Rtemp = HalNFCRead32(0x48); + if(Rtemp & BIT1) { + // DBG_8195A("NFC FW Download IMEM SUCCESS \n"); + } + else { + DBG_8195A("NFC FW Download IMEM FAIL!\n"); + return; + } + + //3 Download DMEM + //setting fw download + HalNFCWrite32(0x48, 0x1); + + //switch DMEM + HAL_WRITE32(NFC_INTERFACE_BASE, 0x14, 1); + + //write fw to MEM + HalNFCFwFullMEM(NFCFWDMEM,sizeof(NFCFWDMEM)); + + HalDelayUs(100); + Rtemp = HalNFCRead32(0x48); + if(Rtemp & BIT1) { + //DBG_8195A("NFC FW Download DMEM SUCCESS \n"); + } + else { + DBG_8195A("NFC FW Download DMEM FAIL!\n"); + return; + } + + //Reset CPU + HalNFCWrite32(0x48, 0x80); + + DBG_8195A("NFC REBOOT SUCCESS \n"); +} + + +u32 +HalNFCDbgRead32( + + IN u32 Addr +) +{ + u32 Rtemp = 0; + u32 Idxtemp = 0; + + //full addr + HAL_WRITE32(NFC_INTERFACE_BASE, 0x0, Addr); + //R_cmd + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, 0x2f); + + while(1) { + if( (HAL_READ32(NFC_INTERFACE_BASE, 0x4)&BIT7) == 0 ){ + Idxtemp++; + if((Idxtemp)%10000 == 0) { + DBG_8195A("Idxtemp: 0x%x\n", Idxtemp); + } + if (Idxtemp > 0x0fffff) { + DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\r\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + DBG_8195A("Read FAIL!\r\n"); + return 0; + } + } + else { + //DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, BIT7); + Rtemp = HAL_READ32(NFC_INTERFACE_BASE, 0xc); + break; + } + } + + return Rtemp; +} + + +VOID +HalNFCDbgWrite32( + + IN u32 Addr, + IN u32 Data +) +{ + u32 Idxtemp = 0; + + //full addr + HAL_WRITE32(NFC_INTERFACE_BASE, 0x0, Addr); + //full data + HAL_WRITE32(NFC_INTERFACE_BASE, 0x8, Data); + //W_cmd + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, 0x1f); + + while(1) { + if( (HAL_READ32(NFC_INTERFACE_BASE, 0x4)&BIT7) == 0 ){ + Idxtemp++; + if((Idxtemp)%10000 == 0) { + DBG_8195A("Idxtemp: 0x%x\n", Idxtemp); + } + if (Idxtemp > 0x0fffff) { + DBG_8195A("A2N_OCP_MISC_R_IN_WHILE: 0x%x\r\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + DBG_8195A("write FAIL!\r\n"); + return; + } + } + else { + //DBG_8195A("A2N_OCP_MISC_W_IN_WHILE: 0x%x\n", HAL_READ32(NFC_INTERFACE_BASE, 0x4)); + HAL_WRITE32(NFC_INTERFACE_BASE, 0x4, BIT7); + break; + } + } +} + +#endif //CONFIG_NFC_EN +#endif //CONFIG_NFC_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pcm.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pcm.c new file mode 100644 index 0000000..0b0197f --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pcm.c @@ -0,0 +1,361 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_pcm.h" +#include "hal_pcm.h" + +extern void * +_memset( void *s, int c, SIZE_T n ); + +VOID +HalPcmOnOffRtl8195a ( + IN VOID *Data +) +{ + PHAL_PCM_ADAPTER pHalPcmAdapter = (PHAL_PCM_ADAPTER) Data; + //todo on off pcm + +} + +//default sampling rate 8khz, linear, 10ms frame size, time slot 0 , tx+rx +// master mode, enable endian swap +// Question: need local tx/rx page? +BOOL +HalPcmInitRtl8195a( + IN VOID *Data +) +{ + + PHAL_PCM_ADAPTER pHalPcmAdapter = (PHAL_PCM_ADAPTER) Data; + _memset((void *)pHalPcmAdapter, 0, sizeof(HAL_PCM_ADAPTER)); + + //4 1) Initial PcmChCNR03 Register + pHalPcmAdapter->PcmChCNR03.CH0MuA = 0; + pHalPcmAdapter->PcmChCNR03.CH0Band = 0; + + + //4 1) Initial PcmTSR03 Register + pHalPcmAdapter->PcmTSR03.CH0TSA = 0; + + //4 1) Initial PcmBSize03 Register + pHalPcmAdapter->PcmBSize03.CH0BSize = 39; // 40word= 8khz*0.01s*1ch*2byte/4byte + + + //4 2) Initial Ctl Register + + pHalPcmAdapter->PcmCtl.Pcm_En = 1; + pHalPcmAdapter->PcmCtl.SlaveMode = 0; + pHalPcmAdapter->PcmCtl.FsInv = 0; + pHalPcmAdapter->PcmCtl.LinearMode = 0; + pHalPcmAdapter->PcmCtl.LoopBack = 0; + pHalPcmAdapter->PcmCtl.EndianSwap = 1; + + return _TRUE; +} + + +BOOL +HalPcmSettingRtl8195a( + IN VOID *Data +) +{ + + PHAL_PCM_ADAPTER pHalPcmAdapter = (PHAL_PCM_ADAPTER) Data; + u8 PcmIndex = pHalPcmAdapter->PcmIndex; + u8 PcmCh = pHalPcmAdapter->PcmCh; + u32 RegCtl, RegChCNR03, RegTSR03, RegBSize03; + u32 Isr03; + + PcmCh=0; + //4 1) Check Pcm index is avaliable + if (HAL_PCMX_READ32(PcmIndex, REG_PCM_CHCNR03) & (BIT24|BIT25)) { + //4 Pcm index is running, stop first + DBG_8195A_DMA("Error, PCM %d ch%d is running; stop first!\n", PcmIndex, PcmCh); + + return _FALSE; + } + + //4 2) Check if there are the pending isr + + + Isr03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_ISR03); + Isr03 &= 0xff000000; + //4 Clear Pending Isr + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_ISR03, Isr03); + //} + + + //4 3) Process RegCtl + RegCtl = HAL_PCMX_READ32(PcmIndex, REG_PCM_CTL); + + //4 Clear Ctl register bits + RegCtl &= ( BIT_INV_CTLX_SLAVE_SEL & + BIT_INV_CTLX_FSINV & + BIT_INV_CTLX_PCM_EN & + BIT_INV_CTLX_LINEARMODE & + BIT_INV_CTLX_LOOP_BACK & + BIT_INV_CTLX_ENDIAN_SWAP); + + RegCtl = BIT_CTLX_SLAVE_SEL(pHalPcmAdapter->PcmCtl.SlaveMode) | + BIT_CTLX_FSINV(pHalPcmAdapter->PcmCtl.FsInv) | + BIT_CTLX_PCM_EN(pHalPcmAdapter->PcmCtl.Pcm_En) | + BIT_CTLX_LINEARMODE(pHalPcmAdapter->PcmCtl.LinearMode) | + BIT_CTLX_LOOP_BACK(pHalPcmAdapter->PcmCtl.LoopBack) | + BIT_CTLX_ENDIAN_SWAP(pHalPcmAdapter->PcmCtl.EndianSwap) | + RegCtl; + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_CTL, RegCtl); + //4 4) Program ChCNR03 Register + + RegChCNR03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_CHCNR03); + + RegChCNR03 &= (BIT_INV_CHCNR03_CH0RE & + BIT_INV_CHCNR03_CH0TE & + BIT_INV_CHCNR03_CH0MUA & + BIT_INV_CHCNR03_CH0BAND); + + RegChCNR03 = BIT_CHCNR03_CH0RE(pHalPcmAdapter->PcmChCNR03.CH0RE) | + BIT_CHCNR03_CH0TE(pHalPcmAdapter->PcmChCNR03.CH0TE) | + BIT_CHCNR03_CH0MUA(pHalPcmAdapter->PcmChCNR03.CH0MuA) | + BIT_CHCNR03_CH0BAND(pHalPcmAdapter->PcmChCNR03.CH0Band) | + RegChCNR03; + + DBG_8195A_DMA("RegChCNR03 data:0x%x\n", RegChCNR03); + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_CHCNR03, RegChCNR03); + // time slot + RegTSR03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_TSR03); + + RegTSR03 &= (BIT_INV_TSR03_CH0TSA); + RegTSR03 = BIT_TSR03_CH0TSA(pHalPcmAdapter->PcmTSR03.CH0TSA) | + RegTSR03; + + DBG_8195A_DMA("RegTSR03 data:0x%x\n", RegTSR03); + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_TSR03, RegTSR03); + + // buffer size + RegBSize03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_BSIZE03); + + RegBSize03 &= (BIT_INV_BSIZE03_CH0BSIZE); + RegBSize03 = BIT_BSIZE03_CH0BSIZE(pHalPcmAdapter->PcmBSize03.CH0BSize) | + RegBSize03; + + DBG_8195A_DMA("RegBSize03 data:0x%x\n", RegBSize03); + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_BSIZE03, RegBSize03); + + + + + return _TRUE; +} + +BOOL +HalPcmEnRtl8195a( + IN VOID *Data +) +{ + + PHAL_PCM_ADAPTER pHalPcmAdapter = (PHAL_PCM_ADAPTER) Data; + u8 PcmIndex = pHalPcmAdapter->PcmIndex; + u8 PcmCh = pHalPcmAdapter->PcmCh; + u32 RegChCNR03; + + PcmCh=0; + pHalPcmAdapter->Enable = 1; + + + //4 1) Check Pcm index is avaliable + RegChCNR03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_CHCNR03); + if (RegChCNR03 & (BIT24|BIT25)) { + //4 Pcm index is running, stop first + DBG_8195A_DMA("Error, PCM %d ch%d is running; stop first!\n", PcmIndex, PcmCh); + + return _FALSE; + } + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_CHCNR03, RegChCNR03|BIT24|BIT25); + pHalPcmAdapter->PcmChCNR03.CH0RE = 1; + pHalPcmAdapter->PcmChCNR03.CH0TE = 1; + + return _TRUE; +} + +BOOL +HalPcmDisRtl8195a( + IN VOID *Data +) +{ + + PHAL_PCM_ADAPTER pHalPcmAdapter = (PHAL_PCM_ADAPTER) Data; + u8 PcmIndex = pHalPcmAdapter->PcmIndex; + u8 PcmCh = pHalPcmAdapter->PcmCh; + u32 RegChCNR03; + + PcmCh=0; + pHalPcmAdapter->Enable = 0; + + + RegChCNR03 = HAL_PCMX_READ32(PcmIndex, REG_PCM_CHCNR03); + + HAL_PCMX_WRITE32(PcmIndex, REG_PCM_CHCNR03, RegChCNR03&(~(BIT24|BIT25))); + pHalPcmAdapter->PcmChCNR03.CH0RE = 0; + pHalPcmAdapter->PcmChCNR03.CH0TE = 0; + + return _TRUE; +} + + + +BOOL +HalPcmIsrEnAndDisRtl8195a ( + IN VOID *Data +) +{ +#ifdef CONFIG_PCM_EN + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + u32 IsrMask, Addr, IsrCtrl; + u8 IsrTypeIndex = 0; + + for (IsrTypeIndex=0; IsrTypeIndex<5; IsrTypeIndex++) { + + if (BIT_(IsrTypeIndex) & pHalGdmaAdapter->GdmaIsrType) { + Addr = (REG_GDMA_MASK_INT_BASE + IsrTypeIndex*8); + + IsrMask = HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, Addr); + + IsrCtrl = ((pHalGdmaAdapter->IsrCtrl)?(pHalGdmaAdapter->ChEn | IsrMask): + ((~pHalGdmaAdapter->ChEn) & IsrMask)); + + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + Addr, + IsrCtrl + ); + + } + } +#endif + return _TRUE; +} + + + +BOOL +HalPcmDumpRegRtl8195a ( + IN VOID *Data +) +{ +#ifdef CONFIG_PCM_EN + PHAL_GDMA_ADAPTER pHalGdmaAdapter = Data; + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + REG_GDMA_CH_EN, + (HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, REG_GDMA_CH_EN)| + (pHalGdmaAdapter->ChEn)) + ); +#endif + return _TRUE; +} + +BOOL +HalPcmRtl8195a ( + IN VOID *Data +) +{ +#ifdef CONFIG_PCM_EN + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + REG_GDMA_CH_EN, + (HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, REG_GDMA_CH_EN)& + ~(pHalGdmaAdapter->ChEn)) + ); +#endif + return _TRUE; +} + +#ifdef CONFIG_PCM_EN +u8 +HalGdmaChIsrCleanRtl8195a ( + IN VOID *Data +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + u32 IsrStatus; + u8 IsrTypeIndex = 0, IsrActBitMap = 0; + + for (IsrTypeIndex=0; IsrTypeIndex<5; IsrTypeIndex++) { + + IsrStatus = HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_RAW_INT_BASE + IsrTypeIndex*8)); + +// DBG_8195A_DMA("Isr Type %d: Isr Status 0x%x\n", IsrTypeIndex, IsrStatus); + + IsrStatus = (IsrStatus & (pHalGdmaAdapter->ChEn & 0xFF)); + + if (BIT_(IsrTypeIndex) & pHalGdmaAdapter->GdmaIsrType) { + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_CLEAR_INT_BASE+ (IsrTypeIndex*8)), + (IsrStatus)// & (pHalGdmaAdapter->ChEn & 0xFF)) + ); + IsrActBitMap |= BIT_(IsrTypeIndex); + + } + + } + return IsrActBitMap; + +} + + +VOID +HalGdmaChCleanAutoSrcRtl8195a ( + IN VOID *Data +) +{ + u32 CfgxLow; + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + CfgxLow = HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF)); + + CfgxLow &= BIT_INVC_CFGX_LO_RELOAD_SRC; + + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF), + CfgxLow + ); + + DBG_8195A_DMA("CFG Low data:0x%x\n", + HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF))); +} + +VOID +HalGdmaChCleanAutoDstRtl8195a ( + IN VOID *Data +) +{ + u32 CfgxLow; + PHAL_GDMA_ADAPTER pHalGdmaAdapter = (PHAL_GDMA_ADAPTER) Data; + CfgxLow = HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF)); + + CfgxLow &= BIT_INVC_CFGX_LO_RELOAD_DST; + + HAL_GDMAX_WRITE32(pHalGdmaAdapter->GdmaIndex, + (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF), + CfgxLow + ); + DBG_8195A_DMA("CFG Low data:0x%x\n", + HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, (REG_GDMA_CH_CFG + pHalGdmaAdapter->ChNum*REG_GDMA_CH_OFF))); + +} +#endif // CONFIG_PCM_EN + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pwm.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pwm.c new file mode 100644 index 0000000..007eeb8 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pwm.c @@ -0,0 +1,205 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * -------------------------- + * bug fixing: pvvx + */ + + +#include "rtl8195a.h" +#include "hal_peri_on.h" + +#ifdef CONFIG_PWM_EN +#include "rtl8195a_pwm.h" +#include "hal_pwm.h" + +//extern HAL_PWM_ADAPTER PWMPin[]; + +//extern HAL_TIMER_OP HalTimerOp; +extern u32 gTimerRecord; + +/** + * @brief Configure a G-Timer to generate a tick with certain time. + * + * @param pwm_id: the PWM pin index + * @param tick_time: the time (micro-second) of a tick + * + * @retval None + */ +void +Pwm_SetTimerTick_8195a( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 tick_time +) +{ + if (tick_time <= MIN_GTIMER_TIMEOUT) { + tick_time = MIN_GTIMER_TIMEOUT; + } + // Initial a G-Timer for the PWM pin + if (pPwmAdapt->tick_time != tick_time) { + pPwmAdapt->tick_time = tick_time; + DBG_PWM_INFO("%s: Timer_Id=%d Count=%d\n", __FUNCTION__, pPwmAdapt->gtimer_id, tick_time); + // if timer is running ? + if(gTimerRecord & (1 << pPwmAdapt->gtimer_id)) { + HalTimerReLoadRtl8195a_Patch(pPwmAdapt->gtimer_id, tick_time); + } else { + TIMER_ADAPTER TimerAdapter; + TimerAdapter.IrqDis = 1; // Disable Irq + TimerAdapter.IrqHandle.IrqFun = (IRQ_FUN) NULL; + TimerAdapter.IrqHandle.IrqNum = TIMER2_7_IRQ; + TimerAdapter.IrqHandle.Priority = 10; + TimerAdapter.IrqHandle.Data = (u32)NULL; + TimerAdapter.TimerId = pPwmAdapt->gtimer_id; + TimerAdapter.TimerIrqPriority = 0; + TimerAdapter.TimerLoadValueUs = tick_time-1; + TimerAdapter.TimerMode = 1; // auto-reload with user defined value + HalTimerInitRtl8195a_Patch((VOID*) &TimerAdapter); + } + } +} + + +/** + * @brief Set the duty ratio of the PWM pin. + * + * @param pwm_id: the PWM pin index + * @param period: the period time, in micro-second. + * @param pulse_width: the pulse width time, in micro-second. + * + * @retval None + */ +void +HAL_Pwm_SetDuty_8195a( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 period, + u32 pulse_width +) +{ + u32 RegAddr; + u32 RegValue; + u32 period_tick; + u32 pulsewidth_tick; + u32 tick_time; + u8 timer_id; + u8 pwm_id; + + pwm_id = pPwmAdapt->pwm_id; + // Adjust the tick time to a proper value + if (period < (MIN_GTIMER_TIMEOUT*2)) { + DBG_PWM_ERR ("HAL_Pwm_SetDuty_8195a: Invalid PWM period(%d), too short!\n", period); + tick_time = MIN_GTIMER_TIMEOUT; + period = MIN_GTIMER_TIMEOUT*2; + } + else { + tick_time = period / 1020; // 0x3fc; // a duty cycle be devided into 1020 ticks + if (tick_time < MIN_GTIMER_TIMEOUT) { + tick_time = MIN_GTIMER_TIMEOUT; + } + } + + Pwm_SetTimerTick_8195a(pPwmAdapt, tick_time); + tick_time = pPwmAdapt->tick_time; + + period_tick = period/tick_time; + if (period_tick == 0) { + period_tick = 1; + } + + if (pulse_width >= period) { + pulse_width = period; + } + pulsewidth_tick = pulse_width/tick_time; + + timer_id = pPwmAdapt->gtimer_id; + + pPwmAdapt->period = period_tick & BIT_MASK_PERI_PWM0_PERIOD; + pPwmAdapt->pulsewidth = pulsewidth_tick & BIT_MASK_PERI_PWM0_DUTY; + + RegAddr = REG_PERI_PWM0_CTRL + (pwm_id*4); + RegValue = BIT_PERI_PWM0_EN | BIT_PERI_PWM0_GT_SEL(timer_id) | BIT_PERI_PWM0_DUTY(pulsewidth_tick) | BIT_PERI_PWM0_PERIOD(period_tick); + + HAL_WRITE32(PERI_ON_BASE, RegAddr, RegValue); +} + +/** + * @brief Initializes and enable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * @param sel: pin mux selection + * @param timer_id: the G-timer index assigned to this PWM + * + * @retval HAL_Status + */ +HAL_Status +HAL_Pwm_Init_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +) +{ + u32 pwm_id; + u32 pin_sel; + + pwm_id = pPwmAdapt->pwm_id; + pin_sel = pPwmAdapt->sel; + // Initial a G-Timer for the PWM pin +//p/ Pwm_SetTimerTick_8195a(pPwmAdapt, MIN_GTIMER_TIMEOUT); + + // Set default duty ration +//p/ HAL_Pwm_SetDuty_8195a(pPwmAdapt, 20000, 10000); + + // Configure the Pin Mux + PinCtrl((PWM0+pwm_id), pin_sel, 1); + + return HAL_OK; +} + + +/** + * @brief Enable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * + * @retval None + */ +void +HAL_Pwm_Enable_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +) +{ + u32 pwm_id; + + pwm_id = pPwmAdapt->pwm_id; + // Configure the Pin Mux + if (!pPwmAdapt->enable) { + PinCtrl((PWM0+pwm_id), pPwmAdapt->sel, 1); + HalTimerEnRtl8195a_Patch(pPwmAdapt->gtimer_id); + pPwmAdapt->enable = 1; + } +} + + +/** + * @brief Disable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * + * @retval None + */ +void +HAL_Pwm_Disable_8195a( + HAL_PWM_ADAPTER *pPwmAdapt +) +{ + u32 pwm_id; + + pwm_id = pPwmAdapt->pwm_id; + // Configure the Pin Mux + if (pPwmAdapt->enable) { + PinCtrl((PWM0+pwm_id), pPwmAdapt->sel, 0); + HalTimerDisRtl8195a(pPwmAdapt->gtimer_id); + pPwmAdapt->enable = 0; + } +} + +#endif //CONFIG_PWM_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c new file mode 100644 index 0000000..951ad08 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_device.c @@ -0,0 +1,3177 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "hal_sdio.h" +#include "mailbox.h" + +#if CONFIG_INIC_EN +#include "freertos_pmu.h" +extern struct sk_buff *rltk_wlan_alloc_skb(unsigned int total_len); +extern unsigned char *skb_put(struct sk_buff * skb, unsigned int len); +extern void inic_sdio_free_data(unsigned char *data); +#if (CONFIG_INIC_SKB_TX == 0) //pre-allocated memory for SDIO TX BD +ALIGNMTO(4) char inic_TX_Buf[SDIO_TX_BD_NUM][SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT]; +#endif +#endif + +extern PHAL_SDIO_ADAPTER pgSDIODev; + +#ifdef CONFIG_SOC_PS_MODULE +//extern RAM_START_FUNCTION gRamWakeupFun; +extern u8 __ram_start_table_start__[]; +extern _LONG_CALL_ VOID HalCpuClkConfig(u8 CpuType); +extern _LONG_CALL_ VOID VectorTableInitRtl8195A(u32 StackP); +extern _LONG_CALL_ VOID HalReInitPlatformLogUartV02(VOID); +extern _LONG_CALL_ VOID HalInitPlatformTimerV02(VOID); +extern VOID InfraStart(VOID); +extern VOID SleepPG(u8 Option, u32 SDuration); +extern VOID PSHalInitPlatformLogUart(VOID); +extern VOID HalReInitPlatformTimer(VOID); +extern VOID DeepStandby(u8 Option, u32 SDuration, u8 GpioOption); +extern VOID QueryRegPwrState(u8 FuncIdx, u8* RegState, u8* HwState); +#endif + +/****************************************************************************** + * Function Prototype Declaration + ******************************************************************************/ +BOOL SDIO_Device_Init( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Device_DeInit( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_IRQ_Handler( + IN VOID *pData +); + +VOID SDIO_Interrupt_Init( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Interrupt_DeInit( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Enable_Interrupt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +); + +VOID SDIO_Disable_Interrupt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +); + +VOID SDIO_Clear_ISR( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +); + +VOID SDIO_TxTask( + IN VOID *pData +); + +VOID SDIO_RxTask( + IN VOID *pData +); + +static __inline VOID SDIO_Wakeup_Task( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +static VOID SDIO_SetEvent( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +); + +static VOID SDIO_ClearEvent( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +); + +static BOOL SDIO_IsEventPending( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +); + +VOID SDIO_IRQ_Handler_BH( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_RX_IRQ_Handler_BH( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_TX_BD_Buf_Refill( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_TX_FIFO_DataReady( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +PSDIO_RX_PACKET SDIO_Alloc_Rx_Pkt( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Free_Rx_Pkt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN PSDIO_RX_PACKET pPkt +); + +VOID SDIO_Recycle_Rx_BD ( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Process_H2C_IOMsg( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Send_C2H_IOMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 *C2HMsg +); + +VOID SDIO_Process_H2C_PktMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *H2CMsg +); + +u8 SDIO_Send_C2H_PktMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *C2HMsg, + IN u16 MsgLen +); + +u8 SDIO_Process_RPWM( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +u8 SDIO_Process_RPWM2( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Reset_Cmd( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Return_Rx_Data( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_Register_Tx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN s8 (*CallbackFun)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize), + IN VOID *pAdapter +); + +s8 SDIO_Rx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN VOID *pData, + IN u16 Offset, + IN u16 Length, + IN u8 CmdType +); + +s8 SDIO_Handle_MsgBlk( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN MSG_BLK *pMblk +); + +#if SDIO_MP_MODE +VOID SDIO_PeriodicalTimerCallback( + void *pContex +); + +u8 SDIO_MapMPCmd( + IN char *CmdStr, + IN u16 *Offset +); + +VOID SDIO_DumpMPStatus( + IN PHAL_SDIO_ADAPTER pSDIODev + ); + +VOID SDIO_StatisticDump( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +s8 SDIO_MP_Loopback( + IN VOID *pAdapter, + IN u8 *pData, + IN u16 Offset, + IN u16 PktSize +); + +s8 SDIO_MP_ContinueTx( + IN VOID *pAdapter, + IN u8 *pData, + IN u16 Offset, + IN u16 PktSize +); + +VOID SDIO_MP_ContinueRx( + IN PHAL_SDIO_ADAPTER pSDIODev +); + +VOID SDIO_DeviceMPApp( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u16 argc, + IN u8 *argv[] +); +#endif /* endof '#if SDIO_MP_MODE' */ + +/****************************************************************************** + * Global Variable Declaration + ******************************************************************************/ + +#if SDIO_MP_MODE +const SDIO_MP_CMD SDIO_MPCmdTable[] = { + {"mp_start", SDIO_MP_START}, + {"mp_stop", SDIO_MP_STOP}, + {"mp_loopback", SDIO_MP_LOOPBACK}, + {"status", SDIO_MP_STATUS}, + {"read_reg8", SDIO_MP_READ_REG8}, + {"read_reg16", SDIO_MP_READ_REG16}, + {"read_reg32", SDIO_MP_READ_REG32}, + {"write_reg8", SDIO_MP_WRITE_REG8}, + {"write_reg16", SDIO_MP_WRITE_REG16}, + {"write_reg32", SDIO_MP_WRITE_REG32}, + {"wakeup", SDIO_MP_WAKEUP}, + {"dump", SDIO_MP_DUMP}, + {"ctx", SDIO_MP_CTX}, + {"crx", SDIO_MP_CRX}, + {"crx_da", SDIO_MP_CRX_DA}, + {"crx_stop", SDIO_MP_CRX_STOP}, + {"dbg_msg", SDIO_MP_DBG_MSG} +}; + +const u8 MP_WlanHdr[]={ + 0x88,0x01,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00, + 0x00,0x01,0x10,0x00,0x06,0x00}; +#endif + +/****************************************************************************** + * External Function & Variable Declaration + ******************************************************************************/ +extern PHAL_SDIO_ADAPTER pgSDIODev; + +extern u32 Strtoul( + IN const u8 *nptr, + IN u8 **endptr, + IN u32 base +); + +/****************************************************************************** + * Function: SDIO_Device_Init + * Desc: SDIO device driver initialization. + * 1. Allocate SDIO TX FIFO buffer and initial TX related register. + * 2. Allocate SDIO RX Buffer Descriptor and RX Buffer. Initial RX related + * register. + * 3. Register the Interrupt function. + * 4. Create the SDIO Task and allocate resource(Semaphore). + * + ******************************************************************************/ +BOOL SDIO_Device_Init( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + int i; + SDIO_TX_PACKET *pTxPkt; + SDIO_RX_PACKET *pPkt; + SDIO_TX_BD_HANDLE *pTxBdHdl; + SDIO_RX_BD_HANDLE *pRxBdHdl; + int ret; + u32 reg_value; + + DBG_SDIO_INFO("SDIO_Device_Init==>\n"); + + // Clean boot from wakeup bit + reg_value = HAL_READ32(PERI_ON_BASE, REG_SOC_FUNC_EN); + reg_value &= ~(BIT(29)); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_FUNC_EN, reg_value); + + /* SDIO Function Enable */ + SDIOD_ON_FCTRL(ON); + SDIOD_OFF_FCTRL(ON); + + /* Enable Clock for SDIO function */ + ACTCK_SDIOD_CCTRL(ON); + SLPCK_SDIOD_CCTRL(ON); + + // Reset SDIO DMA + HAL_SDIO_WRITE8(REG_SPDIO_CPU_RST_DMA, BIT_CPU_RST_SDIO_DMA); + + /* Initial SDIO TX BD */ + DBG_SDIO_INFO("Tx BD Init==>\n"); + +// TODO: initial TX BD + pSDIODev->pTXBDAddr = RtlZmalloc((SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD))+3); + if (NULL == pSDIODev->pTXBDAddr) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for TX_BD Err!\n"); + goto SDIO_INIT_ERR; + } + pSDIODev->pTXBDAddrAligned = (PSDIO_TX_BD)(((((u32)pSDIODev->pTXBDAddr - 1) >> 2) + 1) << 2); // Make it 4-bytes aligned + HAL_SDIO_WRITE32(REG_SPDIO_TXBD_ADDR, pSDIODev->pTXBDAddrAligned); + HAL_SDIO_WRITE16(REG_SPDIO_TXBD_SIZE, SDIO_TX_BD_NUM); + /* Set TX_BUFF_UNIT_SIZE */ +#if 0 + reg = HAL_SDIO_READ32(REG_SPDIO_RXBD_CNT); + reg &= ~((0xff)<<8); + reg |= (SDIO_TX_BD_BUF_USIZE<<8); + HAL_SDIO_WRITE32(REG_SPDIO_RXBD_CNT, reg); +#endif + HAL_SDIO_WRITE8(REG_SPDIO_TX_BUF_UNIT_SZ, SDIO_TX_BD_BUF_USIZE); + + DBG_SDIO_INFO("Tx BD Buf Unit Size(%d), Reg=0x%x\n", SDIO_TX_BD_BUF_USIZE, HAL_SDIO_READ8(REG_SPDIO_TX_BUF_UNIT_SZ)); + + /* Set DISPATCH_TXAGG_PKT */ + HAL_SDIO_WRITE32(REG_SPDIO_AHB_DMA_CTRL, HAL_SDIO_READ32(REG_SPDIO_AHB_DMA_CTRL)|BIT31); + // Reset HW TX BD pointer + pSDIODev->TXBDWPtr = HAL_SDIO_READ32(REG_SPDIO_TXBD_WPTR); + pSDIODev->TXBDRPtr = pSDIODev->TXBDWPtr; + pSDIODev->TXBDRPtrReg = pSDIODev->TXBDWPtr; + HAL_SDIO_WRITE32(REG_SPDIO_TXBD_RPTR, pSDIODev->TXBDRPtrReg); + + DBG_SDIO_INFO("TXBDWPtr=0x%x TXBDRPtr=0x%x\n", pSDIODev->TXBDWPtr, pSDIODev->TXBDRPtr); + + pSDIODev->pTXBDHdl = (PSDIO_TX_BD_HANDLE)RtlZmalloc(SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD_HANDLE)); + if (NULL == pSDIODev->pTXBDHdl) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for TX_BD Handle Err!\n"); + goto SDIO_INIT_ERR; + } + + for (i=0;ipTXBDHdl + i; + pTxBdHdl->pTXBD = pSDIODev->pTXBDAddrAligned + i; +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX +//allocate wlan skb here + pTxBdHdl->skb = rltk_wlan_alloc_skb(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); + DBG_SDIO_INFO("SDIO_Device_Init: pTxBdHdl->pkt @ 0x%x\n", pTxBdHdl->skb); + if(pTxBdHdl->skb) + pTxBdHdl->pTXBD->Address = (u32)pTxBdHdl->skb->tail; + else + DBG_SDIO_ERR("SDIO_Device_Init: rltk_wlan_alloc_skb (%d) failed!\n", SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); +#else + pTxBdHdl->pTXBD->Address = (u32)(&inic_TX_Buf[i][0]); +#endif +#else + // Allocate buffer for each TX BD + pTxBdHdl->pTXBD->Address = (u32)RtlMalloc(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); +#if SDIO_DEBUG + pSDIODev->MemAllocCnt++; +#endif +#endif + if (NULL == (u32*)(pTxBdHdl->pTXBD->Address)) { + // Memory Allocate Failed + int j; + + for (j=0;jpTXBDHdl + j; + pTxBdHdl->pTXBD = pSDIODev->pTXBDAddrAligned + j; + if (pTxBdHdl->pTXBD->Address) { +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX + //free wlan skb here + dev_kfree_skb_any(pTxBdHdl->skb); +#endif + pTxBdHdl->pTXBD->Address =(u32)NULL; +#else + RtlMfree((u8 *)pTxBdHdl->pTXBD->Address, (SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT)); +#endif + } + } + goto SDIO_INIT_ERR; + } + pTxBdHdl->isFree = 1; + DBG_SDIO_INFO("TX_BD%d @ 0x%x 0x%x\n", i, pTxBdHdl, pTxBdHdl->pTXBD); + } + +#if (CONFIG_INIC_EN == 0) + RtlInitListhead(&pSDIODev->FreeTxPktList); // Init the list for free packet handler + /* Allocate memory for TX Packets handler */ + pSDIODev->pTxPktHandler = (SDIO_TX_PACKET *)(RtlZmalloc(sizeof(SDIO_TX_PACKET)*SDIO_TX_PKT_NUM)); + if (NULL == pSDIODev->pTxPktHandler) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for TX PKT Handler Err!\n"); + goto SDIO_INIT_ERR; + } + /* Add all TX packet handler into the Free Queue(list) */ + for (i=0;ipTxPktHandler + i; + RtlListInsertTail(&pTxPkt->list, &pSDIODev->FreeTxPktList); + } +#endif + /* Init RX BD and RX Buffer */ + pSDIODev->pRXBDAddr = RtlZmalloc((SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD))+7); + if (NULL == pSDIODev->pRXBDAddr) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for RX_BD Err!\n"); + goto SDIO_INIT_ERR; + } + pSDIODev->pRXBDAddrAligned = (PSDIO_RX_BD)(((((u32)pSDIODev->pRXBDAddr - 1) >> 3) + 1) << 3); // Make it 8-bytes aligned + HAL_SDIO_WRITE32(REG_SPDIO_RXBD_ADDR, pSDIODev->pRXBDAddrAligned); + HAL_SDIO_WRITE16(REG_SPDIO_RXBD_SIZE, SDIO_RX_BD_NUM); + + // Set the threshold of free RX BD count to trigger interrupt + HAL_SDIO_WRITE16(REG_SPDIO_RX_BD_FREE_CNT, RX_BD_FREE_TH); + DBG_SDIO_INFO("Rx BD Free Cnt(%d), Reg=0x%x\n", RX_BD_FREE_TH, HAL_SDIO_READ16(REG_SPDIO_RX_BD_FREE_CNT)); + + pSDIODev->pRXBDHdl = (PSDIO_RX_BD_HANDLE)RtlZmalloc(SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD_HANDLE)); + if (NULL == pSDIODev->pRXBDHdl) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for RX_BD Handle Err!\n"); + goto SDIO_INIT_ERR; + } + + for (i=0;ipRXBDHdl + i; + pRxBdHdl->pRXBD = pSDIODev->pRXBDAddrAligned + i; + pRxBdHdl->isFree = 1; + DBG_SDIO_INFO("RX_BD%d @ 0x%x 0x%x\n", i, pRxBdHdl, pRxBdHdl->pRXBD); + } + + + RtlInitListhead(&pSDIODev->FreeRxPktList); // Init the list for free packet handler + /* Allocate memory for RX Packets handler */ + pSDIODev->pRxPktHandler = (SDIO_RX_PACKET *)(RtlZmalloc(sizeof(SDIO_RX_PACKET)*SDIO_RX_PKT_NUM)); + if (NULL == pSDIODev->pRxPktHandler) { + DBG_SDIO_ERR("SDIO_Device_Init: Malloc for RX PKT Handler Err!\n"); + goto SDIO_INIT_ERR; + } + /* Add all RX packet handler into the Free Queue(list) */ + for (i=0;ipRxPktHandler + i; + RtlListInsertTail(&pPkt->list, &pSDIODev->FreeRxPktList); + } + RtlInitListhead(&pSDIODev->RxPktList); // Init the list for RX packet to be send to the SDIO bus +// RtlInitListhead(&pSDIODev->RecyclePktList); // Init the list for packet to be recycled after the SDIO RX DMA is done + + RtlMutexInit(&pSDIODev->RxMutex); +#if SDIO_DEBUG + RtlMutexInit(&pSDIODev->StatisticMutex); +#endif + /* Create a Semaphone for SDIO Sync control */ +#if !TASK_SCHEDULER_DISABLED + RtlInitSema(&(pSDIODev->TxSema), 0); + if (NULL == pSDIODev->TxSema){ + DBG_SDIO_ERR("SDIO_Device_Init Create Semaphore Err!\n"); + goto SDIO_INIT_ERR; + } + + RtlInitSema(&(pSDIODev->RxSema), 0); + if (NULL == pSDIODev->RxSema){ + DBG_SDIO_ERR("SDIO_Device_Init Create RX Semaphore Err!\n"); + goto SDIO_INIT_ERR; + } + + /* create a Mailbox for other driver module to send message to SDIO driver */ + pSDIODev->pMBox = RtlMailboxCreate(MBOX_ID_SDIO, SDIO_MAILBOX_SIZE, &(pSDIODev->RxSema)); + if (NULL == pSDIODev->pMBox) { + DBG_SDIO_ERR("SDIO_Device_Init Create Mailbox Err!\n"); + goto SDIO_INIT_ERR; + } +#if SDIO_MP_MODE + pSDIODev->pPeriodTimer = RtlTimerCreate("SDIO_Periodical", SDIO_PERIODICAL_TIMER_INTERVAL, SDIO_PeriodicalTimerCallback, pSDIODev, 1); +#endif + /* Create the SDIO task */ +#ifdef PLATFORM_FREERTOS + ret = xTaskCreate( SDIO_TxTask, "SDIO_TX_TASK", ((1024*2)/sizeof(portBASE_TYPE)), (void *)pSDIODev, SDIO_TASK_PRIORITY + PRIORITIE_OFFSET, &pSDIODev->xSDIOTxTaskHandle); + if (pdTRUE != ret ) + { + DBG_SDIO_ERR("SDIO_Device_Init: Create Task Err(%d)!\n", ret); + goto SDIO_INIT_ERR; + } + + ret = xTaskCreate( SDIO_RxTask, "SDIO_RX_TASK", ((1024*1)/sizeof(portBASE_TYPE)), (void *)pSDIODev, SDIO_TASK_PRIORITY + PRIORITIE_OFFSET, &pSDIODev->xSDIORxTaskHandle); + if (pdTRUE != ret ) + { + DBG_SDIO_ERR("SDIO_Device_Init: Create RX Task Err(%d)!\n", ret); + goto SDIO_INIT_ERR; + } + +#endif +#endif // end of "#if !TASK_SCHEDULER_DISABLED" +#if SDIO_MP_MODE +//1 for MP mode test only + pSDIODev->MP_ModeEn = 1; +// SDIO_Register_Tx_Callback(pSDIODev, (VOID *)SDIO_MP_Loopback, (VOID *) pSDIODev); +// pSDIODev->MP_LoopBackEn = 1; +//End +#endif +#if TASK_SCHEDULER_DISABLED + /* enable the interrupt */ + SDIO_Interrupt_Init(pSDIODev); + + /* Indicate the Host system that the TX/RX is ready */ + HAL_SDIO_WRITE8(REG_SPDIO_CPU_IND, \ + HAL_SDIO_READ8(REG_SPDIO_CPU_IND)|BIT_SYSTEM_TRX_RDY_IND); +#endif + pSDIODev->CRPWM = HAL_SDIO_READ8(REG_SPDIO_CRPWM); + pSDIODev->CRPWM2 = HAL_SDIO_READ16(REG_SPDIO_CRPWM2); + + // Indicate Host this is a iNIC FW + pSDIODev->CCPWM2 |= CPWM2_INIC_FW_RDY_BIT; + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); + +#if !PURE_SDIO_INIC +#ifdef CONFIG_SOC_PS_MODULE + { + REG_POWER_STATE SDIOPwrState; + + // To register a new peripheral device power state + SDIOPwrState.FuncIdx = SDIOD; + SDIOPwrState.PwrState = ACT; + RegPowerState(SDIOPwrState); + } +#endif +#endif + + DBG_SDIO_INFO("<==SDIO_Device_Init\n"); + + return SUCCESS; + + SDIO_INIT_ERR: +#if !TASK_SCHEDULER_DISABLED + if (pSDIODev->TxSema) { + RtlFreeSema(&pSDIODev->TxSema); + pSDIODev->TxSema = NULL; + } + + if (pSDIODev->RxSema) { + RtlFreeSema(&pSDIODev->RxSema); + pSDIODev->RxSema = NULL; + } +#endif + + if (pSDIODev->RxMutex) { + RtlMutexFree(&pSDIODev->RxMutex); + } +#if SDIO_DEBUG + if (pSDIODev->StatisticMutex) { + RtlMutexFree(&pSDIODev->StatisticMutex); + } +#endif + if (pSDIODev->pRxPktHandler) { + RtlMfree((u8*)pSDIODev->pRxPktHandler, sizeof(SDIO_RX_PACKET)*SDIO_RX_PKT_NUM); + pSDIODev->pRxPktHandler = NULL; + } + + if (pSDIODev->pRXBDHdl) { + RtlMfree((u8 *)pSDIODev->pRXBDHdl, SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD_HANDLE)); + pSDIODev->pRXBDHdl = NULL; + } + + if (pSDIODev->pRXBDAddr) { + RtlMfree((u8 *)pSDIODev->pRXBDAddr, (SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD))+7); + pSDIODev->pRXBDAddr = NULL; + } +#if (CONFIG_INIC_EN == 0) + if (pSDIODev->pTxPktHandler) { + RtlMfree((u8 *)pSDIODev->pTxPktHandler, (sizeof(SDIO_TX_PACKET)*SDIO_TX_PKT_NUM)); + pSDIODev->pTxPktHandler = NULL; + } +#endif + if ((pSDIODev->pTXBDHdl) && (pSDIODev->pTXBDAddr)) { + for (i=0;ipTXBDHdl + i; + if (pTxBdHdl->pTXBD->Address) { + +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX + //free wlan skb here + dev_kfree_skb_any(pTxBdHdl->skb); +#endif +#else + RtlMfree((u8 *)pTxBdHdl->pTXBD->Address, (SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT)); +#endif + pTxBdHdl->pTXBD->Address = (u32)NULL; + } + } + } + + if (pSDIODev->pTXBDHdl) { + RtlMfree((u8 *)pSDIODev->pTXBDHdl, (SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD_HANDLE))); + pSDIODev->pTXBDHdl = NULL; + } + + if (pSDIODev->pTXBDAddr) { + RtlMfree(pSDIODev->pTXBDAddr, ((SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD))+3)); + pSDIODev->pTXBDAddr = NULL; + pSDIODev->pTXBDAddrAligned = NULL; + } + +#if !TASK_SCHEDULER_DISABLED + if (pSDIODev->pMBox) { + RtlMailboxDel(pSDIODev->pMBox); + pSDIODev->pMBox = NULL; + } +#if SDIO_MP_MODE + if (pSDIODev->pPeriodTimer) { + RtlTimerDelete(pSDIODev->pPeriodTimer); + pSDIODev->pPeriodTimer = NULL; + } +#endif +#endif + return FAIL; +} + + +/****************************************************************************** + * Function: SDIO_Device_DeInit + * Desc: SDIO device driver free resource. This function should be called in + * a task. + * 1. Free TX FIFO buffer + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +//TODO: Call this function in a task + +VOID SDIO_Device_DeInit( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + int i=0; + SDIO_TX_BD_HANDLE *pTxBdHdl; + + if (NULL == pSDIODev) + return; + + // Indicate the Host that Ameba is InActived + pSDIODev->CCPWM2 = HAL_SDIO_READ16(REG_SPDIO_CCPWM2); + pSDIODev->CCPWM2 &= ~(CPWM2_ACT_BIT); + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); + +#if !TASK_SCHEDULER_DISABLED + /* Exit the SDIO task */ +#if 0 + // if this function is called by TX Task, then the TX task cannot be stopped + while (1) { + SDIO_SetEvent(pSDIODev, SDIO_EVENT_EXIT); + SDIO_Wakeup_Task(pSDIODev); + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_TX_STOPPED) && + SDIO_IsEventPending(pSDIODev, (u32)SDIO_EVENT_RX_STOPPED)) { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_EXIT); + break; // break the while loop + } + RtlMsleepOS(10); + i++; + if (i> 100) { + DBG_SDIO_ERR("SDIO_Device_DeInit: Delete SDIO Task Failed with Timeout\n"); + break; + } + } +#endif +#if SDIO_MP_MODE + if (pSDIODev->pPeriodTimer) { + RtlTimerDelete(pSDIODev->pPeriodTimer); + pSDIODev->pPeriodTimer = NULL; + } +#endif + /* Delete the Mailbox */ + if (pSDIODev->pMBox) { + RtlMailboxDel(pSDIODev->pMBox); + pSDIODev->pMBox = NULL; + } + + /* Delete the Semaphore */ + if (pSDIODev->TxSema) { + RtlFreeSema(&pSDIODev->TxSema); + pSDIODev->TxSema = NULL; + } + + if (pSDIODev->RxSema) { + RtlFreeSema(&pSDIODev->RxSema); + pSDIODev->RxSema = NULL; + } +#endif + + if (pSDIODev->RxMutex) { + RtlMutexFree(&pSDIODev->RxMutex); + } +#if SDIO_DEBUG + if (pSDIODev->StatisticMutex) { + RtlMutexFree(&pSDIODev->StatisticMutex); + } +#endif + if (pSDIODev->pRxPktHandler) { + RtlMfree((u8*)pSDIODev->pRxPktHandler, sizeof(SDIO_RX_PACKET)*SDIO_RX_PKT_NUM); + pSDIODev->pRxPktHandler = NULL; + } + + if (pSDIODev->pRXBDHdl) { + RtlMfree((u8 *)pSDIODev->pRXBDHdl, SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD_HANDLE)); + pSDIODev->pRXBDHdl = NULL; + } + + /* Free RX BD */ + if (pSDIODev->pRXBDAddr) { + RtlMfree((u8 *)pSDIODev->pRXBDAddr, (SDIO_RX_BD_NUM * sizeof(SDIO_RX_BD))+7); + pSDIODev->pRXBDAddr = NULL; + } + + /* Free TX FIFO Buffer */ + for (i=0;ipTXBDHdl + i; + if (pTxBdHdl->pTXBD->Address) { +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX + //free wlan skb here + dev_kfree_skb_any(pTxBdHdl->skb); +#endif +#else + RtlMfree((u8 *)pTxBdHdl->pTXBD->Address, (SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT)); +#endif + pTxBdHdl->pTXBD->Address = (u32)NULL; + } + } +#if (CONFIG_INIC_EN == 0) + if (pSDIODev->pTxPktHandler) { + RtlMfree((u8 *)pSDIODev->pTxPktHandler, (sizeof(SDIO_TX_PACKET)*SDIO_TX_PKT_NUM)); + pSDIODev->pTxPktHandler = NULL; + } +#endif + if (pSDIODev->pTXBDHdl) { + RtlMfree((u8 *)pSDIODev->pTXBDHdl, (SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD_HANDLE))); + pSDIODev->pTXBDHdl = NULL; + } + + if (pSDIODev->pTXBDAddr) { + RtlMfree(pSDIODev->pTXBDAddr, ((SDIO_TX_BD_NUM * sizeof(SDIO_TX_BD))+3)); + pSDIODev->pTXBDAddr = NULL; + pSDIODev->pTXBDAddrAligned = NULL; + } + SDIO_Disable_Interrupt(pSDIODev, 0xffff); + SDIO_Interrupt_DeInit(pSDIODev); + + // Reset SDIO DMA + HAL_SDIO_WRITE8(REG_SPDIO_CPU_RST_DMA, BIT_CPU_RST_SDIO_DMA); + + /* Enable Clock for SDIO function */ +// ACTCK_SDIOD_CCTRL(OFF); + + /* SDIO Function Enable */ +// SDIOD_ON_FCTRL(OFF); + SDIOD_OFF_FCTRL(OFF); +} + +#if TASK_SCHEDULER_DISABLED +/****************************************************************************** + * Function: SDIO_TaskUp + * Desc: For the Task scheduler no running case, use this function to run the + * SDIO task main loop. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_TaskUp( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u16 ISRStatus; + +// DiagPrintf("SDIO_TaskUp==>\n"); + pSDIODev->EventSema++; + if (pSDIODev->EventSema > 1000) { + pSDIODev->EventSema = 1000; + } + if (pSDIODev->EventSema == 1) { + while (pSDIODev->EventSema > 0) { + ISRStatus = HAL_SDIO_READ16(REG_SPDIO_CPU_INT_STAS); + pSDIODev->IntStatus |= ISRStatus; + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_STAS, ISRStatus); // clean the ISR + SDIO_SetEvent(pSDIODev, SDIO_EVENT_IRQ|SDIO_EVENT_C2H_DMA_DONE); + + SDIO_TxTask(pSDIODev); + SDIO_RxTask(pSDIODev); + + pSDIODev->EventSema--; + } + } +// DiagPrintf("<==SDIO_TaskUp\n"); +} +#endif + +/****************************************************************************** + * Function: SDIO_IRQ_Handler + * Desc: SDIO device interrupt service routine + * 1. Read & clean the interrupt status + * 2. Wake up the SDIO task to handle the IRQ event + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_IRQ_Handler( + IN VOID *pData +) +{ + PHAL_SDIO_ADAPTER pSDIODev = pData; + u16 ISRStatus; + + ISRStatus = HAL_SDIO_READ16(REG_SPDIO_CPU_INT_STAS); + DBG_SDIO_INFO("%s:ISRStatus=0x%x\n", __FUNCTION__, ISRStatus); + + pSDIODev->IntStatus |= ISRStatus; + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_STAS, ISRStatus); // clean the ISR +#if !TASK_SCHEDULER_DISABLED + if (ISRStatus & BIT_C2H_DMA_OK) { + SDIO_SetEvent(pSDIODev, SDIO_EVENT_C2H_DMA_DONE); + RtlUpSemaFromISR(&pSDIODev->RxSema); + } + + if (ISRStatus & ~BIT_C2H_DMA_OK) { + SDIO_SetEvent(pSDIODev, SDIO_EVENT_IRQ); + RtlUpSemaFromISR(&pSDIODev->TxSema); + } +#else + SDIO_SetEvent(pSDIODev, SDIO_EVENT_IRQ|SDIO_EVENT_C2H_DMA_DONE); + SDIO_TaskUp(pSDIODev); +#endif +} + +/****************************************************************************** + * Function: SDIO_Interrupt_Init + * Desc: SDIO device interrupt initialization. + * 1. Register the ISR + * 2. Initial the IMR register + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Interrupt_Init( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + IRQ_HANDLE SdioIrqHandle; + + pSDIODev->IntMask = BIT_H2C_DMA_OK | BIT_C2H_DMA_OK | BIT_H2C_MSG_INT | BIT_RPWM1_INT | \ + BIT_RPWM2_INT |BIT_H2C_BUS_RES_FAIL | BIT_RXBD_FLAG_ERR_INT; + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_STAS, pSDIODev->IntMask); // Clean pending interrupt first + + SdioIrqHandle.Data = (u32) pSDIODev; + SdioIrqHandle.IrqNum = SDIO_DEVICE_IRQ; + SdioIrqHandle.IrqFun = (IRQ_FUN) SDIO_IRQ_Handler; + SdioIrqHandle.Priority = SDIO_IRQ_PRIORITY; + + InterruptRegister(&SdioIrqHandle); + InterruptEn(&SdioIrqHandle); + + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_MASK, pSDIODev->IntMask); +} + +/****************************************************************************** + * Function: SDIO_Interrupt_DeInit + * Desc: SDIO device interrupt De-Initial. + * 1. UnRegister the ISR + * 2. Initial the IMR register with 0 + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Interrupt_DeInit( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + IRQ_HANDLE SdioIrqHandle; + + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_STAS, 0xffff); // Clean pending interrupt first + + SdioIrqHandle.Data = (u32) pSDIODev; + SdioIrqHandle.IrqNum = SDIO_DEVICE_IRQ; + SdioIrqHandle.Priority = SDIO_IRQ_PRIORITY; + + InterruptDis(&SdioIrqHandle); + InterruptUnRegister(&SdioIrqHandle); +} + +/****************************************************************************** + * Function: SDIO_Enable_Interrupt + * Desc: SDIO enable interrupt by modify the interrupt mask + * + * Para: + * pSDIODev: The SDIO device data structor. + * IntMask: The bit map to enable the interrupt. + ******************************************************************************/ +__inline VOID SDIO_Enable_Interrupt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +) +{ + RtlEnterCritical(); + pSDIODev->IntMask |= IntMask; + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_MASK, pSDIODev->IntMask); + RtlExitCritical(); +} + +/****************************************************************************** + * Function: SDIO_Disable_Interrupt + * Desc: SDIO disable interrupt by modify the interrupt mask + * + * Para: + * pSDIODev: The SDIO device data structor. + * IntMask: The bit map to disable the interrupt. + ******************************************************************************/ +__inline VOID SDIO_Disable_Interrupt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +) +{ + RtlEnterCritical(); + pSDIODev->IntMask &= ~IntMask; + HAL_SDIO_WRITE16(REG_SPDIO_CPU_INT_MASK, pSDIODev->IntMask); + RtlExitCritical(); +} + +/****************************************************************************** + * Function: SDIO_Clear_ISR + * Desc: SDIO clear ISR bit map. + * + * Para: + * pSDIODev: The SDIO device data structor. + * IntMask: The bit map to be clean. + ******************************************************************************/ +__inline VOID SDIO_Clear_ISR( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 IntMask +) +{ + RtlEnterCritical(); + pSDIODev->IntStatus &= ~IntMask; + RtlExitCritical(); +} + +/****************************************************************************** + * Function: SDIO_TxTask + * Desc: The SDIO task handler. This is the main function of the SDIO device + * driver. + * 1. Handle interrupt events. + * * SDIO TX data ready + * * Error handling + * 2. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_TxTask( + IN VOID *pData +) +{ + PHAL_SDIO_ADAPTER pSDIODev = pData; + + /* Initial resource */ +#if !TASK_SCHEDULER_DISABLED + /* enable the interrupt */ + SDIO_Interrupt_Init(pSDIODev); + + // Update the power state indication + pSDIODev->CCPWM2 = HAL_SDIO_READ16(REG_SPDIO_CCPWM2); + pSDIODev->CCPWM2 |= CPWM2_ACT_BIT; + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); + + /* Indicate the Host system that the TX/RX is ready */ + HAL_SDIO_WRITE8(REG_SPDIO_CPU_IND, \ + HAL_SDIO_READ8(REG_SPDIO_CPU_IND)|BIT_SYSTEM_TRX_RDY_IND); +#if SDIO_MP_MODE + if (pSDIODev->pPeriodTimer) { + RtlTimerStart(pSDIODev->pPeriodTimer, 0); + } +#endif +#endif + +#if !TASK_SCHEDULER_DISABLED + for (;;) +#endif + { + /* Task blocked and wait the semaphore(events) here */ +#if !TASK_SCHEDULER_DISABLED + RtlDownSema(&pSDIODev->TxSema); +#endif + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_IRQ)) { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_IRQ); + SDIO_IRQ_Handler_BH(pSDIODev); + } + + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_TXBD_REFILL)) { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_TXBD_REFILL); + SDIO_TX_BD_Buf_Refill(pSDIODev); + } + +#if !TASK_SCHEDULER_DISABLED + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_EXIT)) { + break; // break the loop to exit the task + } +#endif + } + +#if !TASK_SCHEDULER_DISABLED +#if SDIO_MP_MODE + if (pSDIODev->pPeriodTimer) { + RtlTimerStop(pSDIODev->pPeriodTimer, 0); + } +#endif + SDIO_SetEvent(pSDIODev, SDIO_EVENT_TX_STOPPED); + DBG_SDIO_INFO("SDIO TX Task Stopped!\n"); +#if ( INCLUDE_vTaskDelete == 1 ) + vTaskDelete(NULL); +#endif +#endif +} + +/****************************************************************************** + * Function: SDIO_RxTask + * Desc: The SDIO RX task handler. This is the main function of the SDIO device + * driver to handle SDIO RX. + * 1. Handle interrupt events. + * * SDIO RX done + * 2. Send RX data back to the host by fill RX_BD to hardware. + * 3. Handle messages from mailbox + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_RxTask( + IN VOID *pData +) +{ + PHAL_SDIO_ADAPTER pSDIODev = pData; + MSG_BLK Mblk; + +#if !TASK_SCHEDULER_DISABLED + for (;;) +#endif + { + /* Task blocked and wait the semaphore(events) here */ +#if !TASK_SCHEDULER_DISABLED + RtlDownSema(&pSDIODev->RxSema); +#endif + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_C2H_DMA_DONE)) { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_C2H_DMA_DONE); + SDIO_RX_IRQ_Handler_BH(pSDIODev); + } + +#if SDIO_MP_MODE + if (pSDIODev->MP_ContinueRx) { + SDIO_MP_ContinueRx(pSDIODev); + } +#endif // end of "#if SDIO_MP_MODE" + + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_RX_PKT_RDY)) { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_RX_PKT_RDY); + SDIO_Return_Rx_Data(pSDIODev); + } + +#if !TASK_SCHEDULER_DISABLED + /* handle message block in the mailbox */ + do { + if (_SUCCESS == RtlMailboxReceive(MBOX_ID_SDIO, &Mblk, MBOX_WAIT_NONE, 0)) { + SDIO_Handle_MsgBlk(pSDIODev, &Mblk); + } + else { + break; // no more message pending, break the while loop + } + } while (1); + + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_EXIT)) { + break; // break the loop to exit the task + } +#endif + } + +#if !TASK_SCHEDULER_DISABLED + SDIO_SetEvent(pSDIODev, (u32)SDIO_EVENT_RX_STOPPED); + DBG_SDIO_INFO("SDIO RX Task Stopped!\n"); +#if ( INCLUDE_vTaskDelete == 1 ) + vTaskDelete(NULL); +#endif +#endif +} + + +/****************************************************************************** + * Function: SDIO_Wakeup_Task + * Desc: Send a semaphore to wake up the task. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +static __inline VOID SDIO_Wakeup_Task( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ +#if !TASK_SCHEDULER_DISABLED + RtlUpSema(&pSDIODev->TxSema); + RtlUpSema(&pSDIODev->RxSema); +#else + SDIO_TaskUp(pSDIODev); +#endif +} + +/****************************************************************************** + * Function: SDIO_SetEvent + * Desc: Set an event and wake up SDIO task to handle it. + * + * Para: + * pSDIODev: The SDIO device data structor. + * Event: The event to be set. + ******************************************************************************/ +static VOID SDIO_SetEvent( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +) +{ + RtlEnterCritical(); + pSDIODev->Events |= Event; + RtlExitCritical(); +} + +/****************************************************************************** + * Function: SDIO_ClearEvent + * Desc: Clean a SDIO event. + * + * Para: + * pSDIODev: The SDIO device data structor. + * Event: The event to be cleaned. + ******************************************************************************/ +static VOID SDIO_ClearEvent( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +) +{ + RtlEnterCritical(); + pSDIODev->Events &= ~Event; + RtlExitCritical(); +} + +/****************************************************************************** + * Function: SDIO_IsEventPending + * Desc: To check is a event pending. + * + * Para: + * pSDIODev: The SDIO device data structor. + * Event: The event to check. + ******************************************************************************/ +static BOOL SDIO_IsEventPending( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 Event +) +{ + BOOL ret; + + RtlEnterCritical(); + ret = (pSDIODev->Events & Event) ? 1:0; + RtlExitCritical(); + + return ret; +} + +/****************************************************************************** + * Function: SDIO_IRQ_Handler_BH + * Desc: Process the SDIO IRQ, the button helf. + * 1. SDIO TX data ready. + * 2. H2C command ready. + * 3. Host driver RPWM status updated. + * 4. SDIO RX data transfer done. + * 5. SDIO HW/BUS errors. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_IRQ_Handler_BH( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u32 IntStatus; + + DBG_SDIO_INFO("%s @1 IntStatus=0x%x\n", __FUNCTION__, pSDIODev->IntStatus); + + RtlEnterCritical(); + IntStatus = pSDIODev->IntStatus; + RtlExitCritical(); + + if (IntStatus & BIT_H2C_DMA_OK) { + SDIO_Clear_ISR(pSDIODev, BIT_H2C_DMA_OK); + SDIO_Disable_Interrupt(pSDIODev, BIT_H2C_DMA_OK); + SDIO_TX_FIFO_DataReady(pSDIODev); + SDIO_Enable_Interrupt(pSDIODev, BIT_H2C_DMA_OK); + } + + if (IntStatus & BIT_H2C_MSG_INT) { + SDIO_Clear_ISR(pSDIODev, BIT_H2C_MSG_INT); + SDIO_Process_H2C_IOMsg(pSDIODev); + } + + if (IntStatus & BIT_RPWM1_INT) { + SDIO_Clear_ISR(pSDIODev, BIT_RPWM1_INT); + SDIO_Process_RPWM(pSDIODev); + } + + if (IntStatus & BIT_RPWM2_INT) { + SDIO_Clear_ISR(pSDIODev, BIT_RPWM2_INT); + SDIO_Process_RPWM2(pSDIODev); + } + + if (IntStatus & BIT_SDIO_RST_CMD_INT) { + SDIO_Clear_ISR(pSDIODev, BIT_SDIO_RST_CMD_INT); + SDIO_Reset_Cmd(pSDIODev); + } + + DBG_SDIO_INFO("%s @2 IntStatus=0x%x\n", __FUNCTION__, pSDIODev->IntStatus); +} + +/****************************************************************************** + * Function: SDIO_RX_IRQ_Handler_BH + * Desc: Process the SDIO RX IRQ, the button helf. + * 1. SDIO RX data transfer done. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_RX_IRQ_Handler_BH( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u32 IntStatus; + + RtlEnterCritical(); + IntStatus = pSDIODev->IntStatus; + RtlExitCritical(); + + if (IntStatus & BIT_C2H_DMA_OK) { + SDIO_Clear_ISR(pSDIODev, BIT_C2H_DMA_OK); + RtlDownMutex(&pSDIODev->RxMutex); + pSDIODev->RxFifoBusy = 0; + RtlUpMutex(&pSDIODev->RxMutex); + SDIO_Recycle_Rx_BD(pSDIODev); +// SDIO_Return_Rx_Data(pSDIODev); + } +} + + +/****************************************************************************** + * Function: SDIO_TX_BD_Buf_Refill + * Desc: To refill all TX BD buffer. + * 1. Check all TX BD buffer + * 2. Allocate a new buffer for TX BD buffer is invalid + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_TX_BD_Buf_Refill( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u32 i,j; + PSDIO_TX_BD_HANDLE pTxBdHdl; + #define WAIT_TIMEOUT 100 + + for (i=0;ipTXBDHdl + pSDIODev->TXBDRPtrReg; + if (NULL == (u32*)(pTxBdHdl->pTXBD->Address)) { + for (j=0;jskb = rltk_wlan_alloc_skb(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); + if(pTxBdHdl->skb) + pTxBdHdl->pTXBD->Address = (u32)pTxBdHdl->skb->tail; +#endif +#else + pTxBdHdl->pTXBD->Address = (u32)RtlMalloc(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); +#endif + if (NULL == (u32*)(pTxBdHdl->pTXBD->Address)) { + DBG_SDIO_WARN("%s Alloc Mem(size=%d) Failed\n", __FUNCTION__, SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); + RtlMsleepOS(20); + } + else { +#if SDIO_DEBUG + pSDIODev->MemAllocCnt++; +#endif + pSDIODev->TXBDRPtrReg++; + if (pSDIODev->TXBDRPtrReg >= SDIO_TX_BD_NUM) { + pSDIODev->TXBDRPtrReg = 0; + } + HAL_SDIO_WRITE16(REG_SPDIO_TXBD_RPTR, pSDIODev->TXBDRPtrReg); + break; // break the for loop + } + } + if (j == WAIT_TIMEOUT) { + break; // break the for loop + } + } + else { + break; // break the for loop + } + } + + if (pSDIODev->TXBDRPtrReg != pSDIODev->TXBDRPtr) { + DBG_SDIO_ERR("SDIO_TX_BD_Buf_Refill Err: TXBDRPtrReg=%d TXBDRPtr=%d\n", pSDIODev->TXBDRPtrReg, pSDIODev->TXBDRPtr); + } +} + + +/****************************************************************************** + * Function: SDIO_TX_FIFO_DataReady + * Desc: Handle the SDIO FIFO data ready interrupt. + * 1. Send those data to the target driver via callback fun., like WLan. + * 2. Allocate a buffer for the TX BD + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_TX_FIFO_DataReady( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + PSDIO_TX_BD_HANDLE pTxBdHdl; + PSDIO_TX_DESC pTxDesc; + volatile u16 TxBDWPtr=0; + u32 processed_pkt_cnt=0; + u8 isForceBreak=0; + s8 ret=FAIL; + u32 mem_alloc_failed=0; + u32 reg; + + +// DBG_SDIO_INFO("SDIO_TX_FIFO_DataReady==>\n"); + + TxBDWPtr = HAL_SDIO_READ16(REG_SPDIO_TXBD_WPTR); + if (TxBDWPtr == pSDIODev->TXBDRPtr) { + if ((pSDIODev->IntStatus & BIT_TXFIFO_H2C_OVF) == 0) { + DBG_SDIO_WARN("SDIO TX Data Read False Triggered!, TXBDWPtr=0x%x\n", TxBDWPtr); + return; + } + else { + reg = HAL_SDIO_READ32(REG_SPDIO_AHB_DMA_CTRL); + DBG_SDIO_WARN("SDIO TX Overflow Case: Reg DMA_CTRL==0x%x %x %x %x\n", (reg>> 24)&0xff , (reg>>16)&0xff, (reg>>8)&0xff, (reg)&0xff); + } + } + + do { + DBG_SDIO_INFO("SDIO_TX_DataReady: TxBDWPtr=%d TxBDRPtr=%d\n", TxBDWPtr, pSDIODev->TXBDRPtr); + pTxBdHdl = pSDIODev->pTXBDHdl + pSDIODev->TXBDRPtr; + pTxDesc = (PSDIO_TX_DESC)(pTxBdHdl->pTXBD->Address); + + DBG_SDIO_INFO("SDIO_TX_DataReady: PktSz=%d Offset=%d\n", pTxDesc->txpktsize, pTxDesc->offset); + if ((pTxDesc->txpktsize + pTxDesc->offset) <= (SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT)) { + // use the callback function to fordward this packet to target(WLan) driver + if (pSDIODev->Tx_Callback) { +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX + ret = pSDIODev->Tx_Callback(pSDIODev->pTxCb_Adapter, (u8*)pTxBdHdl->skb, pTxDesc->offset, pTxDesc->txpktsize); // includes TX Desc +#else + ret = pSDIODev->Tx_Callback(pSDIODev->pTxCb_Adapter, (u8*)pTxBdHdl->pTXBD->Address, pTxDesc->offset, pTxDesc->txpktsize); // includes TX Desc +#endif +#else + ret = pSDIODev->Tx_Callback(pSDIODev->pTxCb_Adapter, (u8*)pTxBdHdl->pTXBD->Address, pTxDesc->offset, pTxDesc->txpktsize); // includes TX Desc +#endif +#if 0 + ret = pSDIODev->Tx_Callback(pSDIODev->pTxCb_Adapter, // doesn't include TX Desc + (u8*)(pTxBdHdl->pTXBD->Address+pTxDesc->offset), + pTxDesc->txpktsize); +#endif + } + else { + ret = FAIL; + DBG_SDIO_ERR("SDIO TX_Callback is Null!\n"); + } + } + else { + // Invalid packet, Just drop it + DBG_SDIO_WARN("SDIO_TX_DataReady Err: Incorrect TxDesc, PktSz=%d Offset=%d BufSize=%d\n", pTxDesc->txpktsize, pTxDesc->offset, \ + (SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT)); + ret = SUCCESS; // pretend we call the TX callback OK + } + processed_pkt_cnt++; + if (SUCCESS != ret) { + // may be is caused by TX queue is full, so we skip it and try again later + isForceBreak = 1; + break; // break the while loop + } + else { +#if SDIO_MP_MODE + pSDIODev->MP_TxPktCnt++; + pSDIODev->MP_TxByteCnt += pTxDesc->txpktsize; + + pSDIODev->MP_TxPktCntInPeriod++; + pSDIODev->MP_TxByteCntInPeriod += pTxDesc->txpktsize; +#endif + pSDIODev->TXBDRPtr++; + if (pSDIODev->TXBDRPtr >= SDIO_TX_BD_NUM) { + pSDIODev->TXBDRPtr = 0; + } + + // allocate a new buffer for this TX BD + // buf once if the memory allocation failed, we will try it later + if (mem_alloc_failed == 0) { +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_TX//or use bss for tx bd, not need to re-allocate memory + //allocate wlan skb for each TX BD + pTxBdHdl->skb = rltk_wlan_alloc_skb(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); + if(pTxBdHdl->skb) + pTxBdHdl->pTXBD->Address = (u32)pTxBdHdl->skb->tail; + else + pTxBdHdl->pTXBD->Address = (u32)NULL; +#endif +#else + // Allocate buffer for each TX BD + pTxBdHdl->pTXBD->Address = (u32)RtlMalloc(SDIO_TX_BD_BUF_USIZE*SDIO_TX_BUF_SZ_UNIT); +#endif + if (NULL == (u32*)(pTxBdHdl->pTXBD->Address)) { + // memory allocate error + // once memory allocate failed, stop to allocate new buffer for TX BD buffer + //, we refill TX BD buffer later + DBG_SDIO_WARN("%s: Alloc new TX BD Buf Failed\n", __FUNCTION__); + mem_alloc_failed++; + SDIO_SetEvent(pSDIODev, SDIO_EVENT_TXBD_REFILL); + } + else { +#if SDIO_DEBUG + pSDIODev->MemAllocCnt++; +#endif + pSDIODev->TXBDRPtrReg = pSDIODev->TXBDRPtr; + HAL_SDIO_WRITE16(REG_SPDIO_TXBD_RPTR, pSDIODev->TXBDRPtrReg); + } + } + else { + pTxBdHdl->pTXBD->Address = (u32)NULL; + } + } + + TxBDWPtr = HAL_SDIO_READ16(REG_SPDIO_TXBD_WPTR); + if (isForceBreak) { + break; // break the TX FIFO DMA Done processing + } + } while (pSDIODev->TXBDRPtr != TxBDWPtr); + + // if not all TX data were processed, set an event to trigger SDIO_Task to process them later + if (isForceBreak) { + DBG_SDIO_WARN("SDIO_TX Force Break: TXBDWP=0x%x TXBDRP=0x%x\n", TxBDWPtr, pSDIODev->TXBDRPtr); + RtlEnterCritical(); + if ((pSDIODev->IntStatus & BIT_TXFIFO_H2C_OVF) != 0) { + if (pSDIODev->TXBDRPtr != TxBDWPtr) { + pSDIODev->IntStatus &= ~BIT_TXFIFO_H2C_OVF; + } + } + pSDIODev->IntStatus |= BIT_H2C_DMA_OK; + RtlExitCritical(); + SDIO_SetEvent(pSDIODev, SDIO_EVENT_IRQ); +#if !TASK_SCHEDULER_DISABLED + RtlUpSema(&pSDIODev->TxSema); +#else + SDIO_TaskUp(pSDIODev); +#endif + } + else { + if ((pSDIODev->IntStatus & BIT_TXFIFO_H2C_OVF) != 0) { + SDIO_Clear_ISR(pSDIODev, BIT_TXFIFO_H2C_OVF); + } + } +} + +/****************************************************************************** + * Function: SDIO_Alloc_Rx_Pkt + * Desc: Allocate a RX Packet Handle from the queue. + * + * Para: + * pSDIODev: The SDIO device data structor. + * + * Return: + * The allocated RX packet handler. + ******************************************************************************/ +PSDIO_RX_PACKET SDIO_Alloc_Rx_Pkt( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + _LIST *plist; + SDIO_RX_PACKET *pPkt; + u32 loop_cnt; + + RtlDownMutex(&pSDIODev->RxMutex); + if (RtlIsListEmpty(&pSDIODev->FreeRxPktList)) { + RtlUpMutex(&pSDIODev->RxMutex); + loop_cnt = 0; + do { + pPkt =(SDIO_RX_PACKET *)RtlZmalloc(sizeof(SDIO_RX_PACKET)); + if (NULL != pPkt) { + pPkt->isDyna = 1; // this packet handler is dynamic allocated + DBG_SDIO_WARN("Warn! No Free RX PKT, Use Dyna Alloc\n"); + } + else { + RtlMsleepOS(10); + loop_cnt++; + if (loop_cnt > 100) { + DBG_SDIO_ERR("SDIO_Alloc_Rx_Pkt: Err! Allocate RX PKT Failed!\n"); + break; + } + } + }while (NULL == pPkt); + return pPkt; + } + + plist = RtlListGetNext(&pSDIODev->FreeRxPktList); + pPkt = CONTAINER_OF(plist, SDIO_RX_PACKET, list); + + RtlListDelete(&pPkt->list); + RtlUpMutex(&pSDIODev->RxMutex); + return pPkt; +} + +/****************************************************************************** + * Function: SDIO_Free_Rx_Pkt + * Desc: Put a RX Packet Handle back to the queue. + * + * Para: + * pSDIODev: The SDIO device data structor. + * pPkt: The packet handler to be free. + * + ******************************************************************************/ +VOID SDIO_Free_Rx_Pkt( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN PSDIO_RX_PACKET pPkt +) +{ + if (pPkt->isDyna) { + RtlMfree((u8 *)pPkt, sizeof(SDIO_RX_PACKET)); + } + else { + RtlDownMutex(&pSDIODev->RxMutex); + RtlListInsertTail(&pPkt->list, &pSDIODev->FreeRxPktList); + RtlUpMutex(&pSDIODev->RxMutex); + } +} + +/****************************************************************************** + * Function: SDIO_Recycle_Rx_BD + * Desc: To recycle some RX BD when C2H RX DMA done. + * 1. Free the RX packet. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Recycle_Rx_BD ( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + SDIO_RX_BD_HANDLE *pRxBdHdl; + SDIO_RX_BD *pRXBD; + u32 PktSize; + u32 FreeCnt=0; // for debugging + + DBG_SDIO_INFO("SDIO_Recycle_Rx_BD==> %d %d\n", HAL_SDIO_READ16(REG_SPDIO_RXBD_C2H_RPTR), pSDIODev->RXBDRPtr); + SDIO_Disable_Interrupt(pSDIODev, BIT_C2H_DMA_OK); + while (HAL_SDIO_READ16(REG_SPDIO_RXBD_C2H_RPTR) != pSDIODev->RXBDRPtr) + { + pRxBdHdl = pSDIODev->pRXBDHdl + pSDIODev->RXBDRPtr; + pRXBD = pSDIODev->pRXBDAddrAligned + pSDIODev->RXBDRPtr; + if (!pRxBdHdl->isFree) { + if (pRxBdHdl->isPktEnd && (NULL != pRxBdHdl->pPkt)) { + /* Free this packet */ + // TODO: The RX_DESC format may needs to be refined + PktSize = pRxBdHdl->pPkt->RxDesc.pkt_len; +#if SDIO_MP_MODE + if ((pSDIODev->MP_CRxPktPendingCnt > 0)) { + pSDIODev->MP_CRxPktPendingCnt--; + } + + if (((pSDIODev->MP_CRxPktCnt == 0) && (pSDIODev->MP_CRxPktPendingCnt == 0)) || + (SDIO_CRX_DYNA_BUF == pSDIODev->MP_ContinueRxMode)) +#endif + { +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_RX + dev_kfree_skb_any(pRxBdHdl->pPkt->skb); + pRxBdHdl->pPkt->skb = NULL; +#else + inic_sdio_free_data((u8 *) (pRxBdHdl->pPkt->pData)); +#endif + pRxBdHdl->pPkt->pData = NULL; +#else + RtlMfree((u8 *) (pRxBdHdl->pPkt->pData), (pRxBdHdl->pPkt->Offset+PktSize)); // free packet buffer +#if SDIO_DEBUG + RtlDownMutex(&pSDIODev->StatisticMutex); + pSDIODev->MemAllocCnt--; + RtlUpMutex(&pSDIODev->StatisticMutex); +#endif +#endif +#if SDIO_MP_MODE + pSDIODev->pMP_CRxBuf = NULL; +#endif + } + + _memset((void *)&(pRxBdHdl->pPkt->RxDesc), 0, sizeof(SDIO_RX_DESC)); + RtlDownMutex(&pSDIODev->RxMutex); + RtlListInsertTail(&pRxBdHdl->pPkt->list, &pSDIODev->FreeRxPktList); // Put packet handle to free queue + RtlUpMutex(&pSDIODev->RxMutex); + FreeCnt++; + pRxBdHdl->isPktEnd = 0; + pRxBdHdl->pPkt = NULL; + DBG_SDIO_INFO("SDIO_Recycle_Rx_BD: Recycle Pkt, RXBDRPtr=%d\n", pSDIODev->RXBDRPtr); +#if SDIO_MP_MODE + pSDIODev->MP_RxPktCnt++; + pSDIODev->MP_RxByteCnt += PktSize; + + pSDIODev->MP_RxPktCntInPeriod++; + pSDIODev->MP_RxByteCntInPeriod += PktSize; +#endif + } + _memset((void *)pRXBD , 0, sizeof(SDIO_RX_BD)); // clean this RX_BD + pRxBdHdl->isFree = 1; + } + else { + DBG_SDIO_WARN("SDIO_Recycle_Rx_BD: Warring, Recycle a Free RX_BD,RXBDRPtr=%d\n",pSDIODev->RXBDRPtr); + } + pSDIODev->RXBDRPtr++; + if (pSDIODev->RXBDRPtr >= SDIO_RX_BD_NUM) { + pSDIODev->RXBDRPtr -= SDIO_RX_BD_NUM; + } + } + SDIO_Enable_Interrupt(pSDIODev, BIT_C2H_DMA_OK); + DBG_SDIO_INFO("<==SDIO_Recycle_Rx_BD(%d)\n", FreeCnt); + +} + +/****************************************************************************** + * Function: SDIO_Process_H2C_IOMsg + * Desc: Handle the interrupt for HC2 message ready. Read the H2C_MSG register + * and process the H2C message. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Process_H2C_IOMsg( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u32 H2CMsg; + + // TODO: define H2C message type & format, currently we have 30 bits message only, may needs to extend the HW register + H2CMsg = HAL_SDIO_READ32(REG_SPDIO_CPU_H2C_MSG); + DBG_SDIO_INFO("H2C_MSG: 0x%x\n", H2CMsg); + // TODO: May needs to handle endian free + switch (H2CMsg) + { + default: + break; + } + // TODO: Some H2C message needs to be fordward to WLan driver +} + +/****************************************************************************** + * Function: SDIO_Send_C2H_IOMsg + * Desc: Send C2H message to the Host. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Send_C2H_IOMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u32 *C2HMsg +) +{ + u32 TmpC2HMsg; + + // TODO: define C2H message type & format, currently we have 30 bits message only, may needs to extend the HW register + + // TODO: May needs to handle endian free + TmpC2HMsg = HAL_SDIO_READ32(REG_SPDIO_CPU_C2H_MSG); + TmpC2HMsg = ((TmpC2HMsg ^ (u32)BIT(31)) & (u32)BIT(31)) | *C2HMsg; + HAL_SDIO_WRITE32(REG_SPDIO_CPU_C2H_MSG, TmpC2HMsg); +} + +/****************************************************************************** + * Function: SDIO_Process_H2C_PktMsg + * Desc: Handle the packet H2C message which from block write(CMD53). + * + * Para: + * pSDIODev: The SDIO device data structor. + * H2CMsg: point to the buffer of the H2C message received. + ******************************************************************************/ +VOID SDIO_Process_H2C_PktMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *H2CMsg +) +{ + + // TODO: define H2C message type & format + DBG_SDIO_INFO("H2C_MSG: 0x%x\n", *H2CMsg); + // TODO: May needs to handle endian free + // TODO: Some H2C message needs to be fordward to WLan driver +} + +/****************************************************************************** + * Function: SDIO_Send_C2H_PktMsg + * Desc: To send a C2H message to the Host through the block read command. + * + * Para: + * pSDIODev: The SDIO device data structor. + * H2CMsg: point to the buffer of the H2C message received. + * MsgLen: The length of this message. + ******************************************************************************/ +u8 SDIO_Send_C2H_PktMsg( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u8 *C2HMsg, + IN u16 MsgLen +) +{ + u8 *MsgBuf; + PSDIO_RX_DESC pRxDesc; + SDIO_RX_PACKET *pPkt; + + // TODO: define H2C message type & format + DBG_SDIO_INFO("C2H_MSG: 0x%x\n", *C2HMsg); + // TODO: May needs to handle endian free + + MsgBuf = RtlZmalloc(MsgLen); + if (NULL == MsgBuf) { + DBG_SDIO_ERR("SDIO_Send_C2H_PktMsg: Malloc Err!\n"); + return FAIL; + } + _memcpy((void *)(MsgBuf), (void *)C2HMsg, MsgLen); + + pPkt = SDIO_Alloc_Rx_Pkt(pSDIODev); + if (pPkt == NULL) { + DBG_SDIO_ERR("RX Callback Err! No Free RX PKT!\n"); + return FAIL; + } + pRxDesc = &pPkt->RxDesc; + pRxDesc->type = SDIO_CMD_C2H; + pRxDesc->pkt_len = MsgLen; + pRxDesc->offset = sizeof(SDIO_RX_DESC); + pPkt->pData = MsgBuf; + pPkt->Offset = 0; + RtlDownMutex(&pSDIODev->RxMutex); + RtlListInsertTail(&pPkt->list, &pSDIODev->RxPktList); + pSDIODev->RxInQCnt++; + RtlUpMutex(&pSDIODev->RxMutex); + SDIO_SetEvent(pSDIODev, SDIO_EVENT_RX_PKT_RDY); +#if !TASK_SCHEDULER_DISABLED + if (pSDIODev->RxInQCnt == 1) { + RtlUpSema(&pSDIODev->RxSema); + } +#else + SDIO_TaskUp(pSDIODev); +#endif + + return SUCCESS; + +} + +#ifdef CONFIG_SOC_PS_MODULE +/****************************************************************************** + * Function: SDIO_Wakeup_From_PG + * Desc: To handle the process of system wakeup from power gated. + * + * Para: None + ******************************************************************************/ +VOID SDIO_Wakeup_From_PG(VOID) +{ + ConfigDebugErr = 0xffffffff; + ConfigDebugInfo = _DBG_SDIO_; + ConfigDebugWarn = _DBG_SDIO_; + + HalCpuClkConfig(CLK_200M); + VectorTableInitRtl8195A(0x1FFFFFFC); + +#if CONFIG_CHIP_C_CUT + HalReInitPlatformLogUartV02(); +#else + PSHalInitPlatformLogUart(); +#endif + +#ifdef CONFIG_TIMER_MODULE +#if CONFIG_CHIP_C_CUT + HalInitPlatformTimerV02(); +#else + HalReInitPlatformTimer(); +#endif +// HalDelayUs(1000); +#endif + + InfraStart(); +} +#endif + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +VOID SDIO_Pre_Sleep_Callback(u32 expected_idle_time){ + /* Indicate the Host system that the TX/RX is not ready */ + HAL_SDIO_WRITE8(REG_SPDIO_CPU_IND, \ + HAL_SDIO_READ8(REG_SPDIO_CPU_IND)&~BIT_SYSTEM_TRX_RDY_IND); +} +VOID SDIO_Post_Sleep_Callback(u32 expected_idle_time){ + /* Indicate the Host system that the TX/RX is ready */ + HAL_SDIO_WRITE8(REG_SPDIO_CPU_IND, \ + HAL_SDIO_READ8(REG_SPDIO_CPU_IND)|BIT_SYSTEM_TRX_RDY_IND); +} +#endif + +/****************************************************************************** + * Function: SDIO_Process_RPWM + * Desc: To handle RPWM interrupt. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +u8 SDIO_Process_RPWM( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u8 rpwm; + + rpwm = HAL_SDIO_READ8(REG_SPDIO_CRPWM); + + DBG_SDIO_INFO ("RPWM1: 0x%x\n", rpwm); + // TODO: forward this RPWM message to WLan + return 0; +} + +/****************************************************************************** + * Function: SDIO_Process_RPWM + * Desc: To handle RPWM interrupt. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +u8 SDIO_Process_RPWM2( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u16 rpwm; + u32 reg_value;; + PRAM_FUNCTION_START_TABLE pRamStartFun = (PRAM_FUNCTION_START_TABLE) __ram_start_table_start__; + + rpwm = HAL_SDIO_READ16(REG_SPDIO_CRPWM2); + + DBG_SDIO_INFO ("RPWM2: 0x%x\n", rpwm); + +#ifdef CONFIG_SOC_PS_MODULE + if ((rpwm&RPWM2_TOGGLE_BIT) != (pSDIODev->CRPWM2&RPWM2_TOGGLE_BIT)) { + pSDIODev->CRPWM2 = rpwm; + // Tgoole bit changed, means it's a new RPWM command + if ((rpwm & RPWM2_ACT_BIT) == 0) { + // request to enter sleep mode + pSDIODev->CCPWM2 = HAL_SDIO_READ16(REG_SPDIO_CCPWM2); + pSDIODev->CCPWM2 &= ~(CPWM2_ACT_BIT); + +#if PURE_SDIO_INIC + SDIO_Device_DeInit(pSDIODev); +#endif + if ((rpwm & RPWM2_DSTANDBY_BIT) == 0) { + pSDIODev->CCPWM2 &= ~(CPWM2_DSTANDBY_BIT); + if((rpwm & RPWM2_CG_BIT)){ + //enter clock gated state + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + add_wakeup_event(SLEEP_WAKEUP_BY_SDIO); + register_pre_sleep_callback(SDIO_Pre_Sleep_Callback); + register_post_sleep_callback(SDIO_Post_Sleep_Callback); + release_wakelock(WAKELOCK_SDIO_DEVICE); +#endif + } + else{ + // enter power gated state + if ((rpwm & RPWM2_FBOOT_BIT)) { + pSDIODev->CCPWM2 |= CPWM2_FBOOT_BIT; + // setup the trap to call the wakeup callback when booting + reg_value = HAL_READ32(PERI_ON_BASE, REG_SOC_FUNC_EN); + reg_value |= BIT(29); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_FUNC_EN, reg_value); + // Assign the RAM start address after boot from wakeup + pRamStartFun->RamWakeupFun = SDIO_Wakeup_From_PG; + } + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); + +#if PURE_SDIO_INIC + SleepPG(SLP_SDIO, 0); +#endif + } + } else { + // enter Deep Standby state + pSDIODev->CCPWM2 |= CPWM2_DSTANDBY_BIT; + pSDIODev->CCPWM2 &= ~(CPWM2_FBOOT_BIT); + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); +#if PURE_SDIO_INIC + { + u8 gpio_option, i; + u16 gpio_pin, gpio_en, gpio_act, gpio_lv; + + + gpio_option = 0; + gpio_pin = RPWM2_WKPIN_A5_BIT; + gpio_lv = RPWM2_PIN_A5_LV_BIT; + gpio_en = BIT0; + gpio_act = BIT4; + // Loop 4 to check 4 GPIO wake up event + for (i=0;i<4;i++) { + if (rpwm & gpio_pin) { + gpio_option |= gpio_en; + if (rpwm & gpio_lv) { + // Active High + gpio_option |= gpio_act; + } + } + gpio_pin = gpio_pin << 1; + gpio_lv = gpio_lv << 1; + gpio_en = gpio_en << 1; + gpio_act = gpio_act << 1; + } + + DeepStandby(DSTBY_GPIO, 0, gpio_option); + } +#endif + } +#if !PURE_SDIO_INIC + { + REG_POWER_STATE SDIOPwrState; + u8 HwState; + + SDIOPwrState.FuncIdx = SDIOD; + QueryRegPwrState(SDIOD, &(SDIOPwrState.PwrState), &HwState); + + if (SDIOPwrState.PwrState == ACT) { + SDIOPwrState.PwrState = INACT; + RegPowerState(SDIOPwrState); + } + } +#endif + } else { +#if !PURE_SDIO_INIC + +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + acquire_wakelock(WAKELOCK_SDIO_DEVICE); +#endif + + // Request to Active SDIO iNIC + REG_POWER_STATE SDIOPwrState; + + // Let the power management task know SDIO is in active + SDIOPwrState.FuncIdx = SDIOD; + SDIOPwrState.PwrState = ACT; + RegPowerState(SDIOPwrState); + + pSDIODev->CCPWM2 |= CPWM2_ACT_BIT; + pSDIODev->CCPWM2 ^= CPWM2_TOGGLE_BIT; + HAL_SDIO_WRITE16(REG_SPDIO_CCPWM2, pSDIODev->CCPWM2); +#endif + } + } +#endif // #ifdef CONFIG_SOC_PS_MODULE + return 0; +} + +/****************************************************************************** + * Function: SDIO_Reset_Cmd + * Desc: Handle the SDIO Reset Command interrupt. We did nothing currently. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Reset_Cmd( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + // TODO: + return; +} + +/****************************************************************************** + * Function: SDIO_Return_Rx_Data + * Desc: To send all packets in the RX packet list to the Host system via the + * SDIO bus. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_Return_Rx_Data( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + SDIO_RX_PACKET *pPkt=NULL; + SDIO_RX_DESC *pRxDesc; + SDIO_RX_BD_HANDLE *pRxBdHdl; + _LIST *plist; + SDIO_RX_BD *pRXBD; + u32 Offset=0; + u16 RxBdWrite=0; // to count how much RX_BD used in a Transaction + u16 RxBdRdPtr=0; // RX_BD read pointer + u32 pkt_size; + u8 isForceBreak=0; + u8 isListEmpty; +#if SDIO_RX_PKT_SIZE_OVER_16K + u8 needed_rxbd_num; +#endif + +// DBG_SDIO_INFO("SDIO_Return_Rx_Data==> RXBDWPtr=%d\n", pSDIODev->RXBDWPtr); + RtlDownMutex(&pSDIODev->RxMutex); + if (RtlIsListEmpty(&pSDIODev->RxPktList)) { + RtlUpMutex(&pSDIODev->RxMutex); +// DBG_SDIO_INFO("SDIO_Return_Rx_Data: Queue is empty\n"); + return; + } + + if (pSDIODev->RxFifoBusy) { + RtlUpMutex(&pSDIODev->RxMutex); + SDIO_SetEvent(pSDIODev, SDIO_EVENT_RX_PKT_RDY); + return; + } + RtlUpMutex(&pSDIODev->RxMutex); + + RxBdRdPtr = pSDIODev->RXBDRPtr; + + // since we always need to wait the HW to fetch RX BD done, + // so it seems no need to check the RX BD Read Pointer again +#if 0 + /* Check if we shoule handle the RX_BD recycle ? */ + if (RxBdRdPtr != HAL_SDIO_READ16(REG_SPDIO_RXBD_C2H_RPTR)) { + SDIO_Recycle_Rx_BD(pSDIODev); + RxBdRdPtr = pSDIODev->RXBDRPtr; + } +#endif + do { + /* check if RX_BD available */ + RtlDownMutex(&pSDIODev->RxMutex); + plist = RtlListGetNext(&pSDIODev->RxPktList); + RtlUpMutex(&pSDIODev->RxMutex); + pPkt = CONTAINER_OF(plist, SDIO_RX_PACKET, list); + pRxDesc = &(pPkt->RxDesc); +#if SDIO_RX_PKT_SIZE_OVER_16K + needed_rxbd_num = ((pRxDesc->pkt_len - 1)/MAX_RX_BD_BUF_SIZE) + MIN_RX_BD_SEND_PKT; +#endif + if (RxBdRdPtr != pSDIODev->RXBDWPtr) { + if (pSDIODev->RXBDWPtr > RxBdRdPtr) { +#if SDIO_RX_PKT_SIZE_OVER_16K + if ((pSDIODev->RXBDWPtr - RxBdRdPtr) >= (SDIO_RX_BD_NUM - needed_rxbd_num)) +#else + if ((pSDIODev->RXBDWPtr - RxBdRdPtr) >= (SDIO_RX_BD_NUM - MIN_RX_BD_SEND_PKT)) +#endif + { + DBG_SDIO_WARN("SDIO_Return_Rx_Data: No Available RX_BD, ReadPtr=%d WritePtr=%d\n", \ + RxBdRdPtr, pSDIODev->RXBDWPtr); + isForceBreak = 1; + break; // break the while loop + } + } + else { +#if SDIO_RX_PKT_SIZE_OVER_16K + if ((RxBdRdPtr - pSDIODev->RXBDWPtr) <= needed_rxbd_num) +#else + if ((RxBdRdPtr - pSDIODev->RXBDWPtr) <= MIN_RX_BD_SEND_PKT) +#endif + { + DBG_SDIO_WARN("SDIO_Return_Rx_Data: No Available RX_BD, ReadPtr=%d WritePtr=%d\n", RxBdRdPtr, pSDIODev->RXBDWPtr); + isForceBreak = 1; + break; // break the while loop + } + } + } + + RtlDownMutex(&pSDIODev->RxMutex); + RtlListDelete(&pPkt->list); // remove it from the SDIO RX packet Queue + pSDIODev->RxInQCnt--; + RtlUpMutex(&pSDIODev->RxMutex); + + // TODO: Add RX_DESC before the packet + + /* a SDIO RX packet will use at least 2 RX_BD, the 1st one is for RX_Desc, + other RX_BDs are for packet payload */ + /* Use a RX_BD to transmit RX_Desc */ + pRXBD = pSDIODev->pRXBDAddrAligned + pSDIODev->RXBDWPtr; // get the RX_BD head + pRxBdHdl = pSDIODev->pRXBDHdl + pSDIODev->RXBDWPtr; + if (!pRxBdHdl->isFree) { + DBG_SDIO_ERR("SDIO_Return_Rx_Data: Allocated a non-free RX_BD\n"); + } + pRxBdHdl->isFree = 0; + pRxBdHdl->pPkt = pPkt; + pRXBD->FS = 1; + pRXBD->PhyAddr = (u32)((u8 *)pRxDesc); + pRXBD->BuffSize = sizeof(SDIO_RX_DESC); + pRxBdHdl->isPktEnd = 0; + pSDIODev->RXBDWPtr += 1; + if (pSDIODev->RXBDWPtr >= SDIO_RX_BD_NUM) { + pSDIODev->RXBDWPtr -= SDIO_RX_BD_NUM; + } + RxBdWrite++; + + /* Take RX_BD to transmit packet payload */ + pkt_size = pRxDesc->pkt_len; + Offset = 0; + do { + pRXBD = pSDIODev->pRXBDAddrAligned + pSDIODev->RXBDWPtr; // get the RX_BD head + pRxBdHdl = pSDIODev->pRXBDHdl + pSDIODev->RXBDWPtr; + pRxBdHdl->isFree = 0; + pRxBdHdl->pPkt = pPkt; + pRXBD->FS = 0; + pRXBD->PhyAddr = (u32)(((u8 *)pPkt->pData)+pPkt->Offset); +#if SDIO_RX_PKT_SIZE_OVER_16K + if ((pkt_size - Offset) <= MAX_RX_BD_BUF_SIZE) { + pRXBD->BuffSize = pkt_size - Offset; + pRxBdHdl->isPktEnd = 1; + } + else { + pRXBD->BuffSize = MAX_RX_BD_BUF_SIZE; + pRxBdHdl->isPktEnd = 0; + DBG_SDIO_INFO("SDIO_Return_Rx_Data: Split RX_BD, Offset=%d PktSize=%d\n", \ + Offset, pkt_size); + } +#else + if (pkt_size > MAX_RX_BD_BUF_SIZE) { + // if come to here, please enable "SDIO_RX_PKT_SIZE_OVER_16K" + DBG_SDIO_ERR("SDIO_Return_Rx_Data: The Packet Size bigger than 16K\n"); + pkt_size = MAX_RX_BD_BUF_SIZE; + } + pRXBD->BuffSize = pkt_size; + pRxBdHdl->isPktEnd = 1; +#endif + Offset += pRXBD->BuffSize; + // Move the RX_BD Write pointer forward + RxBdWrite++; + pSDIODev->RXBDWPtr += 1; + if (pSDIODev->RXBDWPtr >= SDIO_RX_BD_NUM) { + pSDIODev->RXBDWPtr -= SDIO_RX_BD_NUM; + } + + if (Offset >= pkt_size) { + pRXBD->LS = 1; +// HAL_SDIO_WRITE16(REG_SPDIO_RXBD_C2H_WPTR, pSDIODev->RXBDWPtr); +// HAL_SDIO_WRITE8(REG_SPDIO_HCI_RX_REQ, BIT_HCI_RX_REQ); +// DBG_SDIO_INFO("SDIO_Return_Rx_Data:RXBDWPtr=%d\n", pSDIODev->RXBDWPtr); + } + } while (Offset < pkt_size); + + if (RxBdWrite >= (SDIO_RX_BD_NUM - MIN_RX_BD_SEND_PKT)) { + isForceBreak = 1; + break; // break the while loop + } + + RtlDownMutex(&pSDIODev->RxMutex); + isListEmpty = RtlIsListEmpty(&pSDIODev->RxPktList); + RtlUpMutex(&pSDIODev->RxMutex); + } while(!isListEmpty); + + if (RxBdWrite > 0) { + RtlDownMutex(&pSDIODev->RxMutex); + HAL_SDIO_WRITE16(REG_SPDIO_RXBD_C2H_WPTR, pSDIODev->RXBDWPtr); + HAL_SDIO_WRITE8(REG_SPDIO_HCI_RX_REQ, BIT_HCI_RX_REQ); + pSDIODev->RxFifoBusy = 1; + RtlUpMutex(&pSDIODev->RxMutex); + } + + if (isForceBreak) { +// SDIO_Recycle_Rx_BD(pSDIODev); + // function end with insufficient resource, set event to try again later + SDIO_SetEvent(pSDIODev, SDIO_EVENT_RX_PKT_RDY); +#if !TASK_SCHEDULER_DISABLED + RtlMsleepOS(1); // no resource, sleep a while + RtlUpSema(&pSDIODev->RxSema); +#else + SDIO_TaskUp(pSDIODev); +#endif + } + DBG_SDIO_INFO("SDIO_Return_Rx_Data(%d)<==\n", RxBdWrite); + +} + +/****************************************************************************** + * Function: SDIO_Register_Tx_Callback + * Desc: For a TX data target driver to register its TX callback function, so + * the SDIO driver can use it to fordward a TX packet to the target driver. + * + * Para: + * pSDIODev: point to the SDIO device handler + * CallbackFun: The function pointer of the callback + * pAdapter: a pointer will be use to call the registered CallBack function. + * It can be used to point to a handler of the caller, like WLan + * Adapter. + ******************************************************************************/ +VOID SDIO_Register_Tx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN s8 (*CallbackFun)(VOID *pAdapter, u8 *pPkt, u16 Offset, u16 PktSize), + IN VOID *pAdapter +) +{ + pSDIODev->Tx_Callback = CallbackFun; + pSDIODev->pTxCb_Adapter = pAdapter; +} + +/****************************************************************************** + * Function: SDIO_Rx_Callback + * Desc: The callback function for an packet receiving, which be called from + * the Target (WLan) driver to send a packet to the SDIO host. + * + * Para: + * pSDIODev: Point to the SDIO device data structer. + * pData: Point to the head of the data to be return to the Host system. + * Length: The length of the data to be send, in byte. + * + * Return: + * The result, SUCCESS or FAIL. + ******************************************************************************/ +s8 SDIO_Rx_Callback( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN VOID *pData, + IN u16 Offset, + IN u16 PktSize, + IN u8 CmdType +) +{ + PSDIO_RX_DESC pRxDesc; + SDIO_RX_PACKET *pPkt; +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_RX + struct sk_buff *skb = (struct sk_buff *)pData; +#endif +#endif + + pPkt = SDIO_Alloc_Rx_Pkt(pSDIODev); + if (pPkt == NULL) { + DBG_SDIO_ERR("RX Callback Err! No Free RX PKT!\n"); + return FAIL; + } + pRxDesc = &pPkt->RxDesc; + pRxDesc->type = CmdType; + pRxDesc->pkt_len = PktSize; +#if CONFIG_INIC_EN +#if CONFIG_INIC_SKB_RX + pRxDesc->offset = sizeof(SDIO_RX_DESC)+Offset;//for data alignment reason + pPkt->skb = skb; + pPkt->pData = skb->data; + pPkt->Offset = 0; +#else //CONFIG_INIC_SKB_RX + pRxDesc->offset = sizeof(SDIO_RX_DESC); + pPkt->pData = pData; + pPkt->Offset = Offset; +#endif//CONFIG_INIC_SKB_RX +#else //CONFIG_INIC_EN + pRxDesc->offset = sizeof(SDIO_RX_DESC); + pPkt->pData = pData; + pPkt->Offset = Offset; +#endif //CONFIG_INIC_EN + RtlDownMutex(&pSDIODev->RxMutex); + RtlListInsertTail(&pPkt->list, &pSDIODev->RxPktList); + pSDIODev->RxInQCnt++; + RtlUpMutex(&pSDIODev->RxMutex); + SDIO_SetEvent(pSDIODev, SDIO_EVENT_RX_PKT_RDY); +#if !TASK_SCHEDULER_DISABLED + if (pSDIODev->RxInQCnt == 1) { + RtlUpSema(&pSDIODev->RxSema); + } +#else + SDIO_TaskUp(pSDIODev); +#endif + + return SUCCESS; +} + +/****************************************************************************** + * Function: SDIO_Handle_MsgBlk + * Desc: Process a message block. + * + * Para: + * pSDIODev: Point to the SDIO device data structer. + * MSG_BLK: The message block to be processed. + * Length: The length of the data to be send, in byte. + * + * Return: + * The result, SUCCESS or FAIL. + ******************************************************************************/ +s8 SDIO_Handle_MsgBlk( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN MSG_BLK *pMblk +) +{ + s8 ret=SUCCESS; + + DBG_SDIO_INFO("SDIO_Handle_MsgBlk==> MsgType=%d\n", pMblk->MsgType); + switch (pMblk->MsgType) { + case MSG_SDIO_RX_PKT: + ret = SDIO_Rx_Callback(pSDIODev, pMblk->pBuf, pMblk->Reserved, pMblk->DateLen, SDIO_CMD_RX_ETH); //pMblk->Reserved = Offset + if (SUCCESS != ret) { + // failed to send this packet to the host, drop it + RtlMfree((u8 *) pMblk->pBuf, (pMblk->Reserved + pMblk->DateLen)); // pMblk->Reserved = Offset +#if SDIO_DEBUG + RtlDownMutex(&pSDIODev->StatisticMutex); + pSDIODev->MemAllocCnt--; + RtlUpMutex(&pSDIODev->StatisticMutex); +#endif +#if SDIO_MP_MODE + pSDIODev->MP_RxDropCnt++; +#endif + } + break; + + case MSG_SDIO_C2H: + break; + + case MSG_SDIO_RPWM: + break; + + default: + DBG_SDIO_WARN("SDIO_Handle_MsgBlk: UnKnown MsgType %d\n", pMblk->MsgType); + break; + } + + return ret; +} + +#if SDIO_MP_MODE + +/****************************************************************************** + * Function: SDIO_PeriodicalTimerCallback + * Desc: The callback function of the 1 Sec timer. It be used to statistic the + * throughput and update the status or something need to do periodically. + * + * Para: + * pContex: this pointer actually is the pointer of the SDIO device. + * + * Return: None + ******************************************************************************/ +VOID SDIO_PeriodicalTimerCallback( + void *pContex +) +{ + PHAL_SDIO_ADAPTER pSDIODev = pContex; + + if (SDIO_IsEventPending(pSDIODev, SDIO_EVENT_DUMP)) { + SDIO_StatisticDump(pSDIODev); +} +} + +#if !TASK_SCHEDULER_DISABLED +/****************************************************************************** + * Function: SDIO_MP_Task + * Desc: The SDIO MP test task handler. This is the main function of the SDIO + * device MP test mode. + * + * Para: + * pSDIODev: The SDIO device data structor. + ******************************************************************************/ +VOID SDIO_MP_Task( + IN VOID *pData +) +{ + PHAL_SDIO_ADAPTER pSDIODev = pData; + MSG_BLK Mblk_r; + MSG_BLK Mblk_w; + SDIO_MP_RX_PACKET *pRxPkt; + _LIST *plist; + int malloc_err_cnt=0; + + DiagPrintf("SDIO_MP_Task Started...\n"); + RtlInitListhead(&pSDIODev->MP_RxPktList); + + /* Initial resource */ + for (;;) + { + /* Task blocked and wait the semaphore(events) here */ + RtlDownSema(&pSDIODev->MP_EventSema); + /* handle message block in the mailbox */ + do { + if (_SUCCESS == RtlMailboxReceive(MBOX_ID_SDIO_MP, &Mblk_r, MBOX_WAIT_NONE, 0)) { + switch (Mblk_r.MsgType) { + case MSG_SDIO_MP_LOOP_TXPKT: + pRxPkt = NULL; + malloc_err_cnt = 0; + do { + pRxPkt = (SDIO_MP_RX_PACKET *)RtlZmalloc(sizeof(SDIO_MP_RX_PACKET)); + if (NULL != pRxPkt) { + pRxPkt->pData = Mblk_r.pBuf; + pRxPkt->Offset = Mblk_r.Reserved; + pRxPkt->DataLen = Mblk_r.DateLen; + RtlListInsertTail(&pRxPkt->list, &pSDIODev->MP_RxPktList); + } + else { + RtlMsleepOS(10); + malloc_err_cnt++; + if (malloc_err_cnt > 100) { + DBG_SDIO_ERR("SDIO_MP_Task: Malloc for Rx Pkt Failed\n"); + // no memory to handle this packet, drop it + RtlMfree(Mblk_r.pBuf, (Mblk_r.Reserved+Mblk_r.DateLen)); + pSDIODev->MP_RxDropCnt++; +#if SDIO_DEBUG + RtlDownMutex(&pSDIODev->StatisticMutex); + pSDIODev->MemAllocCnt--; + RtlUpMutex(&pSDIODev->StatisticMutex); +#endif + break; // break the while loop + } + } + }while (NULL == pRxPkt); + break; + + default: + DBG_SDIO_WARN("SDIO_MP_TASK: UnKnown MsgType %d\n", Mblk_r.MsgType); + break; + } + } + else { + break; // no more message pending, break the while loop + } + } while (1); + + while (!RtlIsListEmpty(&pSDIODev->MP_RxPktList)) { + plist = RtlListGetNext(&pSDIODev->MP_RxPktList); + pRxPkt = CONTAINER_OF(plist, SDIO_MP_RX_PACKET, list); + RtlListDelete(&pRxPkt->list); + + Mblk_w.MsgType = MSG_SDIO_RX_PKT; + Mblk_w.pBuf = pRxPkt->pData; + Mblk_w.Reserved = pRxPkt->Offset; + Mblk_w.DateLen = pRxPkt->DataLen; + if (_SUCCESS != RtlMailboxSendToBack(MBOX_ID_SDIO, &Mblk_w, 2000, 0)) { + DBG_SDIO_ERR("SDIO_MP_Task: Send MSG_SDIO_RX_PKT FAILED\n"); + RtlListInsertHead(&pRxPkt->list, &pSDIODev->MP_RxPktList); + break; + } + else { + RtlMfree((u8 *)pRxPkt, sizeof(SDIO_MP_RX_PACKET)); + } + } + + RtlEnterCritical(); + if (pSDIODev->MP_Events & SDIO_EVENT_EXIT) { + pSDIODev->MP_Events &= ~SDIO_EVENT_EXIT; + RtlExitCritical(); + DBG_SDIO_INFO("SDIO_MP_Task Exiting...\n"); + break; // break the loop to exit the task + } + RtlExitCritical(); + } + + RtlEnterCritical(); + pSDIODev->MP_Events |= SDIO_EVENT_MP_STOPPED; + RtlExitCritical(); + DBG_SDIO_INFO("SDIO_MP_Task Stoped!\n"); +#if ( INCLUDE_vTaskDelete == 1 ) + vTaskDelete(NULL); +#endif +} +#endif // end of "#if !TASK_SCHEDULER_DISABLED" + +/****************************************************************************** + * Function: SDIO_MapMPCmd + * Desc: Map a MP command string to a MP command type. + * + * Para: + * CmdStr: point to the command string buffer + * + * return: + * The MP command type + * + ******************************************************************************/ +u8 SDIO_MapMPCmd( + IN char *CmdStr, + IN u16 *Offset +) +{ + char cmd_str[16]; + u16 i; + u16 str_len=0; + u16 entry_num; + u8 mp_cmd=0xff; + + for (i=0;i<16;i++) { + if ((' ' != *(CmdStr+i)) && ('=' != *(CmdStr+i)) && (*(CmdStr+i))) { + cmd_str[i] = *(CmdStr+i); + str_len++; + } + else { + break; + } + } + + *Offset = str_len+1; + + entry_num = sizeof(SDIO_MPCmdTable)/sizeof(SDIO_MP_CMD); + + for (i=0;iMP_ModeEn); + DiagPrintf("MP_Loopback=%d\n", pSDIODev->MP_LoopBackEn); + DiagPrintf("TX: Packet Count=%d, Byte Count=%d\n", pSDIODev->MP_TxPktCnt, pSDIODev->MP_TxByteCnt); + DiagPrintf("TX: TX_BD_WPTR=%d, TX_BD_RPTR=%d\n", HAL_SDIO_READ16(REG_SPDIO_TXBD_WPTR), HAL_SDIO_READ16(REG_SPDIO_TXBD_RPTR)); + DiagPrintf("RX: Packet Count=%d, Byte Count=%d\n", pSDIODev->MP_RxPktCnt, pSDIODev->MP_RxByteCnt); + DiagPrintf("RX: RXBDWPtr=%d, RXBDRPtr=%d\n", pSDIODev->RXBDWPtr, pSDIODev->RXBDRPtr); +#if SDIO_DEBUG + DiagPrintf("RX: InQueueCount=%d MemAllocatedCnt=%d\n", pSDIODev->RxInQCnt, pSDIODev->MemAllocCnt); +#endif + DiagPrintf("TxDropPkt=%d RxDropPkt=%d\n", pSDIODev->MP_TxDropCnt, pSDIODev->MP_RxDropCnt); +} + +/****************************************************************************** + * Function: SDIO_StatisticDump + * Desc: Periodical dump SDIO throughput and other status. + * + * Para: + * pSDIODev: The SDIO device data structor. + * + * return: None + * + ******************************************************************************/ +VOID SDIO_StatisticDump( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + unsigned long tp; // throughput + u32 oldest_byte_cnt; + u32 tx_avg_tp=0; // in Kbps + u32 rx_avg_tp=0; // in Kbps + + // calculate the TX throughput + if (pSDIODev->TxAvgWinCnt >= SDIO_AVG_TP_WIN_SIZE) { + // flush the oldest one and add the newest one + oldest_byte_cnt = pSDIODev->MP_TxAvgTPWin[pSDIODev->OldestTxAvgWinIdx]; + + if (pSDIODev->MP_TxAvgTPWinSum >= oldest_byte_cnt) { + pSDIODev->MP_TxAvgTPWinSum -= oldest_byte_cnt; + pSDIODev->MP_TxAvgTPWin[pSDIODev->OldestTxAvgWinIdx] = pSDIODev->MP_TxByteCntInPeriod; + pSDIODev->OldestTxAvgWinIdx++; + if (SDIO_AVG_TP_WIN_SIZE <= pSDIODev->OldestTxAvgWinIdx) { + pSDIODev->OldestTxAvgWinIdx = 0; + } + + if (0 == pSDIODev->MP_TxAvgTPWinSum) { + // reset the statistic + pSDIODev->TxAvgWinCnt = 0; + pSDIODev->OldestTxAvgWinIdx = 0; + } + } + else { + pSDIODev->MP_TxAvgTPWinSum = 0; + // reset the statistic + if (pSDIODev->MP_TxByteCntInPeriod > 0) + pSDIODev->TxAvgWinCnt = 1; + else + pSDIODev->TxAvgWinCnt = 0; + pSDIODev->OldestTxAvgWinIdx = 0; + } + pSDIODev->MP_TxAvgTPWinSum += pSDIODev->MP_TxByteCntInPeriod; + tx_avg_tp = (pSDIODev->MP_TxAvgTPWinSum << 3) / (SDIO_PERIODICAL_TIMER_INTERVAL * SDIO_AVG_TP_WIN_SIZE); + } + else { + if ((pSDIODev->MP_TxAvgTPWinSum > 0) || (pSDIODev->MP_TxByteCntInPeriod > 0)) { + pSDIODev->MP_TxAvgTPWinSum += pSDIODev->MP_TxByteCntInPeriod; + pSDIODev->MP_TxAvgTPWin[pSDIODev->TxAvgWinCnt] = pSDIODev->MP_TxByteCntInPeriod; + pSDIODev->TxAvgWinCnt++; + tx_avg_tp = (pSDIODev->MP_TxAvgTPWinSum << 3) / (SDIO_PERIODICAL_TIMER_INTERVAL * pSDIODev->TxAvgWinCnt); + } + } + + // calculate the RX throughput + if (pSDIODev->RxAvgWinCnt >= SDIO_AVG_TP_WIN_SIZE) { + // flush the oldest one and add the newest one + oldest_byte_cnt = pSDIODev->MP_RxAvgTPWin[pSDIODev->OldestRxAvgWinIdx]; + if (pSDIODev->MP_RxAvgTPWinSum >= oldest_byte_cnt) { + pSDIODev->MP_RxAvgTPWinSum -= oldest_byte_cnt; + pSDIODev->MP_RxAvgTPWin[pSDIODev->OldestRxAvgWinIdx] = pSDIODev->MP_RxByteCntInPeriod; + pSDIODev->OldestRxAvgWinIdx++; + if (SDIO_AVG_TP_WIN_SIZE <= pSDIODev->OldestRxAvgWinIdx) { + pSDIODev->OldestRxAvgWinIdx = 0; + } + + if (0 == pSDIODev->MP_RxAvgTPWinSum) { + // reset the statistic + pSDIODev->RxAvgWinCnt = 0; + pSDIODev->OldestRxAvgWinIdx = 0; + } + } + else { + pSDIODev->MP_RxAvgTPWinSum = 0; + // reset the statistic + if (pSDIODev->MP_RxByteCntInPeriod > 0) + pSDIODev->RxAvgWinCnt = 1; + else + pSDIODev->RxAvgWinCnt = 0; + + pSDIODev->OldestRxAvgWinIdx = 0; + } + pSDIODev->MP_RxAvgTPWinSum += pSDIODev->MP_RxByteCntInPeriod; + + rx_avg_tp = (pSDIODev->MP_RxAvgTPWinSum << 3) / (SDIO_PERIODICAL_TIMER_INTERVAL * SDIO_AVG_TP_WIN_SIZE); + } + else { + if ((pSDIODev->MP_RxAvgTPWinSum > 0) || (pSDIODev->MP_RxByteCntInPeriod > 0)) { + pSDIODev->MP_RxAvgTPWinSum += pSDIODev->MP_RxByteCntInPeriod; + pSDIODev->MP_RxAvgTPWin[pSDIODev->RxAvgWinCnt] = pSDIODev->MP_RxByteCntInPeriod; + pSDIODev->RxAvgWinCnt++; + rx_avg_tp = (pSDIODev->MP_RxAvgTPWinSum << 3) / (SDIO_PERIODICAL_TIMER_INTERVAL * pSDIODev->RxAvgWinCnt); + } + } + + if ((pSDIODev->MP_TxByteCntInPeriod > 0) || (pSDIODev->MP_RxByteCntInPeriod > 0)) { + DiagPrintf("SDIO Dump:\n"); + tp = (pSDIODev->MP_TxByteCntInPeriod << 3)/(SDIO_PERIODICAL_TIMER_INTERVAL/1000); + if (tp > 1000) { + DiagPrintf("TX: Packet Count=%d, Byte Count=%d, TP=%d Kbps\n", pSDIODev->MP_TxPktCntInPeriod, pSDIODev->MP_TxByteCntInPeriod, tp/1000); + } + else { + DiagPrintf("TX: Packet Count=%d, Byte Count=%d, TP=%d bps\n", pSDIODev->MP_TxPktCntInPeriod, pSDIODev->MP_TxByteCntInPeriod, tp); + } + tp = (pSDIODev->MP_RxByteCntInPeriod << 3)/(SDIO_PERIODICAL_TIMER_INTERVAL/1000); + if (tp > 1000) { + DiagPrintf("RX: Packet Count=%d, Byte Count=%d, TP=%d Kbps\n", pSDIODev->MP_RxPktCntInPeriod, pSDIODev->MP_RxByteCntInPeriod, tp/1000); + } + else { + DiagPrintf("RX: Packet Count=%d, Byte Count=%d, TP=%d bps\n", pSDIODev->MP_RxPktCntInPeriod, pSDIODev->MP_RxByteCntInPeriod, tp); + } + + pSDIODev->MP_TxPktCntInPeriod = 0; + pSDIODev->MP_TxByteCntInPeriod = 0; + pSDIODev->MP_RxPktCntInPeriod = 0; + pSDIODev->MP_RxByteCntInPeriod = 0; + } + + if ((tx_avg_tp > 0) || (rx_avg_tp > 0)) { + DiagPrintf("TX Avg TP=%d Kbps, RX Avg TP=%d Kbps\n", tx_avg_tp, rx_avg_tp); + } +} + +/****************************************************************************** + * Function: SDIO_MP_Loopback + * Desc: The loopback test function for MP mode. + * + * Para: + * pAdapter: a pointer which got from the callback function register, + * here it point to the SDIO device itself. + * pData: The pointer of the SDIO TX data buffer. + * PktSize: The size (in byte) of this SDIO TX data. + * + * return: + * The result of this function, SUCCESS or FAILED. + * + ******************************************************************************/ +s8 SDIO_MP_Loopback( + IN VOID *pAdapter, + IN u8 *pData, + IN u16 Offset, + IN u16 PktSize +) +{ +#if TASK_SCHEDULER_DISABLED + PHAL_SDIO_ADAPTER pSDIODev=(PHAL_SDIO_ADAPTER)pAdapter; +#endif + s8 ret; + + MSG_BLK MBlk; + +// DBG_SDIO_INFO("SDIO_MP_Loopback==>\n"); + + +#if TASK_SCHEDULER_DISABLED + ret = SDIO_Rx_Callback(pSDIODev, pData, Offset, PktSize, SDIO_CMD_RX_ETH); +#else + // Mailbox test, use message to replace call SDIO_Rx_Callback directly + MBlk.MsgType = MSG_SDIO_MP_LOOP_TXPKT; + MBlk.pBuf = pData; + MBlk.Reserved = (u8)Offset; + MBlk.DateLen = PktSize; + if (_SUCCESS == RtlMailboxSendToBack(MBOX_ID_SDIO_MP, &MBlk, 2000, 0)) { + ret = SUCCESS; + } + else { + DBG_SDIO_ERR("SDIO_MP_Loopback FAILED\n"); + ret = FAIL; + } +#endif + return ret; +} + +/****************************************************************************** + * Function: SDIO_MP_ContinueTx + * Desc: The continue TX test function for MP mode. We just drop the TX packet. + * + * Para: + * pAdapter: a pointer which got from the callback function register, + * here it point to the SDIO device itself. + * pData: The pointer of the SDIO TX data buffer. + * PktSize: The size (in byte) of this SDIO TX data. + * + * return: + * The result of this function, SUCCESS or FAILED. + * + ******************************************************************************/ +s8 SDIO_MP_ContinueTx( + IN VOID *pAdapter, + IN u8 *pData, + IN u16 Offset, + IN u16 PktSize +) +{ + PHAL_SDIO_ADAPTER pSDIODev=(PHAL_SDIO_ADAPTER)pAdapter; + + RtlMfree(pData, (Offset+PktSize)); +#if SDIO_DEBUG + RtlDownMutex(&pSDIODev->StatisticMutex); + pSDIODev->MemAllocCnt--; + RtlUpMutex(&pSDIODev->StatisticMutex); +#endif + return SUCCESS; +} + +/****************************************************************************** + * Function: SDIO_MP_ContinueRx + * Desc: Process Continue RX test. + * + * Para: + * pSDIODev: The SDIO device adapter. + * + * return: None + * + ******************************************************************************/ +VOID SDIO_MP_ContinueRx( + IN PHAL_SDIO_ADAPTER pSDIODev +) +{ + u8 *pRxBuf=NULL; + s8 ret; + + while (1) { + if (pSDIODev->MP_CRxPktPendingCnt > 10) { + break; + } + + if (pSDIODev->MP_ContinueRxMode == SDIO_CRX_STATIC_BUF) { + pRxBuf = pSDIODev->pMP_CRxBuf; + } + else if (pSDIODev->MP_ContinueRxMode == SDIO_CRX_DYNA_BUF) { + pRxBuf = RtlMalloc(pSDIODev->MP_CRxSize+26); // 26: Wlan header +#if SDIO_DEBUG + pSDIODev->MemAllocCnt++; +#endif + if (NULL != pRxBuf) { + _memcpy(pRxBuf, MP_WlanHdr, 26); + _memset((pRxBuf+26), 0x3E, pSDIODev->MP_CRxSize); + } + } + + if (NULL != pRxBuf) { + ret = SDIO_Rx_Callback(pSDIODev, pRxBuf, 0, pSDIODev->MP_CRxSize+26, SDIO_CMD_RX_ETH); + if (SUCCESS == ret) { + if (pSDIODev->MP_CRxPktCnt > 0) { + pSDIODev->MP_CRxPktCnt--; + pSDIODev->MP_CRxPktPendingCnt++; + if (0 == pSDIODev->MP_CRxPktCnt) { + pSDIODev->MP_ContinueRx = 0; + break; // break the while loop + } + } + if (pSDIODev->MP_CRxPktPendingCnt > 10) { + break; + } + } + else { + if (pSDIODev->MP_ContinueRxMode == SDIO_CRX_DYNA_BUF) { + RtlMfree(pRxBuf, pSDIODev->MP_CRxSize+26); +#if SDIO_DEBUG + pSDIODev->MemAllocCnt--; +#endif + } +#if !TASK_SCHEDULER_DISABLED + RtlMsleepOS(10); // no resource, sleep a while + RtlUpSema(&pSDIODev->RxSema); +#else + SDIO_TaskUp(pSDIODev); +#endif + break; + } + } + else { +#if !TASK_SCHEDULER_DISABLED + RtlMsleepOS(10); // no resource, sleep a while + RtlUpSema(&pSDIODev->RxSema); +#else + SDIO_TaskUp(pSDIODev); +#endif + break; + } + } +} + +/****************************************************************************** + * Function: SDIO_DeviceMPApp + * Desc: To handle SDIO MP command + * + * Para: + * pData: point to the command buffer + * + ******************************************************************************/ +VOID SDIO_DeviceMPApp( + IN PHAL_SDIO_ADAPTER pSDIODev, + IN u16 argc, + IN u8 *argv[] +) +{ + u8 cmd_type; + u16 offset=0; + u32 arg1, arg2; + int ret; + int i; + + DBG_SDIO_INFO("==>MP_App: arg_num=%d cmd_str=%s\n", argc, (char *)argv[0]); + + cmd_type = SDIO_MapMPCmd((char *)argv[0], &offset); + DBG_SDIO_INFO("MP_App: MP_Cmdtype=%d\n", cmd_type); + + switch (cmd_type) + { + case SDIO_MP_START: + if (!pSDIODev->MP_ModeEn) { + pSDIODev->MP_ModeEn = 1; + pSDIODev->MP_TxPktCnt = 0; /* SDIO TX packet count */ + pSDIODev->MP_RxPktCnt = 0; /* SDIO RX packet count */ + pSDIODev->MP_TxByteCnt = 0; /* SDIO TX Byte count */ + pSDIODev->MP_RxByteCnt = 0; /* SDIO RX Byte count */ + DiagPrintf("SDIO MP Started!\n"); + } + else { + DiagPrintf("In SDIO MP Mode already!\n"); + } + break; + + case SDIO_MP_STOP: + pSDIODev->MP_ModeEn = 0; + DiagPrintf("SDIO MP Stoped!\n"); + break; + + case SDIO_MP_LOOPBACK: + DBG_SDIO_INFO("MP_App: argv[1]=%s\n", argv[1]); + if (pSDIODev->MP_ModeEn == 0) { + DiagPrintf("Not in MP mode! Please start MP mode first.\n"); + break; + } + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 10); + if (arg1) { + if (pSDIODev->MP_LoopBackEn == 0) { + // Create a Task for MP loopback test +#if !TASK_SCHEDULER_DISABLED + RtlInitSema(&(pSDIODev->MP_EventSema), 0); + if (NULL == pSDIODev->MP_EventSema){ + DBG_SDIO_ERR("SDIO MP_Loopback Create Semaphore Err!\n"); + break; // break the switch case + } + + /* create a Mailbox for other driver module to send message to SDIO driver */ + pSDIODev->pMP_MBox = RtlMailboxCreate(MBOX_ID_SDIO_MP, SDIO_MAILBOX_SIZE, &(pSDIODev->MP_EventSema)); + if (NULL == pSDIODev->pMBox) { + DBG_SDIO_ERR("SDIO MP_Loopback Create Mailbox Err!\n"); + break; // break the switch case + } + + /* Create the SDIO task */ +#ifdef PLATFORM_FREERTOS + ret = xTaskCreate( SDIO_MP_Task, "SDIO_MP_TASK", ((256*4)/sizeof(portBASE_TYPE)), (void *)pSDIODev, SDIO_MP_TASK_PRIORITY, &pSDIODev->MP_TaskHandle); + if (pdTRUE != ret ) + { + DBG_SDIO_ERR("SDIO MP Create Task Err(%d)!\n", ret); + break; + } +#endif + DiagPrintf("SDIO MP Task Created\n"); +#endif // end of "#if !TASK_SCHEDULER_DISABLED" + + // Backup origional TX Callback function + pSDIODev->pTxCallback_Backup = pSDIODev->Tx_Callback; + pSDIODev->pTxCb_Adapter_Backup = (VOID *)pSDIODev->pTxCb_Adapter; + DiagPrintf("Register SDIO TX Callback with Loopback function\n"); + SDIO_Register_Tx_Callback(pSDIODev, &SDIO_MP_Loopback, (VOID *) pSDIODev); + pSDIODev->MP_LoopBackEn = 1; + } + else { + DiagPrintf("SDIO MP LoopBack is On already!\n"); + } + } + else { + if (pSDIODev->MP_LoopBackEn) { + // Restore origional TX Callback function + DiagPrintf("Restore SDIO TX Callback...\n"); + SDIO_Register_Tx_Callback(pSDIODev, pSDIODev->pTxCallback_Backup, pSDIODev->pTxCb_Adapter_Backup); + pSDIODev->MP_LoopBackEn = 0; +#if !TASK_SCHEDULER_DISABLED + /* Exit the SDIO task */ + if (pSDIODev->MP_TaskHandle) { + RtlEnterCritical(); + pSDIODev->MP_Events |= SDIO_EVENT_EXIT; + RtlExitCritical(); + RtlUpSema(&pSDIODev->MP_EventSema); + i=0; + while (1) { + RtlEnterCritical(); + if (pSDIODev->MP_Events & SDIO_EVENT_MP_STOPPED) { + RtlExitCritical(); + break; + } + RtlExitCritical(); + RtlMsleepOS(10); + i++; + if (i> 100) { + DBG_SDIO_ERR("Delete SDIO MP Task Failed with Timeout\n"); + break; + } + } + } + + /* Delete the Mailbox */ + if (pSDIODev->pMP_MBox) { + RtlMailboxDel(pSDIODev->pMP_MBox); + pSDIODev->pMP_MBox = NULL; + } + + /* Delete the Semaphore */ + if (pSDIODev->MP_EventSema) { + RtlFreeSema(&pSDIODev->MP_EventSema); + pSDIODev->MP_EventSema = NULL; + } + DiagPrintf("SDIO MP Task Deleted\n"); +#endif + + } + } + DiagPrintf("SDIO MP LoopBack=%d\n", pSDIODev->MP_LoopBackEn); + break; + + case SDIO_MP_STATUS: + SDIO_DumpMPStatus(pSDIODev); + break; + + case SDIO_MP_READ_REG8: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + DiagPrintf("SDIO_Reg[%x]=%x\n", arg1, HAL_SDIO_READ8(arg1)); + break; + + case SDIO_MP_READ_REG16: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + DiagPrintf("SDIO_Reg[%x]=%x\n", arg1, HAL_SDIO_READ16(arg1)); + break; + + case SDIO_MP_READ_REG32: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + DiagPrintf("SDIO_Reg[%x]=%x\n", arg1, HAL_SDIO_READ32(arg1)); + break; + + case SDIO_MP_WRITE_REG8: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + arg2 = Strtoul((const u8*)(argv[2]), (u8 **)NULL, 16); + HAL_SDIO_WRITE8(arg1, arg2); + DiagPrintf("Write Reg[%x]=%x, Readback:%x\n", arg1, arg2, HAL_SDIO_READ8(arg1)); + break; + + case SDIO_MP_WRITE_REG16: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + arg2 = Strtoul((const u8*)(argv[2]), (u8 **)NULL, 16); + HAL_SDIO_WRITE16(arg1, arg2); + DiagPrintf("Write Reg[%x]=%x, Readback:%x\n", arg1, arg2, HAL_SDIO_READ16(arg1)); + break; + + case SDIO_MP_WRITE_REG32: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 16); + arg2 = Strtoul((const u8*)(argv[2]), (u8 **)NULL, 16); + HAL_SDIO_WRITE32(arg1, arg2); + DiagPrintf("Write Reg[%x]=%x, Readback:%x\n", arg1, arg2, HAL_SDIO_READ32(arg1)); + break; + + case SDIO_MP_WAKEUP: + SDIO_Wakeup_Task(pSDIODev); + break; + + case SDIO_MP_DUMP: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 10); + if (arg1) { + if (!SDIO_IsEventPending(pSDIODev, SDIO_EVENT_DUMP)) { + // reset statistic + for (i=0;iMP_TxAvgTPWin[i] = 0; + pSDIODev->MP_RxAvgTPWin[i] = 0; + } + pSDIODev->MP_TxAvgTPWinSum = 0; + pSDIODev->MP_RxAvgTPWinSum = 0; + pSDIODev->OldestTxAvgWinIdx = 0; + pSDIODev->OldestRxAvgWinIdx = 0; + pSDIODev->TxAvgWinCnt = 0; + pSDIODev->RxAvgWinCnt = 0; + } + SDIO_SetEvent(pSDIODev, SDIO_EVENT_DUMP); + } + else { + SDIO_ClearEvent(pSDIODev, SDIO_EVENT_DUMP); + } + DiagPrintf("SDIO Dump %d\n", arg1); + break; + + case SDIO_MP_CTX: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 10); + if (arg1) { + if (!pSDIODev->MP_ContinueTx) { + // Backup origional TX Callback function + pSDIODev->pTxCallback_Backup = pSDIODev->Tx_Callback; + pSDIODev->pTxCb_Adapter_Backup = (VOID *)pSDIODev->pTxCb_Adapter; + DiagPrintf("Register SDIO TX Callback with Continue TX Test function\n"); + SDIO_Register_Tx_Callback(pSDIODev, &SDIO_MP_ContinueTx, (VOID *) pSDIODev); + pSDIODev->MP_ContinueTx = 1; + } + DiagPrintf("SDIO Continue TX Test Enabled\n"); + } + else { + if (pSDIODev->MP_ContinueTx) { + // Restore origional TX Callback function + DiagPrintf("Restore SDIO TX Callback...\n"); + SDIO_Register_Tx_Callback(pSDIODev, pSDIODev->pTxCallback_Backup, pSDIODev->pTxCb_Adapter_Backup); + pSDIODev->MP_ContinueTx = 0; + DiagPrintf("SDIO Continue TX Test Disabled\n"); + } + else { + DiagPrintf("SDIO Continue TX Test Didn't Enabled\n"); + } + } + break; + + case SDIO_MP_CRX: + case SDIO_MP_CRX_DA: + if(SDIO_MP_CRX == cmd_type) { + pSDIODev->MP_ContinueRxMode = SDIO_CRX_STATIC_BUF; + } + else if (SDIO_MP_CRX_DA == cmd_type) { + pSDIODev->MP_ContinueRxMode = SDIO_CRX_DYNA_BUF; + } + + if (pSDIODev->MP_ContinueRx) { + DiagPrintf("SDIO Continue RX Test Running\n"); + break; + } + pSDIODev->MP_ContinueRx = 1; + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 10); + if (arg1 < 16) { + DiagPrintf("SDIO RX Test Min Pkt Size is 16\n"); + arg1 = 16; + } + + if (arg1 > 4096) { + DiagPrintf("SDIO RX Test Max Pkt Size is 4096\n"); + arg1 = 4096; + } + pSDIODev->MP_CRxSize = arg1; + arg2 = Strtoul((const u8*)(argv[2]), (u8 **)NULL, 10); + pSDIODev->MP_CRxPktCnt = arg2; + if (arg2 == 0) { + pSDIODev->MP_CRxInfinite = 1; + } + + if (SDIO_CRX_STATIC_BUF == pSDIODev->MP_ContinueRxMode) { + if (NULL == pSDIODev->pMP_CRxBuf) { + pSDIODev->pMP_CRxBuf = RtlMalloc(pSDIODev->MP_CRxSize+26); // 26: Wlan header + DiagPrintf("SDIO RX Test: pBuf @ 0x%x\n", (u32)pSDIODev->pMP_CRxBuf); + if (((u32)(pSDIODev->pMP_CRxBuf) & 0x03) != 0) { + DiagPrintf("SDIO RX Test: pBuf Not 4-bytes Aligned!\n"); + } +#if SDIO_DEBUG + pSDIODev->MemAllocCnt++; +#endif + if (NULL != pSDIODev->pMP_CRxBuf) { + _memcpy(pSDIODev->pMP_CRxBuf, MP_WlanHdr, 26); + _memset((pSDIODev->pMP_CRxBuf+26), 0x3E, pSDIODev->MP_CRxSize); + } + } + + if (pSDIODev->pMP_CRxBuf) { + DiagPrintf("SDIO RX Test(Static RX Buf): PktSize=%d, PktCount=%d\n", pSDIODev->MP_CRxSize, pSDIODev->MP_CRxPktCnt); + SDIO_Wakeup_Task(pSDIODev); + } + else { + pSDIODev->MP_ContinueRx = 0; + pSDIODev->MP_CRxInfinite= 0; + pSDIODev->MP_CRxPktCnt = 0; + DiagPrintf("SDIO RX Test: Mem Allocate Failed\n"); + } + } + + if (SDIO_CRX_DYNA_BUF == pSDIODev->MP_ContinueRxMode) { + DiagPrintf("SDIO RX Test(Dyna-Allocate RX Buf): PktSize=%d, PktCount=%d\n", pSDIODev->MP_CRxSize, pSDIODev->MP_CRxPktCnt); + SDIO_Wakeup_Task(pSDIODev); + } + + break; + + case SDIO_MP_CRX_STOP: + pSDIODev->MP_ContinueRx = 0; + pSDIODev->MP_CRxPktCnt = 0; + pSDIODev->MP_CRxInfinite= 0; + DiagPrintf("SDIO RX Test Stopping...\n"); + break; + + case SDIO_MP_DBG_MSG: + arg1 = Strtoul((const u8*)(argv[1]), (u8 **)NULL, 10); + if (arg1) { + ConfigDebugInfo |= _DBG_SDIO_; + ConfigDebugWarn |= _DBG_SDIO_; + DiagPrintf("SDIO Debug Message On.\n"); + } + else { + ConfigDebugInfo &= ~_DBG_SDIO_; + ConfigDebugWarn &= ~_DBG_SDIO_; + DiagPrintf("SDIO Debug Message Off.\n"); + } + break; + + default: + DiagPrintf("SDIO_DeviceMPApp: Unknown Cmd=%s\n", argv[0]); + DiagPrintf("==== SDIO Command Help ====\n"); + DiagPrintf("SDIO mp_start : Enter MP mode\n"); + DiagPrintf("SDIO mp_stop : Exit MP mode(Switch back to Normal mode)\n"); + DiagPrintf("SDIO mp_loopback <1/0> : enable/disable data path loopback test\n"); + DiagPrintf("SDIO ctx <1/0> : Start/Stop SDIO continue TX test\n"); + DiagPrintf("SDIO crx : Start SDIO continue RX test with static RX Buffer\n"); + DiagPrintf("SDIO crx_da : Start SDIO continue RX test with Dynamic Allocate RX Buffer\n"); + DiagPrintf("SDIO crx_stop : Stop SDIO continue RX test\n"); + DiagPrintf("SDIO status : Dump current SDIO driver status\n"); + DiagPrintf("SDIO read_reg8 : Read SDIO register via 1-byte access\n"); + DiagPrintf("SDIO read_reg16 : Read SDIO register via 2-bytes access\n"); + DiagPrintf("SDIO read_reg32 : Read SDIO register via 4-bytes access\n"); + DiagPrintf("SDIO write_reg8 : Write SDIO register via 1-byte access\n"); + DiagPrintf("SDIO write_reg16 : Write SDIO register via 2-bytes access\n"); + DiagPrintf("SDIO write_reg32 : Write SDIO register via 4-bytes access\n"); + DiagPrintf("SDIO dump <1/0> : Start/Stop to dump SDIO throughput statistic periodically.\n"); + break; + } +} +#endif /* endof '#if SDIO_MP_MODE' */ + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c new file mode 100644 index 0000000..56e5d2b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.c @@ -0,0 +1,1941 @@ +/* + */ +#include "rtl8195a.h" +#include "rtl8195a_sdio_host.h" +//------------------------------------------------------------------------- +// Function declarations +/* + signed int SdioHostIsTimeout(uint32_t StartCount, uint32_t TimeoutCnt); + void SdioHostSendCmd(SDIO_HOST_CMD *Cmd); + signed int SdioHostGetResponse(void *Data, int RspType); + void SdioHostSdBusPwrCtrl(uint8_t En, int a2); + int SdioHostSdClkCtrl(void *Data, int En, int Divisor); + int SdioHostChkDataLineActive(uint32_t Timeout); + int SdioHostChkCmdInhibitCMD(uint32_t Timeout); + int SdioHostChkCmdInhibitDAT(uint32_t Timeout); + uint32_t SdioHostIsrHandle(void *Data); + int HalSdioHostDeInitRtl8195a(void *Data); + int HalSdioHostEnableRtl8195a(void *Data); + int HalSdioHostDisableRtl8195a(void *Data); + signed int HalSdioHostIrqInitRtl8195a(void *Data); + signed int HalSdioHostInitHostRtl8195a(void *Data); + int HalSdioHostStopTransferRtl8195a(void *Data, uint32_t a2); + signed int SdioHostErrIntRecovery(void *Data, int a2, signed int a3); + signed int SdioHostChkXferComplete(void *Data, uint32_t Timeout, signed int a3); + signed int SdioHostChkCmdComplete(void *Data, uint32_t Timeout); + int SdioHostCardSelection(void *Data, int Select, int a3); + int SdioHostGetCSD(void *Data, uint32_t a2); + int HalSdioHostReadBlocksDmaRtl8195a(int result, uint32_t a2, int64 a3, uint32_t BlockCnta); + int HalSdioHostWriteBlocksDmaRtl8195a(int result, uint32_t a2, int64 a3, uint32_t BlockCnta); + int SdioHostSwitchFunction(void *Data, int Mode, int Fn2Sel, int Fn1Sel, uint8_t *StatusBuf); + int HalSdioHostGetCardStatusRtl8195a(void *Data, uint32_t a2, int a3); + signed int HalSdioHostInitCardRtl8195a(void *Data, int a2, int a3); + int HalSdioHostGetSdStatusRtl8195a(void *Data, uint32_t a2, int a3); + signed int HalSdioHostChangeSdClockRtl8195a(void *Data, int Frequency); + int HalSdioHostEraseRtl8195a(uint64_t EndAddr, int64 a2, int64 EndAddra); + signed int HalSdioHostGetWriteProtectRtl8195a(void *Data, uint32_t a2, int a3); + int HalSdioHostSetWriteProtectRtl8195a(void *Data, int Setting); + */ +// int DiagPrintf(const char *, ...); weak +// int VectorIrqDisRtl8195A(u32); weak +// int VectorIrqUnRegisterRtl8195A(u32); weak +// int HalPinCtrlRtl8195A(u32, u32, u32); weak +// int VectorIrqRegisterRtl8195A(void); weak +// int VectorIrqEnRtl8195A(u32); weak +// int HalDelayUs(u32); weak +//------------------------------------------------------------------------- +// Data declarations +//------------------------------------------------------------------------- +//-----SdioHostIsTimeout(StartCount, TimeoutCnt) +HAL_Status SdioHostIsTimeout(u32 StartCount, u32 TimeoutCnt) { + u32 t1, t2; + HAL_Status result; + + t1 = HalTimerOp.HalTimerReadCount(1); + t2 = StartCount - t1; + if (StartCount < t1) + t2--; + if (TimeoutCnt >= t2) + result = HAL_OK; + else + result = HAL_TIMEOUT; + return result; +} + +//----- SdioHostSendCmd(PSDIO_HOST_CMD) +void SdioHostSendCmd(PSDIO_HOST_CMD Cmd) { + u16 reg_cmd = ((*(u8 *) &Cmd->CmdFmt & 0x3B) | (*(u8 *) &Cmd->CmdFmt & 0xC0) + | ((*((u8 *) &Cmd->CmdFmt + 1) & 0x3F) << 8)); + HAL_SDIO_HOST_WRITE32(REG_SDIO_HOST_ARG, Cmd->Arg); // 40058008 = Cmd->Arg + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_CMD, reg_cmd); // 4005800E = reg_cmd +} + +//----- +HAL_Status SdioHostGetResponse(void *Data, int RspType) { + HAL_Status result; + + if (Data) { + *((u32 *) Data + 5) = HAL_SDIO_HOST_READ32(REG_SDIO_HOST_RSP0); // 40058010; + *((u32 *) Data + 6) = HAL_SDIO_HOST_READ32(REG_SDIO_HOST_RSP2); + if (RspType == 1) { + *((u32 *) Data + 7) = HAL_SDIO_HOST_READ32(REG_SDIO_HOST_RSP4); + *((u32 *) Data + 8) = HAL_SDIO_HOST_READ32(REG_SDIO_HOST_RSP6); + } + result = HAL_OK; + } else + result = HAL_ERR_PARA; + return result; +} + +//----- +void SdioHostSdBusPwrCtrl(uint8_t En) { + u8 reg_pwr; + + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_PWR_CTRL, + HAL_SDIO_HOST_READ8(REG_SDIO_HOST_PWR_CTRL) & (~ PWR_CTRL_SD_BUS_PWR)); + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_CAPABILITIES) & CAPA_VOLT_SUPPORT_33V) { + DBG_SDIO_WARN("Supply SD bus voltage: 3.3V\n"); + reg_pwr = VOLT_30V << 1; + goto set_pwr; + } + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_CAPABILITIES) & CAPA_VOLT_SUPPORT_30V) { + DBG_SDIO_WARN("Supply SD bus voltage: 3.0V\n"); + reg_pwr = VOLT_30V << 1; + goto set_pwr; + } + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_CAPABILITIES) & CAPA_VOLT_SUPPORT_18V) { + DBG_SDIO_WARN("Supply SD bus voltage: 1.8V\n"); + reg_pwr = VOLT_18V << 1; + goto set_pwr; + } + DBG_SDIO_ERR("No supported voltage\n"); + goto exit_; + set_pwr: + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_PWR_CTRL, reg_pwr); + exit_: + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_PWR_CTRL, + HAL_SDIO_HOST_READ8(REG_SDIO_HOST_PWR_CTRL) | PWR_CTRL_SD_BUS_PWR); +} + +//----- +HAL_Status SdioHostSdClkCtrl(void *Data, int En, int Divisor) { // SD_CLK_DIVISOR + u8 *v3; // r3@1 + HAL_Status result; + char v5; // r2@7 + + v3 = Data; + result = HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) + & (PRES_STATE_CMD_INHIBIT_CMD | PRES_STATE_CMD_INHIBIT_DAT); // v40058024 & 3; + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) + & (PRES_STATE_CMD_INHIBIT_CMD | PRES_STATE_CMD_INHIBIT_DAT) != 0) { + result = HAL_BUSY; + } else { + if (!En) { + v4005802C &= 0xFFFBu; + return 0; + } + v4005802C &= 0xFFFBu; + v4005802C = v4005802C | (u16) ((u16) Divisor << 8); + v4005802C |= 4u; + if (Divisor == 8) { // BASE_CLK_DIVIDED_BY_16 + v5 = 4; + goto LABEL_23; + } + if ((unsigned int) Divisor > 8) { + if (Divisor == 32) { // BASE_CLK_DIVIDED_BY_64 + v5 = 2; + goto LABEL_23; + } + if ((unsigned int) Divisor > 0x20) { // BASE_CLK_DIVIDED_BY_64 + if (Divisor == 64) { // BASE_CLK_DIVIDED_BY_128 + v5 = 1; + goto LABEL_23; + } + if (Divisor == 128) { // BASE_CLK_DIVIDED_BY_256 + v3[133] = 0; + return result; + } + } else if (Divisor == 16) { + v5 = 3; + goto LABEL_23; + } + } else { + if (Divisor == 1) { // BASE_CLK_DIVIDED_BY_2 + v5 = 7; + goto LABEL_23; + } + if ((unsigned int) Divisor < 1) { // BASE_CLK < BASE_CLK_DIVIDED_BY_2 + v5 = 8; + LABEL_23: v3[133] = v5; + return result; + } + if (Divisor == 2) { // BASE_CLK_DIVIDED_BY_4 + v5 = 6; + goto LABEL_23; + } + if (Divisor == 4) { // BASE_CLK_DIVIDED_BY_8 + v5 = 5; + goto LABEL_23; + } + } + + DBG_SDIO_ERR("Unsupported SDCLK divisor!\n"); + return 0; + } + return result; +} + +//----- SdioHostChkDataLineActive(uint32_t Timeout) +HAL_Status SdioHostChkDataLineActive(uint32_t Timeout) { + HAL_Status result; + u32 t1 = HalTimerOp.HalTimerReadCount(1); + do { + if ((HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) + & PRES_STATE_DAT_LINE_ACTIVE) == 0) + break; + result = SdioHostIsTimeout(t1, 3225); + } while (result != HAL_TIMEOUT); + return result; +} + +//----- SdioHostChkCmdInhibitCMD(uint32_t Timeout) +HAL_Status SdioHostChkCmdInhibitCMD(uint32_t Timeout) { + HAL_Status result; + u32 t1 = HalTimerOp.HalTimerReadCount(1); + do { + if ((HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) + & PRES_STATE_CMD_INHIBIT_CMD) == 0) + break; + result = SdioHostIsTimeout(t1, 3225); + } while (result != HAL_TIMEOUT); + return result; +} + +//----- SdioHostChkCmdInhibitDAT(uint32_t Timeout) +int SdioHostChkCmdInhibitDAT(uint32_t Timeout) { + HAL_Status result; + u32 t1 = HalTimerOp.HalTimerReadCount(1); + do { + if ((HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) + & PRES_STATE_CMD_INHIBIT_DAT) == 0) + break; + result = SdioHostIsTimeout(t1, 3225); + } while (result != HAL_TIMEOUT); + return result; +} + +//----- (0000028C) -------------------------------------------------------- +void SdioHostIsrHandle(void *Data) { + int v1; // r5@1 + u32 *v2; // r4@1 + uint8_t v3; // r0@7 + int v4; // r1@7 + void (*v5)(u32); // r3@7 + void (*v6)(u32); // r3@10 +// uint32_t result; // r0@14 + + v1 = v40058030; + v40058038 = 0; + v2 = Data; + if (v1) { + if (v1 << 31 < 0) + *((u8 *) Data + 128) = 1; + if (v1 << 30 < 0) + *((u8 *) Data + 129) = 1; + if (v1 & NOR_INT_STAT_CARD_INSERT) // 0x40 + { + v3 = SdioHostSdClkCtrl(Data, 1, BASE_CLK_DIVIDED_BY_128); // BASE_CLK_DIVIDED_BY_128 + SdioHostSdBusPwrCtrl(v3, v4); + v5 = (void (*)(u32)) v2[35]; + if (v5) + v5(v2[37]); + } + if (v1 & NOR_INT_STAT_CARD_REMOVAL) // 0x80 + { + v40058029 &= 0xFEu; + SdioHostSdClkCtrl(v2, 0, BASE_CLK); // BASE_CLK + v6 = (void (*)(u32)) v2[36]; + if (v6) + v6(v2[38]); + } + if (v1 & NOR_INT_STAT_ERR_INT) // 0x8000 ) + { + v4005803A = 0; + *((u8 *) v2 + 130) = 1; + } + } + v40058034 = 195; +// result = 0; + v40058038 = 195; +// return 0; +} + +//----- (00000328) -------------------------------------------------------- +HAL_Status HalSdioHostDeInitRtl8195a(IN VOID *Data) { + void *v1; // r5@1 + int v2; // r4@1 + + PHAL_SDIO_HOST_ADAPTER v1 = Data; + v40058029 &= 0xFEu; + v2 = SdioHostSdClkCtrl(Data, 0, BASE_CLK); + if (!v2) { + if (v1) { + VectorIrqDisRtl8195A(v1); + VectorIrqUnRegisterRtl8195A(v1); + v4005802C &= 0xFFFEu; + v40059000 &= 0xFFFFFBFF; + v40000214 &= 0xFFFFFFFB; + HalPinCtrlRtl8195A(65, 0, 0); + v40000240 &= 0xFFFFFFF7; + v40000240 &= 0xFFFFFFFB; + } else { + v2 = 3; + } + } + return v2; +} +// 23DC: using guessed type int VectorIrqDisRtl8195A(u32); +// 23E0: using guessed type int VectorIrqUnRegisterRtl8195A(u32); +// 23E4: using guessed type int HalPinCtrlRtl8195A(u32, u32, u32); + +//----- (000003C0) -------------------------------------------------------- +HAL_Status HalSdioHostEnableRtl8195a(IN VOID *Data) // // PHAL_SDIO_HOST_ADAPTER Data +{ + v40000240 |= 4u; + v40000240 |= 8u; + v4005802C |= 1u; + while (!(v4005802C & 2)) + ; + return SdioHostSdClkCtrl(Data, 1, BASE_CLK_DIVIDED_BY_2); +} + +//----- (000003F8) -------------------------------------------------------- +HAL_Status HalSdioHostDisableRtl8195a(IN VOID *Data) { + int result; // r0@1 + + result = SdioHostSdClkCtrl(Data, 0, BASE_CLK); + if (!result) { + v4005802C &= 0xFFFEu; + v40000240 &= 0xFFFFFFF7; + v40000240 &= 0xFFFFFFFB; + } + return result; +} + +//----- HalSdioHostIrqInitRtl8195a +HAL_Status HalSdioHostIrqInitRtl8195a(IN VOID *Data) // PIRQ_HANDLE Data +{ + HAL_Status result; + PIRQ_HANDLE v1 = Data; + if (v1) { + v1->Data = Data; + v1->IrqNum = SDIO_HOST_IRQ; + v1->IrqFun = SdioHostIsrHandle; + v1->Priority = 6; + VectorIrqRegisterRtl8195A((PIRQ_HANDLE) v1); + VectorIrqEnRtl8195A((PIRQ_HANDLE) v1); + result = HAL_OK; + } else + result = HAL_ERR_PARA; + return result; +} + +//----- HalSdioHostInitHostRtl8195a +HAL_Status HalSdioHostInitHostRtl8195a(IN VOID *Data) { + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & (~BIT_SOC_ACTCK_SDIO_DEV_EN)); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & (~BIT_SOC_HCI_SDIOD_ON_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & (~BIT_SOC_HCI_SDIOD_OFF_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_HCI_PINMUX_CTRL) & (~BIT_HCI_SDIOD_PIN_EN)); + + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) | BIT_SOC_ACTCK_SDIO_HST_EN); + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0, + HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) | BIT_SOC_SLPCK_SDIO_HST_EN); + HalPinCtrlRtl8195A(SDIOH, 0, 1); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN, + HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) | BIT_SOC_HCI_SDIOH_EN); + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_SW_RESET, + HAL_SDIO_HOST_READ8(REG_SDIO_HOST_SW_RESET) | 1); //4005802F |= 1; + int x = 1000; + while (HAL_SDIO_HOST_READ8(REG_SDIO_HOST_SW_RESET) & 1) { + if (x-- == 0) { + DBG_SDIO_ERR("SD host initialization FAIL!\n"); + return HAL_TIMEOUT; + } + } + HalSdioHostIrqInitRtl8195a(Data); + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_STATUS_EN, 195); // 40058034 = 195; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_NORMAL_INT_SIG_EN, 195); // 40058038 = 195; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_STATUS_EN, 127); // 40058036 = 127; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_SIG_EN, 127); // 4005803A = 127; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_CLK_CTRL, + HAL_SDIO_HOST_READ16(REG_SDIO_HOST_CLK_CTRL) | CLK_CTRL_INTERAL_CLK_EN); // 4005802C |= 1; + x = 1000; + while (!(HAL_SDIO_HOST_READ16(REG_SDIO_HOST_CLK_CTRL) + & CLK_CTRL_INTERAL_CLK_STABLE)) { + if (x-- == 0) { + DBG_SDIO_ERR("SD host initialization FAIL!\n"); + return HAL_TIMEOUT; + } + } + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x59000, + HAL_READ32(SYSTEM_CTRL_BASE, 0x59000) | 0x400); // 40059000 |= 0x400; + if (HAL_SDIO_HOST_READ32(REG_SDIO_HOST_CAPABILITIES) & 0x80000) + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_HOST_CTRL, 16); //40058028 = 16; + HAL_SDIO_HOST_WRITE8(REG_SDIO_HOST_TIMEOUT_CTRL, 14); //4005802E = 14; + return 0; +} + +//----- (00000578) -------------------------------------------------------- +HAL_Status HalSdioHostStopTransferRtl8195a(IN VOID *Data) { + u8 *v2; // r4@1 + int result; // r0@2 + char v4; // r2@4 + uint32_t v5; // r1@4 + signed int v6; // r2@4 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-10h]@1 + + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v2 = Data; + if (Data) { + result = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (!result) { + result = SdioHostChkCmdInhibitDAT(0); + if (!result) { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt | 0x1B) + & 0xDF | 0xC0); + v4 = *((u8 *) &Cmd.CmdFmt + 1); + v2[128] = 0; + v2[129] = 0; + Cmd.Arg = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v4 & 0xC0 | 0xC; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v2, v5); + if (!result) + result = SdioHostChkXferComplete(v2, 0x1388u, v6); + } + } + } else { + result = 3; + } + return result; +} + +//----- (000005D8) -------------------------------------------------------- +signed int SdioHostErrIntRecovery(void *Data, int a2, signed int a3) { + u8 *v3; // r6@1 + __int16 v4; // r5@4 + int v5; // r3@5 + const char *v6; // r0@11 + signed int result; // r0@13 + int v8; // r3@15 + int v9; // r0@24 + const char *v10; // r0@32 + + v3 = Data; + if (!Data) + return 3; + DBG_SDIO_ERR("Recovering error interrupt...\n", a2, a3); + v4 = v40058032; + if (v40058032 << 28) { + v4005802F |= 2u; + v5 = 0; + while (1) { + ++v5; + a2 = v4005802F << 30; + if (!(v4005802F & 2)) + break; + a2 = 1001; + if (v5 == 1001) + goto LABEL_14; + } + if (v5 == 1000) { + DBG_SDIO_ERR("CMD line reset timeout!\n"); + return 2; + } + } + LABEL_14: if (v40058032 & 0x70) { + v4005802F |= 4u; + v8 = 0; + while (1) { + ++v8; + a2 = v4005802F << 29; + if (!(v4005802F & 4)) + break; + a2 = 1001; + if (v8 == 1001) + goto LABEL_22; + } + if (v8 == 1000) { + DBG_SDIO_ERR("DAT line reset timeout!\n"); + return 2; + } + } + LABEL_22: + DBG_SDIO_ERR("Error interrupt status: 0x%04X\n", v40058032); + v40058032 = v4; + v3[130] = 0; + v9 = HalSdioHostStopTransferRtl8195a(v3, a2); + if (!v9) { + while (1) { + ++v9; + if (!(v40058024 & 3)) + break; + if (v9 == 1001) + goto LABEL_30; + } + if (v9 == 1000) + return 2; + LABEL_30: if (v40058032 << 28) { + DBG_SDIO_ERR("Non-recoverable error(1)!\n"); + LABEL_33: DiagPrintf(v10); + goto LABEL_34; + } + } else { + if (v40058032 & 0x10) { + DBG_SDIO_ERR("Non-recoverable error(2)!\n"); + goto LABEL_34; + } + HalDelayUs(50); + if ((v40058024 & 0xF00000) == 15728640) { + DBG_SDIO_ERR("Recoverable error...\n"); + result = 16; + goto LABEL_44; + } + DBG_SDIO_ERR("Non-recoverable error(3)!\n"); + goto LABEL_34; + } + + LABEL_34: result = 238; + LABEL_44: v4005803A = 127; + return result; + + DBG_SDIO_ERR("Stop transmission error!\n"); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); +// 23F0: using guessed type int HalDelayUs(u32); + +//----- (00000748) -------------------------------------------------------- +signed int SdioHostChkXferComplete(void *Data, uint32_t Timeout, signed int a3) { + uint32_t v3; // r6@1 + u8 *v4; // r4@1 + uint32_t v5; // r5@3 + uint32_t v6; // r7@3 + signed int result; // r0@9 + + v3 = Timeout; + v4 = Data; + if (Data) { + if (Timeout - 1 > 0xFFFFFFFD) { + v6 = 0; + v5 = 0; + } else { + v5 = 1000 * Timeout / 0x1F; + v6 = (*((int (**)(u32)) &HalTimerOp + 2))(1); + } + do { + while (1) { + if (v4[129] && v40058024 & 0x100000) + return 0; + if (v4[130]) + return SdioHostErrIntRecovery(v4, Timeout, a3); + if (!v5) + break; + result = SdioHostIsTimeout(v6, v5); + if (result == 2) + return result; + } + } while (v3); + result = 1; + } else { + result = 3; + } + return result; +} + +//----- (000007C4) -------------------------------------------------------- +signed int SdioHostChkCmdComplete(void *Data, uint32_t Timeout) { + void *v2; // r4@1 + int v3; // r1@2 + signed int v4; // r2@2 + uint32_t v5; // r5@2 + signed int result; // r0@5 + + v2 = Data; + if (Data) { + v5 = (*((int (**)(u32, u32)) &HalTimerOp + 2))(1, Timeout); + while (!*((u8 *) v2 + 128)) { + if (*((u8 *) v2 + 130)) + return SdioHostErrIntRecovery(v2, v3, v4); + result = SdioHostIsTimeout(v5, 1612); + if (result == 2) + return result; + } + result = 0; + } else + result = 3; + + return result; +} + +//----- (0000080C) -------------------------------------------------------- +int SdioHostCardSelection(void *Data, int Select, int a3) { + u8 *v3; // r4@1 + int result; // r0@3 + char v5; // r3@5 + int v6; // r3@5 + uint32_t v7; // r1@5 + signed int v8; // r2@5 + signed int v9; // r5@6 + char v10; // r3@11 + uint32_t v11; // r1@11 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v13; // [sp+8h] [bp-10h]@1 + + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = Select; + v13 = a3; + v3 = Data; + if (Data) { + if (Select == 1) { + result = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (!result) { + result = SdioHostChkCmdInhibitDAT(0); + if (!result) { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt + | 0x1B) & 0x1F); + v5 = *((u8 *) &Cmd.CmdFmt + 1); + v3[128] = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v5 & 0xC0 | 7; + v6 = *((u16 *) v3 + 67); + v3[129] = 0; + Cmd.Arg = v6 << 16; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v3, v7); + if (!result) { + v9 = SdioHostChkXferComplete(v3, 0x1388u, v8); + if (v9 + || (SdioHostGetResponse(v3, + *(u8 *) &Cmd.CmdFmt & 3), v3[24] == 7)) { + result = v9; + } else { + DBG_SDIO_ERR("Command index error!\n"); + result = 238; + } + } + } + } + } else { + result = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (!result) { + *(u8 *) &Cmd.CmdFmt &= 4u; + v10 = *((u8 *) &Cmd.CmdFmt + 1); + v3[128] = 0; + Cmd.Arg = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v10 & 0xC0 | 7; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v3, v11); + } + } + } else { + result = 3; + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (000008FC) -------------------------------------------------------- +int SdioHostGetCSD(void *Data, uint32_t a2) { + void *v2; // r4@1 + int result; // r0@2 + int v4; // r3@3 + uint32_t v5; // r1@3 + signed int v6; // r6@3 + unsigned int v7; // r3@4 + unsigned int v8; // r2@4 + unsigned int v9; // r3@4 + unsigned int v10; // r2@4 + unsigned int v11; // r3@4 + unsigned int v12; // r2@4 + unsigned int v13; // r3@4 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v2 = Data; + if (Data) { + result = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (!result) { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xFC | 9) + & 0xF); + *((u8 *) &Cmd.CmdFmt + 1) = *((u8 *) &Cmd.CmdFmt + 1) & 0xC0 | 9; + v4 = *((u16 *) v2 + 67); + *((u8 *) v2 + 128) = 0; + Cmd.Arg = v4 << 16; + SdioHostSendCmd(&Cmd); + v6 = SdioHostChkCmdComplete(v2, v5); + if (!v6) { + SdioHostGetResponse(v2, *(u8 *) &Cmd.CmdFmt & 3); + v7 = *((u32 *) v2 + 8); + *((u8 *) v2 + 127) = 1; + *((u8 *) v2 + 112) = v7 >> 16; + *((u8 *) v2 + 114) = v7; + v8 = v7 >> 8; + v9 = *((u32 *) v2 + 7); + *((u8 *) v2 + 113) = v8; + *((u8 *) v2 + 115) = BYTE3(v9); + *((u8 *) v2 + 116) = v9 >> 16; + *((u8 *) v2 + 118) = v9; + v10 = v9 >> 8; + v11 = *((u32 *) v2 + 6); + *((u8 *) v2 + 117) = v10; + *((u8 *) v2 + 119) = BYTE3(v11); + *((u8 *) v2 + 120) = v11 >> 16; + *((u8 *) v2 + 122) = v11; + v12 = v11 >> 8; + v13 = *((u32 *) v2 + 5); + *((u8 *) v2 + 121) = v12; + *((u8 *) v2 + 123) = BYTE3(v13); + *((u8 *) v2 + 124) = v13 >> 16; + *((u8 *) v2 + 125) = BYTE1(v13); + *((u8 *) v2 + 126) = v13; + } + result = v6; + } else + result = 3; + return result; + } +} +//----- (000009CC) -------------------------------------------------------- +HAL_Status HalSdioHostReadBlocksDmaRtl8195a(IN VOID *Data, IN u64 ReadAddr, +IN u32 BlockCnt) { + int64 v4; // r4@1 + int v5; // r6@1 + int v6; // r7@3 + char v7; // r3@12 + uint32_t v8; // r1@12 + signed int v9; // r2@13 + int v10; // r1@16 + const char *v11; // r0@17 + char v12; // r3@20 + uint32_t v13; // r1@20 + signed int v14; // r2@23 + uint32_t v15; // r1@23 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + + HAL_Status result; + + *(u32 *) &Cmd.CmdFmt = result; + Cmd.Arg = a2; + v4 = a3; + v5 = result; + if (!result) + return 3; + if (BlockCnt >= 0x10000) + return HAL_ERR_PARA; + v6 = *(u32 *) (result + 16); + if (v6 << 30 || *(u32 *) (*(u32 *) (result + 16) + 4) << 30) + return 3; + if (*(u8 *) (result + 132)) + LODWORD (v4) = a3 >> 9; + while (1) { + while (1) { + HAL_SDIO_HOST_WRITE32(REG_SDIO_HOST_ADMA_SYS_ADDR, v6); // 40058058 = v6; + v40058004 = DATA_BLK_LEN; + if (BlockCnt != 1) + break; + v4005800C = 17; + LABEL_18: result = SdioHostChkCmdInhibitCMD(result); + if (result) + return result; + result = SdioHostChkDataLineActive(0); + if (result) + return result; + Cmd.CmdFmt = + (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 | 0x3A) + & 0x3F); + v12 = *((u8 *) &Cmd.CmdFmt + 1); + *(u8 *) (v5 + 128) = 0; + *(u8 *) (v5 + 129) = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v12 & 0xC0 | 0x11; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *) v5, v13); + if (result) + goto LABEL_21; + SdioHostGetResponse((void *) v5, *(u8 *) &Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete((void *) v5, 0x1388u, v14); + if (!result) + return 0; + if (result != 16) { + if (v40058032 & 0x200) { + v40058032 = 512; + if (HalSdioHostStopTransferRtl8195a((void *) v5, v15)) { + if (ConfigDebugErr & 0x400) { + v11 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_29; + } + } + } + return 238; + } + } + v40058006 = BlockCnta; + v4005800C = 55; + if (BlockCnta <= 1) + goto LABEL_18; + result = SdioHostChkCmdInhibitCMD(result); + if (result) + return result; + result = SdioHostChkDataLineActive(0); + if (result) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 | 0x3A) + & 0x3F); + v7 = *((u8 *) &Cmd.CmdFmt + 1); + *(u8 *) (v5 + 128) = 0; + *(u8 *) (v5 + 129) = 0; + *(u8 *) (v5 + 130) = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v7 & 0xC0 | 0x12; + Cmd.Arg = v4; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *) v5, v8); + if (!result) { + SdioHostGetResponse((void *) v5, *(u8 *) &Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete((void *) v5, 0x1388u, v9); + if (!result) + break; + } + LABEL_21: if (result != 16) + return result; + } + if (!(v40058032 & 0x20)) + return 0; + v10 = ConfigDebugErr << 21; + if (ConfigDebugErr & 0x400) { + v11 = "\r[SDIO Err]Data CRC error!\n"; + LABEL_29: DiagPrintf(v11, v10); + } + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000B78) -------------------------------------------------------- +HAL_Status HalSdioHostWriteBlocksDmaRtl8195a(IN VOID *Data, +IN u64 WriteAddr, +IN u32 BlockCnt) { + + PHAL_SDIO_HOST_ADAPTER pSdioHostAdapter = (PHAL_SDIO_HOST_ADAPTER) Data; //int v5; // r6@1 + uint32_t sec_count; // v4; // r4@1 + +//int v6; // r8@3 + char v7; // r3@12 + uint32_t v8; // r1@12 + signed int v9; // r2@13 + char v10; // r3@25 + uint32_t v11; // r1@25 + signed int v12; // r2@28 + uint32_t v13; // r1@29 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + HAL_Status result; + + *(u32 *) &Cmd.CmdFmt = ?; + Cmd.Arg = a2; + v4 = WriteAddr; +//v5 = result; //pSdioHostAdapter + if (BlockCnt == 0) + return HAL_ERR_PARA; + if (BlockCnt >= 0x10000) + return HAL_ERR_PARA; + ADMA2_DESC_FMT AdmaDescTbl = pSdioHostAdapter->AdmaDescTbl; + if (((u32) AdmaDescTbl & 3) || (AdmaDescTbl.Addr1 & 3)) + return HAL_ERR_PARA; + if (*(u8 *) (Data + 132)) + sec_count = WriteAddr >> 9; // + while (!(HAL_SDIO_HOST_READ32(REG_SDIO_HOST_PRESENT_STATE) & 0x100000)) { + result = SdioHostIsTimeout(v8, 0x3F01u); + if (result == HAL_TIMEOUT) { + DBG_SDIO_ERR("card busy TIMEOUT\n"); + return result; + } + } + + while (1) { + + while (1) { + HAL_SDIO_HOST_WRITE32(REG_SDIO_HOST_ADMA_SYS_ADDR, + (u32)AdmaDescTbl); //40058058 = v6; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_BLK_SIZE, DATA_BLK_LEN); // 40058004 = 512; + if (BlockCnt == 1) { + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_BLK_CNT, 1); // 4005800C = 1; + goto LABEL_23; + } + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_BLK_CNT, BlockCnt); // 40058006 = BlockCnta; + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_XFER_MODE, + XFER_MODE_DMA_EN | XFER_MODE_BLK_CNT_EN | XFER_MODE_AUTO_CMD12_EN | XFER_MODE_MULT_SINGLE_BLK); //4005800C = 0x27; + if (BlockCnt > 1) + break; + + LABEL_23: result = SdioHostChkCmdInhibitCMD(result); + if (result != HAL_OK) + return result; + result = SdioHostChkDataLineActive(0); + if (result != HAL_OK) + return result; + Cmd.CmdFmt = + (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 | 0x3A) + & 0x3F); + v10 = *((u8 *) &Cmd.CmdFmt + 1); + *(u8 *) (pSdioHostAdapter + 128) = 0; + *(u8 *) (pSdioHostAdapter + 129) = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v10 & 0xC0 | 0x18; + Cmd.Arg = sec_count; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *) v5, v11); + if (result) + goto LABEL_26; + SdioHostGetResponse((void *) pSdioHostAdapter, + *(u8 *) &Cmd.CmdFmt & 3); + if (*(u32 *) (pSdioHostAdapter + 20) & 0x4000000) { + LABEL_14: + DBG_SDIO_ERR("Write protect violation!\n"); + return HAL_ERR_PARA; + } + result = SdioHostChkXferComplete((void *) pSdioHostAdapter, 0x1388u, + v12); + if (result != HAL_OK) + return result; + if (result != 16) { + if (HAL_SDIO_HOST_READ16( + REG_SDIO_HOST_ERROR_INT_STATUS) & ERR_INT_STAT_ADMA) { + HAL_SDIO_HOST_WRITE16(REG_SDIO_HOST_ERROR_INT_STATUS, + ERR_INT_STAT_ADMA); // 40058032 = 512; + if (HalSdioHostStopTransferRtl8195a( + (void *) pSdioHostAdapter, v13)) { + DBG_SDIO_ERR("Stop transmission error!\n"); + } + } + return 238; + } + } + result = SdioHostChkCmdInhibitCMD(result); + if (result != HAL_OK) + return result; + result = SdioHostChkDataLineActive(0); + if (result != HAL_OK) + return result; + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 | 0x3A) + & 0x3F); + v7 = *((u8 *) &Cmd.CmdFmt + 1); + *(u8 *) (pSdioHostAdapter + 128) = 0; + *(u8 *) (pSdioHostAdapter + 129) = 0; + *(u8 *) (pSdioHostAdapter + 130) = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v7 & 0xC0 | 0x19; + Cmd.Arg = sec_count; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete((void *) v5, v8); + if (!result) { + SdioHostGetResponse((void *) pSdioHostAdapter, + *(u8 *) &Cmd.CmdFmt & 3); + if (*(u32 *) (pSdioHostAdapter + 20) & 0x4000000) + goto LABEL_14; + result = SdioHostChkXferComplete((void *) pSdioHostAdapter, 0x1F40u, + v9); + if (result != HAL_OK) + break; + } + LABEL_26: if (result != 16) + return result; + } + if (HAL_SDIO_HOST_READ16( + REG_SDIO_HOST_ERROR_INT_STATUS) & ERR_INT_STAT_DATA_CRC) // 40058032 & 0x20) + return HAL_ERR_UNKNOWN; + if (HAL_SDIO_HOST_READ16( + REG_SDIO_HOST_ERROR_INT_STATUS) & ERR_INT_STAT_DATA_TIMEOUT) + result = HAL_TIMEOUT; + else + result = HAL_OK; + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000D34) -------------------------------------------------------- +int SdioHostSwitchFunction(void *Data, int Mode, int Fn2Sel, int Fn1Sel, + uint8_t *StatusBuf) { + u8 *v5; // r4@1 + uint32_t v6; // r0@1 + int v7; // r5@1 + int v8; // r6@1 + char v9; // r7@3 + int result; // r0@3 + char v11; // r3@5 + uint32_t v12; // r1@5 + signed int v13; // r2@6 + uint32_t v14; // r1@6 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-20h]@1 + int v16; // [sp+8h] [bp-18h]@1 + + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = Mode; + v16 = Fn2Sel; + v5 = Data; + v6 = *((u32 *) Data + 4); + v7 = Mode; + v8 = Fn2Sel; + if (!v6 || ((u8) Fn1Sel | (u8) v6) & 3) { + result = 3; + } else { + v40058058 = v6; + v40058004 = 64; + v4005800C = 17; + v9 = *(u8 *) v6; + *(u16 *) (v6 + 2) = 64; + *(u8 *) v6 = ((v9 | 3) & 0xFB | 4 * ((Fn1Sel | v6) & 1)) & 0xEF + | 16 * ((Fn1Sel | v6) & 1) | 0x20; + *(u32 *) (v6 + 4) = Fn1Sel; + result = SdioHostChkCmdInhibitCMD(v6); + if (!result) { + result = SdioHostChkDataLineActive(0); + if (!result) { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 + | 0x3A) & 0x3F); + v11 = *((u8 *) &Cmd.CmdFmt + 1); + v5[128] = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v11 & 0xC0 | 6; + v5[129] = 0; + Cmd.Arg = v8 | 0xFFFFF0 | (v7 << 31); + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v5, v12); + if (!result) { + SdioHostGetResponse(v5, *(u8 *) &Cmd.CmdFmt & 3); + result = SdioHostChkXferComplete(v5, 0x1388u, v13); + if (result) { + if (result != 16) { + if (v40058032 & 0x200) { + v40058032 = 512; + if (HalSdioHostStopTransferRtl8195a(v5, v14)) { + DBG_SDIO_ERR("Stop transmission error!\n"); + } + } + } + result = 238; + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000E34) -------------------------------------------------------- +HAL_Status HalSdioHostGetCardStatusRtl8195a(IN VOID *Data) { + void *v3; // r4@1 + int result; // r0@2 + char v5; // r3@3 + uint32_t v6; // r1@3 + signed int v7; // r5@3 + unsigned int v8; // r3@7 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v10; // [sp+8h] [bp-10h]@1 + + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v10 = a3; + v3 = Data; + if (!Data) + return 3; + result = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (result) + return result; + Cmd.CmdFmt = + (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xF4 | 0x1A) & 0x1F); + v5 = *((u8 *) &Cmd.CmdFmt + 1); + *((u8 *) v3 + 128) = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v5 & 0xC0 | 0xD; + Cmd.Arg = *((u16 *) v3 + 67) << 16; + SdioHostSendCmd(&Cmd); + v7 = SdioHostChkCmdComplete(v3, v6); + if (v7) + return v7; + SdioHostGetResponse(v3, *(u8 *) &Cmd.CmdFmt & 3); + if (*((u8 *) v3 + 24) == 13) { + v8 = *((u32 *) v3 + 5); + *((u32 *) v3 + 10) = v8; + *((u8 *) v3 + 131) = (v8 >> 9) & 0xF; + return v7; + } + DBG_SDIO_ERR("Command index error!\n"); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00000ED0) -------------------------------------------------------- +HAL_Status HalSdioHostInitCardRtl8195a(IN VOID *Data) { + u8 *v3; // r5@1 + int v4; // r0@2 + char v5; // r3@3 + uint32_t v6; // r1@3 + signed int v7; // r4@4 + const char *v8; // r0@6 + int v9; // r0@7 + uint32_t v10; // r1@8 + const char *v11; // r0@11 + int v12; // r3@12 + int v13; // r0@24 + char v14; // r3@25 + uint32_t v15; // r1@25 + signed int v16; // r0@26 + const char *v17; // r0@28 + char v18; // r3@34 + uint32_t v19; // r1@34 + signed int v20; // r0@35 + signed int v21; // r6@35 + u8 v22; // cf@36 + char v23; // r3@39 + uint32_t v24; // r1@39 + signed int v25; // r0@40 + const char *v26; // r0@42 + char v27; // r3@48 + uint32_t v28; // r1@48 + const char *v29; // r0@53 + uint32_t v30; // r0@64 + int v31; // r0@64 + char v32; // r3@65 + uint32_t v33; // r1@65 + int v34; // r0@70 + char v35; // r3@71 + uint32_t v36; // r1@71 + uint32_t v37; // r1@81 + int v38; // r2@81 + int v39; // r6@81 + int v40; // r1@82 + const char *v41; // r0@83 + int v42; // r0@87 + uint32_t v43; // r1@87 + int v44; // r2@87 + int v45; // r3@88 + uint32_t v46; // r1@88 + signed int v47; // r0@89 + const char *v48; // r0@91 + char v49; // r3@98 + uint32_t v50; // r1@98 + void *v52; // [sp+0h] [bp-20h]@1 + int v53; // [sp+4h] [bp-1Ch]@1 + int v54; // [sp+8h] [bp-18h]@1 + + v52 = Data; + v53 = a2; + v54 = a3; + v3 = Data; + if (!Data) { + v7 = 3; + goto LABEL_115; + }; + v4 = SdioHostChkCmdInhibitCMD((uint32_t) Data); + if (!v4) { + v5 = (char) v52; + v3[128] = 0; + LOBYTE (v52) = v5 & 4; + v53 = 0; + BYTE1(v52) &= 0xC0u; + SdioHostSendCmd((SDIO_HOST_CMD *) &v52); + v4 = SdioHostChkCmdComplete(v3, v6); + }; + v7 = v4; + if (v4) { + DBG_SDIO_ERR("Reset sd card fail!\n"); + goto LABEL_104; + }; + goto LABEL_115; + + v9 = SdioHostChkCmdInhibitCMD(0); + if (v9 + || (LOBYTE(v52) = (((u8) v52 & 0xF4 | 0x1A) & 0xDF | 32 * (v7 & 1)) + & 0x3F | ((v7 & 3) << 6), BYTE1(v52) = BYTE1(v52) & 0xC0 + | 8, v3[128] = v7, v53 = 426, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v52), (v9 = SdioHostChkCmdComplete(v3, + v10)) != 0)) { + v7 = v9; + if (v9) + goto LABEL_22; + } else { + SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] != 8) { + if (ConfigDebugErr & 0x400) { + v11 = "\r[SDIO Err]Command index error!\n" + ); // DBG_SDIO_ERR(" + LABEL_18: DiagPrintf(v11); + goto LABEL_21; + } + goto LABEL_21; + } + v12 = *((u32 *) v3 + 5); + if ((u8) v12 != 170) { + DBG_SDIO_ERR("Echo-back of check pattern: %X\n"); + goto LABEL_21; + } + v9 = v12 << 23; + if (!(v12 & 0x100)) { + if (ConfigDebugErr & 0x400) { + v11 = "\r[SDIO Err]Voltage accepted error!\n"; + goto LABEL_18; + } + LABEL_21: v7 = 238; + LABEL_22: if (ConfigDebugErr & 0x400) { + v8 = "\r[SDIO Err]Voltage check fail!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + } + v13 = SdioHostChkCmdInhibitCMD(v9); + if (v13) + goto LABEL_63; + LOBYTE (v52) = ((u8) v52 & 0xFC | 0x1A) & 0x1F; + v14 = BYTE1(v52) & 0xC0 | 0x37; + v3[128] = v7; + BYTE1 (v52) = v14; + v53 = v7; + SdioHostSendCmd((SDIO_HOST_CMD *) &v52); + v13 = SdioHostChkCmdComplete(v3, v15); + if (v13) + goto LABEL_63; + v16 = SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] != 55) { + if (ConfigDebugErr & 0x400) // DBG_SDIO_ERR(" + { + v17 = "\r[SDIO Err]Command index error!\n"; + LABEL_32: DiagPrintf(v17); + goto LABEL_57; + } + goto LABEL_57; + }; + if (!(*((u32 *) v3 + 5) & 0x20)) { + if (ConfigDebugErr & 0x400) { + v17 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_32; + } + LABEL_57: v7 = 238; + goto LABEL_60; + }; + v13 = SdioHostChkCmdInhibitCMD(v16); + if (v13 + || (LOBYTE(v52) = ((u8) v52 & 0xFC | 2) & 7, v18 = BYTE1(v52) & 0xC0 + | 0x29, v3[128] = v7, BYTE1(v52) = v18, v53 = v7, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v52), (v13 = SdioHostChkCmdComplete(v3, + v19)) != 0)) { + LABEL_63: v7 = v13; + if (!v13) + goto LABEL_64; + LABEL_60: if (ConfigDebugErr & 0x400) { + v8 = "\r[SDIO Err]Get OCR fail!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + v20 = SdioHostGetResponse(v3, (u8) v52 & 3); + v21 = 100; + *((u32 *) v3 + 9) = *((u32 *) v3 + 5) & 0xFFFFFF; + while (1) { + v22 = __CFADD__(v21--, -1); + if (!v22) + goto LABEL_51; + v13 = SdioHostChkCmdInhibitCMD(v20); + if (v13) + goto LABEL_63; + LOBYTE (v52) = ((u8) v52 & 0xFC | 0x1A) & 0x1F; + v23 = BYTE1(v52); + v3[128] = 0; + v53 = 0; + BYTE1 (v52) = v23 & 0xC0 | 0x37; + SdioHostSendCmd((SDIO_HOST_CMD *) &v52); + v13 = SdioHostChkCmdComplete(v3, v24); + if (v13) + goto LABEL_63; + v25 = SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] != 55) { + if (ConfigDebugErr & 0x400) { + v26 = "\r[SDIO Err]Command index error!\n"; + LABEL_46: DiagPrintf(v26); + goto LABEL_62; + } + goto LABEL_62; + } + if (!(*((u32 *) v3 + 5) & 0x20)) { + if (ConfigDebugErr & 0x400) { + v26 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_46; + } + LABEL_62: v13 = 238; + goto LABEL_63; + } + v13 = SdioHostChkCmdInhibitCMD(v25); + if (v13) + goto LABEL_63; + LOBYTE (v52) = ((u8) v52 & 0xFC | 2) & 7; + v27 = BYTE1(v52); + v3[128] = 0; + BYTE1 (v52) = v27 & 0xC0 | 0x29; + v53 = 1077673984; + SdioHostSendCmd((SDIO_HOST_CMD *) &v52); + v13 = SdioHostChkCmdComplete(v3, v28); + if (v13) + goto LABEL_63; + SdioHostGetResponse(v3, (u8) v52 & 3); + if (*((u32 *) v3 + 5) < 0) + break; + v20 = HalDelayUs(10000); + }; + if (!v21) { + v7 = 2; + goto LABEL_60; + }; + LABEL_51: if (*((u32 *) v3 + 5) & 0x40000000) { + v3[132] = 1; + if (!(ConfigDebugInfo & 0x400)) + goto LABEL_64; + v29 = "\r[SDIO Inf]This is a SDHC card\n"; + } else { + v3[132] = 0; + if (!(ConfigDebugInfo & 0x400)) + goto LABEL_64; + v29 = "\r[SDIO Inf]This is a SDSC card\n"; + } + DiagPrintf(v29); + LABEL_64: v30 = HalDelayUs(20); + v31 = SdioHostChkCmdInhibitCMD(v30); + if (v31 + || (LOBYTE(v52) = ((u8) v52 & 0xF4 | 9) & 0xF, v32 = BYTE1(v52) + & 0xC0 | 2, v3[128] = v7, BYTE1(v52) = v32, v53 = v7, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v52), (v31 = SdioHostChkCmdComplete(v3, + v33)) != 0)) { + v7 = v31; + if (!v31) + goto LABEL_70; + if (ConfigDebugErr & 0x400) { + v8 = "\r[SDIO Err]Get CID fail!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + v31 = SdioHostGetResponse(v3, (u8) v52 & 3); + LABEL_70: v34 = SdioHostChkCmdInhibitCMD(v31); + if (v34 + || (LOBYTE(v52) = ((u8) v52 & 0xF4 | 0x1A) & 0x1F, v35 = BYTE1(v52) + & 0xC0 | 3, v3[128] = v7, BYTE1(v52) = v35, v53 = v7, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v52), (v34 = SdioHostChkCmdComplete(v3, + v36)) != 0)) { + v7 = v34; + if (v34) + goto LABEL_79; + } else { + SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] != 3) { + if (ConfigDebugErr & 0x400) + DiagPrintf("\r[SDIO Err]Command index error!\n"); + v7 = 238; + LABEL_79: if (ConfigDebugErr & 0x400) { + v8 = "\r[SDIO Err]Get RCA fail!\n"; + goto LABEL_104; + } + goto LABEL_115; + } + *((u16 *) v3 + 67) = *((u16 *) v3 + 11); + } + SdioHostSdClkCtrl(v3, 1, BASE_CLK_DIVIDED_BY_2); + v39 = SdioHostGetCSD(v3, v37); + if (v39) { + v40 = ConfigDebugErr << 21; + if (ConfigDebugErr & 0x400) { + v41 = "\r[SDIO Err]Get CSD fail!\n"; + goto LABEL_108; + } + LABEL_113: v7 = v39; + goto LABEL_115; + } + v39 = SdioHostCardSelection(v3, 1, v38); + if (v39) { + if (!(ConfigDebugErr & 0x400)) + goto LABEL_113; + v41 = "\r[SDIO Err]Select sd card fail!\n"; + LABEL_108: DiagPrintf(v41, v40); + goto LABEL_113; + } + v42 = SdioHostChkCmdInhibitCMD(0); + if (v42) + goto LABEL_120; + LOBYTE (v52) = ((u8) v52 & 0xFC | 0x1A) & 0x1F; + BYTE1 (v52) = BYTE1(v52) & 0xC0 | 0x37; + v45 = *((u16 *) v3 + 67) << 16; + v3[128] = v7; + v53 = v45; + SdioHostSendCmd((SDIO_HOST_CMD *) &v52); + v42 = SdioHostChkCmdComplete(v3, v46); + if (v42) + goto LABEL_120; + v47 = SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] != 55) + goto LABEL_90; + if (!(*((u32 *) v3 + 5) & 0x20)) { + if (ConfigDebugErr & 0x400) { + v48 = "\r[SDIO Err]ACMD isn't expected!\n"; + LABEL_95: DiagPrintf(v48); + } + goto LABEL_96; + } + v42 = SdioHostChkCmdInhibitCMD(v47); + if (v42 + || (LOBYTE(v52) = ((u8) v52 & 0xFC | 0x1A) & 0x1F, v49 = BYTE1(v52) + & 0xC0 | 6, v3[128] = v7, BYTE1(v52) = v49, v53 = 2, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v52), (v42 = SdioHostChkCmdComplete(v3, + v50)) != 0)) { + LABEL_120: v7 = v42; + if (v42) + goto LABEL_102; + LABEL_105: v39 = HalSdioHostGetCardStatusRtl8195a(v3, v43, v44); + if (v39) { + v40 = ConfigDebugErr << 21; + if (!(ConfigDebugErr & 0x400)) + goto LABEL_113; + v41 = "\r[SDIO Err]Get sd card current state fail!\n"; + goto LABEL_108; + } + if (v3[131] != 4) { + DBG_SDIO_ERR( + "The card isn't in TRANSFER state! (Current state: %d)\n", + v3[131], ConfigDebugErr << 21); + v7 = 238; + goto LABEL_115; + } + } else { + SdioHostGetResponse(v3, (u8) v52 & 3); + if (v3[24] == 6) { + v44 = v40058028 | 2; + v40058028 |= 2u; + goto LABEL_105; + } + LABEL_90: if (ConfigDebugErr & 0x400) { + v48 = "\r[SDIO Err]Command index error!\n"; + goto LABEL_95; + } + LABEL_96: v7 = 238; + LABEL_102: if (ConfigDebugErr & 0x400) { + v8 = "\r[SDIO Err]Set bus width fail!\n"; + LABEL_104: DiagPrintf(v8); + } + LABEL_115: + DBG_SDIO_ERR("SD card initialization FAIL!\n"); + } + return v7; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); +// 23F0: using guessed type int HalDelayUs(u32); + +//----- (000014E8) -------------------------------------------------------- +HAL_Status HalSdioHostGetSdStatusRtl8195a(IN VOID *Data) { + int v3; // r3@1 + char *v4; // r4@1 + char v5; // r0@3 + int v6; // r0@3 + int result; // r0@3 + int v8; // r3@4 + uint32_t v9; // r1@4 + const char *v10; // r0@7 + int v11; // r3@8 + char v12; // r3@13 + uint32_t v13; // r1@13 + signed int v14; // r2@14 + signed int v15; // r0@14 + uint32_t v16; // r1@14 + SDIO_HOST_CMD Cmd; // [sp+0h] [bp-18h]@1 + int v18; // [sp+8h] [bp-10h]@1 + + v3 = *((u32 *) Data + 4); + *(u32 *) &Cmd.CmdFmt = Data; + Cmd.Arg = a2; + v18 = a3; + v4 = (char *) Data; + if (!v3 || v3 & 3) { + result = 3; + } else { + v40058058 = v3; + v40058004 = 64; + v4005800C = 17; + v5 = *(u8 *) v3; + *(u16 *) (v3 + 2) = 64; + v6 = (u8) ((v5 | 3) & 0xEB) | 0x20; + *(u8 *) v3 = v6; + *(u32 *) (v3 + 4) = v4 + 48; + result = SdioHostChkCmdInhibitCMD(v6); + if (!result) { + Cmd.CmdFmt = + (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt & 0xFC | 0x1A) + & 0x1F); + *((u8 *) &Cmd.CmdFmt + 1) = *((u8 *) &Cmd.CmdFmt + 1) & 0xC0 | 0x37; + v8 = *((u16 *) v4 + 67); + v4[128] = 0; + Cmd.Arg = v8 << 16; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v4, v9); + if (!result) { + SdioHostGetResponse(v4, *(u8 *) &Cmd.CmdFmt & 3); + if (v4[24] != 55) { + if (ConfigDebugErr & 0x400) { + v10 = "\r[SDIO Err]Command index error!\n"; + LABEL_20: DiagPrintf(v10); + return 238; + } + return 238; + } + v11 = *((u32 *) v4 + 5); + if (!(v11 & 0x20)) { + if (ConfigDebugErr & 0x400) { + v10 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_20; + } + return 238; + } + result = SdioHostChkCmdInhibitCMD(*((u32 *) v4 + 5) << 26); + if (!result) { + result = SdioHostChkDataLineActive(0); + if (!result) { + Cmd.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &Cmd.CmdFmt + & 0xFC | 0x3A) & 0x3F); + v12 = *((u8 *) &Cmd.CmdFmt + 1); + v4[128] = 0; + v4[129] = 0; + Cmd.Arg = 0; + *((u8 *) &Cmd.CmdFmt + 1) = v12 & 0xC0 | 0xD; + SdioHostSendCmd(&Cmd); + result = SdioHostChkCmdComplete(v4, v13); + if (!result) { + SdioHostGetResponse(v4, *(u8 *) &Cmd.CmdFmt & 3); + v15 = SdioHostChkXferComplete(v4, 0x1388u, v14); + if (v15) { + if (v15 == 16) + return 238; + if (!(v40058032 & 0x200)) + return 238; + v40058032 = 512; + if (!HalSdioHostStopTransferRtl8195a(v4, v16) + || !(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_20; + } + result = 0; + } + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001668) -------------------------------------------------------- +HAL_Status HalSdioHostChangeSdClockRtl8195a(IN VOID *Data, IN u8 Frequency) { + PHAL_SDIO_HOST_ADAPTER v2 /*pSdioHostAdapter*/= + (PHAL_SDIO_HOST_ADAPTER) Data; + u8 * v2; // r5@1 + int v3; // r4@6 + int v4; // r2@8 + int v5; // r0@10 + int v6; // r0@10 + char v7; // r3@11 + uint32_t v8; // r1@11 + signed int v9; // r0@12 + const char *v10; // r0@14 + char v11; // r3@22 + uint32_t v12; // r1@22 + signed int v13; // r2@23 + signed int v14; // r0@23 + uint32_t v15; // r1@25 + int v16; // r0@32 + int v17; // r0@34 + int v18; // r0@36 + const char *v19; // r0@40 + int v20; // r2@52 + char v22; // [sp+0h] [bp-58h]@11 + char v23; // [sp+1h] [bp-57h]@11 + int v24; // [sp+4h] [bp-54h]@11 + uint8_t StatusData[64]; // [sp+8h] [bp-50h]@8 + + v2 = Data; + if (!Data || (unsigned int) (Frequency - 5) > 3) + return 3; + if (v2.CurrSdClk == Frequency) { + DBG_SDIO_WARN( + "Current SDCLK frequency is already the specified value...\n"); + return 0; + } + if (Frequency != SD_CLK_41_6MHZ) { // SD_CLK_41_6MHZ + if (Frequency == SD_CLK_10_4MHZ) // SD_CLK_10_4MHZ + v20 = BASE_CLK_DIVIDED_BY_4; + else if (Frequency == SD_CLK_20_8MHZ) // SD_CLK_20_8MHZ + v20 = BASE_CLK_DIVIDED_BY_2; + else if (Frequency != SD_CLK_5_2MHZ) { // SD_CLK_5_2MHZ + DBG_SDIO_ERR("Unsupported SDCLK frequency!\n"); + v3 = 3; + goto LABEL_60; + } + v20 = BASE_CLK_DIVIDED_BY_8; + } + v3 = SdioHostSdClkCtrl(Data, 1, v20); + if (!v3) + return 0; + LABEL_60: if (!(ConfigDebugErr & 0x400)) { + return v3; + v19 = "\r[SDIO Err]Host changes clock fail!\n"; // DBG_SDIO_ERR(" + goto LABEL_62; + } + v4 = *((u32 *) Data + 4); + *(u32 *) StatusData = 0; + *(u32 *) &StatusData[4] = 0; + if (!v4 || v4 & 3) + return 3; + v40058058 = v4; + v40058004 = 8; + v4005800C = 17; + v5 = (u8) ((*(u8 *) v4 | 3) & 0xEB) | 0x20; + *(u8 *) v4 = v5; + *(u16 *) (v4 + 2) = 8; + *(u32 *) (v4 + 4) = StatusData; + v6 = SdioHostChkCmdInhibitCMD(v5); + if (v6) + goto LABEL_70; + v22 = (v22 & 0xF4 | 0x1A) & 0x1F; + v7 = v23; + v2[128] = 0; + v23 = v7 & 0xC0 | 0x37; + v24 = *((u16 *) v2 + 67) << 16; + SdioHostSendCmd((SDIO_HOST_CMD *) &v22); + v6 = SdioHostChkCmdComplete(v2, v8); + if (v6) + goto LABEL_70; + v9 = SdioHostGetResponse(v2, v22 & 3); + if (v2[24] != 55) { + if (!(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]Command index error!\n"; + LABEL_15: DiagPrintf(v10); + return 238; + } + if (!(*((u32 *) v2 + 5) & 0x20)) { + if (!(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]ACMD isn't expected!\n"; + goto LABEL_15; + } + v6 = SdioHostChkCmdInhibitCMD(v9); + if (v6 || (v6 = SdioHostChkDataLineActive(0)) != 0 + || (v22 = (v22 & 0xF4 | 0x3A) & 0x3F, v11 = v23, v2[128] = 0, v2[129] = + 0, v24 = 0, v23 = v11 & 0xC0 | 0x33, SdioHostSendCmd( + (SDIO_HOST_CMD *) &v22), (v6 = SdioHostChkCmdComplete(v2, + v12)) != 0)) { + LABEL_70: v3 = v6; + if (v6) + return v3; + } else { + SdioHostGetResponse(v2, v22 & 3); + v14 = SdioHostChkXferComplete(v2, 0x1388u, v13); + if (v14) { + if (v14 == 16) + return 238; + v15 = v40058032 << 22; + if (!(v40058032 & 0x200)) + return 238; + v40058032 = 512; + if (!HalSdioHostStopTransferRtl8195a(v2, v15) + || !(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]Stop transmission error!\n"; + goto LABEL_15; + } + v3 = 0; + *((u16 *) v2 + 68) = StatusData[0] & 0xF; + } + if (*((u16 *) v2 + 68)) { + v16 = SdioHostSwitchFunction(v2, 0, 15, (int) StatusData, + *(uint8_t **) &v22); + if (v16) + return v16; + if (StatusData[13] & 2) { + v17 = SdioHostSwitchFunction(v2, v16, 1, (int) StatusData, + *(uint8_t **) &v22); + if (v17) + return v17; + if ((StatusData[16] & 0xF) != 1) { + if (!(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]\"High-Speed\" can't be switched!\n"; + goto LABEL_15; + } + v18 = SdioHostSwitchFunction(v2, 1, 1, (int) StatusData, + *(uint8_t **) &v22); + if (v18) + return v18; + if ((StatusData[16] & 0xF) != 1) { + if (!(ConfigDebugErr & 0x400)) + return 238; + v10 = "\r[SDIO Err]Card changes to High-Speed fail!\n"; + goto LABEL_15; + } + v3 = SdioHostSdClkCtrl(v2, 1, v18); + if (v3) { + if (!(ConfigDebugErr & 0x400)) + return v3; + v19 = "\r[SDIO Err]Host changes to High-Speed fail!\n"; + LABEL_62: DiagPrintf(v19); + return v3; + } + } else if (ConfigDebugInfo & 0x400) { +// DBG_SDIO_WARN(" + v19 = + "\r[SDIO Inf]This card doesn't support \"High-Speed Function\" and can't change to high-speed...\n"; + goto LABEL_62; + } + } else if (ConfigDebugInfo & 0x400) { + v19 = + "\r[SDIO Inf]This card doesn't support CMD6 and can't change to high-speed...\n"; + goto LABEL_62; + } + return 0; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (0000194C) -------------------------------------------------------- +HAL_Status HalSdioHostEraseRtl8195a(IN VOID *Data, IN u64 StartAddr, +IN u64 EndAddr) { + uint32_t v3; // r4@1 + uint32_t v4; // r6@1 + int v5; // r8@1 + int result; // r0@4 + char v7; // r3@5 + uint32_t v8; // r1@5 + signed int v9; // r0@6 + char v10; // r3@11 + uint32_t v11; // r1@11 + signed int v12; // r0@12 + char v13; // r3@15 + uint32_t v14; // r1@15 + signed int v15; // r2@15 + SDIO_HOST_CMD v16; // [sp+0h] [bp-20h]@1 + + v16 = (SDIO_HOST_CMD) EndAddr; + v3 = EndAddra; + v4 = a2; + v5 = EndAddr; + if (!(u32) EndAddr) + return 3; + if (*(u8 *) (EndAddr + 132)) { + v4 = a2 >> 9; + v3 = EndAddra >> 9; + } + result = SdioHostChkCmdInhibitCMD(EndAddr); + if (!result) { + v16.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &v16.CmdFmt & 0xFC | 0x1A) + & 0x1F); + v7 = *((u8 *) &v16.CmdFmt + 1); + *(u8 *) (v5 + 128) = 0; + *((u8 *) &v16.CmdFmt + 1) = v7 & 0xC0 | 0x20; + v16.Arg = v4; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *) v5, v8); + if (!result) { + v9 = SdioHostGetResponse((void *) v5, *(u8 *) &v16.CmdFmt & 3); + if (*(u8 *) (v5 + 24) != 32) + goto LABEL_20; + result = SdioHostChkCmdInhibitCMD(v9); + if (result) + return result; + v16.CmdFmt = + (SDIO_HOST_CMD_FMT) ((*(u8 *) &v16.CmdFmt & 0xFC | 0x1A) + & 0x1F); + v10 = *((u8 *) &v16.CmdFmt + 1); + *(u8 *) (v5 + 128) = 0; + *((u8 *) &v16.CmdFmt + 1) = v10 & 0xC0 | 0x21; + v16.Arg = v3; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *) v5, v11); + if (result) + return result; + v12 = SdioHostGetResponse((void *) v5, *(u8 *) &v16.CmdFmt & 3); + if (*(u8 *) (v5 + 24) != 33) { + LABEL_20: + DBG_SDIO_ERR("Command index error!\n"); + result = 238; + } else { + result = SdioHostChkCmdInhibitCMD(v12); + if (!result) { + result = SdioHostChkCmdInhibitDAT(0); + if (!result) { + v16.CmdFmt = (SDIO_HOST_CMD_FMT) ((*(u8 *) &v16.CmdFmt + | 0x1B) & 0x1F); + v13 = *((u8 *) &v16.CmdFmt + 1); + *(u8 *) (v5 + 128) = 0; + *(u8 *) (v5 + 129) = 0; + v16.Arg = 0; + *((u8 *) &v16.CmdFmt + 1) = v13 & 0xC0 | 0x26; + SdioHostSendCmd(&v16); + result = SdioHostChkCmdComplete((void *) v5, v14); + if (!result) + result = SdioHostChkXferComplete((void *) v5, + 0x1388u, v15); + } + } + } + } + } + return result; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001AA8) -------------------------------------------------------- +HAL_Status HalSdioHostGetWriteProtectRtl8195a(IN VOID *Data) { + void *v3; // r4@1 + uint32_t v4; // r1@2 + int v5; // r2@2 + int v6; // r5@2 + signed int result; // r0@6 + int v8; // r2@10 + const char *v9; // r0@13 + + v3 = Data; + if (!Data) + return 3; + v6 = HalSdioHostGetCardStatusRtl8195a(Data, a2, a3); + if (v6) { + if (!(ConfigDebugErr & 0x400)) + return v6; + v9 = "\r[SDIO Err]Get card status fail!\n"; + LABEL_16: DiagPrintf(v9); + return v6; + } + if (*((u8 *) v3 + 131) == 3) { + LABEL_10: v6 = SdioHostGetCSD(v3, v4); + if (!v6) { + *((u32 *) v3 + 11) = ((unsigned int) *((u8 *) v3 + 126) >> 4) & 1; + return SdioHostCardSelection(v3, 1, v8); + } + if (!(ConfigDebugErr & 0x400)) + return v6; + v9 = "\r[SDIO Err]Get CSD fail!\n"; + goto LABEL_16; + } + if (*((u8 *) v3 + 131) == 4 || *((u8 *) v3 + 131) == 5) { + result = SdioHostCardSelection(v3, 0, v5); + if (result) + return result; + goto LABEL_10; + } + if (ConfigDebugErr & 0x400) + DiagPrintf("\r[SDIO Err]Wrong card state!\n", ConfigDebugErr << 21); + return 238; +} +// 23D4: using guessed type int DiagPrintf(const char *, ...); + +//----- (00001B48) -------------------------------------------------------- +HAL_Status HalSdioHostSetWriteProtectRtl8195a(IN VOID *Data, IN u8 Setting) { + int v2; // r3@1 + u8 *v3; // r4@1 + int v4; // r2@2 + uint8_t v5; // r2@5 + int v6; // r1@7 + unsigned int v7; // r2@7 + signed int v8; // r0@8 + u8 v9; // cf@11 + char v10; // r1@13 + int result; // r0@13 + char v12; // r3@15 + uint32_t v13; // r1@15 + signed int v14; // r2@16 + uint32_t v15; // r1@20 + char v16; // [sp+0h] [bp-30h]@15 + char v17; // [sp+1h] [bp-2Fh]@15 + HAL_Status ret; // [sp+4h] [bp-2Ch]@15 + uint8_t tmp[16]; // [sp+8h] [bp-28h]@3 + + v2 = *((u32 *) Data + 4); + v3 = Data; + if (!v2) + return 3; + v4 = *((u32 *) Data + 4) & 3; + if (v2 & 3) + return 3; + do { + tmp[v4] = *((u8 *) Data + v4 + 112); + ++v4; + } while (v4 != 15); + if (Setting == 1) + v5 = tmp[14] | 0x10; + else + v5 = tmp[14] & 0xEF; + v6 = 0; + tmp[14] = v5; + LOBYTE (v7) = 0; + do { + v8 = 7; + do { + v7 = (u8) (2 * v7); + if ((((signed int) tmp[v6] >> v8) & 1) != v7 >> 7) + LOBYTE (v7) = v7 ^ 0x89; + v9 = __CFADD__(v8--, -1); + } while (v9); + ++v6; + } while (v6 != 15); + tmp[15] = 2 * v7 | 1; + v40058058 = v2; + v40058004 = 16; + v4005800C = 1; + v10 = *(u8 *) v2; + *(u16 *) (v2 + 2) = 16; + *(u8 *) v2 = v10 & 0xC8 | 0x23; + *(u32 *) (v2 + 4) = tmp; + result = SdioHostChkCmdInhibitCMD(1u); + if (!result) { + result = SdioHostChkDataLineActive(0); + if (!result) { + v16 = (v16 & 0xF4 | 0x3A) & 0x3F; + v12 = v17; + v3[128] = 0; + v3[129] = 0; + ret = 0; + v17 = v12 & 0xC0 | 0x1B; + SdioHostSendCmd((SDIO_HOST_CMD *) &v16); + result = SdioHostChkCmdComplete(v3, v13); + if (!result) { + SdioHostGetResponse(v3, v16 & 3); + if (*((u32 *) v3 + 5) & 0x4000000) { + DBG_SDIO_ERR("Write protect violation!\n", + ConfigDebugErr << 21); + return 3; + } + result = SdioHostChkXferComplete(v3, 0x1388u, v14); + if (result) { + if (result != 16) { + if (v40058032 & 0x200) { + v40058032 = 512; + if (HalSdioHostStopTransferRtl8195a(v3, v15)) { + DBG_SDIO_ERR("Stop transmission error!\n"); + } + } + } + result = 238; + } + } + } + } + return result; +} + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.zip b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.zip new file mode 100644 index 0000000..b95cc5e Binary files /dev/null and b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_sdio_host.zip differ diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c new file mode 100644 index 0000000..f992d3d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c @@ -0,0 +1,1606 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" + +#ifdef CONFIG_SOC_PS_EN + +extern _LONG_CALL_ +HAL_Status HalSsiInitRtl8195a(VOID *Adaptor); + +//extern _LONG_CALL_ u32 HalGetCpuClk(VOID); + + +VOID _SsiReadInterruptRtl8195a(VOID *Adapter) +{ + SSI_DBG_ENTRANCE("_SsiReadInterrupt()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + u32 ReceiveLevel; + volatile u32 Readable = HalSsiReadableRtl8195a(Adapter); + u8 Index = pHalSsiAdapter->Index; + +// while (Readable) { + if (Readable) { + ReceiveLevel = HalSsiGetRxFifoLevelRtl8195a(Adapter); + + while (ReceiveLevel--) { + if (pHalSsiAdapter->RxData != NULL) { + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + *((u16*)(pHalSsiAdapter->RxData)) = (u16)(HAL_SSI_READ32(Index, REG_DW_SSI_DR)); + pHalSsiAdapter->RxData = (VOID*)(((u16*)pHalSsiAdapter->RxData) + 1); + } + else { + // 8~4 bits mode + *((u8*)(pHalSsiAdapter->RxData)) = (u8)(HAL_SSI_READ32(Index, REG_DW_SSI_DR)); + pHalSsiAdapter->RxData = (VOID*)(((u8*)pHalSsiAdapter->RxData) + 1); + } + } + else { + // for Master mode, doing TX also will got RX data, so drop the dummy data + HAL_SSI_READ32(Index, REG_DW_SSI_DR); + } + + if (pHalSsiAdapter->RxLength > 0) { + pHalSsiAdapter->RxLength--; + } +#if 0 + else if (pHalSsiAdapter->RxLengthRemainder > 0) { + pHalSsiAdapter->RxLengthRemainder--; + } + + // Fixed length receive Complete. (RxLength & RxLengthRemainder == 0) + if ((pHalSsiAdapter->RxLength == 0) && (pHalSsiAdapter->RxLengthRemainder == 0)) { + break; + } +#endif + if (pHalSsiAdapter->RxLength == 0) { + break; + } + } + +// if (pHalSsiAdapter->RxLength == 0) { +// break; +// } + + if (((pHalSsiAdapter->InterruptMask & BIT_IMR_TXEIM)!=0) && (pHalSsiAdapter->TxLength > 0)) { + _SsiWriteInterruptRtl8195a(pHalSsiAdapter); + } + +// Readable = HalSsiReadableRtl8195a(Adapter); + } + + if ((pHalSsiAdapter->RxLength > 0) && + (pHalSsiAdapter->RxLength < (pHalSsiAdapter->RxThresholdLevel+1))) { + SSI_DBG_INT_READ("Setting Rx FIFO Threshold Level to 1\n"); + pHalSsiAdapter->RxThresholdLevel = 0; + HalSsiSetRxFifoThresholdLevelRtl8195a((VOID*)pHalSsiAdapter); + } + + if (pHalSsiAdapter->RxLength == 0) { + DBG_SSI_INFO("_SsiReadInterruptRtl8195a: RX_Done\r\n"); + pHalSsiAdapter->InterruptMask &= ~(BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM); + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); +// if (pHalSsiAdapter->RxData != NULL) { + if (pHalSsiAdapter->RxCompCallback != NULL) { + pHalSsiAdapter->RxCompCallback(pHalSsiAdapter->RxCompCbPara); + } +// } + } + +} + + +VOID _SsiWriteInterruptRtl8195a(VOID *Adapter) +{ + SSI_DBG_ENTRANCE("_SsiWriteInterrupt()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + u32 Writeable = HalSsiWriteableRtl8195a(Adapter); +// u32 TxWriteMax = SSI_TX_FIFO_DEPTH - pHalSsiAdapter->TxThresholdLevel; + u32 TxWriteMax; + u8 Index = pHalSsiAdapter->Index; + u32 i; + volatile u32 bus_busy; + + if (pHalSsiAdapter->TxLength == 0) { + pHalSsiAdapter->InterruptMask &= ~(BIT_IMR_TXEIM); + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + for (i=0;i<1000000;i++) { + bus_busy = HAL_SSI_READ32(Index, REG_DW_SSI_SR) & BIT_SR_BUSY; + if (!bus_busy) { + break; // break the for loop + } + } + + // If it's not a dummy TX for master read SPI, then call the TX_done callback + if (pHalSsiAdapter->TxData != NULL) { + if (pHalSsiAdapter->TxIdleCallback != NULL) { + pHalSsiAdapter->TxIdleCallback(pHalSsiAdapter->TxIdleCbPara); + } + } + + return; + } + + if (Writeable) { + TxWriteMax = SSI_TX_FIFO_DEPTH - HalSsiGetTxFifoLevelRtl8195a(Adapter); + /* Disable Tx FIFO Empty IRQ */ + pHalSsiAdapter->InterruptMask &= ~ BIT_IMR_TXEIM; + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + //Clear RX FIFO first, to prevent RX Overflow + if ((pHalSsiAdapter->RxLength > 0) && (pHalSsiAdapter->TxData != NULL)) { + _SsiReadInterruptRtl8195a(pHalSsiAdapter); + } + + while (TxWriteMax--) { + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + if (pHalSsiAdapter->TxData != NULL) { + HAL_SSI_WRITE16(Index, REG_DW_SSI_DR, *((u16*)(pHalSsiAdapter->TxData))); + pHalSsiAdapter->TxData = (VOID*)(((u16*)pHalSsiAdapter->TxData) + 1); + } + else { + // For master mode: Push a dummy to TX FIFO for Read + if (pHalSsiAdapter->Role == SSI_MASTER) { + HAL_SSI_WRITE16(Index, REG_DW_SSI_DR, (u16)SSI_DUMMY_DATA); // Dummy byte + } + } + } + else { + // 8~4 bits mode + if (pHalSsiAdapter->TxData != NULL) { + HAL_SSI_WRITE8(Index, REG_DW_SSI_DR, *((u8*)(pHalSsiAdapter->TxData))); + pHalSsiAdapter->TxData = (VOID*)(((u8*)pHalSsiAdapter->TxData) + 1); + } + else { + // For master mode: Push a dummy to TX FIFO for Read + if (pHalSsiAdapter->Role == SSI_MASTER) { + HAL_SSI_WRITE8(Index, REG_DW_SSI_DR, (u8)SSI_DUMMY_DATA); // Dummy byte + } + } + } + + pHalSsiAdapter->TxLength--; + + if (pHalSsiAdapter->TxLength == 0) + break; + } + + /* Enable Tx FIFO Empty IRQ */ + pHalSsiAdapter->InterruptMask |= BIT_IMR_TXEIM; + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + } + + if (pHalSsiAdapter->TxLength == 0) { + DBG_SSI_INFO("_SsiWriteInterruptRtl8195a: TX_Done\r\n"); + HalSsiTxFIFOThresholdRtl8195a((VOID*)pHalSsiAdapter, 0); // trigger TX interrupt when TX FIFO is totally empty +// pHalSsiAdapter->InterruptMask &= ~(BIT_IMR_TXOIM | BIT_IMR_TXEIM); + pHalSsiAdapter->InterruptMask &= ~(BIT_IMR_TXOIM); + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + // If it's not a dummy TX for master read SPI, then call the TX_done callback + if (pHalSsiAdapter->TxData != NULL) { + if (pHalSsiAdapter->TxCompCallback != NULL) { + pHalSsiAdapter->TxCompCallback(pHalSsiAdapter->TxCompCbPara); + } + } + } +} + + +u32 _SsiIrqHandleRtl8195a(VOID *Adaptor) +{ + SSI_DBG_ENTRANCE("_SsiIrqHandle()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + u32 InterruptStatus = HalSsiGetInterruptStatusRtl8195a(Adaptor); + u8 Index = pHalSsiAdaptor->Index; + + if (InterruptStatus & BIT_ISR_TXOIS) { + DBG_SSI_ERR("[INT][SSI%d] Transmit FIFO Overflow Interrupt\n", Index); + HAL_SSI_READ32(Index, REG_DW_SSI_TXOICR); + } + + if (InterruptStatus & BIT_ISR_RXUIS) { + SSI_DBG_INT_HNDLR("[INT][SSI%d] Receive FIFO Underflow Interrupt\n", Index); + HAL_SSI_READ32(Index, REG_DW_SSI_RXUICR); + } + + if (InterruptStatus & BIT_ISR_RXOIS) { + DBG_SSI_ERR("[INT][SSI%d] Receive FIFO Overflow Interrupt\n", Index); + HAL_SSI_READ32(Index, REG_DW_SSI_RXOICR); + } + + if (InterruptStatus & BIT_ISR_MSTIS) { + SSI_DBG_INT_HNDLR("[INT][SSI%d] Multi-Master Contention Interrupt\n", Index); + /* Another master is actively transferring data */ + /* TODO: Do reading data... */ + HAL_SSI_READ32(Index, REG_DW_SSI_MSTICR); + } + + if ((InterruptStatus & BIT_ISR_RXFIS) ) { + SSI_DBG_INT_HNDLR("[INT][SSI%d] Receive FIFO Full Interrupt\n", Index); + _SsiReadInterruptRtl8195a(Adaptor); + } + + if ((InterruptStatus & BIT_ISR_TXEIS) || + (((pHalSsiAdaptor->InterruptMask & BIT_IMR_TXEIM)!=0) && (pHalSsiAdaptor->TxLength > 0))) { + /* Tx FIFO is empty, need to transfer data */ + SSI_DBG_INT_HNDLR("[INT][SSI%d] Transmit FIFO Empty Interrupt\n", Index); + _SsiWriteInterruptRtl8195a(Adaptor); + } + + return 0; +} + +HAL_Status HalSsiInitRtl8195a_Patch(VOID *Adaptor) +{ + SSI_DBG_ENTRANCE("HalSsiInitRtl8195a()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + volatile IRQn_Type IrqNum; + u32 IRQ_UNKNOWN = 999; + u32 Ctrlr0Value = 0; + u32 Ctrlr1Value = 0; + u32 SerValue = 0; + u32 BaudrValue = 0; + u32 TxftlrValue = 0; + u32 RxftlrValue = 0; + u32 MwcrValue = 0; + u8 MicrowireTransferMode = pHalSsiAdaptor->MicrowireTransferMode; + u8 DataFrameFormat = pHalSsiAdaptor->DataFrameFormat; + u8 TransferMode = pHalSsiAdaptor->TransferMode; + u8 Index = pHalSsiAdaptor->Index; + u8 Role = pHalSsiAdaptor->Role; + + if (Index > 2) { + DBG_SSI_ERR("HalSsiInitRtl8195a: Invalid SSI Idx %d\r\n", Index); + return HAL_ERR_PARA; + } + HalSsiPinmuxEnableRtl8195a_Patch(pHalSsiAdaptor); + HalSsiDisableRtl8195a(Adaptor); + + /* REG_DW_SSI_CTRLR0 */ + Ctrlr0Value |= BIT_CTRLR0_DFS(pHalSsiAdaptor->DataFrameSize); + Ctrlr0Value |= BIT_CTRLR0_FRF(pHalSsiAdaptor->DataFrameFormat); + Ctrlr0Value |= BIT_CTRLR0_SCPH(pHalSsiAdaptor->SclkPhase); + Ctrlr0Value |= BIT_CTRLR0_SCPOL(pHalSsiAdaptor->SclkPolarity); + Ctrlr0Value |= BIT_CTRLR0_TMOD(pHalSsiAdaptor->TransferMode); + Ctrlr0Value |= BIT_CTRLR0_CFS(pHalSsiAdaptor->ControlFrameSize); + + if (Role == SSI_SLAVE) + Ctrlr0Value |= BIT_CTRLR0_SLV_OE(pHalSsiAdaptor->SlaveOutputEnable); + + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_CTRLR0 Value: %X\n", Index, Ctrlr0Value); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_CTRLR0, Ctrlr0Value); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_CTRLR0(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_CTRLR0, + HAL_SSI_READ32(Index, REG_DW_SSI_CTRLR0)); + + /* REG_DW_SSI_TXFTLR */ + TxftlrValue = BIT_TXFTLR_TFT(pHalSsiAdaptor->TxThresholdLevel); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_TXFTLR Value: %X\n", Index, TxftlrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_TXFTLR, TxftlrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_TXFTLR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_TXFTLR, + HAL_SSI_READ32(Index, REG_DW_SSI_TXFTLR)); + + /* REG_DW_SSI_RXFTLR */ + RxftlrValue = BIT_RXFTLR_RFT(pHalSsiAdaptor->RxThresholdLevel); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_RXFTLR Value: %X\n", Index, RxftlrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_RXFTLR, RxftlrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_RXFTLR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_RXFTLR, + HAL_SSI_READ32(Index, REG_DW_SSI_RXFTLR)); + /** + * Master Only + * REG_DW_SSI_CTRLR1, REG_DW_SSI_SER, REG_DW_SSI_BAUDR + */ + if (Role & SSI_MASTER) { + if ((TransferMode == TMOD_RO) || (TransferMode == TMOD_EEPROM_R) || + ((DataFrameFormat == FRF_NS_MICROWIRE) && (MicrowireTransferMode == MW_TMOD_SEQUENTIAL))) { + Ctrlr1Value = BIT_CTRLR1_NDF(pHalSsiAdaptor->DataFrameNumber); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_CTRLR1 Value: %X\n", Index, Ctrlr1Value); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_CTRLR1, Ctrlr1Value); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_CTRLR1(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_CTRLR1, + HAL_SSI_READ32(Index, REG_DW_SSI_CTRLR1)); + } + + SerValue = BIT_SER_SER(1 << (pHalSsiAdaptor->SlaveSelectEnable)); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_SER Value: %X\n", Index, SerValue); + + //HAL_SSI_WRITE32(Index, REG_DW_SSI_SER, SerValue); + HalSsiSetSlaveEnableRegisterRtl8195a(Adaptor, pHalSsiAdaptor->SlaveSelectEnable); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_SER(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_SER, + HalSsiGetSlaveEnableRegisterRtl8195a(Adaptor)); + + BaudrValue = BIT_BAUDR_SCKDV(pHalSsiAdaptor->ClockDivider); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_BAUDR Value: %X\n", Index, BaudrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_BAUDR, BaudrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_BAUDR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_BAUDR, + HAL_SSI_READ32(Index, REG_DW_SSI_BAUDR)); + } + + // Microwire + MwcrValue |= BIT_MWCR_MWMOD(pHalSsiAdaptor->MicrowireTransferMode); + MwcrValue |= BIT_MWCR_MDD(pHalSsiAdaptor->MicrowireDirection); + MwcrValue |= BIT_MWCR_MHS(pHalSsiAdaptor->MicrowireHandshaking); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_MWCR Value: %X\n", Index, MwcrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_MWCR, MwcrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_MWCR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_MWCR, + HAL_SSI_READ32(Index, REG_DW_SSI_MWCR)); + + SSI_DBG_INIT("SSI%d TransferMechanism: %d\n", Index, pHalSsiAdaptor->TransferMechanism); + if (pHalSsiAdaptor->TransferMechanism == SSI_DTM_INTERRUPT) + { + SSI_DBG_INIT("SSI%d Interrupt initialize, Interrupt: %X\n", Index, pHalSsiAdaptor->InterruptMask); + switch (Index) { + case 0: + IrqNum = SPI0_IRQ; + break; + case 1: + IrqNum = SPI1_IRQ; + break; + case 2: + IrqNum = SPI2_IRQ; + break; + default: + IrqNum = IRQ_UNKNOWN; + break; + } + + if (likely(IrqNum != IRQ_UNKNOWN)) { + /* REG_DW_SSI_IMR */ + HalSsiSetInterruptMaskRtl8195a(Adaptor); + + pHalSsiAdaptor->IrqHandle.Data = (u32)pHalSsiAdaptor; + pHalSsiAdaptor->IrqHandle.IrqFun = (IRQ_FUN)_SsiIrqHandleRtl8195a; + pHalSsiAdaptor->IrqHandle.IrqNum = (IRQn_Type)IrqNum; + pHalSsiAdaptor->IrqHandle.Priority = pHalSsiAdaptor->InterruptPriority; + + InterruptRegister(&pHalSsiAdaptor->IrqHandle); + InterruptEn(&pHalSsiAdaptor->IrqHandle); + } + else { + SSI_DBG_INIT("Unknown SSI Index.\n"); + pHalSsiAdaptor->TransferMechanism = SSI_DTM_BASIC; + } + } + + HalSsiEnableRtl8195a(Adaptor); + + return HAL_OK; +} + +HAL_Status HalSsiPinmuxEnableRtl8195a_Patch(VOID *Adaptor) +{ + SSI_DBG_ENTRANCE("HalSsiPinmuxEnableRtl8195a()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + volatile HAL_Status Result; + u32 PinmuxSelect = pHalSsiAdaptor->PinmuxSelect; + u8 Index = pHalSsiAdaptor->Index; + + SSI_DBG_PINMUX("[1] SSI%d REG_SSI_MUX_CTRL(%X) = %X\n", Index, + PERI_ON_BASE + REG_SPI_MUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_SPI_MUX_CTRL)); + + switch (Index) + { + case 0: + { + ACTCK_SPI0_CCTRL(ON); + SLPCK_SPI0_CCTRL(ON); + PinCtrl(SPI0, PinmuxSelect, ON); + SPI0_FCTRL(ON); + Result = HAL_OK; + break; + } + case 1: + { + ACTCK_SPI1_CCTRL(ON); + SLPCK_SPI1_CCTRL(ON); + PinCtrl(SPI1, PinmuxSelect, ON); + SPI1_FCTRL(ON); + Result = HAL_OK; + break; + } + case 2: + { + ACTCK_SPI2_CCTRL(ON); + SLPCK_SPI2_CCTRL(ON); + PinCtrl(SPI2, PinmuxSelect, ON); + SPI2_FCTRL(ON); + Result = HAL_OK; + break; + } + default: + { + DBG_SSI_ERR("Invalid SSI Index %d!\n", Index); + Result = HAL_ERR_PARA; + break; + } + } + + SSI_DBG_PINMUX("[2] SSI%d REG_SSI_MUX_CTRL(%X) = %X\n", Index, + PERI_ON_BASE + REG_SPI_MUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_SPI_MUX_CTRL)); + + return Result; +} + +HAL_Status HalSsiPinmuxDisableRtl8195a(VOID *Adaptor) +{ + SSI_DBG_ENTRANCE("HalSsiPinmuxEnableRtl8195a()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + volatile HAL_Status Result; + u32 PinmuxSelect = pHalSsiAdaptor->PinmuxSelect; + u8 Index = pHalSsiAdaptor->Index; + + SSI_DBG_PINMUX("[1] SSI%d REG_SSI_MUX_CTRL(%X) = %X\n", Index, + PERI_ON_BASE + REG_SPI_MUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_SPI_MUX_CTRL)); + + switch (Index) + { + case 0: + { + ACTCK_SPI0_CCTRL(OFF); + SLPCK_SPI0_CCTRL(OFF); + PinCtrl(SPI0, PinmuxSelect, OFF); + SPI0_FCTRL(OFF); + Result = HAL_OK; + break; + } + case 1: + { + ACTCK_SPI1_CCTRL(OFF); + SLPCK_SPI1_CCTRL(OFF); + PinCtrl(SPI1, PinmuxSelect, OFF); + SPI1_FCTRL(OFF); + Result = HAL_OK; + break; + } + case 2: + { + ACTCK_SPI2_CCTRL(OFF); + SLPCK_SPI2_CCTRL(OFF); + PinCtrl(SPI2, PinmuxSelect, OFF); + SPI2_FCTRL(OFF); + Result = HAL_OK; + break; + } + default: + { + DBG_SSI_ERR("Invalid SSI Index %d!\n", Index); + Result = HAL_ERR_PARA; + break; + } + } + + SSI_DBG_PINMUX("[2] SSI%d REG_SSI_MUX_CTRL(%X) = %X\n", Index, + PERI_ON_BASE + REG_SPI_MUX_CTRL, + HAL_READ32(PERI_ON_BASE, REG_SPI_MUX_CTRL)); + + return Result; +} + +HAL_Status HalSsiDeInitRtl8195a(VOID *Adapter) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + u8 Index; + volatile HAL_Status Result; + + Index = pHalSsiAdapter->Index; + + if(Index > 2){ + DBG_SSI_ERR("Invalid SSI Index %d!\n", Index); + return HAL_ERR_PARA; + } + + HalSsiInterruptDisableRtl8195a(pHalSsiAdapter); + HalSsiDisableRtl8195a(pHalSsiAdapter); + + Result = HalSsiPinmuxDisableRtl8195a(pHalSsiAdapter); + if(Result != HAL_OK){ + DBG_SSI_ERR("Pinmux Disable Error\n"); + return Result; + } + + return Result; +} + +HAL_Status HalSsiClockOnRtl8195a(VOID *Adapter) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adapter; + volatile HAL_Status Result; + u8 Index = pHalSsiAdaptor->Index; + + switch (Index) + { + case 0: + { + ACTCK_SPI0_CCTRL(ON); + SLPCK_SPI0_CCTRL(ON); + Result = HAL_OK; + break; + } + case 1: + { + ACTCK_SPI1_CCTRL(ON); + SLPCK_SPI1_CCTRL(ON); + Result = HAL_OK; + break; + } + case 2: + { + ACTCK_SPI2_CCTRL(ON); + SLPCK_SPI2_CCTRL(ON); + Result = HAL_OK; + break; + } + default: + { + DBG_SSI_ERR("Invalid SSI Index %d!\n", Index); + Result = HAL_ERR_PARA; + break; + } + } + return Result; +} + +HAL_Status HalSsiClockOffRtl8195a(VOID *Adapter) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adapter; + volatile HAL_Status Result; + u8 Index = pHalSsiAdaptor->Index; + + switch (Index) + { + case 0: + { + ACTCK_SPI0_CCTRL(OFF); + SLPCK_SPI0_CCTRL(OFF); + Result = HAL_OK; + break; + } + case 1: + { + ACTCK_SPI1_CCTRL(OFF); + SLPCK_SPI1_CCTRL(OFF); + Result = HAL_OK; + break; + } + case 2: + { + ACTCK_SPI2_CCTRL(OFF); + SLPCK_SPI2_CCTRL(OFF); + Result = HAL_OK; + break; + } + default: + { + DBG_SSI_ERR("Invalid SSI Index %d!\n", Index); + Result = HAL_ERR_PARA; + break; + } + } + return Result; + +} + +HAL_Status HalSsiSetFormatRtl8195a(VOID *Adaptor) +{ + SSI_DBG_ENTRANCE("HalSsiSetFormatRtl8195a()\n"); + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + u32 Ctrlr0Value = 0; + u32 TxftlrValue = 0; + u32 RxftlrValue = 0; + u8 Index = pHalSsiAdaptor->Index; + u8 Role = pHalSsiAdaptor->Role; + u32 Spi_mode = 0; + + if (Index > 2) { + DBG_SSI_ERR("HalSsiSetFormatRtl8195a: Invalid SSI Idx %d\r\n", Index); + return HAL_ERR_PARA; + } + HalSsiDisableRtl8195a(Adaptor); + + Ctrlr0Value &= ~(BIT_CTRLR0_SCPH(1) | BIT_CTRLR0_SCPOL(1) | BIT_CTRLR0_DFS(0xF)); + + /* REG_DW_SSI_CTRLR0 */ + Ctrlr0Value |= BIT_CTRLR0_DFS(pHalSsiAdaptor->DataFrameSize); + Ctrlr0Value |= BIT_CTRLR0_SCPH(pHalSsiAdaptor->SclkPhase); + Ctrlr0Value |= BIT_CTRLR0_SCPOL(pHalSsiAdaptor->SclkPolarity); + + if (Role == SSI_SLAVE) + Ctrlr0Value |= BIT_CTRLR0_SLV_OE(pHalSsiAdaptor->SlaveOutputEnable); + + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_CTRLR0 Value: %X\n", Index, Ctrlr0Value); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_CTRLR0, Ctrlr0Value); + + Spi_mode = (HAL_SSI_READ32(Index, REG_DW_SSI_CTRLR0) >>6) & 0x3; + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_CTRLR0(%X) = %X, SPI Mode = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_CTRLR0, + HAL_SSI_READ32(Index, REG_DW_SSI_CTRLR0), Spi_mode); + //The tx threshold and rx threshold value will be reset after the spi changes its role + /* REG_DW_SSI_TXFTLR */ + TxftlrValue = BIT_TXFTLR_TFT(pHalSsiAdaptor->TxThresholdLevel); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_TXFTLR Value: %X\n", Index, TxftlrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_TXFTLR, TxftlrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_TXFTLR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_TXFTLR, + HAL_SSI_READ32(Index, REG_DW_SSI_TXFTLR)); + + /* REG_DW_SSI_RXFTLR */ + RxftlrValue = BIT_RXFTLR_RFT(pHalSsiAdaptor->RxThresholdLevel); + SSI_DBG_INIT("[1] Set SSI%d REG_DW_SSI_RXFTLR Value: %X\n", Index, RxftlrValue); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_RXFTLR, RxftlrValue); + + SSI_DBG_INIT("[2] SSI%d REG_DW_SSI_RXFTLR(%X) = %X\n", Index, + SSI0_REG_BASE + (SSI_REG_OFF * Index) + REG_DW_SSI_RXFTLR, + HAL_SSI_READ32(Index, REG_DW_SSI_RXFTLR)); + + HalSsiEnableRtl8195a(Adaptor); + + return HAL_OK; +} + +VOID HalSsiSetSclkRtl8195a(VOID *Adapter, u32 ClkRate) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + u32 ssi_clk; + u32 ClockDivider; + u32 SsiEn; + u32 RegValue; + u32 SystemClock; + u8 spi_idx = pHalSsiAdapter->Index; + + // Set SCLK Freq only available for Master mode + // For Slave mode, the baud rate is depends on the Master side, max rate = ssi_clk/2 + // Fsclk_out = Fssi_clk/SCKDV + SystemClock = HalGetCpuClk(); + + if (spi_idx == 1) { + ssi_clk = SystemClock >> 1; + RegValue = HAL_READ32(SYSTEM_CTRL_BASE, 0x250); + if (ClkRate > (ssi_clk/2)) { + // Use High speed clock: Fixed Freq. + RegValue |= BIT18; + ssi_clk = (200000000*5/6) >> 1; + } + else { + // Use Normal speed clock: CPU_Clk/2 + RegValue &= ~BIT18; + } + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x250, RegValue); + } + else { + ssi_clk = SystemClock >> 2; + } + + if (pHalSsiAdapter->Role == SSI_MASTER) { + if (ClkRate > (ssi_clk/2)) { + DBG_SSI_ERR("spi_frequency: Freq %d is too high, available highest Freq=%d\r\n", ClkRate, (ssi_clk/2)); + ClockDivider = 2; + } + else { + ClockDivider = ssi_clk/ClkRate + 1; + if ((ssi_clk%ClkRate) > (ClkRate/2)) { + ClockDivider++; + } + if (ClockDivider >= 0xFFFF) { + // devider is 16 bits + ClockDivider = 0xFFFE; + } + ClockDivider &= 0xFFFE; // bit 0 always is 0 + } + DBG_SSI_INFO("spi_frequency: Set SCLK Freq=%d\r\n", (ssi_clk/ClockDivider)); + pHalSsiAdapter->ClockDivider = ClockDivider; + + SsiEn = HAL_SSI_READ32(spi_idx, REG_DW_SSI_SSIENR); // Backup SSI_EN register + + // Disable SSI first, so we can modify the Clock Divider + RegValue = SsiEn & BIT_INVC_SSIENR_SSI_EN; + HAL_SSI_WRITE32(spi_idx, REG_DW_SSI_SSIENR, RegValue); + HAL_SSI_WRITE32(spi_idx, REG_DW_SSI_BAUDR, (pHalSsiAdapter->ClockDivider & 0xFFFF)); + // recover the SSI_EN setting + HAL_SSI_WRITE32(spi_idx, REG_DW_SSI_SSIENR, SsiEn); + } + else { + if (ClkRate > (ssi_clk/10)) { + DBG_SSI_ERR("spi_frequency: Freq %d is too high, available highest Freq=%d\r\n", ClkRate, (ssi_clk/10)); + } + } +} + +HAL_Status HalSsiIntReadRtl8195a(VOID *Adapter, VOID *RxData, u32 Length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + u32 RxFifoThresholdLevel; + u8 Index = pHalSsiAdapter->Index; + + DBG_SSI_INFO("HalSsiIntReadRtl8195a: Idx=%d, RxData=0x%x, Len=0x%x\r\n", Index, RxData, Length); +// if (HalSsiBusyRtl8195a(Adapter)) { + // As a Slave mode, if the peer(Master) side is power off, the BUSY flag is always on +// DBG_SSI_WARN("HalSsiIntReadRtl8195a: SSI%d is busy\n", Index); +// return HAL_BUSY; +// } + + if (Length == 0) { + SSI_DBG_INT_READ("SSI%d RxData addr: 0x%X, Length: %d\n", Index, RxData, Length); + return HAL_ERR_PARA; + } + + if (Length > (pHalSsiAdapter->DefaultRxThresholdLevel)) { + RxFifoThresholdLevel = pHalSsiAdapter->DefaultRxThresholdLevel; + } + else { + RxFifoThresholdLevel = 0; + } + + if (pHalSsiAdapter->RxThresholdLevel != RxFifoThresholdLevel) { + DBG_SSI_INFO("Setting Rx FIFO Threshold Level to %d\n", RxFifoThresholdLevel); + pHalSsiAdapter->RxThresholdLevel = RxFifoThresholdLevel; + HalSsiSetRxFifoThresholdLevelRtl8195a((VOID*)pHalSsiAdapter); + } + + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + pHalSsiAdapter->RxLength = Length >> 1; // 2 bytes(16 bit) every transfer + } + else { + // 8~4 bits mode + pHalSsiAdapter->RxLength = Length; // 1 byte(8 bit) every transfer + } + + pHalSsiAdapter->RxData = RxData; + DBG_SSI_INFO("SSI%d RxData addr: 0x%X, Length: %d\n", Index, + pHalSsiAdapter->RxData, pHalSsiAdapter->RxLength); + + pHalSsiAdapter->InterruptMask |= BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM; + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + + return HAL_OK; +} + +// Configure Transmit FIFO Threshold Level +VOID HalSsiTxFIFOThresholdRtl8195a(VOID *Adaptor, u32 txftl) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Adaptor; + u8 Index = pHalSsiAdaptor->Index; + u32 TxftlrValue; + + TxftlrValue = BIT_TXFTLR_TFT(txftl); + + HAL_SSI_WRITE32(Index, REG_DW_SSI_TXFTLR, TxftlrValue); +} + + +HAL_Status +HalSsiIntWriteRtl8195a( + IN VOID *Adapter, // PHAL_SSI_ADAPTOR + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + + DBG_SSI_INFO("HalSsiIntWriteRtl8195a: Idx=%d, RxData=0x%x, Len=0x%x\r\n", pHalSsiAdapter->Index, pTxData, Length); + if ((Length == 0)) { + DBG_SSI_ERR("HalSsiIntSendRtl8195a: Err: pTxData=0x%x, Length=%d\n", pTxData, Length); + return HAL_ERR_PARA; + } + + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + pHalSsiAdapter->TxLength = Length >> 1; // 2 bytes(16 bit) every transfer + } + else { + // 8~4 bits mode + pHalSsiAdapter->TxLength = Length; // 1 byte(8 bit) every transfer + } + + HalSsiTxFIFOThresholdRtl8195a(Adapter, pHalSsiAdapter->TxThresholdLevel); + pHalSsiAdapter->TxData = (void*)pTxData; + pHalSsiAdapter->InterruptMask |= BIT_IMR_TXOIM | BIT_IMR_TXEIM; + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + + return HAL_OK; +} + +HAL_Status HalSsiEnterCriticalRtl8195a(VOID *Data) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Data; + + InterruptDis(&pHalSsiAdaptor->IrqHandle); +#ifdef CONFIG_GDMA_EN + PSSI_DMA_CONFIG pDmaConfig = &pHalSsiAdaptor->DmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if(NULL != pDmaConfig){ + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + if(pHalGdmaAdapter->ChEn != 0){ + InterruptDis(&pDmaConfig->TxGdmaIrqHandle); + } + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + if(pHalGdmaAdapter->ChEn != 0){ + InterruptDis(&pDmaConfig->RxGdmaIrqHandle); + } + } +#endif + return HAL_OK; +} + +HAL_Status HalSsiExitCriticalRtl8195a(VOID *Data) +{ + PHAL_SSI_ADAPTOR pHalSsiAdaptor = (PHAL_SSI_ADAPTOR) Data; + + InterruptEn(&pHalSsiAdaptor->IrqHandle); +#ifdef CONFIG_GDMA_EN + PSSI_DMA_CONFIG pDmaConfig = &pHalSsiAdaptor->DmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if(NULL != pDmaConfig){ + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + if(pHalGdmaAdapter->ChEn != 0){ + InterruptEn(&pDmaConfig->TxGdmaIrqHandle); + } + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + if(pHalGdmaAdapter->ChEn != 0){ + InterruptEn(&pDmaConfig->RxGdmaIrqHandle); + } + } +#endif + return HAL_OK; +} + +HAL_Status +HalSsiIsTimeoutRtl8195a( + u32 StartCount, + u32 TimeoutCnt +) +{ + HAL_Status Status; + u32 CurrentCount, ExpireCount; + + CurrentCount = HalTimerOp.HalTimerReadCount(1); + + if (StartCount < CurrentCount) { + ExpireCount = (0xFFFFFFFF - CurrentCount) + StartCount; + } + else { + ExpireCount = StartCount - CurrentCount; + } + + if (TimeoutCnt < ExpireCount) { + Status = HAL_TIMEOUT; + } + else { + Status = HAL_OK; + } + + return Status; +} + +HAL_Status HalSsiStopRecvRtl8195a(VOID *Data) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; + PSSI_DMA_CONFIG pDmaConfig = &pHalSsiAdapter->DmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + u32 DMAStopAddr = 0; + u32 ReceivedCnt; + u8 Index; + u8 DmaMode = 0; + + Index = pHalSsiAdapter->Index; + pHalSsiAdapter->InterruptMask &= ~(BIT_IMR_RXFIM | BIT_IMR_RXOIM | BIT_IMR_RXUIM); + HalSsiSetInterruptMaskRtl8195a(pHalSsiAdapter); + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + + if(NULL != pHalGdmaAdapter){ + pHalGdmaOp = (PHAL_GDMA_OP)pDmaConfig->pHalGdmaOp; + if ((NULL != pHalGdmaOp) && (HalGdmaQueryChEnRtl8195a((VOID*)pHalGdmaAdapter))){ + DmaMode = 1; + pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChCleanAutoSrc((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + while((HAL_GDMAX_READ32(pHalGdmaAdapter->GdmaIndex, REG_GDMA_CH_EN) & (pHalGdmaAdapter->ChEn)) != 0 ){ + + } + DMAStopAddr = HalGdmaQueryDArRtl8195a((VOID*)pHalGdmaAdapter); + ReceivedCnt = DMAStopAddr - (u32)(pHalSsiAdapter->RxData); + pHalSsiAdapter->RxLength-= ReceivedCnt; + pHalSsiAdapter->RxData = (u8 *)(pHalSsiAdapter->RxData) + ReceivedCnt; + } + } + + while(HalSsiGetRxFifoLevelRtl8195a(pHalSsiAdapter) != 0){ + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + *((u16*)(pHalSsiAdapter->RxData)) = (u16)(HAL_SSI_READ32(Index, REG_DW_SSI_DR)); + pHalSsiAdapter->RxData = (VOID*)(((u16*)pHalSsiAdapter->RxData) + 1); + if(DmaMode){ + pHalSsiAdapter->RxLength--; + } + } + else { + // 8~4 bits mode + *((u8*)(pHalSsiAdapter->RxData)) = (u8)(HAL_SSI_READ32(Index, REG_DW_SSI_DR)); + pHalSsiAdapter->RxData = (VOID*)(((u8*)pHalSsiAdapter->RxData) + 1); + } + pHalSsiAdapter->RxLength--; + } + + return HAL_OK; + +} + +#ifdef CONFIG_GDMA_EN +/** + * GDMA IRQ Handler + */ +VOID SsiTxGdmaIrqHandle (VOID *Data) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; + PSSI_DMA_CONFIG pDmaConfig = &pHalSsiAdapter->DmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pDmaConfig->pHalGdmaOp; + /* Clear Pending ISR */ + pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + + pHalGdmaOp->HalGdmaChCleanAutoDst((VOID*)pHalGdmaAdapter); + + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + // Call user TX complete callback + pHalSsiAdapter->TxLength = 0; + HalSsiTxFIFOThresholdRtl8195a((VOID*)pHalSsiAdapter, 0); // trigger TX interrupt when TX FIFO is totally empty + pHalSsiAdapter->InterruptMask |= (BIT_IMR_TXEIM); + HalSsiSetInterruptMaskRtl8195a((VOID*)pHalSsiAdapter); + + if (NULL != pHalSsiAdapter->TxCompCallback) { + pHalSsiAdapter->TxCompCallback(pHalSsiAdapter->TxCompCbPara); + } + +#if 0 + /* Set SSI DMA Disable */ + HAL_SSI_WRITE32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR, \ + (HAL_SSI_READ32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR) & ~SSI_TXDMA_ENABLE)); +#endif + +} + +VOID SsiRxGdmaIrqHandle (VOID *Data) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; + PSSI_DMA_CONFIG pDmaConfig = &pHalSsiAdapter->DmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pDmaConfig->pHalGdmaOp; + + pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + + pHalGdmaOp->HalGdmaChCleanAutoSrc((VOID*)pHalGdmaAdapter); + + HAL_SSI_WRITE32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR, \ + (HAL_SSI_READ32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR) & ~SSI_RXDMA_ENABLE)); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + + if (NULL != pHalSsiAdapter->RxCompCallback) { + pHalSsiAdapter->RxCompCallback(pHalSsiAdapter->RxCompCbPara); + } + +} + +VOID +HalSsiTxGdmaLoadDefRtl8195a( + IN VOID *Adapter +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + u8 *pDst; + u8 DmaIdx; + u8 DmaCh; + u8 DstPer; + u8 ssi_idx; + u32 DmaChEn; + IRQn_Type IrqNum; + + if ((NULL == pHalSsiAdapter)) { + return; + } + pDmaConfig = &pHalSsiAdapter->DmaConfig; + + ssi_idx = pHalSsiAdapter->Index; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + if (NULL == pHalGdmaAdapter) { + DBG_SSI_ERR("HalSsiTxGdmaLoadDefRtl8195a: HalGdmaAdapter is NULL\r\n"); + return; + } + _memset((void *)pHalGdmaAdapter, 0, sizeof(HAL_GDMA_ADAPTER)); + + pHalSsiAdapter->DmaControl |= SSI_TXDMA_ENABLE; + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + pHalSsiAdapter->DmaTxDataLevel = 48; // When TX FIFO entity number <=48 then DMA Request asserted + } + else { + // 8~4 bits mode + pHalSsiAdapter->DmaTxDataLevel = 56; // When TX FIFO entity number <=56 then DMA Request asserted + } + + switch (ssi_idx) { + case 0: + pDst = (u8*) (SSI0_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 0; + DmaCh = 1; + DmaChEn = GdmaCh1; + IrqNum = GDMA0_CHANNEL1_IRQ; + DstPer = GDMA_HANDSHAKE_SSI0_TX; + break; + + case 1: + pDst = (u8*) (SSI1_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 1; + DmaCh = 1; + DmaChEn = GdmaCh1; + IrqNum = GDMA1_CHANNEL1_IRQ; + DstPer = GDMA_HANDSHAKE_SSI1_TX; + break; + + case 2: + pDst = (u8*) (SSI2_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 0; // SPI2 TX only can use GDMA0 + DmaCh = 3; + DmaChEn = GdmaCh3; + IrqNum = GDMA0_CHANNEL3_IRQ; + DstPer = GDMA_HANDSHAKE_SSI2_TX; + break; + + default: + return; + } + + pHalGdmaAdapter->GdmaCtl.TtFc = TTFCMemToPeri; + pHalGdmaAdapter->GdmaCtl.Done = 1; + pHalGdmaAdapter->GdmaCfg.ReloadDst = 1; + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->GdmaCfg.DestPer = DstPer; + pHalGdmaAdapter->ChDar = (u32)pDst; + pHalGdmaAdapter->GdmaIndex = DmaIdx; + pHalGdmaAdapter->ChNum = DmaCh; + pHalGdmaAdapter->ChEn = DmaChEn; + pHalGdmaAdapter->GdmaIsrType = (TransferType|ErrType); + pHalGdmaAdapter->IsrCtrl = ENABLE; + pHalGdmaAdapter->GdmaOnOff = ON; + + pHalGdmaAdapter->GdmaCtl.IntEn = 1; + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.Dinc = NoChange; + pHalGdmaAdapter->GdmaCtl.Sinc = IncType; + + pDmaConfig->TxGdmaIrqHandle.Data = (u32)pHalSsiAdapter; + pDmaConfig->TxGdmaIrqHandle.IrqNum = IrqNum; + pDmaConfig->TxGdmaIrqHandle.IrqFun = (IRQ_FUN)SsiTxGdmaIrqHandle; + pDmaConfig->TxGdmaIrqHandle.Priority = 10; +} + + +VOID +HalSsiRxGdmaLoadDefRtl8195a( + IN VOID *Adapter +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + u8 *pSrc; + u8 DmaIdx; + u8 DmaCh; + u8 SrcPer; + u8 ssi_idx; + u32 DmaChEn; + IRQn_Type IrqNum; + + if ((NULL == pHalSsiAdapter)) { + return; + } + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + + ssi_idx = pHalSsiAdapter->Index; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + if (NULL == pHalGdmaAdapter) { + return; + } + + _memset((void *)pHalGdmaAdapter, 0, sizeof(HAL_GDMA_ADAPTER)); + + pHalSsiAdapter->DmaControl |= SSI_RXDMA_ENABLE; + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + pHalSsiAdapter->DmaRxDataLevel = 7; // RX FIFO stored bytes > (DMARDLR(7) + 1) then request DMA transfer + } + else { + // 8~4 bits mode + pHalSsiAdapter->DmaRxDataLevel = 3; // RX FIFO stored bytes > (DMARDLR(3) + 1) then request DMA transfer + } + switch (ssi_idx) { + case 0: + pSrc = (u8*) (SSI0_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 0; + DmaCh = 2; + DmaChEn = GdmaCh2; + SrcPer = GDMA_HANDSHAKE_SSI0_RX; + IrqNum = GDMA0_CHANNEL2_IRQ; + break; + + case 1: + pSrc = (u8*) (SSI1_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 1; + DmaCh = 2; + DmaChEn = GdmaCh2; + SrcPer = GDMA_HANDSHAKE_SSI1_RX; + IrqNum = GDMA1_CHANNEL2_IRQ; + break; + + case 2: + pSrc = (u8*) (SSI2_REG_BASE + REG_DW_SSI_DR); + DmaIdx = 1; // SSI2 RX only can use GDMA1 + DmaCh = 3; + DmaChEn = GdmaCh3; + SrcPer = GDMA_HANDSHAKE_SSI2_RX; + IrqNum = GDMA1_CHANNEL3_IRQ; + break; + + default: + return; + } + + pHalGdmaAdapter->GdmaCtl.TtFc = TTFCPeriToMem; + pHalGdmaAdapter->GdmaCtl.Done = 1; + pHalGdmaAdapter->GdmaCfg.ReloadSrc = 1; + pHalGdmaAdapter->GdmaCfg.SrcPer = SrcPer; + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->ChSar = (u32)pSrc; + pHalGdmaAdapter->GdmaIndex = DmaIdx; + pHalGdmaAdapter->ChNum = DmaCh; + pHalGdmaAdapter->ChEn = DmaChEn; + pHalGdmaAdapter->GdmaIsrType = (TransferType|ErrType); + pHalGdmaAdapter->IsrCtrl = ENABLE; + pHalGdmaAdapter->GdmaOnOff = ON; + + pHalGdmaAdapter->GdmaCtl.IntEn = 1; + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthTwoBytes; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.Dinc = IncType; + pHalGdmaAdapter->GdmaCtl.Sinc = NoChange; + + pDmaConfig->RxGdmaIrqHandle.Data = (u32)pHalSsiAdapter; + pDmaConfig->RxGdmaIrqHandle.IrqNum = IrqNum; + pDmaConfig->RxGdmaIrqHandle.IrqFun = (IRQ_FUN)SsiRxGdmaIrqHandle; + pDmaConfig->RxGdmaIrqHandle.Priority = 11; +} + +VOID +HalSsiDmaInitRtl8195a( + IN VOID *Adapter +) +{ + u32 RegValue; + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pTxHalGdmaAdapter; + PHAL_GDMA_ADAPTER pRxHalGdmaAdapter; + u8 ssi_idx; + u32 hdk_tx_bit; + u32 hdk_rx_bit; + u32 DmatdlrValue = 0; + u32 DmardlrValue = 0; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pTxHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + pRxHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + ssi_idx = pHalSsiAdapter->Index; + + // Set REG_PESOC_SOC_CTRL[28:16] to configure the GDMA handshake connection + // SSI2 handshake connection is hardware fixed + if (ssi_idx != 2) { + hdk_tx_bit = 16+pTxHalGdmaAdapter->GdmaCfg.DestPer; + hdk_rx_bit = 16+pRxHalGdmaAdapter->GdmaCfg.SrcPer; + } + else { + hdk_tx_bit = 0; + hdk_rx_bit = 0; + } + + HalSsiDisableRtl8195a(pHalSsiAdapter); + + RegValue = HAL_READ32(PERI_ON_BASE, REG_PESOC_SOC_CTRL); + if (pHalSsiAdapter->DmaControl & SSI_TXDMA_ENABLE) { + // TX DMA is enabled + if (pTxHalGdmaAdapter->GdmaIndex ==0) { + ACTCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + if (hdk_tx_bit != 0) { + RegValue &= ~(1<DmaTxDataLevel); + HAL_SSI_WRITE32(ssi_idx, REG_DW_SSI_DMATDLR, DmatdlrValue); + + /* Set SSI DMA Enable */ + HAL_SSI_WRITE32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR, \ + (HAL_SSI_READ32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR) | SSI_TXDMA_ENABLE)); + } + + if (pHalSsiAdapter->DmaControl & SSI_RXDMA_ENABLE) { + // RX DMA is enabled + if (pRxHalGdmaAdapter->GdmaIndex ==0) { + ACTCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + if (hdk_rx_bit != 0) { + RegValue &= ~(1<DmaRxDataLevel); + HAL_SSI_WRITE32(ssi_idx, REG_DW_SSI_DMARDLR, DmardlrValue); + // the RX DMA will be enabled at read start. + } + + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_SOC_CTRL, RegValue); + + HalSsiEnableRtl8195a(pHalSsiAdapter); +} + +HAL_Status +HalSsiDmaSendRtl8195a( + IN VOID *Adapter, // PHAL_SSI_ADAPTOR + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + + if ((pTxData == NULL) || (Length == 0)) { + DBG_SSI_ERR("HalSsiDmaSendRtl8195a: Err: pTxData=0x%x, Length=%d\n", pTxData, Length); + return HAL_ERR_PARA; + } + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + + pHalSsiAdapter->TxLength = Length; + pHalSsiAdapter->TxData = (void*)pTxData; + + // Cofigure GDMA transfer + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + if (((Length & 0x03)==0) && + (((u32)(pTxData) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + //pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthTwoBytes; + //pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthTwoBytes; + //pHalGdmaAdapter->GdmaCtl.BlockSize = Length >> 2; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length >> 1; + } + else if (((Length & 0x01)==0) && + (((u32)(pTxData) & 0x01)==0)) { + // 2-bytes aligned, move 2 bytes each transfer + //pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthTwoBytes; + //pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthTwoBytes; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length >> 1; + } + else { + DBG_SSI_ERR("HalSsiDmaSendRtl8195a: Aligment Err: pTxData=0x%x, Length=%d\n", pTxData, Length); + return HAL_ERR_PARA; + } + } + else { + // 8~4 bits mode + if (((Length & 0x03)==0) && + (((u32)(pTxData) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length >> 2; + } + else { + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length; + } + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + } + + DBG_SSI_INFO("TX SrcMsize=%d SrcTrWidth=%d DestMsize=%d DstTrWidth=%d BlockSize=%d\n", \ + pHalGdmaAdapter->GdmaCtl.SrcMsize, pHalGdmaAdapter->GdmaCtl.SrcTrWidth, \ + pHalGdmaAdapter->GdmaCtl.DestMsize, pHalGdmaAdapter->GdmaCtl.DstTrWidth, \ + pHalGdmaAdapter->GdmaCtl.BlockSize); + +#if 0 + /* Set SSI DMA Enable */ + // TODO: protect the enable DMA register, it may collision with the DMA disable in the GDMA done ISR + HAL_SSI_WRITE32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR, \ + (HAL_SSI_READ32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR) | SSI_TXDMA_ENABLE)); +#endif + + return HAL_OK; +} + + +HAL_Status +HalSsiDmaSendMultiBlockRtl8195a(VOID *Adapter, u8 *pTxData, u32 Length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_MULTIBLK pSsiDmaMultiBlk; + + u32 BlockNumber = 1; + u32 SingleBlockBytes; + u32 BlockIndex = 0; + + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + pSsiDmaMultiBlk = (PSSI_DMA_MULTIBLK) &pHalSsiAdapter->DmaTxMultiBlk; + SingleBlockBytes = MAX_DMA_BLOCK_SIZE * (1 << (pHalGdmaAdapter->GdmaCtl.SrcTrWidth)) ; + + BlockNumber = Length / MAX_DMA_BLOCK_SIZE; + if(Length % MAX_DMA_BLOCK_SIZE) + BlockNumber++; + + if(BlockNumber > 16){ + DBG_SSI_ERR("HalSsiDmaSendMultiBlockRtl8195a: Data length is too long\n"); + return HAL_ERR_PARA; + } + DBG_SSI_INFO("TX BlockNumber = %x, Length = %x\n", BlockNumber, Length); + + + pHalGdmaAdapter->MaxMuliBlock = BlockNumber; + pHalGdmaAdapter->Rsvd4to7 = 1; + pHalGdmaAdapter->Llpctrl = 1; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 1; + + for(BlockIndex = 0; BlockIndex < BlockNumber; BlockIndex++){ + pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Sarx = (u32) (pTxData + SingleBlockBytes * BlockIndex); + pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Darx = (u32) (pHalGdmaAdapter->ChDar); + + //DBG_SSI_INFO("GdmaChLli[%x].Sarx = %x\n", BlockIndex, pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Sarx); + //DBG_SSI_INFO("GdmaChLli[%x] = %x\n", BlockIndex, &(pSsiDmaMultiBlk->GdmaChLli[BlockIndex])); + pSsiDmaMultiBlk->Lli[BlockIndex].pLliEle = (GDMA_CH_LLI_ELE*) &(pSsiDmaMultiBlk->GdmaChLli[BlockIndex]); + if(BlockIndex == BlockNumber - 1){ + pSsiDmaMultiBlk->Lli[BlockIndex].pNextLli = NULL; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].pNextBlockSiz = NULL; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize = Length - BlockIndex*MAX_DMA_BLOCK_SIZE; + } + else{ + pSsiDmaMultiBlk->Lli[BlockIndex].pNextLli = &(pSsiDmaMultiBlk->Lli[BlockIndex + 1]); + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize = MAX_DMA_BLOCK_SIZE; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].pNextBlockSiz = &(pSsiDmaMultiBlk->BlockSizeList[BlockIndex + 1]); + + } + //DBG_SSI_INFO("Lli[%x] = %x\n", BlockIndex, &(pSsiDmaMultiBlk->Lli[BlockIndex])); + //DBG_SSI_INFO("pSsiDmaMultiBlk->BlockSizeList[%x]= %x\n", BlockIndex, pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize); + } + + pHalGdmaAdapter->pBlockSizeList = (struct BLOCK_SIZE_LIST*) &(pSsiDmaMultiBlk->BlockSizeList); + pHalGdmaAdapter->pLlix = (struct GDMA_CH_LLI*) &(pSsiDmaMultiBlk->Lli); + + return HAL_OK; +} + +HAL_Status +HalSsiDmaRecvRtl8195a( + IN VOID *Adapter, // PHAL_SSI_ADAPTOR + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if ((pRxData == NULL) || (Length == 0)) { + DBG_SSI_ERR("HalSsiDmaRecvRtl8195a: Null Err: pRxData=0x%x, Length=%d\n", pRxData, Length); + return HAL_ERR_PARA; + } + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + + pHalSsiAdapter->RxLength = Length; + pHalSsiAdapter->RxData = (void*)pRxData; + + // Cofigure GDMA transfer + if ((pHalSsiAdapter->DataFrameSize+1) > 8) { + // 16~9 bits mode + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthTwoBytes; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length >> 1; + + if (((Length & 0x03)==0) && + (((u32)(pRxData) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + } + else if (((Length & 0x01)==0) && + (((u32)(pRxData) & 0x01)==0)) { + // 2-bytes aligned, move 2 bytes each transfer + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthTwoBytes; + } + else { + DBG_SSI_ERR("HalSsiDmaRecvRtl8195a: Aligment Err: pTxData=0x%x, Length=%d\n", pRxData, Length); + return HAL_ERR_PARA; + } + } + else { + // 8~4 bits mode + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.BlockSize = Length; + if (((Length & 0x03)==0) && + (((u32)(pRxData) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + } + else { + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + } + } + + DBG_SSI_INFO("RX SrcMsize=%d SrcTrWidth=%d DestMsize=%d DstTrWidth=%d BlockSize=%d\n", \ + pHalGdmaAdapter->GdmaCtl.SrcMsize, pHalGdmaAdapter->GdmaCtl.SrcTrWidth, \ + pHalGdmaAdapter->GdmaCtl.DestMsize, pHalGdmaAdapter->GdmaCtl.DstTrWidth, \ + pHalGdmaAdapter->GdmaCtl.BlockSize); + + /* Set SSI DMA Enable */ + // TODO: protect the enable DMA register, it may collision with the DMA disable in the GDMA TX done ISR + HAL_SSI_WRITE32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR, \ + (HAL_SSI_READ32(pHalSsiAdapter->Index, REG_DW_SSI_DMACR) | SSI_RXDMA_ENABLE)); + + return HAL_OK; +} + +HAL_Status +HalSsiDmaRecvMultiBlockRtl8195a(VOID *Adapter, u8 *pRxData, u32 Length) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_MULTIBLK pSsiDmaMultiBlk; + + + u32 BlockNumber = 1; + u32 SingleBlockBytes; + u32 BlockIndex = 0; + + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + pSsiDmaMultiBlk = (PSSI_DMA_MULTIBLK) &pHalSsiAdapter->DmaRxMultiBlk; + SingleBlockBytes = MAX_DMA_BLOCK_SIZE * (1 << (pHalGdmaAdapter->GdmaCtl.SrcTrWidth)) ; + + BlockNumber = Length / MAX_DMA_BLOCK_SIZE; + if(Length % MAX_DMA_BLOCK_SIZE) + BlockNumber++; + + if(BlockNumber > 16){ + DBG_SSI_ERR("HalSsiDmaRecvMultiBlockRtl8195a: Data length is too long\n"); + return HAL_ERR_PARA; + } + DBG_SSI_INFO("RX BlockNumber = %x, Length = %x\n", BlockNumber, Length); + + + pHalGdmaAdapter->MaxMuliBlock = BlockNumber; + pHalGdmaAdapter->Rsvd4to7 = 1; + pHalGdmaAdapter->Llpctrl = 1; + pHalGdmaAdapter->GdmaCtl.LlpDstEn = 1; + + for(BlockIndex = 0; BlockIndex < BlockNumber; BlockIndex++){ + pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Sarx = (u32) (pHalGdmaAdapter->ChSar); + pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Darx = (u32) (pRxData + SingleBlockBytes * BlockIndex); + + //DBG_SSI_INFO("GdmaChLli[%x].Darx = %x\n", BlockIndex, pSsiDmaMultiBlk->GdmaChLli[BlockIndex].Darx); + //DBG_SSI_INFO("GdmaChLli[%x] = %x\n", BlockIndex, &(pSsiDmaMultiBlk->GdmaChLli[BlockIndex])); + pSsiDmaMultiBlk->Lli[BlockIndex].pLliEle = (GDMA_CH_LLI_ELE*) &(pSsiDmaMultiBlk->GdmaChLli[BlockIndex]); + if(BlockIndex == BlockNumber - 1){ + pSsiDmaMultiBlk->Lli[BlockIndex].pNextLli = NULL; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].pNextBlockSiz = NULL; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize = Length - BlockIndex*MAX_DMA_BLOCK_SIZE; + } + else{ + pSsiDmaMultiBlk->Lli[BlockIndex].pNextLli = &(pSsiDmaMultiBlk->Lli[BlockIndex + 1]); + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize = MAX_DMA_BLOCK_SIZE; + pSsiDmaMultiBlk->BlockSizeList[BlockIndex].pNextBlockSiz = &(pSsiDmaMultiBlk->BlockSizeList[BlockIndex + 1]); + + } + //DBG_SSI_INFO("Lli[%x] = %x\n", BlockIndex, &(pSsiDmaMultiBlk->Lli[BlockIndex])); + //DBG_SSI_INFO("pSsiDmaMultiBlk->BlockSizeList[%x]= %x\n", BlockIndex, pSsiDmaMultiBlk->BlockSizeList[BlockIndex].BlockSize); + } + + pHalGdmaAdapter->pBlockSizeList = (struct BLOCK_SIZE_LIST*) &(pSsiDmaMultiBlk->BlockSizeList); + pHalGdmaAdapter->pLlix = (struct GDMA_CH_LLI*) &(pSsiDmaMultiBlk->Lli); + + return HAL_OK; +} + +#endif // end of "#ifdef CONFIG_GDMA_EN" + +#endif // CONFIG_SOC_PS_EN + diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_timer.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_timer.c new file mode 100644 index 0000000..581c4c4 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_timer.c @@ -0,0 +1,342 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "rtl8195a.h" +#include "rtl8195a_timer.h" + +#ifdef CONFIG_TIMER_EN +extern u32 gTimerRecord; +extern IRQ_FUN Timer2To7VectorTable[MAX_TIMER_VECTOR_TABLE_NUM]; + +#ifdef CONFIG_CHIP_A_CUT +HAL_RAM_BSS_SECTION u32 gTimerRecord; +#endif + +#if defined(CONFIG_CHIP_C_CUT) || defined(CONFIG_CHIP_E_CUT) +extern u32 Timer2To7HandlerData[MAX_TIMER_VECTOR_TABLE_NUM]; +#else +u32 Timer2To7HandlerData[MAX_TIMER_VECTOR_TABLE_NUM]; +#endif + +VOID +HalTimerIrq2To7Handle_Patch( + IN VOID *Data +) +{ + u32 TimerIrqStatus = 0, CheckIndex; + IRQ_FUN pHandler; + + TimerIrqStatus = HAL_TIMER_READ32(TIMERS_INT_STATUS_OFF); + + DBG_TIMER_INFO("%s:TimerIrqStatus: 0x%x\n",__FUNCTION__, TimerIrqStatus); + + for (CheckIndex = 2; CheckIndex<8; CheckIndex++) { + + //3 Check IRQ status bit and Timer X IRQ enable bit + if ((TimerIrqStatus & BIT_(CheckIndex)) && + (HAL_TIMER_READ32(TIMER_INTERVAL*CheckIndex + TIMER_CTL_REG_OFF) & BIT0)) { + //3 Execute Timer callback function + pHandler = Timer2To7VectorTable[CheckIndex-2]; + if (pHandler != NULL) { + pHandler((void*)Timer2To7HandlerData[CheckIndex-2]); + } + //3 Clear Timer ISR + HAL_TIMER_READ32(TIMER_INTERVAL*CheckIndex + TIMER_EOI_OFF); + } + } +} + +HAL_Status +HalTimerIrqRegisterRtl8195a_Patch( + IN VOID *Data +) +{ + PTIMER_ADAPTER pHalTimerAdap = (PTIMER_ADAPTER) Data; + IRQ_HANDLE TimerIrqHandle; + //IRQ_FUN BackUpIrqFun = NULL; + + if (pHalTimerAdap->TimerId > 7) { + DBG_TIMER_ERR("%s: No Support Timer ID %d!\r\n", __FUNCTION__, pHalTimerAdap->TimerId); + return HAL_ERR_PARA; + } + else { + if (pHalTimerAdap->TimerId > 1) { + + TimerIrqHandle.IrqNum = TIMER2_7_IRQ; + TimerIrqHandle.IrqFun = (IRQ_FUN) HalTimerIrq2To7Handle_Patch; + + Timer2To7VectorTable[pHalTimerAdap->TimerId-2] = + (IRQ_FUN) pHalTimerAdap->IrqHandle.IrqFun; + Timer2To7HandlerData[pHalTimerAdap->TimerId-2] = + (uint32_t) pHalTimerAdap->IrqHandle.Data; + } + else { + TimerIrqHandle.IrqNum = (pHalTimerAdap->TimerId ? TIMER1_IRQ : TIMER0_IRQ); + TimerIrqHandle.IrqFun = (IRQ_FUN) pHalTimerAdap->IrqHandle.IrqFun; + } + TimerIrqHandle.Data = (u32)pHalTimerAdap; + InterruptRegister(&TimerIrqHandle); + } + + return HAL_OK; +} + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) +// Patch for A/B Cut +HAL_Status +HalTimerInitRtl8195a_Patch( + IN VOID *Data +) +{ + PTIMER_ADAPTER pHalTimerAdap = (PTIMER_ADAPTER) Data; + HAL_Status ret=HAL_OK; + u32 ControlReg; + + if ((gTimerRecord & (1<TimerId)) != 0) { + DBG_TIMER_ERR ("%s:Error! Timer %d is occupied!\r\n", __FUNCTION__, pHalTimerAdap->TimerId); + return HAL_BUSY; + } + + //4 1) Config Timer Setting + ControlReg = ((u32)pHalTimerAdap->TimerMode<<1)|((u32)pHalTimerAdap->IrqDis<<2); + /* + set TimerControlReg + 0: Timer enable (0,disable; 1,enable) + 1: Timer Mode (0, free-running mode; 1, user-defined count mode) + 2: Timer Interrupt Mask (0, not masked; 1,masked) + */ + HAL_TIMER_WRITE32((TIMER_INTERVAL*pHalTimerAdap->TimerId + TIMER_CTL_REG_OFF), + ControlReg); + + if (pHalTimerAdap->TimerMode) { + //User-defined Mode + HalTimerReLoadRtl8195a_Patch(pHalTimerAdap->TimerId ,pHalTimerAdap->TimerLoadValueUs); + } + else { + // set TimerLoadCount Register + HAL_TIMER_WRITE32((TIMER_INTERVAL*pHalTimerAdap->TimerId + TIMER_LOAD_COUNT_OFF), + 0xFFFFFFFF); + } + + //4 2) Setting Timer IRQ + if (!pHalTimerAdap->IrqDis) { + if (pHalTimerAdap->IrqHandle.IrqFun != NULL) { + //4 2.1) Initial TimerIRQHandle + ret = HalTimerIrqRegisterRtl8195a_Patch(pHalTimerAdap); + if (HAL_OK != ret) { + DBG_TIMER_ERR ("%s: Timer %d Register IRQ Err!\r\n", __FUNCTION__, pHalTimerAdap->TimerId); + return ret; + } + //4 2.2) Enable TimerIRQ for Platform + InterruptEn((PIRQ_HANDLE)&pHalTimerAdap->IrqHandle); + } + else { + DBG_TIMER_ERR ("%s: Timer %d ISR Handler is NULL!\r\n", __FUNCTION__, pHalTimerAdap->TimerId); + return HAL_ERR_PARA; + } + } + + //4 4) Enable Timer +// HAL_TIMER_WRITE32((TIMER_INTERVAL*pHalTimerAdap->TimerId + TIMER_CTL_REG_OFF), +// (ControlReg|0x1)); + + gTimerRecord |= (1<TimerId); + + return ret; +} + +#elif defined(CONFIG_CHIP_C_CUT) +// Patch for C Cut +HAL_Status +HalTimerInitRtl8195a_Patch( + IN VOID *Data +) +{ + PTIMER_ADAPTER pHalTimerAdap = (PTIMER_ADAPTER) Data; + HAL_Status ret=HAL_OK; + + ret = HalTimerInitRtl8195aV02(Data); + + // Patch the Rom code to load the correct count value + if (pHalTimerAdap->TimerMode) { + //User-defined Mode + HalTimerReLoadRtl8195a_Patch(pHalTimerAdap->TimerId ,pHalTimerAdap->TimerLoadValueUs); + } + + return ret; +} +#endif + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +HAL_Status +HalTimerIrqUnRegisterRtl8195a_Patch( + IN VOID *Data +) +{ + PTIMER_ADAPTER pHalTimerAdap = (PTIMER_ADAPTER) Data; + PIRQ_HANDLE pTimerIrqHandle; + u32 i; + + pTimerIrqHandle = &pHalTimerAdap->IrqHandle; + + if (pHalTimerAdap->TimerId > 7) { + DBG_TIMER_ERR("%s:Error: No Support Timer ID!\n", __FUNCTION__); + return HAL_ERR_PARA; + } + else { + if (pHalTimerAdap->TimerId > 1) { + pTimerIrqHandle->IrqNum = TIMER2_7_IRQ; + Timer2To7VectorTable[pHalTimerAdap->TimerId-2] = NULL; + for (i=0;iIrqHandle); + InterruptUnRegister(pTimerIrqHandle); + } + } + else { + pTimerIrqHandle->IrqNum = (pHalTimerAdap->TimerId ? TIMER1_IRQ : TIMER0_IRQ); + InterruptUnRegister(pTimerIrqHandle); + } + + } + + return HAL_OK; +} + + +VOID +HalTimerDeInitRtl8195a_Patch( + IN VOID *Data +) +{ + PTIMER_ADAPTER pHalTimerAdap = (PTIMER_ADAPTER) Data; + u32 timer_id; + + timer_id = pHalTimerAdap->TimerId; + HalTimerDisRtl8195a (timer_id); + if (!pHalTimerAdap->IrqDis) { + if (pHalTimerAdap->IrqHandle.IrqFun != NULL) { + HalTimerIrqUnRegisterRtl8195a_Patch(pHalTimerAdap); + } + } + + gTimerRecord &= ~(1<TimerId); +} + +u32 +HalTimerReadCountRtl8195a_Patch( + IN u32 TimerId +) +{ + u32 TimerCountOld; + u32 TimerCountNew; + u32 TimerRDCnt; + + TimerRDCnt = 0; + TimerCountOld = HAL_TIMER_READ32(TimerId*TIMER_INTERVAL + TIMER_CURRENT_VAL_OFF); + while(1) { + TimerCountNew = HAL_TIMER_READ32(TimerId*TIMER_INTERVAL + TIMER_CURRENT_VAL_OFF); + + if (TimerCountOld == TimerCountNew) { + return (u32)TimerCountOld; + } + else { + TimerRDCnt++; + TimerCountOld = TimerCountNew; + + if (TimerRDCnt >= 2){ + return (u32)TimerCountOld; + } + } + } +} + + +#endif // #if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + +VOID +HalTimerReLoadRtl8195a_Patch( + IN u32 TimerId, + IN u32 LoadUs +) +{ + u32 LoadCount = 0; + u32 ms125; // how many 125ms + u32 remain_us; + + ms125 = LoadUs/125000; + remain_us = LoadUs - (ms125*125000); + LoadCount = ms125 * (GTIMER_CLK_HZ/8); + LoadCount += (remain_us*GTIMER_CLK_HZ)/1000000; + if (LoadCount == 0) { + LoadCount = 1; + } + +// DBG_TIMER_INFO("%s: Load Count=0x%x\r\n", __FUNCTION__, LoadCount); + // set TimerLoadCount Register + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_LOAD_COUNT_OFF), + LoadCount); +} + +#endif // #if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + +VOID +HalTimerIrqEnRtl8195a( + IN u32 TimerId +) +{ + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF), + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) & (~(BIT2))); +} + +VOID +HalTimerIrqDisRtl8195a( + IN u32 TimerId +) +{ + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF), + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) | (BIT2)); +} + +VOID +HalTimerClearIsrRtl8195a( + IN u32 TimerId +) +{ + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_EOI_OFF); +} + +VOID +HalTimerEnRtl8195a_Patch( + IN u32 TimerId +) +{ + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF), + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) | (BIT0)); +} + +VOID +HalTimerDisRtl8195a_Patch( + IN u32 TimerId +) +{ + // Disable Timer will alos disable the IRQ, so need to re-enable the IRQ when re-enable the timer + HAL_TIMER_WRITE32((TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF), + HAL_TIMER_READ32(TIMER_INTERVAL*TimerId + TIMER_CTL_REG_OFF) & (~BIT0)); +} + +#endif // CONFIG_TIMER_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_uart.c b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_uart.c new file mode 100644 index 0000000..bb014c6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_uart.c @@ -0,0 +1,1479 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_uart.h" +#include "hal_uart.h" +#include "hal_gdma.h" + +u8 +HalRuartGetChipVerRtl8195a(VOID) +{ + u8 chip_ver; + + chip_ver = (HAL_READ32(SYSTEM_CTRL_BASE, 0x01F0) >> 4) & 0x0f; + return chip_ver; +} + +/** + * Reset RUART Tx FIFO. + * + * Reset RUART Receiver and Rx FIFO wrapper function. + * It will check LINE_STATUS_REG until reset action completion. + * + * @return BOOL + */ +HAL_Status +HalRuartResetTxFifoRtl8195a( + IN VOID *Data ///< RUART Adapter +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex = pHalRuartAdapter->UartIndex; + u32 rx_trigger_lv; + volatile u32 RegValue; + u32 timeout; + + // Backup the RX FIFO trigger Level setting + rx_trigger_lv = HAL_RUART_READ32(UartIndex, RUART_FIFO_CTL_REG_OFF); + rx_trigger_lv &= 0xC0; // only keep the bit[7:6] + + /* Step 2: Enable clear_txfifo */ + RegValue = (FIFO_CTL_DEFAULT_WITH_FIFO_DMA | RUART_FIFO_CTL_REG_CLEAR_TXFIFO) & (~0xC0); + RegValue |= rx_trigger_lv; + HAL_RUART_WRITE32(UartIndex, RUART_FIFO_CTL_REG_OFF, RegValue); + + // Wait TSR empty + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_STATUS_REG_OFF); + timeout = 100; // wait 10 ms + while (((RegValue & RUART_LINE_STATUS_REG_TEMT)==0) && (timeout > 0)) { + HalDelayUs(100); + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_STATUS_REG_OFF); + timeout--; + } + + return HAL_OK; +} + +// Reset RX FIFO +HAL_Status +HalRuartResetRxFifoRtl8195a_Patch( + IN VOID *Data ///< RUART Adapter +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex; + volatile u32 RegValue; + u32 rx_trigger_lv; + + UartIndex = pHalRuartAdapter->UartIndex; + + /* Step 1: Enable Reset_rcv */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_STS_REG_OFF); + RegValue |= RUART_STS_REG_RESET_RCV; + HAL_RUART_WRITE32(UartIndex, RUART_STS_REG_OFF, RegValue); + + // Backup the RX FIFO trigger Level setting + rx_trigger_lv = HAL_RUART_READ32(UartIndex, RUART_FIFO_CTL_REG_OFF); + rx_trigger_lv &= 0xC0; // only keep the bit[7:6] + + /* Step 2: Enable clear_rxfifo */ + RegValue = (FIFO_CTL_DEFAULT_WITH_FIFO_DMA | RUART_FIFO_CTL_REG_CLEAR_RXFIFO) & (~0xC0); + RegValue |= rx_trigger_lv; + HAL_RUART_WRITE32(UartIndex, RUART_FIFO_CTL_REG_OFF, RegValue); + + /* Step 3: Disable Reset_rcv */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_STS_REG_OFF); + RegValue &= ~(RUART_STS_REG_RESET_RCV); + HAL_RUART_WRITE32(UartIndex, RUART_STS_REG_OFF, RegValue); + + return HAL_OK; +} + +// Reset both TX and RX FIFO +HAL_Status +HalRuartResetTRxFifoRtl8195a( + IN VOID *Data ///< RUART Adapter +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex; + volatile u32 RegValue; + u32 timeout; + u32 rx_trigger_lv; + + UartIndex = pHalRuartAdapter->UartIndex; + + /* Step 1: Enable Reset_rcv */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_STS_REG_OFF); + RegValue |= RUART_STS_REG_RESET_RCV; + HAL_RUART_WRITE32(UartIndex, RUART_STS_REG_OFF, RegValue); + + // Backup the RX FIFO trigger Level setting + rx_trigger_lv = HAL_RUART_READ32(UartIndex, RUART_FIFO_CTL_REG_OFF); + rx_trigger_lv &= 0xC0; // only keep the bit[7:6] + + /* Step 2: Enable clear_txfifo & clear_rxfifo */ + RegValue = (FIFO_CTL_DEFAULT_WITH_FIFO_DMA | RUART_FIFO_CTL_REG_CLEAR_TXFIFO | RUART_FIFO_CTL_REG_CLEAR_RXFIFO) & (~0xC0); + RegValue |= rx_trigger_lv; + HAL_RUART_WRITE32(UartIndex, RUART_FIFO_CTL_REG_OFF, RegValue); + + // Wait THR & TSR empty + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_STATUS_REG_OFF); + timeout = 100; // wait 10 ms + while (((RegValue & RUART_LINE_STATUS_REG_TEMT)==0) && (timeout > 0)) { + HalDelayUs(100); + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_STATUS_REG_OFF); + timeout--; + } + + /* Step 3: Disable Reset_rcv */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_STS_REG_OFF); + RegValue &= ~(RUART_STS_REG_RESET_RCV); + HAL_RUART_WRITE32(UartIndex, RUART_STS_REG_OFF, RegValue); + + return HAL_OK; +} + +HAL_Status +HalRuartGenBaudRateRtl8195a( + IN RUART_SPEED_SETTING *pBaudSetting +) +{ + u32 baud_rate; + u32 min_divisor=0; + u32 min_err=0xffffffff; + u32 uart_ovsr; + u32 uart_ovsr_mod; + u32 min_uart_ovsr; // ovsr with mini err + u32 min_uart_ovsr_mod; + u64 uart_clock; + u32 divisor_temp; + u32 max_jitter_temp; + u32 err_temp; + u32 uart_ovsr_target; + u32 uart_ovsrs_actual; + u32 ovsr_adj; + u32 adj_bits; + u32 div_res; + u32 uart_ovsrs_actual_mod; + + baud_rate = pBaudSetting->BaudRate; + if (baud_rate >= 1000000) { + baud_rate /= 100; + uart_clock = (u64)pBaudSetting->sclk; + } else { + baud_rate /= 2; + uart_clock = (u64)pBaudSetting->sclk * 50; // UART clock is 1/2 CPU clock + } + + div_res = pBaudSetting->divisor_resolution; + while ((min_err > pBaudSetting->max_err) && (div_res > 0)) { + uart_ovsr = pBaudSetting->Ovsr_max; + while(uart_ovsr >= pBaudSetting->Ovsr_min) { +// divisor_temp = (uart_clock/baud_rate)/uart_ovsr; + divisor_temp = div_u64(div_u64(uart_clock, baud_rate), uart_ovsr); + max_jitter_temp = 0; + if (divisor_temp > 0) { + max_jitter_temp = 100000/uart_ovsr; + if (max_jitter_temp >= pBaudSetting->jitter_lim) { + err_temp = 100; + } else { +// err_temp = (uart_clock/divisor_temp)/((uart_ovsr/100)*100); + err_temp = div_u64(div_u64(uart_clock, divisor_temp), (uart_ovsr/100)*100); + if (err_temp > baud_rate) { + err_temp = (err_temp - baud_rate)*1000 / baud_rate; + } else { + err_temp = (baud_rate - err_temp)*1000 / baud_rate; + } + + if (err_temp < min_err) { + min_err = err_temp; + min_divisor = divisor_temp; + min_uart_ovsr = uart_ovsr/100; + min_uart_ovsr_mod = uart_ovsr%100; + } else if (err_temp == min_err) { + uart_ovsr_mod = uart_ovsr%100; + // we perfer OVSR bigger and adj bits smaller + if (((uart_ovsr/100) >= min_uart_ovsr) && (uart_ovsr_mod < min_uart_ovsr_mod)) { + min_err = err_temp; + min_divisor = divisor_temp; + min_uart_ovsr = uart_ovsr/100; + min_uart_ovsr_mod = uart_ovsr_mod; + } + } + } + } + uart_ovsr -= div_res; + } + div_res = div_res >> 1; + } + + if (min_divisor == 0) { + min_divisor = 1; + } +// uart_ovsr_target = (uart_clock/baud_rate)/min_divisor; + uart_ovsr_target = div_u64(div_u64(uart_clock,baud_rate), min_divisor); + + ovsr_adj = 0; + adj_bits = 0; + uart_ovsrs_actual = uart_ovsr_target/100; + uart_ovsrs_actual_mod = uart_ovsr_target%100; + if (uart_ovsrs_actual_mod > 0) { + adj_bits = (uart_ovsrs_actual_mod*pBaudSetting->Ovsr_adj_max_bits)/100; + if ((uart_ovsrs_actual_mod - ((adj_bits*100)/pBaudSetting->Ovsr_adj_max_bits)) > 4) { + adj_bits++; + } + + if (adj_bits > (pBaudSetting->Ovsr_adj_max_bits-1)) { + DBG_UART_WARN("HalRuartGenBaudRateRtl8195a: adj_bits=%d\r\n", adj_bits); + adj_bits = pBaudSetting->Ovsr_adj_max_bits-1; + } + } + ovsr_adj = pBaudSetting->Ovsr_adj_map[adj_bits]; +// DBG_8195A("baud_rate=%d uart_clock=%d uart_ovsr_target=%d min_divisor=%d adj_bits=%d\r\n", baud_rate, uart_clock, uart_ovsr_target, min_divisor, adj_bits); + + pBaudSetting->Ovsr = uart_ovsrs_actual; + pBaudSetting->Div = min_divisor; + pBaudSetting->Ovsr_adj = ovsr_adj; + pBaudSetting->Ovsr_adj_bits = adj_bits; + + DBG_UART_INFO("%sBaudRateRtl8195a: BaudRate:%d Divisor:%d Ovsr:%d Ovsr_ADj:0x%x\n", + "HalRuartGen", pBaudSetting->BaudRate, min_divisor, uart_ovsrs_actual, ovsr_adj); + + return HAL_OK; +} + +HAL_Status +HalRuartDumpBaudRateTableRtl8195a( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + RUART_SPEED_SETTING RuartSpeedSetting; + u32 Divisor; + u32 Ovsr; + u32 Ovsr_adj; + u32 i; + u32 j; + u32 adj; + + RuartSpeedSetting.max_err = 3; + RuartSpeedSetting.Ovsr_min = UART_OVSR_POOL_MIN; + RuartSpeedSetting.Ovsr_max = UART_OVSR_POOL_MAX; + RuartSpeedSetting.divisor_resolution = DIVISOR_RESOLUTION; + RuartSpeedSetting.jitter_lim = JITTER_LIMIT; + RuartSpeedSetting.sclk = UART_SCLK; + + if (pHalRuartAdapter->pDefaultBaudRateTbl != NULL) { + // for debugging + DBG_8195A("==== 10 Bit ====\r\n"); + i = 0; + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_10; + RuartSpeedSetting.Ovsr_adj_max_bits = 10; + while (pHalRuartAdapter->pDefaultBaudRateTbl[i] < 0xffffffff) { + RuartSpeedSetting.BaudRate = pHalRuartAdapter->pDefaultBaudRateTbl[i]; + if (HalRuartGenBaudRateRtl8195a(&RuartSpeedSetting) == HAL_OK) { + Divisor = RuartSpeedSetting.Div; + Ovsr = RuartSpeedSetting.Ovsr; + Ovsr_adj = RuartSpeedSetting.Ovsr_adj; + adj = 0; + for (j=0;j<10;j++) { + if (Ovsr_adj & (1<pDefaultBaudRateTbl[i], Ovsr, Divisor, Ovsr_adj, adj); + } + i++; + } + + + DBG_8195A("==== 9 Bit ====\r\n"); + i = 0; + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_9; + RuartSpeedSetting.Ovsr_adj_max_bits = 9; + while (pHalRuartAdapter->pDefaultBaudRateTbl[i] < 0xffffffff) { + RuartSpeedSetting.BaudRate = pHalRuartAdapter->pDefaultBaudRateTbl[i]; + if (HalRuartGenBaudRateRtl8195a(&RuartSpeedSetting) == HAL_OK) { + Divisor = RuartSpeedSetting.Div; + Ovsr = RuartSpeedSetting.Ovsr; + Ovsr_adj = RuartSpeedSetting.Ovsr_adj; + adj = 0; + for (j=0;j<10;j++) { + if (Ovsr_adj & (1<pDefaultBaudRateTbl[i], Ovsr, Divisor, Ovsr_adj, adj); + } + i++; + } + + DBG_8195A("==== 8 Bit ====\r\n"); + i = 0; + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_8; + RuartSpeedSetting.Ovsr_adj_max_bits = 8; + while (pHalRuartAdapter->pDefaultBaudRateTbl[i] < 0xffffffff) { + RuartSpeedSetting.BaudRate = pHalRuartAdapter->pDefaultBaudRateTbl[i]; + if (HalRuartGenBaudRateRtl8195a(&RuartSpeedSetting) == HAL_OK) { + Divisor = RuartSpeedSetting.Div; + Ovsr = RuartSpeedSetting.Ovsr; + Ovsr_adj = RuartSpeedSetting.Ovsr_adj; + adj = 0; + for (j=0;j<10;j++) { + if (Ovsr_adj & (1<pDefaultBaudRateTbl[i], Ovsr, Divisor, Ovsr_adj, adj); + } + i++; + } + } + return HAL_OK; +} + +HAL_Status +HalRuartSetBaudRateRtl8195a( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + RUART_SPEED_SETTING RuartSpeedSetting; + u32 RegValue; + u32 Dll, Dlm; + u8 UartIndex; + u32 Divisor; + u32 Ovsr; + u32 Ovsr_adj; + u32 i; + u32 cpu_clk; + u32 baud_rate_temp; + u32 err; + u8 is_defined_baud; + u8 word_bits; + u8 adj_bits; + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + u8 chip_ver; + + // get chip version + chip_ver = HalRuartGetChipVerRtl8195a(); +#endif + + if (pHalRuartAdapter->WordLen == RUART_WLS_8BITS) { + word_bits = 8+1; // 1 start bit + 8 data bit + } else { + word_bits = 7+1; + } + + if (pHalRuartAdapter->Parity == RUART_PARITY_ENABLE) { + word_bits++; // 1 parity bit + } + + is_defined_baud = 0; + + if (pHalRuartAdapter->pDefaultBaudRateTbl != NULL) { + i = 0; + while (pHalRuartAdapter->pDefaultBaudRateTbl[i] < 0xffffffff) { + if (pHalRuartAdapter->pDefaultBaudRateTbl[i] == pHalRuartAdapter->BaudRate) { + Divisor = pHalRuartAdapter->pDefaultDivTbl[i]; + Ovsr = pHalRuartAdapter->pDefaultOvsrRTbl[i]; + switch (word_bits) { + case 9: + adj_bits = pHalRuartAdapter->pDefOvsrAdjBitTbl_9[i]; + Ovsr_adj = pHalRuartAdapter->pDefOvsrAdjTbl_9[adj_bits]; + break; + case 10: + adj_bits = pHalRuartAdapter->pDefOvsrAdjBitTbl_10[i]; + Ovsr_adj = pHalRuartAdapter->pDefOvsrAdjTbl_10[adj_bits]; + break; + case 8: + adj_bits = pHalRuartAdapter->pDefOvsrAdjBitTbl_8[i]; + Ovsr_adj = pHalRuartAdapter->pDefOvsrAdjTbl_8[adj_bits]; + break; + + default: + adj_bits = pHalRuartAdapter->pDefOvsrAdjBitTbl_9[i]; + Ovsr_adj = pHalRuartAdapter->pDefOvsrAdjTbl_9[adj_bits]; + break; + } + // Verify again + cpu_clk = UART_SCLK; + baud_rate_temp = cpu_clk/Ovsr/Divisor; +// DBG_8195A("baud_rate_temp %d\n", baud_rate_temp); + + if (baud_rate_temp > pHalRuartAdapter->BaudRate) { + err = baud_rate_temp - pHalRuartAdapter->BaudRate; + } else { + err = pHalRuartAdapter->BaudRate - baud_rate_temp; + } + + // Tolerance is 10% + // If the err is too big, it may caused by "the baud rate table is not for this CPU clock" + if (err < (pHalRuartAdapter->BaudRate/10)) { + is_defined_baud = 1; + } + break; // break the while loop + } else { + i++; + } + } + } + + if (is_defined_baud == 0) { + + switch (word_bits) { + case 9: + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_9; + break; + + case 10: + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_10; + break; + + case 8: + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_8; + break; + + default: + word_bits = 9; + RuartSpeedSetting.Ovsr_adj_map = pHalRuartAdapter->pDefOvsrAdjTbl_9; + break; + } + DBG_UART_INFO("BaudRate(%d) not in the Lookup table \n", pHalRuartAdapter->BaudRate); + RuartSpeedSetting.Ovsr_adj_max_bits = word_bits; + RuartSpeedSetting.max_err = 3; + RuartSpeedSetting.Ovsr_min = UART_OVSR_POOL_MIN; + RuartSpeedSetting.Ovsr_max = UART_OVSR_POOL_MAX; + RuartSpeedSetting.divisor_resolution = DIVISOR_RESOLUTION; + RuartSpeedSetting.jitter_lim = JITTER_LIMIT; + RuartSpeedSetting.sclk = UART_SCLK; + RuartSpeedSetting.BaudRate = pHalRuartAdapter->BaudRate; +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + if (chip_ver < 2) { + // A or B Cut + // workround: +2% bias + RuartSpeedSetting.BaudRate = (pHalRuartAdapter->BaudRate * 102)/100; + } +#endif + if (HalRuartGenBaudRateRtl8195a(&RuartSpeedSetting) == HAL_OK) { + Divisor = RuartSpeedSetting.Div; + Ovsr = RuartSpeedSetting.Ovsr; + Ovsr_adj = RuartSpeedSetting.Ovsr_adj; + } else { + DBG_UART_ERR("Invalid BaudRate(%d), Force Baud Rateit as 9600\n", + pHalRuartAdapter->BaudRate); + Divisor = 434; + Ovsr = 20; + Ovsr_adj = 0; + } + } + + UartIndex = pHalRuartAdapter->UartIndex; + + DBG_UART_INFO("%sBaudRateRtl8195a: BaudRate:%d Divisor:%d Ovsr:%d Ovsr_ADj:0x%x\n", + "HalRuartSet", pHalRuartAdapter->BaudRate, Divisor, Ovsr, Ovsr_adj); + DBG_UART_INFO("RealBaudRate: %d\n", RuartSpeedSetting.sclk/Divisor/Ovsr); + + Dll = Divisor & 0xFF; + Dlm = (Divisor & 0xFF00) >> 8; + + /* Set DLAB bit to 1 to access DLL/DLM */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF); + RegValue |= RUART_LINE_CTL_REG_DLAB_ENABLE; + HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue); + + HAL_RUART_WRITE32(UartIndex, RUART_DLL_OFF, Dll); + HAL_RUART_WRITE32(UartIndex, RUART_DLM_OFF, Dlm); + + /** + * Clean Rx break signal interrupt status at initial stage. + */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_SCRATCH_PAD_REG_OFF); + RegValue |= RUART_SP_REG_RXBREAK_INT_STATUS; + HAL_RUART_WRITE32(UartIndex, RUART_SCRATCH_PAD_REG_OFF, RegValue); + + /* Set OVSR(xfactor) */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_STS_REG_OFF); + RegValue &= ~(RUART_STS_REG_XFACTOR); + RegValue |= (((Ovsr - 5) << 4) & RUART_STS_REG_XFACTOR); + HAL_RUART_WRITE32(UartIndex, RUART_STS_REG_OFF, RegValue); + + /* Set OVSR_ADJ[10:0] (xfactor_adj[26:16]) */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_SCRATCH_PAD_REG_OFF); + RegValue &= ~(RUART_SP_REG_XFACTOR_ADJ); + RegValue |= ((Ovsr_adj << 16) & RUART_SP_REG_XFACTOR_ADJ); + HAL_RUART_WRITE32(UartIndex, RUART_SCRATCH_PAD_REG_OFF, RegValue); + + /* clear DLAB bit */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF); + RegValue &= ~(RUART_LINE_CTL_REG_DLAB_ENABLE); + HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue); + + pHalRuartAdapter->BaudRateUsing = pHalRuartAdapter->BaudRate; + pHalRuartAdapter->WordLenUsing = pHalRuartAdapter->WordLen; + pHalRuartAdapter->ParityUsing = pHalRuartAdapter->Parity; + + return HAL_OK; +} + + +HAL_Status +HalRuartInitRtl8195a_Patch( + IN VOID *Data ///< RUART Adapter +) +{ + /* DBG_ENTRANCE; */ + u32 RegValue; + u8 UartIndex; + u8 PinmuxSelect; + + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + + UartIndex = pHalRuartAdapter->UartIndex; + PinmuxSelect = pHalRuartAdapter->PinmuxSelect; + + if (UartIndex > 2) { + DBG_UART_ERR(ANSI_COLOR_MAGENTA"HalRuartInitRtl8195a: Invalid UART Index\n"ANSI_COLOR_RESET); + return HAL_ERR_PARA; + } + + DBG_UART_INFO("HalRuartInitRtl8195a: [UART %d] PinSel=%d\n", UartIndex, PinmuxSelect); + if(( PinmuxSelect == RUART0_MUX_TO_GPIOE ) && ((UartIndex == 0) || (UartIndex == 1))) { + DBG_UART_WARN(ANSI_COLOR_MAGENTA"UART Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET); + } + + // switch Pin from EEPROM to UART0 + if(( PinmuxSelect == RUART0_MUX_TO_GPIOC ) && (UartIndex == 0)) { + RegValue = HAL_READ32(SYSTEM_CTRL_BASE, 0xa4); + if (RegValue & 0x10) { + DBG_UART_WARN("UART Pin may conflict with EEPROM\n"); + HAL_WRITE32(SYSTEM_CTRL_BASE, 0xa4, (RegValue & (~0x10))); + } + } + + switch (UartIndex) { + case 0: + /* UART 0 */ + ACTCK_UART0_CCTRL(ON); + SLPCK_UART0_CCTRL(ON); + PinCtrl(UART0, PinmuxSelect, ON); + UART0_FCTRL(ON); + UART0_BD_FCTRL(ON); + break; + + case 1: + /* UART 1 */ + ACTCK_UART1_CCTRL(ON); + SLPCK_UART1_CCTRL(ON); + PinCtrl(UART1, PinmuxSelect, ON); + UART1_FCTRL(ON); + UART1_BD_FCTRL(ON); + break; + + case 2: + /* UART 1 */ + ACTCK_UART2_CCTRL(ON); + SLPCK_UART2_CCTRL(ON); + PinCtrl(UART2, PinmuxSelect, ON); + UART2_FCTRL(ON); + UART2_BD_FCTRL(ON); + break; + + default: + DBG_UART_ERR("Invalid UART Index(%d)\n", UartIndex); + return HAL_ERR_PARA; + } + + /* Reset RX FIFO */ + HalRuartResetRxFifoRtl8195a(Data); + DBG_UART_INFO(ANSI_COLOR_CYAN"HAL UART Init[UART %d]\n"ANSI_COLOR_RESET, UartIndex); + + /* Disable all interrupts */ + HAL_RUART_WRITE32(UartIndex, RUART_INTERRUPT_EN_REG_OFF, 0x00); + + /* Set Baudrate Division */ + if ((pHalRuartAdapter->BaudRateUsing != pHalRuartAdapter->BaudRate) || + (pHalRuartAdapter->WordLenUsing != pHalRuartAdapter->WordLen) || + (pHalRuartAdapter->ParityUsing != pHalRuartAdapter->Parity)) { + HalRuartSetBaudRateRtl8195a(pHalRuartAdapter); + } + + /** + * Clean Rx break signal interrupt status at initial stage. + */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_SCRATCH_PAD_REG_OFF); + RegValue |= RUART_SP_REG_RXBREAK_INT_STATUS; + HAL_RUART_WRITE32(UartIndex, RUART_SCRATCH_PAD_REG_OFF, RegValue); + +// DBG_UART_INFO("[R] UART%d INT_EN(0x04) = %x\n", UartIndex, pHalRuartAdapter->Interrupts); + RegValue = ((pHalRuartAdapter->Interrupts) & 0xFF); + HAL_RUART_WRITE32(UartIndex, RUART_INTERRUPT_EN_REG_OFF, RegValue); +// DBG_UART_INFO("[W] UART%d INT_EN(0x04) = %x\n", UartIndex, RegValue); + + /* Configure FlowControl */ + if (pHalRuartAdapter->FlowControl == AUTOFLOW_ENABLE) { + RegValue = HAL_RUART_READ32(UartIndex, RUART_MODEM_CTL_REG_OFF); + RegValue |= RUART_MCL_AUTOFLOW_ENABLE; + HAL_RUART_WRITE32(UartIndex, RUART_MODEM_CTL_REG_OFF, RegValue); + } + + /* RUART DMA Initialization */ +// HalRuartDmaInitRtl8195a(pHalRuartAdapter); + + DBG_UART_INFO("[R] UART%d LCR(0x%02X): %X\n", UartIndex, RUART_LINE_CTL_REG_OFF, HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF)); + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF); + + /* PARITY CONTROL */ + RegValue &= BIT_CLR_LCR_WLS; + RegValue |= BIT_LCR_WLS(pHalRuartAdapter->WordLen); + + RegValue &= BIT_INVC_LCR_STB_EN; + RegValue |= BIT_LCR_STB_EN(pHalRuartAdapter->StopBit); + + RegValue &= BIT_INVC_LCR_PARITY_EN; + RegValue |= BIT_LCR_PARITY_EN(pHalRuartAdapter->Parity); + + /* PARITY TYPE SELECT */ + RegValue &= BIT_INVC_LCR_PARITY_TYPE; + RegValue |= BIT_LCR_PARITY_TYPE(pHalRuartAdapter->ParityType); + + /* STICK PARITY CONTROL */ + RegValue &= BIT_INVC_LCR_STICK_PARITY_EN; + RegValue |= BIT_LCR_STICK_PARITY_EN(pHalRuartAdapter->StickParity); + + HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue); + DBG_UART_INFO("[W] UART%d LCR(0x%02X): %X\n", UartIndex, RUART_LINE_CTL_REG_OFF, HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF)); + + /* Need to assert RTS during initial stage. */ + if (pHalRuartAdapter->FlowControl == AUTOFLOW_ENABLE) { + HalRuartRTSCtrlRtl8195a(Data, 1); + } + pHalRuartAdapter->State = HAL_UART_STATE_READY; + + return HAL_OK; +} + +HAL_Status +HalRuartEnableRtl8195a( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex; + + // Enable IP Clock + UartIndex = pHalRuartAdapter->UartIndex; + switch (UartIndex) { + case 0: + /* UART 0 */ + ACTCK_UART0_CCTRL(ON); + SLPCK_UART0_CCTRL(ON); + break; + + case 1: + /* UART 1 */ + ACTCK_UART1_CCTRL(ON); + SLPCK_UART1_CCTRL(ON); + break; + + case 2: + /* UART 1 */ + ACTCK_UART2_CCTRL(ON); + SLPCK_UART2_CCTRL(ON); + break; + + default: + DBG_UART_ERR("Invalid UART Index(%d)\n", UartIndex); + return HAL_ERR_PARA; + } + + return HAL_OK; +} + +HAL_Status +HalRuartDisableRtl8195a( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex; + + // Gate IP Clock + UartIndex = pHalRuartAdapter->UartIndex; + switch (UartIndex) { + case 0: + /* UART 0 */ + ACTCK_UART0_CCTRL(OFF); + SLPCK_UART0_CCTRL(OFF); + break; + + case 1: + /* UART 1 */ + ACTCK_UART1_CCTRL(OFF); + SLPCK_UART1_CCTRL(OFF); + break; + + case 2: + /* UART 1 */ + ACTCK_UART2_CCTRL(OFF); + SLPCK_UART2_CCTRL(OFF); + break; + + default: + DBG_UART_ERR("Invalid UART Index(%d)\n", UartIndex); + return HAL_ERR_PARA; + } + + return HAL_OK; +} + +HAL_Status +HalRuartFlowCtrlRtl8195a( + IN VOID *Data +) +{ + u32 UartIndex; + u32 RegValue; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + + UartIndex = pHalRuartAdapter->UartIndex; + + RegValue = HAL_RUART_READ32(UartIndex, RUART_MODEM_CTL_REG_OFF); + if (!pHalRuartAdapter->FlowControl) { + // No Auto Flow Control: no flow control or flow controled by software + RegValue &= ~(RUART_MCL_AUTOFLOW_ENABLE); + } + else { + RegValue |= RUART_MCL_AUTOFLOW_ENABLE; + } + HAL_RUART_WRITE32(UartIndex, RUART_MODEM_CTL_REG_OFF, RegValue); + + return HAL_OK; +} + +u32 +_UartTxDmaIrqHandle_Patch( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + u8 IsrTypeMap; + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + // Clear Pending ISR + IsrTypeMap = pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + + if (IsrTypeMap & BlockType) { + pHalGdmaAdapter->MuliBlockCunt++; + } + + if (pHalGdmaAdapter->MuliBlockCunt == pHalGdmaAdapter->MaxMuliBlock) { + // Clean Auto Reload Bit + pHalGdmaOp->HalGdmaChCleanAutoDst((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + + if ((HAL_UART_STATE_BUSY_TX == pHalRuartAdapter->State) || + (HAL_UART_STATE_BUSY_TX_RX == pHalRuartAdapter->State)) { + if (pHalRuartAdapter->State == HAL_UART_STATE_BUSY_TX) { + pHalRuartAdapter->State = HAL_UART_STATE_READY; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_RX; + } + + // Call user TX complete callback + if (NULL != pHalRuartAdapter->TxCompCallback) { + pHalRuartAdapter->TxCompCallback(pHalRuartAdapter->TxCompCbPara); + } + } + } + return 0; +} + +u32 +_UartRxDmaIrqHandle_Patch( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + u8 IsrTypeMap; + u8 LineStatus; + u8 UartIndex; + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + // Clear Pending ISR + IsrTypeMap = pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + + if (IsrTypeMap & BlockType) { + pHalGdmaAdapter->MuliBlockCunt++; + } + + if ((pHalGdmaAdapter->MuliBlockCunt == pHalGdmaAdapter->MaxMuliBlock)) { + // Clean Auto Reload Bit + pHalGdmaOp->HalGdmaChCleanAutoSrc((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + + // Check the Line Status + UartIndex = pHalRuartAdapter->UartIndex; + LineStatus = (u8)HAL_RUART_READ32(UartIndex, RUART_LINE_STATUS_REG_OFF); + pHalRuartAdapter->Status |= LineStatus & RUART_LINE_STATUS_ERR; + + if (pHalRuartAdapter->State == HAL_UART_STATE_BUSY_RX) { + pHalRuartAdapter->State = HAL_UART_STATE_READY; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX; + } + + // Call User Rx complete callback + if (pHalRuartAdapter->RxCompCallback != NULL) { + pHalRuartAdapter->RxCompCallback (pHalRuartAdapter->RxCompCbPara); + } + } + return 0; +} + + +/** + * RUART send a data buffer by DMA(non-block) mode. + * + * RUART send data. + * + * @return VOID + */ +HAL_Status +HalRuartDmaSendRtl8195a_Patch( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; +// u8 UartIndex = pHalRuartAdapter->UartIndex; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + HAL_UART_State State; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_READY) && (State != HAL_UART_STATE_BUSY_RX)) { + DBG_UART_WARN("HalRuartDmaSendRtl8195a: on Busy, State=%d\n", State); + return HAL_BUSY; + } + + if ((pTxData == NULL) || (Length == 0)) { + pHalRuartAdapter->Status = HAL_UART_STATUS_ERR_PARA; + DBG_UART_ERR("HalRuartDmaSendRtl8195a: Err: pTxData=0x%x, Length=%d\n", pTxData, Length); + return HAL_ERR_PARA; + } + + if (State == HAL_UART_STATE_READY) { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX_RX; + } + + pHalRuartAdapter->Status = HAL_UART_STATUS_OK; + pHalRuartAdapter->pTxBuf = pTxData; + pHalRuartAdapter->TxCount = Length; + + // Enable GDMA for TX + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if (((pHalRuartAdapter->TxCount & 0x03)==0) && + (((u32)(pHalRuartAdapter->pTxBuf) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.BlockSize = pHalRuartAdapter->TxCount >> 2; + } + else{ + // move 1 byte each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.BlockSize = pHalRuartAdapter->TxCount; + } + + if (pHalGdmaAdapter->GdmaCtl.BlockSize > 4095) { + // over Maximum block size 4096 + return HAL_ERR_PARA; + } + + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->ChSar = (u32)(pHalRuartAdapter->pTxBuf); + + pHalGdmaAdapter->Rsvd4to7 = 0; + pHalGdmaAdapter->Llpctrl = 0; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 0; + + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; +} + +/** + * RUART Receive data by Interrupt (non-block) mode. + * + * RUART Receive data. + * Receive one byte each time. + * + * @return u8 + */ +HAL_Status +HalRuartDmaRecvRtl8195a_Patch( + IN VOID *Data, ///< RUART Adapter + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + HAL_UART_State State; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_READY) && (State != HAL_UART_STATE_BUSY_TX)) { + DBG_UART_WARN("%s: on Busy, State=%d\n", State); + return HAL_BUSY; + } + + if ((pRxData == NULL) || (Length == 0)) { + pHalRuartAdapter->Status = HAL_UART_STATUS_ERR_PARA; + DBG_UART_ERR("HalRuartDmaRecvRtl8195a: Err: pTxData=0x%x, Length=%d\n", pRxData, Length); + return HAL_ERR_PARA; + } + + if (State == HAL_UART_STATE_READY) { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_RX; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX_RX; + } + + pHalRuartAdapter->Status = HAL_UART_STATUS_OK; + pHalRuartAdapter->pRxBuf = pRxData; + pHalRuartAdapter->RxCount = Length; + + // Enable GDMA for RX + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if (((u32)(pHalRuartAdapter->pRxBuf) & 0x03)==0) { + // 4-bytes aligned, move 4 bytes each DMA transaction + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + } + else{ + // move 1 byte each DMA transaction + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + } + pHalGdmaAdapter->GdmaCtl.BlockSize = pHalRuartAdapter->RxCount; + if (pHalGdmaAdapter->GdmaCtl.BlockSize > 4095) { + // over Maximum block size 4096 + DBG_UART_ERR("HalRuartDmaRecvRtl8195a: BlockSize too big(%d)\n", pHalGdmaAdapter->GdmaCtl.BlockSize); + return HAL_ERR_PARA; + } + + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->ChDar = (u32)(pHalRuartAdapter->pRxBuf); + + pHalGdmaAdapter->Rsvd4to7 = 0; + pHalGdmaAdapter->Llpctrl = 0; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 0; + + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; +} + +/** + * RUART send a data buffer by Multi-Block DMA(non-block) mode. + * + * RUART send data. + * + * @return VOID + */ +HAL_Status +HalRuartMultiBlkDmaSendRtl8195a( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxData, // the Buffer to be send + IN u32 Length // the length of data to be send +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + HAL_UART_State State; + UART_DMA_MULTIBLK *pDmaBlkList; + u32 BlockBytes; + u32 TotalTr; + u32 SrcAddr; + u8 i; + u8 BlkNum; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_READY) && (State != HAL_UART_STATE_BUSY_RX)) { + DBG_UART_WARN("HalRuartDmaSendRtl8195a: on Busy, State=%d\n", State); + return HAL_BUSY; + } + + if ((pTxData == NULL) || (Length == 0)) { + pHalRuartAdapter->Status = HAL_UART_STATUS_ERR_PARA; + DBG_UART_ERR("HalRuartMultiBlkDmaSendRtl8195a: Err: pTxData=0x%x, Length=%d\n", pTxData, Length); + return HAL_ERR_PARA; + } + + if (State == HAL_UART_STATE_READY) { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX_RX; + } + + pHalRuartAdapter->Status = HAL_UART_STATUS_OK; + pHalRuartAdapter->pTxBuf = pTxData; + pHalRuartAdapter->TxCount = Length; + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + pDmaBlkList = pUartGdmaConfig->pTxDmaBlkList; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if (((pHalRuartAdapter->TxCount & 0x03)==0) && + (((u32)(pHalRuartAdapter->pTxBuf) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + TotalTr = Length >> 2; // 4-bytes each write + BlockBytes = UART_DMA_BLOCK_SIZE << 2; // a block can transfer BlockSize*4 bytes + } + else{ + // move 1 byte each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + TotalTr = Length; // 1-byte each write + BlockBytes = UART_DMA_BLOCK_SIZE; + } + + BlkNum = 0; + SrcAddr = (u32)pTxData; + for (i=0; iGdmaChLli[i].Sarx = SrcAddr; + pDmaBlkList->GdmaChLli[i].Darx = (u32) (pHalGdmaAdapter->ChDar); + pDmaBlkList->Lli[i].pLliEle = (GDMA_CH_LLI_ELE*) &(pDmaBlkList->GdmaChLli[i]); + SrcAddr += BlockBytes; + BlkNum++; + if (TotalTr >= UART_DMA_BLOCK_SIZE) { + pDmaBlkList->Lli[i].pNextLli = &(pDmaBlkList->Lli[i+1]); + pDmaBlkList->BlockSizeList[i].pNextBlockSiz = &(pDmaBlkList->BlockSizeList[i+1]); + pDmaBlkList->BlockSizeList[i].BlockSize = UART_DMA_BLOCK_SIZE; + TotalTr -= UART_DMA_BLOCK_SIZE; + } else { + pDmaBlkList->Lli[i].pNextLli = (struct GDMA_CH_LLI*)NULL; + pDmaBlkList->BlockSizeList[i].pNextBlockSiz = (struct BLOCK_SIZE_LIST*)NULL; + pDmaBlkList->BlockSizeList[i].BlockSize = TotalTr; + TotalTr = 0; + break; + } + } + + if (TotalTr > 0) { + // Cannot transfer all data in multiple-block DMA + // Try to increase block number, but maximum block number is 16 + pDmaBlkList->Lli[UART_DMA_MBLK_NUM-1].pNextLli = (struct GDMA_CH_LLI*)NULL; + pDmaBlkList->BlockSizeList[UART_DMA_MBLK_NUM-1].pNextBlockSiz = (struct BLOCK_SIZE_LIST*)NULL; + DBG_UART_ERR("HalRuartMultiBlkDmaSendRtl8195a: Cannot Transfer all data\n"); + } + + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = BlkNum; + pHalGdmaAdapter->Rsvd4to7 = 1; + pHalGdmaAdapter->Llpctrl = 1; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 1; + + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChBlockSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; + +} + +/** + * RUART Receive data by Multi-Block DMA (non-block) mode. + * + * RUART Receive data. + * + * @return u8 + */ +HAL_Status +HalRuartMultiBlkDmaRecvRtl8195a( + IN VOID *Data, ///< RUART Adapter + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + HAL_UART_State State; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + UART_DMA_MULTIBLK *pDmaBlkList; + u32 TotalTr; + u32 DstAddr; + u8 i; + u8 BlkNum; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_READY) && (State != HAL_UART_STATE_BUSY_TX)) { + DBG_UART_WARN("HalRuartMultiBlkDmaRecvRtl8195a: on Busy, State=%d\n", State); + return HAL_BUSY; + } + + if ((pRxData == NULL) || (Length == 0)) { + pHalRuartAdapter->Status = HAL_UART_STATUS_ERR_PARA; + DBG_UART_ERR("HalRuartDmaRecvRtl8195a: Err: pTxData=0x%x, Length=%d\n", pRxData, Length); + return HAL_ERR_PARA; + } + + if (State == HAL_UART_STATE_READY) { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_RX; + } else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX_RX; + } + + pHalRuartAdapter->Status = HAL_UART_STATUS_OK; + pHalRuartAdapter->pRxBuf = pRxData; + pHalRuartAdapter->RxCount = Length; + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + pDmaBlkList = pUartGdmaConfig->pRxDmaBlkList; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if (((u32)(pHalRuartAdapter->pRxBuf) & 0x03)==0) { + // 4-bytes aligned, move 4 bytes each DMA transaction + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeOne; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + } else{ + // move 1 byte each DMA transaction + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeFour; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + } + + TotalTr = Length; // 1-byte each write, total transaction = data lenth + BlkNum = 0; + DstAddr = (u32)pRxData; + for (i=0; iGdmaChLli[i].Sarx = (u32) (pHalGdmaAdapter->ChSar); + pDmaBlkList->GdmaChLli[i].Darx = DstAddr; + pDmaBlkList->Lli[i].pLliEle = (GDMA_CH_LLI_ELE*) &(pDmaBlkList->GdmaChLli[i]); + DstAddr += UART_DMA_BLOCK_SIZE; + BlkNum++; + if (TotalTr >= UART_DMA_BLOCK_SIZE) { + pDmaBlkList->Lli[i].pNextLli = &(pDmaBlkList->Lli[i+1]); + pDmaBlkList->BlockSizeList[i].pNextBlockSiz = &(pDmaBlkList->BlockSizeList[i+1]); + pDmaBlkList->BlockSizeList[i].BlockSize = UART_DMA_BLOCK_SIZE; + TotalTr -= UART_DMA_BLOCK_SIZE; + } else { + pDmaBlkList->Lli[i].pNextLli = (struct GDMA_CH_LLI*)NULL; + pDmaBlkList->BlockSizeList[i].pNextBlockSiz = (struct BLOCK_SIZE_LIST*)NULL; + pDmaBlkList->BlockSizeList[i].BlockSize = TotalTr; + TotalTr = 0; + break; + } + } + + if (TotalTr > 0) { + // Cannot transfer all data in multiple-block DMA + // Try to increase block number, but maximum block number is 16 + pDmaBlkList->Lli[UART_DMA_MBLK_NUM-1].pNextLli = (struct GDMA_CH_LLI*)NULL; + pDmaBlkList->BlockSizeList[UART_DMA_MBLK_NUM-1].pNextBlockSiz = (struct BLOCK_SIZE_LIST*)NULL; + DBG_UART_ERR("HalRuartMultiBlkDmaRecvRtl8195a: Cannot Transfer all data\n"); + } + + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = BlkNum; + pHalGdmaAdapter->Rsvd4to7 = 1; + pHalGdmaAdapter->Llpctrl = 1; + pHalGdmaAdapter->GdmaCtl.LlpDstEn = 1; + + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChBlockSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; +} + +/** + * Stop non-blocking UART TX + * + * + * @return VOID + */ +HAL_Status +HalRuartStopRecvRtl8195a_Patch( + IN VOID *Data // PHAL_RUART_ADAPTER + ) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; + PUART_DMA_CONFIG pUartGdmaConfig; + HAL_UART_State State; + u32 DMA_Dar; + u32 RecvdCnt; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_BUSY_RX) && (State != HAL_UART_STATE_BUSY_TX_RX)) { + DBG_UART_WARN("HalRuartStopRecvRtl8195a: Not in TX state, State=%d\n", State); + return HAL_OK; + } + + if (HAL_OK != RuartLock(pHalRuartAdapter)) { + DBG_UART_WARN("HalRuartStopRecvRtl8195a:Unable to Lock, Statu=%d\n", State); + return HAL_BUSY; + } + + // Disable Rx interrupt + pHalRuartAdapter->Interrupts &= ~(RUART_IER_ERBI | RUART_IER_ELSI); + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + if (NULL != pUartGdmaConfig) { + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + u8 IsrTypeMap; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if ((NULL != pHalGdmaAdapter) && (NULL != pHalGdmaOp) && + (HalGdmaQueryChEnRtl8195a((VOID*)pHalGdmaAdapter))) { + // Clean Auto Reload Bit + pHalGdmaOp->HalGdmaChCleanAutoDst((VOID*)pHalGdmaAdapter); + // Clear Pending ISR + IsrTypeMap = pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + + DMA_Dar = HalGdmaQueryDArRtl8195a((VOID*)pHalGdmaAdapter); + RecvdCnt = DMA_Dar - (u32)(pHalRuartAdapter->pRxBuf); +// DBG_8195A("%s: got %d bytes\r\n", __FUNCTION__, RecvdCnt); + pHalRuartAdapter->RxCount -= RecvdCnt; + pHalRuartAdapter->pRxBuf += RecvdCnt; + } + } + + while (HalRuartGetCRtl8195a(pHalRuartAdapter, pHalRuartAdapter->pRxBuf) == HAL_OK) { + pHalRuartAdapter->RxCount--; + pHalRuartAdapter->pRxBuf++; + } + + if (pHalRuartAdapter->State == HAL_UART_STATE_BUSY_RX) { + pHalRuartAdapter->State = HAL_UART_STATE_READY; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_TX; + } + + RuartUnLock(pHalRuartAdapter); + + return HAL_OK; + +} + +/** + * Stop non-blocking UART TX + * + * + * @return VOID + */ +HAL_Status +HalRuartStopSendRtl8195a_Patch( + IN VOID *Data // PHAL_RUART_ADAPTER + ) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; + PUART_DMA_CONFIG pUartGdmaConfig; + HAL_UART_State State; + u32 DMA_Sar; + u32 TxedCnt; + + State = pHalRuartAdapter->State; + if ((State != HAL_UART_STATE_BUSY_TX) && (State != HAL_UART_STATE_BUSY_TX_RX)) { + DBG_UART_WARN("HalRuartDmaSendRtl8195a: Not in TX state, State=%d\n", State); + return HAL_OK; + } + + if (HAL_OK != RuartLock(pHalRuartAdapter)) { + DBG_UART_WARN("HalRuartDmaSendRtl8195a:Unable to Lock, Statu=%d\n", State); + return HAL_BUSY; + } + + // Disable Tx FIFO empty interrupt + pHalRuartAdapter->Interrupts &= ~RUART_IER_ETBEI; + HalRuartSetIMRRtl8195a (pHalRuartAdapter); + + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + if (NULL != pUartGdmaConfig) { + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + u8 IsrTypeMap; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + pHalGdmaOp = (PHAL_GDMA_OP)pUartGdmaConfig->pHalGdmaOp; + + if ((NULL != pHalGdmaAdapter) && (NULL != pHalGdmaOp) && + (HalGdmaQueryChEnRtl8195a((VOID*)pHalGdmaAdapter))) { + // Clean Auto Reload Bit + pHalGdmaOp->HalGdmaChCleanAutoDst((VOID*)pHalGdmaAdapter); + // Clear Pending ISR + IsrTypeMap = pHalGdmaOp->HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + pHalGdmaOp->HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + + DMA_Sar = HalGdmaQuerySArRtl8195a((VOID*)pHalGdmaAdapter); + TxedCnt = DMA_Sar - (u32)(pHalRuartAdapter->pTxBuf); +// DBG_8195A("%s: got %d bytes\r\n", __FUNCTION__, RecvdCnt); + pHalRuartAdapter->TxCount -= TxedCnt; + pHalRuartAdapter->pTxBuf += TxedCnt; + } + } + + if (State == HAL_UART_STATE_BUSY_TX) { + pHalRuartAdapter->State = HAL_UART_STATE_READY; + } + else { + pHalRuartAdapter->State = HAL_UART_STATE_BUSY_RX; + } + + RuartUnLock(pHalRuartAdapter); + + return HAL_OK; + +} + +VOID +HalRuartEnterCriticalRtl8195a( + IN VOID *Data ///< RUART Adapter +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; +#ifdef CONFIG_GDMA_EN + PUART_DMA_CONFIG pUartGdmaConfig; +#endif + + InterruptDis(&pHalRuartAdapter->IrqHandle); + +#ifdef CONFIG_GDMA_EN + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + if (NULL != pUartGdmaConfig) { + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + if (pHalGdmaAdapter->ChEn != 0) { + InterruptDis(&pUartGdmaConfig->RxGdmaIrqHandle); + } + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + if (pHalGdmaAdapter->ChEn != 0) { + InterruptDis(&pUartGdmaConfig->TxGdmaIrqHandle); + } + } +#endif +} + +VOID +HalRuartExitCriticalRtl8195a( + IN VOID *Data ///< RUART Adapter + ) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; +#ifdef CONFIG_GDMA_EN + PUART_DMA_CONFIG pUartGdmaConfig; +#endif + + InterruptEn(&pHalRuartAdapter->IrqHandle); + +#ifdef CONFIG_GDMA_EN + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + if (NULL != pUartGdmaConfig) { + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + if (pHalGdmaAdapter->ChEn != 0) { + InterruptEn(&pUartGdmaConfig->RxGdmaIrqHandle); + } + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + if (pHalGdmaAdapter->ChEn != 0) { + InterruptEn(&pUartGdmaConfig->TxGdmaIrqHandle); + } + } +#endif +} + +VOID +HalRuartDumpRegRtl8195a( + IN VOID *Data +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 UartIndex; + u32 i; + u32 RegValue; + + UartIndex = pHalRuartAdapter->UartIndex; + /* Set DLAB bit to 1 to access DLL/DLM */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF); + RegValue |= RUART_LINE_CTL_REG_DLAB_ENABLE; + HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue); + + for (i=0;i<0x40;i+=4) { + DBG_8195A("UART Reg[0x%x] = 0x%x\r\n", i, HAL_RUART_READ32(UartIndex, i)); + } + +/* clear DLAB bit */ + RegValue = HAL_RUART_READ32(UartIndex, RUART_LINE_CTL_REG_OFF); + RegValue &= ~(RUART_LINE_CTL_REG_DLAB_ENABLE); + HAL_RUART_WRITE32(UartIndex, RUART_LINE_CTL_REG_OFF, RegValue); +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/Descript.ion b/USDK/component/soc/realtek/8195a/fwlib/src/Descript.ion new file mode 100644 index 0000000..2af2828 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/Descript.ion @@ -0,0 +1,7 @@ +hal_common.c + +hal_efuse.c + +hal_misc.c + +hal_pinmux.c + +hal_sdio_host.c + +hal_soc_ps_monitor.c + +hal_spi_flash_ram.c + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_32k.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_32k.c new file mode 100644 index 0000000..0977a08 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_32k.c @@ -0,0 +1,305 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" + +#ifdef CONFIG_TIMER_MODULE + +VOID +En32KCalibration( + VOID +) +{ + u32 Rtemp; + u32 Ttemp = 0; +#if CONFIG_DEBUG_LOG > 5 + DiagPrintf("32K clock source calibration\n"); +#endif + //set parameter + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + //offset 1 = 0x1500 + Rtemp = 0x811500; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + HalDelayUs(40); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + + //offset 2 = 0x01c0 + Rtemp = 0x8201c0; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + HalDelayUs(40); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + + //offset 4 = 0x0100 + Rtemp = 0x840100; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + HalDelayUs(40); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + + //offset 0 = 0xf980 + Rtemp = 0x80f980; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + HalDelayUs(40); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + + while(1) { + //Polling LOCK + Rtemp = 0x110000; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + //DiagPrintf("Polling lock\n"); + HalDelayUs(40); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL1); + if ((Rtemp & 0x3000) != 0x0){ +#if CONFIG_DEBUG_LOG > 5 + DiagPrintf("32.768 Calibration Success\n", Ttemp); +#endif + break; + } + else { + Ttemp++; + HalDelayUs(30); +#if CONFIG_DEBUG_LOG > 5 + DiagPrintf("Check lock: %d\n", Ttemp); + DiagPrintf("0x278: %x\n", Rtemp); +#endif + if (Ttemp > 100000) { /*Delay 100ms*/ + DiagPrintf("32K Calibration Fail!\n", Ttemp); + break; + } + } + } +} + +#if CONFIG_WDG +WDG_ADAPTER WDGAdapter; +extern HAL_TIMER_OP HalTimerOp; + +#ifdef CONFIG_WDG_NORMAL +/* + * pvvx: if WDT RESET_MODE: + * HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & 0x1FFFFF); + */ +VOID +WDGInitial( + IN u32 Period +) +{ + u8 CountId; + u16 DivFactor; + u32 CountTemp; + u32 CountProcess = 0; + u32 DivFacProcess = 0; + u32 PeriodProcess = 100*Period; + u32 MinPeriodTemp = 0xFFFFFFFF; + u32 PeriodTemp = 0; + u32 *Reg = (u32*)&(WDGAdapter.Ctrl); + +#if CONFIG_DEBUG_LOG > 1 + DBG_8195A("WdgPeriod = %d ms\n", Period); +#endif + for (CountId = 0; CountId < 12; CountId++) { + CountTemp = ((0x00000001 << (CountId+1))-1); + DivFactor = (u16)((PeriodProcess)/(CountTemp*3)); + + if (DivFactor > 0) { + PeriodTemp = 3*(DivFactor+1)*CountTemp; + if (PeriodProcess < PeriodTemp) { + if (MinPeriodTemp > PeriodTemp) { + MinPeriodTemp = PeriodTemp; + CountProcess = CountId; + DivFacProcess = DivFactor; + } + } + } + } + +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("WdgScalar = %p\n", DivFacProcess); + DBG_8195A("WdgCunLimit = %p\n", CountProcess); +#endif + WDGAdapter.Ctrl.WdgScalar = DivFacProcess; + WDGAdapter.Ctrl.WdgEnByte = 0; + WDGAdapter.Ctrl.WdgClear = 1; + WDGAdapter.Ctrl.WdgCunLimit = CountProcess; + WDGAdapter.Ctrl.WdgMode = RESET_MODE; + WDGAdapter.Ctrl.WdgToISR = 0; +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("WdgCtrl = %p\n", (u32)(*Reg)); +#endif + HAL_WRITE32(VENDOR_REG_BASE, 0, (*Reg)); +} + +VOID +WDGIrqHandle +( + IN VOID *Data +) +{ + u32 temp; + WDG_REG *CtrlReg; + + if (NULL != WDGAdapter.UserCallback) { + WDGAdapter.UserCallback(WDGAdapter.callback_id); + } + + // Clear ISR + temp = HAL_READ32(VENDOR_REG_BASE, 0); + CtrlReg = (WDG_REG*)&temp; + CtrlReg->WdgToISR = 1; // write 1 clear + HAL_WRITE32(VENDOR_REG_BASE, 0, (temp)); +} + +VOID +WDGIrqInitial( + VOID +) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + + WDGAdapter.IrqHandle.Data = (u32)&WDGAdapter; + WDGAdapter.IrqHandle.IrqFun = (IRQ_FUN)WDGIrqHandle; + WDGAdapter.IrqHandle.IrqNum = WDG_IRQ; + WDGAdapter.IrqHandle.Priority = 0; + + InterruptRegister(&(WDGAdapter.IrqHandle)); + InterruptEn(&(WDGAdapter.IrqHandle)); + + + WDGAdapter.Ctrl.WdgToISR = 1; // clear ISR first + WDGAdapter.Ctrl.WdgMode = INT_MODE; + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); + WDGAdapter.Ctrl.WdgToISR = 0; +} + +VOID +WDGStart( + VOID +) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + WDGAdapter.Ctrl.WdgEnByte = 0xA5; + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); +} + +VOID +WDGStop( + VOID +) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + WDGAdapter.Ctrl.WdgEnByte = 0; + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); +} + +VOID +WDGRefresh( + VOID +) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + WDGAdapter.Ctrl.WdgClear = 1; + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); +} + +VOID +WDGIrqCallBackReg( + IN VOID *CallBack, + IN u32 Id +) +{ + WDGAdapter.UserCallback = (VOID (*)(u32))CallBack; + WDGAdapter.callback_id = Id; +} + +#endif + +#ifdef CONFIG_WDG_TEST +VOID +WDGIrqHandle +( + IN VOID *Data +) +{ +} + + +VOID +WDGGtimerHandle +( + IN VOID *Data +) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + WDGAdapter.Ctrl.WdgClear = 1; + DBG_8195A("reset WDG\n"); + if (HAL_READ32(SYSTEM_CTRL_BASE,REG_SYS_DSTBY_INFO2) == 0) { + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); + } +} + + +VOID +InitWDGIRQ(VOID) +{ + u32 *Temp = (u32*)&(WDGAdapter.Ctrl); + + WDGAdapter.Ctrl.WdgScalar = 0x96; + WDGAdapter.Ctrl.WdgEnByte = 0xA5; + WDGAdapter.Ctrl.WdgClear = 1; + WDGAdapter.Ctrl.WdgCunLimit = CNTFFFH; + WDGAdapter.Ctrl.WdgMode = RESET_MODE; + WDGAdapter.Ctrl.WdgToISR = 0; + + if (WDGAdapter.Ctrl.WdgMode == INT_MODE) { + + WDGAdapter.IrqHandle.Data = NULL; + WDGAdapter.IrqHandle.IrqFun = (IRQ_FUN)WDGIrqHandle; + WDGAdapter.IrqHandle.IrqNum = WDG_IRQ; + WDGAdapter.IrqHandle.Priority = 5; + + InterruptRegister(&(WDGAdapter.IrqHandle)); + InterruptEn(&(WDGAdapter.IrqHandle)); + } + else { + + WDGAdapter.WdgGTimer.TimerIrqPriority = 0; + WDGAdapter.WdgGTimer.TimerMode = USER_DEFINED; + WDGAdapter.WdgGTimer.IrqDis = OFF; + WDGAdapter.WdgGTimer.TimerId = 2;// + WDGAdapter.WdgGTimer.IrqHandle.IrqFun = (IRQ_FUN)WDGGtimerHandle; + WDGAdapter.WdgGTimer.IrqHandle.IrqNum = TIMER2_7_IRQ; + WDGAdapter.WdgGTimer.IrqHandle.Priority = 5; + WDGAdapter.WdgGTimer.IrqHandle.Data = NULL; + + if ((WDGAdapter.Ctrl.WdgCunLimit == CNTFFFH)&&(WDGAdapter.Ctrl.WdgScalar >= 0x8429)){ + WDGAdapter.WdgGTimer.TimerLoadValueUs = 0xFFFFFFFF - WDGTIMERELY; + } + else { + WDGAdapter.WdgGTimer.TimerLoadValueUs = (BIT0 << (WDGAdapter.Ctrl.WdgCunLimit+1)) + *WDGAdapter.Ctrl.WdgScalar*TIMER_TICK_US - WDGTIMERELY; + } + + HalTimerOp.HalTimerInit((VOID*) &(WDGAdapter.WdgGTimer)); + } + //fill reg + HAL_WRITE32(VENDOR_REG_BASE, 0, ((*Temp))); +} + + +//WDG +VOID HalWdgInit( + VOID +) +{ + +} +#endif //CONFIG_WDG_TEST +#endif //CONFIG_WDG +#endif //#ifdef CONFIG_TIMER_MODULE diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_adc.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_adc.c new file mode 100644 index 0000000..fee78fe --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_adc.c @@ -0,0 +1,1839 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "basic_types.h" +#include "diag.h" +#include "rand.h" +#include "section_config.h" +#include "rtl_utility.h" +#include "osdep_api.h" +#include "hal_adc.h" +#include "hal_gdma.h" +#include "hal_timer.h" +#include "hal_soc_ps_monitor.h" + +#ifdef CONFIG_ADC_EN + +#define ADC_STATIC_ALLOC 0 + +static volatile u32 ADCDatBuf[2]; +static volatile u8 ADCFullStsFlag; +static RTK_STATUS +RtkADCPinMuxDeInit( + IN PSAL_ADC_HND pSalADCHND +); + +static RTK_STATUS +RtkADCIrqDeInit( + IN PSAL_ADC_HND pSalADCHND +); + +static RTK_STATUS +RtkADCDMADeInit( + IN PSAL_ADC_HND pSalADCHND +); +/* DAC SAL global variables declaration when kernel disabled */ +#ifndef CONFIG_KERNEL + SRAM_BF_DATA_SECTION + HAL_ADC_OP HalADCOpSAL; +#endif + +#if ADC0_USED /*#if ADC0_USED*/ +#if ADC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + SAL_ADC_MNGT_ADPT SalADC0MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_ADC_HND_PRIV SalADC0HndPriv; + + SRAM_BF_DATA_SECTION + HAL_ADC_INIT_DAT HalADC0InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC0IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalADC0GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalADC0GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC0GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_ADC_USER_CB SalADC0UserCB; + + SRAM_BF_DATA_SECTION + SAL_ADC_USERCB_ADPT SalADC0UserCBAdpt[SAL_ADC_USER_CB_NUM]; +#endif +#endif /*#if ADC0_USED*/ + +#if ADC1_USED /*#if ADC1_USED*/ +#if ADC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + SAL_ADC_MNGT_ADPT SalADC1MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_ADC_HND_PRIV SalADC1HndPriv; + + SRAM_BF_DATA_SECTION + HAL_ADC_INIT_DAT HalADC1InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC1IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalADC1GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalADC1GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC1GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_ADC_USER_CB SalADC1UserCB; + + SRAM_BF_DATA_SECTION + SAL_ADC_USERCB_ADPT SalADC1UserCBAdpt[SAL_ADC_USER_CB_NUM]; +#endif +#endif /*#if ADC1_USED*/ + +#if ADC2_USED /*#if ADC2_USED*/ +#if ADC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + SAL_ADC_MNGT_ADPT SalADC2MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_ADC_HND_PRIV SalADC2HndPriv; + + SRAM_BF_DATA_SECTION + HAL_ADC_INIT_DAT HalADC2InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC2IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalADC2GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalADC2GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC2GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_ADC_USER_CB SalADC2UserCB; + + SRAM_BF_DATA_SECTION + SAL_ADC_USERCB_ADPT SalADC2UserCBAdpt[SAL_ADC_USER_CB_NUM]; +#endif +#endif /*#if ADC2_USED*/ + +#if ADC3_USED /*#if ADC3_USED*/ +#if ADC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + SAL_ADC_MNGT_ADPT SalADC3MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_ADC_HND_PRIV SalADC3HndPriv; + + SRAM_BF_DATA_SECTION + HAL_ADC_INIT_DAT HalADC3InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC3IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalADC3GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalADC3GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE ADC3GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_ADC_USER_CB SalADC3UserCB; + + SRAM_BF_DATA_SECTION + SAL_ADC_USERCB_ADPT SalADC3UserCBAdpt[SAL_ADC_USER_CB_NUM]; +#endif +#endif /*#if ADC3_USED*/ + +/* Global variables */ +u8 SalAdcInitialFlag = 0; +#ifdef CONFIG_SOC_PS_MODULE +u8 SalAdcEnableState = 0; +#endif + +HAL_ADC_INIT_DAT SalAdcInitialDatKeep = {.ADCIdx = 0, + .ADCEn = 0, + .ADCEndian = 0, + .ADCBurstSz = 0, + .ADCCompOnly = 0, + .ADCOneShotEn = 0, + .ADCOverWREn = 0, + .ADCOneShotTD = 0, + .ADCCompCtrl = 0, + .ADCCompTD = 0, + .ADCDataRate = 0, + .ADCAudioEn = 0, + .ADCEnManul = 0, + .ADCDbgSel = 0, + .RSVD0 = 0, + .ADCData = (u32 *)NULL, + .ADCPWCtrl = 0, + .ADCIntrMSK = 0}; + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetMngtAdpt +// +// Description: +// According to the input index, all the memory space are allocated and all the +// related pointers are assigned. The management adapter pointer will be +// returned. +// +// Arguments: +// [in] u8 I2CIdx - +// I2C module index +// +// Return: +// PSAL_I2C_MNGT_ADPT +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +VOID HalADCOpInit( + IN VOID *Data +) +{ + PHAL_ADC_OP pHalAdcOp = (PHAL_ADC_OP) Data; + + pHalAdcOp->HalADCInit = HalADCInit8195a; + pHalAdcOp->HalADCDeInit = HalADCDeInit8195a; + pHalAdcOp->HalADCEnable = HalADCEnableRtl8195a; + pHalAdcOp->HalADCReceive = HalADCReceiveRtl8195a; + pHalAdcOp->HalADCIntrCtrl = HalADCIntrCtrl8195a; + pHalAdcOp->HalADCReadReg = HalADCReadRegRtl8195a; +} + +#ifndef CONFIG_MBED_ENABLED +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetMngtAdpt +// +// Description: +// According to the input index, all the memory space are allocated and all the +// related pointers are assigned. The management adapter pointer will be +// returned. +// +// Arguments: +// [in] u8 I2CIdx - +// I2C module index +// +// Return: +// PSAL_I2C_MNGT_ADPT +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +#define sizealign4(x) ((sizeof(x) + 3) & (~3)) +PSAL_ADC_MNGT_ADPT +RtkADCGetMngtAdpt( + IN u8 ADCIdx +){ + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_USERCB_ADPT pSalADCUserCBAdpt = NULL; + + /* If the kernel is available, Memory-allocation is used. */ +#if (!ADC_STATIC_ALLOC) +#if 1 // pvvx + pSalADCMngtAdpt = (PSAL_ADC_MNGT_ADPT)RtlZmalloc( + sizealign4(SAL_ADC_MNGT_ADPT) + + sizealign4(SAL_ADC_HND_PRIV) + + sizealign4(HAL_ADC_INIT_DAT) + + sizealign4(HAL_ADC_OP) + + sizealign4(IRQ_HANDLE) + + sizealign4(SAL_ADC_USER_CB) + + sizealign4(HAL_GDMA_ADAPTER) + + sizealign4(HAL_GDMA_OP) + + sizealign4(IRQ_HANDLE) + + (sizealign4(SAL_ADC_USERCB_ADPT)*SAL_ADC_USER_CB_NUM)); + if(!pSalADCMngtAdpt) { + return pSalADCMngtAdpt; + }; + unsigned char *ptr = (unsigned char *)pSalADCMngtAdpt + sizeof(SAL_ADC_MNGT_ADPT); + pSalADCMngtAdpt->pSalHndPriv = (PSAL_ADC_HND_PRIV)ptr; + ptr += sizealign4(SAL_ADC_HND_PRIV); + pSalADCMngtAdpt->pHalInitDat = (PHAL_ADC_INIT_DAT)ptr; + ptr += sizealign4(HAL_ADC_INIT_DAT); + pSalADCMngtAdpt->pHalOp = (PHAL_ADC_OP)ptr; + ptr += sizealign4(HAL_ADC_OP); + pSalADCMngtAdpt->pIrqHnd = (PIRQ_HANDLE)ptr; + ptr += sizealign4(IRQ_HANDLE); + pSalADCMngtAdpt->pUserCB = (PSAL_ADC_USER_CB)ptr; + ptr += sizealign4(SAL_ADC_USER_CB); + pSalADCMngtAdpt->pHalGdmaAdp = (PHAL_GDMA_ADAPTER)ptr; + ptr += sizealign4(HAL_GDMA_ADAPTER); + pSalADCMngtAdpt->pHalGdmaOp = (PHAL_GDMA_OP)ptr; + ptr += sizealign4(HAL_GDMA_OP); + pSalADCMngtAdpt->pIrqGdmaHnd = (PIRQ_HANDLE)ptr; + ptr += sizealign4(IRQ_HANDLE); + pSalADCUserCBAdpt = (PSAL_ADC_USERCB_ADPT)ptr; +#else + pSalADCMngtAdpt = (PSAL_ADC_MNGT_ADPT)RtlZmalloc(sizeof(SAL_ADC_MNGT_ADPT)); + pSalADCMngtAdpt->pSalHndPriv = (PSAL_ADC_HND_PRIV)RtlZmalloc(sizeof(SAL_ADC_HND_PRIV)); + pSalADCMngtAdpt->pHalInitDat = (PHAL_ADC_INIT_DAT)RtlZmalloc(sizeof(HAL_ADC_INIT_DAT)); + pSalADCMngtAdpt->pHalOp = (PHAL_ADC_OP)RtlZmalloc(sizeof(HAL_ADC_OP)); + pSalADCMngtAdpt->pIrqHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalADCMngtAdpt->pUserCB = (PSAL_ADC_USER_CB)RtlZmalloc(sizeof(SAL_ADC_USER_CB)); + pSalADCMngtAdpt->pHalGdmaAdp = (PHAL_GDMA_ADAPTER)RtlZmalloc(sizeof(HAL_GDMA_ADAPTER)); + pSalADCMngtAdpt->pHalGdmaOp = (PHAL_GDMA_OP)RtlZmalloc(sizeof(HAL_GDMA_OP)); + pSalADCMngtAdpt->pIrqGdmaHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalADCUserCBAdpt = (PSAL_ADC_USERCB_ADPT)RtlZmalloc((sizeof(SAL_ADC_USERCB_ADPT)*SAL_ADC_USER_CB_NUM)); +#endif +#else + switch (ADCIdx){ + case ADC0_SEL: + { + pSalADCMngtAdpt = &SalADC0MngtAdpt; + pSalADCMngtAdpt->pSalHndPriv = &SalADC0HndPriv; + pSalADCMngtAdpt->pHalInitDat = &HalADC0InitData; + pSalADCMngtAdpt->pHalOp = &HalADCOpSAL; + pSalADCMngtAdpt->pIrqHnd = &ADC0IrqHandleDat; + pSalADCMngtAdpt->pHalGdmaAdp = &HalADC0GdmaAdpt; + pSalADCMngtAdpt->pHalGdmaOp = &HalADC0GdmaOp; + pSalADCMngtAdpt->pIrqGdmaHnd = &ADC0GDMAIrqHandleDat; + pSalADCMngtAdpt->pUserCB = &SalADC0UserCB; + pSalADCUserCBAdpt = &SalADC0UserCBAdpt; + break; + } + + case ADC1_SEL: + { + pSalADCMngtAdpt = &SalADC1MngtAdpt; + pSalADCMngtAdpt->pSalHndPriv = &SalADC1HndPriv; + pSalADCMngtAdpt->pHalInitDat = &HalADC1InitData; + pSalADCMngtAdpt->pHalOp = &HalADCOpSAL; + pSalADCMngtAdpt->pIrqHnd = &ADC1IrqHandleDat; + pSalADCMngtAdpt->pHalGdmaAdp = &HalADC1GdmaAdpt; + pSalADCMngtAdpt->pHalGdmaOp = &HalADC1GdmaOp; + pSalADCMngtAdpt->pIrqGdmaHnd = &ADC1GDMAIrqHandleDat; + pSalADCMngtAdpt->pUserCB = &SalADC1UserCB; + pSalADCUserCBAdpt = &SalADC1UserCBAdpt; + break; + } + + case ADC2_SEL: + { + pSalADCMngtAdpt = &SalADC2MngtAdpt; + pSalADCMngtAdpt->pSalHndPriv = &SalADC2HndPriv; + pSalADCMngtAdpt->pHalInitDat = &HalADC2InitData; + pSalADCMngtAdpt->pHalOp = &HalADCOpSAL; + pSalADCMngtAdpt->pIrqHnd = &ADC2IrqHandleDat; + pSalADCMngtAdpt->pHalGdmaAdp = &HalADC2GdmaAdpt; + pSalADCMngtAdpt->pHalGdmaOp = &HalADC2GdmaOp; + pSalADCMngtAdpt->pIrqGdmaHnd = &ADC2GDMAIrqHandleDat; + pSalADCMngtAdpt->pUserCB = &SalADC2UserCB; + pSalADCUserCBAdpt = &SalADC2UserCBAdpt; + break; + } + + case ADC3_SEL: + { + pSalADCMngtAdpt = &SalADC3MngtAdpt; + pSalADCMngtAdpt->pSalHndPriv = &SalADC3HndPriv; + pSalADCMngtAdpt->pHalInitDat = &HalADC3InitData; + pSalADCMngtAdpt->pHalOp = &HalADCOpSAL; + pSalADCMngtAdpt->pIrqHnd = &ADC3IrqHandleDat; + pSalADCMngtAdpt->pHalGdmaAdp = &HalADC3GdmaAdpt; + pSalADCMngtAdpt->pHalGdmaOp = &HalADC3GdmaOp; + pSalADCMngtAdpt->pIrqGdmaHnd = &ADC3GDMAIrqHandleDat; + pSalADCMngtAdpt->pUserCB = &SalADC3UserCB; + pSalADCUserCBAdpt = &SalADC3UserCBAdpt; + break; + } + default + break; + } +#endif + + /*To assign user callback pointers*/ + pSalADCMngtAdpt->pUserCB->pTXCB = pSalADCUserCBAdpt; + pSalADCMngtAdpt->pUserCB->pTXCCB = (pSalADCUserCBAdpt+1); + pSalADCMngtAdpt->pUserCB->pRXCB = (pSalADCUserCBAdpt+2); + pSalADCMngtAdpt->pUserCB->pRXCCB = (pSalADCUserCBAdpt+3); + pSalADCMngtAdpt->pUserCB->pRDREQCB = (pSalADCUserCBAdpt+4); + pSalADCMngtAdpt->pUserCB->pERRCB = (pSalADCUserCBAdpt+5); + pSalADCMngtAdpt->pUserCB->pDMATXCB = (pSalADCUserCBAdpt+6); + pSalADCMngtAdpt->pUserCB->pDMATXCCB = (pSalADCUserCBAdpt+7); + pSalADCMngtAdpt->pUserCB->pDMARXCB = (pSalADCUserCBAdpt+8); + pSalADCMngtAdpt->pUserCB->pDMARXCCB = (pSalADCUserCBAdpt+9); + + /*To assign the rest pointers*/ + pSalADCMngtAdpt->pSalHndPriv->ppSalADCHnd = (void**)&(pSalADCMngtAdpt->pSalHndPriv); + + /* To assign the default (ROM) HAL OP initialization function */ + pSalADCMngtAdpt->pHalOpInit = &HalADCOpInit; + + /* To assign the default (ROM) HAL GDMA OP initialization function */ + pSalADCMngtAdpt->pHalGdmaOpInit = &HalGdmaOpInit; + + /* To assign the default (ROM) SAL interrupt function */ + pSalADCMngtAdpt->pSalIrqFunc = &ADCISRHandle; + + /* To assign the default (ROM) SAL DMA TX interrupt function */ + pSalADCMngtAdpt->pSalDMAIrqFunc = &ADCGDMAISRHandle; + + return pSalADCMngtAdpt; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CFreeMngtAdpt +// +// Description: +// Free all the previous allocated memory space. +// +// Arguments: +// [in] PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt - +// I2C SAL management adapter pointer +// +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the RtkI2CFreeMngtAdpt succeeded. +// _EXIT_FAILURE if the RtkI2CFreeMngtAdpt failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkADCFreeMngtAdpt( + IN PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt +){ +#ifdef CONFIG_KERNEL +#if 1 // pvvx + RtlMfree((u8 *)pSalADCMngtAdpt, + sizealign4(SAL_ADC_MNGT_ADPT) + + sizealign4(SAL_ADC_HND_PRIV) + + sizealign4(HAL_ADC_INIT_DAT) + + sizealign4(HAL_ADC_OP) + + sizealign4(IRQ_HANDLE) + + sizealign4(SAL_ADC_USER_CB) + + sizealign4(HAL_GDMA_ADAPTER) + + sizealign4(HAL_GDMA_OP) + + sizealign4(IRQ_HANDLE) + + (sizealign4(SAL_ADC_USERCB_ADPT)*SAL_ADC_USER_CB_NUM)); +#else + RtlMfree((u8 *)pSalADCMngtAdpt->pUserCB->pTXCB, (sizeof(SAL_ADC_USERCB_ADPT)*SAL_ADC_USER_CB_NUM)); + RtlMfree((u8 *)pSalADCMngtAdpt->pIrqGdmaHnd, sizeof(IRQ_HANDLE)); + RtlMfree((u8 *)pSalADCMngtAdpt->pHalGdmaOp, sizeof(HAL_GDMA_OP)); + RtlMfree((u8 *)pSalADCMngtAdpt->pHalGdmaAdp, sizeof(HAL_GDMA_ADAPTER)); + RtlMfree((u8 *)pSalADCMngtAdpt->pUserCB, sizeof(SAL_ADC_USER_CB)); + RtlMfree((u8 *)pSalADCMngtAdpt->pIrqHnd, sizeof(IRQ_HANDLE)); + RtlMfree((u8 *)pSalADCMngtAdpt->pHalOp, sizeof(HAL_ADC_OP)); + RtlMfree((u8 *)pSalADCMngtAdpt->pHalInitDat, sizeof(HAL_ADC_INIT_DAT)); + RtlMfree((u8 *)pSalADCMngtAdpt->pSalHndPriv, sizeof(SAL_ADC_HND_PRIV)); + RtlMfree((u8 *)pSalADCMngtAdpt, sizeof(SAL_ADC_MNGT_ADPT)); +#endif +#else + ; +#endif + + return _EXIT_SUCCESS; +} +#endif + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// I2CISRHandle +// +// Description: +// I2C Interrupt Service Routine. +// According to the input pointer to SAL_I2C_HND, all the rest pointers will be +// found and be used to the rest part of this servie routine. +// The following types of interrupt will be taken care: +// - General Call (providing General Call Callback). Slave receives a general call. +// - STOP Bit (NOT providing General Call Callback) +// - START Bit (NOTproviding General Call Callback) +// - I2C Activity (NOTproviding General Call Callback) +// - RX Done (providing Error Callback). The slave transmitter does NOT +// receive a proper NACK for the end of whole transfer. +// - TX Abort (providing Error Call Callback). The Master/Slave +// transmitting is terminated. +// - RD Req (providing TX and TXC Callback). Slave gets a Read Request +// and starts a slave-transmitter operation. The slave transmit +// data will be written into slave TX FIFO from user data buffer. +// - TX Empty (providing TX and TXC Callback). Master TX FIFO is empty. +// The user transmit data will be written into master TX FIFO +// from user data buffer. +// - TX Over (providing Error Callback). Master TX FIFO is Overflow. +// - RX Full (providing RX and RXC Callback). Master/Slave RX FIFO contains +// data. And the received data will be put into Master/Slave user +// receive data buffer. +// - RX Over (providing Error Callback). Master/Slave RX FIFO is Overflow. +// - RX Under (providing Error Callback). Master/Slave RX FIFO is Underflow. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// NA +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//---------------------------------------------------------------------------------------------------- +VOID +ADCISRHandle( + IN VOID *Data +){ +#ifdef CONFIG_DEBUG_LOG_ADC_HAL + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_ADC_INIT_DAT pHalADCInitDat = NULL; + PHAL_ADC_OP pHalADCOP = NULL; + PSAL_ADC_USER_CB pSalADCUserCB = NULL; + u8 ADCIrqIdx; + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + pHalADCInitDat = pSalADCMngtAdpt->pHalInitDat; + pHalADCOP = pSalADCMngtAdpt->pHalOp; + ADCIrqIdx = pHalADCInitDat->ADCIdx; + pSalADCUserCB = pSalADCHND->pUserCB; + + DBG_8195A_ADC_LVL(HAL_ADC_LVL,"ADC INTR STS:%x\n",pHalADCOP->HalADCReadReg(pHalADCInitDat, REG_ADC_INTR_STS)); +#else + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_ADC_INIT_DAT pHalADCInitDat = NULL; + PHAL_ADC_OP pHalADCOP = NULL; + + //u8 ADCIrqIdx; + + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + pHalADCInitDat = pSalADCMngtAdpt->pHalInitDat; + pHalADCOP = pSalADCMngtAdpt->pHalOp; + //ADCIrqIdx = pHalADCInitDat->ADCIdx; + + DBG_ADC_INFO("ADC INTR STS:%x\n",pHalADCOP->HalADCReadReg(pHalADCInitDat, REG_ADC_INTR_STS)); + if (pSalADCHND->OpType == ADC_RDREG_TYPE){ + ADCFullStsFlag = 1; + ADCDatBuf[0] = (u32)HAL_ADC_READ32(REG_ADC_FIFO_READ); + ADCDatBuf[1] = (u32)HAL_ADC_READ32(REG_ADC_FIFO_READ); + pSalADCHND->pInitDat->ADCIntrMSK = 0; + pHalADCOP->HalADCIntrCtrl(pSalADCHND->pInitDat); + } + else + pHalADCOP->HalADCReadReg(pHalADCInitDat, REG_ADC_INTR_STS); + +#endif +} + +VOID +ADCGDMAISRHandle( + IN VOID *Data +){ + + /* DBG_ENTRANCE; */ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + + PHAL_ADC_OP pHalADCOP = NULL; + PSAL_ADC_USER_CB pSalADCUserCB = NULL; + + PHAL_GDMA_ADAPTER pHalADCGdmaAdapter; + PHAL_GDMA_OP pHalADCGdmaOp; + + + u8 IsrTypeMap = 0; + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHalADCOP = pSalADCMngtAdpt->pHalOp; + + pSalADCUserCB = pSalADCHND->pUserCB; + + pHalADCGdmaAdapter = pSalADCMngtAdpt->pHalGdmaAdp; + pHalADCGdmaOp = pSalADCMngtAdpt->pHalGdmaOp; + + DBG_8195A_ADC_LVL(HAL_ADC_LVL,"%s\n",__func__); + + if ((pHalADCGdmaAdapter->MaxMuliBlock) == pHalADCGdmaAdapter->MuliBlockCunt+1) { + pSalADCHND->pInitDat->ADCIntrMSK = 0; + pHalADCOP->HalADCIntrCtrl(pSalADCHND->pInitDat); + + /* Clear ADC Status */ + HAL_ADC_READ32(REG_ADC_INTR_STS); + + pSalADCHND->pInitDat->ADCEn = ADC_DISABLE; + pHalADCOP->HalADCEnable(pSalADCHND->pInitDat); + pHalADCGdmaOp->HalGdmaChCleanAutoSrc(pHalADCGdmaAdapter); + pHalADCGdmaOp->HalGdmaChDis(pHalADCGdmaAdapter); + pSalADCHND->DevSts = ADC_STS_IDLE; + + if (pSalADCUserCB->pDMARXCCB->USERCB != NULL) { + pSalADCUserCB->pDMARXCCB->USERCB((VOID*)pSalADCUserCB->pDMARXCCB->USERData); + } + } + + //3 Clear Pending ISR + IsrTypeMap = pHalADCGdmaOp->HalGdmaChIsrClean((VOID*)pHalADCGdmaAdapter); + + //3 Maintain Block Count + if (IsrTypeMap & BlockType) { + pHalADCGdmaAdapter->MuliBlockCunt++; + } +} + +RTK_STATUS +RtkADCPinMuxInit( + IN PSAL_ADC_HND pSalADCHND +){ + + u32 ADCLocalTemp; + + /* Check the I2C index first */ + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + + ADCLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + ADCLocalTemp |= BIT25; + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2, ADCLocalTemp); + + /* Turn on DAC active clock */ + ACTCK_ADC_CCTRL(ON); + + /* Enable DAC0 module */ + ADC0_FCTRL(ON); + + return _EXIT_SUCCESS; + +} + +static RTK_STATUS +RtkADCPinMuxDeInit( + IN PSAL_ADC_HND pSalADCHND +){ + + u32 ADCLocalTemp; + + /* Check the I2C index first */ + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + + /* Turn on DAC active clock */ + ACTCK_ADC_CCTRL(OFF); + + /* Enable DAC1 module */ + ADC0_FCTRL(OFF); + + ADCLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + ADCLocalTemp &= (~BIT25); + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_SYSPLL_CTRL2,ADCLocalTemp); + return _EXIT_SUCCESS; +} + + +#if ADC_INTR_OP_TYPE +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqInit +// +// Description: +// I2C interrupt initialization function. +// For I2C interrupt operation mode, I2C module MUST register itself to the platform +// by providing the interrupt handler which contains interrupt input data (arguments), +// interrupt service routine, interrupt number, interrupt priority. And then the interrupt +// should be enabled. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkADCIrqInit( + IN PSAL_ADC_HND pSalADCHND +){ + + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PIRQ_HANDLE pIrqHandle = NULL; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + pIrqHandle = pSalADCMngtAdpt->pIrqHnd; +/* + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; +*/ + + pIrqHandle->Data = (u32)(pSalADCHND); + pIrqHandle->IrqNum = ADC_IRQ; + pIrqHandle->IrqFun = (IRQ_FUN)pSalADCMngtAdpt->pSalIrqFunc; + pIrqHandle->Priority = 5; + InterruptRegister(pIrqHandle); + InterruptEn(pIrqHandle); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqDeInit +// +// Description: +// I2C interrupt de-initialization function. +// According to the given I2C device number, the I2C interrupt will be unreigster +// from the platform and the relative interrupt handler will be cleared. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt de-initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqDeInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqDeInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkADCIrqDeInit( + IN PSAL_ADC_HND pSalADCHND +){ + + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PIRQ_HANDLE pIrqHandle = NULL; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + pIrqHandle = pSalADCMngtAdpt->pIrqHnd; +/* + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; +*/ + InterruptUnRegister(pIrqHandle); + return _EXIT_SUCCESS; + +} + +#endif + + +#if ADC_DMA_OP_TYPE +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqInit +// +// Description: +// I2C interrupt initialization function. +// For I2C interrupt operation mode, I2C module MUST register itself to the platform +// by providing the interrupt handler which contains interrupt input data (arguments), +// interrupt service routine, interrupt number, interrupt priority. And then the interrupt +// should be enabled. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkADCDMAInit( + IN PSAL_ADC_HND pSalADCHND +){ + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_GDMA_ADAPTER pHALADCGdmaAdpt = NULL; + PHAL_GDMA_OP pHALADCGdmaOp = NULL; + PIRQ_HANDLE pIrqHandleADCGdma = NULL; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHALADCGdmaAdpt = pSalADCMngtAdpt->pHalGdmaAdp; + pHALADCGdmaOp = pSalADCMngtAdpt->pHalGdmaOp; + pIrqHandleADCGdma = pSalADCMngtAdpt->pIrqGdmaHnd; +/* + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; +*/ + //HalGdmaOpInit(pHALADCGdmaOp); + pSalADCMngtAdpt->pHalGdmaOpInit(pHALADCGdmaOp); + _memset((void *)pHALADCGdmaAdpt, 0, sizeof(HAL_GDMA_ADAPTER)); + + pHALADCGdmaAdpt->GdmaCtl.IntEn = 1; + + //ADC RX DMA + pHALADCGdmaAdpt->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHALADCGdmaAdpt->GdmaCtl.DstTrWidth = TrWidthFourBytes; + pHALADCGdmaAdpt->GdmaCtl.SrcMsize = MsizeEight; + pHALADCGdmaAdpt->GdmaCtl.DestMsize = MsizeEight; + + pHALADCGdmaAdpt->GdmaCtl.Sinc = NoChange; + pHALADCGdmaAdpt->GdmaCtl.Dinc = IncType; + + pHALADCGdmaAdpt->GdmaCtl.Done = 1; + pHALADCGdmaAdpt->GdmaCtl.TtFc = (GDMA_CTL_TT_FC_TYPE)0x2; + + pHALADCGdmaAdpt->GdmaCfg.SrcPer = 12; + pHALADCGdmaAdpt->GdmaCfg.ReloadSrc = 1; + + pHALADCGdmaAdpt->MuliBlockCunt = 0; + pHALADCGdmaAdpt->MaxMuliBlock = 1;//MaxLlp; + + pHALADCGdmaAdpt->GdmaIsrType = (BlockType|TransferType|ErrType); + pHALADCGdmaAdpt->IsrCtrl = ENABLE; + pHALADCGdmaAdpt->GdmaOnOff = ON; + + pHALADCGdmaAdpt->ChNum = 4; + pHALADCGdmaAdpt->ChEn = GdmaCh4; + + pHALADCGdmaAdpt->TestItem = 3; + DBG_ADC_INFO("pSalADCHND->DevNum:%x\n",pSalADCHND->DevNum); + + pHALADCGdmaAdpt->GdmaIndex = 1; + pIrqHandleADCGdma->IrqNum = GDMA1_CHANNEL4_IRQ; + + /* GDMA interrupt register */ + pIrqHandleADCGdma->Data = (u32) (pSalADCHND); + pIrqHandleADCGdma->IrqFun = (IRQ_FUN) pSalADCMngtAdpt->pSalDMAIrqFunc; + pIrqHandleADCGdma->Priority = 6; + InterruptRegister(pIrqHandleADCGdma); + InterruptEn(pIrqHandleADCGdma); + + /* GDMA initialization */ + /* Enable the whole GDMA module first */ + if (pHALADCGdmaAdpt->GdmaIndex == 0) { + ACTCK_GDMA0_CCTRL(ON); + SLPCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + } + else { + ACTCK_GDMA1_CCTRL(ON); + SLPCK_GDMA1_CCTRL(ON); + GDMA1_FCTRL(ON); + } + + pHALADCGdmaOp->HalGdmaOnOff((VOID*)pHALADCGdmaAdpt); + pHALADCGdmaOp->HalGdmaChIsrEnAndDis((VOID*)pHALADCGdmaAdpt); + //pHALADCGdmaOp->HalGdmaChSeting((VOID*)pHALADCGdmaAdpt); + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqDeInit +// +// Description: +// I2C interrupt de-initialization function. +// According to the given I2C device number, the I2C interrupt will be unreigster +// from the platform and the relative interrupt handler will be cleared. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt de-initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqDeInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqDeInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkADCDMADeInit( + IN PSAL_ADC_HND pSalADCHND +){ + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + + PHAL_GDMA_ADAPTER pHALADCGdmaAdpt = NULL; + PHAL_GDMA_OP pHALADCGdmaOp = NULL; + PIRQ_HANDLE pIrqHandleADCGdma = NULL; + + /*To Get the SAL_I2C_MNGT_ADPT Pointer*/ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHALADCGdmaAdpt = pSalADCMngtAdpt->pHalGdmaAdp; + pHALADCGdmaOp = pSalADCMngtAdpt->pHalGdmaOp; + pIrqHandleADCGdma = pSalADCMngtAdpt->pIrqGdmaHnd; + + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + + //HalGdmaOpInit(pHALADCGdmaOp); + pSalADCMngtAdpt->pHalGdmaOpInit(pHALADCGdmaOp); + + pHALADCGdmaAdpt->IsrCtrl = DISABLE; + pHALADCGdmaOp->HalGdmaChIsrEnAndDis((VOID*)pHALADCGdmaAdpt); + pHALADCGdmaOp->HalGdmaChIsrClean((VOID*)pHALADCGdmaAdpt); + pHALADCGdmaOp->HalGdmaChDis((VOID*)pHALADCGdmaAdpt); + + InterruptUnRegister(pIrqHandleADCGdma); +#if 0 + _memset((void *)pIrqHandleDACGdma , 0, sizeof(IRQ_HANDLE)); + _memset((void *)pHALDACGdmaOp , 0, sizeof(HAL_GDMA_OP)); + _memset((void *)pHALDACGdmaAdpt , 0, sizeof(HAL_GDMA_ADAPTER)); +#endif + return _EXIT_SUCCESS; + +} +#endif + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInit +// +// Description: +// According to the given I2C index, the related SAL_I2C_MNGT_ADPT pointer used +// for retrieving each I2C data sturcture pointer will be reversely parsed first. +// Then, initializing I2C HAL operation, initializing I2C interrupt (if needed), +// initializing I2C DMA (if needed) and initializing I2C pinmux will be done. +// User specified I2C configuration will be assigned to I2C initial data structure +// (PHAL_I2C_INIT_DAT pHalI2CInitDat). I2C HAL initialization is executed after +// all the configuration data taken. +// In the end, I2C module is enabled as a final step of the whole initialization. +// For a slave ack General Call support, an additional step may be followed after +// the above steps. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// _EXIT_SUCCESS if the RtkI2CInit succeeded. +// _EXIT_FAILURE if the RtkI2CInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkADCInit( + IN VOID *Data +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_ADC_INIT_DAT pHalADCInitDat = NULL; + PHAL_ADC_OP pHalADCOP = NULL; + +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE adcPwrState; +#endif + + DBG_ADC_INFO("%s\n",__func__); + /* To Get the SAL_ADC_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHalADCInitDat = pSalADCMngtAdpt->pHalInitDat; + pHalADCOP = pSalADCMngtAdpt->pHalOp; + + /* Check the input I2C index first */ + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + +#if 0 + /* Check the input I2C operation type */ + if (RtkI2COpTypeChk(pSalI2CHND)) + return _EXIT_FAILURE; +#endif + + /* ADC Initial data check, if the setting is different from the previous initial data, + an warning is shown on Log-Uart and directly return from this function */ + if (SalAdcInitialFlag != 0) { + if (_memcmp(pHalADCInitDat, &SalAdcInitialDatKeep, sizeof(HAL_ADC_INIT_DAT))) { + pSalADCMngtAdpt->pHalOpInit(pHalADCOP); + /* DAC Device Status Update */ + pSalADCHND->DevSts = ADC_STS_IDLE; + DBG_ADC_WARN("The ADC initial value is different from the previous value.\n"); + } + } + else { + /* ADC Initialize HAL Operations */ + //HalADCOpInit(pHalADCOP); + pSalADCMngtAdpt->pHalOpInit(pHalADCOP); + + /* ADC Interrupt Initialization */ +#if ADC_INTR_OP_TYPE + RtkADCIrqInit(pSalADCHND); +#endif + + /* ADC DMA Initialization */ +#if ADC_DMA_OP_TYPE + RtkADCDMAInit(pSalADCHND); +#endif + + /* ADC Function and Clock Enable*/ + RtkADCPinMuxInit(pSalADCHND); + pHalADCOP->HalADCInit(pSalADCHND->pInitDat); + + if (pSalADCHND->OpType == ADC_DMA_TYPE){ + pSalADCHND->pInitDat->ADCIntrMSK = (BIT_ADC_FIFO_RD_REQ_EN | + BIT_ADC_FIFO_RD_ERROR_EN); + } + else if (pSalADCHND->OpType == ADC_INTR_TYPE){ + pSalADCHND->pInitDat->ADCIntrMSK = (BIT_ADC_FIFO_FULL_EN | + BIT_ADC_FIFO_RD_REQ_EN | + BIT_ADC_FIFO_RD_ERROR_EN); + } + else{ + pSalADCHND->pInitDat->ADCIntrMSK = 0; + } + + + if (pHalADCInitDat->ADCOneShotEn == ADC_FEATURE_ENABLED) { + pSalADCHND->pInitDat->ADCIntrMSK |= BIT_ADC_AWAKE_CPU_EN; + } + pHalADCOP->HalADCIntrCtrl(pSalADCHND->pInitDat); + + //pSalADCHND->pInitDat->ADCEn = ADC_ENABLE; + //pHalADCOP->HalADCEnable(pSalADCHND->pInitDat); + + if (pHalADCInitDat->ADCOneShotEn == ADC_FEATURE_ENABLED) { + HAL_TIMER_WRITE32(TIMER_INTERVAL, 30); + HAL_TIMER_WRITE32(0x1C, 3); + } + + SalAdcInitialFlag |= (0x01 << pSalADCHND->DevNum); + _memcpy(&SalAdcInitialDatKeep, pSalADCHND->pInitDat, sizeof(HAL_ADC_INIT_DAT)); + } + + /* DAC Device Status Update */ + pSalADCHND->DevSts = ADC_STS_IDLE; + +#ifdef CONFIG_SOC_PS_MODULE + // To register a new peripheral device power state + adcPwrState.FuncIdx = ADC0; + adcPwrState.PwrState = ACT; + RegPowerState(adcPwrState); + + SalAdcEnableState |= (0x01 << pSalADCHND->DevNum); +#endif + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInit +// +// Description: +// According to the given I2C index, the related SAL_I2C_MNGT_ADPT pointer used +// for retrieving each I2C data sturcture pointer will be reversely parsed first. +// Then, initializing I2C HAL operation, initializing I2C interrupt (if needed), +// initializing I2C DMA (if needed) and initializing I2C pinmux will be done. +// User specified I2C configuration will be assigned to I2C initial data structure +// (PHAL_I2C_INIT_DAT pHalI2CInitDat). I2C HAL initialization is executed after +// all the configuration data taken. +// In the end, I2C module is enabled as a final step of the whole initialization. +// For a slave ack General Call support, an additional step may be followed after +// the above steps. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// _EXIT_SUCCESS if the RtkI2CInit succeeded. +// _EXIT_FAILURE if the RtkI2CInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkADCDeInit( + IN VOID *Data +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_ADC_INIT_DAT pHalADCInitDat = NULL; + PHAL_ADC_OP pHalADCOP = NULL; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE adcPwrState; + u8 HwState; +#endif + + /* To Get the SAL_ADC_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHalADCInitDat = pSalADCMngtAdpt->pHalInitDat; + pHalADCOP = pSalADCMngtAdpt->pHalOp; + + /* Check the input ADC index first */ + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + + SalAdcInitialFlag &= (~(0x01 << pSalADCHND->DevNum)); + + if (SalAdcInitialFlag == 0) { +#ifdef CONFIG_SOC_PS_MODULE + adcPwrState.FuncIdx = ADC0; + QueryRegPwrState(adcPwrState.FuncIdx, &(adcPwrState.PwrState), &HwState); + + // if the power state isn't ACT, then switch the power state back to ACT first + if ((adcPwrState.PwrState != ACT) && (adcPwrState.PwrState != INACT)) { + RtkADCEnablePS(Data); + QueryRegPwrState(adcPwrState.FuncIdx, &(adcPwrState.PwrState), &HwState); + } + + if (adcPwrState.PwrState == ACT) { + adcPwrState.PwrState = INACT; + RegPowerState(adcPwrState); + } +#endif + + /* ADC Initialize HAL Operations */ + HalADCOpInit(pHalADCOP); + + RtkADCPinMuxDeInit(pSalADCHND); + + /* ADC Interrupt Initialization */ +#if ADC_INTR_OP_TYPE + RtkADCIrqDeInit(pSalADCHND); +#endif + + /* ADC DMA Initialization */ +#if ADC_DMA_OP_TYPE + RtkADCDMADeInit(pSalADCHND); +#endif + + pHalADCInitDat->ADCEn = ADC_DISABLE; + pHalADCOP->HalADCEnable(pHalADCInitDat); + pHalADCOP->HalADCDeInit(pHalADCInitDat); + + /* ADC Function and Clock Enable*/ + RtkADCPinMuxDeInit(pSalADCHND); + } + + return _EXIT_SUCCESS; +} + +u32 +RtkADCReceive( + IN VOID *Data +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_GDMA_ADAPTER pHALADCGdmaAdpt = NULL; + PHAL_GDMA_OP pHALADCGdmaOp = NULL; + + + + //PIRQ_HANDLE pIrqHandleADCGdma = NULL; + u32 AdcTempDat; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHALADCGdmaAdpt = pSalADCMngtAdpt->pHalGdmaAdp; + pHALADCGdmaOp = pSalADCMngtAdpt->pHalGdmaOp; + + + + if (pSalADCHND->OpType == ADC_DMA_TYPE) { + /* Clear ADC Status */ + HAL_ADC_READ32(REG_ADC_INTR_STS); + + HalGdmaOpInit(pHALADCGdmaOp); + pHALADCGdmaAdpt->GdmaCtl.BlockSize = pSalADCHND->pRXBuf->DataLen; + pHALADCGdmaAdpt->ChSar = (u32)(ADC_REG_BASE); + pHALADCGdmaAdpt->ChDar = (u32)pSalADCHND->pRXBuf->pDataBuf; + pHALADCGdmaAdpt->MuliBlockCunt = 0; + + pHALADCGdmaOp->HalGdmaChSeting(pHALADCGdmaAdpt); + + AdcTempDat = HAL_ADC_READ32(REG_ADC_POWER); + AdcTempDat |= BIT_ADC_PWR_AUTO; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + + pHALADCGdmaOp->HalGdmaChEn(pHALADCGdmaAdpt); + + pSalADCHND->DevSts = ADC_STS_RX_ING; + return _EXIT_SUCCESS; + } + return _EXIT_FAILURE; +} + +//extern u32 HalDelayUs(IN u32 us); + +u32 +RtkADCReceiveBuf( + IN VOID *Data, + IN u32 *pBuf +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PHAL_ADC_OP pHalADCOP = NULL; + + //PIRQ_HANDLE pIrqHandleADCGdma = NULL; + u32 AdcTempDat; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + pHalADCOP = pSalADCMngtAdpt->pHalOp; + + /* Clear ADC Status */ + //HAL_ADC_READ32(REG_ADC_INTR_STS); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_INTR_STS); + DBG_ADC_INFO("RtkADCReceiveBuf, INTR:%x\n", AdcTempDat); + //AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_INTR_STS); + //DBG_8195A(">>INTR:%x\n",AdcTempDat); + + ADCFullStsFlag = 0; +/// HalDelayUs(2000); ? + HalDelayUs(20); + + DBG_ADC_INFO("RtkADCReceiveBuf, Check to enable ADC manully or not\n"); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_POWER); + if (unlikely((AdcTempDat & BIT_ADC_ISO_MANUAL) == 0)) { + ; + } + else { + + pSalADCHND->pInitDat->ADCEn = ADC_ENABLE; + pHalADCOP->HalADCEnable(pSalADCHND->pInitDat); + //AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_POWER); + } + + pSalADCHND->pInitDat->ADCIntrMSK = (BIT_ADC_FIFO_FULL_EN); + pHalADCOP->HalADCIntrCtrl(pSalADCHND->pInitDat); + pSalADCHND->DevSts = ADC_STS_IDLE; + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + + if ((AdcTempDat & BIT_ADC_EN_MANUAL) == 0){ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCReceiveBuf, Before set, Reg AD1:%x\n", AdcTempDat); + AdcTempDat |= BIT_ADC_EN_MANUAL; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCReceiveBuf, After set, Reg AD1:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCReceiveBuf, Before set, Reg AD0:%x\n", AdcTempDat); + AdcTempDat |= BIT_ADC_EN_MANUAL; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCReceiveBuf, After set, Reg AD0:%x\n", AdcTempDat); + } + else{ + ; + } + + while (ADCFullStsFlag == 0){ + } + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCReceiveBuf, End of ADC, Before set, AD0:%x\n", AdcTempDat); + AdcTempDat &= (~BIT_ADC_EN_MANUAL); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCReceiveBuf, End of ADC, After set, AD0:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCReceiveBuf, End of ADC, Before set, AD1:%x\n", AdcTempDat); + AdcTempDat &= (~BIT_ADC_EN_MANUAL); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCReceiveBuf, End of ADC, After set, AD1:%x\n", AdcTempDat); + + /* Clear ADC Status */ + HAL_ADC_READ32(REG_ADC_INTR_STS); + ADCFullStsFlag = 0; + + *pBuf = (u32)ADCDatBuf[0]; + *(pBuf+1) = (u32)ADCDatBuf[1]; + ADCDatBuf[0] = 0; + ADCDatBuf[1] = 0; + + return _EXIT_SUCCESS; +} + + +u32 +RtkADCRxManualRotate( + IN VOID *Data, + IN u32 *pBuf +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + + PHAL_ADC_OP pHalADCOP = NULL; + + u32 AdcTempDat; + u16 tempcnt; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + pHalADCOP = pSalADCMngtAdpt->pHalOp; + + + /* Clear ADC Status */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_INTR_STS); + DBG_ADC_INFO("RtkADCRxManualRotate, INTR:%x\n", AdcTempDat); + + DBG_ADC_INFO("RtkADCRxManualRotate, Check to enable ADC manully or not\n"); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_POWER); + if (unlikely((AdcTempDat & BIT_ADC_ISO_MANUAL) == 0)) { + ; + } + else { + pSalADCHND->pInitDat->ADCEn = ADC_ENABLE; + pHalADCOP->HalADCEnable(pSalADCHND->pInitDat); + } + + + /* Comment when manual rotation + pSalADCHND->pInitDat->ADCIntrMSK = (BIT_ADC_FIFO_FULL_EN); + pHalADCOP->HalADCIntrCtrl(pSalADCHND->pInitDat); + */ + pSalADCHND->DevSts = ADC_STS_IDLE; + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + + if ((AdcTempDat & BIT_ADC_EN_MANUAL) == 0){ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, Before set, Reg AD1:%x\n", AdcTempDat); + /* Clear for manual rotrate first*/ + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + /* Enable filter */ + AdcTempDat |= (BIT0); + + /* Enable manual mode, this is to turn cali. off */ +// AdcTempDat &= ~(BIT11); + AdcTempDat |= (BIT11); + + /* Set rotation to default state + ad1[7][5][4][3][2][1]=100010=>000001=>000110=>001010=>010010 + */ + AdcTempDat |= (BIT7|BIT2); + //AdcTempDat |= (BIT4|BIT2); + + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, After set, Reg AD1:%x\n", AdcTempDat); + //DBG_8195A("1. Reg AD1:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, Before set, Reg AD0:%x\n", AdcTempDat); + AdcTempDat |= (0x01); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, After set, Reg AD0:%x\n", AdcTempDat); + } + else{ + ; + } + + /* Start rotation sequence, ad1[7][5][4][3][2][1]=000001 */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + AdcTempDat |= (BIT1); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + HalDelayUs(500); + + /* Start rotation sequence, ad1[7][5][4][3][2][1]=000110 */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + AdcTempDat |= (BIT3|BIT2); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + HalDelayUs(500); + + /* Read Content */ + for (tempcnt=0; tempcnt<16; tempcnt++){ + ADCDatBuf[0] = (u32)HAL_ADC_READ32(REG_ADC_FIFO_READ); + } + + /* Close ADC */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, Before set, AD0:%x\n", AdcTempDat); + AdcTempDat &= (~0x01); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, After set, AD0:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, Before set, AD1:%x\n", AdcTempDat); + AdcTempDat &= (~0x01); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, After set, AD1:%x\n", AdcTempDat); + + /* Clear ADC Status */ + HAL_ADC_READ32(REG_ADC_INTR_STS); + + /* Open ADC */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, Before set, Reg AD1:%x\n", AdcTempDat); + AdcTempDat |= (BIT0); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, After set, Reg AD1:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, Before set, Reg AD0:%x\n", AdcTempDat); + AdcTempDat |= BIT_ADC_EN_MANUAL; + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, After set, Reg AD0:%x\n", AdcTempDat); + + /* Start rotation sequence, ad1[7][5][4][3][2][1]=001010 */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + AdcTempDat |= (BIT4|BIT2); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + HalDelayUs(500); + + /* Start rotation sequence, ad1[7][5][4][3][2][1]=010010 */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + AdcTempDat |= (BIT5|BIT2); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + HalDelayUs(500); + + //DBG_8195A("INT STAT:%08x\n", HAL_ADC_READ32(REG_ADC_INTR_STS)); + /* Read ADC FIFO */ + /* Read Content */ + for (tempcnt=0; tempcnt<16; tempcnt++){ + ADCDatBuf[1] = (u32)HAL_ADC_READ32(REG_ADC_FIFO_READ); + } + + + /* Close ADC */ + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, Before set, AD0:%x\n", AdcTempDat); + AdcTempDat &= (~BIT_ADC_EN_MANUAL); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD0); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, After set, AD0:%x\n", AdcTempDat); + + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, Before set, AD1:%x\n", AdcTempDat); + AdcTempDat &= (~BIT0); + + /* Disable manual mode */ + AdcTempDat &= (~BIT11); + /* Set roration to default state */ + AdcTempDat &= ~(BIT7|BIT5|BIT4|BIT3|BIT2|BIT1); + + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, AdcTempDat); + AdcTempDat = (u32)HAL_ADC_READ32(REG_ADC_ANAPAR_AD1); + DBG_ADC_INFO("RtkADCRxManualRotate, End of ADC, After set, AD1:%x\n", AdcTempDat); + + /* Clear ADC Status */ + HAL_ADC_READ32(REG_ADC_INTR_STS); + ADCFullStsFlag = 0; + + *pBuf = (u32)ADCDatBuf[0]; + *(pBuf+1) = (u32)ADCDatBuf[1]; + ADCDatBuf[0] = 0; + ADCDatBuf[1] = 0; + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetSalHnd +// +// Description: +// Allocation of lower layer memory spaces will be done by invoking RtkI2CGetMngtAdpt +// in this function and return a SAL_I2C_HND pointer to upper layer. +// According to the given I2C index, RtkI2CGetMngtAdpt will allocate all the memory +// space such as SAL_I2C_HND, HAL_I2C_INIT_DAT, SAL_I2C_USER_CB etc. +// +// +// Arguments: +// [in] u8 I2CIdx - +// I2C Index +// +// Return: +// PSAL_I2C_HND +// A pointer to SAL_I2C_HND which is allocated in the lower layer. +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +PSAL_ADC_HND +RtkADCGetSalHnd( + IN u8 ADCIdx +){ + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_HND pSalADCHND = NULL; + + /* Check the user define setting and the given index */ + if (RtkADCIdxChk(ADCIdx)) { + return (PSAL_ADC_HND)NULL; + } + + /* Invoke RtkI2CGetMngtAdpt to get the I2C SAL management adapter pointer */ + pSalADCMngtAdpt = RtkADCGetMngtAdpt(ADCIdx); + + /* Assign the private SAL handle to public SAL handle */ + pSalADCHND = &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); + + /* Assign the internal HAL initial data pointer to the SAL handle */ + pSalADCHND->pInitDat = pSalADCMngtAdpt->pHalInitDat; + + /* Assign the internal user callback pointer to the SAL handle */ + pSalADCHND->pUserCB = pSalADCMngtAdpt->pUserCB; + + return &(pSalADCMngtAdpt->pSalHndPriv->SalADCHndPriv); + +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetSalHnd +// +// Description: +// Allocation of lower layer memory spaces will be done by invoking RtkI2CGetMngtAdpt +// in this function and return a SAL_I2C_HND pointer to upper layer. +// According to the given I2C index, RtkI2CGetMngtAdpt will allocate all the memory +// space such as SAL_I2C_HND, HAL_I2C_INIT_DAT, SAL_I2C_USER_CB etc. +// +// +// Arguments: +// [in] u8 I2CIdx - +// I2C Index +// +// Return: +// PSAL_I2C_HND +// A pointer to SAL_I2C_HND which is allocated in the lower layer. +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkADCFreeSalHnd( + IN PSAL_ADC_HND pSalADCHND +){ + PSAL_ADC_MNGT_ADPT pSalADCMngtAdpt = NULL; + PSAL_ADC_HND_PRIV pSalADCHNDPriv = NULL; + + /* To get the SAL_DAC_MNGT_ADPT pointer */ + pSalADCHNDPriv = CONTAINER_OF(pSalADCHND, SAL_ADC_HND_PRIV, SalADCHndPriv); + pSalADCMngtAdpt = CONTAINER_OF(pSalADCHNDPriv->ppSalADCHnd, SAL_ADC_MNGT_ADPT, pSalHndPriv); + + /* Invoke RtkDACFreeMngtAdpt to free all the lower layer memory space */ + return (RtkADCFreeMngtAdpt(pSalADCMngtAdpt)); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CLoadDefault +// +// Description: +// Accrording the given I2C index, the default I2C configuration is done. +// +// +// Arguments: +// [in] PSAL_I2C_HND pSalI2CHND - +// SAL I2C handle +// +// Return: +// The status of the loading I2C default configuration. +// _EXIT_SUCCESS if the RtkI2CLoadDefault succeeded. +// _EXIT_FAILURE if the RtkI2CLoadDefault failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkADCLoadDefault( + IN VOID *Data +){ + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + + /* Check the input ADC index first */ + if (RtkADCIdxChk(pSalADCHND->DevNum)) + return _EXIT_FAILURE; + + /* Load SAL handle default value */ + pSalADCHND->PinMux = 0; + pSalADCHND->OpType = ADC_RDREG_TYPE; + pSalADCHND->DevSts = ADC_STS_UNINITIAL; + pSalADCHND->ADCExd = 0; + pSalADCHND->ErrType = (u32)NULL; + + /* Load HAL initial data structure default value */ + pSalADCHND->pInitDat->ADCIdx = pSalADCHND->DevNum; + pSalADCHND->pInitDat->ADCEn = ADC_DISABLE; + pSalADCHND->pInitDat->ADCEndian = ADC_DATA_ENDIAN_LITTLE; + pSalADCHND->pInitDat->ADCBurstSz = 8; + pSalADCHND->pInitDat->ADCCompOnly = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCOneShotEn = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCOverWREn = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCOneShotTD = 8; + pSalADCHND->pInitDat->ADCCompCtrl = ADC_COMP_SMALLER_THAN; + pSalADCHND->pInitDat->ADCCompTD = 8; + pSalADCHND->pInitDat->ADCDataRate = 0; + pSalADCHND->pInitDat->ADCAudioEn = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCEnManul = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCDbgSel = ADC_DBG_SEL_DISABLE; + pSalADCHND->pInitDat->ADCPWCtrl = 0; + pSalADCHND->pInitDat->ADCIntrMSK = ADC_FEATURE_DISABLED; + pSalADCHND->pInitDat->ADCAnaParAd3 = 0; + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkADCDisablePS +// +// Description: +// ADC disable opertion by setting clock disable. +// +// Arguments: +// [in] VOID *Data - +// ADC SAL handle +// +// Return: +// The status of the ADC disable process. +// HAL_OK if the RtkADCDisablePS succeeded. +// HAL_ERR_PARA if the RtkADCDisablePS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-06-15. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkADCDisablePS( + IN VOID *Data +){ + + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + u8 adcIdx = pSalADCHND->DevNum; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE adcPwrState; +#endif + + if (RtkADCIdxChk(adcIdx)) + return HAL_ERR_UNKNOWN; + + +#ifdef CONFIG_SOC_PS_MODULE + SalAdcEnableState &= (~(0x01 << pSalADCHND->DevNum)); + + if (SalAdcEnableState == 0) { + // To register a new peripheral device power state + adcPwrState.FuncIdx = ADC0; + adcPwrState.PwrState = SLPCG; + RegPowerState(adcPwrState); + } +#endif + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkADCEnablePS +// +// Description: +// ADC enable opertion by setting clock enable. +// +// Arguments: +// [in] VOID *Data - +// ADC SAL handle +// +// Return: +// The status of the ADC enable process. +// HAL_OK if the RtkADCEnablePS succeeded. +// HAL_ERR_PARA if the RtkADCEnablePS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-06-15. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkADCEnablePS( + IN VOID *Data +){ + + PSAL_ADC_HND pSalADCHND = (PSAL_ADC_HND) Data; + u8 adcIdx = pSalADCHND->DevNum; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE adcPwrState; +#endif + + if (RtkADCIdxChk(adcIdx)) + return HAL_ERR_UNKNOWN; + +#ifdef CONFIG_SOC_PS_MODULE + SalAdcEnableState |= (0x01 << pSalADCHND->DevNum); + + // To register a new peripheral device power state + adcPwrState.FuncIdx = ADC0; + adcPwrState.PwrState = ACT; + RegPowerState(adcPwrState); +#endif + + return HAL_OK; +} + +#endif // CONFIG_ADC_EN + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_common.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_common.c new file mode 100644 index 0000000..6594168 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_common.c @@ -0,0 +1,23 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "hal_common.h" + +extern HAL_TIMER_OP HalTimerOp; + +HAL_Status +HalCommonInit(void){ + +#ifdef CONFIG_TIMER_MODULE + HalTimerOpInit_Patch((VOID*)(&HalTimerOp)); +#endif + + return HAL_OK; +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_dac.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_dac.c new file mode 100644 index 0000000..81d1382 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_dac.c @@ -0,0 +1,1561 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "rtl_utility.h" +#include "osdep_api.h" +#include "hal_dac.h" +#include "hal_gdma.h" + +#ifdef CONFIG_DAC_EN +#define DAC_STATIC_ALLOC 0 + +/* DAC SAL global variables declaration when kernel disabled */ + +#if DAC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + HAL_DAC_OP HalDACOpSAL; +#endif + + +#if DAC0_USED /*#if DAC0_USED*/ +#if DAC_STATIC_ALLOC + SRAM_BF_DATA_SECTION + SAL_DAC_MNGT_ADPT SalDAC0MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_DAC_HND_PRIV SalDAC0HndPriv; + + SRAM_BF_DATA_SECTION + HAL_DAC_INIT_DAT HalDAC0InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE DAC0IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalDAC0GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalDAC0GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE DAC0GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_DAC_USER_CB SalDAC0UserCB; + + SRAM_BF_DATA_SECTION + SAL_DAC_DMA_USER_DEF SalDAC0DmaUserDef; + + SRAM_BF_DATA_SECTION + SAL_DAC_USERCB_ADPT SalDAC0UserCBAdpt[SAL_DAC_USER_CB_NUM]; +#endif +#endif /*#if DAC0_USED*/ + +#if DAC1_USED /*#if DAC1_USED*/ +#if DAC_STATIC_ALLOC + + SRAM_BF_DATA_SECTION + SAL_DAC_MNGT_ADPT SalDAC1MngtAdpt; + + SRAM_BF_DATA_SECTION + SAL_DAC_HND_PRIV SalDAC1HndPriv; + + SRAM_BF_DATA_SECTION + HAL_DAC_INIT_DAT HalDAC1InitData; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE DAC1IrqHandleDat; + + SRAM_BF_DATA_SECTION + HAL_GDMA_ADAPTER HalDAC1GdmaAdpt; + + SRAM_BF_DATA_SECTION + HAL_GDMA_OP HalDAC1GdmaOp; + + SRAM_BF_DATA_SECTION + IRQ_HANDLE DAC1GDMAIrqHandleDat; + + SRAM_BF_DATA_SECTION + SAL_DAC_USER_CB SalDAC1UserCB; + + SRAM_BF_DATA_SECTION + SAL_DAC_DMA_USER_DEF SalDAC1DmaUserDef; + + SRAM_BF_DATA_SECTION + SAL_DAC_USERCB_ADPT SalDAC1UserCBAdpt[SAL_DAC_USER_CB_NUM]; +#endif +#endif /*#if DAC1_USED*/ + +/* Function prototype */ +VOID DACISRHandle(IN VOID *Data); +VOID DACGDMAISRHandle(IN VOID * Data); +VOID DACGDMALLPISRHandle(IN VOID *Data); + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetMngtAdpt +// +// Description: +// According to the input index, all the memory space are allocated and all the +// related pointers are assigned. The management adapter pointer will be +// returned. +// +// Arguments: +// [in] u8 I2CIdx - +// I2C module index +// +// Return: +// PSAL_I2C_MNGT_ADPT +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +VOID HalDACOpInit( + IN VOID *Data +) +{ + PHAL_DAC_OP pHalDacOp = (PHAL_DAC_OP) Data; + + pHalDacOp->HalDACInit = HalDACInit8195a; + pHalDacOp->HalDACDeInit = HalDACDeInit8195a; + pHalDacOp->HalDACEnable = HalDACEnableRtl8195a; + pHalDacOp->HalDACSend = HalDACSendRtl8195a; + pHalDacOp->HalDACIntrCtrl = HalDACIntrCtrl8195a; + pHalDacOp->HalDACReadReg = HalDACReadRegRtl8195a; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetMngtAdpt +// +// Description: +// According to the input index, all the memory space are allocated and all the +// related pointers are assigned. The management adapter pointer will be +// returned. +// +// Arguments: +// [in] u8 I2CIdx - +// I2C module index +// +// Return: +// PSAL_I2C_MNGT_ADPT +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +PSAL_DAC_MNGT_ADPT +RtkDACGetMngtAdpt( + IN u8 DACIdx +){ + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PSAL_DAC_USERCB_ADPT pSalDACUserCBAdpt = NULL; + + /* If the kernel is available, Memory-allocation is used. */ +#if !DAC_STATIC_ALLOC + + pSalDACMngtAdpt = (PSAL_DAC_MNGT_ADPT)RtlZmalloc(sizeof(SAL_DAC_MNGT_ADPT)); + pSalDACMngtAdpt->pSalHndPriv = (PSAL_DAC_HND_PRIV)RtlZmalloc(sizeof(SAL_DAC_HND_PRIV)); + pSalDACMngtAdpt->pHalInitDat = (PHAL_DAC_INIT_DAT)RtlZmalloc(sizeof(HAL_DAC_INIT_DAT)); + pSalDACMngtAdpt->pHalOp = (PHAL_DAC_OP)RtlZmalloc(sizeof(HAL_DAC_OP)); + pSalDACMngtAdpt->pIrqHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalDACMngtAdpt->pUserCB = (PSAL_DAC_USER_CB)RtlZmalloc(sizeof(SAL_DAC_USER_CB)); + pSalDACMngtAdpt->pDMAConf = (PSAL_DAC_DMA_USER_DEF)RtlZmalloc(sizeof(SAL_DAC_DMA_USER_DEF)); + pSalDACMngtAdpt->pHalGdmaAdp = (PHAL_GDMA_ADAPTER)RtlZmalloc(sizeof(HAL_GDMA_ADAPTER)); + pSalDACMngtAdpt->pHalGdmaOp = (PHAL_GDMA_OP)RtlZmalloc(sizeof(HAL_GDMA_OP)); + pSalDACMngtAdpt->pIrqGdmaHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalDACUserCBAdpt = (PSAL_DAC_USERCB_ADPT)RtlZmalloc((sizeof(SAL_DAC_USERCB_ADPT)*SAL_DAC_USER_CB_NUM)); +#else + switch (DACIdx){ + case DAC0_SEL: + { + pSalDACMngtAdpt = &SalDAC0MngtAdpt; + pSalDACMngtAdpt->pSalHndPriv = &SalDAC0HndPriv; + pSalDACMngtAdpt->pHalInitDat = &HalDAC0InitData; + pSalDACMngtAdpt->pHalOp = &HalDACOpSAL; + pSalDACMngtAdpt->pIrqHnd = &DAC0IrqHandleDat; + pSalDACMngtAdpt->pUserCB = &SalDAC0UserCB; + pSalDACMngtAdpt->pDMAConf = &SalDAC0DmaUserDef; + pSalDACMngtAdpt->pHalGdmaAdp = &HalDAC0GdmaAdpt; + pSalDACMngtAdpt->pHalGdmaOp = &HalDAC0GdmaOp; + pSalDACMngtAdpt->pIrqGdmaHnd = &DAC0IrqHandleDat; + pSalDACUserCBAdpt = &SalDAC0UserCBAdpt; + break; + } + + case DAC1_SEL: + { + pSalDACMngtAdpt = &SalDAC1MngtAdpt; + pSalDACMngtAdpt->pSalHndPriv = &SalDAC1HndPriv; + pSalDACMngtAdpt->pHalInitDat = &HalDAC1InitData; + pSalDACMngtAdpt->pHalOp = &HalDACOpSAL; + pSalDACMngtAdpt->pIrqHnd = &DAC1IrqHandleDat; + pSalDACMngtAdpt->pUserCB = &SalDAC1UserCB; + pSalDACMngtAdpt->pDMAConf = &SalDAC1DmaUserDef; + pSalDACMngtAdpt->pHalGdmaAdp = &HalDAC1GdmaAdpt; + pSalDACMngtAdpt->pHalGdmaOp = &HalDAC1GdmaOp; + pSalDACMngtAdpt->pIrqGdmaHnd = &DAC1IrqHandleDat; + pSalDACUserCBAdpt = &SalDAC1UserCBAdpt; + break; + } + + default: + break; + } +#endif + + /*To assign user callback pointers*/ + pSalDACMngtAdpt->pUserCB->pTXCB = pSalDACUserCBAdpt; + pSalDACMngtAdpt->pUserCB->pTXCCB = (pSalDACUserCBAdpt+1); + pSalDACMngtAdpt->pUserCB->pRXCB = (pSalDACUserCBAdpt+2); + pSalDACMngtAdpt->pUserCB->pRXCCB = (pSalDACUserCBAdpt+3); + pSalDACMngtAdpt->pUserCB->pRDREQCB = (pSalDACUserCBAdpt+4); + pSalDACMngtAdpt->pUserCB->pERRCB = (pSalDACUserCBAdpt+5); + pSalDACMngtAdpt->pUserCB->pDMATXCB = (pSalDACUserCBAdpt+6); + pSalDACMngtAdpt->pUserCB->pDMATXCCB = (pSalDACUserCBAdpt+7); + pSalDACMngtAdpt->pUserCB->pDMARXCB = (pSalDACUserCBAdpt+8); + pSalDACMngtAdpt->pUserCB->pDMARXCCB = (pSalDACUserCBAdpt+9); + + /*To assign the rest pointers*/ + pSalDACMngtAdpt->pSalHndPriv->ppSalDACHnd = (void**)&(pSalDACMngtAdpt->pSalHndPriv); + + /* To assign the default HAL OP initialization function */ + pSalDACMngtAdpt->pHalOpInit = &HalDACOpInit; + + /* To assign the default HAL GDMA OP initialization function */ + pSalDACMngtAdpt->pHalGdmaOpInit = &HalGdmaOpInit; + + /* To assign the default SAL interrupt function */ + pSalDACMngtAdpt->pSalIrqFunc = &DACISRHandle; + + /* To assign the default SAL DMA interrupt function */ + pSalDACMngtAdpt->pSalDMAIrqFunc = &DACGDMAISRHandle; + + return pSalDACMngtAdpt; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CFreeMngtAdpt +// +// Description: +// Free all the previous allocated memory space. +// +// Arguments: +// [in] PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt - +// I2C SAL management adapter pointer +// +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the RtkI2CFreeMngtAdpt succeeded. +// _EXIT_FAILURE if the RtkI2CFreeMngtAdpt failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACFreeMngtAdpt( + IN PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt +){ +#if !DAC_STATIC_ALLOC + RtlMfree((u8 *)pSalDACMngtAdpt->pUserCB->pTXCB, (sizeof(SAL_DAC_USERCB_ADPT)*SAL_DAC_USER_CB_NUM)); + RtlMfree((u8 *)pSalDACMngtAdpt->pIrqGdmaHnd, sizeof(IRQ_HANDLE)); + RtlMfree((u8 *)pSalDACMngtAdpt->pHalGdmaOp, sizeof(HAL_GDMA_OP)); + RtlMfree((u8 *)pSalDACMngtAdpt->pHalGdmaAdp, sizeof(HAL_GDMA_ADAPTER)); + RtlMfree((u8 *)pSalDACMngtAdpt->pDMAConf, sizeof(SAL_DAC_DMA_USER_DEF)); + RtlMfree((u8 *)pSalDACMngtAdpt->pUserCB, sizeof(SAL_DAC_USER_CB)); + RtlMfree((u8 *)pSalDACMngtAdpt->pIrqHnd, sizeof(IRQ_HANDLE)); + RtlMfree((u8 *)pSalDACMngtAdpt->pHalOp, sizeof(HAL_DAC_OP)); + RtlMfree((u8 *)pSalDACMngtAdpt->pHalInitDat, sizeof(HAL_DAC_INIT_DAT)); + RtlMfree((u8 *)pSalDACMngtAdpt->pSalHndPriv, sizeof(SAL_DAC_HND_PRIV)); + RtlMfree((u8 *)pSalDACMngtAdpt, sizeof(SAL_DAC_MNGT_ADPT)); +#else + ; +#endif + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// I2CISRHandle +// +// Description: +// I2C Interrupt Service Routine. +// According to the input pointer to SAL_I2C_HND, all the rest pointers will be +// found and be used to the rest part of this servie routine. +// The following types of interrupt will be taken care: +// - General Call (providing General Call Callback). Slave receives a general call. +// - STOP Bit (NOT providing General Call Callback) +// - START Bit (NOTproviding General Call Callback) +// - I2C Activity (NOTproviding General Call Callback) +// - RX Done (providing Error Callback). The slave transmitter does NOT +// receive a proper NACK for the end of whole transfer. +// - TX Abort (providing Error Call Callback). The Master/Slave +// transmitting is terminated. +// - RD Req (providing TX and TXC Callback). Slave gets a Read Request +// and starts a slave-transmitter operation. The slave transmit +// data will be written into slave TX FIFO from user data buffer. +// - TX Empty (providing TX and TXC Callback). Master TX FIFO is empty. +// The user transmit data will be written into master TX FIFO +// from user data buffer. +// - TX Over (providing Error Callback). Master TX FIFO is Overflow. +// - RX Full (providing RX and RXC Callback). Master/Slave RX FIFO contains +// data. And the received data will be put into Master/Slave user +// receive data buffer. +// - RX Over (providing Error Callback). Master/Slave RX FIFO is Overflow. +// - RX Under (providing Error Callback). Master/Slave RX FIFO is Underflow. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// NA +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//---------------------------------------------------------------------------------------------------- +VOID +DACISRHandle( + IN VOID *Data +){ +#ifdef CONFIG_DEBUG_LOG_DAC_HAL + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PHAL_DAC_INIT_DAT pHalDACInitDat = NULL; + PHAL_DAC_OP pHalDACOP = NULL; + PSAL_DAC_USER_CB pSalDACUserCB = NULL; + u8 DACIrqIdx; + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + pHalDACInitDat = pSalDACMngtAdpt->pHalInitDat; + pHalDACOP = pSalDACMngtAdpt->pHalOp; + DACIrqIdx = pHalDACInitDat->DACIdx; + pSalDACUserCB = pSalDACHND->pUserCB; + + DBG_DAC_INFO("DAC INTR STS:%x\n",pHalDACOP->HalDACReadReg(pHalDACInitDat, REG_DAC_INTR_STS)); + if ((pHalDACOP->HalDACReadReg(pHalDACInitDat, REG_DAC_INTR_STS)) & BIT_DAC_FIFO_STOP_ST){ + pHalDACInitDat->DACEn = DAC_DISABLE; + pHalDACOP->HalDACEnable((void *)pHalDACInitDat); + } +#else + /* To reduce warning */ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PHAL_DAC_INIT_DAT pHalDACInitDat = NULL; + PHAL_DAC_OP pHalDACOP = NULL; + + + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + pHalDACInitDat = pSalDACMngtAdpt->pHalInitDat; + pHalDACOP = pSalDACMngtAdpt->pHalOp; + + + pHalDACOP->HalDACReadReg(pHalDACInitDat, REG_DAC_INTR_STS); +#endif +} + +VOID +DACGDMAISRHandle( + IN VOID *Data +){ + + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + + PHAL_GDMA_ADAPTER pHalDACGdmaAdapter = NULL; + PHAL_GDMA_OP pHalDACGdmaOp = NULL; + PSAL_DAC_USER_CB pSalDACUserCB = NULL; + + u8 IsrTypeMap = 0; + DBG_8195A_DAC_LVL(HAL_DAC_LVL,"%s\n",__func__); + + + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHalDACGdmaAdapter = pSalDACMngtAdpt->pHalGdmaAdp; + pHalDACGdmaOp = pSalDACMngtAdpt->pHalGdmaOp; + pSalDACUserCB = pSalDACMngtAdpt->pUserCB; + + pSalDACMngtAdpt->pHalGdmaOpInit(pHalDACGdmaOp); + + if ((pHalDACGdmaAdapter->MaxMuliBlock) == pHalDACGdmaAdapter->MuliBlockCunt+1) { + pHalDACGdmaOp->HalGdmaChCleanAutoSrc(pHalDACGdmaAdapter); + pHalDACGdmaOp->HalGdmaChDis(pHalDACGdmaAdapter); + pSalDACHND->DevSts = DAC_STS_IDLE; + if (pSalDACUserCB->pDMATXCCB->USERCB != NULL) + { + pSalDACUserCB->pDMATXCCB->USERCB((void*)pSalDACUserCB->pDMATXCCB->USERData); + } + } + else { + //pHalDACGdmaOp->HalGdmaChCleanAutoSrc(pHalDACGdmaAdapter); + pSalDACHND->DevSts = DAC_STS_TX_ING; + + if (pSalDACUserCB->pDMATXCB->USERCB != NULL){ + pSalDACUserCB->pDMATXCB->USERCB((void*)pSalDACUserCB->pDMATXCB->USERData);} + } + + //3 Clear Pending ISR + IsrTypeMap = pHalDACGdmaOp->HalGdmaChIsrClean((VOID*)pHalDACGdmaAdapter); + + //3 Maintain Block Count + if (IsrTypeMap & BlockType) { + pHalDACGdmaAdapter->MuliBlockCunt++; + } + +} + +VOID +DACGDMALLPISRHandle( + IN VOID *Data +){ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + + PHAL_GDMA_ADAPTER pHalDACGdmaAdapter = NULL; + PHAL_GDMA_OP pHalDACGdmaOp = NULL; + + u8 IsrTypeMap; + + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHalDACGdmaAdapter = pSalDACMngtAdpt->pHalGdmaAdp; + pHalDACGdmaOp = pSalDACMngtAdpt->pHalGdmaOp; + + + pSalDACMngtAdpt->pHalGdmaOpInit(pHalDACGdmaOp); +#if 0 + PGDMA_ADAPTER pGdmaAdapte = (PGDMA_ADAPTER) Data; + PHAL_GDMA_ADAPTER pHalGdmaAdapter = pGdmaAdapte->pHalGdmaAdapter; + PGDMA_CH_LLI_ELE pGdmaChLliEle; + struct GDMA_CH_LLI *pGdmaChLli = pHalGdmaAdapter->pLlix; + struct BLOCK_SIZE_LIST *pBlockSizeList = pHalGdmaAdapter->pBlockSizeList; + u32 TotalBlockSize = 0; + u8 IsrTypeMap, BlockIndex; + u8 *pSrc = NULL, *pDst = NULL; + DBG_8195A_DMA("Enter Gdma0 Channel 5 ISr =====>\n"); +#endif + + + + if ((pHalDACGdmaAdapter->MaxMuliBlock) == pHalDACGdmaAdapter->MuliBlockCunt) { + //HalGdmaOp.HalGdmaChCleanAutoSrc(pHalGdmaAdapter); + //DAC0_FCTRL(OFF); + + //HalGdmaOp.HalGdmaChCleanAutoDst(pHalGdmaAdapter); + pHalDACGdmaOp->HalGdmaChDis(pHalDACGdmaAdapter); + + DBG_8195A("dma done\n"); + } + + + IsrTypeMap = pHalDACGdmaOp->HalGdmaChIsrClean((VOID*)pHalDACGdmaAdapter); + + if (IsrTypeMap & BlockType) { + pHalDACGdmaAdapter->MuliBlockCunt++; + } +} + +static RTK_STATUS +RtkDACPinMuxInit( + IN PSAL_DAC_HND pSalDACHND +){ + u32 DACLocalTemp; + + /* Check the I2C index first */ + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + DACLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + DACLocalTemp |= BIT26; + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_SYSPLL_CTRL2,DACLocalTemp); + + switch (pSalDACHND->DevNum){ +#if DAC0_USED + case DAC0_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(ON); + + /* Enable DAC0 module */ + DAC0_FCTRL(ON); + break; + } +#endif +#if DAC1_USED + case DAC1_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(ON); + + /* Enable DAC1 module */ + DAC1_FCTRL(ON); + break; + } +#endif + default: + return _EXIT_FAILURE; + } + + return _EXIT_SUCCESS; +} + +/** \brief HalDACPinMuxInit:\n + * to set DAC clock control and enable control + * + * This function is mainly to set DAC clock control and enable control. + * \para VOID *: Data, It's a pointer to HAL_DAC_INIT_DAT + */ +void +HalDACPinMuxInit( + IN VOID *Data +){ + u32 DACLocalTemp; + PHAL_DAC_INIT_DAT pHalInitPara = (PHAL_DAC_INIT_DAT)Data; + + /* Check the I2C index first */ + if (RtkDACIdxChk(pHalInitPara->DACIdx)) + return; + + DACLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + DACLocalTemp |= BIT26; + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_SYSPLL_CTRL2,DACLocalTemp); + + switch (pHalInitPara->DACIdx){ +#if DAC0_USED + case DAC0_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(ON); + + /* Enable DAC0 module */ + DAC0_FCTRL(ON); + break; + } +#endif +#if DAC1_USED + case DAC1_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(ON); + + /* Enable DAC1 module */ + DAC1_FCTRL(ON); + break; + } +#endif + default: + return; + } + +} + + +static RTK_STATUS +RtkDACPinMuxDeInit( + IN PSAL_DAC_HND pSalDACHND +){ + + u32 DACLocalTemp; + + /* Check the I2C index first */ + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + switch (pSalDACHND->DevNum){ +#if DAC0_USED + case DAC0_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(OFF); + + /* Enable DAC0 module */ + DAC0_FCTRL(OFF); + break; + } +#endif +#if DAC1_USED + case DAC1_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(OFF); + + /* Enable DAC1 module */ + DAC1_FCTRL(OFF); + break; + } +#endif + default: + return _EXIT_FAILURE; + } + + + DACLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + DACLocalTemp &= (~BIT26); + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_SYSPLL_CTRL2,DACLocalTemp); + + return _EXIT_SUCCESS; +} + +/** \brief HalDACPinMuxDeInit:\n + * to disable DAC clock control and enable control + * + * This function is mainly to disable DAC clock control and enable control. + * \para VOID *: Data, a pointer to HAL_DAC_INIT_DAT. + */ +void +HalDACPinMuxDeInit( + IN VOID *Data +){ + + u32 DACLocalTemp; + PHAL_DAC_INIT_DAT pHalInitPara = (PHAL_DAC_INIT_DAT)Data; + + /* Check the I2C index first */ + if (RtkDACIdxChk(pHalInitPara->DACIdx)) + return; + + switch (pHalInitPara->DACIdx){ +#if DAC0_USED + case DAC0_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(OFF); + + /* Enable DAC0 module */ + DAC0_FCTRL(OFF); + break; + } +#endif +#if DAC1_USED + case DAC1_SEL: + { + /* Turn on DAC active clock */ + ACTCK_DAC_CCTRL(OFF); + + /* Enable DAC1 module */ + DAC1_FCTRL(OFF); + break; + } +#endif + default: + return; + } + + + DACLocalTemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2); + DACLocalTemp &= (~BIT26); + + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_SYSPLL_CTRL2,DACLocalTemp); + + return; +} + + +#if DAC_INTR_OP_TYPE +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqInit +// +// Description: +// I2C interrupt initialization function. +// For I2C interrupt operation mode, I2C module MUST register itself to the platform +// by providing the interrupt handler which contains interrupt input data (arguments), +// interrupt service routine, interrupt number, interrupt priority. And then the interrupt +// should be enabled. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkDACIrqInit( + IN PSAL_DAC_HND pSalDACHND +){ + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PIRQ_HANDLE pIrqHandle = NULL; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + pIrqHandle = pSalDACMngtAdpt->pIrqHnd; + + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + switch (pSalDACHND->DevNum){ +#if DAC0_USED + case DAC0_SEL: + { + pIrqHandle->Data = (u32) (pSalDACHND); + pIrqHandle->IrqNum = DAC0_IRQ; + pIrqHandle->IrqFun = (IRQ_FUN) pSalDACMngtAdpt->pSalIrqFunc; + pIrqHandle->Priority = 5; + InterruptRegister(pIrqHandle); + InterruptEn(pIrqHandle); + break; + } +#endif +#if DAC1_USED + case DAC1_SEL: + { + pIrqHandle->Data = (u32) (pSalDACHND); + pIrqHandle->IrqNum = DAC1_IRQ; + pIrqHandle->IrqFun = (IRQ_FUN) pSalDACMngtAdpt->pSalIrqFunc;; + pIrqHandle->Priority = 5; + InterruptRegister(pIrqHandle); + InterruptEn(pIrqHandle); + break; + } +#endif + default: + return _EXIT_FAILURE; + } + + + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqDeInit +// +// Description: +// I2C interrupt de-initialization function. +// According to the given I2C device number, the I2C interrupt will be unreigster +// from the platform and the relative interrupt handler will be cleared. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt de-initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqDeInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqDeInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkDACIrqDeInit( + IN PSAL_DAC_HND pSalDACHND +){ + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PIRQ_HANDLE pIrqHandle = NULL; + + /*To Get the SAL_I2C_MNGT_ADPT Pointer*/ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + pIrqHandle = pSalDACMngtAdpt->pIrqHnd; + + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + InterruptUnRegister(pIrqHandle); + return _EXIT_SUCCESS; +} + +#endif + + +#if DAC_DMA_OP_TYPE +const u16 DACDmaChNo[10] = {GdmaNoCh ,GdmaCh0, + GdmaCh1 ,GdmaCh2, + GdmaCh3 ,GdmaCh4, + GdmaCh5 ,GdmaCh6, + GdmaCh7 ,GdmaAllCh}; + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqInit +// +// Description: +// I2C interrupt initialization function. +// For I2C interrupt operation mode, I2C module MUST register itself to the platform +// by providing the interrupt handler which contains interrupt input data (arguments), +// interrupt service routine, interrupt number, interrupt priority. And then the interrupt +// should be enabled. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkDACDMAInit( + IN PSAL_DAC_HND pSalDACHND +){ + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PHAL_GDMA_ADAPTER pHALDACGdmaAdpt = NULL; + PHAL_GDMA_OP pHALDACGdmaOp = NULL; + PIRQ_HANDLE pIrqHandleDACGdma = NULL; + PSAL_DAC_DMA_USER_DEF pSalDACDmaUserDef = NULL; + + + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHALDACGdmaAdpt = pSalDACMngtAdpt->pHalGdmaAdp; + pHALDACGdmaOp = pSalDACMngtAdpt->pHalGdmaOp; + pIrqHandleDACGdma = pSalDACMngtAdpt->pIrqGdmaHnd; + pSalDACDmaUserDef = pSalDACHND->pDMAConf; + + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + if (pSalDACHND->DACInType == DAC_INPUT_SINGLE_WR) + return _EXIT_SUCCESS; + + /* GDMA operation initialization */ + //HalGdmaOpInit(pHalI2CGdmaOp); + _memset((void *)pHALDACGdmaAdpt, 0, sizeof(HAL_GDMA_ADAPTER)); + pSalDACMngtAdpt->pHalGdmaOpInit(pHALDACGdmaOp); + pHALDACGdmaOp->HalGdamChInit((VOID*)(pHALDACGdmaAdpt)); + + + + pHALDACGdmaAdpt->GdmaIndex = pSalDACHND->DevNum; + pHALDACGdmaAdpt->GdmaCtl.IntEn = 1; + pHALDACGdmaAdpt->ChNum = pSalDACDmaUserDef->TxChNo; + + pHALDACGdmaAdpt->ChEn = DACDmaChNo[pHALDACGdmaAdpt->ChNum+1]; + pHALDACGdmaAdpt->IsrCtrl = ENABLE; + pHALDACGdmaAdpt->GdmaOnOff = ON; + + + /* GDMA initialization */ + /* Enable the whole GDMA module first */ + if (pHALDACGdmaAdpt->GdmaIndex == 0) { + ACTCK_GDMA0_CCTRL(ON); + SLPCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + } + else { + ACTCK_GDMA1_CCTRL(ON); + SLPCK_GDMA1_CCTRL(ON); + GDMA1_FCTRL(ON); + } + + if (pSalDACHND->DACInType == DAC_INPUT_DMA_ONEBLK) { + //DAC TX DMA + pHALDACGdmaAdpt->GdmaCtl.SrcTrWidth = pSalDACDmaUserDef->TxDatSrcWdth; + pHALDACGdmaAdpt->GdmaCtl.DstTrWidth = pSalDACDmaUserDef->TxDatDstWdth; + pHALDACGdmaAdpt->GdmaCtl.SrcMsize = pSalDACDmaUserDef->TxDatSrcBstSz; + pHALDACGdmaAdpt->GdmaCtl.DestMsize = pSalDACDmaUserDef->TxDatDstBstSz; + + pHALDACGdmaAdpt->GdmaCtl.Sinc = IncType; + pHALDACGdmaAdpt->GdmaCtl.Dinc = NoChange; + + pHALDACGdmaAdpt->GdmaCtl.Done = 1; + pHALDACGdmaAdpt->GdmaCtl.TtFc = 0x01; + + pHALDACGdmaAdpt->GdmaCfg.DestPer = 13; + pHALDACGdmaAdpt->GdmaCfg.ReloadSrc = 1; + + pHALDACGdmaAdpt->MuliBlockCunt = 1; + pHALDACGdmaAdpt->MaxMuliBlock = pSalDACHND->pDMAConf->MaxMultiBlk; + + pHALDACGdmaAdpt->GdmaIsrType = (BlockType|TransferType|ErrType); + + + pHALDACGdmaAdpt->TestItem = 3; + + + //pSalDACMngtAdpt->pSalDMAIrqFunc = &DACGDMAISRHandle; + } + else if (pSalDACHND->DACInType == DAC_INPUT_DMA_LLP) { + //DAC TX DMA + pHALDACGdmaAdpt->GdmaCtl.SrcTrWidth = pSalDACDmaUserDef->TxDatSrcWdth; + pHALDACGdmaAdpt->GdmaCtl.DstTrWidth = pSalDACDmaUserDef->TxDatDstWdth; + pHALDACGdmaAdpt->GdmaCtl.SrcMsize = pSalDACDmaUserDef->TxDatSrcBstSz; + pHALDACGdmaAdpt->GdmaCtl.DestMsize = pSalDACDmaUserDef->TxDatDstBstSz; + + pHALDACGdmaAdpt->GdmaCtl.Dinc = NoChange; + + pHALDACGdmaAdpt->GdmaCtl.Done = 1; + pHALDACGdmaAdpt->GdmaCtl.TtFc = 0x01; + pHALDACGdmaAdpt->GdmaCtl.LlpSrcEn = 1; + + pHALDACGdmaAdpt->GdmaCfg.DestPer = 13; + + pHALDACGdmaAdpt->GdmaIsrType = (BlockType|ErrType); + + /* Enable LLP control */ + pHALDACGdmaAdpt->Llpctrl = pSalDACDmaUserDef->LlpCtrl; + + pHALDACGdmaAdpt->MuliBlockCunt = 1; + pHALDACGdmaAdpt->MaxMuliBlock = pSalDACDmaUserDef->MaxMultiBlk; + + pHALDACGdmaAdpt->TestItem = 9; + + //pSalDACMngtAdpt->pSalDMAIrqFunc = &DACGDMALLPISRHandle; + } + + + /* GDMA interrupt register */ + pIrqHandleDACGdma->Data = (u32) (pSalDACHND); + pIrqHandleDACGdma->IrqNum = GDMA0_CHANNEL0_IRQ + pHALDACGdmaAdpt->ChNum + + ((pHALDACGdmaAdpt->GdmaIndex)*6); + pIrqHandleDACGdma->IrqFun = (IRQ_FUN) pSalDACMngtAdpt->pSalDMAIrqFunc; + pIrqHandleDACGdma->Priority = 6; + InterruptRegister(pIrqHandleDACGdma); + InterruptEn(pIrqHandleDACGdma); + + + pHALDACGdmaOp->HalGdmaOnOff((VOID*)pHALDACGdmaAdpt); + pHALDACGdmaOp->HalGdmaChIsrEnAndDis((VOID*)pHALDACGdmaAdpt); + +#if 0 + /* Enable GDMA according to the DMA type */ + if (pSalDACHND->DACInType == DAC_INPUT_DMA_ONEBLK) { + pHALDACGdmaOp->HalGdmaChSeting((VOID*)pHALDACGdmaAdpt); + } + else if (pSalDACHND->DACInType == DAC_INPUT_DMA_LLP){ + //pHALDACGdmaOp->HalGdmaChBlockSeting((VOID*)(pHALDACGdmaAdpt)); + } +#endif + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CIrqDeInit +// +// Description: +// I2C interrupt de-initialization function. +// According to the given I2C device number, the I2C interrupt will be unreigster +// from the platform and the relative interrupt handler will be cleared. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C interrupt de-initialization process. +// _EXIT_SUCCESS if the RtkI2CIrqDeInit succeeded. +// _EXIT_FAILURE if the RtkI2CIrqDeInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +static RTK_STATUS +RtkDACDMADeInit( + IN PSAL_DAC_HND pSalDACHND +){ + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + + PHAL_GDMA_ADAPTER pHALDACGdmaAdpt = NULL; + PHAL_GDMA_OP pHALDACGdmaOp = NULL; + PIRQ_HANDLE pIrqHandleDACGdma = NULL; + + /*To Get the SAL_I2C_MNGT_ADPT Pointer*/ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHALDACGdmaAdpt = pSalDACMngtAdpt->pHalGdmaAdp; + pHALDACGdmaOp = pSalDACMngtAdpt->pHalGdmaOp; + pIrqHandleDACGdma = pSalDACMngtAdpt->pIrqGdmaHnd; + + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + HalGdmaOpInit(pHALDACGdmaOp); + + pHALDACGdmaAdpt->IsrCtrl = DISABLE; + pHALDACGdmaOp->HalGdmaChIsrEnAndDis((VOID*)pHALDACGdmaAdpt); + pHALDACGdmaOp->HalGdmaChIsrClean((VOID*)pHALDACGdmaAdpt); + pHALDACGdmaOp->HalGdmaChDis((VOID*)pHALDACGdmaAdpt); + + InterruptUnRegister(pIrqHandleDACGdma); +#if 0 + _memset((void *)pIrqHandleDACGdma , 0, sizeof(IRQ_HANDLE)); + _memset((void *)pHALDACGdmaOp , 0, sizeof(HAL_GDMA_OP)); + _memset((void *)pHALDACGdmaAdpt , 0, sizeof(HAL_GDMA_ADAPTER)); +#endif + return _EXIT_SUCCESS; +} + +#endif + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInit +// +// Description: +// According to the given I2C index, the related SAL_I2C_MNGT_ADPT pointer used +// for retrieving each I2C data sturcture pointer will be reversely parsed first. +// Then, initializing I2C HAL operation, initializing I2C interrupt (if needed), +// initializing I2C DMA (if needed) and initializing I2C pinmux will be done. +// User specified I2C configuration will be assigned to I2C initial data structure +// (PHAL_I2C_INIT_DAT pHalI2CInitDat). I2C HAL initialization is executed after +// all the configuration data taken. +// In the end, I2C module is enabled as a final step of the whole initialization. +// For a slave ack General Call support, an additional step may be followed after +// the above steps. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// _EXIT_SUCCESS if the RtkI2CInit succeeded. +// _EXIT_FAILURE if the RtkI2CInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACInit( + IN VOID *Data +){ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + //PHAL_DAC_INIT_DAT pHalDACInitDat = NULL; + PHAL_DAC_OP pHalDACOP = NULL; + + u32 DacTemp; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + //pHalDACInitDat = pSalDACMngtAdpt->pHalInitDat; + pHalDACOP = pSalDACMngtAdpt->pHalOp; + + /* Check the input I2C index first */ + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + +#if 0 + /* Check the input I2C operation type */ + if (RtkI2COpTypeChk(pSalI2CHND)) + return _EXIT_FAILURE; +#endif + + /* DAC Initialize HAL Operations */ + HalDACOpInit(pHalDACOP); + + /* DAC Interrupt Initialization */ +#if DAC_INTR_OP_TYPE + RtkDACIrqInit(pSalDACHND); +#endif + + /* DAC DMA Initialization */ +#if DAC_DMA_OP_TYPE + RtkDACDMAInit(pSalDACHND); +#endif + + + /* DAC Function and Clock Enable*/ + RtkDACPinMuxInit(pSalDACHND); + + pHalDACOP->HalDACInit(pSalDACHND->pInitDat); + + #if 1 + HAL_DAC_WRITE32(pSalDACHND->DevNum, REG_DAC_INTR_CTRL, + (BIT_DAC_FIFO_FULL_EN | + BIT_DAC_FIFO_OVERFLOW_EN | + BIT_DAC_FIFO_STOP_EN | + BIT_DAC__WRITE_ERROR_EN | + BIT_DAC_DSC_OVERFLOW0_EN | + BIT_DAC_DSC_OVERFLOW1_EN)); + #else + HAL_DAC_WRITE32(pSalDACHND->DevNum, REG_DAC_INTR_CTRL, + (BIT_DAC_FIFO_FULL_EN| + BIT_DAC_FIFO_OVERFLOW_EN| + BIT_DAC_FIFO_STOP_EN| + BIT_DAC__WRITE_ERROR_EN| + BIT_DAC_DSC_OVERFLOW0_EN| + BIT_DAC_DSC_OVERFLOW1_EN)); + #endif + DBG_DAC_INFO("INTR MSK:%x\n", HAL_DAC_READ32(pSalDACHND->DevNum,REG_DAC_INTR_CTRL)); + + + + DacTemp = HAL_DAC_READ32(pSalDACHND->DevNum, REG_DAC_ANAPAR_DA1); + DacTemp |= (BIT31); + HAL_DAC_WRITE32(pSalDACHND->DevNum, REG_DAC_ANAPAR_DA1, DacTemp); + //DBG_DAC_INFO("REG_DAC_ANAPAR_DA1:%08x\n",DacTemp); + DBG_DAC_INFO("REG_DAC_ANAPAR_DA1:%08x\n",HAL_DAC_READ32(pSalDACHND->DevNum, REG_DAC_ANAPAR_DA1)); + DacTemp = HAL_DAC_READ32(pSalDACHND->DevNum, REG_DAC_CTRL); + DacTemp |= BIT3; + HAL_DAC_WRITE32(pSalDACHND->DevNum, REG_DAC_CTRL, DacTemp); + DBG_DAC_INFO("REG_DAC_CTRL:%08x\n",DacTemp); + + pSalDACHND->pInitDat->DACEn = DAC_ENABLE; + pHalDACOP->HalDACEnable(pSalDACHND->pInitDat); + + /* DAC Device Status Update */ + pSalDACHND->DevSts = DAC_STS_IDLE; + + return _EXIT_SUCCESS; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInit +// +// Description: +// According to the given I2C index, the related SAL_I2C_MNGT_ADPT pointer used +// for retrieving each I2C data sturcture pointer will be reversely parsed first. +// Then, initializing I2C HAL operation, initializing I2C interrupt (if needed), +// initializing I2C DMA (if needed) and initializing I2C pinmux will be done. +// User specified I2C configuration will be assigned to I2C initial data structure +// (PHAL_I2C_INIT_DAT pHalI2CInitDat). I2C HAL initialization is executed after +// all the configuration data taken. +// In the end, I2C module is enabled as a final step of the whole initialization. +// For a slave ack General Call support, an additional step may be followed after +// the above steps. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// _EXIT_SUCCESS if the RtkI2CInit succeeded. +// _EXIT_FAILURE if the RtkI2CInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACDeInit( + IN VOID *Data +){ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PHAL_DAC_INIT_DAT pHalDACInitDat = NULL; + PHAL_DAC_OP pHalDACOP = NULL; + + /* To Get the SAL_DAC_MNGT_ADPT Pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHalDACInitDat = pSalDACMngtAdpt->pHalInitDat; + pHalDACOP = pSalDACMngtAdpt->pHalOp; + + /* Check the input DAC index first */ + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + { + /* DAC Initialize HAL Operations */ + HalDACOpInit(pHalDACOP); + + /* DAC Interrupt Initialization */ +#if DAC_INTR_OP_TYPE + RtkDACIrqDeInit(pSalDACHND); +#endif + + /* DAC DMA Initialization */ +#if DAC_DMA_OP_TYPE + RtkDACDMADeInit(pSalDACHND); +#endif + + pHalDACInitDat->DACEn = DAC_DISABLE; + pHalDACOP->HalDACEnable(pHalDACInitDat); + pHalDACOP->HalDACDeInit(pHalDACInitDat); + + /* DAC Function and Clock Enable*/ + RtkDACPinMuxDeInit(pSalDACHND); + } + + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInit +// +// Description: +// According to the given I2C index, the related SAL_I2C_MNGT_ADPT pointer used +// for retrieving each I2C data sturcture pointer will be reversely parsed first. +// Then, initializing I2C HAL operation, initializing I2C interrupt (if needed), +// initializing I2C DMA (if needed) and initializing I2C pinmux will be done. +// User specified I2C configuration will be assigned to I2C initial data structure +// (PHAL_I2C_INIT_DAT pHalI2CInitDat). I2C HAL initialization is executed after +// all the configuration data taken. +// In the end, I2C module is enabled as a final step of the whole initialization. +// For a slave ack General Call support, an additional step may be followed after +// the above steps. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// _EXIT_SUCCESS if the RtkI2CInit succeeded. +// _EXIT_FAILURE if the RtkI2CInit failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACSend( + IN VOID *Data +){ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PHAL_GDMA_ADAPTER pHALDACGdmaAdpt = NULL; + PHAL_GDMA_OP pHALDACGdmaOp = NULL; + PSAL_DAC_DMA_USER_DEF pSalDACDmaUserDef = NULL; + //PIRQ_HANDLE pIrqHandleDACGdma = NULL; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + pHALDACGdmaAdpt = pSalDACMngtAdpt->pHalGdmaAdp; + pHALDACGdmaOp = pSalDACMngtAdpt->pHalGdmaOp; + pSalDACDmaUserDef = pSalDACMngtAdpt->pDMAConf; + + switch (pSalDACHND->DACInType) { + case DAC_INPUT_SINGLE_WR: + { + break; + } + case DAC_INPUT_DMA_ONEBLK: + { + HalGdmaOpInit(pHALDACGdmaOp); + + pHALDACGdmaAdpt->GdmaCtl.BlockSize = pSalDACHND->pTXBuf->DataLen; + pHALDACGdmaAdpt->ChSar = (u32)pSalDACHND->pTXBuf->pDataBuf; + pHALDACGdmaAdpt->ChDar = (u32)(DAC_REG_BASE+(pSalDACHND->DevNum*0x800)); + + DBG_DAC_INFO("src addr:%x\n", pHALDACGdmaAdpt->ChSar); + DBG_DAC_INFO("dst addr:%x\n", pHALDACGdmaAdpt->ChDar); + pHALDACGdmaOp->HalGdmaChSeting(pHALDACGdmaAdpt); + + pHALDACGdmaOp->HalGdmaChEn(pHALDACGdmaAdpt); + break; + } + case DAC_INPUT_DMA_LLP: + { + pHALDACGdmaAdpt->Rsvd4to7 = 1; + pHALDACGdmaAdpt->pLlix = (struct GDMA_CH_LLI *)pSalDACDmaUserDef->pLlix; + pHALDACGdmaAdpt->pBlockSizeList = (struct BLOCK_SIZE_LIST *)pSalDACDmaUserDef->pBlockSizeList; + pHALDACGdmaAdpt->ChDar = (u32)(DAC_REG_BASE+(pSalDACHND->DevNum*0x800)); + pHALDACGdmaOp->HalGdmaChBlockSeting(pHALDACGdmaAdpt); + + pHALDACGdmaOp->HalGdmaChEn(pHALDACGdmaAdpt); + break; + } + + default: + return _EXIT_FAILURE; + } + + + return _EXIT_SUCCESS; +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetSalHnd +// +// Description: +// Allocation of lower layer memory spaces will be done by invoking RtkI2CGetMngtAdpt +// in this function and return a SAL_I2C_HND pointer to upper layer. +// According to the given I2C index, RtkI2CGetMngtAdpt will allocate all the memory +// space such as SAL_I2C_HND, HAL_I2C_INIT_DAT, SAL_I2C_USER_CB etc. +// +// +// Arguments: +// [in] u8 I2CIdx - +// I2C Index +// +// Return: +// PSAL_I2C_HND +// A pointer to SAL_I2C_HND which is allocated in the lower layer. +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +PSAL_DAC_HND +RtkDACGetSalHnd( + IN u8 DACIdx +){ + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PSAL_DAC_HND pSalDACHND = NULL; + + /* Check the user define setting and the given index */ + if (RtkDACIdxChk(DACIdx)) { + return (PSAL_DAC_HND)NULL; + } + + /* Invoke RtkI2CGetMngtAdpt to get the I2C SAL management adapter pointer */ + pSalDACMngtAdpt = RtkDACGetMngtAdpt(DACIdx); + + /* Assign the private SAL handle to public SAL handle */ + pSalDACHND = &(pSalDACMngtAdpt->pSalHndPriv->SalDACHndPriv); + + /* Assign the internal HAL initial data pointer to the SAL handle */ + pSalDACHND->pInitDat = pSalDACMngtAdpt->pHalInitDat; + + /* Assign the internal user callback pointer to the SAL handle */ + pSalDACHND->pUserCB = pSalDACMngtAdpt->pUserCB; + + /* Assign the internal user DMA config to the SAL handle */ + pSalDACHND->pDMAConf = pSalDACMngtAdpt->pDMAConf; + + return &(pSalDACMngtAdpt->pSalHndPriv->SalDACHndPriv); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetSalHnd +// +// Description: +// Allocation of lower layer memory spaces will be done by invoking RtkI2CGetMngtAdpt +// in this function and return a SAL_I2C_HND pointer to upper layer. +// According to the given I2C index, RtkI2CGetMngtAdpt will allocate all the memory +// space such as SAL_I2C_HND, HAL_I2C_INIT_DAT, SAL_I2C_USER_CB etc. +// +// +// Arguments: +// [in] u8 I2CIdx - +// I2C Index +// +// Return: +// PSAL_I2C_HND +// A pointer to SAL_I2C_HND which is allocated in the lower layer. +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACFreeSalHnd( + IN PSAL_DAC_HND pSalDACHND +){ + PSAL_DAC_MNGT_ADPT pSalDACMngtAdpt = NULL; + PSAL_DAC_HND_PRIV pSalDACHNDPriv = NULL; + + /* To get the SAL_DAC_MNGT_ADPT pointer */ + pSalDACHNDPriv = CONTAINER_OF(pSalDACHND, SAL_DAC_HND_PRIV, SalDACHndPriv); + pSalDACMngtAdpt = CONTAINER_OF(pSalDACHNDPriv->ppSalDACHnd, SAL_DAC_MNGT_ADPT, pSalHndPriv); + + /* Invoke RtkDACFreeMngtAdpt to free all the lower layer memory space */ + return (RtkDACFreeMngtAdpt(pSalDACMngtAdpt)); + +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CLoadDefault +// +// Description: +// Accrording the given I2C index, the default I2C configuration is done. +// +// +// Arguments: +// [in] PSAL_I2C_HND pSalI2CHND - +// SAL I2C handle +// +// Return: +// The status of the loading I2C default configuration. +// _EXIT_SUCCESS if the RtkI2CLoadDefault succeeded. +// _EXIT_FAILURE if the RtkI2CLoadDefault failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +RTK_STATUS +RtkDACLoadDefault( + IN VOID *Data +){ + PSAL_DAC_HND pSalDACHND = (PSAL_DAC_HND) Data; + + /* Check the input DAC index first */ + if (RtkDACIdxChk(pSalDACHND->DevNum)) + return _EXIT_FAILURE; + + /* Load SAL handle default value */ + pSalDACHND->PinMux = 0; + pSalDACHND->OpType = DAC_POLL_TYPE; + pSalDACHND->DevSts = DAC_STS_UNINITIAL; + pSalDACHND->DACExd = 0; + pSalDACHND->ErrType = (u32)NULL; + + /* Load HAL initial data structure default value */ + pSalDACHND->pInitDat->DACIdx = pSalDACHND->DevNum; + pSalDACHND->pInitDat->DACEn = DAC_DISABLE; + pSalDACHND->pInitDat->DACDataRate = DAC_DATA_RATE_250K; + pSalDACHND->pInitDat->DACEndian = DAC_DATA_ENDIAN_LITTLE; + pSalDACHND->pInitDat->DACBurstSz = 7; + pSalDACHND->pInitDat->DACDbgSel = DAC_DBG_SEL_DISABLE; + pSalDACHND->pInitDat->DACDscDbgSel = DAC_DSC_DBG_SEL_DISABLE; + pSalDACHND->pInitDat->DACBPDsc = DAC_BYPASS_DSC_SEL_DISABLE; + pSalDACHND->pInitDat->DACDeltaSig = 0; + pSalDACHND->pInitDat->DACAnaCtrl0 = 0; + pSalDACHND->pInitDat->DACAnaCtrl1 = 0; + pSalDACHND->pInitDat->DACIntrMSK = DAC_FEATURE_DISABLED; + + /* Load DAC DMA user configuration default value */ + pSalDACHND->pDMAConf->MaxMultiBlk = 5000; + pSalDACHND->pDMAConf->TxDatSrcWdth = TrWidthFourBytes; + pSalDACHND->pDMAConf->TxDatSrcBstSz = MsizeFour; + pSalDACHND->pDMAConf->TxDatDstWdth = TrWidthFourBytes; + pSalDACHND->pDMAConf->TxDatDstBstSz = MsizeFour; + pSalDACHND->pDMAConf->TxChNo = 4; + + return _EXIT_SUCCESS; +} + +#endif diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_efuse.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_efuse.c new file mode 100644 index 0000000..9c5bfb7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_efuse.c @@ -0,0 +1,337 @@ +/* +* Disassemble hal_efuse.o pvvx 10.2016 +*/ +#include "rtl8195a.h" +#ifdef CONFIG_EFUSE_EN +#include "hal_efuse.h" + +//#define NO_ROM_API + +#define EFUSE_WRITE_ENABLE 0 + +#define EFUSE_SECTION_SIZE (1<<7) // 128 bytes +#define EFUSE_BUF_MAX_LEN (1<<5) // 32 bytes +#define OTP_START_ADDR EFUSE_SECTION_SIZE +#define OTP_BUF_MAX_LEN (1<<5) // 32 bytes +#define EFUSE_SECTION_CODE 11 + +#ifdef NO_ROM_API +//====================================================== Start libs ROM efuse +//----- HalEFUSEPowerSwitch8195AROM addr 0x6561 +_LONG_CALL_ROM_ int HalEFUSEPowerSwitch8195AROM(IN unsigned char bWrite, IN unsigned char PwrState, IN unsigned char L25OutVoltage) { + if (PwrState == 1) { + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF) | 0x69000000); // EFUSE_UNLOCK + if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & BIT_SYS_FEN_EELDR)) // REG_SYS_FUNC_EN BIT_SYS_FEN_EELDR ? + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_FEN_EELDR); + if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) & BIT_SYSON_CK_EELDR_EN)) // REG_SYS_CLK_CTRL0 BIT_SYSON_CK_EELDR_EN ? + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL0) | BIT_SYSON_CK_EELDR_EN); + if (!(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & BIT_PESOC_EELDR_CK_SEL)) // REG_SYS_CLK_CTRL1 BIT_PESOC_EELDR_CK_SEL ? + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) | BIT_PESOC_EELDR_CK_SEL); + if (bWrite == 1) + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & 0xFFFFF0FF) | BIT_SYS_REGU_LDO25E_EN | BIT_SYS_REGU_LDO25E_ADJ(L25OutVoltage)); + } + else + { + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EEPROM_CTRL0) & 0xFFFFFF); // EFUSE_UNLOCK + if ( bWrite == 1 ) + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25E_EN))); + } + return bWrite; +} + +//----- HALEFUSEOneByteReadROM addr 0x6561 +_LONG_CALL_ROM_ int HALEFUSEOneByteReadROM(IN unsigned int CtrlSetting, IN unsigned short Addr, OUT unsigned char *Data, IN unsigned char L25OutVoltage) +{ +int i = 0, result = 0; + if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) { + HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage); + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) & (~BIT_SYS_EF_FORCE_PGMEN)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL, + (CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA)))) + | BIT_SYS_EF_ADDR(Addr)); + while(1) { + if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) { + *Data = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL); + result = 1; + break; + } + HalDelayUs(1000); + if (i++ >= 100) { + *Data = -1; + break; + }; + }; + HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); + } + else *Data = -1; + return result; +} + +//----- HALEFUSEOneByteWriteROM addr 0x6699 +_LONG_CALL_ROM_ int HALEFUSEOneByteWriteROM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char Data, IN unsigned char L25OutVoltage) +{ +int i = 0, result = 0; + if ( (Addr <= 0xFF) || ((CtrlSetting & 0xFFFF) == 0x26AE) ) { + HalEFUSEPowerSwitch8195AROM(1, 1, L25OutVoltage); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_TEST) | BIT_SYS_EF_FORCE_PGMEN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL, Data | BIT_SYS_EF_RWFLAG | BIT_SYS_EF_ADDR(Addr) | BIT_SYS_EF_DATA(Data) | + (CtrlSetting & (~(BIT_SYS_EF_RWFLAG | (BIT_MASK_SYS_EF_ADDR << BIT_SHIFT_SYS_EF_ADDR) | (BIT_MASK_SYS_EF_DATA << BIT_SHIFT_SYS_EF_DATA))))); + while(1) { + HalDelayUs(1000); + if(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL) & BIT_SYS_EF_RWFLAG) break; + if (i++ >= 100) { + result = 1; + break; + }; + }; + HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); + } + return result; +} +//====================================================== End libs ROM efuse +#endif + +//----- HALOTPOneByteReadRAM +int HALOTPOneByteReadRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, OUT unsigned char *Data, IN unsigned char L25OutVoltage) +{ + int result; + if ( (unsigned int)(Addr - EFUSE_SECTION_SIZE) > OTP_BUF_MAX_LEN - 1 ) + result = 1; + else + result = HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + return result; +} + +//----- HALOTPOneByteWriteRAM +int HALOTPOneByteWriteRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char Data, IN unsigned char L25OutVoltage) +{ +#if EFUSE_WRITE_ENABLE + int result; + if ( (unsigned int)(Addr - EFUSE_SECTION_SIZE) > OTP_BUF_MAX_LEN - 1 ) + result = 1; + else + result = HALEFUSEOneByteWriteROM(CtrlSetting, Addr, Data, L25OutVoltage); + return result; +#else + return 1; +#endif +} + +//----- HALEFUSEOneByteReadRAM +int HALEFUSEOneByteReadRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char *Data, IN unsigned char L25OutVoltage) +{ + int result; + + if ( (unsigned int)(Addr - 160) > 0x33 ) + { + result = HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + } + else + { + *Data = -1; + result = 1; + } + return result; +} + +//----- HALEFUSEOneByteWriteRAM +int HALEFUSEOneByteWriteRAM(IN unsigned int CtrlSetting, IN unsigned short Addr, IN unsigned char Data, IN unsigned char L25OutVoltage) +{ +#if EFUSE_WRITE_ENABLE + int result; + if ( (unsigned int)(Addr - 127) <= 0x54 ) + result = 1; + else { + result = HALEFUSEOneByteWriteROM(CtrlSetting, Addr, Data, L25OutVoltage); + } + return result; +#else + return 1; +#endif +} + +//----- ReadEfuseContant +void ReadEfuseContant(IN unsigned char UserCode, IN unsigned char *pContant) +{ + unsigned int i, offset, bcnt, eFuse_Addr = 0; + unsigned char DataTemp0; + unsigned char DataTemp1; + unsigned char * pbuf = pContant; + + do { + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if (DataTemp0 == 0x0FF) break; + if ((DataTemp0 & 0x0F) == 0x0F) { + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE); + offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1; + bcnt = (~DataTemp1) & 0x0F; + if (((UserCode + EFUSE_SECTION_CODE) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION_CODE + 1) << 2)) { + while(bcnt) { + if (bcnt & 1) eFuse_Addr += 2; + bcnt >>= 1; + } + } + else { + int base = (offset - ((EFUSE_SECTION_CODE + UserCode) << 2)) << 3; + i = 0; + while(bcnt) { + if (bcnt & 1) { + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + i], L25EOUTVOLTAGE); + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + i + 1], L25EOUTVOLTAGE); + } + bcnt >>= 1; + i += 2; + } + } + } + else for(i = (~DataTemp0) & 0x0F; i; i >>= 1) if (i & 1) eFuse_Addr += 2; + eFuse_Addr++; + } + while(eFuse_Addr < EFUSE_SECTION_SIZE - 1); +} + +//----- ReadEfuseContant1 +void ReadEfuseContant1(OUT unsigned char *pContant) +{ + ReadEfuseContant(0, pContant); +} + +//----- ReadEfuseContant2 +void ReadEfuseContant2(OUT unsigned char *pContant) +{ + ReadEfuseContant(1, pContant); +} + +//----- ReadEfuseContant3 +void ReadEfuseContant3(OUT unsigned char *pContant) +{ + ReadEfuseContant(2, pContant); +} + +//----- GetRemainingEfuseLength +int GetRemainingEfuseLength(void) +{ + unsigned int i, eFuse_Addr = 0; + unsigned char DataTemp0; + do + { + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if(DataTemp0 == 0x0FF) break; + if((DataTemp0 & 0x0F) == 0x0F) + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + for (i = (~DataTemp0) & 0x0F; i; i >>= 1 ) if (i & 1) eFuse_Addr += 2; + eFuse_Addr++; + } + while(eFuse_Addr < EFUSE_SECTION_SIZE - 1); + return (EFUSE_SECTION_SIZE - 1 - eFuse_Addr); +} + +//----- WriteEfuseContant +int WriteEfuseContant(IN unsigned char UserCode, IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant) +{ +#if EFUSE_WRITE_ENABLE + int result = 0; + unsigned int i, j, eFuse_Addr; // r4@3 + unsigned char DataTemp0; + unsigned int bmask = WordEnable & 0xF; + + if (bmask) { + eFuse_Addr = 0; + do { // eFuse_Addr = 128 - _GetRemainingEfuseLength + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if (DataTemp0 == 0x0ff) break; + if ((DataTemp0 & 0x0F) == 0x0F) + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + for (i = (~DataTemp0) & 0x0F; i; i >>= 1) if (i & 1) eFuse_Addr += 2; + eFuse_Addr++; + } + while (eFuse_Addr <= EFUSE_SECTION_SIZE - 2); + + j = 0; + do + { + if (bmask & 1) j += 2; + bmask >>= 1; + } + while (bmask); + if ((eFuse_Addr + j) <= EFUSE_SECTION_SIZE - 4) + { + HALEFUSEOneByteWriteRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, (((UserCode + EFUSE_SECTION_CODE) << 7) | 0x0F) + ((CodeWordNum & 3) << 5), L25EOUTVOLTAGE); + HALEFUSEOneByteWriteRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr + 1, (((UserCode + EFUSE_SECTION_CODE) << 3) & 0xF0) | ((~bmask) & 0xF), L25EOUTVOLTAGE); + i = 0; + while (i < j) + { + HALEFUSEOneByteWriteRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr + 2 + i, pContant[i], L25EOUTVOLTAGE); + i++; + } + result = 1; + } + } + return result; +#else + return 1; +#endif +} + +//----- WriteEfuseContant1 +int WriteEfuseContant1(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant) +{ +#if EFUSE_WRITE_ENABLE + return WriteEfuseContant(0, CodeWordNum, WordEnable, pContant); +#else + return 1; +#endif +} + +//----- WriteEfuseContant2 +int WriteEfuseContant2(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant) +{ +#if EFUSE_WRITE_ENABLE + return WriteEfuseContant(1, CodeWordNum, WordEnable, pContant); +#else + return 1; +#endif +} + +//----- WriteEfuseContant2 +int WriteEfuseContant3(IN unsigned char CodeWordNum, IN unsigned char WordEnable, IN unsigned char *pContant) +{ +#if EFUSE_WRITE_ENABLE + return WriteEfuseContant(2, CodeWordNum, WordEnable, pContant); +#else + return 1; +#endif +} + +//----- ReadEOTPContant +void ReadEOTPContant(IN unsigned char *pContant) +{ + int i; + for(i = 0; i < OTP_BUF_MAX_LEN; i++ ) + HALOTPOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+EFUSE_SECTION_SIZE, &pContant[i], L25EOUTVOLTAGE); +} + +//----- WriteEOTPContant +void WriteEOTPContant(IN unsigned char *pContant) +{ +#if EFUSE_WRITE_ENABLE + int i; + unsigned char DataTemp0; + for(i = 0; i < OTP_BUF_MAX_LEN; i++ ) { + HALOTPOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+EFUSE_SECTION_SIZE, &DataTemp0, L25EOUTVOLTAGE); + if (DataTemp0 == 0xFF) + HALOTPOneByteWriteRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+EFUSE_SECTION_SIZE, pContant[i], L25EOUTVOLTAGE); + } +#endif +} + +//----- HALJtagOff +void HALJtagOff(void) +{ +#if EFUSE_WRITE_ENABLE + HALEFUSEOneByteWriteROM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), 211, 0xFE, L25EOUTVOLTAGE); +#endif +} + +#endif //CONFIG_EFUSE_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_gdma.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_gdma.c new file mode 100644 index 0000000..a3f242e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_gdma.c @@ -0,0 +1,578 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "hal_gdma.h" + +#ifdef CONFIG_GDMA_EN + +#define MAX_GDMA_INDX 1 +#define MAX_GDMA_CHNL 6 + +static u8 HalGdmaReg[MAX_GDMA_INDX+1]; + +const HAL_GDMA_CHNL GDMA_Chnl_Option[] = { + {0,0,GDMA0_CHANNEL0_IRQ,0}, + {1,0,GDMA1_CHANNEL0_IRQ,0}, + {0,1,GDMA0_CHANNEL1_IRQ,0}, + {1,1,GDMA1_CHANNEL1_IRQ,0}, + {0,2,GDMA0_CHANNEL2_IRQ,0}, + {1,2,GDMA1_CHANNEL2_IRQ,0}, + {0,3,GDMA0_CHANNEL3_IRQ,0}, + {1,3,GDMA1_CHANNEL3_IRQ,0}, + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL GDMA_Multi_Block_Chnl_Option[] = { + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + + +const u16 HalGdmaChnlEn[6] = { + GdmaCh0, GdmaCh1, GdmaCh2, GdmaCh3, + GdmaCh4, GdmaCh5 +}; + + + +VOID HalGdmaOpInit( + IN VOID *Data +) +{ + PHAL_GDMA_OP pHalGdmaOp = (PHAL_GDMA_OP) Data; + + pHalGdmaOp->HalGdmaOnOff = HalGdmaOnOffRtl8195a; + pHalGdmaOp->HalGdamChInit = HalGdamChInitRtl8195a; + pHalGdmaOp->HalGdmaChDis = HalGdmaChDisRtl8195a; + pHalGdmaOp->HalGdmaChEn = HalGdmaChEnRtl8195a; + pHalGdmaOp->HalGdmaChSeting = HalGdmaChSetingRtl8195a; +#ifndef CONFIG_CHIP_E_CUT + pHalGdmaOp->HalGdmaChBlockSeting = HalGdmaChBlockSetingRtl8195a_Patch; +#else + pHalGdmaOp->HalGdmaChBlockSeting = HalGdmaChBlockSetingRtl8195a_V04; +#endif + pHalGdmaOp->HalGdmaChIsrEnAndDis = HalGdmaChIsrEnAndDisRtl8195a; + pHalGdmaOp->HalGdmaChIsrClean = HalGdmaChIsrCleanRtl8195a; + pHalGdmaOp->HalGdmaChCleanAutoSrc = HalGdmaChCleanAutoSrcRtl8195a; + pHalGdmaOp->HalGdmaChCleanAutoDst = HalGdmaChCleanAutoDstRtl8195a; +} + +VOID HalGdmaOn(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + pHalGdmaAdapter->GdmaOnOff = ON; + HalGdmaOnOffRtl8195a((VOID*)pHalGdmaAdapter); +} + +VOID HalGdmaOff(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + pHalGdmaAdapter->GdmaOnOff = OFF; + HalGdmaOnOffRtl8195a((VOID*)pHalGdmaAdapter); +} + +BOOL HalGdmaChInit(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + return (HalGdamChInitRtl8195a((VOID*)pHalGdmaAdapter)); +} + +VOID HalGdmaChDis(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + HalGdmaChDisRtl8195a((VOID*)pHalGdmaAdapter); +} + +VOID HalGdmaChEn(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + HalGdmaChEnRtl8195a((VOID*)pHalGdmaAdapter); +} + +BOOL HalGdmaChSeting(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + return (HalGdmaChSetingRtl8195a((VOID*)pHalGdmaAdapter)); +} + +BOOL HalGdmaChBlockSeting(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ +#ifndef CONFIG_CHIP_E_CUT + return (HalGdmaChBlockSetingRtl8195a_Patch((VOID*)pHalGdmaAdapter)); +#else + return (HalGdmaChBlockSetingRtl8195a_V04((VOID*)pHalGdmaAdapter)); +#endif +} + +VOID HalGdmaChIsrEn(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + pHalGdmaAdapter->IsrCtrl = ENABLE; + HalGdmaChIsrEnAndDisRtl8195a((VOID*)pHalGdmaAdapter); +} + +VOID HalGdmaChIsrDis(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + pHalGdmaAdapter->IsrCtrl = DISABLE; + HalGdmaChIsrEnAndDisRtl8195a((VOID*)pHalGdmaAdapter); +} + +u8 HalGdmaChIsrClean(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + return (HalGdmaChIsrCleanRtl8195a((VOID*)pHalGdmaAdapter)); +} + +VOID HalGdmaChCleanAutoSrc(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + HalGdmaChCleanAutoSrcRtl8195a((VOID*)pHalGdmaAdapter); +} + +VOID HalGdmaChCleanAutoDst(PHAL_GDMA_ADAPTER pHalGdmaAdapter) +{ + HalGdmaChCleanAutoDstRtl8195a((VOID*)pHalGdmaAdapter); +} + +HAL_Status HalGdmaChnlRegister (u8 GdmaIdx, u8 ChnlNum) +{ + u32 mask; + + if ((GdmaIdx > MAX_GDMA_INDX) || (ChnlNum > MAX_GDMA_CHNL)) { + // Invalid GDMA Index or Channel Number + return HAL_ERR_PARA; + } + + mask = 1 << ChnlNum; + + if ((HalGdmaReg[GdmaIdx] & mask) != 0) { + return HAL_BUSY; + } + else { +#if 1 + if (HalGdmaReg[GdmaIdx] == 0) { + if (GdmaIdx == 0) { + ACTCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + } + else { + ACTCK_GDMA1_CCTRL(ON); + GDMA1_FCTRL(ON); + } + } +#endif + HalGdmaReg[GdmaIdx] |= mask; + return HAL_OK; + } +} + +VOID HalGdmaChnlUnRegister (u8 GdmaIdx, u8 ChnlNum) +{ + u32 mask; + + if ((GdmaIdx > MAX_GDMA_INDX) || (ChnlNum > MAX_GDMA_CHNL)) { + // Invalid GDMA Index or Channel Number + return; + } + + mask = 1 << ChnlNum; + + HalGdmaReg[GdmaIdx] &= ~mask; +#if 1 + if (HalGdmaReg[GdmaIdx] == 0) { + if (GdmaIdx == 0) { + ACTCK_GDMA0_CCTRL(OFF); + GDMA0_FCTRL(OFF); + } + else { + ACTCK_GDMA1_CCTRL(OFF); + GDMA1_FCTRL(OFF); + } + } +#endif +} + +PHAL_GDMA_CHNL HalGdmaChnlAlloc (HAL_GDMA_CHNL *pChnlOption) +{ + HAL_GDMA_CHNL *pgdma_chnl; + + pgdma_chnl = pChnlOption; + if (pChnlOption == NULL) { + // Use default GDMA Channel Option table + pgdma_chnl = (HAL_GDMA_CHNL*)&GDMA_Chnl_Option[0]; + } + else{ + pgdma_chnl = (HAL_GDMA_CHNL*) pgdma_chnl; + } + + while (pgdma_chnl->GdmaIndx <= MAX_GDMA_INDX) { + if (HalGdmaChnlRegister(pgdma_chnl->GdmaIndx, pgdma_chnl->GdmaChnl) == HAL_OK) { + // This GDMA Channel is available + break; + } + pgdma_chnl += 1; + } + + if (pgdma_chnl->GdmaIndx > MAX_GDMA_INDX) { + pgdma_chnl = NULL; + } + + return pgdma_chnl; +} + +VOID HalGdmaChnlFree (HAL_GDMA_CHNL *pChnl) +{ + IRQ_HANDLE IrqHandle; + + IrqHandle.IrqNum = pChnl->IrqNum; + InterruptDis(&IrqHandle); + InterruptUnRegister(&IrqHandle); + HalGdmaChnlUnRegister(pChnl->GdmaIndx, pChnl->GdmaChnl); +} + +VOID HalGdmaMemIrqHandler(VOID *pData) +{ + PHAL_GDMA_OBJ pHalGdmaObj=(PHAL_GDMA_OBJ)pData; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PIRQ_HANDLE pGdmaIrqHandle; + + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + pGdmaIrqHandle = &(pHalGdmaObj->GdmaIrqHandle); + // Clean Auto Reload Bit + HalGdmaChCleanAutoDst((VOID*)pHalGdmaAdapter); + + // Clear Pending ISR + HalGdmaChIsrClean((VOID*)pHalGdmaAdapter); + + HalGdmaChDis((VOID*)(pHalGdmaAdapter)); + pHalGdmaObj->Busy = 0; + + if (pGdmaIrqHandle->IrqFun != NULL) { + pGdmaIrqHandle->IrqFun((VOID*)pGdmaIrqHandle->Data); + } +} + +BOOL HalGdmaMemCpyAggrInit(PHAL_GDMA_OBJ pHalGdmaObj) +{ + HAL_GDMA_CHNL *pgdma_chnl; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PIRQ_HANDLE pGdmaIrqHandle; + IRQ_HANDLE IrqHandle; + + pgdma_chnl = HalGdmaChnlAlloc((PHAL_GDMA_CHNL) &GDMA_Multi_Block_Chnl_Option[0]); // get a whatever GDMA channel + if (NULL == pgdma_chnl) { + DBG_GDMA_ERR("%s: Cannot allocate a GDMA Channel\n", __FUNCTION__); + return _FALSE; + } + + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + pGdmaIrqHandle = &(pHalGdmaObj->GdmaIrqHandle); + + DBG_GDMA_INFO("%s: Use GDMA%d CH%d\n", __FUNCTION__, pgdma_chnl->GdmaIndx, pgdma_chnl->GdmaChnl); + + _memset((void *)pHalGdmaAdapter, 0, sizeof(HAL_GDMA_ADAPTER)); + + pHalGdmaAdapter->GdmaCtl.TtFc = TTFCMemToMem; + pHalGdmaAdapter->GdmaCtl.Done = 1; + pHalGdmaAdapter->MuliBlockCunt = 0; + pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->GdmaIsrType = (TransferType|ErrType); + pHalGdmaAdapter->IsrCtrl = ENABLE; + pHalGdmaAdapter->GdmaOnOff = ON; + pHalGdmaAdapter->GdmaCtl.IntEn = 1; + pHalGdmaAdapter->Rsvd4to7 = 1; + pHalGdmaAdapter->Llpctrl = 1; + pGdmaIrqHandle->IrqNum = pgdma_chnl->IrqNum; + pGdmaIrqHandle->Priority = 10; + + IrqHandle.IrqFun = (IRQ_FUN) HalGdmaMemIrqHandler; + IrqHandle.Data = (u32) pHalGdmaObj; + IrqHandle.IrqNum = pGdmaIrqHandle->IrqNum; + IrqHandle.Priority = pGdmaIrqHandle->Priority; + + InterruptRegister(&IrqHandle); + InterruptEn(&IrqHandle); + pHalGdmaObj->Busy = 0; + + return _TRUE; +} + + +VOID HalGdmaMultiBlockSetting(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + u8 BlockNumber; + u8 BlockIndex; + u8 FourBytesAlign; + + BlockNumber = pHalGdmaObj->BlockNum; + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 1; + pHalGdmaAdapter->GdmaCtl.LlpDstEn = 1; + + if(((pHalGdmaBlock[0].SrcAddr & 0x03) == 0) &&((pHalGdmaBlock[0].DstAddr & 0x03) == 0) + && ((pHalGdmaBlock[0].BlockLength & 0X03) == 0)){ + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + FourBytesAlign = 1; + } + else{ + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + FourBytesAlign = 0; + } + + for(BlockIndex = 0; BlockIndex < BlockNumber; BlockIndex++){ + + pHalGdmaObj->GdmaChLli[BlockIndex].Sarx = pHalGdmaBlock[BlockIndex].SrcAddr; + pHalGdmaObj->GdmaChLli[BlockIndex].Darx = pHalGdmaBlock[BlockIndex].DstAddr; + pHalGdmaObj->BlockSizeList[BlockIndex].pNextBlockSiz = &pHalGdmaObj->BlockSizeList[BlockIndex + 1]; + + if(FourBytesAlign){ + pHalGdmaObj->BlockSizeList[BlockIndex].BlockSize = pHalGdmaBlock[BlockIndex].BlockLength >> 2; + } + else{ + pHalGdmaObj->BlockSizeList[BlockIndex].BlockSize = pHalGdmaBlock[BlockIndex].BlockLength; + } + + pHalGdmaObj->Lli[BlockIndex].pLliEle = (GDMA_CH_LLI_ELE*) &pHalGdmaObj->GdmaChLli[BlockIndex]; + pHalGdmaObj->Lli[BlockIndex].pNextLli = &pHalGdmaObj->Lli[BlockIndex + 1]; + + + if(BlockIndex == BlockNumber - 1){ + pHalGdmaObj->BlockSizeList[BlockIndex].pNextBlockSiz = NULL; + pHalGdmaObj->Lli[BlockIndex].pNextLli = NULL; + } + //DBG_GDMA_INFO("Lli[%d].pLiEle = %x\r\n", BlockIndex,Lli[BlockIndex].pLliEle); + //DBG_GDMA_INFO("Lli[%d].pNextLli = %x\r\n", BlockIndex,Lli[BlockIndex].pNextLli); + } + + pHalGdmaAdapter->pBlockSizeList = (struct BLOCK_SIZE_LIST*) &pHalGdmaObj->BlockSizeList; + pHalGdmaAdapter->pLlix = (struct GDMA_CH_LLI*) &pHalGdmaObj->Lli; + //DBG_GDMA_INFO("pHalGdmaAdapter->pBlockSizeList = %x\r\n", pHalGdmaAdapter->pBlockSizeList); + //DBG_GDMA_INFO("pHalGdmaAdapter->pLlix = %x\r\n", pHalGdmaAdapter->pLlix ); +} + +VOID HalGdmaLLPMemAlign(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PGDMA_CH_LLI_ELE pLliEle; + struct GDMA_CH_LLI *pGdmaChLli; + struct BLOCK_SIZE_LIST *pGdmaChBkLi; + u32 CtlxLow; + u32 CtlxUp; + u8 BlockNumber; + u8 BlockIndex; + + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + BlockNumber = pHalGdmaObj->BlockNum; + + pLliEle = pHalGdmaAdapter->pLlix->pLliEle; + pGdmaChLli = pHalGdmaAdapter->pLlix->pNextLli; + pGdmaChBkLi = pHalGdmaAdapter->pBlockSizeList; + + //4 Move to the second block to configure Memory Alginment setting + pLliEle->Llpx = (u32) pGdmaChLli->pLliEle; + pGdmaChBkLi = pGdmaChBkLi ->pNextBlockSiz; + + for(BlockIndex = 1; BlockIndex < BlockNumber; BlockIndex++){ + pLliEle = pGdmaChLli->pLliEle; + CtlxLow = pLliEle->CtlxLow; + CtlxLow &= (BIT_INVC_CTLX_LO_DST_TR_WIDTH & BIT_INVC_CTLX_LO_SRC_TR_WIDTH); + CtlxUp = pLliEle->CtlxUp; + CtlxUp &= (BIT_INVC_CTLX_UP_BLOCK_BS); + + if(((pHalGdmaBlock[BlockIndex].SrcAddr & 0x03) == 0) &&((pHalGdmaBlock[BlockIndex].DstAddr & 0x03) == 0) + && ((pHalGdmaBlock[BlockIndex].BlockLength & 0X03) == 0)){ + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + pGdmaChBkLi->BlockSize = pHalGdmaBlock[BlockIndex].BlockLength>> 2; + + } + else{ + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + pGdmaChBkLi->BlockSize = pHalGdmaBlock[BlockIndex].BlockLength; + } + + CtlxLow |= (BIT_CTLX_LO_DST_TR_WIDTH(pHalGdmaAdapter->GdmaCtl.DstTrWidth) | + BIT_CTLX_LO_SRC_TR_WIDTH(pHalGdmaAdapter->GdmaCtl.SrcTrWidth)); + CtlxUp |= BIT_CTLX_UP_BLOCK_BS(pGdmaChBkLi->BlockSize); + + pGdmaChLli = pGdmaChLli->pNextLli; + pGdmaChBkLi = pGdmaChBkLi->pNextBlockSiz; + pLliEle->CtlxLow = CtlxLow; + pLliEle->CtlxUp = CtlxUp; + pLliEle->Llpx = (u32)(pGdmaChLli->pLliEle); + + } +} + +VOID HalGdmaMemAggr(PHAL_GDMA_OBJ pHalGdmaObj, PHAL_GDMA_BLOCK pHalGdmaBlock) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + u8 BlockNumber; + + BlockNumber = pHalGdmaObj->BlockNum; + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + + if (pHalGdmaObj->Busy) { + DBG_GDMA_ERR("%s: ==> GDMA is Busy\r\n", __FUNCTION__); + return; + } + pHalGdmaObj->Busy = 1; + + pHalGdmaAdapter->MaxMuliBlock = BlockNumber; + pHalGdmaAdapter->ChSar = pHalGdmaBlock[0].SrcAddr; + pHalGdmaAdapter->ChDar = pHalGdmaBlock[0].DstAddr; + + HalGdmaMultiBlockSetting(pHalGdmaObj, pHalGdmaBlock); + HalGdmaOn((pHalGdmaAdapter)); + HalGdmaChIsrEn((pHalGdmaAdapter)); + HalGdmaChBlockSeting((pHalGdmaAdapter)); + HalGdmaLLPMemAlign(pHalGdmaObj, pHalGdmaBlock); + HalGdmaChEn((pHalGdmaAdapter)); + +} + + + +BOOL HalGdmaMemCpyInit(PHAL_GDMA_OBJ pHalGdmaObj) +{ + HAL_GDMA_CHNL *pgdma_chnl; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PIRQ_HANDLE pGdmaIrqHandle; + IRQ_HANDLE IrqHandle; + + pgdma_chnl = HalGdmaChnlAlloc(NULL); // get a whatever GDMA channel + if (NULL == pgdma_chnl) { + DBG_GDMA_ERR("%s: Cannot allocate a GDMA Channel\n", __FUNCTION__); + return _FALSE; + } + + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + pGdmaIrqHandle = &(pHalGdmaObj->GdmaIrqHandle); + + DBG_GDMA_INFO("%s: Use GDMA%d CH%d\n", __FUNCTION__, pgdma_chnl->GdmaIndx, pgdma_chnl->GdmaChnl); +#if 0 + if (pgdma_chnl->GdmaIndx == 0) { + ACTCK_GDMA0_CCTRL(ON); + GDMA0_FCTRL(ON); + } + else if (pgdma_chnl->GdmaIndx == 1) { + ACTCK_GDMA1_CCTRL(ON); + GDMA1_FCTRL(ON); + } +#endif + _memset((void *)pHalGdmaAdapter, 0, sizeof(HAL_GDMA_ADAPTER)); + +// pHalGdmaAdapter->GdmaCtl.TtFc = TTFCMemToMem; + pHalGdmaAdapter->GdmaCtl.Done = 1; +// pHalGdmaAdapter->MuliBlockCunt = 0; +// pHalGdmaAdapter->MaxMuliBlock = 1; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->GdmaIsrType = (TransferType|ErrType); + pHalGdmaAdapter->IsrCtrl = ENABLE; + pHalGdmaAdapter->GdmaOnOff = ON; + + pHalGdmaAdapter->GdmaCtl.IntEn = 1; +// pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; +// pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; +// pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; +// pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; +// pHalGdmaAdapter->GdmaCtl.Dinc = IncType; +// pHalGdmaAdapter->GdmaCtl.Sinc = IncType; + + pGdmaIrqHandle->IrqNum = pgdma_chnl->IrqNum; + pGdmaIrqHandle->Priority = 10; + + IrqHandle.IrqFun = (IRQ_FUN) HalGdmaMemIrqHandler; + IrqHandle.Data = (u32) pHalGdmaObj; + IrqHandle.IrqNum = pGdmaIrqHandle->IrqNum; + IrqHandle.Priority = pGdmaIrqHandle->Priority; + + InterruptRegister(&IrqHandle); + InterruptEn(&IrqHandle); + pHalGdmaObj->Busy = 0; + + return _TRUE; +} + +VOID HalGdmaMemCpyDeInit(PHAL_GDMA_OBJ pHalGdmaObj) +{ + HAL_GDMA_CHNL GdmaChnl; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PIRQ_HANDLE pGdmaIrqHandle; + + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + pGdmaIrqHandle = &(pHalGdmaObj->GdmaIrqHandle); + + GdmaChnl.GdmaIndx = pHalGdmaAdapter->GdmaIndex; + GdmaChnl.GdmaChnl = pHalGdmaAdapter->ChNum; + GdmaChnl.IrqNum = pGdmaIrqHandle->IrqNum; + HalGdmaChnlFree(&GdmaChnl); +} + +// If multi-task using the same GDMA Object, then it needs a mutex to protect this procedure +VOID* HalGdmaMemCpy(PHAL_GDMA_OBJ pHalGdmaObj, void* pDest, void* pSrc, u32 len) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if (pHalGdmaObj->Busy) { + DBG_GDMA_ERR("%s: ==> GDMA is Busy\r\n", __FUNCTION__); + return 0; + } + pHalGdmaObj->Busy = 1; + pHalGdmaAdapter = &(pHalGdmaObj->HalGdmaAdapter); + + DBG_GDMA_INFO("%s: ==> Src=0x%x Dst=0x%x Len=%d\r\n", __FUNCTION__, pSrc, pDest, len); + if ((((u32)pSrc & 0x03)==0) && + (((u32)pDest & 0x03)==0) && + ((len & 0x03)== 0)) { + // 4-bytes aligned, move 4 bytes each transfer + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthFourBytes; + pHalGdmaAdapter->GdmaCtl.BlockSize = len >> 2; + } + else { + pHalGdmaAdapter->GdmaCtl.SrcMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.SrcTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.DestMsize = MsizeEight; + pHalGdmaAdapter->GdmaCtl.DstTrWidth = TrWidthOneByte; + pHalGdmaAdapter->GdmaCtl.BlockSize = len; + } + + pHalGdmaAdapter->ChSar = (u32)pSrc; + pHalGdmaAdapter->ChDar = (u32)pDest; + pHalGdmaAdapter->PacketLen = len; + + HalGdmaOn((pHalGdmaAdapter)); + HalGdmaChIsrEn((pHalGdmaAdapter)); + HalGdmaChSeting((pHalGdmaAdapter)); + HalGdmaChEn((pHalGdmaAdapter)); + + return (pDest); +} + +#endif // CONFIG_GDMA_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_gpio.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_gpio.c new file mode 100644 index 0000000..ed665ac --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_gpio.c @@ -0,0 +1,207 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" + +#ifdef CONFIG_GPIO_EN + +HAL_GPIO_ADAPTER gHAL_Gpio_Adapter; +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; + +extern VOID GPIO_PullCtrl_8195a(u32 chip_pin, u8 pull_type); + +/** + * @brief To get the GPIO IP Pin name for the given chip pin name + * + * @param chip_pin: The chip pin name. + * + * @retval The gotten GPIO IP pin name + */ +u32 +HAL_GPIO_GetPinName( + u32 chip_pin +) +{ + return HAL_GPIO_GetIPPinName_8195a((u32)chip_pin); +} + +/** + * @brief Set the GPIO pad Pull type + * + * @param pin: The pin for pull type control. + * @param mode: the pull type for the pin. + * @return None + */ +VOID +HAL_GPIO_PullCtrl( + u32 pin, + u32 mode +) +{ + u8 pull_type; + + switch (mode) { + case hal_PullNone: + pull_type = DIN_PULL_NONE; + break; + + case hal_PullDown: + pull_type = DIN_PULL_LOW; + break; + + case hal_PullUp: + pull_type = DIN_PULL_HIGH; + break; + + case hal_OpenDrain: + default: + pull_type = DIN_PULL_NONE; + break; + } + +// HAL_GPIO_PullCtrl_8195a (pin, pull_type); + GPIO_PullCtrl_8195a (pin, pull_type); +} + + +/** + * @brief Initializes a GPIO Pin by the GPIO_Pin parameters. + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin initialization. + * + * @retval HAL_Status + */ +VOID +HAL_GPIO_Init( + HAL_GPIO_PIN *GPIO_Pin +) +{ + u8 port_num; + u8 pin_num; + u32 chip_pin; + HAL_Status ret; + + if (_pHAL_Gpio_Adapter == NULL) { + _pHAL_Gpio_Adapter = &gHAL_Gpio_Adapter; +// DBG_GPIO_INFO("HAL_GPIO_Init: Initial GPIO Adapter\n "); + } + + port_num = HAL_GPIO_GET_PORT_BY_NAME(GPIO_Pin->pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(GPIO_Pin->pin_name); + chip_pin = GPIO_GetChipPinName_8195a(port_num, pin_num); + if (GpioFunctionChk(chip_pin, ENABLE) == _FALSE) { +// if((chip_pin > 0x03) && (chip_pin != 0x25)) { + DBG_GPIO_ERR("HAL_GPIO_Init: GPIO Pin(%x) Unavailable\n ", chip_pin); + return; +// } +// else DBG_GPIO_WARN("HAL_GPIO_Init: GPIO Pin(%x) Warning for RTL8710AF!\n ", chip_pin); + } + + // Make the pin pull control default as High-Z + GPIO_PullCtrl_8195a(chip_pin, HAL_GPIO_HIGHZ); + + ret = HAL_GPIO_Init_8195a(GPIO_Pin); + + if (ret != HAL_OK) { + GpioFunctionChk(chip_pin, DISABLE); + } +} + +/** + * @brief Initializes a GPIO Pin as a interrupt signal + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin initialization. + * + * @retval HAL_Status + */ +VOID +HAL_GPIO_Irq_Init( + HAL_GPIO_PIN *GPIO_Pin +) +{ + u8 port_num; + u8 pin_num; + u32 chip_pin; + HAL_Status ret; + + if (_pHAL_Gpio_Adapter == NULL) { + _pHAL_Gpio_Adapter = &gHAL_Gpio_Adapter; +// DBG_GPIO_INFO("%s: Initial GPIO Adapter\n ", __FUNCTION__); + } + + if (_pHAL_Gpio_Adapter->IrqHandle.IrqFun == NULL) { + _pHAL_Gpio_Adapter->IrqHandle.IrqFun = (IRQ_FUN)HAL_GPIO_MbedIrqHandler_8195a; + _pHAL_Gpio_Adapter->IrqHandle.Priority = 6; + HAL_GPIO_RegIrq_8195a(&_pHAL_Gpio_Adapter->IrqHandle); + InterruptEn(&_pHAL_Gpio_Adapter->IrqHandle); +// DBG_GPIO_INFO("%s: Initial GPIO IRQ Adapter\n ", __FUNCTION__); + } + + port_num = HAL_GPIO_GET_PORT_BY_NAME(GPIO_Pin->pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(GPIO_Pin->pin_name); + chip_pin = GPIO_GetChipPinName_8195a(port_num, pin_num); + if (GpioFunctionChk(chip_pin, ENABLE) == _FALSE) { + DBG_GPIO_ERR("HAL_GPIO_Irq_Init: GPIO Pin(%x) Unavailable\n ", chip_pin); + return; + } + + DBG_GPIO_INFO("HAL_GPIO_Irq_Init: GPIO(name=0x%x)(mode=%d)\n ", GPIO_Pin->pin_name, + GPIO_Pin->pin_mode); + HAL_GPIO_MaskIrq_8195a(GPIO_Pin); + ret = HAL_GPIO_Init_8195a(GPIO_Pin); + if (ret != HAL_OK) { + GpioFunctionChk(chip_pin, DISABLE); + } +} + +/** + * @brief UnInitial GPIO Adapter + * + * + * @retval HAL_Status + */ +VOID +HAL_GPIO_IP_DeInit( + VOID +) +{ + if (_pHAL_Gpio_Adapter != NULL) { + InterruptDis(&_pHAL_Gpio_Adapter->IrqHandle); + HAL_GPIO_UnRegIrq_8195a(&_pHAL_Gpio_Adapter->IrqHandle); + _pHAL_Gpio_Adapter = NULL; + } + +} + +/** + * @brief De-Initializes a GPIO Pin, reset it as default setting. + * + * @param GPIO_Pin: The data structer which contains the parameters for the GPIO Pin. + * + * @retval HAL_Status + */ +VOID +HAL_GPIO_DeInit( + HAL_GPIO_PIN *GPIO_Pin +) +{ + u8 port_num; + u8 pin_num; + u32 chip_pin; + + port_num = HAL_GPIO_GET_PORT_BY_NAME(GPIO_Pin->pin_name); + pin_num = HAL_GPIO_GET_PIN_BY_NAME(GPIO_Pin->pin_name); + chip_pin = GPIO_GetChipPinName_8195a(port_num, pin_num); + HAL_GPIO_DeInit_8195a(GPIO_Pin); + + GpioFunctionChk(chip_pin, DISABLE); +} + + +#endif // CONFIG_GPIO_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2c.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2c.c new file mode 100644 index 0000000..eb628a2 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2c.c @@ -0,0 +1,2941 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include +#include "hal_i2c.h" + +#ifdef CONFIG_I2C_EN +//--------------------------------------------------------------------------------------------------- +//External functions +//--------------------------------------------------------------------------------------------------- +extern HAL_TIMER_OP HalTimerOp; + +#define I2C_STATIC_ALLOC 1 +/* I2C SAL global variables declaration when kernel disabled */ +#ifdef I2C_STATIC_ALLOC + HAL_I2C_OP HalI2COpSAL; +#endif + +#if I2C0_USED /*#if I2C0_USED*/ +#ifdef I2C_STATIC_ALLOC + SAL_I2C_MNGT_ADPT SalI2C0MngtAdpt; + + SAL_I2C_HND_PRIV SalI2C0HndPriv; + + HAL_I2C_INIT_DAT HalI2C0InitData; + + IRQ_HANDLE I2C0IrqHandleDat; + + HAL_GDMA_ADAPTER HalI2C0TxGdmaAdpt; + + HAL_GDMA_ADAPTER HalI2C0RxGdmaAdpt; + + HAL_GDMA_OP HalI2C0GdmaOp; + + IRQ_HANDLE I2C0TxGdmaIrqHandleDat; + + IRQ_HANDLE I2C0RxGdmaIrqHandleDat; + + SAL_I2C_USER_CB SalI2C0UserCB; + + SAL_I2C_USERCB_ADPT SalI2C0UserCBAdpt[SAL_USER_CB_NUM]; + + SAL_I2C_DMA_USER_DEF SalI2C0DmaUserDef; +#endif +#endif /*#if I2C0_USED*/ + +#if I2C1_USED /*#if I2C1_USED*/ +#ifdef I2C_STATIC_ALLOC + SAL_I2C_MNGT_ADPT SalI2C1MngtAdpt; + + SAL_I2C_HND_PRIV SalI2C1HndPriv; + + HAL_I2C_INIT_DAT HalI2C1InitData; + + IRQ_HANDLE I2C1IrqHandleDat; + + HAL_GDMA_ADAPTER HalI2C1TxGdmaAdpt; + + HAL_GDMA_ADAPTER HalI2C1RxGdmaAdpt; + + HAL_GDMA_OP HalI2C1GdmaOp; + + IRQ_HANDLE I2C1TxGdmaIrqHandleDat; + + IRQ_HANDLE I2C1RxGdmaIrqHandleDat; + + SAL_I2C_USER_CB SalI2C1UserCB; + + SAL_I2C_USERCB_ADPT SalI2C1UserCBAdpt[SAL_USER_CB_NUM]; + + SAL_I2C_DMA_USER_DEF SalI2C1DmaUserDef; +#endif +#endif /*#if I2C1_USED*/ + +#if I2C2_USED /*#if I2C2_USED*/ +#ifdef I2C_STATIC_ALLOC + + SAL_I2C_MNGT_ADPT SalI2C2MngtAdpt; + + SAL_I2C_HND_PRIV SalI2C2HndPriv; + + HAL_I2C_INIT_DAT HalI2C2InitData; + + IRQ_HANDLE I2C2IrqHandleDat; + + HAL_GDMA_ADAPTER HalI2C2TxGdmaAdpt; + + HAL_GDMA_ADAPTER HalI2C2RxGdmaAdpt; + + HAL_GDMA_OP HalI2C2GdmaOp; + + IRQ_HANDLE I2C2TxGdmaIrqHandleDat; + + IRQ_HANDLE I2C2RxGdmaIrqHandleDat; + + SAL_I2C_USER_CB SalI2C2UserCB; + + SAL_I2C_USERCB_ADPT SalI2C2UserCBAdpt[SAL_USER_CB_NUM]; + + SAL_I2C_DMA_USER_DEF SalI2C2DmaUserDef; +#endif +#endif /*#if I2C2_USED*/ + +#if I2C3_USED /*#if I2C3_USED*/ +#ifdef I2C_STATIC_ALLOC + + SAL_I2C_MNGT_ADPT SalI2C3MngtAdpt; + + SAL_I2C_HND_PRIV SalI2C3HndPriv; + + HAL_I2C_INIT_DAT HalI2C3InitData; + + IRQ_HANDLE I2C3IrqHandleDat; + + HAL_GDMA_ADAPTER HalI2C3TxGdmaAdpt; + + HAL_GDMA_ADAPTER HalI2C3RxGdmaAdpt; + + HAL_GDMA_OP HalI2C3GdmaOp; + + IRQ_HANDLE I2C3TxGdmaIrqHandleDat; + + IRQ_HANDLE I2C3RxGdmaIrqHandleDat; + + SAL_I2C_USER_CB SalI2C3UserCB; + + SAL_I2C_USERCB_ADPT SalI2C3UserCBAdpt[SAL_USER_CB_NUM]; + + SAL_I2C_DMA_USER_DEF SalI2C3DmaUserDef; +#endif +#endif /*#if I2C3_USED*/ + +/* Used only for A~C Version */ +#ifndef CONFIG_CHIP_E_CUT + + + +VOID +HalI2COpInit_Patch( + IN VOID *Data +) +{ + PHAL_I2C_OP pHalI2COp = (PHAL_I2C_OP) Data; + + pHalI2COp->HalI2CInit = HalI2CInit8195a_Patch; + DBG_I2C_INFO("HalOpInit->HalI2CInit:%x\n",pHalI2COp->HalI2CInit); + + pHalI2COp->HalI2CDeInit = HalI2CDeInit8195a; + DBG_I2C_INFO("HalOpInit->HalI2CDeInit:%x\n",pHalI2COp->HalI2CDeInit); + + pHalI2COp->HalI2CSend = HalI2CSendRtl8195a_Patch; + DBG_I2C_INFO("HalOpInit->HalI2CSend:%x\n",pHalI2COp->HalI2CSend); + + pHalI2COp->HalI2CReceive = HalI2CReceiveRtl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CReceive:%x\n",pHalI2COp->HalI2CReceive); + + pHalI2COp->HalI2CEnable = HalI2CEnableRtl8195a_Patch; + DBG_I2C_INFO("HalOpInit->HalI2CEnable:%x\n",pHalI2COp->HalI2CEnable); + + pHalI2COp->HalI2CIntrCtrl = HalI2CIntrCtrl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CIntrCtrl:%x\n",pHalI2COp->HalI2CIntrCtrl); + + pHalI2COp->HalI2CReadReg = HalI2CReadRegRtl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CReadReg:%x\n",pHalI2COp->HalI2CReadReg); + + pHalI2COp->HalI2CWriteReg = HalI2CWriteRegRtl8195a; + DBG_I2C_INFO("pHalI2COp->HalI2CWriteReg:%x\n",pHalI2COp->HalI2CWriteReg); + + pHalI2COp->HalI2CSetCLK = HalI2CSetCLKRtl8195a_Patch; + DBG_I2C_INFO("HalOpInit->HalI2CSetCLK:%x\n",pHalI2COp->HalI2CSetCLK); + + pHalI2COp->HalI2CMassSend = HalI2CMassSendRtl8195a_Patch; + DBG_I2C_INFO("HalOpInit->HalI2CMassSend:%x\n",pHalI2COp->HalI2CMassSend); + + pHalI2COp->HalI2CClrIntr = HalI2CClrIntrRtl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CClrIntr:%x\n",pHalI2COp->HalI2CClrIntr); + + pHalI2COp->HalI2CClrAllIntr = HalI2CClrAllIntrRtl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CClrAllIntr:%x\n",pHalI2COp->HalI2CClrAllIntr); + + pHalI2COp->HalI2CDMACtrl = HalI2CDMACtrl8195a; + DBG_I2C_INFO("HalOpInit->HalI2CDMACtrl:%x\n",pHalI2COp->HalI2CDMACtrl); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// I2CISRHandle +// +// Description: +// I2C Interrupt Service Routine. +// According to the input pointer to SAL_I2C_HND, all the rest pointers will be +// found and be used to the rest part of this servie routine. +// The following types of interrupt will be taken care: +// - General Call (providing General Call Callback). Slave receives a general call. +// - STOP Bit (NOT providing General Call Callback) +// - START Bit (NOTproviding General Call Callback) +// - I2C Activity (NOTproviding General Call Callback) +// - RX Done (providing Error Callback). The slave transmitter does NOT +// receive a proper NACK for the end of whole transfer. +// - TX Abort (providing Error Call Callback). The Master/Slave +// transmitting is terminated. +// - RD Req (providing TX and TXC Callback). Slave gets a Read Request +// and starts a slave-transmitter operation. The slave transmit +// data will be written into slave TX FIFO from user data buffer. +// - TX Empty (providing TX and TXC Callback). Master TX FIFO is empty. +// The user transmit data will be written into master TX FIFO +// from user data buffer. +// - TX Over (providing Error Callback). Master TX FIFO is Overflow. +// - RX Full (providing RX and RXC Callback). Master/Slave RX FIFO contains +// data. And the received data will be put into Master/Slave user +// receive data buffer. +// - RX Over (providing Error Callback). Master/Slave RX FIFO is Overflow. +// - RX Under (providing Error Callback). Master/Slave RX FIFO is Underflow. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// NA +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//---------------------------------------------------------------------------------------------------- +VOID +I2CISRHandle_Patch( + IN VOID *Data +){ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + PSAL_I2C_HND_PRIV pSalI2CHNDPriv = NULL; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; + PSAL_I2C_USER_CB pSalI2CUserCB = NULL; + u32 I2CLocalTemp = 0; + u32 I2CInTOTcnt = 0; + u32 I2CIrqIdx = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + volatile u32 I2CLocalRawSts = 0; + u32 I2CStsTmp = 0; + + /* To get the SAL_I2C_MNGT_ADPT pointer, and parse the rest pointers */ + pSalI2CHNDPriv = CONTAINER_OF(pSalI2CHND, SAL_I2C_HND_PRIV, SalI2CHndPriv); + pSalI2CMngtAdpt = CONTAINER_OF(pSalI2CHNDPriv->ppSalI2CHnd, SAL_I2C_MNGT_ADPT, pSalHndPriv); + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + I2CInTOTcnt = pSalI2CMngtAdpt->InnerTimeOut; + I2CIrqIdx = pHalI2CInitDat->I2CIdx; + pSalI2CUserCB = pSalI2CHND->pUserCB; + + /* I2C General Call Intr*/ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_GEN_CALL(1)) { + + DBG_I2C_WARN("I2C%d INTR_GEN_CALL\n",I2CIrqIdx); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_GEN_CALL; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* Invoke I2C General Call callback if available*/ + if (pSalI2CUserCB->pGENCALLCB->USERCB != NULL) { + pSalI2CUserCB->pGENCALLCB->USERCB((void *)pSalI2CUserCB->pGENCALLCB->USERData); + } + } + + /* I2C START DET Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_START_DET(1)) { + + DBG_I2C_WARN("I2C%d INTR_START_DET\n",I2CIrqIdx); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_START_DET; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + } + + /* I2C STOP DET Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_STOP_DET(1)) { + + DBG_I2C_WARN("I2C%d INTR_STOP_DET\n",I2CIrqIdx); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_STOP_DET; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + } + + /* I2C Activity Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_ACTIVITY(1)) { + + DBG_I2C_WARN("I2C%d INTR_ACTIVITY\n",I2CIrqIdx); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_ACTIVITY; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + } + + /* I2C RX Done Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_RX_DONE(1)) { + if ((pSalI2CHND->DevSts == I2C_STS_TX_READY) || (pSalI2CHND->DevSts == I2C_STS_TX_ING)) { + /* Disable I2C TX Related Interrupts */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_OVER | + BIT_IC_INTR_MASK_M_RX_DONE | + BIT_IC_INTR_MASK_M_RD_REQ); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + + /* Invoke I2C TX complete callback if available */ + if (pSalI2CUserCB->pTXCCB->USERCB != NULL) + pSalI2CUserCB->pTXCCB->USERCB((void *)pSalI2CUserCB->pTXCCB->USERData); + } else { + DBG_I2C_ERR("I2C%d INTR_RX_DONE\n",I2CIrqIdx); + DBG_I2C_ERR("I2C%d IC_TXFLR:%2x\n",I2CIrqIdx, + pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TXFLR)); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RX_DONE; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_ERROR; + + /* Update I2C error type */ + pSalI2CHND->ErrType |= I2C_ERR_SLV_TX_NACK; + + /* Invoke I2C error callback if available */ + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + } + } + + /* I2C TX Abort Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_TX_ABRT(1)) { + I2CStsTmp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + DBG_I2C_ERR("!I2C%d INTR_TX_ABRT!\n",I2CIrqIdx); + DBG_I2C_ERR("I2C%d IC_TX_ABRT_SOURCE[%2x]: %x\n", I2CIrqIdx, REG_DW_I2C_IC_TX_ABRT_SOURCE, I2CStsTmp); + DBG_I2C_ERR("Dev Sts:%x\n",pSalI2CHND->DevSts); + DBG_I2C_ERR("rx len:%x\n",pSalI2CHND->pRXBuf->DataLen); + DBG_I2C_ERR("tx len:%x\n",pSalI2CHND->pTXBuf->DataLen); + DBG_I2C_ERR("raw sts:%x\n",pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT)); + DBG_I2C_ERR("ic sts:%x\n",pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS)); + /* Clear I2C Interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_ABRT; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + I2CLocalTemp = pSalI2CHND->DevSts; + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_ERROR; + + /* Update I2C error type */ + if ((I2CStsTmp & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CStsTmp & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + + + /* Invoke I2C error callback */ + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_RTY) { + if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE) { + if ((I2CLocalTemp == I2C_STS_RX_READY) || (I2CLocalTemp == I2C_STS_RX_ING)) { + /* Clear Abort source */ + pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_CLR_TX_ABRT); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_RX_ING; + + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & BIT_IC_STATUS_TFNF) { + if (pSalI2CMngtAdpt->MstRDCmdCnt > 0) { + pHalI2CInitDat->I2CCmd = I2C_READ_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pRXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + if ((pSalI2CMngtAdpt->MstRDCmdCnt == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + pSalI2CMngtAdpt->MstRDCmdCnt--; + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + } + + } + } + else if ((I2CLocalTemp == I2C_STS_TX_READY) || (I2CLocalTemp == I2C_STS_TX_ING)){ + /* Clear Abort source */ + pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_CLR_TX_ABRT); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Return to the former transfer status */ + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & BIT_IC_STATUS_TFNF) { + pHalI2CInitDat->I2CCmd = I2C_WRITE_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + if ((pSalI2CHND->pTXBuf->DataLen == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + } + } + } + } + } + + /* I2C RD REQ Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_RD_REQ(1)) { + /* Confirm it's slave mode */ + if (pSalI2CHND->I2CMaster == I2C_SLAVE_MODE) { + if (pSalI2CHND->DevSts == I2C_STS_IDLE) { + /* Disable I2C RD REQ Interrupts first */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_RD_REQ); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + /* Invoke I2C rd req callback if available */ + if (pSalI2CUserCB->pRDREQCB->USERCB != NULL) + pSalI2CUserCB->pRDREQCB->USERCB((void *)pSalI2CUserCB->pRDREQCB->USERData); + } else if ((pSalI2CHND->DevSts == I2C_STS_TX_READY) || (pSalI2CHND->DevSts == I2C_STS_TX_ING)) { + if (pSalI2CHND->pTXBuf->DataLen>0) { + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Invoke I2C TX callback if available */ + if (pSalI2CUserCB->pTXCB->USERCB != NULL) + pSalI2CUserCB->pTXCB->USERCB((void *)pSalI2CUserCB->pTXCB->USERData); + + /* I2C Slave transmits data to Master. If the TX FIFO is NOT full, + write one byte from slave TX buffer to TX FIFO. */ + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_TFNF)) == BIT_IC_STATUS_TFNF) { + pHalI2CInitDat->I2CCmd = I2C_WRITE_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + if ((pSalI2CHND->pTXBuf->DataLen == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + } + } + + /* To clear Read Request Intr */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RD_REQ; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* To check I2C slave TX data length. If all the data are transmitted, + mask all the interrupts and invoke the user callback */ + if (!pSalI2CHND->pTXBuf->DataLen) { + /* This is a software patch */ + pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_RAW_INTR_STAT); + HalDelayUs(1000); + + /* Disable I2C TX Related Interrupts */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_OVER | + BIT_IC_INTR_MASK_M_RX_DONE | + BIT_IC_INTR_MASK_M_RD_REQ); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + + /* Invoke I2C TX complete callback if available */ + if (pSalI2CUserCB->pTXCCB->USERCB != NULL) + pSalI2CUserCB->pTXCCB->USERCB((void *)pSalI2CUserCB->pTXCCB->USERData); + } + } + } + } + + /* I2C TX Empty Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_TX_EMPTY(1)) { + /* Confirm it's master mode */ + if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE) { + + /* To check I2C master TX data length. If all the data are transmitted, + mask all the interrupts and invoke the user callback */ + if (!pSalI2CHND->pTXBuf->DataLen) { + /* I2C Disable TX Related Interrupts */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_EMPTY | + BIT_IC_INTR_MASK_M_TX_OVER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + /* Clear all I2C pending interrupts */ + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + + /* Invoke I2C TX Complete callback */ + if (pSalI2CUserCB->pTXCCB->USERCB != NULL) + pSalI2CUserCB->pTXCCB->USERCB((void *)pSalI2CUserCB->pTXCCB->USERData); + } + + if (pSalI2CHND->pTXBuf->DataLen > 0) { + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Invoke I2C TX callback if available */ + if (pSalI2CUserCB->pTXCB->USERCB != NULL) + pSalI2CUserCB->pTXCB->USERCB((void *)pSalI2CUserCB->pTXCB->USERData); + + /* Check I2C TX FIFO status. If it's not full, one byte data will be written into it. */ + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_TFNF)) == BIT_IC_STATUS_TFNF) { + pHalI2CInitDat->I2CCmd = I2C_WRITE_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + pHalI2CInitDat->I2CReSTR = 1; + if ((pSalI2CHND->pTXBuf->DataLen == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + + } + } + }/*if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE)*/ + } + + /* I2C TX Over Run Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_TX_OVER(1)) { + + DBG_I2C_ERR("!I2C%d INTR_TX_OVER!\n",I2CIrqIdx); + + /* Clear I2C interrupt */ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_OVER; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_ERROR; + + /* Update I2C error type */ + pSalI2CHND->ErrType |= I2C_ERR_TX_OVER; + + /* Invoke I2C error callback if available */ + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + } + + /* I2C RX Full Intr */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_RX_FULL(1)) { + /* Check if it's Master */ + if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE){ + + //DBG_8195A("full\n"); + /* Check if the receive transfer is NOT finished. If it is not, check if there + is data in the RX FIFO and move the data from RX FIFO to user data buffer*/ + if (pSalI2CHND->pRXBuf->DataLen > 0) { + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_RX_ING; + + /* Invoke I2C RX callback if available */ + if (pSalI2CUserCB->pRXCB->USERCB != NULL) + pSalI2CUserCB->pRXCB->USERCB((void *)pSalI2CUserCB->pRXCB->USERData); + + I2CInTOTcnt = (u32)pSalI2CMngtAdpt->InnerTimeOut; + InTimeoutCount = 0; + /* Calculate internal time out parameters */ + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + while (1) { + I2CLocalRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + if ((I2CLocalRawSts & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) != 0) { + *(pSalI2CHND->pRXBuf->pDataBuf) = + pHalI2COP->HalI2CReceive(pHalI2CInitDat); + //DBG_8195A("rx:%x\n",*(pSalI2CHND->pRXBuf->pDataBuf)); + pSalI2CHND->pRXBuf->pDataBuf++; + pSalI2CHND->pRXBuf->DataLen--; + + if ((pSalI2CHND->pRXBuf->DataLen) == 0) + break; + } + else if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT) + & (BIT_IC_RAW_INTR_STAT_RX_OVER | BIT_IC_RAW_INTR_STAT_RX_UNDER)) != 0) { + break; + } + else { + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) & BIT_IC_STATUS_RFNE) + == 0){ + break; + } + } + + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RX Full Timeout, I2C%2x,1\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + break; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RX Full Timeout, I2C%2x,2\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + break; + } + } + } + } + + /* To check I2C master RX data length. If all the data are received, + mask all the interrupts and invoke the user callback. + Otherwise, the master should send another Read Command to slave for + the next data byte receiving. */ + if (!pSalI2CHND->pRXBuf->DataLen) { + /* I2C Disable RX Related Interrupts */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_RX_FULL | + BIT_IC_INTR_MASK_M_RX_OVER | + BIT_IC_INTR_MASK_M_RX_UNDER| + BIT_IC_INTR_MASK_M_TX_ABRT); + + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + /* Clear all I2C pending interrupts */ + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + + /* Invoke I2C RX complete callback if available */ + if (pSalI2CUserCB->pRXCCB->USERCB != NULL) + pSalI2CUserCB->pRXCCB->USERCB((void *)pSalI2CUserCB->pRXCCB->USERData); + } + else { + /* If TX FIFO is not full, another Read Command is written into it. */ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & BIT_IC_STATUS_TFNF) { + if (pSalI2CMngtAdpt->MstRDCmdCnt > 0) { + pHalI2CInitDat->I2CCmd = I2C_READ_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pRXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + pHalI2CInitDat->I2CReSTR = 1; + if ((pSalI2CMngtAdpt->MstRDCmdCnt == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)){ + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + } + pSalI2CMngtAdpt->MstRDCmdCnt--; + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + } + } + } + + }/*(pSalI2CHND->I2CMaster == I2C_MASTER_MODE)*/ + else{ + /* To check I2C master RX data length. If all the data are received, + mask all the interrupts and invoke the user callback. + Otherwise, if there is data in the RX FIFO and move the data from RX + FIFO to user data buffer*/ + if (pSalI2CHND->pRXBuf->DataLen > 0){ + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_RX_ING; + + /* Invoke I2C RX callback if available */ + if (pSalI2CUserCB->pRXCB->USERCB != NULL) + pSalI2CUserCB->pRXCB->USERCB((void *)pSalI2CUserCB->pRXCB->USERData); + + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) != 0) { + *(pSalI2CHND->pRXBuf->pDataBuf) = + pHalI2COP->HalI2CReceive(pHalI2CInitDat); + pSalI2CHND->pRXBuf->pDataBuf++; + pSalI2CHND->pRXBuf->DataLen--; + } + } + + /* All data are received. Mask all related interrupts. */ + if (!pSalI2CHND->pRXBuf->DataLen){ + /*I2C Disable RX Related Interrupts*/ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp &= ~(BIT_IC_INTR_MASK_M_RX_FULL | + BIT_IC_INTR_MASK_M_RX_OVER | + BIT_IC_INTR_MASK_M_RX_UNDER); + + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + + /* Invoke I2C RX complete callback if available */ + if (pSalI2CUserCB->pRXCCB->USERCB != NULL) + pSalI2CUserCB->pRXCCB->USERCB((void *)pSalI2CUserCB->pRXCCB->USERData); + } + } + } + + /*I2C RX Over Run Intr*/ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_RX_OVER(1)) { + + DBG_I2C_ERR("I2C%d INTR_RX_OVER\n",I2CIrqIdx); + + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RX_OVER; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_ERROR; + + /* Update I2C error type */ + pSalI2CHND->ErrType |= I2C_ERR_RX_OVER; + + /* Invoke I2C error callback if available */ + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + } + + /*I2C RX Under Run Intr*/ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_INTR_STAT) & + BIT_CTRL_IC_INTR_STAT_R_RX_UNDER(1)) { + + DBG_I2C_ERR("!I2C%d INTR_RX_UNDER!\n",I2CIrqIdx); + + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RX_UNDER; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + + /* Update I2C device status */ + pSalI2CHND->DevSts = I2C_STS_ERROR; + + /* Update I2C error type */ + pSalI2CHND->ErrType |= I2C_ERR_RX_UNDER; + + /* Invoke I2C error callback if available */ + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + } +} +#endif + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CSend +// +// Description: +// To execute Master-Transmitter and Slave-Transmitter operation. +// There are 3 operation mode in this function which are separated by compile-time +// flag. +// For Master-Transmitter, the User Register Address flag is checked first. +// User Register Address may be sent before any formal transfer, no matter in +// Poll-, Intr- or DMA- Mode. +// +// In Poll-Mode, no matter it's master or slave mode, the transfer will be done in +// this function by checking the transfer length. +// -Master in Poll-Mode: +// a. Send the User Register Address if needed. +// b. Check if all the data are transmitted. If it's NOT, checking the TX FIFO +// status is done for writing data from user TX buffer to I2C TX FIFO when +// TX FIFO is NOT full. +// TX data length decrements one after writing one byte into TX FIFO. +// c. b is executed circularly till the TX buffer data length is zero. +// +// -Slave in Poll-Mode: +// Slave could send data only when it received a Read Commmand matched +// with its own I2C address from other I2C master. Once a slave correctly +// received a Read Command matched with its own addr., a Read-Request +// flag is set at the same time. +// In this Poll-Mode, the slave checks the Read-Request flag to decide +// if it could send its TX buffer data. +// a. Check if the Read-Request flag is set or not. If the flag is set, it should +// check if TX buffer data length is zero. If it's NOT, +// the I2C TX FIFO status will be checked for the following operation. +// b. If the TX FIFO is NOT empty, slave will write one byte data from TX data +// buffer to TX FIFO. +// c. a and b are executed circularly till the TX buffer data length is zero. +//---------------------------------------------------------------------- +// In Intr-Mode, this function is used to unmask the realted I2C interrupt for +// the following interrupt operations. +// -Master in Intr-Mode: +// a. Send the User Register Address if needed. +// b. Unmask the TX-Empty and realted error interrupts. +// +// -Slave in Intr-Mode: +// a. Unmask the RD-Req and realted error interrupts. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C send process. +// _EXIT_SUCCESS if the RtkI2CSend succeeded. +// _EXIT_FAILURE if the RtkI2CSend failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CSend_Patch( + IN VOID *Data +){ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + PSAL_I2C_HND_PRIV pSalI2CHNDPriv = NULL; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; + + PHAL_GDMA_ADAPTER pHalI2CTxGdmaAdpt = NULL; + PHAL_GDMA_OP pHalI2CGdmaOp = NULL; + PSAL_I2C_USER_CB pSalI2CUserCB = NULL; + + u32 I2CLocalTemp = 0; + u32 I2CInTOTcnt = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + u32 I2CChkRawSts = 0; + u32 I2CChkRawSts2 = 0; + u32 I2CDataLenBak = 0; + u32 I2CDataPtrBak = 0; + //u32 I2CInTOTcntIntr = 0; + //u32 InTimeoutCountIntr = 0; + //u32 InStartCountIntr = 0; + u32 I2CMtrTtyCnt = 0; + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalI2CHNDPriv = CONTAINER_OF(pSalI2CHND, SAL_I2C_HND_PRIV, SalI2CHndPriv); + pSalI2CMngtAdpt = CONTAINER_OF(pSalI2CHNDPriv->ppSalI2CHnd, SAL_I2C_MNGT_ADPT, pSalHndPriv); + + + + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + pSalI2CUserCB = pSalI2CHND->pUserCB; + + pHalI2CTxGdmaAdpt = pSalI2CMngtAdpt->pHalTxGdmaAdp; + pHalI2CGdmaOp = pSalI2CMngtAdpt->pHalGdmaOp; + + /* Check if it's Master Mode */ + if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE) { + I2CMtrTtyCnt = 0; + + /* Master run-time update target address */ + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_UPD) { + + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Check Master activity status */ + while ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS)) & BIT_IC_STATUS_MST_ACTIVITY) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,1\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,2\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Check TX FIFO status */ + while (!((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS)) & BIT_IC_STATUS_TFE)) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,3\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_ADD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,4\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + + I2CLocalTemp = 0; + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_TAR); + I2CLocalTemp &= (~BIT_MASK_IC_TAR); + I2CLocalTemp |= BIT_CTRL_IC_TAR(pSalI2CHND->pTXBuf->TargetAddr); + /* Update Master Target address */ + pHalI2COP->HalI2CWriteReg(pHalI2CInitDat, REG_DW_I2C_IC_TAR, I2CLocalTemp); + } + + RtkI2CSendUserAddr(pSalI2CHND, 0); + + /* #if I2C_POLL_OP_TYPE */ + if (pSalI2CHND->OpType == I2C_POLL_TYPE) { /* if (pSalI2CHND->OpType == I2C_POLL_TYPE) */ + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_READY; + + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Send data till the TX buffer data length is zero */ + for (;pSalI2CHND->pTXBuf->DataLen>0;) { + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Check I2C TX FIFO status */ + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_TFNF)) == BIT_IC_STATUS_TFNF) { + /* Wrtie data into I2C TX FIFO */ + pHalI2CInitDat->I2CCmd = I2C_WRITE_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + if ((pSalI2CHND->pTXBuf->DataLen == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + } + else { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_CMD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,5\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_CMD_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,6\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_RTY) { + HalDelayUs(((1000*30)/pHalI2CInitDat->I2CClk)); //the 10 is for ten bit time + I2CLocalTemp = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + if (I2CLocalTemp & BIT_IC_RAW_INTR_STAT_TX_ABRT) { + I2CMtrTtyCnt++; + I2CLocalTemp = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CLocalTemp & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CLocalTemp & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + + pSalI2CHND->DevSts = I2C_STS_ERROR; + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_CLR_TX_ABRT); + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + } + } + } + + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CMngtAdpt->InnerTimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + /* I2C Wait TX FIFO Empty */ + while (1) { + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_TFE | BIT_IC_STATUS_TFNF)) == + (BIT_IC_STATUS_TFE | BIT_IC_STATUS_TFNF)){ + break; + } + else { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,7\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,8\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + } + + /* Invoke I2C TX complete callback if available */ + if (pSalI2CUserCB->pTXCCB->USERCB != NULL) + pSalI2CUserCB->pTXCCB->USERCB((void *)pSalI2CUserCB->pTXCCB->USERData); + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + }/* if (pSalI2CHND->OpType == I2C_POLL_TYPE) */ + /* #if I2C_POLL_OP_TYPE */ + +#if I2C_INTR_OP_TYPE + if (pSalI2CHND->OpType == I2C_INTR_TYPE) { /* if (pSalI2CHND->OpType == I2C_INTR_TYPE) */ + /* Calculate user time out parameters */ + InTimeoutCount = 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CHND->TimeOut; + + //InTimeoutCountIntr = 0; + //InStartCountIntr = 0; + //I2CInTOTcntIntr = pSalI2CHND->AddRtyTimeOut; + + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + //InTimeoutCountIntr = (I2CInTOTcntIntr*1000/TIMER_TICK_US); + //InStartCountIntr = HalTimerOp.HalTimerReadCount(1); + + + I2CDataLenBak = (u32)(pSalI2CHND->pTXBuf->DataLen); + I2CDataPtrBak = (u32)(pSalI2CHND->pTXBuf->pDataBuf); + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_ABRT; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + + /* Send data till the TX buffer data length is zero */ + for (;;) { +SEND_I2C_WR_CMD_INTR: + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Check I2C TX FIFO status */ + /* Fill TX FIFO only when it's completely empty */ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + if ((I2CChkRawSts & BIT_IC_STATUS_TFE) == BIT_IC_STATUS_TFE) { + if (pSalI2CHND->pTXBuf->DataLen > 0) { + /* Wrtie data into I2C TX FIFO */ + pHalI2CInitDat->I2CCmd = I2C_WRITE_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + + if ((pSalI2CHND->pTXBuf->DataLen == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)) + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + + if ((pHalI2CInitDat->I2CReSTR == 1) && (pSalI2CHND->pTXBuf->DataLen == I2CDataLenBak)){ + pHalI2CInitDat->RSVD0 |= BIT0; + } + + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + + if (pHalI2CInitDat->I2CReSTR == 1) { + pHalI2CInitDat->RSVD0 &= (~BIT0); + } + } + } + + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_RTY) { + u32 I2CInTOTcntRty = 0; + u32 InTimeoutCountRty = 0; + u32 InStartCountRty = 0; + +#if 0 + /* SEND_I2C_WR_CMD_INTR Time-Out check */ + if (InTimeoutCountIntr > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCountIntr, InTimeoutCountIntr)) { + /* Reset the data count before status return */ + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + return HAL_TIMEOUT; + } + } +#endif + /* Calculate user master retry local time out parameters */ + InTimeoutCountRty = 0; + InStartCountRty = 0; + I2CInTOTcntRty = pSalI2CHND->TimeOut; + + if ((I2CInTOTcntRty != 0) && (I2CInTOTcntRty!= I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCountRty= (I2CInTOTcntRty*1000/TIMER_TICK_US); + InStartCountRty= HalTimerOp.HalTimerReadCount(1); + } + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + while ((I2CChkRawSts & BIT_IC_STATUS_TFE) == 0) { + I2CChkRawSts2 = pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + if ((I2CChkRawSts2 & BIT_IC_RAW_INTR_STAT_TX_ABRT) != 0){ + break; + } + + /* Time-Out check */ + if (InTimeoutCountRty > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCountRty, InTimeoutCountRty)) { + break; + } + } + else { + if (I2CInTOTcntRty == 0) { + break; + } + } + + /* Read I2C IC status again */ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + } + + HalDelayUs((u32)((1000*30)/pHalI2CInitDat->I2CClk)); //the 10 is for ten bit time + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + if (I2CChkRawSts & BIT_IC_RAW_INTR_STAT_TX_ABRT) { + I2CMtrTtyCnt++; + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CChkRawSts & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CChkRawSts & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + pSalI2CHND->DevSts = I2C_STS_ERROR; + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + + pSalI2CHND->DevSts = I2C_STS_TX_READY; + pSalI2CHND->ErrType = 0; + pSalI2CHND->pTXBuf->DataLen = (u16)I2CDataLenBak; + pSalI2CHND->pTXBuf->pDataBuf= (u8*)I2CDataPtrBak; + /* Calculate user time out parameters */ + InTimeoutCount = 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + goto SEND_I2C_WR_CMD_INTR; + + } + else if (((u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) & BIT_IC_STATUS_TFE) != BIT_IC_STATUS_TFE) { + I2CMtrTtyCnt++; + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CChkRawSts & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CChkRawSts & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + pSalI2CHND->DevSts = I2C_STS_ERROR; + pSalI2CHND->pTXBuf->pDataBuf--; + pSalI2CHND->pTXBuf->DataLen++; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + + pSalI2CHND->DevSts = I2C_STS_TX_READY; + pSalI2CHND->ErrType = 0; + pSalI2CHND->pTXBuf->DataLen = (u16)I2CDataLenBak; + pSalI2CHND->pTXBuf->pDataBuf= (u8 *)I2CDataPtrBak; + /* Calculate user time out parameters */ + InTimeoutCount = 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + goto SEND_I2C_WR_CMD_INTR; + } + else { + /* I2C Enable TX Related Interrupts */ + I2CLocalTemp = 0; + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_EMPTY | + BIT_IC_INTR_MASK_M_TX_OVER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + break; + } + } + else { + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + while ((I2CChkRawSts & BIT_IC_STATUS_TFE) == 0) { + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + } + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + if (I2CChkRawSts & BIT_IC_STATUS_TFE) { + + if (pSalI2CHND->pTXBuf->DataLen > 0) { + /* I2C Enable TX Related Interrupts */ + I2CLocalTemp = 0; + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_EMPTY | + BIT_IC_INTR_MASK_M_TX_OVER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + } + else { + /* Invoke I2C TX complete callback if available */ + if (pSalI2CUserCB->pTXCCB->USERCB != NULL) + pSalI2CUserCB->pTXCCB->USERCB((void *)pSalI2CUserCB->pTXCCB->USERData); + } + + break; //end of send process in INTR mode + } + } + + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + //DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,7\n",pSalI2CHND->DevNum); + //DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + return HAL_TIMEOUT; + } + } + } + } /* if (pSalI2CHND->OpType == I2C_INTR_TYPE) */ +#endif + + /* if (pSalI2CHND->OpType == I2C_DMA_TYPE) */ + if (pSalI2CHND->OpType == I2C_DMA_TYPE) { + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_READY; + + /* I2C Enable TX Related Interrupts */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_OVER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + //HalGdmaOpInit(pHalI2CGdmaOp); + pSalI2CMngtAdpt->pHalGdmaOpInit(pHalI2CGdmaOp); + pHalI2CTxGdmaAdpt->GdmaCtl.BlockSize = pSalI2CHND->pTXBuf->DataLen; + pHalI2CTxGdmaAdpt->ChSar = (u32)pSalI2CHND->pTXBuf->pDataBuf; + pHalI2CTxGdmaAdpt->ChDar = (u32)(I2C0_REG_BASE+REG_DW_I2C_IC_DATA_CMD+ + pSalI2CHND->DevNum*0x400); + pHalI2CGdmaOp->HalGdmaChSeting(pHalI2CTxGdmaAdpt); + pHalI2CGdmaOp->HalGdmaChEn(pHalI2CTxGdmaAdpt); + pSalI2CHND->DevSts = I2C_STS_TX_ING; + pHalI2CInitDat->I2CDMACtrl = BIT_CTRL_IC_DMA_CR_TDMAE(1); + pHalI2COP->HalI2CDMACtrl(pHalI2CInitDat); + + } + /* if (pSalI2CHND->OpType == I2C_DMA_TYPE) */ + + }/* if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE) */ + else{ + /* #if I2C_POLL_OP_TYPE */ + if (pSalI2CHND->OpType == I2C_POLL_TYPE) { + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_READY; + + /* Send data till the TX buffer data length is zero */ + for (;pSalI2CHND->pTXBuf->DataLen>0;) { + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_TX_ING; + + /* Check I2C RD Request flag */ + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_RAW_INTR_STAT)) + & BIT_IC_RAW_INTR_STAT_RD_REQ) { + + /* Check I2C TX FIFO status */ + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_TFNF)) == BIT_IC_STATUS_TFNF) { + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pTXBuf->pDataBuf; + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RD_REQ; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pSalI2CHND->pTXBuf->pDataBuf++; + pSalI2CHND->pTXBuf->DataLen--; + } + } + else { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,9\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + DBG_I2C_ERR("RtkI2CSend Timeout, I2C%2x,10\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + } + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + } + /* #if I2C_POLL_OP_TYPE */ + + /* #if I2C_INTR_OP_TYPE */ + if (pSalI2CHND->OpType == I2C_INTR_TYPE) { + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; +#if 0 + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_ABRT; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_OVER; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_RD_REQ; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_ACTIVITY; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); +#endif + pSalI2CHND->DevSts = I2C_STS_TX_READY; + + /* I2C Enable TX Related Interrupts. In Slave-Transmitter, the below + interrupts should be enabled. */ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_TX_ABRT | + BIT_IC_INTR_MASK_M_TX_OVER | + BIT_IC_INTR_MASK_M_RX_DONE | + BIT_IC_INTR_MASK_M_RD_REQ); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + } + /* #if I2C_INTR_OP_TYPE */ + + /* #if I2C_DMA_OP_TYPE */ + ; + /* #if I2C_DMA_OP_TYPE */ + } + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CReceive +// +// Description: +// To execute Master-Receiver and Slave-Receiver operation. +// There are 3 operation mode in this function which are separated by compile-time +// flag. +// For Master-Receiver, the User Register Address flag is checked first. +// User Register Address may be sent before any formal transfer, no matter in +// Poll-, Intr- or DMA- Mode. +// +// For Master-Receiver, the I2C master have to send a Read Command for receiving +// one byte from the other I2C slave. +// +// In Poll-Mode, no matter it's master or slave mode, the transfer will be done in +// this function by checking the transfer length. +// -Master in Poll-Mode: +// a. Send the User Register Address if needed. +// b. Check if all the data are received. If it's NOT, checking the TX FIFO +// status will be done. If the TX FIFO it's full, a Read Command will be +// wirtten into the TX FIFO. +// c. After b, the I2C master contineously polls the RX FIFO status to see +// if there is a received data. If it received one, it will move the data from +// I2C RX FIFO into user RX data buffer. +// d. b and c are executed circularly till the RX buffer data length is zero. +// +// -Slave in Poll-Mode: +// a. Check if all the data are received. +// b. The I2C slave contineously polls the RX FIFO status to see +// if there is a received data. If it received one, it will move the data from +// I2C RX FIFO into user RX data buffer. +// c. a and b are executed circularly till the RX buffer data length is zero. +// +//---------------------------------------------------------------------- +// In Intr-Mode, this function is used to unmask the realted I2C interrupt for +// the following interrupt operations. +// -Master in Intr-Mode: +// a. Send the User Register Address if needed. +// b. Unmask the RX-Full and realted error interrupts. +// c. Write one or two Read Command into master TX FIFO for requesting +// another slave providing data. +// +// -Slave in Intr-Mode: +// a. Unmask the RX-Full and realted error interrupts. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C receive process. +// _EXIT_SUCCESS if the RtkI2CReceive succeeded. +// _EXIT_FAILURE if the RtkI2CReceive failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CReceive_Patch( + IN VOID *Data +){ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + PSAL_I2C_HND_PRIV pSalI2CHNDPriv = NULL; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; +#if I2C_DMA_OP_TYPE + PHAL_GDMA_ADAPTER pHalI2CRxGdmaAdpt = NULL; + PHAL_GDMA_OP pHalI2CGdmaOp = NULL; +#endif + PSAL_I2C_USER_CB pSalI2CUserCB = NULL; + + u32 I2CLocalTemp = 0; + u32 I2CInTOTcnt = 0; + u32 InTimeoutCount = 0; + u32 InStartCount = 0; + u32 I2CLocalLen = 0; + u32 I2CChkRawSts = 0; + u32 I2CChkRawSts2 = 0; + u32 I2CDataLenBak = 0; + u32 I2CDataPtrBak = 0; + u32 I2CInTOTcntRty = 0; + u32 InTimeoutCountRty = 0; + u32 InStartCountRty = 0; + //u32 I2CInTOTcntIntr = 0; + //u32 InTimeoutCountIntr = 0; + //u32 InStartCountIntr = 0; + u32 I2CMtrTtyCnt = 0; + + /*To Get the SAL_I2C_MNGT_ADPT Pointer*/ + pSalI2CHNDPriv = CONTAINER_OF(pSalI2CHND, SAL_I2C_HND_PRIV, SalI2CHndPriv); + pSalI2CMngtAdpt = CONTAINER_OF(pSalI2CHNDPriv->ppSalI2CHnd, SAL_I2C_MNGT_ADPT, pSalHndPriv); + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + pSalI2CUserCB = pSalI2CHND->pUserCB; +#if I2C_DMA_OP_TYPE + pHalI2CRxGdmaAdpt = pSalI2CMngtAdpt->pHalRxGdmaAdp; + pHalI2CGdmaOp = pSalI2CMngtAdpt->pHalGdmaOp; +#endif + + if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE)/*if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE)*/ + { + I2CMtrTtyCnt = 0; + /* Master run-time update target address */ + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_UPD) { + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Check Master activity status */ + while ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS)) & BIT_IC_STATUS_MST_ACTIVITY) { + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,1\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,2\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Check TX FIFO status */ + while (!((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS)) & BIT_IC_STATUS_TFE)) { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,3\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_ADD_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,4\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_TAR); + I2CLocalTemp &= (~BIT_MASK_IC_TAR); + I2CLocalTemp |= BIT_CTRL_IC_TAR(pSalI2CHND->pRXBuf->TargetAddr); + /* Update Master Target address */ + pHalI2COP->HalI2CWriteReg(pHalI2CInitDat, REG_DW_I2C_IC_TAR, I2CLocalTemp); + } + + +#if I2C_USER_REG_ADDR /*I2C_USER_REG_ADDR*/ + RtkI2CSendUserAddr(pSalI2CHND, 1); +#endif /*I2C_USER_REG_ADDR*/ + +#if I2C_POLL_OP_TYPE/*I2C_POLL_OP_TYPE*/ + if (pSalI2CHND->OpType == I2C_POLL_TYPE) + { + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_RX_READY; + + pSalI2CMngtAdpt->MstRDCmdCnt = pSalI2CHND->pRXBuf->DataLen; + I2CLocalTemp = pSalI2CHND->pRXBuf->DataLen; + + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Receive data till the RX buffer data length is zero */ + for ( ;pSalI2CHND->pRXBuf->DataLen>0; ) { +SEND_I2C_RD_CMD: + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_RX_ING; + /* Check I2C TX FIFO status. If it's NOT full, a Read command is written + into the TX FIFO.*/ + if (pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & BIT_IC_STATUS_TFNF) { + if (pSalI2CMngtAdpt->MstRDCmdCnt > 0) { + pHalI2CInitDat->I2CCmd = I2C_READ_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pRXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + if ((pSalI2CMngtAdpt->MstRDCmdCnt == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)){ + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + } + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + if (pSalI2CMngtAdpt->MstRDCmdCnt > 0) + pSalI2CMngtAdpt->MstRDCmdCnt--; + } + } + + if (I2CLocalTemp == pSalI2CHND->pRXBuf->DataLen){ + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_RTY) { + HalDelayUs(((1000*30)/pHalI2CInitDat->I2CClk)); //the 10 is for ten bit time + I2CChkRawSts = pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + if (I2CChkRawSts & BIT_IC_RAW_INTR_STAT_TX_ABRT) { + I2CMtrTtyCnt++; + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CChkRawSts & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CChkRawSts & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + pSalI2CHND->DevSts = I2C_STS_ERROR; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_CLR_TX_ABRT); + pSalI2CMngtAdpt->MstRDCmdCnt++; + goto SEND_I2C_RD_CMD; + } + } + } + + /* Contineously poll the I2C RX FIFO status */ + while (1) { + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) != 0) { + *(pSalI2CHND->pRXBuf->pDataBuf) = + pHalI2COP->HalI2CReceive(pHalI2CInitDat); + + pSalI2CHND->pRXBuf->pDataBuf++; + pSalI2CHND->pRXBuf->DataLen--; + + if (!pSalI2CHND->pRXBuf->DataLen) { + break; + } + } + else { + break; + } + } + + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,5\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,6\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + + } + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + } +#endif/*I2C_POLL_OP_TYPE*/ + +#if I2C_INTR_OP_TYPE/*I2C_INTR_OP_TYPE*/ + if (pSalI2CHND->OpType == I2C_INTR_TYPE) { + /* Calculate user time out parameters */ + InTimeoutCount= 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CMngtAdpt->InnerTimeOut; + + //InTimeoutCountIntr = 0; + //InStartCountIntr = 0; + //I2CInTOTcntIntr = pSalI2CHND->AddRtyTimeOut; + + if ((I2CInTOTcnt!= 0) && (I2CInTOTcnt!= I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount= HalTimerOp.HalTimerReadCount(1); + } + + //InTimeoutCountIntr = (I2CInTOTcntIntr*1000/TIMER_TICK_US); + //InStartCountIntr = HalTimerOp.HalTimerReadCount(1); + + I2CDataLenBak = (u32)(pSalI2CHND->pRXBuf->DataLen); + I2CDataPtrBak = (u32)(pSalI2CHND->pRXBuf->pDataBuf); + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_RX_READY; + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_ABRT; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_ACTIVITY; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + pHalI2COP->HalI2CClrAllIntr(pHalI2CInitDat); + + /* Clear RX FIFO */ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RXFLR); + while (I2CChkRawSts > 0){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RXFLR); + } + + /* To fill the Master Read Command into TX FIFO */ + pSalI2CMngtAdpt->MstRDCmdCnt = pSalI2CHND->pRXBuf->DataLen; + I2CLocalLen = 2;//pSalI2CHND->pRXBuf->DataLen; + pSalI2CHND->DevSts = I2C_STS_RX_READY; + + + while (1) { +SEND_I2C_RD_CMD_INTR: + + /* Calculate user time out parameters */ + InTimeoutCountRty = 0; + InStartCountRty = 0; + I2CInTOTcntRty = pSalI2CHND->TimeOut; + + if ((I2CInTOTcntRty != 0) && (I2CInTOTcntRty!= I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCountRty= (I2CInTOTcntRty*1000/TIMER_TICK_US); + InStartCountRty= HalTimerOp.HalTimerReadCount(1); + } + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + + if ((pSalI2CMngtAdpt->MstRDCmdCnt > 0) && (I2CLocalLen > 0)){ + pHalI2CInitDat->I2CCmd = I2C_READ_CMD; + pHalI2CInitDat->I2CDataLen= 1; + pHalI2CInitDat->I2CRWData = pSalI2CHND->pRXBuf->pDataBuf; + pHalI2CInitDat->I2CStop = I2C_STOP_DIS; + + if ((pSalI2CMngtAdpt->MstRDCmdCnt == 1) && ((pSalI2CHND->I2CExd & I2C_EXD_MTR_HOLD_BUS) == 0)){ + pHalI2CInitDat->I2CStop = I2C_STOP_EN; + } + + if ((pHalI2CInitDat->I2CReSTR == 1) && (I2CLocalLen == 2)) { + pHalI2CInitDat->RSVD0 |= BIT0; + } + + pHalI2COP->HalI2CMassSend(pHalI2CInitDat); + + if ((pHalI2CInitDat->I2CReSTR == 1) && (I2CLocalLen == 2)) { + pHalI2CInitDat->RSVD0 &= (~BIT0); + } + } + + if (pSalI2CHND->I2CExd & I2C_EXD_MTR_ADDR_RTY) { + + /* SEND_I2C_WR_CMD_INTR Time-Out check */ + //if (InTimeoutCountIntr > 0) { + // if (HAL_TIMEOUT == I2CIsTimeout(InStartCountIntr, InTimeoutCountIntr)) { + // return HAL_TIMEOUT; + // } + //} + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + while ((I2CChkRawSts & BIT_IC_STATUS_TFE) == 0) { + I2CChkRawSts2 = pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + if ((I2CChkRawSts2 & BIT_IC_RAW_INTR_STAT_TX_ABRT) != 0){ + break; + } + + /* Time-Out check */ + if (InTimeoutCountRty > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCountRty, InTimeoutCountRty)) { + break; + } + } + else { + if (I2CInTOTcntRty == 0) { + break; + } + } + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + + } + + HalDelayUs(((1000*30)/pHalI2CInitDat->I2CClk)); //the 10 is for ten bit time + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_RAW_INTR_STAT); + I2CChkRawSts2 = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + if (I2CChkRawSts & BIT_IC_RAW_INTR_STAT_TX_ABRT) { + I2CMtrTtyCnt++; + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CChkRawSts & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CChkRawSts & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + + pSalI2CHND->DevSts = I2C_STS_ERROR; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + pSalI2CHND->DevSts = I2C_STS_RX_READY; + pSalI2CHND->ErrType = 0; + pSalI2CHND->pRXBuf->DataLen = (u16)I2CDataLenBak; + pSalI2CHND->pRXBuf->pDataBuf= (u8 *)I2CDataPtrBak; + + /* Calculate user time out parameters */ + InTimeoutCount = 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CMngtAdpt->InnerTimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + goto SEND_I2C_RD_CMD_INTR; + } + else if ((I2CChkRawSts2 & BIT_IC_STATUS_TFE) != BIT_IC_STATUS_TFE){ + I2CMtrTtyCnt++; + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_TX_ABRT_SOURCE); + if (I2CMtrTtyCnt > I2C_MTR_RTY_CNT) { + if ((I2CChkRawSts & (BIT_IC_TX_ABRT_SOURCE_ABRT_7B_ADDR_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR1_NOACK | + BIT_IC_TX_ABRT_SOURCE_ABRT_10ADDR2_NOACK)) != 0) { + pSalI2CHND->ErrType |= I2C_ERR_MST_A_NACK; + } + else if ((I2CChkRawSts & BIT_IC_TX_ABRT_SOURCE_ABRT_TXDATA_NOACK) != 0){ + pSalI2CHND->ErrType |= I2C_ERR_MST_D_NACK; + } + else { + pSalI2CHND->ErrType |= I2C_ERR_TX_ABRT; + } + pSalI2CHND->DevSts = I2C_STS_ERROR; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_ERR_HW; + } + + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + pSalI2CHND->DevSts = I2C_STS_RX_READY; + pSalI2CHND->ErrType = 0; + pSalI2CHND->pRXBuf->DataLen = (u16)I2CDataLenBak; + pSalI2CHND->pRXBuf->pDataBuf= (u8 *)I2CDataPtrBak; + + /* Calculate user time out parameters */ + InTimeoutCount = 0; + InStartCount = 0; + I2CInTOTcnt = pSalI2CMngtAdpt->InnerTimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + goto SEND_I2C_RD_CMD_INTR; + } + else { + I2CChkRawSts2 = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS); + { + if (I2CLocalLen>0){ + I2CLocalLen--; + pSalI2CMngtAdpt->MstRDCmdCnt --; + } + } + } + } + else { + if (I2CLocalLen>0) { + I2CLocalLen--; + pSalI2CMngtAdpt->MstRDCmdCnt --; + } + } + + if ((I2CLocalLen == 0) || (pSalI2CHND->pRXBuf->DataLen == 1)){ + pHalI2CInitDat->I2CIntrClr = REG_DW_I2C_IC_CLR_TX_ABRT; + pHalI2COP->HalI2CClrIntr(pHalI2CInitDat); + I2CLocalTemp = 0; + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_RX_FULL | + BIT_IC_INTR_MASK_M_RX_OVER | + BIT_IC_INTR_MASK_M_RX_UNDER|BIT_IC_INTR_MASK_M_TX_ABRT); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + break; + } + + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_TX_FF_TO; + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + RtkI2CDeInitForPS(pSalI2CHND); + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) == BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + RtkI2CInitForPS(pSalI2CHND); + + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + while((I2CChkRawSts & BIT_IC_ENABLE_STATUS_IC_EN) != BIT_IC_ENABLE_STATUS_IC_EN){ + I2CChkRawSts = (u32)pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_ENABLE_STATUS); + } + return HAL_TIMEOUT; + } + } + } + + } +#endif/*I2C_INTR_OP_TYPE*/ + }/*if (pSalI2CHND->I2CMaster == I2C_MASTER_MODE)*/ + else + { +#if I2C_POLL_OP_TYPE + if (pSalI2CHND->OpType == I2C_POLL_TYPE) { + /* Calculate user time out parameters */ + I2CInTOTcnt = pSalI2CHND->TimeOut; + if ((I2CInTOTcnt != 0) && (I2CInTOTcnt != I2C_TIMEOOUT_ENDLESS)) { + InTimeoutCount = (I2CInTOTcnt*1000/TIMER_TICK_US); + InStartCount = HalTimerOp.HalTimerReadCount(1); + } + + /* Receive data till the RX buffer data length is zero */ + for (;pSalI2CHND->pRXBuf->DataLen>0; ) { + if ((pHalI2COP->HalI2CReadReg(pHalI2CInitDat,REG_DW_I2C_IC_STATUS) + & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) != 0) { + *(pSalI2CHND->pRXBuf->pDataBuf) = + pHalI2COP->HalI2CReceive(pHalI2CInitDat); + pSalI2CHND->pRXBuf->pDataBuf++; + pSalI2CHND->pRXBuf->DataLen--; + } + else { + /* Time-Out check */ + if (InTimeoutCount > 0) { + if (HAL_TIMEOUT == I2CIsTimeout(InStartCount, InTimeoutCount)) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,9\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + else { + if (I2CInTOTcnt == 0) { + pSalI2CHND->DevSts = I2C_STS_TIMEOUT; + pSalI2CHND->ErrType = I2C_ERR_RX_FF_TO; + DBG_I2C_ERR("RtkI2CReceive Timeout, I2C%2x,10\n",pSalI2CHND->DevNum); + DBG_I2C_ERR("DevSts:%x, ErrType:%x\n", pSalI2CHND->DevSts, pSalI2CHND->ErrType); + if (pSalI2CUserCB->pERRCB->USERCB != NULL) + pSalI2CUserCB->pERRCB->USERCB((void *)pSalI2CUserCB->pERRCB->USERData); + return HAL_TIMEOUT; + } + } + } + } + + /* I2C Device Status Update */ + pSalI2CHND->DevSts = I2C_STS_IDLE; + } +#endif + +#if I2C_INTR_OP_TYPE/*I2C_INTR_OP_TYPE*/ + if (pSalI2CHND->OpType == I2C_INTR_TYPE) { + pSalI2CHND->DevSts = I2C_STS_RX_READY; + + /*I2C Enable RX Related Interrupts*/ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_RX_FULL | + BIT_IC_INTR_MASK_M_RX_OVER | + BIT_IC_INTR_MASK_M_RX_UNDER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + } +#endif/*I2C_INTR_OP_TYPE*/ + +#if I2C_DMA_OP_TYPE/*I2C_INTR_OP_TYPE*/ + if (pSalI2CHND->OpType == I2C_DMA_TYPE) { + pSalI2CHND->DevSts = I2C_STS_RX_READY; + + /*I2C Enable RX Related Interrupts*/ + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_INTR_MASK); + I2CLocalTemp |= (BIT_IC_INTR_MASK_M_RX_OVER | + BIT_IC_INTR_MASK_M_RX_UNDER); + pHalI2CInitDat->I2CIntrMSK = I2CLocalTemp; + pHalI2COP->HalI2CIntrCtrl(pHalI2CInitDat); + + //HalGdmaOpInit(pHalI2CGdmaOp); + pSalI2CMngtAdpt->pHalGdmaOpInit(pHalI2CGdmaOp); + + pHalI2CRxGdmaAdpt->GdmaCtl.BlockSize = pSalI2CHND->pRXBuf->DataLen; + pHalI2CRxGdmaAdpt->ChSar = (u32)(I2C0_REG_BASE+REG_DW_I2C_IC_DATA_CMD+ + pSalI2CHND->DevNum*0x400); + pHalI2CRxGdmaAdpt->ChDar = (u32)pSalI2CHND->pRXBuf->pDataBuf; + + pHalI2CGdmaOp->HalGdmaChSeting(pHalI2CRxGdmaAdpt); + pHalI2CGdmaOp->HalGdmaChEn(pHalI2CRxGdmaAdpt); + pSalI2CHND->DevSts = I2C_STS_RX_ING; + pHalI2CInitDat->I2CDMACtrl = BIT_CTRL_IC_DMA_CR_RDMAE(1); + pHalI2COP->HalI2CDMACtrl(pHalI2CInitDat); + } +#endif/*I2C_INTR_OP_TYPE*/ + + } + + return HAL_OK; +} + + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CInitForPS +// +// Description: +// Add power state registeration for I2C initail process. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C initialization process. +// HAL_OK if the RtkI2CInitForPS succeeded. +// HAL_ERR_UNKNOWN if the RtkI2CInitForPS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-05-31. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CInitForPS( + IN VOID *Data +){ + + u8 i2cInitSts = HAL_OK; + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE i2cPwrState; +#endif + + /* Check the input I2C index first */ + if (FunctionChk((I2C0 + pSalI2CHND->DevNum), pSalI2CHND->PinMux) == _FALSE) + return HAL_ERR_UNKNOWN; + + i2cInitSts = RtkI2CInit(pSalI2CHND); + +#ifdef CONFIG_SOC_PS_MODULE + // To register a new peripheral device power state + if (i2cInitSts == HAL_OK){ + i2cPwrState.FuncIdx = I2C0 + pSalI2CHND->DevNum; + i2cPwrState.PwrState = ACT; + RegPowerState(i2cPwrState); + } +#endif + + return i2cInitSts; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CDeInitForPS +// +// Description: +// Add power state registeration for I2C deinitail process. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C deinitialization process. +// HAL_OK if the RtkI2CDeInitForPS succeeded. +// HAL_ERR_UNKNOWN if the RtkI2CDeInitForPS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-05-31. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CDeInitForPS( + IN VOID *Data +){ + u8 i2cInitSts = HAL_OK; + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE i2cPwrState; + u8 HwState; +#endif + + if (pSalI2CHND == NULL) + return HAL_ERR_UNKNOWN; + + /* Check the input I2C index first */ + if (RtkI2CIdxChk(pSalI2CHND->DevNum)) + return HAL_ERR_UNKNOWN; + +#ifdef CONFIG_SOC_PS_MODULE + i2cPwrState.FuncIdx = I2C0 + pSalI2CHND->DevNum; + + QueryRegPwrState(i2cPwrState.FuncIdx, &(i2cPwrState.PwrState), &HwState); + + // if the power state isn't ACT, then switch the power state back to ACT first + if ((i2cPwrState.PwrState != ACT) && (i2cPwrState.PwrState != INACT)) { + RtkI2CEnablePS(Data); + QueryRegPwrState(i2cPwrState.FuncIdx, &(i2cPwrState.PwrState), &HwState); + } + + if (i2cPwrState.PwrState == ACT) { + i2cPwrState.PwrState = INACT; + RegPowerState(i2cPwrState); + } +#endif + + i2cInitSts = RtkI2CDeInit(pSalI2CHND); + + return i2cInitSts; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CDisablePS +// +// Description: +// I2C disable opertion by setting clock disable. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C disable process. +// HAL_OK if the RtkI2CDisablePS succeeded. +// HAL_ERR_PARA if the RtkI2CDisablePS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-05-31. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CDisablePS( + IN VOID *Data +){ + + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + u8 i2cIdx = pSalI2CHND->DevNum; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE i2cPwrState; +#endif + + if (RtkI2CIdxChk(i2cIdx)) + return HAL_ERR_UNKNOWN; + + switch (i2cIdx) { + case 0: + { + /* I2C 0 */ + ACTCK_I2C0_CCTRL(OFF); + SLPCK_I2C0_CCTRL(OFF); + break; + } + case 1: + { + /* I2C 1 */ + ACTCK_I2C1_CCTRL(OFF); + SLPCK_I2C1_CCTRL(OFF); + break; + } + case 2: + { + /* I2C 2 */ + ACTCK_I2C2_CCTRL(OFF); + SLPCK_I2C2_CCTRL(OFF); + break; + } + case 3: + { + /* I2C 3 */ + ACTCK_I2C3_CCTRL(OFF); + SLPCK_I2C3_CCTRL(OFF); + break; + } + default: + { + return HAL_ERR_PARA; + } + } + +#ifdef CONFIG_SOC_PS_MODULE + // To register a new peripheral device power state + i2cPwrState.FuncIdx = I2C0 + pSalI2CHND->DevNum; + i2cPwrState.PwrState = SLPCG; + RegPowerState(i2cPwrState); +#endif + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CEnablePS +// +// Description: +// I2C enable opertion by setting clock enable. +// +// Arguments: +// [in] VOID *Data - +// I2C SAL handle +// +// Return: +// The status of the I2C enable process. +// HAL_OK if the RtkI2CEnablePS succeeded. +// HAL_ERR_PARA if the RtkI2CEnablePS failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2015-05-31. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CEnablePS( + IN VOID *Data +){ + + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + u8 i2cIdx = pSalI2CHND->DevNum; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE i2cPwrState; +#endif + + if (RtkI2CIdxChk(i2cIdx)) + return HAL_ERR_UNKNOWN; + + switch (i2cIdx) { + case 0: + { + /* I2C 0 */ + ACTCK_I2C0_CCTRL(ON); + SLPCK_I2C0_CCTRL(ON); + break; + } + case 1: + { + /* I2C 1 */ + ACTCK_I2C1_CCTRL(ON); + SLPCK_I2C1_CCTRL(ON); + break; + } + case 2: + { + /* I2C 2 */ + ACTCK_I2C2_CCTRL(ON); + SLPCK_I2C2_CCTRL(ON); + break; + } + case 3: + { + /* I2C 3 */ + ACTCK_I2C3_CCTRL(ON); + SLPCK_I2C3_CCTRL(ON); + break; + } + default: + { + return HAL_ERR_PARA; + } + } + +#ifdef CONFIG_SOC_PS_MODULE + // To register a new peripheral device power state + i2cPwrState.FuncIdx = I2C0 + pSalI2CHND->DevNum; + i2cPwrState.PwrState = ACT; + RegPowerState(i2cPwrState); +#endif + + return HAL_OK; +} + + +#ifndef CONFIG_MBED_ENABLED +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetMngtAdpt +// +// Description: +// According to the input index, all the memory space are allocated and all the +// related pointers are assigned. The management adapter pointer will be +// returned. +// +// Arguments: +// [in] u8 I2CIdx - +// I2C module index +// +// Return: +// PSAL_I2C_MNGT_ADPT +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +PSAL_I2C_MNGT_ADPT +RtkI2CGetMngtAdpt( + IN u8 I2CIdx +){ + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_USERCB_ADPT pSalI2CUserCBAdpt = NULL; + + /* If the kernel is available, Memory-allocation is used. */ +#ifdef I2C_STATIC_ALLOC + + pSalI2CMngtAdpt = (PSAL_I2C_MNGT_ADPT)RtlZmalloc(sizeof(SAL_I2C_MNGT_ADPT)); + pSalI2CMngtAdpt->pSalHndPriv = (PSAL_I2C_HND_PRIV)RtlZmalloc(sizeof(SAL_I2C_HND_PRIV)); + pSalI2CMngtAdpt->pHalInitDat = (PHAL_I2C_INIT_DAT)RtlZmalloc(sizeof(HAL_I2C_INIT_DAT)); + pSalI2CMngtAdpt->pHalOp = (PHAL_I2C_OP)RtlZmalloc(sizeof(HAL_I2C_OP)); + pSalI2CMngtAdpt->pIrqHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalI2CMngtAdpt->pHalTxGdmaAdp = (PHAL_GDMA_ADAPTER)RtlZmalloc(sizeof(HAL_GDMA_ADAPTER)); + pSalI2CMngtAdpt->pHalRxGdmaAdp = (PHAL_GDMA_ADAPTER)RtlZmalloc(sizeof(HAL_GDMA_ADAPTER)); + pSalI2CMngtAdpt->pHalGdmaOp = (PHAL_GDMA_OP)RtlZmalloc(sizeof(HAL_GDMA_OP)); + pSalI2CMngtAdpt->pIrqTxGdmaHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalI2CMngtAdpt->pIrqRxGdmaHnd = (PIRQ_HANDLE)RtlZmalloc(sizeof(IRQ_HANDLE)); + pSalI2CMngtAdpt->pUserCB = (PSAL_I2C_USER_CB)RtlZmalloc(sizeof(SAL_I2C_USER_CB)); + pSalI2CMngtAdpt->pDMAConf = (PSAL_I2C_DMA_USER_DEF)RtlZmalloc(sizeof(SAL_I2C_DMA_USER_DEF)); + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)RtlZmalloc((sizeof(SAL_I2C_USERCB_ADPT)*SAL_USER_CB_NUM)); +#else + switch (I2CIdx){ + case I2C0_SEL: + { + pSalI2CMngtAdpt = &SalI2C0MngtAdpt; + pSalI2CMngtAdpt->pSalHndPriv = &SalI2C0HndPriv; + pSalI2CMngtAdpt->pHalInitDat = &HalI2C0InitData; + pSalI2CMngtAdpt->pHalOp = &HalI2COpSAL; + pSalI2CMngtAdpt->pIrqHnd = &I2C0IrqHandleDat; + pSalI2CMngtAdpt->pHalTxGdmaAdp = &HalI2C0TxGdmaAdpt; + pSalI2CMngtAdpt->pHalRxGdmaAdp = &HalI2C0RxGdmaAdpt; + pSalI2CMngtAdpt->pHalGdmaOp = &HalI2C0GdmaOp; + pSalI2CMngtAdpt->pIrqTxGdmaHnd = &I2C0TxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pIrqRxGdmaHnd = &I2C0RxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pUserCB = &SalI2C0UserCB; + pSalI2CMngtAdpt->pDMAConf = &SalI2C0DmaUserDef; + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&SalI2C0UserCBAdpt; + break; + } + + case I2C1_SEL: + { + pSalI2CMngtAdpt = &SalI2C1MngtAdpt; + pSalI2CMngtAdpt->pSalHndPriv = &SalI2C1HndPriv; + pSalI2CMngtAdpt->pHalInitDat = &HalI2C1InitData; + pSalI2CMngtAdpt->pHalOp = &HalI2COpSAL; + pSalI2CMngtAdpt->pIrqHnd = &I2C1IrqHandleDat; + pSalI2CMngtAdpt->pHalTxGdmaAdp = &HalI2C1TxGdmaAdpt; + pSalI2CMngtAdpt->pHalRxGdmaAdp = &HalI2C1RxGdmaAdpt; + pSalI2CMngtAdpt->pHalGdmaOp = &HalI2C1GdmaOp; + pSalI2CMngtAdpt->pIrqTxGdmaHnd = &I2C1TxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pIrqRxGdmaHnd = &I2C1RxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pUserCB = &SalI2C1UserCB; + pSalI2CMngtAdpt->pDMAConf = &SalI2C1DmaUserDef; + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&SalI2C1UserCBAdpt; + break; + } + + case I2C2_SEL: + { + pSalI2CMngtAdpt = &SalI2C2MngtAdpt; + pSalI2CMngtAdpt->pSalHndPriv = &SalI2C2HndPriv; + pSalI2CMngtAdpt->pHalInitDat = &HalI2C2InitData; + pSalI2CMngtAdpt->pHalOp = &HalI2COpSAL; + pSalI2CMngtAdpt->pIrqHnd = &I2C2IrqHandleDat; + pSalI2CMngtAdpt->pHalTxGdmaAdp = &HalI2C2TxGdmaAdpt; + pSalI2CMngtAdpt->pHalRxGdmaAdp = &HalI2C2RxGdmaAdpt; + pSalI2CMngtAdpt->pHalGdmaOp = &HalI2C2GdmaOp; + pSalI2CMngtAdpt->pIrqTxGdmaHnd = &I2C2TxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pIrqRxGdmaHnd = &I2C2RxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pUserCB = &SalI2C2UserCB; + pSalI2CMngtAdpt->pDMAConf = &SalI2C2DmaUserDef; + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&SalI2C2UserCBAdpt; + break; + } + + case I2C3_SEL: + { + pSalI2CMngtAdpt = &SalI2C3MngtAdpt; + pSalI2CMngtAdpt->pSalHndPriv = &SalI2C3HndPriv; + pSalI2CMngtAdpt->pHalInitDat = &HalI2C3InitData; + pSalI2CMngtAdpt->pHalOp = &HalI2COpSAL; + pSalI2CMngtAdpt->pIrqHnd = &I2C3IrqHandleDat; + pSalI2CMngtAdpt->pHalTxGdmaAdp = &HalI2C3TxGdmaAdpt; + pSalI2CMngtAdpt->pHalRxGdmaAdp = &HalI2C3RxGdmaAdpt; + pSalI2CMngtAdpt->pHalGdmaOp = &HalI2C3GdmaOp; + pSalI2CMngtAdpt->pIrqTxGdmaHnd = &I2C3TxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pIrqRxGdmaHnd = &I2C3RxGdmaIrqHandleDat; + pSalI2CMngtAdpt->pUserCB = &SalI2C3UserCB; + pSalI2CMngtAdpt->pDMAConf = &SalI2C3DmaUserDef; + pSalI2CUserCBAdpt = (PSAL_I2C_USERCB_ADPT)&SalI2C3UserCBAdpt; + break; + } + + default + break; + } +#endif + + /*To assign user callback pointers*/ + pSalI2CMngtAdpt->pUserCB->pTXCB = pSalI2CUserCBAdpt; + pSalI2CMngtAdpt->pUserCB->pTXCCB = (pSalI2CUserCBAdpt+1); + pSalI2CMngtAdpt->pUserCB->pRXCB = (pSalI2CUserCBAdpt+2); + pSalI2CMngtAdpt->pUserCB->pRXCCB = (pSalI2CUserCBAdpt+3); + pSalI2CMngtAdpt->pUserCB->pRDREQCB = (pSalI2CUserCBAdpt+4); + pSalI2CMngtAdpt->pUserCB->pERRCB = (pSalI2CUserCBAdpt+5); + pSalI2CMngtAdpt->pUserCB->pDMATXCB = (pSalI2CUserCBAdpt+6); + pSalI2CMngtAdpt->pUserCB->pDMATXCCB = (pSalI2CUserCBAdpt+7); + pSalI2CMngtAdpt->pUserCB->pDMARXCB = (pSalI2CUserCBAdpt+8); + pSalI2CMngtAdpt->pUserCB->pDMARXCCB = (pSalI2CUserCBAdpt+9); + pSalI2CMngtAdpt->pUserCB->pGENCALLCB= (pSalI2CUserCBAdpt+10); + + /*To assign the rest pointers*/ + pSalI2CMngtAdpt->MstRDCmdCnt = 0; + pSalI2CMngtAdpt->InnerTimeOut = 2000; // inner time-out count, 2000 ms + pSalI2CMngtAdpt->pSalHndPriv->ppSalI2CHnd = (void**)&(pSalI2CMngtAdpt->pSalHndPriv); + + /* To assign the default (ROM) HAL OP initialization function */ +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_Patch; +#elif defined(CONFIG_CHIP_E_CUT) + // TODO: E-Cut + pSalI2CMngtAdpt->pHalOpInit = HalI2COpInit_V04; +#endif + + /* To assign the default (ROM) HAL GDMA OP initialization function */ + pSalI2CMngtAdpt->pHalGdmaOpInit = HalGdmaOpInit; + + /* To assign the default (ROM) SAL interrupt function */ +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) || defined(CONFIG_CHIP_C_CUT) + pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_Patch; +#elif defined(CONFIG_CHIP_E_CUT) + pSalI2CMngtAdpt->pSalIrqFunc = I2CISRHandle_V04; +#endif + + /* To assign the default (ROM) SAL DMA TX interrupt function */ + pSalI2CMngtAdpt->pSalDMATxIrqFunc = I2CTXGDMAISRHandle; + + /* To assign the default (ROM) SAL DMA RX interrupt function */ + pSalI2CMngtAdpt->pSalDMARxIrqFunc = I2CRXGDMAISRHandle; + + return pSalI2CMngtAdpt; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CFreeMngtAdpt +// +// Description: +// Free all the previous allocated memory space. +// +// Arguments: +// [in] PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt - +// I2C SAL management adapter pointer +// +// +// Return: +// The status of the enable process. +// _EXIT_SUCCESS if the RtkI2CFreeMngtAdpt succeeded. +// _EXIT_FAILURE if the RtkI2CFreeMngtAdpt failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-02. +// +//--------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CFreeMngtAdpt( + IN PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt +){ +#ifdef I2C_STATIC_ALLOC + RtlMfree((u8 *)pSalI2CMngtAdpt->pUserCB->pTXCB, (sizeof(SAL_I2C_USERCB_ADPT)*SAL_USER_CB_NUM)); + RtlMfree((u8 *)pSalI2CMngtAdpt->pDMAConf, (sizeof(SAL_I2C_DMA_USER_DEF))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pIrqRxGdmaHnd, (sizeof(IRQ_HANDLE))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pIrqTxGdmaHnd, (sizeof(IRQ_HANDLE))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pHalGdmaOp, (sizeof(HAL_GDMA_OP))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pHalRxGdmaAdp, (sizeof(HAL_GDMA_ADAPTER))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pHalTxGdmaAdp, (sizeof(HAL_GDMA_ADAPTER))); + RtlMfree((u8 *)pSalI2CMngtAdpt->pUserCB, sizeof(SAL_I2C_USER_CB)); + RtlMfree((u8 *)pSalI2CMngtAdpt->pIrqHnd, sizeof(IRQ_HANDLE)); + RtlMfree((u8 *)pSalI2CMngtAdpt->pHalOp, sizeof(HAL_I2C_OP)); + RtlMfree((u8 *)pSalI2CMngtAdpt->pHalInitDat, sizeof(HAL_I2C_INIT_DAT)); + RtlMfree((u8 *)pSalI2CMngtAdpt->pSalHndPriv, sizeof(SAL_I2C_HND_PRIV)); + RtlMfree((u8 *)pSalI2CMngtAdpt, sizeof(SAL_I2C_MNGT_ADPT)); +#else + ; +#endif + + return HAL_OK; +} + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CGetSalHnd +// +// Description: +// Allocation of lower layer memory spaces will be done by invoking RtkI2CGetMngtAdpt +// in this function and return a SAL_I2C_HND pointer to upper layer. +// According to the given I2C index, RtkI2CGetMngtAdpt will allocate all the memory +// space such as SAL_I2C_HND, HAL_I2C_INIT_DAT, SAL_I2C_USER_CB etc. +// +// +// Arguments: +// [in] u8 I2CIdx - +// I2C Index +// +// Return: +// PSAL_I2C_HND +// A pointer to SAL_I2C_HND which is allocated in the lower layer. +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +PSAL_I2C_HND +RtkI2CGetSalHnd( + IN u8 I2CIdx +){ + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND pSalI2CHND = NULL; + + /* Check the user define setting and the given index */ + if (RtkI2CIdxChk(I2CIdx)) { + return (PSAL_I2C_HND)NULL; + } + + /* Invoke RtkI2CGetMngtAdpt to get the I2C SAL management adapter pointer */ + pSalI2CMngtAdpt = RtkI2CGetMngtAdpt(I2CIdx); + + /* Assign the private SAL handle to public SAL handle */ + pSalI2CHND = &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); + + /* Assign the internal HAL initial data pointer to the SAL handle */ + pSalI2CHND->pInitDat = pSalI2CMngtAdpt->pHalInitDat; + + /* Assign the internal user callback pointer to the SAL handle */ + pSalI2CHND->pUserCB = pSalI2CMngtAdpt->pUserCB; + + /* Assign the internal user define DMA configuration to the SAL handle */ + pSalI2CHND->pDMAConf = pSalI2CMngtAdpt->pDMAConf; + + return &(pSalI2CMngtAdpt->pSalHndPriv->SalI2CHndPriv); +} + + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkI2CFreeSalHnd +// +// Description: +// Based on the given pSalI2CHND, the top layer management adapter pointer could +// be reversely parsed. And free memory space is done by RtkI2CFreeMngtAdpt. +// +// +// Arguments: +// [in] PSAL_I2C_HND pSalI2CHND - +// SAL I2C handle +// +// Return: +// The status of the free SAL memory space process. +// _EXIT_SUCCESS if the RtkI2CFreeSalHnd succeeded. +// _EXIT_FAILURE if the RtkI2CFreeSalHnd failed. +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//---------------------------------------------------------------------------------------------------- +HAL_Status +RtkI2CFreeSalHnd( + IN PSAL_I2C_HND pSalI2CHND +){ + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PSAL_I2C_HND_PRIV pSalI2CHNDPriv = NULL; + + /* To get the SAL_I2C_MNGT_ADPT pointer */ + pSalI2CHNDPriv = CONTAINER_OF(pSalI2CHND, SAL_I2C_HND_PRIV, SalI2CHndPriv); + pSalI2CMngtAdpt = CONTAINER_OF(pSalI2CHNDPriv->ppSalI2CHnd, SAL_I2C_MNGT_ADPT, pSalHndPriv); + + /* Invoke RtkI2CFreeMngtAdpt to free all the lower layer memory space */ + return (RtkI2CFreeMngtAdpt(pSalI2CMngtAdpt)); +} + +#endif // end of "#ifndef CONFIG_MBED_ENABLED" + +//--------------------------------------------------------------------------------------------------- +//Function Name: +// RtkSalI2CSts +// +// Description: +// Get i2c status +// +// Arguments: +// A SAL operation adapter pointer +// +// Return: +// NA +// +// Note: +// NA +// +// See Also: +// NA +// +// Author: +// By Jason Deng, 2014-04-03. +// +//--------------------------------------------------------------------------------------------------- +u32 +RtkSalI2CSts( + IN VOID *Data +){ + PSAL_I2C_HND pSalI2CHND = (PSAL_I2C_HND) Data; + PSAL_I2C_HND_PRIV pSalI2CHNDPriv = NULL; + PSAL_I2C_MNGT_ADPT pSalI2CMngtAdpt = NULL; + PHAL_I2C_INIT_DAT pHalI2CInitDat = NULL; + PHAL_I2C_OP pHalI2COP = NULL; + u32 I2CLocalTemp; + + + /* To Get the SAL_I2C_MNGT_ADPT Pointer */ + pSalI2CHNDPriv = CONTAINER_OF(pSalI2CHND, SAL_I2C_HND_PRIV, SalI2CHndPriv); + pSalI2CMngtAdpt = CONTAINER_OF(pSalI2CHNDPriv->ppSalI2CHnd, SAL_I2C_MNGT_ADPT, pSalHndPriv); + + pHalI2CInitDat = pSalI2CMngtAdpt->pHalInitDat; + pHalI2COP = pSalI2CMngtAdpt->pHalOp; + + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_RAW_INTR_STAT); + + if (I2CLocalTemp & BIT_IC_RAW_INTR_STAT_GEN_CALL) { + return 2; + } + else if (I2CLocalTemp & BIT_IC_RAW_INTR_STAT_RD_REQ) { + return 1; + } + + I2CLocalTemp = pHalI2COP->HalI2CReadReg(pHalI2CInitDat, REG_DW_I2C_IC_STATUS); + + if (I2CLocalTemp & BIT_IC_STATUS_RFNE) { + return 3; + } + + return 0; +} + +#endif // CONFIG_I2C_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2s.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2s.c new file mode 100644 index 0000000..2cd8163 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_i2s.c @@ -0,0 +1,562 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "hal_i2s.h" +#include "rand.h" +#include "rtl_utility.h" + +#ifdef CONFIG_I2S_EN + +//1 need to be modified + + +/*====================================================== + Local used variables +*/ +SRAM_BF_DATA_SECTION +HAL_I2S_OP HalI2SOpSAL={0}; + + +VOID +I2SISRHandle( + IN VOID *Data +) +{ + PHAL_I2S_ADAPTER pI2SAdp = (PHAL_I2S_ADAPTER) Data; + PHAL_I2S_OP pHalI2SOP = &HalI2SOpSAL; + PHAL_I2S_INIT_DAT pI2SCfg = pI2SAdp->pInitDat; + u32 I2STxIsr, I2SRxIsr; + u8 I2SPageNum = pI2SCfg->I2SPageNum+1; +// u32 I2SPageSize = (pI2SAdp->I2SPageSize+1)<<2; + u32 i; + u32 pbuf; + + I2STxIsr = pHalI2SOP->HalI2SReadReg(pI2SCfg, REG_I2S_TX_STATUS_INT); + I2SRxIsr = pHalI2SOP->HalI2SReadReg(pI2SCfg, REG_I2S_RX_STATUS_INT); + + pI2SCfg->I2STxIntrClr = I2STxIsr; + pI2SCfg->I2SRxIntrClr = I2SRxIsr; + pHalI2SOP->HalI2SClrIntr(pI2SCfg); + + for (i=0 ; iI2SHWTxIdx)) { +// pbuf = ((u32)(pI2SCfg->I2STxData)) + (I2SPageSize*pI2SCfg->I2SHWTxIdx); + pbuf = (u32)pI2SAdp->TxPageList[pI2SCfg->I2SHWTxIdx]; + pI2SAdp->UserCB.TxCCB(pI2SAdp->UserCB.TxCBId, (char*)pbuf); + I2STxIsr &= ~(1<I2SHWTxIdx); + pI2SCfg->I2SHWTxIdx += 1; + if (pI2SCfg->I2SHWTxIdx == I2SPageNum) { + pI2SCfg->I2SHWTxIdx = 0; + } + } + + if (I2SRxIsr & (1<I2SHWRxIdx)) { +// pbuf = ((u32)(pI2SCfg->I2SRxData)) + (I2SPageSize*pI2SCfg->I2SHWRxIdx); + pbuf = (u32)pI2SAdp->RxPageList[pI2SCfg->I2SHWRxIdx]; + pI2SAdp->UserCB.RxCCB(pI2SAdp->UserCB.RxCBId, (char*)pbuf); + I2SRxIsr &= ~(1<I2SHWRxIdx); + pI2SCfg->I2SHWRxIdx += 1; + if (pI2SCfg->I2SHWRxIdx == I2SPageNum) { + pI2SCfg->I2SHWRxIdx = 0; + } + } + } +} + + +static HAL_Status +RtkI2SIrqInit( + IN PHAL_I2S_ADAPTER pI2SAdapter +) +{ + PIRQ_HANDLE pIrqHandle; + + if (pI2SAdapter->DevNum > I2S_MAX_ID) { + DBG_I2S_ERR("RtkI2SIrqInit: Invalid I2S Index(&d)\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + pIrqHandle = &pI2SAdapter->IrqHandle; + + switch (pI2SAdapter->DevNum){ + case I2S0_SEL: + pIrqHandle->IrqNum = I2S0_PCM0_IRQ; + break; + + case I2S1_SEL: + pIrqHandle->IrqNum = I2S1_PCM1_IRQ; + break; + + default: + return HAL_ERR_PARA; + } + + pIrqHandle->Data = (u32) (pI2SAdapter); + pIrqHandle->IrqFun = (IRQ_FUN) I2SISRHandle; + pIrqHandle->Priority = 6; + InterruptRegister(pIrqHandle); + InterruptEn(pIrqHandle); + + return HAL_OK; +} + +static HAL_Status +RtkI2SIrqDeInit( + IN PHAL_I2S_ADAPTER pI2SAdapter +) +{ + if (pI2SAdapter->DevNum > I2S_MAX_ID) { + DBG_I2S_ERR("RtkI2SIrqDeInit: Invalid I2S Index(&d)\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + InterruptDis(&pI2SAdapter->IrqHandle); + InterruptUnRegister(&pI2SAdapter->IrqHandle); + + return HAL_OK; +} + +static HAL_Status +RtkI2SPinMuxInit( + IN PHAL_I2S_ADAPTER pI2SAdapter +) +{ + u32 I2Stemp; + + if (pI2SAdapter->DevNum > I2S_MAX_ID) { + DBG_I2S_ERR("RtkI2SPinMuxInit: Invalid I2S Index(&d)\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + // enable system pll + I2Stemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) | (1<<9) | (1<<10); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, I2Stemp); + + switch (pI2SAdapter->DevNum){ + case I2S0_SEL: + ACTCK_I2S_CCTRL(ON); + SLPCK_I2S_CCTRL(ON); + LXBUS_FCTRL(ON); // enable lx bus for i2s + + /*I2S0 Pin Mux Setting*/ + PinCtrl(I2S0, pI2SAdapter->PinMux, ON); + if (pI2SAdapter->PinMux == I2S_S0) { + DBG_I2S_WARN(ANSI_COLOR_MAGENTA"I2S0 Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET); + } + I2S0_MCK_CTRL(ON); + I2S0_PIN_CTRL(ON); + I2S0_FCTRL(ON); + + break; + case I2S1_SEL: + ACTCK_I2S_CCTRL(ON); + SLPCK_I2S_CCTRL(ON); + LXBUS_FCTRL(ON); // enable lx bus for i2s + + /*I2S1 Pin Mux Setting*/ + PinCtrl(I2S1, pI2SAdapter->PinMux, ON); + if (pI2SAdapter->PinMux == I2S_S2) { + DBG_I2S_WARN(ANSI_COLOR_MAGENTA"I2S1 Pin may conflict with JTAG\r\n"ANSI_COLOR_RESET); + } + I2S1_MCK_CTRL(ON); + I2S1_PIN_CTRL(ON); + I2S0_FCTRL(ON); //i2s 1 is control by bit 24 BIT_PERI_I2S0_EN + I2S1_FCTRL(ON); + break; + default: + return HAL_ERR_PARA; + } + + return HAL_OK; +} + + +static HAL_Status +RtkI2SPinMuxDeInit( + IN PHAL_I2S_ADAPTER pI2SAdapter +) +{ + if (pI2SAdapter->DevNum > I2S_MAX_ID) { + DBG_I2S_ERR("RtkI2SPinMuxDeInit: Invalid I2S Index(&d)\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + switch (pI2SAdapter->DevNum){ + case I2S0_SEL: + /*I2S0 Pin Mux Setting*/ + //ACTCK_I2C0_CCTRL(OFF); + PinCtrl(I2S0, pI2SAdapter->PinMux, OFF); + I2S0_MCK_CTRL(OFF); + I2S0_PIN_CTRL(OFF); + //I2S0_FCTRL(OFF); + + break; + case I2S1_SEL: + /*I2S1 Pin Mux Setting*/ + //ACTCK_I2C1_CCTRL(OFF); + PinCtrl(I2S1, pI2SAdapter->PinMux, OFF); + I2S1_MCK_CTRL(OFF); + I2S1_PIN_CTRL(OFF); + //I2S1_FCTRL(OFF); + break; + default: + return HAL_ERR_PARA; + } + + return HAL_OK; +} + + +HAL_Status +RtkI2SInit( + IN VOID *Data +) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + PHAL_I2S_OP pHalI2SOP = &HalI2SOpSAL; + PHAL_I2S_INIT_DAT pI2SCfg; + + if (pI2SAdapter == 0) { + DBG_I2S_ERR("RtkI2SInit: Null Pointer\r\n"); + return HAL_ERR_PARA; + } + + if (pI2SAdapter->DevNum > I2S_MAX_ID) { + DBG_I2S_ERR("RtkI2SInit: Invalid I2S Index(&d)\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + pI2SCfg = pI2SAdapter->pInitDat; + + /*I2S Initialize HAL Operations*/ + HalI2SOpInit(pHalI2SOP); + + /*I2S Interrupt Initialization*/ + RtkI2SIrqInit(pI2SAdapter); + + /*I2S Pin Mux Initialization*/ + RtkI2SPinMuxInit(pI2SAdapter); + + /*I2S Load User Setting*/ + pI2SCfg->I2SIdx = pI2SAdapter->DevNum; + + /*I2S HAL Initialization*/ + pHalI2SOP->HalI2SInit(pI2SCfg); + + /*I2S Device Status Update*/ + pI2SAdapter->DevSts = I2S_STS_INITIALIZED; + + /*I2S Enable Module*/ + pI2SCfg->I2SEn = I2S_ENABLE; + pHalI2SOP->HalI2SEnable(pI2SCfg); + + /*I2S Device Status Update*/ + pI2SAdapter->DevSts = I2S_STS_IDLE; + + return HAL_OK; +} + +HAL_Status +RtkI2SDeInit( + IN VOID *Data +) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + PHAL_I2S_OP pHalI2SOP = &HalI2SOpSAL; + PHAL_I2S_INIT_DAT pI2SCfg; + u32 I2Stemp; + + if (pI2SAdapter == 0) { + DBG_I2S_ERR("RtkI2SDeInit: Null Pointer\r\n"); + return HAL_ERR_PARA; + } + + pI2SCfg = pI2SAdapter->pInitDat; + + /*I2S Disable Module*/ + pI2SCfg->I2SEn = I2S_DISABLE; + pHalI2SOP->HalI2SEnable(pI2SCfg); + HalI2SClearAllOwnBit((VOID*)pI2SCfg); + + /*I2C HAL DeInitialization*/ + //pHalI2SOP->HalI2SDeInit(pI2SCfg); + + /*I2S Interrupt DeInitialization*/ + RtkI2SIrqDeInit(pI2SAdapter); + + /*I2S Pin Mux DeInitialization*/ + RtkI2SPinMuxDeInit(pI2SAdapter); + + /*I2S HAL DeInitialization*/ + pHalI2SOP->HalI2SDeInit(pI2SCfg); + + /*I2S CLK Source Close*/ + I2Stemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) & (~((1<<9) | (1<<10))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, I2Stemp); + + /*I2S Device Status Update*/ + pI2SAdapter->DevSts = I2S_STS_UNINITIAL; + + return HAL_OK; +} + +HAL_Status +RtkI2SEnable( + IN VOID *Data +) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + PHAL_I2S_OP pHalI2SOP = &HalI2SOpSAL; + PHAL_I2S_INIT_DAT pI2SCfg; + u32 I2Stemp; + + // Enable IP Clock + I2Stemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) | (1<<9) | (1<<10); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, I2Stemp); + ACTCK_I2S_CCTRL(ON); + SLPCK_I2S_CCTRL(ON); + + pI2SCfg = pI2SAdapter->pInitDat; + pI2SCfg->I2SEn = I2S_ENABLE; + pHalI2SOP->HalI2SEnable(pI2SCfg); + + return HAL_OK; +} + +HAL_Status +RtkI2SDisable( + IN VOID *Data +) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + PHAL_I2S_OP pHalI2SOP = &HalI2SOpSAL; + PHAL_I2S_INIT_DAT pI2SCfg; + u32 I2Stemp; + + pI2SCfg = pI2SAdapter->pInitDat; + pI2SCfg->I2SEn = I2S_DISABLE; + pHalI2SOP->HalI2SEnable(pI2SCfg); + + // Gate IP Clock + ACTCK_I2S_CCTRL(OFF); + SLPCK_I2S_CCTRL(OFF); + + // Close I2S bus clock(WS,SCLK,MCLK). If needs that clock, mark this. + I2Stemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1) & (~((1<<9) | (1<<10))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL1, I2Stemp); + + return HAL_OK; +} + +RTK_STATUS +RtkI2SIoCtrl( + IN VOID *Data +) +{ + return _EXIT_SUCCESS; +} + +RTK_STATUS +RtkI2SPowerCtrl( + IN VOID *Data +) +{ + return _EXIT_SUCCESS; +} + +HAL_Status +RtkI2SLoadDefault( + IN VOID *Adapter, + IN VOID *Setting +) +{ + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Adapter; + PHAL_I2S_INIT_DAT pI2SCfg = pI2SAdapter->pInitDat; + PHAL_I2S_DEF_SETTING pLoadSetting = (PHAL_I2S_DEF_SETTING)Setting; + + if (pI2SAdapter == 0) { + DBG_I2S_ERR("RtkI2SLoadDefault: Null Pointer\r\n"); + return HAL_ERR_PARA; + } + + if (pI2SAdapter->pInitDat == NULL) { + DBG_I2S_ERR("RtkI2SLoadDefault: pInitDat is NULL!\r\n", pI2SAdapter->DevNum); + return HAL_ERR_PARA; + } + + pI2SAdapter->DevSts = pLoadSetting->DevSts; + pI2SAdapter->ErrType = 0; + pI2SAdapter->TimeOut = 0; + + pI2SCfg->I2SIdx = pI2SAdapter->DevNum; + pI2SCfg->I2SEn = I2S_DISABLE; + pI2SCfg->I2SMaster = pLoadSetting->I2SMaster; + pI2SCfg->I2SWordLen = pLoadSetting->I2SWordLen; + pI2SCfg->I2SChNum = pLoadSetting->I2SChNum; + pI2SCfg->I2SPageNum = pLoadSetting->I2SPageNum; + pI2SCfg->I2SPageSize = pLoadSetting->I2SPageSize; + pI2SCfg->I2SRate = pLoadSetting->I2SRate; + pI2SCfg->I2STRxAct = pLoadSetting->I2STRxAct; + pI2SCfg->I2STxIntrMSK = pLoadSetting->I2STxIntrMSK; + pI2SCfg->I2SRxIntrMSK = pLoadSetting->I2SRxIntrMSK; + + return HAL_OK; +} + +VOID HalI2SOpInit( + IN VOID *Data +) +{ + PHAL_I2S_OP pHalI2SOp = (PHAL_I2S_OP) Data; + + pHalI2SOp->HalI2SDeInit = HalI2SDeInitRtl8195a; + pHalI2SOp->HalI2STx = HalI2STxRtl8195a; + pHalI2SOp->HalI2SRx = HalI2SRxRtl8195a; + pHalI2SOp->HalI2SEnable = HalI2SEnableRtl8195a; + pHalI2SOp->HalI2SIntrCtrl = HalI2SIntrCtrlRtl8195a; + pHalI2SOp->HalI2SReadReg = HalI2SReadRegRtl8195a; + pHalI2SOp->HalI2SClrIntr = HalI2SClrIntrRtl8195a; + pHalI2SOp->HalI2SClrAllIntr = HalI2SClrAllIntrRtl8195a; + pHalI2SOp->HalI2SDMACtrl = HalI2SDMACtrlRtl8195a; + +#ifndef CONFIG_CHIP_E_CUT + pHalI2SOp->HalI2SInit = HalI2SInitRtl8195a_Patch; + pHalI2SOp->HalI2SSetRate = HalI2SSetRateRtl8195a; + pHalI2SOp->HalI2SSetWordLen = HalI2SSetWordLenRtl8195a; + pHalI2SOp->HalI2SSetChNum = HalI2SSetChNumRtl8195a; + pHalI2SOp->HalI2SSetPageNum = HalI2SSetPageNumRtl8195a; + pHalI2SOp->HalI2SSetPageSize = HalI2SSetPageSizeRtl8195a; +#else + pHalI2SOp->HalI2SInit = HalI2SInitRtl8195a_V04; + pHalI2SOp->HalI2SSetRate = HalI2SSetRateRtl8195a_V04; + pHalI2SOp->HalI2SSetWordLen = HalI2SSetWordLenRtl8195a_V04; + pHalI2SOp->HalI2SSetChNum = HalI2SSetChNumRtl8195a_V04; + pHalI2SOp->HalI2SSetPageNum = HalI2SSetPageNumRtl8195a_V04; + pHalI2SOp->HalI2SSetPageSize = HalI2SSetPageSizeRtl8195a_V04; +#endif // #ifndef CONFIG_CHIP_E_CUT +} + +HAL_Status +HalI2SInit( + IN VOID *Data +) +{ + HAL_Status ret; + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + u32 Function; + u8 funret; + +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE I2sPwrState; +#endif + + if(pI2SAdapter->DevNum == 0){ + Function = I2S0; + } + else { + Function = I2S1; + } + + funret = FunctionChk(Function, (u32)pI2SAdapter->PinMux); + + if (funret == _FALSE){ + return HAL_ERR_HW; + } + + ret = RtkI2SInit(Data); +#ifdef CONFIG_SOC_PS_MODULE + if(ret == HAL_OK) { + // To register a new peripheral device power state + I2sPwrState.FuncIdx = I2S0 + pI2SAdapter->DevNum; + I2sPwrState.PwrState = ACT; + RegPowerState(I2sPwrState); + } +#endif + + return ret; + +} + +VOID +HalI2SDeInit( + IN VOID *Data +) +{ +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE I2sPwrState; + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; + u8 HwState; + + I2sPwrState.FuncIdx = I2S0 + pI2SAdapter->DevNum; + QueryRegPwrState(I2sPwrState.FuncIdx, &(I2sPwrState.PwrState), &HwState); + + // if the power state isn't ACT, then switch the power state back to ACT first + if ((I2sPwrState.PwrState != ACT) && (I2sPwrState.PwrState != INACT)) { + HalI2SEnable(Data); + QueryRegPwrState(I2sPwrState.FuncIdx, &(I2sPwrState.PwrState), &HwState); + } + + if (I2sPwrState.PwrState == ACT) { + I2sPwrState.PwrState = INACT; + RegPowerState(I2sPwrState); + } +#endif + + RtkI2SDeInit(Data); + +} + + +HAL_Status +HalI2SDisable( + IN VOID *Data +) +{ + HAL_Status ret; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE I2sPwrState; + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; +#endif + + ret = RtkI2SDisable(Data); +#ifdef CONFIG_SOC_PS_MODULE + if (ret == HAL_OK) { + I2sPwrState.FuncIdx = I2S0 + pI2SAdapter->DevNum; + I2sPwrState.PwrState = SLPCG; + RegPowerState(I2sPwrState); + } +#endif + return ret; +} + +HAL_Status +HalI2SEnable( + IN VOID *Data +) +{ + HAL_Status ret; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE I2sPwrState; + PHAL_I2S_ADAPTER pI2SAdapter = (PHAL_I2S_ADAPTER) Data; +#endif + + ret = RtkI2SEnable(Data); +#ifdef CONFIG_SOC_PS_MODULE + if (ret == HAL_OK) { + I2sPwrState.FuncIdx = I2S0 + pI2SAdapter->DevNum; + I2sPwrState.PwrState = ACT; + RegPowerState(I2sPwrState); + } +#endif + return ret; +} + +#endif // CONFIG_I2S_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_log_uart.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_log_uart.c new file mode 100644 index 0000000..90582ff --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_log_uart.c @@ -0,0 +1,442 @@ +/* + * hal_log_uart.c + * + * Created on: 08/10/2016 + * Author: pvvx + */ +#include "rtl8195a.h" + +#ifdef CONFIG_LOG_UART_EN + +#include "hal_log_uart.h" + +//------------------------------------------------------------------------- +// Function declarations +/* +VOID HalLogUartIrqHandle(VOID * Data); +VOID HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartSetIntEn(HAL_LOG_UART_ADAPTER *pUartAdapter); +u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter); +u32 HalLogUartRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pRxData, u32 Length, u32 TimeoutMS); +u32 HalLogUartSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length, u32 TimeoutMS); +HAL_Status HalLogUartIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length); +HAL_Status HalLogUartIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pRxData, u32 Length); +VOID HalLogUartAbortIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartAbortIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter); +HAL_Status HalLogUartRstFIFO(HAL_LOG_UART_ADAPTER *pUartAdapter, u8 RstCtrl); +VOID HalLogUartEnable(HAL_LOG_UART_ADAPTER *pUartAdapter); +VOID HalLogUartDisable(HAL_LOG_UART_ADAPTER *pUartAdapter); + */ +extern VOID UartLogIrqHandleRam(VOID * Data); +// extern DiagPrintf(); +// extern HalGetCpuClk(void); +// extern VectorIrqUnRegisterRtl8195A(); +// extern VectorIrqRegisterRtl8195A(); +// extern VectorIrqEnRtl8195A(); +// extern RuartIsTimeout(); +// extern HalDelayUs(); +// extern HalPinCtrlRtl8195A(); +// extern HalLogUartInit(); +//------------------------------------------------------------------------- +// Data declarations +// extern ConfigDebugWarn; +// extern ConfigDebugErr; +// extern HalTimerOp; +// extern ConfigDebugInfo; +// extern UartLogIrqHandleRam; +//------------------------------------------------------------------------- +/* + * 16 bytes FIFO ... 16*11/38400 = 0.004583 sec + * (0.005/5)*166666666 = 166666.666 + */ +VOID HalLogUartWaitTxFifoEmpty(VOID) { + int x = 16384; + while((!(HAL_READ8(LOG_UART_REG_BASE, 0x14) & BIT6)) && x--); +} + +//----- HalLogUartIrqRxRdyHandle +void HalLogUartIrqRxRdyHandle(HAL_LOG_UART_ADAPTER *pUartAdapter) { + volatile uint8_t *pRxBuf = pUartAdapter->pRxBuf; + if (pRxBuf != NULL) { + while (pUartAdapter->RxCount) { + if (!(HAL_UART_READ32(UART_INTERRUPT_EN_REG_OFF) & 1)) // v40003014 + { + if (pUartAdapter->RxCount <= 7) { + pUartAdapter->FIFOControl = pUartAdapter->FIFOControl + & (~(FCR_RX_TRIG_MASK)); // & 0xFFFFFF3F; + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, + pUartAdapter->FIFOControl); // 40003008 + } + break; + } + *pRxBuf++ = HAL_UART_READ32(UART_REV_BUF_OFF); // 40003000; + --pUartAdapter->RxCount; + } + if (!pUartAdapter->RxCount) { + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg + & (~(IER_ERBFI | IER_ELSI)); // & 0xFFFFFFFA; + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 + if (pUartAdapter->pRxBuf != pRxBuf) { + if (pUartAdapter->RxCompCallback) + pUartAdapter->RxCompCallback(pUartAdapter->RxCompCbPara); + } + if (pUartAdapter->FIFOControl & FCR_RX_TRIG_MASK) // 0xC0 + { + pUartAdapter->FIFOControl = pUartAdapter->FIFOControl + & (~(FCR_RX_TRIG_MASK)); // & 0xFFFFFF3F; + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, + pUartAdapter->FIFOControl); // 40003008 + } + } + pUartAdapter->pRxBuf = pRxBuf; + } else + DBG_UART_WARN("HalLogUartIrqRxDataHandle: No RX Buffer\n"); +} + +//----- HalLogUartIrqHandle +void HalLogUartIrqHandle(VOID * Data) { + PHAL_LOG_UART_ADAPTER pUartAdapter = (PHAL_LOG_UART_ADAPTER) Data; + u32 iir = HAL_UART_READ32(UART_INTERRUPT_IDEN_REG_OFF) & 0x0F; // v40003008 & 0xF; + switch(iir) { + case IIR_MODEM_STATUS: // Clear to send or data set ready or ring indicator or data carrier detect. + break; + case IIR_NO_PENDING: + return; + case IIR_THR_EMPTY: // TX FIFO level lower than threshold or FIFO empty + { + volatile u8 * pTxBuf = pUartAdapter->pTxBuf; + if (pTxBuf != NULL) { + while (pUartAdapter->TxCount) { + if (!(HAL_UART_READ32(UART_LINE_STATUS_REG_OFF) & LSR_THRE)) { // v40003014 & 0x20 // Transmit Holding Register Empty bit(IER_PTIME=0) + HAL_UART_WRITE32(UART_REV_BUF_OFF, *pTxBuf++); + pUartAdapter->TxCount--; // *((_DWORD *)v1 + 4); + } + } + pUartAdapter->pTxBuf = pTxBuf; + if (!(pUartAdapter->TxCount)) { + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg & (~IER_PTIME); // & 0xFFFFFF7F + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, + pUartAdapter->IntEnReg); // 40003004 + if (HAL_UART_READ32(UART_LINE_STATUS_REG_OFF) & LSR_THRE) { // 40003014 & 0x20 ) + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg + & (~IER_ETBEI); // & 0xFFFFFFFD + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, + pUartAdapter->IntEnReg); // 40003004 + if (pUartAdapter->TxCompCallback != NULL) + pUartAdapter->TxCompCallback( + pUartAdapter->TxCompCbPara); + } + } + } else { + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg & (~IER_ETBEI); // & 0xFFFFFFFD + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 + } + } + break; + case IIR_RX_RDY: // RX data ready + case IIR_CHAR_TIMEOUT: // timeout: Rx dara ready but no read + HalLogUartIrqRxRdyHandle(pUartAdapter); // (HAL_LOG_UART_ADAPTER *) + break; + case IIR_RX_LINE_STATUS: // Overrun/parity/framing errors or break interrupt + pUartAdapter->LineStatus = HAL_UART_READ32(UART_LINE_STATUS_REG_OFF); // *((_BYTE *)v1 + 15) = v40003014; // LineStatusCallback + if (pUartAdapter->LineStatusCallback != NULL) + pUartAdapter->LineStatusCallback(pUartAdapter->LineStatusCbPara, pUartAdapter->LineStatus); // v3(*((_DWORD *)v1 + 17)); RxCompCallback + break; + case IIR_BUSY: + break; + default: + DBG_UART_WARN("HalLogUartIrqHandle: UnKnown Interrupt ID!\n"); + break; + } + if (pUartAdapter->api_irq_handler) + pUartAdapter->api_irq_handler(pUartAdapter->api_irq_id, iir); +} + +//----- HalLogUartSetBaudRate +void HalLogUartSetBaudRate(HAL_LOG_UART_ADAPTER *pUartAdapter) { + u32 clk4 = HalGetCpuClk() >> 2; // PLATFORM_CLOCK/2; // (unsigned int) HalGetCpuClk() >> 2; // div 4 + if (pUartAdapter->BaudRate == 0) + pUartAdapter->BaudRate = DEFAULT_BAUDRATE; + u32 br16 = pUartAdapter->BaudRate << 4; // * 16 + if ((br16 != 0) && (br16 <= clk4)) { + unsigned int dll = clk4 / br16; + if ((((10 * clk4) / br16) - (10 * dll)) > 4) + dll++; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, + HAL_UART_READ32(UART_LINE_CTL_REG_OFF) | LCR_DLAB); + HAL_UART_WRITE32(UART_DLL_OFF, dll); + HAL_UART_WRITE32(UART_DLH_OFF, dll >> 8); + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, + HAL_UART_READ32(UART_LINE_CTL_REG_OFF) & (~LCR_DLAB)); + } else + DBG_UART_ERR("Cannot support Baud Sample Rate which bigger than Serial Clk!\n"); +} + +//----- HalLogUartSetLineCtrl +void HalLogUartSetLineCtrl(HAL_LOG_UART_ADAPTER *pUartAdapter) { + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, + pUartAdapter->Stop | pUartAdapter->Parity + | pUartAdapter->DataLength); +} + +//----- HalLogUartSetIntEn +void HalLogUartSetIntEn(HAL_LOG_UART_ADAPTER *pUartAdapter) { + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); +} + +//----- HalLogUartInitSetting +u32 HalLogUartInitSetting(HAL_LOG_UART_ADAPTER *pUartAdapter) { + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (~BIT_SOC_LOG_UART_EN)); // 40000210 &= 0xFFFFEFFF; + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_LOG_UART_EN); // 40000210 |= 0x1000; + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, + HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_LOG_UART_EN); // 40000230 |= 0x1000; +// HalPinCtrlRtl8195A(LOG_UART, 0, 1); ???? + u32 clk4 = HalGetCpuClk() >> 2; // PLATFORM_CLOCK/2; // (unsigned int) HalGetCpuClk() >> 2; // div 4 + if (pUartAdapter->BaudRate == 0) + pUartAdapter->BaudRate = DEFAULT_BAUDRATE; + u32 br16 = pUartAdapter->BaudRate << 4; // * 16 + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, 0); // 40003004 = 0; + if (br16 <= clk4) { + u32 dll = clk4 / br16; + if ((((10 * clk4) / br16) - (10 * dll)) > 4) + dll++; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, LCR_DLAB); // 4000300C = 128; + HAL_UART_WRITE32(UART_DLL_OFF, dll); // v40003000 = + HAL_UART_WRITE32(UART_DLH_OFF, dll >> 8); // v40003004 = + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 0); + } + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, + pUartAdapter->Parity | pUartAdapter->Stop + | pUartAdapter->DataLength); // 4000300C = + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, pUartAdapter->FIFOControl); + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); + + pUartAdapter->IrqHandle.IrqNum = UART_LOG_IRQ; + pUartAdapter->IrqHandle.Data = (u32)pUartAdapter; + pUartAdapter->IrqHandle.IrqFun = HalLogUartIrqHandle; + pUartAdapter->IrqHandle.Priority = 14; + VectorIrqUnRegisterRtl8195A(&pUartAdapter->IrqHandle); + VectorIrqRegisterRtl8195A(&pUartAdapter->IrqHandle); + VectorIrqEnRtl8195A(&pUartAdapter->IrqHandle); + return 0; +} + +//----- HalLogUartRecv +u32 HalLogUartRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, u8 *pRxData, u32 Length, u32 TimeoutMS) { + u32 result, i, timecnt, timeout; // v4 , v10 + volatile u8 LineStatus; + + if ((pRxData != NULL) && Length) { + if (TimeoutMS - 1 > 0xFFFFFFFD) + timeout = 0; + else { + timeout = 1000 * TimeoutMS / 0x1F; + timecnt = HalTimerOp.HalTimerReadCount(1); + } + i = 0; + while (i < Length) { + LineStatus = HAL_UART_READ32(UART_LINE_STATUS_REG_OFF); + if (LineStatus & LSR_DR) { + pRxData[i++] = HAL_UART_READ32(UART_REV_BUF_OFF); + } else if (timeout) { + if (RuartIsTimeout(timecnt, timeout) == HAL_TIMEOUT) { + DBG_UART_INFO("HalLogUartRecv: Rx Timeout, RxCount=%d\n", + timecnt, timeout); + break; + } + } else if (!TimeoutMS) + break; + } + result = i; + pUartAdapter->LineStatus = LineStatus; + } else { + DBG_UART_ERR("HalLogUartRecv: Err: pRxData=0x%x, Length=%d!\n", + pRxData, Length); + result = 0; + } + return result; +} + +//----- HalLogUartSend +u32 HalLogUartSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length, u32 TimeoutMS) { + u32 i, result, timeout, timecnt; + + if ((pTxData != NULL) && Length) { + if (TimeoutMS - 1 > 0xFFFFFFFD) { + timeout = 0; + } else { + timeout = 1000 * TimeoutMS / 0x1F; + timecnt = HalTimerOp.HalTimerReadCount(1); // v4 = (*((int (__fastcall **)(_DWORD))&HalTimerOp + 2))(1); + } + i = 0; + while (i < Length) { + if (HAL_UART_READ32(UART_LINE_STATUS_REG_OFF) & LSR_THRE) { // v40003014 & 0x20 ) + HAL_UART_WRITE32(UART_REV_BUF_OFF, pTxData[i++]); // 40003000 = pTxData[i++]; + } else if (timeout) { + if (RuartIsTimeout(timecnt, timeout) == HAL_TIMEOUT) { + DBG_UART_INFO("HalLogUartSend: Tx Timeout, TxCount=%d\n", + timecnt, timeout); + break; + } + } else if (!TimeoutMS) + break; + } + if (i == Length) + while (!(HAL_UART_READ32(UART_LINE_STATUS_REG_OFF) & LSR_TEMT) + && (!timeout + || RuartIsTimeout(timecnt, timeout) != HAL_TIMEOUT)) + ; // 40003014 & 0x40 + result = i; + } else { + DBG_UART_ERR("HalLogUartSend: Err: pTxData=0x%x, Length=%d!\n", + pTxData, Length); + result = 0; + } + return result; +} + +//----- HalLogUartIntSend +HAL_Status HalLogUartIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pTxData, u32 Length) { + HAL_Status result; + if (pTxData && Length) { + pUartAdapter->TxCount = Length; + pUartAdapter->pTxBuf = pTxData; + pUartAdapter->pTxStartAddr = pTxData; + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg + | (IER_PTIME | IER_ETBEI); // | 0x82; + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 + result = HAL_OK; // 0; + } else { + DBG_UART_ERR("HalLogUartIntSend: Err: pTxData=0x%x, Length=%d!\n", + pTxData, Length); + result = HAL_ERR_PARA; //3; + } + return result; +} + +//----- HalLogUartIntRecv +HAL_Status HalLogUartIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter, + u8 *pRxData, u32 Length) { + HAL_Status result; + + if (pRxData && Length) { + pUartAdapter->pRxBuf = pRxData; + pUartAdapter->pRxStartAddr = pRxData; + pUartAdapter->RxCount = Length; + if (Length > 8) { + pUartAdapter->FIFOControl = pUartAdapter->FIFOControl + | FCR_RX_TRIG_HF; // | 0x80 RCVR Trigger: FIFO 1/2 full + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, pUartAdapter->FIFOControl); // 40003008 + } + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg + | (IER_ERBFI | IER_ELSI); // | 5 + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 + result = HAL_OK; + } else { + DBG_UART_ERR("HalLogUartIntRecv: Err: pRxData=0x%x, Length=%d\n", + pRxData, Length); + result = HAL_ERR_PARA; // 3; + } + return result; +} + +//----- HalLogUartAbortIntSend +void HalLogUartAbortIntSend(HAL_LOG_UART_ADAPTER *pUartAdapter) { + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg + & (~(IER_PTIME | IER_ETBEI)); // & 0xFFFFFF7D + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 +} + +//----- HalLogUartAbortIntRecv +void HalLogUartAbortIntRecv(HAL_LOG_UART_ADAPTER *pUartAdapter) { + pUartAdapter->IntEnReg = pUartAdapter->IntEnReg & (~(IER_ERBFI | IER_ELSI)); // & 0xFFFFFFFA + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, pUartAdapter->IntEnReg); // 40003004 + while (pUartAdapter->RxCount + && (HAL_UART_READ32(UART_LINE_STATUS_REG_OFF) & LSR_DR)) { + *pUartAdapter->pRxBuf++ = HAL_UART_READ32(UART_REV_BUF_OFF); // 40003000 + pUartAdapter->RxCount--; + } +} + +//----- HalLogUartRstFIFO +HAL_Status HalLogUartRstFIFO(HAL_LOG_UART_ADAPTER *pUartAdapter, u8 RstCtrl) { + u32 RegValue = pUartAdapter->FIFOControl; + if (RstCtrl & LOG_UART_RST_TX_FIFO) + RegValue |= FCR_RST_TX; + if (RstCtrl & LOG_UART_RST_RX_FIFO) + RegValue |= FCR_RST_RX; + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, RegValue); // 40003008 = RegValue; + if (RstCtrl & LOG_UART_RST_TX_FIFO) { + int i = 100; + for (RegValue = HAL_UART_READ32(UART_LINE_STATUS_REG_OFF); + !(RegValue & LSR_TEMT); + HAL_UART_WRITE32(UART_LINE_STATUS_REG_OFF, RegValue)) { + if (!(i--)) + break; + HalDelayUs(100); + } + } + return HAL_OK; +} + +//----- HalLogUartEnable +void HalLogUartEnable(HAL_LOG_UART_ADAPTER *pUartAdapter) { + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_LOG_UART_EN); // 40000210 |= 0x1000u; + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, + HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_LOG_UART_EN); // 40000230 |= 0x1000u; + HalPinCtrlRtl8195A(LOG_UART, 0, 1); +} + +//----- HalLogUartDisable +void HalLogUartDisable(HAL_LOG_UART_ADAPTER *pUartAdapter) { + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (~BIT_SOC_LOG_UART_EN)); // 40000210 &= 0xFFFFEFFF; + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, + HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) & (~BIT_SOC_ACTCK_LOG_UART_EN)); // 40000230 &= 0xFFFFEFFF; + HalPinCtrlRtl8195A(LOG_UART, 0, 0); +} + +//----- HalInitLogUart +void HalInitLogUart(void) { + IRQ_HANDLE UartIrqHandle; + LOG_UART_ADAPTER UartAdapter; + + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) & (~BIT_SOC_LOG_UART_EN)); // 40000210 &= 0xFFFFEFFF; + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, + HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_LOG_UART_EN); + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, + HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_LOG_UART_EN); // 40000230 |= 0x1000u; + HalPinCtrlRtl8195A(LOG_UART, 0, 1); + UartAdapter.BaudRate = DEFAULT_BAUDRATE; + UartAdapter.DataLength = UART_DATA_LEN_8BIT; + UartAdapter.FIFOControl = FCR_RX_TRIG_MASK | FCR_FIFO_EN; // 0xC1; + UartAdapter.IntEnReg = IER_ERBFI | IER_ELSI; // 5 + UartAdapter.Parity = LCR_PARITY_NONE; + UartAdapter.Stop = LCR_STOP_1B; + HalLogUartInit(UartAdapter); + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) &UartLogIrqHandleRam; + UartIrqHandle.Data = 0; + UartIrqHandle.Priority = 0; + VectorIrqUnRegisterRtl8195A(&UartIrqHandle); + VectorIrqRegisterRtl8195A(&UartIrqHandle); +} + +//----- HalDeinitLogUart +void HalDeinitLogUart(void) { + HalLogUartWaitTxFifoEmpty(); + HalPinCtrlRtl8195A(LOG_UART, 0, 0); +} + +#endif // CONFIG_LOG_UART_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_mii.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_mii.c new file mode 100644 index 0000000..5f14504 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_mii.c @@ -0,0 +1,134 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" + +#ifdef CONFIG_MII_EN + +#include "hal_mii.h" + +HAL_ETHER_ADAPTER HalEtherAdp; + + + +s32 +HalMiiInit( + IN VOID +) +{ + if (FunctionChk(MII, S0) == _FALSE) + return HAL_ERR_UNKNOWN; + else + return HalMiiInitRtl8195a(); +} + + +VOID +HalMiiDeInit( + IN VOID +) +{ + HalMiiDeInitRtl8195a(); +} + + +s32 +HalMiiWriteData( + IN const char *Data, + IN u32 Size +) +{ + return HalMiiWriteDataRtl8195a(Data, Size); +} + + +u32 +HalMiiSendPacket( + IN VOID +) +{ + return HalMiiSendPacketRtl8195a(); +} + + +u32 +HalMiiReceivePacket( + IN VOID +) +{ + return HalMiiReceivePacketRtl8195a(); +} + + +u32 +HalMiiReadData( + IN u8 *Data, + IN u32 Size +) +{ + return HalMiiReadDataRtl8195a(Data, Size); +} + + +VOID +HalMiiGetMacAddress( + IN u8 *Addr +) +{ + HalMiiGetMacAddressRtl8195a(Addr); +} + + +u32 +HalMiiGetLinkStatus( + IN VOID +) +{ + return HalMiiGetLinkStatusRtl8195a(); +} + + +VOID +HalMiiForceLink( + IN s32 Speed, + IN s32 Duplex +) +{ + HalMiiForceLinkRtl8195a(Speed, Duplex); +} + + +#ifdef CONFIG_MII_VERIFY +VOID +HalMiiOpInit( + IN VOID *Data +) +{ + PHAL_MII_OP pHalMiiOp = (PHAL_MII_OP) Data; + + + pHalMiiOp->HalMiiGmacInit = HalMiiGmacInitRtl8195a; + pHalMiiOp->HalMiiGmacReset = HalMiiGmacResetRtl8195a; + pHalMiiOp->HalMiiGmacEnablePhyMode = HalMiiGmacEnablePhyModeRtl8195a; + pHalMiiOp->HalMiiGmacXmit = HalMiiGmacXmitRtl8195a; + pHalMiiOp->HalMiiGmacCleanTxRing = HalMiiGmacCleanTxRingRtl8195a; + pHalMiiOp->HalMiiGmacFillTxInfo = HalMiiGmacFillTxInfoRtl8195a; + pHalMiiOp->HalMiiGmacFillRxInfo = HalMiiGmacFillRxInfoRtl8195a; + pHalMiiOp->HalMiiGmacTx = HalMiiGmacTxRtl8195a; + pHalMiiOp->HalMiiGmacRx = HalMiiGmacRxRtl8195a; + pHalMiiOp->HalMiiGmacSetDefaultEthIoCmd = HalMiiGmacSetDefaultEthIoCmdRtl8195a; + pHalMiiOp->HalMiiGmacInitIrq = HalMiiGmacInitIrqRtl8195a; + pHalMiiOp->HalMiiGmacGetInterruptStatus = HalMiiGmacGetInterruptStatusRtl8195a; + pHalMiiOp->HalMiiGmacClearInterruptStatus = HalMiiGmacClearInterruptStatusRtl8195a; +} +#endif // #ifdef CONFIG_MII_VERIFY + +#endif // #ifdef CONFIG_MII_EN + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_misc.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_misc.c new file mode 100644 index 0000000..dc26766 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_misc.c @@ -0,0 +1,69 @@ +/* + * hal_misc.c + * + * Created on: 08/10/2016 + * Author: pvvx +*/ +#include "rtl8195a.h" + +//------------------------------------------------------------------------- +// Function declarations +/* +void HalReInitPlatformTimer(void); +void HalSetResetCause(IN HAL_RESET_REASON reason); +HAL_RESET_REASON HalGetResetCause(void); +*/ +// void HalTimerOpInit_Patch(IN void *Data); // in hal_timer.h +//------------------------------------------------------------------------- +// Data declarations +// extern HAL_TIMER_OP HalTimerOp; // This variable declared in ROM code (in hal_timer.h ) + + +//----- HalReInitPlatformTimer +void HalReInitPlatformTimer(void) +{ + TIMER_ADAPTER TimerAdapter; + HAL_PERI_ON_WRITE32(REG_OSC32K_CTRL, HAL_PERI_ON_READ32(REG_OSC32K_CTRL) | BIT_32K_POW_CKGEN_EN); // 40000270 |= 1 + HAL_PERI_ON_WRITE32(REG_SOC_FUNC_EN, HAL_PERI_ON_READ32(REG_SOC_FUNC_EN) | BIT_SOC_GTIMER_EN); // 40000210 |= 0x10000 + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_ACTCK_TIMER_EN); // 40000230 |= 0x4000 + HAL_PERI_ON_WRITE32(REG_PESOC_CLK_CTRL, HAL_PERI_ON_READ32(REG_PESOC_CLK_CTRL) | BIT_SOC_SLPCK_TIMER_EN); // 40000230 |= 0x8000 + HAL_PERI_ON_WRITE32(REG_PON_ISO_CTRL, HAL_PERI_ON_READ32(REG_PON_ISO_CTRL) & (~BIT_ISO_OSC32K_EN)); // 40000204 &= 0xFFFFFFEF + TimerAdapter.TimerIrqPriority = 0; + TimerAdapter.TimerLoadValueUs = 0; + TimerAdapter.TimerMode = FREE_RUN_MODE; + TimerAdapter.IrqDis = 1; + TimerAdapter.TimerId = 1; + HalTimerOpInit_Patch(&HalTimerOp); + HAL_TIMER_OP x; + HalTimerOp.HalTimerInit(&TimerAdapter); + HalTimerOp.HalTimerEn(1); +} + +//----- HalSetResetCause +void HalSetResetCause(HAL_RESET_REASON reason) +{ + HAL_PERI_ON_WRITE32(REG_SYS_DSLP_TIM_CTRL, HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) | BIT31); // 40000094 |= 0x80000000 + HAL_PERI_ON_WRITE32(REG_SYS_DSLP_TIM_CTRL, (HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x9700 | (reason & 0xff)); // 40000094 = (40000094 >> 16 << 16) | 0x9700 | (u8)reason; + while(HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) & 0x8000); +} + +//----- HalGetResetCause +HAL_RESET_REASON HalGetResetCause(void) +{ + HAL_PERI_ON_WRITE32(REG_SYS_DSLP_TIM_CTRL, HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) | BIT31); // 40000094 |= 0x80000000 + HAL_PERI_ON_WRITE32(REG_SYS_DSLP_TIM_CTRL, (HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) & 0xFFFF00FF) | 0x8700); // 40000094 = 40000094 & 0xFFFF00FF | 0x8700 + while(HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL) & 0x8000); + return HAL_PERI_ON_READ32(REG_SYS_DSLP_TIM_CTRL); +} + +u8 HalGetChipId(void) { + u8 chip_id = CHIP_ID_8195AM; +#if CONFIG_DEBUG_LOG > 3 + if (HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xF8, &chip_id, L25EOUTVOLTAGE) != 1) + DBG_MISC_INFO("Get Chip ID Failed\r"); +#else + HALEFUSEOneByteReadROM(HAL_SYS_CTRL_READ32(REG_SYS_EFUSE_CTRL), 0xF8, &chip_id, L25EOUTVOLTAGE); +#endif + return chip_id; +} + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_nfc.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_nfc.c new file mode 100644 index 0000000..324b57e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_nfc.c @@ -0,0 +1,23 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "hal_nfc.h" + +#ifdef CONFIG_NFC_EN + +VOID HalNFCOpInit( + IN VOID *Data +) +{ + +} + +#endif //CONFIG_NFC_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_pcm.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pcm.c new file mode 100644 index 0000000..e3a09e6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pcm.c @@ -0,0 +1,31 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "platform_autoconf.h" +#include "hal_pcm.h" + +#ifdef CONFIG_PCM_EN + +VOID HalPcmOpInit( + IN VOID *Data +) +{ + PHAL_PCM_OP pHalPcmOp = (PHAL_PCM_OP) Data; + + pHalPcmOp->HalPcmOnOff = HalPcmOnOffRtl8195a; + pHalPcmOp->HalPcmInit = HalPcmInitRtl8195a; + pHalPcmOp->HalPcmSetting = HalPcmSettingRtl8195a; + pHalPcmOp->HalPcmEn = HalPcmEnRtl8195a; + pHalPcmOp->HalPcmIsrEnAndDis= HalPcmIsrEnAndDisRtl8195a; + pHalPcmOp->HalPcmDumpReg= HalPcmDumpRegRtl8195a; + pHalPcmOp->HalPcm= HalPcmRtl8195a; +} + +#endif //CONFIG_PCM_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_pinmux.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pinmux.c new file mode 100644 index 0000000..2bcf6cd --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pinmux.c @@ -0,0 +1,140 @@ +/* + * hal_pinmux.c + * + * Created on: 08/10/2016 + * Author: pvvx +*/ +#include "rtl8195a.h" + +//------------------------------------------------------------------------- +// Function declarations +/* +u8 GpioFunctionChk(IN u32 chip_pin, IN u8 Operation); +u32 GpioIcFunChk(IN u32 chip_pin, IN u8 Operation); +u8 FunctionChk(IN u32 Function, IN u32 PinLocation); +u8 RTL8710afFunChk(IN u32 Function, IN u32 PinLocation); +void HalJtagPinOff(); +*/ +// extern _LONG_CALL_ u8 HalPinCtrlRtl8195A(IN u32 Function, IN u32 PinLocation, IN BOOL Operation); +// extern HALEFUSEOneByteReadRAM(); +//------------------------------------------------------------------------- +// Data declarations +extern u16 GPIOState[]; +#define REG_EFUSE_0xF8 0xF8 // [0xF8] = 0xFC RTL8710AF + +#define RTL8710_DEF_PIN_ON 0 + +//----- HalJtagPinOff +void HalJtagPinOff(void) +{ + HalPinCtrlRtl8195A(JTAG, 0, 0); +} + + +#if RTL8710_DEF_PIN_ON + +//----- GpioIcFunChk +u8 GpioIcFunChk(IN u32 chip_pin, IN u8 Operation) +{ + u8 tst, result; + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), REG_EFUSE_0xF8, &tst, L25EOUTVOLTAGE); + + tst += 8; // tst = 0xfc+8 = 0x04 + if ( tst > 7 ) result = 0; + else { + tst = 1 << tst; // v6 = 0x10 + if (tst & 0xEF) result = 1; + else { + result = tst & 0x10; + if(result) { // RTL8710AF ? + if (chip_pin - 1 <= 2) result = 0; // PA_1, PA_2, PA_3 + else { + result = chip_pin - PC_5; // PC_5 + if (chip_pin != PC_5) + result = 1; + } + } + } + } + return result; +} + +#endif // RTL8710_DEF_PIN_ON + +//----- GpioFunctionChk +u8 GpioFunctionChk(IN u32 chip_pin, IN u8 Operation) +{ + u8 result; + u16 tst; + +#if RTL8710_DEF_PIN_ON + result = GpioIcFunChk(chip_pin, Operation); +#else + result = 1; +#endif + if(result) { + result = 1; + tst = 1 << (chip_pin & 0xF); + if (!Operation) { + tst = GPIOState[chip_pin >> 4] & (~tst); + GPIOState[chip_pin >> 4] = tst; + return result; + } + if (!(GPIOState[chip_pin >> 4] & tst)) { + tst |= GPIOState[chip_pin >> 4]; + GPIOState[chip_pin >> 4] = tst; + return result; + } + result = 0; + } + return result; +} + +#if RTL8710_DEF_PIN_ON +//----- RTL8710afFunChk +u8 RTL8710afFunChk(IN u32 Function, IN u32 PinLocation) +{ + u8 result; + if (Function == SPI0_MCS) // SPI0_MCS + return PinLocation - 1 + (PinLocation - 1 <= 0) - (PinLocation - 1); + if (Function > I2C0) { + if (Function == I2S1) goto LABEL_15; + if(Function > I2S1) { + if(Function == JTAG || Function == LOG_UART) return 1; + } + else if(Function == I2C3) goto LABEL_15; + return 0; + } + if(Function == UART2) goto LABEL_15; + if(Function == SPI0) + return PinLocation - 1 + (PinLocation - 1 <= 0) - (PinLocation - 1); + if (Function != UART0) return 0; +LABEL_15: + result = 1 - PinLocation; + if (PinLocation > 1) result = 0; + return result; +} +#endif // RTL8710_DEF_PIN_ON + +//----- FunctionChk +u8 FunctionChk( IN u32 Function, IN u32 PinLocation) +{ +#if RTL8710_DEF_PIN_ON + u8 result, tst; + HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), REG_EFUSE_0xF8, &tst, L25EOUTVOLTAGE); + tst += 8; // tst = 0xfc+8 = 0x04 + if ( tst > 7 ) result = 0; + else { + tst = 1 << tst; // v6 = 0x10 + if (tst & 0xEF) result = 1; + else { + result = tst & 0x10; + if (tst & 0x10) + result = RTL8710afFunChk(Function, PinLocation); + } + } + return result; +#else + return 1; +#endif // RTL8710_DEF_PIN_ON +} diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_pwm.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pwm.c new file mode 100644 index 0000000..147d239 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_pwm.c @@ -0,0 +1,142 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * -------------------------- + * bug fixing: pvvx + */ + + +#include "rtl8195a.h" + +#ifdef CONFIG_PWM_EN +#include "hal_pwm.h" +#include "hal_timer.h" + +const u8 PWMTimerIdx[MAX_PWM_CTRL_PIN]= {3,4,5,2}; // the G-timer ID used for PWM pin 0~3 + +/** + * @brief Initializes and enable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * @param sel: pin mux selection + * + * @retval HAL_Status + */ +HAL_Status +HAL_Pwm_Init( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 pwm_id, + u32 sel +) +{ + u32 timer_id; + + if (NULL == pPwmAdapt) { + DBG_PWM_ERR ("HAL_Pwm_Init: NULL adapter\n"); + return HAL_ERR_PARA; + } + + if ((pwm_id >= MAX_PWM_CTRL_PIN) || (sel > 3)) { + DBG_PWM_ERR ("HAL_Pwm_Init: Invalid PWM index(%d), sel(%d)\n", pwm_id, sel); + return HAL_ERR_PARA; + } + + pPwmAdapt->pwm_id = pwm_id; + pPwmAdapt->sel = sel; + timer_id = PWMTimerIdx[pwm_id]; + pPwmAdapt->gtimer_id = timer_id; +/* + if (_FALSE == FunctionChk((pPwmAdapt->pwm_id + PWM0), pPwmAdapt->sel)) { + DBG_PWM_WARN("HAL_Pwm_Init: Warning for RTL8710AF\n"); + // return HAL_ERR_HW; + } +*/ +#ifndef CONFIG_CHIP_E_CUT + return HAL_Pwm_Init_8195a(pPwmAdapt); +#else + return HAL_Pwm_Init_8195a_V04(pPwmAdapt); +#endif +} + + +/** + * @brief Disable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * + * @retval None + */ +void +HAL_Pwm_Enable( + HAL_PWM_ADAPTER *pPwmAdapt +) +{ + if (NULL == pPwmAdapt) { + DBG_PWM_ERR ("HAL_Pwm_Enable: NULL adapter\n"); + return; + } + +#ifndef CONFIG_CHIP_E_CUT + HAL_Pwm_Enable_8195a(pPwmAdapt); +#else + HAL_Pwm_Enable_8195a_V04(pPwmAdapt); +#endif +} + + +/** + * @brief Disable a PWM control pin. + * + * @param pwm_id: the PWM pin index + * + * @retval None + */ +void +HAL_Pwm_Disable( + HAL_PWM_ADAPTER *pPwmAdapt +) +{ + if (NULL == pPwmAdapt) { + DBG_PWM_ERR ("HAL_Pwm_Disable: NULL adapter\n"); + return; + } + +#ifndef CONFIG_CHIP_E_CUT + HAL_Pwm_Disable_8195a(pPwmAdapt); +#else + HAL_Pwm_Disable_8195a_V04(pPwmAdapt); +#endif +} + +/** + * @brief Set the duty ratio of the PWM pin. + * + * @param pwm_id: the PWM pin index + * @param period: the period time, in micro-second. + * @param pulse_width: the pulse width time, in micro-second. + * + * @retval None + */ +void +HAL_Pwm_SetDuty( + HAL_PWM_ADAPTER *pPwmAdapt, + u32 period, + u32 pulse_width +) +{ + if (NULL == pPwmAdapt) { + DBG_PWM_ERR ("HAL_Pwm_SetDuty: NULL adapter\n"); + return; + } + +#ifndef CONFIG_CHIP_E_CUT + HAL_Pwm_SetDuty_8195a(pPwmAdapt, period, pulse_width); +#else + HAL_Pwm_SetDuty_8195a_V04(pPwmAdapt, period, pulse_width); +#endif +} + + +#endif // end of "#ifdef CONFIG_PWM_EN" diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdio_host.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdio_host.c new file mode 100644 index 0000000..45ba0c6 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdio_host.c @@ -0,0 +1,128 @@ +/* + * hal_sdio_host.c (disasm hal_sdio_host.o) + * + * RTL8710/11 pvvx 12/2016 + */ +#include "rtl8195a.h" +#ifdef CONFIG_SDIO_HOST_EN +#include "sd.h" +#include "sdio_host.h" +#include "hal_sdio_host.h" +#include "rtl8195a_sdio_host.h" +#include "hal_pinmux.h" +//#ifdef RTL8710AF + #include "hal_gpio.h" + #include "PinNames.h" + #include "hal_gpio.h" +//#endif +//------------------------------------------------------------------------- +// Function declarations + +//------------------------------------------------------------------------- +// Data declarations + +//----- HalSdioHostInit(PHAL_SDIO_HOST_ADAPTER) +HAL_Status HalSdioHostInit(IN VOID *Data) { + PHAL_SDIO_HOST_ADAPTER pSdioHostAdapter = (PHAL_SDIO_HOST_ADAPTER) Data; + HAL_Status result; + if (FunctionChk(SDIOH, 0) != 0) { + if (pSdioHostAdapter != NULL) { + if (HalSdioHostInitHostRtl8195a(pSdioHostAdapter) != HAL_OK) { + result = HAL_ERR_HW; + } else { + result = HalSdioHostInitCardRtl8195a(pSdioHostAdapter); + if (result == HAL_OK) { + REG_POWER_STATE RegPwrState; + RegPwrState.FuncIdx = SDIOH; + RegPwrState.PwrState = ACT; + RegPowerState(RegPwrState); + } + } + } else + result = HAL_ERR_PARA; + } else + result = HAL_ERR_UNKNOWN; + return result; +} + +//----- HalSdioHostEnable(PHAL_SDIO_HOST_ADAPTER) +HAL_Status HalSdioHostEnable(void *Data) { +// PHAL_SDIO_HOST_ADAPTER pSdioHostAdapter = (PHAL_SDIO_HOST_ADAPTER) Data; + HAL_Status result = HalSdioHostEnableRtl8195a(Data); + REG_POWER_STATE RegPwrState; + RegPwrState.FuncIdx = SDIOH; + RegPwrState.PwrState = ACT; + if (result == HAL_OK) + RegPowerState(RegPwrState); + return result; +} + +//----- HalSdioHostDeInit(PHAL_SDIO_HOST_ADAPTER) +HAL_Status HalSdioHostDeInit(IN VOID *Data) { + PHAL_SDIO_HOST_ADAPTER pSdioHostAdapter = (PHAL_SDIO_HOST_ADAPTER) Data; + REG_POWER_STATE SdioHostPwrState; + u8 HwState; + HAL_Status result; + SdioHostPwrState.FuncIdx = SDIOH; + SdioHostPwrState.PwrState = ACT; + + QueryRegPwrState(SdioHostPwrState.FuncIdx, &SdioHostPwrState.PwrState, + &HwState); + if (SdioHostPwrState.PwrState & 0xF7) { + HalSdioHostEnable(pSdioHostAdapter); + QueryRegPwrState(SdioHostPwrState.FuncIdx, &SdioHostPwrState.PwrState, + &HwState); + } + if (SdioHostPwrState.PwrState == ACT) { + SdioHostPwrState.PwrState = INACT; + RegPowerState(SdioHostPwrState); + } + if (pSdioHostAdapter != NULL) + result = HalSdioHostDeInitRtl8195a(pSdioHostAdapter); + else + result = HAL_ERR_PARA; + return result; +} + +//----- HalSdioHostDisable(PHAL_SDIO_HOST_ADAPTER) +HAL_Status HalSdioHostDisable(IN VOID *Data) { + HAL_Status result = HalSdioHostDisableRtl8195a(Data); + if (result == HAL_OK) { + REG_POWER_STATE RegPwrState; + RegPwrState.FuncIdx = SDIOH; + RegPwrState.PwrState = SLPCG; + RegPowerState(RegPwrState); // 0x0441 + } + return result; +} + +//----- HalSdioHostOpInit(PHAL_SDIO_HOST_ADAPTER) +void HalSdioHostOpInit(void *Data) { + PHAL_SDIO_HOST_OP phsha = (PHAL_SDIO_HOST_ADAPTER)Data; + phsha->HalSdioHostInitHost = &HalSdioHostInitHostRtl8195a; + phsha->HalSdioHostInitCard = &HalSdioHostInitCardRtl8195a; + phsha->HalSdioHostDeInit = &HalSdioHostDeInitRtl8195a; + phsha->HalSdioHostRegIrq = &HalSdioHostIrqInitRtl8195a; + phsha->HalSdioHostReadBlocksDma = &HalSdioHostReadBlocksDmaRtl8195a; + phsha->HalSdioHostWriteBlocksDma = &HalSdioHostWriteBlocksDmaRtl8195a; + phsha->HalSdioHostStopTransfer = &HalSdioHostStopTransferRtl8195a; + phsha->HalSdioHostGetCardStatus = &HalSdioHostGetCardStatusRtl8195a; + phsha->HalSdioHostGetSdStatus = &HalSdioHostGetSdStatusRtl8195a; + phsha->HalSdioHostChangeSdClock = &HalSdioHostChangeSdClockRtl8195a; + phsha->HalSdioHostErase = &HalSdioHostEraseRtl8195a; + phsha->HalSdioHostGetWriteProtect = &HalSdioHostGetWriteProtectRtl8195a; + phsha->HalSdioHostSetWriteProtect = &HalSdioHostSetWriteProtectRtl8195a; +//#ifdef RTL8710AF + if(HalGetChipId() != CHIP_ID_8195AM) { + GPIOState[0] &= ~((1 << 8) - 1); + { + for (int i = 0; i <= 6; i++) + HAL_GPIO_PullCtrl(i, PullNone); + HAL_GPIO_PullCtrl(PA_6, PullDown); + HAL_GPIO_PullCtrl(PA_7, PullDown); + } + } +//#endif +} + +#endif // CONFIG_SDIO_HOST_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdr_controller.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdr_controller.c new file mode 100644 index 0000000..29a7c8a --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_sdr_controller.c @@ -0,0 +1,1118 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "rtl8195a.h" +#include "platform_opts.h" +#include "hal_sdr_controller.h" +#include "rtl8195a_sdr.h" +#include "flash_api.h" + +#ifdef CONFIG_SDR_EN + +#ifndef USE_SRC_ONLY_BOOT +#define USE_SRC_ONLY_BOOT 0 +#endif + +#if !USE_SRC_ONLY_BOOT +//#define SDRAM_INIT_USE_TCM_HEAP +//#define SDRAM_INIT_USE_FLASH_API +#endif + + +#if 0 +#define HAL_SDR_WRITE32(addr, value32) HAL_WRITE32(SDR_CTRL_BASE, addr, value32) +#define HAL_SDR_WRITE16(addr, value16) HAL_WRITE16(SDR_CTRL_BASE, addr, value16) +#define HAL_SDR_WRITE8(addr, value8) HAL_WRITE8(SDR_CTRL_BASE, addr, value8) +#define HAL_SDR_READ32(addr) HAL_READ32(SDR_CTRL_BASE, addr) +#define HAL_SDR_READ16(addr) HAL_READ16(SDR_CTRL_BASE, addr) +#define HAL_SDR_READ8(addr) HAL_READ8(SDR_CTRL_BASE, addr) + +#define HAL_SDRAM_WRITE32(addr, value32) HAL_WRITE32(SDR_SDRAM_BASE, addr, value32) +#define HAL_SDRAM_WRITE16(addr, value16) HAL_WRITE16(SDR_SDRAM_BASE, addr, value16) +#define HAL_SDRAM_WRITE8(addr, value8) HAL_WRITE8(SDR_SDRAM_BASE, addr, value8) +#define HAL_SDRAM_READ32(addr) HAL_READ32(SDR_SDRAM_BASE, addr) +#define HAL_SDRAM_READ16(addr) HAL_READ16(SDR_SDRAM_BASE, addr) +#define HAL_SDRAM_READ8(addr) HAL_READ8(SDR_SDRAM_BASE, addr) +#endif + +#define DEBUG_SDRAM 2 +//#define CONFIG_SDR_VERIFY + +extern SPIC_INIT_PARA SpicInitParaAllClk[3][CPU_CLK_TYPE_NO]; +extern DRAM_DEVICE_INFO SdrDramInfo; + +/* +HAL_CUT_B_RAM_DATA_SECTION +DRAM_INFO SdrDramDev = { + DRAM_INFO_TYPE, + DRAM_INFO_COL_ADDR_WTH, + DRAM_INFO_BANK_SZ, + DRAM_INFO_DQ_WTH +}; + + +HAL_CUT_B_RAM_DATA_SECTION +DRAM_MODE_REG_INFO SdrDramModeReg = { + BST_LEN_4, + SENQUENTIAL, + 0x3, // Mode0Cas: 3 + 0x0, // Mode0Wr + 0, // Mode1DllEnN + 0, // Mode1AllLat + 0 // Mode2Cwl +}; + +HAL_CUT_B_RAM_DATA_SECTION +DRAM_TIMING_INFO SdrDramTiming = { + DRAM_TIMING_TRFC, // TrfcPs; + DRAM_TIMING_TREFI, // TrefiPs; + DRAM_TIMING_TWRMAXTCK, // WrMaxTck; + DRAM_TIMING_TRCD, // TrcdPs; + DRAM_TIMING_TRP, // TrpPs; + DRAM_TIMING_TRAS, // TrasPs; + DRAM_TIMING_TRRD, // TrrdTck; + DRAM_TIMING_TWR, // TwrPs; + DRAM_TIMING_TWTR, // TwtrTck; + //13090, // TrtpPs; + DRAM_TIMING_TMRD, // TmrdTck; + DRAM_TIMING_TRTP, // TrtpTck; + DRAM_TIMING_TCCD, // TccdTck; + DRAM_TIMING_TRC // TrcPs; +}; + +HAL_CUT_B_RAM_DATA_SECTION +DRAM_DEVICE_INFO SdrDramInfo = { + &SdrDramDev, + &SdrDramModeReg, + &SdrDramTiming, + DRAM_TIMING_TCK, + DFI_RATIO_1 +}; +*/ + +#define FPGA +#define FPGA_TEMP +#define SDR_CLK_DLY_CTRL 0x40000300 +#define MIN_RD_PIPE 0x0 +#define MAX_RD_PIPE 0x7 + +#define DRAM_CALIBRATION_IN_NVM 1 +#ifndef CONFIG_IMAGE_SEPARATE // Store SPIC Calibration only for seprated image +#undef DRAM_CALIBRATION_IN_NVM +#define DRAM_CALIBRATION_IN_NVM 0 +#endif + +#ifdef FPGA +#ifdef FPGA_TEMP +#define MAX_TAP_DLY 0xC +#else +#define MAX_TAP_DLY 0x7F +#define SPEC_MAX_TAP 0xFF +#endif +#else +#define MAX_TAP_DLY 99 // 0~99 +#define SPEC_MAX_TAP 99 +#define WINDOW_COMBIN // combine window [0~a] and [b~99] (for asic mode) +#endif + +#define TAP_DLY 0x1 +#define REC_NUM 512 + + +u32 SdrControllerInit(VOID); +VOID DramInit(DRAM_DEVICE_INFO *); +s32 MemTest(u32 loop_cnt); +u32 SdrCalibration(VOID); +//u32 Sdr_Rand2(VOID); +//#define Sdr_Rand2 Rand + +#ifndef SDRAM_INIT_USE_TCM_HEAP +#if !USE_SRC_ONLY_BOOT +//3 Note: stack overfloat if the arrary is declared in the task +//HAL_CUT_B_RAM_DATA_SECTION +extern u32 AvaWds[2][REC_NUM]; +#endif +#else +typedef struct { + u32 m[2][REC_NUM]; +} sAvaWds, * pAvaWds; +#endif + +#endif // CONFIG_SDR_EN +/* +HAL_CUT_B_RAM_DATA_SECTION +unsigned int rand_x = 123456789; +*/ +#ifdef CONFIG_SDR_EN + +//#pragma arm section code = ".hal.sdrc.text" +#pragma arm section rodata = ".rodata.hal.sdrc" +//, rwdata = ".hal.sdrc.data" +//, zidata = ".hal.sdrc.bss" +//#pragma arm section bss = ".hal.sdrc.bss" + +#ifdef CONFIG_SDR_VERIFY +enum{ + LLT, + TXRPT, + RXBUFF, + TXBUFF, +}; +#define REPORT_OFFSET 0x8000 +#define RAMASK_OFFSET 0x8800 +#define LLT_H_ADDR 0x650 +#define TXREPORT_H_ADDR 0x660 +#define RXBUFF_H_ADDR 0x670 +#define TXBUFF_H_ADDR 0x680 + +#define REG_PKTBUF_DBG_CTRL_8723B 0x0140 + +int +rt_rpt_h_addr(u8 rpt) +{ + u32 r_val, offset; + + if (rpt == LLT){ + offset = LLT_H_ADDR; + } + else if (rpt == TXRPT){ + offset = TXREPORT_H_ADDR; + } + else if (rpt == RXBUFF){ + offset = RXBUFF_H_ADDR; + } + else if (rpt == TXBUFF){ + offset = TXBUFF_H_ADDR; + } + else { + } + + r_val = ((HAL_READ32(WIFI_REG_BASE, REG_PKTBUF_DBG_CTRL_8723B)&0xFFFFF000)|offset); + HAL_WRITE32(WIFI_REG_BASE, REG_PKTBUF_DBG_CTRL_8723B, r_val); +} + + + +int +rt_txrpt_read32(u8 macid, u8 offset) +{ + u32 r_val; + + rt_rpt_h_addr(TXRPT); + r_val = HAL_READ32(WIFI_REG_BASE, (REPORT_OFFSET + macid*4 + offset)); + + return r_val; +} + +int +rt_txrpt_read16(u8 macid, u8 offset) +{ + u16 r_val; + + rt_rpt_h_addr(TXRPT); + r_val = HAL_READ16(WIFI_REG_BASE, (REPORT_OFFSET + macid*8 + offset)); + + return r_val; +} + +int +rt_txrpt_read8(u8 macid, u8 offset) +{ + u8 r_val; + + rt_rpt_h_addr(TXRPT); + r_val = HAL_READ8(WIFI_REG_BASE, (REPORT_OFFSET + macid*16 + offset)); + + return r_val; +} + +int +rt_txrpt_read_1b(u8 macid, u8 offset, u8 bit_offset) +{ + u8 r_val = ((rt_txrpt_read8(macid, offset) & BIT(bit_offset))?1:0); + + return r_val; +} + + +int +rt_txrpt_write32(u8 macid, u8 offset, u32 val) +{ + rt_rpt_h_addr(TXRPT); + HAL_WRITE32(WIFI_REG_BASE, (REPORT_OFFSET + macid*4 + offset), val); +} + +int +rt_txrpt_write16(u8 macid, u8 offset, u16 val) +{ + rt_rpt_h_addr(TXRPT); + HAL_WRITE16(WIFI_REG_BASE, (REPORT_OFFSET + macid*8 + offset), val); +} + +int +rt_txrpt_write8(u8 macid, u8 offset, u8 val) +{ + rt_rpt_h_addr(TXRPT); + DBG_8195A("Write addr %x %x\n", (REPORT_OFFSET + macid*16 + offset), val); + HAL_WRITE8(WIFI_REG_BASE, (REPORT_OFFSET + macid*16 + offset), val); +} + +int +rt_txrpt_write_1b(u8 macid, u8 offset, u8 bit_offset, u8 val) +{ + u8 r_val = rt_txrpt_read8(macid, offset); + + if (val){ + r_val |= BIT(bit_offset); + } + else { + r_val &= (~BIT(bit_offset)); + } + + HAL_WRITE8(WIFI_REG_BASE, (REPORT_OFFSET + macid*16 + offset), r_val); +} + + +u8 +ReadTxrptsdr8( + IN u8 Macid, + IN u8 Offset) +{ + u8 r_val; + + r_val = rt_txrpt_read8(Macid, Offset); + return r_val; +} + +VOID +WriteTxrptsdr8( + IN u8 Macid, + IN u8 Offset, + IN u8 Val) +{ + rt_txrpt_write8(Macid, Offset, Val); +} + +VOID +SdrTestApp( + IN VOID *Data +) +{ + u32 *Cmd =(u32*)Data; + u32 Loop, LoopIndex, Value32, Addr, Loop1, LoopIndex1; + + switch (Cmd[0]) { + case 1: + DBG_8195A("Initial SDR\n"); + + //1 "SdrControllerInit" is located in Image1, so we shouldn't call it in Image2 + if (!SdrControllerInit()) { + DBG_8195A("SDR Calibartion Fail!\n"); + } + break; + case 2: + Loop = Cmd[1]; + Loop1 = Cmd[2]; + DBG_8195A("Verify SDR: Loop = 0x%08x Loop1 = 0x%08x\n",Loop, Loop1); + + for (LoopIndex1=0; LoopIndex1 < Loop1; LoopIndex1++) { + + for (LoopIndex=0; LoopIndex < Loop; LoopIndex++) { + Value32 = Rand2(); + Addr = Rand2(); + Addr &= 0x1FFFFF; + Addr &= (~0x3); + + if (!(LoopIndex & 0xFFFFF)) { + DBG_8195A("Alive: LOOP = 0x%08x, LOOP = 0x%08x\n",LoopIndex1, LoopIndex); + } + + // DBG_8195A("Value: 0x%x; Addr: 0x%x\n", Value32, Addr+SDR_SDRAM_BASE); + HAL_SDRAM_WRITE32(Addr, Value32); + + if (Value32 != HAL_SDRAM_READ32(Addr)) { + DBG_8195A("Loop:%d; Addr: 0x%08x => CheckData error: W: 0x%08x /R:0x%x\n" + ,LoopIndex + ,Addr + ,Value32 + ,HAL_SDRAM_READ32(Addr)); + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO2, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO2)+1); + break; + } + } + } + DBG_8195A("Verify SDR Success\n"); + break; + + case 3: + DBG_8195A("WL read RPT MACID %x\n", Cmd[1]); + { + u8 i =0; + for(i=0;i<16;i++) { + DBG_8195A("WL RPT offset %d = %x\n", i, ReadTxrptsdr8(Cmd[1],i)); + } + } + break; + case 4: + DBG_8195A("WL write RPT MACID %x\n", Cmd[1]); + { + u8 i =0; + for(i=0;i<16;i++) { + WriteTxrptsdr8(Cmd[1],i,Cmd[2]); + //DBG_8195A("WL RPT offset %d = %x\n", i, ReadTxrptsdr8(Cmd[1],i)); + } + } + break; + default: + break; + } + +} + +#endif + +HAL_SDRC_TEXT_SECTION +VOID +SdrCtrlInit( +VOID +){ +// ConfigDebugErr |= _DBG_MISC_; +// DBG_8195A("SDR Ctrl Init\n"); + HAL_SYS_CTRL_WRITE32(REG_SYS_REGU_CTRL0, + ((HAL_SYS_CTRL_READ32(REG_SYS_REGU_CTRL0) & 0xfffff) | BIT_SYS_REGU_LDO25M_ADJ(0x0e))); + + LDO25M_CTRL(ON); +} + +HAL_SDRC_TEXT_SECTION +u32 +SdrControllerInit( +VOID +) +{ +// ConfigDebugErr |= _DBG_MISC_; + DBG_8195A("SDR Controller Init\n"); + + HAL_SYS_CTRL_WRITE32(REG_SYS_REGU_CTRL0, + ((HAL_SYS_CTRL_READ32(REG_SYS_REGU_CTRL0) & 0xfffff) | BIT_SYS_REGU_LDO25M_ADJ(0x03))); + + SRAM_MUX_CFG(0x2); + + SDR_CLK_SEL(SDR_CLOCK_SEL_VALUE); + + HAL_PERI_ON_WRITE32(REG_GPIO_PULL_CTRL4,0); + + ACTCK_SDR_CCTRL(ON); + + SLPCK_SDR_CCTRL(ON); + + PinCtrl(SDR, 0, ON); + + HAL_PERI_ON_WRITE32(REG_GPIO_PULL_CTRL4,0); + + MEM_CTRL_FCTRL(ON); + + HalDelayUs(3000); + + // sdr initialization + DramInit(&SdrDramInfo); + + // sdr calibration + if(!SdrCalibration()) { + return 0; + } + else { + return 1; + } +} + + +HAL_SDRC_TEXT_SECTION +VOID +DramInit ( + IN DRAM_DEVICE_INFO *DramInfo +) +{ + DBG_8195A("%s(%p)\n", __func__, DramInfo); + u32 CsBstLen = 0; // 0:bst_4, 1:bst_8 + u32 CasWr = 0;//, CasWrT; // cas write latency + u32 CasRd = 0, CasRdT = 0, CrlSrt = 0; // cas read latency + u32 AddLat; + u32 DramEmr2 = 0, DramMr0 = 0; + u32 CrTwr, DramMaxWr, DramWr; + u32 CrTrtw = 0, CrTrtwT = 0; + u32 DrmaPeriod; + DRAM_TYPE DdrType; + DRAM_DQ_WIDTH DqWidth; + DRAM_COLADDR_WTH Page; + u32 DfiRate; + volatile struct ms_rxi310_portmap *ms_ctrl_0_map; + ms_ctrl_0_map = (struct ms_rxi310_portmap*) SDR_CTRL_BASE; +// ms_ctrl_0_map = ms_ctrl_0_map; + + DfiRate = 1 << (u32) (DramInfo->DfiRate); + DrmaPeriod = (DramInfo->DdrPeriodPs)*(DfiRate); // according DFI_RATE to setting + + // In PHY, write latency == 3 + DramMaxWr= (DramInfo->Timing->WrMaxTck)/(DfiRate) +1; + DramWr = ((DramInfo->Timing->TwrPs) / DrmaPeriod) +1; + CrTwr = ((DramInfo->Timing->TwrPs) / DrmaPeriod) + 3; + + if (CrTwr < DramMaxWr) { +// CrTwr = CrTwr; + } + else { + CrTwr = DramMaxWr; + } + + if ((DramInfo->Dev->DeviceType) == DRAM_DDR_2) { + DdrType = DRAM_DDR_2; + if (DramInfo->ModeReg->BstLen == BST_LEN_4) { + CsBstLen = 0; //bst_4 + CrTrtwT = 2+2; //4/2+2 + DramMr0 = 0x2; + } + else { // BST_LEN_8 + CsBstLen = 1; // bst_8 + CrTrtwT = 4+2; // 8/2+2 + DramMr0 = 0x3; + } + CasRd = DramInfo->ModeReg->Mode0Cas; + AddLat = DramInfo->ModeReg ->Mode1AllLat; + CasWr = CasRd + AddLat -1; + DramEmr2 = 0; + + DramMr0 =(((DramWr%6)-1) << (PCTL_MR_OP_BFO+1)) | // write_recovery + (0 << PCTL_MR_OP_BFO ) | // dll + (DramInfo->ModeReg->Mode0Cas << PCTL_MR_CAS_BFO ) | + (DramInfo->ModeReg->BstType << PCTL_MR_BT_BFO ) | + DramMr0; + } + else if ((DramInfo->Dev->DeviceType) == DRAM_DDR_3) { + DdrType = DRAM_DDR_3; + if (DramInfo->ModeReg->BstLen == BST_LEN_4) { + CsBstLen = 0; //bst_4 + DramMr0 = 0x2; + } + else { // BST_LEN_8 + CsBstLen = 1; // bst_8 + DramMr0 = 0x0; + } + + CrlSrt = (DramInfo->ModeReg->Mode0Cas >> 1); + if (((DramInfo->ModeReg->Mode0Cas) & 0x1) ) { + CasRdT = CrlSrt+ 12; + } + else { + CasRdT = CrlSrt+ 4; + } + + if (DramInfo->ModeReg->Mode1AllLat == 1) { // CL-1 + AddLat = CasRd -1; + } + else if (DramInfo->ModeReg->Mode1AllLat == 2){ // CL-2 + AddLat = CasRd -2; + } + else { + AddLat = 0; + } + + CasRd = CasRdT + AddLat; + + CasWr = DramInfo->ModeReg->Mode2Cwl + 5 + AddLat; + + DramEmr2 = DramInfo->ModeReg->Mode2Cwl << 3; + + if (DramWr == 16) { + DramWr = 0; + } + else if (DramWr <= 9) { // 5< wr <= 9 + DramWr = DramWr - 4; + } + else { + DramWr = (DramWr + 1) / 2; + } + + DramMr0 =(DramWr << (PCTL_MR_OP_BFO+1) ) | // write_recovery + (0 << PCTL_MR_OP_BFO ) | // dll + ((DramInfo->ModeReg->Mode0Cas >>1 ) << PCTL_MR_CAS_BFO ) | + (DramInfo->ModeReg->BstType << PCTL_MR_BT_BFO ) | + ((DramInfo->ModeReg->Mode0Cas & 0x1) << 2 ) | + DramMr0; + + CrTrtwT = (CasRdT + 6) - CasWr; + + } // ddr2/ddr3 + else if ((DramInfo->Dev->DeviceType) == DRAM_SDR) { + DdrType = DRAM_SDR; + if (DramInfo->ModeReg->BstLen == BST_LEN_4) { + DramMr0 = 2; // bst_4 + CsBstLen = 0; //bst_4 + CasRd = 0x2; + } + else { // BST_LEN_8 + DramMr0 = 3; // bst_8 + CsBstLen = 1; // bst_8 + CasRd = 0x3; + } + + CasWr = 0; + + DramMr0 =(CasRd << PCTL_MR_CAS_BFO) | + (DramInfo->ModeReg->BstType << PCTL_MR_BT_BFO ) | + DramMr0; + + CrTrtwT = 0; // tic: CasRd + rd_rtw + rd_pipe + } // SDR + + + // countting tRTW + if ((CrTrtwT & 0x1)) { + CrTrtw = (CrTrtwT+1) /(DfiRate); + } + else { + CrTrtw = CrTrtwT /(DfiRate); + } + + DqWidth = (DramInfo->Dev->DqWidth); + Page = DramInfo->Dev->ColAddrWth +1; // DQ16 -> memory:byte_unit *2 + if (DqWidth == DRAM_DQ_32) { // paralle dq_16 => Page + 1 + Page = Page +1; + } +#if 1 + + // WRAP_MISC setting + HAL_SDR_WRITE32(REG_SDR_MISC,( + (Page << WRAP_MISC_PAGE_SIZE_BFO) | + (DramInfo->Dev->Bank << WRAP_MISC_BANK_SIZE_BFO) | + (CsBstLen << WRAP_MISC_BST_SIZE_BFO ) | + (DqWidth << WRAP_MISC_DDR_PARAL_BFO) + )); + // PCTL setting + HAL_SDR_WRITE32(REG_SDR_DCR,( + (0x2 << PCTL_DCR_DFI_RATE_BFO) | + (DqWidth << PCTL_DCR_DQ32_BFO ) | + (DdrType << PCTL_DCR_DDR3_BFO ) + )); + + HAL_SDR_WRITE32(REG_SDR_IOCR,( + ((CasRd -4)/(DfiRate) << PCTL_IOCR_TPHY_RD_EN_BFO ) | + (0 << PCTL_IOCR_TPHY_WL_BFO ) | + (((CasWr -3)/(DfiRate)) << PCTL_IOCR_TPHY_WD_BFO ) | + (0 << PCTL_IOCR_RD_PIPE_BFO ) + )); + + if ((DramInfo->Dev->DeviceType) != SDR) { // DDR2/3 + HAL_SDR_WRITE32(REG_SDR_EMR2,DramEmr2); + HAL_SDR_WRITE32(REG_SDR_EMR1,( + (1 << 2 ) | //RTT + (1 << 1 ) | //D.I.C + (DramInfo->ModeReg->Mode1DllEnN ) + )); + } // DDR2/3 + + HAL_SDR_WRITE32(REG_SDR_MR,DramMr0); + + HAL_SDR_WRITE32(REG_SDR_DRR, ( + (0 << PCTL_DRR_REF_DIS_BFO) | + (9 << PCTL_DRR_REF_NUM_BFO) | + ((((DramInfo->Timing->TrefiPs)/DrmaPeriod)+1) << PCTL_DRR_TREF_BFO ) | + ((((DramInfo->Timing->TrfcPs)/DrmaPeriod)+1) << PCTL_DRR_TRFC_BFO ) + )); + + HAL_SDR_WRITE32(REG_SDR_TPR0,( + ((((DramInfo->Timing->TrtpTck)/DfiRate)+1) << PCTL_TPR0_TRTP_BFO) | + (CrTwr << PCTL_TPR0_TWR_BFO ) | + ((((DramInfo->Timing->TrasPs)/DrmaPeriod)+1) << PCTL_TPR0_TRAS_BFO) | + ((((DramInfo->Timing->TrpPs)/DrmaPeriod)+1) << PCTL_TPR0_TRP_BFO ) + )); + + HAL_SDR_WRITE32(REG_SDR_TPR1, ( + (CrTrtw << PCTL_TPR1_TRTW_BFO) | + ((((DramInfo->Timing->TwtrTck)/DfiRate)+3) << PCTL_TPR1_TWTR_BFO) | + ((((DramInfo->Timing->TccdTck)/DfiRate)+1) << PCTL_TPR1_TCCD_BFO) | + ((((DramInfo->Timing->TrcdPs)/DrmaPeriod)+1) << PCTL_TPR1_TRCD_BFO) | + ((((DramInfo->Timing->TrcPs)/DrmaPeriod)+1) << PCTL_TPR1_TRC_BFO ) | + (((DramInfo->Timing->TrrdTck/DfiRate)+1) << PCTL_TPR1_TRRD_BFO) + )); + + HAL_SDR_WRITE32(REG_SDR_TPR2, ( + (DramInfo->Timing->TmrdTck << PCTL_TPR2_TMRD_BFO ) | + (0 << PCTL_TPR2_INIT_NS_EN_BFO ) | + (2 << PCTL_TPR2_INIT_REF_NUM_BFO) + )); + + // set all_mode _idle + HAL_SDR_WRITE32(REG_SDR_CSR,0x700); + + // start to init + HAL_SDR_WRITE32(REG_SDR_CCR,0x01); + while ((HAL_SDR_READ32(REG_SDR_CCR)& 0x1) == 0x0); + + // enter mem_mode + HAL_SDR_WRITE32(REG_SDR_CSR,0x600); +#else + // WRAP_MISC setting + ms_ctrl_0_map->misc = //0x12; + ( + (Page << WRAP_MISC_PAGE_SIZE_BFO) | + (DramInfo->Dev->Bank << WRAP_MISC_BANK_SIZE_BFO) | + (CsBstLen << WRAP_MISC_BST_SIZE_BFO ) | + (DqWidth << WRAP_MISC_DDR_PARAL_BFO) + ); + // PCTL setting + ms_ctrl_0_map->dcr = //0x208; + ( + (0x2 << PCTL_DCR_DFI_RATE_BFO) | + (DqWidth << PCTL_DCR_DQ32_BFO ) | + (DdrType << PCTL_DCR_DDR3_BFO ) + ); + + ms_ctrl_0_map->iocr = ( + ((CasRd -4)/(DfiRate) << PCTL_IOCR_TPHY_RD_EN_BFO ) | + (0 << PCTL_IOCR_TPHY_WL_BFO ) | + (((CasWr -3)/(DfiRate)) << PCTL_IOCR_TPHY_WD_BFO ) | + (0 << PCTL_IOCR_RD_PIPE_BFO ) + ); + + if ((DramInfo->Dev->DeviceType) != SDR) { // DDR2/3 + ms_ctrl_0_map->emr2 = DramEmr2; + + ms_ctrl_0_map->emr1 = ( + (1 << 2 ) | //RTT + (1 << 1 ) | //D.I.C + (DramInfo->ModeReg->Mode1DllEnN ) + ); + } // DDR2/3 + + ms_ctrl_0_map->mr = DramMr0; + + ms_ctrl_0_map->drr = ( + (0 << PCTL_DRR_REF_DIS_BFO) | + (9 << PCTL_DRR_REF_NUM_BFO) | + ((((DramInfo->Timing->TrefiPs)/DrmaPeriod)+1)<< PCTL_DRR_TREF_BFO ) | + ((((DramInfo->Timing->TrfcPs)/DrmaPeriod)+1) << PCTL_DRR_TRFC_BFO ) + ); + + ms_ctrl_0_map->tpr0= ( + ((((DramInfo->Timing->TrtpTck)/DfiRate)+1) << PCTL_TPR0_TRTP_BFO) | + (CrTwr << PCTL_TPR0_TWR_BFO ) | + ((((DramInfo->Timing->TrasPs)/DrmaPeriod)+1) << PCTL_TPR0_TRAS_BFO) | + ((((DramInfo->Timing->TrpPs)/DrmaPeriod)+1) << PCTL_TPR0_TRP_BFO ) + ); + + ms_ctrl_0_map->tpr1= ( + (CrTrtw << PCTL_TPR1_TRTW_BFO) | + ((((DramInfo->Timing->TwtrTck)/DfiRate)+3) << PCTL_TPR1_TWTR_BFO) | + ((((DramInfo->Timing->TccdTck)/DfiRate)+1) << PCTL_TPR1_TCCD_BFO) | + ((((DramInfo->Timing->TrcdPs)/DrmaPeriod)+1) << PCTL_TPR1_TRCD_BFO) | + ((((DramInfo->Timing->TrcPs)/DrmaPeriod)+1) << PCTL_TPR1_TRC_BFO ) | + (((DramInfo->Timing->TrrdTck/DfiRate)+1) << PCTL_TPR1_TRRD_BFO) + ); + + ms_ctrl_0_map->tpr2= ( + (DramInfo->Timing->TmrdTck << PCTL_TPR2_TMRD_BFO ) | + (0 << PCTL_TPR2_INIT_NS_EN_BFO ) | + (2 << PCTL_TPR2_INIT_REF_NUM_BFO) + ); + // set all_mode _idle + ms_ctrl_0_map->csr = 0x700; + + // start to init + ms_ctrl_0_map->ccr = 0x1; + while (((ms_ctrl_0_map->ccr)& 0x1) == 0x0); + + // enter mem_mode + ms_ctrl_0_map->csr= 0x600; +#endif +} // DramInit + + //3 +extern void * +_memset( void *s, int c, SIZE_T n ); + +HAL_SDRC_TEXT_SECTION +u32 +SdrCalibration( + VOID +) +{ +#ifdef FPGA +#ifdef FPGA_TEMP +// u32 Value32; +#endif +#else +// u32 Value32; +#endif + DBG_8195A("%s()\n", __func__); + u32 RdPipe = 0, TapCnt = 0, Pass = 0, AvaWdsCnt = 0; + u32 RdPipeCounter, RecNum[2], RecRdPipe[2];//, AvaWds[2][REC_NUM]; + BOOL RdPipeFlag, PassFlag = 0, Result; + u8 flashtype = 0; + + flashtype = SpicInitParaAllClk[0][0].flashtype; + + Result = _FALSE; + +#if DRAM_CALIBRATION_IN_NVM + // read calibration data from system data 0x5d~0x6c + SPIC_INIT_PARA SpicInitPara; + u32 valid; + union { u8 b[4]; u32 l;} value; +//// +#ifdef SDRAM_INIT_USE_FLASH_API + flash_turnon(); + if(fspic_isinit == 0) flash_init(&flashobj); +#endif +//// + + u32 CpuType = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70)) >> 4); + + valid = RdPipe = TapCnt = 0xFFFFFFFF; + value.l = HAL_READ32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType); + if((value.b[0]^value.b[1])==0xFF) + valid = value.b[0]; +#if DEBUG_SDRAM > 1 + DiagPrintf("dump1 %x, %x %x %x %x \n\r", value.l, value.b[0], value.b[1], value.b[2], value.b[3]); +#endif + value.l = HAL_READ32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType+4); + if((value.b[0]^value.b[1])==0xFF) + RdPipe = value.b[0]; + if((value.b[2]^value.b[3])==0xFF) + TapCnt = value.b[2]; +#if DEBUG_SDRAM > 1 + DiagPrintf("dump2 %x, %x %x %x %x \n\r", value.l, value.b[0], value.b[1], value.b[2], value.b[3]); +#endif + if((valid==1)&&(RdPipe!=0xFFFFFFFF)&&(TapCnt!=0xFFFFFFFF)){ + // wait DRAM settle down + HalDelayUs(10); + // load previous dram calibration data + HAL_SDR_WRITE32(REG_SDR_IOCR, ((HAL_SDR_READ32(REG_SDR_IOCR) & 0xff) | (RdPipe << PCTL_IOCR_RD_PIPE_BFO))); + SDR_DDL_FCTRL(TapCnt); + if(MemTest(3)) + return _TRUE; + } +#endif + +#if !USE_SRC_ONLY_BOOT +#ifdef SDRAM_INIT_USE_TCM_HEAP + pAvaWds AvaWds = (pAvaWds) tcm_heap_calloc(sizeof(u32)*REC_NUM*2); +#else + _memset((u8*)AvaWds, 0, sizeof(AvaWds)); +#endif +#else + u32 AvaWds[2][REC_NUM]; + _memset((u8*)AvaWds, 0, sizeof(u32)*REC_NUM*2); +#endif + + volatile struct ms_rxi310_portmap *ms_ctrl_0_map; + ms_ctrl_0_map = (struct ms_rxi310_portmap*) SDR_CTRL_BASE; +// ms_ctrl_0_map = ms_ctrl_0_map; +// PassFlag = PassFlag; + RdPipeCounter =0; + +// DBG_8195A("%d\n",__LINE__); + + for(RdPipe=MIN_RD_PIPE; RdPipe<=MAX_RD_PIPE; RdPipe++) { +// ms_ctrl_0_map->iocr = (ms_ctrl_0_map->iocr & 0xff) | (RdPipe << PCTL_IOCR_RD_PIPE_BFO); + HAL_SDR_WRITE32(REG_SDR_IOCR, ((HAL_SDR_READ32(REG_SDR_IOCR) & 0xff) | (RdPipe << PCTL_IOCR_RD_PIPE_BFO))); + + DBG_SDR_INFO("IOCR: 0x%x; Write: 0x%x\n", HAL_SDR_READ32(REG_SDR_IOCR), (RdPipe << PCTL_IOCR_RD_PIPE_BFO)); +#if DEBUG_SDRAM > 1 + DBG_8195A("IOCR: 0x%x; Write: 0x%x\n",ms_ctrl_0_map->iocr, (RdPipe << PCTL_IOCR_RD_PIPE_BFO)); +#endif + + RdPipeFlag = _FALSE; + PassFlag = _FALSE; + AvaWdsCnt = 0; + + for(TapCnt=0; TapCnt < (MAX_TAP_DLY+1); TapCnt++) { + // Modify clk delay +#ifdef FPGA +#ifdef FPGA_TEMP + SDR_DDL_FCTRL(TapCnt); +// Value32 = (RD_DATA(SDR_CLK_DLY_CTRL) & 0xFF00FFFF); +// Value32 = (Value32 | (TapCnt << 16)); +// WR_DATA(SDR_CLK_DLY_CTRL, Value32); +#else + HAL_SDR_WRITE32(REG_SDR_DLY0, TapCnt); +// ms_ctrl_0_map->phy_dly0 = TapCnt; +#endif + DBG_SDR_INFO("DLY: 0x%x; Write: 0x%x\n", HAL_PERI_ON_READ32(REG_PESOC_MEM_CTRL), TapCnt); +#else + SDR_DDL_FCTRL(TapCnt); +// Value32 = (RD_DATA(SDR_CLK_DLY_CTRL) & 0xFF00FFFF); +// Value32 = (Value32 | (TapCnt << 16)); +// WR_DATA(SDR_CLK_DLY_CTRL, Value32); +#endif + + Pass = MemTest(10000); + PassFlag = _FALSE; + + if(Pass==_TRUE) { // PASS + + if (!RdPipeFlag) { + DBG_SDR_INFO("%d Time Pass\n", RdPipeCounter); + RdPipeCounter++; + RdPipeFlag = _TRUE; + RecRdPipe[RdPipeCounter - 1] = RdPipe; + } +#ifdef SDRAM_INIT_USE_TCM_HEAP + AvaWds->m[RdPipeCounter-1][AvaWdsCnt] = TapCnt; +#else + AvaWds[RdPipeCounter-1][AvaWdsCnt] = TapCnt; +#endif + AvaWdsCnt++; + + RecNum[RdPipeCounter-1] = AvaWdsCnt; + + if((TapCnt+TAP_DLY)>=MAX_TAP_DLY) { + break; + } + + PassFlag = _TRUE; + + DBG_SDR_INFO("Verify Pass => RdPipe:%d; TapCnt: %d\n", RdPipe, TapCnt); + + } + else { // FAIL +// if(PassFlag==_TRUE) { +// break; +// } +// else { + if (RdPipeCounter > 0) { + RdPipeCounter++; + if (RdPipeCounter < 3) { + RecNum[RdPipeCounter-1] = 0; + RecRdPipe[RdPipeCounter - 1] = RdPipe; + } + break; + } +// } + } + } // for TapCnt + + + if (RdPipeCounter > 2) { + u8 BestRangeIndex, BestIndex; + +#ifdef CONFIG_SDR_VERIFY //to reduce log + u32 i; + DBG_SDR_INFO("Avaliable RdPipe 0\n"); + + for (i=0;i<256;i++) { + DBG_SDR_INFO("%d\n", AvaWds[0][i]); + } + DBG_SDR_INFO("Avaliable RdPipe 1\n"); + for (i=0;i<256;i++) { + DBG_SDR_INFO("%d\n", AvaWds[1][i]); + } +#endif + + DBG_SDR_INFO("Rec 0 => total counter %d; RdPipe:%d;\n", RecNum[0], RecRdPipe[0]); + DBG_SDR_INFO("Rec 1 => total counter %d; RdPipe:%d;\n", RecNum[1], RecRdPipe[1]); + + BestRangeIndex = (RecNum[0] > RecNum[1]) ? 0 : 1; + + BestIndex = RecNum[BestRangeIndex]>>1; +#ifdef SDRAM_INIT_USE_TCM_HEAP + DBG_SDR_INFO("The Finial RdPipe: %d; TpCnt: 0x%x\n", RecRdPipe[BestRangeIndex], AvaWds->m[BestRangeIndex][BestIndex]); +#else + DBG_SDR_INFO("The Finial RdPipe: %d; TpCnt: 0x%x\n", RecRdPipe[BestRangeIndex], AvaWds[BestRangeIndex][BestIndex]); +#endif + // set RdPipe and tap_dly +// ms_ctrl_0_map->iocr = (ms_ctrl_0_map->iocr & 0xff) | (RecRdPipe[BestRangeIndex] << PCTL_IOCR_RD_PIPE_BFO); + HAL_SDR_WRITE32(REG_SDR_IOCR, ((HAL_SDR_READ32(REG_SDR_IOCR) & 0xff) | (RecRdPipe[BestRangeIndex] << PCTL_IOCR_RD_PIPE_BFO))); + +#ifdef FPGA +#ifdef FPGA_TEMP +#ifdef SDRAM_INIT_USE_TCM_HEAP + SDR_DDL_FCTRL(AvaWds->m[BestRangeIndex][BestIndex]); +#else + SDR_DDL_FCTRL(AvaWds[BestRangeIndex][BestIndex]); +#endif + +// Value32 = (RD_DATA(SDR_CLK_DLY_CTRL) & 0xFF00FFFF); +// Value32 = Value32 | (AvaWds[BestRangeIndex][BestIndex] << 16); +// WR_DATA(SDR_CLK_DLY_CTRL, Value32); +#else + HAL_SDR_WRITE32(REG_SDR_DLY0, AvaWds[BestRangeIndex][BestIndex]); +// ms_ctrl_0_map->phy_dly0 = AvaWds[BestRangeIndex][BestIndex]; +#endif +#else + SDR_DDL_FCTRL(AvaWds[BestRangeIndex][BestIndex]); +// Value32 = (RD_DATA(SDR_CLK_DLY_CTRL) & 0xFF00FFFF); +// Value32 = Value32 | (AvaWds[BestRangeIndex][BestIndex] << 16); +// WR_DATA(SDR_CLK_DLY_CTRL, Value32); +#endif + #if DRAM_CALIBRATION_IN_NVM + RdPipe = RecRdPipe[BestRangeIndex]; +#ifdef SDRAM_INIT_USE_TCM_HEAP + TapCnt = AvaWds->m[BestRangeIndex][BestIndex]; +#else + TapCnt = AvaWds[BestRangeIndex][BestIndex]; +#endif + + value.b[0] = (u8)RdPipe; + value.b[1] = ~value.b[0]; + value.b[2] = (u8)TapCnt; + value.b[3] = ~value.b[2]; +#if DEBUG_SDRAM > 1 + DiagPrintf("dump1w %x, %x %x %x %x \n\r", value.l, value.b[0], value.b[1], value.b[2], value.b[3]); +#endif + if( HAL_READ32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType+4) == 0xFFFFFFFF) + { + HAL_WRITE32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType+4, value.l); + if(flashtype == FLASH_MICRON){ + SpicWaitOperationDoneRtl8195A(SpicInitPara); + } + else + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + } + + valid = 1; + value.b[0] = (u8)valid; + value.b[1] = ~value.b[0]; + value.b[2] = 0xFF; + value.b[3] = 0xFF; +#if DEBUG_SDRAM > 1 + DiagPrintf("dump1w %x, %x %x %x %x \n\r", value.l, value.b[0], value.b[1], value.b[2], value.b[3]); +#endif + if( HAL_READ32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType) == 0xFFFFFFFF ) + { + HAL_WRITE32(SPI_FLASH_BASE, FLASH_SDRC_PARA_BASE+8*CpuType, value.l); + if(flashtype == FLASH_MICRON){ + SpicWaitOperationDoneRtl8195A(SpicInitPara); + } + else + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + } + #endif + Result = _TRUE; + break; + } + + if (RdPipeCounter == 0) { + + DBG_SDR_INFO("NOT Find RdPipe\n"); + } + } + +#ifdef SDRAM_INIT_USE_TCM_HEAP + tcm_heap_free(AvaWds); +#endif + return Result; +} // SdrCalibration + +// HAL_RAM_DATA_SECTION +/* + +HAL_SDRC_TEXT_SECTION +VOID +ChangeRandSeed( + IN u32 Seed +) +{ + rand_x = Seed; +} + +HAL_SDRC_TEXT_SECTION +u32 +Sdr_Rand2( + VOID +) +{ + HAL_RAM_DATA_SECTION static unsigned int y = 362436; + + HAL_RAM_DATA_SECTION static unsigned int z = 521288629; + + HAL_RAM_DATA_SECTION static unsigned int c = 7654321; + + unsigned long long t, a= 698769069; + + rand_x = 69069 * rand_x + 12345; + y ^= (y << 13); y ^= (y >> 17); y ^= (y << 5); + t = a * z + c; c = (t >> 32); z = t; + + return rand_x + y + z; +} + +*/ + +HAL_SDRC_TEXT_SECTION +s32 +MemTest( + u32 LoopCnt +) +{ + u32 LoopIndex = 0; + u32 Value32, Addr; + for (LoopIndex = 0; LoopIndex 0x%x != 0x%x\n",LoopIndex, + Addr, Value32, HAL_SDRAM_READ32(Addr)); + return _FALSE; + } + else { + // HAL_SDRAM_WRITE32(Addr, 0); + } + } + return _TRUE; + +} // MemTest + +//#if defined ( __ICCARM__ ) +u8 IsSdrPowerOn( + VOID +) +{ + if ( HAL_READ32(PERI_ON_BASE, REG_SOC_FUNC_EN) & BIT(21) ) { + return 0; + } else { + return 1; + } +} +//#endif + +#else // ifndef CONFIG_SDR_EN + +HAL_SDRC_TEXT_SECTION VOID SdrPowerOff( + VOID +) +{ + SDR_PIN_FCTRL(OFF); + LDO25M_CTRL(OFF); + HAL_WRITE32(PERI_ON_BASE, REG_SOC_FUNC_EN, HAL_READ32(PERI_ON_BASE, REG_SOC_FUNC_EN) | BIT(21)); +} + + +HAL_SDRC_TEXT_SECTION VOID SdrCtrlInit(VOID) +{ + DBG_SDR_ERR("No SDRAM!\n"); + SdrPowerOff(); +} + +HAL_SDRC_TEXT_SECTION u32 SdrControllerInit( VOID) +{ + DBG_SDR_ERR("No SDRAM!\n"); + SdrPowerOff(); + return 1; +} +#endif // end of "#ifdef CONFIG_SDR_EN" + + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_soc_ps_monitor.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_soc_ps_monitor.c new file mode 100644 index 0000000..cd42785 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_soc_ps_monitor.c @@ -0,0 +1,3481 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "rtl8195a.h" +#include "hal_soc_ps_monitor.h" +#include "rtl_consol.h" + +#include "PinNames.h" +#include "gpio_api.h" + + +#ifdef CONFIG_SOC_PS_MODULE +extern VOID UartLogIrqHandleRam(VOID * Data); +#if defined (__ICCARM__) +extern void xPortPendSVHandler( void ); +#elif defined (__GNUC__) +extern void xPortPendSVHandler( void ) __attribute__ (( naked )); +#endif +extern void xPortSysTickHandler( void ); +extern void vPortSVCHandler( void ); +//extern unsigned int HalGetCpuClk(void); +//extern _LONG_CALL_ u32 HalDelayUs(u32 us); + +extern COMMAND_TABLE UartLogRomCmdTable[]; +extern HAL_TIMER_OP HalTimerOp; +extern u32 STACK_TOP; // which is defined in vectors.s + +SYS_ADAPTER SYSAdapte; + +Power_Mgn PwrAdapter; + +VOID ReFillCpuClk(VOID); +extern u8 __ram_start_table_start__[]; + +u32 +PatchHalLogUartInit( + IN LOG_UART_ADAPTER UartAdapter +) +{ + u32 SetData; + u32 Divisor; + u32 Dlh; + u32 Dll; + + /* + Interrupt enable Register + 7: THRE Interrupt Mode Enable + 2: Enable Receiver Line Status Interrupt + 1: Enable Transmit Holding Register Empty Interrupt + 0: Enable Received Data Available Interrupt + */ + // disable all interrupts + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, 0); + + /* + Line Control Register + 7: DLAB, enable reading and writing DLL and DLH register, and must be cleared after + initial baud rate setup + 3: PEN, parity enable/disable + 2: STOP, stop bit + 1:0 DLS, data length + */ + + + // set up buad rate division + +#ifdef CONFIG_FPGA + Divisor = (SYSTEM_CLK / (16 * (UartAdapter.BaudRate))); +#else + { + Divisor = HalGetCpuClk()/(32 * UartAdapter.BaudRate); + Divisor = (Divisor & 1) + (Divisor >> 1); + } +#endif + + // set DLAB bit to 1 + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 0x80); + + Dll = Divisor & 0xff; + Dlh = (Divisor & 0xff00)>>8; + + HAL_UART_WRITE32(UART_DLL_OFF, Dll); + HAL_UART_WRITE32(UART_DLH_OFF, Dlh); + // clear DLAB bit +// HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, 0); // есть далее + + // set data format + SetData = UartAdapter.Parity | UartAdapter.Stop | UartAdapter.DataLength; + HAL_UART_WRITE32(UART_LINE_CTL_REG_OFF, SetData); + + /* FIFO Control Register + 7:6 level of receive data available interrupt + 5:4 level of TX empty trigger + 2 XMIT FIFO reset + 1 RCVR FIFO reset + 0 FIFO enable/disable + */ + // FIFO setting, enable FIFO and set trigger level (2 less than full when receive + // and empty when transfer + HAL_UART_WRITE32(UART_FIFO_CTL_REG_OFF, UartAdapter.FIFOControl); + + /* + Interrupt Enable Register + 7: THRE Interrupt Mode enable + 2: Enable Receiver Line status Interrupt + 1: Enable Transmit Holding register empty INT32 + 0: Enable received data available interrupt + */ + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, UartAdapter.IntEnReg); + + if (UartAdapter.IntEnReg) { + // Enable Peripheral_IRQ Setting for Log_Uart + HAL_WRITE32(VENDOR_REG_BASE, PERIPHERAL_IRQ_EN, 0x1000000); + + // Enable ARM Cortex-M3 IRQ + NVIC_SetPriorityGrouping(0x3); + NVIC_SetPriority(PERIPHERAL_IRQ, 14); + NVIC_EnableIRQ(PERIPHERAL_IRQ); + } + return 0; +} + +//_LONG_CALL_ extern VOID UartLogIrqHandle(VOID * Data); // in ROM +extern void UartLogIrqHandleRam(void * data); +VOID +PSHalInitPlatformLogUart( + VOID +) +{ + IRQ_HANDLE UartIrqHandle; + LOG_UART_ADAPTER UartAdapter; + + //4 Release log uart reset and clock + LOC_UART_FCTRL(OFF); + LOC_UART_FCTRL(ON); + ACTCK_LOG_UART_CCTRL(ON); + + PinCtrl(LOG_UART,S0,ON); + + //4 Register Log Uart Callback function + UartIrqHandle.Data = (u32)NULL; //(u32)&UartAdapter; + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) UartLogIrqHandleRam; + UartIrqHandle.Priority = 0; + + //4 Inital Log uart + UartAdapter.BaudRate = DEFAULT_BAUDRATE; + UartAdapter.DataLength = UART_DATA_LEN_8BIT; + UartAdapter.FIFOControl = 0xC1; + UartAdapter.IntEnReg = 0x00; + UartAdapter.Parity = UART_PARITY_DISABLE; + UartAdapter.Stop = UART_STOP_1BIT; + + //4 Initial Log Uart + PatchHalLogUartInit(UartAdapter); + + //4 Register Isr handle + InterruptRegister(&UartIrqHandle); + + UartAdapter.IntEnReg = 0x05; + + //4 Initial Log Uart for Interrupt +// PatchHalLogUartInit(UartAdapter); + /* + Interrupt Enable Register + 7: THRE Interrupt Mode enable + 2: Enable Receiver Line status Interrupt + 1: Enable Transmit Holding register empty INT32 + 0: Enable received data available interrupt + */ + HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, UartAdapter.IntEnReg); + // Enable Peripheral_IRQ Setting for Log_Uart + HAL_WRITE32(VENDOR_REG_BASE, PERIPHERAL_IRQ_EN, 0x1000000); + // Enable ARM Cortex-M3 IRQ + NVIC_SetPriorityGrouping(0x3); + NVIC_SetPriority(PERIPHERAL_IRQ, 14); + NVIC_EnableIRQ(PERIPHERAL_IRQ); + + //4 initial uart log parameters before any uartlog operation + //RtlConsolInit(ROM_STAGE,GetRomCmdNum(),(VOID*)&UartLogRomCmdTable);// executing boot seq., + //pUartLogCtl->TaskRdy = 1; +} + + +#ifdef CONFIG_SDR_EN +VOID +SDRWakeUp( + VOID +){ + ACTCK_SDR_CCTRL(ON); + SDR_PIN_FCTRL(ON); + HalDelayUs(10); + HAL_WRITE32(0x40005000, 0x34, 0x3); + HAL_WRITE32(0x40005000, 0x10, HAL_READ32(0x40005000, 0x10)&(~BIT28)); +} + +VOID +SDRSleep( + VOID +){ + gpio_t gpio_obj; + + HAL_WRITE32(0x40005000, 0X10, HAL_READ32(0x40005000, 0x10)|BIT28); + ACTCK_SDR_CCTRL(OFF); + gpio_init(&gpio_obj, PG_1); + gpio_mode(&gpio_obj, PullUp); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_HIGH); + + gpio_init(&gpio_obj, PG_2); + gpio_mode(&gpio_obj, PullDown); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); + + gpio_init(&gpio_obj, PG_3); + gpio_mode(&gpio_obj, PullDown); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); + + gpio_init(&gpio_obj, PG_4); + gpio_mode(&gpio_obj, PullDown); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); + + gpio_init(&gpio_obj, PJ_1); + gpio_mode(&gpio_obj, PullDown); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); + + gpio_init(&gpio_obj, PJ_2); + gpio_mode(&gpio_obj, PullDown); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); + + SDR_PIN_FCTRL(OFF); + HAL_WRITE32(0x40005000, 0x34, 0x1); + gpio_init(&gpio_obj, PJ_1); + gpio_mode(&gpio_obj, PullUp); + gpio_dir(&gpio_obj, PIN_OUTPUT); + gpio_write(&gpio_obj, GPIO_PIN_LOW); +} +#endif + +VOID +SYSIrqHandle +( + IN VOID *Data +) +{ + u32 Rtemp; + + //change cpu clk + ReFillCpuClk(); + HalDelayUs(100); + + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) | BIT_SYS_PWRON_TRAP_SHTDN_N); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, Rtemp); + +#ifdef CONFIG_SDR_EN + if (PwrAdapter.SDREn) SDRWakeUp(); +#endif + + //disable DSTBY timer + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, 0); + + //clear wake event IMR + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, 0); + + //clear wake event ISR + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0, Rtemp); + + //set event flag + PwrAdapter.WakeEventFlag = _TRUE; +} + +VOID +InitSYSIRQ(VOID) +{ + IRQ_HANDLE SysHandle; + PSYS_ADAPTER pSYSAdapte; + pSYSAdapte = &SYSAdapte; + SysHandle.Data = (u32) (pSYSAdapte); + SysHandle.IrqNum = SYSTEM_ON_IRQ; + SysHandle.IrqFun = (IRQ_FUN) SYSIrqHandle; + SysHandle.Priority = 0; + + InterruptRegister(&SysHandle); + InterruptEn(&SysHandle); + PwrAdapter.WakeEventFlag = _FALSE; +} + +void vWFSSVCHandler( void ) +{ +#if defined (__ICCARM__) + // TODO: IAR has different way using assembly +#elif defined (__GNUC__) + asm volatile + ( + "svcing:\n" + " mov r0, %0 \n" + " ldmia r0!, {r4-r7} \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ + " ldmia r0!, {r8-r11} \n" + " msr psp, r0 \n" /* Restore the task stack pointer. */ + " orr r14, #0xd \n" + " bx r14 \n" + ::"r"(PwrAdapter.CPUPSP):"r0" + ); +#endif +} + + +VOID +WakeFromSLPPG( + VOID +) +{ + //release shutdone + HAL_WRITE32(PERI_ON_BASE, REG_GPIO_SHTDN_CTRL, 0x7FF); + //HAL_WRITE32(PERI_ON_BASE, REG_CPU_PERIPHERAL_CTRL, 0x110001); + //JTAG rst pull high + HAL_WRITE32(PERI_ON_BASE, REG_GPIO_PULL_CTRL2, 0x05555556); + + ReFillCpuClk(); + + //3 Need Modify + VectorTableInitRtl8195A(0x1FFFFFFC); + + //3 Make PendSV, CallSV and SysTick the same priroity as the kernel. + HAL_WRITE32(0xE000ED00, 0x20, 0xF0F00000); + + //3 Initial Log Uart + PSHalInitPlatformLogUart(); + +#ifdef CONFIG_KERNEL + InterruptForOSInit((VOID*)vWFSSVCHandler, + (VOID*)xPortPendSVHandler, + (VOID*)xPortSysTickHandler); +#endif + //CPURegbackup[13] = CPURegbackup[13]-4; + PwrAdapter.CPURegbackup[16] |= 0x1000000 ; + + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-4) ) )= PwrAdapter.CPURegbackup[16]; //PSR + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-8) ) )= PwrAdapter.CPURegbackup[15]; //PC + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-12) ) )= PwrAdapter.CPURegbackup[14]; //LR + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-16) ) )= PwrAdapter.CPURegbackup[12]; //R12 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-20) ) )= PwrAdapter.CPURegbackup[3]; //R3 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-24) ) )= PwrAdapter.CPURegbackup[2]; //R2 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-28) ) )= PwrAdapter.CPURegbackup[1]; //R1 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-32) ) )= PwrAdapter.CPURegbackup[0]; //R0 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-36) ) )= PwrAdapter.CPURegbackup[11]; //R11 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-40) ) )= PwrAdapter.CPURegbackup[10]; //R10 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-44) ) )= PwrAdapter.CPURegbackup[9]; //R9 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-48) ) )= PwrAdapter.CPURegbackup[8]; //R8 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-52) ) )= PwrAdapter.CPURegbackup[7]; //R7 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-56) ) )= PwrAdapter.CPURegbackup[6]; //R6 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-60) ) )= PwrAdapter.CPURegbackup[5]; //R5 + ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[13]-64) ) )= PwrAdapter.CPURegbackup[4]; //R4 + PwrAdapter.CPURegbackup[13] -= 64; //PSP + + PwrAdapter.CPUPSP = PwrAdapter.CPURegbackup[13]; + //CPURegBackUp(); + + asm volatile( + " cpsie i \n" /* Globally enable interrupts. */ + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +} + +VOID +DurationScaleAndPeriodOP( + IN u32 SDuration, + OUT u32 *ScaleTemp, + OUT u32 *PeriodTemp +) +{ + u8 Idx = 0; + if (SDuration > 8355){ + SDuration = 0x20A3; + } + + //in unit 128us + SDuration = ((SDuration*125)/16); + + for (Idx = 8; Idx < 32; Idx++) { + + if ( (SDuration & 0xFFFFFF00) > 0 ) { + (*ScaleTemp) = (*ScaleTemp) + 1; + SDuration = (SDuration >> 1); + } + else { + break; + } + } + + *ScaleTemp = ((*ScaleTemp) << 8); + *PeriodTemp = SDuration; +} + + +u32 +CLKCal( + IN u8 ClkSel +) +{ + u32 Rtemp = 0; + u32 RRTemp = 0; + + u32 x = (HAL_READ32(PERI_ON_BASE,REG_SYS_CLK_CTRL1) >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL; + + if( ClkSel ){ + //a33_ck + Rtemp |= 0x10000; + } + + //Enable cal + Rtemp |= 0x800000; + HAL_WRITE32(VENDOR_REG_BASE, REG_VDR_ANACK_CAL_CTRL, Rtemp); + + while( (HAL_READ32(VENDOR_REG_BASE, REG_VDR_ANACK_CAL_CTRL) & BIT23) != 0 ); + Rtemp = ((HAL_READ32(VENDOR_REG_BASE, REG_VDR_ANACK_CAL_CTRL) & 0x3FFF)) + 1; + + if( ClkSel ){ + //a33_ck + RRTemp = (Rtemp); + } + else { + //anack + RRTemp = (((2133/Rtemp) >> x) - 1); + } + if ( x == 5 ) + DiagPrintf("Using ana to cal is not allowed!\n"); + + return RRTemp; +} + +VOID +BackupCPUClk( + VOID +) +{ + u32 Cpubp; + Cpubp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO0) & 0xFFFFFFF0); + Cpubp |= ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) >> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO0, Cpubp); +} + +VOID +ReFillCpuClk( + VOID +) +{ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1, + ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) + & (~(BIT_MASK_PESOC_OCP_CPU_CK_SEL << BIT_SHIFT_PESOC_OCP_CPU_CK_SEL))) + | BIT_PESOC_OCP_CPU_CK_SEL(HAL_READ32(SYSTEM_CTRL_BASE,REG_SYS_DSTBY_INFO0)))); +} + +VOID +SleepClkGatted( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 ScaleTemp = 0; + u32 PeriodTemp = 0; + u32 CalTemp = 0; + + //Backup CPU CLK + BackupCPUClk(); + + //truncate duration + SDuration &= 0x0003FFFC; + //2 CSleep + //3 1.1 Set TU timer timescale + //0x4000_0090[21:16] = 6'h1F + //0x4000_0090[15] = 1'b0 => Disable timer + CalTemp = (CLKCal(ANACK) << 16); + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) + & (~((BIT_MASK_SYS_ANACK_TU_TIME << BIT_SHIFT_SYS_ANACK_TU_TIME) | BIT_SYS_DSBYCNT_EN))) + | CalTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[11:8] => Time scale + //0x4000_0090[7:0] => Time period + //max duration 0x7FFFFF us, min 0x80 + DurationScaleAndPeriodOP(SDuration, &ScaleTemp, &PeriodTemp); + + Rtemp = (((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) + & (~((BIT_MASK_SYS_DSTDY_TIM_SCAL << BIT_SHIFT_SYS_DSTDY_TIM_SCAL) | (BIT_MASK_SYS_ANACK_TU_TIME << BIT_SHIFT_SYS_ANACK_TU_TIME)))) + | ScaleTemp) | PeriodTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //3 1.2 Configure platform wake event + //0x4000_0100[0] = 1'b1 => Enable timer and GT as wakeup event to wakeup CPU + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, BIT_SYSON_WEVT_SYSTIM_MSK); + + //3 1.3 Configure power state option: + // 1.4.3 0x120[15:8]: sleep power mode option0 [11] = 1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION) & 0xffff00ff) | 0x74000A00);//A + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 1.4.4 0x124[7:0]: sleep power mode option1 [0] =1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00) | BIT_SYSON_PMOPT_SLP_SWR_ADJ); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + //3 1.5 Enable low power mode + // 1.5.1 0x4000_0118[2] = 1 => for sleep mode + Rtemp = 0x00000004;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000004; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 1.6 Wait CHIP enter low power mode + // 1.7 Wait deep standby timer timeout + // 1.8 Wait CHIP resume to norm power mode + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); + +} + + +VOID SleepPwrGatted( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 ScaleTemp = 0; + u32 PeriodTemp = 0; + u32 CalTemp = 0; + + //Backup CPU CLK + BackupCPUClk(); + + //truncate duration + SDuration &= 0x0003FFFC; + + //2 PSleep + //3 1.1 Set TU timer timescale + //0x4000_0090[21:16] = 6'h1F + //0x4000_0090[15] = 1'b0 => Disable timer + CalTemp = (CLKCal(ANACK) << 16); + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) + & (~((BIT_MASK_SYS_DSTDY_TIM_SCAL << BIT_SHIFT_SYS_DSTDY_TIM_SCAL) | (BIT_MASK_SYS_ANACK_TU_TIME << BIT_SHIFT_SYS_ANACK_TU_TIME)))) + | ScaleTemp; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[11:8] => Time scale + //0x4000_0090[7:0] => Time period + //max duration 0x7FFFFF us, min 0x80 + DurationScaleAndPeriodOP(SDuration, &ScaleTemp, &PeriodTemp); + + Rtemp = (((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) & 0xfffff000) | ScaleTemp) | PeriodTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //3 1.2 Configure platform wake event + //0x4000_0100[0] = 1'b1 => Enable timer and GT as wakeup event to wakeup CPU + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, BIT_SYSON_WEVT_SYSTIM_MSK | BIT_SYSON_WEVT_GTIM_MSK); + + //3 1.4 Configure power state option: + // 1.4.3 0x120[15:8]: sleep power mode option0: + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION) & 0x00ff00ff) | 0x74000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 1.4.4 0x124[7:0]: sleep power mode option1: + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00) | BIT_SYSON_PMOPT_SLP_SWR_ADJ | BIT_SYSON_PMOPT_SLP_ANACK_EN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + //3 1.5 Enable low power mode + // 1.5.1 0x4000_0118[2] = 1 => for sleep mode + Rtemp = 0x00000004;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000004; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 1.6 Wait CHIP enter low power mode + // 1.7 Wait deep standby timer timeout + // 1.8 Wait CHIP resume to norm power mode + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); +#if CONFIG_DEBUG_LOG > 33 +// DiagPrintf("YOU CAN'T SEE ME ~~~~!!!!!!!!!!!!!!!!!!!~~~~~slppg~~~~!!!!!!!!!!"); +#endif +} + + +VOID +DStandby( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 ScaleTemp = 0; + u32 PeriodTemp = 0; + u32 CalTemp = 0; + + //Backup CPU CLK + BackupCPUClk(); + + //Clear A33 timer event + //Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_SLP_WAKE_EVENT_STATUS0); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_SLP_WAKE_EVENT_STATUS0, Rtemp); + + //2 Deep Standby mode + //3 1.1 Set TU timer timescale + //0x4000_0090[21:16] = 6'h1F + //0x4000_0090[15] = 1'b0 => Disable timer + CalTemp = (CLKCal(ANACK) << 16); + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) + & (~((BIT_MASK_SYS_DSTDY_TIM_SCAL << BIT_SHIFT_SYS_DSTDY_TIM_SCAL) | (BIT_MASK_SYS_ANACK_TU_TIME << BIT_SHIFT_SYS_ANACK_TU_TIME)))) + | ScaleTemp; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[11:8] => Time scale + //0x4000_0090[7:0] => Time period + //max duration 0x7FFFFF us, min 0x80 + DurationScaleAndPeriodOP(SDuration, &ScaleTemp, &PeriodTemp); + + Rtemp = (((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) & 0xfffff000) | ScaleTemp) | PeriodTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //3 1.3 Configure platform wake event + // 1.3.1 0x4000_0100[0] = 1'b1 => Enable deep standby timer wakeup event to wakeup CPU + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, BIT_SYSON_WEVT_SYSTIM_MSK); + + //3 1.4 Configure power state option: + // 1.4.4 0x120[7:0]: deep standby power mode option: + Rtemp = 0x74000000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 1.4.5 0x124[7:0]: sleep power mode option1 [0] =1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00) | BIT_SYSON_PMOPT_SLP_SWR_ADJ); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + //3 1.5 Enable low power mode + // [0x4000_0118[1] = 1 => for deep standby mode] + Rtemp = 0x00000002; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 1.6 Wait CHIP enter low power mode + // 1.7 Wait deep standby timer timeout + // 1.8 Wait CHIP resume to norm power mode + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); +#if CONFIG_DEBUG_LOG > 33 +// DiagPrintf("YOU CAN'T SEE ME ~~~~!!!!!!!!!!!!!!!!!!!~~~~~~~~~~~~~~~!!!!!!!!!!"); +#endif +} + + +VOID +DSleep( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + //u32 ScaleTemp = 0; + //u32 PeriodTemp = 0; + u32 UTemp = 0; + u32 MaxTemp = 0; + + u32 Reada335 = 0; + + //2 Deep Sleep mode: + //3 2.1 Set TU timer timescale + + //3 2.2 Configure deep sleep timer: + //2.2.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2 Calibration A33 CLK + UTemp = CLKCal(A33CK); + + //Calculate the max value base on the a33 duration + MaxTemp = 0x7FFFFF*0x100/100000*UTemp/100*0x80; + //DiagPrintf("MaxTemp : 0x%x\n", MaxTemp); + + if ( SDuration >= MaxTemp ) { + SDuration = 0x7FFFFF; + } + else { + //In unit of A33 CLK : max num is bounded by anaclk = 1.5k + SDuration = ((((SDuration)/UTemp)*25/16*25/16*125)); + //DiagPrintf("SDuration : 0x%x\n", SDuration); + } +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("SDuration : 0x%x\n", SDuration); +#endif + //3 2.2.2 Initialize deep sleep counter + //2.2.2.0 0x4000_0094[15:0] = 16'hD300 => Disable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D300); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + //2.2.2.0.1 Clear event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT)); + //2.2.2.1 0x4000_0094[15:0] = 16'h9008 => set counter[7:0] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009000 | ((u8)SDuration)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.2 0x4000_0094[15:0] = 16'h9100 => set counter[15:8] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009100 | ((u8)(SDuration >> 8))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.3 0x4000_0094[15:0] = 16'h9200 => set counter[22:16] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009200 | ((u8)(SDuration >> 16))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.4 0x4000_0094[15:0] = 16'hD380 => Enable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D380); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + HalDelayUs(1000); + Reada335 = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CAL_CTRL); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("a33 timer : 0x%x\n", Reada335); +#endif + + HalDelayUs(8000); + + //3 2.2.3 + //2.3 Enable low power mode: 0x4000_0118[0] = 1'b1; + Rtemp = 0x00000001;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //2.4 Wait CHIP enter deep sleep mode + //2.5 Wait deep sleep counter timeout + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); +#if CONFIG_DEBUG_LOG > 33 +// DiagPrintf("YOU CAN'T SEE ME ~~~~!!!!!!!!!!!!!!!!!!!~~~~~~~~~~~~~~~!!!!!!!!!!"); +#endif +} + +VOID +MSBackupProcess( + void +) +{ + + u8 i = 0; + + //backup main stack + for (i = 0; i < (MAX_BACKUP_SIZE-1); i++) { + PwrAdapter.MSPbackup[i] = HAL_READ32(0x1FFFFE00, (0x1FC - (i*4))); // low 0x1FFFFD18 ! + } + + asm volatile + ( + "MRS r0, MSP\n" + "MOV %0, r0\n" + :"=r"(PwrAdapter.MSPbackup[MAX_BACKUP_SIZE-1]) + ::"memory" + ); +} + + +VOID +MSReFillProcess( + VOID +) +{ + u8 i = 0; + + for (i = 0; i < (MAX_BACKUP_SIZE-1); i++) { + + HAL_WRITE32(0x1FFFFE00, (0x1FC - (i*4)), PwrAdapter.MSPbackup[i]); + } + + asm volatile + ( + "MSR MSP, %0\n" + ::"r"(PwrAdapter.MSPbackup[MAX_BACKUP_SIZE-1]):"memory" + ); +} + + +VOID +SoCPSGPIOCtrl( + VOID +) +{ + HAL_WRITE32(PERI_ON_BASE,0x330,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x334,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x338,0x05555555); + HAL_WRITE32(PERI_ON_BASE,0x33c,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x340,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x344,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x348,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x320,0x0); +} + + +VOID +InitSoCPM( + VOID +) +{ + u8 Idx = 0; + PRAM_FUNCTION_START_TABLE pRamStartFun = (PRAM_FUNCTION_START_TABLE) __ram_start_table_start__; + + PwrAdapter.ActFuncCount = 0; + PwrAdapter.CurrentState = ACT; + for (Idx = 0; Idx < MAXSTATE; Idx++) { + PwrAdapter.PwrState[Idx].FuncIdx = 0xFF; + PwrAdapter.PwrState[Idx].PowerState = 0xFF; + } + PwrAdapter.SDREn = _FALSE; + InitSYSIRQ(); + pRamStartFun->RamWakeupFun = WakeFromSLPPG; +} + +u8 +ChangeSoCPwrState( + IN u8 RequestState, + IN u32 ReqCount +) +{ + + //DiagPrintf("Go to sleep"); + + while(1) { + + HalDelayUs(100); + + if (HAL_READ8(LOG_UART_REG_BASE, 0x14) & BIT6){ + + break; + } + } + + switch (RequestState) { + +// case ACT: +// break; + + case WFE: + __WFE(); + break; + + case WFI: + __WFI(); + break; + + //case SNOOZE: + //break; + + case SLPCG: + SleepClkGatted(ReqCount); + break; + + case SLPPG: + //Resume jump to wakeup function + //HAL_WRITE32(PERI_ON_BASE, 0x218, (HAL_READ32(PERI_ON_BASE,0x218)|BIT31)); + + SoCPSGPIOCtrl(); + SleepPwrGatted(ReqCount); + break; + + case DSTBY: + SoCPSGPIOCtrl(); + DStandby(ReqCount); + break; + + case DSLP: + case INACT: + SoCPSGPIOCtrl(); + DSleep(ReqCount); + break; + } + return 0; +} + + +u32 +SoCPwrChk( + IN u8 ReqState, + OUT u8* FailfuncIdx, + OUT u8* FailState +) +{ + u8 Idx = 0; + u32 Result = _FALSE; + + if ( PwrAdapter.ActFuncCount ) { + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + + if (PwrAdapter.PwrState[Idx].PowerState < ReqState) { + *FailfuncIdx = PwrAdapter.PwrState[Idx].FuncIdx; + *FailState = PwrAdapter.PwrState[Idx].PowerState; + Result = _FALSE; + break; + } + } + } + else { + *FailfuncIdx = PwrAdapter.PwrState[Idx].FuncIdx; + *FailState = PwrAdapter.PwrState[Idx].PowerState; + Result = _TRUE; + } + return Result; +} + + +VOID +RegPowerState( + REG_POWER_STATE RegPwrState +) +{ + u8 Idx; + u8 StateIdx = 0; + u8 FState = 0; + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + if (PwrAdapter.PwrState[Idx].FuncIdx == RegPwrState.FuncIdx) { + StateIdx = Idx; + FState = _TRUE; + break; + } + } + + switch (RegPwrState.PwrState) { + + case INACT : + if (FState) { + for (Idx = StateIdx; Idx < PwrAdapter.ActFuncCount; Idx++) { + PwrAdapter.PwrState[Idx].FuncIdx = PwrAdapter.PwrState[Idx+1].FuncIdx; + PwrAdapter.PwrState[Idx].PowerState = PwrAdapter.PwrState[Idx+1].PowerState; + } + PwrAdapter.ActFuncCount--; + } + else { + } + break; + + default: + + if (FState) { + PwrAdapter.PwrState[StateIdx].PowerState = RegPwrState.PwrState; + } + else { + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].FuncIdx = RegPwrState.FuncIdx; + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].PowerState = RegPwrState.PwrState; + PwrAdapter.ActFuncCount++; + } + + break; + } + + //for debug +#if CONFIG_DEBUG_LOG > 5 + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + DiagPrintf("RegPwrIdx : %d \n", Idx); + DiagPrintf("FuncIdx : %d \n", PwrAdapter.PwrState[Idx].FuncIdx); + DiagPrintf("PowerState : 0x%x \n", PwrAdapter.PwrState[Idx].PowerState); + } +#endif +} + + +VOID +ReadHWPwrState( + IN u8 FuncIdx, + OUT u8* HwState +){ + + switch (FuncIdx){ + case UART0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_UART0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_UART0_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case UART1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_UART1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_UART1_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case UART2: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_UART2_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_UART2_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case SPI0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_SPI0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_SPI0_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case SPI1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_SPI1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_SPI1_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case SPI2: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_SPI2_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL0) & BIT_SOC_ACTCK_SPI2_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case I2C0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2C0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2C0_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case I2C1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2C1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2C1_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case I2C2: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2C2_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2C2_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else { + *HwState = HWINACT; + } + break; + + case I2C3: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2C3_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2C3_EN){ + *HwState = HWACT; + } + else { + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case I2S0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2S0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2S_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case I2S1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_I2S1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_I2S_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case PCM0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_PCM0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_PCM_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case PCM1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC0_EN) & BIT_PERI_PCM1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_PCM_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; +//#ifdef CONFIG_ADC_EN + case ADC0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC1_EN) & BIT_PERI_ADC0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_ADC_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; +//#endif +//#ifdef CONFIG_DAC_EN + case DAC0: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC1_EN) & BIT_PERI_DAC0_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_DAC_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case DAC1: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_PERI_FUNC1_EN) & BIT_PERI_DAC1_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_PERI_CLK_CTRL1) & BIT_SOC_ACTCK_DAC_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; +//#endif + case SDIOD: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & BIT_SOC_HCI_SDIOD_ON_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & BIT_SOC_ACTCK_SDIO_DEV_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case SDIOH: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & BIT_SOC_HCI_SDIOH_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & BIT_SOC_ACTCK_SDIO_HST_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; +#ifdef CONFIG_USB_EN + case USBOTG: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & BIT_SOC_HCI_OTG_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & BIT_SOC_ACTCK_OTG_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else { + *HwState = HWINACT; + } + break; +#endif + case MII: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_HCI_COM_FUNC_EN) & BIT_SOC_HCI_MII_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_HCI_CLK_CTRL0) & BIT_SOC_ACTCK_MII_MPHY_EN){ + *HwState = HWACT; + } + else { + *HwState = HWCG; + } + } + else{ + *HwState = HWINACT; + } + break; + + case PWM0: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_PWM0_CTRL) & BIT_PERI_PWM0_EN){ + *HwState = HWACT; + } + else { + *HwState = HWINACT; + } + break; + + case PWM1: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_PWM1_CTRL) & BIT_PERI_PWM1_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case PWM2: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_PWM2_CTRL) & BIT_PERI_PWM2_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case PWM3: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_PWM3_CTRL) & BIT_PERI_PWM3_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case ETE0: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_TIM_EVT_CTRL) & BIT_PERI_GT_EVT0_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case ETE1: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_TIM_EVT_CTRL) & BIT_PERI_GT_EVT1_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case ETE2: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_TIM_EVT_CTRL) & BIT_PERI_GT_EVT2_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case ETE3: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_TIM_EVT_CTRL) & BIT_PERI_GT_EVT3_EN){ + *HwState = HWACT; + } + else { + *HwState = HWINACT; + } + break; + + case EGTIM: + if (HAL_READ32(PERI_ON_BASE, REG_PERI_EGTIM_CTRL) & BIT_PERI_EGTIM_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWINACT; + } + break; + + case LOG_UART: + if (HAL_READ32(PERI_ON_BASE, REG_SOC_FUNC_EN) & BIT_SOC_LOG_UART_EN){ + if (HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_CTRL) & BIT_SOC_ACTCK_LOG_UART_EN){ + *HwState = HWACT; + } + else{ + *HwState = HWCG; + } + } + else { + *HwState = HWINACT; + } + break; + + default: + *HwState = UNDEF; + break; + } + +} + +VOID +QueryRegPwrState( + IN u8 FuncIdx, + OUT u8* RegState, + OUT u8* HwState +){ + u8 Idx = 0; + u8 StateIdx = INACT; + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + if (PwrAdapter.PwrState[Idx].FuncIdx == FuncIdx) { + StateIdx = PwrAdapter.PwrState[Idx].PowerState; + break; + } + } + + *RegState = StateIdx; + ReadHWPwrState(FuncIdx, HwState); +} + + +VOID +SetSYSTimer( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 ScaleTemp = 0; + u32 PeriodTemp = 0; + u32 CalTemp = 0; + + //0x4000_0090[15] = 1'b0 => Disable timer + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, 0); + + //calculate scale and period + CalTemp = (CLKCal(ANACK) << 16); + DurationScaleAndPeriodOP(SDuration, &ScaleTemp, &PeriodTemp); + + Rtemp = ((CalTemp | ScaleTemp) | PeriodTemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); +} + +VOID +SleepCG( + IN u8 Option, + IN u32 SDuration, + IN u8 ClkSourceEn, + IN u8 SDREn + +) +{ + u32 Rtemp = 0; + u32 WakeEvent = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0); + + u32 Backupvalue = HAL_READ32(0xE000E000, 0x100); + HAL_WRITE32(0xE000E000,0x0180,-1); + + //Backup CPU CLK + BackupCPUClk(); + + //Clear event + PwrAdapter.WakeEventFlag = _FALSE; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0)); + + //3 2 Configure power state option: + // 2.1 power mode option: + if (ClkSourceEn) { + Rtemp = 0x74003B00; //0x74003900; + } + else { + Rtemp = 0x74000900; + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 2.2 sleep power mode option1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00) | BIT_SYSON_PMOPT_SLP_ANACK_EN); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + if (Option & SLP_STIMER) { + + //Set TU timer timescale + SetSYSTimer(SDuration); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; // 0x00008000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //Enable wake event + WakeEvent |= BIT0; + } + + if (Option & SLP_GTIMER) { + + //Enable wake event + WakeEvent |= BIT1; + } + + if (Option & SLP_GPIO) { + + //Enable wake event + WakeEvent |= BIT4; + } + + if (Option & SLP_WL) { + + //Enable wake event + WakeEvent |= BIT8; + } + + if (Option & SLP_NFC) { + + //Enable wake event + WakeEvent |= BIT28; + } + + if (Option & SLP_SDIO) { + + //Enable wake event + WakeEvent |= BIT14; + } + + if (Option & SLP_USB) { + + //Enable wake event + //WakeEvent |= BIT16; + } + + if (Option & SLP_TIMER33) { + + //Enable wake event + WakeEvent |= BIT28; + } +/* + while(1) { + + HalDelayUs(100); + + if (HAL_READ8(LOG_UART_REG_BASE,0x14) & BIT6){ + + break; + } + } +*/ + HalLogUartWaitTxFifoEmpty(); + //Set Event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, WakeEvent); + + //3 Enable low power mode + //Enable low power mode: + if ((*((volatile u8*)(&PwrAdapter.WakeEventFlag)))!= _TRUE){ + + PwrAdapter.SDREn = SDREn; +#ifdef CONFIG_SDR_EN + if (SDREn) SDRSleep(); +#endif + + Rtemp = 0x00000004; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 Wait CHIP enter low power mode + // Wait deep standby timer timeout + // Wait CHIP resume to norm power mode + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + HalDelayUs(300); + HAL_WRITE32(0xE000E000, 0x0100, Backupvalue); + //__WFI(); + } +} + + +VOID +SleepPG( + IN u8 Option, + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 WakeEvent = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0); + + //Backup CPU CLK + BackupCPUClk(); + + //Clear event + PwrAdapter.WakeEventFlag = _FALSE; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0)); + + //3 2 Configure power state option: + // 2.1 power mode option: + Rtemp = 0x74000100; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 2.2 sleep power mode option1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00) | BIT_SYSON_PMOPT_SLP_ANACK_EN); // 0x2); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + if (Option & SLP_STIMER) { + + //Set TU timer timescale + SetSYSTimer(SDuration); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; // 0x00008000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //Enable wake event + WakeEvent |= BIT0; + } + + if (Option & SLP_GTIMER) { + + //Enable wake event + WakeEvent |= BIT1; + } + + if (Option & SLP_GPIO) { + + //Enable wake event + WakeEvent |= BIT4; + } + + if (Option & SLP_WL) { + + //Enable wake event + WakeEvent |= BIT8; + } + + if (Option & SLP_NFC) { + + //Enable wake event + WakeEvent |= BIT28; + } + + if (Option & SLP_SDIO) { + + //Enable wake event + WakeEvent |= BIT14; + } + + if (Option & SLP_USB) { + + //Enable wake event + //WakeEvent |= BIT16; + } + + if (Option & SLP_TIMER33) { + + //Enable wake event + WakeEvent |= BIT28; + } +/* while(1) { + + HalDelayUs(100); + + if (HAL_READ8(LOG_UART_REG_BASE,0x14)&BIT6){ + + break; + } + } */ + HalLogUartWaitTxFifoEmpty(); + + //Set Event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, WakeEvent); + + //3 Enable low power mode + //Enable low power mode: + if (PwrAdapter.WakeEventFlag != _TRUE){ + +#ifdef CONFIG_SDR_EN + LDO25M_CTRL(OFF); +#endif + + Rtemp = 0x00000004; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 Wait CHIP enter low power mode + // Wait deep standby timer timeout + // Wait CHIP resume to norm power mode +// HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); + } +} + + + +VOID +DSTBYGpioCtrl( + IN u8 PinEn, + IN u8 WMode +) +{ + u32 Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE,REG_SYS_GPIO_DSTBY_WAKE_CTRL0)|PinEn|(PinEn<<16)|(PinEn<<24)); + u32 Stemp = (PinEn<<8); + + if (WMode) { + Rtemp = (Rtemp|Stemp); + } + else { + Rtemp = (Rtemp & (~Stemp)); + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_GPIO_DSTBY_WAKE_CTRL0, Rtemp); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_SYS_GPIO_DSTBY_WAKE_CTRL1) | PinEn | (PinEn<<16) | BIT_SYS_WINT_DEBOUNCE_TIM_SCAL(2); // BIT9; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_GPIO_DSTBY_WAKE_CTRL1, Rtemp); +} + + +VOID +DeepStandby( + IN u8 Option, + IN u32 SDuration, + IN u8 GpioOption +) +{ + u32 Rtemp = 0; + + HAL_WRITE32(0x60008000, 0x80006180, PS_MASK); + + //Clear event + PwrAdapter.WakeEventFlag = _FALSE; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0)); + + //3 2 Configure power state option: + // 2.1 deep standby power mode option: + Rtemp = 0x74000100; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, Rtemp); + + // 2.2 sleep power mode option1 + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT) & 0xffffff00)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, Rtemp); + + if (Option & DSTBY_STIMER) { + + //3 3.1 Set TU timer timescale + SetSYSTimer(SDuration); + + //3 3.2 Configure platform wake event + // 1.3.1 0x4000_0100[0] = 1'b1 => Enable deep standby timer wakeup event to wakeup CPU + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0) | BIT0); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | BIT_SYS_DSBYCNT_EN; // 0x00008000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + } + + if (Option & DSTBY_NFC){ + //Enable wake event + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0)|BIT28); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); + } + + if (Option & DSTBY_TIMER33){ + //Enable wake event + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0)|BIT28); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); + } + + if (Option & DSTBY_GPIO){ + + if (GpioOption & BIT0) { + DSTBYGpioCtrl(BIT0, (GpioOption & BIT4)); + } + + if (GpioOption & BIT1) { + DSTBYGpioCtrl(BIT1, (GpioOption & BIT5)); + } + + if (GpioOption & BIT2) { + DSTBYGpioCtrl(BIT2, (GpioOption & BIT6)); + } + + if (GpioOption & BIT3) { + DSTBYGpioCtrl(BIT3, (GpioOption & BIT7)); + } + + //Enable wake event + if (GpioOption & 0xF){ + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0)|BIT29); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); + } + } + + + //3 Enable low power mode + //Enable low power mode: + if (PwrAdapter.WakeEventFlag != _TRUE){ + + SpicDeepPowerDownFlashRtl8195A(); + +#ifdef CONFIG_SDR_EN + LDO25M_CTRL(OFF); +#endif + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_GPIO_SHTDN_CTRL, 0x0); + + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & 0xBFFFFFFF); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, Rtemp); + + Rtemp = 0x00000002; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //3 Wait CHIP enter low power mode + // Wait deep standby timer timeout + // Wait CHIP resume to norm power mode +// HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); + } +} + + + +VOID +DeepSleep( + IN u8 Option, + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 UTemp = 0; + u32 MaxTemp = 0; + +//??? HAL_WRITE32(0x60008000, 0x80006180, PS_MASK); + + //1.1.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //1.1.2 0x4000_0094[15:0] = 16'hD300 => Disable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D300); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + + //1.1.3 Clear event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT)); + + if (Option & DS_TIMER33){ + //2.1.1 Calibration A33 CLK + UTemp = CLKCal(A33CK); + + //Calculate the max value base on the a33 duration + MaxTemp = ((((0x7FFFFF/3)*500)/UTemp)*25); + + if ( SDuration >= MaxTemp ) { + SDuration = 0x7FFFFF; + } + else { + //In unit of A33 CLK : max num is bounded by anaclk = 1.5k + SDuration = ((((SDuration/3)*500)/UTemp)*25); + } + + //2.1.2 Initialize deep sleep counter + //2.1.3.1 0x4000_0094[15:0] = 16'h9008 => set counter[7:0] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009000 | ((u8)SDuration)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + + //2.1.3.2 0x4000_0094[15:0] = 16'h9100 => set counter[15:8] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009100 | ((u8)(SDuration >> 8))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + + //2.1.3.3 0x4000_0094[15:0] = 16'h9200 => set counter[22:16] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009200 | ((u8)(SDuration >> 16))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + + //2.1.3.4 0x4000_0094[15:0] = 16'hD380 => Enable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D380); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + } + + if (Option & DS_GPIO) { + //2.2 en GPIO + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009410); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + while(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & BIT15); + } + + + //0x4000_0100[28] = 1'b1 => Enable A33 wakeup event to wakeup CPU + PwrAdapter.WakeEventFlag = _FALSE; + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0) | BIT28); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); + + //3 2.3 + //2.3 Enable low power mode: 0x4000_0118[0] = 1'b1; + if (PwrAdapter.WakeEventFlag != _TRUE){ + + SpicDeepPowerDownFlashRtl8195A(); + +#ifdef CONFIG_SDR_EN + LDO25M_CTRL(OFF); +#endif + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0) & (~BIT_SYS_REGU_LDO25M_EN); // 0xFFFFFFFD; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_REGU_CTRL0, Rtemp); + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_GPIO_SHTDN_CTRL, 0x0); + + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN) & 0xBFFFFFFF); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_FUNC_EN, Rtemp); + + Rtemp = 0x00000001;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //2.4 Wait CHIP enter deep sleep mode + //2.5 Wait deep sleep counter timeout +// HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); + } +} + +VOID +DSleep_GPIO( + VOID +) +{ + u32 Rtemp = 0; + + //1.1 Clear event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT)); + + //2 Deep Sleep mode: + //3 2.2 Configure GPIO: + //2.2.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009410); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2 + //2.3 Enable low power mode: 0x4000_0118[0] = 1'b1; + Rtemp = 0x00000001;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //2.4 Wait CHIP enter deep sleep mode + //2.5 Wait deep sleep counter timeout +// HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); +} + +VOID +DSleep_Timer( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + u32 UTemp = 0; + u32 MaxTemp = 0; + + //2 Deep Sleep mode: + //3 2.1 Set TU timer timescale + + //3 2.2 Configure deep sleep timer: + //2.2.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2 0x4000_0094[15:0] = 16'hD300 => Disable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D300); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.3 Clear event + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_WEVENT)); + + //2.2.4 Calibration A33 CLK + UTemp = CLKCal(A33CK); + + //Calculate the max value base on the a33 duration + MaxTemp = 0x7FFFFF*0x100/100000*UTemp/100*0x80; + + if ( SDuration >= MaxTemp ) { + SDuration = 0x7FFFFF; + } + else { + //In unit of A33 CLK : max num is bounded by anaclk = 1.5k + SDuration = ((((SDuration)/UTemp)*25/16*25/16*125)); + } + + //DiagPrintf("SDuration : 0x%x\n", SDuration); + + //2.2.5 Initialize deep sleep counter + //2.2.5.1 0x4000_0094[15:0] = 16'h9008 => set counter[7:0] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009000 | ((u8)SDuration)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.5.2 0x4000_0094[15:0] = 16'h9100 => set counter[15:8] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009100 | ((u8)(SDuration >> 8))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.5.3 0x4000_0094[15:0] = 16'h9200 => set counter[22:16] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009200 | ((u8)(SDuration >> 16))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.5.4 0x4000_0094[15:0] = 16'hD380 => Enable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D380); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //HalDelayUs(1000); + //Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CAL_CTRL); + //DiagPrintf("a33 timer : 0x%x\n", Rtemp); + HalDelayUs(8000); + + //3 2.3 + //2.3 Enable low power mode: 0x4000_0118[0] = 1'b1; + Rtemp = 0x00000001;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //2.4 Wait CHIP enter deep sleep mode + //2.5 Wait deep sleep counter timeout +// HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL); + __WFI(); +} + + +VOID +SoCPwrReinitProcess( + VOID +) +{ + //clear resume jumping condition + HAL_WRITE32(PERI_ON_BASE, 0x218, (HAL_READ32(PERI_ON_BASE,0x218)&(~BIT31))); + + #ifdef CONFIG_KERNEL + InterruptForOSInit((VOID*)vPortSVCHandler, + (VOID*)xPortPendSVHandler, + (VOID*)xPortSysTickHandler); + #endif + + //msp stack + MSReFillProcess(); + + //init sys timer + ( * ( ( volatile unsigned long * ) 0xe000e014 ) ) = 0xc34f;//portNVIC_SYSTICK_LOAD_REG + ( * ( ( volatile unsigned long * ) 0xe000e010 ) ) = 0x10007;//portNVIC_SYSTICK_CTRL_REG + + //3 Reinit SYS int + { + IRQ_HANDLE SysHandle; + PSYS_ADAPTER pSYSAdapte; + pSYSAdapte = &SYSAdapte; + SysHandle.Data = (u32) (pSYSAdapte); + SysHandle.IrqNum = SYSTEM_ON_IRQ; + SysHandle.IrqFun = (IRQ_FUN) SYSIrqHandle; + SysHandle.Priority = 0; + + InterruptRegister(&SysHandle); + InterruptEn(&SysHandle); + } + //DiagPrintf("REINIT IRQ0!!!!!!!!!!\n"); + //HAL_WRITE32(0xE000ED00, 0x14, 0x200); + +} + + +VOID +SoCEnterPS( + VOID +) +{ +} + + +VOID +SoCPWRIdleTaskHandle( + VOID +) +{ + //static u32 IdleLoopCount = 0; + static u32 IdleCount = 0; + //u8 Chktemp = 0; + //u32 CMDTemp[6]; + //u32 Rtemp,Rtemp1,Rtemp2; + + //IdleCount++; + //HalDelayUs(1000); + //if ((IdleCount > 5000)||(HAL_READ8(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0+1) == 0x12)) + if (HAL_READ8(SYSTEM_CTRL_BASE, 0xf2) == 0xda) {// { + + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SOC_FUNC_EN, (HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_FUNC_EN)|BIT29)); + + HAL_WRITE32(SYSTEM_CTRL_BASE,0xf0,0); + + #if 0 //slp pg + //backup cpu reg + CPURegBackUp(); + + //backup main stack + MSBackupProcess(); + + //Wait for LogUart print out + while(1) { + HalDelayUs(100); + if (HAL_READ8(LOG_UART_REG_BASE,0x14)&BIT6){ + break; + } + } + + SoCPSGPIOCtrl(); + + ChangeSoCPwrState(SLPPG, 0xFFFFF); + + asm volatile + ( + "SLPPG_WAKEUP_POINT:\n" + ); + + SoCPwrReinitProcess(); + + //DiagPrintf("idle~~~~~~~~~~~~~~~~~\n"); + DiagPrintf("SLP_PG = %d\n", HAL_READ32(SYSTEM_CTRL_BASE,0xf8)); + #endif + asm volatile + ( + "SLPPG_WAKEUP_POINT:\n" + ); + +#if 1 //dslp + //Wait for LogUart print out + while(1) { + HalDelayUs(100); + if (HAL_READ8(LOG_UART_REG_BASE,0x14) & BIT6){ + break; + } + } + + ChangeSoCPwrState(DSTBY, 0xFFFFF); +#endif + + } + + if (IdleCount > 500) { + IdleCount = 0; + if (HAL_READ32(SYSTEM_CTRL_BASE,0xf4) ==0) { + HAL_WRITE32(SYSTEM_CTRL_BASE,0xf0,HAL_READ32(SYSTEM_CTRL_BASE,0xf0)|0xda0000); + HAL_WRITE32(SYSTEM_CTRL_BASE,0xf8,HAL_READ32(SYSTEM_CTRL_BASE,0xf8)+1); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("DSTBY = %d\n", HAL_READ32(SYSTEM_CTRL_BASE,0xf8)); +#endif + } + //DiagPrintf("idle~~~~~~~~~~~~~~~~~\n"); + } + else { + HalDelayUs(100000); + IdleCount++; + } +} + +#ifdef CONFIG_SOC_PS_VERIFY +#if 0 +VOID +SoCPwrDecision( + void +) +{ + u8 Idx = 0; + u8 StateIdx = 0; + u8 State = _TRUE; + u8 NextState = 0; + u32 CurrentCount, RemainCount, PTTemp; + + if ( PwrAdapter.ActFuncCount ) { + + //update remaining count + CurrentCount = HalTimerOp.HalTimerReadCount(1); + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + + if (PwrAdapter.PwrState[Idx].RegCount < CurrentCount) { + PTTemp = (0xFFFFFFFF - CurrentCount + PwrAdapter.PwrState[Idx].RegCount); + } + else { + PTTemp = (PwrAdapter.PwrState[Idx].RegCount - CurrentCount); + } + + if ( PTTemp < PwrAdapter.PwrState[Idx].ReqDuration ) { + PwrAdapter.PwrState[Idx].RemainDuration = PwrAdapter.PwrState[Idx].ReqDuration - PTTemp; + } + else { + //active this function + if ( PwrAdapter.PwrState[Idx].PowerState > SLPPG ) { + //Todo: re-initial function as GPIO wake + } + PwrAdapter.PwrState[Idx].PowerState = ACT; + PwrAdapter.PwrState[Idx].RemainDuration = 0; + PwrAdapter.PwrState[Idx].ReqDuration = 0; + } + } + + //Select next power mode + for (StateIdx = DSLP; StateIdx >= ACT; StateIdx--) { + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + + State = _TRUE; + if (PwrAdapter.PwrState[Idx].PowerState < StateIdx) { + State = _FALSE; + break; + } + } + + if ( State ) { + NextState = StateIdx; + break; + } + } + + //fine min sleep time + RemainCount = PwrAdapter.PwrState[0].RemainDuration; + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + + if ( RemainCount > PwrAdapter.PwrState[Idx].RemainDuration ) { + + RemainCount = PwrAdapter.PwrState[Idx].RemainDuration; + } + } + + //for debug +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("RemainCount : 0x%x \n", RemainCount); + DiagPrintf("NextState : 0x%x \n", NextState); +#endif + #if 0 + //Change state + if ( NextState > SLPCG ) { + if ( RemainCount > 640 ) { + ChangeSoCPwrState(NextState, RemainCount); + } + else { + ChangeSoCPwrState(SLPCG, RemainCount); + } + } + else { + if (NextState != ACT ) { + ChangeSoCPwrState(NextState, RemainCount); + } + } + #endif + } + else { + //todo: go to DSLP + } +} + + +VOID +RegPowerState( + REG_POWER_STATE RegPwrState +) +{ + u8 Idx = 0; + u8 StateIdx; + u8 FState = 0; + + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + if (PwrAdapter.PwrState[Idx].FuncIdx == RegPwrState.FuncIdx) { + StateIdx = Idx; + FState = _TRUE; + } + } + + switch (RegPwrState.PwrState) { + + case INACT : + if (FState) { + for (Idx = StateIdx; Idx < PwrAdapter.ActFuncCount; Idx++) { + PwrAdapter.PwrState[Idx].FuncIdx = PwrAdapter.PwrState[Idx+1].FuncIdx; + PwrAdapter.PwrState[Idx].PowerState = PwrAdapter.PwrState[Idx+1].PowerState; + PwrAdapter.PwrState[Idx].ReqDuration = PwrAdapter.PwrState[Idx+1].ReqDuration; + PwrAdapter.PwrState[Idx].RegCount = PwrAdapter.PwrState[Idx+1].RegCount; + } + PwrAdapter.ActFuncCount--; + } + else { + } + break; + + default: + + if (FState) { + PwrAdapter.PwrState[StateIdx].PowerState = RegPwrState.PwrState; + PwrAdapter.PwrState[StateIdx].ReqDuration = RegPwrState.ReqDuration; + PwrAdapter.PwrState[StateIdx].RegCount = HalTimerOp.HalTimerReadCount(1); + } + else { + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].FuncIdx = RegPwrState.FuncIdx; + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].PowerState = RegPwrState.PwrState; + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].ReqDuration = RegPwrState.ReqDuration; + PwrAdapter.PwrState[PwrAdapter.ActFuncCount].RegCount = HalTimerOp.HalTimerReadCount(1); + PwrAdapter.ActFuncCount++; + } + + break; + } + + //for debug +#if CONFIG_DEBUG_LOG > 3 + for (Idx = 0; Idx < PwrAdapter.ActFuncCount; Idx++) { + DiagPrintf("RegPwrIdx : %d \n", Idx); + DiagPrintf("FuncIdx : %d \n", PwrAdapter.PwrState[Idx].FuncIdx); + DiagPrintf("PowerState : 0x%x \n", PwrAdapter.PwrState[Idx].PowerState); + DiagPrintf("ReqDuration : 0x%x \n", PwrAdapter.PwrState[Idx].ReqDuration); + DiagPrintf("RegCount : 0x%x \n", PwrAdapter.PwrState[Idx].RegCount); + } +#endif +} +#endif + +#if 0 +VOID +En32KCalibration( + VOID +) +{ + u32 Rtemp; + u32 Ttemp = 0; + + while(1) { + + //set parameter + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, 0); + Rtemp = 0x80f880; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("cal en\n"); +#endif + + //Polling LOCK + Rtemp = 0x110000; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); + DiagPrintf("polling lock\n"); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL1); + if ((Rtemp & 0x3000) != 0x0){ + break; + } + else { + Ttemp++; +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("check lock: %d\n", Ttemp); +#endif + } + } + + Rtemp = 0x884000; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_OSC32K_REG_CTRL0, Rtemp); +} +#endif + +VOID +SYSTestIrqHandle +( + IN VOID *Data +) +{ + u32 Rtemp; + static u32 Ttemp = 0; + + //change cpu clk + ReFillCpuClk(); + HalDelayUs(100); + + //JTAG rst pull high + HAL_WRITE32(PERI_ON_BASE, REG_GPIO_PULL_CTRL2, 0x0202aaaa); + + //release shutdone + //HAL_WRITE32(PERI_ON_BASE, REG_GPIO_SHTDN_CTRL, 0x7ff); + + //disable DSTBY timer + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, 0); + + //clear wake event IMR + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, 0); + + //clear wake event ISR + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_STATUS0, Rtemp); + + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO0, Ttemp); + + //DiagPrintf("Ttemp : %d\n", Ttemp); + + Ttemp++; + //Rtemp = HalTimerOp.HalTimerReadCount(1); + //DiagPrintf("32k counter : %x\n", Rtemp);//32k counter : + //DiagPrintf("\n"); + + //PwrAdapter.SleepFlag = 1; + //DiagPrintf("\n"); + //DiagPrintf("0x234 after slp : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,0x234)+1); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO0, HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0)+1); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO1, HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO1)+1); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO2, HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO2)+1); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO3)+1); + //DiagPrintf("f0 counter : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0)); + //DiagPrintf("f1 counter : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO1)); + //DiagPrintf("f2 counter : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO2)); + //DiagPrintf("f3 counter : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO3)); + //DiagPrintf("\n"); + //DiagPrintf("ya ~~~~\n"); + + PwrAdapter.WakeEventFlag = _TRUE; +} + +VOID +InitSYSTestIRQ(VOID) +{ + IRQ_HANDLE SysHandle; + PSYS_ADAPTER pSYSAdapte; + pSYSAdapte = &SYSAdapte; + SysHandle.Data = (u32) (pSYSAdapte); + SysHandle.IrqNum = SYSTEM_ON_IRQ; + SysHandle.IrqFun = (IRQ_FUN) SYSIrqHandle; + SysHandle.Priority = 0; + + InterruptRegister(&SysHandle); + InterruptEn(&SysHandle); + PwrAdapter.WakeEventFlag = _FALSE; +} + +VOID +SetA33Timer( + IN u32 SDuration +) +{ + u32 Rtemp = 0; + //u32 ScaleTemp = 0; + //u32 PeriodTemp = 0; + u32 UTemp = 0; + u32 MaxTemp = 0; + + //2 Deep Sleep mode: + //3 2.1 Set TU timer timescale + + //3 2.2 Configure deep sleep timer: + //2.2.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2 Calibration A33 CLK + UTemp = CLKCal(A33CK); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("CAL : 0x%x\n", UTemp); +#endif + //Calculate the max value base on the a33 duration + MaxTemp = 0x7FFFFF*0x100/100000*UTemp/100*0x80; +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("MaxTemp : 0x%x\n", MaxTemp); +#endif + if ( SDuration >= MaxTemp ) { + SDuration = 0x7FFFFF; + } + else { + //In unit of A33 CLK : max num is bounded by anaclk = 1.5k + SDuration = ((((SDuration)/UTemp)*25/16*25/16*125)); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("SDuration : 0x%x\n", SDuration); +#endif + } + + //3 2.2.2 Initialize deep sleep counter + //2.2.2.1 0x4000_0094[15:0] = 16'h9008 => set counter[7:0] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009000 | ((u8)SDuration)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.2 0x4000_0094[15:0] = 16'h9100 => set counter[15:8] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009100 | ((u8)(SDuration >> 8))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.3 0x4000_0094[15:0] = 16'h9200 => set counter[22:16] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009200 | ((u8)(SDuration >> 16))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.4 0x4000_0094[15:0] = 16'hD380 => Enable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D380); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); +#if CONFIG_DEBUG_LOG > 3 + DiagPrintf("a33 timer : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CAL_CTRL)); +#endif +} + + +VOID +PrintCPU( + VOID +) +{ + +#if CONFIG_DEBUG_LOG > 33 + DiagPrintf("r13 : 0x%x\n", PwrAdapter.CPURegbackup[24]); + DiagPrintf("pc : 0x%x\n", PwrAdapter.CPURegbackup[23]); + DiagPrintf("control : 0x%x\n", PwrAdapter.CPURegbackup[22]); + DiagPrintf("psp : 0x%x\n", PwrAdapter.CPURegbackup[21]); + DiagPrintf("msp : 0x%x\n", PwrAdapter.CPURegbackup[20]); +#endif + + #if 0 + u8 i; + for (i = 0; i < 21; i++){ + PwrAdapter.CPURegbackup[i] = ( * ( ( volatile unsigned long * ) (PwrAdapter.CPURegbackup[24]+(i*4)) ) ); + } + #endif + + u8 i; + for (i = 0; i < 25; i++){ + DiagPrintf("CPURegbackup_idx : %d , 0x%x\n", i, PwrAdapter.CPURegbackup[i]); + } + + + #if 1 + for (i = 0; i < 21; i++) { + DiagPrintf("backup_idx : 0x%x , 0x%x\n", PwrAdapter.CPUPSP+(i*4),( * ( ( volatile unsigned long * ) (PwrAdapter.CPUPSP+(i*4)) ) ));//CPURegbackup[1] + } + #endif + +#if CONFIG_DEBUG_LOG > 33 + { + u32 cpupspc; + asm volatile + ( + "MRS %0, PSP\n" + :"=r"(cpupspc) + ::"memory" + ); + for (i = 0; i < 21; i++) { + DiagPrintf("stack addr : 0x%x , 0x%x\n", (cpupspc+(i*4)),( * ( ( volatile unsigned long * ) (cpupspc+(i*4)) ) ));//CPURegbackup[1] + } + } +#endif +} + + +VOID +SoCPSMEMTestInit( + IN u32 StartAddr, + IN u32 Length, + IN u32 Pattern +) +{ + u32 Idx; + for( Idx = 0; Idx < Length; Idx += 4 ){ + + HAL_WRITE32(StartAddr,Idx,Pattern); + } +} + +u8 +SoCPSMEMTestChk( + IN u32 StartAddr, + IN u32 Length, + IN u32 Pattern +) +{ + u32 Idx; + + for( Idx = 0; Idx < Length; Idx += 4 ){ + if (HAL_READ32(StartAddr,Idx) != Pattern) { + DiagPrintf("addr 0x%x fail\n", (StartAddr+Idx)); + return 0; + } + } + DiagPrintf("addr 0x%x pass\n", StartAddr); + return 1; +} + + +VOID +SoCPWRIdleTaskHandleTest( + VOID +) +{ + static u32 IdleTemp = 0; + u32 Rtemp,Rtemp1,Rtemp2; + u8 RRtemp,CMDTemp[8],Chktemp; + + if (0){//(HAL_READ8(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0) == 0x0) { + + IdleTemp++; + HalDelayUs(1000); + + if (IdleTemp >= 15000) { + DiagPrintf("\n"); + DiagPrintf("Go to sleep ~~~~ \n"); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_DSTBY_INFO0,0x12345678); + DiagPrintf("0xf0 : 0x%x\n",HAL_READ32(SYSTEM_CTRL_BASE,REG_SYS_DSTBY_INFO0)); + //a33 reg chk + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, 0x80008400); + HalDelayUs(1000); + if ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL)&BIT15)==0){ + RRtemp = ((u8)HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL))+1; + } + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009400|RRtemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + DiagPrintf("a33 0x4 : 0x%x\n",RRtemp); + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, 0x80008500); + HalDelayUs(1000); + if ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL)&BIT15)==0){ + DiagPrintf("a33 0x5 before : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL)); + RRtemp = ((u8)HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL))+1; + } + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009500|RRtemp); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + DiagPrintf("a33 0x5 : 0x%x\n",RRtemp); + + ChangeSoCPwrState(7,0xE8800); + } + } + + ////debug + if (PwrAdapter.SleepFlag) { + PwrAdapter.SleepFlag = 0; + HAL_WRITE32(SYSTEM_CTRL_BASE,0x234, 0xdddddddd); + DiagPrintf("0x234 before slp : %x\n", HAL_READ32(SYSTEM_CTRL_BASE,0x234)); + //cal 32k + //En32KCalibration(); + HalDelayUs(1000); + + ChangeSoCPwrState(5,0xb000); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_DSTBY_INFO1, PwrAdapter.SleepFlag); + } + + if (0){//(HAL_READ8(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0) == 0x0) { + + IdleTemp++; + HalDelayUs(1000); + if (IdleTemp > 0xfffff){ + IdleTemp = 0; + __WFI(); + } + } + + if (0){ //((HAL_READ8(SYSTEM_CTRL_BASE,REG_SOC_SYSON_DSTBY_INFO0) == 0x0)) { + IdleTemp++; + HalDelayUs(1000); + if ((IdleTemp > 5000)||(HAL_READ8(SYSTEM_CTRL_BASE,REG_SYS_DSTBY_INFO0+1) == 0x12)){ + + DiagPrintf("\n"); + DiagPrintf("0x20080000 : 0x%x\n", HAL_READ32(0x20080000,0)); + DiagPrintf("0x20080004 : 0x%x\n", HAL_READ32(0x20080000,4)); + DiagPrintf("0x2009F404 : 0x%x\n", HAL_READ32(0x2009F400,4)); + DiagPrintf("0x2009F408 : 0x%x\n", HAL_READ32(0x2009F400,8)); + DiagPrintf("\n"); + + HAL_WRITE32(PERI_ON_BASE,0x330,0x55559555);//0x55552a2a + //slp pg GPIOD GPIOE + HAL_WRITE32(PERI_ON_BASE,0x334,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x338,0x05555555); + HAL_WRITE32(PERI_ON_BASE,0x33c,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x340,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x344,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x320,0x0); + + HAL_WRITE32(0x20080000, 0, (HAL_READ32(0x20080000,0)+1)); + HAL_WRITE32(0x20080000, 4, (HAL_READ32(0x20080000,4)+1)); + HAL_WRITE32(0x2009F404, 0, (HAL_READ32(0x2009F400,4)+1)); + HAL_WRITE32(0x2009F408, 0, (HAL_READ32(0x2009F400,8)+1)); + HalDelayUs(10000); + ChangeSoCPwrState(SLPPG, 0xFFFFF); + } + } + //mem test + if (HAL_READ8(SYSTEM_CTRL_BASE,0xf1) == 0xaa) { + + CMDTemp[0] = 8; + SOCPSTestApp((VOID*)CMDTemp); + Rtemp = HAL_READ32(WIFI_REG_BASE,0x824); + Rtemp2 = Rtemp; + Rtemp2 = ((Rtemp2 & 0x807fffff) | 0x80000000); + HAL_WRITE32(WIFI_REG_BASE,0x824,Rtemp&0x7fffffff); + HAL_WRITE32(WIFI_REG_BASE,0x824,Rtemp2); + HAL_WRITE32(WIFI_REG_BASE,0x824,(Rtemp|0x80000000)); + Rtemp1 = HAL_READ32(WIFI_REG_BASE,0x820)&BIT8; + if (Rtemp1) { + Rtemp = HAL_READ32(WIFI_REG_BASE,0x8b8)&0xfffff; + } + else { + Rtemp = HAL_READ32(WIFI_REG_BASE,0x8a0)&0xfffff; + } + if(Rtemp== 0x00045678){ + Chktemp = 1; + } + + Chktemp &= SoCPSMEMTestChk(0x20010000,0x20000,0x12345678)&SoCPSMEMTestChk(0x200a0000,0x0FFE0,0x12345678) + &SoCPSMEMTestChk(0x1FFF4000,0x5000,0x12345678); + + if (Chktemp) { + HAL_WRITE32(WIFI_REG_BASE,0x4,(HAL_READ32(WIFI_REG_BASE,0x4)&0xFFFFFFF0)); + HAL_WRITE32(SYSTEM_CTRL_BASE,0xfc,(HAL_READ32(SYSTEM_CTRL_BASE,0xfc)+1)); + DiagPrintf("run %d times\n", HAL_READ32(SYSTEM_CTRL_BASE,0xfc)); + CMDTemp[0] = 1; + CMDTemp[1] = 5; + CMDTemp[2] = 0xff; + SOCPSTestApp((VOID*)CMDTemp); + } + else { + HAL_WRITE32(SYSTEM_CTRL_BASE,0xf0,0); + } + + } +} + +//30 +VOID +TimerHandleTset( + IN VOID *Data +) +{ + #if 0 + //static u32 temp = 0; + TIMER_ADAPTER TimerAdapter; + + TimerAdapter.IrqDis = OFF; + //TimerAdapter.IrqHandle = (IRQ_FUN) TimerHandleTset; + TimerAdapter.IrqHandle.IrqFun = (IRQ_FUN) TimerHandleTset; + //DBG_8195A("IrqFun : 0x%x\n", TimerAdapter.IrqHandle.IrqFun); + TimerAdapter.IrqHandle.IrqNum = TIMER2_7_IRQ; + TimerAdapter.IrqHandle.Priority = 0; + TimerAdapter.IrqHandle.Data = NULL; + TimerAdapter.TimerId = 2; + TimerAdapter.TimerIrqPriority = 0; + TimerAdapter.TimerLoadValueUs = 4000; + TimerAdapter.TimerMode = USER_DEFINED; + //temp++; + //DBG_8195A("time : 0x%x\n", temp); + + HalTimerOp.HalTimerInit((VOID*) &TimerAdapter); + #endif + DBG_8195A("<<< time out >>>\n"); +} + +extern IRQ_FUN Timer2To7VectorTable[6]; + +//30 +VOID +InitTimerTest( + //IN VOID *Data + VOID +) +{ + //[0]:type, [1]: timerID, [2]: timerMode, [3]: IrqDIS, [4]:period + TIMER_ADAPTER TimerAdapter; + //u32 *TestParameter; + + //TestParameter = (u32*) Data; + + TimerAdapter.IrqDis = 0; // off :0 + //TimerAdapter.IrqHandle = (IRQ_FUN) TimerHandleTset; + TimerAdapter.IrqHandle.IrqFun = (IRQ_FUN) TimerHandleTset; + //DBG_8195A("IrqFun : 0x%x\n", TimerAdapter.IrqHandle.IrqFun); + TimerAdapter.IrqHandle.IrqNum = TIMER2_7_IRQ; + TimerAdapter.IrqHandle.Priority = 0; + TimerAdapter.IrqHandle.Data = NULL; + TimerAdapter.TimerId = 5; + TimerAdapter.TimerIrqPriority = 0; + TimerAdapter.TimerLoadValueUs = 0x4EC14; + TimerAdapter.TimerMode = 1; // user_define :1 + + + //mer2To7VectorTable[0] = (IRQ_FUN) TimerHandleTset; + + HalTimerOp.HalTimerInit((VOID*) &TimerAdapter); + //mer2To7VectorTable[0] = (IRQ_FUN) TimerHandleTset; + + +} + + +VOID +GpioPsPullCtrl( + VOID +) +{ + gpio_t gpio_obj; + + gpio_init(&gpio_obj, PA_0); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_2); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_5); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_6); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PA_7); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PB_0); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PB_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_5); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_6); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PB_7); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PC_0); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_2); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_5); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_6); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_7); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_8); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PC_9); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PD_0); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_2); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_5); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_6); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_7); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_8); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PD_9); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PE_0); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_2); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_5); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_6); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_7); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_8); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_9); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PE_A); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PF_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PF_1); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PF_2); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PF_3); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PF_4); + gpio_mode(&gpio_obj, PullDown); + gpio_init(&gpio_obj, PF_5); + gpio_mode(&gpio_obj, PullDown); + + gpio_init(&gpio_obj, PG_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_1); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_3); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_4); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_5); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_6); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PG_7); + gpio_mode(&gpio_obj, PullUp); + + gpio_init(&gpio_obj, PH_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_1); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_3); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_4); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_5); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_6); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PH_7); + gpio_mode(&gpio_obj, PullUp); + + gpio_init(&gpio_obj, PI_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_1); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_3); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_4); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_5); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_6); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PI_7); + gpio_mode(&gpio_obj, PullUp); + + gpio_init(&gpio_obj, PJ_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_1); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_3); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_4); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_5); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PJ_6); + gpio_mode(&gpio_obj, PullUp); + + + gpio_init(&gpio_obj, PK_0); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_1); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_2); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_3); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_4); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_5); + gpio_mode(&gpio_obj, PullUp); + gpio_init(&gpio_obj, PK_6); + gpio_mode(&gpio_obj, PullUp); +} + + +VOID +SOCPSTestApp( + VOID *Data +) +{ + u32 *TestParameter; + TestParameter = (u32*) Data; + unsigned int Rtemp, Rtemp1, Rtemp2;//, CalTemp32k, CalTempa33; + static u32 Read32k5 = 0; + static u32 Reada335 = 0; + DiagPrintf("TestParameter[0]: 0x%x\n",TestParameter[0]); + + switch (TestParameter[0]) { + + case 0: + DiagPrintf("SoC PWR Init wlan\n"); + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_HCI_COM_FUNC_EN)|BIT_SOC_HCI_WL_MACON_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SOC_HCI_COM_FUNC_EN,Rtemp); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_PESOC_COM_CLK_CTRL1)|BIT_SOC_ACTCK_WL_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_PESOC_COM_CLK_CTRL1,Rtemp); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_FUNC_EN)|BIT_SOC_LXBUS_EN; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SOC_FUNC_EN,Rtemp); + + HalDelayUs(100); + + Rtemp = HAL_READ32(WIFI_REG_BASE,0x0)|BIT0; + HAL_WRITE32(WIFI_REG_BASE,0x0,Rtemp); + #if 0 + DiagPrintf("SoC PWR debug setting\n"); + Rtemp = 0; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_GPIO_PULL_CTRL3,Rtemp); + + Rtemp = 0; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_GPIO_PULL_CTRL1,Rtemp); + + #if 0 + //en debug + Rtemp = 1;//HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYS_DEBUG_CTRL); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SOC_SYS_DEBUG_CTRL,Rtemp); + + //debug port sel + Rtemp = 0xf0f10004;//HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_EFUSE_SYSCFG3)|0xf0000000; + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SOC_EFUSE_SYSCFG3, Rtemp); + #endif + + //cal 32k + //En32KCalibration(); + + //en gpio + GPIO_FCTRL(ON); + SLPCK_GPIO_CCTRL(ON); + ACTCK_GPIO_CCTRL(ON); + + //DiagPrintf("debug sel 0x2C : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_EFUSE_SYSCFG3)); + //DiagPrintf("debug EN 0xA0 : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYS_DEBUG_CTRL)); + //DiagPrintf("PULL CTRL 0x33c: 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,0x33C)); + //DiagPrintf("debug port : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,REG_SOC_SYS_DEBUG_REG)); + DiagPrintf("0x90 : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,0x90)); + #endif + break; + + case 1: + DiagPrintf("SoC PWR TEST : Enter = %d, Period = %d\n",TestParameter[1], TestParameter[2]); + Rtemp = HalTimerOp.HalTimerReadCount(1); + //GPIO + //HAL_WRITE32(0x40001000,0x4,0x4000000); + + //SIC EN + //HAL_WRITE32(SYSTEM_CTRL_BASE,0x8,0x81000010); + //HAL_WRITE32(SYSTEM_CTRL_BASE,0xA4,0x00000001); + + //Wait for LogUart print out + while(1) { + HalDelayUs(100); + if (HAL_READ8(LOG_UART_REG_BASE,0x14)&BIT6){ + break; + } + } + + #if 0 + + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL0,0x55559555);//0x55552a2a + //slp pg GPIOD GPIOE + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL1,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL2,0x05555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL3,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL4,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL5,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_SHTDN_CTRL,0x0); + #endif + + ChangeSoCPwrState(TestParameter[1], TestParameter[2]); + + Rtemp2 = HalTimerOp.HalTimerReadCount(1); + DiagPrintf("before : %x\n", Rtemp); + DiagPrintf("after : %x\n", Rtemp2); + DiagPrintf("period : %d\n", Rtemp-Rtemp2); + DiagPrintf("0x90 : 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,0x90)); + break; + + case 2: + #if 1 + + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_SHTDN_CTRL,0x7ff); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL0,0x5565A555); + //slp pg GPIOD GPIOE + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL1,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL2,0x05555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL3,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL4,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL5,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_PULL_CTRL6,0x55555555); + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_SHTDN_CTRL,0x0); + + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_FUNC_EN,0x80000011); + #endif + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, TestParameter[1]); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, TestParameter[2]); + + if (TestParameter[4] == 0xff) { + //SIC EN + HAL_WRITE32(PERI_ON_BASE,REG_GPIO_SHTDN_CTRL,0x4); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_FUNC_EN,0xC1000010); + HAL_WRITE32(SYSTEM_CTRL_BASE,REG_SYS_PINMUX_CTRL,0x00000001); + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, TestParameter[3]); + #if 0 + //clear isr + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SOC_SYS_ANA_TIM_CTRL)& 0xffff7fff)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYS_ANA_TIM_CTRL, Rtemp); + + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_SLP_WAKE_EVENT_STATUS0); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SOC_SYSON_SLP_WAKE_EVENT_STATUS0, Rtemp); + #endif + break; + + case 3: + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION, 0x74000e00); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_OPTION_EXT, 2); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, TestParameter[1]); + #if 0 + { + u32 targetunit = 0; + + //cal a33 + Rtemp = CLKCal(A33CK); + + targetunit = (TestParameter[1]/3*250)/Rtemp*50; + if (targetunit > 0x7fffff) { + targetunit = 0x7fffff; + } + + DBG_8195A("targeunit = 0x%08x\n",targetunit); + + targetunit = (50*TestParameter[1]/Rtemp)*250/3; + if (targetunit > 0x7fffff) { + targetunit = 0x7fffff; + } + + DBG_8195A("targeunit = 0x%08x\n",targetunit); + + + } + #endif + #if 0 + //cal a33 + Rtemp = CLKCal(A33CK); + Rtemp1 = (((((TestParameter[1] & 0x0FFFFFFF)<<4)/Rtemp)*20)-1); + DiagPrintf("Rtemp : 0x%x\n", Rtemp); + DiagPrintf("Vendor 0xA0 : 0x%x\n", HAL_READ32(VENDOR_REG_BASE,0xA0)); + DiagPrintf("way1 : 0x%x\n", Rtemp1); + Rtemp2 = (((((TestParameter[1] & 0x0FFFFFFF))/Rtemp)*320)-1); + DiagPrintf("way2 : 0x%x\n", Rtemp2); + + Rtemp = Rtemp1/6; + DiagPrintf("Rtemp1 : %d\n", Rtemp); + Rtemp = 0x7fffffff; + DiagPrintf("Rtemp1 : %d\n", Rtemp); + #endif + break; + + case 4: + DiagPrintf("set timer\n"); + SetA33Timer(TestParameter[1]); + Rtemp = HalTimerOp.HalTimerReadCount(1); + DiagPrintf("32k timer : 0x%x\n", Rtemp); + break; + + case 5: + DiagPrintf("read timer\n"); + Reada335 = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CAL_CTRL); + DiagPrintf("a33 timer : 0x%x\n", Reada335); + Read32k5 = HalTimerOp.HalTimerReadCount(1); + DiagPrintf("32k timer : 0x%x\n", Read32k5); + break; + + case 6: + #if 0 + DiagPrintf("interval cal\n"); + Rtemp1 = HAL_READ32(SYSTEM_CTRL_BASE, REG_SOC_SYS_DSLP_TIM_CAL_CTRL); + Rtemp2 = HalTimerOp.HalTimerReadCount(1); + DiagPrintf("Reada335 : 0x%x\n", Reada335); + DiagPrintf("Read32k5 : 0x%x\n", Read32k5); + DiagPrintf("a33 timer : 0x%x\n", Rtemp1); + DiagPrintf("32k timer : 0x%x\n", Rtemp2); + CalTemp32k = (Read32k5 - Rtemp2); + CalTempa33 = (((Reada335 - Rtemp1)*((HAL_READ32(VENDOR_REG_BASE, REG_VDR_ANACK_CAL_CTRL) & 0x3FFF)+1))/5); + DiagPrintf("a33 timer interval : 0x%x\n", CalTempa33); + DiagPrintf("32k timer interval : 0x%x\n", CalTemp32k); + Read32k5 = Rtemp2; + Reada335 = Rtemp1; + #endif + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) & 0xffff7000) | 0x7ff); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + //0x4000_0090[15] = 1'b1 => Enable timer + Rtemp = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL) | 0x00008000; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_ANA_TIM_CTRL, Rtemp); + + Rtemp = 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SLP_WAKE_EVENT_MSK0, Rtemp); +#if 0 + HAL_WRITE32(PERI_ON_BASE,0x330,0x55559555);//0x55552a2a + HAL_WRITE32(PERI_ON_BASE,0x2C0,0x100001); + //slp pg GPIOD GPIOE + HAL_WRITE32(PERI_ON_BASE,0x334,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x338,0x05555555); + HAL_WRITE32(PERI_ON_BASE,0x33c,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x340,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x344,0x55555555); + HAL_WRITE32(PERI_ON_BASE,0x320,0x0); +#endif + HAL_WRITE32(SYSTEM_CTRL_BASE, 0X120, TestParameter[1]); + HAL_WRITE32(SYSTEM_CTRL_BASE, 0X124, TestParameter[2]); + + if (HAL_READ32(SYSTEM_CTRL_BASE,0xf4) == 0x11) { + HAL_WRITE32(SYSTEM_CTRL_BASE,0x8,0x80000011); + } + + if (TestParameter[4] == 0xff) { + //SIC EN + HAL_WRITE32(SYSTEM_CTRL_BASE,0x8,0x81000010); + HAL_WRITE32(SYSTEM_CTRL_BASE,0xA4,0x00000001); + } + + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, TestParameter[3]); + break; + + case 7: + { + u32 Rtemp = 0; + u32 UTemp = 0; + u32 MaxTemp = 0; + u32 Reada335 = 0; + + //2 Deep Sleep mode: + //3 2.1 Set TU timer timescale + + //3 2.2 Configure deep sleep timer: + //2.2.1 Enable REGU access interface 0x4000_0094[31] = 1 + Rtemp = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) | 0x80000000); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + DiagPrintf("SDuration : 0x%x\n", TestParameter[1]); + + //3 2.2.2 Initialize deep sleep counter + //2.2.2.0 0x4000_0094[15:0] = 16'hD300 => Disable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D300); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + //2.2.2.1 0x4000_0094[15:0] = 16'h9008 => set counter[7:0] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009000 | ((u8)TestParameter[1])); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.2 0x4000_0094[15:0] = 16'h9100 => set counter[15:8] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009100 | ((u8)(TestParameter[1] >> 8))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.3 0x4000_0094[15:0] = 16'h9200 => set counter[22:16] + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x00009200 | ((u8)(TestParameter[1] >> 16))); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + //2.2.2.4 0x4000_0094[15:0] = 16'hD380 => Enable deep sleep counter + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL) & 0xffff0000) | 0x0000D380); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CTRL, Rtemp); + + HalDelayUs(1000); + Reada335 = HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSLP_TIM_CAL_CTRL); + DiagPrintf("a33 timer : 0x%x\n", Reada335); + + HalDelayUs(8000); + + //3 2.2.3 + //2.3 Enable low power mode: 0x4000_0118[0] = 1'b1; + Rtemp = 0x00000001;//HAL_READ32(SYSTEM_CTRL_BASE, REG_SYSON_PWRMGT_CTRL) | 0x00000001; + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_PWRMGT_CTRL, Rtemp); + + //2.4 Wait CHIP enter deep sleep mode + //2.5 Wait deep sleep counter timeout + //__WFI(); + +// DiagPrintf("YOU CAN'T SEE ME ~~~~!!!!!!!!!!!!!!!!!!!~~~~~~~~~~~~~~~!!!!!!!!!!"); + } + break; + + case 8: + DiagPrintf("enable wifi\n"); + + Rtemp = HAL_READ32(PERI_ON_BASE,REG_SOC_HCI_COM_FUNC_EN)|BIT_SOC_HCI_WL_MACON_EN; + HAL_WRITE32PERI_ON_BASE,REG_SOC_HCI_COM_FUNC_EN,Rtemp); + Rtemp = HAL_READ32(PERI_ON_BASE,REG_PESOC_COM_CLK_CTRL1)|BIT_SOC_ACTCK_WL_EN; + HAL_WRITE32(PERI_ON_BASE,REG_PESOC_COM_CLK_CTRL1,Rtemp); + Rtemp = HAL_READ32(PERI_ON_BASE,REG_SOC_FUNC_EN)|BIT_SOC_LXBUS_EN; + HAL_WRITE32(PERI_ON_BASE,REG_SOC_FUNC_EN,Rtemp); + + Rtemp = HAL_READ32(WIFI_REG_BASE,0x0)&0xFFFFFFDF; + HAL_WRITE32(WIFI_REG_BASE,0x0,Rtemp); + Rtemp = HAL_READ32(WIFI_REG_BASE,0x4)|0x1; + HAL_WRITE32(WIFI_REG_BASE,0x4,Rtemp); + Rtemp = HAL_READ32(WIFI_REG_BASE,0x20)|0x1; + HAL_WRITE32(WIFI_REG_BASE,0x20,Rtemp); + while( (HAL_READ32(WIFI_REG_BASE,0x20)&BIT0)!=0); + + Rtemp = HAL_READ32(WIFI_REG_BASE,0x4)|0x30000; + HAL_WRITE32(WIFI_REG_BASE,0x4,Rtemp); + Rtemp = HAL_READ32(WIFI_REG_BASE,0x4)|0x7000000; + HAL_WRITE32(WIFI_REG_BASE,0x4,Rtemp); + Rtemp = HAL_READ32(WIFI_REG_BASE,0x50)&0xFFFFFF00; + HAL_WRITE32(WIFI_REG_BASE,0x50,Rtemp); + break; + + case 9: + #if 0 + PwrAdapter.CPURegbackup[13] = 0x12340; + PwrAdapter.CPUPSP = PwrAdapter.CPURegbackup[13]; + + asm volatile + ( + + " ldr r3, pxCPUPSPConst23 \n" /* Restore the context. */ + "MOV %0, r3\n" + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + "MOV %1, r1\n" + " ldr r0, [r1] \n" + "MOV %2, r0\n" + " .align 2 \n" + "pxCPUPSPConst23: .word PwrAdapter.CPUPSP \n" + :"=r"(PwrAdapter.CPURegbackup[0]),"=r"(PwrAdapter.CPURegbackup[1]),"=r"(PwrAdapter.CPURegbackup[2]),"=r"(PwrAdapter.CPURegbackup[3]) + :"r"(PwrAdapter.CPUPSP) + :"memory" + ); + PrintCPU(); + #endif + break; + + case 10: + Rtemp = HAL_READ32(WIFI_REG_BASE,0x824); + Rtemp2 = Rtemp; + Rtemp2 = Rtemp2 & 0x807fffff | (TestParameter[1]<<23) | 0x80000000; + HAL_WRITE32(WIFI_REG_BASE,0x824,Rtemp&0x7fffffff); + HAL_WRITE32(WIFI_REG_BASE,0x824,Rtemp2); + HAL_WRITE32(WIFI_REG_BASE,0x824,Rtemp|0x80000000); + Rtemp1 = HAL_READ32(WIFI_REG_BASE,0x820)&BIT8; + if (Rtemp1) { + Rtemp = HAL_READ32(WIFI_REG_BASE,0x8b8)&0xfffff; + } + else { + Rtemp = HAL_READ32(WIFI_REG_BASE,0x8a0)&0xfffff; + } + DiagPrintf("rf offset: 0x%x, 0x%x\n", TestParameter[1], Rtemp); + break; + + case 11://addr [1]; date [2] + TestParameter[1] &= 0x3f; + Rtemp = (TestParameter[1]<<20)|(TestParameter[2]&0x000fffff)&0x0fffffff; + HAL_WRITE32(WIFI_REG_BASE,0x840,Rtemp); + + //SoCPWRIdleTaskHandle(); + break; + + case 12: + SoCPSMEMTestInit(TestParameter[1],TestParameter[2],TestParameter[3]); + break; + + case 13: + Rtemp = SoCPSMEMTestChk(TestParameter[1],TestParameter[2],TestParameter[3]); + break; + + case 14: + HAL_WRITE32(SYSTEM_CTRL_BASE,TestParameter[1],0x12345678); + DiagPrintf("w32: 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,TestParameter[1])); + HAL_WRITE32(SYSTEM_CTRL_BASE,TestParameter[1],0); + HAL_WRITE16(SYSTEM_CTRL_BASE,TestParameter[1],0x1234); + DiagPrintf("w16: 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,TestParameter[1])); + HAL_WRITE32(SYSTEM_CTRL_BASE,TestParameter[1],0); + HAL_WRITE8(SYSTEM_CTRL_BASE,TestParameter[1],0x12); + DiagPrintf("w8: 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,TestParameter[1])); + HAL_WRITE32(SYSTEM_CTRL_BASE,TestParameter[1],0x12345678); + DiagPrintf("R32: 0x%x\n", HAL_READ32(SYSTEM_CTRL_BASE,TestParameter[1])); + DiagPrintf("R16: 0x%x\n", HAL_READ16(SYSTEM_CTRL_BASE,TestParameter[1])); + DiagPrintf("R8: 0x%x\n", HAL_READ8(SYSTEM_CTRL_BASE,TestParameter[1])); + Rtemp = ((HAL_READ32(SYSTEM_CTRL_BASE,0xf4))?1:0); + DiagPrintf("R: 0x%x\n", Rtemp); + break; + + case 15: + asm volatile + ( + "MRS R0, BASEPRI\n" + "MOV %0, R0\n" + :"=r"(Rtemp) + ::"memory" + ); + DiagPrintf("basepri: 0x%x\n", Rtemp); + break; + case 16: + HalDelayUs(10000000); + DSleep_GPIO(); + break; + case 17: + DSleep_Timer(TestParameter[1]); + break; + case 18: + DiagPrintf("WDG CAL\n"); + { + u8 CountId; + u16 DivFactor; + u32 CountTemp; + u32 CountProcess = 0; + u32 DivFacProcess = 0; + u32 MinPeriodTemp = 0xFFFFFFFF; + u32 PeriodTemp = 0; + + DBG_8195A(" Period = %d\n", TestParameter[1]); + + for (CountId = 0; CountId < 12; CountId++) { + CountTemp = ((0x00000001 << (CountId+1))-1); + DivFactor = (u16)((100*TestParameter[1])/(CountTemp*3)); + + if (DivFactor > 0) { + PeriodTemp = 3*(DivFactor+1)*CountTemp; + DBG_8195A("PeriodTemp = %d\n", PeriodTemp); + if ((100*TestParameter[1]) PeriodTemp) { + MinPeriodTemp = PeriodTemp; + CountProcess = CountTemp; + DivFacProcess = DivFactor; + } + } + } + } + DBG_8195A("MinPeriodTemp = %d\n", MinPeriodTemp); + DBG_8195A("WdgScalar = 0x%08x\n", DivFacProcess); + DBG_8195A("WdgCunLimit = 0x%08x\n", CountProcess); + } + break; + + case 19: + DBG_8195A("DeepStandby~~~\n"); + DeepStandby(TestParameter[1],TestParameter[2],TestParameter[3]); + break; + + case 20: + DBG_8195A("SleepCG~~~\n"); + if (TestParameter[1]&BIT1){ + InitTimerTest(); + } + SleepCG(TestParameter[1],TestParameter[2],TestParameter[3],TestParameter[4]); + break; + + case 25: + { + //dslp + DBG_8195A("DSLP~~~\n"); + + HalDelayUs(3000000); + + GpioPsPullCtrl(); + + DeepSleep(TestParameter[1],TestParameter[2]); + } + break; + + case 26: + //dstby + DBG_8195A("DSTBY~~~\n"); + + GpioPsPullCtrl(); + + DeepStandby(TestParameter[1],TestParameter[2],TestParameter[3]); + break; + + case 28: + //slpcg + DBG_8195A("SLPCG~~~\n"); + while(1) { + + HalDelayUs(100); + + if (HAL_READ8(LOG_UART_REG_BASE,0x14)&BIT6){ + + break; + } + } + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_CPU_PERIPHERAL_CTRL, 0x0); + + GpioPsPullCtrl(); + + SleepCG(TestParameter[2],TestParameter[3],TestParameter[4],TestParameter[5]); + break; + + default: + break; + } + + +} +#endif //CONFIG_SOC_PS_VERIFY +#endif //CONFIG_SOC_PS_MODULE + diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c new file mode 100644 index 0000000..e30679c --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c @@ -0,0 +1,1466 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "rtl8195a.h" +#include "hal_spi_flash.h" +#include "rtl8195a_spi_flash.h" + +//#pragma arm section code = ".hal.flash.text", rodata = ".hal.flash.rodata", rwdata = ".hal.flash.data", zidata = ".hal.flash.bss" + +//#define SPI_CTRL_BASE 0x1FFEF000 +#define SPI_DLY_CTRL_ADDR 0x40000300 // [7:0] +#define MIN_BAUDRATE 0x01 +#define MAX_BAUDRATE 0x04 +#define MAX_AUTOLEN 0x14 +#define MAX_DLYLINE 99 +#define GOLD_ID_NO_RAM 0xC220 + +#define WR_DATA(addr, data) (*((volatile u32*)(addr)) = (data)) +#define RD_DATA(addr) (*((volatile u32*)(addr))) + +BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode); +u32 SpicCalibrationRtl8195A(u8 SpicBitMode, u32 DefRdDummyCycle); // spi-flash calibration + +VOID SpicSetFlashStatusRefinedRtl8195A(u32 data, SPIC_INIT_PARA SpicInitPara); + +VOID SpicConfigAutoModeRtl8195A(u8 SpicBitMode); // config spi-flash controller to auto mode +VOID SpicReadIDRtl8195A(VOID); + + +_LONG_CALL_ +extern VOID SpicInitRtl8195A(u8 InitBaudRate, u8 SpicBitMode); // spi-flash controller initialization + +_LONG_CALL_ +extern VOID SpicRxCmdRtl8195A(u8); // recieve command + +_LONG_CALL_ +extern VOID SpicSetFlashStatusRtl8195A(u32 data, SPIC_INIT_PARA SpicInitPara); // WRSR, write spi-flash status register + +_LONG_CALL_ +extern VOID SpicWaitBusyDoneRtl8195A(VOID); // wait sr[0] = 0, wait transmission done + +_LONG_CALL_ +extern VOID SpicWaitWipDoneRtl8195A(SPIC_INIT_PARA SpicInitPara); // wait spi-flash status register[0] = 0 + +_LONG_CALL_ +extern VOID SpicEraseFlashRtl8195A(VOID); // CE, flash chip erase + +_LONG_CALL_ +extern u32 SpicCmpDataForCalibrationRtl8195A(void); // compare read_data and golden_data +#ifdef CONFIG_FPGA +_LONG_CALL_ +extern VOID SpicProgFlashForCalibrationRtl8195A(SPIC_INIT_PARA SpicInitPara); // program spi-flash +#endif +_LONG_CALL_ +extern VOID SpicLoadInitParaFromClockRtl8195A(u8 CpuClkMode, u8 BaudRate, PSPIC_INIT_PARA pSpicInitPara); + +_LONG_CALL_ +extern u8 SpicGetFlashStatusRtl8195A(SPIC_INIT_PARA SpicInitPara); + +_LONG_CALL_ +extern VOID SpicTxCmdRtl8195A(u8 cmd, SPIC_INIT_PARA SpicInitPara); + +struct ava_window { + u16 baud_rate; + u16 auto_length; + u32 dly_line_sp; + u32 dly_line_ep; +}; + +#ifdef CONFIG_FPGA +HAL_ROM_DATA_SECTION +SPIC_INIT_PARA FPGASpicInitPara = {1,1,0,0}; +#endif + +#if 0 +HAL_FLASH_DATA_ +SECTION SPIC_INIT_PARA SpicInitParaAllClk[CPU_CLK_TYPE_NO] = {{0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0}, + {0,0,0,0},}; +#else +extern // HAL_FLASH_DATA_SECTION +SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // in rtl_bios_data.c +#endif + +//extern SPIC_INIT_PARA SpicInitCPUCLK[4]; + +/* Send Flash Instruction with Data Phase */ +HAL_FLASH_TEXT_SECTION +VOID +SpicTxCmdWithDataRtl8195A +( + IN u8 cmd, + IN u8 DataPhaseLen, + IN u8* pData, + IN SPIC_INIT_PARA SpicInitPara +) +{ + u8 i; +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("%s(0x%x, 0x%x, 0x%x, 0x%x)\n",__func__, cmd, DataPhaseLen, pData, SpicInitPara); +#endif + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + if (DataPhaseLen > 15) { + DBG_SPIF_WARN("%s: Data Phase Leng too Big(%d)\n", __func__, DataPhaseLen); + DataPhaseLen = 15; + } + + HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, DataPhaseLen); + + // set ctrlr0: TX mode + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + (HAL_SPI_READ32(REG_SPIC_CTRLR0)& 0xFFF0FCFF)); + + // set flash_cmd: wren to fifo + HAL_SPI_WRITE8(REG_SPIC_DR0, cmd); + + //fill addr + for (i=0;i>4)>= 2)){ + + SPI_FLASH_PIN_FCTRL(ON); + + // Wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + while((SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 0x02)==0) { + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_WREN, 0, 0, SpicInitPara); + } + + DBG_8195A("Deep power down\n"); + + // Set flash_cmd: Chip_erase to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_CE, SpicInitPara); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_DP, 0, 0, SpicInitPara); + + // polling WEL + do { + } while((SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 0x02)!=0); + } +} +//This funciton is only valid for Micron Flash +HAL_FLASH_TEXT_SECTION +VOID +SpicDieEraseFlashRtl8195A( + IN u32 Address +) +{ + u8 Addr[3]; + + Addr[0] = (Address >> 16) & 0xFF; + Addr[1] = (Address >> 8) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A(0xC4, 3, Addr); +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicBlockEraseFlashRtl8195A( + IN u32 Address +) +{ + u8 Addr[3]; + + DBG_8195A("Erase Cmd Set\n"); + // Set flash_cmd: Chip_erase to FIFO + Addr[0] = (Address >> 16) & 0xFF; + Addr[1] = (Address >> 8) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A(FLASH_CMD_BE, 3, Addr); +} + + +HAL_FLASH_TEXT_SECTION +VOID +SpicSectorEraseFlashRtl8195A( + IN u32 Address +) +{ + u8 Addr[3]; + + Addr[0] = (Address >> 16) & 0xFF; + Addr[1] = (Address >> 8) & 0xFF; + Addr[2] = Address & 0xFF; + SpicTxFlashInstRtl8195A(FLASH_CMD_SE, 3, Addr); +} + + +HAL_FLASH_TEXT_SECTION +VOID +SpicWriteStatusFlashRtl8195A( + IN u32 Status +) +{ + u8 Buf[3]; + + Buf[0] = Status & 0xFF; + Buf[1] = (Status >> 8) & 0xFF; + //1 For MXIC, Status Register is 8-bit width; for Winbond, Status Reguster is 16-bit width + SpicTxFlashInstRtl8195A(FLASH_CMD_WRSR, 1, Buf); +} + + +HAL_FLASH_TEXT_SECTION +VOID +SpicWriteProtectFlashRtl8195A( + IN u32 Protect +) +{ + SPIC_INIT_PARA SpicInitPara; + u8 Status; + + Status = SpicGetFlashStatusRefinedRtl8195A(SpicInitPara); + if (Protect) { + Status |= 0x1c; // protect whole chip + } + else { + Status &= ~0x1c; // Protect none + } + SpicWriteStatusFlashRtl8195A(Status); +} + + +HAL_FLASH_TEXT_SECTION +BOOLEAN +SpicFlashInitRtl8195A( + IN u8 SpicBitMode +) +{ + u32 DefRdDummyCycle = 0; + SPIC_INIT_PARA SpicInitPara; + +#ifdef CONFIG_FPGA + SpicInitPara.BaudRate = FPGASpicInitPara.BaudRate; + SpicInitPara.RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + SpicInitPara.DelayLine = FPGASpicInitPara.DelayLine; +#endif + + switch (SpicBitMode) { + case SpicOneBitMode: +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("Initial Spic One bit mode\n"); +#endif + // wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + // set auto mode + SpicConfigAutoModeRtl8195A(SpicBitMode); + + /* MXIC spec */ + DefRdDummyCycle = 0; + break; + case SpicDualBitMode: +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("Initial Spic Two bit mode\n"); +#endif +#ifdef CONFIG_FPGA + // program golden_data to golden_address and store golden_data in sram + SpicProgFlashForCalibrationRtl8195A(SpicInitPara); +#endif + // set auto mode + SpicConfigAutoModeRtl8195A(SpicBitMode); + + /* MXIC spec */ + #if FLASH_RD_2IO_EN + DefRdDummyCycle = FLASH_DM_CYCLE_2IO; + #endif + #if FLASH_RD_2O_EN + DefRdDummyCycle = FLASH_DM_CYCLE_2O; + #endif + + break; + case SpicQuadBitMode: +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("Initial Spic Four bit mode\n"); +#endif +#ifdef CONFIG_FPGA + // program golden_data to golden_address and store golden_data in sram + SpicProgFlashForCalibrationRtl8195A(SpicInitPara); +#endif + // set auto mode + SpicConfigAutoModeRtl8195A(SpicBitMode); + + // set 4bit-mode + SpicSetFlashStatusRefinedRtl8195A(0x40, SpicInitPara); + + /* MXIC spec */ + #if FLASH_RD_4IO_EN + DefRdDummyCycle = FLASH_DM_CYCLE_4IO; + #endif + #if FLASH_RD_4O_EN + DefRdDummyCycle = FLASH_DM_CYCLE_4O; + #endif + break; + default: + DBG_8195A("No Support SPI Mode!\n"); + break; + + } + SpicReadIDRtl8195A(); + + if (!SpicCalibrationRtl8195A(SpicBitMode, DefRdDummyCycle)) { + + DBG_8195A("SPI calibration fail and recover one bit mode\n"); + SpicLoadInitParaFromClockRtl8195A(0, 0, &SpicInitPara); + + SpicInitRefinedRtl8195A(SpicInitPara.BaudRate, SpicOneBitMode); + SpicConfigAutoModeRtl8195A(SpicOneBitMode); + + return _FALSE; + } + + return _TRUE; +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicUserProgramRtl8195A +( + //IN flash_t *obj, + IN u8 *data, + IN SPIC_INIT_PARA SpicInitPara, + IN u32 addr, + IN u32* LengthInfo +) +{ + + u32 Info; + u32 Length = (u32) *LengthInfo; + u32 OccuSize; + u32 writeword; + u32 lastwriteword; + u32 ProgramLength; + u32 instruction; + u32 PageSize; + u8 addrbyte[3]; + u8 UnalignOffset; + u8 lastunalignoffset; + u8 index; + u8 *ptr; + u8 *buff; + + + UnalignOffset = 0; + lastunalignoffset = 0; + writeword = 0; + lastwriteword = 0; + ProgramLength = 0; + buff = data; + PageSize = 256; + + OccuSize = addr & 0xFF; + if(OccuSize){ + if((Length >= PageSize) ||((OccuSize + Length) >= PageSize)) + ProgramLength= PageSize - OccuSize; + else + ProgramLength = Length; + } + else{//program from the beginning of the page + if(Length >= PageSize) + ProgramLength = PageSize; + else + ProgramLength = Length; + } + + *LengthInfo -= ProgramLength; + + if(addr & 0x03){ + UnalignOffset = (addr & 0x03); + addr -= UnalignOffset; + writeword = HAL_READ32(SPI_FLASH_BASE, addr); + ptr = (u8*) &writeword + UnalignOffset; + UnalignOffset = 4 - UnalignOffset; + for(index = 0; index < UnalignOffset ; index++){ + *ptr = *buff; + buff++; + ptr++; + ProgramLength--; + if(ProgramLength == 0) + break; + } + } + else{ + if(ProgramLength >= 4){ + writeword = (u32)(*buff) | (u32)((*(buff+1)) << 8)|(u32)((*(buff+2)) <<16)|(u32)((*(buff+3))<<24); + } + } +//address already align + if(ProgramLength & 0x3){ + lastunalignoffset = ProgramLength & 0x3; + if(UnalignOffset) + lastwriteword = HAL_READ32(SPI_FLASH_BASE, (addr + 4) + ProgramLength - lastunalignoffset); + else + lastwriteword = HAL_READ32(SPI_FLASH_BASE, addr + ProgramLength - lastunalignoffset); + buff += (ProgramLength - lastunalignoffset); + ptr = (u8*) &lastwriteword; + for(index = 0;index < lastunalignoffset;index++){ + *ptr = *buff; + buff++; + ptr++; + } + if(UnalignOffset == 0) + if(ProgramLength < 4){ + writeword = lastwriteword; + ProgramLength = 0; + } + } + + + + addrbyte[2] = (addr & 0xFF0000) >>16; + addrbyte[1] = (addr & 0xFF00)>>8; + addrbyte[0] = addr & 0xFF; + + instruction = FLASH_CMD_PP | (addrbyte[2] << 8)|(addrbyte[1] << 16)|(addrbyte[0] << 24); + Info = HAL_SPI_READ32(REG_SPIC_ADDR_LENGTH); + //Store current setting of Address length + // Set flash_cmd: WREN to FIFO + SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + + // Disable SPI_FLASH + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + // set ctrlr0: TX mode + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~ BIT_TMOD(3)))); + + HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_ADDR_PHASE_LENGTH(1)); + + HAL_SPI_WRITE32(REG_SPIC_DR0, instruction); + + HAL_SPI_WRITE32(REG_SPIC_DR0, writeword); + + if(UnalignOffset == 0){ + if(ProgramLength >= 4){ + buff = data + 4; + ProgramLength-=4; + } + } + else + buff = data + UnalignOffset; + //Pre-load data before enabling + index = 0; + while(ProgramLength > 4){ + if((u32)buff & 0x03){ + //while(ProgramLength >= 4){ + writeword = (u32)(*buff) | ((u32)(*(buff+1)) << 8) | ((u32)(*(buff+2)) << 16) | ((u32)(*(buff+3)) << 24); + HAL_SPI_WRITE32(REG_SPIC_DR0, writeword); + ProgramLength -=4; + buff+=4; + //} + } + else{ + //while(ProgramLength >= 4){ + HAL_SPI_WRITE32(REG_SPIC_DR0, (u32)*((u32 *)buff)); + ProgramLength -=4; + buff+=4; + //} + } + index++; + if(index >= 6) + break; + } + + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + + if((u32)buff & 0x03){ + while(ProgramLength >= 4){ + writeword = (u32)(*buff) | ((u32)(*(buff+1)) << 8) | ((u32)(*(buff+2)) << 16) | ((u32)(*(buff+3)) << 24); + HAL_SPI_WRITE32(REG_SPIC_DR0, writeword); + ProgramLength -=4; + buff+=4; + } + } + else{ + while(ProgramLength >= 4){ + HAL_SPI_WRITE32(REG_SPIC_DR0, (u32)*((u32 *)buff)); + ProgramLength -=4; + buff+=4; + } + } + + if(ProgramLength > 0){ + HAL_SPI_WRITE32(REG_SPIC_DR0, lastwriteword); + } + + + // wait spic busy done + SpicWaitBusyDoneRtl8195A(); + // wait flash busy done (wip=0) + if(SpicInitPara.flashtype == FLASH_MICRON){ + SpicWaitOperationDoneRtl8195A(SpicInitPara); + } + else{ + SpicWaitWipDoneRtl8195A(SpicInitPara); + } + + + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + //REG_SPIC_ADDR_LENGTH cannot be programmed if SSIENR is active + //Here to restore the setting of address length + HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, Info); +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicReadIDRtl8195A( + VOID +) +{ + u32 RdData; + u32 RetryNum; + SPIC_INIT_PARA SpicInitPara;// = *PSpicInitPara; + u8 i,j; + + DBG_SPIF_INFO("%s(0x%x)\n", __func__, SpicInitPara); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(3)); + + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A(FLASH_CMD_RDID, SpicInitPara); + RdData = HAL_SPI_READ32(REG_SPIC_DR0); + + SpicInitPara.id[0] = RdData & 0xFF; + SpicInitPara.id[1] = (RdData>> 8) & 0xFF; + SpicInitPara.id[2] = (RdData>>16) & 0xFF; + for(RetryNum =0; RetryNum < 3; RetryNum++){ + if((SpicInitPara.id[0] != 0) && (SpicInitPara.id[0] != 0xFF)){ + if(SpicInitPara.id[0] == 0x20) + SpicInitPara.flashtype = FLASH_MICRON; + else if(SpicInitPara.id[0] == 0xC2) + SpicInitPara.flashtype = FLASH_MXIC; + else if(SpicInitPara.id[0] == 0xEF) + SpicInitPara.flashtype = FLASH_WINBOND; + else + SpicInitPara.flashtype = FLASH_OTHERS; + break; + } + else{ + if(RetryNum == 2) + DBG_8195A("Invalid ID\n"); + } + } + for(i=0;i<3;i++) { + for (j=0; j> 4); + +#if SPIC_CALIBRATION_IN_NVM + if (!SpicInitParaAllClk[SpicBitMode][CpuType].Valid) { + SpicNVMCalLoad(SpicBitMode, CpuType); + } +#endif + if (SpicInitParaAllClk[SpicBitMode][CpuType].Valid) { + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, (SpicInitParaAllClk[SpicBitMode][CpuType].BaudRate & 0x00000FFF)); + rd_data = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + rd_data = (rd_data & 0xFFFF0000) | (SpicInitParaAllClk[SpicBitMode][CpuType].RdDummyCyle & 0x0000FFFF); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, rd_data); + rd_data = SpicInitParaAllClk[SpicBitMode][CpuType].DelayLine; + WR_DATA(SPI_DLY_CTRL_ADDR, ((RD_DATA(SPI_DLY_CTRL_ADDR) & 0xFFFFFF00) | (rd_data & 0x000000FF))); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + pass = SpicCmpDataForCalibrationRtl8195A(); + if (pass) { + // Check the Magic Pattern OK + return 1; + } + } + + // calibration + DBG_8195A("SPI calibration\n"); + + max_wd.auto_length = 0; + max_wd.baud_rate = 0; + max_wd.dly_line_ep = 0; + max_wd.dly_line_sp = 0; + + for(baudr=MIN_BAUDRATE; baudr < (MAX_BAUDRATE+1); baudr++) { + // Disable SPI_FLASH User Mode + if(baudr == MIN_BAUDRATE) + if(SpicBitMode == SpicOneBitMode) + continue; + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, BIT_SCKDV(baudr)); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + //DBG_8195A("(0x14)Baudr: 0x%x\n",HAL_SPI_READ32(REG_SPIC_BAUDR)); + + for(autolen=(DefRdDummyCycle*2*baudr); autolen<(DefRdDummyCycle*2*baudr+MAX_AUTOLEN); autolen++) { + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + rd_data = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + rd_data = (rd_data & 0xFFFF0000) | (0x0000FFFF & autolen); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, rd_data); + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + //DBG_8195A("Auto length: 0x%x\n",autolen); + //DBG_8195A("(0x11C) Auto address length register: 0x%x\n",HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH)); + tmp_str_pt = MAX_DLYLINE; + tmp_end_pt = 0; + last_pass = 0; + + for(dly_line=0; dly_line<=MAX_DLYLINE; dly_line++) { + rd_data = RD_DATA(SPI_DLY_CTRL_ADDR); + rd_data = (rd_data & 0xFFFFFF00) | (dly_line & 0x000000FF); + WR_DATA(SPI_DLY_CTRL_ADDR, rd_data); + //DBG_8195A("SPI_DLY_CTRL_ADDR: 0x%x\n",RD_DATA(SPI_DLY_CTRL_ADDR)); + + pass = SpicCmpDataForCalibrationRtl8195A(); + + + if(pass) { // PASS + if(last_pass==0) { + tmp_str_pt = dly_line; + total_ava_wds++; + } + + if(dly_line==MAX_DLYLINE) { + + tmp_end_pt = dly_line; + + if(total_ava_wds==1) { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + else { + if((tmp_end_pt-tmp_str_pt)>(max_wd.dly_line_ep-max_wd.dly_line_sp)) { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + } + } + last_pass = 1; + } + else { // FAIL + if(last_pass==1) { + tmp_end_pt = dly_line; + if(total_ava_wds == 1) { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + else { + if((tmp_end_pt-tmp_str_pt)>(max_wd.dly_line_ep-max_wd.dly_line_sp)) { + max_wd.baud_rate = baudr; + max_wd.auto_length = autolen; + max_wd.dly_line_sp = tmp_str_pt; + max_wd.dly_line_ep = tmp_end_pt; + } + } + } + last_pass = 0; + } + } +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("total wds: %d\n",total_ava_wds); + DBG_8195A("Baud:%x; auto_length:%x; Delay start:%x; Delay end:%x\n",max_wd.baud_rate, max_wd.auto_length,max_wd.dly_line_sp, max_wd.dly_line_ep); +#endif + } + if (total_ava_wds) { + DBG_8195A("Find the avaiable window\n"); + break; + } + + } + + + if(total_ava_wds==0) { + return 0; + } + else { + // set baudr, auto_length, and delay_line + DBG_8195A("Baud:%x; auto_length:%x; Delay start:%x; Delay end:%x\n",max_wd.baud_rate, max_wd.auto_length,max_wd.dly_line_sp, max_wd.dly_line_ep); + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, (max_wd.baud_rate & 0x00000FFF)); + SpicInitParaAllClk[SpicBitMode][CpuType].BaudRate = max_wd.baud_rate; + rd_data = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + rd_data = (rd_data & 0xFFFF0000) | (max_wd.auto_length & 0x0000FFFF); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, rd_data); + SpicInitParaAllClk[SpicBitMode][CpuType].RdDummyCyle = max_wd.auto_length; + rd_data = ((max_wd.dly_line_sp + max_wd.dly_line_ep) >> 1); + WR_DATA(SPI_DLY_CTRL_ADDR, ((RD_DATA(SPI_DLY_CTRL_ADDR) & 0xFFFFFF00) | (rd_data & 0x000000FF))); + SpicInitParaAllClk[SpicBitMode][CpuType].DelayLine = rd_data; + SpicInitParaAllClk[SpicBitMode][CpuType].Valid = 1; + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); +#if SPIC_CALIBRATION_IN_NVM + SpicNVMCalStore(SpicBitMode, CpuType); +#endif + return 1; + } + +} + + +HAL_FLASH_TEXT_SECTION +VOID +SpicConfigAutoModeRtl8195A +( + IN u8 SpicBitMode +) +{ + + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + if (SpicOneBitMode == SpicBitMode) { + + // set write cmd (ppiix4: 0x38) + HAL_SPI_WRITE32(REG_SPIC_WRITE_QUAD_ADDR_DATA, 0x38); + + // set read cmd (readiox4: 0xEB) + HAL_SPI_WRITE32(REG_SPIC_READ_QUAD_ADDR_DATA, 0xEB); + + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, + (HAL_SPI_READ32(REG_SPIC_VALID_CMD) & (~( + BIT_WR_QUAD_II | + BIT_WR_QUAD_I | + BIT_WR_DUAL_II | + BIT_WR_DUAL_I | + BIT_RD_QUAD_IO | + BIT_RD_QUAD_O | + BIT_RD_DUAL_IO | + BIT_RD_DUAL_I))));//Disable all the four and two bit commands. + } + else if (SpicDualBitMode == SpicBitMode) { + #if FLASH_RD_2IO_EN + HAL_SPI_WRITE32(REG_SPIC_READ_DUAL_ADDR_DATA, FLASH_CMD_2READ); + #endif + + #if FLASH_RD_2O_EN + HAL_SPI_WRITE32(REG_SPIC_READ_DUAL_DATA, FLASH_CMD_DREAD); + #endif + + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, + (HAL_SPI_READ32(REG_SPIC_VALID_CMD)|(FLASH_VLD_DUAL_CMDS))); + + } + else if (SpicQuadBitMode == SpicBitMode) { + #if FLASH_WR_4IO_EN + HAL_SPI_WRITE32(REG_SPIC_WRITE_QUAD_ADDR_DATA, FLASH_CMD_4PP); + #endif + + #if FLASH_RD_4IO_EN + HAL_SPI_WRITE32(REG_SPIC_READ_QUAD_ADDR_DATA, FLASH_CMD_4READ); + #endif + + #if FLASH_RD_4O_EN + HAL_SPI_WRITE32(REG_SPIC_READ_QUAD_DATA, FLASH_CMD_QREAD); + #endif + + HAL_SPI_WRITE32(REG_SPIC_VALID_CMD, + (HAL_SPI_READ32(REG_SPIC_VALID_CMD)|FLASH_VLD_QUAD_CMDS)); + } + + +} + + +/** + * @brief SpicWaitWipDoneRefinedRtl8195A. Wait for flash ready. + * + * @param IN SPIC_INIT_PARA SpicInitPara: spic init parameters with timing setting + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicWaitWipDoneRefinedRtl8195A( + IN SPIC_INIT_PARA SpicInitPara +){ +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("%s(0x%x)\n", __func__, SpicInitPara); +#endif + do { + } while((SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 0x01)); +} + + +#if 1 +HAL_FLASH_TEXT_SECTION +u8 +SpicGetFlashFlagRtl8195A +( + IN SPIC_INIT_PARA SpicInitPara +) +{ + + u32 RdData; + +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("%s(0x%x)\n", __func__, SpicInitPara); +#endif + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(1)); + + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A(0x70, SpicInitPara); + RdData = HAL_SPI_READ8(REG_SPIC_DR0); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + if(RdData & 0x2){ + DBG_SPIF_WARN("Attempts to Program / Erase Protected Area.\n"); + SpicTxCmdWithDataRtl8195A(0x50, 0, 0, SpicInitPara);//Clear Error Bit & Write Enable of Flag Status Register + } + +return RdData; + +} + +HAL_FLASH_TEXT_SECTION +VOID +SpicWaitOperationDoneRtl8195A +( + IN SPIC_INIT_PARA SpicInitPara +) +{ +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("%s(0x%x)\n", __func__, SpicInitPara); +#endif + do { + } while(!(SpicGetFlashFlagRtl8195A(SpicInitPara) & 0x80)); +} + +#endif +/** + * @brief SpicRxCmdRefinedRtl8195A. To send flash RX command. + * Timing store/restore is implemented inside. + * + * @param IN u8 cmd: flash RX command + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicRxCmdRefinedRtl8195A( + IN u8 cmd, + IN SPIC_INIT_PARA SpicInitPara +){ + u32 RdDummyCycle; + u32 BaudRate; + u32 BaudRate12bit; + u32 DelayLine; + u32 DelayLine8bit; + + u32 AutoLength = 0; + u8 CpuClk = ((HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70)) >> 4); + PSPIC_INIT_PARA PSpicInitParaLocal = NULL; + SPIC_INIT_PARA TmpSpicInitPara; + +#ifdef CONFIG_FPGA + PSpicInitParaLocal = &TmpSpicInitPara; + PSpicInitParaLocal->BaudRate = FPGASpicInitPara.BaudRate; + PSpicInitParaLocal->RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + PSpicInitParaLocal->DelayLine = FPGASpicInitPara.DelayLine; +#else + + if (SpicInitParaAllClk[SpicOneBitMode][CpuClk].Valid) { + PSpicInitParaLocal = &(SpicInitParaAllClk[SpicOneBitMode][CpuClk]); + } + else { + PSpicInitParaLocal = &TmpSpicInitPara; + SpicLoadInitParaFromClockRtl8195A(CpuClk, 1, PSpicInitParaLocal); + } +#endif + +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("!cpuclk:%x\n",CpuClk); + DBG_8195A("!baud:%x\n",PSpicInitParaLocal->BaudRate); + DBG_8195A("!delay:%x\n",PSpicInitParaLocal->DelayLine); + DBG_8195A("!dummy:%x\n",PSpicInitParaLocal->RdDummyCyle); + + DBG_SPIF_INFO("%s(0x%x, 0x%x)\n", __func__, cmd, PSpicInitParaLocal); +#endif + + /* Store rd_dummy_cycle */ + AutoLength = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + RdDummyCycle = AutoLength & BIT_MASK_RD_DUMMY_LENGTH; + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, ((AutoLength & (~BIT_MASK_RD_DUMMY_LENGTH))|(PSpicInitParaLocal->RdDummyCyle))); + + /* Store baud rate */ + BaudRate = HAL_SPI_READ32(REG_SPIC_BAUDR); + BaudRate12bit = (BaudRate & BIT_MASK_SCKDV); + HAL_SPI_WRITE32(REG_SPIC_BAUDR,((BaudRate & (~BIT_MASK_SCKDV))|(PSpicInitParaLocal->BaudRate))); + + /* Store delay line */ + DelayLine = HAL_READ32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL); + DelayLine8bit = (DelayLine & BIT_MASK_PESOC_FLASH_DDL_CTRL); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, ((DelayLine & (~BIT_MASK_PESOC_FLASH_DDL_CTRL))|(PSpicInitParaLocal->DelayLine))); + //HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, ((DelayLine & (~BIT_MASK_PESOC_FLASH_DDL_CTRL))|DelayLine8bit)); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + /* set ctrlr0: RX_mode */ + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + ((HAL_SPI_READ32(REG_SPIC_CTRLR0)&0xFFF0FFFF) | BIT_TMOD(3))); + + /* set flash_cmd: write cmd to fifo */ + HAL_SPI_WRITE8(REG_SPIC_DR0, cmd); + + /* Enable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + + /* Wait spic busy done */ + SpicWaitBusyDoneRtl8195A(); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + /* Recover rd_dummy_cycle */ + AutoLength = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + AutoLength = AutoLength & 0xFFFF0000; + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, (AutoLength | RdDummyCycle)); + + /* Recover baud rate */ + BaudRate = HAL_SPI_READ32(REG_SPIC_BAUDR); + BaudRate = (BaudRate & (~BIT_MASK_SCKDV)); + HAL_SPI_WRITE32(REG_SPIC_BAUDR, (BaudRate|BaudRate12bit)); + + /* Recover delay line */ + DelayLine = HAL_READ32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL); + DelayLine = (DelayLine & (~BIT_MASK_PESOC_FLASH_DDL_CTRL)); + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_PESOC_MEM_CTRL, (DelayLine|DelayLine8bit)); +} + +/** + * @brief SpicGetFlashStatusRefinedRtl8195A. For the exchange between one- and two- + * bit mode, the spic timing setting (baud, rd_dummy_cycle (ATUO_LENGTH) + * and delay line) should be changed according to the mode used. + * + * @param IN SPIC_INIT_PARA SpicInitPara: spic init parameters with timing setting + * + * @retval u8 flash status register value + */ +HAL_FLASH_TEXT_SECTION +u8 +SpicGetFlashStatusRefinedRtl8195A( + IN SPIC_INIT_PARA SpicInitPara +){ + + u32 RdData; + + DBG_SPIF_INFO("%s(0x%x)\n", __func__, SpicInitPara); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + /* Set Ctrlr1; 1 byte data frames */ + HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(1)); + + /* Send flash RX command and read the data */ + SpicRxCmdRefinedRtl8195A(FLASH_CMD_RDSR, SpicInitPara); + RdData = HAL_SPI_READ8(REG_SPIC_DR0); + + /* Disable SPI_FLASH User Mode */ + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + return RdData; +} + +/** + * @brief SpicInitRefinedRtl8195A. + * + * @param IN u8 InitBaudRate, + * IN u8 SpicBitMode + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicInitRefinedRtl8195A( + IN u8 InitBaudRate, + IN u8 SpicBitMode +){ + + u32 Value32; + SPIC_INIT_PARA SpicInitPara; + PSPIC_INIT_PARA PSpicInitParaLocal; + + PSpicInitParaLocal = &SpicInitPara; +#ifdef CONFIG_FPGA + PSpicInitParaLocal->BaudRate = FPGASpicInitPara.BaudRate; + PSpicInitParaLocal->RdDummyCyle = FPGASpicInitPara.RdDummyCyle; + PSpicInitParaLocal->DelayLine = FPGASpicInitPara.DelayLine; +#else + u8 CpuClk; + + CpuClk = (((u8)(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1) & (0x70))) >> 4); + + if (SpicInitParaAllClk[SpicBitMode][CpuClk].Valid) { + PSpicInitParaLocal = &(SpicInitParaAllClk[SpicBitMode][CpuClk]); + } + else { + SpicLoadInitParaFromClockRtl8195A(CpuClk, 1, PSpicInitParaLocal); + } + +#endif + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + HAL_SPI_WRITE32(REG_SPIC_BAUDR, BIT_SCKDV(InitBaudRate)); + + HAL_SPI_WRITE32(REG_SPIC_SER, BIT_SER); + + Value32 = HAL_SPI_READ32(REG_SPIC_AUTO_LENGTH); + HAL_SPI_WRITE32(REG_SPIC_AUTO_LENGTH, + ((Value32 & 0xFFFF0000) | BIT_RD_DUMMY_LENGTH(PSpicInitParaLocal->RdDummyCyle))); + + HAL_WRITE32(PERI_ON_BASE, REG_PESOC_MEM_CTRL, + ((HAL_READ32(PERI_ON_BASE, REG_PESOC_MEM_CTRL)&0xFFFFFF00)| + PSpicInitParaLocal->DelayLine)); + + HAL_SPI_WRITE32(REG_SPIC_CTRLR1, BIT_NDF(4)); + + + switch (SpicBitMode) { + case SpicOneBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3))))); + break; + + case SpicDualBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) | + (BIT_ADDR_CH(1)|BIT_DATA_CH(1)))); + + break; + + case SpicQuadBitMode: + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + ((HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~(BIT_CMD_CH(3)|BIT_ADDR_CH(3)|BIT_DATA_CH(3)))) | + (BIT_ADDR_CH(2)|BIT_DATA_CH(2)))); + break; + + } +} + + +/** + * @brief SpicEraseFlashRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicEraseFlashRefinedRtl8195A(VOID) +{ + + SPIC_INIT_PARA SpicInitPara; + + // Wait for flash busy done + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + while((SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 0x02)==0) { + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_WREN, 0, 0, SpicInitPara); + } + + DBG_8195A("Erase Cmd Set\n"); + + // Set flash_cmd: Chip_erase to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_CE, SpicInitPara); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_CE, 0, 0, SpicInitPara); + + // polling WEL + do { + } while((SpicGetFlashStatusRefinedRtl8195A(SpicInitPara) & 0x02)!=0); +} + +/** + * @brief SpicSetFlashStatusRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicSetFlashStatusRefinedRtl8195A +( + IN u32 data, + IN SPIC_INIT_PARA SpicInitPara +) +{ + u32 Info; + + Info = HAL_SPI_READ32(REG_SPIC_ADDR_LENGTH); + + // Set flash_cmd: WREN to FIFO + //SpicTxCmdRtl8195A(FLASH_CMD_WREN, SpicInitPara); + SpicTxCmdWithDataRtl8195A(FLASH_CMD_WREN, 0, 0, SpicInitPara); + + // Disable SPI_FLASH + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + // set ctrlr0: TX mode + HAL_SPI_WRITE32(REG_SPIC_CTRLR0, + (HAL_SPI_READ32(REG_SPIC_CTRLR0) & (~ BIT_TMOD(3)))); + + HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, BIT_ADDR_PHASE_LENGTH(1)); + + // Set flash_cmd: WRSR to FIFO + HAL_SPI_WRITE8(REG_SPIC_DR0, BIT_DR0(FLASH_CMD_WRSR)); + + // Set data FIFO + HAL_SPI_WRITE8(REG_SPIC_DR0, BIT_DR0(data)); + + // Enable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, BIT_SPIC_EN); + + // wait spic busy done + SpicWaitBusyDoneRtl8195A(); + + if((SpicInitParaAllClk[0][0].flashtype) == FLASH_MICRON) + SpicWaitOperationDoneRtl8195A(SpicInitPara); + else + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + // Disable SPI_FLASH User Mode + HAL_SPI_WRITE32(REG_SPIC_SSIENR, 0); + + HAL_SPI_WRITE32(REG_SPIC_ADDR_LENGTH, Info); + + // wait flash busy done (wip=0) + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + +} + + +/** + * @brief SpicWaitWipRtl8195A. + * + * @param NA + * + * @retval NA + */ + +HAL_FLASH_TEXT_SECTION +u32 +SpicWaitWipRtl8195A( + VOID +){ + + SPIC_INIT_PARA SpicInitPara; + + /* Check for flash ready status */ + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + return _TRUE; +} + + +/** + * @brief SpicSetFlashStatusRefinedRtl8195A. + * + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +u32 +SpicOneBitCalibrationRtl8195A( + IN u8 SysCpuClk +){ + u32 DefRdDummyCycle = 0; + + + // set auto mode + SpicConfigAutoModeRtl8195A(SpicOneBitMode); + + /* MXIC spec */ + DefRdDummyCycle = 0; + + if (!SpicCalibrationRtl8195A(SpicOneBitMode, DefRdDummyCycle)) { + return _FALSE; + } + +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("@baud:%x\n",SpicInitParaAllClk[0][SysCpuClk].BaudRate); + DBG_8195A("@delay:%x\n",SpicInitParaAllClk[0][SysCpuClk].DelayLine); + DBG_8195A("@dummy:%x\n\n",SpicInitParaAllClk[0][SysCpuClk].RdDummyCyle); +#endif + return _TRUE; +} + +/** + * @brief SpicDisableRtl8195A. + * Disable SPI Flash memory controller. + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION +VOID +SpicDisableRtl8195A(VOID) +{ + SPI_FLASH_PIN_FCTRL(OFF); +} + +#if SPIC_CALIBRATION_IN_NVM +/** + * @brief SpicNVMCalLoad. + * Load the SPI Flash Controller Calibration data from NVM + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION VOID +SpicNVMCalLoad(u8 BitMode, u8 CpuClk) +{ + SPIC_INIT_PARA *pspci_para; + u32 spci_para; + u32 spci_para_inv; + u32 flash_offset; + +// DBG_SPIF_INFO("SpicNVMCalLoad==> BitMode=%d CpuClk=%d\r\n", BitMode, CpuClk); + + /* each Calibration parameters use 8 bytes, first 4-bytes are the calibration data, + 2nd 4-bytes are the validate data: ~(calibration data) */ + flash_offset = (CpuClk * 8) + (BitMode * CPU_CLK_TYPE_NO * 8); + spci_para = HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset)); + if (spci_para != 0xFFFFFFFF) { + spci_para_inv = HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset+4)); + if (0xFFFFFFFF == (spci_para ^ spci_para_inv)) { + pspci_para = (SPIC_INIT_PARA*)&spci_para; + SpicInitParaAllClk[BitMode][CpuClk].BaudRate = pspci_para->BaudRate; + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle = pspci_para->RdDummyCyle; + SpicInitParaAllClk[BitMode][CpuClk].DelayLine = pspci_para->DelayLine; + SpicInitParaAllClk[BitMode][CpuClk].Valid = pspci_para->Valid; + DBG_SPIF_INFO("%s: Calibration Loaded(BitMode %d, CPUClk %d): BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", + __func__, BitMode, CpuClk, + SpicInitParaAllClk[BitMode][CpuClk].BaudRate, + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle, + SpicInitParaAllClk[BitMode][CpuClk].DelayLine); + } + else { + DBG_SPIF_WARN("%s: Data in Flash(@ 0x%x = 0x%x 0x%x) is Invalid\r\n", + __func__, + (FLASH_SPIC_PARA_BASE+flash_offset), spci_para, spci_para_inv); + } + + } + else { +// DBG_SPIF_INFO("SpicNVMCalLoad: No Data in Flash(@ 0x%x)\r\n", flash_offset); + } +} + +/** + * @brief SpicNVMCalLoadAll. + * Load the SPI Flash Controller Calibration data from NVM + * @param NA + * + * @retval NA + */ +HAL_FLASH_TEXT_SECTION VOID +SpicNVMCalLoadAll(void) +{ + u8 i,j; + + for(i=0;i<3;i++) { + for (j=0; j 4 + DBG_SPIF_INFO("%s ==> BitMode=%d CpuClk=%d\r\n", __func__, BitMode, CpuClk); +#endif + /* each Calibration parameters use 8 bytes, first 4-bytes are the calibration data, + 2nd 4-bytes are the validate data: ~(calibration data) */ + flash_offset = (CpuClk * 8) + (BitMode * CPU_CLK_TYPE_NO * 8); + spci_para = HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset)); + if (spci_para == 0xFFFFFFFF) { +// if (1) { + pspci_para = (SPIC_INIT_PARA*)&spci_para; + pspci_para->BaudRate = SpicInitParaAllClk[BitMode][CpuClk].BaudRate; + pspci_para->RdDummyCyle = SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle; + pspci_para->DelayLine = SpicInitParaAllClk[BitMode][CpuClk].DelayLine; + pspci_para->Valid = SpicInitParaAllClk[BitMode][CpuClk].Valid; + HAL_WRITE32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset), spci_para); + + if((SpicInitParaAllClk[BitMode][CpuClk].flashtype) == FLASH_MICRON) + SpicWaitOperationDoneRtl8195A(SpicInitPara); + else + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + + HAL_WRITE32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset+4), ~spci_para); + + if((SpicInitParaAllClk[BitMode][CpuClk].flashtype) == FLASH_MICRON) + SpicWaitOperationDoneRtl8195A(SpicInitPara); + else + SpicWaitWipDoneRefinedRtl8195A(SpicInitPara); + +#if CONFIG_DEBUG_LOG > 4 + DBG_SPIF_INFO("%s(BitMode %d, CPUClk %d): Calibration Stored: BaudRate=0x%x RdDummyCyle=0x%x DelayLine=0x%x\r\n", + __func__, + BitMode, CpuClk, + SpicInitParaAllClk[BitMode][CpuClk].BaudRate, + SpicInitParaAllClk[BitMode][CpuClk].RdDummyCyle, + SpicInitParaAllClk[BitMode][CpuClk].DelayLine); +#endif + // Read back to check + if (HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset)) != spci_para) { + DBG_SPIF_ERR("%s: Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", + __func__, + flash_offset, spci_para, HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset))); + } + + if (HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset+4)) != ~spci_para) { + DBG_SPIF_ERR("%s: Err(Offset=0x%x), Wr=0x%x Rd=0x%x \r\n", + __func__, + flash_offset+4, ~spci_para, HAL_READ32(SPI_FLASH_BASE, (FLASH_SPIC_PARA_BASE+flash_offset+4))); + } + } + else { + // There is a parameter on the flash memory already + DBG_SPIF_ERR("%s: The flash memory(@0x%x = 0x%x) is not able to be write, Erase it first!\r\n", + __func__, + (FLASH_SPIC_PARA_BASE+flash_offset), spci_para); + } +} + +#endif // #if SPIC_CALIBRATION_IN_NVM diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_ssi.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_ssi.c new file mode 100644 index 0000000..96c92f9 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_ssi.c @@ -0,0 +1,689 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +#include "hal_ssi.h" + +#ifdef CONFIG_SOC_PS_EN + +const HAL_GDMA_CHNL Ssi2_TX_GDMA_Chnl_Option[] = { + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + {0,3,GDMA0_CHANNEL3_IRQ,0}, + {0,0,GDMA0_CHANNEL0_IRQ,0}, + {0,1,GDMA0_CHANNEL1_IRQ,0}, + {0,2,GDMA0_CHANNEL2_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Ssi2_RX_GDMA_Chnl_Option[] = { + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + {1,3,GDMA1_CHANNEL3_IRQ,0}, + {1,0,GDMA1_CHANNEL0_IRQ,0}, + {1,1,GDMA1_CHANNEL1_IRQ,0}, + {1,2,GDMA1_CHANNEL2_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Ssi_MultiBlk_GDMA_Chnl_Option[] = { + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + {0xff,0,0,0} // end +}; + +//TODO: Load default Setting: It should be loaded from external setting file. +const DW_SSI_DEFAULT_SETTING SpiDefaultSetting = +{ + .RxCompCallback = NULL, + .RxCompCbPara = NULL, + .RxData = NULL, + .TxCompCallback = NULL, + .TxCompCbPara = NULL, + .TxData = NULL, + .DmaRxDataLevel = 7, // RX FIFO stored bytes > (DMARDLR(7) + 1) then trigger DMA transfer + .DmaTxDataLevel = 48, // TX FIFO free space > (FIFO_SPACE(64)-DMATDLR(48)) then trigger DMA transfer + .InterruptPriority = 10, + .RxLength = 0, + .RxLengthRemainder = 0, + .RxThresholdLevel = 7, // if number of entries in th RX FIFO >= (RxThresholdLevel+1), RX interrupt asserted + .TxLength = 0, + .TxThresholdLevel = 8, // if number of entries in th TX FIFO <= TxThresholdLevel, TX interrupt asserted + .SlaveSelectEnable = 0, + .ClockDivider = SSI_CLK_SPI0_2/1000000, // SCLK=1M + .DataFrameNumber = 0, + .ControlFrameSize = CFS_1_BIT, + .DataFrameFormat = FRF_MOTOROLA_SPI, + .DataFrameSize = DFS_8_BITS, + .DmaControl = 0, // default DMA is disable + .InterruptMask = 0x0, + .MicrowireDirection = MW_DIRECTION_MASTER_TO_SLAVE, + .MicrowireHandshaking = MW_HANDSHAKE_DISABLE, + .MicrowireTransferMode = MW_TMOD_NONSEQUENTIAL, + .SclkPhase = SCPH_TOGGLES_AT_START, + .SclkPolarity = SCPOL_INACTIVE_IS_HIGH, + .SlaveOutputEnable = SLV_TXD_ENABLE, // Slave + .TransferMode = TMOD_TR, + .TransferMechanism = SSI_DTM_INTERRUPT +}; + +extern HAL_Status HalSsiInitRtl8195a_Patch(VOID *Adaptor); +extern HAL_Status HalSsiPinmuxEnableRtl8195a_Patch(VOID *Adaptor); +extern HAL_Status HalSsiPinmuxDisableRtl8195a(VOID *Adaptor); +extern HAL_Status HalSsiDeInitRtl8195a(VOID * Adapter); +extern HAL_Status HalSsiClockOffRtl8195a(VOID * Adapter); +extern HAL_Status HalSsiClockOnRtl8195a(VOID * Adapter); +extern HAL_Status HalSsiIntReadRtl8195a(VOID *Adapter, VOID *RxData, u32 Length); +extern HAL_Status HalSsiIntWriteRtl8195a(VOID *Adapter, u8 *pTxData, u32 Length); +extern HAL_Status HalSsiEnterCriticalRtl8195a(VOID * Data); +extern HAL_Status HalSsiExitCriticalRtl8195a(VOID * Data); +extern HAL_Status HalSsiIsTimeoutRtl8195a(u32 StartCount, u32 TimeoutCnt); +extern HAL_Status HalSsiStopRecvRtl8195a(VOID * Data); +extern HAL_Status HalSsiSetFormatRtl8195a(VOID * Adaptor); +extern VOID HalSsiSetSclkRtl8195a(VOID *Adapter, u32 ClkRate); +#ifdef CONFIG_GDMA_EN +extern VOID HalSsiDmaInitRtl8195a(VOID *Adapter); +#endif + +VOID HalSsiOpInit(VOID *Adaptor) +{ + PHAL_SSI_OP pHalSsiOp = (PHAL_SSI_OP) Adaptor; + +// pHalSsiOp->HalSsiPinmuxEnable = HalSsiPinmuxEnableRtl8195a; +#if CONFIG_CHIP_E_CUT + pHalSsiOp->HalSsiPinmuxEnable = HalSsiPinmuxEnableRtl8195a_V04; + pHalSsiOp->HalSsiPinmuxDisable = HalSsiPinmuxDisableRtl8195a_V04; +#else + pHalSsiOp->HalSsiPinmuxEnable = HalSsiPinmuxEnableRtl8195a_Patch; + pHalSsiOp->HalSsiPinmuxDisable = HalSsiPinmuxDisableRtl8195a; +#endif + + pHalSsiOp->HalSsiEnable = HalSsiEnableRtl8195a; + pHalSsiOp->HalSsiDisable = HalSsiDisableRtl8195a; +// pHalSsiOp->HalSsiInit = HalSsiInitRtl8195a; +#if CONFIG_CHIP_E_CUT + pHalSsiOp->HalSsiInit = HalSsiInitRtl8195a_V04; +#else + pHalSsiOp->HalSsiInit = HalSsiInitRtl8195a_Patch; +#endif + pHalSsiOp->HalSsiSetSclkPolarity = HalSsiSetSclkPolarityRtl8195a; + pHalSsiOp->HalSsiSetSclkPhase = HalSsiSetSclkPhaseRtl8195a; + pHalSsiOp->HalSsiWrite = HalSsiWriteRtl8195a; + pHalSsiOp->HalSsiRead = HalSsiReadRtl8195a; + pHalSsiOp->HalSsiGetRxFifoLevel = HalSsiGetRxFifoLevelRtl8195a; + pHalSsiOp->HalSsiGetTxFifoLevel = HalSsiGetTxFifoLevelRtl8195a; + pHalSsiOp->HalSsiGetStatus = HalSsiGetStatusRtl8195a; + pHalSsiOp->HalSsiGetInterruptStatus = HalSsiGetInterruptStatusRtl8195a; + pHalSsiOp->HalSsiLoadSetting = HalSsiLoadSettingRtl8195a; + pHalSsiOp->HalSsiSetInterruptMask = HalSsiSetInterruptMaskRtl8195a; + pHalSsiOp->HalSsiGetInterruptMask = HalSsiGetInterruptMaskRtl8195a; + pHalSsiOp->HalSsiSetDeviceRole = HalSsiSetDeviceRoleRtl8195a; + pHalSsiOp->HalSsiWriteable = HalSsiWriteableRtl8195a; + pHalSsiOp->HalSsiReadable = HalSsiReadableRtl8195a; + pHalSsiOp->HalSsiBusy = HalSsiBusyRtl8195a; + pHalSsiOp->HalSsiInterruptEnable = HalSsiInterruptEnableRtl8195a; + pHalSsiOp->HalSsiInterruptDisable = HalSsiInterruptDisableRtl8195a; +// pHalSsiOp->HalSsiReadInterrupt = HalSsiReadInterruptRtl8195a; +#if CONFIG_CHIP_E_CUT + pHalSsiOp->HalSsiReadInterrupt = HalSsiIntReadRtl8195a_V04; +#else + pHalSsiOp->HalSsiReadInterrupt = HalSsiIntReadRtl8195a; +#endif + pHalSsiOp->HalSsiSetRxFifoThresholdLevel = HalSsiSetRxFifoThresholdLevelRtl8195a; + pHalSsiOp->HalSsiSetTxFifoThresholdLevel = HalSsiSetTxFifoThresholdLevelRtl8195a; +// pHalSsiOp->HalSsiWriteInterrupt = HalSsiWriteInterruptRtl8195a; +#if CONFIG_CHIP_E_CUT + pHalSsiOp->HalSsiWriteInterrupt = HalSsiIntWriteRtl8195a_V04; +#else + pHalSsiOp->HalSsiWriteInterrupt = HalSsiIntWriteRtl8195a; +#endif + pHalSsiOp->HalSsiGetRawInterruptStatus = HalSsiGetRawInterruptStatusRtl8195a; + pHalSsiOp->HalSsiGetSlaveEnableRegister = HalSsiGetSlaveEnableRegisterRtl8195a; + pHalSsiOp->HalSsiSetSlaveEnableRegister = HalSsiSetSlaveEnableRegisterRtl8195a; +} + + +#ifdef CONFIG_GDMA_EN +HAL_Status +HalSsiTxMultiBlkChnl( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_CONFIG pDmaConfig; + HAL_GDMA_CHNL *pgdma_chnl; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + + if((pHalSsiAdapter->HaveTxChannel == 1) && (pHalGdmaAdapter->ChNum != 4) && (pHalGdmaAdapter->ChNum != 5)){ + HalSsiTxGdmaDeInit(pHalSsiAdapter); + } + if(pHalSsiAdapter->HaveTxChannel == 0){ + pgdma_chnl = HalGdmaChnlAlloc((HAL_GDMA_CHNL*)Ssi_MultiBlk_GDMA_Chnl_Option); + if (pgdma_chnl == NULL) { + DBG_SSI_ERR("No Available DMA channel\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pDmaConfig->TxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + pHalSsiAdapter->HaveTxChannel = 1; + InterruptRegister(&pDmaConfig->TxGdmaIrqHandle); + InterruptEn(&pDmaConfig->TxGdmaIrqHandle); + } + HalSsiDmaInit(pHalSsiAdapter); + } + DBG_SSI_INFO("TX GDMA Index = %x, Channel = %x\n",pHalGdmaAdapter->GdmaIndex,pHalGdmaAdapter->ChNum); + return HAL_OK; +} + +HAL_Status +HalSsiTxSingleBlkChnl( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_CONFIG pDmaConfig; + HAL_GDMA_CHNL *pgdma_chnl; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + + if(pHalSsiAdapter->HaveTxChannel == 0){ + if (HalGdmaChnlRegister(pHalGdmaAdapter->GdmaIndex, pHalGdmaAdapter->ChNum) != HAL_OK) { + // The default GDMA Channel is not available, try others + if (pHalSsiAdapter->Index == 2) { + // SSI2 TX Only can use GDMA 0 + pgdma_chnl = HalGdmaChnlAlloc((HAL_GDMA_CHNL*)Ssi2_TX_GDMA_Chnl_Option); + } + else { + pgdma_chnl = HalGdmaChnlAlloc(NULL); + } + + if (pgdma_chnl == NULL) { + DBG_SSI_ERR("No Available DMA channel\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pDmaConfig->TxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + pHalSsiAdapter->HaveTxChannel = 1; + } + } + else{ + pHalSsiAdapter->HaveTxChannel = 1; + } + InterruptRegister(&pDmaConfig->TxGdmaIrqHandle); + InterruptEn(&pDmaConfig->TxGdmaIrqHandle); + DBG_SSI_INFO("TX GDMA Index = %x, Channle number = %x\n",pHalGdmaAdapter->GdmaIndex,pHalGdmaAdapter->ChNum); + HalSsiDmaInit(pHalSsiAdapter); + } + + return HAL_OK; + +} + +HAL_Status +HalSsiTxGdmaInit( + IN PHAL_SSI_OP pHalSsiOp, + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + + if ((NULL == pHalSsiOp) || (NULL == pHalSsiAdapter)) { + return HAL_ERR_PARA; + } + + // Load default setting + #if CONFIG_CHIP_E_CUT + HalSsiTxGdmaLoadDefRtl8195a_V04((void*)pHalSsiAdapter); + #else + HalSsiTxGdmaLoadDefRtl8195a((void*)pHalSsiAdapter); + #endif + return HAL_OK; +} + +VOID +HalSsiTxGdmaDeInit( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL GdmaChnl; + + if (NULL == pHalSsiAdapter) { + return; + } + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + GdmaChnl.GdmaIndx = pHalGdmaAdapter->GdmaIndex; + GdmaChnl.GdmaChnl = pHalGdmaAdapter->ChNum; + GdmaChnl.IrqNum = pDmaConfig->TxGdmaIrqHandle.IrqNum; + HalGdmaChnlFree(&GdmaChnl); + pHalSsiAdapter->HaveTxChannel = 0; +} + + +HAL_Status +HalSsiDmaSend( + IN VOID *Adapter, // PHAL_SSI_ADAPTOR + IN u8 *pTxData, ///< Rx buffer + IN u32 Length // buffer length +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pTxHalGdmaAdapter; + + #if CONFIG_CHIP_E_CUT + HalSsiDmaSendRtl8195a_V04(pHalSsiAdapter,pTxData,Length); + #else + HalSsiDmaSendRtl8195a(pHalSsiAdapter,pTxData,Length); + #endif + if (pHalGdmaAdapter->GdmaCtl.BlockSize > MAX_DMA_BLOCK_SIZE) { + // Maximum Data Length is 4092*16 + #if CONFIG_CHIP_E_CUT + HalSsiDmaSendMultiBlockRtl8195a_V04(pHalSsiAdapter, pTxData, pHalGdmaAdapter->GdmaCtl.BlockSize); + #else + HalSsiDmaSendMultiBlockRtl8195a(pHalSsiAdapter, pTxData, pHalGdmaAdapter->GdmaCtl.BlockSize); + #endif + HalSsiTxMultiBlkChnl(pHalSsiAdapter); + } + else{ + pHalGdmaAdapter->ChSar= (u32)pTxData; + HalSsiTxSingleBlkChnl(pHalSsiAdapter); + pHalGdmaAdapter->Rsvd4to7 = 0; + pHalGdmaAdapter->Llpctrl = 0; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 0; + pHalGdmaAdapter->GdmaCtl.LlpDstEn = 0; + pHalGdmaAdapter->GdmaCfg.ReloadDst = 0; + pHalGdmaAdapter->GdmaCfg.ReloadSrc = 0; + } + + // Enable GDMA for TX + pHalGdmaOp = (PHAL_GDMA_OP)pDmaConfig->pHalGdmaOp; + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + + if(pHalGdmaAdapter->Llpctrl) + pHalGdmaOp->HalGdmaChBlockSeting((VOID*)(pHalGdmaAdapter)); + else + pHalGdmaOp->HalGdmaChSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; +} + + +HAL_Status +HalSsiRxMultiBlkChnl( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_CONFIG pDmaConfig; + HAL_GDMA_CHNL *pgdma_chnl; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + + if((pHalSsiAdapter->HaveRxChannel == 1) && (pHalGdmaAdapter->ChNum != 4) && (pHalGdmaAdapter->ChNum != 5)){ + HalSsiRxGdmaDeInit(pHalSsiAdapter); + } + if(pHalSsiAdapter->HaveRxChannel == 0){ + pgdma_chnl = HalGdmaChnlAlloc((HAL_GDMA_CHNL*)Ssi_MultiBlk_GDMA_Chnl_Option); + if (pgdma_chnl == NULL) { + DBG_SSI_ERR("No Available DMA channel\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pDmaConfig->RxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + pHalSsiAdapter->HaveRxChannel = 1; + InterruptRegister(&pDmaConfig->RxGdmaIrqHandle); + InterruptEn(&pDmaConfig->RxGdmaIrqHandle); + } + HalSsiDmaInit(pHalSsiAdapter); + } + DBG_SSI_INFO("RX GDMA index = %x, Channel = %x\n",pHalGdmaAdapter->GdmaIndex,pHalGdmaAdapter->ChNum); + return HAL_OK; +} + +HAL_Status +HalSsiRxSingleBlkChnl( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PSSI_DMA_CONFIG pDmaConfig; + HAL_GDMA_CHNL *pgdma_chnl; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + + if(pHalSsiAdapter->HaveRxChannel == 0){ + if (HalGdmaChnlRegister(pHalGdmaAdapter->GdmaIndex, pHalGdmaAdapter->ChNum) != HAL_OK) { + // The default GDMA Channel is not available, try others + if (pHalSsiAdapter->Index == 2) { + // SSI2 RX Only can use GDMA 1 + pgdma_chnl = HalGdmaChnlAlloc((HAL_GDMA_CHNL*)Ssi2_RX_GDMA_Chnl_Option); + } + else { + pgdma_chnl = HalGdmaChnlAlloc(NULL); + } + + if (pgdma_chnl == NULL) { + DBG_SSI_ERR("No Available DMA channel\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pDmaConfig->RxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + pHalSsiAdapter->HaveRxChannel = 1; + } + } + else{ + pHalSsiAdapter->HaveRxChannel = 1; + } + InterruptRegister(&pDmaConfig->RxGdmaIrqHandle); + InterruptEn(&pDmaConfig->RxGdmaIrqHandle); + DBG_SSI_INFO("RX GDMA Index = %x, Channle number = %x\n",pHalGdmaAdapter->GdmaIndex,pHalGdmaAdapter->ChNum); + HalSsiDmaInit(pHalSsiAdapter); + } + return HAL_OK; + +} + +HAL_Status +HalSsiRxGdmaInit( + IN PHAL_SSI_OP pHalSsiOp, + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + + if ((NULL == pHalSsiOp) || (NULL == pHalSsiAdapter)) { + return HAL_ERR_PARA; + } + + // Load default setting + #if CONFIG_CHIP_E_CUT + HalSsiRxGdmaLoadDefRtl8195a_V04((void*)pHalSsiAdapter); + #else + HalSsiRxGdmaLoadDefRtl8195a((void*)pHalSsiAdapter); + #endif + return HAL_OK; +} + +VOID +HalSsiRxGdmaDeInit( + IN PHAL_SSI_ADAPTOR pHalSsiAdapter +) +{ + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL GdmaChnl; + + if (NULL == pHalSsiAdapter) { + return; + } + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + GdmaChnl.GdmaIndx = pHalGdmaAdapter->GdmaIndex; + GdmaChnl.GdmaChnl = pHalGdmaAdapter->ChNum; + GdmaChnl.IrqNum = pDmaConfig->RxGdmaIrqHandle.IrqNum; + HalGdmaChnlFree(&GdmaChnl); + pHalSsiAdapter->HaveRxChannel = 0; +} + +HAL_Status +HalSsiDmaRecv( + IN VOID *Adapter, // PHAL_SSI_ADAPTOR + IN u8 *pRxData, ///< Rx buffer + IN u32 Length // buffer length +) +{ + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Adapter; + PSSI_DMA_CONFIG pDmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + PHAL_GDMA_OP pHalGdmaOp; + + pDmaConfig = &pHalSsiAdapter->DmaConfig; + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pDmaConfig->pRxHalGdmaAdapter; + + #if CONFIG_CHIP_E_CUT + HalSsiDmaRecvRtl8195a_V04(pHalSsiAdapter,pRxData,Length); + #else + HalSsiDmaRecvRtl8195a(pHalSsiAdapter,pRxData,Length); + #endif + + if (pHalGdmaAdapter->GdmaCtl.BlockSize > MAX_DMA_BLOCK_SIZE) { + // Maximum Data Length is 4092*16 + #if CONFIG_CHIP_E_CUT + HalSsiDmaRecvMultiBlockRtl8195a_V04(pHalSsiAdapter, pRxData, pHalGdmaAdapter->GdmaCtl.BlockSize); + #else + HalSsiDmaRecvMultiBlockRtl8195a(pHalSsiAdapter, pRxData, pHalGdmaAdapter->GdmaCtl.BlockSize); + #endif + HalSsiRxMultiBlkChnl(pHalSsiAdapter); + } + else{ + pHalGdmaAdapter->ChDar = (u32)pRxData; + HalSsiRxSingleBlkChnl(pHalSsiAdapter); + pHalGdmaAdapter->Rsvd4to7 = 0; + pHalGdmaAdapter->Llpctrl = 0; + pHalGdmaAdapter->GdmaCtl.LlpSrcEn = 0; + pHalGdmaAdapter->GdmaCtl.LlpDstEn = 0; + pHalGdmaAdapter->GdmaCfg.ReloadDst = 0; + pHalGdmaAdapter->GdmaCfg.ReloadSrc = 0; + + } + + // Enable GDMA for RX + pHalGdmaOp = (PHAL_GDMA_OP)pDmaConfig->pHalGdmaOp; + pHalGdmaOp->HalGdmaOnOff((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChIsrEnAndDis((VOID*)(pHalGdmaAdapter)); + + if(pHalGdmaAdapter->Llpctrl) + pHalGdmaOp->HalGdmaChBlockSeting((VOID*)(pHalGdmaAdapter)); + else + pHalGdmaOp->HalGdmaChSeting((VOID*)(pHalGdmaAdapter)); + pHalGdmaOp->HalGdmaChEn((VOID*)(pHalGdmaAdapter)); + + return HAL_OK; + +} + +#endif // end of "#ifdef CONFIG_GDMA_EN" + +HAL_Status +HalSsiInit(VOID *Data) +{ + HAL_Status ret; + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; + u32 Function; + u8 PinmuxSelect; + u8 Index; + + PinmuxSelect = pHalSsiAdapter->PinmuxSelect; + Index = pHalSsiAdapter->Index; + switch (Index){ + case 0: + Function = SPI0; + break; + case 1: + Function = SPI1; + break; + case 2: + Function = SPI2; + break; + default: + DBG_SSI_ERR("Invalid SPI Index.\n"); + break; + } + + ret = FunctionChk(Function, (u32)PinmuxSelect); + if(ret == _FALSE){ + DBG_SSI_ERR("Invalid Pinmux Setting.\n"); + return HAL_ERR_PARA; + } + +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE SsiPwrState; +#endif +#if CONFIG_CHIP_E_CUT + ret = HalSsiInitRtl8195a_V04(pHalSsiAdapter); +#else + ret = HalSsiInitRtl8195a_Patch(pHalSsiAdapter); +#endif +#ifdef CONFIG_SOC_PS_MODULE + if(ret == HAL_OK) { + // To register a new peripheral device power state + SsiPwrState.FuncIdx = SPI0+ pHalSsiAdapter->Index; + SsiPwrState.PwrState = ACT; + RegPowerState(SsiPwrState); + } +#endif + + return ret; +} + +HAL_Status +HalSsiDeInit(VOID *Data) +{ + HAL_Status ret; + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE SsiPwrState; + u8 HardwareState; + + SsiPwrState.FuncIdx= SPI0+ pHalSsiAdapter->Index; + QueryRegPwrState(SsiPwrState.FuncIdx, &(SsiPwrState.PwrState), &HardwareState); + + if(SsiPwrState.PwrState != HardwareState){ + DBG_SSI_ERR("Registered State is not the Hardware State"); + return HAL_ERR_UNKNOWN; + } + else{ + if((SsiPwrState.PwrState != INACT) && (SsiPwrState.PwrState !=ACT)){ + DBG_SSI_INFO("Return to ACT state before DeInit"); + HalSsiEnable(pHalSsiAdapter); + QueryRegPwrState(SsiPwrState.FuncIdx, &(SsiPwrState.PwrState), &HardwareState); + } + if(SsiPwrState.PwrState == ACT){ + SsiPwrState.PwrState = INACT; + RegPowerState(SsiPwrState); + } + } +#endif +#if CONFIG_CHIP_E_CUT + ret = HalSsiDeInitRtl8195a_V04(pHalSsiAdapter); +#else + ret = HalSsiDeInitRtl8195a(pHalSsiAdapter); +#endif + return ret; +} + + +HAL_Status +HalSsiEnable(VOID *Data) +{ + HAL_Status ret; + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE SsiPwrState; +#endif +#if CONFIG_CHIP_E_CUT + ret = HalSsiClockOnRtl8195a_V04(pHalSsiAdapter); +#else + ret = HalSsiClockOnRtl8195a(pHalSsiAdapter); +#endif +#ifdef CONFIG_SOC_PS_MODULE + if(ret == HAL_OK) { + // To register a new peripheral device power state + SsiPwrState.FuncIdx = SPI0+ pHalSsiAdapter->Index; + SsiPwrState.PwrState = ACT; + RegPowerState(SsiPwrState); + } +#endif + + return ret; +} + +HAL_Status +HalSsiDisable(VOID *Data) +{ + HAL_Status ret; + PHAL_SSI_ADAPTOR pHalSsiAdapter = (PHAL_SSI_ADAPTOR) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE SsiPwrState; +#endif +#if CONFIG_CHIP_E_CUT + ret = HalSsiClockOffRtl8195a_V04(pHalSsiAdapter); +#else + ret = HalSsiClockOffRtl8195a(pHalSsiAdapter); +#endif +#ifdef CONFIG_SOC_PS_MODULE + if(ret == HAL_OK) { + // To register a new peripheral device power state + SsiPwrState.FuncIdx = SPI0+ pHalSsiAdapter->Index; + SsiPwrState.PwrState = SLPCG; + RegPowerState(SsiPwrState); + } +#endif + + return ret; +} + +HAL_Status HalSsiEnterCritical(VOID *Data) +{ + return HalSsiEnterCriticalRtl8195a(Data); +} + +HAL_Status HalSsiExitCritical(VOID *Data) +{ + return HalSsiExitCriticalRtl8195a(Data); +} + +HAL_Status HalSsiTimeout(u32 StartCount, u32 TimeoutCnt) +{ + return HalSsiIsTimeoutRtl8195a(StartCount,TimeoutCnt); +} + +HAL_Status HalSsiStopRecv(VOID * Data) +{ + return HalSsiStopRecvRtl8195a(Data); +} + +HAL_Status HalSsiSetFormat(VOID * Data) +{ + return HalSsiSetFormatRtl8195a(Data); +} + +#endif // CONFIG_SOC_PS_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_timer.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_timer.c new file mode 100644 index 0000000..9a390db --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_timer.c @@ -0,0 +1,38 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" + +#ifdef CONFIG_TIMER_EN +VOID +HalTimerOpInit_Patch( + IN VOID *Data +) +{ + PHAL_TIMER_OP pHalTimerOp = (PHAL_TIMER_OP) Data; + + pHalTimerOp->HalGetTimerId = HalGetTimerIdRtl8195a; +#ifdef CONFIG_CHIP_E_CUT + pHalTimerOp->HalTimerInit = (BOOL (*)(void*))HalTimerInitRtl8195a_V04; +#else + pHalTimerOp->HalTimerInit = (BOOL (*)(void*))HalTimerInitRtl8195a_Patch; +#endif +#if defined(CONFIG_CHIP_C_CUT) || defined(CONFIG_CHIP_E_CUT) + pHalTimerOp->HalTimerReadCount = HalTimerReadCountRtl8195aV02; +#else + pHalTimerOp->HalTimerReadCount = HalTimerReadCountRtl8195a_Patch; +#endif + pHalTimerOp->HalTimerIrqClear = HalTimerIrqClearRtl8195a; + pHalTimerOp->HalTimerDis = HalTimerDisRtl8195a_Patch; + pHalTimerOp->HalTimerEn = HalTimerEnRtl8195a_Patch; + pHalTimerOp->HalTimerDumpReg = HalTimerDumpRegRtl8195a; +} + +#endif // CONFIG_TIMER_EN diff --git a/USDK/component/soc/realtek/8195a/fwlib/src/hal_uart.c b/USDK/component/soc/realtek/8195a/fwlib/src/hal_uart.c new file mode 100644 index 0000000..2b3fe3c --- /dev/null +++ b/USDK/component/soc/realtek/8195a/fwlib/src/hal_uart.c @@ -0,0 +1,1112 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + + +#include "rtl8195a.h" +#include "rtl8195a_uart.h" +#include "hal_uart.h" +#include "hal_gdma.h" + +#ifdef CONFIG_UART_EN + +#ifndef CONFIG_CHIP_E_CUT +// Pre-Defined Supported Baud Rate Table for CPU 166 MHz +const u32 DEF_BAUDRATE_TABLE[] = { + 110, 300, 600, 1200, + 2400, 4800, 9600, 14400, + 19200, 28800, 38400, 57600, + 76800, 115200, 128000, 153600, + 230400, 380400, 460800, 500000, + 921600, 1000000, 1382400, 1444400, + 1500000, 1843200, 2000000, 2100000, + 2764800, 3000000, 3250000, 3692300, + 3750000, 4000000, 6000000, + + 56000, 256000, + + // For UART to IR Carrier + 66000, 72000, 73400, 76000, + 80000, 112000, + + // End of the table + 0xffffffff +}; + +const u16 ovsr_adj_table_10bit[10] = { + 0x000, 0x020, 0x044, 0x124, 0x294, 0x2AA, 0x16B, 0x2DB, 0x3BB, 0x3EF +}; + +const u16 ovsr_adj_table_9bit[9] = { + 0x000, 0x010, 0x044, 0x92, 0xAA, 0x155, 0x1B6, 0x1BB, 0x1EF +}; + +const u16 ovsr_adj_table_8bit[8] = { + 0x000, 0x010, 0x044, 0x92, 0xAA, 0xB5, 0xBB, 0xEF +}; + +#if 0 // Old format +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +const u8 DEF_OVSR_166[] = { + 10, 10, 12, 14, + 10, 10, 10, 11, + 14, 11, 14, 11, + 14, 10, 11, 14, + 18, 17, 17, 18, + 17, 13, 19, 18, + 10, 11, 13, 19, + 14, 13, 12, 11, + 10, 10, 13, + + 20, 18, + + // For UART to IR Carrier + 13, 13, 18, 15, + 20, 12, +}; + +const u16 DEF_DIV_166[] = { + 74272, 27233, 11347, 4863, + 3404, 1702, 851, 516, + 304, 258, 152, 129, + 76, 71, 58, 38, + 19, 12, 10, 9, + 5, 6, 3, 3, + 5, 4, 3, 2, + 2, 2, 2, 2, + 2, 2, 1, + + 73, 17, + + // For UART to IR Carrier + 97, 89, 63, 73, + 52, 62, +}; + + +const u16 DEF_OVSR_ADJ_166[] = { + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, + 0x2AA, 0x3BB, 0x1B6, 0x010, + 0x1B6, 0x2AA, 0x1B6, 0x2DB, + 0x3BB, 0x000, 0x2AA, 0x294, + 0x2DB, 0x2AA, 0x2AA, 0x000 , + 0x3BB, 0x088, 0x2AA, + + 0x000, 0x2DB, + + // For UART to IR Carrier + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000 +}; +#endif //#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +#ifdef CONFIG_CHIP_C_CUT + +const u8 DEF_OVSR_166[] = { + 13, 12, 12, 12, + 18, 10, 10, 11, + 10, 11, 10, 20, + 20, 20, 20, 20, + 20, 18, 20, 12, + 15, 16, 20, 19, + 18, 15, 10, 13, + 15, 13, 12, 11, + 11, 10, 13, + + 16, 18, + + // For UART to IR Carrier + 13, 13, 18, 15, + 20, 12, +}; + +const u16 DEF_DIV_166[] = { + 58275, 23148, 11574, 5787, + 1929, 1736, 868, 526, + 434, 263, 217, 72, + 54, 36, 32, 27, + 18, 12, 9, 13, + 6, 5, 3, 3, + 3, 3, 4, 3, + 2, 2, 2, 2, + 2, 2, 1, + + 93, 18, + + // For UART to IR Carrier + 97, 89, 63, 73, + 52, 62, +}; + +const u16 DEF_OVSR_ADJ_166[] = { + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x010, + 0x010, 0x010, 0x124, 0x010, + 0x010, 0x088, 0x010, 0x2DB, + 0x000, 0x16B, 0x010, 0x088, + 0x2AA, 0x000, 0x294, 0x088, + 0x000, 0x3BB, 0x3BB, 0x088, + 0x010, 0x294, 0x3BB, + + 0x000, 0x010, + + // For UART to IR Carrier + 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000 +}; + +#endif // #ifdef CONFIG_CHIP_C_CUT +#endif // end of #if 0 // Old format + +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) +const u8 DEF_OVSR_B_CUT[] = { + 20, 20, 20, 20, + 20, 20, 15, 18, + 13, 15, 18, 13, + 18, 12, 11, 10, + 16, 15, 16, 18, + 11, 20, 19, 14, + 18, 11, 20, 19, + 14, 13, 12, 11, + 21, 20, 13, + + 18, 11, + + // For UART to IR Carrier + 13, 13, 18, 15, + 20, 12 + +}; + +const u16 DEF_DIV_B_CUT[] = { + 37202, 13616, 6808, 3404, + 1702, 851, 567, 315, + 327, 189, 118, 109, + 59, 59, 58, 53, + 22, 14, 11, 9, + 8, 4, 3, 4, + 3, 4, 2, 2, + 2, 2, 2, 2, + 1, 1, 1, + + 81, 29, + + // For UART to IR Carrier + 97, 89, 63, 73, + 52, 62 +}; + +const u8 DEF_OVSR_ADJ_BITS_B_CUT_10B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 3, 1, 2, + 1, 4, 7, 1, + 2, 1, 4, 5, + 8, 6, 6, 1, + 8, 4, 6, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 + +}; + +const u8 DEF_OVSR_ADJ_BITS_B_CUT_9B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 3, 1, 1, + 1, 4, 6, 1, + 1, 1, 4, 4, + 7, 6, 5, 1, + 7, 4, 6, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 + +}; + +const u8 DEF_OVSR_ADJ_BITS_B_CUT_8B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 3, 1, 1, + 1, 4, 6, 1, + 1, 1, 4, 4, + 6, 5, 5, 1, + 6, 4, 5, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 +}; + +#endif // #if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + +const u8 DEF_OVSR_C_CUT[] = { + 20, 20, 20, 20, + 20, 20, 20, 14, + 20, 12, 14, 19, + 19, 19, 13, 20, + 19, 18, 20, 15, + 18, 20, 20, 19, + 11, 15, 20, 13, + 15, 13, 12, 11, + 11, 20, 13, + + 16, 13, + + // For UART to IR Carrier + 13, 13, 18, 15, + 20, 12 +}; + +const u16 DEF_DIV_C_CUT[] = { + 37878, 13888, 6944, 3472, + 1736, 868, 434, 413, + 217, 241, 155, 76, + 57, 38, 50, 27, + 19, 12, 9, 11, + 5, 4, 3, 3, + 5, 3, 2, 3, + 2, 2, 2, 2, + 2, 1, 1, + + 93, 25, + + // For UART to IR Carrier + 97, 89, 63, 73, + 52, 62 +}; + +const u8 DEF_OVSR_ADJ_BITS_C_CUT_10B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 3, 1, 2, + 1, 8, 1, 2, + 1, 1, 8, 2, + 1, 9, 8, 3, + 1, 8, 9, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 + +}; + +const u8 DEF_OVSR_ADJ_BITS_C_CUT_9B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 2, 1, 1, + 1, 8, 1, 2, + 1, 1, 8, 2, + 1, 8, 8, 3, + 1, 8, 8, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 + +}; + +const u8 DEF_OVSR_ADJ_BITS_C_CUT_8B[] = { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 2, 1, 1, + 1, 7, 1, 2, + 1, 1, 7, 2, + 1, 7, 7, 2, + 1, 7, 7, + + 0, 0, + + // For UART to IR Carrier + 0, 0, 0, 0, + 0, 0 +}; +#else +extern const u32 DEF_BAUDRATE_TABLE_ROM[]; +extern const u16 ovsr_adj_table_10bit_rom[10]; +extern const u16 ovsr_adj_table_9bit_rom[9]; +extern const u16 ovsr_adj_table_8bit_rom[8]; +extern const u8 DEF_OVSR_ROM[]; +extern const u16 DEF_DIV_ROM[]; +extern const u8 DEF_OVSR_ADJ_10BITS_ROM[]; +extern const u8 DEF_OVSR_ADJ_9BITS_ROM[]; +extern const u8 DEF_OVSR_ADJ_8BITS_ROM[]; + +#endif // #if !(CONFIG_CHIP_E_CUT) + +extern u32 _UartIrqHandle(VOID *Data); + +extern HAL_Status +HalRuartInitRtl8195a_Patch( + IN VOID *Data ///< RUART Adapter + ); + +#if (CONFIG_CHIP_C_CUT) +extern _LONG_CALL_ HAL_Status +HalRuartInitRtl8195aV02( + IN VOID *Data ///< RUART Adapter + ); +#endif + +extern u8 HalRuartGetChipVerRtl8195a(VOID); + +const HAL_GDMA_CHNL Uart2_TX_GDMA_Chnl_Option[] = { + {0,0,GDMA0_CHANNEL0_IRQ,0}, + {0,1,GDMA0_CHANNEL1_IRQ,0}, + {0,2,GDMA0_CHANNEL2_IRQ,0}, + {0,3,GDMA0_CHANNEL3_IRQ,0}, + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Uart2_RX_GDMA_Chnl_Option[] = { + {1,0,GDMA1_CHANNEL0_IRQ,0}, + {1,1,GDMA1_CHANNEL1_IRQ,0}, + {1,2,GDMA1_CHANNEL2_IRQ,0}, + {1,3,GDMA1_CHANNEL3_IRQ,0}, + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Uart_GDMA_MB_Chnl_Option[] = { + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Uart2_TX_GDMA_MB_Chnl_Option[] = { + {0,4,GDMA0_CHANNEL4_IRQ,0}, + {0,5,GDMA0_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + +const HAL_GDMA_CHNL Uart2_RX_GDMA_MB_Chnl_Option[] = { + {1,4,GDMA1_CHANNEL4_IRQ,0}, + {1,5,GDMA1_CHANNEL5_IRQ,0}, + + {0xff,0,0,0} // end +}; + + +VOID +HalRuartOpInit( + IN VOID *Data +) +{ + PHAL_RUART_OP pHalRuartOp = (PHAL_RUART_OP) Data; + + pHalRuartOp->HalRuartAdapterLoadDef = HalRuartAdapterLoadDefRtl8195a; + pHalRuartOp->HalRuartTxGdmaLoadDef = HalRuartTxGdmaLoadDefRtl8195a; + pHalRuartOp->HalRuartRxGdmaLoadDef = HalRuartRxGdmaLoadDefRtl8195a; + pHalRuartOp->HalRuartResetRxFifo = HalRuartResetRxFifoRtl8195a_Patch; +#if CONFIG_CHIP_E_CUT + pHalRuartOp->HalRuartInit = HalRuartInitRtl8195a_V04; +#else + pHalRuartOp->HalRuartInit = HalRuartInitRtl8195a_Patch; // Hardware Init ROM code patch +#endif + pHalRuartOp->HalRuartDeInit = HalRuartDeInitRtl8195a; // Hardware Init + pHalRuartOp->HalRuartPutC = HalRuartPutCRtl8195a; // Send a byte + pHalRuartOp->HalRuartSend = HalRuartSendRtl8195a; // Polling mode Tx + pHalRuartOp->HalRuartIntSend = HalRuartIntSendRtl8195a; // Interrupt mode Tx +#if CONFIG_CHIP_E_CUT + pHalRuartOp->HalRuartDmaSend = HalRuartDmaSendRtl8195a_V04; // DMA mode Tx + pHalRuartOp->HalRuartStopSend = HalRuartStopSendRtl8195a_V04; // Stop non-blocking TX +#else + pHalRuartOp->HalRuartDmaSend = HalRuartDmaSendRtl8195a_Patch; // DMA mode Tx + pHalRuartOp->HalRuartStopSend = HalRuartStopSendRtl8195a_Patch; // Stop non-blocking TX +#endif + pHalRuartOp->HalRuartGetC = HalRuartGetCRtl8195a; // get a byte + pHalRuartOp->HalRuartRecv = HalRuartRecvRtl8195a; // Polling mode Rx + pHalRuartOp->HalRuartIntRecv = HalRuartIntRecvRtl8195a; // Interrupt mode Rx + pHalRuartOp->HalRuartDmaRecv = HalRuartDmaRecvRtl8195a; // DMA mode Rx +#if CONFIG_CHIP_E_CUT + pHalRuartOp->HalRuartStopRecv = HalRuartStopRecvRtl8195a_V04; // Stop non-blocking Rx +#else + pHalRuartOp->HalRuartStopRecv = HalRuartStopRecvRtl8195a_Patch; // Stop non-blocking Rx +#endif + pHalRuartOp->HalRuartGetIMR = HalRuartGetIMRRtl8195a; + pHalRuartOp->HalRuartSetIMR = HalRuartSetIMRRtl8195a; + pHalRuartOp->HalRuartGetDebugValue = HalRuartGetDebugValueRtl8195a; + pHalRuartOp->HalRuartDmaInit = HalRuartDmaInitRtl8195a; + pHalRuartOp->HalRuartRTSCtrl = HalRuartRTSCtrlRtl8195a; + pHalRuartOp->HalRuartRegIrq = HalRuartRegIrqRtl8195a; + pHalRuartOp->HalRuartIntEnable = HalRuartIntEnableRtl8195a; + pHalRuartOp->HalRuartIntDisable = HalRuartIntDisableRtl8195a; +} + +/** + * Load UART HAL default setting + * + * Call this function to load the default setting for UART HAL adapter + * + * + */ +VOID +HalRuartAdapterInit( + PRUART_ADAPTER pRuartAdapter, + u8 UartIdx +) +{ + PHAL_RUART_OP pHalRuartOp; + PHAL_RUART_ADAPTER pHalRuartAdapter; + + if (NULL == pRuartAdapter) { + return; + } + + pHalRuartOp = pRuartAdapter->pHalRuartOp; + pHalRuartAdapter = pRuartAdapter->pHalRuartAdapter; + + if ((NULL == pHalRuartOp) || (NULL == pHalRuartAdapter)) { + return; + } + + // Load default setting + if (pHalRuartOp->HalRuartAdapterLoadDef != NULL) { + pHalRuartOp->HalRuartAdapterLoadDef (pHalRuartAdapter, UartIdx); + pHalRuartAdapter->IrqHandle.Priority = 10; + } + else { + // Initial your UART HAL adapter here + } + + // Start to modify the defualt setting + pHalRuartAdapter->PinmuxSelect = RUART0_MUX_TO_GPIOC; + pHalRuartAdapter->BaudRate = 38400; + +// pHalRuartAdapter->IrqHandle.IrqFun = (IRQ_FUN)_UartIrqHandle; +// pHalRuartAdapter->IrqHandle.Data = (void *)pHalRuartAdapter; + + // Register IRQ + InterruptRegister(&pHalRuartAdapter->IrqHandle); + +} + +/** + * Load UART HAL GDMA default setting + * + * Call this function to load the default setting for UART GDMA + * + * + */ +HAL_Status +HalRuartTxGdmaInit( + PHAL_RUART_ADAPTER pHalRuartAdapter, + PUART_DMA_CONFIG pUartGdmaConfig, + u8 IsMultiBlk +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL *pgdma_chnl; + HAL_GDMA_CHNL *pgdma_chnl_tbl=NULL; + UART_DMA_MULTIBLK *pDmaBlkList; + + if ((NULL == pHalRuartAdapter) || (NULL == pUartGdmaConfig)) { + return HAL_ERR_PARA; + } + + // Load default setting + HalRuartTxGdmaLoadDefRtl8195a (pHalRuartAdapter, pUartGdmaConfig); + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + if (IsMultiBlk) { + // need to allocate a multiple block channel + if (pHalRuartAdapter->UartIndex != 2) { + pgdma_chnl_tbl = (HAL_GDMA_CHNL*)Uart_GDMA_MB_Chnl_Option; + } else { + // UART2 TX Only can use GDMA 0 + pgdma_chnl_tbl = (HAL_GDMA_CHNL*)Uart2_TX_GDMA_MB_Chnl_Option; + } + // Default use the 1st channel of the table + pgdma_chnl = pgdma_chnl_tbl; + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pUartGdmaConfig->TxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + } else { + if (pHalRuartAdapter->UartIndex == 2) { + // UART2 TX Only can use GDMA 0 + pgdma_chnl_tbl = (HAL_GDMA_CHNL *)Uart2_TX_GDMA_Chnl_Option; + } + } + + // Start to patch the default setting + if (HalGdmaChnlRegister(pHalGdmaAdapter->GdmaIndex, pHalGdmaAdapter->ChNum) != HAL_OK) { + // The default GDMA Channel is not available, try others + pgdma_chnl = HalGdmaChnlAlloc(pgdma_chnl_tbl); + + if (pgdma_chnl == NULL) { + // No Available DMA channel + DBG_UART_WARN("HalRuartTxGdmaInit: Allocate DMA Channel Failed\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pUartGdmaConfig->TxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + } + } + + // User can assign a Interrupt Handler here +// pUartGdmaConfig->TxGdmaIrqHandle.Data = pHalRuartAdapter; +// pUartGdmaConfig->TxGdmaIrqHandle.IrqFun = (IRQ_FUN)_UartTxDmaIrqHandle +// pUartGdmaConfig->TxGdmaIrqHandle.Priority = 12; + pUartGdmaConfig->TxGdmaIrqHandle.Priority = 12; +#if CONFIG_CHIP_E_CUT + pUartGdmaConfig->TxGdmaIrqHandle.IrqFun = (IRQ_FUN)_UartTxDmaIrqHandle_V04; +#else + pUartGdmaConfig->TxGdmaIrqHandle.IrqFun = (IRQ_FUN)_UartTxDmaIrqHandle_Patch; +#endif + HalRuartDmaInitRtl8195a (pHalRuartAdapter); + InterruptRegister(&pUartGdmaConfig->TxGdmaIrqHandle); + InterruptEn(&pUartGdmaConfig->TxGdmaIrqHandle); + pUartGdmaConfig->TxDmaMBChnl = IsMultiBlk; + + if (IsMultiBlk) { + pDmaBlkList = pUartGdmaConfig->pTxDmaBlkList; + if (NULL != pDmaBlkList) { + pHalGdmaAdapter->pBlockSizeList = (struct BLOCK_SIZE_LIST*) &(pDmaBlkList->BlockSizeList); + pHalGdmaAdapter->pLlix = (struct GDMA_CH_LLI*) &(pDmaBlkList->Lli); + } else { + DBG_UART_WARN("HalRuartTxGdmaInit: no Block List for DMA\n"); + } + } + + return HAL_OK; +} + +VOID +HalRuartTxGdmaDeInit( + PUART_DMA_CONFIG pUartGdmaConfig +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL GdmaChnl; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pTxHalGdmaAdapter; + GdmaChnl.GdmaIndx = pHalGdmaAdapter->GdmaIndex; + GdmaChnl.GdmaChnl = pHalGdmaAdapter->ChNum; + GdmaChnl.IrqNum = pUartGdmaConfig->TxGdmaIrqHandle.IrqNum; + HalGdmaChnlFree(&GdmaChnl); + pUartGdmaConfig->TxDmaMBChnl = 0; +} + +/** + * Load UART HAL GDMA default setting + * + * Call this function to load the default setting for UART GDMA + * + * + */ +HAL_Status +HalRuartRxGdmaInit( + PHAL_RUART_ADAPTER pHalRuartAdapter, + PUART_DMA_CONFIG pUartGdmaConfig, + u8 IsMultiBlk +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL *pgdma_chnl; + HAL_GDMA_CHNL *pgdma_chnl_tbl=NULL; + UART_DMA_MULTIBLK *pDmaBlkList; + + if ((NULL == pHalRuartAdapter) || (NULL == pUartGdmaConfig)) { + return HAL_ERR_PARA; + } + + // Load default setting + HalRuartRxGdmaLoadDefRtl8195a (pHalRuartAdapter, pUartGdmaConfig); + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + if (IsMultiBlk) { + // need to allocate a multiple block channel + if (pHalRuartAdapter->UartIndex != 2) { + pgdma_chnl_tbl = (HAL_GDMA_CHNL *)Uart_GDMA_MB_Chnl_Option; + } else { + // UART2 RX Only can use GDMA 1 + pgdma_chnl_tbl = (HAL_GDMA_CHNL *)Uart2_RX_GDMA_MB_Chnl_Option; + } + // Default use the 1st channel of the table + pgdma_chnl = pgdma_chnl_tbl; + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pUartGdmaConfig->RxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + } else { + if (pHalRuartAdapter->UartIndex == 2) { + // UART2 RX Only can use GDMA 1 + pgdma_chnl_tbl = (HAL_GDMA_CHNL *)Uart2_RX_GDMA_Chnl_Option; + } + } + + // Start to patch the default setting + if (HalGdmaChnlRegister(pHalGdmaAdapter->GdmaIndex, pHalGdmaAdapter->ChNum) != HAL_OK) { + // The default GDMA Channel is not available, try others + pgdma_chnl = HalGdmaChnlAlloc((HAL_GDMA_CHNL*)pgdma_chnl_tbl); + if (pgdma_chnl == NULL) { + // No Available DMA channel + DBG_UART_WARN("HalRuartRxGdmaInit: Allocate DMA Channel Failed\n"); + return HAL_BUSY; + } + else { + pHalGdmaAdapter->GdmaIndex = pgdma_chnl->GdmaIndx; + pHalGdmaAdapter->ChNum = pgdma_chnl->GdmaChnl; + pHalGdmaAdapter->ChEn = 0x0101 << pgdma_chnl->GdmaChnl; + pUartGdmaConfig->RxGdmaIrqHandle.IrqNum = pgdma_chnl->IrqNum; + } + } + +// pUartGdmaConfig->RxGdmaIrqHandle.Data = pHalRuartAdapter; +#if CONFIG_CHIP_E_CUT + pUartGdmaConfig->RxGdmaIrqHandle.IrqFun = (IRQ_FUN)_UartRxDmaIrqHandle_V04; +#else + pUartGdmaConfig->RxGdmaIrqHandle.IrqFun = (IRQ_FUN)_UartRxDmaIrqHandle_Patch; +#endif + pUartGdmaConfig->RxGdmaIrqHandle.Priority = 11; + + HalRuartDmaInitRtl8195a (pHalRuartAdapter); + InterruptRegister(&pUartGdmaConfig->RxGdmaIrqHandle); + InterruptEn(&pUartGdmaConfig->RxGdmaIrqHandle); + pUartGdmaConfig->RxDmaMBChnl = IsMultiBlk; + if (IsMultiBlk) { + pDmaBlkList = pUartGdmaConfig->pRxDmaBlkList; + if (NULL != pDmaBlkList) { + pHalGdmaAdapter->pBlockSizeList = (struct BLOCK_SIZE_LIST*) &(pDmaBlkList->BlockSizeList); + pHalGdmaAdapter->pLlix = (struct GDMA_CH_LLI*) &(pDmaBlkList->Lli); + } else { + DBG_UART_WARN("HalRuartRxGdma: no Block List for DMA\n"); + } + } + + return HAL_OK; +} + +VOID +HalRuartRxGdmaDeInit( + PUART_DMA_CONFIG pUartGdmaConfig +) +{ + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + HAL_GDMA_CHNL GdmaChnl; + + pHalGdmaAdapter = (PHAL_GDMA_ADAPTER)pUartGdmaConfig->pRxHalGdmaAdapter; + GdmaChnl.GdmaIndx = pHalGdmaAdapter->GdmaIndex; + GdmaChnl.GdmaChnl = pHalGdmaAdapter->ChNum; + GdmaChnl.IrqNum = pUartGdmaConfig->RxGdmaIrqHandle.IrqNum; + HalGdmaChnlFree(&GdmaChnl); + pUartGdmaConfig->RxDmaMBChnl = 0; +} + +/** + * Hook a RX indication callback + * + * To hook a callback function which will be called when a got a RX byte + * + * + */ +VOID +HalRuartRxIndHook( + PRUART_ADAPTER pRuartAdapter, + VOID *pCallback, + VOID *pPara +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter = pRuartAdapter->pHalRuartAdapter; + + pHalRuartAdapter->RxDRCallback = (void (*)(void*))pCallback; + pHalRuartAdapter->RxDRCbPara = pPara; + + // enable RX data ready interrupt + pHalRuartAdapter->Interrupts |= RUART_IER_ERBI | RUART_IER_ELSI; + pRuartAdapter->pHalRuartOp->HalRuartSetIMR(pHalRuartAdapter); +} + + +HAL_Status +HalRuartResetTxFifo( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + return (HalRuartResetTxFifoRtl8195a_V04(Data)); +#else + return (HalRuartResetTxFifoRtl8195a(Data)); +#endif +} + +HAL_Status +HalRuartResetRxFifo( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + return (HalRuartResetRxFifoRtl8195a_V04(Data)); +#else + return (HalRuartResetRxFifoRtl8195a_Patch(Data)); +#endif +} + +HAL_Status +HalRuartResetTRxFifo( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + return (HalRuartResetTRxFifoRtl8195a_V04(Data)); +#else + return (HalRuartResetTRxFifoRtl8195a(Data)); +#endif +} + +HAL_Status +HalRuartSetBaudRate( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + return HalRuartSetBaudRateRtl8195a_V04(Data); +#else + return HalRuartSetBaudRateRtl8195a(Data); +#endif +} + +HAL_Status +HalRuartInit( + IN VOID *Data +) +{ + HAL_Status ret; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE UartPwrState; +#endif +#if CONFIG_CHIP_E_CUT + pHalRuartAdapter->pDefaultBaudRateTbl = (uint32_t*)DEF_BAUDRATE_TABLE_ROM; + + pHalRuartAdapter->pDefaultOvsrRTbl = (uint8_t*)DEF_OVSR_ROM; + pHalRuartAdapter->pDefaultDivTbl = (uint16_t*)DEF_DIV_ROM; + pHalRuartAdapter->pDefOvsrAdjBitTbl_10 = (uint8_t*)DEF_OVSR_ADJ_10BITS_ROM; + pHalRuartAdapter->pDefOvsrAdjBitTbl_9 = (uint8_t*)DEF_OVSR_ADJ_9BITS_ROM; + pHalRuartAdapter->pDefOvsrAdjBitTbl_8 = (uint8_t*)DEF_OVSR_ADJ_8BITS_ROM; + + pHalRuartAdapter->pDefOvsrAdjTbl_10 = (uint16_t*)ovsr_adj_table_10bit_rom; + pHalRuartAdapter->pDefOvsrAdjTbl_9 = (uint16_t*)ovsr_adj_table_9bit_rom; + pHalRuartAdapter->pDefOvsrAdjTbl_8 = (uint16_t*)ovsr_adj_table_8bit_rom; + + ret = HalRuartInitRtl8195a_V04(Data); +#else + pHalRuartAdapter->pDefaultBaudRateTbl = (uint32_t*)DEF_BAUDRATE_TABLE; +#if defined(CONFIG_CHIP_A_CUT) || defined(CONFIG_CHIP_B_CUT) + u8 chip_ver; + + chip_ver = HalRuartGetChipVerRtl8195a(); + if (chip_ver < 2) { + pHalRuartAdapter->pDefaultOvsrRTbl = (uint8_t*)DEF_OVSR_B_CUT; + pHalRuartAdapter->pDefaultDivTbl = (uint16_t*)DEF_DIV_B_CUT; + pHalRuartAdapter->pDefOvsrAdjBitTbl_10 = (uint8_t*)DEF_OVSR_ADJ_BITS_B_CUT_10B; + pHalRuartAdapter->pDefOvsrAdjBitTbl_9 = (uint8_t*)DEF_OVSR_ADJ_BITS_B_CUT_9B; + pHalRuartAdapter->pDefOvsrAdjBitTbl_8 = (uint8_t*)DEF_OVSR_ADJ_BITS_B_CUT_8B; + } + else +#endif + { + pHalRuartAdapter->pDefaultOvsrRTbl = (uint8_t*)DEF_OVSR_C_CUT; + pHalRuartAdapter->pDefaultDivTbl = (uint16_t*)DEF_DIV_C_CUT; + pHalRuartAdapter->pDefOvsrAdjBitTbl_10 = (uint8_t*)DEF_OVSR_ADJ_BITS_C_CUT_10B; + pHalRuartAdapter->pDefOvsrAdjBitTbl_9 = (uint8_t*)DEF_OVSR_ADJ_BITS_C_CUT_9B; + pHalRuartAdapter->pDefOvsrAdjBitTbl_8 = (uint8_t*)DEF_OVSR_ADJ_BITS_C_CUT_8B; + } + pHalRuartAdapter->pDefOvsrAdjTbl_10 = (uint16_t*)ovsr_adj_table_10bit; + pHalRuartAdapter->pDefOvsrAdjTbl_9 = (uint16_t*)ovsr_adj_table_9bit; + pHalRuartAdapter->pDefOvsrAdjTbl_8 = (uint16_t*)ovsr_adj_table_8bit; + + if (_FALSE == FunctionChk((pHalRuartAdapter->UartIndex+UART0), pHalRuartAdapter->PinmuxSelect)) { + return HAL_ERR_HW; + } + ret = HalRuartInitRtl8195a_Patch(Data); +#endif + +#ifdef CONFIG_SOC_PS_MODULE + if(ret == HAL_OK) { + // To register a new peripheral device power state + UartPwrState.FuncIdx = UART0 + pHalRuartAdapter->UartIndex; + UartPwrState.PwrState = ACT; + RegPowerState(UartPwrState); + } +#endif + return ret; +} + +VOID +HalRuartDeInit( + IN VOID *Data +) +{ +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE UartPwrState; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + u8 HwState; + + UartPwrState.FuncIdx = UART0 + pHalRuartAdapter->UartIndex; + QueryRegPwrState(UartPwrState.FuncIdx, &(UartPwrState.PwrState), &HwState); + + // if the power state isn't ACT, then switch the power state back to ACT first + if ((UartPwrState.PwrState != ACT) && (UartPwrState.PwrState != INACT)) { + HalRuartEnable(Data); + QueryRegPwrState(UartPwrState.FuncIdx, &(UartPwrState.PwrState), &HwState); + } + + if (UartPwrState.PwrState == ACT) { + UartPwrState.PwrState = INACT; + RegPowerState(UartPwrState); + } +#endif + + HalRuartDeInitRtl8195a(Data); +} + +HAL_Status +HalRuartDisable( + IN VOID *Data +) +{ + HAL_Status ret; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE UartPwrState; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; +#endif + +#if CONFIG_CHIP_E_CUT + ret = HalRuartDisableRtl8195a_V04(Data); +#else + ret = HalRuartDisableRtl8195a(Data); +#endif +#ifdef CONFIG_SOC_PS_MODULE + if (ret == HAL_OK) { + UartPwrState.FuncIdx = UART0 + pHalRuartAdapter->UartIndex; + UartPwrState.PwrState = SLPCG; + RegPowerState(UartPwrState); + } +#endif + return ret; +} + +HAL_Status +HalRuartEnable( + IN VOID *Data +) +{ + HAL_Status ret; +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE UartPwrState; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; +#endif + +#if CONFIG_CHIP_E_CUT + ret = HalRuartEnableRtl8195a_V04(Data); +#else + ret = HalRuartEnableRtl8195a(Data); +#endif +#ifdef CONFIG_SOC_PS_MODULE + if (ret == HAL_OK) { + UartPwrState.FuncIdx = UART0 + pHalRuartAdapter->UartIndex; + UartPwrState.PwrState = ACT; + RegPowerState(UartPwrState); + } +#endif + return ret; +} + +HAL_Status +HalRuartFlowCtrl( + IN VOID *Data +) +{ + HAL_Status ret; + PHAL_RUART_ADAPTER pHalRuartAdapter = (PHAL_RUART_ADAPTER) Data; + +#if CONFIG_CHIP_E_CUT + ret = HalRuartFlowCtrlRtl8195a_V04((VOID *)Data); +#else + ret = HalRuartFlowCtrlRtl8195a((VOID *)Data); +#endif + // RTS_Pin = AFE ? (~rts | RX_FIFO_Level_Over) : ~rts; + HalRuartRTSCtrlRtl8195a(Data, pHalRuartAdapter->RTSCtrl); + + return ret; +} + +VOID +HalRuartEnterCritical( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + HalRuartEnterCriticalRtl8195a_V04(Data); +#else + HalRuartEnterCriticalRtl8195a(Data); +#endif +} + +VOID +HalRuartExitCritical( + IN VOID *Data +) +{ +#if CONFIG_CHIP_E_CUT + HalRuartExitCriticalRtl8195a_V04(Data); +#else + HalRuartExitCriticalRtl8195a(Data); +#endif +} + +/** + * RUART send a data buffer by DMA(non-block) mode. + * + * RUART send data. + * + * @return VOID + */ +HAL_Status +HalRuartDmaSend( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pTxBuf, // the Buffer to be send + IN u32 Length // the length of data to be send +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; + u32 BlockSize; + HAL_Status ret; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if (((Length & 0x03)==0) && + (((u32)(pTxBuf) & 0x03)==0)) { + // 4-bytes aligned, move 4 bytes each transfer + BlockSize = Length >> 2; + } else { + BlockSize = Length; + } + + if (BlockSize < 4096) { +#if CONFIG_CHIP_E_CUT + ret = HalRuartDmaSendRtl8195a_V04(Data, pTxBuf, Length); +#else + ret = HalRuartDmaSendRtl8195a_Patch(Data, pTxBuf, Length); +#endif + } else { + // over Maximum block size 4095, use multiple block DMA + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + + if (0 == pUartGdmaConfig->TxDmaMBChnl) { + // Current DMA channel doesn't support multiple block, so re-allocate DMA channel + HalRuartTxGdmaDeInit (pHalRuartAdapter->DmaConfig); + ret = HalRuartTxGdmaInit(pHalRuartAdapter, pUartGdmaConfig, 1); + if (HAL_OK != ret) { + DBG_UART_WARN("HalRuartDmaSend: Reallocate DMA Multi-Block Chnl failed(%d)\n", ret); + return ret; + } + } +#if CONFIG_CHIP_E_CUT + ret = HalRuartMultiBlkDmaSendRtl8195a_V04(Data, pTxBuf, Length); +#else + ret = HalRuartMultiBlkDmaSendRtl8195a(Data, pTxBuf, Length); +#endif + } + + return ret; +} + +/** + * RUART receive a data buffer by DMA(non-block) mode. + * + * RUART send data. + * + * @return VOID + */ +HAL_Status +HalRuartDmaRecv( + IN VOID *Data, // PHAL_RUART_ADAPTER + IN u8 *pRxBuf, // the Buffer for store RX data + IN u32 Length // the length of data to receive +) +{ + PHAL_RUART_ADAPTER pHalRuartAdapter=(PHAL_RUART_ADAPTER)Data; +// u32 BlockSize; + HAL_Status ret; + PUART_DMA_CONFIG pUartGdmaConfig; + PHAL_GDMA_ADAPTER pHalGdmaAdapter; + + if (Length < 4096) { +#if CONFIG_CHIP_E_CUT + ret = HalRuartDmaRecvRtl8195a_V04(Data, pRxBuf, Length); +#else + ret = HalRuartDmaRecvRtl8195a_Patch(Data, pRxBuf, Length); +#endif + } else { + // over Maximum block size 4095, use multiple block DMA + pUartGdmaConfig = pHalRuartAdapter->DmaConfig; + + if (!pUartGdmaConfig->RxDmaMBChnl) { + // Current DMA channel doesn't support multiple block, so re-allocate DMA channel + HalRuartRxGdmaDeInit (pHalRuartAdapter->DmaConfig); + ret = HalRuartRxGdmaInit(pHalRuartAdapter, pUartGdmaConfig, 1); + if (HAL_OK != ret) { + DBG_UART_WARN("HalRuartDmaRecv: Reallocate DMA Multi-Block Chnl failed(%d)\n", ret); + return ret; + } + } +#if CONFIG_CHIP_E_CUT + ret = HalRuartMultiBlkDmaRecvRtl8195a_V04(Data, pRxBuf, Length); +#else + ret = HalRuartMultiBlkDmaRecvRtl8195a(Data, pRxBuf, Length); +#endif + } + + return ret; +} + +#endif // CONFIG_UART_EN diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.p.bin b/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.p.bin new file mode 100644 index 0000000..26db83a Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.p.bin differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.r.bin b/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.r.bin new file mode 100644 index 0000000..e0a9791 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/image/ram_1.r.bin differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/export-rom_v04.txt b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/export-rom_v04.txt new file mode 100644 index 0000000..6d0a421 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/export-rom_v04.txt @@ -0,0 +1,739 @@ +SECTIONS +{ + __vectors_table = 0x0; + Reset_Handler = 0x101; + NMI_Handler = 0x109; + HardFault_Handler = 0x10d; + MemManage_Handler = 0x121; + BusFault_Handler = 0x125; + UsageFault_Handler = 0x129; + HalLogUartInit = 0x201; + HalSerialPutcRtl8195a = 0x2d9; + HalSerialGetcRtl8195a = 0x309; + HalSerialGetIsrEnRegRtl8195a = 0x329; + HalSerialSetIrqEnRegRtl8195a = 0x335; + HalCpuClkConfig = 0x341; + HalGetCpuClk = 0x355; + HalRomInfo = 0x39d; + HalGetRomInfo = 0x3b5; + HalResetVsr = 0x3c5; + HalDelayUs = 0x899; + HalNMIHandler = 0x8e1; + HalHardFaultHandler = 0x911; + HalMemManageHandler = 0xc09; + HalBusFaultHandler = 0xc39; + HalUsageFaultHandler = 0xc69; + HalUart0PinCtrlRtl8195A = 0xcfd; + HalUart1PinCtrlRtl8195A = 0xdc9; + HalUart2PinCtrlRtl8195A = 0xe9d; + HalSPI0PinCtrlRtl8195A = 0xf75; + HalSPI1PinCtrlRtl8195A = 0x1015; + HalSPI2PinCtrlRtl8195A = 0x10e5; + HalSPI0MCSPinCtrlRtl8195A = 0x11b5; + HalI2C0PinCtrlRtl8195A = 0x1275; + HalI2C1PinCtrlRtl8195A = 0x1381; + HalI2C2PinCtrlRtl8195A = 0x1459; + HalI2C3PinCtrlRtl8195A = 0x1529; + HalI2S0PinCtrlRtl8195A = 0x1639; + HalI2S1PinCtrlRtl8195A = 0x176d; + HalPCM0PinCtrlRtl8195A = 0x1845; + HalPCM1PinCtrlRtl8195A = 0x1949; + HalSDIODPinCtrlRtl8195A = 0x1a1d; + HalSDIOHPinCtrlRtl8195A = 0x1a6d; + HalMIIPinCtrlRtl8195A = 0x1ab9; + HalWLLEDPinCtrlRtl8195A = 0x1b51; + HalWLANT0PinCtrlRtl8195A = 0x1c0d; + HalWLANT1PinCtrlRtl8195A = 0x1c61; + HalWLBTCOEXPinCtrlRtl8195A = 0x1cb5; + HalWLBTCMDPinCtrlRtl8195A = 0x1d05; + HalNFCPinCtrlRtl8195A = 0x1d59; + HalPWM0PinCtrlRtl8195A = 0x1da9; + HalPWM1PinCtrlRtl8195A = 0x1ead; + HalPWM2PinCtrlRtl8195A = 0x1fb5; + HalPWM3PinCtrlRtl8195A = 0x20b1; + HalETE0PinCtrlRtl8195A = 0x21b9; + HalETE1PinCtrlRtl8195A = 0x22c1; + HalETE2PinCtrlRtl8195A = 0x23c9; + HalETE3PinCtrlRtl8195A = 0x24d1; + HalEGTIMPinCtrlRtl8195A = 0x25d9; + HalSPIFlashPinCtrlRtl8195A = 0x2679; + HalSDRPinCtrlRtl8195A = 0x2725; + HalJTAGPinCtrlRtl8195A = 0x280d; + HalTRACEPinCtrlRtl8195A = 0x2861; + HalLOGUartPinCtrlRtl8195A = 0x28b9; + HalLOGUartIRPinCtrlRtl8195A = 0x291d; + HalSICPinCtrlRtl8195A = 0x2981; + HalEEPROMPinCtrlRtl8195A = 0x29d9; + HalDEBUGPinCtrlRtl8195A = 0x2a31; + HalPinCtrlRtl8195A = 0x2b39; + SpicRxCmdRtl8195A = 0x2e5d; + SpicWaitBusyDoneRtl8195A = 0x2ea5; + SpicGetFlashStatusRtl8195A = 0x2eb5; + SpicWaitWipDoneRtl8195A = 0x2f55; + SpicTxCmdRtl8195A = 0x2f6d; + SpicSetFlashStatusRtl8195A = 0x2fc1; + SpicCmpDataForCalibrationRtl8195A = 0x3049; + SpicLoadInitParaFromClockRtl8195A = 0x3081; + SpicInitRtl8195A = 0x30e5; + SpicEraseFlashRtl8195A = 0x31bd; + SpiFlashApp = 0x3279; + HalPeripheralIntrHandle = 0x33b5; + HalSysOnIntrHandle = 0x3439; + HalWdgIntrHandle = 0x3485; + HalTimer0IntrHandle = 0x34d5; + HalTimer1IntrHandle = 0x3525; + HalI2C3IntrHandle = 0x3575; + HalTimer2To7IntrHandle = 0x35c5; + HalSpi0IntrHandle = 0x3615; + HalGpioIntrHandle = 0x3665; + HalUart0IntrHandle = 0x36b5; + HalSpiFlashIntrHandle = 0x3705; + HalUsbOtgIntrHandle = 0x3755; + HalSdioHostIntrHandle = 0x37a5; + HalI2s0OrPcm0IntrHandle = 0x37f5; + HalI2s1OrPcm1IntrHandle = 0x3845; + HalWlDmaIntrHandle = 0x3895; + HalWlProtocolIntrHandle = 0x38e5; + HalCryptoIntrHandle = 0x3935; + HalGmacIntrHandle = 0x3985; + HalGdma0Ch0IntrHandle = 0x39d5; + HalGdma0Ch1IntrHandle = 0x3a25; + HalGdma0Ch2IntrHandle = 0x3a75; + HalGdma0Ch3IntrHandle = 0x3ac5; + HalGdma0Ch4IntrHandle = 0x3b15; + HalGdma0Ch5IntrHandle = 0x3b65; + HalGdma1Ch0IntrHandle = 0x3bb5; + HalGdma1Ch1IntrHandle = 0x3c05; + HalGdma1Ch2IntrHandle = 0x3c55; + HalGdma1Ch3IntrHandle = 0x3ca5; + HalGdma1Ch4IntrHandle = 0x3cf5; + HalGdma1Ch5IntrHandle = 0x3d45; + HalSdioDeviceIntrHandle = 0x3d95; + VectorTableInitRtl8195A = 0x3de5; + txt0123456789ABCDEF = 0x3ec24; + VectorTableInitForOSRtl8195A = 0x4019; + VectorIrqRegisterRtl8195A = 0x4029; + VectorIrqUnRegisterRtl8195A = 0x4091; + VectorIrqEnRtl8195A = 0x40f1; + VectorIrqDisRtl8195A = 0x418d; + _UartRxDmaIrqHandle = 0x422d; + HalRuartPutCRtl8195a = 0x4281; + HalRuartGetCRtl8195a = 0x429d; + HalRuartRTSCtrlRtl8195a = 0x42bd; + HalRuartGetDebugValueRtl8195a = 0x42e1; + HalRuartGetIMRRtl8195a = 0x43e1; + HalRuartSetIMRRtl8195a = 0x442d; + _UartIrqHandle = 0x4465; + HalRuartDmaInitRtl8195a = 0x4681; + HalRuartIntDisableRtl8195a = 0x4845; + HalRuartDeInitRtl8195a = 0x4855; + HalRuartIntEnableRtl8195a = 0x4985; + _UartTxDmaIrqHandle = 0x4995; + HalRuartRegIrqRtl8195a = 0x49d1; + HalRuartAdapterLoadDefRtl8195a = 0x4a4d; + HalRuartTxGdmaLoadDefRtl8195a = 0x4add; + HalRuartRxGdmaLoadDefRtl8195a = 0x4bc9; + RuartLock = 0x4cc9; + RuartUnLock = 0x4ced; + HalRuartIntSendRtl8195a = 0x4d09; + HalRuartDmaSendRtl8195a = 0x4e35; + HalRuartStopSendRtl8195a = 0x4f89; + HalRuartIntRecvRtl8195a = 0x504d; + HalRuartDmaRecvRtl8195a = 0x51ad; + HalRuartStopRecvRtl8195a = 0x52cd; + RuartIsTimeout = 0x5385; + HalRuartSendRtl8195a = 0x53b1; + HalRuartRecvRtl8195a = 0x5599; + RuartResetRxFifoRtl8195a = 0x5751; + HalRuartResetRxFifoRtl8195a = 0x5775; + HalRuartInitRtl8195a = 0x5829; + HalGdmaOnOffRtl8195a = 0x5df1; + HalGdmaChIsrEnAndDisRtl8195a = 0x5e0d; + HalGdmaChEnRtl8195a = 0x5e51; + HalGdmaChDisRtl8195a = 0x5e6d; + HalGdamChInitRtl8195a = 0x5e91; + HalGdmaChSetingRtl8195a = 0x5ebd; + HalGdmaChBlockSetingRtl8195a = 0x000060dd; + HalGdmaChIsrCleanRtl8195a = 0x6419; + HalGdmaChCleanAutoSrcRtl8195a = 0x64a1; + HalGdmaChCleanAutoDstRtl8195a = 0x6501; + HalEFUSEPowerSwitch8195AROM = 0x6561; + HALEFUSEOneByteReadROM = 0x65f9; + HALEFUSEOneByteWriteROM = 0x6699; + __rtl_memcmpb_v1_00 = 0x681d; + __rtl_random_v1_00 = 0x6861; + __rtl_align_to_be32_v1_00 = 0x6881; + __rtl_memsetw_v1_00 = 0x6899; + __rtl_memsetb_v1_00 = 0x68ad; + __rtl_memcpyw_v1_00 = 0x68bd; + __rtl_memcpyb_v1_00 = 0x68dd; + __rtl_memDump_v1_00 = 0x68f5; + __rtl_AES_set_encrypt_key = 0x6901; + __rtl_cryptoEngine_AES_set_decrypt_key = 0x6c11; + __rtl_cryptoEngine_set_security_mode_v1_00 = 0x6c95; + __rtl_cryptoEngine_init_v1_00 = 0x6ea9; + __rtl_cryptoEngine_exit_v1_00 = 0x7055; + __rtl_cryptoEngine_reset_v1_00 = 0x70b1; + __rtl_cryptoEngine_v1_00 = 0x70ed; + __rtl_crypto_cipher_init_v1_00 = 0x7c69; + __rtl_crypto_cipher_encrypt_v1_00 = 0x7c89; + __rtl_crypto_cipher_decrypt_v1_00 = 0x7cad; + HalSsiPinmuxEnableRtl8195a = 0x7cd5; + HalSsiEnableRtl8195a = 0x7e45; + HalSsiDisableRtl8195a = 0x7ef9; + HalSsiLoadSettingRtl8195a = 0x7fad; + HalSsiSetInterruptMaskRtl8195a = 0x8521; + HalSsiGetInterruptMaskRtl8195a = 0x85c9; + HalSsiSetSclkPolarityRtl8195a = 0x863d; + HalSsiSetSclkPhaseRtl8195a = 0x8715; + HalSsiWriteRtl8195a = 0x87e9; + HalSsiSetDeviceRoleRtl8195a = 0x8861; + HalSsiSetRxFifoThresholdLevelRtl8195a = 0x88c9; + HalSsiSetTxFifoThresholdLevelRtl8195a = 0x8941; + HalSsiReadRtl8195a = 0x89b9; + HalSsiGetRxFifoLevelRtl8195a = 0x8a2d; + HalSsiGetTxFifoLevelRtl8195a = 0x8aa5; + HalSsiGetStatusRtl8195a = 0x8b1d; + HalSsiWriteableRtl8195a = 0x8b91; + HalSsiReadableRtl8195a = 0x8c09; + HalSsiBusyRtl8195a = 0x8c81; + HalSsiReadInterruptRtl8195a = 0x8cf9; + HalSsiWriteInterruptRtl8195a = 0x8efd; + HalSsiSetSlaveEnableRegisterRtl8195a = 0x9009; + HalSsiGetInterruptStatusRtl8195a = 0x90d9; + HalSsiInterruptEnableRtl8195a = 0x914d; + HalSsiInterruptDisableRtl8195a = 0x9299; + HalSsiGetRawInterruptStatusRtl8195a = 0x93e9; + HalSsiGetSlaveEnableRegisterRtl8195a = 0x945d; + HalSsiInitRtl8195a = 0x94d1; + _SsiReadInterrupt = 0x9ba5; + _SsiWriteInterrupt = 0x9db1; + _SsiIrqHandle = 0x9eb1; + HalI2CWrite32 = 0xa061; + HalI2CRead32 = 0xa09d; + HalI2CDeInit8195a = 0xa0dd; + HalI2CSendRtl8195a = 0xa1f1; + HalI2CReceiveRtl8195a = 0xa25d; + HalI2CEnableRtl8195a = 0xa271; + HalI2CIntrCtrl8195a = 0xa389; + HalI2CReadRegRtl8195a = 0xa3a1; + HalI2CWriteRegRtl8195a = 0xa3b1; + HalI2CSetCLKRtl8195a = 0xa3c5; + HalI2CMassSendRtl8195a = 0xa6e9; + HalI2CClrIntrRtl8195a = 0xa749; + HalI2CClrAllIntrRtl8195a = 0xa761; + HalI2CInit8195a = 0xa775; + HalI2CDMACtrl8195a = 0xaa31; + RtkI2CIoCtrl = 0xaa61; + RtkI2CPowerCtrl = 0xaa65; + HalI2COpInit = 0xaa69; + I2CIsTimeout = 0xac65; + I2CTXGDMAISRHandle = 0xb435; + I2CRXGDMAISRHandle = 0xb4c1; + RtkI2CIrqInit = 0xb54d; + RtkI2CIrqDeInit = 0xb611; + RtkI2CPinMuxInit = 0xb675; + RtkI2CPinMuxDeInit = 0xb7c9; + RtkI2CDMAInit = 0xb955; + RtkI2CInit = 0xbc95; + RtkI2CDMADeInit = 0xbdad; + RtkI2CDeInit = 0xbe4d; + RtkI2CSendUserAddr = 0xbee5; + RtkI2CSend = 0xc07d; + _RtkI2CReceive = 0x0c6dd; + RtkI2CLoadDefault = 0xce51; + RtkSalI2COpInit = 0xcf21; + HalI2SWrite32 = 0xcf65; + HalI2SRead32 = 0xcf85; + HalI2SDeInitRtl8195a = 0xcfa9; + HalI2STxRtl8195a = 0xcfc9; + HalI2SRxRtl8195a = 0xd011; + HalI2SEnableRtl8195a = 0xd05d; + HalI2SIntrCtrlRtl8195a = 0xd0b1; + HalI2SReadRegRtl8195a = 0xd0d1; + HalI2SClrIntrRtl8195a = 0xd0dd; + HalI2SClrAllIntrRtl8195a = 0xd0fd; + HalI2SInitRtl8195a = 0xd11d; + GPIO_GetIPPinName_8195a = 0xd2e5; + GPIO_GetChipPinName_8195a = 0xd331; + GPIO_PullCtrl_8195a = 0xd39d; + GPIO_FuncOn_8195a = 0xd421; + GPIO_FuncOff_8195a = 0xd481; + GPIO_Int_Mask_8195a = 0xd4e9; + GPIO_Int_SetType_8195a = 0xd511; + HAL_GPIO_IrqHandler_8195a = 0xd5fd; + HAL_GPIO_MbedIrqHandler_8195a = 0xd645; + HAL_GPIO_UserIrqHandler_8195a = 0xd6a1; + HAL_GPIO_IntCtrl_8195a = 0xd6cd; + HAL_GPIO_Init_8195a = 0xd805; + HAL_GPIO_DeInit_8195a = 0xdac1; + HAL_GPIO_ReadPin_8195a = 0xdbd1; + HAL_GPIO_WritePin_8195a = 0xdc91; + HAL_GPIO_RegIrq_8195a = 0xddad; + HAL_GPIO_UnRegIrq_8195a = 0xddf5; + HAL_GPIO_UserRegIrq_8195a = 0xde15; + HAL_GPIO_UserUnRegIrq_8195a = 0xdef9; + HAL_GPIO_MaskIrq_8195a = 0xdfc1; + HAL_GPIO_UnMaskIrq_8195a = 0xe061; + HAL_GPIO_IntDebounce_8195a = 0xe101; + HAL_GPIO_GetIPPinName_8195a = 0xe1c1; + HAL_GPIO_PullCtrl_8195a = 0xe1c9; + DumpForOneBytes = 0xe259; + CmdRomHelp = 0xe419; + CmdWriteWord = 0xe491; + CmdDumpHelfWord = 0xe505; + CmdDumpWord = 0xe5f1; + CmdDumpByte = 0xe6f5; + CmdSpiFlashTool = 0xe751; + GetRomCmdNum = 0xe7a9; + CmdWriteByte = 0xe7ad; + Isspace = 0xe7ed; + Strtoul = 0xe801; + ArrayInitialize = 0xe8b1; + GetArgc = 0xe8c9; + GetArgv = 0xe8f9; + UartLogCmdExecute = 0xe95d; + UartLogShowBackSpace = 0xe9fd; + UartLogRecallOldCmd = 0xea39; + UartLogHistoryCmd = 0xea71; + UartLogCmdChk = 0xeadd; + UartLogIrqHandle = 0xebf5; + RtlConsolInit = 0xecc5; + RtlConsolTaskRom = 0xed49; + RtlExitConsol = 0xed79; + RtlConsolRom = 0xedcd; + HalTimerOpInit = 0xee0d; + HalTimerIrq2To7Handle = 0xee59; + HalGetTimerIdRtl8195a = 0xef09; + HalTimerInitRtl8195a = 0xef3d; + HalTimerDisRtl8195a = 0xf069; /* error! */ + HalTimerEnRtl8195a = 0xf089; /* error! */ + HalTimerReadCountRtl8195a = 0xf0a9; + HalTimerIrqClearRtl8195a = 0xf0bd; + HalTimerDumpRegRtl8195a = 0xf0d1; + VSprintf = 0xf129; + DiagPrintf = 0xf39d; + DiagSPrintf = 0xf3b9; + DiagSnPrintf = 0xf3d1; + prvDiagPrintf = 0xf3ed; + prvDiagSPrintf = 0xf40d; + _memcmp = 0xf429; + _memcpy = 0xf465; + _memset = 0xf511; + Rand = 0xf585; + _strncpy = 0xf60d; + _strcpy = 0xf629; + prvStrCpy = 0xf639; + _strlen = 0xf651; + _strnlen = 0xf669; + prvStrLen = 0xf699; + _strcmp = 0xf6b1; + _strncmp = 0xf6d1; + prvStrCmp = 0xf719; + StrUpr = 0xf749; + prvAtoi = 0xf769; + prvStrStr = 0xf7bd; + _strsep = 0xf7d5; + skip_spaces = 0xf815; + skip_atoi = 0xf831; + _parse_integer_fixup_radix = 0xf869; + _parse_integer = 0xf8bd; + simple_strtoull = 0xf915; + simple_strtoll = 0xf945; + simple_strtoul = 0xf965; + simple_strtol = 0xf96d; + _vsscanf = 0xf985; + _sscanf = 0xff71; + div_u64 = 0xff91; + div_s64 = 0xff99; + div_u64_rem = 0xffa1; + div_s64_rem = 0xffb1; + _strpbrk = 0xffc1; + _strchr = 0xffed; + aes_set_key = 0x10005; + aes_encrypt = 0x103d1; + aes_decrypt = 0x114a5; + AES_WRAP = 0x125c9; + AES_UnWRAP = 0x12701; + crc32_get = 0x12861; + arc4_byte = 0x12895; + rt_arc4_init = 0x128bd; + rt_arc4_crypt = 0x12901; + rt_md5_init = 0x131c1; + rt_md5_append = 0x131f5; + rt_md5_final = 0x1327d; + rt_md5_hmac = 0x132d5; + rtw_get_bit_value_from_ieee_value = 0x13449; + rtw_is_cckrates_included = 0x13475; + rtw_is_cckratesonly_included = 0x134b5; + rtw_check_network_type = 0x134dd; + rtw_set_fixed_ie = 0x1350d; + rtw_set_ie = 0x1352d; + rtw_get_ie = 0x1355d; + rtw_set_supported_rate = 0x13591; + rtw_get_rateset_len = 0x13611; + rtw_get_wpa_ie = 0x1362d; + rtw_get_wpa2_ie = 0x136c9; + rtw_get_wpa_cipher_suite = 0x13701; + rtw_get_wpa2_cipher_suite = 0x13769; + rtw_parse_wpa_ie = 0x137d1; + rtw_parse_wpa2_ie = 0x138ad; + rtw_get_sec_ie = 0x13965; + rtw_get_wps_ie = 0x13a15; + rtw_get_wps_attr = 0x13a99; + rtw_get_wps_attr_content = 0x13b49; + rtw_ieee802_11_parse_elems = 0x13b91; + str_2char2num = 0x13d9d; + key_2char2num = 0x13db9; + convert_ip_addr = 0x13dd1; + rom_psk_PasswordHash = 0x13e9d; + rom_psk_CalcGTK = 0x13ed5; + rom_psk_CalcPTK = 0x13f69; + wep_80211_encrypt = 0x14295; + wep_80211_decrypt = 0x142f5; + tkip_micappendbyte = 0x14389; + rtw_secmicsetkey = 0x143d9; + rtw_secmicappend = 0x14419; + rtw_secgetmic = 0x14435; + rtw_seccalctkipmic = 0x1449d; + tkip_phase1 = 0x145a5; + tkip_phase2 = 0x14725; + tkip_80211_encrypt = 0x14941; + tkip_80211_decrypt = 0x149d5; + aes1_encrypt = 0x14a8d; + aesccmp_construct_mic_iv = 0x14c65; + aesccmp_construct_mic_header1 = 0x14ccd; + aesccmp_construct_mic_header2 = 0x14d21; + aesccmp_construct_ctr_preload = 0x14db5; + aes_80211_encrypt = 0x14e29; + aes_80211_decrypt = 0x151ad; + _sha1_process_message_block = 0x155b9; + _sha1_pad_message = 0x15749; + rt_sha1_init = 0x157e5; + rt_sha1_update = 0x15831; + rt_sha1_finish = 0x158a9; + rt_hmac_sha1 = 0x15909; + rom_aes_128_cbc_encrypt = 0x15a65; + rom_aes_128_cbc_decrypt = 0x15ae1; + rom_rijndaelKeySetupEnc = 0x15b5d; + rom_aes_decrypt_init = 0x15c39; + rom_aes_internal_decrypt = 0x15d15; + rom_aes_decrypt_deinit = 0x16071; + rom_aes_encrypt_init = 0x16085; + rom_aes_internal_encrypt = 0x1609d; + rom_aes_encrypt_deinit = 0x16451; + bignum_init = 0x17b35; + bignum_deinit = 0x17b61; + bignum_get_unsigned_bin_len = 0x17b81; + bignum_get_unsigned_bin = 0x17b85; + bignum_set_unsigned_bin = 0x17c21; + bignum_cmp = 0x17cd1; + bignum_cmp_d = 0x17cd5; + bignum_add = 0x17cfd; + bignum_sub = 0x17d0d; + bignum_mul = 0x17d1d; + bignum_exptmod = 0x17d2d; + WPS_realloc = 0x17d51; + os_zalloc = 0x17d99; + rom_hmac_sha256_vector = 0x17dc1; + rom_hmac_sha256 = 0x17ebd; + rom_sha256_vector = 0x18009; + phy_CalculateBitShift = 0x18221; + PHY_SetBBReg_8195A = 0x18239; + PHY_QueryBBReg_8195A = 0x18279; + ROM_odm_QueryRxPwrPercentage = 0x1829d; + ROM_odm_EVMdbToPercentage = 0x182bd; + ROM_odm_SignalScaleMapping_8195A = 0x182e5; + ROM_odm_FalseAlarmCounterStatistics = 0x183cd; + ROM_odm_SetEDCCAThreshold = 0x18721; + ROM_odm_SetTRxMux = 0x18749; + ROM_odm_SetCrystalCap = 0x18771; + ROM_odm_GetDefaultCrytaltalCap = 0x187d5; + ROM_ODM_CfoTrackingReset = 0x187e9; + ROM_odm_CfoTrackingFlow = 0x18811; + curve25519_donna = 0x1965d; + aes_test_alignment_detection = 0x1a391; + aes_mode_reset = 0x1a3ed; + aes_ecb_encrypt = 0x1a3f9; + aes_ecb_decrypt = 0x1a431; + aes_cbc_encrypt = 0x1a469; + aes_cbc_decrypt = 0x1a579; + aes_cfb_encrypt = 0x1a701; + aes_cfb_decrypt = 0x1a9e5; + aes_ofb_crypt = 0x1acc9; + aes_ctr_crypt = 0x1af7d; + aes_encrypt_key128 = 0x1b289; + aes_encrypt_key192 = 0x1b2a5; + aes_encrypt_key256 = 0x1b2c1; + aes_encrypt_key = 0x1b2e1; + aes_decrypt_key128 = 0x1b351; + aes_decrypt_key192 = 0x1b36d; + aes_decrypt_key256 = 0x1b389; + aes_decrypt_key = 0x1b3a9; + aes_init = 0x1b419; + CRYPTO_chacha_20 = 0x1b41d; + CRYPTO_poly1305_init = 0x1bc25; + CRYPTO_poly1305_update = 0x1bd09; + CRYPTO_poly1305_finish = 0x1bd8d; + rom_sha512_starts = 0x1ceb5; + rom_sha512_update = 0x1d009; + rom_sha512_finish = 0x1d011; + rom_sha512 = 0x1d261; + rom_sha512_hmac_starts = 0x1d299; + rom_sha512_hmac_update = 0x1d35d; + rom_sha512_hmac_finish = 0x1d365; + rom_sha512_hmac_reset = 0x1d3b5; + rom_sha512_hmac = 0x1d3d1; + rom_sha512_hkdf = 0x1d40d; + rom_ed25519_gen_keypair = 0x1d501; + rom_ed25519_gen_signature = 0x1d505; + rom_ed25519_verify_signature = 0x1d51d; + rom_ed25519_crypto_sign_seed_keypair = 0x1d521; + rom_ed25519_crypto_sign_detached = 0x1d579; + rom_ed25519_crypto_sign_verify_detached = 0x1d655; + rom_ed25519_ge_double_scalarmult_vartime = 0x1f86d; + rom_ed25519_ge_frombytes_negate_vartime = 0x1fc35; + rom_ed25519_ge_p3_tobytes = 0x207d5; + rom_ed25519_ge_scalarmult_base = 0x20821; + rom_ed25519_ge_tobytes = 0x209e1; + rom_ed25519_sc_muladd = 0x20a2d; + rom_ed25519_sc_reduce = 0x2603d; + __rtl_memchr_v1_00 = 0x28a4d; + __rtl_memcmp_v1_00 = 0x28ae1; + __rtl_memcpy_v1_00 = 0x28b49; + __aeabi_memcpy = 0x28b49; + __aeabi_memcpy4 = 0x28b49; + __rtl_memmove_v1_00 = 0x28bed; + __rtl_memset_v1_00 = 0x28cb5; + __aeabi_memset = 0x28cb5; + __rtl_strcat_v1_00 = 0x28d49; + __rtl_strchr_v1_00 = 0x28d91; + __rtl_strcmp_v1_00 = 0x28e55; + __rtl_strcpy_v1_00 = 0x28ec9; + __rtl_strlen_v1_00 = 0x28f15; + __rtl_strncat_v1_00 = 0x28f69; + __rtl_strncmp_v1_00 = 0x28fc5; + __rtl_strncpy_v1_00 = 0x2907d; + __rtl_strstr_v1_00 = 0x293cd; + __rtl_strsep_v1_00 = 0x2960d; + __rtl_strtok_v1_00 = 0x29619; + __rtl__strtok_r_v1_00 = 0x2962d; + __rtl_strtok_r_v1_00 = 0x29691; + __rtl_close_v1_00 = 0x29699; + __rtl_fstat_v1_00 = 0x296ad; + __rtl_isatty_v1_00 = 0x296c1; + __rtl_lseek_v1_00 = 0x296d5; + __rtl_open_v1_00 = 0x296e9; + __rtl_read_v1_00 = 0x296fd; + __rtl_write_v1_00 = 0x29711; + __rtl_sbrk_v1_00 = 0x29725; + __rtl_ltoa_v1_00 = 0x297bd; + __rtl_ultoa_v1_00 = 0x29855; + __rtl_dtoi_v1_00 = 0x298c5; + __rtl_dtoi64_v1_00 = 0x29945; + __rtl_dtoui_v1_00 = 0x299dd; + __rtl_ftol_v1_00 = 0x299e5; + __rtl_itof_v1_00 = 0x29a51; + __rtl_itod_v1_00 = 0x29ae9; + __rtl_i64tod_v1_00 = 0x29b79; + __rtl_uitod_v1_00 = 0x29c55; + __rtl_ftod_v1_00 = 0x29d2d; + __rtl_dtof_v1_00 = 0x29de9; + __rtl_uitof_v1_00 = 0x29e89; + __rtl_fadd_v1_00 = 0x29f65; + __rtl_fsub_v1_00 = 0x2a261; + __rtl_fmul_v1_00 = 0x2a559; + __rtl_fdiv_v1_00 = 0x2a695; + __rtl_dadd_v1_00 = 0x2a825; + __rtl_dsub_v1_00 = 0x2aed9; + __rtl_dmul_v1_00 = 0x2b555; + __rtl_ddiv_v1_00 = 0x2b8ad; + __rtl_dcmpeq_v1_00 = 0x2be4d; + __rtl_dcmplt_v1_00 = 0x2bebd; + __rtl_dcmpgt_v1_00 = 0x2bf51; + __rtl_dcmple_v1_00 = 0x2c049; + __rtl_fcmplt_v1_00 = 0x2c139; + __rtl_fcmpgt_v1_00 = 0x2c195; + __rtl_cos_f32_v1_00 = 0x2c229; + __rtl_sin_f32_v1_00 = 0x2c435; + __rtl_fabs_v1_00 = 0x2c639; + __rtl_fabsf_v1_00 = 0x2c641; + __rtl_dtoa_r_v1_00 = 0x2c77d; + __rom_mallocr_init_v1_00 = 0x2d7d1; + __rtl_free_r_v1_00 = 0x2d841; + __rtl_malloc_r_v1_00 = 0x2da31; + __rtl_realloc_r_v1_00 = 0x2df55; + __rtl_memalign_r_v1_00 = 0x2e331; + __rtl_valloc_r_v1_00 = 0x2e421; + __rtl_pvalloc_r_v1_00 = 0x2e42d; + __rtl_calloc_r_v1_00 = 0x2e441; + __rtl_cfree_r_v1_00 = 0x2e4a9; + __rtl_Balloc_v1_00 = 0x2e515; + __rtl_Bfree_v1_00 = 0x2e571; + __rtl_i2b_v1_00 = 0x2e585; + __rtl_multadd_v1_00 = 0x2e599; + __rtl_mult_v1_00 = 0x2e629; + __rtl_pow5mult_v1_00 = 0x2e769; + __rtl_hi0bits_v1_00 = 0x2e809; + __rtl_d2b_v1_00 = 0x2e845; + __rtl_lshift_v1_00 = 0x2e901; + __rtl_cmp_v1_00 = 0x2e9bd; + __rtl_diff_v1_00 = 0x2ea01; + __rtl_sread_v1_00 = 0x2eae9; + __rtl_seofread_v1_00 = 0x2eb39; + __rtl_swrite_v1_00 = 0x2eb3d; + __rtl_sseek_v1_00 = 0x2ebc1; + __rtl_sclose_v1_00 = 0x2ec11; + __rtl_sbrk_r_v1_00 = 0x2ec41; + __rtl_fflush_r_v1_00 = 0x2ef8d; + __rtl_vfprintf_r_v1_00 = 0x2f661; + __rtl_fpclassifyd = 0x30c15; + CpkClkTbl = 0x30c68; + ROM_IMG1_VALID_PATTEN = 0x30c80; + SpicCalibrationPattern = 0x30c88; + SpicInitCPUCLK = 0x30c98; + BAUDRATE = 0x30ca8; + OVSR = 0x30d1c; + DIV = 0x30d90; + OVSR_ADJ = 0x30e04; + __AES_rcon = 0x30e78; + __AES_Te4 = 0x30ea0; + I2CDmaChNo = 0x312a0; + _GPIO_PinMap_Chip2IP_8195a = 0x312b4; + _GPIO_PinMap_PullCtrl_8195a = 0x3136c; + _GPIO_SWPORT_DDR_TBL = 0x31594; + _GPIO_EXT_PORT_TBL = 0x31598; + _GPIO_SWPORT_DR_TBL = 0x3159c; + UartLogRomCmdTable = 0x316a0; + _HalRuartOp = 0x31700; + _HalGdmaOp = 0x31760; + RTW_WPA_OUI_TYPE = 0x3540c; + WPA_CIPHER_SUITE_NONE = 0x35410; + WPA_CIPHER_SUITE_WEP40 = 0x35414; + WPA_CIPHER_SUITE_TKIP = 0x35418; + WPA_CIPHER_SUITE_CCMP = 0x3541c; + WPA_CIPHER_SUITE_WEP104 = 0x35420; + RSN_CIPHER_SUITE_NONE = 0x35424; + RSN_CIPHER_SUITE_WEP40 = 0x35428; + RSN_CIPHER_SUITE_TKIP = 0x3542c; + RSN_CIPHER_SUITE_CCMP = 0x35430; + RSN_CIPHER_SUITE_WEP104 = 0x35434; + RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X = 0x35444; + RSN_AUTH_KEY_MGMT_UNSPEC_802_1X = 0x35448; + RSN_VERSION_BSD = 0x3544c; + rom_wps_Te0 = 0x35988; + rom_wps_rcons = 0x35d88; + rom_wps_Td4s = 0x35d94; + rom_wps_Td0 = 0x35e94; + str_rom_57ch3Dch0A = 0x3ed05; /* "========================================================\n" */ + str_rom_0123456789ABCDEF = 0x3ec24; /* "0123456789ABCDEF" */ + str_rom_hex_addr = 0x442D6; /* "[Addr] .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F\r\n" */ + str_rom_0123456789abcdef = 0x44660; /* "0123456789abcdef" */ + __rom_b_cut_end__ = 0x4467c; + __rom_c_cut_text_start__ = 0x4467c; + HalInitPlatformLogUartV02 = 0x4467d; + HalReInitPlatformLogUartV02 = 0x4471d; + HalInitPlatformTimerV02 = 0x44755; + HalShowBuildInfoV02 = 0x447cd; + SpicReleaseDeepPowerDownFlashRtl8195A = 0x44831; + HalSpiInitV02 = 0x4488d; + HalBootFlowV02 = 0x44a29; + HalInitialROMCodeGlobalVarV02 = 0x44ae5; + HalResetVsrV02 = 0x44b41; + HalI2CSendRtl8195aV02 = 0x44ce1; + HalI2CSetCLKRtl8195aV02 = 0x44d59; + RtkI2CSendV02 = 0x4508d; + RtkI2CReceiveV02 = 0x459a1; + HalI2COpInitV02 = 0x461ed; + I2CISRHandleV02 = 0x463e9; + RtkSalI2COpInitV02 = 0x46be1; + SpicLoadInitParaFromClockRtl8195AV02 = 0x46c25; + SpiFlashAppV02 = 0x46c85; + SpicInitRtl8195AV02 = 0x46dc5; + SpicEraseFlashRtl8195AV02 = 0x46ea1; + HalTimerIrq2To7HandleV02 = 0x46f5d; + HalTimerIrqRegisterRtl8195aV02 = 0x46fe1; + HalTimerInitRtl8195aV02 = 0x4706d; + HalTimerReadCountRtl8195aV02 = 0x471b5; + HalTimerReLoadRtl8195aV02 = 0x471d1; + HalTimerIrqUnRegisterRtl8195aV02 = 0x4722d; + HalTimerDeInitRtl8195aV02 = 0x472c1; + HalTimerOpInitV02 = 0x472f9; + GPIO_LockV02 = 0x47345; + GPIO_UnLockV02 = 0x47379; + GPIO_Int_Clear_8195aV02 = 0x473a5; + HAL_GPIO_IntCtrl_8195aV02 = 0x473b5; + FindElementIndexV02 = 0x47541; + HalRuartInitRtl8195aV02 = 0x4756d; + DramInit_rom = 0x47619; + ChangeRandSeed_rom = 0x47979; + Sdr_Rand2_rom = 0x47985; + MemTest_rom = 0x479dd; + SdrCalibration_rom = 0x47a45; + SdrControllerInit_rom = 0x47d99; + SDIO_EnterCritical = 0x47e39; + SDIO_ExitCritical = 0x47e85; + SDIO_IRQ_Handler_Rom = 0x47ec5; + SDIO_Interrupt_Init_Rom = 0x47f31; + SDIO_Device_Init_Rom = 0x47f81; + SDIO_Interrupt_DeInit_Rom = 0x48215; + SDIO_Device_DeInit_Rom = 0x48255; + SDIO_Enable_Interrupt_Rom = 0x48281; + SDIO_Disable_Interrupt_Rom = 0x482a1; + SDIO_Clear_ISR_Rom = 0x482c1; + SDIO_Alloc_Rx_Pkt_Rom = 0x482d9; + SDIO_Free_Rx_Pkt_Rom = 0x48331; + SDIO_Recycle_Rx_BD_Rom = 0x48355; + SDIO_RX_IRQ_Handler_BH_Rom = 0x484f1; + SDIO_RxTask_Rom = 0x4851d; + SDIO_Process_H2C_IOMsg_Rom = 0x4856d; + SDIO_Send_C2H_IOMsg_Rom = 0x4859d; + SDIO_Process_RPWM_Rom = 0x485b5; + SDIO_Reset_Cmd_Rom = 0x485e9; + SDIO_Rx_Data_Transaction_Rom = 0x48611; + SDIO_Send_C2H_PktMsg_Rom = 0x48829; + SDIO_Register_Tx_Callback_Rom = 0x488f5; + SDIO_ReadMem_Rom = 0x488fd; + SDIO_WriteMem_Rom = 0x489a9; + SDIO_SetMem_Rom = 0x48a69; + SDIO_TX_Pkt_Handle_Rom = 0x48b29; + SDIO_TX_FIFO_DataReady_Rom = 0x48c69; + SDIO_IRQ_Handler_BH_Rom = 0x48d95; + SDIO_TxTask_Rom = 0x48e9d; + SDIO_TaskUp_Rom = 0x48eed; + SDIO_Boot_Up = 0x48f55; + __rom_c_cut_text_end__ = 0x49070; + __rom_c_cut_rodata_start__ = 0x49070; + BAUDRATE_v02 = 0x49070; + OVSR_v02 = 0x490fc; + DIV_v02 = 0x49188; + OVSR_ADJ_v02 = 0x49214; + SdrDramInfo_rom = 0x492a0; /* DRAM_DEVICE_INFO *DramInfo */ + SdrDramTiming_rom = 0x492b4; + SdrDramModeReg_rom = 0x492e8; + SdrDramDev_rom = 0x49304; + __rom_c_cut_rodata_end__ = 0x49314; + + /* RAM data used in ROM */ + + __ram_image_start__ = 0x10000000; + __rom_bss_start__ = 0x10000300; + __ram_start_table_start__ = 0x10000bc8; + __rom_bss_end__ = 0x10000bc8; + + /* BOOT-LOADER */ + + gRamStartFun = 0x10000bc8; /* HalResetVsrV02(), HalResetVsr() */ + gRamPatchWAKE = 0x10000bcc; /* HalResetVsrV02(), HalResetVsr() */ + gRamPatchFun0 = 0x10000bd0; /* HalResetVsrV02(), HalResetVsr() */ + gRamPatchFun1 = 0x10000bd4; /* HalResetVsrV02(), HalResetVsr() */ + gRamPatchFun2 = 0x10000bd8; /* HalResetVsrV02(), HalResetVsr() */ + __image1_validate_code__ = 0x10000bdc; /* 8 bytes HalResetVsrV02(), HalResetVsr() */ + + +/* __ram_image_end__ = 0x10002100; */ + + /* End RAM data used in ROM */ + + /* 1006D000..1006F998: data SDIO_Device_Init_Rom(), SDIO_Boot_Up(), SDIO_TX_Pkt_Handle_Rom(),.. */ +} diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_dct.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_dct.a new file mode 100644 index 0000000..0a58c33 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_dct.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_http.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_http.a new file mode 100644 index 0000000..86ba7a7 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_http.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_mdns.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_mdns.a new file mode 100644 index 0000000..fd952ff Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_mdns.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform.a new file mode 100644 index 0000000..dcab8f0 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.a new file mode 100644 index 0000000..9bea09a Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.bat b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.bat new file mode 100644 index 0000000..d065674 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_platform_new.bat @@ -0,0 +1,19 @@ +set libname=lib_platform +del %libname%_new.a +md %libname%.lib +cd %libname%.lib +PATH=D:\MCU\GNU_Tools_ARM_Embedded\5.2_2015q4\bin;%PATH% +arm-none-eabi-ar.exe x ..\%libname%.a +del hal_efuse.o +del hal_common.o +del freertos_pmu_8195a.o +del hal_soc_ps_monitor.o +del app_start.o +del hal_log_uart.o +del hal_pinmux.o +del hal_misc.o +del startup.o +rem del hal_spi_flash_ram.o +arm-none-eabi-ar.exe ru ..\%libname%_new.a *.o +cd .. +rem rd /q /s %libname%.lib diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_rtlstd.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_rtlstd.a new file mode 100644 index 0000000..76c4910 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_rtlstd.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_sdcard.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_sdcard.a new file mode 100644 index 0000000..a4e51c7 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_sdcard.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_websocket.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_websocket.a new file mode 100644 index 0000000..d884696 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_websocket.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan.a new file mode 100644 index 0000000..393e0ec Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan_mp.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan_mp.a new file mode 100644 index 0000000..4a6ebbe Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wlan_mp.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wps.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wps.a new file mode 100644 index 0000000..ad496c4 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_wps.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_xmodem.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_xmodem.a new file mode 100644 index 0000000..efa037a Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/lib_xmodem.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rlx8195A-symbol-v04-img2.ld b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rlx8195A-symbol-v04-img2.ld new file mode 100644 index 0000000..b23a7ed --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rlx8195A-symbol-v04-img2.ld @@ -0,0 +1,256 @@ + +ENTRY(Reset_Handler) +ENTRY(main) + +INCLUDE "export-rom_v04.txt" + +MEMORY +{ + ROM (rx) : ORIGIN = 0x000000, LENGTH = 1M /* end 0x00100000 */ + ROM_USED_RAM (rwx): ORIGIN = 0x10000000, LENGTH = 0x2400 /* end 0x10002400 */ + BOOT_RAM (rwx) : ORIGIN = 0x10000bc8, LENGTH = 21560 /* end 0x10006000 */ + ROM_HEAP (rwx) : ORIGIN = 0x10002400, LENGTH = 3K /* end 0x10003000 */ + RAM_HEAP1 (rwx) : ORIGIN = 0x10003000, LENGTH = 12K /* end 0x10006000 */ + BD_RAM (rwx) : ORIGIN = 0x10006000, LENGTH = 424K /* end 0x10070000 */ + TCM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 64K /* end 0x20000000 */ + TCM_TAB (rwx) : ORIGIN = 0x1FFFFD00, LENGTH = 768 /* end 0x20000000 */ + SDRAM_RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 2M /* end 0x30200000 */ +} + +EXTERN(RAM_IMG2_VALID_PATTEN) +EXTERN(InfraStart) + +SECTIONS +{ + /* 0x00000000: ROM */ + + .rom : + { + __rom_image_start__ = .; + KEEP(*(.rom)); + __rom_image_end__ = .; + } > ROM + + /* 0x10000000: SRAM */ + + .rom_ram : /* use in rom */ + { + __ram_image_start__ = .; + KEEP(*(.ram_dedecated_vector_table)) /* 0x10000000: NewVectorTable */ + KEEP(*(.ram_user_define_irq_table)) /* 0x10000100: UserIrqFunTable */ + KEEP(*(.ram_user_define_data_table)) /* 0x10000200: UserIrqDataTable */ + __rom_bss_start__ = .; + KEEP(*(.hal.ram.bss)) /* 0x10000300: CfgSysDebugWarn .. _pHAL_Gpio_Adapter */ + KEEP(*(.timer2_7_vector_table.data)) /* 0x10000358: Timer2To7VectorTable */ + KEEP(*(.infra.ram.bss)) /* 0x10000370: first .. z4 */ + KEEP(*(.mon.ram.bss)) /* 0x10000384: pUartLogCtl .. ArgvArray */ + KEEP(*(.wlan_ram_map)) /* 0x100006d4: rom_wlan_ram_map, FalseAlmCnt, ROMInfo, DM_CfoTrack */ + KEEP(*(.ram.rom.wlanmap)) /* align(8) */ + KEEP(*(.libc.ram.bss)) /* 0x10000760: rom_libgloss_ram_map __rtl_malloc_av_ __rtl_errno */ + __rom_bss_end__ = .; + } > ROM_USED_RAM + + /* 0x10000bc8: bootloader */ + + .ram_image1.text . : /* use in rom & boot */ + { + /* __ram_start_table_start__ = .; */ + __ram_image1_text_start__ = .; + KEEP(*(.boot.start.ram.data*)) + /* __image1_validate_code__ = .; */ + KEEP(*(.image1.validate.rodata)) + + KEEP(*(.infra.ram.data*)) + KEEP(*(.timer.ram.data*)) + KEEP(*(.cutb.ram.data*)) + KEEP(*(.cutc.ram.data*)) + KEEP(*(.libc.reent)) + KEEP(*(.rom.unc.data)) + KEEP(*(.sdr.rand2.data)) + + PROVIDE (__ram_image_end__ = .); /* 0x100020c0: end */ + + /* boot & images data */ + + KEEP(*(.hal.ram.data)) + KEEP(*(.hal.flash.data)) + KEEP(*(.boot.rodata*)) + KEEP(*(.boot.text*)) + KEEP(*(.boot.data*)) + __image1_bss_start__ = .; + KEEP(*(.boot.bss*)) + __image1_bss_end__ = .; + __ram_image1_text_end__ = .; + + } > BOOT_RAM + + .romheap : + { + __rom_heap_start__ = .; + end = __rom_heap_start__; + . = ALIGN(0x1000); + __rom_heap_end__ = .; + } > ROM_HEAP + + .ram_heap1 : + { + __ram_heap1_start__ = .; + /* *(.heap1*) */ + } > RAM_HEAP1 + + .tcm : + { + __ram_tcm_start__ = .; + __tcm_heap_start__ = .; + *(.tcm.heap) + } > TCM + + .soc_ps_monitor : + { + __tcm_heap_end__ = .; + } > TCM_TAB + + .image2.start.table : + { + __ram_heap1_end__ = .; + __ram_image2_text_start__ = .; + __image2_entry_func__ = .; + .image2.start.table1$$Base = .; + KEEP(*(SORT(.image2.ram.data*))) + __image2_validate_code__ = .; + KEEP(*(.image2.validate.rodata*)) + KEEP(*(.custom.validate.rodata*)) + } > BD_RAM + + .ram_image2.text : + { + *(.infra.ram.start*) + . = ALIGN(4); + KEEP(*(.init)) + + /* init data */ + . = ALIGN(4); + PROVIDE (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE (__init_array_end = .); + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + PROVIDE (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE (__fini_array_end = .); + + *(.mon.ram.text*) + *(.hal.flash.text*) + *(.hal.sdrc.text*) + *(.hal.gpio.text*) + *(.fwu.text*) + *(.otg.rom.text*) + *(.text*) + *(.sdram.text*) + *(.p2p.text*) + *(.wps.text*) + *(.websocket.text*) + } > BD_RAM + + .ram_image2.rodata : + { + *(.rodata*) + *(.fwu.rodata*) + *(.sdram.rodata*) + *(.p2p.rodata*) + *(.wps.rodata*) + *(.websocket.rodata*) + . = ALIGN(4); + xHeapRegions = .; + LONG(__ram_heap1_start__) + LONG(__ram_heap1_end__ - __ram_heap1_start__) + LONG(__ram_heap2_start__) + LONG(__ram_heap2_end__ - __ram_heap2_start__) + LONG(__sdram_heap_start__) + LONG(__sdram_heap_end__ - __sdram_heap_start__) + LONG(0) + LONG(0) + UartLogRamCmdTable = .; + KEEP(*(SORT(.mon.tab*))) + UartLogRamCmdTable_end = .; + LONG(0) + } > BD_RAM + + PROVIDE(UartLogRamCmdTableSize = UartLogRamCmdTable_end - UartLogRamCmdTable); + + .ram.data : + { + __data_start__ = .; + *(.data*) + *(.p2p.data*) + *(.wps.data*) + *(.websocket.data*) + *(.sdram.data*) + __data_end__ = .; + __ram_image2_text_end__ = .; + } > BD_RAM + + .ram.bss : + { + __bss_start__ = .; + .ram.bss$$Base = .; + *(.hal.flash.data*) + *(.hal.sdrc.data*) + *(.hal.gpio.data*) + *(.fwu.data*) + *(.bdsram.data*) + *(.bfsram.data*) + *(COMMON) + *(.bss*) + *(.sdram.bss*) + *(.p2p.bss*) + *(.wps.bss*) + *(.websocket.bss*) + *(.ssl_ram_map*) + __bss_end__ = .; + .ram.bss$$Limit = .; + + } > BD_RAM + + .ram_heap2 : + { + . = ALIGN(8); + __ram_heap2_start__ = .; + *(.heap*) /* ucHeap */ + } > BD_RAM + __ram_heap2_end__ = 0x10070000; + + .sdr_text : + { + __sdram_data_start__ = .; + } > SDRAM_RAM + + .sdr_rodata : + { + } > SDRAM_RAM + + .sdr_data : + { + __sdram_data_end__ = .; + } > SDRAM_RAM + + .sdr_bss : + { + __sdram_bss_start__ = .; + __sdram_bss_end__ = .; + . = ALIGN(8); + __sdram_heap_start__ = .; + } > SDRAM_RAM + __sdram_heap_end__ = 0x30200000; + + .boot.head : + { + KEEP(*(.loader.head*)) + } + ASSERT(__ram_image_end__ == 0x100020c0, "Error rom-bios-boot code & data!") +} diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rtl871xAx-symbol-v04-img1.ld b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rtl871xAx-symbol-v04-img1.ld new file mode 100644 index 0000000..5b9a8c2 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/bsp/lib/common/GCC/rtl871xAx-symbol-v04-img1.ld @@ -0,0 +1,240 @@ + + +ENTRY(Reset_Handler) + +INCLUDE "export-rom_v04.txt" + + +MEMORY +{ + ROM (rx) : ORIGIN = 0x000000, LENGTH = 1M + ROM_RAM1 (rwx): ORIGIN = 0x10000000, LENGTH = 0x2100 /* end 0x10002100 */ + BOOT_RAM (rwx): ORIGIN = 0x10000bc8, LENGTH = 13368 /* end 0x10006000 */ + RECY_RAM (rwx): ORIGIN = 0x10002100, LENGTH = 0x3F00 /* end 0x10006000 */ + BD_RAM (rwx) : ORIGIN = 0x10006000, LENGTH = 424K /* end 0x10070000 */ + ROM_RAM3 (rwx): ORIGIN = 0x1006D000, LENGTH = 12K /* end 0x10070000 */ + TCM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 64K /* end 0x20000000 */ + SDRAM (rwx) : ORIGIN = 0x30000000, LENGTH = 2M /* end 0x30200000 */ +} + +EXTERN(PreProcessForVendor) +EXTERN(RtlBootToSram) +EXTERN(_rtl_impure_ptr) +EXTERN(impure_data) + +SECTIONS +{ + /* 0x00000000: ROM */ + + .rom : + { + __rom_image_start__ = .; + KEEP(*(.rom)); + __rom_image_end__ = .; + } > ROM + + /* 0x10000000: SRAM */ + + .rom_ram : /* use in rom */ + { + __ram_image_start__ = .; + KEEP(*(.ram_dedecated_vector_table)) /* 0x10000000: NewVectorTable */ + KEEP(*(.ram_user_define_irq_table)) /* 0x10000100: UserIrqFunTable */ + KEEP(*(.ram_user_define_data_table)) /* 0x10000200: UserIrqDataTable */ + /* __rom_bss_start__ = .; */ + KEEP(*(.hal.ram.bss)) /* 0x10000300: CfgSysDebugWarn .. _pHAL_Gpio_Adapter */ + KEEP(*(.timer2_7_vector_table.data)) /* 0x10000358: Timer2To7VectorTable */ + KEEP(*(.infra.ram.bss)) /* 0x10000370: first .. z4 */ + KEEP(*(.mon.ram.bss)) /* 0x10000384: pUartLogCtl .. ArgvArray */ + KEEP(*(.wlan_ram_map)) /* 0x100006d4: rom_wlan_ram_map, FalseAlmCnt, ROMInfo, DM_CfoTrack */ + KEEP(*(.ram.rom.wlanmap)) /* align(8) */ + KEEP(*(.libc.ram.bss)) /* 0x10000760: rom_libgloss_ram_map __rtl_malloc_av_ __rtl_errno */ + /* __rom_bss_end__ = .; */ + } > ROM_RAM1 + + /* 0x10000bc8: bootloader */ + .ram_image1.text . : /* use in rom & boot */ + { + /* __ram_start_table_start__ = .; */ + __ram_image1_text_start__ = .; + KEEP(*(SORT(.start.ram.data*))) + /* __image1_validate_code__ = .; */ + KEEP(*(.image1.validate.rodata)) + + KEEP(*(.infra.ram.data*)) + KEEP(*(.timer.ram.data*)) + KEEP(*(.cutb.ram.data*)) + KEEP(*(.cutc.ram.data*)) + KEEP(*(.data)); + KEEP(*(.hal.ram.data)) + KEEP(*(.libc.reent)) + KEEP(*(.rom.unc.data)) + KEEP(*(.sdr.rand2.data)) + build/obj/project/src/user/rtl_bios_data.o (.rodata*) + __ram_image_end__ = .; + /* 0x100020c0: end */ + build/obj/project/src/user/rtl_boot.o (.text* .rodata*) + __image1_bss_start__ = .; + __image1_bss_end__ = .; + __ram_image1_text_end__ = .; + } > BOOT_RAM + + .tcm : + { + __tcm_start__ = .; + *(.tcm.heap) + __tcm_end__ = .; + } > TCM + + .image2.start.table : + { + __ram_image2_text_start__ = .; + __image2_entry_func__ = .; + .image2.start.table1$$Base = .; + KEEP(*(SORT(.image2.ram.data*))) + __image2_validate_code__ = .; + KEEP(*(.image2.validate.rodata*)) + KEEP(*(.custom.validate.rodata*)) + } > BD_RAM + + .ram_image2.text : + { + *(.infra.ram.start*) + *(.mon.ram.text*) + *(.hal.flash.text*) + *(.hal.sdrc.text*) + *(.hal.gpio.text*) + *(.fwu.text*) + *(.text*) + *(.sdram.text*) + *(.p2p.text*) + *(.wps.text*) + *(.websocket.text*) + } > BD_RAM + + .ram_image2.rodata : + { + *(.rodata*) + *(.fwu.rodata*) + *(.sdram.rodata*) + *(.p2p.rodata*) + *(.wps.rodata*) + *(.websocket.rodata*) + } > BD_RAM + + .ram.data : + { + __data_start__ = .; + *(.data*) + *(.sdram.data*) + *(.p2p.data*) + *(.wps.data*) + *(.websocket.data*) + __data_end__ = .; + __ram_image2_text_end__ = .; + } > BD_RAM + + .ram.bss : + { + __bss_start__ = .; + .ram.bss$$Base = .; + *(.hal.flash.data*) + *(.hal.sdrc.data*) + *(.hal.gpio.data*) + *(.fwu.data*) + *(.bss*) + *(COMMON) + *(.bdsram.data*) + *(.sdram.bss*) + *(.p2p.bss*) + *(.wps.bss*) + *(.websocket.bss*) + __bss_end__ = .; + .ram.bss$$Limit = .; + } > BD_RAM + + .bf_data : + { + __buffer_data_start__ = .; + *(.bfsram.data*) + __buffer_data_end__ = .; + } > BD_RAM + + .bf_data2 : + { + __buffer_data_start2__ = .; + __buffer_data_end2__ = .; + + } > RECY_RAM + + .sdr_text : + { + __sdram_data_start__ = .; + } > SDRAM + + .sdr_rodata : + { + } > SDRAM + + .sdr_data : + { + __sdram_data_end__ = .; + } > SDRAM + + .sdr_bss : + { + __sdram_bss_start__ = .; + __sdram_bss_end__ = .; + } > SDRAM + + .heap : + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > BD_RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy : + { + *(.stack) + } > BD_RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(BD_RAM) + LENGTH(BD_RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + .boot.head : + { + KEEP(*(.loader.head*)) + } + + .image1.head : + { + KEEP(*(SORT(.image1.head*))) + } + + .image2.head : + { + KEEP(*(SORT(.image2.head*))) + } + + .image3.head : + { + KEEP(*(SORT(.image3.head*))) + } + + .image4.head : + { + KEEP(*(SORT(.image4.head*))) + } + +} diff --git a/USDK/component/soc/realtek/8195a/misc/bsp/lib/va0/rom.a b/USDK/component/soc/realtek/8195a/misc/bsp/lib/va0/rom.a new file mode 100644 index 0000000..4b7947a Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/bsp/lib/va0/rom.a differ diff --git a/USDK/component/soc/realtek/8195a/misc/driver/console_hs_uart.c b/USDK/component/soc/realtek/8195a/misc/driver/console_hs_uart.c new file mode 100644 index 0000000..54f6ba8 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/console_hs_uart.c @@ -0,0 +1,247 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2016 Realtek Corporation. All rights reserved. + * + * + ******************************************************************************/ +#include +#include "FreeRTOS.h" +#include "task.h" +#include +#include "semphr.h" +#include "device.h" +#include "serial_api.h" +#include "at_cmd/log_service.h" +#include "osdep_service.h" +#include "serial_ex_api.h" +#include "pinmap.h" + +char hs_uart_ready = 0; // used to switch between loguart and high speed uart + // 0: loguart + // 1: highspeed uart + +// select uart tx/rx pin with gpio interrupt function +#define UART_TX PA_7 +#define UART_RX PA_6 + +#define KEY_NL 0xa // '\n' +#define KEY_ENTER 0xd // '\r' +#define KEY_BS 0x8 +#define KEY_ESC 0x1B +#define KEY_LBRKT 0x5B +#define STR_END_OF_MP_FORMAT "\r\n\r\r#" + + +#define CMD_HISTORY_LEN 4 // max number of executed command saved +extern char log_buf[LOG_SERVICE_BUFLEN]; +extern xSemaphoreHandle log_rx_interrupt_sema; +char cmd_history[CMD_HISTORY_LEN][LOG_SERVICE_BUFLEN]; +static unsigned int cmd_history_count = 0; + +serial_t loguart_sobj; +//_sema at_printf_sema; +_sema hs_uart_dma_tx_sema; + +#define HS_UART_USE_DMA_TX 1 + +void hs_uart_put_char(u8 c){ + serial_putc(&loguart_sobj, c); +} + +void hs_uart_send_string(char *str) +{ + unsigned int i=0; + while (str[i] != '\0') { + serial_putc(&loguart_sobj, str[i]); + i++; + } +} + +#if UART_AT_USE_DMA_TX +static void hs_uart_send_buf_done(uint32_t id) +{ + //serial_t *sobj = (serial_t *)id; + + rtw_up_sema_from_isr(&uart_at_dma_tx_sema); +} +#endif + +void hs_uart_send_buf(u8 *buf, u32 len) +{ + unsigned char *st_p=buf; + if(!len || (!buf)){ + return; + } +#if UART_AT_USE_DMA_TX + int ret; + while(rtw_down_sema(&uart_at_dma_tx_sema) == _TRUE){ + ret = serial_send_stream_dma(&loguart_sobj, st_p, len); + if(ret != HAL_OK){ + rtw_up_sema(&uart_at_dma_tx_sema); + return; + }else{ + return; + } + } +#else + while(len){ + serial_putc(&loguart_sobj, *st_p); + st_p++; + len--; + } +#endif +} + +void hs_uart_irq(uint32_t id, SerialIrq event) +{ + serial_t *sobj = (serial_t *)id; + unsigned char rc=0; + static unsigned char temp_buf[LOG_SERVICE_BUFLEN] = "\0"; + static unsigned char combo_key = 0; + static unsigned short buf_count = 0; + static unsigned char key_enter = 0; + static char cmd_history_index = 0; + if(event == RxIrq) { + rc = serial_getc(sobj); + + if(key_enter && rc == KEY_NL){ + //serial_putc(sobj, rc); + return; + } + + if(rc == KEY_ESC){ + combo_key = 1; + }else if(combo_key == 1){ + if(rc == KEY_LBRKT) + combo_key = 2; + else + combo_key = 0; + }else if(combo_key == 2){ + if(rc == 'A' || rc == 'B'){ // UP or Down + if(rc == 'A'){ + cmd_history_index--; + if(cmd_history_index < 0) + cmd_history_index = (cmd_history_count>CMD_HISTORY_LEN)?CMD_HISTORY_LEN-1:(cmd_history_count-1)%CMD_HISTORY_LEN; + }else{ + cmd_history_index++; + if(cmd_history_index > (cmd_history_count>CMD_HISTORY_LEN?CMD_HISTORY_LEN-1:(cmd_history_count-1)%CMD_HISTORY_LEN)) + cmd_history_index = 0; + } + + if(cmd_history_count > 0){ + buf_count = strlen(temp_buf); + rtw_memset(temp_buf,'\0',buf_count); + while(--buf_count >= 0){ + serial_putc(sobj, KEY_BS); + serial_putc(sobj, ' '); + serial_putc(sobj, KEY_BS); + } + hs_uart_send_string(cmd_history[cmd_history_index%CMD_HISTORY_LEN]); + strcpy(temp_buf, cmd_history[cmd_history_index%CMD_HISTORY_LEN]); + buf_count = strlen(temp_buf); + } + } + + // exit combo + combo_key = 0; + } + else if(rc == KEY_ENTER){ + key_enter = 1; + if(buf_count>0){ + serial_putc(sobj, KEY_NL); + serial_putc(sobj, KEY_ENTER); + rtw_memset(log_buf,'\0',LOG_SERVICE_BUFLEN); + strncpy(log_buf,(char *)&temp_buf[0],buf_count); + rtw_up_sema_from_isr(&log_rx_interrupt_sema); + rtw_memset(temp_buf,'\0',buf_count); + + /* save command */ + rtw_memset(cmd_history[((cmd_history_count)%CMD_HISTORY_LEN)], '\0', buf_count+1); + strcpy(cmd_history[((cmd_history_count++)%CMD_HISTORY_LEN)], log_buf); + cmd_history_index = cmd_history_count%CMD_HISTORY_LEN; + //cmd_history_count++; + buf_count=0; + }else{ + hs_uart_send_string(STR_END_OF_MP_FORMAT); + } + } + else if(rc == KEY_BS){ + if(buf_count>0){ + buf_count--; + temp_buf[buf_count] = '\0'; + + serial_putc(sobj, rc); + serial_putc(sobj, ' '); + serial_putc(sobj, rc); + } + } + else{ + /* cache input characters */ + if(buf_count < (LOG_SERVICE_BUFLEN - 1)){ + temp_buf[buf_count] = rc; + buf_count++; + serial_putc(sobj, rc); + key_enter = 0; + } + else if(buf_count == (LOG_SERVICE_BUFLEN - 1)){ + temp_buf[buf_count] = '\0'; + + hs_uart_send_string("\r\nERROR:exceed size limit"STR_END_OF_ATCMD_RET); + } + } + } +} + +void console_init_hs_uart(void) +{ + serial_init(&loguart_sobj,UART_TX,UART_RX); + serial_baud(&loguart_sobj,38400); + serial_format(&loguart_sobj, 8, ParityNone, 1); + +#if UART_AT_USE_DMA_TX + rtw_init_sema(&hs_uart_dma_tx_sema, 1); + serial_send_comp_handler(&loguart_sobj, (void*)hs_uart_send_buf_done, (uint32_t)&loguart_sobj); +#endif + + serial_irq_handler(&loguart_sobj, hs_uart_irq, (uint32_t)&loguart_sobj); + serial_irq_set(&loguart_sobj, RxIrq, 1); + + for(char i=0; i +#include "serial_api.h" +#include "serial_ex_api.h" +#include "PinNames.h" +#include "i2c_api.h" +#include "pinmap.h" +#include "ex_api.h" + +#define MBED_I2C_MTR_SDA PB_3 //i2c3 +#define MBED_I2C_MTR_SCL PB_2 + +#define UART_BAUDRATE 115200 + +#define MBED_I2C_SLAVE_ADDR0 0x4D // 0x9A // +#define MBED_I2C_BUS_CLK 500000 //hz *Remind that in baud rate 9600 or 19200, 100000hz is suitable* + +static i2c_t i2cmaster; + +#define I2C_DATA_LENGTH 2 +static char i2cdatardsrc[I2C_DATA_LENGTH]; +static char i2cdatarddst[I2C_DATA_LENGTH]; + +const u8 DLL = 921600/UART_BAUDRATE; + +char ctrl_initial_1[2] = {0x03 << 3,0x80}; +char ctrl_initial_2[2] = {0x00 << 3,921600/UART_BAUDRATE}; +char ctrl_initial_3[2] = {0x01 << 3,0x00}; +char ctrl_initial_4[2] = {0x03 << 3,0xbf}; +char ctrl_initial_5[2] = {0x02 << 3,0x10}; +char ctrl_initial_6[2] = {0x03 << 3,0x03}; +char ctrl_initial_7[2] = {0x02 << 3,0x06}; +char ctrl_initial_8[2] = {0x02 << 3,0x01}; +//end i2c + + +// Master// Tx +#define CLEAR_MST_TXC_FLAG (masterTXC = 0) +#define SET_MST_TXC_FLAG (masterTXC = 1) +#define WAIT_MST_TXC while(masterTXC == 0){;} + +volatile int masterTXC; +static char i2c_ready = 0; + + +static void i2c_master_rxc_callback(void *userdata) +{ + + int i2clocalcnt; + int result = 0; + + // verify result + result = 1; + for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) { + if (i2cdatarddst[i2clocalcnt] != i2cdatardsrc[i2clocalcnt]) { + result = 0; + break; + } + } +} + +static void i2c_master_txc_callback(void *userdata) +{ + SET_MST_TXC_FLAG; +} + +static void i2c_master_write(void) +{ + + //DBG_8195A("Mst-W\n"); + CLEAR_MST_TXC_FLAG; + + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_1[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_2[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_3[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_4[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_5[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_6[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_7[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &ctrl_initial_8[0], 2, 1); + + WAIT_MST_TXC; + +} + +static void i2c_master_enable(void) +{ + _memset(&i2cmaster, 0x00, sizeof(i2c_t)); + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); + i2c_set_user_callback(&i2cmaster, I2C_RX_COMPLETE, i2c_master_rxc_callback); + i2c_set_user_callback(&i2cmaster, I2C_TX_COMPLETE, i2c_master_txc_callback); + //i2c_set_user_callback(&i2cmaster, I2C_ERR_OCCURRED, i2c_master_err_callback); + +} + +void i2c_redirect_init(void) +{ + + // prepare for transmission + + _memset(&i2cdatardsrc[0], 0x00, I2C_DATA_LENGTH); + _memset(&i2cdatarddst[0], 0x00, I2C_DATA_LENGTH); + + i2c_ready = 1; + + i2c_master_enable(); + i2c_master_write(); + +} + +static u8 tx_data_i2c[2]; +static u8 rx_data_i2c[2]; + +void i2c_put_char(u8 c){ + + _memset(&tx_data_i2c[0],0x00,2); + _memset(&rx_data_i2c[0],0x00,2); + tx_data_i2c[0] = 0x00 << 3; + tx_data_i2c[1] = c; + i2c_write(&i2cmaster, 0x4D, &tx_data_i2c[0], 2, 1); + i2c_read (&i2cmaster, 0x4D, &rx_data_i2c[0], 2, 1); +} + +int use_mode; + +void console_init(void) +{ + i2c_redirect_init(); + + if(HalCheckSDramExist()){ + //DiagPrintf("It's 8195_AM\n"); + redirect_rom_init(); + } + +#if !TASK_SCHEDULER_DISABLED + RtlConsolInitRam((u32)RAM_STAGE,(u32)0,(VOID*)NULL); +#else + RtlConsolInitRam((u32)ROM_STAGE,(u32)0,(VOID*)NULL); +#endif + +#if BUFFERED_PRINTF + rtl_printf_init(); +#endif +} + + + +VOID HalSerialPutcRtl8195a(IN u8 c){ + + u32 CounterIndex = 0; + + extern char i2c_ready; + if(i2c_ready) + i2c_put_char(c); + +} + + + + + + + + + + diff --git a/USDK/component/soc/realtek/8195a/misc/driver/low_level_io.c b/USDK/component/soc/realtek/8195a/misc/driver/low_level_io.c new file mode 100644 index 0000000..317e288 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/low_level_io.c @@ -0,0 +1,119 @@ +#include +#include "hal_api.h" +#include "rtl8195a.h" +#include "platform_opts.h" + +#if !defined (__ICCARM__) +extern u8 RAM_IMG1_VALID_PATTEN[]; +void *tmp = RAM_IMG1_VALID_PATTEN; +#endif + +//for internal test +#ifdef USE_MODE + extern int use_mode; + void mode_init(void){use_mode = 1;} +#endif + +#if defined ( __ICCARM__ ) +size_t __write(int Handle, const unsigned char * Buf, size_t Bufsize) +{ + int nChars = 0; + /* Check for stdout and stderr + (only necessary if file descriptors are enabled.) */ + if (Handle != 1 && Handle != 2) + { + return -1; + } + for (/*Empty */; Bufsize > 0; --Bufsize) + { + DiagPutChar(*Buf++); + ++nChars; + } + return nChars; +} + +size_t __read(int Handle, unsigned char * Buf, size_t Bufsize) +{ + int nChars = 0; + /* Check for stdin + (only necessary if FILE descriptors are enabled) */ + if (Handle != 0) + { + return -1; + } + for (/*Empty*/; Bufsize > 0; --Bufsize) + { + int c = DiagGetChar(_FALSE); + if (c < 0) + break; + *(Buf++) = c; + ++nChars; + } + return nChars; +} +#endif + + + +int disablePrintf = FALSE; + + +__weak VOID HalSerialPutcRtl8195a(IN u8 c){ + + u32 CounterIndex = 0; + + if(disablePrintf == TRUE) return; + + while(1) { + CounterIndex++; + if (CounterIndex >=6540) + break; + + if (HAL_UART_READ8(UART_LINE_STATUS_REG_OFF) & 0x60) + break; + } + HAL_UART_WRITE8(UART_TRAN_HOLD_OFF, c); + if (c == 0x0a) { + HAL_UART_WRITE8(UART_TRAN_HOLD_OFF, 0x0d); + } +} + + + + +#include +u32 +DiagPrintf( + IN const char *fmt, ... +) +{ + if(disablePrintf == TRUE) return _TRUE; + + (void)VSprintf(0, fmt, ((const int *)&fmt)+1); + return _TRUE; +} + +extern u32 ConfigDebugErr; +extern u32 ConfigDebugInfo; +extern u32 ConfigDebugWarn; +static u32 backupErr; +static u32 backupInfo; +static u32 backupWarn; +void log_uart_enable_printf(void) +{ + disablePrintf = FALSE; + ConfigDebugErr = backupErr; + ConfigDebugInfo = backupInfo; + ConfigDebugWarn = backupWarn; +} + +void log_uart_disable_printf(void) +{ + disablePrintf = TRUE; + backupErr = ConfigDebugErr; + backupInfo = ConfigDebugInfo; + backupWarn = ConfigDebugWarn; + ConfigDebugErr = 0; + ConfigDebugInfo = 0; + ConfigDebugWarn = 0; +} \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.c b/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.c new file mode 100644 index 0000000..6e20814 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.c @@ -0,0 +1,487 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "rtl8195a.h" +//#include +#include "rtl_consol.h" +#include "FreeRTOS.h" +#include "task.h" +#include +#include "semphr.h" +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "freertos_pmu.h" +#endif +#include "tcm_heap.h" + +// Those symbols will be defined in linker script for gcc compiler +// If not doing this would cause extra memory cost +#if defined (__GNUC__) + + extern volatile UART_LOG_CTL UartLogCtl; + extern volatile UART_LOG_CTL *pUartLogCtl; + extern u8 *ArgvArray[MAX_ARGV]; + extern UART_LOG_BUF UartLogBuf; + +#ifdef CONFIG_UART_LOG_HISTORY + extern u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; +#endif + +#else + +MON_RAM_BSS_SECTION + volatile UART_LOG_CTL UartLogCtl; +MON_RAM_BSS_SECTION + volatile UART_LOG_CTL *pUartLogCtl; +MON_RAM_BSS_SECTION + u8 *ArgvArray[MAX_ARGV]; +MON_RAM_BSS_SECTION + UART_LOG_BUF UartLogBuf; + +#ifdef CONFIG_UART_LOG_HISTORY +MON_RAM_BSS_SECTION + u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; +#endif + +#endif + +#ifdef CONFIG_KERNEL +static void (*up_sema_from_isr)(_sema *) = NULL; +#endif + + +_LONG_CALL_ +extern u8 +UartLogCmdChk( + IN u8 RevData, + IN UART_LOG_CTL *prvUartLogCtl, + IN u8 EchoFlag +); + +_LONG_CALL_ +extern VOID +ArrayInitialize( + IN u8 *pArrayToInit, + IN u8 ArrayLen, + IN u8 InitValue +); + +_LONG_CALL_ +extern VOID +UartLogHistoryCmd( + IN u8 RevData, + IN UART_LOG_CTL *prvUartLogCtl, + IN u8 EchoFlag +); + +_LONG_CALL_ +extern VOID +UartLogCmdExecute( + IN PUART_LOG_CTL pUartLogCtlExe +); + + + +//================================================= + + +/* Minimum and maximum values a `signed long int' can hold. + (Same as `int'). */ +#ifndef __LONG_MAX__ +#if defined (__alpha__) || (defined (__sparc__) && defined(__arch64__)) || defined (__sparcv9) || defined (__s390x__) +#define __LONG_MAX__ 9223372036854775807L +#else +#define __LONG_MAX__ 2147483647L +#endif /* __alpha__ || sparc64 */ +#endif +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1) + +#ifndef __LONG_LONG_MAX__ +#define __LONG_LONG_MAX__ 9223372036854775807LL +#endif + + + + +//====================================================== +//: UartLogIrqHandleRam +//: To deal with Uart-Log RX IRQ +//: VOID +//: VOID +//: NA +//====================================================== +//MON_RAM_TEXT_SECTION +VOID +UartLogIrqHandleRam +( + VOID * Data +) +{ + u8 UartReceiveData = 0; + //For Test + BOOL PullMode = _FALSE; + + u32 IrqEn = DiagGetIsrEnReg(); + + DiagSetIsrEnReg(0); + + UartReceiveData = DiagGetChar(PullMode); + if (UartReceiveData == 0) { + goto exit; + } + + //KB_ESC chk is for cmd history, it's a special case here. + if (UartReceiveData == KB_ASCII_ESC) { + //4 Esc detection is only valid in the first stage of boot sequence (few seconds) + if (pUartLogCtl->ExecuteEsc != _TRUE) + { + pUartLogCtl->ExecuteEsc = _TRUE; + (*pUartLogCtl).EscSTS = 0; + } + else + { + //4 the input commands are valid only when the task is ready to execute commands + if ((pUartLogCtl->BootRdy == 1) +#ifdef CONFIG_KERNEL + ||(pUartLogCtl->TaskRdy == 1) +#endif + ) + { + if ((*pUartLogCtl).EscSTS==0) + { + (*pUartLogCtl).EscSTS = 1; + } + } + else + { + (*pUartLogCtl).EscSTS = 0; + } + } + } + else if ((*pUartLogCtl).EscSTS==1){ + if (UartReceiveData != KB_ASCII_LBRKT){ + (*pUartLogCtl).EscSTS = 0; + } + else{ + (*pUartLogCtl).EscSTS = 2; + } + } + + else{ + if ((*pUartLogCtl).EscSTS==2){ + (*pUartLogCtl).EscSTS = 0; +#ifdef CONFIG_UART_LOG_HISTORY + if ((UartReceiveData=='A')|| UartReceiveData=='B'){ + UartLogHistoryCmd(UartReceiveData,(UART_LOG_CTL *)pUartLogCtl,1); + } +#endif + } + else{ + if (UartLogCmdChk(UartReceiveData,(UART_LOG_CTL *)pUartLogCtl,1)==2) + { + //4 check UartLog buffer to prevent from incorrect access + if (pUartLogCtl->pTmpLogBuf != NULL) + { + pUartLogCtl->ExecuteCmd = _TRUE; +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + if (pUartLogCtl->TaskRdy && up_sema_from_isr != NULL) + //RtlUpSemaFromISR((_Sema *)&pUartLogCtl->Sema); + up_sema_from_isr((_sema *)&pUartLogCtl->Sema); +#endif + } + else + { + ArrayInitialize((u8 *)pUartLogCtl->pTmpLogBuf->UARTLogBuf, UART_LOG_CMD_BUFLEN, '\0'); + } + } + } + } +exit: + DiagSetIsrEnReg(IrqEn); + +} + + + +//MON_RAM_TEXT_SECTION +VOID +RtlConsolInitRam( + IN u32 Boot, + IN u32 TBLSz, + IN VOID *pTBL +) +{ + UartLogBuf.BufCount = 0; + ArrayInitialize(&UartLogBuf.UARTLogBuf[0],UART_LOG_CMD_BUFLEN,'\0'); + pUartLogCtl = &UartLogCtl; + + pUartLogCtl->NewIdx = 0; + pUartLogCtl->SeeIdx = 0; + pUartLogCtl->RevdNo = 0; + pUartLogCtl->EscSTS = 0; + pUartLogCtl->BootRdy = 0; + pUartLogCtl->pTmpLogBuf = &UartLogBuf; +#ifdef CONFIG_UART_LOG_HISTORY + pUartLogCtl->CRSTS = 0; + pUartLogCtl->pHistoryBuf = &UartLogHistoryBuf[0]; +#endif + pUartLogCtl->pfINPUT = (VOID*)&DiagPrintf; + pUartLogCtl->pCmdTbl = (PCOMMAND_TABLE) pTBL; + pUartLogCtl->CmdTblSz = TBLSz; +#ifdef CONFIG_KERNEL + pUartLogCtl->TaskRdy = 0; +#endif + //executing boot sequence + if (Boot == ROM_STAGE) + { + pUartLogCtl->ExecuteCmd = _FALSE; + pUartLogCtl->ExecuteEsc = _FALSE; + } + else + { + pUartLogCtl->ExecuteCmd = _FALSE; + pUartLogCtl->ExecuteEsc= _TRUE;//don't check Esc anymore +#if defined(CONFIG_KERNEL) + /* Create a Semaphone */ + //RtlInitSema((_Sema*)&(pUartLogCtl->Sema), 0); + rtw_init_sema((_sema*)&(pUartLogCtl->Sema), 0); + pUartLogCtl->TaskRdy = 0; +#ifdef PLATFORM_FREERTOS +#define LOGUART_STACK_SIZE 128 //USE_MIN_STACK_SIZE modify from 512 to 128 +#if CONFIG_USE_TCM_HEAP + { + int ret = 0; + void *stack_addr = tcm_heap_malloc(LOGUART_STACK_SIZE*sizeof(int)); + //void *stack_addr = rtw_malloc(stack_size*sizeof(int)); + if(stack_addr == NULL){ + DiagPrintf("Out of TCM heap in \"LOGUART_TASK\" "); + } + ret = xTaskGenericCreate( + RtlConsolTaskRam, + (const char *)"LOGUART_TASK", + LOGUART_STACK_SIZE, + NULL, + tskIDLE_PRIORITY + 5 + PRIORITIE_OFFSET, + NULL, + stack_addr, + NULL); + if (pdTRUE != ret) + { + DiagPrintf("Create Log UART Task Err!!\n"); + } + } +#else + if (pdTRUE != xTaskCreate( RtlConsolTaskRam, (const signed char * const)"LOGUART_TASK", LOGUART_STACK_SIZE, NULL, tskIDLE_PRIORITY + 5 + PRIORITIE_OFFSET, NULL)) + { + DiagPrintf("Create Log UART Task Err!!\n"); + } +#endif + +#endif + +#endif + } + + CONSOLE_8195A(); +} + +extern u8** GetArgv(const u8 *string); +#if SUPPORT_LOG_SERVICE +extern char log_buf[LOG_SERVICE_BUFLEN]; +extern xSemaphoreHandle log_rx_interrupt_sema; +#endif +//====================================================== +void console_cmd_exec(PUART_LOG_CTL pUartLogCtlExe) +{ + u8 CmdCnt = 0; + u8 argc = 0; + u8 **argv; + //u32 CmdNum; + PUART_LOG_BUF pUartLogBuf = pUartLogCtlExe->pTmpLogBuf; +#if SUPPORT_LOG_SERVICE + strncpy(log_buf, (const u8*)&(*pUartLogBuf).UARTLogBuf[0], LOG_SERVICE_BUFLEN-1); +#endif + argc = GetArgc((const u8*)&((*pUartLogBuf).UARTLogBuf[0])); + argv = GetArgv((const u8*)&((*pUartLogBuf).UARTLogBuf[0])); + + if(argc > 0){ +#if SUPPORT_LOG_SERVICE +// if(log_handler(argv[0]) == NULL) +// legency_interactive_handler(argc, argv); + //RtlUpSema((_Sema *)&log_rx_interrupt_sema); + rtw_up_sema((_sema *)&log_rx_interrupt_sema); +#endif + ArrayInitialize(argv[0], sizeof(argv[0]) ,0); + }else{ +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + pmu_acquire_wakelock(BIT(PMU_LOGUART_DEVICE)); +#endif + CONSOLE_8195A(); // for null command + } + + (*pUartLogBuf).BufCount = 0; + ArrayInitialize(&(*pUartLogBuf).UARTLogBuf[0], UART_LOG_CMD_BUFLEN, '\0'); +} +//====================================================== +// overload original RtlConsolTaskRam +//MON_RAM_TEXT_SECTION +VOID +RtlConsolTaskRam( + VOID *Data +) +{ +#if SUPPORT_LOG_SERVICE + log_service_init(); +#endif + //4 Set this for UartLog check cmd history +#ifdef CONFIG_KERNEL + pUartLogCtl->TaskRdy = 1; + up_sema_from_isr = rtw_up_sema_from_isr; +#endif +#ifndef CONFIG_KERNEL + pUartLogCtl->BootRdy = 1; +#endif + do{ +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + //RtlDownSema((_Sema *)&pUartLogCtl->Sema); + rtw_down_sema((_sema *)&pUartLogCtl->Sema); +#endif + if (pUartLogCtl->ExecuteCmd) { + // Add command handler here + console_cmd_exec((PUART_LOG_CTL)pUartLogCtl); + //UartLogCmdExecute((PUART_LOG_CTL)pUartLogCtl); + pUartLogCtl->ExecuteCmd = _FALSE; + } + }while(1); +} + +//====================================================== +#if BUFFERED_PRINTF +xTaskHandle print_task = NULL; +EventGroupHandle_t print_event = NULL; +char print_buffer[MAX_PRINTF_BUF_LEN]; +int flush_idx = 0; +int used_length = 0; + +int available_space(void) +{ + return MAX_PRINTF_BUF_LEN-used_length; +} + +int buffered_printf(const char* fmt, ...) +{ + if((print_task==NULL) || (print_event==NULL) ) + return 0; + char tmp_buffer[UART_LOG_CMD_BUFLEN+1]; + static int print_idx = 0; + int cnt; + + if(xEventGroupGetBits(print_event)!=1) + xEventGroupSetBits(print_event, 1); + + memset(tmp_buffer,0,UART_LOG_CMD_BUFLEN+1); + VSprintf(tmp_buffer, fmt, ((const int *)&fmt)+1); + cnt = _strlen(tmp_buffer); + if(cnt < available_space()){ + if(print_idx >= flush_idx){ + if(MAX_PRINTF_BUF_LEN-print_idx >= cnt){ + memcpy(&print_buffer[print_idx], tmp_buffer, cnt); + }else{ + memcpy(&print_buffer[print_idx], tmp_buffer, MAX_PRINTF_BUF_LEN-print_idx); + memcpy(&print_buffer[0], &tmp_buffer[MAX_PRINTF_BUF_LEN-print_idx], cnt-(MAX_PRINTF_BUF_LEN-print_idx)); + } + }else{ // space is flush_idx - print_idx, and available space is enough + memcpy(&print_buffer[print_idx], tmp_buffer, cnt); + } + // protection needed + taskENTER_CRITICAL(); + used_length+=cnt; + taskEXIT_CRITICAL(); + print_idx+=cnt; + if(print_idx>=MAX_PRINTF_BUF_LEN) + print_idx -= MAX_PRINTF_BUF_LEN; + }else{ + // skip + cnt = 0; + } + + return cnt; +} + + +void printing_task(void* arg) +{ + while(1){ + //wait event + if(xEventGroupWaitBits(print_event, 1, pdFALSE, pdFALSE, 100 ) == 1){ + while(used_length > 0){ + putchar(print_buffer[flush_idx]); + flush_idx++; + if(flush_idx >= MAX_PRINTF_BUF_LEN) + flush_idx-=MAX_PRINTF_BUF_LEN; + taskENTER_CRITICAL(); + used_length--; + taskEXIT_CRITICAL(); + } + // clear event + xEventGroupClearBits( print_event, 1); + } + } +} + +void rtl_printf_init() +{ + if(print_event==NULL){ + print_event = xEventGroupCreate(); + if(print_event == NULL) + printf("\n\rprint event init fail!\n"); + } + if(print_task == NULL){ + if(xTaskCreate(printing_task, (const char *)"print_task", 512, NULL, tskIDLE_PRIORITY + 1, &print_task) != pdPASS) + printf("\n\rprint task init fail!\n"); + } +} +#endif +//====================================================== + + +__weak void console_init(void) +{ + + IRQ_HANDLE UartIrqHandle; + + //4 Register Log Uart Callback function + UartIrqHandle.Data = NULL;//(u32)&UartAdapter; + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) UartLogIrqHandleRam; + UartIrqHandle.Priority = 6; + + + //4 Register Isr handle + InterruptUnRegister(&UartIrqHandle); + InterruptRegister(&UartIrqHandle); + + + +#if !TASK_SCHEDULER_DISABLED + RtlConsolInitRam((u32)RAM_STAGE,(u32)0,(VOID*)NULL); +#else + RtlConsolInitRam((u32)ROM_STAGE,(u32)0,(VOID*)NULL); +#endif + +#if BUFFERED_PRINTF + rtl_printf_init(); +#endif +} diff --git a/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.h b/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.h new file mode 100644 index 0000000..fd5f2a7 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/rtl_consol.h @@ -0,0 +1,140 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _RTK_CONSOL_H_ +#define _RTK_CONSOL_H_ +/* + * Include user defined options first. Anything not defined in these files + * will be set to standard values. Override anything you dont like! + */ + #if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B) +#include "platform_opts.h" +#endif + +//#include "osdep_api.h" +#include "osdep_service.h" +#include "hal_diag.h" +#include "platform_stdlib.h" + +#define CONSOLE_PREFIX "#" + + +//Log UART +//UART_LOG_CMD_BUFLEN: only 126 bytes could be used for keeping input +// cmd, the last byte is for string end ('\0'). +#define UART_LOG_CMD_BUFLEN 127 +#define MAX_ARGV 10 + +//print log buffer length, if buffer get full, the extra logs will be discarded. +#if BUFFERED_PRINTF +#define MAX_PRINTF_BUF_LEN 1024 +#endif + + +typedef u32 (*ECHOFUNC)(IN u8*,...); //UART LOG echo-function type. + +typedef struct _UART_LOG_BUF_ { + u8 BufCount; //record the input cmd char number. + u8 UARTLogBuf[UART_LOG_CMD_BUFLEN]; //record the input command. +} UART_LOG_BUF, *PUART_LOG_BUF; + + + +typedef struct _UART_LOG_CTL_ { + u8 NewIdx; + u8 SeeIdx; + u8 RevdNo; + u8 EscSTS; + u8 ExecuteCmd; + u8 ExecuteEsc; + u8 BootRdy; + u8 Resvd; + PUART_LOG_BUF pTmpLogBuf; + VOID *pfINPUT; + PCOMMAND_TABLE pCmdTbl; + u32 CmdTblSz; +#ifdef CONFIG_UART_LOG_HISTORY + u32 CRSTS; +#endif +#ifdef CONFIG_UART_LOG_HISTORY + u8 (*pHistoryBuf)[UART_LOG_CMD_BUFLEN]; +#endif +#ifdef CONFIG_KERNEL + u32 TaskRdy; + //_Sema Sema; + _sema Sema; +#else + // Since ROM code will reference this typedef, so keep the typedef same size + u32 TaskRdy; + void *Sema; +#endif +} UART_LOG_CTL, *PUART_LOG_CTL; + + +#define KB_ASCII_NUL 0x00 +#define KB_ASCII_BS 0x08 +#define KB_ASCII_TAB 0x09 +#define KB_ASCII_LF 0x0A +#define KB_ASCII_CR 0x0D +#define KB_ASCII_ESC 0x1B +#define KB_ASCII_SP 0x20 +#define KB_ASCII_BS_7F 0x7F +#define KB_ASCII_LBRKT 0x5B //[ + +#define KB_SPACENO_TAB 1 + +#ifdef CONFIG_UART_LOG_HISTORY +#define UART_LOG_HISTORY_LEN 5 +#endif + +#ifdef CONFIG_DEBUG_LOG +#define _ConsolePrint DiagPrintf +#else +#define _ConsolePrint +#endif + +#ifndef CONSOLE_PREFIX +#define CONSOLE_PREFIX "" +#endif + +#define CONSOLE_8195A(...) do {\ + _ConsolePrint("\r"CONSOLE_PREFIX __VA_ARGS__);\ +}while(0) + + +_LONG_CALL_ VOID +RtlConsolInit( + IN u32 Boot, + IN u32 TBLSz, + IN VOID *pTBL +); + +#if defined(CONFIG_KERNEL) +_LONG_CALL_ VOID +RtlConsolTaskRam( + VOID *Data +); +#endif + +_LONG_CALL_ VOID +RtlConsolTaskRom( + VOID *Data +); + + +_LONG_CALL_ u32 +Strtoul( + IN const u8 *nptr, + IN u8 **endptr, + IN u32 base +); + +void console_init(void); + +#endif //_RTK_CONSOL_H_ diff --git a/USDK/component/soc/realtek/8195a/misc/driver/rtl_console_new.c b/USDK/component/soc/realtek/8195a/misc/driver/rtl_console_new.c new file mode 100644 index 0000000..a5841ae --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/rtl_console_new.c @@ -0,0 +1,341 @@ +/* + * console_api.c + * + * Created on: 24/02/17 + * Author: pvvx + */ +//====================================================== +#ifndef LOGUART_STACK_SIZE +#define LOGUART_STACK_SIZE 400 // USE_MIN_STACK_SIZE modify from 512 to 128 +#endif +#define CONSOLE_PRIORITY 0 +//====================================================== +#include "rtl8195a.h" +#include "rtl_bios_data.h" +#include "osdep_api.h" +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) +#include "freertos_pmu.h" +#else +#error "Define configUSE_WAKELOCK_PMU = 1 & configUSE_WAKELOCK_PMU = 1!" +#endif +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED +#else +#error "Define CONFIG_KERNEL & TASK_SCHEDULER_DISABLED = 0!" +#endif +#ifndef CONFIG_UART_LOG_HISTORY +#error "Define CONFIG_UART_LOG_HISTORY!" +#endif +//====================================================== +// #define USE_ROM_CONSOLE +//====================================================== +_LONG_CALL_ extern u8 UartLogCmdChk( +IN u8 RevData, IN UART_LOG_CTL *prvUartLogCtl, +IN u8 EchoFlag); + +_LONG_CALL_ extern void ArrayInitialize( +IN u8 *pArrayToInit, +IN u8 ArrayLen, +IN u8 InitValue); + +_LONG_CALL_ extern void UartLogHistoryCmd( +IN u8 RevData, IN UART_LOG_CTL *prvUartLogCtl, +IN u8 EchoFlag); + +//_LONG_CALL_ extern void UartLogCmdExecute(IN PUART_LOG_CTL pUartLogCtlExe); +//====================================================== +extern PCOMMAND_TABLE UartLogRamCmdTable[]; +extern UartLogRamCmdTableSize; +//====================================================== +//: UartLogIrqHandleRam +//: To deal with Uart-Log RX IRQ +//: void +//: void +//: NA +//====================================================== +// overload original UartLogIrqHandle +MON_RAM_TEXT_SECTION +void UartLogIrqHandleRam(void * Data) { + uint32 IrqEn = DiagGetIsrEnReg(); // HAL_UART_READ32(UART_INTERRUPT_EN_REG_OFF) + DiagSetIsrEnReg(0); // HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, 0) + uint8 UartReceiveData = DiagGetChar(_FALSE); // if(flg) while(!(HAL_UART_READ32(UART_LINE_STATUS_REG_OFF)&1)); return HAL_UART_READ32(UART_REV_BUF_OFF); + if (UartReceiveData == 0) { + goto exit; + } + PUART_LOG_CTL p = pUartLogCtl; + //KB_ESC chk is for cmd history, it's a special case here. + if (UartReceiveData == KB_ASCII_ESC) { + // Esc detection is only valid in the first stage of boot sequence (few seconds) + if (p->ExecuteEsc != _TRUE) { + p->ExecuteEsc = _TRUE; + p->EscSTS = 0; + } else { + //4 the input commands are valid only when the task is ready to execute commands + if (p->BootRdy == 1 || p->TaskRdy == 1) { + if (p->EscSTS == 0) { + p->EscSTS = 1; + } + } else { + p->EscSTS = 0; + } + } + } else if (p->EscSTS == 1) { + if (UartReceiveData != KB_ASCII_LBRKT) { // '[' + p->EscSTS = 0; + } else { + p->EscSTS = 2; + } + } else { + if (p->EscSTS == 2) { + p->EscSTS = 0; + if (UartReceiveData == 'A' || UartReceiveData == 'B') { + // if(UartReceiveData == ...) set pUartLogCtl->SeeIdx ... + // prvStrCpy(pUartLogCtl->pTmpLogBuf->UARTLogBuf, pUartLogCtl->pHistoryBuf[pUartLogCtl->SeeIdx]); + // pUartLogCtl->pTmpLogBuf->BufCount = prvStrLen(pUartLogCtl->pTmpLogBuf->UARTLogBuf); + // if(EchoFlag) pUartLogCtl->pfINPUT(pUartLogCtl->pTmpLogBuf->UARTLogBuf); + UartLogHistoryCmd(UartReceiveData, (UART_LOG_CTL *) pUartLogCtl, + 1); + } + } else { + if (UartLogCmdChk(UartReceiveData, (UART_LOG_CTL *) pUartLogCtl, 1) + == 2) { + // check UartLog buffer to prevent from incorrect access + if (p->pTmpLogBuf != NULL) { + p->ExecuteCmd = _TRUE; + if (p->TaskRdy) { + rtw_up_sema_from_isr((_Sema *) &pUartLogCtl->Sema); + } + } else { + ArrayInitialize((u8 *) pUartLogCtl->pTmpLogBuf->UARTLogBuf, + UART_LOG_CMD_BUFLEN, '\0'); + } + } + } + } + exit: + DiagSetIsrEnReg(IrqEn); // HAL_UART_WRITE32(UART_INTERRUPT_EN_REG_OFF, IrqEn) +} +//====================================================== +//: GetArgvRam +//: парсигн аргументов строки +//: pstr - указатель на строку +//: кол-во аргументов +//: 2 формата: +// 1) cmd=arg1,arg2,... +// 2) cmd arg1 arg2 +// arg может быть обрамлен '"' или '\'' +// для передачи ' ' или ','. +// Начальные пробелы cmd или arg удаляются. +//====================================================== +int GetArgvRam(IN u8 *pstr, u8** argv) { + int arvc = 0; +// u8** argv = ArgvArray; + u8* p = pstr; + u8 t, n = ' '; + int m = 0; + while(*p != 0 + && *p != '\r' + && *p != '\n' + && arvc < MAX_ARGV + && p < &pstr[UART_LOG_CMD_BUFLEN-1]) { + switch(m) { + case 0: // wait cmd + if(*p == ' ') { +// *p = 0; + break; + } + *argv++ = p; + arvc++; + m++; + break; + case 1: // test end cmd, type format parm + if(*p == ' ') { // format cmd arg1 arg2 ... + m++; + *p = 0; + } else if(*p == '=') { // "at" format cmd=arg1,arg2,... + n = ','; + m++; + *p = 0; + } + break; + case 2: // wait start arg + if(*p == ' ') { + *p = 0; + break; + } + if(*p == '"' || *p == '\'') { + t = *p; + m = 4; + *p = 0; + break; + } + *argv++ = p; + arvc++; + m++; + case 3: // end arg + if(*p == n) { // ' ' or ',' + m = 2; + *p = 0; + } + break; + case 4: + *argv++ = p; + arvc++; + m++; + case 5: + if(*p == t) { // '\'' or '"' + m = 3; + *p = 0; + } + break; + } + p++; + } + return arvc; +} +//====================================================== +//: RtlConsolTaskRam +//: overload original RtlConsolTaskRam +//: Data - указатель PUART_LOG_CTL +//: none +//: +//====================================================== +MON_RAM_TEXT_SECTION void RtlConsolTaskRam(void *Data) { + PUART_LOG_CTL p = pUartLogCtl; +#ifdef USE_ROM_CONSOLE // show Help + p->pTmpLogBuf->UARTLogBuf[0] = '?'; + p->pTmpLogBuf->BufCount = 1; + p->ExecuteCmd = _TRUE; +#endif + do { + p->TaskRdy = _TRUE; + rtw_down_sema(&p->Sema); + if (p->ExecuteCmd) { + // UartLogCmdExecute(pUartLogCtl); + int argc = GetArgvRam(p->pTmpLogBuf->UARTLogBuf, ArgvArray); + if(argc) { + StrUpr(ArgvArray[0]); + PCOMMAND_TABLE pcmd = p->pCmdTbl; + int flg = 1; +#ifdef USE_ROM_CONSOLE + for(int i = 0; i < p->CmdTblSz; i++) { +#else + while(pcmd->cmd) { +#endif + if(prvStrCmp(ArgvArray[0], pcmd->cmd) == 0) { + flg = 0; + if(pcmd->ArgvCnt < argc) { +#ifdef USE_ROM_CONSOLE + pcmd->func(argc-1, &ArgvArray[1]); +#else + pcmd->func(argc, &ArgvArray); +#endif + } else { +#ifdef USE_ROM_CONSOLE + DiagPrintf(pcmd->msg); +#else + DiagPrintf("%s%s\n", pcmd->cmd, pcmd->msg); +#endif + } + } + pcmd++; + } + if(flg) DiagPrintf("cmd: %s - nothing!\n", ArgvArray[0]); +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + pmu_release_wakelock(WAKELOCK_LOGUART); +#endif + } +#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1) + else pmu_acquire_wakelock(WAKELOCK_LOGUART); +#endif + p->pTmpLogBuf->BufCount = 0; + p->pTmpLogBuf->UARTLogBuf[0] = 0; + HalSerialPutcRtl8195a('\r'); + HalSerialPutcRtl8195a('>'); + p->ExecuteCmd = _FALSE; + } + } while (1); +} +//====================================================== +//: console_init +//: Initialize rtl console +//: none +//: none +//: delete rtl_concole.h from project +//====================================================== +MON_RAM_TEXT_SECTION void console_init(void) { + IRQ_HANDLE UartIrqHandle; + // Register Log Uart Callback function + UartIrqHandle.Data = 0; // (u32)&UartAdapter; + UartIrqHandle.IrqNum = UART_LOG_IRQ; + UartIrqHandle.IrqFun = (IRQ_FUN) UartLogIrqHandleRam; + UartIrqHandle.Priority = 0; // ?? + // Register Isr handle + InterruptUnRegister(&UartIrqHandle); +#ifdef USE_ROM_CONSOLE // use ROM Consol init & printf "" + RtlConsolInit(RAM_STAGE, (u32) 6, (void*) UartLogRomCmdTable); +#else + UartLogBuf.BufCount = 0; + ArrayInitialize(&UartLogBuf.UARTLogBuf[0], UART_LOG_CMD_BUFLEN, '\0'); + pUartLogCtl = &UartLogCtl; + pUartLogCtl->NewIdx = 0; + pUartLogCtl->SeeIdx = 0; + pUartLogCtl->EscSTS = 0; + pUartLogCtl->BootRdy = 0; + pUartLogCtl->pTmpLogBuf = &UartLogBuf; + pUartLogCtl->CRSTS = 0; + pUartLogCtl->pHistoryBuf = UartLogHistoryBuf; + pUartLogCtl->pfINPUT = (void*) &DiagPrintf; + pUartLogCtl->pCmdTbl = (PCOMMAND_TABLE) UartLogRamCmdTable; + pUartLogCtl->CmdTblSz = UartLogRamCmdTableSize/16; //6; // GetRomCmdNum() + pUartLogCtl->TaskRdy = 0; +#endif + pUartLogCtl->RevdNo = UART_LOG_HISTORY_LEN; + // Create a Semaphone + rtw_init_sema(&pUartLogCtl->Sema, 1); + // executing boot sequence + pUartLogCtl->ExecuteCmd = _FALSE; + pUartLogCtl->ExecuteEsc = _TRUE; //don't check Esc anymore + InterruptRegister(&UartIrqHandle); + if (pdTRUE + != xTaskCreate(RtlConsolTaskRam, + (const signed char * const )"loguart", LOGUART_STACK_SIZE, + NULL, tskIDLE_PRIORITY + CONSOLE_PRIORITY + PRIORITIE_OFFSET, NULL)) { + DiagPrintf("Create Log UART Task Err!!\n"); + } +} + +#ifndef USE_ROM_CONSOLE +//====================================================== +//: console_help +//: Initialize rtl console +//: argc - кол-во аргуметов, argv - список аргументов +//: none +//: +//====================================================== +extern char str_rom_57ch3Dch0A[]; // "=========================================================\n" 57 шт +_WEAK void console_help(int argc, char *argv[]) { // Help + DiagPrintf("CONSOLE COMMAND SET:\n"); + DiagPrintf(&str_rom_57ch3Dch0A[25]); // DiagPrintf("==============================\n"); + PCOMMAND_TABLE pcmdtab = UartLogRamCmdTable; + while(pcmdtab->cmd) { +#ifdef USE_ROM_CONSOLE + DiagPrintf(pcmdtab->msg); +#else + DiagPrintf("%s%s\n", pcmdtab->cmd, pcmdtab->msg); +#endif + pcmdtab++; + } + DiagPrintf(&str_rom_57ch3Dch0A[25]); // DiagPrintf("==============================\n"); +} + +void print_on(int argc, char *argv[]) +{ + print_off = argv[1][0]!='1'; +} +// (!) размещается в специальном сегменте '.mon.tab*' (см. *.ld файл) +MON_RAM_TAB_SECTION COMMAND_TABLE console_commands[] = { + {"PR", 1, print_on, "=<1/0>: Printf on/off"}, // Help + {"?", 0, console_help, ": This Help"} // Help +// {"HELP", 0, console_help, ": Help"} // Help +}; +#endif diff --git a/USDK/component/soc/realtek/8195a/misc/driver/rtl_sec.h b/USDK/component/soc/realtek/8195a/misc/driver/rtl_sec.h new file mode 100644 index 0000000..d4a1424 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/driver/rtl_sec.h @@ -0,0 +1,12 @@ +#ifndef RTL_SEC_H +#define RTL_SEC_H + +#include + +#define SEC_PROCESS_OPT_ENC 1 +#define SEC_PROCESS_OPT_DEC 2 + +#define sec_process_data ProcessSecData +uint32_t sec_process_data(uint8_t key_idx, uint32_t opt, uint8_t *iv, uint8_t *input_buf, uint32_t buf_len, uint8_t *output_buf); + +#endif // RTL_SEC_H diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum new file mode 100644 index 0000000..a664826 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum.exe new file mode 100644 index 0000000..1ad31f6 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/checksum.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggcc_s-1.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggcc_s-1.dll new file mode 100644 index 0000000..1c5e62c Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggcc_s-1.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggmp-10.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggmp-10.dll new file mode 100644 index 0000000..ef02f64 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cyggmp-10.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygiconv-2.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygiconv-2.dll new file mode 100644 index 0000000..e824d2d Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygiconv-2.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygintl-8.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygintl-8.dll new file mode 100644 index 0000000..fa08150 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygintl-8.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygmpfr-4.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygmpfr-4.dll new file mode 100644 index 0000000..253c6c6 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygmpfr-4.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygncursesw-10.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygncursesw-10.dll new file mode 100644 index 0000000..2f30a91 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygncursesw-10.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygpcre-1.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygpcre-1.dll new file mode 100644 index 0000000..de39d78 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygpcre-1.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygreadline7.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygreadline7.dll new file mode 100644 index 0000000..0c9603f Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygreadline7.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygwin1.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygwin1.dll new file mode 100644 index 0000000..0492dcc Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygwin1.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygz.dll b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygz.dll new file mode 100644 index 0000000..29d3bff Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/cygz.dll differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/gawk.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/gawk.exe new file mode 100644 index 0000000..6890ed1 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/gawk.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/grep.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/grep.exe new file mode 100644 index 0000000..1e8308b Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/grep.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/nm.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/nm.exe new file mode 100644 index 0000000..7091e7a Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/nm.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objcopy.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objcopy.exe new file mode 100644 index 0000000..e27f101 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objcopy.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objdump.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objdump.exe new file mode 100644 index 0000000..3496453 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/objdump.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding new file mode 100644 index 0000000..3c79536 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding.exe new file mode 100644 index 0000000..d623f46 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/padding.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick new file mode 100644 index 0000000..018ae52 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick.exe new file mode 100644 index 0000000..27637e3 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/pick.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sed.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sed.exe new file mode 100644 index 0000000..58bd4a2 Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sed.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sort.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sort.exe new file mode 100644 index 0000000..8f7413d Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/sort.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/src/pick.cpp b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/src/pick.cpp new file mode 100644 index 0000000..6bd15ae --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/src/pick.cpp @@ -0,0 +1,136 @@ +// pick.cpp : main project file. + +#include "stdafx.h" + +using namespace System; + +#include +#include +#include +//#include +#include +#include +#include + +#define PATTERN_1 0x96969999 +#define PATTERN_2 0xFC66CC3F +#define PATTERN_3 0x03CC33C0 +#define PATTERN_4 0x6231DCE5 + +unsigned int fw_head[4] = { PATTERN_1, PATTERN_2, PATTERN_3, PATTERN_4 }; +unsigned int seg_head[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; +/* +int main(array ^args) +{ + Console::WriteLine(L"Hello World"); + return 0; +} +*/ +int main(int argc, char* argv[]) +{ + int arg_num = 6; + + if ((argc>5) && (strstr(argv[5], "head"))) arg_num++; + + if (argc != arg_num){ + printf("Usage: pick.exe \n"); + return -1; + } + + unsigned char *buf; + + unsigned int start;//=atoi(argv[1]); + unsigned int end;// = atoi(argv[2]); + unsigned int base; + + int is_raw = 0; + int is_sig = 0; + + char *inf = argv[3]; + char *outf = argv[4]; + + int size; + FILE *ifp, *ofp; + + //if(argv[1][0]=='0'&&(argv[1][1]=='x'||argv[1][1]=='X')) + // sscanf(argv[1], "0x%x", &start); + //else + // start=atoi(argv[1]); + start = strtol(argv[1], NULL, 0); + + //if(argv[2][0]=='0'&&(argv[2][1]=='x'||argv[2][1]=='X')) + // sscanf(argv[2], "0x%x", &end); + //else + // end=atoi(argv[2]); + end = strtol(argv[2], NULL, 0); + + base = start & 0xFFFF0000; + + if (strstr(argv[5], "reset_offset")){ + base = start; + } + + if (strstr(argv[5], "raw")){ + is_raw = 1; + } + else + is_raw = 0; + + if (strstr(argv[5], "sig")){ + is_sig = 1; + } + else + is_sig = 0; + + printf("b:%d s:%d e:%d\n", base, start, end); + //printf("%s %s\n", inf, outf); + + ifp = fopen(inf, "rb"); + if (!ifp) return -2; + ofp = fopen(outf, "wb"); + if (!ofp) return -3; + + fseek(ifp, 0, SEEK_END); + size = ftell(ifp); + + printf("size %d\n", size); + buf = (unsigned char *)malloc(size); + if (!buf) return -4; + + if (end == 0) end = base + size; + + if (end - start + 1 > 0){ + fseek(ifp, start - base, SEEK_SET); + fread(buf, end - start, 1, ifp); + if (is_raw == 0){ + if (strstr(argv[5], "head")){ + int offset = strtol(argv[6], NULL, 0); + printf("append fw head %x\n", offset); + fwrite(fw_head, 4, sizeof(unsigned int), ofp); + seg_head[2] = (0xFFFF0000 | (offset / 1024)); + } + else{ + if (is_sig){ + seg_head[2] = 0x35393138; + seg_head[3] = 0x31313738; + } + else{ + seg_head[2] = 0xFFFFFFFF; + seg_head[3] = 0xFFFFFFFF; + } + } + seg_head[0] = end - start; + seg_head[1] = start; + fwrite(seg_head, 4, sizeof(unsigned int), ofp); + } + fwrite(buf, end - start, 1, ofp); + + } + printf("copy size %d\n", end - start); + fclose(ifp); + fclose(ofp); + free(buf); + + return 0; +} + diff --git a/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/strip.exe b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/strip.exe new file mode 100644 index 0000000..fa020ca Binary files /dev/null and b/USDK/component/soc/realtek/8195a/misc/iar_utility/common/tools/strip.exe differ diff --git a/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c b/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c new file mode 100644 index 0000000..8ea7675 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c @@ -0,0 +1,309 @@ +#include "FreeRTOS.h" + +#include "freertos_pmu.h" + +#include + +#include "platform_autoconf.h" +#include "sys_api.h" +#include "sleep_ex_api.h" + +#include "task.h" + +#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG +#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#endif + +uint32_t missing_tick = 0; + +static uint32_t wakelock = DEFAULT_WAKELOCK; +static uint32_t wakeup_event = DEFAULT_WAKEUP_EVENT; + +typedef struct { + uint32_t nDeviceId; + PSM_HOOK_FUN sleep_hook_fun; + void* sleep_param_ptr; + PSM_HOOK_FUN wakeup_hook_fun; + void* wakeup_param_ptr; +} PSM_DD_HOOK_INFO; + +#define MAX_PSM_DD_HOOK_INFO_SIZE 8 +uint32_t psm_dd_hook_info_size = 0; +PSM_DD_HOOK_INFO psm_dd_hook_infos[MAX_PSM_DD_HOOK_INFO_SIZE]; + +static uint8_t last_wakelock_state[32] = { + DEFAULT_WAKELOCK & 0x01, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static uint32_t last_acquire_wakelock_time[32] = {0}; +static uint32_t hold_wakelock_time[32] = {0}; +static uint32_t base_sys_time = 0; + +static uint32_t sys_sleep_time = 0; + +unsigned char reserve_pll = 0; +unsigned char generate_wakelock_stats = 0; + +/* ++++++++ FreeRTOS macro implementation ++++++++ */ + +/* + * It is called in idle task. + * + * @return true : System is ready to check conditions that if it can enter sleep. + * false : System keep awake. + **/ +/* + * It is called when freertos is going to sleep. + * At this moment, all sleep conditons are satisfied. All freertos' sleep pre-processing are done. + * + * @param expected_idle_time : The time that FreeRTOS expect to sleep. + * If we set this value to 0 then FreeRTOS will do nothing in its sleep function. + **/ +void freertos_pre_sleep_processing(unsigned int *expected_idle_time) { + +#ifdef CONFIG_SOC_PS_MODULE + + uint32_t i; + uint32_t stime; + uint32_t tick_before_sleep; + uint32_t tick_after_sleep; + uint32_t tick_passed; + uint32_t backup_systick_reg; + unsigned char IsDramOn = 1; + unsigned char suspend_sdram = 1; + + /* To disable freertos sleep function and use our sleep function, + * we can set original expected idle time to 0. */ + stime = *expected_idle_time; + *expected_idle_time = 0; + + for (i=0; i tick_before_sleep) { + tick_passed = tick_after_sleep - tick_before_sleep; + } else { + // overflow + tick_passed = (0xffffffff - tick_before_sleep) + tick_after_sleep; + } + + /* If there is a rapid interrupt (<1ms), it makes tick_passed less than 1ms. + * The tick_passed would be rounded and make OS can't step tick. + * We collect the rounded tick_passed into missing_tick and step tick properly. + * */ + tick_passed += missing_tick; + if (tick_passed > stime * 1000) { + missing_tick = tick_passed - stime * 1000; + tick_passed = stime * 1000; + } else { + missing_tick = tick_passed % 1000; + } + + // update kernel tick + vTaskStepTick( tick_passed/1000 ); + } + + sys_sleep_time += tick_passed/1000; + + for (i=0; i 0) { + sprintf(pcWriteBuffer, "%x\t\t%d\r\n", i, hold_wakelock_time[i]); + } + } + pcWriteBuffer += strlen( pcWriteBuffer ); + } + sprintf(pcWriteBuffer, "time passed: %d ms, system sleep %d ms\r\n", current_timestamp - base_sys_time, sys_sleep_time); + } +} + +void pmu_clean_wakelock_stat() { + uint32_t i; + base_sys_time = osKernelSysTick(); + for (i=0; i<32; i++) { + hold_wakelock_time[i] = 0; + if (last_wakelock_state[i] == 1) { + last_acquire_wakelock_time[i] = base_sys_time; + } + } + sys_sleep_time = 0; +} + +void pmu_add_wakeup_event(uint32_t event) { + wakeup_event |= event; +} + +void pmu_del_wakeup_event(uint32_t event) { + wakeup_event &= ~event; + // To fulfill tickless design, system timer is required to be wakeup event + wakeup_event |= SLEEP_WAKEUP_BY_STIMER; +} + +void pmu_register_sleep_callback(uint32_t nDeviceId, PSM_HOOK_FUN sleep_hook_fun, void* sleep_param_ptr, PSM_HOOK_FUN wakeup_hook_fun, void* wakeup_param_ptr) { + uint32_t i; + for (i=0; i 1) { + // if we have more than 2 items, just swap the last item into current slot + psm_dd_hook_infos[i].nDeviceId = psm_dd_hook_infos[psm_dd_hook_info_size-1].nDeviceId; + psm_dd_hook_infos[i].sleep_hook_fun = psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_hook_fun; + psm_dd_hook_infos[i].sleep_param_ptr = psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_param_ptr; + psm_dd_hook_infos[i].wakeup_hook_fun = psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_hook_fun; + psm_dd_hook_infos[i].wakeup_param_ptr = psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_param_ptr; + + // Then erase the last item + psm_dd_hook_infos[psm_dd_hook_info_size-1].nDeviceId = 0; + psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_hook_fun = NULL; + psm_dd_hook_infos[psm_dd_hook_info_size-1].sleep_param_ptr = NULL; + psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_hook_fun = NULL; + psm_dd_hook_infos[psm_dd_hook_info_size-1].wakeup_param_ptr = NULL; + } else { + // we only have one item, just erase it + psm_dd_hook_infos[i].nDeviceId = 0; + psm_dd_hook_infos[i].sleep_hook_fun = NULL; + psm_dd_hook_infos[i].sleep_param_ptr = NULL; + psm_dd_hook_infos[i].wakeup_hook_fun = NULL; + psm_dd_hook_infos[i].wakeup_param_ptr = NULL; + } + psm_dd_hook_info_size--; + break; + } + } +} + +void pmu_set_pll_reserved(unsigned char reserve) { + reserve_pll = reserve; +} + diff --git a/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.h b/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.h new file mode 100644 index 0000000..9191b5d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.h @@ -0,0 +1,4 @@ +#ifndef _FREERTOS_PMU_8195A_H_ +#define _FREERTOS_PMU_8195A_H_ + +#endif \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/misc/os/mailbox.c b/USDK/component/soc/realtek/8195a/misc/os/mailbox.c new file mode 100644 index 0000000..4e43742 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/mailbox.c @@ -0,0 +1,566 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#define _MAILBOX_C_ + +#include "mailbox.h" + +/****************************************************************************** + * Function Prototype Declaration + ******************************************************************************/ +static PRTL_MAILBOX RtlMBoxIdToHdl(IN u8 MBoxId); + +PRTL_MAILBOX RtlMailboxCreate(IN u8 MboxID, IN u32 MboxSize, IN _Sema *pWakeSema); + +VOID RtlMailboxDel(IN PRTL_MAILBOX MboxHdl); + +u8 RtlMailboxSendToBack( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +u8 RtlMailboxSendToFront( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +u8 RtlMailboxReceive( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +u8 RtlMailboxPeek( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +u32 RtlMailboxMsgWaiting( + IN u8 MboxID, + IN u8 IsFromISR +); + +/****************************************************************************** + * Global Variable Declaration + ******************************************************************************/ +static RTL_MBOX_ROOT MBox_Entry; + +/****************************************************************************** + * External Function & Variable Declaration + ******************************************************************************/ + + +/****************************************************************************** + * Function: RtlMBoxIdToHdl + * Desc: Map a mailbox ID to the mailbox pointer. + * Para: + * MBoxId: The Mailbox ID + * Return: The pointer of the mailbox. If didn't found match mailbox, + * return NULL. + * + ******************************************************************************/ +static PRTL_MAILBOX RtlMBoxIdToHdl( + IN u8 MBoxId +) +{ + RTL_MAILBOX *pMbox=NULL; + RTL_MAILBOX *pTmpMbox; + _LIST *pHead; + _LIST *pList; + + // if the Mailbox root entry initialed ? if not, initial it + if (!MBox_Entry.isInitialed) { + RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection + RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox + MBox_Entry.isInitialed = 1; + MSG_MBOX_INFO("MBox Entry Initial...\n"); + } + + pHead = &MBox_Entry.mbox_list; + RtlDownMutex(&MBox_Entry.Mutex); + pList = RtlListGetNext(&MBox_Entry.mbox_list); + while (pList != pHead) { + pTmpMbox = CONTAINER_OF(pList, RTL_MAILBOX, mbox_list); + if (MBoxId == pTmpMbox->mbox_id) { + pMbox = pTmpMbox; + break; + } + pList = RtlListGetNext(pList); + } + RtlUpMutex(&MBox_Entry.Mutex); + + return pMbox; +} + +/****************************************************************************** + * Function: RtlMailboxCreate + * Desc: To create a mailbox with a given mailbox ID and size + * Para: + * MboxID: A number to identify this created mailbox. A message block can + * be send to a mailbox by a given MboxID. The MboxID must be unique + * in the whole system. If this MboxID is conflict with a created + * mailbox, the mailbox creation will fail and return NULL. + * MboxSize: The size of this mailbox to be created. It means maximum number + * of message blocks can be stored in this mailbox. + * pWakeSema: The semaphore to wake up the receiving task to receive the new + * message. If the receiving task doesn't need a semaphore to wakeup + * it, then just let this pointer is NULL. + * Return: The created mailbox pointer. If it failed, return NULL. + ******************************************************************************/ +PRTL_MAILBOX RtlMailboxCreate( + IN u8 MboxID, + IN u32 MboxSize, + IN _Sema *pWakeSema +) +{ + PRTL_MAILBOX pMBox=NULL; + + // if the Mailbox root entry initialed ? if not, initial it + if (!MBox_Entry.isInitialed) { + RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection + RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox + MBox_Entry.isInitialed = 1; + MSG_MBOX_INFO("MBox Entry Initial...\n"); + } + + // check if this mailbox ID is ocupied ? + pMBox = RtlMBoxIdToHdl(MboxID); + if (NULL != pMBox) { + MSG_MBOX_ERR("RtlMailboxCreate: The Mailbox ID %d is used by someone!!\n", MboxID); + return NULL; + } + + pMBox = (RTL_MAILBOX *)RtlZmalloc(sizeof(RTL_MAILBOX)); + if (NULL==pMBox) { + MSG_MBOX_ERR("RtlMailboxCreate: MAlloc Failed\n"); + return NULL; + } + + RtlInitListhead(&pMBox->mbox_list); // Init the link list to be chained into the created mailbox list + pMBox->mbox_id = MboxID; + pMBox->pWakeSema = pWakeSema; +#ifdef PLATFORM_FREERTOS + pMBox->mbox_hdl = xQueueCreate(MboxSize, sizeof(MSG_BLK)); + if (NULL == pMBox->mbox_hdl) { + MSG_MBOX_ERR("RtlMailboxCreate: xQueueCreate Failed\n"); + RtlMfree((void *)pMBox, sizeof(RTL_MAILBOX)); + return NULL; + } +#endif +#ifdef PLATFORM_ECOS +// TODO: Create mailbox +#endif + + // Add this mailbox to the link list of created mailbox + RtlDownMutex(&MBox_Entry.Mutex); + RtlListInsertTail(&pMBox->mbox_list, &MBox_Entry.mbox_list); + RtlUpMutex(&MBox_Entry.Mutex); + + MSG_MBOX_INFO("A Mailbox Created: Size=%d\n", MboxSize); + + return pMBox; +} + +/****************************************************************************** + * Function: RtlMailboxDel + * Desc: To delete a mailbox by a given mailbox handle. + * Para: + * MboxHdl: The handle of the mailbox to be deleted. + * Return: None. + ******************************************************************************/ +VOID RtlMailboxDel( + IN PRTL_MAILBOX MboxHdl +) +{ + if (NULL == MboxHdl) { + MSG_MBOX_ERR("RtlMailboxDel: Try to delete a NULL mailbox\n"); + return; + } + + // Remove this mailbox from the link list of created mailbox + RtlDownMutex(&MBox_Entry.Mutex); + RtlListDelete(&MboxHdl->mbox_list); + RtlUpMutex(&MBox_Entry.Mutex); + + // delete the Queue/Mailbox +#ifdef PLATFORM_FREERTOS + vQueueDelete((xQueueHandle)(MboxHdl->mbox_hdl)); +#endif +#ifdef PLATFORM_ECOS + // TODO: Delete mailbox +#endif + + RtlMfree((void *)MboxHdl, sizeof(RTL_MAILBOX)); +} + +/****************************************************************************** + * Function: RtlMailboxSendToBack + * Desc: To put a message block to the tail of a given mailbox. + * Para: + * MboxID: The identifier of the target mailbox. + * pMsg: The pointer of the message block to be put into the mailbox. + * MSToWait: If the mailbox is full, this value gives a time to wait to put + * this message. The time unit is millisecond. + * The special values are: + * 0: no waiting; + * 0xffffffff: wait without timeout. + * If the waiting is timeout, the message sending is failed and + * return _FAIL. + * IsFromISR: Is this function is called from an ISR ? + * Return: _SUCCESS or _FAIL. + ******************************************************************************/ +u8 RtlMailboxSendToBack( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +) +{ + RTL_MAILBOX *pMbox=NULL; + u32 wait_ticks; +#ifdef PLATFORM_FREERTOS + portBASE_TYPE ret; +#endif + + pMbox = RtlMBoxIdToHdl(MboxID); + + if (NULL == pMbox) { + MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID); + return _FAIL; + } + +#ifdef PLATFORM_FREERTOS + if (MBOX_WAIT_NO_TIMEOUT == MSToWait) { + wait_ticks = portMAX_DELAY; + } + else if (MBOX_WAIT_NONE == MSToWait) { + wait_ticks = 0; + } + else { + wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1); + } + + if (IsFromISR) { + ret = xQueueSendToBackFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks); + } + else { + ret = xQueueSendToBack(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks); + } + + if(ret != pdPASS ) { + // send message to the queue failed + MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID); + ret = _FAIL; + } + else { + // try to give a semaphore to wake up the receiving task + if (pMbox->pWakeSema) { + RtlUpSema(pMbox->pWakeSema); + } + ret = _SUCCESS; + } + + return ret; +#endif + +#ifdef PLATFORM_ECOS + // TODO: Put the message to a mailbox +#endif + +} + + +/****************************************************************************** + * Function: RtlMailboxSendToFront + * Desc: To put a message block to the head of a mailbox. + * Para: + * MboxID: The identifier of the target mailbox. + * pMsg: The pointer of the message block to be put into the mailbox. + * MSToWait: If the mailbox is full, this value gives a time to wait to put + * this message. The time unit is millisecond. + * The special values are: + * 0: no waiting; + * 0xffffffff: wait without timeout. + * If the waiting is timeout, the message sending is failed and + * return _FAIL. + * IsFromISR: Is this function is called from an ISR ? + * Return: _SUCCESS or _FAIL. + ******************************************************************************/ +u8 RtlMailboxSendToFront( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +) +{ + RTL_MAILBOX *pMbox=NULL; + u32 wait_ticks; +#ifdef PLATFORM_FREERTOS + portBASE_TYPE ret; +#endif + + pMbox = RtlMBoxIdToHdl(MboxID); + + if (NULL == pMbox) { + MSG_MBOX_ERR("RtlMailboxSendToBack: Didn't find matched MBoxID=%d\n", MboxID); + return _FAIL; + } + +#ifdef PLATFORM_FREERTOS + if (MBOX_WAIT_NO_TIMEOUT == MSToWait) { + wait_ticks = portMAX_DELAY; + } + else if (MBOX_WAIT_NONE == MSToWait) { + wait_ticks = 0; + } + else { + wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1); + } + + if (IsFromISR) { + ret = xQueueSendToFrontFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//(portTickType) wait_ticks); + } + else { + ret = xQueueSendToFront(pMbox->mbox_hdl, (void *)pMsg, (portTickType) wait_ticks); + } + + if(ret != pdPASS ) { + // send message to the queue failed + MSG_MBOX_ERR("RtlMailboxSendToBack: Put Msg to Queue Failed, MBoxID=%d\n", MboxID); + ret = _FAIL; + } + else { + // try to give a semaphore to wake up the receiving task + if (pMbox->pWakeSema) { + RtlUpSema(pMbox->pWakeSema); + } + ret = _SUCCESS; + } + + return ret; +#endif + +#ifdef PLATFORM_ECOS + // TODO: eCos has no API to put message to the head of a mailbox +#endif + +} + +/****************************************************************************** + * Function: RtlMailboxSendToFront + * Desc: To get a message block from a given mailbox. + * Para: + * MboxID: The identifier of the target mailbox. + * pMsg: The message block to store the gotten message. + * MSToWait: If the mailbox is full, this value gives a time to wait to put + * this message. The time unit is millisecond. + * The special values are: + * 0: no waiting; + * 0xffffffff: wait without timeout. + * If the waiting is timeout, the message sending is failed and + * return _FAIL. + * IsFromISR: Is this function is called from an ISR ? + * Return: _SUCCESS or _FAIL. + ******************************************************************************/ +u8 RtlMailboxReceive( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +) +{ + RTL_MAILBOX *pMbox=NULL; + u32 wait_ticks; +#ifdef PLATFORM_FREERTOS + portBASE_TYPE ret; +#endif + + pMbox = RtlMBoxIdToHdl(MboxID); + + if (NULL == pMbox) { + MSG_MBOX_ERR("RtlMailboxReceive: Didn't find the MBox with ID=%d\n", MboxID); + return _FAIL; + } + +#ifdef PLATFORM_FREERTOS + if (MBOX_WAIT_NONE == MSToWait) { + wait_ticks = 0; + } + else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) { + wait_ticks = portMAX_DELAY; + } + else { + wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1); + } + + if (IsFromISR) { + ret = xQueueReceiveFromISR(pMbox->mbox_hdl, (void *)pMsg, NULL);//( portTickType ) wait_ticks); + } + else { + ret = xQueueReceive(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks); + + } + + if(ret != pdTRUE ) { + // receive message failed + if (0 != MSToWait) { + MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID); + } + ret = _FAIL; + } + else { + ret = _SUCCESS; + } + + return ret; +#endif + +#ifdef PLATFORM_ECOS + // TODO: Get a message from the mailbox +#endif + +} + +/****************************************************************************** + * Function: RtlMailboxPeek + * Desc: To copy the head message from a given mailbox without move this + * message block out from the mailbox. + * Para: + * MboxID: The identifier of the target mailbox. + * pMsg: The message block to store the gotten message. + * MSToWait: If the mailbox is full, this value gives a time to wait to put + * this message. The time unit is millisecond. + * The special values are: + * 0: no waiting; + * 0xffffffff: wait without timeout. + * If the waiting is timeout, the message sending is failed and + * return _FAIL. + * IsFromISR: Is this function is called from an ISR ? + * Return: _SUCCESS or _FAIL. + ******************************************************************************/ +u8 RtlMailboxPeek( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +) +{ + RTL_MAILBOX *pMbox=NULL; + u32 wait_ticks; +#ifdef PLATFORM_FREERTOS + portBASE_TYPE ret; +#endif + + pMbox = RtlMBoxIdToHdl(MboxID); + + if (NULL == pMbox) { + MSG_MBOX_ERR("RtlMailboxPeek: Didn't find the MBox with ID=%d\n", MboxID); + return _FAIL; + } + +#ifdef PLATFORM_FREERTOS + if (MBOX_WAIT_NONE == MSToWait) { + wait_ticks = 0; + } + else if (MBOX_WAIT_NO_TIMEOUT == MSToWait) { + wait_ticks = portMAX_DELAY; + } + else { + wait_ticks = ((MSToWait/portTICK_RATE_MS)>0)?(MSToWait/portTICK_RATE_MS):(1); + } + + if (IsFromISR) { +// ret = xQueuePeekFromISR(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks); + // TODO: check why we have no "xQueuePeekFromISR" + MSG_MBOX_ERR("RtlMailboxPeek: Current version has no 'xQueuePeekFromISR'\n"); + ret = pdFALSE; + } + else { + ret = xQueuePeek(pMbox->mbox_hdl, (void *)pMsg, ( portTickType ) wait_ticks); + + } + + if(ret != pdTRUE ) { + // receive message failed + MSG_MBOX_ERR("RtlMailboxReceive: Receive Msg Failed, MBoxID=%d\n", MboxID); + ret = _FAIL; + } + else { + ret = _SUCCESS; + } + + return ret; +#endif + +#ifdef PLATFORM_ECOS + // TODO: Get a message from the mailbox +#endif + +} + + +/****************************************************************************** + * Function: RtlMailboxMsgWaiting + * Desc: To get the number of message blocks are storing in a given mailbox. + * Para: + * MboxID: The identifier of the target mailbox. + * IsFromISR: Is this function is called from an ISR ? + * Return: The number of message blocks are storing in this mailbox. + ******************************************************************************/ +u32 RtlMailboxMsgWaiting( + IN u8 MboxID, + IN u8 IsFromISR +) +{ + RTL_MAILBOX *pMbox=NULL; + u32 msg_num=0; + + pMbox = RtlMBoxIdToHdl(MboxID); + + if (NULL == pMbox) { + MSG_MBOX_ERR("RtlMailboxMsgWaiting: Didn't find the MBox with ID=%d\n", MboxID); + return 0; + } + +#ifdef PLATFORM_FREERTOS + if (IsFromISR) { + msg_num = uxQueueMessagesWaitingFromISR(pMbox->mbox_hdl); + } + else { + msg_num = uxQueueMessagesWaiting(pMbox->mbox_hdl); + } +#endif + +#ifdef PLATFORM_ECOS + // TODO: call eCos API to implement this function +#endif + + return msg_num; + +} + diff --git a/USDK/component/soc/realtek/8195a/misc/os/mailbox.h b/USDK/component/soc/realtek/8195a/misc/os/mailbox.h new file mode 100644 index 0000000..3c94f89 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/mailbox.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __MAILBOX_H_ +#define __MAILBOX_H_ + +#include "hal_api.h" +#include "osdep_api.h" +#include "hal_util.h" +#ifdef PLATFORM_FREERTOS +#include "queue.h" +#endif + +#define MBOX_WAIT_NO_TIMEOUT 0xffffffff // waiting for send/receive message with no timeout +#define MBOX_WAIT_NONE 0 // No wait for send/receive message + +typedef enum _MAILBOX_ID_ { + MBOX_ID_WLAN = 0, + MBOX_ID_UART = 1, + MBOX_ID_I2C = 2, + MBOX_ID_I2S = 3, + MBOX_ID_SPI = 4, + MBOX_ID_SDIO = 5, + MBOX_ID_SDIO_MP = 6, + + MBOX_ID_MAX = 0xff +} MAILBOX_ID; + +#if defined(CONFIG_SDIO_DEVICE_EN) && defined(CONFIG_SDIO_DEVICE_NORMAL) +typedef enum _MSG_TYPE_SDIO { + MSG_SDIO_RX_PKT=1, // request to send a SDIO RX packet to the host side + MSG_SDIO_C2H=2, // request to send a C2H message + MSG_SDIO_RPWM=3, // request to set the RPWM + MSG_SDIO_MP_LOOP_TXPKT=4, // request to loopback this TX packet + + MSG_SDIO_MAX=0xff +} MSG_TYPE_SDIO; +#endif // end of "#ifdef CONFIG_SDIO_DEVICE_EN" + +/* the data structure of a MailBox to deliver message blocks */ +typedef struct _RTL_MAILBOX_ { + void *mbox_hdl; // the mailbox handle which return from OS create queue API + _Sema *pWakeSema; // the semaphore to wakeup the message receiving task + _LIST mbox_list; // the link list to chain all created mailbox + u8 mbox_id; /* the ID of this Mailbox, this ID is + used to locate the MBox for send/get message */ +} RTL_MAILBOX, *PRTL_MAILBOX; + +/* the data structure of a message block */ +typedef struct _RTL_MSG_BLK { + u8 MsgType; // the message type + u8 Reserved; // reserved + u16 DateLen; // the vaild data length of the pBuf + u32 Para; // the optional parameters associated with this message type + u8 *pBuf; // point to a data buffer associated with this message type +} MSG_BLK, *PMSG_BLK; + +/* the data structure for system level message block management */ +typedef struct _RTL_MBOX_ROOT_ { + _LIST mbox_list; // the link list of all created mailbox + _Mutex Mutex; // the Mutex to protect the mailbox create/delete procedure + u8 isInitialed; // is this Mailbox link-list initialed +} RTL_MBOX_ROOT, *PRTL_MBOX_ROOT; + +// Export Funcction API +extern PRTL_MAILBOX RtlMailboxCreate( + IN u8 MboxID, + IN u32 MboxSize, + IN _Sema *pWakeSema +); + +extern VOID RtlMailboxDel( + IN PRTL_MAILBOX MboxHdl +); + +extern u8 RtlMailboxSendToBack( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +extern u8 RtlMailboxSendToFront( + IN u8 MboxID, + IN MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +extern u8 RtlMailboxReceive( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +extern u8 RtlMailboxPeek( + IN u8 MboxID, + OUT MSG_BLK *pMsg, + IN u32 MSToWait, + IN u8 IsFromISR +); + +extern u32 RtlMailboxMsgWaiting( + IN u8 MboxID, + IN u8 IsFromISR +); + + +#endif // #ifndef __MAILBOX_H_ + diff --git a/USDK/component/soc/realtek/8195a/misc/os/os_support.h b/USDK/component/soc/realtek/8195a/misc/os/os_support.h new file mode 100644 index 0000000..d35ba57 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/os_support.h @@ -0,0 +1,36 @@ + /****************************************************************************** + * + * Name: sys-support.h - System type support for Linux + * $Revision: 1.1.1.1 $ + * + *****************************************************************************/ + +#ifndef __OS_SUPPORT_H__ +#define __OS_SUPPORT_H__ + + +#include +#include +#include "task.h" +#include "osdep_service.h" + +#define RTL_HZ 100 + +#define RtlKmalloc(size, flag) pvPortMalloc(size) +#define RtlKfree(pv) vPortFreeAligned(pv) + + +#ifdef CONFIG_TIMER_MODULE +#define __Delay(t) HalDelayUs(t) +#else +static __inline__ u32 __Delay(u32 us) +{ + DBG_8195A("No Delay: please enable hardware Timer\n"); +} +#endif + + +#define Mdelay(t) __Delay(t*1000) +#define Udelay(t) __Delay(t) + +#endif /* __SYS_SUPPORT_H__ */ diff --git a/USDK/component/soc/realtek/8195a/misc/os/os_timer.h b/USDK/component/soc/realtek/8195a/misc/os/os_timer.h new file mode 100644 index 0000000..bc888b0 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/os_timer.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * Name: sys-support.h - System type support for Linux + * $Revision: 1.1.1.1 $ + * + *****************************************************************************/ + +#ifndef __OS_TIMER_H__ +#define __OS_TIMER_H__ + +#include "diag.h" +#include "os_support.h" +#include "osdep_service.h" + + +#define JIFFIES xTaskGetTickCount() + +enum { + TIMER_NO_INIT = 0, + TIMER_INIT = 1, + TIMER_START = 2, + TIMER_DISABLE = 3 +}; + +struct TIMER_LIST { + _timerHandle TimeHdl; + u32 Flag; + unsigned long Data; + VOID (*Function)(void *); + u32 TimerID; +}; + +static inline VOID InitTimer(IN struct TIMER_LIST *Timer) +{ + u32 TimerID = Timer->TimerID; + VOID (*Function)(VOID *) = Timer->Function; + + save_and_cli(); + + if (Timer->Flag != TIMER_DISABLE) { + if (Timer->Flag == TIMER_NO_INIT) { + Timer->TimeHdl = rtw_timerCreate( (const char *)"Timer", // Just a test name, not used by the kernel. + ( 100 ), // The timer period in ticks. + _FALSE, // The timers will auto-reload themselves when they expire. + ( void * ) TimerID, // Assign each timer a unique id equal to its array index. + Function + #ifdef RTK_MODE_TIMER + ,data // Each timer calls the same callback when it expires. + #endif + ); + if (NULL == Timer->TimeHdl) { + DBG_ERROR_LOG("\rInitial Timer fail!\n"); + } + else { + TimerID++; + } + + Timer->Flag = TIMER_INIT; + } + else if (Timer->Flag == TIMER_START) { + rtw_timerStop(Timer->TimeHdl,0); + Timer->Flag = TIMER_DISABLE; + } + } + + restore_flags(); +} + +static inline void ModTimer(IN struct TIMER_LIST *Timer, IN u32 TimeoutTicks) +{ +#ifndef PLATFORM_FREERTOS + u32 Flags; +#endif + + void (*Function)(void *) = Timer->Function; + + save_and_cli(); + + if (Timer->Flag == TIMER_NO_INIT) { + if (Timer->Function) { + Timer->TimeHdl = rtw_timerCreate((const char *)"Timer", // Just a text name, not used by the kernel. + ( 100 ), // The timer period in ticks. + _FALSE, // The timers will auto-reload themselves when they expire. + ( void * ) Timer->TimerID, // Assign each timer a unique id equal to its array index. + Function + #ifdef RTK_MODE_TIMER + ,Timer->Data // Each timer calls the same callback when it expires. + #endif + ); + if (NULL == Timer->TimeHdl) { + DBG_ERROR_LOG("\rInitial Timer fail!\n"); + } + else { + Timer->TimerID++; + } + + Timer->Flag = TIMER_INIT; + } + else { + restore_flags(); + return; + } + } + else if (Timer->Flag == TIMER_START) { + rtw_timerStop(Timer->TimeHdl,0); + Timer->Flag = TIMER_DISABLE; + } + + TimeoutTicks -= rtw_get_current_time(); + if (TimeoutTicks <= 0) + TimeoutTicks = 2; + + if (xTimerStart(Timer->TimeHdl, TimeoutTicks )) + Timer->Flag = TIMER_START; + else + DBG_ERROR_LOG("\rmod_timer() - no slots available\n"); + restore_flags(); +} + + +static inline int TimerPending (IN const struct TIMER_LIST *Timer) +{ + if (Timer->TimeHdl && Timer->Flag != TIMER_NO_INIT) + return 1; + else + return 0; +} + +static inline void DelTimerSync(IN struct TIMER_LIST *Timer) +{ + save_and_cli(); + + if (Timer->TimeHdl && Timer->Flag != TIMER_INIT) { + if (Timer->Flag == TIMER_START) + rtw_timerStop(Timer->TimeHdl, 0); + + rtw_timerDelete(Timer->TimeHdl, 0); + Timer->Flag = TIMER_NO_INIT; + } + + restore_flags(); +} + + /* + * These inlines deal with timer wrapping correctly. You are + * strongly encouraged to use them + * 1. Because people otherwise forget + * 2. Because if the timer wrap changes in future you wont have to + * alter your driver code. + * + * time_after(a,b) returns true if the time a is after time b. + * + * Do this with "<0" and ">=0" to only test the sign of the result. A + * good compiler would generate better code (and a really good compiler + * wouldn't care). Gcc is currently neither. + */ + #define TIME_AFTER(a,b) ((long)(b) - (long)(a) < 0) + #define TIMER_BEFORE(a,b) TIME_AFTER(b,a) + + #define TIME_AFTER_EQ(a,b) ((long)(a) - (long)(b) >= 0) + #define TIMER_BEFORE_EQ(a,b) TIME_AFTER_EQ(b,a) + + + +#endif //__OS_TIMER_H__ \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/misc/os/osdep_api.c b/USDK/component/soc/realtek/8195a/misc/os/osdep_api.c new file mode 100644 index 0000000..8a6014b --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/osdep_api.c @@ -0,0 +1,535 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + +#define _OSDEP_API_C_ + +#include +#include "osdep_service.h" + +extern _LONG_CALL_ char *_strcpy(char *dest, const char *src); +extern _LONG_CALL_ VOID *_memset(void *dst0, int Val,SIZE_T length); + +u8* RtlMalloc(IN u32 sz) +{ + u8 *pbuf=NULL; + + pbuf = rtw_malloc((u32)sz); + + return pbuf; +} + + +u8* RtlZmalloc(IN u32 sz) +{ + u8 *pbuf; + + pbuf= rtw_malloc((u32)sz); + + if (pbuf != NULL) { + _memset(pbuf, 0, sz); + } + + return pbuf; +} + +VOID RtlMfree(IN u8 *pbuf, IN u32 sz) +{ + rtw_mfree(pbuf, sz); +} + +VOID* RtlMalloc2d(IN u32 h, IN u32 w, IN u32 size) +{ + u32 j; + + VOID **a = (VOID **) rtw_malloc2d(h, w, size); + if(a == NULL) + { + DBG_ERROR_LOG("%s: alloc memory fail!\n", __FUNCTION__); + return NULL; + } + + return a; +} + +VOID RtlMfree2d(IN VOID *pbuf, IN u32 h, IN u32 w, IN u32 size) +{ + rtw_mfree2d(pbuf, h, w, size); +} + +VOID RtlInitSema(IN _Sema *sema, IN u32 init_val) +{ + rtw_init_sema(sema, init_val); +} + +VOID RtlFreeSema(IN _Sema *sema) +{ + rtw_free_sema(sema); +} + +VOID RtlUpSema(IN _Sema *sema) +{ + rtw_up_sema(sema); +} + +VOID RtlUpSemaFromISR(IN _Sema *sema) +{ + rtw_up_sema_from_isr(sema); +} + +u32 RtlDownSema(IN _Sema *sema) +{ + rtw_down_sema(sema); + return _SUCCESS; +} + +u32 RtlDownSemaWithTimeout(IN _Sema *sema,IN u32 ms) +{ + return rtw_down_timeout_sema(sema, ms); +} + +VOID RtlMutexInit(IN _Mutex *pmutex) +{ + rtw_mutex_init(pmutex); +} + +VOID RtlMutexFree(IN _Mutex *pmutex) +{ + rtw_mutex_free(pmutex); +} + +VOID RtlSpinlockInit(IN _Lock *plock) +{ + rtw_spinlock_init((_lock *)plock); +} + +VOID RtlSpinlockFree(IN _Lock *plock) +{ + rtw_spinlock_free((_lock *)plock); +} + +VOID RtlSpinlock(IN _Lock *plock) +{ + rtw_spin_lock((_lock *)plock); +} + +VOID RtlSpinunlock(IN _Lock *plock) +{ + rtw_spin_unlock((_lock *)plock); +} + +VOID RtlSpinlockEx(IN _Lock *plock) +{ +} + +VOID RtlSpinunlockEx(IN _Lock *plock) +{ +} + +u32 RtlGetCurrentTime(VOID) +{ + return rtw_get_current_time(); +} + +VOID RtlSleepSchedulable(IN u32 ms) +{ +} + +VOID RtlMsleepOS(IN u32 ms) +{ + rtw_msleep_os(ms); +} + +VOID RtlUsleepOS(IN u32 us) +{ + rtw_usleep_os(us); +} + +VOID RtlMdelayOS(IN u32 ms) +{ + rtw_mdelay_os(ms); +} + +VOID RtlUdelayOS(IN u32 us) +{ + rtw_udelay_os(us); +} + +VOID RtlYieldOS(VOID) +{ + rtw_yield_os(); +} + + +#if defined(__ICCARM__) +u64 RtlModular64(IN u64 n, IN u64 base) +{ + unsigned int __base = (base); + unsigned int __rem; + //(void)(((typeof((n)) *)0) == ((__uint64_t *)0)); + if (((n) >> 32) == 0) { + __rem = (unsigned int)(n) % __base; + (n) = (unsigned int)(n) / __base; + } else + __rem = __Div64_32(&(n), __base); + return __rem; + +} +#else +u64 RtlModular64(IN u64 x, IN u64 y) +{ + return rtw_modular64(x, y); +} +#endif + +/****************************************************************************** + * Function: RtlTimerCallbckEntry + * Desc: This function is a timer callback wrapper. All OS timer callback + * will call this function and then call the real callback function inside + * this function. + * + * Para: + * pxTimer: The FreeRTOS timer handle which is expired and call this callback. + * + * Return: None + * + ******************************************************************************/ +#ifdef PLATFORM_FREERTOS +void RtlTimerCallbckEntry (IN _timerHandle pxTimer) +{ + PRTL_TIMER pTimer; + + if (NULL == pxTimer) { + MSG_TIMER_ERR("RtlTimerCallbckEntry: NULL Timer Handle Err!\n"); + return; + } + + pTimer = (PRTL_TIMER) rtw_timerGetID( pxTimer ); + pTimer->CallBackFunc(pTimer->Context); +} +#endif // end of "#ifdef PLATFORM_FREERTOS" + +/****************************************************************************** + * Function: RtlTimerCreate + * Desc: To create a software timer. + * + * Para: + * pTimerName: A string for the timer name. + * TimerPeriodMS: The timer period, the unit is milli-second. + * CallbckFunc: The callback function of this timer. + * pContext: A pointer will be used as the parameter to call the timer + * callback function. + * isPeriodical: Is this timer periodical ? (Auto reload after expired) + * Return: The created timer handle, a pointer. It can be used to delete the + * timer. If timer createion failed, return NULL. + * + ******************************************************************************/ +PRTL_TIMER RtlTimerCreate( + IN char *pTimerName, + IN u32 TimerPeriodMS, + IN RTL_TIMER_CALL_BACK CallbckFunc, + IN void *pContext, + IN u8 isPeriodical) +{ + PRTL_TIMER pTimer; + u32 timer_ticks; + int i; + + pTimer = (PRTL_TIMER)RtlZmalloc(sizeof(RTL_TIMER)); + if (NULL == pTimer) { + MSG_TIMER_ERR("RtlTimerCreate: Alloc Mem Err!\n"); + return NULL; + } + + if (portTICK_RATE_MS >= TimerPeriodMS) { + timer_ticks = 1; // at least 1 system tick + } + else { + timer_ticks = TimerPeriodMS/portTICK_RATE_MS; + } + + pTimer->TimerHandle = rtw_timerCreate ((const char*)(pTimer->TimerName), timer_ticks, + (portBASE_TYPE)isPeriodical, (void *) pTimer, RtlTimerCallbckEntry); + +#ifdef PLATFORM_FREERTOS // if any RTOS is used + if (pTimer->TimerHandle) { + pTimer->msPeriod = TimerPeriodMS; + pTimer->CallBackFunc = CallbckFunc; + pTimer->Context = pContext; + pTimer->isPeriodical = isPeriodical; + // copy the timer name + if (NULL != pTimerName) { + for(i = 0; i < sizeof(pTimer->TimerName); i++) + { + pTimer->TimerName[i] = pTimerName[i]; + if(pTimerName[i] == '\0') + { + break; + } + } + } + else { + _strcpy((char*)(pTimer->TimerName), "None"); + } + MSG_TIMER_INFO("RtlTimerCreate: SW Timer Created: Name=%s Period=%d isPeriodical=%d\n", \ + pTimer->TimerName, pTimer->msPeriod, pTimer->isPeriodical); + } + else +#endif + { + RtlMfree((u8 *)pTimer, sizeof(RTL_TIMER)); + pTimer = NULL; + MSG_TIMER_ERR("RtlTimerCreate: OS Create Timer Failed!\n"); + } + + return (pTimer); +} + +/****************************************************************************** + * Function: RtlTimerDelete + * Desc: To delete a created software timer. + * + * Para: + * pTimerHdl: The timer to be deleted + * + * Return: None + * + ******************************************************************************/ +VOID RtlTimerDelete(IN PRTL_TIMER pTimerHdl) +{ +#ifdef PLATFORM_FREERTOS + portBASE_TYPE ret; +#endif + + if (NULL == pTimerHdl) { + MSG_TIMER_ERR("RtlTimerDelete: NULL Timer Handle!\n"); + return; + } + + MSG_TIMER_INFO("RtlTimerDelete: Name=%s\n", pTimerHdl->TimerName); +#ifdef PLATFORM_FREERTOS + /* try to delete the soft timer and wait max RTL_TIMER_API_MAX_BLOCK_TICKS + to send the delete command to the timer command queue */ + ret = rtw_timerDelete(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS); + if (pdPASS != ret) { + MSG_TIMER_ERR("RtlTimerDelete: Delete OS Timer Failed!\n"); + } +#endif + RtlMfree((u8 *)pTimerHdl, sizeof(RTL_TIMER)); + +} + +/****************************************************************************** + * Function: RtlTimerStart + * Desc: To start a created timer.. + * + * Para: + * pTimerHdl: The timer to be started. + * isFromISR: The flag to indicate that is this function is called from an ISR. + * + * Return: _SUCCESS or _FAIL + * + ******************************************************************************/ +u8 RtlTimerStart(IN PRTL_TIMER pTimerHdl, IN u8 isFromISR) +{ +#ifdef PLATFORM_FREERTOS + u8 ret=_FAIL; + portBASE_TYPE HigherPriorityTaskWoken=pdFALSE; + + if (isFromISR) { + if (pdPASS == rtw_timerStartFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken)) + { + // start OS timer successful + if (pdFALSE != HigherPriorityTaskWoken) { + rtw_yield_os(); + } + ret = _SUCCESS; + } + else { + MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) from ISR failed\n", pTimerHdl->TimerName); + } + } + else { + if (pdPASS == rtw_timerStart(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) { + ret = _SUCCESS; + } + else { + MSG_TIMER_ERR("RtlTimerStart: Start Timer(%s) failed\n", pTimerHdl->TimerName); + } + } + + MSG_TIMER_INFO("RtlTimerStart: SW Timer %s Started\n", pTimerHdl->TimerName); + + return ret; +#endif +} + +/****************************************************************************** + * Function: RtlTimerStop + * Desc: To stop a running timer.. + * + * Para: + * pTimerHdl: The timer to be stoped. + * isFromISR: The flag to indicate that is this function is called from an ISR. + * + * Return: _SUCCESS or _FAIL + * + ******************************************************************************/ +u8 RtlTimerStop(IN PRTL_TIMER pTimerHdl, IN u8 isFromISR) +{ +#ifdef PLATFORM_FREERTOS + u8 ret=_FAIL; + portBASE_TYPE HigherPriorityTaskWoken=pdFALSE; + + if (isFromISR) { + if (pdPASS == rtw_timerStopFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken)) + { + // start OS timer successful + if (pdFALSE != HigherPriorityTaskWoken) { + rtw_yield_os(); + } + ret = _SUCCESS; + } + } + else { + if (pdPASS == rtw_timerStop(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) { + ret = _SUCCESS; + } + } + + if (_FAIL == ret) { + MSG_TIMER_ERR("RtlTimerStop: Stop Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR); + } + + MSG_TIMER_INFO("RtlTimerStop: SW Timer %s Stoped\n", pTimerHdl->TimerName); + + return ret; +#endif +} + +/****************************************************************************** + * Function: RtlTimerReset + * Desc: To reset a timer. A reset will get a re-start and reset + * the timer ticks counting. A running timer expired time is relative + * to the time when Reset function be called. Please ensure the timer + * is in active state (Started). A stopped timer also will be started + * when this function is called. + * + * Para: + * pTimerHdl: The timer to be reset. + * isFromISR: The flag to indicate that is this function is called from an ISR. + * + * Return: _SUCCESS or _FAIL + * + ******************************************************************************/ +u8 +RtlTimerReset( + IN PRTL_TIMER pTimerHdl, + IN u8 isFromISR +) +{ +#ifdef PLATFORM_FREERTOS + u8 ret=_FAIL; + portBASE_TYPE HigherPriorityTaskWoken=pdFALSE; + + if (isFromISR) { + if (pdPASS == rtw_timerResetFromISR(pTimerHdl->TimerHandle,&HigherPriorityTaskWoken)) + { + // start OS timer successful + if (pdFALSE != HigherPriorityTaskWoken) { + rtw_yield_os(); + } + ret = _SUCCESS; + } + } + else { + if (pdPASS == rtw_timerReset(pTimerHdl->TimerHandle, RTL_TIMER_API_MAX_BLOCK_TICKS)) { + ret = _SUCCESS; + } + } + + if (_FAIL == ret) { + MSG_TIMER_ERR("RtlTimerReset: Reset Timer(%s) Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR); + } + + MSG_TIMER_INFO("RtlTimerReset: SW Timer %s Reset\n", pTimerHdl->TimerName); + + return ret; +#endif +} + +/****************************************************************************** + * Function: RtlTimerChangePeriod + * Desc: To change the period of a timer that was created previously. + * + * Para: + * pTimerHdl: The timer handle to be changed the priod. + * NewPeriodMS: The new timer period, in milli-second. + * isFromISR: The flag to indicate that is this function is called from an ISR. + * + * Return: _SUCCESS or _FAIL + * + ******************************************************************************/ +u8 RtlTimerChangePeriod( + IN PRTL_TIMER pTimerHdl, + IN u32 NewPeriodMS, + IN u8 isFromISR) +{ +#ifdef PLATFORM_FREERTOS + u32 timer_ticks; + u8 ret=_FAIL; + portBASE_TYPE HigherPriorityTaskWoken=pdFALSE; + + if (portTICK_RATE_MS >= NewPeriodMS) { + timer_ticks = 1; // at least 1 system tick + } + else { + timer_ticks = NewPeriodMS/portTICK_RATE_MS; + } + + if (isFromISR) { + if (pdPASS == rtw_timerChangePeriodFromISR(pTimerHdl->TimerHandle, timer_ticks, &HigherPriorityTaskWoken)) + { + // start OS timer successful + if (pdFALSE != HigherPriorityTaskWoken) { + taskYIELD(); + } + ret = _SUCCESS; + } + } + else { + if (pdPASS == rtw_timerChangePeriod(pTimerHdl->TimerHandle, timer_ticks, RTL_TIMER_API_MAX_BLOCK_TICKS)) { + ret = _SUCCESS; + } + } + + if (_FAIL == ret) { + MSG_TIMER_ERR("RtlTimerChangePeriod: Change Timer(%s) Period Failed, IsFromISR=%d\n", pTimerHdl->TimerName, isFromISR); + } + else { + pTimerHdl->msPeriod = NewPeriodMS; + MSG_TIMER_INFO("RtlTimerChangePeriod: SW Timer %s change period to %d\n", pTimerHdl->TimerName, pTimerHdl->msPeriod); + } + + + return ret; +#endif +} + diff --git a/USDK/component/soc/realtek/8195a/misc/os/osdep_api.h b/USDK/component/soc/realtek/8195a/misc/os/osdep_api.h new file mode 100644 index 0000000..2c8269d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/os/osdep_api.h @@ -0,0 +1,362 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __OSDEP_API_H_ +#define __OSDEP_API_H_ + +#include "os_timer.h" +#include "os_support.h" +#include "osdep_service.h" + + +#define MAX_SEMA_COUNT 32 /* the maximum count of a semaphore */ + +typedef _sema _Sema; +typedef _mutex _Mutex; +typedef u32 _Lock; +typedef struct TIMER_LIST _Timer; +typedef unsigned long _IRQL; +typedef _thread_hdl_ _THREAD_HDL_; +typedef VOID THREAD_RETURN; +typedef VOID THREAD_CONTEXT; + + +#ifndef mdelay +#define mdelay(t) ((t/portTICK_RATE_MS)>0)?(vTaskDelay(t/portTICK_RATE_MS)):(vTaskDelay(1)) +#endif + +#ifndef udelay +#define udelay(t) ((t/(portTICK_RATE_MS*1000))>0)?vTaskDelay(t/(portTICK_RATE_MS*1000)):(vTaskDelay(1)) +#endif + +/* to delete/start/stop a timer it will send a message to the timer task through a message queue, + so we define the max wait time for message sending */ +#define RTL_TIMER_API_MAX_BLOCK_TIME 1000 // unit is ms +#define RTL_TIMER_API_MAX_BLOCK_TICKS (RTL_TIMER_API_MAX_BLOCK_TIME/portTICK_RATE_MS) + +typedef VOID (*RTL_TIMER_CALL_BACK)(void *pContext); + +typedef struct _RTL_TIMER{ +#ifdef PLATFORM_FREERTOS + _timerHandle TimerHandle; // The timer handle of created FreeRTOS soft-timer +#endif + RTL_TIMER_CALL_BACK CallBackFunc; // Callback function of this timer + u32 msPeriod; // The period of this timer + void *Context; // Timer specific context. + u8 isPeriodical; // Is a periodical timer + u8 TimerName[35]; // The Name of timer +}RTL_TIMER, *PRTL_TIMER; + +__inline static VOID RtlEnterCritical(VOID) +{ + rtw_enter_critical(NULL, NULL); +} + +__inline static VOID RtlExitCritical(VOID) +{ + rtw_exit_critical(NULL, NULL); +} + +__inline static VOID RtlEnterCriticalBh(IN _Lock *plock, IN _IRQL *pirqL) +{ + rtw_enter_critical_bh((_lock *)plock, pirqL); +} + +__inline static VOID RtlExitCriticalBh(IN _Lock *plock, IN _IRQL *pirqL) +{ + rtw_exit_critical_bh((_lock *)plock, pirqL); +} + +__inline static u32 RtlEnterCriticalMutex(IN _Mutex *pmutex, IN _IRQL *pirqL) +{ + return rtw_enter_critical_mutex(pmutex, pirqL); +} + +__inline static VOID RtlExitCriticalMutex(IN _Mutex *pmutex,IN _IRQL *pirqL) +{ + rtw_exit_critical_mutex(pmutex, pirqL); +} + +__inline static VOID RtlInitTimer( + IN _Timer *ptimer, + IN VOID *Data, + IN VOID (*pfunc)(VOID *), + IN VOID* cntx +) +{ + ptimer->Function = pfunc; + ptimer->Data = (unsigned long)cntx; + InitTimer(ptimer); +} + +__inline static VOID RtlSetTimer( + IN _Timer *ptimer, + IN u32 delay_time +) +{ + ModTimer(ptimer , (JIFFIES+(delay_time*RTL_HZ/1000))); +} + +__inline static VOID RtlCancelTimer( + IN _Timer *ptimer, + IN u8 *bcancelled +) +{ + DelTimerSync(ptimer); + *bcancelled= _TRUE;//TRUE ==1; FALSE==0 +} + +__inline static u32 RtlSystime2Ms(IN u32 systime) +{ + return rtw_systime_to_ms(systime); +} + +__inline static u32 RtlMs2Systime(IN u32 ms) +{ + return rtw_ms_to_systime(ms); +} + +extern u8* RtlZmalloc(u32 sz); +extern u8* RtlMalloc(u32 sz); +extern VOID RtlMfree(u8 *pbuf, u32 sz); + +extern VOID* RtlMalloc2d(u32 h, u32 w, u32 size); +extern VOID RtlMfree2d(VOID *pbuf, u32 h, u32 w, u32 size); + +extern VOID RtlInitSema(_Sema *sema, u32 init_val); +extern VOID RtlFreeSema(_Sema *sema); +extern VOID RtlUpSema(_Sema *sema); +extern VOID RtlUpSemaFromISR(_Sema *sema); +extern u32 RtlDownSema(_Sema *sema); +extern u32 RtlDownSemaWithTimeout(_Sema *sema, u32 ms); + +extern VOID RtlMutexInit(_Mutex *pmutex); +extern VOID RtlMutexFree(_Mutex *pmutex); + +extern VOID RtlSpinlockInit(_Lock *plock); +extern VOID RtlSpinlockFree(_Lock *plock); +extern VOID RtlSpinlock(_Lock *plock); +extern VOID RtlSpinunlock(_Lock *plock); +extern VOID RtlSpinlockEx(_Lock *plock); +extern VOID RtlSpinunlockEx(_Lock *plock); + +extern VOID RtlSleepSchedulable(u32 ms); + +extern VOID RtlMsleepOS(u32 ms); +extern VOID RtlUsleepOS(u32 us); +extern VOID RtlMdelayOS(u32 ms); +extern VOID RtlUdelayOS(u32 us); +extern VOID RtlYieldOS(VOID); + +#define RtlUpMutex(mutex) RtlUpSema(mutex) +#define RtlDownMutex(mutex) RtlDownSema(mutex) + +__inline static u8 RtlCancelTimerEx(IN _Timer *ptimer) +{ + DelTimerSync(ptimer); + return 0; +} + + +static __inline VOID ThreadEnter(IN char *name) +{ + DBG_8195A("\rRTKTHREAD_enter %s\n", name); +} + +#define ThreadExit() do{DBG_8195A("\rRTKTHREAD_exit %s\n", __FUNCTION__);}while(0) + +__inline static VOID FlushSignalsThread(VOID) +{ +} + + +#define RTL_RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) +#define RTL_RND4(x) (((x >> 2) + (((x & 3) == 0) ? 0: 1)) << 2) + +__inline static u32 RtlRnd4(IN u32 sz) +{ + + u32 val; + + val = ((sz >> 2) + ((sz & 3) ? 1: 0)) << 2; + + return val; + +} + +__inline static u32 RtlRnd8(IN u32 sz) +{ + + u32 val; + + val = ((sz >> 3) + ((sz & 7) ? 1: 0)) << 3; + + return val; + +} + +__inline static u32 RtlRnd128(IN u32 sz) +{ + + u32 val; + + val = ((sz >> 7) + ((sz & 127) ? 1: 0)) << 7; + + return val; + +} + +__inline static u32 RtlRnd256(IN u32 sz) +{ + + u32 val; + + val = ((sz >> 8) + ((sz & 255) ? 1: 0)) << 8; + + return val; + +} + +__inline static u32 RtlRnd512(IN u32 sz) +{ + + u32 val; + + val = ((sz >> 9) + ((sz & 511) ? 1: 0)) << 9; + + return val; + +} + +__inline static u32 BitShift(IN u32 BitMask) +{ + u32 i; + + for (i = 0; i <= 31; i++) + if (((BitMask>>i) & 0x1) == 1) break; + + return i; +} + + +//#ifdef __GNUC__ +#ifdef PLATFORM_LINUX +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define STRUCT_PACKED +#endif + + +//Atomic integer operations +#define RTL_ATOMIC_T atomic_t + +static inline VOID RTL_ATOMIC_SET(IN RTL_ATOMIC_T *v, IN u32 i) +{ + ATOMIC_SET(v,i); +} + +static inline uint32_t RTL_ATOMIC_READ(IN RTL_ATOMIC_T *v) +{ + return ATOMIC_READ(v); +} + +static inline VOID RTL_ATOMIC_ADD(IN RTL_ATOMIC_T *v, IN u32 i) +{ + ATOMIC_ADD(v,i); +} + +static inline VOID RTL_ATOMIC_SUB(IN RTL_ATOMIC_T *v, IN u32 i) +{ + ATOMIC_SUB(v,i); +} + +static inline VOID RTL_ATOMIC_INC(IN RTL_ATOMIC_T *v) +{ + ATOMIC_INC(v); +} + +static inline VOID RTL_ATOMIC_DEC(IN RTL_ATOMIC_T *v) +{ + ATOMIC_DEC(v); +} + +static inline u32 RTL_ATOMIC_ADD_RETURN(IN RTL_ATOMIC_T *v, IN u32 i) +{ + return ATOMIC_ADD_RETURN(v, i); +} + +static inline u32 RTL_ATOMIC_SUB_RETURN(IN RTL_ATOMIC_T *v, IN u32 i) +{ + return ATOMIC_SUB_RETURN(v, i); +} + +static inline u32 RTL_ATOMIC_INC_RETURN(IN RTL_ATOMIC_T *v) +{ + return ATOMIC_INC_RETURN(v); +} + +static inline u32 RTL_ATOMIC_DEC_RETURN(IN RTL_ATOMIC_T *v) +{ + return ATOMIC_DEC_RETURN(v); +} + +extern u64 RtlModular64(u64 x, u64 y); + +extern PRTL_TIMER +RtlTimerCreate( + IN char *pTimerName, + IN u32 TimerPeriodMS, + IN RTL_TIMER_CALL_BACK CallbckFunc, + IN void *pContext, + IN u8 isPeriodical +); + +extern VOID +RtlTimerDelete( + IN PRTL_TIMER pTimerHdl +); + +extern u8 +RtlTimerStart( + IN PRTL_TIMER pTimerHdl, + IN u8 isFromISR +); + +extern u8 +RtlTimerStop( + IN PRTL_TIMER pTimerHdl, + IN u8 isFromISR +); + +extern u8 +RtlTimerReset( + IN PRTL_TIMER pTimerHdl, + IN u8 isFromISR +); + +extern u8 +RtlTimerChangePeriod( + IN PRTL_TIMER pTimerHdl, + IN u32 NewPeriodMS, + IN u8 isFromISR +); + +#endif //#ifndef __OSDEP_API_H_ + + diff --git a/USDK/component/soc/realtek/8195a/misc/platform/gcc_wrap.c b/USDK/component/soc/realtek/8195a/misc/platform/gcc_wrap.c new file mode 100644 index 0000000..795a03e --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/platform/gcc_wrap.c @@ -0,0 +1,22 @@ +/************************************************** + * malloc/free/realloc wrap for gcc compiler + * + **************************************************/ +#if defined(__GNUC__) +#include "FreeRTOS.h" + +void* __wrap_malloc( size_t size ) +{ + return pvPortMalloc(size); +} + +void* __wrap_realloc( void *p, size_t size ) +{ + return pvPortReAalloc(p, size); +} + +void __wrap_free( void *p ) +{ + vPortFree(p); +} +#endif \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.c b/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.c new file mode 100644 index 0000000..83b514d --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.c @@ -0,0 +1,825 @@ +#include +#include +#include "ota_8195a.h" +#include "lwip/netdb.h" + +sys_thread_t TaskOTA = NULL; +#define STACK_SIZE 1024 +#define TASK_PRIORITY tskIDLE_PRIORITY + 1 +#if SWAP_UPDATE +static uint32_t OldImg2Addr; +#endif +static flash_t flash_ota; + +#if CONFIG_CUSTOM_SIGNATURE +/* --------------------------------------------------- + * Customized Signature + * ---------------------------------------------------*/ +// This signature can be used to verify the correctness of the image +// It will be located in fixed location in application image +#include "section_config.h" +SECTION(".custom.validate.rodata") +const unsigned char cus_sig_demo[32] = "Customer Signature-modelxxx"; +#endif + +void* update_malloc(unsigned int size){ + return pvPortMalloc(size); +} + +void update_free(void *buf){ + vPortFree(buf); +} + +void ota_platform_reset(void){ + // Set processor clock to default before system reset + HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021); + osDelay(100); + + // Cortex-M3 SCB->AIRCR + HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY + (HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP + (1 << 2)); // SYSRESETREQ + while(1) osDelay(1000); +} + +#if WRITE_OTA_ADDR +int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr) +{ + uint32_t data, i = 0; + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(flash, OFFSET_DATA, &data); + printf("\n\r[%s] data 0x%x ota_addr 0x%x", __FUNCTION__, data, ota_addr); + if(~0x0 == data){ + flash_write_word(flash, OFFSET_DATA, ota_addr); + } + else{ + //erase backup sector + flash_erase_sector(flash, BACKUP_SECTOR); + //backup system data to backup sector + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(flash, OFFSET_DATA + i, &data); + if(0 == i) + data = ota_addr; + flash_write_word(flash, BACKUP_SECTOR + i,data); + } + //erase system data + flash_erase_sector(flash, OFFSET_DATA); + //write data back to system data + for(i = 0; i < 0x1000; i+= 4){ + flash_read_word(flash, BACKUP_SECTOR + i, &data); + flash_write_word(flash, OFFSET_DATA + i,data); + } + //erase backup sector + flash_erase_sector(flash, BACKUP_SECTOR); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + return 0; +} +#endif + +int update_ota_connect_server(int server_socket, update_cfg_local_t *cfg){ + struct sockaddr_in server_addr; + + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if(server_socket < 0){ + printf("\n\r[%s] Create socket failed", __FUNCTION__); + return -1; + } + + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = cfg->ip_addr; + server_addr.sin_port = cfg->port; + + if(connect(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){ + printf("\n\r[%s] Socket connect failed", __FUNCTION__); + return -1; + } + + return server_socket; +} + +uint32_t update_ota_prepare_addr(void){ + + uint32_t Img2Len = 0; + uint32_t IMAGE_x = 0, ImgxLen = 0, ImgxAddr = 0; + uint32_t NewImg2Addr = 0; +#if WRITE_OTA_ADDR + uint32_t ota_addr = 0x80000; +#endif + + DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_); + // The upgraded image2 pointer must 4K aligned and should not overlap with Default Image2 + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash_ota, IMAGE_2, &Img2Len); + IMAGE_x = IMAGE_2 + Img2Len + 0x10; + flash_read_word(&flash_ota, IMAGE_x, &ImgxLen); + flash_read_word(&flash_ota, IMAGE_x+4, &ImgxAddr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + if(0x30000000 == ImgxAddr){ + printf("\n\r[%s] IMAGE_3 0x%x Img3Len 0x%x", __FUNCTION__, IMAGE_x, ImgxLen); + } + else{ + printf("\n\r[%s] There is no IMAGE_3", __FUNCTION__); + IMAGE_x = IMAGE_2; + ImgxLen = Img2Len; + } +#if WRITE_OTA_ADDR + if((ota_addr > IMAGE_x) && ((ota_addr < (IMAGE_x+ImgxLen))) || (ota_addr < IMAGE_x) || + ((ota_addr & 0xfff) != 0) || (ota_addr == ~0x0)){ + printf("\n\r[%s] illegal ota addr 0x%x", __FUNCTION__, ota_addr); + return -1; + } + else + write_ota_addr_to_system_data(&flash_ota, ota_addr); +#endif + + //Get upgraded image 2 addr from offset + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash_ota, OFFSET_DATA, &NewImg2Addr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + if((NewImg2Addr > IMAGE_x) && ((NewImg2Addr < (IMAGE_x+ImgxLen))) || (NewImg2Addr < IMAGE_x) || + ((NewImg2Addr & 0xfff) != 0) || (NewImg2Addr == ~0x0)){ + printf("\n\r[%s] Invalid OTA Address 0x%x", __FUNCTION__, NewImg2Addr); + return -1; + } + + return NewImg2Addr; +} + +#if SWAP_UPDATE +uint32_t update_ota_swap_addr(uint32_t img_len, uint32_t NewImg2Addr){ + uint32_t SigImage0,SigImage1; + uint32_t Part1Addr=0xFFFFFFFF, Part2Addr=0xFFFFFFFF; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash_ota, 0x18, &Part1Addr); + Part1Addr = (Part1Addr&0xFFFF)*1024; //PART1 : 0x0000B000 + Part2Addr = NewImg2Addr; //PART2 : 0x00080000 + + // read Part1 signature + flash_read_word(&flash_ota, Part1Addr+8, &SigImage0); + flash_read_word(&flash_ota, Part1Addr+12, &SigImage1); + printf("\n\r[%s] Part1 Sig %x", __FUNCTION__, SigImage0); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + if(SigImage0==0x35393138 && SigImage1==0x31313738)//Part1 is the new one with signature "81958711" + OldImg2Addr = Part1Addr; //Change Part1 to older version + else{ + // read Part2 signature + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash_ota, Part2Addr+8, &SigImage0); + flash_read_word(&flash_ota, Part2Addr+12, &SigImage1); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("\n\r[%s] Part2 Sig %x", __FUNCTION__, SigImage0); + if(SigImage0==0x30303030 && SigImage1==0x30303030){// ATSC signature "00000000" + OldImg2Addr = Part1Addr; //Store the new version to Part2 + } + else if(SigImage0==0x35393138 && SigImage1==0x31313738){//Part2 is the new one with signature "81958711" + OldImg2Addr = Part2Addr; //Change Part2 to older version + NewImg2Addr = Part1Addr; + if( img_len > (Part2Addr-Part1Addr) ){ // firmware size too large + printf("\n\r[%s] Part1 size < OTA size", __FUNCTION__); + return -1; + } + } + else + NewImg2Addr = Part2Addr; + } + + printf("\n\r[%s] New %x, Old %x", __FUNCTION__, NewImg2Addr, OldImg2Addr); + return NewImg2Addr; +} +#endif + +int update_ota_erase_upg_region(uint32_t img_len, uint32_t NewImg2Len, uint32_t NewImg2Addr){ + uint32_t NewImg2BlkSize = 0; + + if(NewImg2Len == 0){ + NewImg2Len = img_len; + printf("\n\r[%s] NewImg2Len %d ", __FUNCTION__, NewImg2Len); + if((int)NewImg2Len > 0){ + NewImg2BlkSize = ((NewImg2Len - 1)/4096) + 1; + printf("\n\r[%s] NewImg2BlkSize %d 0x%8x", __FUNCTION__, NewImg2BlkSize, NewImg2BlkSize); + device_mutex_lock(RT_DEV_LOCK_FLASH); + for(int i = 0; i < NewImg2BlkSize; i++) + flash_erase_sector(&flash_ota, NewImg2Addr + i * 4096); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + }else{ + printf("\n\r[%s] Size INVALID", __FUNCTION__); + return -1; + } + } + + printf("\n\r[%s] NewImg2Addr 0x%x", __FUNCTION__, NewImg2Addr); + return NewImg2Len; +} + +int update_ota_checksum(_file_checksum *file_checksum, uint32_t flash_checksum, uint32_t NewImg2Addr){ + +#if CONFIG_CUSTOM_SIGNATURE + char custom_sig[32] = "Customer Signature-modelxxx"; + uint32_t read_custom_sig[8]; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + for(int i = 0; i < 8; i ++){ + flash_read_word(&flash_ota, NewImg2Addr + 0x28 + i *4, read_custom_sig + i); + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("\n\r[%s] read_custom_sig %s", __FUNCTION__ , (char*)read_custom_sig); +#endif + + printf("\n\rflash checksum 0x%8x attached checksum 0x%8x", flash_checksum, file_checksum->u); + + // compare checksum with received checksum + if( (file_checksum->u == flash_checksum) +#if CONFIG_CUSTOM_SIGNATURE + && !strcmp((char*)read_custom_sig,custom_sig) +#endif + ){ + //Set signature in New Image 2 addr + 8 and + 12 + uint32_t sig_readback0,sig_readback1; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_write_word(&flash_ota,NewImg2Addr + 8, 0x35393138); + flash_write_word(&flash_ota,NewImg2Addr + 12, 0x31313738); + flash_read_word(&flash_ota, NewImg2Addr + 8, &sig_readback0); + flash_read_word(&flash_ota, NewImg2Addr + 12, &sig_readback1); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("\n\r[%s] signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1); +#if SWAP_UPDATE + if(OldImg2Addr != ~0x0){ + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_write_word(&flash_ota,OldImg2Addr + 8, 0x35393130); + flash_write_word(&flash_ota,OldImg2Addr + 12, 0x31313738); + flash_read_word(&flash_ota, OldImg2Addr + 8, &sig_readback0); + flash_read_word(&flash_ota, OldImg2Addr + 12, &sig_readback1); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + printf("\n\r[%s] old signature %x,%x", __FUNCTION__ , sig_readback0, sig_readback1); + } +#endif + printf("\n\r[%s] Update OTA success!", __FUNCTION__); + return 0; + } + return -1; +} + +static void update_ota_local_task(void *param) +{ + int server_socket; + unsigned char *buf, *alloc; + _file_checksum *file_checksum; + int read_bytes = 0, size = 0, i = 0; + update_cfg_local_t *cfg = (update_cfg_local_t *)param; + uint32_t address, flash_checksum=0; + uint32_t NewImg2Len = 0, NewImg2Addr = 0, file_info[3]; + int ret = -1 ; + + printf("\n\r[%s] Update task start", __FUNCTION__); + alloc = update_malloc(BUF_SIZE+4); + if(!alloc){ + printf("\n\r[%s] Alloc buffer failed", __FUNCTION__); + goto update_ota_exit; + } + buf = &alloc[4]; + file_checksum = (void*)alloc; + + // Connect server + server_socket = update_ota_connect_server(server_socket, cfg); + if(server_socket == -1){ + goto update_ota_exit; + } + + NewImg2Addr = update_ota_prepare_addr(); + if(NewImg2Addr == -1){ + goto update_ota_exit; + } + + //Clear file_info + memset(file_info, 0, sizeof(file_info)); + + if(file_info[0] == 0){ + printf("\n\r[%s] Read info first", __FUNCTION__); + read_bytes = read(server_socket, file_info, sizeof(file_info)); + // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X + // !W checksum !W padding 0 !W file size !W + // !X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X!X + printf("\n\r[%s] info %d bytes", __FUNCTION__, read_bytes); + printf("\n\r[%s] tx chechsum 0x%x, file size 0x%x", __FUNCTION__, file_info[0],file_info[2]); + if(file_info[2] == 0){ + printf("\n\r[%s] No checksum and file size", __FUNCTION__); + goto update_ota_exit; + } + } + +#if SWAP_UPDATE + NewImg2Addr = update_ota_swap_addr(file_info[2], NewImg2Addr); + if(NewImg2Addr == -1){ + goto update_ota_exit; + } +#endif + + NewImg2Len = update_ota_erase_upg_region(file_info[2], NewImg2Len, NewImg2Addr); + if(NewImg2Len == -1){ + goto update_ota_exit; + } + + // reset + file_checksum->u = 0; + // Write New Image 2 sector + if(NewImg2Addr != ~0x0){ + address = NewImg2Addr; + printf("\n\rStart to read data %d bytes\r\n", NewImg2Len); + while(1){ + memset(buf, 0, BUF_SIZE); + read_bytes = read(server_socket, buf, BUF_SIZE); + if(read_bytes == 0) + break; // Read end + if(read_bytes < 0){ + printf("\n\r[%s] Read socket failed", __FUNCTION__); + goto update_ota_exit; + } + + if(read_bytes<4) + printf("\n\r[%s] Recv small packet", __FUNCTION__); + printf("."); + + if((size+read_bytes)>NewImg2Len){ + printf("\n\r[%s] Redundant bytes received", __FUNCTION__); + read_bytes = NewImg2Len-size; + } + + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(flash_stream_write(&flash_ota, address + size, read_bytes, buf) < 0){ + printf("\n\r[%s] Write stream failed", __FUNCTION__); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto update_ota_exit; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + size += read_bytes; + + file_checksum->c[0] = alloc[4+read_bytes-4]; // checksum attached at file end + file_checksum->c[1] = alloc[4+read_bytes-3]; + file_checksum->c[2] = alloc[4+read_bytes-2]; + file_checksum->c[3] = alloc[4+read_bytes-1]; + + if(size == NewImg2Len) + break; + } + printf("\n\rRead data finished\r\n"); + + // read flash data back and calculate checksum + for(i = 0; i < size-4; i += BUF_SIZE){ + int k; + int rlen = (size-4-i) > BUF_SIZE ? BUF_SIZE : (size-4-i); + flash_stream_read(&flash_ota, NewImg2Addr+i, rlen, buf); + for(k = 0; k < rlen; k++) + flash_checksum+=buf[k]; + } + + ret = update_ota_checksum(file_checksum, flash_checksum, NewImg2Addr); + if(ret == -1){ + printf("\r\nThe checksume is wrong!\r\n"); + goto update_ota_exit; + } + } +update_ota_exit: + if(alloc) + update_free(alloc); + if(server_socket >= 0) + close(server_socket); + if(param) + update_free(param); + TaskOTA = NULL; + printf("\n\r[%s] Update task exit", __FUNCTION__); + if(!ret){ + printf("\n\r[%s] Ready to reboot", __FUNCTION__); + ota_platform_reset(); + } + vTaskDelete(NULL); + return; +} + +int update_ota_local(char *ip, int port){ + update_cfg_local_t *pUpdateCfg; + + if(TaskOTA){ + printf("\n\r[%s] Update task has created.", __FUNCTION__); + return 0; + } + pUpdateCfg = update_malloc(sizeof(update_cfg_local_t)); + if(pUpdateCfg == NULL){ + printf("\n\r[%s] Alloc update cfg failed", __FUNCTION__); + return -1; + } + pUpdateCfg->ip_addr = inet_addr(ip); + pUpdateCfg->port = ntohs(port); + + if(xTaskCreate(update_ota_local_task, "OTA_server", STACK_SIZE, pUpdateCfg, TASK_PRIORITY, &TaskOTA) != pdPASS){ + update_free(pUpdateCfg); + printf("\n\r[%s] Create update task failed", __FUNCTION__); + } + return 0; +} + +void cmd_update(int argc, char **argv){ + int port; + if(argc != 3){ + printf("\n\r[%s] Usage: update IP PORT", __FUNCTION__); + return; + } + port = atoi(argv[2]); + update_ota_local(argv[1], port); +} + +void cmd_ota_image(bool cmd){ + flash_t flash; + uint32_t Part1Addr = 0xFFFFFFFF,Part2Addr = 0xFFFFFFFF; + uint8_t *pbuf = NULL; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, 0x18, &Part1Addr); + Part1Addr = (Part1Addr&0xFFFF)*1024; // first partition + flash_read_word(&flash, OFFSET_DATA, &Part2Addr); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + if(Part2Addr == ~0x0) + return; + + pbuf = update_malloc(FLASH_SECTOR_SIZE); + if(!pbuf) return; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf); + if (cmd == 1) + memcpy((char*)pbuf+8, "81958711", 8); + else + memcpy((char*)pbuf+8, "01958711", 8); + + flash_erase_sector(&flash, Part2Addr); + flash_stream_write(&flash, Part2Addr, FLASH_SECTOR_SIZE, pbuf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + +#if SWAP_UPDATE + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf); + if (cmd == 1) + memcpy((char*)pbuf+8, "01958711", 8); + else + memcpy((char*)pbuf+8, "81958711", 8); + + flash_erase_sector(&flash, Part1Addr); + flash_stream_write(&flash, Part1Addr, FLASH_SECTOR_SIZE, pbuf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); +#endif + update_free(pbuf); +} + +#ifdef HTTP_OTA_UPDATE +/****************************************************************************************************************** +** Function Name : update_ota_http_connect_server +** Description : connect to the OTA server +** Input : server_socket: the socket used +** host: host address of the OTA server +** port: port of the OTA server +** Return : connect ok: socket value +** Failed: -1 +*******************************************************************************************************************/ +int update_ota_http_connect_server(int server_socket, char *host, int port){ + struct sockaddr_in server_addr; + struct hostent *server; + + server_socket = socket(AF_INET, SOCK_STREAM, 0); + if(server_socket < 0){ + printf("\n\r[%s] Create socket failed", __FUNCTION__); + return -1; + } + + server = gethostbyname(host); + if(server == NULL){ + printf("[ERROR] Get host ip failed\n"); + return -1; + } + + memset(&server_addr,0,sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + memcpy(&server_addr.sin_addr.s_addr,server->h_addr,server->h_length); + + if (connect(server_socket,(struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){ + printf("\n\r[%s] Socket connect failed", __FUNCTION__); + return -1; + } + + return server_socket; +} + +/****************************************************************************************************************** +** Function Name : parse_http_response +** Description : Parse the http response to get some useful parameters +** Input : response : The http response got from server +** response_len: The length of http response +** result : The struct that store the usful infor about the http response +** Return : Parse OK: 1 -> Only got the status code +** 3 -> Got the status code and content_length, but didn't get the full header +** 4 -> Got all the information needed +** Failed: -1 +*******************************************************************************************************************/ +int parse_http_response(uint8_t *response, uint32_t response_len, http_response_result_t *result) { + uint32_t i, p, q, m; + uint32_t header_end = 0; + + //Get status code + if(0 == result->parse_status){//didn't get the http response + uint8_t status[4] = {0}; + i = p = q = m = 0; + for (; i < response_len; ++i) { + if (' ' == response[i]) { + ++m; + if (1 == m) {//after HTTP/1.1 + p = i; + } + else if (2 == m) {//after status code + q = i; + break; + } + } + } + if (!p || !q || q-p != 4) {//Didn't get the status code + return -1; + } + memcpy(status, response+p+1, 3);//get the status code + result->status_code = atoi((char const *)status); + if(result->status_code == 200) + result->parse_status = 1; + else{ + printf("\n\r[%s] The http response status code is %d", __FUNCTION__, result->status_code); + return -1; + } + } + + //if didn't receive the full http header + if(3 == result->parse_status){//didn't get the http response + p = q = 0; + for (i = 0; i < response_len; ++i) { + if (response[i] == '\r' && response[i+1] == '\n' && + response[i+2] == '\r' && response[i+3] == '\n') {//the end of header + header_end = i+4; + result->parse_status = 4; + result->header_len = header_end; + result->body = response + header_end; + break; + } + } + if (3 == result->parse_status) {//Still didn't receive the full header + result->header_bak = update_malloc(HEADER_BAK_LEN + 1); + memset(result->header_bak, 0, strlen(result->header_bak)); + memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN); + } + } + + //Get Content-Length + if(1 == result->parse_status){//didn't get the content length + uint32_t content_length = 0; + const uint8_t *content_length_buf1 = "CONTENT-LENGTH"; + const uint8_t *content_length_buf2 = "Content-Length"; + const uint32_t content_length_buf_len = strlen(content_length_buf1); + p = q = 0; + + for (i = 0; i < response_len; ++i) { + if (response[i] == '\r' && response[i+1] == '\n') { + q = i;//the end of the line + if (!memcmp(response+p, content_length_buf1, content_length_buf_len) || + !memcmp(response+p, content_length_buf2, content_length_buf_len)) {//get the content length + int j1 = p+content_length_buf_len, j2 = q-1; + while ( j1 < q && (*(response+j1) == ':' || *(response+j1) == ' ') ) ++j1; + while ( j2 > j1 && *(response+j2) == ' ') --j2; + uint8_t len_buf[12] = {0}; + memcpy(len_buf, response+j1, j2-j1+1); + result->body_len = atoi((char const *)len_buf); + result->parse_status = 2; + } + p = i+2; + } + if (response[i] == '\r' && response[i+1] == '\n' && + response[i+2] == '\r' && response[i+3] == '\n') {//Get the end of header + header_end = i+4;//p is the start of the body + if(result->parse_status == 2){//get the full header and the content length + result->parse_status = 4; + result->header_len = header_end; + result->body = response + header_end; + } + else {//there are no content length in header + printf("\n\r[%s] No Content-Length in header", __FUNCTION__); + return -1; + } + break; + } + } + + if (1 == result->parse_status) {//didn't get the content length and the full header + result->header_bak = update_malloc(HEADER_BAK_LEN + 1); + memset(result->header_bak, 0, strlen(result->header_bak)); + memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN); + } + else if (2 == result->parse_status) {//didn't get the full header but get the content length + result->parse_status = 3; + result->header_bak = update_malloc(HEADER_BAK_LEN + 1); + memset(result->header_bak, 0, strlen(result->header_bak)); + memcpy(result->header_bak, response + response_len - HEADER_BAK_LEN, HEADER_BAK_LEN); + } + } + + return result->parse_status; +} + +int http_update_ota(char *host, int port, char *resource) +{ + int server_socket; + unsigned char *buf, *alloc, *request; + _file_checksum *file_checksum; + int read_bytes = 0, i = 0; + uint32_t address, flash_checksum = 0; + uint32_t NewImg2Len = 0, NewImg2Addr = 0; + int ret = -1; + http_response_result_t rsp_result = {0}; + + alloc = update_malloc(BUF_SIZE + 4); + if(!alloc){ + printf("\n\r[%s] Alloc buffer failed", __FUNCTION__); + goto update_ota_exit; + } + buf = &alloc[4]; + file_checksum = (void*)alloc; + + // Connect server + server_socket = update_ota_http_connect_server(server_socket, host, port); + if(server_socket == -1){ + goto update_ota_exit; + } + + NewImg2Addr = update_ota_prepare_addr(); + if(NewImg2Addr == -1){ + goto update_ota_exit; + } + + // reset + file_checksum->u = 0; + + // Write New Image 2 sector + if(NewImg2Addr != ~0x0){ + uint32_t idx = 0; + int data_len = 0; + printf("\n\r"); + + //send http request + request = (unsigned char *) update_malloc(strlen("GET /") + strlen(resource) + strlen(" HTTP/1.1\r\nHost: ") + + strlen(host) + strlen("\r\n\r\n") + 1); + sprintf(request, "GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n", resource, host); + + ret = write(server_socket, request, strlen(request)); + if(ret < 0){ + printf("\n\r[%s] Send HTTP request failed", __FUNCTION__); + goto update_ota_exit; + } + + while (3 >= rsp_result.parse_status){//still read header + if(0 == rsp_result.parse_status){//didn't get the http response + memset(buf, 0, BUF_SIZE); + read_bytes = read(server_socket, buf, BUF_SIZE); + if(read_bytes == 0) + continue; + if(read_bytes < 0){ + printf("\n\r[%s] Read socket failed", __FUNCTION__); + goto update_ota_exit; + } + + idx = read_bytes; + memset(&rsp_result, 0, sizeof(rsp_result)); + if(parse_http_response(buf, idx, &rsp_result) == -1){ + goto update_ota_exit; + } + } + else if((1 == rsp_result.parse_status) || (3 == rsp_result.parse_status)){//just get the status code + memset(buf, 0, BUF_SIZE); + memcpy(buf, rsp_result.header_bak, HEADER_BAK_LEN); + update_free(rsp_result.header_bak); + rsp_result.header_bak = NULL; + read_bytes = read(server_socket, buf+ HEADER_BAK_LEN, (BUF_SIZE - HEADER_BAK_LEN)); + if(read_bytes == 0) + continue; + if(read_bytes < 0){ + printf("\n\r[%s] Read socket failed", __FUNCTION__); + goto update_ota_exit; + } + + idx = read_bytes + HEADER_BAK_LEN; + + if(parse_http_response(buf, read_bytes + HEADER_BAK_LEN, &rsp_result) == -1){ + goto update_ota_exit; + } + } + else if(3 == rsp_result.parse_status){ + printf("\n\r[%s] Get the content_length failed", __FUNCTION__); + goto update_ota_exit; + } + } + + if (0 == rsp_result.body_len){ + printf("\n\r[%s] New firmware size = 0 !", __FUNCTION__); + goto update_ota_exit; + } + else + printf("\n\r[%s] Download new firmware begin, total size : %d\n\r", __FUNCTION__, rsp_result.body_len); + +#if SWAP_UPDATE + NewImg2Addr = update_ota_swap_addr(rsp_result.body_len, NewImg2Addr); + if(NewImg2Addr == -1){ + goto update_ota_exit; + } +#endif + address = NewImg2Addr; + NewImg2Len = update_ota_erase_upg_region(rsp_result.body_len, NewImg2Len, NewImg2Addr); + if(NewImg2Len == -1){ + goto update_ota_exit; + } + + //Write the body of http response into flash + data_len = idx - rsp_result.header_len; + if(data_len > 0){ + file_checksum->c[0] = alloc[4+data_len-4]; // checksum attached at file end + file_checksum->c[1] = alloc[4+data_len-3]; + file_checksum->c[2] = alloc[4+data_len-2]; + file_checksum->c[3] = alloc[4+data_len-1]; + + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(flash_stream_write(&flash_ota, address, data_len, (buf+rsp_result.header_len)) < 0){ + printf("\n\r[%s] Write sector failed", __FUNCTION__); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto update_ota_exit; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + } + + idx = 0; + idx += data_len; + while (idx < NewImg2Len){ + printf("."); + data_len = NewImg2Len - idx; + if(data_len > BUF_SIZE) + data_len = BUF_SIZE; + + memset(buf, 0, BUF_SIZE); + read_bytes = read(server_socket, buf, data_len); + if(read_bytes == 0) + continue; + if(read_bytes < 0){ + printf("\n\r[%s] Read socket failed", __FUNCTION__); + goto update_ota_exit; + } + + if(read_bytes<4) + printf("\n\r[%s] Recv small packet", __FUNCTION__); + + device_mutex_lock(RT_DEV_LOCK_FLASH); + if(flash_stream_write(&flash_ota, address + idx, read_bytes, buf) < 0){ + printf("\n\r[%s] Write sector failed", __FUNCTION__); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + goto update_ota_exit; + } + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + file_checksum->c[0] = alloc[4+read_bytes-4]; // checksum attached at file end + file_checksum->c[1] = alloc[4+read_bytes-3]; + file_checksum->c[2] = alloc[4+read_bytes-2]; + file_checksum->c[3] = alloc[4+read_bytes-1]; + + idx += read_bytes; + } + printf("\n\r[%s] Download new firmware %d bytes completed\n\r", __FUNCTION__, idx); + + // read flash data back and calculate checksum + for(i = 0; i < idx-4; i += BUF_SIZE){ + int k; + int rlen = (idx-4-i)>BUF_SIZE?BUF_SIZE:(idx-4-i); + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_read(&flash_ota, NewImg2Addr+i, rlen, buf); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + for(k = 0; k < rlen; k++) + flash_checksum+=buf[k]; + } + + ret = update_ota_checksum(file_checksum, flash_checksum, NewImg2Addr); + if(ret == -1){ + printf("\n\r[%s] The checksume is wrong!\n\r", __FUNCTION__); + goto update_ota_exit; + } + } +update_ota_exit: + if(alloc) + update_free(alloc); + if(request) + update_free(request); + if(server_socket >= 0) + close(server_socket); + return ret; +} +#endif diff --git a/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.h b/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.h new file mode 100644 index 0000000..d474f62 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/platform/ota_8195a.h @@ -0,0 +1,97 @@ +#ifndef OTA_8195A_H +#define OTA_8195A_H + +#include +#include +#include +#include +#include + +/************************Related setting****************************/ +#define HTTP_OTA_UPDATE //if define, using http protocol, if not, will use socket +#define CONFIG_CUSTOM_SIGNATURE 0 //if verify the custom signature(define in ota_8195a.c cus_sig) +#define WRITE_OTA_ADDR 1 +#define SWAP_UPDATE 0 + + +#define BUF_SIZE 512 +#define HEADER_BAK_LEN 32 + +#define OFFSET_DATA FLASH_SYSTEM_DATA_ADDR +#define IMAGE_2 0x0000B000 +#if WRITE_OTA_ADDR +#define BACKUP_SECTOR (FLASH_SYSTEM_DATA_ADDR - 0x1000) +#endif +/*******************************************************************/ + + +/****************Define the structures used*************************/ +typedef struct{ + uint32_t ip_addr; + uint16_t port; +}update_cfg_local_t; + +typedef struct { + uint32_t status_code; + uint32_t header_len; + uint8_t *body; + uint32_t body_len; + uint8_t *header_bak; + uint32_t parse_status; +} http_response_result_t; + +typedef union { + uint32_t u; + unsigned char c[4]; +} _file_checksum; +/*******************************************************************/ + + +/****************General functions used by ota update***************/ +void *update_malloc(unsigned int size); +void update_free(void *buf); +void ota_platform_reset(void); +#if WRITE_OTA_ADDR +int write_ota_addr_to_system_data(flash_t *flash, uint32_t ota_addr); +#endif +int update_ota_connect_server(int server_socket, update_cfg_local_t *cfg); +uint32_t update_ota_prepare_addr(void); +#if SWAP_UPDATE +uint32_t update_ota_swap_addr(uint32_t img_len, uint32_t NewImg2Addr); +#endif +int update_ota_erase_upg_region(uint32_t img_len, uint32_t NewImg2Len, uint32_t NewImg2Addr); +int update_ota_checksum(_file_checksum *file_checksum, uint32_t flash_checksum, uint32_t NewImg2Addr); +/*******************************************************************/ + + +/*******************Functions called by AT CMD**********************/ +void cmd_update(int argc, char **argv); +void cmd_ota_image(bool cmd); +/*******************************************************************/ + + +/************************************************************************************************* +** Function Name : update_ota_local +** Description : Starting a thread of OTA updating through socket +** Input : ip:The IP address of OTA server +** port:The Port of OTA server +** Return : 0: Task created OK +** -1: Task created failed +**************************************************************************************************/ +int update_ota_local(char *ip, int port); + + +#ifdef HTTP_OTA_UPDATE +int parse_http_response(uint8_t *response, uint32_t response_len, http_response_result_t *result); +int update_ota_http_connect_server(int server_socket, char *host, int port); + +/************************************************************************************************* +** Function Name : http_update_ota +** Description : The process of OTA updating through http protocol +** Input : cfg:struct update_cfg_local_t +** Return : NULL +**************************************************************************************************/ +int http_update_ota(char *host, int port, char *resource); +#endif + +#endif diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rt_lib_rom.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rt_lib_rom.h new file mode 100644 index 0000000..50cc4ee --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rt_lib_rom.h @@ -0,0 +1,256 @@ +/* + * rtl_lib.h + * + * Definitions for RTL library functions + */ + +#ifndef _RTL_LIB_ROM_H_ +#define _RTL_LIB_ROM_H_ + + +#include +#include + +#include + +#include "../libc/rom/string/rom_libc_string.h" +#include "../libgloss/rtl8195a/rom/rom_libgloss_retarget.h" + +#ifndef _PTR +#define _PTR void * +#endif + +#ifndef _AND +#define _AND , +#endif + +#ifndef _NOARGS +#define _NOARGS void +#endif + +#ifndef _CONST +#define _CONST const +#endif + +#ifndef _VOLATILE +#define _VOLATILE volatile +#endif + +#ifndef _SIGNED +#define _SIGNED signed +#endif + +#ifndef _DOTS +#define _DOTS , ... +#endif + +#ifndef _VOID +#define _VOID void +#endif + + +// +// RTL library functions in ROM +// + +#define __rtl_memset __rtl_memset_v1_00 +#define __rtl_memchr __rtl_memchr_v1_00 +#define __rtl_memmove __rtl_memmove_v1_00 +#define __rtl_strcmp __rtl_strcmp_v1_00 +#define __rtl_memcpy __rtl_memcpy_v1_00 + + + +extern _LONG_CALL_ void * __rtl_memset_v1_00(void * m , int c , size_t n); +extern _LONG_CALL_ void * __rtl_memchr_v1_00(const void * src_void , int c , size_t length); +extern _LONG_CALL_ void * __rtl_memmove_v1_00( void * dst_void , const void * src_void , size_t length); +extern _LONG_CALL_ int __rtl_strcmp_v1_00(const char *s1 , const char *s2); +extern _LONG_CALL_ void * __rtl_memcpy_v1_00(void * __restrict dst0 , const void * __restrict src0 , size_t len0); + + +// +// rtl eabi functions +// + +#define __rtl_itod __rtl_itod_v1_00 +#define __rtl_dtoi __rtl_dtoi_v1_00 +#define __rtl_uitof __rtl_uitof_v1_00 +#define __rtl_uitod __rtl_uitod_v1_00 + + + +#define __rtl_dcmpeq __rtl_dcmpeq_v1_00 +#define __rtl_dcmplt __rtl_dcmplt_v1_00 +#define __rtl_dcmpgt __rtl_dcmpgt_v1_00 + + +#define __rtl_dadd __rtl_dadd_v1_00 +#define __rtl_dsub __rtl_dsub_v1_00 +#define __rtl_dmul __rtl_dmul_v1_00 +#define __rtl_ddiv __rtl_ddiv_v1_00 + +extern _LONG_CALL_ double __rtl_itod_v1_00(int lval); +extern _LONG_CALL_ int __rtl_dtoi_v1_00(double d); +extern _LONG_CALL_ float __rtl_uitof_v1_00(unsigned int lval); +extern _LONG_CALL_ double __rtl_uitod_v1_00(unsigned int lval); + + +extern _LONG_CALL_ int __rtl_dcmpeq_v1_00(double a, double b); +extern _LONG_CALL_ int __rtl_dcmplt_v1_00(double a, double b); +extern _LONG_CALL_ int __rtl_dcmpgt_v1_00(double a, double b); + + +extern _LONG_CALL_ double __rtl_dadd_v1_00(double a, double b); +extern _LONG_CALL_ double __rtl_dsub_v1_00(double a, double b); +extern _LONG_CALL_ double __rtl_dmul_v1_00(double a, double b); +extern _LONG_CALL_ double __rtl_ddiv_v1_00(double a, double b); + + +// +// mprec +// + +#include + + +typedef struct _Bigint _Bigint; + + +#define __rtl_Balloc __rtl_Balloc_v1_00 +#define __rtl_Bfree __rtl_Bfree_v1_00 +#define __rtl_d2b __rtl_d2b_v1_00 +#define __rtl_i2b __rtl_i2b_v1_00 +#define __rtl_pow5mult __rtl_pow5mult_v1_00 +#define __rtl_multadd __rtl_multadd_v1_00 +#define __rtl_mult __rtl_mult_v1_00 +#define __rtl_hi0bits __rtl_hi0bits_v1_00 +#define __rtl_lshift __rtl_lshift_v1_00 +#define __rtl_cmp __rtl_cmp_v1_00 +#define __rtl_diff __rtl_diff_v1_00 + + +extern _LONG_CALL_ _Bigint * __rtl_Balloc_v1_00(struct _reent *ptr, int k); + +extern _LONG_CALL_ void __rtl_Bfree_v1_00(struct _reent *ptr, _Bigint * v); + +extern _LONG_CALL_ _Bigint * __rtl_d2b_v1_00(struct _reent * ptr, double _d, int *e, int *bits); +extern _LONG_CALL_ _Bigint * __rtl_i2b_v1_00(struct _reent *ptr, int i ); +extern _LONG_CALL_ _Bigint * __rtl_pow5mult_v1_00(struct _reent * ptr, _Bigint *b, int k); +extern _LONG_CALL_ _Bigint * __rtl_multadd_v1_00(struct _reent *ptr, _Bigint * b, int m, int a); +extern _LONG_CALL_ _Bigint * __rtl_mult_v1_00(struct _reent *ptr, _Bigint *a, _Bigint *b); +extern _LONG_CALL_ int __rtl_hi0bits_v1_00(register __ULong x); +extern _LONG_CALL_ _Bigint *__rtl_lshift_v1_00(struct _reent *ptr, _Bigint *b, int k); +extern _LONG_CALL_ int __rtl_cmp_v1_00(_Bigint *a, _Bigint *b); +extern _LONG_CALL_ _Bigint *__rtl_diff_v1_00(struct _reent* ptr, _Bigint *a, _Bigint *b); + +// +// dtoa +// + +#define __rtl_dtoa_r __rtl_dtoa_r_v1_00 + +extern char * __rtl_dtoa_r_v1_00(struct _reent *ptr, double _d, int mode, int ndigits, int *decpt, int *sign, char **rve); + +// +// mallocr +// +#include +#include + + + +#define __rom_mallocr_init __rom_mallocr_init_v1_00 + +#define __rtl_calloc_r __rtl_calloc_r_v1_00 +#define __rtl_cfree_r __rtl_cfree_r_v1_00 +#define __rtl_malloc_r __rtl_malloc_r_v1_00 +#define __rtl_free_r __rtl_free_r_v1_00 +#define __rtl_realloc_r __rtl_realloc_r_v1_00 +#define __rtl_memalign_r __rtl_memalign_r_v1_00 +#define __rtl_valloc_r __rtl_valloc_r_v1_00 +#define __rtl_pvalloc_r __rtl_pvalloc_r_v1_00 + + +extern _LONG_CALL_ void __rom_mallocr_init_v1_00(void); + + +#define RARG struct _reent *reent_ptr, +extern _LONG_CALL_ void* __rtl_calloc_r_v1_00(RARG size_t n, size_t elem_size); +extern _LONG_CALL_ void __rtl_cfree_r_v1_00(void *mem); +extern _LONG_CALL_ void* __rtl_malloc_r_v1_00(RARG size_t bytes); +extern _LONG_CALL_ void __rtl_free_r_v1_00(RARG void* mem); +extern _LONG_CALL_ void* __rtl_realloc_r_v1_00(RARG void* oldmem, size_t bytes); +extern _LONG_CALL_ void* __rtl_memalign_r_v1_00(RARG size_t alignment, size_t bytes); +extern _LONG_CALL_ void* __rtl_valloc_r_v1_00(RARG size_t bytes); +extern _LONG_CALL_ void* __rtl_pvalloc_r_v1_00(RARG size_t bytes); + + +// +// stdio +// +extern int __rtl_errno; + +#ifndef _READ_WRITE_RETURN_TYPE +#define _READ_WRITE_RETURN_TYPE _ssize_t +#endif + +#ifndef _READ_WRITE_BUFSIZE_TYPE +#define _READ_WRITE_BUFSIZE_TYPE int +#endif + +#define __rtl_sread __rtl_sread_v1_00 +#define __rtl_swrite __rtl_swrite_v1_00 +#define __rtl_seofread __rtl_seofread_v1_00 +#define __rtl_sseek __rtl_sseek_v1_00 +#define __rtl_sclose __rtl_sclose_v1_00 +#define __rtl_sbrk_r __rtl_sbrk_r_v1_00 + +extern _LONG_CALL_ _READ_WRITE_RETURN_TYPE __rtl_sread_v1_00( + struct _reent *ptr, + void *cookie, + char *buf, + _READ_WRITE_BUFSIZE_TYPE n); + +extern _LONG_CALL_ _READ_WRITE_RETURN_TYPE __rtl_swrite_v1_00( + struct _reent *ptr, + void *cookie, + char const *buf, + _READ_WRITE_BUFSIZE_TYPE n); + +extern _LONG_CALL_ _READ_WRITE_RETURN_TYPE __rtl_seofread_v1_00( + struct _reent *_ptr, + _PTR cookie, + char *buf, + _READ_WRITE_BUFSIZE_TYPE len); + +extern _LONG_CALL_ _fpos_t __rtl_sseek_v1_00( + struct _reent *ptr _AND + void *cookie _AND + _fpos_t offset _AND + int whence); + +extern _LONG_CALL_ int __rtl_sclose_v1_00( + struct _reent *ptr _AND + void *cookie); + +extern _LONG_CALL_ void * __rtl_sbrk_r_v1_00( + struct _reent *ptr, + ptrdiff_t incr); + +// +// vfprintf +// + +#include +#include + +#define __rtl_vfprintf_r __rtl_vfprintf_r_v1_00 + +extern _LONG_CALL_ int __rtl_vfprintf_r_v1_00(struct _reent *, FILE *, const char *, va_list); + +#ifndef CONFIG_RELEASE_BUILD_LIBRARIES +#define __rtl_fflush_r __rtl_fflush_r_v1_00 +extern _LONG_CALL_ int __rtl_fflush_r_v1_00(struct _reent *ptr, register FILE * fp); +#endif + +#endif /* _RTL_LIB_ROM_H_ */ diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_bios_data.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_bios_data.h new file mode 100644 index 0000000..cc58bb5 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_bios_data.h @@ -0,0 +1,234 @@ +/* + * rtl_bios_data.h + * + * Created on: 12/02/2017 + * Author: pvvx + * + * This variables declared in ROM code! + * Variables use fixed addresses! + * (see *.ld script) + */ + +#ifndef _RTL_BIOS_DATA_H_ +#define _RTL_BIOS_DATA_H_ + +#include "platform_autoconf.h" +#include +#include +#include +#include +// component/soc/realtek/common/bsp/ +#include "basic_types.h" +// component/soc/realtek/8195a/fwlib/ +#include "rtl8195a/rtl8195a.h" +#include "hal_gpio.h" +#include "hal_irqn.h" +#include "hal_timer.h" +#include "hal_sdr_controller.h" +// component/soc/realtek/8195a/fwlib/ +#include "ram_lib/wlan/realtek/wlan_ram_map/rom/rom_wlan_ram_map.h" +// component/soc/realtek/8195a/misc/driver/ +#include "rtl_consol.h" +// component/soc/realtek/8195a/misc/rtl_std_lib/ +#include "include/rtl_lib.h" +#include "include/rt_lib_rom.h" +#include "libc/rom/string/rom_libc_string.h" +#include "libgloss/rtl8195a/rom/rom_libgloss_retarget.h" + +//#include "rom/rom_libgloss_retarget.h" + +typedef void (*START_FUNC)(void); + +/* ROM + startup.c */ +extern IRQ_FUN NewVectorTable[64]; // 10000000 +extern IRQ_FUN UserIrqFunTable[64]; // 10000100 +extern u32 UserIrqDataTable[64]; // 10000200 + +/* ROM + diag.h */ +extern u32 CfgSysDebugWarn; // 10000300 +extern u32 CfgSysDebugInfo; // 10000304 +extern u32 CfgSysDebugErr; // 10000308 +extern u32 ConfigDebugWarn; // 1000030c +extern u32 ConfigDebugInfo; // 10000310 +extern u32 ConfigDebugErr; // 10000314 + + +/* ROM + hal_timer.h & .. */ +extern HAL_TIMER_OP HalTimerOp; // 10000318 +extern u16 GPIOState[11]; // 10000334 +extern u32 gTimerRecord; // 1000034C +/* ROM + hal_ssi.h */ +extern u32 SSI_DBG_CONFIG; // 10000350 +extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter; // 10000354 + +/* ROM + rtl8195a_timer.c */ +extern IRQ_FUN Timer2To7VectorTable[MAX_TIMER_VECTOR_TABLE_NUM]; // 10000358 + +/* ROM + Rand() */ +extern u32 _rand_z4, _rand_z3, _rand_z2, _rand_z1, _rand_first; // 10000370.. + +/* ROM + rtl_consol.c */ +extern volatile UART_LOG_CTL *pUartLogCtl; // 10000384 +extern UART_LOG_BUF UartLogBuf; // 10000388 +extern volatile UART_LOG_CTL UartLogCtl; // 10000408 +extern u8 UartLogHistoryBuf[UART_LOG_HISTORY_LEN][UART_LOG_CMD_BUFLEN]; // 10000430 UartLogHistoryBuf[5][127] ! +extern u8 *ArgvArray[MAX_ARGV]; // 100006AC *ArgvArray[10] ! + +/* ROM + ?? */ +extern struct _rom_wlan_ram_map rom_wlan_ram_map; // 100006D4 +typedef struct _FALSE_ALARM_STATISTICS { + u32 Cnt_Parity_Fail; + u32 Cnt_Rate_Illegal; + u32 Cnt_Crc8_fail; + u32 Cnt_Mcs_fail; + u32 Cnt_Ofdm_fail; + u32 Cnt_Ofdm_fail_pre; + u32 Cnt_Cck_fail; + u32 Cnt_all; + u32 Cnt_Fast_Fsync; + u32 Cnt_SB_Search_fail; + u32 Cnt_OFDM_CCA; + u32 Cnt_CCK_CCA; + u32 Cnt_CCA_all; + u32 Cnt_BW_USC; + u32 Cnt_BW_LSC; +} FALSE_ALARM_STATISTICS; +extern FALSE_ALARM_STATISTICS FalseAlmCnt; // 100006E0 + +typedef struct _rom_info { + u8 EEPROMVersion; + u8 CrystalCap; + u64 DebugComponents; + u32 DebugLevel; +} ROM_INFO; +extern ROM_INFO ROMInfo; // 10000720 + +typedef struct _CFO_TRACKING_ { + BOOL bATCStatus; + BOOL largeCFOHit; + BOOL bAdjust; + u8 CrystalCap; + u8 DefXCap; + u32 CFO_tail[2]; + u32 CFO_ave_pre; + u32 packetCount; + u32 packetCount_pre; + BOOL bForceXtalCap; + BOOL bReset; + u8 CFO_TH_XTAL_HIGH; + u8 CFO_TH_XTAL_LOW; + u8 CFO_TH_ATC; +}CFO_TRACKING; +extern CFO_TRACKING DM_CfoTrack; // 10000738 + +/* in rom_libgloss_retarget.h +struct _rom_libgloss_ram_map { + int (*libgloss_close)(int fildes); + int (*libgloss_fstat)(int fildes , struct stat *st); + int (*libgloss_isatty)(int file); + int (*libgloss_lseek)(int file , int ptr , int dir); + int (*libgloss_open)(char *file , int flags , int mode); + int (*libgloss_read)(int file , char *ptr , int len); + int (*libgloss_write)(int file , const char *ptr , int len); + void* (*libgloss_sbrk)(int incr); +}; +*/ +extern struct _rom_libgloss_ram_map rom_libgloss_ram_map; // 10000760 +struct malloc_chunk +{ + size_t prev_size; + size_t size; + struct malloc_chunk *fd; + struct malloc_chunk *bk; +}; +extern struct malloc_chunk * __rtl_malloc_av_[258]; // 10000780 __rom_mallocr_init_v1_00(), _rtl_free_r_v1_00().. +extern u32 __rtl_malloc_trim_threshold; // 10000b88 __rom_mallocr_init_v1_00() +extern u32 __rtl_malloc_top_pad; // 10000b8c __rom_mallocr_init_v1_00() +extern u8 * __rtl_malloc_sbrk_base; // 10000b90 __rom_mallocr_init_v1_00() +extern u32 __rtl_malloc_max_sbrked_mem; // 10000b94 __rom_mallocr_init_v1_00() +extern u32 __rtl_malloc_max_total_mem; // 10000b98 __rom_mallocr_init_v1_00() +struct mallinfo +{ + int arena; + int ordblks; + int smblks; + int hblks; + int hblkhd; + int usmblks; + int fsmblks; + int uordblks; + int fordblks; + int keepcost; +}; +extern struct mallinfo __rtl_malloc_current_mallinfo; // 10000b9c __rom_mallocr_init_v1_00() + +/* IMAGE1 HEAD: ROM + startup.c (bootloader) */ +extern RAM_START_FUNCTION gRamStartFun; // 10000bc8 = { PreProcessForVendor + 1 }; +extern RAM_START_FUNCTION gRamPatchWAKE; // 10000bcc = { RtlBootToSram + 1 }; +extern RAM_START_FUNCTION gRamPatchFun0; // 10000bd0 = { RtlBootToSram + 1 }; +extern RAM_START_FUNCTION gRamPatchFun1; // 10000bd4 = { RtlBootToSram + 1 }; +extern RAM_START_FUNCTION gRamPatchFun2; // 10000bd8 = { RtlBootToSram + 1 }; +//extern uint8 RAM_IMG1_VALID_PATTEN[8]; // 10000bdc = { 0x23, 0x79, 0x16, 0x88, 0xff, 0xff, 0xff, 0xff }; + +/* ROM + hal_sdr_controller.c */ +extern u32 rand_x; // 10000be4: ChangeRandSeed_rom(), Sdr_Rand2_rom() +#define REC_NUM 512 +extern u32 AvaWds[2][REC_NUM]; // 10000be8 +extern DRAM_DEVICE_INFO SdrDramInfo; // 10001be8 +#define DRAM_DEVICE_INFO_INIT() { \ + &SdrDramDev, \ + &SdrDramModeReg, \ + &SdrDramTiming, \ + DRAM_TIMING_TCK, \ + DFI_RATIO_1 } +extern DRAM_TIMING_INFO SdrDramTiming; // 10001bfc +#define DRAM_TIMING_INFO_INIT() { \ + DRAM_TIMING_TRFC, /* TrfcPs; */ \ + DRAM_TIMING_TREFI, /* TrefiPs; */ \ + DRAM_TIMING_TWRMAXTCK, /* WrMaxTck; */\ + DRAM_TIMING_TRCD, /* TrcdPs; */ \ + DRAM_TIMING_TRP, /* TrpPs; */ \ + DRAM_TIMING_TRAS, /* TrasPs; */ \ + DRAM_TIMING_TRRD, /* TrrdTck; */ \ + DRAM_TIMING_TWR, /* TwrPs; */ \ + DRAM_TIMING_TWTR, /* TwtrTck; */ \ + /* 13090, */ /* TrtpPs; */ \ + DRAM_TIMING_TMRD, /* TmrdTck; */ \ + DRAM_TIMING_TRTP, /* TrtpTck; */ \ + DRAM_TIMING_TCCD, /* TccdTck; */ \ + DRAM_TIMING_TRC } /* TrcPs; */ +extern DRAM_MODE_REG_INFO SdrDramModeReg; // 10001c30 +#define DRAM_MODE_REG_INFO_INIT() { \ + BST_LEN_4, \ + SENQUENTIAL, \ + 0x3, /* Mode0Cas: 3 */ \ + 0x0, /* Mode0Wr */ \ + 0, /* Mode1DllEnN */ \ + 0, /* Mode1AllLat */ \ + 0 } /* Mode2Cwl */ +extern DRAM_INFO SdrDramDev; // 10001c4c +#define DRAM_INFO_INIT() { DRAM_INFO_TYPE, DRAM_INFO_COL_ADDR_WTH,DRAM_INFO_BANK_SZ, DRAM_INFO_DQ_WTH } +extern SPIC_INIT_PARA SpicInitParaAllClk[SpicMaxMode][CPU_CLK_TYPE_NO]; // 100021ec [144=0x90] + +/* ROM + "C" standard library */ +extern struct _reent * _rtl_impure_ptr; // 10001c60 = { &impure_reent }; +extern struct _reent impure_reent; // 10001c68 = _REENT_INIT(impure_reent); + +/* ROM ? UserData? */ +extern u32 _rom_unc_data[9]; // 100020e8 + +/* ROM + hal_sdr_controller.c: Sdr_Rand2() */ +extern u32 _sdr_rnd2_c, _sdr_rnd2_z, _sdr_rnd2_y; // 100020BC, 100020B8, 100020B4 + +/* *.ld */ +extern u8 __rom_bss_start__, __rom_bss_end__; +extern u8 __image1_bss_start__, __image1_bss_end__; +extern START_FUNC __image2_entry_func__; +//extern RAM_START_FUNCTION __image2_entry_func__; +extern u8 __image2_validate_code__; + +#ifndef STACK_TOP +#define STACK_TOP 0x1ffffffc +#endif + +#endif /* _RTL_BIOS_DATA_H_ */ diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_lib.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_lib.h new file mode 100644 index 0000000..13c7e8f --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_lib.h @@ -0,0 +1,141 @@ +/* + * rtl_lib.h + * + * Definitions for RTL library functions + */ + +#ifndef _RTL_LIB_H_ +#define _RTL_LIB_H_ + + +#include +#include +#include + + +extern int __rtl_errno; + + +void init_rom_libgloss_ram_map(void); + + +// +// RTL library functions for Libc::stdio +// + +extern int rtl_printf(IN const char* fmt, ...); +extern int rtl_vprintf(const char *fmt, va_list param); +extern int rtl_sprintf(char* str, const char* fmt, ...); +extern int rtl_snprintf(char* str, size_t size, const char* fmt, ...); +extern int rtl_vsnprintf(char *str, size_t size, const char *fmt, va_list param); + +// +// RTL library functions for string +// + +extern void * rtl_memchr(const void * src_void , int c , size_t length); +extern int rtl_memcmp(const void * m1 , const void * m2 , size_t n); +extern void * rtl_memcpy(void * dst0 , const void * src0 , size_t len0); +extern void * rtl_memmove( void * dst_void , const void * src_void , size_t length); +extern void * rtl_memset(void * m , int c , size_t n); +extern char * rtl_strcat(char * s1 , const char * s2); +extern char * rtl_strchr(const char *s1 , int i); +extern int rtl_strcmp(const char *s1 , const char *s2); +extern char* rtl_strcpy(char *dst0 , const char *src0); +extern size_t rtl_strlen(const char *str); +extern char * rtl_strncat(char * s1 , const char * s2 , size_t n); +extern int rtl_strncmp(const char *s1 , const char *s2 , size_t n); +extern char * rtl_strncpy(char * dst0 , const char * src0 , size_t count); +extern char * rtl_strstr(const char *searchee , const char *lookfor); +extern char * rtl_strsep(char **source_ptr , const char *delim); +extern char * rtl_strtok(char * s , const char * delim); + +// +// RTL library functions for math +// + + +extern double rtl_fabs(double); +extern float rtl_fabsf(float a); +extern float rtl_cos_f32(float a); +extern float rtl_sin_f32(float a); + +extern float rtl_fadd(float a, float b); +extern float rtl_fsub(float a, float b); +extern float rtl_fmul(float a, float b); +extern float rtl_fdiv(float a, float b); + +extern int rtl_fcmplt(float a, float b); +extern int rtl_fcmpgt(float a, float b); + + +// +// RTL eabi functions + +extern double rtl_ftod(float f); + +extern double rtl_ddiv(double a, double b); + + +// +// Macro Library Functions +// + +typedef union +{ + float value; + u32 word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +static inline +float rtl_nanf(void) +{ + float x; + + SET_FLOAT_WORD(x,0x7fc00000); + return x; +} + + +// +// Library Test functions +// + +extern int rtl_lib_test(IN u16 argc, IN u8 *argv[]); +extern int rtl_math_test(IN u16 argc, IN u8 *argv[]); +extern int rtl_string_test(IN u16 argc, IN u8 *argv[]); + + +// +// Macro functions +// + +#undef dbg_printf +#define dbg_printf(fmt, args...) \ + rtl_printf("%s():%d : " fmt "\n", __FUNCTION__, __LINE__, ##args); + + +#undef err_printf +#define err_printf(fmt, args...) \ + rtl_printf("%s():%d : " fmt "\n", __FUNCTION__, __LINE__, ##args); + + +#endif /* _RTL_LIB_H_ */ diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_rr_libc.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_rr_libc.h new file mode 100644 index 0000000..e548044 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/include/rtl_rr_libc.h @@ -0,0 +1,166 @@ +/* +* RAM->ROM Calls +*/ + +#ifndef _INC_RTL_RR_LIBC_ +#define _INC_RTL_RR_LIBC_ + +//#undef malloc +#define malloc(size) pvPortMalloc(size) +//#undef free +#define free(pbuf) vPortFree(pbuf) +//extern void* pvPortReAlloc( void *pv, size_t xWantedSize ) +#define realloc(pv, xWantedSize) pvPortReAlloc(pv, xWantedSize) + +#define calloc(nelements, elementSize) calloc_freertos(nelements, elementSize) + +#define snprintf rtl_snprintf +#define sprintf rtl_sprintf +#define printf rtl_printf +#define vprintf rtl_vprintf +#define vsnprintf rtl_vsnprintf +#define vfprintf rtl_vfprintf +#define memchr rtl_memchr +#define memcmp rtl_memcmp +#define memcpy rtl_memcpy +#define memmove rtl_memmove +#define memset rtl_memset +#define strcat rtl_strcat +#define strchr rtl_strchr +#define strcmp rtl_strcmp +#define strcpy rtl_strcpy +#define strlen rtl_strlen +#define strncat rtl_strncat +#define strncmp rtl_strncmp +#define strncpy rtl_strncpy +#define strstr rtl_strstr +#define strsep rtl_strsep +#define strtok rtl_strtok + +#if 0 // __aeabi_ +#define dtoi rtl_dtoi +#define dtoui rtl_dtoui +#define i2f rtl_i2f +#define i2d rtl_i2d +#define ui2f rtl_ui2f +#define ui2d rtl_ui2d +#define itoa rtl_itoa +#define ltoa rtl_ltoa +#define utoa rtl_utoa +#define ultoa rtl_ultoa +#define ftol rtl_ftol +#define ftod rtl_ftod +#define dtof rtl_dtof +#define fadd rtl_fadd +#define fsub rtl_fsub +#define fmul rtl_fmul +#define fdiv rtl_fdiv +#define dadd rtl_dadd +#define dsub rtl_dsub +#define dmul rtl_dmul +#define ddiv rtl_ddiv +#define dcmpeq rtl_dcmpeq +#define dcmplt rtl_dcmplt +#define dcmple rtl_dcmple +#define dcmpgt rtl_dcmpgt +#define fcmplt rtl_fcmplt +#define fcmpgt rtl_fcmpgt + +#define fabsf rtl_fabsf +#define fabs rtl_fabs +#define cos_f32 rtl_cos_f32 +#define sin_f32 rtl_sin_f32 +#endif + +#if 0 +extern void *calloc_freertos(size_t nelements, size_t elementSize); +// ram_libc.c +extern void rtl_libc_init(void); +extern int rtl_snprintf(char *str, size_t size, const char *fmt, ...); +extern int rtl_sprintf(char *str, const char *fmt, ...); +extern int rtl_printf(const char *fmt, ...); +extern int rtl_vprintf(const char *fmt, void *param); +extern int rtl_vsnprintf(char *str, size_t size, const char *fmt, void *param); +extern int rtl_vfprintf(FILE *fp, const char *fmt0, va_list ap); +extern void * rtl_memchr(const void * src_void , int c , size_t length); +extern int rtl_memcmp(const void *m1, const void *m2, size_t n); +extern void * rtl_memcpy(void *dst0, const void *src0, size_t len0); +extern void * rtl_memmove(void *dst_void, const void *src_void, size_t length); +extern void * rtl_memset(void *m, int c, size_t n); +extern char * rtl_strcat(char *s1, const char *s2); +extern char * rtl_strchr(const char *s1, int i); +extern int rtl_strcmp(const char *s1, const char *s2); +extern char * rtl_strcpy(char *dst0, const char *src0); +extern size_t rtl_strlen(const char *str); +extern char * rtl_strncat(char *s1, const char *s2, size_t n); +extern int rtl_strncmp(const char *s1, const char *s2, size_t n); +extern char * rtl_strncpy(char *dst0, const char *src0, size_t count); +extern char * rtl_strstr(const char *searchee, const char *lookfor); +extern char * rtl_strsep(char **source_ptr, const char *delim); +extern char * rtl_strtok(char *s, const char *delim); + +//rtl_eabi_cast_ram.c +extern int rtl_dtoi(double d); +extern int rtl_dtoui(double d); +extern float rtl_i2f(int val); +extern int rtl_i2d(int val); +extern float rtl_ui2f(unsigned int val); +extern int rtl_ui2d(unsigned int val); +extern char *rtl_itoa(int value, char *string, int radix); +extern char *rtl_ltoa(int value, char *string, int radix); +extern char *rtl_utoa(unsigned int value, char *string, int radix); +extern char *rtl_ultoa(unsigned int value, char *string, int radix); +extern int rtl_ftol(float f); +extern int rtl_ftod(float f); +extern float rtl_dtof(double d); +extern float rtl_fadd(float a, float b); +extern float rtl_fsub(float a, float b); +extern float rtl_fmul(float a, float b); +extern float rtl_fdiv(float a, float b); +extern int rtl_dadd(double a, double b); +extern int rtl_dsub(double a, double b); +extern int rtl_dmul(double a, double b); +extern int rtl_ddiv(double a, double b); +extern int rtl_dcmpeq(double a, double b); +extern int rtl_dcmplt(double a, double b); +extern int rtl_dcmple(double a, double b); +extern int rtl_dcmpgt(double a, double b); +extern int rtl_fcmplt(float a, float b); +extern int rtl_fcmpgt(float a, float b); + +// rtl_math_ram.c +extern float rtl_fabsf(float a); +extern int rtl_fabs(double a); +extern float rtl_cos_f32(float a); +extern float rtl_sin_f32(float a); + +// ram_pvvx_libc.c +extern int snprintf(char *str, size_t size, const char *fmt, ...); +extern int sprintf(char *str, const char *fmt, ...); +extern int printf(const char *fmt, ...); +extern int vprintf(const char * fmt, __VALIST param); +extern int vsnprintf(char *str, size_t size, const char *fmt, __VALIST param); +extern int vfprintf(FILE *fp, const char *fmt0, va_list ap); +extern void * memchr(const void * src_void , int c , size_t length); +extern int memcmp(const void *m1, const void *m2, size_t n); +extern void * memcpy(void *dst0, const void *src0, size_t len0); +extern void * memmove(void *dst_void, const void *src_void, size_t length); +extern void * memset(void *m, int c, size_t n); +extern char * strcat(char *s1, const char *s2); +extern char * strchr(const char *s1, int i); +extern int strcmp(const char *s1, const char *s2); +extern char * strcpy(char *dst0, const char *src0); +extern size_t strlen(const char *str); +extern char * strncat(char *s1, const char *s2, size_t n); +extern int strncmp(const char *s1, const char *s2, size_t n); +extern char * strncpy(char *dst0, const char *src0, size_t count); +extern char * strstr(const char *searchee, const char *lookfor); +extern char * strsep(char **source_ptr, const char *delim); +extern char * strtok(char *s, const char *delim); +extern int sscanf(const char *buf, const char *fmt, ...); +extern char toupper(char ch); +extern int _stricmp (const char *s1, const char *s2); +extern unsigned long long __aeabi_llsr(unsigned long long val, unsigned int shift); +#endif + +#endif // _INC_RTL_RR_LIBC_ \ No newline at end of file diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c new file mode 100644 index 0000000..4ff3a67 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c @@ -0,0 +1,1093 @@ + +#include "platform_autoconf.h" +#if 1 //def ENAC_FLOAT +#include +#include +#include "libc/rom/string/rom_libc_string.h" + +#define memchr __rtl_memchr_v1_00 +#define memcmp __rtl_memcmp_v1_00 +#define memcpy __rtl_memcpy_v1_00 +#define memmove __rtl_memmove_v1_00 +#define memset __rtl_memset_v1_00 +#define strcat __rtl_strcat_v1_00 +#define strchr __rtl_strchr_v1_00 +#define strcmp __rtl_strcmp_v1_00 +#define strcpy __rtl_strcpy_v1_00 +#define strlen __rtl_strlen_v1_00 +#define strncat __rtl_strncat_v1_00 +#define strncmp __rtl_strncmp_v1_00 +#define strncpy __rtl_strncpy_v1_00 +#define strstr __rtl_strstr_v1_00 +#define strsep __rtl_strsep_v1_00 +#define strtok __rtl_strtok_v1_00 + +static char toupper(char ch) { + return ((ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch); +}; + +#define NEWFP 1 +#define ENDIAN_LITTLE 1234 +#define ENDIAN_BIG 4321 +#define ENDIAN_PDP 3412 +#define ENDIAN ENDIAN_LITTLE + +/* $Id: strichr.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +//#include + +char * +strichr(char *p, int c) +{ + char *t; + + if (p != NULL) { + for(t = p; *t; t++); + for (; t >= p; t--) { + *(t + 1) = *t; + } + *p = c; + } + return (p); +} + +/* $Id: str_fmt.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +//#include + +#define FMT_RJUST 0 +#define FMT_LJUST 1 +#define FMT_RJUST0 2 +#define FMT_CENTER 3 + +/* + * Format string by inserting blanks. + */ + +void +str_fmt(char *p, int size, int fmt) +{ + int n, m, len; + + len = strlen (p); + switch (fmt) { + case FMT_RJUST: + for (n = size - len; n > 0; n--) + strichr (p, ' '); + break; + case FMT_LJUST: + for (m = size - len; m > 0; m--) + strcat (p, " "); + break; + case FMT_RJUST0: + for (n = size - len; n > 0; n--) + strichr (p, '0'); + break; + case FMT_CENTER: + m = (size - len) / 2; + n = size - (len + m); + for (; m > 0; m--) + strcat (p, " "); + for (; n > 0; n--) + strichr (p, ' '); + break; + } +} + +/* $Id: strtoupp.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +//#include +//#include +/* + * strtoupper() + */ +void +strtoupper(char *p) +{ + if(!p) + return; + for (; *p; p++) + *p = toupper (*p); +} + +/* $Id: atob.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +//#include +//#include +//#include + +//typedef int int32_t; +typedef unsigned int u_int32_t; +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef int32_t register_t; +typedef long long quad_t; +typedef unsigned long long u_quad_t; +typedef double rtype; + +#ifndef __P +#define __P(args) args +#endif + +static char * _getbase __P((char *, int *)); +static int _atob __P((unsigned long long *, char *p, int)); + +static char * +_getbase(char *p, int *basep) +{ + if (p[0] == '0') { + switch (p[1]) { + case 'x': + *basep = 16; + break; + case 't': case 'n': + *basep = 10; + break; + case 'o': + *basep = 8; + break; + default: + *basep = 10; + return (p); + } + return (p + 2); + } + *basep = 10; + return (p); +} + + +/* + * _atob(vp,p,base) + */ +static int +_atob (u_quad_t *vp, char *p, int base) +{ + u_quad_t value, v1, v2; + char *q, tmp[20]; + int digit; + + if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + base = 16; + p += 2; + } + + if (base == 16 && (q = strchr (p, '.')) != 0) { + if (q - p > sizeof(tmp) - 1) + return (0); + + strncpy (tmp, p, q - p); + tmp[q - p] = '\0'; + if (!_atob (&v1, tmp, 16)) + return (0); + + q++; + if (strchr (q, '.')) + return (0); + + if (!_atob (&v2, q, 16)) + return (0); + *vp = (v1 << 16) + v2; + return (1); + } + + value = *vp = 0; + for (; *p; p++) { + if (*p >= '0' && *p <= '9') + digit = *p - '0'; + else if (*p >= 'a' && *p <= 'f') + digit = *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + digit = *p - 'A' + 10; + else + return (0); + + if (digit >= base) + return (0); + value *= base; + value += digit; + } + *vp = value; + return (1); +} + +/* + * atob(vp,p,base) + * converts p to binary result in vp, rtn 1 on success + */ +int +atob(u_int32_t *vp, char *p, int base) +{ + u_quad_t v; + + if (base == 0) + p = _getbase (p, &base); + if (_atob (&v, p, base)) { + *vp = v; + return (1); + } + return (0); +} + + +/* + * llatob(vp,p,base) + * converts p to binary result in vp, rtn 1 on success + */ +int +llatob(u_quad_t *vp, char *p, int base) +{ + if (base == 0) + p = _getbase (p, &base); + return _atob(vp, p, base); +} + + +/* + * char *btoa(dst,value,base) + * converts value to ascii, result in dst + */ +char * +btoa(char *dst, u_int value, int base) +{ + char buf[34], digit; + int i, j, rem, neg; + + if (value == 0) { + dst[0] = '0'; + dst[1] = 0; + return (dst); + } + + neg = 0; + if (base == -10) { + base = 10; + if (value & (1L << 31)) { + value = (~value) + 1; + neg = 1; + } + } + + for (i = 0; value != 0; i++) { + rem = value % base; + value /= base; + if (rem >= 0 && rem <= 9) + digit = rem + '0'; + else if (rem >= 10 && rem <= 36) + digit = (rem - 10) + 'a'; + buf[i] = digit; + } + + buf[i] = 0; + if (neg) + strcat (buf, "-"); + + /* reverse the string */ + for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) + dst[i] = buf[j]; + dst[i] = 0; + return (dst); +} + +/* + * char *btoa(dst,value,base) + * converts value to ascii, result in dst + */ +char * +llbtoa(char *dst, u_quad_t value, int base) +{ + char buf[66], digit; + int i, j, rem, neg; + + if (value == 0) { + dst[0] = '0'; + dst[1] = 0; + return (dst); + } + + neg = 0; + if (base == -10) { + base = 10; + if (value & (1LL << 63)) { + value = (~value) + 1; + neg = 1; + } + } + + for (i = 0; value != 0; i++) { + rem = value % base; + value /= base; + if (rem >= 0 && rem <= 9) + digit = rem + '0'; + else if (rem >= 10 && rem <= 36) + digit = (rem - 10) + 'a'; + buf[i] = digit; + } + + buf[i] = 0; + if (neg) + strcat (buf, "-"); + + /* reverse the string */ + for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--) + dst[i] = buf[j]; + dst[i] = 0; + return (dst); +} + +/* + * gethex(vp,p,n) + * convert n hex digits from p to binary, result in vp, + * rtn 1 on success + */ +int +gethex(int32_t *vp, char *p, int n) +{ + u_long v; + int digit; + + for (v = 0; n > 0; n--) { + if (*p == 0) + return (0); + if (*p >= '0' && *p <= '9') + digit = *p - '0'; + else if (*p >= 'a' && *p <= 'f') + digit = *p - 'a' + 10; + else if (*p >= 'A' && *p <= 'F') + digit = *p - 'A' + 10; + else + return (0); + + v <<= 4; + v |= digit; + p++; + } + *vp = v; + return (1); +} + +/* $Id: vsprintf.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */ + +/* + * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Opsycon AB. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +//#include +//#include +//#include +//#include +//#include + +void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec); + +/* + * int vsprintf(d,s,ap) + */ +int +c_vsprintf (char *d, const char *s, va_list ap) +{ + const char *t; + char *p, *dst, tmp[40]; + unsigned int n; + int fmt, trunc, haddot, width, base, longlong; + double dbl; +#ifndef NEWFP + EP ex; +#endif + + dst = d; + for (; *s;) { + if (*s == '%') { + s++; + fmt = FMT_RJUST; + width = trunc = haddot = longlong = 0; + for (; *s; s++) { + if (strchr("bcdefgilopPrRsuxX%", *s)) + break; + else if (*s == '-') + fmt = FMT_LJUST; + else if (*s == '0') + fmt = FMT_RJUST0; + else if (*s == '~') + fmt = FMT_CENTER; + else if (*s == '*') { + if (haddot) + trunc = va_arg(ap, int); + else + width = va_arg(ap, int); + } else if (*s >= '1' && *s <= '9') { + for (t = s; isdigit(*s); s++); + strncpy(tmp, t, s - t); + tmp[s - t] = '\0'; + atob(&n, tmp, 10); + if (haddot) + trunc = n; + else + width = n; + s--; + } else if (*s == '.') + haddot = 1; + } + if (*s == '%') { + *d++ = '%'; + *d = 0; + } else if (*s == 's') { + p = va_arg(ap, char *); + + if (p) + strcpy(d, p); + else + strcpy(d, "(null)"); + } else if (*s == 'c') { + n = va_arg (ap, int); + *d = n; + d[1] = 0; + } else { + if (*s == 'l') { + if (*++s == 'l') { + longlong = 1; + ++s; + } + } + if (strchr("bdiopPrRxXu", *s)) { + if (*s == 'd' || *s == 'i') + base = -10; + else if (*s == 'u') + base = 10; + else if (*s == 'x' || *s == 'X') + base = 16; + else if(*s == 'p' || *s == 'P') { + base = 16; + if (*s == 'p') { + *d++ = '0'; + *d++ = 'x'; + } + fmt = FMT_RJUST0; + if (sizeof(long) > 4) { + width = 16; + longlong = 1; + } else { + width = 8; + } + } + else if(*s == 'r' || *s == 'R') { + base = 16; + if (*s == 'r') { + *d++ = '0'; + *d++ = 'x'; + } + fmt = FMT_RJUST0; + if (sizeof(register_t) > 4) { + width = 16; + longlong = 1; + } else { + width = 8; + } + } + else if (*s == 'o') + base = 8; + else if (*s == 'b') + base = 2; + if (longlong) + llbtoa(d, va_arg (ap, quad_t), + base); + else + btoa(d, va_arg (ap, int), base); + + if (*s == 'X') + strtoupper(d); + } + else if (strchr ("eEfgG", *s)) { + dbl = va_arg(ap, double); + dtoa(d, dbl, *s, width, trunc); + trunc = 0; + } + } + if (trunc) + d[trunc] = 0; + if (width) + str_fmt (d, width, fmt); + for (; *d; d++); + s++; + } else + *d++ = *s++; + } + *d = 0; + return (d - dst); +} + +/* + * Floating point output, cvt() onward lifted from BSD sources: + * + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#define MAX_FCONVERSION 512 /* largest possible real conversion */ +#define MAX_EXPT 5 /* largest possible exponent field */ +#define MAX_FRACT 39 /* largest possible fraction field */ + +#define TESTFLAG(x) 0 + + +typedef double rtype; + +extern double modf(double, double *); +#define to_char(n) ((n) + '0') +#define to_digit(c) ((c) - '0') +#define _isNan(arg) ((arg) != (arg)) + +static int cvt (rtype arg, int prec, char *signp, int fmtch, + char *startp, char *endp); +static char *c_round (double fract, int *exp, char *start, char *end, + char ch, char *signp); +static char *exponent(char *p, int exp, int fmtch); + + +/* + * _finite arg not Infinity or Nan + */ +static int _finite(rtype d) +{ +#if ENDIAN == ENDIAN_LITTLE + struct IEEEdp { + unsigned manl:32; + unsigned manh:20; + unsigned exp:11; + unsigned sign:1; + } *ip; +#else + struct IEEEdp { + unsigned sign:1; + unsigned exp:11; + unsigned manh:20; + unsigned manl:32; + } *ip; +#endif + + ip = (struct IEEEdp *)&d; + return (ip->exp != 0x7ff); +} + + +void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec) +{ + char buf[MAX_FCONVERSION+1], *cp; + char sign; + int size; + + if( !_finite(arg) ) { + if( _isNan(arg) ) + strcpy (dbuf, "NaN"); + else if( arg < 0) + strcpy (dbuf, "-Infinity"); + else + strcpy (dbuf, "Infinity"); + return; + } + + if (prec == 0) + prec = 6; + else if (prec > MAX_FRACT) + prec = MAX_FRACT; + + /* leave room for sign at start of buffer */ + cp = buf + 1; + + /* + * cvt may have to round up before the "start" of + * its buffer, i.e. ``intf("%.2f", (double)9.999);''; + * if the first character is still NUL, it did. + * softsign avoids negative 0 if _double < 0 but + * no significant digits will be shown. + */ + *cp = '\0'; + size = cvt (arg, prec, &sign, fmtch, cp, buf + sizeof(buf)); + if (*cp == '\0') + cp++; + + if (sign) + *--cp = sign, size++; + + cp[size] = 0; + memcpy (dbuf, cp, size + 1); +} + + +static int +cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp) +{ + register char *p, *t; + register double fract; + double integer, tmp; + int dotrim, expcnt, gformat; + + dotrim = expcnt = gformat = 0; + if (number < 0) { + number = -number; + *signp = '-'; + } else + *signp = 0; + + fract = modf(number, &integer); + + /* get an extra slot for rounding. */ + t = ++startp; + + /* + * get integer portion of number; put into the end of the buffer; the + * .01 is added for modf(356.0 / 10, &integer) returning .59999999... + */ + for (p = endp - 1; integer; ++expcnt) { + tmp = modf(integer / 10, &integer); + *p-- = to_char((int)((tmp + .01) * 10)); + } + switch (fmtch) { + case 'f': + /* reverse integer into beginning of buffer */ + if (expcnt) + for (; ++p < endp; *t++ = *p); + else + *t++ = '0'; + /* + * if precision required or alternate flag set, add in a + * decimal point. + */ + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = c_round(fract, (int *)NULL, startp, + t - 1, (char)0, signp); + } + for (; prec--; *t++ = '0'); + break; + case 'e': + case 'E': +eformat: if (expcnt) { + *t++ = *++p; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + /* if requires more precision and some integer left */ + for (; prec && ++p < endp; --prec) + *t++ = *p; + /* + * if done precision and more of the integer component, + * round using it; adjust fract so we don't re-round + * later. + */ + if (!prec && ++p < endp) { + fract = 0; + startp = c_round((double)0, &expcnt, startp, + t - 1, *p, signp); + } + /* adjust expcnt for digit in front of decimal */ + --expcnt; + } + /* until first fractional digit, decrement exponent */ + else if (fract) { + /* adjust expcnt for digit in front of decimal */ + for (expcnt = -1;; --expcnt) { + fract = modf(fract * 10, &tmp); + if (tmp) + break; + } + *t++ = to_char((int)tmp); + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + } + else { + *t++ = '0'; + if (prec || TESTFLAG(ALTERNATE_FORM)) + *t++ = '.'; + } + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while (--prec && fract); + if (fract) + startp = c_round(fract, &expcnt, startp, + t - 1, (char)0, signp); + } + /* if requires more precision */ + for (; prec--; *t++ = '0'); + + /* unless alternate flag, trim any g/G format trailing 0's */ + if (gformat && !TESTFLAG(ALTERNATE_FORM)) { + while (t > startp && *--t == '0'); + if (*t == '.') + --t; + ++t; + } + t = exponent(t, expcnt, fmtch); + break; + case 'g': + case 'G': + /* a precision of 0 is treated as a precision of 1. */ + if (!prec) + ++prec; + /* + * ``The style used depends on the value converted; style e + * will be used only if the exponent resulting from the + * conversion is less than -4 or greater than the precision.'' + * -- ANSI X3J11 + */ + if (expcnt > prec || (!expcnt && fract && fract < .0001)) { + /* + * g/G format counts "significant digits, not digits of + * precision; for the e/E format, this just causes an + * off-by-one problem, i.e. g/G considers the digit + * before the decimal point significant and e/E doesn't + * count it as precision. + */ + --prec; + fmtch -= 2; /* G->E, g->e */ + gformat = 1; + goto eformat; + } + /* + * reverse integer into beginning of buffer, + * note, decrement precision + */ + if (expcnt) + for (; ++p < endp; *t++ = *p, --prec); + else + *t++ = '0'; + /* + * if precision required or alternate flag set, add in a + * decimal point. If no digits yet, add in leading 0. + */ + if (prec || TESTFLAG(ALTERNATE_FORM)) { + dotrim = 1; + *t++ = '.'; + } + else + dotrim = 0; + /* if requires more precision and some fraction left */ + if (fract) { + if (prec) { + do { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } while(!tmp && !expcnt); + while (--prec && fract) { + fract = modf(fract * 10, &tmp); + *t++ = to_char((int)tmp); + } + } + if (fract) + startp = c_round(fract, (int *)NULL, startp, + t - 1, (char)0, signp); + } + /* alternate format, adds 0's for precision, else trim 0's */ + if (TESTFLAG(ALTERNATE_FORM)) + for (; prec--; *t++ = '0'); + else if (dotrim) { + while (t > startp && *--t == '0'); + if (*t != '.') + ++t; + } + } + return (t - startp); +} + + +static char * +c_round(double fract, int *exp, char *start, char *end, char ch, char *signp) +{ + double tmp; + + if (fract) + (void)modf(fract * 10, &tmp); + else + tmp = to_digit(ch); + if (tmp > 4) + for (;; --end) { + if (*end == '.') + --end; + if (++*end <= '9') + break; + *end = '0'; + if (end == start) { + if (exp) { /* e/E; increment exponent */ + *end = '1'; + ++*exp; + } + else { /* f; add extra digit */ + *--end = '1'; + --start; + } + break; + } + } + /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ + else if (*signp == '-') + for (;; --end) { + if (*end == '.') + --end; + if (*end != '0') + break; + if (end == start) + *signp = 0; + } + return (start); +} + +static char * +exponent(char *p, int exp, int fmtch) +{ + char *t; + char expbuf[MAX_FCONVERSION]; + + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAX_FCONVERSION; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++); + } + else { + *p++ = '0'; + *p++ = to_char(exp); + } + return (p); +} + +int c_sprintf(char *str, const char *fmt, ...) +{ + va_list arg; + va_start(arg, fmt); + int ret = c_vsprintf(str, fmt, arg); + va_end(arg); + return ret; +} + +extern char AvaWds[]; +extern int ram_libgloss_write(int file, const char *ptr, int len); + +int c_printf(const char *fmt, ...) +{ + va_list arg; + va_start(arg, fmt); + int ret = c_vsprintf((char *)&AvaWds, fmt, arg); + va_end(arg); + return ram_libgloss_write(0, (char *)&AvaWds, ret); +} + +#endif // ENAC_FLOAT + +int puts (const char *s) +{ + while(*s) { + HalSerialPutcRtl8195a(*s++); + } +} + +void vTaskDelete(void *); + +void abort(void) +{ + + puts("Abort!\n"); + vTaskDelete(0); + while(1); +} + + + diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libc.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libc.c new file mode 100644 index 0000000..79739ac --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libc.c @@ -0,0 +1,292 @@ +/* + * ram_libc.o + * pvvx 2016 + */ + +#include "rtl_bios_data.h" +#include "va_list.h" + +#define CHECK_LIBC_INIT 0 + +//------------------------------------------------------------------------- +// Function declarations +#if 0 +void rtl_libc_init(void); +int rtl_snprintf(char *str, size_t size, const char *fmt, ...); +int rtl_sprintf(char *str, const char *fmt, ...); +int rtl_printf(const char *fmt, ...); +int rtl_vprintf(const char *fmt, void *param); +int rtl_vsnprintf(char *str, size_t size, const char *fmt, void *param); +int rtl_vfprintf(FILE *fp, const char *fmt0, va_list ap); +void * rtl_memchr(const void * src_void , int c , size_t length); +int rtl_memcmp(const void *m1, const void *m2, size_t n); +void * rtl_memcpy(void *dst0, const void *src0, size_t len0); +void * rtl_memmove(void *dst_void, const void *src_void, size_t length); +void * rtl_memset(void *m, int c, size_t n); +char * rtl_strcat(char *s1, const char *s2); +char * rtl_strchr(const char *s1, int i); +int rtl_strcmp(const char *s1, const char *s2); +char * rtl_strcpy(char *dst0, const char *src0); +size_t rtl_strlen(const char *str); +char * rtl_strncat(char *s1, const char *s2, size_t n); +int rtl_strncmp(const char *s1, const char *s2, size_t n); +char * rtl_strncpy(char *dst0, const char *src0, size_t count); +char * rtl_strstr(const char *searchee, const char *lookfor); +char * rtl_strsep(char **source_ptr, const char *delim); +char * rtl_strtok(char *s, const char *delim); +#endif +// Extern Calls: +// extern int init_rom_libgloss_ram_map(_DWORD) +// extern int _rom_mallocr_init_v1_00(void) +// extern int __rtl_vfprintf_r_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_fflush_r_v1_00(_DWORD, _DWORD) +// extern int __rtl_memchr_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memcmp_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memcpy_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memmove_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memset_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strcat_v1_00(_DWORD, _DWORD) +// extern int __rtl_strchr_v1_00(_DWORD, _DWORD) +// extern int __rtl_strcmp_v1_00(_DWORD, _DWORD) +// extern int __rtl_strcpy_v1_00(_DWORD, _DWORD) +// extern int __rtl_strlen_v1_00(_DWORD) +// extern int __rtl_strncat_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strncmp_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strncpy_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strstr_v1_00(_DWORD, _DWORD) +// extern int __rtl_strsep_v1_00(_DWORD, _DWORD) +// extern int __rtl_strtok_v1_00(_DWORD, _DWORD) + +//------------------------------------------------------------------------- +// Data declarations + +extern struct _reent * _rtl_impure_ptr; + +char libc_has_init; +char print_off; +// extern rtl_impure_ptr +// extern impure_ptr + +//------------------------------------------------------------------------- +// Function + +//----- rtl_libc_init() +void rtl_libc_init(void) { + __rom_mallocr_init_v1_00(); + init_rom_libgloss_ram_map(); + libc_has_init = 1; +} + +//----- rtl_snprintf() +int rtl_snprintf(char *str, size_t size, const char *fmt, ...) { + va_list args; + va_start (args, fmt); + int result; + int w; + FILE f; +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if (size >= 0) { + f._flags = 520; + if (size) + w = size - 1; + else + w = 0; + f._w = w; /* write space left for putc() */ + f._bf._size = w; + f._file = -1; /* fileno, if Unix descriptor, else -1 */ + f._p = str; /* current position in (some) buffer */ + f._bf._base = str; + result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, args); + if (result + 1 < 0) + _rtl_impure_ptr->_errno = 139; + if (size) + *f._p = 0; + } else { + _rtl_impure_ptr->_errno = 139; + result = -1; + } + return result; +} + +//----- rtl_sprintf() +int rtl_sprintf(char *str, const char *fmt, ...) { + FILE f; +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + f._flags = 520; + f._w = 0x7FFFFFFF; + f._bf._size = 0x7FFFFFFF; + f._file = -1; + f._p = str; + f._bf._base = str; + va_list args; + va_start (args, fmt); + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, args); + *f._p = 0; +// va_end (args); + return result; +} + +//----- rtl_printf() +int rtl_printf(const char *fmt, ...) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if(!print_off) { + va_list args; + va_start (args, fmt); + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, + _rtl_impure_ptr->_stdout, fmt, args); + __rtl_fflush_r_v1_00(_rtl_impure_ptr, _rtl_impure_ptr->_stdout); + // va_end (args); + return result; + } + else return 0; +} + +//----- rtl_vprintf() +int rtl_vprintf(const char *fmt, va_list param) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, + _rtl_impure_ptr->_stdout, fmt, param); + __rtl_fflush_r_v1_00(_rtl_impure_ptr, _rtl_impure_ptr->_stdout); + return result; +} + +//----- rtl_vsnprintf() +int rtl_vsnprintf(char *str, size_t size, const char *fmt, va_list param) { + int result; + int w; + int v11; + FILE f; +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if (size >= 0) { + if (size) + w = size - 1; + else + w = 0; + f._flags = 520; + f._p = str; + f._bf._base = str; + f._w = w; + f._bf._size = w; + f._file = -1; + result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, param); + if (result + 1 < 0) + _rtl_impure_ptr->_errno = 139; + if (size) + *f._p = 0; + } else { + _rtl_impure_ptr->_errno = 139; + result = -1; + } + return result; +} + +//----- rtl_vfprintf() +int rtl_vfprintf(FILE *fp, const char *fmt0, va_list ap) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + return __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, fp, fmt0, ap); +} + +//----- rtl_memchr() +void * rtl_memchr(const void * src_void , int c , size_t length) { + return __rtl_memchr_v1_00(src_void, c, length); +} + +//----- rtl_memcmp() +int rtl_memcmp(const void *m1, const void *m2, size_t n) { + return __rtl_memcmp_v1_00(m1, m2, n); +} + +//----- rtl_memcpy() +void * rtl_memcpy(void *dst0, const void *src0, size_t len0) { + return __rtl_memcpy_v1_00(dst0, src0, len0); +} + +//----- rtl_memmove() +void * rtl_memmove(void *dst_void, const void *src_void, size_t length) { + return __rtl_memmove_v1_00(dst_void, src_void, length); +} + +//----- rtl_memset() +void * rtl_memset(void *m, int c, size_t n) { + return __rtl_memset_v1_00(m, c, n); +} + +//----- rtl_strcat() +char * rtl_strcat(char *s1, const char *s2) { + return (char *) __rtl_strcat_v1_00(s1, s2); +} + +//----- rtl_strchr() +char * rtl_strchr(const char *s1, int i) { + return (char *) __rtl_strchr_v1_00(s1, i); +} + +//----- rtl_strcmp() +int rtl_strcmp(const char *s1, const char *s2) { + return __rtl_strcmp_v1_00(s1, s2); +} + +//----- rtl_strcpy() +char * rtl_strcpy(char *dst0, const char *src0) { + return (char *) __rtl_strcpy_v1_00(dst0, src0); +} + +//----- rtl_strlen() +size_t rtl_strlen(const char *str) { + return __rtl_strlen_v1_00(str); +} + +//----- rtl_strncat() +char * rtl_strncat(char *s1, const char *s2, size_t n) { + return (char *) __rtl_strncat_v1_00(s1, s2, n); +} + +//----- rtl_strncmp() +int rtl_strncmp(const char *s1, const char *s2, size_t n) { + return __rtl_strncmp_v1_00(s1, s2, n); +} + +//----- rtl_strncpy() +char * rtl_strncpy(char *dst0, const char *src0, size_t count) { + return (char *) __rtl_strncpy_v1_00(dst0, src0, count); +} + +//----- rtl_strstr() +char * rtl_strstr(const char *searchee, const char *lookfor) { + return (char *) __rtl_strstr_v1_00(searchee, lookfor); +} + +//----- rtl_strsep() +char * rtl_strsep(char **source_ptr, const char *delim) { + return (char *) __rtl_strsep_v1_00(source_ptr, delim); +} + +//----- rtl_strtok() +char * rtl_strtok(char *s, const char *delim) { + return (char *) __rtl_strtok_v1_00(s, delim); +} + diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libgloss_retarget.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libgloss_retarget.c new file mode 100644 index 0000000..afe713a --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libgloss_retarget.c @@ -0,0 +1,127 @@ +/* + * ram_libgloss_retarget.o + * pvvx 2016 + */ + +#include "rtl_bios_data.h" + +//------------------------------------------------------------------------- +// Function declarations + +int ram_libgloss_close(int fildes); +int ram_libgloss_fstat(int fildes, struct stat *st); +int ram_libgloss_isatty(int file); +int ram_libgloss_lseek(int file, int ptr, int dir); +int ram_libgloss_read(int file, char *ptr, int len); +char *ram_libgloss_sbrk(int incr); +int ram_libgloss_write(int file, const char *ptr, int len); +int ram_libgloss_open(char *file, int flags, int mode); +void init_rom_libgloss_ram_map(void); +// Extern Calls: +//extern int HalSerialPutcRtl8195a(); +//extern int rtl_strcmp(); +extern char end; + +//------------------------------------------------------------------------- +// Data declarations +static char *rheap_end; +// extern __rtl_errno; +// extern end; +// extern rom_libgloss_ram_map; + +//----- ram_libgloss_close() +int ram_libgloss_close(int fildes) { + __rtl_errno = 88; + return -1; +} + +//----- ram_libgloss_fstat() +int ram_libgloss_fstat(int fildes, struct stat *st) { + int result; + + if ((unsigned int) fildes > 2) { + __rtl_errno = 9; + result = -1; + } else { + st->st_mode = 0x2000; + result = 0; + } + return result; +} + +//----- ram_libgloss_isatty() +int ram_libgloss_isatty(int file) { + int result; + + if (file <= 2) + result = 1; + else + result = -1; + return result; +} + +//----- ram_libgloss_lseek() +int ram_libgloss_lseek(int file, int ptr, int dir) { + __rtl_errno = 88; + return -1; +} + +//----- ram_libgloss_read() +int ram_libgloss_read(int file, char *ptr, int len) { + __rtl_errno = 88; + return -1; +} + +//----- ram_libgloss_sbrk() +char *ram_libgloss_sbrk(int incr) { + char *prev_heap_end; + + if (!rheap_end) + rheap_end = (char *) &end; + prev_heap_end = rheap_end; + rheap_end += incr; +#if CONFIG_DEBUG_LOG > 4 + DBG_8195A("ROM_heap = %p[%d], end = %p\n", prev_heap_end, incr, rheap_end); +#endif + return prev_heap_end; +} + +//----- ram_libgloss_write() +int ram_libgloss_write(int file, const char *ptr, int len) { + int i; + for (i = 0; i < len; ++i) + HalSerialPutcRtl8195a(ptr[i]); + return len; +} + +//----- ram_libgloss_open() +int ram_libgloss_open(char *file, int flags, int mode) { +// file->_p + int result = rtl_strcmp(file, "/stdin"); + + if (result) { + if (rtl_strcmp(file, "/stdout")) { + if (rtl_strcmp(file, "/stderr")) + result = -1; + else + result = 2; + } else { + result = 1; + } + } else + result = 0; + return result; +} + +//----- init_rom_libgloss_ram_map() +void init_rom_libgloss_ram_map(void) { + rom_libgloss_ram_map.libgloss_close = ram_libgloss_close; + rom_libgloss_ram_map.libgloss_fstat = ram_libgloss_fstat; + rom_libgloss_ram_map.libgloss_isatty = ram_libgloss_isatty; + rom_libgloss_ram_map.libgloss_lseek = ram_libgloss_lseek; + rom_libgloss_ram_map.libgloss_open = ram_libgloss_open; + rom_libgloss_ram_map.libgloss_read = ram_libgloss_read; + rom_libgloss_ram_map.libgloss_write = ram_libgloss_write; + rom_libgloss_ram_map.libgloss_sbrk = ram_libgloss_sbrk; +} + diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_pvvx_libc.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_pvvx_libc.c new file mode 100644 index 0000000..3903e15 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_pvvx_libc.c @@ -0,0 +1,565 @@ +/* + * RTL871x1Ax: RAM libc + * Created on: 22/02/2017 + * Author: pvvx + */ + +#include "rtl_bios_data.h" +#include "va_list.h" + +#define CHECK_LIBC_INIT 0 +//------------------------------------------------------------------------- +// Function declarations + +//void libc_init(); +#if 0 +int snprintf(char *str, size_t size, const char *fmt, ...); +int sprintf(char *str, const char *fmt, ...); +int printf(const char *fmt, ...); +int vprintf(const char * fmt, __VALIST param); +int vsnprintf(char *str, size_t size, const char *fmt, __VALIST param); +int vfprintf(FILE *fp, const char *fmt0, va_list ap); +void * memchr(const void * src_void , int c , size_t length); +int memcmp(const void *m1, const void *m2, size_t n); +void * memcpy(void *dst0, const void *src0, size_t len0); +void * memmove(void *dst_void, const void *src_void, size_t length); +void * memset(void *m, int c, size_t n); +char * strcat(char *s1, const char *s2); +char * strchr(const char *s1, int i); +int strcmp(const char *s1, const char *s2); +char * strcpy(char *dst0, const char *src0); +size_t strlen(const char *str); +char * strncat(char *s1, const char *s2, size_t n); +int strncmp(const char *s1, const char *s2, size_t n); +char * strncpy(char *dst0, const char *src0, size_t count); +char * strstr(const char *searchee, const char *lookfor); +char * strsep(char **source_ptr, const char *delim); +char * strtok(char *s, const char *delim); +int sscanf(const char *buf, const char *fmt, ...); +char toupper(char ch); +int _stricmp (const char *s1, const char *s2); +unsigned long long __aeabi_llsr(unsigned long long val, unsigned int shift); +#endif +// Extern Calls: +// extern int init_rom_libgloss_ram_map(_DWORD) +// extern int _rom_mallocr_init_v1_00(void) +// extern int __rtl_vfprintf_r_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_fflush_r_v1_00(_DWORD, _DWORD) +// extern int __rtl_memchr_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memcmp_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memcpy_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memmove_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_memset_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strcat_v1_00(_DWORD, _DWORD) +// extern int __rtl_strchr_v1_00(_DWORD, _DWORD) +// extern int __rtl_strcmp_v1_00(_DWORD, _DWORD) +// extern int __rtl_strcpy_v1_00(_DWORD, _DWORD) +// extern int __rtl_strlen_v1_00(_DWORD) +// extern int __rtl_strncat_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strncmp_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strncpy_v1_00(_DWORD, _DWORD, _DWORD) +// extern int __rtl_strstr_v1_00(_DWORD, _DWORD) +// extern int __rtl_strsep_v1_00(_DWORD, _DWORD) +// extern int __rtl_strtok_v1_00(_DWORD, _DWORD) + +//------------------------------------------------------------------------- +// Data declarations + +extern struct _reent * _rtl_impure_ptr; + +#if CHECK_LIBC_INIT +extern char libc_has_init; +#endif +extern char print_off; + +#undef snprintf +//------------------------------------------------------------------------- +// Function +//----- snprintf() +int snprintf(char *str, size_t size, const char *fmt, ...) { + va_list args; + va_start (args, fmt); + int result; + int w; + FILE f; +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if (size >= 0) { + f._flags = 520; + if (size) + w = size - 1; + else + w = 0; + f._w = w; /* write space left for putc() */ + f._bf._size = w; + f._file = -1; /* fileno, if Unix descriptor, else -1 */ + f._p = str; /* current position in (some) buffer */ + f._bf._base = str; + result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, args); + if (result + 1 < 0) + _rtl_impure_ptr->_errno = 139; + if (size) + *f._p = 0; + } else { + _rtl_impure_ptr->_errno = 139; + result = -1; + } + return result; +} + + +#ifndef ENAC_FLOAT +#undef sprintf +//----- sprintf() +int sprintf(char *str, const char *fmt, ...) { + FILE f; + +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + f._flags = 520; + f._w = 0x7FFFFFFF; + f._bf._size = 0x7FFFFFFF; + f._file = -1; + f._p = str; + f._bf._base = str; + va_list args; + va_start (args, fmt); + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, args); + *f._p = 0; +// va_end (args); + return result; +} + +#undef printf +//----- printf() +int printf(const char *fmt, ...) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if(!print_off) { + + va_list args; + va_start (args, fmt); + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, + _rtl_impure_ptr->_stdout, fmt, args); + __rtl_fflush_r_v1_00(_rtl_impure_ptr, _rtl_impure_ptr->_stdout); + // va_end (args); + return result; + } + else return 0; +} + +#undef vprintf +//----- vprintf() +int vprintf(const char * fmt, __VALIST param) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + int result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, + _rtl_impure_ptr->_stdout, fmt, param); + __rtl_fflush_r_v1_00(_rtl_impure_ptr, _rtl_impure_ptr->_stdout); + return result; +} +#endif // ENAC_FLOAT + +#undef vsnprintf +//----- vsnprintf() +int vsnprintf(char *str, size_t size, const char *fmt, __VALIST param) { + int result; + int w; + int v11; + FILE f; +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + if (size >= 0) { + if (size) + w = size - 1; + else + w = 0; + f._flags = 520; + f._p = str; + f._bf._base = str; + f._w = w; + f._bf._size = w; + f._file = -1; + result = __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, &f, fmt, param); + if (result + 1 < 0) + _rtl_impure_ptr->_errno = 139; + if (size) + *f._p = 0; + } else { + _rtl_impure_ptr->_errno = 139; + result = -1; + } + return result; +} + +#undef vfprintf +//----- vfprintf() +int vfprintf(FILE *fp, const char *fmt0, va_list ap) { +#if CHECK_LIBC_INIT + if (!libc_has_init) { + rtl_libc_init(); + } +#endif + return __rtl_vfprintf_r_v1_00(_rtl_impure_ptr, fp, fmt0, ap); +} + +#undef memchr +//----- memchr() +void * memchr(const void * src_void , int c , size_t length) { + return __rtl_memchr_v1_00(src_void, c, length); +} + +#undef memcmp +//----- memcmp() +int memcmp(const void *m1, const void *m2, size_t n) { + return __rtl_memcmp_v1_00(m1, m2, n); +} + +#undef memcpy +//----- memcpy() +void * memcpy(void *dst0, const void *src0, size_t len0) { + return __rtl_memcpy_v1_00(dst0, src0, len0); +} + +#undef memmove +//----- memmove() +void * memmove(void *dst_void, const void *src_void, size_t length) { + return __rtl_memmove_v1_00(dst_void, src_void, length); +} + +#undef memset +//----- memset() +void * memset(void *m, int c, size_t n) { + return __rtl_memset_v1_00(m, c, n); +} + +#undef strcat +//----- strcat() +char * strcat(char *s1, const char *s2) { + return (char *) __rtl_strcat_v1_00(s1, s2); +} +#undef strchr +//----- strchr() +char * strchr(const char *s1, int i) { + return (char *) __rtl_strchr_v1_00(s1, i); +} + +#undef strcmp +//----- strcmp() +int strcmp(const char *s1, const char *s2) { + return __rtl_strcmp_v1_00(s1, s2); +} + +#undef strcpy +//----- strcpy() +char * strcpy(char *dst0, const char *src0) { + return (char *) __rtl_strcpy_v1_00(dst0, src0); +} + +#undef strlen +//----- strlen() +size_t strlen(const char *str) { + return __rtl_strlen_v1_00(str); +} + +#undef strncat +//----- strncat() +char * strncat(char *s1, const char *s2, size_t n) { + return (char *) __rtl_strncat_v1_00(s1, s2, n); +} + +#undef strncmp +//----- strncmp() +int strncmp(const char *s1, const char *s2, size_t n) { + return __rtl_strncmp_v1_00(s1, s2, n); +} + +#undef strncpy +//----- strncpy() +char * strncpy(char *dst0, const char *src0, size_t count) { + return (char *) __rtl_strncpy_v1_00(dst0, src0, count); +} + +#undef strstr +//----- strstr() +char * strstr(const char *searchee, const char *lookfor) { + return (char *) __rtl_strstr_v1_00(searchee, lookfor); +} + +#undef strsep +//----- strsep() +char * strsep(char **source_ptr, const char *delim) { + return (char *) __rtl_strsep_v1_00(source_ptr, delim); +} + +#undef strtok +//----- strtok() +char * strtok(char *s, const char *delim) { + return (char *) __rtl_strtok_v1_00(s, delim); +} +#undef sscanf +int sscanf(const char *buf, const char *fmt, ...) { + va_list args; + int i; + + va_start(args, fmt); + i = _vsscanf(buf, fmt, args); + va_end(args); + + return i; +} + +char toupper(char ch) { + return ((ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch); +}; + +int _stricmp (const char *s1, const char *s2) +{ + while (*s2 != 0 && toupper(*s1) == toupper(*s2)) + s1++, s2++; + return (int) (toupper(*s1) - toupper(*s2)); +} + +unsigned long long __aeabi_llsr(unsigned long long val, unsigned int shift) +{ + u32 lo = ((u32)val >> shift) | ((u32)(val >> 32) << (32 - shift)); + u32 hi = (u32)val >> shift; + + return ((unsigned long long)hi << 32) | lo; +} + +/* +#undef __VFP_FP__ + +#if defined(__VFP_FP__) +typedef long __jmp_buf[10 + 8 + 1]; // d8-d15 fpu + fpscr +#else +typedef long __jmp_buf[10]; +#endif + +int setjmp(__jmp_buf buf) __attribute__ ((noinline)); +int setjmp(__jmp_buf buf) +{ + register void * r0 __asm__("r0") = buf; + __asm__( + "mov %%ip, %%sp\n" + "stmia %[store]!, {%%r4-%%r9, %%sl, %%fp, %%ip, %%lr}\n" +#if defined(__VFP_FP__) + "vstmia %[store]!, {%%d8-%%d15}\n" + "vmrs %%r1, fpscr\n" + "str %%r1, [%[store]], #4\n" +#endif + "mov.w %r0, #0\n" + : : [store] "r" (r0) :); +} + +void longjmp(__jmp_buf buf, long value) __attribute__((noreturn)); +void longjmp(__jmp_buf buf, long value) +{ + __asm__( + "ldmia %[load]!, {%%r4-%%r9, %%sl, %%fp, %%ip, %%lr}\n" +#if defined(__VFP_FP__) + "vldmia %[load]!, {%%d8-%%d15}\n" + "ldr %%r0, [%[load]], #4\n" + "vmsr fpscr, %%r0\n" +#endif + "mov %%sp, %%ip\n" + "movs %%r0, %%r1\n" + "it eq\n" + "moveq %%r0, #1\n" + "bx lr\n" + : : [load] "r" (buf), [value] "r" (value):); + __builtin_unreachable(); +} +*/ + +extern __attribute__ ((long_call)) unsigned int Rand(void); + +int rand(void) +{ + return Rand(); +} + + + +//----- rtl_dtoi() +int __aeabi_dtoi(double d) +{ + return __rtl_dtoi_v1_00(d); +} + +//----- __aeabi_dtoui() +int __aeabi_dtoui(double d) +{ + return __rtl_dtoui_v1_00(d); +} + +//----- __aeabi_i2f() +float __aeabi_i2f(int val) +{ + return __rtl_itof_v1_00(val); +} + +//----- __aeabi_i2d() +int __aeabi_i2d(int val) +{ + return __rtl_itod_v1_00(val); +} + +//----- __aeabi_ui2f() +float __aeabi_ui2f(unsigned int val) +{ + return __rtl_uitof_v1_00(val); +} + +//----- __aeabi_ui2d() +int __aeabi_ui2d(unsigned int val) +{ + return __rtl_uitod_v1_00(val); +} + +//----- __aeabi_itoa() +char * __aeabi_itoa(int value, char *string, int radix) +{ + return (char *)__rtl_ltoa_v1_00(value, string, radix); +} + +//----- __aeabi_ltoa() +char * __aeabi_ltoa(int value, char *string, int radix) +{ + return (char *)__rtl_ltoa_v1_00(value, string, radix); +} + +//----- __aeabi_utoa() +char * __aeabi_utoa(unsigned int value, char *string, int radix) +{ + return (char *)__rtl_ultoa_v1_00(value, string, radix); +} + +//----- __aeabi_ultoa() +char * __aeabi_ultoa(unsigned int value, char *string, int radix) +{ + return (char *)__rtl_ultoa_v1_00(value, string, radix); +} + +//----- __aeabi_ftol() +int __aeabi_ftol(float f) +{ + return __rtl_ftol_v1_00(f); +} + +//----- __aeabi_ftod() +int __aeabi_ftod(float f) +{ + return __rtl_ftod_v1_00(f); +} + +//----- __aeabi_dtof() +float __aeabi_dtof(double d) +{ + return __rtl_dtof_v1_00(d); +} + +//----- __aeabi_fadd() +float __aeabi_fadd(float a, float b) +{ + return __rtl_fadd_v1_00(a, b); +} + +//----- __aeabi_fsub() +float __aeabi_fsub(float a, float b) +{ + return __rtl_fsub_v1_00(a, b); +} + +//----- __aeabi_fmul() +float __aeabi_fmul(float a, float b) +{ + return __rtl_fmul_v1_00(a, b); +} + +//----- __aeabi_fdiv() +float __aeabi_fdiv(float a, float b) +{ + return __rtl_fdiv_v1_00(a, b); +} + +//----- __aeabi_dadd() +int __aeabi_dadd(double a, double b) +{ + return __rtl_dadd_v1_00(a, b); +} + +//----- __aeabi_dsub() +int __aeabi_dsub(double a, double b) +{ + return __rtl_dsub_v1_00(a, b); +} + +//----- __aeabi_dmul() +int __aeabi_dmul(double a, double b) +{ + return __rtl_dmul_v1_00(a, b); +} + +//----- __aeabi_ddiv() +int __aeabi_ddiv(double a, double b) +{ + return __rtl_ddiv_v1_00(a, b); +} + +//----- __aeabi_dcmpeq() +int __aeabi_dcmpeq(double a, double b) +{ + return __rtl_dcmpeq_v1_00(a, b); +} + +//----- __aeabi_dcmplt() +int __aeabi_dcmplt(double a, double b) +{ + return __rtl_dcmplt_v1_00(a, b); +} + +//----- __aeabi_dcmple() +int __aeabi_dcmple(double a, double b) +{ + return __rtl_dcmple_v1_00(a, b); +} + +//----- __aeabi_dcmpgt() +int __aeabi_dcmpgt(double a, double b) +{ + return __rtl_dcmpgt_v1_00(a, b); +} + +//----- __aeabi_fcmplt() +int __aeabi_fcmplt(float a, float b) +{ + return __rtl_fcmplt_v1_00(a, b); +} + +//----- __aeabi_fcmpgt() +int __aeabi_fcmpgt(float a, float b) +{ + return __rtl_fcmpgt_v1_00(a, b); +} + +extern _LONG_CALL_ void __aeabi_memset(void *dest, size_t n, int c); // { memset(dest, c, n); } + +void __aeabi_memclr(void *dest, size_t n) { __aeabi_memset(dest, n, 0); } +void __aeabi_memclr4(void *dest, size_t n) { __aeabi_memset(dest, n, 0); } diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_eabi_cast_ram.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_eabi_cast_ram.c new file mode 100644 index 0000000..8f7589a --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_eabi_cast_ram.c @@ -0,0 +1,228 @@ +/* + * rtl_eabi_cast_ram.o + * pvvx 2016 + */ + +#include "basic_types.h" + +//------------------------------------------------------------------------- +// Function declarations + +int rtl_dtoi(double d); +int rtl_dtoui(double d); +float rtl_i2f(int val); +int rtl_i2d(int val); +float rtl_ui2f(unsigned int val); +int rtl_ui2d(unsigned int val); +char *rtl_itoa(int value, char *string, int radix); +char *rtl_ltoa(int value, char *string, int radix); +char *rtl_utoa(unsigned int value, char *string, int radix); +char *rtl_ultoa(unsigned int value, char *string, int radix); +int rtl_ftol(float f); +int rtl_ftod(float f); +float rtl_dtof(double d); +float rtl_fadd(float a, float b); +float rtl_fsub(float a, float b); +float rtl_fmul(float a, float b); +float rtl_fdiv(float a, float b); +int rtl_dadd(double a, double b); +int rtl_dsub(double a, double b); +int rtl_dmul(double a, double b); +int rtl_ddiv(double a, double b); +int rtl_dcmpeq(double a, double b); +int rtl_dcmplt(double a, double b); +int rtl_dcmple(double a, double b); +int rtl_dcmpgt(double a, double b); +int rtl_fcmplt(float a, float b); +int rtl_fcmpgt(float a, float b); + +// Extern Calls: + +// int __rtl_dtoi_v1_00(); +// int __rtl_dtoui_v1_00(); +// int __rtl_itof_v1_00(); +// int __rtl_itod_v1_00(); +// int __rtl_uitof_v1_00(); +// int __rtl_uitod_v1_00(); +// int __rtl_ltoa_v1_00(); +// int __rtl_ultoa_v1_00(); +// int __rtl_ftol_v1_00(); +// int __rtl_ftod_v1_00(); +// int __rtl_dtof_v1_00(); +// int __rtl_fadd_v1_00(); +// int __rtl_fsub_v1_00(); +// int __rtl_fmul_v1_00(); +// int __rtl_fdiv_v1_00(); +// int __rtl_dadd_v1_00(); +// int __rtl_dsub_v1_00(); +// int __rtl_dmul_v1_00(); +// int __rtl_ddiv_v1_00(); +// int __rtl_dcmpeq_v1_00(); +// int __rtl_dcmplt_v1_00(); +// int __rtl_dcmple_v1_00(); +// int __rtl_dcmpgt_v1_00(); +// int __rtl_fcmplt_v1_00(); +// int __rtl_fcmpgt_v1_00(); + + +//----- rtl_dtoi() +int rtl_dtoi(double d) +{ + return __rtl_dtoi_v1_00(d); +} + +//----- rtl_dtoui() +int rtl_dtoui(double d) +{ + return __rtl_dtoui_v1_00(d); +} + +//----- rtl_i2f() +float rtl_i2f(int val) +{ + return __rtl_itof_v1_00(val); +} + +//----- rtl_i2d() +int rtl_i2d(int val) +{ + return __rtl_itod_v1_00(val); +} + +//----- rtl_ui2f() +float rtl_ui2f(unsigned int val) +{ + return __rtl_uitof_v1_00(val); +} + +//----- rtl_ui2d() +int rtl_ui2d(unsigned int val) +{ + return __rtl_uitod_v1_00(val); +} + +//----- rtl_itoa() +char *rtl_itoa(int value, char *string, int radix) +{ + return (char *)__rtl_ltoa_v1_00(value, string, radix); +} + +//----- rtl_ltoa() +char *rtl_ltoa(int value, char *string, int radix) +{ + return (char *)__rtl_ltoa_v1_00(value, string, radix); +} + +//----- rtl_utoa() +char *rtl_utoa(unsigned int value, char *string, int radix) +{ + return (char *)__rtl_ultoa_v1_00(value, string, radix); +} + +//----- rtl_ultoa() +char *rtl_ultoa(unsigned int value, char *string, int radix) +{ + return (char *)__rtl_ultoa_v1_00(value, string, radix); +} + +//----- rtl_ftol() +int rtl_ftol(float f) +{ + return __rtl_ftol_v1_00(f); +} + +//----- rtl_ftod() +int rtl_ftod(float f) +{ + return __rtl_ftod_v1_00(f); +} + +//----- rtl_dtof() +float rtl_dtof(double d) +{ + return __rtl_dtof_v1_00(d); +} + +//----- rtl_fadd() +float rtl_fadd(float a, float b) +{ + return __rtl_fadd_v1_00(a, b); +} + +//----- rtl_fsub() +float rtl_fsub(float a, float b) +{ + return __rtl_fsub_v1_00(a, b); +} + +//----- rtl_fmul() +float rtl_fmul(float a, float b) +{ + return __rtl_fmul_v1_00(a, b); +} + +//----- rtl_fdiv() +float rtl_fdiv(float a, float b) +{ + return __rtl_fdiv_v1_00(a, b); +} + +//----- rtl_dadd() +int rtl_dadd(double a, double b) +{ + return __rtl_dadd_v1_00(a, b); +} + +//----- rtl_dsub() +int rtl_dsub(double a, double b) +{ + return __rtl_dsub_v1_00(a, b); +} + +//----- rtl_dmul() +int rtl_dmul(double a, double b) +{ + return __rtl_dmul_v1_00(a, b); +} + +//----- rtl_ddiv() +int rtl_ddiv(double a, double b) +{ + return __rtl_ddiv_v1_00(a, b); +} + +//----- rtl_dcmpeq() +int rtl_dcmpeq(double a, double b) +{ + return __rtl_dcmpeq_v1_00(a, b); +} + +//----- rtl_dcmplt() +int rtl_dcmplt(double a, double b) +{ + return __rtl_dcmplt_v1_00(a, b); +} + +//----- rtl_dcmple() +int rtl_dcmple(double a, double b) +{ + return __rtl_dcmple_v1_00(a, b); +} + +//----- rtl_dcmpgt() +int rtl_dcmpgt(double a, double b) +{ + return __rtl_dcmpgt_v1_00(a, b); +} + +//----- rtl_fcmplt() +int rtl_fcmplt(float a, float b) +{ + return __rtl_fcmplt_v1_00(a, b); +} + +//----- rtl_fcmpgt() +int rtl_fcmpgt(float a, float b) +{ + return __rtl_fcmpgt_v1_00(a, b); +} diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_math_ram.c b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_math_ram.c new file mode 100644 index 0000000..7fa3703 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_math_ram.c @@ -0,0 +1,46 @@ +/* + * rtl_math_ram..o + * pvvx 2016 + */ + +#include "basic_types.h" + +//------------------------------------------------------------------------- +// Function declarations + +float rtl_fabsf(float a); +int rtl_fabs(double a); +float rtl_cos_f32(float a); +float rtl_sin_f32(float a); + +// Extern Calls: + +// int __rtl_fabsf_v1_00(); +// int __rtl_fabs_v1_00(); +// int __rtl_cos_f32_v1_00(); +// int __rtl_sin_f32_v1_00(); + + +//----- rtl_fabsf() +float rtl_fabsf(float a) +{ + return __rtl_fabsf_v1_00(a); +} + +//----- rtl_fabs() +int rtl_fabs(double a) +{ + return __rtl_fabs_v1_00(a); +} + +//----- rtl_cos_f32() +float rtl_cos_f32(float a) +{ + return __rtl_cos_f32_v1_00(a); +} + +//----- rtl_sin_f32() +float rtl_sin_f32(float a) +{ + return __rtl_sin_f32_v1_00(a); +} diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libc/rom/string/rom_libc_string.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libc/rom/string/rom_libc_string.h new file mode 100644 index 0000000..79855bf --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libc/rom/string/rom_libc_string.h @@ -0,0 +1,49 @@ +/* + * rom_libc_string.h + * + * Definitions for standard library - libc functions. + */ +#ifndef _ROM_LIBC_STRING_H_ +#define _ROM_LIBC_STRING_H_ + +#include + +#define __rtl_memchr __rtl_memchr_v1_00 +#define __rtl_memcmp __rtl_memcmp_v1_00 +#define __rtl_memcpy __rtl_memcpy_v1_00 +#define __rtl_memmove __rtl_memmove_v1_00 +#define __rtl_memset __rtl_memset_v1_00 +#define __rtl_strcat __rtl_strcat_v1_00 +#define __rtl_strchr __rtl_strchr_v1_00 +#define __rtl_strcmp __rtl_strcmp_v1_00 +#define __rtl_strcpy __rtl_strcpy_v1_00 +#define __rtl_strlen __rtl_strlen_v1_00 +#define __rtl_strncat __rtl_strncat_v1_00 +#define __rtl_strncmp __rtl_strncmp_v1_00 +#define __rtl_strncpy __rtl_strncpy_v1_00 +#define __rtl_strstr __rtl_strstr_v1_00 +#define __rtl_strsep __rtl_strsep_v1_00 +#define __rtl_strtok __rtl_strtok_v1_00 + +#define __rtl_critical_factorization __rtl_critical_factorization_v1_00 +#define __rtl_two_way_short_needle __rtl_two_way_short_needle_v1_00 +#define __rtl_two_way_long_needle __rtl_two_way_long_needle_v1_00 + +extern _LONG_CALL_ void * __rtl_memchr_v1_00(const void * src_void , int c , size_t length); +extern _LONG_CALL_ int __rtl_memcmp_v1_00(const void * m1 , const void * m2 , size_t n); +extern _LONG_CALL_ void * __rtl_memcpy_v1_00(void * __restrict dst0 , const void * __restrict src0 , size_t len0); +extern _LONG_CALL_ void * __rtl_memmove_v1_00( void * dst_void , const void * src_void , size_t length); +extern _LONG_CALL_ void * __rtl_memset_v1_00(void * m , int c , size_t n); +extern _LONG_CALL_ char * __rtl_strcat_v1_00(char *__restrict s1 , const char *__restrict s2); +extern _LONG_CALL_ char * __rtl_strchr_v1_00(const char *s1 , int i); +extern _LONG_CALL_ int __rtl_strcmp_v1_00(const char *s1 , const char *s2); +extern _LONG_CALL_ char* __rtl_strcpy_v1_00(char *dst0 , const char *src0); +extern _LONG_CALL_ size_t __rtl_strlen_v1_00(const char *str); +extern _LONG_CALL_ char * __rtl_strncat_v1_00(char *__restrict s1 , const char *__restrict s2 , size_t n); +extern _LONG_CALL_ int __rtl_strncmp_v1_00(const char *s1 , const char *s2 , size_t n); +extern _LONG_CALL_ char * __rtl_strncpy_v1_00(char *__restrict dst0 , const char *__restrict src0 , size_t count); +extern _LONG_CALL_ char * __rtl_strstr_v1_00(const char *searchee , const char *lookfor); +extern _LONG_CALL_ char * __rtl_strsep_v1_00(register char **source_ptr , register const char *delim); +extern _LONG_CALL_ char * __rtl_strtok_v1_00(register char *__restrict s , register const char *__restrict delim); + +#endif /* _ROM_LIBC_STRING_H_ */ diff --git a/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libgloss/rtl8195a/rom/rom_libgloss_retarget.h b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libgloss/rtl8195a/rom/rom_libgloss_retarget.h new file mode 100644 index 0000000..4c05a36 --- /dev/null +++ b/USDK/component/soc/realtek/8195a/misc/rtl_std_lib/libgloss/rtl8195a/rom/rom_libgloss_retarget.h @@ -0,0 +1,37 @@ +#ifndef ROM_LIBGLOSS_RETARGET_H +#define ROM_LIBGLOSS_RETARGET_H + +#include +#include + +#define __rtl_close __rtl_close_v1_00 +#define __rtl_fstat __rtl_fstat_v1_00 +#define __rtl_isatty __rtl_isatty_v1_00 +#define __rtl_lseek __rtl_lseek_v1_00 +#define __rtl_open __rtl_open_v1_00 +#define __rtl_read __rtl_read_v1_00 +#define __rtl_write __rtl_write_v1_00 +#define __rtl_sbrk __rtl_sbrk_v1_00 + +extern _LONG_CALL_ int __rtl_close_v1_00(int fildes); +extern _LONG_CALL_ int __rtl_fstat_v1_00(int fildes , struct stat *st); +extern _LONG_CALL_ int __rtl_isatty_v1_00(int file); +extern _LONG_CALL_ int __rtl_lseek_v1_00(int file , int ptr , int dir); +extern _LONG_CALL_ int __rtl_open_v1_00(char *file , int flags , int mode); +extern _LONG_CALL_ int __rtl_read_v1_00(int file , char *ptr , int len); +extern _LONG_CALL_ int __rtl_write_v1_00(int file , const char *ptr , int len); +extern _LONG_CALL_ void* __rtl_sbrk_v1_00(int incr); + + +struct _rom_libgloss_ram_map { + int (*libgloss_close)(int fildes); + int (*libgloss_fstat)(int fildes , struct stat *st); + int (*libgloss_isatty)(int file); + int (*libgloss_lseek)(int file , int ptr , int dir); + int (*libgloss_open)(char *file , int flags , int mode); + int (*libgloss_read)(int file , char *ptr , int len); + int (*libgloss_write)(int file , const char *ptr , int len); + void* (*libgloss_sbrk)(int incr); +}; + +#endif /* ROM_LIBGLOSS_RETARGET_H */ diff --git a/USDK/component/soc/realtek/common/bsp/basic_types.h b/USDK/component/soc/realtek/common/bsp/basic_types.h new file mode 100644 index 0000000..9ebad69 --- /dev/null +++ b/USDK/component/soc/realtek/common/bsp/basic_types.h @@ -0,0 +1,515 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ +#ifndef __BASIC_TYPES_H__ +#define __BASIC_TYPES_H__ + +//#define PLATFORM_FREERTOS +#include + +#define PLATFORM_LITTLE_ENDIAN 0 +#define PLATFORM_BIG_ENDIAN 1 + +#define SYSTEM_ENDIAN PLATFORM_LITTLE_ENDIAN + +#define SUCCESS 0 +#define FAIL (-1) + +#undef _SUCCESS +#define _SUCCESS 1 + +#undef _FAIL +#define _FAIL 0 + +#ifndef FALSE + #define FALSE 0 +#endif + +#ifndef TRUE + #define TRUE (!FALSE) +#endif + +#define _TRUE TRUE +#define _FALSE FALSE + +#ifndef NULL +#define NULL 0 +#endif + +#ifdef __GNUC__ +#define __weak __attribute__((weak)) +#define likely(x) __builtin_expect ((x), 1) +#define unlikely(x) __builtin_expect ((x), 0) +#endif + +typedef unsigned int uint; +typedef signed int sint; + +#ifdef __ICCARM__ +typedef signed long long __int64_t; +typedef unsigned long long __uint64_t; +#endif + +#define s8 int8_t +#define u8 uint8_t +#define s16 int16_t +#define u16 uint16_t +#define s32 int32_t +#define u32 uint32_t +#define s64 int64_t +#define u64 uint64_t + +typedef unsigned char uint8; +typedef signed char sint8; +typedef signed char int8; +typedef unsigned short uint16; +typedef signed short sint16; +typedef unsigned int uint32; +typedef unsigned int u_int; +typedef signed int sint32; +typedef int int32; +typedef signed long long sint64; +typedef unsigned long long uint64; +typedef float real32; +typedef double real64; + +#ifdef CONFIG_MBED_ENABLED +typedef unsigned int BOOL; +#else +#ifndef BOOL +typedef unsigned char BOOL; +#endif +#ifndef bool +typedef unsigned char bool; +#endif +#endif + +#define UCHAR uint8_t +#define USHORT uint16_t +#define UINT uint32_t +#define ULONG uint32_t + +typedef struct { volatile int counter; } atomic_t; + +typedef enum _RTK_STATUS_ { + _EXIT_SUCCESS = 0, + _EXIT_FAILURE = 1 +}RTK_STATUS, *PRTK_STATUS; + +#define IN +#define OUT +#define VOID void +#define LOCAL static +#define INOUT +#define NDIS_OID uint +#define NDIS_STATUS uint + +#ifndef PVOID +typedef void * PVOID; +#endif + +typedef u32 dma_addr_t; + +typedef void (*proc_t)(void*); + +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; + +typedef __kernel_size_t SIZE_T; +typedef __kernel_ssize_t SSIZE_T; +#define FIELD_OFFSET(s,field) ((SSIZE_T)&((s*)(0))->field) + +#define MEM_ALIGNMENT_OFFSET (sizeof (SIZE_T)) +#define MEM_ALIGNMENT_PADDING (sizeof(SIZE_T) - 1) + +#define SIZE_PTR SIZE_T +#define SSIZE_PTR SSIZE_T + +#define true (1) +#define false (0) + +#ifndef ON +#define ON 1 +#endif + +#ifndef OFF +#define OFF 0 +#endif + +#ifndef ENABLE +#define ENABLE 1 +#endif + +#ifndef DISABLE +#define DISABLE 0 +#endif + + +#define BIT0 0x0001 +#define BIT1 0x0002 +#define BIT2 0x0004 +#define BIT3 0x0008 +#define BIT4 0x0010 +#define BIT5 0x0020 +#define BIT6 0x0040 +#define BIT7 0x0080 +#define BIT8 0x0100 +#define BIT9 0x0200 +#define BIT10 0x0400 +#define BIT11 0x0800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#define BIT_(__n) (1<<(__n)) + +#ifndef BIT +#define BIT(__n) (1<<(__n)) +#endif + +#if defined (__ICCARM__) +#define STRINGIFY(s) #s +#define SECTION(_name) _Pragma( STRINGIFY(location=_name)) +#define ALIGNMTO(_bound) _Pragma( STRINGIFY(data_alignment=_bound)) +#define _PACKED_ __packed +#define _LONG_CALL_ +#define _LONG_CALL_ROM_ +#define _WEAK __weak +#else +#define SECTION(_name) __attribute__ ((__section__(_name))) +#define ALIGNMTO(_bound) __attribute__ ((aligned (_bound))) +#define _PACKED_ __attribute__ ((packed)) +#ifdef CONFIG_RELEASE_BUILD_LIBRARIES +#define _LONG_CALL_ +#define _LONG_CALL_ROM_ __attribute__ ((long_call)) +#ifdef E_CUT_ROM_DOMAIN +#undef _LONG_CALL_ROM_ +#define _LONG_CALL_ROM_ +#endif +#else +#define _LONG_CALL_ __attribute__ ((long_call)) +#define _LONG_CALL_ROM_ _LONG_CALL_ +#endif +#define _WEAK __attribute__ ((weak)) +#endif + + + +//port from fw by thomas +// TODO: Belows are Sync from SD7-Driver. It is necessary to check correctness + +#define SWAP32(x) ((u32)( \ + (((u32)(x) & (u32)0x000000ff) << 24) | \ + (((u32)(x) & (u32)0x0000ff00) << 8) | \ + (((u32)(x) & (u32)0x00ff0000) >> 8) | \ + (((u32)(x) & (u32)0xff000000) >> 24))) + +#define WAP16(x) ((u16)( \ + (((u16)(x) & (u16)0x00ff) << 8) | \ + (((u16)(x) & (u16)0xff00) >> 8))) + +#if SYSTEM_ENDIAN == PLATFORM_LITTLE_ENDIAN +#ifndef rtk_le16_to_cpu +#define rtk_cpu_to_le32(x) ((u32)(x)) +#define rtk_le32_to_cpu(x) ((u32)(x)) +#define rtk_cpu_to_le16(x) ((u16)(x)) +#define rtk_le16_to_cpu(x) ((u16)(x)) +#define rtk_cpu_to_be32(x) SWAP32((x)) +#define rtk_be32_to_cpu(x) SWAP32((x)) +#define rtk_cpu_to_be16(x) WAP16((x)) +#define rtk_be16_to_cpu(x) WAP16((x)) +#endif + +#elif SYSTEM_ENDIAN == PLATFORM_BIG_ENDIAN +#ifndef rtk_le16_to_cpu +#define rtk_cpu_to_le32(x) SWAP32((x)) +#define rtk_le32_to_cpu(x) SWAP32((x)) +#define rtk_cpu_to_le16(x) WAP16((x)) +#define rtk_le16_to_cpu(x) WAP16((x)) +#define rtk_cpu_to_be32(x) ((__u32)(x)) +#define rtk_be32_to_cpu(x) ((__u32)(x)) +#define rtk_cpu_to_be16(x) ((__u16)(x)) +#define rtk_be16_to_cpu(x) ((__u16)(x)) +#endif +#endif + + +/* + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. +*/ + +// +// Byte Swapping routine. +// +#define EF1Byte (u8) +#define EF2Byte le16_to_cpu +#define EF4Byte le32_to_cpu + +// +// Read LE format data from memory +// +#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr))) +#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr))) +#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr))) + +// +// Write LE data to memory +// +#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr)))=EF1Byte(_val) +#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr)))=EF2Byte(_val) +#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr)))=EF4Byte(_val) + +// +// Example: +// BIT_LEN_MASK_32(0) => 0x00000000 +// BIT_LEN_MASK_32(1) => 0x00000001 +// BIT_LEN_MASK_32(2) => 0x00000003 +// BIT_LEN_MASK_32(32) => 0xFFFFFFFF +// +#define BIT_LEN_MASK_32(__BitLen) \ + (0xFFFFFFFF >> (32 - (__BitLen))) +// +// Example: +// BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 +// BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 +// +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) + +// +// Description: +// Return 4-byte value in host byte ordering from +// 4-byte pointer in litten-endian system. +// +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + (EF4Byte(*((u32 *)(__pStart)))) + +// +// Description: +// Translate subfield (continuous bits in little-endian) of 4-byte value in litten byte to +// 4-byte value in host byte ordering. +// +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_32(__BitLen) \ + ) + +// +// Description: +// Mask subfield (continuous bits in little-endian) of 4-byte value in litten byte oredering +// and return the result in 4-byte value in host byte ordering. +// +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + & \ + ( ~ BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) ) \ + ) + +// +// Description: +// Set subfield of little-endian 4-byte value to specified value. +// +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u32 *)(__pStart)) = \ + EF4Byte( \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset) ) \ + ); + + +#define BIT_LEN_MASK_16(__BitLen) \ + (0xFFFF >> (16 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_16(__BitLen) << (__BitOffset)) + +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + (EF2Byte(*((u16 *)(__pStart)))) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_16(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + & \ + ( ~ BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u16 *)(__pStart)) = \ + EF2Byte( \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << (__BitOffset) ) \ + ); + +#define BIT_LEN_MASK_8(__BitLen) \ + (0xFF >> (8 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_8(__BitLen) << (__BitOffset)) + +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + (EF1Byte(*((u8 *)(__pStart)))) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + ( LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset) ) \ + & \ + BIT_LEN_MASK_8(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + & \ + ( ~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) ) \ + ) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u8 *)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ( (((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << (__BitOffset) ) \ + ); + +//pclint +#define LE_BITS_CLEARED_TO_1BYTE_8BIT(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + ) + +//pclint +#define SET_BITS_TO_LE_1BYTE_8BIT(__pStart, __BitOffset, __BitLen, __Value) \ +{ \ + *((pu1Byte)(__pStart)) = \ + EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE_8BIT(__pStart, __BitOffset, __BitLen) \ + | \ + ((u1Byte)__Value) \ + ); \ +} + +// Get the N-bytes aligment offset from the current length +#define N_BYTE_ALIGMENT(__Value, __Aligment) ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / __Aligment) * __Aligment)) + +typedef unsigned char BOOLEAN,*PBOOLEAN; + +#define TEST_FLAG(__Flag,__testFlag) (((__Flag) & (__testFlag)) != 0) +#define SET_FLAG(__Flag, __setFlag) ((__Flag) |= __setFlag) +#define CLEAR_FLAG(__Flag, __clearFlag) ((__Flag) &= ~(__clearFlag)) +#define CLEAR_FLAGS(__Flag) ((__Flag) = 0) +#define TEST_FLAGS(__Flag, __testFlags) (((__Flag) & (__testFlags)) == (__testFlags)) + +/* Define compilor specific symbol */ +// +// inline function +// + +#if defined ( __ICCARM__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition //In dialect C99, inline means that a function's definition is provided + //only for inlining, and that there is another definition + //(without inline) somewhere else in the program. + //That means that this program is incomplete, because if + //add isn't inlined (for example, when compiling without optimization), + //then main will have an unresolved reference to that other definition. + + // Do not inline function is the function body is defined .c file and this + // function will be called somewhere else, otherwise there is compile error +#elif defined ( __CC_ARM ) +#define __inline__ __inline //__linine__ is not supported in keil compilor, use __inline instead +#define inline __inline +#define __inline_definition // for dialect C99 +#elif defined ( __GNUC__ ) +#define __inline__ inline +#define __inline inline +#define __inline_definition inline +#endif + +// +// pack +// + +#if defined (__ICCARM__) + +#define RTW_PACK_STRUCT_BEGIN _Pragma( STRINGIFY(pack(1))) +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END _Pragma( STRINGIFY(pack())) +//#define RTW_PACK_STRUCT_USE_INCLUDES + +#elif defined (__CC_ARM) + +#define RTW_PACK_STRUCT_BEGIN __packed +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END + +#elif defined (__GNUC__) + +#define RTW_PACK_STRUCT_BEGIN +#define RTW_PACK_STRUCT_STRUCT __attribute__ ((__packed__)) +#define RTW_PACK_STRUCT_END + +#elif defined(PLATFORM_WINDOWS) + +#define RTW_PACK_STRUCT_BEGIN +#define RTW_PACK_STRUCT_STRUCT +#define RTW_PACK_STRUCT_END +#define RTW_PACK_STRUCT_USE_INCLUDES +#endif + +// for standard library +#ifdef __ICCARM__ +#define __extension__ /* Ignore */ +#define __restrict /* Ignore */ +#endif + + +#endif// __BASIC_TYPES_H__ diff --git a/USDK/component/soc/realtek/common/bsp/section_config.h b/USDK/component/soc/realtek/common/bsp/section_config.h new file mode 100644 index 0000000..bc212b1 --- /dev/null +++ b/USDK/component/soc/realtek/common/bsp/section_config.h @@ -0,0 +1,327 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#ifndef _SECTION_CONFIG_H_ +#define _SECTION_CONFIG_H_ + +#include "basic_types.h" +#include "platform_autoconf.h" + +#define RAM_DEDECATED_VECTOR_TABLE_SECTION \ + SECTION(".ram_dedecated_vector_table") + +#define RAM_USER_IRQ_FUN_TABLE_SECTION \ + SECTION(".ram_user_define_irq_table") + +#define RAM_USER_IRQ_DATA_TABLE_SECTION \ + SECTION(".ram_user_define_data_table") + +//3 Timer Section +#define SECTION_RAM_TIMER2TO7_VECTOR_TABLE \ + SECTION(".timer2_7_vector_table.data") + +#define SECTION_RAM_BSS_TIMER_RECORDER_TABLE \ + SECTION(".timer.ram.data") + +#define TIMER_ROM_TEXT_SECTION \ + SECTION(".timer.rom.text") + +#define TIMER_ROM_DATA_SECTION \ + SECTION(".timer.rom.rodata") + +#define TIMER_RAM_TEXT_SECTION \ + SECTION(".timer.ram.text") + +#define TIMER_RAM_DATA_SECTION \ + SECTION(".timer.ram.data") + + +//3 Wifi Section +#define WIFI_ROM_TEXT_SECTION \ + SECTION(".wifi.rom.text") + +#define WIFI_ROM_DATA_SECTION \ + SECTION(".wifi.rom.rodata") + +#define WIFI_RAM_TEXT_SECTION \ + SECTION(".wifi.ram.text") + +#define WIFI_RAM_DATA_SECTION \ + SECTION(".wifi.ram.data") + +//3 Hal Section +#define HAL_ROM_TEXT_SECTION \ + SECTION(".hal.rom.text") + +#define HAL_ROM_DATA_SECTION \ + SECTION(".hal.rom.rodata") + +#define HAL_RAM_TEXT_SECTION \ + SECTION(".hal.ram.text") + +#define HAL_FLASH_TEXT_SECTION \ + SECTION(".hal.flash.text") + +#define HAL_FLASH_DATA_SECTION \ + SECTION(".hal.flash.data") + +#define HAL_SDRC_TEXT_SECTION \ + SECTION(".hal.sdrc.text") + +#define HAL_SDRC_DATA_SECTION \ + SECTION(".hal.sdrc.data") + +#define HAL_CUT_B_RAM_DATA_SECTION \ + SECTION(".cutb.ram.data") + +#define HAL_CUT_C_RAM_DATA_SECTION \ + SECTION(".cutc.ram.data") + +#define HAL_RAM_DATA_SECTION \ + SECTION(".hal.ram.data") + +#define HAL_RAM_BSS_SECTION \ + SECTION(".hal.ram.bss") + +#define HAL_ROM_OP_SECTION \ + SECTION(".halop.rom.rodata") + +#define HAL_GPIO_TEXT_SECTION \ + SECTION(".hal.gpio.text") + +#define HAL_GPIO_DATA_SECTION \ + SECTION(".hal.gpio.data") + +#define FWU_DATA_SECTION \ + SECTION(".fwu.data") + +#define FWU_RODATA_SECTION \ + SECTION(".fwu.rodata") + +#define FWU_TEXT_SECTION \ + SECTION(".fwu.text") + +//3 C-Cut ROM Patch/New functions location +#define C_CUT_ROM_TEXT_SECTION \ + SECTION(".cutc.rom.text") + +#define C_CUT_ROM_RODATA_SECTION \ + SECTION(".cutc.rom.rodata") + +#define C_CUT_ROM_DATA_SECTION \ + SECTION(".cutc.ram.data") +//3 No ROM code changed for D_Cut, so no D-Cut section +//3 E-Cut ROM Patch/New functions location +#define E_CUT_ROM_TEXT_SECTION \ + SECTION(".cute.rom.text") + +#define E_CUT_ROM_RODATA_SECTION \ + SECTION(".cute.rom.rodata") + +#define E_CUT_ROM_DATA_SECTION \ + SECTION(".cute.ram.data") + +/* #define FWUROM_DATA_SECTION \ + SECTION(".fwurom.data") */ + +/* #define FWUROM_RODATA_SECTION \ + SECTION(".fwurom.rodata") */ + +#define FWUROM_TEXT_SECTION \ + SECTION(".fwurom.text") + +#define XMPORT_ROM_TEXT_SECTION \ + SECTION(".xmportrom.text") + +#define XDMROM_TEXT_SECTION \ + SECTION(".xmodemrom.text") + + +//3 Store the Image 1 validate code +#define IMAGE1_VALID_PATTEN_SECTION \ + SECTION(".image1.validate.rodata") + +#define IMAGE2_VALID_PATTEN_SECTION \ + SECTION(".image2.validate.rodata") + +//3 Infra Section +#define INFRA_ROM_TEXT_SECTION \ + SECTION(".infra.rom.text") + +#define INFRA_ROM_DATA_SECTION \ + SECTION(".infra.rom.rodata") + +#define INFRA_RAM_TEXT_SECTION \ + SECTION(".infra.ram.text") + +#define INFRA_RAM_DATA_SECTION \ + SECTION(".infra.ram.data") + +#define INFRA_RAM_BSS_SECTION \ + SECTION(".infra.ram.bss") + +#define INFRA_START_SECTION \ + SECTION(".infra.ram.start") + + +//3 Pin Mutex Section +#define PINMUX_ROM_TEXT_SECTION \ + SECTION(".hal.rom.text") + +#define PINMUX_ROM_DATA_SECTION \ + SECTION(".hal.rom.rodata") + +#define PINMUX_RAM_TEXT_SECTION \ + SECTION(".hal.ram.text") + +#define PINMUX_RAM_DATA_SECTION \ + SECTION(".hal.ram.data") + +#define PINMUX_RAM_BSS_SECTION \ + SECTION(".hal.ram.bss") + + +//3 Monitor App Section +#define MON_ROM_TEXT_SECTION \ + SECTION(".mon.rom.text") + +#define MON_ROM_DATA_SECTION \ + SECTION(".mon.rom.rodata") + +#define MON_RAM_TEXT_SECTION \ + SECTION(".mon.ram.text") + +#define MON_RAM_DATA_SECTION \ + SECTION(".mon.ram.data") + +#define MON_RAM_BSS_SECTION \ + SECTION(".mon.ram.bss") + +#define MON_RAM_TAB_SECTION \ + SECTION(".mon.tab.rodata") + +//3 SDIO Section +#define SECTION_SDIO_RAM +#define SECTION_SDIO_ROM +#define SDIO_ROM_BSS_SECTION \ + SECTION(".sdio.rom.bss") +#define SDIO_ROM_TEXT_SECTION \ + SECTION(".sdio.rom.text") + +//3 SRAM Config Section +#define SRAM_BD_DATA_SECTION \ + SECTION(".bdsram.data") + +#define SRAM_BF_DATA_SECTION \ + SECTION(".bfsram.data") + +#define SRAM_HEAP_SECTION \ + SECTION(".sram.heap") + + +#define START_RAM_FUN_SECTION \ + SECTION(".start.ram.data") + +#define START_RAM_FUN_A_SECTION \ + SECTION(".start.ram.data.a") + +#define START_RAM_FUN_B_SECTION \ + SECTION(".start.ram.data.b") + +#define START_RAM_FUN_C_SECTION \ + SECTION(".start.ram.data.c") + +#define START_RAM_FUN_D_SECTION \ + SECTION(".start.ram.data.d") + +#define START_RAM_FUN_E_SECTION \ + SECTION(".start.ram.data.e") + +//Non-Flash Boot Section +#define NON_FLASH_BOOT_DATA_SECTION \ + SECTION(".nonflash.data") +#define NON_FLASH_BOOT_HEAP_SECTION \ + SECTION(".nonflash.heap") + +// USB OTG Section +#define OTG_ROM_BSS_SECTION \ + SECTION(".otg.rom.bss") + +#if defined(CONFIG_CHIP_E_CUT) || defined(CONFIG_USB_BOOT_SIM) +#define OTG_ROM_TEXT_SECTION \ + SECTION(".otg.rom.text") + +#define OTG_ROM_DATA_SECTION \ + SECTION(".otg.rom.rodata") + +#define START_OTG_RAM_FUN_SECTION \ + SECTION(".ram.otg.data.a") + +#define START_OTG_RAM_DATA_SECTION \ + SECTION(".ram.otg.data.b") + +#else +#define OTG_ROM_TEXT_SECTION \ +// SECTION(".otg.ram.text") + +#define OTG_ROM_DATA_SECTION \ +// SECTION(".otg.ram.rodata") + +#define START_OTG_RAM_FUN_SECTION \ +// SECTION(".ram.otg.data.a") + +#define START_OTG_RAM_DATA_SECTION \ +// SECTION(".ram.otg.data.b") +#endif + + +#define IMAGE2_START_RAM_FUN_SECTION \ + SECTION(".image2.ram.data") + +#define SDRAM_DATA_SECTION \ + SECTION(".sdram.data") + +//3 Wlan Section +#define WLAN_ROM_TEXT_SECTION \ + SECTION(".wlan.rom.text") + +#define WLAN_ROM_DATA_SECTION \ + SECTION(".wlan.rom.rodata") + +#define WLAN_RAM_MAP_SECTION \ + SECTION(".wlan_ram_map") + +//3 Apple Section +#define APPLE_ROM_TEXT_SECTION \ + SECTION(".apple.rom.text") + +#define APPLE_ROM_DATA_SECTION \ + SECTION(".apple.rom.rodata") + +//3 Libc Section +#define LIBC_ROM_TEXT_SECTION \ + SECTION(".libc.rom.text") + +#define LIBC_ROM_DATA_SECTION \ + SECTION(".libc.rom.rodata") + +#define LIBC_RAM_BSS_SECTION \ + SECTION(".libc.ram.bss") + +//3 SSL Section +#define SSL_ROM_TEXT_SECTION \ + SECTION(".ssl.rom.text") + +#define SSL_ROM_DATA_SECTION \ + SECTION(".ssl.rom.rodata") + +#define SSL_RAM_MAP_SECTION \ + SECTION(".ssl_ram_map") + +#endif //_SECTION_CONFIG_H_ diff --git a/USDK/example_sources/analogin_voltage/readme.txt b/USDK/example_sources/analogin_voltage/readme.txt new file mode 100644 index 0000000..a68f1cd --- /dev/null +++ b/USDK/example_sources/analogin_voltage/readme.txt @@ -0,0 +1,23 @@ +Example Description + +This example describes how to use ADC. + + +1.Prepare a DC power supply to provide a adjustable voltage. + +2.Connect anode to HDK board A3, and cathode to GND + +3.Run the main function. + +4.Will see result like below + +AD1:00008049 = 1644 mv, AD2:00002a75 = 17 mv, AD3:00002a94 = 20 mv + + +NOTE: + 1. For 8195AM EVB, A0 and A1 are hardware connected. A2 is also available. + For 8711AM EVB, A0 and A1 are not available. Only A2 is avaliable. + 2. ADC need calibration to get correct voltage value by modifing OFFSET and GAIN_DIV. + + + diff --git a/USDK/example_sources/analogin_voltage/src/main.c b/USDK/example_sources/analogin_voltage/src/main.c new file mode 100644 index 0000000..ff8a06d --- /dev/null +++ b/USDK/example_sources/analogin_voltage/src/main.c @@ -0,0 +1,88 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "analogin_api.h" +#include + +#define ADC_CALIBRATION 0 +#define MBED_ADC_EXAMPLE_PIN_1 AD_1 // no pin out +#define MBED_ADC_EXAMPLE_PIN_2 AD_2 // HDK, A1 +#define MBED_ADC_EXAMPLE_PIN_3 AD_3 // HDK, A2 + +#if defined (__ICCARM__) +analogin_t adc0; +analogin_t adc1; +analogin_t adc2; +#else +volatile analogin_t adc0; +volatile analogin_t adc1; +volatile analogin_t adc2; +#endif + +void adc_delay(void) +{ + int i; + for(i=0;i<1600000;i++) + asm(" nop"); +} + +uint16_t adcdat0 = 0; +uint16_t adcdat1 = 0; +uint16_t adcdat2 = 0; + +int32_t v_mv0; +int32_t v_mv1; +int32_t v_mv2; + +/* + * OFFSET: value of measuring at 0.000v, value(0.000v) + * GAIN_DIV: value(1.000v)-value(0.000v) or value(2.000v)-value(1.000v) or value(3.000v)-value(2.000v) + * + * MSB 12bit of value is valid, need to truncate LSB 4bit (0xABCD -> 0xABC). OFFSET and GAIN_DIV are truncated values. + */ +#define OFFSET 0x298 +#define GAIN_DIV 0x34C +#define AD2MV(ad,offset,gain) (((ad/16)-offset)*1000/gain) + +VOID +main ( + VOID +) +{ + uint16_t offset, gain; + analogin_init(&adc0, MBED_ADC_EXAMPLE_PIN_1); // no pinout on HDK board + analogin_init(&adc1, MBED_ADC_EXAMPLE_PIN_2); + analogin_init(&adc2, MBED_ADC_EXAMPLE_PIN_3); +#if ADC_CALIBRATION + sys_adc_calibration(0, &offset, &gain); + printf("ADC:offset = 0x%x, gain = 0x%x\n", offset, gain); + if((offset==0xFFFF) || (gain==0xFFFF)) +#endif + { + offset = OFFSET; + gain = GAIN_DIV; + printf("ADC:offset = 0x%x, gain = 0x%x\n", offset, gain); + } + for (;;){ + adcdat0 = analogin_read_u16(&adc0); + adcdat1 = analogin_read_u16(&adc1); + adcdat2 = analogin_read_u16(&adc2); + + v_mv0 = AD2MV(adcdat0, offset, gain); + v_mv1 = AD2MV(adcdat1, offset, gain); + v_mv2 = AD2MV(adcdat2, offset, gain); + + printf("AD0:%x = %d mv, AD1:%x = %d mv, AD2:%x = %d mv\n", adcdat0, v_mv0, adcdat1, v_mv1, adcdat2, v_mv2); + adc_delay(); + } + analogin_deinit(&adc0); + analogin_deinit(&adc1); + analogin_deinit(&adc2); +} diff --git a/USDK/example_sources/crypto/readme.txt b/USDK/example_sources/crypto/readme.txt new file mode 100644 index 0000000..a67ae05 --- /dev/null +++ b/USDK/example_sources/crypto/readme.txt @@ -0,0 +1,7 @@ +Example Description + +This example describes how to use CRYPTO function, it is based on cutomer requirement modified. + +use Arduino board to test, and it will show at console + + diff --git a/USDK/example_sources/crypto/src/main.c b/USDK/example_sources/crypto/src/main.c new file mode 100644 index 0000000..c958c98 --- /dev/null +++ b/USDK/example_sources/crypto/src/main.c @@ -0,0 +1,433 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "FreeRTOS.h" +#include "task.h" +#include "device.h" +#include "serial_api.h" +#include "hal_crypto.h" +#include "main.h" +#include "diag.h" +#include + +#define STACKSIZE 2048 + +void test_sha1(void) +{ + const unsigned char *sha1_text[3] = { + "", + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + }; + const uint8_t sha1_test_digest[3][20] = { + { 0xda,0x39,0xa3,0xee, 0x5e,0x6b,0x4b,0x0d, 0x32,0x55,0xbf,0xef, 0x95,0x60,0x18,0x90, 0xaf,0xd8,0x07,0x09 }, + { 0xa9,0x99,0x3e,0x36, 0x47,0x06,0x81,0x6a, 0xba,0x3e,0x25,0x71, 0x78,0x50,0xc2,0x6c, 0x9c,0xd0,0xd8,0x9d }, + { 0x84,0x98,0x3e,0x44, 0x1c,0x3b,0xd2,0x6e, 0xba,0xae,0x4a,0xa1, 0xf9,0x51,0x29,0xe5, 0xe5,0x46,0x70,0xf1 } + }; + uint32_t i; + uint8_t digest[20]; + int ret; + for (i=0; i<3; i++) + { + memset((void*)digest, 0, sizeof(digest)); + ret = rtl_crypto_sha1(sha1_text[i], strlen(sha1_text[i]), digest); + if ( rtl_memcmpb((void*)digest, (void*)&sha1_test_digest[i][0], 20) == 0 ) + DiagPrintf("SHA1 test result is correct, ret=%d\r\n", ret); + else + DiagPrintf("SHA test result is WRONG!, ret=%d\r\n", ret); + } +} +//static const u8 plaintext[] = "The quick brown fox jumps over the lazy dog"; +//static const u8 md5_digest[] = "\x9e\x10\x7d\x9d\x37\x2b\xb6\x82" +// "\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"; +//static const u8 md5_key[] = "key"; + +static const char plaintext[] = "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890"; +static const char md5_digest[] = { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }; +static const u8 md5_key[] = "key"; + +static unsigned char md5_test_buf[16][128] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "The quick brown fox jumps over the lazy dog" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" }, + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "The quick brown fox jumps over the lazy dog" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[16] = +{ + 0, 1, 3, 14, 26, 43, 62, 80, 0, 1, 3, 14, 26, 43, 62, 80 +}; + +static const unsigned char md5_test_sum[16][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + {"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82" + "\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"}, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }, + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + {"\x9e\x10\x7d\x9d\x37\x2b\xb6\x82" + "\x6b\xd8\x1d\x35\x42\xa4\x19\xd6"}, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }, + +}; + + + + +u8 digest[64]; +u8 cipher_result[2048]; +u8 test_result[1024]; + +serial_t sobj; + +/* + * + * + * This test_md5 function is used to test hardware md5 functoinality + */ +void test_md5(void) +{ + int i; + int ret; + u8 md5sum[16]; + + DiagPrintf("MD5 test\r\n"); + + ret = rtl_crypto_md5(plaintext, strlen(plaintext), (unsigned char *)&digest); // the length of MD5's digest is 16 bytes. + + if ( rtl_memcmpb(digest, md5_digest, 16) == 0 ) { + DiagPrintf("MD5 test result is correct, ret=%d\r\n", ret); + } else { + DiagPrintf("MD5 test result is WRONG!, ret=%d\r\n", ret); + } + + for( i = 0; i < 16; i++ ) + { + DiagPrintf( " MD5 test #%d: ", i + 1 ); + ret = rtl_crypto_md5(md5_test_buf[i], md5_test_buflen[i], md5sum); // the length of MD5's digest is 16 bytes. + DiagPrintf(" MD5 ret=%d\n", ret); + if( rtl_memcmpb( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + DiagPrintf( "failed\n" ); + memset(md5sum,0,16); + } + else{ + DiagPrintf( "passed\n" ); + memset(md5sum,0,16);} + } + + +} + + +// +// vector : AES CBC 128 bit : +// http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-cbc-128 +// + +//#ifdef __ICCARM__ +//#pragma data_alignment = 4 +//#elif defined (__GNUC__) +//__attribute__ ((aligned (4))) +//#endif +static const unsigned char aes_test_key[16] = +{ + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +} ; + + +//#ifdef __ICCARM__ +//#pragma data_alignment = 4 +//#elif defined (__GNUC__) +//__attribute__ ((aligned (4))) +//#endif +static const unsigned char aes_test_iv_1[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_buf[16] = +{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, +}; +static const unsigned char aes_test_ecb_buf[160] = +{ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a +}; + + + +static const unsigned char aes_test_res_128[16] = +{ + 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, + 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d +}; + +static const unsigned char aes_test_ecb_res_128[160] = +{ + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97, + 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, + 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97 +}; + +/* + * + * THis test_aes_cbc function is use to directly test hardware aes cbc crypto functionality + * + */ +int test_aes_cbc(void) +{ + const u8 *key, *pIv; + u32 keylen= 0; + u32 ivlen = 0; + u8 *message; + u32 msglen; + u8 *pResult; + + int ret; + + DiagPrintf("AES CBC test\r\n"); + + key = aes_test_key; + keylen = 16; + pIv = aes_test_iv_1; + ivlen = 16; + + pResult = cipher_result; + + message = (unsigned char *)aes_test_buf; + msglen = sizeof(aes_test_buf); + ret = rtl_crypto_aes_cbc_init(key,keylen); + if ( ret != 0 ) { + DiagPrintf("AES CBC init failed\r\n"); + return ret; + } + + ret = rtl_crypto_aes_cbc_encrypt(message, msglen, pIv, ivlen, pResult); + if ( ret != 0 ) { + DiagPrintf("AES CBC encrypt failed\r\n"); + return ret; + } + if ( rtl_memcmpb(aes_test_res_128, pResult, msglen) == 0 ) { + DiagPrintf("AES CBC encrypt result success\r\n"); + } else { + DiagPrintf("AES CBC encrypt result failed\r\n"); + } + + message = pResult; + + ret = rtl_crypto_aes_cbc_decrypt(message, msglen, pIv, ivlen, pResult); + if ( ret != 0 ) { + DiagPrintf("AES CBC decrypt failed, ret=%d\r\n", ret); + return ret; + } + + if ( rtl_memcmpb(aes_test_buf, pResult, msglen) == 0 ) { + DiagPrintf("AES CBC decrypt result success\r\n"); + } else { + DiagPrintf("AES CBC decrypt result failed\r\n"); + } + + return 0; +} + +/* + * + * THis test_aes_ecb function is use to directly test hardware ecb cbc crypto functionality + * + * The input parameter for ecb need to confirm iv is null and ivlen is 0 + */ +int test_aes_ecb(void) +{ + + const u8 *key, *pIv; + u32 keylen= 0; + u32 ivlen = 0; + u8 *message; + u32 msglen; + u8 *pResult; + + int ret; + + DiagPrintf("AES ECB test\r\n"); + + key = aes_test_key; + keylen = 16; + pIv = NULL; + ivlen = 0; + + pResult = cipher_result; + message = (unsigned char *)aes_test_ecb_buf; + msglen = sizeof(aes_test_buf); + //for(int i=0;i= 100) { + *Data = -1; + ret = 1; + break; + }; + }; + _HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); + } + else *Data = -1; + return ret; +} + +//----- +int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + if ( (unsigned int)(Addr - 128) > 0x1F ) + result = 1; + else + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + return result; +} + +//----- +int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + + if ( (unsigned int)(Addr - 160) > 0x33 ) + { + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + } + else + { + *Data = -1; + result = 1; + } + return result; +} + +//----- +void _ReadEOTPContant(uint8_t *pContant) +{ + int i; + for(i = 0; i < 32; i++ ) + _HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE); +} + +//----- +void _ReadEfuseContant(int UserCode, uint8_t *pContant) +{ +#define EFUSE_SECTION 11 + uint8_t *pbuf; + int eFuse_Addr; + int offset; + int bcnt; + int i, j; + uint8_t DataTemp0; + uint8_t DataTemp1; + + pbuf = pContant; + eFuse_Addr = 0; + do { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if ( DataTemp0 == 0x0FF ) break; + if ( (DataTemp0 & 0x0F) == 0x0F ) { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE); + offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1; + bcnt = (~DataTemp1) & 0x0F; + if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) { + while (bcnt) + { + if (bcnt & 1) eFuse_Addr += 2; + bcnt >>= 1; + } + } + else + { + int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3; + j = 0; + while ( bcnt ) + { + if ( bcnt & 1 ) + { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE); + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE); + } + bcnt >>= 1; + j += 2; + } + } + } + else + { + for (i = (~DataTemp0) & 0x0F; i; i >>= 1 ) + { + if (i & 1) eFuse_Addr += 2; + } + } + eFuse_Addr++; + } + while (eFuse_Addr <= 0x7E); +} + +//----- +void _ReadEfuseContant1(uint8_t *pContant) +{ + _ReadEfuseContant(0, pContant); +} + +//----- +void _ReadEfuseContant2(uint8_t *pContant) +{ + _ReadEfuseContant(1, pContant); +} + +//----- +void _ReadEfuseContant3(uint8_t *pContant) +{ + _ReadEfuseContant(2, pContant); +} + + +int _efuse_otp_read(u8 address, u8 len, u8 *buf) +{ + u8 content[32]; // the OTP max length is 32 + + if((address + len) > 32) return -1; + _ReadEOTPContant(content); + _memcpy(buf, content + address, len); + return 0; +} +//====================================================== end libs + +//====================================================== +// OTP : one time programming +//====================================================== + +uint8_t buf[128]; + +#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes +static void efuse_otp_task(void *param) +{ + int ret; + u8 i; + + DBG_8195A("\nefuse OTP block: Test Start\n"); + // read OTP content + device_mutex_lock(RT_DEV_LOCK_EFUSE); + ret = efuse_otp_read(0, OTP_MAX_LEN, buf); + device_mutex_unlock(RT_DEV_LOCK_EFUSE); + if(ret < 0){ + DBG_8195A("efuse OTP block: read address and length error\n"); + goto exit; + } + for(i=0; i= 100) { + *Data = -1; + ret = 1; + break; + }; + }; + _HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); + } + else *Data = -1; + return ret; +} + +//----- +int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + if ( (unsigned int)(Addr - 128) > 0x1F ) + result = 1; + else + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + return result; +} + +//----- +int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + + if ( (unsigned int)(Addr - 160) > 0x33 ) + { + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + } + else + { + *Data = -1; + result = 1; + } + return result; +} + +//----- +void _ReadEOTPContant(uint8_t *pContant) +{ + int i; + for(i = 0; i < 32; i++ ) + _HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE); +} + +//----- +void _ReadEfuseContant(int UserCode, uint8_t *pContant) +{ +#define EFUSE_SECTION 11 + uint8_t *pbuf; + int eFuse_Addr; + int offset; + int bcnt; + int i, j; + uint8_t DataTemp0; + uint8_t DataTemp1; + + pbuf = pContant; + eFuse_Addr = 0; + do { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if ( DataTemp0 == 0x0FF ) break; + if ( (DataTemp0 & 0x0F) == 0x0F ) { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE); + offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1; + bcnt = (~DataTemp1) & 0x0F; + if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) { + while (bcnt) + { + if (bcnt & 1) eFuse_Addr += 2; + bcnt >>= 1; + } + } + else + { + int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3; + j = 0; + while ( bcnt ) + { + if ( bcnt & 1 ) + { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE); + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE); + } + bcnt >>= 1; + j += 2; + } + } + } + else + { + for (i = (~DataTemp0) & 0x0F; i; i >>= 1 ) + { + if (i & 1) eFuse_Addr += 2; + } + } + eFuse_Addr++; + } + while (eFuse_Addr <= 0x7E); +} + +//----- +void _ReadEfuseContant1(uint8_t *pContant) +{ + _ReadEfuseContant(0, pContant); +} + +//----- +void _ReadEfuseContant2(uint8_t *pContant) +{ + _ReadEfuseContant(1, pContant); +} + +//----- +void _ReadEfuseContant3(uint8_t *pContant) +{ + _ReadEfuseContant(2, pContant); +} + + +int _efuse_otp_read(u8 address, u8 len, u8 *buf) +{ + u8 content[32]; // the OTP max length is 32 + + if((address + len) > 32) return -1; + _ReadEOTPContant(content); + _memcpy(buf, content + address, len); + return 0; +} +//====================================================== end libs + +//====================================================== +// OTP : one time programming +//====================================================== + +uint8_t buf[128]; + +#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes +static void efuse_otp_task(void *param) +{ + int ret; + u8 i; + + DBG_8195A("\nefuse OTP block: Test Start\n"); + // read OTP content + device_mutex_lock(RT_DEV_LOCK_EFUSE); + ret = efuse_otp_read(0, OTP_MAX_LEN, buf); + device_mutex_unlock(RT_DEV_LOCK_EFUSE); + if(ret < 0){ + DBG_8195A("efuse OTP block: read address and length error\n"); + goto exit; + } + for(i=0; i= 100) { + *Data = -1; + ret = 1; + break; + }; + }; + _HalEFUSEPowerSwitch8195AROM(1, 0, L25OutVoltage); + } + else *Data = -1; + return ret; +} + +//----- +int _HALOTPOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + if ( (unsigned int)(Addr - 128) > 0x1F ) + result = 1; + else + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + return result; +} + +//----- +int _HALEFUSEOneByteReadRAM(uint32_t CtrlSetting, int Addr, uint8_t *Data, uint8_t L25OutVoltage) +{ + int result; + + if ( (unsigned int)(Addr - 160) > 0x33 ) + { + result = _HALEFUSEOneByteReadROM(CtrlSetting, Addr, Data, L25OutVoltage); + } + else + { + *Data = -1; + result = 1; + } + return result; +} + +//----- +void _ReadEOTPContant(uint8_t *pContant) +{ + int i; + for(i = 0; i < 32; i++ ) + _HALOTPOneByteRead(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), i+128, &pContant[i], L25EOUTVOLTAGE); +} + +//----- +void _ReadEfuseContant(int UserCode, uint8_t *pContant) +{ +#define EFUSE_SECTION 11 + uint8_t *pbuf; + int eFuse_Addr; + int offset; + int bcnt; + int i, j; + uint8_t DataTemp0; + uint8_t DataTemp1; + + pbuf = pContant; + eFuse_Addr = 0; + do { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), eFuse_Addr, &DataTemp0, L25EOUTVOLTAGE); + if ( DataTemp0 == 0x0FF ) break; + if ( (DataTemp0 & 0x0F) == 0x0F ) { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &DataTemp1, L25EOUTVOLTAGE); + offset = ((DataTemp1 & 0x0F0) | (DataTemp0 >> 4)) >> 1; + bcnt = (~DataTemp1) & 0x0F; + if (((UserCode + EFUSE_SECTION) << 2) > offset || offset >= ((UserCode + EFUSE_SECTION + 1) << 2)) { + while (bcnt) + { + if (bcnt & 1) eFuse_Addr += 2; + bcnt >>= 1; + } + } + else + { + int base = (offset - ((EFUSE_SECTION + UserCode) << 2)) << 3; + j = 0; + while ( bcnt ) + { + if ( bcnt & 1 ) + { + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j], L25EOUTVOLTAGE); + _HALEFUSEOneByteReadRAM(HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_EFUSE_CTRL), ++eFuse_Addr, &pbuf[base + j + 1], L25EOUTVOLTAGE); + } + bcnt >>= 1; + j += 2; + } + } + } + else + { + for (i = (~DataTemp0) & 0x0F; i; i >>= 1 ) + { + if (i & 1) eFuse_Addr += 2; + } + } + eFuse_Addr++; + } + while (eFuse_Addr <= 0x7E); +} + +//----- +void _ReadEfuseContant1(uint8_t *pContant) +{ + _ReadEfuseContant(0, pContant); +} + +//----- +void _ReadEfuseContant2(uint8_t *pContant) +{ + _ReadEfuseContant(1, pContant); +} + +//----- +void _ReadEfuseContant3(uint8_t *pContant) +{ + _ReadEfuseContant(2, pContant); +} + + +int _efuse_otp_read(u8 address, u8 len, u8 *buf) +{ + u8 content[32]; // the OTP max length is 32 + + if((address + len) > 32) return -1; + _ReadEOTPContant(content); + _memcpy(buf, content + address, len); + return 0; +} +//====================================================== end libs + +//====================================================== +// OTP : one time programming +//====================================================== + +uint8_t buf[128]; + +#define OTP_MAX_LEN 32 // The OTP max length is 32 bytes +static void efuse_otp_task(void *param) +{ + int ret; + u8 i; + + DBG_8195A("\nefuse OTP block: Test Start\n"); + // read OTP content + device_mutex_lock(RT_DEV_LOCK_EFUSE); + ret = efuse_otp_read(0, OTP_MAX_LEN, buf); + device_mutex_unlock(RT_DEV_LOCK_EFUSE); + if(ret < 0){ + DBG_8195A("efuse OTP block: read address and length error\n"); + goto exit; + } + for(i=0; i + +extern void console_init(void); + + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + if ( rtl_cryptoEngine_init() != 0 ) { + DiagPrintf("crypto engine init failed\r\n"); + } + + /* Initialize log uart and at command service */ + console_init(); + + /* pre-processor of application example */ + pre_example_entry(); + + /* wlan intialization */ +#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK) + wlan_network(); +#endif + ethernet_mii_init();// init ethernet driver + /* Execute application example */ + example_entry(); + + /*Enable Schedule, Start Kernel*/ +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + #ifdef PLATFORM_FREERTOS + vTaskStartScheduler(); + #endif +#else + RtlConsolTaskRom(NULL); +#endif +} diff --git a/USDK/example_sources/flash/main_tst_speed_flash.c b/USDK/example_sources/flash/main_tst_speed_flash.c new file mode 100644 index 0000000..71bd019 --- /dev/null +++ b/USDK/example_sources/flash/main_tst_speed_flash.c @@ -0,0 +1,102 @@ +/* + * Test: Speed rd Flash + */ + +#include "rtl8195a.h" +//#include "cortex.h" +//#include "rtl8710.h" +//#include "rom_lib.h" +//#include "mask.h" +#include "core_cm3.h" +#include "flash_api.h" + +//extern uint8_t __StackTop; + +int main(void) +{ + u32 t[10]; + int i = 333333, x = SpicDualBitMode + 1; + HalPinCtrlRtl8195A(JTAG, 0, 1); + HalCpuClkConfig(1); // 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz + ConfigDebugErr = -1; + ConfigDebugInfo = -1; + ConfigDebugWarn = -1; + VectorTableInitRtl8195A(0x1FFFFFFC); + HalInitPlatformLogUartV02(); + HalInitPlatformTimerV02(); + HalShowBuildInfoV02(); + flash_turnon(); + flash_init(&flashobj); +// HalPinCtrlRtl8195A(SPI_FLASH, 0, 1); // SPI_FLASH_PIN_FCTRL(ON); // enable spi flash pins +// SpicLoadInitParaFromClockRtl8195AV02(); +// SpicInitRtl8195AV02(2, SpicDualBitMode); // +// SpicWaitBusyDoneRtl8195A(); + DiagPrintf("Flash[0]: 0x%08X\r\n", *(volatile u32 *)SPI_FLASH_BASE ); +// HalDelayUs(1000000); + DiagPrintf("CPU CLK : %d Hz\r\n", HalGetCpuClk()); + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + if(!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) { + DWT->CYCCNT = 0; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; + } + while(x) { + x--; + DiagPrintf("<---- Init %d ---->\n", x); + if (!SpicFlashInitRtl8195A(x)) {// SpicOneBitMode)){ + + DiagPrintf("SPI Init Fail!\n"); // DBG_SPIF_ERR? + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3)|0xf); + while(1); + } + t[0] = DWT->CYCCNT; + DiagPrintf("Test: t0 = %d\r\n", DWT->CYCCNT - t[0]); + t[0] = DWT->CYCCNT; + volatile u32 * ptr = (volatile u32 *)SPI_FLASH_BASE+0x4000; + for(i=0; i < 16384; i++) *ptr++; + t[1] = DWT->CYCCNT - t[0]; + DiagPrintf("read(): tFlash = %d, clk/byte = %d\r\n", t[1], t[1] >> 16); + ptr = (volatile u32 *)SPI_FLASH_BASE+0x10000; + t[0] = DWT->CYCCNT; + memcpy((u8 *)0x10060000,(u8 *) SPI_FLASH_BASE+0x10000, 65536); + for(i=0; i < 16384; i++) *ptr++; + t[2] = DWT->CYCCNT - t[0]; + DiagPrintf("memcpy(): tFlash = %d, clk/byte = %d\r\n", t[2], t[2] >> 16); + ptr = (volatile u32 *)0x10060000; + t[0] = DWT->CYCCNT; + for(i=0; i < 16384; i++) *ptr++; + t[3] = DWT->CYCCNT - t[0]; + DiagPrintf("Speed rd RAM = %d, clk/byte = %d\r\n", t[3], t[3]>>16); + ptr = (volatile u32 *)0x1FFF0000; + t[0] = DWT->CYCCNT; + for(i=0; i < 16384; i++) *ptr++; + t[4] = DWT->CYCCNT - t[0]; + DiagPrintf("Speed rd TCM = %d, clk/byte = %d\r\n", t[4], t[4]>>16); + DiagPrintf("read(): tFlash/tTCM = %d, tFlash/tRAM = %d\r\n", t[1]/t[4], t[1]/t[3]); + DiagPrintf("memcpy(): tFlash/tTCM = %d, tFlash/tRAM = %d\r\n", t[2]/t[4], t[2]/t[3]); + + t[0] = DWT->CYCCNT; + SpicUserReadRtl8195A(16384*2, 0, (u8 *)0x10060000, x); + t[1] = DWT->CYCCNT - t[0]; + DiagPrintf("Spic 1Read to RAM = %d, clk/byte = %d\r\n", t[1], t[1]>>16); + t[0] = DWT->CYCCNT; + SpicUserReadFourByteRtl8195A(16384*2, 0, (u32 *)0x10060000, x); + t[1] = DWT->CYCCNT - t[0]; + DiagPrintf("Spic 4Read to RAM = %d, clk/byte = %d\r\n", t[1], t[1]>>16); + + t[0] = DWT->CYCCNT; + SpicUserReadRtl8195A(16384*2, 0, (u8 *)0x1FFF0000, x); + t[1] = DWT->CYCCNT - t[0]; + DiagPrintf("Spic 1Read to TCM = %d, clk/byte = %d\r\n", t[1], t[1]>>16); + t[0] = DWT->CYCCNT; + SpicUserReadFourByteRtl8195A(16384*2, 0, (u32 *)0x1FFF0000, x); + t[1] = DWT->CYCCNT - t[0]; + DiagPrintf("Spic 4Read to TCM = %d, clk/byte = %d\r\n", t[1], t[1]>>16); + + } + DiagPrintf("Flash[0]: 0x%08X\r\n", *(volatile u32 *)SPI_FLASH_BASE ); + DiagPrintf("End"); + while(1); +} + + + diff --git a/USDK/example_sources/flash/readme.txt b/USDK/example_sources/flash/readme.txt new file mode 100644 index 0000000..b5b9a92 --- /dev/null +++ b/USDK/example_sources/flash/readme.txt @@ -0,0 +1,8 @@ +Example Description + +This example read a specific flash offset, modify it and re-read again. + +Requirement Components: + None + + diff --git a/USDK/example_sources/flash/src/main.c b/USDK/example_sources/flash/src/main.c new file mode 100644 index 0000000..b3e5ce4 --- /dev/null +++ b/USDK/example_sources/flash/src/main.c @@ -0,0 +1,119 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "objects.h" +#include "flash_api.h" +#include "osdep_service.h" +#include "device_lock.h" +#include "main.h" + +// Decide starting flash address for storing application data +// User should pick address carefully to avoid corrupting image section + +#define FLASH_APP_BASE 0xFF000 +static void flash_test_task(void *param) +{ + flash_t flash; + uint32_t address = FLASH_APP_BASE; + +#if 1 + uint32_t val32_to_write = 0x13572468; + uint32_t val32_to_read; + int loop = 0; + int result = 0; + + for(loop = 0; loop < 10; loop++) + { + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_read_word(&flash, address, &val32_to_read); + DBG_8195A("Read Data 0x%x\n", val32_to_read); + flash_erase_sector(&flash, address); + flash_write_word(&flash, address, val32_to_write); + flash_read_word(&flash, address, &val32_to_read); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + DBG_8195A("Read Data 0x%x\n", val32_to_read); + + // verify result + result = (val32_to_write == val32_to_read) ? 1 : 0; + //printf("\r\nResult is %s\r\n", (result) ? "success" : "fail"); + DBG_8195A("\r\nResult is %s\r\n", (result) ? "success" : "fail"); + result = 0; + } + +#else + int VERIFY_SIZE = 256; + int SECTOR_SIZE = 16; + + uint8_t writedata[VERIFY_SIZE]; + uint8_t readdata[VERIFY_SIZE]; + uint8_t verifydata = 0; + int loop = 0; + int index = 0; + int sectorindex = 0; + int result = 0; + int resultsector = 0; + int testloop = 0; + + for(testloop = 0; testloop < 1; testloop++){ + address = FLASH_APP_BASE; + for(sectorindex = 0; sectorindex < 4080; sectorindex++){ + result = 0; + //address += SECTOR_SIZE; + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_erase_sector(&flash, address); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + //DBG_8195A("Address = %x \n", address); + for(loop = 0; loop < SECTOR_SIZE; loop++){ + for(index = 0; index < VERIFY_SIZE; index++) + { + writedata[index] = verifydata + index; + } + device_mutex_lock(RT_DEV_LOCK_FLASH); + flash_stream_write(&flash, address, VERIFY_SIZE, &writedata); + flash_stream_read(&flash, address, VERIFY_SIZE, &readdata); + device_mutex_unlock(RT_DEV_LOCK_FLASH); + + for(index = 0; index < VERIFY_SIZE; index++) + { + //DBG_8195A("Address = %x, Writedata = %x, Readdata = %x \n",address,writedata[index],readdata[index]); + if(readdata[index] != writedata[index]){ + DBG_8195A("Error: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n",testloop,address,writedata[index],readdata[index]); + } + else{ + result++; + //DBG_8195A(ANSI_COLOR_BLUE"Correct: Loop = %d, Address = %x, Writedata = %x, Readdata = %x \n"ANSI_COLOR_RESET,testloop,address,writedata[index],readdata[index]); + } + } + address += VERIFY_SIZE; + } + if(result == VERIFY_SIZE * SECTOR_SIZE){ + //DBG_8195A("Sector %d Success \n", sectorindex); + resultsector++; + } + } + if(resultsector == 4079){ + DBG_8195A("Test Loop %d Success \n", testloop); + } + resultsector = 0; + verifydata++; + } + //DBG_8195A("%d Sector Success \n", resultsector); + + DBG_8195A("Test Done"); + +#endif + vTaskDelete(NULL); +} + +void main(void) +{ + if(xTaskCreate(flash_test_task, ((const char*)"flash_test_task"), 1024, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS) + printf("\n\r%s xTaskCreate(flash_test_task) failed", __FUNCTION__); + + /*Enable Schedule, Start Kernel*/ + if(rtw_get_scheduler_state() == OS_SCHEDULER_NOT_STARTED) + vTaskStartScheduler(); + else + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/USDK/example_sources/gdma/src/main.c b/USDK/example_sources/gdma/src/main.c new file mode 100644 index 0000000..4f144ed --- /dev/null +++ b/USDK/example_sources/gdma/src/main.c @@ -0,0 +1,158 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "diag.h" +#include "main.h" + +#include "dma_api.h" + +#if 1 +//Multi-Block Example Demo +#define DMA_CPY_LEN 176 +#define DMA_BLOCK_LENGTH 22 +#define DMA_SRC_OFFSET 0 +#define DMA_DST_OFFSET 0 +#define BLOCK_NUM 8 + +gdma_t gdma; +uint8_t TestBuf1[DMA_CPY_LEN]; +uint8_t TestBuf2[DMA_CPY_LEN]; +volatile uint8_t dma_done; + +struct BlockInfo{ + u32 SrcAddr; + u32 DstAddr; + u32 BlockLength; + u32 SrcOffset; + u32 DstOffset; +}; + +void dma_done_handler(uint32_t id) { + DiagPrintf("DMA Copy Done!\r\n"); + dma_done = 1; +} + + +int main(void) { + int i = 0,err = 0; + struct BlockInfo block_info[BLOCK_NUM]; + //Set how many blocks we want to transfer (16 at most) + gdma.gdma_obj.BlockNum = BLOCK_NUM; + //Initialize DMA multi-block mode setting + dma_memcpy_aggr_init(&gdma, dma_done_handler, (uint32_t) &gdma); + + _memset(TestBuf1, 0,DMA_CPY_LEN); + + for(i = 0; i < DMA_CPY_LEN; i++){ + TestBuf1[i] = DMA_CPY_LEN - 1 - i; + } + + _memset(TestBuf2, 0,DMA_CPY_LEN); + dma_done = 0; + + for(i = 0; i < BLOCK_NUM; i++){ + //User can decide the relation between SrcOffset/DstOffset,SrcAddr/DstAddr and Block length + // For example : + //block_info[i].SrcOffset = 0; + //block_info[i].DstOffset = 4; + //block_info[i].SrcAddr = &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC + //block_info[i].DstAddr = &TestBuf2[0] + (DMA_BLOCK_LENGTH + block_info[i].DstOffset )*i;//Dest + //block_info[i].BlockLength = DMA_BLOCK_LENGTH; + + block_info[i].SrcOffset = 0; + block_info[i].DstOffset = 0; + block_info[i].SrcAddr = (uint32_t) &TestBuf1[ i * DMA_BLOCK_LENGTH] ;//SRC + block_info[i].DstAddr = (uint32_t) &TestBuf2[ i * DMA_BLOCK_LENGTH] ;//Dest + block_info[i].BlockLength = DMA_BLOCK_LENGTH; + //DiagPrintf("block_info[%d].SrcAddr = %x\r\n",i, block_info[i].SrcAddr); + //DiagPrintf("block_info[%d].DstAddr = %x\r\n",i, block_info[i].DstAddr); + //DiagPrintf("block_info[%d].BlockLength = %x\r\n",i, block_info[i].BlockLength); + //DiagPrintf("block_info[%d].SrcOffset = %x\r\n",i, block_info[i].SrcOffset); + //DiagPrintf("block_info[%d].DstOffset = %x\r\n",i, block_info[i].DstOffset); + } + + + dma_memcpy_aggr(&gdma, (PHAL_GDMA_BLOCK) &block_info); + + while (dma_done == 0); + + err = 0; + for (i=0;i\n", __FUNCTION__); + gpio_led = (gpio_t *)id; + + led_ctrl = !led_ctrl; + gpio_write(gpio_led, led_ctrl); +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + gpio_irq_t gpio_btn; + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + // Initial Push Button pin as interrupt source + gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led)); + gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_btn); + + led_ctrl = 1; + gpio_write(&gpio_led, led_ctrl); + + while(1); +} + diff --git a/USDK/example_sources/gpio_jtag/readme.txt b/USDK/example_sources/gpio_jtag/readme.txt new file mode 100644 index 0000000..e83e54f --- /dev/null +++ b/USDK/example_sources/gpio_jtag/readme.txt @@ -0,0 +1,14 @@ +Example Description + +This example describes how to disable JTAG module and use GPIO pin to blink led. + +Requirement Components: + a LED + a push button + +PC_4 as input with internal pull-high, connect a push button to this pin and ground. +If button is not pressed while device boot up, then jtag module is turned off. +If button is pressed while device boot up, then we don't turn off jtag module. + +PE_0 as output, connect a LED to this pin and ground. +If jatg module is turned off, then we blink led. diff --git a/USDK/example_sources/gpio_jtag/src/main.c b/USDK/example_sources/gpio_jtag/src/main.c new file mode 100644 index 0000000..bb80336 --- /dev/null +++ b/USDK/example_sources/gpio_jtag/src/main.c @@ -0,0 +1,56 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_api.h" // mbed +#include "sys_api.h" // for sys_jtag_off() +#include "main.h" + +#define GPIO_JTAG_ENABLE_PIN PC_4 +#define GPIO_LED_PIN PE_0 + +void main(void) +{ + int i; + gpio_t gpio_jtag_enable; + gpio_t gpio_led; + + gpio_init(&gpio_jtag_enable, GPIO_JTAG_ENABLE_PIN); + gpio_dir(&gpio_jtag_enable, PIN_INPUT); + gpio_mode(&gpio_jtag_enable, PullUp); + + if (gpio_read(&gpio_jtag_enable) == 0) + { + // JTAG enable pin is disabled + sys_jtag_off(); + printf("jtag off\r\n"); + + // Now you can use jtag pin for other gpio usage + // ex. use PE_0 to blink led + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + while(1) + { + gpio_write(&gpio_led, 1); + for (i=0; i<10000000; i++) asm(" nop"); // simple delay + gpio_write(&gpio_led, 0); + for (i=0; i<10000000; i++) asm(" nop"); // simple delay + } + } + else + { + // JTAG enable pin is enabled + printf("jtag on\r\n"); + } + + for (;;); +} + diff --git a/USDK/example_sources/gpio_level_irq/readme.txt b/USDK/example_sources/gpio_level_irq/readme.txt new file mode 100644 index 0000000..c94401c --- /dev/null +++ b/USDK/example_sources/gpio_level_irq/readme.txt @@ -0,0 +1,21 @@ +Example Description + +This example describes how to implement high/low level trigger on 1 gpio pin. + +Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5: +Connect PC_4 and PC_5 + - PC_4 as gpio input high/low level trigger. + - PC_5 as gpio output + +In this example, PC_5 is signal source that change level to high and low periodically. + +PC_4 setup to listen low level events in initial. +When PC_4 catch low level events, it disable the irq to avoid receiving duplicate events. +(NOTE: the level events will keep invoked if level keeps in same level) + +Then PC_4 is configured to listen high level events and enable irq. +As PC_4 catches high level events, it changes back to listen low level events. + +Thus PC_4 can handle both high/low level events. + +In this example, you will see log that prints high/low level event periodically. diff --git a/USDK/example_sources/gpio_level_irq/src/main.c b/USDK/example_sources/gpio_level_irq/src/main.c new file mode 100644 index 0000000..056e8b5 --- /dev/null +++ b/USDK/example_sources/gpio_level_irq/src/main.c @@ -0,0 +1,73 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_irq_api.h" // mbed +#include "gpio_irq_ex_api.h" +#include "diag.h" +#include "main.h" + +#define GPIO_IRQ_LEVEL_PIN PC_4 +#define GPIO_SIGNAL_SOURCE PC_5 + +gpio_irq_t gpio_level; +int current_level = IRQ_LOW; + +void gpio_level_irq_handler (uint32_t id, gpio_irq_event event) +{ + uint32_t *level = (uint32_t *) id; + + // Disable level irq because the irq will keep triggered when it keeps in same level. + gpio_irq_disable(&gpio_level); + + // make some software de-bounce here if the signal source is not stable. + + if (*level == IRQ_LOW ) + { + printf("low level event\r\n"); + + // Change to listen to high level event + *level = IRQ_HIGH; + gpio_irq_set(&gpio_level, IRQ_HIGH, 1); + gpio_irq_enable(&gpio_level); + } + else if (*level == IRQ_HIGH) + { + printf("high level event\r\n"); + + // Change to listen to low level event + *level = IRQ_LOW; + gpio_irq_set(&gpio_level, IRQ_LOW, 1); + gpio_irq_enable(&gpio_level); + } +} + +void main(void) +{ + int i; + + // configure level trigger handler + gpio_irq_init(&gpio_level, GPIO_IRQ_LEVEL_PIN, gpio_level_irq_handler, (uint32_t)(¤t_level)); + gpio_irq_set(&gpio_level, IRQ_LOW, 1); + gpio_irq_enable(&gpio_level); + + // configure gpio as signal source for high/low level trigger + gpio_t gpio_src; + gpio_init(&gpio_src, GPIO_SIGNAL_SOURCE); + gpio_dir(&gpio_src, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_src, PullNone); + + while(1) { + gpio_write(&gpio_src, 1); + for (i=0; i<20000000; i++) asm("nop"); + gpio_write(&gpio_src, 0); + for (i=0; i<20000000; i++) asm("nop"); + } +} + diff --git a/USDK/example_sources/gpio_light_weight/readme.txt b/USDK/example_sources/gpio_light_weight/readme.txt new file mode 100644 index 0000000..95ab1b4 --- /dev/null +++ b/USDK/example_sources/gpio_light_weight/readme.txt @@ -0,0 +1,13 @@ +Example Description + +This example describes how to use GPIO read/write in a light weight way. + +Requirement Components: + a LED + a push button + +Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5: + - PC_4 as input with internal pull-high, connect a push button to this pin and ground. + - PC_5 as output, connect a LED to this pin and ground. + +In this example, the LED is on when the push button is pressed. diff --git a/USDK/example_sources/gpio_light_weight/src/main.c b/USDK/example_sources/gpio_light_weight/src/main.c new file mode 100644 index 0000000..801b15e --- /dev/null +++ b/USDK/example_sources/gpio_light_weight/src/main.c @@ -0,0 +1,77 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_api.h" // mbed +#include "main.h" + +#define GPIO_LED_PIN PC_5 +#define GPIO_PUSHBT_PIN PC_4 + +/* You can improve time cost of gpio write by import source code of + * function "gpio_direct_write" based on your needs. + * In this example, enable CACHE_WRITE_ACTION as demonstration. + */ +#define CACHE_WRITE_ACTION (0) + +#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1) +const u8 _GPIO_SWPORT_DR_TBL[] = { + GPIO_PORTA_DR, + GPIO_PORTB_DR, + GPIO_PORTC_DR +}; +#endif + +void main(void) +{ + gpio_t gpio_led; + gpio_t gpio_btn; + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + // Initial Push Button pin + gpio_init(&gpio_btn, GPIO_PUSHBT_PIN); + gpio_dir(&gpio_btn, PIN_INPUT); // Direction: Input + gpio_mode(&gpio_btn, PullUp); // Pull-High + +#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1) + u8 port_num = HAL_GPIO_GET_PORT_BY_NAME(gpio_led.hal_pin.pin_name);; + u8 pin_num = HAL_GPIO_GET_PIN_BY_NAME(gpio_led.hal_pin.pin_name);; + u8 dr_tbl = _GPIO_SWPORT_DR_TBL[port_num]; + u32 RegValue; +#endif + + while(1){ +#if defined(CACHE_WRITE_ACTION) && (CACHE_WRITE_ACTION == 1) + if (gpio_read(&gpio_btn)) { + // turn off LED + RegValue = HAL_READ32(GPIO_REG_BASE, dr_tbl); + RegValue &= ~(1 << pin_num); + HAL_WRITE32(GPIO_REG_BASE, dr_tbl, RegValue); + } else { + // turn on LED + RegValue = HAL_READ32(GPIO_REG_BASE, dr_tbl); + RegValue |= (1<< pin_num); + HAL_WRITE32(GPIO_REG_BASE, dr_tbl, RegValue); + } +#else + if (gpio_read(&gpio_btn)) { + // turn off LED + gpio_direct_write(&gpio_led, 0); + } else { + // turn on LED + gpio_direct_write(&gpio_led, 1); + } +#endif + } +} + diff --git a/USDK/example_sources/gpio_port/readme.txt b/USDK/example_sources/gpio_port/readme.txt new file mode 100644 index 0000000..ddfa7b0 --- /dev/null +++ b/USDK/example_sources/gpio_port/readme.txt @@ -0,0 +1,9 @@ +Example Description + +This example describes how to use GPIO Port read/write by mbed api. + +Requirement Components: + 8 LEDs + 2 bords + + diff --git a/USDK/example_sources/gpio_port/src/main.c b/USDK/example_sources/gpio_port/src/main.c new file mode 100644 index 0000000..8c73520 --- /dev/null +++ b/USDK/example_sources/gpio_port/src/main.c @@ -0,0 +1,96 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "port_api.h" // mbed +#include "PortNames.h" // mbed +#include "main.h" + +#define PORT_OUTPUT_TEST 1 //1: output test, 0: input test + +#define LED_PATTERN_NUM 12 + +port_t port0; +const uint8_t led_pattern[LED_PATTERN_NUM]={0x81, 0x42, 0x24, 0x18, 0x00, 0x88, 0x44, 0x22, 0x11, 0xff, 0x00}; +const uint8_t My_Port_Def[] = { + PA_6, PA_7, PA_5, PD_4, + PD_5, PA_4, PA_3, PA_2, + + 0xFF // must end with 0xFF +}; + + +extern void wait_ms(u32); + +/** + * @brief Main program. + * @param None + * @retval None + */ +#if PORT_OUTPUT_TEST + +void main(void) +{ + int i; + unsigned int pin_mask; + + port_mode(&port0, PullNone); + // Assign pins to this port + port0.pin_def = (uint8_t*)My_Port_Def; + pin_mask = 0xFF; // each bit map to 1 pin: 0: pin disable, 1: pin enable + port_init(&port0, PortA, pin_mask, PIN_OUTPUT); + + while(1){ + for (i=0;i +#include "timer_api.h" +#include "main.h" + + +#define SW_RTC_TIMER_ID TIMER4 + +static gtimer_t sw_rtc; +static volatile struct tm rtc_timeinfo; + +const static u8 dim[14] = { + 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28 }; + +static inline bool is_leap_year(unsigned int year) +{ + return (!(year % 4) && (year % 100)) || !(year % 400); +} + + +static u8 days_in_month (u8 month, u8 year) +{ + u8 ret = dim [ month - 1 ]; + if (ret == 0) + ret = is_leap_year (year) ? 29 : 28; + return ret; +} + +static void sw_rtc_tick_handler(uint32_t id) +{ + if(++rtc_timeinfo.tm_sec > 59) { // Increment seconds, check for overflow + rtc_timeinfo.tm_sec = 0; // Reset seconds + if(++rtc_timeinfo.tm_min > 59) { // Increment minutes, check for overflow + rtc_timeinfo.tm_min = 0; // Reset minutes + if(++rtc_timeinfo.tm_hour > 23) { // Increment hours, check for overflow + rtc_timeinfo.tm_hour = 0; // Reset hours + ++rtc_timeinfo.tm_yday; // Increment day of year + if(++rtc_timeinfo.tm_wday > 6) // Increment day of week, check for overflow + rtc_timeinfo.tm_wday = 0; // Reset day of week + // Increment day of month, check for overflow + if(++rtc_timeinfo.tm_mday > + days_in_month(rtc_timeinfo.tm_mon, rtc_timeinfo.tm_year)) { + rtc_timeinfo.tm_mday = 1; // Reset day of month + if(++rtc_timeinfo.tm_mon > 11) { // Increment month, check for overflow + rtc_timeinfo.tm_mon = 0; // Reset month + rtc_timeinfo.tm_yday = 0; // Reset day of year + ++rtc_timeinfo.tm_year; // Increment year + } // - year + } // - month + } // - day + } // - hour + } +} + +static void rtc_init(void) +{ + // Initial a periodical timer + gtimer_init(&sw_rtc, SW_RTC_TIMER_ID); + + // Tick every 1 sec + gtimer_start_periodical(&sw_rtc, 1000000, (void*)sw_rtc_tick_handler, (uint32_t)&sw_rtc); +} + +static void rtc_deinit(void) +{ + gtimer_stop(&sw_rtc); + gtimer_deinit(&sw_rtc); +} + +static void rtc_set_time(uint32_t year, uint8_t mon, uint8_t mday, uint8_t wday, + uint8_t hour, uint8_t min, uint8_t sec) +{ + int i; + + gtimer_stop(&sw_rtc); + rtc_timeinfo.tm_sec = sec; + rtc_timeinfo.tm_min = min; + rtc_timeinfo.tm_hour = hour; + rtc_timeinfo.tm_mday = mday-1; + rtc_timeinfo.tm_wday = wday-1; + rtc_timeinfo.tm_yday = 0; + for (i=0;i<(mon-1);i++) { + rtc_timeinfo.tm_yday += days_in_month(i,year); + } + rtc_timeinfo.tm_yday += (mday-1); + rtc_timeinfo.tm_mon = mon-1; + rtc_timeinfo.tm_year = year; + gtimer_start(&sw_rtc); +} + +static void rtc_read_time(struct tm *timeinfo) +{ + _memcpy((void*)timeinfo, (void*)&rtc_timeinfo, sizeof(struct tm)); + timeinfo->tm_mon++; + timeinfo->tm_mday++; + timeinfo->tm_wday++; + timeinfo->tm_yday++; +} + +void main(void) +{ + struct tm timeinfo; + + rtc_init(); + + // Give RTC a initial value: 2015/4/15 (Wed) 12:00:00 + rtc_set_time(2015, 4, 15, 3, 12, 0, 0); + + while (1) { + rtc_read_time(&timeinfo); + DBG_8195A("%d-%d-%d[%d] %d:%d:%d\r\n", timeinfo.tm_year, timeinfo.tm_mon, timeinfo.tm_mday, + timeinfo.tm_wday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); + wait_ms(1000); + } + rtc_deinit(); +} + diff --git a/USDK/example_sources/i2c-shtc1/readme.txt b/USDK/example_sources/i2c-shtc1/readme.txt new file mode 100644 index 0000000..2b77c13 --- /dev/null +++ b/USDK/example_sources/i2c-shtc1/readme.txt @@ -0,0 +1,13 @@ +Example Description + +This example describes how to use i2c by using mbed api + +work with arduino extended board, which has SHTC1 temperature and humidity +sensor + +Connect + - I2C3 SDA (PB_3) to extended board's SDA + - I2C3 SCL (PB_2) to extended board's SCL + + + diff --git a/USDK/example_sources/i2c-shtc1/src/main.c b/USDK/example_sources/i2c-shtc1/src/main.c new file mode 100644 index 0000000..81f7068 --- /dev/null +++ b/USDK/example_sources/i2c-shtc1/src/main.c @@ -0,0 +1,209 @@ + +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "i2c_api.h" +#include "pinmap.h" +#include "rtl_lib.h" + +#define NO_ERROR 0x00 +#define ACK_ERROR 0x01 +#define CHECKSUM_ERROR 0x02 +#define NULL_ERROR 0x03 + +#define MBED_I2C_MTR_SDA PD_4 +#define MBED_I2C_MTR_SCL PD_5 + +#define MBED_I2C_SLAVE_ADDR0 0x70 +#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001 + + +#define MBED_I2C_BUS_CLK 100000 //hz +#define I2C_DATA_MAX_LENGTH 16 + +uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +int i2cdata_read_pos; + +volatile i2c_t i2cmaster; + + +// Sensor Commands +#define READ_ID 0xEFC8 // command: read ID register +#define SOFT_RESET 0x805D // soft resetSample Code for SHTC1 +#define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled +#define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled +#define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled +#define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled + + +static int SHTC1_GetID(uint16_t *id); +static void SHTC1_WriteCommand(uint16_t cmd); +static int SHTC1_Read2BytesAndCrc(uint16_t *data); +static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum); +static float SHTC1_CalcTemperature(uint16_t rawValue); +static float SHTC1_CalcHumidity(uint16_t rawValue); + + +int SHTC1_Init(uint16_t *pID) +{ + int error = NO_ERROR; + + DiagPrintf("SHTC1_Init \r\n"); + + i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK); + + if (pID == NULL ) return NULL_ERROR; + + + error = SHTC1_GetID(pID); + return error; +} + +static int SHTC1_GetID(uint16_t *id) +{ + int error = NO_ERROR; + uint8_t bytes[2]; + uint8_t checksum; + + SHTC1_WriteCommand(READ_ID); + + i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1); + i2cdata_read_pos = 0; + error = SHTC1_Read2BytesAndCrc(id); + + return error; +} + +static int SHTC1_Read2BytesAndCrc(uint16_t *data) +{ + int error; + int readed; + uint8_t bytes[2]; + uint8_t checksum; + + + + bytes[0] = i2cdata_read[i2cdata_read_pos++]; + bytes[1] = i2cdata_read[i2cdata_read_pos++]; + checksum = i2cdata_read[i2cdata_read_pos++]; + + error = SHTC1_CheckCrc(bytes, 2, checksum); + *data = (bytes[0] << 8) | bytes[1]; + + return error; +} + +static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum) +{ + uint8_t bit; // bit mask + uint8_t crc = 0xFF; // calculated checksum + uint8_t byteCtr; // byte counter + + // calculates 8-Bit checksum with given polynomial + for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++) + { + crc ^= (data[byteCtr]); + for(bit = 8; bit > 0; --bit) + { + if(crc & 0x80) crc = (crc << 1) ^ POLYNOMIAL; + else crc = (crc << 1); + } + } + + // verify checksum + if(crc != checksum) return CHECKSUM_ERROR; + else return NO_ERROR; +} + + +static void SHTC1_WriteCommand(uint16_t cmd) +{ + int writebytes; + + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} + +static float SHTC1_CalcTemperature(uint16_t rawValue) +{ + return 175.0 * (float)rawValue / 65536.0 - 45.0; +} + +static float SHTC1_CalcHumidity(uint16_t rawValue) +{ + return 100.0 * (float)rawValue / 65536.0; +} + +int SHTC1_GetTempAndHumi(float *temp, float *humi) +{ + int error; + uint16_t rawValueTemp; + uint16_t rawValueHumi; + + SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR); + + //Wire1.requestFrom(I2C_ADR_SHTC1, 6); + i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1); + i2cdata_read_pos = 0; + error = NO_ERROR; + error |= SHTC1_Read2BytesAndCrc(&rawValueTemp); + error |= SHTC1_Read2BytesAndCrc(&rawValueHumi); + + //diag_printf("raw temp=0x%x, raw humidity=0x%x, error=%d\n", + // rawValueTemp, rawValueHumi, error); + + if ( error == NO_ERROR ) { + *temp = SHTC1_CalcTemperature(rawValueTemp); + *humi = SHTC1_CalcHumidity(rawValueHumi); + } + + return error; +} + + +void main(void) +{ + gpio_t gpio_led; + int led_status; + int i2clocalcnt; + int error; + uint16_t shtc1_id; + + float temperature = 1.123f; + float humidity = 2.456f; + + + DBG_8195A("sleep 10 sec. to wait for UART console\n"); + RtlMsleepOS(10000); + + + DBG_8195A("start i2c example - SHTC1\n"); + + + error = SHTC1_Init(&shtc1_id); + if ( error == NO_ERROR ) { + DiagPrintf("SHTC1 init ok, id=0x%x\r\n", shtc1_id); + } else { + DiagPrintf("SHTC1 init FAILED! \r\n"); + for(;;); + } + + + while(1){ + error = SHTC1_GetTempAndHumi(&temperature, &humidity); + + rtl_printf("temp=%f, humidity=%f, error=%d\n", + temperature, humidity, error); + + RtlMsleepOS(1000); + + } +} + diff --git a/USDK/example_sources/i2c-shtc1/src/main.zip b/USDK/example_sources/i2c-shtc1/src/main.zip new file mode 100644 index 0000000..64d7f2c Binary files /dev/null and b/USDK/example_sources/i2c-shtc1/src/main.zip differ diff --git a/USDK/example_sources/i2c/readme.txt b/USDK/example_sources/i2c/readme.txt new file mode 100644 index 0000000..065eb44 --- /dev/null +++ b/USDK/example_sources/i2c/readme.txt @@ -0,0 +1,14 @@ +Example Description + +This example describes how to use i2c by using mbed api + +1.Connect LOG-UART connector to PC + +2.Connect + - I2C3 SDA (PB_3) to I2C1 SDA (PC_4) pin, + - I2C3 SCL (PB_2) to I2C1 SCL (PC_5) pin. + +3.Run the main function. + +4.Get the Master and Slave Data. + diff --git a/USDK/example_sources/i2c/src/main.c b/USDK/example_sources/i2c/src/main.c new file mode 100644 index 0000000..7afd5cf --- /dev/null +++ b/USDK/example_sources/i2c/src/main.c @@ -0,0 +1,327 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "PinNames.h" +#include "basic_types.h" +#include "diag.h" +#include + +#include "i2c_api.h" +#include "pinmap.h" +#include "ex_api.h" + +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 + +#define MBED_I2C_SLV_SDA PC_4 +#define MBED_I2C_SLV_SCL PC_5 + +#define MBED_I2C_SLAVE_ADDR0 0xAA +#define MBED_I2C_BUS_CLK 100000 //hz + +#define I2C_DATA_LENGTH 127 +char i2cdatasrc[I2C_DATA_LENGTH]; +char i2cdatadst[I2C_DATA_LENGTH]; +char i2cdatardsrc[I2C_DATA_LENGTH]; +char i2cdatarddst[I2C_DATA_LENGTH]; + +//#define I2C_SINGLE_BOARD +#undef I2C_SINGLE_BOARD + +#ifndef I2C_SINGLE_BOARD + #define I2C_DUAL_BOARD +#endif +#ifdef I2C_SINGLE_BOARD + #define I2C_MASTER_DEVICE + #define I2C_SLAVE_DEVICE +#endif +#ifdef I2C_DUAL_BOARD + //#define I2C_MASTER_DEVICE + #ifndef I2C_MASTER_DEVICE + #define I2C_SLAVE_DEVICE + #endif +#endif + +#define I2C_RESTART_DEMO // test restart + +#ifdef I2C_DUAL_BOARD +// Slave + // RX +#define CLEAR_SLV_RXC_FLAG (slaveRXC = 0) +#define SET_SLV_RXC_FLAG (slaveRXC = 1) +#define WAIT_SLV_RXC while(slaveRXC == 0){;} + // Tx +#define CLEAR_SLV_TXC_FLAG (slaveTXC = 0) +#define SET_SLV_TXC_FLAG (slaveTXC = 1) +#define WAIT_SLV_TXC while(slaveTXC == 0){;} +// Master + // Rx +#define CLEAR_MST_RXC_FLAG (masterRXC = 0) +#define SET_MST_RXC_FLAG (masterRXC = 1) +#define WAIT_MST_RXC while(masterRXC == 0){;} + // Tx +#define CLEAR_MST_TXC_FLAG (masterTXC = 0) +#define SET_MST_TXC_FLAG (masterTXC = 1) +#define WAIT_MST_TXC while(masterTXC == 0){;} +#else // #ifdef I2C_DUAL_BOARD +// Slave + // Rx +#define CLEAR_SLV_RXC_FLAG +#define SET_SLV_RXC_FLAG +#define WAIT_SLV_RXC + // Tx +#define CLEAR_SLV_TXC_FLAG +#define SET_SLV_TXC_FLAG +#define WAIT_SLV_TXC +// Master + // Rx +#define CLEAR_MST_RXC_FLAG +#define SET_MST_RXC_FLAG +#define WAIT_MST_RXC + // Tx +#define CLEAR_MST_TXC_FLAG +#define SET_MST_TXC_FLAG +#define WAIT_MST_TXC +#endif // #ifdef I2C_DUAL_BOARD + +#if defined (__ICCARM__) +i2c_t i2cmaster; +i2c_t i2cslave; +#else +volatile i2c_t i2cmaster; +volatile i2c_t i2cslave; +#endif +volatile int masterTXC; +volatile int masterRXC; +volatile int slaveTXC; +volatile int slaveRXC; + +void i2c_slave_rxc_callback(void *userdata) +{ + + int i2clocalcnt; + int result = 0; + + //DBG_8195A("show slave received data>>>\n"); + for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) { + // DBG_8195A("i2c data: %02x \t %02x\n",i2cdatadst[i2clocalcnt],i2cdatadst[i2clocalcnt+1]); + } + + // verify result + result = 1; + for (i2clocalcnt = 0; i2clocalcnt < 1; i2clocalcnt++) { + if (i2cdatasrc[i2clocalcnt] != i2cdatadst[i2clocalcnt]) { + result = 0; + break; + } + } + DBG_8195A("\r\nSlave receive: Result is %s\r\n", (result) ? "success" : "fail"); + _memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH); + SET_SLV_RXC_FLAG; +} + +void i2c_master_rxc_callback(void *userdata) +{ + + int i2clocalcnt; + int result = 0; + + //DBG_8195A("show master received data>>>\n"); + for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt+=2) { + //DBG_8195A("i2c data: %02x \t %02x\n",i2cdatarddst[i2clocalcnt],i2cdatarddst[i2clocalcnt+1]); + } + + // verify result + result = 1; + for (i2clocalcnt = 0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++) { + if (i2cdatarddst[i2clocalcnt] != i2cdatardsrc[i2clocalcnt]) { + result = 0; + break; + } + } + DBG_8195A("\r\nMaster receive: Result is %s\r\n", (result) ? "success" : "fail"); + +} + +void i2c_slave_txc_callback(void *userdata) +{ + //DBG_8195A("stxc\n"); + SET_SLV_TXC_FLAG; +} + +void i2c_master_txc_callback(void *userdata) +{ + //DBG_8195A("mtxc\n"); + SET_MST_TXC_FLAG; +} + +void i2c_master_err_callback(void *userdata) +{ + DBG_8195A("ERRRRRR:%x\n", i2cmaster.SalI2CHndPriv.SalI2CHndPriv.ErrType); +} + +void demo_i2c_master_enable(void) +{ + _memset(&i2cmaster, 0x00, sizeof(i2c_t)); + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); + i2c_set_user_callback(&i2cmaster, I2C_RX_COMPLETE, i2c_master_rxc_callback); + i2c_set_user_callback(&i2cmaster, I2C_TX_COMPLETE, i2c_master_txc_callback); + i2c_set_user_callback(&i2cmaster, I2C_ERR_OCCURRED, i2c_master_err_callback); +#ifdef I2C_RESTART_DEMO + i2c_restart_enable(&i2cmaster); +#endif +} + +void demo_i2c_slave_enable(void) +{ + _memset(&i2cslave, 0x00, sizeof(i2c_t)); + i2c_init(&i2cslave, MBED_I2C_SLV_SDA ,MBED_I2C_SLV_SCL); + i2c_frequency(&i2cslave,MBED_I2C_BUS_CLK); + i2c_slave_address(&i2cslave, 0, MBED_I2C_SLAVE_ADDR0, 0xFF); + i2c_slave_mode(&i2cslave, 1); + i2c_set_user_callback(&i2cslave, I2C_RX_COMPLETE, i2c_slave_rxc_callback); + i2c_set_user_callback(&i2cslave, I2C_TX_COMPLETE, i2c_slave_txc_callback); +} + +void demo_i2c_master_write_1byte(void) +{ + DBG_8195A("Mst-W\n"); + CLEAR_MST_TXC_FLAG; + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 0); + WAIT_MST_TXC; + DBG_8195A("Mst-W is complete and STOP bit is NOT sent.\n"); +} + +void demo_i2c_master_write_n_1byte(void) +{ + DBG_8195A("Mst-W\n"); + CLEAR_MST_TXC_FLAG; + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], (I2C_DATA_LENGTH-1), 1); + //wait for master TXC + WAIT_MST_TXC; +} + +void demo_i2c_master_write(void) +{ + DBG_8195A("Mst-W\n"); + CLEAR_MST_TXC_FLAG; + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], I2C_DATA_LENGTH, 1); + //wait for master TXC + WAIT_MST_TXC; +} + +void demo_i2c_master_read(void) +{ + DBG_8195A("Mst-R\n"); + DBG_8195A("Mst-R need to wait Slv-W complete.\n"); + CLEAR_MST_RXC_FLAG; + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatarddst[0], I2C_DATA_LENGTH, 1); + WAIT_MST_RXC; +} + +void demo_i2c_slave_read(void) +{ + DBG_8195A("Slv-R\n"); + CLEAR_SLV_RXC_FLAG; + i2c_slave_read(&i2cslave, &i2cdatadst[0], I2C_DATA_LENGTH); + WAIT_SLV_RXC; +} + +void demo_i2c_slave_read_1byte(void) +{ + DBG_8195A("Slv-R\n"); + CLEAR_SLV_RXC_FLAG; + i2c_slave_read(&i2cslave, &i2cdatadst[0], 1); + WAIT_SLV_RXC; +} + +void demo_i2c_slave_write(void) +{ + DBG_8195A("Slv-W\n"); + CLEAR_SLV_TXC_FLAG; + i2c_slave_write(&i2cslave, &i2cdatardsrc[0], I2C_DATA_LENGTH); + WAIT_SLV_TXC; +} + +void main(void) +{ + int i2clocalcnt; + + // prepare for transmission + _memset(&i2cdatasrc[0], 0x00, I2C_DATA_LENGTH); + _memset(&i2cdatadst[0], 0x00, I2C_DATA_LENGTH); + _memset(&i2cdatardsrc[0], 0x00, I2C_DATA_LENGTH); + _memset(&i2cdatarddst[0], 0x00, I2C_DATA_LENGTH); + + for (i2clocalcnt=0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++){ + i2cdatasrc[i2clocalcnt] = i2clocalcnt+0x2; + } + + for (i2clocalcnt=0; i2clocalcnt < I2C_DATA_LENGTH; i2clocalcnt++){ + i2cdatardsrc[i2clocalcnt] = i2clocalcnt+1; + } +// ------- Single board ------- +#ifdef I2C_SINGLE_BOARD + demo_i2c_master_enable(); + demo_i2c_slave_enable(); + // Master write - Slave read + demo_i2c_slave_read(); + #ifdef I2C_RESTART_DEMO + demo_i2c_master_write_1byte(); + demo_i2c_master_write_n_1byte(); // n-1 bytes + #else + demo_i2c_master_write(); + #endif + + // Master read - Slave write + #ifdef I2C_RESTART_DEMO + demo_i2c_slave_read_1byte(); + demo_i2c_master_write_1byte(); + #endif + demo_i2c_slave_write(); + demo_i2c_master_read(); +#endif + +//================================================================ + +// ------- Dual board ------- +#ifdef I2C_DUAL_BOARD +#ifdef I2C_MASTER_DEVICE + demo_i2c_master_enable(); + // Master write - Slave read + #ifdef I2C_RESTART_DEMO + demo_i2c_master_write_1byte(); + demo_i2c_master_write_n_1byte(); // n-1 bytes + #else + demo_i2c_master_write(); + #endif + + // Master read - Slave write + #ifdef I2C_RESTART_DEMO + demo_i2c_master_write_1byte(); + #endif + demo_i2c_master_read(); +#endif // #ifdef I2C_MASTER_DEVICE + +#ifdef I2C_SLAVE_DEVICE + demo_i2c_slave_enable(); + // Master write - Slave read + demo_i2c_slave_read(); + + // Master read - Slave write + #ifdef I2C_RESTART_DEMO + demo_i2c_slave_read_1byte(); + #endif + demo_i2c_slave_write(); +#endif // #ifdef I2C_SLAVE_DEVICE +#endif // #ifdef I2C_DUAL_BOARD + + while(1){;} +} diff --git a/USDK/example_sources/i2c_LPS25HB_pressure/readme.txt b/USDK/example_sources/i2c_LPS25HB_pressure/readme.txt new file mode 100644 index 0000000..2276e6f --- /dev/null +++ b/USDK/example_sources/i2c_LPS25HB_pressure/readme.txt @@ -0,0 +1,7 @@ +Example Description + +this example is use to measure atmos + +work with arduino extended board, which has pressure sensor + +the terminal will feedback real pressure value which is represented in Pa \ No newline at end of file diff --git a/USDK/example_sources/i2c_LPS25HB_pressure/src/main.c b/USDK/example_sources/i2c_LPS25HB_pressure/src/main.c new file mode 100644 index 0000000..da80f25 --- /dev/null +++ b/USDK/example_sources/i2c_LPS25HB_pressure/src/main.c @@ -0,0 +1,183 @@ + +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "i2c_api.h" +#include "pinmap.h" +//#include "rtl_lib.h" +#include "main.h" + +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 +#define MBED_I2C_INTB PA_5 +#define MBED_I2C_SLAVE_ADDR0 0x5D +#define MBED_I2C_BUS_CLK 40000 //hz +#define I2C_DATA_MAX_LENGTH 20 +#define malloc pvPortMalloc +#define free vPortFree + +uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +uint16_t cmd; + +i2c_t i2cmaster; +int count = 0; +//sensor command +#define SENSOR_START 0x20A0 +#define FIFO 0x2E41 +#define REBOOT 0x2110 +#define READ 0x2101 +#define BYPASS 0x2E00 + + +char i2cdatasrc[9] = {0x27, 0x28, 0x29, 0x2A}; +//char i2cdatasrc[7] = {0x40, 0x48, 0x50, 0x27, 0x28, 0x29, 0x2A}; + + +static void ePL_WriteCommand(uint16_t cmd) +{ + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} +/* +struct node +{ + int info; + struct node *ptr; +}*front,*rear,*temp,*front1; +*/ +//int frontelement(); +//void enq(int data); +//void deq(); +/* +void enq(int data) +{ + if (rear == NULL) + { + rear = (struct node *)malloc(1*sizeof(struct node)); + if(rear == NULL) + { + printf("\n\rmalloc rear failed!\n"); + return; + } + rear->ptr = NULL; + rear->info = data; + front = rear; + //printf("front info: %d\n", front->info); + } + else + { + temp=(struct node *)malloc(1*sizeof(struct node)); + rear->ptr = temp; + temp->info = data; + temp->ptr = NULL; + + rear = temp; + //printf("rear info: %d\n", rear->info); + } + count++; +} + +void deq() +{ + front1 = front; + //printf("front info before deq: %d\n", front->info); + if (front1 == NULL) + { + printf("Error: Trying to display elements from empty queue\n"); + return; + } + else + { + if (front1->ptr != NULL) + { + front1 = front1->ptr; + //printf("\nDequed value : %d\n", front->info); + free(front); + front = front1; + } + else + { + //printf("\nDequed value : %d\n", front->info); + free(front); + front = NULL; + rear = NULL; + } + count--; + } +} +*/ +void main(void) +{ + int result; + int i, data; + int temprature; + int flag = 0; + int sum = 0; + int average = 0; + struct node *output; + char intertupt; + + DiagPrintf("Sensor_Init \r\n"); + //for(i=0; i<16; i++) + //printf("ouput before: %d\n", i2cdata_read[i]); + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); + + ePL_WriteCommand(SENSOR_START); + ePL_WriteCommand(REBOOT); + //ePL_WriteCommand(BYPASS); + + while(1){ + //i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[3], 1, 1); + //i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[3], 2, 1); + //printf("Status Reg: %d\n", i2cdata_read[3]); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1); + //printf("--------pressure output LSB: %d\n", i2cdata_read[4]); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1); + //printf("--------pressure output MID: %d\n", i2cdata_read[5]); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[3], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[3], 2, 1); + //printf("--------pressure output MSB: %d\n", i2cdata_read[6]); + Mdelay(2000); + data = (i2cdata_read[3]*256*256*100+i2cdata_read[2]*256*100+i2cdata_read[1]*100)/4128; + printf("pressure: %dPa\n", data); + /* + if(count == 20) + { + deq(); + } + enq(data); + output = front; + sum = front->info; + while(output->ptr != NULL) + { + output = output->ptr; + sum = sum + output->info; + } + + //printf("------count = %d---------\n", count); + average = sum / count; + //printf("---final output: %d---\n", average); + */ + + } + + Mdelay(1000); + + } + + + + + + + + diff --git a/USDK/example_sources/i2c_epl2197_heartrate/inc/HRM_2197.h b/USDK/example_sources/i2c_epl2197_heartrate/inc/HRM_2197.h new file mode 100644 index 0000000..2a44710 --- /dev/null +++ b/USDK/example_sources/i2c_epl2197_heartrate/inc/HRM_2197.h @@ -0,0 +1,77 @@ +/******************************************************************************* + HRM.h - Definition header + *******************************************************************************/ +#ifndef HRM_H +#define HRM_H + +#include + +//------------------------------------------------------ +#define HR_SAMPLE_RATE 25// Hz +#define HR_INTEG_MIN HR_INTEG_40 +#define HR_INTEG_BASE HR_INTEG_250 +#define HR_INTEG_MAX HR_INTEG_250 + +#define HR_TH_HIGH 63000 +#define HR_TH_LOW 30000 +//------------------------------------------------------ + +// HRM I2C address & register sub-addresses +#define HR_SLAVE_ADDRESS 0x82 + +#define HR_FILTER_1 0<<5 +#define HR_FILTER_2 1<<5 +#define HR_FILTER_4 2<<5 +#define HR_FILTER_8 3<<5 +#define HR_FILTER_16 4<<5 +#define HR_FILTER_32 5<<5 +#define HR_FILTER_64 6<<5 +#define HR_FILTER_128 7<<5 + +#define HR_MODE_HR 1<<4 +#define HR_MODE_HRS 9<<4 + +#define HR_GAIN_MID 1 +#define HR_GAIN_LOW 3 + +#define HR_INTEG_20 5 +#define HR_INTEG_25 6 +#define HR_INTEG_30 7 +#define HR_INTEG_40 8 +#define HR_INTEG_55 9 +#define HR_INTEG_70 10 +#define HR_INTEG_90 11 +#define HR_INTEG_110 12 +#define HR_INTEG_150 13 +#define HR_INTEG_200 14 +#define HR_INTEG_250 15 +#define HR_INTEG_350 16 +#define HR_INTEG_450 17 +#define HR_INTEG_550 18 + +#define HR_OSR_64 0<<2 +#define HR_OSR_256 1<<2 +#define HR_OSR_1024 2<<2 +#define HR_OSR_2048 3<<2 + +#define HR_RESETN_RESET 0<<2 +#define HR_RESETN_RUN 1<<2 + +#define HR_PDRIVE_70MA 0<<4 +#define HR_PDRIVE_35MA 1<<4 +#define HR_PDRIVE_200MA 2<<4 +#define HR_PDRIVE_100MA 3<<4 + +#define HR_INT_FRAME 1<<2 +#define HR_INT_DISABLED 2<<2 + +#define HR_IR_DISABLE 0<<7 +#define HR_IR_ENABLE 1<<7 + +//------------------------------------------------------ + +// Declarations +void init_hrm(void); +uint16_t read_hrm(void); + +#endif /* HRM_H */ diff --git a/USDK/example_sources/i2c_epl2197_heartrate/inc/heart_interface.h b/USDK/example_sources/i2c_epl2197_heartrate/inc/heart_interface.h new file mode 100644 index 0000000..52d569c --- /dev/null +++ b/USDK/example_sources/i2c_epl2197_heartrate/inc/heart_interface.h @@ -0,0 +1,39 @@ +/* + * heart_interface.h + * + * Created on: 2014/4/29 + * Author: 01004 + */ + +#ifndef HEART_INTERFACE_H_ +#define HEART_INTERFACE_H_ + +#define MIN_HEART_RATE 48 +#define MAX_HEART_RATE 180 + +extern int g_heartrate; + +typedef void (*hr_callback)(int); + +/* + * If there is no g-sensor, fill x, y, z in 0. + */ +void add_PPG_XYZ(int ppg, short xx, short yy, short zz); + +/* + * A callback to handle heartrate events. + */ +void register_callback(hr_callback callback); + +/* + * Ex: report_period = 25. + * it means report a heart rate every 25 samples. + */ +void start(int report_period); + +void reset(void); + +void stop(void); + + +#endif /* HEART_INTERFACE_H_ */ diff --git a/USDK/example_sources/i2c_epl2197_heartrate/readme.txt b/USDK/example_sources/i2c_epl2197_heartrate/readme.txt new file mode 100644 index 0000000..b77b22d --- /dev/null +++ b/USDK/example_sources/i2c_epl2197_heartrate/readme.txt @@ -0,0 +1,16 @@ +Example Description + +this example is use to measure heart rate of human + +Requirement Components: + extend board + +work with arduino extended board, which has heart rate sensor + +during the measurement, user has to lie his pulp on the sensor and do not rock the sensor + +the test code will return back the heart rate + +Build code +1. Please be sure to copy inc\heart_interface.h, inc\HRM_2197.h +2. Include hr_library.a in IAR project. Add hr_library.a into folder "lib" in IAR project. \ No newline at end of file diff --git a/USDK/example_sources/i2c_epl2197_heartrate/src/main.c b/USDK/example_sources/i2c_epl2197_heartrate/src/main.c new file mode 100644 index 0000000..fa812a6 --- /dev/null +++ b/USDK/example_sources/i2c_epl2197_heartrate/src/main.c @@ -0,0 +1,165 @@ +/******************************************************************************* + * HRM.c - Eminent Heart Rate Module (HRM) routines via I2C + *******************************************************************************/ +#include "HRM_2197.h" +#include +#include +//#include +#include "heart_interface.h" +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "i2c_api.h" +#include "pinmap.h" +//#include "rtl_lib.h" +#include "gpio_api.h" // mbed +#include "main.h" + +#define MBED_I2C_SLAVE_ADDR0 0x41 +#define HR_MODE 0x001b +#define LED_ENABLE 0x3081 +#define FRAME_ENABLE 0x4804 +#define CHIP_RESET 0x4000 +#define CHIP_RUN 0x4004 +#define DATA_LOCK 0x4005 +#define DATA_UNLOCK 0x4004 +#define I2C_DATA_MAX_LENGTH 20 +#define CLOCK_SET 0x3800 +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 +#define MBED_I2C_INTB PA_5 +#define MBED_I2C_BUS_CLK 100000 //hz + +uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +uint16_t cmd; + +i2c_t i2cmaster; + +uint8_t integ_time = HR_INTEG_MIN; +int integ_time_array[] = { 4, 6, 8, 10, 15, 20, 25, 30, 40, 55, 70, 90, 110, 150, 200, 250, 350, 450, 550 }; + + + + +//Step1. define the callback to handle event of heart rate update +/******************************************************************************* + * report heart rate every 1 second + *******************************************************************************/ +void on_heartrate_update(int heartrate) { + printf("heart rate %d\n", heartrate); + //fflush(stdout); +} + +char i2cdatasrc[3] = {0x68, 0x90, 0x98}; + + +static void ePL_WriteCommand(uint16_t cmd) +{ + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} + +uint16_t read_hrm(void) { + uint32_t raw, normalized_raw; + int integ_time_changed = 0; + ePL_WriteCommand(DATA_LOCK); + + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1); + + raw = i2cdata_read[1]; + raw |= (uint16_t) i2cdata_read[2] << 8; + + + normalized_raw = raw >> 4; + normalized_raw = normalized_raw * integ_time_array[HR_INTEG_BASE]; + normalized_raw = normalized_raw / integ_time_array[integ_time]; + + if (raw > HR_TH_HIGH && integ_time > HR_INTEG_MIN) { + integ_time -= 1; + integ_time_changed = 1; + } else if (raw < HR_TH_LOW && integ_time < HR_INTEG_MAX) { + integ_time += 1; + integ_time_changed = 1; + } + + if (integ_time_changed == 1) { + + ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time)); + ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET)); + } + + ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RUN)); + + return normalized_raw; +} + + + +/******************************************************************************* + * main function to read data, input to library, + * and calculate heart rate + *******************************************************************************/ +void main(void) { + int i, length; + int *data; + int should_stop = 0; + uint16_t result; + data = (int*) calloc(3000, sizeof(int)); + //load_ppg_signal(data, &length); //Load Test Data From File + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); +//Step2. delegate the event of heart rate update + register_callback(on_heartrate_update); + + + + +//Step3. Set the data length of heart rate calculation= 2^9 = 512 + + ePL_WriteCommand(((0x00<<3)<<8) | ( HR_MODE_HRS | HR_OSR_1024 | HR_GAIN_MID)); + ePL_WriteCommand(((0x01<<3)<<8) | ( HR_FILTER_4 | integ_time)); + ePL_WriteCommand(((0x09<<3)<<8) | ( HR_PDRIVE_70MA)); + ePL_WriteCommand(((0x06<<3)<<8) | ( HR_IR_ENABLE | HR_INT_FRAME)); + ePL_WriteCommand(((0x08<<3)<<8) | ( HR_RESETN_RESET)); + while(1) { + //Step4. Add ppg data continuously, and the Lib will return the Heart Rate 1 time/sec + result = read_hrm(); + + if(result>100) + add_PPG_XYZ(result, 0, 0, 0); + + Mdelay(40); //Simulate the ppg input time interval = 40ms + if(should_stop) + break; + } + +//Step5. Stop + stop(); + + free(data); + +} + + + + +/******************************************************************************* + * initialize ic parameters + *******************************************************************************/ + + + + +/******************************************************************************* + * read rawdata + *******************************************************************************/ + diff --git a/USDK/example_sources/i2c_epl2590_light/readme.txt b/USDK/example_sources/i2c_epl2590_light/readme.txt new file mode 100644 index 0000000..a82de45 --- /dev/null +++ b/USDK/example_sources/i2c_epl2590_light/readme.txt @@ -0,0 +1,11 @@ +Example Description + +This example describes how to use proximity sensor to detect lightness + +Requirement Components: + extend board + +work with arduino extended board, which has proximity sensor + +when the proximity sensor is in ALS mode (detect lightness), it will keep polling lightness output. + diff --git a/USDK/example_sources/i2c_epl2590_light/src/main.c b/USDK/example_sources/i2c_epl2590_light/src/main.c new file mode 100644 index 0000000..594656e --- /dev/null +++ b/USDK/example_sources/i2c_epl2590_light/src/main.c @@ -0,0 +1,108 @@ + +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "i2c_api.h" +#include "pinmap.h" +//#include "rtl_lib.h" +#include "main.h" + +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 +#define MBED_I2C_INTB PA_5 +#define MBED_I2C_SLAVE_ADDR0 0x49 +#define MBED_I2C_BUS_CLK 100000 //hz +#define I2C_DATA_MAX_LENGTH 20 + +uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +uint16_t cmd; + +i2c_t i2cmaster; +//sensor command +#define WAKE_UP 0x1102 +#define CHIP_REFRESH1 0xFD8E +#define CHIP_REFRESH2 0xFE22 +#define CHIP_REFRESH3 0xFE02 +#define CHIP_REFRESH4 0xFD00 +#define PS_MODE 0x0002 +#define ALS_MODE 0x0001 +#define POWER_UP 0x1102 +#define CHIP_RESET 0x1100 +#define CHANGE_TIME 0x0851 +#define SETTING_1 0x0F19 +#define SETTING_2 0x0D10 +#define INT 0x3022 + +char i2cdatasrc[5] = {0x1B, 0x15, 0x16, 0x80, 0x88}; + + +static void ePL_WriteCommand(uint16_t cmd) +{ + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} + + +void main(void) +{ + int result; + int i; + int light = 0; + int flag = 0; + char intertupt; + + DiagPrintf("Sensor_Init \r\n"); + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); + + ePL_WriteCommand(WAKE_UP); + ePL_WriteCommand(CHIP_REFRESH1); + ePL_WriteCommand(CHIP_REFRESH2); + ePL_WriteCommand(CHIP_REFRESH3); + ePL_WriteCommand(CHIP_REFRESH4); + + ePL_WriteCommand(ALS_MODE); + + //ePL_WriteCommand(SETTING_1); + //ePL_WriteCommand(SETTING_2); + + + ePL_WriteCommand(CHIP_RESET); + + ePL_WriteCommand(POWER_UP); + Mdelay(240); + while(1){ + //ePL_WriteCommand(DATA_LOCK); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1); + // printf("ALS LOW: %d\n", i2cdata_read[1]); + //printf("ALS HIGH: %d\n", i2cdata_read[2]); + light = i2cdata_read[1] + i2cdata_read[2] * 256; + printf("lightness: %d\n", light); + //flag = (i2cdata_read[0] & 8)? 1:0; + //int ret = (i2cdata_read[0] & 4)? 1:0; + //printf("flag: %d\n", flag); + //printf("ret: %d\n", ret); + + //ePL_WriteCommand(POWER_UP); + Mdelay(1000); + + } + + + + + + + +} diff --git a/USDK/example_sources/i2c_epl2590_proximity/readme.txt b/USDK/example_sources/i2c_epl2590_proximity/readme.txt new file mode 100644 index 0000000..0cafbe2 --- /dev/null +++ b/USDK/example_sources/i2c_epl2590_proximity/readme.txt @@ -0,0 +1,12 @@ +Example Description + +This example describes how to use proximity sensor to detect distance + +Requirement Components: + extend board + +work with arduino extended board, which has proximity sensor + +When the proximity sensor is in PS mode (detect distance), if the object is close to the sensor, a near message will print out. Otherwise a far message will print out. + + diff --git a/USDK/example_sources/i2c_epl2590_proximity/src/main.c b/USDK/example_sources/i2c_epl2590_proximity/src/main.c new file mode 100644 index 0000000..f9da2c5 --- /dev/null +++ b/USDK/example_sources/i2c_epl2590_proximity/src/main.c @@ -0,0 +1,115 @@ + +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "i2c_api.h" +#include "pinmap.h" +//#include "rtl_lib.h" +#include "main.h" + +#define MBED_I2C_MTR_SDA PB_3 +#define MBED_I2C_MTR_SCL PB_2 +#define MBED_I2C_INTB PA_5 +#define MBED_I2C_SLAVE_ADDR0 0x49 +#define MBED_I2C_BUS_CLK 100000 //hz +#define I2C_DATA_MAX_LENGTH 20 + +uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH]; +uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH]; +uint16_t cmd; + +i2c_t i2cmaster; +//sensor command +#define WAKE_UP 0x1102 +#define CHIP_REFRESH1 0xFD8E +#define CHIP_REFRESH2 0xFE22 +#define CHIP_REFRESH3 0xFE02 +#define CHIP_REFRESH4 0xFD00 +#define PS_MODE 0x0002 +#define ALS1_MODE 0x0072 +#define ALS2_MODE 0x503E +#define ALS3_MODE 0x583E +#define POWER_UP 0x1102 +#define CHIP_RESET 0x1100 +#define CHANGE_TIME 0x0851 +#define SETTING_1 0x0F19 +#define SETTING_2 0x0D10 +#define INT 0x3022 + +char i2cdatasrc[5] = {0x1B, 0x1E, 0x1F, 0x80, 0x88}; + + +static void ePL_WriteCommand(uint16_t cmd) +{ + i2cdata_write[0] = (uint8_t)(cmd >>8); + i2cdata_write[1] = (uint8_t)(cmd&0xFF); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1); +} + + +void main(void) +{ + int result; + int i; + int flag = 0; + char intertupt; + + DiagPrintf("Sensor_Init \r\n"); + i2c_init(&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL); + i2c_frequency(&i2cmaster,MBED_I2C_BUS_CLK); + + ePL_WriteCommand(WAKE_UP); + ePL_WriteCommand(CHIP_REFRESH1); + ePL_WriteCommand(CHIP_REFRESH2); + ePL_WriteCommand(CHIP_REFRESH3); + ePL_WriteCommand(CHIP_REFRESH4); + + ePL_WriteCommand(PS_MODE); + + ePL_WriteCommand(SETTING_1); + ePL_WriteCommand(SETTING_2); + + + ePL_WriteCommand(CHIP_RESET); + + ePL_WriteCommand(POWER_UP); + Mdelay(240); + while(1){ + //ePL_WriteCommand(DATA_LOCK); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[0], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[1], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[1], 2, 1); + i2c_write(&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdatasrc[2], 1, 1); + i2c_read(&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[2], 2, 1); + //printf("PS LOW: %d\n", i2cdata_read[1]); + //printf("PS HIGH: %d\n", i2cdata_read[2]); + flag = (i2cdata_read[0] & 8)? 1:0; + int ret = (i2cdata_read[0] & 4)? 1:0; + //printf("flag: %d\n", flag); + //printf("ret: %d\n", ret); + + if(flag){ + printf("the object is far\n"); + } + else + { + printf("the object is near\n"); + } + + //ePL_WriteCommand(POWER_UP); + Mdelay(1000); + + } + + + + + + + +} diff --git a/USDK/example_sources/i2s/readme.txt b/USDK/example_sources/i2s/readme.txt new file mode 100644 index 0000000..5a7ec39 --- /dev/null +++ b/USDK/example_sources/i2s/readme.txt @@ -0,0 +1,10 @@ +Example Description + +This example describes how to use i2s by using mbed extend api + +1.Plug ALC5651 shield to Ameba HDK + +2.Run the main function. + +3.Plug earphone to Green phone jack + diff --git a/USDK/example_sources/i2s/src/alc5651.c b/USDK/example_sources/i2s/src/alc5651.c new file mode 100644 index 0000000..1ee3447 --- /dev/null +++ b/USDK/example_sources/i2s/src/alc5651.c @@ -0,0 +1,183 @@ +#include +#include "PinNames.h" +#include "basic_types.h" +#include "diag.h" +#include + +#include "i2c_api.h" +#include "pinmap.h" + +//#define I2C_MTR_SDA PC_4//PB_3 +//#define I2C_MTR_SCL PC_5//PB_2 +#define I2C_MTR_SDA PB_3 +#define I2C_MTR_SCL PB_2 +#define I2C_BUS_CLK 100000 //hz + +#define I2C_ALC5651_ADDR (0x34/2) + +#define RT5651_PRIV_INDEX 0x6a +#define RT5651_PRIV_DATA 0x6c + +#if defined (__ICCARM__) +i2c_t alc5651_i2c; +#else +volatile i2c_t alc5651_i2c; +#define printf DBG_8195A +#endif + +static void alc5651_delay(void) +{ + int i; + + i=10000; + while (i) { + i--; + asm volatile ("nop\n\t"); + } +} + +void alc5651_reg_write(unsigned int reg, unsigned int value) +{ + char buf[4]; + buf[0] = (char)reg; + buf[1] = (char)(value>>8); + buf[2] = (char)(value&0xff); + + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1); + alc5651_delay(); +} + +void alc5651_reg_read(unsigned int reg, unsigned int *value) +{ + int tmp; + char *buf = (char*)&tmp; + + buf[0] = (char)reg; + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1); + alc5651_delay(); + + buf[0] = 0xaa; + buf[1] = 0xaa; + + i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1); + alc5651_delay(); + + *value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF); +} + +void alc5651_index_write(unsigned int reg, unsigned int value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_write(RT5651_PRIV_DATA, value); +} + +void alc5651_index_read(unsigned int reg, unsigned int *value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_read(RT5651_PRIV_DATA, value); +} + +void alc5651_reg_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec reg dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_reg_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_index_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec index dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_index_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_init(void) +{ + i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL); + i2c_frequency(&alc5651_i2c, I2C_BUS_CLK); +} + +void alc5651_set_word_len(int len_idx) // interface2 +{ + // 0: 16 1: 20 2: 24 3: 8 + unsigned int val; + alc5651_reg_read(0x71,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x71,val); + alc5651_reg_read(0x70,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x70,val); + +} + +void alc5651_init_interface1(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x27,0x3820); + alc5651_reg_write(0x77,0x0000); +} + +void alc5651_init_interface2(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x28,0x3030); + alc5651_reg_write(0x2F,0x0080); +} \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_11025_2ch_16b.c b/USDK/example_sources/i2s/src/birds_11025_2ch_16b.c new file mode 100644 index 0000000..040a83d --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_11025_2ch_16b.c @@ -0,0 +1,8041 @@ +#include +int sample_size=32137; + +SECTION(".sdram.data") +short sample[]={ +-1, 1, 0, 0, -1, 2, -2, 1, +1, -1, 0, 1, 1, -1, -1, 1, +-2, 1, 2, -3, 2, -2, 2, -2, +1, -1, -2, 1, 0, -1, 0, 0, +-1, 1, -1, 1, 0, -1, 3, -2, +0, 1, 2, -2, 1, -1, 1, -2, +0, 0, -1, 0, 2, -3, 0, 0, +0, -1, 0, 0, -2, 2, 1, -1, +0, 1, 0, -1, 3, -3, 2, -1, +1, 0, -3, 3, 1, -1, -1, 2, +0, -1, 3, -2, -2, 2, -1, 0, +2, -1, 0, 0, 0, 0, -2, 2, +1, -2, -2, 3, -2, 2, 0, 0, +-1, 2, -2, 2, 0, 0, -1, 1, +1, -1, 2, -1, 1, -1, 1, -1, +2, -1, 0, 1, -1, 0, 0, 0, +-2, 2, -2, 2, -1, 0, 0, 1, +-4, 4, 1, -1, 1, 0, 0, 0, +1, -1, -1, 1, -1, 1, 0, 0, +1, -1, 2, -1, -1, 1, -1, 1, +-2, 2, -3, 3, -1, 0, 2, -2, +-1, 1, -2, 2, -2, 2, -1, 0, +0, 0, -1, 1, 2, -2, 2, -2, +1, -1, 0, 1, -1, 1, 0, 1, +1, -1, 0, 1, -3, 3, -1, 1, +-4, 4, -3, 3, -3, 3, -3, 3, +-3, 2, 2, -3, 3, -3, 1, -1, +-1, 1, 0, 0, -3, 4, -1, 0, +3, -2, -1, 1, 1, -1, 0, 0, +0, 0, 1, -1, 0, 0, 0, 0, +-2, 2, 0, -1, 0, 0, 2, -3, +1, -1, 1, -1, 4, -4, 0, 0, +-2, 3, -2, 2, 1, -1, 2, -1, +0, 0, -1, 2, -1, 1, 0, 1, +0, 0, -2, 2, 0, 0, 0, -1, +1, -1, -1, 0, -2, 1, -3, 2, +1, -2, -2, 2, -2, 1, 5, -6, +1, 0, -2, 2, 1, -1, 1, 0, +3, -2, 0, 0, 1, 0, 1, 0, +0, 1, 0, 0, 2, -2, 0, 1, +-2, 1, 2, -3, 1, -1, -2, 1, +0, 0, 0, -1, 1, -1, -1, 1, +0, -1, 3, -2, 1, 0, 2, -2, +3, -2, 1, -1, 5, -5, 1, 0, +-1, 1, 2, -2, 0, 0, 0, 0, +-2, 2, -1, 0, -1, 1, -2, 1, +-1, 1, 0, -1, 4, -4, 0, 1, +-1, 1, 1, 0, -2, 2, -1, 1, +4, -3, 2, -1, 2, -2, 1, 0, +-2, 2, -1, 1, -3, 2, 1, -1, +-2, 2, 1, -2, 1, -1, 0, 0, +-2, 2, -1, 0, 0, 0, 0, 0, +0, 0, -1, 1, -1, 2, 0, 0, +1, 0, 0, 0, 2, -2, 0, 0, +0, 0, -2, 2, 0, 0, 0, 0, +0, -1, 1, -1, -1, 1, -2, 2, +-2, 2, -1, 1, 1, -2, 3, -2, +-1, 1, 0, 0, -1, 2, 0, 0, +1, 0, -3, 3, -2, 2, -1, 1, +1, -1, 0, 0, -3, 2, -2, 2, +-3, 3, 0, -1, 2, -3, 3, -3, +0, 0, -1, 0, 1, -1, -1, 1, +2, -2, 2, -1, 1, -1, -2, 3, +1, -1, 2, -1, 1, -1, 1, -1, +0, 1, -1, 1, 3, -3, 0, 1, +-5, 5, -3, 2, 1, -1, 0, 0, +-1, 0, 1, -1, -1, 1, 1, -2, +0, 0, 0, 0, 2, -1, 2, -2, +2, -1, 0, 1, -1, 1, 0, 0, +-1, 1, 0, 0, -4, 4, -1, 0, +4, -4, 1, 0, -3, 2, 0, -1, +0, 0, -4, 3, 2, -2, 3, -3, +2, -2, -1, 2, -3, 3, 1, -1, +0, 0, 2, -2, 2, -1, -4, 4, +0, 0, 0, 0, -1, 1, -2, 2, +-2, 1, 0, 0, 0, 0, 0, 0, +0, 0, -2, 2, -4, 3, 1, -1, +2, -2, 2, -2, 1, 0, 0, 0, +1, -1, 0, 0, -1, 1, 1, -1, +1, -1, 1, 0, -2, 2, 2, -2, +-1, 1, -2, 1, 1, -1, -1, 0, +2, -2, 0, 0, -1, 0, 1, -1, +0, 0, 0, 0, -1, 1, 0, 0, +0, 0, 1, -1, -1, 1, 0, 0, +0, 0, 0, 0, 0, 0, -1, 1, +0, -1, 2, -2, 2, -2, 1, -1, +1, -1, 0, 0, 3, -3, 1, 0, +-1, 1, -1, 1, -2, 2, 2, -2, +1, -1, 0, 0, -1, 1, -1, 1, +-2, 2, 3, -3, 3, -2, -2, 2, +-3, 3, -2, 1, 2, -2, -1, 1, +1, -1, -1, 2, 1, -1, 0, 0, +0, 0, -1, 1, -1, 0, 2, -2, +1, -1, 0, 0, -2, 2, -1, 0, +1, -1, -3, 3, -2, 1, 1, -1, +0, -1, 1, -2, 0, 0, 0, 0, +-2, 2, 0, 0, 0, 0, 0, 0, +2, -2, -1, 1, 1, -1, -1, 2, +-2, 2, 1, -1, 0, 0, -1, 1, +0, 0, 2, -2, -1, 1, 0, 0, +-4, 4, -3, 2, 1, -1, -1, 1, +-1, 0, 3, -3, 3, -3, 2, -2, +1, -1, -3, 4, -3, 2, 0, 0, +0, 1, -2, 3, -2, 2, 0, 0, +-1, 2, -2, 2, 1, -1, 2, -2, +0, 0, 0, 0, 0, 0, -1, 1, +-2, 2, -1, 1, -2, 2, 1, -1, +2, -2, 0, 0, 2, -2, 1, -1, +2, -2, 1, -1, 0, -1, 1, -1, +0, -1, 0, 1, -2, 2, 1, -1, +-1, 1, -1, 1, -1, 1, 3, -3, +0, 0, 1, -1, 1, 0, -1, 1, +2, -2, 1, -1, 2, -2, 1, -1, +0, 0, 0, 0, 0, 0, -1, 0, +0, 0, -3, 3, 1, -1, 0, 0, +-1, 1, -1, 1, -1, 0, 1, -1, +1, -1, 1, -1, -1, 1, -1, 1, +2, -2, 0, 1, -1, 1, -2, 3, +-3, 3, 1, -2, 0, 0, 0, 0, +-1, 1, -2, 2, -1, 1, 0, -1, +4, -4, 2, -2, 2, -2, -1, 1, +-2, 1, 2, -2, -3, 4, 0, 0, +0, 1, 1, -1, 2, -2, 1, -2, +2, -2, -3, 3, -2, 1, 1, -2, +1, -1, 0, 0, 2, -2, 0, 0, +-2, 2, 0, 0, -1, 1, -1, 1, +1, -1, 1, -1, -1, 1, 0, 0, +-1, 1, 1, -1, -1, 1, 0, 0, +0, 0, -2, 2, 2, -3, 2, -1, +-2, 1, 3, -4, 0, 1, 0, 0, +0, 1, 0, 0, 2, -2, -2, 2, +0, 0, -2, 3, -2, 1, 2, -2, +-2, 2, 2, -2, 2, -2, 0, -1, +2, -2, 0, 0, 0, 0, -1, 0, +0, 0, -2, 2, -4, 4, -1, 0, +-1, 1, -2, 2, 1, -1, 1, 0, +-1, 1, 2, -2, 2, -1, -1, 1, +2, -2, 0, 0, 0, 0, 3, -3, +1, -1, 0, 0, 1, -1, 2, -2, +3, -3, 3, -2, 0, 1, 0, 0, +2, -3, 0, 0, -2, 1, 1, 0, +-2, 2, 3, -4, 0, 0, 0, 0, +-1, 2, -1, 1, 2, -1, -3, 3, +2, -2, 0, 1, -1, 1, 1, -1, +0, 0, -1, 1, 0, 0, 0, 0, +0, 0, 2, -2, 1, -1, 1, 0, +-1, 1, -2, 2, -1, 1, -1, 2, +0, 0, 0, 0, -2, 2, 3, -3, +0, 1, -2, 1, 0, 1, -1, 1, +0, 0, -1, 2, -2, 2, 1, -1, +1, -1, 0, -1, 1, -1, 0, 1, +-1, 1, 1, -1, 2, -1, -1, 0, +2, -2, -1, 1, 1, -1, 0, 0, +1, -2, 1, 0, -2, 2, -2, 1, +1, -2, 0, 0, -2, 1, 1, -1, +-1, 1, -1, 0, 2, -1, -2, 2, +0, 0, 0, 0, 0, -1, 2, -2, +0, 0, 1, -1, -1, 1, 1, -1, +0, 0, 1, -1, -2, 2, 0, -1, +2, -1, -1, 1, -1, 0, 1, -1, +1, -1, 0, 0, 1, -1, -2, 2, +-2, 1, 1, 0, -2, 2, 0, 0, +-1, 1, 0, 1, -3, 3, 1, -1, +-1, 2, -1, 0, 3, -3, 0, 0, +1, -1, 1, 0, -1, 1, -2, 2, +-1, 0, 2, -2, -2, 2, -2, 1, +0, 0, 0, 0, -1, 2, -1, 1, +0, 0, 1, -1, 1, -1, -2, 2, +1, -1, 1, 0, -1, 1, -2, 2, +2, -2, 1, 0, 0, -1, 3, -3, +0, 1, 0, 0, 0, 0, 1, -1, +0, 1, -2, 2, -3, 3, -1, 0, +2, -1, -1, 1, -2, 2, 0, 0, +0, 1, -1, 1, 0, 0, 3, -3, +2, -2, 0, 0, 0, 0, -1, 0, +1, -1, -3, 3, -2, 2, 1, -1, +0, 0, 1, -1, 0, 0, -4, 4, +0, -1, 1, -1, -3, 3, -2, 2, +0, 0, 1, -1, 2, -1, -1, 2, +0, 0, 1, 0, -3, 3, 1, -1, +-1, 1, -1, 0, 3, -3, 1, -1, +1, -1, 2, -2, 1, -1, 3, -3, +0, 0, 0, 0, 0, 0, 0, -1, +2, -2, 0, 0, 1, -1, 0, 0, +1, -1, -1, 1, -1, 1, -1, 1, +-1, 2, -2, 1, 3, -3, 0, 0, +-1, 1, -2, 2, -3, 3, -1, 1, +1, -1, -1, 2, -1, 1, -1, 1, +1, -2, 0, 1, -1, 1, 0, 1, +-1, 0, 1, -1, 0, 0, 0, 0, +1, -1, 0, 0, 2, -3, 0, 1, +-2, 1, 3, -3, 0, 0, -2, 2, +1, -1, 2, -1, 0, 0, 1, -1, +1, -1, 0, 1, -1, 1, 0, 0, +1, -1, 2, -2, 1, -1, 3, -3, +2, -1, 0, 0, 1, -2, 3, -2, +0, 1, -1, 0, 0, 0, -1, 1, +1, -2, 1, -1, 2, -2, 1, -1, +-1, 1, 0, 0, 1, -1, 1, -1, +-2, 2, -1, 0, 0, 0, 0, 0, +1, -1, 0, 0, -2, 2, 0, -1, +1, 0, -2, 2, 1, -1, 0, 0, +-2, 2, -3, 3, 0, -1, 3, -3, +2, -2, -1, 1, 2, -2, 1, 0, +-1, 1, -1, 1, 0, -1, 2, -1, +-1, 1, 0, 0, 0, 0, 1, 0, +-2, 2, 2, -2, 0, 1, 0, -1, +0, 0, -1, 1, 0, 0, -1, 1, +-1, 1, -1, 1, 1, -1, 1, -1, +3, -3, 2, -2, 2, -2, 2, -1, +-1, 1, 1, -2, 1, -1, -1, 1, +0, 0, 1, -1, 1, 0, -1, 1, +2, -2, -2, 2, -1, 0, 2, -2, +1, -1, 3, -3, 0, 1, -2, 1, +-1, 1, 0, 0, 0, 0, 1, -1, +-1, 1, 0, 0, 0, 0, 0, 0, +1, -1, 3, -3, 2, -1, 0, 1, +0, 0, 1, -1, -2, 2, 0, 0, +-2, 2, -2, 1, 1, -1, 1, -1, +1, -1, -3, 3, 1, -1, 2, -2, +1, -1, 0, 0, 2, -2, 2, -1, +-1, 1, 0, 0, 2, -2, 0, 0, +-3, 3, -2, 2, 0, 0, -1, 1, +0, 0, 0, 0, -2, 2, 1, -1, +1, -1, -2, 3, -1, 0, 1, -1, +-1, 1, 3, -3, 2, -2, 0, 0, +1, -1, -1, 2, -2, 2, 0, -1, +1, -1, 0, 0, -2, 2, -2, 2, +-4, 4, -2, 2, 2, -2, 2, -2, +3, -3, -1, 1, 1, -2, 0, 0, +-4, 4, -1, 1, -2, 2, 1, -2, +3, -2, -1, 1, 0, 0, -1, 1, +0, 0, 1, -1, 0, 0, -2, 2, +0, 0, 0, 1, -1, 1, 3, -3, +1, -1, 0, 0, -1, 2, -2, 2, +-2, 2, 0, -1, -2, 3, -4, 3, +-1, 1, -1, 1, 1, -1, -1, 1, +1, -2, 0, 0, 0, 0, 2, -2, +2, -2, 3, -3, 2, -2, 0, 1, +-1, 1, 3, -3, 2, -2, 1, -2, +3, -3, -1, 1, 0, 0, 0, 0, +-1, 2, -1, 1, 0, 0, 0, -1, +2, -1, -2, 1, 1, -1, 0, 0, +-2, 1, -3, 2, 0, 0, -4, 4, +-2, 1, 0, 0, 0, 0, 0, 0, +-1, 2, 1, -1, 3, -3, 0, 1, +0, 0, 1, -1, 0, 0, 0, 0, +-2, 2, -4, 3, 3, -3, 0, 1, +-1, 0, -1, 2, -3, 3, 0, 0, +0, -1, 2, -1, -1, 1, 1, -2, +-1, 1, 1, -1, 4, -4, -2, 3, +-2, 2, 1, -2, -2, 2, -1, 1, +1, -1, -2, 1, -2, 2, 0, 0, +-1, 0, -1, 0, 1, 1, -2, 1, +1, -3, 4, -3, 0, 1, -4, 2, +2, -2, 3, -1, -2, 1, -3, 2, +1, 0, -1, 1, -4, 2, 2, 0, +0, 1, -2, 0, -2, 2, -1, 2, +-3, 2, -1, 0, 4, -2, -1, 1, +-5, 3, 2, 0, -2, 3, -3, 0, +-1, 2, -3, 5, -2, 0, -1, -1, +1, 2, -3, 3, -1, -2, 3, -1, +-1, 2, -4, 2, -3, 3, 1, 1, +-1, 0, -3, 2, 3, -1, 2, -1, +-4, 1, 4, -3, 3, -1, -4, 1, +-1, 1, 1, 2, -3, 1, 0, -1, +3, 0, -1, 1, -4, 1, 0, 2, +2, 0, -3, -1, 2, -2, 3, 1, +-2, 0, -2, 0, 4, 0, 0, 1, +-3, -1, 3, -1, 2, 0, -3, 0, +-1, 1, 5, -2, -2, 0, -1, -2, +5, 0, -1, 2, -5, 1, 2, 0, +3, 0, -3, -1, 0, 0, 5, -1, +2, -4, -3, 0, 5, -1, 2, -2, +-4, 0, 2, 1, 1, 2, -3, -1, +0, 0, 5, 0, -2, 0, 0, -3, +3, 2, -1, 1, -3, -1, 0, 2, +3, 0, -5, 0, 0, -1, 4, 1, +-1, -1, -3, 0, 5, 0, 0, 1, +-7, 2, 3, -1, 7, -3, -4, 0, +1, -3, 6, 0, -4, 1, 0, -4, +6, -1, 1, -1, -1, -4, 0, 3, +2, 2, -6, 2, -3, 2, 6, 0, +-2, 0, -5, 1, 4, 0, 1, 1, +-10, 4, 4, -2, 5, 0, -7, 1, +0, -1, 7, -1, -3, 1, -8, 3, +7, -3, 5, -2, -8, 2, 2, 0, +4, 1, -4, -2, -1, 0, 6, 0, +-2, 0, -4, 0, 4, 1, 3, -2, +-5, -1, 2, 0, 6, -1, -6, 1, +0, -2, 5, 1, -3, 1, -5, 1, +4, 1, 1, 1, -4, -2, 2, 1, +2, 2, -6, 1, -3, 1, 6, 0, +-1, -1, -4, -1, 4, 1, 3, -1, +-7, 1, 2, -1, 5, 0, -4, -2, +0, -2, 5, 1, -3, 1, -5, 0, +2, 2, 2, 0, -3, -3, 2, 0, +3, 1, -4, -1, -1, -1, 6, 1, +-4, 3, -3, -2, 6, -2, 5, -3, +-7, 1, 2, -1, 6, -1, -6, 2, +-2, -1, 6, 0, -3, 2, -5, 0, +6, -2, 3, -1, -5, 0, 1, 0, +2, 3, -5, 0, 1, -4, 7, -1, +1, -2, -6, 2, 4, 0, 4, -1, +-8, 2, 0, 0, 5, -1, -6, 1, +-4, 1, 4, 2, -3, 3, -7, 3, +2, 3, 2, 1, -5, 0, 1, 0, +3, 1, -3, -1, -2, -1, 7, -3, +2, -2, -5, 1, 4, 0, 6, -3, +-2, -1, -1, 2, 4, -1, -4, 0, +-1, -2, 5, -1, 0, -1, -4, 1, +2, 1, 4, -2, 1, -4, 4, -2, +2, 3, -4, -1, 2, -4, 4, 0, +-1, 0, -3, -1, 2, 2, 0, 2, +-3, 0, 2, -1, 5, -1, -2, 0, +-3, 0, 2, 1, -2, 0, -3, -1, +1, 2, 3, -1, -1, -2, 1, 0, +2, 3, -2, 0, -2, 1, 2, 0, +2, -3, -5, 1, 2, -1, 2, -1, +-2, -1, 1, 0, 4, 0, -1, 1, +2, -2, 3, 1, -1, 1, -5, 1, +0, 0, 1, -1, -5, 1, -2, 1, +4, -1, -1, 2, -2, 3, 4, 0, +1, 0, -3, 1, -2, 1, -4, 2, +-6, 1, -2, -1, 2, -1, 2, -1, +3, -1, 8, -2, 3, 0, 2, -2, +0, -1, -2, 0, -6, 0, -4, 0, +-2, 2, -2, 2, 2, 0, 4, 2, +5, 1, 1, 2, -1, 1, -3, 1, +-7, 0, -5, -2, -2, -2, -4, 3, +-2, 2, 6, 0, 6, 1, 8, -3, +1, 2, -1, 0, -5, -1, -9, 1, +-8, 1, -3, -1, -3, 2, 4, 1, +9, 1, 8, -1, 8, -2, 2, 2, +-5, 1, -10, 0, -10, 0, -10, 3, +-6, 1, 1, 2, 10, 0, 9, 2, +9, 0, 9, -2, -1, 0, -11, 1, +-14, 3, -9, -3, -5, -4, -2, 2, +10, -1, 9, 2, 12, 0, 13, -1, +1, 2, -8, -1, -9, -2, -11, -2, +-14, 0, -3, -3, 7, 0, 10, 0, +15, -1, 17, 0, 11, -3, -3, -1, +-9, 0, -14, 0, -19, 0, -9, -2, +4, -2, 10, -2, 18, -3, 22, -1, +11, 2, 2, -1, -5, -1, -17, 3, +-23, 1, -17, 2, -4, 1, 4, 0, +12, 2, 23, 0, 19, -1, 5, 1, +0, -1, -11, 0, -23, 0, -18, -1, +-10, 1, -4, 1, 9, 0, 24, -2, +22, -1, 10, 2, 7, -1, -6, -1, +-23, 1, -24, 2, -16, 1, -11, 1, +6, -1, 21, 1, 21, 0, 18, -2, +13, 0, 0, -2, -18, -1, -20, -1, +-18, -1, -16, -1, -1, 0, 14, 3, +17, 3, 20, -1, 19, 1, 2, 2, +-14, 0, -19, 0, -19, -1, -22, 0, +-7, -1, 8, 3, 17, -1, 22, -1, +23, 1, 11, 0, -7, 0, -15, 0, +-20, 0, -24, -1, -12, -2, 4, 0, +9, 2, 20, -1, 27, -1, 18, -2, +0, 0, -9, 1, -20, 2, -25, -2, +-18, 0, -5, 2, 9, -5, 15, 1, +27, -1, 21, -1, 4, 1, 1, -2, +-15, 2, -25, -2, -21, 1, -11, 2, +-2, 0, 14, -4, 27, -2, 19, 1, +13, -2, 5, 1, -8, 0, -20, -2, +-20, 0, -13, 0, -6, -3, 7, -1, +20, 0, 21, -2, 15, -1, 10, 2, +-1, -2, -17, -1, -18, -1, -14, -1, +-14, 0, 0, -1, 14, 1, 17, -1, +17, -2, 17, -1, 4, -1, -11, 0, +-16, 2, -17, 1, -18, 1, -8, 3, +6, 2, 8, 4, 14, 0, 18, 1, +4, 4, -7, 0, -8, -1, -11, -3, +-16, 0, -9, 0, 5, 0, 7, -1, +15, -3, 18, 0, 10, -1, 0, -1, +-4, -1, -9, -1, -16, -2, -7, -2, +-6, 4, -1, 3, 7, 2, 15, 0, +11, 0, 1, 1, 1, -1, -5, -3, +-14, 1, -10, -1, -2, -2, -1, -2, +4, 2, 14, -2, 11, -1, 5, 0, +5, -2, -6, 4, -9, -4, -6, -1, +-3, -4, -4, 1, 3, -2, 12, -2, +6, 1, 8, -3, 9, -1, 2, -4, +-6, 1, -8, 0, -9, 5, -9, 0, +1, 1, 6, -1, 7, -2, 5, 2, +5, 1, 2, 1, -3, -4, -3, 2, +-6, -3, -7, 3, -3, -2, 3, 1, +7, -6, 6, -1, 5, 2, 5, -5, +1, 0, 1, -5, -5, 6, -8, -3, +-5, 7, 0, -2, -1, 3, 4, -2, +5, 0, 2, 3, 3, -6, 0, 6, +-6, -1, -5, 5, 1, -8, -1, 5, +-1, -4, 3, 0, 4, 0, 3, -3, +2, 3, 2, -5, 1, 4, -4, -5, +-4, 8, -1, -6, -4, 6, -1, -2, +2, 1, -1, 4, 0, -3, 6, 1, +4, -10, 1, 5, 1, -8, -3, 8, +-3, -6, -2, 5, 0, -2, 2, -3, +0, 5, 2, -5, 2, 6, 1, -9, +-1, 10, -3, -6, -1, 5, 0, -6, +-2, 4, 1, -3, 2, -3, -2, 9, +1, -7, 1, 10, -2, -7, 0, 9, +-2, -7, -2, 7, -4, -2, -1, 0, +1, 1, 1, -5, 2, 7, 3, -10, +4, 8, 1, -10, 0, 8, 0, -9, +-3, 6, -1, -4, 1, -2, 0, 4, +4, -9, 4, 8, 4, -11, -2, 15, +1, -11, 2, 6, -4, -5, 0, 1, +1, -2, -2, -2, 2, 5, 2, -8, +3, 10, 3, -11, 2, 10, 1, -11, +-3, 9, -3, -4, -1, 0, -1, 1, +0, -5, 2, 7, 3, -10, 3, 10, +1, -10, 0, 10, -1, -8, -5, 9, +-4, -2, -3, 0, -1, 4, 2, -7, +0, 11, 4, -12, 2, 12, -1, -9, +-2, 9, 0, -8, -1, 2, -6, 2, +0, -4, -1, 8, 1, -8, 5, 8, +4, -11, 2, 9, 2, -10, -3, 8, +-4, -3, -5, 2, -4, 3, 3, -8, +1, 7, 6, -12, 5, 9, 3, -10, +3, 7, -1, -5, -3, 3, -3, -2, +-3, -1, 0, 3, 0, -7, 2, 9, +5, -9, 3, 9, 2, -7, 1, 6, +-4, -2, -6, 2, -3, 2, -3, -4, +-1, 6, 2, -8, 6, 6, 3, -7, +3, 7, 1, -4, -3, 4, -2, -2, +-4, -1, -3, 3, 1, -9, 0, 8, +4, -8, 4, 7, 5, -7, 3, 5, +-1, -2, -2, -1, -3, 1, -3, -5, +-2, 5, -2, -5, 4, 6, 4, -7, +4, 5, 6, -5, -3, 6, 0, -2, +-2, -3, -5, 5, -3, -7, -2, 9, +-2, -4, 3, 6, 5, -6, 6, 2, +2, -2, 0, -1, -3, 4, -5, -5, +-2, 4, -1, -8, 2, 6, -1, -3, +3, 5, 7, -6, 3, 2, -4, 5, +-1, -4, -3, 5, -4, -7, -3, 8, +-2, -6, 0, 8, 3, -5, 4, 4, +2, 0, -1, 1, -3, 6, -4, -5, +-4, 7, -6, -5, -2, 8, -1, -6, +3, 4, 5, -4, 1, 3, 1, 3, +-1, -3, -4, 7, -3, -8, -2, 8, +-3, -8, 1, 6, 3, -6, 2, 5, +2, 0, 5, -4, 0, 5, -2, -6, +-5, 10, -4, -8, 0, 6, -3, -6, +0, 7, 3, -5, 4, 1, 1, 4, +-1, -2, 0, 5, -2, -8, -3, 9, +-3, -9, -1, 7, 3, -9, 1, 6, +2, -1, 1, 1, 1, 4, 0, -6, +-1, 8, -1, -10, -3, 10, 0, -11, +1, 7, 0, -5, 4, 0, 7, -3, +1, -2, 0, 6, 0, -8, -1, 8, +-1, -12, -4, 12, 0, -9, 0, 7, +2, -4, 3, 1, 2, 2, 3, -8, +1, 7, 1, -13, -2, 10, -2, -11, +1, 8, 1, -8, 2, 4, 6, -5, +-2, 2, 1, 4, 2, -9, -2, 10, +-3, -11, -3, 12, -4, -8, -1, 8, +3, -7, 1, 5, 1, 1, 1, -4, +2, 6, -1, -9, -3, 11, 1, -15, +-1, 11, 1, -12, 1, 8, 1, -4, +2, 0, 0, 4, 1, -6, 0, 8, +-4, -9, -2, 13, -6, -8, -1, 10, +1, -9, 0, 8, 2, -4, 3, -2, +2, 4, -1, -8, 1, 8, 0, -13, +-2, 13, -1, -13, -2, 14, 1, -8, +2, 4, -1, 1, 2, -4, 1, 5, +3, -13, 0, 12, -2, -13, -3, 15, +-1, -11, 0, 11, -1, -6, 5, 0, +4, 0, 0, -5, 1, 7, 0, -11, +-3, 15, -4, -12, 0, 12, 2, -12, +-1, 11, 0, -4, 2, 2, -2, 4, +0, -7, -1, 11, 0, -14, -1, 13, +2, -17, 2, 12, -1, -9, 3, 6, +1, -2, -1, 0, 2, 3, 1, -10, +-1, 11, 0, -15, 1, 13, 0, -14, +1, 11, 0, -7, 2, 5, 1, -2, +-1, -2, 1, 5, -2, -9, 0, 11, +1, -15, -1, 15, 0, -14, 2, 10, +2, -8, 0, 4, 3, -3, 1, -4, +-3, 9, 1, -13, 0, 13, -3, -12, +-1, 15, -2, -9, 3, 7, 4, -9, +1, 3, -2, 4, 0, -6, -2, 9, +-1, -11, -2, 14, 0, -13, 1, 13, +3, -13, -1, 11, -1, -4, 1, 1, +-3, 4, 0, -8, 0, 9, 2, -14, +-1, 14, 0, -12, 2, 11, -3, -6, +3, 4, 1, -4, -3, 1, -1, 4, +-3, -6, 0, 8, -1, -11, 2, 11, +-1, -9, 0, 11, 2, -9, 0, 6, +-3, 0, -1, -2, 1, 2, -1, -8, +0, 9, 2, -12, 4, 8, 2, -11, +1, 9, 3, -9, -2, 6, -3, 0, +-1, -2, -2, 6, -1, -7, -1, 10, +2, -11, 1, 10, 2, -10, 3, 6, +3, -8, -1, 3, -4, 3, -4, -1, +-2, 6, -2, -5, 2, 7, 3, -11, +2, 9, 1, -8, 1, 5, -2, -3, +-2, 3, -2, 1, -2, -3, -2, 7, +2, -8, 1, 9, 1, -7, 1, 8, +2, -8, 0, 5, -3, -2, -1, 0, +-1, 1, -1, -3, 2, 3, 3, -8, +1, 8, 1, -6, 0, 8, -2, -3, +-2, 5, -1, -3, -1, 0, -2, 2, +1, -4, -2, 7, 4, -8, 5, 3, +4, -9, 0, 7, -1, -5, -1, 3, +-2, -2, 0, -1, -4, 5, -1, -2, +2, 4, 2, -5, 1, 6, 0, -4, +-2, 6, 0, -4, -5, 6, -1, -3, +1, -2, 3, -1, 4, -5, 2, 3, +3, -5, 1, 5, 0, -4, -1, 4, +-2, -3, -1, 1, 1, -2, 0, -1, +3, -1, 3, -4, 2, 3, -1, -1, +-2, 7, -1, -3, 0, 2, -3, -1, +0, 0, -2, 1, 1, -2, 3, 0, +1, -1, 2, 2, 3, -5, 1, 3, +-1, -3, -3, 4, -5, 1, 0, 0, +0, 0, 1, -1, 3, 0, 1, -2, +2, 1, 3, -5, -2, 5, -6, 2, +-2, 2, -2, 0, -1, 1, 1, -1, +1, 0, 2, 0, 4, -4, -2, 5, +-1, -2, 1, 0, -3, 0, 0, -1, +-1, 0, -2, 2, 2, -1, 0, 1, +2, 1, 0, 0, 1, 1, -2, 0, +-1, 2, 1, -4, -2, 2, 2, -4, +1, 1, -1, 1, 2, -2, 2, 0, +0, -2, 2, 0, -3, 1, -2, 1, +0, -3, -2, 3, -1, -1, -1, 2, +1, 0, 4, -3, -1, 2, -1, 0, +0, 1, -2, -1, -4, 5, 0, -2, +-1, 2, -1, 0, 2, 0, 3, -2, +2, -1, 0, 1, 2, -3, -1, 1, +0, -2, -2, 3, -2, 0, -1, 2, +0, -1, 2, 0, 1, -1, 3, -3, +1, 0, -1, -2, 2, -2, -1, 0, +-3, 3, -1, -1, 0, 1, 2, -2, +2, -1, 0, 1, 0, -1, 1, -1, +-3, 1, -1, 1, 2, -4, 1, 1, +0, 0, -2, 3, 2, -3, 2, -1, +2, -1, 1, -2, -1, 1, 0, -1, +1, -1, 2, -3, 3, -1, 1, -1, +1, -1, 0, 0, -1, 1, -2, 2, +-1, 0, -1, 2, -4, 2, 2, -1, +0, 0, 1, 0, 0, -1, 3, -2, +4, -3, -1, 1, 2, -2, 2, -2, +2, -2, 2, -2, -1, 2, 0, 0, +0, 1, 0, 0, 1, 0, -1, 0, +-2, 2, -1, 1, 1, -2, -3, 3, +0, -1, -1, 2, -1, 1, 1, 0, +1, -2, 2, -2, -2, 1, 1, -1, +-1, 1, 0, 0, -2, 2, -2, 2, +2, -1, 1, 0, -1, 2, -2, 1, +3, -2, -3, 4, 0, -1, 1, 0, +0, 1, 1, -1, 2, -1, 2, -1, +2, -1, 1, -1, 0, 1, 0, 0, +-1, 1, 0, 1, 0, 0, -1, 2, +-1, 1, 0, 2, -2, 2, 2, -1, +4, -3, 2, 0, 2, 0, 1, 0, +3, 0, 0, 0, 3, 0, 2, 0, +1, 2, 2, -1, 3, 0, 2, 0, +0, 3, 0, 2, 3, -1, 3, 1, +4, -3, 4, 1, 3, -1, 3, 1, +2, 0, 3, 1, 2, 1, 3, 0, +6, -2, 4, 0, 5, 0, 8, -5, +8, -2, 6, -4, 7, 0, 4, -1, +5, 1, 5, 0, 3, 2, 4, 2, +6, -1, 5, 3, 6, -3, 6, 2, +3, 1, 8, 0, 6, -1, 5, 2, +6, 0, 10, -4, 10, -1, 7, -1, +7, 2, 7, -2, 5, 5, 7, -2, +9, 2, 5, 1, 11, -2, 10, -2, +9, 0, 10, 1, 9, -2, 11, 1, +7, 0, 8, 3, 9, -1, 11, 1, +9, -1, 10, 1, 9, 1, 11, 0, +11, 2, 9, 1, 11, 1, 14, -6, +12, 2, 9, 2, 12, 2, 14, -3, +11, 2, 12, 1, 10, 2, 13, 2, +12, -2, 14, 0, 13, -2, 13, 3, +15, -2, 13, 3, 16, -3, 14, 1, +12, 4, 15, 0, 16, 2, 14, -2, +13, 4, 15, -1, 17, 3, 15, 0, +14, 3, 16, -1, 19, -3, 20, 0, +15, 2, 17, 1, 19, -6, 18, 2, +17, -1, 14, 8, 16, 0, 19, -1, +20, -3, 21, -1, 18, 4, 20, -3, +21, -1, 21, -6, 20, 3, 19, 1, +21, 4, 19, -2, 23, -3, 20, 1, +22, 0, 21, 4, 18, 0, 20, 1, +19, -1, 22, 4, 23, 0, 25, -1, +23, -3, 20, 1, 24, 1, 23, 2, +23, 2, 26, -8, 25, -3, 24, -2, +22, 7, 28, -4, 26, -1, 25, -4, +24, 1, 26, 2, 25, 2, 24, 2, +23, -4, 25, 1, 26, 0, 26, 6, +26, -1, 27, -3, 29, -5, 26, 2, +29, 3, 25, 1, 24, 1, 27, -6, +27, 4, 26, 2, 29, 4, 28, -3, +26, -1, 29, -3, 29, 2, 25, 8, +29, -5, 31, -5, 28, -4, 26, 8, +30, 1, 31, 1, 28, -4, 28, -1, +29, 3, 29, 4, 31, 2, 27, -4, +28, 0, 29, -2, 32, 5, 31, 0, +28, 2, 31, -8, 31, 0, 26, 9, +28, 4, 30, 2, 27, -5, 29, 1, +30, 1, 30, 10, 30, -1, 31, -3, +34, -8, 32, 2, 31, 6, 31, 0, +31, -2, 30, -7, 31, 3, 33, 1, +31, 8, 33, -7, 34, -6, 33, -3, +31, 5, 35, 4, 31, -3, 32, -3, +31, -5, 31, 8, 32, 3, 31, 5, +35, -11, 33, -4, 30, 4, 30, 7, +33, 4, 32, -7, 31, -2, 33, -5, +32, 10, 35, -2, 34, 0, 33, -9, +33, -1, 31, 7, 32, 4, 31, 2, +32, -10, 33, 0, 33, -1, 32, 11, +30, 1, 31, -2, 33, -7, 36, -2, +32, 8, 31, 1, 31, -1, 31, -9, +30, 5, 33, 1, 33, 8, 29, -3, +35, -7, 33, -4, 31, 6, 30, 9, +31, -4, 32, -3, 29, -4, 31, 7, +33, 2, 31, 6, 31, -8, 30, -1, +30, 2, 33, 3, 33, 4, 28, -6, +31, -3, 32, -3, 29, 10, 32, 0, +30, 2, 31, -8, 28, 1, 30, 3, +30, 5, 30, 3, 26, -8, 31, -2, +32, -1, 27, 12, 31, -5, 31, -5, +32, -6, 30, 0, 28, 5, 28, 4, +29, -3, 26, -6, 25, 5, 30, 0, +30, 11, 28, -8, 27, -4, 31, -2, +29, 1, 24, 9, 29, -3, 27, -5, +28, -4, 26, 3, 26, 3, 30, 8, +26, -12, 23, -2, 29, 2, 25, 4, +25, 7, 24, -6, 26, -5, 29, -2, +22, 5, 26, 1, 29, 4, 22, -8, +20, -1, 29, 1, 24, 7, 23, 0, +23, -8, 22, 0, 30, -4, 20, 12, +18, -2, 31, -3, 24, -2, 15, -5, +25, 8, 20, 11, 16, -4, 23, -1, +19, -1, 25, -3, 22, 16, 14, -12, +23, 3, 23, 8, 15, -12, 20, 12, +27, 0, 21, -12, 19, 4, 23, -9, +22, 2, 22, 13, 14, -16, 22, 0, +25, 6, 13, -4, 15, 6, 23, -3, +18, 0, 18, -4, 15, 0, 17, 7, +23, 0, 10, -4, 15, 0, 28, 0, +10, 10, 9, -7, 22, -4, 14, 11, +13, -4, 12, 5, 14, 0, 23, -3, +9, 4, 4, -4, 25, 9, 12, 9, +2, -14, 22, 0, 20, 2, 9, 2, +15, 3, 11, -11, 17, 7, 18, -1, +3, -10, 17, 14, 22, 1, -4, -11, +12, -1, 27, 4, 0, 13, 9, -4, +19, -14, 9, 6, 16, 2, 2, 3, +7, -3, 29, 3, -3, -1, 3, -21, +27, 19, 6, 11, 2, -16, 12, 2, +10, -6, 15, 3, 1, 15, 5, -22, +27, 7, 1, 7, -4, -26, 21, 19, +12, 14, -2, -16, 5, -4, 13, -3, +12, 9, 0, 8, 5, -17, 16, 4, +10, 3, -6, -11, 9, 1, 24, 17, +-8, -3, -3, -23, 21, 8, 4, 10, +2, -1, 8, -7, 4, -10, 18, 10, +-8, 2, -8, -16, 35, 25, -8, 1, +-12, -32, 29, 11, -4, 10, -3, 6, +7, -2, -6, -15, 23, 14, 0, -1, +-18, -17, 31, 22, 0, 6, -17, -25, +20, -2, 0, 18, 3, 4, 0, -11, +-4, -3, 22, 5, -7, 4, -13, -8, +24, 0, -2, 24, -6, -20, 6, -21, +1, 31, 11, 3, -12, -12, -4, 4, +26, -6, -13, 14, -10, -10, 15, -6, +2, 32, 0, -24, -5, -18, 7, 21, +16, 0, -15, 0, 1, -10, 14, -3, +-7, 21, -2, -21, -1, -1, 11, 30, +7, -22, -26, -10, 16, 8, 18, 13, +-27, 0, 14, -16, 11, 1, -12, 7, +12, -4, -15, -1, 6, 10, 22, 10, +-33, -30, 11, -8, 25, 47, -27, -26, +7, -12, 14, 18, -9, -23, 5, 17, +-6, 2, 2, -13, 12, 32, -16, -28, +-4, -19, 16, 52, -3, -12, -11, -20, +7, 8, 15, -1, -14, 2, -7, 1, +17, 11, -6, -3, -4, -11, 7, -4, +-4, 5, 10, 28, -7, -14, -14, -30, +25, 39, -5, -10, -19, -21, 23, 39, +2, -22, -12, -11, 9, 11, -3, -7, +0, 30, 4, -12, -11, -26, 8, 25, +8, 0, -18, -3, 0, 11, 13, 0, +-14, 9, -8, -24, 13, 16, -1, 30, +-7, -33, -3, 9, 3, 9, -1, -9, +-10, 28, -1, -13, 6, -6, -7, 34, +-8, -38, 0, 12, 0, 45, -4, -30, +-17, 2, 4, 14, 10, -4, -26, 14, +3, 1, 14, -3, -26, 12, 5, -6, +-4, 4, -20, 20, 21, 7, -23, -17, +-17, 3, 34, 23, -36, -2, -16, 3, +28, 15, -34, 0, -4, -6, 9, 12, +-25, 14, 7, 1, -7, 3, -24, -3, +12, 2, -8, 32, -28, -12, 5, -6, +0, 37, -26, -24, -11, 2, 4, 44, +-21, -14, -16, -8, 3, 31, -28, -17, +-3, 17, -8, 43, -42, -44, 10, 35, +-10, 33, -50, -55, 13, 61, -8, 26, +-53, -58, 14, 61, -20, 3, -42, -29, +20, 82, -50, -48, -10, -1, 14, 78, +-71, -75, 10, 49, -11, 57, -57, -75, +7, 70, -27, -3, -26, -35, -7, 102, +-50, -67, -5, 12, -13, 92, -67, -98, +8, 80, -31, 40, -53, -86, 10, 116, +-69, -43, -7, -17, -9, 130, -92, -115, +31, 61, -39, 70, -81, -107, 28, 122, +-65, -16, -41, -37, -1, 107, -85, -70, +5, 35, -36, 74, -75, -76, 16, 57, +-65, 34, -39, -45, -27, 74, -70, 2, +-6, -4, -67, 55, -49, -33, -6, 47, +-91, 34, -25, -19, -31, 47, -88, -8, +7, 35, -80, 21, -71, -14, 23, 71, +-121, -15, -35, -2, -8, 71, -112, -22, +-12, 31, -58, 29, -74, -22, -13, 67, +-92, -2, -55, -1, -21, 71, -96, -24, +-44, 25, -50, 41, -78, -5, -39, 57, +-92, -13, -42, 24, -50, 51, -101, -14, +-35, 36, -71, 25, -67, 26, -69, -1, +-69, 36, -51, 35, -78, -9, -77, 65, +-66, -27, -42, 49, -102, 35, -70, -27, +-37, 77, -102, -7, -73, 28, -56, 10, +-77, 45, -93, 23, -52, -4, -85, 51, +-76, -10, -56, 65, -121, -17, -38, 45, +-83, 35, -109, -8, -49, 55, -85, -15, +-82, 75, -85, -23, -77, 41, -77, 30, +-83, 2, -89, 62, -72, -38, -89, 104, +-89, -31, -78, 30, -104, 63, -48, -23, +-121, 76, -80, -45, -45, 85, -148, 4, +-46, 2, -88, 78, -113, -45, -54, 83, +-106, 2, -100, -3, -66, 88, -91, -11, +-119, -4, -60, 93, -88, -23, -118, 27, +-73, 78, -74, -78, -110, 131, -80, -37, +-84, -13, -109, 160, -59, -128, -140, 121, +-63, 29, -74, -64, -137, 156, -46, -78, +-133, 43, -46, 98, -133, -70, -96, 69, +-19, 52, -196, -29, -10, 50, -112, 37, +-129, -11, -23, 70, -164, 14, -64, -18, +-64, 107, -130, -35, -99, 16, -35, 103, +-133, -72, -112, 83, -20, 35, -156, -50, +-65, 131, -75, -45, -130, 3, -50, 132, +-102, -86, -114, 56, -43, 84, -112, -75, +-123, 111, -22, 3, -147, -31, -66, 134, +-74, -67, -137, 40, -11, 97, -166, -85, +-38, 108, -83, 9, -152, -30, 19, 133, +-187, -82, -47, 70, -39, 75, -188, -83, +5, 123, -102, -17, -135, 10, -2, 69, +-136, -28, -87, 62, -16, 10, -164, 18, +-28, 19, -60, 38, -146, 7, -6, 19, +-123, 55, -72, -27, -51, 82, -121, -37, +-36, 61, -99, 38, -74, -48, -76, 127, +-72, -88, -68, 123, -100, -44, -38, 17, +-94, 121, -70, -158, -64, 227, -89, -135, +-37, 75, -108, 91, -51, -158, -48, 241, +-119, -158, -19, 117, -97, 7, -63, -33, +-38, 125, -125, -126, 4, 181, -108, -115, +-75, 96, -11, 16, -121, -51, -33, 155, +-64, -135, -90, 155, -27, -75, -73, 66, +-83, 12, -16, -27, -87, 123, -81, -132, +2, 184, -115, -127, -40, 102, -28, 31, +-121, -99, 6, 204, -84, -172, -75, 153, +-1, -44, -109, 10, -27, 71, -40, -77, +-84, 132, -27, -107, -58, 129, -64, -74, +-26, 59, -82, 37, -21, -70, -61, 133, +-61, -117, -15, 136, -87, -79, -19, 57, +-52, 34, -56, -78, -32, 151, -54, -138, +-55, 155, -37, -75, -44, 25, -69, 80, +4, -116, -92, 166, -25, -117, -18, 80, +-99, 12, 17, -37, -91, 82, -19, -48, +-35, 59, -81, -41, 22, 72, -115, -30, +12, 12, -47, 62, -84, -76, 34, 92, +-98, -36, -16, -7, -10, 66, -86, -44, +-9, 5, -23, 86, -91, -101, 13, 105, +-49, -22, -68, -53, 15, 153, -85, -168, +-3, 150, -46, -49, -36, -41, -31, 135, +-44, -143, -14, 126, -62, -43, -7, -12, +-50, 58, -12, -38, -65, 13, 8, 22, +-43, 13, -90, -64, 91, 140, -162, -144, +35, 84, 18, 61, -171, -195, 133, 270, +-133, -198, -29, 40, 64, 149, -149, -242, +52, 228, -54, -91, -37, -49, -20, 140, +-24, -110, -31, 22, -43, 74, 12, -80, +-82, 19, 17, 96, -41, -160, -38, 147, +12, -58, -66, -49, 2, 134, -28, -149, +-57, 141, 26, -117, -45, 103, -71, -68, +102, -14, -167, 152, 49, -270, 32, 307, +-185, -198, 151, -17, -94, 249, -93, -380, +141, 353, -167, -169, 14, -61, 60, 232, +-140, -272, 48, 200, 8, -81, -110, -11, +69, 33, -38, -9, -73, -14, 70, -10, +-84, 87, -10, -164, 33, 171, -99, -81, +68, -69, -79, 209, 0, -278, 36, 243, +-108, -148, 68, 39, -31, 42, -72, -93, +85, 106, -76, -112, -40, 86, 102, -21, +-147, -79, 49, 166, 50, -193, -172, 146, +152, -56, -71, -34, -93, 68, 186, -63, +-234, 50, 139, -73, -3, 114, -162, -145, +208, 109, -176, -7, 29, -118, 92, 192, +-175, -182, 146, 68, -58, 74, -80, -184, +152, 201, -156, -136, 70, 20, 8, 80, +-62, -130, 51, 109, -11, -68, -31, 26, +29, -24, -5, 45, -37, -54, 47, -3, +-19, 111, -31, -221, 59, 233, -53, -102, +5, -134, 71, 338, -121, -389, 122, 208, +-25, 95, -92, -373, 176, 445, -139, -296, +37, 14, 89, 204, -119, -260, 68, 152, +60, 0, -142, -86, 158, 52, -55, 25, +-22, -80, 54, 48, 24, 26, -81, -80, +114, 42, -30, 38, -35, -118, 93, 115, +-29, -52, -30, -51, 112, 106, -60, -126, +-7, 103, 108, -98, -75, 96, 38, -109, +51, 60, 0, 4, -42, -86, 126, 100, +-76, -59, 17, -28, 111, 80, -115, -102, +113, 64, -8, -38, 5, 10, 19, -1, +33, -66, 49, 165, -107, -296, 222, 329, +-164, -221, 68, -41, 152, 297, -222, -442, +241, 349, -52, -114, -67, -165, 189, 281, +-108, -224, 69, 6, 31, 178, 21, -270, +18, 199, -11, -84, 143, -42, -176, 106, +226, -152, -84, 160, -9, -191, 173, 177, +-148, -164, 156, 96, -47, -59, 78, 19, +-24, -36, 64, 13, 39, 0, -28, -59, +96, 59, 7, -77, -6, 57, 84, -102, +29, 134, -73, -189, 215, 150, -157, -86, +136, -28, 17, 49, 16, -29, 22, -73, +68, 67, 31, 10, -56, -196, 197, 283, +-132, -258, 102, 56, 82, 120, -62, -233, +58, 140, 159, -14, -192, -122, 238, 68, +-28, 37, -75, -180, 230, 183, -158, -122, +169, -26, -37, 68, 86, -111, -23, 87, +100, -158, -2, 193, 37, -252, 62, 151, +11, -25, 73, -159, -44, 177, 182, -125, +-136, -48, 163, 110, 3, -120, -2, -20, +96, 93, 40, -194, -22, 155, 103, -149, +53, 71, -96, -68, 266, -10, -193, 14, +206, -78, -46, 56, 52, -107, 84, 128, +-61, -256, 193, 260, -118, -227, 159, -25, +11, 227, -11, -400, 111, 308, 35, -152, +-60, -87, 212, 124, -113, -101, 112, -42, +48, 16, 8, 34, 68, -174, 1, 117, +140, -1, -136, -232, 267, 252, -146, -166, +122, -132, 101, 286, -90, -344, 169, 105, +-24, 115, 58, -318, 36, 235, 69, -91, +-8, -145, 111, 155, -13, -103, 68, -125, +77, 189, -13, -203, 86, -15, 39, 152, +29, -258, 33, 87, 131, 93, -131, -317, +275, 258, -153, -119, 136, -178, 84, 249, +-40, -225, 81, -37, 96, 150, -21, -197, +41, -25, 166, 151, -132, -227, 171, 16, +55, 131, -39, -254, 70, 45, 206, 183, +-249, -440, 294, 327, 32, -68, -177, -365, +344, 512, -102, -493, -45, 177, 287, 21, +-128, -176, 8, 55, 299, 4, -250, -111, +231, -6, 26, 61, 1, -190, 63, 124, +91, -121, 0, 22, 48, -78, 96, 44, +7, -111, 53, 39, 62, -72, 95, -20, +-89, 5, 222, -126, -5, 125, -87, -207, +300, 81, -88, -2, -82, -203, 400, 206, +-284, -184, 134, -54, 275, 146, -317, -222, +291, 47, 92, 59, -195, -212, 259, 104, +79, -15, -207, -193, 353, 172, -88, -140, +-26, -90, 258, 150, -133, -211, 113, 32, +101, 74, -24, -248, 73, 172, 95, -97, +-6, -163, 85, 255, 36, -339, 70, 152, +61, -18, -22, -216, 195, 205, -82, -189, +70, -10, 188, 32, -155, -62, 166, -133, +156, 195, -241, -256, 319, 47, 39, 117, +-265, -339, 515, 294, -282, -217, 68, -28, +314, 68, -287, -82, 225, -121, 138, 170, +-201, -198, 238, -49, 99, 230, -237, -452, +417, 377, -231, -249, 162, -56, 74, 154, +-29, -214, 108, 35, 31, 23, 45, -84, +23, -96, 125, 192, -82, -314, 210, 163, +-129, -17, 195, -223, -9, 200, -22, -124, +180, -140, -31, 211, -8, -240, 186, 22, +-48, 113, -29, -301, 325, 234, -330, -172, +323, -40, 11, 95, -160, -172, 321, 50, +-110, 0, -18, -121, 240, 46, -118, -2, +34, -176, 232, 169, -213, -142, 201, -81, +62, 173, -117, -258, 219, 108, -79, -15, +95, -122, 13, 51, 58, -19, 33, -107, +46, 49, 12, -26, 85, -98, -11, 75, +54, -116, 87, 64, -103, -137, 248, 113, +-167, -158, 168, 38, -23, 29, 67, -161, +-10, 108, 88, -65, 8, -73, 6, 24, +128, 30, -92, -203, 126, 201, 32, -151, +-62, -65, 136, 153, 36, -207, -111, 39, +240, 73, -119, -175, 49, 20, 130, 162, +-120, -368, 144, 301, -14, -125, 29, -170, +1, 240, 131, -185, -118, -72, 137, 203, +18, -236, -88, 32, 227, 139, -178, -285, +160, 176, -1, -19, -13, -217, 47, 287, +47, -286, -14, 110, 59, -5, -3, -100, +43, 40, 24, 34, -14, -198, 94, 250, +-41, -299, 51, 204, 40, -141, -25, 47, +43, -94, 75, 166, -117, -303, 172, 287, +-39, -202, -55, -4, 176, 84, -108, -79, +51, -106, 67, 248, -33, -323, -42, 193, +237, -28, -280, -132, 229, 52, 42, 129, +-234, -369, 344, 399, -221, -264, 96, -63, +66, 324, -99, -457, 101, 349, 5, -153, +-58, -50, 123, 74, -83, -22, 95, -115, +-50, 192, 28, -272, 76, 254, -84, -191, +52, 26, 72, 72, -87, -69, 52, -97, +67, 238, -84, -291, 62, 148, 30, 68, +-43, -257, 26, 213, 86, 25, -142, -356, +149, 476, -5, -329, -148, -2, 245, 232, +-147, -257, -17, 53, 180, 152, -162, -251, +55, 142, 79, 50, -76, -226, 2, 266, +89, -221, -72, 128, 21, -76, 53, 40, +-61, -70, 82, 119, -106, -144, 160, 54, +-156, 105, 118, -288, -9, 402, -107, -423, +178, 308, -100, -92, -77, -107, 234, 101, +-216, 126, 63, -380, 100, 403, -122, -195, +55, -82, 35, 221, -40, -216, -44, 109, +204, 18, -319, -89, 262, 24, -34, 160, +-204, -265, 240, 140, -65, 143, -122, -335, +128, 291, 29, -88, -188, -95, 230, 171, +-184, -129, 123, 2, -92, 152, 99, -232, +-146, 185, 188, -72, -166, 20, 70, -69, +-5, 145, 50, -137, -173, 39, 203, 85, +-77, -138, -123, 98, 198, 4, -127, -50, +-10, 22, 32, 54, 61, -71, -220, 44, +291, -22, -230, 75, 43, -171, 127, 266, +-175, -299, 22, 259, 205, -118, -357, -52, +271, 169, -49, -130, -188, 23, 262, 48, +-213, 0, 107, -102, -65, 211, 59, -291, +-93, 365, 80, -367, -68, 313, 22, -196, +-28, 86, 70, 14, -166, -83, 182, 123, +-93, -89, -109, 30, 240, 8, -239, 24, +89, -66, 36, 82, -107, -12, 55, -72, +11, 132, -95, -89, 108, -20, -101, 136, +36, -113, -15, -47, -16, 259, 34, -362, +-116, 339, 132, -212, -87, 79, -35, 35, +67, -89, -30, 99, -63, -73, 83, 81, +-96, -130, 70, 194, -50, -189, -82, 165, +197, -181, -234, 287, 79, -364, 55, 358, +-103, -269, 14, 220, 18, -222, -32, 216, +28, -116, -134, 0, 206, 44, -210, -22, +101, 40, -72, -112, 75, 189, -127, -184, +62, 186, -6, -240, -57, 334, 6, -340, +25, 278, -68, -236, 21, 284, 4, -303, +-74, 210, 74, -22, -103, -107, 70, 156, +-79, -164, 21, 197, 10, -207, -96, 203, +70, -184, -29, 211, -70, -230, 26, 238, +48, -214, -161, 212, 101, -197, -24, 184, +-54, -145, -35, 98, 94, 1, -125, -132, +24, 253, -8, -273, 14, 216, -70, -130, +-45, 101, 154, -89, -236, 83, 101, -49, +14, 52, -106, -71, 41, 98, -26, -74, +-36, 37, 19, 5, -68, 17, -12, -7, +53, -69, -126, 227, 48, -322, -29, 284, +1, -153, -85, 130, 55, -213, -64, 276, +21, -177, -94, 47, 53, -19, -20, 126, +-85, -157, 25, 53, -2, 76, -18, -78, +-121, 29, 138, -10, -110, 65, -33, -108, +0, 149, 56, -210, -196, 293, 164, -223, +-157, 23, 86, 149, -130, -122, 85, -22, +-97, 140, -13, -120, 55, 74, -173, -10, +141, -113, -118, 309, -19, -380, -5, 218, +60, 85, -240, -201, 229, 30, -164, 227, +-29, -257, 7, 86, 58, 123, -248, -148, +218, 65, -142, 13, -68, -44, 99, 122, +-114, -160, -29, 90, 35, 116, -50, -249, +-125, 171, 198, 75, -282, -166, 136, 69, +-74, 73, -3, -25, -129, -147, 160, 255, +-229, -114, 133, -85, -141, 166, 49, -65, +-79, -66, 41, 126, -148, -30, 94, -93, +-35, 184, -172, -154, 161, 12, -106, 138, +-63, -67, -54, -162, 194, 378, -380, -348, +264, 100, -153, 167, -16, -200, -74, 91, +131, 51, -277, -89, 185, 37, -85, 71, +-177, -113, 225, 135, -257, -85, 95, 54, +-107, -63, 76, 121, -176, -129, 110, 131, +-156, -81, 107, 27, -172, 29, 62, -71, +-40, 128, -87, -109, 43, 91, -124, -65, +122, 58, -255, -60, 223, 84, -266, -69, +194, 94, -295, -110, 249, 96, -247, 6, +32, -104, 6, 167, -29, -65, -167, -67, +156, 107, -113, 0, -166, -111, 262, 170, +-350, -91, 196, 12, -150, 0, 48, 65, +-190, -146, 241, 234, -342, -176, 154, 37, +-57, 109, -56, -108, -125, -23, 132, 197, +-105, -138, -183, -54, 240, 210, -237, -151, +12, -61, -11, 251, 1, -180, -165, -19, +154, 175, -219, -161, 102, 48, -108, 53, +-11, -10, -52, -21, -3, 10, -34, 35, +-139, -19, 164, -45, -242, 172, 94, -204, +-82, 186, -6, -143, -77, 103, 9, -31, +-108, -14, 147, 81, -324, -95, 220, 83, +-84, -56, -209, 62, 166, -47, -83, 122, +-131, -185, 34, 221, 18, -180, -117, 115, +-84, -68, 129, 180, -148, -239, -134, 153, +234, 85, -287, -280, 58, 336, -15, -233, +-9, 195, -165, -223, 88, 244, 3, -197, +-231, 168, 141, -127, -65, 137, -74, -77, +-113, -6, 201, 57, -256, -24, 8, -11, +58, 109, -72, -170, -142, 154, 111, -13, +-76, -152, -83, 252, -21, -151, 29, 42, +-65, -22, -159, 89, 217, -111, -254, 93, +46, -33, -19, 86, -11, -171, -126, 153, +49, 19, -41, -134, -81, 84, 28, 197, +-114, -400, 104, 299, -180, 57, 26, -302, +21, 279, -82, -17, -106, -132, 127, 95, +-145, -15, -23, 53, -2, -68, -38, 23, +-37, 78, -54, -33, 32, -164, -104, 311, +44, -206, -93, 53, 5, 34, -44, -36, +65, 59, -231, -75, 191, 15, -127, 124, +-34, -56, -85, -176, 110, 331, -84, -211, +-157, 12, 127, 72, 11, 3, -193, -38, +-2, 36, 169, -108, -221, 227, 17, -111, +-38, -172, 165, 336, -324, -171, 173, -83, +-32, 120, -76, 48, -22, -90, -2, 54, +-74, -122, 84, 280, -155, -245, -46, 16, +204, 176, -276, -131, 86, 52, -64, -90, +109, 114, -168, 59, -18, -184, 137, 64, +-121, 200, -57, -298, 43, 223, 23, -173, +-100, 240, -23, -189, 30, 33, -30, -10, +-70, 175, 32, -210, -148, -14, 210, 329, +-262, -375, 125, 187, -84, -12, 78, -24, +-75, 30, -71, 57, 153, -243, -105, 363, +-27, -225, -13, -24, 67, 87, -73, 77, +-58, -90, -63, -112, 223, 197, -321, 12, +93, -143, 28, -41, 2, 299, -158, -255, +144, 36, -84, -13, 64, 184, -62, -145, +-63, -94, 193, 200, -141, -18, -32, -145, +16, 33, 118, 205, -177, -236, -18, 105, +51, -77, 61, 170, -259, -170, 153, 83, +-10, -73, -43, 207, -51, -250, 21, 68, +136, 137, -154, -109, 8, -50, 156, 154, +-117, -176, 21, 156, 51, -15, -143, -234, +200, 384, -189, -247, 15, 18, -4, -5, +68, 165, -196, -212, 72, 112, 99, -29, +-133, 16, -4, 38, 99, -142, 7, 147, +-52, 31, 35, -169, 70, 113, -41, 28, +5, -56, 38, -34, -89, 75, 86, 80, +-77, -305, -34, 366, 10, -217, 24, 10, +-99, 108, -5, -104, 128, 64, -132, -45, +96, 45, -82, -37, 167, 25, -63, 5, +11, 28, 17, -105, 95, 95, -56, 21, +-43, -100, 39, 34, 69, 95, -190, -120, +30, 33, 102, 36, -104, -41, -78, 21, +73, 25, 80, -36, -113, -61, 78, 234, +-35, -300, 231, 158, -225, 104, 109, -257, +170, 195, -188, -5, 63, -140, 54, 121, +-47, 2, -15, -81, -22, 67, -94, -92, +182, 161, -178, -121, -54, -48, 223, 157, +-138, -57, -16, -110, 182, 132, -43, -87, +-1, 122, 86, -170, 23, 72, 34, 56, +-65, 39, 73, -334, -14, 478, -66, -240, +55, -133, -73, 227, -27, -61, 53, -25, +-83, -125, 60, 246, 14, -117, -58, -40, +163, -104, -79, 368, 128, -366, -16, 98, +34, 29, 89, 126, -77, -306, 99, 257, +-88, -83, 62, -18, -87, 91, 0, -211, +75, 276, -174, -207, 33, 94, 153, -88, +-201, 158, 128, -160, 34, 43, 29, 34, +-35, -6, 136, -16, 23, -39, -5, 85, +-14, -53, 114, -12, -8, -9, -123, 67, +83, -88, 27, 125, -160, -234, 58, 267, +41, -116, -87, -101, 6, 186, 17, -153, +150, 130, -144, -112, 56, -6, 200, 98, +-87, 21, -44, -232, 243, 280, -146, -200, +42, 187, 11, -249, 2, 168, 16, 32, +-123, -63, 28, -155, 80, 255, -110, -33, +-49, -248, 166, 231, -95, -13, 29, -54, +85, -82, -9, 126, 87, -2, -16, -7, +18, -223, 125, 395, -44, -296, -87, 76, +111, -13, 1, 61, -92, 5, -51, -135, +113, 90, -70, 87, -52, -161, 27, 25, +116, 130, -86, -113, -45, -60, 249, 170, +-97, -93, -8, -103, 120, 212, -10, -131, +40, -8, -45, -30, 46, 191, -10, -229, +-31, 84, 0, 38, 3, -14, -45, -67, +30, 26, -26, 94, -10, -111, 84, 13, +-29, 52, 2, -2, 85, -115, 18, 140, +50, -51, -82, -19, 132, -21, 13, 93, +-94, -123, 65, 103, 7, -66, -34, -5, +-24, 107, -23, -151, 85, 66, -49, 16, +-103, 33, 171, -128, 5, 121, -87, -15, +57, -57, 128, 24, -45, 6, -28, 40, +39, -80, 146, 27, -165, 41, -28, -11, +198, -116, -128, 199, -98, -128, 116, 10, +26, -19, -101, 84, 32, -40, 53, -113, +48, 153, -89, -1, 106, -161, 30, 134, +-3, 21, 11, -123, -1, 112, 112, -35, +-127, -46, 40, 79, 37, -56, -54, -14, +12, 87, -36, -134, 18, 147, 22, -110, +-57, 10, 49, 98, 66, -140, -56, 84, +61, 11, 52, -107, 17, 115, -19, -50, +70, -12, -14, 8, -11, 20, 15, 6, +-3, -42, -36, -7, -34, 83, 104, -37, +-196, -87, 172, 93, -109, 34, 28, -94, +64, 7, -37, 93, 27, -99, 148, 74, +-179, -124, 195, 119, 40, 34, -170, -222, +202, 242, -89, -93, 17, -48, -39, 57, +35, -20, -72, 15, 69, 15, -151, -110, +151, 140, -61, -29, -78, -137, 151, 189, +-37, -90, 4, -45, 67, 82, 32, -30, +-1, -93, 92, 170, -80, -108, 93, -55, +-18, 122, -32, -11, -18, -114, 72, 63, +-140, 93, 69, -142, -35, 47, -41, -3, +63, 78, -70, -143, 48, 98, 47, -39, +-22, 51, 44, -96, 59, 61, -31, 4, +120, -7, -101, -23, 107, -21, 20, 116, +-105, -156, 60, 82, 65, 5, -192, -5, +130, -51, -73, 86, -31, -117, 62, 181, +-102, -216, 104, 116, -25, 59, 2, -154, +64, 69, 15, 40, -13, -62, 147, 15, +-173, 21, 184, -58, 7, 110, -154, -132, +148, 53, 0, 61, -121, -80, 45, -8, +7, 79, -25, -70, -19, 17, -85, 7, +204, 13, -155, -32, -35, -16, 205, 94, +-66, -158, -81, 133, 174, -41, -25, -35, +-20, 42, 49, -39, -1, 49, 36, -27, +-57, -58, 35, 139, -15, -114, 6, -13, +-40, 89, 3, -56, 23, -4, -40, 1, +-3, 22, 49, 18, -43, -137, 44, 211, +29, -155, -56, 9, 100, 115, -9, -124, +-17, 24, 5, 76, 148, -83, -215, 31, +147, -7, 25, 46, -132, -74, 100, 31, +-19, 29, -61, -6, 55, -63, -5, 57, +-93, 54, 153, -166, -117, 131, 51, 21, +0, -135, 74, 92, -122, 0, 156, 8, +-77, -127, 71, 187, -42, -89, 35, -53, +66, 74, -111, -1, 98, -29, -11, -24, +-33, 78, -22, -81, 113, 85, -171, -132, +113, 141, -18, -66, -41, -4, 9, -50, +62, 153, -56, -162, -8, 33, 126, 71, +-107, -59, 56, 24, 38, -82, 12, 161, +-42, -126, 84, 2, -20, 24, -19, 111, +45, -233, -33, 179, 1, -46, 23, 7, +-73, -38, 50, -15, 4, 148, -92, -195, +108, 88, -67, -9, 27, 90, 14, -200, +4, 149, 32, 8, 9, -71, -1, -2, +43, 59, 41, -14, -71, -40, 59, 4, +60, 48, -118, -19, 40, -85, 65, 152, +-112, -128, -6, 59, 79, -12, -58, -18, +-72, 26, 144, -28, -89, 36, -16, -60, +135, 83, -103, -101, 44, 95, 111, -50, +-125, -7, 94, 22, 37, 21, -75, -44, +46, -3, 12, 66, -29, -30, -40, -66, +59, 61, -67, 88, -3, -209, 15, 140, +-24, 41, 2, -107, 16, -1, -2, 118, +2, -82, 40, -47, 2, 130, 6, -111, +47, 60, -7, -53, 6, 66, 31, -62, +-40, 46, 56, -42, -61, 34, 11, -15, +28, -2, -67, -40, 28, 88, 12, -72, +-86, -10, 107, 52, -56, 28, -14, -173, +53, 240, 51, -159, -125, 59, 138, -91, +16, 250, -78, -347, 27, 250, 129, -87, +-157, 96, 58, -287, 14, 396, 19, -250, +-102, 24, 60, -21, 30, 221, -83, -355, +24, 257, 16, -113, 33, 115, -105, -197, +118, 178, -30, -38, -1, -76, 12, 84, +50, -60, -61, 72, 90, -100, -57, 120, +24, -169, 15, 239, -2, -253, -48, 162, +58, -64, -33, 83, -46, -186, 67, 262, +-59, -262, 21, 228, -7, -205, 34, 177, +-90, -142, 169, 109, -177, -62, 137, -14, +-43, 114, 35, -197, -36, 215, 62, -184, +-25, 145, -27, -118, 91, 101, -140, -71, +149, 8, -111, 46, 45, -63, -57, 44, +112, -55, -175, 145, 134, -255, -64, 319, +19, -302, 1, 235, -20, -161, 55, 117, +-45, -82, 67, 41, -102, -2, 196, -36, +-193, 90, 115, -160, -51, 225, 106, -233, +-207, 203, 166, -177, -9, 194, -130, -221, +100, 189, -24, -109, 18, 33, -128, 22, +189, -78, -146, 159, 89, -227, -96, 281, +165, -365, -105, 471, -10, -511, 100, 368, +-4, -120, -112, -40, 120, 18, -10, 48, +-55, 29, -13, -214, 77, 321, -50, -287, +-56, 233, 41, -259, 72, 311, -197, -274, +193, 173, -108, -95, 59, 20, -37, 105, +62, -255, -83, 303, 152, -230, -144, 200, +44, -362, 159, 611, -274, -703, 239, 545, +-141, -293, 111, 140, -195, -101, 254, 38, +-231, 123, 100, -334, 1, 515, -68, -598, +99, 591, -138, -546, 197, 508, -219, -484, +236, 440, -225, -357, 261, 199, -242, 49, +170, -348, -22, 575, -97, -635, 177, 573, +-240, -545, 312, 586, -370, -614, 365, 535, +-365, -400, 359, 265, -329, -94, 183, -173, +33, 414, -179, -490, 242, 403, -314, -334, +503, 359, -644, -317, 604, 48, -384, 348, +240, -568, -252, 521, 284, -395, -133, 405, +-162, -507, 386, 488, -443, -269, 392, -52, +-374, 330, 345, -521, -267, 631, 169, -692, +-129, 675, 124, -565, -52, 380, -85, -157, +208, -63, -223, 254, 242, -391, -284, 435, +337, -397, -255, 304, 97, -186, -8, 51, +56, 80, -115, -169, 20, 218, 156, -277, +-270, 351, 243, -346, -204, 155, 244, 148, +-323, -362, 351, 322, -289, -129, 211, 6, +-150, -38, 112, 117, -67, -67, 21, -88, +68, 216, -183, -243, 302, 215, -342, -193, +325, 129, -302, -8, 316, -142, -327, 220, +264, -202, -148, 140, 22, -100, 64, 88, +-127, -70, 188, 25, -290, 42, 415, -35, +-505, -78, 505, 222, -389, -268, 247, 180, +-148, -39, 102, -60, -18, 133, -110, -272, +240, 486, -334, -667, 389, 731, -446, -636, +458, 415, -370, -128, 215, -189, -81, 459, +3, -659, 58, 816, -175, -935, 338, 953, +-461, -817, 496, 517, -432, -136, 341, -236, +-283, 533, 273, -694, -246, 738, 160, -767, +4, 814, -145, -777, 198, 550, -193, -189, +225, -119, -299, 278, 331, -390, -275, 526, +206, -587, -228, 428, 305, -135, -325, -60, +234, 55, -137, -10, 132, 85, -165, -218, +116, 243, 22, -103, -139, -82, 226, 191, +-317, -239, 468, 252, -558, -223, 517, 122, +-385, 9, 299, -128, -267, 222, 150, -272, +59, 273, -247, -231, 270, 181, -222, -140, +230, 93, -309, -35, 315, -2, -197, 9, +48, 19, 15, -64, -1, 151, -6, -249, +3, 311, -33, -269, 126, 131, -183, 31, +148, -181, -36, 319, -64, -460, 105, 560, +-145, -583, 221, 530, -349, -441, 443, 304, +-470, -58, 379, -292, -193, 651, -32, -876, +220, 890, -303, -746, 326, 583, -358, -458, +440, 293, -444, 13, 305, -435, -66, 792, +-148, -925, 275, 886, -389, -806, 498, 696, +-546, -470, 428, 132, -223, 181, 44, -381, +75, 517, -243, -670, 497, 792, -718, -775, +762, 621, -640, -390, 467, 151, -293, 113, +112, -386, 111, 575, -304, -605, 422, 506, +-471, -406, 507, 353, -574, -279, 589, 90, +-503, 206, 301, -478, -104, 587, -20, -520, +62, 378, -95, -242, 142, 64, -142, 201, +93, -465, -43, 561, 67, -486, -90, 421, +36, -456, 87, 431, -135, -184, 43, -167, +61, 382, -87, -428, 48, 520, -99, -717, +207, 802, -272, -584, 208, 198, -91, 50, +-3, -92, 59, 134, -106, -319, 166, 541, +-240, -607, 324, 493, -358, -300, 296, 108, +-130, 47, -21, -156, 85, 228, -138, -289, +232, 346, -327, -335, 293, 214, -179, -41, +72, -91, -31, 204, -76, -354, 291, 477, +-484, -433, 473, 221, -298, -5, 155, -74, +-113, 74, 49, -139, 166, 317, -449, -486, +615, 531, -607, -422, 515, 234, -436, -63, +337, -60, -152, 171, -119, -324, 322, 470, +-382, -484, 329, 317, -305, -117, 353, 40, +-382, -78, 292, 55, -88, 85, -96, -231, +190, 253, -195, -180, 142, 121, -52, -61, +-57, -40, 123, 138, -118, -129, 80, 13, +-71, 103, 38, -155, 64, 188, -219, -228, +273, 229, -212, -129, 119, -17, -130, 131, +184, -208, -160, 315, 18, -449, 139, 524, +-210, -481, 212, 366, -229, -239, 283, 118, +-311, 27, 249, -192, -94, 314, -75, -350, +171, 315, -195, -256, 181, 201, -213, -113, +253, -32, -269, 193, 229, -279, -174, 235, +96, -143, 24, 121, -180, -179, 289, 197, +-298, -83, 260, -98, -247, 228, 261, -289, +-223, 361, 96, -445, 48, 472, -115, -420, +107, 365, -108, -365, 142, 355, -171, -268, +122, 124, -26, -8, -93, -65, 174, 151, +-236, -262, 271, 331, -285, -284, 248, 145, +-162, 17, 68, -159, 3, 269, -17, -358, +15, 448, -35, -573, 93, 722, -123, -833, +59, 845, 73, -775, -213, 690, 269, -615, +-260, 531, 212, -431, -179, 341, 141, -295, +-70, 258, -57, -193, 175, 128, -235, -92, +222, 93, -163, -112, 155, 86, -175, -28, +179, -19, -104, 3, -19, 54, 95, -47, +-98, -62, 36, 204, 24, -259, -57, 190, +53, -105, -85, 120, 149, -214, -225, 271, +223, -250, -129, 228, 19, -289, -10, 415, +97, -505, -139, 493, 68, -421, 52, 365, +-93, -336, 27, 324, 9, -260, 40, 162, +-145, -36, 175, -75, -144, 183, 104, -279, +-126, 324, 182, -304, -226, 244, 214, -219, +-163, 240, 102, -242, -52, 167, -8, -67, +110, 27, -231, -23, 307, -61, -279, 237, +207, -379, -194, 365, 255, -238, -298, 160, +215, -195, -58, 272, -79, -279, 116, 217, +-118, -147, 144, 127, -240, -148, 333, 183, +-391, -179, 397, 114, -401, -12, 423, -75, +-433, 139, 383, -228, -259, 367, 124, -510, +-45, 582, 8, -557, 43, 451, -131, -299, +222, 126, -311, 41, 390, -211, -427, 409, +393, -662, -320, 866, 286, -915, -313, 839, +292, -779, -165, 778, 14, -688, 7, 401, +77, -39, -92, -183, -39, 237, 176, -311, +-166, 506, 47, -680, 19, 667, -1, -518, +14, 432, -142, -457, 258, 465, -234, -319, +102, 72, -39, 131, 114, -227, -208, 270, +167, -350, -7, 479, -151, -597, 197, 655, +-203, -639, 260, 581, -378, -497, 445, 369, +-432, -168, 386, -51, -368, 215, 338, -333, +-234, 500, 67, -727, 80, 896, -165, -907, +256, 818, -413, -746, 573, 676, -651, -463, +609, 75, -527, 344, 422, -637, -281, 810, +85, -979, 105, 1164, -264, -1264, 397, 1224, +-552, -1058, 673, 839, -685, -582, 596, 283, +-473, 24, 369, -286, -236, 459, 44, -554, +209, 580, -454, -561, 630, 506, -714, -404, +727, 229, -710, -27, 671, -137, -596, 250, +429, -371, -174, 498, -97, -541, 298, 412, +-432, -178, 577, -32, -728, 150, 840, -279, +-841, 496, 746, -716, -625, 815, 508, -765, +-361, 688, 139, -663, 131, 649, -374, -542, +524, 314, -587, -66, 616, -112, -662, 211, +677, -287, -634, 399, 507, -517, -342, 600, +144, -632, 104, 633, -377, -602, 596, 528, +-714, -401, 793, 239, -867, -58, 908, -167, +-824, 421, 638, -637, -420, 726, 210, -731, +45, 753, -390, -810, 720, 809, -966, -643, +1102, 357, -1168, -87, 1161, -141, -1044, 385, +808, -634, -539, 810, 283, -833, -2, 752, +-317, -673, 630, 629, -860, -542, 1001, 358, +-1072, -136, 1093, -50, -1021, 164, 841, -276, +-603, 426, 365, -572, -167, 614, -39, -520, +270, 379, -523, -293, 708, 269, -782, -209, +761, 62, -700, 128, 613, -295, -465, 457, +243, -615, -11, 724, -166, -708, 330, 575, +-532, -434, 774, 320, -958, -208, 1015, 66, +-984, 99, 882, -280, -714, 497, 450, -705, +-187, 828, -50, -813, 288, 752, -592, -736, +910, 684, -1087, -476, 1095, 148, -1051, 94, +1073, -156, -1078, 190, 921, -380, -578, 681, +201, -866, 60, 848, -230, -729, 416, 637, +-659, -565, 873, 443, -966, -273, 931, 74, +-829, 138, 702, -367, -553, 574, 355, -714, +-123, 780, -83, -807, 229, 787, -320, -690, +406, 493, -453, -253, 440, 12, -359, 186, +276, -325, -233, 403, 205, -419, -172, 380, +136, -273, -125, 109, 91, 60, -21, -160, +-62, 192, 89, -224, -65, 267, 61, -252, +-124, 136, 195, 22, -196, -126, 130, 177, +-71, -225, 55, 275, -43, -263, 5, 150, +54, 11, -103, -145, 143, 216, -178, -239, +212, 206, -220, -140, 183, 70, -100, -16, +-30, -38, 169, 121, -273, -238, 331, 335, +-351, -367, 320, 322, -231, -193, 100, 27, +-9, 115, -14, -168, 25, 165, -91, -193, +213, 274, -322, -327, 362, 295, -347, -220, +309, 186, -267, -183, 215, 128, -160, 8, +79, -127, 7, 164, -95, -137, 160, 147, +-251, -215, 419, 287, -634, -314, 802, 280, +-844, -212, 785, 132, -700, -56, 626, -4, +-527, 34, 389, -40, -208, 25, 7, -17, +219, 20, -444, -19, 592, 36, -665, -56, +682, 82, -682, -78, 619, 47, -463, -27, +239, 62, -30, -117, -151, 129, 321, -83, +-484, 49, 601, -94, -632, 184, 585, -247, +-475, 263, 322, -276, -160, 305, 32, -317, +75, 280, -190, -229, 317, 175, -399, -85, +402, -53, -384, 202, 372, -283, -362, 325, +308, -396, -222, 486, 142, -516, -69, 456, +-37, -376, 161, 341, -249, -300, 290, 178, +-336, -5, 433, -124, -503, 164, 458, -177, +-317, 238, 177, -323, -64, 343, -56, -288, +205, 228, -363, -202, 483, 197, -581, -165, +656, 126, -682, -129, 644, 154, -557, -135, +446, 53, -319, 34, 148, -51, 64, 58, +-295, -167, 517, 375, -685, -527, 744, 512, +-670, -410, 536, 356, -421, -335, 331, 221, +-229, 22, 94, -245, 50, 326, -191, -331, +341, 383, -489, -448, 583, 389, -603, -192, +608, -15, -635, 153, 618, -272, -492, 444, +287, -599, -108, 631, 3, -555, 91, 483, +-246, -443, 438, 384, -584, -289, 643, 202, +-607, -141, 491, 37, -321, 144, 150, -337, +-3, 431, -133, -423, 284, 384, -440, -360, +573, 316, -637, -250, 633, 157, -552, -44, +412, -106, -236, 251, 65, -327, 90, 328, +-238, -310, 392, 293, -523, -238, 613, 103, +-652, 70, 648, -220, -576, 318, 446, -414, +-284, 522, 130, -612, 8, 647, -146, -610, +267, 530, -357, -408, 407, 254, -419, -81, +400, -95, -360, 264, 319, -414, -250, 514, +142, -590, 23, 649, -194, -658, 297, 571, +-313, -392, 298, 195, -308, -30, 329, -125, +-312, 306, 238, -487, -119, 593, -16, -612, +134, 602, -220, -573, 269, 475, -282, -295, +284, 78, -283, 118, 252, -278, -197, 438, +130, -573, -81, 638, 63, -623, -45, 565, +-2, -500, 94, 416, -185, -308, 240, 171, +-239, -40, 245, -93, -281, 223, 301, -335, +-249, 422, 112, -448, -4, 443, -39, -388, +46, 303, -93, -192, 186, 67, -265, 32, +327, -93, -380, 118, 427, -163, -405, 245, +319, -331, -243, 367, 204, -322, -155, 244, +41, -195, 113, 170, -237, -108, 290, 2, +-333, 131, 379, -217, -420, 263, 399, -282, +-326, 328, 220, -380, -123, 395, 58, -327, +-15, 176, -27, -17, 94, -87, -184, 151, +271, -218, -337, 294, 375, -326, -366, 292, +297, -243, -197, 237, 119, -247, -68, 194, +-8, -63, 145, -88, -279, 187, 334, -237, +-331, 290, 335, -365, -345, 442, 298, -497, +-166, 511, 40, -505, 39, 465, -88, -417, +166, 356, -232, -273, 240, 132, -211, 58, +211, -224, -257, 324, 269, -377, -190, 441, +70, -535, 24, 593, -79, -563, 145, 454, +-236, -336, 311, 248, -341, -149, 320, 2, +-260, 151, 191, -242, -120, 256, 60, -260, +4, 296, -70, -322, 121, 278, -151, -173, +158, 94, -160, -60, 152, 15, -125, 76, +101, -160, -108, 183, 116, -153, -64, 118, +-37, -106, 127, 83, -146, -57, 128, 59, +-136, -74, 174, 59, -199, -8, 188, -5, +-165, -49, 139, 110, -95, -98, 42, 35, +1, -16, -16, 50, 50, -71, -125, 31, +205, 25, -236, -38, 212, 31, -181, -51, +182, 86, -177, -103, 133, 101, -63, -101, +-19, 126, 90, -144, -150, 145, 194, -129, +-215, 100, 214, -57, -199, 37, 161, -71, +-90, 123, 9, -115, 41, 40, -57, 19, +71, 3, -113, -53, 165, 35, -188, 52, +181, -127, -167, 137, 157, -130, -128, 180, +54, -276, 32, 361, -74, -389, 63, 357, +-38, -299, 40, 257, -80, -228, 116, 182, +-111, -88, 76, -36, -48, 134, 38, -178, +-22, 208, -12, -270, 41, 352, -40, -382, +23, 337, -23, -274, 54, 248, -97, -234, +116, 193, -113, -110, 108, 11, -97, 74, +60, -128, -13, 163, -17, -197, 20, 254, +-31, -307, 61, 301, -84, -194, 65, 35, +-12, 80, -28, -110, 24, 136, -22, -211, +66, 297, -129, -311, 155, 238, -130, -160, +115, 136, -142, -140, 184, 92, -172, 17, +104, -135, -38, 203, 6, -210, -1, 202, +-29, -193, 66, 193, -84, -183, 86, 135, +-93, -52, 111, -20, -120, 41, 108, -10, +-102, -24, 132, 20, -163, -15, 168, 46, +-142, -103, 105, 136, -84, -109, 52, 71, +-3, -59, -67, 72, 119, -47, -147, -21, +142, 98, -136, -134, 144, 143, -150, -170, +137, 200, -71, -207, -11, 171, 72, -137, +-88, 135, 94, -149, -109, 128, 126, -71, +-120, 24, 82, -8, -33, 6, -27, 15, +92, -38, -151, 36, 194, -30, -218, 44, +242, -73, -245, 66, 202, -17, -116, -11, +28, -7, 20, 31, -34, -14, 62, -25, +-127, 41, 173, -10, -155, -13, 105, -17, +-69, 46, 75, -18, -87, -49, 69, 59, +-20, 14, -24, -90, 41, 80, -32, -12, +29, -17, -48, -18, 68, 43, -62, 15, +27, -96, 3, 99, 5, -19, -35, -42, +28, 38, 18, -10, -61, 28, 56, -64, +-29, 81, 21, -76, -34, 66, 52, -42, +-65, -31, 78, 122, -83, -148, 53, 105, +-11, -65, -10, 87, 0, -117, 4, 80, +24, -4, -44, -28, 20, 7, 26, -10, +-42, 79, 27, -156, -15, 164, 35, -130, +-56, 119, 44, -141, -6, 144, -29, -100, +54, 45, -86, -5, 108, -10, -113, 26, +98, -40, -84, 52, 86, -72, -76, 85, +63, -93, -28, 84, -22, -80, 88, 83, +-142, -69, 166, 18, -168, 42, 176, -66, +-205, 62, 218, -53, -195, 58, 141, -47, +-91, 13, 61, 4, -11, -5, -49, -3, +105, -14, -131, 42, 150, -65, -174, 62, +207, -31, -233, -22, 245, 78, -237, -107, +209, 98, -154, -89, 98, 96, -51, -112, +13, 101, 34, -68, -97, 43, 161, -35, +-198, 6, 219, 40, -225, -73, 216, 73, +-196, -55, 158, 53, -108, -52, 57, 19, +-11, 30, -38, -47, 82, 56, -140, -85, +201, 134, -245, -145, 240, 113, -202, -96, +169, 136, -149, -186, 123, 164, -74, -80, +2, 30, 50, -23, -80, -14, 113, 129, +-150, -263, 168, 318, -152, -284, 126, 231, +-98, -226, 89, 212, -66, -157, 28, 85, +11, -36, -47, 9, 83, 38, -124, -96, +145, 123, -121, -108, 77, 83, -40, -92, +26, 109, -9, -101, -40, 83, 103, -76, +-145, 72, 156, -46, -133, -15, 105, 58, +-79, -54, 44, 51, -11, -79, -24, 119, +70, -117, -105, 49, 131, 22, -144, -42, +148, 46, -156, -82, 159, 160, -150, -214, +120, 208, -83, -158, 53, 118, -37, -104, +33, 84, -23, -35, -2, -38, 38, 109, +-71, -152, 81, 176, -81, -181, 86, 176, +-100, -167, 122, 147, -131, -126, 126, 107, +-108, -92, 80, 75, -34, -51, -12, -2, +48, 73, -62, -129, 64, 133, -64, -93, +54, 74, -32, -107, 7, 135, 21, -87, +-56, -26, 93, 113, -106, -133, 101, 123, +-85, -161, 78, 228, -78, -238, 59, 171, +-28, -77, 14, 1, -11, 43, 11, -90, +5, 138, -26, -189, 34, 267, -32, -359, +36, 402, -46, -352, 71, 246, -91, -198, +118, 208, -134, -180, 121, 55, -88, 94, +53, -149, -41, 121, 33, -113, -2, 170, +-43, -232, 77, 227, -84, -168, 83, 102, +-76, -52, 58, -5, -21, 69, -27, -119, +64, 164, -94, -205, 112, 238, -122, -228, +119, 180, -107, -137, 94, 114, -71, -81, +35, 5, 17, 85, -59, -145, 91, 151, +-104, -142, 97, 149, -81, -154, 67, 133, +-62, -89, 68, 44, -58, -21, 28, 6, +8, 28, -34, -85, 58, 131, -74, -152, +91, 143, -106, -137, 118, 153, -135, -162, +147, 134, -141, -83, 128, 36, -113, -10, +96, -17, -72, 70, 33, -117, -2, 143, +-13, -150, 35, 149, -57, -146, 87, 108, +-108, -44, 107, 11, -101, -15, 84, 33, +-68, -8, 46, -26, -33, 36, 25, -23, +-12, 31, -15, -65, 66, 59, -97, -15, +109, -23, -109, 18, 108, 3, -109, 20, +101, -66, -88, 98, 68, -107, -30, 131, +-24, -180, 79, 201, -123, -150, 154, 57, +-172, 19, 187, -83, -189, 161, 168, -235, +-134, 269, 101, -279, -65, 317, 28, -401, +23, 450, -69, -411, 101, 320, -100, -274, +86, 272, -58, -250, 26, 172, 10, -85, +-44, 55, 73, -63, -100, 66, 127, -49, +-145, 44, 157, -82, -145, 147, 112, -216, +-52, 281, 2, -345, 40, 384, -56, -387, +80, 355, -102, -315, 135, 262, -152, -178, +158, 67, -138, 50, 119, -150, -91, 237, +76, -321, -64, 413, 53, -477, -21, 502, +-6, -496, 38, 483, -56, -457, 92, 408, +-129, -319, 175, 219, -184, -137, 199, 53, +-195, 59, 211, -204, -199, 349, 181, -445, +-114, 488, 55, -513, 26, 524, -89, -492, +167, 409, -212, -297, 270, 177, -288, -39, +324, -127, -317, 290, 315, -411, -261, 488, +218, -565, -133, 623, 71, -601, 15, 491, +-56, -345, 133, 224, -174, -123, 239, -11, +-257, 175, 304, -333, -299, 441, 309, -511, +-251, 569, 214, -590, -139, 572, 98, -526, +-5, 473, -72, -402, 192, 293, -260, -156, +360, 31, -382, 94, 419, -270, -364, 503, +301, -725, -180, 886, 86, -978, 69, 1025, +-180, -1003, 335, 879, -402, -645, 476, 351, +-450, -15, 403, -376, -238, 801, 70, -1179, +180, 1412, -353, -1485, 574, 1420, -697, -1230, +827, 885, -829, -392, 791, -180, -621, 727, +440, -1189, -145, 1554, -111, -1799, 435, 1884, +-655, -1764, 862, 1434, -930, -948, 949, 385, +-831, 187, 699, -710, -439, 1146, 208, -1440, +118, 1549, -361, -1474, 613, 1222, -741, -843, +829, 380, -775, 102, 709, -534, -514, 868, +357, -1070, -112, 1114, -75, -994, 281, 729, +-406, -372, 526, -16, -523, 391, 527, -734, +-400, 984, 321, -1078, -171, 967, 80, -705, +33, 364, -94, 5, 180, -398, -178, 764, +218, -1031, -182, 1146, 197, -1106, -170, 955, +172, -719, -163, 414, 189, -64, -203, -256, +276, 490, -274, -612, 292, 610, -230, -481, +164, 253, -70, 14, -26, -263, 151, 472, +-253, -633, 393, 716, -449, -685, 490, 534, +-457, -298, 374, 31, -252, 247, 79, -524, +126, 769, -306, -927, 485, 970, -575, -918, +630, 792, -636, -608, 560, 369, -447, -85, +243, -203, -7, 465, -234, -655, 464, 756, +-635, -761, 738, 677, -810, -524, 759, 326, +-692, -87, 531, -170, -353, 398, 159, -566, +30, 657, -223, -695, 346, 676, -486, -579, +479, 390, -470, -139, 353, -104, -259, 300, +146, -445, -78, 561, -43, -646, 80, 667, +-175, -612, 129, 474, -127, -296, 29, 111, +7, 78, -85, -267, 89, 434, -162, -555, +91, 598, -97, -570, -61, 488, 119, -365, +-246, 211, 269, -44, -346, -125, 305, 261, +-359, -339, 211, 348, -160, -284, -81, 173, +202, -48, -396, -70, 441, 154, -545, -198, +460, 190, -482, -129, 248, 38, -144, 85, +-154, -217, 299, 335, -551, -400, 625, 391, +-798, -300, 719, 163, -752, 5, 491, -177, +-382, 338, 94, -454, 11, 483, -231, -436, +264, 339, -440, -223, 349, 99, -422, 31, +223, -141, -231, 186, 64, -143, -105, 16, +4, 153, -148, -309, 113, 440, -354, -525, +344, 555, -550, -494, 451, 338, -481, -96, +257, -199, -192, 483, -138, -713, 257, 882, +-654, -965, 749, 912, -998, -701, 880, 344, +-863, 84, 535, -498, -367, 841, -94, -1097, +297, 1240, -746, -1240, 812, 1075, -1018, -745, +838, 312, -778, 154, 392, -585, -193, 941, +-319, -1176, 522, 1241, -930, -1110, 898, 796, +-982, -357, 671, -114, -521, 559, 47, -922, +188, 1169, -700, -1274, 831, 1209, -1147, -969, +1016, 584, -1005, -125, 609, -334, -384, 722, +-152, -1013, 401, 1178, -896, -1203, 963, 1058, +-1183, -758, 962, 363, -901, 48, 488, -406, +-304, 710, -193, -916, 355, 989, -751, -883, +707, 608, -830, -241, 559, -148, -484, 497, +100, -786, 14, 982, -393, -1044, 384, 939, +-586, -660, 352, 259, -332, 207, -23, -662, +138, 1039, -522, -1307, 594, 1408, -871, -1316, +708, 1015, -728, -546, 328, 11, -159, 519, +-312, -981, 494, 1345, -905, -1552, 941, 1547, +-1156, -1305, 922, 871, -860, -336, 411, -206, +-197, 691, -277, -1070, 455, 1279, -825, -1287, +791, 1082, -907, -702, 588, 221, -452, 265, +-7, -693, 207, 1005, -621, -1172, 706, 1145, +-957, -909, 789, 500, -766, -1, 340, -483, +-132, 887, -347, -1159, 528, 1281, -881, -1225, +864, 996, -975, -624, 675, 184, -539, 251, +77, -623, 136, 890, -561, -1016, 671, 991, +-919, -811, 796, 522, -801, -179, 444, -154, +-286, 435, -132, -620, 270, 693, -558, -643, +521, 484, -603, -248, 360, -29, -276, 286, +-88, -482, 202, 585, -488, -578, 468, 467, +-558, -267, 331, 15, -230, 259, -158, -503, +340, 680, -708, -760, 776, 732, -938, -598, +790, 365, -726, -73, 375, -235, -160, 508, +-280, -706, 482, 792, -800, -757, 813, 601, +-888, -371, 681, 88, -556, 197, 191, -464, +1, 676, -358, -783, 452, 772, -637, -653, +540, 465, -527, -224, 283, -42, -155, 290, +-138, -492, 240, 605, -454, -635, 423, 588, +-466, -474, 272, 303, -174, -100, -89, -106, +204, 272, -443, -398, 480, 466, -598, -469, +483, 392, -442, -250, 217, 68, -90, 109, +-172, -281, 273, 441, -460, -568, 438, 624, +-485, -588, 315, 492, -228, -345, -16, 172, +142, 18, -364, -205, 413, 356, -527, -437, +434, 453, -398, -411, 182, 333, -50, -216, +-207, 89, 334, 32, -525, -108, 539, 131, +-590, -108, 457, 45, -368, 41, 138, -141, +23, 219, -264, -280, 385, 304, -557, -287, +565, 228, -601, -139, 477, 30, -386, 61, +176, -141, -31, 208, -192, -251, 305, 247, +-453, -189, 457, 93, -499, 17, 401, -127, +-349, 258, 192, -402, -102, 537, -49, -634, +101, 696, -199, -724, 176, 726, -206, -669, +135, 569, -125, -448, 45, 343, -41, -245, +-17, 175, -2, -151, -32, 193, 0, -299, +-36, 426, 20, -546, -73, 652, 91, -740, +-175, 786, 212, -752, -292, 638, 301, -485, +-331, 309, 280, -138, -238, -33, 115, 171, +-13, -240, -137, 241, 232, -196, -354, 143, +385, -69, -428, -3, 387, 46, -348, -31, +250, -51, -165, 172, 51, -312, 9, 465, +-80, -620, 89, 745, -111, -822, 89, 841, +-100, -803, 86, 723, -103, -595, 111, 428, +-159, -245, 193, 55, -246, 125, 267, -309, +-286, 465, 267, -571, -236, 614, 165, -608, +-99, 576, 9, -506, 47, 397, -103, -262, +119, 131, -119, -28, 96, -44, -76, 87, +52, -77, -47, 7, 55, 92, -94, -195, +147, 279, -228, -347, 319, 387, -405, -364, +476, 262, -523, -99, 532, -75, -506, 242, +442, -413, -343, 569, 229, -678, -97, 697, +-27, -636, 146, 544, -250, -433, 335, 305, +-389, -163, 407, 42, -394, 35, 369, -69, +-320, 79, 269, -59, -207, 16, 155, 49, +-110, -90, 74, 98, -41, -67, 16, 22, +28, 41, -64, -126, 134, 221, -206, -285, +308, 295, -411, -254, 539, 168, -644, -46, +748, -130, -798, 350, 823, -567, -787, 749, +717, -862, -587, 918, 419, -903, -202, 808, +-21, -620, 261, 365, -460, -88, 652, -185, +-775, 432, 856, -646, -849, 798, 801, -869, +-687, 838, 565, -731, -404, 568, 264, -375, +-119, 172, 25, 30, 50, -216, -72, 377, +82, -495, -59, 559, 60, -580, -53, 571, +84, -547, -120, 516, 186, -462, -243, 397, +318, -347, -352, 306, 373, -275, -331, 227, +269, -171, -149, 111, 23, -52, 121, -14, +-237, 98, 328, -182, -351, 240, 329, -263, +-231, 248, 102, -185, 63, 68, -214, 112, +359, -336, -462, 586, 513, -826, -499, 1055, +431, -1232, -311, 1341, 180, -1360, -29, 1281, +-90, -1109, 183, 837, -215, -475, 192, 69, +-114, 339, 4, -708, 131, 1032, -251, -1302, +366, 1483, -421, -1564, 432, 1539, -374, -1443, +270, 1301, -113, -1129, -56, 917, 228, -676, +-368, 432, 475, -205, -526, -3, 527, 201, +-478, -387, 387, 563, -274, -721, 161, 857, +-54, -972, -20, 1046, 67, -1072, -86, 1059, +74, -999, -40, 882, 7, -719, 13, 521, +-7, -311, -14, 88, 69, 128, -138, -338, +225, 510, -314, -630, 381, 705, -416, -738, +398, 729, -331, -656, 213, 522, -53, -356, +-128, 190, 301, -32, -456, -118, 566, 257, +-618, -372, 601, 432, -522, -434, 390, 389, +-218, -315, 31, 198, 154, -47, -322, -119, +434, 283, -497, -413, 492, 510, -444, -559, +352, 558, -235, -513, 108, 433, 19, -353, +-134, 271, 218, -181, -282, 90, 325, -20, +-346, -28, 345, 63, -351, -81, 356, 94, +-374, -95, 392, 88, -412, -78, 420, 60, +-405, -26, 353, -34, -264, 118, 132, -208, +36, 301, -236, -405, 451, 519, -677, -612, +883, 655, -1040, -632, 1131, 528, -1124, -366, +1026, 147, -832, 94, 573, -338, -270, 539, +-42, -672, 329, 725, -571, -695, 752, 593, +-864, -422, 898, 204, -848, 47, 723, -317, +-531, 583, 292, -812, -28, 973, -227, -1034, +455, 978, -622, -819, 738, 580, -774, -324, +745, 91, -651, 100, 517, -249, -341, 345, +162, -392, 31, 377, -208, -319, 377, 245, +-523, -169, 657, 93, -766, -9, 865, -83, +-928, 173, 954, -245, -913, 302, 825, -347, +-677, 386, 493, -416, -262, 443, 22, -479, +244, 517, -506, -540, 769, 554, -992, -561, +1174, 558, -1264, -519, 1268, 416, -1147, -256, +942, 57, -646, 155, 331, -385, 7, 618, +-304, -836, 573, 1021, -782, -1152, 944, 1241, +-1033, -1259, 1069, 1179, -1026, -983, 929, 715, +-770, -414, 583, 128, -359, 146, 144, -394, +75, 596, -255, -725, 432, 783, -580, -789, +719, 793, -817, -782, 904, 736, -930, -646, +940, 500, -874, -332, 774, 151, -583, 12, +353, -159, -47, 288, -263, -402, 594, 495, +-872, -548, 1111, 555, -1239, -528, 1304, 468, +-1256, -386, 1152, 286, -968, -161, 759, 36, +-499, 86, 245, -190, 29, 275, -255, -334, +443, 358, -544, -332, 579, 279, -532, -204, +455, 128, -325, -56, 202, -16, -62, 75, +-53, -98, 176, 75, -261, -19, 356, -50, +-390, 111, 415, -177, -361, 262, 301, -366, +-181, 453, 91, -484, 17, 454, -66, -370, +128, 274, -142, -166, 180, 67, -192, 55, +223, -158, -226, 241, 239, -270, -215, 263, +179, -223, -98, 175, 18, -129, 89, 79, +-182, -48, 279, 48, -348, -108, 413, 192, +-422, -313, 414, 419, -358, -504, 311, 533, +-219, -518, 153, 430, -43, -283, -46, 93, +189, 115, -293, -308, 439, 483, -516, -610, +608, 705, -606, -715, 599, 663, -513, -516, +434, 364, -318, -187, 225, 44, -111, 124, +7, -267, 110, 387, -213, -430, 302, 394, +-360, -317, 385, 207, -385, -111, 370, -7, +-339, 77, 321, -139, -293, 107, 288, -57, +-252, -57, 234, 131, -156, -203, 109, 216, +-1, -212, -40, 178, 129, -115, -140, 45, +204, 59, -190, -124, 219, 199, -169, -186, +163, 165, -95, -53, 62, -42, -1, 207, +-26, -331, 41, 463, -33, -508, -18, 524, +60, -473, -124, 385, 163, -288, -195, 127, +181, 8, -163, -173, 100, 253, -31, -358, +-46, 392, 128, -476, -168, 481, 236, -516, +-224, 464, 255, -434, -193, 377, 198, -347, +-91, 327, 64, -306, 57, 348, -82, -366, +181, 448, -178, -446, 211, 487, -161, -407, +130, 362, -57, -220, -1, 128, 50, 27, +-111, -126, 135, 242, -196, -321, 202, 371, +-254, -417, 237, 392, -256, -385, 198, 280, +-147, -234, 50, 98, 51, -79, -132, -13, +220, -19, -225, -12, 261, -59, -187, 97, +196, -192, -93, 256, 102, -267, -1, 249, +16, -133, 83, 61, -87, 94, 190, -151, +-220, 316, 289, -358, -302, 494, 308, -489, +-297, 545, 240, -487, -218, 473, 125, -384, +-98, 277, -12, -136, 38, -46, -138, 154, +163, -314, -228, 340, 225, -463, -232, 447, +210, -543, -152, 469, 128, -503, -32, 407, +18, -410, 96, 326, -90, -281, 204, 185, +-176, -73, 270, -20, -217, 178, 267, -239, +-194, 390, 199, -383, -125, 474, 81, -367, +-20, 366, -45, -192, 67, 133, -130, 47, +116, -149, -179, 307, 149, -414, -222, 468, +189, -492, -249, 401, 205, -371, -207, 197, +147, -157, -94, -39, 28, 65, 64, -224, +-109, 206, 226, -312, -257, 293, 390, -357, +-370, 335, 454, -333, -346, 309, 329, -233, +-147, 208, 64, -75, 106, 64, -173, 81, +260, -56, -290, 187, 293, -133, -304, 230, +246, -169, -256, 251, 148, -239, -124, 304, +-24, -331, 74, 320, -212, -307, 239, 180, +-320, -130, 306, -44, -311, 53, 284, -214, +-249, 196, 249, -340, -195, 300, 233, -384, +-164, 302, 210, -299, -118, 198, 142, -108, +-22, -17, 23, 191, 100, -303, -115, 477, +202, -482, -224, 589, 273, -499, -305, 528, +308, -336, -344, 269, 285, -38, -286, -33, +143, 176, -78, -203, -122, 255, 210, -278, +-390, 254, 445, -255, -543, 136, 534, -112, +-523, -44, 458, 36, -350, -167, 250, 116, +-78, -198, -9, 106, 186, -147, -213, 89, +314, -130, -254, 142, 270, -160, -143, 164, +101, -89, 20, 73, -74, 54, 147, -46, +-185, 171, 201, -152, -238, 294, 216, -277, +-266, 381, 223, -327, -284, 359, 226, -288, +-268, 250, 185, -162, -183, 47, 90, 28, +-53, -167, -35, 201, 97, -329, -160, 287, +254, -362, -295, 237, 396, -239, -396, 93, +462, -90, -384, 5, 379, -41, -240, 49, +173, -96, -13, 149, -67, -166, 203, 223, +-274, -197, 349, 264, -397, -191, 388, 217, +-380, -65, 270, 20, -211, 172, 49, -232, +10, 379, -147, -407, 152, 466, -215, -453, +163, 416, -171, -372, 114, 263, -101, -211, +72, 61, -45, -32, 55, -113, -29, 100, +69, -195, -49, 136, 103, -173, -76, 101, +121, -107, -81, 59, 107, -40, -55, 9, +55, 32, -15, -11, -1, 46, 9, 21, +-22, 22, -2, 46, -2, 9, -45, 41, +42, 35, -109, -16, 101, 98, -167, -97, +142, 153, -191, -162, 166, 178, -181, -208, +149, 181, -130, -189, 81, 95, -24, -78, +-17, -54, 90, 53, -100, -164, 149, 142, +-120, -210, 128, 178, -67, -195, 68, 128, +-19, -79, 26, 21, -7, 41, 25, -52, +-33, 106, 53, -71, -88, 113, 97, -33, +-142, 60, 132, 19, -164, 15, 124, 44, +-127, -17, 51, 60, -25, -42, -62, 39, +97, -11, -170, -48, 191, 85, -227, -171, +233, 168, -220, -231, 206, 167, -150, -185, +110, 77, -25, -51, -14, -80, 99, 120, +-119, -209, 165, 231, -151, -246, 157, 242, +-126, -199, 106, 201, -80, -143, 62, 161, +-68, -96, 61, 144, -95, -103, 96, 170, +-142, -136, 129, 177, -157, -126, 117, 114, +-108, -51, 39, -8, -3, 63, -61, -143, +92, 161, -122, -216, 120, 170, -91, -193, +50, 111, 26, -125, -88, 47, 182, -50, +-230, -32, 311, 44, -316, -107, 334, 133, +-293, -154, 265, 170, -189, -147, 122, 162, +-46, -96, -34, 107, 100, -29, -174, 43, +200, 41, -242, -30, 219, 96, -222, -82, +156, 124, -124, -120, 47, 118, -8, -103, +-56, 45, 87, -26, -126, -50, 140, 48, +-149, -119, 157, 96, -146, -156, 157, 122, +-138, -164, 149, 132, -129, -143, 135, 109, +-104, -82, 85, 47, -29, 24, -13, -74, +82, 170, -138, -188, 195, 258, -249, -231, +270, 288, -292, -261, 265, 302, -238, -263, +159, 262, -95, -214, -11, 182, 72, -130, +-163, 65, 202, -15, -251, -80, 261, 121, +-268, -219, 242, 244, -197, -336, 144, 333, +-69, -385, 4, 349, 77, -338, -119, 257, +181, -191, -190, 103, 213, -19, -194, -29, +178, 98, -130, -105, 79, 172, -18, -170, +-39, 239, 81, -229, -120, 286, 128, -277, +-136, 309, 113, -286, -115, 265, 84, -196, +-97, 120, 82, -54, -98, -30, 92, 59, +-104, -130, 93, 138, -90, -198, 69, 175, +-24, -201, -31, 146, 116, -136, -194, 90, +293, -83, -356, 62, 427, -50, -440, 46, +448, -26, -398, 43, 334, -9, -238, 32, +130, 22, -20, -5, -86, 35, 178, 6, +-261, -11, 309, 56, -342, -70, 332, 93, +-327, -103, 281, 110, -246, -142, 187, 137, +-147, -161, 87, 125, -60, -115, 21, 48, +5, -30, -32, -43, 62, 77, -93, -149, +130, 192, -165, -232, 216, 245, -249, -231, +298, 218, -315, -167, 333, 141, -307, -55, +265, -3, -185, 129, 86, -199, 32, 299, +-150, -324, 260, 351, -343, -325, 387, 289, +-408, -216, 371, 135, -327, -57, 233, -22, +-147, 53, 44, -105, 34, 103, -119, -128, +166, 103, -204, -108, 205, 65, -191, -43, +164, -9, -125, 26, 100, -35, -67, 23, +53, 8, -25, -25, 11, 65, 12, -57, +-29, 87, 59, -64, -71, 63, 107, -15, +-127, -9, 150, 67, -160, -85, 158, 106, +-144, -100, 121, 81, -93, -60, 49, 16, +-13, 28, -36, -114, 68, 172, -107, -245, +115, 255, -129, -267, 117, 224, -102, -203, +73, 146, -42, -104, 4, 51, 33, -20, +-50, 10, 52, -13, -38, 59, 19, -87, +21, 138, -52, -156, 107, 201, -149, -211, +200, 241, -222, -220, 246, 182, -226, -107, +210, 27, -174, 55, 136, -117, -92, 155, +51, -195, -11, 199, -24, -211, 46, 175, +-60, -160, 65, 111, -78, -103, 89, 79, +-116, -83, 131, 71, -148, -72, 156, 61, +-169, -51, 174, 45, -174, -23, 169, -3, +-136, 50, 105, -90, -62, 148, 34, -171, +4, 202, -25, -199, 55, 211, -68, -190, +74, 176, -57, -134, 38, 96, -19, -54, +10, 23, -9, -9, 14, -15, -19, 25, +19, -53, -30, 59, 39, -74, -68, 65, +84, -68, -107, 60, 109, -74, -115, 80, +111, -93, -119, 103, 116, -108, -111, 116, +100, -116, -89, 125, 82, -113, -82, 126, +85, -129, -73, 166, 61, -197, -23, 245, +-2, -276, 37, 311, -59, -323, 96, 333, +-123, -334, 154, 327, -171, -302, 164, 260, +-130, -218, 83, 163, -30, -131, -30, 96, +86, -87, -151, 74, 200, -93, -239, 119, +247, -185, -234, 253, 190, -321, -142, 366, +92, -395, -38, 402, -14, -394, 67, 380, +-106, -340, 140, 292, -147, -222, 153, 175, +-145, -131, 160, 113, -165, -89, 191, 65, +-203, -25, 226, -13, -242, 57, 272, -120, +-289, 207, 290, -327, -262, 454, 206, -584, +-135, 680, 51, -758, 29, 791, -117, -809, +196, 780, -274, -717, 318, 598, -340, -439, +314, 252, -267, -64, 201, -112, -131, 268, +66, -403, 2, 511, -51, -579, 85, 616, +-84, -594, 63, 554, -4, -500, -40, 460, +87, -419, -100, 390, 100, -342, -68, 299, +21, -251, 62, 205, -157, -157, 266, 83, +-362, 12, 424, -128, -459, 244, 440, -338, +-397, 397, 307, -433, -196, 441, 48, -436, +104, 390, -258, -305, 377, 175, -463, -23, +502, -124, -508, 252, 486, -354, -431, 435, +360, -490, -259, 512, 166, -480, -68, 401, +9, -278, 51, 137, -88, 14, 130, -147, +-152, 272, 185, -391, -199, 500, 218, -581, +-232, 618, 256, -613, -284, 577, 298, -526, +-302, 465, 279, -387, -252, 276, 204, -128, +-162, -44, 108, 215, -61, -375, 15, 511, +10, -634, -9, 731, -21, -794, 70, 796, +-128, -720, 194, 566, -240, -362, 282, 129, +-290, 123, 276, -387, -199, 643, 105, -879, +48, 1031, -187, -1085, 341, 1007, -455, -817, +547, 537, -588, -188, 581, -204, -508, 614, +380, -1012, -206, 1352, 2, -1581, 199, 1675, +-393, -1612, 542, 1422, -653, -1115, 692, 727, +-677, -262, 578, -237, -426, 738, 222, -1178, +2, 1514, -228, -1723, 449, 1791, -630, -1746, +778, 1579, -852, -1319, 878, 948, -820, -518, +709, 67, -532, 342, 340, -686, -118, 942, +-110, -1100, 339, 1168, -536, -1134, 702, 992, +-813, -743, 869, 435, -871, -95, 818, -212, +-722, 481, 572, -672, -401, 809, 189, -841, +21, 784, -233, -611, 426, 350, -597, -39, +723, -268, -813, 542, 852, -772, -828, 923, +759, -1004, -640, 969, 495, -832, -318, 585, +139, -286, 51, -44, -218, 344, 372, -612, +-469, 808, 537, -948, -541, 996, 513, -949, +-436, 809, 333, -595, -202, 353, 65, -100, +70, -129, -187, 339, 279, -490, -352, 596, +383, -602, -389, 537, 360, -380, -318, 184, +251, 45, -177, -270, 103, 474, -36, -648, +-21, 765, 76, -827, -118, 794, 157, -692, +-175, 496, 201, -267, -213, -7, 239, 263, +-242, -528, 257, 742, -254, -902, 252, 959, +-215, -918, 177, 757, -116, -503, 42, 193, +54, 164, -166, -513, 273, 859, -384, -1114, +469, 1291, -544, -1312, 576, 1216, -576, -975, +526, 643, -441, -218, 310, -245, -149, 711, +-32, -1127, 212, 1431, -369, -1606, 506, 1610, +-596, -1469, 638, 1163, -605, -748, 514, 235, +-356, 285, 173, -800, 53, 1219, -284, -1521, +500, 1663, -667, -1635, 784, 1424, -824, -1051, +783, 560, -651, 8, 447, -579, -196, 1123, +-90, -1555, 390, 1848, -672, -1938, 899, 1836, +-1053, -1530, 1107, 1088, -1069, -525, 928, -92, +-696, 709, 399, -1260, -65, 1677, -279, -1928, +609, 1977, -884, -1845, 1072, 1528, -1152, -1080, +1141, 514, -1025, 71, 832, -635, -551, 1068, +248, -1364, 70, 1470, -361, -1392, 612, 1130, +-787, -711, 877, 190, -877, 366, 809, -876, +-674, 1297, 484, -1572, -260, 1694, 24, -1608, +172, 1351, -340, -914, 465, 371, -539, 222, +548, -792, -518, 1307, 446, -1702, -351, 1938, +233, -1984, -105, 1823, -2, -1505, 78, 1070, +-141, -570, 192, 39, -214, 464, 214, -908, +-182, 1220, 153, -1396, -111, 1416, 69, -1310, +-22, 1097, -14, -790, 44, 424, -77, -26, +110, -337, -127, 633, 121, -822, -111, 918, +108, -917, -98, 821, 69, -630, -31, 375, +-16, -80, 55, -209, -97, 464, 138, -684, +-173, 853, 184, -952, -188, 955, 188, -872, +-176, 710, 136, -495, -83, 245, 42, 13, +-3, -268, -34, 484, 83, -641, -113, 714, +142, -726, -150, 678, 161, -585, -162, 462, +146, -298, -123, 126, 107, 32, -91, -146, +55, 225, -12, -262, -31, 272, 55, -236, +-90, 167, 113, -64, -140, -32, 138, 104, +-130, -146, 104, 166, -69, -178, 8, 178, +52, -163, -101, 130, 136, -111, -160, 102, +175, -118, -166, 142, 115, -157, -41, 165, +-43, -164, 131, 163, -218, -147, 294, 111, +-333, -49, 340, -23, -315, 95, 257, -151, +-158, 195, 22, -217, 117, 210, -247, -162, +347, 83, -442, 17, 492, -114, -506, 191, +455, -245, -390, 275, 286, -276, -177, 232, +44, -153, 49, 51, -126, 48, 168, -142, +-198, 214, 185, -266, -144, 287, 74, -271, +-10, 211, -44, -119, 75, 22, -99, 78, +87, -162, -54, 232, -3, -270, 60, 269, +-133, -224, 192, 155, -249, -66, 255, -23, +-248, 107, 195, -173, -159, 226, 74, -250, +-6, 244, -88, -218, 132, 172, -191, -126, +199, 67, -212, -12, 163, -49, -135, 98, +76, -129, -52, 136, -6, -134, 39, 118, +-77, -102, 67, 75, -74, -34, 50, -4, +-52, 42, 23, -66, -23, 93, 2, -115, +-13, 143, -8, -165, -7, 184, 1, -190, +-35, 186, 18, -169, -33, 159, 6, -160, +-28, 167, 5, -189, -32, 227, 3, -278, +-39, 331, 29, -387, -77, 425, 76, -450, +-133, 438, 143, -407, -188, 342, 159, -261, +-173, 168, 131, -71, -127, -28, 54, 125, +-31, -191, -36, 229, 30, -220, -53, 176, +5, -99, 19, 6, -122, 111, 180, -236, +-294, 368, 344, -483, -454, 588, 473, -663, +-522, 724, 461, -774, -440, 813, 328, -853, +-268, 879, 123, -909, -48, 914, -85, -917, +126, 894, -225, -856, 215, 790, -244, -710, +179, 594, -184, -457, 108, 301, -108, -135, +41, -35, -71, 199, 51, -335, -133, 443, +144, -494, -250, 509, 276, -480, -376, 438, +366, -382, -421, 341, 367, -308, -374, 293, +266, -302, -221, 337, 78, -409, -37, 516, +-94, -650, 124, 794, -236, -945, 231, 1068, +-306, -1157, 271, 1172, -322, -1124, 266, 989, +-304, -790, 252, 516, -307, -197, 259, -151, +-323, 515, 286, -857, -363, 1161, 339, -1400, +-406, 1562, 365, -1642, -409, 1628, 327, -1513, +-324, 1324, 192, -1080, -148, 813, -22, -535, +101, 265, -306, -13, 385, -186, -566, 331, +606, -415, -741, 445, 726, -441, -785, 409, +676, -372, -634, 319, 431, -273, -306, 228, +20, -189, 160, 161, -463, -146, 637, 130, +-904, -119, 1005, 94, -1172, -44, 1141, -22, +-1171, 109, 1013, -199, -924, 292, 661, -367, +-491, 424, 182, -448, -1, 441, -288, -403, +425, 335, -652, -244, 706, 135, -854, 0, +835, -176, -904, 379, 806, -599, -826, 811, +704, -991, -718, 1123, 596, -1203, -612, 1219, +502, -1172, -533, 1042, 430, -832, -453, 539, +331, -189, -329, -201, 163, 612, -117, -1012, +-82, 1378, 147, -1673, -347, 1871, 394, -1942, +-560, 1891, 552, -1712, -640, 1417, 563, -1038, +-585, 593, 437, -120, -409, -338, 224, 743, +-176, -1062, -7, 1261, 42, -1336, -203, 1289, +191, -1136, -301, 904, 245, -617, -309, 291, +216, 35, -252, -335, 129, 579, -151, -731, +30, 789, -51, -764, -67, 680, 34, -546, +-146, 387, 113, -205, -237, 37, 205, 123, +-315, -251, 274, 356, -370, -431, 300, 491, +-352, -524, 234, 530, -233, -518, 67, 494, +-23, -481, -165, 472, 211, -482, -385, 488, +402, -490, -536, 468, 501, -426, -574, 347, +475, -234, -499, 93, 356, 82, -344, -275, +176, 491, -151, -702, -26, 909, 51, -1076, +-215, 1210, 231, -1306, -369, 1359, 365, -1376, +-490, 1341, 465, -1244, -567, 1085, 518, -869, +-593, 606, 516, -316, -564, 17, 451, 272, +-443, -538, 277, 745, -218, -894, 4, 977, +93, -1018, -329, 1018, 419, -979, -630, 908, +676, -807, -812, 689, 766, -570, -802, 472, +654, -394, -595, 353, 363, -332, -231, 332, +-46, -341, 206, 347, -484, -343, 605, 333, +-816, -304, 852, 251, -964, -165, 883, 52, +-871, 90, 676, -247, -557, 395, 290, -529, +-132, 619, -146, -656, 280, 630, -506, -541, +570, 391, -704, -210, 670, 3, -695, 198, +560, -396, -503, 578, 296, -728, -185, 839, +-59, -889, 194, 871, -434, -784, 548, 625, +-736, -413, 776, 159, -884, 124, 831, -406, +-844, 675, 699, -897, -631, 1064, 430, -1161, +-322, 1181, 105, -1126, -2, 999, -185, -820, +242, 594, -376, -338, 364, 73, -420, 186, +347, -435, -347, 646, 226, -816, -194, 940, +56, -1010, -26, 1033, -81, -1014, 82, 946, +-147, -853, 99, 745, -128, -628, 55, 518, +-74, -404, 0, 302, -16, -206, -51, 125, +24, -61, -71, 6, 20, 58, -66, -129, +29, 224, -91, -329, 84, 413, -163, -453, +149, 416, -201, -299, 142, 113, -138, 114, +29, -350, 24, 557, -151, -738, 204, 869, +-325, -958, 356, 1017, -446, -1044, 443, 1033, +-485, -961, 428, 809, -410, -559, 287, 231, +-200, 151, 31, -542, 74, 906, -228, -1210, +296, 1437, -394, -1582, 386, 1655, -404, -1651, +328, 1573, -286, -1431, 164, 1229, -92, -986, +-31, 697, 83, -386, -174, 51, 196, 280, +-262, -595, 273, 849, -327, -1031, 315, 1118, +-337, -1117, 281, 1041, -244, -927, 152, 784, +-102, -646, 7, 527, 28, -408, -117, 297, +180, -184, -293, 62, 370, 54, -470, -147, +493, 212, -507, -261, 446, 317, -412, -398, +331, 522, -308, -659, 246, 786, -224, -856, +153, 839, -100, -734, 1, 548, 67, -324, +-164, 89, 223, 115, -304, -290, 343, 422, +-397, -532, 404, 616, -421, -676, 375, 712, +-346, -691, 266, 623, -204, -502, 114, 343, +-44, -167, -53, -2, 135, 145, -235, -259, +311, 336, -395, -372, 416, 384, -415, -370, +325, 373, -230, -383, 94, 424, 13, -493, +-103, 561, 137, -607, -165, 611, 154, -558, +-164, 461, 153, -346, -143, 223, 91, -114, +-27, 11, -69, 79, 149, -177, -212, 270, +230, -370, -224, 445, 201, -492, -194, 493, +178, -445, -184, 383, 156, -316, -103, 266, +4, -236, 114, 214, -241, -189, 345, 144, +-439, -72, 502, -15, -551, 99, 577, -176, +-586, 234, 564, -285, -521, 327, 447, -364, +-368, 386, 273, -388, -186, 357, 84, -293, +23, 192, -148, -70, 252, -55, -358, 188, +413, -299, -440, 387, 421, -442, -384, 460, +341, -450, -315, 409, 309, -346, -318, 260, +320, -150, -319, 34, 292, 83, -244, -199, +178, 306, -128, -390, 79, 460, -59, -493, +51, 474, -39, -419, 0, 333, 59, -232, +-141, 126, 230, -51, -302, -8, 339, 41, +-354, -55, 337, 62, -317, -66, 283, 73, +-253, -87, 207, 116, -158, -166, 86, 250, +-18, -369, -40, 509, 74, -659, -94, 799, +101, -915, -110, 985, 114, -995, -130, 945, +143, -844, -163, 705, 178, -547, -197, 373, +216, -195, -235, 1, 245, 192, -243, -387, +223, 560, -198, -697, 155, 780, -104, -810, +36, 776, 36, -693, -120, 569, 201, -446, +-272, 340, 305, -273, -300, 235, 263, -234, +-201, 228, 133, -220, -72, 184, 20, -132, +27, 53, -69, 23, 116, -105, -163, 170, +214, -243, -257, 300, 304, -365, -347, 412, +393, -456, -429, 463, 467, -458, -493, 409, +515, -346, -519, 252, 506, -164, -450, 57, +366, 23, -235, -108, 83, 169, 88, -247, +-232, 309, 351, -390, -405, 445, 430, -514, +-413, 552, 388, -575, -352, 550, 322, -496, +-264, 385, 209, -277, -105, 137, 1, -31, +128, -75, -230, 149, 322, -239, -349, 311, +344, -405, -266, 464, 194, -539, -81, 549, +10, -546, 65, 476, -93, -397, 137, 278, +-153, -178, 210, 52, -223, 30, 265, -140, +-244, 221, 240, -342, -164, 432, 115, -547, +-18, 614, -37, -677, 136, 666, -177, -643, +262, 533, -279, -403, 326, 192, -288, 19, +271, -272, -174, 481, 130, -698, -16, 827, +-25, -946, 120, 980, -137, -1005, 218, 936, +-213, -863, 279, 693, -252, -530, 293, 287, +-244, -69, 269, -200, -199, 403, 203, -609, +-119, 718, 133, -825, -60, 833, 99, -854, +-47, 792, 98, -752, -36, 632, 62, -544, +47, 390, -67, -291, 224, 145, -265, -75, +418, -28, -430, 55, 542, -124, -495, 129, +541, -183, -426, 181, 414, -239, -220, 221, +146, -265, 100, 227, -206, -239, 448, 174, +-508, -163, 659, 94, -605, -78, 634, 8, +-466, 10, 429, -100, -226, 146, 188, -264, +12, 318, -22, -444, 218, 472, -224, -540, +395, 501, -356, -479, 463, 344, -338, -239, +368, 46, -175, 76, 189, -265, -10, 357, +67, -496, 60, 531, 43, -604, 58, 571, +51, -575, 50, 497, 56, -469, 53, 371, +73, -357, 29, 273, 112, -288, -18, 238, +162, -285, -57, 264, 174, -313, -33, 275, +128, -294, 28, 213, 76, -192, 69, 68, +60, -13, 69, -141, 68, 230, 62, -409, +72, 512, 74, -682, 51, 735, 112, -815, +-5, 749, 185, -694, -95, 508, 296, -372, +-198, 140, 388, -14, -261, -171, 413, 235, +-238, -364, 351, 385, -135, -493, 222, 494, +7, -565, 73, 518, 165, -537, -86, 444, +318, -436, -219, 348, 423, -376, -271, 333, +422, -409, -211, 392, 309, -454, -62, 389, +142, -368, 106, 215, -3, -127, 232, -70, +-106, 169, 321, -345, -180, 399, 376, -520, +-208, 520, 369, -584, -162, 525, 293, -523, +-66, 385, 199, -302, 10, 95, 152, 30, +37, -246, 132, 344, 52, -482, 111, 475, +89, -508, 73, 399, 127, -366, 33, 243, +159, -218, 12, 104, 191, -91, -38, -31, +263, 69, -129, -212, 347, 267, -179, -402, +343, 421, -100, -508, 202, 465, 91, -506, +-11, 436, 294, -462, -187, 390, 429, -404, +-285, 305, 496, -276, -316, 117, 484, -32, +-258, -157, 385, 226, -117, -362, 195, 365, +99, -426, -28, 366, 312, -396, -215, 337, +453, -386, -299, 348, 474, -409, -265, 371, +399, -423, -159, 368, 263, -393, -9, 320, +108, -333, 153, 234, -52, -210, 300, 58, +-183, 39, 395, -250, -237, 383, 408, -600, +-208, 697, 329, -840, -85, 838, 170, -872, +90, 766, -10, -711, 258, 540, -163, -438, +385, 245, -267, -142, 470, -42, -340, 133, +529, -304, -376, 367, 527, -491, -337, 500, +450, -565, -227, 513, 305, -513, -58, 402, +117, -359, 138, 227, -87, -181, 338, 63, +-283, -35, 516, -67, -429, 84, 609, -181, +-454, 194, 560, -286, -333, 283, 379, -351, +-116, 316, 144, -340, 104, 266, -50, -250, +262, 141, -172, -97, 348, -33, -224, 84, +355, -198, -195, 224, 289, -303, -104, 285, +188, -328, -11, 280, 112, -314, 26, 292, +98, -359, 18, 372, 110, -463, 27, 462, +67, -507, 100, 447, -44, -412, 228, 280, +-168, -186, 336, 6, -240, 112, 372, -299, +-245, 404, 350, -553, -209, 605, 299, -686, +-145, 656, 208, -647, -30, 529, 65, -445, +124, 273, -104, -149, 275, -38, -232, 162, +369, -346, -281, 450, 368, -596, -237, 651, +275, -722, -106, 701, 119, -701, 67, 622, +-52, -570, 236, 435, -200, -327, 356, 139, +-289, 13, 397, -212, -284, 345, 342, -509, +-179, 581, 176, -671, 26, 661, -61, -669, +250, 588, -267, -525, 401, 393, -357, -294, +426, 147, -327, -50, 352, -69, -211, 117, +217, -182, -46, 177, 50, -214, 116, 211, +-96, -254, 234, 258, -168, -297, 249, 284, +-141, -294, 182, 253, -55, -249, 79, 197, +20, -167, 19, 83, 42, -19, 19, -88, +5, 163, 78, -266, -61, 324, 155, -422, +-136, 490, 227, -588, -181, 632, 258, -668, +-176, 623, 226, -550, -100, 395, 120, -237, +34, 34, -21, 123, 139, -271, -102, 364, +168, -458, -102, 519, 122, -598, -45, 633, +46, -655, 20, 585, -13, -465, 57, 258, +-32, -39, 65, -199, -18, 383, 52, -538, +20, 617, 13, -665, 81, 649, -44, -613, +149, 519, -104, -412, 187, 270, -120, -131, +162, -20, -75, 144, 90, -270, -14, 350, +13, -410, 39, 411, -40, -390, 76, 314, +-87, -228, 122, 114, -132, -10, 169, -106, +-142, 192, 147, -268, -49, 304, 28, -337, +109, 331, -124, -304, 243, 231, -203, -131, +260, -6, -165, 131, 164, -234, -62, 275, +44, -264, 18, 195, -28, -101, 47, -16, +-54, 127, 46, -234, -55, 320, 50, -392, +-55, 424, 51, -418, -37, 362, 46, -264, +-10, 128, 45, 19, -4, -164, 73, 274, +-38, -357, 118, 395, -77, -419, 128, 419, +-78, -404, 99, 345, -67, -248, 52, 111, +-35, 60, -13, -241, 51, 392, -137, -519, +182, 590, -273, -618, 301, 593, -331, -529, +303, 424, -242, -285, 171, 122, -41, 42, +-33, -202, 171, 340, -206, -458, 306, 543, +-300, -598, 350, 610, -331, -573, 343, 483, +-331, -344, 300, 170, -285, 18, 205, -199, +-175, 333, 51, -407, -2, 408, -134, -358, +185, 278, -284, -204, 321, 131, -369, -62, +394, -21, -383, 110, 397, -206, -348, 269, +340, -288, -269, 260, 237, -193, -153, 113, +89, -43, -11, -17, -73, 61, 110, -109, +-188, 155, 163, -200, -227, 241, 168, -256, +-221, 233, 164, -172, -209, 73, 163, 43, +-180, -160, 131, 258, -105, -314, 54, 338, +19, -347, -66, 339, 138, -323, -167, 292, +206, -235, -220, 157, 220, -60, -237, -28, +204, 98, -231, -148, 161, 182, -188, -204, +84, 212, -101, -212, -18, 196, -8, -162, +-81, 126, 50, -103, -104, 105, 72, -116, +-88, 132, 75, -142, -81, 144, 89, -138, +-91, 130, 101, -123, -111, 112, 99, -77, +-102, 23, 47, 51, -66, -115, -6, 175, +-32, -210, -51, 201, -2, -154, -100, 91, +71, -43, -191, 25, 159, -54, -218, 141, +127, -254, -106, 355, -15, -380, 90, 349, +-198, -276, 261, 167, -315, -13, 305, -171, +-283, 377, 172, -578, -90, 775, -77, -909, +144, 941, -297, -858, 294, 693, -418, -439, +358, 124, -431, 234, 309, -570, -321, 860, +153, -1078, -90, 1185, -124, -1126, 223, 915, +-407, -565, 470, 143, -541, 319, 483, -749, +-419, 1067, 253, -1205, -156, 1198, -3, -1037, +25, 766, -114, -381, 31, -25, -66, 421, +-54, -759, -9, 1011, -85, -1089, -26, 968, +-33, -660, -109, 274, 88, 140, -227, -524, +207, 826, -328, -962, 296, 959, -365, -807, +285, 561, -292, -203, 166, -161, -114, 447, +-57, -593, 90, 636, -235, -555, 200, 383, +-278, -141, 134, -81, -157, 272, -11, -392, +-56, 437, -67, -339, -54, 153, -26, 74, +-86, -254, -34, 387, -9, -435, -125, 389, +57, -200, -129, -82, 40, 423, -100, -716, +-25, 905, 2, -873, -126, 651, 34, -278, +-111, -127, 5, 542, -133, -878, 59, 1096, +-243, -1102, 197, 936, -386, -570, 255, 73, +-315, 523, 69, -1019, -62, 1327, -191, -1377, +178, 1249, -362, -910, 254, 417, -312, 207, +96, -801, -62, 1312, -206, -1638, 231, 1753, +-452, -1554, 390, 1111, -519, -491, 345, -172, +-372, 839, 83, -1380, -36, 1700, -317, -1688, +375, 1429, -704, -992, 672, 536, -879, -69, +703, -306, -751, 648, 428, -939, -333, 1253, +-97, -1481, 265, 1570, -681, -1410, 739, 1038, +-970, -463, 788, -162, -770, 741, 378, -1092, +-280, 1151, -45, -856, -76, 369, -2, 110, +-274, -293, 161, 104, -251, 360, -118, -730, +178, 743, -502, -283, 369, -371, -497, 884, +282, -979, -437, 810, 273, -630, -389, 639, +108, -690, -124, 557, -152, -79, -2, -503, +-121, 882, -82, -856, -108, 708, -52, -774, +-96, 1156, -131, -1453, -23, 1388, -238, -991, +261, 580, -663, -127, 433, -524, -212, 1391, +-507, -2001, 651, 2088, -897, -1752, 664, 1378, +-783, -949, 433, 357, -345, 362, -81, -788, +-28, 888, -162, -960, 93, 1321, -543, -1664, +671, 1575, -1121, -947, 1050, 176, -1095, 552, +431, -1210, -2, 1791, -643, -1877, 592, 1291, +-741, -306, 521, -433, -682, 748, 310, -868, +-121, 1115, -532, -1266, 728, 1006, -1113, -259, +845, -471, -695, 795, 71, -669, 69, 493, +-415, -496, 341, 692, -670, -873, 606, 967, +-809, -847, 574, 478, -733, 176, 524, -825, +-545, 1183, -13, -1078, 324, 737, -927, -361, +976, 92, -1220, 75, 1038, 13, -1229, -312, +951, 594, -787, -363, 21, -421, 371, 1332, +-842, -1694, 676, 1324, -783, -490, 628, -307, +-893, 870, 740, -1066, -714, 907, 75, -416, +417, -140, -1119, 590, 961, -846, -509, 1032, +-472, -1024, 714, 591, -598, 388, -230, -1439, +549, 1887, -706, -1286, 196, 34, -78, 1055, +-48, -1333, -289, 975, 44, -546, 243, 435, +-751, -330, 335, -130, 296, 852, -1026, -1164, +696, 787, -121, -54, -646, -346, 758, 293, +-997, -23, 971, -251, -1036, 668, 436, -1042, +29, 958, -521, -161, 463, -781, -771, 1145, +1012, -679, -1449, -91, 1207, 691, -889, -946, +191, 891, 235, -350, -895, -588, 1068, 1480, +-1016, -1743, 373, 1423, -109, -948, 13, 632, +-214, -211, -222, -510, 788, 1280, -1326, -1465, +947, 956, -295, -243, -517, 27, 740, -349, +-968, 743, 991, -718, -1216, 359, 849, 6, +-140, -112, -1116, 124, 1781, -238, -1680, 585, +399, -973, 888, 1119, -1657, -604, 1112, -610, +11, 2011, -1268, -2595, 1638, 1753, -1256, 222, +72, -2231, 992, 3345, -1732, -3174, 1573, 1930, +-1036, -13, 169, -1882, 352, 2984, -791, -2750, +850, 1424, -950, 233, 693, -1399, -434, 1785, +-9, -1481, 44, 835, 64, -203, -343, -81, +119, 31, 334, 44, -926, 291, 1003, -924, +-846, 1295, 491, -824, -376, -285, 214, 1190, +-141, -1118, -132, 223, 331, 646, -699, -655, +812, -190, -749, 1262, 198, -1759, 284, 1310, +-586, -71, 232, -1241, 369, 1870, -1109, -1475, +1255, 533, -723, 216, -579, -385, 1762, 237, +-2259, -96, 1562, 11, -220, 239, -1258, -653, +2093, 962, -2133, -786, 1214, -22, 110, 1242, +-1426, -2173, 2030, 2057, -2006, -645, 1285, -1269, +-284, 2399, -888, -2060, 1516, 806, -1451, 299, +667, -721, 15, 798, -325, -990, 145, 1299, +-47, -1248, 94, 594, -326, 356, 389, -956, +-286, 846, -122, -246, 496, -128, -621, -202, +165, 972, 475, -1301, -884, 669, 569, 463, +98, -1013, -779, 533, 955, 325, -803, -514, +305, -109, 188, 731, -676, -580, 897, -155, +-961, 707, 679, -681, -82, 398, -814, -264, +1362, 166, -1035, 267, -152, -1011, 1129, 1479, +-1018, -1176, -208, 409, 1360, 71, -1591, 16, +854, -5, -56, -768, -454, 1905, 754, -2079, +-1262, 699, 1514, 1085, -966, -1453, -535, 179, +1763, 908, -1532, -24, -245, -2205, 1826, 3185, +-1603, -1287, -358, -2081, 2018, 3795, -1687, -2314, +-392, -758, 2163, 2542, -2116, -1793, 423, -215, +1379, 1502, -2108, -1371, 1482, 469, -128, 424, +-1171, -1000, 1512, 978, -638, -28, -902, -1393, +1700, 1764, -1018, -36, -459, -2639, 949, 3549, +252, -1401, -1923, -1893, 1890, 3194, 330, -1629, +-2819, -576, 3043, 908, -628, 557, -2215, -1668, +2859, 1027, -910, 606, -1660, -1674, 2603, 1653, +-1568, -1099, -76, 572, 793, -150, -459, -80, +-22, 19, -233, 39, 1007, 477, -1412, -1417, +790, 1642, 471, -395, -1362, -1332, 1221, 1656, +-386, -198, -199, -1241, 50, 932, 371, 431, +-123, -620, -1010, -1078, 2176, 2735, -2155, -2185, +649, -160, 1319, 1970, -2270, -1914, 1732, 944, +-592, -500, 78, 605, -362, -315, 467, -602, +472, 1448, -1948, -1681, 2433, 1415, -1064, -680, +-1102, -675, 2102, 2121, -1104, -2409, -475, 1211, +724, 6, 556, 277, -1419, -1266, 418, 798, +1549, 1331, -2004, -2510, 266, 808, 1702, 1851, +-1460, -1889, -598, -1017, 1920, 3170, -855, -1770, +-1163, -1306, 1835, 2148, -731, -275, -338, -1007, +272, -359, 152, 2102, 372, -1103, -1228, -1798, +901, 2826, 780, -621, -1789, -1815, 799, 1487, +1078, 400, -1299, -531, -392, -1468, 1779, 2411, +-727, -335, -1714, -2437, 2829, 2459, -1324, 80, +-994, -1688, 1886, 423, -1002, 1660, 88, -1645, +-177, -254, 671, 1354, -256, -324, -886, -1213, +1602, 1185, -1012, 295, -152, -1499, 903, 1551, +-860, -1109, 738, 892, -726, -616, 521, -220, +364, 1261, -1232, -1648, 1262, 1167, -288, -402, +-548, -129, 604, 494, -230, -809, 432, 804, +-959, -297, 943, -200, 46, -1, -898, 680, +903, -811, -413, -95, 552, 1060, -962, -759, +535, -602, 1108, 1320, -2243, -313, 1555, -1421, +402, 2010, -1379, -1075, 723, -28, 371, 203, +-247, 0, -672, 511, 1062, -1519, -256, 1805, +-642, -942, 738, -88, -28, 365, -434, -250, +288, 517, 349, -988, -765, 878, 727, -270, +-57, 92, -645, -536, 857, 429, -179, 958, +-546, -2382, 498, 1988, 453, 11, -1012, -1265, +525, 376, 501, 1044, -564, -539, -335, -1706, +1031, 2909, -301, -1414, -1025, -1101, 1560, 1901, +-709, -718, -280, -332, 487, -62, 65, 867, +-400, -702, 447, -121, -327, 438, 151, -290, +539, 609, -1214, -1257, 1025, 970, 364, 444, +-1523, -1254, 1295, 243, 40, 1231, -717, -931, +328, -978, 133, 2049, 529, -1010, -1446, -510, +1375, 487, -40, 534, -1042, -556, 1098, -714, +-456, 1449, 213, -640, -212, -476, 73, 422, +396, 265, -485, -175, 213, -587, 134, 552, +-99, 584, 126, -1282, -253, 423, 304, 925, +176, -1036, -605, 8, 497, 560, 195, -52, +-483, -341, 168, -336, 277, 1179, 53, -738, +-703, -729, 901, 1439, -132, -549, -676, -755, +858, 938, -329, -136, -3, -304, -49, -106, +276, 425, -53, 158, -294, -1128, 461, 1437, +-172, -939, 10, 310, -51, 42, 264, -382, +-118, 787, -115, -853, 295, 328, -125, 277, +22, -406, 51, 226, -39, -200, 219, 204, +-222, 259, 72, -983, 250, 1036, -242, -97, +99, -896, 103, 927, -52, -303, 84, 95, +-62, -489, 3, 562, 300, 212, -283, -1088, +-58, 1067, 500, -328, -236, -140, -421, -35, +819, 247, -245, 2, -510, -392, 699, 371, +15, -44, -593, -109, 600, -19, -89, 72, +-74, 61, 30, -116, 11, -64, 313, 169, +-318, 7, -71, -191, 611, 17, -440, 344, +-92, -422, 435, 202, -89, -212, -41, 618, +-425, -777, 1132, 49, -727, 1162, -566, -1787, +1571, 1405, -998, -703, -234, 375, 829, -132, +-223, -689, -214, 1783, -68, -2009, 602, 889, +-161, 532, -655, -917, 834, 243, 114, 284, +-726, 23, 316, -512, 603, 284, -432, 389, +-554, -440, 1151, -465, -263, 1342, -950, -1132, +1258, -4, -260, 925, -606, -951, 700, 426, +-143, -78, 52, 7, -295, 146, 492, -485, +-25, 590, -456, -136, 589, -594, -66, 951, +-385, -643, 616, -64, -400, 722, 176, -1104, +205, 1117, -405, -715, 520, -55, -272, 824, +132, -1167, -82, 1045, 157, -814, 263, 728, +-809, -616, 1036, 158, -312, 547, -535, -1048, +854, 1044, -320, -732, 19, 418, -215, -184, +652, -98, -347, 382, -304, -462, 724, 298, +-389, -126, 133, 110, -190, -108, 436, -149, +-62, 590, -493, -789, 686, 420, -71, 346, +-442, -999, 478, 1103, 4, -678, -173, 48, +184, 381, -185, -396, 501, 67, -492, 267, +161, -227, 336, -264, -213, 733, -156, -631, +363, -48, 94, 605, -489, -420, 499, -326, +-30, 812, -101, -584, -76, 18, 335, 232, +-18, -88, -424, -72, 687, -22, -395, 200, +104, -271, 157, 217, -251, -35, 502, -427, +-502, 1051, 305, -1306, 114, 765, -199, 184, +182, -665, -212, 440, 572, -197, -682, 598, +416, -1233, 194, 1135, -429, -155, 371, -767, +-138, 783, 142, -188, -16, -143, -186, -39, +448, 196, -287, -21, 39, -137, 112, -34, +66, 161, 43, 181, -418, -631, 802, 378, +-424, 543, -323, -1108, 791, 612, -315, 289, +-370, -501, 601, 5, -116, 204, -189, 318, +28, -754, 381, 264, -211, 631, -229, -766, +431, 2, -7, 496, -210, -15, -122, -642, +708, 243, -467, 1000, -406, -1626, 1045, 841, +-564, 418, -247, -803, 494, 244, 97, 143, +-423, 274, 68, -881, 593, 849, -591, -307, +166, 7, 141, -180, 59, 268, -140, 162, +-63, -752, 356, 865, -176, -516, -48, 272, +-72, -436, 572, 643, -564, -445, -78, -95, +810, 529, -631, -646, -122, 573, 603, -497, +-80, 396, -730, -184, 955, -117, -192, 433, +-660, -670, 892, 638, -262, -235, -393, -352, +552, 648, -92, -436, -314, 84, 375, -73, +-68, 305, -41, -273, -113, -146, 388, 474, +-336, -326, 124, 28, 91, -136, -23, 491, +-30, -393, 13, -344, 130, 978, -65, -778, +-88, 42, 215, 319, -20, 1, -232, -371, +437, 104, -334, 556, 128, -874, 171, 583, +-383, -117, 577, -103, -514, 150, 207, -289, +376, 468, -815, -412, 887, 107, -440, 152, +-73, -148, 348, -20, -179, 153, 6, -239, +-6, 323, 195, -334, -123, 177, -141, 64, +315, -235, 44, 341, -581, -500, 765, 671, +-236, -637, -417, 342, 653, -66, -257, -56, +-103, 227, 32, -659, 401, 1061, -513, -867, +172, 17, 351, 780, -429, -861, 124, 398, +221, -120, -94, 298, -265, -506, 502, 284, +-252, 185, -120, -428, 290, 287, -18, -71, +-296, 63, 336, -225, 57, 379, -412, -439, +413, 344, 22, -47, -342, -337, 252, 500, +195, -297, -384, 5, 137, 14, 311, 173, +-340, -183, 2, -84, 347, 225, -257, 20, +25, -285, 30, 28, 200, 628, -227, -948, +-51, 555, 399, 62, -304, -260, -68, 125, +328, -233, -186, 698, 16, -921, -9, 474, +79, 170, 212, -259, -695, -150, 888, 253, +-361, 344, -387, -1025, 729, 950, -353, -206, +-129, -372, 242, 325, 62, -65, -235, 159, +155, -494, -7, 532, 170, -150, -410, -209, +445, 189, -94, 12, -276, -50, 490, -43, +-470, 16, 372, 71, -39, 107, -427, -567, +768, 759, -478, -231, -268, -697, 923, 1165, +-861, -756, 359, -98, 85, 637, -114, -574, +56, 242, -59, -91, 118, 207, 32, -371, +-146, 313, 49, 18, 294, -439, -444, 631, +333, -420, -95, -46, 58, 337, -37, -180, +-102, -229, 365, 387, -353, -51, 94, -493, +184, 726, -160, -477, 107, 61, -256, 157, +589, -180, -564, 294, 97, -586, 456, 759, +-476, -486, 120, -144, 130, 649, 148, -682, +-539, 333, 608, 20, -232, -141, -69, 45, +106, 110, -10, -179, 155, 65, -411, 233, +551, -500, -391, 431, 180, 12, 23, -427, +-211, 392, 455, 46, -443, -381, 105, 247, +350, 166, -406, -380, 163, 218, -1, 21, +233, -20, -408, -160, 144, 223, 441, -68, +-615, -92, 198, 55, 348, 111, -357, -184, +19, 113, 121, -35, 198, 41, -412, -51, +139, -43, 454, 213, -703, -342, 511, 404, +-201, -434, 162, 391, -145, -165, -70, -184, +389, 393, -372, -218, 75, -221, 116, 548, +151, -511, -486, 219, 412, 41, 168, -125, +-631, 107, 578, -128, -101, 236, -225, -409, +247, 520, -123, -408, 175, 19, -280, 439, +232, -623, 102, 451, -456, -212, 646, 245, +-563, -472, 373, 479, -138, -30, 1, -632, +95, 1091, -207, -1164, 471, 963, -718, -598, +728, 67, -291, 544, -289, -949, 597, 888, +-399, -457, 108, 18, -69, 134, 296, -54, +-334, 15, 29, -204, 398, 511, -442, -647, +80, 420, 307, 76, -276, -469, -85, 485, +458, -237, -476, 94, 198, -251, 166, 460, +-331, -328, 363, -206, -324, 702, 296, -706, +-191, 247, 46, 230, 97, -331, -127, 88, +123, 174, -156, -217, 287, 64, -329, 110, +204, -142, 7, 30, -98, 126, 97, -163, +-101, 25, 174, 218, -157, -367, -16, 279, +263, 7, -322, -280, 211, 369, -107, -289, +160, 181, -202, -111, 91, 49, 157, 46, +-313, -106, 304, 49, -217, 88, 227, -153, +-214, 42, 61, 169, 145, -320, -92, 329, +-195, -234, 399, 84, -204, 123, -227, -327, +467, 410, -287, -283, 45, 23, -98, 180, +369, -256, -372, 286, 22, -397, 349, 512, +-312, -451, -57, 160, 341, 177, -235, -320, +-25, 241, 112, -186, 72, 350, -291, -641, +409, 745, -380, -471, 235, -9, 18, 342, +-294, -346, 495, 167, -474, -89, 289, 185, +-95, -268, -8, 166, 87, 54, -105, -163, +0, 62, 185, 133, -241, -265, 78, 335, +181, -410, -251, 434, 64, -262, 134, -78, +-86, 335, -84, -270, 78, -13, 160, 190, +-362, -139, 341, 28, -132, -41, -82, 114, +208, -39, -293, -173, 352, 308, -289, -260, +168, 204, -180, -348, 335, 611, -348, -703, +86, 468, 237, -55, -298, -305, 131, 501, +-58, -568, 254, 514, -438, -304, 276, 46, +18, 84, -10, -26, -227, -38, 193, -146, +310, 527, -776, -744, 607, 486, 86, 118, +-527, -592, 248, 609, 296, -309, -392, 80, +-6, -74, 363, 111, -347, 7, 134, -203, +-40, 264, 80, -162, -37, 61, -135, -49, +198, 75, -117, -107, 125, 234, -305, -430, +360, 417, -72, -5, -341, -532, 444, 646, +-108, -268, -247, -55, 164, -211, 253, 805, +-494, -959, 319, 377, 11, 363, -200, -552, +179, 252, -77, -73, -64, 320, 231, -589, +-348, 416, 180, 69, 277, -324, -655, 112, +603, 224, -276, -270, 58, -14, -65, 339, +34, -470, 207, 371, -474, -106, 360, -216, +113, 443, -462, -457, 327, 309, 3, -141, +-123, -13, 15, 259, -30, -595, 263, 807, +-490, -661, 399, 257, -155, 76, 88, -127, +-237, 15, 213, 37, 86, -3, -336, -30, +229, 49, 27, -161, -70, 377, -204, -573, +408, 629, -286, -523, 3, 279, 22, 73, +169, -415, -290, 535, 192, -378, -70, 186, +4, -284, 71, 630, -330, -795, 625, 478, +-686, 82, 377, -429, -46, 462, -99, -500, +82, 819, -211, -1175, 415, 1154, -524, -688, +343, 91, -46, 398, -179, -853, 204, 1357, +-244, -1707, 321, 1585, -363, -994, 181, 329, +42, 147, -206, -537, 181, 1044, -125, -1532, +87, 1641, -177, -1219, 173, 571, -71, -44, +-117, -343, 199, 716, -177, -1006, -34, 965, +265, -630, -440, 372, 352, -404, -109, 500, +-263, -298, 490, -166, -570, 527, 499, -612, +-436, 633, 153, -766, 287, 871, -764, -618, +835, -7, -494, 622, -77, -867, 340, 775, +-267, -661, 34, 642, -13, -498, 17, 34, +-21, 575, -44, -905, -80, 817, 194, -573, +-175, 445, -175, -307, 372, -78, -179, 644, +-340, -971, 463, 823, -128, -469, -305, 351, +192, -453, 156, 317, -301, 399, -107, -1349, +464, 1786, -402, -1371, -37, 521, 138, 103, +96, -371, -364, 676, 134, -1226, 240, 1701, +-475, -1629, 308, 989, -194, -174, 182, -468, +-257, 894, 59, -1189, 48, 1384, 30, -1422, +-300, 1291, 163, -1010, 291, 608, -786, -108, +755, -427, -494, 865, 296, -1113, -430, 1217, +327, -1331, 55, 1553, -605, -1709, 724, 1542, +-642, -961, 509, 141, -623, 709, 531, -1484, +-207, 2058, -327, -2210, 480, 1818, -397, -1028, +160, 170, -124, 504, -23, -831, 130, 657, +-155, -50, -241, -499, 581, 316, -616, 697, +135, -1735, 180, 1770, -202, -734, -10, -307, +-160, 304, 463, 483, -724, -797, 528, 3, +-287, 1096, 2, -1317, 133, 671, -459, -246, +603, 661, -515, -1205, -20, 953, 337, -107, +-244, -318, -384, -41, 803, 403, -846, -7, +404, -867, -78, 1383, -249, -1332, 538, 1174, +-1023, -1146, 1118, 875, -860, -112, 285, -690, +-68, 969, 0, -824, -54, 762, -167, -846, +296, 771, -563, -532, 834, 439, -1191, -388, +927, -181, -180, 1250, -701, -1901, 850, 1472, +-676, -534, 483, 99, -634, -113, 426, -309, +60, 1312, -643, -1848, 651, 1186, -603, -36, +700, -379, -1061, -17, 795, 183, 1, 482, +-950, -1276, 1078, 1177, -732, -219, 289, -487, +-411, 161, 528, 741, -472, -1101, 30, 463, +63, 557, 129, -1143, -457, 1112, 116, -824, +574, 509, -1251, -118, 1083, -172, -563, -25, +131, 727, -403, -1276, 665, 906, -467, 375, +-546, -1818, 1382, 2557, -1543, -2194, 710, 913, +72, 658, -269, -1670, -446, 1525, 1008, -492, +-762, -435, -665, 449, 1982, 214, -2229, -587, +848, 191, 838, 377, -1702, -228, 982, -665, +253, 1343, -1055, -905, 564, -552, 446, 1982, +-1209, -2309, 793, 1323, 104, 178, -704, -1101, +209, 1084, 356, -756, -173, 923, -1134, -1449, +2083, 1407, -1810, -282, 164, -1307, 1457, 2270, +-2393, -2157, 2182, 1312, -1427, -218, 282, -857, +484, 1707, -906, -2008, 882, 1573, -1042, -516, +1053, -805, -861, 1868, 164, -1994, 223, 851, +-254, 976, 36, -2227, -351, 2115, 642, -1018, +-512, -153, -292, 1071, 628, -1972, -255, 2699, +-558, -2470, 716, 890, -448, 1228, -14, -2591, +285, 2708, -887, -2034, 1267, 988, -888, 438, +-654, -1889, 1889, 2253, -1812, -854, 402, -1216, +590, 1754, -543, 88, -162, -2499, 57, 2793, +770, -351, -1626, -2588, 1281, 3299, -59, -1339, +-1290, -1259, 1419, 2256, -402, -1237, -1114, -445, +1589, 1199, -753, -432, -1018, -1221, 2338, 2343, +-2687, -1707, 1714, -612, -79, 2959, -1767, -3419, +2753, 1753, -2669, 391, 1492, -1313, -172, 975, +-966, -566, 1450, 804, -1458, -1233, 723, 1075, +246, -142, -1128, -1103, 1177, 1923, -592, -1612, +-433, 17, 1106, 1857, -1320, -2353, 913, 802, +-440, 1415, -55, -2173, 314, 951, -638, 644, +729, -863, -741, -107, 607, 601, -775, 336, +842, -1718, -549, 1835, -433, -259, 1339, -1656, +-1748, 2187, 1354, -931, -700, -896, -176, 1677, +841, -810, -1098, -781, 466, 1530, 350, -719, +-533, -786, -431, 1380, 1387, -509, -1323, -656, +-13, 653, 1277, 414, -1650, -991, 1021, 228, +-390, 838, 31, -745, 159, -236, -848, 477, +1712, 557, -2044, -1352, 818, 422, 1507, 1459, +-3489, -2119, 3234, 867, -850, 589, -1967, -437, +3036, -867, -2280, 1204, 890, 403, -54, -2415, +-750, 2520, 1923, -459, -2843, -1472, 1845, 1012, +880, 1301, -3306, -2474, 3091, 575, -684, 2744, +-1627, -3904, 1749, 1602, -290, 1723, -946, -2841, +564, 1370, 839, 444, -2040, -943, 1967, 553, +-739, -153, -1150, -425, 2544, 1386, -2553, -1514, +696, -415, 1785, 3116, -2869, -3412, 1197, 221, +1734, 3434, -3056, -3701, 1269, 575, 1485, 2187, +-2100, -1772, -164, -512, 2346, 1566, -1653, -519, +-1519, -889, 3758, 1243, -2862, -951, -288, 713, +2694, -193, -2631, -820, 576, 1212, 1388, -37, +-1782, -1435, 452, 981, 1108, 1221, -1401, -2304, +124, 639, 1121, 1537, -869, -1023, -686, -1683, +1585, 2817, -753, -477, -943, -2728, 1600, 3209, +-741, -1028, -550, -807, 884, 656, -266, 221, +-444, -305, 308, -137, 688, 403, -1794, -885, +1668, 1768, 185, -1669, -2545, -455, 2981, 2709, +-762, -2048, -1925, -1174, 2018, 2923, 378, -922, +-2020, -1888, 574, 1471, 1942, 1235, -1897, -1558, +-994, -1811, 2874, 4340, -1010, -1942, -2515, -2957, +3296, 4489, -472, -1314, -2434, -1855, 2115, 1009, +380, 1918, -1677, -2349, 457, -419, 1214, 2690, +-1168, -1794, -332, -579, 1311, 1270, -918, 83, +58, -1170, 116, 595, 79, 402, 438, -24, +-1778, -1423, 2319, 1832, -644, -15, -2327, -2541, +3614, 3198, -1673, -1278, -1434, -966, 2185, 1049, +-152, 520, -1394, -892, -122, -1154, 2830, 3157, +-2869, -2111, -410, -1263, 3448, 3220, -3293, -1852, +1017, -560, 472, 991, -609, 241, 973, -546, +-1968, -799, 1905, 1790, -60, -979, -1675, -489, +1313, 993, 240, -852, -596, 1154, -565, -1378, +1137, 197, -34, 1809, -1135, -2357, 591, 755, +781, 875, -806, -699, -617, -220, 1295, -91, +-124, 1112, -1278, -579, 944, -1505, 512, 2254, +-996, -115, 96, -2354, 424, 1829, 511, 907, +-1569, -1934, 945, -220, 987, 2535, -2169, -1997, +1548, -210, -100, 914, -843, 169, 978, -435, +-621, -1061, -90, 2059, 750, -903, -526, -648, +-637, 270, 1313, 1045, -372, -620, -1084, -1284, +917, 1651, 716, 335, -1220, -1542, -637, -237, +2400, 2456, -1205, -1424, -1864, -1879, 2976, 2944, +-866, -358, -1557, -2121, 1492, 1203, 43, 1300, +-390, -1587, -596, -488, 876, 1762, 164, -783, +-935, -571, 581, 648, -259, -319, 776, 643, +-932, -624, -300, -854, 1641, 2400, -1247, -1739, +-264, -691, 697, 2048, 368, -1099, -983, -233, +69, -86, 1085, 1255, -1029, -1181, 306, -259, +-24, 1214, -68, -718, 776, -142, -1404, 109, +705, 504, 881, -705, -1413, 357, 478, -20, +210, -218, 486, 674, -1085, -1132, -25, 857, +1858, 149, -1897, -873, -83, 603, 1699, 17, +-1193, 68, -222, -740, 591, 838, 152, 61, +-402, -977, -294, 840, 872, 20, -477, -407, +-202, -55, 323, 572, -29, -441, 57, 27, +-334, -9, 375, 287, -48, -253, -80, -195, +-58, 521, 60, -453, 328, 390, -530, -561, +211, 482, 321, 301, -365, -1231, 46, 1262, +172, -291, -58, -599, 67, 628, -259, -302, +319, 532, 89, -1139, -435, 1084, 346, -69, +62, -951, -123, 1024, -50, -446, 123, 144, +-10, -319, 303, 359, -805, 102, 722, -674, +481, 798, -1600, -394, 1409, -280, -85, 908, +-629, -1093, 250, 493, 186, 556, 429, -1038, +-1138, 385, 800, 601, 331, -660, -606, -242, +-9, 861, 210, -481, 776, -89, -1395, -122, +519, 608, 1030, -137, -1232, -1139, 196, 1605, +560, -416, -132, -1128, -275, 1292, -6, -204, +408, -511, 79, 78, -588, 537, 235, -343, +661, -283, -501, 402, -546, -26, 1121, -114, +-220, -199, -864, 474, 955, -410, -137, 247, +-223, -60, 42, -344, 158, 713, 222, -434, +-539, -350, 550, 558, -155, 276, -185, -1031, +628, 516, -820, 603, 724, -711, -180, -192, +-229, 397, 565, 781, -736, -1644, 819, 560, +-163, 1414, -743, -1928, 1064, 679, -128, 308, +-682, 156, 340, -788, 826, 33, -809, 1435, +-495, -1749, 1640, 597, -1038, 550, -228, -680, +811, 361, -386, -347, 353, 340, -714, 162, +779, -694, 99, 470, -734, 309, 633, -693, +-70, 420, 66, -157, -66, 293, -270, -241, +750, -507, -122, 1354, -994, -1306, 1386, 297, +-232, 710, -872, -917, 880, 448, 57, 95, +-281, -346, -151, 260, 518, 97, 39, -511, +-529, 590, 502, -175, 107, -366, -318, 489, +339, -159, -198, -92, 226, -144, 135, 593, +-425, -652, 476, 150, 56, 431, -269, -538, +103, 173, 372, 187, -246, -218, -116, 53, +503, 66, -338, -211, 213, 564, -70, -887, +114, 640, 178, 237, -359, -996, 478, 884, +-127, -148, -145, -213, 389, -253, -114, 862, +-286, -692, 830, -256, -709, 1084, 145, -1135, +705, 615, -875, -123, 704, -66, -404, 42, +592, 58, -495, -134, 31, 12, 783, 426, +-896, -868, 559, 758, -23, 9, 18, -700, +34, 490, -29, 487, 110, -1103, 233, 572, +-316, 563, 170, -1053, 214, 530, 26, 103, +-292, 55, 181, -643, 658, 631, -949, 196, +546, -931, 199, 864, -142, -382, 32, 192, +-323, -210, 1089, -177, -837, 904, -196, -1136, +1036, 549, -493, 118, -155, -109, 22, -190, +816, -100, -570, 880, -501, -1102, 1240, 386, +-451, 295, -381, -44, 294, -556, 584, 242, +-415, 962, -560, -1613, 1242, 854, -432, 368, +-520, -685, 681, 163, 107, 12, -329, 578, +-24, -992, 524, 425, -174, 588, -320, -976, +624, 550, -274, 39, -49, -319, 456, 416, +-541, -451, 572, 272, -173, 141, -122, -453, +445, 432, -418, -256, 456, 122, -178, 68, +-49, -353, 305, 431, -54, -67, -91, -362, +77, 264, 316, 284, -197, -568, -167, 222, +448, 288, 104, -356, -560, 123, 431, -184, +434, 633, -666, -871, 144, 488, 691, 157, +-576, -422, -44, 250, 617, -131, -353, 360, +-64, -624, 434, 540, -299, -182, 95, -64, +376, 101, -553, -194, 494, 471, 37, -644, +-233, 423, 121, 48, 255, -339, -69, 309, +-256, -237, 503, 363, -217, -569, 135, 578, +-177, -311, 317, -88, 19, 456, -187, -622, +77, 441, 345, -15, -122, -191, -434, -166, +831, 751, -308, -774, -236, 21, 249, 742, +438, -685, -552, 24, -62, 275, 982, 118, +-926, -458, 188, 106, 575, 440, -390, -277, +-103, -449, 380, 654, 70, 73, -398, -793, +325, 564, 249, 218, -372, -490, 67, 82, +497, 115, -432, 340, -13, -738, 541, 338, +-389, 513, -69, -910, 548, 652, -402, -257, +15, 59, 422, 107, -332, -319, 88, 336, +133, -93, 169, -45, -495, -125, 597, 280, +-82, -132, -355, -17, 469, -230, -63, 527, +-70, -184, -125, -700, 543, 1158, -412, -644, +3, -193, 380, 400, -143, -45, -143, -51, +139, -384, 421, 698, -728, -369, 532, -205, +166, 332, -492, -12, 411, -192, -95, 6, +220, 285, -423, -392, 416, 348, 144, -285, +-535, 159, 493, 41, -10, -190, -109, 217, +-89, -236, 363, 259, -167, -107, -55, -186, +79, 225, 195, 198, -74, -634, -302, 409, +589, 366, -195, -841, -344, 543, 549, 34, +-150, -152, -188, -116, 333, 143, -283, 224, +403, -462, -304, 243, -76, 50, 672, 25, +-801, -233, 503, 60, -26, 422, -87, -581, +81, 209, -80, 98, 274, 219, -261, -842, +121, 955, 92, -352, 44, -355, -332, 585, +590, -448, -408, 393, 14, -477, 419, 401, +-523, -63, 501, -287, -307, 418, 58, -385, +381, 311, -561, -181, 309, -35, 333, 180, +-572, -138, 255, 75, 226, -257, -91, 606, +-320, -716, 400, 327, 154, 263, -496, -551, +234, 414, 254, -172, -70, 104, -457, -111, +522, -22, 235, 218, -787, -182, 474, -136, +375, 374, -595, -218, 109, -199, 424, 478, +-338, -448, 75, 278, -4, -86, 107, -233, +106, 662, -428, -791, 522, 304, -255, 454, +166, -731, -277, 306, 252, 171, 319, -33, +-888, -488, 830, 613, -58, -48, -543, -609, +472, 662, 119, -143, -428, -346, 270, 391, +112, -84, -205, -238, 92, 364, 60, -282, +-23, 115, 12, -21, -40, 52, 128, -112, +7, 53, -247, 55, 448, -35, -312, -91, +45, 12, 206, 388, -261, -765, 346, 643, +-417, -27, 389, -592, -23, 797, -424, -583, +661, 187, -464, 237, 177, -566, 18, 567, +-38, -196, 165, -206, -319, 214, 406, 108, +-204, -300, -75, 97, 323, 224, -358, -296, +299, 134, -90, -10, -140, -5, 418, 46, +-523, -204, 505, 334, -282, -315, -29, 171, +434, 34, -665, -268, 617, 469, -242, -508, +-97, 337, 252, -31, -236, -285, 393, 508, +-622, -521, 650, 228, -140, 280, -577, -659, +1014, 592, -770, -110, 157, -414, 399, 607, +-480, -402, 268, 30, 10, 164, -48, -32, +10, -252, -1, 325, 168, -66, -226, -254, +63, 281, 307, -7, -491, -177, 402, -5, +-119, 392, -6, -554, -6, 302, 63, 142, +39, -319, -180, 42, 323, 431, -378, -562, +446, 148, -426, 439, 367, -651, -183, 407, +0, -161, 234, 288, -415, -569, 538, 589, +-489, -248, 384, -123, -249, 315, 209, -432, +-136, 655, 11, -909, 276, 1032, -564, -927, +742, 594, -576, 0, 185, -716, 193, 1244, +-216, -1288, 31, 998, 24, -683, 270, 531, +-586, -312, 619, -109, -355, 656, 145, -1044, +7, 1221, -284, -1185, 750, 968, -918, -521, +570, -62, 38, 647, -321, -1042, 273, 1184, +-223, -962, 372, 486, -379, 3, 94, -190, +256, 178, -240, -244, -20, 493, 240, -572, +-234, 311, 180, 31, -39, -40, -218, -77, +462, -128, -297, 695, -215, -892, 549, 329, +-262, 603, -302, -1044, 583, 850, -420, -455, +210, 276, -121, -50, -66, -403, 511, 960, +-856, -1180, 764, 1029, -319, -650, -66, 266, +288, 180, -473, -577, 643, 851, -547, -902, +197, 916, 73, -916, -53, 898, -13, -602, +-167, 61, 427, 585, -313, -957, -189, 1027, +531, -939, -294, 1059, -259, -1242, 547, 1100, +-405, -280, 202, -779, -288, 1488, 489, -1534, +-446, 1395, 54, -1381, 392, 1436, -684, -1056, +791, 307, -830, 512, 738, -1060, -491, 1589, +121, -2099, 147, 2295, -221, -1644, 101, 476, +-51, 457, 221, -520, -662, 212, 959, -163, +-809, 571, 244, -763, 103, 494, 45, -31, +-417, 35, 328, -410, 184, 830, -649, -961, +642, 985, -504, -764, 434, 166, -378, 876, +-45, -1559, 454, 1310, -431, -191, -123, -698, +459, 665, -348, 298, 22, -1300, -66, 1834, +149, -1656, 66, 1054, -676, -133, 964, -691, +-836, 1285, 426, -1503, -203, 1753, -147, -2026, +563, 2096, -930, -1378, 773, 159, -536, 929, +439, -1262, -525, 1315, 98, -1481, 468, 1736, +-618, -1307, -85, 389, 443, 288, 196, -87, +-1460, -205, 1708, -126, -877, 950, -151, -1113, +249, 574, -225, -154, 682, 625, -1564, -1091, +1468, 644, -426, 629, -845, -1311, 1071, 989, +-641, -265, -82, 134, 398, -265, -592, 241, +267, 9, 239, 123, -800, -320, 551, -14, +121, 1067, -848, -1654, 729, 1070, -310, 279, +-142, -908, -90, 575, 399, -77, -636, 478, +122, -1250, 589, 1418, -1376, -449, 1420, -687, +-1134, 1180, 475, -796, -118, 271, -422, 161, +858, -358, -1447, 437, 1338, 51, -840, -895, +-110, 1577, 454, -1200, -451, 74, 18, 1033, +-112, -1272, 288, 961, -589, -339, 187, -385, +204, 1311, -452, -1556, -221, 487, 818, 1622, +-1102, -2788, 372, 1897, 268, 434, -638, -2078, +168, 2217, 115, -1385, -275, 706, -320, -14, +911, -839, -1640, 1636, 1418, -1511, -458, 789, +-1403, -211, 2473, 271, -2333, -20, 529, -991, +1186, 2153, -2152, -1846, 1537, 4, -696, 1959, +7, -2131, -202, 732, -74, 699, 850, -699, +-2110, 22, 1853, -19, -257, 1158, -1816, -1815, +1853, 839, -339, 1304, -1548, -2564, 1661, 2200, +-910, -813, -134, -486, 532, 1869, -1411, -3229, +2075, 3720, -2225, -2047, 846, -980, 433, 3371, +-1117, -3631, 765, 2695, -1079, -1724, 1625, 930, +-2081, 593, 1110, -2344, 54, 3008, -1099, -1660, +1245, -436, -1549, 1725, 1227, -1472, -430, 512, +-1148, 624, 1543, -1587, -706, 2259, -991, -1792, +1231, 92, -360, 2061, -1001, -2885, 980, 1773, +-399, 531, -359, -2051, 77, 1810, 97, -18, +11, -1679, -1275, 2073, 2247, -729, -2386, -1122, +506, 1997, 1919, -839, -3879, -1389, 3544, 2752, +-1692, -1616, -1163, -1120, 2964, 3170, -3392, -2575, +1702, 107, 557, 2030, -2540, -1952, 2505, 227, +-1251, 1561, -727, -1964, 1723, 1077, -2068, 494, +1403, -1699, -714, 2021, -423, -1239, 1228, 232, +-2081, 194, 1942, 157, -1168, 0, -572, -1407, +1713, 3286, -1973, -3365, 686, 970, 540, 2303, +-1281, -3613, 684, 2319, 24, 14, -767, -1083, +712, 540, -581, 588, -83, -906, 504, 334, +-901, 562, 300, -816, 548, 363, -1434, 279, +998, -57, 96, -963, -1452, 1675, 1558, -713, +-910, -1317, -346, 2521, 787, -1499, -583, -518, +-563, 1505, 1166, -758, -806, -78, -1142, -189, +2756, 1035, -2897, -784, 808, -573, 1332, 1588, +-2355, -993, 1772, -314, -1498, 815, 1569, 19, +-1425, -816, -642, 489, 3301, 673, -4601, -975, +2396, -206, 1535, 1767, -4574, -1570, 4121, -586, +-1462, 2590, -1369, -1970, 2264, -579, -2250, 1957, +2065, -218, -2153, -2260, 814, 1893, 1654, 1495, +-3775, -3687, 2868, 1675, 211, 2476, -2963, -3820, +2530, 1071, -232, 2323, -1574, -2570, 1005, 312, +237, 1366, -731, -1053, -218, 229, 1121, 128, +-1792, -654, 1793, 1809, -1183, -1885, -1001, -394, +3496, 3255, -4348, -3143, 1754, -310, 1996, 3467, +-3769, -2741, 1761, -788, 1256, 3226, -2319, -2439, +300, 91, 1998, 1523, -2290, -1789, -108, 1351, +2553, -228, -2891, -1184, 218, 1453, 2928, 529, +-3960, -2858, 1525, 2439, 1813, 963, -3278, -3496, +1600, 2308, 676, 773, -1449, -1511, 176, -576, +993, 1937, -1151, -68, 235, -2698, 496, 2838, +-982, -268, 740, -1865, -57, 1883, -869, -888, +607, 260, 605, 438, -1528, -1365, 403, 1298, +1340, 431, -1460, -1669, -825, 283, 2301, 2261, +-795, -1986, -2513, -1612, 3303, 4275, -584, -2323, +-2846, -1966, 3080, 3443, -750, -817, -1177, -1788, +572, 1025, 642, 1444, -447, -1685, -1349, -599, +2232, 2042, -1174, -353, -1026, -2376, 1862, 2677, +-782, 73, -1176, -2945, 1667, 3237, -413, -1276, +-1294, -295, 1255, 19, 99, 890, -993, -170, +-85, -2189, 1485, 3792, -1385, -2680, -349, 91, +1328, 1307, -997, -836, 632, 610, -1588, -1851, +1884, 2785, 333, -1068, -3958, -2136, 4731, 3248, +-1474, -969, -2614, -1699, 3170, 1639, -806, 363, +-817, -1043, -476, -386, 2106, 1404, -1392, -30, +-1321, -2124, 2774, 2362, -1904, -528, 131, -1052, +550, 1128, -690, -768, 1123, 1199, -1600, -1701, +576, 1058, 1384, 449, -2355, -1349, 985, 1303, +910, -1152, -1350, 1231, 267, -567, 154, -1094, +611, 2243, -1244, -1381, 323, -511, 887, 1213, +-857, -352, -282, -65, 489, -921, 539, 1560, +-1404, -40, 731, -2069, 348, 1759, -593, 961, +103, -2460, -237, 546, 787, 2416, -754, -2686, +-274, 354, 1033, 1325, -1004, -703, 593, -361, +-356, 134, -422, 497, 1584, -51, -1804, -575, +103, -212, 1572, 1669, -994, -1415, -1267, -554, +1881, 1611, 128, -414, -2094, -888, 1260, 103, +877, 1530, -1175, -1156, -738, -1143, 1824, 2354, +-512, -844, -1497, -1321, 1694, 1523, -365, 64, +-837, -1131, 1053, 608, -783, 561, 72, -1083, +957, 766, -1449, -10, 436, -700, 1071, 813, +-1195, 29, -268, -1145, 1166, 1245, -296, 48, +-1052, -1400, 960, 1354, 137, 20, -669, -1223, +294, 1185, -169, -150, 517, -882, -452, 1251, +-285, -908, 494, 328, 209, 1, -519, 69, +-611, -110, 1804, -324, -1087, 1054, -1161, -1295, +2310, 679, -1128, 290, -784, -695, 1273, 266, +-503, 444, 114, -630, -696, -4, 1089, 1055, +-378, -1667, -899, 1277, 1579, -110, -1341, -966, +663, 1355, -31, -1227, -419, 1011, 654, -724, +-669, 123, 599, 629, -524, -1033, 317, 956, +159, -780, -600, 634, 556, -182, -52, -603, +-281, 953, 54, -351, 393, -478, -392, 378, +-52, 453, 391, -683, -211, -187, -179, 870, +333, -227, -194, -917, 38, 849, 160, 436, +-431, -1224, 567, 521, -128, 510, -584, -507, +772, -158, -122, 80, -451, 827, 213, -1263, +304, 504, 131, 495, -1159, -705, 1226, 336, +218, -310, -1381, 641, 751, -666, 766, 85, +-842, 528, -585, -766, 1481, 654, -621, -317, +-443, -408, 206, 1212, 567, -1335, -42, 373, +-1311, 823, 1618, -1181, -308, 541, -709, 196, +327, -471, 399, 404, 100, -310, -1160, -16, +1355, 558, -443, -897, -199, 543, 271, 136, +-375, -517, 885, 372, -899, -133, 236, -23, +315, 100, 89, -173, -506, 62, 113, -8, +866, 219, -1047, -455, 353, -59, 499, 1092, +-729, -1479, 669, 458, -310, 774, -153, -793, +633, -150, -392, 189, -63, 1023, 44, -1825, +644, 709, -633, 1110, -337, -1608, 1268, 546, +-629, 168, -572, 289, 940, -828, -159, 157, +-83, 882, -379, -937, 457, 9, 756, 403, +-1501, 152, 717, -784, 887, 462, -978, 294, +-161, -595, 848, 191, 85, 104, -912, 26, +599, -471, 581, 697, -823, -648, 452, 159, +7, 548, -65, -1219, 591, 1230, -1043, -617, +939, -278, 16, 778, -215, -876, -210, 645, +420, -428, 852, 152, -1953, 60, 1482, -359, +585, 550, -1613, -600, 1014, 188, 440, 358, +-653, -673, 255, 322, 119, 208, 182, -460, +-44, 149, -254, 165, 588, -208, -153, -119, +-15, 374, 162, -513, -58, 343, 403, -86, +-253, -189, -184, 115, 774, 60, -231, -58, +-412, -444, 681, 833, 189, -701, -538, 25, +232, 369, 575, -330, -405, 140, 45, -317, +271, 377, 205, -18, 3, -620, -448, 544, +956, 260, -242, -1079, -592, 836, 1206, 108, +-737, -880, 414, 661, 201, -60, -407, -219, +819, -274, -396, 772, -78, -734, 611, -75, +-192, 897, -53, -1326, 484, 1082, -448, -581, +984, -99, -974, 542, 678, -670, 357, 360, +-753, -299, 1115, 736, -1084, -1364, 1477, 981, +-836, 394, -51, -1701, 1100, 1501, -877, -335, +681, -484, -568, 162, 958, 220, -75, 42, +-934, -669, 1529, 542, -323, 75, -545, -492, +604, 316, 335, -338, -83, 512, -489, -314, +920, -621, 113, 1053, -475, -277, 194, -1043, +680, 1084, -100, 126, -700, -1194, 1083, 817, +110, 19, -646, -159, 544, -509, 471, 607, +-392, 108, 105, -907, 383, 759, 34, -181, +-6, -167, 115, -122, 364, 394, -248, -457, +541, 168, -323, 183, 206, -702, 572, 1020, +-688, -1062, 751, 626, -209, -125, 404, -481, +-157, 1033, -25, -1501, 828, 1276, -763, -451, +528, -565, 135, 886, 30, -643, 178, 222, +-119, -181, 449, 142, 116, 35, -366, -396, +465, 348, 328, 3, -379, -363, 186, 136, +512, 291, -66, -435, -327, -121, 667, 664, +103, -692, -403, 98, 329, 246, 630, -163, +-710, -44, 410, -304, 618, 758, -674, -744, +382, 36, 501, 433, -460, -312, 103, -148, +795, 91, -642, 268, 190, -493, 755, 238, +-607, -48, 176, -24, 625, 89, -519, -426, +379, 456, 127, -63, -9, -430, 235, 246, +-89, 249, 344, -412, -207, -157, 443, 695, +-355, -789, 525, 446, -81, -173, -131, -237, +647, 727, -466, -1017, 386, 510, -13, 213, +299, -355, -450, -342, 667, 749, -11, -286, +-369, -607, 588, 795, 76, -434, -184, 201, +-139, -434, 1020, 312, -859, 329, 165, -915, +833, 568, -616, 182, 144, -466, 334, -36, +138, 428, -363, -272, 332, -277, 346, 511, +-413, -421, 265, 74, 340, 244, -287, -500, +174, 373, 221, -50, -69, -131, -63, -180, +414, 419, -143, -132, -176, -559, 762, 742, +-607, -294, 267, -226, 298, 108, -133, 182, +-77, -110, 241, -370, 379, 457, -717, -13, +706, -521, 38, 459, -249, 7, 43, -525, +501, 683, -177, -572, -483, 150, 1100, 331, +-638, -677, 46, 615, 338, -422, 58, 230, +-168, -91, -2, -280, 508, 585, -405, -482, +191, -79, 77, 382, 167, -96, -141, -433, +-22, 456, 400, -47, -268, -307, 105, 236, +83, -127, 115, 157, 23, -194, -190, -82, +408, 329, -69, -250, -209, -104, 276, 169, +197, 81, -384, -304, 289, 150, 231, 52, +-380, -36, 320, -176, 45, 140, -171, 123, +266, -341, -117, 226, 71, -58, 232, 92, +-494, -363, 827, 420, -654, -64, 160, -562, +567, 853, -820, -548, 744, -120, -389, 421, +297, -92, -127, -496, -47, 574, 346, -7, +-277, -727, 65, 929, 174, -556, -45, -5, +-75, 266, 275, -238, -333, 70, 427, -35, +-183, 152, -237, -282, 563, 148, -238, 171, +-217, -382, 306, 165, 200, 207, -381, -240, +-51, -237, 680, 646, -505, -485, -240, -135, +784, 536, -474, -492, 28, 271, -17, -232, +475, 186, -538, 61, 26, -372, 708, 338, +-959, 1, 752, -325, -232, 398, -218, -400, +542, 326, -454, 34, 46, -695, 392, 1031, +-319, -520, -144, -540, 527, 1119, -324, -741, +-116, -54, 256, 376, 152, -121, -510, -178, +318, 35, 383, 377, -850, -695, 686, 652, +-78, -268, -310, -312, 238, 715, 67, -600, +-172, 8, -1, 453, 271, -280, -421, -375, +477, 760, -446, -473, 277, -196, 109, 644, +-553, -689, 749, 475, -510, -180, -4, -212, +398, 554, -442, -561, 229, 131, -58, 372, +26, -503, -22, 192, -142, 159, 340, -211, +-360, -32, 98, 280, 201, -365, -326, 242, +281, -17, -301, -215, 321, 308, -192, -187, +-192, -89, 454, 278, -326, -213, -134, -83, +426, 339, -371, -384, 140, 193, -97, 7, +122, -118, -18, 174, -366, -291, 655, 374, +-627, -248, 224, -146, 161, 528, -386, -602, +317, 362, -224, -122, 145, 72, -214, -104, +189, -54, -14, 393, -407, -644, 633, 547, +-455, -154, -223, -245, 746, 336, -724, -35, +61, -481, 550, 751, -708, -430, 286, -376, +118, 1015, -271, -948, 89, 314, -56, 155, +194, -54, -438, -250, 327, 66, 34, 586, +-486, -1002, 547, 651, -365, 30, 51, -237, +15, -203, -40, 617, -7, -400, -67, -291, +59, 811, -182, -868, 320, 665, -545, -484, +448, 326, -208, -85, -112, -183, 142, 363, +-205, -472, 341, 575, -595, -668, 453, 654, +-108, -523, -163, 323, -95, -80, 358, -232, +-300, 532, -200, -699, 401, 723, -265, -751, +11, 846, -199, -873, 447, 638, -470, -184, +112, -309, 20, 738, 18, -1131, -51, 1402, +-343, -1379, 605, 1060, -491, -642, -34, 245, +250, 226, -125, -781, -200, 1133, 222, -1036, +-147, 712, -45, -616, 134, 776, -292, -722, +225, 178, -108, 522, -7, -930, -187, 1080, +257, -1240, -51, 1309, -403, -890, 406, -9, +21, 797, -523, -968, 387, 681, 108, -433, +-620, 407, 674, -396, -550, 260, 266, -70, +-36, -93, -231, 328, 292, -570, -365, 578, +471, -215, -731, -255, 646, 470, -269, -377, +-231, 252, 326, -250, -304, 246, 438, -1, +-844, -469, 914, 907, -491, -1003, -187, 669, +426, -129, -341, -176, 161, 89, -281, 10, +429, 437, -556, -1349, 498, 1917, -346, -1496, +-19, 458, 359, 325, -515, -558, 350, 796, +-281, -1384, 330, 1869, -414, -1615, 162, 788, +53, -59, 43, -387, -362, 1018, 245, -1961, +342, 2566, -802, -2144, 541, 1016, -157, -43, +272, -362, -935, 683, 1077, -1354, -416, 2180, +-495, -2585, 759, 2385, -534, -1713, 418, 751, +-660, 403, 804, -1335, -710, 1584, 493, -1138, +-435, 665, 169, -675, 309, 973, -737, -987, +663, 660, -356, -456, 281, 676, -521, -912, +613, 670, -406, 102, 66, -907, 89, 1381, +-334, -1430, 618, 1126, -733, -519, 270, -71, +368, 211, -554, 324, 187, -1083, 145, 1364, +-55, -772, -189, -319, 7, 1231, 417, -1520, +-705, 1330, 496, -1059, -149, 1040, -146, -1185, +379, 1148, -574, -534, 603, -555, -408, 1511, +189, -1622, -174, 979, 99, -387, 123, 467, +-440, -777, 387, 580, -197, 85, 315, -296, +-852, -144, 1138, 363, -588, 446, -435, -1549, +1004, 1695, -930, -751, 660, -80, -741, 168, +657, -166, -42, 845, -885, -1612, 1248, 1417, +-697, -249, -191, -688, 709, 683, -664, -166, +235, 16, 148, -280, -371, 556, 100, -635, +398, 748, -775, -826, 600, 575, -92, 170, +-194, -921, 97, 1200, 49, -988, 86, 804, +-514, -841, 801, 786, -970, -185, 880, -667, +-668, 1075, 265, -696, 153, 141, -428, -152, +638, 837, -889, -1432, 1058, 1331, -911, -494, +305, -512, 178, 1205, -294, -1240, -32, 656, +219, 252, -126, -856, -44, 806, 111, -149, +-202, -724, 655, 1541, -1374, -1957, 1621, 1624, +-1030, -324, -265, -1391, 1130, 2583, -1124, -2522, +520, 1384, -140, 182, 291, -1466, -590, 2053, +721, -1620, -709, 384, 462, 903, 194, -1251, +-1383, 582, 2003, 293, -1266, -376, -631, -230, +1969, 598, -1514, 106, -215, -1487, 1611, 2322, +-1583, -1545, 427, -520, 701, 2409, -1129, -2630, +637, 1262, -21, 261, -154, -596, -245, 49, +387, 128, 355, 615, -1400, -1307, 1558, 978, +-509, 125, -713, -897, 994, 972, -812, -757, +879, 547, -1341, 22, 1202, -834, -324, 1098, +-504, -365, 789, -416, -1018, 176, 1723, 741, +-2321, -812, 1724, -342, -128, 1436, -1518, -1160, +2239, -53, -2199, 936, 1473, -1049, -81, 928, +-1477, -633, 2091, -339, -1167, 1884, -317, -2651, +827, 1629, -226, 565, -507, -2155, 298, 2200, +381, -1145, -823, 69, 731, 432, -548, -273, +564, -133, -577, 269, 239, 246, 587, -1004, +-1701, 1252, 2220, -584, -1585, -431, -208, 1066, +1754, -1060, -1888, 670, 629, -40, 690, -675, +-931, 1132, 257, -850, 465, -7, -735, 677, +514, -490, -167, -221, -312, 632, 466, -200, +-151, -655, -473, 1142, 620, -761, 173, -146, +-1340, 812, 1826, -677, -1166, 93, -171, 113, +1141, 566, -1409, -1487, 978, 1459, -361, 94, +-246, -2203, 529, 3141, -283, -1895, -365, -735, +901, 2784, -768, -2635, -79, 488, 932, 1881, +-1195, -2495, 547, 986, 411, 1148, -1055, -1877, +776, 731, 323, 874, -1529, -1192, 1957, 211, +-1264, 605, -37, -218, 1087, -577, -1639, 356, +1742, 954, -1617, -1761, 957, 861, 49, 1071, +-901, -2056, 1134, 1140, -1014, 675, 1101, -1520, +-1319, 778, 911, 474, 304, -764, -1577, 42, +1607, 455, -480, 230, -719, -1318, 797, 1313, +-32, 8, -363, -1046, -318, 608, 1263, 421, +-1037, -163, -733, -1362, 2503, 2051, -2650, -572, +1021, -1432, 641, 1421, -1147, 498, 978, -1521, +-1322, 14, 1950, 2109, -1338, -1845, -967, -728, +3032, 2504, -2667, -1284, -77, -1379, 2546, 2355, +-2751, -761, 988, -1332, 749, 1856, -1282, -929, +746, -88, 223, 775, -1064, -1536, 1027, 1996, +452, -908, -2759, -1628, 3655, 3202, -1598, -1642, +-2395, -1758, 4890, 3184, -3559, -836, -462, -2670, +3565, 3398, -3271, -657, 385, -2601, 2046, 3631, +-1923, -2368, -266, 288, 1910, 1591, -1145, -2564, +-1538, 1843, 3337, 224, -2060, -1322, -1552, -281, +4121, 2775, -3047, -2367, -676, -1451, 3321, 4525, +-2553, -3149, -442, -872, 2395, 2665, -1902, -747, +180, -1416, 723, 714, -366, 1499, -188, -1972, +-118, 249, 1314, 1391, -2489, -1556, 2289, 950, +-159, -173, -2799, -1142, 3973, 2441, -2070, -1847, +-1179, -821, 2406, 2588, -668, -927, -1357, -2182, +753, 2402, 1754, 1007, -2845, -3838, 849, 2591, +1956, 913, -2463, -2178, 282, 102, 1838, 1998, +-1536, -1095, -794, -1712, 2590, 3068, -2048, -1632, +-113, -579, 1508, 1015, -924, 345, -320, -1187, +-24, -69, 1779, 2107, -2402, -2286, 262, 216, +2562, 1460, -2785, -508, 305, -1684, 1554, 1878, +-652, 503, -1236, -2407, 1172, 1457, 582, 715, +-1412, -967, 398, -722, 273, 1303, 963, 599, +-2329, -2360, 1077, 951, 2246, 2532, -4028, -3894, +2077, 1314, 1436, 2262, -2789, -2947, 1119, 889, +775, 340, -428, 1054, -1318, -2589, 1668, 1175, +192, 2319, -2168, -4075, 2126, 2478, -566, 71, +-610, -879, 847, 421, -1139, -641, 1561, 1438, +-841, -1144, -1339, -222, 2888, 750, -1968, 140, +-283, -583, 1188, -466, -325, 1194, -188, 152, +-783, -1964, 1624, 1426, -871, 990, -436, -1950, +453, 381, 324, 914, -90, 175, -1085, -1541, +1206, 336, 288, 2084, -1469, -1830, 897, -1426, +237, 3464, -318, -1483, -161, -1941, -218, 2711, +1055, -819, -911, -456, -76, -201, 351, 837, +210, -18, -67, -911, -1033, 532, 1126, 169, +649, 279, -1996, -1099, 620, 560, 1945, 891, +-2292, -1148, 50, -113, 1658, 810, -925, 247, +-437, -1438, 159, 798, 1052, 1032, -1072, -1771, +-276, 677, 1300, 766, -1230, -1030, 738, 179, +-165, 738, -812, -936, 1669, 283, -1102, 737, +-694, -1210, 1618, 570, -568, 619, -823, -1035, +529, 212, 787, 791, -866, -622, -687, -697, +1862, 1813, -1251, -1470, -225, -207, 1007, 1931, +-972, -2407, 811, 1461, -512, -109, -262, -534, +915, 412, -476, -321, -720, 773, 1059, -1359, +177, 1421, -1593, -826, 1334, -80, 496, 936, +-1875, -1376, 1344, 1054, 321, -171, -1205, -365, +625, -24, 239, 634, -94, -293, -743, -877, +966, 1441, -135, -659, -792, -421, 934, 475, +-551, 172, 322, -207, -175, -580, -292, 963, +824, -259, -683, -625, -49, 561, 510, 131, +-316, -384, 47, 97, -154, -71, 232, 421, +113, -325, -416, -425, 213, 750, 61, 8, +240, -743, -653, 115, 250, 1111, 785, -907, +-1228, -852, 615, 1752, 233, -238, -593, -1944, +763, 2021, -964, -87, 595, -1172, 575, 468, +-1421, 478, 874, 163, 336, -1544, -639, 1658, +-46, -408, 389, -520, 15, 395, -130, -200, +-468, 644, 671, -1047, 273, 684, -1157, -63, +704, -164, 348, 337, -415, -854, -302, 998, +218, 26, 798, -1367, -1007, 1322, -339, 139, +1597, -1127, -1133, 488, -205, 625, 571, -598, +114, -359, -344, 874, -398, -608, 1020, 401, +-754, -551, 196, 316, -16, 581, -50, -1264, +366, 982, -500, -227, 104, -175, 317, 236, +-131, -380, -324, 389, 361, 162, -98, -778, +30, 500, -1, 530, -424, -1067, 803, 587, +-326, -13, -606, 131, 737, -272, 52, -493, +-299, 1464, -574, -1095, 1052, -629, 140, 1850, +-1691, -1266, 1385, -224, 522, 923, -1548, -594, +668, 307, 412, -549, -137, 603, -478, 73, +-174, -845, 1398, 801, -1190, -52, -501, -502, +1512, 402, -675, -55, -592, -36, 627, -68, +180, -71, -327, 524, -299, -872, 561, 631, +-15, 199, -542, -1097, 554, 1433, -445, -1001, +538, 98, -356, 824, -412, -1418, 1032, 1447, +-668, -780, -187, -340, 356, 1178, 326, -1130, +-696, 354, 73, 343, 714, -501, -547, 407, +-330, -440, 718, 344, -116, 288, -673, -1148, +835, 1328, -425, -493, -37, -636, 425, 1089, +-776, -684, 816, -51, -269, 567, -477, -637, +729, 232, -425, 425, 223, -825, -366, 588, +318, 4, 328, -249, -1009, -86, 948, 459, +-261, -285, -306, -277, 475, 561, -474, -311, +355, -121, 153, 249, -749, 17, 635, -433, +329, 728, -1079, -771, 719, 525, 236, -3, +-609, -730, 299, 1363, -134, -1443, 419, 701, +-439, 491, -160, -1292, 701, 1178, -508, -507, +86, 10, -206, 7, 667, 86, -561, 67, +-178, -456, 686, 833, -470, -997, 121, 730, +-190, -10, 465, -705, -469, 675, 394, 75, +-499, -506, 400, -195, 415, 1307, -1422, -1322, +1513, -41, -501, 1314, -460, -1214, 555, 181, +-257, 477, 345, -395, -518, 207, 124, -216, +546, 6, -510, 436, -199, -424, 500, -277, +82, 701, -512, -79, -62, -814, 911, 588, +-676, 621, -476, -1193, 1122, 283, -596, 927, +-160, -940, 232, -8, 35, 420, 191, 165, +-711, -631, 701, 13, 24, 1037, -688, -1175, +753, 142, -379, 934, 14, -1054, 239, 362, +-307, 240, 114, -234, 167, -167, -73, 455, +-426, -313, 719, -211, -318, 761, -260, -936, +255, 618, 220, -157, -225, -17, -531, -61, +1194, -83, -869, 603, -72, -993, 617, 642, +-425, 231, 146, -733, -221, 395, 353, 215, +-113, -317, -207, -68, 158, 196, 132, 208, +-97, -579, -307, 339, 522, 218, -184, -393, +-300, 47, 453, 258, -305, -177, 257, -46, +-337, 103, 251, -162, 105, 423, -373, -631, +312, 327, -46, 268, -65, -398, -111, -162, +465, 596, -643, -113, 385, -898, 237, 1289, +-702, -596, 522, -389, 141, 742, -538, -498, +298, 263, 192, -243, -323, 150, 155, 115, +-142, -318, 457, 403, -678, -599, 471, 805, +61, -521, -512, -346, 642, 1009, -438, -810, +114, 209, 39, -148, 125, 568, -341, -491, +299, -359, -97, 905, 157, -330, -433, -568, +304, 410, 467, 675, -1133, -1182, 871, 368, +-34, 695, -259, -698, -285, -126, 698, 535, +-124, -149, -849, -270, 1036, 134, -252, 172, +-508, -107, 505, -179, -91, 208, -24, 46, +-131, -217, 63, 121, 401, 121, -750, -405, +625, 644, -150, -590, -212, 94, 297, 494, +-183, -621, 98, 289, -127, -130, 343, 427, +-540, -675, 498, 307, -103, 346, -256, -527, +239, 128, 36, 118, -20, 249, -507, -716, +999, 539, -787, 202, -71, -688, 733, 401, +-594, 265, -34, -562, 249, 216, 247, 372, +-866, -637, 756, 352, 15, 217, -691, -537, +573, 317, 0, 210, -291, -489, -29, 272, +471, 84, -504, -116, 137, -130, 186, 190, +-230, 129, 119, -438, -3, 295, -53, 131, +35, -292, 157, -6, -372, 335, 431, -244, +-217, -152, 46, 383, -17, -238, 33, -29, +246, 118, -613, -32, 724, -51, -303, 61, +-278, -17, 637, -87, -535, 257, 207, -318, +167, 100, -398, 255, 524, -383, -497, 198, +220, -54, 346, 240, -925, -486, 976, 260, +-345, 389, -473, -766, 675, 361, -291, 398, +-38, -592, -219, -103, 513, 939, -276, -965, +-421, 83, 619, 841, -141, -933, -462, 222, +373, 487, 165, -554, -589, 90, 544, 308, +-305, -268, -17, -87, 407, 372, -714, -295, +561, -187, 75, 775, -606, -973, 586, 519, +-145, 222, -93, -568, 80, 341, -72, -63, +398, 231, -606, -618, 440, 672, 110, -288, +-416, -123, 395, 346, -175, -516, 217, 659, +-313, -490, 301, -45, 69, 457, -466, -319, +679, -102, -491, 274, 42, -200, 496, 268, +-799, -407, 553, 68, 176, 805, -862, -1358, +815, 779, -124, 504, -541, -1253, 393, 880, +176, -76, -438, -163, -153, -282, 782, 711, +-784, -527, -42, -161, 735, 772, -815, -873, +260, 450, 150, 149, -192, -450, -104, 254, +263, 169, -180, -356, -77, 121, 264, 227, +-353, -337, 435, 199, -429, -43, 224, -112, +295, 312, -626, -375, 445, 3, 272, 643, +-659, -894, 443, 318, 223, 581, -462, -920, +348, 440, -164, 266, 364, -547, -419, 413, +116, -223, 481, 126, -620, 54, 265, -395, +254, 699, -394, -683, 257, 299, -93, 188, +53, -432, -42, 313, -60, -62, 185, 27, +-369, -255, 458, 446, -484, -331, 206, 48, +111, 128, -427, -172, 415, 300, -361, -527, +216, 540, -193, -150, -69, -329, 387, 444, +-697, -170, 543, -101, -123, 96, -337, 12, +432, 42, -381, -211, 354, 253, -386, -86, +161, -175, 391, 446, -842, -716, 762, 796, +-116, -359, -467, -540, 664, 1246, -415, -1114, +217, 341, -107, 257, 145, -242, 43, 32, +-289, -179, 619, 557, -601, -627, 343, 237, +196, 201, -548, -351, 664, 269, -431, -122, +126, -60, 198, 173, -325, -1, 215, -424, +54, 672, -203, -380, 45, -217, 172, 585, +-239, -532, 114, 353, -196, -306, 368, 279, +-390, -110, -45, -137, 364, 266, -317, -297, +-39, 399, -75, -565, 500, 558, -764, -231, +322, -257, 233, 590, -445, -628, 245, 459, +-238, -230, 387, 36, -362, 91, -58, -152, +417, 262, -349, -477, 77, 609, 6, -421, +205, -19, -332, 326, 265, -331, 33, 328, +-287, -575, 521, 703, -461, -206, 216, -675, +151, 1045, -215, -522, 135, -230, -22, 440, +97, -249, -16, 279, -219, -509, 433, 341, +-208, 314, -240, -781, 511, 631, -375, -313, +99, 392, 52, -604, -152, 337, 291, 375, +-384, -878, 178, 868, 134, -706, -287, 683, +71, -576, 157, 164, -253, 256, 173, -327, +-221, 268, 194, -531, 4, 1021, -410, -1162, +506, 775, -234, -353, -117, 287, 53, -316, +221, -40, -293, 701, 30, -1166, 134, 1235, +-51, -1181, 48, 1203, -385, -1043, 706, 414, +-490, 484, -29, -1145, 270, 1342, -67, -1298, +12, 1244, -320, -1031, 603, 459, -339, 262, +-55, -683, 67, 713, 273, -686, -249, 770, +-161, -724, 449, 397, -276, -125, 131, 249, +-302, -394, 417, -135, 24, 1253, -605, -1953, +578, 1482, 18, -253, -379, -709, 124, 946, +188, -807, -72, 740, -248, -783, 255, 792, +-68, -719, 19, 485, -96, 72, -120, -867, +475, 1437, -481, -1372, -35, 845, 407, -423, +-183, 381, -334, -399, 433, 20, -70, 706, +-249, -1271, 191, 1270, -62, -801, 170, 278, +-367, 2, 317, -112, -12, 306, -263, -726, +373, 1187, -412, -1228, 376, 593, -100, 386, +-286, -1000, 398, 879, -28, -414, -429, 313, +464, -684, -70, 933, -180, -587, 29, -148, +267, 638, -237, -626, -93, 327, 434, -19, +-607, -234, 666, 419, -651, -388, 541, 91, +-395, 265, 304, -505, -141, 808, -347, -1453, +1075, 2204, -1541, -2259, 1322, 1117, -629, 703, +21, -2058, 244, 2316, -393, -1858, 630, 1374, +-755, -1053, 433, 674, 196, -233, -566, 66, +281, -290, 435, 434, -1007, 114, 1048, -1354, +-602, 2579, -90, -2988, 785, 2418, -1245, -1404, +1276, 611, -937, -142, 534, -478, -299, 1613, +160, -2897, 111, 3440, -586, -2695, 1047, 1176, +-1301, 111, 1258, -689, -933, 1001, 420, -1582, +75, 2156, -336, -1990, 402, 1008, -553, -49, +895, -200, -1156, 46, 1023, -211, -553, 698, +118, -983, 107, 972, -349, -1088, 798, 1348, +-1266, -1088, 1315, 34, -795, 1103, -23, -1516, +710, 1302, -983, -1021, 817, 705, -407, -118, +133, -373, -241, 70, 569, 750, -598, -876, +75, -194, 597, 1386, -793, -1440, 448, 643, +-140, -275, 317, 694, -720, -848, 838, -26, +-617, 1096, 457, -950, -517, -324, 391, 1064, +345, -88, -1423, -1744, 2040, 2545, -1683, -1603, +661, -12, 335, 880, -875, -749, 986, 286, +-775, -19, 254, -21, 380, -200, -639, 851, +140, -1694, 790, 1955, -1350, -1067, 1005, -535, +-72, 1727, -777, -1747, 1118, 872, -996, 7, +558, -311, 63, 198, -690, -136, 1010, 237, +-828, -139, 160, -431, 724, 1174, -1352, -1418, +1192, 767, -173, 570, -994, -1879, 1276, 2355, +-344, -1577, -1001, 3, 1574, 1122, -847, -803, +-584, -569, 1601, 1322, -1343, -273, 24, -1777, +1127, 2710, -811, -1462, -854, -675, 2265, 1507, +-1899, -495, 57, -790, 1652, 790, -2137, 202, +1735, -842, -1111, 709, 308, -540, 693, 681, +-1227, -424, 649, -643, 514, 1591, -1004, -1315, +434, 140, 327, 702, -645, -864, 918, 1085, +-1585, -1533, 1943, 1219, -1065, 351, -681, -1967, +1863, 2037, -1885, -653, 1432, -633, -1110, 888, +430, -667, 1032, 685, -2457, -680, 2569, 89, +-1342, 848, -129, -1428, 1172, 1566, -2083, -1642, +2885, 1452, -2740, -177, 1188, -2151, 761, 3910, +-1608, -3323, 1171, 571, -607, 2210, 816, -3026, +-1396, 1790, 1447, 105, -648, -1347, -451, 1554, +1093, -1005, -735, 106, -406, 712, 1311, -1016, +-846, 668, -921, -6, 2541, -364, -2603, 110, +1213, 569, 351, -1073, -1191, 880, 1477, 47, +-1641, -1138, 1538, 1563, -786, -880, -465, -489, +1429, 1427, -1432, -1060, 491, -348, 657, 1458, +-1215, -1064, 830, -579, 106, 1871, -927, -1479, +1171, -189, -920, 1437, 440, -1138, 45, -111, +-453, 826, 662, -309, -632, -752, 378, 1215, +33, -638, -545, -438, 877, 1070, -618, -597, +-372, -735, 1505, 1788, -1886, -1305, 1188, -758, +61, 2809, -1027, -2979, 1371, 1060, -1207, 1100, +849, -1548, -510, 304, 328, 831, -240, -414, +45, -1029, 475, 1764, -1222, -952, 1850, -375, +-1892, 579, 1042, 612, 575, -1663, -2136, 993, +2487, 1108, -1177, -2623, -832, 2005, 1916, 85, +-1430, -1532, 245, 1160, 381, 117, -289, -578, +217, -158, -639, 828, 1072, -259, -841, -1044, +-76, 1518, 888, -537, -732, -749, -586, 852, +2140, 136, -2411, -734, 593, 135, 2172, 652, +-3596, -231, 2558, -1073, -384, 1351, -765, 315, +445, -2258, -143, 2031, 858, 384, -1475, -2197, +435, 997, 1811, 2029, -2864, -3216, 1163, 796, +2086, 2789, -4068, -3674, 3194, 1126, -378, 1814, +-2060, -2174, 2518, 308, -1134, 1321, -603, -1438, +1206, 680, -180, 327, -1613, -1786, 2569, 3152, +-1478, -2536, -1330, -715, 3744, 3926, -3357, -3519, +-41, -307, 3579, 3152, -3731, -1632, 166, -2379, +3512, 4060, -3542, -1475, 107, -2549, 2961, 4263, +-2586, -2878, -432, 172, 2667, 2103, -1857, -2971, +-1151, 1811, 3472, 870, -2901, -2614, -211, 1228, +3117, 1842, -3147, -2540, 464, -411, 1911, 3141, +-1438, -1644, -1000, -2388, 2244, 3577, -793, -256, +-1574, -3280, 2324, 2756, -1133, 630, -317, -2679, +659, 1916, 68, -250, -1072, -804, 1408, 1562, +-321, -1897, -1847, 768, 3142, 1218, -1810, -1431, +-1027, -831, 2008, 2258, 266, 154, -2888, -4138, +2078, 4477, 1804, -122, -4477, -4070, 3139, 3615, +236, -9, -1783, -1835, 581, 220, 776, 1745, +82, -919, -2407, -1731, 3478, 2713, -1823, -602, +-1183, -2309, 2789, 2861, -1801, -733, -87, -1351, +297, 998, 1354, 855, -2263, -1181, 514, -979, +2195, 2948, -2612, -1917, 410, -1001, 1337, 2041, +-533, -29, -1091, -1895, 910, 744, 516, 1997, +-548, -2583, -987, 476, 1195, 975, 1381, 324, +-3950, -2052, 2963, 938, 949, 2316, -3640, -3878, +2708, 2066, -157, 602, -743, -1149, -377, 63, +1148, -10, -71, 1733, -1638, -2983, 1873, 1792, +-372, 785, -1215, -2123, 1537, 1396, -943, -233, +373, 139, 205, -606, -1334, 381, 2400, 448, +-1879, -774, -316, 388, 2009, -183, -1371, 347, +-505, 51, 1112, -1131, -109, 1365, -494, 87, +-219, -1482, 584, 760, 665, 1093, -1977, -1180, +1266, -755, 648, 1632, -1171, 198, -69, -2053, +857, 792, -23, 2212, -929, -2865, 652, 337, +-115, 1907, 546, -1336, -1047, -375, 287, 582, +899, 324, -824, -279, -24, -707, -243, 842, +1392, 187, -1150, -805, -791, 424, 1689, -318, +-73, 1041, -1525, -1123, 316, -406, 2180, 1928, +-2248, -1417, -402, -410, 2214, 1067, -1115, 48, +-854, -954, 1065, 155, 53, 1320, -622, -1591, +390, 412, -310, 946, 303, -1414, 278, 857, +-770, 178, 38, -774, 1189, 115, -1009, 1419, +-504, -2149, 1148, 904, -48, 1253, -893, -2129, +39, 1163, 1359, 47, -1256, -44, 29, -745, +454, 1012, 56, -373, -169, -518, -446, 1085, +578, -1129, 75, 616, -183, 170, -788, -444, +1302, -134, -204, 758, -1198, -351, 995, -807, +420, 1341, -1025, -670, 201, -268, 672, 493, +-533, -237, -43, 193, 162, -363, 134, 360, +-407, -246, 534, 249, -362, -94, -385, -492, +1238, 944, -1075, -497, -323, -434, 1503, 637, +-1145, 17, -128, -323, 739, -326, -427, 863, +285, -320, -728, -535, 860, 385, -87, 382, +-824, -234, 882, -970, -264, 1602, -177, -764, +146, -322, 0, 332, -62, 99, 151, 387, +-246, -1378, 141, 1210, 136, 233, -284, -1009, +122, -6, 226, 1302, -452, -909, 284, -670, +301, 1219, -795, -150, 608, -700, 96, -145, +-361, 1577, -194, -1521, 628, -186, 15, 1683, +-1055, -1596, 1006, 521, 91, 245, -671, -344, +135, 324, 179, -548, 663, 788, -1380, -672, +456, 47, 1180, 877, -1307, -1541, -54, 1225, +622, 46, 571, -1249, -1552, 1301, 482, -353, +1398, -441, -1661, 461, 225, -231, 850, 291, +-562, -336, -19, -94, -67, 660, 285, -703, +-27, 284, -226, 61, -31, -279, 253, 644, +159, -853, -673, 308, 512, 611, -12, -704, +-23, -169, -279, 621, 236, 123, 97, -824, +-189, 118, 235, 1152, -749, -1052, 1133, -398, +-281, 1190, -1234, -454, 1410, -296, 189, -260, +-1387, 1057, 591, -493, 730, -864, -418, 1122, +-827, -36, 667, -724, 911, 189, -1441, 629, +11, -519, 1147, -122, -329, 253, -913, 205, +392, -486, 984, 293, -689, 31, -1219, -247, +1968, 401, -319, -388, -1629, 104, 1588, 145, +-209, 34, -474, -288, 17, -68, 421, 897, +-311, -1141, 171, 288, -138, 792, -271, -1035, +905, 575, -865, -304, 84, 334, 319, -31, +269, -657, -855, 830, 303, -58, 882, -749, +-1292, 631, 572, 30, 295, -229, -495, -13, +205, -148, 80, 718, -201, -655, 123, -344, +208, 1059, -513, -440, 300, -811, 378, 1213, +-696, -579, 143, -63, 662, 191, -736, -288, +89, 579, 404, -550, -260, 40, -83, 234, +92, 195, 132, -625, -262, 227, 380, 603, +-670, -810, 811, 255, -290, 212, -665, -131, +1094, 10, -536, -305, -210, 616, 139, -419, +589, -79, -861, 230, 243, 83, 394, -261, +-284, -141, -93, 825, -113, -1096, 639, 633, +-530, 155, -192, -541, 388, 268, 300, 191, +-780, -135, 149, -483, 765, 987, -673, -806, +-168, 125, 433, 416, 86, -468, -286, 217, +-291, 3, 670, 21, -164, -361, -417, 783, +183, -685, 239, -292, 187, 1488, -985, -1597, +792, 233, 377, 1318, -960, -1529, 280, 473, +446, 435, -93, -383, -601, 3, 371, -77, +455, 355, -484, -250, -399, -41, 849, -66, +-162, 377, -645, -193, 525, -399, 71, 504, +-100, 66, -342, -304, 347, -433, 198, 1225, +-436, -833, 15, -408, 316, 1025, 38, -515, +-538, -57, 408, -293, 198, 1051, -521, -1102, +355, 256, -111, 662, -54, -938, 317, 584, +-499, -44, 149, -263, 521, 100, -630, 363, +-90, -562, 669, 149, -276, 435, -481, -465, +437, -54, 306, 341, -540, 0, -184, -381, +907, 71, -756, 691, 62, -955, 435, 360, +-751, 414, 1196, -584, -1369, 245, 624, -117, +655, 533, -1234, -1017, 696, 864, 48, -48, +-69, -702, -378, 742, 483, -232, -143, -52, +-62, -260, -143, 667, 416, -489, -343, -193, +-82, 665, 588, -549, -856, 243, 655, -202, +-58, 227, -397, 94, 226, -592, 360, 645, +-588, -167, 161, -220, 343, 106, -337, 160, +-10, -84, 130, -172, 82, 118, -265, 129, +322, 18, -531, -627, 841, 981, -723, -563, +-69, -213, 878, 688, -953, -797, 385, 842, +67, -753, -47, 216, -76, 531, -48, -837, +212, 569, -103, -306, -181, 342, 335, -221, +-307, -351, 178, 769, 85, -390, -406, -302, +367, 307, 230, 364, -782, -641, 513, 45, +352, 582, -773, -387, 386, -150, -36, 13, +452, 711, -994, -925, 642, 140, 405, 836, +-961, -1021, 610, 463, -200, 81, 419, -146, +-778, -127, 530, 359, 169, -204, -618, -459, +653, 1203, -605, -1198, 510, 185, -152, 942, +-281, -1065, 317, 293, -37, 200, 27, 150, +-352, -564, 359, 142, 237, 714, -679, -931, +243, 307, 603, 243, -753, -106, 42, -263, +552, 89, -274, 627, -494, -1173, 803, 975, +-312, -72, -500, -966, 897, 1397, -559, -861, +-144, -162, 436, 652, 52, -190, -727, -475, +671, 350, 172, 393, -797, -694, 489, 153, +211, 365, -259, -75, -372, -533, 740, 416, +-321, 460, -331, -1037, 507, 649, -230, 173, +-8, -608, 66, 582, -63, -518, -34, 472, +329, -164, -583, -280, 391, 407, 131, -117, +-428, -115, 299, 30, -181, -3, 443, 324, +-731, -557, 477, 102, 233, 783, -737, -1155, +682, 636, -418, 71, 383, -195, -436, -96, +93, 99, 660, 350, -1231, -644, 1007, 353, +-156, 279, -562, -693, 591, 650, -172, -304, +-25, -95, -234, 299, 481, -198, -210, 22, +-424, -195, 772, 703, -483, -847, -153, 79, +599, 1080, -597, -1427, 230, 522, 292, 689, +-658, -992, 549, 247, 60, 663, -673, -959, +702, 606, -128, 4, -466, -475, 566, 586, +-278, -348, 52, 115, -91, -216, 171, 496, +-55, -399, -207, -233, 360, 884, -265, -1006, +66, 674, -8, -314, 151, 53, -264, 289, +59, -685, 431, 847, -785, -645, 581, 256, +83, 168, -606, -558, 487, 636, 132, -119, +-577, -623, 285, 695, 532, 212, -1085, -1131, +750, 948, 207, 138, -888, -838, 693, 482, +42, 233, -489, -340, 242, -125, 333, 412, +-605, -187, 351, -199, 107, 416, -378, -444, +347, 316, -188, 32, 98, -498, -57, 750, +-100, -637, 381, 369, -532, -139, 315, -106, +111, 357, -313, -358, 111, 22, 160, 255, +-120, -62, -155, -394, 326, 511, -294, -171, +269, -99, -289, -86, 146, 409, 236, -349, +-516, -103, 440, 492, -161, -564, 37, 445, +-40, -334, -78, 235, 346, -119, -468, -32, +307, 262, -85, -547, 1, 635, -1, -289, +-79, -240, 130, 425, -97, -152, 83, -16, +-257, -294, 417, 668, -284, -462, -92, -165, +335, 442, -229, -145, 58, -117, -92, -154, +294, 606, -362, -617, 196, 251, 117, -32, +-388, 97, 498, -54, -372, -288, 120, 606, +35, -595, -46, 361, 109, -124, -378, -103, +464, 308, -17, -231, -764, -217, 1012, 575, +-410, -269, -475, -501, 779, 869, -464, -422, +196, -248, -334, 319, 552, 214, -355, -615, +-77, 355, 410, 305, -468, -788, 505, 811, +-487, -514, 335, 175, -30, -54, -114, 222, +-18, -443, 166, 323, -98, 256, -161, -870, +258, 1003, -191, -653, 104, 298, -296, -258, +584, 352, -685, -253, 333, -84, 236, 424, +-552, -645, 350, 798, 104, -860, -262, 693, +99, -303, 136, -56, -147, 161, 207, -88, +-345, 126, 420, -412, -98, 753, -294, -888, +290, 807, 80, -669, -247, 567, -186, -381, +712, 2, -790, 525, 253, -1007, 198, 1276, +-224, -1282, -119, 1092, 167, -849, 251, 633, +-855, -315, 1040, -315, -657, 1199, 160, -1886, +70, 1961, -14, -1496, 196, 928, -585, -461, +996, -109, -957, 924, 620, -1636, -115, 1845, +-296, -1578, 556, 1186, -531, -812, 258, 322, +-89, 245, 151, -608, -417, 690, 403, -818, +-252, 1234, 19, -1582, -8, 1372, -128, -658, +434, 18, -820, 228, 894, -382, -515, 814, +-29, -1382, 491, 1633, -583, -1418, 600, 962, +-567, -459, 707, -94, -626, 643, 370, -1016, +57, 1194, -256, -1389, 277, 1647, -369, -1596, +612, 921, -842, 85, 685, -755, -510, 874, +490, -880, -761, 1154, 616, -1492, -38, 1467, +-743, -1119, 1101, 823, -1128, -680, 1057, 374, +-919, 210, 666, -681, -336, 690, 392, -576, +-483, 969, 286, -1870, 550, 2528, -1235, -2326, +1494, 1473, -1343, -582, 1292, -212, -1058, 1208, +252, -2358, 844, 2937, -1470, -2391, 1081, 1125, +-405, -155, -74, 48, 9, -499, 94, 837, +-405, -596, 710, -303, -834, 1544, 298, -2418, +572, 2304, -1032, -1407, 877, 697, -476, -777, +522, 1024, -632, -371, 564, -1196, -25, 2549, +-408, -2790, 859, 2164, -1220, -1410, 1406, 692, +-919, 264, -16, -1364, 519, 2041, -294, -2042, +-121, 1658, -276, -1133, 914, 308, -1035, 763, +278, -1413, 106, 1086, 228, -260, -660, 57, +109, -835, 1068, 1672, -1710, -1520, 1408, 448, +-571, 637, -48, -1190, 674, 1369, -1041, -1394, +1086, 1116, -515, -496, 143, 10, -221, -125, +504, 528, -252, -413, -414, -426, 685, 1216, +-350, -1121, -239, 357, 285, 66, -105, 392, +-146, -1109, 148, 1089, -384, -212, 656, -697, +-763, 898, 383, -530, 177, 167, -517, 16, +579, -132, -400, 83, 262, 443, 75, -1246, +-254, 1490, 286, -656, 114, -735, -356, 1630, +278, -1552, 97, 780, -201, 264, -140, -1262, +461, 1738, -371, -1183, -226, -307, 573, 1855, +-546, -2509, 106, 1986, 63, -594, -10, -1124, +-342, 2448, 679, -2606, -877, 1415, 533, 277, +574, -1269, -1836, 1211, 2251, -832, -955, 880, +-1159, -1191, 2629, 1078, -2092, -174, 219, -1191, +1665, 2244, -2220, -2223, 1578, 952, -585, 722, +64, -1442, -16, 760, -405, 107, 1476, 287, +-2703, -1592, 2559, 1934, -912, -429, -1158, -1477, +1834, 1893, -1181, -977, 460, 340, -634, -571, +1022, 582, -550, 253, -471, -892, 1073, 251, +-720, 945, 283, -1199, -27, 441, -206, 157, +837, -239, -1075, 747, 435, -1969, 647, 2605, +-1107, -1469, 763, -601, -389, 1758, 194, -1392, +92, 487, -721, 70, 701, -395, 299, 698, +-1641, -463, 1743, -713, -469, 2053, -1081, -2146, +1614, 479, -1086, 1782, 438, -2742, -332, 1439, +824, 1159, -1010, -2812, 421, 1825, 915, 1196, +-1710, -3655, 1175, 3392, 410, -753, -1386, -1883, +772, 2543, 842, -1331, -2010, -212, 1910, 807, +-1049, -197, -114, -981, 1215, 1689, -2230, -1091, +2398, -531, -1519, 1686, 21, -1052, 945, -734, +-1033, 1449, 751, 71, -672, -2375, 734, 2950, +-415, -1096, -64, -1439, 338, 2466, -13, -1511, +-310, -316, 308, 1403, 179, -791, -628, -1260, +772, 3064, -435, -2676, -342, -107, 1173, 2938, +-1439, -3219, 537, 1077, 959, 840, -2071, -541, +1879, -977, -909, 1375, -215, 34, 1032, -1490, +-1601, 1323, 1499, 87, -298, -889, -1404, 11, +2155, 1671, -959, -2320, -1052, 1042, 2115, 1243, +-1356, -2641, 37, 2055, 543, -458, 15, -365, +-667, -71, 483, 260, 643, 1077, -1823, -2887, +1876, 2572, -675, 396, -737, -3279, 745, 3148, +385, -406, -1005, -1713, -425, 1314, 2654, 138, +-3289, -139, 1318, -1129, 1362, 1435, -2365, 364, +1434, -2373, -137, 2041, -162, 536, 95, -2398, +-520, 1241, 1423, 1700, -1244, -2896, -634, 506, +3173, 2969, -3955, -3523, 1958, 272, 1416, 3075, +-3391, -2763, 2517, -729, -221, 3183, -1131, -2105, +350, -712, 1224, 2108, -2038, -1515, 1346, 643, +137, -191, -1804, -671, 2796, 1947, -2208, -1545, +-234, -1205, 2930, 3602, -3113, -2266, 223, -1935, +3132, 4453, -3277, -2452, 291, -1628, 2482, 3448, +-1868, -1944, -956, -597, 2465, 1844, -685, -1634, +-2510, 499, 3672, 1025, -1444, -1932, -2438, 779, +4448, 1589, -2923, -2294, -869, 56, 3275, 2313, +-2455, -1361, -255, -1899, 1512, 3058, -282, -370, +-1457, -2568, 1275, 2243, 676, 512, -2140, -1916, +1798, 761, -14, 1112, -1599, -1950, 2150, 1997, +-1035, -1414, -976, -256, 2315, 2219, -1418, -2446, +-729, 428, 1394, 1050, 548, 315, -2591, -2891, +1353, 2619, 2437, 936, -4688, -4019, 2492, 3126, +1693, 434, -3556, -2553, 1488, 1309, 1484, 1225, +-2068, -1962, -41, 490, 2189, 1125, -2062, -671, +132, -1093, 1353, 1682, -693, 219, -828, -2480, +1016, 2306, 787, 269, -2109, -1888, 1082, 542, +1248, 1574, -1827, -1367, 73, -894, 1550, 1928, +-1129, -540, -331, -1093, 701, 627, -312, 604, +563, -465, -1533, -787, 1173, 733, 870, 1221, +-2601, -2814, 1749, 1784, 901, 1148, -2519, -3086, +1407, 2516, 1210, -417, -2425, -624, 1103, -53, +1086, 756, -1159, 608, -896, -2909, 2248, 3231, +-522, -587, -2285, -2145, 2763, 2121, -701, -556, +-725, 297, 124, -1334, 145, 922, 1361, 1111, +-2422, -2085, 460, 548, 2230, 790, -1986, 46, +-819, -1145, 1868, 56, -63, 1511, -1316, -650, +153, -1435, 1033, 1125, 206, 1588, -1761, -2327, +808, -193, 1366, 2151, -1124, -491, -1009, -1704, +1599, 584, 236, 2398, -1189, -2349, -110, -1142, +999, 3333, 593, -1505, -2374, -1514, 1524, 1943, +474, -390, -755, -463, -282, -64, -233, 21, +1805, 917, -1485, -1285, -1069, 267, 2079, 761, +93, -730, -2223, 254, 1123, -331, 1311, 674, +-1231, -276, -872, -414, 1459, 373, 480, 590, +-1801, -1048, 735, 214, 925, 1431, -847, -2207, +-187, 1337, 566, 558, -396, -1872, 482, 1401, +-267, 287, -959, -1281, 1779, 289, -755, 1361, +-1095, -1656, 1190, 152, 236, 1063, -716, -669, +-712, -456, 1747, 558, -706, 308, -1061, -1095, +1453, 1420, -612, -1432, 42, 937, 91, 478, +-312, -1699, 487, 1429, 101, -91, -734, -213, +441, -678, 445, 1006, -538, 192, -74, -1209, +200, 472, 303, 841, -352, -778, -279, -388, +349, 857, 303, -605, -467, 642, -381, -966, +654, 200, 325, 1286, -969, -1596, -141, 152, +1417, 958, -704, -364, -1107, -633, 1434, 505, +-88, 144, -533, 177, -174, -824, 334, 334, +1004, 1006, -1752, -1190, 527, 131, 993, 413, +-739, 491, -232, -1251, -228, 401, 1507, 1094, +-1332, -1280, -371, 35, 1264, 789, -612, -249, +-27, -832, -360, 908, 508, 29, 298, -868, +-831, 602, 123, 285, 613, -743, -168, 350, +-471, 130, 31, 54, 747, -361, -395, -3, +-424, 777, 288, -760, 408, -32, -49, 425, +-933, 344, 703, -1054, 620, 531, -773, 603, +-706, -828, 1335, 49, 209, 522, -1803, -329, +1162, -134, 461, 377, -686, -737, -214, 994, +123, -526, 876, -548, -836, 889, -420, -54, +835, -878, 342, 786, -1213, -164, 500, -25, +606, 159, -657, -956, 338, 1783, -545, -1253, +597, -302, 340, 1209, -1081, -655, 262, -137, +1060, 139, -854, 211, -545, -166, 914, 74, +71, -386, -535, 553, -288, -63, 702, -467, +100, 116, -546, 489, -452, -110, 1085, -1073, +334, 1397, -2022, -379, 1231, -650, 1188, 428, +-1730, 415, -179, -535, 1415, -158, -113, 698, +-1399, -567, 718, 264, 796, -253, -491, 536, +-1004, -657, 947, 342, 817, 405, -1596, -1013, +207, 782, 1172, 262, -677, -956, -667, 366, +1000, 823, -505, -1267, 337, 685, -397, -195, +-114, 328, 841, -339, -846, -481, 400, 1400, +-422, -1404, 692, 637, -179, -37, -831, -150, +988, 427, -59, -750, -556, 435, 130, 531, +407, -917, -270, 12, 20, 1361, -288, -1720, +513, 925, -218, 15, -50, -451, -158, 814, +-36, -1382, 1154, 1556, -1909, -736, 815, -574, +1127, 1162, -1536, -644, 100, -239, 1008, 617, +-356, -472, -830, 99, 936, 319, -154, -746, +-233, 830, 5, -381, 208, -125, -157, -1, +125, 572, -23, -608, -428, -286, 942, 1295, +-941, -1287, 353, 345, 285, 499, -656, -464, +686, -148, -341, 635, -255, -603, 475, 187, +49, 311, -763, -664, 803, 753, -209, -581, +-241, 137, 322, 423, -399, -762, 531, 427, +-308, 361, -62, -715, -212, 106, 1049, 720, +-1193, -612, 63, -324, 1088, 777, -926, -168, +49, -437, -52, -1, 929, 968, -1202, -1170, +330, 514, 337, 123, 121, -369, -736, 741, +189, -1185, 972, 977, -1262, -122, 521, -138, +-43, -728, 370, 1377, -579, -415, 57, -1402, +422, 2038, -63, -1092, -473, 122, 111, -277, +848, 708, -1117, -278, 358, -657, 364, 946, +-318, -489, -26, 154, -35, -238, 285, 151, +-209, 345, -123, -559, 228, 63, -145, 577, +211, -595, -353, 185, 172, -94, 319, 462, +-707, -596, 773, 50, -643, 735, 316, -995, +255, 581, -716, -110, 554, 194, -68, -737, +106, 1005, -832, -480, 1166, -564, -368, 1335, +-874, -1422, 1260, 1087, -718, -767, 219, 441, +-313, 123, 399, -834, 49, 1276, -741, -1128, +957, 523, -653, 247, 203, -766, 133, 659, +-392, 94, 483, -796, -295, 712, -100, -6, +343, -350, -278, -19, -64, 347, 403, 119, +-499, -841, 133, 711, 435, 224, -702, -756, +303, 173, 308, 722, -476, -848, 47, 208, +313, 330, -162, -356, -243, 134, 291, 26, +12, -142, -155, 160, -187, 116, 615, -576, +-592, 696, 92, -239, 341, -348, -319, 482, +-17, -177, 154, -95, 68, 99, -486, -33, +699, 114, -666, -228, 384, 260, -62, -261, +-234, 218, 344, 61, -383, -665, 413, 1118, +-447, -820, 175, -162, 343, 921, -682, -755, +318, -40, 460, 605, -961, -641, 816, 545, +-398, -535, 11, 192, 389, 702, -879, -1452, +940, 1266, -353, -345, -344, -333, 299, 397, +185, -413, -266, 744, -281, -806, 428, 76, +201, 875, -877, -985, 597, 183, 118, 542, +-400, -524, 196, 132, -374, -18, 852, 218, +-889, -378, 248, 311, 170, -53, -22, -352, +-56, 692, -463, -540, 814, -113, -413, 543, +-130, -137, -134, -649, 661, 747, -381, 30, +-586, -699, 794, 461, -21, 258, -625, -498, +203, 109, 396, 260, -346, -216, -113, 89, +-15, -234, 459, 452, -546, -321, 103, -170, +172, 591, -213, -559, 263, 104, -385, 378, +180, -487, 106, 169, -19, 197, -310, -209, +77, -55, 549, 89, -582, 370, -415, -855, +1180, 652, -680, 268, -643, -1069, 1204, 979, +-736, -135, -57, -589, 327, 632, -309, -220, +103, -137, 154, 236, -353, -194, -99, 67, +884, 176, -1185, -385, 447, 298, 473, 54, +-694, -382, 248, 496, -54, -429, 263, 178, +-386, 334, 43, -811, 236, 663, -93, 148, +-279, -804, 292, 578, -82, 160, -108, -423, +85, -1, -199, 335, 335, -77, -403, -357, +194, 397, -56, -168, -61, 14, 161, 142, +-447, -524, 578, 783, -528, -372, 248, -461, +54, 805, -481, -304, 808, -321, -799, 270, +311, 297, 165, -556, -361, 183, 386, 348, +-610, -466, 686, 152, -288, 241, -453, -438, +707, 389, -441, -143, 104, -194, -167, 425, +64, -449, 345, 389, -722, -441, 369, 531, +182, -373, -302, -156, -132, 712, 245, -871, +103, 604, -534, -185, 490, -110, -248, 217, +-22, -116, 269, -142, -512, 341, 314, -233, +284, -86, -712, 288, 283, -296, 570, 420, +-1049, -750, 669, 808, 37, -191, -583, -709, +577, 1013, -276, -497, -65, -198, -114, 361, +579, -46, -799, -202, 121, 94, 796, 143, +-1017, -194, 230, -47, 510, 371, -466, -422, +-180, 30, 521, 519, -367, -681, 24, 247, +142, 372, -229, -590, 206, 324, -88, 22, +-91, -127, 9, 84, 188, -94, -267, 145, +-15, -87, 251, -82, -270, 177, 54, -99, +-7, -62, 22, 115, -34, 13, -109, -236, +123, 307, -27, -63, -142, -402, 150, 689, +-93, -510, 24, 41, -51, 259, 23, -203, +91, 74, -268, -90, 254, 70, -38, 234, +-173, -512, 34, 257, 304, 370, -425, -572, +19, 48, 452, 508, -537, -353, 149, -143, +124, 115, -132, 436, 78, -616, -334, 18, +589, 630, -470, -589, -100, 96, 619, 125, +-748, -8, 456, 34, -69, -331, -157, 505, +135, -349, -30, 65, 92, 148, -345, -316, +445, 366, -117, -47, -410, -516, 568, 738, +-230, -264, -149, -450, 97, 672, 149, -261, +-130, -183, -228, 134, 426, 268, -239, -421, +-128, 56, 261, 482, -159, -605, 36, 175, +-13, 306, 4, -334, 121, -59, -338, 344, +513, -183, -441, -201, 115, 347, 303, -112, +-499, -228, 429, 339, -226, -166, 120, -80, +-62, 180, -14, -86, 95, -32, -56, 37, +-32, 58, 39, -115, 85, 96, -158, -94, +153, 164, -133, -275, 228, 275, -280, -113, +201, -100, -24, 162, -41, -57, 126, 18, +-356, -270, 695, 581, -619, -470, 28, -120, +655, 571, -642, -391, 50, -71, 396, 94, +-39, 373, -623, -601, 805, 186, -223, 409, +-367, -522, 454, 153, -89, 209, -135, -285, +117, 252, 33, -267, -96, 217, 249, 56, +-404, -463, 472, 717, -276, -608, 101, 273, +30, -58, -130, 32, 474, 149, -703, -711, +522, 1172, 197, -808, -763, -224, 801, 855, +-290, -455, -120, -293, 273, 402, -178, 106, +175, -394, -137, 156, 120, 181, -50, -240, +127, 210, -163, -225, 221, 124, -168, 163, +131, -347, 87, 316, -253, -268, 246, 272, +152, -33, -394, -501, 298, 804, 98, -465, +-161, -206, 94, 599, -144, -604, 496, 492, +-431, -349, -68, 89, 507, 192, -99, -288, +-525, 244, 690, -289, -124, 374, -267, -269, +302, 45, -149, -63, 289, 456, -310, -885, +222, 1017, -129, -759, 447, 156, -584, 701, +317, -1542, 347, 1939, -609, -1711, 562, 1060, +-395, -304, 548, -330, -636, 720, 636, -870, +-321, 1034, -38, -1413, 560, 1686, -741, -1333, +597, 371, -160, 485, 125, -712, -379, 672, +643, -895, -328, 1298, -118, -1394, 458, 1106, +-382, -727, 389, 337, -432, 233, 640, -797, +-602, 973, 405, -824, 174, 900, -583, -1287, +647, 1256, -72, -331, -378, -809, 390, 1096, +213, -503, -662, 72, 823, -459, -526, 1107, +188, -1065, 268, 212, -423, 754, 368, -1196, +-43, 1027, 70, -493, -301, -102, 598, 468, +-399, -429, 122, 143, 127, 25, -85, 85, +241, -213, -403, 108, 593, 139, -410, -193, +186, -12, 200, 165, -367, 39, 404, -529, +13, 879, -348, -693, 367, 20, 172, 679, +-445, -911, 263, 596, 296, -188, -327, 145, +-26, -441, 432, 595, -196, -280, -186, -359, +430, 886, -161, -1025, -60, 830, 193, -489, +9, 170, -169, 49, 488, -208, -601, 440, +545, -794, 16, 1146, -521, -1269, 790, 1102, +-526, -790, 426, 462, -562, -48, 899, -567, +-622, 1230, -51, -1588, 736, 1511, -679, -1311, +393, 1258, -247, -1128, 591, 506, -723, 468, +615, -1145, -249, 1245, 119, -1267, 231, 1597, +-693, -1742, 1151, 969, -772, 445, -61, -1360, +852, 1128, -782, -226, 333, -539, 257, 807, +-464, -486, 601, -500, -421, 1665, 276, -1963, +-75, 911, 194, 400, -74, -545, -287, -491, +966, 1219, -1148, -680, 933, -518, -409, 1116, +259, -910, -50, 643, -312, -935, 1052, 1492, +-1325, -1608, 1092, 898, -446, 230, 398, -1010, +-746, 1041, 1083, -785, -338, 859, -967, -1283, +2125, 1434, -2056, -1045, 1364, 389, -494, 210, +140, -941, 258, 1687, -526, -1861, 783, 1060, +-579, -6, 483, -379, -427, 132, 574, -201, +-339, 828, 132, -1268, 91, 934, -60, -423, +411, 413, -734, -599, 865, 23, -273, 1249, +-174, -2066, 226, 1656, 251, -747, -133, 328, +-429, -248, 1095, -569, -821, 2040, 241, -2619, +203, 1189, 45, 896, 37, -1386, -515, -77, +1197, 1252, -843, -473, -132, -1306, 1121, 1778, +-1021, -588, 490, -736, 172, 954, -427, -570, +838, 236, -845, 167, 423, -924, 667, 1244, +-1172, -506, 962, -730, -49, 1119, -426, -504, +727, -210, -705, 269, 778, -95, -241, 66, +-385, -52, 938, -309, -648, 671, 155, -695, +634, 347, -1113, 29, 1256, -577, -34, 1348, +-1837, -1953, 3118, 1431, -1876, 282, -800, -2223, +2947, 2880, -2583, -1858, 1033, -121, 242, 1571, +-36, -1742, -374, 784, 412, 81, 686, 30, +-2028, -943, 3110, 1229, -2416, -81, 350, -1799, +2073, 2509, -2591, -1405, 1547, -471, -10, 1486, +-401, -1504, 531, 1101, -502, -553, 332, -622, +958, 1985, -2035, -2422, 2048, 1207, -596, 611, +-552, -1859, 1382, 2213, -2034, -2234, 3013, 1672, +-2622, -173, 819, -1804, 1492, 2644, -2179, -1755, +1916, 60, -1357, 844, 1210, -814, -260, 418, +-812, -87, 1432, -506, -837, 1073, 475, -965, +-311, -123, 155, 1150, 841, -1298, -1117, 669, +311, -175, 1081, -249, -788, 1007, -644, -1894, +1851, 1360, -956, 1021, -693, -3619, 1811, 3598, +-1024, -507, -358, -3258, 1334, 4326, -321, -2044, +-1664, -1447, 3243, 2997, -2054, -1700, -1081, -1001, +4297, 2492, -4602, -1812, 2306, -213, 1307, 1595, +-3473, -1472, 3672, 236, -1724, 616, -475, -283, +2092, -1041, -1991, 1797, 1115, -977, 396, -1024, +-1464, 2124, 2163, -1354, -1359, -230, -311, 353, +2210, 1054, -2317, -2060, 1088, 777, 709, 1789, +-1188, -3345, 832, 2468, 195, -237, -668, -1644, +870, 1920, -177, -845, -480, -689, 1075, 1211, +-759, -368, 544, -983, -271, 1109, 299, 13, +370, -919, -812, 114, 816, 1323, 247, -1400, +-777, -516, 478, 2228, 875, -1812, -1495, -379, +1199, 1757, 293, -1175, -1319, -252, 1536, 382, +-332, 640, -620, -1057, 755, -487, 360, 2495, +-703, -2626, 73, 116, 995, 2615, -240, -3046, +-1421, 1005, 2232, 863, -154, -928, -2607, 109, +3676, -695, -1584, 2372, -1023, -2671, 2389, -4, +-1772, 3216, 1204, -3566, -746, 651, 159, 1769, +1782, -1011, -3350, -1493, 3175, 1786, -219, 792, +-2961, -3170, 4381, 2312, -2705, 476, 59, -2061, +2078, 1285, -2241, -236, 1474, 185, 8, -323, +-907, -575, 1120, 1244, 198, -233, -1464, -1611, +1433, 1339, 1040, 1431, -3246, -3743, 2756, 2430, +1320, 1306, -4894, -3743, 4666, 2633, -92, 166, +-4153, -1861, 4745, 1306, -1288, 323, -2038, -1840, +2685, 2160, -272, -766, -1814, -2081, 1675, 3933, +1043, -2598, -3052, -1170, 2401, 3218, 1061, -1408, +-3499, -1718, 2820, 1747, 554, 1088, -2570, -2620, +1864, 397, 576, 2444, -1498, -2196, 751, -715, +905, 2485, -1541, -1759, 1257, 1, 370, 1291, +-1967, -2435, 2387, 2778, -298, -875, -1950, -2731, +2028, 4190, 580, -1633, -1966, -1849, 390, 1722, +2396, 1116, -1914, -1941, -1407, -1221, 3953, 4290, +-2168, -3160, -1697, -1157, 4017, 3811, -2483, -2633, +-528, -326, 2536, 1633, -1794, -681, -6, -785, +1190, 697, -406, 662, -528, -1393, 343, 24, +1062, 1924, -1071, -1896, -498, -467, 1920, 2141, +-766, -1121, -1143, -948, 1435, 932, 415, 749, +-1174, -1162, -49, -697, 1627, 1939, -892, -527, +-770, -1830, 1358, 1930, -131, -51, -491, -1020, +-201, -100, 1332, 1383, -679, -746, -1174, -1530, +2642, 2977, -1595, -2153, -956, -282, 2876, 1920, +-1832, -1546, -647, 230, 1865, -173, -336, 1244, +-1120, -1284, 478, -688, 1428, 2250, -1328, -1340, +-345, -662, 1203, 787, -56, 593, -398, -886, +-609, -363, 1118, 620, 851, 658, -2387, -1017, +894, -790, 2196, 1993, -2448, -670, 176, -881, +1157, -201, 0, 1872, -308, -610, -1375, -2348, +2341, 2217, -19, 1173, -2342, -2692, 1411, -329, +1508, 3470, -1813, -2208, -318, -1478, 1515, 2352, +-402, -63, 43, -1406, -1211, 201, 1503, 1178, +588, -942, -1747, 353, 148, -725, 1528, 664, +253, 883, -2878, -2246, 2060, 1272, 1633, 839, +-2702, -1325, -60, -142, 2410, 1017, -922, -87, +-1367, -1077, 1023, 620, 938, 673, -811, -1004, +-993, 14, 1697, 892, -471, -795, -220, 0, +-138, 470, 65, -113, 1059, -849, -1107, 1365, +-314, -544, 1076, -1251, 408, 2272, -1716, -1505, +664, -127, 1488, 845, -1541, -392, -207, -158, +1164, 112, -246, 20, -494, 60, 68, 17, +415, -383, 231, 365, -870, 92, 621, -38, +-4, -943, 1, 1416, 146, -179, -936, -1631, +1497, 1874, -640, -575, -627, -390, 872, 348, +-217, -551, 136, 1351, -533, -1329, 443, -62, +167, 1068, -105, -519, -356, -130, 88, -673, +776, 1561, -473, -529, -829, -1372, 936, 1284, +940, 774, -2107, -1799, 688, 348, 1418, 1392, +-1239, -1367, -372, 528, 607, -645, 698, 1148, +-906, -471, -462, -1037, 1091, 1622, 136, -1042, +-1035, 607, 177, -768, 851, 513, -243, 472, +-680, -1090, 92, 671, 1177, -147, -975, 465, +-347, -1172, 922, 1164, -515, -196, 508, -1034, +-849, 1656, 322, -1143, 770, -172, -769, 979, +-49, -273, -260, -1085, 1613, 1206, -1355, 167, +-1056, -1177, 2436, 575, -670, 514, -1518, -497, +850, -388, 1337, 803, -1363, -451, -624, 61, +1274, 70, 184, -273, -734, 517, -841, -474, +1712, 243, 164, -14, -2314, -493, 1677, 1255, +661, -1201, -1455, -374, 455, 2055, -37, -1703, +835, -423, -931, 1823, -446, -1285, 1590, 283, +-1190, -157, 157, 82, 351, 875, -495, -1634, +595, 907, -110, 316, -830, -332, 847, -334, +536, -18, -1561, 994, 854, -661, 341, -838, +-206, 1134, -534, 477, 41, -1672, 1164, 846, +-926, 445, -587, -205, 792, -729, 913, 381, +-1758, 993, 32, -1362, 1877, 234, -1134, 778, +-1006, -564, 1243, -64, 519, 84, -1251, 182, +-86, 19, 1101, -536, -191, 703, -884, -343, +225, -154, 923, 438, -391, -296, -1155, -239, +1315, 573, 167, 33, -1162, -1147, 566, 1293, +388, 14, -448, -1229, -8, 864, 280, 315, +-521, -487, 761, -388, -345, 757, -750, -95, +1253, -393, -430, 57, -651, 175, 685, 434, +-74, -1042, -40, 705, -297, 60, 172, -197, +343, -4, -483, -446, 280, 1409, -431, -1564, +617, 500, 55, 676, -1167, -896, 1085, 637, +259, -748, -939, 1068, -135, -695, 1294, -326, +-729, 1102, -848, -1037, 1326, 577, -456, -154, +-301, -214, 200, 545, -16, -365, 128, -379, +-41, 993, -364, -634, 305, -383, 298, 1039, +-501, -706, -117, -30, 543, 355, -32, -31, +-719, -346, 642, 390, 55, -71, -528, -318, +580, 616, -422, -505, -117, -66, 960, 738, +-1137, -685, 13, -133, 1319, 899, -1193, -743, +-202, 28, 1092, 459, -645, -310, -176, -47, +503, 385, -566, -497, 619, 181, -95, 692, +-955, -1270, 1316, 760, -281, 579, -842, -1284, +711, 820, 99, 50, -46, -285, -616, 185, +538, -221, 398, 259, -604, 141, -265, -231, +780, -622, 67, 1690, -989, -1188, 723, -629, +120, 1652, 16, -556, -723, -910, 584, 667, +607, 1081, -1231, -2005, 634, 1251, 233, 145, +-198, -843, -183, 1022, 121, -920, 308, 479, +-238, 347, -140, -585, 223, -65, 226, 805, +-481, -456, 327, -439, 32, 748, -201, -116, +367, -321, -463, 124, 360, 247, 70, 19, +-390, -456, 431, 429, -247, 314, 83, -917, +131, 819, -237, 123, 16, -960, 458, 960, +-522, 85, -138, -969, 938, 783, -955, 361, +175, -980, 549, 531, -616, 377, 181, -457, +171, -90, -225, 511, -59, -172, 394, -318, +-494, 568, 53, -341, 390, 46, -299, 245, +-430, -73, 695, -434, -77, 938, -1029, -577, +1359, -372, -902, 1205, -57, -1150, 760, 745, +-1291, -318, 998, 34, -97, 497, -1001, -763, +792, 567, 286, 29, -1250, -127, 627, -191, +475, 512, -1180, -125, 638, -474, -118, 822, +-315, -450, 176, -80, -298, 545, 80, -580, +-187, 523, 62, -252, -281, 7, -63, 387, +115, -554, -301, 589, -72, -267, -205, 0, +291, 218, -454, -55, -313, -119, 465, 226, +-342, 137, -502, -519, 325, 707, -95, -324, +-415, -16, -40, 104, -60, 155, 60, 43, +-634, -568, 268, 1010, -204, -624, -146, 99, +-365, 58, 114, 266, 117, 19, -1164, -825, +1142, 1446, -842, -913, -459, 13, 652, 487, +-572, -241, -347, 197, -21, -394, 375, 633, +-1019, -290, 155, -114, 349, 389, -893, -139, +156, -259, -12, 842, -513, -954, 253, 483, +-485, 577, -216, -1145, 288, 1079, -528, -660, +-233, 765, 6, -806, 131, 240, -739, 1056, +-32, -1667, 400, 1168, -789, -36, 21, -320, +-109, 34, -24, 316, -261, 65, -561, -538, +668, 749, -722, -301, -251, -165, 420, 529, +-776, -420, 384, 244, -568, 14, 155, -20, +-201, 208, -519, -459, 862, 787, -1427, -480, +515, -218, 522, 929, -1437, -719, 416, -28, +564, 732, -939, -551, -294, 25, 725, 380, +-498, -191, -440, 81, 140, -128, 165, 412, +-447, -300, -170, 53, 189, 301, -327, -355, +158, 461, -387, -378, -180, 274, 508, 47, +-505, -128, -475, 240, 595, -381, 24, 783, +-1019, -750, 589, 316, 264, 298, -848, -320, +246, 249, 70, -460, -39, 1086, -415, -1011, +113, 154, 273, 898, -661, -909, 355, 262, +-68, 374, -456, -272, 674, 43, -840, 131, +393, -100, 170, 325, -877, -462, 972, 523, +-688, -267, -96, 90, 452, 274, -367, -629, +-140, 1002, 21, -783, 466, 186, -825, 570, +192, -758, 597, 555, -902, -94, 432, -66, +-164, 139, 24, -86, 200, 275, -839, -395, +928, 453, -325, -104, -563, -323, 690, 780, +-445, -772, 179, 465, -149, 102, -276, -304, +631, 260, -556, -92, -96, 351, 251, -644, +80, 702, -385, -165, -156, -351, 708, 667, +-734, -523, 102, 260, 179, 273, -209, -661, +156, 722, -447, -176, 454, -332, -234, 587, +-275, -580, 491, 823, -624, -792, 264, 158, +251, 928, -766, -1190, 398, 458, 277, 494, +-653, -446, 22, -217, 517, 732, -532, -523, +-90, 141, 247, 267, -229, -453, 90, 480, +-286, -102, 104, -81, 9, -198, -86, 759, +-231, -580, 37, -197, 251, 817, -456, -603, +-27, 337, 124, -479, 155, 739, -661, -229, +210, -612, 438, 996, -826, -535, 260, 101, +119, -50, -303, 288, 42, -246, -181, 95, +137, 161, -142, -386, -234, 647, 254, -524, +-356, 170, 134, 141, -154, -39, -106, 8, +125, -198, -379, 428, 282, -168, -266, -98, +-183, -46, 267, 499, -194, -355, -381, -301, +372, 686, -34, -208, -614, -307, 395, 169, +67, 453, -544, -545, 171, 74, 98, 378, +-260, -216, -100, -96, 34, 154, 40, 136, +-306, -254, 38, 138, 130, 102, -427, -78, +197, -75, 3, 257, -416, -224, 306, 122, +-157, 28, -162, -37, -136, 1, 394, 101, +-525, -2, -162, -342, 750, 840, -1019, -869, +441, 174, 2, 809, -229, -979, -91, 175, +35, 652, 226, -358, -806, -575, 777, 866, +-406, -12, -318, -793, 512, 578, -444, 268, +4, -512, 141, 49, -285, 348, 74, -179, +144, 27, -597, -187, 545, 209, -81, 495, +-737, -1274, 811, 1008, -218, 466, -695, -1660, +763, 1275, -224, 302, -501, -1178, 456, 435, +-41, 895, -390, -971, 139, -313, 255, 1370, +-464, -805, 20, -687, 378, 1386, -388, -499, +-248, -906, 691, 1399, -643, -483, -64, -900, +638, 1480, -803, -575, 301, -973, 225, 1585, +-445, -424, 69, -1268, 278, 1544, -336, -10, +34, -1447, 15, 1137, 85, 466, -80, -1337, +-334, 600, 535, 761, -266, -1203, -233, 458, +169, 636, 288, -1028, -519, 460, 113, 514, +312, -921, -298, 355, -27, 648, 19, -1015, +290, 408, -518, 541, 382, -950, -129, 630, +-138, 102, 334, -734, -351, 874, -29, -268, +441, -619, -287, 852, -510, 2, 1122, -921, +-883, 585, 57, 862, 614, -1605, -900, 507, +946, 1390, -624, -1937, -177, 543, 832, 1281, +-472, -1629, -536, 352, 749, 1097, 374, -1247, +-1370, 100, 841, 1198, 470, -1484, -610, 601, +-500, 765, 959, -1587, 353, 1263, -1868, -21, +1682, -986, -54, 771, -1077, 392, 948, -1003, +-294, 217, -124, 1100, 453, -1293, -498, 117, +-206, 1053, 1403, -900, -1549, -282, 60, 1131, +1741, -723, -1874, -459, 344, 1213, 1172, -746, +-1102, -380, -234, 897, 1405, -210, -985, -723, +-848, 654, 2409, 398, -1728, -1054, -886, 554, +2786, 426, -1636, -714, -1331, 276, 2677, 139, +-702, -72, -2216, -102, 2723, 74, -272, 103, +-2281, -178, 2364, 166, -150, -60, -1834, -115, +1763, 209, 170, 0, -1943, -236, 1824, 11, +312, 622, -2449, -779, 2419, -42, 151, 1071, +-2844, -1062, 2957, 9, -106, 822, -2906, -460, +3106, -502, -229, 826, -2674, -109, 2649, -813, +244, 1017, -2722, -368, 2112, -506, 1005, 923, +-3205, -576, 2214, -261, 1019, 936, -3160, -818, +2217, -76, 861, 966, -2928, -893, 1993, -159, +1117, 1109, -3205, -822, 2151, -457, 1109, 1316, +-3099, -683, 1740, -859, 1589, 1693, -3099, -731, +1033, -1331, 2613, 2570, -3884, -1522, 1457, -1076, +2360, 2807, -3802, -1954, 1848, -542, 1464, 2164, +-2878, -1446, 1369, -652, 1625, 1985, -3043, -1234, +1411, -960, 2083, 2506, -3801, -1628, 1773, -1126, +2327, 3012, -3994, -1828, 1390, -1361, 2905, 3174, +-4090, -1645, 1082, -1527, 2999, 2972, -3745, -1314, +837, -1612, 2650, 2776, -2966, -932, 153, -2195, +2979, 3493, -3041, -1404, 111, -2329, 3181, 4184, +-3390, -2330, 480, -1478, 2918, 3594, -3203, -2095, +332, -1340, 2936, 3181, -3001, -1603, 80, -1755, +3058, 3514, -3048, -1968, 181, -1438, 3049, 3630, +-3418, -2571, 793, -952, 2730, 3813, -3562, -3113, +1032, -801, 2647, 4150, -3347, -3413, 467, -722, +3170, 4002, -3378, -3200, 254, -577, 3136, 3407, +-3174, -2701, 380, -606, 2617, 3307, -2721, -2890, +223, -379, 2726, 3601, -2952, -3681, 366, 262, +2873, 3532, -3259, -4001, 673, 600, 2445, 3374, +-2671, -4078, 242, 883, 2402, 3090, -2287, -4015, +-173, 964, 2847, 3109, -2878, -4158, 331, 965, +2788, 3375, -3170, -4506, 514, 1225, 2732, 3208, +-2860, -4421, -92, 1312, 3114, 3005, -2774, -4419, +-205, 1668, 2889, 2578, -2593, -4390, 144, 2185, +2230, 1769, -2295, -3702, 363, 1954, 1952, 1505, +-2344, -3318, 540, 1841, 2008, 1557, -2668, -3860, +797, 2793, 2078, 967, -3003, -4024, 1042, 3295, +2096, 512, -3127, -3466, 1034, 2636, 2219, 655, +-3201, -2777, 989, 1860, 2259, 581, -3211, -1976, +1082, 1266, 2009, 526, -3005, -1648, 1090, 1008, +1921, 886, -3139, -2212, 1429, 1306, 1775, 1166, +-3460, -2573, 1935, 1161, 1495, 1556, -3443, -2552, +1898, 800, 1577, 1690, -3397, -2419, 1781, 823, +1486, 1494, -3141, -2460, 1831, 1107, 885, 1424, +-2510, -2717, 1817, 1318, 455, 1484, -2465, -2929, +2471, 1520, -241, 1490, -2492, -3469, 3154, 2645, +-1000, 434, -1899, -3389, 2697, 3726, -945, -1040, +-1257, -2477, 1889, 3695, -931, -1575, -431, -1939, +1293, 3713, -1315, -2418, 474, -662, 681, 2994, +-1110, -3043, 483, 1096, 336, 1136, -345, -2082, +-179, 1427, 348, -291, 162, -219, -677, 32, +737, -70, -251, 798, -440, -1744, 1112, 1893, +-1240, -797, 671, -1104, 377, 2659, -1051, -2889, +1182, 1495, -802, 656, 247, -2224, 525, 2293, +-874, -1049, 465, -595, 453, 1483, -404, -955, +-783, -613, 1951, 1681, -1222, -1048, -867, -898, +2690, 2295, -2505, -1797, 709, -286, 1783, 2261, +-3100, -2513, 2328, 663, 663, 1816, -3298, -2862, +3414, 1591, -558, 836, -2243, -2583, 2834, 2520, +-876, -880, -1159, -1118, 1922, 1862, -736, -769, +-1017, -1074, 2349, 1771, -1693, -608, -238, -1424, +2066, 2554, -1523, -1843, -482, -127, 2133, 1478, +-1302, -928, -692, -850, 2376, 1784, -2137, -948, +835, -711, 1184, 1648, -2176, -1478, 1573, 591, +885, 451, -2386, -1070, 1490, 605, 1491, 653, +-2983, -1462, 1973, 868, 730, 472, -2224, -1374, +2200, 1500, -565, -1400, -1209, 1077, 2536, -125, +-1689, -1218, -575, 1791, 2836, -1055, -2611, -267, +764, 1057, 1327, -1082, -1817, 566, 1556, 333, +-727, -1349, 85, 1565, 865, -460, -1172, -1094, +1024, 1357, -72, 51, -681, -1595, 1386, 1502, +-1246, 140, 600, -1750, 713, 1904, -1373, -652, +1330, -885, -483, 1388, 22, -472, 336, -1044, +-405, 1669, 610, -754, -206, -914, -273, 1810, +607, -1301, -62, 26, -549, 893, 856, -1032, +-284, 759, -399, -650, 984, 704, -844, -548, +400, -104, 274, 961, -431, -1483, 279, 1289, +28, -607, 217, 53, -698, -110, 1074, 501, +-661, -512, -178, -279, 1001, 1381, -1036, -1833, +491, 1079, 237, 363, -374, -1413, 85, 1310, +154, -280, 276, -878, -982, 1336, 1225, -830, +-422, -244, -911, 1006, 1809, -906, -1390, 255, +-52, 103, 1505, 96, -1874, -391, 1063, 259, +251, 216, -1321, -665, 1791, 691, -1497, -87, +417, -956, 912, 1561, -1505, -930, 959, -608, +11, 1579, -420, -1074, 150, -280, 91, 1119, +-56, -965, -73, 333, 138, 146, -490, -384, +968, 454, -894, -437, -44, 392, 995, -390, +-1029, 228, 198, 245, 464, -708, -535, 538, +136, 232, 322, -772, -885, 419, 1163, 382, +-753, -694, -239, 270, 846, 239, -537, -349, +-202, 272, 352, -368, 121, 502, -687, -420, +738, 194, -463, -29, -20, -179, 475, 544, +-660, -769, 298, 464, 363, 40, -594, -32, +-20, -588, 835, 966, -1005, -438, 261, -550, +500, 921, -516, -288, -235, -721, 916, 1196, +-763, -705, -211, -537, 1301, 1733, -1626, -1904, +904, 766, 214, 768, -837, -1421, 560, 878, +67, -37, -298, -219, 4, -212, 364, 759, +-103, -839, -729, 203, 1440, 758, -1015, -1122, +-545, 363, 1908, 833, -1646, -1205, -121, 429, +1714, 538, -1660, -842, 253, 654, 1273, -463, +-1627, 183, 822, 344, 554, -716, -1356, 481, +1074, 39, -111, -244, -470, 218, 225, -496, +373, 961, -382, -861, -185, -108, 1006, 1224, +-1274, -1566, 905, 935, 87, 93, -954, -757, +1035, 696, -191, -226, -579, 9, 326, -372, +900, 895, -1620, -867, 1158, 77, 196, 966, +-1011, -1627, 1032, 1667, -520, -1222, 138, 482, +-7, 405, 152, -1213, -250, 1662, 25, -1533, +709, 725, -1001, 547, 389, -1650, 999, 1785, +-1656, -696, 1124, -965, 171, 2042, -1084, -1819, +1284, 489, -901, 1021, 355, -1776, 322, 1435, +-770, -443, 1078, -449, -934, 828, 603, -750, +54, 420, -620, 47, 859, -400, -584, 290, +110, 317, 293, -833, -428, 578, 428, 369, +-69, -1050, -218, 625, 325, 524, 3, -1094, +-56, 338, -389, 980, 964, -1351, -846, 179, +-35, 1470, 1006, -1844, -1224, 363, 655, 1570, +557, -1851, -1416, -60, 1327, 2244, -2, -2243, +-1341, -112, 1462, 2280, -299, -1849, -757, -598, +583, 2073, 438, -747, -861, -1835, 251, 2590, +799, -616, -936, -1832, 114, 2070, 905, -135, +-918, -1499, -231, 1002, 1406, 642, -1191, -1046, +-520, -476, 2043, 1849, -1459, -869, -752, -1782, +2277, 3054, -1174, -1299, -1322, -1463, 2390, 2057, +-736, -254, -1862, -1032, 2555, -118, -870, 1863, +-1113, -1239, 1419, -1393, -375, 2446, -86, -54, +-508, -2936, 940, 2460, -80, 1299, -1205, -3811, +1232, 1918, 9, 2065, -1035, -3177, 591, 114, +525, 3142, -742, -2380, -81, -1529, 669, 3855, +-36, -2071, -738, -1304, 98, 2493, 1537, -1247, +-2073, 181, 419, -412, 1435, 288, -1246, 1201, +-414, -2124, 799, 458, 999, 2156, -2325, -2026, +706, -1159, 2526, 3266, -3483, -1191, 580, -2690, +3119, 3650, -3695, -830, 552, -2201, 3039, 2502, +-3729, -886, 1198, -589, 2236, 1566, -3669, -2293, +2012, 1682, 1341, 1025, -3410, -3599, 2148, 2674, +1171, 1343, -3339, -3797, 2296, 1592, 688, 2532, +-2729, -3472, 2378, 418, -306, 2414, -1583, -1721, +1981, -852, -748, 1813, -1024, -822, 1666, 135, +-632, -332, -929, -220, 1055, 1664, 574, -1642, +-1803, -596, 652, 2025, 2042, -235, -2905, -2157, +484, 968, 2548, 2658, -2582, -3084, -247, -1203, +2027, 4418, -534, -1729, -1710, -3126, 1201, 3094, +1505, 1490, -2302, -3414, -153, -282, 2533, 3743, +-1401, -1350, -1751, -3710, 2682, 4210, -374, 588, +-1978, -4322, 1586, 2773, 535, 985, -1449, -2004, +448, 149, 865, 1113, -807, -202, -292, -1176, +948, 1216, -263, -90, -1099, -976, 1424, 1024, +47, 55, -1783, -1209, 1412, 943, 1192, 668, +-2838, -1493, 1230, 216, 1700, 1210, -1980, -165, +-591, -2178, 2006, 1897, -129, 1614, -2227, -3813, +1672, 1367, 540, 2617, -748, -2826, -1041, -523, +1371, 2293, 1047, -257, -2912, -1909, 1354, 801, +1516, 1565, -1790, -1422, -522, -579, 1566, 849, +296, 853, -2072, -1039, 898, -1340, 1646, 2743, +-1859, -697, -579, -2107, 2415, 2012, -1534, 120, +-639, -851, 1556, -243, -971, 423, 379, 1128, +-491, -1762, 437, -250, 543, 2465, -1500, -1674, +1052, -1196, 418, 2195, -942, 68, -350, -2511, +1531, 1816, -566, 1232, -1724, -2932, 2327, 1416, +-260, 1159, -2044, -1543, 2071, -250, -400, 1158, +-738, 252, 845, -1613, -984, 589, 957, 1197, +244, -871, -1729, -784, 1077, 582, 1269, 1349, +-1699, -1294, -953, -1637, 2701, 3141, -306, -287, +-3058, -3110, 2204, 2015, 1602, 1760, -2486, -2243, +-759, -1029, 2553, 2477, 144, 33, -2837, -1778, +1109, -413, 1946, 2569, -1086, -481, -1997, -2961, +1753, 2581, 1404, 578, -1975, -1453, -837, -413, +1568, 838, 1474, 1122, -2857, -1586, -523, -756, +3543, 1955, -1256, 303, -2598, -2492, 1933, 1229, +1508, 1230, -1624, -1228, -1399, -295, 1732, 313, +1435, 703, -2397, -284, -844, -911, 2797, 285, +69, 1412, -2909, -910, 809, -1488, 2769, 1724, +-1894, 1082, -1773, -2563, 1965, 316, 1343, 1992, +-2247, -748, -800, -1713, 2669, 1516, -603, 372, +-1415, -696, 267, -107, 1057, -436, 502, 1551, +-2189, -603, 529, -1466, 2071, 1192, -1484, 1268, +-884, -1971, 838, -192, 1090, 1564, -838, -123, +-1457, -1166, 1754, 25, 484, 945, -1374, 528, +-233, -1507, 790, -851, 1011, 3239, -1608, -1278, +-812, -2482, 2486, 2312, -462, 1145, -2013, -2017, +960, -809, 1509, 2141, -959, 365, -1637, -2344, +1617, 465, 1090, 2002, -1924, -1004, -404, -1547, +1730, 1405, 266, 878, -2185, -1401, 865, -448, +1471, 1600, -1406, -664, -225, -572, 514, 862, +301, -940, -142, 1111, -826, -578, 679, -522, +496, 926, -927, -481, 277, 366, 112, -777, +-42, 700, 386, 33, -894, -395, 170, 178, +1246, -243, -1137, 700, -874, -715, 1884, 217, +-158, 75, -1836, -194, 948, 607, 1314, -797, +-1117, 54, -1317, 868, 1674, -787, 968, -14, +-2289, 562, -249, -703, 2541, 556, -609, 234, +-2588, -1221, 1708, 935, 1814, 668, -2231, -1396, +-909, 239, 1911, 723, 884, 206, -2445, -1206, +-169, 72, 2441, 1705, -813, -1374, -1287, -292, +-20, 576, 1666, 333, 130, -227, -2352, -709, +551, 581, 2313, 318, -1039, -319, -2232, -238, +1667, 224, 1349, -287, -1090, 949, -1709, -509, +1002, -1415, 2720, 1796, -2792, 692, -1736, -2276, +3515, 58, 458, 2656, -3773, -1668, 1102, -1164, +3011, 1374, -2188, 458, -1677, -502, 2206, -1131, +862, 993, -2178, 792, 41, -811, 1339, -891, +285, 644, -1393, 1802, -936, -2264, 3153, -396, +-1032, 2225, -2903, -1084, 2651, -61, 1210, -565, +-2539, 567, -325, 1114, 1975, -1459, 298, -774, +-1969, 2059, -271, -192, 2416, -1590, -589, 150, +-1767, 1733, 538, -330, 1433, -2376, -111, 1889, +-1835, 908, 272, -1632, 2126, -227, -837, 1049, +-2062, 77, 1491, -291, 1271, -1019, -1428, 896, +-785, 1493, 961, -2538, 1001, 421, -1111, 1830, +-1130, -1038, 1904, -1083, 314, 1095, -2109, 846, +926, -1484, 1315, -104, -1306, 1213, -629, -458, +1371, -268, -48, -419, -932, 654, 41, 706, +506, -1762, 729, 641, -1507, 930, -279, -794, +2071, -174, -917, 254, -1134, 37, 619, 294, +1174, -299, -567, -353, -1543, 455, 1730, 571, +64, -969, -928, -71, 498, 1235, -464, -1055, +646, 161, 77, 325, -1021, -253, 616, -47, +323, 23, -461, 295, 34, -298, -83, -207, +244, -252, 76, 1243, -150, -383, -380, -1905, +715, 1440, 43, 1746, -859, -2171, 680, -1317, +256, 2825, -650, 112, 26, -1850, 702, -104, +-423, 1352, -894, 247, 1366, -743, -60, -498, +-1481, 178, 947, 1510, 565, -1335, -442, -415, +-793, 1257, 312, -1322, 1655, 981, -1350, 263, +-1347, -1486, 2245, 358, 377, 1352, -1993, -530, +-90, -1649, 2048, 1441, -502, 540, -1689, -1094, +750, 129, 1078, 391, -575, 202, -1106, -626, +793, 283, 617, 458, -440, -154, -894, -521, +758, -82, 1069, 1392, -1605, -824, -59, -834, +1543, 599, -497, 603, -1227, -190, 860, -750, +761, -135, -549, 595, -1192, 562, 797, -824, +1404, -591, -1534, 506, -1034, 536, 1671, 150, +635, -721, -1810, -983, 156, 1801, 985, 459, +128, -1551, -687, 126, -301, 292, 743, 989, +287, -326, -566, -1010, -273, -8, 391, 1128, +468, 395, -759, -1494, -175, -78, 944, 948, +-884, 61, 22, -619, 493, -50, -268, 32, +-81, 146, -320, 41, 685, -191, 33, 183, +-647, -342, 110, -68, 645, 891, -91, -268, +-561, -999, 259, 723, 26, 916, 358, -1089, +-212, 168, -861, 353, 812, -394, 240, 708, +-483, -520, -444, -343, 361, 850, 584, -408, +-660, -854, -7, 1329, 4, -331, 446, -922, +31, 355, -559, 452, 248, 24, 187, -647, +140, 8, -135, 446, -421, 217, 173, -561, +422, 57, -109, 569, -600, -602, 97, 453, +357, 482, -58, -1401, -50, 1054, -413, 502, +283, -1125, 418, 558, -561, -114, 302, -192, +238, 597, -597, -350, 335, -775, 311, 468, +-85, 1055, -561, -1124, 106, -869, 712, 1477, +-528, -343, -366, -124, 405, 76, 61, -748, +-415, 411, 379, 1242, -158, -600, -277, -1424, +670, 978, -376, 908, -470, -349, 990, -578, +28, -129, -1346, 193, 929, 1009, 677, -663, +-606, -669, -838, 453, 461, -352, 1149, 1327, +-1045, -1007, -483, -1050, 636, 1198, -88, 123, +117, -217, 3, -382, -468, -83, 240, 287, +220, 454, -117, -519, 488, -90, -818, 531, +-67, -380, 1095, 73, -562, 169, -103, 171, +-218, 48, -21, -791, 1029, 544, -919, 565, +-667, -821, 1164, 444, 32, -436, -911, -2, +183, 464, 527, -300, 16, 43, -432, -473, +-90, 420, 437, 40, 174, -58, -401, -208, +-167, 59, 695, 256, -411, -39, -497, -327, +972, 171, -157, 773, -1044, -893, 589, -121, +651, 783, -520, -233, -472, 103, 67, -475, +868, -82, -191, 890, -1060, -320, 712, -811, +655, 611, -801, 77, -41, -239, 397, 51, +176, -191, -486, 155, -223, -179, 958, 525, +-496, -496, -481, -397, 349, 1001, 92, -526, +344, 231, -678, -147, -251, -419, 1016, 981, +-360, -351, -619, -424, 721, 554, 64, -46, +-628, -654, 195, 582, 646, 260, -377, -257, +-394, -426, 206, -146, 162, 435, 393, 543, +-742, -646, -197, -465, 977, 365, -567, -147, +-328, 545, 451, 255, 176, -1003, -207, -224, +-827, 710, 1162, 665, 264, -388, -1265, -915, +545, 737, 248, 53, -40, -189, -45, 512, +-278, -62, 169, -828, 274, 186, -240, 797, +-302, -353, 404, -148, 134, -209, -498, -39, +140, 384, 272, -170, -243, -149, 17, 138, +-4, -129, 364, -252, -358, 427, -467, 278, +794, -703, 386, -163, -1077, 1085, -141, -418, +1063, -491, -98, 213, -700, 448, -158, 111, +677, -883, 242, 719, -770, 94, -26, -422, +429, 160, 132, -123, -288, 374, -182, -192, +495, -259, -540, 8, 133, -2, 882, 430, +-1087, -20, -129, -998, 920, 503, -228, 717, +-482, -700, 250, -17, 19, 201, 102, -158, +-41, 53, -318, 528, 402, -441, -121, -589, +-207, 903, 198, -50, 342, -45, -684, -154, +51, -482, 657, 366, -350, 808, -11, -389, +-239, -960, -42, 401, 841, 545, -534, -49, +-809, -206, 1310, -439, -332, 268, -958, 277, +1163, -287, -216, 297, -660, -218, 664, -489, +-274, 546, -44, 486, 420, -520, -575, -589, +-7, 445, 695, 610, -453, -34, -283, -844, +485, -244, -305, 1249, 114, -105, 201, -1120, +-278, 794, -130, 131, 256, -636, -75, 384, +142, 15, 144, 402, -919, -642, 667, -308, +521, 640, -622, 334, -271, -431, 360, -442, +150, 391, -217, 178, 183, -186, -209, 195, +-281, -204, 631, -329, -95, 599, -305, -370, +24, 202, -107, 129, 547, -472, -252, -118, +-414, 447, 394, 551, 94, -970, -285, -134, +61, 695, 70, -197, 161, 77, -270, 50, +-143, -584, 395, 559, -129, 4, -79, -29, +72, 113, -219, -504, 201, 205, 215, 638, +-516, -476, 275, -404, 205, 481, -299, 143, +-67, -457, 277, 82, -32, 370, -202, -457, +204, 116, -160, -74, 38, 79, 42, 288, +16, -538, 49, 171, -247, 206, 150, -357, +51, 368, -17, 117, 32, -407, -124, 105, +-97, 89, 344, 245, -144, -138, -66, -178, +37, 196, -102, 80, 197, -204, -10, -64, +-230, 244, 251, 255, -14, -503, -456, -587, +542, 1103, 97, 146, -632, -1234, 206, 338, +589, 753, -775, -381, 174, -550, 645, 284, +-769, 441, 72, -112, 526, -342, -349, -247, +-34, 824, 66, -256, -95, -379, 511, 770, +-731, -716, -46, -54, 1143, 850, -1020, -355, +-312, -442, 1021, 416, -383, -115, -351, -39, +311, 318, -124, -623, 257, 358, -144, 210, +-283, -761, 527, 522, -348, 246, 88, -543, +88, -211, -237, 736, 371, -174, -233, -754, +-48, 802, 56, 110, -126, -618, 293, 199, +142, 235, -629, 251, -63, -356, 782, -533, +-216, 947, -317, 297, -25, -1175, 283, 347, +-150, 491, -14, -220, 277, 90, -152, -471, +-207, 262, -75, 146, 436, -203, -41, 54, +-292, 65, 54, -274, 42, 83, 68, 275, +-128, -273, 90, -166, 165, 450, -295, 21, +-96, -643, 489, 306, -158, 488, -566, -328, +744, -51, 120, -47, -821, -56, 223, 516, +547, -423, -287, -82, 0, 542, -240, -676, +10, 81, 582, 727, -575, -597, -78, -294, +630, 477, -472, 178, -272, -477, 615, -192, +-142, 713, -345, -315, 346, -373, 60, 308, +-353, 350, 25, -485, 436, -322, -17, 794, +-583, 16, 138, -785, 461, 405, -33, 296, +-502, -357, -37, 74, 738, 87, -343, 53, +-657, -83, 921, -275, -126, 336, -733, 267, +712, -565, 43, -46, -408, 561, 150, -36, +-39, -796, 129, 422, 197, 633, -403, -518, +-122, -348, 386, 55, 194, 624, -477, 42, +-80, -1010, 333, 390, 59, 826, -34, -510, +-576, -752, 461, 600, 566, 666, -866, -609, +56, -426, 450, 186, -182, 783, 15, -478, +-64, -509, 50, 583, -78, 86, -62, -225, +348, -347, -191, 430, -171, 455, 0, -843, +161, 48, 138, 551, -188, -311, -145, 88, +86, -133, 257, 77, -206, 87, 25, -433, +-76, 469, 85, 217, 194, -541, -301, -305, +-96, 710, 466, 292, -153, -1094, -429, 602, +320, 227, 214, -564, -117, 561, -435, -332, +227, -108, 474, 440, -264, -174, -533, -245, +305, 44, 643, 227, -552, 268, -384, -491, +569, -175, 51, 371, -323, 98, 98, 73, +69, -510, -68, 180, -49, 80, 202, 327, +-93, -402, -248, -422, 261, 1044, 20, -531, +-34, -343, -90, 277, -55, 96, 181, 223, +39, -325, -111, -287, -193, 346, 235, 174, +274, 3, -487, -265, -97, -325, 534, 588, +-28, 512, -558, -1259, 59, 90, 872, 1211, +-677, -423, -437, -815, 712, 82, 76, 884, +-370, 67, -76, -1017, 158, 41, 50, 889, +194, -187, -405, -694, 54, 296, 460, 566, +-674, -544, 332, -314, 471, 639, -691, 100, +-196, -617, 815, 72, -98, 641, -823, -588, +544, 140, 267, 246, -232, -395, -201, 287, +-124, -191, 574, 350, -43, -287, -577, -118, +191, 227, 477, -64, -455, 128, 33, -248, +303, 35, -367, 152, 71, -152, 253, 40, +-54, 150, -463, -244, 397, 85, 332, 23, +-643, 18, 82, 21, 406, -51, -149, 45, +-213, -191, 73, 320, 344, -29, -344, -315, +-215, 188, 494, 125, 79, 14, -388, -142, +-351, -302, 722, 372, 138, 449, -753, -496, +295, -738, 313, 963, -590, 176, 495, -528, +195, 130, -704, -471, 248, 690, 260, 132, +-15, -791, -153, 421, -123, 247, 215, -461, +9, 173, -49, 214, -252, -322, 400, 170, +165, 286, -824, -606, 453, 43, 466, 685, +-577, -247, 24, -448, 242, 68, -90, 285, +42, 315, -242, -436, 246, -523, 256, 795, +-417, 147, -229, -634, 487, 95, 320, 271, +-811, -224, 96, 266, 582, -57, -256, -477, +-224, 527, -47, -7, 457, -294, -294, 64, +-79, 279, 155, -34, -55, -643, 70, 722, +-208, -111, 312, -204, -149, 130, -57, -217, +96, 431, -124, -370, 106, -105, 137, 542, +-207, -319, -54, -166, 147, 220, -35, -285, +54, 320, -41, 295, -127, -663, 40, -75, +307, 409, -244, 291, -275, -371, 450, -415, +-30, 511, -291, -73, 364, 193, -377, -174, +-44, -560, 736, 725, -631, 92, -148, -509, +541, 348, -374, -267, -81, -158, 483, 816, +-220, -395, -536, -589, 651, 586, 16, -6, +-508, -156, 418, 99, -154, -69, -7, 28, +283, -144, -508, 37, 136, 302, 468, -216, +-224, -175, -478, -2, 414, 266, 193, 155, +-404, -543, 184, 193, -112, 155, 314, 65, +-163, -237, -584, -10, 798, 338, 157, -257, +-845, -149, 253, 285, 518, 181, -378, -285, +-202, -358, 435, 468, -168, 368, -145, -661, +92, -109, 127, 658, -73, -334, -138, -305, +-83, 383, 428, 39, 15, -66, -784, -480, +436, 254, 524, 687, -484, -652, -173, -338, +211, 514, 8, 180, 132, -159, -186, -499, +-117, 404, 433, 521, -310, -718, -248, -25, +493, 532, -19, -184, -373, -145, 147, -22, +93, 255, -125, -41, 240, -208, -297, -177, +22, 719, 320, -421, -440, -631, 271, 990, +200, -260, -520, -598, 136, 404, 531, 331, +-432, -464, -249, -60, 392, 56, 69, 347, +-207, 94, -105, -905, 224, 489, -122, 742, +204, -744, -290, -234, -79, 600, 609, -61, +-587, -221, 68, 133, 287, 16, -261, -65, +85, 110, 153, -130, -228, 109, -91, -56, +482, -112, -411, 213, 10, -155, 237, -192, +-252, 124, 250, 486, -295, -829, 211, 166, +45, 420, -254, -255, 122, 45, 121, -257, +68, 303, -474, 5, 338, -102, 269, 21, +-488, 165, 156, -210, 179, 127, -252, 183, +154, -230, 61, 184, -252, -221, 288, 205, +-158, 52, -138, -181, 426, 194, -309, -313, +-199, 3, 339, 354, 198, -25, -432, -408, +-204, -288, 597, 601, 5, 229, -406, -545, +-78, -340, 328, 389, 142, 361, -213, -232, +-261, -242, 158, -100, 482, 509, -525, -81, +-85, -133, 382, -97, -163, 352, -63, -111, +32, -373, 162, 736, -187, -263, -114, -380, +210, 223, 125, 220, -131, -17, -188, -298, +-73, -131, 527, 315, -66, 191, -626, -531, +345, -207, 284, 806, -264, -329, -90, -726, +185, 806, -127, 44, 107, -591, 92, 268, +-519, 97, 503, 135, 306, -176, -863, -237, +351, 520, 288, 23, -178, -404, -16, 104, +-165, 444, 188, -205, 117, -368, -283, 392, +91, 112, 278, -153, -339, -389, -82, 262, +246, 567, 167, -767, -260, -209, -225, 541, +263, 93, 203, -445, -111, -133, -458, 386, +462, -60, 169, -254, -604, 138, 436, 263, +97, -370, -480, -160, 396, 741, 19, -304, +-271, -344, 109, 349, 105, 111, -63, -115, +58, 98, -217, -198, 76, 85, 329, 493, +-381, -719, 43, 19, 141, 763, -76, -574, +-12, -315, 4, 561, 72, -272, -135, -98, +72, 220, 87, -260, -68, 10, -187, 36, +110, -36, 414, 328, -393, -398, -364, -256, +506, 591, 182, 155, -397, -547, -35, 21, +300, 507, -275, -216, -43, -84, 553, 218, +-388, -238, -341, 256, 332, 56, 235, -407, +-116, 296, -340, 187, 129, -388, 293, 58, +-140, 121, -267, -177, 251, 142, 168, -73, +-457, -236, 273, 247, 135, -33, -422, -250, +433, 273, -58, -10, -415, -369, 394, 205, +121, 559, -421, -582, 208, -265, 151, 518, +-245, 268, 91, -115, 7, -659, 47, 259, +57, 889, -311, -490, 178, -785, 347, 901, +-473, 90, 54, -730, 199, 392, -121, 132, +101, -227, -66, -147, -41, 214, -114, -172, +251, -4, 70, 261, -322, -416, 111, 22, +70, 232, -131, -135, 254, 135, -2, 24, +-395, -431, 34, 334, 451, 414, 14, -342, +-513, -226, 75, 224, 312, 281, -8, -119, +-44, -145, -377, -93, 269, 362, 472, 164, +-751, -782, 14, 205, 843, 843, -617, -724, +-438, -430, 813, 573, -109, 6, -444, -96, +198, -258, 119, -37, -103, 273, 76, 121, +-68, -540, -75, 180, 185, 525, -182, -504, +70, -51, 182, 274, -306, 109, 92, -45, +182, -109, -283, -9, 128, 100, 304, 314, +-449, -194, -110, -396, 497, 435, -89, 71, +-236, -220, 56, 10, -51, -198, 134, 337, +214, -98, -456, -486, 80, 534, 370, -94, +-398, -505, 29, 429, 463, 36, -430, -292, +-274, 180, 596, -51, -103, -89, -175, 387, +-53, -207, -48, -240, 298, 413, 18, 52, +-283, -216, -167, 86, 459, 226, 66, -355, +-544, 276, 281, 182, 168, -529, -230, 260, +100, 257, -95, -375, 75, -204, 161, 470, +-400, -141, 211, -393, 339, 199, -529, 74, +79, -146, 245, 75, -19, -115, -34, -8, +-302, 215, 201, -277, 260, 204, -157, 222, +-249, -402, 75, 100, 313, 364, -145, -24, +-198, -222, 123, -127, 47, 442, 107, 133, +-110, -423, -345, -215, 375, 525, 390, 212, +-629, -814, -219, 141, 707, 567, -101, -494, +-468, -190, 251, 250, 225, 125, -239, -298, +-243, -312, 430, 470, 92, 369, -408, -752, +-43, -281, 301, 1020, 110, 38, -274, -963, +-97, 290, 224, 896, 80, -498, -218, -505, +14, 702, 97, 77, 48, -419, -114, 22, +-5, 428, 90, -84, -142, -637, 101, 428, +153, 350, -214, -394, -132, -456, 172, 291, +292, 581, -396, -636, -155, -490, 544, 800, +-209, 0, -250, -548, 21, -37, 449, 627, +-86, -87, -667, -762, 567, 686, 90, 468, +-357, -899, 242, 78, -48, 929, -74, -370, +-46, -687, 105, 533, 171, 659, -173, -805, +-190, -334, 117, 937, 340, -192, -291, -646, +-208, 136, 333, 500, 31, -61, -208, -738, +-123, 104, 341, 694, 32, -183, -413, -848, +127, 471, 357, 661, -237, -800, -366, -49, +439, 537, 277, -29, -616, -328, -67, 66, +633, 416, -191, -236, -385, -33, 172, 90, +315, 261, -239, -333, -235, -264, 356, 984, +-45, -449, -165, -921, 54, 931, 69, 516, +-105, -1246, 85, 111, -37, 907, -11, -673, +126, -256, -202, 490, -59, 18, 269, -566, +41, 37, -225, 940, -150, -453, 194, -1053, +278, 898, -208, 1016, -372, -1300, 370, -435, +220, 1379, -437, -156, 47, -912, 220, 295, +41, 1093, -254, -927, -28, -718, 237, 1273, +29, 215, -255, -1260, 92, 54, 237, 1369, +-387, -787, 12, -1197, 500, 1346, -81, 894, +-779, -2069, 316, -293, 967, 2392, -781, -707, +-754, -1836, 1120, 1125, 290, 1259, -1245, -1382, +278, -696, 1020, 1761, -538, 15, -855, -1787, +638, 541, 996, 1951, -1187, -1224, -761, -1755, +1824, 2223, -87, 650, -1820, -2424, 900, 651, +1187, 1722, -1092, -1216, -626, -1167, 922, 1520, +422, 566, -901, -1699, -283, -137, 1097, 1895, +-94, -663, -1205, -1820, 653, 1611, 955, 1058, +-1061, -2170, -484, 75, 1163, 2103, 16, -1174, +-969, -1237, 195, 1629, 779, 332, -270, -1487, +-603, 441, 189, 1075, 655, -834, -328, -698, +-603, 1304, 573, 111, 244, -1598, -442, 830, +-259, 1086, 605, -1365, 56, -276, -630, 1417, +158, -752, 484, -925, -169, 1477, -545, -66, +463, -1490, 353, 761, -696, 1252, -75, -1512, +842, -412, -200, 1801, -930, -627, 595, -1524, +741, 1513, -891, 1030, -394, -2365, 1162, 236, +-190, 2512, -1244, -1794, 917, -1487, 957, 2806, +-1475, -243, -378, -2703, 1679, 1732, -279, 1890, +-1591, -2769, 995, -709, 1125, 3314, -1554, -1124, +-306, -2596, 1693, 2378, -598, 1077, -1361, -2652, +1312, 310, 674, 2357, -1609, -1547, 66, -1527, +1535, 2453, -640, 198, -1355, -2651, 1283, 1491, +841, 1562, -1757, -2217, 66, 46, 1521, 1544, +-550, -522, -1104, -1128, 632, 943, 842, 608, +-638, -1159, -684, 52, 621, 779, 629, -115, +-673, -730, -634, 241, 811, 619, 614, -516, +-964, -230, -664, 298, 1537, 304, 35, -239, +-1808, -879, 1091, 1029, 1260, 916, -1923, -2045, +-255, -109, 2251, 2741, -1121, -1549, -1632, -2146, +2292, 3216, -51, 219, -2250, -3708, 1707, 2147, +1079, 2949, -2519, -4362, 578, -562, 2252, 5201, +-2055, -2789, -1094, -3673, 2919, 5136, -636, 664, +-2742, -5698, 2313, 2626, 1457, 4210, -3265, -5050, +570, -1139, 3021, 5415, -2609, -2149, -1552, -3780, +3889, 4319, -726, 925, -3738, -4656, 2938, 2034, +2062, 3020, -4047, -3731, 438, -104, 3489, 3150, +-2532, -1977, -1670, -1385, 3425, 2851, -613, -689, +-2773, -2406, 2264, 2473, 1162, 598, -2869, -2792, +871, 1407, 2028, 1574, -2233, -2594, -176, 598, +1996, 1967, -1143, -2135, -1001, -358, 1664, 2360, +-82, -1381, -1668, -1339, 1285, 2328, 791, -403, +-1744, -1975, 248, 1784, 1556, 530, -1079, -1888, +-832, 1169, 1321, 226, 111, -1147, -1224, 1237, +634, 53, 688, -1537, -1114, 1112, 179, 847, +808, -1774, -319, 848, -832, 744, 534, -1593, +882, 733, -1036, 1125, -425, -1720, 1314, 79, +-195, 1761, -1536, -1703, 1233, -326, 1162, 2273, +-2141, -1773, -221, -1168, 2456, 2913, -919, -780, +-2106, -2642, 2131, 2677, 714, 743, -2408, -3155, +989, 1791, 1406, 1500, -1778, -2941, -18, 1143, +1536, 1884, -1041, -2688, -550, 309, 1365, 2653, +-788, -2676, -605, -551, 1668, 3485, -1090, -2423, +-969, -1743, 2106, 3877, -650, -1233, -1699, -2889, +1958, 3393, 259, 126, -2238, -3437, 1320, 2453, +1573, 1651, -2543, -3763, 82, 1204, 2453, 2683, +-1723, -3176, -950, -32, 2036, 3076, -619, -2447, +-1176, -990, 1409, 3091, -161, -1367, -1211, -1845, +1377, 2720, 112, -283, -1748, -2439, 1124, 2093, +1288, 829, -1962, -2301, -267, 504, 2133, 1625, +-1047, -1218, -1289, -619, 1798, 1129, -10, -113, +-1690, -685, 1044, 136, 1049, 676, -1553, -447, +-152, -455, 1276, 560, -342, 166, -715, -561, +331, 244, 365, 276, -180, -583, -298, 451, +192, 341, 311, -901, -483, 309, -3, 967, +575, -1233, -432, 76, -238, 1416, 401, -1599, +138, -31, -342, 2099, -319, -2119, 689, -524, +251, 3024, -1322, -2241, 633, -1320, 1203, 3514, +-1546, -1653, -367, -2389, 2068, 3897, -1161, -981, +-1418, -3277, 2472, 4012, -523, -258, -2179, -3937, +2229, 3803, 551, 745, -2728, -4418, 1544, 2915, +1556, 1692, -2837, -3761, 823, 1731, 2182, 1431, +-2797, -2637, 215, 1407, 2733, 956, -2502, -1990, +-840, 777, 3206, 732, -1479, -688, -2251, 16, +3285, -208, -354, 658, -2904, -363, 2744, -549, +244, 1093, -2606, -892, 2321, 86, -156, 831, +-2155, -1583, 2972, 1429, -1250, 219, -2014, -2515, +3742, 3049, -1724, -667, -2333, -2450, 3777, 3121, +-482, -963, -3460, -993, 2591, 724, 2099, 526, +-4248, -410, 937, -999, 3644, 2024, -3874, -1255, +-291, -748, 3508, 1932, -2032, -1059, -1650, -617, +2815, 1234, -658, -574, -1944, -622, 2473, 1445, +-966, -1323, -902, 131, 1861, 1271, -1687, -1888, +318, 684, 1742, 1566, -2546, -2192, 902, -129, +1555, 2638, -2401, -2237, 1113, -229, 978, 1830, +-1871, -1223, 498, -392, 1649, 1124, -1673, 34, +-803, -1695, 2577, 1980, -1039, -628, -1949, -943, +2596, 1772, -335, -1268, -2195, -577, 2934, 2252, +-1499, -1475, -1387, -1948, 3468, 4631, -2261, -2999, +-1460, -2040, 3571, 4741, -1532, -1899, -2297, -2927, +3661, 3971, -1370, -727, -2060, -3059, 3483, 3868, +-1693, -1186, -1690, -2409, 3358, 3259, -1595, -546, +-1741, -2605, 3364, 2949, -1788, -67, -1552, -3163, +3386, 3563, -1632, -734, -1949, -2079, 3437, 2406, +-1267, -668, -2177, -1087, 3395, 1428, -1489, -232, +-1235, -849, 2256, 369, -1423, 460, 114, 15, +600, -1104, -498, 864, 177, 509, -374, -1498, +669, 835, 47, 827, -1463, -1698, 1846, 567, +-371, 1148, -1685, -1365, 2326, 209, -1014, 624, +-913, -447, 1777, 80, -1126, 107, -244, -180, +1197, 338, -1052, -204, 45, -298, 832, 871, +-732, -581, -55, -397, 403, 846, 179, -326, +-818, 6, 461, -454, 689, 756, -1369, -418, +769, -339, 483, 907, -966, -841, 276, -180, +525, 913, -434, -271, -290, -1187, 765, 1580, +-581, -323, 37, -1495, 329, 2013, -338, -424, +178, -1675, -13, 1873, -11, 164, -184, -1961, +189, 1676, 406, 271, -924, -1790, 459, 1584, +581, 138, -1007, -1479, 423, 1012, 561, 690, +-1064, -1488, 742, 307, 38, 1450, -692, -1786, +866, 335, -435, 1282, -277, -1603, 461, 281, +120, 1161, -507, -1082, -148, -529, 1177, 1495, +-1103, -658, -330, -819, 1521, 1218, -943, -370, +-790, -755, 1623, 1232, -626, -510, -1055, -829, +1685, 1613, -720, -861, -900, -653, 1589, 1357, +-574, -310, -1096, -1090, 1464, 1078, -87, 190, +-1301, -932, 1153, 533, -68, 172, -490, -454, +163, 171, 276, 267, -172, -496, -242, 235, +285, 226, 90, -667, -249, 500, -92, 324, +434, -920, -331, 252, -71, 875, 330, -914, +-239, -102, -10, 783, 113, -424, -11, -225, +-144, 481, 160, -177, 21, -206, -90, 490, +-262, -683, 687, 936, -502, -744, -132, -122, +424, 1040, -158, -1145, -116, 626, -75, -307, +676, 322, -1072, -148, 400, -448, 1110, 732, +-1791, -437, 642, 153, 1096, -453, -1593, 437, +678, 366, 458, -970, -758, 393, 132, 373, +617, -230, -606, -99, -188, -500, 1038, 1511, +-1281, -1331, 704, -434, 347, 2536, -943, -2932, +417, 1147, 480, 1381, -319, -2569, -912, 1857, +1609, -27, -677, -1567, -960, 1944, 1486, -970, +-423, -548, -761, 1540, 477, -1535, 869, 554, +-1316, 779, 22, -1517, 1366, 846, -968, 517, +-647, -1239, 1415, 883, -681, -171, -555, -640, +1300, 1225, -1121, -672, 69, -851, 932, 1380, +-866, -22, -59, -1178, 699, 474, -458, 1124, +-143, -1256, 161, -413, 429, 2012, -470, -1346, +-584, -1076, 1445, 2379, -854, -730, -546, -1799, +1266, 1873, -838, 593, -57, -2375, 493, 1267, +-194, 1086, -194, -1775, 15, 272, 363, 940, +-99, -107, -690, -1414, 782, 956, 356, 1214, +-1446, -2178, 945, 471, 690, 1790, -1528, -1812, +530, -272, 1209, 1628, -1574, -257, 46, -1963, +1264, 1531, -548, 1635, -791, -3150, 430, 604, +1008, 2565, -1161, -1828, -336, -1501, 1562, 2574, +-1055, 8, -562, -2658, 1370, 2038, -442, 923, +-817, -2508, 515, 710, 945, 1939, -1407, -1825, +73, -593, 1472, 1629, -1557, -471, 197, -375, +1237, -142, -1361, 391, 18, 284, 1317, -794, +-1192, 479, -50, 163, 929, -314, -751, -62, +27, 30, 247, 791, 441, -714, -1147, -992, +287, 1801, 1808, 437, -2621, -2931, 673, 1646, +2325, 2427, -3238, -3954, 968, 498, 2168, 3808, +-2842, -3364, 549, -1286, 1921, 4007, -2093, -1782, +518, -1648, 827, 1906, -1262, -161, 1182, -198, +-374, -735, -1249, 187, 2063, 1556, -431, -1136, +-2293, -1843, 2846, 2949, -355, 393, -2377, -4112, +2306, 2896, 132, 2024, -1707, -4160, 590, 906, +1340, 2928, -1275, -2088, -662, -1562, 1901, 2408, +-946, 613, -954, -2963, 1632, 1445, -573, 1844, +-804, -2801, 959, 630, 79, 1705, -845, -1674, +220, -145, 969, 1585, -913, -1382, -588, -351, +1611, 1834, -619, -977, -1376, -1519, 1805, 2014, +132, 630, -1964, -2779, 1126, 1271, 1134, 1741, +-1457, -1976, -531, -753, 1614, 2366, 31, -408, +-1881, -2088, 727, 1307, 2005, 1400, -1980, -1693, +-1111, -561, 2668, 1562, -473, 4, -1949, -1089, +1122, -124, 1205, 1165, -1268, 334, -849, -2059, +1487, 522, 702, 2566, -2373, -2424, 740, -1064, +1912, 2752, -1839, -344, -515, -2438, 1747, 1674, +-536, 1315, -1193, -2622, 1391, 1013, -256, 1105, +-654, -1375, 619, 183, -273, 512, 389, 19, +-734, -674, 466, 280, 619, 813, -1386, -1028, +706, -75, 658, 799, -806, 244, -335, -1178, +611, -469, 720, 2992, -1305, -2019, -347, -2208, +1823, 3886, -707, -407, -1108, -2932, 751, 1232, +557, 1920, -72, -1007, -1166, -1803, 258, 847, +1830, 2527, -1382, -2361, -1481, -1517, 2343, 3056, +297, -185, -2189, -2004, 162, 12, 2514, 2302, +-1358, -614, -2017, -2272, 2512, 1567, 285, 1127, +-1711, -1062, 7, -1085, 1068, 1248, 578, 562, +-1523, -993, -488, -197, 1940, 449, -2, 557, +-1999, -587, 398, -657, 2009, 854, -753, 605, +-2327, -1311, 2016, 28, 1400, 1103, -2744, -605, +461, -139, 1576, -8, -790, 27, -840, 481, +748, -449, 526, -175, -809, 83, -209, 652, +725, -352, 58, -1129, -589, 1518, -87, 302, +663, -1871, -13, 826, -892, 1294, 646, -1465, +486, -14, -994, 826, 243, -589, 643, 436, +-464, -238, -318, -542, 539, 941, -120, -121, +-211, -760, 134, 421, 14, 189, 94, 129, +-280, -548, 39, -59, 509, 772, -512, -595, +-188, 86, 583, 133, -144, -354, -398, 463, +420, 90, -214, -763, -47, 443, 444, 657, +-377, -809, -466, -430, 680, 934, 673, 755, +-1538, -1883, -132, -278, 2165, 2656, -1109, -674, +-1684, -2983, 1784, 1966, 963, 2510, -1999, -3204, +-261, -835, 1949, 2842, -438, -264, -1554, -1962, +1160, 758, 312, 814, -740, -540, 561, 111, +-423, -424, -334, 20, 1068, 846, -40, -280, +-1580, -1050, 728, 573, 1760, 1247, -1659, -1334, +-1267, -404, 2221, 984, 481, 173, -2306, -289, +260, -1088, 2014, 1030, -748, 1026, -1480, -1547, +641, -477, 1539, 1228, -936, 784, -1459, -1604, +1504, -590, 769, 1625, -1604, 610, -107, -1798, +1617, -627, -867, 2268, -1000, -59, 1446, -2051, +162, 554, -1466, 1482, 295, -739, 1622, -696, +-1098, 174, -1067, 668, 1297, 248, 476, -1159, +-856, -96, -540, 1667, 471, -547, 1219, -1734, +-827, 1326, -1646, 1234, 1586, -1626, 1370, -702, +-1930, 1692, -967, 216, 1903, -1545, 680, 18, +-1531, 1643, -1053, -630, 1790, -1313, 1277, 1141, +-2714, 481, -284, -960, 2751, 66, -779, 342, +-2029, 90, 1332, -192, 1032, -240, -1189, 292, +-464, 79, 1068, -155, -36, -50, -1002, 81, +727, -53, 577, 333, -1205, -501, 114, -58, +1040, 898, -281, -783, -989, -232, 303, 717, +1232, -59, -841, -545, -934, 169, 1180, 446, +404, -220, -1134, -457, -44, 279, 975, 616, +-227, -614, -679, -562, 383, 995, 216, 38, +-264, -659, 179, -240, -56, 888, -372, 91, +467, -1316, 226, 1124, -672, 77, 97, -939, +510, 793, -393, -6, 185, -212, -24, -321, +-483, 206, 446, 656, 492, -259, -473, -1064, +-826, 586, 738, 1183, 1041, -805, -1279, -1178, +-728, 942, 1699, 1154, -200, -1231, -1129, -560, +450, 726, 409, 203, 197, 524, -655, -1183, +-331, -657, 809, 1728, 350, 512, -864, -1822, +-298, -509, 717, 1873, 446, 287, -624, -1572, +-864, -99, 1202, 956, 391, 121, -899, -81, +-518, -843, 760, 47, 934, 1188, -1324, -493, +-342, -635, 915, 550, 362, -179, -666, -79, +-654, 529, 960, -304, 414, -544, -788, 521, +-708, 198, 1217, -424, 557, 395, -1731, -412, +326, -30, 1400, 270, -1001, 375, -600, -473, +1056, -667, 109, 837, -927, 523, -174, -727, +1418, -372, -323, 161, -1416, 351, 679, 964, +1004, -1148, -367, -1424, -1097, 1900, 196, 1011, +1415, -1466, -446, -962, -1516, 516, 1060, 1636, +766, -190, -851, -1893, -332, -117, 424, 1901, +294, 576, -292, -2307, -50, -61, -136, 1770, +263, -343, 79, -725, -201, 155, -44, 108, +30, -66, 203, 371, -242, -278, 114, -67, +105, 37, -348, -271, 318, 587, 19, 97, +-320, -770, 354, 106, -91, 630, -296, -218, +373, -290, 12, 294, -384, -302, 122, 67, +608, 442, -533, -257, -692, -367, 1020, 176, +518, 388, -1216, -288, -319, -22, 1070, 148, +286, -483, -740, 377, -466, 585, 405, -753, +840, -565, -363, 1096, -1038, 186, 493, -996, +869, 216, -475, 167, -495, 445, 175, -113, +344, -904, -39, 391, -239, 729, 105, -228, +111, -482, -248, 43, -143, -215, 637, 699, +-21, 565, -739, -1318, 150, -508, 326, 1119, +331, 907, -197, -1119, -719, -666, 128, 385, +1010, 568, -283, 595, -1053, -1051, 930, -479, +-97, 464, -301, 724, 352, 246, -177, -1418, +132, -63, -425, 1302, 162, -196, 646, -426, +-307, -210, -881, -320, 564, 1207, 841, -149, +-734, -1142, -457, 476, 449, 586, 219, -342, +-85, -197, 33, 221, -520, -315, 109, 314, +912, 273, -524, -492, -720, -411, 660, 935, +291, 148, -447, -1292, 194, 770, -313, 394, +39, -593, 698, 84, -530, 235, -302, -259, +203, 51, 222, 418, 365, -565, -646, -146, +-453, 846, 778, -171, 502, -1075, -710, 940, +-692, 352, 643, -1040, 1039, 668, -1046, 294, +-727, -1017, 1198, 356, -91, 928, -597, -764, +487, -346, 57, 714, -705, -523, 287, 23, +750, 603, -346, -311, -598, 35, -10, -861, +615, 325, 274, 1609, -630, -953, -275, -1143, +550, 597, 16, 498, -318, 341, 180, -497, +206, -368, -366, 280, -202, -250, 453, 520, +197, 260, -279, -563, -357, -174, 214, -86, +300, 360, -142, 546, -78, -360, -7, -502, +68, -258, -148, 591, 56, 647, 211, -622, +-73, -411, -206, 192, -64, 131, 410, 200, +-111, 147, -419, -502, 376, -155, 108, 334, +-106, 476, -322, -459, 46, -607, 674, 759, +-369, 268, -574, -661, 511, 120, 350, 259, +-592, -469, -65, 506, 676, 181, -254, -742, +-688, 173, 604, 597, 345, -372, -683, -612, +264, 1072, 116, -154, -280, -945, 479, 670, +-493, 219, -239, -440, 1009, 259, -452, -167, +-570, 71, 483, 263, 35, -710, -73, 373, +170, 702, -333, -691, -61, -656, 466, 1066, +-65, 259, -315, -1101, -219, -61, 534, 1112, +173, 86, -463, -1379, -80, 439, -91, 847, +479, -541, 293, -274, -694, 395, -334, 169, +635, -425, 260, -549, -290, 1076, -284, 516, +-3, -1608, 357, 21, -30, 1142, 18, 157, +-254, -817, -245, -507, 665, 837, 59, 364, +-725, -581, 217, -10, 422, 21, -338, -397, +157, 1031, -86, -39, -317, -1311, 477, 471, +172, 865, -578, -414, 93, -260, 356, 223, +-323, -611, -16, 450, 423, 727, -170, -616, +-538, -301, 547, -138, -75, 258, -257, 785, +559, -232, -475, -1324, -186, 651, 478, 1012, +86, -629, -609, -765, 264, 817, 383, 285, +-561, -1124, 391, 776, 26, 523, -428, -994, +157, 19, 289, 564, -152, -133, -67, -128, +168, 103, -374, 7, 20, -241, 686, -24, +-231, 343, -901, 45, 587, -82, 656, -296, +-682, -258, -143, 544, 389, 738, -119, -1160, +-171, -654, 193, 1586, 124, -19, -347, -1132, +224, 340, 200, 471, -513, -343, 79, -139, +395, 597, 36, -359, -351, -385, -39, 382, +101, -8, 93, 192, 109, -94, -128, -416, +-255, 154, 181, 370, 368, 50, -491, -607, +72, 310, 225, 172, -198, -357, 99, 357, +-3, 93, -62, -627, -24, 398, 160, 339, +-127, -716, -86, 182, 291, 669, -106, -447, +-294, -416, 237, 305, 73, 240, -26, -192, +26, -11, -215, 102, 121, -26, 61, -177, +-121, -12, 143, 289, -46, -178, 49, 89, +-143, 98, -110, -286, 356, 0, -239, -99, +37, 590, 193, -21, -326, -783, 114, 167, +168, 670, -172, -279, -57, -422, 194, 401, +-41, -57, -179, -277, 280, 616, -118, -374, +-339, -420, 430, 670, 95, -197, -396, -242, +70, 186, 369, 401, -374, -480, -134, -526, +601, 905, -399, 52, -265, -490, 444, 52, +58, -24, -336, 210, 169, 103, 44, -488, +-317, 332, 290, 39, 179, -110, -179, 219, +-153, -589, 91, 433, -114, 350, 90, -637, +445, 112, -432, 264, -373, 116, 531, -380, +56, -297, -394, 722, 268, 215, 162, -816, +-464, -14, 29, 501, 469, -3, -148, -142, +-147, 7, -110, -130, 0, -81, 434, 364, +-202, -138, -530, -19, 647, 52, 250, -232, +-1005, -2, 403, 320, 666, 77, -735, -395, +27, -91, 605, 555, -590, -210, -193, -481, +604, 344, 46, 473, -366, -355, -222, -518, +404, 413, 10, 314, -285, -91, 352, -513, +-41, 8, -382, 929, 79, -405, 309, -879, +104, 698, -464, 269, 57, -339, 514, 316, +-489, -452, -247, -222, 668, 734, -58, -171, +-591, -253, 295, 178, 345, -252, -343, 155, +-165, 264, 261, -487, 209, 269, -385, 317, +-88, -670, 459, 207, -114, 468, -399, -489, +238, 15, 372, 345, -513, -340, -47, 81, +543, 178, -285, -163, -280, -159, 397, 238, +-104, 257, -362, -501, 590, 117, -172, -8, +-259, 230, 218, 147, -304, -834, 446, 579, +-12, 613, -459, -1104, 128, 11, 444, 1097, +-222, -518, -549, -684, 560, 683, 347, 83, +-615, -263, -383, -71, 958, 86, 18, 236, +-972, -317, 453, -100, 564, 520, -580, -142, +-375, -586, 816, 264, 98, 601, -830, -245, +95, -559, 633, 44, -124, 706, -400, -190, +67, -453, 130, 101, 208, 358, -103, 66, +-427, -734, 249, 246, 360, 915, -288, -637, +-135, -734, 127, 641, 14, 646, 45, -700, +-27, -235, -89, 359, -6, 88, 171, -71, +22, -111, -358, -143, 270, 387, 261, 85, +-667, -691, 360, 302, 467, 590, -803, -628, +269, -51, 284, 500, -310, -458, 253, 8, +-348, 504, 96, -334, 467, -302, -473, 340, +-236, -6, 675, 128, -217, -127, -488, -400, +560, 342, -114, 295, -187, -146, 213, -509, +-123, 347, -109, 403, 290, -599, -48, 39, +-474, 376, 547, -71, 164, -245, -717, 40, +182, 247, 492, -360, -262, 192, -137, 334, +187, -407, -319, -175, 216, 261, 323, 158, +-485, -107, 155, -180, 186, 11, -426, 275, +306, -80, 230, -339, -445, 72, 89, 578, +220, -198, -148, -662, -115, 178, 181, 745, +184, -118, -375, -847, -164, 189, 483, 687, +153, -29, -528, -624, -56, -100, 483, 482, +-135, 350, -274, -507, 116, -432, 122, 588, +129, 320, -137, -510, -497, -304, 445, 393, +474, 455, -633, -418, -51, -531, 333, 557, +-157, 200, 13, -249, 129, -186, -260, 144, +106, 226, 315, -191, -399, -414, -97, 503, +416, 514, -158, -992, -34, 40, 36, 640, +-309, -256, 301, -177, 349, 280, -400, 57, +-413, -693, 506, 376, 303, 790, -586, -828, +99, -341, 355, 812, -407, -90, 69, -615, +399, 435, -402, 245, -163, -553, 461, 246, +-8, 109, -295, -170, -4, 295, 72, -581, +186, 211, -64, 699, -179, -623, 17, -321, +167, 540, 8, -119, -321, -176, 313, 459, +193, -211, -620, -686, 254, 690, 486, 423, +-562, -857, -33, 21, 372, 832, -150, -465, +-121, -672, 53, 699, 203, 483, -165, -658, +-294, -403, 508, 554, 11, 279, -601, -338, +417, -274, 271, 241, -481, 285, -27, -370, +386, 29, -114, 237, -230, -253, 250, -16, +-60, 286, -172, -115, 160, -143, 110, -146, +-157, 376, -55, 276, 90, -828, -21, -32, +274, 1041, -386, -281, -334, -1083, 1023, 722, +-356, 595, -854, -663, 826, -109, 185, 112, +-557, 316, -19, -70, 391, -398, -54, 237, +-278, 140, 152, -139, 81, -41, -62, 136, +-127, -22, 122, -200, 17, 66, -45, 241, +96, 6, -77, -308, -142, 66, 15, -114, +401, 354, -177, 316, -455, -804, 396, -230, +248, 934, -350, 123, -230, -925, 348, 176, +275, 483, -427, -137, -151, -185, 327, 32, +66, 118, -113, -174, -107, 117, -96, 126, +312, -175, 14, -24, -329, 15, 184, 37, +51, 168, -110, -143, 10, -262, 150, 420, +-115, -83, -166, -365, 276, 427, -18, 63, +-184, -414, 23, 21, 97, 484, 47, -232, +-177, -491, 183, 689, -1, 45, -318, -781, +273, 471, 77, 327, -96, -499, -177, 233, +188, 69, 130, -450, -484, 409, 450, 310, +127, -691, -594, 37, 304, 757, 261, -437, +-359, -631, 82, 737, 99, 353, -125, -721, +77, -131, 57, 533, -160, 4, -34, -321, +307, 43, -156, 239, -194, -37, 212, -402, +-52, 257, -83, 356, 219, -294, -51, -300, +-339, 102, 318, 507, 167, -131, -454, -604, +141, 259, 333, 492, -266, -342, -136, -243, +136, 301, 126, 67, -37, -239, -292, -68, +271, 367, 171, -11, -456, -434, 177, 141, +261, 183, -229, 130, -91, -231, 154, -280, +-6, 450, -54, -4, 48, -303, -6, 62, +17, 353, -201, -242, 182, -467, 334, 685, +-581, 147, -54, -785, 630, 195, -220, 561, +-265, -317, 77, -231, -21, 124, 212, 129, +34, 118, -235, -257, -61, -190, 125, 374, +124, 250, 8, -532, -270, -263, 40, 678, +252, 261, -81, -761, -159, -189, 7, 662, +362, 94, -374, -359, -252, -164, 794, 223, +-311, 54, -567, -122, 601, 241, -4, -204, +-284, -257, 243, 433, -255, -62, 105, -169, +320, 127, -381, -170, -89, 48, 349, 194, +5, 8, -349, -250, 78, -167, 293, 452, +-75, 86, -116, -472, -240, 113, 248, 267, +345, -160, -557, -191, 76, 248, 475, 230, +-464, -507, -167, 13, 531, 394, 26, -39, +-592, -255, 33, -122, 741, 427, -188, 12, +-736, -533, 316, 158, 491, 455, -148, -101, +-384, -493, -47, 106, 486, 452, -17, -191, +-438, -224, 55, 120, 389, 147, -87, -77, +-369, -310, 167, 332, 265, 232, -10, -430, +-480, -95, 109, 381, 631, -81, -506, -100, +-293, 48, 538, -80, 13, 105, -343, -19, +14, -44, 141, 136, 141, -258, -163, 109, +-179, 263, 341, -375, -92, 119, -180, 220, +93, -432, -50, 151, 331, 501, -161, -449, +-577, -364, 572, 605, 273, -80, -491, -237, +-5, 177, 90, -26, 124, -143, 15, 45, +-184, 247, -17, -196, 265, -75, -165, 221, +-278, -275, 458, 115, -17, 237, -411, -238, +161, -65, 302, 179, -238, -148, -198, 50, +261, 247, 21, -345, -17, -13, -222, 308, +46, -203, 421, -17, -386, 161, -197, -140, +443, -120, -65, 222, -234, 69, 143, -94, +7, -284, -66, 113, 42, 543, 51, -359, +-76, -485, 26, 518, 96, 140, -278, -295, +287, -7, 102, 116, -468, -52, 331, -21, +112, 89, -364, -65, 241, 104, 178, -226, +-365, -17, 36, 497, 246, -434, -80, -185, +-62, 500, -7, -88, 12, -433, 4, 195, +66, 437, -48, -286, -62, -350, 84, 253, +-77, 120, 52, 47, 67, 36, -163, -482, +69, 121, 49, 581, -177, -346, 156, -225, +160, 169, -285, 90, -140, -177, 224, 101, +210, 231, -186, -403, -293, 82, 133, 99, +336, 15, -152, 230, -399, -516, 379, -3, +227, 647, -646, -295, 143, -516, 722, 506, +-520, 212, -558, -471, 726, 50, 227, 91, +-611, 138, 48, 144, 338, -522, -128, -44, +-62, 592, 123, 119, -76, -797, -57, 87, +134, 806, 50, -511, -47, -324, -119, 418, +107, 139, 213, -222, -247, -326, -85, 346, +332, 227, 0, -199, -377, -202, 176, -115, +408, 483, -394, 79, -212, -614, 456, 239, +-42, 304, -268, -401, 192, 215, -20, 154, +-66, -386, 5, 79, -42, 248, 205, 96, +-175, -508, -188, 164, 212, 459, 51, -393, +-121, -167, -115, 275, 67, 167, 33, -202, +-67, -322, 78, 269, -148, 443, -30, -441, +180, -335, -268, 376, 132, 305, 138, -317, +-339, -243, 147, 315, 6, -78, -38, 23, +141, 181, -269, -333, -2, -91, 275, 481, +-60, -138, -125, -262, -131, 151, 154, -2, +332, 33, -313, 53, -185, -214, 325, 157, +85, 137, -183, -331, -30, 110, 246, 233, +-64, -198, -110, -66, 193, 119, -43, -23, +34, -46, 9, 83, -136, -25, 372, -90, +-60, 53, -411, 129, 293, -225, 334, 113, +-269, 211, -316, -435, 383, 140, 193, 332, +-321, -241, -136, -130, 230, 63, 181, 185, +-288, -131, -93, 74, 147, -112, 153, -118, +-251, 320, -168, -41, 410, -214, -260, -58, +-197, 285, 292, -12, -120, -198, -130, 44, +14, 29, -30, 55, 10, -40, 103, 65, +-171, -85, -241, -185, 269, 213, 116, 313, +-211, -336, -219, -381, 81, 390, 434, 446, +-318, -518, -317, -279, 278, 500, 136, -5, +68, -171, -381, -120, 16, 150, 496, 198, +-294, -276, -187, -54, 415, 188, -157, 78, +-129, -291, 409, 182, -312, 85, -31, -300, +485, 256, -354, 15, -98, -126, 440, 18, +-54, 3, -269, 5, 75, 84, 367, -51, +-50, -68, -431, 100, 270, -234, 378, 293, +-280, 169, -248, -512, 190, 1, 293, 462, +-165, -5, -231, -445, 113, 133, 129, 185, +-9, -38, -179, 24, -50, -277, 234, 187, +-114, 233, -194, -329, 184, -23, -104, 287, +-107, -133, 128, -231, -49, 346, -125, 7, +-62, -364, 107, 132, 47, 299, -233, -201, +-53, -180, 201, 204, -22, -42, -226, 78, +-21, -100, 198, -87, -66, 199, -160, 34, +116, -214, -38, -129, -44, 510, 189, -146, +-141, -551, -157, 558, 271, 105, 38, -546, +-151, 258, 35, 287, 80, -254, 0, -232, +11, 237, 99, 194, -66, -172, 8, -161, +128, 107, -44, 75, 60, -34, 60, 31, +-173, -44, 177, -54, 306, -63, -427, 294, +-122, -125, 599, -221, -56, 180, -474, 71, +194, -51, 248, -198, -70, 217, -66, 152, +-191, -358, 185, -58, 226, 439, -280, -113, +-179, -324, 240, 168, 126, 144, -327, -88, +26, -127, 191, 152, -200, 105, -119, -341, +221, 39, 3, 469, -296, -279, -23, -281, +149, 206, 153, 104, -238, 130, -336, -243, +284, -244, 257, 410, -285, 112, -246, -322, +153, -81, 217, 228, -73, 82, -334, -187, +167, 1, 215, 70, -203, -30, 16, 27, +12, -39, 61, 105, -46, -27, -12, -348, +198, 418, -185, 199, 25, -593, 196, 152, +-115, 336, 45, -285, 41, 73, -70, 79, +241, -216, -9, 186, -299, 0, 229, -88, +247, 36, -128, 30, -153, -38, 43, -39, +218, 85, 44, -38, -120, 88, -153, -153, +190, -93, 166, 312, -205, -68, -9, -165, +18, 53, 46, -28, 64, 63, -187, 177, +16, -265, 175, -102, -152, 312, -118, -149, +143, -19, -39, 164, -119, -212, -3, -83, +130, 307, -191, -15, -153, -249, 343, 53, +-196, 93, -235, 76, 251, -96, -119, -90, +-107, 42, 229, 222, -198, -195, -300, -200, +421, 441, 128, -158, -530, -259, 53, 255, +401, 22, -220, -143, -104, 179, 149, -165, +-145, -162, 171, 441, 89, -97, -327, -350, +210, 133, 235, 254, -326, -134, 101, -135, +273, 128, -269, -105, 42, 148, 295, -28, +-115, -159, -160, 225, 130, -205, 202, -22, +61, 346, -231, -98, -139, -527, 421, 297, +196, 638, -502, -635, -18, -355, 568, 667, +-240, 81, -344, -587, 422, 174, 71, 427, +-292, -287, -94, -345, 297, 333, 181, 352, +-444, -453, -131, -178, 429, 278, 21, 241, +-432, -248, 86, -281, 302, 457, -354, -86, +-103, -359, 332, 368, -131, 195, -275, -509, +54, -96, 206, 606, -84, -38, -347, -549, +179, 135, 219, 358, -294, -98, -187, -267, +215, 63, 302, 288, -439, -116, -415, -365, +752, 272, 108, 342, -801, -353, 236, -265, +501, 330, -369, 256, -182, -503, 327, 149, +64, 364, -208, -525, -86, 2, 180, 529, +339, -35, -243, -638, -522, 58, 588, 809, +557, -269, -834, -797, -177, 605, 904, 482, +-114, -817, -664, -16, 394, 750, 505, -235, +-497, -712, -203, 449, 612, 637, -42, -755, +-471, -197, 305, 655, 258, -125, -299, -400, +-48, 208, 207, 338, 16, -453, -145, -59, +4, 542, 58, -334, 95, -273, -141, 420, +-216, 57, 361, -320, -11, -96, -446, 397, +204, 185, 223, -737, -312, 26, -18, 1031, +105, -505, -207, -1088, 221, 1117, -23, 779, +-470, -1672, 319, 45, 284, 1577, -611, -734, +-19, -1071, 649, 1024, -367, 637, -596, -1284, +534, -141, 529, 1453, -774, -404, -470, -1501, +1017, 1005, 142, 1347, -1034, -1645, 116, -811, +993, 2058, -348, 8, -969, -2116, 756, 925, +767, 1630, -1008, -1531, -415, -878, 1154, 1596, +143, 432, -1164, -1709, 286, 33, 1116, 1888, +-653, -864, -811, -1606, 1054, 1617, 432, 920, +-1195, -1998, 127, -136, 1163, 2036, -500, -628, +-904, -1778, 808, 1382, 629, 1060, -903, -1773, +-285, -138, 908, 1666, 77, -574, -875, -1399, +167, 1281, 764, 739, -390, -1698, -485, 292, +452, 1448, 148, -1120, -380, -811, 65, 1671, +162, -187, -49, -1530, -164, 996, -154, 824, +436, -1150, 37, -189, -769, 1039, 217, -462, +829, -561, -532, 903, -826, -207, 731, -862, +664, 881, -956, 475, -507, -1392, 1140, 294, +109, 1478, -1292, -1239, 459, -951, 1053, 1941, +-1033, -52, -532, -2040, 1285, 1113, -84, 1545, +-1275, -1878, 612, -733, 1064, 2375, -1114, -435, +-563, -2289, 1483, 1704, -292, 1367, -1307, -2406, +1205, -56, 538, 2392, -1592, -1277, 509, -1609, +1410, 2139, -1340, 328, -683, -2109, 1696, 717, +-31, 1555, -1576, -1341, 579, -769, 1369, 1582, +-958, -165, -896, -1240, 1111, 815, 374, 568, +-804, -969, -147, 65, 533, 741, 289, -487, +-561, -297, -340, 547, 839, -90, 140, -295, +-1031, 170, 177, -49, 1178, 221, -617, -17, +-1326, -718, 1489, 707, 815, 682, -2281, -1593, +342, 98, 2285, 2109, -1495, -1364, -1771, -1915, +2387, 2775, 658, 664, -2773, -3567, 799, 1480, +2225, 2805, -2126, -3271, -910, -856, 2707, 3955, +-913, -1495, -2138, -3420, 2307, 3761, 491, 1354, +-2584, -4840, 1356, 1631, 1570, 3982, -2645, -4222, +254, -1421, 2752, 5241, -2184, -1830, -1592, -4045, +3421, 4086, -538, 1436, -3274, -4546, 2724, 1420, +1682, 3128, -3877, -3301, 669, -540, 3483, 3335, +-2642, -1767, -1824, -1880, 3565, 2953, -342, -491, +-3062, -2250, 2200, 2361, 1440, -21, -2832, -2285, +433, 1921, 2322, 876, -1745, -2551, -933, 844, +2057, 1881, -538, -2100, -1267, -192, 1356, 2057, +63, -1318, -1209, -1027, 903, 2031, 461, -461, +-1314, -1619, 597, 1698, 1018, 75, -1381, -1459, +-253, 1059, 1531, 292, -443, -1033, -1195, 736, +745, 119, 741, -1019, -738, 1100, -534, 256, +815, -1685, 221, 999, -894, 1261, 127, -2074, +869, 259, -584, 1876, -807, -1797, 1308, -265, +-12, 1955, -1560, -1446, 1074, -750, 977, 2255, +-1798, -1245, -4, -1343, 1908, 2486, -1106, -570, +-1363, -2260, 1895, 2309, 225, 797, -1995, -3143, +1032, 1544, 1210, 1999, -1836, -2965, 247, 394, +1455, 2382, -1313, -2275, -373, -392, 1560, 2683, +-742, -1935, -922, -1259, 1338, 3137, -271, -1284, +-789, -2122, 1070, 3061, -364, -459, -893, -2717, +1327, 2745, 137, 540, -1754, -3187, 1132, 1959, +1189, 1543, -1968, -3081, 162, 1006, 1832, 2149, +-1336, -2699, -922, -7, 2017, 2577, -419, -1734, +-1748, -1228, 1667, 2386, 496, -517, -1937, -1820, +984, 1855, 1118, 290, -1745, -1899, 227, 954, +1384, 1114, -1211, -1408, -336, -258, 1438, 1302, +-851, -336, -839, -976, 1360, 611, 7, 770, +-1286, -941, 667, -395, 705, 1282, -1011, -486, +-22, -1012, 872, 1445, -505, -129, -517, -1649, +571, 1670, 276, 420, -550, -2210, -289, 1538, +679, 827, 80, -2389, -705, 1483, 173, 1141, +454, -2771, -147, 1445, -524, 1524, 275, -3019, +719, 1514, -853, 1668, -454, -3409, 1339, 1500, +-288, 2323, -1236, -3631, 996, 777, 791, 2844, +-1540, -3114, -21, 5, 1823, 2826, -1086, -2347, +-1212, -577, 1959, 2528, -167, -1666, -1803, -671, +1635, 1925, 643, -1002, -2377, -713, 1312, 1018, +1706, 123, -2948, -602, 634, -411, 2741, 1172, +-3150, -176, 66, -1628, 3310, 2097, -3248, -332, +-312, -2151, 3601, 2739, -3011, -674, -628, -1901, +3253, 2580, -2258, -1229, -826, -640, 2429, 1785, +-1242, -1801, -896, 833, 1601, 457, -468, -1039, +-1239, 569, 1731, -134, -260, 812, -2056, -1728, +2706, 987, -479, 1387, -2668, -3013, 3110, 1988, +-83, 678, -3092, -2198, 2442, 1240, 1408, 743, +-3844, -1528, 1582, 553, 2682, 971, -3993, -1507, +1054, 553, 2307, 880, -2518, -1275, 358, 286, +952, 974, -620, -1287, 265, 415, -391, 903, +188, -1528, 360, 912, -419, 278, -98, -896, +276, 338, 627, 925, -1683, -1475, 926, 100, +1516, 2339, -2817, -3189, 1016, 1216, 2194, 1579, +-3282, -2314, 1101, 449, 2357, 2074, -3764, -2863, +1846, 983, 1728, 2217, -3260, -3969, 1419, 2456, +1692, 1165, -2856, -3457, 1073, 1996, 1897, 1814, +-3119, -3805, 1318, 1593, 1670, 2509, -3016, -3973, +1503, 1282, 1401, 2462, -2840, -3223, 1446, 410, +1417, 2792, -2861, -3070, 1509, 486, 1412, 1975, +-2789, -2214, 1218, 986, 1449, 166, -2499, -821, +1262, 975, 684, -467, -1953, -287, 1817, 620, +-743, -563, -586, 446, 1201, -187, -1074, -325, +699, 802, -408, -757, -217, -86, 1385, 1091, +-1813, -862, 339, -760, 1947, 1845, -2444, -909, +668, -881, 1266, 1345, -1669, -104, 611, -1170, +493, 901, -815, 398, 324, -873, -22, 127, +24, 332, 94, 157, -341, -375, 333, -285, +-159, 730, 253, -273, 39, -195, -753, 50, +1044, -65, -131, 791, -871, -1253, 922, 508, +-361, 654, 9, -913, -57, 260, -26, 414, +213, -512, -309, -166, 140, 1251, -15, -1486, +61, 160, -73, 1495, 161, -1642, -160, 130, +149, 1409, 227, -1364, -675, -239, 784, 1655, +18, -1180, -1225, -749, 1527, 1855, -377, -754, +-1297, -1280, 1622, 1762, -549, -116, -703, -1625, +921, 1487, -518, 215, 149, -1711, -11, 1679, +55, -148, 57, -1460, -317, 1393, 796, 283, +-889, -1423, 208, 539, 1055, 1245, -1746, -1780, +985, 403, 570, 1470, -1656, -1852, 984, 295, +694, 1567, -1662, -1799, 590, 265, 1198, 1322, +-1590, -1352, 273, 72, 1071, 906, -977, -693, +91, -3, 702, 288, -785, -148, 328, -113, +433, 320, -687, -225, 119, -225, 340, 446, +-90, 67, -452, -708, 209, 450, 330, 525, +-321, -949, -269, 403, 434, 179, 184, -223, +-697, 249, 541, -335, 244, -147, -652, 870, +457, -650, 162, -487, -326, 1073, -155, -307, +527, -994, -74, 1549, -810, -1060, 832, 231, +-41, 328, -813, -772, 853, 1327, -234, -1544, +-313, 952, 46, 150, 739, -956, -659, 1080, +-455, -935, 1613, 926, -1398, -698, -153, -253, +1887, 1415, -2113, -1668, 566, 597, 993, 1034, +-1290, -1926, 526, 1451, 13, -328, 78, -365, +-700, 651, 788, -1144, 259, 1555, -1480, -1249, +1436, 445, -158, 394, -756, -1213, 525, 1600, +500, -813, -1017, -765, 438, 1446, 752, -304, +-1555, -1364, 1257, 1490, -101, 14, -1028, -1074, +840, 327, 308, 1057, -924, -1181, 108, -93, +983, 1241, -823, -1029, -308, -231, 776, 1199, +370, -995, -1509, -62, 840, 1047, 1191, -991, +-2135, -384, 929, 1752, 1151, -1141, -2130, -1112, +1060, 2196, 770, -583, -1491, -1628, 680, 1540, +243, 573, -403, -1774, -12, 551, 501, 1235, +-375, -1172, -508, -435, 1276, 1247, -676, -127, +-751, -1382, 1383, 1005, -314, 1189, -1202, -2509, +1183, 1107, 417, 1438, -1584, -2279, 866, 959, +611, 522, -1191, -468, 464, -570, 478, 689, +-516, 541, -89, -1231, 68, 208, 637, 872, +-456, -290, -667, -783, 1054, 386, -189, 887, +-361, -949, -107, -404, 447, 1166, 97, -136, +-818, -1142, 624, 591, 232, 1105, -692, -1402, +231, -171, 356, 1333, -365, -567, 114, -882, +-19, 1081, -84, 70, 297, -1137, -122, 1172, +-393, -506, 383, -204, 390, 673, -531, -535, +-937, -430, 2166, 1088, -547, -10, -2824, -1886, +3598, 1753, -243, 835, -3434, -2675, 3255, 1380, +38, 1214, -2435, -2004, 2010, 785, -141, 523, +-1170, -964, 1246, 787, -232, -77, -1007, -865, +1259, 902, -111, 196, -1223, -823, 1204, -52, +3, 901, -796, -90, 425, -1133, 59, 610, +67, 787, 23, -388, -593, -1368, 318, 1224, +978, 1224, -1011, -2328, -1041, 325, 2430, 1669, +-663, -765, -2432, -1230, 3049, 1063, -463, 870, +-2261, -1704, 2376, 672, -569, 534, -860, -971, +888, 996, -38, -369, -660, -1031, 231, 1472, +1140, 85, -1468, -1265, -312, -41, 2065, 1437, +-1099, -38, -1499, -1908, 2066, 721, 224, 1918, +-1987, -1504, 625, -1485, 1499, 2162, -919, 711, +-1295, -2626, 1297, 631, 937, 2070, -1788, -1446, +8, -1195, 1658, 2009, -1100, -478, -529, -1081, +1213, 1456, -510, -782, -523, -703, 730, 1662, +116, -406, -912, -1678, 337, 1225, 1076, 1365, +-1284, -1990, -237, -354, 1351, 1871, -642, -498, +-509, -1068, 574, 731, -302, -251, 555, 722, +-282, -126, -862, -1720, 961, 1416, 708, 1515, +-1454, -2342, -298, -838, 1923, 3156, -1122, -1012, +-317, -2063, 468, 1936, -738, -222, 1802, -71, +-1259, -145, -1388, -729, 2448, 1188, -334, 20, +-1488, -831, 519, -94, 979, 527, -602, 862, +-300, -1554, 192, -53, -64, 1295, 641, -129, +-420, -927, -971, -395, 1294, 1684, 278, -414, +-1404, -1215, 734, 593, -102, 362, 400, 504, +17, -983, -1390, -786, 1291, 2007, 719, -271, +-1843, -1872, 842, 1398, 443, 354, -675, -661, +459, -215, -62, 364, -492, 283, 268, -369, +833, 8, -1101, -362, -184, 798, 1084, 377, +-456, -2029, -338, 1180, 223, 1617, -117, -2390, +294, 124, 234, 1639, -896, -708, -34, -762, +1593, 524, -790, 374, -1604, -265, 1548, -402, +1178, 513, -2081, -143, -212, -142, 1690, 402, +-379, -782, -689, 766, -238, -9, 748, -658, +283, 290, -699, 353, -178, 74, 306, -956, +566, 684, -394, 483, -814, -918, 1037, 387, +-64, 14, -466, -55, 412, 325, -592, -602, +601, 101, 84, 712, -566, -461, 226, -734, +138, 1076, -103, 33, 73, -1018, 14, 719, +-300, 56, 27, -224, 857, 31, -768, -203, +-654, 574, 1254, -327, -34, -638, -649, 1177, +-379, -444, 596, -705, 1019, 759, -1299, 272, +-881, -758, 1632, -154, 608, 1101, -1696, -543, +-385, -755, 1662, 981, 83, -199, -1437, -147, +188, -38, 1126, -186, -700, 532, -51, -118, +276, -347, -563, -99, 398, 396, 559, 456, +-582, -785, -937, -690, 1381, 1574, 493, 231, +-1672, -2195, 148, 1116, 1336, 1321, -381, -1422, +-848, -393, 261, 839, 423, 377, 178, -756, +-332, -23, -525, 208, 260, -166, 1020, 1102, +-466, -1242, -1613, -786, 1402, 1873, 1269, 127, +-2038, -1593, -257, -210, 1732, 1772, -406, -356, +-980, -1077, 448, 412, 619, -91, -671, 962, +57, -479, 427, -1055, -440, 523, 41, 1186, +167, -500, 44, -1369, -78, 701, -167, 1194, +-271, -750, 1058, -872, -425, 883, -1305, -241, +1429, 254, 519, 442, -1544, -1534, 323, 342, +996, 1960, -751, -1203, -40, -1623, 386, 1552, +-510, 1039, 139, -1381, 952, -500, -1338, 755, +-177, 250, 1667, 203, -885, -780, -818, -519, +595, 1335, 883, 252, -715, -1398, -850, 69, +938, 1146, 592, -254, -830, -783, -525, 238, +810, 594, 368, -408, -584, -124, -481, 279, +471, -355, 755, 397, -853, -26, -508, -437, +890, 342, 235, 108, -719, -242, -194, -29, +879, 290, -485, -190, -91, -161, 413, 306, +-589, -227, 405, 349, 241, -381, -646, -171, +322, 536, 279, 43, -572, -430, 137, -224, +795, 637, -1093, -118, -115, -148, 1381, 13, +-776, -504, -719, 827, 895, 137, -127, -865, +53, 142, -55, 261, -610, 361, 716, -8, +121, -953, -133, 76, -653, 1106, 271, 145, +740, -1138, -412, -734, -428, 1625, -65, 795, +534, -1903, 341, -191, -683, 936, -478, 628, +722, -461, 538, -1108, -441, 624, -966, 543, +572, 40, 1195, -232, -855, -1051, -904, 819, +721, 790, 741, -505, -593, -479, -634, -543, +566, 1040, 377, 963, -638, -1762, 302, -186, +87, 1023, -665, 193, 776, -350, 206, -412, +-817, -72, -33, 554, 786, 313, -93, -714, +-614, 81, 276, -75, -25, 199, 408, 741, +-252, -1026, -682, -470, 1002, 1395, -337, -370, +-399, -756, 741, 705, -703, -174, 25, -324, +833, 597, -786, -210, 53, -463, 250, 608, +-129, -404, 412, 217, -596, 169, -142, -442, +684, 119, 156, 294, -935, -198, 150, -209, +726, 727, -412, -896, -123, -10, 312, 1155, +-534, -721, 88, -695, 997, 892, -849, -42, +-508, -309, 689, 452, 337, -642, -239, -216, +-604, 1159, 2, -190, 1088, -914, -315, -74, +-1045, 660, 627, 794, 403, -966, -224, -866, +-261, 745, 86, 1042, 13, -379, 155, -1359, +-60, 240, 74, 1354, -384, -62, 186, -1215, +574, 173, -668, 222, -72, 528, 444, 517, +-113, -1722, -198, -184, 272, 2160, -250, -564, +-25, -1354, 381, 408, -305, 534, -241, 285, +642, -151, -138, -955, -757, 47, 424, 1473, +751, -310, -591, -1292, -571, 217, 573, 978, +223, 124, -313, -1093, 269, 352, -407, 271, +-237, -209, 855, 380, -3, -298, -831, -170, +-32, -73, 866, 451, -168, 227, -414, -670, +43, -76, -35, 356, 13, 365, 764, -539, +-525, 120, -913, 145, 592, -527, 1019, 481, +-542, 455, -908, -416, 272, -903, 768, 660, +-77, 940, -322, -698, -379, -403, 22, -401, +930, 935, -347, 795, -495, -1448, -67, -280, +376, 815, 240, 357, -39, -392, -534, -336, +-256, 177, 1109, 10, -362, 31, -571, 463, +294, -505, 280, -333, -216, 501, -179, 22, +340, -6, -46, 36, -248, -506, 40, 127, +237, 811, -53, -523, -69, -413, -265, 284, +316, 362, 185, -308, -383, -125, -28, 310, +274, -68, -57, -446, -72, 273, -13, 628, +-83, -584, 240, -292, -29, 178, -308, 341, +230, 121, 169, -354, -183, -290, -147, 183, +72, 394, 306, 173, -339, -770, 189, -46, +-56, 827, -453, -317, 592, -459, 321, 513, +-689, 132, -292, -902, 645, 712, 267, 301, +-545, -647, 11, 196, 168, -10, -235, -57, +515, 291, -245, -280, -439, 192, 385, -22, +427, -486, -807, 374, 85, 353, 726, 56, +-405, -920, -325, 123, 65, 915, 555, -228, +-324, -555, -49, 166, -69, 168, -236, -101, +799, 175, -134, -46, -829, -172, 237, -65, +546, 211, 29, -9, -235, 120, -511, -178, +108, -398, 833, 508, -87, 250, -833, -385, +21, -227, 539, 176, 240, 258, -238, -17, +-562, -78, 156, -589, 607, 487, 36, 667, +-561, -722, -130, -380, 284, 403, 209, 205, +141, 113, -385, -113, -360, -335, 249, -468, +743, 946, -530, 306, -474, -738, 643, 267, +-291, -862, -38, 473, 413, 1314, -283, -812, +-312, -1089, 455, 839, 53, 239, -390, -532, +11, 892, 436, -440, -129, -1002, -312, 978, +96, 396, 48, -694, 67, -12, 251, 152, +-286, 268, -596, -257, 858, -160, 141, 154, +-694, 115, 127, 58, 266, -187, 52, -29, +-209, -124, -8, 392, 54, 77, -116, -520, +291, -282, 110, 1239, -702, -270, 313, -1276, +399, 568, -369, 511, 186, 536, -200, -766, +-66, -979, 305, 882, -144, 755, -81, -423, +243, -556, -162, 39, -196, 378, 220, 129, +132, -400, -238, 108, 174, 445, -152, -723, +-80, 33, 208, 817, 167, -308, -308, -775, +-323, 320, 684, 738, 76, -248, -604, -221, +-136, -782, 590, 418, 99, 1511, -412, -970, +177, -1145, -298, 774, -22, 552, 726, -183, +-251, -188, -445, -204, -284, -108, 759, 540, +303, 96, -996, -960, 263, 798, 403, 426, +-89, -1174, -412, 154, 305, 1068, 166, -408, +-401, -808, 182, 547, 257, 240, -344, -189, +-3, 6, 158, -164, -173, -90, 340, 369, +15, 190, -589, -396, 36, -537, 747, 767, +-169, 257, -579, -718, 268, 333, 256, -10, +-406, -322, 253, 237, 301, 626, -565, -749, +-26, -361, 425, 808, 77, -27, -462, -430, +-43, 189, 600, -47, -288, -129, -360, 322, +485, 137, -275, -553, -14, 121, 464, 256, +-548, -255, 42, 206, 314, 493, -123, -997, +-267, -277, 409, 1305, 15, -51, -522, -987, +313, 106, 196, 512, -339, -51, 227, -62, +202, 82, -805, -589, 566, 357, 485, 648, +-843, -702, 85, -43, 520, 187, -123, -8, +-628, 54, 646, 66, 126, -29, -764, -476, +639, 515, -60, 92, -354, -420, 341, 261, +11, 119, -365, -396, 192, -17, 391, 497, +-402, -47, -195, -279, 326, -117, 26, -175, +-60, 661, 25, 154, -204, -824, 70, 163, +287, 401, -224, -303, -257, 58, 564, 339, +-205, -291, -514, -316, 539, 302, 182, 340, +-460, -442, 43, -192, 277, 675, -158, -402, +-24, -4, 66, -159, -125, 79, 145, 530, +198, -433, -445, -213, -71, 151, 504, 134, +78, 200, -653, -450, 149, 22, 474, 373, +-191, -58, -251, -332, 7, -143, 281, 672, +25, -43, -259, -635, 65, 33, 10, 521, +17, -22, 41, -288, 127, 97, -70, -212, +-524, 20, 399, 545, 558, -169, -608, -590, +-406, 230, 820, 553, -201, -495, -560, -222, +700, 662, -192, -175, -396, -632, 611, 577, +-238, 27, -531, -337, 682, 482, 71, -593, +-418, 231, -45, 493, 226, -542, -3, -396, +-239, 708, 363, 364, 50, -824, -651, -72, +240, 414, 599, 63, -533, -51, -109, -96, +453, -211, -386, 236, 38, 265, 196, -539, +-236, 120, 312, 513, -157, -488, -256, -92, +216, 463, -61, -561, 274, 341, -196, 352, +-273, -676, 280, 204, -75, 169, 78, -384, +50, 713, -234, -284, 64, -690, 101, 669, +-70, 53, 78, -18, -147, -432, -34, 10, +270, 814, -153, -446, -142, -552, -111, 134, +359, 872, 239, -206, -836, -1025, 331, 652, +312, 443, -399, -576, 347, 105, -166, -53, +-249, 92, 140, 470, 306, -574, -225, -572, +-219, 924, 191, 368, 116, -831, -164, -43, +-228, 210, 482, 142, -222, 252, -277, -501, +332, -181, -68, 545, -100, 70, 96, -316, +-126, -366, -120, 293, 510, 836, -231, -780, +-637, -666, 567, 906, 333, 279, -445, -560, +-254, -151, 295, 221, 9, -18, 104, 250, +-93, 183, -470, -1114, 442, 489, 328, 1128, +-641, -958, -24, -599, 491, 760, -292, 350, +16, -439, -15, -364, -83, 219, 45, 613, +7, -504, 321, -273, -596, 351, -131, 27, +894, 139, -517, -401, -421, -105, 616, 613, +-311, -68, -7, -688, 211, 386, -417, 440, +305, -607, 65, 220, -360, 186, 82, -512, +270, 306, -65, 554, -462, -752, 282, -235, +224, 774, -197, -84, -200, -590, 31, 554, +181, -135, 86, -371, -298, 555, -142, -300, +362, -23, -43, 268, -164, -277, -95, -224, +164, 554, -85, -25, 19, -556, 8, 271, +-136, 309, 201, -273, -344, -73, 127, 79, +461, -140, -641, 402, -62, -44, 364, -571, +83, 179, -259, 512, -294, -115, 344, -490, +118, 134, -195, 351, -173, -5, 32, -387, +110, -145, 251, 757, -341, -144, -447, -773, +608, 338, 218, 499, -604, -85, -49, -521, +330, -77, -87, 644, -82, 23, 53, -562, +-121, -117, -96, 626, 268, 7, -148, -455, +-126, 43, 109, 101, -39, 135, -81, 137, +91, -373, -146, -184, 80, 604, 123, -36, +-367, -653, 68, 375, 324, 344, -193, -404, +-375, 107, 392, -156, 187, 13, -673, 380, +170, -149, 528, -296, -423, 177, -147, 53, +114, -172, -154, 317, 358, -95, 36, -222, +-617, 50, 122, 72, 424, 93, -239, 21, +-30, -201, 12, -7, -301, 188, 259, -90, +218, 66, -400, -183, -12, 80, 133, 204, +15, -115, -65, -341, -118, 343, 40, 270, +9, -637, 81, 347, -35, 136, -299, -332, +84, 166, 296, 52, -82, -40, -414, -72, +245, 33, 119, 140, -417, -243, 432, 82, +-75, 211, -388, -243, 206, 97, 0, -63, +96, -101, -134, 268, -87, 223, 81, -762, +-143, 155, 100, 685, 148, -286, -222, -286, +-288, -198, 413, 519, 35, 96, -364, -446, +177, 182, -85, -28, -77, -178, 307, 366, +-159, 41, -454, -336, 428, -64, 126, 78, +-310, 288, 57, 181, -235, -593, 326, -282, +139, 796, -496, 195, -44, -776, 371, -54, +192, 643, -619, -213, -113, -140, 566, -75, +25, 233, -392, 23, -169, -285, 234, 83, +261, 182, -280, 70, -179, -341, 188, 19, +35, 305, -176, -80, 8, -153, 153, -54, +-34, 261, -228, 46, -65, -524, 370, 396, +-165, 143, -102, -217, -102, 32, 43, -257, +373, 357, -407, 84, -240, -361, 510, 143, +-44, 69, -389, -66, 126, -81, 124, 157, +-77, 155, -71, -469, 80, 91, 5, 631, +-235, -716, 111, -11, 247, 694, -360, -498, +235, -216, -223, 348, -125, 160, 510, -327, +-302, -98, -170, 327, 6, -119, 271, 58, +-36, -111, -443, -254, 338, 422, 223, 233, +-507, -573, 183, -114, 91, 449, -77, 82, +100, -270, -275, -59, 221, 11, 74, 203, +-338, 16, 198, -324, 12, 114, 39, 299, +-59, -233, -251, -194, 249, 100, 134, 340, +-145, -139, -284, -561, 389, 523, 9, 269, +-418, -611, 452, 92, -134, 291, -151, -176, +282, 52, -401, -40, 298, -202, 160, 359, +-525, -250, 330, -25, 79, 321, -165, -329, +45, -177, -152, 332, 286, 116, 70, -184, +-350, -361, 131, 313, 95, 290, 123, -441, +-200, -94, 10, 442, 166, -139, -236, -494, +150, 575, 112, -119, -51, -201, -290, 32, +202, -83, 322, 449, -305, -453, -86, -88, +182, 56, 169, 333, -185, -9, -13, -712, +247, 422, -178, 251, -30, -388, 273, 183, +-88, -71, -231, -342, 249, 424, 66, 133, +-122, -483, 81, -167, -103, 534, 169, -7, +165, -505, -223, 173, -19, 56, 234, -22, +77, 121, 29, -300, -176, -65, -149, 256, +482, -61, 317, -37, -759, -271, -118, 75, +911, 270, -201, -153, -364, -311, 95, 189, +163, 10, 244, -127, -48, 242, -254, -321, +192, -233, 303, 415, -110, 16, 9, -252, +-113, -277, 371, 319, -93, 7, -111, -287, +315, 303, -277, -296, 218, -162, 94, 209, +-50, 5, 136, 48, -179, -314, 256, -208, +292, 330, -244, 209, -72, -366, 275, -396, +349, 310, -230, 282, -239, -423, 430, 21, +159, -152, -174, 96, -8, 136, 162, -402, +103, 31, -35, 417, 87, -539, 239, -337, +-244, 679, 267, -2, 199, -629, -181, -86, +350, 383, -45, 17, -112, -188, 321, -302, +149, 9, -124, 236, -23, -45, 192, -232, +142, -218, 32, 284, 1, -176, -26, -143, +266, 195, 222, -192, -192, -201, 95, -56, +294, 257, 127, -34, -7, -360, -154, -171, +331, 173, 451, 335, -495, -554, 81, -207, +444, 440, -226, -338, 382, -114, -20, 292, +-280, -321, 371, -299, 269, 285, 129, 182, +-253, -558, 139, -23, 357, 242, 172, -153, +-126, -109, 78, -105, 183, -78, 127, 89, +118, 73, -170, -564, 316, 120, 137, 461, +-132, -458, 198, -491, 153, 377, 25, 323, +162, -477, 165, -277, -4, 13, 47, 185, +455, 350, -130, -717, -173, -612, 733, 1105, +-192, -6, -283, -997, 470, 96, 139, 490, +99, -177, -173, -335, -47, 13, 673, -64, +-109, 75, -78, -48, 149, -271, 129, -95, +419, 389, -115, -299, -121, -591, 366, 565, +251, 184, -57, -635, -92, -186, 212, 309, +301, 61, -132, -193, 184, -172, 16, -214, +-31, 2, 521, 573, -132, -478, -18, -733, +300, 679, 58, 204, 133, -603, 41, -139, +391, 287, -162, -144, -239, -118, 764, 104, +31, -388, -356, 49, 119, 355, 422, -459, +57, -280, -75, 438, 149, -77, 22, -445, +260, 94, 155, 116, -67, -191, 211, 22, +117, -120, 23, -241, 245, 281, -4, -108, +64, -262, 169, 117, 2, -176, 157, 52, +143, -17, -157, -188, 181, -8, 351, 32, +-103, -74, -21, -276, 128, 220, 353, 38, +102, -378, -228, 41, 207, 33, 257, 23, +62, -116, 41, -180, 6, 33, 103, -59, +226, 158, -16, -258, -42, -249, 243, 351, +117, -114, -22, -327, -12, 138, 271, 66, +298, -165, -249, -89, -136, -118, 623, 217, +145, -50, -366, -314, 132, -78, 305, 229, +164, 47, -127, -383, -80, 18, 263, 58, +208, 20, -103, -114, 111, -96, 34, -65, +119, 89, 165, -16, 73, -254, 3, 108, +-44, -34, 389, -91, 70, -46, -125, 112, +-61, -282, 333, -113, 307, 511, -444, -337, +7, -559, 577, 558, -61, 157, -182, -532, +177, 91, -21, -105, 321, 101, 72, 226, +-229, -441, 250, -123, 177, 273, -60, -59, +89, -184, 137, 176, -9, -292, -35, -64, +141, 326, 204, -170, -57, -197, 38, -22, +-61, 116, 109, -63, 366, -89, -44, 83, +-278, -167, 80, -206, 635, 394, -80, 62, +-526, -655, 305, 69, 506, 586, -204, -264, +-174, -539, 256, 331, 47, 127, 52, -137, +54, -129, 16, -120, 16, 203, -10, -39, +373, -99, -77, -114, -231, -6, 339, 178, +54, -184, -21, -71, 43, 68, 153, -64, +-104, -92, 51, 87, 434, 38, -346, -260, +-160, 100, 480, -67, 101, 35, -278, 119, +57, -312, 255, -79, 35, 238, 14, 91, +-49, -300, -101, -181, 470, 230, 47, 210, +-467, -369, 407, -142, 165, 272, -297, -70, +279, -83, 73, -9, -327, -191, 421, 263, +120, -58, -382, -350, 381, 377, -42, -169, +-155, -216, 333, 285, -28, -84, -75, -189, +120, 23, 58, 123, -5, -85, 84, -44, +-23, -14, -37, -96, 153, 50, 135, 142, +-170, -131, 23, -306, 249, 260, -167, 65, +101, -70, 26, -104, -20, -199, 227, 218, +-128, 125, 67, -92, 59, -369, -83, 112, +188, 326, 9, -136, -104, -196, 119, -155, +70, 208, 61, 219, -114, -189, -76, -374, +304, 141, 30, 425, -174, -277, -30, -253, +291, 93, 94, 155, -309, -33, 54, -140, +251, 46, -36, -156, -5, 196, 16, 26, +-125, -296, 318, 196, -49, -34, -296, -119, +280, 148, 132, -97, -218, -104, 113, 115, +183, 88, -286, -293, 81, 49, 299, 272, +-123, -179, -292, -207, 322, 140, 240, 136, +-381, -168, 104, 13, 97, -6, -165, -86, +302, 76, 19, 152, -479, -251, 353, -32, +345, 160, -411, -131, -128, 178, 290, -109, +66, -186, -71, 94, -18, 174, -125, -12, +216, -269, 145, 91, -326, 71, -115, -15, +494, 82, -83, -125, -424, -157, 373, 193, +45, 195, -271, -323, 201, -21, -30, 259, +-116, -179, 237, -29, -115, 211, -169, -263, +266, 88, 54, 250, -396, -390, 119, 71, +383, 350, -237, -247, -231, -200, 225, 295, +125, -52, -212, -40, 30, 52, -21, -116, +-10, 31, 238, 223, -218, -177, -211, -155, +386, 363, -76, -167, -253, -159, 159, 249, +7, 24, -6, -187, -12, 46, -15, 131, +-62, -104, 30, 88, 61, -24, -50, -65, +-149, 86, 143, 1, 170, 3, -377, 32, +72, 31, 174, -182, -54, 134, -165, 244, +-9, -238, 228, -94, -157, 122, -39, 214, +-45, -135, 12, -154, 146, 167, -183, 74, +-38, -5, 45, -174, 74, 128, -23, 203, +-261, -189, 134, -46, 140, 37, -183, 285, +-75, -121, 91, -290, 55, 328, -159, 22, +3, -78, 77, 110, -186, -134, 94, -17, +152, 279, -324, -37, -42, -227, 322, 139, +-140, 185, -315, -162, 135, -14, 244, 226, +-236, -84, -250, -142, 316, 170, 15, 167, +-362, -171, 159, -87, 112, 251, -240, -36, +66, -56, 53, 120, -186, -87, 25, 44, +133, 190, -258, -157, 7, -32, 111, 229, +-150, -74, 61, 41, -156, -101, 10, 146, +99, 177, -219, -260, 20, 22, 118, 292, +-210, -29, -74, -254, 234, 253, -179, 42, +-243, -62, 232, 121, 9, -99, -326, 16, +151, 229, 43, -123, -265, 0, 110, 97, +8, -14, -264, 75, 118, -33, 70, 156, +-251, -100, -34, -63, 152, 306, -229, -106, +-12, -36, 68, 83, -212, 26, 20, 90, +11, -46, -124, 67, -9, -2, -72, 69, +-122, 5, 92, 61, -107, 21, -153, -13, +39, 123, 47, -68, -172, 92, -237, 62, +238, -79, 79, 170, -518, -16, -35, -124, +436, 272, -272, 89, -340, -293, 12, 72, +167, 344, -14, 30, -337, -303, -223, 9, +388, 453, -29, -90, -614, -194, 198, 141, +210, 92, -411, 45, 6, 96, 11, -133, +-234, -54, 121, 484, -70, -223, -371, -269, +100, 487, 154, 40, -397, -291, -109, 149, +199, 252, -246, -177, -173, 103, 124, 160, +-194, -256, -177, 161, 65, 336, -67, -192, +-163, -174, -178, 234, -15, 254, 17, -209, +-136, 12, -201, 232, -133, -214, 114, 190, +-156, 167, -172, -148, -55, 110, -219, -2, +95, -75, -137, 341, -127, 140, -133, -457, +-162, 9, 25, 579, -20, 84, -286, -448, +-174, -52, 184, 452, -281, 174, -204, -250, +72, -110, -38, 233, -383, 241, -141, -160, +227, -84, -172, 276, -306, 60, -159, -134, +14, 38, 33, 195, -188, 129, -286, -105, +-187, -176, 188, 256, -4, 436, -587, -463, +11, -64, 123, 477, -221, -132, -208, 49, +-118, 71, -89, -140, -36, 242, -136, 179, +-284, -253, -55, 104, 3, 225, -148, -36, +-278, -43, -26, 38, -91, 305, -155, -199, +-84, 37, -263, 111, 17, 233, -193, -200, +-132, -83, 20, 542, -376, -330, -81, 36, +192, 224, -497, 34, -35, -123, 41, 194, +-367, -26, 57, 168, -89, -96, -299, 61, +-146, 191, -4, -223, -20, 384, -255, -79, +-327, -153, 3, 205, 170, 135, -346, 5, +-353, 23, 86, -161, -53, 287, -167, 190, +-148, -301, -290, 242, 90, -84, -11, 248, +-531, -92, 97, 27, 23, 194, -236, -179, +-292, 277, -169, -187, 374, 236, -386, 127, +-451, -267, 87, 82, 101, 340, -154, 62, +-385, -386, -90, 235, -8, 179, 52, 80, +-248, -97, -398, -63, 41, 176, 276, 133, +-568, 34, -85, -179, -54, 222, 7, -111, +-165, 445, -268, -450, -29, 289, -161, -63, +114, 209, -263, 11, -369, -208, 143, 348, +69, -112, -362, 97, -192, -30, 8, 154, +-55, -37, -27, 34, -401, 59, -45, 36, +105, 153, -212, -168, -146, 201, -273, -44, +177, 58, -138, 162, -239, -48, -164, -124, +52, 138, -49, 350, -246, -278, -141, -56, +-15, 142, -35, 332, -214, -243, -107, -89, +-101, 264, -2, 84, -180, -175, -94, 170, +-147, 26, -31, 48, 8, -79, -364, 169, +56, 54, -56, -95, -44, 209, -324, -244, +-15, 242, 124, 248, -302, -326, -127, -59, +56, 424, -305, -76, 210, -94, -146, 104, +-569, -96, 405, 230, 34, 100, -549, -208, +30, 18, 145, 284, -350, -107, 166, -15, +-226, 140, -242, -56, 127, -9, -29, 217, +-277, -126, -4, 61, -102, 62, -49, 2, +-184, 5, 134, 84, -264, 112, -113, -225, +12, 141, -66, 250, -91, -240, -140, 3, +27, 310, -301, -216, 109, 8, 82, 282, +-430, -158, -63, -77, 213, 304, -201, -106, +-308, -92, 202, 221, -103, 30, -344, -189, +201, 186, -73, 143, -362, -270, 225, 282, +-126, -45, -297, -81, 102, 97, 30, 230, +-228, -306, -142, 80, 48, 278, -65, -209, +-122, 55, -30, 132, -159, -7, -105, -216, +112, 322, -155, 72, -132, -237, -86, 34, +-3, 193, -58, -51, -101, 78, -51, 18, +-127, -164, -122, 29, 99, 409, -65, -151, +-235, -296, -113, 222, 81, 130, 55, -4, +-351, 74, -5, -254, 37, 90, -151, 257, +-39, -43, -50, -28, -54, -122, -298, -13, +227, 383, -11, -21, -452, -477, 184, 405, +23, 49, -255, -119, -99, 28, 217, 144, +-301, -156, -136, 52, 140, 159, -195, -113, +-18, 106, 15, -31, -329, -79, 98, 106, +111, 195, -334, -168, 13, -97, -56, 141, +-50, 145, -31, -17, -163, -257, 3, 261, +-42, 58, -173, -160, 6, 120, 54, -26, +-213, 124, -129, -211, 73, 230, -21, -9, +-200, -106, 22, 93, -146, 69, 70, -134, +-85, 158, -267, -31, 221, -17, -117, 31, +-228, 56, -64, -19, 165, -17, -90, 136, +-257, -111, -16, -1, -57, 138, 257, -15, +-387, -156, -121, 262, 92, -104, 49, -89, +-124, 141, -190, 113, -20, -220, 30, 87, +70, 155, -336, -221, 63, 214, -13, 80, +-114, -421, 94, 412, -256, 125, -93, -466, +277, 335, -250, 45, -251, -134, 247, 27, +-62, 121, -222, -72, 7, 20, 39, -9, +-143, 88, 41, -75, -111, 107, -112, 2, +88, -143, -89, 105, -43, 196, -152, -175, +35, -8, 58, -49, -161, 214, -54, 65, +-70, -266, 142, 37, -201, 166, -38, 109, +72, -251, -177, 56, 66, 127, -40, -38, +-83, 20, -113, 1, 172, -88, -170, 149, +-67, 22, 31, -181, 26, 157, -215, 95, +111, -176, -6, -17, -184, 246, 12, -125, +156, -58, -159, 103, -282, -111, 385, 227, +-102, -155, -286, 37, 127, -143, 34, 251, +-64, 153, -36, -463, -106, 44, 13, 471, +155, -114, -174, -373, -190, 24, 201, 555, +70, -335, -209, -103, -78, 67, 92, 51, +41, 112, -55, -15, -65, -299, -161, 200, +252, 236, -8, -254, -278, -102, 68, 333, +193, -290, -223, 120, -20, 68, 126, -2, +-120, -311, 43, 441, -52, -163, -69, -102, +147, 33, -51, 191, -169, -265, 125, 160, +39, -25, -140, -2, 102, 0, -90, -76, +46, 114, -32, 7, -65, -110, 159, 5, +-72, 86, -145, 18, 43, -109, 235, -7, +-203, 131, -130, -113, 213, 6, 9, 95, +-219, -125, 223, -52, -17, 276, -255, -269, +272, 42, -29, 18, -83, 80, -15, -120, +77, 41, 5, -109, -44, 201, 95, -177, +-136, 76, 74, -162, 67, 215, -20, -16, +-103, -214, 130, -27, 12, 353, -99, -190, +56, -253, 147, 133, -199, 323, 115, -428, +-21, 112, 42, -62, 87, 256, -117, -328, +-91, 107, 294, 63, -126, -114, 19, 33, +1, 54, -50, -251, 174, 339, -51, -267, +79, 10, -219, 81, 289, -104, -32, 84, +-41, -146, -34, 156, 224, -308, -156, 372, +26, -330, 125, 286, -40, -499, 99, 535, +-107, -350, 93, 88, 30, -27, 164, -82, +-178, 61, 5, -65, 231, 172, -28, -397, +13, 240, -79, -76, 174, 108, -10, -211, +118, -70, -123, 228, 80, -139, 122, 15, +-10, -182, 14, 166, 10, -57, 203, 23, +-193, -215, 144, 105, 173, 134, -108, -261, +11, 41, 119, 36, 113, 16, -116, -258, +237, 314, -64, -190, -43, -186, 205, 118, +172, 251, -241, -406, 114, -76, 262, 270, +-161, -100, 201, -37, -36, -191, 113, 165, +-100, -122, 432, 83, -316, -36, 168, -251, +100, 229, 193, -77, -170, -105, 138, 35, +90, -44, 194, -40, -135, 26, 158, -147, +11, 185, 146, -302, 205, 297, -218, -381, +143, 242, 189, -171, 209, 137, -245, -252, +188, 73, 111, -24, 265, -9, -96, 47, +-118, -354, 399, 370, 80, -335, -21, 222, +-29, -239, 328, 36, -47, 76, 195, -248, +-72, 120, 202, -44, 170, 64, -5, -372, +0, 312, 201, -204, 350, 90, -348, -18, +270, -317, 183, 253, 64, -165, 98, 281, +121, -562, 36, 284, 4, -96, 498, 49, +-133, -87, -14, -126, 168, 72, 306, -229, +66, 470, -147, -629, 368, 250, 30, 12, +137, -162, 109, -25, 128, 74, 35, -85, +292, -85, -60, -27, 156, -71, 315, 221, +-82, -337, 47, 120, 269, -252, 325, 277, +-222, -82, 155, -179, 224, -151, 286, 220, +2, -4, -125, -219, 401, -20, 181, 3, +21, 46, 65, -129, 185, 14, 188, -67, +100, -54, 86, -12, 143, 87, 187, -269, +165, 148, -53, -80, 243, -77, 221, -37, +151, 114, -127, -192, 291, -100, 179, 169, +279, -60, -171, -184, 106, -42, 469, 236, +52, -291, -34, 79, 40, -231, 597, 290, +-235, -173, 287, -155, -73, 20, 424, -4, +78, 240, 19, -560, 124, 159, 257, 208, +202, -151, -66, -254, 261, 102, 102, 77, +187, -52, 119, -140, 107, -132, 148, 214, +135, -86, 257, -58, -20, -261, 205, 251, +108, -48, 221, -133, 139, -51, 121, -22, +-91, 44, 467, -106, 193, 94, -216, -233, +304, -9, 239, 97, 148, 111, -109, -532, +438, 358, 4, -105, 123, -10, 145, -211, +246, 221, 13, -208, 158, -11, 292, 35, +-126, -75, 354, 25, 93, -176, 155, 47, +-56, 68, 426, -68, 63, -197, -13, 18, +239, 259, 152, -393, 275, 109, -131, 26, +243, -131, 115, -49, 417, 170, -187, -155, +126, -239, 216, 251, 402, -13, -147, -194, +57, -81, 306, 218, 227, -253, 13, 27, +54, 117, 291, -207, 44, -53, 242, 107, +72, -46, 52, -49, 209, -50, 292, -178, +-43, 294, 20, -235, 473, 92, -55, -291, +99, 170, 205, 44, 184, -40, 44, -241, +146, 27, 214, 269, 32, -355, 242, 198, +64, -366, 213, 468, -7, -436, 225, 111, +307, 26, -87, 6, 49, -256, 383, 151, +140, 87, -67, -296, 304, 196, -21, -187, +272, 130, 136, -192, 186, 187, -170, -214, +443, 63, 98, -105, 150, 92, -16, -37, +185, -116, 266, -15, 110, 32, 65, 39, +-18, -131, 500, -24, -102, 5, 171, 46, +138, -152, 202, 77, 44, -8, 135, -167, +294, 79, -18, 81, 181, -187, -2, 45, +437, -43, -52, -5, 126, 69, 135, -151, +162, -14, 191, -22, 147, 165, 42, -270, +64, 81, 337, -23, 81, 30, 131, -90, +-11, 25, 255, -103, 237, 80, 35, -12, +87, -90, 109, -52, 328, 116, -27, -49, +196, -152, 74, 79, 176, 66, 170, -124, +56, -68, 224, 61, 59, 55, 161, -99, +74, -122, 319, 158, -91, -164, 313, 301, +-56, -517, 293, 296, 125, -68, 93, 130, +52, -307, 214, 99, 208, 57, -30, -34, +240, 1, 77, -152, 149, 54, 89, 77, +258, 28, -36, -321, 181, 253, 170, -77, +170, 39, -3, -170, 128, 74, 257, 65, +157, -155, -130, 79, 290, -103, 203, 101, +46, -80, 31, -72, 250, 159, 48, -265, +226, 205, 28, -47, 58, -152, 244, 91, +112, 1, 74, 20, 42, -164, 231, 77, +96, 100, 92, -202, 107, 79, 125, -52, +70, 81, 229, -103, -4, 15, 150, -97, +87, 166, 191, -111, -36, -72, 316, 26, +-102, 54, 151, -75, 204, 63, 78, -126, +-29, -36, 217, 235, 49, -254, 201, 78, +18, -18, -61, -65, 375, 72, 29, -2, +2, -50, -2, -98, 332, 78, 12, 6, +62, 61, 16, -205, 121, 1, 215, 127, +49, 47, -92, -164, 130, -118, 315, 207, +-95, -2, 19, -113, 89, -63, 264, 66, +-49, 29, -8, -74, 150, 12, 105, -19, +103, -52, -92, 69, 120, -10, 213, -70, +-20, -45, -70, 142, 142, -195, 240, 161, +-103, -128, -38, 8, 166, -23, 187, 93, +-99, -111, -24, -99, 239, 269, -90, -265, +180, 43, -80, 9, 87, 194, 27, -392, +125, 149, -30, 193, 38, -261, 20, 38, +148, 14, -43, 60, -39, -110, 151, 36, +47, -1, -94, -133, 100, 290, 41, -302, +15, -11, 64, 206, -123, -68, 201, -182, +-95, 126, 135, -8, -143, -3, 86, -25, +38, 7, 96, -113, -193, 74, 78, 166, +141, -185, -114, -232, 64, 295, -63, 132, +22, -320, 62, -38, 89, 225, -292, -164, +146, 169, 205, -176, -250, -59, -9, 111, +46, 73, 145, -139, -184, 5, -3, -72, +35, 111, 21, 34, -23, -199, 18, 194, +-225, -278, 254, 285, -34, -105, -210, -78, +94, 13, 4, 50, -27, -89, -53, 93, +37, -6, -136, -167, 39, 39, 123, 250, +-291, -317, 124, 133, -57, -28, -24, -81, +37, 174, -185, -105, 80, -56, -35, -40, +-44, 113, -23, 80, -71, -253, -40, 23, +65, 237, -147, -210, 13, 2, -62, 128, +-19, -189, -54, 88, -15, 89, -18, -121, +-212, -85, 203, 178, -145, -36, -88, -123, +-63, 69, 67, 26, -16, -37, -242, -12, +44, 18, 77, -16, -130, -55, -137, 129, +52, -97, -69, -89, 45, 174, -213, -68, +-2, -128, 18, 215, -8, -139, -213, -64, +11, 133, 0, 53, 27, -243, -288, 162, +67, -25, 63, 38, -151, -40, -142, -96, +61, 63, -18, 160, -81, -166, -213, -149, +143, 260, -66, 49, -168, -246, -16, -66, +5, 431, -126, -272, -33, -236, 55, 475, +-297, -268, 101, -99, 46, 327, -249, -285, +-15, -14, 61, 306, -189, -350, 30, 158, +-99, 111, -34, -337, -38, 389, -180, -316, +188, 248, -268, -93, -26, -313, 46, 697, +-186, -623, 129, 172, -305, 155, 142, -178, +-138, 147, -54, -239, -6, 352, -172, -317, +74, 162, -100, -7, -157, -99, 118, 143, +-198, -52, 16, -47, -144, 3, 33, 109, +-59, -71, -131, -47, -20, 63, -60, 55, +-31, -170, -67, 90, -103, 290, -51, -592, +1, 397, -95, 21, -39, -22, -152, -242, +31, 164, -5, 270, -142, -494, -215, 386, +305, -259, -314, 341, -55, -492, 5, 497, +-73, -236, 7, -85, -243, 236, 99, -109, +-158, -39, 94, -95, -208, 561, -215, -818, +358, 505, -309, 83, -186, -326, 137, 199, +-80, -18, -89, -35, -161, 31, 84, 79, +-109, -291, -141, 536, 33, -562, -25, 293, +-240, 105, 77, -340, -70, 408, -32, -336, +-223, 136, 124, 127, -220, -245, 122, 142, +-115, 286, -486, -826, 741, 956, -690, -394, +2, -245, 294, 489, -516, -502, 185, 463, +-4, -46, -280, -500, 23, 642, -23, -354, +-77, 75, -80, 214, -107, -523, -52, 688, +-65, -617, 116, 533, -452, -379, 277, 116, +-318, 193, 194, -419, -137, 561, -484, -482, +606, 268, -486, -34, -62, -186, 167, 469, +-447, -454, 305, -29, -142, 603, -332, -642, +244, 228, -307, 80, 273, 18, -490, -67, +158, -251, -43, 553, -88, -294, -237, -165, +201, 334, -278, -261, 0, 218, -23, -35, +-141, -193, -44, 307, -56, -415, -108, 706, +32, -822, -161, 703, -185, -708, 350, 927, +-598, -848, 307, 402, -242, 76, 80, -238, +-384, 157, 398, -98, -408, 437, -85, -935, +173, 1019, -161, -562, -202, 184, 34, -203, +33, 457, -203, -542, -114, 316, 219, 114, +-482, -350, 317, 330, -195, -247, -325, 127, +455, 229, -477, -461, -58, 260, 281, 42, +-387, 52, -109, -255, 380, 271, -677, -195, +500, 125, -415, 159, -32, -511, 200, 589, +-328, -329, -64, 94, 120, -47, -100, 159, +-257, -229, 209, 223, -318, -128, 202, 16, +-281, 151, 68, -209, -115, 123, -91, -30, +119, 34, -271, 96, 65, -258, -183, 159, +135, 123, -91, -91, -253, -167, 8, 295, +254, -268, -420, 295, 15, -206, 80, 35, +-182, 35, 69, -57, -211, 231, 100, -218, +-189, -11, 15, -48, 125, 507, -546, -648, +596, 357, -590, -159, 262, 65, -115, 292, +-152, -532, 165, 276, -426, 58, 467, -1, +-410, -84, -64, -1, 204, -24, -258, 182, +48, -128, 41, 73, -422, -279, 466, 439, +-352, -181, 52, -73, -158, -8, 90, 106, +-79, 72, 69, -177, -407, 80, 358, -102, +-186, 375, -74, -497, -9, 332, -138, -109, +247, 88, -448, -192, 306, 281, -181, -133, +-160, -169, 274, 317, -355, -105, 173, -145, +-169, 100, 98, 160, -157, -236, -57, 74, +194, 71, -299, 33, 4, -168, 120, 170, +-110, -136, -148, 188, 147, -99, -188, -96, +110, 51, -133, 246, 4, -275, -102, 34, +144, 83, -232, -62, 98, 202, -40, -313, +-133, 219, 121, -179, -117, 274, 15, -118, +-131, -164, 103, 38, -16, 386, -254, -427, +283, 155, -259, -48, 38, 115, 63, -33, +-141, -28, 1, -147, -1, 360, 32, -337, +-138, 172, -1, -3, 44, -133, 36, 232, +-388, -211, 531, 109, -470, 9, 142, -53, +17, 19, -68, 106, -79, -247, 83, 306, +-64, -171, 15, -49, -233, 137, 374, -45, +-334, 2, 52, -58, 10, 112, -16, -179, +51, 352, -290, -440, 391, 318, -375, -150, +140, 95, -26, -79, 43, 206, -219, -524, +150, 769, -17, -693, -39, 510, -97, -400, +116, 281, -209, -131, 355, 40, -478, 86, +309, -228, -210, 270, 226, -330, -235, 596, +-24, -826, 249, 729, -356, -467, 311, 333, +-349, -284, 347, 248, -358, -205, 291, 56, +-191, 207, -35, -366, 101, 339, -5, -244, +-126, 190, -7, -149, 142, 67, -172, 130, +157, -379, -310, 530, 293, -526, -82, 535, +-125, -609, 96, 580, -51, -321, -28, -6, +103, 139, -179, -29, 144, -30, -172, -104, +123, 232, -16, -166, -42, 137, -146, -252, +267, 294, -241, -129, 136, 10, -105, -60, +-6, 147, 105, -74, -220, -134, 314, 337, +-404, -377, 392, 291, -365, -199, 259, 32, +-101, 214, 84, -292, -331, 130, 386, 34, +-122, -202, -55, 601, -119, -917, 173, 727, +-19, -338, -14, 269, -127, -298, 37, 120, +137, 77, -93, -210, -17, 494, -146, -814, +383, 890, -500, -857, 566, 854, -605, -719, +503, 462, -481, -290, 646, 96, -689, 268, +404, -566, -176, 627, 251, -699, -360, 932, +164, -1046, 90, 886, -129, -601, 81, 340, +-227, -133, 433, 7, -446, 65, 269, -152, +-166, 291, 193, -423, -219, 439, 146, -374, +-8, 396, -169, -498, 309, 455, -325, -262, +153, 174, 84, -134, -221, -77, 184, 286, +-104, -226, 75, 112, -64, -180, 11, 250, +-27, -193, 145, 176, -188, -175, 61, 19, +37, 170, -14, -164, 23, 96, -159, -151, +309, 253, -423, -212, 456, -31, -319, 412, +59, -668, 66, 587, -15, -279, -16, 30, +-65, 105, 123, -107, -144, -52, 120, 348, +-40, -635, -15, 833, -89, -879, 269, 726, +-314, -456, 164, 232, 17, -64, -76, -55, +8, 109, 41, -193, 56, 386, -254, -490, +368, 405, -291, -377, 131, 498, -75, -574, +237, 566, -433, -609, 396, 550, -173, -259, +64, 55, -125, -134, 171, 189, -178, -59, +253, 1, -320, -83, 256, 114, -119, -104, +-3, 137, 140, -96, -311, -44, 449, 159, +-496, -228, 408, 292, -217, -321, 84, 365, +-104, -453, 135, 478, -87, -412, 61, 405, +-55, -424, -32, 298, 101, -126, -14, 91, +-29, -103, -139, 50, 264, -81, -109, 249, +-123, -291, 131, 83, -42, 235, 47, -411, +-119, 322, 167, -36, -227, -143, 210, 64, +0, 71, -253, -68, 319, 42, -241, -104, +183, 119, -144, -44, 86, 57, -94, -132, +122, 93, -77, -60, 39, 272, -149, -475, +206, 331, -29, -14, -217, -161, 306, 277, +-350, -418, 438, 409, -425, -245, 253, 115, +-151, 47, 168, -294, -173, 436, 93, -336, +-37, 141, 14, 10, 61, -81, -184, 44, +180, -9, -35, 136, -84, -235, 0, 93, +116, 76, -50, 18, -100, -224, 95, 248, +-4, -146, -13, 82, -21, -13, -23, -83, +55, 97, -20, -44, -41, 103, 20, -212, +-19, 203, 47, -72, -84, 13, 40, -64, +30, 180, -66, -309, -2, 329, 142, -183, +-293, 57, 302, -88, -218, 115, 187, 98, +-284, -439, 262, 596, -66, -441, -83, 212, +-7, -144, 130, 173, -170, -125, 129, 73, +-65, -40, -53, -67, 107, 124, -58, -4, +-16, -8, 9, -277, -13, 501, -22, -386, +146, 233, -324, -201, 405, 60, -420, 132, +423, -84, -424, -32, 288, -99, -80, 296, +-54, -239, 50, 104, -129, -169, 344, 261, +-482, -177, 379, 109, -278, -201, 308, 215, +-329, -43, 186, -42, -29, -15, -97, -45, +182, 216, -173, -240, 43, 112, 3, -30, +73, 26, -156, -37, 129, 45, -79, -5, +46, -77, -95, 99, 127, -17, -75, -65, +-90, 98, 164, -75, -119, 67, 6, -140, +70, 186, -83, -21, -10, -228, 44, 247, +52, -67, -151, -17, 53, -13, 31, -10, +29, 103, -95, -136, -67, 115, 287, -117, +-375, 143, 309, -132, -264, 51, 307, 87, +-400, -250, 316, 346, -49, -328, -124, 344, +-15, -531, 166, 654, -90, -464, -18, 175, +-115, -95, 225, 145, -125, -120, -47, 53, +115, 16, -187, -125, 232, 152, -134, -51, +-65, -16, 121, -42, -9, 184, -235, -357, +396, 402, -293, -161, 35, -90, -91, -37, +381, 278, -322, -146, -159, -194, 399, 243, +-277, -34, 163, -70, -143, 73, 16, -86, +-26, -42, 222, 261, -205, -204, -114, -90, +181, 147, 25, 41, -89, -10, -36, -202, +-5, 198, 112, -36, -154, 26, 205, -81, +-296, 60, 205, -66, -108, 130, 173, -90, +-265, 9, 163, -31, -100, 84, 171, -32, +-211, -79, 83, 128, 32, -85, -101, 58, +156, -148, -230, 256, 255, -186, -331, -4, +417, 128, -384, -169, 199, 156, -101, -102, +144, 147, -207, -326, 165, 378, -126, -200, +129, 69, -170, -103, 165, 75, -134, 80, +57, -139, -26, 94, 60, -167, -111, 311, +85, -286, -85, 137, 81, -77, -8, 106, +-89, -115, 42, 95, 14, -33, 62, -81, +-158, 74, 108, 104, -94, -195, 197, 63, +-256, 79, 155, -92, -85, 63, 68, 3, +18, -105, -158, 77, 171, 70, -100, -131, +62, 95, -52, -95, -35, 119, 57, -86, +27, 49, -136, 43, 189, -234, -274, 330, +354, -241, -310, 170, 118, -212, 23, 275, +-100, -305, 156, 325, -186, -276, 138, 155, +-146, -46, 192, 2, -156, 10, 55, -36, +-70, 97, 171, -203, -213, 296, 169, -320, +-99, 297, -52, -311, 209, 390, -219, -409, +81, 247, 7, -16, 8, -77, -79, 40, +140, -48, -150, 168, 93, -317, -60, 336, +96, -189, -128, 12, 78, 46, 2, -14, +-71, -10, 84, -9, -43, 90, -34, -146, +43, 47, 38, 146, -165, -197, 187, 101, +-68, -5, -72, -27, 60, 7, 17, 55, +-10, -73, -60, 40, 79, -46, -105, 67, +133, 9, -93, -78, 54, 57, -127, -76, +168, 104, -51, 39, -22, -212, -91, 153, +148, 3, -34, -32, -24, 43, -74, -77, +70, -6, 72, 132, -109, -105, 29, 37, +-66, -85, 185, 90, -170, 79, 33, -202, +36, 118, -8, -26, -14, 66, 32, -121, +-59, 89, 40, -54, -12, 84, 71, -130, +-154, 172, 107, -248, 2, 305, -12, -237, +-30, 111, -24, -93, 91, 122, -2, -9, +-138, -131, 92, 34, 98, 173, -193, -167, +149, 77, -157, -172, 282, 256, -366, -93, +311, -68, -217, 61, 121, -89, -16, 197, +-33, -156, 3, 31, -24, -33, 140, 36, +-151, 76, -18, -128, 126, 78, -80, -96, +44, 198, -103, -210, 112, 122, -51, -29, +46, -68, -58, 170, -23, -217, 134, 141, +-134, 7, 80, -68, -132, -22, 273, 145, +-340, -202, 285, 229, -235, -225, 244, 134, +-266, 21, 262, -112, -218, 103, 94, -100, +30, 155, -25, -88, -73, -125, 62, 161, +54, 113, -101, -259, 68, 35, -34, 180, +-82, -147, 233, 137, -226, -165, 77, 51, +-53, 0, 164, 159, -174, -195, 59, -16, +53, 125, -135, -93, 194, 171, -199, -294, +230, 263, -353, -152, 423, 65, -308, -17, +164, 2, -138, 10, 180, -13, -202, -79, +158, 125, 15, 101, -254, -402, 358, 444, +-306, -333, 272, 269, -275, -174, 181, 25, +-31, 69, -17, -167, -1, 281, -29, -268, +70, 154, -42, -123, 25, 154, -112, -179, +211, 233, -192, -232, 114, 63, -72, 94, +38, -99, 30, 101, -101, -155, 112, 188, +-85, -212, 39, 206, 28, -78, -51, -49, +-3, -51, 69, 192, -48, -118, -5, -41, +8, 51, 18, -14, -24, 45, 7, -6, +-1, -83, 29, 5, -94, 167, 154, -130, +-140, -61, 80, 82, -58, 24, 93, 16, +-130, -141, 147, 95, -103, 42, -24, -80, +145, 81, -126, -135, -26, 154, 115, -96, +-37, 94, -91, -205, 137, 262, -94, -180, +20, 91, 21, -86, 1, 63, -12, 1, +-32, -4, 58, -74, 6, 106, -65, -55, +22, 23, 22, -27, -12, 22, 27, 18, +-60, -61, -5, 68, 98, -35, -49, 44, +-68, -127, 47, 158, 59, -27, -103, -169, +137, 257, -190, -247, 164, 268, -80, -335, +81, 317, -94, -210, -22, 166, 149, -198, +-107, 132, 3, -3, -1, -11, 59, 22, +-99, -190, 119, 290, -119, -131, 107, 29, +-164, -180, 258, 291, -224, -192, 107, 69, +-59, -61, 46, 96, 12, -130, 31, 149, +-188, -164, 228, 187, -108, -162, 50, 58, +-54, 24, -52, -47, 139, 97, -25, -135, +-105, 94, 41, -40, 59, 41, -85, -78, +140, 174, -190, -269, 142, 225, -140, -146, +268, 195, -283, -188, 125, -6, -57, 94, +113, 4, -60, 24, -31, -199, -1, 217, +-15, -80, 148, 12, -121, -15, -59, 19, +58, -28, 58, -21, 22, 163, -140, -236, +22, 202, 88, -205, 26, 225, -72, -159, +-51, 70, 72, -56, 30, 53, -34, -13, +9, 33, -79, -87, 83, 21, 19, 142, +-19, -174, -47, 64, -3, -46, 70, 153, +-43, -137, 65, -1, -143, -1, 108, 124, +28, -107, -80, -58, 90, 139, -133, -98, +130, 63, -89, -30, 140, -45, -192, 87, +88, -46, 71, 7, -115, -15, 102, -18, +-74, 104, 17, -141, 37, 89, -16, -35, +8, 7, -46, 37, 28, -109, 78, 133, +-114, -99, 83, 63, -84, -38, 68, 10, +14, 3, -7, 8, -109, -15, 138, -37, +-17, 91, -25, -48, -42, 3, 39, -107, +12, 220, 22, -127, -44, 12, -33, -131, +121, 281, -102, -207, 73, 58, -65, -58, +64, 42, -55, 73, 26, -77, 46, -64, +-39, 109, -37, 28, -3, -121, 87, 76, +-14, -21, -76, 1, 17, 71, 71, -176, +-21, 167, 15, -58, -120, 17, 61, -15, +113, -17, -96, 43, -46, -13, 102, -3, +-67, 19, 55, -97, -39, 92, 29, 41, +-53, -103, 74, 44, -1, -79, -25, 176, +-33, -132, 34, 67, 20, -161, -8, 201, +1, -42, -27, -69, 57, -23, -14, 127, +-25, -100, -13, 23, 33, 32, 41, -64, +-49, 32, 7, -27, 57, 130, -70, -235, +15, 170, 44, -16, -44, -31, 5, 20, +33, -92, 3, 172, -20, -120, 10, 82, +-89, -149, 120, 135, 11, 36, -55, -82, +8, -111, -29, 178, 176, -22, -190, -69, +60, -8, -14, 32, 38, -13, 69, 61, +-58, -68, -86, -54, 91, 138, 38, -98, +-88, 46, 105, -36, -134, 59, 111, -118, +25, 105, -19, 3, -61, -15, -40, -127, +140, 144, -17, 48, -50, -133, 25, -7, +-42, 71, 98, 30, -37, -105, -73, 125, +54, -191, 41, 206, -4, -79, -20, -12, +-8, -23, -23, 25, 82, 72, -82, -122, +78, 58, -85, 5, 142, 1, -122, -17, +69, 21, -89, 5, 87, -97, -19, 205, +12, -189, -19, 96, 34, -105, -11, 168, +3, -105, -14, -10, -23, -30, 62, 105, +-21, -13, 69, -90, -113, 26, 54, 42, +12, 42, -40, -138, 81, 137, -65, -113, +1, 63, 90, -12, -3, 88, -142, -207, +84, 132, 64, 62, -109, -78, 122, -31, +-101, 1, 135, 95, -146, -52, 118, -74, +-121, 118, 91, -113, 44, 118, -67, -123, +20, 122, 23, -157, 32, 177, -94, -117, +50, 63, -14, -124, 72, 193, -26, -101, +17, -39, -84, 2, 109, 117, -118, -81, +216, -35, -294, 37, 251, -54, -62, 214, +-13, -333, 9, 263, -33, -164, 6, 142, +33, -89, 25, -9, -19, 40, -16, -16, +35, 26, 16, -74, -95, 71, 121, 10, +-119, -73, 153, 34, -110, 1, 115, 76, +-89, -159, -64, 115, 177, -18, -183, -29, +177, 42, -136, -41, 203, 68, -312, -179, +318, 252, -217, -143, 103, -20, -80, 16, +148, 97, -59, -68, -114, -116, 204, 224, +-198, -151, 135, 57, -58, -28, 22, 17, +-11, -24, 117, 36, -118, -49, -25, 35, +87, -13, 7, 3, -76, 35, 34, -118, +92, 125, -104, -68, 63, 103, -31, -210, +22, 193, -81, -61, 136, 11, -77, -72, +77, 57, -96, 57, 73, -56, -82, -67, +91, 104, -25, 5, -66, -130, 126, 145, +-44, -53, 8, -6, -97, -58, 95, 137, +19, -47, -100, -149, 118, 152, 10, 36, +-72, -78, -36, -64, 118, 105, -89, -10, +55, -2, -44, -97, 67, 93, -3, 15, +-22, 4, -70, -126, 77, 127, 30, 4, +-37, -118, -37, 104, 72, -18, 71, 0, +-199, -39, 102, 42, 40, 9, -37, -73, +4, 65, -4, -32, 41, 63, 17, -28, +-69, -128, 1, 149, 50, 41, -47, -169, +51, 38, 23, 136, -15, -4, -31, -252, +-20, 173, 88, 56, -119, -50, 91, -102, +18, 239, -3, -310, -38, 245, -11, -122, +9, 83, 7, -85, -6, 45, 58, 23, +-37, -19, 41, -84, -78, 92, 47, 59, +-16, -100, 9, -66, -22, 127, 73, 88, +2, -265, -51, 120, -15, 88, 17, -2, +14, -194, -46, 110, 108, 182, -85, -302, +62, 174, -17, 44, -61, -230, 2, 152, +124, 102, -114, -64, 30, -210, 88, 220, +-126, 48, 80, -235, -93, 89, 166, 211, +-161, -152, 6, -140, 112, 158, -50, 29, +11, -161, -17, 110, 23, 182, -76, -240, +-36, -60, 102, 126, 143, 50, -189, -43, +36, 14, -114, -57, 149, 2, 42, 110, +-194, -170, 162, 38, 82, 187, -131, -104, +-138, -154, 203, 108, -22, 77, -60, -62, +40, -35, 66, 97, -111, -107, -36, 24, +148, -1, -64, 36, -23, 69, 36, -99, +-29, -84, 17, 79, -31, 52, 92, -29, +-6, 44, -90, -9, -29, -175, 61, 23, +68, 244, -22, -66, -96, -58, 129, -101, +-107, 164, -27, -179, 59, 33, 68, 228, +33, -31, -196, -247, 111, 15, 24, 163, +-82, -77, 51, 66, 83, 45, -79, -144, +-69, -39, 64, 92, 73, 69, -101, 3, +-3, -203, 120, 247, -95, -201, -105, 4, +253, 199, -101, 0, -68, -288, 24, 75, +25, 163, -7, -9, 17, -77, 62, -18, +-63, 93, -122, -254, 129, 205, 81, 192, +-195, -269, 212, -46, -180, 91, 135, 110, +-185, -142, 155, 92, 29, -30, -135, -66, +-7, -29, 250, 259, -284, -119, 65, -171, +-26, 93, 198, 31, -207, -25, 54, 156, +42, -40, -68, -321, -15, 154, 164, 115, +-126, 145, -85, -233, 135, 25, -111, -120, +123, 150, -50, 90, 49, 28, -219, -315, +215, 166, -13, 45, -209, -2, 239, 59, +62, -115, -288, -135, 103, 248, 84, 0, +-135, -165, 79, 167, 49, -134, -64, -7, +17, 58, -92, 126, 26, -217, 43, 56, +-9, 175, -11, -164, 12, -5, -48, -95, +-78, 242, 154, -14, -22, -83, -143, -144, +106, 78, -105, 139, 95, -102, 81, 208, +-221, -347, 84, 24, -36, 173, 16, 119, +95, -86, -90, -196, -116, -117, 148, 375, +-96, 67, 122, -214, -76, -128, -181, 41, +59, 112, 229, 159, -97, -137, -155, -127, +48, -1, -63, 29, 103, 318, -79, -254, +87, -184, -37, 195, -197, 30, 51, 10, +297, 87, -283, -227, -145, -126, 146, 304, +139, 81, -90, -126, -38, -80, -260, -204, +255, 276, -14, 227, -2, -345, -18, 95, +-269, -131, 186, 109, 127, 177, -126, -206, +-95, 114, -76, -225, 111, 105, 87, 203, +-126, -50, -18, -259, -133, 198, 147, -111, +-42, 109, 21, 63, -123, -116, -46, -17, +85, -20, 58, 103, -76, -35, -170, 13, +72, -10, -38, -149, 174, 194, -104, 76, +-220, -204, 47, 7, 183, 5, -127, 129, +7, -34, -166, -8, 91, -70, 34, -128, +-68, 201, 98, 134, -299, -248, 148, 101, +-31, -166, 2, 229, 43, -38, -224, -98, +133, 102, -43, -98, -57, 12, -57, 101, +63, -103, -21, 111, -39, -143, -11, 50, +-152, 80, 20, -201, 151, 332, -33, -305, +-230, 152, 102, -83, -197, 21, 261, 11, +-117, 56, -49, 12, -103, -124, -18, 17, +110, 29, -74, 86, -82, -70, -82, -2, +212, -44, -227, 136, 18, -130, -139, -18, +129, 96, 59, 47, -158, -121, -50, 19, +-83, -20, 1, 78, 220, 18, -221, -99, +-12, 52, -212, -124, 244, 245, -12, -94, +-235, -78, 29, 40, 18, -96, -26, 187, +74, 7, -242, -69, -63, -145, 150, 65, +30, 153, -59, -21, -231, -44, -16, -140, +67, -1, 158, 195, -85, 57, -260, -85, +-189, -275, 329, 145, 152, 53, -316, 345, +-155, -319, 20, -195, 41, -41, 189, 282, +-211, 391, -142, -574, -49, -90, 69, 127, +154, 182, -247, 220, -81, -447, 23, -106, +88, 255, -94, 165, -183, -66, 94, -211, +64, -51, -220, 153, 141, 119, -225, 74, +27, -442, 29, 278, 62, -137, -120, 388, +-247, -251, 99, -305, 179, 400, -184, -194, +-81, 369, -78, -454, 74, 45, -15, 155, +-20, 27, -183, -22, -36, -117, 220, 113, +-181, -170, -97, 316, 29, -197, -183, -112, +261, 102, -146, 107, -111, 44, -77, -260, +29, -37, 73, 356, -69, -215, -174, 106, +22, -198, 53, 4, -109, 214, 135, 69, +-317, -287, 24, -93, 175, 288, -79, -11, +-144, 87, -88, -320, -4, -73, 186, 382, +-208, -108, 66, 180, -253, -529, -19, 130, +336, 333, -274, 58, -102, -182, -51, -401, +-25, 292, 302, 281, -296, -7, -201, -222, +47, -328, 139, 359, 8, 114, -90, 99, +-323, -264, 92, -305, 231, 508, -128, -144, +-120, 175, -179, -275, 110, -213, 151, 545, +-230, -256, -58, 141, -3, -255, -71, -88, +182, 442, -164, -155, -139, -104, -72, -92, +185, 29, 72, 287, -339, -124, 31, -179, +-25, 3, -12, 127, 174, 70, -183, 77, +-265, -304, 150, -37, 64, 291, -4, -40, +-158, 91, -120, -385, 16, 66, 257, 396, +-225, -145, -221, -238, 186, 42, -85, 94, +61, 190, -46, -185, -248, -46, 78, -169, +246, 418, -395, -182, 156, -37, -60, 82, +-239, -339, 419, 535, -309, -279, -38, -3, +-62, 9, 7, -153, 198, 445, -225, -368, +-135, 121, 86, -170, -48, 165, 194, 125, +-305, -261, 19, 170, -47, -134, 24, 67, +157, 59, -230, 63, -168, -195, 136, 10, +64, 26, 11, 207, -182, -16, -184, -466, +262, 367, -14, 88, -107, -173, -137, 18, +90, -7, -18, 197, -103, -464, 99, 399, +-25, 257, -280, -820, 198, 488, 61, 358, +-184, -592, -29, 39, 22, 474, -33, -527, +99, 73, -98, 799, -166, -1224, 12, 451, +253, 614, -245, -859, 35, 607, -98, -308, +-12, -248, 126, 719, -214, -549, 304, 73, +-412, 271, -7, -565, 493, 584, -559, -180, +58, -223, 357, 408, -473, -498, 216, 310, +30, 197, -251, -589, 157, 571, 22, -320, +-82, 109, -129, 49, 156, -232, -160, 341, +133, -319, -33, 204, -262, -34, 391, -115, +-473, 191, 348, -336, -29, 669, -466, -861, +642, 480, -538, 287, 233, -851, 128, 1028, +-692, -943, 932, 532, -632, 142, -20, -683, +483, 954, -759, -1020, 543, 693, -56, 76, +-196, -651, -46, 657, 79, -614, 146, 726, +-313, -470, 296, -30, -438, 195, 333, -225, +37, 423, -241, -393, 126, 137, -347, -228, +625, 434, -441, -89, -78, -390, 275, 368, +-317, -103, 200, -208, 85, 562, -283, -474, +105, -6, -25, 222, -58, -499, 350, 1111, +-437, -982, -100, -48, 415, 484, -68, -81, +-446, 9, 411, -446, 126, 964, -742, -1460, +580, 1269, 274, 91, -697, -1304, -96, 993, +1164, 60, -1351, -368, 387, -175, 936, 799, +-1727, -1033, 1347, 738, -207, 15, -690, -677, +712, 625, -284, -162, -190, 37, 356, -189, +-107, 320, -354, -595, 516, 789, -416, -349, +145, -428, 237, 856, -588, -944, 496, 862, +-82, -551, -248, 273, 289, -261, -252, 179, +18, 33, 427, -78, -751, 249, 634, -854, +-357, 1298, 48, -1088, 295, 669, -592, -479, +644, 233, -524, 227, 309, -501, -115, 350, +-8, -154, 51, 112, -117, -113, 92, 114, +118, -38, -344, -144, 214, 29, 57, 532, +-134, -1026, 131, 1148, -339, -976, 490, 350, +-404, 605, 204, -1199, -72, 1297, -105, -1298, +400, 938, -752, 26, 811, -879, -472, 1111, +-75, -963, 483, 552, -693, 95, 623, -602, +-344, 704, 26, -443, 124, 30, -285, 311, +396, -448, -272, 464, -100, -519, 486, 571, +-804, -334, 776, -217, -298, 623, -334, -590, +635, 423, -644, -382, 516, 213, -288, 154, +46, -263, 19, -86, -133, 547, 346, -948, +-359, 1279, 145, -1304, -40, 928, -144, -407, +460, -36, -609, 309, 575, -401, -506, 532, +116, -956, 471, 1338, -766, -1064, 677, 346, +-616, 123, 664, -221, -701, 165, 531, -120, +71, 369, -974, -860, 1346, 1064, -888, -903, +361, 700, -268, -290, 106, -376, 255, 800, +-471, -1038, 599, 1472, -723, -1517, 495, 754, +36, -29, -496, -244, 699, 531, -502, -635, +-61, 398, 456, -570, -368, 1047, 157, -850, +-86, 135, -46, 408, 230, -775, -262, 818, +257, -254, -261, -269, 32, 124, 370, 143, +-507, -37, 328, -157, -98, 390, -36, -820, +86, 1100, -9, -1027, -19, 904, -155, -790, +368, 445, -345, 66, 284, -377, -332, 390, +273, -281, -8, 74, -80, 161, 51, -149, +-174, -158, 406, 435, -415, -568, 336, 609, +-400, -528, 570, 493, -561, -627, 428, 516, +-166, 187, -240, -1064, 668, 1601, -779, -1741, +761, 1302, -675, -126, 375, -1174, 167, 1854, +-502, -1955, 673, 1631, -768, -764, 660, -262, +-161, 733, -321, -616, 621, 353, -751, -56, +692, -99, -222, -169, -334, 528, 742, -548, +-815, 561, 583, -743, 8, 653, -614, -327, +1131, 167, -1350, 102, 1195, -783, -540, 1361, +-141, -1344, 581, 903, -643, -257, 481, -506, +11, 1062, -394, -1007, 371, 401, 18, 344, +-362, -814, 840, 772, -1128, -236, 984, -522, +-555, 1201, 371, -1531, -158, 1421, -46, -1061, +314, 617, -561, -77, 889, -556, -839, 1053, +502, -1197, -54, 1047, -194, -753, 588, 334, +-880, 127, 884, -490, -534, 655, 347, -550, +-86, 185, -167, 308, 409, -734, -541, 871, +848, -747, -729, 604, 275, -577, 180, 545, +-332, -415, 636, 87, -720, 618, 461, -1404, +52, 1567, -376, -1046, 903, 442, -1287, 150, +1189, -927, -452, 1384, -145, -1066, 542, 389, +-508, 250, 237, -767, 153, 781, -80, -225, +41, -339, -90, 699, 109, -1062, 306, 1106, +-481, -590, 434, 7, -121, 401, -234, -933, +804, 1363, -900, -1327, 653, 1095, -236, -765, +-13, 57, 456, 724, -542, -1110, 312, 1301, +41, -1472, 26, 1336, -114, -932, 531, 555, +-961, -85, 1059, -489, -460, 712, -33, -602, +556, 603, -861, -514, 807, 78, -297, 165, +171, 52, 105, -132, -690, -161, 1345, 412, +-1272, -515, 821, 574, 149, -386, -1105, -31, +1690, 323, -1439, -495, 1093, 721, -623, -763, +163, 510, 459, -275, -651, 35, 754, 469, +-619, -980, 341, 1117, 298, -965, -541, 632, +636, -89, -561, -350, 403, 392, 294, -286, +-801, 229, 1028, 2, -809, -245, 512, 115, +190, 170, -692, -357, 945, 711, -733, -1165, +478, 1262, 124, -1023, -520, 660, 721, -59, +-579, -661, 576, 983, -183, -851, -297, 589, +713, -268, -664, -59, 781, 99, -660, 155, +331, -408, 122, 654, -121, -874, 382, 755, +-575, -314, 550, -103, -203, 434, 192, -752, +64, 806, -227, -548, 274, 439, -256, -611, +705, 624, -657, -381, 358, 113, -146, 229, +167, -747, 379, 1167, -795, -1264, 991, 1168, +-940, -916, 990, 286, -518, 680, 1, -1626, +606, 2170, -1008, -1989, 1257, 1042, -717, 125, +66, -970, 556, 1388, -951, -1300, 1360, 656, +-956, 70, 134, -474, 794, 762, -1367, -969, +1835, 673, -1469, 16, 707, -478, 100, 595, +-661, -592, 1474, 491, -1715, -366, 1418, 280, +-710, 6, -31, -497, 1160, 729, -1680, -451, +1444, -197, -612, 981, -141, -1576, 963, 1613, +-1073, -1018, 702, 134, -215, 547, 233, -729, +-285, 516, 603, -204, -663, -26, 323, 41, +536, 246, -976, -489, 1072, 384, -715, -262, +232, 427, 563, -642, -920, 792, 924, -869, +-571, 513, 313, 278, 329, -904, -963, 1119, +1464, -1089, -1361, 782, 1022, -373, -260, 233, +-407, -118, 1020, -281, -1202, 486, 1177, -276, +-661, 135, 260, -43, 88, -436, -151, 763, +259, -288, -128, -477, 127, 900, -15, -1088, +31, 998, 124, -346, -155, -466, 217, 740, +124, -511, -415, 129, 653, 321, -519, -586, +153, 325, 715, 265, -1176, -791, 990, 1241, +-290, -1523, -203, 1432, 662, -1062, -649, 616, +406, -82, 9, -466, -115, 733, 206, -775, +55, 866, -403, -857, 750, 626, -548, -527, +144, 602, 492, -405, -816, 16, 783, 161, +-161, -410, -376, 982, 776, -1347, -721, 1232, +509, -1019, -68, 588, -122, 350, 339, -1175, +-483, 1330, 667, -1134, -463, 721, 322, 76, +-150, -838, 86, 1024, 62, -878, 186, 616, +-319, -103, 215, -426, 152, 518, -314, -365, +699, 354, -945, -344, 878, 102, -369, 321, +-14, -950, 467, 1749, -633, -2241, 588, 1993, +-403, -1189, 555, 134, -496, 1101, 282, -2085, +-70, 2207, 164, -1660, 47, 1005, -235, -254, +226, -611, 39, 1164, -44, -1304, 127, 1183, +-81, -572, -61, -383, 173, 922, 242, -788, +-524, 390, 535, 120, -239, -642, -106, 782, +688, -585, -849, 397, 694, -159, -427, -107, +258, 63, 121, 94, -113, 61, -26, -169, +-201, -184, 910, 607, -1186, -670, 1071, 448, +-460, 56, -483, -849, 1469, 1469, -1615, -1536, +1239, 1213, -573, -754, -139, 273, 831, 19, +-887, -45, 704, 121, -468, -423, 157, 756, +423, -986, -511, 1193, 194, -1308, 240, 1164, +-569, -707, 979, 114, -866, 439, 389, -910, +81, 1348, -364, -1682, 945, 1780, -1294, -1445, +1143, 460, -503, 973, -212, -2098, 1104, 2339, +-1541, -1756, 1333, 557, -535, 941, -437, -2003, +1564, 2083, -2074, -1265, 1737, -125, -756, 1525, +-267, -2157, 1367, 1889, -2022, -1237, 2023, 359, +-1348, 691, 442, -1349, 791, 1422, -1793, -1389, +2043, 1193, -1239, -415, 54, -543, 1207, 1048, +-1962, -1168, 1895, 898, -880, -64, -248, -691, +1098, 537, -1316, 188, 1063, -720, -458, 928, +46, -891, 277, 541, -404, 24, 317, -582, +72, 948, -130, -926, -34, 575, 169, -359, +-82, 344, 188, -41, -169, -626, -35, 1070, +346, -1008, -378, 663, 363, -180, -167, -459, +-52, 1113, 210, -1619, 26, 1868, -298, -1631, +472, 707, -362, 636, 199, -1769, 72, 2322, +-212, -2319, 434, 1774, -593, -631, 532, -814, +51, 1881, -581, -2046, 730, 1289, -421, 39, +27, -1281, 504, 1819, -847, -1494, 946, 559, +-724, 615, 438, -1569, 86, 1926, -559, -1621, +898, 785, -948, 271, 866, -1046, -372, 1254, +-215, -1018, 634, 458, -653, 308, 518, -804, +-33, 651, -475, -55, 706, -539, -479, 777, +201, -458, 364, -139, -1047, 510, 1397, -785, +-849, 1175, -95, -1197, 1140, 547, -1848, 236, +1849, -781, -884, 1266, -260, -1453, 1078, 1098, +-1270, -550, 915, 37, -13, 475, -631, -592, +738, 83, -441, 323, 188, 3, 184, -704, +-440, 1241, 577, -1340, -530, 697, 473, 487, +-115, -1321, -264, 1215, 460, -366, -443, -744, +551, 1508, -415, -1244, -25, 17, 577, 1109, +-776, -1223, 705, 455, -284, 415, -196, -660, +569, 149, -548, 514, 383, -608, 26, 28, +-469, 790, 753, -1364, -554, 1434, 249, -841, +34, -329, -17, 1518, -222, -2055, 478, 1784, +-127, -1051, -496, 202, 840, 438, -669, -667, +391, 695, -47, -784, -137, 774, 76, -532, +78, 282, 87, -68, -209, -275, 128, 635, +-81, -844, 363, 1023, -539, -1022, 627, 489, +-546, 283, 271, -711, 277, 866, -488, -1013, +395, 964, -205, -634, 108, 318, 126, -103, +-227, 32, 247, -266, -335, 527, 458, -204, +-135, -540, -501, 1006, 1067, -1007, -1302, 710, +1213, -120, -642, -553, -156, 709, 886, -110, +-1388, -942, 1693, 1844, -1409, -1775, 509, 298, +704, 1692, -1616, -2523, 1926, 1573, -1248, 209, +-56, -1388, 1334, 1213, -1826, 11, 1555, -1171, +-605, 1253, -529, -317, 1433, -676, -1731, 995, +1485, -597, -777, -105, -30, 520, 551, -288, +-679, -226, 709, 344, -701, 39, 535, -461, +-332, 543, 315, -105, -259, -651, -120, 922, +859, -134, -1472, -1086, 1342, 1613, 0, -1078, +-1785, -28, 2592, 914, -1478, -899, -727, 42, +2536, 756, -2730, -654, 1385, -307, 546, 1364, +-1636, -1641, 1378, 768, -343, 728, -562, -1723, +776, 1554, -86, -385, -1093, -1181, 1824, 2324, +-1484, -2251, 247, 838, 1164, 1095, -1960, -2378, +1748, 2192, -761, -572, -229, -1274, 692, 1666, +-565, -258, 206, -1415, 203, 1637, -317, -344, +142, -1110, 142, 1370, -363, -423, 590, -429, +-478, 291, -214, 154, 1121, 155, -1652, -1038, +1504, 1473, -677, -878, -425, -498, 1109, 1837, +-1240, -2306, 1174, 1688, -1069, -364, 702, -1198, +-16, 2312, -657, -2228, 846, 984, -213, 556, +-917, -1589, 1464, 1740, -468, -978, -1393, -217, +2492, 1019, -1731, -835, -505, -323, 2600, 1719, +-2723, -2063, 626, 700, 1880, 1432, -2733, -2513, +1231, 1688, 1320, 199, -2842, -1524, 2094, 1311, +114, 53, -1938, -1294, 1863, 1295, -187, -85, +-1506, -1137, 1823, 1233, -678, -219, -943, -1178, +1987, 2202, -2070, -2064, 1519, 425, -492, 1803, +-754, -2983, 1780, 2217, -1943, -22, 1039, -1945, +432, 2058, -1420, -472, 1321, -921, -451, 882, +-704, -78, 1523, -273, -1678, -196, 947, 773, +261, -408, -1394, -871, 1561, 1634, -915, -820, +60, -750, 379, 1611, -380, -1218, 147, -76, +34, 1445, -230, -1888, 675, 1055, -827, 404, +72, -1655, 1427, 2162, -2221, -1506, 1207, -216, +1279, 1904, -3166, -2214, 2522, 733, 606, 1630, +-3731, -3004, 3792, 1859, -604, 1225, -3142, -3476, +4195, 2727, -2147, 206, -951, -2632, 2227, 2687, +-1449, -697, 379, -1349, -731, 1542, 1855, -4, +-2004, -1218, 116, 692, 2754, 766, -4231, -1434, +2987, 623, 206, 907, -2796, -1785, 2910, 1197, +-592, 412, -1938, -1835, 2663, 2101, -1092, -1073, +-1240, -366, 2336, 762, -1434, 418, -620, -1749, +1913, 1213, -1343, 1148, -601, -2959, 1723, 2314, +-1156, -6, -454, -1620, 1370, 1378, -1227, -118, +528, -574, -176, 236, -49, -38, 680, 875, +-1570, -1678, 1764, 830, -656, 1386, -874, -2926, +1423, 2151, -359, 660, -1059, -3207, 1468, 3031, +-343, -127, -1310, -3025, 2171, 4055, -1569, -2321, +21, -1152, 1398, 4075, -2049, -4195, 1458, 1377, +28, 2283, -1630, -4188, 1777, 3074, -458, -59, +-1054, -1984, 992, 1440, 130, 349, -710, -1031, +-333, 7, 1683, 1363, -1303, -1332, -1026, -388, +3000, 2157, -2337, -1979, -447, -156, 2818, 2250, +-2533, -2321, 121, 313, 2046, 1950, -1880, -2461, +-183, 938, 1961, 1204, -1818, -2284, 74, 1733, +1490, -90, -1817, -1467, 793, 1998, 577, -1061, +-1937, -801, 2634, 2097, -2117, -1262, -177, -1317, +2636, 3057, -3244, -1731, 1347, -1534, 1029, 3353, +-1875, -1866, 916, -1077, 232, 2382, -298, -1040, +-281, -961, 235, 1248, 754, 339, -1564, -1664, +1138, 1131, 458, 693, -2128, -1912, 2555, 1510, +-1306, -12, -959, -1046, 2641, 852, -2789, -1, +1131, -284, 1125, -210, -2657, 1008, 2118, -1581, +-116, 1578, -1775, -486, 1555, -1523, 278, 3316, +-1794, -3149, 1098, 732, 875, 2047, -1942, -2615, +874, 845, 820, 1111, -1259, -1232, 240, -85, +516, 941, 72, -55, -1182, -1349, 836, 1165, +1128, 1012, -2845, -2826, 2094, 1950, 707, 1339, +-3300, -3890, 3292, 3095, -1175, 371, -1132, -3072, +1569, 2819, -635, -406, -384, -1456, 169, 1260, +413, 210, -693, -893, 480, 418, -655, 114, +812, -91, -477, 400, -621, -1256, 1292, 1719, +-927, -671, -256, -1186, 735, 1919, -33, -465, +-1171, -1295, 1131, 1136, 88, 502, -1389, -977, +1283, -216, -360, 1026, -424, 322, -1, -2399, +625, 2496, -653, 205, -331, -2990, 987, 3084, +-1183, -667, 913, -1299, -885, 1162, 454, 85, +429, -388, -1647, -365, 1668, 1059, -660, -881, +-478, 581, 386, -551, 33, 305, 109, 911, +-1248, -2284, 1700, 2402, -792, -614, -1193, -1663, +2097, 2770, -1478, -2043, -106, 428, 655, 1143, +-437, -1842, 146, 1596, -946, -618, 1531, -334, +-962, 984, -1371, -1035, 3203, 586, -2946, 267, +79, -902, 2714, 1161, -3553, -872, 1740, 335, +402, 307, -1620, -761, 1449, 1218, -1065, -1235, +176, 426, 570, 969, -993, -1410, 169, 440, +786, 1004, -1286, -1307, 245, 496, 968, 470, +-1609, -325, 799, -515, -36, 850, -588, 13, +764, -685, -1440, 256, 1612, 644, -1196, -320, +-467, -1157, 1940, 2318, -2377, -1245, 643, -1672, +1331, 3874, -1875, -2549, -61, -1334, 1727, 4106, +-1287, -2833, -1259, -860, 2121, 3064, -312, -1420, +-2510, -1628, 2547, 2488, -459, -262, -1659, -2108, +1428, 2443, -660, -1049, 404, 81, -1051, -54, +387, 23, 964, 1095, -1903, -2031, 638, 1309, +931, 800, -1430, -1887, 28, 1041, 764, 625, +-181, -937, -1502, -252, 1524, 1406, 160, -652, +-2369, -1211, 2147, 2209, -95, -1109, -2083, -724, +1727, 1536, 29, -355, -1744, -1370, 1431, 1743, +-359, -226, -741, -1058, 580, 871, -573, -31, +593, 261, -739, -914, -463, 697, 1457, 450, +-1320, -584, -757, -755, 2101, 1882, -1616, -485, +-803, -2299, 2079, 3279, -1527, -931, -300, -1724, +827, 1722, -534, 359, 26, -1052, -477, -436, +397, 1878, 289, -934, -1375, -980, 700, 1202, +890, 887, -1924, -2345, 461, 1214, 1127, 1281, +-1117, -2079, -944, 1026, 1771, 82, -754, -136, +-1307, 289, 1628, -687, -905, 414, -65, 959, +-30, -1545, -249, 299, 608, 1670, -869, -1903, +-126, 345, 772, 1137, -430, -724, -1100, -486, +1410, 673, -254, 665, -1606, -1636, 1660, 1038, +-248, 795, -1640, -2037, 1741, 1799, -473, -164, +-1537, -1459, 2079, 2029, -1097, -853, -1153, -1142, +1979, 2299, -884, -1118, -1447, -1117, 1889, 2080, +-491, -823, -1520, -611, 1702, 704, -942, 78, +79, 51, -141, -820, -292, 736, 1040, 891, +-1574, -1982, 454, 893, 969, 1358, -1543, -1664, +283, -415, 1148, 2325, -1641, -1302, 30, -1642, +1884, 3413, -2334, -1882, 225, -1242, 1641, 2714, +-1367, -902, -1017, -1733, 1931, 1994, -268, 582, +-2461, -2765, 2406, 2113, 84, 620, -2265, -2195, +1279, 1203, 748, 992, -1320, -1674, -278, 415, +1154, 1226, -418, -1536, -916, 856, 673, 39, +93, -767, -102, 1545, -941, -1641, 827, 427, +598, 1695, -1953, -2576, 1053, 978, 931, 1892, +-2029, -2885, 725, 1005, 1013, 1723, -1414, -2342, +-174, 702, 1344, 1116, -909, -1059, -825, -164, +1303, 565, -295, 640, -1006, -1525, 661, 684, +323, 901, -814, -1139, 287, 401, -223, -288, +486, 951, -262, -525, -1172, -1194, 1771, 2130, +-430, -632, -1860, -1500, 2132, 1715, -309, 75, +-1825, -1381, 1930, 988, -386, 219, -1499, -786, +1702, 634, -414, -100, -1155, -382, 956, 614, +450, -366, -1315, 180, -74, -440, 1757, 724, +-1312, 84, -1283, -1498, 2126, 1585, 290, 540, +-3291, -2446, 2684, 1532, 663, 1459, -2922, -3102, +1724, 1891, 464, 693, -1059, -2244, -128, 2042, +738, -775, -263, -323, -474, 812, 356, -751, +-142, 295, 94, 472, -68, -741, -686, -215, +1352, 1831, -1171, -2147, -290, 332, 1582, 1902, +-1638, -1950, 190, 33, 1060, 1245, -1116, -540, +-2, -575, 790, 629, -692, -1, -263, -326, +865, 441, -570, -502, -598, 145, 1245, 793, +-802, -1274, -427, 444, 1020, 900, -764, -1075, +154, 16, -32, 765, -135, -485, 426, 90, +-386, -161, -803, -69, 1929, 985, -1468, -1059, +-895, -788, 2750, 2696, -2227, -1700, -288, -1678, +1839, 3375, -860, -1033, -1402, -2396, 1667, 2280, +645, 1422, -2674, -3731, 1259, 1227, 1948, 3120, +-2817, -3793, -49, 287, 2846, 2509, -2229, -1456, +-730, -890, 1964, 979, -589, 609, -873, -1082, +323, 70, 616, 563, -249, -108, -645, -175, +49, -517, 1276, 966, -1222, 79, -559, -1449, +1475, 1011, -244, 749, -1366, -1227, 763, -285, +1256, 1632, -2088, -1158, 693, -310, 1078, 1108, +-1607, -921, 800, 458, 261, -113, -882, -243, +557, 364, 265, 5, -544, -256, -358, -299, +1027, 910, -115, -450, -1573, -572, 1682, 731, +-95, -88, -1049, -197, 487, 58, 71, -562, +790, 1453, -1640, -1193, 320, -488, 1945, 1794, +-2200, -1377, 21, -171, 1814, 1109, -1397, -510, +-265, -732, 913, 741, -196, 625, -378, -1384, +-223, 304, 992, 1172, -760, -1279, -133, 211, +618, 535, -513, -457, 259, 204, -101, -333, +-4, 356, 2, 90, 100, -394, -70, -13, +-276, 334, 611, 81, -364, -436, -329, -110, +767, 641, -683, -225, 496, -357, -348, 41, +-34, 426, 641, 48, -776, -1004, 231, 982, +295, 26, 24, -613, -772, -18, 877, 557, +140, 286, -1306, -1505, 1304, 1043, 103, 775, +-1416, -1785, 1302, 994, 39, 383, -1034, -946, +754, 283, 326, 781, -675, -976, -135, -210, +972, 1673, -662, -1876, -59, 433, 390, 1379, +-696, -2179, 1515, 1550, -1407, -96, -569, -1483, +2755, 2143, -2298, -1118, -339, -785, 2056, 1400, +-1103, -402, -392, -192, 297, -679, 618, 1073, +-112, 392, -1310, -1847, 1497, 990, 81, 824, +-1202, -922, 779, -418, 54, 681, 83, 448, +-283, -1103, -253, 380, 961, 529, -640, -776, +-26, 608, 61, -183, 344, -896, 315, 1700, +-1434, -672, 1142, -1493, 730, 1805, -1298, 248, +-142, -1659, 1031, 458, 468, 1131, -1645, -665, +245, -960, 1889, 1054, -1146, 550, -1457, -1546, +1970, 370, 845, 1495, -2947, -1787, 1468, 91, +1626, 1798, -2216, -2199, 275, 751, 1453, 1219, +-980, -1956, -471, 592, 1267, 1340, -340, -1519, +-1267, -504, 1992, 2148, -652, -1283, -1337, -1163, +2246, 2223, -1257, -962, -235, -880, 1036, 1089, +-505, 91, -109, -922, -75, 314, 880, 735, +-647, -990, -419, 117, 1129, 867, -584, -866, +-161, -405, 665, 1331, -669, -589, 512, -975, +59, 1077, -488, 269, 688, -1182, -282, 388, +-99, 984, 273, -1351, 45, 177, -92, 1075, +-100, -928, 506, -388, -257, 916, -433, -271, +1103, -362, -462, 289, -815, -486, 1433, 877, +-390, -621, -605, -316, 502, 684, 361, -396, +-197, 26, -519, -167, 783, 517, 246, -608, +-1234, -224, 1281, 1050, 109, -554, -1242, -959, +1063, 977, 485, 767, -1077, -1796, 118, 219, +1369, 1814, -1042, -1730, -425, -250, 1280, 1378, +-91, -828, -1088, -100, 766, -57, 900, 553, +-1554, -434, 1092, -405, 103, 799, -918, -407, +1278, -388, -410, 443, -336, 235, 217, -876, +618, 351, -279, 699, -366, -966, 387, -146, +387, 864, -100, -84, -460, -1145, 350, 563, +783, 1018, -686, -1259, -527, -345, 1474, 1109, +-215, -201, -1153, -674, 807, 23, 1167, 671, +-1511, -431, 242, -303, 948, 631, -219, -840, +-478, 441, 346, 425, 574, -913, -460, 275, +101, 78, 4, 220, 775, -196, -607, -692, +-260, 657, 1101, 533, -353, -1193, -462, -123, +845, 1701, -195, -1640, -307, -315, 901, 1819, +-434, -1428, -296, -208, 862, 595, 141, 280, +-1117, -717, 1230, -347, 438, 1195, -1558, -947, +1105, 65, 1050, 320, -1623, -524, 281, 402, +1651, 14, -1295, -599, 115, 211, 768, 615, +-342, -685, 287, -401, -197, 686, 480, 158, +38, -691, -382, -301, 577, 931, 417, -92, +-665, -1130, 32, 556, 1184, 887, -495, -1231, +-715, -188, 1309, 1112, -115, -532, -558, -688, +745, 748, -233, -139, 320, -355, 193, 221, +-422, -182, 484, 125, 536, -176, -677, 36, +208, -59, 819, -140, -469, 342, 4, -665, +389, 577, 387, -152, -621, -801, 538, 1071, +568, -157, -941, -1004, 833, 280, 376, 1123, +-760, -923, 601, -882, 564, 1328, -770, -137, +523, -995, 380, 524, -88, 575, -241, -1136, +517, 52, 317, 1260, -480, -972, 548, -912, +-80, 1306, 300, 217, 13, -1284, -190, -13, +997, 1396, -798, -938, 82, -885, 1158, 1465, +-576, -425, -367, -928, 742, 681, 441, 434, +-507, -954, 120, 44, 428, 706, -3, -625, +280, 52, -160, -38, 226, -63, 97, 287, +197, -416, 189, -142, 5, 566, -174, -593, +367, -176, 869, 1029, -1228, -1264, 368, -81, +1455, 1547, -1336, -1380, 153, -602, 1294, 1608, +-922, -691, 90, -793, 964, 804, -737, -47, +294, -562, 611, 380, -347, 44, -188, -537, +864, 324, -107, 31, -407, -94, 541, -64, +183, -711, 90, 1354, -302, -602, 341, -1281, +585, 1891, -467, -956, -311, -285, 1261, 432, +-268, -199, -948, 144, 1202, -522, 280, 416, +-681, 34, 81, -405, 845, -78, -253, 534, +-267, -391, 459, -429, 304, 679, -401, -206, +248, -617, 400, 646, -153, -123, 17, -388, +121, 118, 446, 135, -443, -125, 493, 4, +19, -358, -294, 250, 688, 374, -121, -834, +-158, 191, 204, 495, 242, -609, 108, 178, +-146, 6, 133, -185, 65, 164, 483, -216, +-402, 261, 51, -362, 396, -166, 111, 802, +-220, -856, 24, -45, 620, 667, -424, -468, +-7, -340, 694, 417, -369, 312, -284, -1006, +867, 346, -127, 815, -585, -1064, 676, -50, +265, 807, -521, -414, 221, -519, 434, 464, +-176, 315, -260, -788, 694, 167, -216, 407, +-282, -247, 621, -264, -170, -78, 110, 625, +-287, -344, 440, -814, 454, 1136, -927, -170, +360, -1059, 867, 966, -655, 35, -250, -718, +722, 81, -43, 838, -309, -806, 427, -146, +-223, 272, 174, 200, 253, 233, -357, -1411, +364, 814, 0, 1140, -132, -1550, 268, -327, +72, 1373, -166, -381, -21, -746, 686, 397, +-885, 172, 663, -111, 275, -78, -979, -292, +1062, 437, -272, -62, -145, -341, 290, -20, +-255, 531, 299, -399, 228, -444, -455, 696, +160, -51, 422, -460, -242, -112, -119, 551, +389, 139, -207, -1217, 60, 1153, 227, -92, +-220, -1001, 161, 1167, 32, -516, 68, -75, +-11, -217, -85, 405, 346, 247, -222, -779, +-7, 243, 220, -4, 142, 606, -490, -578, +431, -674, 289, 1148, -531, -235, 58, -532, +411, 191, 362, 339, -1164, -443, 482, -123, +1285, 951, -1460, -898, -159, -412, 1406, 997, +-645, 59, -592, -869, 875, 94, -9, 637, +-897, -392, 1128, 30, -68, 219, -1256, -932, +1474, 1095, -255, 131, -698, -1406, 666, 1074, +-105, 92, -118, -595, 197, 232, -7, 92, +-293, -11, 475, -247, -117, 329, -360, -359, +734, 436, -611, -368, -67, -129, 971, 549, +-953, -322, 91, -198, 545, 126, -346, 336, +141, -436, -97, 161, 57, -50, -182, -32, +643, 218, -405, -184, -566, -113, 903, 118, +54, 113, -675, -93, 40, -152, 748, 188, +-377, -26, -446, -99, 519, 103, 124, -172, +-276, 438, -233, -507, 241, -210, 774, 1075, +-1236, -673, -24, -632, 1501, 920, -1079, -63, +-563, -172, 1185, -398, -302, 225, -581, 645, +417, -632, 232, -288, -263, 702, -384, -303, +601, -89, 157, 127, -813, -97, 410, 193, +161, -357, 144, 351, -571, 41, -81, -603, +1119, 799, -1089, -402, 46, -245, 690, 556, +-686, -405, 440, 219, -310, -191, -1, 165, +296, -75, -233, -94, -10, 463, -326, -673, +896, 239, -656, 374, -592, -424, 1294, 226, +-601, -263, -553, 191, 656, 182, -110, -299, +-106, 71, -39, 33, -276, -27, 533, 150, +-34, -46, -744, -380, 439, 433, 389, 106, +-438, -318, -356, -66, 451, 134, 185, 323, +-593, -208, 192, -456, 189, 378, -295, 441, +116, -548, -16, -203, -119, 585, 109, -212, +-258, -138, 245, 179, 53, -293, -539, 534, +331, -405, 201, -187, -383, 540, -55, -124, +141, -427, 26, 330, 10, 79, -461, -105, +385, -39, -30, -29, -156, 233, -49, -315, +-210, 177, 587, 241, -607, -399, -61, -179, +568, 731, -652, -266, 102, -473, 352, 418, +-491, -132, 124, 389, 117, -480, -402, 124, +368, -65, -24, 138, -498, 459, 78, -900, +628, 311, -595, 237, -302, 180, 318, -409, +285, -160, -354, 620, -605, -576, 894, 483, +-214, 9, -663, -798, 460, 716, 49, 287, +-200, -422, -217, -402, 57, 394, 355, 623, +-480, -859, -82, 263, 331, -3, -375, -164, +195, 778, -105, -622, -282, -425, 335, 613, +-159, 305, -324, -457, 343, -207, -45, 306, +-342, 167, -168, -183, 555, -93, 6, 263, +-1043, -166, 594, -152, 365, 260, -384, 349, +-415, -652, 108, -143, 682, 872, -905, -224, +153, -701, 377, 607, -543, 211, 54, -650, +223, 546, -30, -152, -571, -67, 278, 138, +315, -239, -413, 404, -252, -152, 237, -293, +172, 414, -299, -109, -244, -55, 115, -19, +368, 306, -409, -395, -458, -69, 616, 877, +-16, -832, -435, -23, -214, 394, 532, 176, +1, -276, -865, -405, 595, 708, 133, -77, +-526, -327, 114, 228, -64, -210, 142, 341, +25, 89, -571, -407, 136, 48, 631, 115, +-688, 780, -224, -1051, 366, -171, 43, 1092, +-176, -186, -475, -730, 458, 221, 317, 889, +-1144, -1113, 558, 441, 560, 713, -1002, -1227, +195, 698, 113, 201, 201, -463, -349, 494, +-371, -347, 503, 15, -60, 205, -307, 51, +-195, 91, 440, -585, -179, 707, -440, -163, +248, -316, 279, 697, -530, -633, -121, 82, +418, 450, -201, -109, -226, -306, 6, 165, +14, 300, 136, -222, -382, -66, 10, 237, +288, -85, -341, 63, -138, -105, 138, 166, +100, 177, -244, -512, -299, 469, 414, 180, +-149, -567, -256, 358, 89, 201, -67, -106, +31, -280, -258, 141, 252, 647, -199, -645, +-242, -70, 303, 437, -263, -73, 9, 120, +82, -334, -340, 301, -44, -109, 431, 147, +-298, 217, -448, -441, 251, 88, 265, 325, +-173, 200, -748, -753, 679, 606, 210, 300, +-1029, -973, 526, 908, 159, 42, -326, -553, +-225, 357, -51, -70, 626, 250, -583, 24, +-496, -473, 691, 484, -99, 10, -351, 50, +-154, -290, 77, 47, 515, 790, -847, -830, +-119, -1, 899, 673, -807, -225, -182, -184, +465, 144, -252, 74, -122, -19, -164, 115, +159, 99, 80, -223, -499, -87, 109, 502, +266, 8, -349, -340, -132, -92, 44, 448, +131, 233, -303, -555, 40, 107, -91, 413, +-157, -163, 290, -213, -273, 587, -288, -504, +191, 95, 103, 332, -232, 1, -231, -273, +16, -38, 360, 648, -472, -292, -265, -532, +604, 784, -604, 157, 136, -758, -6, 242, +-211, 590, 48, -112, -34, -671, -29, 555, +-392, 269, 361, -415, -67, 359, -441, -384, +211, 265, 54, 457, -413, -848, 346, 698, +-299, -66, -243, -277, 476, 378, -531, -199, +135, 247, -23, -254, -304, 244, 379, 130, +-457, -388, 4, 302, 286, 276, -533, -287, +125, -96, 139, 213, -271, 241, -112, -177, +82, -77, -30, 158, -171, -98, -36, 349, +-43, -151, -15, -166, -64, 248, -217, -24, +197, 100, -208, -70, -30, 199, -113, -314, +-35, 164, 193, 511, -496, -499, 143, -84, +211, 279, -557, 389, 314, -508, -105, -56, +-254, 552, 173, -239, -292, -50, 296, 125, +-368, 89, -78, -59, 137, -98, -36, 352, +-129, 12, -319, -478, 326, 325, -28, 587, +-332, -794, -17, 121, 95, 567, 18, -309, +-288, -95, -57, 164, 272, 167, -395, -176, +45, 54, 66, 177, -192, -203, 43, 283, +-252, -183, 247, 80, -46, 278, -568, -495, +434, 448, 108, 55, -597, -331, 266, 400, +-49, -225, -140, -6, 153, 430, -304, -457, +-22, 271, 155, -47, -159, 1, -129, 218, +77, -261, -107, 375, -104, -492, 70, 351, +31, 460, -333, -849, 17, 373, 316, 319, +-302, -164, -323, -199, 388, 125, -66, 463, +-387, -626, 246, 282, -75, 267, -158, -396, +30, 328, 11, -95, -126, -8, -102, 173, +104, -235, -31, 213, -165, 220, -130, -506, +236, 262, -56, 399, -433, -519, 432, 244, +-313, -3, -3, -16, 170, 288, -375, -372, +191, 109, -173, 223, 191, -88, -213, -47, +-210, 94, 374, -55, -373, 57, 147, 62, +24, 119, -467, -312, 440, 133, -2, 373, +-508, -430, 301, 233, 52, -14, -337, -191, +238, 428, -157, -171, -2, -233, -36, 280, +-195, 91, 383, -170, -307, 25, -313, 102, +450, 25, -39, -82, -401, 56, 129, 131, +94, -279, -56, 335, -142, -76, -11, -80, +-3, -34, 44, 85, -12, 446, -315, -757, +279, 209, -7, 601, -287, -569, 231, 41, +-268, 274, 231, -162, -123, 10, -166, 100, +187, 15, -195, -223, 223, 277, -353, 46, +121, -239, 171, 73, -356, 182, 183, -66, +-114, 22, 65, -246, -15, 269, -229, 308, +165, -621, 85, 161, -251, 446, -58, -326, +276, -126, -229, 250, 8, 21, -59, -135, +22, 30, 164, 84, -377, -26, 169, 5, +42, -51, 11, 126, -198, -52, -125, -154, +512, 292, -345, -14, -299, -334, 379, 253, +-17, 33, -117, 154, -143, -382, -6, 52, +327, 353, -251, -58, -235, -259, 284, -93, +-20, 497, -45, -149, -277, -310, 274, 183, +154, 178, -538, -119, 231, -111, 273, 129, +-322, 126, -198, -368, 425, 419, -138, -128, +-273, -294, 284, 509, -115, -333, -47, 12, +27, 130, 78, 33, -219, -190, 92, 105, +159, 170, -299, -361, 121, 376, 38, -127, +23, -267, -291, 424, 316, -121, 43, -229, +-514, 244, 492, 13, -119, -259, -130, 372, +35, -196, -48, -118, 225, 219, -321, -83, +166, 81, -27, -115, -104, -155, 225, 528, +-279, -389, 114, -187, 49, 533, -61, -354, +-84, 49, 135, 49, -4, -16, -290, 51, +457, -112, -275, 50, -172, 123, 356, -223, +-160, 212, -31, -87, -102, -154, 168, 308, +80, -93, -312, -235, 151, 178, 79, 180, +-51, -325, -57, 125, -33, 135, 129, -211, +-72, 127, -79, -6, 179, -91, -187, 191, +1, -157, 261, -111, -324, 313, 67, -175, +221, 56, -265, -163, -31, 90, 364, 259, +-332, -229, -113, -214, 438, 256, -307, 256, +12, -457, 63, 23, -32, 344, 88, -180, +-137, -129, 121, 163, -123, -54, 52, 21, +123, 43, -122, -158, -101, 99, 93, 125, +229, -138, -290, -160, -61, 397, 225, -279, +14, -16, -106, 169, -114, -132, 241, 62, +-98, -76, -14, 110, 37, -42, -63, -121, +45, 209, 38, -53, -62, -180, 39, 258, +-3, -170, -84, -26, 237, 232, -189, -171, +-165, -140, 517, 209, -381, 45, -129, -31, +433, -259, -199, 117, -93, 349, 14, -206, +220, -466, -153, 591, -65, 24, 210, -451, +-247, 225, 211, 129, 33, -46, -252, -330, +224, 385, 31, 130, -181, -620, 104, 452, +128, 115, -168, -290, -63, 8, 272, 147, +-102, 57, -126, -249, 147, 173, -5, 10, +-40, -123, 70, 137, 8, -19, -140, -166, +127, 180, 189, 71, -314, -260, 17, 79, +407, 239, -347, -219, -92, -121, 434, 274, +-167, -69, -298, -117, 397, -11, -52, 198, +-118, -57, 102, -296, -89, 330, 152, 111, +-58, -501, 32, 264, 11, 416, -135, -734, +282, 189, -37, 568, -244, -510, 228, -265, +115, 518, -263, 114, 172, -567, 135, 164, +-203, 280, 10, -112, 151, -149, 152, 2, +-303, 164, -23, 8, 361, -241, -70, 123, +-71, 317, -303, -593, 507, 165, 207, 622, +-833, -743, 578, 33, 193, 460, -413, -279, +248, 99, -130, -259, 280, 252, -202, 73, +-89, -297, 401, 221, -209, -84, -131, -2, +216, -24, 174, 207, -355, -396, 164, 203, +268, 383, -412, -776, 312, 440, 93, 248, +-350, -505, 320, 166, 35, 206, -111, -257, +36, -3, 63, 272, 86, -253, -97, -109, +52, 298, 97, 3, -28, -385, -30, 229, +82, 220, 126, -364, -171, 162, 49, -90, +239, 116, -237, 88, 152, -392, 114, 306, +-314, 11, 438, -108, -90, 11, -275, -92, +390, 269, -77, -270, -50, 34, 60, 211, +60, -256, -16, -36, 91, 309, -19, -114, +-100, -389, 323, 439, -158, 10, -86, -293, +261, 151, -104, -85, 94, 174, -1, -106, +-120, -108, 336, 90, -151, 68, -110, -132, +384, 77, -310, -5, 117, -151, 276, 250, +-291, -183, 82, -5, 227, 87, -87, -72, +-108, -16, 293, 113, -152, -184, 27, 139, +160, -38, -120, -108, 228, 244, -206, -358, +101, 273, 228, -24, -165, -196, 26, 220, +89, -210, 50, 99, 22, 136, 98, -219, +-228, -64, 280, 187, 132, 98, -351, -330, +376, 152, -65, 27, -162, 7, 312, -71, +75, -23, -289, 150, 62, -256, 470, 171, +-207, 13, -352, -136, 549, 174, 12, -277, +-311, 202, 251, 92, 86, -277, -34, 145, +-103, -87, 276, 240, -36, -269, -152, -134, +336, 522, -210, -417, 123, -96, 157, 332, +-121, -169, -30, -47, 215, 40, 111, 45, +-293, -166, 248, 154, 86, 86, -118, -318, +157, 79, 48, 307, -83, -270, -28, -182, +388, 346, -148, -30, -228, -289, 290, 90, +128, 250, 14, -169, -255, -229, 176, 256, +258, 28, -93, -101, -87, -117, 32, 99, +248, 150, -107, -301, 85, 303, -84, -306, +118, 58, 144, 404, -183, -590, 288, 224, +-229, 158, 164, -234, 172, 105, -240, 0, +270, -42, -126, -79, 74, 159, 131, -33, +2, -114, -127, 18, 105, -39, 395, 308, +-517, -387, 199, -100, 412, 600, -478, -534, +293, 25, 43, 233, -91, -143, 201, 149, +-122, -433, 80, 448, 131, -50, -11, -380, +-136, 440, 224, -267, 171, 45, -356, 24, +187, -4, 315, 61, -315, -250, 120, 224, +100, 44, -61, -235, 180, 133, -27, 14, +-147, -37, 172, -97, 335, 79, -430, 135, +37, -306, 457, 183, -243, -10, -49, -85, +108, 130, 233, -144, -243, 44, 2, -32, +426, 49, -371, 59, 55, -165, 385, 27, +-438, 56, 307, 19, 217, 37, -571, -277, +466, 183, 209, 196, -355, -344, -9, 120, +305, -5, 81, 56, -264, -33, 126, -59, +84, -115, 147, 289, -225, -58, 125, -401, +205, 443, -314, -139, 278, -13, 18, -93, +-76, 100, 59, 50, -24, -228, 157, 265, +-8, -124, -43, -94, -74, 100, 236, -4, +105, 52, -317, -199, 139, 130, 254, 45, +-196, -96, 2, 20, 226, 58, -230, -127, +90, -8, 309, 335, -381, -417, 107, 36, +265, 268, -211, -147, 39, -41, 175, -35, +-174, 131, 56, -106, 244, 45, -238, 23, +19, -180, 210, 296, -47, -297, -68, 96, +31, 184, 213, -315, -188, 105, -3, 67, +268, 54, -212, -137, 33, -170, 133, 428, +-30, -160, -51, -302, 82, 279, 102, 66, +-222, -173, 249, -27, 1, 102, -218, -33, +299, 31, -99, -95, -30, 101, 85, -154, +-22, 126, 54, 148, -44, -383, 4, 271, +105, -63, -11, -21, -131, 120, 153, -239, +81, 202, -188, -120, 85, 101, 122, -3, +-81, -194, -38, 222, 106, -103, 32, 19, +-143, 11, 155, -70, 36, 128, -191, -184, +214, 118, 9, 154, -177, -356, 125, 87, +159, 340, -236, -280, 17, -216, 285, 438, +-268, -172, 36, -107, 198, 94, -145, -86, +-20, 197, 99, -184, 28, -43, -68, 181, +-13, -81, 66, -61, 28, 20, -20, 143, +-56, -192, 57, -3, 44, 254, -28, -323, +-1, 193, -7, -36, 24, -52, -3, 31, +63, 1, -43, 114, -72, -305, 69, 228, +164, 78, -153, -192, -224, 9, 429, 107, +-106, 39, -237, -222, 169, 216, 89, -59, +-83, -120, -98, 167, 200, -73, -132, -28, +8, -8, 131, 107, -212, -90, 142, -56, +63, 164, -150, -145, 51, 18, 73, 77, +1, -79, -154, 8, 129, 36, 122, 59, +-380, -245, 396, 266, -71, -15, -310, -281, +379, 297, -127, -104, -54, 5, -9, -58, +43, 79, 116, -69, -184, 87, 15, -8, +64, -236, 83, 356, -108, -129, -102, -155, +147, 66, 85, 224, -151, -197, -96, -174, +233, 352, -51, -101, -184, -217, 231, 244, +-153, 22, -33, -309, 208, 296, -175, 67, +-77, -324, 260, 126, -207, 133, 17, -41, +175, -121, -283, -30, 267, 224, -160, -164, +-22, -41, 240, 252, -352, -395, 178, 286, +41, 53, -9, -265, -117, 236, -35, -172, +274, 119, -236, -38, 7, 58, 56, -91, +-5, -167, 59, 496, -198, -401, 242, 16, +-170, 179, -18, -217, 253, 307, -364, -293, +248, 55, -87, 160, -40, -199, 172, 210, +-259, -210, 147, 62, -49, 177, 138, -267, +-172, 163, -136, -19, 414, -77, -275, 120, +-67, -57, 171, -55, -142, 16, 180, 117, +-162, -61, -67, -123, 245, 94, -191, 50, +84, 8, -102, -160, 77, 62, 103, 141, +-259, -104, 118, -85, 123, 88, -113, 164, +-183, -332, 297, 144, -9, 171, -380, -200, +388, 28, -53, -26, -229, 70, 219, 139, +-121, -398, 103, 292, -84, 144, -152, -499, +412, 470, -353, -96, -68, -235, 341, 204, +-198, 45, -57, -156, -4, 68, 154, 54, +-50, -96, -209, 71, 227, -61, -31, 95, +-113, -116, 45, 45, 97, 115, -135, -238, +-54, 145, 237, 101, -180, -131, -53, -116, +101, 204, -23, 47, 25, -212, -99, 88, +10, 36, 82, -13, -9, 29, -146, -87, +116, 61, -3, 19, -37, -33, -19, 9, +15, -80, 66, 202, -167, -107, 108, -200, +1, 273, -9, 99, -73, -335, -43, -16, +231, 439, -164, -292, -128, -148, 123, 240, +153, 39, -239, -180, -62, 11, 242, 177, +-101, -179, -64, 181, -26, -228, 75, 33, +40, 395, -133, -500, 42, 125, -23, 183, +108, -129, -75, 92, -208, -253, 358, 282, +-137, -39, -248, -137, 285, 22, 27, 133, +-267, 30, 69, -388, 255, 482, -308, -165, +34, -176, 171, 247, -178, -141, 60, 77, +-18, -89, 22, 63, -20, 121, -103, -285, +178, 140, -75, 180, -156, -237, 199, 76, +-82, -68, -29, 170, 46, -70, -92, -160, +83, 213, 14, -47, -127, -117, 50, 73, +112, 158, -172, -257, 6, 31, 159, 215, +-138, -162, -62, 2, 122, 50, -36, -78, +-47, 97, 45, 31, -76, -208, 33, 178, +69, 40, -109, -153, -22, 14, 102, 214, +-115, -194, 60, -126, 53, 421, -234, -338, +169, -20, 130, 249, -296, -165, 79, -16, +141, 58, -133, -2, 23, 39, -83, -114, +144, 41, -58, 183, -154, -323, 231, 219, +-140, 64, -69, -274, 152, 282, -75, -142, +-107, -20, 149, 171, -78, -196, -51, 26, +136, 147, -190, -41, 74, -237, 148, 262, +-237, 78, 11, -407, 225, 354, -237, -25, +48, -166, 117, 85, -239, 8, 168, 83, +61, -143, -235, 7, 79, 157, 136, -104, +-159, -57, -17, 104, 78, 0, -12, -58, +-74, -8, -32, 72, 171, -2, -147, -62, +-62, -31, 125, 175, -68, -169, 60, 58, +-93, 31, -35, -115, 113, 209, -44, -237, +18, 217, -195, -198, 236, 82, -21, 183, +-240, -407, 289, 388, -207, -158, 39, -77, +74, 155, -98, -90, 53, 45, -121, -43, +144, 19, -20, 32, -167, -27, 135, -51, +68, 150, -239, -141, 130, -81, 135, 346, +-282, -282, 99, -120, 160, 423, -267, -324, +121, 3, 117, 236, -308, -227, 201, 41, +86, 71, -221, 66, 28, -243, 76, 161, +71, 104, -175, -206, -59, 108, 211, -52, +-49, 123, -119, -74, -82, -112, 185, 146, +132, 35, -427, -67, 143, -142, 241, 170, +-161, 143, -121, -361, 31, 166, 207, 159, +-245, -244, 98, 129, 1, 6, -159, -116, +281, 204, -245, -115, 44, -178, 111, 367, +-208, -204, 164, -17, -55, 9, -30, 9, +-8, 204, -35, -297, 125, 64, -135, 73, +29, 114, -5, -180, -18, -56, 76, 204, +-154, -66, 87, -28, 45, -29, -196, 45, +175, 52, 3, -54, -206, -106, 219, 210, +-121, -46, -16, -215, 106, 214, -153, 65, +68, -211, 0, 72, 3, 92, -46, -117, +16, 95, -10, -53, 10, -5, 6, 15, +-108, -5, 178, 91, -132, -161, -82, 33, +214, 172, -131, -146, -58, -91, 39, 257, +63, -181, 5, -47, -205, 221, 200, -222, +4, 84, -175, 53, 132, -92, -13, 70, +-42, -58, -62, 40, 171, 44, -125, -134, +-106, 89, 287, 61, -269, -139, 72, 47, +110, 86, -208, -84, 175, -18, -78, 47, +-21, 28, 17, -30, -23, -105, 114, 186, +-208, -71, 93, -72, 72, 36, -65, 75, +-1, -17, -127, -196, 216, 273, -48, -87, +-164, -120, 109, 156, -5, -124, 17, 127, +-43, -42, -42, -122, 85, 167, -52, -65, +-32, -22, 109, 15, -98, 50, -83, -111, +188, 53, -27, 136, -261, -226, 266, 158, +-2, -36, -294, -81, 361, 199, -187, -154, +-156, -51, 365, 193, -280, -140, -20, 14, +196, 97, -118, -110, -66, 9, 46, 7, +162, 204, -271, -312, 73, 25, 215, 325, +-315, -279, 136, 3, 65, 116, -104, 5, +0, -120, 4, 41, 120, 159, -182, -192, +12, -14, 179, 214, -182, -199, 37, 58, +43, 79, -42, -151, 63, 112, -137, -35, +129, 80, -8, -181, -99, 125, 73, 60, +-25, -204, 83, 268, -164, -231, 80, 35, +66, 202, -117, -202, 109, 29, -180, 11, +192, 82, 28, -10, -304, -206, 255, 227, +61, -9, -170, -123, -71, 14, 212, 108, +-1, -35, -228, -149, 175, 259, -46, -248, +48, 150, -32, -11, -96, -143, 164, 243, +-126, -206, 94, 59, -33, 29, -107, -13, +178, 22, -89, -93, -10, 59, 48, 108, +-90, -233, 107, 204, -19, -79, -75, -98, +73, 275, -45, -332, 71, 200, -46, -17, +-78, -75, 168, 92, -97, -113, -54, 143, +122, -149, -65, 113, -17, -27, 32, -104, +12, 186, -28, -123, -31, -20, 90, 75, +-76, -8, 20, 0, 23, -138, -54, 199, +82, -5, -67, -224, 15, 203, 3, -34, +18, -37, 49, 12, -152, -47, 105, 88, +84, -27, -134, -67, -14, 72, 90, -32, +25, 41, -107, -42, 49, -62, 36, 156, +-61, -114, 86, -4, -65, 48, -39, -12, +104, -35, -29, 76, -56, -61, 37, -26, +-10, 86, 53, -56, -18, 68, -150, -173, +200, 180, 32, 44, -257, -270, 188, 212, +45, 33, -129, -169, 90, 106, -88, 6, +84, -54, 48, 42, -187, -32, 147, 65, +28, -77, -129, -7, 77, 97, 53, -56, +-108, -72, 55, 117, 35, -3, -97, -187, +133, 252, -48, -62, -117, -246, 176, 295, +-14, -40, -147, -138, 81, 108, 55, -68, +-9, 77, -101, -18, 55, -45, 105, 18, +-158, 6, 87, 53, -27, -106, -3, 120, +60, -62, -101, -51, 52, 82, 35, 13, +-9, -12, -85, -140, 95, 152, 6, 49, +-104, -111, 92, -15, 17, 70, -72, -9, +-36, -34, 226, 37, -174, -9, -159, -78, +393, 96, -205, 2, -126, -54, 216, 25, +-77, -88, 0, 175, -24, -105, 43, -9, +-13, 21, -21, -68, 72, 155, -91, -50, +35, -168, 51, 106, -24, 206, -44, -349, +22, 140, 64, 166, -52, -267, -26, 137, +22, 27, 64, -63, -68, 48, -35, -99, +142, 107, -91, 9, -62, -158, 163, 167, +-41, -54, -152, -74, 148, 83, 63, 63, +-163, -209, 59, 143, 45, 83, -3, -228, +-33, 208, -2, -160, 75, 121, -111, -33, +97, -103, 8, 206, -117, -197, 88, 75, +34, 82, -41, -129, -48, 23, 57, 92, +34, -71, -55, -10, 0, -10, 40, 81, +-8, -51, -19, -76, 36, 94, -5, 23, +-82, -56, 153, -79, -41, 166, -165, -109, +221, 63, -105, -49, 15, -19, 0, 116, +-75, -153, 194, 171, -154, -140, -19, -39, +139, 185, -62, -88, -78, -116, 121, 145, +-20, 8, -121, -135, 151, 139, -23, -38, +-80, -82, 39, 90, 64, -16, -60, -8, +-11, -16, 74, 3, -101, -35, 122, 79, +-51, 76, -101, -350, 193, 314, -106, 64, +-12, -302, 37, 146, 0, 41, 32, 46, +-97, -217, 81, 174, 39, 42, -92, -155, +-15, 60, 157, 51, -100, 8, -93, -150, +179, 167, -88, -49, 4, -61, 14, 98, +-36, -62, 63, -41, -10, 106, -26, -15, +-55, -110, 116, 76, 26, 62, -187, -106, +129, 32, 55, 64, -96, -135, 12, 166, +-11, -91, 109, -41, -111, 84, -9, -35, +104, 52, -107, -147, 74, 189, -35, -74, +-20, -118, 78, 233, -75, -165, 27, -27, +27, 142, -34, -73, -3, -27, 18, 16, +44, 64, -96, -94, 40, 54, 92, 24, +-101, -123, -5, 140, 71, -45, 2, -31, +-83, -14, 81, 63, -4, -18, -62, -46, +88, 47, -42, -15, -46, 8, 73, -20, +27, 50, -117, -57, 51, 6, 115, 29, +-127, 35, -45, -109, 175, 52, -94, 80, +-46, -129, 97, 67, -76, -20, 87, 44, +-105, -55, 56, 2, 91, 29, -200, -2, +164, -10, -20, -20, -74, 22, 77, 35, +-83, -55, 142, 3, -121, 57, -40, -84, +211, 119, -201, -134, 47, 73, 70, 24, +-29, -71, -24, 63, -20, -105, 141, 171, +-170, -140, 73, -9, 78, 121, -156, -96, +135, 6, -21, 4, -59, 33, 47, 9, +0, -111, 5, 114, -50, 59, 80, -183, +-54, 48, 4, 112, 97, 25, -178, -283, +136, 229, 26, 73, -109, -213, 81, 101, +-30, -34, 38, 57, -8, -48, -43, 71, +-5, -169, 114, 128, -44, 125, -158, -301, +217, 176, -19, 47, -160, -87, 144, -30, +-35, 80, 17, 20, -26, -141, -22, 97, +126, 67, -162, -137, 65, 58, 98, 10, +-135, 19, -6, -42, 137, -8, -36, 69, +-140, -124, 134, 142, 43, -54, -115, -100, +18, 140, 104, -20, -128, -114, 69, 129, +69, -9, -188, -148, 143, 161, 55, 4, +-123, -105, -33, -27, 152, 182, -10, -113, +-172, -79, 149, 154, 14, -88, -79, -17, +54, 45, -20, 43, 17, -139, 4, 51, +-8, 126, -22, -114, 79, -60, -41, 84, +-109, 9, 263, 20, -188, -115, -81, 23, +269, 174, -208, -189, 50, 44, 68, 36, +-131, -20, 125, 14, 22, -49, -160, 92, +97, -126, 112, 86, -177, 41, 40, -138, +119, 113, -141, -61, 93, 31, -5, 22, +-95, -116, 165, 171, -137, -157, 50, 94, +38, 41, -89, -190, 111, 216, -93, -132, +53, 63, 22, -4, -89, -95, 55, 132, +73, -55, -78, 24, -87, -82, 164, 29, +28, 136, -195, -149, 54, -22, 202, 113, +-165, -61, -104, 11, 236, 16, -88, -66, +-114, 68, 182, 0, -74, -63, -58, 65, +93, -42, -9, 1, -54, 36, 20, -21, +33, 21, -29, -99, 30, 144, -59, -26, +35, -114, 60, 65, -58, 79, -61, -82, +90, -68, 66, 182, -164, -152, 71, 32, +62, 38, -56, -45, 30, 75, -60, -124, +31, 55, 119, 89, -154, -98, -1, -54, +132, 110, -93, 20, 25, -77, -39, -54, +51, 157, 21, -88, -86, -44, 93, 113, +-39, -121, -14, 57, 41, 4, -13, 36, +-8, -102, -23, 30, 65, 121, -31, -158, +-31, 72, 41, 23, -37, -64, 73, 55, +-79, -5, 13, -20, 74, -57, -88, 112, +65, 5, -41, -209, 26, 245, -9, -50, +-11, -156, 38, 184, -52, -69, 47, -24, +-36, 18, 23, 39, -4, -22, -37, -52, +74, 65, -52, 22, -19, -104, 63, 105, +-41, -45, 0, -22, -3, 85, 29, -117, +-3, 76, -39, -18, 56, 1, -28, -43, +-11, 73, 34, -9, -29, -92, -29, 111, +87, -37, -52, 20, -69, -73, 114, 62, +-25, 54, -56, -106, 4, 22, 83, 74, +-46, -75, -83, 6, 126, 75, -19, -102, +-77, 29, 49, 31, 40, 21, -31, -77, +-75, 3, 130, 87, -14, -57, -157, -10, +179, -19, -21, 74, -127, -1, 64, -148, +127, 189, -140, -45, -86, -159, 253, 205, +-128, -73, -77, -17, 72, -72, 69, 151, +-85, -27, -40, -179, 148, 244, -148, -194, +69, 139, 33, -69, -80, -52, 71, 155, +-62, -192, 61, 148, 1, -35, -82, -52, +66, 35, 9, -9, -5, 63, -35, -89, +25, -22, 17, 79, -23, 28, 18, -68, +-38, -71, 40, 168, -20, -79, 10, -24, +6, 30, -40, -53, 39, 142, -1, -187, +2, 105, -28, 50, 7, -147, 10, 93, +29, 44, -46, -65, -23, -55, 67, 118, +-46, -25, 16, -38, -11, 11, -34, -11, +74, 48, -5, -5, -115, -101, 136, 125, +-28, -50, -110, -38, 159, 96, -80, -75, +-52, -9, 82, 25, 12, 77, -70, -131, +3, 48, 69, 28, -40, -22, -24, 48, +27, -100, -4, 46, 23, 50, -50, -29, +27, -87, 62, 130, -100, -82, 15, -39, +93, 200, -65, -229, -65, 20, 128, 186, +-72, -144, -2, 0, 24, 7, -33, 56, +60, -13, -95, -122, 123, 188, -56, -131, +-98, -18, 167, 136, -55, -116, -66, 28, +31, -16, 58, 48, -36, -27, -39, -7, +51, -12, -8, 5, -18, 42, 7, -48, +53, 18, -76, -61, -31, 85, 179, 18, +-124, -116, -115, 45, 212, 58, -54, 13, +-126, -109, 100, 17, 49, 157, -130, -187, +79, 79, 19, 31, -86, -84, 85, 124, +-80, -152, 93, 140, -57, -53, -71, -53, +164, 60, -98, 8, -48, 21, 95, -166, +-30, 201, -20, -54, -3, -63, 18, 44, +-2, -26, -23, 78, 17, -81, -17, 2, +28, 55, -38, -46, 38, -15, -13, 36, +-14, 30, 9, -137, 7, 93, 31, 121, +-112, -261, 97, 165, 18, 14, -91, -63, +16, 21, 28, -16, 52, 79, -122, -154, +41, 145, 72, -35, -105, -83, 58, 121, +-19, -90, -34, 36, 51, 46, -32, -120, +4, 93, -18, 31, -18, -122, 50, 101, +-13, 14, -87, -98, 51, 39, 82, 99, +-133, -130, 35, -10, 41, 111, -75, -25, +70, -98, -27, 64, -81, 56, 80, -115, +36, 89, -143, -28, 73, -21, 23, 16, +-56, 18, 13, -1, -18, -71, 29, 92, +-45, -37, -1, -17, 41, 13, -60, -1, +-17, 19, 58, -44, -57, 60, -1, -49, +1, -10, -16, 77, 12, -82, -33, 32, +-3, 16, 4, -31, -10, 15, -25, 23, +8, -34, -26, -14, -1, 107, 0, -128, +-52, 47, 50, 45, -25, -63, -58, 23, +58, -38, -25, 118, -39, -160, -5, 64, +30, 96, -42, -155, -50, 103, 69, -33, +-48, -9, -52, 40, 35, -15, 1, -63, +-52, 73, -1, 36, 0, -129, -28, 81, +35, 30, -87, -70, 22, 29, 47, -13, +-117, 50, 41, -48, 4, -40, -67, 128, +2, -90, 44, -4, -87, 13, -37, 47, +85, -20, -40, -106, -80, 153, 11, -77, +52, -30, -60, 93, -52, -93, 8, 27, +14, 52, -13, -52, -63, -13, -19, 5, +63, 74, -70, -91, -45, 1, 50, 74, +-69, -65, -20, 57, 27, -77, -33, 63, +-66, 8, 16, -80, 40, 85, -78, -31, +-66, -10, 58, -16, 16, 42, -96, 23, +-52, -119, 73, 89, -4, 46, -117, -94, +-12, 28, 79, -22, -51, 104, -130, -98, +110, -52, -23, 154, -154, -96, 140, 7, +-79, -8, -113, 53, 121, -38, -65, -28, +-101, 89, 60, -109, -1, 79, -116, -5, +44, -75, -13, 116, -78, -68, 22, -48, +-12, 107, -47, -45, -44, -55, 29, 61, +-30, 30, -78, -77, 27, 7, -29, 84, +-39, -74, 3, -5, -73, 39, 22, -24, +-6, 29, -102, -28, 27, -34, 21, 81, +-114, -32, 6, -46, 39, 38, -108, 16, +3, -26, 12, -21, -69, 63, -2, -86, +-28, 77, -38, -20, -1, -71, -24, 124, +-66, -92, 3, 25, 1, 2, -99, 38, +45, -27, -49, -87, -70, 162, 78, -80, +-94, -50, -66, 57, 53, -21, -10, 99, +-148, -162, 40, 38, 60, 178, -191, -211, +70, 56, -5, 68, -112, -47, 48, -13, +-49, 0, -36, 64, -27, -105, -2, 75, +-46, 30, -55, -131, 42, 124, -81, 0, +-41, -104, 51, 85, -93, -7, -34, -10, +22, -27, -43, 43, -57, 13, -25, -83, +26, 90, -64, -24, -41, -10, -41, -42, +60, 63, -72, 55, -140, -181, 146, 133, +-78, 39, -99, -123, 36, 51, -24, 31, +-30, -23, -61, -31, -8, 63, 1, -41, +-52, -29, -55, 101, 18, -92, -29, -6, +-58, 102, -29, -86, 14, -24, -22, 93, +-134, -35, 88, -56, -11, 69, -161, -26, +95, -14, -35, 26, -93, -38, 37, 36, +-40, -6, -59, -35, 8, 33, -9, 35, +-87, -97, 10, 36, 3, 100, -86, -119, +10, 1, -41, 74, -5, -13, -28, -55, +-76, 14, 60, 56, -65, -62, -63, 11, +34, 31, -43, -37, -41, 39, -37, -43, +31, 18, -71, 53, -58, -88, 66, 44, +-94, 13, -7, -15, -22, 5, -34, -43, +21, 63, -92, 3, -2, -69, 3, 41, +-19, 30, -69, -46, -34, 12, 72, 24, +-93, -38, -54, 7, 46, 68, -48, -97, +-34, 3, -20, 115, 1, -87, -64, -46, +-12, 74, 44, 52, -118, -121, -12, 1, +62, 146, -88, -113, -43, -32, 17, 119, +-28, -95, -1, 37, -65, 5, -19, -55, +52, 108, -107, -114, 14, 35, 17, 65, +-97, -86, 44, 21, -18, 12, -69, 39, +0, -64, -3, 3, -18, 67, -33, -69, +-36, 30, -1, 5, 15, -25, -60, 37, +-56, -30, 61, 9, -21, -6, -90, 24, +19, -32, 13, 2, -39, 59, -57, -86, +35, 59, -29, -13, -43, -19, 32, 37, +-63, -64, 10, 75, -27, -44, 2, -24, +-13, 63, -68, -60, 68, 20, -56, 6, +-23, -22, -3, 31, -32, -9, 29, -38, +-58, 46, -7, 28, -14, -99, 5, 57, +-7, 61, -90, -80, 54, -20, 25, 61, +-99, 39, -13, -121, 64, 43, -45, 104, +-84, -110, 72, -14, 0, 80, -105, -20, +38, -48, 40, 55, -83, -29, -20, -6, +61, 48, -47, -58, -46, 22, 29, 16, +-13, -14, -8, 10, -42, -30, 18, 12, +26, 51, -90, -68, 20, -5, 38, 83, +-38, -52, -61, -55, 46, 59, 46, 66, +-124, -128, 27, 13, 42, 140, -36, -140, +-27, 15, -12, 77, 42, -86, -44, 43, +-5, 14, 4, -40, -17, -9, 4, 54, +-13, -1, -8, -67, -36, 38, 42, 39, +-2, -27, -70, -64, 43, 83, 10, 11, +-36, -91, -12, 61, 25, 8, -8, -24, +-38, -18, 60, 12, -56, 43, -28, -57, +86, -14, -53, 72, -39, -36, 15, -36, +64, 44, -57, -1, -75, -13, 122, -13, +-32, 7, -75, 39, 58, -52, 1, -7, +-34, 66, 23, -63, -1, -3, -42, 62, +32, -47, 16, -25, -39, 51, -5, -1, +25, -47, 6, 21, -28, 17, -3, -6, +9, -16, 9, -8, -1, 31, -31, 2, +-4, -39, 39, 10, 3, 73, -87, -74, +40, -40, 83, 141, -106, -75, 1, -92, +61, 137, -17, -16, -31, -85, -8, 44, +71, 30, -66, -25, -20, -20, 95, 36, +-82, -4, -22, -36, 88, 44, -45, 23, +-57, -86, 77, 45, -6, 68, -50, -115, +47, 39, -32, 58, 22, -67, 16, 5, +-53, 25, 38, 13, -3, -39, 0, 6, +-12, 37, -12, -23, 31, 4, -27, -5, +21, -3, -25, 31, -14, -8, 75, -47, +-67, 33, -15, 57, 54, -78, -11, -5, +-24, 65, -20, -24, 64, 1, -37, -37, +-33, 25, 63, 81, -36, -101, -7, -33, +9, 131, 28, -38, -39, -89, -15, 44, +87, 77, -65, -77, -27, -50, 77, 136, +-32, -88, -29, -26, 37, 95, -4, -92, +-11, 49, 7, -1, 3, -44, -6, 58, +-2, -18, 22, -22, -25, 6, -8, 34, +43, -34, -17, -5, -28, 27, 37, -42, +2, 45, -28, -20, 24, -5, 1, 2, +-24, -25, 32, 91, 1, -97, -43, -13, +33, 110, 31, -78, -48, -11, -7, 25, +55, 19, -26, -21, -30, -36, 56, 60, +-30, -23, -3, -34, 33, 41, -35, -19, +28, -11, -5, 16, -9, -6, 14, -5, +-32, 23, 31, -3, -6, -26, -27, 32, +29, -11, 11, -1, -35, 5, -4, -23, +74, 49, -73, -40, -18, -10, 98, 53, +-70, -37, -16, 1, 43, -3, 7, 38, +-30, -23, -24, -45, 81, 91, -37, -62, +-48, -20, 74, 72, -1, -52, -55, -18, +19, 50, 58, 11, -59, -87, -10, 58, +60, 40, -31, -82, -9, 23, 13, 8, +25, 29, -24, -69, -12, -3, 42, 116, +-20, -127, -12, 10, 20, 78, 22, -59, +-42, 13, 12, -20, 42, 49, -54, -13, +18, -28, 21, 35, -18, -12, 3, 35, +-9, -56, 29, 34, -9, 26, -15, -61, +21, 30, 2, -2, -4, 28, -21, -77, +41, 32, -7, 64, -38, -136, 56, 81, +-18, 12, -36, -66, 48, 50, 8, -35, +-62, 33, 51, -13, 33, -30, -79, 54, +47, -9, 27, -19, -42, 13, 2, 41, +26, -10, 4, -38, -27, 54, 16, 20, +17, -70, -7, 41, -20, 38, 17, -65, +25, 1, -35, 44, 11, -40, 17, -42, +0, 51, -1, -43, -18, -5, 31, 2, +3, -29, -23, 51, 12, -78, 29, 39, +-18, 25, -16, -46, 30, 70, -21, -49, +10, 54, -4, 32, -15, -49, 34, 54, +-26, 8, 13, 11, 5, -26, -7, 24, +31, 24, -41, -57, 28, 32, 28, -7, +-48, -38, 25, -17, 27, 23, -16, -11, +-24, -103, 38, 72, 24, 14, -60, -103, +30, 39, 39, 12, -35, 12, -7, -22, +23, -27, 5, 112, -14, -27, 9, -49, +1, 86, 13, 17, 4, -4, -24, -13, +33, 42, 1, 25, -13, -45, 14, 33, +-15, -12, 32, -9, -19, -1, -17, -37, +63, -7, -37, -28, -8, -7, 38, -20, +-13, -28, -14, 0, 15, -25, 30, 19, +-35, -23, 6, -20, 39, 56, -11, -8, +-21, 4, 9, 6, 51, 67, -52, 28, +-11, -71, 77, 93, -47, 44, -16, -59, +43, 15, 11, 48, -31, -22, 2, -46, +54, 44, -43, -44, -3, -30, 42, 12, +-15, -56, 3, -23, 8, -12, 2, -2, +10, -58, 10, 8, -17, 13, 16, -40, +24, 52, -35, -25, 6, 20, 29, 60, +0, -32, -24, 28, 13, 54, 43, 9, +-36, 9, -22, 25, 58, 3, 13, 29, +-64, -20, 31, -14, 52, 26, -51, -40, +-2, -11, 35, -30, 12, -6, -29, -49, +4, -27, 53, 32, -38, -98, -6, 13, +41, 36, -7, -47, -25, -8, 19, 17, +48, 47, -62, -21, 10, 6, 63, 49, +-55, 42, -9, 11, 45, -38, 10, 93, +-43, 15, 25, -68, 42, 71, -56, 0, +26, -44, 23, 16, -19, -4, 10, -62, +2, 6, 23, 20, -21, -122, 13, 43, +21, 28, -37, -131, 37, 62, 10, 32, +-42, -96, 37, 29, 29, 101, -62, -80, +26, -26, 60, 162, -64, -63, 6, -22, +43, 84, -4, 20, -21, 17, -6, -77, +62, 107, -25, 6, -33, -84, 54, 47, +-2, -23, -3, 31, -10, -89, 16, 0, +42, 45, -49, -96, 13, 20, 49, -15, +-21, -16, -20, -9, 37, 4, 24, 0, +-37, -27, 24, 61, 32, -41, -20, 34, +-3, 48, 26, -66, 18, 94, -39, -3, +35, -33, 27, 63, -46, -26, 54, 19, +-6, -7, -15, -20, 47, 14, -22, -3, +13, -23, 9, -50, 11, 71, 9, -46, +-7, -86, 31, 104, -11, -52, 21, -46, +12, 44, -13, -3, 42, -20, -9, 7, +4, 56, 17, -79, 20, 66, 8, 46, +-24, -107, 59, 111, 1, -6, -40, -43, +56, 48, 17, -3, -29, -15, 30, -27, +44, 57, -32, -51, 6, -54, 73, 89, +-32, -49, -26, -68, 87, 59, -9, 14, +-49, -52, 68, -19, 22, 57, -28, 4, +19, -62, 29, 45, 15, 39, -12, -36, +21, -5, 24, 65, 4, -10, 6, -60, +20, 95, 33, -26, -13, -59, 16, 88, +29, -47, 12, -6, 3, 13, -4, -28, +67, 33, -18, -46, -17, 1, 81, 12, +-12, -14, -8, -5, 29, -11, 42, 35, +-11, -30, -11, 7, 76, 32, -24, -32, +9, 34, 49, 5, -3, -23, 20, 29, +10, 21, 47, -23, -21, -23, 21, 83, +66, -44, -38, -74, 40, 124, 24, -54, +13, -61, 21, 64, -6, -6, 62, -36, +-11, -26, 17, 66, 35, -43, -2, -31, +47, 57, -9, -40, 35, 17, 33, -9, +-14, 11, 51, 20, 16, -26, -1, 37, +37, -11, 37, 7, -11, 22, 17, -13, +68, 6, -20, 9, 18, 0, 61, -21, +0, 18, 13, 0, 33, -45, 49, 43, +-18, -9, 22, -73, 81, 74, -27, -15, +13, -66, 63, 45, 25, 6, -5, -17, +20, -43, 81, 62, -22, 0, 0, -50, +76, 63, -3, -28, 22, 31, 21, -20, +30, 5, 47, 49, -12, -73, 36, 56, +56, 2, -6, -31, 15, 9, 59, 22, +13, 6, -5, -73, 58, 80, 31, -19, +-3, -67, 50, 61, 25, -25, 14, -15, +49, 1, 5, 11, 21, -10, 58, -12, +12, 27, 8, -33, 52, 10, 40, 32, +-12, -34, 39, 4, 61, 31, -11, 1, +24, -24, 54, 4, 20, 64, -1, -54, +50, -22, 52, 82, -28, -49, 63, -14, +49, 19, -22, 12, 62, -18, 23, -35, +21, 69, 30, -47, 25, -22, 41, 48, +-1, -31, 68, -2, 7, -10, 4, 24, +78, -2, -12, -29, 30, 31, 39, -3, +34, 5, 19, -27, 3, 18, 88, 54, +-16, -80, 15, 24, 77, 67, -3, -63, +32, -2, 25, 33, 47, 10, 21, -43, +15, 19, 49, 20, 24, -49, 41, 54, +2, -55, 49, 12, 53, 36, -20, -64, +45, 49, 57, -37, 10, 21, -3, -3, +69, -25, 41, 40, -28, -47, 67, 38, +38, -21, 15, -4, 19, 13, 28, -13, +71, 30, -13, -54, 23, 43, 68, 3, +13, -19, 7, 12, 36, -2, 55, 39, +-8, -41, 26, 17, 60, 2, 9, 8, +22, 9, 32, -60, 44, 56, 13, 24, +12, -65, 53, -13, 26, 84, 8, -37, +30, -74, 51, 80, 16, -9, 13, -45, +45, 9, 21, 43, 22, -32, 23, -27, +38, 69, 26, -42, 11, -11, 45, 39, +19, -1, 26, -13, 29, -12, 19, 51, +42, -14, 11, -28, 30, 29, 39, 7, +15, -12, 42, -14, 8, 14, 27, 8, +59, -11, -17, -17, 33, 0, 61, 27, +-7, -31, 24, -22, 39, 25, 47, -11, +2, -16, 1, -11, 94, 18, -9, 0, +-12, -30, 90, 26, 2, 3, 4, -7, +35, 7, 43, 1, 17, 18, -9, -10, +65, 10, 17, -4, 4, 17, 40, 0, +22, -39, 32, 56, 1, -15, 29, -33, +36, 26, 9, 2, 37, -22, 0, -20, +41, 34, 32, -10, -19, -38, 51, 11, +40, 29, -4, -35, 8, -33, 62, 71, +23, -22, -36, -51, 72, 57, 40, 19, +-40, -46, 45, 10, 54, 56, -13, -32, +-1, -17, 67, 47, 9, -5, -16, -24, +57, 16, 14, 11, 7, -20, 21, 12, +17, -6, 40, -19, -9, 21, 24, -16, +39, -17, 0, 8, 28, -5, 4, 4, +32, -19, 31, -3, -22, 25, 44, -20, +32, 8, -20, 2, 33, 3, 30, 25, +9, -38, 19, 27, 13, 13, 37, -28, +8, 26, 3, -1, 33, -5, 16, -11, +25, 29, -6, -19, 19, -32, 66, 41, +-34, -10, -4, -29, 79, -13, 0, 55, +-43, -36, 46, -51, 66, 83, -55, -35, +3, -29, 92, 27, -21, 7, -26, -14, +59, -12, 34, 43, -24, -44, 10, 15, +55, 41, -3, -49, -8, 17, 33, 34, +13, -19, 6, -12, 5, 38, 9, -20, +32, -9, 5, 28, -6, -40, 36, 10, +16, 11, -10, -16, 20, -13, 21, 5, +9, 12, 0, -31, 18, 11, 32, -5, +-23, 6, 18, 9, 41, -22, -30, 24, +22, -6, 35, 12, -18, -8, 19, -6, +13, 38, 17, -25, 5, 1, -13, 7, +51, 20, -4, -21, -22, -21, 48, 62, +1, -49, 7, -16, 5, 32, 13, -12, +39, -12, -35, -31, 22, 59, 40, -32, +-25, -43, 15, 58, 16, -19, 16, -5, +-4, -19, 0, 36, 28, 17, -2, -58, +10, 41, 6, 9, 13, -10, 20, -14, +-17, 21, 17, 20, 27, -44, -6, 31, +-4, -2, 23, -10, 24, 4, -19, -10, +2, 14, 40, -17, -6, 10, -19, -19, +34, 12, 16, 14, -18, -52, 16, 35, +14, 16, 3, -32, -3, 3, 3, 24, +35, 5, -19, -26, -2, 6, 40, 35, +-24, 4, 10, -44, 16, 24, -4, 48, +21, -33, -21, -40, 31, 49, 15, 48, +-37, -106, 46, 27, 2, 85, -11, -97, +27, -1, -7, 55, 21, -22, 2, -48, +-2, 37, 24, 27, 3, -74, 11, 36, +-5, 21, 16, -31, 23, 7, -22, 5, +13, 13, 34, -19, -9, 21, -15, -17, +38, -1, 10, 56, -28, -65, 29, 7, +17, 44, -3, -21, -1, -16, 10, -12, +31, 52, -12, -38, 0, -30, 20, 50, +6, -23, 4, 8, -11, -17, 21, 2, +22, 33, -21, -41, 0, 13, 37, 10, +5, -1, -32, -4, 35, -12, 26, 41, +-38, -22, 22, -9, 16, 42, -7, -11, +11, -23, -13, 29, 33, 28, -2, -57, +-15, 11, 34, 64, -13, -55, 13, -15, +6, 50, -10, -9, 31, -27, -23, 21, +11, 18, 25, -32, -27, 22, 27, 13, +6, -37, -16, 39, 20, 4, 10, -29, +-10, 35, -5, -5, 31, 2, -2, 15, +-26, -12, 31, 19, 21, 4, -38, 6, +2, -2, 50, 11, -36, 26, -20, -30, +54, 28, -19, 4, -12, -23, 24, 43, +-6, -22, -2, -1, 4, 37, 0, -12, +-8, -11, 16, 25, 0, 25, -29, -34, +27, 20, 15, 34, -34, -28, 0, 20, +31, 21, -18, 7, -35, -2, 43, 8, +0, 30, -41, -20, 28, 26, -2, 4, +-13, 0, -2, 45, -5, -48, 14, 38, +-27, 41, -10, -36, 14, 25, -14, 11, +-12, 35, -10, -24, 9, 0, -8, 70, +-39, -30, 21, 2, 4, 34, -43, 10, +9, 2, 7, 4, -36, 42, -6, -5, +11, 2, -28, 33, -16, 9, 3, 7, +-15, 9, -20, 30, -14, 7, -2, 11, +-28, 21, -18, 6, 4, 38, -35, -11, +-6, -1, -7, 66, -40, -16, 3, -8, +-13, 43, -46, 20, -4, 9, -6, -8, +-44, 40, -23, 30, 0, -6, -38, 21, +-36, 7, 3, 50, -30, 3, -41, -34, +-7, 80, -19, 19, -46, -39, -23, 42, +-6, 59, -56, -18, -29, -10, -4, 85, +-54, -11, -32, -17, -19, 74, -37, 0, +-33, -5, -41, 37, -17, 31, -40, -2, +-51, 11, -14, 51, -50, -1, -42, 20, +-33, 33, -47, 0, -30, 44, -53, 11, +-41, 4, -34, 43, -55, 27, -49, 13, +-37, 4, -45, 49, -56, 20, -34, -5, +-57, 40, -54, 20, -32, 37, -70, 0, +-49, 12, -38, 70, -67, -11, -59, 13, +-51, 51, -40, 14, -76, 19, -64, 9, +-24, 48, -85, 26, -74, -12, -28, 54, +-73, 28, -79, 3, -54, 35, -57, 30, +-78, 30, -72, 10, -56, 32, -74, 42, +-73, 7, -61, 15, -74, 46, -70, 25, +-68, -5, -79, 55, -75, 29, -67, 2, +-81, 50, -85, 8, -62, 47, -80, 19, +-84, -9, -68, 78, -86, 5, -72, 12, +-86, 35, -89, 27, -60, 55, -104, -29, +-89, 52, -66, 72, -98, -36, -88, 48, +-83, 39, -81, 16, -96, 41, -98, 2, +-70, 45, -104, 48, -103, 2, -69, 25, +-101, 49, -110, 29, -70, 5, -94, 34, +-120, 48, -68, 14, -93, 10, -123, 53, +-76, 37, -95, -8, -113, 53, -95, 41, +-84, -3, -109, 47, -115, 22, -67, 39, +-114, 21, -124, -5, -58, 82, -120, 11, +-123, -13, -66, 67, -115, 34, -122, 17, +-85, 2, -97, 56, -126, 56, -104, -30, +-77, 50, -129, 53, -112, 3, -79, 37, +-119, 18, -112, 40, -94, 28, -107, 22, +-118, 35, -98, 16, -107, 63, -124, 7, +-84, 8, -116, 68, -121, 11, -82, 21, +-130, 39, -109, 35, -85, 15, -121, 19, +-112, 55, -101, 10, -100, 22, -125, 48, +-103, 20, -83, 15, -140, 36, -98, 45, +-80, -3, -138, 33, -98, 46, -84, 6, +-133, 40, -105, 12, -77, 41, -130, 33, +-115, -7, -72, 64, -127, 14, -123, 23, +-71, 38, -115, 3, -132, 69, -84, -3, +-81, 11, -146, 72, -97, -13, -57, 34, +-154, 36, -103, 16, -55, 36, -142, 5, +-107, 48, -72, 21, -108, -2, -118, 55, +-86, 16, -86, 10, -128, 41, -84, 19, +-85, 20, -127, 32, -82, 15, -88, 29, +-119, 35, -97, 9, -81, 36, -112, 29, +-105, 10, -72, 37, -111, 13, -100, 32, +-75, 24, -108, -1, -95, 59, -90, 10, +-93, 8, -95, 49, -97, 1, -80, 49, +-104, 5, -87, -1, -78, 79, -108, -13, +-80, 5, -87, 56, -100, 22, -77, 13, +-91, -2, -93, 63, -77, 23, -88, -24, +-94, 53, -70, 30, -85, 1, -103, 20, +-70, 40, -79, 20, -98, 0, -77, 36, +-71, 22, -84, 12, -96, 19, -59, 24, +-74, 23, -109, 4, -51, 35, -76, 16, +-101, 9, -54, 31, -77, 3, -85, 35, +-75, 15, -67, 6, -74, 35, -90, 7, +-57, 33, -75, 6, -92, 13, -53, 49, +-69, -11, -86, 11, -61, 38, -61, 18, +-80, 0, -68, 10, -59, 50, -75, 3, +-64, -8, -67, 43, -63, 14, -58, 0, +-79, 19, -52, 22, -64, 16, -74, 2, +-50, 28, -72, 16, -60, 2, -55, 28, +-65, 3, -54, 12, -60, 22, -60, 7, +-55, 15, -62, 15, -53, 13, -57, 10, +-64, 21, -54, 16, -52, 8, -64, 19, +-53, 13, -45, 14, -65, 4, -53, 25, +-53, 25, -56, -15, -46, 33, -60, 15, +-40, -9, -51, 28, -58, -3, -34, 23, +-61, 8, -45, -4, -41, 38, -68, -5, +-29, 12, -49, 19, -64, -5, -22, 30, +-53, -3, -58, 3, -32, 41, -44, -11, +-53, 4, -41, 35, -37, -3, -41, 0, +-45, 20, -44, 10, -32, 15, -53, 4, +-46, 8, -20, 28, -58, -6, -37, 3, +-23, 27, -57, -1, -31, 12, -34, 3, +-45, 17, -31, 21, -40, -26, -31, 33, +-35, 25, -45, -33, -23, 32, -32, 22, +-40, -20, -28, 13, -28, 18, -34, 12, +-34, -14, -25, 7, -28, 43, -41, -20, +-31, 0, -12, 38, -47, -7, -34, 0, +5, 12, -46, 1, -31, 6, -3, 10, +-46, 8, -25, 4, -14, 5, -26, 9, +-24, 3, -32, 0, -8, 21, -27, 4, +-45, -6, 2, 29, -22, 0, -45, -11, +7, 22, -20, 7, -46, -2, 2, 11, +-16, 15, -34, -5, -6, 0, -17, 23, +-17, -4, -16, -4, -20, 16, -6, 10, +-26, 5, -18, -4, 0, 16, -21, 7, +-10, -11, -11, 18, -16, 2, -9, 9, +-21, 14, -5, -11, -4, 18, -24, 9, +-2, -3, -5, 12, -25, 2, 1, 17, +-3, 4, -22, -12, -4, 33, -2, 7, +-10, -21, -10, 29, -5, 10, 6, -9, +-15, 11, -12, 6, 22, 17, -24, -6, +-12, -4, 27, 41, -23, -19, -6, -9, +19, 44, -14, -14, 1, -6, 8, 17, +-2, 3, 7, 13, -8, -16, 5, 16, +13, 33, -11, -35, 6, 15, 17, 29, +-7, -16, 3, 10, 13, 3, 4, 14, +10, 6, 0, -18, 13, 28, 17, 5, +-9, -15, 16, 22, 19, 1, -7, 4, +14, 10, 18, -8, 7, 18, 2, 12, +18, -18, 20, 21, -7, 16, 15, -13, +28, 11, -3, 10, 14, 5, 28, -3, +1, 6, 12, 23, 24, -13, 7, 4, +16, 26, 19, -15, 15, 3, 20, 20, +7, -4, 23, 0, 30, 6, 1, 8, +26, -3, 29, 3, -2, 18, 29, -9, +24, 7, 8, 14, 23, -3, 17, 8, +19, 14, 19, 1, 19, -8, 32, 13, +15, 13, 17, -16, 34, 8, 19, 21, +15, -12, 34, -3, 24, 16, 13, 3, +26, -1, 30, 1, 16, 12, 17, 5, +37, -8, 21, 10, 11, 10, 34, -3, +24, 10, 13, 5, 31, -1, 29, 10, +19, -2, 25, 7, 29, 3, 30, -4, +20, 16, 22, -6, 39, 1, 23, 11, +15, -7, 40, 13, 25, 0, 18, -10, +39, 20, 23, -4, 18, -4, 35, 13, +24, -1, 28, 1, 29, -4, 27, 2, +33, 13, 25, -11, 25, -3, 39, 16, +22, -4, 23, -8, 38, 15, 21, 4, +28, -7, 37, -1, 26, 8, 28, 2, +33, -13, 27, 15, 30, 2, 37, -20, +27, 12, 32, 5, 36, -15, 22, 6, +33, 3, 35, 1, 19, -4, 36, -3, +35, 13, 22, -13, 34, 0, 34, 7, +24, -6, 36, 1, 33, -5, 26, 1, +37, 1, 28, -3, 27, 1, 40, 0, +24, -3, 31, 3, 42, -5, 17, 0, +34, 9, 40, -9, 19, -3, 38, 6, +40, -7, 21, -8, 40, 5, 32, 0, +20, -6, 45, 3, 29, -5, 27, -5, +45, 0, 21, 3, 30, -9, 49, 0, +18, 4, 32, -11, 44, 10, 20, -7, +39, -8, 45, 0, 22, -1, 36, -3, +38, -5, 25, 4, 38, -2, 33, -9, +32, -4, 40, 10, 22, -11, 36, -4, +46, 5, 17, -4, 35, -4, 52, -9, +17, 6, 36, -7, 48, -6, 15, 3, +41, -1, 45, -9, 22, -4, 42, 3, +44, -12, 26, 0, 42, -8, 40, 2, +28, -6, 44, -7, 28, 6, 34, -6, +48, -2, 21, -4, 41, -1, 50, -7, +14, 3, 43, -6, 45, 0, 17, -2, +46, -8, 44, -1, 27, -11, 46, 1, +39, -13, 34, -4, 46, 0, 31, -7, +32, -2, 54, -4, 25, 1, 34, -12, +53, 5, 21, -3, 43, -7, 48, -6, +25, 0, 46, -3, 41, -11, 27, 7, +44, -6, 41, -3, 34, -9, 43, -1, +38, -4, 38, -9, 43, 2, 27, -5, +41, 1, 49, -8, 23, -2, 45, -7, +51, 0, 17, -6, 48, -5, 49, -1, +22, -9, 46, 3, 46, -14, 27, 6, +43, -9, 43, -5, 30, 3, 43, -9, +41, -4, 37, -6, 43, 3, 33, -13, +42, 3, 42, -5, 27, -3, 46, -3, +41, -7, 24, 7, 53, -17, 39, 1, +26, -1, 48, -5, 36, -4, 32, 0, +40, -3, 37, -2, 34, 2, 41, -12, +40, 1, 38, -9, 45, -3, 36, -11, +40, 1, 40, 0, 30, -12, 46, 6, +37, -9, 33, -4, 46, -3, 34, 2, +38, -14, 44, -1, 36, 4, 39, -16, +41, 0, 38, -3, 39, 0, 39, -12, +38, 0, 43, -3, 38, -7, 31, -1, +49, -4, 36, -1, 31, -13, 53, 4, +34, -11, 34, -3, 50, -4, 33, -5, +34, 1, 46, -12, 39, 1, 37, -10, +42, -1, 40, -7, 40, -4, 38, -2, +40, -9, 43, 0, 34, -4, 34, 0, +47, -10, 34, 4, 39, -11, 48, -5, +31, -1, 43, -5, 42, -3, 30, -5, +44, 7, 37, -14, 32, 5, 43, -2, +33, -3, 35, -1, 40, -1, 35, 3, +39, -16, 43, 4, 38, -7, 40, -6, +44, -6, 31, 3, 41, 1, 41, -11, +31, 4, 44, -2, 40, -2, 34, -9, +44, 2, 39, -3, 38, -5, 39, -5, +44, -5, 41, 2, 37, -16, 41, 5, +42, -6, 40, -6, 35, -4, 46, -3, +41, -1, 26, -8, 47, 6, 43, -6, +23, 1, 47, -4, 46, -3, 30, -4, +41, -2, 47, -3, 35, -4, 39, 1, +44, -8, 41, 0, 36, 0, 39, -1, +44, -7, 38, 2, 37, -3, 49, -11, +38, 8, 31, -8, 51, -2, 42, -8, +34, 0, 48, -7, 40, -7, 35, 11, +44, -17, 40, 0, 44, 1, 37, -5, +36, -4, 45, 3, 37, 3, 32, -9, +48, 3, 46, -3, 35, -15, 50, -2, +49, 0, 36, -17, 42, 6, 48, -1, +38, -9, 36, 0, 49, -1, 44, -3, +34, -14, 47, 11, 47, -9, 29, -6, +41, 10, 52, -13, 36, -2, 33, 0, +52, 2, 43, -12, 29, 1, 49, 9, +47, -19, 36, -1, 48, 4, 46, -14, +39, 0, 44, 1, 47, -11, 43, 0, +43, -4, 39, 4, 46, -14, 46, 2, +41, 2, 41, -19, 45, 19, 39, -9, +38, -8, 51, 6, 46, -11, 39, -3, +42, -5, 47, 11, 40, -13, 36, -8, +55, 15, 40, -16, 30, 0, 55, 8, +46, -12, 34, -2, 46, 1, 48, 3, +37, -10, 42, -5, 52, 12, 40, -21, +41, 4, 52, 2, 41, -16, 36, 17, +43, -10, 43, 5, 38, -1, 43, -5, +46, 6, 38, -14, 41, 17, 43, -10, +45, -12, 46, 14, 39, -17, 43, 3, +48, 1, 42, -10, 40, 4, 51, -10, +43, 9, 33, -8, 48, -2, 47, 17, +29, -23, 45, 12, 55, 1, 32, -15, +40, 11, 58, -13, 37, 10, 32, -8, +53, -2, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_16000_2ch_16b.c b/USDK/example_sources/i2s/src/birds_16000_2ch_16b.c new file mode 100644 index 0000000..18ea03a --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_16000_2ch_16b.c @@ -0,0 +1,11666 @@ +#include +int sample_size=46639; + +SECTION(".sdram.data") +short sample[]={ +0, 0, -1, 2, 0, -1, -1, 2, +-3, 2, 1, -1, 0, 0, 2, 0, +-2, 1, 2, -2, -1, 2, -3, 2, +1, -1, 1, -1, 4, -4, 1, -2, +2, -2, 2, -3, 1, 2, -4, 1, +2, -1, -2, 0, 1, 0, -1, 1, +-2, 2, 1, -1, -1, 1, 2, -2, +2, -3, 0, 2, -1, -2, 4, -1, +-1, -1, 3, -1, 0, -2, 2, 1, +-3, 1, 3, -2, 2, -2, 1, -1, +1, -1, -1, 0, 1, 0, -3, 2, +-1, 2, 0, -2, 1, 2, -1, 0, +1, 0, 2, -3, 3, -2, 0, -1, +2, -1, -2, 3, -3, 2, 1, 0, +0, -1, -1, 3, -1, -2, 5, -3, +-1, 0, 1, 0, -3, 3, 1, -2, +3, -3, -2, 2, 1, -2, 0, 1, +-3, 2, 1, -2, 1, 0, -2, 2, +-3, 3, -2, 1, 1, 0, -1, 1, +-1, 2, -2, 1, 0, 1, -1, 1, +0, 1, -1, 0, 3, -2, 1, 0, +1, -1, 1, 0, 1, -1, 2, -1, +0, 0, 0, 1, -2, 1, 2, -1, +-2, 2, -3, 3, -2, 1, -2, 2, +-1, 0, 1, -1, -4, 4, -3, 3, +1, -1, 0, 0, 1, -1, -1, 1, +1, -1, 1, 0, -1, 1, -1, 1, +-1, 1, 1, -1, 0, 1, 2, -3, +1, 0, -1, 1, -1, 1, -1, 1, +-2, 2, -2, 3, -4, 3, 0, 0, +0, -1, 3, -2, -2, 2, -2, 1, +-2, 2, -1, 1, -2, 2, 2, -2, +-1, 1, -2, 1, 2, -2, 1, -1, +4, -3, 0, 0, 2, -2, -1, 2, +0, 0, -1, 2, 0, 0, 1, -1, +1, 0, 0, 0, -3, 4, -2, 1, +-1, 1, -4, 4, -4, 4, -2, 2, +-3, 3, -4, 4, -2, 2, -4, 4, +1, -3, 4, -3, 1, -2, 2, -1, +1, -1, -1, 1, 0, -1, 0, 1, +-4, 5, -1, 1, 3, -2, 1, 0, +-1, 2, 2, -2, 1, 1, 0, 0, +1, 0, -1, 1, 2, -2, 0, 0, +-2, 1, 1, -1, -3, 3, -1, 0, +1, -2, 0, 0, 0, -1, 3, -3, +1, -1, -1, 1, 3, -4, 4, -3, +0, 0, 0, 0, -3, 3, -4, 3, +1, -1, 1, 0, 2, -1, 1, -1, +0, 1, -2, 2, 0, 0, -1, 2, +-1, 1, 2, -1, -1, 2, -2, 1, +1, -1, -1, 1, 1, -2, 0, 0, +-1, 0, 0, 0, -2, 2, -2, 2, +-2, 1, 1, -2, 1, -1, -4, 5, +-1, -1, 5, -5, 3, -3, 2, -1, +-4, 4, 0, 0, 3, -2, -1, 2, +3, -3, 3, -1, -1, 1, 1, -1, +0, 0, 1, -1, 1, 0, -2, 1, +1, -1, 1, -1, 1, -2, 0, 1, +-3, 2, 1, -3, 2, -2, 0, -1, +0, 0, -3, 2, 0, -2, 0, 1, +0, -1, 1, 0, -1, 1, -1, 1, +1, -2, 2, -2, 2, -1, 1, 0, +2, -1, 3, -2, 2, -1, 1, -1, +4, -4, 5, -4, 1, 0, -3, 3, +2, -2, 2, -2, 0, 0, 1, -1, +-2, 1, -1, 0, -3, 2, -1, 0, +-1, 0, -3, 3, -2, 0, -1, 1, +-1, 0, 3, -3, 3, -3, 1, -1, +-1, 2, -1, 1, 1, 0, -1, 1, +-2, 3, -2, 2, 3, -3, 3, -2, +2, -1, 2, -2, 2, -2, 2, -2, +-2, 3, -2, 1, 0, 1, -3, 3, +-1, 0, 2, -2, -2, 2, -2, 0, +2, -3, 1, -1, 0, -1, 0, 0, +-2, 2, -2, 2, 0, -1, -1, 1, +-1, 0, 1, -1, 0, 1, -1, 2, +0, 1, -2, 3, 0, 0, 1, -1, +1, 0, 0, 0, 3, -2, 1, 0, +2, -1, -2, 2, 0, 0, -1, 1, +-4, 3, 3, -3, -2, 3, 0, -1, +2, -2, -1, 1, 0, -1, -2, 2, +-3, 1, -1, 2, -3, 2, 0, 0, +0, -1, 3, -3, 1, -1, 0, 1, +-1, 1, 0, 0, -2, 3, 0, -1, +2, -1, -1, 1, -1, 2, -5, 4, +0, 0, -2, 2, 1, -1, 0, 0, +1, 0, -2, 2, -3, 2, -2, 2, +-3, 3, -2, 1, 1, -2, 2, -2, +3, -4, 3, -3, 0, 0, -1, 1, +-1, 0, 1, -1, -1, 1, -1, 1, +3, -3, 1, 0, 1, -2, 2, -1, +-3, 4, -1, 1, 2, -2, 1, -1, +1, -1, 1, -1, 1, 0, 0, 0, +-1, 1, -2, 1, 3, -3, 2, -2, +0, 1, -5, 5, -4, 4, -2, 1, +0, 0, 2, -2, -1, 1, 0, 0, +0, 0, 1, 0, -2, 1, 0, 0, +2, -3, 0, 2, -1, 0, 2, -1, +0, 0, 4, -3, 1, -1, 2, -2, +0, 1, -2, 1, 1, 0, -2, 1, +1, 0, -2, 1, 1, -1, -3, 3, +-4, 4, -2, 0, 5, -5, 2, -1, +0, 0, -2, 2, -3, 2, 2, -2, +0, 0, -2, 4, -4, 2, 3, -3, +1, -2, 4, -4, 1, -1, 0, 0, +-2, 2, -3, 3, 0, 0, 1, -1, +0, 0, 2, -2, 3, -2, 1, 0, +-4, 4, -3, 2, 2, -2, -1, 1, +0, 0, -1, 1, -2, 2, -3, 2, +0, 0, 0, 0, -1, 0, 1, -1, +-2, 1, 2, -3, -2, 3, -3, 2, +-3, 4, -3, 1, 4, -4, 0, 0, +3, -3, 1, 0, 0, -1, 1, 0, +0, -1, 2, -1, 0, 0, 0, 1, +-1, 1, 1, -1, 2, -2, 2, -1, +0, 0, 0, 1, -3, 3, 2, -4, +1, 0, -4, 3, 0, 0, 0, -1, +0, 0, -1, 0, 2, -2, 1, -1, +-1, 1, 0, 0, -1, 0, 2, -2, +-2, 2, 1, -1, -1, 1, -1, 1, +-1, 1, 1, -1, -1, 0, 2, -2, +0, 1, -1, 1, 0, 1, 0, -1, +0, 1, -2, 1, 2, -1, -3, 3, +0, -1, -1, 1, 0, -1, 3, -4, +1, -1, 2, -2, 1, 0, 0, 0, +2, -1, 0, 0, 3, -4, 3, -1, +-1, 0, 0, 0, -1, 1, -1, 2, +-3, 3, 2, -2, 2, -2, 1, 0, +0, 0, 0, 0, -2, 2, 1, 0, +-2, 3, -1, 0, 1, -2, 5, -5, +0, 1, -2, 2, -2, 2, -4, 3, +-1, 0, 2, -2, 0, 0, -1, 1, +1, -1, 0, 1, -2, 1, 0, -1, +2, -1, -1, 1, 0, 0, 0, 1, +-2, 2, 0, -1, 1, -1, 1, -2, +2, -2, 0, 0, -1, 1, -1, 2, +-3, 2, 3, -3, -1, 1, -2, 2, +-3, 2, -1, 0, 1, -1, 1, -1, +0, -1, 2, -2, 1, 0, 0, 0, +0, 1, -2, 1, -1, 1, 0, -1, +1, -1, -2, 1, 1, -1, 2, -2, +0, 0, 0, 1, 0, 0, 1, 0, +-3, 3, -1, 1, 0, 0, 1, -1, +-1, 1, 0, 0, -1, 1, 0, -1, +3, -3, 0, 0, -1, 1, 0, 0, +-2, 3, -6, 5, -2, 2, -1, 0, +1, -1, -1, 1, -1, 1, 1, -2, +4, -4, 3, -3, 2, -2, 1, -1, +2, -2, -2, 3, -4, 4, -2, 2, +-1, 1, 0, 0, 0, 0, -3, 3, +-2, 3, -2, 2, 0, 0, -1, 1, +-1, 2, -3, 3, 0, 0, 1, -1, +1, -2, 1, 0, -1, 0, 1, 0, +-1, 0, 1, 0, -3, 2, -1, 1, +-2, 2, -1, 1, -1, 2, -2, 2, +2, -3, 2, -2, 1, 0, 0, -1, +2, -2, 1, -2, 1, 0, 2, -3, +1, -1, 0, 0, 1, -1, 0, 0, +2, -2, -1, 1, 0, -1, -2, 2, +-3, 2, 1, -1, 0, 0, -2, 2, +0, 0, -2, 2, 0, -1, 4, -4, +1, -1, -1, 1, 1, -1, 2, -2, +-2, 2, 0, -1, 3, -2, 1, 0, +1, -1, 2, -2, 0, 0, 1, -1, +0, 0, 0, 0, 0, 0, 1, -1, +-2, 1, 1, -1, 0, 0, -3, 3, +-2, 1, 2, -2, 0, 0, -1, 1, +0, 0, -2, 2, -2, 1, 1, -1, +0, 0, 1, -1, 1, -1, 1, -1, +-1, 1, -1, 1, -1, 0, 2, -2, +1, -1, -1, 1, -2, 1, 0, 1, +-4, 5, -3, 2, 1, -1, 1, -1, +0, 0, 0, 0, -1, 1, 0, 0, +-3, 3, -1, 0, -1, 1, 0, -1, +3, -3, 3, -3, 3, -3, 1, -1, +2, -2, 0, 1, -4, 4, 1, -2, +2, -1, -2, 3, -3, 2, 1, -1, +-1, 1, 1, -1, 1, -1, 2, -3, +1, -1, 2, -2, 2, -2, -1, 2, +-4, 3, -2, 1, 1, -1, 2, -2, +-1, 0, 1, -1, 0, 1, 2, -3, +1, 0, -3, 3, 0, 0, -1, 1, +0, 0, -1, 1, -1, 1, 0, 0, +2, -2, 0, 0, 0, 0, -1, 1, +0, 0, 0, 1, -1, 1, 1, -1, +0, 1, -2, 2, 2, -2, 0, 1, +-3, 2, 0, 0, 1, -2, 3, -3, +0, 1, -2, 1, 2, -3, 4, -3, +-2, 2, 0, -1, 1, 0, -1, 1, +-1, 1, 3, -4, 1, 1, -2, 2, +0, 0, 0, 1, -3, 3, -2, 2, +0, 0, 2, -2, 0, 1, -2, 1, +4, -4, 2, -1, -1, 0, 2, -2, +1, -1, 1, -1, 1, -1, 0, 0, +-1, 1, 1, -1, -1, 1, -1, 1, +-3, 3, -4, 4, -1, 0, 0, 0, +-1, 2, -2, 2, 0, 0, 1, -1, +1, -1, -1, 1, 0, 0, 2, -2, +3, -3, 0, 1, 0, 0, 1, -1, +1, -2, 1, 0, -1, 1, 3, -3, +2, -2, 1, -1, 0, 0, 1, -1, +-1, 0, 3, -3, 2, -2, 3, -3, +4, -4, 1, -1, -1, 1, 1, -1, +1, -1, 2, -3, 2, -1, -3, 3, +0, -1, 0, 0, -1, 2, -1, 0, +3, -3, 2, -2, -1, 2, 0, 0, +1, 0, -4, 4, 1, -2, 1, -1, +-1, 1, -2, 2, 1, -2, 2, -2, +-2, 2, -1, 1, 2, -2, 0, 0, +1, -1, -1, 1, -1, 1, 1, -1, +-1, 1, 0, 0, 0, 0, 2, -2, +1, -1, 0, -1, 1, -1, -1, 1, +-2, 2, -2, 2, -2, 2, -1, 1, +-2, 2, -1, 0, 0, 0, 0, 0, +-2, 2, 0, -1, 4, -4, 0, 1, +-3, 2, 0, 0, -1, 1, -1, 1, +-1, 0, 0, 0, -1, 1, -2, 2, +-2, 2, 1, -1, 2, -2, 0, -1, +2, -1, 0, 0, 2, -2, -1, 2, +-1, 1, 0, 1, 0, 0, 2, -2, +2, -1, -2, 2, 2, -3, 2, -1, +-3, 3, 2, -2, 0, 0, 0, 0, +1, -1, 2, -2, 0, 1, -2, 2, +-2, 2, -1, 1, 1, -2, 2, -2, +-2, 2, 0, 0, 0, 0, 1, -1, +-1, 1, -1, 1, 1, -2, 1, -1, +-2, 2, -1, 1, 0, 0, 1, -1, +0, 1, 1, -2, 3, -3, -1, 1, +1, -1, 0, 1, -1, 0, -1, 1, +1, -2, 1, 0, -2, 1, 3, -3, +-3, 3, -1, 0, 2, -3, 1, 0, +-1, 1, -1, 1, -1, 0, 0, 0, +2, -3, 0, 1, 0, -1, 1, 0, +-2, 1, 1, -1, -4, 5, -1, -1, +2, -1, -3, 3, 0, 0, 0, 0, +-1, 2, 0, 0, -1, 2, -2, 2, +-2, 1, 1, -1, 0, 1, -3, 3, +1, -1, 3, -3, 1, -1, 0, 0, +1, -1, 1, -1, 0, 0, -2, 2, +-2, 2, -2, 2, 0, -1, 2, -2, +1, 0, -2, 2, -3, 2, 0, -1, +1, 0, -1, 1, -1, 1, -2, 2, +-2, 2, 0, -1, -1, 1, 1, -2, +2, -1, -1, 1, -2, 2, 0, -1, +2, -1, -1, 1, 0, 1, -2, 2, +-1, 1, 2, -2, 2, -1, 0, 0, +1, -1, 3, -3, 3, -2, -1, 1, +0, 0, 0, 0, 0, 0, 1, -1, +1, -1, -1, 2, -1, 1, -2, 2, +-3, 3, -1, 0, 2, -2, 0, 0, +0, 1, -3, 3, 0, 0, -1, 1, +1, -1, -1, 1, -2, 1, 1, -1, +0, 0, 4, -5, 3, -2, -1, 0, +2, -1, -1, 1, 0, 0, 0, -1, +1, -1, -1, 2, -3, 3, -2, 1, +1, -1, -1, 0, 2, -2, -1, 1, +1, -2, 0, 2, -5, 5, -1, 0, +1, -1, 1, -1, -1, 2, -3, 3, +-1, 1, -1, 0, 1, -1, 0, 0, +3, -3, 0, 1, -2, 2, 1, -1, +0, 0, 1, 0, -3, 4, -1, -1, +2, -2, -2, 2, -2, 1, 1, -2, +3, -3, 2, -2, 1, -1, 0, -1, +2, -2, 1, -1, 1, -1, 2, -3, +3, -2, -2, 2, 1, -1, 0, 0, +0, 0, 0, -1, 2, -3, 1, -1, +0, 0, 1, -1, 0, 0, 0, 0, +1, -1, 0, 1, -2, 2, 1, -1, +-3, 3, 0, -1, -1, 2, -4, 3, +1, -2, 2, -2, 2, -1, -2, 2, +0, 0, -2, 3, -3, 2, -2, 2, +-3, 2, 2, -2, -1, 1, -1, 1, +-1, 2, -1, 1, 0, 0, 0, 0, +2, -2, 1, 0, -4, 3, 2, -2, +-1, 3, -2, 0, 2, -2, 0, 1, +0, 0, 1, -1, 0, 1, 0, -1, +2, -2, -2, 2, 3, -4, 2, -1, +-5, 5, 1, -2, 2, -2, 2, -2, +0, 0, -2, 2, -1, 1, 3, -3, +1, 0, 1, -1, 0, 0, 2, -2, +1, 0, 1, -1, 0, 1, -2, 1, +1, 0, -1, 1, 1, -1, 2, -2, +1, -1, 1, -2, 3, -2, 1, -2, +4, -3, -2, 2, 2, -2, 1, 0, +3, -4, 2, -1, -2, 2, 0, 0, +0, 1, -1, 0, -1, 1, -1, 0, +3, -3, 1, -1, 1, -2, 2, -2, +1, 0, -1, 1, 1, -1, 0, 1, +1, -1, 2, -1, 0, 0, 0, 1, +-3, 2, 0, -1, 0, 0, -1, 1, +1, -1, 1, -1, -1, 0, 0, 0, +-4, 4, 0, -1, 1, -1, 1, -1, +-3, 3, -1, 0, 2, -2, -1, 1, +0, 0, -3, 4, -3, 3, -1, 1, +1, -2, 4, -3, 1, -1, 2, -2, +-2, 2, 1, -2, 3, -2, -1, 1, +-1, 1, -2, 2, -1, 1, -1, 0, +2, -3, 1, 0, -1, 1, 0, 0, +-1, 1, 1, -1, 1, -1, 0, 1, +-2, 1, 1, -1, 2, -2, -1, 1, +-1, 0, 3, -2, -2, 2, -1, 1, +-1, 1, 0, 0, -2, 2, 0, -1, +-1, 2, -2, 1, 3, -3, -1, 1, +2, -3, 4, -3, 1, -1, 4, -4, +0, 0, 2, -3, 1, 0, -2, 1, +1, -1, 2, -2, 1, -1, -1, 1, +1, -1, -1, 1, 0, -1, 2, -2, +-1, 1, -1, 0, 1, -1, 1, -1, +-1, 1, -3, 2, 0, -1, 3, -2, +0, 0, 2, -3, 3, -2, 0, 0, +-1, 1, -2, 2, 0, 0, -1, 1, +0, -1, 1, 0, 0, 0, 2, -2, +-1, 2, -2, 1, 3, -2, -1, 2, +0, -1, 1, -1, -1, 0, 4, -5, +3, -2, 0, 0, 1, -1, -1, 1, +1, -1, 2, -1, -2, 2, -1, 1, +-2, 2, 1, 0, -3, 4, -2, 1, +2, -2, 1, -1, 1, -2, 2, -2, +-1, 2, -3, 3, 1, -1, 2, -2, +3, -2, 0, 0, 0, -1, 0, 0, +1, -2, 3, -3, 0, 1, 0, 0, +-1, 1, 0, -1, 3, -2, 0, 0, +-1, 1, -3, 4, -2, 2, 0, 0, +0, 0, 0, 1, -2, 1, 1, -1, +-1, 1, 0, 0, -2, 3, 1, -3, +2, -1, -1, 1, -2, 2, -2, 1, +0, -1, 1, -1, -1, 2, 0, -2, +5, -4, 1, -1, 1, -1, 0, 0, +2, -2, -1, 1, -2, 2, -1, 1, +0, 0, 1, -1, 2, -2, -1, 1, +0, 0, -2, 2, -2, 2, -2, 3, +-5, 5, -3, 2, 2, -2, 1, -1, +2, -2, 3, -3, 2, -1, -2, 2, +2, -3, 1, 0, -1, 1, -3, 4, +-5, 4, 0, 0, -1, 2, -3, 2, +4, -5, 2, -1, -2, 1, 2, -2, +-2, 3, 0, -1, 0, 1, -1, 0, +2, -2, 1, -1, 0, 1, -2, 2, +0, 0, -1, 1, 1, -1, -2, 3, +0, -1, 4, -3, 2, -1, 0, 0, +0, 0, -1, 1, -2, 2, -2, 2, +-1, 1, -1, 1, 1, -1, -2, 3, +-4, 4, -2, 2, -1, 2, -2, 2, +0, 0, 1, -1, -1, 1, 0, 0, +2, -2, 0, 1, 0, 0, 0, 0, +2, -2, 2, -2, 2, -2, 3, -3, +3, -3, 1, -1, 0, 0, -2, 2, +1, -1, 3, -3, 3, -3, 1, -1, +1, -2, 5, -4, 0, 1, -1, 1, +0, 0, -1, 0, 0, 0, -1, 2, +-2, 2, -1, 0, 1, -1, -1, 1, +2, -2, 2, -1, -3, 3, 0, -1, +2, -2, -1, 2, 0, -1, -2, 2, +-4, 3, 2, -2, -2, 3, -4, 3, +-3, 2, 0, 0, 0, 1, 0, 0, +-1, 1, 0, 0, -1, 1, -1, 1, +2, -2, 3, -3, 0, 1, 0, 0, +0, 0, 0, 0, 1, -2, -1, 0, +0, 0, 1, 0, -3, 4, -3, 2, +-1, 0, 3, -4, 3, -1, -4, 3, +1, -1, -1, 2, -4, 4, -1, 1, +0, 1, -1, 0, 2, -2, 2, -1, +-1, 1, 0, -1, 1, -1, 0, 0, +0, 1, 2, -2, 5, -5, 0, 0, +-2, 3, -3, 4, 2, -2, 0, 0, +-3, 2, -2, 2, 0, 1, 1, -1, +-2, 1, -2, 2, -3, 3, 1, 0, +-1, 1, -1, 0, -1, 1, 0, 0, +2, 0, -3, 3, 1, -3, 2, -2, +5, -4, 2, 0, -3, 2, -3, 1, +0, -1, 4, -3, 2, -1, -2, 1, +-3, 1, -2, 2, 0, 1, 2, -1, +-4, 3, -3, 1, 1, 0, 1, 0, +0, 1, -3, 1, -1, 0, -2, 3, +1, 1, -3, 3, -4, 1, -1, 0, +2, -1, 4, -2, 0, 1, -6, 4, +-3, 2, 2, -1, -1, 3, -4, 3, +-2, -1, -2, 2, -1, 4, -3, 5, +-3, 1, -1, -1, -1, 1, 1, 1, +-1, 3, -5, 3, 0, -3, 2, -1, +2, 0, 0, 2, -4, 3, -3, 1, +-2, 4, 0, 1, 2, -1, -4, 2, +-2, 1, -1, 2, 3, -2, 3, -2, +-4, 2, -2, -1, 4, -2, 4, -1, +0, 0, -5, 2, -1, 0, 1, 2, +1, 2, -3, 2, -3, -1, 1, -1, +3, 0, 2, 0, -3, 2, -3, 0, +-3, 3, 2, 1, 2, 0, -2, 0, +-2, -1, 2, -1, 3, 0, 0, 1, +-3, 0, -3, 0, 2, -1, 4, 0, +0, 1, -3, 0, -2, -1, 4, -2, +3, 1, 0, -1, -3, 0, -3, 1, +3, 0, 5, -2, -1, 1, -4, -1, +1, -2, 4, 0, 3, 1, -4, 2, +-4, 0, -2, 2, 4, -1, 3, 1, +-3, -1, -2, -2, -1, 1, 5, -1, +4, -2, 1, -4, -4, 1, 2, -2, +6, -1, 2, -1, -2, -2, -4, 1, +2, 0, 3, 1, -1, 2, -3, -2, +-1, -1, 2, 1, 4, 0, 0, 0, +-4, -2, 1, -3, 4, 1, 0, 4, +-2, -1, -2, -2, -5, 4, 4, 0, +2, 1, -3, 0, -5, 0, 2, -2, +3, 2, 3, -1, -2, -1, -4, -1, +2, 0, 5, 0, 1, 1, -6, 2, +-5, 1, 2, -1, 8, -3, 3, -2, +-5, 0, -1, -2, 6, -2, 5, 0, +-2, 2, -5, -1, 3, -5, 4, 0, +6, -2, -1, -1, -2, -5, 1, -1, +-1, 6, 2, 1, -2, 0, -9, 3, +-2, 1, 6, 0, 3, 1, -4, 0, +-6, 1, -2, 2, 6, 0, 3, 0, +-9, 5, -8, 2, 4, -3, 6, 0, +1, 0, -7, 2, -4, 0, 5, -2, +6, 0, 0, 1, -8, 3, -7, 3, +4, -1, 9, -4, 1, -1, -8, 2, +-3, 0, 5, 0, 4, 1, -1, -1, +-4, -1, -1, 0, 5, 0, 4, 0, +-3, 0, -5, -1, 0, 1, 5, 1, +4, -1, -3, -1, -4, -1, 0, 1, +9, -3, 2, 0, -6, 1, -3, -2, +3, 0, 5, 1, -2, 2, -6, 0, +-4, 1, 1, 2, 5, 0, -2, 1, +-4, -2, -1, -1, 3, 2, 3, 2, +-3, 1, -7, 2, -3, 1, 5, 0, +5, 0, -2, -1, -3, -2, -1, 1, +5, 0, 5, -1, -4, 1, -7, 1, +2, -1, 7, -1, 2, 0, -3, -2, +-3, -2, 4, -1, 5, 1, 0, 1, +-6, 0, -3, -1, 0, 4, 4, 1, +1, -1, -4, -2, -1, -2, 3, 1, +2, 2, 0, -2, -6, 0, -1, -1, +7, -1, 2, 3, -5, 2, -4, -2, +0, -1, 8, -4, 7, -2, -2, -1, +-6, 1, -2, 1, 10, -4, 1, 2, +-5, 0, -5, 0, 1, 0, 8, -2, +-1, 4, -6, 0, -4, 0, 5, -3, +7, -1, 1, -1, -4, -1, -4, 0, +3, 0, 3, 2, -3, 2, -5, -1, +2, -4, 6, -1, 6, -2, 1, -2, +-6, 1, -3, 2, 6, -1, 5, -1, +-2, 0, -8, 3, -1, 0, 6, -2, +3, 0, -5, 1, -6, 1, -1, 1, +4, 1, -1, 3, -7, 3, -6, 3, +0, 3, 4, 2, 1, 1, -6, 1, +-3, -1, 2, 1, 3, 0, 0, -1, +-6, -1, -1, -2, 3, 0, 8, -4, +1, -1, -5, 1, -3, 2, 6, -1, +5, -1, 3, -4, -4, 1, -3, 2, +5, 0, 2, 0, -2, -2, -5, 0, +2, -3, 4, 0, 2, -1, -2, -1, +-4, 1, 1, 2, 4, 0, 4, -2, +0, -3, 3, -5, 4, 0, 3, 2, +-2, 2, -4, -2, 3, -6, 3, 0, +2, 0, -1, -1, -4, -1, 0, -1, +1, 3, 1, 2, -2, 1, -2, -1, +1, 0, 5, -1, 4, -1, -3, 0, +-3, 0, -2, 1, 3, 0, -1, 1, +-2, -2, -4, 0, 0, 0, 2, 1, +1, -1, 1, -4, -2, 1, 1, 1, +4, 1, -2, 3, -2, -1, -1, 0, +-3, 4, 5, -4, 3, -2, -6, 2, +-1, -2, 0, 1, 3, -2, -1, 0, +-2, -1, 1, 0, 4, 0, 3, 1, +-1, 1, -1, -1, 4, -3, 3, 1, +0, 1, -2, 0, -6, 2, -2, 0, +2, -1, 0, 0, -4, 1, -4, 2, +-1, 1, 3, 0, 3, 0, -2, 3, +-3, 4, 2, 1, 3, 1, 1, -1, +-2, 0, -4, 1, -1, 0, -3, 2, +-6, 2, -6, 1, -2, -1, 0, 0, +3, -2, 3, -1, 1, -1, 5, -2, +7, -2, 6, -1, 1, 1, 3, -4, +1, -1, -1, 0, -2, -1, -6, 1, +-6, 0, -3, -1, -3, 2, -2, 2, +0, 1, 1, 0, 4, 0, 4, 3, +4, 1, 3, 0, -1, 2, -1, 1, +0, 0, -6, 3, -8, 0, -4, -3, +-5, -1, 0, -3, -4, 3, -5, 4, +1, 1, 7, -1, 6, 3, 7, -1, +9, -4, 2, 2, -1, 2, 1, -1, +-5, 1, -6, -3, -10, 2, -10, 2, +-3, -2, -4, 1, -3, 1, 0, 2, +6, 1, 9, 1, 9, 0, 9, -2, +8, -2, 5, 0, -2, 3, -5, -1, +-10, 1, -11, 0, -9, 0, -10, 3, +-10, 3, -4, 0, 0, 3, 5, 2, +12, -1, 8, 3, 7, 1, 11, -2, +8, 0, 2, -1, -5, -1, -13, 2, +-13, 2, -12, 1, -7, -4, -6, -4, +-4, 0, 0, 3, 9, -1, 11, 1, +8, 3, 12, -1, 15, -2, 9, 1, +0, 2, -6, 0, -9, -1, -9, -2, +-9, -3, -14, 0, -13, -1, -4, -3, +4, -1, 8, 0, 10, 0, 13, -1, +17, -1, 16, 0, 14, -3, 5, -3, +-4, 0, -9, 0, -10, -1, -16, 1, +-19, 0, -15, -1, -6, -2, 4, -3, +8, -2, 12, -3, 17, -2, 23, -3, +19, 1, 11, 1, 3, 0, 0, -2, +-6, 1, -14, 2, -21, 3, -23, 0, +-17, 1, -12, 3, 0, -2, 2, 1, +9, 0, 15, 2, 23, -1, 22, -2, +13, 0, 4, 2, 1, 0, -4, -1, +-13, 0, -23, 1, -22, -1, -16, -1, +-12, 1, -6, 1, -2, 1, 9, 0, +21, -1, 26, -2, 21, -1, 13, 1, +8, 2, 7, -2, -2, -1, -17, 1, +-23, 0, -25, 3, -19, 1, -13, 0, +-13, 3, -2, -2, 12, -1, 20, 1, +22, 1, 20, -1, 18, -2, 15, 0, +10, -1, -3, -1, -14, -3, -22, 1, +-19, -2, -16, -2, -20, 2, -11, -3, +-2, 0, 10, 2, 17, 3, 17, 3, +18, 0, 22, -2, 18, 2, 7, 3, +-7, 1, -15, 0, -20, 1, -17, -2, +-20, 0, -23, 0, -15, -1, -2, 0, +8, 3, 14, 1, 19, -2, 22, -1, +24, 1, 20, 1, 8, 0, -4, 0, +-12, 0, -15, 0, -20, 0, -23, -2, +-23, -1, -14, -2, 1, -1, 4, 3, +11, 0, 15, 1, 25, -3, 28, -1, +20, -1, 11, -2, -3, 1, -8, 0, +-13, 1, -23, 2, -26, -2, -21, -3, +-15, 3, -6, 2, 6, -4, 11, -3, +16, 1, 25, 0, 27, -1, 18, 0, +8, 1, 0, 1, 1, -3, -13, 3, +-23, 0, -24, -2, -22, 1, -15, 3, +-8, 1, -2, 0, 7, -2, 21, -4, +27, -1, 21, 2, 15, 0, 13, -3, +5, 2, 0, 0, -10, 0, -20, -2, +-20, -2, -20, 2, -13, 0, -9, -2, +-3, -3, 6, -1, 17, -1, 22, 0, +20, -2, 18, -2, 12, 2, 8, 1, +3, -2, -12, 0, -17, -2, -18, 1, +-16, -1, -11, -3, -17, 3, -4, -3, +6, 1, 13, 1, 18, -1, 16, -1, +18, -3, 18, -1, 12, -1, 2, -1, +-11, 0, -14, 0, -16, 3, -16, 1, +-18, 1, -17, 2, -8, 3, 4, 2, +7, 4, 9, 3, 11, 2, 17, -1, +18, 1, 5, 5, -2, 0, -8, 1, +-8, -1, -8, -3, -13, -3, -16, -1, +-14, 0, -4, 0, 5, -1, 7, 0, +9, -2, 17, -3, 19, 0, 15, 0, +9, -2, 2, -1, -3, -1, -3, -2, +-10, 1, -14, -3, -15, -2, -7, -2, +-5, 3, -6, 5, -1, 3, 5, 1, +9, 3, 16, -1, 15, -1, 3, 2, +2, 0, 0, 1, -1, -4, -8, -2, +-14, 1, -14, 1, -7, -2, -1, -2, +-2, -1, 0, -1, 4, 2, 12, 0, +15, -4, 10, 0, 4, 2, 7, -4, +3, 0, -4, 4, -10, -1, -8, -5, +-6, 0, -5, -2, -2, -5, -5, 2, +0, 0, 8, -4, 12, -1, 8, 2, +6, -2, 8, -2, 10, -1, 5, -4, +0, -3, -5, 1, -9, 1, -8, 0, +-7, 5, -12, 4, -5, -3, 1, 2, +5, 1, 7, -5, 8, -1, 5, 3, +5, -1, 4, 2, 3, 2, -2, -3, +-4, -2, -1, 2, -5, 0, -6, -3, +-7, 3, -5, 1, 0, -3, 4, 2, +6, -3, 8, -8, 6, 1, 5, 5, +5, -5, 5, -4, 1, 2, 2, -6, +-1, -2, -5, 6, -8, 0, -7, -2, +-5, 7, -2, 2, 1, -5, -2, 5, +3, 2, 6, -6, 4, 4, 1, 5, +3, -7, 1, -2, 1, 6, -4, 0, +-7, 1, -5, 5, 0, -5, 1, -7, +-1, 6, -2, 1, 1, -8, 3, 3, +4, 3, 4, -7, 3, 0, 2, 5, +2, -6, 2, -1, 0, 5, -1, -4, +-6, -1, -3, 9, -1, -1, -1, -7, +-5, 8, -2, 3, 2, -8, 1, 5, +-1, 7, -2, -5, 2, 0, 6, 3, +7, -11, 2, -5, 3, 6, 0, -5, +1, -6, -3, 9, -3, 0, -2, -8, +-2, 8, -1, 4, 2, -11, 2, 2, +0, 8, 1, -7, 2, -1, 3, 8, +1, -8, 2, -5, -2, 11, -2, -1, +-4, -7, 1, 6, -1, 0, 0, -10, +-2, 7, 1, 3, 2, -13, 2, 3, +-3, 13, -1, -7, 2, -2, 0, 12, +0, -4, -2, -3, 0, 10, -1, -3, +-3, -7, -1, 8, -3, 5, -6, -10, +3, 3, -1, 6, 2, -11, 0, 1, +3, 10, 1, -10, 4, -4, 4, 9, +2, -5, 0, -8, 1, 10, 0, -3, +-1, -11, -3, 10, -3, 3, 2, -15, +0, 5, 0, 9, 1, -14, 5, -1, +2, 9, 7, -11, 0, -4, 0, 16, +-4, -3, 5, -13, 1, 9, -3, 2, +-3, -13, 0, 7, 1, 2, 0, -13, +-3, 6, 3, 6, 3, -10, 0, -1, +5, 11, 0, -8, 5, -7, 0, 12, +3, -4, -2, -12, -1, 13, -7, 3, +2, -14, -4, 7, 1, 5, -2, -12, +2, 3, 1, 11, 4, -12, 2, -2, +3, 11, 4, -6, -2, -5, 3, 11, +-3, -2, -1, -9, -8, 12, -1, 5, +-6, -12, 0, 6, -4, 9, 4, -12, +-1, 1, 2, 13, 0, -9, 7, -6, +0, 14, 0, -3, -1, -8, -2, 12, +0, -1, -1, -14, 0, 7, -8, 8, +-1, -12, -2, 3, 1, 12, -3, -10, +6, -2, 0, 11, 9, -9, 0, -5, +5, 11, 0, -6, 2, -9, -5, 11, +-2, 4, -6, -12, -3, 7, -6, 9, +1, -14, 3, 0, 0, 9, 6, -11, +4, -6, 7, 11, 0, -6, 7, -9, +-1, 9, 4, 0, -6, -9, 1, 7, +-6, 2, 0, -11, -6, 4, 2, 6, +-1, -11, 2, 0, -1, 11, 6, -7, +3, -3, 3, 9, 3, -2, -1, -8, +4, 8, -6, 4, -1, -9, -9, 7, +0, 5, -6, -9, 0, 3, -4, 6, +3, -6, 0, -4, 10, 6, 1, -3, +5, -6, 1, 9, 3, 1, -1, -8, +-3, 7, -2, 2, -3, -10, -4, 5, +-4, 4, 2, -10, -2, -4, 4, 9, +-3, -4, 9, -7, 0, 9, 8, -2, +2, -8, 7, 7, -4, 4, 2, -10, +-5, 3, -1, 4, -3, -9, -4, 0, +-1, 4, -4, -2, -1, -3, 4, 6, +4, -2, 2, -7, 7, 7, 4, -1, +6, -7, -8, 8, 2, 3, -2, -11, +0, 2, -9, 8, 1, -8, -7, -2, +1, 8, -4, 0, 0, -3, 2, 6, +6, -1, 4, -7, 5, 3, 5, 3, +-2, -7, 2, 1, -3, 6, -3, -4, +-7, -4, 1, 6, -7, -4, 5, -7, +-3, 7, 3, 1, -5, -3, 7, 5, +4, 2, 8, -11, 2, 3, -4, 12, +-3, -7, -1, -1, -3, 8, -5, -6, +-3, -3, -5, 9, 1, -2, -5, -5, +3, 8, -2, 3, 8, -9, 0, 7, +6, 4, -1, -7, -1, 5, -3, 7, +-2, -3, -5, -4, -2, 9, -7, -1, +-4, -4, -3, 8, -1, 1, 0, -7, +3, 4, 6, 4, 2, -9, 2, 6, +-1, 8, 3, -6, -3, -1, -1, 11, +-7, -5, 0, -5, -5, 8, 0, -1, +-5, -8, 3, 5, 1, 2, 4, -10, +3, 5, -1, 10, 5, -12, 4, 0, +3, 8, -2, -6, -1, -3, -5, 11, +-5, 0, -5, -9, 1, 7, -3, 0, +-1, -6, -1, 6, 4, 4, 2, -11, +5, 3, 1, 9, 0, -5, -1, 0, +1, 9, -1, -6, -3, -6, -2, 11, +-5, -2, -1, -9, -3, 8, 4, 0, +1, -12, 1, 8, 1, 5, 3, -7, +-1, 2, 4, 10, -2, -8, 3, -4, +-4, 12, 2, -8, -4, -7, -3, 9, +-2, -1, 0, -12, 2, 7, -1, 5, +2, -12, 3, 2, 8, 5, 4, -12, +1, 2, -2, 11, 1, -8, -1, -6, +-1, 11, -1, -6, -1, -10, -5, 13, +-1, 1, 0, -11, 0, 7, 2, 7, +1, -11, 4, 2, 1, 11, 3, -12, +3, -5, 1, 13, 0, -9, 3, -10, +-4, 13, -1, -3, -1, -11, 1, 9, +1, 1, 0, -12, 3, 5, 5, 5, +5, -14, -4, 7, 0, 11, 3, -12, +1, -4, -1, 12, -2, -5, -5, -8, +-1, 12, -4, 2, -3, -10, -1, 8, +3, 4, 1, -13, 2, 6, 1, 10, +1, -12, 2, -2, 1, 14, 1, -11, +-1, -5, -5, 14, 1, -7, 0, -12, +-1, 12, 0, -1, 1, -15, 1, 9, +1, 8, 3, -15, 1, 4, 2, 11, +0, -10, 2, -3, 1, 12, -3, -6, +-4, -6, -1, 15, -5, 1, -4, -9, +-2, 11, 2, 1, 0, -13, 1, 9, +1, 8, 3, -16, 2, 1, 4, 11, +0, -11, 0, -5, 1, 12, 1, -10, +0, -9, -3, 15, 0, -4, -3, -11, +-1, 14, -1, 6, 2, -16, 3, 5, +-1, 13, 0, -14, 3, 0, 1, 13, +2, -15, 3, -8, 0, 14, -1, -6, +-3, -11, -2, 17, -5, 1, 3, -15, +-3, 13, 2, 7, -1, -17, 8, 3, +2, 9, 5, -16, -3, 1, 3, 12, +0, -12, -1, -5, -3, 16, -5, -2, +-3, -11, 0, 14, 3, -2, -1, -14, +1, 12, -3, 9, 4, -16, 0, 5, +1, 14, -5, -14, 5, -2, -6, 18, +4, -14, -4, -7, 1, 15, 0, -8, +3, -13, 2, 12, -1, 4, 0, -17, +4, 9, 2, 8, -2, -14, 1, 5, +1, 11, 3, -15, 0, -4, 0, 17, +-3, -12, 3, -10, -2, 16, 4, -6, +-2, -12, 3, 11, 0, 4, -2, -14, +4, 8, -1, 8, 2, -16, -3, 5, +4, 12, -4, -14, 2, -2, -5, 15, +7, -13, -4, -8, 3, 17, -4, -4, +4, -14, 0, 12, 5, 3, -2, -16, +2, 9, 0, 7, 4, -19, -1, 6, +-3, 13, 1, -14, -2, -5, 6, 14, +-8, -5, 3, -9, -6, 17, 2, 1, +-5, -12, 9, 10, -1, 0, 6, -17, +-3, 9, 1, 12, -5, -15, 3, 1, +-3, 14, -1, -13, 1, -4, -4, 18, +1, -9, -2, -8, 3, 15, 0, -4, +4, -14, -4, 15, 0, 7, -1, -17, +3, 8, -6, 12, 1, -17, 0, 1, +-1, 13, 2, -15, -1, -5, 1, 16, +-3, -6, 4, -9, 0, 13, 1, 3, +-7, -11, 9, 8, -3, 3, 3, -13, +-7, 8, 2, 9, -6, -13, 0, 3, +-2, 10, 1, -10, -2, -4, 4, 12, +-1, -3, -2, -7, 2, 14, -1, -3, +5, -12, -5, 12, 3, 5, -7, -12, +4, 5, -2, 5, 4, -12, -6, 0, +6, 10, -5, -9, 8, -7, 0, 11, +6, -9, -1, -7, 2, 11, 3, -3, +1, -13, -2, 12, -5, 5, 1, -13, +-5, 6, 1, 8, -5, -10, 3, 0, +-4, 13, 3, -10, 1, -4, 1, 13, +3, -7, 2, -8, 3, 9, 2, -4, +3, -12, -5, 10, 0, 6, -9, -7, +1, 5, -5, 7, 1, -7, -5, 1, +6, 9, 0, -10, 6, -4, 0, 9, +2, -2, 0, -10, 3, 10, -3, 0, +-1, -8, -3, 8, -3, 3, 0, -10, +-3, 5, 0, 8, -2, -10, 5, 0, +-3, 10, 4, -6, -3, -2, 4, 10, +-2, -6, 5, -6, -4, 8, 1, 2, +-5, -8, 3, 4, -4, 4, 1, -10, +-2, 5, 1, 4, 5, -10, 0, 0, +4, 7, -3, -4, 4, -3, -3, 10, +0, -1, -4, -4, 0, 7, -3, -1, +0, -8, -2, 6, -2, 3, 0, -8, +-1, 3, -1, 8, -1, -7, 8, -4, +2, 5, 6, -8, 2, -4, 0, 10, +-3, -4, 3, -5, -5, 7, 1, -2, +-3, -6, 1, 5, -5, 5, -2, -3, +1, 1, 3, 6, 0, -7, 4, 0, +-1, 8, 2, -5, -1, 1, -3, 6, +2, -4, -6, -2, -3, 9, -5, -2, +6, -8, -4, 4, 7, -2, 1, -9, +5, 2, 1, 2, 5, -6, 0, 1, +2, 4, 0, -3, -2, 0, 0, 4, +-3, -1, 0, -5, -1, 4, 1, -3, +0, -5, 0, 2, 4, -2, 2, -6, +3, 1, 2, 3, 1, -2, -3, 4, +-2, 6, -1, -2, -1, -2, 1, 2, +-4, 0, -1, -4, 0, 3, -2, 1, +-1, -4, 3, 0, 3, 0, 0, -3, +3, 2, 0, 2, 5, -6, 1, 0, +1, 4, -1, -5, -1, 1, -5, 5, +-2, 0, -4, 0, 1, 0, 1, 0, +-3, -2, 6, -1, 0, 2, 4, -5, +0, 2, 4, 0, 3, -5, 1, 0, +-3, 6, -7, 3, -3, 0, -2, 4, +-2, -1, -2, -1, 0, 2, 1, 0, +0, -2, 2, 3, 0, 0, 7, -6, +0, 3, -1, 5, -2, -2, 2, -1, +0, 0, -3, 1, -2, -2, 1, 0, +-1, -1, -4, 2, 2, 1, 0, 0, +1, -2, 0, 3, 2, 0, 1, -1, +-1, 3, 2, -1, -2, -1, -3, 3, +1, -1, 1, -3, -2, -1, 0, 1, +1, -3, 3, -3, -1, 4, -1, 0, +2, -2, 2, 1, 3, -1, -1, -2, +2, 0, 1, 0, -2, 1, -4, 3, +1, -1, -1, -2, -1, 0, -2, 4, +-2, -1, 1, -1, -1, 4, 1, -2, +4, -4, 1, 1, 0, 1, -4, 1, +3, -1, -2, 2, 0, -3, -4, 4, +-4, 3, 1, -3, -1, 1, -1, 3, +-2, 0, 3, -3, 2, 2, 2, -3, +4, -4, -2, 4, 2, -3, 1, -2, +0, 1, 0, -1, -2, -1, 0, 0, +-3, 4, -2, -1, -1, 1, 0, 2, +0, -1, 3, -1, 0, 2, 3, -3, +1, -3, 4, -1, 0, 0, -1, -2, +2, -1, 2, -2, 0, 0, -5, 3, +0, 1, -3, 0, 2, -1, 0, 2, +3, -4, 3, -2, 0, 1, 1, 0, +-1, -1, 3, 0, -1, -2, -1, 1, +-3, 2, 2, -1, 1, -3, 1, -1, +1, 1, -2, 0, 0, 1, -2, 3, +3, -4, 3, -3, 0, 2, 3, -5, +0, -1, 0, 1, -1, 0, 1, -1, +-1, -1, 3, -2, 0, -3, 4, -2, +2, -1, 0, -1, 1, -1, 1, 0, +1, 1, -4, 1, 2, 1, -5, 2, +1, -1, -1, 1, -3, 3, -4, 1, +-1, 0, 3, -2, -2, 0, 2, 0, +-1, 0, 2, -1, 0, -2, 6, -4, +3, -3, -2, 2, 1, -1, 1, -2, +3, -2, 0, -2, 5, -3, -1, -2, +2, 1, -3, 2, 1, -1, 0, 1, +-1, 1, 2, 0, -1, -1, 3, 1, +-3, 0, 1, 2, -4, 2, 1, -1, +1, -2, -1, 1, -2, 3, -2, -1, +4, 0, -6, 3, 3, -1, -1, 0, +2, 1, 0, -3, 3, -2, -1, 1, +-2, 0, 3, 0, -3, 0, 1, 1, +-3, 0, 2, 2, -5, 3, 0, 2, +0, -1, 2, -2, 1, 1, -2, 0, +0, 2, -3, 0, 5, -3, -2, 1, +-4, 4, 0, -2, 1, -1, 0, 2, +-2, 0, 4, 0, -4, 0, 8, -3, +-3, 1, 5, -2, 0, -1, 2, 0, +1, -1, -1, 1, 2, 0, -3, 0, +2, 2, -3, 1, 4, -1, -3, 1, +0, 3, -1, 0, -2, 3, 2, 1, +-3, 3, 1, 1, 1, -2, 7, -3, +-1, -2, 4, 0, 1, -1, 0, 1, +3, -1, 1, 1, 2, 0, -1, 0, +5, 1, 0, -1, 3, 1, -1, 2, +3, -1, 2, -1, 2, 1, 4, 0, +-3, 1, 4, 3, -4, 4, 5, -2, +1, 1, 4, 2, 4, -4, 4, 0, +5, 1, 1, -2, 5, 1, 0, 1, +7, 1, -3, 1, 8, 0, -2, 2, +4, -1, 4, 0, 5, 0, 7, -3, +1, 3, 8, -1, 5, -5, 11, -4, +6, -1, 8, -4, 6, -3, 5, 1, +8, -3, 0, 2, 9, -1, 3, 1, +5, 0, 3, 2, 6, 2, 4, -2, +6, 1, 5, 3, 3, -2, 10, -2, +3, 3, 5, 2, 3, -1, 10, 1, +4, 0, 7, -1, 5, 4, 5, 0, +11, -5, 8, -1, 12, -1, 5, -2, +10, 2, 5, 2, 9, -3, 6, 2, +4, 5, 7, -1, 7, -2, 10, 4, +2, 2, 12, -3, 8, -1, 14, -3, +6, -1, 11, 1, 9, 1, 9, -2, +11, -1, 9, 1, 9, -1, 6, 2, +9, 3, 8, -1, 11, -1, 11, 2, +10, -1, 9, 0, 10, 1, 10, 2, +8, -2, 15, 1, 8, 3, 11, -1, +9, 2, 12, 1, 14, -7, 14, -3, +10, 6, 10, -1, 10, 4, 11, 0, +18, -4, 8, 0, 13, 3, 12, 0, +10, 1, 12, 4, 13, 0, 13, -2, +11, -1, 17, 0, 10, -2, 15, 1, +11, 4, 17, -4, 12, 2, 13, 2, +16, -2, 13, -4, 16, 5, 7, 5, +18, -2, 12, 4, 18, -1, 14, -3, +13, 2, 14, 3, 13, -1, 18, 0, +16, 3, 16, 0, 13, 1, 14, 4, +17, -2, 16, -4, 23, -1, 17, 1, +17, 1, 14, 3, 19, 0, 18, -7, +20, -2, 17, 3, 18, -2, 16, 6, +12, 8, 19, 0, 17, -3, 21, 1, +18, -3, 23, -5, 20, 4, 17, 4, +22, -4, 19, 0, 22, -1, 20, -7, +21, 0, 18, 4, 20, 0, 19, 2, +21, 3, 19, -2, 21, -6, 23, 0, +21, 0, 20, -1, 24, 3, 19, 4, +18, 1, 19, -1, 22, 2, 16, -2, +24, 1, 20, 6, 25, -2, 24, -1, +25, -1, 24, -4, 19, -1, 23, 2, +22, 1, 25, -2, 23, 6, 23, 0, +28, -9, 24, -3, 27, -3, 24, -3, +23, 5, 24, 5, 27, -4, 28, -3, +23, 0, 27, -4, 22, -2, 26, 5, +24, 2, 28, 0, 22, 6, 24, 0, +24, -5, 22, 1, 27, 0, 25, 0, +25, 4, 26, 6, 25, -1, 27, -4, +27, -3, 30, -5, 24, -1, 29, 5, +28, 2, 26, 1, 25, 3, 23, -1, +29, -8, 25, 0, 29, 5, 24, 2, +30, 4, 28, 2, 29, -3, 25, -4, +28, 0, 29, -3, 30, -1, 28, 9, +24, 6, 28, -5, 31, -4, 29, -5, +30, -5, 24, 4, 29, 9, 29, -1, +32, 1, 28, 1, 29, -6, 27, -2, +28, 1, 31, 3, 25, 2, 35, 5, +27, -1, 31, -5, 24, 0, 31, -2, +27, -1, 31, 2, 34, 6, 29, 0, +30, 1, 27, 1, 32, -9, 33, -5, +26, 8, 30, 8, 23, 5, 35, 5, +24, 0, 31, -6, 26, 0, 31, 1, +31, -1, 27, 9, 33, 8, 26, -1, +34, -4, 30, -4, 37, -8, 31, -2, +32, 8, 31, 5, 30, -1, 33, 3, +28, -5, 34, -9, 27, 2, 35, 2, +32, 2, 31, 6, 34, 5, 31, -9, +37, -7, 29, -2, 37, -3, 27, 3, +36, 8, 34, 1, 31, -3, 33, -1, +30, -5, 33, -5, 28, 4, 35, 8, +29, 2, 35, 4, 30, 3, 37, -14, +35, -7, 30, 4, 32, 2, 29, 7, +31, 10, 35, -2, 29, -7, 34, -2, +29, -4, 37, -5, 28, 7, 37, 9, +32, -4, 37, -1, 31, -2, 35, -10, +32, -5, 33, 7, 31, 5, 31, 3, +32, 7, 31, -2, 31, -10, 35, -3, +31, 1, 35, -2, 31, 10, 31, 10, +30, -1, 30, -3, 34, -2, 30, -8, +39, -6, 32, 8, 33, 6, 28, 0, +34, 2, 29, -3, 32, -11, 32, 2, +28, 5, 36, 0, 33, 6, 32, 8, +28, -6, 35, -9, 36, -3, 30, -3, +34, 2, 27, 14, 32, 4, 31, -5, +31, -1, 32, -6, 27, -4, 32, 5, +29, 5, 36, 2, 26, 6, 35, 2, +26, -9, 33, -5, 28, 5, 31, -1, +33, 3, 32, 8, 35, 0, 25, -7, +32, -3, 29, -4, 33, -4, 29, 9, +28, 7, 35, -1, 26, 2, 34, -1, +27, -10, 32, 0, 27, 6, 32, 1, +30, 4, 28, 9, 32, -3, 23, -8, +32, -2, 29, -4, 34, 0, 25, 12, +30, 8, 33, -8, 28, -5, 35, -6, +29, -6, 32, -2, 29, 5, 28, 5, +29, 3, 28, 3, 30, -7, 23, -6, +29, 4, 23, 3, 34, 0, 27, 10, +30, 6, 27, -12, 27, -7, 29, 2, +29, -4, 33, -2, 21, 12, 27, 4, +29, -4, 27, -2, 28, -9, 27, -3, +26, 3, 25, 1, 28, 4, 28, 10, +31, -2, 24, -12, 23, -6, 28, 5, +28, 0, 27, 2, 23, 10, 26, 2, +24, -7, 25, -5, 28, -4, 28, -3, +25, 6, 20, 3, 29, 1, 28, 5, +27, -2, 21, -10, 19, -2, 26, 2, +30, 1, 24, 6, 22, 6, 25, -6, +24, -8, 19, 1, 28, -3, 27, -4, +26, 11, 14, 8, 21, -4, 29, -4, +30, 1, 21, -5, 15, -5, 20, 3, +26, 10, 20, 14, 14, 0, 20, -5, +22, -1, 19, 1, 23, -5, 22, -1, +29, 16, 12, 6, 19, -17, 19, -1, +28, 15, 18, -2, 16, -12, 16, 2, +23, 13, 28, 2, 21, -15, 20, -4, +20, 3, 21, -4, 25, -11, 20, 7, +24, 15, 16, -2, 15, -17, 18, -4, +31, 12, 17, -1, 16, -4, 11, 4, +17, 3, 25, -2, 19, -3, 17, 0, +17, -3, 18, -4, 12, 7, 19, 8, +26, -3, 13, 1, 11, -7, 11, -1, +27, 2, 24, -1, 12, 10, 4, 3, +17, -15, 22, -1, 16, 13, 13, 0, +12, -2, 12, 3, 11, 4, 17, 0, +21, -5, 19, 2, 5, 5, 1, -6, +22, 3, 23, 14, 13, 6, 0, -6, +9, -14, 21, 0, 25, 7, 11, -3, +10, 4, 14, 7, 14, -10, 10, -7, +16, 4, 20, 5, 14, -3, 3, -15, +9, 9, 24, 16, 21, -3, 1, -9, +-3, -7, 14, -4, 29, 6, 15, 7, +-3, 11, 5, 4, 20, -20, 14, -8, +11, 6, 11, 3, 16, 4, 2, 2, +-1, -2, 20, 0, 27, 3, 7, 3, +-10, -11, 10, -24, 25, 13, 20, 28, +1, -3, 2, -10, 7, -8, 14, 1, +9, 0, 15, -10, 14, 14, 0, 19, +-1, -18, 16, -17, 27, 12, 8, 10, +-9, -10, 1, -26, 18, 10, 21, 33, +6, -1, 0, -14, -1, -6, 10, -8, +12, 2, 14, 3, 9, 9, -2, 14, +3, -18, 10, -14, 17, 13, 11, 0, +3, -4, -9, -8, 6, -8, 23, 18, +19, 15, -5, -3, -13, -16, 9, -21, +19, 8, 12, 19, -2, -3, 3, 4, +8, -3, 6, -18, 4, -1, 18, 3, +10, 10, -15, 2, -13, -24, 24, 9, +31, 33, -5, -2, -25, -27, 9, -20, +27, 7, 11, 20, -15, 1, 1, 5, +10, 8, -4, -19, -4, -10, 21, 13, +17, 8, -9, -5, -22, -20, 16, 3, +31, 32, 3, 1, -26, -19, 2, -17, +19, -6, 8, 20, -4, 16, 3, -5, +5, -3, -10, -12, 3, -5, 19, 13, +12, -3, -14, 3, -18, -1, 18, -20, +20, 19, -1, 23, -12, -10, 3, -25, +4, -22, 2, 22, 6, 35, 9, -11, +-5, -13, -20, 5, 8, -6, 24, 1, +7, 3, -20, 10, -11, -1, 13, -26, +10, 15, 5, 36, -5, -13, 3, -32, +-9, -11, 5, 12, 16, 21, 13, -6, +-14, -4, -13, 7, 8, -21, 15, -3, +0, 24, -8, 4, -2, -14, 0, -21, +1, 16, 12, 37, 13, -16, -10, -28, +-27, 0, 6, 0, 31, 13, 8, 16, +-29, -5, -6, -7, 21, -16, 14, -5, +-12, 17, -3, -4, 11, -3, -4, 1, +-18, -5, 10, 16, 30, 14, -8, -11, +-33, -27, -1, -24, 36, 32, 13, 47, +-25, -26, -14, -33, 19, 12, 15, 11, +-6, -9, -6, -15, 6, 12, -2, 25, +-8, -24, 6, -9, 13, 37, 0, 4, +-19, -34, -8, -28, 13, 25, 13, 54, +-1, -9, -12, -36, -7, 3, 6, 2, +18, 1, 5, 6, -15, -7, -15, 6, +8, 5, 18, 5, -3, 9, -9, -16, +-2, -11, 11, 2, -3, -9, -2, 15, +10, 31, 3, 1, -14, -27, -16, -28, +19, 17, 21, 44, -9, -21, -25, -36, +3, 27, 24, 26, 9, -9, -15, -28, +-6, -7, 8, 22, 3, -11, -4, 0, +-3, 39, 8, 2, -3, -29, -12, -18, +4, 8, 12, 30, 7, -4, -17, -15, +-13, 20, 4, 2, 15, -2, -3, 16, +-16, -5, -11, -20, 9, -6, 13, 27, +-3, 37, -5, -23, -7, -32, -3, 21, +2, 12, 3, -9, -3, 3, -10, 16, +-6, 20, -1, -20, 9, -21, -3, 41, +-8, 16, -9, -41, -1, -13, 1, 35, +0, 44, -1, -10, -10, -37, -16, 12, +-3, 20, 16, -7, 5, 6, -25, 9, +-18, 8, 13, 4, 17, -12, -16, 11, +-23, 14, 4, -14, 10, 3, -20, 12, +-17, 15, 16, 20, 12, -9, -31, -19, +-27, 2, 18, 13, 29, 23, -29, 4, +-45, -12, 7, 16, 29, 13, -13, 2, +-38, 4, -2, -12, 16, 7, -10, 22, +-24, 5, -2, 9, 12, 0, -15, -2, +-25, 7, -6, -12, 16, 8, -7, 39, +-24, 3, -24, -19, 7, -5, 8, 26, +-13, 29, -24, -27, -20, -23, 2, 42, +0, 37, -11, -5, -29, -17, -9, -6, +6, 34, -17, 13, -27, -32, -8, 18, +8, 53, -26, 9, -39, -35, -11, -10, +21, 65, -16, 30, -52, -61, -25, -10, +17, 74, 7, 45, -47, -37, -42, -46, +5, 46, 15, 65, -44, -38, -43, -33, +9, 68, 4, 50, -49, -44, -42, -49, +28, 61, 3, 77, -62, -60, -47, -52, +21, 83, 5, 72, -60, -38, -42, -57, +3, 52, -5, 73, -37, -55, -29, -40, +-3, 92, -23, 57, -51, -72, -22, -42, +11, 91, -24, 77, -66, -82, -36, -51, +16, 121, -18, 67, -68, -87, -31, -33, +12, 102, -39, 55, -71, -92, -7, -24, +20, 148, -60, 38, -88, -126, 4, -5, +33, 139, -60, 30, -96, -108, -9, -1, +21, 140, -50, 13, -82, -100, -9, 36, +2, 106, -70, -13, -66, -71, 6, 35, +-1, 106, -82, -1, -64, -82, 8, 28, +-10, 88, -76, 1, -52, -43, -8, 17, +-48, 78, -70, 19, -28, -41, -8, 35, +-67, 57, -74, -20, -16, -15, -8, 49, +-76, 55, -82, -4, -11, -18, -18, 43, +-77, 30, -77, -19, 2, 30, -21, 52, +-108, -10, -78, -9, 18, 45, -13, 59, +-125, -9, -83, -40, 13, 50, -17, 71, +-110, -13, -72, -12, -4, 43, -41, 37, +-93, -10, -55, -12, -12, 61, -57, 51, +-101, -34, -57, 0, -12, 69, -48, 38, +-98, -20, -64, -6, -29, 53, -55, 39, +-86, -13, -50, 29, -44, 61, -88, -10, +-76, -11, -29, 48, -41, 49, -102, 8, +-82, -10, -34, 34, -54, 41, -79, 13, +-66, 28, -60, 11, -80, -7, -63, 49, +-49, 49, -68, -14, -77, 13, -81, 61, +-71, 17, -60, -26, -39, 35, -78, 82, +-112, -12, -66, -32, -31, 71, -63, 51, +-107, -14, -81, 20, -60, 29, -55, 6, +-74, 37, -91, 53, -87, 5, -56, -11, +-58, 44, -99, 37, -77, -14, -43, 42, +-88, 60, -119, -26, -63, 11, -31, 82, +-96, 14, -118, -19, -70, 45, -49, 39, +-82, -12, -88, 34, -78, 70, -88, -13, +-79, -19, -76, 78, -75, 31, -83, -29, +-85, 58, -89, 53, -78, -40, -70, 25, +-96, 106, -93, 0, -74, -51, -87, 66, +-106, 82, -69, -28, -52, 11, -119, 81, +-119, -13, -41, -29, -46, 92, -139, 56, +-119, -49, -38, 22, -66, 92, -123, 2, +-103, -35, -50, 65, -83, 73, -110, -29, +-104, -13, -75, 78, -64, 67, -92, -9, +-119, -30, -104, 40, -55, 93, -74, 18, +-113, -50, -115, 51, -82, 103, -62, -31, +-85, -57, -102, 108, -106, 97, -68, -99, +-82, -33, -116, 177, -86, 63, -62, -129, +-113, 19, -140, 174, -51, 1, -48, -106, +-132, 77, -125, 140, -45, -42, -93, -77, +-131, 95, -54, 117, -66, -35, -165, -50, +-103, 65, 9, 88, -97, 8, -195, -29, +-67, 26, 4, 66, -134, 28, -165, -15, +-34, 26, -46, 75, -155, 32, -128, -37, +-43, 12, -56, 108, -118, 38, -127, -68, +-101, 17, -46, 121, -51, 29, -140, -70, +-147, 26, -41, 122, -30, 7, -143, -73, +-135, 64, -44, 124, -63, -22, -132, -77, +-111, 69, -49, 137, -74, -14, -121, -92, +-112, 62, -58, 132, -50, -15, -123, -64, +-142, 69, -61, 111, -25, -25, -133, -65, +-135, 97, -39, 112, -58, -57, -155, -52, +-91, 107, -7, 96, -118, -52, -160, -45, +-31, 113, -23, 83, -172, -81, -128, 1, +18, 137, -71, 29, -199, -86, -84, 30, +31, 145, -106, 13, -191, -95, -65, 59, +12, 123, -102, -24, -170, -37, -63, 74, +-8, 54, -95, -18, -161, 6, -61, 63, +-2, 32, -104, -10, -161, 28, -48, 25, +4, 13, -114, 50, -149, 10, -38, -16, +-23, 64, -127, 46, -113, -24, -27, 22, +-63, 72, -126, 2, -76, -37, -36, 81, +-87, 85, -105, -79, -58, 2, -77, 144, +-83, -26, -59, -67, -69, 127, -102, 60, +-80, -113, -34, 35, -78, 181, -100, -58, +-65, -136, -51, 182, -96, 130, -77, -198, +-35, 8, -78, 248, -109, -63, -59, -170, +-19, 164, -88, 153, -117, -152, -46, -34, +-26, 200, -102, -20, -98, -124, -10, 148, +-63, 78, -126, -148, -58, 63, 7, 163, +-92, -94, -134, -61, -26, 163, -11, 31, +-99, -131, -108, 80, -25, 155, -44, -106, +-89, -50, -86, 179, -34, -14, -34, -103, +-89, 129, -85, 50, -43, -112, -18, 66, +-77, 132, -115, -91, -41, -54, 4, 180, +-80, 12, -119, -165, -27, 132, -5, 157, +-91, -176, -112, -28, -14, 220, -7, -17, +-109, -149, -93, 105, 2, 131, -27, -113, +-113, -25, -63, 161, -9, -43, -43, -87, +-84, 146, -63, 24, -27, -112, -42, 92, +-79, 88, -53, -107, -26, 11, -55, 144, +-81, -39, -27, -92, -22, 116, -87, 67, +-63, -121, -7, 44, -45, 138, -90, -98, +-34, -44, -19, 166, -58, -19, -65, -124, +-35, 110, -34, 97, -55, -117, -54, -7, +-53, 173, -39, -40, -31, -132, -58, 150, +-74, 82, -7, -156, -15, 31, -103, 157, +-57, -60, 18, -89, -38, 108, -109, 64, +-27, -88, 8, 9, -77, 96, -81, -21, +8, -29, -21, 66, -114, -9, -19, -34, +16, 85, -84, 19, -93, -71, 21, 41, +-1, 83, -119, -32, -54, -60, 36, 72, +-36, 66, -106, -77, -24, -17, 20, 80, +-49, 21, -77, -33, -45, -33, 7, 48, +-21, 92, -98, -66, -53, -73, 27, 145, +-34, 42, -84, -151, -46, 35, 9, 159, +-27, -56, -100, -132, 0, 114, -1, 132, +-84, -160, -21, -49, -17, 199, -61, -29, +-31, -134, -8, 86, -50, 87, -50, -58, +-16, -52, -24, 65, -49, 49, -18, -58, +-29, 2, -71, 28, 2, -6, 22, 61, +-113, -37, -79, -83, 81, 137, 6, 57, +-170, -177, -45, 8, 132, 198, -45, -31, +-197, -213, 24, 80, 122, 254, -117, -156, +-146, -222, 68, 243, 61, 137, -118, -236, +-100, -59, 60, 207, 2, 58, -105, -195, +-9, -21, -5, 202, -61, -31, 12, -120, +-35, 34, -70, 49, 9, 57, -15, -55, +-40, -102, -65, 127, -2, 96, 27, -156, +-97, -51, -24, 158, 35, 22, -48, -147, +-61, 2, 4, 153, -8, -36, -47, -139, +-44, 130, -26, 53, 34, -175, -24, 111, +-130, 104, 16, -219, 119, 26, -126, 249, +-144, -132, 100, -233, 75, 237, -130, 186, +-147, -307, 114, -99, 102, 323, -181, 46, +-123, -340, 141, 2, 53, 402, -173, -127, +-77, -382, 92, 301, 50, 209, -126, -342, +-85, 8, 71, 205, 46, -82, -94, -43, +-92, 5, 68, -1, 39, 63, -91, -43, +-65, -35, 36, 29, 38, -11, -71, 83, +-87, -56, 65, -164, 29, 220, -126, 89, +-2, -315, 69, 70, -65, 277, -76, -177, +41, -189, 43, 223, -74, 80, -85, -232, +68, 46, 50, 158, -115, -126, -45, -45, +63, 101, 33, -18, -73, -75, -102, 19, +85, 97, 81, -46, -142, -137, -90, 121, +122, 125, 59, -207, -154, -35, -83, 226, +140, -87, 64, -142, -176, 127, -93, 18, +229, -77, -6, 41, -273, 15, 95, -79, +184, 44, -120, 98, -171, -140, 94, -57, +173, 191, -169, -17, -147, -178, 189, 44, +51, 163, -163, -58, -38, -187, 117, 94, +66, 182, -188, -159, -32, -143, 198, 205, +-54, 55, -145, -197, 50, 16, 97, 133, +-59, -20, -69, -117, 48, 26, 31, 104, +-28, -82, -6, -40, -33, 78, 29, -53, +52, 6, -97, 81, 10, -111, 53, -57, +-16, 196, 0, -19, -51, -236, 26, 91, +70, 225, -72, -105, -54, -264, 98, 130, +39, 337, -105, -261, -26, -328, 125, 364, +48, 229, -156, -388, -32, -184, 197, 407, +3, 122, -194, -438, 66, -5, 133, 360, +-37, -80, -71, -229, -36, 55, 127, 141, +67, -2, -182, -120, -5, -21, 206, 88, +-46, 14, -114, -39, 73, -56, 9, 3, +44, 108, 31, -31, -132, -115, 60, 47, +150, 52, -88, 1, -67, -45, 76, -90, +59, 120, -2, 79, -44, -216, -17, 20, +102, 198, 66, -158, -119, -61, -26, 166, +152, -114, 18, -37, -78, 139, 18, -101, +45, -75, 49, 95, 33, 28, -64, -77, +-12, -56, 117, 78, 48, 55, -110, -97, +-10, -46, 150, 87, 29, 26, -118, -101, +32, -3, 129, 76, -23, -44, -34, -43, +54, 64, 6, -18, 0, -119, 105, 114, +-4, 121, -124, -296, 102, -20, 189, 406, +-121, -181, -172, -391, 250, 316, 154, 278, +-244, -384, -25, -192, 235, 381, 65, 87, +-162, -350, -28, -49, 207, 270, 41, 49, +-134, -265, 56, -68, 101, 260, -18, 22, +26, -260, 53, 3, -29, 229, -14, -72, +164, -209, 7, 157, -180, 95, 135, -226, +218, 64, -167, 156, -108, -216, 266, -13, +46, 224, -166, -182, 90, -101, 114, 220, +-44, -107, 24, -98, 79, 149, -26, -94, +5, -78, 115, 149, 25, -57, -71, -142, +75, 130, 97, 5, -16, -149, 18, 121, +5, -20, 49, -156, 129, 160, -58, 19, +-96, -207, 208, 61, 105, 143, -191, -112, +44, -114, 208, 99, -57, 24, -20, -63, +111, 7, -42, -91, 49, 5, 152, 188, +-87, -144, -60, -238, 198, 241, 79, 153, +-132, -299, 6, -89, 177, 226, 46, 51, +-58, -206, -13, -97, 73, 181, 193, 44, +-48, -167, -179, -56, 199, 52, 238, 83, +-206, -31, -101, -187, 308, 49, 24, 203, +-173, -157, 145, -171, 108, 181, -73, 3, +89, -165, 57, 91, -54, 21, 106, -176, +84, 79, -53, 149, 35, -246, 111, -108, +-8, 301, 24, -64, 97, -280, -11, 105, +-26, 124, 155, -74, 85, -105, -175, -48, +100, 113, 222, 41, -115, -185, -22, -46, +156, 155, 20, -30, 34, -195, 68, 53, +-83, 125, 120, -163, 187, -55, -163, 151, +-35, -117, 289, -107, 18, 148, -188, -60, +155, -140, 184, 119, -142, -26, 23, -154, +211, 155, -64, -3, -61, -284, 208, 130, +58, 220, -125, -284, 97, -211, 173, 300, +-48, 129, -23, -405, 86, -70, 81, 371, +76, -98, -63, -295, -16, 97, 226, 105, +42, -68, -164, -57, 124, -64, 189, -20, +-112, 89, 42, -6, 158, -163, -101, -59, +70, 140, 202, 70, -121, -222, -52, -154, +278, 239, 36, 109, -189, -327, 136, -133, +210, 295, -57, 68, -72, -349, 143, -100, +106, 302, -44, 38, 47, -344, 63, -51, +29, 278, 72, -32, 28, -260, -2, -10, +100, 134, 78, 22, -48, -162, 54, -144, +155, 150, -9, 117, -40, -252, 143, -142, +25, 217, 16, 64, 106, -230, -56, -128, +62, 149, 213, 143, -126, -220, -66, -250, +340, 252, -14, 177, -199, -370, 202, -131, +169, 271, -74, 20, 11, -210, 76, -127, +52, 101, 120, 155, 14, -181, -90, -207, +140, 115, 188, 127, -81, -81, -79, -223, +185, -25, 133, 231, -32, -40, -16, -286, +15, -47, 169, 216, 186, 96, -195, -351, +-122, -226, 417, 454, 142, 117, -345, -621, +44, -20, 367, 550, 24, -187, -144, -477, +-16, 208, 185, 243, 241, -244, -148, -134, +-198, 88, 350, -29, 234, 6, -298, -23, +14, -207, 286, 84, 4, 160, -13, -269, +43, -64, 28, 177, 119, -130, 57, -59, +-6, 48, 24, -108, 79, -2, 109, 41, +-5, -99, 23, -63, 87, 53, 13, -34, +126, -122, 75, 40, -142, 34, 118, -167, +262, -26, -53, 141, -126, -128, 80, -189, +289, 128, 72, 84, -260, -195, 21, -140, +392, 153, 105, 98, -343, -263, 10, -118, +482, 205, 27, 14, -336, -206, 91, -89, +345, 123, 74, 61, -194, -189, -56, -134, +297, 136, 203, 77, -187, -207, -133, -129, +299, 142, 239, 65, -211, -198, -77, -148, +289, 165, 132, 58, -151, -230, 34, -80, +150, 130, 91, 52, 6, -211, -31, -138, +117, 225, 95, 15, 29, -312, 15, -20, +53, 250, 90, -72, 29, -344, 35, 96, +132, 257, -3, -261, -48, -210, 196, 202, +113, 46, -109, -192, 1, -76, 199, 51, +147, 25, -123, -43, -74, -142, 259, -71, +204, 173, -183, 11, -136, -331, 291, 1, +302, 325, -235, -177, -249, -349, 404, 218, +322, 174, -329, -284, -197, -109, 478, 120, +194, 14, -356, -59, 37, -127, 279, -70, +109, 139, -45, 53, -188, -309, 200, -100, +376, 391, -229, -116, -221, -479, 402, 247, +182, 286, -295, -366, 73, -192, 270, 257, +-35, 32, -45, -231, 113, -33, 69, 36, +14, 2, 91, 28, 2, -179, -2, -102, +184, 225, 7, -11, -101, -329, 215, 16, +82, 275, -164, -135, 141, -284, 220, 94, +-113, 148, -78, -78, 233, -207, 79, -56, +-38, 241, 11, -49, 12, -338, 181, 96, +119, 212, -212, -179, 12, -230, 437, 116, +-78, 179, -325, -255, 279, -145, 303, 230, +-157, -63, -193, -157, 234, 1, 242, 9, +-113, 53, -126, -120, 126, -116, 252, 104, +-42, 30, -162, -139, 117, -124, 249, 104, +-10, 106, -204, -206, 119, -164, 309, 206, +-123, 71, -121, -298, 195, -24, 103, 169, +-42, -61, -11, -109, 136, -73, 4, 68, +-7, 26, 126, -131, 0, -27, 16, -34, +81, 66, 0, -9, 36, -222, 121, 126, +-64, 42, -7, -219, 247, 126, -95, -20, +-121, -191, 293, 135, 51, 9, -189, -176, +123, -24, 160, 111, -93, 6, 52, -228, +112, 24, -96, 159, 104, -156, 135, -28, +-131, -23, 54, -93, 170, 210, -38, -143, +-32, -269, 59, 266, 104, 39, 68, -213, +-140, -51, 56, 34, 202, 162, -24, -179, +-39, -218, -44, 245, 175, 2, 167, -139, +-276, -61, 61, -92, 313, 280, -168, -37, +-47, -475, 159, 229, 1, 327, 40, -347, +14, -197, -18, 209, 45, 78, 148, -87, +-42, -198, -109, -25, 167, 309, 100, -132, +-90, -321, -66, 181, 182, 135, 123, -101, +-227, -196, 57, -21, 273, 288, -154, -121, +-23, -334, 149, 201, -88, 238, 109, -338, +55, -124, -111, 329, 129, -175, 49, -93, +-93, 118, 108, -222, 69, 269, -99, -75, +63, -443, 98, 542, -23, -81, -3, -538, +37, 511, 40, -60, 46, -364, -27, 386, +-33, -242, 141, -131, 25, 489, -92, -472, +3, -172, 127, 597, 110, -342, -180, -216, +-33, 274, 280, -149, -60, 108, -124, -46, +124, -301, -1, 312, 74, 118, 15, -390, +-180, -5, 153, 310, 243, -83, -232, -252, +-157, 84, 312, 30, 153, 67, -266, 24, +-119, -431, 341, 241, 74, 474, -303, -667, +97, -161, 217, 721, -111, -255, -74, -467, +97, 367, 40, 99, 6, -205, -26, 36, +-45, -104, 161, 82, -1, 156, -176, -316, +255, 19, -44, 296, -210, -245, 304, -164, +-57, 305, -83, -14, 93, -303, -114, 132, +189, 115, 24, -110, -202, 61, 127, -194, +54, 19, 12, 381, -7, -364, -110, -223, +157, 462, 14, -69, -67, -239, 36, 10, +-49, 15, 155, 309, -16, -192, -160, -494, +90, 498, 153, 278, -20, -549, -240, -49, +97, 317, 311, 40, -235, -179, -108, -145, +168, 129, 2, 183, 136, -132, -236, -252, +-45, 185, 370, 213, -215, -237, -64, -137, +161, 195, -168, 107, 167, -251, 79, 10, +-311, 238, 221, -246, 122, 38, -268, 141, +162, -252, 89, 221, -223, 42, 102, -343, +181, 195, -214, 215, 0, -249, 162, -184, +-60, 352, -16, 85, -87, -513, 84, 216, +204, 404, -240, -425, -165, -69, 349, 213, +25, -96, -250, 246, 44, -187, 57, -448, +106, 629, -32, 128, -190, -700, 161, 289, +76, 302, -124, -339, 63, 64, -105, 52, +94, -79, 216, 191, -377, -159, -65, -186, +468, 342, -99, 28, -400, -236, 176, -26, +213, 26, -109, 305, -9, -94, -117, -468, +-33, 366, 327, 230, -115, -363, -349, 42, +320, 98, 100, 17, -328, 19, 208, -207, +33, 124, -214, 240, 248, -294, -87, -93, +-191, 304, 272, -96, -11, -102, -211, 141, +85, -165, 71, 48, -53, 223, 74, -227, +-79, -73, -153, 191, 201, 12, 159, -95, +-282, -56, -147, 98, 361, 51, -64, -60, +-205, -23, 190, -17, -203, 78, 96, 33, +263, -83, -433, -1, 25, 47, 364, -15, +-191, 26, -152, 38, 58, -172, 126, 99, +54, 244, -231, -385, -64, 1, 260, 494, +69, -361, -297, -245, -100, 480, 317, -94, +104, -236, -426, 257, 23, -165, 412, -38, +-295, 370, -86, -373, 238, -91, -214, 497, +80, -333, 104, -193, -229, 466, 102, -124, +83, -338, -161, 312, 77, 136, -7, -360, +-86, 142, 147, 197, -57, -252, -166, 56, +101, 95, 155, -50, -107, 38, -237, -93, +169, 47, 216, 75, -246, -74, -110, 43, +168, -54, 35, -5, -95, 172, -64, -128, +51, -112, 57, 194, -61, 10, -68, -100, +32, -16, 95, 8, -114, 165, -81, -35, +174, -247, -107, 118, -73, 249, 168, -132, +-109, -261, -114, 218, 114, 255, 50, -401, +-76, -4, -59, 438, -21, -353, 105, -94, +3, 404, -132, -320, 42, -4, 8, 342, +13, -395, -34, 38, -68, 375, 161, -333, +-112, -12, -234, 279, 348, -296, 12, 38, +-348, 363, 138, -337, 40, -167, 9, 460, +19, -135, -174, -302, 50, 398, 113, -103, +-127, -362, -7, 528, 146, -51, -242, -497, +-16, 462, 301, -17, -190, -347, -155, 424, +181, -109, -63, -324, -81, 355, 165, 36, +-142, -275, -120, 191, 182, 96, -34, -335, +-99, 203, 28, 284, -29, -441, -2, 60, +68, 324, -111, -343, -43, 78, 120, 336, +-65, -411, -86, -109, 55, 552, 11, -214, +-62, -382, -22, 488, 30, -77, 10, -369, +-126, 462, 60, -83, 108, -347, -229, 404, +28, -78, 125, -269, -118, 370, 31, -80, +-53, -291, -116, 336, 201, -7, -13, -293, +-260, 296, 107, 14, 54, -295, -56, 266, +42, 54, -149, -284, -3, 174, 116, 161, +-40, -242, -67, -71, -68, 293, 48, -25, +31, -289, -76, 192, 55, 121, -75, -222, +-172, 120, 236, 71, 56, -182, -314, 110, +35, 91, 138, -154, -50, 70, -40, 78, +-82, -179, 10, 129, 88, 125, -135, -282, +-19, 124, 103, 191, -133, -282, -19, 149, +14, 165, -43, -401, 99, 196, -134, 366, +-117, -470, 193, -50, -92, 421, -89, -249, +133, -19, -196, 267, 7, -385, 164, 61, +-206, 416, 20, -328, 90, -49, -219, 189, +51, -197, 173, 187, -204, 98, -83, -260, +135, 30, -116, 104, 3, 58, 138, -61, +-248, -66, -68, 99, 241, -82, -117, 56, +-76, 111, 23, -228, -135, 120, 110, 148, +74, -332, -220, 164, -51, 324, 156, -363, +-52, -116, -152, 285, 109, 3, -19, -50, +-192, -76, 165, -44, 11, 171, -279, 23, +149, -143, 125, 16, -286, 171, -10, -128, +195, -210, -139, 394, -85, 81, 73, -509, +-152, 142, 112, 323, 124, -98, -413, -62, +79, -184, 308, 44, -288, 372, -51, -145, +48, -279, -122, 142, 192, 145, -81, 17, +-291, -122, 138, -59, 169, 153, -160, -35, +-208, -78, 136, 106, 97, 39, -207, -68, +17, -131, -11, 131, -84, 250, 167, -267, +-170, -169, -219, 244, 298, 74, 8, 12, +-365, -143, 107, -108, 133, 243, -190, 0, +61, -48, -44, 8, -209, -221, 237, 234, +-5, 254, -356, -359, 217, -51, 67, 216, +-329, -21, 175, 23, 30, -94, -240, -67, +175, 206, -72, 21, -255, -159, 245, -25, +65, 163, -342, 62, 0, -231, 181, 11, +-79, 162, -69, 20, -26, 51, -177, -273, +99, -19, 240, 502, -342, -201, -223, -405, +359, 271, -30, 215, -291, -116, 118, -126, +-52, 25, -105, 116, 236, 20, -257, -82, +-251, -59, 460, 99, -105, 90, -482, -120, +275, -35, 150, 160, -307, -29, 21, -109, +33, 118, -123, -50, 64, -58, -1, 210, +-153, -139, -22, -102, 93, 276, -123, -125, +-79, -144, 154, 216, -162, -40, -168, -132, +233, 110, -63, 81, -270, -92, 174, -14, +4, 97, -277, -60, 198, -22, 49, 87, +-379, -80, 158, 5, 174, 116, -368, -98, +81, 5, 192, 134, -418, -151, 82, -41, +334, 241, -436, -84, -116, -174, 325, 142, +-201, 100, -60, -37, 101, -66, -320, -67, +109, 100, 309, 119, -445, -105, -198, -117, +465, 129, -135, 126, -379, -132, 234, -32, +20, 80, -219, -67, 155, 96, -147, 3, +-202, -224, 344, 273, -105, 133, -409, -390, +210, 128, 137, 205, -237, -130, 9, 36, +-44, -123, -185, 12, 201, 314, 88, -114, +-414, -232, -42, 88, 316, 162, -129, 49, +-197, -174, 28, -131, -41, 211, 22, 190, +27, -185, -187, -177, -62, 157, 188, 156, +-136, -107, -204, -128, 176, 90, -27, 68, +-203, -14, 62, 33, 18, -62, -176, -5, +83, 62, 55, -29, -317, 60, 58, -50, +219, -92, -260, 201, -121, 40, 154, -223, +-101, 76, -65, 182, 54, -201, -144, -38, +-2, 272, 30, -170, -176, -114, 92, 288, +103, -115, -350, -126, -75, 189, 376, -80, +-133, -50, -384, 136, 123, -79, 114, -27, +-93, 178, -24, -79, -178, -175, -45, 216, +199, 70, -116, -252, -129, 110, -14, 110, +-126, -145, 137, 196, 86, 32, -364, -376, +-84, 200, 304, 382, -64, -379, -265, -201, +-9, 430, 68, -44, -21, -243, -26, 270, +-75, -68, -156, -256, 40, 335, 175, 1, +-157, -309, -257, 295, 97, 25, 115, -286, +-130, 304, -30, 40, -105, -318, -147, 197, +258, 83, 4, -170, -358, 139, 19, -36, +131, -59, -48, 224, -39, -200, -111, -145, +-134, 399, 132, -81, 76, -347, -242, 232, +-24, 189, 42, -170, -131, -4, 114, 49, +2, -100, -298, 127, 16, 74, 212, -214, +-97, 104, -230, 96, 19, -144, 94, 172, +-95, -2, -11, -260, -32, 148, -181, 174, +111, -93, 57, -57, -231, -84, 33, 95, +53, 321, -163, -222, -4, -406, 98, 344, +-96, 326, -164, -281, 37, -198, 58, 103, +-35, 234, -81, 35, -130, -264, 10, 27, +111, 158, -62, -105, -191, 69, 17, 85, +93, -160, -158, 36, 6, 71, 65, -15, +-242, 136, 94, -157, 89, -223, -262, 329, +98, 151, 37, -296, -193, 10, 77, 149, +-41, -56, -109, -20, 142, 49, -43, 17, +-251, -61, 54, -48, 182, 70, -131, 109, +-145, 53, 44, -171, -98, -182, -18, 283, +212, 208, -182, -314, -255, -76, 128, 210, +71, -45, 1, 9, -33, 59, -253, -117, +-57, 52, 295, 10, -22, -146, -260, 253, +24, 167, -26, -422, -57, -83, 217, 402, +-55, 26, -373, -181, 109, -69, 250, -39, +-213, 180, -53, 103, 51, -166, -132, 18, +51, 65, -11, -156, -130, 44, 133, 274, +-10, -72, -323, -315, 68, 87, 278, 273, +-145, -81, -217, -114, 49, 94, 24, -68, +-47, -92, 82, 169, 8, 84, -235, -52, +-42, -96, 236, -161, -25, 235, -143, 254, +-10, -368, -82, -76, 60, 317, 111, -203, +-139, -42, -76, 352, 26, -201, -66, -221, +58, 224, 32, -64, -190, 10, 46, 286, +56, -289, -221, -290, 46, 434, 215, 204, +-196, -355, -200, -103, 221, 205, -36, 32, +-155, -75, 211, 18, -61, 5, -251, 79, +138, 2, 135, -291, -95, 157, -47, 404, +-17, -346, -78, -221, 69, 289, 97, -57, +-137, 38, -24, 193, -16, -269, -206, -151, +229, 219, 188, 85, -446, 22, -48, -7, +231, -247, -116, -48, 98, 372, -43, 46, +-253, -282, 178, -5, 76, 34, -139, -9, +47, 171, 76, 73, -116, -196, -140, -176, +215, 180, 121, 198, -204, -106, -20, -37, +-18, -123, -41, -77, 206, 396, -20, -40, +-236, -352, 2, 219, 15, -19, 22, -160, +149, 319, -171, -77, -258, -236, 179, 201, +124, -67, -123, -75, -8, 307, -13, -115, +-101, -332, 48, 184, 180, 202, -16, -81, +-177, -50, -10, -76, 111, 17, 108, 179, +-38, -123, -158, -166, 93, 310, 130, 54, +-226, -444, -16, 98, 273, 414, -155, -160, +-179, -200, 104, 65, -57, -34, 38, 90, +97, 155, -216, -170, -124, -148, 189, 193, +85, 39, -86, -188, -81, 167, -50, 78, +97, -280, 108, 76, -36, 144, -34, -11, +-15, 53, 15, -222, 108, -19, 10, 295, +-71, -119, 26, -92, 27, 99, 7, -146, +-66, 65, -23, 260, 112, -179, -69, -290, +-135, 229, 62, 264, 8, -262, -39, -156, +61, 236, -130, 21, -110, -124, 209, 48, +49, 14, -170, -36, 53, 27, 81, 15, +-127, -26, 98, -5, 193, 30, -150, 5, +-5, 21, 86, -2, -76, -123, 150, 32, +58, 165, -146, -58, 9, -102, -15, -1, +33, 21, 120, 122, -117, -17, -192, -170, +30, 58, 155, 97, 6, -61, -123, -9, +-69, 17, -43, -3, 78, 45, 152, -9, +-79, -118, -106, 6, 107, 242, -12, -35, +-14, -349, 272, 133, -33, 332, -298, -173, +160, -221, 284, 97, -75, 164, -152, -3, +12, -173, 69, -31, 63, 150, -35, 45, +-78, -108, 34, -44, -22, 87, -118, -52, +-8, -69, 170, 184, 4, 24, -278, -230, +-25, 0, 249, 162, 55, 42, -134, -34, +-90, -138, 121, -33, 187, 199, -30, -83, +-72, -80, 60, 240, 71, -208, 43, -175, +39, 309, 17, -56, -30, 17, -38, 60, +62, -472, 71, 267, -110, 577, -54, -527, +94, -308, -45, 413, -71, -11, -22, -72, +8, 154, 54, -217, -77, -156, -50, 296, +131, 77, 7, -153, -123, 35, 88, -145, +149, -123, -55, 426, -8, 74, 139, -484, +31, 63, -65, 207, 81, -106, 128, 196, +-75, -73, -36, -392, 130, 311, -50, 242, +-83, -385, 103, 70, -44, 282, -138, -289, +72, -119, 78, 334, -77, -43, -133, -204, +-58, 134, 190, -43, 112, -88, -256, 229, +-14, -60, 224, -210, -36, 120, 27, 42, +64, -35, -96, 55, 107, -45, 182, -43, +-66, 3, 5, 39, 40, 66, -69, -84, +130, -40, 119, 44, -124, -39, -107, 77, +30, -3, 89, -101, 13, 151, -103, -89, +-136, -234, 59, 346, 151, 136, -117, -457, +-86, 76, 87, 308, -99, -223, 78, -27, +226, 194, -128, -144, -101, -51, 72, 49, +148, -61, 175, 204, -110, 41, -159, -369, +180, 76, 208, 303, -94, -202, -118, -54, +85, 241, 42, -230, -63, -176, 54, 343, +29, 44, -128, -188, -63, 50, 14, -166, +82, -32, 55, 467, -158, -120, -92, -472, +107, 224, 118, 163, -18, -96, -120, 146, +77, -167, 135, -173, -51, 236, 41, -4, +106, -33, -16, 153, -2, -216, 26, -222, +83, 349, 118, 200, -67, -374, -147, -52, +61, 232, 106, -144, 0, 30, -29, 204, +-121, -177, -66, -115, 96, 76, 65, 30, +-54, 122, -101, -40, -7, -246, 36, 77, +84, 220, 96, -74, -137, -94, -107, -40, +182, -20, 199, 215, -48, 0, -127, -311, +64, 87, 135, 237, 13, -93, -8, -77, +60, -9, -36, -70, -40, 93, 82, 176, +-9, -135, -44, -213, 3, 160, -37, 114, +25, -121, 3, 56, -71, -34, 17, -151, +29, 172, -32, 103, -35, -152, 37, -10, +82, 11, 4, -13, -44, 121, 9, -32, +92, -181, 52, 71, 10, 138, 64, -67, +-27, -24, -75, -9, 118, -62, 142, 106, +-99, 38, -88, -142, 58, 28, 26, 117, +22, -88, -25, -94, -53, 143, -7, 72, +-27, -167, 14, -32, 99, 85, -11, 2, +-168, 50, -16, -6, 181, -134, 77, 15, +-54, 155, -80, -19, -8, -121, 131, 33, +114, 24, -14, -44, -62, 83, -20, 22, +33, -114, 106, 5, 119, 42, -131, 3, +-204, 72, 123, -70, 204, -158, -47, 160, +-162, 150, -76, -183, 50, -44, 140, 79, +12, -75, -143, 69, -3, 114, 43, -133, +19, -123, 110, 74, -7, 140, -105, 14, +50, -138, 111, -100, 29, 108, -13, 169, +12, -129, 15, -144, -24, 157, 65, 29, +114, -85, -110, 24, -104, -46, 112, 78, +37, 48, -60, -200, -8, 103, -7, 151, +-20, -216, -17, 14, 4, 172, 47, -96, +-14, -82, -67, 41, 26, 81, 93, 19, +35, -156, -43, 11, -17, 182, 85, -97, +66, -137, 4, 111, 24, 52, -22, -50, +22, -14, 92, -21, -33, 18, -43, 29, +38, -4, 5, 18, -18, -32, 9, -60, +-46, 33, -78, 74, 107, 32, 55, -66, +-229, -99, 23, 27, 223, 123, -167, 24, +-95, -83, 200, -66, -28, 13, -31, 103, +43, 15, -20, -114, 175, 47, 26, 39, +-234, -171, 150, 79, 309, 233, -186, -159, +-185, -224, 210, 154, 73, 178, -101, -104, +26, -118, -23, 48, -52, 41, 73, -12, +-50, -9, -70, 18, 99, 31, -66, -75, +-148, -80, 151, 114, 109, 131, -184, -146, +-71, -161, 159, 170, 68, 121, -53, -133, +15, -61, 16, 29, 54, 59, 101, 41, +-60, -141, 22, -45, 148, 182, -67, 35, +-63, -161, 131, -69, 13, 110, -58, 94, +13, -29, -72, -85, 34, -85, 99, 68, +-147, 167, -76, -66, 110, -148, -7, 53, +-112, 26, 20, -15, 76, 105, -57, -52, +-35, -158, 42, 118, 60, 72, 28, -122, +-29, 90, 17, 3, 74, -183, 57, 139, +-45, 92, 41, -164, 138, 89, -104, 29, +-49, -186, 194, 127, 9, 138, -128, -167, +-17, -52, 28, 83, 103, 8, -19, 20, +-212, -6, 28, -83, 181, 38, -148, 81, +-118, -120, 167, 11, -24, 201, -150, -181, +105, -191, 68, 300, -69, 64, 55, -249, +-16, 34, 27, 34, 147, 2, -124, 103, +21, -126, 218, -52, -88, 157, -129, -79, +131, -79, 179, 128, -77, 15, -190, -102, +70, -43, 152, 79, -7, 85, -111, -62, +-77, -86, 47, 20, 52, 65, -45, 27, +-20, -64, 16, -40, -106, 69, -39, -5, +200, -29, 57, 58, -233, -75, -63, -55, +229, 156, 102, -18, -63, -174, -94, 69, +-20, 131, 210, -76, 56, -72, -135, 55, +45, 6, 66, -32, -38, 20, 48, 25, +43, 8, -60, -85, -21, -27, 40, 174, +-15, -13, -1, -188, 8, 47, -42, 92, +-25, -12, 9, -5, 24, -59, 0, 8, +-49, 44, -19, -44, 49, 76, 34, 0, +-53, -208, 13, 122, 55, 218, 35, -225, +-48, -104, -28, 190, 129, 15, 27, -46, +-60, -74, 15, -23, -18, 170, 85, -40, +133, -127, -183, 97, -139, -21, 283, -26, +55, 111, -253, -81, 47, -71, 100, 79, +-59, 2, 38, 22, -81, 13, -40, -92, +169, -11, -77, 87, -165, 62, 149, -74, +99, -152, -147, 94, 13, 181, 52, -113, +-24, -130, 89, 57, 12, 55, -137, 19, +80, 3, 160, -62, -130, -93, -5, 94, +155, 180, -127, -157, -27, -150, 210, 169, +-56, -3, -153, -44, 124, 99, 32, -129, +-38, -41, 54, 177, -113, -76, -24, -72, +202, 130, -93, -63, -155, -118, 99, 126, +70, 75, -41, -109, -55, -11, 0, 0, +24, -48, 48, 150, 26, 30, -109, -256, +1, 43, 151, 218, 19, -127, -115, -40, +18, 128, 89, -165, 16, -32, 13, 237, +-3, -78, -50, -113, 80, 45, 76, -63, +-90, 108, -11, 127, 70, -197, -12, -120, +-34, 176, 18, 94, -16, -147, 31, 20, +-40, 86, -82, -201, 101, 74, 41, 246, +-140, -195, -18, -111, 121, 111, -28, -28, +-52, 58, 30, 86, 22, -144, 17, -132, +-20, 170, 54, 129, 18, -157, -10, -23, +28, 34, -7, -60, 51, 119, 82, 22, +-76, -142, -45, 50, 72, 13, 66, -54, +14, 135, -122, -31, -43, -192, 124, 125, +46, 118, -114, -127, -76, -19, 39, 40, +34, 19, 74, -24, -116, -43, -111, 79, +144, -38, 71, -42, -80, 107, -80, -99, +64, -17, 147, 138, -55, -122, -119, -36, +110, 131, 122, -30, -33, -75, -101, 17, +41, 53, 151, -22, -39, 16, -89, 18, +36, -130, 31, 78, 11, 124, -2, -125, +-61, 36, -30, -44, 55, -109, 20, 275, +-94, -5, -14, -277, 50, 69, -43, 102, +25, 60, -39, -13, 0, -182, 59, 40, +-46, 130, 24, 4, 9, -20, -4, -134, +81, 36, -33, 194, -12, -139, 75, -80, +-5, 164, 31, -121, -15, -19, -2, 175, +68, -175, -49, 9, -12, 156, 53, -199, +1, 76, -100, 108, 38, -190, 69, 138, +-77, -28, -22, -172, 3, 258, 17, -46, +33, -186, -117, 163, -5, -84, 191, 15, +-130, 223, -59, -318, 105, -78, -57, 442, +136, -216, -8, -175, -203, 304, 143, -306, +162, 75, -97, 470, -19, -588, -41, -63, +21, 558, 194, -399, -65, 99, -185, 259, +83, -658, 97, 352, -90, 502, 83, -651, +-59, 95, -158, 208, 170, -352, 45, 466, +-112, -15, 0, -600, -14, 410, 2, 165, +70, -342, 0, 239, -54, 15, -70, -343, +112, 236, 84, 262, -134, -366, 60, -32, +23, 322, -30, -271, 104, -6, -60, 318, +-58, -347, 173, 16, -66, 348, -103, -402, +139, 27, -23, 425, -36, -379, 39, -83, +-51, 319, -37, -230, 125, 82, -40, 177, +-174, -383, 149, 147, 34, 299, -150, -362, +112, 18, -37, 285, -72, -252, 174, -59, +-124, 288, -75, -173, 180, -150, 1, 329, +-126, -135, -7, -253, 170, 373, -47, -42, +-98, -310, 158, 243, -82, 52, -65, -173, +248, 79, -193, 38, -84, -52, 284, -18, +-158, 70, -114, 12, 171, -156, 6, 105, +-118, 118, 51, -219, 0, 96, -96, 85, +170, -232, -35, 229, -246, 84, 206, -385, +59, 205, -193, 269, 136, -381, -21, 4, +-55, 347, 55, -274, -19, -66, 60, 321, +-55, -246, 29, -72, 50, 283, -144, -178, +176, -108, 116, 253, -337, -67, 132, -249, +180, 268, -236, 98, 185, -364, 5, 227, +-358, 109, 276, -315, 243, 266, -403, 35, +15, -313, 229, 202, -222, 119, 126, -193, +114, -4, -329, 151, 94, -65, 230, -155, +-185, 233, -20, 24, 132, -333, -162, 292, +37, 98, 219, -497, -134, 406, -74, 278, +59, -759, 13, 231, 143, 596, -66, -565, +-159, -55, 85, 393, 107, -385, -17, 118, +-65, 388, -10, -498, -55, -60, 84, 437, +88, -193, -155, -121, 5, 175, -16, -72, +-12, -121, 194, 148, -158, 158, -201, -307, +282, -24, 12, 393, -200, -353, 159, -108, +-14, 550, -86, -379, 140, -298, -76, 569, +-51, -168, 204, -270, -62, 453, -232, -340, +177, -296, 263, 823, -286, -248, -141, -755, +298, 692, -64, 208, -116, -634, 155, 302, +-124, 225, -153, -497, 363, 204, -99, 433, +-368, -559, 357, -116, 1, 703, -240, -361, +160, -449, 31, 671, -113, -89, -6, -567, +178, 574, -87, 74, -176, -703, 305, 568, +-89, 287, -235, -937, 406, 504, -114, 644, +-353, -1084, 412, 148, 76, 946, -413, -801, +215, -205, 204, 801, -347, -550, 76, -212, +289, 781, -272, -482, -146, -414, 377, 767, +-151, -193, -305, -537, 465, 597, -55, 73, +-557, -654, 484, 295, 285, 437, -680, -425, +261, -136, 402, 319, -657, -89, 245, -176, +580, 266, -718, 104, -111, -534, 698, 92, +-263, 720, -308, -458, 396, -478, -157, 644, +-291, -64, 565, -390, -54, 474, -630, -102, +374, -539, 385, 523, -497, 322, -39, -740, +419, 46, -321, 723, -140, -487, 425, -415, +-167, 803, -270, -193, 337, -699, -66, 754, +-261, 120, 372, -817, -34, 485, -392, 384, +293, -679, 185, 124, -347, 481, 140, -377, +188, -188, -304, 375, 53, -5, 294, -314, +-133, 135, -237, 254, 176, -305, 113, -66, +-177, 364, 137, -197, 6, -173, -352, 287, +329, -72, 223, -222, -521, 221, 156, 177, +264, -372, -355, -113, 160, 504, 220, -51, +-411, -474, 72, 186, 398, 249, -342, -149, +-110, -23, 391, -18, -234, -38, -145, 100, +361, 56, -177, -45, -205, -178, 386, 98, +-94, 235, -349, -257, 364, -60, 108, 279, +-384, -172, 143, -166, 238, 291, -311, 17, +36, -324, 342, 137, -379, 213, -96, -208, +500, -28, -273, 129, -301, -67, 493, -38, +-121, 90, -382, -13, 484, -113, -70, 82, +-482, 89, 518, -87, 111, -21, -651, -42, +372, 61, 355, 190, -539, -255, 80, -146, +342, 420, -314, -119, -24, -337, 344, 413, +-243, -40, -187, -478, 351, 503, -2, 207, +-367, -759, 238, 286, 250, 646, -535, -710, +169, -211, 490, 833, -555, -300, -68, -663, +532, 709, -335, 227, -184, -907, 473, 454, +-262, 630, -285, -1025, 510, 108, -34, 1035, +-503, -854, 333, -496, 300, 1183, -506, -281, +88, -967, 385, 918, -423, 290, 33, -1037, +452, 487, -490, 549, -80, -920, 643, 242, +-420, 778, -283, -851, 572, -222, -239, 940, +-260, -325, 499, -573, -222, 559, -342, 81, +500, -522, -77, 289, -320, 365, 331, -490, +-110, -178, -227, 503, 380, 7, -36, -371, +-400, 139, 278, 112, 154, -213, -327, 214, +207, 89, 92, -358, -382, 113, 224, 209, +287, -83, -415, -72, 1, -91, 424, 172, +-361, 59, -161, -307, 623, 205, -294, 207, +-502, -440, 673, 113, -20, 379, -559, -396, +517, -58, 17, 397, -572, -217, 432, -192, +278, 296, -544, -16, 53, -234, 336, 179, +-256, 73, -19, -241, 274, 138, -262, 112, +-151, -211, 376, 111, -58, 33, -241, -117, +127, 156, 48, -114, -54, -32, 13, 257, +55, -283, -86, -70, 15, 435, 53, -241, +-75, -296, 169, 395, -112, 58, -214, -412, +370, 185, -33, 345, -356, -488, 308, -50, +36, 626, -323, -434, 282, -343, 99, 723, +-430, -230, 188, -587, 371, 732, -469, 109, +-114, -893, 556, 444, -208, 687, -419, -832, +422, -236, 145, 935, -431, -332, 158, -641, +250, 797, -351, -33, 32, -836, 447, 772, +-365, 347, -296, -1111, 580, 336, -45, 895, +-479, -789, 298, -353, 215, 911, -420, -287, +59, -709, 423, 859, -306, 144, -348, -1028, +492, 551, 118, 597, -578, -911, 294, 160, +344, 697, -671, -727, 206, -137, 672, 824, +-754, -365, -217, -576, 871, 671, -334, 163, +-539, -753, 635, 354, 58, 533, -645, -739, +403, -59, 398, 746, -671, -387, 53, -398, +630, 541, -537, -56, -168, -406, 712, 401, +-519, 100, -312, -539, 813, 227, -319, 469, +-542, -441, 622, -301, 13, 544, -469, 69, +335, -549, 58, 258, -317, 337, 223, -512, +99, 15, -226, 547, 95, -296, 48, -450, +-117, 482, 134, 201, 19, -525, -141, 213, +46, 302, 26, -597, 33, 164, 81, 674, +-197, -615, -49, -349, 267, 735, -114, -137, +-115, -487, 160, 557, -130, 37, -77, -777, +244, 497, -37, 630, -256, -841, 109, -137, +184, 705, -147, -329, -100, -209, 181, 473, +-12, -262, -210, -374, 227, 550, 43, 148, +-346, -647, 303, 192, 147, 467, -441, -427, +124, -121, 367, 400, -283, -127, -168, -257, +328, 266, -124, 65, -191, -321, 291, 170, +6, 249, -327, -331, 122, -91, 233, 360, +-192, -83, -84, -263, 181, 227, -73, 125, +-207, -363, 272, 42, 181, 479, -469, -296, +-40, -379, 521, 462, -186, 77, -357, -365, +419, 201, -70, 103, -408, -351, 526, 230, +102, 318, -699, -519, 282, -47, 538, 576, +-549, -266, -152, -373, 585, 417, -292, 87, +-388, -424, 644, 222, -46, 269, -673, -483, +452, 52, 340, 510, -584, -330, 117, -328, +347, 409, -437, 59, 135, -293, 342, 191, +-419, -20, -65, -236, 375, 271, -46, 96, +-283, -283, 120, -28, 173, 243, -147, -52, +-62, -167, 88, 179, 92, -2, -156, -139, +-40, 27, 173, 104, -55, 54, -62, -174, +15, -18, 52, 147, -58, -1, -79, -107, +243, 8, -106, 173, -271, -204, 254, -76, +98, 381, -180, -196, -52, -266, 160, 343, +-136, 21, -30, -328, 348, 226, -380, 243, +-105, -530, 459, 95, -209, 611, -182, -604, +227, -137, -10, 702, -218, -484, 215, -201, +103, 605, -332, -307, 77, -265, 303, 349, +-177, 41, -259, -231, 319, -23, 30, 282, +-292, -173, 213, -183, 27, 402, -237, -181, +169, -263, 136, 347, -284, -5, 21, -171, +305, -9, -287, 43, -82, 161, 369, -181, +-173, -18, -273, 217, 285, -381, 156, 260, +-375, 354, 124, -786, 239, 320, -369, 551, +137, -845, 295, 306, -396, 564, -2, -880, +306, 233, -149, 642, -85, -775, 92, 162, +-12, 543, -62, -760, 73, 241, 36, 516, +-100, -681, -49, 191, 116, 284, 91, -392, +-288, 241, 92, -4, 287, -141, -387, 192, +28, -272, 409, 172, -424, 333, -54, -689, +483, 212, -395, 729, -8, -1013, 264, 165, +-237, 1021, 114, -1316, 30, 320, -131, 1117, +104, -1647, -16, 602, 2, 1144, 66, -1805, +-209, 651, 101, 1034, 244, -1525, -305, 554, +-101, 766, 381, -1189, -169, 435, -229, 617, +330, -917, -106, 327, -186, 445, 236, -715, +8, 295, -203, 350, 20, -526, 227, 139, +-99, 296, -233, -347, 266, 39, 43, 322, +-283, -397, 300, -1, -69, 490, -269, -490, +366, -13, -41, 464, -259, -521, 145, 204, +82, 365, -100, -678, 31, 241, -54, 487, +27, -572, 99, 27, -150, 380, 24, -389, +110, 139, -181, 303, 94, -540, 181, 157, +-386, 416, 118, -494, 367, 104, -421, 340, +50, -522, 228, 177, -335, 506, 333, -682, +-9, -11, -391, 744, 356, -650, -50, -112, +-52, 769, 79, -717, -218, -4, 194, 763, +-43, -760, -22, 12, 109, 655, -309, -551, +235, -66, 111, 465, -317, -257, 215, -196, +-21, 271, -146, 33, 180, -202, 12, 37, +-231, 152, 90, -161, 324, -19, -470, 286, +70, -295, 516, -123, -693, 453, 193, -257, +616, -172, -890, 413, 275, -289, 545, -217, +-719, 565, 335, -153, 117, -506, -404, 463, +358, 82, -2, -353, -184, 295, -3, -111, +39, -176, 209, 299, -227, -19, -132, -236, +345, 47, -197, 298, -121, -316, 358, 0, +-309, 377, -146, -532, 548, 289, -348, 295, +-314, -710, 684, 456, -367, 234, -335, -599, +753, 333, -409, 183, -420, -425, 786, 147, +-204, 333, -600, -340, 683, -206, -55, 502, +-595, -46, 671, -542, -76, 402, -624, 344, +662, -728, 2, 193, -629, 666, 525, -829, +174, 19, -613, 947, 286, -916, 329, -315, +-532, 1312, 227, -717, 290, -743, -606, 1338, +299, -559, 319, -758, -475, 1374, 170, -523, +34, -888, -160, 1065, 269, -3, -74, -665, +-180, 354, 69, 199, 29, -442, 142, 127, +-95, 509, -208, -495, 235, -324, -28, 695, +-111, -97, 200, -538, -137, 538, -126, 10, +125, -711, 119, 787, -33, 187, -257, -1138, +159, 799, 123, 391, -190, -1056, 181, 665, +-66, 254, -323, -851, 454, 551, 97, 341, +-656, -757, 455, 194, 182, 595, -621, -593, +553, -154, 9, 723, -579, -444, 472, -368, +105, 736, -359, -184, 84, -525, 242, 469, +-206, 160, -224, -526, 556, 228, -200, 477, +-564, -730, 755, -52, -104, 983, -640, -694, +745, -532, -76, 1167, -772, -487, 792, -840, +135, 1410, -871, -287, 543, -1407, 290, 1454, +-633, 301, 198, -1632, 401, 1042, -395, 641, +-186, -1588, 479, 742, -77, 1039, -468, -1631, +424, 264, 203, 1402, -721, -1402, 363, -127, +579, 1377, -888, -1015, 118, -393, 779, 1117, +-780, -426, -33, -617, 782, 690, -623, 125, +-288, -708, 834, 367, -260, 408, -689, -688, +736, 179, 167, 497, -838, -546, 469, -46, +432, 460, -794, -246, 197, -141, 676, 199, +-765, -11, -157, -91, 950, -112, -505, 359, +-646, -45, 1015, -671, -182, 672, -863, 289, +1010, -1009, -39, 595, -1020, 428, 909, -1056, +302, 620, -1126, 587, 616, -1171, 515, 332, +-995, 839, 403, -891, 551, -25, -780, 788, +28, -669, 672, -213, -354, 925, -488, -507, +633, -627, 96, 990, -748, -151, 558, -782, +255, 786, -855, -14, 519, -690, 420, 648, +-847, 109, 192, -713, 709, 434, -727, 360, +-211, -674, 1000, 153, -588, 559, -609, -581, +1077, -155, -231, 760, -841, -427, 918, -495, +64, 891, -1023, -234, 816, -793, 421, 929, +-1145, 98, 466, -1032, 694, 663, -931, 467, +42, -1000, 912, 440, -723, 626, -527, -1102, +1191, 324, -302, 910, -1033, -1009, 1087, -112, +224, 903, -1330, -493, 830, -451, 794, 751, +-1570, 1, 446, -855, 1233, 575, -1498, 567, +69, -1031, 1487, 243, -1399, 777, -308, -933, +1671, 110, -1101, 875, -633, -897, 1503, -167, +-643, 1029, -821, -659, 1205, -406, -135, 931, +-974, -471, 732, -449, 425, 858, -955, -272, +242, -597, 795, 621, -964, 106, 10, -502, +1033, 201, -930, 227, -269, -334, 1081, 83, +-551, 325, -547, -384, 867, -93, -178, 468, +-617, -187, 596, -348, 168, 417, -650, 140, +179, -639, 563, 294, -544, 617, -180, -843, +751, -44, -465, 932, -491, -780, 1022, -230, +-260, 1038, -996, -769, 1107, -372, 149, 1170, +-1306, -707, 965, -565, 540, 1267, -1464, -530, +635, -832, 925, 1172, -1406, -142, 300, -892, +1162, 845, -1354, 49, -77, -841, 1471, 615, +-1018, 391, -657, -760, 1443, -6, -581, 626, +-844, -297, 1392, -336, -388, 622, -1152, -316, +1277, -568, 227, 1043, -1315, -165, 655, -1037, +697, 941, -1140, 224, 288, -990, 952, 635, +-1195, 383, -8, -977, 1281, 433, -1037, 636, +-377, -961, 1227, 149, -658, 830, -517, -802, +955, -230, -263, 986, -671, -495, 699, -626, +155, 998, -745, -193, 393, -875, 364, 961, +-624, 76, 183, -1014, 423, 723, -463, 337, +-56, -841, 413, 308, -163, 438, -261, -489, +325, -58, -8, 409, -376, -151, 428, -291, +-36, 300, -446, 127, 543, -369, -183, 94, +-358, 246, 566, -169, -214, -79, -281, 101, +374, 54, -130, -162, -115, 40, 224, 275, +-118, -320, -141, -127, 174, 476, 80, -219, +-187, -249, 16, 377, 101, -116, -58, -220, +-6, 263, 45, 29, -16, -185, -69, -40, +59, 179, 90, 77, -165, -313, 26, 120, +197, 252, -245, -330, 24, 27, 268, 238, +-274, -169, -43, -52, 278, 116, -113, 2, +-217, -117, 198, 52, 165, 187, -318, -288, +8, -34, 354, 448, -271, -353, -204, -206, +466, 520, -146, -173, -350, -312, 376, 282, +-10, 97, -273, -205, 283, -13, -53, 198, +-251, -181, 264, -73, 84, 392, -280, -304, +4, -202, 297, 477, -161, -215, -235, -195, +370, 371, -42, -187, -400, -233, 425, 375, +59, 9, -575, -337, 491, 171, 174, 155, +-726, -232, 528, 102, 237, 138, -852, -291, +653, 92, 346, 278, -1110, -303, 595, -88, +688, 368, -1135, -168, 234, -245, 873, 362, +-966, -59, 18, -296, 947, 319, -864, -43, +-191, -229, 1021, 271, -662, -102, -452, -136, +1024, 240, -378, -108, -678, -120, 816, 232, +19, -82, -724, -186, 493, 283, 299, -69, +-694, -209, 180, 286, 579, -155, -527, -94, +-285, 330, 732, -266, -248, -89, -562, 306, +738, -177, -51, -38, -709, 182, 600, -221, +235, 7, -711, 305, 267, -262, 465, -131, +-539, 380, -89, -214, 563, -194, -298, 439, +-316, -197, 559, -323, -173, 493, -417, -112, +523, -398, 20, 485, -508, -10, 324, -491, +217, 357, -476, 248, 201, -489, 304, 114, +-487, 404, 84, -515, 426, 18, -431, 620, +-32, -568, 428, -176, -339, 685, -157, -425, +452, -228, -153, 636, -323, -356, 382, -377, +-19, 653, -368, -113, 372, -484, 132, 447, +-536, 12, 193, -384, 437, 361, -441, 75, +-140, -438, 545, 218, -292, 253, -374, -343, +703, 51, -212, 236, -603, -268, 753, 30, +-48, 257, -719, -241, 653, -43, 214, 247, +-855, -213, 469, -34, 490, 322, -880, -275, +253, -159, 669, 430, -837, -180, 4, -232, +874, 429, -722, -248, -305, -317, 951, 666, +-407, -146, -608, -620, 766, 539, 54, 155, +-664, -527, 364, 310, 312, 221, -549, -535, +117, 146, 501, 487, -566, -390, -76, -224, +679, 392, -502, -59, -290, -232, 799, 224, +-376, 113, -556, -373, 865, 14, -169, 503, +-686, -288, 786, -387, -55, 573, -769, -65, +722, -571, 211, 633, -842, 119, 393, -834, +441, 517, -655, 412, 152, -770, 494, 271, +-603, 468, -38, -693, 687, 134, -446, 605, +-393, -661, 713, -10, -105, 671, -603, -664, +510, -85, 185, 806, -526, -572, 139, -352, +403, 753, -408, -244, -152, -425, 633, 559, +-391, -136, -382, -385, 753, 460, -192, -79, +-623, -286, 678, 266, 109, -6, -737, -107, +432, -46, 381, 84, -654, 187, 84, -327, +601, 2, -569, 409, -174, -405, 781, -61, +-481, 551, -414, -466, 841, -235, -274, 708, +-617, -310, 786, -468, -14, 682, -756, -126, +597, -596, 247, 680, -742, 42, 374, -767, +361, 598, -634, 288, 179, -808, 399, 363, +-411, 492, -83, -725, 403, 69, -153, 659, +-321, -570, 406, -216, 17, 736, -455, -355, +409, -458, 120, 695, -548, -97, 350, -631, +267, 623, -487, 169, 47, -799, 365, 424, +-218, 484, -176, -731, 318, 74, -101, 600, +-261, -522, 367, -182, -9, 688, -413, -329, +342, -486, 143, 666, -398, 0, 104, -619, +303, 463, -270, 264, -156, -700, 425, 231, +-201, 601, -244, -687, 431, -113, -170, 769, +-269, -488, 381, -360, -70, 788, -266, -252, +259, -617, 0, 715, -202, 72, 189, -746, +18, 535, -216, 257, 153, -741, 136, 381, +-229, 401, -23, -697, 244, 164, -102, 536, +-181, -600, 287, -35, -97, 622, -271, -474, +388, -208, 7, 606, -445, -263, 268, -326, +242, 459, -444, -23, 190, -375, 226, 250, +-469, 192, 249, -347, 281, 23, -494, 311, +147, -237, 346, -115, -415, 322, -30, -203, +475, -161, -298, 413, -285, -193, 511, -314, +-174, 452, -307, -15, 467, -395, -115, 306, +-413, 78, 431, -345, 135, 256, -525, 131, +248, -356, 280, 107, -473, 278, 128, -226, +379, -153, -456, 335, -61, -88, 521, -295, +-351, 421, -217, -74, 483, -454, -211, 521, +-215, 57, 362, -571, -141, 352, -200, 232, +315, -415, -71, 107, -242, 237, 210, -252, +116, -57, -266, 297, -6, -101, 354, -263, +-247, 266, -276, 56, 545, -286, -178, 227, +-398, 86, 585, -372, -225, 190, -371, 328, +597, -444, -143, -76, -408, 547, 358, -387, +81, -215, -294, 657, 108, -462, 227, -262, +-295, 782, -78, -487, 409, -346, -173, 795, +-268, -386, 336, -425, -16, 732, -301, -239, +300, -498, 69, 667, -358, -76, 199, -621, +145, 557, -258, 215, 113, -675, 135, 271, +-271, 414, 44, -571, 299, 86, -214, 516, +-178, -565, 299, -108, -19, 722, -276, -444, +264, -393, 85, 732, -411, -233, 261, -478, +242, 663, -473, -122, 140, -562, 334, 556, +-388, 98, 25, -535, 307, 303, -260, 183, +-46, -420, 254, 219, -141, 231, -127, -405, +205, 83, -30, 260, -141, -204, 102, -8, +47, 94, -101, -50, -19, -54, 154, 46, +-94, 147, -104, -205, 220, -66, -164, 306, +-67, -199, 313, -89, -221, 259, -160, -204, +315, -26, -68, 195, -172, -167, 159, 33, +-9, 111, -139, -155, 134, 19, 78, 115, +-230, -58, 82, -23, 188, 30, -260, -73, +46, 50, 232, 130, -252, -169, -3, -48, +218, 184, -177, -130, -17, 6, 189, 163, +-143, -243, -116, 37, 227, 227, 15, -221, +-253, 24, 137, 154, 150, -199, -269, 44, +128, 151, 179, -147, -343, -16, 123, 122, +236, -77, -304, -53, 20, 152, 234, -60, +-172, -149, -89, 213, 195, -27, -22, -210, +-178, 229, 126, -10, 116, -178, -242, 190, +59, -100, 229, -86, -235, 269, -50, -155, +237, -161, -135, 227, -84, -33, 211, -86, +-132, 113, -111, -84, 241, -97, -63, 195, +-184, 30, 185, -252, 31, 124, -204, 142, +148, -255, 93, 157, -227, 153, 45, -408, +184, 200, -130, 337, -63, -523, 122, 65, +-59, 488, -20, -492, 97, -29, -95, 536, +-49, -519, 143, -57, -29, 627, -109, -516, +81, -174, 27, 618, -82, -361, 59, -207, +21, 501, -65, -280, 5, -243, 42, 480, +18, -110, -72, -360, 45, 316, 13, 82, +-79, -320, 133, 201, -64, 147, -126, -365, +199, 153, -50, 282, -150, -391, 196, 30, +-39, 344, -157, -303, 154, -44, 10, 293, +-108, -212, 71, -85, 5, 276, -68, -101, +63, -245, 9, 236, -25, 164, -22, -320, +-19, -7, 104, 272, -42, -138, -103, -99, +118, 199, -30, -82, -93, -189, 195, 250, +-101, 98, -161, -365, 242, 119, -36, 273, +-156, -329, 168, 66, -36, 266, -165, -395, +230, 81, 21, 388, -288, -398, 188, -71, +114, 394, -240, -231, 116, -114, 83, 268, +-190, -133, 68, -99, 141, 183, -160, -30, +-20, -152, 185, 81, -173, 138, -23, -150, +231, -53, -215, 163, -19, -87, 215, -11, +-217, 95, 47, -153, 198, 64, -262, 95, +39, -158, 206, 123, -183, -14, -29, -186, +149, 286, -78, -49, -101, -281, 159, 327, +7, -65, -202, -258, 132, 397, 117, -141, +-222, -313, 64, 439, 135, -74, -174, -325, +40, 356, 137, -53, -151, -295, -44, 327, +214, -8, -87, -279, -152, 220, 165, 17, +23, -175, -126, 164, 73, 2, 41, -164, +-101, 92, 38, 103, 71, -118, -53, -30, +-70, 124, 75, -90, 78, -28, -191, 145, +66, -117, 200, -29, -280, 116, 37, -100, +266, 18, -278, 78, -8, -84, 290, -21, +-223, 44, -136, 25, 311, -16, -61, -17, +-251, -8, 227, -6, 33, 46, -216, -4, +184, -32, 48, -5, -254, -1, 131, 58, +162, -21, -212, -40, 28, 29, 113, -49, +-124, 45, 58, 65, 71, -93, -136, -18, +36, 19, 85, 42, -60, 52, -11, -109, +0, -41, 25, 99, 12, 21, -48, -46, +48, -15, -28, 8, -45, -31, 116, 63, +-60, 65, -78, -134, 100, -27, -13, 104, +-32, 16, 36, -24, -31, -57, -49, 20, +92, 46, 30, -33, -145, 31, 66, -2, +58, -71, -93, 59, 69, 48, 1, -98, +-88, 20, 88, 115, 21, -131, -118, -74, +88, 216, 58, -34, -158, -169, 70, 110, +66, 27, -98, -77, 72, 93, -40, 1, +-36, -129, 88, 44, -63, 110, 41, -58, +5, -58, -109, 64, 115, -36, 23, -45, +-99, 149, 60, -38, -15, -193, -20, 155, +53, 90, -14, -204, -24, 118, -21, 76, +41, -242, 26, 158, -63, 135, 5, -260, +62, 87, -51, 139, -58, -179, 118, 50, +-15, 107, -142, -130, 142, 10, 17, 112, +-166, -108, 175, -31, 0, 135, -189, -88, +194, -54, 25, 118, -225, -64, 152, -42, +132, 96, -256, -23, 54, -69, 207, 12, +-221, 86, 8, -27, 212, -87, -224, 93, +-40, -5, 283, -75, -182, 92, -142, -9, +273, -66, -87, 35, -170, 3, 241, -7, +-19, 3, -233, -2, 195, -15, 86, -10, +-246, 46, 122, -9, 140, -60, -264, 35, +100, 55, 207, -53, -305, -59, 50, 92, +282, 41, -297, -139, -42, 42, 349, 103, +-245, -138, -129, 43, 350, 113, -199, -184, +-143, 42, 330, 167, -161, -185, -181, 15, +292, 155, -51, -188, -204, 22, 175, 166, +70, -153, -205, 1, 55, 84, 189, -79, +-216, 61, -43, -22, 280, -15, -199, 60, +-113, -136, 307, 111, -172, 73, -150, -201, +301, 155, -126, 16, -199, -192, 287, 197, +-8, 29, -290, -184, 207, 86, 124, 62, +-277, -107, 126, 68, 137, 96, -250, -230, +91, 36, 171, 274, -211, -234, -19, -53, +185, 250, -104, -225, -86, -54, 169, 337, +-40, -173, -157, -287, 154, 341, 54, 83, +-179, -368, 85, 217, 97, 126, -149, -368, +43, 229, 131, 175, -164, -364, -6, 141, +178, 175, -151, -262, -39, 92, 182, 162, +-119, -199, -74, -14, 134, 157, 3, -75, +-87, -54, 9, 89, 82, -52, -59, -49, +-23, 98, 94, -4, -71, -94, -74, 61, +147, 50, -2, -122, -165, 67, 110, 105, +94, -188, -159, 25, 22, 156, 136, -135, +-133, 13, -35, 101, 159, -135, -90, 19, +-100, 121, 191, -68, -39, -61, -181, 10, +205, 72, 1, 7, -205, -98, 183, 88, +32, -8, -221, -127, 172, 195, 75, 6, +-245, -268, 133, 193, 110, 139, -203, -286, +75, 111, 107, 164, -164, -282, 62, 102, +110, 225, -176, -313, 41, 20, 152, 300, +-166, -255, -13, -68, 154, 284, -122, -170, +-22, -107, 134, 236, -107, -100, -42, -132, +159, 193, -86, -41, -95, -139, 160, 158, +-27, -8, -138, -150, 129, 144, 56, 31, +-175, -189, 86, 109, 86, 117, -139, -164, +63, -15, 30, 119, -58, -32, 28, -43, +-13, 48, 33, -27, -21, -73, -46, 120, +98, 69, -55, -214, -70, 14, 131, 220, +-22, -142, -112, -73, 93, 164, 47, -118, +-126, -67, 63, 205, 83, -22, -179, -230, +84, 114, 111, 212, -174, -265, 65, -29, +90, 307, -152, -268, 66, -80, 112, 384, +-184, -303, 55, -120, 127, 484, -184, -341, +82, -253, 99, 575, -195, -185, 109, -375, +100, 425, -208, -79, 103, -295, 115, 412, +-193, -71, 44, -397, 115, 341, -101, 118, +-7, -284, 54, 106, -30, 56, -34, -122, +67, 73, 10, 100, -98, -115, 45, -119, +78, 201, -88, 39, -10, -256, 95, 160, +-68, 127, -31, -294, 67, 137, 20, 185, +-95, -290, 20, 73, 106, 214, -122, -241, +3, -25, 94, 264, -43, -147, -92, -156, +122, 234, 24, -39, -194, -180, 196, 210, +4, 6, -209, -249, 186, 176, 52, 125, +-208, -227, 114, 25, 100, 153, -179, -121, +74, -38, 53, 166, -78, -106, 31, -91, +6, 160, 2, -15, -42, -123, 72, 68, +-8, 85, -94, -168, 88, 84, 22, 134, +-77, -263, 10, 106, 95, 157, -88, -211, +-43, 30, 172, 122, -143, -100, -48, -42, +223, 164, -205, -85, -21, -156, 242, 237, +-212, -29, -20, -209, 190, 212, -120, -14, +-107, -186, 238, 189, -102, 33, -182, -192, +295, 88, -136, 118, -110, -158, 226, -8, +-110, 177, -96, -147, 168, -87, -21, 226, +-155, -100, 146, -78, 0, 159, -118, -156, +94, 56, -1, 118, -52, -167, 19, 93, +21, -22, -22, -48, -12, 123, 42, -108, +-19, 34, -49, 41, 61, -157, 70, 155, +-161, 42, 57, -199, 145, 140, -231, 1, +113, -115, 96, 174, -208, -66, 117, -110, +61, 130, -130, -16, 29, -54, 107, 40, +-76, 31, -101, -63, 168, -69, 3, 187, +-215, 11, 193, -301, 61, 216, -269, 188, +200, -450, 92, 237, -289, 321, 158, -627, +133, 278, -253, 370, 100, -664, 134, 361, +-184, 295, 5, -713, 195, 350, -155, 436, +-76, -684, 223, 152, -138, 475, -15, -635, +82, 219, -59, 453, 46, -719, -62, 260, +45, 399, 37, -615, -98, 344, 38, 145, +101, -528, -164, 505, 51, -89, 162, -349, +-242, 510, 73, -342, 197, -87, -253, 495, +14, -495, 247, 17, -210, 511, -34, -549, +190, -10, -105, 591, -59, -539, 128, -103, +-17, 612, -143, -454, 166, -189, 13, 608, +-177, -310, 121, -360, 93, 590, -182, -96, +53, -524, 156, 550, -205, 64, 67, -655, +119, 558, -173, 181, 44, -730, 142, 462, +-147, 289, -30, -670, 194, 293, -144, 411, +-52, -651, 210, 136, -132, 569, -110, -632, +246, -1, -70, 598, -181, -546, 242, -83, +-23, 613, -212, -428, 234, -291, 29, 654, +-257, -183, 175, -514, 178, 579, -313, 27, +44, -609, 366, 507, -400, 186, -10, -648, +469, 325, -441, 353, -22, -556, 467, 72, +-398, 504, -41, -454, 401, -205, -264, 637, +-132, -259, 324, -454, -40, 620, -316, -47, +323, -647, 106, 622, -448, 204, 356, -830, +102, 456, -395, 417, 310, -738, 73, 239, +-273, 466, 158, -625, 109, 31, -116, 617, +-79, -488, 236, -274, -14, 700, -341, -289, +435, -457, 10, 681, -502, -98, 547, -599, +-14, 563, -514, 172, 560, -744, -4, 478, +-517, 397, 482, -936, 109, 476, -499, 523, +316, -956, 259, 400, -449, 525, 109, -842, +382, 156, -333, 760, -111, -682, 406, -381, +-153, 1070, -246, -432, 338, -840, 54, 1243, +-342, -172, 194, -1215, 275, 1222, -337, 264, +-57, -1459, 452, 911, -205, 755, -371, -1554, +567, 438, 33, 1296, -632, -1430, 477, -276, +370, 1611, -739, -877, 207, -938, 704, 1525, +-745, -144, -138, -1463, 986, 1151, -615, 768, +-538, -1747, 1143, 370, -347, 1614, -848, -1593, +1090, -519, -7, 2160, -972, -1216, 751, -1316, +437, 2380, -953, -583, 233, -1912, 835, 2032, +-771, 280, -291, -2075, 1042, 1207, -425, 1072, +-745, -1860, 1088, 270, -39, 1595, -1057, -1365, +960, -572, 338, 1663, -1161, -579, 630, -1166, +635, 1270, -1019, 317, 214, -1455, 756, 654, +-639, 1001, -222, -1349, 761, 8, -227, 1237, +-533, -832, 632, -575, 140, 1080, -688, -87, +366, -971, 494, 639, -768, 573, 168, -992, +654, 79, -667, 918, 28, -679, 546, -478, +-327, 941, -161, -30, 363, -954, -3, 518, +-305, 752, 211, -1052, 216, -110, -388, 1254, +122, -869, 355, -688, -412, 1478, 78, -421, +385, -1182, -415, 1302, 89, 159, 360, -1332, +-453, 855, 175, 575, 253, -1191, -436, 337, +261, 802, 152, -790, -390, -168, 271, 702, +200, -223, -415, -440, 187, 350, 287, 253, +-378, -388, 48, -138, 291, 463, -219, -26, +-125, -565, 285, 431, 4, 352, -341, -805, +279, 268, 266, 640, -537, -720, 173, -153, +472, 780, -560, -285, -56, -663, 637, 779, +-458, 177, -313, -1043, 725, 649, -237, 627, +-504, -1184, 589, 271, 110, 985, -615, -1051, +317, -143, 415, 1161, -641, -808, 19, -481, +635, 1159, -475, -434, -399, -740, 819, 916, +-169, 38, -785, -826, 831, 481, 168, 448, +-994, -713, 629, 15, 489, 676, -1074, -457, +354, -356, 742, 697, -1007, -106, 120, -636, +789, 519, -722, 301, -125, -724, 677, 188, +-326, 599, -420, -638, 549, -159, 25, 823, +-627, -465, 380, -534, 270, 889, -594, -124, +179, -756, 315, 666, -391, 196, 37, -749, +236, 384, -193, 423, -120, -680, 182, 62, +-28, 622, -213, -465, 82, -335, 76, 696, +-145, -144, -31, -611, 98, 640, -98, 104, +27, -725, -53, 454, -14, 369, 94, -696, +-290, 112, 143, 605, 123, -549, -391, -185, +100, 681, 259, -363, -345, -346, -81, 583, +390, -121, -304, -406, -199, 342, 397, 131, +-204, -327, -358, 35, 368, 253, -22, -104, +-404, -215, 141, 200, 216, 131, -241, -304, +-255, 68, 411, 252, -58, -243, -567, -59, +447, 236, 166, -90, -796, -112, 328, 98, +480, 54, -877, -37, 105, -151, 685, 145, +-708, 220, -239, -475, 783, 122, -423, 545, +-627, -660, 787, -15, -79, 728, -885, -607, +578, -230, 314, 787, -921, -385, 283, -468, +560, 713, -834, -145, 51, -479, 653, 494, +-733, -51, -117, -277, 597, 213, -551, 6, +-156, -30, 388, -71, -375, -9, -38, 188, +174, -97, -297, -220, 80, 239, 55, 181, +-348, -455, 161, 119, 76, 493, -477, -580, +131, -71, 279, 728, -564, -521, -76, -350, +543, 774, -454, -182, -410, -620, 701, 511, +-276, 341, -714, -713, 714, 33, 16, 835, +-964, -644, 491, -549, 504, 1204, -1032, -293, +-2, -1134, 941, 1167, -829, 310, -524, -1389, +1104, 696, -463, 841, -946, -1260, 1001, 44, +2, 1221, -1147, -861, 584, -674, 486, 1329, +-986, -172, -32, -1254, 797, 1021, -592, 585, +-593, -1462, 827, 478, -103, 1101, -972, -1250, +531, -173, 480, 1243, -1038, -571, -54, -813, +912, 934, -718, 340, -616, -1146, 956, 328, +-204, 1022, -984, -1042, 695, -355, 322, 1344, +-1060, -573, 105, -1014, 822, 1317, -794, 132, +-627, -1451, 1124, 879, -306, 835, -1170, -1442, +1018, 181, 266, 1269, -1407, -1068, 566, -484, +802, 1377, -1336, -494, -51, -992, 1095, 1130, +-865, 200, -665, -1169, 1069, 542, -263, 715, +-1017, -913, 762, -96, 267, 909, -1097, -421, +269, -681, 674, 837, -890, 240, -270, -1041, +779, 396, -404, 803, -665, -913, 619, -192, +46, 1001, -780, -459, 315, -697, 275, 901, +-568, 159, -129, -1045, 336, 481, -163, 815, +-462, -1016, 154, -227, 233, 1231, -461, -566, +-224, -930, 520, 1230, -276, 124, -633, -1379, +599, 796, 88, 926, -949, -1465, 349, -28, +555, 1611, -955, -1100, -153, -895, 896, 1800, +-641, -437, -703, -1456, 1007, 1493, -176, 368, +-1152, -1707, 859, 769, 355, 1164, -1368, -1478, +442, -192, 829, 1526, -1239, -766, -86, -974, +1014, 1355, -783, 78, -567, -1382, 910, 808, +-208, 827, -904, -1297, 567, -4, 319, 1241, +-891, -729, 20, -755, 623, 1141, -499, 31, +-533, -1102, 633, 616, 34, 698, -888, -992, +381, -178, 529, 1146, -965, -442, -102, -1017, +900, 1144, -697, 342, -663, -1446, 984, 670, +-209, 976, -992, -1335, 702, -41, 313, 1340, +-1023, -843, 155, -777, 754, 1365, -802, -157, +-437, -1207, 906, 958, -335, 475, -840, -1166, +679, 278, 240, 915, -998, -800, 244, -414, +699, 1056, -891, -264, -261, -845, 899, 789, +-523, 285, -691, -892, 788, 279, -44, 660, +-847, -655, 402, -218, 386, 742, -754, -237, +-31, -549, 574, 539, -498, 192, -296, -606, +404, 172, -83, 409, -401, -308, 20, -246, +290, 349, -284, 213, -354, -598, 372, 123, +67, 688, -642, -728, 193, -161, 467, 895, +-700, -521, -211, -475, 773, 795, -447, -50, +-717, -735, 876, 501, -43, 428, -1002, -793, +624, 94, 444, 702, -1070, -507, 146, -392, +888, 721, -958, 5, -306, -795, 974, 526, +-479, 475, -733, -873, 782, 125, 112, 756, +-989, -614, 492, -347, 458, 832, -852, -211, +9, -693, 627, 667, -465, 267, -473, -827, +632, 243, -88, 694, -628, -731, 337, -161, +250, 831, -522, -432, -94, -483, 508, 691, +-337, 59, -402, -755, 508, 457, -90, 430, +-480, -789, 228, 220, 211, 513, -383, -513, +-159, -124, 411, 488, -187, -100, -394, -470, +327, 417, 112, 184, -487, -561, 4, 244, +545, 325, -580, -395, -280, -89, 813, 401, +-564, -79, -352, -416, 666, 351, -263, 216, +-416, -560, 296, 200, 213, 459, -546, -558, +43, -103, 441, 674, -468, -361, -149, -445, +364, 707, -102, -55, -389, -710, 232, 621, +198, 278, -443, -922, -4, 516, 338, 475, +-212, -914, -408, 412, 460, 363, 65, -602, +-713, 254, 453, 132, 284, -152, -756, 14, +213, -51, 496, 208, -629, -143, -103, -151, +590, 321, -391, -172, -312, -95, 415, 185, +22, -110, -459, 81, 93, -139, 500, 43, +-592, 253, -173, -448, 774, 195, -568, 348, +-384, -586, 814, 186, -357, 434, -548, -557, +698, 27, -111, 528, -565, -497, 438, -80, +91, 584, -402, -503, 52, -29, 250, 426, +-122, -403, -362, 192, 349, -33, 134, -131, +-639, 367, 355, -477, 329, 222, -723, 359, +216, -752, 520, 409, -740, 479, 87, -942, +615, 329, -746, 832, 109, -1257, 491, 296, +-651, 1258, 206, -1744, 255, 466, -500, 1434, +311, -2108, 8, 897, -355, 1127, 395, -2169, +-203, 1409, -196, 403, 385, -1784, -307, 1795, +-67, -512, 320, -1184, -365, 2021, 86, -1225, +211, -678, -411, 2094, 281, -1690, 54, -326, +-471, 2142, 505, -1947, -90, -114, -559, 1982, +729, -1904, -246, 139, -540, 1478, 769, -1530, +-277, 289, -457, 803, 577, -822, -96, 179, +-412, 266, 319, -210, 87, -57, -296, 183, +4, -43, 229, -186, -73, 319, -371, -256, +417, -51, 66, 464, -624, -555, 541, 58, +96, 590, -634, -643, 451, -41, 154, 727, +-551, -569, 281, -348, 290, 941, -622, -399, +333, -740, 283, 1121, -754, -189, 619, -1058, +-6, 1183, -642, 59, 765, -1330, -298, 1169, +-392, 311, 660, -1535, -342, 1172, -218, 404, +437, -1565, -236, 1117, -62, 378, 90, -1308, +45, 835, -37, 317, -217, -899, 359, 489, +-152, 287, -275, -554, 431, 184, -189, 213, +-194, -181, 296, -55, -100, 62, -125, 158, +125, -266, 42, 58, -179, 276, 114, -373, +122, 189, -368, 19, 386, -161, -59, 309, +-479, -388, 774, 182, -458, 259, -361, -535, +980, 273, -747, 344, -191, -548, 932, -91, +-734, 883, -172, -714, 796, -456, -511, 1432, +-288, -1091, 656, -386, -214, 1558, -442, -1234, +524, -176, 48, 1138, -551, -863, 403, -20, +205, 508, -545, -308, 238, -55, 317, 34, +-440, 262, 8, -258, 416, -179, -316, 569, +-159, -464, 444, -49, -188, 515, -289, -541, +421, 166, -21, 273, -459, -469, 476, 341, +35, 76, -581, -504, 610, 518, -51, 21, +-586, -639, 719, 705, -187, -66, -489, -723, +681, 864, -176, -181, -468, -620, 545, 793, +100, -348, -745, -186, 599, 460, 360, -522, +-1111, 459, 763, -152, 475, -532, -1269, 1178, +734, -920, 617, -409, -1286, 1670, 525, -1451, +858, -206, -1295, 1711, 295, -1515, 1034, -163, +-1187, 1509, 75, -1099, 988, -435, -777, 1253, +-311, -544, 922, -678, -263, 954, -811, -116, +974, -677, 52, 453, -1031, 337, 844, -503, +301, -236, -1031, 809, 545, -292, 635, -815, +-1157, 1140, 490, -153, 686, -1134, -1177, 1290, +645, -87, 329, -1205, -860, 1231, 671, -26, +-55, -1070, -441, 947, 547, 97, -250, -867, +-124, 619, 309, 250, -191, -765, 11, 415, +33, 382, 51, -739, 7, 310, -236, 411, +376, -717, -52, 332, -524, 358, 754, -710, +-210, 380, -630, 277, 953, -622, -385, 382, +-447, 146, 754, -459, -364, 331, -132, 27, +272, -214, -159, 155, 178, -90, -244, 108, +29, -35, 475, -206, -639, 344, 70, -52, +777, -483, -914, 573, 82, 176, 919, -1085, +-1001, 964, 93, 419, 809, -1718, -788, 1390, +27, 502, 558, -2035, -425, 1476, -54, 670, +293, -2055, -138, 1125, -29, 1054, 26, -1974, +0, 572, 129, 1477, -195, -1711, -49, -101, +405, 1712, -365, -1164, -166, -835, 641, 1836, +-458, -557, -204, -1564, 619, 1960, -306, -27, +-275, -2095, 407, 1968, 29, 299, -386, -2261, +192, 1853, 266, 438, -318, -2189, -86, 1611, +340, 562, -8, -1968, -484, 1249, 403, 635, +325, -1640, -878, 851, 528, 711, 452, -1298, +-1030, 363, 595, 927, 360, -1044, -851, -150, +506, 1260, 182, -945, -487, -540, 270, 1541, +83, -876, -189, -778, 43, 1630, 101, -719, +-97, -976, 1, 1581, 104, -450, -141, -1133, +46, 1419, 150, -168, -243, -1187, 81, 1160, +255, 127, -396, -1177, 126, 829, 329, 411, +-454, -1077, 61, 488, 388, 583, -334, -899, +-177, 162, 470, 708, -134, -664, -428, -173, +470, 733, 113, -392, -577, -348, 291, 612, +400, -179, -602, -372, -4, 401, 668, 41, +-505, -325, -355, 88, 873, 251, -390, -150, +-558, -268, 885, 389, -263, 45, -519, -580, +590, 502, -9, 211, -405, -748, 166, 429, +256, 405, -220, -743, -227, 167, 389, 651, +48, -718, -581, -78, 477, 836, 257, -707, +-811, -148, 529, 799, 318, -645, -817, -78, +444, 619, 346, -491, -711, -56, 306, 406, +391, -296, -650, -50, 264, 272, 299, -216, +-508, 9, 230, 172, 165, -227, -259, 179, +-11, -44, 256, -161, -102, 337, -362, -335, +570, 66, -108, 344, -690, -554, 920, 275, +-133, 331, -996, -659, 1221, 311, -123, 407, +-1253, -750, 1401, 279, -54, 592, -1405, -876, +1355, 149, 170, 813, -1442, -877, 1029, -75, +534, 920, -1348, -691, 485, -291, 936, 816, +-1134, -333, -100, -432, 1221, 465, -853, 148, +-518, -440, 1218, -46, -473, 606, -729, -342, +936, -552, 1, 940, -835, -181, 522, -933, +486, 1054, -841, 70, 52, -1179, 881, 921, +-726, 471, -404, -1344, 1140, 606, -550, 894, +-684, -1341, 1123, 205, -297, 1104, -743, -1038, +807, -200, 72, 1035, -716, -586, 369, -439, +434, 827, -598, -283, -85, -439, 718, 543, +-406, -94, -523, -256, 956, 150, -262, 74, +-834, -17, 1094, -206, -141, 204, -1022, 120, +1119, -424, 18, 309, -1185, 199, 1110, -580, +194, 358, -1320, 298, 1017, -683, 419, 358, +-1369, 361, 789, -731, 646, 360, -1284, 390, +448, -749, 845, 347, -1040, 410, -50, -759, +1096, 317, -764, 487, -612, -782, 1401, 215, +-532, 635, -1074, -835, 1547, 89, -225, 884, +-1373, -970, 1368, -101, 259, 1212, -1504, -1038, +872, -347, 862, 1428, -1518, -966, 299, -603, +1366, 1543, -1464, -753, -113, -916, 1580, 1564, +-1280, -424, -386, -1208, 1538, 1476, -932, -35, +-629, -1447, 1359, 1187, -491, 521, -840, -1559, +1083, 662, -36, 1078, -961, -1570, 743, 249, +374, 1407, -978, -1559, 362, 70, 726, 1388, +-944, -1303, 32, -21, 1000, 1037, -931, -798, +-208, -168, 1186, 722, -867, -295, -417, -509, +1289, 623, -732, 165, -611, -900, 1274, 582, +-473, 500, -823, -1112, 1110, 517, 10, 634, +-1151, -1098, 891, 404, 582, 671, -1459, -972, +618, 211, 1048, 742, -1496, -829, 144, 16, +1462, 743, -1326, -668, -421, -63, 1799, 604, +-1136, -449, -818, -92, 1909, 368, -913, -144, +-1006, -147, 1780, 89, -628, 192, -1053, -224, +1466, -131, -292, 464, -981, -307, 1011, -245, +21, 580, -775, -286, 534, -288, 186, 503, +-448, -159, 131, -305, 217, 386, -118, -48, +-161, -313, 184, 318, 125, -24, -310, -215, +95, 241, 322, -161, -381, 32, -24, 181, +496, -372, -400, 295, -166, 83, 596, -485, +-316, 529, -300, -57, 572, -580, -163, 681, +-347, -15, 415, -707, 13, 631, -341, 170, +263, -751, 140, 483, -365, 312, 232, -741, +152, 371, -355, 400, 209, -700, 146, 265, +-294, 363, 123, -504, 176, 171, -218, 161, +4, -182, 171, 38, -36, 13, -173, 77, +140, -154, 178, 60, -350, 119, 104, -223, +339, 204, -415, -108, -20, -130, 523, 392, +-428, -401, -196, -65, 678, 618, -422, -593, +-277, -164, 706, 865, -356, -657, -325, -372, +638, 1077, -198, -586, -443, -591, 581, 1103, +44, -362, -655, -740, 560, 941, 271, -52, +-826, -826, 506, 694, 417, 252, -807, -799, +292, 346, 546, 464, -663, -549, 6, -63, +667, 544, -543, -253, -189, -391, 732, 615, +-448, -57, -336, -624, 757, 608, -313, 118, +-495, -653, 755, 415, -165, 192, -612, -464, +731, 212, -98, 134, -609, -231, 696, 70, +-136, 13, -476, -3, 600, 18, -172, -171, +-331, 140, 464, 101, -114, -303, -272, 104, +329, 211, 6, -269, -226, -27, 141, 249, +160, -149, -172, -134, -45, 225, 294, -11, +-166, -206, -111, 154, 316, 116, -125, -195, +-146, 33, 257, 156, 1, -46, -229, -105, +239, 72, 58, 179, -263, -183, 230, -78, +8, 337, -149, -116, 141, -301, -61, 361, +11, 170, 26, -580, -100, 286, 72, 497, +44, -814, -136, 202, 10, 702, 207, -911, +-241, 74, -53, 838, 344, -832, -315, -147, +-65, 914, 347, -712, -237, -314, -113, 997, +280, -699, -87, -391, -143, 1063, 172, -710, +58, -374, -115, 1001, -26, -683, 265, -241, +-137, 847, -172, -670, 457, -83, -219, 708, +-187, -660, 459, 55, -182, 629, -175, -694, +337, 115, -41, 663, -201, -722, 208, 58, +58, 737, -169, -664, 102, -77, 36, 744, +-24, -506, -13, -215, -61, 666, 190, -295, +-196, -328, -79, 526, 375, -81, -439, -396, +48, 340, 415, 127, -596, -430, 199, 134, +331, 330, -565, -439, 207, -56, 259, 464, +-397, -411, 102, -157, 186, 470, -168, -382, +14, -108, 21, 374, 102, -380, -21, 44, +-188, 219, 344, -374, -40, 240, -320, 60, +475, -408, -48, 414, -386, 56, 537, -521, +-55, 435, -434, 227, 611, -603, -108, 323, +-445, 406, 639, -614, -125, 193, -452, 550, +566, -593, -43, 27, -480, 666, 489, -518, +-8, -145, -438, 686, 396, -374, -51, -289, +-272, 621, 215, -164, -50, -482, -95, 528, +2, 116, 0, -670, 40, 381, -158, 319, +25, -692, 187, 199, -295, 412, 18, -605, +331, 3, -393, 521, 26, -528, 409, -212, +-411, 638, 37, -434, 393, -367, -336, 719, +10, -372, 334, -476, -178, 831, -95, -362, +320, -542, -45, 904, -214, -338, 341, -517, +3, 820, -230, -212, 261, -455, 69, 589, +-190, 23, 88, -412, 208, 325, -220, 240, +-45, -324, 318, 77, -254, 307, -101, -121, +321, -160, -230, 274, -137, 134, 292, -417, +-194, 227, -168, 389, 283, -629, -177, 125, +-196, 565, 286, -649, -144, -35, -215, 577, +253, -509, -49, -186, -206, 492, 134, -306, +113, -303, -200, 374, -28, -101, 319, -353, +-222, 238, -159, 39, 514, -325, -272, 114, +-265, 159, 686, -266, -293, -72, -345, 352, +732, -221, -228, -284, -363, 618, 570, -270, +-57, -397, -297, 813, 258, -354, 134, -365, +-179, 824, -44, -374, 249, -265, -70, 710, +-242, -329, 270, -172, 34, 549, -371, -267, +243, -93, 142, 391, -489, -181, 220, -117, +264, 269, -568, -17, 155, -269, 375, 168, +-556, 199, 42, -394, 433, 11, -466, 363, +-52, -383, 407, -164, -308, 425, -123, -314, +354, -283, -163, 458, -186, -254, 358, -360, +-92, 452, -236, -165, 420, -365, -91, 336, +-279, -14, 497, -305, -127, 133, -275, 197, +480, -247, -81, -110, -283, 420, 383, -140, +64, -358, -386, 510, 356, 96, 101, -551, +-403, 441, 324, 385, 51, -730, -265, 329, +97, 677, 155, -870, -182, 197, -194, 829, +394, -858, -198, 123, -413, 729, 561, -737, +-144, 146, -567, 479, 564, -542, 13, 138, +-632, 203, 403, -247, 255, 38, -636, -32, +157, 15, 528, -32, -633, -170, -37, 104, +710, -10, -588, -229, -150, 80, 728, 72, +-437, -248, -216, 9, 609, 138, -218, -202, +-236, -47, 398, 198, -39, -208, -151, -37, +154, 333, 51, -382, 33, 29, -101, 512, +64, -563, 235, 101, -333, 585, 84, -618, +366, 161, -509, 538, 157, -588, 364, 184, +-599, 484, 255, -495, 262, 107, -589, 407, +302, -297, 166, -36, -528, 297, 286, -67, +122, -214, -432, 209, 191, 158, 120, -389, +-266, 113, 3, 331, 194, -484, -127, 22, +-208, 417, 330, -474, -69, -88, -326, 414, +427, -351, -11, -203, -415, 343, 438, -175, +130, -245, -542, 236, 412, -80, 309, -181, +-644, 159, 338, -93, 428, -69, -639, 162, +209, -156, 465, -13, -507, 234, 39, -212, +442, -27, -296, 341, -183, -255, 427, -68, +-111, 490, -368, -329, 376, -158, 57, 677, +-440, -377, 202, -294, 247, 785, -449, -317, +38, -413, 331, 742, -364, -170, -56, -497, +244, 607, -152, -4, -157, -536, 165, 436, +-7, 124, -210, -503, 164, 242, -6, 216, +-156, -424, 145, 50, -11, 269, -92, -331, +126, -72, -8, 247, -88, -218, 172, -106, +-49, 147, -101, -95, 265, -81, -139, 27, +-79, 16, 320, -62, -231, -47, 2, 121, +267, -84, -230, -74, 51, 188, 161, -99, +-173, -19, 63, 147, 68, -89, -141, 70, +114, 74, -41, -72, -102, 109, 160, 41, +-124, -69, -80, 112, 187, 55, -160, -80, +-116, 63, 253, 108, -194, -80, -162, -37, +332, 188, -252, -94, -140, -128, 368, 251, +-292, -124, -64, -202, 287, 295, -222, -86, +-29, -311, 131, 300, -9, 2, -100, -390, +30, 251, 194, 63, -201, -372, 5, 174, +277, 108, -242, -312, 13, 96, 251, 141, +-227, -230, 84, 21, 132, 98, -181, -59, +148, -35, 2, 8, -117, 108, 167, -83, +-65, -31, -87, 190, 163, -101, -80, -30, +-101, 194, 151, -72, -53, -14, -140, 135, +129, -46, 15, 34, -195, 56, 97, -20, +98, 55, -232, -7, 34, 8, 180, 67, +-230, -68, -32, -7, 218, 130, -174, -137, +-94, -57, 187, 207, -44, -167, -173, -116, +135, 198, 135, -91, -296, -177, 123, 108, +265, 70, -385, -241, 107, -1, 333, 238, +-382, -278, 52, -117, 365, 352, -336, -231, +-9, -213, 346, 389, -276, -135, -19, -272, +267, 374, -206, -59, -10, -273, 175, 356, +-146, -45, -4, -239, 137, 340, -152, -60, +0, -174, 160, 318, -222, -95, 39, -142, +186, 333, -287, -118, 60, -180, 204, 377, +-303, -118, 44, -248, 225, 391, -303, -90, +73, -295, 138, 345, -214, -26, 129, -315, +-62, 242, -15, 51, 124, -278, -240, 115, +174, 76, 104, -185, -325, 5, 234, 64, +139, -78, -346, -84, 159, 76, 261, -4, +-351, -163, 22, 89, 432, 65, -391, -200, +-57, 75, 467, 140, -339, -200, -101, 27, +385, 193, -163, -168, -225, -22, 320, 230, +-3, -110, -344, -85, 300, 252, 74, -74, +-366, -121, 224, 268, 110, -73, -290, -107, +94, 217, 126, -56, -154, -59, -73, 104, +151, 16, -23, -59, -201, -17, 162, 115, +67, -75, -267, -104, 155, 148, 116, -57, +-274, -130, 127, 97, 133, -2, -232, -127, +78, 7, 157, 90, -200, -154, 40, -51, +183, 188, -191, -210, 20, -48, 191, 238, +-169, -230, -30, -42, 237, 247, -164, -184, +-98, -80, 296, 257, -155, -100, -143, -157, +283, 232, -59, 43, -247, -218, 272, 140, +45, 199, -350, -262, 249, 69, 131, 318, +-375, -341, 152, 26, 241, 438, -366, -427, +34, -31, 311, 552, -310, -512, -45, -59, +243, 630, -116, -587, -188, -61, 198, 645, +69, -603, -320, -82, 193, 624, 161, -556, +-352, -113, 120, 570, 257, -459, -330, -162, +15, 476, 344, -281, -322, -245, -20, 377, +311, -74, -222, -329, -41, 274, 194, 81, +-49, -311, -99, 126, 77, 200, 119, -235, +-167, -24, -14, 306, 246, -217, -199, -83, +-99, 371, 320, -237, -185, -97, -163, 389, +334, -212, -159, -145, -170, 405, 280, -177, +-113, -221, -142, 421, 205, -112, -97, -320, +-86, 394, 135, 37, -103, -444, -7, 335, +38, 165, -31, -521, -2, 301, -50, 190, +116, -512, -119, 268, -39, 190, 215, -465, +-226, 194, -23, 206, 335, -413, -338, 157, +-48, 170, 483, -353, -438, 210, -91, 46, +590, -269, -447, 268, -179, -93, 637, -122, +-360, 231, -298, -168, 619, 30, -209, 126, +-397, -137, 505, 108, 4, 12, -492, -49, +378, 127, 180, -69, -505, 0, 213, 112, +331, -74, -480, 33, 36, 11, 467, 8, +-462, 53, -58, -140, 484, 156, -398, -3, +-110, -215, 443, 296, -311, -155, -126, -183, +370, 372, -241, -267, -92, -128, 235, 361, +-131, -268, -82, -94, 134, 275, -7, -209, +-134, -55, 104, 150, 76, -85, -187, -38, +67, -22, 195, 134, -304, -74, 97, -192, +284, 347, -414, -126, 133, -280, 335, 461, +-451, -144, 76, -326, 431, 507, -458, -104, +-38, -409, 520, 528, -413, -12, -154, -476, +510, 452, -226, 94, -333, -438, 467, 270, +2, 192, -492, -341, 397, 63, 156, 279, +-524, -232, 258, -108, 261, 299, -447, -123, +85, -193, 314, 249, -305, -57, -70, -196, +303, 185, -157, -21, -176, -151, 239, 102, +6, 18, -254, -106, 175, 16, 107, 70, +-262, -80, 131, -16, 111, 52, -187, -58, +68, 59, 95, -49, -101, -33, -23, 148, +156, -135, -120, -2, -35, 174, 165, -149, +-123, 21, -37, 141, 160, -114, -94, 14, +-56, 79, 159, -35, -68, 3, -81, 4, +110, 33, 34, 33, -157, -82, 71, 40, +155, 95, -256, -135, 88, -1, 183, 159, +-260, -146, 24, -85, 257, 264, -280, -158, +-15, -231, 298, 413, -291, -152, -4, -352, +232, 478, -190, -121, -76, -370, 252, 438, +-188, -97, -39, -328, 210, 391, -224, -117, +123, -215, -9, 309, -84, -181, 147, -25, +-108, 189, -27, -220, 123, 106, -48, 145, +-138, -263, 240, 125, -96, 203, -141, -344, +240, 171, -49, 219, -193, -398, 199, 214, +94, 189, -326, -318, 219, 65, 167, 236, +-370, -172, 193, -154, 177, 309, -321, -76, +105, -249, 209, 280, -257, -8, 3, -265, +250, 195, -196, 98, -125, -300, 361, 138, +-262, 147, -91, -291, 371, 124, -339, 101, +15, -218, 286, 105, -289, 76, -35, -182, +334, 82, -306, 99, -45, -199, 378, 92, +-391, 109, 72, -205, 256, 111, -290, 92, +42, -180, 199, 61, -158, 131, -63, -120, +219, -94, -158, 271, 0, -109, 114, -229, +-99, 405, 47, -170, -7, -229, -2, 437, +51, -212, -100, -181, 65, 379, 80, -195, +-170, -108, 91, 236, 94, -127, -207, -16, +162, 40, -4, 14, -146, -40, 190, -63, +-97, 187, -63, -200, 156, 0, -129, 230, +2, -300, 118, 114, -156, 131, 31, -257, +149, 157, -219, 43, 48, -183, 205, 106, +-294, 101, 86, -230, 244, 109, -416, 175, +231, -349, 167, 227, -428, 124, 308, -387, +75, 330, -359, 30, 292, -349, 49, 380, +-349, -52, 327, -334, 37, 460, -405, -120, +429, -410, -43, 636, -358, -225, 432, -501, +-131, 868, -215, -431, 312, -463, -104, 1020, +-136, -694, 176, -267, -25, 1025, -82, -895, +25, 11, 37, 833, 58, -961, -195, 331, +150, 467, 82, -857, -256, 587, 148, 69, +128, -648, -253, 714, 22, -252, 314, -429, +-354, 775, -5, -484, 371, -285, -354, 823, +-6, -584, 275, -230, -217, 797, -19, -566, +118, -196, 26, 694, -184, -470, 107, -170, +177, 538, -350, -262, 215, -276, 96, 456, +-240, -84, 119, -366, 93, 428, -127, -54, +-46, -335, 277, 372, -278, -13, -5, -355, +388, 321, -479, 129, 158, -506, 346, 361, +-562, 241, 283, -727, 284, 528, -578, 288, +268, -950, 365, 672, -643, 371, 247, -1106, +398, 657, -611, 535, 202, -1191, 336, 536, +-440, 740, 46, -1272, 333, 415, -271, 928, +-125, -1305, 310, 269, -81, 1031, -230, -1169, +157, 52, 204, 1010, -375, -865, 83, -218, +375, 955, -496, -545, 153, -483, 311, 924, +-425, -281, 156, -672, 154, 849, -187, -55, +19, -758, 99, 728, -32, 79, -100, -790, +227, 722, -245, 46, 95, -742, 247, 716, +-528, -16, 444, -606, 67, 558, -588, 46, +606, -518, -21, 355, -588, 259, 572, -648, +76, 305, -623, 477, 455, -854, 174, 352, +-513, 522, 178, -841, 339, 324, -390, 391, +-106, -580, 502, 174, -308, 245, -256, -210, +469, -147, -91, 233, -361, 165, 259, -554, +239, 316, -439, 387, 4, -756, 545, 356, +-494, 358, -194, -600, 771, 183, -523, 332, +-349, -305, 931, -197, -548, 484, -389, -92, +918, -535, -493, 585, -377, 77, 834, -671, +-425, 484, -405, 275, 862, -685, -503, 272, +-283, 490, 777, -704, -532, 60, -134, 749, +579, -761, -405, -109, -154, 899, 540, -724, +-375, -209, -141, 882, 434, -608, -217, -268, +-229, 800, 367, -439, -68, -376, -337, 677, +398, -110, -90, -597, -271, 505, 331, 324, +-113, -886, -121, 432, 154, 599, -50, -1074, +-42, 406, 73, 708, -64, -1023, -11, 162, +141, 856, -186, -798, 17, -250, 278, 968, +-359, -488, 81, -572, 324, 903, -380, -109, +-7, -816, 406, 685, -228, 376, -370, -1027, +685, 330, -167, 870, -653, -1000, 863, -209, +-126, 1208, -740, -644, 790, -847, 32, 1372, +-768, -153, 615, -1396, 185, 1329, -644, 402, +302, -1739, 274, 966, -291, 1062, -206, -1817, +423, 281, 37, 1701, -623, -1621, 487, -497, +306, 2119, -828, -1232, 364, -1155, 567, 2205, +-851, -600, 84, -1762, 784, 2005, -660, 239, +-349, -2279, 987, 1630, -419, 960, -724, -2434, +1084, 1096, -179, 1408, -937, -2176, 955, 384, +178, 1772, -1104, -1777, 758, -330, 464, 1973, +-1096, -1254, 448, -836, 664, 1748, -884, -548, +39, -1157, 813, 1311, -619, 130, -350, -1318, +868, 857, -246, 600, -745, -1222, 851, 292, +157, 937, -1108, -870, 845, -338, 397, 1096, +-1229, -441, 708, -734, 552, 976, -1109, -41, +328, -835, 825, 620, -990, 355, -75, -761, +1098, 109, -875, 687, -374, -470, 1211, -494, +-669, 848, -642, -5, 1205, -977, -377, 795, +-913, 410, 1190, -1196, -125, 566, -1080, 729, +1132, -1134, -40, 146, -945, 953, 842, -763, +67, -454, -650, 1035, 345, -179, 324, -1038, +-434, 984, -112, 365, 569, -1425, -276, 863, +-403, 716, 632, -1534, -67, 639, -611, 913, +613, -1360, 83, 303, -647, 915, 450, -942, +238, -10, -567, 691, 176, -400, 427, -266, +-501, 385, -15, 137, 482, -472, -358, 103, +-189, 525, 468, -492, -169, -208, -338, 678, +433, -240, -31, -534, -399, 627, 350, 136, +90, -785, -405, 456, 261, 490, 143, -892, +-354, 202, 176, 760, 161, -808, -267, -175, +57, 953, 206, -536, -206, -612, -20, 1027, +217, -193, -139, -899, -108, 880, 253, 200, +-70, -1045, -233, 571, 327, 625, -33, -1061, +-355, 161, 408, 915, 38, -809, -525, -334, +533, 992, 18, -309, -577, -787, 552, 834, +51, 288, -559, -1093, 375, 464, 281, 916, +-642, -1205, 230, -82, 488, 1426, -691, -1020, +91, -713, 611, 1661, -592, -540, -144, -1311, +699, 1606, -395, 123, -431, -1781, 763, 1286, +-163, 827, -668, -1970, 714, 706, 107, 1397, +-817, -1756, 585, -49, 333, 1711, -853, -1185, +401, -838, 443, 1747, -645, -417, 64, -1452, +477, 1440, -256, 393, -360, -1712, 505, 807, +103, 1101, -663, -1534, 362, -81, 510, 1618, +-825, -1008, 100, -1045, 854, 1864, -832, -267, +-207, -1799, 1009, 1681, -545, 593, -625, -2212, +1022, 1122, -96, 1417, -1051, -2247, 971, 334, +324, 1968, -1286, -1786, 712, -584, 713, 2140, +-1249, -946, 242, -1381, 1031, 1882, -988, 60, +-319, -1895, 1224, 1225, -551, 1113, -866, -2075, +1217, 324, -2, 1960, -1309, -1850, 1057, -610, +540, 2375, -1558, -1239, 728, -1443, 980, 2374, +-1541, -433, 359, -2018, 1136, 1984, -1200, 362, +-95, -2107, 1098, 1217, -594, 941, -636, -1664, +997, 257, -39, 1239, -978, -916, 756, -607, +436, 1162, -1087, -37, 387, -1098, 785, 577, +-990, 893, 22, -1166, 924, -316, -717, 1662, +-348, -939, 943, -1141, -374, 1993, -606, -367, +773, -1790, -14, 1759, -718, 550, 543, -2240, +277, 1114, -727, 1517, 285, -2383, 453, 354, +-622, 2173, 61, -2117, 528, -452, -494, 2405, +-54, -1409, 432, -1216, -253, 2193, -132, -454, +214, -1719, 52, 1650, -299, 448, 185, -1900, +196, 922, -401, 1184, 200, -1778, 176, 145, +-312, 1604, 138, -1342, 140, -506, -236, 1595, +117, -680, 51, -989, -109, 1321, 85, 38, +-55, -1329, 35, 945, 9, 596, -105, -1339, +172, 456, -75, 848, -147, -962, 244, -77, +-93, 857, -165, -424, 289, -556, -123, 732, +-209, 148, 360, -885, -153, 450, -210, 651, +347, -990, -153, 100, -145, 938, 226, -863, +-28, -245, -180, 1029, 133, -510, 75, -668, +-177, 980, 46, 4, 171, -1068, -195, 842, +-50, 459, 267, -1287, -190, 619, -64, 779, +219, -1281, -120, 299, -102, 989, 182, -1097, +5, -30, -215, 1018, 193, -807, 74, -244, +-288, 902, 228, -522, 69, -331, -307, 684, +245, -247, 20, -307, -216, 336, 202, 23, +-33, -197, -99, 25, 59, 166, 40, -67, +-25, -173, -83, 194, 106, 99, -5, -320, +-139, 141, 134, 253, 33, -328, -202, -14, +142, 335, 66, -235, -194, -163, 87, 418, +117, -262, -174, -165, 1, 448, 156, -333, +-103, -29, -54, 282, 88, -280, 42, 79, +-148, 129, 55, -187, 175, 31, -253, 175, +38, -172, 195, -55, -142, 266, -113, -215, +211, -59, 7, 289, -271, -215, 204, -92, +163, 282, -346, -133, 74, -147, 344, 207, +-372, -4, -79, -153, 484, 54, -294, 163, +-317, -178, 576, -72, -129, 280, -509, -155, +559, -141, 40, 211, -614, 22, 441, -200, +289, 47, -724, 227, 317, -235, 431, -77, +-717, 332, 252, -188, 369, -215, -474, 362, +16, -55, 366, -316, -301, 288, -55, 66, +255, -280, -169, 89, -4, 226, -18, -232, +142, -107, -121, 365, -71, -194, 163, -206, +-48, 329, -111, -44, 95, -249, 67, 201, +-200, 79, 158, -191, -61, 17, 38, 157, +-51, -17, -51, -289, 220, 318, -273, 61, +84, -432, 135, 373, -110, 30, -176, -295, +284, 160, 8, 128, -464, -158, 527, -100, +-115, 302, -437, -144, 515, -202, -102, 318, +-364, -80, 357, -212, -18, 207, -273, 57, +184, -262, 50, 148, -138, 138, -49, -264, +175, 77, -127, 170, -61, -165, 124, -85, +-62, 273, -73, -191, 60, -86, 48, 295, +-132, -282, 86, 91, -70, 93, 85, -166, +-120, 187, 35, -172, 108, 66, -250, 162, +227, -356, -108, 321, -38, 7, 70, -413, +-44, 558, -24, -245, -9, -313, 75, 645, +-158, -415, 147, -192, -98, 640, -65, -532, +160, -15, -161, 544, 11, -629, 78, 199, +-106, 386, -28, -633, 133, 294, -195, 381, +55, -775, 94, 422, -251, 462, 215, -1076, +-68, 733, -205, 351, 308, -1203, -205, 975, +-163, 125, 422, -1079, -355, 1020, -118, -89, +472, -819, -444, 945, -31, -294, 452, -524, +-506, 891, 64, -626, 381, -53, -561, 806, +321, -1179, 45, 764, -429, 441, 545, -1632, +-363, 1671, -166, -191, 623, -1723, -662, 2339, +49, -873, 622, -1515, -767, 2664, 122, -1429, +581, -1081, -692, 2555, -37, -1661, 712, -662, +-653, 2216, -193, -1633, 797, -399, -635, 1891, +-171, -1512, 645, -239, -454, 1576, -178, -1267, +401, -249, -161, 1337, -218, -953, 115, -398, +222, 1203, -426, -637, 43, -614, 448, 1106, +-644, -287, 260, -937, 208, 1132, -489, -14, +299, -1212, -9, 1162, -234, 169, 160, -1357, +-5, 1092, -217, 364, 180, -1433, 39, 972, +-421, 520, 430, -1440, -60, 878, -565, 570, +704, -1456, -251, 994, -538, 361, 737, -1389, +-271, 1262, -496, -115, 631, -1066, -133, 1312, +-570, -441, 596, -792, -88, 1290, -487, -568, +441, -778, -106, 1477, -207, -748, 54, -819, +116, 1675, -93, -880, -306, -848, 449, 1701, +-216, -755, -373, -970, 583, 1521, -313, -307, +-342, -1228, 593, 1203, -341, 383, -318, -1631, +624, 908, -450, 1077, -202, -2002, 553, 644, +-448, 1599, -152, -2154, 469, 302, -313, 1928, +-365, -2001, 716, -189, -402, 2162, -568, -1670, +1136, -755, -778, 2365, -494, -1331, 1370, -1160, +-1114, 2343, -263, -973, 1289, -1361, -1139, 2147, +-154, -644, 1074, -1449, -835, 1966, -406, -544, +1039, -1188, -499, 1583, -797, -569, 1233, -601, +-473, 889, -874, -387, 1221, -139, -434, 197, +-739, 18, 870, -68, -135, -188, -668, 415, +476, -286, 152, -165, -487, 542, -64, -500, +490, 73, -213, 385, -723, -519, 911, 235, +-6, 197, -1301, -418, 1242, 257, 211, 84, +-1763, -235, 1423, 106, 429, 64, -2046, -17, +1446, -135, 626, 106, -2167, 140, 1346, -253, +755, -17, -2068, 401, 1087, -323, 833, -324, +-1787, 887, 688, -600, 938, -473, -1476, 1315, +278, -978, 1007, -351, -1125, 1436, -183, -1171, +1211, -241, -974, 1359, -459, -1018, 1355, -360, +-1001, 1185, -394, -549, 1201, -691, -856, 958, +-432, 101, 1122, -1154, -736, 758, -501, 794, +1131, -1673, -725, 599, -513, 1436, 1118, -2094, +-631, 380, -692, 1952, 1297, -2257, -691, 36, +-805, 2317, 1470, -2121, -786, -480, -788, 2577, +1434, -1750, -699, -1084, -839, 2694, 1377, -1245, +-610, -1538, -820, 2455, 1237, -539, -540, -1861, +-627, 1919, 910, 323, -415, -2134, -354, 1368, +415, 994, -150, -2112, -128, 736, -129, 1386, +278, -1714, -163, -33, -389, 1645, 545, -1231, +-254, -595, -431, 1618, 565, -750, -221, -811, +-456, 1220, 582, -183, -303, -867, -260, 649, +376, 392, -282, -809, 2, 61, -66, 819, +74, -624, -89, -403, -202, 950, 282, -339, +-220, -657, -173, 835, 277, -8, -180, -806, +-262, 658, 377, 244, -229, -802, -302, 416, +448, 403, -256, -651, -311, 70, 454, 624, +-237, -582, -318, -187, 384, 853, -122, -650, +-317, -235, 161, 872, 224, -617, -523, -222, +70, 757, 505, -481, -738, -294, 106, 751, +541, -423, -711, -388, 50, 827, 473, -377, +-489, -554, -140, 932, 390, -222, -117, -935, +-515, 1237, 445, -155, 168, -1328, -890, 1633, +628, -266, 245, -1474, -1065, 1780, 717, -247, +269, -1534, -1098, 1680, 658, -28, 402, -1586, +-1203, 1422, 674, 275, 485, -1562, -1340, 975, +866, 792, 258, -1662, -1161, 496, 841, 1500, +46, -1984, -767, 170, 464, 2108, 182, -2299, +-580, 0, 103, 2444, 451, -2429, -584, -78, +-114, 2465, 668, -2292, -594, -156, -259, 2238, +738, -1910, -455, -250, -481, 1883, 780, -1452, +-227, -353, -766, 1545, 846, -996, -78, -507, +-868, 1294, 697, -629, 202, -632, -933, 1126, +416, -438, 563, -625, -1018, 1017, 190, -435, +754, -498, -855, 944, -234, -541, 1022, -311, +-661, 843, -722, -584, 1373, -213, -631, 763, +-952, -507, 1442, -293, -473, 811, -1073, -456, +1307, -461, -195, 977, -1177, -466, 1116, -596, +23, 1086, -1075, -435, 732, -670, 270, 1004, +-843, -231, 210, -745, 566, 798, -645, 70, +-228, -800, 758, 570, -428, 245, -553, -628, +826, 213, -211, 324, -732, -266, 733, -238, +19, 398, -749, 71, 430, -574, 352, 359, +-772, 442, 119, -834, 664, 176, -772, 908, +-147, -1087, 863, -50, -646, 1328, -459, -1229, +994, -291, -412, 1586, -823, -1170, 1109, -548, +-180, 1651, -1154, -883, 1233, -855, -71, 1567, +-1275, -451, 1208, -1140, -5, 1344, -1184, 40, +982, -1335, 122, 995, -1043, 560, 709, -1476, +211, 661, -808, 929, 374, -1464, 301, 357, +-550, 1075, -1, -1189, 473, -64, -456, 1152, +-138, -806, 480, -528, -375, 1209, -121, -410, +290, -927, -167, 1196, -152, -19, 141, -1267, +-43, 1158, -81, 306, -35, -1537, 44, 1127, +42, 530, -281, -1704, 241, 1155, -42, 570, +-289, -1728, 319, 1195, -193, 471, -114, -1603, +220, 1142, -237, 392, 47, -1469, 82, 1098, +-259, 292, 238, -1370, -121, 1167, -210, 85, +368, -1196, -369, 1170, 47, -103, 241, -910, +-458, 929, 323, -153, -26, -483, -382, 464, +415, -165, -129, 67, -353, -37, 396, -267, +-68, 607, -374, -357, 287, -494, 123, 1014, +-435, -440, 131, -797, 366, 1314, -568, -385, +81, -1120, 469, 1573, -573, -326, -8, -1440, +512, 1820, -443, -213, -246, -1792, 661, 1950, +-391, 120, -394, -2199, 699, 1881, -267, 606, +-475, -2494, 564, 1624, -33, 1032, -535, -2483, +383, 1163, 170, 1347, -502, -2203, 119, 538, +399, 1672, -506, -1891, -15, -101, 483, 2001, +-494, -1635, 19, -595, 295, 2180, -268, -1359, +9, -957, 26, 2178, 61, -981, -112, -1271, +-114, 2046, 303, -537, -262, -1487, -127, 1726, +415, -44, -327, -1535, -197, 1235, 545, 438, +-362, -1488, -320, 799, 719, 715, -437, -1371, +-311, 564, 684, 706, -388, -1123, -294, 401, +565, 599, -255, -815, -361, 124, 556, 626, +-163, -572, -436, -218, 486, 796, 30, -457, +-533, -437, 307, 909, 338, -452, -635, -480, +119, 974, 589, -511, -768, -523, 144, 1124, +595, -566, -815, -660, 262, 1234, 444, -445, +-670, -829, 152, 1089, 484, -72, -576, -946, +-43, 744, 632, 324, -571, -904, -138, 353, +687, 538, -525, -691, -228, -7, 734, 637, +-520, -442, -202, -344, 622, 759, -393, -253, +-196, -645, 407, 890, -119, -99, -304, -856, +291, 865, 66, 113, -335, -934, 145, 634, +251, 409, -397, -946, 44, 356, 411, 658, +-464, -942, 0, 184, 431, 773, -336, -916, +-225, 153, 513, 717, -171, -854, -440, 219, +520, 572, -54, -777, -388, 243, 266, 524, +143, -749, -306, 130, 44, 700, 247, -785, +-265, -62, -4, 928, 219, -807, -221, -184, +6, 947, 166, -711, -145, -181, -16, 728, +48, -440, 54, -249, -92, 525, -81, -115, +220, -482, -111, 523, -121, 99, 129, -717, +85, 568, -192, 234, -19, -816, 323, 517, +-376, 308, 18, -737, 443, 399, -585, 261, +127, -548, 581, 263, -809, 233, 165, -443, +764, 170, -967, 299, 140, -470, 870, 126, +-1016, 374, 140, -457, 821, 30, -898, 393, +58, -334, 763, -102, -705, 373, -132, -177, +793, -245, -581, 380, -231, -44, 716, -407, +-403, 427, -293, 63, 558, -532, -145, 409, +-453, 206, 511, -617, 60, 324, -613, 328, +455, -581, 242, 187, -700, 349, 353, -364, +361, -92, -628, 382, 169, -92, 430, -419, +-499, 468, -7, 79, 531, -626, -554, 517, +49, 166, 534, -688, -649, 466, 134, 249, +535, -640, -697, 290, 140, 365, 579, -561, +-711, 89, 132, 476, 511, -456, -587, -97, +57, 511, 485, -263, -527, -330, 40, 488, +533, 2, -647, -535, 135, 437, 520, 197, +-644, -629, 80, 358, 556, 278, -542, -602, +-89, 294, 599, 286, -460, -550, -139, 253, +528, 311, -370, -589, -113, 292, 392, 335, +-242, -709, -122, 434, 265, 305, -70, -838, +-199, 602, 184, 294, 58, -1003, -199, 711, +73, 403, 120, -1190, -137, 700, -45, 649, +208, -1383, -166, 573, -79, 989, 298, -1550, +-281, 404, 0, 1245, 298, -1585, -339, 228, +60, 1365, 268, -1503, -322, 64, 31, 1398, +323, -1362, -367, -89, 12, 1346, 399, -1083, +-429, -341, 21, 1278, 393, -697, -388, -672, +-38, 1229, 414, -373, -335, -886, -112, 1124, +414, -156, -238, -895, -213, 939, 401, -92, +-107, -702, -308, 738, 340, -148, -18, -461, +-205, 577, 82, -185, 131, -345, -73, 494, +-192, -136, 282, -345, -12, 396, -360, 35, +398, -435, 20, 282, -528, 264, 600, -581, +-69, 260, -620, 373, 804, -665, -243, 274, +-564, 386, 861, -646, -351, 220, -472, 407, +806, -561, -317, 70, -473, 447, 752, -392, +-202, -178, -607, 524, 818, -200, -164, -453, +-698, 624, 863, -71, -125, -653, -698, 703, +714, -17, 76, -731, -712, 747, 469, -30, +322, -728, -661, 731, 192, -1, 469, -731, +-509, 658, -16, 108, 447, -772, -297, 577, +-158, 248, 354, -792, -64, 423, -345, 403, +382, -737, 83, 188, -538, 528, 469, -610, +158, -18, -639, 554, 442, -439, 249, -158, +-621, 506, 305, -258, 301, -318, -450, 513, +90, -84, 277, -550, -197, 595, -62, 50, +149, -762, 43, 657, -128, 168, -5, -848, +214, 582, -180, 283, -38, -812, 247, 428, +-186, 348, -55, -694, 280, 256, -149, 361, +-182, -529, 403, 72, -151, 402, -283, -383, +478, -153, -137, 491, -292, -212, 403, -436, +-59, 586, -254, 24, 258, -774, 57, 656, +-199, 293, 68, -1086, 217, 668, -182, 568, +-87, -1289, 313, 543, -84, 843, -261, -1320, +323, 249, 122, 1112, -484, -1236, 390, -100, +220, 1315, -608, -1097, 454, -346, 183, 1343, +-565, -866, 435, -551, 145, 1218, -461, -485, +346, -799, 141, 1027, -342, -16, 206, -1057, +170, 791, -229, 484, 55, -1305, 222, 553, +-124, 903, -116, -1453, 299, 371, -41, 1095, +-270, -1429, 429, 236, -89, 1089, -305, -1248, +550, 94, -254, 1004, -200, -979, 593, -110, +-386, 937, -111, -709, 603, -310, -398, 887, +-160, -526, 649, -390, -323, 784, -294, -403, +660, -357, -159, 637, -466, -316, 659, -299, +2, 512, -576, -258, 579, -230, 162, 383, +-581, -182, 362, -188, 435, 218, -618, -27, +134, -209, 663, 87, -576, 141, -116, -260, +768, 12, -336, 229, -467, -262, 842, -35, +-97, 250, -683, -217, 782, -104, 87, 278, +-661, -179, 539, -202, 284, 351, -610, -137, +341, -324, 406, 390, -530, -28, 191, -478, +464, 369, -399, 195, -46, -649, 580, 271, +-281, 485, -256, -800, 658, 104, -195, 766, +-297, -866, 538, -85, -61, 931, -214, -810, +303, -276, 87, 1001, -156, -665, 163, -464, +153, 1031, -160, -519, 200, -611, 83, 1038, +-126, -437, 233, -629, 7, 985, -51, -430, +179, -519, 49, 844, -65, -429, 210, -381, +18, 703, -76, -423, 322, -282, -161, 644, +52, -482, 343, -181, -292, 623, 155, -535, +329, -121, -306, 572, 155, -469, 334, -179, +-285, 532, 142, -311, 326, -341, -275, 535, +174, -134, 286, -538, -293, 561, 258, 53, +201, -744, -262, 551, 282, 283, 179, -925, +-254, 428, 270, 585, 236, -1023, -338, 177, +317, 883, 263, -985, -401, -139, 335, 1069, +328, -834, -453, -413, 320, 1110, 386, -629, +-466, -576, 288, 1052, 362, -452, -324, -682, +132, 1017, 375, -346, -145, -775, -88, 1038, +458, -302, -61, -791, -223, 988, 521, -276, +-24, -700, -266, 839, 485, -242, 46, -563, +-231, 692, 304, -245, 242, -468, -228, 645, +89, -275, 469, -455, -259, 670, -56, -241, +590, -547, -236, 671, -144, -71, 603, -705, +-165, 594, -173, 174, 538, -836, -56, 462, +-221, 385, 489, -861, 47, 288, -290, 525, +478, -791, 92, 97, -269, 624, 360, -694, +207, -81, -259, 681, 243, -568, 310, -229, +-270, 632, 226, -344, 276, -345, -207, 436, +204, -15, 260, -418, -204, 136, 223, 336, +247, -421, -231, -179, 281, 580, 188, -355, +-167, -403, 243, 658, 177, -261, -116, -463, +181, 600, 196, -167, -91, -492, 164, 535, +207, -62, -91, -578, 137, 541, 249, 33, +-88, -679, 49, 539, 318, 122, 0, -694, +-160, 406, 439, 246, 103, -630, -330, 180, +461, 402, 233, -574, -391, -8, 311, 550, +467, -578, -501, -123, 240, 690, 594, -620, +-570, -231, 250, 849, 571, -657, -478, -364, +148, 980, 564, -618, -339, -488, 7, 971, +559, -477, -182, -552, -136, 858, 498, -325, +24, -551, -250, 731, 384, -259, 241, -489, +-327, 651, 235, -250, 441, -450, -361, 613, +102, -212, 541, -491, -300, 625, -42, -175, +611, -553, -235, 659, -166, -171, 663, -533, +-209, 601, -177, -129, 598, -499, -101, 454, +-202, 67, 477, -583, 72, 292, -274, 398, +382, -759, 200, 109, -276, 754, 253, -900, +312, -107, -238, 1039, 101, -905, 392, -350, +-145, 1184, -51, -750, 394, -608, 42, 1222, +-261, -516, 436, -854, 175, 1232, -425, -320, +484, -1012, 231, 1207, -474, -206, 444, -1042, +335, 1111, -551, -104, 402, -1005, 492, 927, +-697, 49, 412, -950, 588, 717, -777, 190, +402, -882, 631, 542, -766, 242, 322, -722, +682, 354, -715, 215, 214, -477, 718, 139, +-625, 191, 80, -267, 745, -25, -494, 173, +-103, -129, 792, -123, -355, 132, -274, 10, +789, -230, -184, 99, -392, 168, 687, -378, +27, 96, -452, 307, 520, -505, 214, 92, +-429, 404, 302, -549, 377, 33, -392, 483, +147, -531, 462, -73, -340, 553, 55, -473, +462, -198, -228, 591, -66, -367, 464, -322, +-135, 597, -141, -260, 448, -418, -97, 591, +-95, -206, 332, -435, -38, 566, -20, -212, +181, -386, 48, 556, -25, -244, 139, -376, +100, 588, -98, -230, 214, -485, 98, 652, +-172, -124, 257, -662, 157, 692, -283, 43, +262, -833, 290, 662, -424, 232, 295, -952, +346, 572, -447, 395, 254, -970, 380, 416, +-413, 517, 172, -859, 433, 160, -411, 630, +142, -673, 440, -145, -375, 721, 80, -449, +448, -419, -303, 716, -8, -166, 429, -656, +-179, 644, -111, 143, 350, -880, 24, 591, +-250, 370, 294, -1031, 201, 530, -351, 507, +228, -1024, 320, 358, -372, 633, 125, -895, +404, 80, -322, 772, 5, -755, 434, -180, +-192, 887, -162, -623, 482, -414, -71, 964, +-317, -454, 527, -639, -7, 982, -374, -240, +482, -805, 67, 882, -353, 8, 344, -905, +178, 699, -285, 265, 115, -945, 329, 492, +-201, 462, -105, -906, 398, 284, -57, 590, +-280, -797, 354, 80, 171, 647, -454, -652, +311, -74, 336, 619, -543, -477, 251, -165, +452, 507, -565, -302, 176, -204, 543, 386, +-564, -183, 133, -222, 532, 340, -475, -123, +64, -248, 481, 312, -348, -59, 22, -268, +369, 223, -220, 83, 29, -312, 223, 106, +-102, 254, 44, -395, 119, 33, -80, 431, +113, -513, 31, -24, -74, 600, 153, -610, +-5, -78, -75, 710, 118, -637, 96, -144, +-175, 770, 142, -634, 175, -206, -280, 833, +188, -603, 211, -317, -302, 861, 159, -435, +278, -521, -315, 828, 110, -148, 337, -734, +-296, 699, 57, 162, 326, -831, -197, 459, +-3, 427, 226, -800, -49, 219, -50, 584, +105, -741, 96, 57, -110, 683, 52, -697, +141, -89, -119, 762, 49, -567, 83, -314, +-49, 753, 20, -232, 51, -587, -32, 582, +71, 212, -36, -751, 17, 266, 131, 612, +-160, -781, 150, -48, 89, 876, -185, -750, +207, -239, 76, 961, -186, -651, 207, -352, +97, 905, -176, -474, 146, -413, 142, 740, +-145, -251, 48, -416, 189, 485, -118, -1, +-1, -399, 160, 208, -59, 239, -50, -345, +124, -52, -13, 390, -72, -229, 91, -269, +24, 436, -96, -62, 60, -423, 90, 401, +-139, 101, 40, -518, 170, 338, -150, 200, +-38, -496, 255, 227, -86, 227, -154, -369, +292, 51, 22, 282, -242, -220, 244, -150, +149, 301, -256, -18, 123, -326, 243, 210, +-213, 225, 12, -407, 244, 80, -135, 309, +-41, -298, 158, -23, -29, 180, -99, -46, +105, -96, 43, -19, -185, 196, 175, -107, +-42, -228, -130, 371, 176, -43, -98, -477, +-30, 536, 72, 52, -12, -691, -53, 615, +80, 155, 2, -767, -43, 506, 115, 304, +-43, -720, 14, 297, 103, 396, -15, -569, +-46, 97, 180, 384, -39, -352, -83, -99, +205, 383, -65, -157, -35, -306, 86, 383, +43, 57, -129, -455, 70, 249, 102, 346, +-223, -529, 95, -23, 143, 632, -262, -511, +33, -276, 238, 779, -285, -375, -41, -487, +259, 779, -98, -147, -305, -678, 373, 710, +57, 104, -505, -809, 455, 564, 113, 335, +-457, -842, 259, 379, 335, 487, -496, -762, +148, 162, 444, 568, -513, -570, 139, -133, +346, 657, -338, -336, -34, -440, 373, 698, +-253, -94, -188, -633, 418, 585, -185, 160, +-318, -668, 411, 333, -22, 352, -551, -522, +512, 51, 37, 380, -643, -273, 512, -132, +107, 295, -621, -86, 382, -201, 281, 221, +-683, 26, 353, -237, 360, 128, -689, 168, +361, -256, 320, -34, -575, 316, 267, -189, +302, -189, -443, 316, 129, -30, 307, -274, +-308, 220, -47, 90, 332, -281, -184, 154, +-225, 120, 371, -250, -144, 101, -268, 144, +313, -205, -120, 23, -204, 155, 152, -69, +15, -157, -242, 145, 95, 172, 138, -394, +-367, 138, 200, 358, 104, -490, -346, 56, +201, 439, 85, -401, -222, -85, 43, 432, +211, -265, -168, -201, -99, 420, 298, -142, +-118, -325, -202, 439, 319, -37, -44, -423, +-319, 391, 372, 109, -55, -476, -370, 297, +422, 202, -140, -469, -298, 259, 333, 162, +-120, -350, -240, 158, 177, 138, 20, -199, +-274, -15, 101, 209, 79, -125, -246, -130, +59, 274, 83, -176, -163, -72, -21, 297, +134, -310, -141, 74, -32, 234, 179, -329, +-191, 121, 25, 174, 178, -255, -227, 58, +91, 191, 115, -224, -200, -6, 93, 264, +35, -214, -62, -143, -64, 411, 70, -228, +-32, -223, -132, 457, 98, -217, -62, -191, +-105, 294, 30, -65, 11, -146, -191, 137, +78, -28, 49, -49, -268, 95, 96, -117, +77, 27, -181, 158, -76, -154, 164, -146, +-55, 355, -229, -53, 177, -413, 128, 400, +-360, 149, 130, -590, 293, 335, -428, 398, +80, -718, 277, 161, -235, 665, -172, -705, +307, -187, -55, 990, -319, -599, 192, -630, +142, 1165, -344, -263, -56, -988, 409, 1047, +-473, 209, -103, -1240, 450, 752, -383, 667, +-274, -1208, 514, 213, -262, 1037, -434, -937, +544, -401, -104, 1227, -541, -403, 396, -957, +222, 998, -683, 387, 244, -1323, 459, 512, +-641, 1056, -15, -1297, 605, -165, -507, 1412, +-158, -804, 454, -795, -222, 1338, -250, -172, +262, -1134, -31, 929, -263, 480, 172, -1185, +-86, 334, -100, 886, 53, -852, -87, -339, +-120, 1037, 120, -203, -130, -1001, -195, 847, +241, 486, -182, -1127, -241, 261, 291, 892, +-93, -774, -413, -400, 434, 977, -116, -133, +-454, -893, 458, 671, -73, 541, -444, -1103, +333, 253, 95, 970, -497, -951, 275, -191, +125, 903, -337, -395, 5, -427, 203, 502, +-168, 104, -224, -393, 234, -26, -37, 453, +-309, -159, 121, -441, 68, 513, -283, 78, +70, -545, -54, 291, -68, 324, -79, -397, +-17, -62, -92, 286, -18, 24, -2, -256, +-209, 3, 96, 386, -53, -259, -96, -299, +-50, 509, -20, 59, 3, -608, -92, 258, +-83, 600, 121, -652, -184, -323, -104, 998, +194, -271, -174, -865, -155, 787, 133, 415, +-88, -1000, -177, 162, 148, 966, -164, -767, +-172, -536, 235, 1164, -275, -161, -182, -1086, +312, 869, -250, 576, -353, -1215, 362, 122, +-87, 1201, -449, -742, 205, -842, 104, 1236, +-372, 180, -90, -1376, 333, 689, -362, 1057, +-149, -1451, 184, -167, -53, 1728, -263, -1022, +-38, -1054, 260, 1766, -332, -118, -180, -1683, +259, 1221, -42, 943, -520, -1788, 334, 165, +108, 1684, -602, -1197, 149, -941, 372, 1862, +-633, -260, -129, -1704, 620, 1350, -583, 826, +-375, -1758, 638, 294, -205, 1476, -843, -1191, +735, -600, 66, 1576, -1054, -526, 586, -1125, +362, 1413, -1042, 13, 189, -1462, 730, 1240, +-943, 555, -248, -1737, 935, 730, -573, 1293, +-765, -1621, 942, -220, -75, 1810, -1111, -973, +710, -1094, 333, 1602, -1054, 40, 235, -1410, +537, 746, -746, 735, -45, -828, 348, -175, +-497, 495, 92, 90, 115, -170, -607, -306, +276, 137, 268, 518, -844, -195, 100, -670, +578, 344, -708, 842, -283, -672, 607, -688, +-441, 886, -367, 445, 475, -1007, -365, 69, +-364, 838, 482, -667, -294, -119, -433, 886, +349, -832, -123, -405, -309, 1470, 85, -540, +-176, -1243, -26, 1272, -20, 360, -254, -1202, +41, 637, -154, 314, -75, -1013, -17, 862, +-149, 619, -157, -1622, 50, 364, -203, 1548, +-173, -1356, 211, -579, -106, 1882, -627, -916, +67, -1424, 709, 2125, -684, 244, -701, -2339, +688, 1060, 187, 1593, -982, -1932, 230, -63, +503, 1851, -850, -1308, -203, -931, 794, 1934, +-549, -313, -633, -1390, 714, 1131, -355, 232, +-577, -1180, 782, 917, -447, 730, -866, -1701, +1021, 161, -135, 1777, -1239, -1011, 703, -1184, +614, 1624, -1294, 204, -228, -1749, 1095, 812, +-479, 1507, -910, -1562, 545, -868, 174, 1846, +-677, 39, 46, -1433, 374, 580, -588, 728, +-369, -857, 667, -22, -167, 991, -895, -564, +299, -985, 675, 1149, -979, 680, -460, -1444, +1048, -22, -354, 1228, -1011, -615, 609, -396, +288, 733, -938, -495, 246, -170, 381, 873, +-835, -609, 36, -533, 502, 1138, -521, -178, +-456, -1158, 630, 883, -326, 851, -723, -1363, +824, -192, -106, 1361, -1208, -415, 678, -889, +735, 739, -1548, 275, 110, -631, 1141, 137, +-1141, 348, -460, -206, 1226, 39, -824, -79, +-940, -303, 1419, 766, -265, 177, -1539, -1355, +920, 303, 658, 1634, -1322, -934, 19, -1335, +780, 1343, -838, 751, -137, -1404, 677, -96, +-749, 1214, -391, -350, 844, -890, -260, 568, +-1053, 653, 566, -662, 692, -396, -974, 707, +-692, 210, 924, -876, 330, 291, -969, 964, +-411, -1038, 543, -653, 424, 1681, -676, 74, +-596, -1867, 425, 437, 428, 1750, -546, -647, +-523, -1532, 413, 709, 35, 1346, -367, -791, +176, -979, -301, 904, -393, 373, 487, -853, +207, 440, -749, 538, -362, -1165, 402, 141, +474, 1326, -386, -592, -1004, -1033, 338, 707, +931, 542, -631, -346, -933, -252, 813, -55, +183, 359, -1038, 94, 378, -530, 758, 225, +-1118, 714, -477, -750, 1205, -687, -266, 1229, +-1053, 518, 690, -1413, 152, -212, -1115, 1219, +742, 67, 627, -827, -1603, -102, 90, 603, +1420, 283, -1048, -851, -885, -108, 1324, 1347, +-142, -548, -1320, -1443, 618, 1247, 726, 1105, +-794, -1638, -472, -371, 460, 1619, 61, -568, +-298, -1057, 152, 1455, -135, 13, -626, -1720, +417, 1034, 753, 1290, -923, -1470, -868, -477, +1104, 1127, 507, -95, -1385, -305, -9, 234, +1013, -576, -695, 259, -571, 881, 991, -857, +-230, -387, -1290, 866, 838, -134, 1056, -454, +-1490, 447, -898, -54, 1662, -466, 538, 498, +-1899, 396, -391, -940, 1705, -109, 165, 1340, +-1632, -275, -289, -1580, 1470, 548, 217, 1993, +-1571, -945, -286, -2413, 1681, 1703, -119, 2428, +-1779, -2565, 369, -1840, 1658, 3306, -906, 703, +-1498, -3574, 1300, 747, 782, 3167, -1505, -1862, +-191, -2333, 1251, 2395, -534, 1523, -876, -2458, +834, -929, 172, 2522, -965, 208, 244, -2362, +646, 710, -586, 1668, -362, -1212, 456, -760, +-139, 1151, -79, 64, 204, -690, -574, 318, +-98, 82, 917, -392, -374, 557, -1065, 255, +792, -992, 545, -77, -1005, 1282, 58, -37, +682, -1397, -705, 75, -41, 1414, 625, -89, +-552, -1216, -337, 12, 738, 887, -195, 289, +-854, -610, 657, -690, 433, 532, -838, 1219, +-230, -873, 621, -1527, 80, 1593, -429, 1316, +-401, -2235, 354, -512, 639, 2211, -710, -276, +-865, -1471, 1064, 505, 848, 637, -1646, -191, +-705, -244, 2023, -84, 262, 281, -2322, -23, +257, -317, 2213, 412, -871, 162, -1959, -780, +1287, 171, 1541, 971, -1729, -445, -1143, -1192, +2015, 826, 517, 1455, -2212, -1419, 109, -1533, +2088, 2121, -961, 1262, -1697, -2522, 1576, -783, +934, 2455, -1932, 388, -275, -2100, 1804, -61, +-371, 1659, -1342, -340, 497, -1091, 679, 864, +-366, 220, -315, -1082, 81, 657, 69, 997, +-51, -1355, 136, -557, -122, 1638, -299, -48, +245, -1312, 293, 359, -415, 688, -347, -214, +542, -58, 261, -274, -591, -333, -359, 840, +552, 526, 422, -1333, -510, -445, -728, 1498, +640, 236, 713, -1149, -880, -179, -533, 503, +875, 431, 250, 39, -973, -708, 66, -304, +815, 755, -361, 422, -735, -547, 591, -520, +524, 266, -982, 676, -152, -229, 1172, -646, +-308, 445, -1279, 279, 579, -743, 1276, 446, +-721, 763, -1171, -1165, 438, -465, 1148, 1534, +-57, 21, -1261, -1383, -400, 374, 1494, 761, +463, -524, -1715, 76, -120, 576, 1469, -1035, +-436, -480, -997, 1911, 945, 264, 253, -2392, +-1301, -13, 251, 2199, 1572, 58, -727, -1473, +-1693, -383, 742, 401, 1737, 861, -484, 904, +-1853, -1479, -52, -2075, 1911, 2012, 619, 2922, +-1950, -2327, -1090, -3225, 1627, 2135, 1633, 3190, +-1388, -1533, -1889, -3034, 858, 912, 2129, 2644, +-434, -301, -2442, -2149, 415, -208, 2432, 1801, +-694, 333, -2071, -1498, 843, -155, 1573, 1175, +-745, 15, -1353, -1054, 450, -11, 1396, 1166, +-139, 222, -1785, -1412, 98, -737, 1807, 1675, +-12, 1571, -1503, -1973, -301, -2463, 821, 2168, +836, 3146, 80, -2208, -1729, -3274, -869, 1953, +2616, 2697, 1268, -1175, -3077, -1766, -1440, 76, +2838, 828, 1775, 986, -2316, -134, -2190, -1685, +1717, -259, 2540, 1959, -1243, 342, -2690, -1963, +986, -12, 2435, 1703, -835, -655, -1870, -1002, +669, 1102, 1079, 111, -510, -892, -125, 535, +35, 114, -612, -718, 495, 926, 975, 427, +-867, -1628, -1169, -134, 1106, 1754, 1108, 312, +-1086, -1570, -1005, -855, 976, 1258, 733, 1382, +-668, -868, -420, -1512, 335, 357, -100, 1045, +256, 333, 664, -76, -1136, -1198, -848, -1058, +1853, 2197, 932, 1705, -2536, -2875, -602, -1531, +2728, 2759, 181, 856, -2414, -1908, 158, -139, +1771, 851, -480, -395, -694, -98, 491, 864, +-400, -379, -362, -1136, 1417, 667, 121, 1208, +-2117, -996, 17, -1071, 2518, 1696, 1, 473, +-2642, -2455, 37, 529, 2206, 2638, 189, -1288, +-1418, -2025, -499, 1290, 420, 856, 880, -505, +546, 474, -1018, -630, -1286, -1513, 760, 1388, +1932, 2098, -262, -1272, -2144, -2223, -369, 182, +1955, 2074, 1028, 1319, -1260, -1647, -1609, -2540, +439, 816, 1923, 3103, 400, 267, -1847, -2979, +-983, -1075, 1554, 2090, 1121, 1228, -1002, -519, +-782, -897, 518, -1053, 18, 112, 26, 2060, +749, 931, -212, -2205, -1194, -1962, -104, 1625, +1455, 2567, 755, -619, -1386, -2497, -1346, -289, +1092, 1637, 1568, 701, -275, -55, -1376, -699, +-727, -1638, 941, 311, 1744, 2837, -246, 289, +-2523, -3111, -280, -926, 2830, 2433, 672, 1415, +-2553, -1091, -794, -1622, 1968, -381, 648, 1477, +-1098, 1490, -226, -1050, 260, -1850, -286, 395, +532, 1473, 716, 397, -922, -666, -969, -1165, +1012, -116, 1191, 1792, -929, 359, -1141, -1913, +902, -112, 869, 1610, -910, -555, -125, -894, +790, 1255, -509, -8, -595, -1580, 969, 687, +618, 1509, -1159, -1023, -616, -1114, 1112, 1017, +755, 651, -952, -938, -559, -153, 692, 904, +127, -342, -190, -814, 434, 684, -171, 513, +-966, -523, 531, -213, 1304, -60, -703, 60, +-1049, 721, 639, 8, 525, -1172, -374, -125, +236, 1209, 313, 409, -1002, -827, -392, -853, +1735, 161, 683, 1418, -2114, 424, -836, -1801, +2060, -789, 967, 1899, -1486, 717, -830, -1597, +724, -218, 533, 880, 270, -446, -235, -25, +-871, 1101, 5, -768, 1109, -1449, 288, 1326, +-969, 1247, -359, -1403, 594, -587, 542, 972, +-237, -151, -465, -394, -59, 763, 456, -118, +430, -984, -583, 332, -486, 762, 761, -253, +570, -233, -843, 154, -471, -569, 764, -245, +506, 1572, -333, 401, -623, -2460, -50, -365, +706, 2583, 576, 316, -653, -1761, -835, -433, +480, 312, 926, 656, -47, 1232, -653, -813, +-377, -2367, 120, 676, 1081, 2868, 355, -292, +-1498, -2718, -526, -116, 1626, 1982, 470, 369, +-1172, -920, -211, -377, 401, -130, 307, 190, +182, 889, -417, -56, -207, -1083, 562, 87, +-26, 700, -630, -300, 501, -61, 775, 682, +-733, -457, -975, -1152, 790, 630, 1318, 1497, +-538, -430, -1524, -1337, 256, -211, 1604, 682, +-95, 1172, -1038, 69, 13, -1932, 289, -609, +-24, 2042, 655, 810, 239, -1387, -1429, -755, +-245, 346, 1826, 446, 240, 541, -1630, 123, +-23, -1043, 1076, -764, -64, 1141, -386, 1052, +244, -850, -19, -821, -320, 230, 195, 292, +499, 349, -126, 192, -487, -458, 128, -514, +370, -62, -57, 774, -86, 746, 119, -823, +-6, -1202, -229, 528, 34, 1306, 528, -56, +47, -1022, -574, -373, -200, 519, 594, 511, +422, -3, -409, -195, -402, -427, 182, -422, +232, 663, 272, 1061, 144, -620, -707, -1524, +-292, 432, 988, 1480, 449, -35, -897, -1050, +-477, -507, 787, 609, 404, 820, -490, -341, +-48, -592, 93, 175, -107, -171, 275, 164, +257, 964, -332, -672, -302, -1285, 386, 1116, +287, 933, -221, -1197, -61, -236, 61, 922, +-101, -379, 248, -595, 205, 680, -274, 424, +-151, -735, 253, -388, 186, 599, -115, 341, +-54, -386, 51, -210, 72, 244, -62, -45, +54, -230, 243, 278, -125, 502, -260, -542, +202, -874, 315, 754, -105, 1070, -210, -729, +74, -1054, 166, 557, 29, 720, -41, -327, +35, -89, 58, 37, -24, -520, -141, 109, +223, 958, 302, -44, -227, -1259, -313, 41, +99, 1173, 480, -143, 197, -653, -415, 209, +-546, -73, 502, -90, 793, 558, -327, -110, +-728, -543, 72, 95, 672, 285, 329, 56, +-462, -55, -573, -164, 528, -41, 500, 103, +-368, 19, -80, 75, 195, 9, -196, -197, +78, -56, 343, 127, 42, 158, -237, -25, +-338, -139, 344, -171, 586, 25, -186, 438, +-621, -53, 130, -449, 529, 149, -17, 76, +4, -206, -26, 576, -472, 124, -25, -1208, +1128, -3, 240, 1680, -1480, -239, -351, -1804, +1561, 686, 595, 1284, -1189, -1090, -653, -250, +721, 1248, 671, -914, -163, -1111, -287, 1719, +-184, 840, -99, -1950, 394, -619, 590, 1660, +-202, 460, -802, -1025, -61, -338, 854, 257, +532, 232, -592, 348, -652, -116, 200, -590, +610, -72, 467, 419, -275, 332, -906, 85, +-33, -742, 1158, -577, 524, 1121, -1000, 821, +-868, -1252, 855, -856, 1066, 1162, -471, 662, +-940, -914, 321, -313, 664, 509, -132, 25, +-59, -224, 47, 166, -336, 182, 107, -381, +667, -275, -90, 572, -596, 417, 31, -739, +560, -505, 213, 836, -411, 484, -330, -863, +577, -387, 303, 862, -635, 283, 100, -1024, +570, -19, -211, 1253, -385, -527, 326, -1225, +344, 1073, -266, 809, -92, -1314, 232, -109, +-114, 1041, -82, -502, 557, -480, 28, 916, +-873, -200, 145, -1069, 1133, 858, -79, 802, +-1100, -1188, 155, -292, 857, 1070, -17, -204, +-309, -682, 19, 513, -157, 236, 20, -632, +731, 124, -10, 539, -843, -287, 52, -328, +800, 270, -21, 78, -359, -154, 125, 135, +-48, 31, -114, -256, 406, -104, 371, 473, +-554, 240, -444, -838, 590, -187, 519, 1114, +-267, -33, -438, -1184, -7, 282, 520, 1049, +192, -496, -420, -771, 39, 567, 277, 425, +-282, -431, 71, -155, 590, 74, -294, 134, +-502, 305, 355, -313, 383, -572, 16, 515, +-217, 642, -213, -573, 110, -552, 418, 291, +225, 551, -538, 92, -213, -636, 523, -404, +218, 713, -192, 522, -96, -750, -29, -304, +-26, 500, 413, 5, 190, -56, -537, 70, +-198, -256, 675, 3, 179, 273, -561, -54, +81, -168, 418, -21, -195, 237, -218, 59, +445, -652, 158, 231, -502, 1080, -20, -796, +556, -1163, -11, 1258, -377, 773, 252, -1255, +53, -48, -332, 590, 456, -499, 360, 364, +-727, 668, -172, -1037, 823, -638, 58, 1240, +-536, 566, 61, -1042, 309, -526, -55, 672, +-48, 422, 149, -304, 64, -189, -232, -35, +-52, -35, 439, 218, 102, 117, -422, -151, +10, -91, 337, -70, -126, -32, 90, 242, +296, 243, -462, -209, -276, -597, 739, 22, +399, 967, -703, 148, -444, -1106, 559, -300, +612, 941, -206, 365, -672, -551, 38, -260, +645, 20, 122, 24, -311, 466, -144, 239, +0, -669, 158, -499, 400, 503, -44, 730, +-532, -163, 41, -817, 423, -152, 151, 576, +-52, 352, -213, -51, -299, -393, 248, -654, +696, 293, -30, 1344, -883, -235, -200, -1684, +1014, 207, 427, 1498, -786, -130, -441, -946, +448, 49, 384, 175, 114, 45, -182, 570, +-513, -239, 77, -929, 740, 411, 84, 793, +-620, -436, -65, -316, 358, 321, 68, -319, +17, -57, 84, 827, -247, -292, -134, -954, +353, 553, 203, 635, -156, -570, -120, -43, +-46, 274, -86, -512, 460, 208, 370, 777, +-746, -706, -416, -599, 741, 929, 597, 112, +-476, -743, -608, 285, 144, 365, 602, -464, +343, -41, -470, 488, -705, -184, 365, -434, +1085, 363, -343, 352, -1035, -544, 306, -265, +851, 711, -39, 157, -580, -818, -174, -36, +403, 755, 472, -94, -363, -426, -434, 104, +367, -15, 238, -3, -125, 301, 24, 18, +-121, -490, -142, -85, 415, 571, 134, 40, +-452, -350, 38, 18, 322, -78, -89, -56, +-10, 446, 96, 208, -184, -733, 74, -406, +166, 889, -10, 507, -13, -827, -119, -445, +-7, 549, 238, 210, 146, -49, -344, 19, +-97, -511, 449, -108, 58, 834, -430, 81, +99, -845, 402, -45, -186, 694, -314, -70, +305, -463, 411, 288, -558, 133, -294, -469, +835, 210, 129, 450, -933, -368, 118, -276, +932, 260, -301, 154, -637, -68, 329, -118, +363, -71, -169, 171, -42, 48, -8, -265, +-104, 153, 189, 270, 153, -405, -83, -126, +-145, 526, -112, -131, 204, -425, 440, 404, +-247, 112, -632, -588, 284, 327, 756, 543, +-155, -669, -794, -257, 165, 723, 672, -205, +-73, -429, -321, 602, -39, -59, -33, -788, +255, 405, 363, 888, -424, -534, -435, -998, +499, 590, 432, 952, -386, -602, -256, -618, +144, 452, 168, 119, 218, -168, -125, 366, +-420, -222, 185, -609, 493, 558, -121, 462, +-395, -602, 53, -133, 281, 310, 134, -84, +-106, 70, -321, 78, 68, -308, 459, 61, +43, 370, -512, -249, -49, -328, 464, 422, +139, 259, -246, -568, -288, -128, 123, 534, +437, 27, 3, -308, -393, -36, -125, 59, +308, 43, 302, 144, -140, 14, -374, -284, +19, -96, 437, 284, 51, 121, -285, -52, +-36, -126, 93, -392, 5, 227, 205, 809, +56, -436, -365, -872, -75, 498, 404, 648, +201, -409, -316, -269, -248, 326, 195, -275, +293, -177, -59, 782, -206, -31, 39, -999, +99, 194, -136, 807, 193, -206, 353, -277, +-568, 8, -420, -304, 889, 257, 423, 723, +-949, -394, -293, -982, 793, 441, 215, 968, +-379, -421, -203, -661, 43, 303, 271, 202, +181, -135, -266, 261, -149, -49, 206, -536, +-20, 163, 73, 567, 187, -172, -286, -399, +-266, 84, 505, 157, 271, 22, -589, 38, +-79, -94, 546, -78, -62, 64, -480, -30, +318, 27, 400, 260, -399, -123, -393, -600, +416, 243, 626, 883, -452, -305, -799, -1055, +554, 277, 910, 1115, -667, -242, -622, -1047, +623, 243, 240, 813, -344, -231, 95, -496, +99, 213, -224, 128, 145, -146, 112, 255, +-59, -122, 121, -431, -173, 431, -202, 354, +429, -572, 199, -239, -488, 558, -42, 200, +376, -496, -58, -212, -123, 373, 166, 243, +-43, -200, -216, -263, 135, -73, 329, 349, +-111, 332, -373, -511, 130, -433, 342, 618, +-119, 377, -117, -627, 149, -163, -169, 478, +-152, -92, 562, -239, 119, 334, -803, 8, +45, -596, 770, 272, -69, 759, -473, -567, +35, -680, 103, 667, 137, 495, 290, -602, +-308, -295, -478, 440, 508, 102, 431, -190, +-499, -68, -138, 16, 325, 114, -134, 67, +-28, -187, 374, -126, -256, 298, -383, 178, +458, -411, 273, -244, -492, 515, -1, 278, +419, -527, -219, -254, -269, 365, 362, 280, +248, -114, -373, -359, -286, -92, 362, 423, +391, 198, -318, -433, -297, -142, 251, 272, +43, 44, 14, -11, 286, -12, -302, -191, +-445, 17, 469, 268, 527, -25, -385, -217, +-492, 20, 164, 65, 463, 41, 93, 101, +-342, -180, -210, -101, 213, 259, 121, -65, +117, -152, 82, 251, -513, -140, -106, -246, +758, 419, 96, 13, -797, -478, 128, 321, +514, 262, -243, -555, -86, 123, 309, 521, +-218, -362, -319, -319, 424, 288, 244, 226, +-308, -9, -192, -387, 125, -133, 102, 615, +207, 27, 6, -660, -491, 192, -47, 464, +661, -362, 160, -83, -721, 304, -138, -257, +632, -38, 123, 371, -395, -266, -90, -300, +226, 477, 35, 161, -73, -566, 111, -73, +-4, 579, -298, 68, 146, -599, 493, 25, +-364, 494, -456, -226, 587, -74, 246, 303, +-654, -552, 120, -39, 519, 1030, -382, -510, +-162, -1030, 465, 1030, -240, 562, -288, -1234, +587, 112, -5, 1077, -711, -694, 269, -686, +752, 978, -416, 291, -648, -977, 458, -50, +472, 848, -336, -118, -196, -637, 156, 264, +-74, 263, 116, -260, 288, 148, -326, 57, +-345, -412, 417, 206, 359, 508, -321, -442, +-325, -446, 126, 531, 350, 371, 83, -499, +-369, -331, -192, 484, 383, 143, 311, -322, +-434, 124, -267, -85, 455, -223, 182, 487, +-407, 176, -17, -737, 370, -111, -191, 835, +-206, 21, 356, -749, 9, 39, -383, 510, +236, 25, 205, -269, -280, -179, 47, 184, +190, 229, -258, -147, 56, -191, 346, 76, +-279, 174, -195, -30, 264, -129, 103, -35, +-168, 111, -5, 124, 67, -135, -32, -181, +-26, 181, 96, 199, 91, -155, -236, -285, +-89, 177, 375, 397, 20, -333, -353, -307, +94, 422, 191, 77, -152, -339, 69, 132, +156, 143, -300, -201, -45, 23, 411, 159, +-64, -66, -388, -88, 215, -2, 198, 62, +-272, 94, 112, -58, 199, -180, -279, 45, +-95, 301, 274, -144, 71, -318, -92, 299, +-112, 161, -175, -358, 314, 29, 335, 330, +-486, -129, -330, -323, 534, 214, 201, 304, +-381, -274, 73, -245, -48, 293, -131, 144, +397, -310, 125, 44, -522, 277, -70, -363, +434, -77, 95, 666, -154, -411, -325, -504, +69, 661, 464, 95, -107, -449, -319, 99, +95, 140, 43, -172, 118, 133, 84, 251, +-319, -489, 1, -221, 440, 893, -218, -140, +-439, -936, 580, 579, 100, 466, -636, -619, +239, 145, 452, 116, -306, -281, -297, 320, +352, 48, 55, -285, -253, 12, 143, 129, +41, 79, -14, -20, -90, -193, -50, -26, +160, 305, 121, -70, -202, -280, -235, 205, +376, 186, 79, -411, -189, 29, -126, 622, +34, -470, 195, -402, 25, 588, -101, 67, +-134, -279, 45, 5, 87, -85, 196, 156, +-179, 212, -307, -359, 322, 30, 251, 211, +-401, -244, -99, 131, 476, 269, -286, -411, +-199, -137, 375, 542, -1, -201, -279, -256, +116, 427, 77, -375, -241, -165, 366, 744, +66, -270, -543, -704, 85, 542, 560, 472, +-263, -660, -244, -155, 206, 640, -125, -175, +40, -502, 312, 431, -160, 250, -465, -459, +321, -8, 184, 277, -80, -113, 31, 16, +-160, 87, -184, -269, 143, -57, 613, 477, +-333, 82, -737, -758, 313, 20, 751, 920, +-181, -241, -598, -783, -32, 361, 289, 451, +356, -288, -125, -129, -461, 132, -48, -87, +508, -5, 37, 197, -410, -39, 111, -236, +70, 15, -47, 272, 61, -72, 58, -191, +-61, 158, -196, -31, 116, -71, 159, 130, +-112, -103, 3, 41, 102, 196, -329, -405, +28, -128, 575, 773, -242, -88, -507, -942, +206, 377, 395, 626, -49, -389, -208, 11, +-225, -130, 79, -403, 445, 704, -19, 475, +-506, -981, -17, -413, 495, 950, -116, 271, +-231, -675, 25, -67, 122, 275, 62, -195, +-243, 285, 96, 243, 170, -656, -42, -87, +-321, 565, -26, 102, 660, -332, -157, -211, +-766, 154, 384, 192, 497, 105, -403, -224, +-107, -360, 219, 478, -134, 222, -174, -527, +463, -24, -36, 429, -518, -40, 42, -391, +450, 82, 76, 357, -290, -61, -350, -441, +288, 249, 403, 350, -406, -542, -5, 74, +116, 613, -202, -554, 54, -411, 423, 820, +-333, 136, -386, -858, 403, 228, 168, 498, +-282, -329, 124, -5, -16, 54, -352, -123, +313, 107, 322, 81, -334, -133, -289, -29, +269, 209, 88, -236, -42, -125, 133, 584, +-428, -335, 9, -511, 487, 766, -113, -1, +-269, -735, -16, 426, 98, 420, -5, -452, +213, -354, -194, 559, -228, 129, 239, -485, +152, 247, -358, -74, 167, -286, 276, 718, +-599, -73, 97, -992, 650, 526, -316, 713, +-605, -593, 448, -392, 300, 639, -400, -188, +-13, -438, 280, 857, -363, -118, -41, -1164, +512, 783, -241, 967, -422, -1312, 266, -246, +316, 1397, -264, -690, -229, -997, 298, 1535, +-72, 95, -192, -1785, 207, 861, 149, 1345, +-407, -1459, -53, -382, 457, 1429, -178, -602, +-298, -928, 239, 1351, 2, 147, -111, -1669, +104, 751, -71, 1361, -112, -1381, 20, -487, +204, 1381, -111, -415, -207, -896, 108, 954, +186, 304, -156, -1138, -164, 267, 37, 839, +332, -556, -200, -261, -405, 543, 344, -446, +323, -103, -522, 826, -187, -435, 548, -742, +-38, 783, -509, 278, 231, -761, 414, 299, +-653, 417, -112, -689, 803, -23, -207, 980, +-873, -469, 448, -923, 678, 792, -539, 625, +-447, -904, 336, -160, 288, 768, -194, -352, +-212, -430, 139, 794, -95, -69, 51, -997, +37, 613, -112, 785, 86, -851, -125, -358, +-116, 738, 185, -19, 119, -509, -214, 350, +-235, 342, 49, -784, 359, -15, 89, 1115, +-567, -536, -136, -905, 387, 896, 249, 161, +-216, -554, -437, 349, 115, 64, 193, -613, +182, 225, -149, 1052, -374, -689, -77, -1329, +448, 1310, 204, 1084, -525, -1737, -143, -279, +178, 1529, 107, -637, 79, -726, -72, 1193, +-424, -227, 25, -1313, 559, 1044, -172, 1082, +-491, -1664, 182, -373, 198, 1746, -239, -483, +90, -1276, 134, 1124, -345, 516, -56, -1467, +234, 519, -23, 1175, -46, -1404, 8, -198, +-386, 1595, 33, -966, 714, -926, -307, 1666, +-872, -251, 589, -1511, 434, 1294, -606, 537, +58, -1549, 304, 626, -570, 940, -51, -1405, +936, 232, -572, 1526, -728, -1631, 681, -597, +250, 2395, -628, -1043, 151, -1784, 401, 2235, +-754, 266, 80, -2340, 817, 1158, -512, 1658, +-669, -2060, 628, -492, 132, 2134, -376, -620, +39, -1482, 45, 1198, -81, 627, -73, -1187, +26, 26, 67, 631, 138, -36, -496, -22, +-93, -508, 534, -341, 109, 1299, -640, 329, +-194, -2001, 593, 126, -57, 2032, -321, -598, +183, -1232, -225, 458, -224, 184, 545, 221, +34, 548, -769, -898, 162, -923, 605, 1352, +-508, 865, -226, -1413, 446, -323, -71, 862, +-631, -391, 360, 316, 473, 582, -498, -1293, +-427, -266, 340, 1503, 217, -152, 47, -978, +-460, 462, -406, -163, 753, -221, 284, 1148, +-986, -422, -31, -1457, 881, 1088, -555, 948, +-484, -1407, 833, 81, -36, 1217, -1170, -1178, +595, -501, 891, 1694, -1004, -293, -353, -1464, +779, 783, -295, 767, -321, -946, 518, 197, +-340, 612, -439, -785, 668, -105, -168, 839, +-663, -384, 633, -428, 407, 804, -1257, -276, +-17, -1157, 1371, 1130, -446, 1157, -1119, -1698, +425, -769, 668, 1692, -549, 134, -135, -1136, +377, 600, -322, 244, -576, -1174, 837, 588, +255, 1500, -1046, -1175, 73, -1343, 629, 1216, +-437, 900, -170, -868, 697, -213, -603, 192, +-860, -378, 1081, 444, 728, 796, -1525, -859, +-334, -1000, 1263, 1046, -239, 837, -665, -783, +424, -485, -262, 96, -269, 257, 617, 777, +-70, -414, -704, -1318, 197, 784, 280, 1312, +-236, -1171, 237, -695, -177, 1114, -800, 73, +672, -893, 829, 435, -1172, 520, -624, -546, +1108, -89, 156, 9, -844, 94, 292, 780, +-90, -621, -463, -1334, 898, 1410, 175, 1363, +-1586, -2141, 219, -911, 1605, 2616, -629, 65, +-1369, -2538, 626, 630, 750, 2196, -408, -1087, +-227, -1613, -301, 1067, -284, 1029, 1241, -632, +37, -649, -1896, 34, 86, 498, 2151, 388, +-305, -370, -2342, -513, 388, 70, 2045, 512, +-407, 209, -1746, -190, 160, -735, 1173, -121, +233, 1393, -1021, 200, -643, -1978, 815, 13, +750, 2228, -650, -251, -1059, -2291, 476, 575, +995, 2079, -410, -962, -773, -1360, 0, 1056, +266, 351, 277, -763, 385, 656, -994, 263, +-1043, -1487, 1688, 323, 1079, 2043, -2210, -1016, +-1035, -2042, 2524, 1538, 356, 1613, -2652, -1881, +504, -869, 2114, 1976, -1375, 116, -1251, -2030, +1420, 792, 402, 1748, -1321, -1568, 255, -1039, +852, 1767, -1066, 559, -109, -1936, 1161, -110, +-596, 2101, -939, -326, 731, -2083, 261, 469, +-472, 2110, 136, -468, -6, -2219, -534, 661, +196, 2161, 569, -1231, -158, -1537, -717, 1846, +-120, 485, 486, -2283, 468, 671, -487, 2497, +-766, -1775, 417, -2270, 545, 2467, -310, 1743, +-567, -2866, 441, -757, 303, 2791, -913, -454, +-171, -2255, 1357, 1397, -68, 1702, -1770, -1970, +-102, -1277, 2013, 1982, 61, 1196, -2057, -1519, +3, -1417, 1425, 623, -160, 1975, -576, 323, +33, -2566, -455, -1114, 90, 2935, 1153, 1688, +-473, -2975, -1546, -1992, 545, 2662, 1608, 2103, +-643, -2179, -1683, -1964, 566, 1534, 1366, 1784, +-223, -957, -1385, -1541, -352, 467, 1495, 1201, +726, 236, -2019, -1131, -798, -1136, 2452, 1642, +262, 1753, -2782, -2374, 378, -1971, 2831, 2951, +-1428, 1833, -2521, -3126, 2194, -1385, 1635, 2803, +-2613, 735, -699, -2050, 2415, 18, -328, 937, +-1900, -525, 864, 149, 1169, 673, -1063, -843, +-878, -727, 1032, 1377, 586, 593, -902, -1817, +-836, -195, 1054, 1940, 682, 2, -1262, -1992, +-524, -193, 1275, 2245, 192, 471, -1375, -2523, +268, -601, 960, 2338, -613, 859, -651, -1873, +885, -1140, -58, 1365, -899, 1091, 554, -704, +428, -721, -818, -59, 185, 122, 430, 926, +-761, 392, 5, -1605, 1166, -783, -767, 2026, +-1284, 994, 1285, -2119, 929, -1083, -1623, 1904, +-461, 1164, 1649, -1512, -358, -1298, -1348, 1110, +728, 1425, 935, -725, -890, -1447, -631, 241, +421, 1482, 560, 232, 68, -1469, -646, -607, +-739, 1314, 651, 758, 1280, -835, -863, -770, +-1560, 101, 824, 733, 1578, 613, -1022, -614, +-1268, -963, 1077, 220, 468, 1023, -934, 238, +193, -733, 669, -561, -941, 146, -487, 584, +1579, 625, 245, -260, -2336, -1477, -94, -132, +3032, 2012, -259, 524, -3616, -2128, 557, -619, +3751, 1542, -886, 578, -3547, -470, 1073, -441, +2801, -840, -1210, 304, -1963, 2054, 1445, -257, +782, -2796, -1811, 220, 297, 2835, 2124, -67, +-1133, -2008, -2639, -600, 1600, 778, 2935, 1693, +-1694, 378, -3234, -2711, 1554, -1237, 3043, 3095, +-1298, 2088, -2491, -3038, 727, -2673, 1601, 2679, +-34, 2682, -806, -1955, -902, -2226, 403, 1082, +1468, 1569, -258, -407, -2031, -981, 444, 169, +2330, 597, -1031, -229, -2396, -702, 1561, 487, +2190, 1364, -1903, -764, -2063, -2322, 1712, 788, +2226, 3261, -1352, -317, -2679, -4049, 804, -361, +3026, 4290, -261, 1022, -3028, -3741, -549, -1581, +2657, 2580, 1139, 1909, -1744, -1229, -1753, -1796, +355, -28, 2261, 1384, 971, 955, -2573, -1035, +-2222, -1243, 2780, 935, 2766, 858, -2718, -1035, +-2841, -98, 2341, 1103, 2467, -365, -1723, -1185, +-2122, 251, 952, 1182, 1942, 446, -428, -1030, +-1830, -1296, -68, 484, 1667, 2031, 387, 319, +-1298, -2299, -855, -996, 815, 1645, 1125, 1509, +-192, -207, -1294, -1748, -576, -1549, 1321, 1722, +1099, 2951, -1161, -1418, -1415, -3536, 810, 958, +1402, 3108, -389, -447, -1270, -1992, 34, 61, +924, 688, 185, 152, -526, 299, -388, -303, +-42, -631, 758, 573, 608, 299, -1549, -1115, +-907, 437, 2249, 1820, 1106, -1066, -2692, -2384, +-1454, 933, 2752, 2693, 1717, 119, -2194, -2798, +-2020, -1393, 1132, 2325, 2029, 2295, 256, -1157, +-1767, -2454, -1521, -325, 995, 1643, 2282, 1535, +144, 126, -2331, -2136, -1503, -2338, 1649, 1981, +2687, 4229, -529, -1189, -3404, -5122, -699, 148, +3419, 4581, 1513, 836, -2521, -2781, -2104, -1518, +1264, 358, 2175, 1844, -80, 1692, -1770, -1616, +-767, -2809, 907, 900, 1305, 2928, -83, -73, +-1505, -2143, -468, -673, 1325, 966, 639, 1138, +-953, 59, -470, -1142, 487, -662, 32, 764, +-230, 610, 778, 100, 26, -151, -1791, -1311, +46, -338, 2801, 2530, -52, 589, -3472, -3269, +-198, -614, 3593, 3152, 646, 758, -3073, -2450, +-1195, -752, 2002, 1128, 1427, 578, -437, 569, +-1199, -290, -1413, -2125, 674, -176, 2883, 3039, +169, 919, -3804, -3205, -916, -1739, 3872, 2853, +1298, 2032, -3329, -1913, -999, -1729, 2341, 755, +71, 864, -1245, 288, 1033, 187, 465, -841, +-1922, -1106, -230, 864, 2263, 1622, 488, -609, +-2084, -1585, -774, 422, 1312, 1088, 823, -644, +-207, -271, -596, 1159, -748, -380, 52, -1868, +1269, 692, 473, 2365, -1075, -575, -877, -2335, +340, 148, 990, 1753, 522, 192, -707, -711, +-1138, -248, 72, -353, 1281, -77, 662, 888, +-971, 874, -1211, -753, 368, -1795, 1341, 20, +173, 2431, -889, 979, -604, -2436, 270, -1736, +428, 1565, 589, 2009, 138, -64, -1500, -1716, +-670, -1628, 2090, 1230, 892, 2618, -2090, -690, +-878, -2447, 1649, 199, 800, 1291, -1320, 37, +-439, 336, 949, 7, 246, -1643, -824, -287, +-213, 2107, 689, 524, 485, -1460, -404, -624, +-1057, 147, 115, 394, 1382, 1133, 345, 178, +-1266, -1690, -819, -933, 530, 1287, 1187, 1480, +479, -104, -1055, -1393, -1484, -1396, 225, 669, +2304, 2431, 913, 634, -2590, -2684, -1880, -1905, +2130, 2026, 2392, 2591, -1205, -696, -2230, -2437, +209, -695, 1494, 1481, 369, 1678, -398, -234, +-416, -1869, -607, -836, 93, 1377, 1116, 1361, +327, -636, -1113, -1258, -340, 186, 631, 667, +-126, -253, 23, 4, 828, 678, -389, -134, +-1446, -1418, 261, -322, 1758, 2220, 138, 910, +-1530, -2584, -423, -1211, 663, 2175, 549, 1074, +468, -1126, -551, -570, -1106, -142, 200, -90, +1338, 1120, 74, 639, -1110, -1480, 36, -909, +522, 1235, -279, 826, -206, -626, 772, -471, +320, -52, -1304, 40, -636, 569, 1572, 165, +854, -736, -1238, -115, -822, 643, 541, -155, +420, -511, 162, 571, 492, 446, -716, -983, +-1396, -459, 832, 1199, 2006, 457, -400, -1090, +-2154, -354, -258, 608, 1883, 172, 781, 79, +-1266, 15, -830, -610, 498, -345, 517, 945, +202, 629, 9, -1010, -539, -733, -481, 770, +579, 601, 720, -288, -376, -294, -618, -351, +137, 182, 340, 662, -9, -156, 32, -525, +82, 133, -363, 90, -76, -82, 456, 398, +50, -37, -215, -642, 12, 124, -47, 605, +-120, -235, 230, -282, 363, 372, -289, -129, +-487, -600, 235, 501, 503, 907, -42, -779, +-370, -1080, -63, 786, 181, 1116, 142, -616, +-39, -944, -2, 461, 33, 462, -213, -392, +-84, 355, 511, 273, 119, -1224, -513, 36, +-126, 1614, 349, -305, 194, -1417, -75, 343, +-123, 859, -83, -207, 65, -287, 104, 145, +-27, -200, 230, -200, 143, 593, -748, 214, +-264, -763, 1306, -215, 535, 793, -1624, 183, +-624, -810, 1543, -163, 626, 964, -956, 91, +-393, -1165, 262, -47, 30, 1283, 364, 61, +569, -1134, -687, -190, -948, 604, 724, 596, +1004, -99, -338, -934, -599, -229, -19, 937, +-104, 320, 302, -548, 971, -203, -268, -28, +-1463, -107, 10, 465, 1589, 650, 404, -652, +-1199, -1258, -574, 589, 597, 1695, 537, -372, +81, -1661, -250, -16, -291, 1278, -80, 346, +173, -688, 427, -428, 231, 4, -346, 321, +-579, 520, 102, -170, 699, -668, 462, 42, +-424, 413, -868, 75, 28, -35, 1075, -91, +568, -330, -1005, 119, -767, 492, 773, -230, +700, -373, -341, 408, -280, 138, 30, -580, +-33, -30, 181, 672, 313, 182, -14, -680, +-524, -382, 76, 349, 674, 591, -193, 306, +-566, -833, 496, -813, 536, 813, -736, 865, +-286, -304, 900, -577, 97, -382, -754, 77, +223, 701, 640, 772, -477, -646, -447, -1718, +791, 441, 544, 2199, -854, -175, -665, -1963, +819, -45, 840, 1093, -306, 97, -793, 65, +-203, 41, 535, -1066, 851, -350, 103, 1632, +-1213, 656, -614, -1722, 1296, -682, 1151, 1331, +-1087, 463, -1053, -722, 791, -164, 665, 323, +-358, -195, 46, -218, 264, 448, -619, 356, +-208, -489, 1040, -599, 352, 372, -958, 716, +-251, -144, 652, -663, 165, 13, -132, 448, +95, -131, 26, -91, -256, 532, -192, -394, +522, -959, 752, 852, -468, 1134, -1204, -1054, +428, -1071, 1455, 984, -11, 822, -1276, -700, +-197, -588, 901, 428, 375, 398, -175, -225, +-284, -313, -237, 68, 118, 409, 594, -18, +201, -580, -459, 43, -371, 649, 365, -15, +556, -616, -186, -84, -358, 553, 224, 36, +237, -227, -225, -37, 22, -235, 393, 150, +66, 621, -459, -330, -40, -787, 544, 495, +201, 619, -291, -402, -198, -370, 93, 132, +285, 203, 307, 141, -200, -202, -435, -216, +297, 297, 511, 30, -249, -394, -175, 328, +233, 456, 63, -680, -159, -528, 201, 929, +320, 616, -325, -1058, -214, -564, 490, 907, +227, 355, -362, -388, -98, -157, 311, -317, +268, 85, -104, 911, -486, -93, 317, -1271, +807, 184, -403, 1287, -854, -299, 632, -1032, +901, 398, -617, 644, -547, -490, 682, -146, +131, 373, -474, -263, 659, 70, 178, 244, +-1035, -552, 294, 177, 1202, 752, -487, -574, +-724, -684, 483, 597, 333, 651, -123, -308, +38, -751, 34, -54, 2, 799, 12, 474, +-30, -744, 268, -879, 182, 642, -182, 1119, +-270, -525, 248, -1020, 323, 375, 5, 515, +34, -63, -211, 161, -317, -359, 540, -640, +746, 621, -553, 841, -789, -593, 592, -844, +657, 453, -344, 652, 8, -408, 168, -224, +-450, 501, -57, -417, 980, -554, 360, 951, +-1118, 502, -519, -1119, 1115, -346, 617, 866, +-537, 125, -269, -307, -129, 112, 36, -232, +719, -445, 507, 634, -739, 764, -877, -841, +637, -800, 1154, 707, -185, 470, -832, -199, +-56, 73, 236, -504, 473, -577, 541, 1018, +-434, 955, -947, -1166, 289, -1134, 1226, 1006, +143, 974, -972, -607, -315, -537, 643, 154, +453, -45, 4, 155, -318, 664, -275, -326, +186, -1079, 525, 394, 174, 1058, -442, -199, +-269, -896, 422, 7, 481, 753, -329, -60, +-398, -539, 576, 247, 249, 331, -520, -396, +-15, -210, 648, 420, -43, 251, -512, -443, +265, -243, 454, 453, -266, 70, -244, -411, +529, 222, 83, 272, -403, -366, 75, -194, +358, 272, 42, 341, -24, -144, -83, -478, +-119, -4, 253, 426, 297, 243, -7, -253, +-236, -514, -233, 132, 323, 634, 497, -145, +-4, -423, -486, 232, -291, -144, 569, -152, +638, 715, -272, -75, -697, -984, 72, 301, +652, 872, 468, -406, -520, -447, -581, 325, +486, -65, 587, -96, -155, 433, -388, -102, +16, -623, 400, 296, 199, 551, -390, -430, +-92, -179, 570, 344, 113, -184, -585, -194, +54, 418, 595, 134, 58, -557, -343, -146, +-48, 686, 148, 18, 181, -595, 234, 181, +-84, 259, -461, -296, 279, 161, 492, 284, +-232, -542, -86, -88, 224, 725, -242, -198, +42, -698, 495, 514, -79, 456, -237, -637, +-5, -184, 50, 472, 258, 99, 374, -120, +-310, -224, -576, -264, 366, 402, 784, 657, +-177, -586, -558, -895, 14, 692, 254, 787, +355, -483, 320, -495, -600, 29, -594, 214, +809, 346, 859, 29, -691, -415, -753, -289, +510, 223, 630, 472, -2, 116, -453, -450, +-147, -498, 257, 232, 386, 778, 80, 71, +-370, -802, -223, -376, 370, 607, 423, 542, +-138, -323, -335, -434, -105, 15, 426, 82, +432, 210, -373, 335, -449, -227, 318, -760, +546, 169, -66, 1041, -482, -222, -53, -948, +536, 320, 255, 573, -440, -371, -271, -183, +471, 403, 330, -66, -331, -392, -151, 148, +171, 273, 98, -48, 222, -103, 28, -58, +-543, -123, 134, 139, 793, 261, -210, -156, +-594, -132, 221, 8, 412, -234, -18, 259, +-26, 673, -114, -543, -228, -970, 388, 691, +419, 959, -352, -565, -403, -726, 323, 257, +389, 376, -74, 3, -131, 32, -147, -114, +-24, -413, 452, 64, 329, 723, -670, -56, +-324, -744, 804, 102, 307, 393, -583, -32, +-161, 67, 365, -190, 96, -276, -46, 331, +189, 255, -179, -372, -374, -104, 505, 371, +534, -137, -597, -282, -350, 277, 478, 178, +238, -321, -68, -27, -87, 259, -178, -149, +46, -160, 396, 301, 29, 62, -269, -264, +-17, -121, 103, 71, 55, 360, 226, 129, +76, -583, -408, -339, -143, 647, 558, 549, +308, -586, -441, -665, -378, 510, 320, 486, +489, -312, -150, -75, -403, -35, 180, -245, +280, 306, -195, 317, -67, -255, 424, -305, +-43, 18, -633, 307, 288, 59, 775, -137, +-354, 49, -698, -258, 481, -153, 462, 708, +-389, 34, -55, -765, 278, 164, -228, 234, +-17, -39, 406, 456, -135, -387, -218, -870, +132, 832, 56, 791, 127, -955, 119, -422, +-375, 728, -69, 38, 580, -361, 66, 226, +-647, 105, 80, -407, 685, 10, -231, 580, +-488, -191, 475, -554, 199, 391, -430, 263, +-39, -423, 480, 46, 134, 307, -562, -170, +-129, -211, 551, 138, 365, 160, -501, -66, +-380, -102, 367, 105, 290, -246, 50, 24, +-127, 721, -313, -549, -64, -704, 547, 851, +286, 358, -512, -707, -263, -66, 180, 341, +331, -45, 171, -24, -86, -1, -458, 13, +-193, -99, 674, -103, 437, 328, -442, 46, +-719, -317, 281, -89, 782, 137, 33, 326, +-585, -60, -266, -556, 380, 166, 384, 557, +-86, -329, -381, -299, 131, 343, 133, 129, +-143, -415, 181, -88, 272, 679, -383, 10, +-310, -909, 562, 84, 108, 917, -313, -47, +139, -764, 75, -25, -460, 404, 324, 130, +681, 76, -469, -257, -789, -503, 467, 379, +893, 709, -426, -368, -583, -695, 66, 171, +494, 665, 224, -40, -351, -521, -331, -77, +261, 372, 365, 172, -189, -280, -154, -245, +55, 316, 64, 211, 71, -405, 4, 34, +-45, 227, 6, -153, 31, 39, -77, 102, +231, -243, 57, 47, -365, 219, 43, -119, +418, -25, 4, 65, -465, -269, 173, 70, +312, 570, -170, -282, -144, -710, 264, 376, +59, 776, -474, -443, 275, -713, 513, 474, +-394, 589, -539, -545, 595, -375, 375, 585, +-581, 216, 8, -655, 271, -72, -41, 608, +-122, 7, 183, -410, 98, -110, -358, 225, +69, 157, 437, 55, -132, -273, -414, -226, +291, 333, 248, 227, -204, -279, -192, -127, +253, 130, 233, 39, -437, -20, 10, -31, +483, 103, -135, -106, -460, -213, 360, 370, +405, 61, -588, -458, -145, 192, 765, 333, +-172, -337, -635, -186, 336, 386, 463, 149, +-232, -518, -416, 10, 354, 574, 162, -260, +-333, -435, 220, 376, 318, 356, -673, -500, +-36, -253, 941, 516, -209, 261, -843, -494, +135, -390, 1014, 595, -266, 417, -867, -713, +331, -255, 720, 638, -379, 116, -338, -461, +240, -62, 142, 247, -38, 64, 0, 25, +-82, -229, 39, -165, 55, 347, 4, 201, +218, -330, -301, -241, -173, 276, 459, 184, +157, -95, -476, -68, -85, -234, 466, 74, +-29, 552, -257, -270, 141, -544, 4, 330, +-78, 383, 149, -126, 133, -339, -408, -51, +211, 238, 282, 379, -347, -250, -63, -657, +510, 368, -317, 741, -306, -512, 605, -506, +-65, 507, -561, -25, 500, -89, 220, 337, +-586, -339, 141, -394, 467, 602, -302, 328, +-251, -778, 405, 55, 0, 648, -348, -520, +355, -201, 90, 837, -547, -475, 428, -682, +356, 1040, -650, 107, -84, -1225, 767, 632, +-178, 1022, -603, -1247, 256, -467, 464, 1465, +-268, -163, -110, -1215, 61, 727, -115, 555, +150, -932, 368, 260, -401, 804, -415, -969, +649, -264, 166, 1284, -606, -434, 233, -1065, +380, 1083, -571, 391, -80, -1316, 812, 446, +-93, 1059, -910, -1025, 279, -494, 793, 1240, +-353, -96, -442, -1153, 368, 647, 19, 852, +-288, -1004, 389, -301, 103, 954, -406, -176, +-90, -511, 328, 431, 158, -57, -128, -367, +-255, 424, 46, 252, 341, -506, -127, -154, +-180, 390, 137, 107, 208, -185, -271, 64, +-194, -34, 350, -385, 305, 390, -344, 650, +-454, -587, 314, -809, 504, 670, -117, 885, +-506, -661, -100, -749, 592, 668, 71, 459, +-523, -738, 174, 157, 324, 695, -509, -786, +-8, -372, 766, 1221, -306, -161, -746, -1133, +439, 659, 640, 713, -518, -893, -411, -202, +712, 1056, -154, -394, -527, -884, 442, 990, +394, 239, -554, -1076, -212, 638, 476, 520, +-37, -1080, -139, 334, 137, 1036, -103, -1037, +-261, -496, 247, 1305, 388, -84, -275, -1135, +-408, 633, 65, 630, 482, -993, 173, 363, +-575, 843, -247, -1311, 537, -165, 221, 1869, +-476, -685, 78, -1740, 127, 1440, -322, 986, +308, -1683, 390, 252, -719, 1226, -210, -1296, +922, -170, -206, 1749, -855, -892, 763, -1482, +247, 1856, -900, 396, 316, -2038, 701, 1129, +-683, 1335, -356, -2256, 827, -5, -248, 2573, +-382, -1301, 395, -1686, -194, 1698, -174, 487, +595, -1068, -314, 416, -765, 49, 820, -573, +490, 691, -947, 417, -186, -874, 678, -37, +-163, 522, -3, -105, 87, 170, -621, -97, +162, -549, 838, 497, -415, 632, -760, -1022, +608, 12, 210, 1268, -512, -901, 183, -1000, +378, 1664, -519, 483, -301, -1777, 510, -33, +272, 1425, -335, 25, -396, -797, 43, -388, +455, 419, 75, 1028, -493, -492, 20, -1392, +162, 1082, -215, 1299, 127, -1796, 481, -482, +-676, 2248, -512, -737, 919, -1796, 222, 1871, +-974, 456, 174, -1949, 672, 1156, -691, 1057, +-293, -2118, 933, 319, -158, 2358, -1009, -1562, +527, -1614, 440, 2144, -588, 480, 84, -1854, +488, 777, -783, 971, -269, -1607, 909, 295, +81, 1739, -725, -1096, -119, -1170, -63, 1309, +273, 225, 951, -575, -881, 541, -1396, -379, +1039, -774, 1386, 1114, -1231, 602, -835, -1041, +967, -276, -232, 571, -507, -51, 1002, 193, +4, 516, -1678, -942, 324, -727, 1634, 1518, +-473, 684, -1408, -1507, 244, -300, 994, 1021, +-206, 24, -759, -294, 55, 216, 558, -201, +-193, -174, -618, 361, 157, 97, 595, -151, +-182, 266, -768, -274, -50, -601, 785, 759, +136, 1058, -961, -1149, -234, -1176, 801, 1337, +13, 1045, -564, -1077, -21, -578, -1, 607, +-18, 30, 451, 108, -443, 572, -841, -750, +854, -933, 705, 1402, -1413, 910, -394, -1556, +1445, -543, -256, 1396, -1381, 137, 866, -829, +546, 134, -1317, 368, 221, -5, 1164, -226, +-1053, -162, -912, 620, 1262, 311, 372, -1180, +-1342, -118, -90, 1691, 854, -147, -254, -1725, +-392, 444, 105, 1473, -253, -464, -23, -1097, +452, 619, -332, 830, -547, -793, 148, -602, +340, 1087, -13, 780, -330, -1426, -610, -1109, +272, 1940, 890, 1499, -640, -2173, -1063, -1728, +632, 2312, 682, 1779, -615, -2225, -511, -1333, +259, 2049, -39, 643, 184, -1750, -97, 398, +-841, 1371, 347, -1171, 996, -893, -1108, 1657, +-1153, 472, 1624, -1525, 844, 4, -2284, 1076, +-730, -461, 2435, -232, 348, 1029, -2673, -674, +-231, -1323, 2394, 1376, -140, 1639, -2262, -1644, +329, -1771, 1533, 1609, -760, 1929, -768, -1330, +648, -1726, -362, 966, -721, 1364, 1223, -536, +357, -530, -2103, 83, -380, -334, 2344, 386, +201, 1222, -2337, -515, -669, -2002, 1786, 743, +938, 2398, -1445, -669, -1467, -2494, 1018, 913, +1322, 2250, -1215, -1348, -954, -1604, 1290, 2157, +-93, 905, -1730, -3211, 977, 160, 1646, 4118, +-1980, -1234, -1437, -4240, 2095, 2253, 512, 3504, +-1860, -2799, 324, -1891, 708, 2983, -1374, -96, +455, -2515, 1504, 1911, -1627, 1759, -1382, -2748, +1837, -1072, 645, 2859, -1964, 779, 86, -2374, +1320, -653, -1002, 1842, -969, 705, 1239, -1417, +628, -631, -1533, 1499, -927, 396, 1321, -1868, +898, 272, -1018, 2319, -1401, -957, 497, -2491, +1227, 1588, -166, 2471, -1275, -1770, -385, -2226, +939, 1671, 316, 2081, -793, -1297, -378, -1877, +299, 847, -237, 1962, 237, -386, 367, -2153, +-1177, 331, -803, 2230, 2091, -187, 432, -2072, +-3179, -38, -78, 1884, 3633, 710, -849, -1808, +-3911, -1423, 1476, 1943, 3404, 2120, -2248, -1960, +-3019, -2597, 2545, 2048, 2174, 2750, -2875, -1789, +-1759, -2525, 2635, 1277, 1298, 2326, -2726, -606, +-1196, -2030, 2383, 59, 833, 1926, -2431, 381, +-621, -1996, 2137, -322, -108, 2168, -2009, 23, +516, -2130, 1552, 459, -1378, 1886, -1104, -711, +1718, -1304, 206, 835, -2105, 435, 292, -582, +2061, 813, -1106, 91, -2026, -2072, 1308, 658, +1531, 3252, -1455, -1418, -1380, -3826, 1016, 2120, +1020, 3698, -822, -2230, -1081, -2895, 420, 1826, +848, 1965, -496, -947, -869, -1134, 390, 88, +531, 698, -582, 618, -613, -491, 580, -929, +354, 511, -678, 1010, -701, -500, 585, -678, +775, 270, -709, 325, -1280, 298, 648, 92, +1409, -949, -953, -451, -1576, 1650, 927, 831, +1205, -2021, -1022, -1164, -1028, 2161, 615, 1401, +700, -1821, -405, -1402, -763, 1293, -373, 1180, +981, -612, 789, -544, -1629, 15, -1507, -233, +2171, 548, 1665, 965, -2887, -746, -1638, -1421, +2901, 742, 935, 1530, -2661, -402, -187, -1230, +1712, -46, -1086, 791, -627, 527, 1952, -187, +-655, -815, -3028, -296, 1557, 864, 3576, 783, +-2435, -546, -4020, -1074, 2538, -129, 4076, 1467, +-2717, 1079, -4105, -1855, 2554, -1757, 3495, 1939, +-2634, 2183, -2652, -1401, 2417, -2215, 1127, 387, +-2395, 1857, 488, 1076, 1843, -1113, -2086, -2387, +-1613, 159, 3019, 3099, 1305, 1179, -3579, -3027, +-1500, -2514, 3293, 2354, 1708, 3557, -2849, -1250, +-2209, -3831, 2093, 84, 1994, 3420, -1286, 925, +-1822, -2461, 422, -1390, 1030, 1411, 144, 1346, +-350, -554, -975, -936, -62, 314, 1291, 576, +-229, -740, -1770, -365, 1015, 1661, 1813, 571, +-2417, -2585, -1832, -1107, 3437, 3105, 1679, 1975, +-4235, -2965, -1765, -2753, 4075, 2168, 1747, 3376, +-3421, -974, -2059, -3543, 2130, -149, 2151, 3374, +-922, 846, -2311, -2883, -424, -889, 2177, 2342, +1269, 501, -2082, -1894, -2031, 94, 1528, 1614, +2592, -252, -1200, -1457, -3195, -263, 486, 1448, +3764, 1488, -272, -1451, -4088, -2744, -221, 1201, +3925, 3637, 340, -545, -3344, -3677, -705, -302, +2179, 2877, 919, 1067, -1218, -1316, -1142, -1307, +167, -585, 1135, 1135, 278, 2206, -1242, -485, +-463, -3083, 1140, -243, 87, 3132, -1025, 817, +-79, -2548, 863, -894, 71, 1807, -786, 508, +-623, -1225, 498, 117, 1115, 1163, -224, -621, +-1611, -1337, -395, 600, 1381, 1558, 1125, 172, +-887, -1506, -1891, -1282, -267, 935, 2151, 2270, +1418, 483, -1976, -2896, -2766, -2170, 1245, 2988, +3525, 3474, -482, -2275, -3783, -3904, -339, 1014, +3127, 3376, 726, 436, -2130, -2046, -773, -1527, +598, 480, 374, 1913, 755, 895, -84, -1367, +-1814, -1813, -415, 331, 2261, 2035, 555, 1045, +-2179, -1698, -938, -2270, 1618, 1053, 1153, 3234, +-964, -442, -1604, -3701, 229, 295, 1789, 3335, +214, -406, -1798, -2063, -614, 518, 1131, 235, +859, -370, -374, 1698, -972, 37, -709, -3176, +750, 410, 1459, 3826, -490, -746, -1874, -3384, +45, 880, 1636, 2086, -150, -826, -851, -311, +547, 891, -412, -1443, -1544, -1054, 1437, 2555, +2816, 1589, -2346, -2875, -4000, -2144, 2493, 2374, +4473, 2512, -2129, -1300, -4197, -2363, 1172, 85, +2942, 1713, -204, 831, -1225, -678, -738, -1042, +-640, -535, 1129, 670, 1959, 1564, -1108, 141, +-2853, -2194, 861, -886, 2702, 2384, -586, 1171, +-2165, -2143, 497, -653, 1156, 1404, -799, -242, +-299, -513, 1191, 1197, -295, -207, -1719, -1829, +195, 697, 2116, 1900, 110, -886, -2307, -1418, +-637, 1051, 2033, 514, 742, -1178, -1366, 428, +-607, 1441, 295, -1047, 162, -1764, 469, 1246, +436, 1915, -1041, -884, -972, -1797, 1000, 327, +1034, 1300, -574, 76, -724, -361, -287, -31, +137, -814, 887, -333, 407, 1690, -1212, 1056, +-837, -1932, 1054, -1703, 714, 1283, -650, 2128, +-313, 124, 105, -2221, -298, -1633, 87, 1943, +774, 2627, -62, -1321, -1083, -2666, -241, 543, +1165, 1905, 154, 64, -983, -628, 46, -430, +864, -286, -762, 312, -891, 590, 1387, 74, +1023, -77, -1654, -472, -1378, -841, 1221, 588, +1507, 1695, -106, -245, -1604, -2014, -1158, -328, +1159, 1614, 2061, 822, -414, -585, -2319, -901, +-448, -649, 1617, 509, 1092, 1537, -384, 374, +-1424, -1851, -872, -1331, 1132, 1575, 1704, 1967, +-529, -846, -2079, -2080, -3, 104, 1702, 1620, +417, 510, -1335, -777, -446, -997, 960, 161, +314, 1246, -1011, 54, -253, -1182, 1318, 8, +191, 956, -1384, 15, -629, -838, 1288, -176, +967, 819, -735, 548, -1237, -795, -67, -1053, +1134, 758, 712, 1461, -624, -587, -1198, -1553, +77, 179, 1115, 1536, 320, 233, -804, -1360, +-293, -531, 304, 1135, -85, 754, 13, -1035, +537, -792, -85, 1105, -782, 572, -82, -1124, +489, -67, 323, 780, 149, -360, -322, -110, +-1094, 547, 89, -645, 1796, -447, 430, 1184, +-2100, 240, -1072, -1335, 1948, -65, 1422, 1137, +-1360, 71, -1536, -739, 788, -239, 1123, 348, +-402, 497, -252, -13, 72, -813, -656, -234, +78, 1263, 1406, 266, -310, -1677, -1667, -38, +504, 1843, 1530, -313, -755, -1653, -1070, 684, +922, 1152, 518, -1026, -971, -390, 16, 1152, +793, -307, -393, -1149, -408, 883, 543, 852, +56, -1150, -668, -269, 357, 966, 591, -291, +-474, -677, -533, 806, 429, 340, 395, -985, +-135, -271, -287, 874, -188, 420, 196, -555, +394, -545, -2, 6, -519, 560, -81, 489, +437, -331, 169, -782, -194, -143, -288, 750, +52, 652, 338, -372, -14, -1026, -335, -199, +183, 1072, 296, 743, -389, -827, -245, -1020, +515, 342, 394, 934, -536, 95, -562, -570, +398, -207, 735, -138, -154, 62, -669, 938, +-34, 38, 260, -1399, 151, -67, 540, 1314, +-195, -20, -1182, -835, -29, 191, 1604, 131, +406, -367, -1448, 444, -746, 425, 747, -719, +1050, -433, 181, 703, -911, 370, -1059, -667, +649, -259, 1434, 743, -223, 47, -1079, -971, +-101, 102, 270, 1282, 148, -228, 813, -1532, +57, 288, -1528, 1452, -306, -230, 1644, -1167, +604, 85, -1176, 749, -498, 43, 333, -476, +175, -80, 536, 428, 345, -106, -1039, -562, +-721, 359, 1264, 662, 717, -543, -1032, -731, +-213, 557, 682, 630, -413, -460, -287, -438, +943, 271, 109, 216, -976, -175, -50, -86, +615, 117, 135, 38, 106, -138, -94, -91, +-699, 92, 53, 17, 1068, 91, 180, 175, +-1035, -460, -301, -555, 913, 790, 347, 972, +-723, -1026, -138, -1265, 724, 934, -11, 1132, +-722, -529, 229, -615, 708, -153, -101, -219, +-394, 717, -41, 1026, -51, -963, 261, -1731, +685, 856, -213, 1931, -992, -629, -92, -1508, +1233, 209, 565, 625, -922, 70, -814, 292, +546, -180, 843, -987, -105, -10, -273, 1192, +-35, 215, -351, -962, -120, -370, 1083, 298, +615, 404, -1257, 309, -964, -337, 1080, -755, +1229, 134, -365, 859, -961, -47, -321, -672, +552, -32, 856, 213, 188, 46, -892, 223, +-555, -264, 656, -498, 898, 505, -141, 437, +-802, -792, 97, -333, 652, 1010, -189, 127, +-320, -1268, 734, 69, 209, 1319, -1080, -365, +27, -1206, 1185, 573, 37, 804, -559, -720, +137, -393, -251, 657, -174, -16, 1344, -605, +485, 339, -1870, 317, -668, -559, 1995, -76, +1070, 560, -1442, -105, -1070, -634, 890, 108, +1077, 622, -133, -80, -683, -648, -1, -93, +360, 576, 103, 155, 55, -499, 293, -207, +-182, 241, -358, 162, 300, -3, 538, -242, +-58, -234, -288, 348, 194, 205, 147, -545, +-79, -68, 100, 527, 437, -153, -48, -395, +-430, 145, -88, 80, 682, -73, 537, 265, +-485, -227, -506, -622, 260, 476, 744, 686, +245, -626, -376, -633, -466, 500, 219, 362, +709, -337, 199, -83, -441, 130, -155, -286, +300, -101, 220, 464, 185, 147, 259, -514, +-197, -488, -471, 376, 321, 795, 1028, -251, +-114, -1099, -1068, 25, 232, 1150, 1196, 60, +-136, -1048, -826, -198, 603, 700, 639, 156, +-610, -268, -164, -203, 862, -347, 192, 291, +-532, 743, -128, -532, 457, -1026, 480, 734, +-95, 971, -433, -1036, 390, -718, 474, 1135, +-444, 236, 112, -1193, 1006, 210, -519, 890, +-955, -518, 1218, -451, 802, 390, -1168, -177, +-48, -71, 1272, 791, -638, -543, -599, -1344, +1518, 1003, 345, 1544, -1590, -1261, 240, -1528, +1564, 1052, -313, 1126, -676, -609, 587, -692, +75, 67, -530, 121, 762, 172, 980, 349, +-829, -293, -990, -672, 923, 103, 1344, 656, +-373, 65, -929, -580, 127, -125, 619, 331, +370, -214, 237, -171, -203, 660, -603, -25, +278, -1038, 1027, -122, 232, 998, -534, 509, +-261, -808, 170, -1056, 553, 363, 641, 1329, +-165, 15, -891, -1375, 76, -302, 1169, 928, +488, 236, -656, -267, -449, -123, 417, -494, +705, -124, 258, 902, -392, 246, -220, -1051, +359, -331, 366, 780, 97, 188, 22, -390, +-10, -117, 16, -130, 344, 60, 295, 410, +-226, -257, 96, -546, 565, 496, -168, 385, +-464, -872, 681, -120, 656, 1028, -639, -319, +-229, -1044, 774, 678, 136, 718, -271, -1127, +488, -198, 212, 1327, -647, -489, 323, -1375, +996, 936, -272, 1106, -638, -1181, 416, -738, +592, 954, -168, 295, 57, -604, 302, -53, +-74, 192, -81, -183, 365, -24, 397, 268, +39, -40, -336, -444, -111, -37, 644, 416, +454, 84, -274, -333, -299, -288, 198, 115, +410, 347, 470, 106, -66, -444, -486, -429, +91, 399, 720, 597, 317, -394, -300, -695, +-329, 308, 144, 422, 730, -234, 417, -44, +-668, 51, -362, -478, 877, 48, 647, 809, +-487, -205, -472, -897, 464, 133, 616, 634, +111, -47, -503, -297, -197, -127, 748, -170, +633, 216, -525, 372, -529, -296, 611, -415, +804, 218, -196, 193, -599, -210, 135, 8, +814, 186, 121, -196, -510, -383, 53, 218, +589, 493, 4, -194, -165, -540, 354, -29, +100, 326, -155, 232, 308, -38, 200, -557, +-223, -259, 241, 741, 333, 230, -357, -802, +60, -73, 777, 688, -246, -316, -502, -640, +678, 686, 472, 509, -538, -980, 69, -405, +388, 803, -41, 263, 212, -299, 198, -319, +-508, -390, 178, 347, 888, 844, -128, -418, +-651, -993, 293, 336, 549, 701, 87, -296, +78, -233, -312, 238, -317, -336, 798, -334, +754, 654, -780, 432, -702, -790, 868, -570, +808, 576, -401, 541, -451, -251, 203, -448, +336, -166, 301, 214, 77, 439, -362, -102, +-116, -588, 496, 8, 421, 495, -226, -5, +-335, -475, 216, -3, 525, 469, 38, -116, +-247, -524, -48, 160, 342, 402, 201, -146, +-77, -175, -75, -87, -10, -175, 332, 292, +327, 469, -359, -491, -301, -667, 689, 467, +453, 582, -616, -275, -232, -440, 628, 5, +239, 112, -203, 121, 21, 196, -111, -202, +40, -455, 656, 69, 104, 518, -746, 83, +34, -482, 847, -344, 101, 394, -408, 467, +-55, -433, 57, -524, 266, 501, 577, 402, +-297, -658, -816, -270, 513, 728, 1045, 79, +-432, -767, -655, 101, 364, 585, 385, -341, +5, -306, 140, 483, -165, -63, -306, -596, +416, 261, 461, 543, -267, -242, -265, -497, +248, -5, 148, 380, 28, 240, 207, -225, +-70, -473, -282, 30, 201, 546, 414, 26, +-66, -469, -238, -32, 80, 220, 190, -50, +12, -53, 117, 156, 153, -59, -209, -299, +-121, -1, 345, 349, 306, 69, -228, -327, +-217, -148, 70, 121, 341, 159, 228, 99, +-248, -184, -308, -279, 297, 164, 481, 223, +-181, -139, -366, 7, 224, -86, 321, -227, +-60, 274, -189, 252, 89, -348, 239, -188, +-39, 216, -195, 38, 276, -20, 277, 87, +-488, -232, -78, -252, 839, 453, -77, 346, +-953, -686, 425, -378, 961, 751, -581, 358, +-634, -706, 772, -374, 165, 533, -491, 264, +300, -133, 259, -287, -412, -418, 4, 532, +443, 699, 6, -854, -250, -626, -20, 911, +129, 324, 184, -666, 27, -179, -197, 350, +36, 149, 317, -251, -127, -52, -292, 78, +447, -42, 240, 109, -530, 63, -174, -281, +526, -101, 293, 386, -308, 103, -278, -407, +26, -135, 332, 231, 340, 208, -218, 53, +-399, -392, -89, -291, 486, 460, 545, 436, +-484, -385, -723, -639, 425, 392, 756, 589, +-229, -484, -471, -236, 154, 412, -35, -225, +185, -209, 469, 442, -359, -8, -707, -293, +523, -137, 877, 117, -743, 459, -587, -304, +813, -428, 287, 457, -650, 98, -129, -466, +683, 127, -30, 527, -441, -234, -84, -732, +324, 183, 366, 1089, -300, -243, -413, -1277, +142, 287, 541, 1091, -13, -121, -452, -838, +-69, -67, 211, 562, 272, 61, 81, -161, +-377, -76, -389, -252, 534, 143, 623, 546, +-634, -398, -614, -577, 615, 620, 523, 415, +-474, -716, -290, -314, 202, 736, 162, 257, +41, -669, -36, -233, -282, 365, 77, 397, +420, -80, -257, -634, -323, -83, 462, 664, +87, 303, -599, -763, 249, -337, 586, 802, +-486, 152, -474, -763, 547, 155, 432, 559, +-583, -369, -334, -379, 502, 371, 284, 401, +-473, -378, -115, -471, 339, 345, -116, 539, +-33, -366, 85, -421, -41, 243, -184, 246, +63, -23, 309, -161, -118, -193, -408, 177, +162, 325, 431, -378, -304, -173, -236, 377, +340, 41, -95, -311, -271, -40, 299, 301, +224, 45, -533, -306, -80, -41, 386, 206, +165, 166, -242, -205, -453, -307, 344, 299, +355, 281, -283, -354, -271, -199, 275, 334, +-50, 25, -204, -209, 384, 49, -88, 165, +-451, -206, 47, -112, 627, 331, -193, 114, +-713, -520, 385, -92, 495, 705, -525, -121, +-156, -614, 327, 275, -89, 309, -97, -290, +65, 40, -19, 182, -189, -327, 111, -66, +337, 523, -441, -43, -314, -682, 462, 235, +385, 658, -556, -452, -577, -298, 636, 200, +555, 203, -625, 167, -581, -487, 445, -301, +582, 751, -340, 341, -668, -969, 343, -340, +408, 1078, -266, 239, -234, -968, 157, -141, +-158, 650, 131, 40, 110, -233, -101, 142, +-405, -403, 163, -170, 541, 926, -383, -1, +-498, -1023, 344, 47, 378, 811, -394, -10, +-225, -405, 298, -44, -81, -252, -143, 405, +189, 610, -195, -772, 1, -570, 27, 869, +22, 365, -260, -872, 244, 19, 171, 748, +-614, -585, 50, -210, 605, 742, -367, -319, +-337, -438, 256, 459, 130, 135, -481, -475, +426, 143, 134, 480, -653, -578, 35, -185, +472, 882, -14, -529, -406, -471, 85, 870, +-234, -167, 262, -781, 342, 671, -437, 362, +-431, -845, 356, 200, 271, 592, -215, -646, +-153, -92, 73, 929, -348, -708, 323, -633, +330, 1238, -487, -86, -285, -1212, 412, 823, +-80, 739, -148, -1440, 285, 196, -217, 1454, +-467, -1141, 283, -722, 530, 1517, -391, -367, +-453, -1071, 163, 1073, 321, 357, -98, -1306, +-107, 292, -223, 1087, 48, -655, 289, -584, +-215, 782, -257, -228, 330, -487, -58, 1009, +-253, -229, -27, -1223, 243, 877, -102, 886, +-69, -1248, -29, -89, -168, 1139, 15, -732, +349, -752, -34, 1383, -577, 171, 26, -1584, +383, 336, 217, 1375, -369, -742, -469, -669, +231, 697, 560, -21, -210, -366, -693, 417, +277, -6, 568, -487, -539, 324, -333, 244, +682, -408, -173, 19, -518, 450, 358, -230, +158, -466, -483, 351, 268, 498, 310, -435, +-710, -432, -64, 458, 704, 241, -28, -377, +-835, 29, 307, 189, 418, -200, -562, -87, +256, 438, 415, -17, -867, -762, -119, 381, +987, 867, -91, -861, -980, -546, 284, 1045, +524, 46, -334, -745, -105, 333, 169, 74, +-262, -376, -79, 597, 560, 393, -463, -1406, +-305, -117, 625, 2065, -73, -638, -606, -1851, +195, 1278, 616, 859, -493, -1379, -304, 413, +430, 932, -179, -1344, -115, -305, 293, 1787, +-63, -298, -524, -1731, 273, 910, 248, 1151, +-190, -1554, 125, 136, -210, 1687, -421, -1510, +499, -1219, 622, 2394, -767, 445, -495, -2654, +608, 704, 48, 1912, -91, -1626, 296, -327, +-633, 1780, -604, -1324, 1256, -1089, 434, 2465, +-1517, -249, 58, -2598, 980, 1815, -371, 1539, +-302, -2735, 563, 147, -500, 2606, -381, -1536, +915, -1583, -171, 2085, -773, 45, 662, -1229, +87, 863, -826, -221, 369, -673, 871, 1118, +-915, 14, -420, -1155, 845, 635, -213, 379, +-154, -752, 305, 719, -317, 204, -373, -1441, +731, 788, 7, 1295, -622, -1412, 162, -705, +444, 1740, -583, -236, -53, -1433, 622, 963, +-97, 682, -736, -916, 59, -153, 758, 415, +-79, 6, -465, 447, -166, -558, 304, -936, +203, 1507, -118, 648, -57, -2091, -140, 197, +-259, 1897, 496, -901, 222, -1211, -610, 1366, +-286, 77, 722, -1138, -55, 1081, -564, 101, +297, -1541, 388, 1252, -503, 1085, -221, -2084, +672, -157, -126, 2032, -444, -456, 290, -1450, +75, 720, -441, 519, 335, -516, 319, 428, +-597, 13, -122, -965, 420, 497, -122, 909, +-21, -639, 364, -228, -675, 203, -391, -528, +1257, 543, 246, 1107, -1533, -1206, 85, -1193, +1274, 1432, -443, 915, -668, -1193, 584, -348, +2, 750, -863, -386, 677, -240, 774, 1116, +-975, -138, -722, -1651, 920, 518, 773, 1633, +-859, -614, -620, -1181, 641, 542, 576, 461, +-634, -178, -381, 113, 527, -162, 116, -374, +-282, 491, -247, 243, 10, -684, 528, 317, +10, 606, -860, -945, 183, -218, 797, 1368, +-302, -291, -489, -1301, 392, 687, -117, 906, +-95, -930, 493, -111, -319, 852, -624, -752, +679, -410, 348, 1406, -1053, -215, 240, -1482, +957, 714, -940, 1011, -383, -767, 1112, -127, +-305, 109, -764, -377, 770, 731, 256, 502, +-1150, -1434, 613, -177, 829, 1830, -1033, -486, +-335, -1554, 740, 934, 75, 1080, -412, -1039, +-17, -616, -46, 825, 33, 489, 360, -484, +-275, -718, -283, 474, 479, 985, -186, -819, +-375, -953, 822, 1363, 22, 676, -1532, -1993, +748, -32, 1570, 2452, -1369, -763, -1265, -2478, +1444, 1508, 696, 2100, -1195, -1929, -121, -1532, +505, 2211, -191, 794, 259, -2201, 53, -125, +-585, 2037, 211, -233, 678, -1891, -761, 534, +-414, 1522, 1332, -434, -193, -1104, -1729, 121, +461, 811, 2010, 168, -710, -438, -2003, -291, +394, -119, 2003, 461, 8, 843, -1964, -776, +-296, -1439, 1798, 1115, 544, 2098, -1705, -1757, +-486, -2260, 1429, 2354, 289, 1840, -1073, -2320, +-337, -1228, 769, 1786, 131, 653, -328, -916, +-46, -172, -252, 64, -65, -250, 765, 660, +344, 572, -1309, -1018, -514, -790, 1660, 1155, +498, 742, -1665, -943, -252, -640, 1258, 909, +-363, 242, -551, -924, 907, 379, -389, 845, +-1255, -640, 1075, -921, 1128, 731, -1476, 867, +-387, -448, 1322, -580, -614, -153, -816, 254, +1737, 700, -23, 265, -2517, -1033, 967, -822, +2447, 1263, -1706, 1022, -1831, -1075, 1962, -988, +979, 721, -2162, 895, -177, -590, 2219, -743, +-410, 1060, -2114, 235, 570, -1599, 1975, 251, +-491, 2166, -1574, -555, 199, -2644, 996, 890, +43, 2712, -306, -1081, -447, -2390, -287, 1262, +754, 1692, 352, -1221, -849, -896, -189, 989, +732, 208, -224, -393, -404, 90, 676, -284, +-100, 32, -1068, 850, 969, -308, 919, -1107, +-1693, 515, -669, 1155, 2195, -509, 278, -1098, +-2554, 492, 101, 1030, 2277, -626, -162, -824, +-1814, 903, -88, 506, 1372, -1094, 288, -191, +-876, 1096, -478, 144, 559, -1013, 574, -220, +-488, 894, -562, 263, 546, -505, 317, -409, +-606, 105, -235, 645, 481, 244, 221, -879, +-261, -398, -416, 1027, -146, 466, 838, -1046, +510, -456, -1339, 978, -696, 378, 1890, -726, +357, -158, -1940, 132, -43, 99, 1681, 683, +-320, -235, -1379, -1443, 638, 397, 777, 2312, +-669, -833, -412, -2817, 421, 1301, 401, 2868, +-227, -1384, -494, -2833, -87, 1259, 964, 2832, +21, -1042, -1224, -2775, 71, 787, 1260, 2637, +-183, -366, -1228, -2522, 179, 7, 991, 2283, +1, 339, -984, -1805, -302, -730, 1139, 1276, +612, 1037, -1634, -733, -496, -1070, 1907, 237, +322, 787, -2208, 221, 385, -240, 1833, -530, +-1020, -429, -1252, 604, 1552, 1195, 363, -531, +-1873, -1838, 475, 462, 1710, 2079, -1161, -153, +-1052, -2047, 1346, -224, 77, 1843, -961, 534, +736, -1390, 505, -802, -1528, 897, 130, 944, +1775, -459, -462, -731, -1819, -2, 446, 245, +1546, 533, -240, 400, -1227, -1036, -71, -892, +731, 1283, 382, 1136, -285, -1124, -411, -969, +-411, 548, 339, 404, 1226, 459, -218, 247, +-2142, -1337, 231, -905, 2746, 1812, -480, 1402, +-2826, -1636, 717, -1555, 2226, 761, -986, 1417, +-1134, 480, 1179, -967, -260, -1672, -1237, 351, +1396, 2290, 1394, 497, -2045, -2217, -1780, -1436, +2213, 1681, 2276, 2157, -2120, -802, -2698, -2512, +1841, -30, 2679, 2341, -1484, 775, -2420, -1900, +1202, -1194, 1738, 1454, -859, 1203, -1137, -1210, +544, -789, 708, 1253, 4, 198, -986, -1590, +-421, 281, 1662, 2216, 834, -514, -2686, -2801, +-1227, 252, 3671, 3196, 1483, 442, -4361, -3161, +-1805, -1399, 4635, 2594, 1939, 2419, -4270, -1634, +-2226, -3233, 3688, 565, 2298, 3679, -2771, 316, +-2396, -3800, 1881, -589, 2233, 3598, -913, 307, +-1994, -3282, -209, 418, 1757, 2882, 1233, -1075, +-1496, -2377, -2315, 1098, 1188, 1842, 3238, -262, +-823, -1248, -3968, -1169, 394, 463, 4264, 2724, +147, 582, -4078, -3870, -826, -1650, 3488, 4145, +1439, 2501, -2662, -3460, -1993, -2718, 1892, 1914, +2037, 2366, -1224, -160, -1786, -1448, 812, -1257, +1037, 304, -423, 1959, -114, 656, -93, -1859, +-704, -1248, 758, 1377, 1356, 1379, -1713, -1038, +-1697, -1093, 2698, 1112, 1729, 727, -3398, -1621, +-1762, -597, 3532, 2269, 1843, 869, -3141, -2579, +-1873, -1440, 2096, 2149, 1713, 2045, -554, -859, +-1422, -2402, -1011, -1008, 859, 2404, 2245, 2804, +-109, -2073, -3023, -3659, -521, 1258, 2894, 3407, +1116, -142, -2230, -2194, -1590, -1051, 1161, 615, +1890, 1960, -2, 848, -2195, -2399, -922, -1810, +2386, 2375, 1366, 2072, -2240, -1883, -1465, -1661, +1762, 948, 1100, 847, -800, 295, -532, 50, +-421, -1577, -223, -679, 1448, 2339, 1167, 1050, +-2206, -2215, -2004, -1310, 2298, 1314, 2478, 1367, +-1660, 173, -2530, -1276, 660, -1633, 1925, 949, +411, 2524, -818, -308, -1347, -2616, -226, -398, +1603, 1887, 909, 833, -1237, -447, -969, -1059, +395, -878, 276, 692, 573, 1631, 984, 426, +-1473, -1833, -2222, -1899, 1769, 1511, 3303, 3252, +-1636, -826, -3769, -4032, 1008, 49, 3591, 4008, +-199, 467, -2921, -3000, -382, -596, 1620, 1219, +741, 328, -79, 875, -927, 253, -1243, -2770, +743, -840, 2206, 3871, -463, 1271, -2582, -4003, +277, -1224, 2184, 3176, -72, 681, -1599, -1722, +301, 5, 880, 530, -816, -889, -500, 215, +1513, 1499, 603, -418, -2293, -1396, -960, 50, +2743, 742, 1164, 443, -2500, 119, -1075, -492, +1604, -834, 599, -58, -404, 1042, 166, 1079, +-674, -718, -900, -1987, 1220, -32, 1182, 2317, +-1056, 812, -949, -1811, 360, -1168, 326, 572, +271, 1000, 463, 655, -445, -111, -1182, -1366, +160, -1163, 1425, 1258, 515, 2210, -1344, -223, +-935, -2645, 881, -1409, 886, 2522, -400, 2764, +-279, -1905, 72, -3227, -578, 1091, 25, 2559, +1094, -310, 152, -1166, -1117, -169, -259, -235, +552, 219, 122, 1074, 193, 42, 360, -1109, +-679, -294, -979, 514, 443, 237, 1562, 316, +372, 150, -1719, -842, -1444, -806, 1278, 947, +2312, 1220, -484, -538, -2521, -1103, -353, -223, +1996, 535, 786, 902, -878, 272, -760, -1160, +-213, -1050, 218, 911, 992, 1646, 460, -478, +-1310, -1810, -891, 110, 1254, 1458, 850, 246, +-1081, -922, -489, -581, 1111, 530, 30, 852, +-1384, -404, 244, -989, 1667, 319, -65, 1133, +-1775, -221, -411, -1214, 1465, 38, 947, 1124, +-889, 323, -1013, -904, -47, -695, 725, 577, +784, 868, 47, 6, -1334, -954, -804, -777, +1501, 1223, 1214, 1391, -1315, -1628, -1245, -1587, +1126, 1927, 782, 1476, -983, -2020, -121, -1156, +865, 1938, -251, 503, -884, -1404, 213, 169, +937, 577, 136, -679, -785, 381, -779, 810, +540, -1118, 1257, -602, 15, 1534, -1610, 121, +-607, -1589, 1655, 449, 1120, 1365, -1370, -836, +-1507, -1030, 980, 861, 1567, 714, -524, -517, +-1295, -445, 122, 8, 710, 37, 181, 647, +77, 345, -451, -1097, -705, -703, 552, 1249, +1081, 818, -550, -959, -1066, -707, 496, 405, +740, 355, -477, 161, -243, 140, 510, -518, +-123, -637, -677, 595, 344, 892, 809, -395, +-327, -800, -745, -41, 88, 557, 629, 363, +22, -287, -319, -345, -6, 75, 17, 35, +-185, -37, 201, 380, 345, 214, -140, -700, +-473, -425, 117, 586, 172, 631, 73, -100, +248, -602, -79, -645, -687, 325, -157, 1209, +1099, 255, 356, -1287, -1205, -1062, -406, 842, +1001, 1803, 324, -60, -802, -2185, 31, -747, +734, 2054, -477, 1187, -872, -1433, 786, -987, +1166, 456, -891, 280, -1239, 582, 591, 544, +1051, -1312, -75, -1070, -645, 1518, -306, 1070, +124, -1245, 370, -529, 246, 671, -173, -219, +-93, -107, -402, 806, -257, -233, 853, -1003, +695, 318, -901, 817, -922, -410, 509, -313, +852, 534, 1, -85, -377, -862, -357, 224, +-265, 1234, 267, -3, 819, -1469, 276, -463, +-1091, 1424, -980, 858, 1038, -1006, 1418, -980, +-712, 338, -1305, 735, 288, 433, 691, -400, +39, -937, 198, 200, -264, 930, -865, -211, +346, -507, 1054, 426, -389, -40, -701, -830, +355, 593, 200, 1035, -367, -817, 150, -1012, +463, 758, -250, 736, -439, -604, 55, -268, +309, 427, 265, -105, -137, -368, -406, 167, +-61, 467, 379, 100, 77, -612, -238, -564, +135, 725, 104, 896, -410, -661, -246, -891, +717, 435, 483, 549, -761, -263, -658, 107, +433, 219, 673, -777, 33, -446, -242, 1223, +-433, 865, -580, -1296, 669, -1368, 1285, 1124, +-363, 1618, -1768, -770, -250, -1523, 1793, 436, +836, 1092, -1308, -302, -1115, -417, 621, 347, +854, -277, -20, -449, -104, 688, -281, 588, +-704, -766, 34, -679, 1382, 574, 454, 686, +-1571, -297, -931, -582, 1215, 70, 1158, 405, +-540, 22, -1023, -224, -106, 104, 625, -67, +430, -275, -80, 328, -357, 486, -370, -635, +45, -608, 605, 895, 262, 657, -627, -1128, +-337, -606, 591, 1320, -19, 422, -434, -1459, +498, -69, 353, 1479, -901, -352, -385, -1399, +1057, 761, 399, 1259, -758, -1081, -417, -1029, +196, 1139, 376, 801, 378, -965, -144, -629, +-841, 675, -46, 469, 841, -451, 317, -248, +-495, 386, -602, -51, 63, -526, 763, 418, +304, 746, -737, -720, -513, -1008, 690, 959, +482, 1088, -659, -1025, -243, -969, 668, 895, +21, 723, -820, -626, 222, -545, 893, 366, +-301, 544, -848, -272, 245, -661, 678, 329, +-208, 762, -318, -410, 287, -770, -187, 424, +-400, 581, 634, -260, 543, -244, -902, -104, +-594, -37, 940, 458, 458, 209, -742, -667, +-257, -226, 583, 598, -27, 194, -437, -371, +131, -171, 513, 51, 6, 256, -821, 194, +-115, -496, 888, -195, 485, 766, -880, -94, +-761, -880, 731, 522, 760, 804, -394, -989, +-573, -558, 203, 1332, 128, 267, -106, -1560, +320, 12, 193, 1602, -578, -227, -423, -1416, +731, 309, 415, 1095, -533, -385, -153, -605, +99, 389, -222, 22, 371, -277, 590, 491, +-712, -42, -683, -734, 767, 450, 456, 694, +-473, -866, -77, -441, 56, 1062, -205, 226, +250, -1029, 369, -160, -509, 689, -10, 259, +456, -65, -551, -515, -309, -644, 1239, 760, +36, 1204, -1571, -789, 54, -1522, 1598, 583, +-76, 1530, -1235, -298, 152, -1226, 564, 32, +-162, 782, -19, 64, 307, -381, -221, 16, +-545, 202, 213, -258, 648, -200, 89, 379, +-587, 368, -369, -292, 291, -553, 470, -78, +194, 645, -348, 510, -523, -483, -129, -825, +774, -2, 607, 958, -653, 576, -1075, -819, +541, -1059, 1058, 488, -247, 1230, -743, -122, +21, -972, 316, -222, -37, 439, 138, 350, +296, 205, -542, -252, -491, -785, 690, 11, +622, 1087, -626, 362, -633, -1219, 573, -623, +459, 1123, -463, 714, -266, -926, 462, -587, +57, 589, -328, 369, -32, -197, 129, -217, +171, -151, 120, 159, -306, 475, -426, -271, +424, -711, 644, 551, -447, 696, -515, -772, +205, -477, 220, 784, 120, 133, 290, -548, +-517, 258, -704, 74, 775, -538, 926, 400, +-790, 687, -898, -732, 686, -685, 557, 730, +-393, 644, -128, -457, 129, -625, -222, 109, +32, 572, 391, 97, -30, -358, -319, -172, +-62, 0, 93, 127, 193, 369, 113, -41, +-133, -599, -316, -65, -51, 598, 514, 156, +201, -410, -609, -195, -144, 89, 498, 227, +2, 147, -255, -266, 170, -147, 79, 245, +-432, -60, 176, -215, 514, 372, -314, 179, +-373, -668, 270, -136, 180, 695, -99, 153, +44, -416, -241, -242, -19, -135, 521, 429, +-104, 683, -676, -589, 202, -1045, 803, 617, +-304, 1175, -730, -537, 202, -1031, 567, 418, +108, 674, -461, -303, -347, -287, 381, 276, +415, -50, -283, -307, -247, 288, 197, 280, +-107, -419, -11, -79, 464, 446, -181, -328, +-706, -386, 453, 794, 694, 297, -666, -1158, +-428, -183, 690, 1183, 124, 83, -490, -844, +52, 50, 157, 193, -29, -191, 211, 499, +-183, 321, -327, -915, 329, -452, 156, 866, +-202, 536, 166, -357, -80, -578, -596, -361, +452, 505, 926, 982, -721, -332, -990, -1236, +729, 59, 681, 1042, -328, 288, -242, -607, +-229, -537, -214, 146, 718, 568, 557, 145, +-888, -383, -764, -224, 783, 74, 762, 155, +-424, 170, -671, -12, 103, -265, 487, -105, +42, 197, -234, 168, 51, -46, -58, -198, +-251, -88, 373, 259, 432, 133, -602, -427, +-436, -37, 733, 659, 239, -169, -600, -815, +-45, 366, 427, 764, -149, -430, -99, -465, +166, 299, -189, -3, 21, -40, 434, 467, +-368, -246, -377, -738, 553, 379, 283, 724, +-509, -322, -156, -462, 301, 100, 15, 35, +72, 195, 157, 366, -605, -405, -186, -633, +999, 449, 135, 714, -1132, -295, -109, -680, +1003, 39, 76, 579, -597, 204, -159, -433, +67, -431, 286, 333, 445, 581, -492, -307, +-751, -597, 541, 243, 861, 549, -522, -91, +-777, -520, 344, -76, 462, 501, 3, 215, +-229, -445, -322, -283, 41, 335, 501, 222, +70, -132, -568, -85, -50, -107, 443, -84, +21, 316, -313, 205, 108, -381, 55, -273, +-13, 256, 20, 335, -97, -82, 6, -310, +308, -115, -171, 194, -363, 306, 348, -67, +267, -422, -308, -19, -100, 434, 283, 28, +-200, -301, -46, -25, 489, 109, -166, 67, +-630, -3, 356, -95, 697, -4, -436, 79, +-585, 13, 420, -107, 511, -28, -367, 215, +-404, 48, 395, -359, 307, -70, -435, 498, +-140, -5, 518, -431, -43, 72, -601, 158, +220, -73, 769, 197, -487, 62, -829, -538, +608, -76, 870, 736, -687, 151, -732, -758, +496, -283, 501, 580, -269, 447, -157, -234, +-57, -656, -247, -195, 281, 925, 487, 464, +-328, -1072, -688, -570, 189, 1003, 596, 597, +66, -754, -478, -610, -357, 438, 245, 626, +535, -201, -137, -565, -630, 32, 138, 420, +576, 120, -344, -297, -415, -208, 510, 150, +292, 322, -633, 2, -285, -592, 671, 0, +359, 864, -622, -113, -392, -1038, 532, 278, +329, 968, -340, -370, -132, -616, 212, 290, +-115, 130, -62, -72, 447, 338, -13, -200, +-603, -602, 95, 433, 707, 580, -112, -517, +-592, -367, 269, 559, 261, 50, -173, -617, +102, 343, 114, 565, -278, -554, -67, -416, +539, 402, -3, 367, -607, -127, 120, -357, +672, -67, -233, 320, -636, 43, 357, -240, +625, 253, -439, 86, -652, -645, 447, -1, +744, 1024, -425, 37, -885, -1294, 380, -218, +860, 1443, -287, 357, -710, -1423, 4, -281, +405, 1082, 244, 36, -93, -332, -561, -8, +-278, -440, 680, 303, 464, 788, -699, -582, +-721, -766, 609, 652, 741, 636, -604, -586, +-612, -562, 412, 531, 305, 476, -193, -432, +-113, -358, -147, 228, 49, 270, 333, 60, +-157, -310, -342, -243, 207, 353, 278, 266, +-344, -341, -56, -171, 427, 279, -159, 1, +-462, -172, 347, 22, 595, 164, -486, 164, +-515, -466, 431, -292, 466, 859, 47, 225, +-649, -923, -172, -295, 790, 751, 201, 549, +-598, -632, -34, -732, 389, 609, -194, 637, +88, -554, 396, -270, -367, 256, -353, 147, +348, -145, 590, -169, -314, 497, -584, -263, +310, -546, 420, 664, -35, 317, -427, -742, +117, -165, 242, 743, -139, -55, -46, -489, +126, 81, -48, 183, -247, 90, 323, -92, +37, -21, -513, -206, 333, 69, 280, 514, +-488, -368, -228, -366, 569, 471, -29, 24, +-529, -367, 100, 334, 319, 144, -204, -532, +-256, -2, 329, 585, -91, 13, -424, -589, +240, -2, 454, 418, -509, 79, -480, -238, +628, -154, 271, 167, -579, 6, -183, 7, +410, 120, 43, -161, -370, -159, 235, 192, +212, 213, -586, -240, 28, -234, 794, 389, +-209, 170, -812, -710, 226, 100, 851, 1039, +-215, -516, -700, -1137, 171, 785, 667, 1052, +-266, -825, -346, -790, 405, 635, -67, 463, +-186, -375, 333, -43, 135, 88, -526, -359, +160, 194, 631, 536, -327, -287, -477, -615, +392, 362, 555, 442, -491, -313, -391, -224, +588, 203, 242, 127, -527, -166, -106, -115, +631, 128, -203, 172, -326, 33, 167, -422, +118, -143, 84, 710, -114, 118, -241, -806, +81, -41, 338, 745, -217, -130, -148, -473, +136, 288, -165, 117, -13, -389, 233, 243, +128, 284, -584, -372, -117, -169, 589, 409, +-23, -63, -362, -340, 33, 444, -176, -8, +-55, -624, 658, 381, -204, 556, -776, -575, +128, -394, 691, 617, -135, 184, -530, -526, +228, -67, 13, 525, -208, -168, 262, -434, +183, 498, -310, -44, -430, -361, 473, 386, +342, 35, -409, -482, -84, 145, 108, 549, +-62, -254, 235, -579, 58, 386, -313, 339, +-64, -344, 476, -25, -79, 293, -341, -359, +68, -365, 582, 900, -332, 238, -430, -1095, +510, -186, 141, 908, -185, 393, -88, -773, +103, -378, 29, 543, 21, 116, 67, -194, +75, 117, -134, 128, -212, -528, 252, -108, +484, 868, -512, -8, -255, -783, 248, -30, +433, 588, -299, -96, -289, -263, 273, 565, +98, -524, -283, -641, 87, 1173, 294, 213, +-215, -1107, -396, 159, 377, 677, 152, -372, +-134, -322, -203, 687, -114, -68, 338, -959, +-29, 647, -186, 577, -88, -829, 256, 227, +-284, 409, -66, -886, 417, 294, -110, 1079, +-482, -891, 49, -683, 461, 972, 26, 68, +-478, -684, 83, 643, -5, -17, 143, -988, +179, 713, -204, 868, -377, -1134, 354, -411, +94, 1343, -185, -550, 203, -891, -34, 1428, +-481, -70, 175, -1735, 702, 1124, -287, 1232, +-573, -1675, 178, -255, 417, 1508, -167, -689, +44, -800, 127, 1182, -512, 103, 69, -1365, +668, 542, -142, 1131, -367, -989, -29, -411, +138, 894, 52, -286, 325, -522, -114, 769, +-517, 20, 134, -804, 482, 339, -87, 391, +-232, -391, 179, 283, -200, 187, -203, -938, +494, -2, 308, 1631, -478, -397, -578, -1900, +522, 762, 451, 1713, -161, -1019, -371, -1119, +-133, 1090, 202, 282, 247, -821, -34, 374, +-125, 415, -257, -801, 100, 217, 248, 738, +-45, -820, -185, -330, 185, 1332, -124, -396, +-426, -1458, 597, 1174, 180, 959, -381, -1449, +-350, -137, 124, 1017, 486, -473, 36, -236, +-414, 714, -226, -524, 170, -674, 487, 1086, +-197, 423, -354, -1407, 75, 44, 188, 1345, +-133, -597, 163, -776, 97, 843, -448, -64, +93, -493, 308, 485, 104, 123, -466, -668, +40, 11, 509, 1116, -467, -453, -109, -1331, +447, 1010, 67, 1067, -446, -1251, -115, -495, +398, 977, 182, -63, -118, -310, -535, 409, +174, -492, 521, -372, -96, 974, -340, 215, +8, -1201, 96, 99, 51, 1023, 338, -442, +-385, -409, -368, 266, 633, 159, 105, -103, +-655, -181, 231, 79, 587, 359, -725, -194, +-54, -582, 756, 602, -543, 348, -242, -918, +804, 438, -360, 745, -969, -1540, 1191, 198, +603, 2296, -1655, -1586, 54, -2231, 1424, 2848, +-460, 1124, -954, -3017, 756, 125, 285, 2283, +-906, -1016, 583, -1209, 397, 1625, -632, -233, +-248, -1334, 397, 1215, 496, 329, -410, -1107, +-501, 610, 131, 118, 773, -1005, -108, 1306, +-953, 595, 199, -2638, 1138, 890, -636, 2668, +-1002, -2243, 1124, -1622, 560, 2824, -1427, 42, +94, -2452, 1300, 1686, -730, 819, -616, -2486, +859, 1223, -65, 2148, -756, -2828, 798, -1047, +232, 3613, -1222, -495, 558, -3138, 1032, 1772, +-1232, 1558, -311, -1996, 1348, 86, -381, 1567, +-1133, -1402, 990, -800, 429, 2150, -1049, -79, +392, -2162, 466, 843, -778, 1359, 144, -1149, +991, -23, -920, 636, -578, -888, 1180, 117, +15, 1059, -973, -656, 496, -659, 450, 933, +-845, -168, 205, -898, 953, 1034, -842, 765, +-788, -1882, 1277, -201, 392, 2103, -1418, -555, +87, -1506, 1294, 1053, -583, 547, -774, -1194, +638, 286, 346, 947, -436, -555, -52, -481, +130, 143, -231, -13, 421, 760, 300, 206, +-995, -1508, -48, -216, 1218, 1804, -356, 40, +-858, -1419, 538, 130, 60, 659, -173, -422, +527, 429, -395, 538, -653, -1314, 873, -438, +194, 1514, -810, 404, 414, -1035, 342, -498, +-998, -10, 432, 965, 1329, 1047, -1334, -1663, +-1105, -1540, 1816, 2193, 695, 1341, -2003, -2192, +-23, -763, 1725, 1704, -623, 90, -1013, -888, +804, 298, 477, 38, -750, -137, -232, 443, +579, -565, 277, -163, -345, 1206, -666, -490, +265, -1660, 1169, 1360, -555, 1613, -1236, -1959, +665, -1161, 1164, 2008, -757, 715, -1054, -1774, +1069, -202, 498, 1183, -1052, -104, -75, -484, +926, 93, -145, 67, -860, -32, 228, -9, +931, 202, -427, 97, -949, -625, 589, -124, +1124, 1214, -1077, -141, -904, -1636, 1165, 573, +839, 1863, -1075, -1106, -918, -1889, 871, 1729, +1079, 1532, -593, -2035, -1311, -910, 368, 1594, +1562, 603, -260, -700, -1735, -701, 281, -377, +1767, 1103, -283, 1362, -1571, -1677, 101, -1859, +1135, 1922, 623, 1955, -930, -1707, -1360, -1754, +712, 1121, 2244, 1274, -941, -211, -2483, -805, +1164, -674, 2280, 541, -1554, 1129, -1400, -503, +1749, -934, 307, 512, -1601, 334, 361, -511, +1451, 186, -635, 791, -1150, -618, 381, -1159, +773, 862, 360, 1352, -771, -819, -816, -1350, +940, 757, 591, 1021, -966, -899, 36, -259, +1041, 1149, -1117, -655, -894, -1442, 2095, 1431, +516, 1553, -2541, -1669, -47, -1621, 2375, 1572, +-575, 1432, -1622, -1254, 1156, -919, 631, 739, +-1611, 480, 93, -565, 2120, 31, -680, 679, +-2416, -598, 1140, -824, 2267, 1105, -1523, 719, +-1723, -1457, 2085, -157, 590, 1637, -2639, -1042, +1023, -1316, 2572, 2398, -2262, 609, -1970, -3357, +2679, -12, 1114, 3930, -2359, -427, -3, -4046, +1134, 779, -598, 3582, 182, -862, 766, -2829, +-1254, 715, -438, 2156, 1756, -580, -87, -1656, +-1620, 528, 403, 1395, 1189, -695, -248, -1173, +-760, 938, -427, 857, 700, -1031, 1293, -454, +-939, 795, -2091, 181, 1541, -271, 2203, -275, +-1877, -196, -1882, 669, 2057, 358, 1075, -1052, +-1946, -318, -55, 1316, 1589, 233, -868, -1493, +-1174, -129, 1654, 1514, 507, 172, -1815, -1505, +-100, -341, 1654, 1520, -20, 471, -1457, -1340, +13, -727, 1206, 987, 187, 1214, -1202, -695, +-263, -1688, 1185, 485, 273, 1920, -1262, -226, +-69, -1871, 1224, -140, -326, 1707, -978, 379, +699, -1332, 525, -436, -855, 600, -75, 689, +723, 42, -161, -1046, -603, -291, 354, 1132, +417, 495, -381, -1194, -447, -538, 358, 1136, +848, 517, -727, -678, -1105, -989, 1124, 315, +1206, 1848, -1457, -298, -1144, -2627, 1830, 462, +575, 3063, -1686, -579, -82, -3148, 1505, 707, +-568, 2597, -904, -592, 900, -1505, 172, -27, +-770, 457, 430, 821, 381, 330, -945, -1552, +437, -624, 992, 1821, -1275, 514, -579, -1316, +1935, -500, -215, 398, -2111, 633, 888, 662, +2157, -834, -1484, -1703, -1968, 1201, 1691, 2256, +1806, -1335, -1585, -2372, -1706, 1120, 1340, 2220, +1525, -741, -1057, -1724, -1172, 152, 786, 1182, +610, 343, -581, -622, 108, -491, 321, -119, +-795, 501, 12, 818, 1168, -352, -306, -1374, +-1170, 159, 314, 1623, 985, 11, 54, -1400, +-878, -234, -920, 798, 1372, 501, 1660, -44, +-2166, -765, -2095, -420, 2861, 618, 2194, 607, +-3327, 58, -1634, -680, 2955, -998, 854, 593, +-1930, 1933, -58, -350, 544, -2539, -412, -35, +365, 2501, 922, 687, -660, -1822, -1495, -1663, +396, 760, 2094, 2758, 364, 243, -2910, -3390, +-994, -1195, 3625, 3376, 1271, 2120, -4037, -3022, +-1078, -2515, 3902, 2223, 731, 2367, -3330, -1075, +-455, -2000, 2564, 50, 322, 1616, -1632, 521, +-547, -1454, 805, -492, 1200, 1633, -383, -3, +-1926, -2188, 207, 592, 2726, 3161, -255, -1169, +-3421, -3949, 318, 1245, 3890, 4247, -122, -545, +-4141, -4044, -408, -595, 4122, 3121, 1259, 1994, +-3823, -1728, -2201, -3329, 3189, 314, 3028, 4270, +-2322, 645, -3500, -4529, 1312, -1014, 3471, 4190, +-280, 923, -2954, -3640, -855, -573, 2305, 3276, +1895, 136, -1752, -3032, -2751, -18, 1333, 2749, +3413, 568, -1104, -2374, -3731, -1556, 806, 1702, +3692, 2458, -283, -531, -3374, -2830, -252, -1044, +2457, 2418, 1020, 2594, -1285, -1263, -1761, -3558, +99, -350, 2256, 3609, 795, 1927, -2333, -2807, +-1262, -2949, 2097, 1470, 1159, 3269, -1495, -293, +-803, -2902, 752, -321, 461, 2262, 118, 190, +-589, -1694, -914, 324, 1270, 1583, 1435, -802, +-2098, -1855, -1773, 915, 2664, 1929, 1827, -224, +-2289, -1488, -1929, -1135, 1079, 407, 1962, 2659, +709, 1132, -1784, -3710, -2651, -2749, 1489, 3897, +4065, 3965, -1060, -3313, -4535, -4164, 611, 2004, +3943, 3344, -270, -294, -2354, -2063, -186, -976, +497, 453, 539, 1660, 1265, 1055, -799, -1763, +-2691, -2031, 1117, 1142, 3491, 2652, -1447, -157, +-3426, -3090, 1392, -546, 2773, 2967, -971, 919, +-1562, -2189, 84, -1013, 149, 820, 977, 916, +1121, 827, -1676, -702, -2182, -2155, 1906, 157, +2551, 2923, -1321, 550, -2353, -2864, 273, -1157, +1662, 1845, 694, 1509, -604, -165, -1217, -1511, +-396, -1598, 1074, 1220, 874, 2672, -268, -673, +-558, -2591, -980, -74, -342, 1495, 2050, 608, +1720, 394, -2764, -941, -2969, -2280, 2920, 928, +3607, 3561, -2524, -664, -3402, -3854, 1767, 375, +2318, 3040, -697, -106, -912, -1580, -322, 164, +-374, -235, 980, -429, 1262, 1989, -1154, 559, +-1715, -2995, 927, -598, 1757, 3071, -396, 600, +-1763, -2447, 181, -467, 1487, 1437, -263, 148, +-1161, -351, 793, 256, 825, -559, -1670, -397, +-460, 752, 2410, 562, 291, -614, -2699, -497, +-373, 390, 2321, 67, 702, -193, -1446, 359, +-994, 460, 335, -768, 1146, -1026, 310, 929, +-749, 1478, -325, -529, -130, -1602, -169, -259, +1053, 1155, 849, 1134, -1483, -229, -1456, -1624, +1312, -761, 1579, 1229, -611, 1556, -1100, -90, +-297, -1745, 322, -1484, 919, 1360, 388, 2780, +-1026, -641, -625, -3124, 707, -193, 136, 2455, +-34, 840, 595, -1259, -408, -960, -1181, 77, +370, 627, 1347, 471, -126, 56, -808, -313, +-56, -763, -263, -135, -55, 1043, 1331, 512, +480, -840, -1776, -498, -1034, 457, 1278, -125, +1389, -98, -23, 1108, -1277, -106, -1359, -1799, +494, -150, 2419, 2022, 503, 602, -2605, -1657, +-1364, -901, 1929, 756, 1722, 943, -778, 250, +-1541, -660, -258, -973, 1015, 69, 740, 1397, +-502, 504, -627, -1548, 262, -815, 214, 1559, +-352, 761, 38, -1459, 645, -483, 29, 1116, +-640, 341, -629, -482, 422, -744, 1214, -131, +97, 1411, -1438, 687, -623, -2075, 1078, -1079, +798, 2472, -102, 1022, -694, -2123, -893, -792, +272, 1306, 1501, 396, 175, -268, -1477, 1, +-302, -745, 816, -69, 140, 1327, -19, -185, +272, -1358, -595, 537, -451, 1080, 520, -771, +349, -731, 80, 710, 10, 523, -678, -354, +-648, -374, 998, -259, 1193, 306, -845, 833, +-1340, -135, 215, -1201, 1121, -123, 522, 1305, +-708, 287, -915, -1099, 192, -254, 979, 706, +29, -11, -573, -210, -104, 258, 31, -165, +213, -316, 215, 322, -280, 131, -271, -317, +418, 176, 383, 358, -858, -489, -387, -526, +1074, 676, 685, 718, -1164, -610, -1072, -738, +1020, 215, 1294, 592, -618, 209, -1333, -237, +350, -373, 908, -373, -202, 329, -267, 884, +312, -180, -402, -910, -561, -94, 892, 445, +712, 248, -1029, 436, -608, -312, 683, -1297, +549, 322, -409, 1630, -275, -227, 101, -1329, +92, 189, 65, 498, -117, -300, 20, 528, +137, 521, -57, -1268, -301, -734, 190, 1322, +302, 897, -178, -698, -243, -887, 34, -370, +243, 778, 170, 1282, -392, -526, -275, -1584, +512, 85, 471, 1206, -696, 408, -510, -395, +650, -671, 439, -676, -242, 751, -352, 1554, +-237, -635, 37, -1981, 724, 360, 403, 2012, +-1020, -205, -683, -1613, 732, 187, 986, 1009, +-416, -277, -740, -411, 29, 437, 41, -113, +238, -526, 705, 495, 26, 519, -1502, -743, +-322, -580, 1600, 1107, 788, 542, -1170, -1496, +-898, -431, 271, 1659, 529, 377, 835, -1571, +86, -411, -1546, 1254, -802, 458, 1671, -815, +1228, -434, -1155, 496, -1342, 150, 439, -267, +1125, 234, 7, 149, -608, -478, -82, -255, +48, 603, -80, 404, 260, -644, 245, -355, +-220, 604, -251, 70, -2, -552, -27, 293, +265, 608, 406, -571, -401, -737, -617, 577, +344, 797, 504, -214, -207, -698, -42, -325, +-29, 403, -363, 642, 183, 173, 487, -613, +-313, -770, -165, 167, 432, 1167, -369, 489, +-669, -1185, 741, -1005, 1101, 841, -756, 1054, +-1475, -304, 320, -531, 1504, -208, 503, -361, +-1256, 539, -1043, 1082, 604, -469, 992, -1349, +295, 50, -481, 1155, -806, 358, -474, -534, +883, -654, 1265, -127, -431, 712, -1490, 493, +-352, -502, 1130, -420, 849, 65, -217, 192, +-910, 336, -704, -5, 437, -499, 1066, -64, +515, 513, -817, -44, -1520, -456, 135, 280, +2166, 303, 505, -331, -2114, -212, -877, 184, +1481, 169, 837, 49, -637, 20, -519, -303, +-33, -343, 96, 417, 435, 853, -4, -492, +-440, -1272, 259, 575, 231, 1265, -735, -556, +47, -861, 1022, 451, -115, 285, -963, -435, +46, 258, 395, 506, 239, -554, 328, -623, +-473, 442, -909, 796, 427, -105, 1299, -886, +-329, -166, -1269, 707, 178, 281, 931, -380, +-42, -122, -509, 86, -74, -321, 258, 103, +88, 766, -111, -42, -199, -983, 116, -284, +376, 892, -166, 711, -489, -522, 18, -1159, +628, 255, 217, 1267, -623, -248, -476, -889, +419, 354, 749, 331, -209, -535, -809, 134, +65, 622, 570, -299, 115, -491, -325, 99, +-57, 185, -81, 288, 111, 159, 265, -525, +-222, -496, -150, 508, 366, 724, -138, -311, +-672, -763, 717, 140, 727, 533, -1050, -62, +-680, -154, 1012, 139, 569, -253, -637, -266, +-335, 503, -42, 331, 169, -504, 692, -340, +-92, 366, -976, 128, 21, 14, 828, 116, +-6, -497, -333, -232, 77, 878, -329, 249, +-109, -1128, 694, -120, 199, 1124, -603, -83, +-343, -736, 135, 82, 410, 208, 431, 121, +-291, 299, -876, -417, 47, -645, 871, 713, +371, 682, -654, -788, -535, -560, 191, 689, +433, 365, 194, -520, -71, -103, -326, 230, +-399, -32, 208, 130, 693, -85, 32, -448, +-627, 341, -181, 734, 169, -560, 162, -1082, +329, 657, 253, 1510, -872, -689, -578, -1759, +913, 539, 884, 1733, -614, -213, -871, -1524, +119, -16, 485, 1065, 396, 66, -5, -439, +-545, 1, -451, -99, 333, -110, 658, 356, +105, 151, -465, -242, -635, -138, 134, -28, +898, -24, 236, 243, -813, 338, -423, -351, +444, -553, 378, 242, -28, 481, -86, 92, +-270, -112, -266, -503, 347, -432, 462, 802, +-173, 960, -428, -923, -92, -1180, 132, 846, +380, 883, 137, -494, -359, -211, -470, -109, +281, -427, 580, 639, -108, 851, -557, -1021, +62, -891, 387, 1147, -125, 597, -260, -947, +270, -302, 257, 612, -360, 141, -399, -236, +263, -235, 688, -45, -158, 452, -679, 175, +-239, -500, 584, -361, 521, 446, -263, 499, +-590, -321, -196, -392, 451, -46, 520, 265, +-98, 347, -576, -108, -428, -346, 547, -272, +770, 212, -459, 764, -876, -151, 544, -1053, +641, 155, -865, 1026, -93, -217, 1217, -646, +-454, 263, -1494, -15, 857, -113, 1438, 635, +-906, -159, -997, -1043, 535, 432, 479, 1152, +-57, -629, 14, -883, -369, 532, -252, 468, +548, -175, 148, -107, -293, -168, -34, -242, +-64, 454, -71, 502, 438, -628, 65, -558, +-781, 593, 231, 481, 808, -461, -482, -247, +-693, 335, 586, -154, 519, -171, -436, 467, +-362, 120, 45, -656, 334, -162, 355, 669, +-315, 170, -640, -456, 346, -136, 553, 119, +-228, 73, -281, 182, 31, 2, -46, -295, +203, -50, 210, 137, -406, 42, 2, 220, +382, 40, -451, -682, -166, -98, 917, 1044, +-127, 27, -1203, -1096, 348, 131, 1154, 924, +-411, -430, -813, -566, 265, 761, 411, 189, +-126, -1026, -6, 112, -21, 1060, -175, -284, +30, -801, 140, 314, 132, 374, -87, -353, +-302, 108, 113, 437, 356, -457, -255, -534, +-252, 502, 392, 629, 125, -308, -404, -541, +-220, -86, 371, 295, 432, 481, -180, 25, +-766, -640, -19, -376, 977, 609, 135, 489, +-864, -327, -132, -300, 439, -126, -79, -84, +314, 562, 256, 498, -935, -845, -424, -774, +1291, 912, 384, 813, -1153, -771, -162, -664, +591, 572, -98, 337, 58, -254, 382, -63, +-611, -130, -505, 11, 887, 459, 399, -43, +-869, -838, -103, 135, 701, 1251, -318, -292, +-420, -1445, 548, 325, 256, 1356, -568, -176, +-161, -1020, 357, -17, 49, 477, 15, 145, +57, 122, -247, -109, -297, -679, 341, -6, +475, 960, -106, 156, -633, -946, -274, -215, +701, 612, 573, 172, -582, -133, -625, -58, +177, -322, 628, -144, 176, 742, -441, 288, +-540, -1094, 229, -286, 862, 1370, -188, 125, +-971, -1497, 174, 88, 951, 1394, -196, -137, +-677, -1145, -25, 16, 377, 760, 372, 190, +-70, -223, -727, -493, -184, -213, 922, 607, +380, 479, -868, -437, -410, -601, 474, 147, +385, 422, 62, 214, -292, -41, -492, -550, +100, -301, 767, 585, 38, 659, -789, -435, +-40, -947, 530, 319, 51, 989, -246, -335, +-29, -745, 73, 454, 46, 304, -58, -563, +-139, 104, 186, 583, 301, -287, -391, -495, +-451, 234, 569, 350, 409, -70, -555, -133, +-186, -90, 318, -23, -110, 68, -1, 33, +439, 293, -281, -65, -725, -771, 525, 129, +785, 1103, -629, -153, -604, -1189, 593, 213, +232, 885, -453, -236, 232, -302, 273, 163, +-696, -328, -84, 54, 1028, 628, -60, -158, +-1237, -556, 183, -41, 1225, 501, -286, 337, +-967, -677, 300, -326, 486, 866, -109, -50, +-55, -696, -86, 294, -292, 308, 228, -200, +447, 23, -121, -47, -634, -279, -22, 208, +813, 595, 20, -204, -804, -1057, -12, 178, +726, 1475, -48, -213, -557, -1537, -38, 128, +601, 1267, 54, 116, -702, -833, -47, -523, +775, 570, 77, 874, -757, -671, -174, -827, +648, 859, 355, 400, -587, -686, -457, -146, +627, 365, 189, 239, -380, -280, 44, -179, +44, 211, -125, -206, 122, 224, 252, 570, +-346, -969, -144, -374, 292, 1336, 130, -171, +-189, -954, -183, 371, 232, 471, -64, -350, +58, -307, 172, 622, -464, 24, -14, -820, +559, 323, 116, 757, -832, -573, -21, -539, +864, 834, -53, 68, -572, -777, -287, 183, +602, 444, 335, 263, -376, -530, -440, -656, +-74, 621, 901, 807, 120, -241, -1064, -1145, +-221, -43, 1084, 1270, 382, 177, -1168, -971, +-148, -308, 619, 470, 369, 408, -280, -11, +-570, -408, 158, -242, 457, 241, 189, 372, +-577, -68, -231, -435, 534, 83, 226, 340, +-506, -51, -92, -428, 395, 205, -110, 583, +-103, -586, 70, -448, 77, 761, -215, 190, +-31, -732, 411, 161, -56, 501, -552, -442, +121, -189, 629, 452, -289, 98, -300, -360, +82, -109, 62, 113, 147, 210, 135, 236, +-409, -471, -54, -271, 395, 394, -60, 288, +-255, -167, 213, -299, 117, 78, -457, -42, +162, 223, 412, 374, -97, -732, -467, -204, +77, 877, 467, -231, -172, -479, -235, 321, +270, 152, -71, -299, -364, 0, 481, 354, +175, -283, -556, -191, 61, 493, 275, -98, +-46, -521, -120, 197, 79, 618, -11, -257, +-107, -629, 22, 308, 116, 337, -15, -76, +-130, -47, 197, -117, -310, -254, -44, 132, +659, 687, -412, -246, -310, -823, 168, 360, +311, 438, -80, -139, -180, 18, 54, -183, +-52, -331, 24, 356, 293, 492, -154, -376, +-456, -450, 499, 311, 156, 273, -368, -374, +-187, 261, 482, 241, 79, -825, -547, 301, +216, 693, 222, -557, -260, -206, 134, 294, +100, 155, -197, -344, -239, -33, 170, 386, +614, -36, -288, -171, -967, -416, 417, 337, +962, 623, -271, -341, -973, -596, 158, -115, +826, 918, -211, 161, -394, -886, 288, 11, +-224, 229, -156, 291, 669, 157, -39, -477, +-788, -463, 320, 643, 647, 619, -659, -959, +57, -236, 400, 826, -183, -90, -333, -450, +255, 44, 358, 335, -361, -201, -77, 107, +153, 136, -198, -836, 320, 693, 20, 805, +-418, -1316, 39, -141, 375, 1042, -218, -215, +-103, -448, 270, 166, -481, 130, 107, -289, +641, 289, -445, 306, -623, -774, 592, 110, +473, 815, -511, -662, -378, -317, 373, 847, +122, -202, 215, -798, -463, 605, -6, 550, +265, -843, 20, -9, -39, 602, -82, -465, +261, 82, -282, 449, -166, -687, 552, -10, +85, 736, -517, -234, -98, -684, 352, 537, +70, 446, 64, -984, -148, 430, -592, 797, +440, -1288, 595, 127, -387, 1376, -755, -1087, +449, -674, 413, 1439, -228, -243, -250, -1109, +107, 824, -334, 507, 453, -1129, 448, 330, +-963, 1072, -220, -1317, 1005, -429, 76, 1968, +-944, -616, 312, -1850, 488, 1540, -521, 964, +231, -1827, 491, 226, -752, 1447, -164, -1243, +1023, -690, -126, 1939, -1029, -383, 661, -1893, +547, 1398, -635, 978, -336, -1732, 805, 231, +-80, 1355, -585, -1170, 323, -562, -25, 1534, +1, -393, 142, -1105, -174, 1090, -370, -24, +340, -1016, 291, 1062, -595, 477, 145, -1632, +219, 263, -402, 1530, 69, -824, 449, -910, +-183, 1096, -727, -29, 488, -1054, 835, 1181, +-985, 300, -283, -1765, 941, 823, -103, 1283, +-591, -1438, 401, -327, 295, 1380, -616, -424, +371, -1169, 496, 1161, -643, 524, -270, -1534, +935, 561, -178, 1060, -722, -1520, 730, 158, +-130, 1750, -602, -1443, 792, -1094, 1, 1963, +-752, 160, 128, -1655, 619, 605, -536, 872, +-41, -1168, 584, 288, -966, 1205, -98, -1472, +1374, -378, -605, 1856, -1328, -926, 1216, -916, +526, 1581, -1410, -623, 602, -1102, 736, 1493, +-998, 231, -47, -1528, 915, 640, -493, 724, +-189, -1217, 855, 881, -926, 765, -248, -2266, +1444, 606, -128, 2441, -1626, -1904, 985, -1538, +1010, 2686, -1462, -249, 212, -2441, 1409, 2146, +-1202, 1066, -1040, -2999, 1786, 358, 388, 2933, +-1655, -1518, 14, -1942, 974, 2001, -143, 207, +-457, -1025, -5, 776, 118, -589, -61, -353, +110, 1468, -490, -494, 289, -1821, 713, 1616, +-1075, 1523, -427, -2652, 1266, -288, 187, 2413, +-1141, -699, 65, -1305, 871, 1156, -470, -266, +47, -1056, 407, 1985, -411, 115, -419, -2910, +1014, 1193, 110, 2565, -1165, -2041, 731, -1480, +783, 2409, -1292, -75, -92, -2136, 1572, 1589, +-546, 1098, -1143, -2126, 467, -247, 780, 2222, +-485, -707, 67, -1768, -135, 1759, -636, 450, +439, -1948, 838, 611, -571, 1547, -894, -891, +406, -1196, 404, 862, -194, 591, 364, -379, +-416, 142, -961, -597, 844, -514, 1244, 1595, +-1084, 359, -1245, -2225, 1482, 416, 574, 1924, +-1284, -1154, 72, -996, 1289, 1476, -695, -2, +-851, -1399, 1018, 761, 366, 860, -565, -884, +-66, -182, 241, 411, -338, -389, 399, 433, +565, 617, -918, -1231, -356, -429, 787, 1522, +144, 99, -341, -1195, -232, 120, -171, 414, +427, -85, 52, 596, -453, -425, 78, -1157, +268, 992, -497, 1040, 9, -1061, 612, -779, +-207, 945, -783, 311, 367, -590, 820, 78, +-737, 145, -248, -66, 520, 45, 113, -289, +-430, 232, 157, 697, 398, -783, -211, -979, +-110, 1367, -69, 1000, 421, -1775, 154, -687, +-409, 1722, -107, 403, 260, -1578, 259, -95, +-116, 1499, -215, -259, -179, -1431, 173, 414, +420, 1622, -156, -553, -714, -2042, 165, 1074, +665, 2043, -284, -1551, -506, -1780, 168, 2024, +145, 1334, -32, -2554, 29, -590, -381, 2789, +54, -152, 750, -2589, -625, 560, -848, 2162, +1198, -724, 927, -1604, -1770, 901, -860, 695, +2252, -893, 838, 376, -2302, 602, -981, -1327, +2552, 38, 984, 1840, -2376, -806, -924, -1855, +2269, 1391, 896, 1646, -2239, -1689, -316, -1514, +1866, 1946, -332, 1064, -1102, -1649, 847, -527, +113, 688, -1381, 253, 1210, 333, 1342, 141, +-2519, -1388, -883, -535, 2986, 2266, 300, 625, +-2890, -2485, 117, -469, 2041, 1983, -412, 148, +-911, -1116, 499, 436, -337, -54, -325, -775, +1035, 820, 343, 728, -1390, -642, -109, -729, +1146, -65, 124, 771, -728, 800, 117, -878, +370, -1027, -223, 987, -307, 534, 637, -1085, +552, 672, -1133, 961, -467, -2042, 1160, -487, +617, 2755, -1227, 124, -265, -2763, 844, 147, +-147, 2155, -500, -272, 491, -1308, 221, 347, +-687, 538, -427, -276, 600, -263, 887, 121, +-524, 800, -1643, -398, 556, -1478, 2053, 844, +-808, 1954, -1976, -1128, 997, -2343, 1389, 1333, +-1018, 2493, -413, -1345, 599, -2420, -415, 896, +300, 2589, 771, -396, -953, -2780, -844, -288, +1542, 3034, 845, 1120, -1735, -3631, -623, -1351, +1345, 3925, 886, 1013, -778, -3485, -1255, -627, +232, 2588, 1794, 390, -125, -1574, -2070, -385, +317, 710, 2056, 678, -998, -158, -1697, -1172, +1715, -83, 981, 1777, -2406, 10, -148, -2082, +2486, 70, -608, 1879, -2089, 217, 898, -1282, +1424, -861, -1104, 432, -395, 1721, 835, 408, +-434, -2612, -330, -841, 774, 3035, 58, 969, +-701, -2925, 120, -984, 388, 2563, 58, 738, +63, -1859, -333, -704, -171, 989, 537, 1209, +301, -401, -653, -2113, -265, 167, 802, 3059, +154, -134, -851, -3796, -267, 187, 1172, 3987, +267, -308, -1580, -3260, -281, 161, 1810, 1894, +307, 326, -2262, -403, 92, -884, 2086, -748, +-663, 1223, -1638, 1429, 1109, -1210, 1050, -1517, +-1534, 845, -531, 1132, 1562, -26, 599, -695, +-1593, -958, -1029, 410, 1792, 1813, 1444, -224, +-1844, -2553, -1479, 313, 1611, 2949, 1466, -622, +-1213, -2647, -1106, 563, 855, 2059, 468, -478, +-52, -1150, 23, 491, -800, -276, -92, -341, +1410, 1619, 111, 374, -2014, -2784, 208, -666, +1973, 3519, -271, 1014, -1702, -3509, 130, -1509, +836, 3024, 211, 1820, 399, -2240, -1140, -1489, +-1479, 1035, 1828, 876, 2322, 140, -2513, -77, +-2486, -760, 2544, -923, 2157, 993, -2135, 1904, +-1402, -877, 1291, -2422, 804, 251, -632, 2653, +-31, 531, 188, -2381, -362, -1298, -307, 1404, +914, 2411, 1030, -498, -1709, -3141, -1691, -603, +2715, 3283, 2194, 1873, -3665, -3163, -1990, -2718, +3870, 2309, 1754, 3096, -3565, -855, -1403, -3328, +2710, -579, 919, 3109, -1373, 1556, -770, -2513, +-268, -1936, 1311, 1859, 913, 1576, -1870, -1285, +-1003, -796, 2239, 1102, 559, -33, -2588, -1246, +-8, 363, 2773, 1881, -289, 45, -3028, -2666, +167, -910, 3324, 3179, 379, 2093, -3359, -3070, +-1287, -3255, 3368, 2448, 2158, 4047, -2921, -1575, +-2456, -3982, 1876, 501, 2622, 3435, -504, 284, +-2274, -2771, -953, -571, 1824, 2131, 2207, 449, +-1170, -1781, -3193, -305, 552, 1633, 3807, 478, +26, -1653, -4284, -1181, -523, 1558, 4435, 1920, +785, -1025, -4266, -2410, -1113, -46, 3573, 2327, +1293, 1355, -2561, -1433, -1440, -2670, 1157, 244, +1437, 3304, 96, 927, -1149, -2830, -1249, -1806, +762, 1791, 2028, 2197, -440, -545, -2256, -1877, +262, -581, 2193, 1555, -17, 1166, -2065, -1577, +-39, -979, 2177, 2185, 166, 159, -2220, -2848, +-416, 773, 2375, 2789, 676, -834, -1894, -2254, +-1090, 62, 917, 1140, 1409, 1021, 654, 438, +-1610, -2142, -2464, -2118, 1536, 2730, 3805, 3286, +-1087, -2753, -4653, -3645, 374, 1939, 4531, 3252, +306, -546, -3681, -2652, -1037, -729, 2175, 1919, +1759, 1566, -860, -1149, -2278, -1828, -163, 481, +2427, 1526, 825, 326, -2243, -626, -979, -1285, +1551, -224, 1017, 2006, -366, 1098, -988, -2115, +-631, -1884, 655, 1817, 1704, 2252, -124, -906, +-2179, -1982, -406, -328, 1908, 1088, 1248, 1585, +-1242, -162, -1684, -2272, 312, -531, 1708, 1838, +450, 995, -1346, -761, -776, -1304, 755, -224, +397, 881, -326, 680, 357, -58, 215, -677, +-1506, -741, -416, -119, 2290, 1495, 679, 1206, +-2470, -2177, -1237, -1971, 2080, 2329, 1819, 2491, +-1435, -2205, -2263, -2508, 653, 2031, 2567, 1887, +66, -1315, -2470, -803, -596, 347, 1912, -417, +1059, 740, -652, 1734, -1382, -1499, -806, -2708, +1541, 1742, 2195, 3265, -1248, -1422, -2899, -3101, +683, 969, 2778, 1825, -157, -417, -1716, -151, +37, 145, 115, -1282, -375, -498, 987, 1918, +1334, 1049, -1476, -1706, -2320, -1454, 875, 769, +2694, 1025, 265, 325, -2333, -13, -1326, -1007, +1022, -1033, 1761, 689, 330, 1529, -1408, 390, +-943, -1195, 141, -1469, 774, 30, 1098, 1999, +114, 1463, -1528, -1468, -1233, -2401, 1217, 329, +1682, 2208, 53, 1050, -1294, -875, -1320, -1770, +537, -847, 1741, 1428, 524, 2522, -1226, -261, +-879, -3286, -3, -1108, 386, 2830, 1519, 2231, +372, -1792, -2171, -2515, -1215, 680, 2003, 1821, +1152, 115, -1034, -908, -320, -281, -209, 87, +-835, -375, 566, 441, 1849, 1003, -134, -595, +-2172, -1273, -945, 249, 1463, 1252, 1965, -153, +-215, -731, -2286, 199, -1005, 0, 1597, -319, +1695, 543, -310, 543, -1379, -680, -1031, -420, +502, 167, 1816, 416, 509, 682, -1556, -428, +-1230, -1288, 848, 372, 1350, 1925, -18, -374, +-861, -2188, -503, 387, 465, 2227, 423, -281, +-298, -2115, -135, 91, 658, 1636, -59, 395, +-1409, -969, 25, -1145, 1756, 303, 421, 1578, +-1691, 294, -935, -1713, 1008, -818, 927, 1435, +81, 737, -525, -602, -1121, -546, -217, -402, +1582, 394, 972, 962, -1617, -374, -1164, -1195, +1137, 807, 940, 1025, -627, -1588, -455, -378, +508, 2125, -101, -49, -363, -2060, 135, 142, +453, 1413, 305, 93, -494, -247, -692, -305, +369, -720, 799, 228, -3, 1265, -510, 248, +-254, -1230, 32, -703, 237, 575, 336, 933, +64, 293, -401, -932, -410, -792, 100, 661, +388, 677, 357, -617, -83, 21, -637, 692, +-417, -947, 352, -894, 699, 1274, 388, 1182, +-714, -971, -1014, -1442, 70, 359, 1280, 1125, +842, 335, -1054, -493, -1496, -714, 522, -66, +1425, 607, 131, 255, -745, -29, -305, 177, +-144, -812, -138, -589, 949, 1240, 923, 896, +-1147, -908, -1540, -879, 883, 297, 1488, 378, +-335, 527, -602, 375, -203, -1133, -566, -901, +313, 1092, 1429, 1252, 132, -689, -1942, -1187, +-374, 33, 1493, 777, 355, 560, -549, -339, +-210, -937, -109, -175, -318, 1070, 250, 424, +795, -932, -36, -541, -794, 432, -422, 675, +378, 5, 669, -827, 128, -111, -390, 578, +-439, 75, -210, -58, 396, 106, 766, -428, +-91, -375, -745, 765, -233, 579, 228, -640, +337, -586, 431, 190, 61, 417, -806, 455, +-699, 69, 732, -1080, 961, -375, 56, 1253, +-772, 429, -995, -742, 94, -512, 1482, 154, +835, 444, -1385, 301, -1505, -425, 828, -484, +1387, 676, -76, 22, -785, -928, -206, 535, +-259, 918, 59, -606, 1014, -934, 263, 182, +-877, 890, -802, 305, 316, -674, 850, -761, +625, 499, -648, 776, -1131, -493, 176, -266, +1226, 712, 9, -457, -740, -1128, 221, 1198, +90, 1370, -577, -1430, 169, -1256, 911, 1070, +169, 993, -984, -444, -720, -513, 574, -76, +1135, 81, 146, 313, -1147, 82, -726, -184, +638, 62, 830, -59, 28, -397, -356, 198, +-605, 643, -269, -122, 587, -627, 600, -108, +-12, 147, -474, 351, -641, 550, -241, -452, +839, -1240, 1339, 369, -569, 1530, -1991, -292, +-339, -1136, 2100, -11, 1143, 364, -1266, 407, +-1532, 285, -2, -642, 1302, -603, 1082, 701, +-485, 518, -1456, -576, -440, -104, 1029, 259, +983, -260, -121, 171, -666, 496, -1054, -623, +54, -474, 1563, 1005, 713, 336, -1300, -1124, +-1232, -262, 462, 899, 1270, 473, 403, -395, +-912, -967, -948, -6, 549, 1282, 851, 201, +-417, -1235, -303, -229, 576, 903, -365, -163, +-804, -289, 802, 745, 734, -488, -748, -1136, +-338, 998, 425, 1161, -272, -1170, -167, -784, +914, 999, 108, 183, -1195, -670, -218, 339, +931, 470, 507, -576, -456, -517, -500, 494, +-154, 690, 388, 11, 432, -937, -262, -661, +-154, 1322, 51, 989, -333, -1470, 100, -900, +537, 1440, -63, 402, -475, -1289, 212, 496, +-83, 907, -599, -1262, 815, -491, 1111, 1615, +-1316, 279, -1585, -1629, 1307, -179, 1674, 1253, +-654, 214, -1443, -718, -190, -420, 891, 395, +853, 534, -197, -406, -1128, -477, -244, 535, +982, 369, 308, -820, -468, -158, -202, 894, +86, -22, -61, -595, 297, -32, -49, 119, +-267, 74, 300, 624, 141, -267, -688, -1270, +41, 599, 1000, 1422, -284, -667, -1001, -1164, +409, 450, 820, 776, -570, -57, -510, -422, +558, -354, 379, 324, -524, 610, -318, -414, +169, -637, 522, 600, 174, 467, -715, -742, +-431, -205, 786, 791, 449, -98, -694, -746, +-182, 313, 516, 583, -177, -213, -414, -697, +597, 57, 129, 828, -400, 89, -24, -707, +-232, -410, 9, 440, 1064, 693, -51, -16, +-1651, -835, 92, -410, 1610, 786, -64, 494, +-935, -303, 6, -323, -126, -478, 51, 214, +1036, 1039, -85, -84, -1417, -1244, 174, 157, +866, 1103, -96, -567, 179, -540, -154, 1078, +-1086, -153, 301, -1227, 1482, 491, -343, 944, +-1224, -302, 278, -241, 445, -253, -122, -722, +324, 993, 76, 1457, -788, -1475, -79, -1738, +730, 1511, 19, 1411, -3, -1175, -176, -525, +-724, 452, 294, -429, 1083, 288, -169, 968, +-1098, -663, -34, -1063, 815, 715, 98, 654, +-347, -443, -53, -116, -90, 127, -54, -217, +281, -116, 134, 387, -192, 302, -249, -316, +77, -547, 219, 123, -79, 734, -53, -7, +222, -665, -204, 89, -412, 203, 485, -149, +422, 412, -606, 145, -352, -923, 755, -40, +32, 1158, -857, -144, 405, -993, 791, 240, +-656, 534, -570, -195, 527, 123, 193, -120, +-25, -741, 169, 665, -554, 1048, -596, -1278, +1034, -859, 883, 1595, -1288, 279, -871, -1441, +1140, 355, 585, 962, -770, -904, -98, -349, +270, 1268, -381, -333, 65, -1252, 802, 850, +-389, 917, -935, -1010, 576, -529, 720, 960, +-631, 304, -374, -808, 570, -292, 84, 631, +-515, 512, 52, -471, 497, -799, -154, 435, +-360, 787, -4, -284, 361, -449, 68, 23, +-379, -80, -144, 257, 415, 599, 201, -406, +-527, -854, -234, 224, 497, 878, 378, 135, +-503, -676, -546, -515, 477, 275, 499, 874, +-271, -20, -414, -1021, -49, 65, 296, 682, +239, -43, -105, -320, -366, -18, -65, 147, +335, -4, 106, -48, -97, -156, -114, 185, +-322, 345, 235, -413, 586, -482, -330, 548, +-720, 546, 478, -571, 454, -441, -342, 385, +-133, 295, -23, -120, -43, -210, 344, -5, +60, 112, -640, -3, 111, 5, 665, 96, +-354, -133, -625, -129, 684, 298, 186, -73, +-718, -379, 230, 495, 356, 251, -365, -927, +-70, -39, 377, 1158, -126, -74, -519, -1192, +317, 23, 472, 1032, -189, 158, -631, -792, +-58, -377, 893, 641, 62, 391, -918, -597, +-98, -114, 964, 636, -246, -404, -809, -717, +766, 1014, 330, 697, -996, -1397, -77, -535, +943, 1382, 61, 315, -741, -1054, -142, 2, +258, 581, 230, -403, 190, -126, -259, 762, +-423, -100, -60, -984, 398, 47, 471, 1034, +-267, 226, -832, -992, 7, -414, 957, 808, +-67, 396, -671, -492, 273, -245, 2, 197, +-505, -20, 528, 100, 628, 190, -797, -379, +-586, -124, 701, 531, 194, -71, -367, -593, +381, 199, -145, 693, -785, -253, 416, -676, +716, 103, -265, 494, -394, 301, -62, -274, +-188, -770, 319, 121, 664, 950, -296, 48, +-968, -769, 24, -303, 817, 449, 274, 479, +-374, -101, -609, -523, -78, -104, 578, 405, +269, 163, -351, -255, -198, 16, -123, 39, +-42, -264, 357, 169, 303, 461, -531, -310, +-385, -557, 510, 379, 79, 529, -321, -313, +142, -522, 227, 229, -382, 510, -147, -145, +252, -469, 123, 38, 14, 396, -37, 41, +-336, -240, -182, -53, 353, -92, 536, 106, +-159, 444, -888, -69, -282, -869, 1006, 67, +736, 1211, -1004, -164, -1017, -1185, 739, 87, +982, 1000, -539, 135, -782, -859, 366, -207, +394, 667, -327, 150, -128, -422, 106, -105, +137, 273, 61, 21, -386, -168, -442, -67, +736, 252, 674, 104, -1013, -380, -778, -125, +948, 448, 649, 123, -697, -461, -360, -87, +278, 490, -55, -43, 100, -569, 273, 301, +-278, 582, -334, -372, 120, -732, 295, 344, +30, 883, -105, -242, -320, -839, -7, -26, +396, 684, -85, 285, -272, -461, 99, -273, +74, 11, -258, 212, 69, 379, 332, -198, +-281, -434, -294, 66, 281, 355, 101, -8, +-326, -282, 116, 139, 276, 271, -476, -477, +-127, -291, 538, 833, -31, 271, -643, -899, +294, -313, 523, 637, -676, 511, -252, -391, +765, -503, 113, 89, -882, 258, 47, 387, +722, -145, -227, -671, -437, 164, 390, 584, +44, -51, -611, -402, 236, -135, 735, 352, +-385, 213, -838, -375, 408, -202, 576, 462, +-288, 100, -314, -528, 173, 27, -61, 543, +-292, -254, 334, -330, 387, 437, -487, -130, +-573, -396, 418, 574, 450, 210, -174, -892, +-311, 41, -90, 976, -112, -298, 378, -794, +236, 460, -479, 452, -319, -417, 401, -181, +251, 293, -447, 68, -85, -124, 497, -121, +-146, -46, -518, 330, 104, 104, 477, -508, +205, -11, -600, 537, -537, -297, 597, -182, +746, 574, -591, -398, -851, -622, 501, 762, +803, 642, -569, -871, -630, -684, 522, 789, +300, 646, -369, -591, -37, -495, -170, 297, +-31, 277, 558, 25, 60, -132, -1002, -242, +-140, 94, 1142, 229, 165, -10, -967, -132, +-402, -193, 641, 109, 465, 423, -235, -178, +-547, -571, -110, 233, 535, 593, 181, -114, +-481, -644, -87, -50, 310, 730, -19, 77, +-274, -661, 125, -7, 147, 407, -92, 5, +-92, -182, -102, 4, 51, 67, 169, -66, +48, -26, -303, 169, -156, -17, 278, -202, +172, 23, -277, 142, -121, 63, 122, -138, +-25, -101, -22, 98, 73, 126, -73, -24, +-112, -179, -14, -108, 109, 311, 66, 225, +-156, -519, -113, -264, 135, 685, 72, 191, +-148, -682, 23, -78, 32, 511, -93, -47, +0, -193, 185, 104, -84, -92, -276, -13, +122, 2, 276, 121, -114, 280, -202, -394, +-59, -481, 71, 571, 292, 481, 44, -388, +-597, -402, -56, -106, 623, 460, 51, 452, +-499, -474, -156, -333, 328, 142, 80, -13, +-161, 454, 51, 217, -30, -860, -249, -253, +1, 828, 639, 215, -220, -428, -864, -298, +499, 118, 664, 309, -533, -143, -486, 31, +512, 179, 195, -488, -305, 0, -90, 620, +127, -211, 36, -450, -20, 325, 129, 172, +-171, -294, -320, -64, 422, 162, 366, 375, +-504, -270, -352, -699, 325, 511, 456, 699, +-250, -447, -358, -599, 126, 148, 40, 593, +134, 67, 124, -524, -223, -100, -334, 269, +250, 40, 405, 281, -284, -281, -255, -624, +60, 673, 215, 406, 44, -500, -248, -320, +96, 137, 56, 424, -111, 38, 49, -393, +199, -218, -197, 350, -319, 232, 592, -149, +43, -223, -599, -174, 94, 432, 562, 160, +-133, -425, -514, -53, 278, 149, 289, 231, +-272, -107, -49, -341, 263, 239, -192, 177, +-93, -205, 229, 64, -37, -52, -72, -65, +78, 233, -151, -91, 70, -149, 195, 148, +-140, -28, -74, -99, 68, 178, 81, -19, +-156, -284, 185, 150, 85, 302, -352, -274, +92, -184, 355, 246, -263, 11, -90, -54, +375, 114, -284, -188, -282, -245, 500, 397, +386, 400, -669, -551, -445, -478, 756, 529, +484, 448, -578, -314, -434, -327, 268, 50, +330, 4, 289, 349, -296, 281, -689, -706, +343, -275, 860, 669, -314, 211, -685, -299, +223, -361, 438, 110, -83, 478, -91, -234, +-77, -253, -77, 325, 334, -81, -97, -234, +-269, 144, 431, 326, -5, -182, -547, -610, +408, 591, 292, 435, -352, -749, -53, -57, +265, 518, -61, -208, -265, -244, 399, 577, +258, -179, -556, -922, -367, 657, 930, 961, +263, -714, -896, -950, -129, 468, 679, 922, +279, -257, -618, -481, -55, -244, 431, 188, +-55, 592, -247, -134, 351, -413, -125, -25, +-147, 109, 272, 290, -160, -100, 78, -296, +131, 326, -118, -28, -88, -383, 269, 286, +-44, 274, -219, -251, 219, -171, 226, 109, +-272, 212, -139, -316, 201, 52, 244, 566, +71, -482, -411, -530, -104, 517, 536, 576, +33, -393, -245, -691, 71, 438, 37, 504, +-171, -424, 155, -281, 505, 499, -252, 54, +-584, -684, 238, 391, 485, 464, 186, -611, +-241, 74, -593, 345, 230, -428, 809, 47, +-181, 409, -596, -193, 281, -202, 217, 131, +-218, -197, 198, 326, 212, 337, -321, -832, +10, -78, 155, 1103, -50, -366, 153, -1258, +326, 1148, -423, 980, -535, -1961, 990, -71, +270, 2119, -897, -1030, 205, -1368, 485, 1529, +-393, 390, 78, -1408, 559, 306, -609, 1077, +-192, -911, 916, -332, -282, 1291, -697, -942, +647, -874, 554, 1885, -767, -55, -163, -1956, +599, 824, 17, 1271, -127, -1080, 104, -281, +-281, 970, -68, -735, 780, -494, -105, 1476, +-796, -418, 413, -1300, 570, 1136, -512, 467, +15, -1343, 480, 450, -516, 1169, 52, -1130, +677, -621, -399, 1393, -487, -402, 654, -693, +455, 1167, -730, -528, -207, -1167, 586, 1217, +351, 915, -358, -1208, -294, -817, 24, 981, +593, 575, 220, -630, -801, 50, -10, -170, +922, -468, -289, 1026, -624, 455, 529, -1518, +432, -106, -501, 1454, -151, -184, 419, -1161, +-25, 350, 80, 889, 36, -467, -293, -659, +-22, 544, 702, 373, -200, -416, -451, -128, +272, 97, 314, 119, -300, 18, 102, 40, +368, -149, -404, -162, -167, 256, 687, 159, +-77, -184, -511, -112, 326, -31, 343, 111, +-182, 242, -332, -55, 314, -570, 336, 112, +-80, 917, -397, -393, -19, -984, 549, 634, +154, 860, -322, -799, -278, -462, 141, 586, +605, 126, -112, -216, -290, 113, -144, -185, +182, -346, 493, 749, -100, 218, -393, -1157, +-11, 271, 422, 1014, 143, -608, -264, -592, +-77, 616, 168, 363, 192, -717, -65, -17, +-126, 774, 50, -645, 462, -226, -262, 1017, +-579, -755, 845, -581, 402, 1360, -963, -298, +-34, -1194, 927, 976, -286, 542, -283, -1259, +415, 309, -260, 1179, -308, -1260, 900, -554, +208, 1867, -1271, -542, 276, -1573, 1195, 1479, +-544, 341, -455, -1548, 513, 1049, -235, 792, +-7, -1892, 664, 265, -314, 1918, -666, -1153, +762, -1133, 231, 1494, -645, -124, 348, -1221, +519, 1340, -588, 525, -511, -2042, 1109, 160, +412, 2121, -1125, -646, -203, -1545, 927, 587, +387, 890, -738, -193, -258, -589, 640, -156, +286, 665, -595, 481, 18, -1376, 666, -328, +-286, 2098, -304, -224, 391, -2151, 93, 555, +-258, 1443, 417, -290, 42, -493, -673, -413, +298, -320, 1049, 1187, -689, 678, -831, -1803, +1102, -274, 244, 1571, -862, -306, 511, -764, +547, 695, -1159, -295, 345, -789, 1300, 1444, +-819, 201, -869, -2043, 968, 668, 467, 1854, +-708, -1344, 403, -992, -13, 1398, -930, -187, +1366, -706, 863, 1019, -2214, -372, -97, -1125, +2396, 1103, -392, 783, -2042, -1503, 1297, -91, +894, 1590, -1170, -1034, 158, -1091, 923, 1804, +-634, 329, -454, -1857, 938, 89, -11, 1420, +-537, -238, 433, -819, 105, 429, -537, -90, +638, -517, 182, 953, -465, 312, 0, -1345, +512, 75, -306, 1016, -38, -451, 613, -233, +-194, 732, -721, -768, 558, -880, 749, 1654, +-527, 693, -327, -2020, 243, -321, 184, 1820, +128, -302, 386, -1100, -548, 1020, -478, 38, +863, -1762, 666, 1115, -826, 2101, -450, -1858, +837, -1978, -6, 1714, -198, 1535, 563, -742, +-367, -1199, -602, -446, 622, 828, 998, 1227, +-612, -187, -1068, -1783, 660, -345, 1168, 1812, +-496, 542, -909, -1400, 617, -557, 634, 857, +-558, 382, -239, -602, 848, -126, 69, 671, +-908, -123, 46, -1096, 1271, 357, -7, 1299, +-1191, -330, 107, -1353, 1147, 110, -29, 1186, +-837, -51, 309, -710, 730, -76, -595, 233, +-275, 97, 988, -35, 50, -109, -853, 240, +30, -227, 1007, -407, -24, 456, -708, 433, +10, -599, 970, -417, -65, 818, -1168, 10, +455, -1095, 1695, 691, -497, 1204, -2289, -1516, +746, -1182, 3102, 2058, -800, 1150, -3332, -2555, +1014, -996, 3243, 2787, -952, 615, -2361, -2776, +1030, -175, 1246, 2333, -552, -186, -2, -1660, +209, 178, -895, 863, 783, -8, 1501, -45, +-1833, -318, -1190, -949, 2904, 872, 826, 1589, +-3367, -1348, -141, -1949, 3493, 1448, -260, 2056, +-2635, -1507, 573, -1747, 1604, 1288, -290, 1228, +-571, -1229, 225, -638, 380, 1302, -190, 88, +-612, -1710, 833, 345, 1231, 2117, -1304, -722, +-1458, -2403, 1905, 965, 1431, 2336, -2079, -1449, +-426, -1750, 2225, 1921, -923, 713, -1797, -2430, +2626, 426, 1197, 2630, -3378, -1382, -245, -2485, +3379, 1741, -363, 1949, -2297, -1564, 997, -1353, +1258, 999, -1336, 798, -23, -549, 1704, -555, +-502, 488, -1549, 298, 888, -708, 1199, -221, +-676, 873, -304, 450, 519, -1296, -96, -605, +-503, 1521, 624, 370, 944, -1326, -585, -132, +-1074, 918, 361, -251, 1291, -734, 367, 743, +-878, 783, -1073, -1380, 697, -1325, 1880, 2073, +-386, 1954, -1862, -2732, 205, -2621, 1910, 2985, +140, 3195, -1388, -3129, -366, -3509, 1017, 2966, +1180, 3300, -422, -2431, -2098, -3016, 387, 1561, +3379, 2696, -357, -671, -4157, -2601, 806, -116, +4779, 2547, -1091, 461, -4561, -2471, 1572, -534, +4399, 2068, -1970, 394, -3450, -1449, 2316, -459, +2755, 701, -2108, 585, -1956, 17, 2095, -952, +1491, -777, -1666, 1368, -972, 1324, 1678, -1843, +851, -1557, -1665, 1831, -470, 1353, 2080, -1311, +482, -962, -2302, 220, -250, 339, 2775, 1047, +94, 161, -2352, -2223, 49, -676, 2104, 3086, +-1, 693, -1265, -3414, 4, -487, 909, 3030, +358, 286, -616, -2547, -359, -196, 825, 1955, +636, 166, -950, -1407, -301, -519, 1036, 893, +353, 978, -852, -617, 246, -1340, 615, 275, +-571, 1190, 62, 162, 993, -709, -270, -827, +-844, -44, 350, 1278, 836, 779, 263, -1450, +-584, -1569, -692, 1202, 735, 2111, 1166, -869, +-406, -2293, -1419, 349, 578, 1897, 1776, 164, +-564, -1338, -1542, -483, 693, 436, 1467, 348, +-331, 650, -908, -144, -89, -1726, 788, -295, +633, 2438, -151, 836, -743, -2959, -214, -1416, +696, 3074, 1003, 1578, -5, -2654, -1325, -1665, +-860, 1923, 1909, 1229, 2111, -1150, -2122, -253, +-2669, 85, 2317, -969, 3066, 582, -2070, 2348, +-2481, -1114, 1837, -3468, 1893, 1099, -1444, 3903, +-685, -678, 1494, -3698, -296, -44, -1487, 2534, +1543, 820, 1914, -879, -2249, -1588, -2254, -936, +3250, 1971, 2604, 2114, -3654, -1674, -2305, -2936, +3971, 1004, 1908, 3004, -3456, -512, -1148, -2282, +2948, -27, 858, 1262, -2349, 44, -56, -475, +1780, 470, 97, -224, -1264, -1090, -70, 308, +1099, 1243, 791, 349, -784, -1107, -1458, -1537, +710, 488, 2452, 2681, -30, 331, -3095, -3519, +-783, -1333, 4025, 3789, 2024, 1961, -4495, -3608, +-2696, -2081, 4646, 2721, 3552, 1791, -4218, -1565, +-3552, -1701, 3507, 665, 3578, 1623, -2328, -221, +-2959, -1840, 1240, -116, 2523, 2527, 189, 64, +-1878, -3453, -1189, -57, 1506, 4043, 2396, 187, +-918, -3963, -3035, -884, 510, 3072, 3638, 1726, +343, -1741, -3616, -2261, -895, -46, 3416, 2102, +1579, 1599, -2514, -1303, -1687, -2592, 1586, -77, +1854, 2719, -426, 1330, -1584, -2209, -73, -2128, +1368, 1186, 777, 2354, -1220, -545, -917, -2270, +1630, 584, 1194, 1992, -1794, -1382, -1350, -1942, +2040, 2230, 1863, 2300, -1541, -2723, -2078, -3123, +756, 2575, 2303, 3546, 545, -1742, -1647, -3142, +-1594, 232, 688, 1680, 2498, 1381, 923, 207, +-2512, -2530, -2307, -2143, 2243, 2714, 3539, 3589, +-1313, -2276, -4060, -4313, 792, 1515, 4034, 3960, +15, -717, -3474, -2994, -267, -135, 2877, 1825, +649, 658, -1886, -774, -820, -1014, 1267, -127, +934, 955, -274, 807, -607, -518, -413, -1499, +217, -270, 1103, 1877, 628, 1140, -1079, -1921, +-1258, -1826, 734, 1305, 1886, 1975, 156, -267, +-1728, -1700, -813, -686, 1208, 758, 1307, 1076, +-25, 480, -1032, -922, -999, -1572, 692, 212, +1597, 1848, 277, 879, -1538, -1615, -736, -1890, +1161, 1113, 938, 1931, -200, -395, -581, -1203, +-394, -459, -40, 9, 1128, 1138, 950, 1109, +-1461, -1680, -1499, -1976, 1714, 2006, 2125, 2242, +-1414, -2066, -2536, -2164, 1235, 1670, 2786, 1785, +-496, -1121, -2513, -1055, -166, 363, 1964, -112, +833, 348, -574, 1298, -1211, -780, -462, -2169, +1001, 589, 1559, 2289, -312, 37, -1644, -1735, +-304, -710, 1118, 647, 830, 809, -158, 506, +-304, -457, -600, -1131, -508, -132, 738, 655, +1690, 566, 121, 571, -2231, -691, -1267, -1762, +2126, 254, 2406, 2034, -1251, 414, -2402, -1225, +324, -832, 1508, -415, 382, 479, 49, 1979, +-9, 510, -1236, -2615, -1040, -1723, 1895, 1734, +2176, 2499, -1241, 202, -2465, -2460, -106, -2324, +2077, 1488, 1509, 3511, -808, -48, -2093, -3415, +-144, -1189, 1700, 2114, 557, 1611, -435, -362, +51, -1328, -574, -1009, -1130, 685, 1087, 1359, +2019, -223, -492, -879, -1804, 270, -522, 24, +608, -990, 1480, 718, 1359, 1724, -1547, -870, +-2807, -2122, 714, 296, 3325, 1998, 774, 391, +-2391, -1300, -1975, -851, 787, 169, 2470, 938, +828, 748, -1786, -690, -1445, -1104, 496, 38, +1157, 934, 933, 649, -194, -629, -1472, -1046, +-768, 263, 1476, 1029, 1101, 36, -892, -854, +-391, -239, 255, 520, -429, 390, -74, -99, +1178, -714, 441, -437, -1091, 1269, -879, 885, +349, -1913, 1108, -1067, 839, 2160, -652, 962, +-1755, -1854, -53, -741, 2019, 1118, 822, 440, +-1314, -332, -1248, -214, 386, -187, 1250, 103, +290, 229, -560, -170, -477, 76, -53, 262, +172, -382, 475, -316, 411, 316, -414, 227, +-779, 101, 290, 87, 817, -703, -382, -703, +-141, 1195, 639, 1353, -507, -1376, -955, -1686, +857, 1095, 1297, 1566, -748, -678, -1222, -990, +424, 466, 831, 188, -168, -739, -36, 561, +123, 1238, -567, -961, -110, -1480, 645, 775, +171, 1181, -130, -267, -69, -345, -366, -117, +-285, -784, 599, 70, 729, 1638, -162, 372, +-850, -1713, -712, -1055, 530, 1008, 1606, 1471, +319, 234, -2004, -1553, -1110, -1334, 1655, 1343, +1496, 1591, -621, -972, -1217, -913, -367, 594, +415, -274, 817, -404, 611, 1320, -564, 435, +-1145, -1877, -136, -391, 993, 1715, 851, 80, +-273, -1044, -980, 505, -574, 168, 681, -1065, +843, 464, 97, 1293, -458, -686, -739, -1021, +-234, 516, 788, 321, 1074, -150, -489, 531, +-1355, -329, 141, -1180, 1072, 846, -131, 1330, +-359, -1171, 496, -1191, -206, 1272, -964, 1044, +288, -1163, 1257, -948, -144, 727, -735, 869, +-93, 123, -302, -891, -52, -985, 1440, 839, +739, 1428, -2110, -537, -1476, -1264, 1713, -6, +2031, 670, -563, 564, -1797, -67, -821, -814, +897, -316, 1683, 711, 282, 418, -1536, -538, +-1151, -205, 634, 422, 1266, -155, 335, -344, +-334, 336, -918, 333, -967, -366, 701, -284, +1997, 479, 209, 65, -2325, -818, -1127, 295, +1786, 1273, 1677, -429, -1004, -1775, -1263, 164, +237, 2127, 330, 400, -11, -2109, 753, -982, +270, 1755, -1494, 1151, -571, -1237, 1489, -663, +848, 733, -1227, -195, -620, -536, 824, 1009, +210, 685, -627, -1433, 116, -844, 593, 1225, +89, 694, -684, -534, -681, -112, 662, -255, +1279, -578, -284, 555, -1617, 1020, -50, -124, +1228, -976, 270, -797, -358, 542, -48, 1526, +-643, 150, -426, -1660, 1150, -684, 824, 1178, +-682, 661, -1075, -220, -257, -157, 711, -688, +1230, -516, 229, 1135, -1795, 995, -1154, -950, +1446, -1114, 1751, 376, -455, 938, -1626, 160, +-737, -633, 962, -250, 1366, 222, 47, 8, +-1216, 118, -820, 315, 394, -263, 1102, -584, +458, 336, -700, 669, -865, -419, -147, -494, +675, 374, 869, 333, 96, -146, -1232, -385, +-864, -148, 997, 428, 1346, 670, -504, -411, +-1193, -1246, -127, 286, 802, 1538, 390, 63, +-276, -1412, -417, -480, -14, 934, 427, 631, +-136, -154, -544, -494, 572, -557, 682, 218, +-778, 816, -940, 75, 634, -568, 1134, -172, +-282, 43, -1029, -7, -144, 444, 772, 421, +112, -762, -125, -696, -80, 797, -160, 604, +-298, -610, 291, -22, 521, 316, -295, -841, +-361, 65, 234, 1518, -47, -311, -440, -1718, +568, 387, 758, 1464, -772, -397, -1160, -840, +583, 522, 1179, 69, 72, -710, -861, 655, +-788, 883, 169, -1115, 1211, -829, 606, 1264, +-1264, 530, -1097, -1049, 955, -115, 1032, 733, +-475, -177, -614, -488, 75, 253, 148, 480, +31, -43, 23, -670, 141, -221, 16, 882, +-244, 525, -331, -971, 186, -695, 560, 947, +33, 669, -490, -680, -364, -485, 164, 292, +482, 337, 382, 93, -549, -200, -697, -328, +406, 174, 707, 486, -197, -246, -583, -509, +109, 413, 559, 491, -254, -448, -715, -501, +456, 321, 995, 740, -443, -127, -1290, -914, +99, -76, 1492, 990, 364, 261, -1375, -845, +-701, -283, 914, 563, 845, 306, -391, -265, +-798, -263, 187, 113, 599, 364, -327, -49, +-412, -627, 635, 121, 511, 1066, -872, -194, +-827, -1303, 877, 118, 1164, 1370, -612, 195, +-1124, -1243, 198, -381, 703, 1021, 133, 326, +42, -630, -204, 26, -618, 269, -12, -309, +832, -14, 389, 317, -505, 60, -557, 197, +-179, -316, 520, -908, 864, 601, -218, 1646, +-1147, -559, -17, -1991, 856, 281, 135, 1781, +-19, 250, -54, -887, -767, -847, -131, -177, +1176, 1432, 494, 1012, -1139, -1668, -614, -1205, +802, 1636, 465, 892, -212, -1329, -119, -275, +-184, 1092, -150, -195, 314, -878, 315, 388, +-100, 764, -226, -118, -172, -533, 95, -375, +371, 340, 157, 863, -389, -84, -275, -901, +443, -155, 206, 661, -367, 418, -6, -254, +410, -386, -193, -30, -386, 192, 298, 242, +453, 167, -306, -185, -406, -458, 362, 82, +233, 735, -295, 162, -67, -882, 285, -302, +28, 1036, -215, 475, -168, -992, 147, -569, +455, 853, 8, 814, -770, -501, -176, -992, +999, 175, 313, 1092, -999, 242, -395, -924, +831, -488, 383, 666, -611, 628, -262, -239, +288, -447, 186, -137, -37, 268, -289, 503, +-100, -71, 372, -605, 193, 92, -519, 602, +-286, -108, 426, -385, 326, 128, -151, 268, +-493, 133, -308, -151, 463, -484, 786, 231, +-564, 977, -1209, -281, 615, -1258, 1211, 496, +-842, 1303, -1059, -645, 960, -871, 644, 862, +-1166, 285, -537, -832, 1146, 314, 430, 780, +-1068, -496, -730, -559, 589, 441, 920, 419, +-201, -97, -1231, -127, -384, -197, 1173, -64, +491, 530, -1128, 293, -578, -591, 666, -390, +310, 685, -576, 471, -195, -591, 260, -368, +-183, 610, -244, 305, 84, -558, -82, -38, +-173, 611, 79, -180, -134, -477, -309, 483, +-93, 366, 231, -552, -111, -112, -328, 610, +-50, 5, -179, -446, -162, 150, 260, 309, +53, -62, -637, -16, -418, -87, 365, -75, +325, 415, -345, 194, -581, -617, -247, -56, +344, 722, 171, 29, -424, -496, -393, 69, +-8, 257, -122, -102, -27, 253, 178, 268, +-468, -705, -508, -188, 199, 1052, 183, 97, +-387, -832, -194, 123, -72, 391, -532, -248, +187, 366, 567, 473, -915, -920, -965, -530, +938, 1341, 598, 541, -1304, -1240, -700, -266, +729, 909, 246, 14, -552, -281, -418, 329, +-331, -156, -14, -406, 517, 495, -191, 433, +-1082, -409, -240, -266, 721, 261, 51, 340, +-829, -16, -463, -427, 338, 10, 67, 832, +-522, -73, -304, -1129, 253, 380, -126, 1403, +-689, -630, -144, -1109, 372, 882, -103, 492, +-556, -752, -310, 459, -105, 575, 77, -1207, +145, -227, -312, 1755, -810, 71, -147, -1730, +645, 143, -85, 1360, -791, -111, -265, -576, +146, 69, -139, -55, -139, 166, 87, 541, +-416, -185, -678, -638, 189, 268, 618, 681, +-575, -137, -906, -573, 275, 206, 438, 542, +-579, -155, -512, -364, 442, 247, -225, 281, +-639, -259, 273, 54, 212, 369, -945, -316, +-147, -334, 981, 706, -460, 397, -1438, -828, +266, -359, 1318, 917, -431, 487, -1415, -691, +-263, -549, 846, 549, 498, 682, -654, -265, +-1006, -606, -89, 189, 774, 488, 169, -40, +-665, -140, -506, 70, -45, -73, 195, -30, +181, 392, -196, 94, -556, -476, -144, 68, +265, 533, -98, -184, -292, -279, 59, 378, +39, 159, -445, -412, -405, 77, 447, 465, +350, -151, -417, -262, -704, 401, -193, -62, +602, -432, 470, 574, -569, 471, -971, -806, +64, -285, 929, 891, 89, 93, -926, -516, +-293, 295, 323, 58, 118, -602, -35, 590, +-62, 909, -432, -907, -232, -909, 397, 1009, +249, 869, -514, -662, -430, -631, 398, 341, +284, 480, -612, 66, -280, -293, 679, -104, +-25, 282, -914, 23, 125, -176, 921, 303, +-498, 148, -939, -478, 575, 105, 715, 588, +-745, -292, -616, -389, 545, 665, 319, 113, +-300, -818, -242, 323, -164, 939, -57, -533, +436, -787, 257, 672, -745, 705, -568, -588, +700, -449, 650, 537, -715, 289, -566, -337, +462, -18, 194, 227, -450, -94, 146, -4, +481, 277, -663, -69, -615, -360, 779, 300, +646, 497, -825, -454, -626, -428, 526, 717, +403, 359, -437, -775, -151, -129, 343, 817, +-224, -18, -502, -535, 335, 224, 566, 181, +-404, -215, -552, 374, 75, 151, 322, -667, +63, 55, 43, 853, -317, -114, -570, -751, +392, 280, 682, 622, -405, -268, -699, -442, +223, 378, 393, 480, -265, -382, -97, -533, +237, 513, -320, 658, -309, -559, 409, -488, +243, 658, -524, 159, -290, -599, 491, 426, +125, 639, -654, -900, -118, -585, 658, 1248, +59, 619, -763, -1117, -281, -543, 557, 720, +416, 578, -401, -95, -625, -538, -40, -298, +562, 580, 228, 515, -538, -566, -413, -332, +265, 623, 219, 136, -254, -548, -36, 82, +67, 463, -259, -22, -156, -133, 179, -111, +43, -233, -116, 394, -87, 690, -193, -519, +-215, -862, 287, 596, 245, 788, -386, -481, +-344, -259, 21, 360, 105, -349, 190, -166, +80, 926, -598, 113, -459, -1123, 560, -21, +529, 1045, -578, -16, -656, -580, 268, 130, +373, 94, -206, -79, -267, 339, 5, -11, +-56, -427, -157, 268, 57, 364, 128, -468, +-245, -134, -318, 659, 189, -2, 129, -592, +-335, 124, -144, 409, 242, -115, -170, -25, +-320, 160, 205, -258, 57, -137, -404, 416, +-64, 182, 317, -228, -187, -107, -388, -97, +-26, 47, 262, 485, 53, 160, -351, -629, +-380, -347, 108, 608, 465, 460, -88, -272, +-678, -353, -209, -140, 462, 212, 249, 544, +-396, -18, -476, -638, 67, -67, 316, 521, +-67, 166, -261, -205, -141, -138, -93, -62, +58, 153, 88, 262, -110, -88, -299, -254, +-116, 56, 241, 198, 43, 52, -413, -39, +-176, -127, 277, -25, 119, 271, -452, 21, +-231, -284, 306, 109, 81, 219, -287, -141, +-143, -30, -141, 105, 21, -109, 417, 146, +-214, 198, -832, -460, 161, -133, 920, 827, +-389, 84, -954, -1085, 321, -38, 567, 1203, +-389, 118, -230, -979, 86, -313, -303, 563, +92, 626, 497, -31, -497, -759, -693, -421, +566, 684, 556, 774, -717, -352, -504, -866, +520, -9, 236, 732, -409, 327, -246, -382, +154, -436, 131, 50, -161, 406, -301, 130, +146, -195, 283, -42, -313, 20, -558, -220, +369, 16, 618, 722, -493, 121, -789, -1240, +259, -300, 828, 1605, -140, 560, -956, -1624, +-105, -816, 760, 1359, 228, 1027, -686, -772, +-401, -1078, 396, 46, 317, 1016, -155, 681, +-400, -752, -160, -1159, 263, 339, 313, 1375, +-248, 213, -484, -1307, 40, -703, 410, 1058, +141, 1084, -420, -663, -476, -1296, 321, 282, +624, 1442, -335, 45, -850, -1430, 328, -340, +783, 1371, -405, 730, -704, -1239, 244, -1086, +533, 976, -143, 1432, -427, -480, -125, -1659, +265, -95, 246, 1660, -218, 684, -323, -1296, +129, -1171, 86, 777, -87, 1419, 145, -172, +55, -1331, -534, -387, -10, 1101, 553, 815, +33, -814, -419, -1004, -215, 575, 110, 1044, +257, -328, 258, -989, -375, 80, -479, 937, +306, 208, 477, -870, -270, -471, -190, 758, +-3, 732, -132, -575, 220, -913, 307, 415, +-393, 978, -326, -286, 451, -913, 143, 209, +-443, 867, -12, -168, 447, -860, -127, 159, +-354, 918, -52, -54, 247, -940, 440, -154, +-217, 834, -862, 518, 203, -509, 1109, -911, +-203, 2, -1165, 1208, 300, 650, 1008, -1271, +-554, -1261, -692, 1087, 828, 1734, 405, -690, +-946, -1942, -358, 220, 883, 1898, 455, 260, +-445, -1616, -694, -664, -168, 1232, 813, 1001, +841, -827, -669, -1208, -1334, 456, 435, 1401, +1200, -195, 101, -1570, -599, 142, -551, 1671, +-347, -186, 855, -1640, 1277, 203, -829, 1513, +-1852, -72, 613, -1231, 1976, -229, -424, 829, +-1463, 663, 215, -313, 854, -1049, -68, -208, +-464, 1278, 69, 647, 453, -1183, 43, -923, +-775, 816, -273, 1061, 1284, -276, 700, -1106, +-1630, -214, -1129, 1055, 1761, 622, 1377, -919, +-1399, -897, -1490, 743, 913, 1056, 1411, -464, +-243, -1063, -1235, 120, -401, 890, 1124, 330, +1063, -552, -943, -744, -1755, 159, 810, 994, +2373, 241, -451, -926, -2759, -584, -106, 728, +2754, 753, 1004, -470, -2375, -608, -1793, 212, +1520, 327, 2515, 19, -427, -57, -2859, -97, +-578, -87, 2754, 86, 1476, 166, -2342, -56, +-1901, -160, 1618, 82, 2183, 165, -893, -122, +-2110, -176, 165, 119, 2013, 197, 580, 17, +-1941, -138, -1105, -277, 1718, -1, 1809, 587, +-1507, 281, -2356, -818, 1184, -630, 2832, 901, +-556, 918, -3232, -755, -61, -1013, 3380, 414, +844, 884, -3246, 104, -1569, -634, 2871, -584, +2235, 378, -2186, 904, -2669, -122, 1287, -1038, +2911, -59, -174, 1055, -2863, 158, -918, -977, +2599, -215, 1986, 871, -2170, 327, -2675, -804, +1567, -475, 3169, 795, -905, 641, -3218, -783, +162, -774, 3095, 673, 693, 910, -2800, -397, +-1462, -1056, 2376, 38, 2309, 1149, -1901, 368, +-2840, -1072, 1252, -776, 3219, 841, -437, 1168, +-3162, -493, -513, -1434, 2797, 23, 1661, 1652, +-2163, 572, -2652, -1882, 1341, -1141, 3586, 2080, +-541, 1659, -4001, -2097, -200, -2070, 4075, 1890, +870, 2315, -3691, -1413, -1321, -2349, 3044, 753, +1795, 2234, -2224, -50, -2140, -2002, 1393, -615, +2668, 1758, -565, 1222, -3084, -1502, -189, -1799, +3454, 1214, 1103, 2345, -3476, -783, -1965, -2772, +3133, 135, 2948, 3008, -2289, 688, -3618, -2931, +1116, -1542, 4158, 2527, 232, 2263, -4183, -1821, +-1326, -2751, 3814, 991, 2331, 2933, -3017, -152, +-2798, -2818, 1979, -717, 3193, 2525, -771, 1623, +-3210, -2165, -342, -2517, 3228, 1785, 1466, 3313, +-3051, -1344, -2173, -3898, 2727, 836, 2923, 4163, +-2181, -253, -3194, -4057, 1415, -420, 3546, 3600, +-437, 1188, -3486, -2910, -490, -1987, 3317, 2109, +1595, 2707, -2876, -1299, -2244, -3241, 2255, 526, +3001, 3526, -1494, 160, -3305, -3584, 817, -782, +3662, 3494, -72, 1431, -3704, -3320, -468, -2126, +3694, 3027, 1280, 2894, -3372, -2522, -1882, -3649, +2809, 1759, 2755, 4218, -1821, -765, -3315, -4435, +769, -316, 3798, 4232, 447, 1333, -3706, -3690, +-1320, -2116, 3387, 2895, 2160, 2664, -2682, -2007, +-2472, -3074, 1932, 1139, 2857, 3420, -1006, -341, +-2945, -3751, 245, -375, 3152, 3957, 733, 1103, +-3178, -3959, -1360, -1883, 3091, 3679, 2147, 2657, +-2598, -3112, -2541, -3351, 1989, 2308, 2843, 3913, +-932, -1425, -2795, -4242, 29, 534, 2691, 4267, +1041, 420, -2376, -4055, -1758, -1469, 2178, 3674, +2520, 2508, -1806, -3139, -2935, -3450, 1494, 2381, +3335, 4173, -790, -1454, -3346, -4600, -48, 409, +3275, 4674, 1201, 646, -2813, -4390, -2112, -1683, +2196, 3879, 2973, 2620, -1378, -3285, -3221, -3392, +638, 2667, 3280, 3878, 120, -2001, -2942, -4058, +-606, 1176, 2613, 3988, 1133, -274, -2155, -3726, +-1470, -626, 1812, 3286, 1942, 1426, -1377, -2753, +-2232, -2188, 949, 2261, 2603, 2908, -331, -1894, +-2808, -3571, -209, 1530, 2921, 4039, 929, -997, +-2775, -4236, -1604, 171, 2550, 4092, 2250, 799, +-1959, -3607, -2734, -1689, 1232, 2793, 3173, 2266, +-371, -1827, -3287, -2512, -459, 914, 3229, 2421, +1263, -225, -2876, -2108, -1881, -294, 2393, 1684, +2371, 749, -1742, -1311, -2675, -1218, 1034, 957, +2974, 1735, -320, -612, -3178, -2221, -296, 131, +3294, 2460, 937, 530, -3222, -2383, -1572, -1310, +2953, 1932, 2197, 2010, -2358, -1281, -2816, -2430, +1611, 537, 3203, 2548, -676, 102, -3379, -2442, +-226, -644, 3305, 2222, 930, 1129, -2935, -2028, +-1475, -1619, 2498, 1784, 1699, 2082, -1926, -1409, +-1915, -2488, 1430, 828, 2176, 2766, -1096, -145, +-2480, -2915, 741, -577, 2953, 2986, -562, 1214, +-3186, -3076, 128, -1738, 3276, 3199, 358, 2103, +-3045, -3298, -885, -2355, 2493, 3203, 1337, 2545, +-1887, -2821, -1482, -2829, 1255, 2189, 1501, 3176, +-961, -1546, -1285, -3490, 782, 978, 1216, 3654, +-876, -618, -1094, -3650, 837, 421, 1062, 3485, +-652, -420, -943, -3151, 328, 423, 683, 2670, +83, -399, -373, -2115, -244, 334, -76, 1452, +392, -309, 392, -759, -347, 374, -606, -78, +406, -454, 760, 916, -577, 401, -745, -1710, +864, -138, 746, 2275, -1147, -305, -579, -2613, +1327, 816, 405, 2715, -1237, -1382, -138, -2586, +1207, 1799, -221, 2216, -958, -2004, 513, -1721, +884, 1918, -550, 1256, -732, -1634, 358, -1007, +601, 1208, 326, 1069, -320, -787, -1068, -1368, +23, 334, 1996, 1711, 288, 101, -2449, -1996, +-451, -549, 2830, 2140, 528, 923, -2837, -2223, +-376, -1234, 2940, 2271, 461, 1451, -3038, -2287, +-509, -1638, 3343, 2093, 981, 1907, -3519, -1859, +-1220, -2219, 3497, 1698, 1686, 2376, -3068, -1736, +-1665, -2282, 2474, 1790, 1698, 1995, -1531, -1696, +-1575, -1723, 952, 1312, 1758, 1502, -348, -610, +-1990, -1484, 336, -241, 2384, 1650, -131, 963, +-2443, -2047, 102, -1289, 2370, 2396, 447, 1156, +-1714, -2365, -1063, -894, 1272, 1688, 1937, 864, +-725, -613, -2303, -1281, 740, -341, 2520, 1809, +-687, 714, -2207, -2084, 958, -568, 2166, 1873, +-769, 224, -2072, -1457, 609, -71, 2352, 1148, +174, 160, -2275, -1096, -967, -417, 2377, 1038, +1956, 753, -1982, -858, -2365, -1191, 1853, 656, +2542, 1519, -1432, -784, -2080, -1437, 1333, 1237, +1961, 702, -1064, -1703, -1813, 327, 1089, 1805, +2371, -1097, -947, -1551, -2668, 1166, 1052, 1249, +2982, -779, -708, -1169, -2757, 460, 748, 1156, +2463, -536, -627, -1069, -1730, 825, 1002, 922, +1173, -1046, -1095, -1007, -463, 1111, 1345, 1266, +235, -1055, -1131, -1469, -10, 717, 1219, 1399, +76, 14, -1116, -1278, 209, -1007, 1394, 1426, +-418, 1626, -1396, -1752, 972, -1562, 1380, 1735, +-1009, 1112, -1035, -1168, 1139, -1000, 722, 413, +-822, 1376, -156, -35, 723, -1781, -146, -54, +-410, 1769, 430, 237, 455, -1515, -263, -715, +-381, 1439, 77, 1047, 664, -1620, 234, -827, +-689, 1586, -282, 216, 756, -1113, 518, 268, +-686, 462, -460, -513, 757, 1, 611, 724, +-850, -394, -346, -1003, 962, 957, 144, 968, +-658, -1558, 154, -400, 234, 1605, -133, -336, +451, -900, -65, 585, -795, -177, 415, -135, +1043, 918, -605, -597, -992, -1146, 781, 1066, +924, 1152, -723, -1218, -683, -1223, 598, 1272, +570, 1253, -357, -1348, -272, -1073, 78, 1200, +27, 853, 296, -868, 348, -894, -688, 599, +-641, 1163, 1190, -672, 806, -1309, -1585, 918, +-716, 1007, 1773, -904, 638, -437, -1643, 434, +-717, -34, 1567, 224, 891, 82, -1574, -554, +-964, 6, 1851, 447, 548, 117, -1935, -355, +45, -469, 1849, 595, -588, 761, -1605, -1093, +776, -838, 1407, 1418, -642, 830, -1348, -1349, +564, -1006, 1049, 1035, -404, 1280, -595, -784, +246, -1376, -7, 622, 57, 1141, 222, -459, +-325, -810, -48, 316, 388, 598, -429, -419, +-358, -363, 872, 578, 319, -40, -1093, -503, +-494, 438, 1212, 104, 511, -616, -1052, 287, +-473, 541, 659, -294, 336, -554, -231, -10, +-473, 743, 65, 280, 728, -897, -494, -337, +-854, 658, 1013, 409, 707, -210, -1286, -625, +-455, -26, 1009, 727, 298, -106, -422, -484, +-387, 352, -120, -20, 444, -402, 388, 374, +-468, 276, -548, -467, 449, -91, 529, 428, +-630, -150, -410, -443, 819, 546, 108, 376, +-743, -919, -33, -71, 453, 732, 291, -165, +-139, 28, -792, -74, 23, -818, 1078, 645, +-33, 1047, -1066, -956, -94, -792, 781, 610, +274, 618, -443, 54, -562, -845, 125, -476, +822, 1270, 211, 489, -1231, -1575, -289, -393, +1616, 1737, 129, 419, -1786, -1900, 200, -439, +1478, 1963, -359, 271, -890, -1670, 97, -42, +403, 982, 293, -38, -230, -196, -424, -199, +164, -359, 217, 624, 270, 513, 29, -990, +-966, -448, 73, 1089, 1624, 460, -291, -914, +-1930, -693, 306, 602, 1935, 1071, 52, -370, +-1881, -1285, -583, 255, 1907, 1165, 865, -235, +-1732, -816, -933, 298, 1486, 482, 1017, -495, +-1147, -273, -1116, 719, 1084, 154, 1235, -772, +-1115, -113, -1033, 565, 953, 140, 759, -320, +-548, -55, -465, 198, 39, -302, 300, -211, +383, 922, -53, 138, -685, -1544, -19, 177, +1063, 1730, 18, -512, -1323, -1453, 331, 579, +1469, 1063, -668, -395, -1202, -841, 701, 240, +810, 641, -231, -193, -420, -220, -581, 11, +382, -354, 1290, 450, -350, 784, -1593, -1123, +422, -745, 1686, 1635, -429, 284, -1323, -1784, +571, 381, 825, 1539, -535, -980, -220, -1096, +310, 1485, -113, 458, 113, -1738, 170, 289, +-390, 1624, -165, -879, 601, -1350, 477, 1224, +-643, 1115, -881, -1356, 850, -1093, 1390, 1463, +-1005, 1180, -1396, -1625, 1086, -1226, 1238, 1818, +-964, 1096, -920, -1931, 855, -839, 755, 1859, +-960, 620, -404, -1740, 1200, -416, -73, 1592, +-1098, 139, 661, -1344, 827, 176, -921, 983, +-289, -410, 974, -592, 81, 468, -911, 316, +116, -274, 810, -312, -157, -24, -696, 566, +301, 248, 478, -835, -308, -367, -272, 889, +318, 536, 316, -718, -208, -809, -311, 432, +230, 1074, 318, -105, -80, -1178, 47, -265, +-238, 1030, -411, 783, 765, -778, 628, -1396, +-1200, 592, -533, 1879, 1320, -434, 399, -1997, +-1126, 19, -383, 1885, 1066, 693, 692, -1706, +-1145, -1518, -876, 1451, 1385, 2211, 1115, -1043, +-1475, -2593, -1048, 412, 1179, 2616, 1000, 330, +-625, -2205, -901, -1089, 17, 1353, 728, 1842, +551, -319, -478, -2447, -833, -589, 209, 2668, +1066, 1161, 108, -2283, -963, -1524, -392, 1427, +838, 1758, 757, -491, -580, -1733, -1132, -296, +268, 1310, 1445, 838, 169, -473, -1673, -1162, +-728, -608, 1749, 1201, 1335, 1706, -1467, -925, +-1873, -2609, 1036, 412, 2194, 3069, -174, 211, +-2277, -2909, -701, -715, 2062, 2041, 1616, 989, +-1746, -652, -2207, -941, 1226, -876, 2361, 600, +-676, 1938, -2128, 135, 281, -2225, 1451, -1197, +-43, 1692, -407, 2320, -15, -562, -568, -3098, +26, -841, 1163, 3213, 220, 2221, -1281, -2633, +-643, -3193, 1017, 1439, 1031, 3541, -701, 112, +-1131, -3144, 202, -1730, 848, 2166, 355, 3034, +-378, -853, -800, -3685, 19, -550, 864, 3630, +232, 1669, -218, -3047, -492, -2097, -832, 2159, +786, 1671, 1779, -1197, -985, -668, -2169, 535, +617, -498, 1908, -411, 103, 1338, -1218, 917, +-781, -1581, 142, -1765, 1045, 1100, 1207, 2500, +-751, 9, -2490, -2620, 117, -1514, 3296, 2024, +804, 2977, -3445, -973, -1883, -3817, 2942, -185, +2892, 3767, -2243, 1108, -3616, -3026, 1478, -1579, +3888, 2098, -783, 1508, -3800, -1488, 128, -1127, +3708, 1544, 452, 730, -3635, -2162, -880, -669, +3502, 2973, 1296, 1085, -3111, -3468, -1888, -1835, +2463, 3124, 2508, 2737, -1768, -1878, -3098, -3515, +1233, 167, 3217, 3858, -770, 1292, -2976, -3352, +429, -2141, 2608, 1994, -110, 2375, -2208, -318, +-193, -2173, 2013, -894, 410, 1708, -1799, 1065, +-691, -1106, 1456, -290, 996, 614, -1041, -785, +-1173, -560, 268, 1454, 1241, 1079, 723, -1351, +-1006, -1805, -1797, 497, 574, 2055, 2674, 846, +195, -1381, -2987, -2112, -1188, -204, 2747, 2635, +2007, 2228, -1872, -1992, -2472, -3880, 657, 298, +2114, 4382, 721, 1791, -1140, -3351, -1732, -3374, +-209, 1091, 2117, 3696, 1479, 1481, -1500, -2541, +-2271, -3234, 193, 232, 2496, 3501, 1277, 2388, +-1991, -2350, -2383, -4312, 1003, 353, 2705, 4943, +167, 1580, -2378, -4224, -1038, -2724, 1566, 2621, +1414, 2777, -490, -853, -1406, -1958, -293, -472, +1133, 771, 765, 1110, -682, 260, -792, -1171, +-2, -859, 762, 952, 721, 1073, -754, -694, +-1309, -1111, 590, 414, 1626, 1112, -37, 35, +-1658, -1119, -994, -692, 1544, 1033, 2133, 1302, +-1056, -647, -2828, -1495, 232, -133, 2762, 977, +801, 1122, -1758, 190, -1707, -1797, 244, -1717, +1912, 1683, 1331, 3099, -1505, -656, -2242, -3791, +656, -866, 2018, 3448, 237, 2167, -697, -2060, +-793, -2695, -1043, 189, 827, 2239, 2393, 1370, +-173, -992, -2861, -1962, -834, -539, 2318, 1552, +1673, 1627, -1149, -529, -1790, -1704, -374, -471, +1152, 725, 1583, 873, -15, 808, -2035, -454, +-1115, -2062, 1590, -616, 1830, 2467, -299, 1755, +-2215, -1919, -920, -2351, 2042, 860, 1717, 2050, +-1601, 86, -1815, -979, 999, -479, 1348, -287, +-519, 126, -711, 1112, 495, 843, -164, -1227, +-620, -1960, 872, 678, 900, 2602, -1248, 302, +-1053, -2431, 1043, -1328, 1034, 1443, -258, 2092, +-883, -3, -792, -2425, 466, -1374, 1637, 2260, +205, 2282, -2013, -1591, -1126, -2637, 1857, 648, +1957, 2411, -1380, 263, -2297, -1543, 752, -913, +2108, 236, -370, 1112, -1427, 998, 329, -742, +774, -1618, -737, -114, -503, 1383, 1168, 976, +811, -506, -1276, -1200, -1473, -553, 680, 434, +1899, 1232, 552, 1054, -1594, -1064, -1891, -2521, +335, -27, 2695, 3147, 1414, 1637, -2410, -2508, +-2849, -2917, 990, 867, 3143, 3013, 905, 1093, +-2119, -1732, -2318, -2443, 134, -169, 2383, 2415, +1900, 1583, -1172, -947, -2908, -1737, -548, -1140, +2250, 590, 1829, 2647, -280, 1166, -1912, -2784, +-1862, -2521, 898, 1656, 2687, 2707, 651, -151, +-1784, -1563, -1679, -763, -325, -258, 1361, 651, +2297, 1614, 177, 294, -2822, -1603, -2238, -1439, +1730, 329, 3489, 2009, 328, 1312, -3087, -1575, +-2107, -2317, 1281, 440, 2495, 2207, 897, 574, +-1370, -1175, -2066, -806, -642, -63, 1564, 250, +2285, 694, 152, 542, -2455, -361, -1997, -859, +1013, -630, 2823, 361, 1162, 1492, -1993, 683, +-2774, -1402, 26, -1675, 2814, 156, 2043, 2066, +-1429, 1533, -2909, -1554, -537, -2514, 1933, 302, +2056, 2149, 133, 1124, -2312, -766, -2021, -1972, +1343, -584, 2602, 1802, 142, 1030, -1658, -884, +-1117, -402, 83, 47, 765, -764, 1165, 86, +657, 1592, -1389, 505, -2076, -1379, 506, -1387, +2514, 220, 690, 1876, -1585, 1143, -1395, -1477, +45, -1880, 964, 321, 1177, 1565, 355, 840, +-1297, -455, -1669, -1161, 443, -690, 2073, 438, +600, 980, -1208, 751, -1079, 41, -206, -1490, +435, -1883, 1252, 1207, 789, 3292, -978, 89, +-2061, -3257, -200, -1676, 2341, 1772, 1540, 2489, +-1376, 336, -2141, -1936, -222, -1861, 1483, 273, +1596, 2049, -60, 1545, -1754, -1004, -1493, -2412, +737, -528, 2202, 1832, 717, 1711, -1666, -284, +-1679, -1981, 176, -1140, 1552, 1199, 1446, 1655, +-563, 173, -2239, -1246, -649, -1325, 1851, 460, +1426, 1643, -825, 196, -1355, -1299, -92, -369, +555, 932, 350, -28, 309, -901, 18, 728, +-696, 991, -668, -1197, 516, -836, 1011, 1058, +-43, 351, -922, -479, -258, 268, 552, -16, +49, -745, -204, 148, 328, 928, 309, -121, +-703, -662, -763, 211, 507, 55, 1361, -407, +120, 517, -1596, 511, -1035, -699, 1072, -380, +1851, 547, -105, 35, -1934, -401, -1024, 309, +1110, 525, 1626, -433, 324, -832, -1347, 261, +-1643, 1030, 143, 23, 2032, -937, 1349, -178, +-1220, 681, -2347, 192, -479, -627, 2102, -173, +2115, 945, -686, 238, -2779, -1242, -1245, -556, +2000, 1098, 2566, 1093, -316, -509, -2419, -1382, +-1462, -164, 882, 934, 2090, 561, 1159, 208, +-1325, -447, -2547, -1431, -333, -83, 2389, 1968, +1576, 656, -958, -1487, -1507, -842, -778, 400, +132, 501, 1397, 409, 1584, 172, -546, -419, +-2317, -736, -1191, -77, 1400, 773, 2403, 392, +543, -244, -2109, -280, -2211, -274, 451, 123, +2306, 137, 1203, -320, -719, 555, -1556, 1006, +-1553, -963, 133, -1785, 2925, 398, 1960, 1999, +-2293, 1015, -3502, -1248, -29, -2372, 3370, -166, +2530, 2656, -1643, 1544, -3797, -1725, -811, -2098, +3137, 303, 2645, 1404, -1158, 657, -2998, 78, +-1011, -683, 1843, -1278, 2238, -83, -35, 1329, +-2109, 905, -1282, -316, 857, -940, 1371, -958, +609, -75, -148, 1550, -1479, 1625, -1732, -1096, +1105, -2709, 3179, 155, 317, 2590, -3453, 407, +-1992, -1291, 2139, -99, 2889, -142, -35, -713, +-2451, 548, -1707, 1393, 808, 322, 2016, -1368, +1022, -1605, -728, 547, -1994, 2142, -1173, 638, +1493, -1445, 2321, -1401, 50, -182, -1902, 1101, +-1349, 1751, 271, 113, 1374, -2389, 1267, -1521, +-76, 1786, -1495, 2114, -1583, -464, 353, -1598, +2138, -751, 1297, 441, -1180, 1088, -2313, 389, +-562, -350, 1925, -278, 1697, -889, -529, -637, +-1526, 1708, -921, 1772, 300, -1426, 1314, -2389, +986, 383, -393, 2153, -1608, 802, -1010, -1113, +1253, -1456, 2054, -161, -210, 1302, -2140, 1196, +-866, -488, 1414, -1565, 1576, -446, -289, 1156, +-1581, 851, -735, -370, 922, -534, 1243, -186, +-35, -376, -1051, 37, -527, 1248, 106, 547, +327, -1582, 849, -1116, 543, 1096, -1209, 1163, +-1590, -219, 551, -755, 2072, -338, 571, 245, +-1558, 223, -1209, -21, 206, 250, 910, 223, +1132, -361, 253, -478, -1645, -16, -1316, 515, +1300, 696, 1583, -94, -476, -1124, -1082, -433, +108, 1200, 361, 802, -413, -976, -3, -692, +923, 677, 88, 300, -1097, -325, -438, -16, +647, -106, 612, -120, -163, 354, -493, 168, +-8, -243, 52, -203, -130, -310, 226, -289, +278, 599, -75, 1263, -119, -165, -317, -2062, +-246, -1077, 787, 1578, 604, 2246, -784, 283, +-694, -2341, 405, -2302, 715, 1106, 123, 2927, +-622, 701, -501, -1569, 343, -1574, 672, -371, +193, 1045, -804, 1317, -971, 234, 683, -619, +1505, -650, -234, -523, -1649, -173, -480, 998, +1084, 1385, 858, -667, -82, -1852, -526, 289, +-761, 1469, -504, -478, 879, -1161, 1723, 815, +6, 1246, -2107, -711, -1334, -1481, 1447, -283, +2263, 972, 104, 1336, -1858, 163, -1509, -1655, +321, -1341, 1938, 981, 1276, 1681, -1226, -68, +-1840, -1113, -195, -398, 1091, 305, 1119, 404, +124, 348, -1128, -94, -1072, -622, 323, -126, +1041, 660, 513, 379, -259, -116, -783, -237, +-799, -601, 417, -343, 1525, 1028, 486, 1171, +-1520, -631, -1189, -1391, 846, -222, 1507, 583, +324, 628, -1161, 487, -1194, -266, 350, -807, +1265, -469, 541, -74, -319, 411, -1015, 876, +-1076, 307, 436, -721, 1842, -914, 711, -299, +-1452, 448, -1717, 685, -109, 374, 1647, 147, +1523, -324, -694, -1210, -1830, -806, -426, 1210, +953, 1948, 859, -25, 276, -1649, -299, -668, +-804, 333, -409, 197, 477, 761, 725, 931, +332, -334, -336, -1059, -632, -691, -257, -18, +295, 888, 483, 1227, 432, 128, -492, -1302, +-937, -1163, 188, 266, 1043, 981, -75, 529, +-1013, -177, -88, -595, 660, -385, 175, 132, +-267, 43, -93, -27, -208, 304, -295, -12, +426, -300, 743, 117, -179, 109, -694, -259, +-259, -338, 212, 87, 636, 868, 435, 535, +-449, -788, -561, -1004, 50, 53, 221, 1109, +69, 926, 184, -642, 384, -1071, -331, 380, +-965, 668, -153, -397, 965, -186, 475, 667, +-401, 201, -424, -730, -467, -477, -138, 571, +697, 741, 624, -368, -435, -1140, -546, -77, +10, 1364, 64, 463, 73, -1221, 494, -720, +283, 287, -532, 325, -414, 518, 165, 186, +283, -617, 167, -481, 124, -32, 33, 258, +-281, 555, -429, 204, -60, -443, 400, -468, +385, 121, 70, 618, -420, 113, -581, -681, +-76, 101, 436, 1093, 237, -75, -36, -1381, +-22, -208, -143, 1478, -421, 669, -64, -1105, +538, -638, 416, 645, -424, 204, -402, -451, +415, -24, 438, 471, -330, 345, -532, -485, +178, -946, 529, -143, 181, 808, -81, 1013, +-327, -5, -607, -1635, 88, -997, 817, 1231, +276, 1071, -552, -487, -577, -379, 36, 262, +429, -91, 227, -665, -351, -413, -300, 704, +280, 1322, 302, 395, -388, -1125, -368, -1487, +511, 24, 532, 1442, -437, 875, -691, -140, +138, -451, 971, -601, 608, -285, -1013, 88, +-1243, 253, 629, 915, 1293, 557, 236, -1117, +-463, -915, -857, 542, -717, 43, 440, -410, +1331, 984, 441, 960, -1045, -1116, -1019, -1623, +267, 155, 645, 1219, -27, 422, -73, -253, +196, -175, 32, -364, -316, -342, -384, 83, +113, 243, 505, 446, -30, 316, -193, -539, +545, -524, 90, 459, -889, 459, -519, -262, +780, -259, 976, 113, -272, 197, -683, 133, +92, 186, -78, 138, -533, -521, 478, -712, +1068, 474, -174, 1027, -1255, -132, -647, -774, +828, 68, 1088, 398, -144, -490, -963, -423, +-442, 631, 297, 328, 555, -395, 332, 43, +-165, -49, -382, -571, -327, 96, 67, 514, +491, -30, 298, -65, -38, -16, -383, -302, +-415, -27, 304, 261, 709, 158, -135, 88, +-838, -204, -193, -381, 843, 88, 695, 720, +-628, 488, -1099, -751, -66, -903, 911, 524, +647, 814, -239, -109, -639, -124, -449, 122, +-87, -350, 451, -518, 888, 107, 158, 800, +-1053, 550, -783, -649, 510, -952, 1075, 142, +216, 663, -802, 107, -486, -282, 316, -105, +360, 54, 244, -159, 18, -89, -584, 178, +-481, -131, 549, 21, 864, 602, -213, -225, +-898, -1023, -179, 158, 373, 1014, 106, 40, +193, -550, 368, 180, -311, 299, -860, -583, +-144, -387, 883, 849, 674, 670, -528, -576, +-857, -575, 181, 203, 769, 497, 194, 169, +-486, -625, -543, -506, 115, 601, 713, 601, +376, -95, -381, -184, -564, -364, -95, -493, +217, -33, 147, 322, 306, 538, 337, 506, +-529, -427, -906, -959, 250, -119, 1007, 378, +118, -45, -783, -14, -372, 508, 345, 576, +396, -215, 163, -1030, -17, -637, -603, 346, +-762, 724, 711, 708, 1427, 349, -259, -636, +-1349, -1049, -243, 28, 691, 858, 314, 147, +-55, -405, -2, 131, -27, 493, -274, 213, +-170, -400, 200, -846, 329, -239, 74, 806, +-292, 664, -377, -213, 38, -367, 498, -95, +215, -175, -363, -233, -396, 122, 53, 399, +416, 67, 79, -303, -291, -117, -34, 102, +41, 64, -34, -123, 336, -327, 216, 6, +-552, 543, -570, 376, 237, -285, 886, -752, +544, -336, -612, 826, -1143, 908, -164, -388, +935, -814, 802, -68, -125, 204, -712, 297, +-560, 601, -35, -67, 505, -920, 735, -182, +15, 854, -769, 327, -460, -538, 184, -216, +417, 187, 294, -109, -1, 8, -301, 397, +-322, 44, 129, -382, 488, -203, -223, -16, +-685, -42, 403, 61, 1055, 341, -178, 409, +-1208, -265, -351, -1014, 819, -351, 717, 944, +-179, 752, -602, -378, -220, -629, 247, -34, +160, 309, -54, 28, 97, -210, 139, 1, +-352, 322, -251, 460, 407, -153, 210, -959, +-277, -229, -176, 926, -4, 439, 304, -288, +405, 1, -390, 13, -737, -427, 159, -408, +753, 68, 174, 705, -362, 797, -124, -121, +21, -974, -318, -752, -182, 193, 628, 754, +719, 366, -437, -69, -1156, -85, -113, -337, +1305, -457, 570, 40, -1232, 442, -786, 219, +912, -234, 865, -106, -458, 348, -836, -22, +145, -643, 680, -276, -162, 471, -479, 668, +324, 263, 417, -485, -299, -797, -576, -218, +14, 460, 691, 663, 367, 437, -568, -146, +-531, -718, 329, -811, 375, 6, -213, 1183, +-222, 891, 229, -683, 281, -1129, -174, 33, +-313, 959, -81, 229, 119, -804, 228, -211, +-42, 467, -119, 17, 443, 157, 19, 441, +-969, -468, -274, -831, 944, 26, 634, 560, +-272, 537, -638, 218, -324, -435, 174, -629, +442, -111, 110, 361, -201, 355, -63, -38, +173, -196, -27, 131, -456, 158, -136, -324, +545, -436, 444, 263, -302, 545, -365, -275, +22, -331, -50, 505, -158, 159, 417, -521, +460, -268, -342, -120, -533, 152, -19, 829, +378, 395, 278, -805, -218, -840, -271, 144, +59, 686, 72, 266, 82, -299, 173, -13, +-55, 344, -379, -297, -146, -606, 346, 249, +263, 598, -165, -68, -169, -198, 86, 260, +16, -2, -184, -496, -91, -232, 290, 371, +306, 661, -304, 118, -474, -733, 259, -456, +453, 340, -113, 427, -244, 142, -171, -311, +42, -461, 349, 196, 65, 497, -267, -127, +-77, -425, 139, 5, 61, 161, -168, -148, +-52, -10, 180, 424, -33, 41, -36, -572, +184, -146, -122, 423, -288, 116, 122, -288, +147, -127, -5, 377, 33, 367, -12, -344, +-11, -380, -13, 146, -269, 61, 34, 102, +403, 316, 18, -17, -214, -229, -37, -135, +37, 43, -26, 265, -97, 63, 111, -218, +239, -137, -118, -40, -235, 169, 11, 377, +270, 126, 98, -411, -442, -786, -299, -221, +559, 1072, 482, 929, -355, -709, -577, -1181, +-127, -157, 564, 756, 545, 731, -547, -166, +-755, -709, 536, -367, 779, 122, -296, 509, +-714, 382, -86, -142, 614, -243, 310, -371, +-387, -318, -237, 591, 173, 745, 2, -389, +-154, -665, 239, 372, 449, 667, -432, -415, +-906, -824, 389, 289, 1265, 925, -75, 175, +-1262, -553, -421, -463, 886, 138, 720, 440, +-395, -117, -624, -315, 64, 363, 309, 236, +-94, -544, 11, -323, 273, 477, -4, 426, +-435, -519, -106, -658, 549, 431, 81, 676, +-481, -143, 92, -494, 325, -424, -245, 81, +-167, 799, 292, 287, 176, -828, -237, -577, +-200, 556, 145, 767, 9, -113, -181, -672, +113, -186, 366, 328, 144, 227, -334, 220, +-668, 212, -111, -375, 775, -717, 515, -1, +-322, 985, -348, 766, -173, -631, -33, -1126, +321, 10, 113, 815, -241, 264, -56, -250, +268, 50, 170, -16, -118, -497, -235, -87, +-188, 465, -70, 88, 316, -206, 411, -63, +-130, 25, -341, 108, -79, -57, 45, -326, +46, -17, 87, 372, 16, 122, -112, -231, +-47, -285, 168, -29, 182, 457, -144, 353, +-375, -399, -28, -605, 384, 0, 378, 595, +-248, 426, -700, -239, 57, -319, 887, 49, +291, -15, -663, -196, -654, 138, 104, 504, +681, 28, 287, -605, -313, -93, -141, 645, +55, 91, -284, -734, -215, -263, 485, 672, +486, 574, -417, -354, -601, -756, 190, -73, +673, 518, 29, 317, -646, 17, -320, -392, +468, -587, 502, 268, -171, 757, -466, -39, +-23, -544, 358, -273, 201, 141, -218, 476, +-355, 269, -48, -399, 318, -624, 401, -30, +79, 722, -505, 590, -488, -426, 152, -813, +471, 15, 325, 618, -58, 233, -429, -295, +-471, -239, 102, 123, 703, 130, 395, 4, +-596, 92, -791, -56, 318, -288, 981, -141, +-21, 261, -928, 488, -237, -13, 716, -617, +419, -295, -350, 315, -375, 515, 80, 245, +118, -546, -61, -771, 63, 201, 276, 877, +95, 341, -378, -419, -360, -552, 72, -237, +376, 79, 350, 410, -44, 653, -489, 21, +-314, -977, 241, -631, 313, 574, 65, 931, +86, 240, -126, -693, -577, -864, -180, -36, +749, 820, 647, 752, -458, -187, -838, -750, +36, -404, 599, -18, 130, 452, -181, 801, +-28, -58, -2, -931, -64, -286, 26, 527, +36, 367, -126, 30, -102, -199, 233, -396, +289, -193, -145, 372, -329, 685, -28, 37, +6, -876, 35, -430, 282, 599, 103, 442, +-197, -209, -134, -182, -147, 96, -7, -46, +322, -167, 145, 187, -201, 165, -88, -389, +47, -257, -69, 454, -46, 499, 221, -137, +177, -555, -191, -457, -341, 79, -16, 795, +414, 612, 305, -657, -295, -979, -517, 346, +34, 896, 394, -234, 211, -630, 29, 308, +-241, 436, -460, -339, -43, -380, 503, 253, +412, 422, -62, -22, -506, -319, -496, -196, +131, -5, 705, 136, 464, 279, -437, 290, +-732, -137, -50, -589, 557, -230, 344, 358, +-192, 258, -324, 90, -14, 163, 162, -197, +47, -510, -63, -5, -67, 308, -33, 29, +178, 240, 147, 234, -223, -710, -278, -587, +112, 810, 252, 775, 34, -541, -70, -670, +-21, 73, -78, 221, -141, 133, 93, 190, +195, 143, 40, -149, -6, -489, -144, -191, +-233, 366, 28, 283, 346, 85, 273, 61, +-197, -176, -553, -365, -116, -281, 524, 213, +384, 883, -101, 416, -459, -1018, -497, -1087, +240, 465, 941, 1263, 175, 436, -927, -665, +-567, -895, 448, -323, 648, 379, 117, 849, +-322, 586, -331, -490, -56, -1026, 156, -361, +90, 586, 64, 860, 209, 123, -41, -705, +-459, -565, -119, 147, 571, 642, 194, 384, +-643, -476, -269, -682, 689, 89, 477, 627, +-450, 382, -696, -231, -134, -642, 668, -232, +698, 593, -307, 500, -925, -387, -134, -508, +668, 335, 377, 425, -159, -394, -211, -235, +-186, 354, -258, -86, 112, -125, 587, 425, +272, -42, -439, -486, -531, 13, -31, 245, +507, 5, 387, 5, -351, 104, -428, -59, +261, -248, 359, -36, -211, 230, -309, 51, +50, -169, 261, -45, 198, 135, -77, 124, +-443, -131, -234, -229, 498, 128, 539, 137, +-295, -133, -625, 88, -44, 96, 429, -176, +293, 65, -108, 78, -279, -239, -133, -17, +79, 316, 312, 154, 195, -230, -384, -301, +-442, 65, 249, 269, 482, 81, 159, -3, +-153, 13, -464, -226, -444, -340, 312, 66, +803, 503, 198, 474, -674, -99, -522, -820, +312, -694, 552, 504, -180, 1081, -572, 18, +202, -689, 733, -13, -46, 52, -747, -511, +-205, 82, 365, 843, 285, 247, 66, -706, +-54, -539, -159, 390, -173, 559, 2, -155, +212, -455, 112, -20, -76, 352, -55, 143, +-207, -274, -100, -201, 556, 301, 341, 367, +-662, -274, -638, -626, 385, -39, 742, 671, +74, 480, -577, -271, -285, -524, 308, -233, +202, 66, -93, 275, 18, 346, -2, 233, +-216, -230, -79, -772, 353, -280, 329, 754, +-197, 653, -471, -239, -235, -609, 234, -232, +620, 307, 306, 275, -636, -174, -686, -114, +244, 329, 670, 121, 148, -481, -307, -321, +-256, 399, -156, 455, 78, -200, 436, -367, +124, 19, -472, 98, -96, 236, 298, 292, +-67, -471, -41, -623, 178, 470, -185, 663, +-157, -287, 298, -361, 130, 211, -219, -14, +-88, -268, 102, 257, 36, 334, -121, -333, +-16, -425, 189, 252, 127, 530, -122, -34, +-218, -475, -39, -106, 167, 271, 61, -46, +-62, -291, 64, 198, 32, 549, -98, 38, +-96, -591, -85, -488, 133, 161, 339, 455, +-15, 305, -432, 159, -217, -368, 297, -669, +409, 108, -100, 529, -405, 6, 111, -54, +348, 264, -276, -65, -481, -625, 303, -295, +747, 643, -61, 636, -809, -339, -168, -530, +622, 196, 186, 266, -408, -336, -245, -354, +249, 387, 470, 786, -7, -68, -661, -928, +-325, -284, 574, 549, 535, 333, -325, -141, +-532, -188, 160, 64, 399, 78, -179, -100, +-227, 9, 312, 18, 209, -197, -405, -37, +-370, 263, 269, 217, 532, -98, 122, -312, +-383, -132, -478, 45, -11, 73, 575, 345, +238, 231, -431, -493, -187, -393, 227, 291, +-82, 197, -9, 52, 376, 122, 23, -224, +-633, -260, -365, 162, 619, 301, 815, 53, +-265, -323, -896, -227, -194, 222, 536, 292, +481, 156, -79, -87, -533, -461, -156, -320, +446, 300, 206, 612, -247, 231, -175, -523, +3, -655, 101, 183, 150, 687, 16, 114, +-122, -502, -128, -341, -140, 238, 51, 366, +437, 1, 316, -48, -494, -168, -752, -540, +146, -8, 788, 792, 336, 450, -403, -453, +-450, -759, -32, -98, 230, 556, 68, 335, +15, 48, 139, -100, -29, -507, -308, -323, +-77, 514, 401, 684, 212, -77, -394, -716, +-402, -335, 237, 528, 480, 456, 81, -200, +-359, -183, -279, -85, 123, -108, 230, 247, +-65, 217, -112, -102, 181, -110, 114, -295, +-324, -150, -199, 618, 390, 485, 211, -673, +-410, -856, -187, 422, 432, 959, 263, -105, +-343, -802, -456, -278, 87, 369, 605, 505, +248, 51, -467, -495, -464, -265, 134, 152, +384, 15, 165, 206, -103, 537, -226, -185, +-151, -901, 133, -285, 182, 786, -107, 844, +20, -253, 219, -886, -276, -206, -433, 514, +436, 428, 554, -75, -365, -313, -540, -29, +211, 166, 384, 24, -88, -55, -245, -19, +47, 72, 197, 21, 71, -137, -200, 52, +-291, 160, 185, -208, 490, -148, -140, 278, +-507, 52, 113, -217, 366, -120, -153, -191, +-170, 226, 224, 630, -1, -275, -313, -879, +133, 46, 338, 668, -188, 95, -281, -261, +102, 28, 79, -76, 120, -271, 209, 178, +-257, 318, -458, -83, 168, -118, 541, -10, +78, 15, -441, 179, -253, 12, 319, -280, +224, 93, -214, 373, -158, -82, 162, -211, +165, 132, -116, 43, -242, -206, 161, 36, +276, 314, -272, -22, -283, -272, 346, 125, +308, 138, -238, -307, -381, -221, -45, 169, +343, 335, 343, 177, -29, -202, -429, -422, +-415, -394, 186, 37, 627, 650, 198, 473, +-348, -292, -346, -564, -161, -378, 164, -6, +376, 519, 162, 450, -121, -132, -230, -234, +-281, -215, -50, -283, 424, 197, 430, 514, +-260, 89, -610, -213, 43, -121, 468, -83, +40, 52, -187, 392, -45, 71, -58, -608, +94, -49, 194, 776, -77, 184, -238, -537, +-85, -327, 109, 67, 247, 275, 117, 244, +-123, 9, -138, -153, -204, -283, -145, -243, +275, 151, 538, 375, 48, 193, -616, -199, +-432, -628, 332, -287, 479, 680, 16, 620, +-249, -414, -198, -875, 62, -110, 201, 872, +-74, 422, -139, -641, 222, -421, 156, 221, +-367, 194, -389, 102, 389, 122, 741, -7, +-188, -279, -895, -260, -95, 324, 637, 542, +191, -61, -163, -423, -57, -196, -57, 145, +-158, 454, -12, 243, 222, -400, 184, -408, +-172, 139, -277, 378, 82, 185, 327, -124, +92, -245, -337, -329, -270, -115, 142, 660, +253, 521, 177, -613, 39, -743, -327, 11, +-326, 458, 124, 435, 278, -56, 184, -473, +119, -318, -306, 61, -482, 349, 146, 208, +611, -266, 102, -264, -574, 89, -269, 219, +515, 222, 346, -170, -444, -575, -358, 78, +337, 767, 327, 228, -146, -491, -287, -393, +-21, 161, 160, 387, 108, 85, -47, -108, +-21, -17, 50, 60, -127, -61, -234, -253, +172, 174, 407, 623, -84, -144, -400, -833, +-21, -106, 235, 749, 31, 465, -64, -483, +-27, -727, -21, 138, 5, 597, 94, -56, +-23, -402, -129, 10, -2, 217, 153, -8, +50, -252, -56, -107, -123, 172, -192, -42, +60, -103, 432, 316, 244, 186, -384, -402, +-556, -469, -16, 96, 525, 610, 384, 390, +-165, -263, -401, -537, -146, -167, 233, 430, +241, 434, -191, -143, -356, -310, 212, 92, +567, 223, 10, -114, -586, -176, -329, 251, +213, 289, 352, -271, 217, -388, -19, 151, +-291, 407, -311, 73, 42, -330, 311, -272, +231, 172, -98, 187, -306, -178, -161, -91, +236, 151, 344, 37, -115, -186, -454, -225, +5, 103, 473, 294, 28, -110, -461, -318, +-27, 44, 494, 283, 80, 70, -471, -285, +-245, -329, 356, 142, 386, 621, -133, 283, +-420, -570, -40, -610, 363, 179, 112, 527, +-247, 319, -106, 168, 117, -195, 28, -662, +-18, -355, 88, 521, 76, 905, -175, 256, +-291, -855, 129, -859, 494, 404, 50, 976, +-482, 58, -192, -787, 282, -318, 159, 458, +-124, 290, -5, -150, 99, -204, -40, -191, +-78, 40, -37, 240, -122, -135, 54, -259, +338, 230, 75, 261, -308, -264, -189, -368, +117, 41, 143, 281, -58, 68, -125, -151, +181, 54, 276, 229, -137, -108, -391, -428, +-205, -97, 159, 503, 452, 473, 295, -129, +-253, -403, -503, -215, -164, 84, 283, 333, +302, 261, 37, -44, -26, -172, -62, -141, +-356, -111, -206, 87, 478, 441, 547, 276, +-291, -515, -809, -733, -58, 151, 858, 928, +475, 403, -659, -742, -781, -814, 221, 172, +815, 577, 189, 114, -532, -109, -332, -83, +148, -258, 214, -210, 59, 77, -97, 238, +-31, 277, 112, -69, -59, -552, -184, -215, +97, 567, 176, 474, -116, -321, -153, -482, +114, 46, 239, 284, -79, 176, -326, 102, +15, -33, 306, -121, 24, -67, -271, -26, +-94, 34, 285, 200, 316, 299, -240, 39, +-531, -432, -18, -359, 469, 290, 296, 452, +-161, -55, -285, -247, -52, -27, 69, -53, +-51, -190, -3, 78, 241, 385, 219, -46, +-251, -601, -450, -138, 96, 560, 507, 226, +2, -503, -427, -424, -126, 274, 375, 441, +380, -109, -270, -339, -643, 11, 16, 187, +614, -21, 205, -179, -245, 71, -172, 383, +-42, 80, -96, -428, -29, -198, 237, 352, +265, 325, -45, -8, -263, -200, -278, -140, +-82, 186, 405, 265, 443, -154, -228, -318, +-547, 219, -39, 472, 405, -178, 176, -543, +-235, 19, -108, 431, 125, 188, -47, -244, +-112, -452, 155, -96, 204, 443, -176, 281, +-374, -327, 95, -425, 553, -3, 46, 241, +-543, 86, -201, -130, 288, -87, 220, 77, +9, -19, 5, -186, -73, 43, -274, 267, +-153, -52, 299, -287, 324, 120, -27, 402, +-191, 18, -245, -370, -132, -194, 251, 285, +306, 389, -8, 69, -229, -120, -195, -208, +67, -239, 146, 145, 19, 487, 81, 235, +107, -216, -243, -439, -354, -296, 28, 234, +513, 624, 447, 244, -317, -582, -739, -717, +-161, 166, 580, 722, 540, 110, -174, -542, +-569, -339, -118, 105, 336, 251, 245, 173, +-6, -88, -304, -378, -318, -356, 220, 150, +474, 619, 80, 373, -322, -420, -353, -861, +-27, -218, 276, 855, 275, 875, 53, -178, +-206, -934, -291, -538, -5, 560, 214, 989, +175, 151, 10, -749, -218, -554, -134, 355, +122, 714, 85, 88, 36, -462, 47, -259, +-153, 76, -83, 320, 148, 403, 21, -230, +-126, -728, -32, -92, 125, 572, 195, 392, +-59, -103, -285, -500, -114, -495, 63, 10, +253, 544, 304, 545, -186, -241, -544, -932, +-18, -343, 511, 685, 254, 614, -284, -192, +-332, -556, -58, -336, 101, 144, 392, 600, +361, 404, -462, -494, -704, -780, 246, 196, +637, 972, 6, 355, -390, -695, -83, -757, +246, 268, 68, 995, -180, 379, -31, -617, +-11, -738, -59, -45, 207, 771, 197, 736, +-107, -324, -184, -983, -185, -290, -49, 763, +333, 714, 299, -298, -161, -758, -382, -268, +-132, 228, 302, 464, 264, 372, -81, -296, +-197, -757, -183, -329, -42, 386, 353, 688, +270, 260, -257, -623, -383, -830, -52, 52, +312, 891, 350, 519, -107, -601, -467, -738, +-232, 203, 323, 577, 561, 198, 40, -109, +-602, -324, -449, -211, 290, 316, 612, 407, +150, -68, -451, -255, -369, -19, 88, 95, +286, 151, 273, 242, -87, -146, -449, -620, +-84, 26, 370, 975, 151, 398, -142, -917, +-148, -952, -54, 292, 117, 1190, 77, 489, +-111, -978, -37, -1066, 100, 318, 2, 1040, +-83, 165, 29, -788, 141, -453, -39, 336, +-236, 445, -103, 75, 205, -381, 240, -579, +58, 16, -174, 854, -245, 655, -126, -528, +89, -1215, 303, -357, 255, 1119, -108, 1292, +-411, -176, -265, -1464, 259, -789, 501, 972, +-4, 1253, -452, -74, -174, -911, 188, -647, +203, 266, 124, 1159, -77, 544, -274, -1100, +-124, -1157, 156, 417, 227, 1286, 81, 571, +-143, -778, -255, -1256, 31, -174, 328, 1227, +65, 1023, -379, -691, -247, -1588, 279, -378, +487, 1407, 182, 1510, -483, -438, -765, -2177, +-38, -1139, 969, 1612, 770, 2207, -515, -135, +-1213, -2080, -305, -1276, 1038, 921, 1002, 1791, +-380, 476, -1238, -1353, -420, -1445, 916, 425, +970, 1805, -142, 776, -956, -1221, -738, -1679, +320, -79, 1203, 1831, 689, 1627, -944, -802, +-1549, -2390, 19, -782, 1764, 2056, 1125, 2095, +-1159, -857, -1800, -2446, -8, -522, 1614, 1791, +1018, 1525, -703, -548, -1290, -1841, -347, -790, +770, 1241, 934, 1581, 104, -77, -841, -1600, +-818, -1232, 219, 719, 1072, 1909, 594, 555, +-785, -1720, -1199, -1737, 74, 701, 1236, 2215, +762, 652, -713, -1813, -1246, -1776, -114, 760, +1099, 2231, 800, 507, -420, -1795, -961, -1406, +-390, 788, 587, 1724, 789, 364, 87, -1340, +-568, -1066, -577, 607, -45, 1272, 546, 270, +598, -994, -99, -994, -747, 426, -403, 1430, +490, 404, 598, -1339, -25, -1241, -417, 690, +-425, 1625, -6, 189, 637, -1399, 402, -961, +-439, 753, -579, 1352, -33, -116, 419, -1518, +457, -522, -29, 1316, -573, 1103, -369, -668, +363, -1522, 655, -357, 12, 1390, -705, 1298, +-460, -698, 400, -1767, 822, -254, 234, 1648, +-792, 1176, -859, -974, 288, -1780, 1042, -126, +452, 1881, -704, 1459, -1013, -1210, 90, -2396, +1159, -50, 599, 2549, -857, 1512, -1221, -1799, +138, -2559, 1493, 487, 802, 2882, -1077, 1029, +-1516, -2320, 30, -2340, 1555, 920, 1108, 2933, +-873, 937, -1697, -2453, -205, -2626, 1529, 892, +1205, 3313, -773, 1019, -1720, -2759, -211, -2483, +1575, 1189, 1097, 2889, -853, 608, -1627, -2323, +-142, -1980, 1585, 1065, 1054, 2538, -907, 454, +-1556, -2228, -170, -1806, 1411, 1195, 1171, 2619, +-625, 251, -1629, -2545, -492, -1589, 1370, 1689, +1471, 2407, -537, -436, -1821, -2307, -502, -638, +1328, 1440, 1270, 1254, -260, -243, -1288, -1271, +-757, -750, 571, 855, 1077, 1244, 383, -193, +-626, -1142, -932, -465, -183, 568, 715, 766, +788, 140, 58, -569, -795, -663, -827, 10, +167, 726, 982, 413, 717, -452, -334, -532, +-1201, 0, -740, 294, 954, 311, 1579, 242, +-104, -279, -1797, -919, -931, -318, 1386, 1230, +1752, 1377, -449, -672, -2091, -2194, -789, -693, +1755, 2161, 1871, 2276, -810, -1156, -2421, -3211, +-339, -406, 2288, 3209, 1367, 2154, -1662, -2191, +-2117, -3584, 695, 318, 2464, 4201, 498, 2074, +-2271, -3431, -1672, -4228, 1472, 1302, 2480, 5292, +-165, 1473, -2661, -4755, -1325, -4024, 2090, 2633, +2565, 5489, -746, 452, -3121, -5347, -978, -3578, +2637, 3447, 2510, 5522, -1301, -422, -3294, -5602, +-408, -2672, 3140, 3911, 2094, 4712, -2148, -1309, +-3389, -5205, 429, -1401, 3868, 4210, 1731, 3554, +-3099, -2195, -3547, -4581, 1117, -210, 4237, 4289, +1270, 2272, -3507, -2925, -3051, -3300, 1734, 1152, +3775, 3361, 326, 490, -3438, -2788, -2064, -1680, +2282, 1872, 3100, 2553, -655, -677, -3203, -2968, +-1025, -611, 2486, 2685, 2283, 1795, -1285, -1748, +-2810, -2557, -39, 528, 2638, 2715, 1169, 588, +-1945, -2438, -1879, -1483, 983, 1808, 2068, 2072, +17, -910, -1767, -2393, -898, -242, 1149, 2282, +1558, 1300, -388, -1742, -1835, -2054, -430, 806, +1636, 2354, 1196, 260, -954, -2173, -1665, -1258, +-39, 1529, 1659, 1894, 948, -704, -1052, -1918, +-1450, 138, 140, 1580, 1352, 52, 679, -1334, +-803, -124, -1146, 1363, 212, 580, 1208, -1245, +292, -1265, -1051, 738, -652, 1760, 609, -32, +822, -1787, 141, -420, -644, 1561, -826, 692, +-7, -1321, 1065, -1083, 761, 942, -669, 1546, +-1197, -276, -120, -1853, 1212, -549, 916, 1757, +-742, 1198, -1612, -1411, -116, -1785, 1861, 903, +1252, 2327, -1290, -173, -2199, -2664, -61, -968, +2274, 2363, 1624, 2242, -1355, -1327, -2542, -3118, +-70, -164, 2491, 3166, 1350, 1583, -1729, -2459, +-2051, -2508, 706, 1393, 2134, 2932, 301, -266, +-1760, -2959, -1062, -692, 1113, 2664, 1463, 1581, +-401, -1957, -1489, -2370, -172, 1002, 1299, 2992, +571, 124, -1168, -3243, -934, -1327, 1147, 3012, +1376, 2521, -950, -2146, -1854, -3493, 345, 659, +2085, 3874, 578, 1012, -1909, -3495, -1467, -2420, +1329, 2415, 2063, 3270, -434, -971, -2276, -3637, +-712, -686, 2020, 3377, 1916, 2230, -1228, -2471, +-2638, -3328, -35, 1063, 2607, 3638, 1215, 464, +-1852, -3257, -1899, -1777, 811, 2489, 2014, 2722, +58, -1411, -1646, -3169, -696, 137, 1216, 3072, +1064, 1147, -845, -2399, -1303, -2115, 457, 1433, +1604, 2707, 84, -288, -1693, -2790, -988, -868, +1314, 2293, 1853, 1840, -327, -1188, -2102, -2215, +-948, -148, 1620, 1811, 1821, 1148, -645, -957, +-2059, -1481, -339, 95, 1754, 1140, 1128, 436, +-1080, -515, -1657, -662, 166, -181, 1740, 531, +789, 642, -1221, -184, -1393, -749, 278, -265, +1310, 470, 532, 527, -658, -61, -782, -551, +-44, -211, 481, 498, 369, 296, -15, -486, +-298, -359, -286, 510, 37, 622, 385, -323, +238, -898, -363, -86, -466, 1091, 200, 655, +631, -1043, 29, -1090, -577, 850, -273, 1495, +268, -506, 380, -1882, 143, 15, -202, 2224, +-476, 766, -240, -2345, 441, -1761, 835, 2054, +1, 2678, -1268, -1299, -685, -3318, 1171, 110, +1383, 3458, -525, 1225, -1768, -3145, -495, -2581, +1746, 2358, 1506, 3638, -1320, -1276, -2199, -4236, +492, -99, 2525, 4264, 533, 1586, -2370, -3824, +-1592, -2985, 1727, 2894, 2412, 4098, -720, -1442, +-2746, -4575, -517, -242, 2612, 4222, 1603, 1753, +-2028, -3177, -2385, -2526, 1155, 2072, 2849, 2638, +-156, -1178, -2981, -2457, -935, 552, 2753, 2326, +1978, 92, -2021, -1979, -2801, -667, 750, 1316, +3205, 845, 778, -536, -2977, -473, -2172, 12, +2139, -174, 3103, 42, -931, 686, -3397, 97, +-308, -1004, 3123, -224, 1236, 1092, -2544, 207, +-1742, -1139, 1984, -164, 1992, 1233, -1720, 12, +-2261, -1578, 1678, 84, 2697, 2129, -1535, -7, +-3245, -2809, 1086, -334, 3677, 3306, -168, 863, +-3861, -3347, -1111, -1351, 3422, 2884, 2562, 1549, +-2127, -1877, -3630, -1198, 91, 629, 3803, 519, +2116, 532, -3015, 265, -3726, -1275, 1506, -809, +4482, 1694, 195, 1177, -4277, -1718, -1706, -1440, +3156, 1377, 2750, 1585, -1510, -768, -3008, -1463, +-214, 130, 2734, 1206, 1368, 314, -2258, -1152, +-1845, -578, 1749, 1284, 1914, 682, -1401, -1524, +-1682, -739, 1164, 1657, 1512, 732, -1196, -1712, +-1622, -1061, 1355, 1450, 1990, 1751, -1205, -793, +-2442, -2493, 810, -237, 2565, 2749, -335, 1177, +-2393, -2403, -74, -1579, 2120, 1711, 503, 1509, +-1704, -857, -1146, -1233, 1063, -19, 1821, 988, +-86, 1007, -2187, -717, -1067, -1794, 1959, 610, +2096, 2157, -1101, -656, -2659, -1991, -76, 830, +2697, 1706, 1049, -707, -2504, -1603, -1538, -36, +2479, 1901, 1753, 1316, -2672, -2544, -2029, -2737, +2656, 3041, 2556, 3863, -2072, -2829, -3166, -4561, +912, 1496, 3550, 4586, 478, 491, -3510, -4046, +-1665, -2360, 3068, 3094, 2445, 3360, -2464, -2168, +-2852, -3716, 1847, 1332, 3126, 3807, -1215, -529, +-3291, -3743, 368, -388, 3333, 3304, 581, 1385, +-3180, -2478, -1402, -2309, 2886, 1636, 2053, 3213, +-2524, -941, -2559, -3823, 1849, 459, 3062, 3883, +-861, 79, -3378, -3199, -288, -515, 3373, 2292, +1329, 868, -3083, -1529, -2058, -1100, 2544, 1017, +2447, 1241, -1918, -471, -2409, -1044, 1393, -153, +1929, 394, -1005, 474, -1300, 407, 722, -308, +715, -1090, -395, -198, -240, 1345, 126, 595, +-207, -1307, -193, -983, 678, 949, 655, 1345, +-1054, -443, -1294, -1694, 1242, -200, 1832, 1712, +-1243, 658, -2091, -1300, 1012, -763, 2148, 636, +-708, 649, -2010, -126, 387, -441, 1794, 45, +-165, 307, -1539, -141, -20, -184, 1322, 311, +223, 220, -1163, -347, -403, -382, 971, 370, +533, 797, -672, -283, -528, -1089, 212, 188, +368, 937, 369, -74, -139, -291, -843, 53, +-158, -436, 1131, -112, 464, 852, -1214, 40, +-694, -1004, 1054, 48, 863, 980, -720, -47, +-807, -969, 220, -316, 579, 685, 330, 814, +-394, -212, -655, -1354, 257, -347, 794, 1677, +-263, 742, -686, -1792, 259, -1099, 419, 1635, +-150, 1511, -251, -1122, 105, -1913, 134, 364, +-25, 2174, -58, 438, -68, -2033, -173, -1007, +138, 1691, 624, 1432, -133, -1249, -988, -1639, +-11, 870, 1055, 1765, 255, -372, -892, -1650, +-522, -208, 725, 1311, 761, 888, -662, -773, +-888, -1498, 719, 173, 788, 1813, -740, 342, +-588, -1828, 652, -767, 528, 1590, -527, 999, +-519, -1280, 222, -1222, 489, 745, 154, 1332, +-197, -73, -567, -1336, -347, -725, 1006, 1048, +807, 1262, -1122, -638, -1193, -1395, 858, 194, +1423, 1215, -247, 189, -1483, -1020, -519, -517, +1475, 987, 1025, 882, -1242, -997, -1311, -1159, +863, 1001, 1509, 1370, -516, -743, -1610, -1390, +116, 292, 1658, 1331, 296, 400, -1442, -1037, +-831, -995, 975, 633, 1384, 1252, -500, -195, +-1578, -1036, 126, -98, 1295, 628, 65, 257, +-703, -317, -153, -397, 76, 137, 273, 463, +261, -79, -256, -503, -349, -29, 75, 481, +246, 108, 173, -606, -53, -304, -327, 705, +-156, 542, 323, -615, 307, -823, -238, 142, +-406, 963, 197, 434, 369, -893, -149, -771, +-231, 635, 54, 747, 68, -255, 90, -485, +-1, -96, -209, 348, 19, 386, 217, -363, +-13, -398, -11, 563, -149, 146, -327, -726, +409, 359, 600, 892, -558, -809, -608, -947, +496, 1063, 324, 830, -207, -1013, 44, -459, +-229, 737, -246, -79, 634, -381, 396, 587, +-1003, 37, -654, -902, 1161, 155, 1126, 763, +-1067, -215, -1602, -305, 807, 184, 1741, -302, +-451, -356, -1551, 629, 167, 619, 1164, -549, +91, -844, -769, 153, -342, 739, 380, 103, +609, -268, -16, 28, -885, -385, -212, -494, +1153, 1040, 201, 1110, -1362, -1582, -17, -1623, +1366, 2064, -80, 2005, -1066, -2323, -92, -2093, +457, 2355, 480, 1958, 288, -2088, -816, -1656, +-976, 1725, 926, 1488, 1448, -1410, -772, -1483, +-1620, 1291, 417, 1510, 1482, -1312, 26, -1397, +-971, 1349, -562, 1127, 248, -1340, 1025, -919, +514, 1178, -1214, 936, -1106, -997, 958, -1204, +1345, 780, -245, 1322, -1312, -585, -540, -1205, +1134, 429, 1007, 935, -993, -466, -1111, -878, +1009, 496, 975, 1153, -935, -311, -932, -1466, +664, -167, 984, 1361, -301, 790, -937, -695, +-79, -1163, 823, -176, 237, 1148, -513, 1007, +-290, -724, 71, -1595, 192, 116, 386, 1981, +209, 684, -789, -1997, -747, -1470, 886, 1563, +1222, 2084, -756, -607, -1396, -2279, 568, -579, +1217, 1965, -330, 1621, -941, -1233, 128, -2251, +588, 337, 89, 2279, -221, 392, -204, -1744, +-131, -867, 118, 724, 368, 932, 190, 455, +-400, -626, -661, -1463, 167, -72, 1159, 1872, +225, 955, -1410, -1648, -686, -1765, 1260, 986, +1095, 2179, -784, -158, -1419, -2057, 143, -652, +1631, 1363, 500, 1364, -1541, -112, -1026, -1780, +973, -1372, 1219, 1632, -69, 2672, -871, -674, +-745, -3199, 81, -735, 1052, 2683, 786, 2039, +-850, -1216, -1368, -2622, 355, -534, 1600, 2372, +158, 1965, -1515, -1514, -645, -2719, 1183, 429, +965, 2772, -545, 675, -981, -2219, -313, -1703, +659, 1146, 1119, 2299, -111, 118, -1628, -2171, +-402, -1096, 1690, 1334, 750, 1253, -1451, -364, +-1001, -677, 1096, -173, 1236, -140, -704, 102, +-1446, 649, 241, 185, 1503, -751, 214, -355, +-1328, 606, -539, 369, 1038, -319, 594, -221, +-697, -43, -455, -158, 238, 289, 226, 797, +430, 18, 146, -1268, -1221, -933, -705, 1084, +1776, 2077, 1465, 0, -1899, -2734, -2253, -1602, +1628, 2551, 2908, 3154, -1118, -1498, -3283, -4113, +437, -170, 3248, 4181, 397, 2025, -2802, -3274, +-1213, -3482, 2090, 1655, 1756, 3933, -1420, -11, +-1775, -3259, 977, -1004, 1398, 1810, -877, 1007, +-936, -387, 992, -231, 861, -372, -1100, -825, +-1358, 79, 980, 1445, 2152, 1063, -468, -1161, +-2830, -2413, -307, -122, 3018, 3181, 1125, 1974, +-2658, -2903, -1750, -3638, 1844, 1632, 1984, 4453, +-711, 235, -1773, -4035, -477, -2006, 1150, 2533, +1392, 3036, -292, -455, -1809, -2875, -508, -1410, +1675, 1644, 1154, 2535, -1241, 104, -1509, -2765, +686, -1620, 1569, 2294, -176, 2501, -1348, -1372, +-260, -2656, 908, 297, 629, 2256, -344, 627, +-850, -1645, -301, -1209, 802, 1089, 901, 1492, +-396, -659, -1332, -1734, -260, 103, 1458, 1864, +986, 732, -1223, -1551, -1623, -1733, 607, 516, +1978, 2399, 336, 910, -1887, -2322, -1252, -2085, +1182, 1413, 1756, 2491, -85, 38, -1531, -2052, +-1031, -1519, 661, 1022, 1673, 2435, 529, 291, +-1497, -2239, -1638, -1440, 426, 1016, 2192, 2003, +1147, 574, -1863, -1661, -2438, -1576, 730, 648, +2705, 1538, 673, 506, -1869, -636, -1681, -1099, +472, -472, 1841, 703, 789, 1199, -1099, 588, +-1446, -1130, -274, -2086, 1314, 178, 1682, 2875, +-479, 1244, -2414, -2434, -698, -2448, 2142, 954, +1668, 2754, -1129, 789, -2004, -2102, -51, -2120, +1720, 879, 920, 2689, -1087, 286, -1363, -2562, +465, -1030, 1433, 1925, -121, 1228, -1142, -1049, +59, -1010, 633, 195, -195, 584, -14, 378, +391, -78, -514, -588, -612, -466, 819, 517, +912, 969, -825, -219, -1183, -1150, 488, -234, +1232, 775, 51, 647, -802, 261, -574, -580, +-34, -1605, 651, -255, 980, 2650, -122, 1760, +-1441, -2712, -876, -3282, 1162, 1540, 1661, 3903, +-302, 406, -1624, -3036, -539, -2074, 736, 969, +692, 2383, 432, 1096, -63, -1077, -980, -1930, +-1008, -1102, 491, 1085, 1836, 2766, 780, 741, +-1827, -2971, -2058, -2393, 864, 1666, 2476, 2877, +669, 269, -1698, -1894, -1961, -1700, 13, -68, +2311, 1854, 1771, 1951, -1531, -751, -2814, -2654, +86, -752, 2646, 1826, 1186, 1590, -1379, -100, +-1518, -1224, -226, -1295, 688, 152, 1175, 1566, +708, 723, -820, -780, -1686, -804, -507, -228, +1483, 240, 1757, 672, -200, 493, -1944, -299, +-1305, -857, 777, -527, 2050, 577, 1042, 1175, +-1476, 192, -2485, -1209, -95, -942, 2795, 637, +1667, 1138, -1934, -20, -2364, -756, 570, -128, +1924, 176, 570, -228, -867, 106, -1087, 571, +-135, 12, 941, -485, 726, -253, -350, -25, +-815, 189, -344, 609, 482, 362, 727, -897, +58, -1181, -514, 655, -485, 1801, -79, 136, +535, -1788, 637, -1081, -204, 1132, -899, 1671, +-296, -189, 856, -1588, 736, -408, -586, 1072, +-937, 386, 174, -594, 786, 11, 292, 515, +-423, -249, -586, -767, 86, 63, 576, 965, +89, 351, -377, -796, -85, -611, 89, 289, +57, 418, 61, 139, 71, 124, -93, -168, +-297, -667, -40, -147, 544, 820, 266, 360, +-577, -630, -459, -267, 289, 408, 532, 30, +99, -404, -467, 29, -316, 520, 396, 242, +220, -512, -384, -679, -104, 293, 450, 983, +230, 180, -337, -802, -598, -740, -170, 33, +773, 991, 969, 1153, -280, -386, -1639, -2023, +-806, -1046, 1583, 1755, 1928, 2504, -632, -63, +-2313, -2861, -808, -2225, 1610, 1610, 1942, 3648, +-158, 602, -2040, -3248, -1240, -2439, 1047, 1314, +1894, 2789, 351, 746, -1575, -1738, -1284, -1731, +787, 303, 1331, 1383, -223, 382, -818, -522, +176, -147, 489, 80, -379, -383, -683, -378, +220, 463, 1076, 861, 567, 121, -991, -820, +-1526, -977, 50, 69, 1898, 1425, 1352, 918, +-1187, -1060, -2303, -1396, -363, 201, 2103, 990, +1812, 458, -734, 79, -2286, -288, -981, -1034, +1511, -610, 1942, 1156, 26, 1557, -1607, -291, +-1278, -1645, 201, -867, 1499, 569, 1285, 1330, +-595, 1010, -1907, -637, -741, -1850, 1390, -720, +1615, 1154, -215, 1603, -1621, 589, -904, -1196, +985, -2016, 1535, -319, -153, 1994, -1661, 1762, +-598, -622, 1272, -2061, 1181, -995, -383, 1142, +-1420, 1636, -786, 99, 1040, -1042, 1679, -701, +-87, -57, -1724, 350, -939, 698, 862, 536, +1329, -404, 294, -1209, -751, -560, -840, 1087, +-393, 1566, 294, -91, 1106, -1868, 1004, -1188, +-644, 1151, -1941, 1930, -823, 270, 1581, -1603, +2100, -1485, 24, 430, -2045, 1745, -1665, 854, +563, -914, 2002, -1506, 1165, -436, -697, 1216, +-1686, 1490, -1240, -296, 513, -1697, 2287, -651, +1467, 1072, -1665, 1100, -2765, -194, -145, -969, +2569, -340, 1837, 432, -1128, 286, -2390, 87, +-493, 62, 1682, -284, 1360, -322, -384, 134, +-1285, 282, -643, 106, 668, -74, 1056, -182, +-21, -59, -1021, 117, -522, -22, 782, -36, +998, 291, -355, 113, -1240, -589, -300, -367, +947, 743, 881, 717, -92, -611, -881, -874, +-865, 215, 189, 703, 1253, 282, 770, -279, +-844, -579, -1379, -127, -31, 491, 1249, 366, +849, -54, -511, -396, -1142, -456, -362, 126, +781, 690, 854, 404, -82, -461, -756, -922, +-439, -123, 358, 992, 469, 620, -79, -467, +-244, -630, 56, -381, 205, 102, -113, 1003, +-405, 579, -51, -1094, 586, -1025, 378, 805, +-427, 1147, -614, -494, -1, -1070, 570, 285, +276, 823, -403, -44, -137, -275, 399, -137, +-105, -389, -568, -18, -71, 613, 504, 541, +572, 2, 110, -830, -693, -1003, -896, 348, +-39, 1416, 1102, 701, 1115, -679, -406, -1378, +-1676, -694, -685, 1010, 1331, 1566, 1389, 137, +-404, -1284, -1317, -1015, -364, 293, 578, 737, +450, 210, 299, 387, 94, 415, -588, -1031, +-742, -1500, 82, 239, 786, 1668, 683, 1279, +-103, -404, -890, -1892, -664, -1288, 288, 845, +743, 1871, 542, 831, 45, -924, -832, -1560, +-1054, -416, 331, 871, 1373, 775, 533, 158, +-679, 16, -867, -286, -515, -835, 241, -505, +1248, 750, 802, 1165, -900, -25, -1356, -975, +-62, -423, 893, 439, 705, 337, 192, -301, +-527, -225, -999, 472, -229, 419, 949, -311, +839, -610, -61, -242, -776, 491, -982, 572, +-15, -294, 1345, -410, 1101, 372, -847, 122, +-1687, -534, -164, -126, 1515, 275, 971, 215, +-835, 411, -1249, 47, 44, -843, 1049, -659, +612, 425, -409, 959, -943, 492, -563, -487, +636, -828, 1432, -234, 253, 151, -1444, 111, +-1118, 537, 451, 994, 1164, 54, 753, -1697, +-267, -1586, -1067, 788, -873, 2250, 211, 994, +1283, -1006, 1062, -1547, -629, -871, -1720, 131, +-451, 1227, 1302, 1578, 1095, 304, -312, -1485, +-884, -1772, -424, -381, 174, 1297, 494, 1961, +337, 708, -181, -1661, -272, -2163, -20, 59, +-118, 1819, -61, 1033, 328, -510, 193, -849, +-181, -280, -144, 222, -59, 188, -58, -113, +118, 35, 213, 391, -84, 30, -237, -404, +101, -54, 259, 166, -144, -215, -350, -219, +154, 379, 386, 618, -101, -44, -359, -748, +29, -489, 377, 334, 20, 652, -400, 199, +-132, -380, 382, -337, 234, 193, -196, 196, +-368, -319, -126, -201, 447, 405, 575, 390, +-190, -111, -975, -397, -461, -335, 791, 72, +1158, 441, 92, 257, -1144, -234, -1007, -273, +232, 146, 1057, 175, 726, -361, -174, -359, +-759, 424, -646, 766, -116, 48, 488, -851, +865, -819, 446, 306, -633, 1185, -1112, 490, +-292, -843, 813, -794, 924, 159, 42, 313, +-702, 132, -503, 448, 37, 288, 264, -641, +350, -868, 103, 38, -243, 784, -201, 639, +71, -42, 139, -553, 76, -366, -195, 26, +-355, -107, 93, -132, 621, 635, 389, 1002, +-420, -119, -728, -1346, -158, -1008, 388, 257, +304, 1186, 295, 1189, 254, -27, -352, -1303, +-755, -927, -357, 152, 383, 372, 981, 514, +542, 851, -869, 139, -1090, -1030, 397, -934, +952, 14, -182, 473, -563, 640, 209, 766, +297, 57, -171, -1224, 9, -1193, 95, 400, +-389, 1328, -277, 556, 426, -455, 654, -481, +137, -131, -634, -362, -902, -337, 15, 812, +1058, 1170, 723, -343, -423, -1291, -888, -405, +-301, 601, 367, 686, 454, 127, 99, -464, +-83, -294, 28, 244, -75, 58, -489, -321, +-352, 36, 597, 469, 905, 254, -62, -303, +-943, -640, -592, -309, 414, 666, 773, 1017, +98, -227, -476, -1346, -88, -315, 213, 1084, +-271, 529, -346, -521, 415, -403, 701, 62, +-126, 254, -697, 122, -262, -286, 204, -189, +144, 439, 255, 326, 453, -439, -99, -576, +-779, 90, -582, 778, 316, 570, 888, -642, +575, -1136, -317, 161, -910, 1249, -664, 318, +180, -996, 1103, -525, 943, 770, -544, 680, +-1475, -556, -364, -965, 1084, 35, 794, 1049, +-429, 645, -674, -634, 106, -903, 560, 157, +96, 711, -616, -68, -524, -657, 326, 65, +854, 725, 338, 158, -438, -330, -649, 6, +-355, -268, 105, -955, 568, -36, 596, 1577, +21, 1173, -577, -767, -599, -1569, 47, -561, +554, 598, 290, 657, -258, 377, -290, 329, +57, -217, 290, -754, 155, -212, -273, 322, +-447, -73, -43, -186, 412, 433, 401, 603, +58, -38, -266, -546, -406, -375, -211, -72, +215, -82, 397, 138, 97, 615, -166, 486, +-99, -183, -40, -533, -1, -480, 86, -320, +-39, 126, -169, 762, 24, 740, 237, -157, +121, -776, -48, -412, -187, 83, -216, 186, +-35, 151, 321, 146, 338, 244, -202, 112, +-502, -415, -16, -498, 439, -3, 166, 292, +-82, 447, -117, 397, -309, -381, -260, -889, +372, -134, 670, 755, 25, 612, -690, -203, +-520, -667, 287, -169, 668, 473, 209, 111, +-496, -461, -528, -58, 170, 633, 678, 331, +276, -561, -566, -644, -708, 146, 124, 629, +829, 363, 310, -379, -596, -830, -433, 54, +352, 1157, 303, 357, -287, -1053, -159, -678, +438, 507, 126, 667, -705, -27, -381, -452, +797, -48, 787, 321, -433, -155, -859, -244, +-80, 416, 495, 209, 205, -634, -138, -419, +-33, 524, 186, 816, -45, 78, -385, -896, +-171, -827, 380, 411, 388, 1174, -36, 382, +-275, -868, -331, -986, -217, -28, 307, 902, +624, 1023, 85, -56, -450, -1322, -292, -844, +-59, 756, -117, 1014, 153, 3, 578, -600, +379, -374, -356, 190, -766, 453, -371, 165, +396, -221, 674, -586, 225, -539, -217, 580, +-309, 1412, -275, 220, -109, -1425, 252, -1177, +329, 383, 20, 1179, -66, 696, 30, -136, +-208, -743, -435, -874, 47, -82, 667, 859, +429, 715, -399, -129, -702, -555, -96, -250, +561, 218, 323, -55, -290, -509, -178, 289, +239, 1159, -4, 220, -405, -1203, -122, -980, +448, 351, 452, 1069, -152, 474, -578, -452, +-210, -487, 402, 114, 306, 150, -227, -461, +-305, -405, 84, 663, 413, 940, 231, -133, +-366, -683, -592, -310, 126, -170, 613, -117, +-34, 286, -510, 665, 184, 654, 551, -272, +-198, -1351, -604, -740, -72, 906, 437, 1209, +388, 175, -50, -789, -583, -900, -311, 76, +528, 1054, 471, 410, -423, -962, -372, -747, +399, 769, 328, 1041, -327, -274, -396, -1000, +23, -318, 293, 483, 267, 497, -79, -2, +-235, -278, 36, -46, 204, 119, -167, 37, +-400, -39, -16, -210, 575, -231, 561, 187, +-261, 359, -959, 101, -440, -11, 722, -77, +890, -284, -78, -325, -732, -177, -311, 353, +323, 960, 312, 416, -79, -1049, -242, -1349, +-69, 152, 187, 1549, 239, 878, -84, -858, +-343, -1109, 1, 17, 439, 612, 95, 369, +-472, -166, -329, -487, 217, 46, 397, 634, +238, 140, -88, -575, -349, -399, -216, 184, +83, 336, 99, 22, 54, 21, 150, 258, +91, -122, -80, -525, -209, -120, -235, 225, +51, 293, 471, 379, 202, -132, -449, -668, +-321, -103, 289, 487, 245, 157, -164, -295, +-105, -178, 107, 339, 40, 385, -42, -365, +-61, -622, -55, 182, 79, 662, 163, 110, +-85, -626, -212, -457, 33, 475, 282, 749, +115, -49, -251, -616, -306, -400, 83, 92, +290, 404, 40, 231, -65, -161, 67, -155, +-12, 31, -217, 85, -70, 67, 159, -53, +110, -190, -122, -126, -55, 102, 134, 271, +57, 43, -80, -238, 56, 81, -16, 275, +-272, -176, -57, -283, 352, 18, 127, -110, +-292, -45, -71, 527, 288, 493, 63, -320, +-318, -768, -127, -342, 230, 462, 179, 700, +-99, 79, -177, -542, -49, -377, 155, 233, +169, 389, -89, -147, -226, -399, 62, 235, +290, 603, -15, -182, -415, -770, -174, -63, +394, 661, 383, 222, -158, -395, -397, -243, +-124, 95, 283, 293, 341, 384, -158, -156, +-529, -863, 19, -328, 621, 790, 167, 704, +-547, -214, -356, -507, 263, -154, 424, 79, +96, -2, -299, 51, -238, 307, 183, 100, +214, -458, -228, -257, -282, 400, 168, 227, +362, -265, 100, 16, -147, 283, -209, -295, +-101, -527, 81, 312, 19, 734, -168, -71, +76, -642, 473, -178, 205, 294, -474, 248, +-561, 162, 74, -33, 556, -449, 246, -438, +-341, 249, -317, 784, 194, 380, 372, -527, +-33, -778, -443, -91, -287, 508, 294, 362, +468, -14, 47, -138, -262, -94, -123, 0, +-73, -45, -156, -220, 75, -19, 423, 373, +222, 155, -385, -225, -582, -45, 121, 132, +824, -73, 318, -210, -825, -127, -764, 114, +465, 342, 921, 211, 10, -171, -769, -394, +-286, -240, 594, 292, 464, 551, -454, -50, +-649, -606, 99, -290, 604, 293, 319, 532, +-130, 314, -364, -345, -352, -683, 16, -153, +423, 443, 213, 413, -292, 133, -216, -141, +275, -460, 291, -448, -175, 254, -401, 919, +-143, 389, 183, -816, 307, -940, 245, 193, +-89, 843, -468, 250, -237, -372, 431, -56, +464, 311, -266, -201, -637, -670, -72, -15, +612, 723, 464, 357, -302, -342, -617, -303, +-111, 109, 476, 93, 365, -239, -169, -106, +-386, 376, -141, 238, 170, -389, 326, -335, +160, 376, -285, 486, -410, -271, 61, -658, +456, 20, 219, 653, -269, 217, -416, -466, +-56, -317, 426, 264, 374, 342, -272, -159, +-560, -332, 22, 115, 570, 293, 233, -48, +-373, -175, -385, -143, 124, -58, 412, 344, +2, 367, -481, -322, -109, -436, 573, 112, +265, 129, -460, -79, -244, 264, 266, 372, +-52, -379, -288, -794, 283, 145, 467, 1077, +-180, 323, -496, -991, -154, -839, 237, 467, +442, 1106, 180, 277, -501, -912, -567, -731, +224, 407, 704, 659, 293, 17, -405, -266, +-743, -165, -244, -77, 782, 50, 861, 225, +-342, 161, -1022, -223, -240, -388, 706, 112, +616, 542, -183, 190, -744, -415, -374, -561, +563, -87, 809, 582, -15, 586, -787, -69, +-557, -495, 249, -511, 661, -146, 308, 542, +-276, 652, -432, -104, -113, -537, 129, -280, +129, 61, 175, 300, 187, 387, -123, 10, +-439, -584, -223, -580, 314, 377, 453, 1038, +30, 260, -333, -862, -202, -845, 80, 15, +106, 822, 19, 764, 29, -260, 38, -816, +-23, -220, -88, 316, -74, 252, 3, 107, +128, -51, 183, -115, -35, -93, -346, -171, +-154, 48, 408, 490, 369, 202, -397, -540, +-596, -560, 283, 225, 782, 749, -45, 226, +-802, -647, -181, -441, 605, 429, 199, 438, +-352, -296, 4, -445, 234, 151, -253, 538, +-327, 120, 312, -473, 513, -373, -95, 187, +-594, 301, -267, 8, 492, 16, 573, 166, +-264, -145, -681, -476, 35, -105, 574, 397, +87, 363, -365, 93, -71, -225, 215, -527, +43, -161, -173, 572, -131, 468, 146, -348, +316, -548, -40, 20, -514, 424, -166, 222, +599, -102, 461, -230, -417, -184, -678, 96, +-23, 299, 550, -70, 369, -383, -192, 87, +-344, 506, 30, 102, 201, -390, -166, -338, +-292, -9, 236, 268, 489, 251, -72, 19, +-488, -121, -55, -161, 400, -158, 52, 75, +-417, 280, -125, 133, 445, -181, 303, -331, +-296, -186, -386, 287, 76, 580, 296, 167, +70, -535, -156, -646, -157, -88, -9, 549, +213, 716, 249, 152, -91, -694, -426, -767, +-254, 36, 263, 660, 509, 571, 204, 41, +-355, -514, -519, -580, -58, -85, 458, 372, +321, 515, -179, 315, -339, -291, -75, -718, +136, -280, 137, 469, 110, 630, 125, 131, +-81, -449, -457, -543, -359, -95, 401, 377, +742, 538, 34, 234, -646, -433, -336, -719, +283, -61, 289, 609, -72, 374, -172, -133, +76, -241, 164, -202, -100, -59, -270, 236, +57, 252, 384, -29, 124, -307, -391, -408, +-345, 84, 211, 835, 405, 442, -6, -773, +-238, -842, 20, 243, 109, 710, -220, 178, +-257, -327, 214, -247, 496, 119, 169, 328, +-362, 89, -562, -509, -149, -582, 513, 386, +563, 1015, -146, 158, -593, -905, -138, -661, +429, 363, 252, 796, -328, 158, -327, -644, +249, -450, 450, 363, -89, 551, -492, -74, +-187, -532, 353, -122, 396, 429, -25, 98, +-316, -300, -177, 151, 16, 261, 56, -461, +133, -468, 182, 471, -15, 772, -199, -27, +-132, -754, 3, -435, 113, 394, 183, 462, +14, -138, -302, -309, -171, 116, 355, 442, +389, 93, -276, -659, -603, -592, 22, 459, +660, 921, 281, 92, -495, -786, -447, -588, +215, 399, 387, 863, 13, 97, -205, -837, +-114, -638, -1, 348, 134, 875, 197, 391, +-38, -480, -373, -757, -191, -232, 408, 448, +475, 578, -250, 110, -635, -324, -26, -360, +587, -153, 291, 213, -345, 421, -433, 34, +3, -396, 373, -147, 247, 262, -178, 175, +-299, -172, 45, -245, 257, 69, 10, 314, +-233, 75, -84, -180, 145, -140, 176, -147, +27, -75, -156, 387, -144, 512, 60, -202, +79, -847, -39, -407, 121, 663, 262, 1005, +-211, 54, -678, -1067, -22, -834, 969, 531, +521, 1072, -847, 133, -913, -658, 363, -370, +894, 50, 146, 106, -520, 259, -410, 286, +43, -145, 364, -440, 277, -107, -156, 286, +-316, 212, -25, -72, 186, -140, 91, -49, +-11, 76, -99, 135, -130, -7, 33, -206, +157, -132, -1, 90, -86, 215, 58, 204, +81, -42, -46, -320, -121, -138, -142, 94, +-35, -89, 288, 7, 361, 536, -124, 374, +-545, -497, -206, -833, 400, -218, 432, 700, +-38, 903, -367, -2, -321, -900, 23, -560, +408, 337, 371, 553, -134, 127, -472, -194, +-217, -205, 218, -65, 310, 95, 77, 124, +-99, -91, -99, -153, -112, 129, -136, 224, +57, -59, 333, -171, 158, -52, -286, 8, +-269, 12, 131, 33, 203, 106, -35, 157, +-108, -93, -45, -371, 59, -49, 148, 421, +25, 201, -246, -371, -135, -323, 213, 265, +224, 447, -70, -46, -202, -405, -78, -266, +49, 148, 89, 471, 107, 223, -25, -491, +-173, -532, 8, 322, 259, 752, -12, 14, +-358, -778, -92, -405, 296, 560, 178, 577, +-68, -244, -96, -453, -167, 115, -71, 347, +292, -121, 207, -457, -395, -18, -328, 602, +438, 338, 475, -479, -304, -644, -576, 99, +43, 748, 495, 412, 179, -580, -317, -811, +-230, 76, 172, 845, 141, 516, -95, -378, +-87, -739, 70, -203, 92, 436, 4, 449, +-162, 6, -149, -312, 155, -232, 294, 76, +-3, 235, -315, 169, -127, -99, 187, -398, +131, -170, -117, 405, -105, 424, 115, -86, +219, -343, -22, -310, -348, -96, -184, 308, +341, 508, 359, 124, -182, -461, -445, -574, +-35, 26, 392, 588, 253, 379, -203, -250, +-301, -435, -36, -98, 127, 280, 133, 242, +115, -67, -30, -242, -281, -168, -158, 94, +295, 375, 348, 193, -199, -336, -445, -392, +26, 38, 390, 244, 155, 157, -198, 137, +-212, -7, -12, -346, 153, -322, 89, 246, +-75, 446, -45, -9, 39, -334, 24, -171, +-7, 85, 38, 327, -86, 223, -198, -372, +65, -582, 442, 164, 169, 768, -522, 287, +-496, -610, 284, -663, 637, 147, 107, 671, +-398, 268, -252, -339, 56, -356, 29, -28, +-15, 131, 168, 124, 210, 154, -43, 76, +-221, -200, -174, -336, -5, -55, 119, 340, +141, 428, 103, 18, 14, -523, -204, -529, +-247, 144, 72, 698, 284, 512, 104, -265, +-106, -792, -154, -423, -136, 413, 98, 637, +365, 185, 43, -254, -552, -356, -320, -192, +596, 117, 642, 246, -335, 42, -783, -148, +-40, 25, 624, 242, 247, -36, -359, -419, +-191, -146, 238, 396, 16, 274, -299, -188, +29, -204, 423, 87, 111, 60, -365, -158, +-301, -96, 137, 171, 350, 190, 152, 53, +-220, -81, -332, -273, -50, -268, 299, 170, +238, 486, -40, 190, -119, -343, -135, -408, +-242, 51, -29, 358, 445, 127, 343, -172, +-347, -216, -529, -76, 151, 271, 569, 373, +61, -150, -528, -534, -325, -131, 305, 355, +521, 323, 128, 19, -444, -204, -555, -275, +-12, -126, 644, 245, 596, 447, -220, -1, +-787, -529, -392, -336, 406, 239, 580, 462, +184, 268, -223, -203, -376, -515, -291, -248, +108, 279, 473, 454, 292, 107, -236, -316, +-445, -252, -147, 74, 251, 137, 382, 130, +95, 54, -331, -274, -332, -286, 68, 229, +296, 443, 232, 82, 40, -361, -298, -390, +-484, 86, 42, 407, 667, 107, 347, -184, +-516, -81, -574, 41, 146, -16, 538, -59, +202, 38, -269, 120, -312, -46, -54, -106, +132, 131, 137, 82, 146, -252, 14, -141, +-265, 276, -194, 263, 221, -193, 302, -350, +-119, 129, -258, 379, -7, -119, 83, -449, +-57, -17, 109, 481, 351, 396, -16, -282, +-611, -690, -378, -90, 502, 609, 643, 285, +-80, -294, -494, -226, -184, 98, 106, 143, +83, -23, 102, -161, 127, -94, -21, 97, +-173, 235, -144, 85, 51, -258, 250, -163, +120, 239, -323, 108, -308, -282, 249, -101, +460, 276, -33, 216, -427, -115, -229, -264, +202, -41, 356, 202, 76, 41, -298, -183, +-277, -16, 109, 264, 256, 139, 47, -288, +-36, -309, -34, 192, -212, 333, -173, -75, +307, -225, 401, 15, -163, 152, -512, 69, +-104, -158, 409, -201, 281, 91, -160, 238, +-281, 84, 12, -20, 153, -133, 29, -294, +-88, -131, -27, 349, 41, 530, 62, 5, +14, -645, -82, -437, -40, 357, 136, 529, +50, 24, -259, -283, -86, -174, 396, 38, +202, 132, -407, 26, -321, -88, 303, -22, +362, 90, -158, 28, -359, -55, 45, 49, +375, 54, 119, -256, -310, -197, -275, 390, +127, 423, 272, -310, 62, -538, -114, 55, +-66, 485, -20, 236, 0, -286, 11, -448, +5, -55, 17, 417, 72, 409, -1, -77, +-102, -473, -41, -289, 87, 181, 8, 273, +-83, 58, 17, 32, 131, 123, -7, -95, +-160, -461, -49, -263, 133, 436, 50, 588, +-163, -80, -93, -477, 178, -174, 240, 133, +-62, 157, -308, 68, -210, -144, 81, -144, +255, 221, 235, 281, -2, -210, -280, -372, +-305, 52, -28, 230, 261, -36, 335, 22, +32, 287, -381, -51, -355, -558, 210, -236, +530, 500, 58, 566, -598, -122, -414, -659, +432, -310, 759, 455, 30, 539, -793, -106, +-575, -460, 401, -156, 798, 165, 153, 88, +-545, 57, -441, 252, 146, 80, 376, -453, +107, -448, -179, 142, -94, 560, 94, 462, +94, -145, -69, -788, -107, -464, 11, 581, +140, 788, 92, -121, 2, -708, -54, -247, +-110, 362, -69, 351, 159, 76, 252, -156, +-28, -372, -294, -229, -134, 296, 225, 427, +316, 43, 17, -185, -334, -196, -280, -229, +203, -91, 487, 338, 100, 500, -450, -20, +-370, -608, 215, -317, 445, 395, 64, 395, +-316, -198, -159, -342, 174, 143, 128, 378, +-109, -85, -66, -404, 32, -81, -55, 210, +-31, 229, 185, 201, 102, -182, -229, -537, +-259, -35, 65, 579, 217, 276, 84, -329, +-75, -379, -135, -27, -120, 274, -3, 265, +103, 41, 26, -204, -75, -348, -3, -168, +76, 338, -85, 531, -190, 48, 38, -522, +210, -450, -74, 100, -273, 446, 73, 332, +311, -58, -68, -421, -342, -270, -27, 228, +209, 255, -15, -112, -107, -79, 111, 199, +110, 120, -208, -230, -246, -365, 97, 37, +288, 485, 97, 228, -112, -309, -129, -275, +-124, 55, -99, 130, 155, 10, 381, -18, +123, 81, -348, 50, -325, -192, 119, -129, +328, 229, 153, 215, -94, -184, -190, -297, +-69, 36, 183, 310, 214, 119, -47, -200, +-190, -168, 27, 44, 191, 106, 39, 35, +-80, -66, 57, -46, 69, 82, -143, 56, +-73, -58, 318, -83, 294, -39, -249, 93, +-439, 157, 8, -101, 421, -234, 339, 114, +-72, 331, -411, -72, -287, -424, 226, -101, +459, 408, 109, 274, -281, -187, -287, -248, +-66, -75, 190, 23, 300, 182, 54, 135, +-275, -132, -235, -51, 26, 126, 145, -126, +176, -242, 51, 131, -287, 306, -307, 62, +195, -168, 381, -215, -128, -110, -428, 155, +-34, 281, 293, 45, 72, -222, -192, -127, +-138, 47, -5, 35, 7, 36, -32, 65, +-17, -31, 65, -17, 95, 82, -88, -31, +-307, -204, -164, -130, 214, 140, 290, 370, +4, 210, -201, -296, -231, -515, -184, -163, +77, 380, 425, 582, 247, 122, -367, -565, +-467, -511, 26, 202, 288, 485, 161, 111, +120, -178, 5, -158, -340, -117, -318, -20, +257, 240, 508, 224, 16, -152, -441, -285, +-170, -38, 344, 149, 291, 190, -213, 53, +-268, -254, 238, -175, 364, 270, -195, 192, +-392, -277, 192, -193, 515, 224, -11, 197, +-454, -92, -116, -131, 386, -11, 333, 24, +-78, -3, -287, 2, -162, 36, 127, 81, +345, 5, 265, -134, -176, -19, -448, 124, +-105, -112, 426, -203, 412, 252, -62, 417, +-365, -132, -245, -508, 56, -230, 305, 255, +272, 464, -42, 181, -298, -331, -183, -405, +69, 22, 161, 287, 106, 110, 10, -43, +-117, 39, -192, -50, -61, -275, 178, -56, +187, 358, -126, 216, -271, -238, -5, -296, +187, 28, -20, 276, -199, 161, -53, -216, +123, -292, 52, 114, -84, 370, -130, 66, +-95, -336, -23, -273, 108, 126, 114, 343, +-66, 144, -241, -217, -142, -283, 100, 40, +199, 205, 42, 0, -167, -38, -218, 105, +-60, -57, 147, -204, 174, 27, -43, 197, +-205, 105, -65, -27, 119, -216, 41, -264, +-108, 156, -21, 520, 171, 114, 97, -570, +-196, -429, -216, 404, 103, 594, 286, -156, +75, -572, -137, -97, -114, 399, 33, 301, +84, -93, 61, -336, -7, -217, -9, 122, +61, 312, 93, 156, -27, -117, -88, -224, +49, -116, 142, 71, 24, 144, -48, 32, +47, -44, 115, 23, -25, 19, -169, -54, +-1, -38, 351, -82, 276, -54, -266, 227, +-489, 236, 1, -210, 562, -301, 400, 59, +-229, 170, -506, 81, -115, 33, 311, -122, +270, -210, -5, 53, -72, 301, -69, 139, +-173, -246, -111, -363, 226, -2, 306, 413, +-30, 280, -317, -216, -231, -372, 53, -49, +287, 217, 172, 164, -203, -5, -312, -127, +16, -135, 236, 48, 55, 220, -208, 82, +-203, -256, 49, -311, 231, 121, 94, 491, +-213, 172, -277, -394, -68, -355, 107, 72, +162, 200, 161, 112, -47, 130, -368, 64, +-340, -238, 104, -369, 393, 20, 223, 432, +-175, 272, -364, -172, -196, -316, 104, -147, +231, 104, 187, 247, -27, 124, -296, -129, +-265, -166, 144, -10, 330, 85, 32, 30, +-205, -29, -61, 9, 59, 16, 7, -41, +35, 50, 62, 149, -79, -116, -63, -371, +178, 3, 136, 542, -163, 284, -148, -436, +154, -498, 196, 137, -37, 457, -111, 73, +56, -289, 94, -81, -57, 216, -48, 24, +197, -235, 218, -22, -112, 214, -316, 46, +-34, -125, 325, -37, 274, 33, -27, 27, +-167, 29, -152, -40, -39, -78, 145, 38, +219, 80, 93, -25, -40, 7, -137, 88, +-174, -91, -4, -243, 254, 22, 203, 307, +-102, 139, -196, -171, -19, -172, 52, 7, +-8, 47, 49, -30, 108, 0, -52, 164, +-195, 152, -56, -167, 159, -329, 140, 8, +-104, 318, -217, 90, -40, -211, 144, -53, +54, 191, -95, 61, -119, -211, -52, -199, +63, 94, 131, 309, -83, 126, -303, -216, +-78, -224, 315, 11, 167, 100, -307, 90, +-303, 86, 130, -14, 216, -127, -96, -95, +-216, -12, 45, 110, 225, 221, -15, -9, +-377, -367, -256, -142, 288, 388, 468, 278, +-12, -264, -500, -331, -340, 69, 223, 263, +433, 66, 32, -163, -304, -59, -117, 175, +162, 29, 35, -314, -141, -134, 43, 363, +272, 332, 23, -175, -314, -391, -145, -128, +310, 199, 299, 276, -137, 61, -319, -208, +52, -158, 357, 92, 100, 71, -273, -104, +-138, 35, 240, 194, 275, -58, -11, -233, +-214, 71, -128, 209, 88, -126, 202, -247, +185, 99, 89, 346, -108, 160, -278, -273, +-157, -530, 243, -119, 478, 636, 183, 621, +-378, -297, -471, -809, 72, -236, 562, 554, +290, 575, -364, -88, -449, -585, 140, -286, +446, 361, 127, 467, -238, -13, -264, -409, +-107, -350, 175, 90, 366, 501, 149, 321, +-324, -297, -451, -485, -45, -99, 390, 240, +333, 299, -109, 191, -425, -167, -229, -443, +247, -81, 329, 443, -127, 245, -419, -333, +-91, -352, 300, 167, 214, 457, -166, 143, +-311, -404, -139, -493, 100, 45, 203, 567, +114, 414, -178, -238, -362, -563, -85, -208, +305, 311, 232, 366, -153, 63, -334, -212, +-176, -264, 104, -62, 338, 224, 257, 274, +-253, 0, -668, -336, -230, -306, 642, 161, +682, 485, -245, 183, -806, -321, -270, -409, +522, -91, 511, 321, -134, 423, -459, -58, +-140, -516, 267, -131, 284, 498, 13, 252, +-192, -437, -181, -424, -40, 177, 142, 527, +327, 304, 271, -252, -203, -635, -596, -344, +-248, 443, 602, 805, 828, 173, -28, -747, +-887, -730, -526, 279, 542, 903, 863, 259, +119, -714, -657, -640, -510, 285, 290, 769, +703, 265, 220, -535, -477, -724, -492, -23, +171, 797, 617, 594, 240, -452, -408, -828, +-415, -42, 148, 645, 456, 361, 141, -258, +-265, -432, -241, -107, 61, 345, 202, 375, +119, -170, -63, -525, -146, -60, -55, 531, +50, 297, 56, -384, 88, -443, 50, 117, +-193, 430, -276, 168, 95, -211, 393, -319, +81, -143, -408, 197, -334, 463, 175, 222, +363, -479, 9, -737, -314, 60, -166, 983, +140, 654, 75, -679, -194, -1273, -62, -159, +271, 1370, 95, 1136, -415, -777, -363, -1706, +246, -229, 510, 1519, -4, 1112, -603, -686, +-392, -1424, 394, -332, 632, 1088, -45, 1088, +-709, -324, -497, -1343, 323, -602, 790, 991, +319, 1352, -631, -60, -933, -1513, -51, -1092, +974, 833, 760, 1842, -428, 449, -1032, -1655, +-387, -1656, 683, 559, 964, 2097, 79, 890, +-972, -1544, -813, -1939, 455, 288, 1186, 2088, +400, 1037, -885, -1287, -1029, -1772, 124, -56, +1135, 1557, 774, 1253, -521, -515, -1162, -1720, +-295, -822, 986, 1259, 1020, 1797, -246, -120, +-1158, -1961, -531, -1164, 850, 1223, 1146, 1981, +-70, 105, -1163, -1908, -670, -1410, 714, 912, +1171, 2038, 143, 528, -1015, -1678, -832, -1672, +400, 579, 1107, 2000, 431, 667, -717, -1486, +-901, -1509, 21, 451, 859, 1688, 653, 669, +-298, -1200, -875, -1479, -371, 283, 586, 1713, +759, 706, -24, -1329, -670, -1398, -414, 536, +293, 1629, 496, 393, 22, -1391, -374, -1208, +-196, 769, 149, 1682, 184, 125, 14, -1597, +-74, -973, -160, 933, -225, 1378, 25, 1, +451, -1175, 306, -716, -437, 613, -752, 988, +-78, -84, 774, -949, 695, -271, -316, 818, +-1032, 576, -511, -613, 635, -922, 1020, 183, +167, 1164, -951, 489, -966, -1056, 223, -1195, +1171, 469, 620, 1632, -816, 466, -1225, -1524, +33, -1426, 1258, 791, 707, 2004, -841, 381, +-1220, -1861, 81, -1535, 1260, 952, 720, 2151, +-807, 414, -1260, -1919, -53, -1700, 1246, 890, +920, 2386, -677, 573, -1407, -2160, -162, -1890, +1369, 1090, 950, 2530, -868, 398, -1421, -2255, +181, -1722, 1556, 1214, 597, 2416, -1265, 182, +-1257, -2290, 639, -1449, 1687, 1429, 320, 2168, +-1539, -137, -1209, -2087, 818, -1090, 1692, 1260, +349, 1776, -1359, -77, -1299, -1704, 410, -949, +1587, 1047, 749, 1453, -961, -174, -1356, -1381, +-31, -550, 1167, 921, 787, 947, -385, -309, +-794, -984, -316, -231, 291, 736, 573, 553, +359, -374, -223, -646, -680, 25, -379, 541, +504, 226, 886, -316, 94, -284, -911, 98, +-789, 127, 350, -61, 1191, 116, 597, 311, +-982, -191, -1508, -734, 103, -128, 1894, 1032, +1089, 836, -1485, -866, -2131, -1637, 281, 46, +2409, 2045, 1231, 1290, -1679, -1575, -2448, -2570, +114, 132, 2621, 3057, 1532, 1757, -1731, -2343, +-2584, -3246, 190, 655, 2628, 3720, 1284, 1337, +-1938, -3049, -2334, -3024, 724, 1434, 2704, 3948, +632, 774, -2424, -3751, -1855, -3005, 1472, 2295, +2537, 4489, -256, 80, -2603, -4624, -962, -2603, +2131, 3330, 1941, 4467, -1312, -998, -2682, -5121, +88, -1716, 2898, 4310, 1428, 4025, -2338, -2157, +-2805, -5116, 956, -661, 3484, 4532, 872, 3084, +-3195, -2624, -2566, -4267, 1928, 291, 3690, 4095, +19, 1645, -3766, -3017, -2056, -2857, 2652, 1498, +3512, 3343, -668, 142, -3753, -3105, -1441, -1561, +2847, 2264, 2956, 2439, -1171, -1197, -3375, -2713, +-600, 239, 2876, 2623, 1993, 580, -1638, -2348, +-2676, -1418, 172, 1750, 2619, 2200, 1160, -707, +-1803, -2553, -1919, -555, 712, 2241, 2038, 1583, +274, -1439, -1637, -2111, -882, 480, 1105, 2179, +1193, 470, -526, -1861, -1272, -1312, -15, 1204, +1246, 1898, 513, -361, -1054, -2044, -986, -435, +705, 1771, 1391, 1000, -64, -1238, -1481, -1257, +-797, 629, 1040, 1247, 1403, -140, -105, -1087, +-1353, -126, -805, 966, 644, 263, 1096, -1023, +256, -517, -743, 1104, -837, 1034, 22, -878, +849, -1635, 590, 175, -489, 1933, -873, 810, +-128, -1728, 757, -1654, 722, 1106, -386, 2088, +-1169, -328, -256, -2126, 1274, -428, 922, 1902, +-976, 1111, -1513, -1517, 208, -1716, 1742, 986, +703, 2183, -1442, -264, -1579, -2413, 570, -627, +1973, 2253, 565, 1595, -1710, -1610, -1611, -2456, +857, 500, 2047, 2899, 273, 892, -1859, -2704, +-1279, -2183, 1191, 1829, 1827, 2972, -342, -534, +-1907, -3059, -429, -725, 1581, 2580, 1017, 1672, +-1031, -1831, -1422, -2323, 396, 982, 1580, 2750, +330, 39, -1381, -2899, -893, -1209, 924, 2556, +1141, 2281, -445, -1712, -1099, -2975, 211, 591, +1106, 3193, 5, 611, -1163, -2986, -466, -1768, +1164, 2339, 1199, 2726, -729, -1236, -1781, -3235, +-90, -99, 1931, 3128, 1062, 1346, -1410, -2495, +-1763, -2273, 538, 1559, 2021, 2804, 473, -424, +-1721, -2911, -1353, -794, 1069, 2453, 1951, 1861, +-115, -1435, -2046, -2433, -838, 183, 1669, 2375, +1531, 918, -901, -1864, -1880, -1659, 67, 1119, +1884, 2008, 714, -221, -1497, -1952, -1298, -702, +839, 1417, 1518, 1374, -107, -527, -1483, -1534, +-501, -382, 1292, 1126, 959, 995, -901, -365, +-1353, -1117, 209, -438, 1386, 730, 586, 990, +-1021, -15, -1143, -1087, 349, -707, 1178, 770, +271, 1190, -934, -254, -723, -1388, 472, -315, +895, 1412, -2, 925, -809, -1245, -461, -1573, +363, 789, 628, 2085, 185, -65, -438, -2245, +-613, -733, -96, 2058, 590, 1397, 587, -1688, +-239, -1946, -719, 1183, -229, 2435, 416, -511, +448, -2770, 63, -330, -364, 2809, -527, 1159, +-3, -2587, 724, -1865, 584, 2219, -571, 2542, +-1123, -1672, 1, -3206, 1279, 750, 754, 3633, +-919, 521, -1269, -3542, 156, -1795, 1432, 2860, +738, 2731, -1085, -1803, -1485, -3179, 274, 623, +1854, 3168, 781, 513, -1525, -2782, -1630, -1404, +781, 2111, 2021, 1913, 161, -1347, -1924, -2069, +-1003, 626, 1587, 1938, 1770, 44, -930, -1546, +-2354, -587, 32, 853, 2657, 797, 1145, 4, +-2430, -525, -2278, -693, 1755, -165, 3147, 1009, +-713, 995, -3565, -981, -373, -1739, 3617, 753, +1513, 2344, -3279, -381, -2534, -2742, 2578, -157, +3316, 2846, -1553, 766, -3644, -2656, 455, -1186, +3461, 2300, 592, 1293, -2899, -1991, -1371, -1125, +2028, 1833, 1773, 831, -1115, -1749, -1819, -558, +318, 1616, 1599, 353, 358, -1253, -1403, -160, +-1004, 542, 1216, -134, 1680, 425, -1017, 623, +-2396, -1399, 643, -1235, 2960, 2070, 32, 1791, +-3282, -2264, -974, -2148, 3072, 1969, 1996, 2225, +-2350, -1272, -2922, -2065, 1047, 399, 3436, 1751, +582, 384, -3501, -1393, -2235, -927, 2887, 1076, +3392, 1231, -1900, -766, -3828, -1385, 688, 397, +3443, 1414, 338, 23, -2521, -1291, -874, -445, +1377, 1080, 776, 805, -556, -906, -235, -1086, +280, 832, -257, 1287, -358, -796, 421, -1330, +468, 674, -280, 1180, -359, -408, -89, -948, +29, -60, 620, 739, 580, 821, -1171, -624, +-1422, -1869, 1405, 580, 2225, 2894, -1074, -524, +-2788, -3403, 247, 361, 3039, 3096, 836, 90, +-3062, -2221, -1755, -959, 3039, 1446, 2419, 2118, +-2804, -1248, -2766, -3161, 2323, 1526, 3033, 3682, +-1384, -1713, -3063, -3675, 334, 1299, 2968, 3496, +630, -281, -2713, -3404, -1412, -980, 2405, 3278, +2081, 2134, -1975, -2770, -2638, -3059, 1442, 1764, +2917, 3763, -891, -549, -2967, -4071, 248, -519, +2876, 3751, 502, 1393, -2665, -2821, -1245, -2245, +2403, 1677, 1886, 3062, -2004, -801, -2287, -3476, +1433, 373, 2642, 3104, -618, -227, -2760, -2154, +-245, 160, 2632, 1292, 880, -109, -2300, -974, +-1213, 114, 1895, 1034, 1247, -192, -1738, -970, +-1194, 273, 1676, 648, 920, -321, -1702, -341, +-583, 393, 1478, 262, 101, -567, -1079, -298, +315, 825, 674, 281, -709, -1009, -555, -341, +1122, 905, 940, 774, -1489, -513, -1561, -1481, +1626, 25, 2124, 1957, -1372, 368, -2252, -1788, +862, -664, 1966, 1054, -363, 987, -1608, -200, +-9, -1280, 1196, -414, 146, 1255, -858, 673, +-204, -743, 429, -606, 16, 23, -156, 294, +184, 391, 99, 119, -339, -218, -117, -449, +350, -265, 23, 561, -216, 573, 370, -442, +288, -413, -709, 263, -483, -139, 875, -207, +839, 776, -701, 360, -964, -1187, 490, -580, +788, 1201, -395, 640, -364, -861, 328, -515, +-148, 358, -254, 431, 393, 124, 70, -627, +-383, -534, 53, 1044, 94, 911, -54, -1324, +131, -1254, -29, 1217, -107, 1515, 176, -782, +65, -1653, -204, 232, 39, 1667, 335, 317, +109, -1547, -555, -861, -262, 1249, 1015, 1389, +435, -760, -1366, -1760, -638, 107, 1464, 1840, +882, 614, -1318, -1592, -1264, -1287, 938, 1051, +1431, 1744, -725, -356, -1296, -1859, 513, -324, +804, 1709, -415, 857, -307, -1506, 265, -1235, +11, 1367, -90, 1486, 187, -1162, 49, -1594, +-352, 655, 54, 1480, 765, 189, -201, -1165, +-1191, -1092, 473, 757, 1543, 1703, -628, -347, +-1673, -1904, 502, -132, 1620, 1820, -226, 731, +-1647, -1623, -312, -1316, 1546, 1372, 763, 1676, +-1308, -1004, -1287, -1749, 727, 479, 1620, 1636, +-99, 96, -1673, -1411, -391, -512, 1421, 1076, +636, 619, -861, -628, -647, -479, 464, 226, +767, 288, -284, 8, -810, -213, 332, -117, +855, 243, -269, 229, -661, -264, -34, -391, +264, 151, 337, 492, 62, 165, -467, -416, +-337, -626, 154, 202, 376, 1008, 202, 6, +-275, -1033, -487, -94, 29, 667, 443, 48, +376, -214, -246, 37, -675, 140, 150, -64, +909, -525, -67, -19, -750, 976, 37, 209, +517, -1038, 171, -509, -125, 641, -396, 931, +-200, -165, 426, -1399, 485, 11, -184, 1643, +-781, -254, -274, -1449, 938, 705, 470, 846, +-1031, -1115, -492, -136, 873, 1370, 325, -391, +-458, -1457, -267, 716, -158, 1358, 278, -931, +791, -992, -76, 1055, -1201, 308, -166, -1023, +1485, 523, 605, 846, -1707, -1167, -913, -700, +1944, 1411, 1165, 755, -1942, -1417, -1249, -987, +1558, 1448, 1070, 1216, -1085, -1572, -742, -1171, +525, 1594, 309, 728, -110, -1375, 44, 17, +-496, 1035, -433, -819, 1117, -739, 737, 1392, +-1460, 415, -898, -1602, 1370, 115, 883, 1520, +-836, -788, -715, -1296, 193, 1221, 704, 1108, +452, -1062, -709, -1133, -910, 378, 782, 1384, +1193, 430, -921, -1635, -1274, -945, 967, 1470, +1220, 1058, -915, -705, -1103, -939, 415, -366, +856, 785, 274, 1184, -596, -617, -953, -1447, +296, 308, 1202, 1296, 67, 200, -946, -1095, +-453, -717, 314, 1014, 875, 967, 578, -931, +-1017, -954, -1335, 715, 791, 975, 1915, -274, +-264, -1262, -2128, -338, -274, 1610, 2106, 1048, +697, -1570, -1969, -1700, -1038, 965, 1590, 2098, +1200, -8, -1091, -2031, -1162, -922, 581, 1435, +779, 1546, -189, -476, -405, -1750, -110, -482, +156, 1477, 509, 1092, 34, -774, -937, -1271, +-207, -132, 1183, 1097, 600, 950, -1098, -620, +-975, -1470, 771, -196, 1305, 1637, -204, 1271, +-1430, -1516, -476, -2225, 1224, 1212, 1118, 2593, +-777, -807, -1533, -2219, 248, 345, 1478, 1351, +149, 166, -1188, -365, -421, -580, 735, -491, +571, 619, -270, 1059, -496, -169, -99, -1176, +46, -494, 226, 770, 637, 868, 45, -11, +-1062, -671, -422, -709, 934, 48, 656, 1017, +-427, 629, -415, -783, -140, -1070, -56, 144, +389, 1129, 540, 616, -409, -747, -838, -1149, +213, -44, 814, 1237, 89, 947, -625, -876, +-404, -1515, 343, 257, 502, 1463, -125, 385, +-391, -893, 129, -933, 127, 209, -159, 1301, +-44, 223, 193, -1407, 229, -283, -98, 1248, +-477, 101, -130, -954, 497, 53, 431, 727, +65, 81, -725, -615, -1155, -589, 704, 384, +2430, 1270, -133, 200, -3350, -1773, -1015, -1145, +3552, 1723, 2279, 2097, -2986, -1083, -3162, -2619, +1956, 139, 3320, 2489, -846, 642, -2854, -1898, +43, -939, 2177, 1238, 345, 814, -1588, -836, +-467, -595, 1226, 721, 640, 600, -949, -683, +-949, -851, 665, 448, 1323, 1023, -343, 41, +-1513, -803, -2, -573, 1325, 123, 341, 803, +-861, 713, -513, -527, 332, -1201, 364, -144, +-66, 941, 22, 793, 225, 76, -273, -910, +-616, -1353, -12, 297, 821, 2156, 878, 772, +-483, -1993, -1767, -1671, -438, 967, 2212, 1852, +1615, 329, -1958, -1197, -2639, -1275, 1248, 68, +3187, 1578, -460, 907, -3075, -1341, -169, -1268, +2441, 906, 438, 1050, -1583, -637, -493, -737, +844, 682, 492, 817, -212, -823, -632, -1294, +-428, 623, 737, 1587, 1210, 117, -526, -1124, +-1814, -999, -186, -70, 1927, 1234, 1212, 1309, +-1396, -388, -2052, -1789, 357, -1103, 2258, 1191, +801, 2214, -1635, 180, -1639, -2118, 357, -1640, +1706, 839, 947, 2469, -902, 870, -1645, -2210, +-438, -2085, 1394, 941, 1520, 2310, -417, 707, +-1885, -1693, -634, -1844, 1469, 779, 1318, 2053, +-781, -79, -1443, -1664, 178, -244, 1238, 1358, +219, 407, -872, -1408, -513, -744, 481, 1385, +741, 1304, -3, -694, -814, -1743, -636, -648, +617, 1572, 1234, 1879, -91, -643, -1550, -2195, +-504, -634, 1232, 1454, 930, 1524, -568, -325, +-929, -1524, 33, -293, 586, 799, -93, -24, +-195, -158, 655, 893, 157, 369, -1089, -1415, +-551, -1400, 775, 872, 1143, 2350, 279, 657, +-1309, -2188, -1452, -2312, 851, 786, 1931, 3103, +-110, 964, -1535, -2660, -152, -1854, 784, 1497, +-468, 1437, -517, -533, 1515, -300, 1030, 351, +-2041, -520, -1874, -802, 1446, 459, 2227, 1197, +-164, 193, -1650, -911, -935, -596, 560, -23, +1156, 193, 394, 951, -686, 773, -570, -1145, +171, -1517, 126, 460, -148, 1358, 379, 511, +621, -297, -302, -901, -1128, -981, -423, 337, +1190, 1632, 1240, 684, -797, -1286, -1411, -1183, +313, 340, 753, 604, -285, 311, 150, 582, +768, -13, -475, -1310, -1425, -1032, -67, 962, +1682, 1998, 992, 85, -1406, -2165, -1434, -941, +872, 1464, 1170, 1063, -491, -429, -581, -576, +351, -325, 289, -49, -123, 494, -445, 407, +-359, -224, 577, -279, 957, -14, -328, -230, +-1266, -241, -264, 728, 1013, 1069, 698, -672, +-479, -2017, -624, -129, 67, 2420, 206, 1249, +-104, -1921, 13, -1950, 371, 770, 330, 1793, +-373, 359, -988, -982, -235, -882, 1325, 98, +1262, 672, -738, 371, -1960, -92, -593, -402, +1677, -383, 1851, 284, -424, 522, -2176, -284, +-952, -383, 1385, 481, 1452, 163, -165, -780, +-820, -46, -547, 971, -309, 104, 382, -835, +897, -259, 240, 284, -580, 294, -566, 438, +-155, -25, 203, -913, 522, -438, 491, 907, +-140, 788, -964, -570, -495, -774, 904, 264, +820, 443, -591, -233, -517, -86, 442, 421, +23, -9, -606, -609, 227, -246, 766, 556, +-91, 670, -622, -158, -153, -947, 262, -467, +190, 866, -12, 992, -126, -506, 68, -1122, +123, 144, -116, 822, -295, 29, -188, -334, +401, 13, 849, -40, -186, -213, -1344, 130, +-335, 551, 1162, 32, 796, -941, -287, -316, +-651, 1145, -541, 576, -221, -962, 536, -734, +1176, 400, 447, 749, -1335, 309, -1543, -542, +313, -842, 1700, 40, 1133, 1000, -633, 608, +-1789, -784, -859, -1047, 1108, 394, 1571, 969, +315, -101, -1144, -453, -1270, 99, 118, -55, +1270, -323, 514, 156, -725, 500, -483, 131, +441, -340, 171, -346, -564, -133, -201, 91, +576, 474, 596, 566, 39, -184, -870, -1034, +-1057, -772, 491, 747, 1710, 1772, 458, 263, +-1380, -2054, -1323, -1380, 280, 1361, 1395, 1883, +753, -161, -633, -1479, -951, -765, -249, 464, +363, 889, 462, 468, 293, -358, 56, -766, +-282, -116, -582, 456, -364, -135, 310, -173, +918, 988, 752, 543, -669, -1497, -1774, -1399, +-451, 869, 1834, 1824, 1689, 577, -778, -1115, +-2139, -1601, -591, -393, 1533, 1334, 1350, 1512, +-384, -247, -1154, -1429, -505, -397, 493, 473, +816, -84, 42, 261, -724, 1050, -235, -55, +578, -1282, 242, -731, -421, 313, -235, 1068, +154, 1060, 160, -377, 92, -1540, 17, -788, +-114, 698, -70, 1347, -315, 628, -229, -895, +801, -1239, 913, 140, -830, 878, -1557, -15, +184, -373, 1645, 567, 802, 605, -1059, -910, +-1380, -1476, 218, 218, 1293, 1987, 337, 1202, +-783, -1303, -408, -2156, 390, -274, 312, 1734, +-364, 1519, -486, -309, 408, -1490, 1044, -811, +-175, 493, -1609, 693, -466, 263, 1619, 247, +1076, 29, -886, -782, -1201, -932, -230, 238, +627, 1365, 1002, 840, 353, -771, -936, -1381, +-1073, -322, 122, 944, 1070, 1003, 767, -38, +-301, -856, -985, -580, -591, 203, 437, 630, +884, 343, 359, -397, -404, -451, -663, 278, +-433, 239, 211, -363, 871, -56, 576, 473, +-602, 103, -1083, -430, -123, -287, 853, 252, +679, 377, -112, -62, -688, -283, -605, -84, +335, 91, 889, 254, -54, 67, -750, -408, +103, -103, 557, 401, -241, -47, -510, -207, +234, 352, 608, 74, -47, -570, -656, -204, +-165, 419, 590, 428, 257, 84, -428, -329, +-478, -510, 210, -131, 859, 492, 137, 485, +-1282, -211, -625, -318, 1231, 186, 1071, -149, +-567, -597, -1164, 268, -227, 967, 849, 176, +466, -760, -429, -619, 51, 123, 344, 384, +-643, 190, -521, 357, 611, 276, 543, -631, +11, -945, -46, -114, -459, 785, -633, 1052, +174, 340, 838, -814, 424, -1243, -377, -716, +-564, 776, -282, 2015, -36, 678, 349, -1659, +671, -1513, 212, 95, -534, 833, -785, 889, +-282, 527, 594, -336, 873, -1071, 266, -810, +-386, 468, -888, 978, -760, 175, 585, -5, +1453, 144, 434, -804, -958, -1028, -1131, 410, +-208, 1204, 890, 543, 925, -317, -11, -604, +-734, -504, -715, -511, 40, 111, 776, 1490, +422, 1115, -488, -1148, -450, -1703, 313, -67, +405, 982, -444, 735, -610, 147, 490, -301, +910, -436, -101, -364, -793, -161, -499, 269, +199, 650, 780, 387, 462, -441, -511, -648, +-601, 65, 79, 182, 230, -271, -11, 276, +240, 899, 402, 18, -414, -1160, -889, -832, +268, 702, 1037, 1350, -107, -38, -885, -1189, +106, -253, 737, 713, -145, 226, -834, -420, +32, -293, 966, 359, 220, 558, -846, -307, +-320, -710, 515, 230, 93, 554, -216, -274, +320, -321, 274, 416, -530, 274, -562, -401, +201, -315, 666, 127, 493, 263, -288, 220, +-950, -195, -349, -462, 764, 345, 612, 704, +-259, -583, -439, -1018, 13, 456, 315, 1207, +-70, 180, -647, -980, -54, -837, 1036, 432, +559, 932, -857, -67, -949, -551, 116, 177, +691, 394, 489, -355, 79, -780, -307, -14, +-594, 1079, -458, 772, 271, -565, 1030, -960, +601, -407, -832, 81, -1129, 634, 124, 997, +810, 288, 343, -976, -82, -1227, -292, -188, +-279, 864, 61, 1103, 95, 563, -25, -638, +165, -1427, 85, -689, -109, 688, 83, 1313, +-113, 770, -475, -632, 171, -1272, 769, -298, +73, 449, -685, 151, -348, 317, 298, 877, +417, 264, 23, -1346, -305, -1648, -108, 457, +274, 2202, 45, 947, -349, -1242, -68, -1409, +389, -172, 204, 616, -297, 565, -420, 302, +118, 209, 667, -187, 211, -874, -701, -798, +-650, 350, 219, 1394, 815, 893, 578, -769, +-444, -1398, -927, -427, -193, 557, 570, 942, +454, 676, -38, -486, -298, -1111, 74, -115, +238, 691, -492, 135, -558, -275, 526, 175, +828, 314, 120, -186, -522, -358, -822, -108, +-218, -55, 837, 143, 657, 592, -210, 266, +-419, -566, -264, -550, 11, -21, 122, 247, +-189, 479, 75, 296, 797, -438, 311, -430, +-837, 320, -967, 251, -122, -450, 884, -339, +1101, 416, 84, 653, -952, 208, -875, -438, +-99, -916, 621, -510, 756, 792, 147, 1227, +-350, 68, -289, -767, -331, -476, -385, -376, +297, -291, 955, 763, 283, 1384, -623, 73, +-517, -1425, -131, -980, 14, 365, 398, 803, +407, 532, 12, 64, -46, -463, -336, -455, +-769, 5, 47, 166, 1110, 45, 469, -47, +-679, 133, -623, 462, 47, 15, 362, -769, +293, -349, -48, 470, -338, 325, -146, -6, +290, 7, 249, 17, -118, -10, -251, -362, +-130, -498, 92, 414, 265, 919, 78, 7, +-107, -689, -45, -416, -209, 44, -205, 412, +354, 378, 399, -151, -181, -382, -357, -56, +-120, 269, 126, 219, 297, -159, 20, -446, +-204, -192, 21, 488, 14, 693, -169, -103, +49, -734, 243, -300, 87, 144, -162, 169, +-303, 370, 33, 290, 387, -187, 103, -343, +-197, -313, -119, -146, -156, 296, -20, 420, +372, 283, 145, 22, -332, -702, -89, -685, +308, 518, -61, 847, -525, -23, -105, -516, +647, -399, 557, 212, -220, 726, -721, -88, +-475, -982, 269, -142, 719, 920, 348, 441, +-317, -502, -500, -482, -59, 147, 318, 225, +-52, -184, -257, -50, 360, 328, 444, 51, +-387, -286, -554, 39, -1, 304, 438, -161, +534, -541, -213, -36, -920, 488, -76, 362, +905, 214, 326, -175, -399, -929, -373, -509, +-273, 781, 103, 856, 584, 26, 225, -470, +-390, -534, -183, -21, 145, 416, -205, 23, +-322, -156, 424, 172, 793, 104, -46, -55, +-848, -73, -558, -235, 236, -71, 607, 238, +363, 93, -14, -11, -173, 117, -375, 44, +-514, -252, -69, -432, 657, 8, 753, 631, +58, 364, -730, -292, -716, -354, -10, -221, +501, -31, 468, 337, 230, 252, -79, -34, +-471, 52, -523, -133, -53, -591, 520, -235, +570, 699, 139, 799, -369, -150, -554, -836, +-201, -470, 242, 235, 257, 402, 195, 205, +235, 128, -46, 56, -415, -121, -426, -275, +-156, -493, 348, -356, 778, 648, 246, 1119, +-758, -96, -638, -843, 399, 30, 523, 109, +-255, -860, -344, -352, 271, 1183, 392, 1262, +-65, -157, -439, -1326, -271, -982, 329, 482, +464, 1012, -95, -60, -396, -646, -204, 320, +114, 880, 421, -238, 237, -1258, -351, -464, +-329, 944, 53, 925, 68, -205, 41, -693, +86, -211, 102, 148, 252, 153, -50, 257, +-742, 106, -379, -346, 738, -260, 770, 150, +-246, 116, -699, 80, -215, 188, 286, -74, +269, -216, 111, -3, -44, -103, -213, -133, +-115, 315, 128, 385, 6, -40, -139, -417, +77, -610, 346, -10, 188, 1159, -454, 816, +-627, -966, 239, -1326, 716, 33, -28, 723, +-374, 501, 98, 556, 110, 225, -250, -923, +-157, -1235, 188, -54, 258, 1029, -34, 915, +-267, 81, 33, -583, 280, -592, -2, -186, +-252, 169, -174, 378, 60, 303, 296, -116, +131, -402, -253, -117, -75, 445, 204, 351, +-68, -528, -251, -699, 22, 343, 190, 878, +197, 218, 119, -548, -273, -777, -523, -236, +25, 717, 687, 742, 420, -52, -336, -281, +-599, -231, -306, -679, 232, -591, 627, 744, +277, 1614, -380, 399, -292, -1396, 151, -1317, +-17, 136, -404, 922, -53, 599, 639, -19, +520, -256, -279, -162, -524, -185, -358, -245, +-228, -34, 465, 394, 993, 586, -27, -135, +-1038, -990, -366, -198, 473, 1146, 404, 573, +127, -891, -237, -973, -443, 116, 47, 1038, +473, 746, 91, -525, -364, -1012, -212, -148, +239, 601, 342, 394, -70, -95, -381, -171, +-79, 1, 243, -54, 27, -218, -184, -97, +146, 223, 392, 394, -7, 205, -513, -240, +-479, -593, 113, -445, 715, 425, 495, 952, +-356, 14, -642, -814, -131, -124, 373, 429, +315, 1, -202, -276, -381, -220, 230, 150, +536, 738, -97, 262, -567, -854, -244, -702, +255, 338, 426, 745, 200, 261, -243, -434, +-474, -383, -165, 187, 450, 148, 519, -185, +-219, -98, -602, 138, -3, 354, 472, 193, +29, -464, -418, -466, 38, 231, 560, 334, +13, -49, -611, -208, -134, 22, 395, 561, +193, 325, -73, -890, -258, -1032, -184, 378, +389, 1265, 397, 629, -386, -583, -503, -1015, +121, -262, 388, 500, 148, 439, -267, 74, +-242, -145, 364, -32, 370, 145, -543, -290, +-671, -599, 426, 241, 926, 914, -25, 181, +-843, -668, -349, -406, 440, 209, 496, 195, +96, -42, -476, 51, -569, 68, 367, 0, +842, 141, -233, -125, -852, -538, 96, 40, +686, 660, 16, 127, -490, -439, -97, -194, +340, 227, 200, 283, -220, -101, -353, -441, +6, -171, 452, 332, 307, 445, -301, 104, +-464, -300, -29, -244, 303, -76, 202, -246, +-52, -16, -79, 666, 49, 560, -45, -354, +-222, -793, -50, -219, 245, 507, 251, 353, +-83, -252, -407, -238, -136, 184, 509, 326, +358, 64, -482, -395, -573, -401, 202, 123, +601, 408, 192, 297, -362, -114, -386, -612, +79, -163, 339, 713, 68, 263, -183, -506, +-71, -113, 83, 116, 17, -294, -98, -8, +-43, 576, 238, 279, 237, -370, -250, -437, +-484, -35, -39, 174, 414, 102, 452, 201, +22, 183, -588, -324, -474, -439, 328, 171, +546, 418, 67, 107, -230, -103, -268, -298, +-148, -388, 139, 137, 271, 670, 153, 333, +-110, -401, -260, -625, -51, -207, 144, 350, +-24, 509, -33, 130, 100, -292, 14, -220, +84, 73, 172, -16, -262, -268, -546, -33, +-15, 466, 638, 437, 560, -165, -241, -611, +-826, -376, -315, 294, 663, 633, 625, 141, +-389, -585, -729, -432, 189, 400, 723, 628, +-49, -55, -634, -677, -61, -367, 582, 508, +231, 521, -580, -383, -531, -348, 425, 483, +694, 113, -53, -665, -442, -68, -222, 689, +-21, 295, 197, -407, 226, -642, -151, -205, +-258, 650, 141, 798, 401, -106, 79, -799, +-539, -456, -523, 251, 308, 423, 739, 138, +98, -23, -582, -35, -330, -94, 379, -168, +352, -170, -310, 126, -338, 454, 242, 61, +227, -552, -212, -263, -77, 441, 304, 477, +87, -171, -366, -591, -222, -35, 196, 573, +95, -24, -59, -610, 222, 129, 184, 712, +-355, 37, -336, -637, 166, -277, 218, 393, +-64, 226, -30, -409, 145, -76, 45, 745, +-207, 225, -164, -878, 98, -537, 148, 519, +-28, 515, -50, -32, 69, -53, -5, -132, +-191, -517, -74, -115, 244, 782, 179, 547, +-148, -452, -199, -686, -103, -313, -105, 157, +174, 779, 557, 699, 83, -453, -767, -1108, +-458, -249, 555, 838, 461, 628, -342, -352, +-229, -505, 337, 88, 120, 128, -338, -173, +-239, 117, 47, 509, 238, 148, 297, -640, +-63, -798, -399, 130, -130, 1042, 187, 624, +142, -495, 95, -772, -102, -149, -374, 270, +-5, 137, 492, 121, 113, 322, -457, 33, +-236, -535, 259, -416, 228, 244, -97, 528, +-165, 226, 41, -190, 91, -351, -93, -360, +-224, -149, 29, 549, 478, 895, 252, -77, +-583, -1135, -660, -654, 251, 571, 696, 908, +262, 218, -304, -491, -498, -489, -176, -48, +266, 196, 208, 121, -46, -23, 81, 167, +124, 451, -285, -172, -482, -1108, 74, -406, +633, 1193, 307, 1088, -469, -460, -588, -1171, +69, -462, 540, 558, 136, 809, -340, 182, +-88, -397, 165, -446, -121, -290, -118, 130, +105, 655, -46, 373, -10, -493, 351, -575, +65, 100, -634, 337, -475, 82, 517, 75, +837, 112, -173, -274, -899, -468, -134, 76, +628, 603, 136, 363, -417, -331, -57, -686, +328, -144, -38, 688, -410, 454, 20, -473, +446, -443, 4, 302, -402, 350, -151, -245, +127, -468, 235, 81, 224, 716, -215, 340, +-501, -673, -42, -741, 398, 184, 239, 756, +-100, 358, -228, -460, -202, -578, -43, 264, +122, 586, 186, -268, 124, -576, -76, 257, +-335, 498, -242, -193, 224, -342, 343, 155, +-24, 282, -172, -59, -135, -367, -112, -242, +94, 347, 160, 566, -122, -95, -74, -608, +148, -223, -67, 341, -179, 383, 115, 7, +130, -317, -277, -149, -263, 150, 362, -24, +515, -161, -295, 222, -689, 417, -38, -61, +400, -552, 220, -372, 79, 240, -141, 552, +-434, 286, -190, -223, 284, -496, 310, -239, +31, 267, -182, 381, -221, 132, -113, -101, +24, -369, 83, -399, 172, 234, 241, 769, +-100, 249, -600, -662, -366, -697, 462, 97, +641, 620, 17, 410, -548, -18, -438, -358, +131, -530, 368, -158, 52, 508, -152, 578, +-56, 18, 13, -465, 22, -521, -108, -70, +-204, 539, 120, 517, 277, -125, -82, -475, +-246, -210, -33, 97, 84, 115, 47, 85, +-61, 174, -116, 150, 71, -178, 52, -458, +-164, -173, -48, 463, 228, 548, 65, -149, +-308, -671, -266, -268, 154, 499, 360, 494, +85, -201, -311, -362, -397, 78, 43, 55, +531, -256, 219, 4, -542, 389, -541, 223, +229, -166, 619, -330, 138, -135, -471, 220, +-319, 162, 161, -194, 35, -88, -181, 290, +127, 177, 409, -217, 77, -241, -475, -17, +-530, 67, 113, 68, 537, 99, 141, 81, +-263, 2, -118, -144, 86, -200, -51, 44, +-277, 227, -110, 13, 371, -92, 310, 74, +-262, -53, -363, -211, -21, 71, 135, 260, +95, 88, 19, -115, -48, -321, -102, -198, +-103, 427, -9, 487, 68, -341, -2, -575, +46, 195, 108, 490, -136, -87, -309, -351, +-98, 1, 200, 192, 290, 54, 111, -31, +-300, -45, -398, -81, 50, -11, 392, 130, +18, 100, -442, -165, -34, -213, 501, 182, +66, 287, -502, -136, -196, -213, 202, 104, +72, 51, 14, -156, 90, -77, -36, 135, +-196, 374, -65, 179, 95, -602, -27, -651, +-146, 395, 38, 791, 215, 96, 72, -335, +-176, -291, -365, -299, -131, -26, 396, 506, +342, 416, -275, -245, -348, -433, 85, 23, +141, 231, -120, -84, -140, -240, 137, 101, +308, 391, -42, 142, -508, -276, -285, -299, +379, -75, 428, 29, -134, 123, -312, 300, +-3, 297, -23, -86, -240, -610, 132, -549, +472, 282, 18, 847, -487, 403, -315, -435, +54, -760, 327, -228, 414, 575, -33, 504, +-607, -199, -457, -284, 230, -27, 557, -94, +251, 88, -225, 334, -401, -54, -244, -333, +18, -66, 279, 90, 312, 150, -20, 229, +-346, -51, -226, -345, 107, -174, 181, 156, +42, 294, -132, 98, -157, -192, 11, -159, +172, -44, 84, 10, -63, 290, -182, 231, +-246, -416, 32, -435, 372, 303, 132, 453, +-265, -58, -120, -219, -5, 2, -178, -64, +47, -245, 414, 107, 117, 470, -446, 31, +-411, -415, 169, -112, 515, 175, 134, 83, +-410, 4, -298, -81, 96, -115, 180, 62, +61, 216, -53, 151, -124, -235, -15, -505, +98, 107, 41, 758, -101, 109, -227, -790, +-36, -340, 340, 630, 151, 542, -348, -333, +-101, -591, 296, -10, -151, 360, -435, 253, +211, 43, 517, -301, -59, -341, -382, 188, +-139, 328, -26, -61, 90, -88, 302, 90, +98, -58, -389, -271, -343, -159, 227, 312, +490, 539, -14, -15, -513, -583, -144, -379, +341, 141, 80, 428, -163, 291, 100, -145, +63, -282, -254, -80, -106, -32, 273, 19, +178, 200, -255, 169, -273, -90, 151, -299, +196, -162, -74, 268, 21, 329, 100, -88, +-240, -293, -242, -173, 159, -2, 259, 237, +103, 346, -62, 14, -305, -497, -215, -452, +314, 345, 384, 713, -225, -45, -455, -631, +165, -224, 451, 275, -124, 273, -362, -26, +169, -196, 249, 55, -295, 118, -252, -272, +395, -143, 348, 362, -383, 117, -429, -349, +250, -87, 365, 319, -100, 173, -176, -276, +46, -386, -46, 40, -143, 354, 141, 200, +339, -5, 24, -200, -360, -394, -158, -124, +181, 415, 121, 393, 76, -168, 113, -464, +-164, -166, -220, 320, 182, 401, 180, -116, +-200, -584, -129, -137, 164, 588, 154, 227, +49, -441, -74, -122, -281, 139, -146, -223, +316, 51, 385, 504, -72, -61, -335, -522, +-113, -113, 121, 93, 206, 45, 170, 350, +-68, 287, -236, -464, 29, -667, 267, 124, +68, 625, -205, 113, -109, -392, 191, -124, +250, 238, -32, 6, -281, -384, -115, -175, +233, 399, 222, 407, -75, -162, -120, -489, +64, -328, 20, 134, -111, 554, 83, 246, +279, -464, 88, -424, -190, 117, -177, 188, +57, -15, 242, -18, 152, 98, 39, 38, +34, -270, -79, -288, -254, 165, -128, 266, +328, -41, 592, -40, 201, -35, -599, -274, +-747, -170, 178, 180, 920, 263, 393, 78, +-432, -250, -400, -352, 7, 20, 108, 252, +160, -16, 267, -179, 161, 61, -87, 215, +-232, -131, -139, -483, 264, -129, 383, 400, +18, 270, -109, -86, 24, -218, -101, -335, +-30, -161, 371, 316, 193, 265, -306, -261, +-84, -258, 356, 213, 42, 163, -277, -343, +85, -319, 313, 148, 9, 181, -94, -8, +140, 71, 61, -6, -180, -309, 30, -330, +382, -41, 293, 304, -107, 370, -273, -13, +-54, -414, 220, -441, 351, -143, 313, 364, +-88, 445, -429, -189, -93, -422, 397, 3, +366, -2, 21, -212, -155, 92, -116, 266, +72, -97, 179, -381, 117, -194, 53, 302, +-26, 399, -6, -298, 251, -754, 191, -129, +-218, 619, -87, 470, 398, -214, 255, -627, +-177, -407, -38, 140, 343, 379, 171, 170, +-202, -92, -90, -199, 245, -276, 320, -248, +108, 54, -90, 265, -126, 99, 22, -88, +180, -190, 190, -316, 105, -101, 45, 282, +5, 85, -18, -324, -16, -133, 138, 194, +356, 56, 199, -198, -156, -230, -127, -161, +151, -8, 292, 214, 224, 205, 98, -137, +7, -368, -116, -264, -103, -101, 289, 140, +606, 411, 130, 97, -510, -579, -236, -495, +459, 238, 370, 392, -157, -162, -33, -424, +433, -2, 149, 329, -400, -8, -118, -423, +366, -329, 322, 64, 244, 367, 150, 206, +-181, -386, -207, -533, 179, 23, 360, 314, +287, 24, 153, -158, -88, -115, -111, -115, +151, -98, 209, -76, 82, -29, 182, 155, +134, 112, -135, -388, -68, -522, 317, 128, +304, 566, -73, 125, -110, -505, 135, -602, +223, -128, 132, 465, 31, 453, 66, -165, +197, -523, 181, -315, 55, -61, -27, 32, +38, 185, 340, 380, 402, 111, -150, -741, +-392, -971, 308, 189, 738, 1156, 48, 422, +-502, -817, -115, -884, 409, -79, 365, 490, +79, 390, 73, -122, 22, -410, -280, -207, +-75, 13, 591, -40, 504, -39, -160, 85, +-212, 23, 141, -176, 117, -276, 71, -170, +354, 184, 362, 379, -46, -154, -244, -744, +8, -313, 356, 532, 361, 528, 133, -180, +-58, -627, -115, -419, -10, 95, 242, 320, +353, 140, 84, -93, -139, -196, 106, -190, +244, -168, -104, -224, -89, -63, 415, 443, +419, 459, -115, -436, -203, -976, 192, -215, +289, 704, 97, 518, 88, -278, 118, -603, +45, -289, 186, 169, 393, 260, -16, -71, +-484, -262, 36, -2, 755, 125, 444, -226, +-246, -386, -345, 46, -52, 417, 287, 90, +422, -494, 189, -471, -115, 131, -32, 443, +148, 72, 67, -408, 44, -375, 232, 33, +275, 221, 58, 6, -71, -190, 103, -73, +248, 54, 113, -130, -15, -299, 134, -31, +240, 295, 68, 53, -57, -342, 113, -184, +191, 114, 49, -33, 18, -184, 137, 23, +207, 103, 52, -121, -154, -190, -9, -53, +357, 11, 333, 33, -13, -6, -130, -214, +6, -252, 99, 117, 232, 292, 374, -93, +169, -384, -180, -159, -159, 94, 173, 45, +325, -1, 172, 22, 62, -113, 50, -226, +19, -74, 11, 34, 61, -57, 183, 28, +215, 159, 41, -147, -111, -438, 23, -92, +230, 336, 208, 163, 58, -269, -17, -333, +-38, -25, 50, 204, 286, 60, 367, -156, +93, -127, -284, -89, -270, -143, 273, 29, +650, 241, 290, 30, -292, -289, -298, -275, +100, -97, 294, 105, 278, 271, 179, 61, +-46, -340, -178, -289, -50, 43, 174, 90, +320, 14, 168, 22, -86, -78, -31, -157, +141, -69, 60, -57, 10, -26, 184, 137, +179, 19, 60, -275, 96, -143, 3, 121, +-117, 28, 145, -92, 399, -78, 185, -78, +-94, 40, -114, 106, -82, -203, 91, -376, +424, 82, 374, 506, -201, 128, -464, -593, +-19, -585, 515, 215, 447, 664, -84, 113, +-280, -515, 31, -307, 171, 123, -5, -13, +91, -156, 366, 203, 163, 301, -233, -197, +-128, -467, 222, -162, 280, 198, 80, 232, +-62, -45, 18, -255, 152, -17, 128, 180, +22, -159, -42, -364, -21, 39, 94, 346, +233, 86, 159, -225, -43, -219, -30, -94, +52, 25, -52, 114, -35, 33, 262, -128, +364, -86, 93, 70, -192, 25, -270, -198, +-66, -263, 417, 55, 626, 441, 85, 216, +-520, -461, -391, -613, 217, -19, 595, 544, +329, 442, -190, -232, -316, -657, 33, -237, +259, 360, 113, 277, 6, -82, 62, -121, +75, -107, 9, -192, 27, -52, 31, 184, +-53, 115, 77, -98, 359, -107, 204, -79, +-275, -133, -230, -6, 234, 189, 303, 60, +31, -200, -47, -148, 22, 48, 52, 55, +140, -48, 80, -95, -160, -72, -24, 57, +422, 143, 284, -74, -323, -266, -399, -38, +134, 135, 481, -79, 273, -82, -122, 189, +-283, 75, -41, -268, 233, -266, 221, -13, +72, 205, -10, 238, 25, -8, -34, -291, +-150, -287, 34, -62, 462, 216, 357, 319, +-318, 1, -438, -392, 187, -292, 513, 127, +58, 255, -312, 6, -38, -157, 337, -41, +166, 14, -301, -162, -195, -123, 377, 239, +438, 212, -195, -302, -382, -348, 190, 227, +385, 318, -101, -232, -266, -344, 152, 108, +315, 267, 48, -12, -136, -206, -23, -158, +111, 1, 107, 126, 26, 76, -14, -76, +69, -98, 66, 1, -22, -15, -71, -99, +40, -55, 173, 73, 162, 139, -1, 66, +-199, -199, -41, -345, 250, -1, 167, 317, +-154, 101, -69, -114, 186, -18, 18, -101, +-95, -261, 130, -33, 218, 230, -58, 175, +-118, 41, 110, -131, 102, -356, -74, -224, +-43, 239, 171, 362, 142, 38, -67, -186, +-113, -194, 53, -200, 133, -62, 67, 215, +59, 285, 24, 67, -127, -219, -155, -385, +143, -219, 306, 250, 99, 464, -141, 76, +-163, -372, -48, -298, 156, 6, 334, 122, +104, 150, -253, 77, -245, -139, 73, -134, +267, 47, 140, -43, -47, -156, -59, 112, +79, 258, -32, -93, -150, -313, 122, -18, +337, 222, 8, 7, -368, -197, -113, -5, +275, 155, 265, -12, -51, -156, -218, -85, +-3, 60, 257, 167, 130, 44, -253, -254, +-193, -226, 194, 168, 318, 298, 75, 5, +-230, -247, -300, -214, 62, 10, 473, 213, +216, 134, -307, -126, -271, -136, 156, 36, +180, 26, -114, -80, -114, -68, 227, 42, +319, 168, -176, 90, -488, -222, -47, -237, +544, 127, 359, 167, -252, -108, -414, -37, +-105, 186, 247, 12, 247, -243, 35, -148, +-93, 57, -11, 146, -36, 174, -148, 36, +49, -227, 274, -215, 174, 70, -187, 152, +-359, -4, -110, -14, 372, 85, 441, 22, +-164, -141, -502, -186, -52, -26, 419, 240, +169, 260, -267, -102, -184, -348, 168, -85, +157, 264, -142, 160, -126, -170, 166, -169, +192, 132, -134, 199, -246, -138, 28, -265, +281, 154, 166, 349, -232, -112, -377, -406, +-2, -27, 430, 365, 258, 237, -199, -192, +-338, -365, -92, -12, 225, 304, 232, 95, +-35, -149, -222, -14, -41, 79, 83, -47, +-59, -108, -52, -18, 166, 162, 203, 203, +-156, -114, -360, -324, -37, 28, 374, 362, +195, 79, -275, -298, -241, -154, 84, 195, +145, 214, -13, -6, -16, -170, 7, -130, +-22, 94, -9, 164, -41, -27, -55, -93, +6, 74, 91, 75, 27, -90, -51, -66, +-124, 65, -112, 63, 159, 2, 277, -5, +-103, 8, -389, 44, -48, 49, 242, -81, +119, -173, -42, 53, -102, 329, -183, 126, +-46, -229, 241, -201, 114, -6, -148, 114, +-126, 222, 20, 134, -57, -170, -52, -218, +145, 27, 104, 166, -131, 104, -179, 32, +19, -37, 46, -169, 38, -61, 91, 230, +-5, 222, -241, -94, -180, -191, 151, -34, +212, 9, -11, 124, -195, 297, -123, 31, +24, -372, 100, -190, 80, 277, -67, 253, +-173, -69, -18, -105, 120, 91, -12, 62, +-183, -136, -47, -112, 211, 117, 134, 284, +-228, 92, -327, -214, 37, -188, 317, 56, +156, 243, -234, 134, -338, -138, -86, -156, +232, 90, 261, 224, -46, 61, -336, -169, +-259, -141, 188, 82, 331, 228, -39, 148, +-368, -100, -169, -219, 214, -28, 189, 231, +-137, 161, -228, -105, 45, -83, 129, 106, +-30, 68, -185, -74, -91, -59, 133, 147, +116, 186, -153, -61, -267, -199, 65, 7, +169, 240, -83, 90, -115, -93, 38, 20, +-17, 10, -189, -120, -20, 101, 164, 313, +-20, 0, -212, -268, -105, -96, 133, 154, +96, 285, -130, 126, -240, -252, -28, -213, +244, 196, 74, 240, -259, -42, -284, -73, +51, 80, 264, 82, 40, -76, -296, -104, +-235, 137, 174, 233, 172, -24, -166, -156, +-236, 22, 12, 133, 163, 3, -45, 0, +-283, 87, -91, -6, 183, -5, 100, 143, +-168, 70, -239, -192, -45, -71, 149, 264, +66, 206, -263, -111, -126, -132, 137, 87, +15, 64, -190, 12, -127, 88, 51, 66, +32, -37, -84, -3, -120, 86, -14, -8, +-3, 22, -140, 88, -104, -2, 31, 13, +73, 97, -120, 14, -205, -67, -39, 102, +42, 106, 58, -66, -32, -3, -220, 116, +-280, 84, 39, -59, 312, -33, 81, 150, +-344, 138, -512, -146, -21, -121, 459, 201, +204, 268, -328, 57, -407, -257, -147, -219, +34, 169, 169, 348, 119, 208, -99, -59, +-317, -287, -349, -225, -58, 212, 379, 458, +282, 129, -401, -244, -589, -177, -45, 84, +401, 155, 123, 82, -351, 34, -309, 84, +99, 84, 66, -101, -227, -197, -155, 103, +104, 475, 85, 162, -225, -458, -360, -266, +-105, 377, 275, 407, 105, 9, -313, -298, +-366, -157, -48, 230, 234, 291, -19, 6, +-298, -191, -231, 57, 91, 254, 58, 27, +-172, -253, -254, -61, -87, 345, 99, 310, +-52, -41, -92, -289, -188, -143, -176, 172, +-121, 312, 8, 201, 45, -160, -93, -208, +-128, 139, -228, 261, -176, -85, -51, -196, +94, 207, 4, 273, -279, -8, -137, -138, +-35, 39, -158, 132, -213, -36, 70, -114, +41, 124, -198, 393, -136, 202, -84, -252, +-170, -465, -182, -38, -9, 498, 25, 495, +-23, 98, -190, -386, -347, -400, -136, 21, +181, 377, 19, 427, -345, 89, -251, -216, +-21, -241, 87, -30, -27, 204, -234, 306, +-415, 146, -175, -159, 232, -186, 97, 65, +-166, 288, -321, 151, -258, -69, -140, -124, +-15, -22, 62, 154, -10, 184, -133, 157, +-287, 19, -286, -180, -176, -160, 2, 27, +270, 409, -1, 468, -518, -217, -460, -542, +53, 17, 207, 487, -87, 225, -200, -168, +-257, -30, -137, 174, -120, -14, -85, -139, +-62, 50, -44, 309, -99, 214, -308, -173, +-197, -207, -80, 116, 39, 269, -50, 107, +-174, -42, -263, -55, -204, -27, 11, 77, +-47, 305, -192, 91, -124, -261, -43, -24, +-255, 203, -209, 78, 41, 190, -100, 123, +-258, -426, -102, -76, 45, 662, -155, 121, +-362, -385, -242, -21, 217, 176, 98, 191, +-453, 119, -387, -150, 143, -72, 65, 233, +-333, 47, -239, -36, 23, 205, 54, 22, +-234, -181, -307, 121, -166, 276, -99, -106, +27, -146, -7, 268, -126, 322, -305, -208, +-331, -255, -176, 214, 104, 132, 199, 143, +-172, 117, -438, -98, -362, 79, 20, -102, +79, -147, -66, 399, -192, 336, -114, -227, +-182, -202, -299, 199, -113, 84, 136, -54, +77, 183, -466, 185, -417, -211, 90, -25, +173, 358, -151, -57, -236, -198, -228, 282, +-372, 107, -71, -253, 348, 184, 98, 326, +-506, -38, -549, -190, -61, -159, 125, 162, +78, 417, 13, 165, -289, -132, -411, -311, +-147, -99, -36, 417, -32, 214, 87, -107, +-35, 198, -347, -105, -364, -326, -234, 343, +106, 124, 418, -61, -314, 400, -598, -188, +-56, -331, 23, 407, -122, -20, 9, -206, +15, 571, -409, 79, -171, -596, -4, 266, +-222, 277, -2, -264, -7, 288, 44, 226, +-384, -228, -421, -119, 3, 137, 162, 268, +128, -20, -326, -151, -307, 214, -239, -11, +63, -77, -62, 350, -59, -162, 53, -121, +-287, 348, -349, -165, -159, 16, 188, 334, +10, -123, -236, -96, -136, 129, -194, 66, +-288, 60, 46, -56, 218, 78, -244, 298, +-249, -130, -153, -96, -191, 9, 7, -117, +141, 477, -203, 283, -213, -395, -153, -109, +-181, 57, 33, -16, 23, 478, -188, 156, +-114, -371, -228, -75, -44, 45, -100, 230, +-35, 266, -42, -201, -192, -125, -155, 188, +-48, 77, -146, 26, -143, 52, 198, -48, +-182, -32, -426, 146, 26, 188, 27, -82, +-92, -124, 23, 261, -193, 14, -340, -305, +-82, 182, 159, 402, 36, 70, -252, -219, +-302, -342, -14, 136, 89, 461, -259, 97, +-187, -164, 201, -101, 117, 118, -478, 22, +-596, -120, 339, 175, 375, 283, -113, -14, +-517, -156, -335, -141, 155, 59, 222, 362, +-258, 37, -309, -205, 247, 61, -51, 86, +-403, 80, -156, -5, 57, -143, 68, 171, +16, 218, -325, -123, -189, -56, 106, 77, +-155, 95, -100, 8, 17, -40, -269, 99, +23, -62, 171, 164, -339, 181, -263, -285, +113, -68, -89, 151, -51, 282, -21, 58, +-114, -268, -247, -140, 140, 321, -163, 254, +-212, -266, -132, -100, 154, 115, 200, 252, +-410, 90, -354, -306, -44, -67, 214, 352, +58, 97, -166, -101, -461, -118, -8, -18, +282, 356, -154, 15, -201, -201, -365, 11, +231, -38, 152, 409, -269, -26, -382, -406, +77, 256, 276, 238, -294, -136, -178, -53, +-259, -8, 189, 50, 119, 366, -229, -97, +-125, -331, -258, 26, 51, 310, -7, 187, +19, -253, -229, -57, -9, 146, -45, 87, +-169, 100, -81, -146, -192, -205, 165, 188, +22, 416, -225, -100, -129, -211, -72, -75, +-120, 9, 13, 273, 12, 41, -142, -114, +-63, 125, -57, 95, -99, -131, -98, -99, +-149, -88, -86, 182, 203, 492, -92, -65, +-152, -376, -212, -167, -189, 137, 45, 259, +101, 70, 47, -28, -161, 102, -419, -25, +66, -244, 78, -86, -61, 217, -188, 332, +20, -98, -127, -26, 7, 58, -30, -255, +-238, -30, -231, 126, 135, 155, 335, 503, +-354, -320, -303, -641, -191, 360, 339, 282, +34, 28, -351, -18, -90, -216, -145, 149, +166, 118, 165, 20, -484, -182, -192, 6, +169, 195, 57, 61, -265, -38, 19, -106, +-73, 230, 22, -76, -116, -153, -476, 96, +284, -14, 185, 302, -204, 40, -252, -208, +-111, -162, 109, 92, -201, 118, 110, 130, +-197, 194, 70, -265, -179, -118, -218, -28, +310, 292, -366, 187, 113, -355, -312, 51, +106, 170, 60, -128, -53, 110, -254, 169, +-157, -326, 26, 35, 3, 353, 122, -149, +-292, 30, -74, -137, -9, 68, -90, 221, +-81, -150, -17, -19, 180, -2, -428, 190, +-81, -40, 47, -119, 230, 97, -247, 40, +-205, -54, -175, 170, 26, -94, 119, -129, +91, 312, -173, -91, -358, -54, 56, -8, +-110, -57, -49, 267, 265, -24, 62, -120, +-514, -99, -159, 148, 60, 287, 48, -326, +103, -22, -89, 73, -64, 68, -386, 252, +172, -202, -233, -204, 181, 151, 61, 164, +-125, 34, -246, -279, -225, 131, 391, 307, +-343, -46, 92, -429, -115, -13, 122, 438, +-201, 334, -379, -476, 243, -385, 79, 542, +154, 50, -507, -72, -207, 20, 244, -248, +74, 254, 36, 122, -400, -197, 63, 108, +-161, -7, 249, -137, -214, 281, -107, -163, +128, 78, -178, -27, 20, 64, -284, 170, +190, -366, -23, 126, -92, 17, -24, 182, +-128, 238, -99, -467, -52, 143, 95, 26, +113, -284, -329, 526, 56, -33, -113, -12, +-148, -106, 240, -382, -46, 387, -180, 41, +-65, 109, -101, 119, 300, -391, -400, -46, +58, 298, 69, -24, -97, -52, 51, 174, +-247, -246, 45, 237, -121, -146, 341, -148, +-302, 337, -157, -28, 106, -61, -71, -114, +67, -34, -6, 269, -311, 86, 67, -231, +211, -110, -158, 107, -155, 110, -67, 187, +42, -157, 135, -291, 75, 396, -329, -127, +-345, -217, 380, 434, 191, -111, -70, -97, +-341, 64, -183, -133, 336, -68, -168, 157, +204, 326, -295, 27, 159, -435, -191, -333, +-97, 336, 115, 392, -60, 217, 348, -374, +-432, -323, -118, -123, -4, 219, 43, 691, +429, -246, -410, -452, 19, 108, -207, 33, +-15, -69, 268, 265, -168, -60, 165, 137, +-186, -73, -6, -386, -173, 22, -46, 377, +219, 195, 260, -256, -381, -84, -143, -255, +-17, 407, 136, 246, 229, -712, -238, 382, +-195, 181, 68, -316, 231, 454, -233, -463, +75, -368, -52, 957, 9, -279, -50, -360, +-111, 392, 140, -523, 114, 386, -73, 318, +-291, -624, 159, 180, -43, 242, 214, -273, +-170, 176, -135, 45, 166, -266, 27, 224, +-283, -79, 319, -176, -155, 519, -137, -284, +232, -430, -260, 742, 419, -673, -190, 247, +-402, 641, 395, -1114, -348, 743, 515, -162, +-31, -513, -411, 1061, -18, -849, 145, 39, +140, 529, 18, -520, -189, 299, -128, -150, +271, -257, 174, 489, -380, 87, -166, -597, +427, 261, -129, 129, 158, -362, -208, 544, +-79, -278, 159, -281, -44, 514, 29, -506, +149, 67, -339, 512, 346, -518, -37, 45, +-374, 323, 409, -589, -194, 294, 149, 331, +74, -388, -231, 260, -28, -385, 249, -242, +-70, 751, -17, -159, 48, -111, -264, -83, +343, -555, 137, 650, -384, 56, 164, 51, +10, -315, -5, -341, 34, 681, 61, -636, +20, 542, 94, 123, -246, -907, -149, 664, +425, 2, -37, -326, 20, 336, -101, -292, +-28, 17, 208, 392, -330, -659, 198, 154, +323, 611, -461, -662, 539, 53, -374, 185, +-65, -253, 200, 321, -31, -280, 445, -21, +-607, 361, 306, -685, 24, 638, -225, -287, +666, -528, -573, 1083, -53, -720, 487, -121, +-245, 639, 19, -758, 235, -91, -107, 936, +-173, -510, 323, -605, -265, 939, 257, -479, +105, -391, 30, 780, -256, -647, 96, 98, +-21, 461, 312, -463, 87, 24, -310, -168, +342, 84, -300, 269, 88, -296, 308, 183, +-145, -42, 70, -551, 173, 402, -173, 212, +-188, -351, 570, 242, -336, -162, 226, -261, +102, 244, -382, -89, 521, 92, -321, 39, +443, -231, -270, 27, -161, -126, 462, -53, +16, 713, -26, -858, -94, 126, 72, 319, +14, -645, 201, 789, 141, -412, -277, -397, +170, 495, 320, -113, -274, 47, 105, -256, +-23, -248, 50, 268, 513, 229, -171, 21, +-325, -368, 311, -322, -148, 226, 540, 282, +-156, -143, -343, -28, 735, -43, -412, -255, +83, 55, 355, 160, -461, -126, 413, -69, +488, 178, -658, -29, 124, -392, 348, 111, +-103, 71, 254, 133, 141, -167, -276, -247, +-11, 364, 457, -380, -195, 203, 226, -30, +292, -323, -544, 540, 410, -656, 172, 244, +-286, 424, 363, -969, 292, 679, -176, 94, +-87, -838, 99, 633, 25, -105, 432, -239, +52, 223, 21, -18, -224, -398, 95, 119, +291, 226, 64, -392, 213, 279, 185, 9, +-272, -270, -210, -82, 544, -41, 256, 389, +-181, -394, 383, -142, -349, 537, -48, -558, +773, -198, -393, 700, 181, -506, 377, -205, +-363, 375, 240, -374, 221, 197, -33, 203, +377, -491, -123, -14, -148, 56, 293, 80, +152, 48, 250, -372, 268, 429, -581, -85, +124, -717, 808, 513, -471, 4, 334, -317, +271, 479, -357, -130, 542, -575, -63, 55, +-174, 415, 275, -355, 316, 121, 316, 94, +-217, -292, -46, 26, 49, -109, 373, 133, +65, -364, 410, 312, -100, 361, -340, -754, +573, -172, 38, 566, 143, -76, 83, -471, +78, 375, 237, -337, -39, 23, 253, 415, +-101, -613, 380, 220, 144, -59, -204, -189, +227, 52, 358, 100, 114, 169, -32, -501, +-6, 132, 12, -5, 519, -274, 129, 140, +222, 330, -261, -226, -41, -264, 436, 18, +171, -247, 121, 189, 433, 337, -247, -291, +-291, -239, 623, 106, 139, -160, 112, -31, +380, 288, -398, -271, 290, -92, 301, 191, +-159, -278, 507, 44, 11, 84, -76, -369, +353, 314, -47, 66, 238, -446, 189, 258, +194, -307, -44, 324, -76, -116, 538, -446, +-126, 538, 502, -462, 25, 247, -263, 156, +312, -783, 117, 457, 296, 5, 233, -57, +150, 60, -72, -256, -191, -173, 345, 96, +580, 409, -75, -458, 255, -61, -287, 213, +131, -485, 327, 211, 447, 279, 130, -250, +-521, -55, 764, -265, -172, 121, -171, -20, +1053, -17, -367, 390, -15, -404, 388, -557, +-188, 316, 283, 362, 484, -207, -75, 65, +-25, -366, 310, -231, -97, 460, 457, -236, +-8, 204, 40, -130, 523, -231, -372, 49, +437, -357, 134, 602, -135, -264, 563, -70, +-38, 140, 133, -601, 92, 282, 61, 44, +366, 135, -125, -137, 451, -302, 66, 250, +26, -270, 342, -28, -467, 380, 592, -525, +331, 218, 196, 177, -87, -482, -360, 108, +832, -83, -191, -34, 428, 361, 216, -94, +-508, -535, 622, -92, 187, 523, 47, -216, +126, -64, 10, 20, 290, -265, 140, 85, +168, 170, 150, -91, -166, -489, 521, 538, +169, -209, -196, -264, 238, 455, 262, -429, +198, -13, 40, 39, 163, -110, -54, 173, +176, 41, 522, -235, 19, -196, -145, 84, +171, -58, 336, 375, -70, -171, 415, -693, +267, 666, -377, -128, 386, -342, 11, 414, +189, -601, 408, 346, 112, 320, 124, -621, +-448, 163, 585, -286, 91, 169, 186, 421, +660, -458, -600, -122, 90, 74, 443, -178, +-18, 292, 457, 22, 112, -668, -182, 521, +221, 120, 129, -474, 306, 214, 4, -232, +135, -46, 405, 360, -246, -239, 360, -123, +-125, 164, 296, -165, 432, -305, -80, 249, +93, 265, -108, -418, 331, 177, 496, -50, +-99, -391, -107, 218, 345, -65, 104, 282, +156, -132, 276, -261, -94, 158, 124, -579, +320, 582, 62, 246, 94, -697, 165, 264, +165, 141, 157, -619, 63, 339, 242, 496, +-1, -790, 27, 80, 432, 289, 211, -299, +85, 336, -297, -283, 389, -259, 86, 181, +396, 97, 317, 131, -614, -433, 685, 23, +92, 288, -254, -335, 598, 24, -92, 251, +246, -428, 331, 173, -201, 246, 50, -488, +158, 137, 557, 108, -88, -297, 157, 171, +192, 130, -167, -235, 214, -1, 392, -86, +7, -8, 311, 18, 10, 109, -80, -51, +210, -184, 126, 57, 626, -118, -295, 61, +-33, 87, 566, -121, -230, -96, 372, 6, +158, 158, -58, -172, 105, -79, 395, -62, +160, 73, -147, 231, 386, -298, -121, -90, +135, 162, 318, -181, 374, 63, -225, 23, +155, -65, 242, 167, -92, -311, 445, -37, +-69, 163, 326, -205, 156, 275, -42, 1, +186, -534, -74, 322, 352, 86, 318, -343, +-24, 382, 150, -223, 141, -175, -125, 308, +288, -323, 332, 16, 96, 217, 106, -156, +65, 30, 12, -161, 207, 23, 228, -14, +218, 149, 92, -7, -100, -319, 410, 79, +-6, 72, 18, 6, 413, 66, 46, -142, +-22, -199, 267, 134, 266, 110, -225, -176, +500, 277, -106, -319, 59, -231, 482, 457, +10, -292, -68, -3, 290, 273, 219, -73, +-211, -489, 420, 46, 159, 506, 100, -384, +121, 171, 42, 147, 79, -675, 205, 301, +276, 222, 100, -220, -50, 38, 196, 166, +223, -270, 37, -152, 151, 306, 107, -349, +157, 388, 141, 69, 258, -505, -113, 113, +29, -8, 559, 146, -243, 59, 395, -297, +138, 286, -347, -379, 543, 25, -4, 483, +277, -510, 231, 110, -222, 93, 4, -213, +506, 94, 52, 42, 199, -52, -25, -16, +62, -105, 147, 5, 235, 282, 126, -448, +-46, -29, 466, 591, -145, -547, -45, 96, +386, 13, 26, -212, 235, 420, 97, -279, +7, 36, 53, 19, 192, -298, 185, 244, +128, 240, 52, -382, 121, -47, 118, 264, +43, -340, 283, 207, -177, 147, 419, -407, +127, 319, -233, -179, 456, -196, -117, 347, +151, -157, 330, 79, -182, -112, 201, -228, +227, 318, 115, -191, -167, 109, 149, 7, +407, -186, -115, 261, 264, -282, -83, -128, +-20, 290, 385, 118, 5, -282, -11, -37, +437, 107, -150, -65, -70, 11, 138, -122, +326, 141, 177, 39, -33, -114, -37, 58, +38, -186, 115, -10, 311, 146, 181, -72, +-185, 118, 171, -31, 107, -146, -169, -165, +358, 55, 216, 240, -68, -62, 201, 50, +-189, -89, -56, -385, 482, 221, 127, 198, +2, -85, -61, 58, 29, -137, 39, -198, +275, 162, 193, 76, -51, -160, -38, 210, +23, -165, 177, -185, 109, 429, 113, -428, +77, 24, -18, 330, -105, -371, 189, 262, +273, -62, -2, -297, 42, 204, -116, 125, +-27, -206, 365, -6, 56, 95, 168, -15, +-217, -99, -50, -39, 192, 44, 175, -14, +129, 78, 29, -4, -145, -220, -97, -69, +472, 376, -83, -84, -188, -295, 497, 70, +-285, 42, 41, 7, 207, 234, -181, -157, +223, -507, 131, 334, -155, 314, 178, -210, +-80, -115, 4, -63, 220, 10, -52, 111, +159, -16, -191, -20, 3, -63, 238, -56, +47, 139, -69, -108, 84, -170, -197, 251, +286, 193, 49, -439, -223, -128, 373, 316, +-195, -24, -46, 116, 86, -149, 111, -352, +16, 385, -108, -50, 258, -165, -230, 322, +-47, -356, 213, 153, -25, 88, 50, -342, +99, 171, -251, -1, -104, 126, 393, 164, +-52, -337, -124, -307, 104, 188, -40, 244, +-67, 190, 81, -160, -81, -381, 111, -12, +177, 264, -165, 49, -196, -171, -68, 93, +329, 157, 161, -317, -246, -60, -191, 99, +107, 28, -30, 174, 116, -98, 193, -165, +-301, 70, -96, -102, 200, 7, -196, 68, +195, 133, -2, -45, -203, -362, 306, 352, +-330, -39, -130, -437, 238, 440, 157, 96, +-123, -285, -237, 79, 20, -117, 55, 46, +79, 92, -100, -81, -12, -80, -6, 137, +-80, 77, 103, -199, -218, -48, -42, -115, +246, 252, -14, 197, -266, -286, -91, -207, +183, 287, -80, 4, -59, -298, -7, 217, +101, 83, -207, -73, -118, 18, 153, -197, +-47, 21, -68, 67, 16, -17, -87, 291, +-10, -214, -53, -282, -134, 89, 152, 121, +-56, 209, -100, -198, -99, -207, 75, 179, +-103, 131, -41, -179, 15, -157, -82, 252, +-49, -39, 74, 47, -117, -28, -174, -364, +-28, 297, 229, 170, -89, -248, -277, 174, +60, -247, -76, -32, -106, 390, 273, -351, +-162, 84, -222, 141, -67, -302, -28, 239, +175, 12, -49, -271, -172, 210, -132, 13, +-31, -7, 72, -34, -96, -194, 2, 122, +50, 213, -292, -151, -52, -145, 44, 21, +40, 212, -67, -18, -18, -268, -229, 74, +-139, 68, 237, 104, -138, 87, -21, -362, +91, 11, -574, 274, 182, -149, 333, 42, +-443, 88, 223, -120, -312, -72, -195, -20, +364, 21, -245, 235, 34, 0, -31, -217, +-356, -178, 56, 80, 161, 328, -67, 4, +-182, -110, -126, -292, 22, -73, -51, 390, +26, 260, -150, -301, -118, -449, 98, 234, +42, 442, -348, -152, -101, -352, 187, 24, +1, 393, -68, -52, -311, -348, -27, -12, +210, 300, -230, 146, 27, -400, -204, -60, +83, 361, -25, 24, -265, -394, 194, 65, +-111, 360, -336, -207, 234, -218, 63, 380, +-312, 77, -25, -681, -139, 203, 227, 695, +-243, -271, -140, -541, 284, 134, -354, 471, +-147, -234, 168, -167, 3, 301, -306, -211, +57, -193, 107, 449, -346, -59, 44, -375, +45, 219, -120, 144, -4, -183, -236, -24, +-11, 82, 255, 74, -420, -21, -1, -96, +147, -27, -377, 58, 106, 43, 113, 101, +-275, -135, -2, -80, -85, 112, -73, -44, +9, 171, -89, -140, -1, -232, -118, 247, +-19, 250, -181, -59, 3, -505, 38, -42, +-150, 677, 40, -126, -157, -299, -48, 283, +-93, -414, -127, -119, 227, 854, -147, -216, +-206, -782, -36, 689, -285, -60, 447, -425, +-24, 694, -671, -326, 297, -441, -6, 522, +-282, 149, 216, -301, -119, -153, -180, 164, +-130, 261, 78, -223, -85, -2, -94, -28, +68, -252, -26, 634, -380, 170, -147, -1036, +331, 183, 96, 874, -302, -363, -402, -296, +183, 128, 109, 23, -196, 92, 79, -32, +-207, -77, -197, 1, 106, 259, 22, -233, +-162, -238, -97, 457, -79, 133, -57, -482, +193, -216, -293, 785, -253, -158, 227, -632, +-153, 540, -25, 103, 73, -354, -369, 39, +29, 119, 23, 135, -54, -71, -209, -331, +122, 232, 147, 497, -574, -400, -309, -738, +630, 661, 278, 861, -947, -924, -201, -400, +707, 751, -196, -79, -506, -378, 92, 135, +34, 405, 120, 61, -248, -684, -355, -15, +259, 684, -140, -57, -8, -554, -99, 293, +-51, 437, -113, -562, -151, -238, 91, 719, +-284, -74, 187, -665, 22, 633, -298, 155, +-262, -693, 191, 196, 95, 625, -524, -518, +316, -354, 304, 818, -960, -225, -45, -425, +618, 328, -95, 58, -482, -85, -105, -147, +177, 89, 48, 600, -517, -597, 39, -550, +403, 852, -211, 129, -526, -211, 96, -420, +252, 22, -390, 683, 12, -480, 350, 82, +-594, 409, -231, -902, 436, 264, -218, 745, +-77, -382, -24, -145, -338, -77, 67, -32, +272, 448, -460, -283, -144, -274, 275, 688, +-190, -222, -234, -640, 128, 723, -154, -22, +-152, -726, 127, 803, -208, 268, -88, -1013, +226, 406, -436, 499, -307, -887, 705, 464, +-253, 835, -771, -1116, 563, -390, -128, 1421, +-267, -504, 215, -825, -286, 1141, -350, -558, +497, -503, 16, 1491, -716, -807, 100, -1062, +226, 1309, -112, 64, -68, -569, -162, 287, +-322, -185, 280, -148, -6, 579, -200, -104, +-73, -652, -231, 368, 125, 417, 205, -272, +-574, -201, -85, 50, 550, 290, -308, -250, +-626, -164, 315, 459, 352, 94, -377, -425, +-397, -163, 103, 292, 203, 172, 70, -104, +-533, 73, -252, -195, 593, -124, -92, 425, +-617, -194, 68, -295, 504, 528, -443, 116, +-554, -724, 652, 108, -51, 700, -485, -414, +212, -123, -460, 199, 346, -155, 103, 122, +-415, 163, -89, -311, 26, 7, 126, 391, +-354, -313, 31, -89, 215, 312, -406, -74, +-47, -49, 193, -121, -226, 99, -235, 107, +301, -173, -105, 178, -272, 71, 54, -150, +-110, -180, -53, 66, -97, 362, 235, -124, +-161, -37, -250, -141, -193, -105, 113, 410, +170, -175, 72, -230, -510, 434, -207, -6, +516, -538, -378, 407, 6, 90, 19, -427, +-119, 375, -100, 200, -33, -348, 33, 90, +-152, -76, -133, -296, 156, 594, 175, 185, +-717, -422, 68, -308, 696, 355, -618, 210, +-374, -612, 590, 478, -111, 470, -541, -742, +321, -100, 144, 328, -624, -53, 143, 201, +446, -40, -343, -232, -322, 167, 24, -109, +193, -99, -4, 259, -287, 47, -31, -138, +216, 91, -101, -95, -583, -219, 312, 160, +486, 404, -689, -126, 60, -423, 191, 254, +-475, -16, 255, -198, 87, 475, -332, -65, +356, -455, -353, 403, -361, -179, 387, -244, +210, 614, -456, -83, -72, -473, 322, 99, +-510, 374, 118, -263, 302, 67, -313, 123, +-176, -403, 12, 366, 296, 200, -241, -356, +-445, -143, 507, 194, -40, 262, -373, -123, +117, -175, -17, -25, -14, -8, -136, 332, +107, -33, -15, -385, -500, 199, 510, 33, +4, -27, -412, 245, 85, -251, -151, -160, +209, 363, 42, -200, -241, -61, -170, 299, +197, -119, -10, -62, -223, -121, 95, -35, +68, 292, -234, 48, 59, -33, -41, -304, +-159, 1, 222, 414, -54, -369, -311, 74, +138, 455, 156, -486, -313, -127, 49, 445, +-29, -362, 108, 12, -141, 491, -54, -309, +94, -41, -337, -67, 288, -302, -42, 629, +-47, 99, -230, -397, -45, -91, 427, 123, +-385, 126, -181, -218, 293, 292, -45, 18, +-173, -327, 55, 222, -150, -185, 126, 10, +-76, 623, 98, -744, -141, -46, -252, 807, +420, -719, -488, 21, 545, 445, -280, -252, +-586, -75, 663, 147, 61, -107, -371, 75, +-261, 120, 507, -343, -200, 233, -155, 202, +187, -368, -280, 44, 79, 179, 200, 80, +-216, -153, -96, -194, 217, 235, -544, 74, +586, -126, 117, 63, -797, -6, 343, -157, +302, 198, -561, 21, 309, -355, 268, 506, +-691, 77, 179, -851, 395, 696, -283, 84, +-197, -557, 138, 557, 36, -217, -121, -159, +304, 537, -493, -619, 51, -229, 264, 1109, +-207, -510, 149, -751, -106, 1086, -187, -287, +169, -813, 3, 1062, -248, -203, 247, -754, +139, 916, -360, -134, -236, -689, 561, 610, +-239, 63, -344, -634, 816, 552, -708, 422, +-288, -930, 817, -34, -328, 974, -337, -671, +360, -202, -39, 860, -335, -877, 275, 242, +76, 516, -284, -761, -28, 270, 443, 244, +-416, -126, -112, 2, 249, -277, -99, 332, +120, 75, -105, -433, -115, 379, -74, 60, +166, -505, 173, 421, -451, 323, 330, -819, +49, 256, -662, 635, 614, -681, -68, 3, +-64, 670, -64, -683, -150, -165, 226, 840, +-76, -325, -119, -487, 86, 404, 77, 47, +-92, -124, -119, 143, 102, -21, 89, -340, +-383, 249, 339, 249, 66, -363, -320, 237, +319, -2, -469, -295, 227, 126, 246, 248, +-276, -116, -21, -65, 32, -3, 212, -48, +-517, 116, 336, -23, 233, 194, -613, -492, +312, 179, 362, 587, -656, -726, 150, 98, +491, 459, -617, -471, 150, 54, 235, 163, +-154, 7, 83, 135, -78, -395, -215, 34, +-24, 440, 469, -386, 12, -184, -622, 763, +471, -124, -203, -1010, -364, 549, 908, 623, +-551, -714, -142, 224, 488, 372, -563, -675, +-56, 44, 623, 684, -242, -566, -377, -188, +690, 866, -634, -422, -269, -729, 1106, 794, +-678, 257, -506, -1053, 1164, 704, -622, 586, +-544, -1233, 1002, 386, -615, 787, -201, -1076, +901, 162, -467, 995, -605, -749, 595, -487, +101, 905, -426, -199, 495, -893, -110, 1323, +-697, -170, 619, -1336, 227, 1207, -552, 189, +274, -1043, 178, 638, -600, 261, 276, -617, +526, 283, -589, 230, -8, -423, 278, 135, +-224, 278, 72, -224, 194, -181, -252, 166, +-49, 287, 216, -491, -4, 259, -194, 324, +-22, -911, 291, 584, -39, 468, -404, -900, +220, 436, 273, 430, -215, -971, -208, 393, +270, 528, -84, -604, -6, 283, 40, 58, +-65, -420, 110, 306, -225, 40, 172, -76, +-31, 18, 14, 32, 177, 33, -410, -196, +133, -22, 243, 291, -236, -44, 52, -191, +224, 161, -389, -126, 48, -40, 404, 199, +-333, -4, -164, -85, 317, -386, 206, 629, +-525, 274, 22, -1229, 445, 678, -378, 573, +157, -912, 132, 464, -343, -23, 114, -189, +225, 388, -267, -468, 37, -7, 144, 748, +-137, -617, 139, -509, -102, 1252, -134, -495, +114, -938, 236, 1226, -189, -159, -204, -740, +141, 567, 227, 211, -205, -575, -83, 141, +179, 519, -166, -724, 79, 152, 271, 780, +-445, -827, -58, -82, 566, 721, -278, -655, +-290, -11, 418, 872, -293, -872, 96, -119, +416, 1016, -657, -978, 18, -124, 520, 1092, +-196, -770, -184, 62, 183, 243, -53, -452, +-239, 294, 455, 73, -264, 37, -175, -214, +640, 122, -669, 14, -39, -272, 722, 442, +-564, -234, -153, -193, 594, 594, -234, -477, +-522, -207, 674, 624, -4, -338, -584, -213, +345, 398, 227, -2, -314, -458, 80, 450, +82, 114, -270, -769, 284, 668, -14, 173, +-163, -790, 157, 684, -28, 88, -114, -867, +38, 686, -2, 112, 131, -554, -28, 533, +-44, -187, -29, -223, -195, 269, 227, -158, +217, 32, -225, 199, -153, 36, 70, -593, +111, 366, -54, 530, 22, -694, 53, -34, +-210, 424, 168, -150, 71, 55, -279, -38, +95, -360, 242, 481, -2, -40, -414, -298, +157, 330, 275, -134, -200, -194, -118, 183, +289, 105, -155, -238, -143, 235, 242, 44, +-154, -473, -66, 469, 286, -147, -188, -275, +-36, 741, 51, -393, -62, -492, -156, 491, +524, 21, -185, -26, -594, -68, 672, -119, +-115, 444, -400, -503, 385, -157, 197, 809, +-478, -535, -1, -221, 438, 665, -476, -347, +263, -310, 156, 295, -429, 165, 238, -81, +37, -283, -97, 220, -38, 128, 233, -247, +-163, 83, -146, 2, 132, -39, 58, 112, +62, 75, -182, -106, -3, -217, -18, 125, +134, 188, 52, -74, -100, 49, -54, -175, +-110, -138, 285, 402, -171, -115, 42, -281, +85, 370, -244, -55, 218, -312, -151, 257, +51, 8, 153, -162, -226, 235, 46, -15, +83, -247, -150, 58, 112, 216, 13, -120, +-63, 6, -21, 27, -46, -147, 200, 190, +-215, 84, 142, -400, -129, 161, -71, 373, +529, -347, -701, -52, 139, 238, 466, -279, +-476, 76, 138, 354, 223, -167, -448, -467, +101, 261, 318, 549, -111, -528, -156, -156, +-4, 457, 50, -317, -50, -22, 216, 398, +-227, -339, -115, -68, 412, 363, -273, -269, +-228, -190, 427, 373, -182, -113, -83, -71, +227, 336, -281, -415, 82, -234, 165, 517, +-274, 99, 96, -353, 234, 60, -195, 181, +-288, -212, 416, -152, 56, 325, -547, 96, +488, -289, 109, 194, -655, -105, 365, -352, +339, 573, -439, -15, -45, -372, 395, 303, +-418, -197, -45, -124, 606, 300, -331, 2, +-451, -139, 536, 28, -95, 55, -319, -253, +531, 143, -265, 327, -224, -330, 177, 6, +119, 178, -76, -308, -298, 98, 477, 267, +-167, -127, -211, -110, 220, -21, -181, 105, +78, -5, 196, -69, -241, 83, -79, -47, +252, -57, -172, 215, 16, -198, 112, -70, +-220, 223, 102, -177, 93, 207, -60, -173, +-35, -98, -185, 374, 257, -354, 35, 132, +-247, 126, 138, -355, -57, 244, 139, 97, +-148, 11, -39, -206, 63, -160, -47, 339, +205, 40, -189, -210, -18, 112, -63, -23, +33, -147, 202, 206, -224, -44, 161, -33, +-105, 69, -328, -197, 525, 236, -1, -86, +-467, -190, 237, 481, 179, -468, -310, -63, +109, 675, 341, -624, -661, -135, 145, 676, +642, -403, -529, -181, -54, 548, 191, -431, +-282, -356, 244, 775, 263, -8, -469, -666, +133, 366, 91, 98, -366, -297, 429, 261, +133, 123, -550, -424, 212, 212, 299, 305, +-450, -567, 79, 190, 337, 293, -255, -370, +34, 257, -25, 5, -186, -367, 395, 340, +-74, 194, -465, -547, 291, 93, 303, 501, +-262, -280, -89, -34, -45, -46, -35, -265, +180, 411, 235, 123, -48, -166, -705, -131, +285, -196, 509, 313, -407, 139, 51, -230, +105, 8, -104, 88, -74, -29, 27, -107, +-62, -10, 125, 55, 218, 269, -169, -74, +-319, -425, 116, 165, 101, 162, 72, -79, +110, 190, -287, -56, 74, -261, 9, -13, +-182, 263, 340, -74, -130, -20, -201, 132, +336, -255, -111, 121, -341, 67, 257, -216, +99, 236, -228, -4, 268, -74, -84, -9, +-286, -21, 115, 3, 277, 12, -371, 124, +219, -93, 253, -102, -761, 77, 499, 72, +244, -22, -648, -65, 389, 62, 181, -119, +-443, 3, 69, 337, 452, -223, -588, -258, +42, 297, 695, 62, -688, -245, 20, 69, +356, 173, -382, -202, 239, 135, 140, 104, +-403, -413, 165, 100, 172, 456, -281, -308, +154, -90, 107, 198, -298, -184, 124, -58, +225, 244, -352, 50, 115, -269, 120, 130, +-195, 56, 174, -284, -18, 212, -188, 291, +112, -377, 116, -66, -305, 325, 261, -318, +46, 171, -226, 126, 132, -311, -169, 206, +165, 25, -48, -58, 72, -103, 25, 28, +-295, 73, 239, 99, -43, 11, -126, -315, +289, 130, -82, 145, -344, -51, 285, -70, +44, 36, -247, 58, 206, -39, 97, -22, +-232, -148, -64, 170, 207, 119, -58, -162, +-36, -8, 24, 32, 56, 0, -162, -47, +75, 51, -32, 99, 10, -170, 228, 45, +-421, 209, 227, -238, 107, -164, -280, 277, +67, 149, 255, -329, -53, 110, -456, 172, +364, -404, 176, 333, -494, 140, 313, -578, +121, 493, -323, 166, 132, -674, 76, 380, +-184, 307, 64, -581, 214, 257, -210, 307, +-18, -623, 87, 388, -162, 221, 171, -595, +76, 298, -191, 259, -51, -354, 259, -16, +-127, 326, -229, -295, 214, -73, 186, 496, +-227, -357, -122, -269, 226, 391, -154, 87, +117, -262, 32, 26, -282, 177, 307, -291, +-43, 176, -149, 249, 57, -432, 47, -11, +-47, 382, 14, -123, 132, -196, -245, 123, +68, -29, 152, 48, -119, 19, -43, -104, +43, 90, 55, -56, -43, 100, -26, 20, +-47, -280, 64, 166, 74, 150, -66, -40, +-168, -110, 122, -90, 174, 217, -150, -51, +-85, -129, 15, 145, 96, -90, -49, 55, +64, 82, -20, -192, -157, 94, 162, 28, +-11, -90, -146, 47, 110, 166, 144, -149, +-246, -128, 119, 261, 66, -232, -371, 13, +416, 178, -22, -60, -194, 87, 222, -188, +-305, -147, 71, 294, 164, 77, -23, -314, +-5, 243, -66, 44, -27, -302, -57, 223, +70, -96, 161, -23, -105, 314, -85, -292, +54, -73, -65, 274, -25, -284, 199, -24, +23, 491, -314, -310, 175, -261, 37, 375, +-90, -224, 142, 14, -135, 306, 40, -333, +74, 7, -113, 212, -4, -223, 85, 91, +-61, 148, 63, -223, 48, 18, -167, 222, +-40, -211, 204, -154, -31, 441, -101, -146, +122, -301, -120, 322, -36, -124, 69, -145, +99, 331, -27, -54, -86, -219, -26, 86, +-135, -114, 401, 127, -117, 301, -306, -413, +296, 81, -104, 169, -120, -429, 243, 307, +88, 280, -470, -364, 222, 54, 325, 46, +-501, -101, 153, 78, 278, -57, -288, 241, +9, -127, 189, -213, -251, 246, 48, -153, +265, -31, -143, 215, -109, -60, 44, -81, +-88, 27, 178, -53, 67, 42, -275, -10, +193, 119, -7, 5, -281, -340, 375, 339, +-55, 71, -272, -452, 347, 363, -130, 111, +-290, -360, 358, 150, 63, 29, -331, 11, +233, 89, 5, -195, -327, -23, 355, 187, +166, 7, -528, -192, 201, 96, 322, 155, +-537, -192, 338, -120, 154, 288, -520, 27, +382, -316, 83, 203, -311, 43, 17, -217, +271, 208, -147, 57, -34, -107, 127, -28, +-280, -187, 145, 170, 198, 321, -195, -214, +-11, -141, 81, -96, -54, 80, 5, 302, +-53, -231, -43, -21, 308, 200, -132, -171, +-306, -140, 248, 158, 26, -13, -189, 19, +347, 224, -126, -237, -402, -226, 491, 229, +-22, 90, -425, -184, 358, 149, 105, 133, +-389, -330, 267, -5, 170, 289, -570, -113, +302, -167, 371, 205, -469, -43, 103, -107, +110, 140, -149, -58, 62, -29, 137, 32, +-156, -120, -189, 27, 526, 291, -219, -24, +-409, -454, 372, 112, 133, 372, -263, -201, +8, -238, 311, 428, -377, -54, -12, -499, +311, 482, -139, 36, -58, -506, 73, 408, +-6, 169, -145, -403, 172, 157, -1, 61, +-95, -212, 108, 215, -42, 4, -197, -195, +234, 159, 95, 122, -244, -210, 59, -126, +100, 189, -102, 119, -22, -190, 122, 47, +-20, 150, -131, -260, 70, 63, 48, 250, +-18, -326, -95, 24, 98, 333, 57, -214, +-122, -54, 65, 51, -87, -194, 70, 234, +124, 147, -196, -235, 75, -26, 28, 29, +-115, 35, 162, -13, -59, -5, -112, 124, +188, -116, -157, 14, 30, -24, 173, -205, +-290, 389, 127, 6, 136, -296, -116, 173, +-77, -199, 117, 83, -37, 261, -65, -261, +194, 125, -190, -16, -36, -312, 272, 339, +-182, 87, -128, -298, 142, 162, 96, 90, +-54, -246, -111, 40, -32, 259, 113, -252, +72, 72, -40, 209, -167, -461, 90, 199, +140, 325, -140, -394, -12, 121, 45, 114, +-4, -257, 22, 176, 13, 5, -68, -62, +47, 120, -79, -137, 98, -37, 76, 100, +-175, 36, 112, -60, -135, -13, 92, 68, +82, -99, -190, 44, 216, 80, -114, -104, +-57, 28, 51, -9, -73, 23, 169, 49, +19, -66, -189, 20, 40, -58, 6, -52, +15, 308, 135, -128, -176, -350, 15, 337, +206, 84, -272, -295, -27, 169, 309, 152, +-208, -352, 0, 27, 178, 426, -182, -338, +-126, -85, 195, 419, 127, -448, -204, -54, +60, 545, 2, -389, -138, -53, 234, 421, +-60, -430, -192, -121, 231, 385, -33, -56, +-157, -34, 147, 45, -3, -151, -234, -136, +272, 266, 148, 141, -422, -327, 186, 119, +116, 69, -242, -201, 165, 239, 41, -80, +-72, -176, 90, 265, -97, -91, -221, -172, +350, 254, 51, 12, -314, -308, 237, 150, +-10, 215, -223, -314, 34, 107, 268, 242, +-139, -336, 6, 86, 64, 120, -360, -175, +359, 152, 43, -7, -319, -141, 286, 98, +26, 181, -228, -273, 49, -106, 131, 351, +-207, -197, 136, -40, 254, 319, -315, -238, +-120, -227, 259, 241, -109, -11, -57, -21, +298, 168, -209, -126, -98, -128, 181, -14, +-181, 131, 22, 122, 145, -197, 45, 20, +-59, 138, -104, -183, -76, 77, 95, 107, +84, -281, -26, 182, 125, 254, -174, -375, +-115, 34, 93, 230, 26, -240, 113, 3, +-3, 236, -74, -92, -41, -168, -93, 159, +136, -14, 26, -148, -12, 191, 31, -17, +-81, -118, 33, 162, -59, -117, -57, -172, +197, 284, -27, 81, -96, -250, 118, 50, +-172, 36, 12, -122, 117, 176, -35, 88, +5, -175, 28, -5, 16, -27, -143, -2, +0, 126, 159, 45, 10, -87, -110, -164, +21, 114, 87, 105, -121, -70, -39, -45, +153, 68, -40, 33, -92, -150, 255, 63, +-227, 61, -188, -12, 360, -8, -50, -45, +-142, 48, 72, -52, 35, -30, -34, 141, +-42, -16, 41, -157, -6, 56, 60, 109, +-21, -117, -59, 9, 74, 109, -85, -87, +-39, -57, 216, 41, -57, 92, -179, -66, +187, -81, -79, 158, -62, -82, 80, -77, +13, 144, 34, -78, -10, -20, -60, 96, +-126, -95, 185, -58, 69, 117, -108, 47, +43, -104, -57, 65, -66, -49, 118, -191, +-24, 284, -9, 89, 97, -227, -119, 88, +-14, -97, 5, -120, 66, 292, 83, 99, +-167, -333, 53, 48, 130, 191, -235, -291, +167, 124, 49, 236, -237, -233, 205, 73, +11, -48, -66, -174, 53, 308, -81, 19, +-60, -201, 77, 50, 64, 4, 6, 4, +24, 30, -138, -34, -11, 33, 100, 93, +-11, -260, 79, 38, -71, 318, 27, -271, +-59, 37, -172, 150, 213, -214, 65, 95, +-10, 22, -77, -30, -95, 56, 76, -46, +114, 16, -121, 12, -3, -51, 149, -80, +-180, 92, 94, 146, 27, -108, -150, -105, +145, 95, 44, -52, -74, -113, 47, 278, +-73, -30, -27, -216, 62, 212, 15, -154, +6, -172, 1, 362, -4, -20, -16, -163, +-18, 68, 36, -138, 46, 65, -19, 185, +-54, -137, 13, -83, -17, 114, -1, 9, +113, -84, -35, 46, -50, -55, 44, 19, +-79, 66, 184, 21, -118, -14, -92, -274, +157, 232, -105, 199, 115, -332, -75, 151, +-76, 85, 161, -271, -86, 120, 50, 170, +10, -124, -71, 1, 51, 63, -56, -110, +-109, -85, 211, 172, 41, 88, -109, -84, +34, -21, -50, -181, 0, 29, -10, 266, +195, -75, -22, -76, -230, -4, 70, -68, +93, 58, -99, 24, 52, -37, 153, 63, +-67, 31, -41, -82, -47, -103, -95, 75, +148, 144, 119, -111, -173, -43, -8, 91, +175, -73, -170, 34, -26, 40, 116, -118, +14, -24, 84, 170, -112, 12, 6, -136, +-62, 86, -98, -177, 225, -12, 39, 382, +-81, -175, 38, -137, -96, 77, 68, -140, +-21, 126, -41, 140, 191, -145, -88, -54, +-115, 115, 13, -11, 77, -194, -14, 129, +75, 192, 7, -175, -118, -29, 100, 64, +-51, -90, -90, 15, 149, 148, 27, -42, +-168, -124, 161, 53, -45, -13, -79, 61, +124, -5, 60, -70, -140, 89, -1, -76, +118, 44, -196, 64, 93, -237, 126, 158, +-120, 216, 14, -290, 83, 4, -95, 156, +5, -200, 176, 89, -225, 221, 110, -214, +70, -73, -229, 125, 176, -132, -15, 76, +-29, 197, 91, -156, -20, -100, 15, 80, +-117, -54, 16, 41, 134, 146, -115, -99, +13, -147, 64, 132, -5, 69, 0, -188, +-108, 90, 102, 55, 116, -96, -65, 197, +-2, -104, -188, -260, 63, 193, 204, 149, +-106, -91, -56, 22, 61, -82, 46, -85, +-58, 130, 12, -17, 128, 61, -158, 33, +-41, -244, 223, 108, -221, 193, -64, -283, +384, 112, -190, 178, -128, -327, 241, 201, +-197, 70, 26, -300, 262, 235, -268, 58, +-20, -138, 150, 33, -135, -3, 16, -62, +214, 7, -164, 278, 26, -191, 162, -253, +-281, 337, 72, -193, 192, 27, -248, 352, +84, -451, 268, 21, -311, 319, -88, -362, +278, 70, 61, 407, -207, -311, 95, -241, +38, 345, -151, -64, 126, -161, -89, 237, +24, -67, 92, -112, -23, 75, 2, -54, +-15, 63, -4, 25, -23, -78, 105, 78, +-26, -89, -131, -43, 86, 221, 39, -119, +-50, -93, -24, 107, 141, -99, -19, 70, +-144, 91, 225, -76, -45, -56, -326, -67, +241, 171, 182, 8, -306, -182, 81, 164, +220, -22, -266, -100, 137, 146, 216, -54, +-453, -157, 108, 69, 378, 253, -325, -130, +-78, -211, 266, 174, -203, -73, 16, 47, +328, 194, -240, -221, -197, -116, 251, 127, +42, 130, -165, -45, 12, -150, 98, 110, +-26, 31, -38, -130, 26, 113, 6, -21, +48, -87, 119, 140, -163, -85, -107, -84, +125, 185, 34, -94, 29, -83, -28, 205, +-66, -109, -36, -129, 170, 113, 38, 39, +-186, -45, 107, 39, 6, 78, -49, -273, +48, 56, -19, 306, -120, -244, 141, 39, +105, 80, -200, -221, 169, 131, -21, 87, +-159, -17, 151, -11, -46, -97, -75, -10, +80, 51, 100, 156, -129, -122, -97, -187, +224, 233, -44, -9, -24, -58, 66, 58, +-135, -135, -42, 32, 100, 104, 38, 61, +10, -75, -98, -202, -27, 68, 218, 192, +-41, -5, -96, -53, 4, -56, -85, -108, +100, 111, 108, 104, -158, -90, 7, 56, +141, -63, -159, -122, 63, 124, 160, 60, +-156, -10, 17, -4, 29, -51, -173, -125, +137, 122, 155, 193, -188, -250, 93, -23, +-45, 124, -105, -66, 213, 112, 49, -82, +-123, -45, -154, 79, 87, -103, 113, 137, +-36, -18, 18, -185, -68, 165, 38, -18, +13, -71, -35, 126, 119, -13, -30, -40, +-77, -101, -14, -49, 4, 185, 36, 126, +33, -186, -76, -148, 41, 110, 99, 32, +-49, 144, -3, 77, -3, -369, -50, -63, +-51, 254, 155, 12, -24, 40, -185, -35, +167, -207, 29, 162, -34, 218, 89, -352, +-104, -58, -27, 379, 52, -184, -83, -123, +56, 264, 38, -164, -93, -143, 85, 299, +67, -87, -91, -151, 48, 219, 46, -258, +-134, 2, 31, 383, 55, -226, -57, -76, +42, 89, -15, -233, -39, 177, 70, 316, +60, -279, -13, -195, -45, 129, -24, -1, +-54, 166, 78, 65, -35, -258, 28, -51, +-27, 26, -27, 204, 188, 144, -140, -368, +-47, -63, 180, 345, -108, -21, -51, -266, +-7, -31, -23, 148, 120, 109, 67, 88, +-150, -141, -55, -233, 204, 39, -1, 229, +-180, 118, 95, -218, 17, -183, -139, 107, +171, 205, 56, 137, -162, -184, -84, -225, +104, 64, 129, 106, -82, 125, -12, -107, +56, -194, -97, 140, 74, 180, 10, 96, +-136, -185, 1, -270, -18, 108, 50, 121, +269, 31, -42, 57, -218, -44, 44, -59, +-32, 71, -122, -75, 114, -111, 180, 220, +-41, 8, -215, -199, 12, 1, 220, 33, +70, 216, -80, 67, -125, -280, -202, -68, +175, 25, 210, 112, -144, 110, -3, -87, +-15, -50, -5, -20, 152, 97, -59, 14, +-170, -150, 26, 35, 52, 44, 112, -35, +15, 37, -197, 108, 127, -1, 23, -126, +-107, -64, 105, -55, -56, 96, -30, 118, +60, -73, 75, 16, 6, 47, -56, 1, +-87, -25, -65, -174, 84, -119, 42, 157, +54, 260, 73, -1, -147, -109, -52, -14, +120, -151, 3, 17, -52, 207, -150, -166, +109, -176, 74, 170, -37, 205, 209, 97, +-110, -116, -226, -229, 75, -153, 89, 157, +20, 184, -52, -104, -76, 2, 74, 81, +134, 35, -52, -18, -48, -153, -96, -112, +-24, 110, 149, 95, 7, -4, 19, 155, +-138, -132, -25, -248, 187, 217, -22, 121, +-42, -214, -188, -138, 54, 199, 314, 191, +-83, -13, -147, -92, -32, -322, 52, -19, +-14, 330, 21, 5, 54, -10, -78, 46, +52, -189, 147, -8, -131, 213, -97, -156, +26, -239, -159, 152, 341, 241, 86, 155, +-477, -207, 320, -294, 98, 91, -286, 89, +151, 50, 64, 125, -261, -140, 73, -113, +248, 247, -123, -73, -7, -205, -125, 134, +-91, -111, 429, 148, -81, 367, -354, -374, +118, -220, 26, 204, -52, -106, 241, 103, +2, 77, -316, -153, 98, 255, 180, 115, +-145, -309, -41, -263, 58, 74, -64, 179, +199, 69, 60, 229, -405, -67, 104, -315, +228, 111, -232, -63, 57, -183, 157, 263, +-132, 98, 85, 8, 53, 129, -279, -316, +-3, -247, 220, 306, 62, 88, -159, -127, +-196, 140, 202, 17, 264, -71, -78, -53, +-298, -232, -54, 111, 158, 332, 102, -69, +-112, -186, -114, 7, 148, 117, 30, -5, +5, -176, -50, 10, -38, 110, 46, 37, +-162, 120, 32, -137, 90, -268, -20, 266, +16, 197, -5, -192, -23, -15, 12, -63, +15, -109, -133, 79, -45, 183, 133, 130, +89, -129, -17, -101, -210, -70, 34, -149, +96, 168, -108, 208, -15, -136, 113, 0, +174, 250, -255, -179, -142, -393, 170, 118, +-80, 187, -9, 59, 51, 226, 39, -99, +89, -210, -148, -79, -169, -274, 108, 196, +99, 472, -89, -1, 12, -129, 136, -177, +-53, -194, -259, 43, -58, 69, 75, 93, +182, 203, 177, 33, -138, -157, -259, -172, +55, -31, 42, 25, -159, -54, 146, 281, +52, 272, -134, -304, 84, -283, 85, -4, +-92, 149, -133, 156, -131, -63, -25, 23, +466, 133, -5, -67, -420, -252, -42, -188, +-84, 147, 200, 306, 232, 137, -134, -125, +-15, -107, -35, -40, -256, -243, -125, -82, +284, 331, 133, 318, -169, -71, 77, -309, +48, -62, -257, 157, -189, -186, 136, -50, +223, 430, 53, -37, -110, -256, -145, 139, +-65, -22, -78, -239, 34, 6, 154, 193, +102, 173, -149, 74, -79, -243, 36, -225, +-221, 172, 58, 100, 157, -155, -52, 51, +-15, 231, 13, -63, -98, -156, -166, 54, +76, -89, 72, -45, 40, 192, 66, -31, +-106, -39, -220, 72, -9, -54, 69, -20, +-47, -80, 63, -104, 204, 292, -101, 186, +-262, -316, -95, -61, -28, 45, 237, -135, +94, 174, -184, 114, -1, -79, -25, 58, +-192, -45, 5, -87, 219, -55, -89, -139, +-86, 136, 150, 338, -70, -50, -237, -263, +-87, 28, 207, 51, 1, -185, -161, 88, +171, 282, 11, -110, -285, -176, -4, 105, +127, 43, -24, -83, -56, -44, -64, 33, +-65, 99, 21, -2, 68, -93, -30, 70, +-39, 66, -35, -242, 10, 40, -131, 292, +-154, -248, 105, -141, 106, 369, 99, 3, +-45, -318, -295, 84, -24, 170, 132, -200, +-255, -1, 49, 157, 341, -125, -165, 85, +-201, 151, 120, -192, -178, -66, -144, 36, +218, -62, 23, 78, -100, 134, 20, -71, +-139, -40, -170, 32, 246, -110, 97, 45, +-266, 134, -37, -38, 10, -146, -173, -21, +27, 113, 245, 55, -58, 63, -98, -99, +-89, -123, -139, 88, 44, -30, -156, -29, +65, 164, 289, -10, -87, -105, -248, 2, +23, -18, -118, -29, -225, -62, 353, 222, +149, 151, -307, -326, -119, 11, -23, 136, +6, -209, 45, 40, -19, 171, -13, 43, +77, 59, -190, -123, -329, -124, 171, -83, +147, 22, -50, 221, 142, 38, -121, 11, +-287, -52, -46, -116, -62, -63, 44, -136, +194, 176, 78, 238, -36, -37, -200, 71, +-289, -150, -211, -378, 174, 96, 386, 159, +114, -28, -209, 367, -350, 196, -92, -465, +-5, -242, 3, 1, 106, -154, 137, 292, +72, 512, -318, 103, -158, -411, -12, -525, +-75, 123, 51, 219, 228, -58, 26, 395, +-352, 226, -33, -468, -65, -295, -17, -52, +210, 141, -90, 366, -97, 69, -151, -83, +-122, -82, 194, -254, 107, -100, -250, 197, +-89, 97, 160, 83, -128, 241, -224, -223, +63, -449, 97, 172, -62, 215, 122, -205, +-47, 287, -349, 364, -93, -559, 21, -384, +186, 389, 167, 151, -238, -158, -159, 218, +4, 205, -111, -451, -5, -298, 151, 375, +-68, 88, -76, -92, 43, 213, -291, -140, +-113, -217, 298, 208, 47, -17, -137, -241, +-123, 254, -134, 241, 126, -270, -169, -149, +-145, 6, 393, 33, -52, 198, -286, 67, +-17, -38, -55, -111, -131, -334, 104, 71, +146, 473, -143, -68, -2, -226, -164, 171, +-193, -77, 211, -278, 25, 87, -188, 176, +72, 142, 149, 125, -325, -273, -210, -331, +134, 91, 98, 185, 136, 174, -155, 36, +-185, -50, -37, 30, -120, -439, -25, -177, +212, 540, 72, 88, -265, -118, 16, 234, +63, -120, -384, -562, -80, -58, 296, 441, +191, 219, -126, 86, -333, 7, -42, -335, +52, -408, -218, 31, 152, 397, 368, 274, +-193, 60, -348, -62, -125, -275, -66, -342, +146, -66, 162, 392, -46, 268, 38, -84, +-159, 170, -351, -159, -100, -602, 182, 54, +258, 501, -24, 51, -178, -117, -90, 170, +-185, -48, -122, -462, 165, -156, 202, 564, +-71, 221, -215, -368, -125, 125, 31, 94, +-5, -450, -145, -96, 157, 400, 144, 250, +-208, -85, -157, -217, -103, -64, -81, -46, +118, -109, 236, 224, 14, 282, -334, -70, +-191, -215, 84, -132, 4, -40, -105, 109, +90, 121, 161, 56, -22, 122, -267, -43, +-295, -280, 68, -237, 184, 188, 29, 322, +9, -52, -44, 20, -188, 127, -152, -393, +-25, -306, 44, 330, 244, 295, 98, 147, +-415, -195, -219, -383, 173, 97, 58, 34, +-55, 26, -5, 317, 71, -15, -67, -221, +-246, -13, -159, -144, 166, -135, 298, 394, +-148, 242, -378, -364, 89, -73, 239, 276, +-290, -217, -281, -315, 394, 344, 217, 391, +-390, -319, -123, -239, 69, 265, -150, -115, +-5, -257, 178, 317, 106, 318, -141, -288, +-282, -224, -56, 209, 133, -123, -62, -179, +18, 411, 231, 129, -171, -403, -329, 60, +83, 144, 64, -165, -202, 30, 140, 22, +221, 52, -148, 146, -198, -54, -186, -149, +-35, -108, 219, 29, 79, 69, -66, 73, +48, 265, -178, -25, -360, -524, 123, -140, +272, 431, -28, 212, -18, -171, -119, -114, +-218, 8, 65, -36, 91, 74, -62, 206, +-32, -223, -90, -423, 61, 402, 163, 655, +-245, -395, -280, -792, 151, 169, 195, 734, +1, 180, -139, -488, -157, -479, -6, 269, +78, 539, -77, -144, -6, -584, 155, -13, +-64, 918, -147, 206, -116, -1280, -143, -373, +206, 1254, 251, 357, -216, -918, -155, -101, +50, 628, -24, -119, -171, -601, 57, 55, +229, 735, -245, 39, -74, -729, 363, 68, +-174, 577, -515, -267, 94, -526, 538, 359, +53, 507, -580, -326, -224, -394, 535, 316, +162, 260, -459, -420, -158, -238, 332, 522, +68, 306, -305, -593, -76, -285, 116, 640, +126, 33, -47, -523, -110, 296, -104, 212, +-44, -386, 181, 11, -93, 258, -160, -7, +253, -247, 47, 38, -416, 310, 14, -211, +397, -198, -214, 340, -402, -115, 373, -346, +371, 562, -593, 243, -323, -967, 613, -65, +133, 1159, -583, -193, -11, -1070, 623, 549, +-263, 757, -799, -860, 477, -429, 796, 1017, +-654, 148, -642, -1003, 669, 208, 359, 873, +-715, -589, -249, -762, 605, 915, 165, 622, +-377, -1019, -71, -238, -46, 772, -76, -311, +215, -389, 154, 704, -261, 172, -145, -739, +314, -26, -202, 506, -404, -281, 433, -168, +339, 531, -449, -60, -93, -392, 262, 129, +-396, -30, -111, -244, 618, 430, 84, 356, +-610, -459, -108, -319, 416, 170, -37, 304, +-305, -79, 70, -394, 247, 222, 54, 532, +-275, -225, -164, -602, 189, 216, 14, 420, +-182, -573, 100, -107, 355, 1122, -103, 1, +-537, -1304, -108, -54, 415, 847, 281, -80, +-125, -34, -417, 298, -196, -632, 500, -188, +399, 1030, -616, -285, -601, -1440, 516, 846, +647, 1721, -69, -1081, -633, -1424, -622, 698, +579, 706, 1135, 37, -589, -128, -1484, -645, +701, -28, 1609, 955, -969, -159, -1497, -1030, +1057, 414, 1133, 985, -833, -529, -784, -819, +456, 440, 515, 430, -250, -192, -391, 34, +66, -86, 359, -190, 123, 323, -438, -60, +-249, -574, 463, 452, 175, 805, -509, -750, +-55, -781, 599, 939, -116, 360, -650, -1019, +169, 237, 530, 835, -136, -617, -353, -291, +52, 609, 225, -385, -36, -317, -377, 750, +151, -198, 567, -513, -323, 841, -654, -236, +488, -1176, 468, 957, -729, 862, -51, -1158, +793, -145, -395, 924, -600, -604, 633, -501, +188, 1062, -612, -76, 174, -843, 339, 448, +-307, 96, -30, -287, 196, 351, -131, -137, +-71, -210, 47, 330, 53, -116, 180, -88, +-206, 168, -353, -448, 317, 112, 248, 830, +-275, -452, -17, -870, 205, 823, -268, 643, +-202, -1347, 459, -169, 86, 1669, -504, -451, +151, -1348, 352, 978, -444, 608, -54, -1315, +583, -52, -241, 1490, -682, -269, 490, -1338, +648, 553, -723, 889, -426, -756, 800, -526, +73, 874, -755, 289, 199, -833, 572, -87, +-346, 665, -326, 13, 344, -567, 53, 53, +-355, 517, 93, -187, 341, -376, -77, 344, +-415, 128, 39, -528, 612, 274, -327, 650, +-719, -743, 674, -521, 639, 1010, -918, 60, +-364, -790, 911, 466, -112, 187, -621, -632, +391, 277, 273, 316, -368, -177, -68, 162, +221, -500, -127, -75, -158, 1038, 256, -777, +203, -705, -325, 1581, -167, -308, 300, -1542, +-61, 1256, -329, 639, 270, -1502, 409, 471, +-501, 885, -227, -1042, 666, 175, -220, 849, +-751, -1059, 570, -268, 692, 1332, -793, -122, +-307, -1091, 747, 256, -302, 693, -409, -399, +741, -221, -168, 405, -871, -268, 856, -28, +680, 613, -1346, -558, -405, -645, 1396, 989, +62, 233, -967, -1104, 326, 523, 289, 926, +-586, -1208, 150, -384, 613, 1337, -388, -483, +-372, -911, 595, 1320, 8, 382, -740, -1703, +217, 125, 724, 1383, -330, -718, -622, -542, +445, 1062, 527, -209, -497, -707, -452, 519, +347, -165, 404, -581, -173, 883, -318, 544, +210, -1071, 97, -279, -320, 882, 100, -55, +310, -702, -188, 97, -147, 740, 238, 56, +6, -725, -344, -28, 14, 333, 475, -170, +19, 262, -524, 123, 75, -609, 413, 421, +-210, 434, -197, -1130, 253, 255, -7, 1229, +-116, -1094, 217, -353, -206, 1402, -228, -899, +411, -806, 106, 1495, -362, -223, 123, -1006, +205, 789, -399, 43, 35, -510, 465, 424, +-172, -203, -216, -77, 254, 634, -110, -613, +-290, -405, 408, 929, 202, -237, -490, -630, +142, 633, 257, 95, -492, -512, 278, 326, +517, 184, -764, -674, -20, 63, 905, 1048, +-645, -301, -577, -1313, 1017, 797, 63, 1221, +-864, -1579, 459, -700, 471, 2246, -716, -116, +-129, -2281, 725, 938, 24, 1649, -612, -1544, +162, -823, 578, 1886, -519, 61, -462, -1750, +938, 532, 164, 1028, -1006, -726, 334, -175, +720, 454, -668, -223, -322, 146, 747, 3, +166, -644, -623, 504, -143, 529, 639, -741, +150, 146, -833, 549, 105, -760, 1071, -164, +-568, 851, -916, -238, 1110, -523, 468, 679, +-1431, 135, 213, -1131, 1425, 246, -764, 1338, +-909, -720, 1007, -1098, 279, 1228, -819, 494, +177, -1488, 449, 166, -68, 1297, -63, -494, +-402, -856, 131, 415, 756, 562, -553, -122, +-520, -651, 1136, -47, -45, 1062, -1262, -267, +673, -1316, 793, 1003, -924, 997, 116, -1629, +769, -131, -714, 1649, -137, -890, 795, -962, +-389, 1504, -508, -52, 734, -1443, 315, 827, +-770, 896, -89, -1106, 756, -252, -157, 1051, +-582, -311, 636, -824, 366, 730, -949, 367, +64, -799, 946, 75, -450, 531, -443, -115, +768, -404, -71, -56, -697, 687, 536, -141, +367, -949, -781, 744, 298, 559, 834, -1116, +-617, 404, -501, 643, 581, -1101, 218, 435, +-390, 833, 60, -1276, 484, 108, -86, 1425, +-691, -834, 304, -1158, 825, 985, -716, 876, +-370, -1003, 1283, -485, -334, 1267, -1364, -198, +1050, -1480, 894, 895, -1078, 1163, -169, -1149, +760, -466, -32, 906, -359, 90, -43, -627, +227, -281, 255, 649, -93, 486, -113, -844, +142, -231, -86, 993, -143, -395, 286, -1003, +325, 965, -213, 698, -365, -1141, 306, -87, +432, 981, -492, -527, -297, -824, 895, 956, +153, 616, -922, -1276, 162, 48, 793, 1412, +-429, -1134, -452, -1004, 826, 1900, 164, -72, +-739, -1684, 188, 1277, 305, 606, -154, -1783, +322, 611, -191, 1230, -266, -1275, 826, -132, +-204, 1204, -1029, -612, 737, -715, 925, 627, +-877, 246, -375, -359, 1013, -14, -45, 443, +-898, -167, 319, -683, 667, 434, -251, 339, +-228, -379, 481, 410, 37, -169, -848, -628, +273, 633, 1263, 168, -639, -597, -1197, 230, +1375, 389, 873, -165, -1899, -439, -53, 112, +1928, 537, -690, -481, -1112, -236, 1222, 886, +265, -351, -1181, -766, 455, 750, 941, 166, +-680, -815, -355, 430, 797, 747, -64, -798, +-589, -581, 248, 1047, 546, 119, -2, -1146, +-529, 543, 173, 894, 607, -947, -584, -256, +-346, 736, 1140, -344, 24, -137, -1118, 357, +454, -144, 846, 115, -620, -102, -464, -435, +851, 427, 370, 312, -865, -613, -133, 153, +972, 767, -143, -800, -809, -677, 632, 1394, +643, -62, -748, -1488, -226, 1192, 710, 810, +-16, -1767, -450, 199, 313, 1291, 572, -791, +-500, -348, -528, 665, 834, -171, 256, -167, +-796, 23, 479, -193, 615, 386, -886, 158, +-110, -650, 880, 287, -271, 605, -279, -811, +631, -306, -74, 1011, -517, -92, 188, -879, +385, 539, -49, 538, -173, -905, 328, -77, +168, 846, -479, -317, 158, -307, 301, 480, +-412, -343, 340, -427, 632, 798, -526, 63, +-406, -951, 576, 681, 26, 594, -494, -1370, +687, 263, 490, 1304, -1046, -1035, 49, -530, +1042, 1253, -661, -210, -503, -1220, 1238, 649, +1, 1319, -1187, -1303, 673, -1165, 877, 2249, +-1042, 206, -335, -2601, 1244, 1091, 121, 1774, +-997, -1698, 146, -539, 877, 1414, -354, -28, +-788, -985, 867, -58, 962, 892, -1319, -14, +-590, -887, 1710, 559, -130, 617, -1562, -1076, +1007, -199, 1353, 1069, -1404, -50, -730, -739, +1589, 153, -19, 528, -1475, -358, 1066, -367, +1254, 615, -1653, -87, -428, -575, 1725, 691, +-361, 155, -1322, -858, 988, 159, 1207, 529, +-1111, 74, -1015, -473, 1348, -487, 684, 1159, +-1474, 219, 61, -1914, 1492, 896, -456, 1691, +-957, -1876, 605, -514, 361, 1765, -343, -516, +262, -803, -6, 670, -303, -72, 667, -155, +40, 278, -1030, -436, 495, 90, 1111, 668, +-694, -493, -719, -407, 827, 526, 481, -143, +-856, -178, -186, 543, 1092, -302, 14, -488, +-987, 742, 319, 81, 815, -1111, -534, 414, +-431, 1234, 940, -881, 221, -889, -1201, 1247, +261, 124, 1420, -1253, -857, 609, -1033, 642, +1594, -793, 285, 229, -1641, 482, 703, -666, +1182, -173, -1135, 472, -395, 80, 1220, -117, +-88, -84, -767, 153, 449, 11, 337, -571, +-368, 65, 46, 872, 280, 2, -68, -917, +-34, -27, 123, 955, -9, -330, 30, -1006, +32, 954, 52, 799, 126, -1262, -169, -341, +-33, 988, 478, -38, -4, -528, -533, 130, +218, 239, 599, 124, -330, -204, -592, -620, +621, 567, 816, 816, -727, -1291, -842, -101, +942, 1706, 687, -1233, -1061, -1013, -39, 1986, +1011, -449, -305, -1432, -525, 1413, 332, 288, +241, -1320, -43, 415, -83, 709, -56, -613, +345, -181, 109, 718, -516, -195, 18, -698, +731, 541, -24, 204, -778, -729, 297, 664, +859, 465, -481, -1249, -702, 366, 685, 908, +561, -1334, -512, 286, -396, 1525, 479, -1383, +515, -622, -618, 1502, -314, -499, 924, -967, +-105, 864, -690, 741, 673, -701, 179, -937, +-760, 898, 416, 738, 554, -1479, -511, 140, +-29, 1629, 392, -974, -199, -1059, -69, 1166, +197, 232, 12, -933, 152, 296, 113, 610, +-372, -320, -68, -361, 571, -5, -73, 336, +-439, 112, 471, -455, 422, 372, -793, 222, +-241, -970, 1142, 650, -181, 791, -964, -1656, +851, 347, 493, 1973, -995, -1695, 220, -1313, +593, 2447, -560, 41, 215, -2412, 543, 1246, +-521, 1851, -178, -2078, 453, -977, -117, 2228, +-76, -98, 378, -1747, -25, 1023, -289, 1011, +22, -1455, 180, -360, 96, 1419, 18, -219, +-59, -1190, 58, 768, 169, 951, -179, -1068, +-135, -676, 182, 965, 165, 399, 239, -679, +-194, -240, -487, 613, 532, 196, 420, -788, +-832, -93, 67, 866, 1011, -242, -366, -633, +-718, 675, 568, 155, 307, -740, -568, 291, +114, 194, 556, -407, -204, 497, -147, 123, +246, -525, -415, 169, -139, -185, 980, 91, +37, 739, -1188, -847, 453, -399, 1256, 1471, +-1041, -574, -1022, -1468, 1555, 1433, 691, 785, +-1608, -1684, -26, 192, 1438, 1278, -531, -870, +-1094, -524, 953, 901, 774, -163, -1019, -469, +-79, 613, 790, -78, -412, -815, -373, 710, +458, 506, 340, -1231, -75, 459, -475, 1093, +-37, -1481, 722, -113, -276, 1704, -677, -1029, +864, -943, 488, 1516, -1030, -114, -102, -1287, +903, 891, -271, 808, -667, -1432, 877, -154, +507, 1867, -1302, -877, -53, -1896, 1436, 2033, +-498, 1213, -1146, -2618, 1045, -122, 914, 2362, +-1272, -713, -609, -1838, 1446, 1058, 287, 1627, +-1586, -1284, 265, -1559, 1860, 1736, -838, 1140, +-1775, -2189, 1502, -431, 1262, 2270, -1954, -140, +-291, -2043, 2207, 639, -631, 1685, -1929, -1388, +1431, -1058, 1262, 2059, -1807, 75, -358, -1924, +1981, 908, -246, 957, -1944, -1402, 737, -26, +1807, 1383, -1037, -287, -1450, -1235, 1436, 392, +1153, 1098, -1811, -811, -667, -810, 2051, 1223, +173, 406, -1877, -1001, 430, -253, 1561, 300, +-898, 510, -918, 85, 1062, -914, 329, 281, +-750, 997, 104, -1021, 468, -495, -156, 1391, +-297, -301, 64, -1111, 376, 788, 58, 596, +-217, -785, -36, -223, 14, 575, 97, -176, +114, -327, -89, 665, 94, 28, 189, -943, +-364, 187, -96, 921, 563, -303, -73, -872, +-418, 635, 320, 749, 236, -1279, -305, -135, +-56, 1668, 137, -962, 151, -1257, 149, 1900, +-312, 275, -155, -2203, 505, 640, 33, 2019, +-507, -1292, 251, -1601, 427, 1922, -423, 822, +-108, -2503, 595, 450, -219, 2538, -567, -1799, +453, -1703, 545, 2416, -312, 516, -556, -2024, +236, 64, 673, 1416, -327, 154, -635, -1453, +723, -285, 435, 1951, -941, -323, 0, -2072, +929, 1289, -353, 1517, -706, -1890, 780, -657, +463, 1942, -1040, -103, 60, -1691, 1051, 588, +-592, 1373, -656, -852, 1004, -1027, 237, 1030, +-932, 582, 80, -1138, 686, -146, -93, 1099, +-542, -76, 218, -912, 652, 69, -344, 692, +-640, 51, 482, -601, 540, -206, -501, 721, +-293, 281, 688, -911, 242, -74, -994, 877, +-170, -444, 1440, -606, -19, 1002, -1627, 323, +588, -1355, 1639, -25, -1273, 1416, -1307, -538, +1811, -1122, 789, 1294, -1788, 475, -159, -1626, +1497, 317, -212, 1216, -1120, -854, 322, -520, +1031, 940, -235, 123, -886, -623, 285, -96, +690, 55, -356, 212, -376, 535, 514, -453, +198, -872, -497, 955, -45, 759, 555, -1525, +-172, -329, -490, 1704, 594, -27, 323, -1408, +-750, 23, 23, 1122, 628, 189, -348, -1259, +-199, -246, 528, 1636, 36, 79, -518, -1764, +-109, 71, 707, 1503, 101, -24, -847, -1106, +251, -176, 871, 863, -615, 343, -522, -708, +747, -382, 145, 399, -424, 474, -52, -10, +347, -750, 242, -154, -574, 1102, -207, -31, +929, -1358, -125, 483, -758, 1485, 526, -1081, +246, -1418, -360, 1693, 192, 1003, -146, -2079, +-242, -218, 808, 2018, 58, -707, -1019, -1428, +234, 1280, 806, 474, -304, -1152, -465, 380, +358, 551, 296, -754, -308, -19, -153, 673, +218, -218, -53, -436, 42, 382, 328, 224, +-309, -645, -178, 75, 343, 782, -259, -549, +63, -499, 587, 1056, -564, -95, -250, -1316, +842, 669, -317, 1100, -631, -1034, 599, -406, +437, 1109, -445, -417, -236, -853, 306, 916, +109, 315, -229, -902, 44, 282, 299, 507, +-107, -552, -185, 84, 147, 176, 68, -552, +-287, 692, 117, 552, 627, -1351, -358, -70, +-845, 1331, 789, -499, 724, -838, -1259, 727, +-170, 421, 1574, -528, -557, -435, -1382, 171, +1238, 836, 731, -83, -1587, -1398, 132, 429, +1621, 1867, -725, -959, -1446, -2136, 1137, 1317, +1264, 2207, -1522, -1394, -873, -2077, 1917, 1319, +413, 1733, -1970, -1082, 20, -1326, 1858, 607, +-271, 1166, -1663, -46, 594, -1340, 1616, -250, +-1028, 1511, -1370, 181, 1568, -1336, 793, -27, +-1811, 930, 25, 87, 1688, -648, -711, -279, +-1142, 563, 1014, 372, 417, -432, -882, -283, +210, 68, 571, 223, -539, 355, -237, -380, +564, -508, -109, 607, -348, 412, 525, -537, +-60, -495, -830, 143, 625, 1015, 922, 132, +-1102, -1612, -914, 20, 1506, 1771, 1052, -349, +-1756, -1471, -1314, 432, 2028, 1107, 1618, -189, +-2311, -874, -1599, -173, 2597, 685, 1315, 557, +-2641, -502, -877, -1020, 2489, 537, 494, 1456, +-2000, -861, -250, -1609, 1406, 1171, 186, 1473, +-869, -1174, -357, -1313, 574, 1023, 784, 1379, +-578, -1095, -1276, -1599, 846, 1534, 1577, 1694, +-1312, -2134, -1523, -1460, 1810, 2582, 1095, 926, +-2086, -2661, -432, -405, 1909, 2343, -110, 295, +-1329, -1813, 303, -713, 764, 1332, -204, 1317, +-411, -1007, 52, -1676, 371, 727, 105, 1675, +-428, -378, -61, -1521, 411, -17, -32, 1324, +-317, 292, 62, -998, 494, -263, -18, 430, +-969, -40, 211, 305, 1392, 374, -750, -962, +-1403, -541, 1375, 1408, 1023, 550, -1769, -1748, +-405, -455, 1712, 2100, -367, 152, -1203, -2371, +1048, 483, 372, 2321, -1314, -1286, 402, -1933, +1055, 1821, -705, 1461, -655, -1924, 476, -1104, +634, 1861, -22, 795, -1060, -1889, -345, -373, +1637, 1870, 630, -62, -1990, -1580, -855, 226, +2159, 1131, 1124, 58, -2314, -917, -1395, -676, +2515, 1189, 1634, 1330, -2605, -1821, -1702, -1641, +2319, 2381, 1779, 1483, -1847, -2419, -2074, -1117, +1417, 1872, 2486, 1006, -1283, -1154, -2730, -1274, +1283, 739, 2510, 1556, -1090, -627, -2169, -1559, +582, 448, 1869, 1365, 40, -19, -1804, -1208, +-493, -490, 1879, 1231, 639, 806, -1954, -1486, +-571, -883, 2129, 1968, 102, 806, -2179, -2531, +811, -636, 1882, 2941, -1667, 378, -1176, -3038, +2061, -125, 484, 2862, -1901, 70, -203, -2524, +1630, -284, 281, 2055, -1464, 572, -396, -1453, +1441, -671, 314, 804, -1596, 528, -40, -224, +1667, -275, -358, -282, -1688, -20, 699, 726, +1554, 413, -1008, -1058, -1424, -873, 1109, 1171, +1057, 1260, -1156, -1050, -488, -1423, 842, 856, +13, 1433, -321, -728, -12, -1475, 23, 689, +191, 1628, -211, -719, -175, -1771, 812, 848, +-96, 1782, -1291, -1167, 296, -1633, 1717, 1609, +-146, 1401, -2205, -1931, -82, -1211, 2795, 1937, +328, 1233, -3237, -1776, -611, -1544, 3457, 1735, +1173, 2041, -3595, -1835, -1976, -2555, 3675, 1828, +2544, 3009, -3698, -1540, -2754, -3308, 3390, 1080, +2545, 3358, -2863, -656, -2213, -3168, 2060, 329, +1525, 2808, -1292, -35, -558, -2278, 380, -328, +-689, 1515, 695, 781, 1723, -618, -2005, -1207, +-2284, -131, 3208, 1404, 2229, 572, -3842, -1297, +-1796, -856, 3800, 1012, 1510, 1202, -3230, -774, +-1491, -1617, 2564, 726, 1798, 1932, -1933, -902, +-2129, -2001, 1581, 1180, 2370, 1765, -1314, -1275, +-2374, -1239, 1061, 794, 2157, 603, -651, 438, +-1976, -240, 42, -1997, 1925, 337, 470, 3066, +-1924, -602, -908, -3154, 1608, 528, 1038, 2550, +-1152, -20, -1232, -1875, 662, -516, 1277, 1429, +-614, 653, -1121, -991, 794, -338, 436, 343, +-1077, -236, 542, 292, 1099, 921, -1415, -559, +-860, -1711, 1757, 503, 715, 2497, -1563, -434, +-765, -3051, 1121, 418, 1049, 3255, -531, -103, +-1314, -3288, 89, -624, 1611, 3411, 315, 1336, +-1921, -3698, -421, -1549, 2159, 3995, 321, 1344, +-2214, -4134, -66, -1209, 2086, 4152, -243, 1371, +-1999, -4201, 390, -1523, 1907, 4342, -434, 1376, +-2016, -4326, 253, -1010, 1845, 3806, 19, 761, +-1578, -2640, -423, -806, 950, 1210, 622, 1053, +-209, -69, -720, -1193, -724, -602, 529, 1008, +1698, 1124, -226, -529, -2487, -1766, -244, 48, +2956, 2369, 786, 292, -3066, -2562, -1201, -608, +2897, 2356, 1584, 1101, -2461, -2073, -1739, -1653, +1786, 1948, 1907, 1963, -929, -1796, -2038, -1941, +122, 1455, 2217, 1887, 343, -1072, -2234, -1976, +-507, 1000, 1911, 2057, 534, -1201, -1558, -1851, +-816, 1351, 1535, 1548, 793, -1082, -2123, -1556, +-439, 522, 2833, 2057, -390, 90, -3364, -2648, +913, -674, 3300, 2881, -972, 1407, -3036, -2626, +580, -2213, 2514, 2131, -160, 2807, -1984, -1532, +-85, -2832, 1214, 854, 175, 2355, -385, -14, +-127, -1609, -341, -811, -87, 854, 927, 1418, +416, -111, -1332, -1646, -766, -544, 1760, 1642, +952, 1059, -2166, -1534, -995, -1299, 2512, 1421, +871, 1266, -2781, -1141, -694, -973, 2828, 672, +441, 573, -2901, -53, -319, -191, 2873, -523, +111, 93, -2908, 1057, -38, -402, 2509, -1480, +173, 1184, -2066, 1763, -774, -2209, 1461, -1694, +1344, 3158, -992, 1385, -1785, -3490, 305, -1101, +1834, 3111, 399, 1174, -1758, -2242, -1010, -1413, +1414, 1381, 1181, 1534, -893, -620, -1026, -1264, +207, -79, 538, 731, 441, 822, 111, -14, +-1000, -1328, -890, -759, 1165, 1469, 1720, 1696, +-1137, -1224, -2633, -2657, 953, 847, 3348, 3545, +-1019, -392, -3690, -4049, 1040, -48, 3310, 4061, +-1078, 526, -2565, -3551, 748, -915, 1435, 2856, +-264, 1166, -620, -2028, -363, -1125, -65, 1101, +641, 984, 188, -110, -783, -789, 60, -440, +404, 687, -645, 321, -17, -578, 1113, 440, +-544, 493, -1324, -1289, 657, -332, 1144, 1893, +-453, 346, -1009, -2001, -71, -602, 695, 1705, +589, 1123, -402, -987, -1197, -1485, -24, 157, +1478, 1421, 274, 583, -1658, -750, -416, -866, +1286, -182, 354, 656, -871, 1286, -321, 26, +43, -2328, 130, -738, 679, 3139, -276, 1330, +-1259, -3278, 358, -1625, 1159, 2811, -730, 1723, +-795, -1912, 915, -1416, 5, 966, -1205, 830, +614, -2, 1267, -133, -1270, -722, -1352, -199, +1334, 1129, 1045, 131, -1120, -965, -731, 371, +473, 515, 106, -1018, 34, 87, 422, 1769, +-563, -595, -1193, -2301, 778, 1013, 1704, 2594, +-1099, -1119, -2104, -2576, 1085, 1149, 1858, 2463, +-1006, -1206, -1502, -2117, 513, 1490, 774, 1642, +-323, -1637, -167, -1010, 119, 1592, -748, 542, +-390, -1295, 1548, -207, 492, 1129, -2581, 80, +-787, -1048, 3141, 78, 827, 1084, -3595, -163, +-1092, -1028, 3495, 381, 1076, 1029, -3429, -646, +-1036, -831, 2857, 1032, 470, 421, -2268, -1221, +3, 289, 1416, 1274, -540, -817, -1027, -1132, +450, 914, 769, 1147, -325, -400, -1033, -1310, +-82, -106, 1008, 1591, 302, 350, -1257, -1453, +-773, -254, 1117, 945, 887, 318, -1171, -105, +-1101, -458, 938, -557, 700, 600, -1104, 927, +-232, -343, 1037, -759, -791, -82, -1117, 306, +1434, 620, 765, 460, -2198, -1003, -561, -1221, +2294, 1378, 319, 2080, -2418, -1479, -642, -2911, +1959, 1390, 932, 3757, -1471, -930, -1623, -4169, +507, 277, 1851, 4197, 309, 648, -1931, -3709, +-1433, -1442, 1137, 2894, 2118, 2078, -280, -1525, +-2808, -2318, -802, 25, 2702, 2470, 1104, 1268, +-2473, -2431, -1077, -1617, 1486, 2274, 229, 1165, +-658, -1627, 389, -164, -247, 809, -1253, -749, +315, -23, 1519, 1553, -234, -223, -1824, -1971, +-476, 58, 1561, 2125, 723, 450, -1259, -1856, +-1064, -784, 374, 1377, 712, 998, 470, -555, +-560, -941, -1619, -329, 93, 824, 2086, 1324, +217, -505, -2507, -2003, -936, 320, 2265, 2290, +1247, -63, -1990, -1956, -1741, -224, 1204, 1413, +1691, 877, -678, -734, -1898, -1565, 52, 303, +1629, 2035, -135, 15, -1422, -1712, 111, -64, +590, 892, -538, 26, -105, 192, 582, 251, +-285, -871, -1166, -419, -109, 959, 1412, 604, +425, -189, -1868, -665, -1152, -935, 1642, 713, +1500, 2162, -1464, -346, -2089, -2958, 807, -265, +2047, 3266, -512, 1029, -1906, -2743, 21, -1330, +1121, 1605, -130, 1211, -483, 58, 76, -716, +-329, -1408, -417, 287, 375, 2023, 598, 294, +-238, -1556, -1345, -895, -388, 514, 1593, 1581, +709, 800, -1645, -1900, -1324, -1699, 789, 1850, +1401, 2070, -13, -1284, -1407, -1693, -1173, 735, +779, 993, 1739, -353, -479, -191, -2183, 438, +46, -96, 1658, -679, -167, -99, -1114, 1008, +100, 819, 256, -1024, -540, -1532, -14, 898, +665, 2043, -158, -474, -982, -1963, -270, 9, +663, 1539, 588, 510, -346, -707, -1284, -692, +-386, -189, 1519, 722, 730, 1095, -1661, -484, +-1270, -1627, 1156, 257, 1498, 1989, -896, 31, +-1882, -2097, 330, -113, 1888, 2192, -135, 195, +-2197, -2107, -246, -174, 2082, 2049, 354, 426, +-2185, -1889, -885, -875, 1717, 1850, 1230, 1543, +-1350, -1630, -1843, -1882, 468, 1271, 1936, 1825, +67, -575, -2150, -1250, -533, -34, 1761, 629, +183, 374, -1346, 19, 216, -15, 436, -507, +-926, -689, 31, 942, 1182, 1484, -261, -866, +-1604, -1900, -76, 315, 1486, 1985, 384, 674, +-1493, -1514, -905, -1559, 1114, 702, 1111, 2292, +-792, 439, -1760, -2661, 147, -1424, 2217, 2844, +201, 2154, -2601, -2550, -749, -2369, 2044, 1785, +1017, 2348, -1094, -418, -1601, -2062, -416, -1040, +1804, 1750, 1520, 2277, -1905, -1233, -2459, -2793, +1192, 616, 2552, 2748, -284, 218, -2438, -2217, +-815, -918, 1576, 1557, 1245, 1467, -705, -724, +-1319, -1656, -457, 49, 779, 1700, 1026, 374, +-299, -1524, -1265, -286, -274, 1393, 736, -66, +255, -1281, -18, 602, -108, 1429, -903, -990, +-470, -1678, 1230, 1206, 957, 2108, -1252, -986, +-1650, -2518, 710, 486, 1937, 2910, -260, 255, +-2057, -2912, -445, -890, 1585, 2557, 845, 1430, +-1028, -1836, -1327, -1646, 128, 1096, 1357, 1590, +485, -330, -1288, -1073, -1145, -261, 754, 260, +1201, 735, -210, 755, -1115, -876, -550, -1437, +659, 765, 773, 1577, -355, -382, -825, -1029, +120, 141, 232, 205, -309, -242, 308, 662, +617, 842, -821, -1162, -1303, -1518, 685, 1191, +1834, 1997, -264, -578, -2328, -1985, -474, -300, +2198, 1697, 1010, 1069, -1982, -1189, -1465, -1261, +1439, 681, 1586, 1067, -1048, -183, -1808, -769, +510, -62, 1733, 720, -153, 92, -1602, -734, +-420, 75, 979, 674, 841, -169, -236, -289, +-1330, 233, -833, -282, 1260, -278, 1636, 948, +-778, 564, -2093, -1337, -567, -1084, 1795, 1273, +2051, 1827, -1154, -587, -3390, -2444, 181, -396, +3753, 2751, 488, 1354, -3245, -2618, -1001, -1873, +1898, 2308, 1067, 1966, -607, -1940, -987, -1672, +-444, 1680, 624, 1215, 651, -1396, -239, -641, +-574, 1125, -190, 184, 263, -792, 196, -29, +-275, 498, 59, 405, 330, -250, -730, -1147, +-523, 105, 1207, 1986, 592, 90, -1643, -2512, +-765, -376, 1632, 2510, 835, 803, -1491, -1850, +-1069, -1137, 1062, 836, 1081, 1238, -684, 80, +-1066, -977, 150, -478, 869, 530, 200, 481, +-817, -135, -566, -363, 620, 93, 735, 407, +-409, -341, -1029, -592, -4, 683, 1204, 887, +230, -786, -1357, -1138, -399, 553, 1186, 1235, +230, -33, -849, -1080, -58, -461, 327, 771, +-202, 623, -174, -424, 246, -336, 365, 251, +-228, -125, -1114, -406, -28, 401, 1911, 967, +264, -171, -2680, -1705, -602, -587, 2884, 2282, +805, 1693, -2574, -2325, -1158, -2701, 1647, 1675, +1426, 3197, -470, -346, -1731, -2957, -833, -1352, +1556, 2031, 1893, 2893, -892, -570, -2651, -3754, +-332, -1147, 2663, 3685, 1615, 2638, -2041, -2751, +-2699, -3319, 840, 1288, 3054, 2923, 389, 187, +-2799, -1720, -1273, -1101, 1812, 331, 1390, 1210, +-584, 666, -999, -733, -544, -975, 321, 146, +825, 675, 190, 197, -328, -81, -519, -145, +-642, -456, 373, -337, 1367, 692, 86, 1065, +-1637, -545, -741, -1584, 1130, 29, 1212, 1458, +-210, 687, -1348, -717, -906, -1321, 942, -179, +1724, 1604, -362, 752, -2151, -1491, -153, -882, +2028, 1153, 311, 661, -1654, -831, -302, -297, +1098, 629, 351, -23, -801, -539, -551, 115, +580, 385, 618, 31, -217, -21, -568, -272, +-455, -520, 163, 369, 1172, 941, 371, -209, +-1613, -968, -974, -139, 1464, 621, 1312, 407, +-991, -275, -1106, -302, 323, 248, 268, -305, +91, -590, 835, 1101, -19, 1011, -1830, -1612, +-531, -1278, 2117, 1557, 1323, 1300, -1851, -1082, +-1852, -1234, 1109, 414, 1899, 1147, -284, 216, +-1628, -927, -292, -722, 1015, 330, 474, 1006, +-276, 522, -285, -1028, -493, -1239, -88, 753, +990, 1450, 305, -319, -1017, -1258, -402, -79, +857, 894, 172, 159, -532, -528, 59, 68, +218, 134, -112, -407, -66, 114, 38, 536, +-10, -68, 74, -375, 107, -204, -149, -3, +-355, 321, 249, 334, 604, -108, -254, -409, +-749, -338, 209, 134, 739, 633, -232, 219, +-593, -547, 527, -338, 250, 75, -890, 59, +236, 481, 959, 396, -430, -866, -662, -779, +203, 843, 247, 847, 320, -453, 140, -607, +-760, -157, -419, 37, 937, 609, 765, 709, +-840, -646, -1183, -1430, 667, 228, 1547, 1816, +-382, 279, -1641, -1798, 86, -577, 1458, 1408, +311, 609, -1114, -851, -598, -662, 719, 213, +761, 830, -156, 406, -686, -1062, -436, -984, +453, 1195, 954, 1439, -240, -1226, -978, -1771, +346, 1185, 605, 1882, -711, -1216, -172, -1803, +1440, 1307, 197, 1573, -2155, -1460, -678, -1470, +2711, 1485, 1323, 1550, -2594, -1287, -1637, -1639, +1802, 789, 1630, 1296, -617, -216, -1182, -414, +-167, -181, 380, -725, 357, 80, 650, 1497, +79, 503, -1402, -1581, -602, -1231, 1593, 992, +1024, 1461, -1125, -148, -981, -972, 468, -559, +657, 21, -14, 801, -43, 748, 108, -642, +-442, -1033, -430, 251, 764, 884, 703, 15, +-647, -730, -508, -6, 341, 826, 5, -242, +20, -1278, 802, 313, 72, 1778, -1422, 67, +-455, -1956, 1513, -897, 1075, 1484, -780, 1624, +-1204, -562, -279, -1726, 728, -469, 1131, 1033, +458, 1113, -1170, -34, -1503, -1181, 447, -850, +2053, 609, 773, 1325, -1549, 247, -1775, -1408, +275, -1076, 2321, 1037, 1393, 1622, -2064, -424, +-2525, -2006, 1313, -178, 2796, 2235, -162, 459, +-2143, -2312, -783, -589, 1321, 2076, 1380, 786, +-534, -1656, -1343, -1238, -14, 1028, 1148, 1649, +760, -243, -873, -1849, -1435, -759, 776, 1641, +2104, 1652, -578, -1175, -2289, -2235, 485, 535, +2203, 2236, -267, 23, -1722, -1773, 152, -514, +1256, 955, 60, 790, -501, -153, -132, -909, +-181, -496, 153, 759, 878, 809, 158, -510, +-1117, -971, -369, 130, 1030, 992, 609, 285, +-640, -955, -579, -856, 569, 651, 531, 1291, +-563, -155, -330, -1391, 790, -511, 197, 946, +-688, 977, -47, -294, 647, -1189, 146, -407, +-455, 1064, -88, 914, 315, -840, 142, -1292, +32, 449, -15, 1335, -219, 24, -8, -1069, +499, -585, 241, 502, -502, 851, -520, -106, +638, -761, 1009, 66, -403, 323, -1319, -489, +191, -34, 1491, 910, 210, -57, -1016, -1095, +-360, -32, 388, 803, 460, -11, 368, -371, +-150, 19, -593, -136, -209, -34, 646, 520, +892, -27, -492, -920, -1274, -181, 503, 1004, +1593, 587, -200, -681, -1445, -1125, -126, -199, +1197, 1224, 769, 1133, -500, -822, -1125, -1840, +-101, -116, 1338, 1931, 881, 988, -998, -1642, +-1163, -1507, 489, 1017, 1265, 1323, 423, -458, +-779, -759, -1026, -4, 265, -34, 1513, 142, +382, 599, -1474, -201, -443, -921, 1533, 73, +372, 825, -1380, 59, -18, -592, 1301, -373, +160, 168, -701, 610, -258, 169, 108, -782, +422, -582, 614, 579, -59, 869, -645, -209, +-140, -1059, 360, -357, 383, 725, 352, 739, +-35, -21, -545, -947, -237, -926, 404, 629, +757, 1408, 416, -6, -792, -1319, -1007, -805, +702, 612, 1483, 1079, 108, 51, -1138, -761, +-835, -510, 553, -50, 1610, 488, 421, 587, +-1542, -412, -762, -758, 1118, 357, 832, 575, +-75, -582, -283, -623, -511, 632, 32, 730, +912, -513, 278, -818, -470, 130, -76, 384, +68, -46, -39, 188, 592, 213, 583, -595, +-617, -682, -803, 267, 573, 888, 1078, 441, +-3, -835, -721, -1307, -266, 344, 675, 1778, +654, 192, -513, -2040, -496, -791, 725, 1850, +685, 1043, -428, -1383, -590, -1066, 157, 468, +850, 570, 630, 303, -663, 83, -1053, -839, +688, -805, 1639, 838, -145, 995, -1609, -732, +-296, -839, 1565, 495, 1252, 393, -820, -471, +-1656, -257, 273, 362, 1891, 305, 598, -307, +-1353, -618, -643, -83, 1029, 648, 567, 485, +-374, -451, 70, -859, 239, -147, -206, 649, +138, 541, 562, -116, 77, -647, -432, -658, +-122, 143, 588, 963, 659, 445, -52, -814, +-690, -1043, -350, 61, 830, 1166, 1102, 645, +-158, -1011, -1136, -1186, -237, 373, 1203, 1121, +843, 233, -654, -860, -633, -759, 597, 408, +494, 732, -260, -224, 38, -538, 558, 61, +66, 160, -446, -141, -46, -40, 610, 107, +656, -114, -179, -162, -732, 109, 76, -7, +978, -292, 397, 108, -467, 352, -264, -425, +235, -485, 412, 667, 454, 399, -24, -1014, +-633, -540, 120, 934, 1172, 718, 129, -487, +-1030, -1019, 54, -464, 1080, 749, 398, 1152, +-578, -76, -500, -1413, 577, -850, 997, 947, +-191, 1176, -789, -369, 255, -1105, 746, -320, +206, 671, -39, 777, -168, -388, -226, -1266, +456, -146, 724, 1286, -135, 741, -461, -899, +275, -1413, 471, -65, -72, 1380, 26, 817, +492, -755, -110, -1238, -436, -418, 656, 971, +861, 1266, -612, -553, -818, -1714, 688, -69, +1174, 1450, 79, 493, -812, -967, -378, -930, +515, 224, 828, 944, 348, 306, -369, -769, +-398, -791, 214, 260, 548, 830, 86, -24, +21, -704, 331, -38, -3, 256, -167, -263, +243, -58, 223, 345, 2, 20, 239, -393, +269, -359, 30, 229, 43, 572, -138, -281, +-145, -892, 613, 202, 979, 1107, -260, -131, +-1352, -1501, 93, -346, 1779, 1563, 628, 870, +-1333, -1348, -772, -1490, 1113, 610, 1184, 1585, +-430, 26, -997, -1348, 344, -531, 1169, 692, +9, 564, -807, -261, 126, -599, 811, -76, +314, 518, -285, 116, -424, -579, 143, -271, +901, 339, 379, 204, -609, -151, -288, -48, +452, 48, 412, -531, 160, -538, 128, 1023, +-147, 1121, -272, -1389, 238, -1614, 717, 1195, +324, 1486, -431, -879, -647, -1098, 285, 450, +1279, 406, 447, -301, -1122, 122, -765, 102, +944, -581, 1124, -90, -49, 528, -640, 76, +-401, -279, 341, -354, 874, -214, 288, 462, +-555, 436, -247, -467, 351, -629, 443, 83, +291, 619, -244, 229, -372, -723, 396, -523, +566, 578, -69, 466, -119, -375, 87, -389, +-100, -55, 311, 127, 524, 193, -270, -66, +-314, -144, 562, 50, 354, -249, -428, -350, +-148, 390, 558, 562, 453, -330, -201, -791, +-300, -83, 149, 705, 227, 246, 176, -613, +282, -251, -17, 370, -201, -7, 125, -301, +95, 65, 28, 116, 492, -168, 227, -40, +-525, 248, -131, -138, 447, -610, 283, 103, +137, 859, 18, -56, -350, -1035, -22, -174, +626, 814, 332, 271, -404, -474, -356, -458, +445, -115, 668, 463, -80, 583, -636, -415, +-116, -1013, 802, 6, 584, 1059, -423, 435, +-655, -920, 180, -868, 795, 463, 312, 859, +-423, -26, -387, -632, 254, -477, 504, 143, +214, 697, -232, 204, -367, -725, 222, -506, +696, 353, 41, 476, -673, -2, 47, -286, +675, -275, 67, -215, -172, 125, 139, 627, +-155, 195, -242, -903, 533, -712, 711, 739, +-281, 1062, -907, -446, -34, -1283, 1034, 22, +618, 1101, -531, 229, -724, -692, 121, -546, +694, -17, 369, 753, -318, 554, -327, -856, +329, -726, 292, 490, -290, 156, -30, -46, +476, 695, 91, -103, -355, -1390, 16, -516, +378, 1272, 109, 1331, -247, -553, -16, -1753, +321, -431, 119, 1289, 1, 935, -147, -459, +-240, -900, 446, -255, 610, 431, -613, 358, +-641, -118, 1024, -95, 681, 19, -1109, -340, +-460, -172, 1045, 461, 400, 235, -576, -291, +-99, -290, 317, -190, 33, 200, -193, 576, +39, -84, 502, -789, 140, -223, -463, 592, +-236, 460, 324, -198, 425, -497, 76, -294, +-333, 48, -192, 504, 369, 597, 244, -503, +-232, -1206, -115, 361, 278, 1445, 165, -373, +-169, -1420, -88, 374, 168, 1085, 126, -301, +-58, -558, 102, 85, 70, -187, -219, -87, +76, 707, 395, 272, -60, -750, -278, -423, +55, 256, 169, 54, 234, 182, 122, 624, +-454, -195, -237, -1166, 637, -268, 442, 1063, +-407, 616, -409, -563, 27, -608, 239, 15, +572, 290, 354, 309, -802, -90, -1025, -665, +673, -39, 1628, 1020, -11, 261, -1600, -1113, +-660, -692, 1148, 565, 1161, 926, -415, 274, +-1099, -698, -87, -812, 869, 97, 525, 667, +-570, 309, -850, -350, 489, -330, 1346, 418, +-367, 139, -1572, -957, 186, -202, 1549, 1378, +144, 535, -1091, -1327, -259, -917, 625, 874, +288, 963, -261, -456, -128, -670, 153, 163, +177, 186, -19, 37, -324, 155, -18, -257, +525, -224, 143, 380, -607, -26, -95, -374, +728, 382, 99, 252, -813, -662, -206, -195, +1030, 637, 437, 209, -967, -321, -539, -236, +703, -151, 463, 161, -341, 455, -91, -79, +137, -453, -82, 67, -6, 221, 19, -183, +-199, -69, 266, 250, 663, 85, -345, -169, +-981, -166, 118, -49, 912, 121, 369, 176, +-352, 8, -675, -122, -251, -134, 632, -39, +651, 208, -237, 95, -661, -246, -191, 8, +449, 176, 452, -222, -99, 3, -307, 486, +-192, -134, -204, -772, 273, -57, 935, 957, +-9, 572, -1408, -859, -546, -1003, 1343, 443, +1137, 894, -782, 8, -1391, -248, 100, -129, +1211, -434, 373, -163, -733, 614, -533, 585, +194, -253, 470, -790, 206, -204, -180, 686, +-423, 359, -286, -445, 435, -210, 703, 240, +-184, -18, -870, -113, -88, 193, 551, 30, +150, -344, 79, 18, 78, 522, -617, -14, +-572, -703, 834, -7, 964, 828, -712, -13, +-1078, -834, 453, 66, 881, 659, -357, -137, +-517, -331, 377, 210, 183, 21, -520, -230, +-17, 180, 496, 154, -68, -323, -217, -12, +67, 517, -298, -42, -227, -698, 801, -47, +461, 689, -1063, 124, -812, -453, 881, 1, +1037, 198, -496, -257, -1031, -105, 47, 397, +665, 153, 130, -284, -267, -155, -54, 84, +13, 64, -239, -16, -193, -16, 407, 116, +527, 156, -361, -189, -794, -403, -36, 89, +624, 531, 400, 127, -212, -338, -552, -202, +-323, -52, 267, 20, 552, 309, 49, 302, +-538, -121, -343, -420, 338, -363, 293, 206, +-243, 706, -202, 181, 99, -569, 92, -449, +-107, 124, -107, 529, 66, 200, 15, -479, +-257, -116, 22, 378, 443, -244, -103, -235, +-605, 560, -81, 149, 434, -596, 237, -232, +-188, 372, -376, 440, -122, -43, 226, -531, +39, -189, 3, 375, 146, 220, -273, -106, +-453, -71, 241, -25, 409, -103, -198, 37, +-196, 246, 52, -51, -187, -340, -253, 110, +406, 430, 404, 0, -594, -403, -574, -351, +514, 169, 525, 731, -498, 185, -512, -778, +241, -315, 434, 458, -113, 50, -500, -78, +-17, 404, 399, -52, -128, -555, -450, 83, +141, 258, 403, -304, -60, 161, -444, 724, +-387, -237, 138, -889, 677, 6, 170, 525, +-742, 150, -483, 150, 227, 47, 280, -590, +276, -298, 102, 648, -688, 280, -645, -576, +552, -3, 802, 710, -289, -77, -830, -892, +-136, -190, 494, 788, 207, 541, -194, -217, +-183, -446, -191, -411, -191, -113, 234, 661, +372, 709, -166, -441, -550, -787, -93, 261, +403, 411, 46, -444, -392, -72, 11, 814, +299, 230, -246, -750, -366, -599, 135, 185, +294, 677, -71, 417, -399, -242, -170, -483, +326, -227, 234, 160, -276, 352, -336, 155, +-218, -123, 21, -198, 625, -70, 363, 224, +-819, 166, -889, -259, 363, -219, 809, 123, +96, 298, -374, 382, -389, -168, -396, -840, +76, -171, 777, 833, 170, 576, -942, -277, +-379, -747, 732, -283, 195, 738, -550, 540, +-227, -588, 98, -455, 193, 474, 231, 315, +-242, -323, -604, -113, -66, 254, 461, -76, +298, -237, -217, 253, -492, 352, -210, -219, +170, -413, 277, 97, 115, 404, -224, 17, +-371, -224, -166, 0, 84, 12, 314, 103, +279, 300, -367, -325, -722, -599, -10, 578, +624, 867, 256, -479, -318, -819, -426, 129, +-305, 448, 116, 212, 601, 183, 216, -160, +-771, -610, -634, -125, 499, 679, 637, 397, +-275, -374, -547, -314, -6, 154, 92, 86, +-75, -184, 65, 110, 210, 472, -68, -4, +-496, -488, -418, -109, 352, 66, 735, 3, +-139, 674, -825, 537, -270, -996, 345, -1012, +234, 658, 65, 1054, -72, 168, -381, -474, +-432, -752, 186, -177, 741, 969, 70, 626, +-1072, -905, -565, -763, 960, 927, 751, 930, +-717, -830, -796, -949, 163, 661, 293, 796, +26, -415, 207, -402, -66, 403, -647, 216, +-258, -376, 472, -177, 294, 287, -165, 147, +-260, -5, -347, 229, -52, -107, 449, -612, +185, 154, -450, 830, -409, -163, 36, -709, +366, 360, 277, 647, -374, -395, -585, -573, +45, 243, 433, 503, 103, 150, -249, -171, +-272, -326, -67, -105, 35, 327, -10, 304, +132, -73, 40, -244, -412, -71, -240, 214, +332, 155, 218, -116, -260, -1, -306, 88, +-100, -158, 118, 58, 179, 416, 19, -65, +-194, -516, -392, 21, -119, 619, 416, 218, +178, -534, -410, -325, -216, 408, 112, 361, +-46, -37, -35, -87, 72, -241, -178, -264, +-202, 361, 200, 689, 146, -60, -363, -743, +-292, -189, 244, 538, 171, 216, -269, -102, +-162, 158, 166, -69, 50, -350, -284, 165, +-306, 293, 49, -206, 412, 7, 184, 447, +-472, 2, -520, -439, 35, -144, 301, 172, +262, 317, 91, 395, -499, -176, -738, -752, +222, 68, 952, 1017, 5, 82, -1053, -1048, +-374, -126, 673, 1044, 342, 321, -332, -689, +-243, -281, -206, 329, -288, 119, 250, -70, +633, 231, -111, 266, -890, -301, -412, -455, +540, 271, 527, 493, -211, -83, -426, -56, +-162, 105, -171, -434, -25, -151, 529, 865, +270, 417, -791, -794, -769, -571, 532, 470, +881, 653, -328, 35, -947, -361, -58, -154, +556, 125, 72, 129, -274, 52, -136, -4, +-144, 15, -142, 151, 137, 130, 231, -110, +-117, -261, -479, -95, -217, 343, 346, 476, +268, -8, -281, -379, -319, -238, -79, -33, +-20, 279, 148, 583, 93, 76, -288, -593, +-200, -255, 139, 306, -70, 358, -285, 162, +57, -326, 269, -288, -51, 546, -408, 326, +-275, -617, 124, -189, 226, 501, 44, 184, +-172, 33, -278, -21, -221, -410, 0, -124, +269, 563, 251, 469, -392, -221, -673, -669, +223, -175, 622, 812, -330, 635, -568, -509, +249, -705, 187, 33, -341, 514, -99, 557, +82, 75, -112, -651, 53, -492, 24, 469, +-403, 675, -208, -111, 363, -407, 206, 165, +-348, 242, -412, -398, 28, -148, 320, 767, +-30, 278, -439, -834, -65, -210, 385, 846, +-142, 160, -608, -610, 83, 52, 514, 410, +-219, -118, -516, -67, 150, 257, 232, -105, +-357, -227, -230, 311, 325, 305, 93, -265, +-513, -316, -215, 169, 442, 442, 93, 163, +-530, -267, -230, -261, 285, 28, 138, 198, +-181, 270, -252, 147, -130, -193, 73, -206, +74, 128, -73, 125, -143, -103, -128, 105, +-35, 355, -7, -30, -67, -363, -6, -3, +-12, 259, -254, 45, -108, 6, 220, 98, +-46, -37, -280, 10, 12, 189, -9, -129, +-248, -362, 60, 291, 265, 663, -216, -87, +-479, -540, 25, -131, 421, 147, -45, 337, +-551, 447, -78, -177, 429, -631, -100, -6, +-466, 566, 92, 248, 147, -237, -317, -194, +-6, 115, 302, 136, -256, 49, -427, 78, +99, -104, 160, -168, -58, 227, 21, 367, +-118, -2, -393, -377, -87, -358, 339, 338, +144, 814, -256, -36, -304, -853, -99, -193, +83, 665, 101, 393, 26, -229, -134, -284, +-314, -16, -122, 166, 299, 206, 97, 72, +-404, -169, -196, -104, 235, 218, 21, 149, +-229, -187, -22, -20, 10, 296, -239, -42, +-66, -290, 323, 256, 55, 383, -537, -341, +-383, -361, 386, 426, 480, 414, -293, -288, +-598, -298, 32, 265, 330, 276, -114, -263, +-242, -228, 115, 421, 96, 322, -264, -404, +-238, -204, 75, 395, 168, 32, -32, -275, +-204, 251, -141, 238, 49, -298, 46, 15, +-122, 373, -142, -272, -16, -441, 73, 522, +77, 706, -149, -401, -354, -771, -78, 179, +331, 641, 201, 101, -271, -179, -447, -124, +-104, -231, 382, 118, 228, 591, -381, 24, +-357, -647, 171, -51, 185, 620, -138, 99, +-176, -431, -48, 8, 35, 340, 35, -31, +-73, -192, -161, 134, -89, 183, 36, -143, +97, -179, -18, 226, -167, 376, -172, -138, +-93, -508, 132, 9, 271, 615, -183, 222, +-514, -482, 92, -210, 426, 360, -251, 67, +-376, -232, 280, 211, 176, 304, -379, -247, +-146, -304, 189, 152, -87, 273, -103, 69, +220, -91, -49, -95, -461, 56, -29, 90, +404, -54, -68, -20, -387, 92, 104, 56, +287, 109, -277, 45, -463, -319, 183, -161, +504, 470, -88, 305, -560, -366, -157, -217, +364, 303, 177, 110, -303, -300, -243, -38, +208, 408, 102, 175, -255, -337, -22, -256, +138, 176, -241, 279, -182, 75, 339, -131, +200, -137, -390, 46, -426, 128, 102, 49, +467, 11, 104, -53, -422, -82, -294, 137, +117, 167, 156, -209, 31, -166, -37, 336, +-148, 185, -110, -271, 9, -49, -1, 81, +-9, -187, 70, 197, 34, 571, -226, -224, +-252, -789, 190, 37, 321, 782, -220, 264, +-328, -523, 173, -351, 97, 299, -281, 290, +45, -131, 284, -118, -193, 44, -306, 57, +162, 122, 115, -21, -208, -260, 62, 19, +177, 350, -307, 79, -252, -226, 343, -154, +193, 45, -355, 203, -158, 114, 186, -85, +-15, -7, -128, -30, 95, -269, 72, 74, +-215, 579, -179, 97, 126, -595, 201, -311, +-9, 375, -233, 471, -222, -40, 109, -417, +281, -134, -73, 244, -260, 174, 39, -2, +41, -97, -171, -121, 102, 59, 246, 132, +-208, -27, -333, -15, 119, 36, 200, -78, +-42, -10, 12, 147, -41, 33, -329, -150, +-101, -121, 460, 144, 283, 318, -422, -59, +-465, -416, 130, -26, 374, 291, 52, 43, +-145, 77, -91, 131, -141, -356, -134, -320, +140, 333, 324, 350, -9, 0, -407, -75, +-208, -279, 236, -281, 200, 291, -54, 473, +-37, -21, -149, -351, -270, -230, 176, 109, +454, 293, -117, 86, -549, -127, -94, -121, +394, -70, 266, 122, -162, 248, -411, -137, +-145, -350, 348, 220, 309, 443, -245, -287, +-369, -464, 112, 331, 258, 405, -81, -286, +-151, -266, 14, 165, 27, 121, 59, 39, +27, 11, -227, -215, -98, -67, 305, 325, +93, 79, -304, -359, -101, -39, 150, 409, +48, 29, 43, -454, -32, -68, -295, 435, +-11, 150, 466, -282, 51, -209, -582, 101, +-139, 271, 512, 1, 127, -332, -338, 26, +-54, 407, 93, -62, -131, -376, 47, 49, +260, 225, -132, -7, -291, -42, 137, 63, +188, 6, -200, -210, -98, -153, 255, 391, +14, 382, -285, -481, -5, -492, 201, 442, +0, 423, -83, -295, -34, -231, -88, 143, +88, 56, 214, -42, -207, 43, -312, 30, +292, -55, 361, -97, -318, 41, -391, 191, +220, -49, 305, -229, -76, 122, -154, 230, +-20, -211, -78, -222, -26, 212, 246, 246, +124, -56, -275, -250, -211, -160, 156, 184, +169, 300, -24, -64, -41, -318, -45, -34, +-84, 276, -2, 74, 118, -224, 65, -53, +-120, 174, -105, 11, 116, -129, 131, 8, +-163, 162, -198, 40, 205, -262, 257, -128, +-202, 321, -298, 149, 132, -222, 286, 2, +-34, 56, -283, -234, -125, 9, 284, 346, +292, 115, -275, -185, -420, -272, 185, -138, +440, 262, -84, 405, -336, -47, 36, -454, +155, -203, -74, 310, -4, 310, 133, -104, +-77, -253, -114, -47, 121, 138, 12, 82, +-158, -85, 41, -17, 177, 127, 21, -52, +-110, -182, -127, 38, -64, 154, 131, 92, +253, -33, 17, -262, -316, -97, -185, 387, +208, 146, 191, -399, 2, -92, -17, 295, +-158, -3, -147, -135, 188, 62, 185, -14, +-129, -75, -83, 86, 82, 81, -6, -74, +-49, -127, -11, 15, 37, 222, 66, 53, +-25, -284, -73, -62, 40, 284, 61, 13, +-81, -248, -74, -1, 158, 214, 178, 112, +-209, -160, -342, -254, 249, 55, 491, 241, +-201, 50, -528, 4, 83, -35, 461, -281, +54, -125, -245, 284, -106, 325, -13, 62, +77, -402, 215, -488, 17, 302, -277, 677, +-16, -112, 268, -534, -51, -61, -233, 217, +127, 164, 268, 87, -106, -161, -270, -327, +43, 34, 254, 506, 51, 182, -190, -585, +-101, -353, 117, 501, 167, 380, 12, -253, +-189, -237, -139, -24, 155, 36, 252, 196, +-32, 114, -231, -214, -32, -167, 149, 148, +61, 151, -41, -93, -32, -126, 25, 75, +87, 139, 5, -42, -150, -182, -60, -36, +183, 209, 216, 152, -56, -166, -345, -243, +-93, 34, 423, 259, 257, 144, -342, -192, +-330, -278, 186, 70, 413, 278, 79, 45, +-392, -157, -255, -101, 323, -35, 311, 74, +-155, 213, -171, 31, 96, -316, 37, -190, +-85, 289, 64, 358, 134, -139, -41, -495, +-69, -103, 107, 564, 6, 374, -188, -543, +55, -611, 301, 357, 64, 705, -248, -19, +-176, -581, 165, -365, 289, 228, -21, 568, +-274, 183, -23, -481, 275, -433, 122, 172, +-152, 375, -157, 97, 19, -122, 138, -157, +186, -109, 107, 35, -223, 161, -318, 115, +128, -54, 392, -225, 79, -131, -97, 293, +-53, 348, -275, -325, -157, -598, 544, 222, +558, 779, -452, 36, -768, -777, 254, -297, +774, 551, -36, 323, -492, -264, 55, -81, +209, 91, -133, -243, 93, -71, 288, 410, +-203, 82, -321, -373, 241, -50, 377, 217, +-75, -13, -268, -86, -90, 4, 156, -37, +300, 112, 68, 164, -325, -318, -192, -316, +349, 506, 308, 460, -288, -580, -287, -561, +318, 465, 344, 563, -252, -231, -313, -473, +207, -8, 309, 326, -37, 142, -141, -218, +3, -227, 32, 121, 51, 286, 120, -23, +27, -322, -96, -132, -21, 234, 105, 270, +93, -25, -2, -343, -44, -241, -26, 297, +53, 376, 143, -202, 89, -321, -134, 120, +-152, 103, 172, -149, 262, 88, -93, 262, +-221, -152, 150, -383, 278, 77, -160, 359, +-287, -19, 266, -201, 424, 51, -213, -22, +-404, -159, 190, 171, 354, 222, -30, -233, +-140, -229, 10, 201, 57, 217, 61, -125, +47, -261, -22, -36, 44, 269, 118, 247, +-51, -188, -157, -444, 133, -18, 315, 485, +-59, 176, -292, -370, 60, -167, 275, 164, +19, -20, -105, -50, 91, 184, 103, 37, +-126, -209, -100, -83, 251, 70, 257, 85, +-223, 61, -251, -93, 289, -111, 299, 133, +-242, 64, -235, -227, 295, -27, 318, 264, +-167, -9, -254, -236, 87, 11, 255, 127, +124, -8, -104, -60, -177, -48, 106, 57, +290, 103, -56, -138, -222, -124, 152, 217, +208, 42, -122, -284, -11, 89, 230, 276, +-41, -246, -231, -247, 119, 305, 315, 185, +20, -281, -168, -123, -22, 205, 84, 26, +84, -213, 66, 4, 4, 252, 54, 43, +111, -229, -119, -150, -188, 21, 269, 165, +379, 224, -205, -101, -331, -342, 242, 17, +336, 231, -152, -34, -240, -32, 133, 67, +312, -143, 138, -74, -177, 211, -294, 13, +32, -254, 432, -7, 341, 226, -212, 9, +-489, -193, 11, 32, 577, 158, 257, -183, +-358, -204, -218, 291, 206, 230, 205, -289, +53, -172, -27, 154, -116, -27, -20, -31, +262, 245, 179, -10, -220, -439, -140, -87, +307, 502, 163, 213, -250, -475, -7, -313, +303, 315, 62, 257, -117, -146, -58, -135, +-16, -7, 194, 20, 284, 87, -96, -23, +-292, -178, 75, 23, 306, 248, 60, 45, +-144, -275, 10, -223, 173, 143, 80, 347, +-32, 47, -96, -356, -67, -248, 243, 202, +365, 323, -111, 0, -388, -286, 14, -207, +285, 100, 177, 274, 105, 122, -19, -207, +-230, -296, -131, 18, 246, 272, 317, 102, +30, -116, -117, -89, -81, -99, -57, -71, +119, 216, 262, 173, 5, -271, -120, -128, +106, 320, 11, -63, -139, -448, 188, 200, +245, 549, -161, -215, -94, -555, 276, 95, +39, 405, -265, -24, 110, -244, 368, -2, +-63, 113, -248, 2, 174, -44, 198, -60, +-157, -71, -36, 97, 211, 162, 84, -87, +2, -156, -15, 25, -171, -24, 35, -69, +463, 227, 163, 218, -491, -357, -244, -445, +539, 323, 391, 584, -380, -233, -276, -582, +352, 130, 213, 372, -214, -117, 4, -67, +227, 193, -14, -238, -108, -352, 64, 375, +139, 426, 107, -401, -2, -399, -146, 347, +-49, 251, 249, -295, 278, -111, -107, 182, +-348, -32, 19, -59, 452, 144, 183, -34, +-295, -252, -142, -4, 220, 275, 120, 81, +-88, -234, 32, -135, 177, 135, 65, 97, +-119, -56, -142, -35, 65, -61, 361, -96, +254, 134, -317, 204, -414, -170, 256, -267, +511, 138, -15, 198, -273, -142, -49, -97, +66, 150, 161, 17, 242, -146, -94, -8, +-329, 49, 100, -44, 466, 9, 56, 115, +-421, 13, -89, -153, 465, -94, 192, 75, +-418, 64, -129, -5, 542, 64, 225, 31, +-533, -207, -279, -206, 511, 210, 445, 340, +-189, -132, -339, -336, -76, 45, 168, 151, +321, -59, 158, 35, -230, 81, -192, -97, +125, -68, 120, -61, 86, -79, 156, 288, +-104, 245, -243, -445, 193, -340, 333, 388, +-164, 247, -258, -211, 198, -51, 263, 23, +-80, -139, -105, 72, 74, 213, 9, -132, +-29, -226, 124, 149, 126, 209, -19, -136, +-41, -192, -61, 57, -66, 89, 166, -11, +300, 53, -9, 18, -305, -185, -127, -74, +248, 197, 284, 77, -53, -129, -230, -37, +11, 30, 245, 24, 68, 48, -238, -135, +-85, -158, 354, 287, 233, 278, -315, -338, +-276, -353, 259, 207, 306, 292, -73, -27, +-199, -132, 13, -64, 206, -35, 75, 25, +-184, 112, -88, 1, 248, -140, 203, 62, +-161, 135, -217, -203, 89, -114, 238, 304, +58, 25, -75, -368, -63, 44, -43, 354, +111, -54, 217, -299, -34, -39, -256, 146, +31, 74, 308, 30, 51, 29, -224, -170, +-57, -252, 171, 168, 95, 430, -27, -45, +-40, -450, -45, -121, 65, 269, 178, 194, +-32, -40, -224, -168, 83, -116, 313, 73, +-54, 99, -293, -29, 68, 1, 297, 25, +-21, -94, -175, -8, 47, 107, 97, -124, +-19, -122, 9, 286, 57, 171, -19, -349, +-43, -196, 6, 280, 82, 114, 101, -205, +-38, 30, -144, 195, -13, -140, 188, -196, +127, 169, -117, 97, -162, -174, 55, 69, +182, 187, 44, -184, -80, -193, -68, 169, +9, 131, 115, -110, 88, -49, -87, 81, +-126, -17, 97, -94, 192, 60, -47, 101, +-210, -151, 37, -122, 249, 246, 32, 185, +-199, -255, -87, -303, 128, 102, 204, 366, +21, 152, -256, -325, -127, -367, 281, 186, +218, 417, -214, -52, -214, -314, 147, 16, +223, 123, -38, -102, -153, 8, -31, 205, +93, -41, 84, -243, 22, -13, -47, 184, +-71, 73, 2, -82, 62, -97, 53, -20, +19, 59, -9, 124, -57, 11, -38, -243, +51, -69, 73, 328, 11, 62, -26, -343, +-11, 8, 2, 262, -8, -87, 21, -136, +12, 98, 4, -20, 45, -47, 44, 174, +-71, 7, -96, -299, 24, -45, 99, 310, +160, 107, 25, -197, -296, -122, -220, 18, +316, 62, 356, 146, -184, 10, -315, -236, +12, -38, 169, 251, 115, 20, 12, -228, +-131, -11, -119, 167, 128, 18, 154, -87, +-120, -32, -137, -13, 154, 28, 122, 107, +-193, -8, -102, -167, 179, -11, 126, 175, +-106, 15, -119, -162, 15, -24, 95, 121, +69, 24, -10, -79, -95, -26, -128, 19, +116, 37, 271, 91, -158, -68, -371, -237, +218, 102, 430, 353, -229, -134, -412, -375, +172, 122, 325, 266, -63, -82, -184, -87, +12, 35, 6, -63, -38, 6, 128, 95, +119, -78, -145, -27, -147, 190, 50, -63, +57, -315, 70, 100, 85, 359, -84, -52, +-172, -263, -25, -68, 124, 42, 149, 175, +26, 195, -161, -204, -171, -337, 53, 109, +219, 340, 89, 44, -223, -253, -144, -178, +210, 170, 107, 273, -227, -108, -88, -331, +217, 23, 112, 362, -148, 108, -200, -305, +69, -217, 266, 138, -42, 188, -284, 38, +77, -37, 273, -111, -141, -133, -234, 32, +201, 205, 165, 79, -260, -228, -104, -116, +330, 296, 41, 77, -359, -405, -31, -29, +258, 448, 21, 3, -62, -356, 38, 37, +-162, 206, -134, -109, 243, -94, 195, 148, +-186, 18, -183, -83, 82, 116, 76, -40, +-45, -334, 58, 109, 59, 507, -174, -100, +-76, -496, 257, 90, 6, 319, -319, -161, +93, -141, 339, 280, -167, 59, -311, -348, +194, -39, 191, 311, -216, -12, -72, -214, +251, 119, -21, 139, -262, -220, 43, -117, +141, 262, -69, 125, 66, -242, 136, -110, +-270, 202, -251, 53, 320, -163, 309, 1, +-226, 128, -287, 1, 99, -69, 174, -54, +-90, -29, -60, 75, 176, 117, 6, -6, +-298, -128, 5, -105, 298, 53, -19, 115, +-185, 32, 62, 5, 34, -63, -143, -171, +58, 26, 209, 222, -62, 31, -254, -113, +-20, -75, 201, -71, 108, 103, -68, 247, +-190, -97, -143, -343, 210, 41, 321, 317, +-182, 49, -434, -190, 114, -76, 414, 48, +-31, -20, -326, -17, -24, 170, 210, 120, +-17, -293, -118, -277, 122, 364, 50, 381, +-298, -401, -37, -394, 423, 397, 57, 342, +-463, -295, -132, -261, 360, 111, 178, 178, +-189, 64, -148, -119, -7, -140, 7, 98, +95, 123, 157, -88, -99, -63, -268, 68, +43, -11, 238, -40, 12, 78, -151, 14, +-60, -147, 30, 12, 101, 210, 57, -38, +-145, -248, -156, 23, 129, 219, 216, 65, +-75, -90, -230, -158, 1, -93, 128, 165, +0, 223, -14, -64, 42, -213, -64, -38, +-99, 117, 20, 48, 64, -35, 73, 21, +-8, 30, -151, -76, -63, -50, 142, 77, +48, 49, -85, -44, -4, -13, -7, 18, +-54, -72, 72, -31, 79, 184, -125, 102, +-114, -246, 105, -210, 83, 175, -57, 288, +-5, 63, -12, -247, -147, -334, 3, 81, +247, 467, 52, 112, -218, -388, -154, -217, +33, 178, 156, 205, 171, 52, -92, -109, +-299, -194, -43, 17, 243, 232, 116, -4, +-114, -175, -99, 116, -24, 106, -23, -306, +51, -108, 111, 462, -19, 194, -135, -459, +-31, -263, 53, 315, -24, 205, 40, -156, +127, -2, -93, 88, -285, -220, 58, -96, +367, 325, 18, 103, -372, -255, -139, -59, +259, 43, 212, -10, -82, 219, -263, 83, +-125, -420, 223, -139, 257, 490, -166, 159, +-310, -418, 80, -111, 249, 278, -50, 27, +-164, -132, 24, 52, 61, 24, -43, -113, +12, 34, 44, 190, -82, -6, -104, -267, +93, -95, 169, 293, -85, 179, -225, -219, +20, -130, 204, 100, -8, -43, -143, -15, +19, 212, 70, 5, -71, -265, -61, -35, +71, 208, 80, 72, -46, -100, -126, -120, +-36, -15, 131, 168, 98, 141, -115, -168, +-167, -248, 47, 97, 184, 264, 11, -6, +-164, -174, -98, -24, 87, 80, 99, 4, +-20, -71, -87, 7, 1, 139, 49, 36, +-49, -207, -67, -95, 48, 206, 96, 130, +-23, -118, -114, -138, -60, -17, 83, 137, +74, 194, -100, -129, -74, -346, 139, 112, +63, 436, -203, -70, -149, -420, 189, 18, +231, 312, -94, 35, -293, -166, -36, -63, +233, 47, 73, 52, -131, 5, -43, 11, +20, 31, -86, -96, 32, -111, 173, 177, +-56, 189, -238, -228, 33, -232, 230, 257, +-31, 244, -216, -253, -13, -206, 150, 236, +59, 146, -116, -214, -126, -78, 53, 209, +149, 64, -57, -186, -162, -101, 82, 111, +132, 152, -123, 32, -163, -163, 116, -214, +195, 117, -45, 371, -249, -49, -78, -449, +240, -6, 141, 413, -215, 35, -162, -267, +177, -31, 127, 80, -201, -4, -141, 68, +180, 71, 177, -98, -136, -130, -225, 37, +10, 164, 179, 54, 91, -139, -139, -93, +-132, 79, 41, 89, 89, 2, 4, -40, +-22, -57, -66, -13, -99, 70, 83, 52, +169, -11, -67, -43, -202, -86, -7, 2, +133, 170, 8, 33, -57, -200, 40, -2, +16, 185, -134, -97, -59, -142, 136, 207, +40, 62, -43, -246, 28, 77, -75, 204, +-189, -256, 123, -113, 290, 398, -145, 22, +-303, -447, 133, 56, 239, 397, -172, -102, +-173, -284, 166, 104, 77, 155, -128, -71, +-2, -30, 48, 39, -114, -28, -34, -25, +173, 23, 38, 31, -161, 21, -125, -48, +97, -72, 178, 84, -29, 133, -242, -120, +-62, -228, 254, 121, 120, 343, -216, -52, +-214, -420, 136, -51, 238, 430, -78, 128, +-265, -380, 25, -141, 273, 316, -12, 117, +-313, -224, -46, -89, 286, 87, 108, 67, +-212, 93, -140, -27, 30, -249, 72, -15, +93, 311, 51, 37, -119, -240, -208, -11, +19, 97, 200, -47, 102, 31, -102, 131, +-127, -54, -91, -175, -44, -13, 182, 140, +266, 93, -124, -11, -429, -77, -60, -140, +359, -57, 170, 214, -129, 229, -153, -180, +-111, -338, -6, 84, 210, 335, 117, -7, +-241, -251, -103, -8, 207, 174, -5, -6, +-257, -148, 92, 18, 264, 203, -136, 16, +-246, -295, 125, -87, 182, 352, -159, 136, +-145, -287, 145, -73, 88, 144, -114, -101, +-38, -12, 44, 287, -72, -11, -27, -307, +136, -40, 15, 131, -139, 55, -30, 114, +85, 27, -46, -238, -42, -119, 94, 194, +15, 136, -146, -57, -47, -50, 161, -27, +38, -32, -184, 26, -90, 58, 188, 46, +127, -9, -204, -124, -157, -78, 182, 169, +118, 177, -186, -147, -69, -242, 175, 52, +-3, 248, -149, 82, -8, -171, 81, -162, +-3, 77, -10, 159, 2, -38, -56, -109, +-4, 59, 33, 71, -22, -81, -16, -39, +63, 65, -45, -23, -127, -22, 90, 107, +156, 22, -127, -163, -205, -76, 97, 145, +205, 159, -47, -53, -161, -217, -40, -41, +51, 245, 25, 102, 78, -251, 42, -121, +-176, 237, -138, 112, 174, -214, 190, -84, +-156, 169, -168, 48, 81, -114, 103, -7, +-21, 66, -44, -33, -62, -46, -43, 61, +142, 71, 105, -72, -216, -121, -160, 58, +242, 152, 178, -26, -263, -143, -150, -25, +237, 96, 85, 77, -215, -37, -50, -97, +185, -7, -7, 62, -131, 21, 16, 29, +49, 3, -70, -129, 33, -45, 134, 182, +-111, 79, -186, -152, 88, -70, 168, 44, +-46, 16, -58, 84, 34, 67, -107, -184, +-96, -153, 169, 219, 173, 199, -129, -186, +-198, -168, 38, 133, 96, 82, 5, -115, +-10, 9, 23, 154, -47, -43, -73, -190, +27, 30, 76, 166, -2, -10, -98, -95, +0, 1, 111, 18, 22, 26, -138, 43, +-105, -93, 102, -96, 190, 162, -11, 148, +-275, -176, -119, -140, 288, 172, 184, 87, +-281, -176, -238, -32, 287, 202, 235, 49, +-307, -193, -256, -99, 283, 153, 263, 140, +-252, -114, -244, -131, 151, 117, 198, 106, +-55, -102, -124, -63, -58, 17, -3, -29, +151, 127, 124, 183, -205, -221, -234, -327, +201, 197, 278, 372, -187, -85, -259, -281, +114, -13, 191, 134, -57, 76, -104, 6, +2, -92, -29, -110, 25, 74, 125, 188, +0, -3, -207, -217, -59, -82, 209, 202, +93, 140, -162, -171, -104, -136, 105, 167, +50, 93, -71, -168, 28, -45, 55, 118, +-108, -6, -71, -3, 158, 79, 66, -129, +-148, -143, -44, 214, 74, 138, -4, -248, +0, -63, 92, 270, -76, -16, -162, -289, +85, 44, 159, 280, -78, 0, -104, -195, +108, -39, -18, 66, -181, 4, 105, 50, +270, 108, -116, -86, -335, -224, 44, 49, +292, 254, 76, 12, -143, -174, -162, -47, +-59, 21, 134, 56, 230, 131, -55, -69, +-263, -223, -16, 117, 181, 228, 2, -197, +-74, -157, 100, 261, -5, 44, -172, -283, +25, 60, 166, 250, -50, -108, -106, -175, +113, 85, 56, 71, -162, -36, -60, 14, +163, 24, 75, -46, -124, -82, -38, 17, +84, 166, -5, 15, -94, -236, 34, 2, +120, 266, -27, -88, -106, -265, 3, 194, +72, 238, -26, -265, -19, -181, 86, 264, +-4, 83, -139, -207, -13, 28, 170, 121, +35, -117, -151, -26, -59, 151, 109, -65, +73, -128, -71, 132, -54, 83, 27, -172, +30, -54, 10, 177, 5, 55, -37, -147, +-55, -62, 66, 88, 67, 47, -68, -12, +-55, 23, 66, -53, 26, -139, -77, 75, +17, 244, 76, -41, -29, -275, -66, -11, +27, 214, 31, 25, -38, -108, 54, 4, +68, 24, -100, -60, -123, -5, 92, 85, +165, 34, -23, -72, -127, -64, -70, 45, +46, 54, 93, -35, 54, 1, -53, 63, +-104, -75, 20, -109, 92, 115, -4, 121, +-73, -102, 43, -95, 77, 56, -69, 43, +-89, -3, 36, -18, 101, -36, 16, 42, +-73, 70, -45, -86, 28, -83, 26, 102, +-18, 48, 44, -69, 59, 48, -83, 25, +-155, -173, 55, -8, 250, 272, 27, 37, +-260, -292, -117, -93, 210, 228, 147, 135, +-126, -134, -90, -143, 74, 65, 17, 115, +-98, -39, 49, -72, 156, 37, -60, 19, +-190, -37, 25, 42, 190, 44, 12, -84, +-136, -66, -49, 79, 85, 86, 93, -27, +-47, -90, -103, -51, 19, 89, 110, 128, +-24, -91, -107, -204, 54, 87, 132, 274, +-41, -56, -170, -326, 3, -25, 181, 301, +71, 104, -133, -199, -127, -98, 48, 106, +101, 19, 39, -68, -9, 55, -57, 74, +-100, -65, 33, -58, 170, 33, -7, -9, +-158, 4, 5, 80, 110, -29, -47, -102, +-58, 72, 96, 106, 21, -104, -99, -97, +-25, 81, 65, 56, 42, 4, 10, 41, +-32, -74, -90, -150, 23, 57, 125, 184, +-5, 31, -126, -100, -15, -80, 101, -10, +38, 67, -27, 54, -86, -33, -66, -41, +136, 17, 202, 35, -129, -3, -332, -69, +75, -45, 392, 90, 28, 83, -341, -77, +-89, -48, 225, 53, 80, -64, -85, -69, +-25, 154, 10, 89, -26, -157, 27, -47, +51, 102, -53, -57, -26, -82, 77, 123, +20, 117, -93, -61, -22, -156, 83, -115, +38, 137, -14, 282, -33, -81, -44, -363, +2, 27, 74, 345, 41, 8, -49, -271, +-45, -28, -14, 175, 23, 34, 60, -87, +36, -2, -73, 43, -88, -69, 75, -56, +131, 126, -33, 87, -153, -161, -6, -110, +156, 153, 88, 93, -106, -117, -165, -82, +33, 42, 194, 99, 60, 63, -146, -141, +-102, -170, 72, 176, 75, 218, 1, -190, +-3, -176, -17, 189, -52, 53, 29, -189, +92, 77, -55, 166, -94, -169, 89, -122, +109, 210, -96, 70, -110, -205, 51, -36, +86, 167, 29, 46, -30, -108, -62, -87, +-33, 48, 41, 113, 74, -4, 3, -83, +-49, -16, -35, 6, 23, -6, 42, 80, +8, 37, -18, -128, -23, -66, 27, 89, +40, 62, -23, 13, -89, -20, 22, -124, +170, -31, 16, 166, -221, 32, -59, -134, +224, 47, 47, 80, -160, -143, 23, -15, +84, 181, -117, -48, -48, -143, 193, 129, +58, 96, -183, -192, -76, -102, 128, 161, +108, 138, -46, -58, -109, -156, -29, -56, +118, 143, 80, 121, -119, -113, -112, -125, +102, 91, 131, 116, -51, -66, -99, -110, +-12, 23, 47, 85, 69, 8, 10, -38, +-85, 1, -26, -6, 95, -21, 9, 8, +-102, -28, 44, -5, 134, 167, -70, 51, +-170, -325, 80, -149, 180, 386, -51, 221, +-130, -306, 33, -209, 57, 132, -29, 92, +36, 41, 38, 61, -81, -155, -57, -162, +84, 186, 84, 184, -30, -145, -94, -131, +-54, 48, 87, 39, 150, 62, -43, 50, +-195, -139, -6, -99, 184, 157, 29, 94, +-118, -129, 4, -62, 55, 95, -39, 42, +-29, -61, 56, -68, 34, 21, -12, 115, +-21, 35, -54, -117, -37, -84, 91, 61, +133, 100, -59, 19, -191, -95, -6, -67, +181, 102, 56, 69, -105, -132, -42, -37, +11, 178, -22, 9, 53, -179, 99, 11, +-63, 114, -141, -32, 60, -3, 123, 71, +-56, -106, -81, -95, 69, 184, 40, 104, +-85, -214, -12, -102, 91, 215, 9, 103, +-74, -187, -8, -112, 61, 127, 12, 114, +-37, -53, -13, -75, -2, -8, 12, 14, +54, 53, 7, 37, -91, -92, -43, -40, +113, 121, 84, 12, -75, -155, -86, 8, +13, 145, 66, -6, 55, -81, -23, -7, +-87, -16, -1, 11, 103, 80, 7, -7, +-93, -88, -1, 11, 90, 47, 6, -15, +-77, 3, -33, 6, 49, -30, 84, 20, +4, 48, -111, -45, -66, -52, 100, 30, +129, 29, -33, 32, -153, 15, -55, -103, +143, -61, 123, 143, -103, 74, -126, -134, +78, -46, 81, 78, -73, -8, 1, -6, +85, 55, -72, -42, -100, -65, 139, 44, +119, 30, -165, -14, -120, 18, 162, -12, +105, -38, -130, 10, -54, 22, 91, 26, +-20, 20, -66, -66, 108, -41, 80, 91, +-181, 18, -97, -101, 213, 55, 114, 93, +-190, -128, -103, -67, 136, 157, 65, 17, +-42, -128, 4, 45, -34, 48, -63, -121, +105, 32, 111, 172, -135, -86, -119, -177, +150, 85, 111, 137, -141, -52, -85, -73, +132, 2, 71, 8, -89, 11, -52, 36, +42, 28, 25, -50, 1, -101, 11, 43, +-34, 182, -35, -3, 65, -198, 46, -59, +-92, 88, -18, 101, 141, 108, -6, -90, +-178, -289, 14, 28, 194, 342, -2, 25, +-141, -256, 7, -27, 75, 96, -18, -27, +-11, 15, 49, 49, 0, -47, -42, 20, +-36, 51, -10, -163, 75, -73, 112, 278, +-53, 109, -197, -295, -8, -133, 231, 203, +83, 118, -188, -72, -109, -71, 124, -44, +79, 17, -63, 108, 2, 32, 41, -119, +-74, -94, -31, 90, 140, 136, 28, -34, +-169, -139, -33, 2, 169, 86, 61, -6, +-119, -2, -99, 32, 30, -68, 131, -42, +82, 106, -104, 4, -153, -131, 44, 44, +159, 153, 37, -60, -94, -162, -92, 26, +34, 138, 120, 36, 3, -104, -139, -93, +7, 89, 173, 138, -18, -84, -195, -174, +-5, 60, 187, 168, 63, 7, -99, -97, +-109, -93, -30, -24, 110, 146, 150, 130, +-46, -151, -196, -161, -18, 118, 170, 121, +56, -74, -97, -69, -42, 8, 54, 32, +9, 76, -22, -8, 15, -147, 19, -44, +-7, 146, -10, 106, -20, -62, 6, -132, +90, -39, 12, 77, -161, 59, -36, -1, +252, 18, 80, -32, -294, -141, -114, 2, +275, 210, 125, 51, -214, -191, -82, -64, +161, 121, 36, 17, -134, -49, -24, 41, +144, -10, 69, -70, -122, 62, -134, 62, +67, -118, 187, -49, 13, 155, -172, 45, +-79, -148, 141, -42, 108, 110, -107, 6, +-84, -85, 112, 54, 69, 75, -142, -116, +-38, -69, 167, 162, 12, 26, -160, -189, +25, 57, 136, 207, -65, -134, -88, -194, +93, 160, 47, 129, -98, -150, -5, -27, +104, 139, -12, -56, -94, -134, -18, 75, +71, 106, 82, -44, -2, -22, -117, 24, +-98, -77, 92, -63, 175, 121, 21, 130, +-173, -81, -145, -160, 87, 4, 222, 124, +57, 32, -214, -71, -161, -14, 139, 55, +210, -16, -47, -74, -207, 19, 3, 78, +181, 0, 35, -72, -137, -15, -46, 62, +89, 2, 55, -66, -17, 14, -56, 62, +-28, -24, 34, -8, 47, 37, -22, -73, +-17, -67, 34, 136, -27, 103, -57, -124, +35, -110, 88, 34, 6, 76, -64, 76, +-67, -22, -16, -156, 114, -19, 107, 189, +-91, 22, -149, -179, 44, -3, 131, 122, +-3, -37, -53, -53, 10, 88, 12, 1, +-62, -128, -24, -13, 113, 121, 99, 67, +-100, -62, -162, -118, 59, -27, 155, 105, +-17, 85, -88, -16, 17, -69, 10, -90, +-53, 7, 53, 156, 80, 35, -64, -171, +-76, -26, 66, 150, 65, -20, -56, -118, +-39, 35, 42, 53, 27, -7, -12, 35, +-3, -19, -20, -127, -25, 13, 40, 173, +55, 7, -30, -157, -64, -13, 21, 118, +37, 2, -37, -78, 13, 5, 71, 52, +-46, 8, -97, -16, 69, -31, 94, -57, +-67, 23, -53, 146, 64, 17, 7, -219, +-53, -76, 33, 254, 27, 114, -52, -236, +5, -108, 55, 175, -30, 78, -40, -96, +44, -38, 11, 18, -45, 12, 18, 45, +36, 16, -42, -57, -36, -46, 58, 29, +45, 78, -59, 15, -53, -103, 43, -31, +57, 120, -30, 11, -35, -120, 11, 37, +0, 111, 3, -78, 39, -84, 5, 75, +-57, 37, 0, -42, 57, 5, 2, -19, +-46, -37, -2, 89, 37, 55, 9, -125, +-36, -53, -43, 113, 41, 31, 85, -45, +-33, 24, -120, -29, -1, -75, 116, 61, +33, 112, -65, -36, -50, -102, -15, -16, +42, 66, 84, 67, -4, -43, -121, -88, +-42, 46, 115, 97, 79, -52, -67, -92, +-82, 24, 11, 49, 60, 18, 40, 25, +-3, -41, -71, -92, -65, 22, 80, 103, +139, 10, -63, -58, -186, -20, 30, -10, +191, -13, 21, 62, -157, 82, -72, -80, +57, -149, 131, 69, 73, 205, -147, -56, +-189, -234, 113, 34, 246, 202, -46, -9, +-192, -102, -28, -2, 71, -54, 63, -11, +62, 200, -67, 26, -136, -277, 67, -4, +151, 253, -74, -72, -130, -170, 87, 166, +99, 67, -78, -221, -58, 22, 68, 203, +6, -88, -62, -156, 42, 120, 74, 106, +-49, -99, -90, -59, 27, 42, 64, 1, +11, -5, -10, 63, -9, 11, -35, -92, +-1, -64, 53, 49, -1, 79, -29, 35, +12, -12, 8, -93, -42, -88, 8, 94, +43, 148, -20, -66, -19, -119, 33, 65, +4, 25, -52, -97, 2, 73, 38, 128, +8, -142, -5, -127, 1, 169, -24, 106, +-20, -151, 19, -86, 8, 87, 20, 77, +23, 17, -43, -60, -65, -101, 39, 28, +65, 123, -29, 15, -37, -67, 26, -19, +5, 8, -50, -7, -10, 1, 61, 37, +65, 46, -60, -47, -119, -109, 42, 46, +156, 132, -34, -56, -169, -113, 33, 76, +156, 83, -17, -63, -132, -51, -13, -1, +75, 8, 55, 83, -5, 43, -72, -123, +-47, -69, 43, 106, 70, 33, -7, -62, +-51, 45, -24, 43, 26, -92, 14, -52, +-5, 62, 22, 57, -4, 20, -55, -47, +0, -103, 97, 36, 15, 137, -96, -63, +-55, -157, 69, 103, 89, 199, -7, -113, +-110, -239, -54, 57, 112, 228, 70, 16, +-95, -149, -42, -41, 74, 45, -15, -4, +-48, 37, 65, 77, 12, -90, -96, -133, +37, 117, 136, 145, -68, -143, -164, -135, +50, 140, 164, 110, -3, -99, -106, -60, +-45, 39, 20, -10, 57, 5, 45, 56, +-22, -21, -72, -45, 1, 20, 50, -13, +14, -31, -19, 52, -18, 37, -5, -51, +34, -11, 51, 16, -48, -59, -108, -9, +22, 110, 177, 43, 49, -104, -197, -81, +-136, 34, 143, 73, 183, 48, -62, 9, +-164, -71, -32, -113, 110, 42, 91, 182, +-58, -2, -122, -196, 31, 7, 126, 170, +-42, -51, -105, -113, 55, 113, 53, 50, +-86, -155, 20, 20, 109, 166, -71, -69, +-139, -130, 78, 65, 151, 43, -43, -21, +-133, 79, -11, -27, 97, -189, 34, 42, +-47, 216, -27, -31, 5, -146, -5, 26, +14, 39, 25, -43, -30, 38, -19, 69, +19, -47, -3, -77, -17, 20, 30, 64, +-3, 3, -41, -51, 30, -28, 35, 22, +-37, 48, -22, 30, 31, -81, -19, -123, +10, 94, 58, 216, -46, -85, -107, -257, +45, 65, 125, 210, -23, -50, -99, -98, +-23, 48, 19, -18, 21, -35, 68, 105, +7, 0, -121, -159, -51, 36, 115, 171, +62, -55, -96, -147, -48, 61, 66, 103, +16, -59, -69, -68, -8, 66, 52, 69, +3, -76, -34, -97, -1, 74, 7, 125, +-36, -61, -16, -127, 36, 44, 45, 115, +-23, -5, -83, -93, -51, -57, 75, 59, +109, 120, -47, -17, -132, -151, 4, -39, +105, 111, -20, 79, -78, -21, 29, -86, +70, -75, -35, 70, -93, 114, -22, -54, +85, -107, 87, 55, -86, 78, -129, -57, +38, -38, 106, 30, -26, 0, -64, 12, +12, 40, -7, -48, -16, -75, 24, 58, +10, 75, -50, -46, -24, -47, 37, 24, +31, 4, -38, -12, -70, 31, 8, 0, +64, -47, -6, 18, -67, 57, -4, -40, +22, -68, -21, 51, -15, 76, 18, -49, +-11, -67, -33, 40, -9, 46, 3, -32, +4, -23, -6, 14, -24, 16, -21, 21, +8, -22, -8, -63, -31, 41, -3, 114, +18, -55, -29, -127, -52, 56, 27, 105, +46, -51, -37, -51, -78, 33, 12, -36, +58, -12, -10, 119, -52, -13, -30, -184, +-5, 29, 14, 201, 29, -36, -43, -158, +-80, 42, 8, 92, 69, -45, -12, -39, +-82, 38, -38, 31, 26, -1, 31, -46, +-13, -58, -50, 54, -33, 111, 14, -36, +5, -131, -39, 1, 2, 109, 31, 27, +-48, -73, -89, -29, 39, 30, 85, -1, +-59, 2, -110, 54, 18, -15, 60, -104, +-30, 15, -64, 133, -35, 2, 27, -111, +45, -6, -34, 39, -115, -5, -27, 51, +82, 41, 42, -118, -51, -81, -85, 134, +-46, 82, 29, -117, 61, -63, -9, 97, +-77, 46, -55, -85, -7, -45, 12, 68, +16, 54, -1, -35, -35, -46, -62, -11, +-45, -4, 33, 42, 58, 66, -43, -55, +-101, -107, -11, 52, 56, 94, -21, -47, +-77, -34, -24, 59, 28, -28, 10, -73, +-32, 70, -68, 74, -46, -85, 27, -63, +51, 74, -13, 42, -91, -42, -80, -19, +4, -1, 71, -20, 24, 37, -62, 68, +-102, -38, -55, -116, 43, 3, 75, 134, +-12, 35, -109, -99, -91, -36, 5, 29, +76, -20, 41, 32, -87, 104, -144, -56, +2, -168, 133, 45, -3, 164, -181, -22, +-61, -98, 141, 10, 31, 13, -176, -10, +-90, 61, 103, 8, 68, -97, -96, 9, +-117, 105, -13, -33, 73, -99, 20, 57, +-103, 91, -89, -74, 42, -80, 40, 82, +-66, 82, -75, -72, 4, -99, 20, 44, +-20, 104, -39, -8, -57, -89, -33, -33, +21, 52, 20, 63, -59, 4, -81, -71, +-9, -56, 30, 59, -27, 86, -59, -30, +-7, -82, 0, 5, -63, 51, -51, 0, +36, -21, 18, 23, -81, 15, -88, -43, +10, -46, 60, 44, -21, 75, -111, -23, +-61, -76, 55, -7, 39, 41, -86, 21, +-87, 6, 12, -29, 36, -44, -46, 42, +-62, 50, -12, -72, 0, -36, -40, 108, +-42, 9, -12, -132, -1, 16, -23, 128, +-58, -30, -56, -91, 7, 33, 28, 31, +-61, -19, -92, 52, 15, 17, 46, -125, +-84, -37, -93, 152, 46, 62, 55, -127, +-83, -68, -113, 69, -19, 13, 55, -21, +28, 88, -73, 31, -148, -174, -31, -75, +126, 210, 20, 127, -184, -179, -89, -134, +108, 113, 27, 94, -130, -44, -61, -27, +47, -10, -9, -32, -62, 46, -36, 63, +-22, -75, -26, -74, 2, 98, -26, 84, +-79, -102, -36, -102, 41, 91, -11, 119, +-101, -60, -55, -118, 47, 28, 17, 84, +-90, -5, -82, -28, 12, -1, 22, -28, +-34, 7, -50, 76, -57, -9, -42, -98, +17, 11, 17, 93, -58, -8, -61, -44, +-37, 3, -39, -39, 11, -14, 69, 121, +-74, 53, -189, -164, -11, -95, 149, 153, +-3, 114, -157, -97, -68, -103, 34, 29, +4, 60, -27, 18, -27, -19, -55, -43, +-53, -7, -11, 61, 10, 17, -16, -80, +-50, -23, -69, 99, -21, 37, 19, -104, +-9, -57, -60, 94, -52, 80, -31, -66, +-13, -92, 25, 19, -10, 94, -122, 29, +-91, -72, 85, -57, 83, 44, -125, 57, +-151, -32, 45, -40, 91, 28, -64, 18, +-115, -39, -8, -3, 31, 43, -24, 2, +-73, -38, -41, -21, 5, 29, 15, 56, +-41, -7, -86, -97, -30, -37, 41, 117, +-8, 83, -87, -88, -44, -103, 15, 29, +-30, 81, -44, 26, 11, -25, -17, -55, +-90, -31, -37, 48, 61, 57, -5, -28, +-102, -63, -59, 17, 31, 50, 6, -15, +-47, -31, -45, 27, -40, 17, -29, -53, +26, -7, -1, 83, -100, 11, -72, -88, +57, -17, 28, 67, -96, 13, -55, -31, +25, 12, -29, -1, -60, -46, 21, -1, +6, 69, -83, 28, -62, -61, 16, -54, +6, 28, -15, 60, -25, 3, -66, -48, +-76, -16, 21, 31, 71, 22, -41, -22, +-121, -42, -40, 19, 49, 74, 4, 2, +-57, -110, -38, -39, -23, 119, -16, 77, +3, -77, -33, -92, -73, -4, -18, 72, +63, 83, -15, -6, -119, -128, -67, -69, +62, 116, 48, 127, -65, -63, -94, -143, +-21, 21, 18, 129, -12, -6, -25, -102, +-3, 23, -29, 74, -80, -60, -18, -56, +63, 99, -7, 39, -113, -122, -34, -36, +67, 121, -10, 30, -102, -86, -27, -29, +55, 26, -4, 13, -74, 32, -49, 25, +-3, -63, 4, -52, -9, 59, -18, 62, +-30, -46, -37, -50, -34, 38, -12, 31, +18, -38, 9, -11, -49, 41, -81, -3, +-28, -30, 54, 6, 40, 6, -67, -6, +-90, 23, -14, 1, 35, -54, 7, 10, +-24, 79, -61, -17, -47, -84, 19, 29, +32, 67, -53, -42, -57, -37, 27, 55, +9, -1, -60, -67, -27, 30, 21, 70, +-27, -47, -28, -69, 30, 44, -25, 55, +-84, -43, 6, -42, 66, 32, -33, 21, +-75, -29, 4, -8, 3, 30, -42, 15, +-9, -26, 34, -40, -36, 10, -54, 69, +-6, 23, -1, -85, -23, -62, 10, 75, +15, 91, -71, -27, -75, -81, 32, -33, +79, 29, -16, 73, -96, 49, -63, -75, +26, -113, 65, 43, 2, 140, -90, 15, +-77, -114, 40, -60, 80, 56, -27, 73, +-104, 2, -49, -60, 65, -31, 50, 51, +-40, 24, -88, -52, -27, -12, 56, 60, +36, 8, -46, -59, -72, -9, -1, 44, +26, 8, -2, -17, -17, 4, -9, 5, +-37, -24, -29, -23, 40, 31, 36, 55, +-62, -18, -77, -82, 17, -10, 59, 87, +5, 44, -37, -58, -66, -72, -31, -12, +58, 71, 77, 86, -58, -30, -122, -140, +4, -28, 76, 153, 11, 79, -38, -131, +-22, -93, -36, 92, -9, 75, 39, -65, +16, -55, -48, 51, -26, 41, 19, -29, +-4, -37, -22, -16, 3, 22, -3, 60, +-11, 14, -6, -67, -16, -45, -38, 36, +11, 52, 54, 21, -8, -30, -73, -71, +-31, -17, 52, 93, 26, 56, -23, -82, +-36, -71, -15, 47, 8, 55, 28, -13, +1, -26, -51, -14, -5, -20, 58, 12, +-2, 50, -89, 11, -21, -59, 89, -46, +31, 42, -62, 68, -55, -13, -6, -65, +24, -16, 62, 41, 23, 26, -102, -13, +-81, -13, 67, -9, 115, -16, -40, 9, +-99, 41, -14, 11, 59, -56, 26, -38, +-34, 54, -26, 55, 12, -46, 30, -64, +-21, 29, -40, 66, -3, -1, 44, -61, +21, -28, -35, 36, -29, 46, -8, -3, +22, -50, 24, -23, 0, 27, -22, 24, +-25, 0, 7, -6, 5, -14, 12, -20, +5, 4, 6, 30, -26, 21, -28, -16, +-4, -37, 26, -19, 45, 49, -8, 71, +-71, -32, -64, -111, 65, -8, 107, 132, +-26, 68, -112, -122, -21, -117, 71, 69, +39, 131, -16, -4, -24, -104, -37, -41, +-5, 46, 63, 46, 38, 5, -79, -28, +-60, -29, 71, 8, 79, 38, -58, 9, +-94, -39, 22, -22, 89, 36, 22, 56, +-80, -14, -57, -86, 42, -21, 76, 100, +-11, 59, -68, -88, 3, -86, 47, 60, +-18, 86, -28, -27, 36, -63, 34, -6, +-50, 26, -31, 23, 32, 15, 25, -20, +-16, -41, -1, 6, 4, 46, -30, 10, +-3, -23, 28, -6, 9, 9, -31, -9, +14, -8, 16, 19, -41, 29, -27, -1, +63, -42, 52, -38, -65, 29, -62, 74, +31, 13, 52, -79, 5, -51, -21, 54, +-22, 58, -35, -12, 28, -20, 59, 3, +-12, -31, -76, -30, 0, 59, 69, 87, +-3, -27, -39, -124, -13, -37, 16, 112, +6, 97, 34, -49, -15, -106, -63, -33, +5, 56, 88, 86, 24, 15, -86, -104, +-45, -75, 57, 91, 63, 109, -26, -74, +-54, -113, 2, 61, 35, 94, 14, -58, +-18, -67, -8, 60, 5, 38, 6, -63, +2, -23, -5, 52, -7, 26, 0, -29, +27, -25, -5, -7, -32, 18, -12, 34, +39, -5, 29, -46, -18, -4, -39, 44, +0, -16, 42, -38, 14, 31, -25, 35, +-22, -34, 18, -18, 24, 27, -13, -21, +-27, -33, 13, 69, 35, 60, 4, -97, +-45, -91, -21, 83, 36, 100, 48, -42, +-11, -79, -50, 4, -26, 29, 40, 14, +48, 23, -14, -15, -54, -51, -4, -7, +60, 57, 6, 23, -45, -53, 0, -32, +43, 34, 0, 25, -34, -23, 12, -21, +31, 9, -15, 15, -18, -2, 18, -12, +4, 2, -37, 21, 8, 16, 32, -18, +-1, -28, -38, 17, -5, 30, 33, -15, +17, -15, -5, 19, -42, -2, -20, -29, +49, 18, 66, 45, -54, -24, -91, -57, +36, 24, 100, 57, -5, -11, -89, -34, +-12, -1, 43, 4, 27, 2, 8, 40, +-20, 9, -45, -71, -13, -22, 78, 84, +41, 34, -63, -86, -63, -41, 40, 72, +73, 42, 1, -50, -49, -46, -45, 11, +26, 50, 62, 39, 20, -42, -67, -84, +-39, 17, 51, 100, 47, 8, -20, -83, +-33, -26, 3, 31, 12, 9, 21, 20, +20, 18, -24, -67, -34, -68, 19, 83, +41, 109, -6, -74, -28, -126, -6, 39, +13, 104, 31, -15, 11, -53, -34, 8, +-35, -1, 41, -15, 44, 45, -28, 34, +-48, -47, 18, -27, 39, 37, -6, 10, +-16, -11, 2, 33, -6, 1, -5, -62, +23, 8, 22, 72, -21, -7, -20, -66, +16, 2, 15, 28, 5, -3, -2, 23, +-11, 5, -24, -79, 26, -31, 41, 107, +-17, 39, -52, -126, 15, -57, 56, 107, +-2, 45, -52, -83, -16, -30, 46, 50, +40, -4, -23, -32, -63, 33, 4, 22, +82, -47, 23, -24, -74, 47, -37, 35, +59, -16, 48, -23, -28, -4, -34, 19, +-8, 41, 23, 22, 24, -30, 8, -39, +-25, 18, -17, 68, 16, 18, 25, -63, +6, -42, -9, 49, -17, 62, -13, -24, +27, -65, 31, -15, -13, 41, -34, 32, +6, -31, 28, -67, 7, -10, 0, 52, +5, -4, -11, -59, -19, 1, 19, 23, +33, -37, -7, -18, -22, 54, -10, -9, +21, -82, 28, 13, 11, 82, -31, -19, +-19, -54, 25, 51, 16, 44, -19, -50, +-10, 1, 23, 89, -10, 20, -23, -58, +16, 4, 31, 54, -18, 18, -20, 3, +23, 10, 11, -21, -20, -15, 11, 45, +32, 28, -20, -48, -37, -34, 31, 34, +51, 18, -17, -34, -45, -36, 8, -19, +41, -6, 21, 29, -13, 11, -27, -89, +-14, -80, 29, 58, 55, 84, -11, -49, +-59, -105, -10, -4, 59, 51, 33, 10, +-23, 1, -34, 17, -1, -33, 21, -49, +20, 56, -2, 109, -13, -2, -3, -86, +10, -7, 4, 83, 1, 54, 21, -2, +3, -4, -26, -9, -5, -5, 35, 48, +16, 47, -20, -26, -7, -38, 16, 24, +-6, 24, -9, -24, 27, -14, 18, 11, +-40, -16, -20, -38, 54, -15, 40, -11, +-41, -28, -35, -16, 30, -3, 34, -23, +-5, -36, -19, -6, -11, -4, 8, -25, +36, -3, 16, 22, -30, -16, -28, -45, +32, 13, 37, 56, 5, 14, -20, -16, +-20, 5, -7, 9, 39, 19, 46, 76, +-32, 56, -66, -53, 19, -52, 81, 76, +10, 105, -63, 0, -20, -61, 37, -16, +35, 37, 11, 46, -21, 9, -34, -54, +9, -39, 59, 34, 13, 21, -50, -57, +-23, -47, 45, 16, 27, -3, -10, -55, +-12, -41, 10, -17, 7, -12, 1, 1, +5, -18, 9, -58, 15, -24, -3, 40, +-17, 2, 4, -48, 35, 11, 12, 51, +-30, -13, -23, -28, 20, 50, 31, 65, +11, -6, -8, -30, -24, 29, -9, 58, +39, 37, 38, 8, -16, 3, -50, 20, +-10, 24, 48, 4, 55, 14, -10, 30, +-62, -12, -24, -38, 58, 8, 58, 28, +-25, -23, -50, -38, -1, -10, 35, -20, +27, -30, 10, -3, -22, -30, -28, -69, +16, -6, 59, 41, 6, -44, -47, -99, +-15, -1, 39, 64, 29, 0, -6, -47, +-23, -22, -20, 0, 24, 19, 57, 48, +5, 24, -68, -27, -20, -10, 70, 40, +44, 46, -46, 42, -48, 38, 14, -11, +45, -41, 30, 41, -11, 106, -44, 14, +-7, -79, 56, -14, 36, 75, -48, 32, +-33, -45, 36, -35, 38, 9, -16, 18, +-11, -19, 10, -59, 0, -41, 11, 35, +20, 26, -1, -93, -26, -98, 17, 49, +35, 80, -12, -71, -34, -124, 20, 18, +47, 98, -6, 0, -44, -94, -5, -49, +51, 66, 36, 106, -38, 0, -56, -113, +23, -29, 81, 144, 10, 107, -65, -74, +-27, -74, 45, 63, 37, 75, -1, 21, +-9, 34, -27, -4, -13, -78, 42, 12, +56, 132, -21, 21, -55, -109, 3, -26, +53, 47, 20, -12, -17, -4, 0, 28, +-3, -57, -13, -95, 28, 30, 49, 68, +-10, -58, -52, -82, 2, 11, 56, 19, +28, -31, -17, -18, -32, 1, -2, -16, +39, 6, 40, 18, -10, -33, -35, -17, +5, 56, 49, 23, 19, -49, -15, 9, +-16, 89, 3, 5, 25, -70, 31, 35, +-2, 100, -38, -2, -1, -63, 62, 22, +19, 62, -47, -11, -6, -20, 58, 25, +17, 6, -43, -32, 8, -8, 48, 14, +7, 1, -26, -1, 12, -21, 19, -57, +1, -16, 12, 72, 18, 16, -8, -115, +-4, -68, 29, 87, 14, 61, -13, -77, +11, -68, 34, 28, -2, 35, -19, 0, +30, -13, 35, -24, -8, 4, -11, 64, +18, 11, 17, -80, 13, 3, 29, 124, +-2, 16, -27, -118, 13, -1, 66, 123, +16, 24, -48, -75, -17, -7, 52, 48, +49, 13, -10, -5, -27, -16, 6, -36, +51, 6, 40, 58, -16, -10, -36, -97, +22, -28, 74, 82, 31, 40, -52, -77, +-37, -81, 53, 20, 83, 63, -3, 18, +-65, -39, -7, -53, 69, -15, 51, 39, +-14, 57, -27, -6, 11, -66, 28, -19, +28, 58, 20, 51, -5, -11, -9, -39, +16, -11, 33, 44, 13, 65, 6, -9, +5, -76, 6, -3, 23, 96, 36, 32, +14, -95, -14, -36, 4, 82, 36, 33, +22, -62, 13, -23, 13, 37, -7, -11, +-6, -32, 47, 25, 59, 15, -19, -47, +-46, -26, 38, 26, 79, 7, 12, -17, +-31, -2, 1, -10, 26, -16, 35, 21, +41, 29, -4, -23, -36, -29, 22, 32, +77, 35, 16, -23, -40, -16, 13, 35, +58, 27, 20, -23, -2, -18, 17, 22, +14, 31, 15, 16, 46, -17, 21, -41, +-34, 3, 12, 79, 80, 35, 29, -97, +-37, -77, 6, 91, 56, 93, 21, -67, +1, -99, 33, 20, 13, 61, -13, 7, +35, -26, 59, -40, -2, -35, -16, 36, +38, 60, 39, -36, -5, -74, 19, 21, +46, 58, 9, -22, -9, -30, 41, 21, +50, 5, -8, -20, -5, 22, 42, 31, +45, -21, 3, -15, -3, 36, 22, 15, +43, -21, 36, 6, 7, 29, -18, 6, +21, -13, 70, 1, 36, 10, -25, 9, +-3, 4, 60, -14, 50, -19, 6, 12, +0, 24, 20, -20, 30, -45, 51, 6, +35, 53, -17, -9, -12, -83, 67, -21, +76, 79, -3, 29, -34, -77, 26, -50, +65, 35, 43, 35, 19, -3, -2, -14, +-5, -40, 43, -26, 83, 58, 21, 55, +-43, -52, 3, -48, 76, 53, 48, 33, +-6, -30, 10, 11, 35, 34, 14, -35, +24, -18, 52, 69, 34, 14, -9, -73, +6, -2, 56, 72, 57, 4, 12, -45, +-11, -6, 19, 8, 55, 10, 49, 38, +5, -9, -10, -78, 26, -4, 63, 92, +38, 7, -1, -96, 7, -24, 50, 60, +43, 13, 11, -39, 14, -14, 45, 3, +37, 0, 2, 12, 8, 1, 47, -27, +56, -3, 18, 30, 2, -5, 15, -35, +50, 1, 55, 42, 23, 12, -12, -34, +13, -19, 61, 24, 60, 30, 2, 10, +-9, -11, 30, -26, 56, -11, 41, 46, +14, 56, -1, -34, 19, -78, 64, 20, +58, 84, -9, 3, -19, -64, 64, -15, +79, 25, 4, 10, -20, 12, 46, 1, +59, -49, 18, -22, 10, 64, 39, 28, +24, -68, 20, -38, 47, 46, 27, 28, +-2, -30, 41, -16, 71, 1, 4, -10, +-21, 10, 52, 30, 76, -9, 3, -36, +-8, 4, 39, 30, 46, 3, 25, -4, +41, 5, 24, -23, -10, -21, 30, 49, +89, 56, 30, -45, -39, -76, 20, 32, +86, 88, 38, 5, -4, -68, 26, -22, +33, 31, 27, 29, 41, 16, 45, -21, +8, -43, 12, 13, 46, 49, 42, -19, +22, -49, 41, 32, 28, 35, 2, -61, +27, -31, 75, 70, 39, 15, -16, -70, +4, 1, 56, 47, 62, -28, 28, -27, +2, 42, -5, 1, 40, -49, 82, 15, +41, 38, -32, -34, 8, -26, 70, 44, +56, 2, 12, -41, 20, 12, 23, 23, +10, -22, 44, 4, 74, 35, 22, -31, +-21, -41, 21, 43, 72, 39, 48, -29, +12, -17, 4, 20, 14, -8, 43, 5, +57, 43, 28, -2, -16, -42, 17, 7, +62, 28, 49, -12, 10, 4, 13, 33, +27, -27, 32, -60, 43, 19, 38, 72, +10, 14, 3, -55, 36, -59, 52, 4, +34, 77, 10, 48, 9, -71, 27, -89, +48, 35, 44, 79, 20, -6, 0, -52, +30, -27, 44, 11, 29, 39, 16, 27, +24, -41, 23, -49, 27, 38, 39, 62, +32, -27, 8, -52, 19, 13, 44, 42, +32, 10, 16, -4, 23, -11, 37, -24, +18, 15, 20, 52, 40, 10, 33, -41, +7, -19, 23, 23, 44, 24, 33, 1, +14, -10, 31, -17, 40, -9, 9, 13, +7, 16, 49, 0, 60, -12, 0, -14, +-15, -18, 41, 4, 71, 29, 25, 5, +-10, -36, 17, -34, 39, 14, 39, 21, +49, -8, 29, -18, -15, -14, -1, -11, +75, 8, 79, 23, -14, -3, -41, -32, +49, -9, 87, 30, 22, 13, -16, -13, +13, -2, 35, 9, 35, -2, 46, 6, +21, 19, -14, 0, 12, -9, 65, 11, +43, 5, -6, -7, 8, 19, 38, 19, +32, -38, 21, -28, 35, 44, 16, 43, +2, -38, 22, -39, 47, 12, 24, 23, +7, 3, 32, -13, 28, -29, 0, -19, +20, 25, 59, 27, 23, -14, -20, -43, +11, -17, 56, 20, 51, 29, 9, 5, +-6, -51, 4, -41, 41, 42, 68, 65, +24, -20, -35, -71, -7, -8, 77, 58, +69, 42, -13, -20, -36, -46, 26, -8, +69, 51, 42, 47, -6, -22, -22, -46, +19, 7, 65, 47, 45, 19, -18, -20, +-15, -25, 42, 5, 52, 23, 12, 7, +-2, -16, 22, -11, 18, 16, 12, 2, +38, -26, 32, -8, -4, 20, -4, 5, +41, -25, 39, -18, 6, 5, 7, 4, +29, -5, 13, 2, 4, 0, 38, -21, +43, -13, -5, 22, -18, 19, 33, -15, +57, -14, 13, 17, -21, 4, 10, -9, +40, 20, 33, 25, 6, -23, 16, -30, +18, 32, 12, 35, 22, -23, 39, -22, +16, 23, -6, 16, 12, -5, 31, -4, +26, -12, 14, -4, 27, 27, 8, 13, +-11, -44, 18, -31, 71, 30, 33, 31, +-40, -15, -28, -30, 50, -25, 77, -5, +17, 49, -41, 32, -30, -66, 35, -63, +84, 49, 36, 70, -55, -32, -42, -59, +54, 6, 90, 26, 14, 9, -49, 4, +-17, -18, 49, -24, 59, 28, 22, 34, +-20, -33, -18, -38, 28, 43, 55, 47, +25, -28, -19, -42, -7, 16, 25, 43, +31, 14, 11, -21, 5, -24, 8, 17, +4, 37, 7, -6, 22, -36, 32, 8, +10, 32, -11, -16, 4, -38, 36, 7, +30, 26, 1, -6, -10, -15, 10, -12, +28, -12, 18, 9, 13, 20, 4, -14, +1, -29, 11, 4, 37, 13, 21, -12, +-20, 3, -13, 22, 40, -8, 42, -22, +-14, 13, -25, 20, 23, -6, 49, 1, +3, 17, -16, -14, 9, -18, 26, 30, +8, 30, 16, -20, 20, -21, -7, 11, +-15, 7, 31, 11, 50, 20, -5, -22, +-36, -43, 10, 25, 51, 59, 12, -19, +-6, -66, 9, 0, 12, 37, -5, 2, +27, -11, 42, -9, -7, -35, -36, -10, +18, 58, 57, 21, 11, -71, -24, -38, +0, 50, 26, 32, 11, -22, 17, -14, +10, -4, -8, -19, -6, 22, 23, 57, +22, -14, 0, -61, 0, 4, 14, 48, +7, 11, 5, -15, 24, -5, 17, -16, +-10, 3, -13, 42, 25, 8, 30, -43, +9, -11, -9, 36, -6, 7, 10, -23, +28, 2, 26, 6, -6, -15, -21, 2, +1, 14, 39, -11, 28, -10, -8, 12, +-27, -9, 8, -22, 36, 22, 26, 26, +-10, -36, -14, -42, 14, 27, 20, 45, +11, -8, 0, -31, 4, -12, -8, 14, +5, 25, 33, 14, 20, -12, -25, -26, +-16, -4, 33, 26, 31, 34, -16, 12, +-19, -30, 25, -40, 17, 18, -7, 59, +6, 25, 23, -33, -12, -50, -13, -15, +34, 55, 36, 74, -26, -28, -31, -108, +35, -17, 41, 112, -13, 48, -16, -88, +22, -67, 18, 34, -5, 58, 6, 6, +27, -41, -1, -48, -9, 7, 15, 61, +22, 16, 5, -70, 6, -37, 10, 52, +-3, 36, 0, -26, 23, -22, 28, 5, +-11, 3, -20, 10, 10, 13, 39, -12, +19, -10, -8, 21, -24, 5, 7, -37, +42, 12, 23, 63, -20, -4, -23, -71, +26, -12, 31, 57, 9, 23, -6, -20, +1, -16, -4, -21, 11, -11, 30, 40, +19, 35, -16, -44, -9, -57, 18, 28, +16, 44, 10, -15, 2, -16, 4, 11, +-13, -10, 5, -25, 28, 25, 25, 35, +-11, -24, -21, -35, 2, 14, 30, 23, +35, -6, -2, 1, -32, 3, -8, -21, +46, -2, 35, 39, -19, 16, -34, -34, +18, -15, 32, 36, 2, 31, -9, -9, +13, -30, 0, -7, -13, 32, 23, 40, +32, -10, -9, -60, -26, -14, 21, 66, +28, 46, -6, -45, -10, -57, 23, 14, +9, 50, -17, 17, 8, -25, 30, -27, +-5, 6, -27, 33, 18, 13, 34, -27, +-5, -18, -27, 32, 20, 25, 29, -28, +-5, -27, -19, 33, 9, 37, 22, -20, +10, -30, -2, 20, -15, 32, -2, -8, +23, -10, 29, 18, -9, 10, -30, -12, +0, 1, 38, 21, 29, 6, -16, 0, +-41, 9, -5, 0, 48, -4, 32, 25, +-34, 25, -49, -18, 23, -20, 52, 31, +2, 26, -35, -30, -3, -13, 23, 39, +11, 18, -10, -30, -3, -11, 4, 37, +3, 27, 2, -11, -9, -18, -3, 0, +16, 24, 15, 36, -23, 0, -22, -36, +11, 2, 40, 46, 4, 24, -32, -25, +-23, -11, 10, 31, 33, 22, 9, 8, +-36, 8, -35, -2, 19, -2, 46, 24, +-3, 29, -49, -11, -9, -12, 29, 32, +11, 18, -19, -20, -9, 16, 0, 49, +-10, -10, 2, -48, 14, 30, -10, 72, +-33, 2, -8, -36, 14, 10, 5, 25, +-16, 11, -14, 31, -11, 21, -9, -33, +4, -19, 11, 59, -19, 56, -40, -22, +-8, -30, 30, 21, 7, 36, -40, 15, +-30, 9, 9, 1, 18, -4, -15, 23, +-37, 42, -17, 7, 12, -17, 6, 12, +-24, 34, -29, 20, -9, 7, 5, 6, +-9, 6, -17, 15, -21, 30, -17, 18, +-8, 0, -3, 13, -20, 24, -33, 9, +-13, 10, 6, 35, -16, 24, -38, -22, +-11, -13, 5, 53, -19, 54, -42, -11, +-14, -31, 9, 18, -13, 44, -45, 26, +-35, 17, 0, 6, 2, -7, -27, 7, +-46, 46, -29, 39, -4, 0, -4, -1, +-33, 20, -48, 13, -22, 12, 3, 50, +-14, 36, -42, -32, -41, -31, -13, 55, +-5, 81, -23, 7, -43, -44, -42, -4, +-15, 53, -3, 63, -33, 22, -60, -33, +-34, -17, 0, 61, -19, 77, -54, -10, +-45, -44, -20, 31, -19, 73, -35, 23, +-36, -20, -33, 1, -43, 34, -30, 38, +-15, 25, -34, 2, -60, -6, -37, 26, +-16, 52, -33, 18, -56, -7, -42, 22, +-28, 41, -44, 13, -46, 2, -30, 35, +-38, 42, -55, 2, -46, -2, -31, 30, +-40, 43, -54, 27, -54, 21, -45, 7, +-37, 4, -40, 33, -52, 52, -56, 18, +-38, -12, -36, 17, -61, 40, -60, 23, +-36, 25, -36, 37, -67, 9, -66, -14, +-40, 35, -36, 71, -59, 23, -68, -21, +-58, 12, -56, 55, -44, 34, -41, 13, +-66, 19, -85, 14, -54, 10, -25, 41, +-47, 51, -95, 12, -82, -14, -36, 25, +-35, 60, -72, 32, -84, -2, -69, 16, +-54, 35, -52, 31, -67, 31, -78, 28, +-76, 13, -60, 14, -58, 38, -70, 45, +-79, 23, -68, 4, -60, 12, -69, 37, +-75, 48, -70, 26, -66, -5, -72, 11, +-78, 57, -79, 49, -69, 0, -68, 8, +-76, 48, -88, 32, -81, 7, -63, 38, +-68, 54, -86, -5, -86, -13, -69, 56, +-73, 69, -86, 4, -79, -8, -70, 36, +-89, 33, -95, 18, -71, 52, -61, 46, +-97, -19, -109, -12, -77, 78, -64, 83, +-87, -9, -99, -27, -89, 46, -84, 61, +-82, 16, -83, 18, -88, 42, -105, 24, +-95, 2, -72, 31, -80, 61, -111, 39, +-108, 4, -79, 9, -72, 33, -97, 49, +-117, 42, -96, 18, -72, 7, -76, 19, +-115, 47, -119, 47, -79, 23, -66, 6, +-100, 11, -127, 47, -99, 58, -72, 24, +-91, -7, -112, 19, -109, 66, -96, 44, +-85, -1, -88, 11, -110, 48, -123, 32, +-94, 19, -67, 42, -95, 35, -140, -9, +-112, 6, -61, 75, -79, 65, -134, -12, +-130, -20, -78, 44, -72, 66, -113, 36, +-131, 19, -106, 12, -86, 3, -88, 34, +-111, 79, -127, 46, -112, -25, -82, -4, +-82, 64, -122, 63, -134, 12, -96, 8, +-78, 38, -104, 26, -123, 19, -113, 40, +-95, 40, -97, 16, -107, 24, -119, 39, +-111, 19, -96, 21, -101, 58, -124, 48, +-118, -7, -85, -1, -94, 58, -128, 58, +-123, 12, -87, 9, -92, 31, -131, 40, +-126, 35, -88, 31, -89, 13, -115, 10, +-122, 44, -108, 52, -103, 18, -98, 2, +-104, 34, -124, 48, -121, 31, -89, 16, +-82, 15, -125, 25, -139, 47, -94, 43, +-70, 7, -110, 0, -139, 40, -110, 54, +-77, 17, -93, 10, -129, 36, -127, 30, +-93, 9, -73, 35, -111, 57, -137, 6, +-114, -7, -77, 48, -84, 58, -132, 10, +-135, 8, -93, 48, -70, 28, -106, 0, +-135, 39, -124, 67, -90, 9, -69, -25, +-98, 43, -146, 75, -128, 10, -66, -11, +-59, 36, -130, 49, -159, 16, -90, 19, +-48, 38, -96, 17, -148, 8, -117, 41, +-75, 49, -79, 6, -105, -6, -119, 39, +-113, 53, -85, 16, -78, 2, -104, 24, +-128, 42, -100, 26, -68, 14, -93, 23, +-125, 33, -109, 24, -75, 14, -83, 25, +-111, 40, -117, 26, -99, 11, -80, 22, +-88, 43, -112, 28, -116, 8, -85, 22, +-73, 37, -100, 19, -119, 14, -92, 37, +-73, 32, -93, -1, -110, 10, -97, 56, +-87, 42, -92, -8, -94, 7, -92, 49, +-99, 31, -97, 2, -80, 33, -87, 50, +-107, -3, -94, -19, -73, 55, -85, 73, +-106, 0, -97, -26, -74, 27, -84, 57, +-104, 33, -91, 18, -78, 14, -85, -4, +-96, 16, -92, 66, -80, 48, -78, -19, +-92, -16, -96, 43, -81, 55, -68, 19, +-81, 1, -102, 10, -97, 27, -72, 39, +-68, 34, -90, 7, -97, 1, -83, 27, +-72, 38, -70, 18, -79, 11, -94, 16, +-91, 18, -67, 23, -52, 27, -88, 18, +-111, 3, -74, 21, -46, 39, -73, 16, +-107, 2, -82, 23, -54, 30, -66, 6, +-88, 12, -83, 37, -75, 25, -73, -1, +-65, 14, -71, 36, -89, 18, -83, 8, +-58, 33, -61, 25, -87, -6, -93, 15, +-63, 50, -51, 29, -72, -12, -86, -3, +-76, 33, -58, 36, -58, 22, -72, 10, +-81, -3, -71, 6, -58, 39, -64, 46, +-75, 4, -69, -18, -61, 12, -67, 44, +-69, 27, -55, -1, -61, 3, -76, 16, +-70, 22, -49, 21, -57, 18, -80, 7, +-65, 4, -51, 27, -62, 28, -74, 5, +-60, 2, -52, 25, -61, 23, -64, 2, +-57, 5, -54, 22, -62, 20, -61, 8, +-56, 11, -56, 15, -62, 16, -58, 14, +-51, 11, -56, 10, -65, 16, -61, 22, +-55, 17, -50, 6, -57, 13, -64, 19, +-57, 15, -44, 13, -47, 14, -64, 6, +-61, 8, -50, 32, -51, 28, -60, -6, +-51, -9, -46, 32, -57, 34, -57, -6, +-39, -8, -42, 25, -62, 18, -55, -4, +-34, 14, -45, 30, -64, -2, -49, -9, +-34, 27, -50, 32, -69, -1, -46, -4, +-23, 23, -49, 20, -71, -5, -44, 7, +-23, 32, -41, 8, -65, -15, -54, 10, +-33, 41, -36, 18, -47, -18, -53, -2, +-47, 32, -38, 27, -37, -1, -40, -8, +-41, 9, -46, 20, -47, 12, -38, 10, +-33, 15, -47, 9, -58, -1, -39, 13, +-20, 28, -38, 12, -62, -11, -42, 0, +-16, 25, -36, 21, -57, -1, -42, 5, +-26, 15, -35, 1, -46, 7, -38, 30, +-30, 14, -38, -23, -39, -6, -29, 43, +-32, 35, -46, -21, -40, -25, -24, 27, +-25, 42, -37, 0, -42, -19, -30, 0, +-26, 20, -29, 18, -31, 13, -36, 4, +-32, -17, -26, -2, -25, 38, -30, 34, +-40, -13, -40, -24, -22, 19, -12, 39, +-31, 8, -55, -12, -32, 1, 3, 14, +-11, 7, -50, 1, -43, 4, -6, 8, +-10, 10, -40, 8, -44, 7, -16, 3, +-13, 6, -24, 7, -25, 9, -24, 3, +-31, -2, -27, 8, -6, 20, -18, 15, +-43, -10, -42, -1, -5, 24, 2, 23, +-33, -8, -47, -15, -15, 12, 11, 22, +-17, 9, -49, -4, -32, 1, 2, 11, +-2, 16, -31, 9, -32, -7, -10, -6, +-7, 14, -20, 23, -18, 1, -13, -10, +-20, 2, -20, 15, -11, 14, -9, 9, +-25, 4, -28, -2, -7, -1, 1, 16, +-18, 17, -20, -8, -7, -9, -9, 15, +-16, 15, -15, 0, -8, 5, -16, 19, +-20, 6, -8, -10, 3, 3, -13, 24, +-24, 9, -10, -6, 3, 5, -6, 11, +-24, 4, -17, 6, 4, 18, 1, 11, +-18, -13, -20, -6, -6, 29, 0, 31, +-4, -10, -11, -21, -10, 12, -10, 34, +-5, 8, 5, -11, 2, 0, -17, 11, +-20, 6, 10, 10, 20, 17, -15, 0, +-34, -17, 3, 9, 29, 41, -2, 12, +-30, -33, -6, -12, 19, 41, 9, 27, +-15, -15, -7, -18, 11, 12, 4, 16, +-1, 2, 3, 11, 7, 10, -7, -12, +-6, -10, 12, 31, 14, 37, -4, -15, +-9, -34, 5, 16, 20, 40, 8, 6, +-8, -16, -2, 3, 12, 13, 13, 0, +4, 10, 7, 19, 10, -4, 0, -19, +4, 7, 20, 33, 17, 7, -2, -21, +-7, 0, 17, 22, 26, 9, 5, -4, +-7, 6, 8, 13, 21, -2, 16, -6, +8, 13, 3, 25, 3, 2, 16, -19, +25, 3, 12, 29, -7, 17, 3, -11, +27, -6, 27, 12, 4, 13, -4, 7, +19, 4, 30, 0, 14, -4, 0, 11, +8, 25, 26, 3, 19, -16, 8, 1, +9, 29, 20, 14, 19, -15, 15, -10, +19, 17, 19, 19, 10, 0, 9, -5, +27, 1, 34, 5, 11, 9, 3, 6, +21, 0, 37, -5, 19, 10, -3, 20, +16, -1, 36, -10, 22, 9, 8, 17, +15, 5, 22, -3, 20, 4, 15, 14, +21, 12, 20, 4, 18, -8, 21, -3, +33, 9, 24, 21, 9, 4, 20, -19, +29, -2, 32, 18, 18, 20, 10, -3, +26, -17, 34, 2, 27, 15, 16, 10, +14, 2, 25, -2, 31, 0, 28, 3, +17, 12, 12, 11, 24, -2, 36, -7, +30, 3, 11, 16, 12, 8, 30, -3, +35, 1, 20, 12, 14, 6, 21, -1, +33, 0, 32, 10, 19, 5, 21, -5, +23, 8, 28, 8, 31, -4, 29, -3, +24, 13, 17, 11, 25, -9, 37, -4, +36, 12, 19, 7, 12, -5, 30, 1, +42, 15, 25, 3, 15, -16, 26, 1, +38, 20, 33, 6, 15, -11, 19, -2, +34, 12, 31, 9, 24, -3, 26, 1, +31, 0, 28, -5, 25, 0, 33, 12, +30, 9, 27, -12, 20, -10, 31, 6, +39, 17, 29, 4, 16, -11, 25, -7, +38, 12, 31, 14, 21, 0, 23, -5, +39, -6, 33, 2, 28, 6, 25, 10, +31, -6, 32, -12, 29, 5, 27, 19, +29, 0, 38, -22, 32, -7, 26, 14, +30, 10, 36, -10, 35, -13, 22, 4, +25, 8, 37, 0, 36, 0, 22, 0, +21, -7, 36, -5, 39, 13, 28, 5, +23, -14, 30, -7, 38, 10, 32, 5, +25, -7, 28, -1, 39, 0, 33, -3, +27, -4, 29, 4, 36, 1, 35, -3, +23, 0, 29, -1, 38, 3, 36, -2, +24, -3, 24, 3, 43, 0, 38, -6, +20, -4, 20, 9, 41, 5, 41, -7, +24, -9, 22, 2, 37, 6, 45, -3, +30, -9, 22, -8, 34, 3, 44, 5, +28, -2, 17, -7, 34, 0, 46, 3, +31, -3, 22, -9, 34, -2, 43, 0, +33, 2, 16, 3, 31, -10, 49, -7, +38, 8, 16, 3, 25, -13, 44, 0, +41, 10, 22, -2, 24, -13, 46, -5, +46, 1, 29, -2, 22, 0, 35, -3, +43, -7, 31, -1, 26, 4, 34, 1, +41, -6, 32, -8, 29, -7, 40, 5, +36, 10, 25, -9, 24, -13, 43, 1, +48, 6, 26, -3, 15, -3, 35, -4, +55, -10, 39, -4, 16, 7, 25, -1, +52, -13, 43, -3, 18, 2, 23, 1, +47, -2, 47, -8, 28, -11, 23, 2, +41, 3, 49, -9, 36, -8, 26, -1, +35, -5, 46, -8, 40, 2, 25, 1, +38, -15, 44, -2, 30, 6, 25, -3, +40, -6, 49, -2, 30, -4, 20, -3, +39, 0, 57, -7, 35, -4, 14, 3, +32, -2, 55, -8, 41, 3, 18, 1, +28, -10, 49, -5, 49, -1, 28, -7, +30, -9, 45, 2, 45, -6, 35, -16, +33, -3, 45, 3, 44, -6, 29, -7, +28, -2, 44, -4, 53, -4, 31, 3, +19, -7, 43, -11, 55, 4, 33, 5, +21, -8, 41, -7, 55, -5, 37, -7, +25, 1, 40, 2, 50, -10, 39, -11, +26, 6, 33, 2, 47, -8, 42, -3, +35, -5, 35, -10, 43, -2, 42, 2, +36, -9, 38, -9, 45, 1, 37, -1, +26, -5, 35, 0, 49, -2, 46, -10, +26, -3, 27, -3, 51, -8, 55, -2, +28, 0, 19, -9, 46, -7, 58, 4, +36, -7, 23, -10, 36, 4, 53, -4, +44, -14, 29, 1, 31, 6, 47, -14, +45, -8, 34, 5, 32, -1, 40, -9, +46, -5, 38, -5, 35, -6, 44, 0, +40, -1, 32, -14, 40, -4, 44, 8, +41, -8, 28, -6, 32, 4, 50, -7, +45, -10, 24, 7, 30, 1, 52, -17, +50, -9, 31, 4, 25, 0, 43, -7, +48, -4, 34, -3, 31, -4, 37, 3, +39, -4, 39, -7, 34, 6, 35, -2, +42, -14, 40, -1, 39, -1, 39, -10, +41, -5, 46, -5, 35, -9, 37, -7, +44, 8, 39, -2, 29, -14, 38, -2, +47, 7, 40, -7, 31, -9, 36, -2, +47, -4, 40, 0, 32, 1, 39, -15, +44, -10, 41, 7, 36, 4, 38, -15, +41, -9, 40, 0, 40, -4, 36, -1, +41, -3, 38, -10, 39, -10, 40, 4, +42, -1, 44, -12, 32, -1, 32, -2, +43, -5, 49, -1, 35, -2, 26, -12, +44, -7, 52, 5, 39, -8, 28, -12, +39, 1, 50, -3, 41, -10, 30, 0, +34, 2, 44, -11, 45, -8, 39, 2, +36, -7, 39, -9, 42, 0, 41, -3, +39, -10, 41, -2, 37, 1, 38, -11, +42, -6, 42, 2, 39, -5, 32, -2, +33, 1, 46, -10, 45, -6, 33, 5, +35, -6, 48, -14, 46, -3, 34, 1, +32, -6, 48, -5, 42, 0, 32, -11, +33, 0, 42, 8, 44, -9, 31, -11, +32, 5, 42, 4, 39, -7, 34, -3, +32, 3, 39, -6, 39, 2, 36, 6, +36, -10, 41, -14, 43, 3, 40, 2, +39, -12, 39, -4, 44, -5, 41, -7, +29, 6, 38, 4, 45, -8, 39, -9, +31, 3, 36, 3, 44, -3, 43, -2, +33, -5, 36, -9, 44, 1, 42, 3, +38, -7, 38, -5, 39, -2, 40, -8, +44, -4, 43, 4, 37, -7, 38, -16, +41, 2, 41, 5, 43, -11, 40, -7, +37, -2, 36, -5, 45, -5, 47, 3, +32, -5, 29, -9, 37, 6, 53, 0, +40, -6, 24, -2, 32, 2, 51, -6, +49, -3, 34, -2, 32, -6, 37, -1, +50, -2, 43, -4, 35, -6, 36, 2, +42, -3, 44, -9, 41, -2, 40, 0, +35, 0, 37, -1, 43, -4, 43, -6, +40, -1, 35, 5, 39, -9, 48, -12, +45, 4, 33, 5, 29, -7, 47, -7, +51, 1, 39, -8, 34, -6, 39, 6, +49, -11, 44, -13, 32, 11, 39, 4, +43, -14, 42, -12, 41, 5, 43, 2, +42, -6, 34, -3, 37, -5, 43, 0, +43, 7, 37, 1, 29, -8, 40, -6, +50, 5, 49, -1, 38, -11, 37, -13, +49, -4, 54, 4, 44, -6, 36, -18, +39, -3, 45, 11, 48, -3, 42, -12, +34, -2, 37, 0, 49, -3, 48, 3, +42, -8, 33, -15, 39, 0, 51, 12, +48, -6, 33, -15, 30, 4, 41, 11, +52, -9, 49, -12, 34, 0, 32, -1, +41, 2, 54, 1, 46, -9, 31, -12, +32, 7, 46, 12, 53, -11, 41, -18, +36, -2, 43, 9, 50, -4, 45, -13, +40, -6, 40, 6, 43, -1, 48, -13, +44, -5, 42, 0, 44, -5, 40, 1, +40, 3, 45, -12, 49, -11, 43, 11, +41, 2, 40, -21, 43, -5, 45, 20, +41, 2, 35, -19, 39, -4, 50, 8, +50, -5, 45, -11, 39, -2, 40, -6, +43, -1, 46, 12, 45, -1, 36, -20, +37, -7, 51, 15, 54, 4, 38, -18, +27, -7, 41, 11, 57, 4, 48, -10, +37, -11, 36, 1, 44, 1, 50, 2, +45, 1, 38, -9, 38, -13, 48, 6, +50, 12, 46, -15, 34, -17, 45, 6, +50, 11, 48, -18, 39, -10, 35, 17, +40, 4, 44, -13, 42, 4, 40, 8, +38, -8, 43, -5, 47, 9, 43, -5, +37, -13, 41, 9, 42, 15, 43, -17, +44, -18, 46, 10, 47, 9, 39, -13, +41, -12, 45, 10, 49, 1, 44, -12, +40, -4, 41, 4, 47, -7, 52, -6, +40, 11, 33, -2, 38, -15, 50, 4, +50, 21, 35, -7, 30, -22, 42, 9, +57, 17, 49, -12, 32, -16, 34, 8, +50, 3, 57, -13, 44, 2, 29, 10, +33, -10, 52, -11, 56, 15, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_22050_2ch_16b.c b/USDK/example_sources/i2s/src/birds_22050_2ch_16b.c new file mode 100644 index 0000000..ec5e9b5 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_22050_2ch_16b.c @@ -0,0 +1,16075 @@ +#include +int sample_size=64274; + +SECTION(".sdram.data") +short sample[]={ +-1, 1, 0, 0, -1, 2, 0, -1, +1, 1, -4, 4, -1, 0, 2, -1, +-1, 1, 1, -2, 1, 1, -3, 1, +1, -2, 2, -1, -2, 2, -4, 3, +1, -1, 0, -1, 0, -1, 5, -4, +1, -3, 2, -2, 1, 0, 2, -5, +2, -1, 0, 2, -3, 1, -1, 0, +3, -1, -2, 1, -2, 1, 4, -2, +-5, 3, -1, 0, 1, 1, -2, -1, +0, 1, 2, -1, 3, -4, 1, 0, +1, 2, -3, 0, 4, -3, 4, -1, +-2, 0, 2, -2, 3, 0, -1, -2, +3, -1, -1, 3, -2, -1, 3, -2, +4, -2, -1, -1, 2, -1, 1, 1, +-1, -2, 1, 1, 0, 0, -2, 0, +-2, 4, 0, 0, 1, -3, 0, 2, +0, 0, -1, 0, 0, 1, 3, -3, +0, -3, 5, -2, 1, 0, 0, -2, +3, 0, -2, 3, -5, 2, 1, 1, +0, 0, 1, -2, -1, 3, -2, 2, +-1, -1, 5, -4, 2, 0, -2, 0, +2, 0, -2, 3, -4, 2, 3, -2, +3, -3, -1, 0, -1, 2, 1, -3, +1, -1, -2, 3, -2, 1, 0, -1, +3, -2, -1, 1, -3, 2, -2, 3, +-4, 2, 0, 0, 1, 0, 0, 0, +-2, 2, -1, 2, -2, 2, -1, 0, +1, 1, -1, 1, 0, 0, 0, 1, +-1, -1, 3, -3, 2, 0, 0, -1, +2, -1, 1, -1, 0, 0, 2, -2, +3, -2, -1, 0, 1, -1, -1, 1, +-2, 1, 1, -1, 1, -1, -3, 2, +-2, 2, -3, 2, -1, 1, -2, 3, +-2, 1, 1, -2, 1, 0, -4, 4, +-5, 4, -1, 1, 1, -1, 0, 0, +1, -1, 0, 0, -1, 1, 1, 0, +1, -2, 1, 0, -2, 3, 0, -1, +-1, 2, -1, 1, 2, -2, 0, 1, +0, 0, 4, -4, 0, 1, 0, -1, +-1, 1, -3, 2, 2, -1, -3, 3, +-2, 2, -1, 2, -5, 4, -3, 2, +1, -1, -1, 0, 2, -3, 2, -1, +-2, 2, -3, 2, -1, 1, -3, 2, +-1, 1, -1, 2, -2, 1, 2, -2, +1, 0, -3, 3, -1, 0, 3, -2, +0, 0, 2, -3, 4, -3, 0, 0, +1, 0, 2, -1, -1, 1, -1, 2, +1, -1, -3, 3, 0, -1, 1, -1, +-1, 0, 2, -1, 0, 0, -2, 3, +-3, 4, -3, 2, -1, 0, -1, 2, +-5, 5, -4, 3, -3, 4, -3, 2, +-3, 3, -5, 5, -3, 1, -2, 2, +-4, 4, -1, -1, 4, -4, 3, -3, +2, -3, 1, -1, 2, -2, 1, 0, +-1, 1, 0, 1, 0, -1, 1, 0, +-3, 5, -4, 3, -1, 0, 2, -2, +3, -3, 1, 1, -2, 2, 1, -2, +2, -1, 0, 1, 0, 0, 0, 0, +0, 0, -1, 1, 1, -1, 2, -1, +-1, 1, -2, 2, 1, -1, 0, 1, +-4, 3, 0, 0, -1, 0, 2, -2, +0, 0, -1, -1, 3, -3, 2, -2, +1, -2, -1, 1, 0, -1, 4, -5, +5, -4, 1, 0, 1, -1, -1, 1, +-2, 2, -3, 4, -4, 3, 3, -2, +0, 1, 1, -1, 2, -1, 1, -1, +1, 0, -1, 2, -2, 2, -1, 1, +0, 1, -1, 2, -2, 1, 1, -2, +1, 0, -1, 2, -3, 3, 0, -1, +1, 0, -2, 2, 1, -2, 2, -2, +-1, 1, 0, 0, 0, 0, -1, 1, +-3, 2, -2, 1, -2, 2, -2, 0, +1, -2, 1, -2, 0, 2, -6, 5, +-2, 0, 3, -4, 5, -5, 2, -2, +3, -2, -1, 3, -4, 4, 0, 0, +3, -3, 2, 0, -2, 2, 3, -3, +3, -3, 1, 0, -1, 1, 1, -1, +1, 0, 0, 0, 1, 0, 1, -1, +0, 2, -2, 1, 1, -1, 1, -1, +2, -2, 1, -1, 1, -1, -3, 3, +-3, 1, 2, -2, 2, -3, 2, -2, +0, 0, 1, -1, -1, 2, -3, 2, +1, -2, 0, 1, -1, 0, 1, -2, +1, 0, 0, 0, -1, 1, -2, 2, +1, -2, 2, -2, 2, -1, 2, -2, +1, 0, 0, 0, 3, -2, 2, -2, +3, -2, 2, -1, 1, -1, 4, -4, +5, -4, 4, -4, 2, 0, -2, 3, +-2, 1, 2, -3, 3, -2, 0, 0, +0, 0, 2, -2, -2, 2, -1, 0, +0, 1, -4, 3, 0, 0, 0, 0, +-1, 0, -2, 2, -4, 2, 0, -1, +-1, 2, -2, 1, 1, -2, 3, -3, +4, -4, 2, -1, 0, 0, 0, 1, +-3, 3, 1, -1, 0, 1, -1, 1, +0, 2, -3, 4, -1, 0, 3, -2, +3, -3, 4, -2, 0, 0, 3, -3, +1, 0, 2, -2, 3, -2, -2, 2, +-2, 2, -1, 1, 0, 0, -2, 3, +-3, 3, -1, 0, 2, -2, 0, 0, +-2, 2, -2, 1, 1, -3, 3, -2, +-1, 0, 1, -2, 0, 1, 0, 0, +-2, 2, -3, 3, 0, 0, 0, -1, +-1, 2, -1, 1, 0, 0, 0, 0, +2, -1, -3, 3, 0, 0, 0, 1, +-3, 3, -1, 2, 0, 0, 1, -1, +1, 0, 0, 0, 0, 0, 2, -1, +3, -2, -1, 1, 3, -2, -1, 2, +-2, 1, 1, 0, -1, 1, -4, 4, +-2, 0, 4, -5, -2, 3, -2, 1, +2, -3, 1, -2, 1, 0, -2, 1, +0, -1, -1, 2, -4, 3, -1, 0, +-1, 2, -3, 2, -1, 0, 0, 1, +0, -2, 3, -3, 3, -2, 2, -1, +-1, 2, 0, 0, -1, 1, 0, 0, +-1, 3, -3, 2, 1, -1, 3, -2, +0, 1, -1, 1, 0, 2, -5, 6, +-2, 1, 1, 0, -4, 4, 1, -2, +3, -1, -2, 1, 3, -2, -2, 3, +-4, 2, -1, 2, -3, 3, -2, 1, +-3, 4, -3, 1, 2, -3, 1, -1, +2, -3, 3, -3, 3, -3, 1, -2, +0, 0, -2, 2, 0, -1, -1, 1, +2, -2, 0, 1, -2, 1, 1, -1, +1, -2, 3, -2, 0, 0, 1, -2, +3, -2, -1, 2, -3, 3, -1, 1, +2, -2, 2, -2, 1, -1, 1, -1, +1, -1, 1, 0, 1, -1, 0, -1, +0, 1, -1, 1, -2, 1, 1, -2, +3, -4, 2, -2, 0, 1, -2, 3, +-7, 6, -4, 3, -1, 1, -2, 1, +1, -1, 2, -2, 0, 0, -1, 2, +0, -1, -1, 0, 0, 0, 1, -1, +-3, 2, 0, 0, 2, -2, 1, -2, +2, 0, -3, 3, 1, -3, 3, 0, +-1, 0, 2, -3, 3, -2, 1, -1, +1, -1, 2, -1, 0, 1, -3, 2, +1, 0, 0, 1, -2, 1, 1, -1, +1, 0, -3, 2, 3, -3, -2, 3, +-5, 4, -1, 3, -4, 2, 3, -5, +5, -4, 2, -2, -1, 1, 1, 0, +-3, 3, -4, 2, 2, -2, 1, -1, +-1, 0, -1, 2, -6, 5, -2, 0, +5, -4, 0, -1, 3, -4, 4, -3, +0, -1, 1, -1, -1, 2, -3, 2, +-2, 3, -2, 2, 2, -2, 1, 0, +0, 0, 1, -1, 1, -2, 4, -3, +1, -1, 0, 1, -4, 5, -3, 2, +0, 0, 2, -2, -1, 2, -1, 0, +0, 0, -2, 2, -2, 2, -3, 2, +-2, 2, 0, 0, 1, -1, -1, 2, +0, -1, 1, -1, -2, 1, 0, -1, +2, -2, -1, 2, -4, 3, -2, 1, +-3, 4, -4, 3, 1, -3, 5, -3, +-1, 1, 2, -4, 4, -2, 0, 0, +0, 0, 1, -1, 1, 0, 0, -1, +3, -2, 1, 0, 0, -1, 0, 1, +-1, 1, -1, 0, 2, -2, 1, -1, +2, -2, 2, 0, -1, 0, 0, -1, +-1, 3, -3, 2, 2, -4, 4, -2, +-2, 3, -3, 2, 0, 1, 0, 0, +1, -1, 0, 1, -1, -1, 1, -1, +1, 0, 2, -2, -1, 2, -1, 1, +2, -2, -3, 3, 2, -3, 2, -1, +-3, 3, 1, -1, 1, 0, -3, 2, +0, 0, -2, 2, -1, 0, 2, -1, +-1, 1, 0, -1, 3, -2, 0, 1, +-3, 2, 1, 0, -2, 1, 0, -1, +1, 0, -1, 1, -2, 1, 2, -2, +0, 1, -4, 3, 1, -2, 0, 1, +-1, 0, 1, -1, 2, -4, 3, -2, +0, 0, 2, -3, 1, 0, 0, 0, +0, -1, 1, -1, 1, 0, 0, -1, +3, -4, 4, -3, -1, 2, 0, -1, +1, 0, -2, 2, 0, 0, -2, 3, +-3, 3, -1, -1, 4, -3, 1, 0, +2, -3, -1, 2, -1, -1, 2, 0, +-3, 3, 0, -1, 0, 0, -2, 3, +-2, 1, 1, -1, 1, -1, 5, -6, +4, -2, -2, 2, -2, 1, -2, 2, +-4, 4, -3, 2, -2, 2, 1, -2, +3, -2, -1, 1, 0, -1, 0, 1, +0, -2, 1, 0, -3, 3, 0, -1, +0, 0, 2, -2, 0, 1, -2, 2, +0, 0, 1, -1, -3, 3, -1, 1, +0, 0, 0, -1, 2, -1, 1, -2, +2, -2, 1, -1, 0, 1, -1, 1, +0, 1, -3, 3, -2, 1, 3, -3, +2, -1, -3, 3, -1, 1, -3, 3, +-2, 1, 1, -1, 0, -1, 1, -1, +0, 0, 0, -1, 1, -2, 2, -1, +-1, 0, 0, 0, 0, 1, -2, 1, +-2, 1, -1, 1, -1, 0, 1, -1, +2, -1, -2, 2, 0, -1, 3, -1, +1, -2, 1, -1, 0, 1, 0, 0, +0, 0, 0, 0, 0, 1, -4, 5, +-1, 0, 0, 0, -1, 0, 2, -1, +0, 1, -2, 1, 1, -1, -2, 2, +-1, 0, 2, -2, 2, -3, 0, 0, +0, 0, 0, 1, -1, 0, 0, 1, +-6, 6, -5, 4, -1, 1, -2, 1, +0, -1, 1, -1, -1, 1, -2, 1, +0, 0, 0, -1, 4, -5, 3, -2, +2, -2, 3, -3, 1, 0, 2, -2, +3, -2, -2, 3, -3, 3, -4, 4, +-3, 2, 0, 1, -1, 1, 0, 0, +0, 0, -2, 2, -3, 3, -2, 2, +-3, 2, -1, 1, 0, 0, -1, 0, +-1, 2, -2, 2, -3, 2, -1, 0, +2, -2, 1, -1, 1, -2, 3, -2, +-2, 2, 1, -2, 1, 1, -1, 0, +1, -1, -1, 1, -2, 1, -2, 2, +0, 0, -2, 3, -3, 2, 0, 1, +-3, 3, -1, 1, 1, -1, 3, -3, +3, -1, 0, 0, 1, -2, 0, 0, +2, -3, 2, -1, 0, -1, 2, -2, +1, -2, 3, -3, 0, 1, -1, -1, +2, -2, 0, 1, 0, -1, 2, -2, +0, 0, -1, 1, 1, -1, -1, 3, +-4, 2, 0, 0, 0, 0, 2, -2, +-2, 3, -1, 1, 0, 0, -2, 2, +-1, 1, 1, -2, 3, -4, 3, -2, +0, 0, 0, 0, 0, 0, 2, -2, +2, -1, -1, 3, -2, 1, 3, -3, +1, 0, 2, -2, 0, 1, 1, -2, +4, -2, -1, 1, 2, -2, 1, 0, +-1, 0, 1, -1, 0, 0, 0, -1, +1, -1, 0, 1, -2, 1, 2, -2, +0, 1, -1, 1, -2, 3, -3, 2, +2, -3, 2, -1, -1, 1, 0, -1, +-1, 2, 0, 0, -1, 2, -4, 3, +1, -1, 0, 0, 1, -1, 1, 0, +1, -2, 1, -1, 2, -2, 0, 1, +-1, 1, 0, 1, -3, 2, 2, -2, +2, -1, 1, -2, 0, 1, -1, 2, +-2, 1, 0, 0, -2, 3, -5, 5, +-3, 2, 0, 0, 1, -2, 1, 0, +0, 0, 0, -1, -1, 1, 0, 0, +0, 0, -1, 2, -3, 3, -1, 0, +0, 1, -2, 1, 1, -2, 2, -3, +4, -4, 3, -3, 2, -2, 2, -1, +0, -1, 3, -3, 0, 1, -4, 4, +-3, 2, 2, -3, 3, -2, -2, 2, +-2, 3, -4, 3, 1, -2, 1, 0, +-3, 2, 2, -2, 0, 1, 1, -2, +4, -3, 0, 0, 2, -3, 2, -2, +2, -2, 0, 0, -4, 4, -3, 3, +-2, 1, 0, 0, 1, -2, 2, -2, +-1, 1, 0, -1, 1, 0, 0, 0, +1, -1, 3, -3, 1, 1, -4, 3, +-1, 0, 0, 1, -1, 1, 0, 0, +-1, 1, -1, 0, -1, 2, -2, 1, +2, -2, 2, -1, 1, -1, 0, 0, +-1, 1, -1, 1, -1, 0, 2, -1, +-2, 2, -1, 0, 1, 0, 1, -2, +0, 1, -3, 3, 1, -2, 1, -1, +0, 0, -3, 4, -2, 1, 2, -1, +0, 0, 4, -5, 2, 0, -2, 1, +0, 1, -1, 0, 4, -5, 3, -2, +-1, 2, -1, 1, 0, 0, 2, -1, +-1, 1, -1, 0, -1, 1, 2, -4, +5, -3, -3, 3, -1, 0, -1, 1, +1, -1, -1, 1, -3, 3, -3, 3, +-1, 0, 0, 1, 1, -2, 2, -2, +-3, 3, -1, 1, 2, -3, 4, -4, +2, -1, -1, 1, 1, -2, 2, -2, +1, -1, 1, -1, 1, 0, 0, -1, +1, -1, -2, 2, 0, -1, 1, 0, +-1, 1, 0, 0, -2, 2, -3, 3, +-5, 4, -3, 3, 0, -1, 0, 0, +-1, 1, -1, 2, -3, 2, 1, 0, +-1, 1, 2, -2, 1, 0, -1, 0, +0, 1, 0, 0, 3, -3, 3, -3, +2, -2, -1, 1, 0, 0, 1, -1, +0, -1, 2, -2, 2, -1, -1, 1, +-2, 1, 3, -4, 2, -2, 2, -3, +2, -1, -1, 1, 2, -2, 0, 1, +-1, 0, 2, -2, 3, -3, 2, -1, +2, -2, 5, -5, 2, -2, 2, -1, +-1, 2, -1, 0, 2, -2, 1, 0, +1, -2, 4, -4, 1, 1, -4, 3, +-1, 1, 0, 0, 1, -1, -2, 3, +-1, 0, 1, -1, 2, -3, 5, -4, +-1, 1, -1, 1, 0, 0, 0, -1, +0, 1, -4, 4, -1, 0, 4, -3, +-1, 1, -1, 1, -1, 2, -2, 1, +2, -3, 3, -2, -1, 1, -2, 2, +-2, 1, 1, -2, 2, -1, 0, 1, +0, -1, 2, -1, -3, 3, 0, -1, +1, 0, -1, 0, 0, 0, 0, 0, +0, 0, 0, -1, 2, -2, 2, -2, +0, 0, 1, -1, 2, -1, -1, 1, +-1, 1, -2, 3, -2, 1, -1, 2, +-3, 2, 0, 0, -2, 3, -1, 0, +0, 0, 0, 0, 0, 0, 0, 1, +-3, 3, 0, -2, 3, -3, 2, -2, +1, 0, -4, 4, -1, -1, 1, 0, +-2, 2, 0, 0, -2, 2, 0, -1, +1, 0, -1, 1, -1, 1, -2, 3, +-2, 2, -1, 0, 1, -2, 2, -2, +0, 0, 1, -1, 2, -1, 0, 0, +1, -2, 3, -2, -2, 3, -1, 0, +0, 1, -2, 1, 1, -1, 1, -1, +2, -3, 1, 0, -2, 1, 0, 0, +4, -5, 2, 0, -5, 4, 1, -2, +1, -1, 1, -1, -1, 1, 1, -2, +2, -1, 1, -2, 1, -1, -2, 2, +-2, 2, -2, 2, -2, 2, 0, 0, +1, -1, 2, -2, 1, 0, -3, 3, +-1, 0, 1, -1, -1, 0, 2, -2, +0, 0, -2, 2, -1, 0, 2, -2, +1, -1, 1, 0, -3, 3, -2, 0, +0, 0, -1, 0, 2, -1, -1, 2, +0, -1, 1, -2, 4, -4, 0, 1, +-1, 0, 1, -1, 1, -1, -1, 2, +0, 0, 0, 1, -1, 0, 3, -3, +0, 1, -3, 2, 3, -3, 1, 0, +-3, 3, -2, 1, 1, -2, 2, -2, +1, -1, -1, 1, -1, 0, -1, 1, +-2, 1, 0, -1, 1, 0, 2, -3, +2, -1, -2, 2, 2, -3, 1, 0, +-2, 2, 0, -1, 0, 0, -3, 4, +-4, 3, 2, -3, 2, -1, -3, 3, +-3, 2, 1, -1, 0, 0, -1, 1, +-2, 2, 1, -1, -1, 2, -2, 2, +-1, 2, -3, 2, 2, -2, 1, 0, +-1, 1, -3, 3, -1, 0, 3, -3, +2, -3, 2, -2, 0, 0, 0, -1, +1, -1, 1, -1, 1, -1, 0, 1, +-2, 2, -1, 1, -2, 3, -3, 2, +0, -1, 1, -1, 2, -2, 1, 0, +-2, 2, -2, 2, -2, 2, -1, 0, +2, -2, -1, 2, -1, 0, 0, 1, +-3, 2, 0, 1, -4, 3, 0, -2, +0, 1, -2, 1, 1, -1, 2, -2, +1, 0, -2, 2, -2, 2, -2, 2, +1, -2, 2, -1, -1, 1, 0, -1, +0, 2, -3, 3, -1, 1, -1, 1, +2, -3, 2, -2, 0, 0, 0, 0, +1, -2, 1, -2, 4, -4, 2, -1, +-1, 1, -1, 1, 0, -1, 0, 0, +0, 0, 1, -1, 0, 0, 3, -3, +-1, 2, -2, 1, 0, 0, -4, 3, +-1, 1, -3, 4, -1, -1, 3, -2, +0, 0, 0, 0, 0, 0, -2, 3, +-4, 2, 2, -1, -3, 3, 0, -1, +0, 1, -1, 1, -2, 2, 0, 0, +1, -1, -1, 0, 3, -3, 4, -5, +4, -2, -2, 2, 2, -3, 1, 0, +-2, 1, 0, 0, 0, 0, 0, -1, +1, -1, 0, 1, -3, 3, -2, 3, +-4, 3, 1, -2, 0, 1, -1, 0, +2, -2, 1, -1, 0, 1, 0, -1, +2, -2, -2, 4, -6, 5, -1, 0, +1, 0, 1, -2, 1, -1, -1, 2, +-2, 2, -3, 4, -2, 1, 1, 0, +-2, 1, 2, -3, 1, 1, 0, -1, +4, -4, 0, 2, -3, 3, 0, 0, +1, -1, 0, 0, 1, -1, 0, 1, +-3, 4, -2, 1, 1, -2, 2, -1, +-1, 3, -3, 2, 0, 0, 1, -2, +4, -4, 1, -1, 2, -2, 1, -1, +1, 0, 0, -1, 3, -3, 0, 0, +2, -2, 2, -1, 1, -2, 4, -4, +-1, 2, -2, 1, 1, -1, 0, 0, +1, 0, -1, 0, 1, -1, 1, -2, +3, -3, 1, -1, 0, 0, 0, 0, +1, -1, 1, 0, -1, 1, 1, -2, +0, 0, 1, -1, -1, 3, -3, 1, +3, -2, -4, 5, -2, 0, 2, -1, +-2, 2, -3, 3, -3, 2, 2, -3, +3, -2, 1, -2, 1, -1, -2, 3, +-1, 0, 1, 0, -3, 4, -3, 2, +-2, 2, -3, 2, -2, 2, 0, -1, +2, -1, -2, 2, 0, 0, -1, 2, +-2, 1, -1, 1, 0, 0, 0, 0, +0, -1, 2, -2, 0, 0, -1, 2, +-3, 3, 1, -3, 2, 0, -5, 5, +1, -2, 2, -1, -1, 0, 1, -1, +-2, 2, 2, -2, 0, 1, -2, 1, +1, -1, 1, -2, 1, 0, -2, 2, +2, -3, 5, -5, 0, 3, -6, 5, +0, -1, 2, -2, 3, -3, 2, -1, +1, -1, 0, 1, -3, 3, -1, 1, +0, -1, 3, -3, 1, 0, -1, 0, +2, -2, -1, 1, 2, -3, 2, -1, +-1, 1, 2, -2, 0, 1, -2, 2, +-2, 1, 2, -1, -2, 3, 0, -2, +2, -1, 0, -1, 4, -3, -1, 2, +2, -3, 4, -3, 1, -1, 3, -4, +4, -3, -1, 2, -2, 1, 2, -3, +1, 0, 1, -2, 4, -4, 2, -1, +-2, 2, 0, 0, 0, 0, -1, 0, +0, 0, -2, 1, 0, -1, -2, 2, +1, -3, 4, -3, 0, 0, 1, -2, +2, -2, 2, -2, 2, 0, -1, 1, +0, 0, 0, 0, 1, 0, -1, 1, +2, -2, 2, -1, 0, 0, 1, 0, +-1, 1, -2, 2, -1, 1, 1, -1, +0, 1, -1, 0, 0, 0, 0, -1, +2, -2, -1, 2, 0, -1, 0, 1, +-4, 4, -2, 1, 1, -2, 1, -1, +1, -1, 0, 1, -3, 3, -1, 0, +3, -3, 0, 1, -1, 0, 0, 1, +-2, 2, -3, 4, -4, 3, 0, 0, +-2, 1, 3, -4, 4, -3, 1, -1, +2, -2, 1, -1, -1, 2, -2, 1, +3, -4, 3, -2, -1, 1, 0, 0, +-1, 2, -2, 2, 0, 0, -1, 1, +0, -1, 2, -2, 2, -2, 0, 1, +-1, 1, 0, 0, 0, 1, -1, 1, +1, -2, 0, 0, 0, -1, 1, 0, +-3, 3, 0, -1, 2, -2, 1, -1, +1, -1, -2, 3, -1, -1, 4, -3, +-1, 2, -2, 1, 0, 0, -2, 2, +0, -1, 0, 1, -3, 2, 1, -1, +0, 0, -1, 2, -3, 2, 2, -3, +2, -1, 0, 1, 0, -1, 5, -5, +2, -1, 1, -1, 4, -4, 3, -3, +0, 0, 1, -2, 4, -3, -1, 2, +-2, 1, 0, 0, 1, -1, 3, -3, +1, 0, -1, 1, -1, 1, 0, 0, +0, 1, -2, 1, 3, -3, 2, -1, +0, 0, -1, 2, -1, 0, 1, -1, +0, -1, 1, -1, -2, 2, -3, 2, +-1, 1, 1, -2, 3, -3, 1, 0, +0, -1, 3, -3, 3, -3, 2, -1, +-1, 1, 0, 1, -3, 3, -1, 0, +1, 0, -2, 2, 0, -1, 1, -1, +-1, 0, 1, -1, -1, 0, 2, -3, +-1, 3, -4, 2, 3, -3, 1, 0, +0, 0, -1, 1, 1, -2, 2, -1, +-2, 2, 2, -4, 5, -4, 3, -2, +1, 0, 0, 0, 1, -1, -1, 2, +-1, 0, 2, -2, 2, -1, -2, 2, +-2, 1, 0, 1, -3, 3, 1, -1, +0, 2, -4, 4, -1, 0, 1, -1, +2, -2, 0, 0, 1, -2, 2, -2, +0, -1, 0, 1, -5, 5, -1, -1, +1, -1, 1, -2, 4, -3, 2, -1, +0, 0, 1, -1, 0, 0, -1, 0, +2, -2, 2, -2, 3, -2, -1, 2, +-1, 0, 1, 0, -2, 2, 0, -2, +4, -3, 0, 1, 1, -1, -1, 3, +-4, 3, -2, 2, -4, 3, 1, -1, +-1, 2, 0, 0, 1, 0, -2, 2, +0, -1, 2, -1, -1, 2, -1, 0, +0, 1, -3, 3, 1, -2, 4, -3, +0, 1, -1, 1, -1, 1, -4, 4, +0, -1, 1, 0, 0, -1, 2, -1, +-3, 3, 0, -1, 5, -4, 3, -2, +1, -1, 1, -1, 1, -1, 0, 1, +1, -2, 2, 0, -3, 3, -1, 1, +-2, 2, -1, 0, 1, -1, 0, 0, +2, -3, 2, 0, -2, 2, 0, -1, +0, 1, -3, 3, -2, 1, -1, 2, +-5, 5, -4, 3, -3, 3, 0, -2, +3, -2, -1, 1, 3, -4, 3, -3, +2, -3, 3, -1, -3, 3, -1, -1, +4, -3, 0, 0, -1, 1, -1, 1, +-4, 5, -5, 4, -1, 1, 0, 0, +-1, 2, -3, 3, 0, -2, 6, -6, +2, -1, -2, 2, 0, -1, 3, -2, +-2, 3, -2, 1, 2, -2, 0, 1, +-1, 1, 2, -2, 1, -1, 1, -1, +1, 0, -2, 2, -2, 1, 0, 0, +-1, 1, 0, 0, 0, 0, 0, 1, +-4, 3, 2, -4, 4, -3, 2, -2, +2, -1, -1, 1, 0, -1, 0, 1, +-2, 2, -1, 1, -3, 3, -2, 2, +0, 1, -2, 2, 1, -2, 1, 0, +-4, 4, -4, 4, -4, 3, -2, 1, +-1, 2, -2, 2, -1, 1, 0, 0, +1, -1, -1, 1, -1, 1, 0, 0, +2, -2, 2, -1, -1, 1, 0, -1, +0, 1, 0, 0, 3, -3, 1, -1, +1, -2, 2, -2, 2, -2, 4, -4, +2, -1, 1, -1, 0, 1, -2, 2, +-2, 1, 1, -2, 3, -3, 2, -3, +4, -4, 0, 0, 0, -1, 3, -3, +5, -4, 1, 1, -2, 1, 0, 0, +0, 0, 0, 0, -1, 0, 1, 0, +-1, 2, -2, 2, -1, 1, -1, 1, +1, -2, 0, 2, -2, 0, 3, -3, +2, -2, 0, 1, -3, 3, 0, -1, +2, -2, 1, 0, -2, 2, 0, -1, +0, 1, -3, 3, -4, 4, 0, -2, +2, 0, -4, 5, -3, 2, -3, 4, +-2, 1, 1, -1, -2, 2, 1, -1, +0, 0, -1, 1, 0, 0, 0, 0, +-1, 2, -1, 1, 1, -1, 2, -3, +4, -4, 0, 0, -2, 1, 1, -1, +0, 1, 0, 0, 1, -1, 1, -1, +0, 0, -1, 1, 1, -1, 0, 1, +-2, 3, -4, 4, -3, 1, 0, 0, +1, -1, 5, -5, 2, 1, -5, 4, +0, -2, 0, 0, -2, 2, -3, 3, +-3, 4, 0, 0, 1, 0, -3, 2, +1, -3, 2, -1, 2, -1, 1, 1, +-2, 2, 0, -2, 2, -2, -1, 1, +1, 0, -1, 2, 0, -1, 4, -4, +4, -4, 1, -1, -2, 2, -2, 3, +-3, 4, 0, -1, 3, -3, -2, 2, +-2, 1, -2, 2, -2, 2, 1, 0, +1, -1, 0, 0, -3, 2, -2, 1, +-3, 4, -1, 1, 2, 0, -1, 1, +-1, 0, -2, 0, 1, -1, -2, 3, +2, -2, 1, 2, -5, 4, 1, -4, +1, -2, 2, -3, 5, -4, 3, -1, +0, 2, -2, 2, -3, 2, -2, 0, +2, -2, 3, -2, 4, -2, 0, 1, +-2, 1, -3, 2, -2, 1, -1, 3, +0, 1, 2, -1, -1, 1, -4, 3, +-4, 2, 1, -2, 1, 1, 1, 0, +2, 0, -3, 2, -2, -1, -1, 1, +-4, 4, 0, 1, 0, 2, -3, 3, +-3, 2, -3, 1, -1, 0, 2, -1, +2, -1, 4, -3, -1, 2, -5, 3, +-5, 4, -3, 1, 4, -2, 0, 3, +-1, 3, -5, 4, -2, -2, -1, 1, +-2, 2, -1, 3, -3, 5, -3, 3, +-3, 0, -1, -2, -1, 0, 1, 0, +1, 1, 0, 2, -4, 4, -4, 1, +0, -3, 3, -2, 1, 1, 4, -1, +-1, 3, -3, 1, -4, 3, -4, 2, +-1, 3, -3, 4, 2, -1, 2, -1, +-3, 1, -4, 1, -2, 1, -1, 2, +2, 0, 5, -3, 2, -2, -3, 1, +-5, 2, 1, -3, 4, -2, 5, -2, +3, -1, -1, 0, -4, 2, -4, 1, +1, 0, 1, 2, 1, 2, -1, 2, +-3, 2, -4, 0, 1, -3, 1, 1, +3, -1, 3, 0, -1, 1, -4, 1, +-3, 0, -3, 3, -2, 3, 3, 0, +1, 1, -1, 0, -3, -1, -1, -1, +1, -2, 4, -1, 2, 1, 1, 0, +-3, 1, -3, -1, -3, 1, 1, -1, +4, 0, 2, 0, 0, 0, -4, 0, +-2, -2, -2, 0, 4, -3, 5, 0, +1, 1, 1, -2, -4, 0, -4, 0, +-1, 1, 3, -1, 6, -1, 2, -1, +-2, 1, -5, 1, 1, -4, 2, 0, +4, 0, 5, -1, -3, 4, -5, 0, +-4, 1, -4, 2, 3, 0, 4, 0, +4, 0, -2, 1, -3, -2, -1, -2, +-1, 1, 2, 0, 6, -2, 2, -1, +3, -6, -2, -1, -4, 1, 2, -1, +7, -3, 5, 0, 1, -2, 0, -2, +-5, 1, -2, 0, 2, 1, 4, 1, +1, 2, -2, 1, -4, -1, -2, -2, +-1, 1, 3, 0, 5, 0, 2, 0, +-1, -1, -5, -1, 0, -4, 3, -1, +3, 2, 1, 4, -3, 2, -1, -3, +-3, -1, -4, 2, -2, 3, 6, -2, +3, 2, -3, 1, -2, -2, -6, 2, +1, -3, 5, 1, 1, 3, 4, -3, +-1, -1, -5, 0, -3, -1, 2, 0, +4, 1, 5, -1, -1, 2, -6, 2, +-6, 0, -4, 2, 3, -2, 9, -4, +5, -2, 2, -3, -5, 1, -4, -2, +2, -3, 6, -2, 6, 0, 2, 1, +-4, 2, -6, -1, 2, -6, 4, -2, +4, 1, 6, -2, 2, -1, -3, -1, +-1, -6, 1, -3, -1, 4, 0, 5, +2, 2, 0, -1, -6, 2, -9, 3, +-2, 1, 4, 0, 6, 0, 3, 0, +-3, 1, -5, -1, -5, 2, -2, 2, +5, 0, 5, 0, 2, 0, -8, 5, +-11, 4, -4, 0, 5, -3, 7, 0, +4, 0, 0, -1, -8, 3, -6, 0, +0, -1, 5, -2, 8, -1, 1, 1, +-2, 0, -9, 4, -8, 3, -2, 2, +7, -3, 10, -4, 4, -2, -3, 0, +-9, 3, -3, -1, 3, 1, 4, 1, +5, 0, -1, 0, -2, -3, -5, 0, +-1, 0, 4, 0, 5, 1, 4, -1, +-3, 2, -5, -2, -3, 0, -2, 1, +5, 0, 4, 1, 4, -3, -3, 0, +-5, -2, -2, 0, -1, 2, 8, -4, +7, -1, -2, 1, -6, 0, -5, -1, +0, -2, 4, 0, 5, 1, 3, 1, +-5, 3, -6, -1, -5, 1, -2, 2, +4, 1, 5, 1, 2, 0, -5, 1, +-4, -3, -1, -1, 0, 1, 5, 2, +1, 3, -1, 0, -6, 2, -7, 1, +-3, 1, 3, 0, 5, 1, 4, -1, +-1, 0, -4, -3, -2, -2, -1, 2, +4, 1, 6, -1, 3, -1, -4, 1, +-6, 0, -5, 1, 3, -2, 8, -1, +4, 1, 1, -1, -2, -2, -4, -1, +0, -3, 6, -1, 4, 2, 4, 0, +-3, 3, -6, -1, -3, -2, -2, 3, +1, 3, 5, 0, 2, 0, -2, -2, +-4, -1, -2, -2, 4, -1, 2, 3, +3, 2, 1, -1, -3, -1, -6, 1, +-1, -1, 5, -2, 7, 0, 0, 4, +-5, 3, -5, -1, -2, -2, 0, 0, +6, -3, 10, -4, 5, -2, -3, 0, +-4, -2, -6, 3, 0, -1, 10, -4, +5, 0, -1, 2, -6, 1, -5, -1, +-3, 1, 4, -1, 8, -2, 3, 2, +-5, 4, -5, 0, -5, 1, 0, -1, +7, -3, 7, -1, 2, 1, -1, -3, +-4, 0, -6, 1, 2, -1, 3, 3, +2, 2, -1, 1, -7, 2, -3, -4, +3, -4, 4, -1, 8, -2, 4, -1, +1, -3, -4, 0, -7, 2, -2, 1, +5, 0, 6, -1, 3, -1, -2, 1, +-8, 3, -7, 2, 1, 0, 6, -1, +6, -1, 0, 1, -5, 1, -7, 1, +-3, 1, 1, 2, 4, 1, 2, 3, +-4, 3, -7, 3, -7, 3, -2, 3, +1, 3, 4, 1, 2, 1, -3, 0, +-6, 1, -4, -1, 2, -1, 2, 2, +3, 0, 2, -1, -5, 1, -5, -2, +0, -2, 1, 1, 7, -3, 8, -4, +1, -1, -3, -1, -5, 2, -3, 1, +6, -1, 5, 0, 5, -3, 2, -4, +-1, -2, -6, 4, -1, 1, 5, 0, +3, 0, 1, -1, -4, -1, -4, -1, +-3, 0, 5, -4, 4, 1, 2, -1, +2, -3, -4, 1, -4, 0, -1, 1, +2, 2, 5, 0, 5, -2, 1, -2, +1, -5, 3, -5, 3, -1, 4, 1, +2, 2, -1, 1, -4, 0, -3, -3, +4, -7, 3, -1, 2, 1, 3, 0, +-1, 0, -3, -1, -4, 0, 1, -1, +2, 3, 1, 3, 1, 2, -2, 1, +-3, 1, 0, -2, 2, 0, 3, 0, +7, -3, 0, 2, -3, -1, -3, -1, +-4, 1, 0, 1, 3, 0, 0, 2, +-2, -1, -1, -2, -6, 2, 0, -2, +1, 2, 1, 1, 3, -1, 0, -1, +2, -5, -2, 2, -1, 1, 5, -1, +3, 2, -2, 4, -3, 0, -1, -2, +-1, 0, -2, 4, -1, 2, 7, -6, +3, -2, -6, 2, -4, -1, 0, -1, +0, 1, 3, -1, 3, -2, -1, 0, +-2, -1, -1, -1, 1, 0, 4, 0, +4, 0, 1, 2, -2, 1, 0, -1, +1, -1, 5, -3, 3, 2, 0, 2, +0, 0, -4, 1, -5, 1, -4, 1, +0, -1, 2, -1, 1, -1, -3, 1, +-4, 0, -3, 1, -3, 2, 2, -1, +3, 0, 3, -1, 1, 1, -5, 5, +-2, 2, 1, 2, 4, 0, 3, 1, +1, 0, 0, -1, -4, 2, -3, 0, +-2, 1, -1, 1, -4, 3, -7, 2, +-5, 0, -6, 1, 0, -3, 1, 1, +1, 0, 5, -3, 1, 1, 1, -1, +4, -3, 6, -2, 7, -2, 8, -2, +2, 2, 0, -1, 3, -4, 1, -1, +0, -1, -2, 1, -2, -1, -4, 0, +-7, 1, -6, 0, -4, -1, -2, 1, +-3, 3, -2, 2, -1, 1, 0, 1, +2, 0, 3, 1, 5, 1, 4, 4, +4, 1, 5, 0, 0, 2, 0, 2, +-2, 3, 0, -2, -2, 2, -7, 2, +-7, 1, -7, -2, -2, -4, -6, 1, +-1, -4, 0, 0, -5, 4, -4, 4, +-2, 2, 3, 0, 7, -1, 7, 2, +4, 3, 9, -4, 9, -3, 4, 0, +1, 3, -1, 2, 1, -1, -3, 1, +-6, 0, -6, -3, -8, 0, -13, 5, +-8, -1, -3, -1, -4, 0, -3, 0, +-3, 2, 1, 1, 3, 2, 9, 0, +8, 2, 8, 0, 10, -1, 8, -1, +8, -3, 7, -1, 2, 2, -3, 3, +-5, 0, -7, 0, -12, 1, -10, 0, +-9, 0, -10, 2, -10, 3, -10, 3, +-7, 1, -1, 0, 0, 3, 5, 2, +10, 0, 13, -1, 8, 4, 7, 2, +10, -1, 10, -2, 9, -1, 3, 0, +0, -2, -5, -1, -12, 3, -14, 2, +-12, 1, -13, 3, -9, -4, -5, -5, +-7, -2, -3, -2, -3, 4, 3, 1, +11, -1, 11, 0, 10, 2, 7, 3, +14, -2, 13, 0, 14, -2, 7, 3, +0, 1, -3, 0, -9, 0, -7, -3, +-11, 0, -9, -4, -10, -2, -15, 1, +-14, -1, -10, -1, -3, -3, 4, -2, +6, 1, 10, -1, 10, 1, 12, -1, +16, -1, 16, 0, 17, -1, 14, -1, +11, -4, 4, -2, -3, -1, -8, 1, +-9, -1, -10, -1, -15, 1, -18, 1, +-18, -1, -15, -1, -10, -1, -1, -3, +4, -2, 7, -2, 10, -2, 13, -2, +18, -3, 21, -3, 23, -2, 17, 2, +10, 2, 7, -1, 0, 0, -1, -3, +-4, -1, -12, 3, -15, 1, -21, 3, +-25, 3, -19, -2, -16, 3, -14, 4, +-2, -2, 0, 1, 2, 0, 8, 0, +11, 2, 18, 1, 22, 0, 24, -2, +19, -1, 11, 0, 5, 1, 1, 1, +1, -2, -4, -1, -11, 0, -18, 0, +-24, 1, -23, -1, -17, -2, -14, 1, +-11, 1, -6, 0, -5, 3, 2, -1, +9, 1, 18, -2, 25, -1, 25, -2, +22, -1, 16, 0, 10, 2, 8, 1, +7, 0, 4, -3, -6, 1, -18, 1, +-20, -1, -27, 4, -23, 1, -20, 3, +-15, -1, -12, 2, -14, 3, -3, -1, +6, -1, 16, -1, 19, 2, 23, -1, +21, 1, 19, -1, 20, -3, 15, 1, +14, -2, 9, 0, -1, -1, -8, -3, +-18, -1, -21, 0, -22, 0, -16, -4, +-17, 0, -20, 2, -16, -2, -7, -3, +-3, 2, 8, 0, 15, 3, 16, 3, +19, 2, 16, 3, 21, -2, 23, -1, +18, 2, 12, 2, 2, 3, -7, 1, +-13, -1, -19, 1, -20, 0, -17, -2, +-18, -2, -23, 1, -23, 0, -16, -1, +-8, -1, 2, 1, 8, 3, 13, 2, +17, -1, 19, -2, 22, -1, 24, 0, +22, 2, 20, 0, 10, 1, 1, -1, +-7, 0, -13, 0, -13, 0, -18, 1, +-20, -1, -24, -1, -24, -2, -21, -1, +-13, -2, -1, -3, 3, 2, 5, 2, +12, 0, 13, 1, 20, -1, 26, -2, +29, -2, 23, 2, 17, -2, 11, -3, +-2, 2, -5, 0, -9, 2, -13, 0, +-18, 2, -27, 2, -24, -4, -21, -2, +-18, 0, -11, 3, -7, 3, 5, -5, +9, -4, 11, -2, 16, 1, 21, 1, +27, -1, 27, -2, 20, 1, 12, -1, +7, 1, -2, 3, 3, -5, -5, 1, +-17, 3, -22, 0, -24, -2, -23, -2, +-21, 2, -17, 3, -11, 2, -7, 1, +-2, -1, 4, -1, 13, -3, 23, -4, +27, -1, 24, 1, 19, 2, 14, -1, +15, -4, 9, 1, 4, 2, 0, 0, +-7, -1, -16, 0, -21, -2, -20, -3, +-20, 1, -19, 3, -12, -2, -10, -1, +-6, -4, 0, -3, 5, 0, 16, -2, +20, 1, 22, -1, 21, -1, 19, -3, +16, -1, 12, 2, 9, 2, 7, -1, +0, -2, -11, 0, -18, -1, -16, -3, +-19, 2, -16, -1, -12, -4, -14, 0, +-16, 3, -9, -2, 3, -3, 6, 3, +14, 0, 18, 0, 17, -1, 16, -1, +17, -2, 20, -3, 16, 0, 12, -1, +5, -1, -5, -1, -11, 1, -15, 0, +-14, 1, -18, 4, -15, 0, -18, 2, +-19, 1, -14, 2, -9, 4, 1, 1, +7, 2, 7, 5, 9, 2, 10, 3, +12, 2, 18, -2, 18, 0, 12, 3, +3, 5, -3, 0, -5, 0, -10, 1, +-8, -2, -8, -3, -12, -2, -14, -3, +-16, 0, -16, 0, -9, -1, -1, 0, +4, 0, 8, -1, 6, 1, 9, -3, +17, -4, 18, -1, 18, -1, 14, 0, +10, -1, 5, -2, 1, -1, -4, 1, +-2, -4, -4, 0, -12, 1, -12, -4, +-15, -2, -14, -2, -7, -3, -5, 2, +-6, 4, -5, 5, -2, 4, 4, 0, +7, 3, 9, 3, 16, -1, 16, -1, +13, -1, 2, 3, 2, -1, 2, 2, +-1, 1, -1, -3, -4, -4, -11, 0, +-14, 1, -14, 1, -12, -1, -4, -3, +0, -2, -3, 0, 0, -3, 0, 0, +3, 2, 10, 1, 13, -1, 15, -4, +12, -1, 5, 3, 5, -1, 7, -3, +5, -2, 0, 2, -6, 5, -9, -2, +-10, -3, -7, -4, -5, -1, -7, 0, +-2, -6, -3, -3, -6, 3, -3, 1, +3, -2, 8, -3, 14, -3, 8, 4, +7, -1, 6, -2, 6, -2, 11, -2, +9, -1, 6, -5, 1, -3, -2, -2, +-5, 0, -9, 2, -8, -2, -8, 2, +-8, 5, -10, 4, -11, 1, -2, -4, +1, 1, 2, 3, 8, -3, 6, -4, +8, -2, 7, 2, 3, 4, 5, -2, +6, 1, 2, 4, 4, -1, -1, -1, +-5, -4, -2, -1, -2, 3, -5, 0, +-6, -2, -6, -2, -7, 3, -5, 3, +-4, -2, 1, -3, 4, 2, 5, 0, +7, -5, 8, -9, 6, -1, 5, 6, +6, 2, 4, -3, 6, -7, 3, 1, +0, 1, 2, -6, 1, -5, -2, 1, +-6, 7, -6, 2, -9, -3, -7, 0, +-4, 7, -5, 6, 0, -2, 1, -5, +-2, 4, 0, 6, 5, -3, 5, -5, +5, 0, 3, 8, 1, 3, 5, -8, +1, -3, 1, 1, 2, 5, -4, 3, +-6, -4, -7, 5, -5, 4, 0, -2, +0, -7, 1, -6, -1, 6, -3, 7, +0, -6, 0, -5, 3, -1, 4, 6, +3, 0, 5, -8, 2, -2, 3, 4, +3, 4, 1, -4, 3, -8, 1, 5, +-1, 4, 1, -3, -5, -4, -6, 0, +-4, 10, -2, 3, -1, -8, -1, -4, +-5, 6, -4, 9, 0, -2, 2, -8, +1, 2, 1, 9, -1, 5, -2, -5, +1, -4, 4, 5, 5, 2, 8, -9, +3, -10, 1, -2, 3, 7, 1, -2, +0, -9, 1, -3, -3, 8, -5, 8, +0, -8, -4, -6, -2, 6, -1, 10, +-2, -1, 4, -12, 2, -3, 0, 9, +1, 5, 1, -5, 2, -7, 3, 5, +2, 8, 1, -6, 1, -8, 2, 0, +-2, 11, -2, 6, -2, -9, -5, -4, +1, 5, 2, 3, -4, -3, 2, -11, +-2, 5, -3, 11, 4, -4, 1, -12, +2, -4, 1, 12, -4, 12, -2, -6, +4, -9, 0, 6, 0, 11, 1, 1, +-3, -9, -1, 1, 0, 11, -2, 1, +-1, -6, -3, -6, -3, 5, 0, 11, +-6, -2, -6, -9, 2, -2, 1, 9, +-1, 3, 2, -12, 1, -5, 0, 9, +4, 7, 1, -6, 1, -12, 6, 3, +3, 9, 2, -2, 2, -9, -1, -6, +0, 10, 2, 7, -1, -13, -1, -8, +-1, 7, -5, 10, 0, -2, 3, -17, +0, -2, 0, 13, 0, 4, 0, -12, +5, -11, 4, 8, 1, 9, 7, -8, +4, -11, -2, 2, 2, 16, -3, 6, +-2, -14, 7, -8, 2, 6, -4, 10, +-1, -5, -3, -15, -2, 4, 4, 8, +-1, -4, -1, -12, 1, -2, -5, 13, +5, 2, 4, -8, -3, -7, 4, 4, +6, 12, -2, -3, 4, -15, 4, 1, +-2, 10, 4, 4, 1, -11, -3, -12, +0, 13, -5, 11, -6, -5, 2, -12, +-1, -1, -5, 14, 4, -1, -2, -12, +-3, -4, 7, 8, -1, 11, 1, -10, +9, -13, -2, 7, 3, 8, 8, 1, +-4, -10, 0, -3, 4, 13, -3, 3, +-2, -7, 0, -8, -10, 9, -2, 14, +-1, -3, -9, -12, 1, 0, -2, 11, +-5, 6, 5, -12, 3, -9, -3, 11, +5, 11, 0, -3, 2, -15, 9, 1, +1, 15, -3, 4, 4, -9, -3, -6, +-5, 10, 3, 10, -3, -11, -2, -12, +5, 1, -9, 12, -7, 5, 2, -14, +-6, -4, 1, 12, 3, 7, -8, -5, +6, -13, 5, 6, -2, 11, 11, -6, +5, -10, -2, -2, 6, 10, 3, 3, +-2, -13, 4, -6, -4, 9, -7, 9, +1, 0, -7, -13, -6, 0, -1, 16, +-8, 2, -1, -11, 9, -10, -3, 7, +0, 9, 9, -10, 1, -11, 7, 0, +9, 10, -2, 2, 6, -14, 7, -4, +-3, 8, 5, 5, 1, -4, -8, -11, +2, 5, -3, 9, -7, -5, 0, -8, +-2, -4, -8, 11, 6, 4, -1, -11, +-4, -6, 7, 6, -3, 11, 2, -3, +11, -11, -2, 3, 2, 8, 8, 3, +-5, -5, 1, -8, 7, 8, -7, 10, +-3, -4, -1, -6, -10, 0, -4, 13, +1, 1, -7, -11, -1, 0, 0, 5, +-6, 6, 3, -3, 2, -10, 0, 2, +12, 6, 5, 0, -3, -6, 8, -5, +2, 9, -2, 7, 8, -7, -4, -4, +-5, 3, 2, 10, -6, -4, -4, -10, +0, 2, -9, 7, -2, 2, 6, -9, +-7, -9, 4, 2, 4, 9, -5, -1, +7, -8, 8, -4, -2, 10, 6, 2, +8, -9, -2, -4, 9, 2, 0, 11, +-6, -4, 4, -10, -3, 1, -7, 6, +3, 1, -3, -9, -9, -4, 3, 5, +-4, 3, -5, -1, 1, -3, -3, -1, +4, 8, 8, 1, -1, -9, 4, -2, +9, 4, 0, 6, 8, -8, 6, -6, +-10, 8, 0, 7, 3, -1, -5, -11, +2, -4, -4, 11, -11, 3, 3, -7, +-3, -6, -8, 2, 4, 10, -3, 1, +-7, -3, 5, 1, 1, 5, 2, 4, +10, -7, 1, -6, 4, 3, 10, 4, +-2, -1, -2, -7, 5, -3, -5, 8, +-2, 2, -2, -2, -11, -6, 0, 1, +1, 7, -8, -5, 2, -9, 5, -2, +-5, 7, 4, 4, 0, -5, -6, -1, +9, 6, 7, 3, 1, -3, 11, -11, +4, 0, -7, 15, 1, 4, -4, -5, +-4, -5, 4, 5, -8, 8, -5, -8, +1, -6, -8, 3, -4, 8, 3, 2, +-6, -8, -1, 0, 4, 8, -3, 5, +3, -3, 9, -10, -2, 7, 4, 10, +7, -4, -4, -4, 0, 2, -1, 9, +-5, 6, -1, -5, -5, -4, -6, 2, +1, 8, -8, 2, -8, -8, -1, 3, +-4, 8, -3, 2, 3, -4, -2, -6, +3, 5, 9, 7, 1, -5, 3, -7, +4, 3, -3, 11, 2, 3, 3, -8, +-5, -3, -1, 7, -2, 9, -8, -4, +-1, -10, -1, 3, -6, 7, 0, 0, +-3, -6, -5, -6, 5, 7, 3, 5, +-1, -7, 6, -7, 3, 3, -3, 13, +4, 1, 5, -14, 3, -2, 5, 8, +1, 4, -4, -5, 1, -8, -4, 6, +-6, 10, -3, 1, -7, -8, -1, -5, +2, 10, -4, 1, -2, -7, -1, -1, +-2, 5, 3, 9, 5, -5, 0, -12, +5, 2, 5, 10, -2, 4, 1, -5, +0, -4, -3, 8, 3, 7, -2, -6, +-4, -10, -1, 4, -3, 10, -7, 1, +0, -12, -2, -2, -5, 9, 6, 4, +1, -10, 1, -10, 2, 9, -2, 9, +4, -3, 3, -6, -2, 0, 4, 11, +2, 6, -3, -9, 3, -9, 0, 8, +-6, 11, 3, -8, 0, -10, -7, 2, +0, 9, -1, 3, -4, -12, 4, -8, +1, 10, -2, 7, 2, -5, 2, -11, +3, 1, 8, 8, 6, -3, 3, -12, +3, -2, -3, 12, 1, 6, 1, -8, +-1, -10, -1, 5, -1, 10, -1, -5, +-1, -14, -2, -1, -5, 15, -2, 4, +2, -10, -2, -8, 0, 7, 2, 12, +1, -5, 2, -10, 5, 0, 1, 13, +1, 4, 4, -15, 3, -9, 2, 8, +1, 9, -1, -9, 3, -16, 0, 3, +-5, 13, -2, 0, 0, -13, -2, -5, +1, 10, 3, 5, -2, -9, 2, -10, +2, 5, 4, 9, 7, -4, 3, -14, +-2, 3, -3, 17, 2, 1, 4, -12, +1, -8, 1, 5, -2, 13, -2, -5, +-4, -12, -5, 3, 0, 12, -4, 5, +-6, -7, -1, -7, -2, 10, 2, 9, +5, -9, -1, -11, 3, 5, 2, 13, +-2, 2, 2, -13, 2, -7, 0, 13, +3, 8, 0, -11, 0, -11, -3, 8, +-5, 13, 0, -5, 3, -17, -2, -2, +0, 12, 0, 4, -1, -13, 3, -11, +1, 10, -1, 13, 4, -5, 2, -14, +1, 1, 3, 15, 1, 3, -1, -11, +2, -7, 1, 9, 1, 10, -2, -6, +-6, -11, -1, 5, -2, 15, -6, 3, +-5, -10, -3, -4, -2, 12, 3, 5, +1, -10, -1, -10, 2, 8, 0, 14, +3, -5, 3, -15, 3, -3, 3, 13, +3, 5, 0, -12, -2, -9, 2, 7, +0, 11, 0, -9, 2, -16, -4, 4, +-1, 14, -1, 1, -1, -15, -3, -4, +-1, 14, 0, 12, -1, -8, 2, -14, +4, 3, -2, 18, -1, 2, 2, -15, +1, -5, 4, 14, 0, 6, 1, -15, +5, -15, 0, 6, -1, 14, 1, -4, +-5, -15, -2, 0, -1, 18, -7, 8, +0, -15, 4, -9, -5, 14, 1, 13, +2, -7, -3, -17, 9, 0, 5, 14, +0, -2, 6, -15, -1, -6, -4, 14, +6, 7, 1, -13, -6, -10, 5, 6, +-6, 17, -7, 1, 1, -14, -6, -2, +0, 15, 6, 5, -3, -14, 1, -9, +3, 11, -6, 16, 2, -4, 4, -16, +-3, 1, 4, 18, -1, 6, -7, -15, +7, -10, -1, 14, -7, 15, 6, -13, +0, -17, -7, 8, 5, 12, 0, -3, +-1, -17, 6, -7, 0, 12, -1, 11, +0, -10, 0, -15, 3, 8, 5, 14, +-1, -3, -2, -13, 2, -1, -2, 15, +2, 3, 3, -15, -1, -12, 2, 10, +-2, 15, -3, -10, 1, -18, 2, 2, +-2, 15, 2, 0, 3, -16, -3, -6, +2, 11, 6, 10, -5, -7, 0, -13, +7, 4, -3, 16, 2, -2, 4, -17, +-6, -2, 3, 15, 4, 6, -7, -13, +3, -11, -1, 11, -8, 13, 9, -10, +1, -17, -7, 2, 6, 17, -2, 3, +-6, -15, 10, -9, -1, 11, -1, 11, +10, -9, -5, -15, -1, 4, 9, 16, +-6, -3, 6, -20, 5, -1, -11, 15, +2, 9, 3, -12, -9, -14, 6, 6, +6, 12, -11, 0, 2, -14, 2, -2, +-10, 19, 5, 8, -3, -11, -6, -9, +13, 8, 1, 11, -1, -11, 10, -16, +-4, 3, -2, 17, 3, 6, -6, -16, +0, -7, 5, 12, -7, 11, -2, -9, +4, -15, -4, 7, -4, 18, 3, -4, +-4, -15, 0, -2, 4, 15, -2, 6, +4, -15, 3, -9, -3, 11, -2, 18, +0, -4, 0, -17, 2, 1, 0, 18, +-7, 5, 0, -16, 4, -9, -5, 13, +0, 10, 5, -11, -3, -16, 1, 5, +3, 15, -7, 1, 3, -14, 4, -3, +-4, 11, 6, 10, -4, -5, -8, -11, +11, 5, 3, 11, -4, -5, 4, -11, +-3, -1, -7, 16, 6, 4, -5, -12, +-7, -6, 7, 11, -5, 9, -2, -8, +6, -11, -7, 2, 4, 11, 8, 4, +-12, -11, 3, -3, 4, 14, -7, 7, +6, -10, 6, -13, -10, 9, 5, 14, +0, -2, -12, -11, 7, -3, 0, 11, +-4, 2, 8, -13, -6, -7, -4, 7, +10, 9, -6, -3, 0, -16, 12, -1, +-3, 12, 5, -2, 7, -12, -3, -6, +1, 12, 7, 5, -2, -9, 3, -12, +2, 6, -8, 15, -1, -1, 1, -13, +-5, -1, -1, 12, 0, 6, -5, -9, +-1, -8, 3, 7, -4, 13, -1, -3, +6, -14, -1, 1, -1, 13, 6, 1, +-1, -12, 3, -6, 6, 7, -1, 5, +4, -9, 6, -12, -8, 5, 0, 12, +-1, 3, -11, -8, -1, 0, 1, 9, +-7, 5, 1, -4, -1, -7, -6, 5, +8, 9, 2, -5, -2, -12, 9, 0, +0, 8, -2, 4, 6, -7, -1, -10, +0, 7, 6, 9, -8, -5, -1, -9, +3, 4, -9, 9, 0, 2, 3, -10, +-8, -4, 1, 11, 1, 7, -8, -7, +7, -9, 3, 4, -7, 10, 8, -1, +-1, -8, -4, -1, 7, 11, -1, 1, +-1, -9, 7, -6, -4, 6, -3, 8, +3, -2, -8, -8, 0, -1, 4, 8, +-7, 2, 0, -9, 3, -4, -5, 8, +2, 3, 8, -9, -2, -7, 3, 2, +4, 9, -2, 0, 0, -5, 3, -2, +-2, 9, -3, 7, 1, -6, -5, -3, +-1, 4, 1, 7, -4, -3, -1, -9, +1, 0, -5, 9, -3, 2, 3, -7, +-4, -4, 2, 6, 0, 10, -4, -4, +5, -9, 8, -1, 2, 3, 4, 0, +7, -12, 0, -3, 1, 9, -1, 4, +-4, -6, 5, -6, -3, 5, -5, 7, +4, -4, -3, -7, -4, 0, 4, 7, +-7, 5, -4, -2, 3, -2, -2, 2, +2, 6, 4, -2, -2, -8, 5, 3, +2, 8, -6, 0, 6, -6, -1, 0, +-9, 7, 6, 2, -1, -5, -8, -2, +1, 5, -7, 8, -6, -3, 9, -10, +-3, 0, -2, 4, 8, -1, 2, -9, +2, -5, 6, 4, -1, 3, 3, -4, +6, -5, -2, 1, 2, 6, 3, 0, +-3, -4, -2, 1, 1, 2, -3, 4, +-2, -2, -1, -6, -1, 1, -1, 4, +1, -4, 1, -5, -1, -1, 1, 3, +4, -2, 4, -6, 1, -3, 5, 1, +1, 5, 2, -3, -1, 0, -4, 4, +-1, 6, -2, 3, -1, -4, -1, -2, +1, 1, 0, 2, -5, 0, -2, -4, +1, -1, -1, 5, -3, 1, 0, -4, +-1, -1, 4, -1, 4, 2, 0, -4, +2, -2, 3, 3, 0, 2, 2, -2, +6, -6, 0, -2, -1, 7, 2, -2, +-2, -4, -2, 0, -1, 4, -8, 5, +-1, -1, -3, 0, -4, 1, 4, 0, +2, 1, -7, -1, 5, -3, 4, 1, +0, 1, 3, -2, 4, -5, -1, 4, +4, 1, 3, -4, 2, -4, 3, -1, +-3, 5, -5, 6, -6, 2, -5, 0, +1, 2, -4, 3, -2, -1, -2, -1, +-2, 1, 0, 2, 3, -1, -3, -1, +3, -2, 2, 4, -2, 1, 5, -6, +6, -3, -1, 1, -1, 6, -2, 2, +-2, -4, 1, 0, 2, -1, -2, 0, +-4, 3, -1, -4, -1, 1, 1, 0, +0, -2, -6, 3, 0, 1, 2, 1, +0, 1, 2, -4, 1, 1, -1, 3, +2, 1, 2, -2, 0, 0, -1, 3, +2, 1, 1, -2, -1, 0, -5, 3, +1, 1, 0, -2, 1, -3, -1, -1, +-2, 1, 1, 0, 2, -3, 1, -5, +4, 1, -3, 4, 0, 0, 2, -2, +2, -2, 2, 2, 4, -1, 1, -1, +-2, 0, 3, -3, 1, 3, 0, -2, +-2, 1, -6, 4, 1, -1, 0, 0, +-1, -2, -1, -1, -1, 4, -2, 3, +0, 0, -1, -1, 1, 1, -1, 5, +-1, -1, 5, -5, 3, -2, 0, 0, +3, 2, -4, 1, -2, -1, 2, 1, +1, 0, -3, 2, 1, -4, -3, 3, +-7, 8, 0, -1, 0, -1, 0, -2, +0, 2, -1, 3, -1, 0, 1, -2, +3, -1, 2, 1, 2, -1, 5, -7, +2, -1, -2, 4, 0, 0, 4, -4, +0, -2, -1, 2, 2, -1, -1, -1, +-3, 1, 2, -3, -4, 5, -2, 3, +-2, -1, -3, 1, 1, 1, -1, 2, +-1, 0, 3, -3, 1, 1, 0, 2, +3, -3, 2, -2, 1, -4, 4, 0, +2, -1, -1, -1, -2, -1, 4, -4, +0, 0, 3, -3, 0, -1, -5, 5, +-2, 1, 1, 1, -5, 2, 1, -4, +2, 3, -1, 1, 2, -4, 4, -2, +1, -2, 0, 3, 2, 0, 0, -2, +-2, 1, 4, -1, 0, 0, -1, -1, +-2, 1, -3, 4, -2, 0, 4, -2, +0, -2, 1, -3, 3, 2, 0, 0, +-1, -1, 0, 3, -1, 0, -1, 4, +1, -3, 6, -6, 1, 0, 0, 1, +2, -2, 4, -5, -2, 0, 1, 2, +0, -2, -1, 1, 1, -2, 1, -1, +-1, 0, 6, -4, -1, -2, 1, -2, +6, -3, 1, 1, -1, -3, 3, 0, +-1, 0, 3, -2, 1, 3, -1, -1, +-4, 2, 3, 2, -3, 0, -5, 3, +1, -1, 2, -2, -5, 6, 0, 0, +-4, 2, -4, 2, 4, -3, 2, 0, +-3, -1, 3, 0, 0, 2, 0, -2, +2, 0, 0, 0, 1, -4, 6, -2, +4, -5, 1, -1, -4, 3, 3, -2, +-1, -1, 2, -3, 4, -2, 0, -2, +2, -3, 6, -3, -2, -3, 2, 0, +1, 3, -4, 0, -1, 1, 4, -2, +-4, 3, 0, 1, 2, -1, -2, 0, +1, -1, 2, 0, -2, 1, -2, -1, +1, 3, -4, 3, -1, -1, 2, 1, +1, -4, -1, 1, -1, 4, -2, 1, +-3, 1, 3, -2, 2, 1, -7, 4, +2, -2, 3, 0, -4, 0, 3, 0, +2, -1, -1, -4, 5, 0, 1, 0, +-6, 2, 3, -1, 2, -1, -5, 1, +3, -1, -2, 2, -2, -1, 2, 1, +-1, 3, -5, 2, -2, 2, 1, 0, +-1, -2, 3, -2, 3, 1, -3, 0, +1, 1, -1, 2, -3, 1, 0, -2, +5, -3, 0, 1, -5, 4, -2, 3, +2, -2, -1, -3, 3, 3, 0, 0, +-3, 1, 5, 0, 1, -1, -5, 0, +9, -4, 2, -1, -4, 2, 6, -4, +3, -1, -4, 1, 6, -2, 0, 1, +-3, -1, 4, 2, 0, 2, -3, -3, +1, 5, -1, 0, -2, 1, 2, 1, +3, -2, -4, 3, 0, 3, 1, -1, +-2, 3, -3, 2, 5, 1, -3, 2, +-1, 2, 0, 3, 0, -4, 4, -2, +7, -2, -1, -3, 1, 2, 5, -1, +1, -1, -2, 2, 5, -1, 1, 0, +2, 0, 3, 1, 0, 0, 0, -1, +6, 2, 1, -2, 1, -1, 3, 2, +1, 1, -1, 2, 5, -2, 2, -1, +1, 1, 4, 0, 4, 0, -4, 1, +1, 1, 3, 4, -5, 4, 1, -1, +8, -2, -3, 2, 4, 3, 7, -3, +0, -3, 5, 1, 8, 0, -2, 0, +5, -2, 6, 1, -3, 3, 6, -2, +5, 3, -5, 0, 6, -1, 6, 3, +-3, 0, 1, 1, 9, -2, 1, 0, +6, 1, 8, -5, 2, 0, 2, 4, +8, -2, 5, -3, 7, -5, 11, -4, +6, 0, 6, -4, 9, -3, 6, -4, +4, 2, 7, 0, 7, -4, -1, 3, +6, 0, 9, -2, 2, 2, 3, 0, +6, 1, 1, 4, 6, 1, 6, 0, +1, -2, 9, 2, 6, 4, 1, -1, +7, -2, 11, -3, 3, 3, 5, 3, +5, 0, 2, 0, 10, -1, 8, 2, +3, 0, 6, -3, 7, 4, 3, 3, +5, -1, 10, -3, 10, -6, 8, 1, +12, -1, 8, -4, 4, 1, 11, 1, +7, 2, 3, 0, 12, -4, 5, 4, +1, 5, 10, 3, 5, -2, 6, -3, +13, 3, 6, 4, 1, 2, 13, -4, +8, -2, 10, 0, 14, -3, 7, -3, +7, 1, 13, 0, 9, 2, 6, 0, +12, -4, 9, 2, 10, 0, 10, 1, +6, -1, 7, 2, 7, 5, 11, 0, +6, 0, 11, -2, 10, 2, 11, 1, +9, -1, 10, -1, 8, 2, 10, 1, +11, 3, 7, 0, 11, -3, 16, 3, +7, 3, 9, 0, 11, 0, 8, 2, +10, 3, 15, -4, 13, -6, 14, -4, +14, 4, 7, 5, 11, -4, 11, 5, +7, 4, 16, -4, 16, -1, 11, -3, +8, 2, 14, 3, 13, -1, 8, 2, +13, 2, 11, 4, 12, 2, 16, -2, +11, -1, 12, -1, 17, -1, 14, -1, +10, -3, 14, 1, 15, 4, 11, 2, +18, -4, 16, 0, 7, 4, 18, 0, +16, -2, 12, -4, 17, -2, 14, 7, +7, 6, 15, -3, 18, 1, 11, 5, +16, 1, 19, -2, 11, -3, 14, 2, +14, 4, 12, 1, 14, -1, 17, -1, +16, 3, 17, 2, 15, 1, 15, -1, +12, 4, 14, 3, 19, -3, 14, -4, +20, -3, 23, -1, 17, 1, 17, 1, +17, 1, 13, 4, 18, 0, 20, -4, +17, -6, 20, -4, 19, 4, 15, 0, +19, -3, 16, 6, 13, 7, 15, 7, +18, 1, 18, -5, 18, 0, 22, 0, +19, -2, 18, -5, 25, -3, 19, 6, +15, 4, 22, -1, 20, -4, 20, -2, +22, 2, 21, -6, 19, -6, 23, -1, +18, 3, 18, 3, 21, 0, 18, 1, +21, 4, 21, 2, 19, -1, 21, -5, +23, -5, 21, 3, 23, -1, 19, -1, +21, 1, 26, 1, 18, 5, 19, 2, +19, 0, 17, 0, 23, 0, 19, 2, +15, -2, 26, -1, 22, 7, 18, 3, +27, -2, 24, -1, 23, -2, 27, 0, +22, -5, 21, -3, 19, 2, 24, 1, +22, 4, 23, -2, 26, 0, 23, 7, +21, 2, 27, -6, 28, -8, 23, -4, +26, -2, 26, -4, 24, -3, 22, 4, +23, 8, 25, 2, 26, -4, 30, -5, +25, 0, 22, -1, 29, -4, 22, -4, +23, 0, 26, 6, 24, 2, 24, 0, +29, 1, 21, 6, 22, 3, 27, -4, +22, -5, 21, 0, 27, 1, 25, -1, +26, 0, 26, 3, 25, 6, 27, 5, +25, -1, 24, -4, 30, -2, 27, -5, +29, -5, 30, -4, 21, 2, 29, 4, +32, 3, 21, 0, 29, 2, 26, 2, +20, 1, 29, -4, 28, -8, 22, -1, +32, 4, 26, 4, 24, 2, 31, 3, +28, 4, 28, 1, 30, -4, 24, -4, +27, -3, 29, 1, 27, -2, 32, -5, +29, 3, 27, 9, 26, 9, 24, 0, +30, -6, 33, -3, 27, -4, 31, -7, +29, -4, 25, 1, 27, 10, 29, 6, +29, -1, 31, 0, 32, 3, 28, 0, +28, -6, 30, -4, 25, 0, 27, 1, +33, 4, 26, 2, 26, 3, 36, 6, +29, 2, 26, -4, 35, -5, 22, 1, +27, -2, 34, -2, 24, -1, 30, 1, +36, 5, 31, 4, 31, 1, 30, -2, +28, 3, 29, 0, 30, -8, 33, -9, +32, 0, 23, 8, 31, 9, 27, 6, +23, 4, 34, 6, 32, 1, 20, -2, +34, -6, 28, -2, 22, 3, 38, 0, +30, -1, 23, 8, 36, 10, 30, 5, +25, 1, 35, -6, 29, -2, 31, -4, +38, -9, 31, -5, 32, 0, 31, 9, +31, 8, 32, -1, 29, 1, 34, 2, +30, 0, 28, -8, 36, -9, 28, 1, +27, 4, 40, 0, 31, 4, 27, 4, +37, 7, 30, 5, 31, -10, 37, -9, +33, -5, 31, -4, 35, -2, 34, -2, +26, 6, 34, 8, 40, 3, 27, -1, +32, -4, 35, 0, 26, -3, 34, -7, +33, -4, 25, 1, 34, 9, 35, 7, +26, 2, 35, 2, 33, 5, 28, 1, +38, -12, 36, -14, 32, -1, 32, 4, +29, 2, 32, 4, 30, 7, 26, 11, +39, 3, 31, -6, 27, -6, 37, -3, +28, -2, 29, -5, 41, -5, 26, 4, +32, 10, 39, 8, 29, -3, 36, -4, +37, 2, 28, -4, 35, -8, 35, -10, +28, -1, 35, 7, 31, 7, 28, 3, +35, 4, 30, 6, 32, 3, 32, -6, +30, -11, 35, -4, 33, 0, 30, 0, +35, -1, 34, 4, 27, 15, 34, 7, +29, 1, 28, -4, 33, -2, 33, -3, +31, -7, 34, -9, 40, -3, 32, 9, +32, 7, 33, 4, 28, -1, 32, 2, +35, -1, 26, -6, 31, -11, 37, -1, +24, 7, 32, 3, 37, 0, 31, 3, +35, 8, 32, 8, 25, -4, 36, -11, +33, -5, 35, -4, 34, -3, 28, -2, +35, 3, 30, 15, 24, 10, 38, -2, +28, -4, 28, -2, 38, -2, 28, -8, +25, -3, 36, 3, 25, 7, 31, 4, +39, 2, 25, 4, 30, 7, 36, 0, +26, -7, 30, -9, 35, -2, 26, 5, +30, 1, 32, -1, 32, 4, 33, 8, +34, 4, 32, -3, 26, -6, 27, -5, +36, -2, 27, -4, 32, -6, 35, 6, +23, 11, 30, 5, 39, 0, 24, 0, +31, 2, 34, 0, 27, -10, 30, -7, +31, 2, 26, 6, 29, 3, 33, 1, +29, 6, 28, 8, 32, 4, 29, -7, +23, -9, 28, -1, 34, -4, 28, -3, +34, -1, 32, 7, 20, 15, 33, 6, +35, -8, 25, -6, 33, -5, 35, -5, +28, -6, 34, -6, 29, 0, 30, 4, +28, 6, 27, 3, 30, 3, 28, 4, +28, -2, 31, -8, 21, -7, 27, 2, +29, 4, 21, 1, 32, 0, 37, 5, +20, 13, 34, 4, 31, -9, 21, -13, +32, -4, 29, 1, 24, 0, 38, -6, +29, 0, 20, 12, 27, 9, 26, 0, +30, -4, 30, -2, 24, -4, 31, -9, +28, -4, 23, 3, 30, 2, 23, 2, +26, 3, 32, 8, 25, 9, 32, -4, +29, -11, 17, -11, 28, -4, 26, 6, +26, 2, 32, -2, 24, 4, 23, 9, +27, 7, 23, -2, 25, -7, 24, -6, +26, -4, 30, -4, 27, -4, 26, 4, +24, 7, 19, 1, 27, 1, 32, 3, +25, 6, 28, -1, 24, -9, 16, -7, +23, -1, 24, 2, 30, 0, 30, 3, +21, 6, 24, 7, 23, 1, 24, -9, +25, -8, 19, -2, 21, 1, 31, -5, +25, -5, 27, 5, 24, 14, 12, 6, +18, -2, 28, -6, 28, -3, 31, 2, +26, -3, 15, -6, 18, -5, 18, 3, +23, 6, 29, 12, 16, 14, 16, 3, +16, -5, 19, -4, 25, -2, 18, 2, +20, 0, 26, -7, 18, -2, 29, 9, +27, 17, 8, 6, 18, -15, 21, -14, +17, 5, 30, 15, 23, 6, 13, -8, +20, -12, 14, 0, 17, 10, 30, 11, +24, 3, 25, -14, 21, -12, 17, -1, +23, 2, 18, 1, 22, -9, 28, -10, +17, 3, 23, 14, 25, 12, 13, -2, +17, -15, 16, -16, 18, 0, 33, 12, +23, 7, 12, -5, 19, -4, 10, 4, +13, 4, 21, 2, 24, -3, 22, -3, +19, -2, 15, 1, 18, -3, 18, -5, +15, -1, 16, 5, 12, 11, 27, 0, +24, -3, 10, 2, 15, -5, 9, -6, +10, 0, 30, 2, 24, 0, 21, 1, +13, 11, 1, 7, 10, -8, 20, -14, +20, -4, 21, 12, 12, 10, 13, -2, +14, -1, 11, 0, 13, 4, 12, 5, +13, 1, 22, -1, 21, -5, 18, 0, +14, 7, -1, -1, 0, -5, 22, -1, +23, 11, 20, 14, 16, 5, -2, -2, +4, -12, 13, -13, 17, -2, 30, 7, +20, 3, 9, -3, 12, 1, 10, 9, +15, 3, 16, -9, 8, -11, 13, 0, +17, 5, 18, 5, 20, 3, 8, -9, +2, -14, 9, 2, 14, 18, 26, 12, +24, -1, 4, -10, -1, -7, -3, -6, +11, -6, 27, 3, 27, 6, 13, 8, +2, 9, -5, 11, 10, -2, 21, -19, +14, -16, 14, 1, 11, 6, 9, 3, +17, 4, 13, 3, 2, 3, -3, -2, +6, -2, 24, 0, 29, 2, 14, 3, +0, 0, -12, -12, 5, -26, 23, -7, +23, 24, 22, 28, 6, 6, -5, -12, +6, -9, 6, -8, 10, -4, 16, 5, +8, -2, 10, -10, 21, -1, 7, 20, +0, 19, 0, -7, 1, -26, 22, -12, +29, 10, 14, 14, 5, 4, -12, -11, +-4, -27, 13, -12, 17, 21, 22, 33, +14, 11, -2, -12, 2, -12, 0, -6, +1, -7, 16, -6, 12, 3, 10, 4, +18, 2, 3, 12, -2, 15, 4, -7, +3, -24, 12, -11, 19, 10, 11, 9, +13, -4, 2, -3, -9, -6, -3, -11, +9, -3, 23, 16, 24, 20, 9, 8, +-5, -5, -15, -13, -4, -22, 17, -17, +17, 9, 15, 22, 7, 8, -5, -4, +4, 2, 8, 5, 5, -12, 9, -17, +1, -3, 11, 2, 22, 4, 8, 10, +-8, 8, -18, -12, -10, -24, 22, 3, +34, 32, 20, 24, -5, -4, -26, -24, +-13, -28, 20, -15, 23, 7, 21, 19, +-1, 15, -17, -2, -1, 3, 10, 13, +4, -1, -1, -19, -9, -16, 8, 4, +25, 15, 17, 8, 0, 1, -17, -12, +-23, -20, 11, -4, 32, 26, 23, 28, +4, 0, -23, -18, -22, -18, 13, -17, +17, -7, 11, 12, 6, 23, -7, 15, +2, -4, 11, -5, -4, -3, -7, -14, +-4, -10, 13, 7, 21, 12, 12, -2, +-3, -2, -20, 7, -18, -4, 14, -20, +25, -3, 13, 28, 2, 23, -14, -1, +-7, -19, 7, -25, 2, -24, 2, 2, +3, 35, 5, 32, 11, -1, 5, -21, +-13, -6, -18, 5, -5, -3, 20, -5, +25, 2, 8, 3, -8, 5, -24, 12, +-12, -2, 14, -26, 10, -11, 10, 26, +9, 37, -8, 5, 1, -29, 2, -30, +-10, -15, -2, 3, 10, 17, 13, 21, +19, 1, 0, -12, -19, 1, -12, 7, +-1, -12, 13, -21, 17, 1, -1, 24, +-4, 14, -7, -2, -4, -14, 3, -21, +-3, -9, 2, 25, 14, 39, 12, 5, +9, -30, -11, -25, -30, -3, -11, 2, +17, 0, 28, 14, 23, 19, -15, 7, +-29, -8, -8, -6, 12, -12, 23, -17, +13, -3, -10, 16, -12, 10, 3, -9, +10, -3, 4, 3, -14, -4, -17, -2, +7, 13, 27, 20, 24, 6, -10, -13, +-34, -24, -20, -31, 10, -15, 34, 29, +29, 56, -10, 19, -25, -34, -18, -37, +5, -4, 25, 17, 14, 11, -5, -5, +-5, -14, -5, -13, 5, 10, 5, 29, +-9, 8, -8, -27, 8, -19, 7, 27, +15, 32, 0, 3, -19, -28, -14, -37, +-6, -20, 11, 19, 20, 54, 4, 39, +-1, -18, -9, -39, -15, -14, 0, 7, +6, 2, 13, -2, 20, 6, -2, 4, +-15, -7, -14, 0, -12, 10, 11, 4, +22, 3, 3, 11, -4, 3, -9, -14, +-8, -18, 8, -1, 8, 1, -1, -10, +-5, 3, 2, 26, 12, 30, 5, 10, +-6, -18, -17, -30, -17, -29, 8, 0, +28, 39, 16, 39, -6, -11, -21, -46, +-23, -16, 6, 28, 23, 33, 18, 8, +6, -16, -15, -27, -14, -20, 5, 11, +6, 20, 4, -5, 0, -17, -8, 17, +-2, 38, 8, 16, 3, -19, -3, -30, +-15, -19, -2, -4, 9, 21, 10, 28, +11, 4, -6, -20, -22, -5, -11, 21, +0, 10, 10, -7, 16, 3, -1, 15, +-16, 6, -13, -14, -12, -20, 6, -10, +17, 10, 6, 35, -2, 37, -5, -5, +-7, -41, -6, -23, -5, 16, 1, 24, +3, 1, 2, -9, 0, 0, -8, 10, +-11, 20, -3, 20, -5, -5, 5, -34, +10, -11, -3, 35, -8, 39, -8, -7, +-10, -43, -3, -23, 2, 14, -2, 41, +3, 45, -1, 12, -5, -33, -10, -32, +-18, 4, -10, 26, 5, 11, 14, -7, +13, 1, -12, 12, -27, 6, -18, 9, +1, 8, 20, -5, 15, -11, -13, 5, +-25, 21, -18, 5, 5, -15, 14, -1, +-3, 10, -25, 12, -18, 14, 4, 22, +21, 13, 10, -13, -27, -20, -36, -9, +-15, 7, 16, 13, 37, 20, 6, 21, +-38, -3, -47, -12, -15, 5, 22, 20, +28, 12, -3, 0, -34, 6, -32, -1, +-5, -11, 18, -3, 8, 19, -16, 21, +-20, 5, -18, 7, 9, 9, 13, -1, +-12, -4, -22, 5, -23, 4, -10, -11, +17, -5, 9, 27, -10, 37, -22, 11, +-28, -17, -17, -16, 9, -4, 11, 18, +-3, 38, -16, 19, -23, -24, -26, -35, +-9, 1, 2, 48, 2, 42, -6, 10, +-17, -10, -28, -18, -19, -12, 4, 13, +4, 37, -17, 19, -25, -25, -23, -22, +-8, 26, 12, 53, -11, 36, -35, -8, +-37, -35, -25, -26, 12, 27, 19, 71, +-11, 39, -44, -38, -49, -61, -21, -1, +13, 65, 19, 73, -5, 23, -48, -37, +-52, -56, -21, -11, 11, 60, 18, 72, +-17, 1, -59, -56, -39, -28, 3, 52, +12, 78, -4, 27, -48, -41, -58, -64, +-8, -9, 31, 75, 11, 88, -40, -4, +-70, -85, -44, -45, 10, 58, 27, 102, +-12, 48, -55, -34, -60, -66, -18, -23, +6, 66, -4, 83, -22, -1, -43, -74, +-29, -38, -1, 69, -12, 103, -27, 27, +-52, -65, -40, -77, 0, 12, 8, 99, +-14, 97, -53, -14, -67, -105, -34, -47, +7, 85, 11, 133, -30, 32, -67, -80, +-53, -77, -7, 23, 10, 109, -26, 79, +-68, -34, -61, -103, -8, -27, 26, 119, +-10, 136, -73, 0, -93, -121, -35, -79, +32, 66, 27, 138, -38, 68, -98, -65, +-81, -106, -11, -5, 27, 120, -4, 118, +-62, -19, -84, -101, -45, -33, 12, 83, +-2, 103, -59, 16, -79, -63, -54, -58, +5, 30, 17, 103, -38, 78, -85, -17, +-76, -87, -17, -29, 17, 65, -15, 85, +-63, 28, -78, -38, -39, -34, -6, 11, +-32, 67, -63, 71, -68, 6, -36, -40, +-6, -9, -22, 57, -66, 57, -85, -3, +-46, -31, -9, -5, -6, 46, -47, 63, +-97, 36, -74, -8, -20, -26, -4, 17, +-31, 51, -78, 30, -88, -13, -42, -8, +9, 43, -11, 53, -85, 15, -113, -22, +-69, -6, 1, 38, 27, 58, -45, 51, +-126, -9, -109, -46, -35, -6, 18, 59, +-4, 81, -84, 17, -113, -27, -66, -7, +-13, 32, -10, 53, -57, 23, -94, -7, +-72, -23, -31, 14, -11, 71, -48, 58, +-94, -4, -93, -41, -57, 4, -14, 62, +-21, 63, -64, 25, -95, -21, -85, -18, +-40, 18, -32, 55, -48, 50, -75, -1, +-86, -8, -45, 29, -38, 64, -68, 33, +-88, -24, -83, -13, -41, 30, -24, 57, +-47, 45, -95, 16, -104, -10, -63, -2, +-35, 36, -44, 46, -71, 26, -79, 14, +-69, 25, -57, 26, -68, -4, -81, -4, +-68, 39, -51, 62, -52, 34, -68, -16, +-76, -5, -78, 43, -81, 58, -71, 27, +-65, -22, -53, -15, -39, 41, -65, 83, +-107, 46, -105, -38, -67, -32, -36, 42, +-37, 83, -70, 40, -107, -15, -97, 3, +-68, 29, -64, 30, -52, 7, -62, 15, +-83, 49, -84, 50, -96, 28, -73, -15, +-52, -6, -58, 38, -79, 51, -106, 21, +-73, -18, -43, 23, -60, 71, -97, 41, +-122, -20, -88, -22, -36, 52, -37, 80, +-82, 28, -122, -20, -107, -6, -68, 47, +-51, 50, -59, 9, -89, -11, -90, 26, +-77, 74, -84, 46, -86, -19, -82, -31, +-76, 38, -76, 86, -75, 28, -80, -26, +-86, 0, -85, 71, -89, 63, -85, -17, +-71, -35, -70, 32, -92, 106, -100, 66, +-86, -33, -76, -49, -77, 25, -102, 102, +-103, 65, -74, -18, -50, -26, -66, 47, +-126, 82, -130, 10, -77, -46, -33, -4, +-41, 88, -113, 93, -153, -2, -103, -48, +-47, 3, -41, 82, -89, 79, -124, -5, +-115, -40, -73, 7, -47, 82, -82, 78, +-107, 1, -106, -42, -107, -4, -77, 69, +-65, 86, -72, 45, -89, -8, -119, -36, +-117, -2, -95, 56, -57, 93, -57, 58, +-94, -26, -113, -43, -118, 24, -100, 108, +-71, 78, -63, -34, -78, -73, -95, 9, +-104, 132, -108, 110, -82, -36, -62, -118, +-85, -17, -115, 156, -105, 158, -75, -3, +-63, -129, -90, -54, -141, 124, -132, 162, +-58, 31, -33, -107, -76, -63, -134, 92, +-141, 151, -75, 59, -44, -80, -88, -80, +-138, 44, -102, 134, -45, 105, -58, -22, +-127, -68, -172, -17, -98, 68, 3, 99, +-24, 50, -132, -5, -195, -33, -127, 5, +-4, 51, -11, 63, -109, 40, -181, -8, +-133, -9, -27, 28, -26, 68, -104, 69, +-162, 11, -135, -31, -64, -24, -36, 58, +-61, 113, -111, 56, -131, -33, -120, -67, +-103, 20, -59, 110, -34, 98, -65, 5, +-132, -72, -164, -24, -112, 77, -34, 120, +-17, 40, -91, -69, -160, -46, -135, 59, +-64, 134, -36, 74, -77, -50, -126, -78, +-132, -1, -85, 119, -48, 134, -63, 21, +-103, -82, -126, -74, -112, 61, -76, 138, +-43, 81, -55, -33, -117, -77, -146, 15, +-122, 102, -59, 108, -14, 11, -76, -81, +-153, -32, -136, 85, -68, 142, -24, 45, +-72, -74, -147, -66, -141, 40, -50, 135, +-5, 89, -85, -20, -166, -77, -139, -20, +-43, 110, 7, 121, -84, 13, -180, -87, +-153, -30, -31, 105, 22, 124, -76, 30, +-184, -79, -173, -57, -49, 67, 33, 141, +-40, 85, -164, -57, -185, -89, -92, 26, +0, 128, -3, 94, -102, -27, -173, -55, +-132, 16, -44, 80, -6, 66, -51, -4, +-134, -17, -158, 9, -88, 55, -6, 62, +-18, 11, -102, -7, -161, 13, -129, 37, +-26, 21, 10, 8, -63, 41, -146, 45, +-146, 8, -63, -23, -4, 20, -48, 79, +-123, 44, -136, -8, -71, -20, -23, 32, +-51, 75, -111, 38, -122, -23, -71, -37, +-38, 50, -55, 119, -97, 49, -109, -71, +-69, -63, -57, 88, -83, 137, -85, 8, +-69, -95, -56, -14, -71, 134, -93, 104, +-103, -44, -68, -111, -32, 13, -60, 176, +-94, 120, -99, -84, -72, -163, -48, 33, +-61, 235, -96, 125, -92, -139, -48, -178, +-38, 83, -72, 252, -105, 82, -101, -168, +-51, -153, -19, 106, -46, 232, -106, 68, +-119, -147, -67, -121, -23, 111, -35, 193, +-91, 14, -122, -143, -62, -46, -8, 164, +-42, 132, -109, -79, -122, -132, -59, 51, +0, 190, -17, 61, -109, -118, -144, -90, +-66, 96, -8, 166, -13, 15, -77, -125, +-126, -58, -87, 134, -28, 165, -27, -27, +-67, -144, -93, -14, -89, 168, -60, 109, +-23, -91, -35, -96, -80, 80, -93, 145, +-79, -2, -46, -112, -18, -16, -33, 135, +-85, 116, -119, -57, -81, -127, -17, 25, +4, 179, -51, 97, -120, -127, -106, -136, +-37, 105, 5, 223, -32, 30, -99, -190, +-118, -92, -65, 160, 7, 194, -6, -13, +-86, -164, -122, -54, -78, 142, -3, 149, +2, -30, -64, -136, -114, -4, -82, 153, +-20, 86, -13, -97, -41, -93, -75, 94, +-86, 145, -53, -16, -31, -118, -29, 0, +-55, 138, -82, 77, -61, -81, -34, -89, +-29, 64, -54, 146, -80, 34, -67, -105, +-19, -71, -13, 91, -65, 137, -91, -9, +-59, -121, -18, -20, -10, 144, -63, 99, +-91, -86, -55, -114, -19, 64, -21, 165, +-53, 25, -68, -133, -58, -70, -36, 115, +-29, 140, -47, -17, -55, -129, -55, -26, +-54, 144, -49, 135, -40, -69, -28, -156, +-44, 22, -67, 186, -74, 83, -29, -127, +12, -115, -33, 78, -99, 167, -89, 28, +-23, -113, 20, -77, -19, 77, -91, 127, +-100, 13, -31, -86, 19, -40, -28, 73, +-86, 86, -88, -4, -25, -57, 20, 13, +-28, 65, -106, 17, -86, -51, 11, -7, +16, 83, -54, 63, -106, -41, -83, -65, +9, 23, 37, 91, -49, 55, -119, -38, +-84, -73, 7, -1, 34, 94, -30, 72, +-99, -40, -88, -83, -11, 2, 22, 75, +-15, 57, -68, -2, -76, -34, -58, -37, +-17, -7, 12, 71, -17, 95, -78, 0, +-99, -112, -42, -53, 23, 118, 5, 140, +-59, -37, -83, -151, -63, -38, -15, 137, +11, 138, -18, -35, -90, -150, -79, -61, +9, 135, 17, 165, -62, -31, -77, -190, +-21, -53, -7, 174, -40, 140, -60, -75, +-38, -147, -6, 3, -19, 124, -55, 78, +-52, -37, -34, -78, -12, -27, -21, 61, +-50, 79, -38, -8, -15, -57, -24, -14, +-61, 40, -61, 7, 8, -4, 37, 50, +-44, 39, -130, -72, -86, -90, 41, 72, +87, 160, -19, 22, -162, -168, -133, -113, +30, 100, 132, 198, 23, 49, -164, -170, +-174, -188, 5, 54, 139, 268, 46, 135, +-140, -199, -170, -274, -21, 54, 98, 295, +60, 133, -80, -181, -144, -217, -70, 9, +52, 200, 52, 155, -57, -60, -102, -199, +-33, -85, 22, 155, -32, 170, -61, -27, +-7, -142, 11, -45, -52, 46, -75, 51, +-17, 55, 13, 39, -19, -68, -37, -122, +-54, 14, -61, 159, -8, 106, 47, -106, +-30, -161, -105, -9, -36, 148, 32, 113, +15, -60, -53, -145, -70, -51, -26, 114, +11, 137, -6, -25, -39, -157, -49, -43, +-42, 154, -33, 96, 11, -135, 37, -126, +-31, 124, -121, 167, -90, -86, 65, -221, +123, 0, -29, 248, -195, 142, -116, -180, +73, -271, 125, 28, 18, 316, -133, 178, +-180, -220, -31, -313, 149, 11, 122, 312, +-95, 217, -215, -152, -94, -340, 107, -104, +149, 314, -27, 341, -171, -129, -131, -439, +17, -98, 102, 381, 64, 269, -68, -218, +-147, -308, -72, 53, 54, 229, 80, 44, +14, -109, -92, -45, -122, 12, -18, -14, +79, 12, 56, 62, -53, 10, -100, -71, +-63, -25, 22, 29, 52, 2, 18, 3, +-65, 79, -110, 28, -25, -165, 77, -124, +51, 171, -84, 252, -118, -89, 8, -316, +81, -59, 4, 279, -81, 205, -84, -157, +7, -273, 63, -15, 32, 248, -58, 139, +-106, -157, -46, -203, 70, 58, 86, 191, +-44, 16, -121, -148, -56, -63, 41, 88, +65, 69, 25, -28, -55, -81, -114, -32, +-67, 53, 91, 96, 118, 11, -28, -132, +-160, -106, -110, 94, 63, 196, 139, -4, +39, -219, -128, -110, -159, 173, -19, 184, +141, -85, 120, -192, -51, -8, -196, 141, +-123, 38, 130, -75, 232, -45, -45, 49, +-276, 36, -116, -48, 175, -70, 193, 38, +-35, 125, -190, 1, -145, -156, 57, -100, +203, 137, 84, 166, -186, -31, -208, -182, +47, -93, 207, 104, 64, 162, -130, 38, +-145, -163, -9, -163, 103, 40, 122, 222, +-8, 90, -197, -165, -114, -208, 137, 45, +174, 227, -37, 78, -162, -161, -80, -157, +69, 55, 110, 128, 11, 70, -90, -77, +-66, -111, 23, -29, 61, 104, 16, 78, +-29, -69, -10, -94, -14, 28, -30, 77, +4, -37, 77, -51, 11, 44, -99, 86, +-38, -60, 66, -142, 33, -9, -11, 187, +-3, 117, -15, -152, -51, -225, -2, 9, +81, 238, 39, 164, -67, -94, -91, -277, +21, -144, 104, 205, 61, 363, -68, 11, +-106, -419, -14, -293, 103, 240, 124, 442, +-4, 67, -155, -377, -110, -348, 92, 96, +194, 435, 54, 217, -173, -299, -143, -401, +77, 20, 160, 367, 39, 183, -51, -168, +-73, -241, -60, -38, 21, 127, 140, 132, +106, 24, -102, -90, -182, -113, 3, -17, +198, 81, 120, 63, -95, 0, -131, -42, +31, -45, 68, -57, 3, 21, 25, 100, +77, 61, -25, -84, -132, -116, -18, 7, +159, 75, 117, 41, -73, -2, -112, -13, +-4, -83, 80, -79, 72, 75, 24, 170, +-17, -12, -40, -213, -42, -99, 37, 178, +113, 159, 82, -127, -57, -177, -132, 65, +-9, 161, 139, -56, 111, -150, -28, 41, +-77, 140, -18, -20, 46, -150, 41, -40, +46, 84, 55, 76, 2, -13, -70, -82, +-38, -72, 61, 7, 124, 98, 58, 60, +-78, -57, -103, -107, 16, -25, 142, 75, +112, 79, -36, -23, -119, -103, -19, -41, +115, 62, 111, 63, -15, -39, -57, -66, +8, 0, 58, 71, 16, 8, -17, -106, +29, -81, 103, 114, 55, 192, -101, -89, +-101, -315, 77, -81, 212, 359, 103, 281, +-149, -245, -216, -453, 57, -20, 306, 433, +158, 280, -179, -235, -219, -439, 44, -72, +228, 350, 165, 301, -36, -130, -166, -349, +-87, -149, 132, 180, 202, 262, 49, 57, +-122, -203, -78, -258, 84, 5, 117, 238, +12, 184, -18, -120, 31, -258, 54, -84, +24, 175, -49, 203, -20, -61, 121, -231, +156, -84, -38, 198, -183, 142, -32, -141, +233, -200, 206, 82, -82, 202, -230, -37, +-19, -236, 258, -46, 179, 234, -102, 90, +-150, -210, 48, -175, 155, 159, 61, 165, +-46, -110, -9, -171, 75, 67, 66, 132, +-23, -74, -27, -146, 53, 30, 118, 152, +55, -6, -59, -167, -47, -77, 74, 133, +120, 85, 36, -123, -19, -118, 12, 103, +23, 96, -4, -132, 63, -137, 129, 108, +57, 165, -110, -80, -100, -206, 126, -37, +243, 159, 43, 111, -182, -84, -94, -166, +153, -35, 202, 103, -4, 64, -99, -56, +35, -43, 115, 4, 1, -49, -45, -104, +78, 46, 164, 192, 22, 32, -137, -252, +-47, -229, 157, 145, 192, 307, 15, 41, +-127, -292, -75, -221, 106, 80, 172, 232, +78, 95, -42, -121, -50, -221, -11, -91, +40, 141, 148, 166, 181, -11, -24, -172, +-204, -105, -61, -8, 233, 62, 286, 80, +-13, 48, -265, -91, -98, -191, 253, -42, +252, 183, -55, 166, -188, -126, 28, -249, +197, -31, 84, 194, -67, 67, -4, -154, +119, -115, 60, 88, -55, 94, 2, -110, +129, -159, 96, 39, -14, 203, -51, 24, +48, -265, 115, -201, 55, 166, -24, 285, +18, -51, 98, -303, 61, -136, -25, 147, +-39, 148, 79, -12, 185, -97, 70, -107, +-152, -68, -95, 29, 181, 136, 238, 47, +-24, -132, -143, -181, 18, -6, 151, 146, +90, 87, -6, -115, 35, -196, 91, -19, +-17, 149, -78, 80, 101, -158, 234, -145, +55, 65, -183, 143, -100, -67, 198, -191, +272, -9, 9, 143, -197, 29, -60, -172, +212, -88, 207, 99, -51, 85, -150, -136, +57, -132, 219, 107, 81, 156, -118, -123, +-65, -287, 160, -12, 197, 279, 5, 152, +-129, -248, -8, -338, 170, -22, 164, 320, +-13, 236, -75, -207, 17, -414, 82, -91, +85, 339, 84, 240, 63, -179, -45, -324, +-84, -52, 74, 162, 235, 91, 110, -44, +-113, -79, -136, -47, 113, -68, 238, -45, +56, 29, -125, 95, -4, 19, 181, -119, +78, -161, -103, -53, -12, 109, 211, 149, +144, 16, -99, -215, -153, -237, 111, 4, +281, 265, 105, 175, -166, -179, -130, -346, +148, -128, 240, 234, 89, 273, -95, -33, +-82, -338, 72, -261, 176, 97, 83, 307, +-32, 128, -13, -237, 72, -328, 65, -52, +23, 252, 56, 195, 68, -107, 38, -265, +-8, -125, 27, 81, 105, 127, 105, 60, +-8, -85, -44, -185, 52, -151, 150, 70, +109, 207, -39, 60, -55, -220, 89, -267, +137, 9, 14, 218, -14, 144, 99, -128, +75, -237, -50, -142, -18, 77, 177, 200, +187, 103, -77, -168, -196, -333, 96, -100, +344, 261, 109, 290, -211, -142, -128, -392, +189, -166, 242, 213, 49, 228, -82, -29, +-14, -195, 77, -194, 58, -59, 56, 99, +105, 194, 102, 5, -29, -231, -93, -229, +41, 18, 218, 167, 163, 107, -40, -40, +-135, -192, -9, -202, 190, -28, 180, 210, +35, 161, -38, -114, -17, -287, -5, -169, +57, 76, 184, 222, 220, 160, -4, -153, +-261, -410, -127, -235, 305, 305, 421, 478, +26, -45, -333, -594, -179, -391, 232, 316, +363, 528, 104, 8, -120, -517, -125, -339, +-22, 190, 122, 347, 255, 14, 210, -277, +-98, -171, -279, 41, -37, 73, 373, -40, +346, -15, -88, 33, -309, -76, -8, -208, +284, -49, 185, 212, -18, 106, -36, -223, +49, -246, 24, 82, 34, 168, 99, -58, +115, -165, 30, -5, -4, 54, 12, -70, +37, -96, 93, 12, 109, 60, 57, -48, +-31, -110, 31, -64, 86, 38, 51, 40, +16, -67, 115, -123, 142, -32, -30, 87, +-138, 11, 45, -142, 275, -142, 192, 54, +-50, 141, -149, -35, -48, -225, 124, -145, +281, 108, 216, 157, -88, -20, -258, -210, +-77, -182, 273, 19, 389, 193, 114, 106, +-267, -181, -299, -279, 118, -56, 472, 197, +289, 131, -185, -87, -326, -211, -26, -135, +299, 34, 313, 141, 87, 73, -142, -127, +-195, -215, -4, -101, 260, 113, 317, 154, +72, -16, -199, -215, -199, -188, 81, 25, +354, 159, 262, 82, -91, -127, -249, -231, +-18, -117, 252, 134, 270, 170, 16, -48, +-151, -234, -37, -149, 132, 48, 141, 137, +91, 72, 50, -130, -38, -246, -19, -106, +100, 192, 127, 189, 70, -117, 30, -312, +16, -142, 21, 168, 70, 228, 85, -22, +62, -327, 10, -245, 41, 137, 129, 305, +84, -16, -46, -336, -54, -216, 138, 125, +214, 204, 70, -14, -102, -181, -73, -150, +80, -11, 204, 49, 191, 39, 0, -8, +-154, -65, -89, -140, 178, -128, 301, 42, +158, 183, -146, 64, -236, -244, 0, -304, +301, 28, 371, 327, 46, 139, -319, -300, +-282, -365, 218, 36, 500, 324, 249, 108, +-262, -247, -386, -254, 25, 2, 484, 120, +372, 46, -175, -30, -331, -72, -7, -123, +279, -119, 217, 13, 97, 152, -17, 102, +-157, -166, -139, -339, 206, -93, 431, 329, +121, 282, -309, -268, -271, -500, 219, -45, +448, 422, 123, 228, -268, -282, -168, -392, +200, -36, 268, 258, 50, 145, -97, -140, +-11, -223, 102, -55, 110, 46, 31, 10, +18, 5, 81, 41, 69, -68, -28, -214, +-10, -109, 152, 159, 155, 206, -37, -86, +-118, -321, 87, -183, 252, 173, 58, 265, +-159, -24, -48, -305, 215, -215, 223, 82, +-3, 183, -180, 61, -30, -107, 212, -199, +187, -167, 7, 57, -40, 242, 15, 73, +-7, -278, 42, -291, 168, 69, 196, 259, +-21, 73, -227, -218, -75, -255, 333, -51, +381, 201, -95, 174, -376, -153, -63, -312, +362, -49, 331, 229, -6, 76, -247, -164, +-164, -143, 167, -9, 326, 1, 144, 27, +-116, 54, -157, -62, -30, -171, 174, -78, +261, 97, 92, 87, -143, -34, -149, -151, +57, -146, 233, -15, 217, 150, -6, 108, +-196, -119, -115, -260, 184, -111, 329, 180, +63, 203, -214, -83, -102, -305, 164, -116, +178, 151, 65, 126, -42, -54, -46, -116, +63, -96, 135, -62, 34, 51, -56, 87, +60, -43, 118, -132, 38, -51, -30, -16, +46, -32, 79, 60, 32, 70, -14, -138, +53, -208, 125, 71, 32, 180, -102, -91, +-3, -215, 235, 41, 135, 152, -165, -103, +-152, -200, 193, 29, 283, 161, 2, -29, +-194, -172, -43, -110, 198, 25, 154, 113, +-44, 64, -81, -124, 102, -227, 121, -10, +-39, 189, -75, 48, 130, -170, 176, -74, +-37, 41, -126, -83, 48, -92, 189, 148, +81, 152, -56, -235, -47, -307, 37, 93, +71, 290, 108, 5, 97, -217, -52, -126, +-142, -32, 46, 34, 219, 147, 108, 80, +-42, -242, -43, -264, -46, 102, -8, 245, +189, -17, 238, -162, -86, -61, -285, -92, +32, -96, 346, 161, 131, 291, -201, -138, +-106, -487, 142, -129, 115, 410, -4, 310, +25, -225, 46, -393, -3, -88, -15, 205, +8, 154, 97, -2, 145, -100, 5, -184, +-148, -166, -31, 103, 169, 313, 154, 30, +-7, -346, -102, -244, -82, 153, 91, 221, +232, 29, 87, -114, -192, -186, -156, -159, +188, 91, 274, 293, -42, 39, -197, -324, +48, -277, 162, 152, -24, 341, -63, 41, +127, -363, 108, -252, -89, 226, -68, 259, +127, -160, 117, -232, -54, 113, -76, 57, +84, -217, 137, 33, -12, 334, -96, -128, +14, -530, 126, 73, 65, 594, -22, -24, +-18, -655, 17, -90, 38, 556, 42, 95, +44, -486, 35, -92, -29, 395, -62, -41, +64, -426, 145, 82, 40, 509, -87, -118, +-62, -633, 14, -23, 111, 610, 159, 124, +33, -512, -185, -193, -131, 270, 176, 78, +256, -167, -25, 84, -191, 120, 0, -247, +121, -263, 26, 219, 2, 357, 109, -81, +10, -388, -168, -168, -81, 229, 223, 277, +267, -33, -56, -282, -312, -139, -115, 100, +253, 63, 315, -5, 30, 114, -264, 33, +-233, -363, 110, -289, 363, 397, 139, 552, +-245, -257, -230, -764, 130, -67, 252, 696, +43, 346, -147, -488, -84, -489, 71, 171, +88, 400, 32, 8, 2, -218, 5, -40, +-56, 23, -36, -107, 115, -7, 160, 225, +-93, 53, -184, -304, 124, -183, 260, 246, +-119, 255, -266, -176, 139, -318, 284, 4, +-72, 314, -159, 119, 82, -249, 40, -250, +-110, 101, 63, 216, 232, -31, -30, -89, +-219, 39, -14, -32, 155, -249, 56, 34, +-9, 392, 43, 106, -41, -473, -121, -294, +63, 333, 172, 371, -12, -123, -94, -288, +30, -53, 1, -4, -47, 20, 99, 242, +147, 229, -73, -340, -172, -538, -6, 107, +144, 654, 145, 199, 39, -479, -176, -407, +-215, 126, 82, 316, 348, 143, 105, -82, +-285, -188, -173, -172, 152, 20, 102, 190, +4, 175, 129, -51, 0, -268, -301, -183, +-77, 161, 364, 307, 174, 10, -265, -255, +-141, -196, 183, 94, 45, 215, -166, 107, +52, -202, 263, -214, -50, 116, -316, 257, +9, -101, 333, -256, 52, 104, -274, 197, +-51, -155, 233, -183, 85, 234, -203, 193, +-122, -249, 172, -289, 205, 157, -97, 313, +-223, 39, 41, -279, 186, -250, 18, 120, +-64, 406, -16, 84, -66, -455, -60, -317, +137, 371, 226, 464, -65, -171, -323, -455, +-127, -10, 298, 252, 274, -6, -111, -46, +-259, 236, -29, 64, 81, -511, 53, -308, +97, 525, 74, 596, -139, -335, -175, -674, +81, 47, 212, 542, -14, 96, -127, -341, +25, -91, 24, 158, -115, 14, 26, -115, +291, 124, 36, 140, -384, -168, -248, -286, +322, 121, 414, 351, -48, 63, -434, -238, +-208, -153, 234, -12, 264, -1, -18, 196, +-104, 290, -8, -102, -67, -521, -155, -110, +50, 467, 329, 298, 112, -280, -326, -270, +-309, 79, 227, 132, 357, 7, -106, 44, +-327, 19, 61, -177, 271, -126, -75, 202, +-234, 279, 101, -123, 243, -334, -143, -52, +-249, 307, 95, 124, 278, -170, -8, -121, +-224, 149, -97, 14, 123, -178, 85, -12, +-34, 264, -22, 80, 77, -247, -19, -153, +-190, 119, -80, 181, 189, 3, 248, -62, +-32, -117, -314, -16, -221, 62, 228, 123, +323, -18, -91, -49, -282, -37, 60, -19, +154, -2, -192, 69, -109, 84, 320, -43, +183, -67, -377, -36, -308, 65, 254, 12, +356, 4, -72, -18, -266, 85, -87, -16, +50, -154, 102, -69, 137, 270, 27, 190, +-207, -304, -198, -342, 43, 260, 273, 498, +157, -129, -122, -525, -323, -75, -132, 479, +201, 190, 335, -296, 50, -197, -377, 236, +-314, 89, 234, -252, 422, -50, -112, 386, +-363, 93, 23, -454, 273, -192, -83, 451, +-196, 294, 106, -391, 182, -344, -142, 266, +-187, 427, 89, -116, 168, -403, -68, -80, +-155, 378, 62, 208, 72, -258, -72, -284, +-90, 178, 133, 285, 82, -93, -112, -236, +-186, 34, 27, 162, 158, -14, 140, -32, +-63, 35, -250, -36, -145, -91, 175, 57, +296, 110, -36, -28, -272, -59, -146, 34, +138, 7, 131, -94, 31, 30, -104, 173, +-79, 33, -45, -197, 61, -106, 69, 154, +6, 153, -79, -36, -71, -113, -8, -25, +70, -24, 97, 26, -83, 143, -157, 120, +3, -142, 182, -245, -13, -5, -179, 257, +-13, 206, 178, -97, 5, -286, -167, -143, +-101, 265, 91, 330, 115, -112, 5, -446, +-71, -14, -76, 460, -40, 145, -14, -435, +101, -193, 78, 381, -69, 210, -138, -349, +21, -183, 46, 364, -6, 186, 12, -379, +4, -233, -88, 360, -40, 291, 145, -263, +70, -292, -245, 210, -219, 256, 248, -187, +326, -282, -144, 201, -368, 377, -2, -98, +177, -452, 11, -63, -17, 437, 74, 222, +-61, -336, -173, -291, -22, 286, 137, 321, +74, -272, -118, -411, -104, 276, 112, 525, +120, -169, -180, -577, -239, 64, 154, 519, +298, -25, -51, -446, -292, 46, -69, 444, +170, -31, 67, -432, -148, -61, -53, 377, +157, 160, 44, -253, -216, -184, -119, 182, +139, 230, 133, -168, -78, -309, -110, 120, +-3, 436, 20, 5, -28, -453, -32, -124, +67, 390, 33, 165, -99, -339, -117, -152, +72, 346, 101, 256, -33, -342, -124, -412, +-31, 206, 56, 546, 37, 19, -42, -539, +-58, -172, -26, 465, 14, 255, 43, -421, +-13, -263, -107, 387, -76, 318, 153, -348, +86, -321, -169, 282, -187, 327, 113, -237, +134, -304, -67, 217, -92, 329, 45, -158, +-13, -357, -159, 98, -22, 358, 192, -11, +116, -349, -224, -15, -205, 332, 71, 79, +152, -326, -50, -105, -30, 290, 36, 167, +-48, -246, -168, -198, 3, 171, 125, 251, +44, -43, -51, -269, -72, -108, -68, 198, +-49, 277, 70, -79, 42, -296, -35, -77, +-72, 284, 67, 119, -7, -181, -175, -129, +-134, 172, 203, 110, 228, -145, -124, -119, +-314, 120, -59, 157, 169, -85, 82, -126, +-37, 45, -61, 158, -35, -75, -99, -159, +-3, 60, 88, 248, 40, -40, -150, -279, +-78, -16, 99, 299, 60, 75, -124, -281, +-96, -54, 49, 304, -10, 95, -51, -380, +52, -170, 77, 403, -149, 358, -177, -316, +61, -457, 192, 130, -72, 445, -172, -15, +44, -324, 119, 52, -148, 318, -178, -109, +129, -414, 158, 66, -129, 478, -187, 84, +94, -386, 105, -112, -132, 239, -200, 25, +92, -200, 204, 100, -30, 266, -242, -40, +-89, -264, 132, -67, 42, 110, -136, 94, +-40, 62, 170, 2, 16, -103, -255, -57, +-179, 96, 185, 18, 183, -96, -101, 42, +-157, 175, 30, -58, -8, -224, -134, 50, +-14, 274, 164, -44, 66, -329, -192, -11, +-182, 419, 11, 175, 165, -336, 36, -318, +-140, 140, -136, 267, 84, 51, 99, -72, +-118, -35, -190, -79, 81, -86, 197, 79, +-92, 171, -285, 49, -24, -131, 255, -104, +70, 31, -248, 183, -215, 42, 122, -221, +184, -219, -43, 264, -200, 416, -22, -81, +76, -514, -79, -163, -132, 358, 150, 279, +204, -46, -223, -112, -392, -57, 68, -197, +392, -76, 19, 258, -312, 350, -107, -95, +114, -334, -64, -142, -105, 169, 139, 165, +147, 77, -207, -15, -295, -119, 7, -117, +231, 53, 129, 157, -129, -11, -246, -107, +-119, -20, 158, 122, 159, 54, -94, -6, +-201, -104, 10, -122, 53, 0, -100, 273, +-52, 197, 157, -197, 31, -334, -286, 2, +-204, 249, 210, 125, 279, 24, -128, -6, +-370, -118, -86, -205, 238, 67, 79, 237, +-172, 68, -85, -112, 111, 20, -55, -1, +-237, -201, -16, -84, 277, 329, 47, 300, +-351, -202, -189, -352, 257, -3, 179, 239, +-270, 67, -235, -26, 169, 17, 173, -35, +-203, -149, -180, -11, 143, 193, 116, 137, +-240, -81, -224, -159, 160, -60, 273, 80, +-84, 187, -344, 62, -138, -175, 152, -196, +161, 72, -66, 174, -103, 50, -34, 38, +-26, 42, -169, -198, -96, -287, 194, 167, +255, 501, -157, 93, -445, -471, -122, -319, +322, 201, 232, 341, -220, 86, -272, -123, +32, -144, 131, -62, -138, 62, -115, 113, +174, 68, 138, -35, -333, -84, -342, -77, +229, 30, 438, 130, -122, 86, -546, -76, +-132, -134, 350, 21, 210, 154, -253, 73, +-222, -119, 41, -84, 86, 89, -113, 80, +-77, -120, 61, -54, 52, 184, -96, 108, +-152, -202, -39, -145, 83, 213, 48, 196, +-150, -158, -117, -217, 78, 108, 135, 195, +-176, -27, -233, -174, 20, -15, 257, 123, +-17, 107, -288, -46, -142, -97, 193, -2, +111, 98, -248, 31, -190, -90, 172, -21, +225, 80, -234, 35, -337, -103, 59, -15, +340, 110, -56, 67, -358, -112, -86, -49, +310, 122, 42, 89, -406, -139, -189, -151, +357, 126, 262, 226, -365, -15, -401, -233, +110, -68, 334, 139, -93, 151, -243, 8, +24, -40, 135, -68, -226, -79, -265, -19, +182, 119, 370, 143, -110, -8, -543, -142, +-178, -121, 387, 71, 319, 180, -293, 83, +-399, -124, 26, -108, 292, 48, -45, 72, +-234, -55, -9, -10, 165, 136, -148, 2, +-302, -227, 82, -56, 347, 345, -17, 196, +-451, -291, -214, -301, 231, 173, 242, 274, +-141, -31, -206, -109, -4, 31, 39, -44, +-171, -163, -145, 89, 153, 314, 248, 103, +-111, -245, -423, -212, -186, 23, 248, 164, +259, 147, -114, 57, -249, -106, -87, -216, +39, -88, -38, 166, -23, 277, 52, 70, +23, -186, -147, -242, -191, 2, 16, 190, +187, 175, 16, -28, -263, -159, -156, -109, +135, 63, 136, 117, -138, 22, -199, -7, +-4, 22, 104, 9, -34, -85, -178, -5, +-37, 57, 161, 33, 16, -38, -295, 53, +-188, 32, 191, -100, 223, -95, -153, 135, +-295, 208, -44, -37, 158, -213, 10, -86, +-153, 203, -41, 146, 62, -123, -50, -232, +-158, 107, 4, 261, 66, -6, -77, -288, +-175, -19, 58, 280, 189, 89, -51, -222, +-366, -107, -204, 181, 247, 74, 334, -118, +-109, -75, -424, 140, -191, 55, 170, -89, +154, -72, -58, 144, -68, 136, -33, -89, +-128, -217, -194, 14, 50, 261, 192, 90, +17, -212, -206, -168, -91, 163, -11, 149, +-97, -90, -87, -94, 148, 215, 170, 150, +-156, -240, -382, -339, -130, 150, 257, 475, +223, 111, -108, -427, -284, -330, -126, 256, +36, 390, 81, -41, -15, -319, -20, 21, +-36, 280, -58, -2, -150, -336, -118, -36, +65, 352, 187, 140, 31, -316, -248, -177, +-253, 293, -13, 210, 188, -246, 59, -219, +-107, 262, -104, 269, 5, -183, -132, -304, +-182, 99, 62, 256, 292, -33, 15, -176, +-330, 57, -248, 139, 73, -84, 153, -95, +1, 168, -51, 153, -50, -225, -70, -257, +-174, 196, -76, 383, 107, -44, 173, -399, +-91, -129, -240, 279, -77, 250, 92, -72, +-35, -164, -132, 3, 53, 80, 140, -49, +-78, -83, -304, 112, -128, 165, 152, -76, +204, -210, -50, 43, -219, 194, -190, -9, +30, -149, 114, 95, 1, 186, -102, -90, +-31, -273, 32, -16, -130, 245, -159, 144, +41, -65, 184, -96, -63, -44, -220, -91, +-74, 10, 128, 249, -2, 293, -153, -162, +-95, -476, 67, -185, 95, 393, -56, 426, +-170, -35, -132, -331, 43, -206, 70, 34, +21, 175, -54, 241, -60, 70, -137, -185, +-97, -241, 15, 63, 114, 178, 50, 15, +-119, -115, -186, 64, -80, 139, 117, -39, +51, -160, -120, -4, -135, 119, 108, 7, +41, -1, -199, 110, -153, 63, 180, -251, +109, -234, -215, 152, -171, 396, 132, 70, +103, -269, -177, -182, -120, 118, 67, 145, +45, -19, -158, -65, -43, -5, 117, 54, +90, 29, -185, -2, -230, -76, -22, -52, +204, 9, 111, 100, -134, 103, -186, 87, +-40, -35, 47, -209, -88, -207, -103, 105, +97, 372, 213, 158, -97, -245, -321, -294, +-159, 62, 132, 203, 116, 38, 14, -86, +5, 48, -13, 71, -177, -70, -260, -95, +-23, 64, 261, 63, 212, -132, -143, -83, +-257, 234, -69, 312, 67, -121, -58, -438, +-81, -183, 127, 311, 209, 344, -78, 7, +-372, -189, -196, -116, 221, -65, 272, -47, +-95, 107, -230, 213, -12, 65, 79, -156, +-92, -93, -100, 79, 53, 64, 45, -127, +-118, -119, -94, 119, 120, 277, 112, 93, +-176, -237, -321, -295, -18, 0, 281, 284, +192, 191, -153, -78, -258, -165, -87, 11, +72, 88, 38, -44, -51, -145, -5, 11, +85, 178, 57, 124, -152, -16, -231, -58, +-53, -91, 215, -181, 162, -30, -71, 301, +-162, 307, -34, -167, -30, -401, -79, -27, +9, 331, 146, 75, 53, -276, -137, -58, +-128, 334, -4, 183, 20, -279, -68, -276, +-8, 109, 90, 197, 27, -86, -180, -76, +-109, 233, 100, 214, 75, -263, -178, -436, +-171, 26, 96, 475, 237, 303, -3, -201, +-288, -354, -185, -90, 157, 184, 184, 153, +-130, -12, -167, -81, 113, -7, 199, 21, +-123, 6, -267, 59, -47, 95, 210, -104, +125, -291, -55, -24, -101, 423, -27, 298, +-12, -296, -72, -420, -45, 47, 81, 287, +131, 10, -51, -104, -141, 144, -33, 195, +45, -149, -154, -326, -164, -64, 167, 206, +357, 166, -76, 27, -454, 29, -190, 19, +236, -137, 141, -264, -117, -57, 12, 302, +129, 325, -106, -44, -283, -282, 18, -135, +224, 61, 61, 26, -145, -30, -51, 88, +74, 182, 86, 85, -51, -126, -177, -240, +-105, -139, 173, 135, 250, 268, -21, 93, +-200, -111, -84, -70, 43, -28, -61, -168, +-44, -100, 139, 284, 192, 353, -74, -132, +-239, -390, -114, -14, 47, 261, 12, -30, +-12, -234, 115, 105, 118, 318, -135, -27, +-323, -312, -96, -46, 203, 206, 182, 11, +-61, -189, -110, 62, -13, 306, 20, 55, +-75, -336, -91, -263, 28, 144, 162, 283, +148, 80, -45, -91, -170, -61, -115, -50, +45, -80, 105, 12, 122, 172, 64, 91, +-72, -177, -163, -204, -30, 147, 175, 342, +107, 8, -167, -415, -217, -268, 111, 274, +272, 422, 4, 22, -277, -288, -119, -148, +90, 54, 28, 17, -80, -37, 52, 103, +131, 184, -60, 5, -248, -221, -144, -163, +125, 107, 191, 206, 62, -10, -84, -198, +-81, -7, -86, 233, -40, 66, 52, -258, +144, -161, 74, 148, -27, 161, -51, -2, +-17, 30, -17, 37, 0, -179, 79, -208, +100, 133, 14, 293, -81, 0, -23, -206, +31, -27, 35, 109, 8, -68, -6, -141, +-78, 102, -47, 280, 73, 58, 93, -287, +-67, -293, -162, 78, -42, 362, 72, 183, +30, -222, -62, -297, 11, 20, 54, 241, +-78, 94, -194, -119, -22, -86, 203, 45, +150, 46, -95, -28, -159, -28, 22, 20, +127, 32, 1, -2, -130, -27, 20, -13, +227, 15, 122, 32, -145, 4, -100, 10, +96, 30, 62, -18, -79, -117, 41, -69, +186, 109, 44, 163, -136, -1, -85, -123, +31, -78, -13, -2, -12, 6, 96, 60, +109, 126, -77, 24, -207, -151, -145, -129, +35, 63, 151, 125, 109, 12, -32, -70, +-123, -14, -90, 22, -58, 3, -35, -1, +42, 41, 162, 33, 103, -43, -74, -119, +-149, -59, 7, 138, 112, 241, 11, 14, +-78, -313, 103, -252, 275, 182, 70, 372, +-269, 78, -226, -260, 155, -225, 324, 17, +140, 164, -121, 149, -160, 24, -55, -132, +52, -163, 63, -14, 74, 132, 22, 127, +-61, -2, -82, -105, 5, -89, 39, 28, +-44, 85, -112, -26, -82, -115, 64, 12, +168, 190, 85, 103, -182, -150, -266, -216, +-54, -15, 218, 151, 207, 128, 25, 26, +-124, -22, -134, -93, -38, -148, 126, -25, +206, 180, 93, 114, -63, -146, -84, -106, +25, 194, 75, 143, 73, -260, 40, -261, +45, 174, 31, 271, 22, -60, -21, -81, +-42, 159, -30, -45, 54, -464, 96, -133, +10, 597, -118, 508, -94, -352, 61, -644, +73, -40, -39, 412, -92, 154, -34, -156, +-26, -11, 3, 162, 51, -52, 26, -296, +-89, -122, -79, 239, 57, 267, 136, -29, +15, -154, -124, -12, -55, 13, 117, -184, +169, -177, 20, 235, -78, 451, -1, 31, +127, -456, 110, -293, -6, 193, -68, 224, +21, -67, 138, -21, 108, 220, -48, 18, +-103, -391, 36, -235, 128, 331, 11, 390, +-124, -142, -38, -378, 96, 25, 41, 345, +-127, 70, -121, -326, 39, -211, 118, 215, +32, 299, -79, -51, -126, -246, -125, -32, +-16, 149, 171, -17, 211, -152, -44, 47, +-265, 233, -99, 24, 199, -237, 170, -127, +-36, 120, -26, 101, 92, -36, 32, -15, +-94, 54, -1, 1, 187, -67, 170, -38, +-31, 2, -70, 10, 46, 59, 43, 68, +-63, -41, -9, -104, 159, -13, 144, 47, +-42, -16, -155, -21, -95, 84, -3, 46, +82, -108, 77, -51, 22, 147, -73, 50, +-132, -251, -127, -176, 26, 275, 165, 380, +84, -118, -123, -457, -141, -109, 45, 346, +60, 201, -87, -201, -43, -183, 213, 151, +191, 162, -73, -98, -185, -159, -24, 25, +66, 46, 129, -65, 189, 42, 141, 237, +-87, 81, -209, -297, -40, -294, 202, 139, +247, 342, 36, 24, -140, -259, -123, -53, +47, 244, 97, 71, 19, -299, -70, -225, +7, 210, 76, 332, 19, -1, -115, -205, +-115, -45, -35, 42, 13, -162, 57, -168, +103, 247, 25, 456, -144, -19, -157, -506, +-18, -271, 119, 255, 124, 259, 68, -62, +-65, -42, -118, 144, -5, -27, 156, -285, +107, -103, -34, 213, -31, 148, 93, -89, +102, -18, 5, 156, -24, 12, 7, -293, +26, -243, 53, 179, 119, 423, 104, 116, +-32, -331, -157, -292, -98, 121, 65, 226, +125, -63, 47, -154, -9, 115, -25, 218, +-90, -50, -131, -230, -49, -82, 81, 69, +102, 47, 31, 46, -55, 123, -105, 42, +-65, -187, 8, -221, 39, 40, 51, 244, +118, 125, 81, -93, -93, -114, -183, -40, +-28, -53, 177, -21, 237, 160, 97, 203, +-83, -83, -138, -312, -16, -113, 117, 228, +130, 218, 40, -37, -26, -135, 16, -40, +57, -7, 7, -66, -75, -28, -15, 126, +72, 190, 50, 12, -49, -228, -36, -199, +-2, 84, -14, 219, -37, 38, 25, -121, +29, -12, -43, 82, -67, -74, 2, -167, +45, 28, 7, 224, -31, 90, -43, -126, +-4, -112, 51, 22, 88, 14, 32, -30, +-22, 42, -47, 125, -1, 12, 60, -166, +98, -135, 48, 75, 8, 167, 37, 35, +62, -81, -16, -36, -90, 17, -18, -52, +135, -51, 169, 75, 9, 121, -134, -33, +-91, -140, 37, -41, 53, 114, 20, 93, +21, -70, 4, -138, -51, -12, -47, 155, +-15, 120, -10, -82, -30, -170, 12, -35, +85, 83, 81, 49, -45, -1, -161, 43, +-114, 45, 75, -64, 182, -134, 115, -36, +-5, 123, -66, 136, -81, -9, -43, -128, +52, -66, 142, 47, 128, 42, 36, -43, +-40, -12, -63, 86, -32, 64, 5, -74, +47, -104, 98, -4, 145, 55, 40, 15, +-158, 9, -232, 69, -25, 23, 195, -136, +203, -155, 16, 75, -133, 238, -155, 79, +-86, -171, 7, -142, 94, 53, 141, 67, +48, -62, -104, -30, -131, 122, 3, 114, +49, -73, 19, -176, 29, -88, 110, 59, +59, 139, -69, 115, -102, -3, 19, -119, +109, -147, 95, -55, 30, 104, -12, 195, +-4, 60, 13, -170, 23, -174, -21, 67, +-7, 165, 69, 14, 134, -96, 7, -16, +-146, 17, -115, -46, 70, 17, 112, 128, +15, 3, -60, -195, -32, -66, 2, 204, +-9, 135, -19, -168, -20, -173, -14, 97, +-2, 181, 44, -15, 32, -136, -23, -61, +-71, 28, -22, 70, 57, 80, 97, 16, +53, -130, -4, -128, -52, 76, -21, 188, +55, 16, 96, -177, 58, -112, 6, 84, +17, 117, 18, 3, -21, -48, -9, -24, +80, -14, 76, -20, -19, 13, -68, 37, +-3, 14, 36, -4, 18, 16, -20, 1, +-11, -51, 10, -62, -20, 7, -85, 63, +-57, 72, 86, 39, 137, -26, -63, -95, +-234, -94, -65, -6, 214, 99, 153, 115, +-158, 28, -198, -64, 84, -88, 191, -57, +3, -1, -81, 78, 21, 100, 40, 5, +-30, -108, 70, -56, 193, 84, 44, 49, +-213, -136, -138, -126, 211, 130, 344, 253, +29, 24, -279, -254, -172, -214, 151, 71, +208, 237, 8, 120, -104, -89, -16, -156, +36, -46, -37, 57, -66, 54, 30, 1, +68, -13, -58, -9, -98, 8, 23, 36, +98, 19, -46, -66, -174, -108, -54, -17, +177, 130, 152, 157, -74, -13, -201, -202, +-72, -162, 124, 89, 153, 218, 34, 68, +-50, -123, -18, -114, 30, -16, 14, 34, +32, 47, 109, 76, 65, -1, -55, -139, +-42, -115, 118, 80, 128, 185, -40, 65, +-118, -112, 16, -163, 133, -56, 56, 82, +-61, 130, -38, 65, 16, -25, -49, -74, +-61, -94, 60, -75, 116, 41, -48, 165, +-178, 119, -65, -78, 95, -168, 77, -49, +-45, 75, -112, 33, -40, -31, 77, 39, +61, 104, -41, -10, -67, -170, -6, -91, +42, 123, 60, 134, 52, -65, 16, -102, +-29, 75, -7, 97, 44, -119, 78, -167, +67, 82, -1, 199, -51, -12, 41, -166, +151, 9, 41, 142, -135, -34, -74, -192, +143, -11, 169, 209, -11, 111, -136, -134, +-68, -153, 1, 9, 25, 84, 89, 28, +89, 0, -65, 25, -205, 3, -110, -67, +140, -65, 171, 51, -82, 100, -212, -24, +-33, -136, 164, 2, 73, 200, -136, 85, +-126, -236, 79, -241, 133, 138, -2, 322, +-67, 37, 30, -245, 50, -129, -40, 78, +18, 42, 155, -27, 54, 68, -145, 88, +-34, -93, 210, -151, 148, 47, -94, 155, +-165, -11, -6, -145, 172, -25, 189, 123, +21, 80, -164, -53, -178, -102, 25, -61, +166, 26, 110, 102, -7, 84, -95, -24, +-118, -100, -52, -68, 39, 11, 67, 61, +21, 58, -55, 20, -31, -49, 19, -76, +-7, -5, -109, 69, -89, 29, 76, -44, +217, -11, 88, 58, -158, -8, -233, -115, +-34, -37, 196, 134, 209, 115, 42, -93, +-66, -177, -80, -16, -99, 149, 19, 103, +194, -54, 170, -110, -51, -21, -124, 57, +-11, 26, 108, -31, 27, -21, -36, 18, +13, 28, 72, 23, 25, -1, -47, -71, +-59, -90, 11, 48, 40, 177, -4, 62, +-17, -153, 4, -160, 15, 33, -33, 119, +-38, 38, -26, -12, 11, -5, 14, -34, +26, -59, -2, 10, -39, 58, -48, -10, +-2, -35, 43, 65, 56, 79, -1, -113, +-58, -200, -4, 44, 52, 277, 48, 105, +36, -226, -18, -207, -78, 84, 9, 182, +117, 35, 93, -51, -30, -42, -59, -79, +8, -58, 4, 106, -16, 155, 84, -35, +162, -161, 14, -18, -221, 105, -183, 2, +153, -75, 296, 44, 22, 106, -246, -33, +-132, -129, 113, -22, 104, 79, -36, 31, +-31, -11, 41, 32, -55, 25, -118, -61, +52, -88, 173, -5, -8, 76, -184, 87, +-111, 43, 133, -67, 184, -157, -36, -84, +-147, 129, -18, 203, 76, 15, 14, -167, +-20, -125, 55, 24, 99, 76, -38, 44, +-137, 19, -23, 12, 170, -15, 134, -70, +-88, -100, -134, -13, 91, 158, 153, 179, +-57, -61, -153, -243, 37, -80, 210, 155, +74, 102, -156, -80, -136, -24, 90, 101, +124, -7, -23, -163, -36, -46, 51, 166, +-6, 95, -127, -114, -62, -97, 168, 89, +149, 100, -122, -80, -189, -147, -6, 12, +117, 154, 76, 81, -17, -78, -62, -93, +-44, 9, -12, 12, 24, -59, 26, 4, +49, 158, 49, 102, -49, -159, -115, -240, +-7, 23, 130, 241, 125, 90, -7, -155, +-114, -86, -57, 124, 65, 57, 88, -171, +27, -123, 11, 164, 13, 206, 0, -56, +-44, -170, -21, -18, 96, 37, 104, -53, +-40, -2, -90, 168, -5, 122, 60, -127, +51, -230, -33, -57, -38, 162, 11, 174, +7, -17, -18, -151, 28, -32, 11, 128, +-71, 5, -85, -201, 54, -57, 123, 251, +0, 186, -133, -160, -95, -224, 59, 14, +117, 106, 12, -5, -83, -17, -19, 95, +26, 89, 26, -78, 21, -193, 15, -91, +-27, 138, 25, 215, 61, 16, 11, -162, +-16, -74, 19, 56, 20, -1, -6, -62, +23, 60, 82, 137, 74, -18, -65, -145, +-89, -39, 3, 82, 73, 7, 70, -74, +56, 45, -19, 141, -113, -11, -106, -201, +42, -92, 131, 156, 66, 158, -52, -56, +-134, -124, -70, -16, 21, 45, 40, 24, +38, 17, 81, -17, -31, -63, -175, 9, +-85, 78, 120, -3, 137, -94, 23, 19, +-79, 107, -101, -37, -21, -129, 89, 38, +154, 146, 37, -25, -122, -153, -110, -12, +80, 132, 147, 58, 92, -65, -37, -76, +-98, -12, -65, 49, 75, 44, 155, -14, +50, -19, -95, 46, -82, 8, 21, -117, +43, -65, 27, 140, 5, 133, 13, -81, +-31, -94, -61, 58, -46, -9, 32, -162, +58, 15, 17, 283, -80, 119, -79, -242, +16, -220, 57, 53, -26, 135, -30, 63, +35, 62, -30, 17, -45, -145, 41, -151, +57, 48, -33, 148, -24, 58, 32, -2, +20, -17, -27, -99, 41, -120, 79, 73, +-13, 209, -56, 24, 30, -196, 73, -76, +14, 154, -2, 60, 34, -156, -4, -53, +-38, 185, 47, 62, 60, -192, -30, -71, +-54, 190, 19, 57, 49, -196, 30, -51, +-55, 202, -98, 37, 17, -192, 104, -3, +6, 178, -80, -62, -37, -219, 1, 78, +2, 263, 17, -31, 43, -249, -18, -5, +-134, 162, -42, -45, 173, -120, 116, 157, +-144, 207, -129, -203, 90, -363, 67, 111, +-60, 448, 68, 36, 151, -384, -59, -77, +-215, 313, -19, -23, 216, -372, 155, 112, +-64, 556, -85, -36, -2, -675, -35, -144, +-42, 596, 116, 208, 191, -449, -18, -66, +-191, 463, -127, -67, 89, -660, 140, -19, +-16, 768, -85, 244, 76, -618, 46, -315, +-166, 388, -131, 120, 129, -366, 163, 59, +-34, 552, -111, -18, -31, -649, 15, -183, +-26, 510, 0, 256, 51, -321, 64, -168, +-13, 262, -42, 145, -78, -302, -40, -246, +104, 221, 150, 386, -47, -40, -126, -395, +40, -117, 82, 325, -30, 158, -25, -297, +99, -154, 41, 314, -95, 192, -72, -334, +137, -229, 124, 322, -105, 270, -142, -337, +86, -320, 114, 306, -28, 406, -61, -220, +21, -421, 30, 97, -50, 335, -63, -73, +25, -235, 137, 157, 0, 243, -178, -208, +-102, -347, 163, 173, 109, 396, -115, -50, +-114, -391, 101, -27, 67, 322, -126, 99, +-40, -286, 167, -151, 45, 231, -190, 210, +-68, -172, 151, -270, 136, 137, -49, 309, +-112, -64, -91, -377, 90, 5, 162, 379, +17, 110, -153, -352, -17, -170, 155, 235, +21, 185, -171, -131, 1, -145, 258, 64, +6, 84, -278, -4, -54, -61, 297, -21, +77, 15, -221, 92, -131, 9, 136, -129, +135, -98, -25, 155, -125, 156, -27, -131, +86, -182, -16, 112, -109, 174, 29, -157, +195, -169, -22, 198, -257, 270, -96, -206, +250, -353, 123, 92, -180, 420, -106, 47, +142, -388, 54, -175, -112, 313, -4, 258, +51, -248, -5, -268, 5, 192, 64, 292, +-41, -165, -45, -287, 76, 106, 48, 281, +-130, -51, -46, -265, 240, -12, 152, 243, +-240, 109, -266, -226, 193, -218, 256, 177, +-126, 326, -184, -96, 190, -365, 157, 36, +-265, 350, -302, -14, 208, -334, 424, 38, +-33, 333, -406, -18, -136, -336, 286, -59, +100, 273, -213, 126, -38, -150, 264, -157, +22, 42, -315, 149, -140, 55, 245, -155, +212, -140, -123, 156, -180, 250, 65, -123, +138, -338, -81, 68, -162, 411, 95, -27, +238, -509, 13, -49, -181, 613, -65, 236, +64, -662, 15, -481, 39, 503, 140, 650, +42, -253, -169, -601, -131, 79, 48, 448, +138, -79, 67, -412, -12, 146, -77, 489, +-27, -45, -21, -557, -47, -133, 5, 433, +145, 238, 64, -233, -143, -207, -90, 127, +34, 124, -5, -60, -75, -162, 133, -7, +155, 189, -98, 186, -312, -141, -3, -349, +287, 49, 121, 403, -212, 58, -116, -482, +163, -112, 75, 513, -112, 260, -57, -515, +150, -409, 21, 382, -118, 458, -50, -214, +202, -423, 108, 228, -141, 377, -245, -290, +30, -580, 318, 291, 196, 813, -217, -23, +-341, -906, 73, -327, 282, 741, 62, 504, +-211, -431, -20, -534, 137, 272, 21, 442, +-248, -154, -87, -494, 316, 57, 231, 564, +-322, 145, -363, -562, 236, -420, 324, 493, +-125, 589, -271, -257, 67, -716, 156, 57, +17, 691, -119, 138, -73, -634, 54, -293, +179, 594, 27, 400, -241, -513, -84, -585, +275, 469, 166, 729, -305, -336, -171, -914, +331, 149, 276, 1054, -325, 122, -355, -1070, +236, -469, 436, 941, -65, 708, -427, -654, +-64, -804, 360, 408, 164, 754, -305, -269, +-219, -745, 216, 186, 303, 782, -114, -21, +-354, -819, -51, -187, 361, 718, 159, 375, +-361, -566, -269, -494, 343, 422, 404, 572, +-302, -199, -569, -682, 117, -51, 694, 567, +109, 341, -642, -358, -290, -401, 567, 91, +362, 309, -521, 45, -448, -253, 517, -75, +638, 223, -351, 295, -772, -203, 53, -531, +718, -107, 222, 673, -466, 497, -302, -480, +312, -711, 263, 149, -290, 666, -358, 24, +338, -507, 538, -53, -162, 504, -678, 91, +-138, -567, 573, -319, 380, 527, -323, 587, +-482, -259, 133, -758, 437, -88, -19, 717, +-447, 413, -66, -574, 398, -636, 201, 373, +-322, 771, -279, -154, 212, -867, 298, -70, +-175, 849, -310, 321, 165, -751, 378, -506, +-78, 550, -437, 627, -62, -320, 383, -640, +220, 74, -283, 586, -229, 126, 212, -436, +254, -290, -166, 240, -283, 346, 81, -36, +310, -309, 120, -159, -219, 252, -250, 261, +41, -123, 245, -366, 65, 31, -176, 363, +-27, 94, 194, -316, -2, -168, -358, 249, +-104, 180, 447, -150, 283, -254, -380, 75, +-407, 301, 247, 131, 357, -305, -163, -371, +-319, 113, 169, 502, 340, 193, -115, -405, +-423, -394, -5, 117, 445, 366, 165, 64, +-382, -147, -258, -72, 303, 31, 286, -54, +-215, -36, -322, 73, 184, 97, 320, 48, +-90, -39, -366, -133, 44, -159, 386, 143, +74, 264, -395, -5, -208, -315, 363, -74, +304, 269, -191, 132, -375, -222, 78, -230, +324, 159, 64, 287, -329, 0, -120, -329, +341, -145, 217, 233, -346, 234, -363, -112, +286, -204, 452, 10, -126, 149, -524, 6, +0, -83, 482, -41, 145, 77, -490, 73, +-199, -61, 445, -101, 292, -18, -440, 162, +-408, 38, 390, -45, 529, -89, -226, 10, +-672, -52, 80, -1, 626, 188, 165, 124, +-532, -194, -249, -344, 346, 143, 290, 398, +-220, 54, -311, -438, 177, -138, 330, 410, +-47, 221, -389, -424, -61, -371, 314, 415, +240, 577, -230, -260, -344, -747, 83, -20, +444, 808, 30, 338, -532, -691, -173, -605, +553, 422, 362, 805, -485, -140, -459, -812, +278, -265, 528, 773, -155, 541, -475, -586, +31, -772, 481, 362, 37, 982, -494, -164, +-156, -1042, 442, -224, 363, 1101, -337, 554, +-475, -900, 105, -919, 548, 559, 95, 1148, +-490, -169, -235, -1140, 395, -292, 314, 1062, +-342, 585, -346, -782, 308, -797, 441, 516, +-263, 870, -566, -309, 169, -901, 660, 81, +14, 984, -650, 178, -166, -925, 542, -537, +239, 706, -439, 760, -262, -323, 408, -767, +320, -8, -377, 623, -413, 182, 277, -473, +460, -335, -148, 362, -411, 476, 92, -121, +320, -563, -87, -193, -345, 408, 81, 407, +392, -110, 58, -391, -405, -81, -228, 244, +323, 81, 276, -203, -191, -47, -277, 296, +200, 103, 254, -305, -193, -237, -355, 181, +122, 253, 444, -12, 38, -76, -419, -92, +-202, -81, 383, -9, 302, 233, -314, 75, +-435, -262, 276, -179, 595, 260, -97, 316, +-715, -266, -132, -381, 683, 109, 320, 488, +-556, -16, -387, -446, 478, -118, 391, 376, +-396, 232, -527, -287, 281, -260, 582, 128, +-19, 298, -546, -24, -194, -261, 369, -57, +224, 219, -204, 119, -234, -202, 201, -160, +236, 178, -151, 171, -357, -113, 32, -186, +376, 124, 121, 114, -256, -106, -190, -70, +110, 134, 118, 54, -14, -214, -52, 27, +-7, 248, 54, 30, 36, -371, -92, -88, +-39, 409, 76, 225, 34, -322, -95, -392, +84, 196, 157, 401, -140, 32, -280, -404, +91, -205, 409, 346, -13, 360, -384, -238, +-122, -547, 366, 109, 131, 645, -314, 93, +-175, -663, 288, -311, 269, 614, -275, 474, +-372, -499, 118, -638, 499, 328, 45, 829, +-514, -95, -270, -880, 416, -309, 454, 820, +-227, 668, -526, -519, -21, -895, 493, 79, +218, 956, -357, 255, -304, -768, 221, -538, +328, 637, -116, 667, -376, -493, 34, -832, +459, 305, 165, 1035, -487, -15, -387, -1075, +362, -444, 527, 913, -115, 793, -536, -502, +-87, -944, 410, 97, 235, 905, -311, 230, +-353, -837, 190, -499, 440, 720, 36, 793, +-500, -494, -292, -1003, 339, 154, 520, 1008, +-137, 195, -583, -908, -56, -377, 573, 722, +204, 547, -622, -591, -360, -689, 599, 354, +645, 813, -470, -23, -845, -785, 147, -318, +879, 626, 176, 573, -728, -387, -400, -708, +515, 127, 553, 793, -322, 124, -627, -733, +87, -442, 700, 595, 152, 603, -630, -285, +-399, -659, 502, 32, 560, 563, -353, 107, +-640, -437, 225, -234, 718, 425, -139, 310, +-790, -309, -30, -503, 799, 139, 251, 582, +-709, 165, -443, -485, 479, -461, 522, 235, +-273, 565, -481, 90, 138, -522, 381, -304, +-55, 391, -348, 420, 15, -262, 294, -506, +67, 73, -218, 577, -95, 181, 157, -468, +47, -489, -112, 239, -32, 574, 158, 53, +58, -506, -134, -206, -88, 467, 45, 236, +58, -450, -11, -468, 68, 468, 86, 694, +-105, -186, -222, -818, 0, -187, 280, 709, +74, 374, -194, -432, -113, -492, 148, 370, +60, 563, -187, -237, -89, -791, 164, -62, +223, 914, -99, 454, -259, -656, -85, -774, +197, 318, 188, 686, -83, -31, -178, -530, +-63, -26, 192, 481, 98, 76, -135, -490, +-198, -314, 147, 435, 275, 543, -149, -148, +-330, -659, 78, -126, 449, 540, -18, 343, +-410, -375, -192, -394, 354, 160, 330, 389, +-160, 15, -373, -345, -9, -115, 343, 233, +44, 251, -271, -211, -131, -270, 274, 76, +200, 365, -163, 55, -330, -355, 5, -210, +290, 205, 142, 351, -180, -80, -189, -295, +71, -91, 170, 275, -9, 196, -245, -223, +-84, -336, 275, 49, 319, 507, -193, 174, +-483, -443, -105, -427, 475, 236, 347, 495, +-273, -39, -445, -360, 130, -95, 441, 315, +-88, 84, -493, -317, 15, -171, 612, 344, +191, 389, -590, -295, -500, -522, 403, 34, +647, 606, -81, 183, -654, -457, -147, -375, +539, 249, 315, 445, -445, -71, -486, -416, +361, -99, 618, 429, -131, 198, -747, -386, +-117, -379, 626, 300, 369, 515, -444, -62, +-454, -529, 276, -203, 406, 364, -191, 321, +-423, -167, 205, -277, 432, 98, -81, 210, +-460, -153, -95, -241, 347, 120, 256, 321, +-108, 16, -308, -268, -63, -185, 210, 92, +171, 254, -108, 32, -143, -184, -23, -113, +82, 186, 121, 99, 6, -111, -175, -121, +-95, -3, 149, 92, 121, 96, -56, 73, +-88, -159, -14, -133, 21, 24, 53, 159, +3, 58, -119, -64, -48, -91, 210, -58, +146, 177, -255, 84, -268, -183, 140, -234, +283, 231, 18, 342, -169, -135, -137, -388, +50, -34, 157, 375, -59, 130, -215, -269, +138, -249, 351, 217, -155, 389, -480, -139, +56, -545, 474, -52, 75, 678, -336, 254, +-148, -655, 190, -426, 171, 562, -109, 520, +-221, -458, 63, -536, 306, 330, 8, 547, +-316, -185, -157, -497, 237, 6, 292, 349, +-53, 151, -341, -151, -147, -231, 313, -35, +227, 231, -217, 197, -248, -260, 148, -250, +224, 229, -136, 348, -220, -206, 52, -389, +270, 108, 31, 332, -266, 51, -172, -220, +232, -72, 274, -20, -204, 29, -324, 143, +121, 96, 374, -174, -6, -166, -353, 237, +-176, 102, 239, -339, 336, -136, -98, 571, +-375, 242, -8, -697, 356, -420, 65, 673, +-381, 579, -75, -642, 379, -598, 186, 550, +-358, 713, -281, -511, 242, -781, 265, 356, +-53, 825, -213, -195, 4, -808, 80, 137, +35, 743, -56, -82, -59, -791, 72, 54, +69, 771, -5, 46, -116, -688, -63, -95, +23, 541, 146, 39, 115, -387, -211, 23, +-234, 304, 165, -86, 357, -200, -146, 157, +-414, 71, 71, -269, 449, -42, 44, 490, +-524, 112, -107, -654, 497, -327, 184, 768, +-453, 571, -151, -823, 348, -792, 78, 833, +-237, 997, 9, -867, 169, -1144, -36, 894, +-146, 1285, 39, -936, 101, -1436, -34, 937, +-28, 1576, 85, -840, 8, -1650, -232, 648, +-18, 1614, 262, -449, 180, -1472, -275, 281, +-302, 1317, 151, -136, 359, -1189, -8, 1, +-400, 1056, -30, 113, 307, -903, 98, -203, +-294, 803, -102, 183, 215, -661, 151, -265, +-103, 617, -210, 264, -40, -445, 166, -313, +205, 308, -88, 334, -284, -232, -36, -294, +300, 109, 129, 399, -281, -139, -131, -432, +319, 22, 106, 560, -352, 23, -122, -578, +353, -77, 185, 554, -262, 61, -200, -554, +77, 15, 198, 612, -20, -18, -88, -672, +-7, -115, 26, 681, -73, 253, 4, -532, +146, -344, -21, 367, -136, 321, -51, -327, +166, -237, 9, 341, -165, 320, -50, -425, +270, -390, 78, 329, -365, 495, -189, -254, +383, -460, 312, 187, -329, 450, -324, -193, +241, -518, 247, 166, -298, 649, -106, -24, +391, -756, 114, -179, -478, 761, -105, 355, +355, -717, 95, -444, -208, 683, 59, 502, +93, -694, -211, -519, -58, 677, 207, 602, +27, -643, -162, -598, 125, 491, 80, 627, +-274, -359, -119, -542, 337, 178, 149, 480, +-315, -16, -123, -397, 246, -100, 55, 219, +-207, 226, -37, -115, 197, -174, 69, -64, +-122, 172, -238, 95, 60, -139, 375, -157, +55, 170, -518, 268, -132, -207, 621, -370, +171, 114, -684, 464, -260, -48, 810, -422, +306, -15, -811, 424, -429, 18, 816, -463, +380, -137, -639, 515, -295, 330, 545, -417, +117, -513, -468, 233, -29, 517, 366, -95, +93, -376, -262, 76, -55, 304, -40, -179, +39, -250, 142, 132, 174, 293, -232, -18, +-277, -221, 160, -170, 308, 113, -104, 328, +-339, -57, 143, -389, 328, 42, -126, 477, +-460, -143, 99, -516, 545, 231, 21, 605, +-626, -304, -144, -648, 651, 273, 230, 660, +-674, -197, -279, -587, 680, 109, 359, 482, +-647, -3, -505, -439, 566, -90, 620, 347, +-352, 291, -743, -260, 211, -423, 726, 38, +-86, 505, -718, 210, 15, -476, 756, -416, +21, 307, -725, 635, -173, -149, 736, -732, +246, -85, -640, 808, -360, 291, 515, -840, +489, -481, -386, 815, -526, 730, 164, -760, +578, -1021, -70, 565, -526, 1254, 8, -215, +547, -1383, -10, -51, -601, 1320, -65, 246, +607, -1308, 135, -347, -461, 1316, -135, 521, +286, -1176, -2, -775, -228, 861, 125, 813, +231, -375, -30, -703, -260, 87, -26, 471, +52, 96, 47, -431, 81, -218, 131, 390, +-106, 495, -278, -265, 52, -686, 233, -40, +11, 672, -195, 331, 59, -537, 193, -418, +-86, 391, -207, 532, -41, -431, 143, -679, +113, 402, 93, 971, -100, -262, -270, -1174, +-4, 44, 249, 1173, 92, 151, -219, -1078, +25, -207, 194, 945, -54, 231, -389, -838, +7, -328, 530, 752, 206, 443, -597, -531, +-372, -630, 537, 330, 420, 683, -514, -37, +-405, -733, 562, -156, 371, 683, -508, 343, +-469, -610, 436, -514, 385, 513, -148, 589, +-372, -242, 1, -670, 243, 51, 168, 534, +-173, 203, -388, -457, 178, -353, 527, 388, +15, 544, -780, -250, -91, -853, 753, 72, +285, 978, -759, 321, -335, -1017, 704, -617, +451, 895, -693, 834, -626, -751, 613, -1110, +788, 686, -426, 1362, -859, -367, 214, -1680, +751, -32, 11, 1715, -652, 512, -142, -1544, +455, -865, 347, 1305, -314, 1066, -439, -1047, +62, -1304, 475, 796, 173, 1523, -458, -406, +-330, -1690, 331, -1, 542, 1667, -278, 412, +-697, -1544, 87, -670, 849, 1299, 170, 871, +-905, -1005, -373, -1000, 787, 665, 567, 978, +-685, -228, -633, -929, 548, -89, 710, 717, +-354, 388, -807, -532, 121, -578, 829, 360, +202, 641, -762, -149, -521, -716, 628, 44, +697, 642, -367, 143, -828, -575, 158, -277, +812, 419, 73, 321, -769, -206, -315, -315, +740, 100, 498, 169, -596, 26, -767, -72, +412, -123, 929, -97, -84, 238, -1001, 380, +-272, -307, 990, -682, 498, 159, -878, 941, +-692, 48, 826, -997, 823, -266, -668, 961, +-1002, 392, 460, -964, 1114, -500, -147, 933, +-1144, 741, -127, -829, 1067, -938, 301, 542, +-918, 1030, -452, -210, 806, -984, 514, 1, +-540, 851, -685, 201, 299, -843, 678, -345, +100, 758, -648, 637, -403, -649, 475, -871, +620, 391, -271, 983, -768, -111, 150, -982, +804, -48, -13, 850, -873, 200, -121, -799, +844, -248, 318, 674, -741, 427, -540, -598, +535, -521, 739, 379, -312, 655, -891, -200, +56, -674, 1007, -8, 223, 651, -1016, 249, +-518, -646, 881, -405, 763, 477, -656, 679, +-903, -389, 436, -779, 988, 149, -191, 914, +-1109, 56, -27, -997, 1118, -270, 369, 923, +-1043, 617, -629, -846, 827, -796, 772, 529, +-505, 953, -926, -292, 280, -991, 948, 129, +119, 1009, -1061, 79, -497, -1132, 955, -260, +870, 1086, -702, 583, -1166, -916, 410, -785, +1249, 577, 16, 829, -1356, -221, -381, -812, +1318, -74, 817, 745, -1203, 409, -1186, -631, +946, -739, 1425, 408, -628, 976, -1569, -96, +310, -1048, 1672, -181, 36, 996, -1729, 350, +-381, -912, 1627, -485, 757, 845, -1449, 675, +-952, -739, 1093, -859, 1144, 499, -781, 1003, +-1198, -268, 429, -995, 1191, 44, -11, 932, +-1140, 100, -301, -885, 845, -214, 675, 790, +-617, 415, -835, -681, 297, -543, 988, 404, +-81, 618, -1096, -144, -111, -510, 1101, -63, +383, 367, -1098, 165, -578, -304, 845, -197, +813, 258, -599, 334, -859, -240, 275, -416, +865, 68, -53, 480, -784, 108, -150, -412, +641, -284, 388, 297, -474, 474, -538, -158, +150, -630, 691, -92, 71, 765, -635, 388, +-326, -742, 637, -685, 496, 614, -574, 855, +-722, -449, 442, -973, 1027, 333, -250, 1034, +-1173, -161, -145, -1142, 1294, 9, 421, 1164, +-1197, 215, -774, -1178, 1097, -433, 1031, 1156, +-865, 646, -1278, -978, 531, -928, 1420, 785, +-225, 1011, -1430, -429, -110, -1039, 1462, 215, +376, 948, -1401, -33, -752, -906, 1245, -194, +1119, 824, -895, 454, -1342, -535, 472, -674, +1416, 154, -175, 642, -1381, 182, -51, -534, +1396, -298, 343, 478, -1398, 429, -683, -604, +1141, -642, 1084, 597, -767, 997, -1214, -404, +268, -1184, 1210, 75, 88, 1136, -1157, 221, +-323, -1006, 1088, -369, 633, 845, -1101, 549, +-878, -750, 882, -714, 1185, 577, -643, 873, +-1267, -369, 311, -966, 1232, 131, -37, 980, +-1106, 140, -178, -940, 910, -427, 409, 815, +-732, 691, -584, -604, 470, -895, 741, 372, +-229, 996, -741, -122, -26, -1082, 702, -93, +171, 1061, -576, 366, -298, -1006, 487, -558, +381, 780, -327, 702, -432, -524, 136, -729, +422, 261, 54, 630, -336, 22, -197, -547, +271, -154, 275, 325, -243, 331, -361, -193, +251, -345, 438, -17, -262, 367, -493, 170, +286, -295, 485, -272, -304, 147, -503, 305, +307, -26, 482, -189, -221, -85, -453, 84, +133, 99, 345, 25, -77, -157, -254, -101, +75, 206, 217, 245, -53, -206, -209, -406, +-56, 120, 174, 467, 157, 37, -71, -449, +-190, -104, -10, 352, 122, 156, 42, -294, +-65, -184, -23, 215, 31, 206, 44, -55, +-20, -202, -62, -79, -40, 37, 89, 216, +104, 112, -70, -203, -174, -270, 47, 155, +239, 341, -37, -94, -261, -332, -21, -11, +333, 298, 33, 52, -289, -182, -141, -100, +259, 92, 189, 99, -129, -9, -251, -96, +-45, -93, 281, 133, 172, 185, -178, -107, +-329, -361, 109, 75, 354, 455, 58, 59, +-411, -512, -187, -186, 387, 467, 314, 296, +-304, -304, -395, -369, 180, 143, 377, 289, +-85, 69, -320, -201, 54, -140, 309, 76, +-62, 201, -307, -56, -12, -276, 301, 53, +134, 391, -214, 25, -237, -485, 29, -118, +315, 448, 99, 200, -270, -366, -257, -210, +252, 317, 332, 214, -163, -276, -451, -299, +109, 203, 511, 371, -5, -36, -610, -351, +-94, -113, 650, 265, 221, 163, -676, -164, +-350, -173, 689, 172, 422, 177, -675, -157, +-576, -274, 739, 129, 718, 330, -653, -6, +-973, -361, 497, -126, 1119, 327, -194, 225, +-1155, -225, -105, -339, 1091, 183, 326, 334, +-986, -56, -506, -388, 899, 35, 667, 337, +-771, 6, -812, -303, 584, -24, 939, 300, +-356, -37, -1016, -225, 125, -23, 1015, 268, +150, -11, -961, -204, -374, -51, 735, 224, +576, 99, -517, -235, -656, -133, 265, 212, +698, 220, -55, -233, -700, -197, -175, 197, +599, 195, 451, -243, -440, -156, -624, 288, +159, 181, 747, -295, 41, -230, -745, 253, +-244, 212, 722, -155, 413, -182, -639, 159, +-559, 129, 449, -176, 696, -195, -247, 191, +-684, 295, -30, -137, 655, -350, 226, 23, +-510, 400, -408, 10, 334, -373, 523, -107, +-163, 424, -545, 178, 0, -418, 575, -291, +94, 364, -547, 395, -219, -332, 488, -416, +362, 221, -365, 514, -449, -144, 180, -521, +487, -49, -63, 503, -474, 239, -41, -402, +469, -349, 141, 274, -462, 464, -257, -237, +395, -545, 373, 127, -322, 689, -403, 5, +216, -727, 439, -174, -142, 657, -439, 304, +-19, -587, 453, -329, 156, 495, -376, 444, +-274, -446, 283, -554, 339, 288, -239, 629, +-352, -76, 133, -617, 492, -45, -39, 478, +-508, 143, -215, -435, 467, -152, 397, 383, +-292, 246, -486, -321, 87, -368, 563, 207, +43, 376, -582, -26, -227, -370, 639, -23, +392, 288, -626, 83, -553, -280, 523, -109, +676, 272, -394, 157, -756, -207, 208, -225, +824, 182, 19, 198, -853, -132, -250, -253, +809, 159, 455, 311, -707, -106, -618, -398, +566, -6, 750, 436, -406, 98, -864, -374, +181, -170, 967, 405, 32, 170, -943, -449, +-307, -325, 872, 513, 528, 524, -660, -382, +-715, -676, 373, 132, 790, 667, -78, 38, +-690, -519, -185, -163, 563, 481, 309, 220, +-393, -420, -455, -398, 302, 305, 554, 541, +-163, -64, -670, -505, 20, -183, 705, 365, +155, 230, -698, -176, -336, -253, 665, 104, +520, 280, -575, 36, -712, -337, 437, -277, +822, 284, -250, 477, -860, -44, 105, -597, +857, -146, 35, 534, -874, 336, -217, -519, +826, -463, 456, 485, -683, 648, -611, -354, +419, -836, 686, 156, -223, 830, -641, 109, +59, -777, 642, -215, 68, 649, -656, 346, +-251, -595, 605, -471, 483, 515, -470, 584, +-632, -373, 224, -691, 725, 294, 12, 706, +-691, -179, -229, -803, 571, 72, 376, 849, +-366, 137, -443, -800, 131, -369, 476, 644, +76, 480, -497, -427, -261, -526, 511, 305, +434, 505, -474, -216, -592, -498, 358, 124, +715, 473, -153, -67, -777, -380, -68, -12, +763, 283, 296, 36, -672, -128, -466, -71, +490, -45, 591, 26, -259, 212, -654, 100, +30, -320, 672, -224, 184, 308, -673, 354, +-366, -315, 630, -417, 552, 268, -533, 543, +-693, -212, 363, -650, 807, 49, -182, 703, +-837, 157, -38, -680, 846, -324, 244, 578, +-758, 467, -443, -509, 615, -576, 585, 407, +-445, 705, -643, -264, 266, -809, 668, 84, +-133, 829, -624, 138, -33, -785, 555, -319, +153, 668, -399, 491, -295, -506, 260, -636, +354, 331, -66, 696, -432, -89, -62, -760, +433, -86, 192, 696, -415, 314, -302, -631, +404, -474, 385, 476, -328, 597, -493, -302, +251, -717, 522, 159, -64, 748, -494, 98, +-123, -805, 354, -298, 267, 672, -203, 540, +-306, -497, 77, -640, 327, 268, -22, 659, +-337, -50, -70, -681, 381, -110, 180, 631, +-376, 353, -295, -576, 307, -530, 371, 380, +-179, 651, -381, -157, 5, -679, 344, -24, +163, 632, -275, 247, -315, -612, 223, -447, +379, 477, -129, 666, -437, -288, 100, -783, +413, 59, -12, 783, -432, 182, -50, -755, +383, -331, 120, 632, -304, 553, -188, -517, +251, -691, 165, 291, -149, 784, -192, -57, +144, -803, 180, -113, -93, 721, -217, 292, +31, -685, 248, -388, 63, 549, -203, 532, +-178, -432, 128, -612, 230, 254, 2, 655, +-263, -78, -59, -688, 276, -62, 113, 640, +-330, 240, -182, -595, 336, -343, 304, 461, +-253, 454, -432, -313, 88, -475, 455, 151, +55, 462, -447, 24, -96, -414, 419, -150, +116, 300, -448, 279, -159, -193, 458, -331, +252, 42, -401, 340, -334, 75, 324, -314, +381, -148, -206, 262, -437, 206, 72, -272, +487, -250, 112, 249, -475, 355, -282, -205, +420, -445, 336, 92, -329, 472, -373, 69, +288, -439, 406, -155, -199, 336, -484, 219, +44, -300, 533, -229, 129, 249, -470, 293, +-301, -174, 393, -338, 345, 51, -281, 324, +-418, 129, 201, -264, 466, -233, -80, 146, +-517, 336, -92, -78, 527, -377, 217, 19, +-447, 453, -336, 53, 364, -531, 354, -157, +-253, 548, -342, 310, 168, -484, 333, -425, +-119, 316, -314, 459, 55, -142, 325, -400, +9, 11, -293, 326, -107, 75, 218, -261, +207, -171, -111, 190, -271, 267, -47, -65, +334, -326, 200, -59, -322, 294, -385, 153, +276, -256, 511, -178, -204, 236, -561, 227, +150, -220, 584, -337, -137, 138, -592, 436, +69, 51, 608, -491, 49, -238, -521, 438, +-192, 402, 364, -396, 248, -483, -186, 358, +-263, 579, 59, -344, 291, -671, 54, 294, +-318, 750, -207, -194, 294, -806, 337, 80, +-160, 785, -382, 71, 29, -775, 360, -187, +60, 685, -327, 322, -128, -615, 326, -429, +213, 518, -279, 529, -274, -385, 175, -652, +287, 218, -98, 694, -241, 34, 50, -673, +235, -227, -12, 554, -280, 371, -78, -433, +272, -460, 230, 342, -197, 543, -297, -230, +46, -666, 312, 68, 67, 735, -282, 156, +-151, -715, 273, -358, 246, 608, -268, 480, +-348, -480, 203, -549, 444, 385, -110, 604, +-466, -259, -24, -664, 464, 96, 107, 643, +-382, 87, -188, -543, 317, -212, 216, 417, +-229, 251, -223, -326, 139, -293, 247, 286, +-72, 336, -224, -191, -26, -386, 211, 82, +70, 333, -149, 25, -104, -218, 83, -49, +110, 123, -24, 31, -98, -49, -65, -62, +106, -21, 130, 91, -82, 155, -187, -89, +80, -264, 205, 21, -107, 312, -236, 41, +127, -300, 308, -54, -93, 266, -336, 49, +-21, -256, 319, -49, 99, 223, -213, 44, +-129, -181, 135, -22, 117, 166, -102, 11, +-128, -152, 59, -54, 195, 124, -12, 80, +-217, -47, -87, -63, 234, 22, 137, 22, +-213, -65, -188, -34, 196, 105, 228, 137, +-158, -106, -241, -187, 93, 20, 240, 199, +-54, -17, -201, -164, 19, 43, 204, 196, +26, -68, -206, -263, -113, 40, 158, 273, +217, 21, -69, -249, -255, -15, -46, 200, +249, 24, 114, -212, -235, -32, -144, 187, +249, 75, 192, -142, -261, -102, -247, 98, +216, 97, 292, -48, -148, -120, -296, 37, +54, 147, 265, 20, 32, -192, -221, -68, +-101, 205, 149, 119, 160, -200, -70, -166, +-187, 193, -22, 179, 201, -150, 100, -167, +-193, 142, -179, 119, 162, -175, 249, -112, +-101, 226, -268, 166, 12, -210, 243, -219, +50, 115, -207, 209, -75, -44, 192, -129, +97, 39, -196, 103, -141, -66, 174, -152, +193, 17, -105, 209, -220, 98, 29, -192, +215, -199, 31, 125, -208, 235, -74, -94, +199, -237, 124, 100, -156, 306, -194, -102, +82, -407, 205, 30, 21, 491, -171, 106, +-67, -521, 112, -247, 59, 475, -79, 366, +-44, -412, 92, -436, 48, 362, -103, 491, +-95, -317, 82, -572, 132, 271, -22, 636, +-128, -154, -32, -678, 95, 23, 51, 633, +-72, 94, -50, -546, 65, -160, 52, 482, +-46, 198, -57, -423, 4, -290, 31, 360, +48, 373, 3, -209, -68, -422, -24, 54, +76, 377, 8, 61, -96, -315, 28, -124, +138, 291, -40, 185, -187, -269, 17, -279, +203, 232, 22, 358, -204, -140, -44, -406, +195, 38, 74, 401, -188, 46, -96, -352, +137, -104, 113, 299, -84, 138, -98, -242, +49, -175, 66, 189, -31, 234, -76, -98, +40, -291, 59, -51, -4, 294, -33, 211, +-6, -188, -42, -311, -11, 36, 93, 288, +60, 77, -92, -203, -110, -110, 69, 160, +108, 136, -68, -137, -122, -221, 112, 79, +168, 307, -124, 68, -228, -331, 83, -216, +241, 260, -17, 292, -204, -183, -12, -309, +179, 165, 19, 322, -201, -160, -54, -402, +239, 117, 144, 462, -228, 2, -226, -462, +157, -125, 253, 389, -93, 194, -226, -279, +53, -211, 193, 210, -29, 189, -193, -134, +-19, -184, 173, 83, 92, 175, -149, -7, +-132, -156, 113, -93, 171, 111, -114, 157, +-195, -12, 111, -192, 232, -47, -98, 150, +-249, 76, 80, -118, 232, -39, -69, 122, +-233, -2, 93, -152, 247, -11, -70, 178, +-273, -1, 31, -151, 256, 20, 26, 166, +-203, -87, -70, -214, 139, 120, 93, 293, +-88, -86, -139, -349, 43, 59, 176, 344, +19, -30, -197, -367, -100, 54, 176, 403, +160, -19, -129, -452, -197, -50, 82, 452, +190, 127, -50, -387, -174, -186, 23, 345, +170, 190, 25, -302, -167, -235, -99, 271, +161, 260, 172, -198, -96, -267, -205, 113, +18, 238, 178, -86, 47, -182, -127, 57, +-63, 182, 89, -41, 71, -171, -66, -37, +-86, 143, 43, 102, 86, -75, 16, -124, +-71, 11, -71, 135, 6, -6, 125, -123, +56, -11, -160, 159, -130, 10, 177, -147, +206, -35, -175, 129, -260, 24, 137, -116, +301, 0, -92, 97, -307, 25, 33, -96, +317, -38, 46, 22, -301, 48, -150, 23, +239, -2, 245, -25, -142, -16, -286, -2, +50, -21, 264, 20, 11, 38, -240, 22, +-26, -41, 227, -18, 71, -8, -231, -7, +-150, 23, 182, 58, 210, -2, -96, -65, +-206, -2, 45, 21, 149, -25, -24, -40, +-122, 82, 44, 67, 123, -51, -29, -92, +-138, -5, -4, 23, 116, 13, 34, 69, +-59, 43, -32, -65, 7, -126, -3, 4, +22, 91, 33, 66, -22, -19, -44, -45, +34, -23, 36, 5, -65, 2, -44, -38, +93, 32, 74, 96, -95, 39, -98, -129, +61, -102, 84, 45, -21, 103, -50, 33, +20, -12, 28, -32, -28, -61, -63, -8, +4, 50, 107, 41, 55, -39, -110, 6, +-112, 36, 85, -4, 94, -77, -51, -16, +-75, 85, 67, 51, 56, -64, -72, -91, +-70, 55, 65, 121, 97, -12, -52, -182, +-113, -57, 28, 181, 142, 156, -7, -112, +-155, -179, -33, 29, 139, 130, 33, 4, +-98, -93, -5, 29, 80, 98, -45, 2, +-78, -130, 62, -68, 65, 81, -54, 115, +-23, 7, 79, -99, -20, -36, -118, 46, +8, 41, 140, -79, 23, -37, -110, 107, +-24, 126, 66, -101, 0, -207, -53, 19, +24, 214, 49, 64, -2, -201, -25, -67, +-25, 180, -20, 90, 18, -223, 59, -119, +7, 216, -57, 187, -40, -174, 43, -212, +58, 118, -21, 194, -91, -62, -17, -175, +115, 45, 66, 147, -122, -2, -116, -140, +113, -22, 141, 122, -98, 52, -159, -114, +106, -88, 182, 99, -96, 106, -199, -75, +78, -122, 223, 51, -34, 108, -233, -33, +-37, -102, 236, 18, 120, 97, -204, 13, +-191, -68, 149, -60, 228, 7, -100, 70, +-230, 71, 59, -48, 244, -101, -33, 18, +-267, 102, -36, -4, 281, -98, 117, 13, +-256, 92, -182, 12, 189, -85, 220, -20, +-132, 34, -221, 16, 78, -13, 253, -2, +-17, 5, -259, -6, -62, 0, 239, -23, +137, -11, -196, 26, -174, 46, 149, -19, +213, -62, -119, -20, -250, 57, 86, 57, +291, -20, -33, -81, -323, -41, -30, 77, +327, 101, 112, -33, -318, -141, -187, -18, +279, 136, 267, 48, -220, -133, -310, -58, +162, 146, 322, 73, -105, -158, -332, -122, +72, 155, 321, 157, -4, -122, -323, -168, +-59, 96, 286, 173, 124, -97, -205, -183, +-176, 63, 136, 200, 186, -34, -34, -163, +-210, 4, -46, 116, 203, -18, 126, -70, +-184, 54, -212, 37, 164, -64, 251, -2, +-98, 84, -299, -72, 60, -111, 303, 107, +-4, 165, -310, -116, -49, -169, 297, 120, +90, 164, -267, -137, -167, -173, 233, 138, +232, 195, -147, -72, -300, -190, 56, 7, +297, 134, 39, 26, -274, -103, -81, -31, +243, 134, 106, 80, -214, -180, -149, -190, +191, 159, 179, 285, -119, -80, -212, -288, +37, 28, 194, 270, 29, -19, -161, -287, +-78, -30, 144, 326, 116, 158, -106, -291, +-169, -313, 56, 158, 191, 390, 11, -9, +-178, -372, -59, -86, 153, 341, 87, 107, +-113, -341, -112, -163, 104, 335, 142, 224, +-70, -278, -181, -260, 34, 197, 193, 253, +5, -138, -192, -229, -38, 90, 183, 234, +68, -34, -157, -206, -100, -52, 97, 159, +112, 88, -11, -89, -85, -88, -54, 51, +46, 76, 82, -55, -13, -79, -86, 25, +7, 106, 97, 11, 6, -87, -114, -61, +-63, 72, 119, 82, 124, -64, -74, -108, +-172, 52, 19, 163, 172, -39, 51, -192, +-145, -28, -98, 186, 114, 62, 123, -140, +-73, -56, -160, 125, 43, 50, 156, -133, +11, -66, -166, 108, -62, 106, 169, -48, +123, -90, -150, -34, -178, 11, 136, 58, +197, 70, -89, -28, -222, -104, 57, 22, +221, 108, -20, -38, -229, -150, -28, 53, +244, 224, 64, 0, -223, -273, -123, -99, +201, 265, 138, 178, -145, -201, -153, -224, +105, 160, 153, 229, -76, -127, -149, -267, +56, 100, 169, 307, -44, -38, -176, -332, +-1, -54, 192, 331, 41, 127, -176, -276, +-85, -189, 144, 228, 104, 208, -123, -156, +-96, -225, 90, 102, 119, 223, -85, -51, +-125, -211, 52, -8, 161, 201, -21, 38, +-166, -169, -23, -77, 151, 156, 76, 92, +-139, -129, -106, -122, 90, 107, 160, 156, +-54, -87, -167, -180, -1, 20, 175, 201, +13, 43, -137, -154, -19, -107, 101, 80, +9, 110, -69, -9, 7, -67, 14, -12, +-2, 49, 5, 6, 44, -78, -54, -49, +-49, 106, 60, 145, 81, -55, -79, -219, +-97, -63, 62, 210, 124, 147, -18, -140, +-134, -163, -21, 95, 111, 138, 72, -89, +-97, -160, -89, 58, 74, 209, 132, 49, +-94, -192, -159, -188, 75, 109, 184, 269, +-52, 11, -166, -303, 28, -96, 153, 291, +-8, 165, -157, -298, 1, -224, 165, 291, +40, 287, -185, -276, -61, -358, 171, 271, +83, 432, -172, -211, -77, -538, 171, 99, +83, 573, -172, 67, -95, -521, 175, -187, +120, 411, -162, 201, -142, -345, 148, -218, +161, 355, -107, 282, -172, -312, 53, -386, +150, 182, -2, 399, -111, -26, -17, -289, +60, -41, 23, 173, -34, 22, -46, -124, +24, -27, 75, 114, 13, 101, -97, -58, +-50, -169, 73, -74, 85, 188, -30, 173, +-102, -124, 9, -246, 101, 67, 13, 274, +-91, -24, -29, -289, 51, -40, 65, 306, +-2, 88, -85, -265, -61, -148, 91, 235, +99, 183, -92, -170, -102, -233, 55, 100, +99, 270, -5, -3, -84, -256, -79, -96, +94, 218, 142, 135, -102, -164, -186, -169, +117, 145, 209, 202, -110, -101, -214, -259, +62, 27, 228, 264, -7, 65, -207, -208, +-55, -137, 193, 129, 85, 141, -154, -54, +-97, -157, 120, 35, 69, 162, -76, 12, +-35, -179, 37, -56, 7, 148, 8, 94, +-12, -77, -44, -126, 40, 15, 78, 127, +-48, 43, -104, -164, 34, -59, 94, 200, +13, 94, -81, -232, -41, -140, 43, 223, +100, 153, -28, -153, -134, -165, 10, 88, +178, 132, -1, -19, -209, -130, -8, -23, +226, 151, 28, 82, -262, -164, -33, -166, +266, 153, 60, 216, -249, -103, -69, -241, +187, 69, 111, 225, -136, -38, -163, -224, +94, 13, 236, 216, -81, 51, -286, -185, +67, -107, 287, 125, -58, 147, -258, -60, +56, -173, 220, 8, -22, 183, -187, 47, +-24, -202, 158, -107, 92, 178, -141, 155, +-128, -142, 109, -132, 134, 131, -94, 87, +-110, -158, 57, -52, 81, 193, -28, 40, +-58, -165, 0, -12, 27, 122, 20, -51, +-20, -85, -22, 98, 0, 74, 49, -109, +0, -40, -46, 112, -42, -12, 53, -162, +101, 23, -8, 206, -169, 7, -23, -211, +212, -29, 33, 177, -227, 3, -33, -151, +233, 25, 14, 181, -207, -32, -30, -167, +176, -13, 39, 136, -122, 24, -70, -73, +70, -28, 110, 37, -8, 45, -139, -3, +-70, -74, 147, -93, 138, 89, -120, 205, +-209, -6, 96, -301, 251, -108, -61, 323, +-278, 222, 32, -334, 287, -328, 19, 352, +-285, 443, -79, -344, 263, -550, 121, 313, +-223, 598, -142, -280, 175, -606, 153, 274, +-109, 624, -175, -240, 43, -693, 207, 125, +24, 721, -218, 66, -75, -689, 219, -209, +79, 609, -171, 268, -51, -592, 126, -292, +-3, 620, -53, 342, 44, -619, -10, -408, +-63, 569, 45, 404, 75, -493, -45, -350, +-90, 494, 12, 269, 128, -517, 17, -222, +-173, 543, -38, 165, 219, -528, 56, -81, +-238, 511, -84, -23, 242, -514, 133, 87, +-217, 543, -191, -111, 183, -565, 229, 81, +-119, 596, -231, -23, 73, -635, 198, -65, +-20, 640, -140, 187, -30, -631, 118, -281, +83, 556, -93, 376, -146, -489, 106, -439, +173, 377, -66, 525, -190, -243, 23, -584, +173, 75, 60, 609, -158, 100, -119, -596, +162, -248, 147, 555, -142, 394, -158, -529, +147, -500, 133, 459, -102, 628, -151, -380, +80, -672, 161, 225, -11, 702, -180, -90, +-32, -669, 196, -58, 68, 635, -182, 220, +-97, -618, 189, -345, 123, 533, -150, 515, +-182, -475, 127, -563, 228, 329, -56, 623, +-251, -248, 23, -623, 253, 122, 40, 638, +-247, 42, -74, -649, 247, -208, 140, 558, +-212, 425, -199, -459, 166, -530, 269, 282, +-37, 623, -338, -161, -51, -654, 388, 19, +170, 669, -425, 136, -237, -629, 438, -279, +313, 508, -400, 413, -355, -371, 374, -484, +391, 192, -289, 568, -393, -27, 229, -594, +389, -182, -104, 570, -351, 372, -8, -469, +319, -512, 157, 320, -241, 624, -286, -191, +215, -713, 398, 14, -150, 800, -450, 193, +128, -779, 469, -405, -76, 667, -413, 539, +47, -505, 389, -587, 8, 342, -286, 618, +-57, -200, 220, -655, 106, 16, -71, 663, +-139, 207, -42, -622, 213, -400, 189, 499, +-227, 550, -323, -373, 294, -633, 445, 230, +-255, 690, -528, -50, 263, -704, 581, -137, +-202, 652, -583, 348, 161, -605, 621, -516, +-70, 536, -587, 696, -33, -479, 582, -843, +158, 390, -480, 923, -247, -255, 398, -939, +375, 139, -257, 889, -402, 23, 130, -855, +459, -239, 37, 766, -400, 543, -163, -590, +341, -844, 284, 353, -228, 1052, -309, -56, +111, -1197, 376, -216, 37, 1249, -323, 532, +-170, -1217, 300, -860, 317, 1065, -155, 1155, +-368, -773, 6, -1378, 444, 428, 195, 1498, +-399, -17, -385, -1554, 363, -429, 565, 1477, +-174, 901, -667, -1227, 2, -1310, 718, 809, +282, 1542, -642, -288, -474, -1611, 551, -224, +728, 1495, -346, 746, -872, -1268, 153, -1204, +999, 841, 171, 1581, -1027, -267, -417, -1772, +959, -383, 747, 1712, -819, 1040, -905, -1498, +612, -1563, 1074, 1103, -302, 2020, -1062, -641, +11, -2301, 1010, 65, 385, 2402, -828, 562, +-630, -2275, 572, -1132, 906, 1871, -266, 1620, +-965, -1327, -84, -1882, 1018, 649, 428, 1977, +-881, 24, -718, -1878, 749, -632, 1003, 1592, +-488, 1160, -1121, -1184, 230, -1486, 1245, 630, +88, 1624, -1134, -55, -388, -1541, 1052, -511, +624, 1267, -775, 988, -772, -873, 525, -1318, +839, 396, -173, 1467, -770, 88, -123, -1409, +729, -519, 390, 1182, -505, 835, -565, -791, +365, -1051, 680, 344, -68, 1089, -693, 140, +-166, -976, 696, -574, 413, 741, -600, 848, +-582, -369, 532, -1020, 687, 20, -351, 987, +-653, 352, 215, -839, 605, -687, 8, 555, +-426, 887, -132, -90, 309, -987, 281, -382, +-137, 833, -311, 825, 11, -546, 354, -1140, +143, 194, -348, 1288, -225, 216, 341, -1341, +347, -624, -283, 1225, -354, 1010, 259, -942, +418, -1309, -180, 565, -418, 1431, 193, -137, +448, -1399, -160, -247, -434, 1254, 183, 549, +426, -990, -182, -802, -390, 689, 188, 903, +386, -305, -154, -875, -372, -38, 136, 709, +417, 289, -8, -433, -420, -459, -53, 163, +427, 453, 162, 149, -342, -358, -229, -351, +268, 113, 249, 472, -110, 167, -296, -481, +9, -421, 274, 391, 167, 653, -228, -270, +-311, -791, 196, 60, 454, 845, -20, 193, +-569, -754, -59, -463, 559, 534, 273, 676, +-539, -206, -421, -839, 432, -102, 553, 874, +-269, 444, -705, -852, 134, -748, 705, 715, +113, 992, -678, -431, -275, -1188, 547, 135, +467, 1198, -326, 233, -587, -1172, 137, -516, +640, 1028, 90, 770, -653, -827, -306, -971, +541, 583, 505, 1061, -381, -250, -706, -1083, +120, -50, 848, 956, 139, 365, -875, -759, +-414, -578, 827, 474, 664, 713, -673, -168, +-848, -746, 439, -121, 997, 669, -240, 383, +-1056, -538, -82, -552, 1056, 323, 271, 681, +-992, -76, -473, -714, 809, -194, 605, 636, +-624, 447, -618, -487, 317, -620, 675, 265, +-93, 716, -619, -23, -191, -770, 528, -212, +376, 740, -447, 478, -542, -646, 214, -713, +606, 460, -120, 847, -575, -183, -83, -888, +490, -65, 131, 804, -374, 282, -193, -666, +241, -457, 198, 524, -152, 570, -218, -316, +-21, -674, 191, 93, 63, 683, -178, 167, +-187, -611, 78, -427, 119, 476, -9, 595, +-157, -270, -73, -723, 92, 99, 49, 751, +-93, 104, -37, -730, 63, -298, -104, 628, +-28, 469, 130, -438, -50, -629, -293, 229, +20, 681, 305, 18, -63, -698, -385, -200, +-102, 626, 312, 360, 176, -518, -292, -462, +-331, 369, 178, 495, 380, -174, -149, -503, +-449, 10, 7, 400, 390, 161, 58, -275, +-450, -246, -259, 107, 304, 259, 291, 76, +-272, -217, -389, -196, 18, 100, 276, 284, +138, 12, -219, -300, -367, -121, 18, 255, +444, 207, 92, -192, -557, -241, -343, 95, +473, 229, 441, 8, -475, -185, -720, -49, +226, 81, 763, 94, -113, 17, -905, -51, +-186, -141, 793, -60, 326, 279, -714, 197, +-599, -315, 447, -429, 704, 348, -285, 597, +-905, -257, -62, -726, 826, 112, 242, 812, +-851, 32, -601, -771, 565, -258, 688, 727, +-423, 431, -888, -585, 120, -580, 810, 395, +41, 656, -867, -250, -292, -601, 729, 102, +341, 511, -695, -24, -569, -379, 486, -12, +460, 210, -426, 49, -562, -64, 195, -13, +379, -77, -263, -64, -342, 140, 97, 150, +207, -65, -216, -271, -227, -55, 143, 283, +114, 262, -252, -247, -286, -444, 204, 167, +195, 569, -272, 6, -443, -699, 69, -142, +430, 693, -79, 373, -583, -644, -268, -554, +489, 476, 348, 677, -464, -189, -645, -747, +212, -100, 713, 630, -168, 440, -873, -456, +-205, -681, 788, 178, 312, 866, -825, 170, +-720, -979, 482, -545, 833, 918, -308, 943, +-1066, -705, -208, -1263, 963, 348, 462, 1405, +-946, 104, -874, -1376, 602, -528, 990, 1175, +-421, 874, -1235, -836, -55, -1158, 1098, 437, +277, 1290, -1116, 54, -705, -1294, 667, -542, +785, 1113, -425, 977, -1008, -741, -82, -1303, +803, 288, 368, 1428, -781, 216, -746, -1392, +367, -665, 830, 1193, -169, 1017, -1045, -838, +-318, -1242, 760, 384, 586, 1265, -703, 140, +-976, -1095, 171, -622, 968, 740, 93, 974, +-1077, -253, -548, -1157, 706, -223, 765, 1118, +-601, 696, -1033, -925, 101, -1058, 948, 585, +148, 1288, -1001, -115, -637, -1417, 532, -348, +843, 1309, -348, 852, -1150, -1061, -271, -1239, +1063, 664, 562, 1425, -1072, -126, -1031, -1500, +648, -334, 1175, 1315, -426, 784, -1392, -1034, +-176, -1129, 1252, 687, 434, 1268, -1215, -184, +-949, -1364, 730, -237, 1023, 1193, -448, 653, +-1258, -868, -149, -974, 1059, 516, 392, 1016, +-999, -32, -824, -995, 579, -318, 862, 802, +-357, 630, -1101, -466, -149, -906, 869, 128, +351, 957, -849, 336, -753, -879, 384, -733, +723, 644, -177, 938, -889, -232, -262, -1064, +626, -128, 393, 971, -605, 471, -649, -735, +242, -813, 526, 481, -130, 952, -589, -29, +-250, -1051, 237, -388, 276, 936, -167, 774, +-500, -593, -217, -1132, 249, 230, 280, 1212, +-230, 304, -547, -1194, -140, -758, 468, 965, +268, 1113, -580, -551, -625, -1408, 275, 87, +707, 1439, -191, 517, -953, -1328, -287, -1081, +760, 1006, 457, 1508, -746, -477, -883, -1783, +304, -50, 907, 1779, -90, 609, -1096, -1587, +-436, -1094, 907, 1243, 643, 1442, -847, -695, +-1104, -1684, 441, 94, 1138, 1668, -214, 536, +-1355, -1407, -362, -1077, 1154, 975, 541, 1382, +-1052, -388, -990, -1498, 607, -186, 980, 1397, +-358, 692, -1107, -1092, -188, -1126, 907, 678, +369, 1336, -789, -146, -797, -1344, 351, -413, +784, 1167, -156, 831, -880, -748, -364, -1146, +576, 286, 472, 1206, -407, 199, -774, -1063, +-76, -647, 689, 787, 276, 922, -709, -335, +-706, -1088, 375, -183, 801, 1053, -229, 696, +-1023, -783, -294, -1147, 861, 378, 500, 1389, +-821, 119, -937, -1388, 371, -628, 990, 1226, +-183, 997, -1117, -837, -315, -1290, 863, 387, +507, 1406, -737, 128, -873, -1332, 257, -651, +881, 1136, -5, 1015, -1012, -738, -490, -1256, +704, 305, 660, 1269, -576, 157, -951, -1120, +87, -557, 849, 824, 188, 866, -926, -436, +-601, -1032, 566, 14, 777, 1042, -441, 385, +-1014, -885, -25, -679, 882, 585, 270, 870, +-937, -247, -624, -878, 516, -130, 726, 802, +-385, 416, -874, -580, -72, -638, 676, 320, +278, 718, -671, -14, -563, -682, 314, -269, +579, 552, -218, 457, -665, -318, -94, -575, +380, 96, 177, 502, -294, 162, -390, -352, +-78, -330, 251, 87, 224, 427, -306, 232, +-442, -449, -44, -504, 433, 336, 174, 766, +-526, -187, -482, -893, 230, -31, 636, 896, +-191, 299, -787, -804, -255, -504, 666, 557, +490, 691, -697, -259, -819, -793, 291, -44, +964, 749, -160, 381, -1070, -666, -269, -586, +856, 410, 550, 728, -804, -95, -885, -763, +383, -208, 1019, 608, -183, 571, -1184, -448, +-210, -772, 908, 160, 475, 870, -792, 160, +-801, -867, 348, -407, 863, 650, -66, 664, +-1036, -411, -261, -808, 797, 118, 449, 810, +-676, 230, -692, -788, 283, -463, 634, 573, +3, 697, -757, -280, -350, -837, 514, -16, +463, 799, -409, 376, -643, -744, 91, -576, +491, 552, 115, 712, -491, -272, -406, -796, +240, 8, 482, 699, -115, 341, -643, -609, +-123, -591, 486, 435, 224, 727, -455, -222, +-396, -795, 152, 59, 353, 693, 11, 145, +-412, -532, -286, -326, 207, 323, 391, 435, +-169, -48, -481, -531, -104, -152, 384, 498, +201, 324, -315, -419, -466, -434, 29, 291, +587, 442, 82, -68, -748, -446, -384, -115, +721, 313, 435, 329, -707, -171, -566, -454, +460, -14, 520, 485, -289, 209, -529, -489, +-64, -352, 367, 389, 278, 514, -357, -241, +-507, -634, 142, 30, 523, 667, -82, 231, +-553, -627, -126, -441, 304, 503, 260, 616, +-240, -300, -380, -773, -57, 110, 396, 837, +140, 146, -401, -887, -297, -356, 140, 863, +370, 490, -36, -742, -425, -567, -322, 634, +380, 503, 473, -454, -388, -408, -662, 296, +157, 268, 723, -142, -73, -88, -746, 8, +-205, -60, 603, 54, 370, 210, -554, -72, +-534, -297, 276, 59, 581, 311, -153, -26, +-606, -291, -81, 36, 378, 188, 267, -42, +-273, -70, -433, 90, -57, -82, 526, -172, +261, 235, -637, 226, -481, -320, 508, -334, +653, 393, -487, 407, -787, -384, 253, -475, +778, 291, -68, 562, -856, -198, -120, -577, +680, 32, 274, 594, -610, 96, -404, -609, +396, -172, 366, 568, -189, 272, -406, -575, +-31, -251, 230, 495, 196, 178, -106, -389, +-411, -52, -87, 319, 420, -176, 258, -189, +-524, 336, -447, 123, 442, -501, 514, -48, +-341, 648, -702, 4, 206, -738, 687, -88, +-38, 836, -798, 239, -116, -877, 771, -461, +150, 889, -751, 754, -273, -933, 699, -1037, +171, 964, -616, 1342, -215, -965, 526, -1636, +114, 1008, -510, 1788, -63, -981, 405, -1915, +-2, 1050, -463, 1919, 76, -1102, 383, -1839, +-146, 1157, -404, 1718, 145, -1290, 360, -1474, +-205, 1388, -354, 1286, 165, -1556, 315, -1134, +-219, 1710, -335, 1027, 249, -1793, 248, -1032, +-293, 1899, -272, 1051, 348, -1960, 225, -1138, +-455, 1976, -242, 1287, 476, -1948, 305, -1390, +-640, 1821, -339, 1427, 654, -1639, 373, -1409, +-701, 1456, -456, 1249, 689, -1180, 400, -1088, +-546, 905, -507, 845, 423, -611, 455, -557, +-251, 313, -450, 360, 36, -132, 411, -182, +16, -52, -256, 151, -203, 153, 99, -155, +223, -202, 84, 227, -287, 196, -334, -335, +334, -186, 444, 477, -313, 186, -606, -572, +269, -267, 660, 629, -234, 358, -635, -595, +66, -492, 613, 507, 5, 652, -553, -377, +-153, -789, 469, 136, 300, 962, -553, 79, +-330, -1014, 519, -382, 405, 1058, -656, 639, +-393, -1005, 744, -874, 264, 869, -735, 1136, +-270, -725, 807, -1311, 116, 484, -723, 1486, +-125, -266, 637, -1599, 141, 67, -599, 1630, +-98, 120, 420, -1611, 118, -301, -316, 1529, +-77, 390, 146, -1280, -10, -532, 99, 1074, +-23, 538, -234, -799, -43, -536, 373, 539, +46, 558, -466, -377, -33, -434, 397, 135, +97, 362, -404, -27, -79, -180, 284, -67, +95, -5, -182, 135, -127, 143, 109, -177, +113, -247, -8, 206, -178, 320, -41, -266, +261, -243, 27, 243, -349, 136, -19, -281, +514, 50, -109, 316, -631, -260, 217, -294, +739, 346, -321, 342, -866, -434, 449, -342, +881, 359, -434, 457, -943, -195, 423, -628, +923, -68, -325, 816, -874, 399, 146, -1022, +855, -657, -26, 1180, -723, 846, -176, -1297, +618, -967, 329, 1324, -478, 1011, -435, -1221, +301, -979, 543, 997, -142, 859, -591, -743, +23, -645, 550, 461, 152, 458, -544, -235, +-221, -234, 415, 0, 326, 25, -266, 219, +-439, 149, 178, -349, 405, -304, 33, 467, +-465, 341, -105, -507, 417, -333, 207, 531, +-319, 292, -337, -528, 269, -207, 400, 487, +-142, 135, -497, -461, 52, -67, 609, 489, +-37, 32, -632, -539, -31, -55, 703, 624, +53, 113, -752, -712, -25, -156, 728, 775, +95, 222, -752, -849, -76, -276, 691, 879, +146, 314, -569, -840, -308, -310, 515, 768, +459, 210, -370, -660, -712, -43, 313, 542, +943, -180, -233, -431, -1101, 458, 122, 302, +1243, -794, 23, -183, -1276, 1141, -190, 141, +1239, -1480, 443, -140, -1180, 1733, -650, 189, +1050, -1850, 887, -285, -874, 1874, -1095, 402, +713, -1760, 1194, -567, -459, 1527, -1229, 779, +227, -1218, 1145, -936, 64, 826, -946, 1054, +-384, -469, 766, -1070, 673, 158, -487, 965, +-950, 127, 289, -793, 1105, -331, -47, 480, +-1128, 500, -172, -112, 1071, -591, 396, -291, +-888, 583, -650, 672, 764, -517, 864, -982, +-602, 384, -1041, 1213, 554, -218, 1107, -1371, +-503, 49, -1056, 1435, 500, 131, 933, -1422, +-473, -304, -761, 1350, 468, 422, 593, -1156, +-438, -566, -435, 969, 428, 614, 323, -717, +-387, -678, -192, 502, 308, 718, 140, -323, +-220, -724, -38, 139, 76, 761, 7, -11, +45, -730, 86, -118, -166, 712, -191, 182, +331, -686, 305, -235, -408, 674, -485, 257, +573, -642, 590, -313, -617, 625, -676, 305, +666, -552, 704, -311, -635, 494, -625, 287, +533, -435, 531, -236, -410, 344, -355, 204, +289, -263, 140, -107, -154, 155, 81, -12, +108, -72, -299, 138, -110, 31, 520, -250, +173, -55, -638, 361, -348, 142, 804, -428, +477, -351, -829, 506, -639, 648, 850, -555, +756, -1001, -800, 562, -787, 1393, 651, -553, +804, -1700, -500, 470, -716, 1958, 304, -310, +611, -2101, -131, 62, -469, 2119, 21, 280, +328, -2027, 39, -673, -163, 1835, -39, 1065, +63, -1544, -37, -1435, 42, 1173, 127, 1705, +-42, -704, -264, -1829, -4, 164, 412, 1825, +76, 369, -499, -1654, -216, -911, 618, 1421, +274, 1389, -579, -1096, -363, -1820, 524, 705, +413, 2149, -360, -297, -413, -2331, 142, -140, +428, 2405, 49, 494, -359, -2338, -227, -816, +272, 2199, 337, 1084, -132, -2003, -335, -1299, +-74, 1721, 297, 1475, 281, -1407, -174, -1564, +-478, 1072, -3, 1577, 706, -738, 134, -1534, +-819, 416, -307, 1441, 919, -91, 419, -1294, +-943, -254, -464, 1144, 849, 568, 516, -934, +-760, -896, -465, 740, 606, 1168, 398, -529, +-423, -1382, -325, 275, 287, 1555, 213, -54, +-118, -1587, -167, -230, 18, 1604, 129, 472, +29, -1503, -98, -750, -58, 1357, 127, 982, +38, -1147, -135, -1165, -56, 894, 171, 1284, +101, -626, -221, -1336, -142, 331, 266, 1324, +220, -41, -303, -1252, -296, -248, 333, 1122, +340, 478, -276, -924, -414, -666, 193, 729, +429, 757, -39, -471, -435, -844, -150, 248, +415, 840, 300, 21, -314, -789, -472, -257, +215, 684, 540, 402, -19, -506, -578, -520, +-180, 377, 537, 519, 371, -202, -423, -505, +-561, 53, 262, 433, 689, 88, -38, -305, +-781, -214, -189, 134, 804, 274, 406, 60, +-791, -262, -536, -270, 680, 228, 629, 440, +-543, -154, -597, -602, 309, 50, 556, 714, +-97, 74, -440, -728, -113, -252, 267, 697, +270, 410, -96, -560, -328, -580, -143, 398, +342, 736, 355, -230, -304, -830, -549, 37, +217, 909, 724, 87, -139, -891, -814, -202, +39, 841, 846, 251, 69, -766, -827, -264, +-162, 642, 725, 296, 279, -527, -646, -291, +-365, 391, 547, 263, 440, -262, -468, -262, +-476, 213, 414, 218, 428, -155, -336, -198, +-386, 157, 259, 170, 299, -204, -129, -73, +-246, 220, -28, 8, 192, -288, 229, 112, +-190, 316, -416, -240, 157, -308, 640, 323, +-141, 345, -827, -436, 55, -353, 1021, 470, +59, 413, -1194, -459, -202, -504, 1298, 436, +423, 577, -1416, -358, -589, -699, 1382, 272, +829, 829, -1328, -150, -1035, -912, 1162, -54, +1201, 977, -873, 246, -1355, -944, 560, -453, +1390, 826, -153, 634, -1348, -678, -250, -715, +1211, 425, 632, 750, -977, -180, -947, -673, +690, -69, 1173, 469, -386, 318, -1249, -240, +53, -441, 1224, -89, 227, 532, -1060, 397, +-481, -518, 811, -686, 693, 417, -533, 956, +-794, -280, 169, -1110, 864, 48, 160, 1208, +-811, 217, -483, -1219, 670, -492, 781, 1095, +-481, 830, -993, -935, 226, -1087, 1138, 661, +25, 1288, -1170, -329, -248, -1395, 1079, 17, +458, 1312, -905, 324, -583, -1148, 636, -581, +692, 888, -339, 721, -719, -577, 46, -814, +660, 355, 253, 772, -554, -146, -473, -692, +353, -2, 698, 561, -135, 67, -834, -351, +-110, -128, 956, 153, 335, 105, -983, 44, +-551, -47, 971, -215, 742, 0, -883, 316, +-922, 73, 768, -402, 1083, -150, -608, 476, +-1216, 216, 422, -482, 1346, -347, -232, 509, +-1380, 433, -33, -463, 1410, -527, 280, 410, +-1323, 612, -536, -370, 1192, -642, 764, 275, +-988, 717, -927, -227, 714, -718, 1060, 120, +-390, 752, -1097, -46, 4, -761, 1137, -60, +370, 765, -1077, 196, -766, -754, 1007, -337, +1101, 718, -824, 496, -1384, -671, 595, -673, +1568, 617, -257, 870, -1643, -523, -108, -1085, +1587, 363, 520, 1281, -1383, -171, -903, -1385, +1079, -98, 1247, 1456, -679, 335, -1493, -1421, +283, -625, 1640, 1337, 132, 906, -1673, -1178, +-470, -1155, 1602, 930, 763, 1384, -1419, -648, +-999, -1522, 1184, 321, 1167, 1606, -875, 42, +-1257, -1582, 537, -453, 1304, 1447, -198, 851, +-1238, -1156, -132, -1215, 1115, 820, 436, 1465, +-923, -433, -665, -1637, 681, 98, 848, 1728, +-395, 181, -945, -1698, 102, -434, 992, 1593, +201, 578, -973, -1343, -457, -680, 928, 1056, +700, 687, -831, -726, -907, -674, 719, 419, +1063, 675, -526, -111, -1191, -664, 335, -212, +1286, 640, -106, 509, -1282, -565, -130, -786, +1254, 446, 389, 972, -1109, -288, -636, -1099, +901, 129, 916, 1123, -598, 40, -1153, -1104, +272, -186, 1345, 1017, 117, 347, -1426, -910, +-475, -501, 1387, 777, 856, 634, -1199, -612, +-1177, -733, 904, 456, 1492, 757, -525, -308, +-1686, -735, 133, 174, 1833, 657, 254, -59, +-1824, -545, -606, -27, 1763, 384, 894, 120, +-1569, -215, -1116, -151, 1335, 19, 1295, 168, +-1054, 171, -1344, -165, 731, -318, 1367, 114, +-417, 470, -1247, -82, 109, -542, 1105, 3, +120, 579, -857, 87, -287, -548, 622, -160, +354, 466, -368, 238, -321, -372, 134, -289, +285, 278, 40, 323, -150, -201, -186, -337, +66, 126, 248, 338, 85, -107, -286, -263, +-180, 92, 264, 206, 322, -169, -212, -120, +-420, 261, 161, 60, 515, -359, -33, -33, +-566, 458, -59, -14, 572, -530, 226, 42, +-534, 612, -300, -37, 442, -703, 414, -20, +-320, 755, -413, 156, 192, -752, 418, -321, +-39, 700, -372, 457, -54, -564, 352, -584, +165, 455, -323, 647, -192, -310, 308, -697, +247, 192, -281, 731, -237, -69, 234, -694, +260, -45, -156, 638, -263, 96, 102, -494, +263, -112, -14, 350, -226, 83, -54, -189, +167, -39, 125, 41, -44, 15, -169, 78, +-79, -16, 223, -170, 202, 25, -214, 219, +-315, -80, 195, -197, 399, 139, -100, 153, +-474, -256, -3, -123, 539, 379, 163, 101, +-562, -501, -298, -169, 571, 610, 424, 275, +-524, -681, -491, -435, 465, 679, 568, 629, +-348, -656, -589, -816, 253, 542, 603, 981, +-64, -375, -615, -1090, -70, 177, 612, 1098, +292, 73, -561, -1050, -464, -288, 538, 925, +649, 497, -416, -741, -757, -662, 328, 547, +829, 766, -125, -285, -812, -788, -31, 51, +751, 707, 262, 204, -643, -532, -411, -367, +527, 335, 566, 503, -390, -112, -652, -574, +276, -63, 712, 630, -115, 259, -754, -619, +-11, -419, 740, 558, 195, 538, -721, -412, +-341, -587, 657, 257, 481, 545, -572, -128, +-589, -455, 479, 21, 658, 348, -404, 7, +-677, -229, 338, -44, 660, 110, -269, -7, +-628, -24, 244, 58, 560, -49, -171, -167, +-501, 23, 119, 241, 461, 6, -35, -294, +-389, -112, -31, 261, 345, 174, 115, -206, +-222, -244, -158, 111, 145, 246, 205, -14, +26, -252, -210, -59, -91, 201, 235, 150, +208, -147, -199, -192, -217, 76, 199, 227, +266, 22, -105, -195, -247, -71, 61, 142, +261, 138, 72, -25, -237, -107, -110, -75, +254, 85, 190, 198, -222, 24, -178, -238, +209, -107, 176, 278, -168, 243, -103, -189, +126, -352, 45, 74, -86, 461, 10, 146, +72, -502, -77, -352, -71, 520, 54, 570, +99, -478, -40, -740, -136, 384, -50, 868, +194, -287, 119, -961, -238, 88, -222, 981, +263, 89, 266, -973, -266, -315, -312, 875, +207, 472, 324, -831, -142, -643, -300, 721, +35, 751, 288, -687, 40, -886, -206, 570, +-90, 937, 157, -510, 143, -994, -23, 380, +-115, 958, -80, -322, 155, -927, 248, 250, +-125, 860, -310, -213, 164, -824, 443, 185, +-109, 776, -426, -138, 123, -748, 445, 144, +-4, 758, -363, -77, -17, -757, 330, 41, +140, 814, -214, 96, -156, -792, 166, -178, +206, 799, -67, 360, -166, -697, 43, -438, +126, 614, -5, 568, -28, -436, 14, -590, +-67, 310, -37, 626, 175, -108, 45, -583, +-306, -16, -61, 523, 387, 175, 44, -426, +-514, -276, -47, 296, 552, 351, 2, -161, +-611, -425, -29, -8, 581, 419, 15, 140, +-563, -442, -82, -304, 467, 351, 112, 374, +-386, -331, -152, -475, 258, 212, 156, 444, +-147, -220, -95, -465, 44, 136, 24, 387, +56, -194, 121, -373, -80, 168, -219, 285, +145, -242, 366, -273, -89, 282, -399, 224, +109, -346, 512, -276, -10, 393, -492, 354, +8, -366, 575, -445, 112, 304, -553, 573, +-98, -153, 621, -596, 210, 39, -591, 656, +-196, 155, 612, -600, 301, -235, -523, 603, +-344, 435, 482, -473, 415, -498, -353, 423, +-474, 648, 296, -226, 486, -658, -226, 138, +-475, 696, 154, 62, 400, -619, -135, -173, +-338, 572, 59, 340, 200, -439, -50, -478, +-136, 288, -20, 603, -5, -119, -9, -677, +56, -97, -28, 655, -158, 209, -59, -624, +215, -384, 78, 463, -286, 430, -187, -406, +311, -556, 242, 189, -338, 571, -306, -108, +322, -682, 377, -126, -286, 620, -371, 214, +258, -662, 406, -404, -148, 561, -353, 479, +122, -563, 359, -633, 31, 480, -254, 710, +-75, -440, 281, -810, 224, 353, -160, 860, +-241, -256, 200, -836, 333, 157, -80, 823, +-269, 6, 71, -678, 299, -91, 47, 596, +-173, 280, -106, -384, 163, -297, 220, 276, +-69, 425, -276, -45, 19, -324, 337, -28, +28, 323, -346, 207, -92, -124, 311, -221, +122, 33, -314, 325, -182, 185, 231, -300, +186, -324, -238, 311, -261, 514, 162, -229, +229, -644, -166, 118, -322, 700, 89, 12, +268, -722, -76, -181, -326, 615, -24, 247, +266, -557, 43, -401, -221, 359, -139, 378, +133, -284, 172, -477, -27, 58, -219, 381, +-90, -10, 269, -404, 215, -175, -249, 259, +-310, 165, 295, -246, 453, -267, -228, 90, +-512, 246, 236, -31, 673, -287, -111, -148, +-651, 258, 82, 278, 734, -248, 94, -439, +-607, 238, -119, 598, 549, -184, 266, -686, +-331, 202, -238, 798, 202, -94, 268, -771, +23, 118, -186, 822, -121, 9, 129, -693, +242, 15, -29, 722, -292, 103, -62, -545, +292, -65, 156, 559, -317, 153, -260, -396, +235, -92, 325, 386, -249, 178, -454, -257, +131, -159, 472, 184, -92, 241, -579, -56, +-57, -275, 526, -89, 126, 277, -548, 206, +-280, -266, 441, -369, 314, 141, -395, 393, +-398, -76, 256, -496, 384, -107, -173, 410, +-377, 137, 47, -470, 363, -313, 33, 346, +-316, 306, -107, -374, 334, -460, 194, 224, +-283, 405, -205, -202, 318, -472, 328, 30, +-273, 362, -308, 19, 318, -315, 422, -165, +-239, 182, -376, 235, 254, -57, 444, -311, +-104, -97, -369, 362, 51, 280, 430, -296, +120, -400, -372, 243, -174, 568, 416, -21, +256, -564, -368, -98, -237, 670, 323, 373, +241, -570, -230, -506, -203, 607, 60, 778, +192, -419, 63, -847, -210, 369, -277, 996, +173, -150, 377, -930, -186, 104, -559, 917, +57, 24, 593, -786, -6, -22, -678, 689, +-199, 53, 608, -548, 271, -64, -565, 388, +-458, 29, 378, -243, 515, -50, -232, 60, +-632, -52, 1, -3, 646, 41, 178, -116, +-666, -162, -357, 44, 628, 127, 501, -96, +-538, -230, -578, -43, 448, 168, 648, 21, +-266, -225, -607, -164, 174, 123, 599, 126, +26, -130, -453, -217, -64, 45, 391, 204, +170, -52, -198, -276, -113, 34, 135, 361, +116, -43, 30, -461, 35, 43, -60, 594, +-101, 19, 144, -629, 259, -20, -142, 720, +-351, 129, 172, -655, 449, -102, -154, 698, +-521, 214, 155, -585, 545, -184, -164, 611, +-584, 310, 133, -448, 552, -277, -165, 403, +-570, 362, 90, -202, 503, -284, -111, 110, +-534, 301, 16, 67, 437, -210, -16, -172, +-446, 156, -83, 303, 303, -54, 90, -397, +-243, -67, -179, 418, 87, 155, 192, -470, +16, -287, -269, 386, -142, 328, 283, -386, +230, -445, -291, 213, -309, 397, 295, -167, +395, -477, -208, -22, -439, 334, 153, 59, +549, -352, -7, -178, -541, 200, -101, 134, +636, -200, 278, -177, -553, 119, -356, 92, +549, -145, 516, -95, -415, 143, -517, 77, +318, -183, 597, -87, -156, 213, -522, 146, +42, -211, 493, -184, 136, 257, -385, 273, +-243, -188, 287, -320, 366, 249, -176, 463, +-445, -147, 49, -504, 433, 149, 74, 688, +-424, 1, -238, -671, 307, -72, 307, 770, +-232, 262, -448, -665, 106, -328, 392, 625, +-42, 491, -411, -465, -79, -524, 264, 348, +89, 593, -184, -175, -199, -596, 58, 49, +178, 544, -21, 82, -235, -502, -30, -205, +199, 378, 12, 247, -185, -297, -32, -361, +157, 142, 35, 317, -125, -96, -17, -376, +119, -54, 66, 268, -117, 40, -33, -266, +160, -140, 82, 133, -161, 73, -64, -115, +253, -103, 98, -6, -235, 35, -83, 11, +322, -31, 103, -94, -287, -10, -58, 117, +311, 22, 83, -153, -248, -49, -38, 185, +221, 59, 58, -145, -168, -26, -43, 167, +157, 34, 11, -94, -146, 45, 15, 130, +126, -4, -58, -69, -155, 74, 85, 125, +124, -15, -107, -69, -179, 55, 95, 135, +163, 23, -110, -81, -239, -9, 43, 108, +259, 105, -72, -42, -329, -111, -13, 24, +339, 189, -18, 37, -398, -211, -29, -70, +375, 229, 19, 111, -386, -264, -39, -182, +326, 220, 27, 228, -248, -219, -60, -334, +147, 113, 69, 338, -16, -85, -92, -417, +-76, -50, 124, 342, 188, 52, -94, -367, +-238, -167, 127, 255, 287, 150, -60, -241, +-279, -234, 71, 143, 297, 201, -40, -110, +-231, -216, 83, 20, 221, 135, -74, 4, +-154, -59, 123, -40, 132, -18, -113, 52, +-100, 107, 143, -34, 95, -132, -134, 58, +-89, 189, 124, 0, 111, -159, -131, 29, +-123, 198, 80, 45, 137, -114, -75, -1, +-166, 145, 2, 42, 149, -59, 34, 30, +-189, 78, -109, 9, 135, -19, 139, 56, +-133, 25, -218, -20, 51, 9, 221, 73, +-23, 11, -265, -89, -56, -16, 219, 122, +90, 58, -205, -167, -157, -111, 130, 162, +154, 141, -47, -176, -189, -208, -56, 93, +193, 179, 164, -64, -190, -215, -253, -78, +194, 131, 339, 110, -143, -120, -383, -253, +110, 5, 433, 258, -24, 37, -409, -339, +-30, -181, 426, 294, 124, 222, -362, -278, +-162, -329, 345, 198, 214, 354, -277, -123, +-192, -384, 225, 48, 212, 392, -173, 25, +-175, -358, 133, -49, 160, 369, -97, 112, +-141, -319, 75, -88, 136, 330, -63, 148, +-176, -264, 61, -92, 184, 296, -84, 148, +-228, -234, 57, -121, 250, 293, -79, 196, +-297, -234, 34, -210, 280, 269, -16, 298, +-320, -206, -47, -321, 289, 184, 62, 376, +-311, -116, -82, -379, 261, 41, 20, 371, +-210, 26, 6, -357, 141, -112, -98, 272, +-76, 144, 167, -234, 4, -204, -236, 121, +20, 153, 303, -87, -25, -181, -327, -8, +-6, 77, 352, 19, 84, -89, -337, -103, +-141, 7, 299, 89, 262, 3, -213, -163, +-348, -76, 167, 124, 463, 98, -66, -146, +-495, -159, 26, 102, 496, 185, 71, -60, +-433, -209, -128, 17, 373, 223, 204, 46, +-235, -194, -279, -75, 137, 205, 341, 155, +-42, -125, -379, -158, -40, 134, 375, 236, +105, -59, -353, -203, -176, 69, 281, 273, +195, -10, -227, -204, -215, 28, 104, 217, +185, 26, -36, -133, -169, -4, -90, 98, +99, 58, 145, -23, -69, -62, -208, -37, +-21, 75, 230, 98, 57, -84, -250, -147, +-123, 36, 228, 149, 156, -34, -214, -168, +-188, -36, 165, 100, 206, 41, -132, -109, +-202, -104, 79, 2, 211, 105, -18, -1, +-216, -186, -2, -83, 226, 168, 47, 89, +-199, -239, -69, -144, 206, 210, 109, 148, +-159, -222, -148, -194, 162, 184, 198, 201, +-104, -136, -249, -226, 90, 85, 299, 255, +-45, -4, -278, -231, -17, -65, 279, 230, +109, 163, -247, -126, -192, -200, 210, 78, +282, 286, -181, 41, -332, -264, 97, -87, +358, 344, -20, 196, -388, -315, -67, -244, +331, 356, 171, 373, -312, -319, -269, -430, +241, 305, 304, 541, -188, -256, -322, -602, +88, 224, 235, 662, 35, -163, -219, -710, +-165, 99, 149, 712, 230, -37, -85, -728, +-320, -76, 17, 685, 347, 119, 34, -661, +-340, -238, -128, 572, 309, 263, 204, -521, +-241, -351, -299, 363, 214, 357, 348, -278, +-155, -405, -349, 100, 97, 379, 346, 7, +-39, -380, -262, -139, -9, 296, 198, 206, +85, -226, -98, -255, -97, 113, 12, 270, +143, 11, 86, -266, -136, -87, -158, 267, +127, 198, 243, -244, -96, -221, -281, 265, +37, 292, 322, -206, 24, -296, -334, 210, +-77, 355, 317, -112, 121, -348, -301, 87, +-144, 405, 233, 11, 162, -388, -198, -65, +-170, 410, 150, 170, 140, -365, -132, -249, +-135, 307, 97, 365, 87, -216, -104, -436, +-68, 109, 64, 491, 16, -30, -43, -527, +19, -58, -45, 494, -37, 99, 104, -504, +28, -169, -172, 428, -48, 195, 231, -406, +39, -274, -265, 310, -91, 273, 326, -281, +161, -326, -381, 210, -225, 286, 418, -216, +324, -280, -422, 194, -401, 232, 402, -230, +502, -200, -323, 231, -567, 145, 254, -237, +609, -94, -97, 234, -622, 42, -24, -198, +627, 9, 149, 190, -530, -23, -276, -128, +434, 78, 389, 110, -301, -59, -476, -42, +167, 118, 522, 52, -49, -97, -497, -16, +-106, 125, 463, 38, 240, -82, -406, 10, +-365, 58, 319, -23, 462, 13, -256, 78, +-511, -57, 161, -123, 506, 135, -81, 155, +-510, -190, -8, -174, 460, 244, 70, 165, +-428, -315, -126, -178, 368, 326, 131, 169, +-303, -364, -158, -200, 230, 324, 122, 193, +-153, -306, -128, -221, 63, 233, 131, 181, +0, -203, -140, -181, -54, 118, 142, 120, +99, -74, -115, -70, -162, -29, 85, -15, +255, 99, -79, 108, -323, -176, 80, -207, +382, 226, -35, 290, -432, -230, 13, -362, +465, 243, 68, 419, -468, -185, -143, -452, +459, 149, 268, 520, -422, -51, -371, -527, +383, -25, 447, 571, -284, 158, -494, -515, +159, -230, 507, 466, 0, 329, -483, -338, +-168, -345, 431, 222, 328, 370, -360, -77, +-440, -343, 261, -40, 493, 306, -144, 161, +-517, -237, -1, -235, 488, 154, 98, 274, +-433, -73, -204, -292, 316, -3, 269, 254, +-215, 41, -314, -245, 96, -92, 313, 184, +-16, 87, -275, -155, -100, -115, 210, 88, +183, 89, -160, -51, -242, -104, 86, -19, +257, 80, -25, 37, -257, -74, -25, -69, +240, 52, 51, 33, -197, -56, -44, 6, +125, 62, 80, -58, -56, -83, -125, 110, +47, 106, 156, -122, -17, -117, -173, 145, +17, 144, 174, -118, 4, -117, -160, 120, +-29, 135, 161, -73, 60, -99, -136, 60, +-73, 83, 128, -8, 109, -33, -99, 9, +-106, 6, 41, 9, 124, 50, 26, 29, +-126, -60, -109, -64, 134, 81, 190, 104, +-155, -60, -222, -146, 141, 31, 240, 170, +-96, 13, -266, -202, 24, -88, 287, 224, +40, 161, -328, -253, -92, -281, 337, 233, +99, 372, -313, -223, -123, -462, 244, 154, +138, 479, -180, -98, -191, -499, 128, 23, +230, 457, -136, 17, -231, -449, 151, -59, +189, 399, -180, 60, -105, -363, 177, -51, +14, 312, -164, -2, 72, -260, 129, 53, +-90, 226, -100, -94, 43, -197, 113, 126, +32, 222, -175, -102, -67, -253, 242, 95, +78, 311, -244, -53, -75, -344, 214, 47, +129, 402, -149, -25, -198, -397, 105, 16, +267, 392, -23, 45, -324, -311, -31, -119, +373, 214, 94, 215, -360, -105, -124, -271, +327, -8, 163, 307, -251, 101, -221, -302, +199, -156, 251, 253, -133, 193, -257, -196, +53, -241, 257, 108, 52, 266, -284, -48, +-136, -301, 318, -29, 180, 284, -355, 55, +-179, -283, 363, -89, 164, 236, -365, 68, +-151, -209, 330, -84, 148, 165, -271, 84, +-220, -146, 229, -122, 286, 127, -224, 139, +-344, -128, 239, -159, 358, 108, -264, 177, +-328, -98, 240, -182, 287, 92, -191, 187, +-238, -66, 103, -172, 217, 17, 3, 159, +-211, 68, -56, -126, 225, -160, 59, 111, +-199, 266, -25, -61, 162, -345, -5, 52, +-84, 412, 17, -27, 48, -423, -27, 22, +-11, 438, 76, 10, -30, -403, -101, -32, +45, 383, 140, 53, -37, -317, -162, -52, +16, 245, 195, 42, -14, -157, -219, -19, +57, 65, 198, 2, -87, 21, -167, -19, +103, -117, 149, 49, -117, 185, -133, -118, +122, -231, 107, 151, -127, 236, -92, -187, +126, -239, 71, 197, -123, 194, -114, -201, +141, -165, 142, 178, -170, 127, -176, -144, +164, -141, 212, 91, -163, 176, -270, -58, +169, -232, 326, 32, -229, 294, -351, -25, +267, -348, 344, 40, -278, 393, -334, -65, +262, -398, 326, 81, -237, 407, -319, -72, +208, -395, 314, 77, -172, 421, -337, -69, +147, -434, 398, 75, -141, 480, -441, -28, +160, -559, 460, 4, -141, 658, -448, 50, +146, -768, 415, -67, -127, 867, -357, 99, +112, -943, 296, -110, -64, 1020, -216, 99, +-2, -1066, 180, -81, 37, 1092, -119, 58, +-40, -1077, 28, -38, 12, 1052, 85, -28, +23, -995, -188, 92, -41, 913, 251, -191, +46, -827, -255, 258, -83, 741, 223, -335, +132, -686, -160, 401, -244, 615, 101, -459, +354, -593, -77, 500, -420, 579, 39, -537, +429, -623, -1, 544, -394, 659, -52, -517, +325, -690, 74, 440, -241, 713, -75, -356, +121, -720, 89, 272, 26, 687, -142, -185, +-139, -619, 205, 78, 221, 542, -263, 68, +-224, -467, 271, -195, 199, 398, -211, 302, +-157, -315, 127, -364, 131, 270, 0, 389, +-158, -214, -81, -384, 234, 170, 154, 376, +-324, -79, -164, -388, 415, -27, 177, 431, +-471, 136, -171, -457, 517, -254, 179, 505, +-545, 362, -166, -553, 545, -495, 206, 623, +-520, 606, -287, -650, 493, -743, 393, 621, +-455, 882, -496, -541, 433, -1015, 513, 391, +-352, 1118, -517, -227, 255, -1177, 480, -10, +-137, 1229, -441, 210, 5, -1241, 388, -442, +102, 1219, -315, 637, -210, -1135, 215, -830, +258, 985, -96, 982, -270, -796, -56, -1054, +219, 537, 236, 1080, -206, -277, -371, -1038, +180, -3, 474, 982, -193, 235, -476, -872, +165, -459, 464, 743, -128, 644, -402, -588, +95, -772, 305, 420, -42, 851, -188, -228, +-4, -855, 70, 43, 100, 875, -31, 84, +-151, -856, 81, -176, 207, 857, -203, 224, +-192, -813, 350, -266, 181, 764, -494, 312, +-134, -677, 607, -325, 102, 539, -666, 380, +-90, -399, 683, -433, 138, 241, -640, 539, +-253, -123, 616, -649, 354, -8, -529, 758, +-454, 128, 428, -845, 471, -220, -266, 849, +-476, 303, 63, -797, 443, -328, 126, 651, +-405, 352, -308, -511, 345, -321, 417, 321, +-259, 276, -477, -117, 121, -230, 463, -115, +43, 156, -405, 361, -207, -98, 267, -543, +361, -23, -114, 698, -470, 107, -79, -741, +549, -180, 251, 699, -583, 227, -413, -568, +569, -264, 580, 369, -526, 341, -720, -167, +464, -388, 842, -75, -388, 454, -882, 289, +296, -456, 886, -474, -170, 402, -850, 609, +62, -289, 838, -669, 50, 116, -822, 709, +-135, 57, 840, -667, 188, -243, -836, 615, +-180, 417, 810, -528, 158, -606, -693, 429, +-168, 783, 574, -319, 238, -894, -494, 166, +-306, 959, 462, -20, 344, -951, -420, -126, +-345, 907, 317, 243, 339, -822, -177, -348, +-362, 708, 34, 460, 395, -583, 46, -545, +-404, 389, -121, 619, 408, -142, 127, -665, +-380, -136, -131, 668, 329, 423, 92, -664, +-243, -655, -69, 610, 142, 846, 61, -548, +-89, -973, -43, 430, 67, 1031, 31, -235, +-91, -1051, -26, -11, 133, 991, 57, 313, +-210, -894, -83, -569, 287, 704, 140, 771, +-360, -471, -161, -893, 384, 211, 213, 925, +-344, 86, -271, -895, 239, -377, 383, 760, +-45, 686, -528, -570, -117, -948, 665, 277, +320, 1101, -750, 79, -440, -1131, 746, -477, +587, 1001, -666, 867, -677, -758, 530, -1193, +761, 416, -357, 1435, -799, -14, 184, -1567, +773, -409, -4, 1551, -672, 847, -130, -1383, +469, -1269, 253, 1068, -209, 1614, -332, -596, +-105, -1855, 405, 53, 344, 1928, -385, 556, +-569, -1860, 294, -1106, 716, 1647, -136, 1572, +-826, -1280, -73, -1941, 860, 837, 268, 2144, +-791, -234, -508, -2253, 647, -376, 693, 2175, +-411, 1025, -874, -1964, 144, -1592, 979, 1629, +150, 1995, -1039, -1166, -399, -2260, 1000, 670, +634, 2292, -864, -96, -824, -2231, 651, -456, +1000, 2016, -376, 979, -1128, -1725, 147, -1429, +1152, 1342, 119, 1698, -1079, -862, -345, -1822, +911, 370, 575, 1732, -684, 137, -731, -1544, +439, -578, 833, 1259, -153, 928, -872, -920, +-127, -1158, 821, 561, 428, 1254, -702, -163, +-691, -1229, 513, -229, 958, 1066, -319, 602, +-1135, -793, 107, -888, 1234, 470, 96, 1056, +-1231, -123, -301, -1081, 1127, -178, 504, 994, +-944, 430, -717, -780, 688, -623, 920, 534, +-438, 743, -1087, -201, 155, -767, 1180, -127, +94, 684, -1181, 455, -363, -469, 1116, -741, +608, 184, -991, 905, -825, 177, 798, -979, +1004, -490, -571, 913, -1153, 784, 316, -775, +1271, -1002, -88, 540, -1302, 1122, -96, -240, +1259, -1172, 230, -89, -1100, 1056, -343, 451, +896, -848, 414, -769, -616, 503, -457, 1012, +320, -114, 490, -1157, -23, -302, -476, 1181, +-238, 683, 447, -1127, 433, -1009, -328, 982, +-561, 1234, 180, -770, 661, -1392, 4, 498, +-701, 1441, -157, -206, 696, -1374, 292, -90, +-614, 1225, -387, 299, 474, -954, 473, -454, +-294, 671, -526, 505, 104, -349, 556, -474, +68, 30, -546, 420, -193, 230, 477, -262, +291, -466, -368, 127, -375, 583, 213, 106, +449, -612, -94, -309, -474, 536, -30, 503, +454, -335, 136, -667, -414, 132, -234, 720, +346, 161, 305, -751, -272, -391, -343, 662, +191, 624, 355, -527, -116, -814, -345, 341, +52, 900, 317, -68, 16, -966, -261, -205, +-92, 877, 218, 524, 157, -768, -169, -792, +-188, 556, 131, 960, 207, -296, -63, -1079, +-209, 20, -16, 1035, 246, 294, 109, -970, +-265, -590, -167, 787, 274, 834, 253, -539, +-260, -1026, -337, 249, 239, 1054, 452, 105, +-192, -998, -555, -445, 181, 804, 622, 723, +-135, -491, -665, -943, 95, 167, 631, 1005, +28, 262, -585, -984, -189, -648, 512, 844, +360, 1022, -442, -539, -531, -1329, 365, 210, +621, 1471, -237, 283, -713, -1511, 95, -700, +719, 1351, 85, 1155, -695, -1061, -274, -1506, +611, 670, 450, 1745, -479, -145, -631, -1895, +325, -342, 753, 1805, -137, 908, -815, -1626, +-75, -1336, 811, 1232, 296, 1665, -754, -737, +-485, -1859, 662, 195, 640, 1804, -523, 421, +-720, -1673, 340, -935, 744, 1312, -141, 1369, +-650, -851, -77, -1678, 494, 332, 299, 1716, +-281, 272, -473, -1665, 75, -784, 588, 1344, +158, 1220, -585, -874, -417, -1553, 508, 328, +651, 1647, -337, 366, -857, -1667, 152, -954, +975, 1407, 92, 1526, -999, -1013, -351, -1933, +914, 496, 612, 2123, -707, 180, -853, -2196, +428, -763, 1042, 1979, -107, 1415, -1173, -1658, +-217, -1847, 1196, 1125, 536, 2140, -1096, -456, +-832, -2236, 884, -200, 1062, 2059, -590, 911, +-1196, -1756, 213, -1395, 1233, 1207, 170, 1804, +-1159, -567, -564, -1984, 985, -148, 896, 1947, +-697, 891, -1147, -1735, 322, -1516, 1321, 1285, +71, 2030, -1365, -736, -494, -2315, 1323, 73, +870, 2377, -1138, 606, -1196, -2243, 860, -1242, +1434, 1902, -543, 1770, -1523, -1435, 210, -2133, +1492, 834, 118, 2272, -1301, -218, -435, -2194, +1010, -367, 741, 1860, -651, 846, -933, -1400, +267, -1162, 1051, 796, 98, 1318, -1038, -190, +-418, -1279, 896, -364, 723, 1025, -682, 826, +-938, -619, 409, -1084, 1067, 53, -131, 1163, +-1069, 560, -142, -1041, 974, -1123, 420, 737, +-826, 1615, -644, -336, 615, -1890, 796, -180, +-366, 1986, -863, 764, 105, -1842, 813, -1302, +154, 1461, -748, 1833, -359, -930, 616, -2168, +521, 242, -444, 2374, -637, 447, 269, -2352, +647, -1091, -62, 2130, -667, 1667, -80, -1726, +595, -2077, 217, 1143, -522, 2330, -293, -484, +412, -2353, 288, -219, -223, 2161, -278, 843, +70, -1789, 211, -1355, 116, 1295, -216, 1696, +-238, -717, 210, -1873, 329, 100, -189, 1866, +-367, 493, 173, -1706, 330, -1003, -90, 1371, +-301, 1368, 51, -944, 272, -1564, -15, 443, +-233, 1591, 4, 46, 199, -1467, -33, -507, +-112, 1219, 42, 930, 53, -920, -60, -1198, +-3, 523, 85, 1378, -67, -153, -91, -1337, +95, -210, 159, 1153, -163, 532, -170, -896, +145, -679, 202, 498, -125, 832, -241, -165, +133, -806, 263, -221, -100, 710, -339, 576, +112, -553, 336, -779, -52, 226, -376, 1002, +39, 30, 353, -1016, -30, -341, -287, 959, +-24, 603, 232, -839, 72, -769, -136, 559, +-170, 962, 101, -280, 181, -1023, -48, -88, +-170, 995, -30, 484, 172, -935, 116, -782, +-174, 730, -203, 1072, 166, -527, 239, -1235, +-135, 263, -218, 1286, 69, 62, 227, -1318, +-37, -309, -192, 1163, -32, 615, 168, -1033, +129, -769, -146, 768, -187, 896, 106, -538, +275, -938, -114, 327, -270, 874, 69, -79, +315, -843, -56, -18, -326, 648, 45, 206, +294, -519, -22, -223, -273, 285, 57, 233, +190, -72, -20, -221, -147, -28, -3, 101, +62, 179, 41, -59, 16, -178, -69, -83, +-75, 216, 70, 199, 109, -205, -79, -263, +-139, 100, 50, 374, 167, -35, -19, -340, +-210, -107, -21, 319, 216, 211, 36, -278, +-181, -272, -88, 200, 147, 392, 127, -252, +-102, -380, -172, 215, 47, 406, 174, -233, +-2, -357, -126, 238, -54, 233, 73, -161, +93, -243, -2, 216, -130, 112, -84, -99, +201, -171, 127, 70, -208, 204, -180, -30, +170, -190, 192, -99, -77, 322, -176, 27, +-74, -228, 213, -145, 150, 297, -165, 139, +-257, -261, 117, -162, 315, 170, -7, 261, +-330, -172, -147, -195, 371, 20, 228, 232, +-297, 18, -378, -148, 248, -97, 463, 60, +-117, 196, -526, -9, -81, -221, 591, -96, +205, 266, -533, 143, -382, -219, 480, -179, +476, 111, -369, 216, -574, -12, 182, -172, +685, -141, -51, 148, -693, 231, -165, -83, +721, -301, 245, 3, -681, 345, -295, 66, +537, -314, 342, -203, -397, 289, -346, 281, +167, -204, 388, -336, -72, 107, -386, 338, +40, -15, 294, -275, -29, -114, -174, 203, +21, 219, -32, -116, 53, -307, 146, 15, +-108, 378, -169, 46, 65, -348, 167, -152, +-32, 301, -95, 202, -92, -185, 98, -245, +151, 83, -130, 259, -149, -12, 120, -179, +97, -90, -140, 106, 82, 139, 11, 73, +-177, -256, 83, -186, 231, 304, -176, 304, +-218, -332, 170, -347, 146, 319, -23, 310, +-169, -201, -157, -290, 165, 105, 351, 193, +-236, 74, -478, -154, 261, -199, 516, 115, +-291, 286, -535, -48, 235, -350, 483, 19, +-150, 310, -450, 60, 23, -270, 394, -125, +20, 203, -331, 171, -75, -116, 209, -259, +88, 83, -88, 265, -139, -21, -50, -269, +165, -35, 71, 219, -172, 97, -100, -130, +145, -210, 38, 111, -67, 252, -79, -84, +-20, -308, 101, 117, 50, 301, -132, -177, +-38, -219, 100, 171, -72, 156, 8, -207, +83, 0, -140, 175, -73, -103, 244, -159, +-60, 193, -253, 182, 131, -323, 165, -129, +-169, 389, -77, 136, 114, -513, -10, -60, +-31, 580, -15, 8, -55, -608, 37, 5, +88, 658, -135, -36, -60, -648, 169, 17, +-42, 673, -206, -31, 95, -670, 140, 66, +-116, 661, -124, -108, 69, -648, 73, 141, +-37, 625, -140, -145, 15, -624, 147, 118, +-62, 662, -201, -47, 63, -782, 196, -2, +-175, 923, -177, 34, 179, -1074, 150, -53, +-280, 1194, -133, 38, 280, -1242, 100, -72, +-341, 1259, -160, 78, 400, -1231, 145, -85, +-464, 1137, -214, 118, 483, -1082, 177, -79, +-499, 969, -215, 70, 461, -918, 232, -10, +-511, 905, -257, -142, 488, -869, 203, 316, +-542, 942, -123, -631, 528, -965, -64, 969, +-527, 1004, 178, -1298, 494, -1066, -347, 1650, +-499, 1063, 429, -1869, 487, -1138, -533, 2107, +-562, 1179, 569, -2261, 546, -1217, -567, 2340, +-614, 1268, 475, -2367, 611, -1253, -376, 2267, +-711, 1285, 167, -2130, 772, -1292, -53, 1954, +-852, 1307, -124, -1747, 833, -1353, 168, 1571, +-812, 1354, -246, -1369, 647, -1360, 270, 1143, +-543, 1354, -317, -921, 314, -1323, 292, 629, +-171, 1317, -286, -383, -51, -1279, 169, 109, +247, 1225, -193, 134, -471, -1118, 154, -405, +572, 988, -259, 655, -603, -828, 281, -940, +462, 686, -318, 1139, -388, -499, 246, -1306, +240, 301, -220, 1415, -200, -101, 105, -1430, +155, -174, -117, 1460, -207, 377, 36, -1361, +273, -636, -78, 1301, -455, 804, 87, -1149, +509, -963, -132, 1039, -704, 1074, 165, -934, +713, -1158, -195, 923, -799, 1177, 115, -939, +753, -1143, -109, 1001, -706, 1062, -107, -1036, +669, -943, 155, 994, -640, 908, -333, -985, +563, -866, 348, 884, -550, 983, -349, -898, +363, -1067, 257, 845, -292, 1254, -184, -853, +33, -1381, 62, 776, 136, 1518, -64, -671, +-368, -1617, -23, 487, 476, 1648, -24, -211, +-609, -1662, -19, -78, 568, 1506, 31, 483, +-655, -1362, -91, -822, 562, 1020, 131, 1250, +-642, -722, -196, -1564, 601, 301, 154, 1843, +-644, 113, -225, -2005, 587, -532, 136, 2027, +-528, 995, -267, -1972, 411, -1341, 294, 1702, +-370, 1737, -530, -1411, 300, -1965, 684, 932, +-365, 2213, -938, -480, 362, -2321, 1081, -36, +-485, 2361, -1273, 517, 479, -2295, 1319, -895, +-547, 2068, -1409, 1269, 459, -1835, 1336, -1475, +-422, 1463, -1314, 1728, 190, -1202, 1183, -1801, +-42, 892, -1086, 1852, -351, -699, 953, -1718, +551, 541, -877, 1474, -913, -393, 776, -1191, +1029, 330, -779, 792, -1148, -173, 581, -518, +1112, 126, -512, 164, -1029, 42, 163, 21, +899, -129, -19, -227, -780, 263, -256, 319, +542, -381, 317, -338, -340, 444, -444, 340, +-68, -519, 411, -250, 367, 498, -438, 208, +-798, -500, 307, -150, 1063, 454, -213, 124, +-1416, -418, -50, -101, 1563, 348, 276, 101, +-1793, -258, -627, -77, 1779, 124, 869, 77, +-1806, 19, -1237, -72, 1653, -118, 1410, 9, +-1497, 243, -1736, 20, 1247, -226, 1768, -189, +-990, 240, -1913, 374, 631, -200, 1805, -600, +-349, 116, -1761, 922, -76, -153, 1584, -1100, +294, 66, -1435, 1350, -627, -89, 1126, -1450, +779, 52, -909, 1493, -1042, 56, 541, -1547, +1191, -123, -371, 1408, -1403, 358, 137, -1312, +1386, -516, -80, 1039, -1425, 742, -88, -731, +1244, -912, 161, 347, -1180, 1036, -431, 83, +1057, -1115, 486, -535, -1018, 1120, -713, 1000, +920, -1074, 716, -1425, -904, 893, -837, 1867, +651, -701, 964, -2146, -654, 311, -1106, 2426, +378, 47, 1284, -2498, -412, -520, -1455, 2481, +241, 1014, 1438, -2342, -152, -1459, -1561, 2009, +-29, 1960, 1407, -1663, 192, -2276, -1445, 1138, +-444, 2551, 1309, -623, 511, -2605, -1259, 67, +-707, 2478, 1074, 528, 660, -2224, -966, -1057, +-693, 1796, 678, 1564, 611, -1354, -612, -1904, +-490, 815, 278, 2129, 300, -321, -173, -2095, +-163, -234, -110, 1948, -109, 696, 293, -1601, +95, -1151, -429, 1208, -332, 1464, 520, -796, +240, -1604, -516, 354, -428, 1635, 420, -20, +414, -1431, -456, -336, -502, 1178, 305, 579, +495, -821, -441, -755, -410, 409, 278, 846, +238, -25, -300, -798, -109, -369, 59, 692, +-106, 662, 59, -474, 71, -873, -248, 244, +-167, 935, 261, 32, 85, -935, -333, -246, +-169, 803, 204, 498, 185, -682, -277, -651, +-324, 508, 201, 753, 312, -293, -264, -806, +-474, 148, 225, 700, 368, 138, -194, -672, +-517, -285, 102, 505, 438, 538, -102, -434, +-507, -695, -55, 347, 418, 825, 9, -257, +-313, -909, -270, 193, 164, 893, 294, -92, +-34, -841, -581, -31, -113, 790, 615, 122, +148, -706, -751, -273, -291, 683, 675, 376, +281, -663, -651, -473, -436, 584, 487, 639, +378, -562, -366, -722, -482, 369, 104, 953, +380, -253, 97, -1130, -444, 38, -418, 1375, +345, 149, 591, -1602, -413, -283, -841, 1719, +292, 484, 919, -1811, -319, -627, -1065, 1743, +141, 871, 1041, -1643, -92, -1075, -1128, 1448, +-136, 1297, 1034, -1187, 269, -1467, -1139, 903, +-497, 1536, 1085, -508, 565, -1609, -1185, 126, +-688, 1547, 1131, 398, 585, -1562, -1108, -862, +-626, 1473, 915, 1376, 469, -1366, -731, -1849, +-539, 1234, 425, 2196, 469, -955, -233, -2569, +-583, 753, -43, 2704, 523, -385, 183, -2854, +-609, 118, -419, 2791, 507, 225, 512, -2677, +-509, -525, -698, 2447, 347, 770, 678, -2139, +-207, -990, -828, 1829, -45, 1102, 764, -1467, +244, -1216, -876, 1148, -492, 1237, 753, -777, +594, -1284, -727, 500, -766, 1227, 456, -183, +795, -1215, -265, -9, -924, 1117, -96, 189, +914, -1041, 269, -296, -951, 986, -548, 328, +760, -892, 665, -386, -612, 899, -890, 343, +220, -825, 1045, -365, -11, 801, -1231, 365, +-379, -746, 1313, -392, 521, 645, -1346, 495, +-820, -589, 1190, -555, 931, 459, -1063, 720, +-1149, -408, 742, -814, 1229, 277, -570, 971, +-1343, -196, 237, -1033, 1264, 49, -76, 1094, +-1190, 92, -227, -1078, 926, -240, 361, 953, +-694, 447, -626, -854, 378, -556, 648, 594, +-108, 751, -807, -446, -183, -770, 688, 209, +387, 763, -674, -25, -655, -655, 491, -109, +729, 398, -358, 300, -902, -210, 155, -342, +800, -96, 28, 413, -792, 296, -294, -364, +589, -504, 458, 234, -478, 716, -717, -69, +250, -844, 775, -218, -91, 1013, -918, 471, +-171, -1050, 846, -796, 363, 1068, -849, 1058, +-643, -954, 659, -1336, 821, 804, -537, 1506, +-1067, -546, 258, -1634, 1184, 253, -84, 1668, +-1367, 80, -190, -1586, 1371, -461, 333, 1483, +-1422, 749, -547, -1203, 1261, -1077, 636, 958, +-1168, 1236, -781, -560, 885, -1390, 839, 175, +-755, 1439, -893, 212, 455, -1396, 850, -603, +-334, 1335, -789, 845, 62, -1114, 614, -1096, +93, 903, -541, 1174, -310, -537, 320, -1257, +449, 205, -335, 1220, -509, 172, 158, -1155, +502, -519, -181, 1019, -439, 793, 18, -777, +304, -1086, 13, 568, -262, 1233, -106, -228, +98, -1417, 105, -29, -119, 1467, -63, 341, +-44, -1495, -22, -640, 62, 1491, 91, 850, +-234, -1388, -168, -1101, 272, 1357, 115, 1203, +-362, -1214, -122, -1328, 321, 1123, 12, 1366, +-323, -970, -25, -1384, 248, 797, -76, 1418, +-234, -659, 57, -1398, 189, 492, -202, 1437, +-163, -432, 193, -1402, 140, 340, -377, 1418, +-87, -324, 351, -1335, -5, 240, -449, 1293, +72, -198, 406, -1145, -255, 99, -349, 963, +240, -28, 329, -742, -412, 36, -265, 421, +309, -28, 289, -216, -370, 226, -343, -84, +270, -341, 327, 161, -203, 621, -428, -247, +85, -819, 351, 168, 74, 1014, -410, -13, +-247, -1214, 343, -159, 368, 1290, -361, 443, +-526, -1400, 296, -672, 536, 1411, -245, 968, +-598, -1421, 84, -1244, 558, 1357, 58, 1544, +-598, -1217, -266, -1838, 544, 959, 412, 2139, +-590, -615, -514, -2345, 429, 153, 590, 2495, +-360, 314, -610, -2483, 108, -796, 606, 2345, +20, 1232, -600, -2090, -179, -1548, 440, 1663, +316, 1849, -382, -1238, -394, -1972, 117, 674, +519, 2121, -70, -182, -554, -2115, -106, -355, +573, 2069, 93, 831, -533, -1953, -140, -1208, +390, 1692, 100, 1592, -280, -1468, -69, -1778, +58, 1036, 30, 2019, 33, -696, 27, -2067, +-241, 235, -37, 2079, 261, 181, 95, -1978, +-412, -555, -101, 1708, 377, 928, 178, -1432, +-453, -1147, -271, 1003, 412, 1357, 373, -638, +-434, -1427, -548, 278, 446, 1427, 567, 8, +-383, -1380, -686, -193, 371, 1231, 581, 341, +-232, -1078, -625, -417, 121, 887, 552, 501, +-17, -677, -572, -563, -123, 437, 571, 663, +162, -235, -495, -711, -337, -31, 433, 811, +380, 187, -268, -790, -537, -375, 95, 800, +556, 485, 113, -790, -620, -539, -315, 712, +598, 699, 450, -765, -625, -732, -574, 654, +629, 963, 542, -656, -600, -1044, -591, 474, +568, 1188, 492, -285, -412, -1207, -586, 8, +309, 1127, 551, 306, -108, -1002, -673, -538, +-31, 741, 691, 750, 123, -505, -683, -807, +-282, 201, 673, 820, 326, 17, -574, -712, +-514, -260, 576, 590, 512, 440, -488, -429, +-587, -616, 430, 265, 508, 751, -297, -81, +-479, -864, 118, -102, 395, 927, 34, 313, +-368, -931, -171, -485, 280, 832, 244, 663, +-202, -666, -309, -803, 77, 440, 335, 896, +59, -185, -428, -948, -147, -56, 420, 943, +261, 271, -465, -906, -288, -458, 346, 861, +370, 562, -238, -760, -457, -652, 58, 702, +504, 666, 114, -616, -579, -651, -223, 544, +484, 670, 294, -510, -382, -616, -322, 379, +188, 703, 308, -326, -5, -732, -325, 142, +-94, 844, 254, 19, 172, -912, -247, -209, +-191, 932, 184, 417, 185, -931, -160, -534, +-197, 830, 129, 617, 160, -710, -79, -627, +-139, 539, 20, 589, 49, -335, 43, -561, +42, 129, -118, 526, -124, 78, 112, -511, +203, -292, -118, 516, -181, 450, 8, -479, +147, -618, 97, 424, -70, 715, -235, -314, +8, -793, 361, 195, -15, 798, -434, -65, +-41, -749, 550, -13, 5, 649, -614, 93, +-89, -548, 745, -142, 143, 449, -832, 197, +-272, -377, 889, -271, 424, 340, -921, 328, +-552, -282, 868, -421, 695, 254, -847, 448, +-743, -147, 716, -486, 802, 63, -605, 440, +-796, 69, 401, -413, 837, -151, -242, 322, +-822, 241, 25, -233, 846, -330, 96, 154, +-788, 380, -230, -24, 698, -492, 307, -23, +-564, 473, -373, 192, 366, -538, 484, -256, +-255, 456, -514, 412, 42, -411, 627, -510, +54, 320, -608, 547, -242, -171, 587, -588, +380, 98, -543, 480, -493, 95, 408, -399, +593, -208, -328, 224, -558, 360, 115, -59, +578, -489, 13, -76, -539, 532, -166, 246, +562, -587, 233, -352, -586, 557, -265, 457, +613, -501, 281, -546, -623, 425, -319, 572, +596, -262, 404, -617, -601, 131, -463, 592, +534, 39, 572, -569, -527, -187, -556, 512, +387, 311, 592, -407, -326, -414, -552, 290, +183, 475, 557, -115, -87, -506, -611, -85, +67, 495, 635, 263, -21, -436, -715, -429, +23, 366, 692, 527, 60, -249, -676, -606, +-161, 143, 610, 616, 305, -59, -536, -594, +-424, -42, 450, 583, 487, 83, -363, -515, +-516, -188, 273, 537, 489, 218, -186, -502, +-473, -316, 134, 548, 385, 360, -38, -575, +-350, -417, -20, 605, 248, 497, 117, -669, +-191, -538, -190, 660, 122, 679, 197, -692, +-19, -789, -225, 624, -5, 964, 130, -543, +113, -1111, -125, 374, -140, 1263, 65, -158, +203, -1381, -46, -123, -274, 1478, 63, 403, +296, -1485, -62, -696, -354, 1438, 101, 949, +342, -1318, -90, -1152, -355, 1124, 75, 1341, +343, -948, -28, -1429, -358, 686, -13, 1532, +351, -483, 111, -1528, -424, 215, -130, 1483, +408, 53, 219, -1383, -447, -330, -230, 1201, +389, 634, 272, -1025, -322, -857, -349, 785, +281, 1043, 360, -558, -168, -1145, -444, 322, +136, 1165, 402, -111, -11, -1124, -404, -47, +-100, 1015, 379, 144, 194, -895, -319, -179, +-290, 762, 272, 185, 257, -664, -136, -167, +-222, 558, 21, 183, 121, -515, 121, -210, +-21, 447, -241, 258, -48, -381, 281, -322, +162, 284, -348, 368, -227, -138, 351, -448, +353, -4, -412, 487, -435, 151, 457, -541, +528, -259, -510, 541, -600, 352, 567, -552, +630, -407, -564, 490, -665, 471, 565, -446, +668, -503, -503, 330, -695, 544, 447, -229, +694, -558, -319, 83, -730, 517, 215, 85, +745, -487, -47, -244, -816, 374, -64, 429, +850, -299, 194, -562, -884, 162, -287, 680, +866, -59, 375, -758, -739, -81, -511, 803, +632, 163, 581, -809, -399, -274, -696, 809, +236, 322, 687, -763, 10, -422, -661, 709, +-186, 488, 575, -639, 324, -573, -418, 503, +-418, 673, 312, -424, 413, -727, -136, 253, +-397, 797, 3, -128, 350, -794, 144, -59, +-297, 757, -296, 224, 294, -679, 414, -392, +-232, 543, -540, 498, 224, -407, 611, -581, +-116, 246, -652, 579, 17, -99, 667, -569, +105, -39, -606, 508, -207, 153, 527, -443, +278, -316, -355, 379, -321, 431, 226, -289, +295, -605, -46, 200, -238, 699, -18, -91, +130, -821, 121, -50, -15, 853, -119, 170, +-95, -840, 153, -333, 183, 766, -149, 435, +-193, -655, 134, -553, 243, 528, -119, 572, +-214, -383, 57, -613, 297, 236, 4, 561, +-290, -106, -100, -536, 384, -54, 185, 477, +-379, 157, -240, -399, 395, -338, 315, 309, +-328, 424, -310, -158, 255, -584, 351, -8, +-159, 641, -298, 221, 73, -717, 293, -470, +29, 713, -183, 675, -115, -664, 143, -939, +226, 563, -37, 1089, -256, -377, -31, -1278, +309, 153, 144, 1315, -216, 126, -265, -1340, +185, -429, 401, 1231, -47, 719, -493, -1115, +3, -1001, 614, 906, 81, 1173, -593, -698, +-130, -1324, 659, 450, 158, 1334, -548, -189, +-196, -1338, 559, -94, 239, 1191, -431, 370, +-232, -1062, 386, -653, 302, 804, -274, 864, +-236, -553, 181, -1072, 301, 216, -71, 1167, +-215, 118, -5, -1269, 245, -469, 124, 1227, +-140, 761, -181, -1182, 124, -1014, 308, 1015, +-16, 1167, -345, -871, 27, -1286, 457, 642, +44, 1291, -463, -456, 14, -1291, 557, 211, +3, 1198, -522, -13, 57, -1127, 618, -216, +-39, 963, -543, 392, 28, -859, 639, -557, +72, 670, -561, 649, -135, -572, 617, -713, +310, 397, -510, 694, -356, -308, 460, -691, +552, 180, -297, 609, -565, -111, 199, -601, +719, 30, -13, 505, -665, 7, -60, -484, +676, -61, 276, 377, -522, 75, -349, -327, +441, -142, 590, 192, -217, 138, -633, -115, +123, -213, 767, -16, 144, 196, -691, 82, +-247, -239, 642, -178, 555, 180, -434, 209, +-649, -184, 300, -261, 872, 103, -53, 259, +-842, -76, -51, -288, 864, -24, 290, 276, +-670, 63, -338, -317, 581, -170, 534, 288, +-346, 230, -530, -299, 294, -343, 633, 200, +-64, 401, -540, -155, 41, -507, 577, -31, +202, 531, -409, 152, -277, -564, 430, -396, +477, 524, -196, 537, -532, -454, 223, -775, +634, 306, 6, 880, -537, -168, 13, -1008, +541, -54, 157, 1006, -301, 200, -118, -1000, +296, -448, 224, 900, -56, 569, -151, -800, +102, -782, 253, 644, 39, 849, -159, -502, +76, -1002, 272, 341, -6, 994, -144, -219, +126, -1054, 222, 98, -17, 981, -93, -40, +101, -955, 177, -61, 59, 854, -80, 47, +40, -788, 230, -157, 71, 711, -157, 117, +90, -674, 322, -213, -43, 638, -219, 171, +220, -659, 359, -236, -139, 621, -258, 225, +264, -639, 385, -293, -95, 536, -299, 323, +193, -509, 419, -409, -10, 341, -299, 451, +102, -265, 423, -539, 54, 60, -278, 559, +46, 39, 434, -612, 59, -254, -279, 576, +57, 386, 434, -583, 41, -588, -260, 447, +59, 729, 393, -371, 111, -884, -244, 106, +-31, 963, 393, 72, 243, -1018, -293, -391, +-137, 947, 424, 603, 352, -863, -306, -861, +-239, 633, 387, 1001, 487, -477, -220, -1120, +-381, 174, 297, 1125, 595, -20, -99, -1114, +-448, -247, 180, 1022, 554, 357, 69, -967, +-337, -567, -1, 838, 374, 658, 293, -805, +-140, -819, -215, 655, 183, 882, 470, -618, +31, -954, -340, 431, 29, 942, 535, -382, +190, -935, -360, 205, -95, 841, 469, -159, +301, -812, -216, 40, -174, 702, 233, -25, +381, -719, 78, -62, -227, 646, -83, 73, +412, -703, 371, -185, -205, 639, -326, 254, +329, -669, 553, -418, -75, 541, -432, 527, +156, -477, 604, -692, 92, 262, -399, 749, +-10, -127, 536, -852, 241, -105, -279, 788, +-170, 254, 410, -797, 408, -441, -174, 627, +-295, 540, 295, -555, 497, -676, -63, 351, +-288, 700, 117, -234, 453, -792, 148, 40, +-220, 728, -95, 86, 388, -745, 325, -254, +-178, 575, -165, 334, 315, -479, 343, -441, +-103, 228, -143, 415, 224, -57, 348, -424, +-30, -205, -186, 274, 193, 360, 386, -185, +-26, -531, -211, -42, 199, 574, 376, 155, +-5, -621, -153, -370, 132, 548, 322, 408, +80, -500, -110, -528, 45, 368, 278, 513, +157, -304, -82, -591, 15, 140, 236, 583, +211, -94, -57, -652, -37, -84, 194, 649, +277, 138, 11, -689, -112, -309, 89, 623, +303, 359, 213, -581, -132, -493, -148, 404, +273, 514, 481, -298, -64, -594, -353, 67, +155, 563, 572, 41, 163, -604, -374, -245, +-123, 540, 502, 329, 496, -563, -307, -499, +-415, 477, 432, 578, 703, -478, -226, -739, +-533, 346, 334, 820, 711, -297, -38, -971, +-509, 114, 113, 983, 639, 1, 210, -1052, +-407, -201, -119, 929, 507, 321, 395, -902, +-210, -472, -278, 710, 260, 527, 489, -638, +67, -618, -299, 474, -28, 582, 445, -421, +328, -644, -165, 311, -284, 583, 262, -276, +538, -650, 39, 165, -404, 604, 24, -111, +590, -685, 251, -19, -345, 647, -209, 74, +491, -720, 474, -197, -231, 659, -399, 226, +358, -672, 616, -319, -121, 555, -427, 319, +197, -495, 607, -440, 50, 331, -339, 444, +-19, -196, 485, -596, 282, -23, -223, 604, +-202, 212, 318, -694, 430, -489, -61, 635, +-256, 676, 109, -601, 443, -945, 156, 432, +-220, 1055, -103, -277, 354, -1216, 336, 12, +-84, 1196, -211, 198, 135, -1209, 396, -495, +183, 1071, -236, 687, -158, -977, 408, -947, +442, 780, -224, 1061, -370, -639, 356, -1227, +586, 428, -114, 1233, -469, -287, 192, -1294, +661, 75, 95, 1213, -547, 59, -52, -1182, +752, -278, 344, 1029, -617, 388, -310, -924, +796, -574, 558, 738, -584, 622, -511, -618, +700, -731, 726, 433, -422, 685, -658, -323, +478, -684, 857, 149, -190, 550, -721, -74, +196, -475, 896, -70, 71, 319, -680, 96, +-95, -244, 809, -188, 357, 116, -541, 156, +-375, -65, 610, -198, 633, -49, -328, 127, +-572, 94, 324, -130, 778, -224, -38, 48, +-593, 256, -9, -17, 719, -395, 282, -79, +-453, 399, -280, 128, 504, -497, 485, -238, +-189, 450, -396, 291, 182, -465, 552, -417, +104, 375, -395, 451, -89, -322, 522, -571, +294, 197, -299, 565, -239, -102, 386, -648, +396, -43, -117, 581, -316, 152, 171, -599, +457, -292, 65, 491, -330, 374, 7, -468, +447, -489, 151, 358, -249, 497, -43, -315, +330, -581, 155, 235, -101, 521, -26, -201, +169, -587, 140, 153, 20, 535, -29, -124, +64, -605, 180, 40, 77, 596, -97, 14, +37, -660, 267, -191, 105, 653, -174, 285, +-23, -656, 311, -502, 213, 589, -191, 607, +-201, -504, 309, -793, 415, 354, -166, 854, +-388, -216, 267, -964, 547, 14, -86, 945, +-432, 125, 122, -940, 558, -336, 82, 825, +-410, 439, -69, -695, 540, -618, 241, 490, +-387, 667, -186, -292, 473, -772, 350, 45, +-302, 735, -274, 149, 330, -717, 444, -386, +-149, 572, -337, 524, 155, -437, 447, -710, +43, 216, -294, 785, -46, -32, 316, -896, +256, -195, -129, 897, -249, 354, 134, -920, +413, -551, 70, 815, -353, 660, -53, -725, +425, -798, 265, 513, -307, 846, -247, -319, +332, -919, 407, 68, -147, 890, -354, 139, +150, -893, 439, -366, 95, 796, -349, 529, +-101, -719, 404, -728, 348, 552, -281, 840, +-333, -400, 332, -981, 498, 181, -155, 1000, +-440, 18, 182, -1021, 521, -254, 27, 923, +-403, 432, -13, -829, 425, -641, 206, 639, +-222, 751, -204, -477, 191, -880, 352, 253, +45, 889, -301, -80, -81, -910, 348, -134, +276, 828, -189, 283, -302, -756, 139, -452, +453, 612, 75, 533, -435, -497, -139, -616, +530, 329, 319, 608, -434, -205, -350, -603, +451, 59, 516, 520, -294, 24, -519, -467, +290, -123, 672, 366, -138, 155, -582, -328, +123, -224, 667, 260, 37, 240, -513, -227, +-54, -300, 550, 164, 200, 289, -380, -103, +-144, -317, 377, -1, 241, 272, -226, 98, +-113, -264, 205, -220, 188, 196, -91, 299, +-55, -164, 117, -425, 112, 97, -65, 488, +-14, -26, 150, -609, 39, -68, -100, 645, +26, 164, 166, -710, 17, -280, -82, 690, +-31, 376, 129, -675, 141, -501, -58, 610, +-170, 571, 118, -558, 284, -689, -54, 471, +-274, 750, 90, -369, 361, -841, 15, 207, +-298, 853, -19, -19, 378, -865, 153, -215, +-289, 788, -157, 424, 358, -686, 274, -628, +-219, 499, -238, 743, 242, -295, 324, -833, +-82, 53, -216, 805, 80, 162, 240, -769, +46, -350, -89, 665, -45, 487, 88, -575, +130, -612, 47, 454, -108, 692, -39, -339, +166, -785, 97, 184, -104, 800, -56, -5, +119, -803, 63, -215, -30, 686, -35, 421, +46, -516, 51, -615, -16, 262, -6, 703, +78, 20, -7, -735, -76, -307, 116, 643, +114, 565, -122, -533, -73, -775, 228, 356, +102, 908, -173, -198, -62, -990, 243, 21, +137, 986, -158, 138, -104, -955, 215, -293, +203, 842, -118, 420, -130, -727, 117, -502, +222, 545, 4, 549, -141, -381, -22, -542, +211, 183, 109, 489, -120, -8, -78, -424, +128, -158, 136, 296, -45, 287, -94, -181, +19, -362, 137, 6, 16, 397, -81, 121, +-39, -376, 99, -279, 62, 310, -48, 373, +-92, -212, 40, -462, 130, 86, 4, 506, +-141, 21, -33, -518, 187, -153, 97, 500, +-134, 215, -152, -424, 149, -298, 232, 342, +-20, 297, -244, -216, 9, -334, 294, 89, +148, 318, -223, 44, -165, -288, 229, -180, +279, 225, -69, 253, -257, -81, 57, -354, +300, -47, 112, 336, -233, 214, -94, -330, +212, -301, 191, 234, -124, 339, -137, -141, +80, -305, 155, 43, 3, 190, -109, 52, +-50, -86, 100, -85, 125, -75, -131, 112, +-137, 179, 142, -59, 134, -311, -198, -5, +-81, 392, 165, 124, 45, -485, -135, -263, +-28, 537, 75, 405, 35, -545, -21, -550, +-62, 513, 28, 641, 92, -393, -8, -731, +-77, 254, 76, 734, 91, -62, -40, -729, +-34, -88, 83, 637, 92, 219, 5, -528, +-74, -308, 26, 385, 184, 340, 44, -223, +-164, -387, 7, 89, 211, 372, 26, 83, +-114, -387, -6, -213, 84, 312, 72, 351, +-2, -208, -136, -452, -12, 55, 186, 493, +14, 170, -226, -512, -44, -368, 210, 423, +89, 570, -217, -336, -197, -704, 194, 175, +230, 773, -180, 8, -290, -794, 77, -194, +256, 735, 69, 399, -263, -662, -267, -563, +256, 521, 423, 713, -240, -360, -511, -804, +220, 162, 534, 845, -80, 32, -467, -833, +-52, -215, 460, 765, 271, 370, -395, -659, +-361, -485, 430, 488, 455, 585, -344, -308, +-404, -627, 292, 63, 401, 675, -130, 141, +-362, -628, 13, -372, 375, 565, 120, 536, +-384, -427, -208, -647, 343, 233, 273, 715, +-295, -58, -376, -660, 151, -173, 448, 597, +-68, 285, -603, -410, -65, -398, 631, 250, +105, 395, -692, -78, -219, -351, 594, -62, +283, 296, -533, 120, -426, -198, 415, -205, +514, 158, -336, 209, -624, -60, 270, -252, +671, -13, -191, 231, -671, 128, 154, -206, +654, -240, -45, 135, -571, 310, -17, -27, +534, -340, 122, -70, -425, 293, -177, 184, +366, -230, 247, -235, -225, 126, -297, 288, +129, -75, 328, -273, 0, 0, -362, 272, +-111, 27, 347, -243, 157, -75, -356, 209, +-224, 123, 271, -180, 163, -134, -231, 92, +-220, 173, 90, -15, 147, -130, -32, -146, +-240, 103, -96, 275, 224, -28, 108, -400, +-327, -68, -176, 480, 325, 148, 129, -462, +-330, -273, -162, 426, 256, 343, 139, -306, +-156, -405, -191, 195, 61, 426, 223, -91, +60, -419, -236, -34, -123, 417, 234, 133, +215, -390, -178, -249, -264, 366, 135, 339, +322, -300, -52, -415, -386, 206, 12, 461, +408, -77, 27, -487, -474, -29, -46, 482, +433, 106, 33, -453, -453, -152, -80, 414, +336, 151, 50, -320, -296, -175, -175, 236, +161, 164, 148, -109, -128, -201, -278, 20, +24, 206, 196, 75, -35, -207, -251, -143, +-47, 231, 148, 146, 37, -233, -148, -159, +-126, 306, 79, 107, 119, -318, -71, -99, +-185, 350, 75, 70, 179, -328, -79, -69, +-210, 275, 104, 109, 203, -242, -92, -127, +-210, 177, 108, 190, 203, -164, -116, -208, +-162, 101, 77, 277, 108, -40, -46, -324, +-49, -61, -78, 391, 6, 150, 86, -420, +-34, -199, -170, 406, 4, 233, 96, -344, +-51, -228, -121, 214, -62, 226, 48, -117, +29, -170, -112, 24, -181, 149, 90, -37, +137, -94, -162, 59, -241, 73, 68, -111, +161, -72, -41, 129, -185, 135, -122, -77, +79, -260, 160, -4, -46, 346, -261, 178, +-68, -384, 225, -312, 179, 317, -233, 460, +-308, -225, 173, -575, 403, 88, -148, 668, +-431, 91, 69, -718, 349, -275, 50, 672, +-278, 512, -214, -567, 135, -739, 323, 397, +-99, 970, -367, -152, -56, -1124, 253, -146, +154, 1141, -200, 475, -376, -1029, 41, -771, +458, 818, -87, 1043, -580, -534, -64, -1227, +488, 208, 77, 1269, -487, 181, -336, -1169, +357, -557, 400, 965, -386, 876, -567, -652, +226, -1125, 532, 270, -131, 1230, -587, 179, +-164, -1133, 524, -639, 311, 882, -514, 1027, +-536, -475, 377, -1312, 582, 48, -210, 1405, +-675, 422, -33, -1286, 668, -884, 150, 1002, +-616, 1208, -273, -550, 433, -1386, 254, 123, +-253, 1362, -334, 335, 56, -1193, 279, -711, +-8, 896, -321, 1011, -50, -487, 183, -1154, +-47, 87, -172, 1108, -13, 331, 50, -918, +-57, -683, -130, 577, -88, 982, 126, -125, +5, -1113, -270, -346, -136, 1033, 235, 742, +55, -738, -320, -974, -211, 343, 198, 1048, +248, 99, -262, -974, -439, -492, 178, 730, +452, 808, -254, -335, -548, -975, 140, -73, +469, 983, -102, 504, -493, -875, -105, -830, +419, 671, 167, 1063, -449, -358, -294, -1088, +348, 20, 245, 925, -257, 272, -271, -651, +-2, -421, 201, 346, 94, 478, -243, -46, +-272, -375, 126, -248, 217, 217, -83, 441, +-309, 29, -123, -531, 203, -221, 89, 514, +-279, 368, -146, -370, 102, -480, -31, 198, +-110, 503, -37, 44, -84, -413, -55, -199, +8, 222, -141, 249, -22, 35, 75, -195, +-157, -245, -181, 92, 82, 394, 45, 72, +-116, -449, -74, -251, -69, 370, -36, 485, +-6, -177, 1, -620, -54, -114, -120, 622, +-64, 494, 117, -485, -3, -800, -272, 195, +-78, 1007, 189, 195, 44, -951, -224, -587, +-179, 697, 71, 887, 113, -290, -133, -1002, +-207, -163, 30, 994, 134, 591, -170, -783, +-273, -946, 89, 438, 199, 1168, -223, 32, +-372, -1173, 82, -501, 299, 1013, -114, 906, +-482, -625, -153, -1175, 350, 99, 168, 1268, +-426, 500, -368, -1028, 162, -1023, 252, 592, +-90, 1326, -380, -8, -224, -1357, 253, -568, +235, 1219, -354, 1097, -353, -836, 125, -1528, +151, 323, -43, 1778, -153, 298, -299, -1717, +-11, -894, 313, 1420, -44, 1397, -398, -876, +-185, -1734, 153, 217, 254, 1859, -129, 502, +-549, -1612, -85, -1170, 504, 1146, 60, 1626, +-578, -469, -328, -1840, 314, -234, 405, 1810, +-299, 915, -729, -1466, 31, -1485, 686, 913, +-32, 1777, -774, -148, -337, -1771, 487, -533, +487, 1484, -485, 1083, -908, -1013, 171, -1400, +922, 516, -149, 1551, -1097, 8, -244, -1533, +863, -412, 369, 1404, -864, 822, -768, -1223, +491, -1158, 834, 1005, -377, 1478, -1080, -608, +-92, -1712, 933, 97, 308, 1767, -937, 551, +-791, -1575, 567, -1173, 909, 1222, -408, 1596, +-1194, -611, -38, -1770, 1008, -44, 206, 1649, +-965, 671, -614, -1235, 574, -1076, 574, 687, +-458, 1138, -716, -54, 139, -876, 417, -335, +-226, 392, -471, 422, 130, 66, 282, -125, +-375, -264, -529, -274, 207, 98, 547, 505, +-274, 347, -848, -325, -140, -676, 709, -230, +210, 702, -709, 838, -613, -286, 365, -1046, +506, -374, -360, 805, -658, 907, 82, -234, +468, -1029, -206, -259, -600, 887, -83, 469, +498, -658, -1, -560, -614, 665, -262, 697, +322, -657, 146, -1073, -329, 520, -266, 1456, +44, -11, -6, -1529, -214, -645, -40, 1270, +83, 1029, -210, -721, -214, -1076, 32, 462, +-52, 888, -189, -393, -60, -973, 11, 402, +-109, 1351, -152, -66, -168, -1585, -7, -628, +28, 1513, -262, 1229, -231, -1029, 125, -1604, +191, 556, -161, 1871, -527, -71, -507, -2057, +363, -634, 756, 2055, -211, 1499, -1016, -1427, +-515, -2152, 529, 431, 713, 2333, -308, 413, +-1000, -1964, -157, -999, 729, 1586, 215, 1427, +-794, -1123, -679, -1775, 386, 456, 756, 1970, +-287, 246, -997, -1628, -157, -700, 715, 1147, +72, 843, -850, -848, -286, -965, 733, 725, +258, 1381, -1031, -336, -705, -1746, 790, -438, +830, 1650, -749, 1273, -1248, -991, 141, -1718, +1129, 209, 272, 1771, -1193, 527, -1011, -1525, +554, -1226, 1036, 1056, -80, 1800, -1100, -82, +-568, -1959, 520, -951, 519, 1418, -364, 1554, +-654, -400, -52, -1509, 407, -315, 149, 1044, +-654, 639, -589, -647, 293, -751, 645, 383, +-108, 1008, -884, 61, -553, -1149, 468, -772, +818, 904, -314, 1384, -1191, -130, -379, -1464, +911, -625, 655, 1058, -760, 951, -1053, -495, +75, -876, 859, 307, 90, 665, -901, -288, +-443, -668, 591, 302, 354, 881, -666, -170, +-656, -1015, 290, -163, 539, 1104, -151, 583, +-734, -933, -338, -1030, 517, 488, 376, 1419, +-720, 178, -745, -1362, 545, -858, 751, 904, +-459, 1229, -1232, -221, -193, -1119, 1223, -325, +556, 826, -1321, 531, -1146, -428, 809, -524, +1135, 111, -514, 445, -1394, 77, -64, -231, +1248, -3, 191, 95, -1426, -276, -780, -266, +1132, 553, 1068, 837, -954, -321, -1573, -1328, +131, -522, 1403, 1322, 298, 1449, -1214, -558, +-846, -1804, 625, -492, 734, 1420, -547, 1257, +-856, -568, 239, -1431, 717, -233, -285, 1165, +-956, 762, -191, -547, 791, -996, 443, -89, +-750, 865, -1028, 619, 109, -395, 1041, -808, +366, -131, -906, 654, -1069, 605, -50, -330, +1020, -880, 597, -17, -600, 1067, -960, 511, +-411, -1036, 352, -1199, 675, 633, 254, 1735, +-623, 353, -807, -1631, -234, -1405, 490, 707, +547, 1844, -102, 666, -697, -1266, -544, -1534, +231, -2, 413, 1457, -89, 1077, -419, -562, +20, -1360, 145, -313, -365, 992, -488, 684, +70, -501, 593, -739, 218, 399, -533, 882, +-774, -292, -222, -1208, 351, -156, 526, 1282, +307, 878, -441, -677, -1048, -1258, -488, -136, +696, 913, 931, 586, -29, -177, -1137, -376, +-748, -212, 643, -118, 820, 214, -405, 386, +-1024, 64, -67, -453, 960, -358, 439, 485, +-1050, 749, -1092, -197, 417, -1112, 1184, -485, +101, 1004, -1152, 1266, -617, -171, 696, -1435, +630, -765, -785, 754, -928, 1157, 560, 205, +1203, -732, -341, -668, -1665, -24, -414, 555, +1355, 571, 957, -10, -1063, -847, -1399, -606, +313, 824, 1367, 1249, 113, -281, -1340, -1637, +-782, -674, 737, 1436, 981, 1528, -191, -516, +-902, -1809, -514, -421, 313, 1449, 420, 1019, +-45, -939, -325, -1298, -21, 651, 196, 1523, +-200, -169, -606, -1776, -269, -580, 716, 1609, +793, 1370, -393, -786, -1289, -1610, -622, -112, +898, 1109, 1209, 526, -253, -399, -1399, -294, +-547, 265, 919, -145, 750, -615, -594, 171, +-996, 1014, 183, 272, 1010, -1008, 114, -626, +-1252, 569, -871, 741, 901, -150, 1410, -600, +-151, 31, -1775, 477, -1073, 28, 977, -522, +1772, -166, 237, 580, -1708, 564, -1531, -400, +423, -1030, 1726, -90, 823, 1200, -939, 930, +-1624, -697, -516, -1620, 1101, -491, 1366, 1480, +14, 1909, -1415, -212, -1277, -2485, 389, -1688, +1701, 1641, 697, 3099, -1283, 336, -1634, -3094, +39, -2362, 1661, 1737, 1059, 3499, -1083, 296, +-1824, -3357, -28, -2122, 1639, 2098, 849, 3247, +-1047, -191, -1421, -3188, 194, -1694, 1262, 1918, +365, 2820, -1047, 14, -799, -2513, 544, -1812, +865, 1223, -220, 2555, -985, 416, -254, -2155, +687, -1586, 539, 1182, -454, 1878, -699, -16, +-18, -1605, 452, -690, 59, 943, -307, 898, +65, -256, 232, -737, -324, -13, -628, 451, +52, -27, 875, -422, 444, 78, -869, 730, +-1059, 220, 315, -779, 1128, -881, 175, 275, +-952, 1275, -564, 680, 601, -770, 596, -1393, +-513, -316, -671, 1109, 369, 1250, 615, -67, +-227, -1190, -736, -820, -123, 248, 700, 884, +382, 623, -694, -57, -800, -653, 377, -781, +898, -175, 35, 893, -813, 1236, -589, -77, +280, -1722, 619, -1175, 179, 1217, -317, 2212, +-451, 42, -404, -2324, 157, -1360, 712, 1440, +421, 2011, -646, -147, -1139, -1604, -130, -745, +1231, 702, 1152, 753, -750, 59, -1863, -257, +-604, -246, 1643, -147, 1792, 108, -540, 301, +-2301, 8, -1040, -336, 1631, -94, 2036, 479, +-260, 325, -2225, -513, -1187, -709, 1339, 197, +2028, 990, 0, 485, -2099, -763, -1367, -1261, +1148, -35, 2136, 1527, 142, 1275, -2048, -887, +-1465, -2224, 1086, -591, 2099, 2114, 54, 2178, +-2060, -729, -1207, -2707, 1332, -1174, 1841, 1713, +-296, 2321, -1984, 81, -924, -1964, 1341, -1440, +1543, 709, -312, 1652, -1504, 431, -602, -1167, +699, -838, 789, 694, -26, 892, -490, -483, +-276, -1044, 20, 181, 128, 1345, 18, 495, +-39, -1299, 58, -1283, 137, 641, -208, 1643, +-321, 303, 3, -1237, 367, -932, 269, 426, +-248, 846, -568, 169, -165, -269, 536, -56, +489, -128, -118, -432, -627, -252, -503, 696, +237, 987, 635, -36, 424, -1374, -296, -979, +-797, 734, -554, 1504, 538, 404, 1031, -967, +76, -950, -959, -53, -770, 477, 370, 480, +946, 380, 254, 38, -848, -561, -726, -723, +350, -78, 833, 678, 171, 755, -759, 1, +-645, -573, 326, -620, 911, -129, 98, 469, +-973, 682, -653, 110, 669, -642, 1136, -515, +-105, 326, -1251, 622, -858, -183, 719, -742, +1436, 91, 332, 1028, -1119, 337, -1192, -1126, +-87, -1081, 976, 611, 1079, 1541, 146, 371, +-945, -1266, -1254, -995, -289, 455, 1181, 957, +1481, 36, -177, -583, -1695, 3, -967, 699, +914, 20, 1368, -1190, -70, -796, -1273, 1115, +-419, 1961, 981, 132, 721, -2115, -774, -1821, +-1221, 787, 75, 2189, 1533, 1045, 989, -896, +-1024, -1446, -1850, -602, -452, 186, 1370, 505, +1722, 852, 249, 1122, -1540, 9, -1698, -1952, +-271, -2229, 1457, 338, 1876, 3244, 356, 2578, +-1676, -1333, -1957, -3956, -341, -2007, 1615, 2122, +2069, 3706, 381, 1336, -1807, -2281, -2047, -3190, +-256, -796, 1674, 2149, 2082, 2541, 259, 401, +-2027, -1749, -2122, -1964, 332, -262, 2394, 1502, +1513, 1576, -1257, -74, -2212, -1448, -417, -963, +1571, 525, 1492, 1162, -238, 401, -1465, -772, +-1054, -973, 384, -85, 1348, 977, 1030, 1046, +-441, -37, -1768, -1266, -1026, -1393, 960, 19, +1795, 1723, 581, 2028, -1070, -40, -1435, -2591, +-395, -2618, 613, 494, 891, 3510, 807, 2712, +301, -1352, -983, -3931, -1959, -1976, -785, 2078, +1882, 3215, 2881, 906, 316, -1702, -2901, -1861, +-2786, -529, 397, 500, 3032, 863, 2396, 1002, +-649, 599, -2876, -685, -2190, -1687, 674, -955, +2805, 1013, 2078, 1995, -860, 636, -2867, -1500, +-1721, -1726, 1314, 240, 2630, 1748, 906, 667, +-1584, -1186, -1894, -1044, -85, 675, 1324, 1083, +835, -228, -407, -931, -479, -60, 131, 750, +1, 3, -615, -781, -199, 33, 806, 1163, +1013, 526, -226, -1267, -1433, -1434, -916, 248, +837, 1705, 1584, 1202, 399, -453, -1128, -1603, +-1353, -1251, 50, 235, 1182, 1555, 817, 1456, +-340, -87, -773, -1532, -305, -1353, 295, 66, +167, 1046, -184, 859, 279, 311, 805, 55, +-99, -520, -1401, -1413, -1008, -1209, 1038, 1043, +2152, 2864, 551, 1238, -2177, -2284, -2269, -3143, +728, -49, 2713, 2762, 1283, 1899, -1586, -941, +-2273, -1849, -160, -362, 1775, 901, 1128, 431, +-654, -443, -914, -345, 127, 632, 428, 726, +-386, -349, -683, -1230, 488, -508, 1502, 982, +434, 1305, -1645, -54, -1879, -1552, 281, -887, +2351, 1235, 1780, 1796, -1009, -494, -2649, -2459, +-1120, -841, 1483, 2211, 2106, 2317, 539, -765, +-1127, -2593, -1295, -933, -437, 1376, 296, 1326, +658, -189, 936, -362, 604, 459, -527, 1, +-1415, -1390, -1136, -1322, 427, 942, 1821, 2468, +1566, 1246, -370, -1384, -2005, -2428, -1671, -1210, +246, 706, 1906, 2048, 1682, 1892, 84, 293, +-1444, -1977, -1729, -2701, -643, -965, 1126, 1913, +1913, 3111, 1028, 1332, -825, -1663, -2000, -3060, +-1172, -1378, 806, 1322, 1842, 2221, 921, 1011, +-733, -320, -1227, -810, -368, -958, 529, -1055, +260, -408, -219, 1117, 201, 2169, 732, 1210, +325, -1162, -722, -2691, -1182, -1745, -468, 930, +889, 2767, 1531, 2002, 798, -559, -820, -2379, +-1804, -1926, -1032, 200, 827, 1571, 1801, 1249, +1038, 297, -367, -50, -1304, -490, -1232, -1319, +-381, -1524, 880, 188, 1739, 2437, 1272, 2433, +-683, -342, -2414, -2944, -1769, -2430, 1034, 404, +2846, 2490, 1597, 1990, -1336, 35, -2620, -1393, +-997, -1654, 1426, -934, 1896, 391, 337, 1623, +-1016, 1711, -787, 134, 114, -1678, 242, -1827, +-209, -230, -81, 1259, 755, 1351, 784, 517, +-335, -384, -1290, -914, -802, -1168, 670, -448, +1551, 1125, 664, 1817, -934, 348, -1422, -1637, +-255, -1540, 1169, 412, 1001, 1654, -381, 425, +-989, -1207, 35, -729, 824, 1007, 187, 1050, +-771, -691, -622, -1595, 571, -147, 1186, 1606, +316, 1207, -1031, -769, -1167, -1585, 48, -356, +1165, 1090, 1049, 986, -199, -334, -1129, -992, +-596, -209, 464, 822, 637, 573, -6, -550, +-235, -927, 212, 85, 439, 916, -244, 453, +-949, -405, -460, -474, 951, -114, 1361, -55, +4, -67, -1251, 338, -870, 747, 444, 219, +868, -852, 159, -1110, -375, -58, 9, 1044, +514, 1070, 87, 93, -948, -778, -945, -976, +501, -572, 1839, 313, 1135, 1310, -1113, 1225, +-2273, -293, -799, -1812, 1568, -1451, 2092, 659, +413, 2036, -1369, 982, -1423, -1121, -110, -1461, +767, -15, 633, 924, 333, 223, 211, -643, +-221, -23, -817, 1025, -663, 585, 248, -1174, +1071, -1585, 821, 219, -272, 1889, -1001, 1075, +-586, -1058, 239, -1440, 673, -27, 568, 981, +-7, 304, -457, -582, -419, -209, -119, 681, +249, 503, 576, -646, 389, -947, -369, -13, +-787, 836, -211, 560, 724, -212, 868, -406, +-29, 42, -945, 98, -656, -448, 383, -687, +834, 331, 490, 1607, -170, 1076, -568, -1277, +-577, -2523, -90, -606, 493, 2098, 818, 2225, +468, -94, -457, -1712, -1023, -1181, -510, -37, +507, 325, 978, 451, 561, 1106, -246, 1063, +-663, -579, -489, -2294, -251, -1692, 206, 1087, +955, 2873, 1018, 1599, -233, -1411, -1486, -2712, +-1138, -1112, 662, 1310, 1686, 1903, 720, 588, +-894, -719, -1009, -825, -127, -336, 400, -118, +331, -85, 307, 422, 201, 877, -269, 409, +-477, -737, -85, -1014, 536, -104, 363, 742, +-384, 411, -605, -345, 205, -258, 946, 472, +486, 591, -678, -415, -1186, -1196, -344, -636, +1018, 941, 1420, 1551, 352, 527, -1140, -1036, +-1479, -1302, -319, -506, 1295, 294, 1439, 843, +12, 1151, -1036, 707, -698, -879, 123, -1991, +340, -1060, 27, 1203, 94, 2127, 667, 735, +592, -1074, -676, -1381, -1494, -465, -425, 316, +1394, 446, 1674, 477, -65, 531, -1564, 288, +-1019, -551, 558, -1208, 1075, -750, 276, 661, +-424, 1527, -290, 700, 225, -702, 174, -1137, +-215, -368, -304, 263, 77, 322, 460, 282, +416, 368, -116, 209, -514, -304, -260, -575, +214, -462, 407, -137, 101, 446, -132, 966, +-79, 670, 109, -481, 86, -1353, -70, -886, +-221, 464, -127, 1351, 301, 874, 530, -284, +149, -1004, -413, -762, -569, -29, -158, 544, +457, 593, 676, 244, 232, -77, -387, -194, +-515, -322, -163, -531, 228, -341, 258, 486, +194, 1150, 334, 712, 109, -676, -518, -1601, +-770, -788, 13, 876, 937, 1522, 872, 578, +-149, -618, -972, -1057, -659, -671, 309, 140, +904, 828, 374, 811, -371, -11, -397, -704, +55, -443, 125, 150, -111, 33, 1, -262, +312, 282, 311, 961, -40, 325, -452, -1197, +-287, -1287, 204, 447, 496, 1595, 166, 527, +-179, -1097, -195, -928, 47, 425, 50, 905, +-105, -87, 42, -807, 325, -297, 210, 671, +-159, 706, -317, -136, -73, -805, 209, -518, +289, 305, 70, 667, -133, 291, -69, -272, +-8, -433, 85, -59, 54, 232, 3, 107, +-90, -208, 113, -192, 240, 191, 72, 544, +-246, 292, -248, -592, 81, -1012, 359, -176, +236, 1060, -76, 1128, -242, -93, -117, -1211, +116, -897, 158, 314, 110, 960, -19, 382, +-37, -334, 16, -251, 51, 128, 61, -79, +-23, -508, -123, -260, -66, 544, 263, 958, +368, 247, -6, -940, -306, -1147, -321, 41, +-33, 1145, 317, 734, 495, -384, 239, -717, +-189, -54, -573, 251, -509, -116, 277, -210, +902, 349, 559, 514, -314, -96, -756, -567, +-477, -308, 233, 180, 652, 307, 550, 130, +79, 18, -509, -71, -677, -141, -51, -149, +723, 26, 508, 92, -163, 52, -403, 18, +29, 82, 195, 47, -32, -153, -215, -174, +98, -61, 372, 114, 186, 150, 0, 145, +-236, -19, -372, -126, -140, -142, 434, -180, +639, -32, 184, 311, -415, 407, -622, -80, +-112, -469, 492, -194, 444, 219, 11, 133, +-73, -252, 74, 46, -78, 630, -413, 352, +-405, -769, 329, -1190, 1145, 32, 718, 1501, +-734, 1226, -1523, -791, -552, -1857, 1094, -409, +1573, 1458, 395, 1117, -987, -764, -1203, -1150, +-218, 410, 688, 1250, 869, -149, 259, -1637, +-234, -662, -306, 1493, -203, 1783, -171, -313, +-102, -2021, 310, -1193, 579, 895, 497, 1675, +-183, 520, -758, -826, -616, -898, 99, -199, +800, 258, 831, 216, 163, 284, -627, 346, +-783, 33, -213, -441, 338, -569, 616, -90, +563, 328, 241, 426, -400, 305, -896, 157, +-570, -363, 412, -921, 1197, -530, 824, 755, +-256, 1384, -1179, 398, -955, -1174, 298, -1358, +1234, -12, 945, 1287, -232, 921, -1005, -393, +-668, -975, 339, -290, 772, 445, 270, 364, +-200, -80, -90, -245, 101, 18, -106, 261, +-338, 145, -49, -295, 548, -470, 579, -58, +-97, 571, -581, 629, -406, -111, 176, -855, +537, -620, 442, 406, -42, 978, -430, 380, +-445, -689, 146, -885, 698, -9, 323, 844, +-494, 677, -494, -413, 268, -1044, 603, -262, +128, 1077, -404, 935, -367, -665, 191, -1421, +478, -125, 206, 1420, -261, 889, -234, -875, +117, -1233, 205, 202, -40, 1096, -237, 203, +139, -815, 564, -438, 285, 750, -556, 683, +-841, -611, 70, -1117, 1020, 157, 877, 1314, +-283, 555, -1115, -1002, -535, -1060, 564, 324, +864, 1075, 204, 216, -286, -753, -254, -480, +0, 443, -32, 569, -237, -218, 113, -622, +667, -74, 518, 566, -367, 359, -854, -295, +-280, -443, 560, -24, 757, 306, 69, 125, +-417, -159, -162, -56, 124, 140, 35, 99, +-187, -159, 7, -269, 384, -108, 520, 307, +-16, 574, -667, 43, -520, -741, 218, -732, +749, 411, 462, 1115, -127, 370, -454, -925, +-378, -1028, -22, 226, 402, 1124, 521, 519, +74, -697, -396, -888, -242, 64, 235, 751, +261, 379, -184, -325, -262, -402, 258, -45, +611, 70, 53, 76, -589, 245, -409, 276, +257, -190, 487, -649, 270, -320, -4, 541, +-161, 815, -268, 55, -167, -725, 94, -592, +324, 21, 452, 494, 146, 520, -446, 227, +-537, -369, 61, -708, 529, -392, 360, 441, +-26, 906, -209, 262, -114, -677, -11, -688, +-67, 130, -2, 497, 342, 110, 436, -138, +-27, 22, -538, 76, -420, -186, 249, -236, +716, 99, 295, 267, -443, 105, -443, -158, +131, -154, 464, -61, 123, 102, -307, 287, +-233, 63, 281, -497, 486, -544, 24, 494, +-470, 1121, -339, 126, 264, -1363, 552, -1057, +174, 784, -345, 1581, -283, 172, 247, -1221, +236, -680, -220, 591, -280, 443, 331, -420, +648, -212, -24, 734, -722, 632, -493, -678, +494, -1258, 792, -207, 125, 1188, -497, 1099, +-379, -192, 140, -1106, 328, -734, 112, 267, +-119, 765, -39, 404, 116, -182, 149, -341, +13, -122, -218, -36, -205, -65, 167, 51, +451, 233, 219, 170, -266, -64, -404, -160, +17, -92, 349, -58, 148, -85, -164, 5, +29, 222, 363, 300, 63, 124, -502, -256, +-445, -573, 324, -422, 817, 328, 433, 964, +-470, 579, -791, -552, -282, -1125, 467, -482, +750, 621, 375, 951, -253, 287, -669, -451, +-430, -514, 279, -134, 637, 19, 356, -19, +-148, 182, -308, 509, -180, 342, -32, -340, +20, -777, 178, -466, 373, 296, 288, 772, +-210, 609, -540, -108, -208, -737, 291, -687, +417, -27, 190, 530, 23, 530, -102, 210, +-210, -55, -322, -298, -123, -582, 406, -595, +694, 188, 340, 1193, -455, 1062, -894, -489, +-428, -1682, 600, -908, 1064, 866, 415, 1499, +-571, 409, -834, -821, -246, -823, 395, -36, +506, 288, 251, 24, 100, 88, -94, 520, +-435, 336, -454, -588, 68, -938, 652, -42, +616, 881, -105, 629, -602, -329, -373, -590, +182, 16, 350, 305, 136, -160, -18, -428, +53, 241, 96, 824, -148, 211, -297, -877, +-59, -815, 316, 362, 345, 935, 59, 188, +-162, -590, -156, -280, -47, 348, -70, 94, +-95, -491, 244, -206, 619, 691, 241, 664, +-629, -490, -791, -1026, -26, -65, 768, 956, +771, 484, 81, -558, -629, -628, -644, 220, +-111, 555, 378, -4, 620, -489, 438, -187, +-105, 400, -657, 385, -692, -196, -9, -506, +943, -101, 948, 478, -189, 409, -1095, -259, +-647, -642, 429, -168, 892, 612, 440, 623, +-284, -189, -588, -825, -328, -390, 93, 505, +476, 701, 518, 15, -18, -488, -571, -229, +-375, 117, 243, 47, 437, -96, 96, 92, +-118, 293, -31, 177, 25, -250, -167, -500, +-187, -190, 216, 425, 450, 511, 107, -1, +-430, -367, -282, -164, 174, 51, 339, -67, +33, -143, -143, 149, 36, 485, 119, 311, +-92, -374, -168, -846, 93, -352, 197, 652, +58, 988, -15, 189, -9, -782, -86, -785, +-119, 45, 32, 578, 201, 312, 263, -50, +9, 13, -359, 12, -245, -386, 230, -521, +453, 122, 111, 810, -352, 531, -339, -422, +174, -835, 438, -267, 103, 546, -312, 597, +-313, -70, 113, -516, 520, -153, 275, 376, +-478, 201, -639, -358, 187, -355, 861, 285, +399, 531, -625, 9, -862, -474, 92, -283, +947, 158, 517, 282, -494, 106, -704, -53, +-34, -111, 497, -114, 327, -68, -101, 132, +-170, 183, 14, -54, -1, -266, -123, -30, +4, 340, 218, 185, 185, -328, -6, -417, +-117, 174, -146, 519, -137, 94, 6, -479, +299, -268, 449, 367, 56, 395, -566, -303, +-566, -555, 115, 145, 738, 730, 591, 191, +-187, -687, -789, -558, -472, 391, 398, 671, +691, -121, 208, -611, -283, -2, -296, 640, +-74, 158, -14, -694, -5, -597, 252, 423, +451, 985, 32, 350, -537, -798, -490, -1057, +170, -62, 665, 1045, 356, 849, -279, -337, +-442, -921, -117, -296, 148, 447, 159, 329, +205, -160, 195, -92, -65, 343, -404, 148, +-292, -541, 236, -563, 526, 325, 222, 792, +-272, 159, -393, -595, -112, -399, 223, 199, +273, 274, 149, -55, 14, -55, -210, 153, +-325, 56, -53, -259, 333, -227, 442, 206, +75, 379, -415, -17, -450, -436, 64, -244, +441, 331, 338, 506, -7, -30, -258, -580, +-314, -352, -141, 327, 236, 502, 438, 74, +209, -294, -218, -226, -394, -9, -198, 65, +148, 34, 364, 68, 302, 147, -19, 81, +-317, -142, -343, -300, -32, -131, 364, 195, +382, 283, -9, 91, -277, -48, -178, -55, +31, -212, 100, -390, 8, -54, 67, 671, +235, 709, 99, -285, -259, -1007, -349, -455, +-30, 584, 348, 788, 395, 60, 52, -531, +-306, -289, -342, 269, -54, 162, 248, -371, +308, -280, 105, 502, -170, 750, -194, -124, +-23, -975, 128, -569, 45, 526, -132, 829, +15, 113, 401, -415, 262, -208, -444, 26, +-738, -203, 6, -251, 918, 296, 742, 754, +-385, 315, -1004, -682, -376, -1010, 595, -128, +734, 950, 91, 856, -344, -208, -325, -828, +-120, -375, 45, 313, 226, 342, 296, -65, +97, -80, -237, 237, -288, 182, 41, -334, +199, -513, 27, -4, -43, 557, 156, 426, +194, -177, -157, -452, -406, -185, -144, 143, +440, 170, 556, 54, -116, 21, -600, 39, +-265, -67, 395, -126, 485, -33, -41, 68, +-508, 1, -203, -45, 439, 65, 460, 253, +-110, 120, -534, -371, -348, -588, 233, -15, +705, 786, 447, 732, -420, -254, -907, -1059, +-338, -674, 742, 516, 1024, 1144, -13, 456, +-962, -734, -556, -1026, 440, -110, 632, 795, +27, 651, -338, -183, -93, -586, 229, -220, +29, 269, -212, 198, -53, -129, 226, -48, +101, 265, -77, 55, 51, -429, 99, -309, +-143, 377, -300, 578, 31, -40, 467, -613, +329, -388, -281, 301, -477, 581, -28, 195, +359, -386, 228, -490, -136, -78, -148, 344, +102, 373, 143, 69, -72, -228, -226, -275, +-68, -185, 244, 22, 331, 343, 45, 451, +-314, -20, -337, -614, 71, -517, 370, 255, +206, 754, -145, 294, -176, -502, 70, -578, +125, 94, -165, 475, -266, 132, 160, -304, +601, -160, 270, 285, -601, 287, -704, -281, +114, -588, 769, -8, 445, 774, -273, 547, +-489, -511, -123, -920, 140, -122, 80, 775, +111, 632, 282, -222, 185, -693, -336, -259, +-581, 357, -25, 373, 642, -11, 496, -189, +-279, -115, -519, -30, -42, 26, 326, 103, +101, 119, -220, 3, -15, -191, 353, -200, +178, 82, -398, 338, -424, 221, 180, -230, +569, -482, 192, -175, -431, 418, -367, 554, +230, 27, 414, -526, -23, -439, -391, 87, +-169, 402, 321, 308, 408, 40, 19, -242, +-408, -356, -369, -191, 52, 214, 480, 465, +390, 209, -109, -304, -466, -435, -198, -33, +222, 259, 185, 163, -46, -23, 28, -1, +291, 9, 68, -112, -460, -193, -461, 9, +180, 238, 683, 204, 420, -87, -278, -217, +-605, -96, -301, 78, 187, 59, 457, 25, +348, 100, -33, 60, -330, -160, -318, -217, +-29, 92, 239, 250, 157, 14, 54, -233, +175, -14, 72, 251, -396, 19, -504, -350, +116, -113, 728, 388, 512, 299, -400, -315, +-777, -437, -91, 168, 588, 518, 310, -21, +-253, -557, -215, -167, 166, 517, 284, 400, +-157, -292, -446, -502, -49, -56, 464, 309, +350, 267, -105, 108, -345, -99, -201, -384, +73, -326, 136, 262, 103, 628, 192, 151, +171, -573, -201, -493, -500, 261, -217, 555, +408, 15, 666, -434, 198, -105, -567, 318, +-660, 93, 33, -302, 601, -127, 438, 331, +-127, 238, -399, -299, -197, -418, 130, 119, +216, 539, 52, 201, -88, -428, -4, -517, +129, 50, 35, 546, -211, 412, -262, -216, +170, -602, 531, -211, 155, 427, -525, 394, +-510, -185, 274, -285, 690, 207, 116, 248, +-611, -425, -376, -554, 416, 417, 505, 1031, +-159, 32, -501, -1198, 27, -713, 456, 895, +97, 1173, -466, -290, -207, -1247, 495, -296, +467, 1056, -322, 727, -714, -680, -89, -1037, +713, 159, 635, 1064, -298, 466, -805, -713, +-290, -878, 520, 65, 597, 828, 9, 485, +-419, -409, -199, -649, 118, -13, 84, 459, +-91, 153, 62, -248, 324, -65, 133, 249, +-361, 18, -447, -381, 46, -217, 518, 399, +385, 526, -140, -122, -427, -668, -273, -318, +68, 429, 310, 621, 319, 79, 68, -515, +-298, -501, -384, 128, -65, 528, 355, 191, +454, -294, 25, -182, -490, 158, -377, -4, +213, -302, 491, -37, 168, 495, -322, 404, +-351, -348, 129, -755, 380, -214, 38, 667, +-334, 720, -149, -111, 297, -737, 291, -428, +-188, 296, -383, 505, 45, 183, 387, -171, +89, -275, -266, -200, -136, 38, 194, 279, +156, 202, -183, -83, -228, -231, 231, -136, +353, 74, -107, 182, -376, 107, -104, -67, +236, -128, 232, -83, -22, 12, -177, 123, +-48, 144, 70, 10, 45, -191, -32, -191, +-40, 71, 13, 259, 113, 163, 120, -116, +-106, -288, -278, -201, -60, 204, 310, 451, +314, 72, -130, -451, -354, -346, -90, 252, +245, 426, 137, -16, -114, -343, -100, -107, +176, 241, 150, 127, -217, -158, -294, -149, +84, 85, 412, 172, 173, 6, -297, -106, +-363, -82, 120, -9, 347, 29, 30, 81, +-274, 101, -36, -14, 280, -134, 109, -173, +-250, 11, -254, 270, 90, 213, 276, -193, +133, -376, -63, 14, -86, 377, -112, 170, +-197, -285, -16, -286, 396, 132, 401, 340, +-195, 86, -604, -284, -268, -306, 412, 96, +536, 388, -14, 180, -393, -266, -74, -352, +142, -2, -120, 329, -165, 216, 203, -200, +438, -281, 83, 76, -443, 317, -436, -15, +119, -446, 440, -126, 220, 596, -22, 392, +-191, -562, -308, -654, -195, 296, 284, 670, +449, 65, 71, -460, -345, -217, -239, 183, +80, 166, 98, -114, 21, -129, 138, 193, +143, 295, -183, -134, -317, -615, 11, -201, +413, 732, 251, 698, -379, -476, -494, -980, +255, -4, 649, 886, -20, 329, -645, -559, +-240, -322, 451, 324, 451, 119, -102, -313, +-469, -15, -174, 357, 312, 112, 281, -259, +-155, -210, -238, 36, 88, 127, 145, 109, +0, 60, -26, -14, -32, -153, -136, -190, +-12, 46, 161, 290, 146, 152, 61, -235, +-229, -266, -320, 105, 107, 314, 408, 52, +98, -401, -183, -257, -146, 441, -132, 553, +5, -310, 173, -726, 160, 0, 11, 590, +-65, 269, -154, -245, -100, -220, 40, -6, +73, -36, 132, -65, 190, 204, -94, 279, +-386, -159, -139, -361, 334, 50, 370, 279, +-81, -45, -449, -239, -167, 82, 422, 359, +281, 26, -352, -449, -334, -288, 243, 376, +330, 452, -5, -206, -261, -424, -165, 165, +191, 388, 126, -303, -239, -489, -71, 284, +410, 737, 211, -4, -377, -788, -484, -439, +62, 521, 583, 733, 268, -103, -371, -709, +-319, -290, 150, 508, 119, 502, -141, -243, +-39, -591, 242, -26, 267, 548, -129, 277, +-518, -345, -174, -385, 396, 88, 262, 301, +-88, 34, -10, -146, 29, 31, -139, 134, +-176, -103, -167, -293, 102, -84, 586, 350, +376, 474, -480, -46, -803, -704, -176, -523, +587, 456, 749, 913, 90, 138, -569, -787, +-511, -608, -64, 289, 203, 623, 364, 128, +330, -320, -27, -205, -391, 92, -422, 90, +-33, -90, 423, -71, 431, 126, -120, 186, +-428, -11, -80, -212, 189, -191, 44, 50, +-64, 268, 29, 139, 63, -176, 56, -197, +5, 93, -173, 139, -157, -83, 69, -90, +225, 93, 50, 84, -117, -121, -53, -31, +128, 216, 13, 89, -312, -396, -218, -378, +405, 351, 522, 772, -126, 106, -579, -872, +-305, -659, 239, 447, 435, 801, 189, 14, +-134, -410, -200, -18, -230, 73, -163, -414, +144, -299, 449, 552, 248, 875, -231, -14, +-506, -1010, -217, -759, 370, 399, 425, 999, +-65, 342, -319, -512, -83, -587, 23, 40, +104, 311, 158, -30, -59, -163, -237, 292, +-25, 430, 221, -260, 122, -673, -24, -175, +-218, 478, -350, 475, 64, 42, 617, -297, +392, -328, -502, -105, -750, 153, 12, 212, +718, 157, 326, 70, -372, -169, -318, -441, +93, -111, 201, 534, -36, 390, -279, -295, +-29, -508, 478, -27, 220, 380, -392, 321, +-478, -146, -23, -408, 353, -136, 421, 238, +36, 354, -256, 70, -345, -358, -283, -367, +249, 222, 575, 511, 6, -63, -439, -567, +-63, -93, 169, 636, -2, 333, -192, -606, +-84, -647, 340, 289, 350, 877, -296, 212, +-562, -741, -21, -607, 426, 382, 269, 604, +-176, -70, -241, -332, 150, 8, 112, 114, +-292, -86, -275, -89, 274, 86, 453, 144, +72, -14, -376, -139, -373, -83, 64, 161, +300, 142, 89, -232, -91, -308, 110, 304, +61, 548, -386, -229, -315, -740, 330, -17, +467, 802, -14, 293, -276, -690, -217, -512, +-32, 416, 124, 615, 24, -7, 13, -521, +216, -433, 28, 243, -343, 633, -179, 49, +165, -510, 280, -118, 31, 316, -354, -59, +-109, -400, 450, 136, 142, 766, -572, 146, +-329, -938, 432, -658, 621, 612, -31, 903, +-724, 15, -396, -719, 414, -463, 524, 448, +-66, 521, -403, -344, -122, -581, 296, 418, +133, 859, -395, -185, -232, -1186, 373, -452, +429, 1182, -178, 1081, -524, -681, -173, -1412, +331, 59, 366, 1388, -4, 481, -359, -1265, +-234, -978, 234, 1058, 216, 1478, -164, -531, +-222, -1812, 92, -324, 251, 1693, 120, 1114, +-332, -1091, -387, -1470, 196, 412, 445, 1427, +37, 111, -385, -1309, -199, -552, 191, 1199, +197, 1114, -144, -873, -91, -1611, 111, 137, +10, 1738, -95, 725, -109, -1349, -49, -1221, +127, 687, 210, 1309, -92, -155, -228, -1163, +-115, -295, 105, 1003, 242, 729, 4, -727, +-200, -1019, -169, 190, -40, 992, 171, 285, +333, -664, -85, -426, -519, 418, -162, 358, +344, -491, 451, -394, -92, 578, -609, 701, +-250, -342, 452, -961, 429, -153, -143, 877, +-494, 524, -215, -570, 486, -594, 399, 333, +-449, 594, -660, -153, 172, -742, 775, -156, +329, 890, -710, 649, -805, -639, 198, -1078, +881, 14, 353, 1054, -535, 622, -638, -615, +-45, -890, 411, 142, 307, 777, -10, 151, +-297, -658, -183, -337, 115, 649, 53, 640, +-133, -515, 55, -1008, 111, 70, -99, 1097, +-73, 525, 79, -719, -19, -857, -180, 166, +-99, 742, 130, 218, 225, -466, 32, -379, +-204, 325, -271, 552, -142, -155, 101, -847, +339, -234, 301, 942, -151, 824, -576, -620, +-324, -1166, 231, 76, 391, 1004, 259, 243, +-23, -595, -419, -209, -388, 407, 40, 191, +234, -442, 159, -535, 196, 253, -36, 1079, +-340, 452, -334, -1097, -116, -1436, 283, 363, +505, 1857, 127, 780, -497, -1459, -386, -1499, +-1, 606, 182, 1514, 130, 43, 85, -1260, +71, -309, -40, 1122, -329, 643, -396, -1044, +116, -1194, 541, 564, 279, 1700, -400, 337, +-483, -1657, -17, -1206, 335, 1006, 107, 1634, +-224, -184, -97, -1537, 208, -521, 115, 1238, +-306, 991, -275, -865, 66, -1319, 233, 443, +73, 1534, -100, 48, -11, -1554, 24, -587, +-221, 1423, -413, 1042, 98, -1092, 677, -1434, +385, 659, -617, 1659, -911, -97, 109, -1716, +862, -484, 262, 1530, -577, 941, -330, -1136, +294, -1216, 278, 716, -373, 1332, -615, -357, +283, -1471, 943, 33, 75, 1707, -1041, 481, +-551, -1881, 542, -1206, 662, 1706, -89, 1955, +-635, -1113, -157, -2407, 552, 255, 194, 2469, +-721, 629, -447, -2146, 617, -1481, 734, 1511, +-233, 2112, -936, -544, -304, -2332, 627, -502, +441, 1967, -299, 1301, -309, -1143, 17, -1663, +69, 277, 9, 1522, -81, 445, -117, -1068, +21, -791, 14, 409, 56, 635, 200, 111, +-110, -75, -554, -38, -195, -431, 418, -661, +479, 194, 66, 1342, -513, 890, -644, -1191, +101, -1925, 584, -22, 212, 1993, -309, 1238, +-268, -962, 147, -1399, 50, -123, -375, 594, +-222, 131, 476, 101, 442, 542, -197, 365, +-752, -814, -322, -1310, 631, -43, 491, 1515, +-383, 1216, -556, -669, 76, -1467, 410, -286, +192, 897, -507, 290, -550, -463, 307, 179, +644, 900, 101, -155, -561, -1374, -523, -672, +18, 1047, 431, 1345, 203, -165, 58, -1121, +-66, -298, -601, 554, -476, -57, 389, -539, +844, 375, 149, 1145, -838, 70, -789, -1493, +422, -984, 916, 1070, -145, 1494, -849, -279, +-255, -1468, 753, -219, 602, 1311, -661, 540, +-1148, -1284, 154, -1052, 1236, 1021, 426, 1562, +-961, -204, -857, -1581, 373, -664, 724, 1035, +-130, 1002, -611, -492, 70, -863, 485, 278, +-45, 802, -701, -156, -160, -852, 646, -197, +289, 785, -639, 512, -563, -562, 483, -559, +812, 389, -115, 787, -1296, -353, -602, -1250, +1067, -258, 1171, 1531, -305, 1336, -1241, -902, +-609, -1915, 543, -462, 847, 1541, -105, 1228, +-634, -576, -96, -1127, 348, 128, 166, 910, +-490, -166, -629, -1123, 299, -357, 1038, 1395, +67, 1369, -1015, -701, -575, -1852, 383, -692, +648, 1226, -124, 1341, -631, -32, 64, -945, +716, -343, 21, 292, -1033, -82, -733, -349, +682, 189, 1430, 903, 103, 506, -1525, -820, +-1017, -1325, 672, -135, 1205, 1235, -18, 1027, +-856, -283, -263, -887, 444, -463, -24, 88, +-557, 88, 11, 408, 579, 785, 309, 151, +-517, -1099, -644, -1182, 47, 435, 472, 1631, +42, 620, -242, -1245, 142, -1173, 215, 456, +-408, 1092, -805, 213, 26, -870, 1174, -519, +621, 582, -949, 685, -1263, -223, -5, -542, +1106, -64, 638, 59, -630, -73, -722, 238, +251, 784, 259, 115, -477, -1312, -339, -1165, +657, 899, 946, 2125, -469, 405, -1602, -2126, +-534, -1906, 1313, 1084, 1384, 2664, -363, 491, +-1575, -2249, -756, -1883, 779, 941, 917, 2382, +47, 657, -468, -1772, -268, -1646, -130, 385, +-523, 1497, -81, 761, 1133, -494, 954, -861, +-903, -389, -1878, 67, -582, 403, 1572, 588, +1978, 206, -180, -345, -2243, -565, -1597, -326, +858, 162, 2105, 511, 841, 376, -1233, 77, +-1716, -200, -358, -644, 978, -682, 1061, 257, +336, 1348, -724, 974, -1117, -914, -480, -1996, +662, -509, 1018, 1789, 389, 1911, -682, -341, +-1182, -2242, -438, -1365, 765, 1288, 1056, 2172, +107, 194, -786, -1736, -697, -1126, -140, 772, +262, 1101, 221, -202, 299, -773, 436, 262, +-68, 899, -1258, -121, -1229, -1433, 756, -765, +2082, 1415, 803, 1932, -1756, -286, -2343, -2361, +61, -1270, 2520, 1494, 1563, 2250, -1583, 2, +-2489, -2170, 2, -1211, 2327, 1259, 1110, 1888, +-1562, -124, -1759, -1989, 390, -977, 1541, 1560, +480, 1837, -1101, -663, -987, -2035, 568, -585, +1009, 1569, -386, 1588, -1182, -495, 24, -1941, +1151, -875, 482, 1506, -970, 1893, -1015, -149, +298, -2033, 856, -1397, 72, 873, -465, 2161, +-147, 941, 218, -1435, -6, -2184, -516, -265, +-306, 2085, 392, 1706, 583, -1012, 131, -2180, +-452, -166, -727, 2021, -262, 1078, 318, -1607, +528, -1969, 465, 711, -164, 2745, -895, 833, +-574, -2482, 345, -2556, 658, 882, 283, 3194, +-381, 1292, -659, -2314, -45, -2712, 620, 680, +293, 2776, -650, 844, -907, -2084, 143, -1846, +1338, 1016, 780, 2407, -921, 415, -1756, -2141, +-671, -1868, 1362, 664, 1920, 2250, 148, 1264, +-1877, -887, -1518, -1892, 396, -1146, 1485, 359, +566, 1691, -592, 1822, -510, 142, -36, -2158, +-131, -2528, -529, -113, 45, 2838, 1020, 2847, +802, -397, -789, -3293, -1618, -2551, -506, 959, +1224, 3263, 1574, 1972, 15, -1365, -1655, -2842, +-1357, -1248, 425, 1381, 1471, 2226, 870, 786, +-429, -1221, -1326, -1704, -1082, -445, 281, 922, +1503, 1199, 1272, 551, -666, -415, -2238, -1336, +-1078, -1251, 1692, 555, 2350, 2393, -205, 1404, +-2618, -1693, -1714, -3165, 1679, -607, 2820, 2946, +-20, 2992, -2984, -730, -1824, -3432, 1811, -1847, +2824, 1761, -96, 2805, -2761, 380, -1507, -1914, +1558, -1302, 2179, 635, -241, 963, -2091, -210, +-832, -521, 1212, 372, 1350, 743, -253, -194, +-1405, -1186, -768, -588, 745, 990, 1163, 1547, +156, -135, -828, -1759, -1142, -1135, -99, 1105, +1245, 1880, 929, 411, -654, -1565, -1370, -1826, +-409, -36, 981, 1946, 1194, 1952, -354, -376, +-1407, -2468, -400, -1744, 886, 924, 836, 2413, +-371, 1297, -1015, -943, -155, -2104, 922, -1067, +376, 890, -812, 1667, -668, 700, 420, -613, +827, -935, -191, -406, -823, -24, -58, 43, +658, 553, 67, 1033, -768, 374, -405, -1176, +777, -1752, 1057, -228, -560, 1855, -1641, 1970, +-406, -321, 1450, -2220, 1307, -1632, -591, 746, +-1787, 2174, -520, 1163, 1486, -869, 1097, -1928, +-776, -894, -1431, 847, -144, 1760, 1215, 763, +834, -852, -621, -1550, -1058, -723, -308, 716, +388, 1484, 612, 828, 407, -674, -39, -1516, +-570, -875, -853, 724, -436, 1445, 741, 680, +1413, -608, 376, -986, -1331, -615, -1628, 99, +-16, 545, 1592, 848, 1377, 486, -654, -426, +-1755, -1064, -507, -681, 1108, 256, 919, 973, +-484, 811, -863, -32, 73, -703, 844, -730, +103, -294, -1070, 212, -782, 549, 839, 659, +1662, 503, 184, -281, -1970, -1313, -1971, -1243, +769, 406, 2974, 1917, 1569, 1530, -2178, -715, +-3530, -2180, -517, -1156, 3257, 932, 3089, 1516, +-872, 589, -3678, -338, -1947, -485, 1922, -463, +2959, -834, 442, -423, -2236, 1137, -1762, 2052, +891, 475, 1830, -2129, -73, -2534, -1803, 115, +-711, 2691, 1648, 2012, 1896, -620, -643, -2017, +-2837, -1291, -1606, -73, 1868, 856, 3300, 1570, +865, 1465, -2700, -386, -3320, -2660, -152, -2346, +3135, 716, 2626, 3398, -711, 2642, -2766, -1056, +-1663, -3858, 850, -2482, 1786, 1577, 800, 3713, +-293, 1738, -780, -1746, -980, -2850, -570, -925, +627, 1362, 1456, 1749, 800, 464, -1050, -835, +-2029, -970, -483, -137, 1969, 563, 1984, 502, +-724, -161, -2675, -691, -1199, -450, 1940, 673, +2594, 1397, -45, 497, -2630, -1540, -2018, -2337, +712, -340, 2666, 2509, 1735, 3060, -1013, 177, +-2814, -3340, -1811, -3595, 1155, 184, 3049, 3924, +1747, 3455, -1386, -580, -3025, -3730, -1661, -2829, +1213, 575, 2771, 2844, 1499, 2222, -893, -134, +-2077, -1814, -1664, -1736, -175, -422, 1587, 847, +2310, 1496, 1060, 999, -1563, -429, -3254, -1537, +-1617, -987, 2206, 674, 3842, 1366, 1093, 166, +-2903, -1069, -3597, -544, -227, 825, 3048, 941, +2647, -257, -492, -1222, -2555, -763, -1804, 464, +487, 1151, 2056, 924, 1422, 4, -509, -1065, +-1790, -1448, -1281, -611, 449, 936, 1651, 2014, +1083, 1286, -434, -919, -1358, -2390, -1070, -1445, +88, 682, 1134, 1929, 1123, 1494, 189, 255, +-810, -981, -1355, -1936, -712, -1690, 711, 353, +1615, 2834, 920, 2725, -757, -442, -1768, -3489, +-897, -2766, 787, 927, 1565, 3245, 729, 1838, +-688, -1041, -1308, -2087, -585, -775, 543, 573, +896, 656, 421, 195, -323, 215, -535, 268, +-400, -298, -176, -701, 250, -215, 866, 730, +776, 462, -695, -735, -1872, -986, -759, 586, +1758, 1887, 2385, 709, 175, -1807, -2591, -2451, +-2571, -300, 472, 2196, 3003, 2549, 2223, 650, +-782, -1941, -2711, -2898, -1937, -1265, 444, 1600, +2015, 2975, 1789, 1673, 410, -958, -1239, -2494, +-2028, -1865, -1316, -21, 596, 1474, 2093, 1796, +1992, 1232, 84, 86, -1952, -1557, -2381, -2791, +-984, -1784, 1427, 1582, 2823, 4281, 1888, 2938, +-962, -1883, -3208, -5109, -2639, -3045, 722, 2081, +3419, 4569, 2618, 2351, -589, -1426, -2828, -2833, +-2368, -1728, 36, -250, 2074, 900, 2050, 1933, +466, 2016, -1299, 117, -1734, -2398, -816, -2846, +528, -395, 1259, 2440, 1217, 2708, 139, 360, +-1175, -1821, -1442, -1914, -336, -542, 1070, 736, +1341, 1228, 179, 989, -947, 94, -786, -859, +19, -1220, 521, -431, 150, 613, -333, 898, +57, 342, 809, 111, 442, -10, -1068, -709, +-1780, -1425, -163, -477, 2348, 1800, 2361, 2550, +-654, 0, -3345, -3015, -2307, -2528, 1418, 927, +3588, 3166, 1887, 1813, -1678, -1252, -3137, -2480, +-1459, -968, 1190, 838, 2258, 1028, 1199, 531, +-207, 538, -927, 373, -1350, -895, -1430, -2131, +-98, -1138, 2029, 1658, 2823, 3122, 606, 1311, +-2859, -2038, -3671, -3499, -383, -1336, 3391, 2228, +3443, 3270, -234, 921, -3324, -1878, -2280, -2282, +1040, -535, 2311, 974, 429, 948, -1330, 394, +-582, 295, 1130, 146, 981, -588, -1073, -1266, +-1912, -769, -352, 786, 1881, 1790, 2017, 857, +-5, -938, -1947, -1671, -1722, -526, 102, 1013, +1347, 1028, 1086, -289, 221, -881, -336, 175, +-576, 1123, -761, 432, -577, -1372, 233, -1747, +1173, 183, 1102, 2248, -104, 1822, -1089, -699, +-1087, -2347, -310, -1456, 567, 763, 981, 1766, +792, 861, 104, -406, -857, -698, -1166, -289, +-617, -261, 541, -368, 1279, -78, 1009, 666, +-113, 1098, -1206, 652, -1248, -573, -319, -1726, +971, -1429, 1315, 268, 450, 2209, -561, 2203, +-934, -21, -608, -2439, 54, -2437, 452, -183, +406, 1908, 568, 2161, 529, 761, -451, -753, +-1562, -1795, -1144, -1872, 936, -358, 2299, 1988, +973, 2657, -1515, 503, -2110, -2062, -413, -2229, +1482, -173, 1571, 1358, -43, 875, -1369, 11, +-849, 163, 505, 491, 938, -421, 313, -1598, +-621, -1134, -785, 984, -50, 2139, 652, 926, +645, -1001, 290, -1399, -452, -593, -1050, 97, +-682, 189, 486, 562, 1371, 1104, 923, 778, +-417, -685, -1353, -1773, -982, -1238, -48, 412, +848, 1637, 1182, 1463, 792, 319, -244, -808, +-1299, -1534, -1510, -1473, -606, -229, 1191, 1596, +2352, 2430, 1471, 1205, -1186, -1396, -3003, -3033, +-1852, -1900, 1124, 1052, 3003, 2946, 1846, 2158, +-865, -362, -2434, -2259, -1517, -2095, 395, -496, +1492, 1187, 1040, 1881, 21, 1345, -365, -201, +-426, -1624, -486, -1747, -606, -486, -29, 1216, +837, 1709, 1093, 774, 225, -768, -954, -1339, +-987, -620, 29, 501, 641, 694, 144, -12, +-289, -336, 168, 129, 812, 661, 343, 386, +-979, -635, -1407, -1427, -303, -865, 1337, 1109, +1651, 2384, 267, 1099, -1280, -1719, -1344, -2772, +-214, -705, 612, 1881, 629, 2090, 526, 195, +475, -1137, -240, -851, -1046, -174, -956, -198, +65, -142, 1173, 704, 1126, 1298, -139, 421, +-1099, -1218, -611, -1614, 370, -236, 519, 1252, +-76, 1194, -431, 46, -45, -731, 717, -521, +746, -127, -312, -44, -1374, 74, -1003, 485, +688, 548, 1760, -147, 872, -718, -819, -448, +-1388, 394, -559, 590, 451, -22, 630, -609, +217, -193, 185, 630, 505, 659, 60, -346, +-1109, -1123, -1426, -505, 12, 845, 1765, 1231, +1828, 170, -2, -1010, -1892, -879, -1857, 99, +-120, 628, 1651, 281, 1725, 40, 213, 112, +-1211, 38, -1237, -421, -203, -698, 590, -186, +557, 784, 307, 1090, 157, 86, -8, -1033, +-392, -1036, -691, 70, -280, 908, 501, 672, +891, -86, 320, -358, -463, -278, -698, -364, +-193, -149, 291, 419, 332, 669, 80, 98, +-66, -496, 82, -441, 106, 93, -222, 220, +-382, -67, -10, -45, 431, 337, 312, 316, +-94, -292, -214, -642, -44, -173, 27, 521, +-68, 525, -150, -158, 85, -445, 347, -11, +336, 383, -130, 49, -559, -551, -337, -442, +219, 465, 525, 1061, 328, 288, -138, -1011, +-377, -1211, -213, 26, 57, 1214, 170, 1051, +194, -246, 26, -1120, -52, -662, 0, 422, +43, 693, -41, 9, -246, -382, -150, 201, +306, 638, 534, -255, 75, -1239, -443, -527, +-430, 1189, 23, 1444, 330, -153, 307, -1462, +54, -868, -86, 539, -122, 959, -116, 231, +-47, -372, 72, -282, 115, 97, 37, 59, +-19, -286, 201, -247, 311, 350, -192, 658, +-794, 89, -507, -662, 703, -674, 1420, 146, +530, 793, -1217, 499, -1652, -395, -133, -826, +1444, -293, 1302, 699, -123, 909, -978, -51, +-618, -1086, 131, -836, 209, 456, 49, 1275, +179, 620, 611, -732, 445, -1083, -526, -339, +-1168, 431, -452, 654, 819, 582, 1152, 108, +334, -642, -572, -924, -612, -281, -145, 722, +-3, 898, -98, 137, 168, -513, 865, -416, +785, -66, -355, -40, -1407, -128, -1016, 107, +520, 608, 1568, 690, 1046, -154, -437, -1156, +-1232, -1149, -787, 248, 231, 1617, 696, 1324, +526, -454, 180, -1655, -97, -1092, -283, 405, +-317, 1269, -135, 830, -20, -191, 233, -713, +381, -514, 411, -154, 64, 89, -337, 321, +-613, 537, -348, 303, 265, -339, 680, -686, +636, -272, 192, 296, -514, 395, -884, 142, +-515, -34, 376, -24, 1070, -89, 910, -295, +-167, -237, -1155, 245, -904, 511, 262, 98, +991, -445, 630, -323, -191, 274, -452, 462, +-162, -104, 39, -571, -42, -309, 43, 373, +205, 676, 331, 302, 170, -421, -212, -729, +-534, -337, -151, 229, 558, 518, 564, 594, +-137, 342, -647, -460, -206, -1109, 617, -633, +671, 617, -262, 1138, -860, 492, -224, -335, +742, -590, 762, -497, -226, -319, -744, 46, +-221, 501, 621, 861, 555, 686, -307, -339, +-722, -1573, -92, -1403, 812, 497, 807, 2137, +-143, 1470, -1002, -790, -763, -1980, 344, -926, +1073, 718, 747, 1050, -119, 261, -710, -93, +-728, 183, -191, 45, 358, -807, 756, -1106, +815, 42, 241, 1508, -828, 1470, -1302, -354, +-454, -1776, 966, -1163, 1641, 662, 626, 1366, +-1067, 498, -1416, -562, -207, -633, 949, -22, +788, 330, -72, 50, -377, -331, 92, -184, +356, 331, -190, 544, -711, 183, -252, -466, +765, -715, 1038, -253, 123, 502, -891, 756, +-746, 273, 164, -427, 656, -661, 329, -193, +-92, 371, -93, 377, 91, -102, 89, -252, +-85, 221, -279, 519, -251, -167, 174, -1036, +731, -565, 724, 894, -66, 1414, -1098, 128, +-1027, -1348, 267, -1198, 1419, 353, 1094, 1289, +-204, 657, -1226, -510, -902, -881, 264, -287, +911, 431, 575, 531, 64, 87, -220, -292, +-291, -324, -255, -112, -178, 247, 182, 402, +543, 123, 503, -419, -3, -536, -465, 31, +-473, 607, -92, 474, 483, -174, 595, -596, +118, -409, -371, 231, -327, 548, 105, 196, +360, -238, 112, -153, -219, -44, -128, -177, +243, -190, 385, 269, 149, 625, -316, 189, +-441, -696, -6, -757, 501, 210, 450, 822, +75, 398, -287, -374, -287, -509, -59, -132, +109, 160, 270, 212, 338, 177, 220, 78, +-241, -226, -456, -284, -162, 40, 450, 337, +554, 73, -20, -365, -351, -215, -122, 414, +213, 569, 184, -182, -24, -862, -166, -509, +70, 595, 381, 1135, 218, 279, -273, -959, +-404, -1063, 76, 101, 518, 943, 353, 573, +-174, -214, -365, -360, -112, -152, 252, -257, +335, -286, 223, 257, -39, 894, -441, 508, +-338, -698, 393, -1261, 875, -238, 273, 1108, +-710, 1074, -862, -262, 121, -1108, 1103, -526, +698, 598, -468, 739, -862, -98, -99, -585, +705, -92, 416, 398, -446, 59, -271, -309, +619, 32, 606, 375, -504, -124, -1013, -563, +23, -10, 1181, 781, 837, 447, -562, -628, +-925, -872, -62, -42, 577, 763, 369, 688, +-41, 22, -105, -605, 56, -732, 67, -204, +-30, 509, 35, 862, 13, 448, -64, -447, +108, -1059, 301, -667, 199, 530, -52, 1236, +-281, 646, -243, -701, 154, -1123, 406, -284, +214, 628, 4, 509, 32, 6, -34, 13, +-270, 151, -354, -268, 162, -748, 814, -278, +682, 712, -301, 989, -955, 111, -498, -866, +577, -862, 870, 75, 154, 792, -391, 504, +-70, -310, 265, -515, -49, 127, -465, 491, +-257, -154, 540, -801, 1053, -224, 399, 915, +-774, 945, -1190, -294, -262, -1188, 987, -564, +1102, 591, 140, 794, -557, 72, -378, -333, +-121, -85, -147, 123, 10, -199, 513, -524, +818, -108, 374, 763, -558, 908, -1089, -150, +-500, -1128, 671, -763, 1253, 418, 612, 855, +-452, 255, -857, -189, -352, -17, 163, -3, +228, -605, 413, -707, 633, 265, 344, 1325, +-446, 935, -973, -638, -555, -1601, 588, -776, +1234, 868, 685, 1337, -400, 374, -991, -698, +-542, -669, 332, -79, 683, 174, 460, -47, +116, -6, -155, 477, -349, 608, -304, -155, +-8, -1066, 342, -742, 541, 515, 288, 1124, +-182, 504, -498, -521, -283, -889, 229, -385, +582, 509, 386, 704, -217, 86, -576, -541, +-87, -347, 612, 282, 450, 443, -251, -61, +-519, -469, -53, -230, 546, 256, 521, 484, +-172, 156, -562, -365, -83, -486, 447, 18, +435, 457, -78, 257, -451, -290, -69, -351, +514, 184, 355, 402, -226, 5, -379, -405, +-28, -260, 329, 87, 303, 352, 29, 337, +-37, 12, -10, -388, -124, -445, -134, -53, +118, 338, 331, 425, 279, 198, 46, -155, +-149, -482, -274, -432, -234, 137, 144, 619, +523, 394, 434, -300, 51, -466, -337, 31, +-536, 236, -238, -197, 424, -282, 766, 383, +455, 704, -244, -31, -721, -952, -450, -607, +215, 527, 616, 954, 647, 106, 194, -649, +-576, -398, -735, 242, -11, 235, 627, -188, +610, -109, 87, 329, -376, 358, -342, -233, +-55, -640, 279, -179, 424, 576, 180, 527, +-301, -252, -385, -501, 96, 7, 536, 345, +417, 31, -276, -331, -584, -124, -86, 358, +497, 394, 518, -109, 43, -566, -319, -366, +-258, 340, 41, 694, 120, 103, 181, -571, +203, -376, 226, 252, 14, 344, -393, -114, +-358, -276, 281, 163, 605, 403, 131, -109, +-279, -600, -139, -187, 203, 583, 105, 572, +-274, -305, -101, -782, 424, -95, 404, 720, +-82, 478, -260, -433, -138, -625, 19, -34, +46, 476, 142, 282, 357, -25, 364, -124, +-150, -185, -604, -306, -429, -171, 334, 386, +829, 734, 472, 264, -324, -782, -586, -996, +-227, 19, 143, 1018, 266, 730, 307, -254, +431, -669, 173, -366, -550, 21, -836, 156, +-52, 290, 940, 337, 998, 105, -21, -271, +-986, -447, -718, -274, 258, 95, 737, 415, +519, 444, 52, 155, -378, -277, -417, -568, +-82, -446, 204, 78, 364, 666, 358, 701, +71, 59, -292, -673, -384, -771, -134, -184, +336, 553, 508, 723, 237, 234, -182, -383, +-336, -491, -255, -174, 21, 74, 424, 82, +545, 139, 99, 325, -479, 286, -497, -134, +15, -685, 515, -610, 519, 272, 86, 1033, +-383, 573, -447, -613, -70, -956, 413, -111, +552, 701, 129, 436, -373, -284, -482, -429, +-10, 80, 494, 407, 459, 89, -49, -353, +-384, -319, -162, 134, 119, 317, 157, 142, +94, -75, 202, -114, 205, -57, -181, -83, +-545, -117, -147, 40, 660, 292, 681, 185, +-139, -133, -661, -208, -317, -28, 297, -7, +461, -221, 148, -73, -65, 503, -27, 665, +-46, -153, -243, -1057, -151, -738, 335, 556, +562, 1201, 137, 417, -404, -672, -481, -845, +-13, -170, 454, 413, 388, 375, 25, 73, +-147, -20, -115, 44, -158, -85, -108, -345, +126, -357, 472, 131, 475, 689, -233, 474, +-772, -360, -349, -753, 586, -197, 803, 401, +123, 326, -545, -8, -451, 1, 102, 58, +362, -221, 186, -340, -53, 29, 3, 416, +195, 275, -2, -220, -388, -399, -300, -7, +387, 375, 745, 130, 191, -300, -636, -256, +-558, 151, 165, 367, 500, 40, 269, -304, +-23, -210, -73, 183, -106, 225, -156, -73, +-126, -268, 194, -15, 400, 313, 160, 178, +-188, -156, -251, -260, -33, -132, 97, -9, +81, 184, 58, 374, 199, 230, 226, -297, +-74, -659, -408, -329, -311, 418, 217, 811, +611, 364, 369, -492, -210, -861, -542, -268, +-327, 584, 191, 627, 541, -26, 364, -342, +-140, -78, -439, 39, -190, -197, 266, -197, +316, 242, -29, 450, -257, 107, -20, -276, +356, -342, 338, -157, -277, 110, -641, 311, +-87, 176, 713, -88, 674, -119, -185, 46, +-817, -83, -374, -356, 534, -114, 629, 578, +-43, 612, -425, -278, -82, -775, 278, -182, +114, 400, -276, 151, -111, -73, 348, 297, +304, 373, -155, -419, -284, -1008, -14, -137, +137, 1098, 79, 894, 48, -483, 204, -1076, +69, -243, -312, 661, -353, 496, 182, -232, +571, -350, 312, 83, -381, 303, -630, -9, +-11, -394, 654, -255, 455, 316, -316, 569, +-593, 3, 58, -605, 571, -348, 208, 391, +-367, 460, -340, -137, 73, -419, 447, -30, +404, 341, -181, 158, -571, -193, -289, -264, +297, -15, 601, 180, 389, 172, -273, -7, +-637, -124, -246, -72, 309, 99, 403, -52, +187, -328, 40, 79, -78, 721, -243, 241, +-316, -848, -79, -753, 377, 451, 601, 960, +171, 157, -461, -667, -472, -457, -84, 192, +183, 335, 324, 28, 289, -85, 115, 2, +-71, -1, -332, 2, -501, 4, -93, -123, +598, -150, 679, 164, 198, 346, -468, 28, +-764, -288, -367, -249, 513, -29, 786, 110, +363, 294, -283, 271, -596, -131, -386, -544, +140, -284, 456, 422, 374, 558, 77, -90, +-321, -507, -327, -165, 73, 309, 255, 308, +-25, -89, -139, -439, 114, -234, 308, 402, +164, 674, -378, 37, -501, -815, 128, -678, +599, 321, 197, 919, -284, 457, -198, -451, +161, -749, 179, -234, -271, 348, -411, 345, +282, 142, 797, 84, 259, 0, -622, -330, +-835, -535, -156, -66, 860, 666, 859, 684, +-148, -110, -721, -729, -435, -559, 23, 113, +406, 648, 499, 481, 126, -149, -274, -522, +-440, -325, -181, 102, 277, 373, 442, 286, +87, -76, -242, -326, -177, -266, 17, 110, +64, 431, 65, 130, 75, -360, 39, -264, +-18, 203, -42, 213, -22, -77, 49, -137, +3, 98, -79, 128, 94, -152, 282, -220, +9, 86, -358, 256, -206, 20, 186, -144, +420, -28, 200, 94, -313, -76, -422, -285, +88, -17, 416, 517, 122, 404, -179, -361, +-204, -769, 75, -231, 299, 632, 100, 804, +-443, -41, -267, -819, 404, -568, 571, 326, +-7, 790, -613, 238, -503, -588, 356, -573, +778, 193, 72, 636, -564, 263, -268, -472, +255, -616, 232, 81, 0, 602, -137, 332, +-54, -204, 186, -405, 208, -227, -183, 108, +-353, 234, 38, 160, 405, 104, 308, -47, +-217, -310, -456, -288, -39, 106, 416, 400, +232, 222, -125, -189, -254, -296, -134, -48, +207, 126, 387, 80, -48, 11, -457, -25, +-135, -42, 403, 45, 393, 99, -126, -105, +-507, -274, -163, 36, 494, 418, 476, 145, +-263, -405, -664, -308, -42, 238, 709, 421, +451, -42, -475, -403, -646, -209, 53, 278, +562, 401, 372, 34, -147, -471, -485, -373, +-208, 356, 401, 547, 311, -51, -218, -544, +-267, -269, 193, 345, 444, 522, -73, -8, +-732, -570, -262, -352, 814, 269, 728, 562, +-279, 233, -832, -351, -529, -609, 438, -199, +1039, 553, 292, 688, -803, -75, -750, -769, +114, -432, 791, 400, 479, 613, -426, 96, +-497, -410, 33, -359, 246, 53, 148, 247, +39, 130, -79, 33, 15, 22, -38, -183, +-110, -287, 137, -21, 45, 351, -62, 318, +177, -60, 168, -383, -278, -277, -329, 107, +76, 339, 464, 146, 327, -75, -293, -77, +-470, -97, -83, -230, 378, -107, 365, 394, +-125, 490, -319, -132, 48, -675, 149, -252, +-43, 372, -45, 445, -18, 135, 207, -237, +182, -336, -344, -168, -274, 93, 341, 264, +328, 399, -143, 100, -358, -527, -58, -624, +498, 73, 236, 814, -532, 529, -327, -452, +424, -767, 505, -11, -188, 531, -618, 89, +6, -242, 681, 105, 175, 343, -548, -151, +-325, -552, 295, -221, 493, 549, -6, 657, +-482, -190, -164, -800, 370, -176, 275, 662, +-194, 387, -325, -532, 121, -515, 493, 470, +-120, 762, -583, -329, 47, -1007, 636, -11, +249, 1104, -518, 485, -583, -960, 255, -978, +795, 620, 149, 1352, -577, -8, -490, -1433, +142, -714, 573, 1054, 222, 1259, -312, -324, +-200, -1351, 84, -258, -17, 1024, -97, 604, +21, -704, 317, -710, 323, 521, -293, 921, +-655, -281, -32, -1174, 672, -123, 404, 1191, +-384, 711, -538, -906, 190, -1133, 560, 462, +-49, 1312, -615, 66, -236, -1292, 586, -541, +734, 1045, -148, 1003, -913, -582, -477, -1268, +555, 4, 830, 1205, 54, 625, -625, -860, +-342, -1049, 296, 326, 303, 1222, -179, 302, +-282, -1035, 225, -739, 445, 545, -70, 881, +-392, -58, -253, -674, 89, -121, 346, 456, +234, 113, -49, -431, -161, -173, -246, 422, +-123, 439, 302, -149, 284, -541, -95, -229, +-222, 286, -86, 358, 153, 75, 263, -175, +-41, -90, -347, 119, -192, -27, 206, -366, +437, -178, 233, 552, -284, 706, -538, -43, +-240, -917, 349, -738, 575, 338, 206, 1112, +-256, 571, -501, -615, -323, -994, 251, -159, +616, 783, 187, 629, -424, -400, -399, -691, +195, 221, 458, 822, -134, -6, -550, -961, +-74, -482, 695, 925, 505, 1025, -454, -432, +-843, -1221, -94, -184, 703, 1029, 602, 665, +-208, -586, -779, -936, -140, 184, 695, 1053, +307, 300, -552, -980, -437, -727, 297, 738, +605, 1020, 146, -375, -576, -1080, -451, 114, +242, 1068, 447, 149, 8, -1034, -198, -463, +-19, 1006, 133, 902, -12, -680, -292, -1268, +-156, 146, 231, 1298, 459, 541, 130, -913, +-364, -984, -442, 447, -131, 1062, 244, -36, +475, -1024, 345, -65, -296, 1107, -611, 355, +-263, -1264, 348, -985, 584, 1106, 86, 1756, +-464, -240, -228, -2021, 253, -856, 86, 1569, +-295, 1579, -102, -686, 454, -1658, 444, 110, +-410, 1500, -811, 224, 2, -1448, 870, -608, +493, 1458, -678, 1295, -825, -980, 387, -1930, +949, 191, -159, 2121, -895, 656, -212, -1849, +744, -1228, 595, 1500, -479, 1778, -854, -937, +117, -2360, 843, 48, 97, 2619, -593, 1144, +-202, -1957, 388, -1932, 98, 758, -383, 1842, +-90, 222, 536, -1087, 309, -336, -668, 628, +-768, 48, 390, -656, 1071, -47, 175, 813, +-878, 571, -698, -554, 298, -816, 665, 58, +12, 595, -290, 134, 168, -117, 108, 184, +-527, 73, -453, -398, 348, -487, 855, 332, +228, 927, -835, 78, -699, -1072, 387, -468, +666, 1071, -69, 962, -504, -792, -112, -1511, +449, 160, 289, 1829, -426, 878, -585, -1230, +3, -1619, 531, 84, 396, 1377, -44, 928, +-413, -312, -412, -801, -125, -556, 247, -149, +457, 556, 202, 1039, -362, 401, -439, -1075, +49, -1374, 216, 366, -45, 1855, -213, 738, +64, -1643, 511, -1617, 177, 987, -794, 2184, +-737, 11, 417, -2244, 962, -836, 224, 1861, +-834, 1474, -709, -1287, 453, -1678, 766, 838, +-248, 1912, -831, -303, -164, -2158, 807, -526, +658, 2238, -624, 1667, -1031, -1492, 81, -2423, +832, 256, 213, 2322, -522, 900, -355, -1529, +427, -1341, 451, 970, -555, 1415, -861, -611, +136, -1620, 904, 204, 467, 1841, -411, 771, +-705, -1423, -228, -1484, 67, 555, -138, 1360, +321, 125, 1008, -682, 247, 48, -1306, 542, +-1461, -290, 182, -997, 1701, -75, 1134, 1267, +-913, 883, -1549, -579, -95, -1026, 963, -254, +211, 534, -771, 346, -187, -140, 919, 126, +732, 636, -922, 47, -1641, -1058, -161, -1020, +1550, 626, 1248, 1713, -507, 684, -1464, -1211, +-819, -1324, 577, 114, 1022, 991, 303, 524, +-597, -331, -723, -234, -140, 186, 489, 51, +452, -294, -189, -191, -633, 278, -367, 322, +306, 42, 615, -208, 197, 154, -501, 223, +-763, -355, -268, -666, 498, -24, 792, 1099, +161, 1079, -750, -429, -898, -1713, -17, -819, +782, 1093, 466, 1630, -329, 296, -546, -1143, +-154, -918, 104, 231, -68, 585, -43, 51, +376, -69, 283, 417, -632, 507, -931, -516, +84, -1280, 1177, -299, 669, 1483, -1070, 1410, +-1402, -459, 168, -1693, 1416, -721, 614, 1068, +-1135, 1202, -1236, -60, 503, -879, 1276, -318, +-207, 334, -1294, 354, -401, 101, 1108, -150, +895, -225, -890, -223, -1477, 339, 14, 757, +1344, 170, 732, -1004, -801, -1025, -1305, 583, +-95, 1670, 902, 664, 398, -1321, -395, -1553, +-423, 183, -44, 1529, 88, 962, -293, -621, +-178, -1225, 389, -271, 338, 958, -344, 851, +-584, -356, -310, -1060, 246, -348, 385, 932, +90, 1274, -82, 73, -361, -1526, -624, -1536, +-305, 452, 570, 2363, 896, 1601, -37, -1134, +-1193, -2774, -892, -1204, 455, 1867, 949, 2838, +282, 453, -650, -2334, -703, -2064, -26, 602, +268, 2233, -39, 837, 49, -1413, 257, -1322, +-229, 741, -823, 1557, -369, -53, 811, -1584, +972, -849, -510, 1216, -1723, 1648, -625, -118, +1465, -1489, 1711, -798, -480, 766, -2423, 989, +-1345, -186, 1424, -746, 2437, 260, 319, 1051, +-2289, -60, -2200, -1454, 524, -977, 2380, 1108, +1184, 2179, -1363, 539, -2217, -1840, -311, -2188, +1595, 32, 1056, 2186, -747, 1967, -1113, -397, +-8, -2150, 666, -1323, -179, 669, -975, 1693, +-115, 725, 1320, -601, 861, -744, -1174, -20, +-2128, -6, -523, -337, 1941, 31, 1999, 906, +-346, 1155, -2227, -169, -1758, -1857, 303, -1505, +1850, 919, 1406, 2483, -343, 1225, -1732, -1456, +-1569, -2574, 199, -443, 1653, 2201, 1058, 1942, +-892, -811, -1607, -2324, -185, -487, 1335, 2208, +559, 1917, -1346, -1539, -1460, -3229, 743, -273, +2133, 3699, 350, 2969, -2253, -2014, -1969, -4550, +834, -1043, 2266, 3814, 467, 3451, -1698, -1321, +-1186, -3730, 763, -776, 866, 2827, -860, 1788, +-1192, -1874, 712, -2289, 1755, 1075, -116, 2935, +-2146, 466, -1404, -2730, 1145, -2257, 1996, 1109, +53, 2971, -1911, 1209, -1073, -1646, 1023, -2300, +1211, -403, -529, 1581, -1522, 1680, -409, 64, +1213, -1399, 1187, -1191, -425, 400, -1651, 1613, +-1199, 730, 567, -1321, 1576, -1668, 772, 459, +-637, 2345, -1529, 1095, -1107, -1824, 400, -2587, +1348, 138, 728, 2828, -345, 2040, -1219, -1204, +-1027, -2881, 177, -1132, 958, 1800, 572, 2503, +-290, 509, -870, -1835, -463, -1974, 272, -126, +104, 1695, -264, 1850, 116, 100, 540, -1842, +0, -1824, -1184, 414, -1317, 2164, 633, 1471, +2316, -796, 748, -2093, -2393, -1029, -2868, 965, +465, 1906, 3548, 1114, 1956, -763, -2508, -2150, +-3897, -1426, -323, 1061, 3559, 2737, 2714, 1552, +-1720, -1559, -3896, -3227, -1169, -1162, 2857, 2363, +2967, 3226, -758, 438, -3373, -2634, -1843, -2563, +1685, 133, 2912, 2390, 605, 2007, -2496, -222, +-2500, -1962, 249, -1597, 2463, 231, 1604, 1764, +-1223, 1566, -2492, -333, -797, -1983, 1778, -1255, +1701, 1050, -586, 2182, -2041, 483, -813, -1775, +1377, -1727, 1465, 621, -691, 2006, -1984, 793, +-393, -1204, 1645, -1402, 1189, 215, -1083, 1099, +-2087, 205, -242, -587, 1932, 101, 1462, 1063, +-1195, -9, -2385, -1804, -530, -1455, 1787, 1591, +1697, 3312, -497, 715, -1965, -3367, -1161, -3504, +717, 998, 1394, 4333, 554, 2285, -840, -2235, +-1272, -3672, -444, -661, 653, 2314, 899, 2231, +64, -63, -888, -1367, -809, -1050, 181, -102, +702, 494, 272, 759, -558, 628, -824, -118, +-76, -938, 697, -770, 445, 315, -329, 1150, +-847, 567, -654, -574, 307, -846, 990, -110, +471, 349, -664, 339, -1348, 270, -727, 312, +1004, -30, 1520, -830, 110, -1004, -1580, 256, +-1496, 1722, 330, 1351, 1643, -710, 714, -2303, +-942, -1299, -1348, 1271, -360, 2535, 740, 951, +855, -1466, -9, -2160, -588, -539, -760, 1357, +-581, 1515, 249, 238, 1189, -791, 883, -594, +-788, -54, -2161, -72, -1195, -222, 1646, 355, +2793, 1050, 326, 625, -2914, -770, -2725, -1564, +820, -607, 3143, 1162, 1322, 1595, -1948, 376, +-2363, -1001, 163, -1176, 1841, -308, 325, 576, +-1563, 791, -631, 539, 1590, 26, 1443, -525, +-1409, -850, -3108, -384, -681, 459, 3275, 1056, +3334, 706, -1133, -290, -4570, -1003, -2782, -980, +2398, -139, 4808, 1022, 1520, 1746, -3626, 694, +-4549, -1543, -204, -2449, 4058, -638, 3256, 2124, +-1431, 2613, -3890, 441, -1434, -2041, 2272, -2263, +2375, -514, -817, 1305, -2394, 1862, -78, 1283, +2140, -108, 812, -1810, -2197, -2358, -2442, -728, +850, 1990, 3410, 3149, 1596, 1433, -2406, -1858, +-3723, -3626, -872, -2039, 2864, 1616, 3269, 3938, +210, 2518, -2872, -1350, -3030, -3868, -84, -2518, +2586, 1080, 2188, 3369, -220, 2329, -1960, -687, +-1671, -2555, 35, -1882, 1131, 341, 780, 1734, +131, 1362, -171, -98, -708, -1011, -961, -767, +-213, 175, 983, 763, 1137, 138, -454, -807, +-1806, -677, -640, 808, 1788, 1818, 1861, 630, +-1191, -1908, -3251, -2699, -986, -394, 3006, 2789, +3529, 3256, -604, 287, -4388, -3199, -3073, -3402, +1831, -281, 4359, 3055, 1948, 3461, -2292, 587, +-3740, -2727, -1418, -3385, 1751, -797, 2738, 2506, +1275, 3235, -1045, 636, -2318, -2446, -1689, -2588, +250, 58, 2079, 2270, 2092, 1610, -123, -905, +-2369, -1837, -2321, -373, -109, 1446, 2408, 1277, +2563, -311, -130, -1410, -2828, -1107, -2843, 135, +113, 1326, 3324, 1843, 3042, 613, -959, -1802, +-3951, -2907, -2683, -970, 1464, 2493, 3927, 3610, +1874, 947, -2144, -2771, -3209, -3464, -1083, -721, +1544, 2264, 2188, 2712, 667, 779, -975, -1072, +-1414, -1495, -858, -1164, 137, -577, 1039, 521, +971, 1976, -9, 2003, -1137, -57, -1111, -2604, +255, -2716, 1182, 104, 419, 2832, -714, 2589, +-955, -272, -135, -2517, 773, -1856, 685, 572, +-115, 1894, -719, 796, -819, -835, -347, -1094, +583, 232, 1124, 1204, 648, 460, -648, -1051, +-1630, -1379, -1012, -112, 475, 1304, 1462, 1472, +1331, 467, 10, -956, -1450, -1684, -1869, -1248, +-861, 359, 1051, 1898, 2361, 2161, 1598, 701, +-870, -1909, -2829, -3385, -2552, -1687, 495, 2214, +3299, 4338, 2885, 2063, -586, -2336, -3498, -4349, +-2928, -1917, 725, 1930, 3027, 3422, 2087, 1782, +-719, -842, -2162, -2094, -1216, -1795, 311, -491, +565, 1028, 339, 1909, 711, 1432, 601, -179, +-408, -1615, -1708, -1943, -1449, -600, 785, 1151, +2308, 2062, 1188, 1464, -1212, -401, -2270, -2204, +-1014, -2328, 1101, -108, 1813, 2541, 846, 3057, +-746, 185, -1655, -3205, -1233, -3041, 403, 614, +1659, 3350, 1362, 1869, -417, -1333, -1794, -2144, +-1251, -216, 285, 869, 1208, 12, 1003, -519, +124, 886, -681, 1816, -952, -135, -895, -2886, +-92, -2250, 1079, 1686, 1514, 3833, 312, 1307, +-1350, -2774, -1823, -3099, -373, 161, 1363, 2419, +1365, 1277, -205, -874, -1004, -821, -155, 676, +625, 622, -264, -1269, -1535, -1856, -851, 377, +1837, 2725, 3083, 2263, 399, -1090, -3742, -3398, +-3993, -2144, 568, 1336, 4705, 3217, 3676, 1932, +-1500, -968, -4655, -2561, -2590, -1651, 1589, 292, +3164, 1611, 1380, 1487, -836, 389, -1245, -678, +-765, -1035, -806, -917, -474, -385, 894, 532, +2069, 1375, 1262, 1417, -1322, -55, -3035, -1864, +-1285, -2127, 1811, 21, 2740, 2298, 627, 2153, +-1864, -501, -1961, -2275, 141, -1054, 1433, 1027, +529, 1143, -835, -339, -702, -780, 677, 455, +1142, 1232, -196, -65, -1579, -1745, -1304, -1175, +561, 1087, 2050, 2040, 1390, 454, -903, -1580, +-2319, -1339, -1371, 514, 922, 1344, 2145, 9, +923, -1149, -945, -394, -1346, 1232, -437, 1298, +215, -562, 280, -2056, 151, -1075, 471, 1271, +635, 2229, -215, 732, -1223, -1316, -1120, -1911, +341, -519, 1355, 1000, 912, 1242, -335, 339, +-889, -401, -537, -218, -340, -41, 8, -549, +466, -951, 953, 14, 545, 1531, -654, 1774, +-1440, 27, -685, -2089, 749, -2124, 1240, -122, +311, 1810, -648, 2138, -538, 926, 3, -1056, +42, -2372, -227, -1934, -241, 467, 403, 2795, +791, 2506, 206, -409, -716, -2731, -1063, -2140, +-352, 373, 938, 1996, 1032, 1265, -99, -159, +-935, -622, -590, -505, 514, -401, 849, -281, +-297, 161, -1311, 549, -439, 531, 1271, 99, +1609, -89, -41, -103, -1844, -594, -1714, -857, +187, -243, 1623, 1150, 1488, 1676, 363, 473, +-933, -1445, -1712, -1938, -1304, -527, 317, 1181, +1846, 1627, 1956, 647, 172, -418, -1929, -850, +-2094, -894, -468, -646, 1303, 113, 1649, 1135, +853, 1522, -276, 588, -1114, -1153, -1496, -2116, +-742, -1134, 776, 1060, 1771, 2316, 1357, 1419, +-466, -815, -2030, -2110, -1484, -1407, 424, 521, +1662, 1606, 1191, 1106, -321, -3, -1385, -832, +-809, -1058, 466, -557, 988, 536, 380, 1252, +-730, 610, -1010, -675, 8, -1182, 1246, -189, +956, 790, -479, 817, -1389, -38, -1024, -778, +398, -662, 1486, 74, 1056, 801, -258, 801, +-1099, 62, -1210, -939, -296, -1179, 789, -117, +1166, 1251, 692, 1459, -282, -7, -1121, -1423, +-1068, -1358, -35, 12, 942, 1344, 1009, 1318, +179, 20, -723, -1256, -685, -1165, -34, -20, +325, 1152, 10, 1109, -145, -104, 115, -1220, +518, -931, 301, 494, -484, 1316, -764, 398, +-261, -983, 336, -846, 487, 381, 335, 785, +171, -33, 54, -531, -491, 83, -1056, 579, +-662, -112, 866, -916, 1803, -325, 975, 959, +-1088, 1084, -2274, -304, -1161, -1326, 1218, -669, +2290, 712, 1020, 1096, -1071, 249, -1937, -591, +-850, -682, 877, -189, 1351, 238, 300, 494, +-549, 445, -291, 26, 135, -616, -219, -826, +-682, -27, -163, 1134, 1074, 1080, 1244, -502, +-427, -1689, -1670, -728, -894, 1283, 1013, 1701, +1595, -131, 117, -1676, -1381, -990, -859, 956, +675, 1358, 1079, -116, -15, -1271, -978, -343, +-430, 1000, 680, 771, 658, -690, -329, -1218, +-610, 76, -34, 1357, 575, 663, 271, -935, +-538, -1041, -532, 263, 379, 959, 708, 182, +144, -813, -600, -467, -617, 703, 101, 826, +576, -249, 344, -1007, -56, -548, -245, 470, +-296, 917, -190, 454, 75, -356, 327, -658, +392, -488, 54, -59, -366, 369, -506, 637, +-26, 466, 394, -152, 363, -667, 68, -740, +-176, -171, -314, 523, -183, 869, 107, 545, +335, -216, 202, -900, -189, -936, -327, -138, +30, 855, 374, 1173, 193, 436, -393, -760, +-399, -1197, 51, -560, 572, 505, 504, 940, +-149, 569, -701, -217, -535, -563, 132, -334, +731, -79, 640, -177, -90, 15, -623, 688, +-523, 905, 44, -166, 274, -1307, 149, -979, +233, 532, 555, 1316, 144, 484, -804, -690, +-1153, -718, -218, 103, 1214, 361, 1533, -169, +229, -327, -1297, 241, -1325, 702, -342, 112, +740, -689, 1114, -727, 765, 134, -17, 774, +-784, 488, -1244, -347, -625, -738, 775, -176, +1506, 620, 737, 626, -635, -305, -1093, -967, +-447, -420, 221, 815, 228, 1243, 118, 68, +534, -1354, 842, -1227, -26, 409, -1339, 1466, +-1303, 821, 249, -652, 1600, -1187, 1267, -408, +-308, 556, -1219, 711, -707, 172, 164, -358, +307, -447, 174, -61, 417, 381, 638, 294, +101, -276, -952, -586, -1185, -34, 83, 690, +1372, 576, 1023, -330, -447, -922, -1084, -407, +-189, 557, 672, 824, 282, 99, -575, -565, +-398, -503, 631, 62, 911, 355, -41, 178, +-925, -132, -643, -184, 263, -13, 635, 113, +252, 88, 65, -51, 110, -150, -19, -111, +-548, 41, -630, 94, 147, 9, 1001, 44, +815, 208, -199, 71, -1038, -434, -708, -711, +341, -66, 956, 969, 500, 1114, -421, -176, +-732, -1492, -76, -1178, 668, 466, 507, 1466, +-264, 765, -738, -476, -177, -779, 643, -348, +629, -150, 24, -259, -398, 219, -304, 1032, +-29, 1000, -24, -411, -11, -1778, 413, -1387, +693, 663, 201, 2086, -662, 1139, -981, -914, +-332, -1625, 790, -587, 1288, 570, 537, 609, +-638, 157, -1108, 114, -602, 316, 454, -100, +960, -839, 520, -845, -174, 144, -316, 1121, +-94, 897, -77, -236, -348, -964, -333, -636, +430, 27, 1185, 332, 790, 406, -653, 386, +-1506, 152, -816, -407, 709, -759, 1547, -427, +850, 441, -332, 866, -949, 309, -783, -486, +-176, -637, 474, -107, 829, 221, 752, 140, +123, 48, -732, 202, -944, 89, -264, -443, +614, -505, 987, 163, 570, 739, -311, 271, +-810, -670, -388, -806, 431, 173, 638, 1030, +42, 539, -479, -791, -116, -1208, 695, -70, +643, 1247, -452, 889, -1076, -603, -281, -1308, +986, -277, 1007, 973, 10, 774, -609, -409, +-219, -870, 170, -115, -184, 625, -464, 382, +409, -419, 1419, -568, 875, 179, -1006, 557, +-1999, 41, -643, -567, 1501, -324, 2092, 344, +555, 526, -1277, -10, -1615, -594, -313, -474, +993, 190, 1206, 620, 469, 355, -406, -327, +-693, -635, -238, -350, 280, 298, 322, 581, +151, 250, 0, -335, 152, -504, 296, -162, +-42, 187, -424, 250, -222, 113, 275, 3, +563, -157, 356, -322, -152, -167, -325, 279, +11, 423, 263, -72, 116, -555, -35, -284, +-65, 379, 203, 462, 439, -120, 182, -449, +-299, -190, -417, 188, -175, 133, 353, -94, +815, 31, 512, 261, -289, -10, -649, -603, +-375, -480, 190, 392, 697, 866, 646, 231, +150, -747, -281, -759, -535, 30, -326, 651, +221, 339, 687, -218, 560, -328, 62, 11, +-429, 149, -354, -139, 76, -334, 299, -44, +258, 406, 161, 414, 219, -58, 260, -502, +-17, -605, -440, -158, -402, 523, 209, 829, +911, 260, 857, -704, -249, -1089, -1063, -315, +-575, 840, 647, 1076, 1198, 94, 410, -904, +-756, -888, -687, 12, 446, 671, 918, 479, +211, -87, -654, -259, -418, -203, 489, -290, +873, -302, 223, 254, -426, 777, -461, 378, +-52, -731, 419, -1122, 541, -93, 356, 1165, +-122, 921, -456, -616, -127, -1332, 566, -273, +513, 1076, -194, 866, -468, -572, 280, -1166, +994, -102, 374, 966, -1018, 542, -935, -537, +729, -677, 1513, 70, 348, 368, -1081, -104, +-815, -342, 787, 363, 1199, 769, -262, -185, +-1157, -1392, 52, -914, 1508, 1013, 1025, 1852, +-849, 396, -1548, -1653, -18, -1704, 1523, 143, +1077, 1506, -454, 1002, -852, -349, 73, -897, +663, -479, 95, 52, -562, 172, -103, 70, +960, 232, 1111, 354, -105, 41, -1221, -547, +-898, -656, 510, -96, 1511, 504, 1023, 624, +-309, 84, -1015, -469, -550, -520, 268, -12, +609, 337, 499, 57, 299, -345, 236, -150, +-54, 549, -511, 548, -532, -334, 232, -1037, +921, -587, 876, 455, 87, 1030, -503, 681, +-438, -271, -129, -1069, 184, -1037, 460, -68, +677, 1066, 553, 1235, -81, 164, -795, -1133, +-718, -1232, 239, -112, 1090, 862, 998, 695, +93, -33, -645, -255, -657, -135, -13, -247, +512, -543, 723, -209, 485, 614, -4, 915, +-426, 115, -315, -930, 125, -912, 421, 63, +381, 781, 143, 471, 58, -205, 5, -367, +8, -154, -33, -76, 108, -147, 365, 98, +372, 406, 1, 166, -260, -451, 84, -574, +523, 173, 385, 717, -313, 200, -522, -778, +177, -715, 927, 445, 602, 1012, -427, 114, +-700, -1048, 68, -777, 768, 604, 457, 1080, +-199, -75, -222, -1233, 413, -503, 521, 1017, +-122, 1080, -650, -574, -47, -1537, 929, -393, +834, 1319, -199, 1226, -730, -505, -297, -1451, +523, -514, 674, 814, 129, 836, -231, -100, +73, -600, 321, -259, 142, 203, -124, 121, +-105, -160, 200, -154, 465, 127, 365, 268, +109, 52, -178, -321, -375, -425, -117, -36, +483, 369, 712, 338, 315, 0, -204, -317, +-412, -356, -123, -172, 228, 151, 382, 334, +473, 279, 412, -19, -55, -443, -465, -534, +-329, -125, 214, 525, 696, 640, 588, 60, +62, -685, -325, -653, -349, 82, -171, 578, +326, 247, 708, -210, 655, -192, -36, 114, +-748, -21, -534, -426, 466, -351, 995, 408, +600, 805, -239, 134, -716, -781, -268, -774, +428, 61, 659, 651, 472, 416, 36, -114, +-455, -324, -473, -166, 91, -145, 749, -162, +836, 74, 78, 414, -668, 274, -598, -241, +225, -512, 862, -186, 747, 255, -18, 272, +-588, -87, -462, -204, 116, 4, 757, 199, +647, 57, -66, -276, -514, -402, -227, -56, +319, 437, 594, 461, 162, -36, -273, -507, +2, -461, 339, -38, 243, 285, -95, 311, +-111, 207, 240, 7, 393, -365, -20, -615, +-224, -195, 134, 600, 407, 715, 198, -92, +-341, -796, -248, -453, 521, 429, 739, 638, +-105, -144, -645, -788, -159, -268, 703, 724, +724, 789, -167, -323, -541, -1076, 34, -492, +429, 586, 199, 750, -50, 151, 144, -275, +338, -301, -14, -363, -528, -383, -125, 90, +732, 780, 780, 705, -40, -308, -664, -1070, +-392, -585, 402, 464, 604, 797, 243, 135, +67, -438, 75, -228, -174, 213, -466, 57, +-165, -449, 706, -388, 1044, 309, 219, 805, +-879, 327, -904, -619, 171, -908, 1091, -262, +821, 583, -126, 683, -591, 193, -355, -350, +156, -459, 345, -287, 318, -54, 285, 254, +185, 430, -209, 262, -369, -306, -134, -581, +338, -250, 589, 327, 336, 479, -164, 78, +-390, -372, -195, -428, 239, 45, 545, 447, +328, 278, -83, -296, -239, -536, -155, -101, +124, 399, 361, 351, 267, -84, -25, -242, +-70, -106, -80, -98, -60, -179, 155, -27, +376, 425, 362, 486, -114, -112, -520, -785, +-197, -567, 562, 301, 779, 737, 111, 356, +-620, -298, -495, -483, 294, -249, 636, 71, +305, 118, -143, 83, -151, 184, 37, 175, +-65, -105, -147, -431, 227, -376, 666, 65, +375, 478, -390, 418, -742, -46, -97, -442, +732, -502, 707, -105, 26, 444, -401, 558, +-250, 20, 11, -604, 70, -541, 133, 212, +483, 692, 532, 239, -167, -585, -828, -630, +-523, 134, 604, 752, 1154, 340, 370, -529, +-711, -698, -680, 56, 91, 635, 516, 260, +325, -442, 21, -406, 64, 243, 133, 474, +-194, -108, -376, -608, 28, -268, 528, 446, +489, 573, -30, 23, -414, -455, -192, -471, +197, -90, 258, 272, 67, 392, 35, 232, +173, -100, 154, -415, -165, -436, -294, -23, +1, 459, 371, 465, 387, -55, 31, -463, +-260, -286, -164, 105, 85, 220, 195, 26, +117, -112, 4, -13, 78, 157, 226, 61, +17, -184, -230, -297, -177, -89, 123, 241, +417, 341, 321, 75, -109, -263, -301, -312, +-164, -90, 24, 105, 264, 158, 363, 152, +202, 90, -156, -116, -373, -308, -205, -196, +282, 141, 539, 305, 247, 40, -270, -147, +-403, -22, -33, 25, 361, -193, 296, -216, +28, 157, -182, 393, -154, 120, 70, -329, +247, -343, 161, 37, -90, 213, -196, 82, +15, -52, 416, 33, 254, 84, -346, -129, +-494, -357, 163, -134, 821, 410, 436, 559, +-641, -57, -905, -745, 153, -564, 1053, 351, +614, 825, -588, 345, -910, -505, 106, -765, +841, -168, 279, 495, -482, 471, -246, 55, +338, -144, 390, -236, -183, -447, -417, -264, +-3, 523, 428, 899, 300, 44, -76, -1028, +-249, -776, -137, 460, 71, 981, 124, 221, +182, -596, 141, -526, -43, 8, -211, 344, +-57, 276, 189, -62, 310, -264, -47, -92, +-385, 90, -63, 23, 468, -35, 407, 63, +-224, 150, -559, -17, -218, -270, 387, -244, +545, 138, 205, 401, -245, 190, -381, -262, +-167, -408, 27, -113, 263, 186, 419, 243, +250, 193, -192, 67, -408, -234, -318, -486, +-37, -205, 400, 351, 667, 601, 311, 223, +-499, -396, -844, -709, -245, -250, 631, 594, +780, 637, 166, -133, -508, -612, -419, -141, +92, 401, 121, 133, -84, -361, 192, -226, +504, 367, 177, 337, -507, -114, -765, -298, +-21, -196, 927, -78, 788, 140, -445, 479, +-1034, 146, -176, -497, 809, -447, 616, 265, +-243, 483, -662, -54, -266, -443, 519, -214, +586, 394, -90, 506, -465, -29, -263, -634, +-3, -644, 307, 135, 467, 994, 98, 799, +-367, -527, -446, -1301, -133, -515, 347, 802, +534, 1075, 174, 202, -353, -665, -402, -775, +-110, -123, 173, 494, 236, 443, 275, -10, +135, -177, -181, -70, -476, -136, -367, -242, +269, -33, 827, 464, 412, 458, -574, -326, +-841, -756, -164, -139, 701, 700, 678, 588, +-109, -293, -552, -797, -286, -314, 126, 567, +227, 716, 139, 45, 35, -633, 24, -528, +-136, 66, -280, 377, -53, 424, 394, 220, +307, -282, -255, -632, -443, -342, 28, 335, +522, 679, 194, 427, -493, -426, -447, -853, +325, -238, 670, 662, 75, 707, -674, -191, +-492, -756, 282, -242, 691, 570, 302, 454, +-499, -274, -632, -534, -3, -149, 517, 402, +425, 499, -128, 25, -530, -506, -154, -498, +337, 69, 166, 581, -143, 464, -74, -241, +82, -588, 53, -196, -36, 253, -178, 299, +-122, 110, 152, -61, 312, -162, 76, -199, +-310, -110, -392, 225, 47, 394, 460, -80, +266, -456, -308, -167, -393, 323, 114, 293, +335, -49, -50, -311, -325, -196, -85, 137, +332, 298, 345, 131, -250, -202, -552, -295, +-83, -39, 366, 175, 303, 214, 121, 127, +-186, -151, -503, -385, -228, -122, 393, 344, +463, 356, -15, -57, -365, -429, -272, -218, +130, 256, 282, 281, -143, -47, -284, -215, +249, -75, 326, 135, -131, 158, -437, -123, +-299, -275, 239, 20, 633, 312, 189, 277, +-633, -170, -610, -552, 212, -236, 710, 527, +164, 604, -556, -167, -352, -666, 219, -221, +278, 406, -84, 359, -134, -177, -34, -254, +84, 104, 5, 219, -146, -110, -151, -379, +104, -46, 397, 450, 13, 408, -546, -245, +-380, -685, 262, -206, 542, 620, 322, 591, +-375, -294, -838, -578, -240, -71, 632, 184, +760, 199, 18, 241, -751, 88, -677, -439, +111, -551, 648, 93, 508, 787, -96, 592, +-757, -472, -463, -1037, 356, -370, 517, 821, +101, 1016, -309, -48, -311, -926, 90, -641, +106, 290, -201, 627, 57, 236, 227, -273, +17, -122, -79, 145, -315, -187, -357, -534, +322, 0, 610, 872, -32, 613, -534, -508, +-483, -1027, 134, -283, 581, 644, 198, 714, +-398, 60, -354, -451, 16, -223, 288, -51, +58, -236, -313, -11, 36, 671, 209, 588, +-164, -462, -140, -989, 62, -275, -16, 821, +77, 800, -77, -242, -300, -882, 170, -249, +395, 729, -120, 466, -583, -595, -267, -570, +499, 470, 529, 649, -321, -224, -528, -621, +-47, -92, 242, 500, 249, 287, -277, -310, +-409, -432, 423, 152, 494, 538, -470, 83, +-570, -697, -25, -349, 336, 740, 459, 584, +-61, -631, -504, -745, -47, 422, 44, 821, +-265, -116, 77, -885, 456, -241, 216, 825, +-312, 544, -615, -583, -195, -703, 434, 269, +324, 731, 13, -46, -245, -754, -209, -171, +112, 877, -98, 474, -365, -923, 209, -878, +567, 665, 6, 1203, -466, -172, -446, -1283, +101, -385, 438, 1160, -29, 890, -322, -955, +136, -1297, 262, 530, -148, 1583, -423, 90, +-367, -1583, 287, -679, 676, 1267, 71, 1045, +-493, -843, -467, -1185, -91, 402, 336, 1256, +317, 155, -95, -1241, -91, -724, -128, 843, +-248, 1082, -49, -175, 228, -1013, 232, -297, +-133, 713, -398, 399, -33, -693, 375, -373, +25, 856, -245, 700, -198, -756, -54, -1237, +211, 178, 170, 1428, -176, 537, -97, -1125, +48, -937, -141, 669, -144, 1067, -36, -249, +168, -1281, 390, -220, -13, 1355, -540, 933, +-402, -903, 122, -1515, 355, -29, 363, 1438, +44, 853, -387, -818, -536, -1012, -173, 220, +386, 665, 569, 64, 129, -461, -571, -61, +-627, 464, 79, 138, 709, -463, 262, -322, +-543, 368, -590, 368, 277, -112, 669, -425, +-82, -51, -642, 452, -180, 258, 412, -294, +267, -528, -285, -58, -419, 542, 262, 492, +546, -181, -268, -653, -726, -257, -158, 385, +549, 492, 622, -56, -128, -395, -844, -63, +-363, 210, 600, 108, 406, -199, -399, -203, +-389, 170, 410, 456, 547, 103, -471, -645, +-907, -564, 5, 474, 916, 1024, 649, 15, +-478, -1113, -981, -591, -205, 746, 707, 929, +370, -199, -270, -796, -297, -111, 53, 475, +151, 22, -131, -421, -357, 41, 113, 767, +606, 457, -103, -908, -676, -1448, -153, 299, +588, 2032, 353, 915, -352, -1600, -612, -1794, +-64, 552, 619, 1792, 436, 243, -395, -1356, +-642, -476, 144, 1154, 406, 700, -89, -1052, +-266, -1320, 30, 540, 295, 1793, 110, 520, +-384, -1504, -471, -1451, 213, 682, 444, 1688, +-22, 84, -166, -1643, 87, -490, 34, 1671, +-360, 1049, -405, -1465, 160, -2005, 847, 606, +406, 2566, -650, 911, -878, -2132, -13, -2095, +629, 1052, 220, 2251, -209, 13, 45, -1959, +333, -407, -316, 1743, -919, 772, -361, -1720, +1065, -1529, 1267, 1471, -461, 2331, -1512, -503, +-460, -2789, 944, -675, 719, 2590, -290, 1712, +-601, -1850, 195, -2464, 543, 841, -343, 2762, +-767, 405, 116, -2423, 926, -1463, 231, 1589, +-800, 1742, -542, -663, 613, -1321, 570, 325, +-520, 843, -754, -449, 112, -850, 986, 440, +449, 1176, -914, -12, -928, -1232, 527, -410, +729, 865, -170, 512, -312, -645, 78, -374, +288, 840, -144, 568, -604, -1046, -69, -1180, +763, 807, 345, 1678, -503, 44, -509, -1639, +31, -993, 554, 1183, 122, 1535, -637, -474, +-307, -1633, 549, -171, 487, 1286, -82, 698, +-613, -615, -633, -866, 288, 75, 799, 432, +254, 95, -286, 107, -452, 464, -309, -215, +152, -1190, 331, -443, 183, 1417, 8, 1507, +-183, -818, -26, -2103, -78, -285, -341, 1843, +-59, 1268, 543, -1027, 388, -1605, -251, 183, +-650, 1523, -377, 210, 527, -1248, 634, -340, +-220, 1234, -610, 511, -86, -1353, 466, -1023, +369, 1333, -278, 1730, -642, -690, 41, -2177, +661, -424, 254, 1831, -436, 1441, -388, -750, +192, -1631, 335, -245, -146, 1027, -449, 509, +89, -465, 557, -173, 146, 537, -572, 146, +-434, -853, 195, -653, 400, 638, 1, 1097, +-245, 9, 177, -761, 359, -253, -326, 303, +-913, -187, -87, -497, 1152, 354, 1011, 1271, +-577, 493, -1543, -1357, -435, -1575, 1141, 258, +1001, 1716, -404, 966, -900, -737, -89, -1232, +644, -62, 197, 771, -795, 137, -534, -621, +738, -175, 1077, 947, -199, 868, -1128, -678, +-802, -1682, 438, -409, 1221, 1467, 542, 1441, +-654, -246, -1042, -1413, -167, -686, 634, 578, +783, 685, -26, -9, -769, -128, -445, 88, +342, 17, 498, -354, 25, -322, -239, 346, +-296, 624, -214, -135, 43, -681, 389, -51, +514, 774, -237, 351, -861, -837, -335, -880, +641, 614, 737, 1346, -79, 149, -656, -1285, +-243, -920, 403, 667, 118, 1243, -344, 3, +79, -1038, 473, -296, 103, 837, -634, 414, +-559, -825, 415, -803, 895, 804, -120, 1337, +-1046, -153, -344, -1535, 924, -738, 774, 1023, +-774, 1182, -1029, -197, 319, -856, 1127, -26, +84, 219, -911, -293, -448, -224, 707, 689, +780, 896, -589, -345, -1063, -1530, 276, -579, +1291, 1452, 147, 1489, -1048, -619, -693, -1728, +377, -460, 729, 1335, 132, 1191, -401, -460, +-274, -1251, 19, -416, -34, 706, -64, 819, +160, 202, 349, -518, -42, -769, -518, -312, +-93, 757, 465, 1044, 163, -105, -483, -1306, +-264, -758, 633, 1019, 790, 1580, -606, -185, +-1553, -2008, -78, -1022, 1752, 1647, 1164, 2257, +-1127, -340, -1895, -2658, -250, -1374, 1579, 1809, +1119, 2576, -598, -83, -1161, -2487, -150, -1594, +578, 1386, 160, 2391, -200, 138, 188, -2098, +328, -1403, -268, 1005, -573, 2015, -36, 468, +695, -1636, 438, -1557, -701, 428, -916, 1681, +509, 803, 1351, -668, 124, -1175, -1481, -450, +-1390, 502, 593, 801, 2077, 376, 968, -238, +-1373, -438, -2036, -325, -560, -151, 1392, 8, +1962, 567, 437, 922, -1507, 61, -1805, -1284, +-232, -1414, 1534, 353, 1634, 2219, -27, 1580, +-1629, -1458, -1301, -3012, 511, -551, 1444, 2673, +622, 2441, -702, -735, -1058, -2691, -326, -1190, +613, 1318, 674, 1729, -80, 201, -316, -871, +-130, -573, -69, 109, -274, 21, -171, -285, +394, 156, 853, 874, 381, 555, -965, -575, +-1364, -1311, -120, -478, 1553, 1019, 1375, 1248, +-459, 107, -1716, -1036, -738, -857, 903, 202, +1072, 1058, -308, 281, -891, -847, 226, -536, +890, 570, -99, 959, -1360, -13, -673, -990, +1181, -888, 1546, 394, -304, 1132, -1671, 562, +-483, -377, 1152, -715, 836, -359, -907, -130, +-1069, 190, 811, 561, 1828, 696, -152, 235, +-2455, -754, -1334, -1264, 1823, -454, 2585, 1192, +-226, 1483, -2656, 175, -1424, -1210, 1537, -1207, +2146, 17, -129, 1011, -2176, 885, -1151, -201, +1525, -1008, 2010, -446, -90, 946, -2090, 987, +-1435, -734, 857, -1554, 2087, -316, 833, 1765, +-1151, 1853, -1562, -528, -377, -2671, 874, -1509, +882, 1615, 144, 2824, -289, 619, -314, -2295, +-454, -2203, -442, 537, 300, 2257, 857, 954, +367, -1155, -598, -1447, -836, 118, 48, 1046, +715, 367, 286, -386, -556, -225, -314, 108, +487, -198, 600, -297, -511, 270, -1100, 863, +215, 233, 1538, -953, 560, -960, -1457, 221, +-1658, 1271, 388, 743, 2237, -569, 1190, -1211, +-1680, -443, -2371, 841, -155, 1053, 2133, 0, +1670, -1094, -529, -641, -1821, 701, -1059, 1035, +561, -35, 1380, -1135, 712, -612, -457, 630, +-896, 1082, -552, 262, 215, -792, 782, -924, +461, -97, -300, 854, -764, 687, -272, -26, +536, -496, 591, -512, -235, -189, -609, 206, +-333, 626, 302, 548, 504, -185, 174, -927, +-214, -655, -356, 472, -411, 1128, -186, 479, +608, -719, 959, -1126, 245, -151, -1167, 872, +-1454, 874, 312, -133, 1951, -738, 1020, -334, +-1274, 129, -1807, 96, -157, 46, 1563, 600, +1170, 522, -698, -479, -1468, -1418, -246, -734, +1054, 1381, 722, 2268, -449, 188, -765, -2632, +-178, -2268, 372, 1084, 534, 3149, 152, 1519, +-292, -1944, -487, -3046, -376, -735, 240, 2404, +979, 2772, 485, 60, -878, -2620, -1115, -2357, +-63, 531, 1093, 2603, 998, 1879, -407, -778, +-1287, -2503, -545, -1512, 591, 993, 958, 2304, +418, 1094, -650, -951, -986, -1857, -386, -922, +641, 721, 1337, 1485, 431, 923, -1393, -465, +-1529, -1187, 331, -813, 1857, 251, 1232, 773, +-1219, 602, -2152, 112, 18, -207, 1958, -427, +1021, -576, -1196, -403, -1612, 379, 276, 1107, +1816, 1010, 439, -495, -1683, -1793, -1245, -1206, +903, 910, 1856, 2118, 100, 1008, -1769, -1074, +-909, -2063, 1088, -838, 1081, 1151, -423, 1826, +-954, 651, 89, -1007, 1156, -1449, 206, -583, +-1433, 721, -966, 1206, 988, 539, 1747, -488, +258, -847, -1613, -350, -1566, 86, 307, 236, +1573, 421, 1020, 607, -444, 314, -1269, -844, +-692, -1324, 321, -312, 700, 1327, 567, 1521, +35, 37, -368, -1356, -399, -1116, -426, 183, +-298, 631, 501, 375, 1152, 389, 795, 547, +-964, -127, -2113, -1349, -862, -1384, 1971, 327, +2531, 2101, -13, 1649, -2682, -626, -2040, -2106, +1063, -1386, 2442, 356, 645, 1412, -1560, 1245, +-1164, 527, 728, -551, 1037, -1493, -654, -1558, +-1394, 24, 319, 1900, 1943, 2085, 1248, 318, +-1384, -1853, -2703, -2331, -890, -740, 2100, 1601, +2948, 2477, 601, 1141, -2617, -1229, -3065, -2563, +-77, -1380, 2854, 1024, 2552, 2367, -478, 1419, +-2783, -748, -1785, -2113, 1039, -1330, 2152, 719, +721, 1839, -1055, 922, -1349, -912, -103, -1479, +787, -50, 704, 1256, 186, 765, -441, -947, +-1114, -1528, -547, 51, 1056, 2005, 1857, 1669, +511, -940, -2215, -2763, -2845, -1636, 319, 1495, +3691, 3191, 2904, 1626, -1571, -1638, -4705, -3288, +-2456, -1752, 2925, 1349, 4889, 3203, 1305, 2137, +-3502, -832, -4381, -3202, -489, -2646, 3675, 506, +3517, 3371, -160, 2939, -3188, -608, -2785, -3673, +354, -2604, 2665, 1386, 2073, 3636, -314, 1423, +-1887, -2316, -1775, -2983, -259, 269, 1323, 2950, +1920, 1598, 907, -1652, -1147, -2605, -2529, -374, +-1528, 1889, 1389, 1757, 3329, 192, 1760, -955, +-2008, -1291, -4001, -1213, -1583, -274, 2741, 1553, +4166, 2777, 1043, 1251, -3073, -2388, -3818, -4110, +-672, -1453, 2961, 3098, 3249, 4572, 472, 1167, +-2499, -3192, -2872, -3898, -491, -806, 2205, 2232, +2369, 2625, 218, 985, -1857, -765, -1773, -1421, +161, -1446, 1407, -694, 723, 703, -368, 1919, +-350, 1487, 55, -394, -153, -1973, -702, -1639, +-170, 258, 1283, 1766, 1355, 1380, -779, -391, +-2534, -1566, -1036, -735, 2343, 937, 3091, 1328, +-208, -148, -3602, -1712, -2738, -1151, 1382, 1150, +3959, 2426, 1950, 953, -2046, -1820, -3499, -2790, +-1185, -866, 1799, 1857, 2391, 2622, 917, 1181, +-664, -1016, -1330, -2309, -1395, -2061, -695, -286, +778, 2274, 2095, 3374, 1775, 1122, -648, -2718, +-2891, -3927, -2179, -1070, 902, 2671, 2915, 3350, +1956, 828, -796, -1674, -2492, -2109, -1737, -1151, +341, 60, 1774, 1255, 1809, 2008, 388, 1256, +-1472, -1078, -2277, -2862, -872, -1744, 1767, 1460, +2614, 3076, 629, 1327, -2089, -1668, -2335, -2365, +-146, -553, 1934, 1069, 1488, 1016, -205, 388, +-873, 324, -535, 42, -365, -1147, -500, -1740, +15, -101, 1253, 2182, 1834, 2119, 5, -291, +-2380, -2336, -2566, -1818, 301, 288, 2983, 1592, +2551, 1373, -516, 556, -2724, -445, -2162, -1480, +273, -1748, 1946, -278, 1514, 1902, 318, 2485, +-613, 471, -1218, -1981, -1268, -2471, -279, -493, +1161, 1526, 1729, 1763, 584, 558, -1049, -315, +-1418, -852, -453, -1152, 411, -834, 391, 298, +216, 1381, 805, 1558, 1026, 536, -467, -1160, +-2415, -2314, -1877, -1613, 1057, 909, 3539, 3198, +2272, 2539, -1804, -987, -4014, -3856, -1932, -2863, +2057, 1302, 3630, 3962, 1521, 2302, -1889, -1492, +-2830, -2985, -975, -1172, 1176, 894, 1540, 1068, +733, 291, 75, 635, -399, 1039, -1102, -279, +-1315, -2600, -169, -2380, 1615, 1188, 2133, 4003, +257, 2353, -2205, -2163, -2221, -4144, 282, -1286, +2084, 2582, 1537, 2741, -549, 10, -1648, -1723, +-575, -829, 888, 546, 792, 470, -511, -725, +-1057, -684, 4, 762, 1480, 1502, 1331, 338, +-782, -1242, -2441, -1242, -1438, -167, 1580, 682, +2957, 663, 929, 429, -2002, 214, -2440, -168, +-272, -621, 1568, -857, 1190, -401, -87, 431, +-353, 1131, 125, 1197, -139, 181, -1016, -1341, +-868, -2003, 725, -706, 1700, 1381, 714, 2379, +-931, 1004, -1344, -1202, -333, -1945, 412, -953, +386, 366, 207, 969, 365, 948, 462, 629, +-117, 173, -984, -716, -1095, -1524, 29, -1273, +1168, 300, 1354, 2030, 335, 2085, -1102, 361, +-1506, -1856, -391, -2733, 851, -1433, 1139, 1511, +277, 3442, -520, 2129, -351, -1420, 100, -3619, +-136, -1989, -615, 1401, -201, 2790, 716, 1137, +1087, -868, 179, -1182, -941, -407, -952, -77, +-69, -264, 576, 97, 289, 885, 68, 961, +202, -81, 422, -989, -59, -915, -943, 27, +-988, 498, -96, 347, 1083, 195, 1566, 351, +654, 229, -989, -413, -1983, -1051, -1364, -764, +599, 536, 2295, 1454, 1956, 898, -291, -427, +-2287, -1177, -2086, -797, 37, -132, 1879, 462, +1627, 795, 141, 870, -885, 232, -911, -835, +-457, -1432, -144, -728, 171, 752, 740, 1744, +1068, 1078, 269, -726, -1055, -1856, -1496, -969, +-276, 730, 1265, 1469, 1284, 691, -132, -443, +-1230, -979, -636, -652, 700, 110, 1074, 832, +-148, 802, -1342, -133, -807, -959, 854, -800, +1659, 323, 664, 1093, -1107, 771, -1781, -531, +-635, -1215, 920, -609, 1592, 573, 853, 1142, +-604, 587, -1211, -391, -792, -1039, -87, -707, +542, 187, 866, 906, 712, 790, 201, 122, +-799, -582, -1531, -1137, -694, -691, 1081, 728, +1812, 1838, 712, 832, -1231, -1483, -1721, -2247, +-263, -178, 1309, 2217, 1023, 1888, -400, -701, +-1035, -2400, -69, -1063, 858, 1488, 460, 1811, +-512, -120, -892, -1404, -292, -533, 702, 709, +896, 443, 318, -582, -442, -357, -911, 820, +-790, 790, 165, -650, 1076, -1373, 1173, -141, +182, 1450, -1202, 1057, -1618, -880, -390, -1528, +1376, -48, 1796, 1456, 485, 909, -1370, -810, +-1848, -1376, -491, -144, 1335, 1043, 1672, 811, +347, -107, -1117, -680, -1243, -394, -182, -21, +653, -14, 614, 143, 178, 634, 99, 642, +-55, -300, -565, -1202, -764, -919, -42, 570, +962, 1482, 1033, 702, -121, -670, -1198, -1125, +-762, -410, 424, 374, 929, 482, 253, 196, +-578, 186, -379, 171, 341, -194, 439, -709, +-159, -604, -674, 261, -330, 1025, 593, 673, +865, -320, 63, -847, -657, -567, -687, 51, +-103, 519, 574, 539, 526, 178, -15, -291, +-282, -426, -230, -125, 56, 111, 47, 50, +-179, -66, -94, 86, 258, 411, 357, 340, +133, -319, -287, -806, -506, -407, -37, 344, +254, 768, 115, 529, 62, -39, 220, -455, +185, -692, -106, -613, -622, 70, -621, 968, +220, 1143, 1075, 288, 834, -937, -476, -1483, +-1251, -821, -619, 612, 648, 1725, 1003, 1480, +234, -239, -688, -1955, -610, -1934, 367, 20, +742, 1998, -19, 1912, -923, -56, -719, -1595, +531, -1208, 1414, 48, 620, 514, -979, 280, +-1442, 405, -385, 838, 899, 207, 1091, -1219, +315, -1592, -439, -29, -630, 1706, -394, 1405, +-23, -452, 211, -1395, 371, -472, 336, 587, +23, 368, -210, -365, -74, -202, -251, 662, +-513, 621, -144, -390, 675, -1044, 1044, -397, +285, 684, -912, 822, -1172, -102, -244, -626, +669, -122, 915, 515, 331, 286, -250, -478, +-360, -866, -366, -74, -347, 1004, -168, 1107, +264, 27, 712, -1242, 777, -1353, 51, -111, +-976, 1318, -1306, 1397, -400, 178, 1177, -1078, +1617, -1195, 400, -254, -1146, 535, -1320, 743, +-231, 566, 737, 155, 599, -553, 61, -950, +117, -409, 166, 649, -296, 909, -878, 85, +-437, -625, 689, -298, 1086, 381, 139, 327, +-821, -552, -567, -765, 230, 336, 455, 1231, +-50, 561, -362, -869, -42, -1248, 448, -176, +373, 1000, -215, 809, -488, -244, -268, -704, +96, -148, 307, 395, 301, 225, 203, -293, +-158, -361, -385, 10, -317, 382, 52, 446, +357, 161, 277, -383, -127, -745, -224, -488, +69, 484, 214, 1125, -26, 537, -402, -655, +-424, -1073, 186, -320, 823, 588, 577, 637, +-334, -46, -941, -268, -594, 163, 255, 316, +712, -292, 542, -907, 66, -487, -249, 801, +-244, 1447, -512, 560, -628, -1069, 58, -1772, +1113, -655, 1233, 1257, 121, 1848, -1357, 511, +-1693, -1245, -336, -1566, 1367, -254, 1806, 1075, +510, 946, -1103, -113, -1542, -637, -575, -114, +667, 348, 993, -46, 396, -596, -118, -241, +-104, 631, -146, 855, -499, 63, -689, -873, +-189, -830, 922, 70, 1428, 778, 401, 675, +-1206, -47, -1675, -593, -500, -504, 1102, 38, +1510, 353, 534, 342, -667, -39, -1081, -238, +-585, -48, 165, 138, 641, -77, 535, -289, +201, -77, -156, 449, -342, 538, -400, -179, +-278, -905, 89, -493, 552, 639, 559, 1118, +19, 204, -616, -1120, -592, -1085, 153, 361, +619, 1412, 91, 682, -475, -994, -174, -1369, +537, 86, 564, 1447, -352, 815, -1006, -893, +-437, -1430, 751, -18, 1068, 1470, 173, 998, +-681, -814, -701, -1526, -164, -325, 201, 1205, +362, 1156, 405, -187, 319, -1116, -86, -696, +-730, 345, -708, 804, 115, 354, 812, -373, +651, -485, 47, -7, -508, 378, -675, 167, +-330, -439, 222, -426, 752, 333, 618, 875, +-142, 297, -794, -868, -661, -1177, 177, 30, +860, 1352, 472, 1079, -457, -522, -677, -1416, +-39, -643, 644, 781, 433, 1094, -433, 174, +-804, -684, -54, -677, 847, -45, 685, 537, +-275, 536, -913, 12, -454, -620, 427, -562, +718, 190, 164, 830, -427, 457, -261, -499, +207, -862, 184, -204, -373, 650, -417, 600, +320, -60, 850, -359, 363, -199, -773, -104, +-1026, -113, -49, 102, 993, 478, 739, 379, +-276, -292, -785, -716, -324, -273, 467, 450, +465, 556, -132, 109, -467, -360, -142, -295, +312, -82, 507, 55, 230, 202, -499, 316, +-815, 77, -205, -470, 684, -478, 899, 258, +367, 781, -702, 151, -1116, -817, -329, -619, +750, 538, 937, 1036, 236, -17, -551, -1185, +-634, -716, -22, 849, 282, 1342, 97, 36, +-129, -1438, 101, -1092, 400, 725, 185, 1594, +-379, 475, -708, -1165, -238, -1248, 648, 81, +772, 1174, -20, 670, -550, -488, -278, -744, +96, -20, 17, 448, -216, 41, 94, -354, +688, 48, 451, 544, -586, 88, -976, -667, +-203, -492, 815, 527, 711, 880, -177, -111, +-470, -1040, -83, -513, 95, 775, -84, 999, +-172, 0, 122, -988, 529, -709, 88, 265, +-537, 679, -240, 401, 427, 46, 295, -112, +-481, -496, -684, -747, 375, -234, 1305, 943, +384, 1338, -1218, 177, -1379, -1322, 98, -1505, +1505, -33, 1116, 1440, -533, 1313, -1266, -149, +-397, -1200, 543, -901, 511, 178, -71, 791, +-216, 461, 140, -151, 301, -386, -24, -115, +-499, 183, -464, 166, 111, -240, 640, -318, +518, 6, 17, 409, -486, 448, -624, 28, +-170, -431, 291, -560, 453, -265, 414, 255, +118, 716, -322, 589, -493, -101, -469, -726, +-95, -810, 640, -232, 889, 580, 327, 1030, +-581, 600, -1205, -392, -540, -1187, 792, -906, +1126, 266, 317, 1206, -567, 958, -743, -211, +-171, -940, 322, -716, 228, 1, -16, 421, +13, 421, 290, 284, 242, 167, -407, -126, +-764, -684, -125, -686, 711, 46, 804, 936, +45, 1008, -806, -1, -702, -1158, 213, -1130, +747, 130, 344, 1212, -335, 960, -547, -302, +-7, -1090, 473, -573, 232, 396, -219, 634, +-304, 252, -62, -184, 103, -243, 147, -184, +165, -149, 166, 79, -80, 408, -430, 393, +-411, -271, 123, -771, 746, -266, 501, 749, +-349, 811, -684, -269, -237, -958, 221, -376, +283, 642, 93, 677, 189, -178, 288, -561, +-185, 10, -858, 390, -536, -68, 606, -538, +1173, -99, 445, 731, -876, 636, -1127, -431, +-57, -1037, 867, -355, 600, 683, -190, 885, +-415, 186, -58, -565, 162, -668, -98, -241, +-230, 341, 53, 572, 372, 262, 256, -210, +-140, -356, -330, -191, -156, -29, 25, 24, +94, 162, 196, 348, 169, 247, 54, -270, +-139, -603, -292, -281, -274, 334, 74, 612, +479, 208, 458, -291, -152, -401, -645, -159, +-291, 60, 319, 165, 469, 252, -14, 142, +-272, -162, -89, -315, 227, -60, 123, 237, +-302, 116, -369, -211, 260, -179, 574, 252, +94, 462, -452, -75, -387, -659, 113, -443, +349, 350, 108, 695, -104, 259, 12, -308, +-12, -394, -257, -233, -148, -161, 342, 63, +492, 615, -76, 690, -637, -106, -458, -1071, +363, -898, 846, 368, 237, 1299, -635, 752, +-709, -609, -18, -1168, 515, -366, 520, 657, +134, 719, -304, -17, -537, -463, -269, -206, +283, 228, 547, 199, 216, -228, -291, -296, +-362, 130, 27, 434, 193, 151, -86, -402, +-156, -328, 226, 230, 454, 426, 2, -173, +-674, -599, -505, -71, 462, 798, 877, 672, +75, -507, -808, -1200, -532, -353, 405, 930, +686, 1028, 30, -59, -495, -845, -235, -447, +156, 246, 171, 202, -39, -192, 88, 43, +191, 593, -90, 435, -444, -507, -91, -1023, +353, -351, 256, 692, -107, 907, -161, 282, +154, -340, 128, -566, -422, -546, -545, -273, +283, 369, 1018, 984, 529, 723, -802, -416, +-1211, -1241, -120, -765, 953, 423, 724, 1042, +-94, 642, -400, -157, -209, -655, -189, -606, +-334, -157, 12, 341, 753, 572, 786, 307, +-152, -181, -1065, -399, -843, -253, 296, 3, +1057, 118, 634, 162, -262, 174, -725, 100, +-511, -101, 110, -266, 504, -189, 313, 63, +-44, 215, -235, 185, -78, 32, 109, -119, +-92, -200, -301, -138, 59, 107, 513, 305, +424, 134, -295, -309, -818, -416, -211, 129, +678, 649, 613, 295, -165, -584, -591, -778, +-252, 79, 377, 860, 330, 515, -153, -406, +-196, -651, 79, -70, 137, 322, -144, 63, +-184, -166, 233, 168, 443, 467, -186, -4, +-591, -709, -150, -574, 522, 331, 533, 831, +-121, 341, -525, -434, -276, -529, 244, -81, +225, 134, 25, 32, -9, 102, 218, 378, +35, 266, -565, -351, -564, -740, 396, -279, +1025, 568, 379, 789, -768, 179, -1091, -546, +-62, -671, 922, -191, 730, 405, -162, 565, +-595, 258, -350, -244, -21, -543, 89, -375, +195, 185, 502, 635, 266, 407, -493, -316, +-875, -661, -247, -276, 753, 387, 927, 569, +34, 191, -883, -326, -688, -523, 138, -202, +592, 289, 325, 532, 9, 219, -168, -297, +-306, -502, -304, -185, -12, 301, 372, 349, +477, 79, 28, -147, -538, -102, -406, -68, +138, -135, 436, -87, 216, 183, -208, 393, +-302, 113, 80, -324, 142, -421, -20, -101, +1, 276, 34, 374, -52, 154, -94, -171, +-12, -315, 238, -199, 245, 3, -273, 231, +-421, 318, 65, 139, 440, -216, 246, -430, +-189, -171, -348, 277, 31, 418, 297, 74, +-26, -280, -271, -219, 16, -8, 476, 124, +248, 71, -428, 68, -629, -14, 39, -79, +746, -74, 545, 16, -337, 90, -756, 36, +-235, -18, 486, -125, 603, -58, 52, 114, +-521, 230, -413, 53, 202, -284, 516, -337, +177, 38, -373, 494, -421, 286, 173, -258, +522, -424, 140, -34, -474, 217, -510, 82, +170, -71, 821, 89, 364, 262, -689, -38, +-908, -498, -19, -415, 959, 262, 822, 748, +-358, 391, -1040, -417, -432, -788, 446, -318, +666, 373, 174, 663, -324, 361, -221, -135, +14, -552, -172, -632, -236, -168, 129, 719, +500, 992, 387, 115, -264, -1012, -744, -1025, +-416, 123, 291, 1081, 604, 810, 364, -261, +-134, -899, -488, -596, -451, 193, -97, 698, +348, 508, 561, -124, 171, -577, -439, -400, +-603, 87, -54, 417, 575, 308, 400, -10, +-341, -296, -578, -291, 24, -35, 589, 191, +376, 327, -346, 195, -708, -238, -198, -610, +548, -216, 690, 608, 98, 797, -615, -77, +-620, -995, 58, -670, 591, 531, 414, 1031, +-141, 208, -381, -693, -93, -571, 192, 144, +94, 357, -188, -2, -80, -74, 344, 240, +392, 268, -128, -336, -606, -639, -304, -64, +404, 697, 702, 546, 156, -301, -558, -667, +-456, -148, 218, 544, 427, 378, 9, -370, +-168, -574, 58, 154, 178, 739, 11, 246, +-283, -566, -220, -609, 289, 33, 544, 469, +54, 397, -516, 46, -479, -270, 234, -356, +686, -136, 278, 183, -508, 328, -633, 38, +59, -253, 687, -51, 495, 314, -348, 158, +-781, -458, -320, -609, 534, 109, 826, 948, +205, 758, -725, -445, -890, -1275, -46, -776, +847, 704, 738, 1478, -156, 604, -734, -984, +-528, -1371, 62, -132, 373, 1006, 365, 713, +174, -240, -81, -342, -433, -2, -603, -200, +-133, -426, 581, 138, 762, 851, 87, 452, +-731, -640, -893, -956, -90, -55, 833, 845, +783, 681, -181, -224, -869, -804, -485, -441, +311, 404, 499, 704, 112, 188, -196, -447, +-155, -487, -95, -39, -153, 284, 12, 278, +321, 149, 209, -73, -222, -342, -373, -314, +-64, 104, 328, 435, 284, 258, -222, -215, +-361, -389, 93, -58, 423, 271, 128, 152, +-395, -125, -436, -162, 184, -13, 679, 100, +368, 201, -472, 166, -714, -268, -45, -610, +505, -96, 493, 797, 246, 706, -196, -297, +-683, -941, -391, -533, 465, 348, 785, 835, +234, 586, -480, -302, -512, -909, 114, -580, +407, 462, 38, 911, -242, 211, 126, -575, +446, -460, 46, 118, -488, 249, -374, 155, +128, -19, 566, -279, 517, -78, -139, 448, +-721, 239, -312, -597, 337, -500, 460, 420, +245, 763, -157, 43, -441, -715, -111, -546, +300, 332, 190, 734, -103, 127, -129, -500, +14, -342, 129, 92, 45, 193, -233, 152, +-163, 53, 267, -86, 319, -56, -306, -47, +-484, -219, 182, -64, 517, 469, 28, 357, +-471, -368, -435, -549, 200, 80, 591, 498, +74, 109, -529, -381, -345, -166, 144, 376, +339, 293, 101, -318, -336, -510, -266, -17, +224, 515, 271, 471, -206, -139, -440, -580, +-78, -323, 453, 242, 429, 414, -308, 165, +-737, -110, -217, -268, 608, -165, 560, 103, +-180, 151, -603, -25, -285, -23, 256, 129, +393, 48, 22, -171, -379, -205, -137, 3, +359, 254, 243, 224, -388, -83, -553, -348, +180, -172, 795, 313, 363, 436, -577, -129, +-788, -720, -114, -276, 739, 808, 743, 892, +-128, -364, -734, -1310, -448, -519, 271, 956, +688, 1247, 249, 7, -502, -1131, -338, -771, +314, 331, 287, 801, -174, 271, -203, -335, +136, -272, 417, 136, 53, 56, -463, -344, +-330, -162, 442, 389, 631, 538, -29, 3, +-589, -620, -367, -510, 308, 260, 666, 616, +260, 156, -553, -335, -573, -312, 204, 27, +642, 244, 264, 136, -364, -106, -528, -183, +41, -91, 638, 113, 225, 176, -440, 152, +-286, 19, 112, -329, 157, -449, 116, 72, +89, 707, -49, 465, -181, -379, -243, -800, +12, -247, 336, 633, 209, 591, -225, -159, +-261, -550, 78, -110, 96, 368, -161, 168, +-113, -334, 108, -243, 239, 329, 204, 360, +-278, -123, -647, -424, -94, -166, 556, 329, +375, 322, -139, -208, -384, -384, -109, 196, +64, 479, -215, -110, -191, -642, 453, -181, +587, 632, -217, 561, -771, -300, -492, -733, +312, -205, 711, 564, 260, 521, -445, -166, +-488, -529, 93, -228, 276, 353, -134, 473, +-231, -140, 167, -566, 296, -9, 121, 546, +-229, 67, -537, -442, -180, -111, 526, 402, +497, 210, -133, -349, -406, -429, -126, 117, +147, 554, 12, 320, -67, -381, 222, -637, +215, -36, -111, 562, -285, 313, -218, -271, +274, -278, 464, 86, -43, 312, -379, -83, +-200, -586, 128, -230, 553, 748, 254, 860, +-651, -308, -406, -1087, 426, -576, 389, 493, +61, 941, -158, 476, -205, -435, 35, -875, +124, -243, -19, 467, 81, 428, -4, -64, +49, -182, 142, 8, -39, 225, -180, 36, +-176, -485, -35, -466, 481, 346, 483, 876, +-427, 253, -516, -618, -64, -700, 203, -44, +473, 539, 213, 406, -440, -222, -343, -356, +152, 368, 236, 413, 114, -611, -249, -912, +-220, 400, 263, 1265, 281, 280, -50, -986, +-376, -779, -335, 370, 259, 744, 472, 63, +-105, -563, -115, -277, -103, 530, -340, 597, +51, -432, 370, -980, 48, 33, -88, 1050, +-178, 363, -204, -773, 249, -402, 135, 559, +-320, 393, -191, -713, 249, -646, 366, 688, +-20, 1139, -499, -172, -350, -1284, 158, -455, +389, 820, 361, 755, -194, -373, -516, -689, +-34, 322, 146, 716, -77, -351, 153, -1040, +237, 1, 29, 1171, -203, 711, -434, -826, +-32, -1249, 479, 258, 87, 1350, -266, 174, +71, -1289, 171, -502, 17, 1286, -330, 1011, +-458, -1099, 268, -1660, 774, 470, 206, 1952, +-461, 442, -584, -1629, -100, -1141, 455, 970, +347, 1362, -145, -392, -112, -1300, 174, -61, +81, 1225, -380, 585, -444, -977, 329, -1185, +704, 422, 114, 1440, -352, 250, -318, -1126, +-110, -672, 146, 627, 103, 722, 27, -326, +313, -734, 210, 179, -269, 838, -521, 95, +-148, -756, 389, -493, 462, 466, 4, 520, +-296, -177, -88, -325, 157, 302, -24, 410, +-374, -420, -74, -959, 479, -192, 474, 1345, +35, 1317, -527, -702, -702, -1981, 18, -698, +702, 1480, 420, 1706, -22, -219, -284, -1695, +-392, -698, -157, 974, 115, 915, 229, -347, +259, -793, 19, 94, -131, 736, -122, 69, +-266, -817, -79, -249, 303, 777, 185, 542, +-26, -644, -137, -946, -141, 407, 204, 1322, +82, 206, -528, -1502, -205, -1001, 603, 1089, +425, 1563, -144, -211, -380, -1541, -406, -448, +-106, 956, 321, 652, 451, -514, 217, -537, +-267, 463, -438, 582, -211, -420, -7, -990, +367, 44, 476, 1184, -92, 745, -434, -871, +-213, -1346, 78, 110, 196, 1366, 74, 616, +-179, -947, 140, -881, 282, 446, -210, 789, +-421, -207, -24, -617, 299, 130, 279, 525, +111, 133, -350, -549, -422, -584, 228, 278, +555, 1123, -122, 373, -565, -1178, -7, -1203, +411, 528, 324, 1632, -102, 423, -426, -1227, +-332, -1059, 219, 424, 391, 944, 199, 80, +51, -475, -320, 0, -513, 415, -54, -257, +563, -759, 378, 3, -68, 936, -332, 722, +-256, -580, 80, -1182, 112, -182, -8, 1036, +181, 648, 328, -517, -177, -566, -622, 10, +-122, 302, 599, 159, 466, -8, -365, -186, +-616, -164, 38, 40, 719, 263, 227, 333, +-747, -246, -448, -634, 655, -104, 571, 789, +-484, 438, -605, -690, 295, -674, 788, 615, +-46, 1019, -1121, -667, -471, -1608, 1209, 242, +1212, 2322, -745, 969, -1622, -2336, -215, -2542, +1403, 1198, 917, 3353, -625, 611, -1132, -2778, +-8, -1968, 954, 1296, 300, 2275, -847, 45, +-416, -1938, 793, -663, 542, 1499, -442, 944, +-583, -1189, -194, -1204, 242, 810, 634, 1294, +310, -276, -429, -1160, -543, 102, -309, 853, +252, -195, 783, -1060, 399, 223, -550, 1791, +-932, 371, -182, -2324, 961, -1662, 946, 2060, +-569, 2763, -1308, -689, -148, -3113, 1295, -962, +845, 2534, -845, 2039, -1353, -1476, 168, -2403, +1430, 724, 390, 2332, -1021, -188, -701, -2476, +532, -491, 787, 2665, -250, 1661, -850, -2208, +84, -3016, 1026, 779, 172, 3620, -1113, 1148, +-681, -2924, 951, -2471, 1170, 1420, -536, 2630, +-1401, -113, -54, -2029, 1308, -581, 657, 1614, +-928, 940, -1140, -1412, 436, -1554, 1266, 839, +26, 2201, -1069, 272, -249, -2004, 771, -1465, +330, 1096, -605, 1731, -615, -185, 597, -1216, +1022, -86, -342, 862, -1279, -98, -218, -942, +1107, -99, 736, 1037, -571, 652, -961, -761, +165, -948, 868, 318, 56, 945, -818, -103, +-341, -1025, 855, -218, 779, 1246, -555, 1066, +-1321, -994, -60, -1954, 1320, -50, 873, 2048, +-750, 1142, -1401, -1184, -34, -1586, 1293, 241, +733, 1435, -812, 221, -927, -1114, 121, -609, +752, 815, 347, 918, -377, -215, -326, -786, +30, -316, 183, 185, -196, -54, -78, 216, +486, 831, 482, 462, -504, -882, -1054, -1552, +15, -179, 1095, 1560, 784, 1416, -713, -461, +-940, -1441, 125, -548, 593, 607, -19, 609, +-289, -320, 320, -211, 430, 762, -359, 539, +-876, -878, 37, -1395, 977, -15, 387, 1408, +-726, 1168, -516, -309, 491, -1060, 575, -633, +-487, -229, -968, 150, 373, 939, 1510, 1340, +383, 82, -1666, -2011, -1384, -1879, 794, 805, +2065, 2666, 514, 1146, -1706, -1685, -1560, -2142, +725, 20, 1764, 1704, 238, 848, -1276, -690, +-815, -774, 646, 155, 897, 362, 50, -191, +-790, -116, -482, 424, 292, 85, 574, -744, +339, -254, -159, 967, -531, 917, -656, -774, +41, -1798, 1018, -188, 910, 2079, -575, 1579, +-1429, -1192, -425, -2343, 968, -466, 1230, 1849, +38, 1753, -1306, -532, -909, -1782, 801, -684, +1179, 956, -72, 979, -1017, -104, -570, -563, +622, -211, 887, 150, -44, 67, -770, -4, +-649, -33, 318, -16, 1003, 178, 345, 224, +-796, -48, -921, -627, 3, -484, 1205, 572, +908, 1229, -851, 147, -1470, -1433, -126, -1247, +1201, 736, 1163, 1998, -162, 638, -1337, -1796, +-973, -1967, 374, 570, 1228, 2484, 933, 1041, +-323, -1723, -1361, -2011, -950, 119, 452, 1634, +1507, 1014, 1011, -210, -812, -779, -1783, -710, +-581, -553, 1210, 45, 1687, 1314, 176, 1575, +-1493, -234, -1238, -2345, 162, -1797, 1005, 1021, +1075, 2721, 395, 1309, -877, -1501, -1431, -2338, +-868, -675, 984, 1325, 2318, 1465, 899, 414, +-1961, -479, -2461, -797, 32, -811, 2435, -234, +1828, 791, -1267, 1173, -2250, 222, -80, -1011, +1833, -832, 865, 278, -1130, 692, -1408, 40, +310, -505, 1588, -147, 658, 647, -903, 697, +-1275, -430, -197, -1303, 694, -631, 761, 984, +481, 1565, -136, 316, -1016, -1238, -874, -1408, +475, 82, 1160, 1310, 337, 778, -853, -712, +-710, -939, 662, 429, 1006, 1116, -581, -58, +-1648, -1589, -214, -989, 2009, 1304, 1651, 2106, +-1111, 306, -2546, -1957, -675, -1944, 2001, 253, +1891, 2082, -671, 1379, -1927, -767, -299, -1522, +1452, -542, 815, 667, -1127, 813, -1471, -12, +449, -582, 2082, -183, 1026, 633, -1713, 443, +-2396, -591, 23, -1079, 2464, 29, 1758, 1335, +-1211, 892, -2459, -847, -320, -1495, 2281, 116, +1344, 1626, -1777, 545, -2279, -1754, 964, -1330, +3068, 1542, 587, 2549, -2816, -245, -2413, -3228, +1227, -2090, 3012, 1995, 815, 3912, -2131, 889, +-1615, -3321, 745, -3474, 1146, 606, -176, 3679, +-629, 2140, 439, -1555, 871, -2982, -409, -929, +-1542, 1770, -266, 2070, 1555, 117, 1254, -1655, +-727, -1307, -1632, 404, -418, 1528, 1165, 720, +1026, -973, -42, -1323, -718, 25, -703, 1328, +-418, 781, 378, -689, 1264, -1124, 1035, -81, +-729, 775, -2294, 498, -1013, -114, 1950, -269, +2589, -257, -99, -321, -2568, 13, -1851, 675, +1221, 660, 2458, -389, 299, -1127, -1859, -472, +-1161, 922, 1033, 1285, 1468, 6, -315, -1366, +-1754, -1108, -372, 525, 1636, 1509, 1291, 774, +-887, -814, -1812, -1529, -368, -559, 1370, 1049, +1384, 1514, -201, 294, -1435, -1139, -904, -1318, +494, -283, 1206, 959, 656, 1409, -550, 547, +-1253, -1013, -468, -1759, 827, -592, 1142, 1315, +180, 1891, -1114, 386, -995, -1456, 430, -1732, +1254, -236, 274, 1409, -928, 1530, -840, 40, +492, -1251, 991, -1021, -32, 7, -860, 629, +-400, 696, 527, 526, 635, -252, -82, -994, +-675, -803, -279, 416, 456, 1164, 489, 758, +-37, -593, -531, -1320, -422, -503, 98, 896, +786, 1095, 688, 249, -585, -627, -1390, -997, +-360, -743, 1318, 548, 1468, 1770, -242, 1135, +-1883, -1286, -1162, -2641, 1279, -745, 1860, 2316, +0, 2821, -1629, -118, -1022, -2986, 842, -2270, +1443, 1084, -58, 2788, -1347, 1043, -341, -1248, +869, -1525, 606, -409, -465, 314, -696, 486, +264, 787, 781, 759, -196, -294, -966, -1650, +37, -1115, 1163, 869, 546, 1915, -1199, 569, +-1342, -1026, 772, -1212, 1950, -299, 234, 333, +-1938, 548, -1516, 709, 1031, 639, 2450, -380, +544, -1676, -2163, -1330, -2071, 1035, 527, 2561, +2459, 1060, 1430, -1761, -1145, -2604, -2313, -522, +-823, 2020, 1395, 2164, 1914, 36, 286, -1732, +-1406, -1454, -1270, 25, 185, 1052, 1074, 1044, +448, 175, -490, -509, -382, -677, 392, -343, +296, -145, -564, 326, -742, 783, 347, 706, +1186, -196, 404, -1260, -922, -1077, -1108, 340, +3, 1614, 944, 1003, 819, -568, 66, -1413, +-662, -698, -1106, 418, -702, 808, 1120, 553, +2185, 185, 510, -303, -2412, -797, -2697, -613, +482, 193, 3579, 723, 2320, 619, -2011, 236, +-3762, -231, -748, -794, 2676, -1047, 2411, -253, +-529, 1307, -1918, 1897, -622, 403, 734, -1938, +237, -2346, -377, -214, -25, 2161, 794, 2174, +842, 305, -392, -1640, -1498, -2047, -1127, -1103, +495, 872, 1902, 2595, 1768, 2126, -427, -706, +-2821, -3343, -2359, -2577, 1070, 798, 3828, 3645, +2175, 2796, -2310, -992, -4159, -3702, -959, -2463, +3268, 1213, 3354, 3072, -414, 1772, -3257, -832, +-2062, -2156, 1221, -1386, 2534, 244, 923, 1546, +-1191, 1316, -1534, -107, -545, -1448, 501, -1113, +1157, 713, 1083, 1655, -167, 309, -1658, -1816, +-1627, -1773, 503, 949, 2570, 3159, 1819, 1538, +-1508, -2603, -3432, -3963, -1287, -676, 2581, 3547, +3761, 3892, 578, 174, -3364, -3514, -3688, -3508, +-19, -262, 3652, 2677, 3592, 3137, -196, 1166, +-3716, -1591, -3530, -3353, 176, -2402, 3635, 1075, +3527, 4101, -112, 3046, -3513, -1513, -3379, -4582, +79, -2500, 3225, 2270, 3012, 4251, -49, 1237, +-2598, -2813, -2599, -3303, -411, 134, 1976, 3090, +2650, 2187, 930, -1360, -1824, -3013, -3069, -1120, +-1170, 1854, 2233, 2676, 3494, 820, 889, -1645, +-2949, -2577, -3537, -1253, -156, 1192, 3265, 2682, +3115, 1859, -309, -537, -3202, -2593, -2476, -2483, +531, -401, 2395, 2188, 1860, 3116, 110, 1458, +-1442, -1597, -1839, -3574, -1011, -2368, 800, 936, +2259, 3607, 1633, 3025, -789, -268, -2517, -3299, +-1632, -3241, 1060, -339, 2378, 2722, 949, 3175, +-1175, 636, -1524, -2255, -325, -2685, 727, -438, +684, 1932, 214, 1860, 98, -279, -446, -1709, +-1098, -738, -366, 1084, 1364, 1565, 1852, -153, +-254, -1878, -2627, -1438, -1964, 775, 1440, 2081, +3215, 1209, 1286, -500, -1885, -1433, -2713, -1408, +-1021, -817, 1170, 476, 1990, 2257, 1544, 2656, +273, 133, -1621, -3457, -2882, -4129, -1528, -238, +2031, 4419, 4223, 4730, 1801, -92, -2843, -4685, +-4506, -4118, -1187, 472, 3230, 3614, 3511, 2802, +175, 14, -2373, -1863, -1668, -1858, -46, -819, +558, 197, 358, 1179, 774, 1790, 1286, 1059, +74, -992, -2169, -2462, -2426, -1618, 585, 798, +3501, 2588, 2331, 2088, -1880, -455, -3746, -2873, +-1169, -2417, 2432, 627, 2818, 2950, 164, 2019, +-1900, -780, -1254, -2289, -44, -1308, 200, 349, +251, 945, 1066, 921, 1341, 896, -87, 301, +-2279, -1243, -2294, -2143, 575, -960, 2966, 1671, +2174, 2950, -849, 1118, -2520, -1888, -1738, -2905, +393, -1021, 1606, 1408, 1336, 2047, 409, 1173, +-554, -92, -1127, -1092, -1098, -1847, -194, -1394, +889, 673, 1240, 2668, 495, 2044, -282, -762, +-514, -2603, -724, -1700, -1026, 478, -476, 1515, +1217, 939, 2534, 437, 1387, 360, -1999, -548, +-3948, -2100, -1569, -1830, 2936, 914, 4407, 3497, +1014, 2319, -3369, -1677, -3738, -3915, -94, -1668, +2811, 2087, 2057, 2911, -196, 661, -1240, -1534, +-628, -1204, -338, 155, -448, 125, 57, -698, +1226, -132, 1388, 1802, -111, 1809, -1800, -904, +-1616, -3065, 354, -1567, 1832, 1839, 1394, 3030, +-289, 776, -1696, -2045, -1270, -2083, 567, -25, +1502, 1395, 641, 862, -863, -286, -1135, -319, +301, 230, 1356, -48, 284, -704, -1597, -461, +-1394, 464, 975, 867, 2448, 445, 920, -475, +-1963, -791, -2524, -161, -252, 387, 2016, 228, +2008, -173, 106, -128, -1377, 319, -1371, 574, +-482, 107, 462, -916, 1096, -1166, 903, -35, +-137, 1387, -717, 1494, -537, 40, -85, -1307, +-200, -1528, -206, -399, 539, 771, 1354, 1335, +668, 1042, -1087, 122, -1980, -1172, -814, -1651, +1298, -760, 1935, 708, 601, 1709, -848, 1347, +-1166, 152, -601, -1270, -64, -1935, 362, -1372, +835, 700, 870, 2673, 8, 2304, -988, -510, +-1012, -2968, 71, -2370, 734, 415, 286, 2369, +-231, 1847, 282, -39, 557, -1307, -60, -1171, +-1054, -407, -1013, 260, 289, 607, 1333, 603, +925, 275, -348, 16, -836, -234, -371, -643, +21, -717, -280, -95, -293, 846, 674, 1059, +1419, 185, 630, -791, -1187, -823, -1932, -23, +-772, 459, 1023, 46, 1639, -411, 1048, 315, +-49, 1097, -1025, 477, -1524, -1186, -1155, -1749, +289, -385, 2010, 1554, 2242, 1937, 130, 323, +-2271, -1435, -2530, -1592, -397, -385, 1934, 772, +2197, 1002, 588, 709, -1104, 74, -1569, -564, +-874, -1003, 306, -757, 1074, 193, 891, 1240, +110, 1287, -728, -92, -637, -1507, 41, -1417, +393, 334, 110, 1710, -300, 1043, -269, -825, +338, -1519, 646, -352, 214, 975, -380, 921, +-705, 67, -657, -480, 15, -669, 923, -703, +1174, 91, 344, 1259, -971, 1409, -1491, -181, +-533, -2160, 811, -1800, 1183, 904, 570, 2698, +-57, 1232, -512, -1458, -873, -2117, -842, -450, +26, 1190, 1170, 1025, 1410, -3, 117, -259, +-1301, 23, -1210, -314, 73, -796, 800, -223, +455, 1098, -82, 1075, 27, -415, 307, -1413, +-142, -490, -768, 1041, -442, 1066, 353, -285, +549, -1147, 280, -439, 73, 604, 87, 817, +-177, 145, -729, -382, -824, -414, 181, -299, +1330, -195, 1201, 297, -222, 811, -1445, 574, +-1147, -365, 33, -1183, 955, -779, 1061, 523, +463, 1326, -513, 656, -993, -632, -735, -1099, +134, -303, 939, 609, 718, 523, -135, -129, +-594, -259, -296, 128, -22, 220, 45, -197, +144, -385, 298, -2, 125, 398, -265, 150, +-370, -257, -27, -207, 492, 248, 499, 426, +-346, -108, -1009, -668, -331, -510, 828, 399, +1164, 952, 356, 493, -1064, -549, -1487, -893, +-279, -396, 1189, 306, 1441, 589, 333, 439, +-1115, 48, -1334, -238, -121, -348, 909, -415, +748, -304, -104, 240, -456, 849, 21, 659, +320, -317, -242, -901, -723, -577, -246, 162, +874, 443, 1081, 289, -138, 304, -1162, 426, +-734, -160, 281, -1154, 845, -1021, 462, 497, +-236, 1630, -529, 913, -101, -770, 87, -1360, +86, -303, 113, 615, 41, 374, -127, -290, +-43, 73, 74, 796, 126, 462, 39, -959, +-258, -1423, -247, -219, 178, 1269, 366, 1339, +106, 166, -206, -819, -289, -920, -71, -640, +110, -85, 240, 824, 249, 1380, -85, 592, +-487, -960, -288, -1616, 245, -622, 674, 791, +377, 1171, -549, 600, -856, -152, -128, -490, +657, -678, 616, -772, 76, -184, -319, 1093, +-349, 1614, -279, 334, -189, -1525, 106, -1894, +603, -200, 792, 1754, 11, 1696, -1031, -208, +-988, -1602, -17, -1017, 908, 537, 1044, 1058, +180, 240, -803, -576, -684, -334, -46, 336, +64, 327, 52, -360, 236, -539, 583, 179, +669, 750, -257, 352, -1415, -624, -1151, -933, +515, -36, 1622, 1190, 1188, 925, -325, -657, +-1376, -1596, -932, -528, 13, 1276, 421, 1546, +573, 15, 812, -1477, 608, -1208, -474, 282, +-1577, 1283, -1286, 803, 532, -316, 1916, -877, +1342, -500, -462, 294, -1599, 507, -1182, 64, +182, -292, 1094, 4, 917, 321, -40, 131, +-588, -348, -416, -533, 20, -76, 53, 557, +-77, 651, 10, -10, 295, -704, 303, -528, +-24, 293, -295, 610, -241, 71, -57, -541, +12, -276, -16, 461, 213, 673, 484, -107, +173, -877, -471, -642, -691, 324, -145, 953, +532, 561, 534, -202, -82, -655, -218, -627, +7, -199, 10, 322, -296, 660, -278, 525, +229, 150, 556, -490, 86, -818, -414, -633, +-206, 127, 391, 980, 217, 1131, -508, 242, +-750, -1026, 90, -1404, 1147, -437, 1032, 910, +-277, 1241, -1490, 364, -1216, -496, 228, -553, +1355, -240, 1340, -284, 258, -323, -1064, 343, +-1466, 1123, -535, 761, 642, -527, 1047, -1360, +707, -869, 130, 422, -460, 1148, -737, 755, +-791, -80, -375, -573, 659, -686, 1386, -436, +917, 132, -458, 717, -1429, 696, -1185, -3, +-1, -603, 1059, -455, 1152, -68, 439, 131, +-293, 202, -833, 330, -954, 231, -440, -176, +432, -500, 1008, -275, 955, 290, 324, 502, +-683, 37, -1463, -444, -1231, -281, 334, 346, +1979, 396, 1792, -67, -347, -387, -2074, -217, +-1634, 93, 347, 231, 1614, 149, 1018, 39, +-191, 70, -770, -73, -481, -311, -93, -413, +31, -22, 155, 612, 443, 887, 236, 50, +-324, -1104, -381, -1154, 145, 282, 449, 1385, +-84, 812, -760, -626, -308, -1041, 774, -192, +904, 586, 2, 350, -921, -340, -697, -283, +180, 348, 429, 606, 225, -89, 316, -748, +317, -617, -220, 180, -850, 776, -791, 698, +298, -7, 1283, -766, 896, -770, -524, -56, +-1313, 651, -615, 601, 596, 51, 930, -387, +266, -255, -415, 70, -461, 33, -130, -303, +200, -184, 236, 427, 72, 770, -92, 198, +-169, -688, -173, -969, 103, -302, 394, 640, +201, 1014, -275, 549, -474, -374, -280, -1119, +295, -896, 639, 385, 380, 1283, -260, 667, +-704, -643, -512, -898, 159, -50, 686, 625, +688, 172, -41, -486, -772, -300, -633, 459, +128, 601, 533, -70, 439, -580, -39, -369, +-325, 88, -161, 186, -9, 205, -93, 298, +45, 231, 308, -231, 135, -658, -232, -465, +-248, 236, 127, 838, 381, 542, -63, -200, +-697, -816, -291, -488, 867, 225, 940, 584, +-331, 207, -1247, -170, -672, -157, 679, 108, +1134, 35, 278, -341, -587, -318, -558, 252, +-143, 602, -52, 256, 91, -382, 505, -589, +648, -117, -74, 364, -912, 264, -717, -24, +263, 62, 819, 143, 416, -248, -293, -591, +-314, -159, 70, 727, -98, 836, -389, -171, +-137, -1120, 534, -658, 662, 650, 47, 1089, +-571, 107, -534, -729, -159, -525, 140, 130, +373, 242, 480, 108, 328, 174, -224, 303, +-858, -95, -641, -742, 216, -509, 825, 519, +730, 1020, 34, 219, -684, -813, -680, -827, +-149, 133, 282, 775, 439, 442, 306, -346, +72, -487, -101, -28, -263, 252, -455, 56, +-287, -20, 243, 128, 625, 49, 547, -351, +-170, -386, -639, 258, -373, 796, -8, 394, +179, -708, 171, -1163, 205, -306, 396, 1174, +267, 1507, -577, 65, -1051, -1637, -300, -1526, +791, 270, 1148, 1703, 426, 1291, -734, -403, +-974, -1503, -343, -958, 282, 474, 495, 1056, +444, 454, 265, -354, -88, -377, -506, -46, +-601, 14, -216, -180, 364, -91, 694, 288, +420, 351, -41, 30, -461, -243, -645, -192, +-450, -74, 296, -23, 869, -36, 661, 97, +-149, 347, -842, 320, -638, -161, 87, -617, +511, -417, 393, 191, 96, 528, -103, 331, +-81, 56, -221, -76, -373, -314, -103, -596, +362, -421, 516, 474, 205, 1183, -287, 684, +-456, -792, -196, -1479, -2, -471, 148, 997, +372, 1092, 312, 6, -12, -583, -344, -204, +-537, -6, -199, -367, 433, -327, 592, 514, +200, 1089, -373, 268, -539, -1147, -108, -1196, +400, 305, 273, 1329, -114, 619, -303, -673, +-68, -925, 338, -74, 326, 582, -159, 414, +-463, -68, -355, -237, 59, -236, 652, -200, +571, 83, -141, 439, -621, 368, -590, -146, +-134, -553, 520, -423, 693, 104, 270, 625, +-276, 460, -599, -154, -463, -483, -38, -311, +415, -58, 605, 154, 312, 375, -187, 301, +-530, -31, -599, -304, -196, -343, 587, -267, +878, 40, 259, 574, -695, 717, -931, -51, +8, -962, 917, -792, 488, 331, -698, 1055, +-784, 456, 466, -566, 1214, -636, 181, 72, +-1376, 304, -1237, -137, 641, -164, 1736, 439, +653, 569, -1061, -290, -1236, -1057, -64, -445, +686, 893, 494, 1161, 13, -89, -40, -1124, +-5, -657, -316, 425, -465, 696, 68, 182, +567, -181, 303, -156, -195, -66, -264, -245, +-29, -243, -25, 207, -117, 674, -26, 364, +399, -511, 390, -822, -306, -179, -779, 643, +-108, 641, 826, -37, 581, -547, -413, -284, +-885, 261, -192, 223, 700, -227, 650, -244, +-124, 251, -519, 492, -347, 98, -41, -557, +200, -587, 377, 63, 374, 662, -37, 450, +-588, -165, -585, -467, 181, -211, 678, 75, +326, 106, -231, 72, -354, 160, -103, 156, +44, -74, -46, -292, 64, -181, 316, 71, +161, 136, -345, 36, -325, 122, 226, 251, +369, 38, -194, -523, -601, -665, 74, 168, +888, 1005, 493, 647, -736, -589, -1172, -1068, +-56, -221, 1152, 864, 867, 698, -386, -411, +-940, -798, -370, 46, 388, 846, 465, 367, +38, -755, -157, -901, 14, 225, 25, 1077, +-147, 521, -142, -615, 20, -819, 123, -41, +154, 564, 110, 261, -34, -311, -275, -206, +-235, 340, 138, 427, 391, -244, 96, -705, +-361, -341, -283, 455, 229, 764, 415, 289, +45, -400, -369, -582, -379, -283, -54, 34, +384, 306, 503, 481, 183, 350, -328, -131, +-758, -607, -454, -618, 505, 8, 978, 677, +368, 608, -587, -16, -821, -410, -131, -304, +463, -122, 188, -158, -87, -6, 248, 502, +489, 725, -178, 55, -986, -929, -727, -995, +633, 155, 1374, 1157, 406, 825, -955, -374, +-952, -1033, 79, -441, 605, 474, 190, 624, +-212, 37, 108, -255, 438, -102, -70, -63, +-789, -146, -548, -10, 550, 374, 984, 402, +175, -202, -814, -805, -616, -487, 329, 693, +692, 1230, -50, 220, -639, -1246, -190, -1233, +525, 217, 503, 1352, -142, 917, -590, -399, +-300, -1051, 284, -517, 289, 278, 39, 462, +-1, 233, 54, 78, 33, 132, -233, -67, +-365, -558, -97, -602, 417, 136, 509, 904, +190, 716, -294, -269, -643, -951, -475, -542, +205, 336, 801, 594, 647, 229, -184, -108, +-812, -95, -533, -74, 16, -254, 519, -377, +600, 104, 173, 728, -313, 631, -559, -424, +-475, -1158, 105, -486, 814, 961, 648, 1302, +-300, -63, -958, -1404, -556, -984, 550, 663, +963, 1403, 210, 457, -621, -852, -594, -1074, +-126, -161, 294, 674, 405, 642, 362, 151, +75, -158, -457, -371, -753, -511, -228, -244, +677, 388, 936, 717, 194, 374, -777, -329, +-814, -687, -36, -407, 468, 173, 473, 440, +215, 314, -8, 185, -266, -26, -490, -390, +-367, -606, 217, -193, 729, 463, 526, 793, +-327, 424, -789, -467, -316, -993, 387, -496, +486, 606, 98, 1022, -221, 220, -189, -768, +-16, -653, 90, 269, 39, 631, 46, -10, +-60, -558, -161, -193, -17, 516, 241, 490, +336, -203, -95, -588, -590, -259, -382, 278, +395, 408, 721, 108, 119, -121, -535, -139, +-440, -90, 179, -81, 269, -1, -48, 72, +-175, 23, 212, 100, 427, 303, -48, 103, +-732, -536, -531, -726, 484, 83, 964, 1002, +236, 823, -775, -417, -738, -1207, 186, -519, +688, 696, 179, 849, -419, 23, -210, -490, +378, -145, 327, 170, -453, -160, -707, -351, +109, 167, 967, 647, 659, 250, -603, -397, +-1249, -549, -303, -207, 996, 264, 1072, 548, +-150, 389, -1051, -341, -548, -819, 407, -169, +575, 781, 95, 583, -143, -443, -64, -686, +-20, 26, -231, 503, -253, 180, 169, -185, +488, -93, 292, 80, -190, -82, -580, -282, +-487, -91, 299, 379, 819, 605, 354, 123, +-486, -730, -787, -1015, -146, -39, 630, 1280, +581, 1190, -126, -384, -540, -1534, -380, -894, +159, 620, 607, 1280, 339, 568, -382, -443, +-695, -855, -186, -624, 579, 105, 723, 867, +8, 840, -689, -308, -601, -1132, 48, -460, +639, 807, 584, 832, -52, -220, -650, -684, +-595, -264, 245, 234, 697, 389, 148, 228, +-372, -174, -196, -350, 105, -66, 44, 222, +-80, -58, -101, -211, 176, 330, 293, 678, +-80, -262, -419, -1186, -128, -335, 251, 1155, +243, 944, 99, -549, -193, -1016, -246, -91, +-25, 627, 249, 393, 6, -211, -120, -524, +190, -45, 169, 615, -333, 381, -427, -571, +152, -734, 526, 179, 425, 868, -274, 373, +-843, -667, -337, -749, 714, 283, 725, 889, +-41, 98, -497, -764, -565, -446, -156, 314, +526, 451, 624, 359, 24, 89, -387, -588, +-442, -804, -382, -15, 189, 823, 851, 822, +622, 163, -569, -759, -1067, -1130, -406, -296, +650, 977, 1159, 1153, 311, 115, -1007, -880, +-914, -803, 168, -73, 622, 444, 464, 501, +193, 255, -378, -62, -628, -380, -159, -387, +320, -102, 430, 257, 369, 388, -229, 225, +-622, -185, -291, -446, 340, -147, 568, 277, +135, 323, -433, 33, -429, -321, 140, -376, +403, 208, 24, 677, -201, 102, -50, -729, +57, -562, 100, 427, -4, 796, -225, 79, +-152, -696, 306, -404, 363, 433, -46, 508, +-494, -205, -405, -535, 283, -34, 676, 414, +88, 342, -478, -134, -238, -347, 32, -210, +82, 68, 79, 122, 128, 188, 204, 329, +-71, -43, -455, -532, -161, -369, 368, 205, +273, 432, -71, 270, -271, -57, -78, -331, +306, -225, 161, 76, -394, 22, -301, -39, +247, 298, 450, 457, 140, -263, -251, -851, +-483, -162, -111, 827, 408, 493, 378, -456, +-119, -529, -355, 111, -8, 379, 280, 88, +47, -254, -395, -244, -173, 188, 483, 344, +436, -88, -321, -434, -517, -33, 10, 484, +298, 221, 172, -384, -70, -501, -143, 41, +-5, 569, 95, 494, -13, -253, -111, -710, +-54, -246, 35, 417, 124, 389, 65, 16, +-109, -80, -104, -57, 155, -75, 32, -216, +-420, -227, -83, 107, 657, 635, 295, 467, +-546, -446, -382, -879, 64, -146, 200, 599, +334, 404, 43, -96, -275, -78, -77, 19, +58, -160, -51, -376, -22, -115, 47, 446, +252, 566, 189, -11, -413, -546, -453, -425, +350, 137, 501, 472, -22, 105, -337, -359, +-339, -70, 70, 526, 533, 86, 229, -751, +-461, -421, -382, 710, 199, 672, 381, -325, +-104, -590, -235, -48, 109, 291, 197, 241, +-38, 1, -210, -391, -244, -152, -111, 331, +386, 296, 585, -41, 98, -122, -839, -313, +-838, -380, 254, 244, 1051, 729, 610, 315, +-371, -407, -972, -600, -560, -459, 538, 176, +822, 888, 123, 633, -503, -545, -277, -833, +241, -78, 102, 246, -401, 217, -128, 287, +639, 273, 444, -197, -309, -553, -781, -499, +-179, 267, 808, 948, 475, 409, -582, -826, +-431, -851, 382, 303, 351, 814, -53, 174, +-330, -450, -282, -366, 229, 10, 494, 329, +27, 179, -375, -252, -170, -12, 161, 387, +63, -245, -227, -826, 180, 165, 377, 1291, +-168, 337, -415, -1226, -148, -916, 222, 658, +360, 979, -76, -5, -384, -559, 137, -275, +285, 170, -368, 224, -384, -104, 311, -282, +638, 226, 62, 526, -775, -129, -562, -789, +449, -206, 729, 830, 195, 509, -461, -639, +-620, -715, 54, 405, 402, 804, 111, -31, +201, -851, 87, -437, -531, 703, -200, 786, +366, -295, 112, -880, 35, -40, 60, 672, +-200, 165, 20, -524, 266, -83, -44, 596, +-377, 74, -117, -709, 417, -317, 521, 595, +-139, 619, -536, -180, -259, -738, 127, -314, +337, 696, 178, 631, -68, -567, 120, -866, +-125, 493, -698, 1115, -126, -332, 617, -1350, +598, -65, 20, 1477, -726, 578, -710, -1282, +307, -1074, 656, 860, 138, 1301, -170, -275, +-354, -1278, -40, -263, 98, 1053, -333, 658, +-5, -774, 806, -955, 300, 546, -845, 1263, +-782, -207, 176, -1604, 1010, -450, 562, 1710, +-676, 1334, -840, -1221, 190, -2023, 685, 244, +93, 2098, -522, 693, -57, -1582, 704, -1251, +180, 978, -756, 1482, -543, -452, 499, -1689, +999, -200, 136, 1836, -1059, 1050, -601, -1500, +768, -1791, 777, 707, -162, 1981, -704, 170, +-399, -1689, 550, -775, 742, 1307, -305, 1090, +-672, -863, 61, -1407, 292, 333, -21, 1534, +-80, 274, 135, -1345, 104, -657, -150, 1021, +-391, 735, -172, -862, 420, -846, 431, 766, +-344, 1270, -529, -317, 168, -1649, 373, -493, +-177, 1413, -376, 1222, 10, -664, 408, -1351, +346, -86, -304, 1174, -729, 373, -232, -1083, +872, -568, 822, 1182, -542, 1027, -1113, -1083, +78, -1586, 959, 512, 361, 1811, -452, 248, +-553, -1548, 185, -808, 642, 963, -21, 1196, +-648, -396, 34, -1381, 687, -243, 317, 1399, +-523, 824, -703, -1143, 247, -1188, 954, 705, +187, 1438, -850, -441, -370, -1583, 669, -1, +413, 1917, -711, 610, -427, -1778, 717, -1496, +548, 1055, -420, 1972, -747, -29, -121, -1630, +565, -792, 473, 1081, -504, 951, -491, -692, +547, -1056, 407, 606, -758, 1403, -903, -354, +598, -1759, 1357, -294, 69, 1786, -1529, 866, +-899, -1439, 1082, -1116, 1295, 1127, -538, 1197, +-1369, -925, 196, -1409, 1233, 503, 148, 1633, +-1025, 195, -474, -1456, 664, -815, 772, 1037, +-327, 899, -744, -837, 506, -855, 770, 1103, +-622, 1265, -1057, -1222, 403, -2154, 1408, 578, +611, 2724, -1206, 769, -1456, -2449, 707, -1979, +1689, 1547, -42, 2549, -1494, -608, -347, -2754, +1350, -172, 988, 2764, -1134, 1204, -1702, -2381, +363, -2401, 1890, 1149, 762, 3073, -1250, 565, +-1424, -2652, 128, -1721, 1037, 1443, 463, 1786, +-366, -525, -418, -1092, -213, 414, 164, 541, +85, -792, -97, -651, 120, 1023, -41, 1252, +-495, -581, -72, -2002, 884, -431, 359, 2221, +-955, 1776, -1053, -1612, 425, -2632, 1312, 273, +470, 2445, -800, 936, -1033, -1470, 85, -1280, +957, 724, 280, 1031, -604, -787, -27, -1197, +517, 1000, 88, 2147, -442, -343, -558, -2880, +338, -1230, 1159, 2391, 133, 2586, -1234, -863, +-428, -2808, 1001, -692, 907, 2229, -575, 1567, +-1419, -1560, 123, -1968, 1629, 874, 624, 2230, +-1037, 108, -1117, -2112, -73, -1275, 938, 1302, +633, 2111, -465, -243, -265, -2203, 233, -633, +-205, 1867, -692, 1222, -145, -1356, 641, -1675, +900, 494, -65, 1788, -1046, 648, -710, -1162, +242, -1389, 628, 74, 134, 1127, -173, 533, +203, -340, 289, -129, -761, 132, -1008, -542, +200, -875, 1364, 316, 1061, 1721, -684, 847, +-1802, -1566, -429, -1960, 1539, 499, 1154, 2154, +-616, 578, -1238, -1562, -124, -1190, 1257, 885, +769, 1414, -897, -288, -1126, -1477, 353, -339, +1102, 1202, 350, 857, -450, -582, -477, -850, +85, 59, 262, 462, -167, -169, -259, -307, +481, 530, 764, 837, -300, -421, -1030, -1392, +-374, -472, 630, 1236, 657, 1280, 14, -286, +-372, -1208, -227, -496, -258, 491, -159, 348, +355, -74, 372, 235, -129, 609, -484, -381, +-101, -1291, 271, -408, 197, 1268, -412, 1224, +-438, -272, 404, -1352, 561, -692, 49, 691, +-663, 937, -660, -20, 258, -609, 1034, -146, +193, 210, -856, 123, -396, -88, 341, 36, +490, -24, 90, -303, -360, 0, -306, 661, +351, 534, 418, -694, -63, -1279, -211, -183, +-121, 1566, -65, 1386, 145, -735, 516, -1973, +128, -644, -355, 1363, -317, 1566, -40, -95, +244, -1558, 325, -937, 134, 779, -161, 1480, +-183, 185, -241, -1290, -107, -1156, 168, 401, +417, 1607, 261, 997, -289, -1046, -742, -2132, +-273, -380, 527, 2099, 613, 1859, -53, -827, +-619, -2478, -334, -920, 153, 1954, 229, 2281, +17, -577, -17, -2727, 43, -1141, -200, 2044, +-417, 2460, 122, -394, 749, -2615, 243, -1365, +-963, 1355, -901, 2223, 569, 336, 1574, -1677, +609, -1361, -1495, 611, -1876, 1274, 245, 34, +2313, -887, 1605, -82, -979, 959, -2452, 187, +-1252, -1258, 1711, -869, 2654, 1171, 519, 1719, +-2102, -241, -2159, -2101, 172, -1102, 2279, 1458, +1779, 2119, -968, 114, -2264, -2120, -630, -1724, +1638, 863, 1366, 2337, -571, 726, -1297, -1431, +8, -1381, 1045, -3, 104, 693, -1320, 398, +-586, 167, 1698, 400, 1631, 236, -1280, -829, +-2818, -1581, -483, -274, 2612, 1883, 2358, 2114, +-949, -436, -2930, -2459, -1076, -1502, 1588, 1042, +1824, 1947, -98, 459, -1214, -1065, -371, -711, +560, 521, -107, 258, -649, -752, 30, -503, +976, 775, 876, 1054, -537, 92, -1436, -726, +-401, -811, 978, -343, 938, 177, 96, 808, +-686, 973, -471, 54, 343, -1169, 400, -1128, +-90, 406, -310, 1237, -256, 289, 434, -1040, +981, -376, -8, 1259, -1158, 913, -852, -1454, +414, -2103, 1268, 404, 786, 2660, -786, 1647, +-1234, -1556, -28, -2679, 805, -581, 417, 1938, +-417, 1721, -514, -289, 252, -1405, 623, -646, +-4, 592, -637, 599, -647, -58, -115, -339, +706, -247, 957, 0, 285, 561, -986, 742, +-1669, -397, -324, -1484, 1749, -771, 1805, 1296, +-436, 2084, -2150, 272, -1172, -2132, 1177, -2213, +1753, 469, -3, 2752, -1196, 1785, -472, -1232, +565, -2725, 240, -1253, -494, 1388, 119, 2662, +921, 1169, 310, -1609, -1044, -2764, -1152, -1159, +342, 1714, 1824, 3188, 985, 1351, -1187, -2474, +-1744, -3811, -279, -543, 1158, 3562, 1390, 3224, +384, -862, -850, -3516, -1286, -1801, -772, 1565, +677, 2480, 1817, 632, 849, -1339, -1248, -1331, +-2019, -204, -246, 616, 1888, 802, 1527, 512, +-1044, -165, -2156, -1028, -94, -1005, 2042, 366, +1302, 1726, -1575, 1070, -2305, -1145, 251, -2034, +2493, -523, 1183, 1518, -1517, 1676, -2098, 229, +-30, -1077, 1810, -1272, 999, -674, -909, 268, +-1126, 1380, 360, 1677, 766, 186, -143, -2230, +-712, -2449, 2, 333, 785, 2999, 410, 2229, +-435, -1113, -674, -3031, 27, -1532, 424, 1652, +270, 2541, 37, 537, 97, -1616, -117, -1620, +-392, -208, -195, 936, 348, 1327, 616, 770, +159, -727, -539, -2046, -677, -1307, 166, 1444, +799, 3055, 452, 1103, -462, -2640, -892, -3571, +-337, -201, 782, 3608, 1219, 3023, -16, -978, +-1448, -3321, -1234, -1646, 502, 1177, 1822, 1870, +1056, 764, -1248, -203, -2243, -447, -176, -841, +1973, -1040, 1402, -105, -988, 1383, -1813, 1696, +-235, 24, 1615, -1721, 1068, -1515, -1071, 247, +-1550, 1368, -85, 905, 1490, 99, 1303, -515, +-263, -855, -1698, -935, -1428, 22, 525, 1448, +2165, 1639, 1529, -158, -1056, -2315, -2310, -1905, +-1015, 1020, 1346, 2999, 2076, 1188, 550, -1975, +-1317, -2555, -1465, -233, 53, 1950, 981, 1667, +524, -386, -71, -1415, 68, -384, -41, 550, +-760, -87, -626, -716, 475, 290, 1436, 1662, +694, 1067, -1276, -1459, -1919, -2906, 28, -924, +1924, 2638, 1342, 3402, -593, 348, -1723, -3184, +-859, -3171, 678, 39, 834, 3105, 213, 2714, +396, -371, 249, -2568, -1042, -1683, -1779, 418, +-498, 1239, 2177, 799, 2762, 177, -274, 59, +-3426, -240, -2400, -738, 1344, -1098, 3376, -222, +1365, 1396, -1920, 1976, -2316, 387, -200, -1952, +1356, -2300, 1118, -441, -146, 2004, -665, 2520, +-43, 584, 327, -1911, -137, -2362, -373, -843, +-357, 1133, 304, 2442, 1356, 1816, 878, -781, +-1147, -2993, -2416, -2386, -778, 494, 2585, 3258, +3388, 2986, -441, -340, -4097, -3622, -2701, -3188, +2008, 382, 4248, 3290, 1454, 2977, -2867, 114, +-3466, -2655, -140, -3155, 2597, -778, 2023, 2319, +-427, 3206, -1410, 981, -847, -2076, -530, -2954, +105, -721, 1367, 1937, 1397, 2134, -532, 40, +-2122, -1532, -1201, -946, 1382, 705, 2365, 1020, +51, -275, -2409, -1245, -1731, -587, 1206, 1017, +2796, 1873, 869, 844, -2205, -1516, -2835, -2751, +-214, -1234, 2775, 1960, 2924, 3640, -111, 1635, +-3029, -2258, -2991, -4201, 105, -1959, 3338, 2427, +3303, 4529, -330, 1933, -3374, -2543, -2795, -4126, +336, -1537, 2765, 2170, 2493, 3393, 109, 1187, +-1799, -1902, -2222, -2659, -1003, -660, 1066, 1734, +2505, 1897, 1860, -39, -690, -1703, -3033, -1243, +-2503, 560, 854, 1660, 3674, 949, 2612, -756, +-1357, -1858, -4286, -1254, -2466, 704, 2218, 2247, +4452, 1620, 1709, -592, -2955, -2320, -4161, -1986, +-859, 93, 2999, 2026, 3271, 2275, 237, 771, +-2474, -1253, -2283, -2693, -254, -1967, 1323, 750, +1545, 3144, 759, 2575, -362, -428, -1143, -2865, +-1425, -2548, -511, -8, 1248, 2238, 2066, 2322, +699, 487, -1564, -1414, -2176, -1818, -348, -960, +1850, 709, 1903, 1827, -26, 1158, -1868, -926, +-1596, -1973, 552, -360, 2155, 2013, 1289, 1638, +-1000, -1480, -2227, -2775, -1075, -185, 1459, 2740, +2386, 2125, 723, -767, -1462, -2403, -1916, -1390, +-754, 415, 748, 1121, 1434, 1059, 1241, 979, +590, 338, -1087, -1589, -2599, -2871, -1879, -1173, +1400, 2575, 3857, 4114, 2425, 968, -1988, -3446, +-4721, -4100, -2344, -357, 2474, 3176, 4505, 3132, +1718, 401, -2466, -2135, -3575, -2502, -1246, -895, +1493, 1284, 2420, 2211, 1506, 1288, -471, -767, +-2054, -2035, -1997, -1262, -55, 526, 2061, 1576, +2249, 1045, 63, 65, -2155, -559, -1877, -1142, +190, -1178, 1689, 19, 1209, 1778, 214, 2005, +-670, 191, -946, -2143, -871, -2480, -89, -205, +928, 2312, 1699, 2429, 897, 259, -1219, -1729, +-2158, -1922, -939, -653, 1110, 533, 2043, 1338, +1300, 1594, -640, 570, -1811, -1391, -1467, -2272, +77, -853, 1453, 1264, 1564, 1874, 279, 865, +-1121, -488, -1366, -1228, -347, -1193, 747, -237, +693, 667, -70, 938, -274, 575, 229, 42, +572, -491, -340, -753, -1569, -735, -996, -348, +1200, 655, 2395, 1758, 818, 1321, -1756, -1128, +-2604, -2872, -742, -1474, 1716, 1779, 2531, 3328, +884, 1158, -1540, -2307, -2477, -3206, -1107, -231, +1360, 2568, 2562, 2087, 1296, -483, -1358, -1597, +-2436, -579, -1144, 343, 1183, -86, 1980, -385, +1023, 783, -298, 1872, -1117, 576, -1387, -2183, +-961, -2874, 668, -67, 2242, 3179, 1996, 2970, +-493, -473, -2906, -3311, -2249, -2243, 676, 984, +2762, 2169, 1837, 740, -750, -596, -1794, -249, +-620, 297, 358, -305, 34, -1362, -401, -922, +169, 942, 1378, 2108, 1355, 1096, -541, -1050, +-2446, -2085, -1980, -1119, 450, 589, 2493, 1184, +2281, 767, 23, 288, -2023, 112, -2257, -487, +-718, -1180, 944, -1096, 1778, 128, 1401, 1281, +8, 1461, -1257, 639, -1408, -660, -514, -1448, +159, -1459, 628, -430, 1053, 1110, 996, 2200, +213, 1561, -1068, -465, -1771, -2331, -1004, -2218, +898, -159, 1872, 1801, 1283, 2115, 11, 990, +-1044, -431, -1546, -1513, -1068, -1724, 385, -985, +1589, 599, 1538, 2186, 294, 2420, -1019, 426, +-1319, -2394, -533, -3244, -1, -1070, 193, 2036, +921, 3281, 1595, 1560, 578, -1463, -1412, -2923, +-2375, -1514, -948, 933, 1582, 1906, 2164, 1031, +365, -334, -1007, -911, -672, -537, 2, 43, +-376, 4, -817, -333, -230, -73, 1286, 880, +1810, 945, 467, -218, -1528, -1255, -2158, -1046, +-1031, 185, 838, 1227, 2011, 835, 1790, -371, +152, -817, -1765, -119, -2254, 274, -877, -23, +1150, -361, 2040, 32, 1340, 722, -251, 582, +-1192, -340, -1401, -806, -876, -292, 202, 123, +1523, 268, 1689, 568, 449, 666, -1210, -51, +-1760, -1092, -843, -1142, 731, 194, 1482, 1771, +907, 1440, -169, -731, -810, -2221, -794, -1081, +-225, 1305, 474, 2210, 574, 632, 50, -1664, +-363, -1916, -178, -161, 403, 1463, 682, 1387, +-237, 234, -1317, -797, -968, -1245, 678, -910, +1760, 302, 1059, 1429, -708, 1329, -1801, -125, +-1150, -1590, 444, -1572, 1206, 101, 877, 1513, +204, 1072, -217, -156, -709, -665, -1126, -554, +-685, -462, 624, -173, 1726, 563, 1213, 986, +-675, 331, -1971, -927, -1021, -1141, 775, 287, +1390, 1503, 575, 430, -583, -1506, -764, -1313, +75, 1030, 501, 2102, 28, 428, -418, -1733, +-219, -1720, 153, 271, 398, 1440, 480, 839, +165, -117, -454, -267, -772, -178, -383, -543, +515, -678, 832, -23, 395, 1027, -232, 1169, +-518, 221, -348, -1002, -95, -1240, 79, -426, +202, 507, 359, 915, 267, 821, 12, 172, +-305, -757, -534, -1125, -265, -407, 98, 649, +331, 927, 431, 28, 302, -689, -23, -119, +-477, 744, -667, 243, -383, -1067, 251, -1176, +582, 283, 701, 1599, 417, 1189, -407, -347, +-1026, -1559, -915, -1232, -95, 140, 914, 1103, +1391, 929, 723, 280, -641, -351, -1665, -719, +-1140, -627, 443, -89, 1458, 472, 1012, 591, +-79, 158, -709, -59, -576, 190, -137, -32, +-162, -859, -238, -888, 338, 376, 1147, 1425, +990, 991, -429, -411, -1723, -1191, -1352, -731, +545, 168, 1668, 462, 1014, 338, -371, 541, +-744, 573, -276, -314, -269, -1336, -573, -1004, +-147, 442, 874, 1500, 1435, 1111, 531, -386, +-1286, -1288, -1914, -910, -339, 54, 1317, 663, +1194, 805, 72, 416, -528, -252, -397, -832, +-72, -844, -143, -43, -314, 929, -114, 1001, +475, -20, 803, -914, 291, -827, -501, -42, +-810, 517, -480, 701, 58, 358, 602, -359, +638, -849, 274, -339, -199, 412, -439, 525, +-449, 82, -300, -96, -7, 50, 500, 79, +796, -353, 344, -590, -425, -17, -742, 799, +-397, 805, 78, -92, 255, -770, 337, -620, +416, -24, 373, 354, -44, 419, -701, 446, +-953, 370, -335, -292, 816, -1095, 1038, -791, +572, 599, -141, 1300, -734, 520, -1040, -494, +-729, -790, 277, -440, 1345, 70, 1451, 364, +207, 462, -1414, 279, -1812, -194, -487, -684, +1180, -279, 1471, 617, 449, 524, -493, -560, +-790, -875, -302, 216, -120, 1110, -307, 557, +25, -601, 911, -1049, 858, -507, 25, 385, +-784, 878, -1028, 646, -453, -67, 429, -726, +764, -868, 871, -179, 386, 790, -642, 785, +-1186, -141, -719, -686, 429, -61, 1218, 681, +692, 235, -517, -1006, -691, -1051, 26, 644, +355, 1897, -106, 752, -581, -1335, -199, -1789, +639, -217, 883, 1241, 337, 1169, -587, 65, +-1107, -640, -681, -488, 305, -142, 995, -1, +1070, 135, 231, 307, -858, 218, -1202, -86, +-574, -167, 463, 16, 957, 85, 622, -198, +-15, -404, -256, -13, -516, 550, -594, 566, +-334, -41, 325, -601, 728, -482, 550, -66, +89, 156, -301, 184, -544, 487, -664, 533, +-400, -69, 182, -1041, 1035, -1118, 1415, 151, +314, 1476, -1377, 1098, -1948, -466, -870, -1204, +1197, -567, 2249, 200, 1175, 366, -729, 367, +-1670, 446, -1377, 176, -203, -548, 971, -855, +1388, -171, 1025, 750, -115, 745, -1234, -165, +-1366, -609, -485, -129, 660, 294, 1254, 40, +846, -283, -22, 67, -476, 550, -822, 224, +-1073, -671, -330, -738, 978, 352, 1602, 1095, +824, 431, -756, -843, -1616, -1051, -1041, -52, +220, 833, 1126, 786, 1181, 208, 342, -415, +-642, -926, -1167, -729, -717, 350, 451, 1258, +1038, 818, 378, -540, -508, -1250, -447, -522, +305, 667, 513, 756, -378, -168, -971, -519, +-103, 328, 1003, 694, 847, -312, -308, -1302, +-869, -494, -223, 1159, 413, 1454, 126, -157, +-434, -1458, -149, -795, 667, 690, 881, 939, +-203, -84, -1173, -693, -775, -110, 312, 607, +943, 408, 723, -396, -89, -755, -537, -279, +-526, 475, -252, 753, 40, 470, 469, -137, +493, -835, -22, -1059, -324, -60, -151, 1411, +101, 1387, -165, -333, -332, -1726, 70, -1001, +514, 900, 379, 1497, -164, 59, -500, -1271, +-110, -483, 317, 1051, -116, 856, -663, -857, +-49, -1389, 1125, 61, 1172, 1566, -398, 1101, +-2000, -753, -1306, -1631, 887, -548, 2030, 948, +1088, 1135, -699, 186, -1505, -609, -977, -697, +107, -271, 818, 330, 1021, 652, 548, 228, +-340, -478, -1038, -595, -903, 86, 219, 688, +991, 360, 610, -565, -173, -828, -462, 136, +-282, 875, 81, 453, 24, -401, -68, -572, +253, -152, 234, 149, -217, 70, -264, 53, +147, 513, 370, 497, 23, -544, -641, -1297, +-483, -348, 551, 1275, 990, 1342, 65, -189, +-935, -1343, -798, -834, 348, 392, 989, 904, +279, 429, -716, -135, -616, -417, 174, -425, +677, -217, 352, 369, -387, 669, -569, 192, +-167, -630, 128, -674, 435, 191, 523, 836, +60, 308, -630, -628, -740, -681, -78, 214, +808, 785, 741, 255, -222, -651, -737, -624, +-241, 251, 393, 657, 401, 342, -273, -310, +-526, -683, 192, -426, 665, 385, 110, 831, +-398, 377, -214, -382, -33, -735, -173, -481, +-268, 149, 439, 640, 1082, 669, 364, 162, +-1229, -531, -1497, -886, 60, -420, 1524, 519, +1126, 883, -392, 327, -983, -272, -331, -325, +112, -373, -165, -476, -112, -19, 649, 806, +1018, 953, -25, -30, -1305, -1127, -1006, -928, +466, 461, 923, 1149, 241, 215, -150, -963, +209, -437, 70, 862, -773, 835, -1004, -636, +202, -1258, 1434, -142, 994, 1014, -621, 820, +-1307, -176, -392, -432, 569, -106, 427, -274, +-90, -757, 40, -136, 393, 1417, 128, 1541, +-581, -388, -735, -2233, 66, -1432, 736, 1040, +379, 2117, -117, 589, 15, -1191, -28, -982, +-535, 236, -659, 334, 165, -380, 1038, -204, +798, 796, -312, 880, -1102, -307, -667, -1292, +327, -636, 823, 701, 374, 949, -260, 41, +-285, -478, -112, -174, 3, 129, -164, 36, +-4, -250, 213, -178, 291, 147, 30, 466, +-189, 293, -260, -114, -162, -522, 149, -500, +228, 16, 43, 612, -133, 639, -34, -74, +191, -659, 112, -365, -362, 246, -423, 223, +183, -135, 686, 24, 281, 473, -494, 280, +-685, -578, 35, -919, 779, 35, 366, 1080, +-644, 764, -734, -528, 326, -1002, 947, -249, +281, 617, -781, 438, -740, -129, 176, -110, +562, 216, 181, -143, -65, -739, 123, -282, +109, 984, -499, 1161, -810, -463, -71, -1675, +1172, -595, 1153, 1357, -372, 1353, -1556, -475, +-866, -1445, 747, -284, 1247, 1093, 282, 686, +-743, -771, -492, -964, 222, 433, 224, 1260, +-288, 141, -329, -1303, 347, -842, 807, 820, +94, 1287, -953, 19, -765, -1155, 422, -716, +956, 554, 284, 988, -692, 213, -597, -697, +242, -717, 585, -37, 96, 624, -416, 668, +-421, 151, 179, -604, 527, -866, 138, -140, +-314, 773, -351, 755, -104, -53, 211, -546, +377, -329, 87, 6, -285, -11, -373, -68, +-74, 353, 352, 630, 436, 122, -47, -722, +-540, -835, -402, -99, 157, 718, 564, 821, +428, 205, -205, -485, -701, -733, -458, -446, +321, 120, 690, 731, 273, 788, -276, -26, +-445, -952, -279, -708, 31, 321, 284, 702, +302, 243, 132, -241, -130, -309, -366, -83, +-260, 123, 65, 128, 346, -21, 202, -16, +-24, -114, -112, -143, -76, 135, -294, 397, +-231, 149, 297, -472, 625, -588, 201, 28, +-573, 724, -738, 570, 89, -278, 752, -727, +296, -308, -310, 328, -255, 429, -67, 148, +-16, -136, -72, -223, 128, -124, 386, 44, +116, 116, -553, 35, -488, -23, 264, 13, +679, 111, 187, -20, -666, -193, -606, -123, +435, 230, 751, 247, -132, -232, -711, -392, +-173, 167, 512, 667, 265, 98, -295, -830, +-328, -702, 132, 469, 367, 1162, 81, 404, +-452, -858, -438, -1114, 260, -117, 567, 896, +257, 875, -265, 34, -577, -711, -509, -733, +289, -84, 894, 646, 434, 622, -537, -115, +-911, -650, -247, -222, 766, 528, 789, 442, +-393, -505, -935, -882, 11, 164, 952, 1272, +366, 740, -798, -931, -845, -1485, 166, -149, +927, 1282, 566, 1060, -358, -368, -735, -1041, +-318, -337, 170, 583, 245, 393, 240, -373, +226, -418, 52, 357, -332, 758, -433, 91, +-244, -824, 89, -843, 415, 114, 522, 948, +195, 840, -478, -98, -819, -962, -428, -819, +543, 168, 945, 860, 153, 547, -672, -205, +-447, -541, 303, -233, 203, 164, -396, 121, +-404, -43, 449, 67, 861, 260, 107, -9, +-883, -412, -804, -254, 249, 337, 758, 500, +185, -86, -383, -576, -58, -355, 440, 384, +-34, 714, -778, 177, -476, -585, 514, -641, +829, -47, 176, 402, -405, 492, -413, 297, +-101, -61, -101, -594, -184, -727, 244, -34, +677, 829, 455, 797, -382, -43, -953, -698, +-621, -661, 345, -93, 823, 443, 493, 545, +-19, 288, -447, -205, -621, -507, -370, -364, +179, 120, 595, 406, 419, 278, -106, -104, +-380, -254, -213, -1, -98, 124, -150, -129, +8, -250, 304, 72, 435, 462, 89, 312, +-546, -333, -597, -654, 146, -138, 529, 524, +130, 567, -299, -14, -193, -539, 183, -469, +302, 92, -136, 535, -441, 366, -127, -136, +207, -496, 215, -284, 103, 150, 7, 390, +4, 232, -126, -138, -355, -226, -279, -89, +144, -40, 432, -99, 551, 106, 122, 404, +-611, 342, -873, -237, -412, -842, 568, -521, +1194, 664, 628, 1196, -708, 231, -1344, -1000, +-641, -1025, 703, 47, 1198, 925, 371, 798, +-719, -69, -865, -815, -87, -644, 571, 191, +361, 680, -242, 330, -317, -238, -29, -415, +90, -137, 135, 229, 138, 221, 17, -28, +-306, -156, -578, -144, -155, 24, 771, 258, +945, 217, -187, -182, -1191, -393, -882, -168, +456, 310, 1166, 454, 464, 33, -561, -423, +-714, -361, -69, 138, 259, 484, 67, 202, +-111, -456, 197, -483, 301, 223, -89, 670, +-391, 291, -297, -462, 28, -787, 304, -249, +229, 668, 35, 876, -75, 133, -194, -713, +-336, -771, -59, -125, 340, 527, 298, 674, +-132, 213, -302, -370, -82, -468, 157, -158, +81, 12, -198, 112, -212, 365, 164, 324, +351, -121, -8, -453, -422, -313, -261, 102, +201, 350, 295, 228, -29, -126, -330, -281, +-87, -37, 330, 316, 194, 201, -405, -387, +-446, -582, 174, 90, 539, 859, 182, 572, +-477, -445, -556, -936, 215, -360, 729, 401, +20, 742, -742, 415, -426, -267, 457, -616, +765, -331, 85, 112, -791, 219, -644, 345, +324, 353, 739, -82, 156, -626, -506, -482, +-364, 275, 280, 614, 400, 267, -242, -213, +-613, -405, -72, -252, 664, 107, 625, 397, +-261, 256, -931, -189, -463, -439, 495, -147, +703, 389, 68, 418, -392, -131, -323, -523, +66, -232, 184, 401, -151, 486, -323, -158, +65, -511, 504, -24, 317, 452, -271, 61, +-757, -479, -361, -194, 421, 549, 551, 545, +195, -381, -242, -899, -333, -165, -158, 859, +-82, 742, -118, -382, 255, -897, 490, -205, +32, 651, -446, 484, -478, -208, -36, -466, +467, -93, 354, 264, -239, 222, -449, -37, +-69, -121, 451, -119, 317, -122, -322, 18, +-553, 315, -103, 292, 288, -185, 492, -515, +312, -171, -269, 470, -723, 385, -526, -305, +293, -403, 916, 316, 554, 510, -494, -295, +-1002, -816, -434, -152, 614, 856, 930, 846, +91, -220, -829, -1075, -618, -684, 252, 438, +638, 1008, 150, 432, -369, -504, -186, -721, +8, -185, -197, 330, -144, 331, 350, 120, +551, -9, 95, -130, -785, -246, -942, -144, +155, 155, 1095, 243, 756, 83, -349, -64, +-971, -136, -662, -202, 234, -92, 715, 217, +490, 436, -31, 81, -430, -478, -548, -519, +-196, 101, 327, 608, 554, 435, 157, -138, +-413, -611, -398, -493, 58, 183, 305, 706, +137, 450, -184, -366, -262, -639, 62, -152, +231, 367, 50, 329, -92, -8, -88, -177, +-111, -118, -86, 43, 45, 74, 136, -23, +169, -84, 18, -5, -263, 145, -306, 128, +-19, -114, 275, -203, 271, -41, -49, 99, +-315, 148, -151, 72, 89, -63, 81, -175, +-26, -76, -53, 61, 57, 141, 48, 105, +-62, -30, -139, -136, -62, -204, 2, -48, +87, 258, 136, 391, -23, -28, -162, -549, +-144, -438, 10, 288, 168, 741, 87, 225, +-127, -543, -102, -588, 52, 66, 40, 507, +-52, 243, -90, -211, -1, -179, 182, 84, +102, 29, -172, -118, -281, -14, -34, 23, +259, -6, 259, 166, -73, 306, -215, -46, +-161, -580, -54, -460, 24, 327, 190, 760, +297, 285, 94, -355, -438, -467, -573, -307, +73, -58, 586, 359, 413, 624, -176, 205, +-504, -478, -312, -505, 131, -9, 336, 124, +118, -18, -138, 238, -108, 563, 71, 113, +12, -724, -174, -793, -247, 139, -13, 824, +539, 502, 478, -188, -453, -440, -927, -330, +-69, -63, 825, 262, 585, 293, -309, -65, +-757, -163, -230, 146, 511, 199, 416, -326, +-125, -475, -288, 162, -142, 631, 75, 203, +134, -462, 22, -421, -39, 185, 76, 399, +108, 30, -148, -305, -378, -152, -74, 28, +504, 199, 473, 375, -200, 122, -584, -561, +-335, -681, 183, 188, 505, 884, 352, 479, +-203, -385, -467, -708, -134, -346, 139, 235, +66, 580, 45, 406, 188, -182, 108, -521, +-119, -278, -355, 178, -266, 236, 190, 46, +500, 181, 160, 239, -329, -381, -311, -726, +-62, 71, 117, 848, 209, 397, 150, -356, +-151, -513, -220, -243, 59, 87, 152, 385, +-48, 357, -106, -9, 11, -339, 155, -397, +164, -65, -176, 336, -446, 361, 81, 16, +649, -164, 173, -214, -533, -260, -452, 3, +142, 456, 548, 328, 333, -254, -351, -396, +-533, -63, 37, 116, 432, 193, 211, 221, +-225, -31, -249, -361, 125, -196, 258, 258, +-84, 282, -265, -83, 20, -184, 228, 53, +69, 45, -109, -142, -53, -22, 87, 227, +-51, 92, -153, -183, 69, -145, 253, 106, +12, 115, -163, -78, -77, -117, 14, 99, +107, 183, 71, -70, -153, -279, -24, -109, +280, 288, 65, 300, -297, -128, -241, -364, +201, -84, 380, 237, -19, 138, -367, -78, +-27, -36, 390, 109, 72, 1, -413, -279, +-293, -250, 302, 203, 627, 561, 239, 276, +-579, -464, -770, -710, -4, -128, 804, 570, +673, 581, -117, 15, -690, -396, -456, -352, +111, -15, 355, 52, 315, 9, 320, 290, +17, 476, -545, -33, -670, -732, 47, -532, +834, 339, 697, 666, -255, 258, -780, -208, +-352, -355, 314, -340, 481, 2, 135, 463, +-164, 326, -83, -251, -37, -383, -151, 100, +4, 314, 334, -36, 131, -292, -312, -92, +-201, 180, 342, 322, 377, 157, -294, -431, +-542, -604, 137, 239, 598, 867, 118, 152, +-346, -709, -200, -466, 88, 318, 282, 491, +33, -56, -297, -431, -126, -9, 399, 584, +428, 196, -121, -759, -638, -787, -464, 474, +482, 1218, 1031, 421, 126, -812, -829, -1087, +-638, -272, 145, 771, 659, 953, 559, 85, +-201, -527, -638, -429, -164, -263, 383, -68, +322, 428, -73, 568, -308, 65, 64, -426, +374, -327, -94, -46, -326, 88, 153, 174, +238, 296, -151, -14, -53, -362, 147, -111, +115, 340, -45, 151, -186, -357, -10, -270, +271, 227, 125, 434, -220, 17, -161, -266, +129, -213, 341, -16, 80, 189, -279, 207, +-246, -181, 75, -342, 208, 254, 256, 584, +180, -53, -115, -750, -429, -425, -241, 353, +350, 736, 501, 361, 35, -398, -278, -775, +-93, -268, 98, 625, 48, 550, -99, -105, +-161, -552, 219, -205, 515, 384, 196, 474, +-463, -240, -597, -700, -14, 11, 473, 723, +451, 276, 213, -563, -28, -350, -437, 362, +-580, 321, -16, -352, 727, -318, 671, 225, +-128, 427, -674, -3, -269, -321, 379, -142, +278, 138, -121, -65, -160, -167, 227, 368, +294, 517, -82, -300, -342, -893, -14, -158, +205, 932, 37, 828, -44, -639, 112, -1371, +307, -22, 217, 1671, -445, 899, -752, -1462, +230, -1771, 1090, 714, 417, 2184, -781, 257, +-621, -1900, 317, -1085, 595, 1232, -54, 1421, +-441, -377, 91, -1413, 618, -329, 94, 1125, +-748, 788, -324, -745, 743, -1034, 688, 560, +-409, 1235, -825, -425, 16, -1628, 848, -35, +582, 1866, -499, 949, -777, -1487, 72, -1717, +589, 488, 288, 1734, -141, 416, -102, -1165, +84, -687, -26, 714, -369, 745, -97, -682, +645, -1027, 618, 567, -309, 1462, -837, -61, +-155, -1532, 722, -580, 523, 1213, -353, 979, +-465, -784, 260, -1219, 506, 334, -223, 1413, +-555, 309, 222, -1321, 729, -959, 98, 880, +-634, 1202, -451, -480, 395, -1063, 835, 439, +194, 1111, -714, -368, -550, -1452, 217, -312, +580, 1397, 478, 1226, -91, -418, -443, -1421, +-277, -792, -62, 614, 246, 1146, 677, 268, +312, -614, -585, -278, -712, 207, 117, -274, +901, -572, 451, 308, -640, 1223, -645, 474, +297, -1201, 656, -1321, 283, 341, -412, 1461, +-514, 631, 213, -830, 405, -1115, 23, -8, +-18, 968, 139, 623, -5, -444, -155, -831, +-340, -155, 102, 651, 724, 495, 260, -232, +-497, -403, -398, -94, 135, 63, 404, 132, +209, 96, -302, 22, -160, 25, 414, 11, +262, -193, -318, -200, -433, 105, 135, 291, +700, 156, 232, -144, -561, -182, -346, -88, +305, -21, 418, 25, 169, 208, -225, 229, +-417, 18, 59, -383, 417, -562, 303, 158, +67, 885, -301, 505, -383, -714, -69, -1027, +425, -6, 508, 1070, 99, 732, -303, -582, +-324, -936, -210, -61, 125, 578, 600, 334, +368, -148, -242, -174, -309, 86, -153, 38, +-123, -398, 253, -281, 504, 556, 224, 812, +-242, -259, -395, -1162, -176, -332, 245, 977, +418, 843, 208, -473, -162, -878, -269, -169, +-43, 671, 126, 563, 215, -281, 152, -747, +-60, -85, -141, 815, -86, 276, 117, -770, +417, -482, 234, 856, -637, 664, -507, -834, +550, -996, 976, 622, 26, 1328, -947, -180, +-552, -1366, 586, -418, 885, 1161, -117, 846, +-553, -777, 21, -1125, 421, 364, -56, 1387, +-498, 92, -89, -1555, 817, -761, 809, 1441, +-601, 1457, -1242, -896, -97, -1850, 1191, 194, +834, 1762, -566, 316, -762, -1548, 186, -597, +467, 1442, -184, 1035, -282, -1257, 359, -1692, +627, 581, -36, 2075, -834, 423, -323, -1731, +758, -1152, 624, 1020, -399, 1314, -554, -610, +218, -1333, 693, 344, 167, 1704, -637, 287, +-742, -1821, 380, -1435, 1256, 1024, 458, 2157, +-877, 361, -999, -1620, 53, -1295, 843, 370, +822, 1068, -63, 561, -754, -237, -498, -600, +305, -432, 680, 8, 324, 634, -390, 793, +-565, -253, 171, -1511, 719, -731, 140, 1469, +-473, 1894, -269, -353, 267, -2175, 391, -1129, +-53, 1121, -280, 1513, 182, 240, 497, -581, +-107, -451, -638, -373, -312, -524, 706, 32, +1054, 1205, -162, 1201, -1242, -653, -456, -1901, +1030, -524, 862, 1386, -429, 1121, -812, -494, +210, -945, 964, 138, 19, 719, -1145, -283, +-379, -1058, 1306, 215, 1004, 1603, -616, 526, +-1265, -1703, -203, -1543, 1041, 930, 802, 2123, +-435, 232, -572, -1826, 409, -1040, 376, 1021, +-700, 1115, -742, -535, 1072, -857, 1778, 505, +-345, 950, -2298, -523, -898, -1307, 1730, -51, +2146, 1428, -217, 866, -2232, -999, -850, -1443, +1615, 304, 1296, 1674, -780, 235, -950, -1667, +207, -981, 976, 1351, 322, 1702, -931, -397, +-541, -1854, 715, -817, 772, 1014, -204, 1335, +-524, 60, -72, -928, 591, -474, 114, 446, +-658, 229, 35, -604, 739, -268, 234, 854, +-368, 916, -371, -516, 42, -1346, 549, -314, +132, 1005, -467, 691, -18, -456, 603, -548, +329, 415, -355, 627, -748, -588, -57, -1327, +990, 8, 626, 1799, -371, 1208, -580, -1044, +-135, -2070, 204, -358, 311, 1636, 38, 1247, +194, -713, 437, -1251, -146, 288, -761, 1167, +-399, -111, 626, -1775, 1053, -668, 319, 1891, +-806, 2192, -836, -639, 244, -2748, 836, -1485, +167, 1351, -410, 2208, 136, 721, 559, -809, +-88, -1238, -751, -928, -375, -182, 552, 791, +1111, 1262, 513, 881, -841, -458, -1179, -1696, +-137, -1342, 1088, 507, 1132, 1828, -24, 1127, +-1082, -642, -635, -1460, 532, -675, 888, 543, +148, 889, -607, 262, -455, -529, 519, -514, +838, 188, 27, 662, -778, 249, -723, -786, +377, -1003, 1254, 175, 694, 1306, -700, 883, +-1164, -504, -217, -1354, 915, -785, 1023, 618, +-15, 1194, -856, 380, -440, -574, 501, -630, +812, -173, -89, 224, -792, 189, -186, 83, +913, 10, 706, -132, -319, -40, -827, 247, +-400, -1, 627, -486, 992, -295, 129, 360, +-637, 625, -561, 124, 38, -641, 884, -646, +737, 301, -507, 871, -1178, 72, -230, -1003, +1244, -655, 1636, 981, -71, 1413, -2052, -365, +-1798, -1983, 889, -1075, 3104, 1433, 1781, 2373, +-1853, 310, -3422, -2435, -795, -2239, 2722, 824, +2999, 2876, -193, 1339, -2639, -1885, -1513, -2599, +1089, -98, 1627, 2217, 249, 1532, -641, -779, +-84, -1700, 401, -586, -259, 759, -898, 785, +317, 128, 1812, -144, 749, -3, -1837, -311, +-2057, -956, 868, -403, 3139, 1259, 1333, 1747, +-2433, -162, -3076, -2127, 310, -1779, 3367, 759, +2140, 2523, -1492, 1289, -2648, -1459, -501, -2267, +1628, -411, 1351, 1571, -83, 1481, -751, -404, +-282, -1494, 263, -488, 391, 1073, 197, 1101, +-410, -527, -612, -1697, 242, -648, 1423, 1585, +971, 1956, -943, -229, -2038, -2343, -472, -1738, +2005, 1153, 2104, 2604, -533, 685, -2290, -2117, +-623, -1902, 1913, 890, 1519, 2251, -1398, 217, +-2188, -2286, 796, -1418, 3160, 1706, 1064, 2592, +-2764, -199, -2833, -2852, 896, -1816, 3425, 1479, +1360, 2658, -1902, 572, -2061, -1771, 390, -1724, +1906, 113, 419, 1246, -1296, 782, -810, -255, +1262, -777, 1497, -379, -221, 407, -1681, 594, +-863, -125, 1100, -746, 1439, -412, 106, 425, +-858, 986, -290, 460, 405, -869, 401, -1453, +-262, -195, -525, 1412, 81, 1193, 1001, -444, +868, -1345, -250, -507, -1116, 684, -865, 795, +346, -217, 1182, -845, 1093, -217, 156, 943, +-769, 935, -1178, -467, -721, -1840, 821, -1206, +1914, 1333, 1055, 2862, -1034, 1026, -1839, -2544, +-735, -3588, 1278, -468, 1849, 3526, 511, 3769, +-1079, -420, -1274, -4377, -316, -3347, 753, 1498, +1316, 4414, 967, 2222, -243, -2111, -1845, -3747, +-1699, -1379, 863, 1983, 3281, 2922, 2050, 1016, +-2070, -1641, -4131, -2585, -1105, -1069, 3802, 1535, +4284, 2542, -445, 772, -4566, -1836, -2998, -2327, +2205, -199, 4762, 1910, 1363, 1564, -3463, -350, +-3441, -1427, 746, -931, 3628, 241, 2031, 740, +-1723, 630, -2898, 278, -483, -299, 2292, -1013, +2033, -1009, -351, 275, -1963, 1777, -1037, 1358, +1095, -925, 1857, -2459, 407, -1037, -1482, 1526, +-1467, 2155, 577, 354, 2139, -1374, 1155, -1292, +-1262, -176, -2324, 268, -434, 324, 2337, 825, +2293, 1049, -484, -179, -2328, -2013, -1299, -1985, +1033, 691, 2123, 3153, 674, 1850, -1093, -1906, +-1057, -3393, -106, -799, 752, 2496, 872, 2585, +231, -238, -555, -2442, -610, -1682, -57, 832, +834, 1925, 961, 841, -210, -905, -1057, -1384, +-396, -635, 698, 467, 1055, 1158, 196, 870, +-795, -299, -463, -1330, 629, -1059, 593, 286, +-325, 1175, -549, 854, 305, -63, 1025, -651, +336, -881, -746, -648, -782, 25, 122, 1137, +759, 1307, 788, 285, 246, -1449, -334, -1919, +-817, -504, -551, 1601, 567, 2269, 1292, 467, +768, -1821, -523, -2241, -1421, -304, -719, 1587, +1208, 1717, 1804, 224, 278, -1108, -1413, -1217, +-1364, -276, 358, 402, 1620, 380, 973, 412, +-402, 656, -953, 214, -578, -1080, 133, -1751, +773, -453, 810, 1808, 311, 2463, -208, 313, +-751, -2587, -560, -2917, 96, 98, 696, 3145, +1041, 2571, 682, -747, -313, -2976, -1292, -1909, +-1296, 930, 27, 2273, 2183, 951, 2512, -1008, +-153, -893, -3000, 94, -2629, 78, 922, -806, +3758, -678, 2283, 1128, -1683, 2364, -3250, 653, +-970, -2748, 2107, -3250, 2368, -38, -56, 3595, +-1784, 3199, -699, -591, 1213, -3641, 1107, -2568, +-714, 702, -1644, 2496, 237, 1737, 2351, 42, +1713, -924, -1437, -1507, -3245, -1555, -1074, -350, +3137, 1926, 3905, 2630, -206, 689, -4145, -2197, +-3005, -3102, 1866, -904, 4490, 2339, 1588, 2901, +-2824, 433, -3189, -2053, 44, -1969, 2869, -150, +2172, 1191, -944, 928, -2348, -135, -550, -546, +1535, 108, 1459, 509, 74, -286, -1209, -1079, +-916, -615, 319, 681, 1031, 1222, 1078, 803, +274, -231, -961, -1251, -1573, -1601, -452, -699, +1480, 1363, 2449, 2678, 980, 1404, -1884, -1835, +-3136, -3677, -1155, -1762, 2609, 2350, 4428, 4180, +1392, 1382, -3668, -2918, -4883, -3852, -645, -559, +4639, 2691, 5059, 2658, -66, 77, -5002, -1846, +-4133, -1877, 1124, -254, 4663, 1326, 3237, 1578, +-1306, 242, -3706, -1361, -1968, -1753, 1134, -198, +2663, 2103, 1749, 2181, -250, -701, -1764, -3323, +-1803, -2183, -384, 1903, 1647, 4043, 2606, 1505, +1030, -2704, -1799, -3835, -3088, -1075, -995, 2292, +2396, 3167, 3564, 1221, 1071, -1377, -2597, -2507, +-3500, -1724, -683, 46, 2830, 1780, 3322, 2266, +555, 1073, -2384, -1134, -2556, -2599, -291, -1973, +1824, 366, 2063, 2486, 624, 2509, -1027, 212, +-1595, -2268, -571, -2604, 800, -661, 1435, 1763, +885, 2420, -539, 718, -1588, -1721, -671, -2145, +1288, -54, 1920, 2049, 414, 1333, -1836, -1391, +-1968, -2476, 239, -155, 2407, 2785, 2093, 2606, +-312, -849, -2295, -3854, -1912, -2769, 179, 1508, +1984, 4233, 2128, 2401, 572, -1675, -1190, -3487, +-1945, -1809, -1337, 711, 375, 1654, 2120, 1532, +2380, 1187, 684, 39, -1861, -1986, -3206, -3086, +-1346, -1148, 2077, 2557, 3919, 4240, 1959, 1508, +-2103, -3098, -4171, -4605, -1734, -1211, 2634, 3250, +3941, 3840, 1309, 508, -2465, -2661, -3279, -2630, +-520, -300, 2470, 1574, 2452, 1622, 222, 412, +-1731, -620, -1663, -1068, -68, -844, 1309, -94, +1204, 770, 288, 1073, -408, 594, -626, -400, +-495, -1365, -252, -1298, 319, -38, 1013, 1653, +1074, 1947, 171, 292, -1098, -1948, -1474, -2331, +-478, -403, 1134, 1742, 1897, 2067, 1028, 657, +-739, -1068, -1791, -1694, -1144, -995, 370, 221, +1473, 931, 1344, 1107, 317, 707, -511, -51, +-1154, -1182, -1079, -1607, -49, -674, 1261, 1000, +1554, 1875, 690, 1268, -836, -420, -1649, -2064, +-787, -1930, 758, 152, 1328, 2025, 763, 1670, +-74, -118, -566, -1203, -514, -999, -398, -409, +-174, -132, 493, 508, 1335, 1371, 1028, 1190, +-707, -731, -1999, -2459, -1186, -1585, 1299, 1467, +2610, 3036, 1211, 979, -1530, -2167, -2809, -2768, +-1002, -257, 2033, 2166, 2870, 1938, 808, -269, +-1780, -1560, -2418, -866, -731, 280, 1488, 201, +1871, -205, 782, 375, -260, 1277, -1004, 673, +-1195, -1332, -550, -2224, 480, -644, 1430, 1695, +1489, 2211, 121, 559, -1403, -1301, -1469, -1663, +-291, -723, 840, 402, 1243, 831, 612, 772, +-90, 562, -300, -21, -361, -855, -624, -1104, +-630, -398, 62, 452, 1101, 659, 1701, 559, +845, 632, -1084, 224, -2362, -979, -1576, -1792, +835, -816, 2824, 1161, 2243, 2027, -447, 933, +-2495, -706, -1933, -1250, 220, -867, 1520, -490, +1110, -228, 253, 730, 23, 1864, 137, 1602, +-298, -606, -1304, -2688, -1386, -2354, 306, 50, +2385, 2240, 2316, 2554, -100, 1144, -2214, -982, +-2339, -2657, -545, -2628, 1410, -357, 2221, 2613, +1444, 3493, -181, 1154, -1767, -2190, -1952, -3427, +-334, -1466, 1385, 1306, 1541, 2365, 371, 1396, +-412, -68, -188, -1054, 62, -1379, -583, -1005, +-1240, 184, -354, 1323, 1525, 1168, 2131, -44, +549, -951, -1315, -516, -1774, 336, -820, 252, +196, -724, 814, -821, 1470, 696, 1682, 1849, +318, 837, -2075, -1329, -2892, -2198, -1014, -854, +2146, 1218, 3273, 1994, 1601, 861, -1215, -716, +-2635, -1378, -2041, -871, -102, -119, 1827, 525, +2446, 1017, 1181, 849, -934, -69, -2068, -1058, +-1352, -1059, 128, -270, 1010, 618, 1145, 975, +980, 701, 254, -202, -796, -1024, -1550, -948, +-1010, 33, 578, 942, 1805, 859, 1016, 0, +-564, -776, -950, -709, -128, -21, 267, 494, +-190, 510, -508, 220, 59, -166, 1061, -628, +1066, -781, -96, -6, -1087, 1291, -1111, 1372, +-323, -457, 557, -2187, 1087, -1319, 1062, 1246, +430, 2366, -833, 628, -1722, -1565, -1173, -1719, +706, -52, 1993, 1110, 1474, 789, -309, -61, +-1478, -337, -1352, -229, -286, -197, 900, -125, +1242, 122, 526, 278, -264, 3, -626, -190, +-472, 65, -183, 315, 81, 20, 190, -456, +449, -386, 536, 119, 192, 363, -466, 221, +-819, 74, -369, 167, 579, -36, 851, -671, +-8, -942, -569, -34, 27, 1421, 642, 1575, +119, -199, -913, -1965, -901, -1603, 356, 449, +1512, 1851, 942, 1171, -627, -577, -1413, -1228, +-648, -421, 581, 580, 935, 352, 229, -509, +-286, -597, -12, 606, 193, 1385, -204, 370, +-615, -1366, -185, -1572, 508, -54, 579, 1327, +95, 1054, -120, -60, -77, -521, -117, -178, +-367, -137, -412, -612, 89, -718, 715, 439, +796, 1571, 177, 1190, -450, -542, -894, -1769, +-818, -1408, -161, 111, 924, 1341, 1602, 1472, +973, 720, -846, -593, -2140, -1723, -1408, -1550, +737, 298, 2029, 1916, 1377, 1463, -227, -495, +-1199, -1432, -1081, -466, -395, 594, 218, 137, +618, -663, 855, -187, 682, 1144, -10, 1275, +-932, -469, -1128, -1910, -443, -1041, 520, 1025, +1091, 1651, 905, 201, 97, -1062, -654, -535, +-997, 653, -725, 395, 169, -792, 906, -868, +830, 521, 269, 1418, -187, 480, -552, -1028, +-744, -1106, -497, 64, 136, 695, 887, 213, +1153, -173, 367, 230, -997, 535, -1321, -351, +-388, -1239, 874, -466, 951, 1227, -11, 1465, +-539, -258, -5, -1672, 531, -1019, -3, 920, +-789, 1616, -835, 463, 274, -1165, 1249, -1310, +800, -149, -388, 886, -780, 921, -297, 433, +-55, -191, -347, -976, -224, -1127, 713, -164, +1616, 1265, 825, 1455, -1407, 117, -2442, -1185, +-1007, -1147, 1364, -161, 2446, 533, 1292, 688, +-696, 546, -1752, 123, -1488, -523, -447, -834, +825, -369, 1664, 467, 1330, 787, 31, 282, +-1416, -453, -1582, -521, -649, 79, 704, 425, +1288, 29, 909, -406, 123, -220, -305, 287, +-682, 479, -1128, 54, -845, -410, 360, -388, +1715, 192, 1816, 524, 170, 61, -1930, -742, +-2284, -538, -518, 630, 1598, 1291, 2217, 400, +708, -1241, -1179, -1716, -1487, -359, -349, 1600, +406, 2023, 343, 404, -15, -1664, 241, -2121, +859, -450, 439, 1575, -985, 1863, -1560, 204, +-365, -1318, 1179, -1021, 1608, 325, 230, 672, +-1178, -157, -1122, -717, 203, 87, 843, 1158, +363, 916, -459, -731, -539, -1637, 192, -723, +598, 930, 392, 1306, -77, 300, -661, -521, +-862, -316, -208, 11, 855, -370, 1308, -608, +581, -19, -950, 911, -1609, 993, -566, 189, +882, -669, 1149, -1026, 353, -838, -336, 0, +-217, 1144, -69, 1484, -511, 492, -806, -1097, +44, -1710, 1183, -623, 1117, 874, 85, 1227, +-892, 382, -1096, -180, -607, -188, 117, -267, +823, -744, 1175, -710, 965, 406, -387, 1396, +-1808, 990, -1668, -475, 61, -1359, 1751, -901, +1890, 270, 406, 897, -1131, 786, -1613, 55, +-1028, -555, 201, -556, 1268, -66, 1376, 234, +508, 66, -631, -6, -1282, 170, -946, 330, +-44, 32, 719, -495, 1108, -568, 720, 123, +-237, 711, -831, 487, -871, -397, -444, -669, +261, -97, 751, 435, 867, 385, 577, 43, +-382, -267, -1271, -384, -1145, -242, 44, 120, +1299, 554, 1420, 684, 127, 67, -1072, -971, +-1098, -1175, -345, -32, 560, 1317, 809, 1338, +364, -3, -168, -1257, -390, -1228, -391, -114, +-62, 879, 381, 916, 306, 260, -218, -190, +-587, -455, -28, -605, 862, -417, 661, 224, +-413, 790, -1133, 596, -712, -111, 472, -572, +1268, -360, 713, -23, -429, 36, -995, -27, +-723, 189, 209, 560, 800, 427, 333, -421, +-123, -1037, -81, -452, -91, 666, -124, 973, +-203, 103, -306, -638, 123, -251, 611, 419, +337, 63, -285, -836, -439, -486, -131, 946, +297, 1456, 41, 21, -453, -1600, -204, -1293, +622, 520, 906, 1562, 66, 649, -1077, -764, +-1214, -891, -9, 161, 1118, 627, 1078, -118, +262, -731, -579, -56, -959, 1052, -760, 836, +-114, -686, 753, -1440, 1292, -365, 683, 1200, +-680, 1129, -1594, -293, -872, -1060, 662, -373, +1383, 616, 581, 575, -492, -196, -732, -562, +-277, -164, 155, 367, 157, 498, 49, 198, +29, -323, 24, -685, 117, -411, 139, 460, +-86, 976, -230, 537, -344, -625, -194, -1183, +329, -397, 557, 826, 291, 1071, -203, 127, +-501, -730, -453, -642, -69, -5, 264, 370, +482, 340, 494, 172, 49, -34, -699, -234, +-756, -358, -53, -66, 677, 364, 682, 480, +10, -59, -556, -567, -479, -337, 72, 369, +547, 659, 351, 99, -410, -535, -753, -567, +-130, -46, 840, 564, 965, 729, -28, 156, +-1146, -682, -1133, -863, -22, -154, 1255, 784, +1360, 929, 86, 81, -1217, -773, -1312, -701, +-139, 53, 919, 561, 1060, 464, 264, -17, +-591, -313, -821, -282, -231, -30, 544, 254, +537, 360, -166, 68, -590, -454, -144, -584, +633, 135, 755, 980, -127, 751, -1038, -550, +-927, -1305, 231, -601, 1299, 798, 1057, 1355, +-267, 558, -1220, -794, -839, -1243, 162, -407, +755, 786, 451, 970, 85, 86, 23, -609, +-18, -328, -411, 269, -610, 234, -216, -227, +518, -277, 864, 133, 418, 326, -308, 115, +-620, 87, -519, 197, -239, -190, 204, -859, +753, -641, 833, 706, 132, 1691, -911, 840, +-1043, -1180, -104, -2012, 805, -667, 636, 1292, +61, 1702, -65, 538, 86, -629, -275, -925, +-776, -843, -458, -453, 625, 598, 1226, 1631, +619, 1154, -721, -834, -1249, -2073, -429, -887, +665, 1312, 812, 1764, 195, 98, -216, -1339, +-159, -815, -109, 659, -209, 1011, -181, -43, +150, -937, 410, -499, 269, 490, -21, 845, +-222, 305, -214, -308, -171, -537, -12, -456, +264, -141, 368, 509, 207, 862, -198, 413, +-474, -526, -229, -895, 346, -373, 462, 379, +20, 707, -365, 421, -194, -67, 269, -414, +377, -337, -95, -79, -476, 140, -177, 214, +320, 248, 520, 198, 117, 26, -460, -290, +-430, -460, 156, -171, 454, 433, 142, 742, +-250, 317, -258, -549, 96, -923, 287, -247, +113, 830, -127, 1044, -227, 128, -178, -949, +13, -952, 311, 37, 450, 949, 140, 946, +-515, 96, -777, -821, -155, -984, 822, -204, +936, 797, -1, 1052, -949, 362, -837, -649, +170, -967, 868, -364, 578, 507, -274, 846, +-655, 385, -258, -232, 216, -482, 281, -321, +152, -71, -13, 223, -219, 493, -287, 389, +-69, -139, 314, -590, 392, -355, 6, 334, +-505, 614, -497, 131, 97, -362, 452, -333, +385, 78, 24, 283, -287, 219, -513, 131, +-396, -72, 43, -376, 647, -443, 814, 204, +-48, 906, -1134, 690, -1067, -545, 344, -1296, +1380, -410, 686, 1098, -928, 1259, -1338, -174, +-34, -1200, 1197, -494, 732, 807, -709, 773, +-1281, -383, -294, -792, 1007, 84, 1046, 879, +-121, 463, -1085, -528, -981, -734, -91, -44, +788, 539, 954, 460, 275, 37, -713, -153, +-1259, -123, -649, -170, 619, -211, 1258, 101, +484, 536, -852, 475, -1161, -141, -297, -672, +607, -473, 627, 339, -88, 828, -594, 368, +-348, -440, 182, -684, 193, -85, -189, 603, +-296, 555, -88, -171, 101, -574, -47, -153, +-210, 523, -83, 465, 95, -253, -78, -559, +-266, 0, -293, 632, -102, 381, 173, -348, +176, -563, -192, 45, -352, 596, -131, 354, +-58, -262, -183, -433, -219, -8, 49, 366, +307, 217, 84, -51, -465, -57, -693, -1, +-312, -112, 275, -118, 481, 213, 129, 478, +-371, 169, -574, -493, -486, -548, -123, 195, +330, 718, 332, 363, -84, -311, -459, -471, +-447, -47, -148, 311, 17, 138, -128, -105, +-117, 113, 155, 421, 110, 109, -424, -650, +-634, -630, -254, 399, 246, 1073, 263, 372, +-160, -644, -431, -710, -192, 134, -5, 490, +-314, 56, -517, -250, 76, 277, 674, 681, +155, 17, -1018, -987, -1207, -847, 65, 575, +1180, 1474, 638, 583, -885, -937, -1413, -1136, +-410, 16, 645, 899, 627, 482, -110, -285, +-571, -243, -470, 255, -345, 215, -306, -333, +-52, -424, 447, 208, 383, 674, -355, 317, +-1056, -344, -769, -441, 194, -83, 725, 273, +310, 369, -491, 206, -865, -130, -511, -411, +142, -270, 382, 422, -30, 835, -470, 175, +-500, -926, -119, -929, 263, 429, 65, 1462, +-502, 652, -661, -1034, -205, -1206, 294, 248, +292, 1133, -175, 310, -542, -705, -454, -276, +-234, 813, -100, 564, 11, -832, 167, -1228, +91, 247, -237, 1700, -720, 1071, -723, -924, +-48, -1704, 598, -345, 410, 1206, -375, 1116, +-789, -87, -485, -671, 21, -259, 126, 105, +-105, -38, -211, -14, -34, 365, 86, 530, +-274, 23, -691, -596, -552, -509, 165, 239, +656, 714, 255, 421, -766, -271, -986, -589, +-212, -193, 522, 468, 400, 518, -353, 13, +-791, -387, -276, -274, 443, 228, 124, 390, +-597, 41, -553, -282, 133, -35, 476, 359, +-147, 228, -971, -332, -550, -491, 658, 173, +873, 823, -334, 464, -1399, -488, -1029, -911, +503, -205, 1374, 794, 509, 907, -958, 109, +-1408, -694, -664, -752, 387, -34, 906, 687, +575, 736, -246, 95, -947, -537, -961, -570, +-319, 20, 522, 514, 755, 364, 176, -31, +-524, -184, -699, -23, -418, 62, -95, -33, +143, -141, 217, 137, 165, 400, -86, 225, +-458, -284, -529, -454, -152, 41, 213, 544, +183, 292, -167, -284, -317, -336, -82, 146, +126, 441, 16, 121, -335, -358, -565, -289, +-236, 260, 424, 466, 531, 85, 14, -347, +-484, -190, -710, 353, -506, 285, 91, -330, +620, -411, 607, 325, 14, 797, -775, 194, +-996, -752, -372, -723, 546, 327, 918, 900, +321, 297, -666, -473, -892, -340, -260, 304, +248, 287, 288, -419, 61, -503, -40, 473, +-16, 1126, -176, 312, -466, -1046, -326, -1150, +148, 185, 464, 1280, 243, 855, -315, -307, +-660, -903, -280, -459, 335, 271, 485, 542, +-31, 351, -660, 34, -471, -255, 340, -272, +684, 17, -11, 290, -816, 140, -678, -139, +366, -134, 965, 245, 175, 365, -943, -128, +-871, -475, 248, -104, 976, 528, 402, 462, +-711, -253, -901, -574, -68, 70, 610, 730, +419, 285, -121, -640, -342, -651, -228, 390, +-167, 1027, -156, 319, 29, -823, 417, -827, +457, 196, -134, 976, -828, 561, -710, -437, +181, -749, 907, -119, 625, 554, -416, 462, +-928, -88, -322, -345, 419, -64, 435, 243, +-130, 113, -442, -114, -37, -57, 566, 193, +224, 254, -673, -70, -844, -381, 30, -129, +925, 424, 772, 550, -363, -92, -1016, -659, +-518, -346, 364, 554, 660, 789, 161, -5, +-427, -763, -364, -497, 186, 459, 310, 791, +-151, 114, -526, -547, -307, -318, 397, 258, +664, 298, 82, -135, -573, -133, -556, 358, +-125, 388, 270, -284, 301, -674, 88, -98, +29, 711, 8, 710, -353, -184, -622, -783, +-175, -331, 608, 509, 705, 638, -17, 41, +-736, -512, -608, -367, 86, 270, 504, 598, +189, 263, -271, -411, -233, -637, 171, -84, +174, 697, -285, 713, -453, -156, -22, -786, +451, -368, 355, 547, -231, 603, -601, -188, +-273, -603, 345, 89, 500, 819, -65, 410, +-627, -804, -461, -1048, 273, 147, 659, 1330, +254, 946, -506, -496, -768, -1209, -281, -559, +388, 498, 636, 807, 295, 467, -332, -31, +-655, -420, -487, -561, 24, -239, 484, 416, +533, 759, 7, 254, -530, -552, -552, -591, +-118, 160, 330, 656, 277, 258, -123, -419, +-256, -459, -8, 135, 96, 481, -98, 244, +-290, -109, -179, -137, 118, -79, 171, -196, +8, -200, -113, 272, -94, 759, -105, 420, +-194, -572, -262, -994, 0, -221, 371, 847, +277, 846, -211, -114, -469, -629, -295, -144, +-27, 364, 102, 19, 112, -493, 189, -144, +181, 747, -228, 834, -688, -237, -514, -1098, +220, -627, 748, 606, 442, 1020, -410, 227, +-829, -559, -419, -425, 268, 137, 466, 193, +106, -75, -273, -20, -289, 316, -76, 234, +26, -266, -69, -405, -166, 109, -67, 511, +118, 158, 128, -459, -117, -392, -373, 324, +-256, 651, 143, 127, 258, -539, -47, -436, +-351, 169, -239, 462, 116, 136, 216, -175, +-147, -35, -396, 175, -94, 18, 240, -307, +126, -202, -276, 235, -389, 446, -40, 150, +318, -180, 128, -208, -306, -74, -394, -96, +-160, -59, 118, 240, 278, 502, 108, 276, +-203, -351, -410, -693, -376, -328, -45, 431, +372, 709, 424, 300, -34, -237, -562, -397, +-632, -273, -111, -118, 400, 139, 451, 458, +67, 493, -401, -29, -542, -576, -253, -502, +164, 103, 320, 502, 109, 374, -204, -35, +-257, -203, -149, -166, -128, -90, -55, -31, +56, 153, 104, 280, 21, 143, -149, -153, +-297, -262, -233, -87, 26, 159, 246, 189, +146, 84, -245, 0, -430, -66, -184, -116, +175, -106, 307, 127, 38, 274, -410, 87, +-438, -244, -11, -212, 318, 140, 178, 256, +-153, 36, -292, -178, -158, -39, -96, 117, +-164, 16, 93, -113, 410, 87, 170, 293, +-516, 13, -824, -475, -189, -353, 773, 424, +787, 847, -299, 182, -1029, -874, -548, -945, +447, 169, 673, 1155, -7, 812, -495, -358, +-215, -981, 103, -586, -100, 175, -309, 642, +21, 652, 509, 263, 246, -356, -603, -784, +-815, -581, -18, 203, 779, 870, 557, 772, +-410, -7, -890, -773, -295, -787, 466, -127, +487, 583, -49, 706, -418, 265, -345, -275, +13, -513, 184, -335, 134, 34, -60, 362, +-283, 358, -266, 52, 87, -177, 336, -143, +128, 35, -345, -4, -611, -161, -178, -223, +596, 201, 629, 703, -118, 516, -818, -540, +-699, -1288, 94, -584, 783, 1021, 655, 1658, +-197, 456, -900, -1289, -715, -1663, 180, -287, +745, 1278, 528, 1469, -186, 281, -735, -915, +-530, -1160, 129, -510, 465, 421, 305, 1018, +-35, 923, -331, 27, -387, -981, -190, -1218, +128, -283, 355, 937, 283, 1359, -144, 526, +-485, -793, -389, -1387, 46, -699, 368, 657, +364, 1384, 38, 840, -374, -512, -566, -1339, +-255, -923, 394, 460, 676, 1398, 202, 966, +-612, -514, -854, -1418, -96, -883, 799, 560, +648, 1463, -281, 924, -793, -560, -438, -1541, +295, -966, 604, 556, 196, 1588, -273, 1100, +-430, -407, -253, -1584, 58, -1284, 304, 250, +272, 1565, -9, 1400, -334, -34, -318, -1344, +48, -1448, 191, -240, 9, 1133, -77, 1456, +44, 452, 206, -855, -13, -1324, -490, -626, +-388, 587, 282, 1257, 546, 773, 199, -441, +-250, -1218, -429, -747, -251, 470, 45, 1149, +157, 631, 272, -489, 315, -1014, -70, -520, +-522, 458, -467, 932, 80, 527, 553, -389, +365, -935, -226, -562, -335, 358, -35, 972, +-27, 635, -140, -329, 26, -1017, 311, -649, +313, 397, -182, 1048, -556, 534, -187, -512, +421, -950, 372, -312, -108, 620, -460, 843, +-164, 105, 354, -740, 376, -735, -118, 127, +-375, 869, -236, 671, -12, -266, 210, -917, +423, -627, 333, 270, -268, 847, -848, 700, +-514, -6, 559, -694, 1116, -927, 372, -402, +-863, 576, -1092, 1273, 40, 863, 1056, -507, +646, -1610, -616, -1201, -913, 512, 77, 1855, +982, 1389, 486, -521, -628, -1939, -973, -1382, +-191, 537, 777, 1861, 839, 1273, 139, -469, +-455, -1638, -687, -1133, -561, 333, 19, 1410, +769, 1107, 997, -190, 428, -1268, -845, -1101, +-1423, 106, -504, 1279, 907, 1174, 1182, -182, +462, -1485, -358, -1111, -615, 580, -556, 1679, +-492, 775, -45, -1046, 969, -1592, 1415, -293, +339, 1281, -1397, 1310, -1863, -35, -304, -1136, +1716, -986, 1767, 13, -100, 747, -1514, 884, +-1016, 367, 305, -362, 917, -1004, 431, -832, +-259, 185, -481, 1263, -121, 1109, 289, -173, +458, -1326, 141, -1101, -491, 138, -824, 1145, +-223, 1017, 1015, 73, 1390, -878, 193, -1051, +-1532, -299, -1780, 760, 64, 1127, 1966, 453, +1723, -733, -312, -1203, -1828, -465, -1454, 788, +333, 1201, 1569, 425, 1145, -754, -119, -1092, +-1072, -374, -1140, 579, -230, 876, 934, 491, +1366, -204, 635, -703, -960, -746, -1895, -153, +-862, 672, 1369, 991, 2407, 355, 939, -601, +-1749, -1018, -2723, -475, -844, 511, 1864, 1001, +2761, 453, 1043, -454, -1634, -747, -2747, -240, +-1280, 295, 1189, 362, 2633, 112, 1852, -21, +-685, -68, -2714, -76, -2202, -120, 416, -50, +2693, 76, 2444, 176, -278, 100, -2648, -97, +-2238, -166, 250, -33, 2335, 151, 2083, 167, +-147, -65, -2043, -199, -1795, -136, 38, 121, +1697, 200, 1862, 149, 192, -21, -1713, -103, +-1941, -244, -223, -255, 1777, 16, 2212, 479, +351, 610, -2098, 59, -2482, -760, -173, -934, +2399, -64, 2675, 1035, 173, 1077, -2685, 6, +-2874, -1098, 15, -990, 2958, 32, 2933, 856, +-105, 788, -3070, 182, -2911, -430, 234, -738, +3096, -523, 2829, 178, -217, 838, -2938, 767, +-2687, -121, 128, -944, 2641, -819, 2647, 221, +239, 1021, -2308, 703, -2711, -386, -619, -986, +2071, -489, 2993, 500, 1031, 898, -2095, 356, +-3202, -553, -1081, -894, 2173, -281, 3345, 679, +1032, 955, -2307, 189, -3152, -848, -823, -965, +2198, -55, 3003, 917, 875, 939, -2078, 62, +-2899, -871, -942, -1000, 1950, -175, 3073, 863, +1147, 1118, -2045, 310, -3212, -831, -1106, -1203, +2124, -459, 3279, 754, 1136, 1333, -2095, 648, +-3103, -702, -1142, -1455, 1721, -826, 3004, 648, +1599, 1660, -1305, 1135, -3062, -709, -2112, -2091, +986, -1353, 3501, 1061, 2653, 2582, -1104, 1332, +-3901, -1528, -2638, -2852, 1431, -1081, 4090, 1901, +2371, 2810, -1763, 750, -3815, -1966, -1789, -2485, +1847, -544, 3342, 1750, 1466, 2159, -1630, 530, +-2857, -1440, -1352, -1962, 1349, -649, 2793, 1233, +1668, 1997, -1235, 817, -3047, -1227, -1863, -2196, +1408, -971, 3509, 1412, 2101, 2510, -1625, 1054, +-3813, -1645, -2122, -2778, 1771, -1133, 4005, 1800, +2336, 3002, -1641, 1241, -3980, -1829, -2511, -3138, +1369, -1357, 4046, 1772, 2950, 3172, -1117, 1455, +-4107, -1622, -3015, -3110, 1085, -1541, 4067, 1474, +3043, 3010, -981, 1534, -3776, -1327, -2691, -2835, +845, -1583, 3360, 1096, 2658, 2767, -442, 1834, +-2983, -914, -2632, -3004, 140, -2193, 2882, 1003, +3034, 3499, 67, 2416, -3074, -1380, -3096, -3996, +124, -2325, 3313, 1915, 3239, 4218, -298, 1923, +-3421, -2325, -2929, -4041, 493, -1439, 3347, 2368, +2965, 3601, -394, 1211, -3239, -2070, -2760, -3251, +316, -1327, 3104, 1722, 3002, 3192, -102, 1593, +-3054, -1581, -2897, -3363, 106, -1748, 3026, 1694, +3087, 3541, -2, 1673, -3056, -1974, -2981, -3616, +186, -1407, 3238, 2263, 3090, 3636, -368, 1142, +-3446, -2540, -2816, -3701, 788, -932, 3620, 2829, +2771, 3834, -953, 827, -3604, -3094, -2490, -4021, +1064, -787, 3497, 3307, 2662, 4163, -721, 762, +-3326, -3404, -2804, -4170, 461, -701, 3394, 3346, +3214, 4017, -192, 641, -3389, -3183, -3182, -3748, +265, -554, 3413, 2932, 3168, 3416, -254, 546, +-3198, -2696, -2739, -3248, 391, -587, 2981, 2631, +2629, 3304, -231, 587, -2735, -2870, -2480, -3507, +249, -377, 2775, 3297, 2745, 3620, -99, 36, +-2972, -3682, -2804, -3617, 401, 277, 3262, 3915, +2877, 3517, -466, -484, -3272, -3995, -2623, -3429, +715, 590, 3121, 4006, 2428, 3400, -442, -704, +-2683, -4098, -2238, -3273, 266, 896, 2411, 4097, +2412, 3069, 152, -1006, -2284, -3992, -2549, -3015, +-161, 957, 2578, 3998, 2851, 3123, 110, -928, +-2889, -4165, -2827, -3283, 335, 972, 3240, 4346, +2793, 3384, -500, -1093, -3190, -4497, -2567, -3356, +514, 1218, 3065, 4538, 2741, 3213, -144, -1326, +-2873, -4415, -2836, -3070, -106, 1332, 2837, 4321, +3151, 3005, 326, -1400, -2808, -4389, -3019, -2922, +-204, 1660, 2788, 4501, 2895, 2603, 98, -2042, +-2602, -4381, -2469, -2154, 148, 2205, 2472, 4048, +2238, 1789, -216, -2157, -2294, -3687, -1951, -1589, +337, 1986, 2334, 3387, 1962, 1505, -388, -1828, +-2366, -3269, -1893, -1573, 551, 1830, 2520, 3484, +2012, 1595, -591, -2225, -2685, -3869, -2004, -1396, +807, 2841, 2898, 4076, 2056, 955, -878, -3254, +-2988, -4000, -2073, -622, 1038, 3276, 3167, 3755, +2076, 532, -1044, -3047, -3124, -3475, -2077, -582, +1007, 2651, 3195, 3125, 2225, 637, -957, -2213, +-3204, -2765, -2242, -689, 979, 1848, 3269, 2392, +2259, 587, -1009, -1562, -3209, -2010, -2136, -463, +1080, 1266, 3149, 1678, 2009, 504, -1099, -1046, +-2995, -1641, -1885, -675, 1070, 964, 3016, 1876, +1907, 902, -1131, -1133, -3167, -2253, -1868, -1042, +1413, 1320, 3372, 2478, 1757, 1138, -1702, -1337, +-3477, -2566, -1600, -1322, 1951, 1138, 3487, 2559, +1467, 1574, -1952, -939, -3439, -2557, -1522, -1705, +1926, 791, 3407, 2504, 1549, 1702, -1777, -801, +-3392, -2423, -1620, -1581, 1769, 832, 3365, 2359, +1453, 1490, -1776, -938, -3160, -2448, -1239, -1465, +1857, 1098, 2847, 2602, 837, 1435, -1817, -1266, +-2468, -2718, -652, -1447, 1799, 1331, 2397, 2794, +429, 1488, -2025, -1386, -2423, -2920, -253, -1536, +2449, 1521, 2647, 3149, -299, 1482, -2946, -1943, +-2468, -3446, 695, -1166, 3128, 2612, 2288, 3628, +-1066, 458, -3033, -3357, -1875, -3429, 1033, 401, +2672, 3788, 1613, 2887, -980, -1086, -2261, -3767, +-1233, -2440, 829, 1362, 1893, 3644, 924, 2197, +-971, -1549, -1567, -3696, -398, -1952, 1060, 1884, +1334, 3730, -35, 1470, -1390, -2434, -952, -3546, +504, -677, 1281, 2886, 728, 3027, -640, -331, +-1133, -3069, -397, -2097, 482, 1107, 679, 2743, +409, 1102, -180, -1498, -359, -2050, -280, -295, +-185, 1399, 17, 1149, 379, -230, 492, -931, +128, -263, -444, 443, -662, 59, -80, -550, +708, -100, 741, 962, -257, 826, -977, -809, +-447, -1777, 781, -314, 1138, 1908, -34, 1826, +-1274, -815, -861, -2629, 687, -1121, 1412, 2039, +335, 2663, -1023, -186, -1049, -2899, 284, -1911, +1193, 1492, 490, 2949, -865, 657, -831, -2307, +222, -2214, 1038, 463, 548, 2331, -541, 1216, +-939, -1062, -181, -1856, 452, -565, 634, 1085, +434, 1434, 177, 461, -432, -940, -961, -1446, +-845, -647, 685, 896, 1968, 1700, 1205, 841, +-1265, -1091, -2474, -2034, -900, -865, 2013, 1349, +2730, 2288, 219, 679, -2555, -1755, -2223, -2386, +728, -325, 2916, 2204, 1770, 2316, -1480, -239, +-3084, -2580, -1097, -2024, 2276, 713, 3354, 2690, +718, 1728, -2903, -1031, -3350, -2837, 100, -1463, +3349, 1496, 3080, 2903, -516, 897, -3317, -2178, +-2294, -2642, 1106, 65, 2816, 2558, 1615, 1887, +-895, -875, -2102, -2445, -1110, -1094, 806, 1135, +1837, 1899, 1206, 720, -644, -804, -1991, -1495, +-1066, -1010, 1283, 377, 2366, 1645, 850, 1543, +-1734, -503, -2279, -2329, -235, -1599, 2066, 1340, +2024, 2669, 178, 811, -1500, -2037, -1719, -2156, +-482, 6, 1275, 1712, 2092, 1297, 1054, 129, +-1274, -796, -2372, -1253, -723, -975, 1922, 474, +2421, 1882, 103, 1284, -2185, -1039, -1675, -2173, +879, -649, 2357, 1526, 1159, 1586, -1246, -184, +-2151, -1451, -707, -819, 1591, 519, 2322, 1177, +861, 472, -1379, -606, -2349, -1159, -1113, -455, +1491, 657, 2877, 1219, 1495, 533, -1478, -621, +-3004, -1381, -1228, -751, 2000, 723, 2996, 1633, +713, 625, -2086, -1299, -2201, -1518, 170, 351, +2194, 1679, 1717, 334, -608, -1542, -2050, -1046, +-1180, 1248, 1155, 1765, 2516, -270, 1183, -1980, +-1701, -1076, -2748, 1011, -569, 1638, 2479, 523, +2791, -950, 112, -1276, -2608, -387, -2160, 905, +758, 1143, 2595, 23, 1335, -1182, -1173, -809, +-1860, 645, -73, 1295, 1619, 238, 993, -1154, +-780, -1271, -1204, 106, 121, 1486, 1326, 1285, +841, -363, -654, -1692, -1079, -1203, -217, 479, +948, 1472, 1113, 1053, -54, -96, -1076, -1075, +-663, -1447, 660, -545, 1411, 1345, 359, 2114, +-1290, 299, -1193, -2088, 662, -1928, 1709, 581, +712, 2081, -1104, 991, -1382, -820, 119, -1373, +1349, -736, 820, 351, -507, 1223, -802, 1155, +7, -360, 720, -1701, 338, -1161, -417, 771, +-391, 1771, 248, 821, 589, -849, 328, -1558, +-209, -872, -469, 794, -202, 1754, 105, 791, +623, -1291, 595, -1760, -78, 18, -703, 1611, +-505, 844, 221, -769, 857, -987, 619, 139, +-323, 685, -824, 53, -356, -541, 560, -194, +962, 550, 232, 621, -852, -401, -743, -1105, +400, -310, 968, 1256, 308, 1175, -585, -733, +-457, -1725, 184, -171, 369, 1513, -106, 889, +-11, -841, 434, -949, 261, 308, -555, 481, +-721, -314, 202, -306, 1106, 727, 658, 671, +-712, -693, -1154, -1363, -167, -95, 1083, 1407, +978, 1262, -239, -527, -1013, -1674, -520, -961, +462, 961, 788, 1789, 284, 481, -385, -1421, +-387, -1494, -27, 117, 73, 1436, 20, 927, +179, -353, 412, -1163, 276, -756, -486, 334, +-1016, 1226, -124, 802, 1196, -690, 1263, -1525, +-388, -364, -1778, 1246, -945, 1125, 1163, -325, +1810, -1089, 381, -264, -1403, 382, -1585, 223, +-10, -84, 1571, 240, 1426, 242, -287, -277, +-1797, -562, -1214, -51, 989, 368, 2013, 407, +273, 60, -1757, -249, -1343, -543, 819, -290, +1878, 557, 326, 1017, -1580, -7, -1362, -1260, +518, -1098, 1560, 686, 894, 1622, -777, 723, +-1485, -1032, -486, -1542, 955, -574, 1069, 996, +56, 1513, -739, 563, -497, -1059, 213, -1497, +162, -278, -77, 1115, 51, 1100, 307, -85, +-88, -923, -332, -603, -122, 238, 401, 718, +139, 234, -494, -504, -544, -507, 448, 283, +943, 566, 282, -62, -837, -564, -1135, -95, +-133, 554, 1167, 165, 1041, -521, -200, -424, +-1108, 408, -700, 608, 285, 92, 718, -464, +313, -547, -100, -232, -398, 408, -438, 754, +-55, 423, 686, -596, 448, -920, -592, -225, +-1058, 559, 149, 642, 1254, 254, 778, -215, +-920, -554, -1281, -533, -148, 168, 983, 713, +711, 340, -39, -427, -458, -454, -388, 227, +-313, 345, 18, -235, 428, -403, 522, 123, +58, 522, -563, 159, -634, -423, 41, -380, +662, 175, 485, 404, -381, 67, -818, -503, +-99, -259, 809, 476, 520, 707, -411, -233, +-715, -958, -182, -303, 377, 673, 426, 506, +282, -168, 24, -142, -522, 212, -781, -293, +-80, -839, 917, -12, 886, 1196, -223, 876, +-1038, -662, -681, -1274, 267, -301, 813, 593, +453, 734, -78, 380, -535, -86, -585, -801, +-189, -859, 456, 152, 824, 1397, 466, 832, +-676, -800, -1304, -1667, -299, -387, 1315, 1372, +1400, 1624, -346, -83, -1776, -1782, -865, -1474, +1072, 677, 1401, 1975, 49, 877, -974, -1158, +-678, -1545, 92, -71, 374, 961, 392, 626, +242, -155, -154, -247, -478, -74, -250, -359, +180, -317, 259, 382, 183, 869, 302, 172, +84, -942, -751, -934, -872, 341, 372, 1108, +1569, 706, 893, -488, -1184, -1035, -1887, -653, +-422, 288, 1533, 1050, 1778, 925, 227, -294, +-1532, -1224, -1762, -918, -274, 482, 1669, 1220, +1847, 474, -40, -611, -1740, -820, -1495, -3, +332, 630, 1696, 300, 1170, -424, -478, -561, +-1510, 149, -936, 768, 685, 343, 1684, -488, +627, -745, -1114, -120, -1416, 521, -77, 437, +1118, 52, 916, -325, -202, -212, -656, 102, +-421, 189, -51, -202, 217, -420, 325, 28, +400, 948, 136, 636, -387, -799, -691, -1519, +-173, -176, 794, 1622, 990, 1231, -112, -645, +-1246, -1621, -792, -494, 865, 954, 1529, 1112, +79, 46, -1349, -784, -966, -784, 445, 111, +1121, 676, 423, 414, -270, -195, -367, -362, +-557, 56, -497, -127, 309, -303, 1208, 14, +933, 883, -642, 625, -1624, -843, -688, -1449, +1130, 88, 1680, 1620, 214, 1022, -1320, -1116, +-1044, -1687, 431, 217, 1098, 1617, 265, 802, +-590, -1218, -397, -1440, 258, 499, 195, 1654, +-95, 467, -25, -1511, 269, -1259, 72, 844, +-355, 1691, -377, 162, 133, -1546, 635, -1231, +605, 844, -73, 1673, -923, 484, -842, -1320, +218, -1608, 1537, 81, 1110, 1705, -744, 1416, +-1754, -618, -621, -2061, 1198, -1035, 1562, 1339, +44, 2086, -1260, 297, -954, -1899, 359, -1663, +1178, 558, 518, 1944, -811, 989, -992, -1088, +245, -1762, 1230, -249, 396, 1378, -981, 1251, +-822, -403, 540, -1372, 1184, -460, 79, 826, +-1060, 866, -469, -178, 608, -841, 929, -227, +53, 475, -886, 462, -576, -7, 403, -346, +796, -301, 299, -172, -585, 194, -629, 623, +124, 381, 620, -413, 250, -919, -307, -358, +-391, 675, 22, 944, 375, 312, 360, -645, +-36, -980, -320, -425, -297, 539, 145, 1112, +377, 582, 225, -514, -108, -1199, 21, -655, +-1, 408, -319, 1134, -485, 875, 294, -126, +1007, -1275, 536, -1308, -946, 60, -1269, 1700, +39, 1582, 1294, -389, 948, -1903, -440, -1475, +-1187, 470, -538, 1789, 575, 1517, 1230, -171, +601, -1790, -801, -1892, -1448, -106, -339, 2030, +1261, 2274, 1696, 149, -17, -2265, -1665, -2385, +-1327, -134, 395, 2241, 1436, 2297, 964, 207, +-320, -1910, -978, -2078, -753, -527, -52, 1231, +590, 2011, 757, 1233, 489, -647, -338, -2328, +-854, -1918, -637, 552, 231, 2702, 1006, 2025, +810, -726, -178, -2525, -957, -1741, -728, 520, +64, 1969, 942, 1620, 895, -86, 48, -1487, +-888, -1586, -1137, -259, -249, 1015, 1061, 1379, +1381, 560, 378, -323, -1171, -1053, -1750, -1115, +-508, -509, 1382, 844, 2033, 1871, 653, 1239, +-1414, -832, -2217, -2627, -784, -1734, 1506, 1064, +2235, 3046, 1013, 1836, -1175, -1258, -2296, -2951, +-1307, -1472, 928, 1096, 2307, 2099, 1748, 1084, +-749, -355, -2581, -815, -1838, -1003, 756, -894, +2515, -233, 1670, 1287, -848, 1890, -2196, 819, +-1177, -1330, 839, -2311, 1486, -1345, 481, 822, +-432, 2392, -353, 2111, 15, 9, -330, -2478, +-593, -2934, 68, -757, 1024, 2511, 971, 3545, +-126, 1321, -1274, -2355, -1080, -3823, 17, -1662, +1121, 1889, 1230, 3662, 76, 2027, -1053, -1117, +-1133, -3178, -174, -2512, 680, 46, 825, 2747, +395, 3140, -81, 896, -651, -2450, -754, -3630, +-237, -1494, 655, 2181, 810, 3813, 231, 1701, +-166, -2008, -271, -3531, -597, -1361, -868, 1860, +-43, 2526, 1481, 545, 1711, -1292, -317, -1022, +-2204, 225, -1695, 436, 534, -485, 1938, -717, +1337, 338, -207, 1481, -1169, 1168, -1083, -625, +-486, -2067, 190, -1659, 862, 382, 1319, 2315, +964, 2194, -638, 190, -2287, -2108, -1975, -2655, +682, -1116, 3135, 1569, 2531, 3184, -751, 2189, +-3510, -1167, -2863, -3672, 623, -2744, 3512, 974, +3117, 3718, -421, 2631, -3714, -856, -3243, -3185, +542, -2174, 3778, 767, 3083, 2467, -911, 1466, +-3702, -859, -2590, -1906, 1149, -597, 3690, 1390, +2247, 1569, -1569, -480, -3658, -2282, -1854, -1307, +2074, 1629, 3619, 3150, 1284, 1127, -2223, -2605, +-3414, -3646, -1113, -948, 2139, 2785, 3210, 3707, +1209, 1209, -2083, -2177, -3378, -3666, -1151, -2039, +2334, 1423, 3250, 3859, 663, 2657, -2453, -1018, +-2721, -3675, -90, -2543, 2403, 524, 2075, 2701, +-317, 2241, -2106, 319, -1589, -1570, 554, -2179, +1984, -1002, 1256, 1084, -754, 1934, -1888, 729, +-964, -953, 713, -964, 1675, 258, 927, 580, +-671, -432, -1403, -1081, -926, -137, 179, 1385, +1075, 1574, 1204, 154, 587, -1585, -747, -1959, +-1775, -646, -1398, 1213, 624, 2056, 2550, 1355, +2015, -253, -641, -1714, -2849, -2141, -2464, -1148, +506, 970, 2951, 2807, 2508, 2650, -179, 77, +-2564, -3084, -2482, -3863, -218, -1229, 1754, 2756, +1998, 4440, 933, 2277, -567, -1759, -1532, -4137, +-1713, -3096, -637, 195, 1168, 3056, 2347, 3548, +1523, 1542, -712, -1539, -2265, -3445, -2074, -2894, +-126, -225, 1889, 2585, 2548, 3725, 1054, 2134, +-1358, -1334, -2835, -4160, -1717, -3718, 838, 153, +2725, 4203, 1981, 4532, -330, 596, -2232, -3778, +-2047, -4325, -48, -902, 1622, 2791, 1707, 3315, +495, 969, -853, -1450, -1425, -1976, -802, -1051, +385, 158, 1209, 849, 947, 1131, -123, 779, +-913, -208, -764, -1210, -203, -1141, 369, -17, +900, 1237, 742, 1124, -153, -52, -1264, -1171, +-1212, -992, 239, 129, 1509, 1074, 1361, 908, +-48, 51, -1429, -949, -1661, -1150, -592, -406, +1312, 881, 2456, 1561, 1211, 691, -1356, -809, +-2889, -1545, -1597, -904, 1302, 300, 2747, 951, +1652, 1166, -548, 899, -1974, -135, -1809, -1602, +-603, -2219, 972, -768, 1976, 1969, 1665, 3223, +-41, 1610, -2109, -1850, -2274, -3787, -314, -2266, +1703, 1319, 1877, 3699, 501, 2622, -611, -543, +-632, -2811, -861, -2612, -1083, -510, -390, 1555, +1427, 2287, 2409, 1462, 1000, -261, -1680, -1698, +-2867, -1876, -1350, -861, 1314, 804, 2580, 1872, +1584, 1584, -553, 32, -1861, -1428, -1569, -1589, +-478, -588, 691, 491, 1537, 823, 1496, 900, +352, 836, -1349, 323, -2149, -1080, -1080, -2037, +1021, -1364, 2118, 1000, 1517, 2740, -75, 1981, +-1791, -674, -2186, -2705, -604, -2125, 1616, 293, +2472, 2016, 871, 1695, -1603, 72, -2262, -917, +-556, -803, 1340, -410, 1473, -287, 152, -131, +-879, 470, -657, 1173, 386, 1070, 368, -168, +-478, -1697, -618, -2001, 386, -272, 1267, 1933, +640, 2517, -1070, 706, -1556, -1709, -318, -2510, +1109, -1155, 1262, 939, 336, 2162, -481, 1798, +-859, 100, -943, -1882, -397, -2556, 695, -881, +1599, 1838, 1132, 2992, -656, 1188, -2036, -1751, +-1677, -2869, 401, -1290, 2264, 1419, 2083, 2402, +-228, 1214, -2351, -766, -2039, -1561, 214, -1104, +2101, -208, 1618, 516, -468, 1136, -1501, 1199, +-720, 275, 638, -1080, 853, -1671, -228, -768, +-1006, 584, -301, 1465, 920, 1148, 1349, 171, +259, -843, -1311, -1212, -1702, -787, -635, -107, +1089, 613, 1898, 1172, 1271, 1336, -270, 475, +-1727, -1273, -2060, -2535, -900, -1607, 1070, 981, +2723, 3172, 2209, 2568, -285, -260, -2844, -2942, +-3097, -3184, -630, -701, 2197, 2040, 3131, 2997, +1576, 1716, -848, -532, -2518, -2147, -2329, -2479, +-768, -1106, 1310, 1187, 2515, 2516, 2136, 1891, +208, -22, -2151, -1461, -2859, -1700, -1343, -1377, +1170, -432, 2431, 1138, 1929, 2599, 394, 2162, +-1043, -502, -2040, -3117, -2049, -2905, -467, -148, +1799, 2586, 2697, 2638, 1338, 603, -725, -1238, +-2014, -1477, -1719, -833, -834, -361, 286, -61, +1553, 825, 2320, 1573, 1479, 1151, -824, -351, +-2835, -1622, -2867, -1699, -515, -707, 2396, 688, +3578, 1968, 1809, 1900, -1220, 349, -3235, -1821, +-2580, -2497, -244, -1037, 1956, 1244, 2488, 2179, +1513, 1278, -167, -488, -1672, -1205, -2078, -924, +-1383, -264, 146, 64, 1706, 262, 2360, 636, +1467, 728, -625, 365, -2433, -363, -2509, -770, +-829, -866, 1462, -508, 2798, 183, 2177, 1174, +95, 1507, -2126, 562, -2965, -1004, -1636, -1884, +842, -1375, 2772, 69, 2714, 1601, 718, 2268, +-1848, 1203, -2986, -1145, -1779, -2651, 410, -1898, +1995, 435, 2226, 2013, 1335, 1879, -467, 742, +-2180, -662, -2617, -1780, -816, -1767, 1688, -292, +2724, 1605, 1410, 1773, -649, 348, -1658, -897, +-1399, -697, -526, 46, 275, -84, 717, -751, +1058, -441, 1173, 761, 490, 1660, -992, 829, +-2204, -659, -1603, -1610, 506, -1371, 2330, -329, +2086, 1138, 164, 1946, -1480, 1374, -1699, -571, +-943, -2025, 178, -1761, 841, -138, 1159, 1275, +1090, 1510, 392, 868, -864, -106, -1734, -878, +-1480, -1178, 124, -785, 1808, -9, 1862, 745, +436, 973, -942, 833, -1390, 484, -851, -282, +-216, -1412, 193, -2137, 816, -919, 1307, 1737, +935, 3324, -186, 1867, -1543, -1353, -2043, -3302, +-866, -2403, 1302, 158, 2521, 2258, 1640, 2534, +-432, 1206, -2142, -725, -1975, -2093, -562, -2035, +913, -752, 1714, 969, 1577, 2066, 441, 1924, +-1012, 438, -1899, -1516, -1592, -2420, -127, -1462, +1578, 562, 2187, 1941, 1131, 1920, -763, 698, +-1967, -903, -1686, -1989, -318, -1643, 928, -12, +1680, 1479, 1537, 1733, 310, 789, -1402, -427, +-2265, -1317, -1145, -1474, 914, -503, 2056, 984, +1480, 1645, -271, 786, -1368, -688, -1209, -1324, +-241, -541, 481, 629, 502, 857, 339, -141, +316, -952, 222, -211, -134, 1107, -691, 1035, +-822, -583, -236, -1537, 688, -500, 1044, 928, +495, 916, -474, -126, -907, -455, -522, 94, +294, 351, 543, -258, 67, -747, -238, -272, +-8, 654, 358, 875, 431, 93, -298, -709, +-878, -405, -768, 202, 200, 247, 1067, -323, +1324, -309, 230, 469, -1187, 743, -1686, 23, +-829, -763, 735, -563, 1866, 282, 1506, 536, +-155, 15, -1671, -399, -1868, -169, -588, 480, +957, 531, 1711, -14, 1289, -775, 143, -769, +-1073, 5, -1815, 887, -1290, 903, 104, 39, +1709, -851, 2098, -753, 955, 23, -978, 659, +-2266, 513, -2005, -168, -237, -634, 1701, -399, +2555, 517, 1586, 993, -640, 265, -2456, -943, +-2603, -1256, -706, -275, 1659, 958, 2867, 1356, +1837, 650, -519, -607, -2218, -1382, -2266, -946, +-930, 223, 793, 919, 1947, 754, 1951, 358, +877, 172, -967, -297, -2454, -1159, -2164, -1339, +-211, 40, 1992, 1691, 2475, 1781, 1012, 46, +-882, -1430, -1530, -1306, -1301, -237, -649, 466, +-51, 522, 857, 433, 1674, 382, 1561, 158, +112, -257, -1667, -664, -2332, -684, -1367, -159, +537, 582, 2088, 773, 2348, 311, 1005, -190, +-1055, -291, -2497, -284, -2203, -274, -361, -12, +1626, 261, 2314, 33, 1392, -320, -117, 89, +-1126, 964, -1608, 924, -1617, -525, -953, -1827, +912, -1413, 2913, 366, 2783, 1794, 134, 1863, +-2834, 661, -3646, -982, -1692, -2280, 1433, -1993, +3461, 69, 3096, 2294, 504, 2647, -2569, 736, +-3827, -1653, -2124, -2417, 1128, -1203, 3376, 630, +3044, 1401, 372, 1030, -2130, 411, -2994, 64, +-1702, -473, 589, -1123, 2200, -1188, 2276, -160, +906, 1024, -1157, 1385, -2140, 749, -1588, -160, +30, -765, 1255, -1003, 1348, -954, 803, -393, +282, 704, -390, 1800, -1363, 1710, -1998, 15, +-930, -2170, 1483, -2605, 3143, -495, 2132, 2049, +-1029, 2353, -3464, 373, -2915, -1225, 35, -846, +2642, 63, 3014, -52, 1208, -704, -1206, -411, +-2520, 682, -2063, 1396, -354, 992, 1348, -143, +2043, -1363, 1413, -1798, 287, -856, -1033, 977, +-1925, 2122, -1799, 1496, -327, -229, 1685, -1518, +2429, -1574, 1376, -787, -642, 129, -1866, 1081, +-1745, 1723, -649, 1377, 482, -319, 1300, -2194, +1478, -2401, 928, -426, -169, 1906, -1246, 2440, +-1789, 862, -1299, -952, 261, -1604, 1783, -1123, +2151, -241, 985, 569, -825, 1078, -2199, 821, +-2033, 43, -475, -335, 1492, -297, 2246, -464, +1259, -1033, -391, -731, -1434, 902, -1404, 2259, +-806, 1492, 97, -912, 977, -2549, 1392, -1807, +953, 445, 8, 2017, -1078, 1814, -1689, 360, +-1132, -993, 420, -1561, 1904, -1119, 1960, 19, +294, 1104, -1598, 1514, -2104, 816, -865, -482, +913, -1475, 1826, -1309, 1341, -102, -90, 1063, +-1333, 1204, -1501, 385, -619, -430, 670, -595, +1328, -303, 1014, -197, 10, -365, -930, -243, +-962, 611, -377, 1317, 46, 777, 251, -869, +454, -1827, 891, -987, 756, 714, -296, 1489, +-1548, 834, -1629, -154, -241, -744, 1485, -635, +2039, -262, 905, 203, -896, 312, -1744, 114, +-1131, -19, -98, 163, 667, 347, 968, 100, +1162, -319, 713, -542, -514, -317, -1779, 42, +-1626, 448, 234, 706, 1758, 569, 1559, -118, +20, -973, -1079, -1062, -930, -80, 53, 1121, +453, 1252, 81, 88, -457, -1088, -185, -906, +643, 174, 890, 782, 68, 273, -914, -257, +-1028, -233, -183, 25, 587, -76, 746, -212, +383, 62, -246, 369, -499, 264, -270, -108, +90, -259, 55, -209, -131, -241, -16, -392, +288, -192, 301, 468, 51, 1186, -128, 1037, +-118, -332, -251, -1829, -414, -1972, -40, -429, +763, 1523, 898, 2354, -22, 1667, -881, -130, +-829, -2092, 10, -2809, 617, -1420, 709, 1297, +302, 2908, -298, 2143, -701, 23, -523, -1516, +66, -1766, 583, -1174, 663, -178, 281, 877, +-340, 1414, -1070, 1071, -925, 192, 206, -496, +1402, -706, 1316, -610, -87, -536, -1436, -368, +-1473, 199, -245, 1132, 916, 1501, 1182, 418, +561, -1311, -90, -1855, -444, -411, -652, 1276, +-779, 1261, -565, -291, 285, -1323, 1424, -569, +1669, 991, 462, 1413, -1352, 258, -2255, -1152, +-1329, -1497, 687, -682, 2253, 337, 2045, 1124, +371, 1357, -1344, 793, -2005, -532, -1403, -1738, +-77, -1642, 1315, -159, 2065, 1444, 1313, 1693, +-509, 549, -1879, -789, -1670, -1059, -417, -544, +732, 139, 1234, 364, 1083, 410, 415, 379, +-590, 183, -1261, -245, -1133, -624, -126, -394, +789, 273, 1016, 688, 641, 467, 15, 26, +-434, -165, -809, -241, -882, -516, -355, -643, +771, -99, 1497, 953, 1096, 1407, -393, 566, +-1632, -836, -1453, -1435, 12, -828, 1251, 144, +1499, 578, 744, 638, -482, 609, -1304, 387, +-1270, -194, -266, -730, 910, -748, 1238, -419, +727, -136, 21, 153, -519, 590, -1006, 868, +-1218, 585, -549, -219, 785, -814, 1792, -957, +1446, -567, -153, -17, -1550, 492, -1856, 701, +-1006, 541, 432, 295, 1606, 153, 1859, -119, +663, -726, -1038, -1287, -1853, -958, -1142, 380, +180, 1772, 1000, 1881, 947, 523, 569, -1179, +138, -1601, -278, -733, -699, 204, -779, 301, +-283, 210, 397, 660, 703, 1056, 665, 622, +303, -398, -195, -1017, -565, -948, -594, -561, +-303, -57, 162, 587, 399, 1172, 489, 1162, +495, 374, -18, -812, -793, -1454, -919, -1156, +-163, -68, 776, 763, 998, 976, 9, 565, +-895, 61, -817, -395, 36, -604, 645, -467, +470, -65, -9, 182, -274, 37, -145, -74, +-77, 145, -271, 305, -314, 45, 104, -301, +689, -176, 700, 139, 25, 178, -616, -120, +-624, -300, -268, -354, 89, -90, 416, 451, +669, 932, 512, 650, -128, -312, -624, -1055, +-527, -955, -67, -211, 229, 692, 170, 1215, +89, 960, 88, -142, 335, -1131, 333, -907, +-188, 184, -872, 847, -845, 317, -82, -423, +806, -381, 949, 332, 193, 697, -374, 244, +-451, -507, -425, -805, -473, -350, -214, 440, +336, 853, 863, 492, 576, -414, -191, -1097, +-679, -852, -411, 310, -31, 1324, 116, 1048, +9, -331, 111, -1287, 435, -918, 515, -27, +36, 361, -539, 319, -552, 461, -109, 503, +228, 4, 281, -566, 219, -648, 130, -280, +123, -5, 74, 192, -133, 465, -359, 537, +-422, 204, -217, -294, 197, -564, 428, -383, +401, 38, 217, 519, -94, 569, -459, 38, +-596, -615, -384, -476, 98, 461, 435, 1106, +350, 443, 72, -842, -38, -1369, -28, -457, +-62, 1028, -236, 1507, -440, 560, -196, -848, +300, -1194, 569, -251, 474, 611, -195, 501, +-581, -184, -301, -455, 329, -101, 562, 314, +240, 515, -370, 329, -588, -276, -226, -847, +321, -874, 544, -205, 310, 564, 58, 986, +-121, 979, -244, 234, -577, -1033, -500, -1787, +102, -943, 749, 765, 694, 1567, 86, 721, +-518, -395, -664, -625, -393, -55, 120, 275, +382, 11, 405, -446, 67, -723, -355, -396, +-407, 373, -26, 1147, 343, 1277, 346, 522, +-122, -606, -546, -1467, -298, -1432, 357, -341, +700, 982, 326, 1476, -438, 898, -746, 63, +-421, -319, 323, -487, 894, -604, 976, -460, +92, -124, -1101, 103, -1428, 184, -354, 560, +1007, 1027, 1330, 584, 564, -645, -121, -1388, +-535, -690, -817, 443, -891, 464, -441, -300, +512, -377, 1258, 650, 1110, 1345, 63, 569, +-991, -1030, -1245, -1775, -535, -1061, 399, 413, +701, 1183, 247, 896, -127, 104, -80, -256, +179, -191, 155, -229, -32, -408, -297, -365, +-422, -52, -257, 176, 197, 259, 482, 399, +306, 493, -217, 96, -185, -548, 393, -677, +542, -78, -140, 587, -830, 498, -849, -26, +-47, -374, 868, -219, 1088, 56, 353, 199, +-556, 179, -681, 135, -120, 156, 207, 219, +-221, 73, -542, -448, -30, -804, 885, -412, +1029, 574, 151, 1075, -914, 535, -1265, -442, +-681, -781, 421, -239, 1182, 387, 958, 321, +25, -401, -793, -659, -926, -68, -377, 665, +163, 529, 488, -167, 554, -370, 342, 22, +-9, 115, -307, -341, -382, -552, -353, -43, +-141, 510, 238, 372, 495, -42, 387, -116, +114, 23, -93, -71, -372, -306, -485, -171, +-202, 138, 403, 262, 724, 175, 350, 121, +-460, 37, -831, -213, -464, -391, 350, -234, +944, 228, 770, 686, -145, 728, -1002, 65, +-1049, -849, -301, -1044, 592, -152, 969, 812, +644, 811, -9, 120, -512, -271, -641, -36, +-472, 126, -240, -132, 82, -509, 497, -489, +866, -56, 677, 537, -203, 857, -1033, 567, +-1053, -288, -226, -1010, 670, -821, 1101, -8, +669, 639, -205, 534, -833, 68, -649, -251, +-25, -242, 406, -31, 359, 51, 265, -80, +208, -203, -63, -40, -508, 173, -682, 37, +-191, -209, 585, 62, 942, 537, 427, 393, +-473, -525, -903, -1036, -500, -361, 164, 709, +363, 983, 152, 224, 74, -489, 300, -414, +363, 207, -85, 401, -700, -96, -811, -709, +-240, -440, 625, 445, 972, 1045, 585, 537, +-346, -411, -910, -769, -654, -359, 195, 209, +742, 478, 600, 429, 43, 39, -443, -568, +-617, -737, -364, -111, 179, 664, 670, 718, +639, 178, 178, -171, -380, -181, -594, -282, +-402, -481, -7, -456, 207, -87, 183, 227, +152, 386, 335, 558, 390, 578, -25, 107, +-760, -678, -921, -968, -177, -437, 753, 237, +970, 347, 281, 8, -565, -131, -775, 150, +-334, 529, 232, 632, 456, 275, 336, -460, +176, -1011, 59, -898, -195, -226, -690, 449, +-847, 698, -26, 739, 1172, 660, 1414, 322, +239, -373, -1073, -1024, -1255, -925, -346, -60, +546, 745, 644, 728, 243, 31, -23, -406, +-55, -161, 24, 296, -28, 502, -222, 323, +-291, -46, -100, -523, 173, -846, 327, -585, +276, 191, 36, 858, -237, 793, -390, 162, +-319, -355, 40, -359, 420, -161, 478, -74, +96, -219, -311, -238, -470, -48, -268, 267, +95, 403, 383, 160, 331, -178, -70, -309, +-291, -120, -129, 68, 54, 105, 20, 48, +-48, -96, 165, -276, 416, -296, 178, 46, +-409, 461, -705, 567, -421, 232, 193, -250, +768, -674, 884, -717, 413, -197, -447, 684, +-1106, 1111, -977, 559, -102, -432, 757, -873, +1038, -478, 630, 59, -75, 210, -596, 209, +-732, 459, -509, 582, -116, 112, 270, -690, +651, -880, 715, -147, 291, 702, -470, 804, +-791, 98, -507, -507, -20, -436, 333, 20, +417, 180, 327, -53, 150, -146, -95, 150, +-308, 394, -350, 205, -185, -217, 247, -389, +489, -230, 141, -52, -542, -16, -654, -43, +145, 22, 970, 206, 893, 398, -157, 423, +-1091, -6, -1035, -676, -112, -1027, 730, -500, +924, 532, 431, 1089, -230, 686, -587, -169, +-479, -668, -74, -521, 232, -57, 249, 276, +26, 248, -39, -34, 51, -201, 200, -125, +8, 109, -367, 335, -381, 469, 126, 277, +440, -389, 256, -941, -187, -651, -286, 354, +-149, 958, -29, 596, 142, -112, 411, -267, +395, 8, -158, 89, -726, -209, -625, -478, +78, -423, 693, -135, 631, 319, 87, 755, +-333, 859, -283, 368, -36, -435, 32, -980, +-240, -913, -363, -351, -59, 363, 563, 745, +855, 576, 393, 159, -558, -91, -1137, -69, +-802, -188, 351, -420, 1301, -457, 1027, -139, +-322, 288, -1365, 445, -955, 267, 360, -87, +1149, -286, 791, -68, -206, 295, -863, 275, +-680, -213, 124, -642, 672, -484, 432, 71, +-303, 539, -529, 686, -8, 481, 493, 37, +387, -525, -133, -809, -555, -586, -506, -36, +-18, 440, 532, 646, 722, 623, 234, 375, +-456, -50, -720, -515, -278, -814, 356, -807, +465, -269, 80, 635, -283, 1298, -246, 967, +86, -160, 325, -1090, 251, -1055, -107, -198, +-328, 724, -248, 916, -94, 210, 88, -664, +186, -716, 212, 4, -6, 461, -196, 211, +77, -63, 476, 207, 196, 490, -621, 21, +-984, -711, -274, -832, 724, -245, 995, 373, +468, 572, -202, 554, -578, 387, -604, 0, +-271, -478, 80, -661, 365, -404, 428, 46, +109, 351, -161, 415, -174, 205, -26, -97, +154, -209, 136, -15, -211, 212, -458, 140, +-273, -218, 244, -486, 618, -328, 475, 234, +-96, 601, -447, 268, -305, -376, -22, -417, +48, 207, -135, 566, -156, 117, 274, -447, +591, -466, 310, -199, -298, -116, -588, -25, +-363, 449, 47, 859, 342, 560, 394, -337, +144, -989, -231, -821, -321, -113, -109, 518, +98, 676, 71, 312, 59, -163, 128, -302, +169, 52, 10, 350, -274, 76, -381, -506, +-147, -602, 248, -22, 395, 578, 188, 512, +-139, 0, -227, -282, -75, -21, 103, 276, +51, 108, -108, -330, -193, -505, -103, -239, +189, 205, 382, 570, 238, 637, -230, 220, +-544, -478, -272, -795, 302, -396, 512, 214, +168, 476, -212, 372, -234, 149, -199, -155, +-117, -477, 97, -400, 334, 92, 250, 512, +-91, 352, -270, -156, -140, -446, 52, -241, +160, 90, 61, 177, -101, -59, -178, -178, +-22, 52, 191, 392, 70, 322, -85, -206, +-24, -573, 152, -334, 113, 217, -220, 427, +-298, 149, -20, -197, 203, -301, 123, -74, +4, 298, 12, 495, 32, 186, -13, -348, +-25, -483, 18, -104, -51, 179, -255, 80, +-169, 20, 255, 221, 387, 307, 109, 62, +-171, -189, -196, -218, -27, -131, 28, -28, +26, 169, -54, 264, -85, 103, -17, -151, +221, -222, 220, -122, -38, -63, -247, 45, +-185, 243, -6, 376, 223, 250, 272, -93, +12, -492, -375, -774, -511, -599, -12, 210, +585, 1122, 618, 1156, 46, 123, -484, -998, +-585, -1204, -316, -538, 157, 295, 637, 817, +623, 801, -48, 250, -817, -437, -725, -708, +224, -491, 904, -114, 598, 213, -242, 499, +-704, 505, -564, 170, 20, -181, 555, -247, +573, -277, 74, -432, -393, -308, -355, 340, +6, 874, 188, 578, 20, -304, -148, -770, +-71, -344, 298, 467, 481, 744, 74, 139, +-719, -690, -903, -825, -66, -74, 1028, 766, +1173, 866, 105, 275, -1040, -373, -1175, -610, +-286, -426, 689, 9, 1043, 404, 422, 362, +-365, -107, -702, -380, -360, -48, 159, 436, +341, 317, 49, -293, -133, -612, 29, -277, +261, 342, 191, 609, -123, 240, -428, -490, +-316, -792, 237, -259, 557, 564, 199, 737, +-379, 202, -399, -334, 133, -498, 369, -458, +58, -259, -319, 267, -193, 785, 182, 615, +323, -209, 123, -897, -181, -713, -306, 94, +-77, 769, 144, 753, 86, 141, -130, -510, +-160, -643, 89, -241, 322, 225, 337, 336, +98, 207, -247, 202, -584, 272, -621, 101, +-105, -384, 616, -717, 815, -514, 361, 209, +-280, 924, -426, 1043, -249, 312, -176, -743, +-81, -1181, 174, -625, 345, 348, 109, 813, +-181, 502, -224, -67, 7, -243, 251, 14, +259, 113, 61, -206, -128, -507, -231, -244, +-221, 301, -164, 444, -86, 105, 188, -186, +446, -162, 356, -42, -58, 13, -345, 82, +-269, 100, -74, -78, 47, -295, 35, -254, +59, 109, 82, 368, 61, 251, -54, -44, +-104, -261, -88, -289, 94, -186, 201, 121, +181, 471, -48, 464, -313, 5, -352, -523, +-56, -622, 274, -253, 449, 282, 337, 619, +-117, 517, -625, 34, -602, -350, 77, -314, +777, -31, 788, 91, 68, -74, -614, -193, +-769, -41, -433, 331, 191, 496, 637, 179, +579, -416, 79, -584, -305, -102, -258, 542, +27, 559, 15, -95, -246, -696, -349, -593, +15, 109, 517, 712, 603, 689, 20, 114, +-587, -561, -601, -758, -91, -340, 523, 277, +643, 528, 135, 360, -473, 123, -652, -87, +-279, -421, 326, -628, 625, -250, 363, 499, +-136, 766, -469, 268, -342, -363, 54, -542, +339, -323, 317, -38, 82, 274, -237, 479, +-368, 383, -241, -49, 41, -518, 299, -630, +422, -300, 318, 309, 19, 769, -430, 689, +-619, 43, -315, -682, 163, -804, 440, -246, +449, 423, 259, 607, -26, 283, -316, -160, +-504, -348, -447, -204, -23, 72, 496, 184, +731, 77, 395, 4, -337, 72, -872, 70, +-653, -111, 182, -276, 940, -246, 771, -6, +-135, 290, -868, 492, -730, 315, 77, -223, +712, -608, 621, -477, 49, 4, -418, 379, +-415, 508, -80, 428, 152, 5, 112, -592, +-50, -837, -29, -359, 121, 463, 273, 875, +212, 595, -116, -23, -416, -482, -400, -571, +-112, -386, 201, -123, 377, 89, 398, 326, +184, 586, -153, 608, -482, 81, -454, -736, +-79, -1039, 283, -491, 343, 420, 156, 934, +41, 803, 91, 217, -19, -500, -384, -915, +-583, -758, -248, -110, 478, 597, 885, 926, +557, 682, -278, -18, -852, -628, -673, -715, +43, -399, 571, -104, 455, 155, 20, 567, +-174, 807, -99, 385, 14, -508, -9, -933, +-64, -485, -29, 261, 58, 568, 25, 368, +-66, 104, -174, -64, -52, -246, 196, -385, +338, -331, 169, -18, -175, 414, -350, 684, +-182, 473, 20, -233, 9, -871, -17, -717, +155, 68, 286, 667, 155, 524, -121, 0, +-202, -283, -130, -165, -131, 59, -135, 80, +85, -112, 309, -174, 265, 61, -27, 276, +-218, 105, -119, -328, 26, -440, 25, -38, +-74, 471, -82, 579, 76, 219, 259, -268, +193, -545, -66, -539, -298, -303, -326, 166, +-99, 705, 269, 870, 450, 299, 297, -684, +-129, -1084, -510, -465, -452, 603, -16, 930, +340, 231, 364, -590, 188, -573, 53, 141, +-85, 568, -343, 241, -456, -338, -219, -479, +253, -106, 535, 338, 453, 444, 121, 168, +-231, -176, -532, -323, -554, -238, -213, -84, +319, 31, 696, 133, 644, 243, 91, 312, +-559, 266, -752, -76, -387, -472, 225, -569, +568, -192, 445, 288, 56, 375, -274, 193, +-332, 85, -124, 160, 105, 81, 150, -272, +78, -516, -41, -277, -66, 182, -68, 299, +-53, 85, 54, 50, 222, 322, 153, 269, +-96, -395, -315, -897, -245, -446, 50, 628, +259, 1071, 199, 391, 31, -559, -67, -795, +-52, -304, -14, 168, -72, 222, -145, 151, +-82, 145, 122, 194, 206, 170, 110, 11, +14, -263, -5, -490, -91, -346, -223, 111, +-209, 400, -8, 311, 255, 123, 378, 81, +246, 50, -97, -117, -448, -314, -533, -366, +-117, -288, 392, 19, 567, 552, 300, 915, +-46, 549, -342, -494, -532, -1293, -475, -1013, +32, 120, 726, 1100, 906, 1183, 211, 471, +-697, -387, -971, -891, -413, -848, 346, -414, +693, 109, 517, 569, 88, 863, -261, 733, +-374, 93, -287, -715, -71, -1033, 119, -661, +152, 43, 78, 677, 48, 886, 159, 525, +198, -185, -60, -720, -397, -686, -414, -236, +44, 284, 546, 630, 470, 575, -192, 68, +-670, -551, -425, -737, 333, -302, 782, 317, +469, 630, -238, 501, -680, 116, -642, -351, +-205, -626, 413, -491, 817, 96, 638, 638, +-93, 608, -807, 25, -836, -553, -134, -510, +541, 93, 658, 554, 264, 305, -121, -332, +-240, -456, -177, 40, -197, 357, -259, 38, +-139, -261, 270, 32, 576, 421, 461, 195, +-58, -354, -505, -453, -562, -58, -267, 240, +174, 183, 519, -9, 500, -20, 17, 80, +-472, 85, -441, -40, 34, -226, 434, -210, +300, 15, -147, 213, -352, 176, -215, -51, +57, -166, 248, -98, 248, 60, 166, 151, +-57, 134, -344, -31, -466, -227, -155, -202, +391, 66, 673, 223, 333, 31, -307, -130, +-651, 5, -412, 172, 88, 35, 414, -175, +401, -55, 142, 151, -136, 41, -282, -204, +-217, -191, -77, 104, 79, 320, 256, 236, +339, -19, 101, -284, -324, -316, -547, -93, +-227, 189, 299, 265, 502, 126, 327, 0, +79, 13, -156, 13, -372, -137, -541, -332, +-368, -307, 212, 2, 731, 376, 712, 551, +136, 459, -541, 55, -758, -504, -330, -905, +283, -723, 595, 92, 328, 942, -297, 1013, +-600, 201, -189, -601, 482, -554, 725, 15, +215, 162, -546, -292, -709, -495, -254, 18, +257, 721, 388, 761, 259, 111, 87, -610, +-3, -779, -91, -269, -160, 410, -187, 631, +-111, 260, 49, -292, 211, -459, 179, -212, +21, 171, -79, 362, -60, 211, -110, -113, +-248, -322, -101, -198, 406, 169, 631, 435, +164, 285, -587, -210, -832, -600, -298, -512, +466, 42, 763, 583, 465, 699, -157, 290, +-573, -269, -460, -524, 29, -432, 336, -172, +252, 38, -33, 202, -82, 325, 25, 338, +38, 281, -130, 46, -224, -395, -96, -766, +239, -565, 428, 207, 271, 830, -134, 741, +-425, 112, -439, -451, -219, -605, 130, -360, +460, 72, 641, 364, 339, 294, -350, -45, +-834, -246, -591, -53, 105, 282, 626, 320, +580, -82, 125, -493, -252, -446, -319, 29, +-227, 501, -167, 481, -31, 29, 233, -370, +450, -336, 231, -32, -284, 103, -471, 102, +-84, 238, 284, 358, 164, -1, -119, -610, +-72, -676, 165, 53, 86, 750, -218, 590, +-224, -127, 121, -503, 326, -190, 135, 209, +-168, 126, -209, -225, -41, -214, 91, 195, +91, 436, -27, 123, -129, -374, -56, -491, +107, -100, 205, 406, 131, 535, -49, 177, +-200, -307, -203, -469, -72, -175, 112, 198, +170, 230, 46, -73, -58, -299, -12, -114, +87, 348, 34, 547, -67, 271, -109, -273, +-92, -630, -95, -548, 12, -120, 231, 329, +341, 451, 106, 343, -270, 248, -444, 87, +-247, -327, 144, -690, 415, -453, 379, 211, +-2, 552, -378, 256, -312, -104, 120, -46, +388, 216, 107, 209, -400, -199, -504, -603, +-28, -538, 601, 62, 719, 710, 136, 741, +-615, 111, -764, -531, -167, -529, 517, 2, +556, 370, 41, 170, -382, -286, -381, -463, +-72, -138, 282, 451, 480, 801, 297, 464, +-206, -383, -659, -927, -546, -592, 101, 185, +651, 578, 608, 396, 10, 4, -528, -210, +-504, -176, 2, 11, 415, 128, 301, 25, +-165, -96, -320, -47, 1, 58, 359, -9, +270, -184, -170, -155, -501, 77, -351, 269, +132, 259, 484, 78, 490, -173, 156, -310, +-257, -222, -477, -29, -450, 48, -121, 56, +399, 213, 586, 400, 213, 215, -321, -333, +-438, -607, -64, -242, 234, 266, 44, 304, +-149, 83, 41, 66, 343, 135, 286, -42, +-190, -307, -639, -257, -549, 56, 82, 282, +758, 280, 860, 87, 196, -209, -657, -366, +-876, -188, -373, 152, 280, 319, 601, 254, +484, 159, 100, 9, -338, -269, -544, -487, +-227, -372, 284, 60, 463, 474, 164, 610, +-190, 359, -270, -167, -112, -657, -6, -664, +75, -115, 137, 530, 144, 659, 35, 216, +-79, -329, -136, -540, -128, -313, -137, 121, +-94, 396, 144, 297, 427, 14, 445, -75, +29, -30, -594, -229, -803, -517, -297, -364, +446, 300, 786, 805, 525, 628, -74, 4, +-480, -598, -468, -770, -182, -394, 114, 237, +233, 575, 103, 402, -9, 126, 59, 23, +141, -107, 40, -410, -177, -553, -323, -173, +-113, 451, 269, 761, 432, 465, 152, -160, +-297, -666, -521, -642, -251, -83, 236, 525, +491, 598, 350, 132, -10, -256, -339, -204, +-373, -78, -143, -121, 147, -92, 252, 175, +90, 322, -126, 119, -117, -97, 100, -115, +229, -157, 48, -324, -277, -216, -363, 328, +16, 742, 405, 432, 334, -432, -148, -999, +-456, -629, -212, 368, 291, 1000, 474, 629, +182, -271, -275, -792, -501, -581, -337, -36, +114, 385, 544, 527, 550, 348, 73, -97, +-437, -481, -567, -427, -250, -44, 199, 157, +387, 45, 282, 34, 80, 361, -107, 534, +-218, 77, -212, -651, -110, -887, 111, -367, +230, 466, 71, 978, -125, 769, -30, -40, +190, -775, 146, -797, -276, -204, -522, 396, +-82, 567, 569, 347, 604, -26, -18, -297, +-582, -248, -501, -2, 77, 166, 431, 104, +279, -12, -77, -56, -265, -34, -141, 15, +99, 85, 193, 36, 143, -97, -9, -116, +-220, 71, -316, 187, -99, -15, 322, -267, +499, -162, 109, 189, -425, 268, -459, -13, +18, -216, 392, -151, 233, -136, -177, -188, +-243, 70, 60, 553, 235, 533, 27, -214, +-286, -867, -208, -627, 207, 187, 368, 667, +54, 410, -305, -106, -271, -256, 25, -44, +147, 59, 51, -151, 107, -282, 237, -7, +78, 329, -316, 285, -484, -25, -170, -164, +363, -70, 543, -11, 239, -8, -207, 93, +-474, 187, -302, 47, 152, -230, 381, -220, +181, 145, -155, 386, -258, 168, -69, -195, +166, -213, 199, 51, 60, 164, -164, -14, +-258, -198, -25, -110, 296, 180, 245, 312, +-155, 79, -414, -238, -134, -213, 334, 117, +421, 222, 67, -63, -293, -341, -398, -262, +-211, 23, 100, 259, 359, 332, 378, 244, +189, -13, -139, -276, -414, -418, -490, -433, +-221, -279, 281, 127, 616, 593, 461, 673, +-14, 242, -362, -316, -375, -561, -267, -496, +-106, -320, 142, -37, 353, 365, 331, 600, +127, 390, -92, -58, -193, -258, -255, -201, +-278, -218, -152, -304, 181, -120, 486, 312, +456, 522, 25, 280, -508, -83, -583, -213, +-103, -145, 395, -84, 406, -77, 39, 52, +-188, 322, -122, 372, -35, -74, -60, -578, +11, -418, 169, 349, 184, 781, -16, 379, +-205, -308, -222, -556, -89, -334, 57, -29, +182, 179, 251, 290, 148, 262, -55, 104, +-144, -59, -138, -162, -183, -255, -221, -311, +-68, -172, 255, 137, 525, 356, 426, 334, +-65, 152, -562, -139, -630, -485, -198, -646, +361, -245, 525, 491, 269, 843, -76, 423, +-243, -359, -244, -859, -112, -701, 99, 36, +207, 790, 74, 814, -155, 54, -134, -654, +141, -593, 278, -50, 65, 263, -336, 207, +-489, 109, -149, 115, 472, 117, 780, 32, +332, -159, -509, -331, -893, -257, -407, 148, +387, 543, 624, 472, 247, 1, -110, -375, +-144, -383, -48, -166, -40, 78, -123, 334, +-149, 474, -17, 248, 177, -237, 245, -520, +144, -329, -131, 83, -311, 349, -178, 346, +107, 166, 309, -73, 269, -208, -27, -262, +-329, -327, -356, -258, -93, 199, 182, 738, +264, 629, 199, -178, 156, -822, 27, -716, +-253, -156, -410, 299, -234, 491, 95, 450, +292, 133, 229, -281, 180, -483, 150, -367, +-96, -97, -438, 170, -471, 354, -47, 297, +476, -32, 582, -322, 156, -285, -418, -20, +-588, 167, -182, 224, 430, 237, 572, 67, +109, -347, -449, -573, -496, -179, -16, 520, +414, 756, 353, 302, 17, -309, -257, -552, +-279, -348, -74, 63, 111, 364, 162, 337, +111, 87, -9, -93, -70, -82, 3, 2, +56, 60, -43, 15, -199, -152, -225, -249, +64, 35, 395, 523, 332, 542, -74, -118, +-377, -769, -301, -665, 55, 67, 241, 699, +120, 714, -23, 164, -63, -531, -39, -787, +-13, -360, -24, 350, -1, 605, 80, 199, +74, -318, -52, -370, -123, -58, -81, 199, +62, 177, 157, -22, 88, -216, -22, -242, +-62, -28, -119, 168, -190, 70, -138, -143, +108, -64, 397, 261, 416, 349, 66, 10, +-396, -409, -588, -528, -365, -249, 124, 229, +503, 593, 515, 557, 187, 150, -215, -319, +-397, -536, -307, -403, -32, 9, 236, 432, +292, 517, 74, 190, -269, -228, -375, -329, +-47, -72, 432, 206, 554, 207, 161, -42, +-386, -229, -605, -86, -337, 242, 87, 366, +326, 67, 340, -348, 244, -418, 75, -82, +-109, 311, -309, 401, -342, 169, -155, -163, +135, -372, 306, -283, 293, 42, 108, 265, +-144, 138, -300, -145, -260, -191, -49, 10, +256, 155, 374, 85, 163, -79, -237, -223, +-453, -229, -221, -34, 280, 248, 461, 269, +139, -35, -348, -313, -421, -245, -11, 54, +443, 270, 400, 226, -70, -5, -451, -265, +-414, -374, -5, -199, 400, 208, 434, 582, +117, 554, -271, 38, -421, -576, -187, -720, +208, -274, 365, 307, 153, 527, -162, 408, +-251, 252, -82, 153, 105, -98, 89, -495, +-2, -678, -18, -363, 54, 280, 117, 802, +44, 872, -142, 367, -302, -473, -204, -1050, +174, -793, 472, 129, 359, 907, -130, 855, +-479, 91, -352, -654, 54, -738, 305, -174, +203, 405, -51, 463, -123, 114, 5, -161, +105, -207, 38, -203, -67, -167, -79, 23, +-40, 235, -66, 140, -124, -193, 1, -293, +268, 12, 316, 333, 60, 246, -251, -142, +-316, -406, -116, -304, 105, 14, 169, 253, +80, 240, -82, 33, -141, -146, 22, -73, +268, 139, 270, 231, -12, 12, -315, -314, +-385, -418, -228, -148, 21, 322, 295, 593, +463, 429, 362, -23, 8, -354, -383, -382, +-499, -213, -300, -3, 67, 219, 324, 347, +321, 287, 134, 66, -22, -119, -19, -174, +-33, -145, -212, -131, -393, -87, -221, 81, +290, 351, 638, 479, 456, 170, -172, -421, +-750, -793, -684, -529, 10, 218, 739, 850, +852, 832, 203, 123, -621, -711, -914, -957, +-424, -449, 360, 296, 811, 593, 555, 334, +-109, -16, -543, -108, -441, -73, -72, -157, +209, -285, 214, -223, 120, -13, -12, 158, +-106, 250, -59, 289, 80, 138, 91, -240, +-63, -559, -193, -388, -82, 190, 155, 645, +189, 521, -15, -55, -180, -503, -133, -444, +62, -47, 236, 247, 189, 267, -82, 174, +-312, 124, -233, 50, 105, -59, 301, -122, +175, -92, -121, -48, -276, -23, -159, 15, +118, 112, 347, 248, 321, 296, -53, 159, +-467, -181, -493, -475, -91, -411, 344, 38, +486, 443, 268, 435, -83, 53, -282, -236, +-247, -203, -63, -35, 73, -4, 24, -137, +-64, -179, -22, 20, 138, 322, 291, 335, +203, -81, -134, -546, -441, -498, -382, 60, +60, 548, 472, 445, 390, -104, -86, -549, +-415, -499, -316, -21, 36, 422, 384, 433, +456, 37, 105, -312, -406, -296, -655, -14, +-292, 179, 350, 135, 611, -49, 312, -181, +-113, -84, -268, 186, -165, 387, -62, 219, +-50, -200, -107, -454, -46, -246, 145, 193, +293, 420, 249, 298, 18, 47, -197, -135, +-279, -217, -278, -139, -175, 86, 125, 294, +469, 214, 483, -99, 52, -349, -434, -185, +-536, 263, -172, 501, 268, 199, 406, -360, +190, -543, -151, -198, -253, 283, -55, 424, +121, 242, 45, -82, -108, -354, -106, -452, +92, -217, 243, 215, 141, 488, -159, 302, +-373, -152, -261, -455, 191, -391, 536, -59, +363, 187, -206, 231, -552, 73, -338, -94, +87, -147, 321, -47, 235, 71, 56, 48, +-8, -110, 6, -184, -47, -12, -193, 223, +-296, 228, -141, -64, 191, -288, 397, -154, +262, 219, -5, 407, -154, 203, -219, -174, +-245, -379, -177, -264, 71, 74, 327, 378, +305, 384, 80, 169, -128, -54, -249, -130, +-210, -198, -35, -263, 137, -150, 135, 186, +42, 464, 19, 418, 116, 113, 116, -210, +-134, -402, -356, -435, -320, -226, -33, 158, +350, 546, 585, 590, 413, 197, -136, -421, +-656, -804, -678, -567, -198, 126, 413, 681, +673, 575, 466, -14, -70, -508, -517, -500, +-493, -187, -94, 124, 283, 236, 344, 238, +185, 129, 17, -73, -212, -295, -379, -430, +-270, -313, 122, 51, 467, 483, 395, 628, +68, 361, -247, -218, -395, -735, -303, -825, +-58, -297, 200, 540, 315, 1033, 255, 800, +101, 18, -99, -716, -261, -947, -288, -528, +-108, 267, 143, 924, 212, 910, 186, 260, +91, -520, -86, -816, -225, -487, -179, 185, +19, 689, 149, 614, 81, 104, 32, -390, +61, -438, 23, -196, -132, 51, -167, 220, +19, 401, 150, 383, 67, -55, -84, -612, +-122, -668, -37, -115, 81, 452, 177, 588, +183, 317, -14, -35, -243, -373, -259, -555, +-103, -482, 32, -125, 145, 310, 299, 609, +314, 565, 13, 69, -415, -617, -524, -942, +-132, -492, 379, 320, 505, 813, 240, 588, +-178, -2, -389, -460, -275, -544, -72, -363, +42, -35, 198, 350, 419, 622, 429, 505, +-58, -85, -670, -700, -700, -781, -27, -116, +594, 696, 561, 963, 72, 445, -341, -377, +-334, -873, -40, -696, 219, 53, 207, 807, +-28, 958, -178, 378, -92, -390, 25, -810, +-36, -654, -72, -141, 99, 512, 264, 899, +176, 681, -53, -87, -184, -826, -174, -926, +-191, -319, -123, 521, 114, 914, 368, 594, +342, -182, 21, -713, -283, -663, -376, -230, +-229, 147, 117, 369, 347, 489, 276, 385, +19, -47, -163, -582, -196, -744, -185, -431, +-139, 118, 75, 540, 365, 691, 361, 425, +4, -173, -333, -765, -392, -854, -189, -310, +110, 468, 340, 924, 375, 659, 137, -135, +-268, -808, -467, -721, -338, -48, 18, 522, +422, 527, 572, 234, 287, -25, -241, -194, +-635, -338, -541, -273, -48, 77, 454, 416, +614, 412, 331, 62, -170, -220, -493, -234, +-411, -38, -62, 77, 187, 103, 297, 162, +293, 246, 130, 112, -216, -316, -454, -619, +-250, -285, 177, 541, 372, 1001, 206, 548, +-78, -478, -159, -1121, -142, -901, -93, -2, +50, 908, 128, 1179, 85, 537, -63, -584, +-126, -1262, -1, -923, 90, 129, 64, 945, +-44, 903, -81, 101, -10, -662, 110, -779, +130, -258, -27, 309, -201, 488, -220, 327, +-74, 15, 177, -313, 264, -571, 195, -487, +57, 38, -125, 709, -240, 925, -228, 463, +-141, -446, 8, -1131, 183, -1068, 315, -197, +288, 921, 77, 1453, -223, 997, -413, -197, +-352, -1268, -45, -1427, 353, -460, 512, 838, +236, 1421, -235, 846, -455, -191, -261, -852, +65, -873, 218, -454, 205, 253, 152, 1000, +55, 1127, -121, 275, -268, -965, -221, -1415, +-19, -689, 171, 529, 231, 1241, 173, 1080, +24, 237, -136, -746, -253, -1278, -186, -963, +97, 71, 318, 1108, 233, 1361, -101, 537, +-390, -778, -340, -1575, 23, -1198, 371, 70, +484, 1352, 341, 1737, -77, 890, -563, -749, +-779, -2065, -460, -1950, 321, -303, 988, 1690, +959, 2394, 194, 1278, -772, -709, -1215, -2034, +-762, -1837, 284, -427, 1125, 1125, 1128, 1812, +289, 1254, -777, -118, -1239, -1367, -757, -1661, +262, -703, 1067, 822, 1022, 1780, 294, 1393, +-539, -6, -987, -1357, -849, -1768, -221, -990, +636, 522, 1206, 1828, 994, 1971, -7, 678, +-1192, -1250, -1595, -2361, -749, -1736, 772, 299, +1821, 2199, 1463, 2406, -83, 676, -1585, -1574, +-1817, -2454, -663, -1329, 891, 677, 1678, 1945, +1195, 1692, -62, 319, -1095, -1187, -1266, -1848, +-625, -1189, 304, 309, 909, 1543, 950, 1613, +434, 547, -345, -861, -912, -1677, -893, -1410, +-276, -151, 587, 1309, 1078, 1904, 838, 1071, +-77, -668, -1023, -1993, -1226, -1821, -457, -203, +678, 1619, 1270, 2184, 941, 1048, -75, -903, +-1054, -2155, -1233, -1737, -495, 58, 584, 1825, +1181, 2123, 871, 709, 0, -1194, -761, -2019, +-952, -1213, -542, 421, 172, 1607, 766, 1535, +783, 356, 313, -1015, -267, -1507, -627, -798, +-601, 462, -277, 1247, 190, 1056, 581, 148, +652, -816, 289, -1209, -322, -716, -745, 404, +-610, 1323, 2, 1224, 591, 97, 635, -1203, +233, -1581, -209, -679, -433, 817, -444, 1640, +-281, 1098, 170, -304, 623, -1374, 600, -1322, +34, -265, -519, 964, -618, 1400, -279, 651, +146, -737, 434, -1529, 490, -946, 277, 518, +-183, 1494, -559, 1169, -529, -78, -88, -1238, +443, -1481, 675, -625, 368, 753, -261, 1634, +-715, 1254, -613, -163, -57, -1520, 553, -1643, +826, -414, 540, 1178, -180, 1798, -867, 977, +-957, -633, -281, -1747, 621, -1512, 1042, -103, +717, 1505, -101, 2075, -862, 1051, -1051, -982, +-414, -2377, 602, -1882, 1180, 256, 830, 2279, +-216, 2497, -1125, 658, -1227, -1782, -354, -2801, +897, -1499, 1548, 1101, 966, 2817, -398, 2187, +-1496, -252, -1454, -2473, -362, -2695, 988, -796, +1667, 1730, 1145, 2929, -268, 1893, -1516, -636, +-1598, -2771, -461, -2853, 1000, -710, 1698, 2095, +1121, 3311, -323, 1867, -1550, -1122, -1563, -3168, +-307, -2595, 1187, -20, 1688, 2379, 868, 2782, +-591, 1082, -1588, -1344, -1367, -2654, -65, -1895, +1323, 310, 1653, 2229, 657, 2350, -795, 652, +-1601, -1554, -1190, -2516, 50, -1534, 1248, 711, +1551, 2455, 721, 2270, -660, 186, -1565, -2092, +-1342, -2626, -96, -991, 1252, 1474, 1743, 2648, +865, 1603, -754, -758, -1779, -2242, -1364, -1716, +99, 79, 1323, 1439, 1501, 1518, 652, 623, +-541, -504, -1243, -1223, -1133, -1155, -287, -197, +654, 950, 1091, 1361, 809, 579, 116, -573, +-616, -1147, -957, -776, -713, 36, -9, 666, +636, 800, 884, 437, 603, -126, 1, -603, +-649, -707, -965, -399, -656, 232, 129, 707, +823, 640, 1012, 27, 596, -528, -177, -574, +-950, -232, -1237, 148, -686, 288, 558, 321, +1553, 293, 1375, 187, 19, -244, -1450, -777, +-1797, -883, -655, -140, 1078, 1025, 1992, 1616, +1258, 934, -510, -742, -1927, -2047, -1833, -1871, +-253, -88, 1618, 1993, 2242, 2740, 1033, 1213, +-1109, -1540, -2402, -3204, -1647, -2147, 590, 833, +2287, 3219, 2000, 2968, -55, 206, -2048, -2832, +-2248, -3710, -486, -1505, 1707, 2130, 2436, 4300, +1081, 2942, -1218, -987, -2530, -4371, -1689, -4253, +573, -575, 2420, 3837, 2242, 5206, 201, 2194, +-2029, -2789, -2697, -5545, -1092, -3652, 1470, 1220, +2927, 5155, 1982, 4846, -634, 683, -2822, -4157, +-2751, -5681, -382, -2664, 2296, 2629, 3183, 5800, +1461, 4205, -1485, -780, -3293, -5073, -2323, -5119, +569, -1166, 3066, 3698, 2998, 5390, 443, 2742, +-2603, -2170, -3567, -5105, -1557, -3776, 1867, 590, +3898, 4320, 2750, 4401, -738, 954, -3723, -3270, +-3727, -4624, -686, -2218, 2901, 2056, 4220, 4399, +2079, 3054, -1730, -852, -4081, -3741, -2993, -3259, +451, -93, 3404, 2842, 3465, 3131, 739, 856, +-2523, -1999, -3598, -2926, -1692, -1393, 1588, 1330, +3447, 2804, 2357, 1962, -629, -677, -2963, -2749, +-2735, -2441, -356, 87, 2242, 2492, 2939, 2688, +1177, 586, -1529, -1973, -2899, -2760, -1707, -1220, +879, 1423, 2621, 2682, 2014, 1616, -300, -998, +-2214, -2575, -2104, -1848, -204, 628, 1746, 2390, +2003, 1961, 602, -212, -1179, -2133, -1792, -2151, +-983, -395, 563, 1779, 1639, 2338, 1398, 939, +-53, -1429, -1546, -2410, -1681, -1364, -342, 947, +1307, 2311, 1791, 1694, 774, -415, -843, -2111, +-1718, -1949, -1230, -157, 215, 1786, 1530, 2070, +1563, 576, 364, -1445, -1101, -1873, -1566, -558, +-854, 1206, 508, 1451, 1320, 242, 1100, -1137, +121, -1135, -930, 70, -1216, 1240, -535, 1222, +657, 45, 1190, -1241, 711, -1538, -447, -455, +-1122, 1079, -772, 1805, 207, 852, 835, -891, +785, -1811, 309, -871, -321, 864, -759, 1643, +-854, 722, -308, -862, 501, -1578, 1164, -804, +866, 732, -101, 1632, -1035, 1135, -1173, -432, +-431, -1714, 661, -1553, 1347, 87, 939, 1711, +-185, 1750, -1349, 115, -1543, -1687, -415, -1959, +1240, -342, 2019, 1742, 1148, 2294, -709, 619, +-2151, -1791, -1938, -2677, -210, -1140, 1731, 1452, +2453, 2898, 1308, 1898, -910, -749, -2512, -2934, +-2099, -2649, 13, -54, 2140, 2699, 2435, 3076, +729, 740, -1563, -2256, -2418, -3138, -1160, -1193, +995, 1785, 2152, 3047, 1384, 1516, -436, -1391, +-1779, -2966, -1511, -1690, -36, 1164, 1397, 2860, +1541, 1854, 379, -776, -1063, -2670, -1453, -2170, +-537, 281, 820, 2636, 1340, 2658, 585, 172, +-759, -2690, -1424, -3112, -630, -558, 946, 2692, +1693, 3484, 710, 1039, -1115, -2439, -1953, -3743, +-954, -1736, 1007, 1867, 2074, 3863, 1329, 2429, +-618, -1218, -2097, -3779, -1711, -2905, 193, 560, +1995, 3408, 1979, 3134, 249, 116, -1734, -2963, +-2212, -3410, -836, -918, 1284, 2456, 2475, 3660, +1606, 1687, -760, -1896, -2560, -3756, -2178, -2325, +90, 1255, 2267, 3535, 2457, 2681, 516, -565, +-1717, -3137, -2328, -2903, -978, -57, 1112, 2820, +2059, 3085, 1150, 554, -657, -2481, -1644, -3126, +-1167, -1008, 293, 2016, 1400, 3056, 1187, 1479, +-178, -1389, -1311, -2863, -1213, -1863, 84, 814, +1380, 2708, 1434, 2212, 83, -284, -1386, -2490, +-1724, -2442, -619, -231, 1110, 2094, 2028, 2517, +1295, 832, -540, -1389, -1937, -2304, -1884, -1358, +-258, 516, 1562, 1789, 2156, 1621, 887, 227, +-1019, -1196, -2080, -1571, -1281, -618, 521, 626, +1815, 1148, 1488, 670, -1, -124, -1467, -625, +-1684, -672, -540, -377, 1032, 118, 1782, 606, +1036, 691, -466, 214, -1577, -460, -1320, -753, +-182, -436, 1039, 127, 1250, 573, 626, 525, +-353, 189, -853, -341, -722, -539, -169, -338, +339, 257, 499, 555, 370, 284, 72, -328, +-166, -590, -333, -193, -290, 446, -110, 744, +202, 325, 388, -417, 325, -903, -102, -596, +-476, 293, -465, 1092, -17, 989, 513, -135, +586, -1239, 121, -1212, -464, 99, -548, 1394, +-233, 1419, 198, -39, 382, -1595, 345, -1684, +142, -25, -94, 1868, -355, 2082, -485, 230, +-291, -2113, 155, -2589, 667, -551, 816, 2273, +290, 3025, -769, 884, -1341, -2263, -742, -3335, +656, -1321, 1580, 2003, 1199, 3498, -251, 1800, +-1532, -1653, -1631, -3699, -379, -2393, 1333, 1246, +2098, 3914, 967, 2890, -1182, -975, -2370, -4079, +-1401, -3238, 910, 638, 2454, 4031, 1818, 3540, +-541, -208, -2393, -3954, -2198, -3910, 20, -241, +2206, 3834, 2550, 4262, 499, 769, -1899, -3499, +-2737, -4414, -1073, -1266, 1489, 2916, 2881, 4256, +1532, 1684, -1146, -2184, -2862, -3777, -1878, -1708, +823, 1731, 2809, 3189, 2176, 1412, -537, -1488, +-2766, -2632, -2477, -1074, 207, 1401, 2724, 2326, +2771, 962, 190, -1185, -2504, -1975, -2994, -926, +-803, 782, 2025, 1440, 3216, 741, 1567, -347, +-1452, -687, -3345, -302, -2240, -2, 868, -78, +3305, -218, 2701, 172, -354, 621, -3073, 548, +-2897, -374, -57, -995, 2745, -587, 2847, 633, +229, 1083, -2429, 301, -2621, -916, -150, -1017, +2290, 81, 2341, 1173, -151, 826, -2507, -684, +-2180, -1573, 704, -583, 2963, 1446, 2081, 2031, +-1261, 250, -3441, -2326, -2012, -2481, 1672, 179, +3719, 3077, 2053, 2667, -1699, -633, -3880, -3400, +-2337, -2443, 1360, 979, 3775, 3150, 2854, 1841, +-482, -983, -3361, -2124, -3453, -980, -771, 464, +2582, 697, 3960, 448, 2133, 519, -1739, 519, +-4235, -422, -3105, -1428, 956, -1023, 4192, 869, +3674, 2021, -314, 970, -3878, -1266, -3756, -2144, +-281, -739, 3093, 1329, 3534, 1946, 967, 624, +-2059, -1070, -3099, -1540, -1614, -594, 1035, 681, +2794, 1206, 2065, 643, -668, -552, -2656, -1257, +-1959, -647, 716, 820, 2493, 1452, 1527, 364, +-1014, -1331, -2176, -1533, -859, 133, 1267, 1697, +1821, 1289, 266, -667, -1664, -1887, -1727, -1193, +328, 707, 2176, 1977, 1736, 1553, -678, -340, +-2538, -2181, -1779, -2218, 894, -157, 2640, 2319, +1518, 2631, -1012, 393, -2435, -2266, -1175, -2450, +1092, -243, 2151, 1917, 934, 1829, -938, 119, +-1877, -1227, -1117, -1241, 480, -352, 1750, 496, +1647, 1115, 145, 1055, -1645, 85, -2252, -1446, +-789, -1696, 1457, -18, 2610, 2008, 1417, 1715, +-1062, -605, -2653, -2152, -1926, -973, 544, 1274, +2562, 1837, 2245, 295, -321, -1365, -2626, -1545, +-2211, -476, 687, 1093, 2950, 2100, 1862, 1420, +-1505, -1361, -3315, -3523, -1389, -2128, 2194, 2350, +3445, 4745, 1203, 2058, -2293, -3165, -3471, -5054, +-1466, -1929, 1933, 2844, 3528, 4617, 1989, 2296, +-1538, -1788, -3647, -4250, -2313, -3003, 1329, 915, +3680, 4064, 2297, 3224, -1359, -789, -3607, -3939, +-2035, -3010, 1531, 976, 3508, 3800, 1784, 2704, +-1707, -1150, -3416, -3665, -1647, -2473, 1658, 1071, +3327, 3307, 1759, 2367, -1603, -619, -3313, -2861, +-1775, -2515, 1629, 101, 3376, 2873, 1683, 3018, +-1856, 54, -3369, -3351, -1554, -3250, 1872, 412, +3318, 3693, 1704, 2813, -1656, -795, -3350, -3194, +-1984, -1955, 1381, 821, 3435, 2348, 2201, 1392, +-1293, -605, -3488, -1725, -2159, -1156, 1349, 462, +3372, 1462, 1846, 1042, -1426, -279, -3040, -1067, +-1248, -824, 1556, -88, 2294, 323, 457, 466, +-1457, 469, -1367, 431, 161, -15, 1052, -716, +553, -1108, -306, -407, -440, 829, -60, 1443, +119, 498, -97, -957, -334, -1514, -44, -598, +630, 861, 886, 1496, 89, 816, -1244, -698, +-1492, -1656, 46, -1154, 1840, 543, 1826, 1705, +-424, 1213, -2255, -468, -1672, -1400, 773, -886, +2286, 257, 1372, 813, -1060, 591, -2058, -7, +-957, -395, 1130, -383, 1778, 66, 546, 307, +-1159, 154, -1426, -223, -239, -206, 1102, 125, +1166, 404, 81, 150, -1043, -224, -1012, -499, +20, -234, 967, 362, 846, 791, -52, 521, +-775, -554, -590, -1076, -49, -482, 348, 690, +345, 901, 402, 156, 198, -380, -354, -169, +-828, 60, -558, -272, 490, -486, 1170, 27, +704, 825, -676, 569, -1343, -429, -620, -1010, +743, -320, 1284, 755, 528, 878, -670, 39, +-989, -836, -415, -880, 334, -149, 558, 545, +505, 928, 144, 594, -413, -233, -710, -1210, +-315, -1198, 473, 113, 812, 1605, 197, 1480, +-655, -344, -613, -1903, 105, -1520, 518, 571, +253, 1973, -124, 1530, -335, -460, -54, -1904, +121, -1672, 163, 112, 11, 1864, -39, 1946, +-75, 161, -32, -1763, -159, -1967, -132, -234, +113, 1675, 575, 1911, 466, 267, -360, -1572, +-964, -1806, -572, -144, 505, 1551, 1073, 1712, +518, 130, -453, -1393, -965, -1483, -561, -280, +399, 1047, 969, 1356, 604, 692, -482, -576, +-1118, -1469, -416, -1195, 776, 309, 1019, 1656, +-8, 1474, -931, -304, -626, -1769, 315, -1481, +820, 328, 405, 1739, -420, 1269, -692, -411, +-286, -1623, 222, -1162, 518, 289, 343, 1337, +87, 1145, -192, 53, -432, -1097, -634, -1314, +-241, -578, 826, 832, 1230, 1476, 278, 849, +-1136, -687, -1486, -1459, -291, -826, 1186, 554, +1471, 1192, 470, 738, -918, -399, -1473, -1042, +-871, -748, 691, 342, 1675, 1216, 1055, 880, +-722, -484, -1655, -1461, -1031, -881, 662, 823, +1650, 1616, 968, 761, -682, -915, -1640, -1488, +-945, -635, 710, 738, 1640, 1326, 952, 824, +-675, -282, -1498, -1178, -1014, -1091, 281, -85, +1399, 1120, 1306, 1188, 3, 193, -1416, -879, +-1363, -936, 34, -125, 1235, 507, 946, 596, +-116, 142, -736, -234, -388, -469, -37, -254, +91, 140, 197, 489, 371, 254, 140, -217, +-203, -511, -422, -255, -198, 247, 137, 483, +218, 223, 239, -352, 118, -665, -63, -280, +-274, 496, -320, 835, -77, 343, 333, -559, +343, -910, 189, -544, -351, 249, -391, 917, +-154, 836, 377, 83, 340, -922, 17, -998, +-313, -138, -134, 811, -21, 809, 148, 103, +6, -475, 131, -452, 29, -188, -151, 149, +-177, 436, -3, 387, 221, -127, 141, -568, +-56, -272, -3, 510, -45, 511, -275, -266, +-297, -724, 205, 32, 729, 964, 377, 594, +-529, -760, -811, -1256, -123, -142, 574, 1275, +426, 1016, -106, -375, -165, -1176, 70, -358, +-148, 611, -351, 533, -111, -349, 624, -376, +678, 288, -176, 641, -1100, -141, -874, -902, +438, -431, 1478, 520, 1043, 767, -458, 24, +-1825, -459, -1216, -167, 614, 180, 1850, -76, +1116, -470, -716, -293, -1612, 491, -741, 843, +674, 303, 1169, -525, 461, -973, -478, -417, +-753, 314, -430, 771, 173, 389, 528, -141, +596, -261, 166, 14, -588, -113, -887, -528, +-240, -522, 926, 569, 1054, 1505, -135, 741, +-1344, -1289, -791, -2270, 697, -444, 1388, 2275, +279, 2553, -856, -258, -965, -2972, -87, -2186, +378, 1190, 483, 3049, 466, 1382, 388, -1741, +-351, -2539, -1092, -486, -927, 1829, 474, 1961, +1612, -31, 1072, -1809, -664, -1574, -1737, 429, +-983, 1925, 725, 1222, 1501, -974, 791, -1925, +-477, -590, -971, 1423, -716, 1585, -198, -188, +441, -1564, 1012, -1049, 878, 596, -126, 1463, +-1375, 714, -1317, -696, 65, -1511, 1354, -699, +1333, 787, 207, 1517, -941, 520, -1307, -902, +-666, -1287, 599, -198, 1431, 906, 827, 844, +-641, -189, -1498, -990, -587, -583, 1022, 475, +1308, 1208, 97, 678, -1143, -644, -1047, -1459, +90, -875, 1012, 535, 933, 1401, -38, 1037, +-839, -21, -823, -976, -111, -1150, 690, -597, +746, 489, 57, 1239, -471, 1149, -453, 2, +-148, -1244, 95, -1581, 159, -386, 287, 1315, +413, 2008, 242, 781, -482, -1336, -1010, -2304, +-590, -1090, 691, 1205, 1408, 2392, 744, 1406, +-841, -717, -1565, -2209, -529, -1780, 942, 45, +1265, 1891, 232, 2137, -826, 591, -877, -1554, +-33, -2358, 548, -1029, 498, 1240, 58, 2294, +-168, 1081, -248, -895, -178, -1835, -147, -967, +6, 277, 250, 973, 364, 888, 260, 571, +-107, -57, -578, -1001, -625, -1445, -190, -676, +774, 1026, 1147, 1944, 395, 1185, -969, -797, +-1483, -2125, -512, -1600, 989, 429, 1509, 2112, +671, 1810, -793, -112, -1455, -1848, -959, -1777, +512, -249, 1559, 1226, 1258, 1609, -319, 961, +-1602, -234, -1375, -1519, 80, -1978, 1252, -770, +1254, 1538, 337, 2875, -527, 1613, -907, -1252, +-800, -3173, -324, -2194, 443, 589, 1075, 2773, +1012, 2563, 17, 427, -1165, -1806, -1406, -2664, +-326, -1472, 1123, 775, 1556, 2591, 493, 2276, +-1068, 38, -1508, -2394, -606, -2660, 867, -532, +1386, 2056, 668, 2684, -478, 881, -981, -1474, +-822, -2513, -197, -1413, 503, 679, 1060, 2228, +969, 1948, -149, 80, -1415, -1840, -1432, -2098, +68, -602, 1624, 1204, 1445, 1630, -161, 629, +-1556, -441, -1308, -774, 190, -340, 1436, -151, +1221, -112, -104, -56, -1386, 405, -1283, 649, +41, 304, 1266, -498, 1359, -791, 10, -267, +-1138, 459, -1226, 679, -68, 124, 1017, -272, +960, -348, -64, -66, -757, -74, -572, -149, +64, 14, 269, 553, 232, 767, 356, 330, +472, -743, -148, -1375, -1173, -993, -1227, 390, +319, 1815, 2001, 1966, 1766, 433, -473, -1848, +-2617, -2933, -2144, -1459, 649, 1638, 3003, 3633, +2363, 2462, -848, -1212, -3266, -3953, -2316, -3216, +997, 511, 3185, 3854, 2156, 3797, -886, 373, +-2808, -3324, -2030, -4171, 530, -1267, 2412, 2583, +1931, 4009, -330, 1796, -2114, -1805, -1569, -3245, +538, -1662, 1710, 930, 861, 1921, -889, 997, +-1286, -174, -11, -425, 1171, -183, 1007, -320, +-377, -741, -1559, -706, -1223, 236, 462, 1235, +2035, 1560, 1821, 585, -444, -1129, -2534, -2349, +-2335, -1865, 407, 503, 2847, 2950, 2500, 3149, +-372, 405, -2742, -3162, -2434, -4115, 286, -1269, +2258, 2907, 2098, 4477, 95, 2027, -1509, -2126, +-1675, -4133, -737, -2592, 596, 897, 1437, 3313, +1339, 2906, 225, 483, -1313, -2133, -1776, -2833, +-627, -1597, 1124, 761, 1889, 2383, 873, 2418, +-929, 587, -1819, -1801, -964, -2979, 744, -1505, +1645, 1419, 915, 3147, -580, 1854, -1351, -1104, +-794, -2823, 331, -1802, 926, 647, 786, 2197, +64, 1679, -559, -141, -851, -1655, -561, -1637, +244, -149, 923, 1393, 968, 1599, 162, 220, +-919, -1379, -1299, -1668, -621, -373, 810, 1340, +1614, 1855, 991, 745, -608, -991, -1802, -2022, +-1388, -1455, 373, 207, 1752, 1984, 1748, 2310, +140, 690, -1612, -1801, -1945, -2826, -700, -1332, +1149, 1337, 1896, 2636, 1141, 1690, -404, -396, +-1446, -1918, -1460, -2061, -523, -807, 739, 1159, +1622, 2420, 1360, 1726, 37, -449, -1429, -2192, +-1888, -2046, -977, -431, 768, 1272, 2045, 2016, +2009, 1423, 239, -181, -1945, -1702, -2712, -1906, +-1151, -533, 1435, 1023, 2737, 1568, 1625, 944, +-480, 3, -2017, -719, -1919, -1102, -497, -875, +1016, -122, 1897, 704, 1217, 1192, -152, 1041, +-1330, 344, -1483, -985, -805, -2044, 344, -1628, +1419, 519, 1812, 2612, 752, 2605, -1258, 139, +-2373, -2401, -1555, -2959, 816, -1060, 2329, 1525, +1896, 2745, -99, 1864, -1810, -342, -1948, -2259, +-509, -2402, 1097, -729, 1801, 1666, 952, 2698, +-576, 1322, -1508, -1272, -1190, -2648, 231, -1415, +1374, 1044, 1112, 2146, -237, 1089, -1134, -686, +-692, -1365, 386, -706, 634, 151, 66, 556, +-318, 551, 108, 305, 401, 26, -43, -438, +-785, -626, -548, -463, 472, 283, 1194, 907, +606, 857, -741, -155, -1365, -1017, -621, -987, +668, -50, 1292, 686, 659, 806, -342, 516, +-781, 267, -715, -304, -311, -1171, 85, -1603, +591, -460, 1001, 1793, 737, 2978, -307, 1372, +-1281, -2006, -1448, -3896, -322, -2234, 1150, 1569, +1833, 3908, 934, 2804, -698, -435, -1611, -2906, +-1120, -2872, 34, -1014, 800, 1197, 731, 2337, +550, 1952, 354, 526, -54, -1081, -730, -1843, +-1191, -1781, -851, -803, 288, 788, 1503, 2437, +1805, 2540, 617, 505, -1344, -2413, -2449, -3383, +-1521, -1502, 766, 1557, 2377, 3035, 2029, 2029, +276, -176, -1483, -1739, -2166, -2035, -1516, -1264, +138, 18, 1936, 1489, 2528, 2281, 1155, 1530, +-1391, -593, -2876, -2424, -2031, -2296, 572, -356, +2513, 1605, 2211, 2016, 306, 1118, -1440, -168, +-1704, -1010, -926, -1445, 26, -1102, 617, 9, +1100, 1288, 1117, 1512, 615, 529, -589, -606, +-1493, -982, -1577, -611, -478, -249, 1040, 137, +1918, 451, 1535, 713, -16, 538, -1509, 5, +-2032, -569, -1110, -880, 359, -650, 1726, 15, +1997, 880, 1079, 1150, -793, 631, -2285, -545, +-2327, -1304, -438, -1068, 1980, 34, 2967, 1038, +1415, 1095, -1305, 257, -2773, -590, -1765, -692, +478, -145, 1914, 206, 1486, 4, 354, -254, +-802, 36, -1117, 469, -902, 509, -56, -53, +784, -438, 1017, -416, 498, -192, -306, -9, +-786, 66, -714, 385, -223, 625, 355, 482, +779, -338, 566, -1217, 36, -1140, -435, 123, +-567, 1543, -422, 1649, -109, 300, 327, -1376, +699, -1844, 578, -852, -47, 820, -700, 1795, +-891, 1281, -253, -212, 610, -1478, 1019, -1303, +542, -15, -522, 1011, -999, 862, -625, -154, +282, -565, 803, -195, 555, 474, 129, 381, +-464, -236, -601, -765, -384, -521, 261, 269, +535, 945, 389, 750, -185, -120, -360, -828, +-171, -783, 72, -71, 60, 392, 89, 439, +23, 192, 96, 111, 50, 120, -65, -108, +-238, -530, -286, -641, -9, -78, 465, 684, +537, 811, 72, 47, -574, -583, -616, -545, +-138, 119, 349, 417, 570, 109, 314, -302, +-99, -365, -473, 62, -458, 472, 77, 464, +454, 111, 259, -493, -247, -750, -394, -391, +-18, 429, 403, 980, 424, 663, 51, -190, +-343, -809, -590, -850, -489, -430, -1, 243, +721, 913, 1062, 1295, 637, 741, -445, -605, +-1530, -1866, -1504, -1887, -151, -272, 1581, 1760, +2214, 2674, 923, 1624, -1122, -690, -2299, -2712, +-1659, -2960, 168, -1023, 1725, 1943, 2127, 3656, +978, 2521, -808, -620, -2035, -3239, -1746, -3177, +-225, -825, 1342, 1830, 1937, 2821, 1141, 1801, +-415, -255, -1652, -1831, -1562, -1972, -235, -755, +1166, 769, 1378, 1382, 266, 808, -707, -159, +-750, -529, 56, -224, 544, 99, 279, -42, +-438, -394, -715, -484, -350, 13, 491, 629, +1061, 889, 892, 423, -7, -285, -1194, -915, +-1560, -1013, -832, -515, 750, 553, 1906, 1446, +1781, 1268, 160, -46, -1628, -1344, -2347, -1461, +-1271, -386, 751, 718, 2231, 965, 2094, 570, +449, 181, -1414, 19, -2290, -291, -1565, -881, +245, -1071, 1827, -322, 2013, 1020, 840, 1724, +-749, 1040, -1678, -494, -1439, -1553, -556, -1443, +656, -452, 1464, 563, 1581, 1202, 540, 1364, +-934, 795, -1875, -431, -1469, -1630, 88, -1717, +1470, -561, 1805, 850, 767, 1613, -722, 1459, +-1595, 626, -1347, -661, -94, -1804, 1228, -1921, +1581, -621, 702, 1246, -848, 2280, -1696, 1658, +-983, -75, 445, -1644, 1483, -2021, 1236, -1090, +110, 545, -929, 1639, -1466, 1521, -975, 340, +285, -760, 1471, -1055, 1667, -678, 453, -175, +-1136, 144, -1755, 447, -1037, 670, 303, 701, +1309, 219, 1222, -521, 530, -1163, -410, -1050, +-885, -83, -808, 1102, -557, 1674, -80, 977, +448, -523, 1062, -1810, 1228, -1738, 527, -350, +-851, 1358, -1841, 1987, -1658, 1219, -140, -347, +1580, -1615, 2263, -1743, 1371, -734, -439, 796, +-1946, 1712, -2108, 1404, -980, 206, 768, -1033, +1874, -1524, 1832, -1112, 674, 17, -659, 1184, +-1550, 1663, -1668, 873, -1030, -632, 261, -1659, +1778, -1303, 2389, 9, 1306, 1147, -1010, 1244, +-2748, 496, -2391, -496, -272, -974, 2010, -627, +2738, 59, 1453, 473, -749, 329, -2279, 119, +-2074, 91, -344, 66, 1334, -216, 1875, -372, +982, -249, -286, 109, -1171, 308, -1188, 196, +-495, 109, 506, -68, 1074, -150, 860, -167, +-63, -64, -895, 105, -969, 86, -269, -73, +702, -32, 1152, 167, 572, 337, -489, 44, +-1245, -500, -878, -648, 120, -55, 950, 729, +1040, 938, 467, 119, -278, -803, -832, -910, +-999, -237, -583, 561, 316, 674, 1127, 385, +1241, -15, 355, -421, -819, -573, -1445, -321, +-950, 191, 272, 539, 1172, 400, 1206, 93, +400, -163, -601, -438, -1123, -475, -893, -229, +-29, 312, 740, 692, 1000, 577, 492, 59, +-210, -572, -741, -949, -661, -563, -192, 297, +407, 1020, 514, 851, 223, -3, -192, -578, +-239, -653, -59, -456, 165, -248, 195, 203, +-60, 918, -329, 1013, -385, 64, -15, -1124, +456, -1303, 648, -157, 193, 1097, -372, 1196, +-657, 123, -457, -1010, 117, -979, 492, 51, +544, 824, 47, 640, -419, -67, -289, -311, +189, -154, 379, -185, -20, -368, -541, -257, +-451, 267, 0, 640, 408, 596, 647, 292, +460, -206, 137, -836, -488, -1099, -925, -551, +-806, 646, -153, 1382, 711, 1136, 1326, 221, +1021, -794, -38, -1307, -1267, -1230, -1682, -288, +-708, 985, 827, 1629, 1678, 1119, 1199, -142, +-220, -1212, -1180, -1309, -1159, -616, -296, 359, +503, 785, 563, 451, 405, 175, 290, 360, +218, 566, -162, -60, -667, -1243, -799, -1589, +-306, -604, 368, 836, 793, 1704, 796, 1511, +334, 549, -292, -816, -879, -1855, -869, -1761, +-298, -478, 380, 1062, 731, 1870, 672, 1468, +427, 293, 28, -947, -596, -1593, -1144, -1175, +-865, -99, 181, 821, 1237, 950, 1229, 522, +397, 107, -534, 45, -907, -102, -785, -442, +-515, -841, -32, -726, 770, 41, 1301, 942, +950, 1202, -308, 525, -1300, -526, -1294, -972, +-364, -614, 628, 112, 909, 528, 716, 333, +359, -135, -107, -402, -639, -130, -1002, 426, +-683, 558, 249, 195, 973, -354, 987, -614, +381, -485, -272, -76, -740, 462, -1034, 700, +-723, 228, 211, -382, 1210, -485, 1483, 75, +575, 470, -976, 64, -1675, -458, -1185, -432, +338, 0, 1474, 300, 1391, 198, 259, 286, +-1025, 424, -1318, 154, -592, -502, 460, -949, +1076, -642, 810, 179, 119, 795, -586, 939, +-926, 569, -819, -191, -143, -720, 749, -817, +1444, -344, 993, 76, -318, 130, -1449, 124, +-1427, 361, -386, 840, 683, 954, 1157, 196, +990, -1141, 436, -1981, -391, -1444, -952, 319, +-1126, 1901, -630, 2151, 200, 1013, 1054, -544, +1411, -1462, 848, -1482, -442, -972, -1537, -258, +-1544, 510, -297, 1298, 1078, 1632, 1447, 1090, +781, -171, -280, -1464, -878, -1894, -722, -1318, +-363, -109, 137, 1129, 407, 1885, 492, 1782, +334, 586, -91, -1189, -315, -2320, -189, -1809, +-58, -69, -27, 1538, -176, 1758, -22, 808, +323, -336, 287, -896, 90, -696, -201, -272, +-190, 151, -51, 280, -93, 110, -43, -90, +42, -90, 184, 209, 207, 404, -24, 115, +-256, -288, -139, -375, 70, -46, 310, 186, +97, 15, -235, -284, -347, -232, -86, 128, +354, 585, 355, 580, -6, 111, -321, -499, +-300, -804, 11, -473, 373, 112, 262, 578, +-59, 632, -396, 245, -311, -194, 82, -458, +401, -314, 306, 120, 2, 286, -292, 79, +-342, -309, -276, -345, 138, 89, 508, 458, +608, 422, 201, 108, -549, -270, -968, -388, +-703, -380, 213, -171, 998, 204, 1177, 425, +526, 378, -506, 59, -1240, -300, -1097, -290, +-326, -37, 603, 228, 1085, 179, 858, -263, +316, -471, -361, -232, -765, 380, -714, 780, +-500, 581, -17, -82, 399, -743, 748, -1000, +869, -558, 407, 344, -365, 1074, -997, 1074, +-1070, 183, -357, -768, 490, -1011, 991, -424, +893, 226, 189, 351, -450, 158, -741, 187, +-513, 451, -65, 435, 167, -112, 276, -782, +381, -905, 206, -353, -31, 394, -249, 805, +-270, 728, -14, 297, 91, -227, 140, -544, +124, -493, -37, -148, -236, 40, -364, -79, +-154, -205, 336, 55, 621, 698, 512, 1047, +-11, 566, -598, -496, -721, -1330, -384, -1283, +127, -489, 435, 427, 300, 1110, 276, 1338, +324, 904, 233, -97, -186, -1132, -650, -1339, +-731, -650, -383, 106, 138, 389, 666, 366, +1031, 563, 659, 855, -239, 585, -1194, -261, +-1045, -1050, 4, -1100, 931, -473, 800, 171, +-104, 451, -635, 585, -291, 715, 271, 748, +356, 249, 7, -711, -206, -1420, 28, -1176, +142, -63, -117, 1058, -445, 1285, -323, 656, +180, -171, 599, -597, 642, -431, 257, -170, +-282, -189, -803, -449, -899, -345, -339, 450, +589, 1230, 1110, 994, 822, -149, -5, -1177, +-713, -1133, -881, -299, -455, 458, 101, 762, +452, 588, 454, 134, 223, -326, -41, -514, +-65, -203, 9, 220, 21, 204, -205, -93, +-503, -336, -483, -89, 113, 327, 769, 468, +942, 277, 300, -119, -515, -516, -987, -618, +-698, -426, 3, 253, 645, 923, 766, 993, +305, 166, -293, -975, -458, -1319, -132, -407, +220, 779, 69, 1096, -327, 389, -406, -451, +51, -547, 613, -271, 698, 81, 129, 227, +-527, 239, -670, 54, -318, -265, 108, -321, +222, 42, 126, 486, 217, 416, 410, -93, +393, -585, -110, -570, -649, -135, -827, 459, +-435, 825, 209, 653, 792, -163, 862, -1010, +518, -1085, -130, -175, -738, 959, -922, 1192, +-662, 338, -130, -736, 659, -1046, 1155, -300, +1062, 671, 95, 919, -1041, 313, -1469, -640, +-718, -1009, 513, -560, 1207, 335, 816, 1050, +-76, 926, -711, 108, -608, -760, 13, -983, +464, -322, 514, 479, 60, 692, -504, 185, +-694, -523, -373, -592, 271, 16, 802, 627, +750, 627, 231, 51, -343, -334, -650, -141, +-587, 25, -350, -273, -12, -881, 340, -768, +634, 350, 605, 1495, 274, 1605, -258, 470, +-603, -957, -655, -1566, -288, -1165, 257, -152, +551, 606, 425, 725, 18, 498, -322, 365, +-306, 338, -78, 62, 172, -503, 292, -752, +220, -360, -80, 178, -357, 297, -459, -79, +-194, -249, 202, 54, 439, 525, 430, 631, +200, 256, -71, -284, -279, -554, -401, -445, +-358, -187, -98, -49, 185, -82, 414, 10, +301, 367, 40, 644, -150, 550, -149, 92, +-69, -365, -28, -533, -35, -503, 67, -424, +77, -241, -37, 86, -144, 591, -134, 879, +58, 652, 246, -5, 174, -640, 80, -753, +-60, -381, -162, -8, -212, 172, -210, 189, +-45, 137, 201, 156, 402, 162, 301, 258, +-105, 172, -467, -185, -421, -520, -17, -488, +403, -148, 369, 192, 89, 313, -73, 430, +-94, 501, -178, 166, -316, -457, -328, -895, +54, -602, 540, 172, 663, 755, 276, 748, +-373, 284, -731, -352, -579, -654, -28, -453, +521, 117, 658, 493, 345, 245, -190, -271, +-600, -456, -534, -79, -61, 498, 468, 654, +684, 184, 366, -465, -262, -765, -734, -427, +-676, 206, -107, 575, 607, 588, 818, 212, +347, -355, -377, -788, -691, -648, -327, 258, +281, 1100, 446, 915, 118, -166, -307, -1079, +-276, -937, 173, -26, 472, 637, 177, 697, +-490, 234, -770, -300, -240, -426, 636, -157, +1030, 261, 457, 257, -454, -185, -898, -319, +-566, 67, 94, 475, 492, 284, 364, -407, +26, -715, -132, -319, -97, 358, 137, 838, +164, 693, -46, 63, -327, -666, -374, -1071, +-69, -649, 342, 293, 472, 1041, 244, 1079, +-66, 248, -251, -678, -313, -1109, -334, -806, +-214, -39, 120, 695, 545, 1078, 585, 941, +170, 101, -323, -956, -455, -1391, -281, -766, +-58, 487, -102, 1122, -90, 823, 130, 36, +493, -517, 582, -582, 306, -300, -282, 122, +-670, 417, -738, 412, -330, 133, 239, -124, +631, -421, 625, -631, 256, -580, -125, 143, +-274, 1084, -315, 1382, -286, 498, -199, -881, +-17, -1575, 265, -1155, 365, 15, 183, 942, +-23, 1159, -74, 759, 10, 127, -1, -402, +-262, -780, -431, -924, -253, -526, 264, 245, +673, 849, 586, 890, 49, 315, -517, -259, +-728, -536, -374, -451, 201, -17, 579, 216, +441, 53, -61, -377, -344, -458, -177, 300, +155, 1058, 231, 954, -99, -46, -396, -1129, +-297, -1283, 80, -532, 480, 410, 519, 1063, +162, 876, -303, 205, -577, -412, -405, -617, +107, -222, 430, 187, 365, 167, -22, -174, +-345, -610, -270, -359, -31, 439, 293, 985, +437, 787, 234, -92, -157, -664, -562, -547, +-558, -282, 17, -163, 533, -160, 510, -52, +-53, 335, -529, 577, -250, 741, 353, 558, +560, -213, 122, -1089, -499, -1365, -568, -562, +-182, 699, 269, 1309, 490, 969, 376, 174, +88, -628, -321, -955, -633, -798, -366, -29, +274, 847, 646, 1019, 419, 271, -302, -781, +-573, -1118, -148, -356, 395, 773, 452, 1172, +32, 539, -410, -511, -421, -1004, -132, -665, +138, 21, 316, 516, 291, 560, 109, 241, +-164, -116, -241, -277, -56, -146, 154, 77, +189, 111, -119, 42, -379, 4, -334, -93, +29, -221, 456, -256, 706, -67, 403, 306, +-220, 346, -834, 192, -918, 29, -277, -23, +607, -50, 981, -199, 672, -336, -135, -306, +-682, -243, -619, 22, -156, 534, 303, 924, +401, 785, 145, -168, -103, -1196, -252, -1420, +-172, -644, 20, 708, 184, 1571, 263, 1222, +131, 28, -182, -1091, -323, -1163, -197, -382, +225, 353, 446, 618, 199, 456, -273, 60, +-511, -288, -334, -499, 92, -174, 364, 428, +368, 606, 285, 233, 18, -393, -194, -626, +-361, -342, -274, 89, -31, 337, 118, 290, +91, 10, 62, -33, 78, 164, 164, 230, +113, -35, -32, -470, -113, -458, -225, -72, +-251, 182, -123, 258, 154, 337, 476, 362, +375, 119, -107, -469, -495, -653, -379, -203, +52, 342, 398, 467, 201, 142, -87, -260, +-195, -288, -58, -87, 120, 309, 70, 502, +-9, 101, -33, -440, -73, -666, -60, -231, +-25, 452, 70, 650, 190, 298, 62, -274, +-148, -721, -198, -479, -97, 149, 170, 716, +291, 725, 154, 78, -84, -459, -326, -612, +-308, -412, -20, -14, 232, 274, 268, 403, +78, 287, -100, -72, 10, -199, 54, -129, +28, -20, -133, 107, -233, 63, -66, 71, +130, 7, 149, -151, 101, -179, -122, -145, +-128, -7, 45, 207, 119, 254, 100, 123, +-33, -150, -86, -227, 70, 81, 48, 298, +-160, 107, -255, -223, -133, -326, 245, -70, +363, 29, 85, -133, -228, -109, -271, 233, +43, 615, 289, 518, 181, -48, -118, -607, +-337, -751, -186, -451, 128, 152, 251, 634, +174, 686, -32, 274, -193, -298, -140, -584, +-75, -396, 93, 25, 208, 397, 135, 353, +-34, -56, -217, -394, -181, -286, 70, 246, +285, 632, 193, 328, -95, -378, -419, -760, +-331, -438, 54, 333, 425, 655, 448, 361, +94, -190, -285, -433, -391, -238, -236, 27, +74, 178, 335, 339, 358, 390, 71, 125, +-361, -455, -530, -898, -130, -518, 428, 324, +610, 915, 185, 727, -416, 24, -578, -454, +-257, -468, 203, -213, 439, 50, 350, 63, +60, -13, -224, 25, -362, 176, -128, 335, +163, 120, 274, -333, 55, -484, -290, -171, +-312, 347, -22, 424, 276, 16, 372, -259, +169, -108, -51, 242, -161, 220, -227, -261, +-143, -589, -23, -258, 84, 410, 62, 778, +-124, 343, -153, -347, 103, -635, 391, -353, +469, 122, 55, 316, -439, 249, -620, 193, +-383, 115, 156, -69, 535, -385, 455, -542, +80, -290, -354, 261, -404, 710, -76, 731, +254, 209, 395, -459, 160, -807, -242, -612, +-426, -8, -393, 451, 35, 502, 419, 259, +446, -15, 216, -130, -160, -121, -270, -90, +-119, 2, -82, -1, -99, -116, -145, -215, +-29, -111, 320, 227, 421, 392, 232, 155, +-183, -146, -595, -217, -513, 2, 1, 147, +630, 14, 831, -134, 246, -211, -618, -170, +-1003, -8, -543, 171, 429, 337, 942, 310, +653, 44, -123, -202, -752, -386, -611, -365, +20, -90, 597, 298, 633, 572, 7, 347, +-595, -231, -659, -583, -214, -484, 406, -44, +601, 349, 388, 509, 61, 483, -234, 150, +-363, -364, -377, -668, -241, -531, 131, -4, +397, 424, 369, 469, 12, 323, -326, 102, +-277, -91, 59, -312, 352, -525, 291, -446, +-39, 14, -345, 632, -377, 937, -191, 495, +92, -406, 240, -1042, 313, -888, 276, -52, +100, 705, -200, 778, -469, 273, -386, -277, +61, -343, 495, 46, 521, 305, 42, 85, +-483, -439, -630, -673, -248, -220, 345, 466, +661, 728, 490, 401, -59, -189, -544, -421, +-578, -240, -216, 54, 296, 182, 530, -15, +338, -258, -44, -179, -346, 133, -368, 428, +-149, 279, 68, -223, 260, -474, 333, -269, +198, 263, -74, 596, -399, 291, -402, -279, +-81, -661, 301, -454, 468, 225, 253, 626, +-121, 475, -372, -84, -411, -507, -142, -394, +248, 23, 472, 349, 389, 359, -95, -27, +-512, -329, -497, -270, -69, 50, 469, 328, +543, 185, 171, -79, -277, -165, -481, -163, +-279, -137, 129, -55, 376, 203, 326, 476, +-109, 278, -471, -255, -342, -510, 148, -270, +598, 141, 426, 187, -188, -38, -496, -34, +-264, 248, 164, 430, 247, 138, -148, -508, +-307, -818, 20, -353, 434, 551, 463, 1090, +-21, 631, -448, -431, -444, -1107, -186, -897, +129, 32, 355, 895, 433, 1070, 267, 471, +-221, -495, -640, -1052, -542, -690, -2, 142, +569, 704, 687, 563, 328, 48, -168, -231, +-613, -242, -739, -160, -379, -79, 339, -25, +968, 101, 859, 240, -1, 199, -825, 17, +-975, -295, -346, -414, 469, -103, 792, 324, +563, 545, -17, 311, -590, -181, -733, -503, +-383, -563, 305, -282, 837, 255, 712, 636, +100, 631, -585, 205, -837, -286, -496, -500, +88, -526, 553, -400, 653, 45, 306, 505, +-113, 744, -417, 387, -414, -238, -146, -512, +61, -435, 142, -158, 139, 89, 139, 238, +224, 390, 140, 354, -111, 17, -368, -397, +-433, -715, -156, -500, 260, 234, 457, 897, +377, 955, 6, 217, -296, -685, -311, -997, +-143, -711, 67, -46, 137, 621, 53, 925, +23, 689, 24, -80, 35, -743, 35, -713, +-28, -212, -80, 243, -86, 341, -66, 206, +-6, 124, 86, 9, 165, -107, 177, -102, +28, -92, -237, -142, -359, -153, -151, 39, +263, 410, 523, 483, 254, 59, -319, -478, +-670, -679, -362, -337, 359, 301, 800, 714, +455, 598, -324, -19, -803, -653, -477, -623, +273, -49, 611, 509, 297, 508, -237, -21, +-318, -457, 42, -413, 255, -10, 21, 449, +-348, 509, -351, 131, 110, -318, 504, -546, +460, -303, 14, 139, -482, 315, -578, 232, +-234, -3, 327, -37, 685, 142, 433, 127, +-218, -116, -669, -416, -505, -432, 154, -11, +564, 347, 368, 425, -105, 305, -373, 68, +-184, -127, 129, -396, 202, -545, 67, -192, +-120, 347, -198, 666, -103, 412, 88, -239, +288, -580, 281, -423, -55, 1, -427, 404, +-485, 373, -15, 150, 557, -61, 644, -230, +167, -218, -482, -169, -717, 13, -384, 282, +180, 242, 544, -66, 501, -351, 111, -276, +-258, 207, -359, 509, -144, 305, 160, -82, +184, -425, -73, -381, -321, -167, -205, 57, +218, 275, 506, 292, 320, 148, -175, 5, +-483, -125, -305, -143, 152, -164, 408, -169, +179, 21, -245, 208, -420, 271, -163, 162, +315, -101, 492, -265, 225, -328, -211, -241, +-456, 77, -267, 429, 97, 571, 280, 341, +230, -208, 7, -625, -160, -654, -160, -337, +-129, 198, 19, 592, 191, 733, 259, 494, +202, -119, -104, -697, -381, -858, -401, -450, +-182, 199, 231, 645, 487, 657, 443, 425, +170, -28, -272, -434, -533, -629, -426, -491, +-86, -82, 381, 279, 483, 462, 225, 521, +-112, 349, -362, -34, -271, -505, -35, -724, +86, -423, 179, 151, 114, 574, 101, 646, +151, 313, 56, -151, -132, -493, -411, -582, +-519, -299, -126, 87, 437, 383, 753, 555, +498, 435, -207, 94, -628, -393, -517, -748, +-69, -528, 353, 60, 308, 557, 78, 585, +-140, 178, -184, -139, 23, -239, 167, -233, +117, -182, -63, -71, -278, 131, -192, 314, +124, 210, 345, 26, 328, -190, -46, -385, +-407, -388, -412, -119, -113, 495, 308, 887, +427, 514, 148, -376, -142, -1005, -232, -763, +-45, 60, 149, 649, 29, 626, -222, 185, +-299, -258, -87, -345, 306, -194, 505, 82, +331, 299, -16, 292, -398, 54, -579, -399, +-399, -688, 21, -402, 503, 363, 662, 979, +286, 801, -257, -61, -589, -834, -405, -923, +114, -330, 441, 424, 341, 793, -40, 579, +-431, -80, -327, -629, 67, -627, 413, -112, +429, 453, -15, 584, -410, 226, -449, -291, +-182, -537, 268, -275, 457, 225, 310, 431, +20, 139, -286, -269, -298, -188, -133, 220, +-22, 309, 65, -127, 65, -614, 122, -446, +214, 239, 92, 770, -60, 677, -183, 47, +-201, -605, -52, -755, 5, -351, 85, 279, +190, 574, 144, 299, 22, -134, -231, -344, +-343, -154, -62, 214, 306, 427, 471, 314, +211, -190, -359, -706, -604, -702, -354, -64, +238, 705, 678, 930, 472, 398, -98, -382, +-551, -836, -521, -669, -12, 11, 357, 683, +363, 846, 114, 328, -167, -484, -194, -908, +-108, -658, -52, 41, 67, 690, 152, 865, +190, 489, 116, -149, -183, -675, -378, -744, +-279, -390, 94, 140, 517, 545, 493, 587, +3, 291, -507, -110, -613, -344, -150, -385, +431, -250, 580, -61, 275, 227, -217, 425, +-489, 293, -356, -85, -35, -386, 289, -305, +397, 56, 192, 275, -108, 220, -314, -19, +-236, -249, 58, -235, 246, -33, 180, 225, +-50, 315, -237, 95, -166, -126, 15, -178, +153, -146, 192, -127, 108, -156, -32, 14, +-147, 401, -187, 553, -49, 273, 84, -350, +84, -843, -2, -685, -28, -48, 143, 730, +279, 1059, 78, 613, -380, -278, -678, -1051, +-338, -1091, 493, -272, 1015, 716, 658, 1089, +-343, 617, -1101, -258, -847, -659, 76, -481, +827, -121, 800, 102, 177, 91, -392, 196, +-553, 332, -360, 236, -13, -64, 265, -392, +388, -401, 269, -76, -59, 223, -304, 306, +-272, 158, -55, -72, 164, -137, 170, -112, +67, -44, 13, 70, -68, 119, -121, 118, +-122, -4, -32, -186, 132, -199, 143, -90, +7, 67, -79, 199, -50, 219, 70, 194, +105, 24, -2, -241, -66, -314, -118, -133, +-154, 63, -107, 52, 4, -126, 254, -34, +418, 368, 218, 594, -163, 317, -514, -330, +-468, -816, -17, -737, 390, -237, 488, 463, +269, 939, -135, 811, -339, 133, -378, -660, +-243, -943, 66, -492, 340, 177, 462, 558, +286, 493, -131, 130, -418, -128, -431, -221, +-159, -205, 192, -70, 309, 26, 262, 128, +70, 129, -93, -48, -95, -166, -101, -103, +-119, 98, -122, 264, -112, 121, 106, -99, +318, -159, 283, -128, 35, -11, -303, 13, +-339, -7, -60, 40, 169, 30, 226, 96, +45, 177, -103, 84, -89, -127, -68, -350, +8, -288, 102, 141, 135, 411, 96, 328, +-112, -69, -278, -449, -145, -346, 89, 51, +275, 407, 212, 444, -31, 47, -169, -304, +-186, -396, -90, -290, 43, 38, 57, 329, +97, 466, 122, 306, 28, -251, -83, -630, +-173, -480, -68, 113, 197, 706, 234, 661, +-1, 24, -294, -607, -333, -799, -9, -249, +276, 479, 266, 711, 93, 348, -83, -286, +-96, -515, -113, -175, -188, 215, -80, 360, +192, 75, 337, -352, 152, -428, -328, -121, +-499, 393, -90, 658, 447, 292, 582, -297, +122, -685, -456, -558, -578, 60, -221, 610, +304, 741, 503, 327, 252, -454, -129, -870, +-371, -620, -228, 77, 104, 757, 212, 821, +89, 341, -68, -294, -143, -742, -12, -613, +76, -119, 91, 340, 68, 548, -47, 343, +-163, -7, -178, -237, -46, -346, 223, -176, +294, 61, 141, 180, -138, 256, -331, 150, +-192, -46, 75, -262, 201, -430, 145, -172, +-58, 270, -162, 491, -63, 377, 77, -33, +216, -308, 183, -323, -58, -326, -291, -153, +-350, 113, -66, 373, 336, 533, 429, 289, +163, -145, -248, -495, -467, -630, -245, -263, +137, 266, 392, 574, 349, 522, 11, 45, +-268, -354, -302, -417, -143, -269, 68, 98, +129, 304, 128, 255, 139, 94, 85, -160, +-38, -250, -222, -182, -308, -92, -63, 177, +268, 372, 401, 301, 193, 19, -264, -390, +-470, -439, -215, -142, 162, 114, 403, 258, +260, 188, -44, 117, -214, 155, -234, 5, +-91, -233, 71, -393, 146, -310, 129, 148, +-14, 458, -96, 347, -32, 21, 10, -313, +51, -304, 18, -108, -19, 31, 34, 264, +21, 355, -109, 177, -184, -216, -124, -620, +179, -470, 444, 155, 328, 658, -130, 714, +-586, 146, -566, -543, -39, -756, 492, -469, +628, 191, 276, 654, -232, 538, -406, 125, +-273, -318, -19, -439, 92, -201, 6, -9, +-25, 120, 88, 152, 207, 101, 210, 172, +30, 119, -169, -64, -217, -232, -187, -356, +-69, -189, 65, 128, 116, 347, 145, 465, +129, 248, 75, -167, 24, -508, -149, -621, +-280, -266, -193, 304, 24, 652, 268, 692, +248, 257, 74, -354, -74, -732, -147, -725, +-163, -192, -121, 425, -14, 643, 268, 497, +361, 89, 93, -239, -354, -330, -612, -344, +-265, -168, 453, 72, 777, 206, 456, 236, +-309, 48, -804, -140, -546, -94, 98, 57, +597, 236, 510, 150, -11, -222, -367, -407, +-287, -267, 61, 157, 265, 460, 26, 278, +-260, -65, -228, -254, 91, -186, 413, 71, +320, 119, -80, -25, -362, -144, -375, -159, +-98, 45, 229, 214, 339, 176, 260, 117, +9, -3, -267, -108, -330, -227, -215, -342, +68, -168, 315, 191, 283, 438, 105, 438, +-70, 72, -133, -321, -100, -442, -186, -289, +-246, 108, -88, 355, 237, 259, 512, 43, +345, -178, -172, -233, -542, -161, -454, -41, +63, 240, 545, 420, 456, 223, 4, -186, +-453, -527, -545, -401, -145, 43, 290, 338, +518, 385, 428, 204, 15, -43, -386, -171, +-587, -275, -451, -259, 56, -93, 525, 144, +745, 422, 449, 403, -200, 7, -700, -405, +-731, -555, -291, -259, 342, 187, 596, 414, +485, 447, 177, 255, -168, -100, -316, -402, +-381, -514, -314, -281, -33, 136, 284, 399, +485, 443, 367, 187, -31, -189, -344, -341, +-445, -252, -257, 5, 74, 151, 295, 118, +389, 133, 243, 119, -97, -71, -348, -291, +-374, -337, -128, -25, 180, 368, 288, 430, +267, 214, 162, -141, -18, -422, -262, -397, +-477, -126, -387, 268, 123, 411, 598, 178, +627, -95, 124, -184, -523, -94, -667, 42, +-288, 20, 258, -30, 538, -52, 390, -25, +9, 93, -278, 119, -352, -13, -179, -111, +5, -69, 130, 124, 145, 163, 137, -82, +139, -268, 55, -184, -178, 117, -293, 353, +-175, 238, 123, -88, 354, -349, 223, -294, +-102, 111, -272, 388, -176, 230, 23, -188, +98, -459, -12, -262, -49, 179, 118, 480, +334, 489, 257, 109, -159, -440, -589, -681, +-580, -394, -40, 264, 577, 633, 702, 382, +270, -92, -281, -343, -488, -227, -306, 41, +7, 152, 112, 121, 85, 0, 87, -141, +119, -154, 124, -80, 18, 56, -129, 202, +-176, 225, -150, 86, -14, -175, 163, -302, +253, -85, 160, 214, -164, 230, -411, -46, +-268, -299, 133, -181, 452, 137, 396, 301, +-35, 226, -363, -16, -404, -230, -173, -244, +172, -83, 340, 142, 303, 199, 62, 17, +-254, -159, -341, -144, -201, 58, 82, 264, +285, 230, 168, -37, 24, -326, -28, -354, +-35, -24, -63, 316, -218, 318, -248, 33, +67, -223, 376, -188, 421, 3, 64, 129, +-399, 145, -487, 47, -203, -127, 235, -227, +459, -137, 261, 96, -59, 243, -270, 176, +-262, 54, 4, -13, 142, -84, 111, -200, +31, -300, -94, -194, -69, 132, 12, 456, +22, 530, 76, 205, 49, -349, -14, -685, +-58, -497, -96, 75, 27, 537, 154, 497, +81, 129, -117, -200, -282, -288, -109, -174, +317, -18, 401, 101, 103, 130, -342, 42, +-495, -63, -90, -81, 330, -18, 404, 81, +136, 79, -285, -6, -364, -50, -93, 1, +213, 92, 396, 26, 173, -222, -179, -309, +-345, -26, -274, 410, 37, 512, 273, 83, +222, -451, 92, -545, -85, -178, -125, 303, +-35, 491, -39, 300, -8, -71, 20, -399, +-12, -446, 28, -179, -2, 199, 15, 467, +97, 432, 16, 109, -42, -273, -94, -484, +-88, -363, 66, -4, 82, 257, -9, 270, +-48, 118, -83, 1, 57, 60, 142, 124, +44, 22, -65, -239, -164, -481, -103, -358, +93, 119, 122, 564, 53, 596, -101, 135, +-204, -360, -29, -454, 151, -224, 245, 55, +192, 170, -110, 145, -281, 103, -281, -38, +-169, -189, 96, -140, 218, 98, 258, 330, +235, 236, 17, -158, -182, -390, -313, -268, +-321, 70, -78, 257, 123, 97, 297, -71, +361, 16, 142, 230, -146, 246, -403, -138, +-426, -531, -27, -470, 371, -4, 514, 521, +257, 645, -342, 269, -637, -277, -443, -650, +118, -532, 709, 15, 712, 506, 178, 595, +-494, 208, -882, -291, -552, -452, 164, -270, +706, 33, 758, 187, 217, 92, -379, 33, +-587, 131, -411, 254, 57, 161, 356, -224, +318, -540, 125, -438, -138, -42, -192, 389, +-37, 587, 64, 486, 127, 138, 51, -425, +-99, -812, -97, -613, -64, 88, 44, 770, +157, 801, 105, 177, 52, -493, 1, -698, +-65, -339, -73, 194, -123, 418, -68, 337, +125, 137, 234, -53, 221, -206, -5, -369, +-268, -340, -263, -10, -87, 348, 170, 452, +355, 222, 235, -76, 5, -182, -263, -194, +-398, -218, -178, -215, 170, -116, 452, 190, +426, 481, 9, 462, -392, 99, -489, -429, +-231, -633, 245, -288, 449, 242, 309, 518, +-27, 297, -315, -170, -268, -374, -4, -201, +175, 192, 178, 404, -24, 162, -138, -233, +-48, -399, 9, -210, 12, 108, -66, 221, +-60, 222, 128, 244, 204, 102, 67, -225, +-157, -520, -323, -379, -184, 188, 69, 573, +195, 441, 194, -14, 47, -392, -68, -399, +-108, -172, -152, 90, -111, 293, -28, 289, +57, 156, 111, -12, 30, -207, -69, -322, +-50, -323, 5, -112, 81, 283, 11, 531, +-164, 434, -173, 22, -35, -445, 168, -574, +192, -341, -63, 65, -268, 398, -175, 441, +119, 291, 327, 15, 136, -315, -215, -438, +-329, -255, -143, 115, 154, 339, 193, 177, +-7, -96, -114, -144, -39, 32, 125, 218, +154, 163, -78, -80, -265, -305, -238, -368, +-13, -111, 248, 307, 270, 490, 116, 280, +-49, -153, -144, -381, -124, -237, -115, 1, +-140, 134, -46, 111, 151, 2, 349, -23, +342, 22, 26, 87, -310, 77, -410, -110, +-190, -230, 156, -97, 320, 158, 265, 302, +91, 128, -95, -183, -180, -310, -164, -194, +-38, 96, 164, 309, 243, 233, 145, 2, +-57, -208, -199, -215, -106, -43, 92, 69, +185, 105, 114, 74, -46, -22, -73, -66, +39, -58, 100, 25, 11, 108, -148, 43, +-139, -36, 122, -76, 370, -87, 312, -38, +-52, 41, -419, 142, -405, 151, -82, -56, +292, -238, 454, -162, 329, 112, 45, 343, +-268, 199, -432, -185, -316, -407, 41, -295, +378, 127, 452, 435, 188, 335, -141, 9, +-322, -258, -289, -253, -130, -105, 49, -37, +229, 48, 304, 175, 181, 188, -83, 44, +-286, -145, -279, -106, -86, 97, 71, 87, +145, -117, 175, -263, 152, -121, 5, 201, +-251, 310, -377, 175, -167, -26, 228, -185, +407, -214, 171, -180, -266, -63, -427, 154, +-196, 277, 162, 216, 295, 3, 115, -212, +-117, -202, -205, -52, -132, 41, -25, 55, +14, 17, -4, 46, -27, 74, -33, -3, +10, -49, 81, 0, 95, 70, 22, 53, +-174, -98, -313, -210, -232, -166, 15, -21, +269, 204, 304, 366, 108, 317, -96, 36, +-211, -347, -236, -524, -211, -367, -145, -12, +82, 387, 363, 591, 428, 443, 147, -11, +-322, -525, -532, -651, -309, -268, 64, 253, +281, 499, 239, 324, 124, -6, 128, -173, +66, -178, -146, -137, -375, -105, -360, -47, +19, 144, 432, 294, 487, 196, 157, -65, +-297, -289, -446, -244, -177, -41, 214, 107, +416, 184, 229, 186, -167, 81, -332, -134, +-131, -300, 257, -156, 423, 194, 108, 322, +-311, 85, -399, -262, -41, -304, 433, 0, +485, 248, 83, 232, -346, 22, -432, -145, +-99, -123, 314, -38, 424, 16, 266, 25, +-55, -6, -267, -4, -258, 16, -144, 35, +81, 82, 279, 59, 352, -46, 267, -130, +-46, -79, -380, 84, -415, 108, -162, -91, +271, -234, 512, -76, 363, 297, 39, 455, +-285, 158, -374, -290, -234, -507, -39, -358, +187, 3, 337, 318, 272, 464, 109, 346, +-168, -11, -313, -357, -210, -443, -59, -208, +118, 134, 168, 286, 112, 185, 83, 13, +-11, -43, -114, 32, -161, 25, -190, -142, +-44, -275, 147, -151, 209, 190, 149, 388, +-117, 229, -287, -111, -176, -331, 27, -266, +186, -18, 111, 204, -127, 287, -184, 149, +-108, -135, 46, -321, 146, -232, 47, 84, +-45, 351, -103, 303, -147, 11, -87, -295, +-66, -370, 4, -162, 127, 133, 119, 325, +48, 300, -101, 65, -254, -192, -194, -313, +-53, -191, 109, 80, 221, 207, 121, 108, +-22, -45, -153, -42, -250, 87, -149, 72, +-21, -109, 118, -203, 220, -87, 97, 122, +-63, 200, -180, 124, -187, 41, 15, -70, +118, -217, 69, -288, -14, -136, -132, 247, +-42, 515, 127, 355, 165, -142, 96, -596, +-141, -551, -279, 1, -135, 549, 78, 609, +272, 111, 249, -452, 10, -541, -106, -185, +-151, 256, -82, 438, 59, 279, 65, -2, +81, -250, 59, -348, -22, -225, -6, 8, +16, 233, 54, 317, 123, 189, 16, -7, +-62, -173, -72, -229, -18, -151, 140, -28, +127, 99, 20, 152, -22, 75, -42, -13, +60, -40, 136, 4, 32, 47, -64, -9, +-169, -55, -100, -39, 200, -51, 367, -93, +310, -66, -44, 113, -448, 303, -457, 205, +-122, -133, 345, -339, 623, -224, 389, 59, +-54, 181, -420, 123, -501, 77, -156, 40, +193, -52, 339, -177, 270, -208, 28, -18, +-71, 225, -50, 296, -87, 153, -126, -137, +-192, -358, -82, -330, 206, -69, 319, 292, +229, 445, -41, 251, -303, -109, -301, -371, +-175, -328, 26, -59, 259, 161, 276, 232, +130, 144, -142, 12, -349, -78, -224, -150, +27, -134, 211, -2, 204, 151, -24, 223, +-196, 103, -232, -154, -135, -331, 91, -283, +220, 30, 186, 401, 14, 468, -223, 162, +-299, -281, -184, -474, -35, -270, 106, 42, +150, 199, 165, 172, 161, 103, 4, 124, +-238, 129, -406, -9, -347, -232, -27, -386, +291, -249, 387, 121, 264, 406, -33, 404, +-287, 110, -354, -203, -258, -314, -26, -252, +163, -84, 220, 105, 225, 222, 113, 233, +-78, 83, -264, -112, -343, -180, -149, -127, +177, 1, 324, 83, 226, 65, -59, 13, +-209, -30, -117, -12, 7, 30, 59, 5, +20, -37, -4, -9, 67, 100, 58, 149, +-52, -28, -102, -297, -25, -345, 171, -35, +205, 420, 7, 555, -180, 196, -180, -346, +22, -592, 217, -344, 189, 156, 19, 449, +-103, 334, -97, -32, 48, -284, 115, -204, +35, 67, -62, 220, -77, 85, 80, -165, +254, -222, 207, -17, -6, 188, -255, 177, +-307, -2, -66, -124, 224, -83, 357, 2, +259, 33, 17, 27, -128, 31, -168, 19, +-161, -38, -74, -86, 38, -37, 165, 57, +233, 85, 143, 17, 44, -42, -42, 19, +-130, 87, -162, 26, -159, -152, -18, -246, +205, -91, 273, 180, 168, 312, -60, 181, +-215, -68, -143, -212, -11, -163, 48, -30, +31, 52, -17, 34, 42, -30, 119, -27, +56, 60, -75, 182, -187, 177, -155, -18, +30, -261, 158, -326, 168, -105, 44, 214, +-165, 312, -213, 116, -118, -147, 40, -207, +165, -15, 71, 173, -42, 160, -104, -21, +-134, -217, -62, -237, -7, -79, 81, 152, +145, 307, 16, 237, -197, -15, -294, -231, +-165, -256, 175, -95, 347, 60, 154, 94, +-178, 95, -399, 91, -244, 76, 109, 4, +232, -102, 133, -130, -110, -88, -252, -32, +-79, 45, 108, 150, 217, 219, 122, 106, +-222, -197, -384, -379, -299, -201, 47, 207, +452, 451, 439, 248, 122, -163, -297, -381, +-550, -261, -345, 56, 51, 253, 373, 211, +427, 33, 91, -150, -224, -147, -283, 33, +-121, 172, 138, 111, 148, -166, -33, -337, +-124, -157, -62, 219, 161, 439, 288, 288, +66, -102, -196, -364, -324, -348, -152, -126, +234, 141, 376, 268, 225, 257, -88, 87, +-342, -140, -215, -233, 101, -135, 328, 54, +293, 132, -38, 11, -277, -107, -213, -28, +32, 140, 286, 182, 297, -25, 91, -230, +-97, -159, -222, 99, -173, 228, 6, 57, +118, -209, 203, -251, 210, -18, 136, 250, +77, 347, -83, 200, -244, -101, -265, -404, +-146, -531, 151, -264, 430, 297, 443, 737, +210, 641, -219, 17, -518, -644, -409, -782, +-26, -354, 430, 286, 577, 670, 246, 550, +-223, 87, -519, -413, -359, -593, 119, -316, +418, 174, 369, 494, 79, 433, -215, 66, +-282, -288, -223, -438, -116, -349, 116, -32, +293, 325, 354, 523, 198, 361, -194, -96, +-425, -453, -429, -459, -150, -185, 262, 134, +414, 277, 334, 294, 30, 250, -321, 46, +-415, -242, -272, -437, 79, -292, 362, 159, +297, 455, -28, 339, -349, -85, -396, -421, +-89, -354, 230, 13, 316, 356, 167, 452, +-134, 197, -308, -218, -262, -506, -138, -480, +68, -87, 175, 374, 192, 599, 131, 433, +-87, -40, -299, -459, -342, -546, -153, -280, +194, 136, 340, 394, 207, 349, -56, 144, +-304, -97, -318, -248, -179, -264, -5, -153, +233, 65, 343, 249, 297, 289, 4, 144, +-445, -116, -661, -345, -421, -359, 219, -112, +757, 268, 714, 484, 106, 343, -584, -30, +-795, -358, -411, -429, 234, -261, 623, 35, +500, 324, 46, 455, -379, 258, -433, -184, +-181, -502, 152, -368, 330, 154, 259, 519, +72, 363, -128, -154, -208, -529, -180, -426, +-87, 8, 40, 397, 175, 529, 313, 352, +343, -40, 142, -429, -248, -645, -562, -462, +-520, 67, -43, 607, 590, 812, 880, 446, +562, -272, -206, -823, -838, -801, -824, -166, +-174, 614, 592, 891, 901, 486, 571, -303, +-115, -823, -634, -657, -673, -26, -197, 604, +394, 755, 693, 369, 517, -233, -40, -691, +-490, -717, -564, -234, -217, 442, 337, 863, +603, 647, 448, -112, -41, -746, -459, -784, +-462, -201, -115, 465, 299, 649, 458, 348, +258, -122, -89, -420, -294, -396, -263, -140, +-46, 200, 156, 442, 186, 333, 161, -58, +10, -451, -107, -480, -133, -49, -109, 424, +19, 543, 51, 174, 49, -335, 84, -528, +83, -268, 43, 160, -140, 421, -299, 344, +-209, 52, 86, -201, 358, -327, 333, -268, +-11, -96, -377, 156, -438, 396, -180, 457, +206, 181, 382, -329, 213, -735, -92, -635, +-314, 29, -259, 782, -13, 1037, 153, 489, +111, -510, -104, -1228, -215, -1085, -38, -78, +216, 1117, 268, 1550, -19, 778, -400, -676, +-470, -1679, -137, -1347, 312, 49, 528, 1362, +283, 1581, -231, 595, -606, -733, -534, -1427, +-16, -1073, 520, 4, 650, 1028, 248, 1288, +-366, 645, -738, -495, -592, -1288, -55, -1133, +531, -150, 797, 1010, 519, 1454, -121, 848, +-767, -399, -967, -1446, -459, -1504, 390, -449, +1016, 995, 916, 1835, 133, 1354, -702, -186, +-1027, -1637, -676, -1954, 125, -810, 809, 965, +988, 2050, 526, 1656, -358, 11, -1012, -1676, +-958, -2114, -216, -957, 773, 921, 1177, 2082, +765, 1622, -186, 3, -1021, -1533, -1088, -1863, +-417, -870, 551, 606, 1164, 1601, 968, 1496, +148, 429, -785, -924, -1169, -1707, -700, -1342, +289, 35, 1082, 1474, 1121, 1889, 349, 874, +-661, -873, -1153, -1980, -823, -1606, 172, 2, +1058, 1616, 1167, 2018, 448, 924, -641, -858, +-1190, -2001, -847, -1675, 115, -130, 1022, 1489, +1156, 2035, 494, 1105, -494, -624, -1116, -1910, +-892, -1782, -67, -307, 804, 1381, 1105, 1993, +626, 1054, -246, -635, -899, -1778, -908, -1507, +-278, -138, 489, 1255, 906, 1672, 726, 844, +71, -575, -600, -1571, -873, -1396, -550, -137, +176, 1284, 735, 1693, 766, 748, 257, -830, +-402, -1706, -684, -1161, -486, 290, 26, 1480, +457, 1440, 478, 268, 146, -1112, -236, -1622, +-390, -818, -201, 701, 61, 1670, 205, 1275, +172, -185, 27, -1486, -46, -1520, -91, -373, +-172, 1001, -221, 1482, -155, 816, 122, -347, +443, -1154, 441, -1042, 38, -189, -517, 742, +-779, 1037, -452, 483, 215, -471, 783, -947, +836, -561, 265, 327, -530, 909, -1012, 638, +-837, -206, -63, -914, 727, -861, 1044, -53, +673, 877, -196, 1157, -953, 484, -1106, -697, +-515, -1393, 477, -981, 1135, 290, 1001, 1446, +116, 1473, -923, 283, -1290, -1239, -685, -1837, +450, -948, 1260, 764, 1049, 1941, 14, 1592, +-1027, -49, -1279, -1709, -530, -2034, 618, -782, +1278, 1119, 978, 2152, -84, 1542, -1087, -246, +-1266, -1879, -536, -2110, 613, -737, 1326, 1277, +1057, 2371, 0, 1648, -1115, -437, -1396, -2238, +-550, -2289, 733, -501, 1488, 1708, 1022, 2545, +-300, 1367, -1364, -881, -1315, -2402, -121, -2027, +1222, -57, 1505, 1945, 539, 2391, -896, 928, +-1602, -1280, -935, -2428, 500, -1612, 1593, 495, +1419, 2139, 70, 2024, -1337, 329, -1683, -1532, +-688, -2108, 849, -1059, 1695, 716, 1274, 1852, +-24, 1560, -1271, 109, -1575, -1335, -767, -1724, +574, -770, 1519, 730, 1365, 1583, 270, 1141, +-943, -165, -1466, -1236, -890, -1241, 250, -265, +1100, 807, 1123, 1167, 367, 561, -454, -399, +-794, -969, -619, -729, -136, 71, 271, 719, +539, 745, 548, 160, 278, -483, -142, -680, +-559, -289, -689, 267, -327, 548, 306, 349, +835, -92, 804, -363, 133, -308, -666, 1, +-1034, 163, -672, 102, 177, -48, 976, -11, +1176, 224, 552, 304, -628, -16, -1496, -548, +-1319, -712, -40, -202, 1502, 715, 1942, 1188, +814, 687, -1110, -587, -2290, -1595, -1646, -1366, +348, 94, 2116, 1715, 2301, 2110, 654, 788, +-1478, -1371, -2598, -2653, -1790, -1920, 458, 515, +2386, 2764, 2508, 2958, 661, 663, -1739, -2352, +-2778, -3564, -1610, -1846, 799, 1479, 2537, 3646, +2232, 2805, 88, -376, -2121, -3268, -2604, -3507, +-913, -849, 1561, 2543, 2694, 3955, 1576, 2161, +-905, -1494, -2658, -4092, -2115, -3418, 151, 137, +2312, 3770, 2455, 4377, 479, 1358, -1853, -2904, +-2588, -4842, -1070, -2779, 1355, 1628, 2599, 4771, +1569, 3967, -871, -123, -2655, -4236, -2152, -4827, +261, -1443, 2551, 3257, 2748, 5231, 595, 2902, +-2188, -1831, -3229, -5009, -1597, -4034, 1474, 139, +3426, 4101, 2525, 4591, -520, 1458, -3266, -2776, +-3273, -4529, -511, -2575, 2704, 1426, 3768, 4015, +1692, 3130, -1846, -323, -3868, -3311, -2736, -3308, +669, -548, 3514, 2557, 3488, 3316, 648, 1305, +-2653, -1787, -3731, -3200, -1819, -1891, 1503, 1040, +3569, 2939, 2693, 2214, -347, -495, -2979, -2624, +-3051, -2251, -646, 199, 2209, 2374, 3110, 2196, +1416, -11, -1273, -2189, -2839, -2272, -1983, -321, +423, 1925, 2392, 2451, 2341, 891, 361, -1467, +-1744, -2546, -2289, -1481, -944, 848, 1104, 2413, +2054, 1878, 1228, -258, -532, -2100, -1673, -2029, +-1274, -203, 196, 1743, 1358, 2044, 1246, 618, +57, -1347, -1087, -2032, -1199, -1031, -260, 879, +892, 2019, 1261, 1420, 445, -453, -745, -1927, +-1313, -1615, -698, 130, 600, 1724, 1420, 1591, +1011, 92, -280, -1410, -1375, -1444, -1366, -222, +-262, 1053, 1058, 1235, 1545, 300, 817, -806, +-432, -1035, -1318, -243, -1198, 728, -265, 935, +756, 115, 1121, -875, 748, -1022, -65, -68, +-734, 1102, -931, 1316, -526, 250, 207, -1177, +801, -1691, 842, -700, 230, 1000, -558, 1960, +-907, 1264, -565, -628, 124, -2075, 753, -1688, +862, 252, 327, 1998, -579, 1879, -1157, 25, +-813, -1802, 320, -1912, 1318, -261, 1214, 1595, +-39, 1946, -1316, 492, -1540, -1426, -473, -2091, +1059, -738, 1769, 1339, 975, 2266, -648, 1022, +-1800, -1239, -1528, -2426, 10, -1339, 1554, 1010, +1912, 2489, 693, 1744, -1084, -577, -2068, -2444, +-1380, -2264, 448, -66, 1929, 2307, 1760, 2772, +222, 811, -1499, -2016, -1996, -3148, -818, -1484, +1020, 1553, 1988, 3203, 1216, 2000, -595, -962, +-1866, -2954, -1379, -2278, 239, 394, 1606, 2589, +1425, 2377, 68, 50, -1289, -2276, -1514, -2482, +-375, -397, 1061, 2108, 1561, 2662, 712, 795, +-752, -1949, -1507, -2943, -911, -1265, 449, 1668, +1329, 3138, 955, 1739, -270, -1281, -1104, -3155, +-806, -2121, 314, 870, 1093, 3067, 722, 2411, +-386, -453, -1142, -2927, -888, -2728, 254, 12, +1324, 2741, 1322, 3004, 161, 547, -1341, -2428, +-1753, -3172, -648, -1109, 1135, 1985, 2035, 3172, +1173, 1567, -687, -1492, -1940, -3048, -1580, -1903, +150, 1025, 1747, 2909, 1830, 2144, 407, -533, +-1344, -2712, -1942, -2395, -920, -20, 911, 2339, +2012, 2555, 1420, 669, -420, -1758, -1902, -2543, +-1770, -1243, -49, 1087, 1679, 2377, 1918, 1617, +460, -507, -1284, -2134, -1943, -1831, -837, 100, +971, 1860, 1905, 1904, 1134, 286, -635, -1484, +-1741, -1901, -1322, -705, 256, 935, 1465, 1758, +1376, 1102, 88, -313, -1164, -1415, -1441, -1340, +-334, -247, 1017, 912, 1471, 1304, 507, 693, +-843, -316, -1494, -1062, -819, -959, 478, -271, +1341, 624, 1126, 1051, 19, 764, -1071, -79, +-1319, -951, -450, -1105, 667, -406, 1198, 720, +673, 1280, -286, 757, -1033, -490, -820, -1356, +-54, -997, 776, 288, 866, 1468, 286, 1270, +-525, -109, -823, -1594, -512, -1639, 109, -129, +573, 1671, 590, 1999, 306, 412, -216, -1631, +-530, -2222, -637, -659, -254, 1516, 240, 2319, +681, 809, 612, -1472, 101, -2397, -537, -947, +-704, 1473, -358, 2567, 168, 1134, 505, -1479, +436, -2774, 190, -1367, -141, 1441, -427, 2921, +-537, 1522, -277, -1432, 291, -3025, 756, -1572, +711, 1507, 26, 3177, -849, 1669, -1138, -1593, +-440, -3414, 674, -1922, 1341, 1501, 921, 3599, +-306, 2323, -1265, -1191, -1223, -3629, -222, -2672, +991, 771, 1459, 3453, 807, 2837, -567, -356, +-1530, -3138, -1354, -2851, -11, 2, 1427, 2742, +1854, 2809, 649, 334, -1050, -2339, -2016, -2738, +-1210, -566, 636, 1959, 1969, 2554, 1580, 653, +-177, -1641, -1750, -2277, -1817, -651, -194, 1364, +1613, 1932, 2101, 659, 628, -1002, -1466, -1533, +-2389, -723, -1111, 500, 1313, 997, 2735, 735, +1679, 123, -966, -331, -2953, -616, -2261, -691, +646, -402, 3084, 367, 2757, 1166, -280, 1092, +-3156, -165, -3048, -1621, 74, -1630, 3224, 160, +3311, 2103, 123, 1993, -3234, -339, -3503, -2523, +-304, -2145, 3193, 531, 3608, 2734, 505, 2133, +-3004, -670, -3532, -2739, -613, -1902, 2704, 891, +3231, 2572, 738, 1394, -2264, -1225, -2882, -2267, +-819, -647, 1733, 1609, 2411, 1778, 902, -176, +-1257, -1804, -1965, -1132, -921, 817, 829, 1643, +1592, 466, 959, -1028, -464, -1044, -1510, 30, +-1236, 588, 272, 109, 1707, -117, 1641, 432, +-250, 847, -2210, -279, -2081, -1694, 399, -1419, +2692, 1007, 2394, 2674, -472, 1416, -3078, -1705, +-2648, -3026, 382, -1028, 3108, 2010, 2849, 2750, +-73, 641, -2909, -1763, -3103, -2184, -570, -573, +2467, 1207, 3364, 1735, 1425, 747, -2000, -731, +-3827, -1555, -2255, -920, 1564, 551, 4077, 1531, +2712, 959, -1349, -563, -4014, -1497, -2694, -924, +1082, 549, 3402, 1417, 2305, 894, -737, -460, +-2488, -1270, -1715, -910, 362, 317, 1467, 1174, +960, 974, -172, -252, -630, -1253, -196, -1027, +286, 409, 56, 1453, -370, 935, -380, -717, +164, -1542, 616, -608, 372, 903, -197, 1304, +-422, 278, -274, -779, -68, -947, -37, -282, +270, 368, 743, 865, 639, 831, -524, 40, +-1693, -1397, -1191, -1788, 919, 1, 2490, 2454, +1498, 2460, -1129, -639, -2849, -3291, -1775, -2242, +1047, 1347, 2980, 3101, 2159, 1501, -844, -1238, +-3238, -2204, -2454, -1358, 1063, 403, 3656, 1944, +2430, 2131, -1550, -91, -3793, -2865, -1990, -2730, +1916, 983, 3628, 3927, 1687, 2243, -1728, -2173, +-3214, -4008, -1602, -1344, 1359, 2502, 2989, 3522, +1699, 1105, -1114, -2161, -2893, -3414, -1801, -1482, +1093, 1939, 2972, 3694, 1864, 1838, -1156, -1862, +-3099, -3836, -1891, -2118, 1304, 1597, 3136, 3873, +1695, 2526, -1496, -1355, -3027, -3987, -1453, -2671, +1536, 1315, 2862, 3793, 1388, 2433, -1439, -1046, +-2798, -3181, -1440, -2402, 1422, 370, 2884, 2862, +1474, 2813, -1522, -39, -2870, -3118, -1337, -2857, +1533, 501, 2843, 3080, 1399, 1940, -1376, -1003, +-2756, -2210, -1511, -784, 1199, 965, 2690, 1228, +1460, 170, -1189, -827, -2511, -837, -1181, 136, +1265, 981, 2210, 684, 673, -501, -1544, -993, +-1958, -265, -62, 658, 1807, 578, 1391, -153, +-719, -523, -1846, -141, -600, 391, 1190, 416, +1233, -102, -274, -662, -1100, -382, -331, 451, +728, 911, 611, 163, -459, -857, -954, -916, +-152, 32, 1061, 886, 1368, 966, -53, 329, +-1750, -754, -1814, -1447, 301, -908, 2360, 888, +2007, 1957, -573, 995, -2493, -1040, -1717, -1801, +721, -774, 2100, 692, 1224, 1215, -693, 883, +-1628, 2, -879, -979, 598, -1254, 1177, -362, +532, 995, -543, 1293, -832, 308, -272, -680, +347, -816, 341, -317, -36, 62, -191, 266, +42, 377, 234, 361, 79, 95, -230, -124, +-376, -356, 28, -457, 318, -318, 224, 262, +-169, 749, -177, 494, 245, -286, 523, -621, +19, -197, -705, 268, -733, 48, 124, -355, +1037, -52, 939, 690, -115, 793, -1061, -233, +-887, -1250, 198, -905, 940, 484, 520, 1342, +-375, 666, -558, -549, 22, -953, 326, -332, +-62, 276, -384, 495, -11, 341, 390, 115, +247, -480, -302, -805, -301, -230, 4, 998, +199, 1301, -57, 22, 5, -1547, 84, -1480, +106, 205, -123, 1708, -86, 1458, 109, -234, +204, -1583, -25, -1437, -192, 122, -93, 1455, +191, 1450, 350, 29, 174, -1379, -266, -1511, +-652, -215, -237, 1276, 769, 1650, 1066, 486, +63, -1179, -1302, -1784, -1245, -766, 242, 1020, +1572, 1850, 1199, 1012, -408, -761, -1644, -1827, +-1245, -1294, 335, 446, 1576, 1739, 1175, 1534, +-551, -129, -1466, -1630, -742, -1620, 634, -113, +972, 1485, 99, 1668, -549, 198, -313, -1469, +174, -1715, 230, -106, -47, 1663, -118, 1676, +103, -125, 200, -1753, 26, -1487, -303, 175, +-282, 1441, 275, 1266, 778, 269, 255, -877, +-838, -1346, -1117, -930, 171, 499, 1528, 1665, +1084, 1315, -749, -489, -1772, -1824, -797, -1362, +1018, 472, 1649, 1791, 536, 1395, -1080, -287, +-1610, -1801, -666, -1594, 996, 243, 1606, 1897, +717, 1627, -902, -328, -1664, -1860, -948, -1416, +587, 303, 1613, 1578, 1216, 1286, -371, -155, +-1578, -1288, -1276, -1205, 263, 40, 1451, 1085, +1038, 938, -170, -55, -977, -706, -721, -566, +71, 51, 751, 302, 698, 286, -25, 53, +-817, -129, -606, -238, 328, -99, 898, 121, +465, 346, -455, 143, -713, -210, -237, -420, +79, -281, 304, 235, 327, 441, 248, 416, +-58, 4, -475, -393, -462, -659, -91, -396, +174, 378, 396, 1003, 318, 590, 38, -504, +-257, -1019, -553, -420, -248, 520, 145, 572, +453, 99, 426, -242, 226, -112, -406, 64, +-623, 135, -377, 81, 552, -222, 887, -532, +267, -265, -621, 573, -649, 988, -39, 309, +496, -778, 414, -1040, 134, -359, -92, 476, +-279, 985, -424, 721, -192, -155, 300, -1298, +537, -1065, 425, 476, -139, 1655, -646, 684, +-745, -1116, -177, -1362, 797, 326, 981, 1282, +-19, 274, -983, -1106, -924, -738, 292, 882, +918, 1263, 423, -149, -279, -1480, -465, -923, +-246, 911, -156, 1560, -41, 195, 494, -1308, +787, -1054, 302, 612, -668, 1148, -1258, -23, +-342, -1020, 994, -269, 1540, 1025, 472, 752, +-1339, -805, -1872, -1399, -143, -138, 1817, 1346, +1976, 1343, -263, -262, -2171, -1549, -1560, -1261, +552, 522, 1883, 1826, 969, 1127, -746, -1032, +-1241, -1977, -426, -541, 501, 1512, 511, 1485, +50, -380, -99, -1377, 46, -353, -186, 1042, +-659, 619, -415, -860, 767, -1119, 1349, 360, +303, 1557, -1356, 573, -1521, -1192, 62, -1396, +1478, 425, 1179, 1569, -207, 463, -1013, -1399, +-694, -1263, -41, 573, 496, 1705, 740, 704, +505, -923, -236, -1396, -1039, -664, -816, 526, +446, 1301, 1375, 1161, 783, -137, -904, -1640, +-1574, -1506, -336, 227, 1229, 1651, 1383, 1251, +-94, -148, -1368, -968, -980, -898, 115, -542, +830, 181, 792, 1065, 267, 1187, -306, 71, +-898, -1361, -893, -1274, 125, 33, 1048, 1193, +1030, 1099, -16, 133, -864, -920, -828, -1153, +-251, -377, 259, 959, 758, 1317, 904, 194, +441, -1069, -791, -1160, -1555, 63, -838, 1010, +858, 955, 1948, 75, 1194, -896, -900, -1274, +-2080, -441, -1274, 1035, 919, 1843, 2161, 771, +1167, -1202, -1058, -2132, -2118, -1065, -1038, 1007, +1108, 2147, 1856, 1404, 776, -548, -930, -1959, +-1524, -1679, -518, 40, 700, 1554, 879, 1761, +260, 533, -370, -1009, -397, -1759, -187, -1045, +-8, 524, 222, 1623, 500, 1251, 347, -114, +-350, -1175, -969, -1242, -505, -403, 668, 589, +1245, 1253, 651, 951, -675, -85, -1370, -1239, +-744, -1389, 579, -443, 1359, 1041, 984, 1860, +-327, 1162, -1323, -896, -1202, -2454, -41, -1683, +1176, 1068, 1428, 2782, 416, 1496, -1010, -1277, +-1606, -2351, -664, -848, 883, 1031, 1474, 1318, +591, 458, -709, -223, -1207, -400, -494, -553, +462, -655, 834, -115, 475, 738, -145, 1124, +-525, 479, -401, -597, -76, -1184, 16, -794, +97, 149, 308, 924, 617, 899, 429, 333, +-452, -329, -1106, -700, -646, -760, 416, -384, +1055, 353, 671, 1026, -228, 902, -543, -13, +-341, -965, -164, -1128, -91, -382, 48, 619, +434, 1147, 603, 832, 122, -121, -680, -1009, +-816, -1144, -189, -482, 686, 626, 743, 1310, +212, 1106, -445, -143, -650, -1363, -383, -1472, +229, -194, 521, 1165, 414, 1371, -111, 444, +-417, -617, -210, -1064, 199, -837, 148, 14, +-62, 1030, -177, 1224, -24, 131, 142, -1216, +253, -1200, 188, 204, -73, 1238, -405, 674, +-435, -550, -53, -934, 454, -132, 529, 618, +325, 634, 72, 49, -507, -485, -1115, -726, +-970, -453, 495, 286, 2229, 1118, 1960, 1134, +-582, -30, -3102, -1536, -2797, -1879, 447, -382, +3597, 1751, 3298, 2431, -197, 854, -3618, -1688, +-3467, -2665, 58, -1173, 3264, 1386, 3100, 2481, +21, 1234, -2650, -1045, -2404, -2001, 12, -962, +1974, 782, 1763, 1440, -151, 490, -1501, -693, +-1198, -980, 264, -94, 1276, 766, 929, 787, +-258, -72, -1146, -899, -993, -873, 154, 20, +1218, 905, 1194, 945, -63, 209, -1373, -610, +-1249, -808, 113, -563, 1218, -25, 1071, 485, +-42, 895, -831, 746, -761, -80, -145, -993, +421, -1154, 383, -349, 114, 621, -118, 1019, +24, 765, 251, 280, 37, -383, -401, -1109, +-615, -1377, -311, -489, 355, 1251, 888, 2171, +942, 1232, 284, -977, -1016, -2307, -1778, -1645, +-1024, 321, 863, 1745, 2510, 1702, 1800, 470, +-680, -774, -2832, -1421, -2413, -1200, 443, -240, +3054, 1021, 2590, 1685, -430, 913, -2932, -802, +-2271, -1744, 539, -930, 2408, 721, 1540, 1379, +-577, 460, -1611, -717, -834, -922, 380, 11, +926, 920, 472, 850, -12, -317, -435, -1336, +-666, -1128, -501, 386, 218, 1532, 1097, 1278, +1178, 7, -53, -986, -1502, -1188, -1658, -842, +-317, -121, 1509, 865, 2005, 1517, 909, 1141, +-1088, -99, -2208, -1425, -1521, -1811, 473, -1037, +2096, 640, 1916, 2067, 212, 1991, -1565, 355, +-1934, -1599, -984, -2288, 638, -1410, 1600, 445, +1533, 2061, 413, 2379, -948, 783, -1638, -1566, +-1279, -2727, -65, -1564, 1319, 712, 1738, 2220, +952, 1969, -633, 459, -1831, -1369, -1485, -2203, +24, -1275, 1462, 788, 1669, 2091, 402, 1353, +-1097, -559, -1489, -1643, -555, -1014, 808, 522, +1202, 1398, 520, 745, -529, -685, -903, -1566, +-541, -751, 241, 860, 712, 1735, 703, 1029, +78, -470, -552, -1585, -903, -1598, -592, -521, +356, 1160, 1131, 2154, 1093, 1430, -31, -541, +-1304, -2079, -1432, -1824, -189, -290, 1084, 1279, +1329, 1785, 455, 1066, -629, -438, -999, -1450, +-525, -1154, 264, 114, 583, 794, 200, 326, +-342, -306, -82, -46, 563, 783, 590, 879, +-258, -183, -1136, -1447, -831, -1676, 135, -446, +943, 1366, 1168, 2343, 707, 1560, -338, -526, +-1418, -2397, -1660, -2547, -284, -814, 1479, 1785, +1917, 3085, 578, 1944, -1120, -966, -1460, -2935, +-293, -2120, 712, 460, 492, 1988, -596, 1259, +-742, -287, 591, -695, 1796, 7, 1052, 334, +-1258, -189, -2619, -883, -1362, -652, 1117, 302, +2451, 1126, 1581, 1005, -378, 100, -1517, -812, +-1501, -877, -565, -417, 542, -34, 1119, 115, +966, 432, 223, 1085, -619, 891, -771, -327, +-298, -1607, 170, -1455, 240, 7, -109, 1208, +-86, 1240, 361, 571, 652, -105, 372, -535, +-469, -969, -1092, -1063, -906, -331, 63, 849, +1246, 1663, 1473, 1112, 343, -372, -1184, -1490, +-1451, -1264, -333, -126, 818, 656, 630, 532, +-160, 336, -259, 439, 461, 577, 782, -46, +-76, -1038, -1127, -1476, -1364, -707, -218, 778, +1235, 1955, 1772, 1597, 789, -205, -1046, -1948, +-1901, -1968, -835, -134, 850, 1441, 1429, 1458, +426, 291, -694, -560, -644, -604, 54, -386, +460, -281, 252, 10, -57, 391, -297, 573, +-495, 262, -378, -241, 275, -312, 929, -161, +842, 0, -122, -189, -1139, -357, -1110, 9, +-152, 796, 807, 1158, 1114, 395, 382, -1208, +-433, -2004, -728, -1030, -355, 1166, 138, 2528, +251, 1638, -20, -772, -104, -2396, 16, -1878, +299, 163, 445, 1665, 212, 1606, -318, 473, +-884, -703, -895, -1098, -37, -791, 1132, -61, +1602, 558, 769, 638, -776, 364, -1911, 12, +-1568, -270, -147, -422, 1600, -426, 2099, 25, +1191, 518, -709, 451, -2060, -110, -1854, -563, +-220, -128, 1376, 472, 1737, 417, 705, -368, +-380, -795, -835, -178, -650, 787, -475, 848, +-261, -11, 199, -782, 805, -656, 812, -27, +261, 266, -423, 302, -665, 346, -522, 438, +-172, 68, 46, -640, 329, -962, 555, -345, +505, 688, 281, 1099, -399, 496, -944, -559, +-813, -890, 106, -389, 1042, 401, 949, 492, +-56, 18, -816, -312, -451, -55, 286, 366, +442, 330, -230, -197, -577, -594, -180, -466, +660, 88, 683, 643, 82, 700, -557, 285, +-536, -488, -144, -948, 227, -717, 251, 180, +165, 1063, -16, 1047, -101, 52, -97, -985, +107, -1062, 133, -90, 1, 749, -183, 675, +-298, 21, -258, -353, 31, -183, 541, 59, +856, -33, 362, -181, -785, -161, -1336, 185, +-662, 521, 640, 413, 1261, -270, 799, -933, +-42, -706, -531, 447, -669, 1223, -544, 736, +-387, -491, -13, -1134, 622, -636, 1096, 200, +1043, 709, -17, 702, -1273, 317, -1787, -278, +-859, -822, 619, -762, 1627, -115, 1585, 732, +604, 1051, -749, 539, -1660, -493, -1623, -1184, +-363, -803, 1029, 338, 1667, 1018, 1182, 615, +101, -236, -1010, -505, -1421, -98, -962, 140, +189, -66, 1146, -332, 1125, -154, 195, 289, +-692, 493, -725, 318, -92, -98, 503, -358, +291, -382, -336, -210, -571, -90, -197, 112, +433, 357, 700, 620, 499, 470, 116, -93, +-551, -825, -1131, -1093, -952, -681, 125, 459, +1434, 1535, 1603, 1637, 437, 251, -989, -1595, +-1645, -2224, -1105, -908, 137, 1130, 1135, 2115, +1385, 1283, 637, -328, -427, -1406, -958, -1280, +-843, -421, -254, 451, 247, 866, 444, 789, +458, 345, 315, -262, 142, -729, -19, -646, +-333, -62, -529, 442, -556, 237, -234, -282, +303, -207, 755, 661, 1001, 1126, 628, 287, +-464, -1297, -1521, -1823, -1651, -763, -347, 970, +1453, 1835, 2144, 1386, 1274, 174, -662, -1049, +-2013, -1636, -1807, -1294, -296, -162, 1337, 1120, +1747, 1736, 862, 1098, -423, -287, -1122, -1359, +-971, -1134, -273, -92, 409, 466, 858, 144, +607, -159, -61, 379, -673, 1027, -603, 645, +50, -533, 590, -1290, 419, -996, -109, -223, +-476, 475, -258, 1017, 48, 1226, 185, 670, +166, -529, 84, -1462, 78, -1345, -26, -379, +-118, 680, -76, 1304, -124, 1188, -384, 398, +-264, -760, 342, -1356, 1105, -875, 799, 245, +-400, 886, -1572, 519, -1283, -256, 124, -375, +1415, 250, 1565, 824, 529, 441, -883, -719, +-1521, -1522, -999, -1130, 313, 341, 1248, 1757, +983, 1964, 18, 661, -779, -1189, -663, -2234, +-14, -1615, 412, 49, 411, 1561, -102, 1908, +-503, 1025, -465, -367, 132, -1373, 884, -1368, +968, -514, -87, 438, -1288, 761, -1543, 524, +-175, 229, 1396, 240, 1689, 210, 479, -176, +-901, -793, -1329, -1036, -775, -497, -53, 512, +578, 1332, 959, 1233, 888, 263, 257, -899, +-762, -1413, -1221, -947, -820, 93, 107, 927, +930, 1149, 1087, 593, 596, -233, -174, -821, +-862, -803, -954, -305, -530, 259, 242, 585, +815, 591, 816, 144, 381, -370, -210, -569, +-596, -146, -653, 353, -472, 307, -104, -188, +498, -369, 870, -28, 755, 439, 5, 377, +-850, -55, -1085, -415, -527, -414, 392, -62, +894, 309, 769, 400, 213, 148, -329, -194, +-714, -280, -692, -136, -230, 7, 571, 130, +891, 248, 370, 195, -509, -141, -708, -433, +-80, -200, 567, 274, 376, 357, -248, -62, +-574, -274, -211, 64, 386, 399, 614, 123, +268, -413, -385, -570, -636, -110, -340, 335, +355, 507, 615, 342, 244, 86, -275, -227, +-551, -460, -412, -495, 144, -176, 707, 278, +796, 608, 28, 439, -1129, -85, -1246, -403, +-112, -186, 1208, 181, 1392, 55, 357, -468, +-784, -540, -1167, 137, -737, 859, 254, 845, +858, 94, 676, -644, -97, -814, -455, -465, +34, 117, 427, 377, -25, 306, -742, 186, +-650, 316, 214, 424, 758, 36, 500, -681, +98, -985, -49, -625, -73, 125, -447, 750, +-680, 1058, -399, 891, 302, 188, 797, -670, +729, -1180, 147, -1190, -379, -674, -596, 333, +-441, 1581, -218, 1981, -69, 845, 211, -1017, +504, -1961, 686, -1346, 321, -142, -229, 642, +-676, 885, -780, 892, -493, 670, 151, 178, +697, -523, 910, -1026, 530, -1064, -6, -397, +-421, 581, -823, 1014, -968, 591, -483, 4, +557, -9, 1413, 199, 1185, -176, 157, -981, +-844, -1088, -1246, -219, -886, 884, -121, 1187, +708, 739, 1104, 43, 723, -450, 14, -608, +-571, -526, -848, -510, -620, -482, -85, -38, +566, 989, 814, 1682, 357, 1012, -320, -669, +-633, -1813, -288, -1424, 288, -144, 506, 821, +107, 982, -542, 661, -696, 223, -6, -145, +780, -379, 897, -436, 192, -388, -593, -292, +-775, -86, -548, 239, -49, 563, 488, 652, +789, 300, 598, -313, -112, -710, -684, -484, +-580, 80, -94, 262, 255, -71, 185, -263, +-14, 199, 102, 818, 382, 741, 364, -122, +-223, -1029, -873, -1208, -696, -458, 257, 700, +1035, 1384, 680, 914, -363, -362, -892, -1167, +-377, -773, 501, 235, 724, 723, 66, 387, +-655, -193, -767, -463, 10, -305, 847, 162, +825, 570, 16, 482, -797, -192, -711, -732, +75, -489, 505, 298, 261, 615, -202, 167, +-131, -420, 311, -339, 410, 217, -51, 510, +-599, 171, -647, -336, -106, -460, 401, -155, +667, 133, 613, 256, 135, 265, -465, 167, +-951, -163, -700, -481, 170, -245, 811, 462, +738, 777, 79, 57, -416, -940, -425, -999, +-123, 37, 223, 1059, 303, 1110, -28, 284, +-513, -681, -596, -1109, 64, -742, 943, 217, +986, 921, 162, 751, -863, -77, -1117, -578, +-473, -278, 277, 303, 678, 425, 628, -36, +325, -621, 56, -761, -238, -235, -498, 654, +-605, 1178, -465, 786, 10, -212, 685, -912, +1054, -907, 736, -467, -298, -91, -1155, 244, +-1080, 681, -156, 983, 656, 782, 766, -33, +356, -948, 9, -1314, -178, -891, -314, 0, +-307, 775, -74, 1101, 125, 1018, 85, 510, +-21, -343, 45, -1192, 204, -1393, 88, -755, +-84, 283, -53, 1070, 94, 1310, -36, 924, +-409, -20, -388, -996, 202, -1268, 737, -601, +561, 216, -137, 439, -678, 170, -557, 151, +-64, 577, 331, 887, 456, 471, 220, -644, +-111, -1677, -292, -1637, -228, -219, 118, 1554, +284, 2205, 82, 1136, -254, -596, -336, -1585, +-14, -1319, 345, -403, 369, 377, 66, 663, +-286, 571, -468, 351, -227, 259, 222, 177, +670, -123, 496, -638, -134, -989, -738, -737, +-764, 72, -217, 1024, 431, 1442, 799, 927, +763, -286, 182, -1267, -604, -1329, -927, -573, +-586, 245, 134, 739, 597, 950, 522, 817, +222, 152, -147, -758, -300, -1124, -88, -528, +251, 374, 173, 681, -375, 250, -735, -233, +-255, -183, 554, 189, 894, 366, 521, 90, +-39, -276, -492, -370, -787, -185, -720, -63, +-83, -49, 721, 74, 925, 434, 379, 609, +-215, 249, -433, -397, -358, -694, -216, -447, +-21, -52, 152, 170, 16, 338, -208, 488, +-40, 392, 528, -116, 824, -556, 312, -433, +-588, 144, -1051, 440, -868, 130, -227, -404, +562, -512, 1087, -75, 1071, 462, 329, 677, +-572, 465, -1047, 47, -875, -428, -360, -832, +272, -889, 678, -333, 793, 649, 433, 1276, +-96, 955, -344, -27, -335, -698, -249, -693, +-393, -384, -380, -382, 4, -398, 683, 45, +949, 943, 425, 1405, -355, 801, -685, -539, +-509, -1445, -179, -1251, -64, -271, 68, 563, +394, 804, 477, 651, 239, 366, -3, -6, +-66, -404, -118, -549, -529, -327, -769, 18, +-264, 166, 681, 120, 1137, 17, 560, -47, +-388, 27, -800, 283, -564, 467, -53, 156, +290, -501, 365, -795, 294, -340, 66, 330, +-236, 512, -327, 240, -196, 4, 163, -11, +347, 16, 222, 17, -63, 12, -222, -158, +-246, -473, -125, -506, 21, 100, 195, 815, +261, 843, 114, 131, -85, -558, -83, -666, +-48, -385, -164, -41, -277, 254, -104, 461, +344, 388, 496, 19, 151, -328, -236, -359, +-376, -108, -228, 172, -28, 302, 126, 203, +295, -62, 216, -351, -84, -445, -191, -217, +-72, 266, 79, 692, -12, 635, -171, 43, +-78, -597, 146, -695, 233, -271, 157, 87, +-50, 170, -197, 186, -317, 362, -126, 384, +221, 112, 396, -231, 160, -340, -102, -327, +-214, -296, -104, -141, -140, 187, -154, 418, +64, 396, 352, 292, 316, 168, -73, -216, +-342, -761, -186, -806, 200, -63, 282, 776, +-58, 846, -466, 238, -452, -346, 39, -525, +601, -435, 711, -70, 315, 484, -282, 712, +-675, 167, -685, -730, -309, -927, 255, -174, +665, 745, 652, 892, 243, 276, -257, -432, +-512, -616, -399, -283, -40, 179, 316, 277, +185, 8, -162, -227, -268, -63, 134, 254, +553, 301, 354, -25, -284, -275, -621, -155, +-405, 184, 15, 300, 368, -12, 543, -441, +463, -502, -159, -77, -823, 390, -765, 492, +89, 333, 847, 232, 734, 74, 20, -416, +-395, -936, -413, -775, -323, 142, -236, 929, +61, 901, 472, 317, 568, -224, 146, -489, +-335, -567, -367, -308, -47, 161, 144, 420, +-67, 167, -380, -157, -224, -106, 337, 150, +804, 184, 599, 16, -137, -52, -777, -62, +-813, -155, -361, -249, 230, -70, 573, 182, +551, 226, 298, 51, 17, -16, -134, 69, +-211, 130, -407, 25, -508, -179, -376, -399, +122, -391, 638, -15, 823, 498, 531, 649, +-74, 256, -657, -232, -845, -396, -522, -302, +29, -215, 429, -100, 544, 163, 417, 377, +240, 265, 40, 25, -241, -30, -519, 60, +-532, -65, -319, -440, 153, -598, 536, -211, +602, 498, 414, 913, 17, 658, -339, -78, +-544, -712, -480, -811, -143, -383, 202, 137, +284, 415, 234, 348, 190, 208, 238, 131, +163, 113, -139, 25, -389, -105, -462, -220, +-359, -346, -112, -509, 236, -449, 646, 120, +762, 922, 242, 1120, -524, 338, -901, -662, +-478, -764, 305, -75, 655, 301, 265, -238, +-294, -896, -419, -615, -31, 504, 384, 1396, +395, 1287, 91, 321, -262, -782, -465, -1385, +-317, -1115, 83, -112, 470, 856, 446, 983, +41, 230, -332, -569, -371, -520, -226, 265, +13, 890, 257, 581, 432, -441, 314, -1212, +-136, -1000, -432, 23, -314, 980, -19, 1084, +109, 403, 43, -410, 41, -700, 79, -415, +82, -8, 113, 155, 240, 154, 174, 201, +-263, 269, -757, 98, -603, -252, 170, -397, +870, -175, 823, 133, 133, 171, -553, 63, +-670, 97, -344, 188, 128, 83, 320, -160, +274, -219, 142, -50, 59, 1, -90, -142, +-193, -155, -201, 133, -11, 429, 136, 357, +53, 50, -114, -255, -107, -498, 63, -609, +297, -303, 352, 534, 103, 1254, -372, 972, +-699, -282, -414, -1354, 302, -1275, 728, -272, +419, 567, -214, 697, -387, 509, -42, 512, +192, 543, 60, 92, -211, -775, -274, -1314, +-31, -972, 195, 6, 273, 880, 156, 1112, +-121, 766, -269, 126, -100, -427, 180, -665, +277, -557, 56, -249, -195, 34, -245, 246, +-179, 384, -1, 356, 189, 132, 309, -209, +157, -396, -150, -285, -269, 112, -25, 476, +191, 451, 101, -124, -168, -712, -248, -700, +-70, 30, 143, 757, 189, 820, 199, 303, +177, -319, 9, -704, -314, -762, -525, -402, +-327, 310, 250, 858, 684, 746, 589, 168, +84, -260, -434, -258, -602, -209, -458, -486, +-144, -785, 277, -535, 589, 421, 546, 1414, +104, 1505, -379, 459, -399, -972, -82, -1648, +175, -1132, 41, -48, -299, 763, -393, 909, +-5, 564, 508, 104, 731, -204, 351, -246, +-251, -164, -525, -159, -462, -226, -340, -236, +-273, -85, 99, 209, 734, 510, 989, 581, +326, 124, -690, -667, -1028, -983, -438, -301, +290, 822, 528, 1196, 370, 393, 173, -703, +-59, -1157, -348, -718, -441, 133, -127, 880, +329, 1089, 462, 536, 137, -427, -257, -1017, +-377, -801, -177, -44, 172, 538, 366, 581, +264, 252, -59, -95, -363, -198, -302, -87, +0, 9, 232, -30, 160, -180, -94, -214, +-184, -74, 66, 157, 335, 354, 356, 381, +3, 213, -402, -98, -579, -425, -414, -616, +17, -499, 548, 20, 744, 735, 467, 931, +-188, 304, -620, -584, -574, -766, -153, -166, +254, 387, 436, 309, 252, -60, -123, -271, +-410, -260, -252, -157, 259, 172, 561, 651, +293, 686, -251, 5, -571, -812, -406, -929, +-32, -300, 298, 437, 425, 749, 342, 549, +75, 32, -250, -443, -460, -488, -399, -100, +-46, 248, 408, 172, 609, -100, 294, -199, +-295, -77, -616, 102, -347, 262, 203, 380, +471, 188, 213, -292, -263, -607, -398, -354, +-38, 173, 467, 402, 485, 199, -60, -71, +-574, -206, -462, -144, 56, 159, 402, 552, +284, 542, 60, -181, -105, -1042, -240, -1115, +-281, -239, -16, 841, 419, 1267, 496, 857, +4, -12, -520, -801, -513, -1024, -82, -566, +319, 136, 372, 541, 198, 481, -102, 215, +-351, -17, -212, -154, 220, -84, 519, 99, +211, 107, -503, -256, -806, -613, -295, -382, +551, 382, 966, 900, 483, 627, -384, -156, +-841, -678, -569, -556, 91, -73, 521, 267, +501, 213, 274, 8, -124, -37, -528, 66, +-625, 85, -133, 5, 652, 31, 840, 142, +117, 9, -720, -387, -769, -513, -6, -44, +640, 557, 535, 578, -60, 55, -467, -398, +-360, -381, 65, -67, 336, 224, 289, 316, +19, 154, -282, -183, -359, -432, -179, -342, +188, 17, 465, 355, 402, 467, -15, 307, +-406, -13, -471, -295, -185, -311, 163, -135, +313, -89, 230, -225, 41, -206, -96, 212, +-77, 691, 37, 686, 30, 125, -90, -538, +-221, -799, -148, -479, 91, 132, 266, 548, +269, 430, 96, -30, -223, -335, -405, -225, +-265, 90, 192, 307, 584, 301, 396, 91, +-215, -251, -658, -490, -512, -351, 67, 33, +546, 346, 535, 406, 193, 291, -257, 28, +-458, -393, -316, -627, 37, -239, 310, 490, +290, 724, 23, 166, -158, -454, -157, -390, +-18, 42, 92, 113, 42, -195, -38, -296, +-107, 125, -64, 545, 129, 498, 307, 25, +202, -400, -132, -481, -470, -237, -417, 53, +-50, 178, 318, 118, 483, 117, 420, 227, +90, 211, -379, -99, -669, -464, -435, -416, +163, 34, 568, 393, 459, 372, 89, 118, +-183, -57, -257, -166, -269, -333, -172, -406, +12, -144, 218, 359, 262, 682, 205, 480, +28, -43, -164, -512, -263, -637, -149, -385, +62, 26, 143, 401, 6, 524, -76, 338, +23, -25, 96, -293, 43, -292, 8, -56, +121, 88, 186, 9, -71, -210, -447, -256, +-528, 26, -147, 394, 402, 548, 708, 303, +557, -172, 7, -543, -611, -597, -819, -264, +-404, 231, 351, 597, 819, 547, 557, 75, +-193, -494, -750, -640, -575, -234, 177, 390, +715, 679, 490, 393, -203, -186, -637, -651, +-371, -607, 226, -68, 591, 548, 389, 636, +-226, 58, -681, -520, -551, -368, 120, 282, +709, 521, 619, -37, 49, -631, -381, -454, +-410, 265, -204, 697, -59, 460, 74, -91, +248, -507, 231, -646, -16, -426, -263, 141, +-234, 732, 80, 856, 345, 345, 372, -412, +61, -798, -407, -622, -663, -87, -388, 345, +241, 431, 725, 248, 584, 42, 6, -25, +-530, -32, -555, -62, -123, -116, 387, -167, +460, -192, 50, -73, -398, 207, -367, 450, +37, 293, 349, -215, 184, -569, -158, -386, +-222, 153, 41, 540, 303, 479, 217, 40, +-157, -456, -383, -564, -274, -128, 75, 457, +230, 495, 67, -90, -62, -602, 64, -341, +273, 373, 203, 714, -211, 322, -455, -350, +-261, -649, 110, -364, 277, 179, 127, 457, +-83, 189, -55, -310, 63, -404, 160, 147, +51, 728, -138, 562, -242, -302, -127, -931, +61, -683, 173, 149, 98, 653, -31, 498, +-70, 62, 14, -101, 77, -32, 5, -109, +-142, -422, -197, -495, -35, -6, 206, 682, +272, 833, 81, 250, -152, -464, -218, -720, +-143, -532, -102, -232, -107, 113, 23, 572, +357, 896, 562, 619, 232, -227, -444, -991, +-836, -1007, -456, -246, 327, 630, 700, 929, +312, 462, -283, -274, -408, -592, 8, -309, +355, 124, 217, 181, -169, -68, -367, -164, +-247, 106, -20, 451, 131, 456, 266, 27, +310, -561, 120, -869, -222, -587, -401, 209, +-223, 930, 80, 1012, 200, 353, 142, -461, +111, -820, 47, -562, -146, -57, -367, 256, +-240, 219, 205, 91, 495, 129, 270, 294, +-236, 269, -482, -108, -263, -514, 131, -554, +321, -167, 192, 317, -57, 523, -179, 407, +-120, 85, 51, -197, 106, -334, 19, -362, +-137, -351, -220, -176, -119, 270, 227, 808, +492, 852, 364, 156, -218, -798, -737, -1173, +-654, -642, -13, 279, 587, 885, 663, 838, +316, 295, -121, -294, -434, -580, -490, -459, +-264, -130, 92, 130, 309, 198, 215, 127, +-11, -4, -24, 8, 110, 233, 147, 448, +-101, 200, -425, -568, -469, -1125, -79, -708, +438, 498, 646, 1385, 326, 1121, -256, 15, +-643, -952, -520, -1143, -32, -592, 446, 192, +499, 755, 98, 796, -290, 354, -287, -171, +7, -450, 174, -449, -17, -356, -196, -167, +-75, 208, 87, 610, 51, 621, -92, 108, +-4, -516, 293, -661, 327, -266, -93, 213, +-598, 347, -674, 167, -119, 34, 615, 92, +884, 130, 373, -65, -514, -398, -897, -464, +-425, -112, 349, 392, 627, 619, 202, 413, +-316, -82, -372, -539, -3, -679, 310, -301, +208, 371, -198, 761, -403, 462, -168, -257, +302, -624, 425, -323, 71, 241, -332, 452, +-367, 163, -122, -287, 91, -487, 191, -259, +254, 282, 231, 712, -54, 575, -416, -109, +-479, -778, -111, -805, 284, -215, 407, 469, +221, 759, -45, 514, -187, -75, -233, -587, +-210, -597, -99, -37, 33, 559, 133, 516, +192, -134, 158, -628, 82, -376, -86, 291, +-290, 560, -356, 189, -153, -312, 195, -359, +384, -12, 217, 283, -63, 256, -170, 5, +-147, -268, -136, -389, -109, -233, 28, 185, +181, 564, 116, 490, -103, -30, -152, -528, +38, -552, 148, -159, -15, 274, -188, 434, +-121, 306, 117, 4, 186, -267, -44, -304, +-331, -81, -299, 142, 112, 83, 538, -123, +474, -149, -112, 133, -658, 406, -585, 349, +-49, -51, 355, -465, 357, -562, 185, -286, +87, 175, -17, 500, -267, 519, -439, 255, +-286, -121, 79, -419, 340, -485, 321, -255, +115, 127, -70, 384, -202, 354, -227, 170, +-164, -12, -68, -180, 27, -380, 80, -449, +106, -151, 208, 409, 244, 765, 61, 528, +-328, -151, -625, -731, -467, -762, 124, -276, +624, 331, 633, 623, 202, 506, -314, 200, +-588, -95, -467, -335, -69, -513, 297, -464, +357, -87, 114, 419, -110, 651, -139, 457, +-57, 10, 3, -372, 25, -550, 9, -477, +-86, -124, -214, 350, -126, 636, 155, 472, +295, 4, 112, -403, -173, -446, -248, -216, +-99, 41, 45, 133, 85, 104, 55, 82, +-15, 133, -99, 196, -112, 136, 32, -95, +115, -369, -9, -452, -159, -186, -124, 283, +85, 615, 245, 477, 109, -43, -184, -559, +-351, -640, -253, -227, 58, 363, 321, 633, +330, 354, 107, -171, -203, -416, -400, -192, +-372, 116, -40, 101, 381, -167, 543, -244, +191, 20, -387, 338, -685, 376, -404, 137, +172, -145, 597, -311, 512, -298, 55, -93, +-409, 178, -491, 258, -158, 57, 169, -201, +113, -170, -114, 109, -160, 319, 87, 206, +372, -96, 354, -282, 21, -222, -392, -52, +-605, 52, -402, 66, 109, 68, 509, 90, +432, 101, 39, 69, -246, 14, -221, -86, +-16, -189, 88, -192, -5, -18, -187, 186, +-289, 204, -118, 18, 247, -105, 447, -20, +232, 81, -204, -19, -411, -200, -259, -153, +-5, 89, 128, 260, 125, 192, 76, 38, +26, -108, -34, -264, -67, -344, -109, -131, +-109, 347, -54, 601, 28, 272, 64, -375, +25, -638, -15, -246, 81, 354, 115, 500, +-40, 137, -238, -289, -303, -328, -153, -62, +99, 164, 244, 169, 292, 49, 190, -22, +-84, -36, -360, -52, -415, -81, -143, -52, +243, 45, 386, 139, 124, 126, -309, -37, +-422, -225, -30, -214, 436, 67, 415, 313, +-72, 232, -486, -97, -386, -267, -2, -96, +213, 116, 105, 98, 7, -88, 37, -160, +90, -81, 21, 68, -126, 248, -201, 391, +-85, 240, 58, -296, 86, -774, -42, -605, +-143, 167, -82, 776, 101, 680, 215, 117, +141, -278, -33, -334, -209, -286, -357, -302, +-296, -199, 51, 156, 408, 521, 434, 517, +38, 91, -372, -357, -361, -447, -46, -143, +172, 180, 118, 212, -90, -29, -178, -237, +-75, -177, 146, 114, 306, 366, 207, 332, +-161, 48, -492, -259, -453, -341, -25, -215, +428, -57, 487, 21, 120, 66, -256, 173, +-310, 300, -86, 334, 61, 164, -76, -190, +-246, -578, -56, -677, 322, -300, 464, 363, +143, 818, -328, 716, -503, 174, -314, -431, +-43, -753, 188, -622, 364, -75, 424, 513, +202, 670, -272, 256, -624, -233, -557, -329, +-105, -123, 373, -18, 559, -96, 385, -12, +37, 245, -281, 317, -399, 9, -331, -299, +-162, -280, 34, -48, 230, 79, 343, 105, +263, 182, -5, 230, -276, 76, -359, -214, +-179, -348, 70, -219, 188, 29, 150, 230, +37, 291, -99, 173, -170, -68, -134, -213, +-1, -170, 138, -63, 169, -38, 63, 32, +-46, 242, -125, 355, -219, 63, -248, -426, +-66, -540, 226, -104, 381, 413, 174, 476, +-180, 131, -264, -195, -93, -202, 4, -31, +-102, 19, -179, -135, 47, -246, 364, -37, +365, 341, 12, 454, -410, 94, -515, -330, +-234, -378, 219, -73, 495, 156, 401, 145, +-41, 54, -402, 4, -398, -49, -112, -120, +134, -98, 187, 35, 111, 177, 21, 224, +-59, 136, -122, -131, -88, -453, 24, -443, +98, 72, 71, 667, -9, 646, -126, -52, +-219, -735, -168, -687, 100, 5, 347, 655, +261, 678, -136, 116, -373, -480, -133, -607, +247, -231, 202, 210, -226, 364, -460, 280, +-125, 144, 411, -50, 508, -309, 112, -398, +-304, -119, -362, 283, -154, 341, -39, 74, +-10, -141, 117, -64, 282, 76, 254, 48, +-39, -135, -397, -269, -429, -233, -101, 34, +322, 400, 499, 550, 240, 258, -270, -286, +-511, -595, -269, -467, 193, -91, 337, 249, +88, 427, -162, 377, -67, 103, 130, -202, +98, -294, -159, -157, -268, -40, -80, -31, +220, -11, 300, 119, 75, 221, -243, 174, +-341, -2, -103, -203, 200, -305, 220, -205, +19, 97, -92, 360, 32, 313, 126, 12, +-52, -248, -301, -282, -252, -181, 32, -61, +259, 85, 240, 270, 130, 350, 11, 211, +-131, -156, -313, -506, -292, -548, 28, -115, +402, 510, 400, 728, 10, 283, -427, -381, +-417, -629, 47, -329, 451, 114, 339, 320, +-130, 273, -399, 58, -149, -152, 256, -176, +278, 28, -104, 169, -395, -14, -202, -296, +295, -228, 508, 174, 166, 387, -382, 120, +-529, -278, -140, -318, 337, 3, 398, 298, +69, 295, -195, 15, -159, -300, 12, -417, +46, -198, -102, 162, -146, 351, 39, 277, +271, 95, 327, -27, 84, -170, -262, -348, +-357, -371, -136, -93, 139, 318, 191, 508, +86, 280, 76, -142, 126, -438, 30, -404, +-204, -93, -251, 261, 11, 448, 260, 290, +165, -143, -127, -535, -242, -491, -55, 53, +154, 571, 187, 470, 108, -106, 38, -457, +-46, -215, -200, 136, -298, 45, -138, -224, +208, -105, 431, 356, 322, 471, -34, 2, +-308, -475, -287, -427, -84, -67, 95, 99, +178, 37, 213, 100, 171, 353, 8, 391, +-182, -22, -225, -582, -4, -700, 226, -219, +239, 410, 41, 619, -172, 255, -209, -242, +-27, -388, 185, -134, 273, 185, 158, 209, +-90, -72, -270, -360, -230, -342, 12, 24, +248, 427, 263, 471, 69, 138, -124, -290, +-123, -486, 11, -415, 88, -165, -7, 213, +-110, 528, -30, 476, 175, 3, 278, -485, +159, -517, -72, -140, -219, 185, -181, 199, +-32, 39, 158, -44, 245, -5, 178, 83, +66, 105, 38, -46, 31, -275, -35, -344, +-175, -89, -266, 241, -149, 281, 159, 54, +486, -86, 584, -28, 317, -10, -256, -174, +-755, -299, -741, -164, -124, 98, 650, 262, +916, 244, 476, 101, -203, -127, -526, -343, +-365, -333, -50, -65, 96, 212, 108, 215, +159, -12, 250, -181, 250, -101, 125, 108, +-67, 223, -193, 50, -238, -302, -118, -481, +177, -255, 408, 202, 314, 434, 28, 280, +-120, -2, -49, -157, 29, -237, -83, -323, +-125, -295, 104, -3, 384, 334, 298, 343, +-99, -2, -333, -337, -110, -272, 280, 76, +314, 289, -29, 104, -279, -285, -112, -426, +213, -175, 314, 158, 91, 223, -105, 65, +-52, -10, 127, 66, 142, 63, -58, -124, +-184, -332, -31, -355, 258, -186, 413, 63, +287, 311, -5, 397, -240, 234, -253, -109, +-82, -394, 140, -474, 279, -364, 361, -100, +339, 280, 138, 514, -226, 314, -431, -186, +-240, -458, 164, -244, 434, 51, 394, 27, +147, -182, -70, -156, -158, 124, -139, 281, +-26, 110, 120, -203, 176, -380, 144, -298, +84, 13, 45, 363, -17, 437, -46, 27, +67, -549, 264, -746, 257, -329, -32, 334, +-258, 669, -104, 493, 277, 4, 439, -452, +182, -635, -139, -468, -177, -82, 106, 272, +343, 377, 271, 240, -55, 25, -219, -130, +-109, -192, 144, -253, 323, -292, 301, -225, +150, -2, -24, 222, -118, 246, -127, 94, +-24, -56, 109, -132, 195, -220, 194, -313, +135, -233, 80, 72, 36, 292, 18, 164, +-17, -186, -16, -340, -19, -127, 76, 143, +258, 184, 363, 3, 229, -185, -44, -239, +-205, -208, -105, -156, 103, -44, 250, 114, +295, 248, 224, 209, 128, -28, 62, -278, +-15, -371, -101, -283, -147, -160, -12, -40, +324, 163, 592, 383, 460, 344, -65, -74, +-499, -566, -425, -634, 88, -195, 509, 317, +433, 430, 22, 84, -210, -322, -9, -417, +363, -131, 411, 241, -10, 303, -385, 20, +-297, -334, 124, -449, 389, -286, 344, 3, +254, 272, 241, 385, 141, 189, -102, -241, +-263, -566, -147, -456, 156, -14, 340, 293, +344, 242, 276, -12, 183, -155, 22, -134, +-140, -111, -104, -115, 77, -105, 226, -86, +186, -73, 82, -37, 133, 80, 209, 203, +110, 75, -96, -288, -160, -569, 24, -404, +322, 126, 367, 529, 136, 460, -116, 4, +-128, -461, 44, -639, 192, -491, 223, -81, +153, 377, 73, 560, 20, 332, 66, -150, +161, -487, 218, -477, 160, -270, 73, -78, +-6, 0, -32, 65, 52, 200, 264, 352, +452, 339, 315, -58, -124, -707, -423, -1052, +-185, -627, 417, 384, 755, 1117, 416, 909, +-212, -12, -503, -848, -262, -988, 188, -523, +453, 89, 381, 477, 157, 493, 41, 207, +83, -177, 55, -404, -157, -333, -304, -117, +-68, 11, 454, -9, 681, -72, 382, -13, +-122, 79, -286, 69, -74, -45, 163, -197, +141, -269, 49, -249, 131, -96, 350, 186, +424, 386, 189, 224, -109, -292, -248, -727, +-126, -594, 151, 19, 370, 569, 390, 617, +246, 171, 76, -348, -58, -626, -112, -540, +-94, -193, 27, 160, 209, 319, 357, 241, +297, 48, 62, -101, -128, -184, -60, -206, +184, -175, 251, -171, 12, -205, -187, -210, +-30, -5, 358, 382, 518, 573, 268, 242, +-139, -477, -244, -969, -20, -729, 259, 37, +296, 677, 155, 707, 63, 200, 99, -354, +121, -603, 74, -476, 51, -136, 194, 173, +380, 292, 285, 128, -153, -143, -478, -263, +-250, -123, 379, 105, 776, 107, 564, -159, +17, -385, -343, -315, -339, 49, -150, 380, +116, 349, 333, -23, 425, -458, 311, -578, +56, -277, -127, 177, -72, 443, 91, 307, +146, -79, 71, -402, 18, -447, 123, -205, +254, 95, 291, 220, 151, 120, -15, -93, +-69, -190, 53, -115, 212, 21, 235, 40, +122, -125, -5, -284, 24, -237, 162, 29, +249, 284, 152, 216, 5, -106, -58, -346, +64, -268, 193, 7, 164, 120, 57, -24, +7, -172, 55, -133, 156, 55, 207, 118, +144, -22, -25, -170, -158, -191, -82, -85, +179, -6, 398, 10, 352, 36, 101, 24, +-100, -74, -123, -233, -19, -283, 68, -67, +123, 221, 233, 288, 363, 39, 323, -295, +100, -371, -163, -189, -220, 37, -49, 106, +202, 32, 323, -4, 264, 23, 121, -1, +67, -108, 51, -222, 38, -185, 15, -34, +9, 31, 33, -18, 100, -63, 190, 42, +228, 164, 140, 46, -10, -256, -115, -439, +-39, -250, 125, 144, 247, 349, 219, 213, +120, -115, 16, -351, -12, -318, -42, -105, +-15, 131, 101, 207, 272, 66, 385, -106, +288, -172, 40, -115, -245, -81, -351, -135, +-138, -119, 297, 39, 621, 219, 560, 195, +149, -56, -272, -277, -368, -313, -155, -213, +145, -71, 280, 65, 296, 227, 262, 259, +173, 49, 17, -258, -139, -391, -175, -223, +-61, 26, 91, 107, 252, 55, 321, 13, +214, 21, 9, -11, -107, -120, -33, -155, +117, -95, 130, -49, 36, -58, 2, -41, +115, 85, 223, 146, 163, -10, 74, -237, +70, -266, 94, -56, 9, 121, -116, 79, +-46, -45, 208, -93, 389, -81, 316, -79, +65, -59, -105, 53, -115, 121, -105, -20, +-59, -287, 81, -384, 327, -104, 489, 325, +308, 505, -120, 222, -449, -336, -383, -705, +11, -558, 430, 10, 573, 562, 345, 616, +-60, 154, -286, -381, -186, -535, 70, -238, +184, 89, 67, 103, -21, -100, 100, -154, +322, 99, 347, 340, 63, 227, -214, -155, +-226, -448, 15, -400, 246, -112, 298, 151, +176, 268, 25, 175, -65, -49, -19, -235, +91, -199, 160, 53, 137, 185, 58, -1, +-9, -295, -44, -353, -33, -57, 31, 275, +136, 318, 232, 94, 210, -172, 59, -255, +-58, -197, -43, -111, 38, -17, 35, 63, +-63, 116, -67, 67, 108, -64, 325, -141, +369, -89, 193, 29, -46, 89, -220, -6, +-273, -171, -188, -275, 73, -205, 444, 84, +642, 385, 432, 427, -90, 69, -507, -438, +-515, -660, -162, -431, 293, 78, 580, 498, +512, 575, 158, 271, -198, -258, -344, -628, +-175, -544, 114, -88, 256, 342, 183, 379, +45, 119, 10, -101, 48, -133, 86, -92, +57, -133, 8, -194, 15, -113, 45, 75, +16, 199, -50, 135, -7, -39, 192, -126, +373, -101, 273, -76, -70, -109, -343, -128, +-228, -4, 116, 156, 339, 176, 262, 11, +56, -187, -52, -206, -22, -72, 25, 56, +43, 71, 95, -2, 152, -68, 87, -93, +-104, -92, -172, -26, 45, 80, 382, 148, +442, 44, 79, -175, -347, -262, -453, -110, +-159, 102, 263, 109, 478, -72, 382, -134, +107, 38, -169, 203, -282, 122, -182, -148, +72, -314, 237, -255, 243, -80, 153, 112, +41, 231, -9, 243, 14, 100, 20, -143, +-50, -306, -141, -308, -101, -172, 168, 23, +463, 219, 471, 330, 43, 218, -419, -96, +-460, -372, -61, -394, 405, -136, 497, 163, +162, 265, -222, 142, -291, -70, -37, -157, +276, -83, 335, 15, 83, -6, -276, -145, +-325, -196, 7, 3, 409, 258, 503, 274, +122, -55, -334, -399, -386, -350, 8, 55, +381, 383, 338, 248, -50, -176, -289, -396, +-159, -215, 181, 136, 330, 284, 196, 143, +-19, -81, -136, -204, -80, -192, 54, -95, +112, 21, 117, 121, 63, 118, -3, 26, +-10, -79, 47, -114, 87, -45, 51, 12, +-23, -13, -60, -76, -53, -103, 65, -39, +163, 56, 180, 121, 134, 138, -8, 60, +-176, -126, -168, -317, 21, -316, 245, -31, +244, 263, 35, 285, -168, 66, -123, -109, +115, -69, 178, -6, 10, -106, -99, -245, +-17, -204, 175, 35, 232, 222, 50, 218, +-131, 126, -101, 28, 71, -90, 154, -265, +46, -376, -65, -224, -89, 113, 57, 366, +194, 328, 157, 74, 8, -136, -109, -198, +-111, -197, 21, -198, 119, -161, 120, 7, +71, 211, 50, 296, 64, 222, 3, 20, +-106, -187, -183, -343, -86, -380, 164, -196, +306, 144, 228, 429, 37, 425, -139, 98, +-178, -274, -121, -405, -33, -260, 128, -25, +286, 94, 314, 134, 90, 150, -195, 113, +-300, -27, -192, -169, 49, -145, 249, 2, +238, 50, 120, -66, -24, -163, -90, -38, +-12, 206, 74, 252, 28, 21, -131, -261, +-124, -290, 96, -47, 310, 184, 276, 186, +-40, -24, -348, -193, -292, -123, 14, 65, +274, 155, 313, 54, 134, -107, -102, -154, +-223, -99, -113, 4, 110, 112, 263, 165, +193, 95, -88, -122, -300, -298, -195, -227, +86, 46, 299, 292, 300, 271, 112, 43, +-124, -175, -294, -271, -290, -203, -47, -43, +324, 131, 482, 231, 235, 140, -178, -55, +-379, -171, -216, -117, 108, 23, 244, 55, +85, -12, -121, -80, -156, -85, 39, -20, +295, 73, 331, 162, 20, 156, -379, -30, +-473, -251, -151, -269, 347, -36, 587, 203, +344, 158, -121, -51, -403, -131, -380, 16, +-134, 184, 152, 113, 295, -113, 228, -247, +73, -187, -60, -20, -87, 92, -10, 144, +-2, 178, -111, 138, -135, -13, 22, -206, +217, -272, 285, -116, 145, 88, -114, 164, +-333, 74, -331, -34, -115, -12, 238, 64, +500, 82, 372, -2, -91, -129, -466, -191, +-421, -154, -8, -12, 375, 196, 370, 300, +43, 198, -261, -90, -267, -325, -26, -291, +196, -22, 189, 239, -33, 261, -189, 45, +-113, -180, 103, -211, 239, -26, 135, 187, +-123, 205, -257, -10, -169, -259, 77, -236, +260, 85, 268, 352, 56, 260, -246, -130, +-390, -401, -248, -281, 107, 81, 421, 355, +384, 338, 72, 77, -233, -231, -349, -378, +-232, -210, 13, 122, 227, 301, 268, 189, +123, -63, -89, -149, -221, -29, -136, 76, +46, 46, 75, -59, -33, -112, -89, -72, +-7, 24, 169, 161, 235, 228, 73, 92, +-222, -176, -366, -331, -205, -152, 136, 197, +386, 360, 286, 174, -83, -167, -324, -314, +-247, -161, -5, 108, 162, 256, 120, 185, +5, 20, -38, -121, 2, -187, 9, -119, +-26, 46, -11, 168, -11, 137, -44, -23, +-52, -105, -45, -33, 20, 89, 89, 97, +64, -33, -1, -109, -54, -59, -105, 37, +-145, 87, -75, 45, 144, 4, 290, -5, +175, -4, -159, 13, -388, 38, -248, 56, +87, 30, 237, -90, 175, -170, 25, -108, +-56, 121, -97, 326, -158, 248, -177, -30, +-12, -244, 211, -235, 228, -83, 26, 30, +-149, 115, -158, 201, -51, 219, 26, 88, +-43, -145, -97, -252, 23, -140, 153, 44, +134, 160, -16, 146, -178, 78, -182, 34, +-34, -8, 59, -98, 37, -175, 33, -92, +79, 132, 80, 274, -16, 209, -201, -27, +-271, -198, -102, -156, 142, -40, 234, 6, +138, 33, -50, 152, -182, 295, -181, 198, +-69, -129, 28, -373, 87, -293, 109, 70, +53, 328, -55, 263, -163, 32, -142, -138, +13, -82, 116, 69, 69, 113, -76, 3, +-185, -142, -113, -146, 99, -12, 227, 163, +155, 285, -101, 199, -329, -47, -302, -227, +-38, -218, 242, -60, 316, 128, 152, 240, +-139, 200, -338, -3, -311, -166, -113, -170, +127, -9, 294, 172, 242, 220, 19, 108, +-224, -79, -368, -195, -259, -140, 57, 15, +326, 168, 297, 234, 7, 166, -289, 0, +-362, -172, -143, -218, 166, -83, 256, 125, +120, 254, -126, 168, -257, -41, -124, -140, +81, -55, 133, 91, 51, 116, -97, 13, +-185, -75, -138, -86, 33, 36, 159, 189, +121, 190, -53, 30, -254, -154, -242, -193, +10, -34, 196, 176, 98, 235, -88, 82, +-137, -81, -40, -56, 54, 43, -5, 19, +-155, -99, -166, -81, 12, 142, 160, 312, +94, 186, -99, -124, -210, -264, -161, -168, +16, 32, 158, 192, 107, 280, -47, 229, +-197, -19, -238, -276, -85, -264, 156, 15, +243, 264, 78, 241, -188, 30, -321, -104, +-243, -43, 7, 64, 240, 110, 225, 34, +9, -91, -240, -119, -343, 5, -133, 195, +170, 241, 230, 58, 31, -120, -207, -143, +-251, -9, -97, 131, 91, 97, 165, -2, +20, -18, -203, 56, -275, 86, -110, -7, +135, -31, 190, 60, 63, 150, -128, 104, +-259, -102, -190, -210, -35, -59, 114, 209, +164, 296, -7, 137, -254, -92, -231, -182, +16, -36, 138, 99, 54, 79, -122, 17, +-205, 27, -124, 91, 23, 88, 63, 10, +14, -41, -79, -16, -126, 75, -89, 67, +-6, -21, 14, 8, -84, 79, -154, 70, +-105, 1, 1, -12, 69, 64, 59, 95, +-98, 29, -219, -67, -149, -23, -32, 113, +38, 135, 56, 1, 47, -79, -29, 2, +-165, 86, -285, 127, -251, 66, -11, -56, +264, -64, 284, 21, 53, 160, -259, 176, +-499, -10, -453, -185, -42, -131, 382, 109, +435, 276, 124, 246, -274, 101, -450, -144, +-325, -306, -142, -200, 3, 77, 109, 309, +180, 336, 129, 219, -24, 33, -194, -169, +-335, -298, -367, -267, -216, 10, 81, 340, +384, 455, 391, 247, -38, -96, -511, -265, +-601, -195, -276, 4, 194, 140, 407, 150, +206, 94, -177, 46, -405, 38, -306, 84, +6, 106, 164, 10, 2, -137, -211, -202, +-225, -52, -57, 277, 120, 481, 120, 278, +-75, -222, -296, -506, -359, -271, -215, 230, +93, 484, 295, 349, 149, 54, -181, -218, +-381, -310, -353, -129, -132, 167, 153, 316, +217, 244, -7, 13, -253, -175, -307, -128, +-193, 108, 57, 256, 140, 152, -36, -88, +-178, -258, -243, -150, -219, 174, -13, 382, +103, 322, -6, 78, -79, -177, -99, -295, +-175, -182, -203, 50, -152, 238, -120, 316, +-34, 253, 70, 38, 9, -221, -82, -220, +-116, 19, -167, 239, -228, 245, -203, -22, +-96, -233, -12, -97, 92, 212, 76, 312, +-158, 148, -291, -55, -147, -139, -42, -46, +-66, 114, -168, 121, -237, -3, -71, -107, +125, -86, 38, 128, -161, 350, -190, 370, +-124, 127, -75, -213, -135, -444, -198, -392, +-172, 21, -43, 426, 38, 561, 10, 428, +-20, 98, -121, -259, -291, -477, -339, -349, +-176, -24, 86, 254, 196, 446, -7, 414, +-299, 173, -352, -95, -185, -249, -35, -245, +79, -109, 65, 75, -59, 228, -199, 305, +-367, 247, -399, 46, -154, -170, 175, -212, +230, -80, 23, 129, -150, 285, -286, 234, +-331, 41, -231, -79, -163, -126, -74, -90, +27, 43, 59, 147, 15, 196, -61, 169, +-166, 143, -282, 40, -306, -137, -246, -190, +-171, -156, -31, -14, 162, 226, 274, 493, +0, 477, -429, -17, -566, -483, -384, -485, +-1, -57, 249, 404, 98, 462, -106, 180, +-179, -122, -253, -162, -232, 57, -143, 177, +-106, 53, -125, -98, -70, -133, -61, 19, +-61, 234, -37, 325, -105, 198, -292, -105, +-282, -263, -149, -135, -97, 101, 17, 263, +38, 230, -85, 66, -157, -24, -223, -61, +-288, -55, -178, -11, -37, 22, 27, 211, +-90, 314, -193, 104, -163, -189, -69, -237, +-54, 31, -222, 202, -296, 130, -113, 79, +45, 192, -43, 211, -209, -156, -246, -464, +-125, -136, 37, 519, 2, 597, -194, 19, +-334, -376, -360, -220, -120, 79, 230, 181, +207, 179, -178, 192, -502, 73, -430, -138, +-21, -157, 211, 58, 27, 239, -295, 110, +-334, -77, -163, 38, 18, 203, 91, 114, +-64, -121, -275, -158, -315, 73, -215, 298, +-140, 173, -90, -141, 0, -180, 45, 52, +-45, 350, -118, 335, -250, -55, -355, -332, +-311, -195, -196, 184, -27, 220, 197, 75, +185, 165, -83, 158, -341, -34, -456, -69, +-374, 62, -98, 14, 110, -216, 51, -93, +-40, 344, -152, 470, -191, 160, -113, -238, +-125, -287, -291, 28, -268, 221, -127, 102, +49, -59, 196, 20, 22, 204, -397, 229, +-546, -49, -264, -255, 91, -4, 218, 320, +26, 240, -199, -155, -239, -228, -206, 139, +-289, 316, -371, 60, -160, -252, 215, -73, +351, 316, 101, 315, -366, 60, -630, -137, +-472, -204, -109, -164, 114, 7, 109, 302, +70, 416, 52, 230, -136, -10, -363, -190, +-406, -311, -242, -222, -53, 148, -40, 451, +-48, 270, 54, -68, 89, -29, -67, 208, +-275, 25, -419, -364, -324, -190, -235, 326, +-59, 307, 337, -97, 369, 13, -199, 382, +-639, 152, -446, -395, -34, -308, 53, 304, +-72, 342, -112, -184, -11, -230, 90, 357, +-164, 581, -425, -60, -248, -610, 28, -171, +-91, 463, -225, 252, -53, -234, 23, -65, +-8, 376, 54, 266, -191, -138, -523, -228, +-375, -99, -36, 97, 89, 253, 197, 222, +140, -19, -244, -187, -367, 16, -278, 238, +-267, 30, -44, -174, 99, 121, -98, 345, +-103, -40, 80, -315, -33, 70, -282, 342, +-355, 2, -310, -236, -90, 115, 166, 367, +140, 38, -112, -187, -244, -71, -153, 96, +-127, 129, -253, 39, -269, 66, -108, -4, +207, -84, 194, 154, -226, 298, -298, 64, +-180, -203, -180, -92, -171, 57, -129, -126, +50, -33, 186, 467, -116, 486, -270, -67, +-164, -397, -181, -196, -174, 86, -123, 1, +7, -28, 105, 394, -120, 470, -208, -28, +-64, -339, -240, -229, -177, 25, -6, 64, +-112, 149, -81, 375, 2, 118, -60, -208, +-153, -186, -203, 24, -133, 226, -48, 82, +-88, 1, -198, 77, -117, 19, 171, -16, +86, -67, -340, 0, -425, 154, -89, 207, +102, 91, -14, -131, -91, -142, -17, 121, +2, 285, -219, -30, -359, -328, -213, -77, +-20, 289, 170, 411, 111, 192, -111, -92, +-260, -233, -336, -366, -144, -118, 94, 348, +49, 430, -161, 209, -323, -87, -100, -180, +224, -99, 176, 49, -75, 142, -551, -23, +-691, -124, -30, 24, 501, 264, 335, 279, +14, 53, -342, -111, -555, -168, -353, -135, +16, -48, 248, 205, 190, 380, -172, 95, +-429, -176, -128, -139, 253, 47, 94, 131, +-303, 42, -380, 92, -187, 23, 16, -164, +77, -39, 57, 194, 53, 252, -159, 33, +-388, -175, -165, -42, 79, 63, 3, 75, +-157, 108, -163, 14, 61, -64, -74, 30, +-316, 87, -22, -31, 185, -7, 50, 243, +-290, 195, -429, -200, -16, -272, 126, 6, +-113, 122, -64, 244, -21, 276, -59, 13, +-29, -221, -258, -262, -193, -48, 175, 320, +-41, 368, -285, 5, -147, -286, -172, -153, +-2, 74, 283, 139, 152, 265, -277, 183, +-490, -162, -279, -299, -47, -105, 138, 273, +218, 335, 25, 27, -152, -86, -326, -95, +-453, -146, 7, 9, 359, 292, 21, 285, +-179, -84, -161, -227, -401, -13, -179, -27, +292, -16, 211, 356, -107, 321, -341, -267, +-377, -402, -96, 97, 309, 364, 189, 160, +-282, -119, -253, -127, -162, 10, -278, -22, +96, 4, 310, 262, -56, 325, -212, -88, +-131, -375, -201, -165, -236, 66, 28, 294, +59, 325, -38, -12, 32, -238, -175, -153, +-224, 111, 101, 145, -53, 62, -221, 140, +-41, 5, -146, -182, -199, -216, 41, -18, +170, 350, 20, 391, -207, 38, -215, -264, +-71, -162, -97, -56, -106, -88, -68, 175, +-12, 249, 86, 94, -129, -89, -155, -104, +7, 186, -125, 105, -37, -33, -81, -103, +-179, -174, -26, -15, -215, -82, -89, 223, +293, 563, -22, 163, -135, -184, -88, -381, +-286, -274, -163, 30, -148, 142, -51, 280, +219, 165, 14, -31, 13, 7, 13, 72, +-500, 78, -278, -95, 108, -251, 29, -164, +102, 63, -134, 255, -209, 348, -2, 96, +-43, -205, -109, 32, -42, 101, 33, -173, +-56, -197, -288, -86, -218, 154, -131, 106, +174, 164, 442, 561, -141, 98, -440, -650, +-238, -554, -279, 133, 61, 516, 439, 157, +-2, 3, -309, 82, -224, -179, -136, -181, +-81, 117, -51, 174, 269, 74, 183, 24, +-427, -146, -444, -169, -42, 109, 113, 174, +184, 111, -103, 44, -296, -93, 17, -85, +2, 62, -114, 235, 50, -61, -10, -276, +-399, 83, -372, 45, 209, -37, 401, 243, +-68, 245, -192, 21, -234, -204, -265, -213, +38, -88, 78, 71, -143, 169, -88, 65, +92, 164, -124, 237, -158, -130, 153, -285, +-194, -91, -427, -33, 295, 82, 169, 387, +-454, 188, 59, -292, 23, -238, -425, 108, +131, 211, 176, -45, -110, -130, 56, 165, +-266, 204, -299, -96, 1, -338, -53, -11, +16, 422, 107, 107, 34, -155, -194, -1, +-280, -18, 20, -162, 35, 75, -179, 302, +-6, -24, -85, -152, -119, 0, 309, -45, +-90, 93, -503, 187, -63, 8, -14, -152, +79, -55, 295, 112, -169, 67, -330, -35, +-113, -14, -220, 138, -72, 94, 139, -252, +88, -72, 86, 318, 40, 103, -336, -152, +-344, -43, -4, 17, 8, -81, -121, 1, +-87, 248, 172, 147, 301, -141, -22, -111, +-435, -75, -426, -59, -49, 280, 117, 302, +-46, -221, 144, -288, 101, 60, -171, 81, +53, 5, -234, 189, -397, 214, 132, -83, +27, -320, -272, -115, 168, 180, 260, 148, +-178, 143, -96, 11, -135, -313, -491, -72, +118, 290, 404, 257, -301, 89, -163, -300, +131, -437, -117, 2, -10, 325, 159, 471, +-303, 288, -474, -399, 102, -632, 206, -30, +68, 521, 210, 272, -157, -189, -566, -1, +-251, 78, 202, -284, 181, -75, 67, 319, +80, 149, -246, -103, -357, -139, 74, 63, +-40, 160, -132, -224, 329, -53, -108, 335, +-463, -51, 265, -154, 62, 133, -311, -7, +170, -56, -180, 167, -318, 173, 206, -283, +47, -251, -27, 226, -49, 30, -141, -9, +49, 389, -160, 137, -178, -387, 41, -253, +-116, 266, 96, 60, 247, -386, -188, 101, +-281, 547, 11, 52, 34, -187, -220, 126, +-115, -163, 195, -462, 155, 72, -116, 383, +-213, 84, -40, -30, -127, 237, -65, 65, +318, -406, -69, -238, -470, 128, 104, 261, +228, 127, -214, -187, 17, 45, 103, 217, +-299, -197, -71, -111, 49, 279, -197, -43, +228, -349, 252, 93, -339, 326, -295, 53, +95, -69, 51, -74, -87, -101, 55, -97, +50, 72, -36, 299, -241, 146, -261, -143, +264, -223, 211, -122, -156, 79, -102, 122, +-193, 107, -92, 200, 77, 27, -4, -330, +178, -235, 141, 305, -182, 283, -377, -334, +-345, -219, 154, 366, 484, 263, 108, -176, +-130, -152, -95, 91, -485, -12, -154, -148, +436, -77, -44, 12, -108, 236, 247, 329, +-191, 149, -215, -170, 232, -489, -117, -387, +-333, 86, 132, 430, 92, 400, -161, 249, +295, -18, 211, -481, -422, -354, -305, -88, +46, -135, -47, 338, -15, 736, 389, 185, +224, -462, -398, -429, -215, -9, 155, 162, +-326, -12, -132, -127, 472, 229, -69, 195, +-151, -126, 251, 134, -139, 115, -141, -251, +43, -345, -210, -152, -98, 265, -8, 380, +153, 232, 401, -134, -9, -264, -399, -45, +-225, -253, 2, -35, -29, 631, 130, 207, +299, -617, 6, -363, -279, 528, -208, 305, +-49, -390, 179, 4, 218, 437, -165, -193, +-170, -792, 149, 52, -27, 975, -136, 197, +143, -674, -121, -170, -193, 428, 173, -195, +78, -489, 92, 505, 96, 536, -368, -370, +-177, -504, 212, 105, -55, 419, 52, -54, +259, -272, -170, 128, -226, 215, 18, -118, +103, -281, 171, 147, -213, 205, -257, -232, +377, -169, 76, 330, -373, 419, 16, -415, +209, -632, -92, 489, -143, 492, 402, -692, +156, -303, -629, 1019, -175, 208, 424, -1151, +-153, 36, -198, 927, 595, -399, 219, -776, +-571, 699, -172, 743, -43, -855, 16, -563, +327, 800, 8, 215, 26, -510, 4, 19, +-363, 288, -41, -189, 261, -371, 207, 177, +111, 554, -356, 77, -453, -529, 299, -350, +371, 389, -158, 246, 79, -417, 116, -40, +-270, 549, -130, -6, 101, -614, 122, 23, +-30, 534, -50, -206, 153, -546, 87, 252, +-301, 597, -58, -167, 497, -548, -85, 113, +-551, 431, 197, -202, 318, -552, -186, 199, +-19, 642, 240, -160, 23, -344, -239, 251, +-134, -29, 67, -546, 246, -209, 64, 640, +-196, 492, 87, -350, 83, -156, -288, 143, +-44, -475, 370, -440, 249, 492, -249, 531, +-328, -142, 190, 46, 142, -22, -147, -701, +91, -37, 27, 712, -11, -212, 135, -540, +-27, 676, 74, 504, 33, -911, -396, -505, +-148, 658, 408, 351, 227, -385, -73, -214, +22, 330, -27, 27, -160, -430, 35, 116, +189, 480, -37, -205, -342, -664, 132, 88, +579, 801, -207, 15, -372, -713, 479, -80, +168, 391, -598, -100, -7, -219, 375, 254, +-192, 125, 188, -397, 505, -55, -423, 475, +-409, -132, 441, -643, 141, 409, -391, 599, +148, -892, 627, -460, -207, 1085, -721, 279, +248, -897, 575, -221, -157, 697, -190, 164, +102, -859, 138, -366, 194, 813, -251, 659, +-248, -521, 427, -911, -8, 269, -303, 926, +317, -342, 178, -894, 20, 352, 84, 689, +-286, -438, -109, -554, 179, 457, -55, 470, +151, -346, 442, -329, -90, 92, -376, -149, +240, -143, 182, 319, -348, 188, -37, -219, +350, -133, 178, 254, -117, 26, -77, -620, +216, -189, 133, 532, -146, 262, -287, -243, +71, -214, 567, 238, -70, 61, -412, -469, +507, -65, 170, 257, -613, -23, 211, -63, +439, 133, -301, 60, 85, -157, 468, -185, +-348, 11, -380, 5, 364, -289, 348, 154, +42, 784, 1, -335, -104, -962, -55, 427, +56, 503, 32, -613, 45, -205, 211, 760, +213, 66, -91, -848, -260, -105, 96, 529, +453, 40, 48, -98, -293, 52, 44, -187, +138, -363, -120, -102, 64, 269, 483, 295, +299, 120, -308, -25, -374, -329, 162, -459, +221, -103, -162, 250, 359, 320, 529, 74, +-554, -217, -351, -9, 705, 37, 265, -222, +-472, -191, -55, -10, 509, 186, 22, 99, +-464, -172, 154, -103, 776, 91, 162, 160, +-651, 14, -243, -379, 461, -242, 248, 178, +-108, 102, 106, 31, 299, 174, 111, -215, +-193, -380, -281, 210, 150, 241, 491, -346, +-11, -124, -198, 394, 330, -169, 406, -454, +-334, 387, -413, 294, 457, -695, 408, -183, +-274, 825, -147, 6, 318, -955, 415, 12, +101, 936, -204, -111, -148, -978, 84, 79, +72, 683, -10, -161, 392, -361, 340, 81, +-49, 180, 51, 50, -104, -321, -266, -345, +196, 214, 316, 318, 99, -228, 115, -287, +212, 266, 198, 226, 67, -271, -367, -216, +-295, -67, 364, -149, 542, 161, 212, 382, +-171, -223, 76, -524, 392, 155, -325, 546, +-460, -211, 625, -725, 627, 31, -316, 717, +-219, 39, 449, -704, 331, -148, -283, 464, +-179, -81, 367, -358, 277, 181, -127, 355, +211, -134, 352, -498, -53, -117, -244, 176, +-15, -47, 323, 110, 205, 160, 100, -290, +358, -248, 270, 374, -326, 322, -547, -577, +240, -633, 967, 376, -18, 476, -488, -311, +401, -293, 494, 361, -261, 355, -180, -316, +457, -578, 333, -237, -327, 329, -131, 371, +295, -251, 235, -277, 370, 318, 351, 83, +-157, -334, -192, -71, 22, -23, -26, -103, +322, 88, 319, -3, 18, -368, 361, 80, +324, 662, -356, 22, -344, -762, 415, -456, +462, 260, -55, 555, 120, 65, 202, -569, +-37, -162, 146, 395, 225, -148, 77, -446, +3, 328, 228, 415, 66, -406, -90, -428, +485, 300, 283, 102, -308, -394, 11, 24, +220, 50, 304, -41, 365, 357, -3, -44, +-70, -507, 104, -82, -123, 209, 46, -61, +589, -295, 242, -67, 111, 268, 287, 318, +-201, -55, -282, -410, 129, -140, 369, 6, +364, -181, 31, -159, 160, 224, 453, 429, +127, -44, -424, -372, -294, -221, 477, 43, +552, 60, 9, -223, 71, -76, 436, 293, +104, 103, -420, -274, 88, -232, 576, 203, +38, 92, -147, -312, 370, -78, 424, 190, +-97, -25, -132, -342, 289, -40, 244, 468, +-49, -4, 130, -517, 323, -1, 141, 209, +153, -304, 165, 20, -265, 476, 39, -341, +588, -559, 77, 364, -49, 290, 535, -471, +274, -59, -381, 585, -93, -191, 339, -814, +123, 80, 183, 534, 332, -116, 196, -145, +232, 187, 100, -113, -132, -261, -133, -141, +-65, -178, 487, 255, 666, 452, 13, -216, +22, -485, 271, 43, -215, 268, -234, -232, +365, -444, 288, 220, 341, 455, 560, -104, +-154, -211, -536, -50, 347, -224, 726, -172, +-290, 145, -462, 65, 813, -164, 815, 151, +-379, 394, -329, -134, 417, -678, 273, -424, +-187, 240, 50, 504, 461, 121, 438, -212, +78, 0, -238, -27, 149, -508, 326, -263, +-70, 452, 112, 163, 464, -249, 125, 132, +-245, 176, 370, -348, 507, -198, -299, 132, +-95, -303, 593, -183, 152, 590, -269, 158, +250, -531, 533, 94, 46, 274, -66, -530, +254, -369, 40, 319, 9, 127, 294, 7, +274, 177, -98, -125, 172, -378, 542, -45, +-46, 239, -112, -162, 479, -340, 17, 242, +-457, 368, 307, -359, 711, -399, 194, 422, +149, 249, 224, -460, -457, -249, -239, 105, +766, -7, 382, -146, -301, 63, 422, 410, +608, 65, -475, -385, -309, -497, 588, -205, +422, 448, 48, 365, 61, -289, 125, -172, +63, 146, 31, -120, 296, -275, 243, 15, +42, 129, 236, 171, 186, -6, -150, -511, +16, -199, 546, 580, 357, 79, -201, -607, +-86, 52, 230, 480, 264, -235, 270, -386, +152, 68, 59, 73, 105, -119, 140, -25, +-61, 175, 38, 118, 469, -126, 446, -259, +45, -212, -159, 28, -63, 49, 234, -53, +351, 305, 88, 299, -42, -559, 430, -668, +491, 419, -245, 580, -245, -397, 333, -412, +251, 385, -91, 57, 230, -621, 510, 84, +123, 741, 162, -122, 169, -618, -476, 12, +-45, 71, 710, -340, 142, 76, -114, 572, +606, 66, 551, -490, -429, -232, -473, 106, +376, -26, 456, -160, 0, 111, 157, 387, +514, -153, 150, -714, -180, 27, -31, 707, +187, -2, 213, -520, 152, -50, 293, 183, +90, -205, -142, -245, 484, 254, 310, 311, +-305, -178, 186, -289, 298, 33, -151, 170, +105, -91, 583, -305, 271, -224, -102, 204, +99, 441, -8, -89, -101, -425, 274, 102, +515, 227, 372, -305, -124, -352, -214, 109, +186, 147, 328, -67, 130, 233, 62, 193, +272, -429, 247, -172, -62, 246, -42, -389, +228, -414, 339, 623, 99, 584, 43, -447, +133, -586, 135, 183, 191, 405, 162, -239, +134, -615, 97, 107, 115, 768, 262, 96, +0, -784, -101, -309, 298, 486, 410, 119, +226, -322, 171, 145, -85, 267, -280, -346, +236, -384, 426, 92, -42, 146, 373, 93, +657, 196, -365, -117, -472, -456, 571, -75, +581, 365, -284, 71, -195, -355, 526, -117, +336, 299, -174, 96, 200, -402, 509, -160, +8, 468, -204, 116, 54, -499, 59, -156, +293, 267, 594, 66, 45, -250, -152, -152, +327, 266, 173, 175, -124, -226, -46, -136, +238, 7, 430, -80, 170, -55, -8, 10, +332, 20, 194, 82, -241, 93, 56, -117, +232, -198, 12, 6, 412, 22, 576, -131, +-124, 8, -409, 153, 264, 9, 594, -123, +-103, -100, -102, -81, 493, 51, 206, 171, +-114, -46, 53, -213, 107, -56, 306, -35, +451, -78, -41, 191, -182, 230, 364, -166, +197, -323, -177, -6, 121, 181, 269, -68, +359, -175, 365, 93, -112, 85, -215, -117, +336, 26, 275, 167, -177, -159, 214, -340, +421, 53, -44, 215, 92, -144, 421, -106, +116, 299, -88, 173, 145, -421, 131, -414, +-81, 268, 185, 381, 463, -291, 244, -268, +7, 350, 36, 141, 199, -407, 149, -127, +-120, 296, 9, 32, 392, -357, 330, -61, +145, 324, 106, 15, 83, -168, 94, 48, +15, -88, 31, -159, 235, 47, 232, -2, +204, 14, 235, 195, 102, 21, -100, -294, +59, -203, 419, 99, 148, 116, -205, -12, +207, 37, 437, 67, 105, -72, -1, -223, +2, -158, 195, 96, 436, 218, 4, -55, +-213, -150, 397, 203, 359, 124, -280, -500, +36, -261, 548, 446, 237, 168, -29, -350, +-30, -73, 32, 270, 444, 186, 199, -85, +-295, -450, 167, -372, 439, 282, 148, 518, +95, -135, 129, -372, 95, 293, 72, 295, +29, -544, 117, -473, 222, 326, 257, 392, +239, -112, 35, -201, -57, 42, 111, 152, +253, 56, 208, -298, 47, -301, 76, 299, +187, 134, 82, -388, 144, 173, 172, 517, +123, -188, 287, -494, 64, -86, -244, 133, +148, 3, 549, 61, 136, 234, -242, -103, +359, -313, 488, 183, -384, 135, -205, -497, +579, -91, 198, 611, -58, 75, 386, -516, +249, -60, -33, 294, -204, -64, -86, -216, +510, 26, 364, 109, -48, 21, 242, -46, +105, -44, -121, -8, 137, -123, 132, -75, +137, 251, 305, 161, 117, -416, -105, -376, +218, 469, 429, 482, -23, -456, -291, -364, +191, 337, 400, -38, 46, -348, 107, 255, +262, 319, 92, -260, 14, -161, 26, 183, +52, -58, 186, -308, 206, -23, 164, 357, +126, 235, 72, -278, 55, -368, 142, 109, +144, 283, -4, -174, 172, -282, 264, 285, +-130, 287, 22, -344, 573, -238, 110, 322, +-357, 58, 201, -421, 408, -35, -79, 359, +-63, 9, 348, -159, 277, 103, -116, -10, +-69, -328, 291, -59, 262, 323, 81, -25, +58, -218, -177, 202, 0, 80, 560, -297, +155, 52, -158, 236, 292, -169, 104, -333, +-171, 8, 29, 292, 251, 224, 346, -81, +-45, -287, -145, -107, 432, 153, 289, 22, +-209, -73, -100, 34, 48, -85, 155, -94, +364, 138, 238, 130, 60, -87, -11, -83, +-84, 45, 31, -58, 60, -212, 93, -2, +300, 186, 304, 3, 83, -58, -159, 119, +-29, 54, 297, -115, 47, -137, -216, -171, +146, -93, 412, 171, 195, 225, -42, 15, +40, -71, 191, 79, -124, -43, -291, -384, +246, -219, 489, 274, 161, 273, 57, -35, +-28, -47, -73, 58, 28, -60, 14, -226, +65, -150, 263, 125, 272, 209, 98, -84, +-74, -138, -33, 158, -18, 120, 47, -299, +201, -202, 126, 379, 80, 160, 155, -518, +43, -117, 47, 494, -45, -1, -155, -357, +168, 131, 281, 263, 191, -226, 60, -308, +-50, 75, 54, 251, -124, 83, -154, -194, +349, -139, 275, 84, 24, 89, 193, -5, +10, -36, -284, -123, -49, -45, 163, 53, +159, 3, 214, -7, 115, 71, 70, 59, +21, -69, -189, -216, -157, -182, 197, 200, +455, 362, 23, -32, -409, -347, 191, -142, +479, 84, -175, 67, -284, -17, 235, 66, +208, 228, -178, 41, -11, -466, 260, -420, +162, 276, -100, 479, -90, 69, 203, -209, +18, -163, -196, -57, 159, -58, 221, -4, +-41, 121, 55, 59, 144, -32, -158, -15, +-177, -39, 177, -82, 205, -49, 104, 118, +-37, 75, -69, -197, 118, -169, -132, 123, +-117, 330, 377, 117, 157, -384, -345, -406, +53, 123, 354, 306, -60, 34, -242, -3, +39, 139, 90, -128, 73, -420, 135, -60, +-21, 407, -153, 99, 158, -354, 194, 88, +-259, 315, -181, -233, 197, -263, 153, 282, +-16, 143, 11, -350, 86, -151, 88, 200, +-185, 32, -310, -5, 94, 224, 404, 133, +81, -188, -185, -447, -62, -219, 87, 174, +45, 251, -94, 227, -63, 185, 94, -84, +-11, -354, -81, -322, 116, -17, 217, 235, +32, 218, -207, -6, -197, -182, -135, -30, +33, 185, 378, 132, 236, -237, -104, -304, +-249, 70, -229, 100, 57, -16, 110, 146, +-83, 137, 99, -56, 255, -189, 23, -101, +-295, 87, -229, -51, 164, -125, 134, 75, +-205, 68, 22, 67, 288, 177, -113, -130, +-243, -401, 177, 58, 194, 411, -336, -81, +-318, -494, 190, -25, 206, 517, 147, 154, +58, -319, -308, -110, -172, 77, 6, -91, +-4, -72, 128, 101, 48, 103, -68, -63, +-66, -103, -17, -39, 26, 93, -97, 195, +-9, -74, 104, -208, -150, -44, -247, -100, +103, -70, 261, 269, 38, 289, -118, -40, +-282, -327, -165, -244, 202, 126, 76, 313, +-90, -43, -55, -344, -64, -12, 48, 264, +97, 79, -104, -73, -259, -14, -63, -7, +167, -170, 33, -135, -93, 125, -46, 50, +-9, -66, -12, 194, -93, 241, -35, -192, +28, -379, -148, -84, -117, 96, 164, 114, +54, 206, -132, 123, -54, -208, -141, -292, +-21, 19, 119, 212, -148, 130, -83, -55, +48, -266, -55, -108, -20, 242, -106, 122, +-25, -96, 121, 61, -97, 72, -172, -280, +-142, -295, -73, 256, 186, 373, 189, -108, +-152, -205, -296, 115, -79, 41, 79, -346, +-80, -42, -163, 459, 89, 34, 272, -388, +-111, 32, -328, 281, -86, -100, -90, -278, +-73, 128, 144, 278, 126, -163, -39, -275, +-157, 105, -173, 208, -118, -43, -37, -21, +44, 44, 40, -144, -91, -169, -80, 37, +130, 241, -40, 157, -313, -162, -127, -186, +19, -61, 40, 30, 57, 212, -37, 144, +-57, -170, -30, -252, -145, -6, -304, 132, +-22, 39, 259, 96, -22, 166, -189, -112, +48, -369, 120, -95, -307, 304, -554, 146, +223, -161, 533, -35, -224, 138, -345, 36, +187, -113, -4, -105, -502, -39, -97, -22, +402, 3, -3, 146, -269, 233, 53, -4, +69, -214, -258, -193, -314, -161, 9, 36, +204, 325, 83, 235, -105, -31, -143, -81, +-197, -211, -82, -306, 49, -64, -62, 290, +-17, 420, 39, 184, -159, -257, -160, -495, +-35, -268, 91, 280, 116, 506, -189, 137, +-369, -262, -108, -356, 177, -130, 104, 249, +-2, 379, -58, 24, -227, -331, -290, -271, +-12, 9, 256, 257, -26, 305, -256, 20, +47, -401, -94, -261, -230, 206, 179, 345, +45, 101, -328, -282, -76, -362, 177, 99, +13, 400, -310, 99, -265, -289, 199, -242, +276, 191, -210, 446, -287, -46, -23, -654, +-124, -332, -63, 524, 250, 699, -80, -24, +-394, -567, 31, -436, 285, 51, -127, 505, +-410, 268, -101, -312, 175, -248, 99, 181, +-88, 232, -292, -202, -129, -342, 256, 162, +-3, 456, -361, 16, -108, -413, 123, -182, +4, 250, -87, 220, -78, -78, -22, -190, +-210, -14, -208, 67, 266, 76, 170, 84, +-399, -27, -263, -70, 185, -87, 118, -34, +-329, 71, -229, 32, 242, 59, 110, 114, +-222, -63, -189, -173, 9, -46, -36, 125, +-153, -1, 0, -12, 6, 190, -104, -29, +-12, -312, -40, -124, -95, 230, -68, 295, +-47, 160, -177, -111, -88, -481, 158, -381, +-84, 267, -162, 663, 65, 164, -80, -465, +-153, -134, -49, 297, -57, -142, -142, -531, +-103, 11, 190, 798, 119, 490, -280, -646, +-211, -768, 28, 365, -241, 690, -206, -337, +408, -521, 352, 465, -457, 523, -601, -442, +103, -585, 376, 168, -228, 549, -309, 170, +188, -270, 92, -260, -161, -113, -174, 122, +-174, 320, -59, 99, 90, -234, -37, -104, +-152, 124, -37, -153, 66, -284, 28, 391, +-157, 711, -421, -65, -219, -982, 226, -562, +301, 726, 85, 821, -220, -128, -446, -522, +-294, -158, 149, 138, 260, 47, -109, 35, +-169, 102, 66, -16, -45, -80, -280, -66, +-194, 6, 71, 228, 106, 122, -34, -351, +-138, -298, -160, 320, -51, 436, -76, 48, +-122, -383, 155, -547, 124, 137, -326, 791, +-350, 228, 35, -693, 198, -434, -96, 485, +-199, 447, 133, -236, 42, -310, -370, -31, +-188, 118, 112, 130, 0, 123, -29, 33, +-113, -247, -219, -301, 79, 160, 288, 551, +-126, 262, -591, -472, -470, -825, 226, -116, +722, 989, 313, 887, -712, -469, -899, -1092, +47, -117, 695, 727, 261, 347, -477, -334, +-493, -364, 22, 33, 104, 324, 22, 389, +128, 106, -69, -544, -442, -600, -263, 151, +217, 687, 95, 343, -211, -345, -7, -527, +12, 23, -208, 630, 17, 217, -61, -529, +-305, -523, 76, 214, 55, 741, -324, 146, +0, -713, 234, -337, -19, 648, -209, 496, +-355, -474, -209, -613, 195, 121, 232, 660, +-195, 307, -487, -620, 67, -587, 671, 509, +-104, 706, -1011, -239, -385, -583, 466, 5, +517, 325, 40, 123, -507, -108, -378, -76, +-35, -142, 86, -57, 242, 522, -118, 426, +-544, -582, -183, -869, 336, 187, 341, 888, +-122, 242, -530, -235, -380, -182, 132, -471, +344, -191, -117, 606, -423, 465, 0, -441, +400, -329, -1, 552, -660, 222, -404, -833, +388, -464, 275, 744, -270, 701, -136, -226, +38, -383, -126, -54, -296, -81, -177, -115, +302, 177, 220, 459, -414, -146, -411, -559, +88, 117, 242, 661, -29, 146, -342, -737, +-153, -414, 144, 685, -34, 506, -247, -610, +-93, -605, 96, 575, -4, 900, -272, -282, +-106, -1010, 270, -76, -33, 882, -549, 185, +-361, -865, 417, -245, 637, 1012, -394, 689, +-928, -834, 48, -1202, 592, 284, -126, 1410, +-434, 273, 87, -1293, 150, -416, -214, 1087, +-459, 350, -102, -1099, 547, -319, 263, 1369, +-604, 677, -569, -1407, 72, -1128, 310, 891, +48, 1139, -117, -219, -93, -635, -68, 26, +-252, 273, -341, -224, 187, -295, 291, 315, +-184, 550, -159, -39, -81, -691, -173, -311, +-179, 480, 17, 513, 324, -61, -3, -312, +-620, -197, -324, -15, 421, 211, 422, 249, +-208, -216, -727, -365, -320, 171, 434, 442, +416, 215, -89, -268, -456, -446, -432, -142, +27, 220, 195, 300, 170, 109, 139, -101, +-346, -8, -608, 73, -138, -252, 508, -218, +406, 278, -393, 346, -604, -183, -166, -428, +381, 87, 459, 603, -352, 202, -800, -550, +-55, -600, 644, 177, 232, 798, -556, 121, +-302, -559, 267, -102, -319, 231, -323, -1, +520, -125, 207, 56, -437, 246, -230, 20, +-120, -344, -39, -133, 215, 350, -31, 265, +-328, -281, -156, -313, 216, 211, 165, 274, +-350, -43, -348, -79, 178, -64, 169, -108, +-161, 6, -281, 207, -160, 24, 281, -194, +177, 73, -378, 207, -190, 36, 65, -140, +-85, -172, -82, -160, -37, 80, -161, 361, +98, 173, 231, -189, -154, -55, -272, -14, +-208, -261, -201, -35, 63, 390, 214, 179, +120, -359, 91, -186, -335, 271, -617, 423, +18, -173, 535, -600, -51, 73, -439, 521, +80, -8, 108, -453, -185, -31, -37, 494, +-111, 204, -127, -301, 109, -198, -32, 118, +-165, 22, -88, -391, -154, -32, 221, 668, +303, 335, -382, -226, -675, -430, -13, -348, +778, 156, 233, 499, -791, 54, -487, -599, +359, -105, 487, 789, -106, 404, -651, -607, +-124, -600, 469, 120, 124, 331, -439, 36, +-506, -3, 256, 206, 577, 74, -105, -310, +-411, -86, -284, 188, -114, -47, 198, -176, +177, -18, -39, 225, -135, 218, -336, -125, +37, -112, 264, 89, 19, 1, -209, -142, +-598, -241, -76, 43, 796, 354, 184, 358, +-651, -71, -315, -442, 301, -226, 138, 303, +-450, 122, -188, -322, 418, 24, 89, 456, +-402, 202, 24, -426, 347, -348, -268, 346, +-569, 235, -42, -480, 391, -151, 344, 561, +-197, 356, -476, -275, -116, -487, 403, -114, +-39, 353, -560, 303, 22, -207, 438, -205, +44, 267, -304, 66, -239, -382, -91, -93, +102, 490, 274, 238, 38, -298, -530, -294, +-336, -114, 430, 148, 377, 326, -337, 135, +-334, -121, 46, -206, 76, -94, -13, -8, +-36, -32, -86, 227, -92, 327, 112, -127, +130, -418, -478, -47, -283, 257, 540, 17, +295, -92, -437, 170, -289, 183, 93, -186, +-109, -367, -54, 136, 227, 340, 127, -90, +-182, -283, -234, 109, -179, 320, 99, -42, +233, -138, -124, -40, -230, -115, -3, -132, +119, 121, 63, 270, -203, 138, -162, -52, +156, -62, -49, -275, -229, -255, 57, 383, +211, 304, 3, -309, -285, -262, -220, 365, +164, 420, 260, -307, -162, -549, -295, 141, +71, 457, 4, -127, -6, -416, 116, 152, +-81, 534, -220, 6, 95, -374, 98, -17, +-360, 63, -47, -357, 347, -135, -42, 621, +-122, 424, 1, -265, -308, -354, -136, -148, +389, 39, 237, 181, -396, 113, -361, -183, +165, -54, 253, 373, -3, 76, -210, -390, +-73, -75, 60, 213, -139, -81, -29, -276, +137, 290, -50, 630, -57, -365, 192, -869, +-276, 325, -362, 889, 419, -256, 87, -757, +-499, 174, 338, 492, 492, 35, -714, -283, +-601, -113, 526, 188, 478, 19, -41, -120, +-314, 47, -477, 199, 73, -64, 516, -330, +-30, 41, -370, 465, 2, -35, 215, -353, +-190, -97, -242, 139, 200, 205, 178, 65, +-27, -30, -261, -217, -125, -205, 325, 185, +-211, 237, -540, -29, 616, -104, 577, -16, +-597, 89, -610, -26, 103, -187, 594, 35, +7, 267, -638, -23, 77, -356, 592, -18, +-30, 618, -644, 189, -247, -835, 487, -389, +337, 844, -238, 333, -310, -654, -75, -181, +112, 525, 148, 113, -140, -500, -55, 58, +338, 575, -177, -168, -575, -822, 201, -58, +354, 1050, -149, 500, -83, -996, 123, -744, +7, 781, -219, 843, -125, -636, 108, -957, +198, 511, -185, 1035, -247, -394, 205, -944, +259, 236, 22, 958, -326, -118, -451, -838, +207, -104, 542, 674, -91, 242, -621, -630, +134, -336, 827, 610, -317, 672, -1016, -379, +221, -971, 808, -104, 33, 979, -523, 427, +-253, -819, 317, -492, 263, 860, -263, 386, +-340, -929, 200, -229, 258, 880, -19, 129, +-274, -755, -212, -137, 254, 496, 402, 146, +-273, -117, -496, -16, 169, -82, 253, -262, +-131, 115, 68, 471, 85, -140, -114, -467, +-93, 126, -128, 440, -77, -39, 156, -499, +237, -115, -2, 654, -409, 315, -44, -674, +601, -568, -218, 522, -780, 713, 288, -274, +576, -714, -194, 105, -87, 781, 25, -39, +-164, -854, -130, -144, 144, 743, 170, 505, +-134, -513, -145, -599, 38, 193, 89, 372, +87, 33, -65, -174, -146, 36, -68, 163, +77, -21, 189, -296, -152, -198, -371, 340, +239, 355, 423, -262, -268, -235, -274, 259, +290, 147, -31, -272, -502, -240, 172, 141, +488, 229, -118, 167, -255, -169, 0, -118, +-78, 74, 160, -97, 230, -21, -451, 124, +-269, -1, 528, 46, 297, 178, -506, -208, +-388, -531, 410, 338, 507, 749, -315, -291, +-619, -687, 135, 89, 692, 602, -116, -16, +-647, -523, 104, 14, 381, 265, -6, 0, +-112, 66, 22, 135, 67, -123, -161, -446, +-200, 45, -133, 480, 199, 101, 522, -441, +83, -339, -556, 566, -341, 682, 500, -264, +143, -994, -754, -398, 78, 913, 940, 667, +-99, -541, -741, -478, 73, 360, 557, 499, +-186, -354, -628, -688, 25, 151, 599, 722, +307, 118, -444, -713, -445, -299, 529, 819, +394, 499, -820, -608, -553, -842, 932, 162, +727, 989, -722, 189, -906, -1015, 557, -419, +1071, 1043, -494, 707, -1112, -905, 387, -955, +914, 645, -349, 988, -802, -405, 323, -1097, +904, 211, -63, 1142, -871, 207, -363, -940, +548, -620, 471, 599, -297, 802, -355, -389, +348, -1052, 439, 320, -472, 1484, -719, -193, +315, -1601, 724, -122, 6, 1326, -566, 465, +-89, -1031, 463, -581, 99, 770, -559, 516, +-285, -464, 526, -446, 565, 233, -357, 451, +-578, -167, 198, -405, 278, 54, -76, 362, +-173, 115, 39, -263, 303, -206, -73, -39, +-303, 257, -10, 331, 135, -323, 197, -389, +-48, 405, -211, 508, -106, -634, 73, -697, +298, 688, 116, 796, -351, -467, -312, -766, +174, 306, 397, 848, 40, -307, -224, -967, +-276, 146, 88, 863, 302, 81, -156, -616, +-64, 29, 118, 437, -50, -150, -50, -439, +98, 73, -19, 352, -211, -26, 70, -107, +211, 35, -165, -20, 25, 44, 277, 77, +-169, -101, -376, -188, 53, -60, 359, 212, +39, 270, -250, -107, -42, -230, 263, 50, +88, 118, -384, -96, -216, -162, 410, 135, +284, 198, -256, -28, -368, 11, 47, -228, +329, -391, 306, 400, -192, 851, -562, -248, +-17, -1206, 547, -95, 52, 1239, -391, 245, +60, -947, 327, -104, -95, 596, -352, -96, +5, -334, 277, 271, 118, 245, -235, -411, +-172, -393, 221, 502, 111, 698, -195, -429, +87, -962, 105, 132, -135, 1236, -129, 201, +-55, -1390, 168, -425, 279, 1195, -68, 556, +-260, -765, -178, -619, 92, 414, 251, 617, +143, -135, -219, -546, -205, -181, 154, 592, +96, 313, -117, -651, -107, -461, 244, 732, +261, 682, -371, -639, -422, -755, 231, 373, +542, 699, 33, -259, -541, -776, -123, 299, +422, 972, 17, -240, -380, -1041, 173, 47, +543, 1097, -218, 42, -672, -1201, -22, -193, +574, 1198, 235, 307, -285, -877, -202, -131, +57, 543, 186, -169, -56, -419, -345, 174, +174, 272, 434, 18, -230, 36, -464, -115, +357, -203, 553, 201, -508, 108, -655, -350, +471, -18, 696, 437, -316, 1, -634, -474, +109, 34, 594, 617, 140, -58, -575, -696, +-422, -39, 546, 636, 571, 130, -405, -499, +-574, -197, 160, 339, 440, 305, 92, -133, +-281, -484, -160, 65, 241, 649, 44, -53, +-341, -795, 81, -62, 301, 881, -39, 161, +-179, -821, -19, -203, 166, 828, 21, 264, +-170, -866, -25, -421, 34, 792, -13, 400, +76, -584, 127, -263, -34, 504, -73, 168, +12, -479, -78, -88, -186, 305, 11, -43, +337, -145, 202, 54, -195, 162, -214, 223, +-106, -146, 50, -580, 164, -84, 10, 786, +-51, 337, 5, -629, 81, -466, -34, 268, +-198, 411, 24, -43, 290, -160, -62, 137, +-312, -5, -2, -402, 185, -60, 210, 535, +128, 115, -370, -434, -322, -41, 211, 315, +302, 23, 60, -282, -234, -123, -196, 177, +260, 197, 192, -59, -236, -231, -177, 126, +126, 342, 179, -235, -121, -463, -230, 244, +207, 443, 255, -354, -203, -374, -129, 565, +53, 516, 14, -504, 4, -665, -195, 169, +-33, 476, 547, 30, 186, -109, -694, 63, +-376, -133, 587, -180, 399, 342, -469, 263, +-351, -576, 297, -435, 399, 618, 31, 612, +-462, -509, -318, -603, 427, 393, 308, 574, +-421, -203, -181, -553, 482, -43, 104, 313, +-458, 198, -91, 69, 294, -156, 39, -308, +-98, 56, -72, 309, -36, 57, 239, -246, +72, -77, -295, 136, -111, -18, 121, -65, +65, 53, 89, 114, 66, 85, -127, -30, +-148, -190, 16, -204, -13, 70, 36, 239, +171, 97, 49, -62, -113, -9, -38, 36, +-93, -254, -124, -182, 179, 298, 210, 307, +-206, -160, -89, -376, 265, 123, -99, 395, +-257, -81, 169, -350, 98, -59, -197, 285, +22, 82, 210, -235, 0, 1, -218, 246, +-56, 63, 180, -200, -8, -210, -164, 47, +53, 242, 117, 83, -23, -154, -61, -23, +-23, 98, -49, -85, -32, -119, 177, 96, +39, 255, -247, -46, 114, -415, 134, -89, +-389, 429, 97, 269, 603, -258, -249, -332, +-709, 164, 196, 227, 641, -204, -123, -215, +-453, 203, 89, 370, 368, 37, -87, -379, +-455, -429, -42, 100, 412, 655, 159, 269, +-116, -552, -151, -416, -123, 334, 37, 352, +83, -266, -95, -300, 75, 293, 216, 348, +-147, -227, -321, -369, 100, 154, 402, 370, +-30, -101, -477, -388, -72, -65, 436, 358, +84, 146, -308, -269, -27, -14, 259, 365, +-63, -27, -286, -530, 66, -245, 277, 393, +-94, 463, -259, -19, 37, -358, 277, -144, +111, 199, -213, 150, -364, -128, 68, -279, +494, -42, 84, 329, -551, 252, -194, -154, +587, -251, 277, 122, -584, 192, -430, -363, +417, -303, 500, 414, -136, 493, -446, -231, +-107, -428, 411, 199, 144, 195, -516, -270, +-180, -186, 525, 185, 412, 275, -334, -14, +-632, -152, 88, -60, 578, 49, -36, 81, +-484, -174, 91, -216, 510, 224, -80, 383, +-482, -66, -11, -365, 185, 22, 85, 251, +139, -93, -185, -292, -355, 25, 274, 343, +413, 112, -257, -160, -317, -105, 156, -85, +124, 26, -175, 108, -50, 35, 226, -53, +137, -67, -203, 90, -249, 33, 109, -122, +249, -12, -106, 175, -172, 79, 119, -286, +120, -97, -177, 281, -129, -5, 141, -145, +133, 161, -56, 92, -28, -323, -41, -62, +-200, 416, 10, -4, 308, -380, 66, 106, +-277, 303, -80, -184, 157, -325, -48, 188, +25, 254, 153, -9, -190, 42, -127, -138, +126, -308, -17, -16, -56, 299, 191, 235, +70, -149, -206, -196, -70, 86, 34, 96, +-119, -108, 48, -154, 246, 149, -24, 168, +-217, -120, 129, -43, 136, 111, -370, -72, +-239, -168, 406, 144, 433, 221, -253, -270, +-504, -196, 90, 438, 335, 163, 67, -584, +-257, -210, -202, 696, 390, 294, 273, -709, +-537, -387, -482, 544, 478, 489, 681, -365, +-282, -496, -532, 334, 95, 480, 230, -324, +-172, -641, -199, 78, 278, 788, 391, 314, +-189, -633, -452, -477, 100, 353, 310, 334, +-273, -217, -278, -233, 332, 182, 446, 326, +-167, -101, -568, -434, -2, 6, 487, 496, +92, 79, -416, -540, -220, -197, 356, 492, +279, 186, -225, -378, -149, -38, 105, 337, +-21, -23, -257, -383, 105, -90, 423, 450, +-19, 251, -489, -398, -229, -458, 349, 190, +400, 563, -78, 59, -273, -355, -92, -16, +-5, 69, -102, -283, 21, -151, 158, 358, +224, 356, 229, -84, -138, -155, -637, -102, +-380, -239, 589, -81, 543, 300, -309, 290, +-276, -99, 126, -229, 109, -2, -21, 78, +-138, 66, -64, -34, 34, -121, -26, -49, +-56, 0, 127, 47, 237, 224, 94, 221, +-228, -168, -348, -447, -65, -100, 192, 285, +83, 138, 39, -84, 163, 54, 21, 201, +-280, -40, -105, -261, 198, -181, -74, 12, +-215, 275, 162, 114, 304, -177, -136, 25, +-331, 153, 138, -79, 327, -228, -83, 60, +-373, 236, -143, -150, 294, -190, 212, 207, +-221, 160, -114, -87, 296, -68, 59, -3, +-295, -37, -205, -1, 40, 2, 348, -17, +66, 74, -419, 113, 47, -44, 541, -152, +-120, -55, -752, 92, 61, 70, 785, 46, +-27, -36, -679, -91, -14, 49, 535, 24, +109, -139, -402, -63, -288, 238, 266, 281, +476, -208, -286, -395, -658, 38, 305, 309, +768, 117, -198, -185, -731, -197, 86, 81, +507, 241, -156, -59, -318, -200, 211, 136, +321, 216, -169, -155, -388, -399, 68, -45, +338, 506, -31, 246, -286, -336, 39, -231, +263, 173, -23, 126, -272, -166, -101, -169, +312, 92, 168, 250, -335, 119, -161, -202, +242, -209, 110, 138, -197, 172, -37, -192, +208, -242, 6, 175, -199, 387, -95, 50, +134, -411, 177, -215, -169, 334, -251, 154, +268, -313, 254, -48, -264, 357, -130, -7, +148, -341, -109, 42, -85, 228, 180, -11, +19, -58, -86, -68, 158, -108, 31, 32, +-309, 91, -79, 49, 274, 120, 17, 57, +-226, -262, 49, -228, 290, 162, 46, 200, +-339, -1, -231, -47, 259, -79, 265, -14, +-232, 90, -189, 35, 179, -45, 194, 1, +-11, -75, -235, -151, -172, 92, 158, 241, +165, 26, -51, -152, -71, -78, 0, 37, +24, 33, 74, -6, -76, -16, -153, -50, +87, 56, 58, 137, -143, -47, 121, -171, +261, 10, -263, 238, -322, 72, 309, -289, +239, -216, -279, 103, -162, 318, 56, 156, +206, -268, 256, -236, -215, 226, -471, 220, +48, -297, 489, -261, 111, 406, -499, 322, +-135, -448, 462, -401, 113, 480, -331, 509, +-120, -428, 157, -586, 118, 264, -119, 599, +-176, -101, 108, -578, 245, 16, -17, 584, +-226, 8, -46, -626, 150, -4, -54, 652, +-165, 13, 157, -598, 186, -112, -56, 470, +-165, 228, -148, -295, 154, -286, 255, 128, +-135, 330, -275, -61, -53, -417, 238, 59, +250, 513, -81, 50, -274, -515, -107, -249, +204, 321, 81, 331, -189, -25, 85, -250, +212, -137, -225, 188, -226, 134, 248, -254, +212, -142, -176, 356, -140, 231, 35, -321, +54, -366, 41, 123, -33, 402, -67, 81, +121, -260, 106, -156, -206, 93, -161, 72, +185, -52, 146, 41, -79, 88, -102, -102, +-33, -65, 42, 83, 67, 4, 21, -48, +-47, 112, -32, 102, -32, -220, -44, -216, +67, 162, 99, 228, 10, 25, -78, -42, +-181, -92, -28, -161, 225, 31, 148, 220, +-101, 37, -152, -183, -60, -53, 21, 146, +78, -2, 57, -113, -55, 105, 22, 120, +102, -137, -126, -137, -161, 105, 133, 85, +121, -74, -77, -74, -131, 41, -23, 153, +219, 92, 102, -183, -237, -212, -97, 195, +228, 171, 43, -255, -362, -119, -64, 214, +493, 101, 61, -48, -372, 41, 106, 39, +179, -222, -272, -212, -157, 134, 169, 311, +162, 89, 10, -304, -28, -128, -6, 332, +-59, 96, -58, -317, -14, -114, -65, 231, +26, 10, 180, -210, 97, 139, -97, 317, +-133, -116, -3, -360, 55, 42, -54, 300, +-85, -71, 62, -338, 201, 24, 110, 491, +-220, 173, -261, -486, 162, -274, 194, 306, +-149, 193, -29, -279, 159, -90, -50, 363, +-123, 102, 58, -348, 92, -140, -23, 246, +-118, 116, -29, -220, 117, -69, 10, 228, +-66, 91, 53, -193, 84, -156, -9, 144, +-174, 216, -118, -90, 131, -324, 179, -15, +0, 434, -147, 160, -1, -403, 131, -218, +-89, 275, -132, 163, 31, -254, 65, -144, +85, 277, 83, 236, -66, -152, -110, -237, +18, 11, -118, 56, -114, -124, 348, 18, +264, 375, -322, 125, -308, -420, 204, -159, +209, 339, -186, 26, -146, -424, 130, -45, +269, 495, 61, 221, -435, -319, -252, -214, +437, 143, 342, 57, -368, -130, -368, 7, +285, 67, 325, -65, -119, 115, -276, 235, +14, -165, 261, -308, -64, 103, -272, 206, +42, -139, 275, -159, 124, 144, -181, 189, +-151, -15, 42, -128, -11, -31, -76, 33, +87, -50, 243, -15, -48, 50, -288, -7, +29, 42, 246, 168, -74, -54, -328, -358, +100, -3, 416, 453, -89, 45, -356, -471, +69, -107, 340, 440, -56, 194, -408, -356, +-29, -191, 385, 182, 178, 80, -269, -55, +-238, 74, 242, 89, 187, -134, -299, -188, +-229, 44, 284, 179, 414, 109, -155, -94, +-537, -196, 6, 29, 527, 211, 41, 71, +-518, -188, -19, -206, 572, 73, -31, 306, +-576, 103, 55, -300, 463, -185, 15, 233, +-283, 148, -199, -198, 115, -135, 292, 195, +-11, 178, -220, -87, 37, -80, 162, -23, +-163, -141, -230, -136, 167, 179, 279, 395, +-44, 41, -197, -263, -29, -148, 101, -81, +18, -87, -54, 126, -12, 334, 7, 9, +-96, -302, -38, 14, 258, 218, 210, 24, +-265, -197, -331, -184, 92, 102, 269, 143, +-26, -45, -226, -22, 114, 193, 366, 149, +-133, -243, -516, -325, 39, 20, 528, 248, +74, 131, -477, -146, -167, -118, 398, 182, +252, 207, -302, -159, -286, -338, 253, 1, +373, 280, -263, 156, -541, -169, 185, -216, +613, 114, -16, 186, -451, -74, -69, -143, +274, 52, 0, 126, -174, -48, 29, -89, +98, 47, 121, 8, -73, -113, -355, -71, +91, 128, 528, 294, 24, 112, -551, -335, +-229, -403, 368, 75, 289, 416, -77, 174, +-264, -267, -85, -300, 318, 173, 141, 456, +-387, -86, -223, -575, 322, -34, 226, 564, +-153, 110, -86, -534, -14, -203, 68, 477, +68, 310, -181, -304, -56, -297, 190, 154, +57, 199, -89, -178, -66, -154, 94, 202, +71, 154, -163, -147, -175, -172, 157, 94, +285, 224, -64, 24, -230, -213, -46, -193, +139, 24, 82, 215, -115, 154, -70, -110, +47, -177, 104, 83, 55, 188, -150, -82, +-80, -267, 72, 41, 63, 330, 29, -12, +-41, -355, -90, -56, -5, 345, 145, 176, +50, -229, -140, -160, -8, 118, 56, -40, +-84, -200, -25, 87, 171, 310, 81, 84, +-184, -222, -78, -147, 143, 38, 15, 20, +-140, 26, 30, 41, 173, -44, -47, -8, +-174, 116, 45, 47, 162, -128, -72, -36, +-190, 92, 183, -149, 178, -193, -260, 255, +-149, 377, 202, -146, 151, -334, -52, 85, +-134, 94, -59, -231, 91, -20, 91, 330, +-112, 102, -68, -258, 189, -33, 51, 231, +-232, -145, -88, -334, 255, 108, 155, 391, +-218, 42, -193, -322, 67, -69, 138, 235, +109, 87, -13, -186, -106, -203, -99, 119, +-47, 285, 55, -60, 138, -277, 58, 109, +-18, 322, -110, -219, -155, -428, 72, 176, +220, 467, -22, -30, -141, -404, -23, 27, +31, 297, 39, -105, 1, -231, -10, 81, +59, 181, -19, -60, -83, -94, 43, 132, +-4, 24, -76, -156, 55, -65, 165, 67, +-31, 98, -182, 29, 62, -40, 59, -66, +-184, 16, 75, 77, 206, -49, -119, -92, +-151, 71, 178, 107, 98, -50, -193, -93, +-53, 35, 92, 15, -64, -29, -29, 53, +151, 51, 127, -38, -95, -48, -185, 21, +-8, -19, 82, -127, -35, 49, 5, 307, +166, 77, -3, -387, -200, -251, -20, 286, +214, 314, 76, -143, -293, -282, -170, 66, +298, 285, 192, 16, -187, -344, -151, -194, +170, 335, 149, 361, -168, -249, -198, -394, +-22, 228, 194, 392, 219, -268, -101, -491, +-187, 199, 56, 571, 82, -93, -120, -497, +-101, 96, 196, 457, 160, -73, -207, -513, +-178, -101, 173, 392, 176, 187, -111, -112, +-172, -41, 59, 54, 167, -15, -54, -172, +-243, -174, 6, 85, 375, 328, 140, 132, +-385, -278, -219, -198, 287, 203, 162, 112, +-226, -220, -113, -39, 186, 250, 101, 21, +-88, -266, -23, -39, 93, 268, -13, 58, +-231, -252, -149, -89, 294, 225, 326, 191, +-217, -168, -293, -302, 179, 41, 190, 320, +-120, 72, -212, -313, -86, -98, 200, 331, +241, 143, -97, -305, -158, -166, 145, 231, +31, 93, -361, -184, -49, -8, 445, 170, +86, 10, -390, -157, -46, -62, 316, 137, +81, 197, -185, -56, -182, -358, 55, -75, +191, 347, -69, 121, -201, -264, 112, -85, +327, 320, 38, 150, -356, -304, -205, -285, +189, 84, 194, 242, -109, -17, -166, -100, +191, 147, 256, 116, -180, -103, -256, -165, +101, -84, 154, 5, -139, 93, -136, 190, +108, 31, 144, -200, 65, -88, 7, 164, +-78, 82, -109, -173, -86, -73, -38, 188, +105, 67, 132, -249, -35, -129, 22, 328, +135, 262, -85, -262, -229, -313, -56, 130, +83, 275, 50, -99, 46, -249, 109, 42, +46, 237, -82, 101, -56, -165, -32, -182, +-110, 85, -8, 160, 159, -70, 48, -168, +-45, 66, 36, 202, 17, -36, -68, -164, +-38, 59, 44, 143, -50, -92, -115, -249, +72, 16, 189, 314, 34, 152, -151, -189, +-14, -198, 133, 56, -118, 99, -164, -99, +93, -80, 116, 158, -2, 190, -24, -55, +2, -172, 26, -36, 43, 20, -29, -51, +-144, -4, -67, 118, 109, 101, 154, 21, +22, -66, -91, -181, -81, -84, 22, 137, +120, 137, -32, -10, -152, -82, -18, -41, +107, 30, 122, 94, -78, 1, -148, -159, +198, -33, 167, 116, -272, 40, -292, -7, +174, 2, 341, -29, -43, -41, -200, 22, +-12, 34, 62, -72, 56, -53, -12, 99, +-55, 125, -30, -29, 22, -159, 30, -76, +-7, 108, 54, 117, 40, -62, -87, -115, +-35, 43, 74, 119, -3, -6, -122, -114, +-24, -49, 181, 23, 149, 74, -133, 83, +-212, -55, 114, -134, 151, 36, -128, 153, +-88, -27, 58, -165, 54, 20, 20, 145, +26, -19, 23, -108, -23, 25, -46, 101, +-136, -24, -45, -127, 219, -37, 126, 99, +-99, 114, -57, -10, 36, -103, -13, 6, +-99, 91, -34, -114, 104, -213, 69, 112, +-80, 329, 5, 47, 128, -237, -40, -63, +-121, 110, -9, -97, 8, -191, 10, 73, +87, 312, 101, 163, -82, -232, -164, -295, +80, 84, 184, 256, -102, -98, -204, -281, +146, 98, 212, 338, -188, -6, -186, -236, +168, 29, 157, 100, -77, -177, -60, -155, +57, 225, -9, 274, -96, -94, -66, -213, +34, -10, 103, 59, 45, -7, 8, -3, +32, 30, -21, 16, -131, -35, -88, -7, +104, 111, 72, 40, -19, -243, 70, -173, +32, 271, -75, 271, -5, -197, 44, -223, +-139, 184, -179, 146, 136, -183, 216, -105, +9, 130, -6, 47, -24, -67, -130, 30, +-74, 49, 47, -40, 122, -20, 75, 25, +-114, 14, -111, -30, 158, -83, 98, -58, +-176, 59, -45, 181, 159, 69, -3, -126, +-162, -133, -1, 11, 173, 101, 53, -41, +-84, -169, -14, 61, 45, 293, -54, 45, +-88, -271, 32, -61, 54, 214, 21, -26, +19, -312, -13, -33, 16, 359, -7, 167, +-16, -191, 1, -118, -43, 60, 24, -42, +51, -141, 28, 74, 23, 225, -70, 22, +-38, -166, 18, -98, -9, 70, -21, 113, +8, -17, 106, -88, 61, -7, -84, 43, +-48, -57, 57, -32, -33, 89, -60, 39, +182, 18, 56, 47, -243, -140, -26, -261, +156, 109, -8, 395, -71, -4, 93, -331, +51, -13, -191, 263, -11, -10, 183, -275, +-23, -60, -70, 226, 60, 148, 43, -91, +-67, -103, -46, 54, 53, 63, -2, -60, +-126, -140, -75, -54, 182, 151, 188, 178, +-84, -6, -88, -76, 18, -27, -6, -90, +-43, -188, -13, 5, -2, 272, 43, 147, +215, -110, 48, -96, -252, 1, -126, -32, +62, -67, 125, 29, 5, 73, -128, -3, +52, -41, 174, 32, 55, 74, -61, 17, +-74, -66, -7, -114, -79, -73, -102, 84, +92, 164, 197, 31, 58, -136, -159, -68, +-127, 97, 125, 31, 153, -82, -116, 9, +-177, 77, 72, -7, 115, -119, 8, -78, +70, 84, 56, 172, -96, 45, -73, -145, +44, -55, -83, 89, -146, -110, 106, -218, +225, 152, 43, 389, -92, 1, -20, -290, +34, -62, -90, 87, -28, -81, 110, -99, +-44, 143, -92, 196, 134, -36, 150, -158, +-75, -60, -154, 81, -50, 109, 24, -53, +77, -197, 31, -42, -19, 231, 81, 177, +66, -118, -116, -164, -77, 27, 103, 76, +26, -62, -126, -78, -50, 43, 108, 139, +148, 78, -70, -116, -181, -121, 105, 32, +142, 31, -121, -13, -86, 52, 86, 55, +114, -74, 51, -53, -112, 83, -137, 14, +102, -95, 112, 46, -151, 127, -119, -116, +146, -217, 159, 111, -73, 320, -108, 11, +43, -303, 79, -96, 4, 203, -116, 53, +-15, -199, 220, -45, -11, 250, -240, 160, +67, -180, 210, -211, -112, 61, -212, 114, +112, -97, 155, -91, -89, 164, -28, 201, +97, -57, 28, -204, -10, -61, 9, 85, +-54, -1, -123, -60, 27, 52, 162, 155, +-4, 47, -123, -153, -2, -153, 95, 46, +10, 175, 3, 25, 15, -180, -89, -66, +-68, 161, 104, 43, 160, -124, 3, 64, +-70, 192, 14, -71, -131, -307, -176, -97, +129, 228, 218, 199, 22, -33, -130, -75, +-62, 22, 56, -30, 60, -142, 34, -37, +-51, 127, -53, 51, 96, -41, 108, 84, +-99, 80, -194, -164, 85, -208, 225, 104, +-92, 273, -285, -50, 44, -291, 395, 50, +74, 310, -336, -59, -60, -320, 232, 73, +31, 307, -229, -110, -8, -305, 325, 90, +30, 271, -308, -11, -66, -155, 173, -12, +51, 34, -138, -7, -60, -44, 184, -79, +157, 89, -149, 274, -132, 24, 209, -385, +100, -160, -266, 321, -137, 90, 205, -294, +173, 59, -170, 427, -204, -59, 213, -495, +291, -27, -151, 402, -342, 32, -18, -383, +262, -62, 204, 431, -52, 237, -207, -326, +-7, -381, 179, 108, -47, 343, -167, -21, +66, -255, 84, 30, -107, 235, -24, 7, +126, -181, 40, -32, -21, 75, 6, -27, +-20, -31, -2, 85, -3, 45, -39, -86, +29, -18, 99, 78, 28, -42, -135, -141, +-92, 50, 97, 226, 71, 0, -18, -208, +-44, -30, -48, 110, 90, -27, 142, -90, +-46, 86, -168, 128, 43, -23, 252, -74, +-30, -56, -347, -84, -125, 19, 297, 189, +258, 64, -187, -196, -272, -79, 115, 173, +276, 60, -46, -145, -271, -35, 100, 143, +358, 42, -104, -146, -461, -139, -22, 22, +448, 227, 176, 193, -336, -146, -237, -280, +211, 16, 200, 169, -181, -53, -166, -77, +237, 191, 292, 158, -139, -168, -359, -240, +-34, -19, 257, 127, 131, 145, -99, 74, +-154, -91, -12, -159, 111, 12, 53, 147, +-35, 4, -42, -142, -6, -1, 33, 133, +9, -20, 9, -129, 119, 40, 88, 132, +-135, -50, -197, -165, 4, 39, 126, 184, +56, -20, 17, -184, 27, 15, -26, 206, +-65, 11, -66, -205, -12, -81, 141, 98, +169, 91, -90, -2, -185, -45, 59, 4, +111, 111, -47, 12, -44, -266, 24, -143, +43, 294, -37, 243, -126, -194, 3, -175, +210, 162, 94, 66, -194, -219, -52, -73, +216, 176, -2, 100, -206, -19, -10, 4, +144, -23, 8, -97, -124, -53, -25, 8, +91, 54, 104, 146, 26, 80, -173, -193, +-131, -216, 170, 125, 170, 218, -71, -45, +-63, -94, 82, 62, 10, 4, -133, -136, +-96, -34, 45, 104, 102, 94, 44, 66, +15, 1, -10, -155, -111, -193, -74, 2, +142, 192, 193, 152, -31, 0, -141, -65, +-15, -35, -10, -70, -91, -118, 15, 10, +149, 167, 95, 84, -114, -72, -145, -36, +93, 72, 146, -52, -87, -165, -139, -6, +112, 133, 197, 81, -59, -1, -154, -8, +31, -3, 75, -34, -110, -101, -145, -106, +114, 103, 242, 257, -22, 13, -179, -270, +37, -94, 111, 160, -149, 40, -102, -64, +189, 80, 158, 65, 12, -123, -109, -66, +-190, 98, -63, -6, 98, -97, 139, 94, +16, 138, -44, -132, 32, -181, -50, 92, +-55, 152, 73, -72, 20, -94, -58, 96, +32, 93, 117, -24, 9, -41, -92, -61, +-52, -115, -20, -53, 3, 131, 15, 211, +38, 78, 47, -158, -47, -229, -65, -39, +52, 115, 118, 52, 16, 50, -63, 185, +5, 89, 2, -274, -24, -344, -47, 22, +-77, 258, 83, 112, 162, -19, -50, 45, +-204, 18, -16, -169, 199, -165, 42, 138, +-80, 309, 59, -16, 66, -387, -78, -161, +-101, 322, 27, 266, 52, -199, -66, -244, +-46, 154, 86, 222, 56, -132, -89, -265, +-42, 72, 108, 299, 83, 7, -36, -263, +-81, 0, 40, 219, 106, -121, -77, -304, +-125, 151, 25, 402, 73, -11, 8, -295, +-53, -32, 10, 132, 59, -130, -58, -198, +-41, 175, 62, 389, 62, 57, 59, -339, +0, -240, -60, 72, -19, 97, -30, -2, +-67, 116, 24, 202, 75, -45, -37, -258, +-14, -131, 57, 16, -61, 31, -54, 174, +157, 264, 113, -41, -150, -378, -133, -201, +144, 238, 135, 312, -104, -3, -104, -251, +4, -204, -19, 9, -36, 143, 66, 128, +135, 105, 55, 85, -102, -72, -168, -244, +14, -191, 208, 22, 101, 191, -119, 230, +-164, 81, 46, -177, 136, -264, -85, -92, +-137, 110, 107, 197, 183, 201, -5, 88, +-158, -157, -132, -282, -21, -111, 126, 80, +148, 107, 7, 122, -95, 95, -23, -107, +85, -235, -29, -44, -100, 176, 71, 187, +76, 134, -76, 25, -122, -212, -36, -308, +25, -68, -33, 162, 39, 123, 249, 34, +191, 50, -110, 49, -230, -31, -53, -81, +70, -14, -46, 74, -138, -22, -14, -165, +162, -32, 183, 215, 42, 133, -144, -149, +-212, -178, -31, -20, 184, 26, 194, 72, +67, 222, -65, 161, -97, -163, -145, -270, +-214, -81, 20, 23, 302, 36, 151, 129, +-117, 135, -94, -23, 29, -95, -13, -49, +-47, -28, 98, 26, 140, 112, -41, 31, +-180, -134, -104, -101, 41, 53, 57, 62, +67, -20, 130, -25, 11, 37, -191, 100, +-80, 85, 168, -38, 55, -125, -140, -89, +-7, -57, 99, -50, -18, 58, -83, 160, +6, 62, 63, -73, 68, -25, 65, 58, +-14, 35, -60, 2, -57, 0, -112, -71, +-49, -183, 65, -156, 77, 19, 32, 215, +49, 263, 97, 94, -12, -99, -166, -92, +-85, -13, 93, -91, 95, -155, -5, 38, +-33, 218, -115, 49, -131, -234, 102, -193, +152, 83, -41, 221, 1, 194, 193, 120, +80, -23, -221, -172, -221, -229, 21, -194, +115, -19, 73, 212, 23, 201, -25, -34, +-76, -108, -70, 26, 48, 84, 145, 51, +86, 29, -48, -21, -74, -122, -39, -170, +-112, -72, -51, 95, 141, 142, 100, 29, +-1, 6, 27, 141, -56, 64, -159, -242, +-24, -249, 175, 107, 111, 266, -45, 51, +-43, -195, -117, -219, -191, -21, 95, 218, +333, 231, 118, 59, -151, -27, -145, -89, +-65, -271, 10, -284, 58, 72, -11, 333, +-16, 153, 61, -64, 41, 1, -54, 73, +-54, -82, 105, -199, 157, -21, -44, 204, +-182, 108, -61, -209, 42, -276, -123, 2, +-71, 219, 363, 237, 280, 196, -358, 5, +-371, -284, 283, -309, 337, -24, -196, 148, +-240, 70, 91, 36, 184, 122, -49, 75, +-274, -147, -55, -188, 269, 93, 169, 243, +-99, -33, -88, -266, 19, -51, -153, 137, +-170, -66, 260, -82, 394, 311, -79, 363, +-411, -182, -127, -476, 157, -93, 44, 208, +-78, 4, 45, -105, 249, 130, 108, 144, +-268, -128, -247, -78, 90, 252, 233, 239, +31, -110, -171, -333, -65, -289, 73, -65, +-1, 167, -53, 169, 128, 67, 245, 151, +-88, 220, -409, -47, -110, -335, 304, -151, +152, 143, -205, -6, -129, -243, 174, -39, +143, 273, -100, 180, -74, -27, 141, 62, +69, 137, -217, -152, -233, -417, 45, -171, +225, 260, 145, 268, -6, -43, -157, -122, +-242, 87, -24, 139, 274, -35, 269, -76, +56, -23, -204, -136, -300, -226, -106, 25, +102, 332, 161, 245, 102, -71, -51, -208, +-174, -103, -64, 41, 142, 112, 97, 72, +-11, -94, 11, -174, -29, -38, -84, 109, +8, 84, 50, 36, -121, 106, -133, 64, +86, -206, 96, -294, -2, 55, -2, 360, +4, 162, 11, -166, -21, -127, -28, 15, +22, -60, 24, -134, -41, -30, -143, 102, +-78, 175, 97, 186, 128, 47, 87, -139, +22, -134, -139, -43, -194, -106, 16, -154, +149, 48, -15, 265, -108, 166, -30, -104, +50, -130, 167, 121, 166, 245, -149, -36, +-324, -400, -29, -313, 173, 89, 0, 243, +-96, 94, 7, 74, 61, 220, 24, 96, +62, -207, 93, -205, -80, -66, -224, -189, +-113, -248, 84, 142, 152, 495, 20, 319, +-101, -37, -17, -136, 109, -128, 113, -211, +-50, -192, -241, -18, -208, 90, -10, 58, +68, 80, 124, 183, 228, 175, 155, 13, +-73, -135, -258, -184, -209, -151, 50, -32, +119, 39, -103, -30, -131, -30, 117, 233, +157, 390, -52, 76, -132, -325, 36, -342, +137, -120, 35, 36, -81, 145, -138, 190, +-128, 65, -127, -77, -80, -6, 295, 130, +464, 89, -53, -77, -433, -225, -220, -264, +-27, -127, -78, 128, 61, 297, 312, 269, +185, 102, -106, -92, -104, -162, 26, -57, +-41, -43, -217, -202, -257, -236, -42, 6, +263, 310, 271, 386, -43, 189, -158, -112, +27, -301, 131, -224, -40, 46, -263, 157, +-249, -82, -38, -248, 175, 65, 236, 420, +119, 212, -13, -235, -117, -228, -158, 89, +-94, 126, -62, -117, -80, -238, -12, -88, +103, 127, 159, 195, 119, 176, -51, 137, +-187, -22, -60, -260, 62, -285, -119, -5, +-207, 213, 43, 108, 202, -114, 49, -123, +-63, 102, -17, 237, 5, 83, -1, -154, +-101, -146, -194, 26, -44, 21, 107, -126, +73, -59, 31, 160, 66, 139, 52, -60, +-71, -66, -211, 64, -182, 38, -1, -55, +87, -37, 1, -20, -46, -111, 51, -119, +188, 151, 140, 364, -147, 122, -279, -275, +-151, -248, -87, 45, -20, 40, 171, -134, +250, -19, 21, 215, -188, 141, -77, -64, +40, -32, -48, 61, -176, -13, -139, -102, +103, -66, 219, -54, 13, -134, -171, -68, +-34, 206, 151, 347, 41, 134, -162, -192, +-233, -253, -148, -35, 96, 111, 214, -20, +8, -184, -184, -40, -27, 251, 197, 246, +60, -61, -229, -231, -239, -76, 13, 112, +145, 85, 43, -47, -41, -82, -54, -46, +-64, 4, -64, 71, -62, 96, 5, 20, +75, -82, 38, -65, -28, 78, -48, 113, +-35, -101, -27, -250, 5, 7, -54, 315, +-200, 114, -126, -294, 80, -229, 126, 222, +96, 351, 100, -12, 21, -315, -194, -175, +-289, 162, -58, 193, 166, -97, -6, -205, +-274, 41, -55, 180, 330, -13, 234, -126, +-159, 85, -283, 208, -12, -22, 115, -210, +-149, -92, -251, 46, 20, -8, 220, -61, +89, 41, -100, 149, -67, 91, 21, -68, +-70, -85, -218, 29, -117, 11, 206, -104, +258, -47, -81, 115, -262, 127, -103, 1, +49, -116, -37, -138, -175, -29, -76, 100, +174, 92, 222, 52, -7, 67, -148, -10, +-54, -153, -92, -113, -174, 60, -15, 64, +22, -65, -150, -39, -74, 128, 230, 135, +265, -39, -25, -117, -249, -32, -185, 4, +27, -19, -25, -19, -276, -62, -127, -31, +324, 197, 338, 279, -94, -70, -310, -334, +-161, -77, -34, 196, -23, 23, 6, -209, +44, -65, 25, 171, -34, 142, -19, 46, +62, 64, 29, 11, -221, -136, -369, -145, +-72, -79, 252, -85, 146, 19, -48, 202, +36, 165, 140, 11, -76, 6, -302, 2, +-204, -104, -40, -111, -44, -55, -48, -122, +100, -98, 199, 167, 117, 293, 29, 97, +-54, -40, -185, 56, -265, 10, -291, -293, +-200, -367, 77, -20, 347, 233, 354, 85, +131, -34, -117, 226, -306, 434, -336, 99, +-137, -410, 9, -437, -27, -96, 7, -2, +96, -154, 113, -5, 149, 405, 93, 522, +-206, 271, -339, -99, -114, -460, -2, -571, +-75, -189, -46, 265, 51, 212, 188, -53, +221, 107, -78, 460, -350, 285, -171, -291, +32, -498, -87, -257, -72, -69, 175, 16, +151, 235, -87, 366, -128, 175, -80, -54, +-176, -75, -149, -70, 95, -198, 223, -256, +83, -70, -199, 162, -251, 186, 23, 55, +156, 76, -22, 240, -230, 114, -198, -317, +35, -479, 138, -95, 24, 313, -56, 185, +72, -171, 127, -52, -159, 430, -350, 389, +-187, -297, -18, -683, 35, -261, 149, 335, +253, 355, 40, -17, -253, -152, -215, 112, +-39, 334, -10, 76, -105, -423, -81, -487, +96, 18, 137, 397, -24, 174, -134, -131, +-13, 16, 49, 212, -216, -13, -316, -292, +7, -131, 278, 192, 190, 138, -76, -183, +-139, -215, -103, 162, -176, 379, -58, 81, +125, -269, -44, -231, -293, -31, -36, 1, +385, 21, 190, 154, -246, 186, -260, 51, +-60, -39, 3, -42, -91, -180, -137, -333, +23, -117, 191, 350, 98, 437, -125, 3, +-89, -290, 18, -77, -190, 179, -256, 21, +54, -270, 217, -214, 43, 76, -177, 195, +-125, 138, 128, 152, 172, 150, -127, -93, +-389, -373, -195, -315, 115, 6, 110, 187, +109, 175, 151, 176, -54, 108, -229, -48, +-154, -30, -49, 50, -73, -216, -127, -509, +-22, -150, 177, 459, 208, 431, -13, -37, +-253, -136, -143, 150, 146, 199, 14, -192, +-349, -548, -299, -376, 72, 156, 298, 440, +249, 305, 58, 112, -188, 87, -339, 28, +-178, -209, 67, -423, 25, -387, -192, -67, +-106, 288, 298, 404, 372, 278, -33, 104, +-348, 9, -317, -91, -141, -255, -81, -352, +-24, -289, 170, -31, 196, 319, 25, 430, +-38, 144, 30, -87, -51, 91, -300, 154, +-335, -272, -134, -606, 76, -292, 250, 311, +249, 492, 48, 173, -148, -133, -165, -55, +-88, 166, -144, 88, -208, -255, -83, -474, +128, -253, 238, 318, 132, 607, -79, 189, +-211, -331, -188, -198, -87, 221, 15, 128, +54, -330, -92, -423, -138, -17, 113, 365, +229, 375, 30, 146, -203, -91, -209, -214, +-94, -165, -113, -36, -96, -33, 52, -128, +176, -16, 238, 257, 83, 317, -218, 94, +-341, -145, -198, -215, 41, -161, 90, -89, +-35, -19, -102, 95, -7, 148, 158, 81, +153, 59, 17, 118, -146, 70, -320, -116, +-297, -276, -43, -293, 174, -81, 170, 255, +37, 345, 5, 89, 10, -102, -58, 39, +-156, 165, -208, -113, -115, -478, -24, -327, +5, 178, 127, 393, 258, 264, 157, 162, +-233, -4, -457, -339, -193, -369, 132, -2, +151, 154, 19, -23, -52, 8, -37, 271, +39, 250, 70, -70, -38, -232, -187, -97, +-255, -5, -156, -151, 83, -205, 290, 111, +248, 454, -103, 285, -399, -212, -240, -370, +139, -9, 272, 285, -24, 53, -405, -348, +-275, -310, 245, 165, 459, 514, 88, 277, +-368, -267, -301, -407, 33, -2, 47, 268, +-122, -6, -116, -317, 61, -132, 181, 313, +148, 420, 9, 51, -181, -347, -287, -279, +-174, 109, 49, 172, 126, -156, -13, -253, +-93, 144, 99, 457, 240, 151, -20, -343, +-331, -287, -283, 135, 30, 187, 166, -96, +-62, -133, -198, 39, 38, 49, 277, -4, +145, 92, -141, 151, -208, 17, -184, -117, +-189, -149, -67, -121, 136, -33, 220, 63, +79, 67, -79, 49, 2, 169, 41, 268, +-161, 13, -360, -420, -235, -490, 180, -56, +315, 386, 69, 394, -39, 71, -22, -173, +-72, -159, -196, -34, -199, 5, 48, -33, +141, 2, 6, 158, -52, 193, -43, -118, +-59, -459, -80, -273, 54, 398, 196, 750, +8, 258, -305, -568, -313, -830, -1, -258, +229, 502, 178, 725, 40, 337, -82, -223, +-162, -568, -155, -491, -64, 26, 63, 524, +64, 476, -61, -51, -80, -511, 74, -515, +155, 47, -6, 791, -153, 830, -124, -207, +-120, -1254, -160, -940, -37, 474, 251, 1293, +303, 601, -45, -612, -268, -854, -142, -52, +28, 611, 40, 366, -61, -311, -168, -606, +-72, -252, 205, 423, 194, 734, -179, 220, +-276, -564, 113, -632, 364, 92, 18, 602, +-462, 259, -450, -431, 34, -562, 481, 26, +456, 588, -29, 443, -521, -191, -524, -527, +24, -211, 536, 319, 375, 389, -214, -67, +-464, -479, -218, -303, 209, 284, 337, 602, +15, 236, -280, -466, -224, -636, -6, 4, +121, 636, 135, 349, 70, -403, -73, -440, +-120, 201, -85, 436, -118, -65, -33, -388, +171, -110, 90, 226, -176, 221, -165, 4, +137, -208, 281, -202, -38, 109, -403, 329, +-250, 35, 225, -333, 390, -174, -37, 276, +-472, 236, -263, -273, 331, -372, 545, 265, +-12, 695, -665, 72, -468, -877, 322, -734, +629, 486, 106, 1153, -509, 300, -458, -967, +193, -864, 626, 430, 170, 1041, -688, 135, +-722, -960, 227, -679, 963, 537, 453, 1036, +-671, 131, -884, -918, 11, -663, 771, 498, +467, 928, -439, 4, -744, -974, -147, -644, +529, 644, 507, 1149, -52, 123, -380, -1013, +-181, -693, 19, 461, -84, 694, -91, -180, +111, -637, 252, 26, 136, 736, -191, 415, +-312, -459, 2, -704, 307, -56, 37, 520, +-459, 232, -310, -370, 347, -271, 555, 367, +50, 464, -462, -106, -268, -432, 243, -133, +153, 184, -384, -11, -346, -278, 266, -24, +625, 504, 228, 457, -446, -175, -569, -531, +-80, -304, 379, 82, 284, 284, -170, 274, +-301, -46, -85, -381, 196, -242, 245, 309, +92, 566, -135, 172, -317, -455, -160, -598, +145, -38, 158, 524, -44, 259, -183, -511, +-48, -534, 254, 477, 344, 1128, 14, 355, +-427, -990, -501, -1180, -112, -56, 334, 837, +423, 507, 215, -204, -83, -103, -347, 343, +-413, 25, -156, -679, 384, -457, 620, 639, +163, 959, -596, -240, -793, -1451, -128, -755, +639, 1259, 702, 1875, 221, 100, -285, -1715, +-658, -1311, -723, 335, -114, 1005, 884, 484, +1162, 50, 83, -45, -1321, -343, -1330, -665, +337, -203, 1748, 733, 994, 825, -1070, -229, +-1800, -1057, -274, -486, 1420, 750, 1227, 1027, +-273, 17, -1129, -946, -636, -694, 310, 277, +673, 652, 301, 189, -267, -196, -439, -47, +-197, 71, 154, -165, 355, -210, 273, 162, +-98, 335, -470, -153, -359, -590, 193, -137, +515, 766, 169, 803, -398, -311, -459, -1144, +119, -487, 588, 833, 274, 919, -468, -323, +-620, -1016, -19, -113, 531, 927, 405, 511, +-125, -603, -393, -636, -189, 305, 105, 542, +229, -255, 114, -636, -197, 141, -367, 757, +-31, 106, 528, -703, 442, -189, -295, 823, +-741, 378, -253, -1026, 625, -988, 607, 682, +-353, 1420, -753, 111, 19, -1195, 787, -600, +347, 744, -657, 716, -652, -527, 312, -904, +705, 261, 28, 1086, -596, 213, -264, -892, +406, -492, 319, 474, -211, 339, -276, -301, +73, -156, 202, 337, -14, 121, -182, -335, +-39, -141, 52, 305, 15, 150, 112, -226, +173, -85, -63, 208, -393, -105, -265, -486, +272, 9, 413, 785, 5, 533, -279, -586, +-110, -1012, 197, 0, 118, 1112, -259, 662, +-348, -942, 136, -1321, 487, 306, 174, 1660, +-402, 648, -394, -1271, 210, -1227, 450, 553, +-98, 1315, -495, 19, -82, -1301, 535, -732, +370, 927, -401, 1419, -736, 32, -46, -1343, +802, -885, 582, 658, -456, 1098, -894, 38, +-81, -952, 784, -587, 487, 549, -454, 917, +-716, 90, 29, -787, 650, -567, 322, 276, +-367, 665, -467, 240, 57, -402, 376, -522, +91, -8, -312, 510, -251, 321, 156, -272, +357, -441, 150, 39, -233, 434, -402, 112, +-172, -466, 432, -317, 559, 491, -240, 708, +-832, -229, -282, -1011, 778, -356, 859, 863, +-298, 797, -1049, -408, -364, -791, 756, 125, +678, 650, -362, -46, -672, -638, 29, -134, +541, 505, 204, 257, -299, -180, -314, 34, +72, 91, 226, -477, -16, -475, -223, 658, +-101, 919, 207, -522, 333, -1307, 13, 205, +-337, 1610, -279, 371, 138, -1590, 292, -1023, +-39, 1174, -348, 1397, -146, -613, 363, -1440, +468, 118, -116, 1291, -638, 186, -179, -1057, +597, -334, 405, 987, -488, 481, -781, -988, +71, -921, 951, 636, 519, 1307, -622, 196, +-832, -1021, 160, -822, 748, 288, 35, 814, +-674, 176, -152, -513, 706, -297, 375, 347, +-725, 226, -774, -325, 559, -184, 1226, 505, +58, 436, -1353, -573, -982, -908, 686, 147, +1383, 1101, 257, 414, -939, -923, -610, -776, +429, 688, 453, 1168, -306, -274, -546, -1402, +132, -420, 678, 1190, 231, 837, -517, -829, +-466, -1078, 307, 554, 607, 1511, -79, 188, +-729, -1540, -378, -1167, 489, 780, 743, 1409, +36, -44, -682, -1149, -504, -240, 312, 1006, +719, 536, 209, -696, -536, -653, -588, 333, +-24, 434, 443, -448, 431, -622, 12, 421, +-336, 1111, -270, 318, 141, -950, 274, -909, +-84, 245, -323, 885, -37, 269, 305, -573, +243, -617, -167, 24, -259, 655, 38, 621, +247, -65, 76, -701, -239, -456, -329, 222, +25, 328, 428, -88, 371, -80, -131, 366, +-518, 185, -241, -480, 354, -420, 371, 545, +-104, 655, -330, -558, -58, -1105, 255, 239, +122, 1404, -161, 272, -54, -1325, 216, -624, +13, 1198, -350, 895, -178, -1075, 318, -1240, +397, 698, -84, 1439, -359, -169, -67, -1237, +299, -188, 120, 882, -363, 235, -275, -613, +308, -167, 438, 433, -13, 6, -349, -412, +-85, 189, 248, 655, 79, -164, -315, -891, +-220, -189, 322, 888, 472, 450, -92, -659, +-486, -588, -78, 417, 421, 626, 73, -167, +-485, -526, -112, 24, 636, 487, 391, 67, +-625, -610, -658, -473, 479, 491, 896, 1048, +-209, 211, -1034, -1139, -224, -1096, 962, 611, +673, 1618, -567, 230, -801, -1754, 218, -1247, +786, 1309, 107, 2164, -723, -125, -455, -2293, +424, -1176, 694, 1512, 137, 1850, -540, -449, +-464, -1954, 248, -561, 640, 1641, 63, 1439, +-735, -755, -483, -1773, 633, -252, 940, 1272, +-133, 753, -1009, -606, -343, -659, 774, 249, +658, 418, -440, -114, -777, -169, 6, 269, +733, 27, 495, -602, -286, -324, -628, 673, +-261, 683, 400, -374, 665, -693, 89, 205, +-717, 704, -633, -130, 482, -861, 1091, -243, +106, 742, -1142, 592, -705, -401, 871, -629, +1217, 200, -281, 792, -1435, 88, -451, -1001, +1287, -793, 1134, 688, -607, 1377, -1327, 137, +-101, -1369, 1086, -886, 574, 917, -614, 1358, +-660, -268, 178, -1487, 552, -515, 158, 1133, +-88, 1086, -54, -332, -272, -1058, -390, -407, +240, 498, 786, 631, 176, 223, -847, -314, +-534, -645, 817, -379, 1021, 578, -431, 1047, +-1315, -34, -188, -1339, 1166, -740, 657, 1163, +-716, 1411, -719, -554, 543, -1740, 798, -216, +-330, 1614, -809, 846, 106, -1240, 807, -1242, +190, 776, -706, 1477, -446, -198, 524, -1539, +794, -448, -3, 1222, -746, 988, -489, -639, +430, -1150, 721, 15, 27, 1038, -663, 449, +-277, -773, 670, -787, 669, 392, -425, 923, +-943, 15, -60, -772, 957, -365, 525, 470, +-588, 468, -625, -7, 379, -350, 752, -382, +-96, -43, -765, 565, -190, 557, 702, -449, +474, -987, -547, 47, -628, 1141, 445, 357, +957, -1009, 50, -578, -829, 871, -506, 649, +385, -842, 596, -777, 68, 795, -386, 999, +-186, -659, 284, -1263, 484, 316, 86, 1513, +-539, 395, -596, -1305, 278, -1192, 937, 413, +252, 1361, -898, 590, -568, -843, 861, -1090, +1134, 242, -499, 1284, -1510, 354, -251, -1326, +1440, -1138, 971, 803, -686, 1593, -1023, 140, +62, -1288, 765, -728, 368, 607, -267, 815, +-337, 44, -137, -563, 116, -572, 260, -93, +267, 604, 35, 767, -187, -65, -67, -919, +120, -478, 61, 709, -165, 831, -146, -441, +192, -1182, 383, -138, 255, 1223, -176, 839, +-422, -700, -165, -1105, 372, 124, 515, 1007, +-63, 291, -638, -909, -299, -824, 680, 516, +846, 1233, -152, 241, -898, -1202, -416, -830, +650, 937, 726, 1320, -178, -597, -753, -1801, +-103, -145, 819, 1885, 572, 954, -463, -1458, +-666, -1352, 68, 972, 467, 1585, 68, -558, +-145, -1759, 242, -71, 224, 1643, -393, 606, +-292, -1226, 602, -886, 690, 859, -460, 1054, +-1104, -368, -77, -1069, 1169, -222, 854, 661, +-554, 440, -1016, -164, 46, -358, 990, -39, +508, 362, -662, 354, -817, -307, 112, -718, +780, -109, 408, 662, -268, 305, -364, -369, +153, -39, 519, 467, 116, -79, -695, -745, +-670, -175, 466, 715, 1317, 370, 400, -471, +-1185, -456, -1195, 246, 736, 469, 1801, 141, +279, -256, -1794, -437, -1248, -192, 1179, 423, +1835, 483, -132, -277, -1571, -670, -461, 171, +1213, 885, 883, 148, -726, -918, -1072, -531, +244, 635, 1157, 698, 403, -386, -753, -790, +-625, 122, 430, 922, 757, 431, -37, -775, +-628, -955, -288, 213, 362, 1107, 564, 380, +280, -989, -248, -819, -526, 648, -69, 1142, +623, -103, 412, -1085, -539, -334, -719, 709, +367, 372, 1178, -442, 314, -264, -995, 320, +-814, 225, 524, -166, 1014, 29, 141, 153, +-801, -256, -544, -444, 509, 94, 936, 627, +192, 180, -750, -541, -724, -390, 344, 532, +966, 752, 283, -341, -767, -1226, -621, -234, +519, 1299, 965, 901, 68, -1073, -800, -1357, +-458, 717, 466, 1698, 656, -74, -35, -1779, +-459, -639, -197, 1271, 464, 999, 614, -649, +-49, -868, -774, 218, -434, 655, 640, -12, +841, -335, -154, -37, -809, 15, 9, -182, +909, -17, 377, 468, -785, 264, -712, -478, +448, -516, 858, 362, 1, 760, -566, -126, +-18, -962, 640, -361, 249, 804, -434, 817, +-453, -325, 84, -941, 436, -112, 260, 852, +-60, 478, -216, -689, 47, -811, 405, 293, +206, 865, -367, 112, -359, -586, 254, -184, +402, 462, -210, 131, -339, -594, 360, -399, +769, 566, 86, 774, -651, -293, -496, -972, +348, -9, 562, 1126, -94, 372, -536, -1217, +74, -884, 931, 966, 471, 1296, -782, -444, +-909, -1359, 431, -81, 1078, 1217, 48, 590, +-1043, -914, -330, -1146, 1067, 216, 944, 1485, +-574, 812, -1201, -1272, 54, -1826, 1239, 491, +567, 2407, -900, 717, -993, -2293, 391, -1815, +1256, 1360, 505, 2266, -728, -213, -892, -1942, +116, -630, 869, 1215, 521, 1054, -567, -293, +-874, -986, 124, -572, 1272, 377, 874, 886, +-875, 339, -1546, -726, 82, -712, 1675, 493, +839, 955, -1232, -129, -1366, -1157, 573, -472, +1859, 818, 526, 913, -1463, -97, -1303, -754, +656, -405, 1618, 354, 159, 545, -1463, -16, +-764, -585, 1335, -265, 1617, 538, -552, 428, +-1842, -427, -397, -571, 1575, 397, 1107, 777, +-837, -153, -1428, -863, 115, -295, 1531, 480, +1038, 500, -738, 148, -1562, -185, -385, -622, +1345, -509, 1278, 744, -512, 1273, -1513, -285, +-199, -1916, 1382, -552, 1042, 1941, -612, 1467, +-1145, -1334, -88, -1939, 768, 424, 387, 1776, +-288, 297, -156, -1189, 336, -516, 77, 589, +-371, 387, -21, -332, 701, -104, 367, 306, +-757, -73, -876, -481, 409, 37, 1292, 706, +435, 280, -863, -617, -906, -554, 279, 298, +991, 442, 420, -158, -638, -357, -840, 304, +188, 482, 1076, -231, 584, -683, -629, 4, +-934, 807, 64, 339, 921, -855, 483, -917, +-557, 454, -694, 1376, 285, 372, 1027, -1215, +354, -1033, -928, 670, -1000, 1277, 500, -114, +1497, -1301, 362, -367, -1398, 997, -1022, 638, +1046, -598, 1620, -568, -287, 465, -1664, 568, +-384, -334, 1431, -697, 1015, -87, -802, 453, +-1224, 310, 213, -20, 1206, -112, 475, -112, +-736, -2, -609, 188, 328, 66, 609, -400, +13, -535, -369, 146, -92, 826, 284, 602, +208, -323, -61, -911, -91, -474, 57, 589, +125, 896, -2, -72, -8, -1122, 54, -511, +28, 1032, 22, 1186, 133, -376, 73, -1362, +-142, -455, -185, 840, 221, 745, 481, -186, +126, -571, -446, -156, -422, 253, 251, 228, +648, 145, 235, 47, -511, -348, -643, -623, +168, 4, 954, 1047, 708, 629, -477, -1017, +-1145, -1212, -383, 783, 946, 1689, 1091, -310, +-273, -2018, -1104, -310, -226, 1896, 967, 903, +657, -1522, -414, -1222, -640, 1043, -17, 1374, +417, -436, 240, -1333, -4, -154, -57, 934, +-98, 497, -78, -537, 193, -569, 384, 246, +69, 723, -473, 80, -373, -733, 258, -456, +732, 507, 341, 578, -529, -417, -719, -639, +112, 467, 908, 986, 532, -235, -547, -1256, +-878, -191, 1, 1225, 863, 392, 604, -1280, +-240, -675, -639, 1392, -291, 1266, 363, -1032, +701, -1612, 199, 344, -643, 1499, -609, 116, +441, -1249, 908, -601, 1, 789, -811, 1043, +-193, 207, 758, -842, 414, -1066, -604, 16, +-567, 1272, 440, 704, 752, -1112, -22, -1261, +-545, 724, -124, 1698, 432, 68, 176, -1599, +-222, -839, -154, 934, 153, 1038, 160, -301, +12, -943, 80, -105, 226, 706, 26, 470, +-333, -260, -322, -453, 237, -235, 565, 26, +132, 275, -479, 354, -250, -91, 439, -453, +652, 44, -122, 632, -883, -18, -431, -950, +817, -233, 995, 1205, -293, 654, -1109, -1339, +-80, -1263, 1090, 1193, 567, 2033, -771, -454, +-754, -2495, 441, -721, 710, 2188, -196, 1778, +-543, -1355, 280, -2344, 661, 221, 4, 2508, +-615, 1039, -231, -1910, 389, -2100, 303, 692, +-180, 2242, -159, 488, 267, -1725, 333, -1131, +-40, 1077, -288, 1500, -181, -326, 95, -1583, +172, -552, 133, 1145, 72, 1129, -7, -457, +-30, -1283, -51, -230, 141, 1199, 157, 938, +-70, -601, -259, -1314, -59, -323, 163, 884, +185, 853, 176, -109, 250, -698, -81, -422, +-488, 303, -329, 656, 543, 212, 678, -604, +-203, -733, -878, 158, -114, 844, 931, 359, +709, -673, -466, -549, -865, 439, -38, 735, +717, -226, 336, -728, -430, -91, -452, 539, +274, 32, 578, -429, 135, 104, -348, 606, +-115, 76, 257, -551, -26, -177, -523, 203, +-185, -150, 721, -216, 917, 564, -216, 627, +-1172, -595, -495, -1099, 1062, 368, 1215, 1465, +-444, 171, -1620, -1644, -497, -998, 1448, 1289, +1479, 1607, -429, -443, -1641, -1706, -492, -287, +1271, 1359, 1078, 769, -535, -894, -1338, -951, +-187, 366, 1201, 872, 932, -49, -562, -643, +-1006, -52, 81, 653, 847, 179, 185, -754, +-614, -557, -376, 709, 302, 927, 502, -456, +281, -1217, -46, 192, -338, 1438, -483, 213, +44, -1571, 684, -753, 379, 1428, -587, 1285, +-710, -965, 428, -1561, 1087, 344, 209, 1558, +-945, 221, -744, -1329, 450, -730, 881, 995, +64, 1192, -785, -465, -397, -1552, 839, -277, +971, 1655, -357, 1235, -1357, -1361, -394, -2163, +1213, 363, 1104, 2642, -575, 1054, -1383, -2124, +-115, -2169, 1339, 828, 1036, 2393, -658, 575, +-1486, -1811, -318, -1609, 1259, 590, 1225, 1971, +-476, 936, -1596, -1343, -478, -2005, 1496, -40, +1613, 2112, -577, 1410, -2103, -1332, -709, -2224, +1746, -40, 1755, 2137, -760, 1436, -2087, -1090, +-308, -2042, 2041, -291, 1396, 1753, -1248, 1308, +-2095, -1124, 129, -1907, 2094, 240, 1019, 2110, +-1443, 835, -1654, -1681, 510, -1444, 1987, 850, +720, 1515, -1509, -268, -1751, -1467, 365, -316, +1998, 1230, 1042, 1046, -1191, -407, -1799, -1286, +16, -586, 1848, 824, 1241, 1120, -1065, -154, +-2008, -1294, -176, -526, 1914, 1062, 1430, 1111, +-858, -228, -1857, -1015, -302, -493, 1585, 137, +1155, 334, -772, 508, -1391, 378, -23, -411, +1151, -905, 581, -22, -542, 1117, -616, 501, +112, -1059, 542, -1010, 173, 695, -242, 1327, +-308, -120, -90, -1297, 230, -435, 377, 903, +139, 854, -165, -340, -189, -813, -32, -236, +12, 535, 31, 341, 123, -322, 122, -401, +-21, 363, -89, 695, 130, -109, 229, -904, +-92, -535, -440, 580, -92, 914, 471, 144, +424, -835, -219, -717, -460, 446, 35, 1126, +447, 46, 180, -1347, -235, -692, -263, 1271, +43, 1350, 141, -875, 113, -1834, 213, 191, +87, 2055, -252, 757, -354, -1790, 84, -1743, +534, 834, 210, 2230, -365, 570, -441, -1909, +223, -1725, 542, 920, 93, 2302, -490, 290, +-231, -2345, 433, -1461, 494, 1806, -255, 2467, +-664, -675, -105, -2853, 603, -758, 584, 2295, +-20, 1797, -538, -974, -514, -1982, 83, -381, +647, 1207, 505, 1237, -350, 140, -770, -1196, +-48, -1360, 885, 265, 563, 1900, -624, 966, +-870, -1573, 159, -1911, 940, 624, 385, 2260, +-713, 570, -694, -1879, 374, -1547, 1019, 929, +154, 1890, -979, 241, -640, -1619, 701, -1157, +998, 787, -234, 1537, -1048, 307, -222, -1282, +1003, -1045, 706, 491, -474, 1282, -919, 266, +-62, -1050, 641, -837, 521, 478, -146, 1094, +-551, 287, -264, -754, 442, -799, 662, 30, +35, 638, -693, 548, -534, -85, 340, -551, +749, -514, 217, 104, -528, 753, -493, 536, +246, -401, 763, -950, 302, -161, -673, 813, +-1010, 533, 75, -614, 1346, -771, 980, 359, +-765, 1157, -1629, 268, -179, -1125, 1686, -1112, +1221, 442, -1032, 1449, -1977, 343, -70, -1243, +1971, -942, 1299, 945, -981, 1448, -1760, -358, +-152, -1605, 1420, -466, 964, 1276, -569, 914, +-1160, -697, -322, -1043, 829, 158, 972, 950, +80, 405, -860, -499, -680, -526, 255, -118, +794, 82, 272, 43, -475, 292, -470, 550, +237, 72, 571, -862, 143, -791, -428, 543, +-402, 1378, 165, 171, 562, -1489, 143, -1109, +-512, 837, -386, 1695, 478, 300, 695, -1222, +-104, -1153, -766, 106, -268, 1045, 551, 890, +495, -209, -322, -1210, -436, -922, 189, 734, +521, 1642, 171, 502, -390, -1376, -491, -1547, +-98, 156, 586, 1451, 639, 999, -178, -409, +-842, -1104, -299, -634, 777, 335, 767, 891, +-360, 533, -928, -346, -87, -769, 753, -374, +430, 248, -277, 522, -383, 415, -107, 68, +237, -550, 401, -753, 193, -23, -449, 988, +-622, 821, 159, -597, 938, -1358, 344, -239, +-729, 1392, -592, 1238, 419, -801, 591, -1909, +-107, -411, -353, 1844, 114, 1603, 146, -908, +-300, -2157, -258, -307, 534, 1868, 815, 1260, +-214, -1168, -1015, -1645, -420, 307, 671, 1527, +761, 357, -33, -1113, -633, -554, -266, 687, +320, 623, 442, -487, 38, -696, -365, 154, +-200, 698, 118, 223, 187, -455, -54, -411, +-75, 192, 295, 524, 231, -4, -252, -603, +-402, -375, 145, 585, 308, 701, -159, -310, +-276, -900, 345, 4, 591, 1073, -258, 454, +-757, -1035, 54, -1128, 830, 488, 248, 1420, +-744, 330, -523, -1160, 419, -754, 741, 721, +162, 955, -446, -429, -401, -1079, 73, -56, +316, 1073, 170, 474, -177, -700, -178, -687, +57, 397, 325, 661, 118, -147, -208, -563, +-171, 68, 42, 369, 205, -275, -3, -478, +-261, 507, -163, 1046, 392, -181, 608, -1373, +-58, -612, -894, 1069, -586, 1090, 744, -426, +1116, -1105, -152, -158, -1374, 833, -498, 571, +1236, -249, 1267, -596, -686, -414, -1630, -10, +-140, 577, 1558, 824, 893, 6, -1140, -1187, +-1381, -1089, 489, 805, 1670, 1905, 514, 589, +-1401, -1867, -1401, -2087, 469, 351, 1800, 2486, +751, 1675, -1356, -1138, -1692, -2518, 368, -935, +2003, 1608, 963, 2031, -1332, 165, -1816, -1555, +17, -1322, 1787, 128, 1220, 1112, -778, 1069, +-1680, 86, -495, -1012, 1474, -1300, 1461, -41, +-465, 1352, -1865, 1171, -669, -430, 1555, -1344, +1541, -548, -647, 636, -1840, 893, -325, 192, +1575, -457, 1144, -676, -876, -188, -1442, 396, +72, 671, 1187, 136, 485, -413, -735, -417, +-623, -96, 403, 100, 666, 176, -139, 386, +-639, 195, -210, -411, 525, -654, 344, 58, +-284, 732, -394, 464, 299, -310, 526, -638, +-228, -432, -865, 7, -138, 720, 1042, 1019, +889, 79, -645, -1405, -1481, -1266, -458, 608, +1398, 1791, 1689, 611, -53, -1224, -1948, -1351, +-1714, 85, 601, 1157, 2548, 829, 1561, -207, +-1403, -842, -2871, -676, -794, 28, 2382, 639, +2561, 739, -380, 239, -2778, -609, -1610, -1068, +1404, -384, 2496, 1054, 509, 1466, -1714, -73, +-1619, -1747, 199, -1275, 1391, 898, 838, 1920, +-372, 609, -864, -1324, -543, -1595, 153, -123, +748, 1450, 790, 1408, -51, -282, -1203, -1866, +-1098, -1261, 528, 1159, 1819, 2371, 823, 514, +-1456, -2286, -1974, -2203, 204, 838, 2193, 2856, +1242, 1110, -1397, -1997, -2052, -2429, 42, 157, +1865, 2256, 1040, 1543, -862, -640, -1307, -1835, +-120, -1182, 831, 372, 592, 1576, -162, 1411, +-454, -181, -265, -1686, 114, -1528, 349, 333, +299, 1695, -65, 1277, -448, -434, -229, -1500, +263, -1048, 371, 388, 34, 1287, -321, 890, +-220, -368, 116, -1014, 445, -477, 397, 296, +-367, 355, -950, -52, -350, 121, 1097, 540, +1211, 196, -481, -869, -1727, -1036, -533, 189, +1553, 1495, 1479, 990, -657, -882, -1918, -1831, +-461, -533, 1515, 1692, 1170, 1835, -772, -428, +-1341, -2363, 186, -1085, 1346, 1718, 186, 2222, +-1199, -418, -737, -2494, 880, -1131, 1100, 1714, +-201, 2241, -1001, -76, -486, -2145, 365, -1499, +700, 899, 488, 2057, -42, 666, -909, -1530, +-1022, -1706, 110, 354, 1583, 1841, 1394, 901, +-571, -1102, -2104, -1478, -1314, -115, 1110, 1091, +2388, 898, 1059, 46, -1665, -767, -2623, -1011, +-592, -395, 2318, 1050, 2700, 1769, -74, 275, +-2863, -2087, -2287, -2125, 734, 697, 2784, 2870, +1761, 1460, -996, -1700, -2595, -2540, -1588, -446, +1109, 1749, 2739, 1723, 1475, 126, -1645, -1251, +-2974, -1480, -845, -293, 2230, 1236, 2532, 1571, +7, 118, -2217, -1485, -1844, -1347, 236, 203, +1834, 1348, 1463, 1058, -112, -148, -1631, -1083, +-1550, -1098, 208, -54, 1859, 1203, 1412, 1273, +-653, -184, -2076, -1679, -961, -1195, 1402, 984, +2034, 2215, -81, 616, -2137, -2054, -1106, -2365, +1574, 403, 1984, 2903, -546, 1806, -2283, -1521, +-703, -3039, 1805, -791, 1745, 2242, -569, 2539, +-1900, -79, -866, -2326, 1019, -1918, 1596, 438, +432, 2015, -1111, 1403, -1399, -424, -146, -1527, +1290, -932, 1207, 299, -416, 921, -1600, 503, +-734, -86, 1146, -308, 1534, -269, -118, -265, +-1681, -217, -1086, 273, 950, 754, 1743, 615, +264, -407, -1527, -1276, -1463, -887, 465, 634, +1600, 1633, 685, 941, -1023, -821, -1116, -1741, +187, -714, 846, 981, 221, 1636, -332, 400, +-236, -1209, -17, -1503, 10, -62, 94, 1518, +191, 1435, -152, -395, -367, -1847, 159, -1162, +843, 1010, 279, 2007, -972, 454, -1152, -1742, +194, -1727, 1582, 621, 1321, 2232, -554, 974, +-2116, -1599, -1476, -2170, 1139, -122, 2791, 1994, +1385, 1822, -1934, -349, -3228, -2124, -920, -1673, +2601, 628, 3398, 2540, 545, 1683, -3111, -1203, +-3680, -3085, -233, -1513, 3751, 1915, 3730, 3405, +-570, 1178, -4331, -2408, -3183, -3437, 1545, -768, +4191, 2695, 2024, 3183, -2158, 231, -3492, -2821, +-927, -2650, 2036, 340, 2263, 2698, -18, 1978, +-1404, -721, -781, -2247, 407, -1362, -7, 622, +-692, 1528, 200, 1052, 1818, -6, 1084, -892, +-1945, -1201, -3099, -625, 39, 687, 3756, 1457, +2857, 799, -1902, -724, -4316, -1468, -1399, -743, +3105, 664, 3657, 1452, 116, 849, -3169, -702, +-2692, -1715, 469, -908, 2807, 1114, 2221, 2046, +-531, 486, -2583, -1792, -2019, -1917, 727, 383, +2708, 2195, 1770, 1165, -1148, -1141, -2648, -1755, +-1266, -303, 1490, 894, 2320, 716, 689, 367, +-1419, 470, -1961, -308, -629, -1755, 1245, -1514, +1930, 1205, 636, 3091, -1304, 1148, -2040, -2325, +-600, -2993, 1336, -233, 1718, 2354, 398, 2102, +-1174, -43, -1491, -1708, -434, -1575, 976, -71, +1343, 1345, 189, 1261, -1202, -86, -991, -1045, +480, -560, 1048, 220, -109, 252, -1067, -257, +-145, 9, 1332, 758, 738, 809, -1176, -322, +-1657, -1613, 188, -1309, 1823, 744, 1239, 2426, +-731, 1523, -1657, -1507, -844, -3059, 707, -1052, +1358, 2290, 872, 3109, -329, 501, -1249, -2611, +-1065, -3040, 189, -371, 1467, 2861, 1337, 3296, +-298, 34, -1887, -3568, -1346, -3194, 934, 1100, +2190, 4234, 816, 2221, -1587, -2473, -2051, -4248, +76, -973, 1967, 3388, 1360, 3923, -891, -49, +-2051, -4024, -651, -3455, 1429, 1210, 1793, 4550, +73, 2438, -1813, -2561, -1661, -4362, 303, -901, +1789, 3244, 1283, 3197, -462, -229, -1539, -2575, +-1084, -1825, 279, 216, 964, 1257, 775, 1188, +146, 516, -396, -461, -703, -1162, -831, -1008, +-327, 200, 844, 1157, 1686, 1219, 862, 210, +-1327, -1198, -2495, -1729, -1000, -552, 1852, 1637, +2986, 2296, 886, 371, -2337, -2121, -3055, -2293, +-457, -27, 2593, 2197, 2872, 2105, 86, -36, +-2600, -2186, -2349, -2188, 169, 206, 2247, 2466, +1986, 2096, -21, -702, -1809, -2559, -1889, -1547, +-301, 1047, 1720, 2312, 2079, 1095, 191, -1182, +-1932, -2192, -1908, -749, 210, 1636, 1879, 2156, +1322, -18, -489, -2128, -1639, -1564, -1133, 909, +626, 2079, 1806, 791, 723, -1108, -1607, -1773, +-2071, -723, 422, 986, 2786, 2051, 1379, 1169, +-2250, -1220, -3227, -2705, -29, -1341, 3163, 1637, +2545, 3078, -991, 1392, -3180, -1750, -1740, -3211, +1288, -1534, 2552, 1765, 1111, 3358, -1262, 1488, +-1924, -1870, -581, -3103, 980, -1069, 1070, 1720, +187, 2367, -358, 792, -286, -1021, -107, -1622, +-321, -973, -331, 231, 270, 1266, 954, 1377, +727, 322, -565, -1130, -1506, -1646, -845, -621, +1106, 1125, 2026, 1850, 487, 704, -1913, -1270, +-2134, -1914, 290, -439, 2578, 1515, 1776, 1668, +-1367, -8, -2875, -1414, -913, -1051, 2152, 251, +2607, 862, -147, 469, -2754, -7, -2027, -121, +1044, -298, 2880, -511, 1230, -213, -1970, 740, +-2742, 969, -332, -245, 2198, -1524, 2050, -774, +-198, 1511, -1937, 2096, -1703, -383, -36, -2893, +1451, -1643, 1712, 2160, 321, 3455, -1358, 280, +-1864, -3285, -607, -2809, 1138, 889, 1835, 3195, +827, 1909, -951, -1045, -1917, -2461, -1036, -1448, +874, 733, 1734, 1894, 861, 1237, -741, -411, +-1275, -1345, -600, -920, 274, -9, 543, 655, +480, 841, 414, 736, 137, 7, -667, -1012, +-1252, -1429, -654, -443, 913, 1214, 1922, 2060, +1071, 952, -1334, -1401, -2746, -2764, -1277, -1359, +1980, 1895, 3387, 3564, 831, 1392, -3052, -2600, +-3352, -3948, 201, -916, 3378, 3149, 2333, 3719, +-1251, 301, -2852, -3107, -1067, -3040, 1276, 163, +1518, 2736, 249, 2319, -600, -373, -577, -2145, +-404, -1511, -245, 330, 138, 1327, 636, 950, +488, 166, -428, -515, -754, -824, -31, -517, +523, 342, 22, 798, -684, 205, -307, -562, +869, -163, 914, 720, -557, 496, -1463, -882, +-553, -1367, 955, 180, 1244, 1783, 165, 1380, +-879, -758, -964, -2033, -297, -1121, 437, 859, +761, 1858, 587, 1164, -33, -426, -907, -1521, +-1167, -1318, -225, -90, 1086, 1178, 1422, 1334, +135, 498, -1474, -545, -1390, -981, 141, -725, +1273, -222, 855, 390, -334, 1010, -884, 1263, +-451, 345, 48, -1561, -22, -2417, 173, -562, +613, 2521, 436, 3162, -628, 170, -1281, -3138, +-353, -2959, 1067, 410, 1001, 3042, -427, 2257, +-1217, -615, -234, -2294, 943, -1343, 471, 529, +-880, 1228, -1054, 598, 450, 25, 1510, -66, +448, -323, -1487, -759, -1681, -430, 215, 683, +1687, 1127, 1032, 107, -687, -919, -1308, -531, +-439, 622, 428, 624, 345, -567, -64, -1027, +85, 304, 417, 1718, 69, 929, -928, -1463, +-1196, -2312, 56, -182, 1660, 2436, 1428, 2239, +-740, -668, -2346, -2762, -1242, -1626, 1298, 1418, +2137, 2723, 446, 778, -1516, -1981, -1549, -2197, +-65, 390, 958, 2321, 612, 1181, -215, -1318, +-405, -1896, 46, 0, 107, 1645, -568, 1053, +-865, -646, 14, -1301, 1498, -304, 1332, 942, +-935, 943, -2708, -132, -1396, -1026, 1896, -608, +3234, 589, 661, 1068, -2984, 266, -3319, -864, +95, -887, 3359, 277, 2719, 1111, -1109, 531, +-3541, -831, -1844, -1026, 1731, 267, 2803, 1229, +404, 394, -2049, -1037, -1636, -867, 572, 721, +1465, 1332, 261, 37, -1091, -1384, -922, -972, +203, 582, 858, 1387, 563, 802, -334, -395, +-969, -1235, -813, -1040, 196, 256, 944, 1536, +808, 1157, -304, -497, -1310, -1474, -1099, -646, +307, 647, 1338, 884, 926, 341, -595, -45, +-1585, -205, -795, -532, 737, -621, 1197, 79, +38, 928, -1152, 890, -657, -66, 742, -757, +847, -647, -722, -100, -1471, 219, -112, 420, +1640, 658, 1164, 569, -1238, -329, -2310, -1381, +-380, -1172, 1942, 706, 1925, 2314, -488, 1561, +-2379, -1239, -1658, -3147, 664, -1666, 2024, 1966, +1320, 3898, -580, 1638, -1819, -2578, -1599, -4147, +-106, -1296, 1448, 2916, 1787, 4055, 469, 1091, +-1282, -2764, -2189, -3655, -1187, -941, 689, 2401, +2079, 3169, 1765, 1050, -289, -1512, -2458, -2518, +-2506, -1475, -54, 547, 2519, 2360, 2383, 2258, +-450, -111, -2556, -2601, -1718, -2280, 696, 711, +1459, 2581, 286, 1236, -737, -1209, -195, -1404, +450, 200, -83, 902, -1092, -179, -999, -881, +460, 98, 1528, 1467, 871, 1005, -800, -879, +-1806, -1979, -1183, -862, 575, 1274, 1642, 2106, +987, 840, -595, -1219, -1484, -1900, -1009, -673, +105, 1044, 698, 1534, 663, 632, 507, -490, +-103, -970, -1171, -773, -1565, -212, -334, 642, +1594, 1348, 1953, 1004, 109, -566, -2096, -1961, +-2373, -1292, -169, 988, 2144, 2303, 2138, 1054, +-88, -1190, -2173, -1927, -2130, -620, -33, 937, +1705, 1468, 1708, 857, -3, -280, -1606, -1377, +-1759, -1424, -170, 57, 1418, 1789, 1293, 1675, +-333, -242, -1472, -1682, -714, -1056, 467, 444, +617, 889, -282, 270, -598, -91, 98, 308, +582, 315, 160, -459, -684, -997, -1197, -310, +-456, 786, 865, 980, 1431, 360, 511, -170, +-1333, -508, -2078, -891, -718, -843, 1346, 422, +2098, 1947, 616, 1780, -1600, -552, -2344, -2756, +-810, -2250, 1430, 825, 2113, 3193, 461, 2361, +-1517, -875, -1790, -2872, -323, -1823, 1025, 703, +871, 1803, -192, 1180, -552, 232, -172, -246, +85, -957, -299, -1404, -522, -562, -144, 1271, +454, 1999, 635, 718, 242, -1045, -616, -1578, +-1356, -877, -886, 169, 691, 1095, 1706, 1653, +893, 963, -945, -969, -1942, -2419, -1131, -1422, +445, 1271, 1426, 2681, 1152, 1249, 6, -1282, +-1172, -2058, -1517, -611, -946, 1010, 564, 1117, +1758, 58, 1236, -488, -699, -139, -2142, 409, +-1394, 266, 818, -304, 1642, -688, 518, -377, +-921, 399, -1005, 1123, -52, 938, 461, -225, +-74, -1544, -538, -1441, -231, 270, 464, 1986, +627, 1683, -138, -359, -850, -1913, -867, -1425, +-98, 354, 586, 1503, 744, 1124, 366, 26, +-391, -741, -1171, -757, -1138, -487, 75, -21, +1445, 657, 1395, 1180, -326, 656, -1791, -712, +-1572, -1654, 151, -841, 1622, 1047, 1455, 1970, +-220, 814, -1809, -1378, -1635, -2018, 134, -369, +1707, 1793, 1499, 1913, -433, -143, -2132, -2005, +-1515, -1455, 630, 687, 2095, 2071, 1164, 1151, +-1099, -875, -2276, -1988, -1125, -1117, 948, 978, +1991, 2256, 1046, 1323, -926, -1071, -2033, -2410, +-1418, -1167, 427, 1232, 1848, 2139, 1477, 842, +-432, -887, -2029, -1314, -1636, -544, 554, 322, +1780, 630, 708, 469, -977, 146, -1183, -4, +165, -8, 736, -292, -257, -764, -942, -551, +-207, 692, 983, 1670, 968, 914, -345, -981, +-1568, -2005, -1103, -1028, 417, 895, 1468, 1978, +1006, 1359, -500, -297, -1596, -1684, -1153, -1732, +329, -393, 1426, 1439, 1073, 2284, -313, 1211, +-1524, -1272, -1643, -2882, -11, -1683, 1818, 1558, +1972, 3464, -207, 1663, -2404, -1899, -2110, -3350, +285, -1205, 2056, 1810, 1587, 2713, -91, 1162, +-1322, -888, -1624, -2040, -1049, -1700, 414, -90, +1929, 1967, 1922, 2553, -281, 601, -2579, -2135, +-2472, -2820, 79, -550, 2437, 2141, 2263, 2593, +81, 582, -2020, -1671, -2281, -2177, -590, -717, +1256, 1188, 1772, 1909, 787, 1015, -659, -691, +-1368, -1652, -1023, -1191, -299, 415, 659, 1635, +1149, 1236, 694, -444, -374, -1541, -1212, -798, +-972, 872, 78, 1318, 738, 30, 456, -1237, +68, -776, -26, 909, -36, 1546, -564, 177, +-1013, -1662, -412, -1608, 897, 440, 1461, 2249, +558, 1664, -1143, -776, -1892, -2532, -918, -1760, +1016, 957, 1967, 2831, 998, 1944, -1091, -1000, +-2050, -2921, -1083, -1858, 731, 1049, 1684, 2754, +995, 1684, -468, -868, -1370, -2300, -1258, -1415, +-186, 667, 1004, 1812, 1337, 1164, 484, -339, +-882, -1092, -1576, -768, -851, -126, 588, 233, +1328, 518, 807, 901, -328, 683, -1066, -515, +-956, -1550, -262, -1054, 663, 733, 910, 1717, +339, 862, -515, -666, -873, -1102, -297, -316, +355, 356, 188, 169, -278, -250, -99, 101, +490, 893, 656, 895, -294, -489, -1349, -1759, +-1136, -1261, 382, 824, 1712, 2183, 1495, 1385, +-398, -705, -2156, -1957, -1866, -1433, 259, 247, +2127, 1645, 1872, 1604, -315, 157, -2166, -1380, +-1823, -1453, 281, -146, 1912, 1066, 1553, 1042, +-397, 149, -1870, -643, -1503, -707, 313, -142, +1710, 565, 1259, 661, -395, -33, -1560, -702, +-1166, -436, 76, 384, 1000, 686, 991, 72, +426, -403, -474, -183, -1279, 234, -1273, -22, +-136, -459, 1407, -210, 1849, 764, 477, 1066, +-1401, 77, -2078, -1324, -1230, -1495, 558, -86, +2048, 1582, 2212, 1939, 340, 534, -2402, -1530, +-3341, -2440, -897, -1104, 2708, 1522, 3565, 2940, +650, 1468, -2694, -1631, -2917, -3106, -412, -1283, +1729, 1896, 1749, 2896, 430, 688, -666, -2071, +-986, -2239, -822, 120, -220, 2049, 604, 1329, +796, -756, 310, -1566, -326, -342, -595, 1026, +-384, 833, -43, -293, 285, -796, 267, -264, +-44, 337, -304, 508, 15, 421, 399, 69, +3, -681, -834, -1155, -732, -260, 510, 1432, +1385, 1891, 576, 36, -1231, -2188, -1719, -2107, +-262, 377, 1536, 2419, 1523, 1885, -106, -430, +-1612, -1926, -1383, -1485, 159, 34, 1368, 1140, +1084, 1243, -209, 482, -1143, -530, -919, -1008, +25, -593, 745, 236, 788, 639, 106, 449, +-677, -30, -889, -331, -278, -310, 589, 80, +897, 419, 298, 182, -585, -473, -1028, -665, +-594, 123, 537, 1010, 1215, 834, 616, -425, +-745, -1292, -1406, -853, -479, 496, 908, 1265, +1075, 864, -1, -250, -825, -1022, -503, -910, +218, -30, 317, 796, -100, 816, -273, 73, +-105, -535, 244, -376, 366, 136, 254, 209, +-368, -195, -1028, -443, -845, -31, 694, 682, +1906, 967, 1083, 262, -1453, -1040, -2731, -1768, +-952, -777, 2132, 1383, 2773, 2701, 382, 1340, +-2272, -1667, -2363, -3357, -236, -1700, 1665, 1683, +1754, 3409, 622, 1930, -796, -1070, -1696, -2891, +-1440, -2360, -15, -136, 1719, 2258, 2121, 3079, +614, 1450, -1662, -1730, -2647, -3739, -1347, -2499, +1260, 1233, 2818, 4040, 1952, 3133, -667, -769, +-2838, -3795, -2558, -3117, -34, 316, 2550, 2853, +2807, 2495, 546, 290, -2215, -1437, -2750, -1685, +-765, -908, 1560, 158, 2003, 979, 707, 1220, +-653, 596, -1019, -434, -825, -1099, -387, -777, +276, 79, 789, 659, 665, 533, 96, 138, +-302, -77, -412, -89, -610, -227, -638, -459, +27, -463, 1031, 89, 1307, 903, 245, 1104, +-1264, 154, -1624, -1230, -516, -1516, 886, -349, +1463, 1093, 873, 1424, -213, 679, -1174, -385, +-1369, -1156, -639, -1255, 794, -358, 1740, 1123, +1265, 1680, -626, 547, -2072, -1209, -1483, -1598, +683, -272, 2024, 1141, 1100, 1082, -895, -135, +-1638, -899, -533, -432, 823, 438, 1037, 556, +247, -96, -627, -548, -902, -265, -260, 277, +562, 388, 747, 131, 295, -32, -335, -24, +-552, -213, -532, -526, -342, -347, 216, 426, +1027, 976, 1086, 500, -109, -519, -1568, -974, +-1549, -495, 57, 277, 1667, 642, 1547, 490, +-65, -2, -1385, -403, -1056, -279, 59, 161, +497, 150, 134, -513, 78, -636, 598, 464, +825, 1526, -261, 758, -1674, -1255, -1553, -2002, +357, -449, 2132, 1595, 1944, 1751, -204, 132, +-2240, -1355, -2008, -1326, 48, -187, 1846, 890, +1785, 1117, 161, 465, -1362, -527, -1461, -1014, +-318, -735, 862, 47, 938, 718, 286, 1038, +-214, 624, -341, -424, -295, -1413, -510, -1131, +-297, 326, 590, 1504, 1017, 1142, 335, -287, +-752, -1228, -1032, -926, -156, 168, 799, 865, +634, 598, -222, -212, -518, -513, -92, -102, +265, 281, 135, -27, -98, -395, -127, -151, +11, 423, 29, 499, -5, 18, 18, -332, +120, -350, 83, -183, -45, -73, -330, 164, +-294, 364, 212, 353, 617, 53, 370, -271, +-373, -417, -787, -376, -297, -114, 520, 321, +731, 641, 69, 412, -638, -202, -428, -603, +458, -370, 619, -13, -306, 85, -891, 65, +-63, 396, 964, 614, 671, 94, -435, -869, +-811, -1055, -237, -30, 287, 1020, 248, 954, +256, -31, 362, -672, 74, -577, -617, -207, +-821, -70, -68, 147, 943, 597, 1020, 834, +113, 246, -1054, -904, -1288, -1456, -148, -643, +1267, 1006, 1489, 1816, 147, 816, -1427, -1068, +-1422, -1831, 4, -652, 1315, 1032, 1216, 1405, +52, 342, -1037, -744, -1022, -915, -152, -380, +775, 244, 871, 753, 339, 800, -354, 116, +-662, -1007, -618, -1323, -114, -195, 560, 1430, +994, 1651, 412, -18, -676, -1845, -971, -1731, +-20, 432, 784, 2121, 363, 1429, -647, -1032, +-670, -2186, 575, -752, 1473, 1595, 630, 1884, +-1372, -131, -2216, -1970, -647, -1450, 2067, 783, +2852, 2086, 487, 1102, -2362, -1087, -2659, -1991, +-247, -849, 1986, 986, 1940, 1436, 370, 488, +-998, -474, -1204, -401, -462, -151, 198, -416, +374, -745, 366, -81, 513, 1122, 653, 1480, +-24, 343, -1203, -1281, -1371, -1790, -9, -724, +1558, 954, 1556, 1626, 23, 867, -1312, -379, +-1107, -968, -74, -770, 729, -385, 625, 67, +105, 631, -132, 990, 41, 485, 94, -576, +-203, -1154, -634, -596, -307, 421, 628, 903, +980, 484, 308, -332, -692, -725, -710, -297, +8, 573, 363, 752, 30, -123, -124, -1195, +339, -928, 832, 574, 330, 1754, -938, 1128, +-1449, -714, -408, -1969, 1146, -1448, 1668, 310, +726, 1755, -677, 1733, -1265, 283, -940, -1284, +-179, -1698, 594, -781, 1045, 475, 1072, 1223, +474, 1103, -750, 358, -1618, -662, -1294, -1250, +217, -958, 1721, 50, 1949, 1038, 560, 1304, +-1184, 581, -2021, -740, -1410, -1578, 236, -1114, +1907, 428, 2401, 1645, 914, 1436, -1710, -128, +-3010, -1719, -1468, -1775, 1540, 10, 2959, 1992, +1536, 1869, -919, -391, -2134, -2291, -1456, -1552, +204, 815, 1490, 2161, 1526, 1135, 321, -861, +-1060, -1899, -1322, -1144, -393, 525, 709, 1708, +1212, 1384, 825, -111, -301, -1565, -1403, -1755, +-1289, -467, 338, 1347, 2028, 2110, 1623, 954, +-656, -1241, -2322, -2394, -1329, -1190, 1154, 1157, +2247, 2270, 815, 1038, -1250, -995, -1646, -1765, +-236, -849, 1101, 489, 1069, 1053, 37, 793, +-509, 106, -321, -569, -119, -954, -162, -584, +-82, 326, 458, 1002, 900, 726, 420, -258, +-673, -983, -1134, -786, -407, 115, 782, 890, +1076, 864, 395, 61, -538, -859, -821, -1118, +-203, -418, 637, 755, 679, 1343, -59, 718, +-685, -603, -381, -1385, 566, -962, 777, 191, +-8, 1056, -642, 1078, -450, 271, 277, -709, +663, -1202, 313, -712, -239, 392, -457, 1236, +-121, 973, 269, -262, 275, -1333, 116, -1158, +38, 172, 19, 1255, -68, 1109, -224, -47, +-126, -932, 279, -1017, 523, -345, 286, 427, +-270, 894, -656, 596, -441, -240, 436, -765, +1096, -395, 720, 310, -413, 313, -1310, -313, +-863, -511, 590, 215, 1490, 882, 854, 501, +-420, -642, -1045, -1068, -536, -320, 146, 658, +444, 684, 465, -6, 420, -403, 190, -188, +-254, 44, -593, -114, -441, -172, 82, 179, +686, 539, 994, 178, 297, -614, -891, -912, +-1281, -211, -182, 772, 1324, 1038, 1476, 403, +62, -555, -1261, -1106, -1229, -964, -24, -115, +1063, 975, 1165, 1468, 492, 782, -437, -740, +-1109, -1809, -876, -1417, 114, 238, 1218, 1776, +1367, 1803, 309, 121, -1062, -1704, -1358, -1899, +-420, -269, 805, 1381, 1276, 1400, 810, 107, +-76, -843, -888, -672, -1083, -87, -450, 64, +780, -81, 1507, 164, 905, 557, -686, 388, +-1543, -443, -622, -931, 1075, -398, 1496, 525, +132, 809, -1282, 236, -944, -412, 578, -603, +1285, -365, 607, 2, -448, 429, -671, 610, +-315, 259, 14, -487, 194, -895, 462, -501, +625, 369, 359, 932, -294, 681, -652, -183, +-342, -962, 143, -922, 386, -160, 386, 653, +377, 860, 277, 539, -65, -87, -498, -774, +-487, -1152, -73, -651, 380, 576, 697, 1411, +739, 1018, 273, -282, -626, -1236, -1197, -1225, +-585, -356, 789, 663, 1525, 1130, 962, 680, +-268, -224, -1114, -743, -1091, -665, -358, -315, +742, 5, 1567, 406, 1225, 686, -287, 363, +-1559, -436, -1233, -852, 291, -288, 1256, 547, +898, 634, 153, -187, -194, -828, -307, -521, +-488, 446, -360, 930, 345, 431, 926, -529, +559, -909, -204, -427, -456, 275, -134, 419, +122, 64, -35, -31, 0, 210, 449, 307, +796, -217, 304, -731, -596, -710, -973, -6, +-263, 628, 781, 911, 1127, 529, 476, -319, +-372, -1201, -734, -1266, -423, -93, 236, 1364, +819, 1689, 680, 257, -178, -1607, -752, -2005, +-335, -332, 605, 1645, 924, 1847, 340, 149, +-488, -1453, -653, -1377, -272, -199, 357, 634, +826, 576, 854, 354, 158, 264, -812, 8, +-1156, -718, -175, -1071, 1248, -372, 1624, 888, +414, 1224, -1142, 175, -1565, -975, -419, -912, +1083, 106, 1768, 678, 1055, 298, -473, -399, +-1650, -474, -1317, -62, 313, 374, 1728, 396, +1616, 40, 142, -413, -1273, -633, -1219, -343, +105, 216, 1084, 700, 786, 578, -97, 14, +-366, -685, 72, -848, 308, -424, 11, 292, +-218, 699, 77, 589, 488, 145, 493, -346, +9, -660, -380, -735, -376, -303, 66, 392, +570, 978, 750, 732, 398, -105, -173, -962, +-658, -1089, -631, -477, 16, 527, 890, 1190, +1197, 919, 570, -210, -498, -1279, -1140, -1208, +-692, -170, 451, 922, 1289, 1056, 1017, 423, +-93, -510, -886, -985, -590, -727, 358, 131, +776, 788, 291, 570, -237, -158, -169, -598, +315, -320, 556, 111, 195, 204, -342, -43, +-399, -149, -34, -46, 466, 116, 761, 23, +538, -157, -107, -175, -670, 18, -579, 143, +198, -55, 932, -270, 800, -163, 107, 280, +-479, 338, -402, -172, 2, -678, 284, -302, +399, 578, 476, 768, 355, -150, -86, -1075, +-586, -800, -436, 340, 507, 1089, 1155, 719, +633, -149, -621, -857, -975, -999, -148, -574, +907, 278, 984, 1064, 337, 1114, -447, 271, +-692, -913, -305, -1484, 558, -904, 1040, 446, +636, 1345, -386, 1014, -835, -166, -230, -1024, +560, -969, 739, -262, 337, 489, 18, 885, +-55, 614, -142, -328, -296, -1153, -7, -1063, +546, 106, 772, 1157, 285, 1242, -368, 235, +-466, -925, 104, -1487, 493, -929, 390, 309, +-44, 1341, -128, 1242, 266, 189, 489, -877, +29, -1267, -472, -898, -224, -35, 671, 990, +1031, 1403, 236, 609, -831, -953, -899, -1727, +119, -881, 1097, 726, 1120, 1456, 322, 806, +-542, -430, -826, -1115, -379, -944, 292, -124, +757, 692, 792, 923, 437, 432, -149, -433, +-476, -930, -363, -746, 65, 30, 507, 728, +473, 730, 106, 5, -63, -653, 208, -524, +305, 80, 77, 293, -215, -75, -38, -306, +253, -27, 285, 316, 63, 249, 27, -95, +224, -387, 321, -428, 160, -173, 12, 320, +54, 595, -41, 182, -195, -615, -144, -880, +413, -161, 943, 860, 861, 1020, -171, -19, +-1196, -1250, -1103, -1372, 383, -84, 1657, 1383, +1470, 1543, -58, 212, -1355, -1382, -1169, -1746, +170, -613, 1329, 1005, 1268, 1603, 170, 757, +-896, -701, -924, -1360, 48, -784, 1053, 258, +999, 801, 15, 565, -785, -46, -514, -516, +324, -564, 816, -152, 565, 381, 75, 499, +-326, 52, -432, -505, -230, -545, 392, -79, +885, 334, 688, 312, -142, 17, -653, -165, +-384, -84, 234, 86, 523, -92, 395, -562, +185, -699, 144, 186, 96, 1322, -139, 1191, +-298, -595, -123, -2019, 334, -1302, 693, 853, +597, 1902, 59, 779, -443, -951, -696, -1340, +-323, -291, 587, 626, 1258, 451, 933, -177, +-255, -231, -1217, 182, -974, 198, 262, -363, +1226, -572, 1116, -74, 228, 490, -443, 386, +-656, -34, -432, -274, 47, -325, 638, -364, +862, -163, 467, 355, -285, 614, -584, 205, +-245, -471, 245, -710, 433, -346, 437, 221, +318, 602, -26, 495, -400, -129, -342, -777, +259, -682, 632, 104, 429, 715, -71, 474, +-182, -186, 15, -493, 74, -330, -100, -84, +74, 67, 506, 173, 491, 190, -102, -5, +-482, -167, -115, -95, 546, 56, 578, -119, +-46, -397, -457, -276, -243, 286, 322, 661, +641, 331, 422, -378, -72, -790, -355, -556, +-220, 161, 136, 683, 257, 538, 169, -179, +200, -643, 277, -372, 160, 214, -136, 344, +-196, -25, 46, -309, 187, -155, 39, 131, +13, 131, 336, -89, 537, -184, 134, 0, +-461, 233, -447, 125, 110, -339, 439, -609, +368, -184, 171, 603, 140, 816, 36, 67, +-231, -868, -359, -909, 59, -46, 556, 749, +592, 667, 122, 7, -401, -467, -485, -522, +-17, -323, 560, -37, 693, 410, 270, 666, +-379, 333, -626, -506, -303, -1022, 428, -634, +885, 369, 614, 1048, -162, 797, -658, -201, +-593, -1033, 67, -984, 676, -68, 740, 780, +266, 831, -303, 196, -531, -441, -251, -651, +230, -495, 496, -88, 433, 440, 148, 705, +-169, 337, -395, -412, -252, -810, 253, -474, +672, 185, 506, 535, -183, 393, -669, 28, +-317, -240, 451, -296, 642, -270, 192, -233, +-206, -77, -67, 299, 135, 628, -27, 431, +-327, -361, -123, -1017, 464, -789, 815, 217, +418, 1117, -388, 968, -906, -141, -580, -1172, +341, -1098, 1035, 30, 882, 1001, 67, 888, +-664, -7, -766, -654, -236, -680, 422, -383, +698, 38, 489, 623, -16, 873, -421, 217, +-336, -840, 154, -1008, 448, -120, 199, 557, +-251, 245, -251, -154, 207, 217, 473, 711, +234, 216, -230, -930, -329, -1404, -9, -577, +340, 809, 321, 1593, 48, 1146, -227, -276, +-185, -1545, 140, -1579, 319, -335, 186, 1039, +23, 1386, -6, 626, -133, -396, -283, -912, +-42, -718, 543, -154, 691, 373, -38, 484, +-888, 214, -606, -131, 662, -149, 1255, 17, +290, -32, -1040, -315, -993, -345, 257, 101, +1092, 488, 614, 336, -295, -115, -574, -331, +-80, -293, 287, -218, 233, -74, -38, 313, +-178, 577, -119, 266, 243, -443, 510, -792, +274, -403, -261, 300, -484, 657, -244, 465, +193, -16, 442, -409, 389, -483, 122, -333, +-203, -84, -376, 185, -153, 542, 282, 660, +415, 153, 111, -837, -227, -1217, -214, -270, +69, 1142, 307, 1332, 204, -78, -63, -1398, +-198, -1017, -70, 475, 122, 1190, 196, 446, +77, -542, -63, -583, 34, -54, 154, 70, +23, -238, -194, -180, -132, 424, 242, 753, +389, 234, 82, -591, -268, -770, -222, -233, +33, 241, 163, 170, 179, -9, 243, 251, +186, 612, -208, 330, -530, -587, -222, -1169, +458, -660, 725, 490, 271, 1131, -356, 715, +-527, -217, -226, -740, 48, -550, 201, -89, +414, 223, 619, 305, 357, 314, -469, 78, +-1157, -407, -833, -670, 476, -160, 1575, 750, +1289, 996, -187, 136, -1465, -950, -1398, -1128, +-154, -359, 1126, 546, 1399, 943, 544, 742, +-637, 114, -1131, -602, -589, -933, 330, -562, +891, 149, 704, 632, -28, 574, -775, 147, +-864, -330, -47, -455, 1109, -30, 1248, 482, +-53, 275, -1435, -595, -1265, -988, 278, -129, +1493, 1153, 1100, 1312, -278, 76, -1081, -1266, +-674, -1349, 218, -184, 643, 1016, 394, 1109, +-95, 148, -285, -723, -126, -656, 114, -11, +184, 293, 163, 122, 5, 27, -250, 155, +-304, 50, 49, -297, 477, -313, 447, 164, +-107, 386, -611, -27, -362, -415, 397, -77, +728, 482, 206, 333, -595, -405, -797, -687, +-92, -101, 884, 567, 988, 534, 15, 12, +-962, -320, -861, -281, 76, -189, 791, -130, +562, 111, -124, 417, -366, 361, -51, -130, +142, -459, 27, -240, -102, 193, -11, 225, +58, -70, -88, -227, -193, -5, 170, 230, +647, 203, 470, -19, -407, -174, -1003, -183, +-572, -115, 417, -15, 903, 114, 633, 186, +38, 125, -413, -16, -669, -114, -535, -135, +22, -128, 655, -29, 764, 151, 261, 233, +-403, 6, -668, -236, -410, -138, 77, 155, +497, 146, 505, -166, 156, -219, -224, 199, +-302, 484, -217, 119, -195, -557, -178, -743, +201, -157, 804, 684, 816, 1026, -169, 455, +-1271, -620, -1258, -1218, 10, -679, 1335, 430, +1471, 975, 320, 534, -1050, -109, -1449, -269, +-587, -119, 676, -219, 1214, -446, 645, -296, +-327, 271, -810, 716, -548, 597, -4, 25, +391, -590, 453, -775, 262, -330, -48, 423, +-271, 732, -436, 314, -369, -339, 37, -453, +596, -65, 712, 239, 181, 103, -614, -134, +-841, -78, -252, 160, 448, 181, 477, -122, +138, -342, 38, -140, 158, 349, -29, 502, +-572, 47, -788, -589, -81, -599, 971, 131, +1114, 801, 55, 523, -1082, -391, -1059, -832, +34, -259, 950, 552, 697, 566, -265, -65, +-685, -423, -173, -115, 425, 230, 315, 109, +-289, -210, -513, -151, -18, 176, 483, 255, +304, -93, -164, -340, -243, -82, 9, 412, +7, 447, -332, -118, -355, -659, 326, -497, +929, 225, 484, 690, -686, 383, -1271, -241, +-567, -440, 717, -68, 1271, 238, 591, 59, +-583, -274, -1092, -212, -568, 203, 313, 414, +665, 175, 351, -201, -121, -290, -263, -113, +-91, 70, 42, 91, -56, 39, -245, -24, +-265, -22, 73, 31, 523, 154, 552, 161, +-27, -44, -681, -342, -755, -380, -182, -14, +443, 429, 643, 494, 386, 107, -62, -276, +-437, -331, -554, -146, -355, -61, 53, -23, +457, 112, 534, 337, 174, 342, -342, 82, +-575, -234, -338, -423, 179, -423, 453, -164, +187, 343, -211, 694, -287, 488, -85, -155, +115, -592, 119, -535, -20, -146, -136, 264, +-106, 532, 18, 381, 95, -147, -30, -509, +-244, -204, -169, 321, 227, 246, 440, -287, +69, -361, -485, 230, -556, 601, -102, 180, +351, -473, 422, -558, 176, -130, -145, 323, +-343, 484, -344, 335, -102, -75, 191, -476, +183, -469, -19, -28, -4, 361, 146, 339, +36, 53, -337, -118, -494, -91, -91, -17, +420, -51, 395, -103, -68, -25, -303, 173, +-121, 233, 49, -20, -69, -315, -296, -240, +-206, 179, 291, 433, 592, 246, 142, -160, +-606, -402, -743, -411, -77, -165, 652, 305, +594, 717, -163, 529, -674, -242, -448, -807, +116, -496, 459, 232, 335, 442, -108, 54, +-478, -159, -370, 169, 101, 411, 403, 36, +139, -502, -346, -417, -433, 134, 6, 334, +391, -77, 329, -312, -46, 138, -374, 702, +-475, 462, -337, -430, 55, -908, 538, -433, +650, 316, 112, 516, -614, 232, -771, 79, +-290, 188, 209, 65, 315, -410, 246, -650, +286, -157, 174, 562, -351, 628, -846, -64, +-607, -583, 266, -249, 906, 493, 626, 663, +-220, -4, -806, -767, -656, -784, -31, -46, +465, 700, 408, 800, 55, 298, -198, -224, +-206, -440, -162, -431, -206, -394, -215, -154, +68, 381, 367, 850, 347, 627, -58, -227, +-460, -864, -510, -558, -86, 262, 339, 550, +340, -2, -72, -504, -378, -170, -221, 599, +217, 789, 275, 131, -130, -631, -429, -814, +-256, -413, 126, 172, 316, 604, 174, 656, +-146, 318, -383, -179, -333, -463, 14, -434, +344, -202, 319, 82, -44, 305, -343, 336, +-341, 167, -241, -56, -173, -178, 100, -194, +562, -100, 646, 109, 1, 271, -862, 150, +-1041, -179, -309, -319, 594, -143, 829, 112, +359, 247, -167, 362, -392, 357, -388, -36, +-408, -663, -331, -793, 92, -138, 683, 679, +682, 869, -100, 407, -906, -223, -779, -664, +150, -701, 765, -175, 368, 608, -349, 845, +-542, 215, -218, -598, 49, -650, 143, 15, +215, 553, 244, 372, -15, -153, -458, -353, +-592, -64, -204, 237, 295, 137, 481, -188, +301, -240, -66, 101, -406, 404, -477, 285, +-258, -160, 53, -438, 237, -287, 278, 140, +166, 403, -56, 256, -293, -97, -376, -225, +-244, -72, -56, 46, 119, -1, 289, 69, +363, 283, 121, 189, -406, -369, -738, -683, +-460, -93, 204, 826, 617, 903, 456, -24, +-19, -857, -357, -725, -432, -2, -374, 445, +-219, 377, 137, 207, 531, 191, 559, 87, +6, -286, -725, -603, -870, -401, -202, 245, +596, 715, 717, 518, 146, -89, -482, -461, +-539, -306, -147, 62, 134, 203, 44, 19, +-64, -179, -19, -60, 153, 301, 200, 468, +16, 127, -332, -368, -546, -451, -417, -109, +103, 90, 674, -20, 660, 70, -29, 605, +-708, 816, -744, 43, -206, -1089, 292, -1220, +339, -137, 174, 953, 69, 1067, -15, 442, +-194, -163, -423, -543, -463, -745, -117, -545, +448, 235, 741, 1007, 325, 877, -603, -188, +-1149, -1102, -619, -814, 560, 431, 1168, 1267, +557, 724, -558, -615, -998, -1242, -498, -476, +192, 711, 352, 975, 116, 184, 42, -565, +196, -445, 123, 192, -348, 474, -662, 131, +-381, -323, 229, -364, 524, -9, 282, 292, +-89, 227, -230, 11, -278, 33, -345, 218, +-224, 109, 173, -379, 466, -599, 291, -50, +-206, 718, -522, 689, -409, -168, -80, -758, +210, -313, 395, 544, 319, 703, -121, 0, +-559, -639, -555, -523, -99, 94, 355, 500, +398, 436, 106, 155, -176, -93, -301, -267, +-248, -320, -89, -153, 26, 184, 15, 388, +-4, 285, 90, 2, 163, -206, -72, -230, +-402, -80, -386, 144, 27, 248, 370, 114, +276, -98, -95, -92, -329, 71, -299, 80, +-151, -114, 13, -137, 154, 174, 184, 416, +81, 168, -62, -342, -223, -500, -382, -100, +-311, 457, 66, 610, 424, 194, 321, -405, +-154, -581, -445, -164, -246, 374, 58, 479, +85, 181, -66, -56, -60, -87, 60, -143, +30, -300, -183, -261, -254, 165, -24, 637, +251, 622, 179, 27, -194, -615, -441, -679, +-247, -98, 167, 476, 309, 467, 41, 65, +-267, -105, -252, 93, 10, 147, 186, -153, +78, -362, -167, -76, -346, 327, -289, 262, +-40, -128, 275, -214, 429, 162, 200, 447, +-298, 206, -605, -273, -454, -431, -31, -201, +257, 86, 297, 218, 259, 327, 162, 414, +-168, 200, -638, -374, -753, -753, -170, -331, +682, 602, 921, 1009, 206, 302, -773, -773, +-1034, -977, -322, -67, 524, 915, 676, 906, +160, 32, -312, -667, -328, -540, -168, 37, +-232, 343, -309, 183, -48, -57, 445, -12, +632, 236, 159, 327, -591, 34, -900, -403, +-488, -485, 257, -17, 687, 490, 463, 451, +-90, 9, -432, -178, -362, 49, -163, 104, +-142, -285, -181, -497, 69, 40, 488, 805, +523, 799, -99, -66, -854, -844, -914, -740, +-117, 13, 802, 631, 890, 660, 80, 237, +-800, -213, -882, -361, -189, -195, 468, 46, +471, 153, 33, 124, -259, 67, -218, 20, +-114, -10, -139, 10, -177, 109, -44, 178, +175, 102, 245, -73, 64, -232, -266, -246, +-484, -82, -339, 243, 92, 490, 402, 411, +292, 24, -117, -320, -382, -363, -288, -210, +-97, -59, -50, 111, 22, 413, 150, 578, +154, 283, -90, -330, -329, -607, -230, -305, +69, 166, 119, 373, -108, 346, -289, 218, +-143, -96, 174, -424, 266, -284, 67, 344, +-249, 658, -427, 131, -310, -572, -3, -509, +201, 162, 222, 504, 86, 272, -81, 29, +-213, 56, -277, -18, -258, -320, -137, -407, +44, 1, 244, 515, 330, 616, 84, 260, +-438, -270, -724, -635, -292, -550, 455, 83, +634, 791, -1, 863, -634, 155, -469, -633, +163, -755, 365, -287, -28, 249, -347, 523, +-198, 586, 71, 390, 38, -103, -105, -629, +-35, -681, 123, -120, -30, 567, -358, 731, +-397, 252, -13, -317, 371, -399, 325, 13, +-86, 341, -414, 123, -428, -365, -148, -396, +205, 251, 312, 804, 58, 474, -323, -466, +-418, -863, -59, -189, 354, 706, 242, 729, +-292, -75, -613, -604, -254, -276, 386, 327, +483, 378, -65, -28, -532, -205, -387, 58, +150, 258, 327, 35, -42, -266, -406, -158, +-285, 264, 157, 419, 362, 112, 41, -298, +-438, -368, -489, -80, -19, 284, 440, 442, +300, 293, -245, -45, -547, -303, -307, -286, +143, -86, 308, 104, 116, 203, -132, 263, +-243, 247, -243, 73, -136, -181, 18, -264, +107, -71, 57, 158, -54, 155, -127, -34, +-144, -96, -128, 123, -57, 343, -4, 237, +-19, -149, -67, -362, -39, -170, 24, 169, +-34, 248, -223, 82, -248, -22, 22, 44, +219, 101, 64, 0, -227, -61, -250, 56, +-11, 189, 72, 37, -134, -299, -243, -333, +-19, 143, 255, 645, 185, 533, -216, -87, +-494, -529, -311, -401, 137, -52, 420, 134, +212, 245, -301, 427, -552, 428, -222, -20, +296, -543, 383, -557, -86, -19, -482, 491, +-267, 517, 168, 154, 193, -205, -179, -274, +-316, -88, 34, 130, 319, 157, 68, 74, +-385, 54, -439, 80, -62, -26, 217, -189, +120, -132, -47, 171, -23, 387, 23, 282, +-132, -21, -366, -313, -322, -443, 41, -258, +327, 293, 272, 786, -37, 618, -284, -189, +-321, -820, -195, -621, -34, 142, 88, 673, +108, 548, 71, 53, 6, -291, -122, -298, +-268, -112, -305, 72, -72, 177, 251, 208, +288, 158, -71, 1, -405, -171, -323, -164, +53, 50, 246, 251, 59, 176, -200, -89, +-184, -203, 0, 20, 36, 277, -129, 187, +-258, -176, -69, -292, 254, 71, 303, 449, +-54, 294, -490, -272, -569, -507, -123, -103, +426, 467, 555, 514, 117, 35, -469, -386, +-605, -311, -192, 111, 272, 376, 291, 210, +-51, -208, -283, -361, -136, -26, 127, 446, +154, 446, -93, -73, -308, -470, -249, -236, +-19, 282, 152, 357, 158, -50, 2, -297, +-158, 4, -207, 363, -138, 221, 9, -215, +87, -266, 7, 153, -108, 381, -163, 4, +-99, -505, -1, -364, 61, 360, 95, 837, +37, 449, -153, -418, -340, -838, -283, -401, +13, 364, 315, 651, 319, 332, 29, -83, +-308, -174, -453, -119, -318, -191, 48, -204, +381, 115, 355, 537, -57, 471, -443, -145, +-400, -633, -9, -397, 259, 287, 160, 621, +-86, 265, -201, -296, -144, -394, -51, -6, +18, 329, 47, 227, 25, -95, -57, -208, +-142, -6, -155, 213, -81, 168, 11, -72, +82, -234, 89, -105, -13, 207, -134, 405, +-184, 223, -165, -228, -111, -505, 21, -296, +215, 264, 263, 620, -33, 401, -454, -192, +-447, -519, 47, -250, 446, 244, 223, 343, +-331, -1, -442, -240, 15, -24, 364, 335, +165, 294, -287, -110, -377, -383, -36, -224, +189, 122, 33, 289, -164, 208, -75, 48, +191, -73, 163, -118, -214, -60, -458, 54, +-215, 111, 266, 23, 377, -67, -6, -33, +-377, 67, -269, 89, 151, 53, 324, 91, +24, 124, -413, -41, -469, -316, -32, -296, +439, 133, 457, 521, -2, 376, -475, -153, +-508, -431, -114, -180, 302, 238, 359, 298, +49, -16, -292, -296, -338, -188, -46, 195, +245, 422, 152, 245, -158, -170, -244, -388, +-3, -239, 161, 92, -30, 283, -300, 247, +-206, 88, 200, -80, 392, -163, 127, -122, +-320, 21, -509, 118, -296, 112, 120, 46, +435, 15, 383, -7, -32, -75, -402, -87, +-410, 46, -124, 209, 145, 135, 176, -148, +73, -286, 16, -21, -39, 339, -125, 308, +-156, -77, -87, -282, 5, -83, 15, 112, +-17, -25, -2, -191, 54, 75, 82, 520, +-22, 461, -225, -216, -302, -775, -84, -548, +262, 226, 348, 763, 8, 580, -366, -64, +-299, -549, 86, -464, 240, 18, -22, 378, +-279, 301, -112, -30, 241, -187, 243, -86, +-129, 36, -366, 52, -169, 75, 182, 123, +190, 40, -97, -176, -195, -251, 42, 1, +226, 301, 3, 303, -358, 20, -317, -207, +122, -215, 408, -97, 172, 55, -273, 177, +-355, 201, -55, 61, 184, -79, 86, -57, +-112, 31, -109, -59, 58, -252, 140, -168, +-10, 271, -222, 583, -229, 305, -38, -305, +168, -624, 212, -364, 76, 165, -100, 504, +-249, 440, -251, 66, -60, -317, 199, -401, +284, -134, 49, 180, -235, 259, -222, 137, +4, 11, 110, -64, -60, -123, -171, -113, +25, 16, 259, 141, 167, 97, -200, -24, +-382, -43, -155, 29, 174, 24, 224, -68, +33, -70, -57, 57, 21, 150, 3, 75, +-200, -76, -347, -168, -119, -127, 323, 48, +508, 261, 191, 303, -348, 14, -565, -347, +-298, -364, 152, -1, 385, 281, 247, 193, +-25, 3, -141, 66, -113, 180, -90, -34, +-155, -402, -150, -396, -2, 74, 234, 430, +323, 342, 114, 63, -248, -53, -418, -95, +-245, -260, 115, -356, 291, -99, 168, 350, +-25, 502, -70, 234, -31, -164, -153, -351, +-286, -295, -124, -85, 279, 170, 462, 293, +160, 193, -370, -17, -537, -132, -220, -131, +233, -97, 419, -40, 270, 120, -41, 258, +-316, 130, -410, -215, -194, -372, 183, -45, +420, 413, 281, 416, -135, -118, -413, -548, +-277, -305, 97, 309, 290, 525, 130, 109, +-121, -346, -167, -320, -43, 30, 35, 201, +24, 112, 46, 37, 74, 51, -22, -33, +-216, -209, -213, -179, 95, 118, 318, 340, +164, 155, -190, -235, -307, -348, -86, -20, +127, 364, 118, 322, 32, -110, 35, -449, +36, -281, -147, 189, -302, 444, -100, 236, +320, -144, 453, -309, 42, -209, -498, 24, +-509, 215, 25, 260, 495, 37, 363, -269, +-124, -284, -333, 80, -135, 402, 105, 227, +35, -223, -132, -378, -48, -90, 201, 205, +230, 198, -80, 12, -328, -63, -161, -2, +160, 66, 239, 37, -23, -107, -247, -243, +-103, -164, 188, 226, 229, 528, -57, 276, +-282, -385, -158, -677, 112, -193, 197, 478, +53, 546, -82, 24, -66, -367, -36, -250, +-74, 68, -57, 153, 127, 28, 233, -43, +-1, 3, -327, 58, -301, 26, 146, -34, +464, -88, 237, -87, -281, 27, -488, 174, +-166, 143, 278, -92, 340, -238, 88, -67, +-148, 228, -151, 223, -43, -98, -24, -316, +-96, -143, -42, 186, 163, 296, 270, 146, +84, -88, -223, -231, -317, -244, -105, -77, +156, 185, 208, 321, 73, 174, -42, -142, +-43, -316, -33, -188, -64, 118, -84, 278, +-25, 148, 70, -127, 128, -225, 66, -58, +-72, 145, -154, 142, -73, -32, 91, -125, +175, -69, 46, 77, -179, 163, -239, 95, +-7, -129, 282, -290, 265, -143, -54, 213, +-330, 348, -256, 75, 75, -204, 294, -137, +215, 87, -50, 43, -259, -193, -255, -191, +-43, 116, 270, 344, 370, 232, 95, -29, +-339, -207, -462, -270, -104, -234, 353, -33, +433, 272, 73, 428, -308, 243, -286, -165, +9, -443, 177, -362, 75, 12, -92, 342, +-38, 356, 112, 83, 95, -193, -74, -252, +-155, -116, 4, 62, 138, 146, 30, 99, +-132, -39, -121, -95, 64, 1, 181, 119, +107, 68, -24, -122, -113, -182, -127, -37, +-114, 126, -41, 148, 109, 101, 238, 31, +215, -113, -10, -271, -274, -184, -316, 186, +-84, 417, 203, 165, 246, -300, 89, -373, +-3, -1, -16, 288, -84, 159, -200, -109, +-135, -124, 121, 27, 258, 65, 113, -54, +-117, -77, -147, 34, 13, 117, 80, 64, +13, -55, -50, -125, -39, -107, -9, 26, +23, 188, 63, 207, 56, -35, -18, -273, +-78, -203, -39, 119, 54, 287, 73, 82, +-16, -197, -109, -217, -71, 6, 96, 188, +224, 202, 126, 63, -174, -137, -383, -270, +-181, -174, 311, 91, 531, 242, 165, 155, +-386, 5, -531, 7, -124, 6, 359, -150, +431, -296, 109, -167, -200, 157, -222, 346, +-91, 316, -24, 131, 20, -172, 119, -502, +215, -496, 118, 26, -148, 618, -277, 611, +-70, -4, 223, -505, 215, -428, -79, -28, +-247, 200, -84, 200, 213, 151, 274, 91, +29, -66, -239, -274, -249, -310, -7, -43, +218, 366, 225, 512, 40, 152, -161, -452, +-186, -640, -48, -155, 103, 468, 181, 552, +122, 98, -14, -289, -167, -277, -207, -86, +-59, -6, 160, 39, 268, 159, 150, 211, +-102, 51, -228, -199, -132, -241, 68, -46, +150, 170, 85, 178, -9, 16, -49, -137, +-31, -126, 7, 21, 56, 136, 92, 122, +16, -23, -105, -157, -154, -165, -42, -12, +147, 175, 239, 231, 170, 77, -47, -164, +-301, -264, -314, -149, -3, 89, 387, 248, +426, 232, 43, 35, -366, -211, -399, -303, +-72, -128, 291, 161, 413, 277, 230, 143, +-151, -76, -421, -159, -316, -114, 106, -55, +416, -14, 290, 82, -67, 200, -239, 172, +-110, -52, 91, -309, 92, -297, -40, 1, +-77, 334, 34, 391, 141, 106, 95, -303, +-46, -496, -93, -262, 20, 255, 118, 625, +24, 422, -159, -241, -145, -742, 96, -532, +292, 193, 216, 716, -46, 567, -251, -30, +-235, -507, -26, -567, 220, -262, 298, 175, +122, 516, -157, 514, -273, 119, -96, -389, +182, -574, 276, -281, 126, 166, -97, 388, +-190, 275, -134, 45, 0, -109, 107, -158, +156, -148, 189, -104, 145, 3, -51, 114, +-294, 170, -327, 117, -28, 3, 314, -136, +373, -237, 128, -164, -85, 115, -71, 397, +-58, 324, -222, -153, -311, -607, -20, -482, +519, 177, 700, 738, 196, 609, -575, -115, +-826, -729, -241, -647, 567, 22, 763, 563, +205, 473, -415, -26, -423, -290, 17, -106, +262, 107, 64, -22, -146, -269, 25, -149, +292, 256, 190, 409, -212, 70, -384, -327, +-78, -295, 330, 44, 397, 220, 97, 85, +-209, -83, -260, -79, -131, 1, 44, -18, +220, -25, 298, 112, 173, 207, -130, -20, +-356, -393, -232, -367, 161, 196, 441, 672, +267, 390, -186, -399, -408, -787, -148, -314, +310, 449, 438, 683, 96, 237, -321, -333, +-354, -492, 4, -223, 321, 157, 293, 328, +37, 216, -145, -58, -111, -266, -1, -234, +36, 2, 28, 244, 62, 267, 116, 35, +89, -249, -27, -314, -96, -116, -52, 167, +51, 306, 117, 224, 98, -4, 26, -263, +-25, -375, -47, -188, -32, 220, 12, 451, +84, 232, 145, -216, 124, -376, -12, -113, +-168, 173, -168, 126, 51, -103, 266, -113, +240, 126, -26, 278, -239, 77, -146, -282, +152, -382, 312, -78, 112, 295, -239, 324, +-310, 25, 38, -211, 432, -120, 392, 64, +-86, 25, -444, -148, -286, -105, 186, 166, +394, 284, 196, 32, -78, -286, -151, -265, +-46, 47, 42, 275, 56, 199, 59, -57, +64, -244, 29, -234, -19, -45, 3, 193, +100, 320, 105, 202, -20, -125, -157, -414, +-102, -377, 155, 15, 322, 425, 175, 438, +-160, 22, -297, -357, -83, -307, 210, 20, +259, 163, 67, 19, -108, -99, -56, 27, +94, 188, 136, 110, -6, -116, -157, -212, +-114, -97, 129, 39, 332, 82, 218, 86, +-152, 73, -343, -16, -114, -131, 296, -110, +385, 74, 46, 168, -306, 0, -268, -215, +113, -161, 401, 125, 280, 262, -85, 67, +-296, -196, -178, -201, 86, 11, 243, 133, +223, 74, 86, -28, -84, -58, -187, -59, +-114, -24, 132, 67, 300, 118, 147, -5, +-152, -188, -227, -129, 28, 136, 261, 229, +159, -30, -94, -279, -120, -120, 103, 243, +231, 257, 46, -129, -208, -373, -183, -120, +98, 291, 319, 314, 226, -39, -25, -304, +-168, -178, -101, 115, 31, 202, 84, 14, +85, -194, 82, -156, 52, 80, 8, 250, +19, 154, 97, -94, 103, -239, -78, -177, +-224, -46, -91, 61, 280, 168, 438, 239, +134, 117, -303, -186, -357, -344, 31, -152, +386, 169, 295, 216, -69, 12, -288, -88, +-155, 20, 136, 68, 301, -84, 269, -177, +84, -15, -151, 200, -296, 143, -227, -122, +73, -254, 381, -79, 460, 169, 225, 206, +-206, 16, -484, -178, -355, -134, 130, 80, +552, 172, 486, -31, 11, -272, -376, -180, +-309, 196, 35, 376, 246, 98, 210, -277, +92, -288, 16, 11, -38, 155, -109, 6, +-97, -96, 71, 68, 270, 249, 250, 103, +-31, -278, -265, -440, -159, -123, 184, 371, +350, 510, 98, 121, -221, -407, -185, -509, +131, -106, 305, 324, 146, 344, -71, 40, +-109, -182, -64, -146, -37, -35, 41, 3, +220, 27, 305, 81, 105, 58, -209, -85, +-291, -178, -45, -61, 244, 166, 289, 242, +87, 79, -109, -186, -124, -310, 33, -197, +162, 69, 144, 310, 43, 313, -34, 52, +-76, -277, -112, -382, -32, -179, 206, 160, +390, 344, 252, 241, -151, -25, -397, -256, +-222, -288, 123, -141, 287, 94, 217, 252, +137, 249, 96, 77, 7, -172, -158, -312, +-248, -227, -114, 39, 170, 250, 344, 230, +266, 33, 44, -110, -104, -111, -103, -75, +-81, -106, -62, -95, 21, 90, 193, 271, +262, 160, 86, -183, -118, -310, -79, -12, +91, 313, 98, 154, -96, -312, -122, -421, +128, 62, 305, 553, 141, 399, -168, -227, +-179, -590, 113, -305, 284, 221, 80, 416, +-228, 159, -191, -176, 161, -232, 377, -53, +182, 104, -188, 90, -250, 5, 54, -44, +278, -43, 135, -68, -133, -79, -147, 21, +87, 156, 210, 153, 125, -34, 11, -174, +8, -114, -12, 24, -135, 18, -153, -83, +111, -38, 436, 188, 390, 311, -88, 53, +-508, -388, -390, -518, 191, -99, 624, 490, +415, 597, -175, 65, -485, -531, -183, -525, +294, 23, 379, 411, 41, 234, -218, -130, +-92, -147, 179, 124, 199, 154, 2, -208, +-120, -434, -52, -104, 85, 450, 135, 505, +128, -47, 85, -546, -5, -384, -122, 192, +-140, 444, 5, 127, 233, -276, 322, -252, +164, 52, -151, 179, -349, 13, -208, -107, +177, 5, 454, 145, 322, 50, -80, -177, +-320, -240, -179, -42, 123, 219, 243, 258, +93, 52, -69, -201, -60, -235, 87, -56, +179, 133, 115, 143, -21, 12, -139, -60, +-151, -42, -38, -32, 171, -93, 376, -89, +329, 75, -30, 233, -421, 139, -429, -158, +32, -309, 482, -119, 464, 189, 63, 226, +-255, -11, -221, -190, -38, -82, 54, 119, +98, 129, 195, -39, 249, -148, 50, -65, +-257, 44, -308, 41, 12, -36, 392, -35, +420, 50, 34, 116, -363, 57, -364, -83, +51, -162, 448, -108, 388, 30, -81, 95, +-444, 54, -242, -3, 308, 24, 577, 80, +216, 27, -392, -142, -571, -269, -119, -146, +461, 171, 596, 377, 209, 206, -230, -176, +-358, -356, -211, -154, -2, 132, 166, 151, +295, -14, 303, -59, 91, 67, -201, 92, +-273, -36, -75, -115, 140, -61, 141, -44, +73, -109, 112, -16, 158, 278, 3, 363, +-233, -46, -205, -509, 131, -419, 377, 142, +201, 463, -190, 215, -309, -159, -36, -185, +271, 8, 276, 28, 20, -109, -147, -103, +-79, 116, 60, 227, 62, 36, -28, -226, +-26, -219, 89, 60, 158, 254, 98, 149, +-14, -117, -46, -230, -37, -99, -70, 78, +-79, 104, 43, 19, 242, -6, 299, 53, +97, 57, -192, -87, -309, -198, -157, -98, +133, 127, 317, 204, 263, 48, 12, -113, +-204, -104, -196, -1, 9, 30, 216, 18, +218, 46, 3, 33, -217, -112, -214, -215, +83, -25, 373, 317, 316, 355, -71, -49, +-390, -434, -284, -362, 118, 56, 368, 333, +256, 248, -34, 7, -202, -129, -149, -112, +27, -61, 191, -39, 179, -16, 6, 52, +-178, 111, -168, 60, 61, -85, 275, -133, +240, 25, -16, 169, -233, 45, -208, -215, +13, -200, 210, 129, 219, 317, 69, 57, +-53, -317, -76, -285, -62, 116, -51, 362, +27, 164, 169, -187, 215, -297, 53, -121, +-188, 88, -239, 145, 0, 82, 268, 30, +263, 41, 10, 18, -208, -125, -175, -274, +27, -175, 172, 171, 137, 433, 24, 282, +-34, -162, -40, -445, -49, -302, -24, 63, +78, 281, 178, 234, 104, 63, -116, -88, +-224, -168, -42, -152, 253, -35, 288, 97, +-3, 109, -275, 14, -218, -41, 98, 7, +303, 37, 168, -38, -104, -102, -177, -14, +-26, 107, 110, 37, 80, -158, -8, -158, +-22, 129, 36, 342, 57, 145, -1, -262, +-44, -382, -35, -70, 3, 269, 56, 238, +107, -61, 90, -205, -11, -24, -124, 195, +-130, 124, -6, -151, 154, -244, 201, -19, +77, 210, -102, 118, -186, -126, -94, -135, +82, 107, 181, 214, 125, -10, -7, -256, +-82, -190, -76, 91, -43, 218, 32, 78, +109, -99, 120, -104, 32, 16, -102, 81, +-143, 12, -19, -88, 154, -69, 192, 59, +39, 127, -165, 1, -193, -184, 1, -150, +217, 118, 213, 301, 9, 155, -179, -176, +-175, -360, -29, -223, 124, 91, 203, 333, +161, 334, -28, 82, -235, -276, -243, -442, +13, -217, 296, 217, 288, 438, -11, 224, +-272, -170, -224, -320, 37, -107, 235, 129, +199, 96, -1, -79, -143, -92, -129, 101, +-26, 203, 75, 45, 104, -194, 71, -222, +25, -32, -21, 152, -71, 170, -65, 49, +-12, -64, 44, -110, 66, -77, 54, -20, +25, 40, 8, 95, -16, 123, -57, 32, +-55, -174, -7, -248, 58, -25, 79, 291, +42, 274, -6, -96, -25, -344, -20, -137, +0, 213, -1, 225, -9, -51, 8, -191, +26, -38, 9, 102, 0, 21, 26, -89, +53, 12, 46, 171, -33, 106, -109, -164, +-81, -301, 14, -97, 71, 224, 125, 303, +161, 81, 79, -160, -146, -198, -336, -77, +-235, 18, 156, 42, 440, 101, 293, 146, +-117, 47, -349, -166, -226, -230, 25, -19, +161, 223, 153, 194, 96, -66, 19, -227, +-86, -115, -162, 103, -94, 159, 90, 51, +200, -70, 81, -78, -127, -29, -174, -16, +-3, -2, 191, 45, 143, 107, -106, 57, +-219, -90, -69, -166, 149, -56, 196, 128, +58, 161, -108, 15, -141, -146, -57, -129, +35, 16, 93, 119, 89, 77, 41, -29, +-16, -80, -78, -42, -136, 9, -92, 18, +112, 38, 285, 83, 135, 59, -243, -116, +-394, -238, -49, -80, 408, 258, 402, 341, +-81, -9, -461, -369, -298, -292, 159, 109, +364, 307, 178, 124, -112, -115, -197, -109, +-65, 16, 42, 12, -1, -64, -49, -33, +36, 87, 156, 68, 129, -70, -66, -90, +-197, 84, -121, 191, 31, -3, 73, -280, +47, -247, 74, 120, 96, 369, 20, 203, +-123, -145, -175, -266, -87, -140, 45, -10, +132, 54, 157, 144, 96, 241, -31, 108, +-162, -209, -198, -373, -81, -162, 100, 197, +216, 343, 173, 184, -31, -99, -241, -261, +-200, -222, 71, 6, 242, 246, 107, 275, +-161, 17, -235, -275, -22, -304, 203, -29, +196, 295, 14, 337, -162, 72, -216, -253, +-88, -328, 154, -125, 267, 134, 86, 212, +-211, 122, -263, 23, 22, -32, 281, -76, +173, -136, -166, -126, -282, -17, -17, 142, +264, 209, 179, 90, -153, -147, -290, -260, +-34, -54, 303, 259, 251, 268, -141, -116, +-360, -408, -147, -188, 181, 299, 237, 423, +38, 39, -84, -330, -4, -256, 30, 94, +-127, 225, -215, 33, -26, -164, 248, -89, +266, 112, 5, 130, -229, -28, -199, -93, +0, 52, 122, 123, 60, -80, -39, -325, +-6, -176, 90, 296, 59, 506, -119, 125, +-197, -414, -8, -439, 243, 24, 174, 357, +-173, 169, -311, -192, -17, -209, 329, 115, +253, 303, -158, 64, -370, -286, -103, -299, +251, 52, 231, 305, -88, 165, -245, -149, +-44, -204, 224, 46, 177, 211, -125, 56, +-265, -213, -70, -216, 150, 63, 113, 284, +-52, 173, -34, -126, 143, -265, 124, -93, +-175, 163, -368, 185, -135, -18, 297, -162, +413, -77, 95, 87, -274, 122, -321, 23, +-68, -59, 180, -64, 169, -55, -32, -40, +-134, 14, -5, 97, 167, 120, 121, 46, +-148, -63, -299, -135, -77, -120, 245, -23, +252, 93, -23, 113, -198, 56, -84, 10, +94, 2, 53, -51, -114, -153, -109, -139, +85, 54, 215, 216, 97, 149, -151, -33, +-254, -114, -111, -84, 114, -75, 205, -59, +128, 75, -8, 239, -116, 179, -195, -132, +-182, -346, 22, -194, 292, 159, 325, 318, +1, 160, -391, -94, -390, -194, 31, -98, +400, 23, 319, 40, -60, -25, -318, -39, +-222, 72, 68, 198, 213, 133, 77, -161, +-110, -387, -97, -210, 91, 279, 152, 521, +-72, 160, -302, -424, -164, -517, 249, 2, +422, 492, 99, 378, -363, -118, -434, -378, +-57, -218, 321, 68, 332, 186, 49, 153, +-193, 62, -189, -73, -64, -170, 1, -105, +6, 81, 50, 160, 141, 44, 147, -100, +-37, -89, -252, 29, -218, 65, 43, -10, +233, -55, 166, 14, -36, 86, -150, 33, +-105, -109, -20, -134, 33, 38, 91, 200, +105, 127, 10, -131, -140, -249, -193, -84, +-48, 157, 171, 211, 229, 89, 59, -43, +-171, -120, -225, -159, -60, -129, 111, 33, +107, 215, 6, 229, -32, 37, 22, -170, +35, -202, -43, -71, -116, 82, -64, 114, +25, 43, 59, -29, 72, -19, 68, 37, +-2, 33, -114, -43, -156, -92, -34, -33, +125, 64, 126, 84, -13, 16, -84, -45, +-29, -31, 16, 17, -23, 6, -57, -66, +19, -76, 111, 51, 62, 199, -94, 148, +-163, -100, -54, -296, 106, -208, 120, 78, +3, 280, -61, 266, -12, 89, 17, -137, +-65, -328, -149, -317, -54, -26, 171, 358, +240, 448, 56, 118, -171, -298, -227, -398, +-122, -142, 15, 150, 117, 237, 181, 156, +163, 41, -20, -76, -249, -179, -275, -171, +-54, 7, 193, 209, 238, 180, 74, -55, +-97, -185, -130, -20, -67, 186, -24, 88, +-23, -233, 0, -320, 76, 39, 113, 447, +38, 390, -87, -113, -133, -492, -55, -348, +44, 118, 35, 368, -25, 191, 6, -105, +109, -139, 107, 56, -70, 98, -269, -117, +-212, -259, 113, -44, 361, 286, 235, 286, +-135, -40, -374, -256, -252, -136, 80, 40, +289, 23, 230, -16, 26, 128, -175, 254, +-267, 35, -174, -358, 66, -396, 286, 68, +260, 488, -38, 348, -311, -172, -266, -430, +35, -170, 255, 206, 172, 244, -74, 0, +-176, -140, -73, -41, 60, 78, 64, 28, +-20, -94, -41, -85, 29, 71, 52, 189, +-29, 109, -113, -114, -99, -272, 43, -174, +176, 125, 131, 327, -74, 195, -224, -123, +-159, -253, 62, -87, 205, 92, 108, 39, +-88, -82, -139, -7, -28, 184, 80, 170, +47, -80, -67, -261, -89, -156, -7, 103, +80, 207, 91, 108, 14, -44, -82, -120, +-127, -119, -73, -54, 48, 75, 147, 190, +112, 157, -42, -53, -168, -255, -154, -228, +1, 29, 162, 252, 162, 218, 9, -6, +-135, -167, -165, -127, -65, 8, 74, 79, +121, 42, 59, -33, -28, -73, -86, -19, +-56, 89, 32, 143, 48, 41, -18, -155, +-77, -216, -55, -42, 32, 187, 102, 208, +67, 37, -32, -126, -105, -154, -105, -81, +-27, 17, 81, 131, 103, 210, 3, 103, +-115, -191, -100, -354, 65, -134, 160, 294, +49, 430, -154, 84, -236, -345, -80, -375, +175, -10, 273, 289, 122, 243, -137, -8, +-291, -161, -192, -125, 80, -20, 235, 50, +139, 59, -53, 30, -135, -1, -55, 9, +30, 36, -22, -2, -88, -111, -4, -134, +147, 38, 142, 238, -57, 187, -235, -120, +-155, -325, 99, -152, 233, 220, 95, 346, +-143, 64, -212, -282, -63, -273, 107, 54, +147, 281, 61, 151, -73, -145, -151, -222, +-104, -17, 34, 196, 142, 168, 109, -44, +-77, -191, -176, -144, -50, 21, 133, 141, +135, 154, -41, 80, -194, -48, -133, -188, +83, -229, 211, -51, 137, 252, -59, 366, +-231, 89, -214, -336, 6, -417, 230, -36, +230, 365, -13, 332, -241, -35, -201, -265, +49, -156, 221, 42, 117, 78, -137, 7, +-240, 12, -72, 88, 166, 78, 229, -39, +66, -140, -166, -118, -240, 5, -107, 132, +81, 157, 178, 51, 142, -103, -24, -155, +-164, -57, -143, 68, -16, 108, 78, 56, +87, -5, 18, -35, -20, -52, -23, -55, +-67, -13, -110, 52, -36, 77, 117, 40, +178, -8, 41, -29, -153, -61, -197, -85, +-56, -32, 101, 108, 120, 173, 12, 40, +-64, -164, -18, -168, 50, 52, 29, 188, +-80, 42, -148, -182, -45, -125, 113, 149, +119, 217, 1, -41, -45, -245, 13, -69, +14, 225, -101, 155, -197, -203, -46, -290, +240, 84, 282, 403, -29, 184, -314, -309, +-239, -411, 108, 14, 289, 395, 91, 254, +-209, -165, -215, -311, 41, -72, 195, 181, +72, 150, -108, -29, -96, -85, 31, -4, +55, 41, -61, -3, -128, -41, -10, -19, +158, 18, 137, 31, -33, 31, -160, 21, +-160, -25, -33, -79, 135, -55, 184, 68, +68, 152, -127, 66, -246, -144, -129, -245, +141, -79, 268, 226, 124, 345, -135, 106, +-274, -281, -171, -411, 101, -121, 257, 312, +159, 422, -101, 86, -266, -319, -160, -356, +122, -1, 271, 309, 119, 241, -189, -69, +-311, -232, -103, -124, 201, 47, 284, 90, +91, 65, -166, 88, -225, 69, -90, -88, +24, -245, 63, -147, 83, 163, 93, 310, +64, 104, -34, -186, -174, -208, -207, -2, +-50, 110, 137, 24, 201, -55, 117, 18, +-43, 128, -137, 85, -121, -79, -92, -178, +-83, -105, 6, 47, 185, 140, 288, 121, +133, 40, -217, -25, -430, -71, -251, -123, +141, -137, 368, -37, 238, 166, -26, 288, +-156, 144, -152, -178, -126, -360, -80, -196, +28, 167, 190, 340, 219, 161, -21, -145, +-252, -249, -175, -75, 101, 134, 205, 155, +7, 0, -240, -137, -166, -109, 161, 57, +282, 197, 43, 137, -243, -108, -234, -301, +40, -185, 236, 174, 110, 373, -145, 156, +-210, -205, -18, -274, 164, -18, 120, 149, +-53, 14, -122, -140, -29, 0, 43, 256, +0, 212, -91, -113, -38, -309, 102, -160, +125, 74, -12, 126, -130, 64, -104, 75, +23, 125, 85, 22, -5, -189, -84, -245, +-11, -51, 90, 179, 66, 202, -52, 49, +-153, -64, -88, -60, 93, -28, 163, -31, +37, -32, -143, 8, -190, 49, -40, 58, +170, 48, 206, 21, 8, -49, -222, -130, +-207, -111, 35, 52, 221, 212, 122, 181, +-120, -48, -198, -248, -18, -213, 168, 12, +104, 213, -89, 228, -146, 64, -45, -131, +60, -208, 73, -115, -2, 70, -23, 171, +10, 95, -7, -66, -54, -120, -34, -15, +17, 96, 32, 65, -6, -53, -38, -92, +5, -7, 62, 66, 12, 16, -110, -52, +-113, -6, 51, 94, 182, 94, 91, -44, +-135, -166, -232, -125, -81, 38, 154, 170, +213, 168, 51, 34, -129, -141, -153, -217, +-67, -94, 29, 144, 48, 260, 26, 99, +55, -183, 96, -266, 6, -46, -162, 218, +-199, 222, -34, -29, 195, -223, 231, -142, +3, 87, -212, 173, -167, 51, 17, -94, +129, -92, 84, 20, -12, 69, -45, 9, +-44, -56, -64, -42, -65, 40, 49, 89, +172, 44, 112, -68, -126, -134, -269, -63, +-104, 87, 202, 158, 290, 62, 29, -89, +-274, -142, -238, -61, 83, 50, 254, 105, +103, 80, -155, 3, -206, -78, -7, -93, +179, -24, 107, 49, -81, 55, -128, 20, +-23, 20, 63, 37, 26, -23, -65, -122, +-34, -111, 111, 55, 118, 191, -63, 121, +-211, -76, -123, -161, 90, -66, 190, 32, +74, 34, -74, 17, -69, 77, 23, 106, +2, -15, -121, -202, -126, -199, 48, 52, +214, 276, 173, 200, -44, -90, -216, -253, +-167, -114, 16, 113, 109, 150, 63, -3, +0, -119, -15, -38, 10, 123, 19, 132, +-46, -35, -85, -186, -33, -127, 40, 74, +77, 169, 45, 77, -47, -68, -98, -92, +-34, -20, 76, 25, 108, 13, 30, 24, +-99, 52, -156, 0, -82, -111, 73, -118, +187, 53, 156, 211, -24, 138, -234, -110, +-268, -228, -26, -71, 273, 160, 293, 171, +-5, -39, -316, -182, -296, -79, 67, 137, +369, 197, 224, 44, -191, -156, -391, -194, +-156, -48, 248, 139, 373, 188, 66, 51, +-285, -133, -296, -160, -17, 8, 214, 154, +200, 106, 9, -59, -121, -120, -112, -38, +-63, 18, -33, -21, 45, -2, 162, 145, +162, 212, -43, -3, -268, -319, -239, -331, +68, 28, 327, 374, 221, 323, -137, -29, +-319, -278, -142, -216, 132, 7, 216, 127, +71, 113, -103, 59, -106, 7, -19, -58, +0, -125, -32, -93, 9, 43, 100, 176, +114, 156, -9, -16, -183, -191, -184, -198, +13, -11, 204, 191, 173, 212, -25, 12, +-176, -195, -135, -173, 32, 52, 122, 200, +44, 85, -60, -129, -44, -157, 54, 8, +61, 117, -51, 48, -136, -40, -47, 12, +131, 83, 158, -12, -12, -186, -149, -140, +-94, 128, 36, 266, 69, 60, 6, -231, +-28, -203, 46, 101, 89, 273, -30, 68, +-172, -232, -114, -250, 84, 40, 178, 274, +70, 194, -114, -57, -121, -196, 42, -118, +114, 22, -40, 65, -181, 15, -74, 7, +193, 78, 272, 109, 32, -7, -286, -187, +-306, -206, -16, 2, 259, 226, 254, 212, +60, -4, -112, -167, -173, -128, -147, -15, +-66, 21, 65, 32, 208, 99, 214, 124, +-1, -26, -233, -215, -224, -159, -5, 131, +170, 270, 125, 34, -44, -256, -82, -183, +50, 156, 105, 266, -35, -13, -168, -276, +-95, -144, 101, 182, 165, 246, 18, -7, +-131, -215, -68, -128, 97, 71, 124, 112, +-40, 16, -170, -36, -102, 0, 82, 35, +176, 8, 77, -46, -93, -80, -119, -59, +-7, 49, 81, 159, 47, 115, -53, -99, +-94, -239, 0, -81, 110, 207, 98, 226, +-24, -79, -106, -294, -73, -102, 24, 259, +74, 278, 20, -81, -50, -334, -12, -154, +73, 205, 67, 255, -45, -19, -139, -207, +-79, -75, 85, 129, 173, 93, 69, -93, +-102, -118, -151, 61, -51, 149, 82, 2, +122, -157, 38, -78, -65, 118, -80, 154, +-15, -34, 33, -184, 31, -94, 18, 105, +8, 182, 3, 48, -19, -117, -64, -141, +-37, -24, 56, 83, 95, 78, 14, 13, +-75, -11, -72, 20, 18, 1, 78, -93, +25, -140, -65, -4, -55, 198, 41, 224, +79, -3, 16, -245, -62, -226, -61, 20, +10, 207, 51, 144, 9, -38, -38, -109, +17, -33, 92, 37, 45, 12, -82, -56, +-148, -45, -66, 37, 106, 85, 180, 56, +78, -27, -64, -85, -127, -66, -98, 12, +-21, 69, 59, 42, 93, -27, 79, -34, +25, 35, -57, 60, -111, -33, -54, -136, +50, -68, 93, 105, 38, 163, -50, 31, +-67, -121, 22, -114, 94, 2, 38, 72, +-73, 40, -103, 3, -36, -7, 62, -25, +102, -37, 57, 6, -29, 76, -75, 59, +-57, -57, 0, -127, 38, -27, 25, 101, +-13, 90, -2, -30, 60, -62, 65, 37, +-24, 73, -134, -56, -148, -179, 0, -69, +201, 183, 230, 266, 31, 38, -214, -241, +-253, -268, -57, -24, 188, 211, 227, 218, +42, 35, -137, -147, -122, -167, 10, -38, +84, 105, 21, 117, -84, 11, -66, -83, +83, -58, 161, 29, 48, 44, -140, -9, +-185, -37, -40, 22, 150, 68, 173, 18, +24, -80, -119, -96, -120, -6, -30, 91, +70, 98, 113, 19, 57, -55, -53, -92, +-107, -71, -59, 11, 52, 116, 110, 134, +38, -2, -86, -178, -98, -190, 23, 29, +131, 252, 102, 223, -46, -65, -163, -309, +-121, -243, 54, 63, 177, 294, 138, 223, +-13, -36, -145, -210, -149, -140, -30, 40, +81, 111, 101, 18, 58, -69, 14, -24, +-16, 75, -50, 84, -95, -16, -78, -86, +50, -51, 165, 26, 108, 21, -71, -20, +-159, 2, -60, 70, 86, 57, 97, -55, +-28, -107, -92, -9, -3, 123, 101, 95, +56, -62, -61, -146, -97, -52, -29, 77, +49, 84, 66, 18, 35, 8, 11, 42, +-5, -8, -60, -123, -88, -147, -18, -2, +100, 158, 112, 168, 6, 43, -110, -77, +-106, -103, 6, -73, 97, -22, 76, 38, +13, 77, -29, 52, -70, -14, -100, -50, +-35, -32, 120, 14, 224, 35, 114, 27, +-172, -10, -342, -60, -159, -76, 220, -10, +393, 92, 170, 109, -202, 10, -340, -94, +-128, -60, 159, 36, 217, 32, 58, -77, +-75, -93, -67, 53, -3, 180, 9, 94, +-18, -113, -18, -153, 41, -8, 58, 103, +-15, 20, -66, -105, -18, -71, 64, 86, +71, 160, -14, 76, -93, -55, -61, -140, +37, -159, 84, -92, 48, 98, -1, 278, +-20, 213, -34, -104, -47, -357, -27, -231, +19, 147, 74, 346, 66, 160, 0, -164, +-55, -264, -49, -79, -27, 136, -4, 157, +24, 28, 56, -80, 59, -60, 19, 20, +-66, 47, -109, -27, -34, -95, 93, -38, +138, 101, 56, 150, -89, 16, -152, -163, +-63, -166, 92, 25, 161, 174, 101, 112, +-37, -61, -158, -134, -155, -69, -14, 24, +152, 81, 186, 103, 61, 65, -105, -80, +-163, -206, -72, -128, 61, 140, 95, 282, +46, 86, -2, -212, -6, -235, -2, 37, +-30, 216, -52, 61, -7, -167, 77, -118, +83, 124, -37, 190, -112, -37, -43, -224, +97, -102, 134, 160, 7, 210, -129, -18, +-115, -201, 3, -127, 87, 81, 80, 167, +38, 74, -7, -62, -45, -121, -63, -82, +-44, 12, 0, 104, 55, 99, 76, 5, +31, -76, -27, -67, -50, -7, -41, 10, +-3, -12, 37, 13, 42, 82, 16, 71, +-5, -49, -22, -140, -26, -79, 7, 50, +41, 98, 37, 55, -8, 15, -71, 7, +-81, -50, 23, -123, 151, -87, 141, 80, +-38, 170, -210, 56, -173, -110, 71, -99, +228, 65, 110, 108, -111, -49, -139, -156, +18, -19, 110, 164, -3, 120, -134, -95, +-76, -158, 123, 20, 197, 178, 38, 79, +-157, -150, -169, -202, -18, -30, 124, 155, +139, 179, 44, 57, -64, -81, -110, -155, +-77, -120, 19, 9, 123, 149, 113, 157, +-21, 5, -145, -148, -120, -133, 33, 22, +153, 139, 112, 99, -24, -42, -108, -120, +-76, -81, -11, 28, 37, 85, 63, 58, +66, -10, 17, -38, -61, -13, -87, 7, +-10, -10, 85, -24, 73, -2, -38, 4, +-103, -27, -11, -33, 122, 74, 112, 182, +-48, 80, -179, -209, -104, -355, 104, -99, +195, 315, 67, 409, -104, 63, -131, -303, +-15, -305, 76, -29, 39, 152, -26, 106, +-1, 35, 59, 62, 30, 54, -61, -106, +-95, -223, -23, -87, 82, 177, 105, 247, +36, 39, -44, -174, -91, -153, -84, -5, +-14, 59, 93, 38, 158, 47, 78, 82, +-100, 13, -196, -131, -94, -157, 104, 12, +182, 175, 65, 126, -93, -55, -99, -145, +8, -55, 63, 73, 10, 93, -51, 16, +-35, -57, 34, -77, 62, -45, 26, 36, +-8, 107, -16, 95, -29, -16, -54, -118, +-54, -112, 15, -15, 115, 82, 140, 101, +26, 58, -140, -27, -186, -102, -55, -88, +128, 26, 176, 125, 54, 70, -80, -91, +-99, -138, -24, 11, 15, 169, -17, 116, +-9, -95, 62, -175, 106, -39, 32, 109, +-110, 86, -143, -30, -7, -38, 129, 55, +103, 57, -34, -84, -107, -151, -32, -4, +75, 195, 66, 165, -37, -80, -87, -238, +-19, -115, 77, 143, 76, 231, -9, 56, +-72, -164, -48, -191, 25, -30, 60, 133, +31, 144, -23, 28, -36, -74, -15, -78, +-2, -27, -1, 4, 16, 18, 51, 44, +43, 64, -26, 1, -92, -96, -74, -77, +36, 51, 129, 126, 94, 30, -27, -126, +-102, -130, -78, 34, -3, 145, 52, 79, +68, -50, 55, -82, 3, -24, -65, 0, +-83, -21, -15, 4, 83, 67, 92, 67, +-7, -18, -88, -88, -61, -47, 34, 39, +91, 46, 42, 0, -46, -17, -77, 9, +-42, 9, 18, -21, 71, -24, 82, 25, +30, 54, -65, 5, -120, -62, -70, -55, +52, 11, 141, 39, 114, 27, -8, 28, +-126, 36, -147, -18, -44, -108, 106, -95, +175, 46, 78, 163, -94, 85, -156, -88, +-49, -136, 97, -21, 101, 76, -22, 39, +-78, -30, 6, -4, 87, 54, 28, 21, +-106, -62, -109, -72, 55, 11, 187, 57, +90, 23, -128, -14, -198, 3, -36, 19, +165, -14, 161, -40, -21, -20, -143, 17, +-72, 24, 65, 19, 74, 33, -34, 14, +-79, -51, 22, -79, 138, -3, 82, 90, +-119, 65, -207, -61, -40, -92, 193, 34, +210, 125, -7, 21, -199, -140, -156, -111, +48, 73, 148, 160, 68, 23, -29, -124, +-30, -71, 8, 68, -23, 67, -76, -73, +-22, -111, 114, 47, 142, 180, -12, 68, +-170, -147, -130, -182, 76, -5, 189, 157, +77, 115, -115, -29, -156, -92, -8, -46, +135, 2, 112, 11, -23, 5, -98, 15, +-59, 35, 20, 38, 47, 5, 19, -61, +1, -104, 11, -42, 3, 106, -35, 181, +-49, 70, 9, -130, 78, -195, 55, -76, +-52, 58, -99, 97, 2, 103, 130, 115, +98, 33, -77, -173, -177, -289, -66, -102, +137, 233, 183, 329, 24, 72, -129, -217, +-107, -213, 19, -5, 81, 103, 28, 29, +-31, -37, -13, 14, 42, 60, 38, 6, +-11, -52, -40, 5, -41, 75, -32, -11, +-7, -172, 54, -137, 115, 130, 90, 301, +-44, 125, -182, -208, -158, -304, 37, -75, +216, 180, 191, 197, -20, 43, -194, -76, +-159, -81, 22, -53, 144, -39, 88, 11, +-35, 90, -59, 101, 16, 11, 47, -101, +-22, -136, -91, -44, -27, 94, 113, 149, +129, 71, -24, -73, -165, -140, -115, -63, +66, 62, 174, 80, 97, 10, -57, -24, +-133, 17, -98, 32, -7, -39, 88, -88, +136, -11, 96, 99, -35, 74, -153, -71, +-143, -128, 0, -2, 140, 145, 143, 119, +39, -58, -67, -169, -111, -97, -78, 60, +18, 138, 107, 91, 104, -19, -11, -109, +-127, -115, -100, -5, 69, 127, 174, 142, +68, -5, -129, -166, -188, -153, -42, 26, +146, 166, 176, 131, 52, -2, -76, -87, +-120, -100, -98, -87, -35, -31, 64, 92, +153, 183, 137, 101, -10, -113, -168, -218, +-173, -79, -10, 125, 151, 156, 145, 19, +14, -94, -93, -75, -80, -9, 7, 18, +57, 36, 20, 73, -21, 51, -13, -58, +15, -147, 24, -95, 6, 60, -10, 158, +-11, 119, -13, -5, -22, -106, 14, -131, +80, -64, 76, 35, -41, 85, -161, 59, +-110, 8, 113, 2, 267, 19, 120, -19, +-190, -116, -305, -126, -81, 23, 228, 190, +269, 174, 21, -29, -211, -189, -168, -135, +53, 44, 166, 121, 63, 37, -94, -52, +-127, -22, -12, 44, 123, 15, 139, -63, +22, -52, -116, 56, -159, 95, -66, -15, +96, -130, 188, -78, 111, 91, -64, 160, +-175, 36, -125, -126, 38, -131, 165, 3, +119, 108, -45, 63, -139, -56, -62, -79, +87, 29, 132, 104, 0, 25, -144, -119, +-98, -118, 86, 56, 166, 172, 33, 49, +-137, -157, -124, -145, 50, 93, 146, 223, +38, 44, -109, -214, -87, -193, 52, 72, +111, 219, 14, 74, -93, -136, -65, -119, +54, 68, 103, 133, 18, -6, -79, -146, +-84, -92, -21, 72, 52, 130, 87, 39, +75, -56, 12, -33, -79, 26, -132, -3, +-90, -81, 50, -88, 166, 30, 155, 151, +29, 134, -126, -12, -198, -148, -117, -148, +54, -22, 198, 100, 203, 113, 43, 26, +-168, -61, -241, -60, -99, 9, 126, 55, +230, 19, 131, -57, -84, -68, -208, -1, +-116, 72, 85, 65, 182, -4, 90, -64, +-71, -62, -140, 7, -60, 61, 61, 36, +90, -36, 48, -65, -7, -4, -45, 61, +-55, 43, -28, -24, 20, -27, 50, 30, +39, 25, -17, -61, -35, -104, 9, 3, +33, 149, -11, 137, -60, -30, -41, -151, +33, -111, 89, 0, 62, 65, -10, 77, +-61, 79, -70, 32, -58, -81, -10, -157, +91, -72, 142, 121, 67, 184, -86, 31, +-165, -155, -83, -142, 73, 35, 136, 126, +59, 37, -41, -76, -51, -46, -3, 67, +25, 78, -2, -43, -60, -127, -57, -69, +35, 58, 123, 127, 117, 82, -9, -10, +-153, -92, -156, -118, -4, -59, 149, 45, +131, 118, -5, 90, -91, 15, -54, -42, +27, -74, 22, -90, -40, -57, -37, 61, +55, 156, 97, 97, 16, -87, -83, -174, +-86, -46, 18, 123, 93, 119, 53, -41, +-38, -128, -69, -39, -12, 62, 42, 54, +39, 0, 5, 6, -14, 40, -4, -7, +-8, -104, -30, -109, -21, 32, 27, 164, +62, 119, 40, -58, -28, -156, -69, -77, +-34, 72, 33, 114, 44, 20, -14, -70, +-38, -61, 19, 11, 73, 52, 27, 34, +-77, -3, -100, -15, 11, -23, 117, -46, +74, -54, -48, 3, -90, 112, -8, 139, +66, 6, 34, -185, -43, -208, -41, 6, +29, 244, 48, 223, -11, -50, -53, -249, +-10, -159, 51, 87, 39, 187, -32, 73, +-54, -74, 4, -90, 48, -17, 18, 17, +-39, 11, -31, 22, 26, 47, 43, 28, +-7, -28, -55, -65, -35, -47, 35, 8, +74, 59, 26, 78, -51, 25, -73, -69, +-20, -106, 50, -16, 65, 106, 12, 95, +-44, -43, -36, -121, 3, -25, 11, 110, +-3, 90, 1, -58, 26, -122, 39, -25, +-1, 80, -51, 60, -41, -20, 23, -38, +56, 4, 27, 0, -28, -44, -45, -24, +-10, 74, 29, 105, 34, -8, 6, -129, +-27, -96, -49, 50, -33, 117, 37, 38, +87, -42, 54, -21, -52, 28, -121, -13, +-69, -79, 51, -46, 115, 66, 68, 122, +-31, 54, -68, -67, -52, -103, -29, -52, +3, 21, 48, 71, 84, 75, 53, 13, +-47, -74, -123, -88, -81, 4, 40, 100, +128, 77, 89, -37, -20, -107, -93, -52, +-76, 32, -6, 54, 48, 28, 59, 18, +40, 26, 12, -14, -32, -81, -80, -83, +-73, 6, 18, 94, 127, 85, 133, 1, +-11, -54, -170, -44, -157, -10, 23, -9, +178, -20, 149, 12, -17, 74, -151, 92, +-127, -4, -22, -132, 60, -143, 121, 8, +128, 183, 28, 176, -137, -42, -219, -228, +-91, -161, 156, 78, 258, 207, 98, 99, +-134, -72, -189, -100, -74, -18, 42, -9, +72, -69, 63, -22, 69, 145, 32, 195, +-89, -19, -144, -262, -39, -184, 127, 123, +149, 252, -9, 33, -150, -202, -95, -114, +71, 147, 134, 172, 32, -76, -89, -222, +-78, -46, 23, 188, 72, 151, 6, -87, +-64, -192, -26, -35, 62, 151, 79, 125, +3, -38, -86, -116, -85, -48, 4, 35, +67, 30, 50, -11, 14, -8, -10, 49, +-8, 60, -12, -8, -33, -85, -26, -93, +25, -27, 53, 55, 15, 83, -27, 57, +-22, 27, 11, -11, 18, -66, -16, -114, +-42, -71, -5, 69, 46, 164, 25, 96, +-22, -75, -27, -141, 8, -27, 37, 86, +9, 34, -45, -83, -41, -58, 11, 99, +38, 149, 24, -23, -1, -191, -4, -122, +-1, 111, -7, 200, -28, 48, -26, -140, +13, -147, 18, -5, 7, 94, 16, 88, +30, 40, 9, 1, -43, -62, -74, -105, +-25, -59, 57, 58, 69, 125, 6, 68, +-49, -32, -31, -67, 18, -31, 26, 4, +-12, 4, -51, -6, -30, -6, 26, 16, +67, 43, 73, 49, -3, 0, -104, -87, +-112, -105, -2, 4, 133, 126, 136, 103, +-28, -49, -165, -134, -110, -39, 67, 97, +160, 99, 70, -13, -81, -79, -130, -47, +-49, -5, 50, -1, 76, 21, 55, 80, +20, 80, -38, -28, -76, -134, -54, -95, +3, 49, 65, 113, 69, 28, 13, -61, +-38, -22, -50, 64, -28, 50, 13, -54, +29, -104, 10, -37, -7, 51, 10, 70, +24, 46, -6, 20, -46, -25, -47, -87, +22, -93, 96, 19, 63, 136, -39, 89, +-97, -86, -75, -170, 14, -39, 93, 173, +87, 201, 28, -14, -60, -229, -117, -209, +-68, 21, 58, 214, 130, 184, 58, -5, +-74, -140, -98, -113, -1, -4, 72, 46, +27, 11, -59, -4, -33, 52, 57, 84, +58, -11, -37, -142, -94, -125, -10, 60, +127, 190, 108, 87, -59, -133, -171, -190, +-99, -17, 84, 161, 168, 137, 80, -29, +-57, -117, -106, -56, -65, 31, -8, 23, +29, -20, 56, 1, 57, 50, 22, 39, +-30, -32, -73, -51, -42, -4, 30, 21, +48, -13, 27, -40, -5, 5, -23, 62, +-18, 44, -10, -29, 3, -50, 42, -4, +55, 24, 7, -27, -79, -65, -111, -9, +-26, 88, 109, 108, 180, 13, 75, -94, +-128, -112, -218, -39, -116, 41, 93, 72, +217, 64, 130, 38, -59, 10, -163, -44, +-125, -107, -4, -101, 102, 17, 118, 158, +50, 155, -69, -20, -127, -186, -61, -132, +74, 77, 129, 172, 22, 33, -106, -130, +-87, -87, 33, 89, 89, 127, 3, -36, +-90, -155, -21, -46, 99, 143, 83, 136, +-58, -55, -157, -157, -71, -52, 107, 79, +161, 62, 50, -19, -96, 4, -133, 81, +-49, 27, 57, -137, 97, -173, 43, 18, +-33, 209, -46, 152, -23, -61, 1, -156, +4, -56, -7, 57, 14, 39, 33, -35, +-2, -21, -34, 57, -22, 75, 8, -2, +21, -79, -9, -70, -20, 0, 10, 61, +31, 53, 0, 4, -45, -43, -15, -50, +41, -18, 40, 17, -12, 42, -45, 48, +-20, 26, 30, -55, 11, -131, -28, -90, +11, 86, 56, 225, 29, 126, -65, -139, +-114, -267, -30, -92, 100, 168, 120, 203, +17, 9, -89, -125, -89, -62, -26, 45, +13, 22, 19, -55, 25, -17, 62, 92, +57, 83, -42, -73, -123, -158, -86, -33, +38, 150, 130, 144, 73, -38, -59, -162, +-103, -80, -33, 82, 56, 118, 60, 10, +-20, -86, -67, -67, -33, 34, 33, 95, +51, 45, 8, -66, -29, -117, -26, -45, +1, 90, 13, 138, -19, 35, -41, -107, +-15, -127, 22, -10, 49, 107, 40, 101, +-17, 10, -67, -74, -84, -94, -45, -49, +51, 34, 120, 112, 82, 104, -42, -14, +-132, -134, -92, -130, 32, -9, 104, 103, +46, 110, -66, 44, -74, -27, 5, -75, +67, -97, 57, -50, -31, 65, -93, 128, +-72, 57, -9, -76, 72, -117, 114, -18, +39, 93, -91, 72, -146, -31, -58, -72, +74, -17, 107, 30, 26, 13, -67, -6, +-57, 18, 7, 43, 10, 0, -18, -76, +-14, -73, 13, 22, 30, 95, -1, 53, +-50, -39, -42, -66, 1, -15, 40, 26, +38, 13, -5, -17, -57, 0, -69, 31, +-20, 18, 49, -32, 59, -42, 2, 9, +-57, 60, -57, 32, 4, -49, 26, -76, +-3, -11, -25, 77, -16, 77, 12, -12, +15, -83, -20, -51, -34, 31, -17, 62, +-5, 19, 4, -35, 5, -33, 0, 2, +-10, 16, -24, 15, -27, 24, -7, 10, +9, -31, -2, -64, -27, -18, -28, 88, +1, 110, 17, -8, 3, -130, -42, -99, +-56, 47, 0, 123, 50, 47, 38, -66, +-22, -65, -77, 12, -61, 25, 15, -38, +60, -40, 32, 64, -25, 119, -52, 5, +-40, -161, -19, -143, -2, 64, 10, 203, +28, 97, 19, -111, -45, -156, -84, -16, +-47, 105, 26, 70, 71, -37, 30, -62, +-53, -4, -79, 40, -53, 38, 0, 13, +37, -12, 28, -45, 3, -67, -34, -20, +-54, 77, -34, 114, -4, 37, 20, -94, +4, -128, -38, -33, -25, 78, 17, 106, +30, 30, -15, -57, -86, -69, -78, -17, +22, 28, 93, 17, 51, -12, -69, 7, +-118, 47, -53, 39, 44, -46, 63, -104, +-1, -42, -55, 87, -63, 129, -41, 29, +-2, -92, 44, -94, 42, -1, -8, 44, +-84, 12, -114, -2, -34, 45, 60, 69, +81, -19, 33, -130, -39, -109, -80, 50, +-80, 158, -45, 77, 8, -80, 57, -129, +54, -27, -2, 91, -61, 90, -79, -11, +-48, -91, -15, -65, 6, 25, 15, 80, +15, 55, 9, -16, -17, -52, -41, -39, +-59, -14, -62, -4, -19, 4, 39, 49, +62, 73, 16, 13, -73, -87, -100, -110, +-44, 0, 32, 105, 54, 75, -10, -32, +-72, -67, -64, 7, -22, 60, 24, 0, +26, -79, 0, -49, -30, 66, -59, 103, +-70, 6, -36, -98, 19, -80, 51, 28, +40, 85, -18, 37, -79, -31, -98, -40, +-66, -9, 0, 0, 58, -18, 67, -8, +12, 46, -51, 73, -93, 19, -99, -76, +-53, -115, 21, -42, 72, 87, 66, 133, +-1, 47, -88, -70, -114, -96, -84, -23, +-14, 29, 57, 4, 76, -23, 41, 32, +-50, 104, -136, 56, -130, -96, -16, -173, +110, -54, 115, 127, -24, 157, -166, 18, +-152, -98, 4, -74, 141, 9, 96, 27, +-82, -11, -184, -1, -113, 55, 45, 51, +121, -40, 58, -97, -68, -26, -130, 86, +-97, 89, -17, -29, 58, -108, 70, -46, +2, 79, -93, 103, -117, -6, -48, -107, +46, -74, 60, 50, -19, 115, -78, 50, +-78, -64, -23, -116, 26, -50, 13, 63, +-13, 107, -33, 52, -44, -48, -59, -88, +-42, -56, -6, 13, 27, 62, 27, 64, +-33, 30, -79, -29, -77, -75, -22, -69, +25, 7, 21, 83, -28, 85, -62, 5, +-38, -75, 1, -73, 3, -2, -40, 47, +-75, 39, -43, -5, 24, -24, 46, 2, +-9, 30, -78, 15, -103, -27, -49, -57, +28, -36, 58, 36, 24, 80, -63, 50, +-114, -31, -81, -78, 3, -47, 69, 13, +43, 40, -54, 29, -108, 13, -72, 3, +-2, -23, 46, -50, 13, -23, -51, 47, +-66, 65, -38, -12, -3, -86, 0, -42, +-26, 78, -49, 101, -37, -19, -15, -128, +-2, -73, -3, 80, -26, 126, -50, 15, +-66, -94, -45, -70, 1, 28, 36, 52, +1, -1, -74, -15, -95, 39, -42, 60, +45, -29, 45, -126, -52, -86, -116, 69, +-70, 161, 37, 79, 78, -79, 8, -136, +-97, -52, -118, 56, -69, 59, 9, -15, +57, -20, 42, 60, -9, 97, -95, -6, +-147, -162, -96, -161, 39, 39, 131, 221, +61, 180, -107, -52, -194, -213, -93, -137, +73, 56, 108, 145, -4, 68, -123, -34, +-112, -49, -12, -9, 50, -13, 8, -35, +-48, -1, -59, 66, -40, 66, -19, -31, +-28, -107, -22, -54, -1, 80, -4, 125, +-48, 27, -79, -108, -54, -130, 8, -8, +46, 122, -8, 125, -81, 3, -101, -114, +-40, -107, 37, 6, 50, 85, -16, 63, +-94, -7, -95, -34, -39, -10, 25, -4, +26, -27, -19, -18, -42, 41, -52, 76, +-55, 14, -55, -79, -27, -85, 16, 12, +29, 93, -18, 57, -68, -27, -62, -46, +-42, -9, -38, -2, -36, -45, -6, -32, +58, 63, 52, 134, -73, 55, -186, -116, +-138, -182, 29, -53, 147, 136, 83, 171, +-81, 38, -157, -106, -99, -122, 1, -31, +36, 50, 7, 62, -25, 31, -25, 3, +-29, -25, -53, -42, -59, -30, -41, 18, +-9, 63, 10, 39, 0, -41, -25, -84, +-49, -29, -68, 71, -59, 101, -10, 16, +15, -92, 10, -103, -26, -8, -62, 98, +-58, 104, -39, 8, -30, -87, -16, -96, +16, -23, 25, 62, -20, 94, -106, 46, +-136, -36, -40, -83, 86, -56, 112, 19, +-9, 69, -156, 43, -161, -27, -27, -52, +95, -15, 80, 31, -32, 28, -123, -19, +-90, -41, -9, -2, 33, 38, 14, 33, +-38, -7, -70, -38, -63, -32, -20, -7, +6, 33, 17, 57, -5, 34, -63, -33, +-84, -96, -56, -75, 8, 35, 43, 129, +4, 99, -68, -25, -86, -119, -38, -98, +8, 1, 5, 74, -45, 74, -46, 29, +-2, -13, 12, -39, -28, -57, -85, -39, +-78, 16, 2, 63, 64, 55, 21, -7, +-65, -62, -105, -52, -67, 11, 12, 54, +33, 30, -1, -23, -44, -34, -48, 0, +-43, 37, -42, 16, -34, -43, -8, -49, +35, 15, 5, 82, -73, 55, -108, -41, +-62, -87, 40, -39, 69, 46, -12, 63, +-97, 12, -80, -30, -8, -15, 25, 18, +-20, 4, -67, -36, -34, -41, 26, 6, +20, 63, -46, 62, -92, 3, -63, -61, +0, -68, 23, -20, -1, 39, -13, 63, +-18, 30, -36, -20, -68, -49, -83, -27, +-35, 13, 47, 35, 73, 23, 0, -8, +-90, -37, -119, -39, -56, 9, 27, 63, +48, 65, 0, -3, -50, -96, -53, -103, +-33, 2, -21, 114, -24, 117, -5, 11, +4, -90, -27, -99, -61, -45, -69, 23, +-16, 75, 56, 87, 43, 55, -42, -36, +-117, -121, -102, -118, -16, 5, 71, 129, +63, 143, -19, 30, -84, -113, -96, -141, +-42, -34, 9, 102, 15, 119, -10, 9, +-25, -94, -18, -74, -3, 37, -16, 83, +-67, 7, -75, -85, -19, -58, 51, 65, +53, 109, -30, 6, -109, -114, -83, -99, +16, 34, 66, 124, 18, 64, -76, -52, +-98, -84, -30, -31, 44, 19, 44, 23, +-19, 12, -70, 27, -69, 41, -31, -2, +-1, -67, 5, -68, -1, 5, -13, 74, +-17, 67, -26, -14, -33, -69, -38, -38, +-34, 27, -24, 51, -3, 8, 22, -40, +12, -25, -12, 21, -64, 41, -82, 0, +-50, -32, 4, -16, 61, 8, 52, 10, +-22, -6, -88, 0, -88, 24, -38, 16, +21, -32, 35, -52, 8, 2, -11, 69, +-39, 61, -64, -31, -55, -87, -13, -32, +33, 59, 31, 67, -27, -14, -77, -64, +-41, -19, 21, 51, 30, 37, -18, -40, +-62, -65, -42, 6, 10, 76, 15, 49, +-28, -45, -38, -83, 1, -23, 30, 58, +-11, 63, -81, -6, -65, -61, 13, -38, +68, 20, 28, 39, -58, 7, -78, -28, +-19, -22, 18, 12, -7, 31, -36, 19, +-36, -8, 15, -37, 33, -38, -17, -6, +-60, 45, -44, 70, -7, 28, 3, -55, +-10, -99, -24, -47, 3, 56, 28, 110, +-7, 59, -74, -29, -87, -81, -30, -65, +52, -20, 83, 24, 24, 62, -58, 76, +-97, 40, -78, -53, -12, -122, 45, -83, +64, 44, 28, 137, -47, 104, -97, -19, +-85, -109, -5, -99, 73, -14, 77, 63, +-5, 79, -83, 41, -102, -19, -51, -60, +40, -50, 78, 9, 35, 57, -33, 33, +-77, -31, -83, -52, -19, -7, 47, 54, +56, 48, 19, -16, -44, -58, -79, -34, +-46, 23, 9, 43, 25, 15, 12, -15, +-11, -12, -18, 5, -8, 9, -19, -8, +-45, -29, -28, -25, 16, 12, 55, 50, +26, 50, -50, -2, -89, -69, -53, -74, +19, -6, 61, 72, 38, 86, -9, 20, +-32, -53, -60, -78, -64, -55, -22, -4, +45, 60, 85, 94, 52, 64, -61, -31, +-129, -129, -73, -117, 28, 13, 76, 145, +42, 140, -17, -6, -39, -140, -21, -123, +-30, 18, -36, 113, -8, 76, 29, -32, +40, -87, 5, -36, -45, 43, -45, 61, +-4, 14, 18, -32, 6, -41, -21, -26, +-17, -10, 3, 20, 3, 55, -11, 52, +-9, 0, -7, -61, -9, -69, -24, -15, +-38, 39, -5, 55, 44, 39, 49, 11, +-7, -27, -57, -65, -74, -63, -17, -2, +47, 84, 47, 95, 8, 10, -26, -84, +-35, -94, -30, -9, -9, 62, 7, 57, +22, 9, 27, -28, -7, -23, -49, -14, +-35, -19, 18, -15, 60, 14, 25, 45, +-55, 42, -89, -4, -30, -56, 63, -63, +88, -17, 19, 51, -55, 72, -66, 30, +-44, -37, -5, -64, 17, -36, 39, 17, +66, 44, 34, 30, -63, -1, -118, -17, +-68, -12, 35, -7, 124, -15, 85, -13, +-37, 7, -104, 36, -68, 38, 0, -1, +55, -51, 53, -60, -2, -8, -35, 59, +-30, 66, -9, 5, 21, -64, 33, -67, +-7, -1, -35, 58, -39, 62, -9, 10, +29, -46, 46, -60, 17, -25, -26, 25, +-39, 49, -25, 39, -7, 0, 10, -40, +32, -50, 20, -16, 3, 22, -12, 32, +-27, 17, -26, -1, 2, -6, 8, -8, +4, -16, 13, -21, 7, -7, 6, 16, +3, 31, -17, 24, -39, 2, -17, -25, +-5, -36, 14, -30, 45, 8, 38, 61, +-3, 74, -49, 15, -84, -76, -57, -109, +42, -38, 110, 82, 85, 139, -25, 71, +-107, -76, -88, -156, 1, -89, 66, 49, +64, 137, 13, 99, -17, -15, -22, -97, +-32, -86, -35, -14, -7, 45, 47, 54, +68, 29, 24, -1, -69, -25, -92, -34, +-16, -20, 75, 11, 94, 34, 16, 33, +-84, -5, -97, -38, -17, -35, 62, 0, +88, 43, 38, 58, -47, 25, -89, -45, +-52, -86, 17, -50, 77, 45, 64, 110, +-5, 66, -63, -43, -52, -115, 14, -73, +48, 39, 17, 100, -36, 59, -24, -29, +18, -67, 52, -40, 19, 4, -45, 25, +-55, 26, -1, 21, 35, 13, 29, -12, +4, -39, -21, -34, 1, 6, 11, 42, +-15, 37, -31, 1, -4, -23, 17, -15, +30, 2, 6, 9, -32, -5, -12, -15, +24, 0, 16, 18, -26, 29, -49, 22, +-16, -10, 56, -37, 75, -47, 15, -21, +-71, 35, -75, 71, -14, 56, 47, -12, +53, -76, 21, -76, -10, -6, -24, 64, +-18, 64, -36, 16, -22, -25, 30, -18, +65, 1, 30, -8, -31, -39, -75, -34, +-41, 27, 47, 87, 65, 80, 9, -4, +-34, -101, -34, -118, -16, -33, 17, 84, +9, 132, 9, 72, 33, -39, 15, -105, +-48, -87, -59, -23, -12, 44, 58, 83, +91, 77, 21, 16, -68, -79, -85, -118, +-26, -48, 49, 77, 79, 136, 32, 53, +-31, -89, -59, -128, -28, -27, 17, 96, +34, 96, 25, -16, -4, -92, -18, -48, +-13, 50, 5, 70, 4, -3, 6, -65, +5, -43, -4, 27, -5, 54, -6, 29, +-7, -17, 13, -34, 28, -22, -1, -9, +-25, 5, -31, 28, -9, 33, 28, 7, +46, -31, 17, -45, -15, -7, -37, 40, +-32, 28, 8, -24, 42, -43, 30, 1, +0, 44, -24, 33, -32, -19, 0, -42, +22, -3, 25, 27, 2, 1, -26, -40, +-25, -27, 7, 53, 30, 92, 32, 19, +5, -99, -38, -119, -43, -12, -9, 106, +31, 110, 53, 7, 33, -75, -18, -75, +-47, -10, -44, 30, -9, 23, 39, 15, +57, 22, 22, 14, -24, -25, -51, -50, +-37, -33, 30, 20, 58, 59, 23, 38, +-33, -22, -40, -59, -4, -33, 41, 17, +32, 42, -10, 17, -33, -19, -13, -29, +29, -11, 29, 10, -5, 16, -28, 8, +-7, -6, 13, -11, 19, -6, -20, 13, +-36, 21, 0, 19, 32, -2, 26, -28, +-5, -26, -29, 4, -36, 34, 10, 22, +31, -12, 24, -24, 10, 1, -9, 19, +-40, 5, -38, -25, 0, -22, 48, 20, +78, 47, 17, 21, -75, -40, -96, -59, +-14, -11, 78, 52, 97, 52, 20, 1, +-71, -35, -80, -27, -12, -2, 39, 7, +38, -2, 23, 7, 10, 38, -8, 35, +-31, -24, -45, -73, -28, -44, 40, 44, +85, 90, 44, 37, -41, -62, -77, -91, +-52, -19, 28, 63, 79, 74, 52, 6, +-3, -52, -42, -55, -55, -18, -35, 24, +27, 48, 56, 52, 56, 10, 7, -53, +-60, -89, -69, -36, -8, 58, 54, 99, +56, 41, 16, -55, -32, -81, -35, -31, +-6, 23, 8, 28, 13, 6, 20, 16, +24, 30, 12, -3, -26, -68, -39, -86, +-12, -3, 30, 109, 42, 116, 15, -5, +-23, -126, -27, -116, -8, 9, 3, 105, +20, 80, 30, -17, 21, -60, -10, -24, +-39, 14, -40, 2, 13, -19, 58, 2, +38, 49, -15, 47, -51, -15, -37, -54, +18, -29, 45, 27, 19, 35, -10, 2, +-19, -13, -4, 17, 3, 36, -7, -5, +-9, -57, 11, -42, 27, 36, 22, 72, +-7, 27, -32, -48, -13, -62, 13, -9, +18, 32, 10, 16, 7, -4, -3, 16, +-4, 28, -14, -14, -27, -75, 8, -70, +43, 33, 36, 114, -6, 63, -48, -71, +-41, -136, 19, -50, 58, 80, 34, 109, +-16, 10, -52, -79, -37, -66, 12, 13, +50, 50, 46, 9, 9, -35, -43, -17, +-63, 35, -21, 35, 51, -13, 82, -52, +34, -31, -52, 29, -77, 53, -27, 31, +43, -8, 72, -27, 25, -17, -30, -4, +-36, 10, -24, 32, -2, 41, 22, 27, +27, -11, 21, -41, 6, -36, -19, 3, +-30, 53, -6, 66, 15, 19, 25, -46, +20, -68, 2, -30, -9, 41, -12, 72, +-19, 39, -15, -28, 23, -67, 34, -46, +25, 0, -11, 41, -35, 43, -22, 10, +11, -39, 29, -66, 16, -44, 4, 18, +-2, 51, 7, 18, -3, -44, -13, -54, +-20, -3, 4, 30, 34, 1, 30, -41, +0, -29, -21, 30, -19, 52, -12, -11, +15, -79, 27, -53, 27, 38, 13, 83, +-16, 26, -37, -56, -14, -46, 21, 34, +26, 71, 8, 16, -20, -50, -19, -29, +9, 54, 24, 89, -8, 31, -25, -44, +-14, -50, 20, 11, 34, 54, 9, 38, +-28, 10, -21, 1, 16, 12, 22, -1, +10, -27, -23, -18, -5, 22, 25, 54, +31, 23, -7, -35, -41, -57, -25, -17, +26, 33, 61, 33, 23, -7, -23, -39, +-50, -38, -17, -25, 25, -16, 41, -4, +28, 20, 3, 35, -18, -9, -28, -85, +-18, -104, -3, -29, 37, 73, 57, 94, +25, 14, -36, -85, -57, -104, -30, -33, +29, 38, 64, 47, 35, 13, -6, -4, +-34, 11, -31, 15, -8, -22, 17, -57, +22, -28, 20, 57, 5, 113, -12, 72, +-12, -27, -2, -86, 4, -48, 13, 35, +1, 87, -2, 65, 15, 18, 20, -7, +3, -4, -21, -4, -24, -13, 2, 1, +35, 43, 28, 60, 2, 23, -21, -29, +-13, -46, 9, -6, 14, 33, -5, 25, +-15, -13, 6, -28, 31, -9, 24, 11, +-18, -2, -46, -28, -17, -37, 42, -22, +61, -7, 23, -15, -38, -29, -50, -23, +-7, -8, 36, -5, 36, -18, 13, -37, +-14, -29, -21, -5, -10, 0, -7, -16, +17, -25, 35, -7, 28, 20, -4, 13, +-31, -23, -37, -46, 8, -21, 43, 34, +34, 55, 17, 29, -11, -8, -21, -13, +-22, 2, -12, 12, 4, 7, 45, 23, +52, 68, 5, 81, -48, 28, -71, -51, +-7, -73, 59, 4, 80, 93, 20, 111, +-47, 45, -58, -35, -17, -59, 34, -30, +37, 18, 33, 42, 9, 47, -10, 25, +-33, -20, -29, -60, 0, -46, 48, 9, +55, 43, 6, 18, -39, -45, -51, -67, +-5, -30, 44, 14, 43, 13, 6, -30, +-10, -57, -15, -45, 2, -23, 14, -15, +6, -12, 1, -2, 5, -1, 4, -28, +7, -58, 17, -45, 7, 7, -3, 42, +-19, 15, -9, -39, 14, -40, 37, 13, +23, 52, -12, 28, -32, -26, -29, -32, +9, 21, 27, 70, 33, 59, 12, 8, +2, -33, -14, -17, -24, 30, -17, 56, +11, 53, 48, 31, 37, 10, 10, 1, +-38, 9, -47, 22, -23, 25, 26, 14, +57, 1, 55, 14, 14, 30, -44, 17, +-60, -19, -33, -41, 30, -12, 72, 23, +55, 26, -11, -11, -49, -41, -42, -31, +-5, -11, 34, -13, 32, -29, 26, -28, +14, -5, -10, -9, -29, -50, -26, -68, +1, -26, 46, 31, 56, 34, 10, -40, +-38, -98, -43, -72, -7, 13, 33, 65, +44, 34, 16, -22, -7, -47, -19, -30, +-27, -8, -14, 2, 21, 17, 50, 41, +50, 47, -6, 18, -63, -22, -56, -27, +10, 6, 70, 40, 63, 49, 0, 42, +-56, 43, -51, 40, -8, 11, 30, -31, +47, -39, 33, 22, 11, 92, -23, 95, +-45, 15, -23, -68, 24, -66, 62, 5, +44, 71, -19, 64, -59, -2, -26, -47, +24, -42, 48, -11, 27, 17, -17, 18, +-19, -5, 1, -39, 12, -61, -3, -47, +8, 5, 13, 49, 20, 20, 9, -67, +-22, -124, -18, -69, 11, 42, 43, 96, +15, 29, -15, -92, -39, -130, -7, -52, +39, 62, 43, 97, 13, 32, -36, -60, +-39, -96, -12, -55, 40, 29, 53, 97, +31, 101, -28, 24, -62, -80, -39, -112, +23, -27, 79, 111, 59, 162, -8, 71, +-67, -62, -48, -104, 2, -22, 49, 72, +46, 83, 10, 41, -3, 18, -10, 34, +-23, 17, -27, -47, -4, -77, 34, -5, +66, 107, 32, 119, -26, 5, -58, -100, +-30, -84, 21, 6, 53, 49, 37, 5, +-4, -23, -16, 6, -3, 29, 4, -13, +-12, -89, -10, -90, 13, -1, 52, 78, +39, 45, -7, -54, -47, -95, -41, -45, +15, 20, 51, 25, 50, -14, 9, -34, +-15, -17, -36, 2, -21, -7, 9, -17, +36, 5, 48, 22, 22, 0, -15, -36, +-37, -28, -17, 30, 20, 61, 51, 20, +29, -39, -3, -40, -15, 32, -20, 89, +-3, 48, 11, -41, 28, -68, 31, 11, +18, 94, -15, 83, -39, -2, -17, -63, +33, -34, 64, 40, 27, 65, -34, 18, +-42, -28, 0, -16, 53, 19, 50, 25, +-5, -7, -44, -31, -13, -21, 36, 8, +44, 13, 16, 1, -25, 0, -16, -5, +14, -23, 23, -53, 7, -50, 2, 9, +11, 71, 18, 53, 11, -47, -12, -122, +-7, -87, 19, 33, 30, 105, 13, 55, +-10, -53, -7, -96, 20, -45, 35, 24, +11, 44, -16, 18, -14, -2, 21, -12, +46, -21, 20, -21, -9, 5, -14, 55, +1, 58, 23, -15, 17, -77, 10, -46, +22, 64, 28, 127, 4, 46, -21, -83, +-23, -108, 14, 1, 59, 112, 56, 98, +1, -5, -48, -74, -35, -43, 7, 27, +58, 47, 56, 21, 15, -2, -19, -7, +-29, -16, -5, -34, 27, -26, 57, 18, +41, 57, 9, 29, -33, -51, -34, -98, +8, -54, 56, 43, 75, 87, 32, 43, +-32, -47, -63, -99, -24, -68, 41, 7, +87, 60, 63, 54, -8, 14, -63, -28, +-48, -55, 15, -47, 66, -17, 69, 23, +20, 56, -18, 52, -31, 6, -5, -51, +20, -63, 29, -16, 27, 45, 29, 67, +14, 40, -3, -8, -11, -36, -3, -34, +21, -5, 33, 35, 24, 66, 6, 52, +8, -12, 3, -70, 6, -59, 7, 23, +22, 92, 35, 76, 31, -25, 12, -99, +-13, -60, -8, 43, 12, 87, 39, 32, +25, -45, 16, -62, 13, -5, 14, 35, +3, 15, -14, -30, -1, -29, 32, 16, +70, 33, 42, -1, -16, -48, -52, -41, +-18, 1, 54, 28, 79, 13, 46, -15, +-14, -13, -28, -3, -10, -5, 20, -19, +27, -10, 34, 19, 44, 35, 27, 10, +-11, -30, -37, -33, -10, 6, 48, 44, +76, 32, 38, -12, -26, -31, -35, -5, +7, 35, 54, 37, 50, 7, 12, -27, +-1, -24, 7, 8, 21, 26, 12, 32, +11, 21, 29, 3, 47, -24, 27, -41, +-25, -21, -28, 35, 20, 83, 76, 52, +65, -42, 3, -115, -37, -76, -13, 51, +39, 125, 55, 67, 26, -54, -2, -113, +14, -63, 33, 30, 21, 64, -8, 34, +-7, -5, 35, -26, 62, -36, 38, -44, +-13, -26, -18, 26, 17, 68, 48, 34, +36, -44, 0, -79, -2, -33, 32, 44, +45, 60, 23, 1, -7, -41, -5, -21, +33, 16, 60, 21, 32, -9, -9, -19, +-13, 11, 20, 38, 49, 21, 47, -20, +17, -26, -7, 8, 1, 38, 17, 22, +37, -13, 45, -18, 35, 8, 16, 28, +-10, 22, -15, -2, 15, -13, 63, -6, +65, 8, 28, 9, -18, 9, -27, 9, +19, -1, 61, -13, 59, -21, 28, -8, +1, 19, -3, 26, 16, -2, 23, -37, +32, -44, 48, -6, 50, 42, 21, 47, +-17, -8, -24, -73, 21, -73, 78, 1, +80, 74, 28, 66, -26, -14, -31, -82, +10, -65, 58, 0, 62, 45, 43, 36, +26, 4, 9, -8, -6, -17, -5, -37, +17, -42, 64, -1, 84, 62, 37, 70, +-19, 0, -44, -67, 0, -52, 61, 27, +77, 64, 37, 21, -1, -28, -5, -14, +21, 29, 38, 32, 16, -17, 14, -49, +31, 6, 51, 67, 46, 49, 15, -31, +-11, -74, -2, -20, 38, 57, 61, 63, +57, 1, 24, -43, -6, -31, -8, 2, +16, 9, 45, 4, 60, 23, 45, 38, +13, 5, -11, -57, -4, -74, 26, -3, +58, 81, 60, 74, 28, -19, 2, -93, +-3, -67, 22, 19, 52, 60, 50, 28, +22, -25, 9, -38, 13, -14, 37, 2, +51, 1, 30, 1, 5, 11, 0, 11, +21, -11, 48, -26, 62, -14, 36, 20, +9, 28, 4, -4, 5, -31, 31, -28, +53, 10, 57, 39, 39, 32, 10, -7, +-13, -34, 2, -27, 41, 3, 65, 30, +63, 29, 22, 18, -14, 2, -4, -14, +24, -24, 48, -24, 56, 5, 40, 47, +18, 65, 7, 19, -3, -53, 16, -81, +52, -22, 69, 62, 53, 81, 4, 21, +-32, -48, 2, -60, 65, -14, 86, 22, +50, 20, -8, 8, -25, 12, 23, 11, +62, -16, 55, -52, 27, -37, 5, 32, +19, 69, 39, 31, 32, -49, 15, -73, +25, -20, 47, 39, 40, 49, 12, 3, +0, -32, 26, -22, 72, -3, 59, 0, +5, -10, -24, 0, 3, 24, 63, 28, +80, -2, 33, -34, -12, -28, -6, 7, +28, 30, 51, 19, 40, -2, 25, -5, +34, 7, 42, -4, 18, -27, -9, -26, +5, 17, 53, 66, 89, 53, 54, -20, +-18, -79, -36, -61, 15, 24, 72, 88, +81, 66, 28, -8, -5, -64, 13, -53, +30, 0, 32, 32, 28, 31, 30, 25, +44, 11, 49, -18, 19, -42, 3, -31, +16, 20, 39, 52, 52, 18, 34, -38, +20, -49, 37, 6, 42, 57, 22, 17, +4, -54, 9, -63, 48, 11, 75, 73, +53, 37, 3, -46, -18, -64, 3, -1, +41, 51, 68, 20, 58, -39, 30, -33, +12, 21, -5, 43, -5, -4, 29, -49, +67, -25, 80, 32, 46, 39, -20, -10, +-30, -48, 21, -16, 64, 41, 71, 31, +41, -22, 9, -40, 16, -3, 26, 32, +18, 12, 11, -21, 28, -13, 64, 26, +71, 32, 34, -20, -14, -55, -15, -18, +22, 44, 64, 52, 70, 2, 39, -35, +12, -20, 7, 13, 4, 15, 15, -12, +41, -3, 51, 34, 57, 37, 28, -1, +-11, -41, -8, -28, 27, 19, 61, 28, +59, 3, 34, -17, 8, 8, 9, 34, +24, 8, 26, -45, 33, -61, 41, -9, +43, 56, 35, 69, 13, 24, 0, -36, +13, -63, 38, -57, 52, -12, 46, 49, +28, 82, 10, 52, 8, -37, 14, -101, +30, -76, 47, 19, 49, 82, 38, 58, +20, -10, 0, -49, 11, -44, 38, -19, +44, 10, 34, 32, 24, 42, 14, 22, +23, -33, 27, -61, 19, -28, 29, 41, +38, 70, 38, 24, 28, -44, 9, -54, +8, -11, 35, 32, 43, 42, 35, 14, +22, -1, 14, -5, 23, -11, 37, -24, +30, -13, 15, 26, 19, 52, 35, 32, +42, -14, 31, -43, 10, -28, 9, 8, +32, 28, 44, 23, 38, 8, 23, -6, +14, -12, 27, -15, 45, -17, 29, 1, +7, 14, 5, 16, 23, 10, 61, -6, +62, -11, 17, -12, -16, -18, -11, -16, +33, -1, 69, 23, 61, 28, 21, 1, +-7, -29, -2, -43, 26, -25, 39, 14, +36, 26, 44, 8, 47, -10, 35, -18, +0, -16, -20, -13, 1, -11, 58, 2, +95, 20, 62, 20, -8, 0, -49, -26, +-12, -31, 59, -3, 91, 27, 53, 27, +3, 3, -16, -13, 2, -7, 30, 6, +34, 8, 35, -2, 43, 1, 41, 14, +18, 17, -12, 6, -8, -11, 29, -5, +64, 12, 58, 9, 16, -4, -9, -4, +5, 15, 29, 29, 41, 0, 32, -42, +19, -37, 30, 10, 34, 56, 15, 44, +3, -17, 7, -53, 27, -30, 47, 7, +39, 24, 12, 19, 8, 1, 28, -10, +34, -21, 24, -31, -1, -20, 8, 12, +41, 34, 59, 22, 32, -8, -11, -37, +-18, -40, 13, -15, 49, 14, 61, 28, +42, 28, 11, 7, -6, -34, -3, -61, +7, -32, 34, 30, 63, 71, 62, 48, +22, -23, -25, -70, -36, -51, 9, 10, +74, 56, 84, 57, 40, 19, -20, -25, +-40, -46, -6, -32, 45, 10, 69, 50, +55, 58, 18, 18, -12, -33, -23, -46, +-1, -18, 40, 29, 66, 48, 55, 26, +9, -5, -27, -25, -14, -26, 26, -4, +57, 17, 47, 22, 15, 10, -2, -8, +4, -19, 24, -9, 21, 12, 10, 14, +17, -6, 38, -26, 38, -18, 17, 7, +-8, 20, -7, 9, 23, -16, 50, -27, +37, -17, 11, 2, 1, 7, 13, 1, +27, -4, 25, -2, 0, 6, 8, -4, +34, -19, 47, -22, 34, -3, -8, 23, +-23, 25, 5, 1, 43, -19, 58, -16, +34, 9, -8, 18, -20, 1, 4, -11, +30, 6, 42, 26, 33, 25, 10, -10, +7, -38, 19, -20, 19, 27, 11, 45, +16, 14, 22, -28, 38, -28, 32, 4, +6, 27, -7, 17, 6, -3, 21, -4, +32, -5, 29, -10, 14, -11, 18, 7, +27, 29, 14, 22, -8, -19, -7, -51, +15, -31, 61, 14, 69, 41, 18, 25, +-33, -11, -45, -28, -5, -30, 56, -25, +78, -13, 55, 21, -3, 57, -38, 34, +-43, -37, -7, -85, 46, -50, 81, 35, +69, 82, 4, 43, -58, -36, -55, -65, +3, -29, 71, 17, 94, 26, 43, 15, +-19, 5, -50, 4, -27, -14, 25, -30, +59, -11, 59, 29, 35, 42, -2, 5, +-22, -44, -22, -41, 12, 14, 43, 60, +52, 41, 36, -18, -6, -47, -21, -30, +-6, 17, 16, 43, 35, 33, 28, 7, +12, -18, 6, -30, 6, -12, 8, 20, +5, 37, 1, 21, 12, -22, 20, -35, +33, -9, 26, 28, 3, 27, -8, -10, +-9, -40, 18, -27, 35, 11, 37, 27, +13, 12, -4, -12, -10, -15, 1, -11, +20, -14, 31, -10, 17, 5, 16, 21, +10, 13, 3, -16, 2, -31, 3, -14, +16, 11, 38, 14, 30, -3, 4, -14, +-22, 8, -21, 22, 20, 7, 47, -16, +44, -23, -2, 4, -29, 24, -16, 13, +18, -4, 50, -7, 38, 10, -6, 17, +-14, -8, -7, -25, 18, -6, 26, 30, +12, 38, 7, 7, 20, -26, 20, -23, +5, 2, -16, 13, -11, 7, 19, 8, +53, 21, 41, 12, -7, -20, -32, -47, +-25, -20, 21, 38, 53, 61, 29, 18, +1, -49, -4, -64, 3, -16, 17, 32, +6, 31, -5, 3, 13, -13, 43, -6, +37, -12, -1, -32, -34, -32, -24, 15, +18, 61, 61, 40, 36, -32, 0, -77, +-24, -42, -15, 29, 18, 57, 24, 24, +13, -17, 13, -23, 18, -7, 9, -3, +-4, -20, -12, -6, 1, 34, 20, 58, +30, 17, 11, -46, -2, -58, 0, -10, +7, 41, 16, 42, 7, 10, -1, -14, +18, -10, 22, -6, 21, -15, -1, -10, +-17, 21, -10, 43, 20, 19, 33, -26, +26, -45, 6, -9, -2, 29, -12, 31, +-4, -1, 11, -25, 18, -8, 34, 9, +25, 3, -3, -11, -15, -13, -20, 10, +-1, 14, 34, -4, 37, -15, 26, -8, +-8, 11, -22, 4, -22, -20, 11, -21, +34, 13, 34, 35, 19, 14, -9, -34, +-21, -53, 0, -15, 14, 35, 21, 49, +16, 16, 5, -23, 0, -30, 4, -18, +-1, 2, -9, 18, 2, 25, 28, 20, +33, 5, 15, -15, -17, -27, -34, -16, +3, 6, 32, 27, 38, 35, 11, 27, +-25, 4, -22, -26, 14, -45, 26, -23, +16, 24, -6, 57, -3, 49, 14, 7, +22, -33, 0, -52, -24, -40, -5, -3, +31, 49, 42, 81, 21, 48, -33, -39, +-38, -105, 6, -78, 44, 24, 44, 112, +0, 87, -23, -23, -10, -97, 18, -77, +27, -2, 8, 55, -6, 56, 2, 18, +18, -23, 27, -48, -2, -48, -12, -16, +1, 37, 16, 61, 24, 27, 14, -42, +0, -77, 9, -31, 9, 37, 5, 59, +-6, 21, 0, -26, 15, -30, 30, -9, +26, 7, -6, 4, -23, 5, -11, 15, +10, 12, 35, -5, 37, -19, 8, -3, +-5, 19, -21, 19, -20, -16, 14, -37, +40, -2, 35, 54, 13, 54, -22, -4, +-28, -65, -2, -57, 33, 7, 31, 55, +18, 43, 2, 2, -7, -22, 1, -17, +0, -16, -5, -23, 13, -11, 26, 26, +30, 51, 15, 24, -14, -36, -18, -68, +2, -31, 19, 33, 17, 51, 13, 12, +9, -24, 1, -16, 5, 7, -2, 8, +-17, -16, 4, -27, 22, 1, 29, 40, +26, 32, -4, -10, -23, -40, -15, -25, +-1, 13, 24, 28, 36, 11, 34, -8, +3, -1, -24, 8, -31, -4, -8, -21, +39, -13, 51, 22, 23, 40, -14, 19, +-40, -23, -18, -36, 26, -10, 32, 31, +17, 41, -6, 20, -9, -10, 9, -29, +13, -24, -5, 0, -15, 30, 9, 44, +35, 28, 27, -16, 2, -57, -29, -48, +-16, 12, 23, 66, 31, 65, 13, 4, +-10, -55, -14, -62, 15, -13, 22, 36, +9, 48, -18, 28, -8, -11, 19, -29, +29, -27, 11, -6, -24, 21, -25, 33, +15, 17, 34, -13, 24, -33, -6, -16, +-32, 24, -4, 38, 28, 13, 29, -26, +7, -37, -16, -3, -18, 40, 5, 41, +22, 4, 20, -32, 8, -29, 3, 9, +-11, 35, -14, 25, -2, -5, 15, -18, +29, 4, 27, 19, -4, 14, -26, -5, +-26, -13, 1, 2, 32, 19, 40, 17, +23, 2, -15, 1, -37, 6, -34, 8, +1, -2, 44, -6, 49, 11, 14, 32, +-31, 25, -59, -7, -17, -29, 34, -12, +53, 27, 27, 39, -21, 5, -32, -34, +-12, -21, 17, 18, 24, 44, 9, 18, +-3, -22, -13, -30, 1, -4, 6, 34, +0, 38, 6, 12, 2, -12, -9, -20, +-5, -10, -1, 6, 16, 22, 22, 37, +-3, 26, -25, -7, -26, -36, -4, -20, +23, 21, 40, 46, 16, 34, -21, -5, +-34, -29, -22, -14, -5, 22, 26, 33, +32, 19, 13, 9, -16, 8, -46, 7, +-34, -4, 7, -4, 38, 9, 45, 28, +-1, 32, -42, 2, -41, -21, -4, -6, +29, 26, 24, 34, 0, 4, -18, -22, +-17, 3, 1, 40, -2, 45, -12, -2, +-1, -49, 6, -27, 16, 38, -4, 75, +-29, 41, -30, -19, -9, -36, 11, -4, +14, 25, 0, 22, -14, 11, -17, 21, +-11, 36, -11, 17, -11, -24, -2, -39, +7, 0, 11, 58, -6, 70, -36, 23, +-36, -32, -15, -33, 20, 1, 31, 33, +2, 35, -31, 18, -44, 11, -21, 8, +9, 1, 20, -5, 8, 4, -20, 28, +-38, 43, -27, 26, -9, -6, 14, -16, +11, 2, -9, 28, -28, 33, -29, 20, +-17, 10, 0, 6, 4, 7, -6, 6, +-15, 9, -18, 21, -20, 30, -21, 24, +-11, 6, -7, 1, -3, 12, -11, 23, +-30, 21, -31, 7, -18, 7, 0, 24, +7, 37, -18, 25, -36, -11, -30, -28, +-4, -3, 5, 49, -8, 66, -30, 33, +-43, -15, -21, -34, 4, -8, 5, 29, +-11, 45, -39, 32, -46, 20, -29, 17, +-3, 6, 6, -3, -7, -7, -28, 9, +-46, 41, -40, 50, -23, 30, -4, 0, +-2, -5, -13, 9, -38, 20, -48, 17, +-36, 6, -11, 23, 3, 52, -7, 47, +-32, 3, -43, -43, -43, -32, -21, 25, +-6, 80, -7, 76, -19, 19, -36, -33, +-47, -40, -41, -2, -24, 44, -3, 64, +-8, 60, -29, 25, -56, -17, -56, -39, +-28, -9, -4, 47, -2, 86, -32, 58, +-53, -12, -52, -48, -31, -17, -18, 46, +-18, 73, -30, 46, -37, 1, -36, -20, +-31, -6, -39, 21, -42, 38, -30, 38, +-16, 30, -20, 16, -38, -2, -60, -7, +-50, 10, -25, 40, -17, 53, -27, 28, +-48, -3, -57, -3, -42, 20, -28, 42, +-34, 33, -45, 8, -47, 2, -36, 20, +-29, 43, -39, 42, -54, 9, -52, -6, +-43, 4, -30, 28, -35, 43, -46, 38, +-55, 26, -53, 21, -51, 15, -39, 1, +-38, 6, -38, 24, -44, 47, -56, 50, +-54, 20, -47, -7, -33, -7, -37, 23, +-60, 40, -64, 31, -55, 20, -36, 24, +-32, 38, -50, 28, -71, 2, -68, -15, +-47, 12, -36, 57, -37, 69, -55, 35, +-67, -9, -66, -20, -56, 12, -58, 49, +-50, 53, -43, 28, -40, 13, -55, 17, +-75, 18, -86, 14, -62, 8, -34, 24, +-27, 50, -46, 50, -84, 27, -100, -6, +-73, -13, -40, 19, -29, 53, -45, 56, +-75, 30, -86, 1, -76, 2, -66, 24, +-55, 34, -49, 34, -59, 30, -67, 32, +-79, 30, -79, 19, -73, 10, -59, 14, +-59, 33, -61, 46, -74, 42, -78, 24, +-75, 8, -61, 4, -60, 15, -68, 34, +-73, 45, -76, 45, -70, 25, -65, 0, +-68, -5, -74, 21, -77, 54, -82, 61, +-74, 29, -69, -2, -67, 2, -71, 33, +-80, 50, -88, 32, -85, 8, -72, 15, +-61, 46, -67, 56, -80, 20, -90, -21, +-84, -8, -73, 44, -66, 76, -80, 57, +-84, 3, -85, -12, -71, 11, -72, 40, +-87, 36, -96, 17, -89, 27, -68, 54, +-60, 55, -76, 11, -106, -28, -110, -14, +-87, 51, -67, 99, -66, 72, -83, 2, +-99, -37, -96, -6, -88, 48, -85, 68, +-83, 37, -81, 11, -85, 18, -82, 36, +-97, 42, -105, 19, -99, 2, -80, 15, +-71, 43, -80, 62, -106, 49, -114, 18, +-104, 3, -79, 6, -71, 26, -78, 41, +-99, 48, -118, 46, -108, 27, -87, 13, +-73, 7, -70, 13, -92, 33, -121, 50, +-120, 48, -94, 32, -67, 14, -68, 6, +-91, 7, -122, 30, -124, 55, -99, 58, +-75, 36, -75, 6, -96, -7, -111, 13, +-112, 53, -106, 67, -95, 41, -87, 4, +-83, -3, -93, 23, -108, 47, -124, 42, +-114, 20, -87, 22, -68, 40, -76, 43, +-114, 23, -140, -12, -125, -5, -81, 42, +-58, 83, -77, 68, -119, 11, -143, -29, +-123, -13, -85, 37, -65, 65, -84, 59, +-115, 34, -131, 21, -123, 17, -98, 8, +-87, 3, -85, 17, -95, 56, -114, 81, +-127, 57, -121, 0, -105, -31, -81, -3, +-78, 51, -98, 74, -129, 54, -135, 15, +-112, 1, -83, 21, -80, 39, -98, 30, +-119, 18, -123, 24, -113, 40, -98, 44, +-93, 28, -99, 14, -106, 22, -116, 38, +-120, 34, -109, 17, -99, 17, -95, 39, +-106, 63, -124, 49, -124, 7, -104, -15, +-82, 7, -91, 53, -116, 68, -133, 42, +-121, 10, -94, 6, -80, 20, -102, 36, +-130, 40, -135, 36, -109, 34, -85, 30, +-85, 15, -107, 6, -120, 18, -123, 46, +-112, 54, -104, 37, -104, 12, -97, 0, +-100, 23, -112, 45, -126, 47, -124, 34, +-104, 21, -81, 13, -83, 16, -113, 22, +-140, 35, -134, 50, -98, 44, -70, 20, +-81, -2, -115, 2, -139, 32, -127, 56, +-98, 46, -76, 17, -85, 7, -110, 22, +-133, 39, -129, 33, -106, 12, -81, 14, +-74, 38, -100, 58, -134, 36, -133, -8, +-115, -6, -86, 33, -70, 62, -92, 53, +-128, 14, -142, -1, -123, 23, -90, 49, +-70, 37, -84, 7, -116, 4, -136, 39, +-130, 66, -112, 51, -84, -2, -69, -27, +-81, 11, -115, 65, -148, 73, -140, 26, +-94, -14, -57, -3, -57, 34, -103, 52, +-156, 38, -155, 12, -101, 15, -56, 34, +-55, 35, -98, 16, -144, 6, -141, 20, +-105, 49, -78, 50, -71, 21, -89, -6, +-108, -4, -117, 31, -119, 57, -105, 44, +-84, 15, -76, 2, -88, 9, -111, 29, +-127, 43, -116, 33, -83, 18, -68, 14, +-86, 19, -115, 31, -127, 33, -109, 23, +-82, 15, -72, 17, -89, 28, -108, 40, +-119, 34, -111, 18, -98, 11, -82, 17, +-80, 36, -95, 44, -110, 27, -119, 12, +-105, 10, -80, 26, -73, 37, -87, 28, +-110, 12, -120, 15, -100, 32, -77, 41, +-76, 25, -90, -2, -109, 1, -107, 30, +-94, 59, -88, 50, -89, 8, -94, -11, +-93, 9, -92, 42, -95, 49, -101, 21, +-98, 2, -86, 20, -78, 47, -91, 47, +-105, 7, -104, -27, -86, -1, -73, 56, +-78, 80, -98, 43, -106, -14, -99, -28, +-80, 5, -73, 46, -87, 56, -103, 39, +-99, 21, -85, 18, -78, 13, -81, 0, +-91, -3, -97, 25, -92, 63, -85, 65, +-78, 23, -78, -23, -89, -24, -96, 15, +-94, 53, -81, 56, -70, 30, -70, 7, +-85, 0, -101, 8, -103, 20, -88, 32, +-71, 39, -64, 38, -80, 20, -93, 2, +-98, 0, -88, 18, -78, 36, -71, 36, +-71, 21, -73, 9, -86, 14, -93, 16, +-95, 18, -81, 20, -61, 24, -53, 28, +-72, 22, -105, 11, -110, 3, -81, 16, +-53, 36, -49, 35, -74, 15, -104, 1, +-101, 10, -74, 27, -56, 32, -58, 13, +-76, 3, -89, 15, -84, 34, -77, 36, +-74, 16, -75, -2, -65, 7, -66, 28, +-73, 35, -89, 22, -90, 4, -72, 16, +-58, 34, -56, 30, -76, 7, -91, -8, +-93, 15, -74, 45, -50, 48, -54, 22, +-69, -11, -83, -12, -87, 10, -73, 35, +-63, 38, -54, 27, -63, 20, -70, 8, +-82, 1, -77, -4, -68, 10, -59, 35, +-59, 49, -68, 37, -76, 1, -69, -18, +-67, -6, -59, 21, -68, 45, -70, 36, +-63, 13, -55, -2, -58, 2, -73, 11, +-76, 19, -69, 23, -53, 21, -46, 21, +-64, 15, -79, 8, -74, 1, -56, 11, +-52, 30, -60, 30, -70, 15, -73, 0, +-59, 2, -51, 19, -57, 29, -61, 18, +-64, 3, -62, 1, -52, 10, -57, 24, +-60, 21, -63, 13, -59, 7, -56, 11, +-56, 15, -57, 15, -65, 17, -57, 13, +-53, 13, -51, 10, -56, 10, -64, 15, +-63, 19, -60, 23, -54, 16, -51, 8, +-52, 7, -58, 15, -66, 19, -59, 16, +-55, 14, -42, 12, -45, 14, -57, 11, +-65, 4, -63, 7, -52, 26, -49, 36, +-52, 24, -59, -1, -58, -16, -45, 3, +-48, 33, -53, 39, -60, 14, -55, -11, +-38, -11, -38, 16, -51, 29, -62, 14, +-59, -2, -40, 1, -34, 22, -45, 30, +-63, 7, -60, -13, -45, -3, -33, 25, +-41, 38, -61, 20, -67, -4, -53, -7, +-28, 11, -26, 27, -51, 19, -68, 0, +-65, -5, -36, 12, -23, 32, -32, 22, +-50, -5, -67, -14, -58, 3, -41, 31, +-32, 41, -36, 19, -45, -12, -49, -17, +-55, 5, -46, 30, -42, 35, -38, 17, +-36, -3, -42, -9, -39, -2, -43, 15, +-46, 20, -46, 15, -47, 10, -33, 10, +-36, 16, -37, 12, -53, 5, -59, -1, +-44, 8, -28, 24, -19, 26, -37, 14, +-58, -7, -58, -12, -39, 4, -15, 22, +-25, 27, -45, 14, -57, -2, -48, 2, +-31, 13, -26, 13, -33, 3, -44, 0, +-45, 18, -37, 31, -30, 20, -33, -9, +-42, -27, -38, -5, -32, 34, -27, 48, +-34, 26, -47, -18, -42, -34, -36, -7, +-22, 31, -24, 46, -33, 21, -38, -9, +-43, -20, -34, -5, -26, 9, -27, 23, +-29, 20, -29, 12, -33, 14, -37, 1, +-33, -14, -29, -14, -26, 6, -24, 38, +-30, 42, -33, 15, -42, -19, -42, -27, +-29, -1, -18, 32, -11, 38, -25, 16, +-48, -6, -53, -11, -36, 1, -2, 11, +2, 13, -15, 5, -46, 2, -54, 2, +-30, 6, -7, 7, -2, 11, -27, 9, +-43, 6, -45, 9, -27, 3, -8, 4, +-17, 6, -21, 7, -26, 8, -25, 8, +-22, 3, -30, -2, -31, 2, -23, 10, +-7, 19, -8, 20, -31, 6, -42, -13, +-47, -5, -22, 14, 4, 27, 1, 24, +-21, 1, -47, -17, -43, -10, -20, 9, +7, 22, 8, 19, -22, 8, -44, -2, +-47, -3, -21, 4, 2, 11, 3, 16, +-14, 15, -36, 6, -32, -5, -19, -10, +-6, 0, -7, 16, -18, 24, -21, 15, +-17, -6, -12, -10, -19, -3, -21, 8, +-18, 17, -14, 15, -5, 11, -14, 8, +-25, 4, -29, -1, -21, -3, -1, 2, +-1, 15, -11, 21, -22, 7, -20, -10, +-7, -12, -9, 5, -11, 19, -16, 13, +-17, 4, -10, -1, -9, 8, -14, 20, +-22, 13, -16, -2, -7, -10, 2, -1, +-1, 17, -22, 24, -21, 7, -16, -3, +-3, -3, 6, 7, -9, 13, -15, 4, +-27, 4, -15, 7, 2, 16, 5, 19, +-2, 4, -19, -13, -20, -12, -15, 9, +-3, 34, 1, 34, -3, 5, -5, -20, +-15, -20, -8, 2, -10, 30, -11, 30, +-3, 9, -1, -8, 9, -10, -2, 3, +-15, 10, -22, 8, -15, 6, 14, 10, +20, 18, 6, 12, -23, -7, -36, -17, +-11, -4, 18, 25, 29, 42, 4, 19, +-23, -18, -27, -35, -5, -11, 17, 33, +17, 43, 4, 18, -13, -14, -15, -22, +5, -7, 9, 15, 8, 19, -1, 6, +-1, 3, 4, 11, 6, 13, 4, 0, +-11, -14, -6, -12, 6, 15, 13, 42, +15, 33, -4, -4, -8, -36, -8, -25, +4, 16, 19, 40, 16, 29, 7, -1, +-10, -15, -5, -8, 3, 11, 11, 12, +17, 1, 4, 3, 6, 14, 5, 20, +10, 4, 7, -15, -3, -17, 4, 3, +13, 27, 22, 31, 16, 4, 1, -18, +-7, -15, -4, 7, 18, 22, 26, 16, +20, 1, 2, -4, -7, 4, 1, 14, +13, 9, 21, -2, 18, -9, 11, 2, +8, 18, 2, 23, 2, 14, 6, -12, +19, -18, 25, -2, 20, 20, 7, 31, +-9, 16, -1, -6, 15, -12, 29, -2, +30, 11, 10, 14, 0, 10, -4, 6, +14, 5, 30, 2, 26, -2, 16, -4, +1, 5, 1, 21, 12, 24, 24, 5, +26, -12, 11, -15, 10, 3, 6, 27, +16, 26, 22, 5, 18, -16, 16, -14, +15, 1, 20, 21, 19, 21, 14, 7, +8, -3, 8, -5, 24, 0, 34, 3, +29, 6, 13, 8, 0, 8, 11, 3, +23, -1, 36, -5, 32, 1, 7, 18, +-2, 19, 8, 4, 31, -10, 35, -7, +23, 8, 10, 18, 8, 13, 17, 3, +20, -2, 22, -2, 18, 9, 13, 15, +23, 13, 19, 10, 22, 0, 16, -6, +20, -8, 26, 2, 32, 10, 30, 19, +10, 17, 12, -6, 20, -18, 26, -9, +33, 9, 28, 20, 23, 20, 8, 8, +16, -13, 28, -16, 32, -2, 33, 11, +23, 16, 17, 9, 12, 5, 17, -1, +29, -2, 29, 0, 31, 1, 24, 5, +16, 13, 12, 13, 16, 4, 30, -4, +34, -7, 35, -2, 21, 11, 8, 16, +12, 10, 21, 0, 36, -3, 33, 2, +24, 11, 15, 11, 14, 3, 21, 1, +28, -2, 36, 4, 30, 10, 19, 7, +20, -2, 21, -3, 26, 9, 25, 10, +32, 1, 30, -5, 28, -5, 28, 9, +19, 14, 18, 9, 23, -6, 31, -10, +40, 2, 33, 12, 25, 11, 11, 0, +14, -5, 30, 0, 39, 12, 40, 14, +23, 0, 15, -14, 21, -12, 28, 9, +40, 20, 36, 11, 24, -2, 14, -12, +18, -3, 29, 8, 35, 13, 30, 8, +25, -2, 24, -2, 29, 1, 29, 2, +32, -7, 24, -2, 26, 2, 34, 9, +31, 16, 30, 0, 27, -12, 21, -12, +24, -3, 35, 11, 40, 15, 33, 11, +23, -5, 16, -12, 23, -8, 35, 3, +39, 17, 29, 13, 23, 2, 19, -3, +25, -6, 40, -7, 36, 0, 29, 4, +29, 5, 24, 12, 29, 1, 32, -11, +32, -11, 31, -2, 28, 16, 27, 17, +28, 3, 37, -18, 37, -20, 32, -4, +26, 11, 27, 15, 33, 6, 35, -10, +38, -15, 28, -7, 22, 7, 24, 9, +33, 3, 39, 0, 35, -1, 23, 3, +21, -5, 23, -6, 37, -5, 40, 9, +33, 15, 27, 0, 22, -13, 27, -12, +32, 0, 39, 9, 33, 9, 26, -4, +27, -6, 25, 0, 39, -1, 37, 1, +32, -5, 28, -4, 26, 1, 32, 4, +36, 2, 37, -5, 29, -1, 20, -1, +31, -1, 34, 2, 40, 0, 34, -1, +26, -6, 22, 3, 28, 3, 46, -2, +41, -2, 29, -9, 19, 1, 17, 8, +36, 9, 44, 0, 39, -9, 27, -8, +19, -5, 27, 6, 35, 7, 47, -3, +39, -4, 26, -12, 24, -7, 26, -1, +41, 5, 43, 6, 32, -1, 20, -5, +18, -7, 35, 0, 45, 3, 42, 0, +28, -3, 21, -10, 29, -4, 38, -1, +44, 2, 37, -1, 22, 4, 15, 1, +31, -11, 46, -9, 48, -1, 35, 9, +16, 6, 19, -11, 31, -10, 45, 0, +44, 11, 31, 4, 20, -5, 22, -14, +41, -9, 48, 0, 45, 0, 31, 0, +21, -3, 26, 1, 34, -3, 44, -8, +38, -3, 27, -1, 28, 5, 29, 2, +39, -1, 40, -7, 32, -9, 30, -7, +30, -6, 42, 7, 38, 11, 31, 1, +25, -11, 21, -15, 37, -1, 48, 2, +46, 7, 32, -3, 15, -4, 20, -1, +34, -5, 53, -8, 52, -10, 32, -1, +21, 5, 13, 5, 38, -7, 53, -14, +46, -3, 31, -1, 12, 4, 25, 0, +40, -1, 51, -2, 47, -11, 27, -10, +25, -6, 26, 5, 43, 3, 51, -9, +41, -9, 34, -9, 26, 0, 30, -2, +42, -9, 44, -4, 44, -3, 28, 6, +26, -5, 40, -15, 44, -5, 38, 5, +27, 6, 26, -4, 34, -4, 46, -5, +50, -2, 32, -1, 23, -7, 23, 1, +39, -2, 57, -5, 48, -7, 30, -3, +14, 4, 22, -2, 44, -4, 54, -9, +47, 2, 24, 6, 18, -4, 30, -8, +43, -9, 55, -1, 45, -2, 29, -6, +27, -11, 35, -6, 48, 4, 46, -5, +40, -13, 33, -15, 32, -4, 42, 6, +46, -4, 42, -5, 30, -8, 25, -4, +33, -1, 44, -6, 55, -4, 44, 0, +24, 2, 21, -8, 32, -12, 54, -5, +53, 4, 35, 8, 23, -6, 24, -8, +43, -8, 55, -5, 47, -5, 34, -7, +24, 1, 34, 3, 46, -2, 49, -11, +42, -13, 29, 0, 27, 6, 32, 4, +46, -10, 46, -4, 39, -3, 38, -6, +32, -7, 39, -11, 45, 1, 40, 2, +42, -5, 32, -9, 40, -11, 44, 2, +42, -1, 36, -1, 24, -5, 31, -2, +41, 1, 48, -4, 51, -9, 33, -8, +24, -1, 27, -3, 44, -8, 60, -5, +49, -2, 33, 3, 15, -6, 27, -10, +49, -5, 57, 2, 50, 1, 28, -11, +24, -11, 31, 2, 44, 3, 57, -6, +43, -16, 35, -5, 27, 5, 31, 7, +46, -11, 48, -15, 42, -3, 35, 3, +31, 4, 35, -6, 41, -9, 46, -4, +43, -6, 35, -4, 36, -8, 41, 1, +45, 1, 37, -3, 31, -13, 38, -12, +41, 5, 44, 5, 43, -5, 33, -11, +28, -2, 31, 6, 49, -6, 51, -10, +40, -9, 27, 8, 22, 7, 41, -8, +52, -16, 52, -13, 41, 1, 24, 4, +27, 0, 36, -6, 50, -8, 46, -1, +34, -5, 32, -3, 32, -3, 37, 3, +40, -2, 39, -9, 40, -3, 32, 5, +34, 4, 38, -10, 41, -13, 43, -2, +37, 1, 41, -3, 39, -12, 39, -4, +46, -4, 44, -7, 36, -6, 33, -12, +41, 2, 44, 8, 40, 0, 33, -11, +28, -13, 39, 0, 47, 5, 43, 4, +40, -12, 29, -9, 32, -2, 42, -3, +46, -2, 43, -2, 33, 3, 33, -3, +38, -15, 44, -14, 43, 0, 39, 9, +38, 4, 33, -9, 42, -19, 41, -6, +39, 1, 43, -4, 37, -1, 37, -3, +40, 0, 39, -7, 39, -12, 37, -9, +40, -3, 40, 7, 41, -3, 46, -12, +36, -6, 30, -2, 32, 0, 39, -8, +49, -2, 47, -1, 38, -1, 26, -7, +30, -15, 47, -4, 51, 5, 48, 0, +34, -10, 27, -14, 35, -1, 44, 1, +52, -3, 43, -12, 32, -4, 31, 3, +33, 1, 43, -8, 45, -12, 44, -5, +40, 2, 35, -4, 39, -9, 37, -9, +43, 1, 42, -2, 39, -6, 39, -9, +40, -6, 40, 4, 37, -2, 38, -10, +41, -9, 42, -2, 42, 3, 40, -5, +35, -3, 32, -1, 32, 4, 45, -10, +48, -9, 41, -4, 36, 3, 29, 2, +42, -14, 48, -12, 46, -5, 42, 0, +30, 1, 32, -7, 44, -6, 49, -2, +40, 1, 32, -11, 33, -7, 34, 7, +44, 6, 46, -4, 36, -15, 31, -7, +30, 7, 42, 4, 42, 2, 37, -10, +37, -3, 30, 3, 34, 0, 40, -7, +38, -1, 38, 7, 36, 3, 35, -8, +40, -16, 42, -8, 44, 7, 40, 1, +39, -5, 38, -14, 40, -4, 41, -2, +46, -11, 38, -3, 29, 3, 34, 8, +42, 0, 44, -10, 41, -9, 33, -3, +31, 6, 37, 1, 42, -1, 47, -4, +40, -2, 34, -4, 34, -10, 39, -6, +45, 1, 42, 4, 39, -3, 38, -9, +37, -4, 40, -3, 39, -4, 40, -9, +45, -6, 43, 4, 42, 1, 37, -8, +37, -17, 41, -8, 39, 7, 42, 5, +41, -6, 43, -13, 39, -4, 37, -3, +37, -3, 36, -6, 48, -5, 48, 3, +40, 0, 30, -7, 28, -11, 34, 3, +44, 7, 54, -3, 43, -4, 26, -5, +26, 1, 32, 1, 48, -4, 54, -7, +44, -1, 36, -1, 32, -6, 32, -3, +40, -1, 48, -2, 49, -4, 38, -5, +36, -5, 36, 0, 37, 3, 44, -5, +44, -10, 42, -3, 40, -2, 40, 1, +36, 0, 35, -1, 39, -1, 43, -5, +45, -7, 40, -4, 39, 0, 36, 6, +35, -2, 44, -14, 49, -11, 45, 3, +40, 5, 29, 4, 29, -8, 43, -9, +50, -1, 51, -2, 40, -6, 35, -10, +36, 0, 38, 6, 49, -8, 48, -16, +41, -8, 32, 12, 35, 8, 44, -4, +40, -15, 43, -15, 41, 0, 41, 7, +45, 1, 41, -5, 38, -5, 33, -3, +36, -5, 42, -2, 43, 3, 43, 8, +38, 1, 30, -4, 32, -10, 40, -5, +49, 4, 50, 3, 47, -3, 38, -11, +34, -14, 42, -11, 50, -3, 54, 5, +50, -1, 39, -10, 38, -18, 37, -9, +42, 7, 46, 9, 47, 0, 46, -13, +37, -9, 34, -1, 35, 0, 43, -2, +52, -4, 46, 5, 45, -5, 38, -13, +32, -13, 39, -3, 46, 12, 52, 7, +46, -8, 36, -16, 30, -7, 32, 10, +41, 10, 49, -2, 54, -15, 46, -9, +35, -1, 31, 0, 34, -1, 41, 3, +52, 2, 53, -4, 43, -12, 31, -11, +31, -1, 36, 15, 49, 8, 54, -7, +46, -19, 38, -14, 35, -1, 41, 8, +47, 5, 51, -9, 45, -12, 41, -11, +40, -1, 40, 7, 43, 1, 47, -9, +48, -12, 43, -4, 44, 0, 41, -2, +45, -6, 39, 1, 40, 3, 42, -2, +45, -14, 50, -14, 45, 2, 42, 13, +42, 1, 40, -17, 41, -19, 44, 0, +45, 21, 43, 11, 39, -9, 34, -19, +38, -9, 45, 7, 51, 5, 49, -4, +47, -12, 42, -8, 39, -1, 39, -6, +43, -6, 43, 5, 46, 11, 47, 4, +40, -14, 35, -21, 36, -8, 46, 11, +55, 15, 52, 0, 41, -18, 29, -15, +28, 1, 44, 10, 55, 8, 56, -5, +45, -11, 36, -11, 36, -3, 37, 3, +46, 0, 50, 1, 46, 3, 44, -2, +37, -8, 36, -14, 43, -6, 49, 9, +51, 14, 48, -7, 42, -21, 32, -14, +43, 1, 50, 15, 49, 4, 49, -19, +42, -16, 35, 5, 37, 17, 39, 6, +43, -10, 45, -10, 41, 7, 41, 8, +39, -1, 38, -11, 43, -5, 47, 7, +46, 6, 41, -9, 39, -14, 37, 0, +43, 16, 42, 14, 41, -10, 46, -26, +42, -9, 47, 9, 48, 13, 42, -1, +38, -16, 41, -14, 43, 4, 46, 10, +48, 1, 46, -11, 40, -9, 40, -2, +41, 5, 44, -3, 52, -11, 50, -4, +42, 10, 34, 8, 34, -9, 40, -15, +45, 0, 55, 15, 46, 20, 36, -6, +31, -24, 31, -12, 46, 12, 55, 20, +56, 1, 43, -18, 31, -15, 32, 3, +41, 11, 52, -1, 58, -13, 49, -5, +38, 9, 28, 8, 31, -6, 43, -16, +56, -3, 54, 15, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_24000_2ch_16b.c b/USDK/example_sources/i2s/src/birds_24000_2ch_16b.c new file mode 100644 index 0000000..6bb37b0 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_24000_2ch_16b.c @@ -0,0 +1,17496 @@ +#include +int sample_size=69958; + +SECTION(".sdram.data") +short sample[]={ +-1, 1, 0, 0, -1, 2, -1, 0, +2, 0, -3, 4, -4, 3, 1, -1, +2, 0, -1, 0, 2, -2, 1, 1, +-3, 1, 1, -1, 2, -1, -1, 2, +-4, 3, -1, 1, 2, -2, -1, 0, +3, -2, 4, -4, 1, -3, 3, -2, +1, 0, 3, -5, 2, -1, 0, 2, +-2, 1, -3, 1, 2, -1, 1, -1, +-3, 1, 0, 0, 3, -1, -6, 4, +0, 0, 1, 1, -2, -1, 0, 0, +1, 1, 4, -5, 1, -1, 3, 1, +-2, 2, -2, -2, 5, -3, 2, 0, +-2, 0, 2, -2, 4, -1, -2, -1, +3, -2, 0, 3, -3, 1, 0, -2, +4, -2, 2, -2, -2, -1, 3, -1, +0, 1, -1, -2, 1, 1, 0, 1, +-1, -1, -3, 4, 0, 2, 0, -2, +1, -1, -1, 3, 0, -1, -2, 1, +1, 0, 3, -3, 0, -3, 4, -3, +2, 1, -1, -2, 3, -2, 1, 2, +-4, 3, -3, 1, 2, 1, -1, -1, +2, -2, -1, 4, -2, 1, -1, -1, +4, -4, 4, -1, -3, 1, 1, -1, +1, 1, -4, 3, -2, 0, 4, -3, +2, -3, -1, 1, -1, 2, 1, -3, +1, -1, -2, 3, -3, 2, -1, -1, +1, -1, 3, -1, -3, 2, -2, 2, +-2, 4, -4, 2, 0, 0, 1, 0, +0, 0, -2, 2, -1, 2, -2, 2, +-2, 1, 1, 0, 0, 1, -1, 1, +0, 0, 0, 1, 0, -1, 3, -2, +2, -1, 0, -1, 1, -2, 2, -1, +1, -1, 0, -1, 3, -2, 1, -1, +-1, 0, 1, -1, -1, 2, -2, 1, +0, -1, 2, -1, -3, 2, -2, 2, +-2, 3, -3, 1, -1, 1, -2, 3, +-1, 0, 1, -2, 1, 1, -4, 4, +-5, 4, -2, 1, 1, -2, 0, 0, +0, 0, 1, 0, -1, 1, 0, 1, +1, 0, 1, -2, 1, 1, -3, 3, +1, -1, -1, 2, -1, 1, 2, -2, +1, 0, -1, 2, 2, -3, 4, -3, +-1, 2, 1, -1, -2, 3, -3, 1, +2, -1, -3, 3, -2, 2, -1, 2, +-3, 3, -5, 4, 0, 0, 0, 0, +-1, -1, 3, -3, 1, 0, -2, 2, +-3, 2, -1, 1, -3, 2, -1, 1, +0, 1, -3, 2, 0, -1, 3, -2, +0, 1, -3, 2, 1, -1, 2, -2, +0, 0, 2, -3, 4, -3, 0, 0, +1, 0, 2, -1, 1, 0, -2, 3, +0, 0, 1, 0, -3, 3, 1, -2, +1, 0, 0, -1, 2, 0, 0, 0, +-1, 2, -3, 4, -3, 3, -3, 1, +0, 0, -3, 4, -6, 4, -3, 3, +-3, 4, -3, 1, -2, 3, -5, 5, +-3, 2, -2, 1, -3, 4, -3, 2, +1, -3, 4, -4, 3, -2, 2, -3, +1, -1, 2, -2, 1, 0, -1, 1, +0, 1, -1, 0, 1, -1, -2, 4, +-4, 5, -3, 2, 1, -1, 2, -2, +3, -2, 0, 2, -2, 2, 1, -2, +2, -2, 0, 1, 0, 0, 0, 0, +0, 0, 0, 1, -1, 0, 2, -2, +2, -1, -1, 1, -2, 2, 1, -1, +1, 0, -4, 4, -1, 0, -1, 0, +0, -2, 2, -1, -1, 1, 0, -2, +3, -4, 2, -2, 1, -2, -1, 2, +0, -1, 3, -4, 5, -5, 3, -1, +0, 0, 1, 0, -2, 2, -1, 2, +-4, 5, -3, 2, 3, -2, 0, 1, +1, -1, 3, -1, 1, -1, 1, -1, +0, 1, -1, 2, -2, 2, 0, 0, +0, 1, -1, 2, -2, 1, 2, -2, +1, 0, -1, 2, -2, 3, -2, 0, +2, -2, -2, 2, -1, 0, 1, -2, +2, -1, -1, 1, 0, -1, 0, 0, +-1, 0, -3, 3, -3, 1, -2, 2, +-3, 2, 0, -1, 1, -2, 1, -1, +-2, 3, -6, 5, 0, -1, 3, -4, +6, -5, 2, -2, 3, -3, 1, 2, +-5, 4, -2, 1, 1, -2, 4, -3, +-1, 2, -1, 1, 3, -4, 3, -2, +1, 0, -1, 1, 0, -1, 1, 0, +0, 0, 1, 0, 1, -1, 1, 0, +-2, 2, -1, 0, 2, -1, 1, -1, +2, -2, 1, 0, 1, -2, -2, 3, +-4, 3, 1, -2, 1, -2, 3, -3, +1, 0, 0, -1, 0, -1, -2, 3, +-3, 1, 1, -3, 0, 0, -1, 1, +1, -2, 1, -1, 0, 0, 0, 0, +-1, 2, -1, 1, 2, -2, 2, -2, +2, -1, 2, -2, 1, 0, 0, 0, +3, -2, 2, -2, 3, -2, 2, -1, +1, -1, 1, -1, 5, -4, 5, -4, +4, -4, 1, 1, -2, 3, -2, 2, +1, -2, 4, -3, 1, 0, -1, 0, +1, -2, 1, 0, -3, 2, 0, -1, +-1, 1, -3, 2, -1, 0, 0, 0, +-2, 1, -1, 1, -4, 3, -2, 0, +0, 0, -2, 2, -1, 0, 1, -2, +3, -3, 4, -4, 2, -1, 0, 0, +0, 0, -3, 3, 0, 0, 2, 0, +-1, 1, 0, 1, -1, 3, -3, 3, +0, -1, 3, -2, 3, -3, 4, -3, +0, 1, 3, -3, 3, -1, 1, -1, +4, -3, 1, 1, -2, 3, -1, 2, +-1, 0, 0, 0, -2, 3, -3, 3, +-1, 0, 2, -2, 0, 0, -1, 1, +-2, 2, -1, -1, 3, -3, 1, -1, +-1, 0, 1, -2, -1, 1, 0, -1, +-1, 2, -4, 3, -1, 0, 0, -1, +0, 0, -2, 2, 0, -1, 0, 0, +1, -1, 1, 0, -3, 3, 0, 0, +0, 1, -3, 3, -1, 2, -1, 1, +1, -1, 1, 0, 1, 0, 0, 0, +1, 0, 2, -2, 3, -2, -1, 1, +3, -3, 0, 2, -3, 2, 1, 0, +0, 0, -2, 2, -4, 4, 2, -4, +3, -2, -4, 4, -1, 0, 1, -2, +1, -2, 1, 0, -2, 1, -1, -1, +1, 0, -3, 4, -3, 1, 0, 1, +-2, 3, -3, 1, 0, 0, 0, 1, +0, -1, 3, -4, 3, -1, 2, -2, +-1, 2, -1, 1, 1, 0, -2, 1, +1, 1, -3, 3, -1, 0, 1, -1, +3, -2, -1, 1, -1, 1, 0, 1, +-4, 5, -5, 3, 2, -1, -1, 3, +-3, 2, 3, -3, 1, 0, -2, 0, +3, -2, -2, 3, -3, 2, -2, 2, +-2, 2, -3, 2, -2, 2, -4, 4, +-1, -2, 2, -2, 1, -2, 2, -3, +3, -3, 4, -3, 1, -2, 0, -1, +-2, 2, 0, 0, 0, 1, -1, 0, +3, -2, -2, 2, -1, 0, 1, 0, +2, -3, 3, -2, 0, 0, 1, -2, +3, -2, 1, 1, -4, 4, -2, 2, +1, 0, 3, -3, 1, -1, 2, -1, +1, -1, 1, -2, 1, 0, 1, -1, +0, -1, 0, 0, 0, 1, -2, 1, +-1, 0, 3, -3, 3, -3, 1, -1, +0, 1, -2, 3, -7, 6, -4, 3, +-1, 2, -3, 1, 0, -1, 2, -2, +1, -2, -1, 1, -1, 1, 0, -1, +-1, 0, 1, 0, 1, 0, -2, 2, +-1, 1, 2, -2, 0, -1, 3, -2, +-1, 3, -3, 0, 3, -3, 1, 1, +-1, -1, 2, -3, 4, -2, 1, -1, +1, -2, 1, 0, 1, 0, -3, 3, +0, 0, 1, 0, -2, 1, -1, 1, +2, -1, 0, 1, -3, 1, 3, -2, +-1, 2, -6, 5, -1, 2, -4, 4, +0, -3, 6, -5, 3, -3, 1, -1, +-1, 1, 1, 0, -4, 4, -4, 2, +2, -2, 1, -1, -1, 0, 0, 1, +-4, 5, -5, 3, 2, -4, 4, -2, +0, -1, 4, -5, 4, -2, 0, -1, +1, -1, 0, 1, -3, 3, -2, 2, +-3, 3, 0, -1, 2, -1, 0, 1, +0, 0, 1, -1, 2, -2, 4, -3, +1, 0, 0, 1, -4, 5, -4, 3, +0, 1, 1, -2, 1, 0, -3, 2, +1, -1, -1, 1, -2, 2, -2, 2, +-3, 2, -2, 2, -1, 0, 1, -1, +-1, 1, -1, 0, 1, -2, -1, 1, +-1, 1, 1, -2, 2, -2, -1, 3, +-4, 3, -2, 1, -3, 4, -4, 4, +-1, -1, 4, -4, 2, 0, -1, -1, +4, -4, 2, 0, 0, -1, -1, 0, +1, -1, 1, 0, -1, -1, 3, -2, +1, 0, 0, 0, 1, 0, 0, 2, +-2, 1, 0, -1, 3, -2, 1, -1, +2, -3, 1, 0, -1, 0, 0, -1, +-1, 2, -3, 3, 0, -3, 5, -4, +1, 1, -3, 3, -3, 1, 0, 1, +-1, -1, 1, -2, -1, 2, 0, -1, +0, -1, 1, -1, 1, -1, 1, -2, +-3, 4, 1, -2, 1, 1, -3, 2, +4, -3, 1, 0, -3, 2, 0, 0, +2, -1, -3, 3, 0, 1, 0, 2, +-2, 1, 1, -1, 1, 0, -1, 1, +1, -2, 3, -2, 0, 1, -3, 2, +1, -1, -1, 2, -1, -1, 1, -1, +0, 0, -2, 2, -1, 0, 3, -2, +-2, 3, -3, 2, 1, -1, 0, 1, +-2, 1, 1, -1, 2, -3, 3, -4, +1, 0, 1, -1, 3, -3, 0, 1, +0, 0, 0, -1, 1, -1, 1, 0, +-1, -1, 3, -4, 4, -3, 2, 0, +-3, 2, 2, -2, -1, 3, -1, 0, +0, 1, -2, 3, -3, 3, -1, -1, +4, -4, 1, 0, 1, -2, 2, 0, +-3, 2, 2, -3, -1, 2, -2, 1, +1, -1, 0, 1, -2, 3, -2, 1, +1, -2, 0, -1, 4, -5, 5, -4, +0, 1, -2, 2, -1, 1, -3, 3, +-4, 3, -2, 2, -2, 1, 1, -2, +3, -2, -1, 1, -1, 0, 0, 0, +0, 0, 2, -2, -1, 3, -2, 1, +1, -1, 0, -1, 3, -2, -1, 1, +-1, 1, 0, 0, 2, -1, -2, 3, +-2, 2, 1, 0, 0, 0, 1, -1, +1, -1, 1, -2, 2, -2, 1, -1, +0, 1, -2, 1, 0, 0, -2, 3, +-3, 2, 1, -1, 3, -3, -1, 1, +-3, 3, -1, 2, -4, 3, -2, 1, +1, -1, 0, -1, 1, -2, 1, 0, +0, -1, 1, -2, 2, -2, 1, 0, +-1, 0, 0, 0, 0, 1, -2, 1, +-2, 1, -1, 1, -1, 0, 1, -1, +2, -1, 0, 1, -2, 1, 3, -2, +1, -1, 2, -2, 1, 0, 0, 1, +-1, 0, 1, -1, 0, 1, 0, 0, +-4, 5, -3, 1, 1, 0, -1, 1, +1, -1, 1, -1, -1, 1, -1, 1, +1, -1, -2, 2, -1, 0, 2, -2, +2, -3, 1, -1, -1, 1, 0, 0, +-2, 1, 0, -1, -1, 3, -6, 6, +-4, 3, -1, 1, -2, 1, 0, -1, +1, -1, -1, 1, -2, 2, -1, 0, +0, 0, 1, -2, 5, -5, 2, -1, +3, -3, 3, -3, 1, -1, 1, -2, +3, -3, -1, 3, -3, 3, -3, 4, +-4, 4, -1, 1, -1, 1, -1, 1, +0, 0, 0, 0, -2, 2, -3, 3, +-2, 2, -3, 3, -2, 1, 0, 1, +0, 0, -1, 1, -2, 2, -2, 2, +-3, 2, -1, 0, 2, -2, 1, -1, +0, -1, 3, -3, -1, 2, -1, -1, +2, -1, -1, 2, 0, -1, 1, 0, +-1, 1, -2, 2, -2, 2, 0, 0, +-2, 2, -3, 2, 0, 0, -2, 3, +-3, 2, 0, 0, 1, -2, 3, -4, +2, 0, 0, 0, 1, -1, 0, 0, +2, -3, 2, -2, 0, 0, 2, -2, +1, -1, 2, -3, 2, -1, -1, 1, +0, -2, 2, -1, -1, 1, 0, -2, +3, -2, 0, 0, -1, 1, 0, -1, +1, 1, -4, 4, -2, 0, 0, 1, +1, -2, 2, -1, -2, 3, -1, 1, +0, 0, -1, 2, -2, 2, 1, -1, +3, -3, 4, -4, 1, 0, 0, 0, +0, 1, 0, -1, 2, -3, 1, 0, +-1, 2, -2, 1, 2, -3, 2, 0, +1, -2, 2, -1, -1, 1, 4, -4, +1, 0, -1, 0, 2, -2, 1, 0, +-1, 0, 1, -1, 0, 1, 0, -1, +1, -1, 1, 0, -2, 2, -1, -1, +2, -2, -1, 1, -1, 1, -3, 3, +-3, 1, 2, -3, 2, -1, -1, 1, +0, 0, 0, 1, -2, 1, 1, -1, +-3, 4, -2, 1, 2, -1, -1, 0, +1, -1, 1, 0, 1, -2, 1, -1, +1, -2, 2, -1, -2, 2, 1, -1, +-2, 3, -2, 0, 3, -2, 1, -1, +2, -2, 0, 1, -1, 1, -2, 2, +0, -1, -1, 2, -5, 5, -5, 4, +-1, 1, 1, -1, 1, -2, 1, 0, +0, 0, 1, -1, -1, 1, 0, 0, +-1, 0, -1, 1, -3, 3, -2, 1, +0, 0, -1, 2, -1, 0, 1, -2, +3, -3, 4, -4, 3, -3, 2, -3, +2, -1, 0, 0, 2, -3, 2, -1, +-2, 3, -4, 3, -1, 1, 3, -4, +2, -1, -2, 2, -2, 3, -4, 4, +0, -1, 2, -1, -2, 2, 0, -1, +2, -1, -1, 1, 3, -4, 3, -1, +0, -1, 2, -3, 2, -2, 1, -2, +1, 0, -3, 4, -4, 3, -2, 2, +-1, 0, 1, -1, 2, -2, 2, -1, +-1, 1, 1, -1, 1, 0, 0, 0, +1, -1, 2, -3, 2, -1, -3, 4, +-2, 1, 0, 0, -1, 1, -1, 1, +0, 0, -1, 2, -1, 0, -1, 2, +-2, 1, 2, -2, 2, -1, 2, -1, +0, 0, 0, 0, -1, 1, -1, 1, +-1, 0, 2, -1, -2, 3, -1, -1, +1, 0, 0, -1, 2, 0, -4, 4, +0, -1, 1, -1, 1, -1, -1, 2, +-3, 3, -1, 0, 2, -2, -1, 0, +4, -6, 2, 0, -2, 1, 0, 0, +-2, 2, 2, -4, 5, -5, 1, 0, +-2, 2, -1, 0, 0, 0, 2, -1, +-1, 1, -1, 0, 0, 1, 0, -2, +6, -5, 0, 3, -2, 1, -1, 1, +-1, 1, 1, -1, -1, 2, -2, 3, +-3, 3, -1, 0, 0, 1, 0, -1, +3, -3, -1, 2, -3, 2, 0, -1, +3, -4, 4, -4, 1, 0, -1, 1, +1, -2, 2, -2, 1, -1, 2, -1, +1, 0, 0, -1, 1, -1, 0, 1, +-3, 2, 2, -3, 0, 2, -1, 0, +0, 1, -2, 2, -2, 3, -5, 4, +-3, 3, -2, 0, 1, -1, -2, 2, +0, 0, -2, 3, -2, 1, 1, 0, +-1, 0, 2, -3, 1, 0, -1, 0, +0, 1, -1, 0, 2, -2, 3, -3, +3, -3, 1, 0, -1, 1, 0, -1, +1, -1, 0, -1, 2, -2, 1, -1, +0, 1, -2, 2, 2, -3, 4, -3, +1, -1, 3, -3, 0, 1, -1, 0, +2, -1, -1, 1, -1, 0, 2, -2, +3, -3, 2, -2, 1, -1, 4, -5, +4, -3, 1, -1, 2, -1, -2, 2, +0, -1, 2, -1, 1, -1, 1, -1, +4, -4, 2, 0, -3, 3, -2, 1, +0, 0, 1, -1, 0, 1, -2, 3, +-1, 0, 1, -1, 2, -3, 5, -4, +0, 1, -2, 1, 0, 0, -1, 0, +1, -1, -2, 4, -4, 3, 1, -2, +4, -2, -1, 2, -1, 0, -1, 2, +-2, 1, 1, -2, 3, -3, 1, 1, +-2, 2, -1, 2, -1, 0, 3, -3, +0, 0, 0, 0, 0, -1, 2, -2, +-3, 4, -1, -1, 1, 0, -1, 0, +0, 0, -1, 0, 0, 0, -1, 0, +1, -2, 1, -2, 2, -2, 0, 0, +1, -1, 1, -1, 0, 0, -2, 2, +-1, 1, -3, 3, -1, 0, -2, 3, +-2, 1, 0, 0, -3, 3, 0, 0, +0, 0, 1, -1, 0, 1, 0, 0, +-2, 3, -2, 1, 3, -3, 2, -2, +3, -2, -1, 2, -4, 3, 0, -1, +1, 0, -3, 2, 0, 0, -1, 2, +-1, 0, 1, -1, -1, 1, -1, 0, +-2, 2, -2, 2, -3, 2, 0, 0, +1, -1, 2, -2, 1, 0, 1, -1, +2, -1, 1, 0, 0, 0, 2, -3, +2, 0, -4, 3, 0, -1, -1, 1, +-1, 1, 1, -1, 1, -1, 2, -2, +2, -1, -1, 2, -1, 0, 1, -2, +5, -5, -1, 3, -4, 2, 2, -2, +0, -1, 2, -1, -1, 2, 1, -2, +1, -1, 1, -2, 2, -2, 0, 0, +-2, 3, -2, 1, -3, 3, -2, 1, +0, 0, 1, -1, 3, -2, 1, -1, +-2, 3, -2, 1, 2, -1, -1, 1, +1, -1, 1, -1, -1, 1, -2, 2, +0, -1, 2, -2, 1, -1, 1, -1, +-2, 3, -3, 2, 1, -1, -1, 1, +1, -2, 1, 1, -2, 1, 1, -1, +1, -2, 5, -4, -1, 2, -1, 0, +1, -1, 1, -1, -1, 1, -2, 1, +1, 0, -2, 2, 1, -2, 3, -3, +-1, 2, -3, 2, 3, -4, 1, 0, +-3, 3, -2, 2, 0, -2, 3, -2, +1, -1, 1, 0, -2, 2, 0, 0, +-1, 2, -1, 0, 0, 0, 1, -1, +1, -2, 3, -2, -2, 3, 0, -2, +3, -2, -2, 2, -1, 0, 0, -1, +0, 1, -4, 5, -4, 2, 2, -3, +2, -1, -2, 3, -3, 3, 0, -1, +1, -1, -1, 1, -1, 2, -1, 1, +1, -1, -2, 3, -2, 1, -2, 2, +-2, 2, 1, -2, 2, -1, -1, 1, +-1, 2, -3, 2, 1, -2, 3, -2, +3, -3, 2, -1, 0, 0, 1, -1, +1, -2, 1, -1, 1, -1, 1, 0, +-2, 2, -1, 1, -1, 2, -3, 3, +-2, 1, 0, -1, 1, -1, 2, -3, +1, 0, -2, 2, -2, 2, -3, 3, +-1, 1, 1, -1, 2, -1, -2, 2, +1, -1, -1, 2, -2, 1, 0, 1, +-4, 3, 0, -1, 1, 0, -2, 1, +0, -1, 1, -2, 2, -2, -1, 2, +-2, 1, -2, 2, -2, 1, 2, -2, +2, -1, 0, 1, -1, 0, 1, 0, +-3, 4, -1, 0, -1, 2, 0, -2, +3, -3, 1, -1, 0, 1, 0, 0, +2, -2, 1, -1, 4, -4, 3, -2, +0, 0, -1, 1, -1, 0, 1, -1, +0, 1, 0, -1, 0, 0, 0, -1, +2, -2, -1, 2, -3, 2, 1, 0, +-3, 4, -2, 1, -2, 3, -4, 2, +2, -3, 2, -1, 0, 0, 0, 0, +0, 0, -2, 3, -4, 3, 2, -2, +-2, 3, -1, -1, 1, 0, -1, 1, +-1, 1, -2, 2, 1, -2, 1, 0, +-1, 0, 3, -3, 4, -4, 4, -3, +-2, 3, 0, -2, 3, -2, -1, 2, +0, 0, 0, 0, 0, 0, 1, -1, +1, -1, 0, 2, -3, 3, -2, 2, +-4, 4, 0, -2, 2, 0, -1, 1, +1, -1, 1, -1, 1, 0, -1, 1, +1, -1, 2, -1, -2, 4, -6, 5, +-2, 0, 1, 0, 1, -1, 2, -2, +-1, 1, -1, 2, -3, 3, -3, 3, +-2, 1, 1, 0, -2, 2, 2, -3, +1, 1, -1, 0, 4, -4, 1, 0, +-2, 3, -2, 2, 1, -1, 0, 0, +0, 0, 1, -1, 0, 1, -3, 4, +-3, 1, 1, -2, 2, -2, 0, 1, +-4, 4, -1, 0, 0, 0, 2, -4, +4, -3, 1, -1, 3, -2, 0, -1, +2, -1, -1, 0, 4, -4, 1, 0, +1, -1, 2, -2, 1, -1, 3, -3, +4, -3, -2, 3, -1, 0, 1, -1, +0, 0, 1, -1, -1, 1, 1, -1, +1, -1, 3, -3, 2, -1, 0, -1, +1, 0, 0, -1, 1, -1, 0, 0, +-1, 1, 1, -1, 1, 0, 0, -1, +1, 1, -5, 4, 1, -3, 1, 2, +-5, 5, 0, -1, 1, 0, -2, 2, +-3, 3, -2, 2, 1, -2, 3, -3, +1, -1, 2, -2, -1, 2, -2, 2, +0, -1, 0, 1, -4, 4, -2, 1, +-2, 3, -3, 2, -2, 2, -1, 0, +3, -2, -1, 2, -2, 1, 0, 0, +-2, 2, -1, 1, -1, 1, 0, -1, +0, 1, 0, -1, 2, -2, 1, 0, +-1, 1, -3, 3, -2, 0, 3, -3, +-1, 4, -5, 3, 2, -3, 1, 0, +0, -1, 1, 0, -2, 2, 1, -2, +2, -1, -2, 2, 0, -1, 1, -1, +2, -2, 0, 1, -1, 1, 3, -4, +5, -4, -1, 3, -6, 5, -1, -1, +2, -2, 2, -3, 2, -2, 1, -1, +1, -1, -2, 3, -2, 2, -1, 1, +1, -1, 3, -3, 1, 0, -1, 0, +2, -2, 0, 1, 0, -1, 4, -3, +0, 1, 0, -1, 2, -1, -1, 2, +-2, 2, -2, 1, 2, -2, -2, 3, +-1, -1, 3, -2, 0, 0, 3, -4, +2, 0, -1, 0, 4, -4, 2, -1, +1, -1, 3, -4, 4, -3, -1, 2, +-2, 1, 2, -2, 2, -1, 0, -1, +3, -4, 4, -2, 0, 1, -2, 2, +0, -1, 0, 1, -1, 0, 0, 0, +-2, 2, 0, -1, -1, 2, -1, 0, +4, -4, 1, 0, 0, -1, 2, -2, +2, -2, 2, -2, 1, 0, -2, 2, +0, 0, 0, 0, 1, -1, -1, 1, +0, -1, 3, -2, 0, 0, 1, -1, +0, 0, -1, 2, -3, 3, -1, 0, +1, -1, 1, 0, -1, 1, 1, -1, +0, 0, 2, -2, 1, 0, -2, 1, +2, -2, -1, 2, -4, 3, -2, 1, +1, -2, 1, -1, 1, -1, 1, 0, +-3, 4, -3, 2, 1, -2, 3, -2, +-1, 2, 0, -1, -1, 2, -2, 2, +-3, 4, -4, 3, 0, 0, -2, 2, +1, -2, 5, -4, 2, -1, 1, -2, +2, -2, 0, 0, -1, 2, -1, 1, +3, -4, 4, -2, -1, 1, 0, 0, +-1, 1, -2, 2, -2, 1, 0, 0, +-2, 2, 1, -2, 2, -2, 2, -2, +0, 1, -1, 1, 0, 0, 0, 0, +-1, 1, 0, -1, 2, -1, -1, 1, +1, -2, -1, 2, -3, 2, 1, -1, +2, -2, 1, -1, 1, -1, -1, 2, +-3, 1, 4, -4, 1, 1, -2, 2, +-1, 1, 0, 0, -2, 2, 1, -2, +0, 2, -3, 2, 1, -1, -1, 1, +0, 1, -3, 3, 0, -2, 2, -2, +1, -1, -1, 1, 1, -2, 5, -5, +1, 0, 1, -2, 3, -4, 3, -3, +1, 0, 0, -1, 3, -4, 1, 0, +-2, 2, -1, 0, 0, 0, 1, -2, +3, -3, 1, 0, -1, 1, -1, 1, +0, 0, 1, 0, -2, 2, 0, -2, +3, -3, 0, 0, 0, 0, -2, 2, +0, -1, 1, -1, 0, -1, 2, -1, +-1, 2, -3, 3, -2, 1, 0, -1, +3, -3, 2, -2, 0, 0, 1, -2, +3, -3, 3, -2, 2, -1, -1, 1, +0, 0, -2, 3, -3, 1, 1, -1, +-1, 2, -1, 1, 1, -2, 1, 0, +-1, 0, 1, -1, -1, 1, 2, -3, +-1, 3, -4, 3, 1, -2, 2, -1, +0, 0, -1, 1, -1, 1, 2, -3, +1, 1, -2, 1, 3, -4, 5, -4, +3, -2, 1, 0, 0, 0, 1, -1, +0, 1, -2, 2, 1, -2, 2, -2, +1, -1, -2, 3, -2, 1, 0, 1, +-3, 3, 0, -1, 1, 0, -4, 4, +-3, 2, 0, -1, 1, -2, 2, -1, +0, 0, 2, -3, 2, -1, 0, -1, +0, 1, -5, 6, -2, 0, 2, -1, +0, 0, 3, -4, 3, -2, 1, -1, +0, 0, 1, -1, 0, 1, 0, 0, +2, -2, 2, -2, 3, -3, 0, 1, +-2, 1, 1, -1, -1, 2, -2, 1, +2, -3, 3, -2, -1, 1, 1, -1, +-1, 3, -4, 4, -1, 2, -4, 4, +0, -1, 1, 1, -2, 1, 1, -1, +-1, 2, -2, 2, 0, -1, 2, -1, +-2, 2, -1, 0, 0, 1, -3, 3, +-1, -1, 4, -4, 2, -1, -1, 2, +-1, 1, -1, 2, -4, 3, 0, -1, +0, 0, 0, -1, 3, -2, -2, 3, +-2, 0, 3, -4, 4, -3, 1, -1, +1, -1, 1, 0, 1, -1, -1, 1, +2, -3, 2, 0, -3, 3, -1, 1, +-2, 2, -1, 1, 1, -1, 0, 0, +0, -1, 3, -3, 0, 1, -2, 1, +1, -1, -1, 1, -3, 3, -2, 1, +-1, 1, -4, 5, -5, 4, -3, 3, +-3, 1, 3, -4, 2, -1, -1, 0, +3, -4, 3, -2, 2, -3, 3, -2, +-2, 3, -2, 1, 3, -4, 2, -1, +-1, 1, -1, 1, -1, 2, -5, 6, +-4, 3, -1, 1, 0, 0, -1, 2, +-3, 3, -1, 0, 5, -6, 5, -3, +0, 1, -2, 2, 1, -2, 2, -1, +-3, 3, -1, 0, 1, -1, 0, 0, +-2, 2, 1, -2, 2, -1, 1, -1, +1, -1, 0, 1, -2, 2, -1, 0, +0, 0, -1, 1, 1, -1, 0, 0, +0, 0, -3, 4, 0, -2, 4, -4, +2, -2, 2, -3, 1, 0, -1, 1, +1, -1, 0, 1, -2, 2, -1, 1, +-2, 3, -3, 2, 0, 0, -2, 2, +-1, 0, 2, -2, -1, 2, -4, 4, +-4, 4, -3, 3, -1, 1, -1, 2, +-3, 2, -1, 1, -1, 0, 1, -1, +1, 0, -1, 1, 0, 0, 0, -1, +2, -3, 1, 0, -1, 1, 0, -1, +0, 1, -1, 0, 3, -3, 2, -1, +1, -1, 3, -3, 2, -2, 3, -3, +3, -3, 1, -1, 1, -1, 0, 1, +-2, 2, -1, 1, 0, -1, 4, -3, +2, -2, 4, -4, 2, -1, -1, 0, +1, -2, 3, -4, 4, -4, 0, 1, +-2, 1, 0, 0, 0, 0, 0, 0, +-1, 1, 1, -1, 0, 1, -2, 2, +-2, 2, -1, 0, -1, 0, 2, -2, +0, 2, -2, 1, 3, -3, 2, -2, +1, -1, -3, 3, -2, 0, 1, -1, +2, -2, 0, 1, -2, 1, 1, -1, +-1, 1, -3, 3, -5, 4, -1, -1, +3, -2, -3, 4, -4, 3, -2, 2, +-4, 4, 0, -1, 1, 0, -2, 2, +1, -1, 0, 0, -1, 1, 0, 0, +0, 0, -1, 1, -2, 2, 0, 0, +1, -2, 3, -4, 3, -3, -1, 1, +-1, 1, 1, -1, 0, 1, -1, 1, +1, -2, 1, -1, 1, -1, -1, 1, +0, -1, 1, 0, -1, 2, -3, 3, +-4, 4, -2, 1, -1, 0, 1, -1, +4, -4, 5, -2, -4, 6, -2, 0, +1, -1, -1, 1, -2, 3, -3, 4, +-3, 3, 0, -1, 1, 0, -3, 3, +1, -2, 2, -1, 1, -1, 2, 0, +-1, 2, -1, 1, 1, -3, 1, -1, +-1, 0, 1, 0, -1, 2, 0, -1, +4, -4, 4, -4, 2, -2, -2, 2, +-3, 3, -3, 4, -2, 3, 2, -3, +2, -2, -2, 2, -2, 1, -2, 2, +-2, 2, 0, 0, 1, -1, 0, 0, +-2, 1, -3, 1, -1, 2, -4, 4, +1, -1, 1, 1, -2, 1, -1, 0, +-2, 1, 1, -1, -1, 3, 0, -1, +3, -1, -3, 5, -3, 0, 3, -4, +0, -1, 3, -4, 5, -3, 3, -1, +0, 2, -2, 2, -3, 2, -3, 1, +1, -2, 3, -2, 4, -3, 3, -1, +-1, 1, -2, 1, -3, 2, -2, 1, +-1, 3, -1, 2, 2, -1, 0, 0, +-3, 3, -5, 3, -2, -1, 2, -1, +0, 2, 1, 0, 1, 0, -3, 2, +-2, -1, -1, 0, -4, 4, -1, 1, +1, 1, -2, 3, -3, 2, -4, 2, +-2, 0, 0, -1, 2, -1, 2, -1, +4, -3, 0, 2, -6, 3, -4, 3, +-5, 3, 3, -2, 2, 2, -1, 3, +-2, 3, -5, 2, -1, -2, -2, 2, +-2, 2, 0, 3, -3, 6, -3, 4, +-4, 2, -1, -2, -1, 0, -1, 0, +1, 1, 1, 1, -1, 3, -5, 4, +-3, 0, 0, -3, 3, -3, 1, 1, +3, -2, 2, 2, -4, 3, -2, 1, +-6, 3, -2, 1, -2, 4, -2, 3, +2, -1, 2, -1, -2, 2, -4, 1, +-2, 1, -1, 2, 0, 1, 4, -2, +4, -2, 0, -1, -4, 2, -5, 1, +2, -3, 4, -2, 5, -2, 4, -1, +0, 0, -3, 1, -5, 2, -1, -1, +1, 1, 1, 2, 1, 2, -1, 2, +-4, 2, -4, 0, 1, -3, 1, 1, +3, -1, 4, 0, 0, 1, -3, 1, +-4, 1, -2, 1, -3, 4, 0, 1, +3, 0, 1, 1, -1, 0, -3, -1, +-1, -2, 0, -1, 4, -2, 3, 1, +1, 0, 0, 1, -4, 1, -3, -1, +-3, 1, 2, -1, 4, 0, 2, 0, +1, 0, -3, 1, -3, -2, -2, 0, +1, -2, 6, -2, 3, 2, 1, 0, +0, -1, -4, 0, -4, 0, -1, 1, +2, 0, 6, -2, 3, -1, 1, -1, +-6, 2, -2, -3, 2, -3, 2, 0, +4, -1, 4, 0, -3, 4, -5, 0, +-3, 0, -5, 2, 2, -1, 3, 1, +5, -1, 0, 2, -3, -1, -2, -2, +-1, -1, 0, 1, 3, 0, 6, -2, +3, -1, 3, -6, 0, -2, -5, 2, +0, -1, 4, -2, 8, -2, 2, 1, +2, -4, -1, -1, -5, 1, -2, 0, +1, 1, 4, 0, 2, 2, -1, 1, +-4, 0, -2, -3, -1, 0, 1, 1, +4, 0, 4, 0, 1, 0, -2, -1, +-5, 0, 0, -4, 3, -2, 3, 1, +2, 4, -2, 4, -2, -2, -1, -3, +-4, 0, -4, 3, -1, 3, 6, -2, +2, 3, -3, 1, -2, -2, -6, 2, +-2, -1, 6, -3, 2, 4, 2, 0, +3, -2, -3, 0, -5, 0, -2, -2, +2, 0, 3, 1, 6, -1, 1, 2, +-5, 2, -7, 1, -4, 1, -2, 1, +6, -4, 8, -3, 4, -2, 1, -2, +-5, 1, -4, -2, 2, -3, 5, -2, +7, -1, 3, 1, -1, 1, -6, 2, +-3, -4, 4, -6, 4, -1, 5, 0, +6, -2, 2, -1, -3, -1, -1, -5, +1, -4, 0, 2, 0, 5, 2, 3, +1, 0, -2, 0, -8, 3, -8, 3, +-1, 0, 4, 0, 6, 0, 3, 0, +-2, 1, -5, 0, -4, 0, -5, 4, +2, 0, 6, 1, 4, -1, 0, 1, +-9, 6, -10, 4, -4, 0, 4, -3, +7, -1, 4, 1, 2, -1, -4, 2, +-9, 2, -3, -2, 1, 0, 7, -3, +7, 0, 1, 1, -2, 0, -9, 4, +-8, 3, -3, 2, 4, -1, 10, -4, +8, -3, 1, -2, -6, 2, -9, 3, +-2, -1, 3, 1, 4, 1, 5, 0, +-1, 1, -2, -3, -5, -1, -3, 0, +2, 0, 5, 0, 5, 0, 3, -1, +-5, 2, -5, -2, -3, 1, -2, 1, +5, 0, 4, 2, 5, -2, 0, -1, +-5, -1, -3, -2, -2, 2, 2, 0, +10, -4, 6, 0, -2, 1, -6, 1, +-5, -1, -1, -1, 4, -1, 5, 1, +4, 1, -1, 3, -7, 2, -5, -1, +-5, 2, -1, 1, 4, 1, 5, 0, +2, 1, -4, 1, -5, -2, -1, -3, +-1, 2, 4, 1, 3, 4, 0, 2, +-2, 0, -8, 2, -6, 1, -3, 1, +3, 0, 5, 1, 5, -1, 1, 0, +-4, -1, -3, -3, -2, 1, 0, 1, +5, 1, 6, -1, 2, 0, -5, 1, +-6, 0, -6, 1, 2, -1, 7, -2, +6, 1, 1, 0, 0, -3, -4, -2, +-3, -2, 2, -3, 6, -1, 4, 2, +4, -1, -3, 3, -7, 0, -3, -2, +-2, 1, 0, 4, 3, 1, 5, 0, +0, 0, -2, -3, -5, -1, -1, -3, +4, -1, 2, 4, 3, 2, 1, 0, +-1, -2, -6, 1, -4, -1, 2, -1, +6, -1, 5, 2, -2, 4, -5, 2, +-6, -1, -2, -2, 0, 0, 5, -2, +10, -4, 7, -3, 0, 0, -4, -2, +-4, 0, -6, 4, 4, -3, 10, -3, +5, 0, -1, 2, -6, 1, -5, -1, +-4, 1, 2, -1, 7, -2, 7, 0, +-1, 4, -6, 2, -5, 0, -5, 1, +1, -2, 7, -2, 8, -1, 2, 1, +-1, -2, -3, -1, -6, 2, -1, -1, +4, 0, 2, 4, 2, 1, -3, 2, +-7, 1, -3, -4, 3, -4, 3, 0, +7, -2, 6, 0, 2, -2, -1, -1, +-7, 2, -5, 2, 0, 1, 6, -1, +6, 0, 3, -1, -3, 1, -7, 2, +-8, 3, -1, 0, 4, -1, 6, -2, +3, 0, -3, 1, -6, 1, -6, 1, +-2, 1, 1, 2, 5, 0, 2, 3, +-4, 3, -6, 3, -7, 3, -4, 2, +0, 3, 3, 2, 4, 1, 0, 1, +-3, 0, -6, 2, -4, -1, 3, -1, +2, 2, 3, 0, 2, -1, -2, 0, +-7, 0, -2, -3, 0, 0, 2, 0, +8, -4, 7, -4, 0, -1, -3, -1, +-5, 2, -4, 2, 4, -1, 6, 1, +5, -2, 4, -3, 0, -4, -2, 0, +-6, 4, 1, 0, 4, 0, 3, 0, +1, -1, -3, -1, -4, -2, -4, 0, +1, -3, 7, -2, 1, 2, 3, -3, +0, -1, -5, 1, -4, 1, -1, 1, +2, 2, 4, 0, 6, -2, 2, -2, +0, -4, 2, -6, 3, -3, 3, 0, +4, 1, 1, 2, -2, 1, -4, 1, +-3, -3, 3, -7, 4, -2, 2, 1, +3, -1, 0, 0, -3, -1, -3, -1, +-3, -1, 2, -1, 1, 3, 1, 2, +0, 2, -2, 1, -3, 1, -2, -2, +2, -1, 2, 1, 6, -2, 5, -1, +-3, 2, -2, -2, -3, 0, -3, 1, +0, 1, 3, 0, 1, 2, -3, 1, +0, -4, -5, 1, -3, -1, 2, 0, +0, 3, 2, 0, 2, -1, 0, -2, +2, -5, -2, 2, -2, 2, 5, -1, +3, 2, 0, 3, -4, 2, -1, -2, +-1, -1, -1, 1, -2, 5, 1, 0, +7, -7, 3, -2, -6, 2, -5, 0, +0, -2, 0, 1, 1, 0, 4, -2, +1, -1, -2, 0, -2, -1, 0, -1, +2, 0, 4, 0, 4, 0, 2, 2, +-2, 1, 0, -1, 0, -1, 3, -3, +6, -2, 1, 3, 0, 0, -1, 0, +-5, 1, -5, 1, -4, 1, 0, -1, +1, -1, 1, -1, -2, 0, -5, 1, +-4, 0, -4, 3, -2, 1, 3, -1, +3, 0, 3, -1, 0, 2, -5, 5, +-2, 3, 1, 2, 3, 0, 4, 0, +1, 1, 1, -1, -1, 0, -4, 2, +-2, 0, -2, 1, -1, 1, -4, 3, +-7, 3, -5, 0, -6, 2, -3, -1, +2, -2, -1, 2, 3, -3, 4, -2, +0, 1, 1, -1, 4, -3, 6, -2, +6, -2, 8, -2, 4, 1, 0, 1, +2, -3, 2, -3, 0, -1, 0, 0, +-2, 1, -1, -1, -4, 1, -7, 1, +-6, 0, -4, -1, -2, 0, -3, 2, +-2, 2, -1, 1, 0, 1, 0, 1, +3, 0, 3, 1, 6, 1, 3, 4, +4, 1, 5, 0, 1, 2, -1, 2, +-1, 2, -2, 1, 1, -2, -5, 4, +-7, 1, -7, 1, -6, -3, -1, -4, +-7, 2, -1, -4, 0, -1, -4, 3, +-5, 4, -3, 3, 0, 2, 5, -1, +7, 0, 6, 3, 4, 3, 9, -4, +9, -3, 4, 0, 2, 3, -2, 3, +1, -1, -1, 0, -5, 1, -7, -1, +-5, -3, -10, 2, -13, 4, -7, -1, +-3, -2, -5, 0, -3, 0, -4, 2, +0, 0, 1, 3, 6, 0, 9, 1, +8, 2, 9, -1, 9, -1, 8, -1, +8, -3, 7, -1, 2, 1, -2, 3, +-5, 1, -6, -1, -10, 1, -12, 1, +-9, -1, -9, 1, -9, 2, -10, 3, +-10, 3, -7, 1, -2, 0, 0, 3, +3, 3, 8, 1, 12, -2, 11, 1, +6, 4, 8, 0, 10, -1, 10, -2, +8, -1, 3, 0, 0, -2, -5, -1, +-10, 2, -15, 3, -12, 0, -13, 3, +-12, 0, -6, -6, -6, -4, -7, -3, +-2, -2, -3, 4, 3, 1, 10, -1, +11, 0, 11, 1, 7, 4, 10, 0, +15, -2, 13, 0, 14, -2, 4, 4, +0, 0, -4, 1, -9, 0, -7, -3, +-10, 0, -9, -3, -9, -4, -13, 0, +-16, 1, -12, -1, -8, -1, -1, -3, +5, -1, 6, 1, 10, -1, 10, 1, +11, -1, 16, -2, 16, 0, 18, -1, +16, 0, 13, -3, 9, -4, 1, -1, +-4, -1, -9, 1, -9, -1, -10, -1, +-14, 0, -18, 1, -19, 0, -16, -1, +-12, -1, -6, -2, 2, -3, 5, -2, +8, -2, 10, -2, 13, -3, 18, -3, +21, -3, 23, -2, 19, 1, 12, 3, +8, 0, 4, 0, -2, -1, 0, -4, +-6, 1, -13, 2, -16, 1, -21, 2, +-25, 3, -20, -2, -16, 1, -16, 5, +-6, 0, 1, -1, 0, 1, 4, 0, +9, 1, 13, 2, 19, 1, 22, 0, +24, -2, 20, -1, 13, 0, 7, 1, +2, 2, 1, 0, 0, -2, -7, 0, +-13, -1, -20, 0, -24, 1, -23, -1, +-17, -2, -14, 1, -12, 2, -7, 0, +-5, 2, -3, 1, 7, -1, 11, 1, +22, -3, 24, 0, 25, -3, 22, 0, +15, 0, 11, 2, 7, 2, 8, 0, +4, -2, 0, -3, -15, 3, -19, -2, +-23, 1, -27, 3, -22, 2, -20, 3, +-15, -1, -12, 1, -15, 4, -6, -1, +3, -1, 13, -2, 18, 2, 21, 1, +24, 0, 19, 1, 20, -2, 19, -2, +15, 1, 14, -2, 10, -1, 0, 0, +-6, -3, -15, -1, -20, -1, -23, 1, +-20, -2, -15, -4, -18, 1, -20, 2, +-15, -2, -7, -3, -3, 2, 5, 1, +14, 2, 15, 4, 19, 2, 17, 4, +17, 1, 22, -3, 22, 0, 17, 2, +11, 2, 2, 3, -7, 1, -12, -1, +-17, 1, -21, 1, -18, -2, -17, -2, +-20, -1, -24, 1, -21, -1, -15, -1, +-6, -1, 3, 1, 7, 3, 12, 2, +16, -1, 19, -2, 21, -1, 23, 0, +24, 1, 22, 1, 18, 0, 7, 1, +0, -1, -7, 0, -13, 0, -13, -1, +-17, 2, -19, -1, -22, 0, -25, -1, +-23, -1, -18, -1, -9, -3, 1, -2, +3, 3, 6, 1, 12, 0, 13, 1, +19, -1, 24, -1, 29, -3, 27, 0, +19, 1, 16, -4, 6, 0, -4, 2, +-5, 0, -10, 2, -13, 0, -18, 2, +-26, 3, -25, -3, -22, -4, -20, 0, +-14, 1, -10, 4, -3, 0, 7, -5, +9, -3, 12, -2, 16, 1, 21, 1, +27, 0, 27, -2, 23, 0, 13, 1, +10, -2, 1, 4, -1, -1, 3, -5, +-9, 3, -17, 2, -22, 0, -24, -2, +-23, -2, -21, 1, -18, 3, -13, 2, +-9, 2, -4, 0, 0, -1, 7, -2, +16, -4, 25, -4, 27, -1, 24, 1, +19, 2, 14, 0, 15, -4, 11, -1, +5, 2, 2, 1, -3, -1, -10, -1, +-18, -1, -21, -3, -20, -3, -20, 2, +-19, 3, -13, -1, -9, -1, -9, -2, +-1, -5, 2, 1, 10, -2, 18, -1, +20, 1, 23, -1, 20, -1, 19, -3, +16, -1, 12, 2, 9, 2, 7, 0, +4, -3, -7, -1, -16, 0, -18, -3, +-17, -2, -20, 3, -15, -3, -12, -3, +-14, 0, -16, 3, -11, -1, 2, -4, +5, 2, 11, 1, 17, 0, 17, 0, +17, -1, 16, -1, 17, -2, 20, -3, +16, 0, 12, -1, 6, -1, -4, 0, +-9, 0, -15, 1, -14, -1, -16, 4, +-17, 2, -15, 0, -19, 2, -18, 1, +-14, 2, -9, 4, 0, 2, 7, 2, +7, 5, 8, 3, 10, 2, 11, 3, +15, 0, 20, -2, 17, 1, 11, 4, +2, 5, -3, 0, -5, 0, -9, 1, +-9, -1, -7, -3, -10, -2, -13, -3, +-15, -2, -16, 0, -14, 0, -7, -1, +-1, 0, 4, -1, 8, -1, 7, 1, +8, -2, 15, -5, 18, -1, 18, -1, +17, 0, 12, 0, 9, -2, 4, -1, +0, -1, -5, 1, -2, -4, -4, 0, +-11, 1, -12, -3, -14, -2, -15, -1, +-11, -3, -4, -1, -6, 4, -5, 4, +-5, 5, -1, 4, 4, 1, 8, 2, +8, 4, 15, -1, 16, 0, 15, -2, +8, 2, 0, 1, 4, -1, 0, 2, +0, -1, -1, -3, -4, -4, -12, 0, +-14, 1, -14, 1, -13, -1, -7, -2, +-1, -3, -2, 0, -2, -1, 1, -3, +-1, 2, 5, 2, 10, 2, 13, -1, +15, -4, 13, -2, 7, 3, 4, 1, +7, -3, 6, -3, 4, -1, -2, 4, +-7, 3, -9, -2, -10, -3, -7, -4, +-5, -2, -7, 1, -3, -5, -2, -5, +-5, 1, -5, 3, 0, -2, 5, -2, +10, -4, 14, -2, 7, 5, 8, -1, +6, -2, 6, -2, 11, -3, 10, 0, +7, -3, 4, -5, -1, -2, -3, -2, +-7, 2, -9, 2, -8, -2, -8, 2, +-8, 5, -10, 4, -12, 2, -5, -4, +1, -2, 1, 4, 6, 0, 8, -4, +6, -3, 8, -2, 6, 3, 3, 3, +5, -2, 6, 0, 2, 5, 4, 0, +1, -1, -5, -3, -4, -3, -2, 1, +-3, 2, -5, -1, -6, -2, -6, -2, +-7, 3, -5, 3, -3, -1, -1, -4, +4, 1, 3, 2, 7, -3, 6, -7, +8, -8, 5, 3, 5, 5, 6, 2, +4, -4, 6, -7, 4, 0, 0, 3, +2, -5, 1, -6, -1, -2, -4, 5, +-6, 6, -7, 0, -9, -3, -6, 1, +-4, 7, -4, 6, 0, -2, 1, -6, +-2, 2, -1, 7, 3, 0, 6, -5, +5, -4, 5, 2, 1, 9, 1, 1, +4, -9, 2, -3, 0, 1, 3, 5, +-3, 5, -6, -3, -6, 1, -7, 6, +-2, 1, 0, -4, 1, -8, 0, -4, +-1, 7, -3, 6, -1, -6, 0, -6, +2, -2, 5, 4, 2, 5, 6, -7, +3, -6, 2, 0, 3, 5, 3, 3, +1, -5, 4, -8, 1, 5, -1, 5, +1, -2, -4, -3, -6, -3, -5, 7, +-2, 9, -2, -2, -1, -8, -2, -1, +-5, 8, -4, 8, 0, -2, 2, -9, +1, 0, 1, 8, 0, 7, -2, -2, +-1, -6, 2, 0, 4, 6, 6, -2, +8, -11, 2, -9, 2, -2, 3, 7, +1, -1, 0, -9, 0, -5, 0, 4, +-5, 11, -2, 1, -1, -10, -4, -3, +-1, 7, -1, 9, -1, -3, 4, -12, +2, -4, 0, 8, 0, 7, 1, -2, +1, -8, 3, -2, 3, 9, 2, 4, +1, -9, 1, -7, 2, 1, -2, 11, +-2, 7, -1, -7, -5, -7, -1, 4, +3, 4, -2, 1, -2, -8, 3, -9, +-5, 10, -1, 8, 3, -5, 1, -12, +2, -5, 2, 10, -3, 14, -4, -1, +3, -11, 2, -1, -1, 10, 1, 9, +0, -3, -4, -9, -1, 4, 0, 11, +-2, 2, -1, -6, -3, -6, -4, 2, +0, 12, -2, 5, -8, -7, -2, -8, +4, 2, 0, 9, -1, 0, 2, -12, +2, -6, -1, 9, 4, 8, 2, -2, +0, -13, 5, -4, 5, 9, 2, 5, +2, -6, 1, -9, -1, -4, 1, 12, +1, 6, -1, -12, -2, -10, 0, 4, +-5, 11, -3, 4, 2, -12, 2, -14, +-1, 6, 0, 12, 0, 0, 1, -13, +5, -10, 4, 7, 1, 10, 5, -5, +7, -12, -2, -3, 1, 11, 0, 16, +-5, -4, 1, -15, 8, -5, 0, 8, +-4, 9, -1, -5, -3, -15, -3, 1, +3, 10, 2, 0, -3, -9, 2, -10, +-3, 7, -3, 12, 7, -2, 2, -9, +-3, -6, 4, 5, 6, 12, -1, 1, +2, -15, 7, -5, -1, 8, 2, 8, +4, -1, -2, -15, -2, -5, -1, 16, +-6, 9, -6, -6, 2, -12, 1, -4, +-6, 13, 2, 5, 2, -11, -6, -9, +3, 2, 5, 12, -3, 6, 5, -14, +7, -10, -3, 8, 3, 9, 9, 1, +-3, -8, -2, -8, 4, 10, 0, 9, +-4, -3, 1, -10, -3, -4, -10, 13, +0, 12, -2, -5, -9, -12, 0, -1, +0, 11, -6, 9, 2, -6, 6, -14, +-2, 3, 0, 13, 5, 7, -2, -7, +4, -14, 8, 4, 0, 15, -4, 5, +3, -9, 0, -8, -7, 6, 2, 14, +1, -2, -4, -15, 2, -7, 2, 5, +-11, 13, -5, 1, 2, -14, -5, -5, +0, 12, 4, 9, -7, -1, 0, -12, +9, -4, -2, 14, 3, 4, 12, -9, +2, -9, -1, 0, 6, 11, 3, 3, +-2, -12, 3, -8, -1, 7, -8, 10, +-1, 5, -3, -8, -9, -11, -3, 9, +-3, 15, -8, -2, 1, -12, 9, -10, +-2, 7, -1, 11, 9, -6, 3, -13, +3, -4, 11, 6, 3, 10, -2, -6, +9, -14, 3, 0, -3, 8, 5, 5, +2, -4, -9, -11, 1, 1, 0, 12, +-7, -1, -3, -7, 1, -8, -7, 2, +-4, 12, 7, -1, -3, -11, -3, -6, +6, 6, -2, 11, -1, 0, 11, -12, +2, -2, -2, 8, 8, 6, 4, 0, +-6, -8, 5, -6, 5, 10, -8, 8, +-2, -4, 0, -7, -10, -2, -7, 11, +1, 7, -4, -10, -6, -6, 2, 3, +-4, 6, -4, 4, 5, -5, 1, -9, +0, 3, 12, 5, 7, 0, -3, -5, +6, -7, 6, 4, -4, 11, 3, -1, +6, -7, -8, -2, -2, 5, 2, 9, +-6, -5, -4, -10, 0, 1, -8, 7, +-6, 5, 7, -6, -3, -11, -4, -4, +9, 7, -1, 7, -3, -4, 9, -8, +7, -3, -2, 11, 5, 4, 10, -9, +-2, -5, 6, -1, 7, 10, -7, 5, +-1, -10, 4, -6, -6, 3, -5, 6, +3, 0, -3, -10, -9, -4, 2, 4, +-1, 4, -7, -1, 0, -2, -1, -4, +-1, 3, 8, 7, 5, -4, -1, -8, +5, -1, 9, 5, 0, 6, 7, -7, +9, -8, -8, 6, -5, 9, 4, 3, +-2, -7, -3, -11, 3, 2, -8, 11, +-9, 0, 3, -7, -4, -6, -8, 1, +2, 10, 0, 4, -9, -3, 1, -1, +5, 3, -1, 5, 6, 0, 9, -8, +-1, -4, 6, 3, 10, 4, -1, -1, +-3, -6, 5, -5, -2, 7, -5, 5, +2, -1, -8, -3, -8, -6, 3, 5, +-2, 5, -8, -6, 2, -8, 5, -2, +-5, 7, 2, 6, 4, -3, -7, -4, +2, 4, 11, 5, 2, 1, 4, -6, +12, -11, 1, 4, -7, 15, 0, 4, +-3, -5, -6, -5, 4, 2, -4, 10, +-9, -3, 0, -9, -3, -2, -9, 5, +-1, 8, 2, -1, -7, -8, -1, 0, +3, 9, -2, 5, 1, 0, 9, -10, +2, -1, -2, 13, 9, 2, 2, -6, +-5, -3, 1, 4, -2, 10, -5, 5, +-1, -5, -4, -5, -7, 1, 0, 7, +-5, 7, -9, -7, -4, -4, -1, 7, +-5, 6, -1, 1, 3, -5, -2, -6, +3, 5, 9, 8, 2, -3, 2, -8, +5, 0, -1, 9, -2, 9, 5, -3, +0, -8, -5, 0, 0, 8, -3, 8, +-8, -5, -1, -11, -1, 2, -6, 8, +-2, 2, 0, -4, -6, -8, 0, -1, +6, 9, 1, 1, 0, -8, 7, -6, +2, 4, -3, 13, 3, 4, 6, -14, +3, -7, 4, 7, 4, 7, -3, 0, +-2, -8, 1, -4, -5, 9, -5, 9, +-3, 0, -7, -8, -2, -6, 3, 8, +-3, 5, -3, -7, -1, -3, -2, 1, +0, 8, 5, 6, 3, -9, 1, -10, +6, 4, 5, 10, -2, 4, 1, -4, +1, -5, -3, 5, 1, 9, 2, 0, +-5, -10, -2, -6, -1, 8, -4, 9, +-7, -1, 1, -12, -2, -3, -6, 8, +5, 6, 3, -6, 0, -13, 3, 2, +0, 12, 0, 4, 5, -5, 1, -6, +-2, 2, 4, 11, 3, 6, -3, -8, +1, -11, 3, 4, -6, 13, -1, 0, +4, -13, -5, -5, -5, 5, 1, 9, +-2, 0, -3, -12, 4, -8, 1, 9, +-2, 9, 2, -2, 1, -11, 2, -6, +5, 8, 9, 4, 4, -7, 4, -12, +2, 2, -3, 12, 1, 6, 1, -7, +-1, -11, -1, 2, -1, 12, -1, 2, +-1, -12, -1, -10, -3, 7, -6, 14, +-1, 0, 2, -11, -2, -7, 0, 6, +1, 13, 1, -2, 1, -10, 4, -5, +3, 9, 0, 11, 3, -5, 4, -16, +2, -5, 2, 10, 0, 9, 0, -9, +3, -16, 1, -1, -5, 13, -3, 5, +0, -9, -1, -11, -2, 3, 3, 10, +2, 1, -2, -11, 3, -9, 2, 5, +4, 9, 7, -2, 5, -14, -1, -4, +-3, 15, -1, 11, 4, -8, 2, -11, +1, -5, 1, 8, -2, 12, -2, -6, +-4, -12, -5, 1, 0, 12, -2, 8, +-6, -4, -3, -10, 0, 0, -2, 14, +4, 3, 3, -11, -1, -9, 4, 6, +2, 13, -1, 3, 1, -11, 4, -11, +0, 8, 2, 13, 2, -2, -1, -15, +0, -4, -4, 12, -4, 11, 1, -7, +3, -17, -2, -3, 0, 11, 1, 8, +-2, -9, 1, -15, 3, 0, -1, 15, +0, 8, 4, -10, 1, -12, 1, 3, +2, 15, 1, 3, -1, -10, 2, -9, +2, 5, 0, 12, 1, 1, -6, -11, +-5, -7, 0, 11, -3, 14, -6, 1, +-5, -10, -3, -4, -2, 12, 2, 8, +2, -7, -2, -12, 2, -1, 1, 15, +0, 7, 3, -11, 2, -14, 3, 1, +3, 14, 3, 4, 0, -11, -2, -11, +1, 3, 2, 12, -1, 1, 3, -17, +-1, -8, -4, 10, -1, 13, -1, -3, +0, -15, -3, -3, -1, 13, 0, 14, +-1, -4, 1, -15, 4, -5, 2, 14, +-3, 14, 1, -8, 1, -14, 2, 0, +3, 15, 0, 4, 1, -15, 5, -16, +2, 3, -2, 15, 2, 3, -2, -13, +-5, -10, 0, 9, -3, 18, -7, 2, +3, -16, 3, -7, -5, 14, 1, 14, +3, -4, -3, -17, 5, -7, 9, 12, +0, 8, 3, -10, 5, -14, -4, 0, +-3, 15, 7, 4, 0, -13, -7, -11, +5, 3, -3, 17, -10, 7, 0, -11, +-3, -10, -5, 8, 4, 15, 4, -2, +-4, -15, 2, -7, 3, 12, -7, 16, +1, -2, 5, -15, -2, -6, 1, 15, +4, 14, -7, -6, -1, -17, 7, -2, +-4, 17, -5, 11, 6, -15, 1, -17, +-8, 6, 4, 13, 2, 2, -3, -15, +5, -14, 4, 4, -2, 15, 0, 4, +0, -14, 0, -12, 4, 11, 5, 14, +-1, -2, -3, -13, 2, -5, 0, 12, +0, 11, 4, -8, 0, -17, 0, -5, +1, 16, -3, 11, -2, -13, 1, -18, +2, 2, -2, 15, 1, 4, 4, -14, +-1, -12, -2, 5, 6, 14, 2, 4, +-7, -11, 3, -10, 6, 8, -3, 15, +2, -2, 5, -17, -6, -5, 0, 13, +7, 12, -4, -7, -3, -16, 5, -2, +-6, 16, -4, 7, 10, -13, -1, -16, +-6, 2, 5, 17, 1, 6, -8, -12, +7, -14, 5, 4, -6, 15, 7, 3, +5, -14, -8, -11, 3, 9, 8, 15, +-7, -4, 6, -21, 7, -4, -10, 14, +-3, 13, 6, -5, -6, -18, -4, -5, +11, 11, -1, 10, -11, -4, 4, -14, +1, 0, -10, 19, 4, 10, 0, -9, +-10, -11, 9, 2, 8, 13, -4, 1, +6, -17, 7, -11, -6, 9, 1, 17, +1, 3, -6, -16, -2, -8, 6, 10, +-5, 14, -6, -3, 4, -16, 1, -6, +-6, 18, 0, 12, 2, -10, -5, -14, +2, 1, 3, 15, -2, 7, 3, -13, +5, -13, -3, 6, -3, 18, -1, 8, +0, -15, 0, -12, 3, 8, -2, 18, +-7, 1, 0, -16, 5, -10, -4, 12, +-2, 12, 5, -6, 0, -18, -2, -4, +4, 14, -2, 11, -6, -6, 7, -14, +1, 0, -3, 12, 5, 10, -3, -4, +-10, -12, 8, 0, 8, 13, -5, 2, +1, -11, 3, -8, -7, 6, -4, 17, +7, -1, -7, -12, -7, -5, 7, 10, +-4, 10, -4, -5, 6, -12, -2, -4, +-5, 10, 12, 9, -2, -2, -10, -13, +7, 2, 2, 14, -7, 6, 6, -9, +8, -14, -9, 5, 0, 15, 6, 4, +-11, -9, -4, -8, 8, 4, -6, 11, +0, -3, 8, -13, -7, -6, -4, 7, +10, 9, -4, 0, -5, -15, 12, -9, +2, 11, -2, 6, 9, -8, 3, -12, +-4, -1, 2, 13, 7, 3, -2, -9, +2, -13, 3, 4, -8, 16, -4, 5, +2, -11, -2, -9, -5, 7, 1, 11, +-2, 1, -4, -11, 0, -7, 3, 7, +-4, 14, -2, -2, 6, -14, 2, -5, +-3, 12, 5, 8, 4, -7, -2, -12, +6, -2, 4, 9, -1, 3, 4, -10, +6, -13, -7, 4, -2, 12, 2, 6, +-10, -6, -6, -5, 2, 7, -3, 8, +-6, 3, 3, -7, -4, -5, -5, 6, +8, 9, 3, -4, -4, -12, 8, -3, +4, 8, -4, 7, 4, -1, 5, -12, +-4, -4, 3, 11, 4, 7, -9, -6, +0, -9, 3, 4, -9, 9, -3, 4, +4, -7, -5, -9, -5, 6, 5, 11, +-5, 2, -4, -10, 9, -7, 1, 6, +-7, 10, 8, -1, 0, -7, -5, -4, +5, 10, 3, 6, -4, -6, 4, -9, +4, -1, -7, 9, 0, 6, 1, -4, +-8, -8, 0, -1, 5, 8, -6, 4, +-3, -8, 5, -7, -3, 5, -4, 8, +7, -3, 5, -10, -2, -5, 5, 4, +3, 8, -2, -1, 0, -5, 3, -3, +0, 7, -4, 10, 1, -2, -3, -6, +-5, 1, 1, 6, -1, 5, -4, -6, +0, -8, 1, 1, -4, 9, -4, 3, +4, -6, -3, -5, 0, 1, 2, 11, +-3, 3, -1, -8, 8, -7, 6, 1, +1, 3, 5, -1, 7, -13, 1, -3, +0, 8, 1, 7, -5, -3, 2, -8, +2, -1, -7, 7, -1, 3, 4, -6, +-5, -6, -3, 1, 4, 7, -7, 6, +-6, -2, 3, -2, -1, 0, 0, 5, +5, 3, 1, -7, -1, -5, 7, 6, +-1, 7, -5, -1, 6, -6, 0, 0, +-10, 7, 4, 4, 3, -4, -8, -4, +-2, 3, -1, 8, -10, 5, 0, -8, +9, -8, -5, 1, 0, 3, 8, -1, +2, -9, 1, -6, 6, 2, 2, 4, +-1, -2, 8, -6, 2, -3, -2, 3, +3, 5, 2, -2, -3, -4, -2, 1, +1, 2, -3, 4, -2, 0, -1, -6, +0, -2, -1, 4, 0, 1, 1, -6, +1, -4, -1, 0, 2, 3, 4, -2, +4, -6, 1, -3, 4, -1, 2, 6, +0, -1, 3, -3, -4, 3, -1, 4, +-2, 6, -1, 1, -1, -5, -1, -2, +1, 2, 0, 1, -4, 1, -4, -3, +1, -3, 0, 3, -2, 4, -3, -2, +1, -3, -1, -1, 5, -1, 3, 3, +-1, -4, 2, -2, 2, 3, 2, 2, +0, -1, 7, -5, 2, -5, 0, 3, +0, 5, 2, -4, -3, -3, -1, 0, +-1, 5, -8, 5, -1, 0, -3, 0, +-4, 0, 0, 0, 6, -1, -5, 1, +-3, -2, 7, -2, 2, 1, 1, 1, +3, -2, 5, -6, -2, 3, 4, 2, +4, -4, 1, -4, 3, -3, 0, 2, +-4, 6, -5, 5, -6, 1, -5, 0, +2, 2, -4, 3, -1, -1, -2, -1, +-2, 0, -1, 2, 3, 0, 0, -1, +-2, -1, 5, -1, -1, 6, 0, -1, +5, -6, 6, -3, -1, 1, 0, 6, +-1, 3, -3, -3, 1, -2, 2, 1, +1, -2, -4, 3, -3, 1, -1, -4, +0, 2, 1, -1, 1, -2, -6, 2, +-1, 2, 2, 0, 0, 2, 0, -2, +2, -2, 0, 3, 0, 2, 3, 1, +1, -3, 0, 1, -2, 2, 2, 1, +0, -2, 0, -1, -5, 3, -1, 1, +2, 0, 0, -3, 1, -2, -3, 0, +-1, 1, 1, 0, 3, -3, 0, -5, +4, 0, -2, 5, -3, 1, 2, -1, +1, -2, 3, -1, 1, 2, 5, -3, +-1, 0, 0, -1, 3, -3, 1, 3, +0, -2, -1, 0, -5, 5, -3, 0, +2, -1, -3, 0, 1, -3, -3, 1, +0, 4, -4, 3, 1, -1, -2, -1, +1, 0, -1, 6, -2, 1, 4, -4, +4, -4, 2, 0, 0, 0, 3, 2, +-6, 0, 0, 0, 1, 1, 1, 0, +-3, 3, 0, -4, 0, 0, -9, 8, +-2, 2, -1, -2, 1, -1, -1, -1, +0, 4, -2, 2, -1, 0, 1, -2, +3, -1, 2, 1, 0, 1, 5, -6, +3, -4, 1, 3, -3, 3, 3, -2, +2, -4, 0, -1, -1, 2, 2, -1, +-1, -1, -3, 1, 2, -3, -3, 3, +-2, 6, -1, -1, -2, 0, -2, 1, +2, 2, -2, 2, 0, -1, 3, -3, +1, 1, 0, 2, 2, -3, 4, -1, +0, -4, 5, -2, 2, 1, 2, -2, +-3, 0, 1, -2, 3, -3, -1, 1, +4, -4, -1, -1, -3, 4, -4, 2, +3, 0, -4, 3, -2, -2, 2, -2, +1, 5, -1, -2, 2, -3, 5, -2, +0, -2, 1, 3, 1, 0, 2, -2, +-3, 0, 3, 0, 1, -1, -1, 0, +-1, -1, -2, 3, -3, 3, -1, -1, +4, -2, -1, -2, 1, -3, 2, 1, +1, 2, -2, -2, 1, 3, -1, 1, +-1, 2, -1, 3, 3, -6, 5, -4, +0, 1, 1, 2, 1, -2, 5, -4, +-2, -2, 0, 3, 0, -1, -1, 0, +0, 1, 1, -3, 0, 0, 0, -1, +6, -5, -2, -2, 2, -2, 6, -4, +3, 1, -2, -2, 3, -2, 0, 2, +0, -3, 4, 1, -1, 2, -1, -2, +-4, 3, 5, 1, -4, 0, -4, 3, +-1, 0, 3, -3, -4, 5, -3, 3, +0, 0, -7, 4, 1, -1, 3, -3, +2, 0, -4, -1, 4, 0, -1, 2, +0, -2, 2, -1, 1, 1, 0, -3, +4, -3, 7, -2, 2, -5, 0, 2, +-4, 2, 5, -2, -2, 0, 3, -3, +4, -2, 0, -2, 1, -2, 5, -3, +3, -3, -4, -2, 5, 2, -3, 2, +-2, 0, -1, 1, 4, -2, -5, 3, +-1, 1, 3, -1, -2, 1, 1, -1, +1, 0, 2, 1, -6, 0, 1, -1, +-1, 4, -3, 2, -1, -1, 2, 1, +1, -4, -2, 0, 0, 4, -3, 2, +-2, 1, -2, 0, 6, -2, -4, 4, +-5, 3, 3, -2, 2, 1, -4, 0, +3, 0, 4, -1, -3, -4, 5, -1, +2, 0, -3, 1, -4, 1, 7, -2, +-3, 1, -2, 0, 3, 0, -3, 2, +-2, -1, 1, 0, 1, 3, -6, 2, +-2, 2, -1, 2, 2, -1, -2, -2, +6, -1, -1, 2, -2, 0, 1, 2, +-2, 2, -3, 2, -2, -2, 7, -3, +1, 0, -2, 3, -7, 4, 3, 1, +-1, -3, 1, -2, 2, 3, -1, -1, +-3, 2, 4, -1, 3, -1, -7, 0, +7, -2, 5, -3, -2, 2, -1, -1, +9, -4, -1, 1, -2, -1, 6, -1, +-1, 1, -3, 0, 2, 1, 2, 3, +-5, -3, 2, 3, -1, 3, 0, -1, +-2, 3, 4, -1, 1, 0, -4, 4, +1, 3, 1, -1, -1, 2, -5, 3, +6, 1, -2, 3, -3, 1, 1, 3, +0, 0, 2, -4, 6, -1, 7, -3, +-2, -3, 2, 2, 4, -1, 2, -1, +-3, 2, 4, -1, 3, -1, 0, 1, +4, 0, 1, 1, -1, -1, 1, 0, +6, 1, 0, -2, 1, -1, 2, 2, +2, 1, -2, 2, 3, 0, 4, -3, +-1, 1, 3, 0, 4, 0, 3, 0, +-5, 2, 3, 1, 2, 4, -4, 4, +-1, 0, 9, -2, 0, 0, -1, 3, +8, 0, 3, -5, 1, -1, 6, 1, +7, 0, -3, 0, 6, -2, 5, 0, +-2, 3, 4, -2, 8, 1, -3, 2, +0, -2, 9, 2, 2, 2, -3, 1, +3, 0, 9, -2, 0, 1, 6, 1, +8, -5, 3, -2, 1, 4, 6, 0, +8, -3, 4, -4, 10, -6, 9, -2, +6, -1, 6, -4, 9, -3, 6, -4, +4, 2, 6, 1, 8, -4, 1, 1, +1, 3, 10, -2, 5, 1, 2, 2, +4, -1, 6, 2, 0, 3, 6, 1, +7, 0, 1, -1, 8, 0, 7, 5, +3, 0, 2, -1, 12, -3, 7, -1, +3, 4, 5, 2, 4, 0, 2, 0, +10, -1, 9, 2, 3, 1, 6, -3, +7, 2, 6, 5, 2, 0, 8, -1, +10, -5, 10, -4, 8, 2, 13, -1, +8, -4, 4, 1, 10, 1, 8, 1, +3, 2, 8, -4, 12, -1, 0, 5, +6, 4, 9, 2, 4, -3, 7, -3, +13, 3, 7, 3, -1, 3, 12, -3, +10, -3, 8, -1, 13, -1, 12, -3, +5, -2, 9, 2, 13, 0, 8, 2, +7, -1, 11, -4, 11, 1, 8, 0, +12, 0, 6, 1, 8, -2, 5, 5, +10, 2, 9, 0, 7, -1, 12, -2, +10, 3, 12, 1, 8, 0, 10, -2, +8, 1, 10, 1, 12, 2, 9, 2, +7, -2, 14, -1, 14, 3, 6, 3, +10, -1, 11, 0, 9, 2, 9, 3, +14, -2, 13, -7, 13, -5, 15, -1, +10, 7, 8, 1, 12, -2, 9, 6, +8, 3, 16, -4, 16, -1, 11, -3, +8, 0, 12, 5, 15, -1, 9, 1, +10, 1, 13, 3, 11, 4, 13, 1, +16, -2, 10, 0, 12, -1, 17, -1, +15, 0, 11, -4, 12, -1, 16, 3, +12, 3, 13, -1, 19, -4, 13, 2, +8, 4, 19, -1, 15, -2, 12, -4, +16, -3, 17, 5, 7, 8, 11, 0, +19, -2, 14, 3, 11, 4, 18, -1, +18, -3, 10, -3, 14, 3, 14, 4, +13, 1, 13, -1, 17, -1, 16, 2, +17, 3, 16, 1, 14, 0, 15, 0, +11, 5, 15, 2, 19, -3, 14, -3, +19, -3, 23, -1, 19, 0, 16, 2, +18, 0, 14, 3, 14, 3, 20, -1, +19, -5, 17, -6, 21, -3, 19, 4, +15, 1, 19, -4, 18, 4, 13, 7, +14, 7, 16, 5, 18, -3, 17, -3, +19, 1, 22, 0, 19, -3, 18, -4, +26, -4, 20, 6, 15, 5, 20, 0, +22, -3, 18, -4, 22, 1, 21, 0, +21, -8, 19, -4, 23, 0, 18, 4, +18, 3, 22, 1, 18, 0, 21, 4, +20, 4, 21, -1, 18, -2, 24, -7, +21, -2, 22, 3, 22, -2, 19, -1, +21, 1, 26, 1, 19, 5, 17, 4, +21, 0, 16, 1, 21, -1, 23, 1, +17, 0, 16, -3, 28, 0, 20, 7, +19, 3, 26, -2, 25, -1, 22, -2, +27, 0, 24, -2, 21, -6, 20, 1, +20, 1, 24, 2, 21, 3, 24, -3, +25, 0, 23, 7, 20, 3, 26, -5, +28, -9, 24, -5, 24, -3, 27, -2, +25, -4, 23, -1, 22, 6, 23, 7, +25, 2, 26, -3, 30, -6, 26, -1, +21, 1, 28, -4, 25, -4, 20, -3, +26, 4, 25, 5, 25, 1, 24, 0, +29, 1, 20, 6, 23, 3, 26, -3, +24, -5, 20, -1, 26, 1, 27, 0, +25, 0, 26, 1, 25, 4, 25, 6, +27, 4, 26, -2, 23, -4, 30, -2, +27, -4, 28, -5, 30, -5, 26, -1, +21, 5, 35, 4, 27, 2, 22, -1, +30, 3, 25, 2, 20, 2, 27, -3, +31, -9, 21, -3, 30, 3, 29, 5, +24, 2, 26, 2, 32, 3, 26, 4, +30, 0, 29, -4, 25, -4, 26, -3, +29, 0, 27, 0, 30, -5, 31, 0, +26, 6, 28, 10, 24, 6, 25, -2, +31, -6, 33, -3, 27, -4, 32, -7, +29, -4, 25, 0, 25, 7, 28, 10, +29, 1, 30, -2, 32, 1, 31, 3, +27, -2, 29, -6, 30, -4, 25, -1, +27, 1, 33, 3, 29, 3, 23, 1, +34, 5, 34, 4, 26, 0, 29, -5, +34, -3, 19, 1, 30, -3, 34, -2, +25, -2, 28, 0, 36, 5, 33, 5, +30, 3, 31, -1, 29, 0, 28, 4, +29, -3, 31, -9, 33, -9, 33, 1, +22, 8, 31, 9, 28, 7, 23, 3, +29, 6, 37, 4, 24, 0, 24, -3, +36, -6, 24, 0, 24, 3, 38, -1, +31, -1, 22, 7, 35, 11, 32, 6, +25, 4, 31, -4, 35, -5, 26, -1, +36, -7, 36, -8, 31, -5, 32, 1, +31, 9, 31, 8, 32, 0, 30, 0, +31, 2, 35, 1, 25, -4, 33, -10, +34, -6, 27, 3, 28, 3, 41, 0, +30, 4, 27, 4, 37, 6, 32, 8, +29, -7, 36, -11, 35, -6, 31, -4, +32, -3, 35, -2, 33, -1, 25, 7, +36, 7, 39, 3, 29, 0, 29, -4, +38, -1, 27, -1, 30, -6, 35, -6, +30, -3, 25, 4, 37, 9, 33, 6, +27, 2, 35, 2, 33, 5, 28, 3, +35, -9, 40, -16, 31, -7, 34, 3, +29, 2, 31, 3, 31, 4, 30, 8, +26, 11, 40, 3, 32, -5, 26, -6, +37, -4, 31, -2, 26, -4, 38, -6, +37, -2, 23, 7, 38, 10, 36, 6, +30, -5, 36, -4, 38, 2, 27, -3, +34, -7, 37, -10, 30, -5, 31, 4, +36, 8, 28, 5, 31, 3, 34, 5, +29, 6, 33, 3, 31, -6, 30, -11, +34, -6, 35, 0, 29, -1, 34, 0, +35, -1, 31, 10, 27, 13, 36, 4, +26, 1, 30, -4, 32, -1, 33, -2, +31, -6, 32, -9, 40, -7, 35, 6, +31, 9, 33, 6, 31, 2, 28, -1, +34, 3, 34, -2, 27, -6, 29, -12, +39, -3, 24, 7, 29, 5, 36, 1, +34, 1, 31, 6, 37, 9, 28, 5, +27, -7, 37, -10, 32, -5, 36, -4, +34, -3, 30, -2, 31, 1, 37, 12, +20, 15, 34, 2, 35, -3, 26, -5, +30, -1, 38, -3, 27, -8, 24, -3, +37, 2, 26, 7, 29, 5, 39, 3, +32, 3, 23, 6, 37, 5, 32, -3, +26, -8, 31, -9, 35, 0, 24, 5, +31, 1, 32, -1, 33, 2, 32, 8, +34, 5, 33, 1, 29, -6, 25, -5, +30, -4, 36, -2, 25, -5, 34, -5, +34, 6, 26, 11, 25, 7, 41, 0, +27, 0, 27, 0, 34, 3, 32, -5, +26, -11, 31, -4, 31, 3, 26, 6, +30, 3, 33, 1, 31, 4, 26, 8, +32, 5, 30, -2, 27, -10, 22, -5, +33, -1, 31, -5, 29, -2, 33, -1, +33, 7, 19, 15, 31, 8, 37, -6, +27, -8, 28, -4, 37, -6, 31, -5, +29, -7, 35, -4, 27, 1, 32, 5, +26, 6, 29, 3, 27, 3, 31, 4, +25, 0, 33, -7, 24, -8, 23, -4, +29, 5, 27, 3, 22, 1, 34, 0, +37, 6, 19, 13, 34, 5, 32, -6, +22, -14, 26, -6, 35, -1, 22, 1, +31, -3, 37, -6, 26, 3, 20, 13, +28, 8, 25, 0, 29, -4, 31, -2, +24, -3, 29, -9, 30, -7, 24, 1, +26, 3, 29, 1, 21, 2, 30, 3, +30, 9, 26, 9, 31, -3, 32, -10, +16, -11, 26, -7, 28, 4, 25, 5, +29, -1, 30, 0, 22, 6, 25, 9, +26, 6, 22, -2, 26, -7, 23, -6, +26, -4, 28, -4, 30, -4, 25, -1, +27, 7, 20, 4, 21, 1, 29, 1, +31, 3, 25, 5, 28, -1, 26, -9, +15, -7, 22, -3, 23, 2, 28, 1, +31, 1, 27, 5, 20, 7, 26, 6, +21, -1, 26, -10, 24, -7, 21, -3, +19, 2, 31, -4, 28, -6, 25, 0, +28, 12, 17, 12, 13, 2, 22, -3, +29, -6, 27, -2, 32, 2, 25, -3, +16, -6, 16, -5, 20, 1, 19, 5, +30, 8, 22, 15, 15, 10, 16, -1, +16, -5, 20, -4, 25, -2, 18, 1, +18, 1, 27, -6, 18, -4, 25, 5, +31, 16, 17, 14, 9, -3, 23, -18, +17, -9, 20, 8, 30, 15, 23, 6, +13, -8, 19, -12, 17, -3, 13, 9, +28, 11, 27, 9, 24, -6, 24, -16, +20, -9, 17, 0, 24, 2, 16, 0, +23, -8, 28, -11, 19, 1, 19, 12, +28, 15, 17, 5, 14, -9, 17, -17, +15, -12, 22, 5, 33, 12, 22, 6, +12, -5, 20, -5, 10, 4, 11, 3, +18, 4, 25, -1, 22, -3, 22, -3, +16, -1, 17, 1, 18, -5, 18, -5, +15, 0, 17, 4, 11, 12, 23, 3, +29, -4, 13, 1, 12, -1, 14, -8, +7, -3, 15, 1, 32, 2, 22, 0, +23, 1, 12, 12, 2, 8, 6, -4, +19, -14, 19, -9, 21, 6, 18, 14, +10, 4, 15, -3, 12, 0, 12, 0, +12, 5, 13, 5, 11, 1, 22, -1, +21, -4, 19, -3, 16, 6, 7, 4, +-5, -4, 8, -5, 25, 2, 22, 13, +21, 14, 16, 5, -1, -2, 2, -10, +12, -14, 14, -6, 26, 5, 27, 7, +13, -1, 9, -3, 13, 4, 9, 9, +16, 2, 15, -9, 8, -11, 12, -2, +18, 5, 17, 5, 21, 5, 15, -3, +3, -14, 4, -10, 10, 9, 17, 18, +28, 10, 23, -1, 4, -10, 0, -8, +-4, -6, 7, -7, 22, 0, 30, 6, +20, 6, 8, 9, -1, 10, -3, 10, +14, -6, 20, -20, 15, -16, 13, 0, +12, 6, 8, 3, 16, 3, 15, 3, +8, 3, -3, 1, 0, -3, 10, -1, +27, 1, 28, 3, 14, 3, 1, 0, +-12, -10, 0, -25, 19, -16, 24, 14, +22, 30, 17, 19, -1, -3, -2, -13, +7, -8, 6, -8, 10, -4, 16, 5, +9, -1, 8, -10, 21, -5, 13, 14, +0, 23, 2, 8, -2, -18, 6, -24, +26, -6, 27, 13, 12, 13, 5, 4, +-11, -9, -8, -26, 11, -18, 16, 10, +21, 33, 20, 25, 7, -1, -3, -15, +4, -10, -3, -6, 3, -8, 15, -6, +13, 2, 8, 4, 18, 1, 9, 9, +-4, 16, 3, 6, 2, -19, 6, -22, +15, -4, 18, 13, 10, 7, 13, -5, +2, -4, -8, -5, -4, -11, 5, -7, +19, 10, 25, 21, 19, 15, 1, 2, +-8, -8, -16, -15, 1, -23, 17, -15, +17, 8, 15, 22, 9, 11, -3, -3, +-1, -1, 10, 6, 4, -2, 8, -18, +7, -12, 1, -1, 14, 2, 21, 5, +8, 10, -8, 9, -17, -9, -16, -24, +13, -8, 33, 25, 29, 32, 9, 12, +-15, -14, -27, -27, -5, -26, 23, -12, +22, 8, 22, 19, 1, 17, -17, 1, +-7, -1, 9, 12, 7, 7, 2, -11, +-5, -21, -7, -10, 15, 8, 25, 15, +17, 7, -1, 1, -14, -11, -25, -20, +1, -10, 30, 17, 29, 33, 15, 15, +-7, -11, -28, -19, -14, -18, 17, -17, +16, -6, 12, 13, 6, 23, -5, 17, +-3, 0, 12, -7, 2, -2, -7, -9, +-6, -14, 0, -4, 18, 11, 20, 10, +10, -3, -4, -2, -20, 7, -20, -2, +7, -19, 26, -12, 17, 20, 8, 29, +-6, 12, -15, -10, -1, -22, 7, -26, +2, -22, 2, 5, 4, 35, 4, 34, +11, 5, 7, -19, -6, -13, -19, 3, +-13, 1, 4, -6, 27, -3, 21, 4, +5, 3, -10, 6, -24, 12, -13, 0, +11, -24, 13, -18, 6, 15, 14, 38, +-3, 24, -6, -14, 4, -32, -1, -27, +-10, -11, 0, 5, 11, 17, 12, 22, +21, 4, 5, -12, -15, -4, -17, 9, +-4, -2, 4, -20, 19, -16, 12, 10, +-3, 24, -4, 12, -8, -2, -4, -14, +2, -21, -1, -14, -2, 16, 12, 39, +13, 23, 12, -17, 3, -33, -20, -17, +-29, 1, -6, 1, 18, 1, 27, 14, +25, 19, -9, 10, -30, -6, -15, -7, +5, -7, 20, -17, 22, -13, 5, 5, +-14, 17, -9, 6, 4, -9, 10, -2, +4, 3, -12, -3, -19, -4, -2, 9, +22, 19, 29, 15, 11, -3, -24, -18, +-32, -27, -15, -30, 14, -11, 34, 32, +30, 56, -6, 26, -24, -27, -21, -42, +-5, -17, 19, 12, 22, 17, 5, 4, +-7, -9, -4, -15, -5, -11, 7, 12, +4, 30, -8, 10, -11, -22, 6, -27, +8, 14, 11, 37, 13, 20, -13, -11, +-17, -35, -13, -34, -2, -15, 12, 24, +20, 55, 5, 41, -1, -10, -6, -39, +-17, -23, -5, 2, 3, 7, 9, -2, +17, 1, 17, 7, -8, 2, -15, -8, +-14, 1, -13, 9, 8, 5, 23, 2, +8, 10, -4, 8, -5, -7, -12, -19, +-1, -12, 10, 3, 6, -2, -2, -10, +-5, 5, 2, 26, 11, 30, 8, 15, +-4, -12, -12, -27, -21, -32, -6, -18, +19, 18, 28, 45, 10, 30, -9, -21, +-22, -46, -23, -15, 5, 26, 21, 35, +20, 15, 10, -10, -7, -24, -20, -27, +-4, -8, 7, 19, 6, 15, 4, -10, +-1, -15, -7, 19, -3, 38, 8, 20, +3, -13, 0, -30, -12, -24, -10, -11, +6, 7, 9, 28, 12, 23, 8, -3, +-9, -21, -23, -3, -11, 20, -2, 12, +8, -6, 16, -1, 6, 13, -13, 13, +-16, -4, -12, -19, -9, -18, 12, -6, +15, 15, 6, 37, -2, 37, -5, -1, +-7, -39, -6, -31, -5, 6, -2, 26, +4, 13, 2, -7, 2, -7, -2, 3, +-9, 12, -11, 20, -3, 20, -5, -3, +2, -32, 12, -20, 0, 24, -6, 44, +-8, 18, -8, -31, -9, -40, 1, -12, +1, 21, -2, 44, 3, 44, -2, 13, +-4, -30, -10, -35, -16, -6, -16, 23, +0, 21, 9, 0, 17, -7, 6, 6, +-19, 11, -27, 6, -17, 9, 2, 8, +19, -3, 19, -12, -7, 0, -22, 18, +-23, 15, -6, -9, 12, -12, 10, 5, +-11, 10, -26, 12, -15, 15, 4, 22, +21, 14, 13, -10, -19, -20, -38, -14, +-24, 2, 0, 11, 31, 15, 31, 23, +-9, 15, -44, -7, -44, -11, -13, 6, +21, 20, 30, 14, 3, 1, -27, 4, +-37, 4, -17, -9, 9, -10, 19, 6, +-2, 24, -19, 16, -20, 4, -17, 7, +9, 8, 14, 0, -8, -5, -22, 3, +-23, 7, -19, -5, 6, -13, 18, 9, +0, 35, -13, 33, -24, 4, -27, -19, +-17, -15, 8, -5, 12, 14, 1, 35, +-13, 30, -21, -9, -25, -36, -21, -23, +-2, 22, 1, 53, 2, 35, -8, 7, +-17, -11, -28, -17, -21, -13, 1, 7, +7, 33, -9, 31, -25, -8, -23, -33, +-21, -5, 2, 39, 10, 53, -16, 29, +-36, -11, -36, -35, -28, -28, 6, 15, +22, 66, 0, 58, -32, -6, -52, -62, +-40, -42, -9, 25, 18, 74, 16, 67, +-9, 16, -49, -37, -53, -57, -26, -20, +5, 46, 20, 79, 1, 33, -43, -37, +-59, -55, -21, 1, 8, 69, 12, 72, +-9, 18, -50, -44, -59, -65, -15, -18, +28, 61, 21, 96, -21, 36, -63, -61, +-64, -81, -23, -5, 22, 82, 22, 97, +-20, 35, -57, -39, -60, -66, -22, -30, +5, 52, 0, 91, -15, 33, -35, -53, +-42, -71, -14, 6, -1, 94, -17, 91, +-30, 9, -54, -71, -38, -76, -3, 5, +10, 90, -8, 108, -40, 28, -68, -84, +-54, -93, -14, 11, 15, 120, 3, 117, +-40, 4, -68, -86, -52, -75, -8, 18, +11, 103, -15, 95, -60, 0, -70, -91, +-35, -80, 16, 46, 19, 148, -29, 105, +-84, -36, -89, -126, -30, -71, 31, 63, +31, 138, -24, 89, -88, -33, -97, -109, +-41, -60, 16, 64, 22, 140, -24, 81, +-72, -52, -82, -99, -39, -23, 12, 84, +3, 106, -52, 32, -78, -51, -68, -70, +-18, -11, 21, 78, -2, 104, -60, 49, +-89, -45, -67, -86, -10, -17, 17, 67, +-12, 86, -57, 38, -80, -28, -53, -42, +-13, -9, -14, 43, -50, 80, -68, 50, +-63, -14, -26, -40, -6, 0, -23, 60, +-66, 58, -86, 3, -55, -30, -16, -16, +-2, 29, -25, 62, -76, 54, -98, 18, +-55, -19, -12, -20, -5, 26, -36, 51, +-78, 30, -90, -10, -52, -14, 0, 31, +6, 57, -55, 33, -109, -8, -101, -23, +-44, 10, 16, 46, 20, 60, -56, 47, +-127, -10, -112, -47, -46, -14, 11, 46, +11, 84, -53, 47, -112, -16, -97, -22, +-43, 6, -5, 42, -18, 50, -64, 18, +-95, -8, -73, -23, -35, 7, -12, 64, +-33, 69, -82, 20, -99, -33, -80, -29, +-36, 32, -10, 68, -30, 57, -70, 17, +-96, -23, -86, -19, -42, 15, -31, 50, +-43, 58, -66, 15, -88, -13, -68, 8, +-33, 47, -49, 63, -74, 15, -90, -27, +-80, -9, -40, 30, -24, 56, -41, 49, +-84, 23, -109, -3, -80, -11, -44, 18, +-34, 46, -54, 41, -76, 19, -77, 15, +-68, 27, -57, 25, -67, -3, -80, -7, +-72, 30, -55, 61, -49, 50, -61, 4, +-74, -20, -77, 15, -80, 52, -80, 55, +-69, 19, -65, -24, -53, -16, -39, 35, +-57, 80, -99, 65, -111, -14, -85, -49, +-49, 4, -32, 68, -45, 78, -82, 21, +-109, -16, -93, 6, -68, 29, -64, 31, +-54, 10, -55, 8, -80, 41, -82, 53, +-92, 42, -91, 8, -62, -21, -52, 8, +-61, 44, -83, 50, -106, 18, -75, -17, +-44, 14, -55, 67, -85, 56, -118, 1, +-111, -34, -60, 9, -29, 75, -48, 70, +-94, 14, -124, -22, -104, -3, -69, 46, +-51, 53, -56, 17, -81, -10, -95, 8, +-79, 59, -80, 71, -85, 17, -86, -32, +-80, -21, -75, 52, -76, 85, -75, 28, +-80, -25, -86, -9, -85, 56, -87, 79, +-89, 14, -77, -38, -68, -14, -76, 65, +-98, 109, -98, 46, -85, -41, -75, -47, +-77, 19, -98, 98, -107, 82, -83, 1, +-58, -34, -50, 8, -94, 78, -137, 62, +-117, -14, -66, -46, -30, 8, -44, 92, +-111, 95, -154, 8, -115, -48, -59, -17, +-35, 58, -65, 96, -111, 39, -125, -30, +-104, -33, -62, 27, -49, 90, -86, 73, +-108, 2, -106, -42, -108, -14, -85, 54, +-64, 90, -69, 65, -77, 17, -103, -27, +-122, -31, -113, 13, -89, 65, -53, 94, +-58, 56, -92, -22, -111, -47, -118, 5, +-108, 89, -81, 107, -64, 17, -67, -66, +-85, -56, -98, 50, -106, 143, -107, 95, +-80, -43, -63, -117, -80, -37, -112, 131, +-111, 179, -86, 62, -64, -92, -71, -120, +-110, 21, -149, 158, -116, 142, -49, 5, +-33, -112, -76, -63, -129, 79, -147, 153, +-93, 92, -46, -40, -63, -103, -120, -21, +-135, 92, -77, 140, -41, 75, -67, -40, +-135, -66, -171, -15, -105, 63, -5, 101, +-7, 63, -98, 11, -183, -29, -177, -19, +-65, 29, 12, 59, -36, 61, -129, 30, +-183, -11, -128, -8, -30, 26, -20, 64, +-87, 75, -153, 29, -155, -20, -95, -35, +-42, 8, -42, 92, -75, 105, -120, 35, +-130, -44, -120, -65, -103, 19, -63, 106, +-35, 108, -52, 33, -109, -58, -160, -59, +-147, 29, -77, 107, -18, 107, -29, 7, +-108, -76, -162, -38, -134, 60, -68, 132, +-35, 92, -63, -26, -114, -83, -137, -41, +-112, 65, -62, 146, -49, 101, -72, -15, +-111, -92, -126, -63, -111, 66, -78, 137, +-46, 94, -47, -11, -98, -80, -143, -27, +-138, 72, -97, 116, -32, 82, -22, -27, +-97, -82, -157, -16, -132, 92, -71, 143, +-24, 60, -59, -60, -131, -81, -156, -2, +-92, 106, -13, 131, -26, 42, -120, -47, +-169, -76, -125, 3, -35, 118, 8, 121, +-76, 23, -171, -79, -172, -59, -71, 68, +19, 134, -15, 85, -133, -25, -196, -91, +-146, -26, -23, 89, 32, 142, -44, 81, +-159, -51, -191, -96, -116, -4, -20, 109, +12, 125, -51, 27, -146, -58, -170, -34, +-105, 40, -29, 86, -7, 57, -56, -7, +-132, -17, -161, 5, -105, 46, -23, 69, +0, 28, -65, -5, -138, -1, -162, 25, +-97, 37, -7, 14, 4, 11, -71, 44, +-146, 45, -150, 11, -80, -21, -9, 2, +-26, 68, -94, 67, -142, 14, -113, -20, +-48, -8, -23, 50, -63, 74, -115, 31, +-122, -24, -75, -39, -39, 35, -48, 114, +-84, 82, -113, -31, -90, -91, -57, 0, +-66, 131, -87, 111, -81, -24, -67, -96, +-55, -6, -71, 131, -91, 117, -103, -16, +-82, -109, -38, -52, -42, 122, -79, 181, +-100, 43, -93, -136, -65, -139, -47, 75, +-63, 239, -96, 126, -95, -120, -55, -198, +-36, 7, -59, 233, -94, 184, -110, -61, +-83, -205, -34, -75, -21, 167, -56, 220, +-112, 43, -118, -149, -71, -131, -26, 77, +-28, 203, -72, 82, -120, -105, -99, -125, +-28, 58, -12, 190, -61, 74, -120, -111, +-116, -119, -57, 60, -1, 190, -11, 86, +-89, -94, -149, -122, -99, 26, -26, 166, +-2, 113, -33, -57, -99, -129, -125, -15, +-77, 155, -26, 157, -27, -24, -62, -143, +-91, -50, -91, 136, -73, 161, -35, -16, +-21, -128, -54, -29, -90, 128, -90, 121, +-75, -33, -42, -112, -18, -13, -30, 129, +-76, 133, -117, -16, -99, -131, -40, -53, +3, 126, -12, 176, -81, 14, -126, -163, +-94, -99, -29, 133, 5, 221, -29, 42, +-92, -177, -120, -138, -85, 97, -15, 218, +14, 95, -43, -112, -108, -150, -117, 12, +-61, 166, 4, 131, -1, -42, -62, -136, +-113, -23, -93, 137, -34, 126, -8, -42, +-28, -129, -57, -4, -86, 147, -77, 106, +-45, -59, -30, -112, -30, 16, -54, 138, +-82, 88, -66, -61, -39, -107, -27, 10, +-41, 137, -70, 107, -81, -39, -52, -116, +-10, -30, -21, 116, -70, 128, -91, -15, +-60, -120, -23, -43, -5, 120, -45, 139, +-90, -21, -76, -134, -35, -45, -14, 130, +-30, 144, -59, -19, -67, -139, -57, -60, +-36, 111, -28, 148, -43, 17, -55, -118, +-55, -84, -55, 81, -52, 171, -46, 63, +-35, -128, -29, -131, -49, 59, -68, 188, +-74, 83, -34, -116, 11, -135, -15, 29, +-83, 166, -104, 102, -57, -62, 2, -120, +16, -27, -40, 110, -99, 114, -95, -1, +-28, -87, 18, -46, -18, 62, -77, 94, +-94, 28, -55, -52, 10, -28, 8, 48, +-60, 57, -115, -7, -65, -53, 19, 6, +14, 84, -51, 65, -103, -30, -95, -72, +-17, -5, 42, 77, -3, 84, -94, 10, +-117, -64, -56, -60, 24, 25, 28, 101, +-36, 64, -98, -39, -93, -86, -23, -16, +21, 65, 3, 71, -50, 23, -77, -24, +-70, -37, -47, -34, -6, 12, 11, 83, +-22, 91, -79, -2, -100, -109, -53, -74, +14, 84, 21, 160, -36, 43, -78, -124, +-78, -124, -47, 34, -3, 162, 10, 111, +-25, -57, -93, -151, -82, -69, 0, 116, +25, 180, -39, 36, -86, -159, -45, -149, +-7, 72, -17, 198, -51, 78, -58, -114, +-33, -135, -5, 15, -19, 123, -53, 88, +-55, -19, -39, -78, -19, -51, -10, 25, +-39, 87, -50, 48, -29, -35, -13, -54, +-30, -2, -64, 41, -61, 6, 2, -6, +40, 43, -19, 52, -113, -34, -122, -110, +-18, -15, 78, 136, 65, 135, -66, -41, +-173, -181, -117, -90, 36, 107, 132, 199, +46, 78, -134, -135, -195, -212, -72, -56, +102, 204, 122, 251, -30, 7, -173, -269, +-147, -225, 4, 108, 100, 295, 63, 140, +-67, -158, -143, -238, -100, -58, 16, 154, +73, 207, 0, 55, -90, -138, -88, -193, +-10, -22, 19, 179, -38, 157, -61, -28, +-12, -143, 16, -66, -36, 35, -79, 52, +-44, 53, 9, 54, 3, 3, -30, -107, +-40, -100, -58, 49, -58, 165, -6, 101, +47, -97, -14, -168, -103, -50, -63, 116, +14, 153, 34, 20, -17, -120, -69, -130, +-61, 1, -15, 137, 12, 123, -8, -36, +-39, -157, -48, -66, -43, 129, -36, 143, +-9, -62, 37, -176, 13, -8, -71, 187, +-131, 102, -57, -147, 87, -208, 118, 26, +-29, 248, -189, 164, -145, -131, 33, -290, +128, -95, 75, 236, -63, 304, -175, 5, +-148, -309, 27, -254, 163, 84, 104, 323, +-100, 210, -216, -132, -120, -338, 68, -188, +164, 204, 53, 403, -124, 119, -175, -339, +-79, -382, 55, 71, 103, 417, 51, 211, +-76, -237, -147, -315, -87, 10, 35, 230, +84, 112, 45, -82, -45, -89, -125, -3, +-91, 4, 22, -15, 85, 28, 42, 62, +-62, 3, -98, -71, -70, -32, 10, 26, +52, 12, 34, -8, -26, 48, -104, 83, +-85, -57, 16, -193, 87, -56, 30, 217, +-95, 233, -116, -96, -2, -316, 82, -115, +26, 227, -60, 279, -98, -19, -40, -272, +43, -189, 61, 109, 10, 259, -75, 77, +-104, -182, -41, -196, 65, 47, 95, 194, +-16, 63, -113, -123, -93, -120, 5, 36, +61, 100, 56, 32, 2, -54, -73, -79, +-116, -19, -58, 57, 90, 96, 125, 25, +2, -115, -138, -134, -152, 19, -8, 188, +121, 126, 118, -120, -21, -222, -154, -36, +-145, 204, -1, 165, 143, -89, 127, -195, +-21, -45, -177, 130, -174, 87, 26, -46, +229, -76, 146, 0, -168, 61, -266, 12, +-55, -60, 197, -64, 187, 43, -25, 126, +-181, 23, -172, -134, -6, -146, 172, 53, +174, 195, -48, 84, -240, -108, -145, -184, +104, -46, 204, 123, 48, 159, -127, 43, +-152, -150, -37, -181, 83, -25, 127, 185, +71, 186, -118, -48, -204, -219, -30, -151, +177, 119, 149, 222, -56, 55, -161, -161, +-91, -172, 49, 28, 115, 123, 51, 104, +-59, -20, -95, -116, -26, -84, 45, 17, +56, 124, 3, 48, -30, -79, -9, -92, +-14, 20, -28, 85, -11, -15, 63, -62, +55, 2, -63, 89, -92, 35, 12, -117, +70, -120, 18, 37, -11, 200, -3, 103, +-14, -146, -48, -233, -20, -50, 69, 204, +67, 220, -22, 27, -98, -213, -55, -264, +60, -40, 105, 280, 44, 341, -77, -33, +-106, -418, -24, -328, 86, 157, 134, 453, +48, 229, -105, -232, -165, -435, -26, -181, +150, 256, 182, 438, 7, 121, -186, -339, +-137, -394, 65, -10, 164, 351, 70, 258, +-36, -79, -67, -257, -74, -148, -32, 58, +68, 144, 156, 110, 68, -5, -126, -99, +-178, -111, -6, -22, 189, 77, 154, 71, +-41, 19, -152, -35, -42, -42, 75, -54, +40, -39, -2, 57, 42, 102, 73, 43, +-37, -95, -132, -117, -34, -3, 138, 71, +154, 56, -16, 5, -121, -3, -66, -45, +43, -101, 86, -38, 61, 118, 15, 158, +-20, -40, -40, -214, -44, -115, 22, 147, +104, 201, 104, -43, 4, -205, -121, -62, +-95, 153, 56, 102, 153, -117, 83, -125, +-42, 67, -75, 137, -22, -12, 43, -147, +44, -73, 41, 62, 57, 92, 33, 32, +-37, -55, -73, -86, -7, -55, 81, 32, +125, 103, 49, 53, -77, -56, -107, -109, +-12, -46, 122, 57, 141, 90, 31, 29, +-99, -79, -97, -92, 34, -3, 130, 76, +94, 49, -27, -47, -56, -65, 1, -6, +56, 65, 30, 36, -15, -80, 4, -112, +72, 7, 106, 192, -4, 121, -124, -183, +-74, -309, 101, -26, 213, 370, 112, 298, +-120, -181, -232, -466, -43, -188, 251, 321, +275, 426, -9, 45, -246, -385, -154, -374, +104, 43, 233, 378, 155, 281, -33, -122, +-159, -348, -120, -205, 78, 103, 206, 276, +133, 163, -52, -78, -134, -268, -23, -195, +111, 82, 104, 251, 4, 164, -18, -122, +29, -261, 52, -122, 39, 121, -31, 237, +-49, 55, 49, -182, 165, -208, 106, 27, +-99, 227, -178, 89, 0, -165, 238, -195, +217, 67, -44, 213, -226, 25, -112, -207, +183, -165, 264, 145, 46, 219, -163, -36, +-102, -249, 89, -109, 151, 191, 53, 150, +-45, -103, -18, -183, 63, 18, 80, 154, +7, 1, -42, -148, 9, -82, 86, 112, +115, 124, 22, -59, -66, -171, -40, -60, +74, 134, 123, 99, 52, -95, -14, -149, +-3, 33, 28, 146, 4, -25, 13, -177, +96, -63, 125, 161, 27, 133, -123, -106, +-95, -205, 112, -52, 246, 145, 106, 142, +-141, -25, -164, -162, 42, -114, 217, 44, +139, 110, -59, 26, -83, -67, 55, -33, +114, 3, 4, -47, -50, -105, 48, 2, +159, 179, 96, 120, -92, -137, -124, -303, +38, -93, 198, 244, 163, 276, -17, -21, +-129, -304, -77, -222, 93, 55, 174, 227, +112, 150, -11, -59, -60, -198, -29, -190, +4, 20, 73, 177, 173, 134, 161, -51, +-51, -176, -205, -102, -78, -14, 196, 55, +311, 82, 98, 64, -206, -23, -231, -173, +74, -149, 308, 47, 176, 216, -111, 117, +-176, -161, 41, -245, 196, -43, 107, 184, +-49, 116, -43, -110, 90, -162, 107, 0, +-4, 132, -58, 18, 49, -154, 138, -130, +79, 76, -20, 202, -52, 29, 37, -247, +114, -245, 78, 71, -4, 304, -17, 120, +69, -226, 95, -277, 33, -28, -41, 180, +-27, 121, 94, -24, 184, -96, 87, -109, +-130, -75, -139, -2, 96, 117, 265, 106, +115, -51, -120, -180, -103, -139, 71, 54, +154, 151, 75, 68, -7, -122, 30, -200, +92, -45, 14, 127, -86, 131, 18, -79, +206, -194, 186, -48, -58, 126, -198, 105, +-37, -123, 232, -179, 263, 6, 15, 141, +-190, 54, -107, -153, 154, -133, 253, 45, +64, 128, -142, -21, -89, -182, 138, -57, +210, 150, 40, 128, -125, -152, -64, -287, +147, -40, 210, 254, 59, 225, -112, -128, +-81, -363, 97, -205, 197, 152, 109, 355, +-54, 127, -62, -282, 28, -403, 83, -75, +86, 328, 82, 284, 77, -95, -12, -332, +-89, -180, -21, 104, 173, 152, 221, 36, +37, -69, -142, -72, -115, -47, 129, -70, +238, -46, 83, 19, -109, 90, -65, 54, +143, -78, 154, -159, -25, -128, -108, 20, +71, 138, 228, 134, 106, -22, -115, -228, +-154, -236, 86, -22, 278, 238, 172, 238, +-94, -66, -196, -321, 14, -280, 223, 43, +208, 297, 31, 215, -111, -104, -69, -352, +75, -254, 176, 77, 103, 299, -17, 199, +-30, -138, 41, -343, 86, -211, 35, 112, +32, 281, 64, 113, 65, -163, 31, -262, +-9, -114, 25, 78, 97, 127, 117, 82, +24, -44, -50, -161, 0, -189, 108, -61, +156, 157, 62, 188, -62, -5, -38, -252, +99, -254, 137, 8, 26, 208, -25, 179, +73, -63, 106, -230, -5, -199, -63, -40, +59, 158, 220, 187, 132, 47, -123, -221, +-184, -327, 104, -92, 343, 242, 163, 323, +-164, -34, -202, -369, 76, -298, 264, 51, +166, 282, -19, 136, -81, -89, 12, -211, +80, -181, 57, -51, 56, 91, 99, 198, +115, 59, 13, -180, -92, -265, -39, -105, +138, 123, 231, 158, 100, 69, -77, -82, +-132, -205, 6, -196, 189, -32, 190, 196, +61, 195, -33, -41, -26, -257, -10, -252, +14, -42, 108, 154, 217, 232, 188, 98, +-62, -214, -268, -416, -124, -230, 280, 270, +441, 501, 142, 113, -266, -477, -301, -576, +43, -17, 346, 514, 298, 400, 18, -182, +-134, -544, -117, -277, -18, 206, 117, 352, +241, 68, 247, -251, -2, -229, -253, -27, +-198, 90, 174, 18, 435, -52, 231, 12, +-179, 22, -295, -100, 19, -209, 283, -55, +206, 198, 11, 155, -53, -144, 29, -296, +43, -63, 15, 180, 62, 90, 113, -126, +102, -141, 15, 24, -3, 46, 13, -71, +32, -100, 88, -7, 106, 66, 87, -8, +-9, -100, -14, -97, 68, -20, 80, 58, +36, 14, 22, -86, 131, -121, 137, -27, +-20, 85, -139, 31, -15, -116, 234, -166, +259, -29, 59, 138, -126, 82, -126, -124, +0, -237, 164, -90, 290, 132, 203, 151, +-81, -13, -257, -198, -134, -206, 184, -41, +395, 149, 270, 185, -87, -34, -343, -260, +-197, -237, 235, 22, 483, 210, 253, 114, +-185, -86, -334, -208, -90, -159, 243, -5, +345, 118, 193, 128, -43, -30, -194, -188, +-153, -199, 73, -42, 294, 141, 304, 143, +64, -21, -190, -208, -217, -209, 4, -22, +301, 137, 345, 139, 79, -31, -214, -197, +-197, -216, 77, -44, 281, 171, 250, 151, +0, -61, -149, -232, -59, -170, 109, 16, +154, 124, 103, 118, 75, -37, 7, -210, +-50, -225, 17, -9, 119, 232, 119, 151, +67, -140, 29, -311, 17, -170, 17, 128, +57, 243, 88, 89, 73, -228, 38, -345, +4, -93, 78, 246, 131, 262, 63, -96, +-56, -344, -53, -211, 126, 107, 218, 218, +115, 41, -63, -148, -112, -186, 7, -74, +143, 30, 224, 50, 147, 29, -42, -20, +-160, -74, -81, -143, 168, -132, 301, 18, +204, 170, -60, 129, -252, -137, -126, -331, +148, -180, 377, 184, 303, 326, -53, 36, +-346, -345, -260, -349, 214, 30, 495, 318, +326, 173, -141, -177, -419, -298, -185, -110, +286, 93, 533, 100, 189, 15, -272, -42, +-299, -80, 30, -127, 281, -119, 225, 1, +113, 139, 13, 137, -117, -71, -184, -311, +13, -263, 364, 110, 373, 392, -17, 151, +-351, -368, -227, -477, 237, -22, 450, 414, +182, 286, -216, -192, -252, -420, 79, -194, +287, 170, 182, 252, -34, 32, -90, -199, +21, -199, 109, -29, 107, 45, 32, 12, +14, 1, 71, 40, 84, -21, 5, -183, +-44, -188, 69, 24, 186, 227, 101, 134, +-81, -169, -101, -326, 111, -155, 253, 175, +79, 273, -143, 33, -104, -265, 144, -287, +261, -31, 117, 170, -105, 147, -169, -2, +52, -142, 229, -205, 170, -151, 3, 66, +-43, 241, 13, 114, -4, -214, 15, -343, +120, -76, 210, 221, 121, 212, -125, -48, +-225, -264, 8, -224, 376, -14, 363, 210, +-81, 180, -376, -117, -152, -314, 279, -150, +399, 174, 146, 187, -152, -64, -260, -188, +-65, -96, 236, 7, 316, -2, 121, 32, +-117, 54, -161, -50, -59, -162, 125, -122, +260, 55, 186, 113, -41, 31, -183, -92, +-88, -167, 115, -120, 248, 19, 201, 160, +-12, 103, -192, -106, -143, -255, 114, -170, +329, 106, 199, 239, -122, 72, -211, -225, +9, -279, 199, -19, 155, 172, 51, 105, +-47, -61, -48, -116, 50, -97, 131, -75, +79, 18, -52, 95, 0, 26, 107, -109, +99, -112, 4, -25, -23, -24, 60, -24, +76, 67, 33, 70, -13, -117, 35, -225, +122, -9, 78, 197, -58, 39, -93, -207, +112, -134, 249, 128, 53, 105, -196, -148, +-126, -188, 198, 34, 293, 164, 47, 6, +-176, -161, -124, -142, 130, -29, 210, 87, +66, 110, -92, 7, -38, -180, 131, -206, +104, 27, -44, 190, -80, 58, 104, -158, +197, -114, 25, 37, -125, -28, -53, -126, +146, 9, 168, 211, 29, 48, -69, -305, +-34, -265, 41, 120, 70, 292, 106, 40, +108, -206, -4, -162, -141, -54, -57, -1, +163, 92, 202, 159, 43, -19, -53, -300, +-39, -213, -48, 134, -5, 244, 174, 5, +257, -166, 4, -81, -276, -67, -138, -121, +249, 14, 311, 277, -16, 191, -221, -290, +-49, -471, 156, -56, 109, 421, -1, 330, +16, -166, 52, -406, 9, -200, -15, 132, +-9, 213, 43, 73, 132, -43, 121, -129, +-41, -195, -150, -144, -16, 125, 166, 314, +166, 74, 21, -303, -88, -324, -105, 29, +1, 248, 187, 131, 208, -40, -11, -144, +-228, -193, -106, -134, 214, 118, 272, 294, +-15, 69, -206, -284, -20, -337, 168, 8, +63, 329, -88, 231, 16, -160, 160, -404, +53, -120, -109, 283, -49, 223, 132, -171, +123, -244, -34, 77, -93, 115, 33, -170, +147, -126, 67, 267, -74, 207, -72, -373, +61, -444, 126, 258, 50, 573, -24, -78, +-18, -652, 13, -190, 37, 515, 41, 300, +43, -370, 42, -371, 12, 239, -58, 311, +-36, -246, 100, -374, 139, 198, 28, 497, +-88, -120, -67, -633, 1, -171, 85, 545, +160, 387, 105, -350, -85, -450, -215, 65, +-26, 272, 234, -26, 225, -150, -60, 115, +-190, 112, -12, -228, 118, -301, 56, 109, +-18, 394, 79, 112, 87, -303, -85, -349, +-176, -3, 3, 290, 270, 232, 239, -81, +-74, -285, -311, -147, -157, 85, 196, 88, +339, -9, 156, 68, -163, 121, -297, -152, +-120, -437, 228, -95, 354, 526, 72, 474, +-262, -326, -232, -766, 100, -155, 263, 630, +106, 537, -105, -257, -142, -620, 7, -166, +94, 365, 72, 304, 18, -98, 2, -203, +3, -21, -59, 22, -40, -103, 90, -40, +179, 192, -1, 159, -205, -196, -44, -313, +248, 16, 162, 325, -229, 148, -208, -250, +188, -296, 276, 22, -58, 311, -180, 166, +46, -196, 85, -296, -78, -39, -56, 233, +190, 106, 168, -92, -130, -53, -198, 52, +26, -69, 156, -252, 56, 31, -10, 379, +36, 204, -2, -361, -123, -465, -34, 103, +156, 447, 117, 190, -74, -256, -68, -234, +42, -27, -10, -8, -45, 25, 86, 221, +162, 279, -16, -202, -176, -571, -88, -216, +91, 498, 160, 565, 120, -94, -15, -545, +-211, -311, -193, 179, 95, 311, 347, 156, +159, -60, -234, -175, -258, -193, 57, -67, +172, 137, 21, 205, 48, 113, 133, -140, +-77, -277, -312, -143, -45, 181, 361, 312, +220, 43, -213, -224, -232, -250, 110, -1, +156, 193, -97, 191, -126, -12, 166, -267, +230, -140, -124, 165, -310, 246, 12, -104, +329, -270, 124, 48, -242, 224, -167, -26, +161, -264, 208, 42, -60, 298, -227, 44, +-39, -329, 209, -220, 183, 203, -107, 306, +-229, 62, 2, -255, 185, -289, 82, -9, +-65, 352, -29, 310, -31, -200, -83, -509, +-18, -123, 184, 478, 207, 399, -88, -205, +-318, -459, -173, -69, 239, 256, 336, 73, +27, -89, -254, 118, -168, 249, 52, -186, +67, -569, 61, -112, 101, 619, 65, 545, +-141, -336, -186, -698, 36, -91, 213, 506, +84, 316, -133, -254, -49, -263, 52, 56, +-24, 149, -121, -53, 91, -90, 294, 150, +22, 132, -367, -146, -313, -305, 213, 14, +462, 347, 160, 205, -312, -131, -409, -248, +-20, -72, 293, -15, 215, 25, -50, 227, +-100, 281, -8, -81, -54, -512, -151, -242, +-41, 363, 269, 451, 271, -47, -116, -376, +-402, -113, -163, 129, 331, 108, 305, -4, +-141, 51, -328, 23, 17, -170, 287, -154, +23, 107, -239, 328, -73, 55, 256, -284, +104, -271, -247, 107, -182, 314, 157, 53, +270, -179, -19, -122, -218, 144, -133, 55, +90, -166, 124, -92, -2, 177, -43, 244, +22, -112, 79, -252, -86, -80, -190, 163, +-49, 165, 199, -7, 254, -53, 7, -123, +-274, -37, -302, 41, 66, 113, 361, 66, +155, -70, -237, -23, -209, -51, 136, -2, +113, -5, -209, 78, -114, 89, 293, -44, +263, -55, -255, -70, -432, 56, 30, 32, +394, 10, 206, -13, -199, 8, -235, 93, +-54, -57, 57, -151, 105, -71, 133, 253, +64, 248, -169, -206, -230, -407, -72, -19, +194, 518, 265, 271, 57, -355, -196, -480, +-324, 71, -86, 494, 208, 164, 337, -280, +110, -249, -318, 175, -394, 198, 9, -172, +451, -211, 209, 183, -292, 389, -293, -122, +128, -471, 251, -98, -109, 473, -197, 310, +75, -349, 206, -411, -49, 98, -238, 482, +-22, 139, 165, -334, 102, -335, -149, 100, +-107, 408, 86, 122, 58, -281, -67, -286, +-107, 147, 110, 314, 121, 0, -55, -244, +-184, -98, -104, 156, 123, 92, 153, -48, +115, -8, -122, 33, -250, -49, -136, -89, +154, 48, 320, 119, 36, 1, -226, -70, +-247, -1, 36, 46, 163, -54, 97, -75, +-10, 91, -118, 168, -65, -4, -48, -202, +63, -113, 73, 136, 17, 175, -52, 17, +-98, -113, -22, -65, 12, -11, 115, -24, +45, 69, -118, 156, -147, 92, 22, -165, +186, -246, 7, -28, -172, 225, -79, 261, +151, -3, 109, -232, -115, -270, -161, 36, +-39, 351, 127, 249, 93, -211, -5, -439, +-71, 6, -81, 448, -38, 234, -33, -356, +74, -359, 106, 212, 7, 398, -129, -71, +-94, -401, 57, 1, 26, 401, -3, 110, +11, -395, 6, -251, -78, 313, -73, 370, +109, -123, 135, -380, -103, -10, -315, 328, +-42, 93, 347, -289, 244, -201, -217, 276, +-358, 358, -2, -94, 179, -449, 43, -171, +-37, 367, 59, 370, 21, -126, -150, -428, +-132, -46, 47, 396, 146, 194, 39, -365, +-130, -369, -101, 291, 101, 541, 142, -46, +-107, -584, -283, -194, -14, 465, 302, 312, +176, -318, -189, -349, -268, 236, 1, 407, +175, -113, 58, -431, -146, -82, -81, 354, +132, 251, 111, -172, -142, -269, -216, 20, +21, 277, 174, 96, 75, -275, -114, -249, +-93, 199, 2, 431, 19, 13, -19, -440, +-47, -228, 50, 308, 60, 329, -40, -176, +-142, -343, -46, 81, 115, 405, 70, 117, +-55, -419, -126, -372, -27, 214, 53, 549, +44, 138, -21, -483, -68, -372, -32, 266, +-14, 488, 41, -80, 27, -489, -36, -71, +-121, 454, -53, 249, 160, -367, 93, -341, +-140, 217, -219, 392, 26, -74, 183, -387, +11, -23, -103, 362, -48, 179, 67, -297, +-61, -292, -156, 171, -5, 350, 186, 1, +151, -347, -182, -106, -248, 291, -28, 227, +168, -198, 56, -303, -82, 98, 12, 311, +22, 66, -69, -287, -170, -166, 7, 174, +128, 256, 55, 21, -22, -258, -88, -181, +-49, 69, -87, 305, 16, 146, 71, -200, +24, -278, -51, 2, -66, 301, 76, 102, +-3, -169, -154, -161, -176, 118, 101, 183, +289, -77, 43, -163, -255, -24, -267, 189, +50, 87, 165, -118, 65, -111, -41, 54, +-65, 165, -27, -50, -99, -168, -36, -17, +66, 222, 86, 137, -54, -222, -169, -214, +-2, 110, 107, 308, 36, -4, -136, -285, +-97, -53, 47, 286, 3, 177, -49, -307, +3, -321, 107, 192, -34, 499, -205, 83, +-110, -477, 126, -335, 169, 240, -106, 429, +-166, -32, 30, -327, 132, -18, -80, 318, +-231, 68, 21, -393, 196, -222, 46, 334, +-212, 419, -112, -107, 132, -388, 79, -45, +-140, 240, -207, 38, 59, -203, 215, 23, +51, 276, -197, 95, -202, -215, 50, -208, +128, 37, -22, 113, -147, 88, 1, 54, +174, -5, 16, -102, -237, -73, -227, 85, +106, 54, 242, -76, 10, -47, -173, 149, +-85, 111, 59, -157, -58, -189, -128, 117, +7, 268, 164, -55, 85, -326, -171, -89, +-202, 367, -62, 321, 136, -170, 124, -412, +-56, -123, -167, 256, -86, 214, 122, 13, +74, -75, -125, -33, -195, -74, 42, -100, +216, 48, 2, 158, -256, 123, -194, -74, +160, -137, 228, -62, -38, 89, -286, 185, +-171, -4, 142, -229, 183, -227, -14, 218, +-201, 447, -82, 74, 78, -428, -2, -411, +-144, 164, -42, 384, 235, 174, 118, -103, +-293, -93, -372, -62, 74, -204, 395, -88, +96, 201, -281, 389, -213, 61, 76, -301, +49, -269, -134, 6, -24, 216, 186, 124, +94, 72, -245, -35, -288, -119, -6, -119, +217, 21, 179, 170, -64, 36, -223, -85, +-214, -90, 20, 69, 204, 112, 92, 28, +-145, -20, -187, -120, 26, -114, 53, -8, +-87, 253, -84, 251, 116, -101, 127, -337, +-176, -186, -310, 188, -42, 213, 303, 83, +201, 11, -198, -14, -364, -131, -85, -208, +232, 47, 124, 231, -133, 132, -152, -89, +62, -51, 68, 58, -173, -102, -203, -209, +87, 20, 282, 383, -7, 251, -356, -216, +-210, -358, 213, -62, 257, 231, -160, 131, +-324, -19, -10, -3, 252, 12, 32, -87, +-260, -142, -109, 47, 168, 201, 101, 127, +-233, -76, -254, -163, 93, -81, 293, 36, +74, 170, -293, 145, -283, -58, -6, -227, +197, -125, 111, 130, -92, 159, -95, 43, +-38, 38, -17, 50, -149, -150, -148, -318, +105, -16, 282, 442, 91, 376, -355, -199, +-386, -511, 14, -176, 360, 267, 187, 327, +-230, 78, -280, -117, -15, -147, 156, -89, +-59, 30, -181, 104, 46, 101, 227, 21, +-20, -62, -426, -88, -239, -63, 295, 48, +426, 132, -97, 89, -547, -57, -247, -144, +259, -30, 343, 124, -78, 140, -310, -30, +-107, -141, 86, -26, 52, 111, -137, 54, +-60, -130, 59, -55, 57, 171, -63, 147, +-168, -133, -72, -229, 27, 81, 111, 269, +-50, 55, -167, -241, -74, -146, 111, 156, +120, 179, -187, -29, -236, -177, -30, -44, +239, 106, 113, 128, -238, 22, -247, -103, +7, -58, 246, 37, -11, 105, -274, -5, +-153, -91, 183, -14, 241, 75, -189, 56, +-360, -92, -83, -56, 314, 77, 176, 114, +-272, -22, -306, -129, 60, 18, 324, 135, +-49, 64, -414, -153, -194, -154, 315, 104, +353, 231, -234, 72, -473, -203, -129, -167, +319, 52, 194, 172, -216, 108, -189, -20, +67, -39, 121, -74, -233, -78, -285, -27, +117, 97, 377, 161, 102, 42, -467, -97, +-426, -162, 97, -41, 470, 130, 155, 176, +-379, 41, -360, -139, 38, -102, 301, 41, +4, 81, -235, -31, -96, -52, 146, 103, +42, 99, -304, -125, -185, -225, 206, 81, +325, 375, -104, 126, -457, -311, -220, -308, +195, 130, 289, 304, -50, 46, -234, -122, +-93, -27, 56, 35, -35, -126, -214, -115, +-75, 174, 192, 310, 236, 70, -114, -248, +-418, -227, -250, -11, 161, 144, 325, 167, +34, 96, -232, -15, -199, -181, -18, -194, +30, -23, -51, 209, -11, 270, 51, 58, +30, -173, -124, -257, -207, -58, -57, 157, +149, 203, 142, 80, -140, -119, -273, -153, +-64, -69, 172, 99, 105, 105, -151, 17, +-202, -4, -26, 13, 102, 29, 21, -77, +-154, -43, -130, 41, 82, 57, 152, -1, +-97, -28, -321, 77, -128, 5, 212, -104, +223, -95, -122, 112, -308, 230, -117, 23, +122, -173, 109, -189, -111, 88, -125, 224, +10, 60, 54, -188, -84, -199, -154, 150, +12, 254, 64, 19, -47, -276, -183, -119, +-30, 247, 185, 199, 95, -94, -217, -245, +-381, 35, -64, 184, 309, 26, 303, -128, +-136, -68, -424, 142, -232, 71, 114, -67, +209, -103, -5, 65, -79, 189, -49, 28, +-47, -163, -177, -191, -159, 104, 95, 258, +186, 66, 24, -208, -204, -197, -120, 125, +-9, 186, -67, -10, -118, -150, 16, 63, +217, 260, 74, 19, -241, -315, -378, -291, +-83, 210, 262, 473, 234, 147, -53, -370, +-285, -429, -184, 93, -20, 419, 83, 203, +41, -242, -32, -245, -15, 143, -45, 262, +-62, -58, -156, -340, -123, -54, 44, 332, +174, 228, 113, -217, -173, -318, -282, 117, +-165, 338, 101, 30, 177, -321, 10, -114, +-117, 309, -100, 244, 10, -176, -118, -323, +-195, 24, -20, 271, 253, 82, 194, -168, +-207, -84, -340, 143, -152, 74, 138, -123, +127, -58, -8, 188, -49, 149, -55, -202, +-52, -294, -165, 83, -124, 397, 35, 169, +177, -297, 88, -348, -191, 46, -211, 322, +-36, 193, 96, -104, -44, -160, -136, -5, +30, 82, 142, -15, 15, -106, -264, 35, +-246, 180, 15, 77, 212, -174, 148, -162, +-110, 108, -223, 181, -183, -24, 27, -152, +119, 67, 23, 204, -81, -5, -83, -253, +43, -171, -44, 158, -170, 236, -115, 72, +103, -96, 168, -83, -92, -45, -216, -94, +-95, -1, 115, 209, 55, 331, -134, 11, +-131, -417, -20, -395, 117, 77, 43, 501, +-92, 313, -181, -116, -115, -339, 49, -199, +68, 28, 35, 153, -47, 251, -55, 133, +-105, -88, -141, -271, -38, -117, 52, 154, +125, 144, 8, -27, -135, -111, -184, 80, +-89, 140, 111, -18, 75, -153, -72, -72, +-171, 117, 5, 55, 135, -15, -74, 35, +-222, 134, -85, -5, 217, -286, 78, -208, +-215, 148, -187, 401, 83, 146, 168, -224, +-119, -251, -173, -1, -24, 187, 105, 65, +-38, -46, -163, -60, 1, 14, 120, 55, +92, 26, -176, 5, -243, -73, -76, -61, +150, -15, 199, 68, -43, 114, -177, 93, +-157, 65, 17, -96, 25, -227, -103, -186, +-96, 125, 85, 372, 227, 198, -27, -175, +-294, -341, -257, -69, 25, 190, 166, 144, +60, -39, 8, -64, 3, 80, -26, 50, +-194, -77, -261, -97, -50, 50, 225, 88, +270, -93, -28, -138, -258, 93, -181, 345, +19, 166, 46, -281, -94, -427, -52, -90, +146, 344, 208, 338, -53, 29, -354, -180, +-274, -144, 104, -64, 324, -70, 89, 25, +-213, 175, -169, 192, 48, -13, 55, -169, +-111, -69, -93, 83, 49, 70, 58, -108, +-87, -147, -135, 46, 49, 250, 159, 220, +-7, -77, -282, -304, -266, -234, 76, 87, +293, 296, 173, 172, -150, -74, -265, -173, +-121, -23, 41, 93, 75, 13, -33, -127, +-37, -97, 30, 105, 102, 180, 11, 89, +-184, -34, -223, -57, -53, -92, 207, -180, +188, -72, -19, 231, -163, 370, -92, 42, +-2, -370, -68, -289, -58, 152, 49, 322, +155, -21, 25, -282, -140, -41, -130, 324, +-23, 237, 38, -205, -56, -339, -41, -35, +50, 226, 95, 72, -59, -143, -198, 15, +-55, 276, 113, 164, 66, -293, -176, -439, +-188, -34, 45, 430, 231, 411, 119, -43, +-205, -351, -286, -257, -49, 51, 228, 207, +112, 113, -167, -34, -148, -80, 112, -5, +214, 22, -71, 5, -270, 40, -143, 101, +135, 5, 210, -241, 30, -234, -83, 154, +-93, 468, -10, 192, -19, -348, -73, -411, +-45, 20, 57, 293, 149, 81, 4, -121, +-129, 40, -103, 229, 35, 62, -10, -271, +-203, -281, -107, 12, 214, 219, 352, 158, +-63, 29, -445, 25, -274, 31, 150, -83, +244, -247, -50, -190, -86, 131, 88, 371, +91, 230, -186, -136, -261, -280, 50, -114, +220, 61, 87, 36, -134, -34, -89, 52, +46, 168, 95, 148, 34, -23, -125, -197, +-176, -232, -45, -74, 220, 182, 231, 262, +-29, 87, -196, -106, -115, -85, 41, -18, +-26, -124, -78, -177, 48, 98, 202, 396, +119, 209, -158, -273, -228, -351, -90, 49, +52, 257, 15, -16, -21, -242, 93, 21, +141, 317, -22, 136, -287, -250, -257, -237, +44, 103, 238, 184, 129, -62, -89, -180, +-103, 91, -15, 306, 24, 92, -57, -289, +-106, -337, -17, 15, 110, 277, 187, 205, +73, -20, -104, -94, -174, -49, -87, -58, +58, -77, 105, 14, 123, 168, 79, 121, +-41, -121, -149, -244, -113, -10, 100, 312, +183, 248, 14, -179, -226, -446, -169, -163, +154, 327, 266, 413, 20, 41, -265, -277, +-176, -198, 59, 18, 73, 53, -50, -34, +-47, 12, 120, 162, 89, 153, -114, -57, +-256, -235, -127, -148, 125, 104, 191, 211, +97, 42, -65, -182, -86, -106, -84, 165, +-73, 206, -4, -91, 88, -283, 147, -75, +48, 176, -29, 147, -53, -4, -20, 24, +-12, 54, -15, -127, 60, -245, 98, -22, +72, 282, -46, 196, -71, -117, -2, -187, +34, 23, 34, 101, 6, -77, -2, -144, +-71, 63, -67, 274, 43, 156, 105, -179, +22, -349, -144, -145, -130, 230, 3, 358, +79, 92, 13, -263, -63, -285, 10, 13, +57, 236, -44, 140, -186, -82, -111, -124, +132, -3, 215, 65, 54, 14, -154, -39, +-125, -16, 53, 26, 125, 30, 0, -1, +-130, -28, -17, -15, 196, 7, 197, 33, +-56, 15, -169, 1, -2, 23, 116, 23, +16, -46, -81, -125, 67, -50, 186, 113, +55, 167, -122, 25, -115, -113, 13, -101, +12, -25, -31, 9, 33, 16, 125, 98, +68, 113, -121, -16, -208, -165, -137, -120, +30, 60, 147, 127, 125, 41, 11, -66, +-111, -39, -110, 14, -72, 17, -50, -6, +-20, 11, 74, 47, 170, 24, 88, -50, +-71, -120, -154, -69, -25, 102, 108, 244, +57, 121, -63, -202, -20, -350, 215, -79, +244, 306, -28, 330, -302, 0, -193, -277, +165, -220, 323, 4, 182, 154, -81, 164, +-169, 69, -103, -77, 13, -175, 66, -109, +64, 52, 72, 149, 0, 105, -66, -20, +-81, -107, 2, -91, 44, 14, -28, 88, +-97, 15, -113, -103, -2, -69, 126, 115, +167, 194, 6, 23, -232, -193, -248, -198, +-33, 3, 219, 150, 218, 136, 57, 41, +-96, -14, -148, -62, -83, -141, 37, -110, +187, 70, 181, 202, 51, 44, -82, -171, +-76, -80, 28, 197, 72, 164, 78, -212, +43, -316, 44, 37, 38, 312, 26, 100, +8, -135, -36, 16, -39, 164, -22, -147, +68, -477, 94, -99, 14, 577, -105, 580, +-120, -183, 27, -675, 87, -306, 18, 297, +-85, 358, -71, -13, -25, -153, -26, 50, +13, 155, 50, -75, 29, -295, -82, -155, +-94, 188, 21, 305, 126, 76, 90, -145, +-77, -96, -118, 34, 0, -44, 152, -221, +153, -127, 4, 277, -77, 449, -11, 73, +115, -414, 128, -391, 31, 65, -59, 282, +-38, 65, 84, -108, 147, 84, 71, 220, +-76, -73, -93, -412, 42, -216, 128, 312, +34, 427, -112, -23, -81, -387, 61, -164, +93, 265, -42, 282, -155, -115, -77, -355, +70, -118, 115, 260, 24, 287, -78, -45, +-123, -247, -132, -88, -56, 135, 108, 65, +231, -131, 113, -87, -169, 158, -255, 207, +-15, -62, 222, -246, 152, -104, -37, 121, +-34, 111, 81, -22, 65, -34, -69, 42, +-67, 36, 107, -45, 214, -63, 103, -20, +-70, 5, -50, 15, 55, 66, 40, 66, +-58, -34, -31, -105, 134, -39, 171, 46, +36, 12, -129, -37, -139, 25, -60, 99, +26, -5, 92, -120, 69, -23, 19, 152, +-72, 58, -128, -229, -137, -230, -29, 152, +140, 427, 142, 133, -14, -358, -173, -389, +-82, 77, 72, 372, 39, 131, -94, -219, +-45, -185, 200, 131, 217, 189, -5, -37, +-187, -179, -100, -54, 41, 73, 84, -12, +160, -58, 188, 103, 112, 244, -114, 40, +-207, -303, -52, -310, 172, 76, 268, 348, +105, 150, -87, -200, -163, -204, -46, 118, +87, 240, 82, -49, -4, -334, -72, -175, +16, 228, 73, 337, 32, 42, -93, -198, +-134, -106, -56, 50, -10, -58, 38, -225, +74, -31, 103, 376, -20, 400, -159, -124, +-150, -514, -21, -274, 115, 223, 126, 302, +92, 2, -21, -95, -115, 89, -80, 110, +74, -170, 169, -275, 64, -6, -45, 235, +-22, 122, 96, -92, 107, -31, 16, 144, +-24, 76, -6, -217, 25, -323, 32, -36, +86, 348, 127, 370, 75, -32, -66, -372, +-161, -249, -91, 137, 59, 231, 128, -27, +65, -173, 0, 29, -17, 232, -54, 92, +-122, -177, -113, -200, -6, -16, 99, 74, +94, 40, 25, 50, -53, 123, -105, 59, +-76, -151, -10, -245, 37, -66, 39, 194, +84, 220, 125, 23, 29, -127, -134, -93, +-174, -36, -5, -56, 178, -19, 240, 146, +127, 220, -49, -2, -138, -279, -82, -240, +70, 88, 135, 277, 109, 130, 9, -91, +-23, -124, 24, -28, 56, -9, 14, -64, +-74, -42, -33, 93, 52, 194, 77, 103, +-10, -136, -58, -259, -16, -101, -3, 161, +-19, 200, -36, 3, 31, -121, 29, -16, +-36, 86, -68, -38, -24, -169, 46, -64, +23, 171, -10, 197, -45, -16, -32, -149, +7, -79, 61, 35, 88, 7, 30, -29, +-16, 33, -49, 121, -16, 58, 42, -124, +90, -177, 83, -35, 18, 149, 15, 135, +46, -8, 58, -84, -30, -26, -89, 17, +-24, -49, 115, -59, 183, 45, 63, 131, +-95, 37, -137, -115, -24, -117, 57, 26, +43, 132, 18, 61, 21, -89, 3, -135, +-51, -17, -49, 144, -22, 146, -6, -26, +-27, -168, -16, -110, 51, 41, 98, 83, +51, 26, -83, 2, -165, 51, -103, 39, +76, -64, 180, -133, 134, -63, 22, 92, +-55, 152, -77, 62, -73, -89, -5, -121, +88, -21, 153, 59, 112, 27, 26, -49, +-41, -8, -65, 81, -35, 78, -6, -45, +37, -115, 73, -46, 135, 41, 119, 45, +-34, -1, -204, 27, -210, 72, 13, 5, +200, -142, 207, -159, 41, 45, -116, 229, +-157, 151, -122, -102, -28, -194, 44, -45, +129, 91, 124, 25, 13, -76, -122, -6, +-125, 130, 5, 115, 48, -56, 26, -172, +15, -124, 88, 15, 102, 117, -11, 142, +-100, 71, -76, -48, 58, -137, 110, -139, +91, -40, 29, 106, -13, 196, -3, 91, +4, -127, 31, -210, -7, -33, -21, 157, +19, 113, 105, -47, 120, -88, -35, 5, +-152, 9, -111, -46, 66, 12, 117, 124, +36, 49, -46, -161, -55, -154, -1, 102, +-6, 227, -10, 12, -24, -216, -16, -119, +-14, 131, 0, 174, 45, -12, 33, -135, +-10, -79, -68, 10, -47, 60, 26, 80, +86, 63, 87, -45, 31, -158, -16, -87, +-56, 112, -13, 183, 55, 12, 95, -170, +70, -137, 10, 44, 13, 133, 20, 49, +2, -37, -32, -42, 24, -15, 92, -17, +61, -17, -29, 18, -69, 36, -5, 16, +34, -6, 26, 13, -12, 11, -20, -31, +5, -68, 3, -36, -45, 35, -93, 69, +-29, 69, 104, 30, 132, -31, -58, -95, +-231, -98, -117, -25, 159, 76, 225, 125, +-31, 71, -233, -22, -97, -84, 162, -80, +158, -46, -28, 12, -76, 83, 21, 100, +46, 15, -28, -98, 32, -85, 174, 47, +140, 93, -108, -49, -234, -172, -22, -48, +290, 194, 314, 233, -20, -14, -281, -259, +-187, -224, 116, 32, 228, 227, 71, 176, +-86, -17, -72, -152, 30, -118, 13, 4, +-57, 66, -54, 43, 46, -4, 65, -13, +-56, -9, -101, 4, -7, 33, 101, 30, +19, -31, -141, -106, -149, -78, 49, 44, +207, 161, 103, 131, -107, -49, -201, -209, +-71, -162, 112, 69, 162, 216, 68, 123, +-37, -79, -40, -139, 11, -63, 31, 14, +7, 38, 54, 55, 114, 74, 52, -18, +-56, -140, -49, -123, 99, 51, 148, 183, +14, 117, -114, -52, -65, -162, 91, -127, +123, 0, 15, 109, -70, 124, -27, 52, +16, -28, -47, -73, -68, -93, 33, -86, +123, 1, 27, 132, -148, 167, -149, 29, +11, -141, 112, -148, 50, -10, -62, 80, +-112, 26, -41, -31, 71, 30, 74, 103, +-17, 35, -73, -134, -34, -158, 22, 23, +53, 164, 60, 73, 45, -104, 6, -77, +-31, 89, -6, 95, 41, -105, 74, -184, +76, 20, 23, 201, -42, 94, -22, -134, +109, -116, 137, 90, -18, 118, -147, -84, +-49, -188, 151, 2, 173, 205, 14, 139, +-128, -95, -98, -177, -13, -52, 11, 71, +53, 65, 105, 6, 56, 8, -110, 26, +-208, -6, -94, -71, 137, -66, 185, 40, +-35, 104, -209, 19, -119, -120, 108, -86, +155, 122, -22, 200, -167, -25, -80, -285, +108, -191, 125, 173, -4, 321, -70, 64, +14, -226, 62, -184, -16, 34, -30, 81, +103, -13, 147, 2, -33, 101, -152, 49, +21, -126, 222, -137, 139, 55, -85, 157, +-172, 17, -49, -138, 132, -78, 207, 85, +113, 123, -78, 16, -197, -86, -133, -96, +75, -44, 167, 40, 104, 105, -5, 85, +-90, -12, -117, -95, -80, -84, 16, -17, +61, 46, 57, 65, -17, 47, -58, -1, +-16, -64, 21, -70, -13, 4, -112, 69, +-95, 35, 44, -38, 202, -29, 159, 44, +-69, 37, -228, -77, -176, -106, 67, 28, +222, 156, 187, 81, 22, -114, -68, -175, +-76, -27, -105, 138, -14, 129, 148, -9, +218, -111, 49, -71, -113, 26, -97, 58, +36, 5, 109, -35, 8, -15, -33, 19, +9, 28, 71, 23, 41, 8, -34, -50, +-61, -100, -29, -28, 44, 131, 19, 161, +-10, -14, -17, -181, 10, -136, 13, 48, +-36, 119, -35, 45, -33, -10, 7, -7, +13, -19, 22, -59, 19, -32, -22, 44, +-45, 44, -43, -30, 11, -22, 44, 75, +57, 76, 3, -101, -58, -208, -20, -27, +41, 240, 55, 219, 40, -92, 22, -274, +-52, -105, -67, 148, 38, 162, 123, 15, +88, -51, -27, -42, -63, -74, -3, -76, +15, 58, -20, 168, 27, 66, 141, -128, +131, -128, -69, 43, -247, 97, -142, -21, +177, -72, 297, 43, 54, 110, -224, -3, +-194, -125, 50, -72, 141, 56, 28, 67, +-58, 2, 3, -1, 33, 41, -81, 12, +-109, -69, 55, -88, 175, -12, 28, 69, +-164, 89, -161, 64, 37, -19, 207, -127, +97, -150, -106, -11, -128, 177, 15, 181, +74, -15, 10, -170, -19, -130, 41, 9, +107, 76, 9, 55, -122, 25, -99, 16, +79, 4, 193, -35, 68, -87, -126, -93, +-113, 11, 107, 168, 154, 180, -36, -33, +-158, -235, -30, -148, 182, 97, 164, 163, +-53, -2, -190, -90, -63, 33, 128, 97, +102, -42, -33, -165, -36, -43, 49, 159, +13, 125, -108, -76, -111, -134, 81, 19, +210, 130, 31, 28, -185, -132, -152, -119, +32, 52, 120, 157, 73, 74, -13, -73, +-62, -102, -49, -9, -23, 26, 14, -38, +28, -48, 31, 83, 60, 173, 27, 29, +-74, -207, -111, -219, 4, 43, 129, 241, +132, 118, 22, -127, -100, -137, -93, 69, +17, 126, 95, -65, 64, -200, 14, -32, +12, 212, 12, 173, -2, -78, -44, -170, +-28, -30, 80, 43, 119, -34, 10, -44, +-95, 108, -49, 184, 29, 19, 69, -196, +30, -205, -44, -8, -32, 176, 10, 170, +11, -6, -20, -147, 18, -74, 28, 101, +-42, 86, -95, -131, -35, -186, 107, 74, +98, 284, -35, 115, -140, -196, -88, -215, +57, 8, 117, 110, 42, 17, -77, -34, +-48, 57, 15, 117, 28, 18, 24, -144, +21, -185, 7, -38, -29, 169, 33, 207, +60, 16, 15, -157, -16, -101, 7, 39, +31, 34, -4, -58, 6, -16, 44, 120, +99, 103, 41, -70, -84, -142, -81, -20, +4, 82, 73, 15, 71, -75, 61, 9, +12, 134, -84, 73, -126, -136, -51, -192, +97, 9, 122, 191, 44, 120, -67, -80, +-136, -120, -71, -20, 12, 44, 44, 29, +31, 17, 71, 3, 43, -53, -121, -42, +-168, 49, -18, 69, 149, -35, 120, -90, +14, 32, -78, 107, -106, -20, -35, -133, +56, -17, 153, 143, 101, 67, -51, -121, +-149, -119, -50, 56, 117, 132, 141, 31, +84, -72, -41, -75, -96, -17, -75, 43, +37, 52, 154, 4, 103, -30, -31, 16, +-119, 50, -37, -41, 33, -130, 42, -24, +24, 157, 3, 125, 16, -74, -28, -108, +-56, 36, -59, 39, 3, -129, 57, -108, +45, 171, -17, 278, -100, -6, -57, -280, +27, -182, 56, 67, -25, 135, -38, 68, +35, 58, -11, 45, -54, -91, -1, -182, +71, -60, 19, 118, -45, 130, -7, 32, +35, -2, 16, -22, -28, -99, 35, -126, +83, 36, 11, 205, -57, 107, -13, -137, +72, -178, 49, 48, 0, 162, 7, -11, +36, -168, -14, -21, -37, 189, 44, 74, +66, -174, -10, -129, -63, 141, -9, 154, +43, -112, 46, -181, 4, 74, -83, 200, +-83, -37, 37, -190, 104, 16, 8, 178, +-78, -28, -48, -228, -3, -22, 2, 256, +7, 132, 32, -194, 34, -189, -62, 93, +-138, 134, -3, -84, 183, -106, 116, 158, +-130, 223, -156, -133, 47, -388, 108, -79, +-31, 397, -22, 308, 140, -217, 100, -353, +-128, 73, -204, 307, 16, -88, 219, -369, +164, 75, -40, 553, -103, 155, -15, -588, +-15, -465, -54, 353, 14, 559, 179, -114, +149, -448, -72, 101, -196, 455, -118, -117, +86, -659, 145, -131, 19, 705, -95, 500, +15, -405, 104, -597, -67, 96, -193, 405, +-54, -97, 174, -348, 135, 179, -47, 547, +-110, -18, -41, -636, 20, -316, -21, 404, +-14, 445, 29, -145, 70, -337, 35, 44, +-32, 301, -46, 20, -85, -345, -25, -203, +106, 231, 154, 395, -13, 36, -141, -368, +-9, -255, 89, 195, 29, 328, -60, -82, +28, -329, 105, -7, 10, 357, -104, 124, +-66, -352, 134, -242, 141, 271, -63, 354, +-168, -186, 1, -439, 146, 29, 39, 473, +-56, 193, -45, -385, 40, -333, 17, 178, +-55, 322, -61, -70, 9, -252, 136, 89, +50, 283, -134, -36, -177, -389, 42, -118, +194, 358, 22, 295, -142, -191, -84, -374, +118, 28, 62, 322, -120, 126, -68, -251, +134, -234, 129, 142, -135, 275, -161, 25, +42, -298, 183, -146, 84, 241, -75, 269, +-111, -125, -90, -378, 86, -13, 165, 363, +57, 210, -124, -264, -106, -316, 117, 94, +119, 270, -68, 65, -171, -189, 87, -94, +253, 81, -24, 78, -273, 1, -98, -65, +273, -24, 174, -2, -157, 75, -214, 66, +10, -71, 181, -146, 78, -26, -57, 202, +-128, 110, -9, -151, 86, -180, -8, 89, +-103, 204, -29, -87, 181, -222, 97, 42, +-178, 320, -242, 88, 46, -343, 275, -264, +48, 193, -192, 415, -98, 23, 136, -381, +85, -232, -104, 231, -44, 356, 49, -75, +24, -349, -19, -68, 38, 317, 48, 180, +-64, -252, -26, -248, 80, 130, 51, 285, +-116, -10, -94, -264, 186, -104, 235, 189, +-71, 217, -341, -67, -90, -286, 291, -107, +173, 266, -175, 287, -162, -141, 193, -365, +181, -4, -207, 345, -353, 113, 22, -304, +434, -168, 232, 269, -255, 238, -386, -184, +12, -315, 301, 28, 52, 281, -214, 115, +-59, -139, 251, -176, 111, 1, -258, 137, +-264, 115, 88, -64, 301, -195, 83, -41, +-184, 231, -141, 200, 96, -183, 131, -331, +-75, 54, -171, 408, 36, 102, 241, -457, +114, -307, -130, 403, -157, 582, 12, -166, +57, -764, 7, -252, 57, 617, 141, 602, +44, -254, -162, -622, -152, -49, 4, 450, +130, 147, 106, -391, 23, -193, -44, 399, +-76, 380, -9, -241, -32, -551, -44, -54, +7, 438, 137, 265, 99, -185, -122, -267, +-121, 47, -11, 168, 46, 26, -69, -129, +-15, -134, 180, 64, 114, 208, -135, 162, +-314, -161, -15, -354, 278, -9, 178, 376, +-134, 225, -222, -358, 85, -391, 151, 252, +-2, 535, -138, 7, 3, -609, 155, -291, +0, 425, -111, 458, -74, -149, 175, -472, +167, 59, -70, 443, -229, 28, -161, -578, +202, -311, 314, 618, 109, 700, -288, -236, +-316, -923, 84, -305, 276, 708, 120, 615, +-191, -243, -105, -648, 110, -48, 107, 503, +-105, 209, -267, -362, 49, -422, 348, 220, +178, 560, -343, 112, -381, -542, 177, -504, +365, 332, 14, 691, -301, 88, -90, -655, +160, -466, 109, 436, -32, 625, -130, -76, +-51, -673, 62, -228, 179, 589, 57, 467, +-219, -368, -163, -714, 169, 91, 302, 826, +-94, 273, -346, -755, 9, -712, 395, 514, +187, 1016, -370, -20, -349, -1074, 197, -570, +457, 798, 83, 937, -395, -257, -267, -983, +209, -206, 360, 778, -27, 463, -352, -545, +-135, -645, 253, 320, 297, 774, -94, 30, +-355, -787, -146, -417, 279, 560, 322, 645, +-161, -175, -418, -720, -46, -141, 469, 594, +279, 449, -398, -320, -548, -676, 97, -65, +688, 539, 277, 443, -524, -192, -544, -500, +256, -110, 642, 247, -26, 261, -649, -98, +-236, -245, 641, -23, 577, 242, -357, 299, +-788, -164, -118, -522, 669, -277, 467, 465, +-254, 735, -504, -15, -10, -735, 397, -488, +121, 405, -368, 611, -308, -71, 362, -505, +552, -95, -50, 483, -647, 244, -390, -430, +391, -544, 577, 160, 62, 707, -502, 317, +-338, -509, 263, -707, 411, 55, -53, 733, +-450, 435, -129, -485, 351, -741, 320, 89, +-163, 791, -397, 354, -37, -668, 328, -697, +180, 324, -279, 866, -255, 127, 204, -796, +377, -503, -26, 479, -433, 719, -195, -84, +283, -677, 373, -276, -60, 446, -353, 488, +-73, -127, 284, -468, 195, -197, -208, 282, +-276, 342, 58, -17, 303, -287, 191, -238, +-133, 149, -288, 320, -113, 79, 174, -297, +219, -283, -28, 186, -179, 348, 12, 34, +196, -326, 10, -183, -336, 223, -211, 227, +338, -58, 442, -274, -99, -96, -526, 229, +-160, 280, 384, 2, 257, -383, -234, -319, +-299, 154, 167, 502, 355, 247, -23, -333, +-407, -465, -209, -66, 333, 341, 389, 249, +-92, -70, -444, -140, -104, -37, 359, 31, +244, -65, -221, -32, -343, 70, 114, 95, +350, 70, 60, -19, -329, -85, -219, -186, +279, -46, 331, 240, -78, 216, -431, -84, +-133, -323, 380, -52, 314, 265, -127, 166, +-403, -155, -68, -293, 300, 22, 227, 282, +-148, 196, -343, -166, 55, -332, 372, -47, +145, 263, -376, 219, -372, -110, 235, -213, +482, -32, 63, 139, -495, 75, -293, -77, +324, -63, 440, -5, -101, 110, -530, 34, +-62, -74, 469, -99, 286, -21, -396, 164, +-498, 59, 228, -32, 594, -84, 136, -39, +-613, 13, -435, -85, 388, 93, 584, 190, +3, 84, -564, -239, -219, -339, 330, 125, +331, 395, -110, 171, -379, -351, -1, -346, +329, 220, 207, 426, -240, -29, -352, -530, +52, -214, 330, 504, 222, 547, -225, -240, +-361, -759, -12, -207, 401, 677, 266, 661, +-379, -323, -467, -824, 155, -222, 635, 705, +145, 658, -566, -326, -404, -809, 278, -261, +552, 722, -35, 687, -489, -353, -176, -873, +378, -186, 362, 916, -284, 620, -461, -633, +24, -985, 503, 72, 297, 1159, -357, 503, +-487, -847, 10, -1029, 522, 216, 305, 1214, +-345, 428, -458, -888, 80, -967, 486, 322, +121, 1149, -428, 266, -274, -892, 340, -746, +450, 485, -180, 929, -599, -65, -78, -903, +615, -387, 397, 770, -417, 780, -588, -375, +127, -986, 569, -235, 116, 836, -466, 691, +-262, -323, 370, -783, 402, -172, -221, 569, +-521, 410, -14, -261, 495, -527, 245, -33, +-341, 508, -321, 357, 189, -245, 297, -565, +-99, -174, -351, 384, 2, 451, 383, 12, +205, -374, -265, -244, -416, 140, 51, 229, +393, -52, 148, -210, -266, 37, -234, 310, +223, 80, 262, -299, -143, -270, -376, 103, +-48, 296, 418, 70, 274, -69, -229, -82, +-432, -93, -1, -71, 446, 41, 217, 252, +-351, 43, -440, -262, 209, -202, 619, 177, +131, 394, -615, -78, -511, -425, 380, -181, +681, 349, -9, 406, -651, -200, -229, -431, +529, -65, 375, 381, -350, 264, -586, -238, +86, -313, 613, 1, 265, 297, -376, 162, +-503, -181, 70, -229, 397, 40, 136, 238, +-240, 76, -223, -208, 191, -174, 262, 151, +-65, 205, -355, -30, -162, -216, 296, -24, +312, 190, -49, 9, -297, -123, -114, -29, +133, 152, 109, 34, -11, -217, -56, -4, +-14, 235, 36, 131, 64, -273, -45, -308, +-94, 221, 21, 414, 83, 47, -5, -421, +-92, -313, 109, 247, 155, 397, -120, 69, +-286, -365, -36, -317, 390, 202, 207, 443, +-273, 89, -347, -488, 84, -395, 391, 341, +15, 621, -328, -18, -161, -675, 271, -349, +318, 530, -174, 621, -416, -240, -103, -750, +409, -170, 382, 737, -234, 598, -531, -449, +-121, -868, 485, -142, 422, 863, -214, 687, +-535, -415, -149, -933, 422, -265, 396, 813, +-146, 713, -435, -337, -91, -863, 333, -165, +249, 822, -196, 501, -366, -580, 39, -829, +448, 198, 260, 1048, -363, 329, -536, -879, +67, -907, 574, 332, 302, 1103, -354, 362, +-486, -779, 42, -833, 427, 244, 218, 904, +-287, 291, -398, -751, 74, -712, 432, 405, +254, 973, -309, 159, -510, -967, -50, -684, +474, 547, 437, 969, -247, 4, -576, -931, +-76, -403, 539, 641, 360, 704, -465, -310, +-598, -847, 203, -127, 814, 740, 249, 595, +-766, -376, -687, -781, 335, -160, 876, 674, +176, 575, -696, -317, -529, -739, 319, -143, +693, 717, 48, 519, -620, -401, -406, -778, +395, -75, 667, 748, -31, 457, -661, -368, +-382, -654, 462, -22, 634, 560, -149, 248, +-696, -318, -174, -428, 659, 159, 445, 492, +-524, 83, -696, -445, 215, -427, 811, 243, +196, 576, -693, 188, -537, -431, 334, -542, +634, 38, 22, 538, -534, 381, -215, -264, +333, -552, 289, -77, -175, 487, -329, 340, +52, -313, 293, -502, 98, 1, -191, 554, +-167, 345, 107, -289, 127, -591, -55, -165, +-110, 502, 42, 460, 168, -131, 13, -530, +-139, -131, -86, 476, 40, 272, 66, -363, +-4, -573, 31, 164, 109, 784, -4, 283, +-187, -583, -183, -741, 106, 143, 280, 745, +27, 269, -197, -455, -123, -514, 126, 269, +114, 632, -146, 20, -159, -700, 51, -549, +243, 523, 123, 908, -193, 97, -240, -820, +-44, -654, 210, 389, 193, 689, -64, 48, +-174, -510, -119, -228, 123, 413, 188, 323, +-32, -248, -192, -541, -129, -63, 247, 558, +220, 460, -188, -222, -326, -662, 32, -182, +451, 484, 127, 469, -351, -168, -346, -515, +103, -97, 455, 325, 152, 321, -263, -139, +-350, -337, 57, -68, 344, 238, 59, 269, +-247, -163, -208, -306, 186, -38, 291, 302, +1, 277, -292, -198, -255, -354, 140, -96, +284, 289, 101, 315, -196, -111, -194, -291, +52, -129, 165, 226, 72, 276, -203, -89, +-195, -346, 91, -205, 369, 289, 187, 496, +-322, -1, -462, -497, -52, -387, 479, 240, +383, 513, -183, 55, -481, -338, -95, -233, +430, 195, 228, 283, -351, -137, -415, -332, +241, -42, 615, 420, 95, 336, -604, -319, +-534, -526, 292, -70, 698, 553, 178, 399, +-542, -283, -503, -506, 252, -114, 564, 435, +98, 326, -559, -187, -396, -414, 407, -67, +621, 427, -23, 253, -724, -294, -374, -474, +458, 50, 605, 542, -37, 287, -603, -322, +-226, -514, 395, -41, 340, 405, -240, 291, +-425, -169, 152, -292, 459, 33, 71, 238, +-409, -21, -320, -281, 192, -75, 362, 259, +144, 265, -202, -96, -291, -274, -25, -162, +211, 99, 186, 257, -78, 72, -159, -154, +-58, -175, 43, 84, 121, 203, 87, -27, +-67, -126, -192, -104, -38, 33, 163, 91, +113, 96, -52, 80, -94, -140, -27, -160, +14, -17, 43, 121, 43, 140, -62, -31, +-126, -65, 32, -109, 243, -5, 90, 195, +-278, 59, -269, -175, 104, -258, 298, 148, +94, 391, -133, 37, -173, -351, -55, -278, +128, 198, 115, 360, -134, 7, -187, -305, +185, -218, 348, 227, -115, 401, -489, -43, +-106, -520, 435, -295, 294, 475, -207, 619, +-317, -216, -2, -739, 227, -144, 124, 683, +-143, 412, -215, -490, 47, -557, 305, 229, +97, 608, -267, 41, -268, -499, 71, -265, +330, 244, 181, 317, -172, 46, -349, -193, +-75, -219, 330, -12, 232, 224, -185, 229, +-286, -190, 44, -324, 272, 67, 20, 387, +-239, 118, -130, -401, 158, -247, 255, 216, +-39, 314, -274, 12, -169, -220, 206, -85, +317, -15, -95, -1, -360, 123, -88, 137, +337, -26, 259, -254, -179, -13, -356, 272, +-95, 10, 278, -366, 327, -106, -74, 547, +-380, 366, -114, -572, 304, -642, 248, 291, +-241, 869, -332, -12, 151, -847, 394, -273, +64, 737, -404, 588, -250, -583, 236, -792, +285, 237, 9, 863, -215, 147, -85, -796, +84, -365, 53, 609, 12, 539, -88, -449, +-21, -711, 79, 259, 66, 754, -6, 45, +-113, -684, -78, -241, 3, 487, 103, 283, +174, -329, -48, -234, -289, 227, -117, 218, +273, -195, 307, -137, -214, 178, -409, 60, +43, -260, 433, -113, 196, 421, -438, 335, +-366, -435, 296, -650, 477, 197, -107, 936, +-476, 164, 3, -1010, 351, -613, 54, 911, +-239, 1029, -28, -678, 176, -1334, 29, 318, +-141, 1552, -63, 107, 115, -1644, 42, -618, +-51, 1561, -3, 1141, 94, -1211, -11, -1542, +-235, 646, -45, 1678, 236, -58, 243, -1522, +-121, -431, -392, 1228, -70, 761, 291, -845, +303, -976, -167, 440, -382, 1019, 28, -48, +304, -901, 127, -285, -268, 757, -188, 420, +159, -512, 210, -561, 23, 275, -195, 639, +-163, -81, 22, -485, 200, -200, 182, 371, +-105, 315, -284, -230, -82, -301, 262, -9, +234, 416, -167, 89, -285, -394, 116, -294, +334, 305, -75, 519, -369, -198, -35, -561, +366, -21, 192, 559, -244, 136, -237, -526, +8, -207, 198, 528, 89, 367, -100, -478, +-46, -566, 7, 222, 15, 707, -88, 76, +27, -562, 149, -328, -14, 325, -122, 408, +-103, -227, 129, -348, 106, 115, -114, 474, +-152, -15, 69, -554, 297, -196, -35, 439, +-381, 442, -167, -294, 365, -467, 378, 102, +-230, 479, -410, 34, 31, -536, 375, -203, +-35, 507, -337, 517, 84, -348, 409, -741, +13, -13, -495, 786, -108, 373, 341, -658, +173, -603, -179, 436, -72, 784, 171, -245, +-92, -846, -200, -6, 51, 872, 213, 303, +-36, -782, -150, -501, 131, 495, 98, 672, +-233, -216, -219, -630, 235, -47, 313, 454, +-136, 297, -321, -283, 51, -332, 247, 6, +-20, 254, -207, 198, -28, -132, 197, -171, +93, -91, -84, 133, -230, 163, -104, -74, +296, -178, 304, -47, -196, 298, -540, 146, +82, -297, 641, -335, 106, 152, -669, 470, +-379, 16, 701, -410, 593, -177, -518, 350, +-824, 282, 258, -297, 893, -426, -51, 99, +-681, 580, -139, 204, 573, -462, 112, -511, +-472, 172, -114, 554, 310, 65, 264, -375, +-209, -156, -165, 303, -23, 125, -34, -297, +77, -153, 155, 192, 159, 282, -253, -32, +-289, -218, 107, -185, 321, 27, 61, 328, +-356, 131, -105, -303, 312, -287, 213, 303, +-296, 386, -409, -316, 205, -464, 538, 279, +45, 616, -601, -191, -317, -711, 523, -5, +523, 685, -359, 252, -682, -566, 181, -360, +744, 322, 103, 431, -734, -113, -431, -439, +570, -88, 667, 323, -183, 346, -788, -121, +-170, -459, 700, -187, 406, 322, -488, 500, +-609, -61, 320, -551, 722, -311, -98, 384, +-726, 631, -234, -96, 673, -718, 471, -314, +-471, 637, -601, 676, 127, -401, 684, -910, +167, 23, -545, 1008, -419, 458, 260, -918, +574, -974, -49, 514, -523, 1296, -147, 159, +489, -1289, 297, -748, -465, 975, -460, 1077, +284, -530, 590, -1316, -73, 155, -463, 1372, +-91, 378, 283, -1163, 48, -916, -253, 663, +40, 1005, 238, 14, 115, -756, -202, -351, +-194, 365, 44, 399, 36, -58, 60, -470, +81, -150, 133, 393, -84, 519, -292, -133, +-32, -702, 218, -298, 137, 463, -152, 659, +-119, -116, 162, -629, 138, -206, -143, 522, +-197, 453, -31, -477, 138, -694, 125, 246, +90, 1010, -8, 193, -269, -1076, -147, -693, +141, 799, 253, 1003, -36, -377, -212, -1065, +83, 30, 181, 963, -40, 241, -388, -784, +-108, -537, 457, 574, 418, 702, -291, -152, +-678, -754, 50, -282, 648, 597, 199, 565, +-617, -197, -319, -745, 575, -141, 416, 660, +-391, 461, -616, -413, 191, -731, 546, 147, +80, 712, -296, 273, -308, -527, 135, -553, +228, 220, 152, 526, -186, 185, -410, -441, +113, -424, 494, 251, 282, 600, -612, 126, +-567, -742, 429, -577, 730, 559, -61, 951, +-842, -1, -148, -1109, 724, -524, 476, 878, +-600, 932, -786, -451, 318, -1291, 921, 6, +165, 1402, -891, 704, -489, -1190, 532, -1438, +665, 593, -161, 1719, -653, 308, -133, -1551, +427, -1023, 420, 1061, -164, 1398, -499, -392, +-162, -1601, 325, -297, 455, 1480, -88, 1039, +-513, -1007, -220, -1572, 400, 278, 530, 1671, +-229, 532, -721, -1412, -135, -1093, 730, 874, +605, 1360, -544, -199, -868, -1355, 121, -386, +918, 988, 303, 781, -795, -398, -575, -922, +521, -116, 774, 684, -140, 524, -838, -299, +-289, -738, 673, -52, 669, 644, -250, 413, +-857, -454, -255, -633, 756, 208, 630, 636, +-364, 145, -852, -545, -46, -399, 795, 308, +405, 435, -522, 10, -730, -361, 205, -145, +838, 183, 217, 128, -746, 7, -686, -81, +443, -123, 948, -105, 97, 177, -912, 425, +-665, -58, 632, -672, 976, -354, -185, 665, +-1069, 798, -269, -375, 1031, -996, 656, -76, +-728, 986, -1027, 437, 274, -873, 1169, -749, +285, 613, -976, 1071, -801, -152, 646, -1186, +971, -397, -164, 908, -995, 844, -238, -431, +857, -966, 510, -2, -454, 828, -776, 404, +44, -683, 687, -689, 407, 380, -321, 899, +-715, 139, -81, -962, 610, -601, 527, 606, +-378, 941, -761, -134, 78, -993, 795, -231, +269, 755, -761, 559, -570, -550, 519, -685, +800, 251, -131, 743, -846, 140, -333, -723, +638, -410, 715, 405, -271, 671, -903, -74, +-215, -696, 883, -241, 696, 479, -592, 597, +-1031, -252, 74, -700, 1077, -140, 465, 634, +-817, 582, -848, -468, 423, -781, 1016, 39, +81, 874, -1052, 421, -563, -816, 828, -755, +969, 406, -298, 1047, -1174, 120, -229, -1048, +962, -590, 673, 634, -512, 948, -971, -186, +81, -1024, 929, -199, 508, 894, -704, 651, +-1035, -739, 219, -998, 1159, 342, 503, 1161, +-980, 279, -1052, -1023, 477, -738, 1252, 526, +251, 892, -1232, 25, -885, -789, 837, -448, +1380, 473, -149, 752, -1587, 3, -596, -827, +1312, -549, 1235, 578, -764, 951, -1585, -66, +76, -1030, 1634, -444, 687, 817, -1420, 780, +-1290, -492, 817, -949, 1673, 105, -60, 1025, +-1651, 344, -601, -906, 1208, -771, 1136, 506, +-642, 1039, -1330, -27, 23, -1003, 1164, -393, +646, 749, -813, 693, -971, -485, 192, -823, +957, 129, 467, 843, -740, 292, -808, -707, +234, -579, 987, 292, 265, 678, -1004, 112, +-646, -497, 687, -313, 1054, 181, -290, 381, +-1184, 0, -243, -339, 956, -139, 758, 277, +-574, 346, -921, -182, 43, -445, 856, -93, +384, 403, -646, 363, -590, -208, 234, -438, +701, -121, 171, 421, -560, 412, -496, -220, +143, -627, 694, -175, 223, 686, -540, 609, +-545, -412, 262, -936, 790, -43, 16, 962, +-783, 486, -508, -773, 681, -833, 967, 493, +-297, 1020, -1159, -68, -395, -1127, 1136, -374, +914, 1024, -716, 779, -1288, -673, 92, -1158, +1435, 279, 511, 1259, -1161, 295, -1135, -1110, +631, -867, 1439, 748, 6, 1098, -1382, -128, +-674, -1082, 1139, -341, 1162, 867, -645, 606, +-1485, -515, -88, -857, 1495, 120, 846, 863, +-1017, 380, -1351, -525, 295, -721, 1449, 10, +353, 598, -1257, 433, -829, -309, 904, -551, +1261, 45, -385, 611, -1489, 199, -327, -747, +1246, -545, 1063, 615, -661, 1035, -1312, -160, +-108, -1210, 1113, -425, 735, 920, -789, 876, +-1012, -489, 274, -989, 1215, 37, 275, 940, +-1230, 397, -806, -793, 817, -746, 1300, 428, +-251, 973, -1379, 29, -356, -964, 1083, -484, +840, 716, -680, 828, -986, -292, 149, -981, +948, -232, 327, 869, -729, 700, -652, -487, +286, -992, 826, 6, 144, 991, -683, 490, +-495, -798, 383, -883, 666, 435, -83, 1067, +-603, 100, -231, -1065, 499, -540, 420, 720, +-239, 821, -485, -241, -68, -875, 406, -130, +272, 585, -152, 455, -365, -276, -61, -519, +326, -28, 229, 347, -259, 328, -380, -180, +175, -356, 481, -106, -22, 286, -565, 332, +-100, -130, 536, -345, 233, -140, -505, 267, +-363, 248, 408, -68, 452, -188, -206, -91, +-478, 76, 16, 102, 376, 59, 83, -98, +-249, -175, -127, 50, 202, 283, 146, 135, +-117, -323, -205, -356, -33, 174, 175, 466, +168, 88, -31, -421, -192, -247, -83, 269, +98, 304, 98, -99, -15, -341, -68, -18, +1, 256, 32, 164, 45, -82, -25, -205, +-60, -81, -48, 14, 56, 190, 133, 183, +-4, -91, -148, -297, -120, -119, 172, 315, +192, 244, -114, -189, -256, -319, 0, 16, +337, 297, 80, 91, -261, -165, -225, -143, +133, 31, 301, 129, 11, 41, -197, -42, +-235, -119, 56, -51, 295, 167, 145, 169, +-173, -103, -347, -365, 30, -27, 345, 433, +204, 255, -255, -334, -412, -483, 99, 158, +450, 504, 173, 140, -399, -381, -345, -329, +190, 159, 390, 288, -10, 116, -332, -166, +-85, -190, 277, -6, 169, 172, -255, 137, +-232, -196, 102, -225, 315, 152, 83, 392, +-228, -10, -233, -480, -23, -196, 303, 387, +190, 350, -147, -211, -348, -384, -25, 72, +380, 373, 205, 54, -283, -345, -422, -240, +171, 237, 507, 373, 67, 4, -567, -329, +-328, -222, 510, 182, 532, 260, -279, -8, +-750, -233, 55, -64, 778, 229, 229, 124, +-745, -185, -561, -273, 679, 100, 843, 341, +-343, 92, -1109, -289, -157, -302, 1111, 163, +666, 351, -731, 73, -1052, -330, 244, -264, +1104, 246, 262, 320, -961, -34, -668, -384, +694, -91, 941, 339, -276, 150, -1075, -201, +-176, -263, 955, 183, 645, 236, -666, -119, +-936, -214, 226, -3, 1011, 275, 289, 22, +-873, -201, -665, -109, 444, 139, 834, 231, +31, -110, -770, -240, -387, -28, 476, 278, +643, 152, -151, -263, -701, -189, -233, 171, +517, 242, 596, -156, -176, -268, -693, 144, +-283, 318, 540, -36, 635, -369, -269, -88, +-749, 300, -121, 170, 741, -164, 458, -193, +-547, 123, -690, 180, 154, -101, 788, -239, +227, -10, -603, 330, -525, 151, 246, -255, +667, -316, 95, 103, -528, 400, -422, 19, +265, -360, 572, -200, 42, 322, -516, 374, +-322, -221, 380, -457, 500, -38, -185, 504, +-561, 232, -90, -420, 522, -375, 358, 221, +-321, 533, -500, -21, 15, -519, 488, -255, +222, 339, -376, 488, -368, -79, 195, -480, +472, -204, 2, 382, -489, 419, -235, -263, +366, -553, 439, 8, -188, 662, -484, 310, +-34, -583, 450, -564, 227, 286, -353, 691, +-364, -3, 109, -652, 469, -210, 119, 523, +-370, 461, -313, -360, 176, -642, 428, 54, +-48, 633, -390, 318, -167, -474, 363, -482, +406, 200, -214, 474, -507, 34, -167, -453, +470, -150, 442, 361, -195, 313, -510, -187, +-163, -460, 481, -27, 393, 378, -293, 252, +-593, -203, 27, -340, 709, 72, 288, 285, +-643, 75, -599, -269, 388, -170, 787, 226, +-49, 237, -808, -70, -323, -299, 648, -42, +664, 259, -331, 111, -857, -193, -88, -227, +832, 184, 492, 317, -612, -53, -768, -383, +249, -180, 896, 364, 150, 318, -830, -169, +-570, -398, 576, 37, 891, 444, -190, 62, +-951, -473, -317, -331, 810, 450, 710, 621, +-421, -159, -865, -711, -126, -285, 789, 557, +497, 493, -389, -232, -665, -515, -17, -28, +590, 507, 293, 204, -354, -391, -515, -458, +122, 137, 600, 585, 175, 210, -554, -375, +-493, -455, 388, 58, 664, 403, -50, 139, +-740, -208, -290, -247, 642, 90, 612, 286, +-365, 103, -859, -241, -7, -388, 857, 31, +420, 461, -678, 348, -684, -277, 386, -591, +827, -18, -51, 551, -876, 347, -326, -454, +711, -580, 706, 260, -359, 745, -838, 142, +-106, -799, 701, -529, 457, 520, -452, 766, +-573, -94, 139, -795, 645, -198, 134, 618, +-611, 468, -435, -413, 381, -681, 700, 157, +-23, 722, -702, 216, -388, -664, 471, -491, +669, 487, -110, 650, -694, -216, -271, -811, +512, -82, 503, 807, -181, 456, -524, -560, +-155, -751, 373, 170, 405, 752, -134, 206, +-532, -560, -156, -436, 546, 352, 445, 514, +-389, -141, -681, -524, 91, -79, 750, 470, +302, 215, -609, -318, -623, -281, 294, 138, +780, 262, 115, -19, -714, -124, -461, -70, +433, -48, 660, 9, -38, 167, -658, 203, +-325, -176, 464, -357, 605, -1, -175, 431, +-734, 202, -170, -420, 697, -360, 528, 287, +-488, 560, -763, -91, 116, -661, 845, -225, +279, 565, -716, 556, -607, -320, 405, -698, +835, -35, -26, 677, -805, 349, -387, -551, +593, -592, 668, 301, -272, 767, -726, 45, +-103, -787, 672, -420, 353, 601, -458, 702, +-528, -241, 172, -817, 557, -138, 91, 709, +-393, 488, -336, -431, 184, -724, 395, 88, +95, 718, -338, 320, -344, -566, 222, -618, +429, 283, 32, 710, -481, 136, -230, -691, +417, -452, 410, 436, -226, 650, -565, -68, +13, -759, 540, -239, 266, 608, -350, 599, +-434, -327, 54, -820, 386, -55, 218, 729, +-227, 503, -308, -471, 22, -701, 327, 90, +112, 662, -285, 295, -251, -539, 177, -528, +406, 253, -17, 677, -432, 134, -214, -666, +342, -473, 375, 373, -136, 678, -390, 12, +-127, -667, 290, -321, 289, 456, -55, 576, +-385, -154, -156, -713, 339, -215, 319, 601, +-184, 610, -438, -307, 63, -800, 418, -97, +120, 715, -367, 501, -288, -501, 266, -707, +328, 151, -53, 770, -349, 283, -88, -686, +275, -600, 149, 333, -136, 789, -217, 89, +79, -772, 223, -403, 7, 517, -199, 659, +-143, -242, 163, -752, 222, -71, -5, 661, +-226, 420, -162, -491, 128, -618, 232, 170, +63, 669, -230, 181, -178, -618, 170, -432, +270, 382, -90, 620, -373, -84, -41, -660, +385, -193, 264, 505, -259, 449, -449, -266, +-4, -522, 430, -4, 253, 447, -326, 263, +-363, -281, 194, -372, 412, 35, -77, 359, +-473, 202, -75, -242, 469, -323, 279, 21, +-341, 330, -430, 172, 150, -246, 471, -272, +78, 95, -412, 323, -302, 23, 263, -350, +471, -149, 14, 306, -491, 336, -296, -193, +371, -465, 427, -25, -172, 440, -472, 285, +-8, -297, 478, -392, 186, 84, -374, 379, +-420, 91, 167, -349, 535, -187, 121, 249, +-439, 312, -396, -95, 260, -368, 467, -89, +-32, 258, -464, 286, -197, -64, 402, -314, +368, -145, -207, 217, -516, 320, -68, -97, +515, -377, 306, -59, -343, 414, -475, 257, +119, -393, 493, -448, 70, 220, -382, 600, +-221, 57, 270, -573, 292, -335, -144, 349, +-318, 470, 5, -77, 318, -412, 132, -131, +-241, 279, -234, 237, 67, -122, 270, -283, +116, -58, -180, 253, -261, 233, -15, -96, +336, -328, 234, -95, -245, 263, -449, 236, +31, -142, 554, -294, 201, 50, -487, 305, +-403, 93, 374, -320, 517, -277, -231, 195, +-586, 432, 16, 90, 602, -454, 230, -364, +-436, 261, -407, 548, 154, -14, 406, -600, +71, -204, -257, 553, -221, 447, 111, -468, +289, -645, 68, 261, -292, 775, -279, 44, +166, -800, 410, -335, 77, 632, -348, 594, +-273, -381, 191, -746, 340, 80, -16, 718, +-336, 252, -130, -612, 300, -502, 281, 391, +-174, 651, -355, -64, -13, -715, 310, -275, +151, 558, -211, 571, -187, -216, 107, -686, +230, -134, -19, 560, -278, 414, -129, -335, +209, -563, 305, 93, -30, 605, -324, 195, +-171, -565, 184, -503, 297, 348, -25, 719, +-295, 24, -133, -730, 259, -394, 291, 527, +-175, 619, -402, -230, -29, -695, 448, -51, +237, 664, -337, 325, -401, -511, 131, -568, +469, 236, 60, 637, -377, 98, -236, -518, +253, -334, 314, 310, -106, 401, -292, -106, +-54, -424, 250, -55, 162, 400, -149, 223, +-209, -273, 0, -365, 215, 89, 87, 338, +-130, 84, -137, -197, 27, -135, 131, 94, +41, 88, -67, -14, -103, -61, -25, -56, +134, -5, 112, 106, -90, 153, -190, -76, +37, -266, 225, -65, -5, 275, -248, 200, +-74, -202, 292, -251, 195, 112, -222, 257, +-307, -44, 46, -259, 324, -25, 106, 222, +-198, 76, -170, -166, 75, -93, 170, 136, +-19, 109, -146, -98, -70, -140, 132, 13, +174, 139, -63, 54, -217, -53, -89, -62, +222, 14, 184, 36, -145, -55, -254, -56, +38, 40, 295, 162, 66, 45, -247, -175, +-174, -150, 158, 70, 223, 197, -64, -28, +-205, -166, -18, 7, 191, 193, 111, 45, +-149, -254, -195, -132, 11, 196, 227, 231, +155, -99, -136, -237, -249, 33, -26, 198, +244, 34, 152, -205, -189, -90, -223, 160, +125, 143, 302, -58, -34, -169, -342, -11, +-108, 122, 297, 69, 240, -71, -181, -116, +-296, 38, 22, 145, 262, 57, 116, -158, +-175, -153, -190, 119, 39, 215, 195, -22, +92, -253, -128, -73, -175, 233, 6, 147, +204, -156, 115, -181, -162, 106, -221, 168, +54, -102, 282, -195, 82, 79, -235, 274, +-201, 21, 115, -268, 235, -160, 7, 152, +-212, 202, -83, -38, 174, -136, 149, 2, +-133, 113, -214, 6, 41, -147, 242, -94, +86, 112, -183, 215, -185, 28, 77, -221, +214, -182, 32, 122, -198, 248, -123, -32, +154, -251, 191, -41, -44, 291, -228, 156, +-93, -308, 164, -330, 178, 199, -24, 490, +-176, 31, -62, -525, 107, -292, 79, 401, +-56, 487, -79, -188, 50, -577, 96, -23, +-24, 573, -129, 243, -51, -518, 112, -457, +121, 381, -30, 620, -128, -118, -50, -682, +80, -176, 82, 576, -35, 386, -83, -352, +9, -494, 81, 158, 21, 500, -59, 36, +-50, -465, 8, -250, 31, 356, 48, 408, +18, -106, -57, -444, -53, -145, 41, 321, +69, 277, -56, -137, -77, -323, 74, -2, +127, 320, -64, 146, -186, -273, -3, -302, +197, 157, 90, 398, -166, 41, -150, -388, +111, -234, 189, 276, -36, 343, -207, -108, +-42, -356, 149, -45, 107, 304, -75, 155, +-113, -211, 27, -232, 75, 93, 13, 278, +-80, 68, -29, -237, 69, -245, 39, 73, +-14, 323, -33, 161, -3, -209, -42, -314, +-20, -7, 81, 278, 85, 164, -37, -136, +-137, -200, -26, 37, 116, 198, 63, 54, +-110, -193, -97, -192, 134, 111, 166, 306, +-100, 101, -246, -289, -3, -303, 242, 123, +115, 364, -159, 65, -156, -331, 85, -173, +170, 279, -36, 263, -206, -219, -44, -396, +230, 84, 184, 465, -160, 141, -287, -393, +10, -338, 279, 214, 118, 390, -205, -8, +-165, -332, 114, -119, 179, 245, -44, 171, +-194, -127, -44, -200, 152, 30, 146, 189, +-75, 66, -184, -108, -18, -158, 182, -8, +101, 152, -179, 132, -160, -50, 136, -196, +232, -45, -66, 142, -266, 105, -12, -82, +238, -103, 85, 86, -219, 86, -127, -86, +205, -141, 193, 62, -139, 172, -263, -30, +41, -149, 256, 5, 71, 169, -180, -11, +-142, -234, 83, -29, 145, 277, 12, 175, +-136, -258, -103, -282, 88, 166, 173, 328, +5, -56, -193, -370, -129, -14, 134, 396, +206, 149, -24, -372, -221, -322, -82, 270, +175, 414, 135, -72, -108, -417, -159, -94, +41, 364, 172, 192, 43, -271, -146, -299, +-148, 158, 83, 352, 214, -17, 48, -309, +-187, -129, -153, 222, 85, 174, 173, -137, +26, -166, -128, 60, -74, 187, 76, -2, +90, -170, -23, -93, -106, 84, -19, 159, +80, 16, 70, -111, -12, -104, -80, 51, +-65, 131, 11, -16, 122, -120, 79, -37, +-126, 146, -176, 79, 60, -122, 265, -109, +38, 57, -278, 127, -165, -45, 226, -106, +268, 23, -123, 97, -308, 28, -11, -93, +306, -54, 155, 13, -225, 41, -277, 41, +58, 3, 310, -7, 133, -32, -227, -5, +-253, -8, 87, -20, 263, 22, 37, 36, +-230, 31, -106, -31, 186, -33, 178, -4, +-106, -14, -258, 7, -25, 36, 234, 56, +164, -24, -130, -62, -202, 2, 35, 20, +154, -15, 21, -52, -125, 49, -32, 98, +122, -1, 67, -85, -92, -70, -121, 21, +40, 14, 113, 21, 28, 71, -59, 44, +-38, -51, 6, -130, -1, -38, 10, 78, +36, 85, 12, 29, -44, -45, -25, -36, +50, -19, 21, 11, -71, -2, -44, -39, +86, 27, 92, 90, -58, 71, -127, -82, +0, -144, 99, -21, 41, 85, -47, 91, +-34, 9, 30, -11, 24, -37, -31, -61, +-62, -10, -13, 42, 96, 56, 87, -24, +-47, -22, -151, 35, -21, 23, 123, -32, +53, -80, -74, 15, -61, 87, 74, 47, +59, -61, -63, -100, -83, 27, 24, 121, +115, 56, 16, -131, -105, -162, -77, 52, +88, 211, 127, 100, -43, -149, -155, -167, +-33, 29, 135, 131, 63, 33, -86, -92, +-52, -22, 69, 93, 32, 64, -93, -64, +-31, -136, 83, -22, 45, 97, -62, 110, +-20, 4, 78, -100, 3, -48, -114, 30, +-48, 61, 113, -37, 104, -86, -61, 34, +-98, 137, 16, 83, 63, -155, -13, -190, +-51, 33, 21, 211, 53, 101, 7, -177, +-21, -138, -26, 112, -23, 185, -8, -74, +42, -250, 52, 0, -13, 252, -60, 142, +-36, -197, 44, -213, 61, 92, -4, 211, +-83, 13, -60, -185, 71, -59, 119, 133, +-13, 104, -157, -69, -63, -134, 144, 15, +124, 124, -101, 50, -168, -107, 66, -109, +204, 62, 0, 132, -213, -1, -75, -135, +195, -55, 161, 102, -124, 78, -223, -62, +4, -95, 242, 25, 131, 98, -174, 26, +-232, -58, 52, -70, 261, -20, 64, 46, +-222, 84, -147, 35, 159, -85, 217, -84, +-90, 39, -265, 100, -42, -1, 267, -101, +182, -11, -186, 86, -267, 54, 39, -61, +275, -68, 85, 16, -218, 30, -166, 10, +134, -16, 246, 1, -22, 5, -255, -7, +-113, 2, 192, -20, 221, -18, -81, 9, +-245, 45, -37, 26, 228, -45, 142, -57, +-183, -6, -229, 64, 100, 54, 294, -16, +24, -77, -307, -61, -161, 46, 245, 111, +281, 42, -117, -107, -353, -119, -37, 43, +336, 140, 211, 18, -246, -138, -316, -63, +115, 134, 345, 110, 32, -109, -334, -178, +-140, 39, 268, 214, 239, 46, -152, -181, +-313, -118, 20, 137, 293, 159, 122, -99, +-188, -190, -213, 16, 70, 204, 212, 60, +68, -157, -154, -94, -183, 79, 64, 91, +219, -60, 73, -49, -211, 62, -206, 33, +149, -60, 270, -22, -9, 88, -299, -17, +-115, -134, 263, -5, 209, 183, -162, 78, +-295, -184, 56, -116, 303, 152, 66, 153, +-261, -130, -206, -195, 174, 84, 285, 222, +-4, 34, -302, -187, -167, -113, 213, 86, +258, 120, -59, -15, -282, -108, -48, -16, +243, 134, 131, 97, -174, -143, -214, -230, +97, 34, 240, 302, 32, 131, -208, -234, +-149, -223, 109, 135, 184, 251, 2, -63, +-162, -287, -90, -54, 123, 299, 149, 244, +-40, -175, -183, -380, -70, -87, 159, 344, +151, 295, -62, -162, -181, -367, -25, -15, +158, 347, 92, 123, -93, -313, -139, -251, +47, 227, 165, 356, 36, -80, -162, -360, +-125, -85, 118, 289, 175, 174, -39, -187, +-194, -213, -40, 87, 174, 242, 108, 19, +-118, -196, -153, -129, 26, 93, 133, 163, +65, 1, -49, -111, -87, -58, -38, 72, +55, 66, 82, -58, -6, -80, -84, 4, +-26, 104, 89, 51, 56, -61, -68, -91, +-120, -5, 5, 104, 149, 45, 92, -89, +-98, -97, -169, 60, 9, 166, 169, -8, +90, -185, -101, -100, -154, 135, 28, 160, +152, -60, 59, -140, -131, 8, -131, 138, +77, 16, 153, -138, 15, -68, -157, 96, +-103, 123, 126, -10, 177, -96, -33, -58, +-224, -11, -58, 31, 209, 70, 141, 56, +-138, -52, -211, -100, 61, 24, 226, 110, +26, -7, -209, -150, -134, -35, 179, 198, +200, 149, -88, -153, -242, -269, -26, 16, +231, 295, 102, 134, -150, -210, -162, -237, +74, 116, 176, 262, -9, -15, -159, -279, +-56, -103, 151, 270, 111, 218, -115, -170, +-159, -321, 36, 17, 194, 338, 46, 134, +-166, -249, -122, -250, 94, 135, 162, 284, +-40, -5, -148, -252, -19, -115, 129, 197, +81, 174, -116, -99, -112, -207, 52, -6, +162, 198, 21, 79, -162, -141, -84, -140, +95, 77, 156, 172, -32, -17, -159, -160, +-57, -71, 123, 146, 148, 138, -63, -95, +-167, -181, -34, -18, 161, 191, 89, 113, +-119, -101, -89, -161, 52, -19, 93, 120, +-36, 79, -57, -32, 15, -65, 10, -7, +2, 49, -4, 14, 50, -65, -26, -75, +-72, 51, 15, 158, 91, 69, 30, -150, +-121, -204, -59, 11, 82, 230, 121, 125, +-17, -140, -136, -176, -44, 53, 85, 166, +114, -14, -38, -169, -121, -72, -28, 159, +125, 182, 92, -22, -137, -218, -141, -166, +79, 118, 190, 271, -13, 66, -175, -268, +-41, -214, 135, 178, 97, 302, -111, -55, +-126, -367, 67, -73, 165, 356, 6, 229, +-191, -301, -68, -370, 154, 200, 129, 479, +-120, -5, -160, -537, 86, -256, 177, 441, +-29, 466, -197, -178, -24, -533, 195, -72, +101, 428, -160, 204, -162, -313, 107, -300, +196, 239, -14, 405, -195, -72, -70, -460, +129, -175, 116, 344, -49, 325, -105, -110, +-5, -283, 60, -35, 26, 171, -27, 55, +-51, -113, -3, -75, 66, 71, 57, 130, +-43, 39, -103, -116, -11, -166, 87, -25, +76, 212, -36, 161, -104, -111, -8, -257, +96, -15, 53, 271, -70, 119, -72, -220, +18, -235, 64, 136, 54, 302, -26, -14, +-90, -281, -55, -126, 90, 234, 111, 209, +-62, -115, -127, -263, 3, -31, 104, 260, +56, 167, -48, -143, -94, -253, -51, -3, +128, 239, 125, 107, -104, -166, -195, -184, +64, 99, 239, 234, -5, 3, -227, -245, +-95, -153, 186, 184, 176, 231, -91, -25, +-203, -228, -22, -105, 200, 136, 94, 145, +-133, -26, -138, -162, 74, -36, 123, 150, +-29, 105, -77, -96, 2, -176, 37, 26, +0, 157, 11, 72, -16, -85, -45, -129, +30, 0, 84, 115, -6, 91, -113, -110, +-32, -152, 86, 88, 72, 214, -24, -22, +-87, -264, -23, -77, 46, 241, 104, 149, +-16, -134, -132, -192, -42, 33, 150, 152, +114, 47, -152, -93, -163, -115, 104, 53, +219, 161, -46, 40, -267, -186, -16, -159, +257, 139, 116, 235, -223, -26, -158, -255, +120, -72, 188, 214, -8, 133, -188, -150, +-105, -192, 154, 86, 218, 210, -104, 37, +-288, -184, 18, -130, 293, 90, 63, 169, +-257, 24, -109, -162, 195, -110, 151, 103, +-109, 177, -173, -23, 17, -217, 161, -83, +94, 177, -129, 173, -152, -100, 52, -178, +169, 59, -1, 155, -146, -51, -37, -171, +89, 58, 57, 192, -43, -15, -56, -165, +5, -6, 21, 125, 30, -24, -19, -107, +-18, 46, -20, 122, 36, -36, 35, -117, +-23, 36, -52, 106, -29, -60, 67, -156, +99, 35, -2, 210, -160, 37, -80, -189, +181, -119, 139, 152, -147, 105, -195, -100, +116, -121, 210, 112, -66, 155, -202, -71, +-9, -164, 177, -13, 57, 131, -109, 56, +-100, -70, 27, -45, 115, 8, 65, 58, +-75, 22, -144, -19, -14, -96, 173, -72, +116, 110, -122, 203, -221, 18, 48, -282, +257, -196, 66, 215, -257, 353, -159, -78, +202, -450, 242, -102, -101, 494, -287, 318, +-28, -433, 270, -531, 134, 282, -196, 637, +-198, -78, 103, -669, 211, -93, 6, 643, +-182, 297, -111, -574, 122, -536, 196, 354, +-24, 696, -222, -4, -81, -688, 207, -298, +132, 527, -136, 474, -128, -366, 83, -597, +89, 225, -61, 689, -14, -9, 44, -718, +-26, -235, -60, 623, 48, 390, 80, -446, +-27, -464, -93, 350, -33, 481, 99, -269, +103, -528, -86, 183, -171, 559, 50, -92, +228, -534, 11, 20, -240, 513, -101, 13, +219, -514, 194, -88, -131, 527, -265, 213, +14, -500, 276, -357, 110, 388, -205, 515, +-185, -230, 117, -626, 192, -3, -17, 632, +-137, 284, -64, -550, 95, -485, 115, 324, +-11, 615, -160, -76, -63, -630, 175, -181, +126, 520, -105, 436, -184, -312, 25, -583, +173, 13, 87, 585, -109, 302, -183, -460, +64, -515, 204, 208, 31, 654, -210, 64, +-78, -667, 181, -340, 107, 546, -106, 611, +-159, -330, 49, -724, 171, 9, 52, 695, +-138, 305, -147, -560, 106, -488, 187, 275, +-16, 649, -202, 4, -56, -660, 200, -295, +126, 511, -122, 591, -212, -307, 40, -685, +245, 3, 92, 655, -200, 281, -188, -571, +142, -446, 236, 319, -16, 620, -255, -37, +-74, -651, 236, -271, 184, 464, -133, 577, +-271, -194, 23, -655, 270, -150, 181, 567, +-184, 443, -322, -403, 49, -598, 404, 117, +156, 672, -404, 191, -323, -581, 327, -440, +461, 314, -146, 592, -525, -17, -18, -555, +510, -277, 212, 388, -396, 515, -332, -138, +256, -597, 398, -208, -45, 515, -354, 504, +-138, -267, 254, -635, 282, -79, -36, 623, +-336, 381, -160, -473, 326, -643, 349, 185, +-197, 808, -452, 199, 64, -734, 484, -569, +96, 452, -396, 763, -202, -95, 309, -735, +290, -229, -154, 586, -264, 468, 7, -357, +229, -634, 100, 35, -63, 649, -134, 336, +-89, -495, 145, -601, 252, 173, -7, 696, +-372, 175, -137, -629, 443, -452, 341, 414, +-342, 654, -514, -93, 232, -704, 613, -247, +-18, 554, -603, 562, -180, -299, 565, -746, +387, -31, -387, 796, -513, 405, 164, -726, +588, -724, 103, 479, -477, 929, -303, -120, +307, -962, 474, -220, -46, 823, -447, 522, +-178, -557, 350, -775, 387, 166, -118, 849, +-410, 370, -113, -680, 343, -837, 314, 259, +-164, 1062, -348, 314, -43, -1022, 341, -842, +256, 716, -170, 1238, -330, -166, -43, -1409, +363, -495, 273, 1224, -173, 1102, -368, -688, +-68, -1466, 403, -13, 333, 1460, -194, 756, +-520, -1112, -59, -1356, 571, 442, 404, 1627, +-360, 429, -642, -1428, 67, -1215, 712, 773, +375, 1603, -518, 128, -660, -1518, 215, -934, +834, 971, 282, 1463, -758, -133, -657, -1584, +473, -764, 979, 1141, 45, 1507, -1035, -281, +-516, -1755, 799, -749, 999, 1373, -347, 1623, +-1165, -545, -153, -2022, 1072, -508, 718, 1862, +-699, 1547, -964, -1233, 172, -2211, 1013, 168, +457, 2377, -732, 999, -800, -1916, 214, -1901, +994, 907, 360, 2288, -779, 288, -786, -2028, +328, -1287, 1063, 1194, 227, 1879, -920, -132, +-747, -1866, 602, -886, 1139, 1302, -56, 1603, +-1138, -408, -515, -1766, 974, -568, 985, 1365, +-453, 1301, -1142, -586, -126, -1543, 1110, -351, +619, 1268, -687, 1104, -906, -590, 210, -1453, +942, -267, 285, 1318, -619, 999, -630, -759, +253, -1381, 767, 6, 217, 1313, -566, 672, +-555, -821, 319, -1096, 709, 133, 140, 1084, +-606, 540, -497, -667, 374, -982, 739, 50, +28, 996, -764, 561, -380, -626, 649, -972, +649, 94, -318, 980, -699, 488, 31, -664, +618, -913, 273, 127, -327, 929, -354, 527, +72, -570, 364, -968, 196, -71, -196, 945, +-303, 754, 9, -536, 339, -1176, 223, -97, +-256, 1190, -354, 788, 119, -871, 460, -1302, +98, 229, -424, 1479, -216, 540, 350, -1210, +384, -1190, -193, 603, -433, 1458, 93, 158, +481, -1312, 63, -804, -453, 863, -159, 1158, +420, -230, 251, -1183, -339, -398, -309, 903, +260, 791, 373, -357, -132, -880, -393, -177, +15, 657, 415, 488, 199, -208, -308, -570, +-340, -183, 197, 354, 424, 412, 29, 26, +-375, -404, -199, -326, 267, 106, 272, 459, +-45, 276, -293, -351, -134, -551, 213, 18, +258, 690, 27, 351, -339, -587, -209, -683, +283, 263, 440, 849, -25, 175, -567, -716, +-180, -594, 480, 336, 466, 769, -245, 205, +-654, -676, -27, -672, 601, 340, 390, 921, +-449, 190, -661, -949, 176, -707, 700, 664, +237, 1067, -590, -83, -511, -1205, 309, -493, +635, 937, 122, 976, -561, -432, -432, -1230, +320, -128, 624, 1134, 34, 684, -651, -799, +-385, -1071, 419, 305, 637, 1143, -65, 298, +-716, -960, -402, -739, 544, 514, 775, 934, +-178, 49, -920, -847, -305, -494, 830, 478, +745, 743, -491, -3, -979, -721, -22, -412, +1013, 433, 486, 681, -805, -42, -881, -695, +330, -348, 1074, 475, 91, 644, -1006, -108, +-536, -708, 686, -314, 816, 515, -322, 634, +-805, -148, -124, -729, 628, -265, 476, 569, +-355, 600, -589, -252, -91, -777, 555, -151, +394, 727, -377, 574, -604, -459, -25, -870, +610, 28, 267, 885, -468, 448, -460, -632, +155, -764, 500, 232, 13, 817, -379, 194, +-196, -665, 217, -526, 248, 393, -86, 685, +-228, -11, -129, -675, 120, -372, 174, 469, +-29, 612, -213, -75, -150, -672, 104, -343, +113, 496, 3, 619, -146, -133, -116, -740, +63, -228, 84, 645, -27, 535, -108, -368, +33, -735, 25, 14, -121, 707, 3, 363, +129, -473, -38, -647, -289, 125, -76, 683, +294, 278, 114, -548, -305, -565, -320, 277, +101, 670, 337, 72, 69, -629, -344, -344, +-305, 416, 175, 496, 397, -107, -39, -518, +-454, -151, -189, 341, 304, 321, 306, -82, +-201, -339, -478, -126, -105, 176, 363, 251, +247, 43, -283, -220, -402, -207, -46, 52, +252, 279, 218, 134, -78, -223, -354, -266, +-256, 65, 226, 307, 434, 98, -61, -247, +-591, -211, -311, 111, 450, 229, 512, 45, +-292, -175, -794, -106, -183, 53, 699, 97, +478, 68, -559, -17, -839, -72, 105, -155, +827, -14, 249, 296, -705, 199, -673, -264, +275, -486, 781, 122, 114, 667, -815, 158, +-627, -641, 433, -506, 801, 483, -77, 736, +-931, -170, -502, -779, 578, -248, 731, 691, +-242, 565, -933, -392, -272, -736, 707, -9, +551, 719, -475, 315, -845, -526, 57, -466, +784, 253, 210, 488, -716, -51, -610, -381, +383, -69, 587, 206, -190, 109, -654, -48, +-179, -38, 437, -23, 150, -106, -386, -4, +-255, 168, 148, 129, 194, -81, -210, -272, +-257, -91, 93, 238, 169, 320, -119, -44, +-362, -471, -51, -199, 300, 428, 49, 486, +-365, -225, -403, -707, 129, -45, 429, 690, +-26, 444, -548, -518, -425, -723, 288, 168, +552, 755, -80, 301, -677, -573, -428, -626, +474, 157, 630, 674, -296, 360, -871, -484, +-266, -698, 722, 38, 540, 815, -558, 517, +-952, -651, -94, -986, 862, 153, 503, 1199, +-675, 527, -1009, -1021, -12, -1139, 990, 455, +494, 1408, -832, 314, -1049, -1243, 204, -977, +1103, 704, 294, 1309, -1062, 40, -942, -1255, +467, -758, 1086, 827, 11, 1210, -1163, -90, +-707, -1295, 583, -677, 884, 916, -97, 1228, +-1006, -163, -565, -1373, 490, -645, 795, 1025, +-51, 1250, -942, -326, -570, -1464, 474, -462, +821, 1223, -90, 1095, -1020, -600, -575, -1383, +512, -169, 851, 1179, -91, 837, -1059, -568, +-633, -1133, 528, -220, 926, 937, -104, 872, +-1096, -322, -583, -1158, 592, -397, 905, 953, +-203, 1020, -1111, -379, -483, -1306, 664, -343, +828, 1123, -312, 1022, -1063, -559, -466, -1415, +603, -199, 849, 1303, -224, 988, -1129, -773, +-619, -1473, 727, -7, 1055, 1418, -327, 839, +-1345, -942, -528, -1376, 1017, 208, 994, 1403, +-606, 616, -1385, -1059, -296, -1205, 1161, 433, +805, 1349, -826, 376, -1336, -1135, -58, -1021, +1159, 583, 575, 1227, -854, 218, -1171, -1074, +58, -831, 1073, 576, 445, 1030, -881, 131, +-1024, -913, 208, -660, 980, 500, 272, 881, +-908, 148, -890, -819, 279, -698, 895, 416, +165, 958, -900, 252, -764, -870, 288, -827, +766, 420, 118, 1043, -789, 236, -656, -897, +259, -792, 698, 477, 59, 979, -758, 158, +-517, -876, 313, -726, 523, 497, -77, 975, +-575, 167, -373, -918, 115, -794, 331, 522, +77, 1068, -375, 229, -465, -1013, -70, -887, +302, 548, 242, 1200, -251, 245, -550, -1156, +-218, -943, 375, 666, 444, 1310, -291, 148, +-760, -1320, -257, -914, 590, 813, 547, 1404, +-452, 73, -944, -1473, -213, -974, 749, 972, +559, 1591, -557, -39, -1013, -1728, -158, -895, +854, 1285, 559, 1572, -636, -423, -1080, -1811, +-63, -523, 1013, 1505, 529, 1307, -853, -705, +-1164, -1718, 172, -277, 1187, 1516, 336, 1151, +-1103, -769, -1100, -1604, 447, -193, 1211, 1440, +71, 1022, -1220, -753, -847, -1467, 651, -120, +1017, 1362, -166, 911, -1088, -782, -588, -1384, +640, -46, 816, 1349, -222, 808, -978, -792, +-512, -1291, 577, -13, 712, 1262, -219, 750, +-876, -711, -469, -1210, 451, -35, 623, 1155, +-94, 706, -746, -644, -542, -1110, 324, -45, +698, 1044, 28, 684, -808, -544, -640, -1077, +373, -180, 831, 994, -19, 882, -957, -440, +-677, -1262, 489, -371, 913, 1160, -90, 1074, +-1072, -551, -665, -1442, 614, -259, 937, 1336, +-222, 959, -1108, -745, -503, -1380, 698, -52, +794, 1356, -300, 800, -1019, -824, -430, -1330, +655, 72, 756, 1376, -285, 690, -1042, -931, +-430, -1219, 679, 252, 748, 1269, -331, 476, +-1030, -910, -349, -973, 657, 285, 710, 1076, +-334, 416, -1012, -806, -327, -902, 699, 237, +724, 1056, -432, 397, -1042, -819, -236, -830, +758, 277, 659, 981, -548, 276, -990, -737, +-130, -698, 762, 268, 514, 849, -586, 224, +-834, -642, -54, -628, 655, 259, 413, 745, +-516, 195, -728, -564, -34, -564, 610, 228, +294, 645, -509, 195, -572, -497, 51, -489, +390, 191, 156, 497, -279, 186, -409, -312, +-150, -383, 171, -37, 308, 336, -56, 414, +-464, -92, -322, -600, 123, -301, 467, 537, +60, 702, -553, -273, -487, -893, 153, -152, +654, 826, 88, 589, -722, -525, -581, -826, +233, 58, 806, 779, 93, 442, -882, -508, +-683, -741, 406, 56, 963, 752, -56, 447, +-1046, -542, -557, -745, 592, 110, 896, 746, +-187, 398, -1080, -527, -494, -678, 719, 52, +912, 696, -379, 483, -1180, -486, -277, -789, +841, 18, 692, 825, -472, 497, -1015, -608, +-190, -803, 751, 138, 660, 828, -485, 393, +-1013, -629, -65, -732, 821, 187, 468, 806, +-586, 340, -811, -669, 39, -694, 631, 261, +369, 805, -460, 293, -746, -675, -28, -680, +613, 258, 345, 827, -478, 281, -641, -749, +34, -647, 482, 404, 260, 807, -337, 90, +-549, -759, -81, -480, 446, 419, 349, 694, +-332, 86, -623, -728, -27, -495, 489, 462, +259, 748, -390, -70, -485, -804, 6, -269, +338, 599, 228, 500, -231, -239, -433, -569, +-154, -124, 302, 411, 353, 395, -210, -82, +-477, -529, -168, -229, 330, 420, 321, 464, +-155, -170, -467, -579, -308, -82, 332, 462, +550, 316, -159, -206, -791, -442, -298, -67, +725, 308, 519, 353, -568, -76, -752, -456, +159, -208, 669, 336, 114, 465, -510, -126, +-409, -566, 82, -163, 401, 491, 226, 462, +-369, -260, -529, -645, 44, -93, 517, 601, +175, 476, -499, -361, -379, -694, 108, -9, +360, 707, 132, 402, -324, -492, -354, -731, +-36, 174, 390, 829, 210, 284, -342, -771, +-377, -677, -30, 529, 346, 886, 230, -155, +-235, -908, -458, -177, -195, 777, 481, 343, +421, -490, -377, -419, -695, 257, -12, 328, +702, -67, 295, -151, -618, 4, -586, -34, +186, -39, 685, 128, 116, 187, -642, -152, +-474, -278, 296, 61, 590, 321, -14, 34, +-613, -278, -279, -104, 252, 209, 403, 60, +30, -87, -406, -17, -371, 95, 68, -151, +563, -129, 224, 243, -617, 246, -567, -265, +318, -410, 784, 186, -39, 558, -878, -39, +-358, -569, 616, -222, 637, 502, -341, 443, +-841, -317, -38, -562, 674, 21, 358, 582, +-500, 249, -587, -511, 182, -442, 488, 337, +101, 570, -366, -119, -316, -640, 70, -2, +241, 513, 179, 117, -110, -396, -409, -92, +-169, 322, 335, -39, 412, -304, -226, 168, +-663, 342, -47, -193, 615, -502, 323, 236, +-505, 621, -650, -119, 250, -742, 690, -141, +94, 790, -733, 477, -453, -645, 593, -836, +587, 333, -367, 1108, -759, 150, 96, -1277, +725, -665, 13, 1205, -625, 1254, -232, -921, +489, -1757, 275, 480, -452, 2031, -290, 88, +285, -2086, 315, -676, -291, 2033, -371, 1098, +239, -1724, 333, -1484, -197, 1402, -403, 1702, +96, -1085, 396, -1773, -63, 773, -403, 1838, +-68, -495, 353, -1955, 114, 214, -365, 2019, +-203, 192, 330, -2026, 190, -693, -303, 1951, +-295, 1198, 279, -1694, 352, -1710, -308, 1240, +-444, 2144, 174, -608, 572, -2352, -73, -104, +-736, 2244, -96, 769, 713, -1894, 313, -1264, +-678, 1402, -575, 1469, 548, -820, 626, -1444, +-267, 263, -693, 1241, -63, 62, 615, -803, +221, -268, -363, 433, -413, 279, 88, -155, +415, -181, 50, -65, -233, 118, -249, 193, +-2, -52, 213, -250, 177, -6, -53, 331, +-396, -2, -190, -387, 438, -67, 388, 518, +-330, 156, -628, -541, 128, -387, 708, 489, +80, 593, -642, -283, -333, -718, 428, -52, +507, 744, -251, 409, -533, -579, -63, -728, +486, 193, 327, 967, -489, 236, -474, -906, +327, -737, 613, 633, -200, 1135, -800, -213, +145, -1253, 789, -372, -23, 1179, -779, 924, +-180, -859, 811, -1315, 226, 296, -684, 1524, +-363, 319, 479, -1475, 508, -888, -361, 1172, +-505, 1325, 157, -708, 414, -1560, 13, 134, +-322, 1566, -71, 341, 152, -1231, -2, -779, +70, 834, 57, 950, -188, -414, -189, -860, +164, -41, 375, 743, -168, 297, -445, -494, +49, -366, 397, 147, 123, 380, -383, 13, +-192, -180, 246, -101, 199, -25, -76, 60, +-214, 185, -17, 38, 131, -261, 97, -172, +-38, 273, -179, 293, -50, -258, 253, -288, +103, 190, -294, 223, -224, -173, 381, -198, +344, 318, -483, 102, -457, -381, 477, -156, +650, 432, -443, 280, -862, -440, 353, -385, +958, 274, -88, 511, -1024, 52, -208, -568, +973, -444, 456, 369, -718, 888, -703, -15, +394, -1159, 823, -455, -73, 1227, -717, 926, +-293, -1089, 516, -1329, 535, 760, -231, 1561, +-586, -300, -114, -1540, 519, -178, 398, 1272, +-315, 497, -565, -873, 81, -575, 544, 446, +229, 516, -467, -136, -412, -310, 269, -37, +444, -2, 67, 116, -463, 251, -269, 7, +305, -439, 372, -187, -11, 510, -475, 338, +-148, -464, 373, -448, 319, 371, -171, 526, +-431, -277, -42, -517, 440, 167, 244, 494, +-297, -84, -469, -465, 154, 17, 603, 493, +16, 71, -625, -516, -229, -233, 587, 512, +460, 449, -546, -441, -569, -640, 381, 289, +683, 788, -157, -59, -755, -889, -10, -198, +688, 866, 240, 452, -489, -716, -489, -623, +265, 517, 632, 651, 81, -353, -647, -568, +-511, 273, 620, 459, 848, -317, -350, -378, +-1107, 455, -21, 387, 1209, -683, 480, -522, +-1077, 864, -879, 861, 732, -917, 1184, -1287, +-210, 744, -1307, 1672, -314, -341, 1152, -1865, +852, -214, -785, 1838, -1235, 780, 309, -1522, +1338, -1245, 265, 945, -1180, 1514, -733, -242, +810, -1451, 981, -425, -243, 1073, -964, 911, +-325, -542, 744, -1088, 761, -5, -255, 939, +-996, 472, -276, -604, 995, -676, 724, 117, +-650, 599, -1049, 342, 230, -269, 1094, -604, +291, -235, -884, 580, -747, 726, 553, -292, +1046, -1059, -83, -173, -1147, 1134, -359, 701, +1122, -971, 669, -1134, -879, 589, -877, 1400, +659, -93, 909, -1418, -382, -446, -862, 1256, +200, 817, 763, -825, -57, -1079, -635, 360, +-33, 1093, 553, 81, 97, -894, -439, -467, +-112, 619, 311, 691, 162, -289, -209, -746, +-93, -90, 79, 733, 25, 372, 16, -543, +82, -596, 23, 306, -247, 703, -91, -73, +390, -711, 263, -168, -393, 676, -549, 343, +398, -539, 769, -536, -218, 385, -901, 619, +-34, -194, 971, -608, 261, -16, -827, 572, +-440, 143, 608, -463, 523, -228, -367, 319, +-438, 278, 178, -196, 277, -215, -113, 101, +-55, 101, 159, -89, -23, 0, -353, 158, +34, -36, 544, -257, 138, -40, -612, 352, +-475, 209, 623, -335, 775, -477, -411, 166, +-991, 784, 59, 165, 1123, -959, 286, -685, +-1003, 960, -608, 1255, 718, -701, 827, -1715, +-389, 187, -807, 1971, 21, 512, 674, -1920, +220, -1207, -418, 1469, -327, 1794, 198, -738, +291, -2049, -19, -184, -162, 1935, -39, 1045, +66, -1395, -25, -1710, 3, 573, 128, 1957, +49, 384, -180, -1709, -230, -1217, 190, 1031, +404, 1724, -57, -124, -520, -1729, -195, -847, +601, 1336, 387, 1595, -453, -561, -560, -2001, +226, -432, 640, 1970, 24, 1370, -486, -1462, +-279, -2091, 261, 632, 408, 2426, 19, 290, +-352, -2311, -272, -1169, 190, 1847, 391, 1837, +47, -1139, -319, -2186, -244, 273, 86, 2186, +357, 564, 192, -1843, -252, -1212, -474, 1251, +-3, 1577, 684, -545, 314, -1641, -679, -140, +-654, 1423, 506, 709, 948, -965, -269, -1078, +-1023, 354, -72, 1213, 952, 270, 375, -1031, +-778, -867, -527, 647, 512, 1271, 559, -108, +-228, -1395, -495, -558, 39, 1290, 352, 1105, +64, -883, -160, -1479, -145, 277, 47, 1649, +127, 349, 31, -1470, -83, -979, -94, 1053, +96, 1410, 97, -459, -73, -1549, -140, -223, +45, 1428, 194, 785, 29, -1028, -252, -1189, +-112, 474, 262, 1328, 255, 121, -224, -1189, +-387, -668, 131, 838, 463, 985, 33, -320, +-440, -1079, -255, -181, 343, 935, 374, 567, +-91, -576, -440, -835, -185, 169, 360, 857, +397, 267, -127, -644, -524, -630, -162, 341, +488, 718, 401, 58, -227, -652, -590, -361, +-73, 465, 552, 495, 392, -172, -331, -524, +-641, -86, 11, 407, 656, 265, 406, -174, +-517, -326, -704, -76, 172, 212, 873, 255, +218, 7, -837, -275, -548, -276, 590, 177, +773, 465, -271, 43, -768, -556, -64, -338, +569, 509, 345, 592, -314, -282, -388, -739, +-42, -64, 293, 738, 265, 397, -70, -510, +-314, -664, -231, 157, 201, 797, 448, 227, +45, -713, -542, -597, -355, 486, 467, 848, +652, -190, -280, -897, -807, -156, -16, 826, +826, 403, 329, -654, -710, -551, -556, 408, +443, 615, 689, -152, -136, -584, -719, -49, +-146, 445, 617, 185, 391, -283, -454, -271, +-541, 175, 275, 267, 552, -68, -87, -243, +-505, -8, -70, 253, 391, 3, 153, -232, +-194, 24, -232, 223, 3, -29, 185, -288, +248, 68, -113, 351, -431, -101, -90, -395, +564, 58, 377, 486, -603, 13, -671, -570, +424, -124, 1003, 558, -137, 333, -1199, -483, +-295, -534, 1201, 318, 823, 673, -1040, -61, +-1257, -741, 637, -267, 1518, 720, -24, 589, +-1624, -511, -562, -857, 1353, 138, 1116, 988, +-825, 283, -1455, -881, 169, -674, 1437, 550, +533, 931, -1087, -142, -1057, -937, 487, -280, +1276, 696, 226, 595, -1134, -339, -844, -655, +688, -67, 1228, 446, -89, 391, -1255, -114, +-517, -439, 968, -294, 953, 246, -489, 623, +-1072, 95, -102, -695, 935, -553, 580, 548, +-559, 941, -819, -189, 11, -1120, 821, -313, +494, 1042, -543, 832, -817, -731, 44, -1173, +922, 174, 481, 1278, -729, 488, -916, -1105, +305, -1025, 1139, 608, 218, 1346, -1085, 64, +-679, -1358, 764, -669, 981, 985, -294, 1094, +-1021, -397, -170, -1220, 794, -198, 568, 1003, +-411, 634, -721, -567, -34, -871, 618, 147, +447, 830, -338, 212, -645, -617, -80, -455, +633, 366, 523, 474, -418, -101, -806, -350, +13, -91, 969, 156, 418, 110, -859, 51, +-835, -12, 576, -181, 1129, -140, -149, 214, +-1213, 283, -363, -127, 1128, -431, 822, -2, +-811, 503, -1179, 185, 344, -465, 1388, -423, +175, 358, -1300, 604, -741, -163, 1014, -660, +1177, -132, -523, 683, -1357, 354, -90, -557, +1307, -556, 648, 342, -973, 725, -1035, -124, +440, -741, 1203, -160, 157, 684, -1036, 424, +-709, -566, 626, -607, 1111, 305, -57, 770, +-1183, -13, -634, -780, 1035, -326, 1175, 671, +-523, 636, -1534, -437, -126, -870, 1550, 82, +828, 1016, -1177, 340, -1385, -962, 554, -829, +1600, 703, 263, 1221, -1420, -249, -979, -1377, +876, -363, 1442, 1320, -70, 902, -1527, -969, +-713, -1332, 1213, 399, 1369, 1552, -611, 260, +-1683, -1447, -115, -910, 1656, 1041, 802, 1409, +-1272, -431, -1317, -1593, 689, -295, 1541, 1480, +2, 966, -1435, -1019, -628, -1446, 1059, 295, +1083, 1584, -502, 512, -1217, -1272, -125, -1209, +1081, 669, 655, 1569, -690, 111, -960, -1556, +167, -866, 1008, 1273, 376, 1397, -780, -711, +-778, -1683, 362, 61, 990, 1653, 157, 503, +-945, -1292, -627, -915, 700, 803, 999, 1037, +-283, -278, -1176, -926, -212, -176, 1149, 682, +688, 498, -854, -296, -1086, -663, 441, -164, +1294, 629, 96, 585, -1228, -364, -618, -906, +974, -44, 1023, 983, -471, 499, -1198, -841, +-112, -881, 1107, 523, 723, 1076, -712, -94, +-1156, -1105, 129, -316, 1313, 932, 591, 664, +-1127, -606, -1168, -907, 615, 222, 1532, 945, +116, 218, -1499, -832, -852, -552, 1094, 565, +1472, 742, -399, -242, -1704, -777, -432, -59, +1625, 655, 1186, 291, -1133, -454, -1707, -387, +441, 206, 1918, 361, 325, 29, -1731, -230, +-1002, -141, 1273, 14, 1489, 152, -645, 200, +-1602, -59, -59, -328, 1471, -131, 640, 370, +-1045, 349, -972, -323, 493, -490, 1069, 128, +9, 584, -856, 92, -377, -530, 524, -281, +540, 364, -196, 419, -426, -164, -101, -436, +271, -52, 216, 392, -22, 205, -171, -280, +-177, -307, 78, 131, 240, 354, 138, -41, +-225, -284, -279, -35, 102, 239, 377, 19, +125, -242, -391, 43, -305, 276, 294, -44, +490, -370, -63, -3, -571, 455, -148, 80, +498, -505, 435, -205, -325, 527, -545, 375, +81, -482, 561, -584, 206, 320, -441, 740, +-337, -13, 225, -772, 424, -336, 12, 641, +-360, 605, -180, -337, 260, -752, 326, 2, +-105, 754, -369, 297, -10, -584, 365, -563, +165, 376, -317, 702, -228, -82, 206, -689, +300, -200, -60, 586, -297, 356, -60, -363, +249, -394, 173, 168, -129, 323, -212, -37, +4, -181, 174, -19, 122, 42, -39, 11, +-157, 76, -128, 20, 147, -147, 271, -90, +-12, 188, -349, 119, -157, -195, 339, -115, +330, 198, -185, 103, -472, -273, -15, -133, +518, 352, 298, 216, -424, -398, -531, -409, +245, 340, 676, 623, 30, -161, -684, -782, +-272, -160, 583, 796, 507, 541, -348, -664, +-627, -874, 119, 320, 620, 1073, 217, 139, +-513, -1058, -446, -590, 305, 799, 629, 919, +48, -350, -652, -1059, -370, -118, 566, 940, +679, 556, -268, -617, -834, -835, -40, 209, +835, 882, 415, 256, -605, -698, -660, -575, +306, 352, 748, 686, 129, 84, -674, -553, +-429, -381, 446, 269, 664, 542, -118, 92, +-737, -509, -177, -389, 650, 350, 488, 630, +-446, -56, -687, -705, 169, -268, 741, 612, +201, 538, -689, -342, -490, -653, 466, 36, +713, 591, -168, 185, -786, -411, -159, -310, +731, 210, 429, 305, -576, -73, -608, -223, +364, -39, 684, 110, -127, 14, -681, -44, +-57, 51, 607, 8, 212, -132, -448, -126, +-343, 143, 318, 217, 400, -76, -111, -301, +-388, -94, -49, 258, 334, 205, 190, -136, +-156, -295, -234, -18, 21, 239, 215, 157, +152, -148, -56, -235, -229, 19, -34, 215, +246, 134, 213, -147, -168, -205, -262, 27, +102, 221, 309, 121, 67, -142, -248, -168, +-142, 32, 168, 172, 247, 100, 9, -50, +-252, -109, -101, -73, 236, 72, 237, 199, +-145, 85, -262, -178, 75, -221, 265, 114, +14, 335, -210, 100, -17, -293, 132, -305, +23, 146, -86, 462, 2, 173, 83, -449, +-52, -472, -93, 285, 7, 727, 102, 23, +48, -813, -99, -384, -128, 714, -2, 710, +221, -488, 92, -935, -231, 68, -254, 971, +182, 338, 350, -837, -97, -715, -387, 478, +-75, 920, 359, -119, 188, -1001, -238, -311, +-267, 880, 72, 647, 290, -704, 63, -945, +-189, 346, -145, 1065, 95, -8, 187, -1082, +52, -371, -73, 897, -126, 623, -28, -687, +203, -790, 226, 407, -142, 843, -317, -151, +90, -854, 456, -73, 97, 772, -426, 302, +-178, -662, 372, -456, 338, 544, -178, 623, +-337, -325, 57, -729, 333, 118, 149, 810, +-193, 217, -201, -725, 90, -469, 241, 572, +60, 734, -165, -226, -96, -797, 103, -70, +102, 747, -23, 423, -23, -507, 14, -587, +-61, 244, -60, 659, 132, 108, 145, -551, +-201, -325, -269, 355, 183, 474, 371, -75, +-156, -477, -514, -164, 51, 339, 552, 340, +49, -132, -594, -435, -225, -128, 514, 346, +331, 335, -414, -216, -451, -495, 206, -54, +451, 466, -33, 248, -399, -414, -123, -449, +253, 192, 189, 475, -109, -82, -142, -505, +18, -108, 38, 398, 26, 155, 94, -390, +93, -225, -152, 272, -188, 224, 180, -280, +367, -273, -41, 248, -406, 292, -61, -224, +476, -412, 287, 136, -360, 512, -382, 53, +281, -521, 556, -284, -50, 433, -566, 532, +-74, -174, 603, -603, 332, -85, -486, 602, +-447, 411, 388, -399, 598, -555, -116, 195, +-614, 697, -91, 175, 573, -595, 325, -403, +-382, 465, -492, 661, 211, -113, 544, -684, +-12, -142, -512, 633, -166, 448, 399, -368, +226, -577, -283, 115, -273, 620, 118, 222, +189, -481, -51, -480, -138, 216, -42, 632, +8, 113, -25, -607, 41, -452, 32, 375, +-91, 626, -163, -135, 17, -682, 233, -233, +38, 518, -289, 418, -212, -362, 251, -606, +338, -3, -182, 574, -427, 236, 18, -530, +480, -560, 152, 222, -414, 638, -269, 11, +327, -710, 389, -364, -125, 534, -376, 568, +14, -372, 359, -787, 185, 59, -175, 829, +-225, 233, 80, -802, 324, -542, 142, 619, +-205, 769, -224, -344, 196, -840, 352, 40, +-1, 819, -276, 298, -78, -592, 270, -445, +205, 341, -75, 591, -184, 21, -45, -448, +202, -205, 203, 318, -72, 425, -278, -11, +-49, -319, 311, -132, 181, 254, -257, 306, +-287, 26, 127, -211, 321, -163, -18, 134, +-345, 341, -130, 134, 240, -315, 200, -341, +-190, 227, -315, 561, 46, 28, 275, -631, +36, -323, -318, 531, -201, 561, 209, -301, +220, -715, -134, -34, -324, 631, -33, 263, +261, -505, 105, -515, -178, 189, -210, 490, +26, 8, 193, -494, 107, -303, -107, 238, +-227, 340, -32, -104, 291, -410, 211, -171, +-214, 237, -358, 222, 140, -167, 516, -317, +84, -68, -511, 234, -270, 158, 525, -151, +551, -295, -298, -75, -626, 292, 114, 266, +732, -218, 226, -471, -549, 63, -359, 615, +384, 192, 510, -623, -54, -399, -389, 594, +-99, 653, 258, -346, 244, -734, 8, 189, +-184, 823, -141, 133, 81, -666, 246, -272, +102, 613, -226, 495, -238, -330, 109, -471, +316, 205, 43, 558, -363, 28, -222, -403, +230, -92, 351, 367, -148, 257, -492, -189, +-96, -245, 437, 54, 270, 270, -405, 136, +-497, -166, 159, -267, 531, -17, 42, 300, +-556, 194, -319, -239, 369, -403, 437, 16, +-210, 397, -518, 161, -57, -381, 436, -412, +204, 142, -308, 420, -324, -4, 114, -508, +363, -281, 47, 330, -301, 360, -189, -250, +240, -545, 332, -34, -105, 453, -335, 154, +-5, -413, 422, -368, 202, 166, -341, 345, +-273, -18, 315, -314, 455, -194, -125, 134, +-444, 262, 33, 60, 478, -244, 209, -271, +-311, 114, -277, 422, 191, 143, 431, -378, +59, -360, -375, 256, -208, 578, 354, 93, +380, -513, -220, -345, -394, 446, 85, 671, +395, -71, 49, -728, -283, -223, -147, 783, +84, 672, 196, -469, 68, -870, -175, 201, +-308, 1028, 20, 266, 399, -860, 120, -506, +-467, 689, -420, 724, 320, -362, 547, -736, +-146, 151, -685, 684, -213, 65, 572, -538, +411, -196, -399, 358, -632, 197, 33, -196, +595, -178, 251, 36, -469, 27, -557, -61, +161, 18, 653, 32, 168, -119, -634, -168, +-490, 8, 446, 142, 707, -15, -143, -212, +-766, -165, -147, 80, 694, 157, 445, -62, +-434, -243, -557, -135, 208, 133, 603, 132, +123, -98, -425, -230, -238, -50, 290, 196, +342, 97, -39, -201, -222, -222, -25, 187, +156, 333, 98, -133, 29, -458, 35, 28, +-46, 585, -116, 187, 65, -562, 276, -351, +71, 529, -337, 585, -195, -300, 356, -623, +363, 162, -276, 715, -498, 126, 161, -587, +559, -252, -24, 539, -597, 484, -161, -264, +534, -477, 260, 106, -480, 505, -418, 163, +299, -298, 448, -224, -198, 152, -532, 301, +-19, 82, 431, -186, 127, -214, -400, 52, +-284, 304, 192, 159, 269, -270, -65, -353, +-268, 115, -123, 437, 117, 64, 188, -489, +26, -303, -253, 333, -205, 417, 182, -202, +335, -553, -69, -78, -409, 412, -86, 222, +433, -356, 280, -416, -300, 69, -417, 334, +153, 61, 555, -338, 121, -241, -485, 134, +-347, 212, 408, -75, 614, -254, -135, -43, +-630, 160, -121, 26, 656, -166, 430, -70, +-433, 147, -548, 90, 201, -158, 645, -146, +109, 143, -515, 229, -280, -49, 328, -279, +450, -26, -55, 335, -416, 192, -181, -242, +309, -306, 375, 230, -108, 489, -457, -7, +-130, -501, 379, -172, 303, 590, -210, 477, +-449, -377, -52, -619, 375, 187, 242, 792, +-270, 179, -452, -661, 52, -411, 400, 509, +103, 657, -359, -168, -282, -674, 160, -104, +235, 601, -16, 397, -223, -385, -164, -542, +84, 132, 176, 543, -1, 129, -228, -462, +-105, -344, 169, 251, 121, 391, -130, -50, +-154, -424, 63, -201, 153, 262, -11, 264, +-127, -156, -8, -374, 115, -72, 86, 257, +-90, 117, -91, -215, 113, -234, 152, 35, +-38, 151, -189, -13, 53, -134, 267, -80, +39, 5, -243, 35, -90, 12, 304, -26, +186, -87, -234, -51, -198, 95, 203, 86, +275, -76, -107, -157, -230, 49, 53, 191, +224, 12, 29, -148, -169, -24, -60, 165, +144, 66, 72, -90, -134, -14, -69, 126, +108, 75, 72, -61, -135, -31, -107, 111, +127, 106, 101, -32, -112, -67, -187, 48, +58, 137, 189, 55, -26, -67, -233, -53, +-128, 63, 208, 127, 178, 59, -198, -84, +-306, -96, 59, 53, 340, 192, -9, 43, +-390, -201, -137, -123, 334, 170, 211, 215, +-290, -127, -295, -299, 179, -13, 288, 292, +-82, 135, -241, -284, -36, -310, 150, 115, +78, 346, -6, 3, -72, -400, -107, -222, +39, 251, 197, 270, 98, -179, -203, -372, +-172, -34, 201, 286, 265, 104, -71, -248, +-285, -249, 12, 99, 301, 234, 87, -16, +-227, -226, -92, -107, 214, 116, 131, 95, +-149, -29, -107, -58, 152, -37, 120, -16, +-109, 49, -118, 109, 103, 3, 152, -135, +-75, -28, -143, 170, 14, 128, 167, -100, +31, -130, -161, 94, -95, 192, 94, 27, +137, -116, -56, -15, -174, 134, -49, 86, +121, -53, 117, -13, -99, 70, -199, 59, +-19, -18, 171, -1, 100, 61, -161, 17, +-213, -19, 31, 5, 224, 68, 53, 38, +-232, -74, -182, -62, 129, 65, 211, 131, +-31, -32, -239, -193, -96, -54, 154, 184, +147, 129, -40, -168, -186, -227, -102, 33, +137, 199, 224, 35, -24, -183, -300, -180, +-102, 18, 315, 156, 263, 66, -225, -157, +-367, -248, 106, 3, 438, 252, 83, 105, +-382, -274, -221, -308, 304, 124, 368, 350, +-132, 12, -379, -382, -16, -218, 385, 283, +163, 324, -283, -131, -213, -391, 176, -35, +272, 376, -67, 191, -241, -276, -7, -273, +199, 193, 75, 356, -150, -44, -104, -334, +98, -23, 133, 335, -54, 166, -181, -237, +-1, -175, 196, 224, 33, 267, -216, -89, +-132, -263, 190, 58, 191, 336, -173, 97, +-276, -273, 63, -185, 281, 264, 24, 329, +-302, -120, -164, -366, 229, -11, 219, 397, +-162, 170, -300, -309, 83, -296, 247, 179, +-44, 354, -207, -23, 11, -359, 147, -144, +-62, 240, -125, 221, 115, -134, 121, -282, +-165, -27, -182, 188, 171, 77, 270, -145, +-123, -160, -319, 13, 11, 76, 348, 23, +146, -76, -288, -116, -260, -26, 165, 68, +357, 72, 55, -91, -351, -163, -237, -10, +294, 147, 433, 69, -111, -160, -495, -161, +-50, 74, 478, 201, 243, 16, -329, -199, +-354, -114, 176, 159, 385, 191, 49, -54, +-299, -204, -230, -23, 177, 216, 338, 155, +0, -109, -370, -179, -166, 55, 299, 258, +294, 77, -179, -186, -364, -122, 7, 189, +326, 235, 114, -81, -257, -193, -204, 36, +88, 218, 199, 62, 17, -127, -155, -55, +-138, 79, 9, 89, 159, 19, 80, -45, +-135, -63, -197, -19, 24, 90, 232, 93, +67, -80, -235, -153, -181, -7, 149, 149, +250, 51, -72, -144, -269, -127, -51, 37, +239, 103, 138, 3, -177, -123, -185, -95, +77, 0, 218, 103, 30, 32, -198, -159, +-111, -152, 179, 79, 175, 189, -82, -63, +-206, -273, 19, -42, 221, 241, 78, 113, +-161, -229, -164, -210, 126, 141, 228, 244, +-2, -33, -250, -250, -109, -82, 257, 217, +212, 195, -160, -102, -259, -229, 36, -22, +282, 238, 121, 171, -219, -98, -245, -213, +100, -22, 333, 263, 46, 190, -345, -136, +-197, -267, 237, 67, 322, 378, -107, 116, +-387, -340, -70, -246, 314, 309, 240, 444, +-209, -149, -371, -516, 36, -32, 366, 575, +121, 271, -320, -515, -235, -464, 151, 390, +224, 627, 32, -183, -210, -718, -197, -61, +80, 697, 252, 285, 67, -596, -268, -527, +-231, 387, 195, 625, 319, -174, -72, -681, +-347, -120, -110, 587, 302, 293, 246, -462, +-160, -471, -354, 192, 6, 478, 399, 6, +134, -448, -312, -239, -259, 250, 214, 345, +315, -76, -69, -383, -263, -147, -39, 273, +185, 264, 135, -126, -50, -315, -121, -48, +-47, 245, 69, 203, 159, -113, 29, -267, +-161, -19, -144, 285, 134, 195, 249, -220, +-32, -272, -289, 163, -94, 366, 262, 0, +235, -356, -191, -96, -309, 349, 59, 260, +335, -209, 63, -326, -309, 108, -161, 406, +201, 83, 222, -357, -110, -223, -244, 291, +15, 373, 206, -113, 35, -420, -177, -80, +-86, 388, 117, 308, 76, -255, -103, -438, +-82, 39, 49, 487, 44, 168, -42, -452, +-6, -355, 5, 298, -72, 447, 14, -156, +113, -517, -8, -45, -178, 445, -47, 192, +224, -378, 95, -352, -222, 196, -205, 378, +186, -64, 342, -414, -100, -107, -436, 334, +-46, 169, 486, -290, 249, -238, -439, 206, +-432, 249, 307, -178, 585, -271, -61, 128, +-634, 256, -173, -89, 567, -252, 422, 67, +-346, 231, -583, -37, 105, -195, 630, 29, +171, 190, -494, 9, -394, -142, 275, 22, +526, 136, -1, 14, -504, -90, -276, 31, +384, 127, 447, 7, -165, -102, -496, -1, +-107, 125, 439, 51, 333, -76, -277, -24, +-486, 66, 33, 6, 526, -24, 202, 55, +-470, 54, -385, -106, 293, -92, 481, 160, +-100, 148, -512, -172, -109, -215, 428, 164, +255, 271, -306, -158, -365, -346, 157, 79, +368, 369, -26, -2, -327, -407, -103, -124, +241, 335, 130, 210, -133, -269, -156, -292, +12, 128, 132, 278, 74, -53, -84, -259, +-138, -58, 16, 165, 160, 72, 69, -88, +-128, -64, -163, -29, 58, -20, 259, 77, +37, 135, -313, -70, -139, -270, 312, -3, +280, 344, -239, 143, -393, -346, 138, -287, +462, 302, 56, 412, -456, -142, -238, -474, +370, -22, 424, 512, -175, 241, -541, -405, +-35, -411, 539, 271, 271, 559, -411, -12, +-444, -543, 191, -196, 510, 449, 85, 398, +-444, -230, -328, -435, 251, 14, 494, 401, +4, 192, -517, -246, -260, -300, 402, 65, +435, 318, -193, 135, -519, -233, -70, -259, +460, 87, 265, 296, -319, 70, -391, -263, +86, -192, 387, 151, 114, 230, -303, -54, +-264, -254, 135, -60, 314, 186, 11, 105, +-263, -130, -171, -153, 131, 34, 251, 119, +8, 15, -257, -92, -150, -86, 179, 16, +229, 84, -68, 24, -257, -77, -42, -72, +230, 39, 120, 54, -161, -44, -136, -30, +79, 55, 121, 22, 34, -103, -97, -32, +-105, 139, 79, 78, 151, -132, -9, -121, +-175, 123, -31, 175, 163, -55, 89, -165, +-122, 23, -128, 170, 68, 55, 165, -117, +1, -62, -146, 78, -55, 78, 128, -10, +123, -34, -74, 2, -127, 12, -7, -1, +109, 37, 96, 50, -50, -6, -148, -82, +-59, -31, 179, 105, 164, 91, -165, -64, +-234, -150, 94, 1, 265, 162, 19, 85, +-261, -145, -146, -189, 191, 66, 256, 267, +-99, 44, -337, -316, -19, -231, 344, 262, +113, 379, -295, -151, -197, -496, 175, -44, +234, 475, -62, 219, -236, -404, -84, -371, +221, 243, 165, 422, -191, -94, -210, -451, +150, -58, 213, 390, -135, 155, -174, -318, +118, -219, 131, 238, -129, 214, -92, -181, +145, -197, 73, 151, -114, 190, -88, -129, +47, -193, 111, 109, 56, 239, -139, -18, +-150, -266, 152, -70, 222, 278, -105, 201, +-241, -226, 32, -293, 230, 167, 95, 389, +-159, -57, -204, -398, 67, -52, 271, 375, +90, 188, -266, -245, -233, -256, 219, 59, +347, 269, -87, 129, -375, -176, -40, -258, +341, 23, 163, 306, -222, 141, -272, -261, +102, -247, 302, 142, 38, 292, -265, -9, +-152, -281, 162, -142, 242, 194, -16, 238, +-300, -89, -126, -301, 298, -57, 250, 269, +-267, 146, -327, -219, 197, -228, 368, 126, +-115, 220, -388, -61, 17, -217, 354, -22, +88, 176, -281, 74, -233, -140, 180, -143, +336, 80, -70, 179, -403, -31, -50, -197, +426, -44, 137, 186, -393, 110, -212, -156, +301, -154, 261, 110, -187, 189, -260, -40, +46, -180, 226, -42, 98, 136, -152, 131, +-185, -30, 87, -176, 228, -95, -34, 189, +-197, 239, 1, -102, 163, -348, 9, 13, +-90, 405, -6, 125, 52, -387, 7, -226, +-44, 329, 41, 336, 58, -216, -70, -367, +-85, 84, 66, 387, 140, 28, -29, -310, +-160, -110, -40, 227, 177, 131, 102, -124, +-177, -106, -135, 52, 175, 40, 131, -1, +-142, 25, -142, -36, 121, -117, 150, 44, +-90, 192, -166, -49, 63, -264, 157, 6, +-35, 283, -159, 47, 7, -300, 147, -105, +18, 263, -141, 132, -100, -224, 144, -162, +158, 159, -127, 167, -221, -96, 54, -176, +262, -12, 34, 181, -284, 97, -153, -152, +288, -206, 255, 113, -289, 286, -338, -39, +238, -349, 393, -37, -151, 384, -424, 124, +39, -373, 413, -201, 82, 327, -374, 296, +-183, -246, 298, -347, 267, 162, -198, 412, +-344, -49, 88, -443, 413, -52, 47, 450, +-452, 237, -155, -437, 429, -409, 284, 368, +-345, 606, -358, -220, 249, -768, 394, 38, +-129, 867, -368, 212, 21, -878, 325, -468, +61, 828, -206, 699, -136, -695, 112, -891, +161, 500, -23, 1026, -119, -264, -27, -1065, +29, 0, 9, 1052, 76, 195, 60, -959, +-140, -370, -154, 837, 154, 466, 221, -717, +-102, -540, -255, 581, -6, 594, 239, -478, +117, -654, -151, 368, -257, 683, 13, -253, +347, -738, 134, 105, -361, 774, -277, 60, +279, -791, 367, -295, -146, 745, -385, 510, +-12, -589, 325, -695, 113, 342, -222, 794, +-145, -65, 85, -786, 116, -204, 60, 678, +-31, 396, -190, -472, -63, -513, 254, 227, +186, 529, -272, 58, -250, -457, 219, -278, +276, 297, -107, 428, -246, -86, 16, -460, +161, -104, 90, 433, -48, 245, -173, -318, +-43, -341, 241, 194, 171, 384, -284, -17, +-267, -373, 293, -189, 383, 330, -238, 361, +-472, -179, 154, -510, 543, -6, -23, 589, +-571, 238, -107, -599, 543, -505, 275, 531, +-433, 751, -460, -347, 275, -941, 580, 13, +-23, 1035, -650, 365, -208, -936, 592, -774, +388, 656, -419, 1066, -511, -251, 201, -1177, +521, -278, 19, 1116, -432, 739, -230, -850, +285, -1125, 328, 411, -77, 1333, -350, 95, +-127, -1298, 250, -632, 246, 1034, -75, 1040, +-278, -597, -111, -1216, 146, 51, 291, 1152, +21, 444, -376, -867, -216, -792, 363, 422, +388, 971, -300, 32, -453, -893, 152, -485, +480, 657, 6, 796, -434, -280, -94, -919, +296, -139, 171, 856, -172, 509, -129, -595, +23, -749, 80, 253, 96, 874, -31, 74, +-154, -834, 30, -372, 231, 724, -55, 603, +-310, -534, 106, -727, 405, 272, -82, 805, +-537, -18, 53, -728, 617, -216, 73, 552, +-657, 417, -229, -321, 616, -511, 409, 27, +-442, 541, -587, 264, 206, -486, 685, -531, +69, 300, -624, 754, -351, -42, 469, -861, +483, -248, -194, 790, -507, 533, -115, -613, +391, -669, 329, 321, -155, 685, -479, -47, +-103, -590, 450, -141, 339, 366, -313, 247, +-475, -117, 65, -234, 463, -140, 189, 71, +-318, 352, -361, 160, 49, -414, 382, -439, +244, 300, -265, 689, -453, -112, -6, -750, +560, -155, 293, 681, -498, 361, -569, -475, +297, -452, 768, 172, 12, 455, -837, 118, +-348, -311, 762, -349, 670, 44, -557, 490, +-849, 257, 250, -438, 919, -531, 84, 225, +-826, 701, -383, 63, 671, -658, 620, -389, +-427, 482, -776, 618, 170, -178, 857, -682, +89, -174, -834, 612, -294, 486, 742, -389, +445, -723, -544, 51, -522, 842, 300, 321, +569, -764, -50, -668, -560, 511, -165, 902, +505, -164, 334, -951, -390, -214, -418, 847, +187, 522, 432, -615, 21, -717, -348, 289, +-242, 800, 228, 56, 366, -728, -77, -374, +-414, 483, -96, 599, 401, -106, 198, -660, +-326, -305, -274, 497, 218, 679, 281, -198, +-126, -886, -218, -203, 18, 901, 151, 604, +31, -742, -91, -919, -46, 414, 62, 1066, +50, 43, -67, -1030, -76, -493, 80, 738, +134, 855, -58, -271, -236, -1001, 27, -240, +308, 844, 97, 687, -366, -487, -200, -924, +334, 12, 321, 897, -195, 471, -405, -639, +10, -816, 368, 177, 293, 928, -226, 384, +-530, -786, -13, -864, 678, 329, 367, 1105, +-660, 275, -647, -1003, 464, -856, 866, 533, +-119, 1210, -920, 144, -233, -1202, 782, -844, +578, 817, -515, 1371, -768, -151, 163, -1558, +780, -633, 195, 1333, -618, 1324, -405, -707, +300, -1744, 451, -155, 41, 1699, -293, 1063, +-308, -1173, -31, -1728, 441, 289, 336, 1932, +-328, 752, -624, -1614, 54, -1637, 733, 881, +298, 2104, -637, 158, -665, -2101, 368, -1156, +857, 1566, 27, 1911, -840, -582, -480, -2258, +608, -535, 775, 2006, -159, 1590, -907, -1232, +-345, -2295, 767, 175, 791, 2399, -408, 964, +-1075, -1970, -50, -1849, 1082, 1112, 557, 2246, +-837, -10, -934, -2181, 388, -1017, 1113, 1608, +193, 1759, -1060, -687, -680, -2112, 765, -323, +1014, 1896, -277, 1208, -1101, -1248, -223, -1733, +910, 371, 665, 1740, -513, 515, -890, -1340, +48, -1161, 864, 653, 433, 1426, -620, 136, +-757, -1308, 195, -788, 865, 859, 314, 1181, +-727, -206, -729, -1227, 335, -447, 1029, 895, +154, 938, -1056, -310, -662, -1089, 844, -341, +1051, 905, -442, 846, -1229, -438, -65, -1067, +1150, -103, 553, 981, -838, 570, -916, -611, +323, -838, 1074, 138, 234, 845, -991, 351, +-757, -558, 652, -678, 1107, 113, -182, 729, +-1197, 394, -375, -460, 1044, -776, 850, -8, +-670, 839, -1149, 572, 136, -609, 1211, -982, +417, 152, -1021, 1117, -908, 420, 625, -991, +1233, -893, -128, 568, -1291, 1152, -378, 6, +1143, -1145, 746, -561, -776, 777, -943, 950, +347, -192, 928, -1037, 64, -446, -695, 730, +-362, 952, 343, -182, 502, -1147, 48, -493, +-423, 981, -390, 1074, 223, -535, 572, -1425, +98, -93, -552, 1454, -399, 711, 372, -1167, +631, -1218, -64, 639, -699, 1449, -252, -12, +614, -1350, 519, -575, -380, 1001, -646, 914, +75, -486, 621, -958, 239, -23, -448, 781, +-460, 352, 174, -403, 555, -466, 124, -15, +-506, 403, -353, 311, 323, -97, 484, -479, +-81, -223, -482, 425, -187, 512, 355, -133, +391, -654, -174, -206, -470, 559, -59, 524, +430, -221, 262, -710, -308, -148, -394, 619, +104, 548, 443, -336, 85, -801, -381, -46, +-251, 787, 262, 496, 337, -592, -105, -828, +-357, 218, -38, 918, 306, 283, 158, -818, +-192, -704, -227, 438, 52, 936, 253, 103, +77, -966, -204, -606, -169, 661, 135, 955, +216, -178, -14, -1093, -208, -335, -104, 872, +164, 789, 242, -467, -72, -1051, -304, -86, +-48, 1000, 327, 623, 205, -681, -271, -1010, +-357, 175, 162, 1052, 483, 405, 48, -803, +-556, -852, -236, 305, 530, 985, 439, 303, +-412, -792, -589, -804, 229, 354, 622, 1004, +51, 297, -562, -897, -332, -869, 380, 484, +529, 1202, -90, 239, -655, -1217, -208, -907, +590, 825, 479, 1404, -389, -64, -690, -1568, +95, -697, 716, 1234, 245, 1393, -588, -525, +-547, -1744, 318, -322, 691, 1586, 60, 1216, +-691, -1026, -435, -1798, 502, 170, 709, 1874, +-163, 852, -817, -1530, -232, -1598, 708, 715, +602, 1920, -437, 305, -814, -1778, 54, -1169, +867, 1084, 328, 1695, -704, -113, -623, -1773, +393, -825, 755, 1261, -24, 1518, -651, -395, +-290, -1787, 363, -540, 477, 1432, 16, 1327, +-439, -684, -370, -1737, 250, -231, 587, 1521, +96, 1099, -580, -858, -481, -1622, 366, -51, +747, 1541, 42, 1049, -825, -1001, -487, -1732, +675, 99, 846, 1831, -282, 1004, -1027, -1446, +-207, -1803, 926, 552, 681, 2120, -543, 626, +-989, -1929, -4, -1587, 1015, 1122, 595, 2210, +-772, 39, -1054, -2285, 286, -1107, 1261, 1642, +319, 1970, -1137, -592, -885, -2248, 708, -551, +1232, 1818, -95, 1594, -1251, -957, -549, -2038, +923, -172, 1035, 1860, -363, 1264, -1213, -1153, +-328, -1891, 1053, 40, 911, 1935, -558, 1129, +-1231, -1387, -141, -1944, 1223, 316, 810, 2230, +-838, 877, -1307, -1858, 196, -1866, 1494, 915, +531, 2375, -1268, 288, -1179, -2259, 722, -1441, +1553, 1532, -16, 2221, -1539, -434, -662, -2426, +1194, -765, 1140, 1979, -594, 1694, -1281, -1082, +-93, -2111, 1086, -13, 698, 1883, -601, 953, +-998, -1213, -27, -1449, 995, 257, 611, 1418, +-678, 619, -977, -923, 151, -1135, 1055, 132, +442, 1155, -842, 650, -882, -699, 379, -1091, +1096, -96, 153, 1059, -996, 901, -619, -539, +647, -1389, 918, -319, -150, 1425, -979, 1217, +-346, -952, 767, -1825, 729, 68, -375, 1987, +-884, 973, -88, -1572, 770, -1772, 476, 622, +-480, 2185, -733, 548, 120, -1937, 740, -1624, +285, 1098, -591, 2329, -568, 55, 298, -2385, +656, -1249, 64, 1823, -630, 2183, -347, -800, +446, -2533, 511, -457, -169, 2263, -585, 1551, +-48, -1414, 467, -2186, 216, 224, -241, 2196, +-288, 913, 40, -1604, 203, -1723, 168, 633, +-92, 1987, -311, 446, -34, -1687, 339, -1348, +208, 923, -315, 1822, -305, 71, 213, -1782, +329, -1002, -51, 1223, -311, 1604, -59, -379, +263, -1731, 136, -504, -179, 1365, -176, 1177, +118, -689, 166, -1451, -78, -141, -99, 1313, +45, 892, 58, -831, -48, -1319, -36, 107, +86, 1381, 1, 613, -116, -1070, -17, -1042, +159, 434, 92, 1206, -220, 188, -129, -982, +156, -626, 207, 465, -79, 872, -274, 70, +27, -767, 273, -525, 105, 340, -299, 853, +-213, 132, 259, -783, 281, -621, -128, 415, +-374, 997, 37, 34, 358, -982, 51, -564, +-272, 718, -153, 961, 178, -307, 184, -1063, +-29, -236, -177, 899, -123, 748, 151, -533, +161, -991, -48, -66, -173, 966, -61, 665, +140, -677, 170, -1065, -59, 143, -256, 1191, +-52, 487, 262, -1075, 152, -953, -199, 618, +-190, 1249, 79, -17, 232, -1312, 2, -517, +-195, 985, -90, 998, 104, -519, 195, -1207, +-2, 3, -207, 1064, -121, 533, 183, -827, +248, -805, -147, 414, -269, 871, 28, 50, +311, -838, 83, -303, -321, 548, -145, 501, +230, -218, 223, -538, -171, 15, -225, 305, +119, 197, 175, -104, -18, -222, -153, -35, +-25, 75, 60, 192, 46, 26, 33, -164, +-27, -151, -92, 34, -33, 286, 107, 88, +83, -257, -101, -237, -134, 115, 39, 379, +170, 32, 36, -325, -185, -215, -133, 180, +149, 360, 177, -40, -77, -351, -184, -157, +-36, 307, 168, 340, 113, -294, -97, -387, +-181, 157, 0, 438, 174, -32, 74, -465, +-100, 14, -109, 320, 2, 85, 96, -265, +76, -144, -24, 257, -138, 80, -82, -99, +183, -168, 176, 4, -148, 240, -240, 24, +26, -113, 255, -232, 67, 126, -132, 295, +-175, -91, -21, -229, 231, -115, 141, 312, +-152, 164, -270, -244, 13, -199, 329, 47, +137, 326, -208, 14, -339, -241, 75, -126, +414, 101, 115, 228, -350, -30, -357, -143, +231, -101, 490, 36, 7, 198, -482, 64, +-339, -168, 385, -209, 540, 99, -142, 293, +-611, 9, -187, -254, 574, -135, 421, 129, +-372, 219, -595, 6, 24, -156, 683, -174, +268, 42, -550, 260, -565, 92, 290, -220, +744, -258, -69, 137, -717, 339, -195, 14, +547, -315, 385, -229, -329, 237, -426, 344, +14, -57, 378, -369, 206, -133, -314, 292, +-279, 248, 176, -132, 261, -273, -78, -72, +-166, 214, 17, 226, -20, -75, 11, -305, +164, -118, -9, 310, -191, 268, -73, -204, +149, -337, 118, 1, -68, 348, -93, 134, +-87, -202, 95, -245, 170, 44, -92, 276, +-178, 59, 23, -147, 181, -162, -66, 24, +-79, 134, 127, 136, -72, 6, -155, -301, +115, -140, 229, 310, -148, 327, -264, -239, +109, -455, 188, 148, 43, 412, -108, 47, +-196, -339, -71, -150, 273, 173, 290, 175, +-326, 52, -455, -163, 225, -206, 562, 75, +-117, 287, -603, 89, -74, -313, 518, -202, +226, 226, -369, 261, -361, -66, 160, -287, +381, -69, -18, 216, -331, 171, -112, -83, +187, -274, 147, -24, -49, 264, -124, 133, +-125, -191, 49, -226, 180, 89, -2, 216, +-186, 57, -78, -148, 150, -212, 49, 89, +-63, 263, -74, 18, -59, -305, 69, -101, +97, 323, -29, 111, -150, -283, 35, -113, +75, 218, -83, 115, 18, -215, 84, -17, +-109, 189, -138, -45, 196, -189, 114, 41, +-260, 297, -92, -75, 222, -356, 63, 56, +-199, 419, -34, 32, 113, -528, -10, -76, +-33, 567, -14, 173, -46, -547, -17, -324, +108, 524, -16, 447, -166, -421, 43, -550, +157, 264, -96, 650, -196, -130, 100, -664, +152, -19, -82, 667, -154, 140, 12, -626, +102, -271, 14, 562, -88, 383, -128, -445, +89, -519, 122, 305, -87, 635, -201, -74, +46, -783, 216, -167, -95, 847, -245, 465, +57, -850, 240, -767, -50, 735, -329, 1026, +27, -528, 291, -1186, 41, 192, -358, 1264, +-173, 127, 366, -1205, 261, -425, -348, 1007, +-422, 682, 238, -779, 485, -833, -160, 547, +-523, 858, -32, -274, 507, -906, 169, 115, +-511, 902, -320, -20, 411, -894, 383, -61, +-375, 1003, -446, 130, 331, -1204, 400, -194, +-351, 1379, -422, 452, 330, -1584, 442, -802, +-368, 1695, -533, 1213, 310, -1578, 612, -1721, +-229, 1314, -769, 2201, 47, -892, 794, -2502, +136, 258, -758, 2670, -419, 419, 589, -2571, +572, -1066, -342, 2202, -747, 1655, -44, -1662, +740, -2039, 363, 995, -657, 2211, -676, -279, +375, -2167, 810, -413, -144, 1941, -829, 957, +-163, -1511, 646, -1369, 348, 949, -458, 1592, +-472, -374, 152, -1556, 390, -254, 63, 1340, +-293, 748, -215, -956, 9, -1080, 205, 430, +228, 1213, -205, 99, -478, -1091, 29, -613, +592, 762, 62, 987, -662, -293, -176, -1164, +541, -302, 203, 1160, -467, 782, -265, -836, +296, -1222, 222, 391, -208, 1429, -232, 143, +56, -1344, 179, -754, -1, 1108, -224, 1174, +-112, -623, 155, -1416, 246, 24, -224, 1483, +-425, 495, 137, -1221, 511, -992, -43, 887, +-702, 1296, -143, -440, 716, -1444, 277, -2, +-665, 1504, -567, 344, 502, -1389, 629, -674, +-286, 1273, -697, 896, -96, -1064, 651, -1035, +302, 734, -536, 1225, -550, -474, 245, -1246, +657, 54, -112, 1282, -621, 368, -134, -1261, +431, -748, 186, 1033, -304, 1214, -195, -764, +19, -1512, 56, 298, 120, 1655, 60, 294, +-276, -1651, -301, -817, 233, 1278, 438, 1336, +-220, -752, -597, -1603, 42, 75, 562, 1487, +127, 699, -612, -1162, -334, -1204, 447, 435, +433, 1482, -311, 408, -646, -1426, 158, -1157, +603, 879, -2, 1794, -670, -141, -220, -2013, +568, -737, 264, 1770, -433, 1639, -457, -1233, +183, -2132, 476, 288, 6, 2311, -532, 713, +-383, -2029, 482, -1547, 620, 1252, -400, 2184, +-960, -309, 144, -2331, 1140, -733, 87, 1994, +-1307, 1697, -493, -1368, 1237, -2189, 803, 388, +-1116, 2346, -1155, 567, 732, -2072, 1298, -1325, +-381, 1396, -1342, 1919, -179, -655, 1162, -2096, +525, -130, -828, 1932, -933, 844, 255, -1625, +1065, -1150, 193, 1050, -1023, 1306, -818, -557, +774, -1198, 1127, 216, -503, 846, -1303, 95, +-55, -578, 1257, -131, 351, 243, -1009, 70, +-717, 55, 501, -18, 838, -157, -158, -213, +-772, 282, -315, 347, 482, -304, 452, -440, +-182, 212, -473, 569, -288, -182, 176, -561, +486, 75, 190, 548, -617, 27, -727, -525, +379, -110, 1068, 446, 0, 201, -1364, -368, +-633, -262, 1236, 258, 1198, 279, -936, -117, +-1777, -247, 275, 24, 1937, 121, 428, 69, +-1913, 14, -1260, -73, 1472, -114, 1750, -35, +-812, 215, -2180, 137, -34, -162, 2097, -243, +729, -50, -1748, 381, -1467, 264, 1118, -317, +1691, -584, -390, 134, -1774, 930, -429, 71, +1445, -1053, 938, -476, -985, 1096, -1329, 893, +272, -1020, 1307, -1160, 293, 663, -1127, 1435, +-901, -240, 613, -1555, 1208, -197, -129, 1341, +-1415, 750, -451, -1026, 1219, -1085, 833, 493, +-1013, 1157, -1159, 175, 519, -1021, 1201, -674, +-119, 528, -1195, 1025, -459, 105, 984, -1069, +742, -767, -731, 734, -1076, 1382, 274, -197, +1174, -1649, -6, -635, -1140, 1626, -501, 1452, +859, -1208, 876, -2054, -688, 345, -1139, 2425, +99, 599, 1307, -2265, 289, -1554, -1412, 1620, +-757, 2352, 1059, -703, 1150, -2627, -791, -474, +-1457, 2425, 232, 1615, 1409, -1783, 287, -2358, +-1361, 679, -849, 2691, 984, 516, 1121, -2448, +-610, -1513, -1351, 1627, 54, 2214, 1255, -543, +265, -2342, -1079, -618, -606, 1896, 654, 1620, +714, -1105, -441, -2108, -677, -6, 74, 2150, +386, 988, 74, -1619, -259, -1693, -89, 716, +-153, 1983, -50, 239, 318, -1693, 78, -1140, +-381, 1054, -443, 1667, 370, -245, 473, -1685, +-278, -623, -598, 1389, -88, 1163, 604, -761, +173, -1359, -557, 36, -433, 1229, 322, 533, +537, -778, -347, -855, -520, 156, 104, 882, +374, 380, -89, -554, -312, -764, 37, 56, +-8, 854, -89, 455, 80, -613, 60, -847, +-242, 213, -210, 941, 211, 277, 195, -802, +-225, -664, -319, 474, 42, 835, 255, 30, +64, -896, -368, -382, -253, 645, 238, 701, +308, -284, -204, -847, -527, -14, 51, 656, +433, 436, 63, -444, -457, -621, -344, 96, +345, 637, 340, 348, -219, -612, -499, -615, +-45, 367, 432, 848, 66, -67, -258, -936, +-346, -224, 0, 827, 295, 508, 201, -623, +-263, -677, -591, 308, 106, 776, 618, -30, +106, -717, -741, -299, -418, 604, 576, 572, +511, -459, -370, -699, -728, 113, 63, 848, +591, 184, 146, -803, -484, -523, -415, 544, +150, 928, 374, -248, 147, -1134, -374, -259, +-509, 1212, 63, 850, 655, -1151, 170, -1306, +-801, 778, -566, 1717, 614, -258, 812, -1897, +-474, -349, -1054, 1762, 39, 1025, 1038, -1391, +278, -1542, -1014, 793, -704, 1800, 651, -5, +946, -1798, -351, -686, -1210, 1423, -133, 1251, +1173, -781, 485, -1589, -1138, 45, -902, 1505, +887, 801, 1008, -1154, -617, -1511, -1172, 535, +219, 1873, 1013, 421, 26, -2015, -827, -1296, +-404, 1658, 476, 2074, 470, -897, -163, -2669, +-586, 40, -244, 2713, 418, 1011, 433, -2415, +-235, -1909, -713, 1790, -91, 2423, 633, -796, +377, -2692, -596, -144, -691, 2455, 282, 999, +714, -1884, 56, -1646, -787, 1194, -469, 1857, +498, -349, 713, -1849, -206, -346, -976, 1515, +-221, 894, 827, -975, 561, -1252, -686, 425, +-866, 1272, 212, 188, 867, -1136, 209, -646, +-815, 846, -677, 889, 389, -409, 931, -1057, +-66, 79, -1008, 1018, -471, 239, 741, -881, +766, -521, -410, 758, -969, 676, -258, -551, +894, -771, 725, 284, -667, 872, -1208, -81, +105, -810, 1407, -211, 330, 696, -1345, 495, +-959, -535, 948, -653, 1281, 211, -495, 821, +-1455, 108, -236, -846, 1319, -437, 713, 690, +-1026, 821, -1174, -498, 447, -987, 1262, 94, +5, 1084, -1150, 319, -566, -997, 754, -632, +733, 620, -274, 935, -851, -248, -264, -959, +592, -206, 542, 760, -237, 643, -816, -516, +-207, -779, 639, 93, 539, 761, -409, 277, +-873, -592, 1, -413, 800, 197, 387, 441, +-716, 140, -746, -295, 350, -319, 782, -64, +29, 416, -768, 341, -453, -273, 440, -548, +628, -78, -77, 678, -787, 421, -373, -505, +575, -814, 662, 160, -321, 1090, -917, 298, +-136, -1064, 818, -888, 523, 856, -648, 1316, +-903, -345, 181, -1571, 989, -305, 286, 1546, +-972, 907, -812, -1148, 590, -1440, 1139, 572, +-178, 1658, -1366, 145, -410, -1508, 1220, -889, +878, 1142, -1008, 1327, -1263, -440, 464, -1517, +1368, -304, -9, 1377, -1330, 892, -518, -826, +961, -1348, 853, 159, -641, 1436, -1027, 530, +115, -1135, 935, -1185, 231, 688, -795, 1452, +-487, -17, 346, -1453, 580, -630, -66, 1173, +-558, 1043, -294, -562, 275, -1290, 511, -61, +-159, 1183, -577, 642, -137, -778, 465, -1108, +278, 267, -417, 1193, -322, 384, 99, -1029, +308, -952, -11, 647, -263, 1245, -125, 7, +51, -1371, 156, -619, -66, 1178, -103, 1137, +-42, -686, -44, -1560, -1, 122, 85, 1654, +65, 509, -257, -1478, -171, -1135, 247, 1182, +191, 1502, -272, -647, -304, -1719, 215, 66, +237, 1752, -184, 443, -290, -1491, 94, -953, +227, 1142, -118, 1297, -223, -691, 21, -1442, +223, 145, -122, 1517, -243, 276, 67, -1377, +250, -689, -92, 1158, -409, 1020, 112, -884, +326, -1166, -71, 465, -451, 1281, 30, -111, +451, -1177, -135, -218, -406, 892, -14, 495, +452, -656, -27, -447, -501, 301, -60, 342, +367, -140, 224, -171, -410, 248, -348, -87, +223, -341, 369, 23, -37, 605, -461, 170, +-158, -788, 286, -448, 298, 657, -103, 903, +-453, -452, -147, -1192, 378, 3, 366, 1289, +-303, 597, -592, -1232, 94, -1103, 593, 861, +123, 1572, -583, -323, -369, -1833, 345, -361, +511, 1817, -100, 1121, -623, -1491, -232, -1782, +505, 803, 520, 2247, -417, 112, -691, -2284, +85, -1125, 689, 1870, 208, 2011, -631, -1087, +-432, -2476, 268, 8, 598, 2506, -33, 1044, +-604, -2044, -241, -1818, 342, 1133, 468, 2284, +-184, -133, -479, -2205, -186, -869, 358, 1682, +436, 1709, -274, -923, -528, -2065, -51, -112, +581, 2064, 167, 1082, -507, -1675, -288, -1748, +266, 828, 333, 2218, -195, 25, -207, -2160, +-9, -931, 66, 1682, 20, 1716, 35, -1020, +34, -2040, -248, 62, -75, 2034, 210, 839, +222, -1664, -262, -1451, -363, 866, 191, 1810, +376, -46, 7, -1707, -529, -720, -167, 1213, +429, 1296, 386, -574, -331, -1489, -666, -128, +195, 1358, 680, 733, 91, -1047, -742, -1079, +-325, 564, 617, 1204, 419, -86, -347, -1130, +-613, -299, 121, 877, 561, 608, 108, -539, +-494, -733, -399, 115, 396, 738, 479, 276, +-161, -584, -564, -582, -139, 244, 515, 831, +316, 59, -271, -798, -553, -436, -22, 661, +535, 754, 321, -508, -376, -832, -646, 118, +154, 996, 699, 172, 177, -995, -779, -474, +-438, 789, 670, 937, 566, -609, -469, -1126, +-765, 137, 299, 1217, 698, 407, -18, -1101, +-656, -784, -296, 595, 535, 1102, 432, -80, +-217, -1054, -679, -450, -45, 723, 686, 839, +271, -308, -527, -881, -605, -210, 388, 741, +653, 538, -66, -406, -728, -685, -261, -21, +702, 664, 416, 361, -485, -431, -643, -651, +297, 116, 624, 755, -60, 279, -524, -703, +-213, -644, 349, 476, 299, 915, -95, -89, +-397, -1014, -106, -318, 288, 858, 254, 711, +-138, -522, -357, -938, -30, 65, 267, 930, +278, 416, -230, -730, -412, -766, 45, 355, +474, 952, 162, 69, -495, -935, -295, -484, +295, 773, 431, 768, -67, -477, -485, -915, +-206, 133, 343, 975, 464, 124, -166, -832, +-604, -396, -81, 698, 508, 593, 292, -524, +-348, -654, -388, 209, 85, 782, 324, 45, +158, -756, -219, -368, -291, 578, 59, 731, +281, -352, 103, -899, -282, -63, -174, 949, +167, 488, 215, -822, -88, -783, -249, 498, +14, 952, 200, -153, 58, -918, -144, -183, +-95, 733, 41, 407, 48, -433, 41, -539, +49, 108, -106, 530, -141, 200, 35, -395, +227, -494, 37, 194, -212, 650, -104, 96, +59, -686, 160, -423, 70, 580, -85, 661, +-232, -309, -37, -821, 355, -3, 120, 796, +-356, 310, -312, -631, 354, -507, 452, 409, +-307, 567, -585, -140, 99, -556, 768, -59, +110, 455, -813, 227, -430, -316, 705, -378, +789, 185, -519, 435, -977, 19, 122, -471, +1092, -211, 247, 418, -1032, 357, -565, -227, +762, -483, 843, 45, -471, 438, -911, 177, +48, -326, 886, -340, 323, 175, -720, 346, +-599, 78, 383, -355, 826, -237, -113, 225, +-789, 366, -240, -10, 655, -497, 473, -132, +-430, 400, -542, 388, 60, -282, 575, -559, +202, 102, -450, 540, -428, 247, 182, -543, +634, -438, 30, 332, -591, 562, -351, -36, +435, -615, 607, -147, -241, 432, -668, 346, +-125, -176, 652, -415, 371, -67, -480, 279, +-500, 346, 142, -90, 586, -484, 107, -162, +-493, 458, -357, 437, 349, -331, 553, -637, +-233, 118, -613, 684, 33, 178, 684, -650, +123, -424, -650, 480, -325, 576, 527, -175, +559, -651, -403, -102, -669, 557, 120, 356, +769, -346, 133, -540, -736, 96, -326, 560, +505, 190, 548, -454, -346, -406, -575, 244, +64, 510, 556, 46, 199, -467, -549, -331, +-353, 276, 435, 512, 534, -1, -315, -543, +-677, -301, 157, 447, 686, 509, 110, -214, +-649, -624, -349, -61, 470, 617, 550, 259, +-192, -463, -657, -461, -83, 300, 600, 540, +328, -103, -462, -526, -484, -146, 262, 537, +516, 291, -44, -413, -508, -475, -106, 275, +386, 642, 217, -154, -227, -681, -305, -96, +95, 757, 242, 311, 97, -736, -194, -525, +-210, 574, 84, 823, 204, -391, 80, -993, +-191, 22, -143, 1085, 89, 413, 133, -1011, +73, -836, -171, 693, -112, 1210, 67, -221, +202, -1377, 13, -391, -285, 1305, -53, 998, +257, -978, 177, -1430, -294, 382, -232, 1684, +244, 241, 291, -1577, -159, -884, -353, 1225, +70, 1383, 337, -719, 82, -1603, -344, 53, +-177, 1613, 240, 563, 326, -1382, -141, -1030, +-441, 869, 38, 1361, 430, -297, 173, -1387, +-450, -332, -287, 1137, 334, 879, 361, -703, +-120, -1183, -480, 125, -11, 1223, 408, 450, +222, -1031, -321, -880, -383, 622, 204, 1117, +395, -155, 21, -1124, -383, -268, -225, 935, +292, 563, 339, -670, -90, -701, -419, 386, +-78, 718, 353, -144, 173, -677, -171, -37, +-216, 565, 15, 210, 120, -474, 121, -348, +48, 327, -196, 429, -182, -123, 131, -482, +311, -74, 1, 394, -407, 281, -134, -223, +376, -444, 362, -3, -353, 464, -529, 275, +244, -427, 670, -478, -51, 256, -799, 618, +-124, -52, 800, -674, 358, -167, -726, 584, +-571, 400, 588, -463, 712, -538, -337, 217, +-822, 599, 87, 51, 805, -582, 208, -265, +-684, 364, -487, 458, 508, -130, 663, -508, +-180, -165, -822, 389, -110, 452, 817, -216, +429, -592, -680, -103, -730, 630, 499, 387, +834, -524, -110, -648, -867, 283, -243, 805, +733, -29, 520, -824, -380, -292, -739, 756, +54, 526, 697, -580, 311, -713, -476, 281, +-575, 843, 214, -25, 606, -794, 136, -333, +-503, 652, -360, 602, 317, -440, 438, -752, +-52, 74, -398, 816, -168, 245, 280, -696, +297, -540, -53, 413, -388, 729, -155, -88, +390, -731, 364, -285, -255, 568, -554, 526, +110, -304, 637, -653, 148, -20, -578, 602, +-409, 267, 452, -426, 571, -469, -176, 203, +-624, 502, -81, 55, 547, -460, 285, -331, +-305, 326, -397, 493, 101, -74, 344, -631, +111, -224, -189, 602, -185, 495, 66, -444, +129, -771, 114, 167, -34, 860, -118, 161, +-102, -803, 102, -517, 238, 593, -59, 712, +-219, -266, -59, -817, 265, -77, 127, 730, +-191, 338, -181, -529, 93, -552, 303, 261, +18, 578, -267, -8, -192, -514, 273, -273, +366, 370, -165, 387, -423, -126, 1, -482, +490, -161, 172, 413, -379, 370, -283, -194, +239, -586, 386, -104, -68, 590, -324, 435, +-81, -429, 263, -799, 201, 140, -93, 915, +-186, 302, -64, -930, 183, -768, 214, 684, +-38, 1085, -251, -227, -99, -1303, 264, -317, +247, 1177, -82, 838, -307, -819, -110, -1259, +337, 265, 333, 1349, -164, 384, -492, -1243, +23, -961, 612, 813, 198, 1305, -514, -256, +-398, -1454, 466, -335, 541, 1245, -260, 840, +-541, -864, 53, -1185, 609, 298, 124, 1204, +-440, 292, -252, -1041, 332, -797, 399, 570, +-154, 1054, -324, -8, -7, -1101, 315, -587, +179, 786, -172, 1043, -183, -304, 37, -1312, +257, -329, 122, 1219, -122, 910, -198, -920, +25, -1345, 310, 373, 156, 1491, -229, 197, +-287, -1437, 249, -735, 421, 1076, -78, 1093, +-466, -644, 28, -1280, 560, 96, 117, 1198, +-484, 376, -221, -988, 541, -758, 370, 558, +-389, 937, -437, -134, 276, -975, 624, -300, +-49, 764, -561, 612, -169, -536, 564, -791, +472, 174, -342, 779, -541, 107, 97, -717, +668, -347, 255, 492, -507, 473, -453, -312, +334, -567, 709, 89, -2, 502, -657, 81, +-228, -464, 572, -228, 537, 307, -253, 272, +-579, -176, -20, -322, 615, -2, 442, 216, +-365, 97, -608, -135, 141, -215, 753, -31, +310, 175, -598, 148, -506, -158, 342, -263, +769, 11, 138, 265, -678, 85, -453, -268, +504, -206, 840, 144, -105, 254, -836, -58, +-209, -292, 780, -100, 592, 222, -416, 210, +-658, -189, 132, -320, 721, 9, 289, 359, +-497, 117, -448, -353, 345, -318, 640, 187, +20, 426, -530, -37, -181, -488, 496, -273, +446, 373, -134, 466, -481, -185, -44, -640, +537, -186, 390, 635, -252, 466, -538, -455, +160, -809, 646, 103, 206, 909, -465, 261, +-317, -849, 407, -717, 446, 585, -44, 920, +-328, -207, -20, -1057, 314, -286, 214, 928, +-41, 623, -164, -646, 39, -974, 246, 241, +151, 1023, -112, 178, -97, -987, 201, -625, +225, 749, -75, 840, -123, -418, 142, -1042, +225, 58, 11, 988, -109, 226, 46, -863, +177, -545, 126, 660, -24, 617, -70, -419, +122, -745, 227, 129, 20, 720, -156, 25, +89, -670, 329, -296, 32, 566, -242, 407, +50, -493, 403, -556, 130, 273, -292, 641, +-108, -149, 378, -675, 317, -122, -143, 579, +-296, 304, 162, -481, 436, -486, 104, 188, +-277, 538, -116, 33, 366, -537, 309, -335, +-121, 329, -255, 515, 167, -149, 429, -627, +27, -213, -275, 559, -8, 478, 418, -428, +200, -730, -236, 51, -123, 816, 262, 279, +364, -763, -55, -692, -238, 410, 37, 945, +411, -43, 250, -1013, -271, -511, -210, 788, +297, 893, 496, -437, -61, -1122, -398, -156, +23, 1076, 526, 596, 349, -839, -338, -996, +-329, 333, 304, 1127, 612, 80, 24, -1066, +-478, -582, -47, 776, 508, 856, 377, -469, +-208, -1036, -273, -30, 136, 1031, 400, 368, +250, -926, -161, -769, -216, 601, 119, 988, +470, -321, 203, -1090, -286, -132, -210, 987, +322, 425, 520, -843, -39, -684, -370, 484, +-5, 780, 490, -249, 308, -813, -188, -67, +-220, 685, 124, 254, 397, -628, 231, -460, +-100, 411, -243, 559, 88, -276, 479, -700, +286, -3, -252, 661, -321, 246, 280, -635, +591, -539, 92, 352, -418, 691, -157, -69, +514, -781, 459, -334, -156, 585, -382, 617, +136, -359, 547, -837, 217, -59, -265, 771, +-226, 399, 304, -660, 505, -701, 40, 286, +-347, 782, -62, 37, 489, -801, 364, -408, +-178, 548, -256, 624, 146, -300, 457, -799, +192, -68, -180, 692, -185, 361, 233, -575, +459, -615, 58, 236, -259, 623, -22, 53, +398, -583, 276, -336, -132, 273, -138, 413, +191, -11, 375, -409, 67, -294, -198, 123, +3, 420, 379, 115, 246, -417, -166, -452, +-136, 179, 282, 586, 352, 53, -18, -630, +-158, -415, 87, 460, 317, 556, 180, -263, +-85, -676, -54, -61, 166, 614, 289, 236, +61, -501, -87, -498, 46, 260, 243, 570, +220, -72, -40, -641, -64, -261, 127, 547, +293, 450, 146, -423, -98, -674, -53, 116, +172, 709, 320, 113, 162, -659, -153, -433, +-148, 405, 234, 554, 499, -164, 106, -625, +-366, -204, -99, 474, 443, 402, 500, -312, +-87, -606, -384, -10, -8, 602, 548, 238, +485, -578, -270, -540, -474, 354, 230, 693, +775, -143, 181, -842, -585, -226, -194, 767, +614, 531, 577, -664, -225, -860, -477, 302, +154, 976, 636, 52, 296, -1024, -344, -477, +-286, 750, 330, 739, 556, -475, 98, -938, +-341, 63, -135, 841, 373, 266, 459, -759, +23, -547, -296, 469, -76, 634, 396, -248, +418, -746, -6, -23, -323, 643, -57, 214, +482, -597, 427, -454, -127, 391, -398, 540, +101, -201, 592, -689, 292, -78, -288, 618, +-322, 294, 293, -577, 616, -557, 104, 362, +-431, 634, -188, -161, 563, -729, 506, -109, +-211, 599, -414, 282, 163, -470, 620, -514, +189, 199, -302, 510, -202, 76, 304, -527, +495, -425, 52, 302, -285, 604, -109, -6, +389, -767, 407, -420, -56, 624, -261, 747, +16, -369, 417, -1063, 302, -101, -98, 1051, +-238, 547, 92, -902, 429, -1007, 235, 459, +-139, 1179, -197, 32, 142, -1215, 392, -609, +241, 916, -155, 985, -268, -510, 191, -1274, +541, -63, 180, 1232, -406, 546, -209, -1055, +486, -1019, 537, 643, -143, 1209, -478, -202, +86, -1307, 649, -318, 334, 1115, -404, 679, +-421, -829, 409, -1013, 760, 369, 17, 1054, +-697, 47, -150, -1001, 838, -496, 573, 724, +-491, 715, -664, -415, 410, -886, 931, 22, +73, 792, -750, 238, -271, -646, 801, -483, +669, 358, -371, 494, -690, -138, 201, -474, +905, -115, 248, 300, -607, 186, -412, -164, +551, -266, 754, -25, -106, 182, -629, 90, +-129, -124, 744, -190, 539, -23, -351, 130, +-592, 100, 183, -95, 812, -240, 253, -49, +-507, 219, -398, 172, 425, -241, 692, -364, +13, 105, -505, 414, -186, 36, 540, -516, +495, -255, -122, 405, -424, 398, -15, -281, +527, -583, 359, 47, -193, 553, -389, 183, +152, -534, 555, -441, 190, 326, -324, 541, +-244, -98, 351, -651, 447, -187, 13, 511, +-331, 399, -76, -362, 414, -599, 341, 92, +-117, 581, -324, 168, 128, -579, 448, -414, +139, 377, -238, 519, -107, -190, 291, -648, +249, -33, -34, 555, -101, 198, 76, -518, +188, -399, 101, 386, 3, 453, -27, -228, +73, -602, 179, 12, 99, 593, -79, 182, +-35, -554, 216, -501, 226, 376, -57, 643, +-175, -123, 99, -778, 338, -261, 155, 706, +-213, 539, -204, -493, 266, -842, 458, 137, +-2, 901, -425, 226, -55, -844, 546, -646, +337, 586, -302, 840, -357, -236, 252, -972, +550, -201, 66, 837, -399, 504, -167, -568, +457, -785, 436, 167, -204, 783, -399, 210, +131, -666, 559, -588, 153, 347, -372, 712, +-211, 21, 350, -734, 460, -421, -81, 489, +-365, 641, -13, -159, 427, -780, 277, -266, +-184, 640, -255, 607, 88, -408, 349, -882, +205, 6, -150, 923, -253, 371, 91, -846, +404, -758, 208, 530, -270, 950, -265, -164, +235, -1028, 448, -289, 73, 832, -386, 634, +-150, -531, 372, -883, 402, 84, -103, 882, +-385, 328, 22, -755, 412, -706, 297, 425, +-196, 881, -328, -36, 104, -949, 467, -411, +245, 755, -343, 747, -313, -449, 304, -998, +532, -3, 2, 979, -472, 429, -89, -805, +477, -809, 363, 420, -218, 955, -361, 12, +125, -959, 433, -472, 177, 699, -217, 766, +-231, -352, 120, -948, 356, -100, 192, 861, +-200, 462, -269, -659, 122, -763, 394, 286, +172, 843, -253, 81, -278, -796, 140, -445, +453, 554, 171, 648, -364, -271, -331, -745, +310, -73, 564, 647, -35, 317, -541, -476, +-145, -496, 559, 213, 449, 506, -320, 1, +-535, -461, 162, -205, 711, 310, 149, 285, +-560, -179, -291, -367, 503, 13, 539, 338, +-220, 112, -487, -302, 50, -255, 562, 189, +218, 293, -353, -55, -239, -321, 269, -116, +386, 226, -68, 220, -244, -88, 33, -323, +247, -91, 125, 272, -118, 256, -35, -208, +114, -426, 122, 44, -39, 479, -62, 169, +126, -517, 104, -412, -48, 397, -85, 593, +107, -200, 144, -753, -15, -69, -82, 731, +-30, 352, 124, -634, 152, -625, -6, 405, +-175, 763, -25, -126, 274, -856, 168, -206, +-194, 784, -220, 499, 192, -598, 346, -771, +-11, 270, -295, 856, -77, 122, 343, -804, +272, -523, -165, 533, -308, 773, 108, -143, +426, -870, 112, -297, -285, 698, -181, 636, +275, -378, 324, -835, -47, -50, -231, 769, +-9, 430, 238, -561, 142, -702, -46, 224, +-90, 781, 0, 129, 113, -745, 123, -453, +32, 544, -110, 680, -54, -268, 150, -823, +135, -85, -53, 766, -116, 424, 57, -564, +119, -701, 19, 190, -40, 747, -24, 233, +56, -598, 47, -590, -13, 229, -14, 711, +66, 219, 39, -616, -88, -601, 23, 266, +163, 793, 23, 169, -157, -786, -3, -589, +247, 532, 76, 878, -169, -179, -90, -998, +206, -232, 212, 890, -85, 598, -174, -657, +49, -837, 284, 279, 89, 904, -160, 96, +-97, -817, 140, -405, 222, 553, 20, 595, +-134, -252, -73, -624, 155, -54, 198, 475, +-36, 294, -135, -270, -8, -394, 165, -18, +101, 346, -61, 245, -90, -199, 8, -365, +139, -61, 47, 361, -65, 266, -73, -232, +41, -417, 112, -12, 10, 447, -67, 221, +-83, -330, 69, -427, 125, 130, 8, 509, +-133, 91, -79, -470, 155, -340, 158, 348, +-38, 455, -194, -143, -43, -491, 225, -83, +188, 424, -71, 211, -247, -247, 15, -334, +286, 51, 197, 325, -145, 128, -258, -201, +91, -301, 310, 52, 161, 292, -198, 165, +-203, -192, 130, -342, 299, 12, 105, 337, +-231, 240, -131, -272, 160, -381, 247, 88, +-10, 382, -189, 112, -32, -316, 132, -185, +132, 122, -40, 179, -107, 26, -43, -91, +94, -81, 143, -88, -89, 76, -176, 189, +42, 54, 207, -244, -38, -238, -222, 209, +30, 384, 163, -30, 9, -533, -140, -198, +-27, 537, 75, 462, 40, -404, -1, -705, +-66, 178, -15, 783, 74, 159, 71, -731, +-59, -472, -47, 516, 99, 657, 79, -170, +-43, -732, -39, -145, 68, 599, 104, 391, +32, -363, -51, -528, -53, 111, 122, 472, +167, 144, -33, -350, -165, -320, 49, 157, +210, 367, 34, 103, -112, -358, -36, -303, +73, 190, 81, 420, 44, 72, -75, -433, +-130, -304, 75, 246, 180, 496, -34, 57, +-230, -542, -45, -370, 200, 357, 135, 638, +-150, -81, -265, -743, 30, -266, 293, 628, +71, 591, -285, -379, -220, -772, 143, 10, +249, 770, 65, 382, -246, -617, -307, -673, +128, 289, 471, 829, 65, 108, -530, -796, +-244, -475, 463, 558, 416, 751, -219, -223, +-454, -841, -24, -162, 451, 744, 335, 495, +-279, -516, -490, -676, 148, 152, 607, 722, +83, 193, -515, -572, -204, -487, 404, 265, +339, 674, -162, 73, -366, -622, -32, -444, +345, 422, 248, 693, -255, -115, -383, -709, +93, -289, 417, 597, 90, 548, -392, -295, +-310, -650, 204, -91, 446, 606, -14, 333, +-582, -333, -270, -482, 512, 39, 456, 456, +-417, 159, -644, -250, 143, -316, 636, 80, +108, 299, -584, 78, -402, -202, 387, -222, +568, 123, -143, 232, -689, 31, -114, -223, +665, -166, 360, 143, -533, 227, -517, 38, +368, -265, 611, -197, -103, 158, -570, 310, +-103, 25, 506, -331, 296, -176, -300, 197, +-386, 306, 134, -35, 409, -300, 86, -132, +-299, 209, -249, 259, 168, -116, 327, -269, +35, -30, -334, 258, -230, 125, 250, -208, +317, -177, -132, 84, -409, 240, -22, -3, +311, -204, 83, -93, -256, 112, -213, 173, +79, -8, 157, -119, 18, -160, -198, 6, +-204, 264, 103, 158, 242, -240, -62, -378, +-376, 145, -49, 489, 348, 51, 98, -477, +-323, -291, -213, 373, 212, 434, 215, -146, +-69, -473, -219, -96, -89, 423, 164, 263, +203, -264, -16, -386, -259, 64, -91, 425, +232, 131, 236, -362, -113, -329, -305, 237, +-7, 456, 310, -40, 188, -477, -265, -188, +-323, 397, 172, 370, 395, -200, -42, -480, +-479, -11, -84, 477, 417, 196, 174, -381, +-377, -339, -313, 269, 233, 371, 263, -110, +-111, -345, -317, -40, -97, 271, 186, 124, +134, -117, -113, -205, -290, -14, -45, 197, +193, 135, 76, -110, -196, -248, -200, 56, +71, 268, 134, 22, -7, -279, -165, -89, +-114, 326, 81, 107, 121, -300, -25, -181, +-198, 281, -26, 248, 187, -241, 74, -255, +-188, 109, -136, 288, 184, -4, 162, -260, +-119, -94, -208, 177, 85, 209, 229, -120, +-51, -240, -193, -6, -21, 259, 143, 161, +29, -226, -60, -286, -51, 83, -78, 420, +27, 66, 82, -430, -25, -220, -168, 356, +-47, 347, 110, -231, 1, -350, -102, 33, +-113, 298, -9, 92, 57, -179, 5, -133, +-136, 53, -175, 149, 91, -38, 151, -101, +-106, 34, -269, 93, -47, -45, 179, -139, +68, 46, -117, 154, -193, 91, -72, -152, +107, -247, 153, 36, -49, 346, -259, 214, +-116, -319, 175, -409, 246, 124, -61, 515, +-361, 159, -127, -511, 336, -418, 313, 324, +-276, 653, -398, -33, 90, -726, 350, -318, +106, 590, -241, 666, -269, -268, -12, -869, +308, -185, 180, 868, -279, 696, -313, -600, +35, -1071, 266, 92, 136, 1165, -196, 505, +-378, -928, -78, -983, 434, 428, 179, 1233, +-478, 218, -430, -1162, 253, -808, 451, 760, +-103, 1180, -518, -114, -288, -1204, 362, -549, +437, 885, -265, 1032, -636, -287, -60, -1212, +559, -407, 241, 999, -420, 978, -536, -405, +56, -1204, 573, -350, 224, 1003, -532, 997, +-567, -392, 261, -1328, 652, -367, 52, 1215, +-617, 1039, -445, -630, 404, -1440, 609, -162, +-139, 1342, -647, 915, -159, -789, 452, -1357, +263, 75, -208, 1334, -367, 659, -63, -912, +260, -1142, 164, 259, -210, 1226, -279, 490, +83, -922, 151, -982, -87, 339, -167, 1112, +-13, 331, 56, -858, -42, -835, -115, 279, +-131, 1031, 48, 446, 125, -797, -140, -1000, +-278, 200, -32, 1171, 262, 480, 1, -853, +-320, -956, -232, 264, 146, 1056, 299, 397, +-94, -774, -471, -868, -167, 213, 439, 969, +252, 452, -453, -663, -456, -900, 237, 106, +457, 1001, -81, 544, -489, -752, -224, -1010, +326, 256, 358, 1177, -222, 367, -500, -964, +-20, -787, 425, 444, 113, 902, -297, 91, +-253, -680, -6, -422, 197, 288, 133, 524, +-157, 93, -334, -315, -41, -356, 239, -29, +113, 382, -193, 366, -303, -145, -55, -559, +216, -141, 83, 522, -266, 405, -196, -274, +82, -552, 28, -26, -108, 487, -70, 321, +-42, -222, -100, -413, -18, -58, -15, 261, +-148, 231, -11, 23, 79, -185, -129, -262, +-212, 5, 13, 356, 109, 264, -74, -266, +-103, -461, -66, -2, -65, 494, -25, 385, +-5, -291, 2, -613, -55, -125, -114, 576, +-90, 604, 82, -228, 86, -856, -193, -323, +-234, 760, 72, 858, 183, -281, -33, -1024, +-246, -375, -156, 789, 72, 879, 123, -202, +-93, -990, -226, -469, -55, 743, 140, 965, +8, -150, -291, -1100, -164, -538, 175, 817, +147, 1070, -278, -161, -361, -1186, 59, -566, +311, 874, 0, 1108, -437, -179, -348, -1205, +172, -625, 369, 826, -74, 1204, -507, -7, +-252, -1214, 215, -850, 236, 694, -79, 1333, +-372, 175, -285, -1239, 131, -988, 348, 696, +-114, 1479, -465, 201, -151, -1440, 202, -1126, +94, 890, -60, 1730, -167, 81, -301, -1724, +-44, -1054, 301, 1133, 88, 1707, -351, -123, +-314, -1758, 1, -955, 246, 1228, 173, 1704, +-286, -183, -540, -1774, 11, -946, 503, 1209, +104, 1676, -540, -146, -447, -1789, 145, -948, +477, 1281, 81, 1721, -626, -257, -559, -1885, +337, -869, 636, 1366, -181, 1635, -781, -281, +-360, -1766, 422, -771, 581, 1233, -193, 1469, +-938, -298, -414, -1606, 742, -590, 664, 1229, +-615, 1286, -1041, -525, -15, -1539, 893, -237, +368, 1402, -793, 970, -904, -954, 186, -1467, +927, 295, 206, 1679, -950, 555, -810, -1431, +384, -1340, 942, 745, 47, 1761, -1005, 300, +-767, -1605, 498, -1280, 982, 928, -68, 1812, +-1162, 129, -639, -1674, 729, -1104, 837, 988, +-321, 1585, -1053, 52, -355, -1432, 669, -877, +533, 764, -427, 1151, -762, 110, -37, -838, +469, -564, 29, 191, -485, 500, -235, 250, +326, -33, 105, -167, -502, -291, -453, -242, +262, 138, 558, 500, -195, 394, -826, -213, +-423, -653, 555, -472, 559, 329, -308, 951, +-840, 454, -298, -689, 540, -998, 387, -150, +-443, 883, -647, 896, 21, -155, 497, -999, +-28, -555, -575, 653, -370, 826, 319, -183, +405, -831, -313, -134, -603, 886, -121, 466, +354, -809, 119, -1039, -316, 445, -303, 1488, +0, 385, 51, -1273, -166, -1273, -162, 555, +77, 1484, -12, 366, -271, -1099, -151, -805, +44, 667, -67, 835, -188, -377, -77, -1004, +18, 80, -78, 1343, -147, 589, -167, -1147, +-115, -1462, 63, 363, -63, 1782, -304, 707, +-175, -1346, 150, -1489, 191, 588, -136, 1888, +-477, 350, -590, -1850, 43, -1432, 779, 1181, +351, 2290, -696, 208, -985, -2121, -209, -1666, +668, 1042, 643, 2296, -354, 299, -1002, -1921, +-313, -1296, 646, 1157, 492, 1871, -486, -188, +-915, -1907, -206, -942, 699, 1380, 551, 1738, +-565, -332, -958, -1673, -81, -572, 712, 1127, +191, 984, -774, -587, -567, -1173, 479, 89, +685, 1415, -447, 730, -1163, -1165, -208, -1615, +1012, 170, 623, 1801, -878, 1112, -1241, -1009, +13, -1763, 1097, -181, 611, 1640, -809, 1176, +-1358, -842, -209, -1762, 998, -275, 762, 1651, +-462, 1482, -1125, -563, -434, -2010, 542, -878, +548, 1337, -248, 1698, -695, 59, -256, -1436, +297, -945, 377, 586, -229, 1086, -792, 132, +-343, -866, 451, -554, 605, 535, -171, 1002, +-874, 93, -639, -1071, 278, -993, 878, 457, +184, 1485, -995, 664, -986, -972, 220, -1403, +1050, -12, 333, 1243, -933, 747, -992, -591, +68, -882, 860, 214, 284, 723, -753, -26, +-761, -712, 254, -183, 661, 793, -102, 577, +-840, -623, -423, -943, 424, 115, 499, 1160, +-174, 541, -721, -863, -453, -1143, 373, 111, +570, 1353, -301, 859, -980, -816, -183, -1419, +846, -203, 474, 1243, -728, 1005, -1206, -421, +-104, -1115, 1200, -371, 749, 755, -1030, 698, +-1490, -208, 137, -618, 1326, -191, 444, 363, +-1115, 359, -1173, -76, 384, -212, 1243, 41, +48, 81, -1426, -276, -926, -302, 866, 396, +1367, 913, -275, 160, -1649, -1075, -882, -1171, +923, 285, 1261, 1675, -190, 1040, -1310, -933, +-708, -1787, 644, -448, 790, 1342, -373, 1434, +-945, -147, -144, -1397, 735, -873, 285, 663, +-751, 1223, -816, 270, 155, -812, 853, -907, +302, 72, -787, 878, -1054, 652, -52, -280, +962, -825, 709, -386, -515, 428, -1171, 763, +-691, 220, 468, -686, 1076, -752, 314, 296, +-727, 1113, -943, 408, -424, -1015, 297, -1292, +660, 268, 444, 1685, -353, 1042, -851, -939, +-578, -1878, 92, -593, 618, 1326, 419, 1747, +-231, 305, -720, -1387, -542, -1523, 193, -133, +435, 1331, 59, 1343, -406, -43, -197, -1258, +198, -1001, -61, 393, -496, 1082, -384, 359, +212, -673, 603, -655, 187, 445, -503, 902, +-793, -106, -373, -1161, 233, -633, 494, 903, +477, 1305, 1, 169, -754, -1123, -1025, -1044, +-212, 184, 812, 953, 901, 530, -2, -162, +-1074, -388, -950, -233, 314, -156, 977, 78, +174, 376, -908, 277, -779, -157, 376, -537, +997, -176, 201, 606, -1146, 711, -1083, -206, +298, -1085, 1191, -690, 476, 690, -901, 1400, +-1047, 525, 120, -1008, 915, -1385, 167, -196, +-1051, 1023, -705, 1052, 723, 68, 1183, -746, +-230, -690, -1641, -120, -831, 469, 969, 632, +1432, 271, -156, -499, -1563, -952, -866, -99, +830, 1153, 1276, 1056, -154, -554, -1367, -1643, +-815, -733, 599, 1269, 1092, 1728, 148, 101, +-778, -1634, -801, -1302, -84, 672, 475, 1588, +287, 421, -151, -1290, -317, -1076, 17, 810, +196, 1524, -157, 17, -569, -1675, -450, -1117, +415, 1050, 948, 1832, 271, 312, -924, -1469, +-1245, -1258, -218, 366, 1104, 1125, 1120, 403, +-300, -407, -1381, -331, -767, 233, 693, 19, +1001, -588, -76, -252, -1038, 758, -576, 887, +662, -292, 917, -1103, -221, -357, -1331, 668, +-799, 716, 856, -121, 1465, -614, 253, -124, +-1502, 442, -1608, 268, 95, -358, 1639, -471, +1402, 158, -497, 695, -1898, 397, -1294, -568, +575, -1016, 1727, -98, 968, 1130, -673, 1111, +-1624, -266, -1043, -1521, 515, -1185, 1468, 556, +934, 1968, -575, 1424, -1564, -959, -1054, -2615, +577, -1420, 1710, 1702, 813, 3136, -1048, 910, +-1768, -2565, -593, -3130, 1214, 88, 1662, 3297, +123, 2547, -1664, -1379, -1508, -3579, 447, -1300, +1684, 2515, 764, 3171, -982, -25, -1515, -3050, +-174, -2313, 1151, 987, 881, 3010, -530, 1516, +-1182, -1491, -275, -2656, 826, -967, 697, 1841, +-404, 2416, -986, 208, -260, -2140, 626, -1792, +666, 741, -213, 2022, -759, 754, -346, -1179, +310, -1454, 380, 116, -144, 1129, -261, 651, +140, -444, 206, -698, -332, -10, -641, 460, +-92, 67, 751, -397, 751, -167, -380, 566, +-1201, 616, -560, -260, 810, -967, 1003, -658, +-107, 558, -1001, 1292, -520, 632, 562, -712, +690, -1410, -294, -639, -805, 785, -30, 1393, +691, 641, 276, -754, -537, -1208, -661, -511, +105, 463, 739, 895, 321, 590, -677, -48, +-868, -602, 150, -817, 916, -394, 420, 519, +-556, 1287, -842, 762, -243, -860, 497, -1870, +558, -632, 82, 1566, -346, 2149, -446, 17, +-426, -2239, 44, -1733, 637, 843, 623, 2219, +-185, 849, -1082, -1190, -852, -1462, 411, -161, +1416, 883, 886, 620, -982, 2, -1847, -260, +-725, -252, 1415, -161, 2021, 31, 255, 298, +-1930, 153, -1996, -212, 265, -323, 2180, 152, +1534, 535, -849, 169, -2279, -613, -1049, -677, +1285, 165, 2100, 962, 504, 675, -1749, -436, +-1966, -1264, 51, -752, 2004, 850, 1613, 1705, +-752, 707, -2196, -1433, -1113, -2153, 1278, -368, +2095, 2120, 285, 2310, -1883, -193, -1696, -2531, +561, -2005, 2037, 639, 920, 2451, -1281, 1577, +-1936, -843, -283, -2091, 1600, -1089, 1403, 920, +-359, 1634, -1497, 547, -807, -1038, 497, -1088, +897, 266, 320, 1076, -388, 215, -433, -973, +-158, -741, 81, 650, 116, 1351, -1, 255, +-32, -1363, 44, -1317, 159, 405, -139, 1652, +-340, 816, -144, -840, 238, -1312, 396, -269, +81, 771, -401, 692, -549, 2, -40, -270, +559, -28, 501, -144, -72, -393, -557, -369, +-631, 468, -2, 1032, 535, 526, 616, -811, +143, -1485, -528, -418, -822, 1100, -403, 1433, +650, 236, 1022, -982, 160, -986, -870, -191, +-934, 433, 5, 486, 874, 447, 714, 229, +-291, -212, -1000, -731, -436, -592, 531, 91, +813, 742, 122, 735, -737, 30, -722, -531, +115, -655, 871, -308, 535, 280, -608, 659, +-1020, 516, -166, -248, 1000, -710, 969, -357, +-342, 445, -1274, 592, -877, -169, 574, -745, +1452, -131, 732, 912, -720, 753, -1372, -569, +-702, -1390, 419, -454, 1153, 1132, 911, 1427, +-62, 37, -1016, -1343, -1257, -974, -378, 360, +978, 996, 1613, 298, 459, -524, -1293, -332, +-1614, 468, -100, 596, 1329, -489, 1103, -1293, +-422, -479, -1283, 1329, -356, 1942, 941, 243, +865, -1926, -483, -2152, -1289, -3, -545, 1993, +1018, 1797, 1587, 87, 239, -1350, -1507, -1256, +-1704, -392, -155, 263, 1447, 512, 1729, 851, +458, 1130, -1312, 342, -1834, -1505, -887, -2450, +806, -1043, 1896, 2026, 1464, 3508, -396, 1475, +-1955, -2319, -1794, -3951, -147, -1667, 1613, 2151, +2129, 3726, 727, 1903, -1372, -1553, -2275, -3317, +-1081, -2022, 822, 897, 2141, 2729, 1638, 1955, +-436, -298, -2285, -1974, -1937, -1845, 420, -196, +2350, 1444, 1803, 1689, -699, 340, -2271, -1211, +-1280, -1356, 829, -153, 1840, 1007, 913, 1005, +-743, 27, -1523, -934, -881, -898, 457, -20, +1348, 957, 1116, 1108, -100, 208, -1573, -985, +-1530, -1548, 103, -719, 1635, 913, 1497, 2113, +-15, 1594, -1312, -751, -1340, -2818, -286, -2474, +608, 507, 892, 3361, 834, 3162, 496, -303, +-506, -3533, -1740, -3295, -1670, 191, 341, 3102, +2592, 2661, 2515, 92, -393, -1960, -3079, -1731, +-2738, -511, 198, 474, 2830, 827, 2833, 993, +332, 823, -2312, -137, -2894, -1370, -1004, -1604, +1726, -252, 2914, 1503, 1562, 1899, -1256, 336, +-2884, -1573, -1806, -1756, 995, -28, 2634, 1647, +1593, 1178, -819, -647, -2126, -1424, -1137, -238, +653, 1116, 1381, 757, 514, -531, -517, -885, +-432, 37, 120, 743, 63, 117, -564, -761, +-405, -282, 492, 895, 1105, 1065, 525, -430, +-879, -1630, -1474, -983, -503, 751, 1117, 1775, +1538, 1054, 370, -480, -1060, -1573, -1435, -1395, +-336, -134, 995, 1250, 1108, 1712, 220, 736, +-703, -859, -643, -1694, -131, -995, 366, 347, +85, 1086, -166, 832, 239, 327, 806, 85, +191, -354, -1146, -1195, -1398, -1520, 42, -140, +1878, 2217, 1820, 2667, -333, 136, -2563, -2863, +-1932, -2880, 938, 225, 2714, 2731, 1532, 2144, +-1153, -514, -2422, -1888, -1040, -1009, 1212, 586, +1776, 827, 330, 18, -973, -559, -694, -122, +281, 760, 383, 654, -398, -357, -709, -1219, +253, -710, 1423, 680, 989, 1400, -890, 631, +-2132, -996, -1105, -1579, 1202, -135, 2519, 1670, +1313, 1533, -1334, -843, -2649, -2464, -1237, -978, +1226, 1920, 2195, 2643, 1114, 218, -650, -2335, +-1411, -2007, -946, 317, -93, 1687, 424, 872, +734, -401, 945, -249, 549, 485, -500, 22, +-1374, -1274, -1288, -1531, -62, 262, 1494, 2234, +1903, 2073, 756, -53, -1243, -2147, -2111, -2195, +-1304, -748, 618, 1009, 1965, 2099, 1674, 1884, +226, 460, -1277, -1667, -1785, -2762, -1129, -1741, +445, 785, 1738, 2916, 1717, 2638, 409, 270, +-1297, -2326, -2005, -2958, -970, -1061, 862, 1383, +1838, 2243, 1129, 1217, -428, -101, -1255, -739, +-782, -898, 221, -1049, 551, -892, -3, 114, +-176, 1570, 352, 2154, 744, 926, 275, -1297, +-703, -2673, -1179, -1974, -693, 422, 549, 2480, +1444, 2591, 1288, 594, 33, -1665, -1383, -2500, +-1762, -1311, -607, 689, 1091, 1615, 1801, 1184, +1037, 284, -260, -21, -1211, -391, -1347, -1109, +-710, -1634, 341, -729, 1454, 1473, 1721, 2817, +733, 1697, -1297, -1235, -2497, -3109, -1551, -2199, +1117, 483, 2816, 2432, 1933, 2200, -716, 466, +-2570, -1079, -1863, -1692, 394, -1364, 1989, -379, +1430, 921, -171, 1812, -1110, 1503, -665, -141, +148, -1736, 242, -1851, -152, -452, -208, 1079, +558, 1446, 915, 876, 253, -42, -939, -664, +-1269, -1079, -387, -1073, 1008, -111, 1526, 1352, +548, 1774, -930, 373, -1447, -1536, -535, -1718, +918, -145, 1260, 1514, 220, 1161, -906, -553, +-689, -1311, 452, -116, 775, 1265, -10, 802, +-823, -860, -604, -1595, 493, -274, 1191, 1447, +613, 1516, -678, -163, -1322, -1539, -608, -1107, +650, 409, 1296, 1267, 759, 660, -473, -584, +-1147, -961, -545, -159, 433, 805, 678, 674, +130, -332, -263, -975, 23, -379, 428, 699, +221, 829, -616, 85, -942, -536, -170, -383, +1132, -86, 1313, -60, 23, -65, -1189, 277, +-1061, 737, 138, 439, 878, -499, 531, -1190, +-222, -684, -301, 478, 226, 1204, 518, 876, +-93, -97, -1014, -825, -934, -976, 379, -615, +1736, 153, 1509, 1127, -397, 1430, -2104, 413, +-1798, -1222, 338, -1952, 2050, -782, 1789, 1236, +-24, 2025, -1475, 730, -1394, -1180, -169, -1494, +722, -220, 703, 871, 397, 541, 257, -450, +41, -487, -545, 561, -871, 1084, -438, 97, +481, -1485, 1116, -1425, 764, 356, -247, 1877, +-981, 1271, -726, -739, 44, -1572, 581, -596, +684, 750, 315, 813, -247, -161, -494, -607, +-356, 35, -61, 752, 284, 425, 576, -659, +431, -970, -246, -203, -769, 730, -492, 755, +392, 80, 940, -426, 574, -236, -438, 154, +-1001, -21, -473, -553, 485, -644, 826, 383, +527, 1569, -95, 1286, -511, -745, -627, -2470, +-318, -1632, 249, 1031, 689, 2571, 793, 1487, +207, -796, -639, -1751, -1030, -1018, -444, 13, +473, 319, 982, 416, 682, 973, -27, 1244, +-607, 120, -594, -1708, -373, -2385, -116, -672, +446, 1933, 1081, 2855, 899, 1147, -370, -1626, +-1475, -2705, -1252, -1323, 368, 998, 1606, 1978, +1228, 1123, -336, -313, -1176, -914, -649, -622, +133, -209, 424, -119, 304, -37, 315, 499, +192, 872, -245, 469, -479, -599, -223, -1079, +396, -438, 547, 519, -38, 719, -606, 10, +-402, -427, 512, -70, 951, 597, 352, 509, +-734, -477, -1187, -1183, -494, -781, 789, 651, +1464, 1560, 864, 1037, -546, -409, -1510, -1389, +-1161, -1017, 228, -245, 1526, 461, 1273, 899, +-99, 1162, -1038, 712, -767, -727, 9, -1922, +357, -1499, 140, 466, -31, 2048, 384, 1637, +782, -133, 256, -1385, -1036, -1201, -1436, -282, +-243, 357, 1422, 442, 1727, 474, 239, 531, +-1381, 392, -1395, -250, -23, -1061, 1040, -1116, +808, -180, -67, 1154, -465, 1446, -188, 399, +267, -832, 152, -1124, -197, -402, -324, 224, +-20, 332, 387, 282, 490, 332, 164, 345, +-383, -28, -475, -461, -112, -572, 303, -404, +386, -66, 74, 490, -130, 967, -94, 738, +81, -251, 120, -1243, -22, -1190, -158, -135, +-235, 1057, 42, 1309, 425, 497, 498, -544, +34, -1032, -444, -699, -573, -23, -196, 521, +373, 619, 687, 337, 426, 2, -175, -166, +-532, -240, -397, -425, 4, -538, 275, -157, +235, 669, 201, 1169, 342, 666, 125, -603, +-433, -1581, -804, -1075, -289, 416, 670, 1499, +1053, 1128, 460, -36, -568, -899, -1002, -1011, +-459, -510, 437, 263, 913, 850, 380, 824, +-313, 82, -459, -636, -51, -602, 164, 0, +-21, 172, -115, -171, 140, -151, 361, 580, +244, 953, -111, 79, -480, -1293, -265, -1283, +147, 307, 511, 1547, 261, 954, -89, -719, +-243, -1228, -67, -252, 93, 850, -14, 653, +-104, -391, 106, -799, 337, -186, 200, 693, +-142, 732, -320, -12, -147, -725, 146, -708, +286, 13, 206, 591, -63, 574, -123, 48, +-47, -369, 8, -396, 96, 12, 43, 227, +15, 119, -98, -184, 64, -233, 239, 76, +154, 451, -107, 513, -319, -119, -120, -885, +184, -880, 382, 159, 177, 1176, -94, 1066, +-241, -92, -143, -1167, 101, -1045, 145, 16, +153, 885, 15, 728, -31, -66, -29, -389, +43, -104, 48, 152, 62, -183, -40, -515, +-123, -250, -74, 504, 207, 957, 407, 494, +111, -629, -209, -1247, -367, -629, -205, 686, +95, 1171, 408, 402, 472, -553, 187, -672, +-211, -12, -563, 247, -558, -62, 98, -260, +812, 182, 791, 562, 65, 219, -618, -400, +-723, -545, -269, -134, 384, 246, 664, 297, +526, 109, 84, 28, -468, -72, -698, -122, +-276, -171, 545, -33, 718, 87, 153, 75, +-348, 31, -309, 29, 145, 96, 156, 16, +-49, -170, -222, -166, 71, -78, 370, 102, +233, 145, 64, 158, -149, 60, -330, -103, +-335, -125, 66, -167, 558, -159, 594, 25, +99, 355, -430, 391, -634, -51, -192, -464, +406, -279, 534, 127, 153, 245, -92, -119, +5, -215, 63, 314, -186, 669, -464, 130, +-338, -923, 390, -1154, 1152, 9, 806, 1415, +-455, 1441, -1499, -232, -1031, -1781, 433, -1250, +1578, 678, 1215, 1645, -130, 504, -1188, -1099, +-1088, -963, -110, 565, 693, 1247, 887, -11, +373, -1540, -174, -1108, -301, 901, -264, 2008, +-151, 858, -191, -1325, 34, -2009, 411, -621, +600, 1224, 449, 1616, -218, 463, -741, -792, +-678, -955, -67, -349, 641, 185, 921, 259, +518, 211, -237, 360, -798, 258, -654, -107, +-69, -527, 396, -527, 621, -54, 571, 322, +282, 431, -262, 329, -840, 212, -771, -130, +-57, -755, 913, -876, 1184, -51, 502, 1131, +-539, 1271, -1243, 131, -870, -1279, 305, -1341, +1201, -147, 1075, 1179, 62, 1159, -869, 14, +-933, -899, -157, -738, 664, 125, 662, 492, +95, 256, -221, -154, -57, -228, 100, 29, +-88, 253, -332, 190, -158, -206, 391, -472, +676, -279, 250, 313, -396, 702, -587, 422, +-251, -391, 297, -905, 545, -503, 429, 460, +-35, 983, -399, 481, -486, -509, -61, -975, +590, -365, 597, 543, -95, 935, -646, 271, +-265, -732, 418, -994, 580, -26, 64, 1140, +-395, 935, -403, -530, 101, -1445, 462, -572, +343, 1069, -92, 1392, -334, -44, -72, -1302, +184, -851, 171, 607, -105, 1043, -224, 60, +153, -822, 553, -501, 373, 624, -374, 852, +-884, -207, -377, -1136, 678, -597, 1110, 874, +517, 1248, -642, 78, -1108, -1200, -384, -914, +600, 386, 882, 1084, 280, 355, -228, -647, +-311, -674, -76, 133, 31, 676, -153, 227, +-184, -487, 323, -538, 712, 123, 415, 593, +-438, 315, -852, -293, -359, -459, 444, -109, +803, 268, 347, 233, -319, -77, -342, -150, +-6, 43, 139, 160, -36, 41, -190, -198, +47, -267, 389, -97, 529, 268, 98, 589, +-576, 212, -652, -527, -99, -899, 589, -192, +711, 889, 237, 997, -257, -22, -473, -1089, +-341, -920, -7, 287, 392, 1114, 534, 662, +197, -500, -316, -978, -369, -345, 34, 577, +337, 680, 99, 82, -282, -443, -179, -321, +347, -9, 605, 70, 62, 77, -559, 222, +-499, 312, 93, -43, 489, -544, 374, -580, +137, 120, -96, 777, -190, 657, -283, -207, +-114, -767, 112, -543, 328, 26, 456, 480, +219, 535, -315, 329, -611, -176, -203, -647, +366, -625, 534, -57, 201, 720, -94, 828, +-219, 54, -86, -743, -18, -666, -60, 95, +-31, 503, 267, 211, 472, -121, 186, -55, +-348, 95, -585, -27, -187, -266, 451, -151, +708, 167, 176, 261, -472, 87, -445, -154, +62, -166, 465, -73, 246, 39, -187, 255, +-351, 216, 13, -202, 440, -649, 398, -287, +-137, 773, -495, 1063, -298, -12, 268, -1374, +556, -1154, 260, 493, -250, 1606, -391, 775, +48, -861, 341, -1166, 39, -68, -322, 752, +-160, 169, 457, -479, 619, -121, -58, 761, +-697, 675, -596, -504, 299, -1274, 826, -647, +435, 769, -287, 1364, -535, 557, -186, -661, +253, -1132, 301, -519, 74, 378, -128, 771, +-40, 414, 101, -128, 156, -357, 66, -184, +-144, -39, -262, -60, -51, -30, 328, 134, +435, 250, 101, 113, -327, -91, -386, -162, +15, -88, 346, -61, 201, -78, -111, -40, +-103, 158, 286, 293, 285, 246, -196, -28, +-592, -391, -275, -597, 469, -317, 817, 420, +418, 968, -433, 631, -795, -400, -448, -1102, +271, -783, 719, 235, 619, 942, 84, 733, +-453, -41, -684, -546, -288, -447, 358, -90, +639, 16, 371, -18, -102, 143, -311, 465, +-225, 460, -76, -81, 4, -664, 68, -722, +275, -173, 385, 508, 203, 793, -298, 527, +-538, -172, -208, -730, 252, -728, 438, -150, +245, 435, 74, 592, -59, 347, -150, 64, +-271, -153, -304, -395, 0, -637, 496, -517, +690, 301, 328, 1204, -406, 1119, -883, -229, +-608, -1565, 283, -1343, 1022, 202, 827, 1445, +-54, 1157, -792, -133, -722, -962, -93, -683, +445, 50, 497, 282, 262, 36, 111, 45, +-34, 454, -350, 488, -511, -231, -216, -947, +387, -623, 735, 410, 439, 946, -280, 417, +-608, -437, -339, -568, 176, 9, 361, 313, +174, -53, 8, -448, 0, -58, 122, 694, +-14, 667, -241, -286, -268, -1039, 53, -560, +349, 551, 331, 915, 51, 174, -150, -569, +-172, -383, -65, 256, -47, 276, -112, -319, +32, -475, 461, 196, 588, 860, -1, 392, +-751, -705, -735, -981, 8, -16, 746, 943, +820, 609, 249, -384, -468, -746, -741, -112, +-367, 538, 135, 358, 515, -260, 611, -484, +341, -40, -195, 446, -682, 359, -694, -184, +-110, -509, 810, -212, 1080, 360, 268, 532, +-848, 45, -1037, -537, -195, -551, 688, 117, +853, 712, 311, 527, -332, -272, -590, -825, +-356, -457, 27, 392, 398, 746, 570, 285, +247, -390, -362, -413, -593, -47, -150, 145, +359, -18, 401, -81, 53, 122, -119, 294, +-35, 195, 26, -194, -109, -484, -244, -344, +56, 214, 394, 571, 374, 310, -138, -200, +-466, -358, -178, -89, 219, 48, 337, -75, +37, -147, -142, 106, -8, 448, 130, 421, +-2, -108, -186, -735, -57, -732, 177, 62, +163, 883, 26, 884, -15, 2, -10, -825, +-88, -787, -121, -26, -3, 549, 169, 424, +261, 23, 162, -47, -214, 64, -379, -132, +-94, -510, 343, -418, 426, 287, 57, 833, +-361, 513, -355, -375, 96, -837, 440, -455, +239, 351, -181, 692, -381, 279, -151, -363, +300, -465, 538, 35, 125, 411, -555, 126, +-618, -375, 155, -372, 838, 215, 569, 550, +-363, 197, -936, -371, -414, -441, 619, -56, +937, 258, 178, 244, -644, 57, -640, -65, +27, -115, 492, -112, 367, -80, -47, 97, +-191, 202, -45, 42, 43, -212, -81, -211, +-102, 162, 88, 357, 240, 59, 152, -398, +-22, -383, -117, 190, -146, 515, -142, 195, +-46, -403, 208, -420, 435, 140, 317, 502, +-253, 117, -664, -515, -418, -424, 279, 323, +769, 729, 564, 148, -153, -667, -759, -637, +-610, 203, 165, 730, 699, 216, 473, -521, +-69, -435, -348, 345, -226, 612, -42, -64, +-18, -758, 3, -548, 249, 413, 454, 979, +144, 537, -431, -538, -591, -1128, -146, -583, +502, 583, 628, 1160, 133, 480, -386, -596, +-405, -888, -83, -206, 150, 452, 159, 359, +194, -103, 219, -177, 40, 238, -290, 325, +-428, -219, -69, -694, 397, -295, 501, 563, +112, 739, -310, 50, -388, -610, -131, -421, +198, 138, 281, 316, 193, 31, 63, -110, +-92, 76, -311, 156, -255, -66, 69, -310, +396, -145, 416, 262, 42, 370, -408, -6, +-478, -418, -43, -325, 390, 184, 417, 534, +147, 257, -158, -363, -301, -594, -290, -126, +-53, 442, 293, 458, 437, 29, 205, -295, +-189, -242, -396, -36, -267, 61, 38, 46, +309, 39, 367, 119, 186, 141, -149, 15, +-354, -208, -311, -295, 20, -95, 370, 203, +395, 286, 48, 122, -253, -36, -232, -48, +-42, -129, 97, -340, 61, -320, -1, 225, +125, 803, 240, 554, 53, -438, -275, -1011, +-353, -480, -75, 495, 293, 843, 428, 291, +199, -404, -178, -493, -372, 16, -252, 329, +60, -16, 288, -436, 290, -178, 82, 562, +-173, 749, -200, -29, -57, -908, 108, -784, +99, 191, -76, 863, -114, 525, 192, -206, +445, -406, 96, -110, -563, 14, -707, -235, +34, -243, 887, 257, 845, 735, -124, 492, +-953, -396, -728, -1031, 192, -655, 799, 440, +531, 1086, -91, 587, -369, -421, -303, -825, +-109, -334, 40, 297, 205, 378, 304, 2, +174, -133, -121, 132, -331, 283, -144, -47, +149, -493, 169, -408, -19, 158, -22, 593, +171, 386, 195, -174, -119, -452, -398, -254, +-255, 88, 247, 187, 623, 104, 268, 17, +-407, 39, -574, 13, -84, -97, 473, -117, +449, -21, -49, 71, -502, 6, -289, -47, +321, 26, 545, 207, 134, 234, -396, -131, +-529, -544, -152, -471, 404, 247, 730, 867, +352, 647, -454, -302, -909, -1049, -454, -781, +547, 272, 1089, 1101, 464, 831, -680, -235, +-930, -1051, -148, -760, 627, 243, 526, 867, +-65, 543, -337, -235, -102, -585, 224, -275, +85, 215, -180, 270, -151, -40, 140, -147, +215, 131, -9, 261, -56, -128, 89, -477, +75, -208, -170, 435, -300, 574, -3, 13, +425, -569, 427, -514, -93, 97, -493, 553, +-286, 448, 196, -86, 371, -498, 122, -410, +-178, 24, -122, 372, 109, 365, 147, 86, +-39, -205, -219, -282, -142, -220, 132, -73, +343, 197, 231, 452, -108, 336, -373, -233, +-271, -670, 136, -432, 373, 305, 213, 755, +-118, 372, -203, -384, 6, -660, 149, -159, +-20, 405, -282, 375, -139, -90, 344, -329, +611, -46, 130, 332, -659, 253, -697, -285, +38, -596, 729, -144, 596, 643, -66, 762, +-493, -80, -335, -883, 43, -683, 135, 269, +67, 854, 140, 490, 295, -312, 172, -694, +-306, -292, -597, 300, -188, 425, 498, 101, +671, -164, 78, -162, -506, -69, -384, -9, +118, 47, 326, 116, 41, 112, -222, -9, +-27, -186, 333, -218, 260, 21, -256, 292, +-519, 318, -103, -26, 443, -409, 512, -427, +-42, 21, -494, 517, -285, 504, 271, -29, +417, -526, 16, -472, -359, 1, -284, 366, +190, 372, 431, 155, 259, -110, -206, -325, +-449, -330, -285, -99, 150, 291, 500, 463, +380, 195, -78, -275, -450, -462, -303, -130, +136, 208, 249, 240, 52, 40, -69, -31, +145, 18, 291, -16, -45, -142, -505, -186, +-440, 27, 156, 230, 661, 228, 529, -31, +-91, -213, -567, -156, -491, 12, -56, 99, +333, 23, 466, 50, 269, 106, -93, 36, +-342, -176, -320, -219, -59, 65, 214, 249, +205, 102, 56, -195, 122, -152, 178, 163, +-108, 216, -520, -137, -394, -360, 256, -10, +753, 411, 498, 295, -344, -284, -797, -473, +-298, 8, 465, 506, 522, 263, -37, -394, +-316, -495, -82, 124, 251, 587, 232, 270, +-225, -363, -440, -491, -73, -78, 429, 291, +423, 293, 15, 155, -298, -12, -310, -262, +-54, -434, 123, -130, 125, 446, 109, 594, +211, 28, 153, -600, -192, -500, -495, 193, +-307, 575, 253, 193, 657, -361, 474, -320, +-207, 166, -730, 301, -476, -69, 227, -323, +629, -41, 390, 354, -133, 233, -396, -266, +-248, -450, 68, -33, 221, 479, 135, 418, +-48, -154, -73, -565, 54, -361, 133, 234, +-13, 574, -234, 355, -256, -241, 146, -601, +522, -295, 287, 327, -359, 494, -639, 28, +-110, -346, 584, -73, 571, 329, -159, 80, +-656, -554, -267, -465, 454, 486, 511, 1035, +-84, 184, -511, -1070, -157, -1027, 392, 366, +332, 1334, -227, 550, -486, -880, 47, -1131, +581, 114, 368, 1140, -392, 617, -714, -686, +-155, -1078, 623, -64, 764, 976, 18, 800, +-724, -288, -644, -981, 100, -537, 659, 429, +468, 851, -109, 314, -429, -485, -182, -639, +106, -53, 109, 446, -70, 258, -24, -174, +260, -203, 285, 155, -94, 208, -478, -158, +-337, -412, 174, -91, 544, 465, 357, 505, +-126, -99, -420, -651, -327, -441, -22, 248, +245, 655, 350, 368, 224, -253, -83, -604, +-378, -335, -333, 285, 5, 519, 383, 145, +452, -294, 75, -212, -436, 128, -475, 80, +20, -244, 452, -222, 388, 264, -65, 565, +-405, 177, -252, -538, 220, -723, 367, -117, +26, 682, -326, 748, -207, 17, 220, -669, +360, -615, 12, 47, -379, 493, -237, 399, +232, 27, 362, -226, -16, -272, -273, -179, +-123, 53, 191, 275, 181, 229, -118, -32, +-279, -212, 50, -196, 395, -15, 160, 146, +-276, 175, -339, 51, -3, -96, 258, -125, +220, -78, -20, 12, -176, 114, -78, 151, +54, 56, 65, -132, -3, -231, -48, -75, +-22, 180, 42, 258, 137, 98, 91, -164, +-130, -291, -281, -198, -80, 176, 264, 452, +367, 201, 17, -330, -330, -482, -258, -33, +90, 425, 263, 305, 49, -157, -135, -339, +-76, -54, 188, 247, 160, 138, -180, -135, +-317, -178, -54, 18, 351, 177, 341, 94, +-59, -69, -403, -107, -245, -61, 227, 6, +324, 33, 2, 86, -275, 101, -76, -1, +257, -116, 191, -179, -142, -77, -318, 180, +-90, 298, 206, 63, 260, -316, 69, -321, +-76, 105, -86, 382, -112, 167, -197, -266, +-67, -321, 309, 27, 478, 332, 73, 224, +-490, -123, -543, -360, -15, -187, 535, 215, +458, 389, -85, 127, -396, -277, -92, -361, +147, -55, -58, 286, -206, 303, 46, -54, +392, -312, 342, -144, -147, 221, -517, 277, +-340, -140, 199, -455, 441, -83, 222, 591, +1, 464, -167, -404, -283, -775, -286, -50, +68, 659, 448, 439, 335, -225, -92, -460, +-379, -91, -175, 208, 92, 148, 99, -118, +21, -143, 110, 142, 182, 316, -72, 52, +-317, -487, -196, -535, 222, 231, 438, 890, +93, 436, -475, -690, -442, -928, 281, 33, +657, 877, 102, 464, -591, -441, -448, -508, +241, 143, 552, 324, 223, -143, -305, -281, +-447, 142, -53, 354, 347, 49, 260, -268, +-142, -218, -262, 16, 35, 121, 164, 120, +49, 77, -36, 27, -11, -79, -78, -196, +-129, -141, 46, 124, 167, 299, 144, 123, +60, -234, -200, -285, -347, 42, -18, 301, +372, 189, 279, -246, -104, -435, -175, 31, +-142, 606, -112, 382, 43, -475, 180, -692, +161, 24, 13, 580, -51, 352, -143, -172, +-135, -276, -7, -70, 70, 8, 85, -81, +175, 11, 147, 280, -182, 216, -387, -220, +-114, -352, 322, 35, 398, 284, 20, 36, +-394, -242, -353, -68, 203, 294, 474, 275, +19, -204, -452, -483, -207, -145, 306, 456, +310, 416, -1, -202, -251, -444, -211, 47, +114, 439, 218, -44, -114, -559, -243, -155, +159, 601, 443, 603, 49, -284, -445, -811, +-456, -352, 75, 536, 573, 760, 359, 35, +-260, -652, -428, -519, -5, 245, 207, 638, +-18, 200, -152, -478, 46, -503, 279, 135, +239, 563, -151, 250, -516, -329, -250, -418, +323, -11, 369, 302, -3, 156, -83, -112, +48, -91, -35, 112, -168, 86, -175, -170, +-154, -290, 136, -55, 583, 343, 437, 491, +-334, 81, -822, -580, -455, -713, 311, 23, +771, 833, 554, 714, -196, -244, -618, -861, +-446, -469, -23, 362, 202, 621, 356, 172, +361, -286, 66, -273, -294, 19, -472, 132, +-250, -8, 186, -119, 507, -3, 307, 167, +-230, 164, -416, -43, -61, -215, 188, -198, +70, 14, -61, 244, -5, 214, 68, -71, +52, -244, 53, -70, -64, 164, -202, 75, +-114, -115, 100, -66, 229, 99, 49, 89, +-105, -110, -85, -73, 94, 167, 99, 195, +-188, -193, -351, -501, 14, -120, 556, 584, +397, 709, -239, -82, -587, -916, -300, -651, +205, 368, 436, 844, 275, 231, -56, -390, +-196, -208, -209, 128, -231, -123, -75, -500, +248, -91, 460, 694, 194, 833, -243, -54, +-502, -985, -292, -867, 271, 143, 482, 963, +145, 688, -287, -182, -228, -666, -16, -385, +35, 206, 132, 263, 142, -78, -74, -152, +-239, 279, -59, 463, 199, -112, 171, -652, +18, -427, -114, 252, -329, 564, -250, 317, +275, -97, 659, -334, 265, -306, -563, -81, +-750, 152, -66, 216, 664, 165, 516, 102, +-213, -71, -422, -362, -106, -374, 201, 206, +138, 597, -116, 216, -283, -394, 29, -483, +489, -11, 247, 367, -318, 361, -529, -33, +-170, -392, 235, -278, 446, 79, 284, 339, +-118, 290, -282, -63, -362, -414, -237, -316, +280, 256, 577, 513, 98, 28, -432, -540, +-195, -306, 145, 442, 100, 624, -114, -144, +-198, -781, 38, -405, 413, 516, 276, 856, +-345, 126, -561, -735, -83, -673, 397, 227, +351, 673, -30, 166, -303, -324, -41, -187, +216, 119, -25, 48, -354, -114, -197, -62, +326, 100, 446, 145, 107, -6, -331, -127, +-426, -120, -80, 90, 267, 206, 226, -43, +-37, -351, -46, -138, 157, 479, -23, 449, +-422, -341, -293, -735, 309, -57, 498, 760, +86, 496, -246, -486, -258, -735, -125, 17, +65, 654, 111, 416, -15, -214, 60, -563, +223, -358, -1, 293, -342, 636, -213, 126, +118, -476, 278, -285, 163, 254, -231, 171, +-331, -314, 161, -279, 473, 422, -71, 744, +-613, -69, -260, -988, 440, -643, 636, 535, +103, 963, -634, 251, -611, -570, 127, -701, +596, 27, 297, 648, -262, 248, -376, -543, +-26, -451, 318, 543, 113, 844, -381, -127, +-298, -1131, 269, -763, 498, 798, 78, 1398, +-463, 169, -420, -1315, 40, -1030, 410, 628, +298, 1389, -63, 208, -371, -1327, -242, -1009, +200, 873, 265, 1627, -71, 86, -263, -1669, +-52, -1237, 209, 853, 235, 1831, -6, 387, +-425, -1456, -311, -1252, 244, 586, 443, 1424, +84, 254, -359, -1204, -285, -929, 83, 728, +265, 1468, 14, 156, -188, -1535, 8, -1187, +106, 739, -20, 1767, -99, 474, -111, -1389, +-52, -1291, 97, 444, 228, 1394, 11, 363, +-225, -1000, -175, -881, -33, 398, 199, 1137, +199, 314, -59, -956, -209, -909, -162, 264, +-44, 992, 144, 407, 334, -557, 83, -610, +-448, 158, -391, 549, 116, -63, 453, -632, +344, -91, -272, 737, -612, 586, -191, -434, +453, -960, 464, -254, -54, 778, -449, 751, +-394, -265, 229, -763, 589, -140, 53, 601, +-658, 399, -507, -382, 350, -734, 775, -33, +311, 903, -667, 707, -877, -471, -49, -1128, +791, -410, 681, 797, -181, 1008, -697, 53, +-464, -909, 145, -666, 427, 372, 271, 759, +-27, 102, -293, -648, -217, -433, 75, 487, +109, 800, -97, -70, -63, -991, 144, -633, +20, 620, -120, 1092, -36, 216, 89, -844, +-38, -805, -177, 158, -117, 742, 93, 350, +229, -342, 118, -514, -121, 26, -263, 560, +-238, 341, -65, -476, 170, -831, 363, -2, +271, 1008, -161, 806, -567, -531, -401, -1216, +129, -274, 387, 896, 328, 683, 132, -338, +-208, -547, -488, 72, -271, 440, 109, 60, +234, -500, 156, -514, 197, 207, 11, 1043, +-309, 700, -352, -681, -230, -1581, 107, -607, +433, 1322, 445, 1746, -101, 46, -546, -1754, +-321, -1246, 15, 740, 185, 1519, 137, 231, +87, -1188, 82, -719, 12, 773, -190, 1120, +-440, -228, -227, -1405, 309, -722, 549, 1035, +166, 1642, -449, 120, -473, -1672, -59, -1324, +320, 693, 198, 1756, -157, 503, -200, -1260, +81, -1269, 238, 355, -40, 1458, -363, 510, +-209, -1153, 99, -1195, 233, 517, 87, 1545, +-98, 316, -33, -1390, 33, -1131, -95, 819, +-393, 1596, -254, 42, 380, -1587, 701, -937, +185, 1120, -739, 1544, -881, -244, 88, -1709, +844, -715, 448, 1306, -443, 1369, -527, -488, +69, -1559, 390, -313, 48, 1285, -568, 944, +-479, -837, 471, -1387, 926, 234, 70, 1707, +-1007, 672, -721, -1639, 338, -1712, 751, 833, +260, 2399, -479, 506, -544, -2194, 150, -1787, +586, 1163, 3, 2424, -769, 257, -418, -2187, +578, -1606, 795, 1161, 11, 2332, -855, 369, +-674, -2048, 287, -1723, 697, 881, 136, 2125, +-399, 579, -225, -1519, 36, -1494, 70, 400, +7, 1518, -67, 635, -129, -889, -14, -1048, +37, 33, 2, 695, 152, 392, 141, -34, +-290, -46, -555, -91, -76, -511, 442, -638, +481, 197, 111, 1281, -430, 1124, -695, -679, +-198, -2000, 513, -1014, 454, 1234, -33, 2050, +-389, 436, -146, -1324, 179, -1229, 7, 15, +-381, 595, -258, 157, 404, 54, 528, 464, +15, 534, -602, -306, -681, -1312, 169, -894, +737, 624, 245, 1691, -515, 861, -497, -885, +108, -1446, 405, -344, 248, 856, -374, 496, +-670, -374, -9, -189, 619, 747, 463, 603, +-211, -799, -637, -1372, -416, -271, 106, 1243, +440, 1275, 201, -156, 58, -1109, -7, -518, +-480, 479, -640, 248, 11, -495, 742, -214, +681, 869, -239, 985, -960, -412, -627, -1599, +542, -801, 910, 1101, -73, 1551, -823, 17, +-486, -1402, 510, -806, 845, 922, -26, 1197, +-1102, -345, -824, -1548, 613, -503, 1221, 1349, +233, 1435, -996, -296, -895, -1571, 241, -868, +775, 772, 157, 1246, -585, 52, -311, -950, +394, -399, 362, 673, -300, 614, -708, -419, +5, -833, 659, -122, 299, 780, -567, 599, +-695, -410, 235, -701, 831, 54, 420, 786, +-831, 374, -1277, -927, -2, -1113, 1303, 212, +976, 1718, -445, 1164, -1248, -924, -678, -1931, +383, -794, 919, 1212, 239, 1616, -575, 112, +-424, -1127, 176, -711, 350, 622, 12, 747, +-608, -445, -558, -1133, 334, -294, 1047, 1334, +249, 1531, -907, -251, -825, -1752, 60, -1353, +668, 464, 372, 1570, -451, 875, -523, -440, +283, -937, 705, -193, -56, 288, -1023, -69, +-832, -357, 409, 40, 1419, 783, 755, 801, +-1010, -239, -1563, -1283, -319, -999, 1062, 414, +1017, 1356, -258, 839, -849, -389, -258, -880, +425, -520, 115, 44, -540, 99, -233, 237, +421, 722, 565, 592, -59, -400, -688, -1364, +-499, -843, 186, 776, 463, 1641, 20, 554, +-246, -1178, 83, -1324, 269, 119, -191, 1091, +-768, 657, -508, -471, 659, -925, 1210, -63, +142, 752, -1179, 539, -1157, -345, 76, -517, +1102, -82, 750, 76, -419, -69, -884, 96, +-58, 651, 421, 610, -109, -640, -587, -1533, +-41, -626, 854, 1415, 828, 2039, -621, 178, +-1597, -2125, -690, -2065, 1083, 568, 1594, 2629, +273, 1502, -1295, -1384, -1397, -2516, -21, -775, +1022, 1799, 719, 2181, -107, 145, -472, -1920, +-264, -1598, -112, 266, -489, 1465, -292, 1031, +809, -171, 1294, -853, 26, -658, -1611, -144, +-1634, 186, 76, 501, 1882, 552, 1817, 130, +-318, -367, -2211, -564, -1812, -373, 389, 67, +2014, 453, 1525, 479, -408, 189, -1746, -33, +-1314, -376, 168, -739, 1115, -549, 978, 462, +271, 1385, -731, 984, -1114, -737, -660, -1985, +408, -1082, 1030, 1149, 734, 2227, -141, 934, +-1041, -1381, -1047, -2294, -118, -705, 928, 1670, +997, 2082, 94, 143, -766, -1677, -750, -1366, +-277, 403, 192, 1245, 262, 357, 219, -731, +398, -427, 354, 671, -383, 756, -1436, -446, +-1053, -1492, 847, -679, 2078, 1341, 1077, 2035, +-1300, 277, -2517, -2027, -1038, -2045, 1702, 319, +2562, 2260, 336, 1633, -2269, -897, -2145, -2244, +483, -848, 2367, 1392, 1145, 1897, -1378, 122, +-1960, -1839, -209, -1509, 1432, 769, 1110, 2172, +-388, 724, -1346, -1585, -492, -1807, 864, 28, +869, 1777, -542, 1452, -1172, -529, -93, -1904, +1086, -1205, 783, 1038, -578, 2086, -1241, 824, +-365, -1368, 740, -2087, 666, -630, -176, 1440, +-449, 2121, -89, 664, 221, -1505, 20, -2212, +-481, -603, -417, 1748, 201, 2165, 612, 41, +376, -2075, -147, -1525, -630, 898, -659, 2116, +-104, 474, 365, -1873, 536, -1870, 468, 649, +-74, 2703, -819, 1435, -771, -1779, 55, -3041, +628, -775, 536, 2489, 16, 2888, -558, 44, +-583, -2868, 104, -2305, 635, 995, 289, 2775, +-587, 1088, -956, -1767, -195, -2257, 1079, 58, +1251, 2257, -101, 1711, -1482, -898, -1597, -2433, +-106, -1276, 1652, 1141, 1819, 2265, 80, 1199, +-1832, -787, -1694, -1877, -29, -1400, 1380, -111, +1080, 1280, -191, 1970, -691, 1259, -303, -802, +11, -2564, -230, -2210, -533, 348, 115, 2936, +995, 2903, 918, 2, -476, -2961, -1588, -3159, +-1069, -338, 538, 2641, 1661, 3093, 1109, 636, +-639, -2195, -1803, -2695, -1111, -813, 561, 1546, +1474, 2224, 961, 955, -220, -950, -1191, -1792, +-1311, -948, -347, 451, 1023, 1229, 1632, 981, +740, 238, -1260, -693, -2250, -1439, -806, -1127, +1753, 597, 2410, 2371, 243, 1701, -2315, -978, +-2378, -3157, 354, -1948, 2854, 1490, 1858, 3580, +-1393, 1833, -3160, -1863, -1062, -3463, 2163, -1387, +2770, 1905, 9, 2832, -2627, 735, -2035, -1675, +810, -1733, 2391, 3, 1013, 1113, -1461, 431, +-1926, -524, -80, -306, 1451, 580, 1178, 661, +-388, -278, -1403, -1199, -883, -689, 510, 720, +1239, 1633, 546, 581, -473, -1296, -1120, -1754, +-868, -233, 452, 1684, 1360, 1638, 681, 47, +-797, -1718, -1368, -1790, -496, -191, 812, 1748, +1324, 2186, 213, 477, -1239, -1906, -1066, -2472, +287, -603, 1047, 1754, 558, 2339, -618, 846, +-980, -1181, -98, -2111, 905, -1130, 527, 678, +-652, 1673, -854, 1083, 5, -205, 840, -944, +450, -728, -606, -196, -700, -2, 186, 105, +652, 663, 0, 1028, -772, 394, -481, -1041, +562, -1801, 1194, -778, 89, 1263, -1442, 2268, +-1281, 1003, 478, -1356, 1690, -2313, 905, -1109, +-925, 1145, -1779, 2186, -492, 1124, 1404, -716, +1323, -1930, -374, -1243, -1452, 304, -813, 1617, +732, 1437, 1273, 7, 331, -1261, -923, -1468, +-951, -431, -214, 860, 411, 1485, 609, 893, +451, -507, 67, -1434, -425, -1236, -803, 157, +-739, 1299, 69, 1254, 1158, 142, 1281, -846, +-29, -940, -1497, -534, -1576, 153, -52, 524, +1493, 846, 1586, 610, -64, -179, -1668, -928, +-1231, -982, 404, -212, 1308, 597, 458, 1057, +-721, 610, -778, -161, 181, -744, 839, -721, +206, -334, -956, 136, -1013, 500, 279, 633, +1589, 632, 1146, 172, -852, -762, -2330, -1492, +-1411, -903, 1374, 779, 3018, 1985, 1465, 1486, +-2001, -601, -3632, -2119, -1392, -1558, 2379, 386, +3772, 1545, 1118, 1095, -2612, 90, -3574, -489, +-751, -438, 2499, -532, 2781, -857, 251, -357, +-2195, 1092, -1980, 2063, 417, 943, 1896, -1524, +786, -2781, -1332, -1279, -1622, 1658, 296, 2839, +2082, 1204, 1463, -1163, -1133, -2021, -2881, -1182, +-1608, -78, 1607, 791, 3339, 1479, 1731, 1633, +-1697, 396, -3587, -1896, -2023, -2936, 1553, -1223, +3460, 1893, 1848, 3597, -1309, 2081, -2789, -1469, +-1611, -3886, 736, -2665, 1794, 1026, 1097, 3601, +-44, 2681, -631, -524, -935, -2780, -896, -2230, +-186, 63, 987, 1706, 1448, 1572, 604, 253, +-1145, -869, -2033, -990, -762, -240, 1590, 475, +2338, 602, 364, 101, -2158, -522, -2406, -701, +106, -68, 2560, 1033, 2188, 1344, -561, 213, +-2715, -1677, -2023, -2344, 453, -593, 2516, 2107, +2236, 3268, -76, 1409, -2341, -2092, -2691, -4039, +-626, -2341, 2077, 1762, 3040, 4273, 1211, 2894, +-1658, -1023, -3034, -3746, -1813, -3002, 811, 83, +2663, 2566, 2141, 2706, -19, 818, -1737, -1222, +-2064, -1997, -1207, -1328, 354, -8, 1865, 1037, +2273, 1515, 956, 942, -1453, -364, -3212, -1482, +-2212, -1236, 1135, 210, 3769, 1342, 2744, 869, +-954, -585, -3749, -1076, -2846, -108, 721, 1021, +3260, 804, 2476, -341, -443, -1224, -2495, -858, +-2090, 260, -142, 1061, 1761, 1099, 1930, 443, +512, -556, -1239, -1361, -1813, -1297, -907, -244, +760, 1198, 1671, 2039, 1070, 1260, -335, -757, +-1295, -2314, -1237, -1853, -320, 34, 815, 1629, +1278, 1890, 777, 962, -207, -195, -1026, -1311, +-1352, -2015, -541, -1540, 741, 453, 1627, 2762, +1069, 2936, -387, 345, -1665, -2883, -1406, -3554, +47, -834, 1345, 2423, 1411, 3118, 279, 920, +-929, -1502, -1287, -2016, -506, -662, 523, 562, +907, 683, 548, 277, -150, 137, -538, 344, +-458, -40, -316, -553, -22, -646, 444, 144, +970, 810, 608, 280, -850, -817, -1866, -992, +-937, 453, 1424, 1804, 2508, 1236, 1112, -1083, +-1664, -2546, -3048, -1602, -1462, 962, 1653, 2605, +3141, 2223, 1723, 123, -1109, -2162, -2731, -2888, +-2025, -1397, 115, 1253, 1853, 2908, 1992, 2294, +1036, 26, -548, -2052, -1745, -2449, -1967, -1219, +-796, 525, 1004, 1648, 2201, 1758, 1916, 1184, +156, 120, -1810, -1371, -2429, -2679, -1538, -2341, +603, 272, 2450, 3463, 2695, 4226, 845, 1176, +-1894, -3388, -3377, -5108, -2235, -2287, 1031, 2456, +3413, 4562, 2817, 2658, -47, -903, -2516, -2792, +-2802, -2220, -1053, -810, 1291, 365, 2322, 1369, +1614, 2154, -60, 1693, -1514, -387, -1682, -2586, +-789, -2814, 466, -582, 1205, 2163, 1300, 2921, +569, 1208, -762, -1207, -1476, -2123, -1098, -1387, +269, 28, 1291, 952, 1206, 1243, -26, 904, +-965, 34, -807, -821, -77, -1254, 494, -630, +311, 353, -223, 936, -240, 608, 477, 157, +846, 110, 24, -171, -1403, -927, -1682, -1429, +29, -317, 2343, 1779, 2502, 2625, -43, 592, +-2942, -2485, -3112, -3158, -181, -617, 2947, 2467, +3322, 3000, 657, 771, -2381, -1870, -3033, -2361, +-1185, -755, 1222, 860, 2273, 1054, 1412, 579, +65, 505, -777, 521, -1182, -284, -1514, -1720, +-1026, -2023, 696, -178, 2494, 2361, 2627, 3015, +154, 904, -2966, -2158, -3729, -3518, -898, -1735, +2840, 1596, 3902, 3385, 1319, 2013, -2360, -804, +-3353, -2448, -998, -1721, 1819, 62, 2079, 1106, +63, 852, -1368, 377, -595, 292, 1003, 185, +1215, -430, -542, -1170, -1906, -1098, -1242, 85, +872, 1483, 2290, 1634, 1475, 237, -602, -1285, +-2106, -1599, -1572, -360, 111, 1028, 1322, 1078, +1188, -68, 419, -924, -216, -235, -490, 878, +-689, 1010, -752, -377, -349, -1784, 529, -1394, +1273, 691, 996, 2355, -150, 1752, -1070, -584, +-1134, -2276, -513, -1824, 357, 141, 886, 1654, +961, 1424, 511, 207, -258, -665, -1077, -585, +-1087, -235, -496, -285, 631, -366, 1261, -85, +1087, 582, 126, 1090, -1000, 844, -1358, -78, +-814, -1361, 353, -1786, 1284, -864, 1125, 985, +163, 2461, -673, 1942, -936, -260, -597, -2452, +-4, -2539, 440, -585, 407, 1535, 499, 2321, +628, 1412, 140, -70, -1034, -1283, -1642, -1974, +-682, -1622, 1357, 93, 2286, 2197, 897, 2628, +-1413, 652, -2197, -1825, -867, -2440, 1036, -863, +1816, 1017, 783, 1289, -813, 385, -1410, -46, +-415, 320, 698, 420, 908, -629, 260, -1613, +-609, -1187, -810, 764, -233, 2096, 543, 1441, +695, -425, 491, -1457, -38, -1060, -764, -250, +-1060, 179, -434, 207, 678, 682, 1398, 1106, +915, 792, -297, -564, -1289, -1687, -1170, -1522, +-355, -155, 505, 1283, 1132, 1725, 1080, 1027, +510, -113, -586, -1046, -1404, -1604, -1478, -1395, +-565, -188, 1087, 1504, 2293, 2428, 1865, 1645, +-328, -591, -2604, -2686, -2760, -2779, -551, -620, +2110, 2034, 2988, 2992, 1291, 1698, -1175, -697, +-2455, -2302, -1568, -2127, 198, -708, 1388, 917, +1309, 1813, 321, 1676, -254, 550, -425, -995, +-418, -1858, -557, -1471, -541, -65, 110, 1410, +892, 1673, 1087, 792, 350, -657, -823, -1346, +-1096, -880, -366, 163, 553, 789, 459, 354, +-109, -237, -246, -259, 394, 317, 818, 677, +239, 310, -1013, -654, -1416, -1413, -544, -1044, +1029, 610, 1763, 2245, 934, 1885, -665, -375, +-1532, -2620, -984, -2275, 104, 128, 671, 2183, +604, 1912, 529, 111, 485, -1117, -121, -946, +-943, -253, -1084, -151, -386, -239, 765, 250, +1336, 1133, 719, 1129, -565, -91, -1109, -1490, +-455, -1491, 415, -118, 525, 1244, -17, 1268, +-417, 255, -213, -621, 483, -681, 883, -241, +311, -75, -848, -12, -1455, 178, -635, 584, +979, 462, 1767, -222, 846, -716, -716, -505, +-1415, 293, -814, 622, 190, 231, 681, -472, +416, -514, 124, 202, 310, 776, 499, 454, +-156, -580, -1224, -1122, -1401, -467, -79, 805, +1616, 1260, 1988, 474, 650, -782, -1359, -1080, +-2141, -369, -1177, 476, 679, 553, 1894, 157, +1475, 46, -39, 120, -1261, 21, -1248, -412, +-318, -703, 511, -334, 619, 537, 379, 1138, +215, 628, 88, -555, -134, -1200, -541, -748, +-661, 368, -151, 938, 558, 613, 896, -89, +380, -364, -363, -273, -714, -357, -407, -264, +161, 172, 348, 653, 257, 493, -24, -164, +-30, -553, 100, -355, 93, 146, -241, 209, +-383, -51, -81, -82, 369, 262, 412, 400, +39, -39, -201, -573, -160, -518, 21, 125, +-3, 619, -84, 408, -152, -246, 118, -436, +330, -23, 369, 366, -27, 171, -491, -437, +-490, -581, -16, 11, 422, 903, 507, 900, +179, -153, -230, -1214, -377, -1082, -187, 147, +55, 1215, 167, 1121, 197, -17, 82, -1026, +-61, -938, -12, -1, 14, 727, 45, 448, +-127, -222, -258, -312, -85, 353, 354, 606, +535, -290, 103, -1215, -386, -740, -498, 867, +-109, 1604, 240, 573, 369, -1057, 190, -1415, +-15, -322, -104, 813, -123, 867, -110, 116, +-45, -380, 74, -297, 108, 68, 69, 108, +-36, -200, 109, -338, 314, 56, 152, 602, +-491, 518, -825, -181, -273, -756, 892, -585, +1416, 216, 531, 792, -1070, 561, -1758, -245, +-589, -812, 1030, -560, 1629, 301, 594, 978, +-611, 596, -994, -471, -388, -1183, 195, -634, +190, 580, 53, 1279, 148, 702, 572, -573, +559, -1123, -182, -628, -1065, 198, -942, 601, +146, 655, 1106, 464, 999, -104, 112, -766, +-630, -892, -599, -240, -152, 697, -8, 934, +-74, 324, 11, -406, 642, -518, 969, -206, +336, -3, -875, -95, -1467, -97, -713, 213, +750, 669, 1586, 662, 1060, -143, -301, -1085, +-1194, -1265, -989, -187, -112, 1282, 620, 1693, +641, 514, 400, -1151, 59, -1649, -141, -740, +-311, 643, -306, 1279, -126, 817, -42, -124, +206, -695, 346, -590, 438, -263, 234, 13, +-162, 194, -485, 447, -606, 517, -168, 143, +362, -460, 713, -674, 615, -247, 228, 279, +-434, 411, -863, 200, -694, -8, 22, -36, +838, -34, 1119, -186, 578, -330, -555, -118, +-1217, 355, -770, 490, 339, 59, 983, -440, +708, -368, -64, 170, -459, 493, -282, 140, +-5, -453, 12, -527, -46, -41, 109, 554, +234, 635, 341, 193, 132, -481, -207, -725, +-531, -382, -262, 153, 431, 478, 654, 584, +194, 513, -507, -29, -559, -829, 97, -1094, +755, -305, 536, 814, -372, 1114, -862, 462, +-275, -305, 648, -587, 868, -524, 95, -387, +-690, -112, -550, 294, 192, 695, 761, 890, +310, 461, -461, -637, -706, -1671, -28, -1328, +793, 437, 863, 2055, 70, 1782, -858, -175, +-983, -1824, -175, -1599, 829, -43, 1050, 1053, +489, 846, -318, 87, -746, -67, -709, 202, +-184, 40, 315, -727, 706, -1168, 853, -325, +501, 1101, -379, 1764, -1235, 643, -1074, -1153, +34, -1813, 1285, -694, 1578, 935, 444, 1330, +-1100, 470, -1447, -526, -414, -683, 790, -163, +973, 292, 244, 215, -349, -198, -222, -338, +282, -3, 262, 453, -345, 510, -716, 105, +-204, -495, 739, -718, 1072, -331, 361, 368, +-699, 772, -941, 500, -249, -134, 509, -638, +600, -533, 161, 11, -127, 439, -70, 316, +106, -134, 82, -253, -58, 169, -263, 531, +-283, 84, -18, -838, 540, -960, 822, 164, +479, 1332, -456, 1142, -1234, -343, -846, -1462, +403, -1087, 1445, 387, 1137, 1276, 16, 820, +-1109, -281, -1135, -892, -210, -584, 751, 137, +837, 574, 371, 397, -44, -49, -249, -328, +-290, -306, -253, -99, -184, 234, 124, 407, +500, 209, 558, -270, 224, -590, -320, -268, +-511, 351, -377, 661, 100, 285, 566, -309, +554, -612, 77, -373, -371, 225, -350, 546, +18, 293, 349, -174, 231, -221, -106, -55, +-241, -96, 29, -225, 330, -85, 360, 413, +73, 609, -354, 111, -435, -704, -51, -798, +457, 54, 507, 768, 203, 626, -166, -111, +-345, -541, -182, -367, 5, 5, 158, 192, +293, 209, 336, 170, 210, 72, -223, -215, +-457, -302, -261, -41, 277, 288, 629, 244, +259, -216, -242, -377, -321, 4, 6, 568, +237, 454, 159, -311, -38, -878, -167, -524, +32, 485, 350, 1136, 312, 616, -107, -607, +-433, -1205, -215, -580, 309, 595, 538, 930, +226, 372, -243, -303, -357, -339, -109, -150, +228, -248, 346, -306, 251, 69, 80, 771, +-306, 803, -480, -83, -67, -1128, 662, -1054, +815, 188, 72, 1239, -788, 967, -842, -311, +51, -1092, 1045, -676, 895, 408, -140, 832, +-872, 261, -539, -493, 355, -441, 747, 166, +137, 380, -529, -70, -155, -297, 655, 58, +623, 381, -375, -48, -1046, -550, -352, -241, +887, 574, 1209, 766, 154, -95, -915, -879, +-711, -686, 162, 209, 596, 813, 330, 648, +-41, 22, -112, -569, 30, -757, 90, -378, +-16, 298, 0, 789, 47, 757, -35, 71, +-36, -728, 180, -1077, 304, -469, 177, 652, +-61, 1235, -268, 719, -279, -543, 62, -1153, +372, -619, 329, 374, 63, 689, 8, 248, +30, -56, -92, 80, -318, 116, -327, -353, +207, -752, 792, -305, 763, 613, -105, 1037, +-862, 425, -799, -594, 130, -1011, 870, -475, +659, 463, -103, 807, -382, 322, 16, -411, +257, -484, -38, 119, -457, 503, -333, -1, +307, -728, 1005, -556, 791, 496, -203, 1134, +-1116, 502, -999, -736, 101, -1170, 1118, -339, +1037, 666, 117, 788, -537, 119, -441, -324, +-136, -165, -147, 106, -85, -18, 241, -439, +736, -435, 733, 209, 136, 937, -744, 764, +-1074, -310, -456, -1146, 631, -798, 1249, 287, +815, 874, -182, 465, -828, -110, -649, -134, +-42, 69, 214, -198, 255, -759, 482, -557, +631, 453, 301, 1360, -437, 950, -956, -490, +-705, -1545, 288, -1154, 1144, 372, 1042, 1342, +140, 982, -756, -166, -954, -816, -310, -527, +444, 4, 681, 168, 455, -52, 138, -27, +-117, 403, -319, 654, -350, 165, -144, -793, +181, -1086, 467, -207, 508, 879, 153, 1055, +-264, 294, -510, -617, -261, -879, 203, -428, +563, 421, 478, 744, -39, 309, -517, -375, +-418, -548, 310, -37, 659, 427, 253, 345, +-383, -201, -486, -469, -14, -203, 540, 248, +561, 485, -33, 249, -547, -245, -312, -519, +278, -248, 511, 303, 270, 449, -269, 82, +-421, -384, 42, -280, 542, 226, 347, 402, +-187, 46, -398, -373, -133, -337, 246, -15, +364, 259, 161, 398, -39, 214, -13, -131, +-34, -463, -143, -388, -117, -5, 128, 349, +327, 428, 298, 239, 103, -75, -107, -406, +-227, -519, -298, -164, -88, 423, 315, 626, +557, 197, 355, -413, 0, -421, -360, 61, +-533, 237, -297, -140, 303, -345, 739, 189, +628, 695, 75, 407, -553, -574, -702, -987, +-240, -252, 351, 746, 644, 891, 632, 13, +193, -645, -522, -452, -782, 164, -225, 312, +486, -74, 693, -219, 382, 117, -165, 431, +-414, 195, -278, -404, 10, -623, 306, -89, +425, 586, 201, 561, -239, -151, -431, -530, +-71, -175, 407, 291, 568, 239, 126, -184, +-489, -323, -504, 20, 65, 423, 533, 349, +508, -138, 52, -560, -290, -426, -312, 201, +-23, 684, 107, 402, 151, -361, 200, -583, +211, -124, 204, 375, -89, 252, -429, -175, +-328, -261, 279, 159, 612, 417, 236, 5, +-228, -538, -237, -431, 81, 316, 231, 707, +-74, 263, -300, -599, 45, -692, 473, 86, +371, 753, -99, 465, -248, -390, -177, -656, +7, -200, 30, 390, 96, 420, 243, 87, +426, -82, 217, -146, -320, -213, -629, -320, +-357, -115, 371, 410, 822, 733, 558, 370, +-183, -593, -595, -1082, -390, -433, 6, 683, +230, 1058, 274, 335, 346, -473, 428, -649, +78, -295, -595, 37, -840, 152, -156, 280, +812, 342, 1100, 195, 400, -155, -695, -409, +-1013, -406, -320, -124, 515, 216, 728, 461, +449, 410, 2, 118, -377, -282, -436, -562, +-132, -490, 145, -73, 332, 519, 384, 775, +246, 428, -112, -308, -360, -801, -351, -660, +-45, -25, 384, 615, 501, 712, 261, 265, +-144, -327, -324, -517, -300, -278, -102, 13, +243, 96, 549, 83, 430, 213, -100, 351, +-547, 223, -445, -218, 54, -707, 506, -621, +548, 169, 174, 963, -276, 825, -496, -233, +-254, -975, 169, -640, 550, 323, 451, 731, +-6, 252, -434, -368, -458, -401, -9, 83, +473, 407, 504, 167, 88, -276, -340, -397, +-296, -56, 11, 294, 163, 260, 132, 60, +103, -112, 230, -99, 178, -58, -195, -84, +-540, -118, -249, 4, 523, 259, 789, 257, +208, -20, -534, -222, -585, -133, -72, 18, +416, -64, 414, -242, 102, -4, -67, 531, +-30, 674, -30, -35, -213, -954, -226, -966, +151, 85, 544, 1101, 419, 959, -112, -80, +-495, -854, -407, -729, 83, -44, 471, 432, +387, 376, 54, 92, -143, -22, -120, 33, +-140, -11, -153, -249, -8, -404, 273, -207, +550, 368, 340, 726, -386, 339, -773, -442, +-329, -749, 544, -241, 840, 357, 306, 390, +-402, 75, -588, -49, -149, 75, 276, -47, +341, -317, 94, -277, -64, 136, 26, 432, +203, 253, 6, -203, -353, -414, -378, -104, +180, 314, 720, 292, 529, -156, -249, -339, +-751, -118, -334, 277, 297, 328, 497, -31, +241, -313, -23, -215, -69, 158, -102, 250, +-139, 12, -167, -245, 41, -171, 349, 191, +345, 313, 26, 59, -239, -215, -227, -246, +-8, -118, 93, -6, 88, 169, 48, 362, +163, 302, 252, -115, 71, -588, -279, -569, +-436, -5, -142, 647, 372, 766, 619, 192, +298, -581, -230, -858, -543, -299, -375, 506, +84, 706, 488, 161, 490, -306, 89, -233, +-338, 42, -407, -43, -34, -245, 325, -124, +280, 310, -54, 441, -258, 112, -57, -249, +304, -358, 405, -212, -33, 10, -596, 261, +-459, 282, 284, 58, 831, -137, 494, -78, +-343, 56, -826, -115, -364, -354, 490, -156, +678, 488, 134, 709, -399, 34, -264, -716, +150, -559, 280, 166, -51, 387, -299, 33, +-16, -35, 381, 347, 286, 356, -132, -374, +-306, -1007, -66, -418, 113, 837, 123, 1175, +29, 168, 123, -965, 206, -868, -47, 99, +-369, 731, -308, 392, 225, -263, 565, -356, +372, 38, -262, 304, -653, 110, -291, -299, +444, -392, 678, 11, 149, 508, -511, 462, +-500, -196, 196, -631, 568, -285, 208, 392, +-344, 493, -382, -48, -34, -410, 351, -210, +498, 264, 135, 292, -426, 3, -542, -273, +-130, -208, 390, 34, 605, 189, 371, 171, +-235, -3, -641, -111, -365, -107, 168, 67, +439, 51, 281, -240, 116, -248, -10, 383, +-115, 723, -283, -9, -298, -933, -62, -702, +371, 423, 602, 975, 299, 364, -333, -536, +-546, -635, -257, -69, 70, 352, 252, 223, +337, -47, 252, -67, 85, 8, -86, -2, +-336, -2, -498, 13, -209, -105, 469, -166, +728, 30, 442, 343, -154, 216, -670, -135, +-708, -321, -146, -187, 646, 2, 754, 125, +357, 303, -257, 277, -582, -53, -472, -499, +-24, -438, 393, 158, 442, 623, 267, 308, +-85, -328, -380, -475, -261, -44, 127, 340, +246, 294, -9, -73, -158, -424, 67, -321, +268, 220, 283, 676, -138, 411, -536, -429, +-314, -917, 358, -397, 573, 543, 96, 915, +-296, 391, -204, -447, 139, -759, 213, -355, +-142, 251, -464, 401, -65, 212, 652, 98, +689, 69, -71, -86, -764, -428, -775, -502, +-52, 9, 874, 678, 900, 710, 3, 24, +-680, -658, -575, -684, -142, -175, 236, 465, +512, 665, 398, 268, -5, -312, -331, -523, +-436, -275, -158, 119, 257, 369, 457, 316, +177, 1, -186, -286, -238, -325, -59, -88, +58, 315, 59, 391, 72, -50, 69, -402, +33, -198, -24, 225, -39, 216, -29, -55, +41, -151, 29, 27, -69, 176, -12, -37, +226, -231, 227, -127, -147, 198, -372, 217, +-140, -24, 220, -145, 417, -26, 236, 97, +-251, -38, -453, -260, -113, -168, 379, 340, +298, 569, -34, 98, -228, -609, -148, -705, +142, -52, 297, 706, 91, 789, -438, 5, +-329, -771, 272, -702, 617, 63, 255, 732, +-390, 595, -680, -197, -216, -713, 600, -374, +699, 355, -63, 632, -569, 216, -283, -457, +227, -653, 267, -62, 57, 533, -107, 504, +-124, -3, 66, -350, 244, -376, 112, -110, +-282, 164, -316, 231, 81, 152, 404, 103, +338, -27, -135, -279, -459, -332, -224, -42, +294, 335, 394, 360, 52, 42, -193, -286, +-253, -243, -75, 0, 243, 131, 386, 77, +-20, 12, -441, -17, -254, -49, 278, 15, +480, 97, 138, 23, -364, -230, -471, -209, +52, 182, 569, 425, 402, 62, -306, -424, +-668, -315, -138, 179, 622, 449, 636, 107, +-170, -332, -720, -359, -351, 32, 334, 399, +573, 321, 252, -96, -224, -518, -492, -324, +-206, 356, 365, 568, 386, 68, -112, -487, +-323, -436, -22, 111, 406, 525, 308, 365, +-355, -260, -748, -594, -45, -241, 877, 325, +710, 561, -225, 265, -807, -281, -665, -601, +117, -396, 949, 290, 789, 747, -281, 420, +-944, -421, -528, -782, 301, -255, 820, 479, +435, 601, -405, 113, -540, -372, -62, -420, +233, -54, 194, 217, 86, 208, -26, 56, +-69, 41, 41, -24, -88, -236, -79, -268, +148, 7, 43, 354, -65, 336, 128, 16, +233, -335, -136, -362, -386, -57, -151, 270, +271, 303, 499, 42, 178, -87, -381, -74, +-447, -106, -77, -232, 361, -131, 405, 327, +-6, 538, -336, 106, -114, -555, 174, -561, +54, 84, -62, 457, -39, 387, 6, 48, +239, -267, 162, -332, -325, -180, -336, 70, +243, 227, 412, 386, 28, 275, -320, -259, +-283, -684, 181, -422, 544, 357, 41, 860, +-581, 396, -275, -512, 414, -765, 543, -108, +-52, 527, -597, 235, -304, -199, 515, -106, +561, 320, -201, 193, -583, -344, -160, -544, +373, -93, 475, 606, -15, 649, -473, -119, +-252, -784, 283, -405, 383, 485, -20, 642, +-331, -116, -190, -707, 335, -191, 414, 689, +-287, 634, -556, -485, 79, -993, 630, -80, +343, 1044, -389, 754, -672, -607, -111, -1220, +694, -176, 604, 1234, -204, 1013, -639, -573, +-374, -1485, 236, -455, 577, 1132, 231, 1274, +-278, -138, -268, -1328, 51, -682, 37, 730, +-83, 1001, -67, -75, 136, -944, 385, -342, +215, 769, -409, 813, -637, -415, -28, -1172, +650, -248, 506, 1078, -213, 1003, -609, -420, +-145, -1329, 511, -400, 377, 1083, -325, 1067, +-611, -430, -75, -1328, 652, -349, 722, 1074, +-95, 1059, -871, -369, -666, -1303, 278, -489, +871, 926, 487, 1111, -357, -83, -626, -1175, +-133, -726, 368, 639, 250, 1205, -205, 212, +-283, -1016, 156, -852, 480, 327, 83, 949, +-335, 333, -358, -554, -91, -511, 219, 199, +359, 441, 157, -54, -76, -451, -170, -123, +-243, 423, -153, 464, 246, -37, 347, -515, +22, -386, -213, 98, -172, 398, 12, 247, +227, -27, 221, -196, -122, -40, -353, 126, +-183, -40, 184, -346, 428, -265, 316, 416, +-126, 751, -508, 334, -438, -596, 24, -989, +513, -391, 510, 661, 99, 1116, -303, 416, +-506, -657, -333, -1009, 177, -280, 606, 655, +367, 811, -249, -33, -509, -736, -141, -342, +398, 608, 342, 697, -303, -303, -527, -995, +-18, -388, 698, 919, 565, 1101, -293, -167, +-859, -1195, -428, -678, 464, 674, 765, 1047, +313, 143, -507, -890, -726, -743, 52, 424, +720, 1054, 287, 273, -516, -928, -523, -885, +146, 430, 585, 1159, 414, 248, -288, -1001, +-652, -701, -199, 642, 382, 982, 390, -167, +-50, -1071, -192, -401, -29, 969, 127, 1029, +45, -361, -239, -1323, -259, -508, 57, 1006, +387, 1144, 401, -63, -49, -1161, -424, -717, +-415, 646, -105, 1032, 244, -15, 456, -1010, +421, -337, -130, 953, -580, 825, -477, -664, +51, -1477, 526, -158, 491, 1630, -100, 1446, +-481, -688, -177, -2043, 259, -831, 113, 1452, +-260, 1785, -208, -137, 298, -1680, 565, -783, +49, 1141, -740, 1213, -623, -537, 311, -1508, +915, -171, 363, 1600, -711, 1230, -856, -877, +221, -1995, 987, -392, 241, 1859, -806, 1565, +-639, -919, 292, -2045, 866, -166, 290, 2001, +-674, 1319, -786, -1336, 195, -2315, 845, -18, +202, 2518, -546, 1690, -384, -1305, 256, -2406, +327, -438, -206, 1698, -360, 1372, 136, -408, +597, -1072, 158, -107, -734, 636, -764, 46, +290, -652, 1075, -198, 479, 669, -641, 804, +-933, -108, -194, -879, 607, -500, 501, 364, +-170, 541, -226, 25, 205, -95, 96, 193, +-509, 89, -515, -334, 157, -549, 809, 35, +591, 843, -407, 635, -978, -568, -296, -1091, +610, 24, 557, 1245, -177, 777, -500, -891, +-128, -1521, 411, -87, 391, 1686, -248, 1377, +-633, -568, -304, -1768, 328, -933, 552, 812, +260, 1396, -149, 645, -447, -478, -392, -789, +-127, -559, 217, -194, 451, 436, 309, 989, +-184, 766, -514, -493, -197, -1494, 189, -809, +153, 1092, -125, 1830, -195, 282, 113, -1807, +519, -1574, 222, 841, -683, 2224, -889, 682, +58, -1879, 908, -1787, 696, 789, -320, 2186, +-974, 473, -403, -1817, 651, -1264, 684, 1149, +-304, 1876, -831, -222, -283, -2101, 668, -1087, +859, 1672, -146, 2356, -1080, -95, -596, -2459, +538, -1629, 755, 1227, -15, 2280, -559, 477, +-309, -1634, 426, -1353, 504, 789, -381, 1571, +-930, -43, -266, -1610, 725, -782, 811, 1319, +79, 1698, -613, -19, -630, -1749, -128, -1179, +57, 737, -142, 1350, 271, 223, 969, -683, +564, -167, -893, 520, -1649, 155, -731, -838, +1037, -766, 1772, 499, 590, 1383, -1249, 585, +-1446, -714, -19, -1010, 952, -297, 372, 493, +-688, 441, -484, -42, 581, -80, 1056, 493, +18, 510, -1463, -419, -1373, -1236, 323, -745, +1655, 899, 1154, 1702, -492, 716, -1436, -1084, +-1038, -1471, 256, -274, 1031, 841, 691, 862, +-196, 29, -772, -414, -570, -61, 41, 210, +550, -18, 404, -306, -196, -192, -622, 259, +-453, 341, 161, 125, 589, -179, 443, -44, +-192, 313, -696, -16, -671, -532, -37, -607, +608, 221, 773, 1175, 120, 1050, -718, -353, +-942, -1649, -250, -1179, 657, 607, 695, 1670, +16, 1064, -545, -525, -420, -1264, -38, -579, +101, 422, -102, 537, -17, 17, 365, -70, +343, 360, -460, 580, -994, -186, -361, -1176, +821, -936, 1188, 649, -41, 1778, -1439, 873, +-1125, -914, 470, -1695, 1437, -551, 601, 1075, +-1029, 1258, -1389, 160, 60, -818, 1296, -590, +545, 152, -1018, 401, -1101, 261, 178, -6, +1304, -183, 587, -236, -1057, -199, -1459, 370, +-83, 749, 1276, 311, 997, -788, -366, -1226, +-1346, -104, -773, 1393, 533, 1465, 861, -126, +111, -1666, -471, -1273, -375, 446, -31, 1550, +101, 1001, -265, -475, -257, -1235, 253, -641, +468, 628, -45, 1091, -553, 316, -511, -798, +-150, -969, 359, -36, 334, 1093, 82, 1220, +-92, 85, -322, -1447, -618, -1676, -445, -159, +268, 1962, 921, 2267, 540, 279, -611, -2169, +-1306, -2588, -543, -375, 648, 2301, 922, 2726, +261, 370, -619, -2241, -753, -2305, -187, -20, +277, 2043, 78, 1674, -65, -519, 197, -1743, +161, -629, -453, 1247, -834, 1369, -225, -326, +859, -1609, 994, -904, -303, 1011, -1640, 1783, +-1148, 455, 805, -1207, 1946, -1340, 861, 3, +-1503, 1087, -2437, 690, -709, -454, 1772, -674, +2381, 358, 333, 1053, -2134, 89, -2457, -1314, +-240, -1305, 2086, 370, 2000, 2051, -127, 1635, +-2085, -569, -1797, -2283, 344, -1793, 1688, 527, +893, 2286, -781, 1937, -1141, -227, -195, -2059, +650, -1685, 190, 61, -827, 1535, -718, 1369, +614, 38, 1454, -812, 322, -567, -1536, 84, +-2074, -73, -406, -326, 1876, -6, 2160, 814, +187, 1217, -1903, 344, -2203, -1371, -680, -2004, +1229, -470, 1927, 1817, 918, 2388, -750, 629, +-1823, -1796, -1495, -2529, 185, -483, 1577, 2049, +1335, 2232, -423, -44, -1610, -2192, -981, -1577, +776, 1008, 1307, 2608, -105, 916, -1639, -2355, +-1188, -3026, 969, 155, 2131, 3727, 548, 3209, +-1982, -1240, -2360, -4504, -93, -2644, 2095, 2252, +1629, 4447, -703, 1514, -1856, -2800, -632, -3353, +1005, 120, 703, 2990, -914, 1658, -1239, -1742, +444, -2517, 1775, 311, 637, 2843, -1649, 1765, +-2099, -1571, -249, -3052, 1860, -1082, 1603, 2038, +-505, 2858, -2002, 775, -923, -1775, 981, -2317, +1318, -644, -187, 1329, -1468, 1866, -972, 716, +622, -931, 1477, -1528, 609, -630, -962, 957, +-1719, 1608, -946, 398, 710, -1463, 1588, -1652, +858, 249, -413, 2233, -1428, 1667, -1388, -946, +-265, -2739, 1096, -1476, 1217, 1609, 348, 2988, +-629, 1252, -1294, -1782, -919, -2831, 213, -1051, +947, 1696, 673, 2584, -112, 1072, -768, -1297, +-747, -2239, 18, -1091, 296, 835, -79, 2008, +-242, 1480, 267, -396, 518, -1985, -46, -1754, +-1173, 365, -1391, 2067, 154, 1800, 2134, -188, +1657, -1878, -1115, -1758, -3168, -6, -1830, 1525, +1768, 1851, 3661, 691, 1272, -1057, -2802, -2195, +-3898, -1418, -718, 844, 3177, 2636, 3412, 2113, +-217, -524, -3621, -2947, -2988, -2611, 744, 453, +3511, 3109, 2158, 2769, -1475, -267, -3422, -2792, +-1753, -2527, 1507, -30, 2977, 2205, 1318, 2330, +-1746, 492, -2972, -1484, -1154, -2059, 1511, -820, +2561, 910, 805, 1948, -1706, 1238, -2444, -594, +-645, -2040, 1712, -1285, 1886, 766, -133, 2208, +-1857, 1141, -1559, -1112, 562, -2133, 1753, -718, +777, 1477, -1403, 1859, -1816, 293, -26, -1413, +1735, -1300, 1182, 180, -871, 1132, -2137, 383, +-878, -477, 1404, -311, 2048, 853, 194, 766, +-2087, -847, -2018, -2051, 180, -821, 1994, 2158, +1536, 3236, -543, 652, -1933, -3201, -1403, -3818, +340, -199, 1374, 3853, 1011, 3639, -209, -158, +-1227, -3534, -1062, -2896, -114, 410, 811, 2564, +836, 2021, 21, -180, -868, -1330, -887, -1163, +-21, -268, 657, 364, 518, 695, -200, 759, +-809, 339, -628, -490, 238, -1028, 734, -562, +339, 486, -381, 1165, -840, 579, -717, -492, +124, -883, 908, -343, 781, 299, -198, 334, +-1109, 330, -1293, 249, -173, 307, 1342, -251, +1377, -921, -61, -959, -1605, 279, -1560, 1674, +6, 1529, 1534, -149, 1198, -2054, -361, -1989, +-1367, 5, -1025, 2179, 107, 2235, 890, 233, +741, -1807, -128, -2062, -582, -466, -774, 1316, +-621, 1586, 16, 559, 1003, -633, 1184, -763, +67, -273, -1620, 29, -2120, -189, -399, -119, +2193, 544, 2639, 1081, 101, 552, -2877, -744, +-2944, -1554, 111, -905, 2910, 757, 2353, 1668, +-709, 1024, -2645, -397, -1506, -1246, 1020, -957, +1735, -50, -96, 667, -1606, 777, -618, 542, +1468, 65, 1701, -440, -660, -828, -2956, -620, +-2124, 133, 1555, 828, 3991, 1058, 2059, 351, +-2460, -525, -4656, -1077, -2279, -915, 2551, -106, +4832, 962, 2184, 1734, -2694, 1079, -4950, -899, +-2168, -2418, 2519, -1760, 4442, 729, 1613, 2698, +-2648, 2154, -3733, -170, -865, -2251, 2400, -2187, +2428, -577, -458, 1166, -2425, 1860, -925, 1521, +1697, 467, 1814, -1125, -724, -2312, -2823, -1961, +-1611, 161, 1736, 2506, 3447, 3062, 1271, 1194, +-2390, -1866, -3803, -3592, -1506, -2521, 2119, 718, +3640, 3523, 1657, 3570, -1576, 605, -3412, -2808, +-2225, -3860, 829, -1608, 2765, 1692, 1988, 3433, +-296, 2260, -1888, -521, -1862, -2441, -322, -2238, +922, -337, 1081, 1403, 333, 1743, 32, 737, +-382, -577, -823, -1049, -921, -598, -28, 296, +1007, 771, 1177, 156, -240, -715, -1699, -849, +-1218, 361, 1008, 1641, 2298, 1458, 606, -612, +-2422, -2580, -3002, -2270, 13, 432, 3418, 3105, +3354, 3141, -575, 305, -4225, -2974, -3676, -3674, +586, -1204, 4089, 2126, 3423, 3788, -275, 2258, +-3442, -950, -3251, -3379, -532, -2943, 2158, -160, +2669, 2744, 1246, 3213, -921, 847, -2245, -2114, +-1985, -2899, -410, -849, 1498, 1647, 2395, 2340, +1296, 475, -1117, -1544, -2626, -1621, -2007, 78, +252, 1552, 2467, 1225, 2636, -251, 237, -1347, +-2419, -1275, -3211, -244, -1160, 937, 2100, 1760, +3807, 1517, 1689, -325, -2232, -2405, -4067, -2744, +-2151, -457, 1742, 2683, 3920, 3621, 2235, 1310, +-1553, -2246, -3327, -3688, -1995, -1862, 556, 1210, +2215, 2880, 1704, 2066, 33, 29, -1220, -1315, +-1367, -1457, -776, -1129, 144, -558, 1010, 413, +1041, 1807, 280, 2194, -857, 757, -1311, -1729, +-488, -3108, 859, -1690, 1068, 1291, 62, 3131, +-856, 2138, -899, -631, -104, -2560, 766, -1929, +734, 257, 83, 1842, -625, 1273, -810, -316, +-672, -1215, 105, -588, 860, 781, 1122, 1148, +380, 128, -826, -1219, -1660, -1323, -1024, -160, +325, 1223, 1358, 1529, 1494, 828, 552, -507, +-900, -1494, -1835, -1639, -1613, -683, -281, 956, +1521, 2109, 2381, 2042, 1449, 494, -916, -1920, +-2706, -3376, -2836, -2163, -332, 1271, 2637, 4109, +3538, 3454, 1271, -238, -2156, -3744, -3765, -3931, +-2097, -797, 1428, 2468, 3052, 3381, 2036, 1693, +-600, -726, -2119, -2037, -1548, -1955, -63, -947, +645, 500, 357, 1628, 497, 1892, 766, 879, +396, -675, -727, -1815, -1797, -1852, -1375, -494, +740, 1114, 2246, 2025, 1598, 1707, -627, 149, +-2139, -1668, -1824, -2589, 96, -1461, 1610, 1063, +1659, 3059, 453, 2639, -960, -460, -1680, -3356, +-1229, -3043, 252, 279, 1554, 3169, 1587, 2572, +257, -404, -1454, -2238, -1724, -1317, -623, 557, +750, 684, 1242, -256, 875, -408, 22, 1091, +-703, 1795, -930, 36, -957, -2621, -309, -2800, +725, 452, 1541, 3512, 1030, 3017, -494, -750, +-1741, -3476, -1577, -2344, 70, 883, 1472, 2452, +1327, 1158, -173, -825, -989, -962, -408, 440, +568, 875, 209, -532, -1088, -1985, -1551, -1017, +128, 1494, 2582, 2974, 2803, 1631, -286, -1639, +-3951, -3422, -4011, -2172, 89, 1047, 4295, 3128, +4483, 2498, 332, 4, -3973, -2230, -4171, -2341, +-774, -854, 2589, 893, 2924, 1711, 918, 1340, +-970, 258, -1239, -685, -777, -1038, -796, -946, +-634, -557, 393, 245, 1782, 1083, 1930, 1574, +216, 917, -2253, -790, -2898, -2170, -609, -1863, +2084, 378, 2717, 2346, 724, 2219, -1649, -144, +-2185, -2171, -512, -1615, 1231, 371, 1130, 1430, +-207, 453, -1016, -727, -313, -528, 939, 788, +1041, 1160, -320, -203, -1566, -1728, -1416, -1354, +191, 722, 1835, 2024, 1874, 1230, 119, -924, +-1883, -1767, -2194, -635, -647, 1050, 1442, 1154, +2094, -290, 730, -1161, -958, -379, -1379, 1151, +-588, 1436, 128, -53, 302, -1803, 186, -1767, +249, 173, 658, 1992, 420, 1931, -533, 84, +-1334, -1576, -988, -1852, 388, -434, 1356, 945, +1016, 1295, -59, 567, -892, -292, -656, -345, +-436, -57, -190, -195, 164, -816, 641, -806, +976, 369, 383, 1687, -708, 1711, -1465, 83, +-791, -1955, 487, -2298, 1296, -753, 699, 1302, +-318, 2201, -749, 1712, -271, 119, 63, -1627, +-4, -2461, -272, -1644, -208, 719, 414, 2803, +785, 2642, 361, 110, -541, -2420, -1031, -2632, +-794, -708, 375, 1508, 1179, 1908, 709, 721, +-429, -407, -958, -606, -489, -497, 551, -395, +867, -295, -98, 89, -1228, 504, -884, 575, +690, 295, 1718, -89, 1036, -37, -861, -263, +-2047, -730, -1397, -816, 472, -76, 1646, 1225, +1516, 1677, 496, 675, -703, -1139, -1599, -2021, +-1607, -1160, -475, 532, 1177, 1608, 2111, 1345, +1564, 240, -417, -576, -2122, -875, -2001, -891, +-484, -638, 1222, 19, 1673, 1003, 1129, 1516, +57, 1061, -798, -466, -1417, -1821, -1322, -1968, +-238, -379, 1146, 1555, 1815, 2331, 1218, 1202, +-518, -864, -1991, -2089, -1683, -1615, -2, 101, +1457, 1461, 1561, 1435, 420, 515, -959, -447, +-1369, -990, -415, -997, 659, -348, 979, 671, +318, 1268, -695, 631, -1056, -525, -253, -1225, +990, -535, 1284, 532, 158, 934, -1040, 478, +-1418, -422, -634, -828, 751, -534, 1521, 217, +982, 822, -272, 815, -1025, 135, -1293, -775, +-562, -1265, 452, -556, 1148, 726, 991, 1601, +334, 965, -648, -597, -1199, -1577, -949, -1172, +95, 166, 947, 1365, 1036, 1358, 335, 252, +-587, -1065, -796, -1347, -307, -527, 251, 679, +230, 1335, -107, 732, -100, -490, 199, -1311, +544, -776, 271, 547, -459, 1322, -774, 575, +-405, -786, 213, -1067, 474, -65, 431, 795, +232, 474, 149, -358, -64, -433, -658, 274, +-1076, 548, -589, -184, 852, -916, 1781, -435, +1249, 769, -542, 1231, -2112, 242, -1890, -1079, +16, -1193, 1964, -70, 2075, 1011, 482, 959, +-1364, 62, -1907, -628, -833, -687, 784, -216, +1397, 177, 603, 462, -409, 495, -486, 239, +-5, -316, 77, -811, -450, -653, -657, 327, +71, 1268, 1183, 946, 1222, -559, -360, -1690, +-1597, -941, -1233, 899, 513, 1873, 1632, 665, +971, -1186, -774, -1658, -1421, -225, -396, 1335, +926, 1129, 981, -357, -92, -1286, -981, -363, +-533, 911, 519, 954, 818, -303, 3, -1260, +-632, -623, -383, 874, 266, 1334, 607, 93, +50, -1151, -609, -877, -486, 380, 399, 955, +709, 276, 277, -725, -466, -684, -717, 361, +-220, 974, 437, 330, 544, -705, 184, -982, +-126, -266, -267, 622, -290, 911, -188, 425, +66, -317, 294, -662, 416, -539, 180, -213, +-222, 240, -507, 527, -350, 651, 199, 238, +411, -323, 328, -744, 7, -690, -167, -132, +-334, 509, -189, 862, 31, 653, 316, 3, +281, -704, -3, -1032, -331, -626, -216, 292, +170, 1070, 393, 1082, 105, 249, -428, -847, +-393, -1185, 2, -656, 511, 367, 596, 904, +84, 775, -531, 91, -725, -482, -262, -510, +368, -215, 804, -76, 523, -195, -167, 81, +-626, 695, -553, 936, -22, 25, 261, -1146, +200, -1261, 138, -74, 442, 1159, 488, 1094, +-206, -15, -1019, -851, -1059, -562, -29, 188, +1275, 352, 1539, -158, 441, -347, -1105, 98, +-1458, 663, -751, 428, 316, -407, 1031, -821, +1040, -469, 550, 444, -220, 770, -882, 389, +-1249, -417, -631, -732, 659, -253, 1477, 515, +1061, 738, -236, 43, -1051, -809, -868, -852, +-79, 107, 275, 1122, 185, 1081, 141, -246, +599, -1419, 835, -1216, 59, 310, -1193, 1411, +-1484, 1100, -293, -225, 1215, -1165, 1670, -876, +595, 77, -802, 733, -1201, 590, -502, 48, +227, -405, 297, -431, 177, -89, 367, 357, +645, 355, 333, -92, -574, -571, -1280, -363, +-717, 358, 705, 780, 1470, 332, 714, -536, +-638, -922, -1063, -335, -207, 542, 646, 853, +420, 255, -395, -457, -626, -605, 212, -193, +931, 285, 628, 314, -442, 77, -962, -188, +-497, -153, 332, -3, 641, 120, 270, 89, +80, -25, 86, -141, 81, -138, -337, -25, +-701, 97, -369, 56, 515, 0, 1080, 86, +644, 224, -325, 17, -1054, -446, -743, -723, +213, -186, 906, 781, 737, 1233, -113, 414, +-704, -1031, -532, -1585, 289, -609, 717, 938, +365, 1439, -378, 582, -735, -540, -192, -772, +585, -406, 704, -131, 185, -268, -299, -19, +-409, 707, -143, 1201, 0, 541, -45, -971, +54, -1883, 500, -1117, 682, 855, 193, 2086, +-600, 1282, -1004, -634, -549, -1645, 428, -1027, +1249, 212, 1016, 727, 10, 398, -935, 80, +-1045, 178, -428, 304, 572, -191, 946, -851, +567, -873, -114, -17, -332, 990, -162, 1102, +-35, 217, -215, -760, -423, -922, -121, -366, +720, 162, 1219, 358, 630, 409, -734, 381, +-1503, 160, -950, -340, 422, -745, 1476, -581, +1227, 114, 147, 818, -731, 678, -968, -32, +-608, -644, -13, -534, 563, -27, 836, 232, +756, 134, 191, 52, -614, 168, -985, 182, +-553, -283, 290, -574, 893, -230, 906, 502, +274, 701, -517, 7, -803, -785, -301, -749, +447, 210, 651, 1004, 148, 699, -430, -528, +-317, -1248, 413, -649, 840, 770, 200, 1321, +-829, 362, -983, -970, 10, -1223, 1087, -69, +962, 996, 52, 809, -602, -289, -333, -886, +128, -394, 10, 457, -451, 608, -180, -2, +913, -618, 1455, -380, 488, 349, -1285, 525, +-1979, -13, -655, -568, 1347, -375, 2159, 244, +1066, 556, -782, 221, -1702, -411, -1096, -635, +359, -219, 1184, 405, 1094, 617, 283, 244, +-463, -389, -691, -631, -284, -386, 245, 209, +328, 579, 230, 398, 17, -113, 61, -516, +242, -375, 242, -19, -200, 246, -424, 223, +-170, 100, 299, -3, 559, -149, 406, -310, +-54, -237, -343, 159, -135, 439, 197, 213, +231, -374, 32, -539, -50, -79, -45, 482, +270, 395, 426, -159, 198, -449, -273, -230, +-422, 146, -269, 188, 151, -40, 680, -71, +776, 178, 179, 226, -492, -220, -625, -673, +-291, -357, 252, 476, 695, 859, 678, 310, +219, -650, -184, -848, -500, -258, -462, 505, +-64, 587, 476, 59, 716, -319, 434, -265, +-46, 85, -464, 123, -333, -145, 53, -341, +292, -97, 278, 330, 180, 477, 180, 140, +269, -331, 174, -607, -195, -499, -500, 59, +-303, 641, 320, 812, 939, 192, 870, -680, +-123, -1108, -1004, -519, -822, 577, 229, 1154, +1125, 606, 952, -491, -127, -1035, -917, -652, +-443, 254, 617, 687, 888, 440, 216, -97, +-631, -255, -516, -209, 266, -255, 881, -345, +553, -33, -179, 609, -516, 729, -348, 15, +90, -983, 480, -1013, 527, 68, 353, 1188, +-103, 978, -437, -417, -262, -1330, 398, -723, +654, 692, 141, 1189, -435, 248, -289, -1011, +583, -974, 984, 205, 191, 1007, -1076, 479, +-962, -517, 548, -721, 1523, -79, 796, 390, +-711, 91, -1177, -337, -72, -95, 1237, 683, +839, 582, -634, -524, -1098, -1473, 204, -778, +1508, 1010, 1140, 1872, -545, 752, -1615, -1266, +-655, -1968, 1069, -702, 1566, 1052, 398, 1501, +-786, 530, -684, -618, 266, -867, 648, -414, +76, 61, -552, 177, -231, 73, 753, 179, +1230, 355, 456, 216, -838, -281, -1269, -700, +-432, -493, 922, 102, 1535, 586, 869, 584, +-375, 50, -1006, -459, -650, -544, 142, -134, +564, 312, 578, 202, 364, -196, 271, -363, +162, 136, -205, 667, -580, 391, -460, -489, +304, -1049, 915, -590, 917, 367, 240, 997, +-428, 849, -502, 68, -272, -808, 43, -1183, +296, -714, 558, 363, 685, 1240, 479, 1118, +-168, 21, -796, -1149, -762, -1271, 88, -301, +954, 728, 1152, 864, 474, 229, -368, -233, +-755, -201, -462, -133, 180, -341, 573, -550, +728, -110, 459, 642, 20, 926, -397, 253, +-386, -780, 9, -1046, 335, -337, 456, 579, +252, 747, 102, 187, 35, -328, 4, -327, +5, -127, -34, -80, 108, -147, 343, 59, +404, 385, 113, 282, -229, -243, -125, -646, +349, -261, 552, 500, 180, 666, -463, -66, +-449, -877, 264, -631, 929, 456, 669, 1027, +-300, 307, -734, -855, -249, -1059, 609, 61, +705, 1064, 152, 725, -322, -633, -64, -1235, +510, -177, 468, 1126, -144, 1049, -655, -503, +-170, -1527, 775, -767, 1008, 934, 198, 1535, +-618, 335, -625, -1181, 26, -1273, 683, -44, +575, 958, 54, 726, -240, -154, 74, -601, +311, -312, 198, 149, -72, 195, -153, -87, +54, -196, 360, -36, 473, 234, 277, 225, +48, -34, -232, -374, -371, -407, -116, -31, +441, 347, 724, 377, 441, 82, -54, -227, +-390, -389, -308, -268, 55, -52, 299, 261, +410, 327, 483, 251, 378, -71, -70, -456, +-461, -533, -369, -219, 73, 423, 611, 670, +694, 358, 328, -405, -171, -785, -360, -421, +-323, 308, -87, 568, 401, 166, 712, -217, +670, -207, 52, 101, -661, 38, -706, -326, +101, -476, 890, 46, 893, 723, 279, 645, +-484, -204, -683, -890, -146, -666, 470, 126, +656, 659, 501, 447, 115, -28, -352, -330, +-550, -215, -176, -134, 449, -169, 902, -101, +638, 212, -168, 439, -730, 187, -534, -289, +247, -514, 846, -212, 809, 210, 174, 315, +-496, 25, -573, -215, -200, -107, 455, 112, +826, 199, 462, -47, -209, -326, -520, -390, +-195, -26, 298, 426, 600, 489, 284, 82, +-222, -422, -152, -536, 234, -245, 348, 160, +107, 319, -156, 289, -44, 168, 294, -38, +379, -397, -15, -615, -239, -259, 67, 482, +367, 794, 340, 226, -143, -597, -413, -765, +50, -63, 725, 618, 590, 509, -278, -320, +-630, -790, -155, -248, 675, 673, 785, 875, +60, -42, -567, -974, -222, -863, 315, 128, +393, 808, 57, 562, -28, -15, 205, -305, +328, -295, -36, -372, -531, -386, -211, 4, +580, 674, 899, 842, 282, 113, -462, -858, +-667, -993, -67, -158, 554, 686, 546, 713, +190, 7, 68, -442, 77, -240, -142, 195, +-438, 129, -324, -336, 410, -509, 1037, -12, +758, 642, -301, 736, -1043, -8, -700, -782, +388, -856, 1118, -172, 815, 591, -71, 700, +-567, 285, -460, -252, 12, -476, 319, -362, +334, -179, 306, 84, 267, 344, 105, 429, +-290, 170, -347, -372, -128, -575, 324, -277, +582, 268, 423, 502, -23, 223, -366, -231, +-317, -475, -15, -251, 412, 252, 526, 460, +237, 166, -132, -371, -232, -527, -167, -112, +101, 366, 329, 410, 336, 23, 55, -236, +-75, -174, -65, -70, -91, -143, -6, -165, +219, 69, 398, 489, 338, 452, -116, -115, +-514, -755, -293, -676, 388, 107, 824, 677, +442, 604, -325, -22, -702, -438, -229, -442, +463, -143, 614, 100, 246, 113, -151, 82, +-162, 180, 26, 192, -24, -28, -161, -357, +35, -458, 519, -161, 639, 288, 91, 526, +-577, 298, -688, -151, 42, -474, 754, -493, +722, -117, 101, 393, -371, 594, -324, 204, +-66, -427, 71, -684, 67, -210, 256, 499, +574, 647, 422, 27, -312, -669, -841, -584, +-529, 128, 519, 742, 1150, 464, 662, -339, +-443, -768, -841, -308, -301, 455, 359, 583, +503, -11, 226, -530, 2, -302, 80, 304, +134, 468, -176, -65, -380, -586, -103, -404, +423, 252, 572, 635, 246, 312, -274, -238, +-392, -522, -65, -385, 243, 2, 242, 301, +55, 394, 38, 237, 151, -55, 194, -372, +-77, -471, -293, -213, -173, 284, 206, 537, +428, 300, 303, -239, -65, -471, -270, -223, +-144, 125, 80, 224, 199, 42, 132, -99, +31, -64, 17, 124, 199, 132, 157, -59, +-110, -266, -252, -260, -112, 0, 185, 285, +434, 328, 310, 70, -79, -251, -306, -322, +-199, -154, -44, 68, 177, 143, 344, 165, +326, 130, 79, 37, -250, -193, -371, -312, +-158, -160, 308, 152, 534, 313, 310, 73, +-185, -130, -421, -81, -207, 54, 229, -94, +385, -250, 191, -107, -49, 284, -204, 368, +-125, 52, 86, -351, 247, -346, 182, 4, +-51, 207, -192, 135, -101, -33, 272, -19, +435, 83, 2, 27, -480, -232, -395, -352, +319, -46, 833, 453, 429, 555, -581, 0, +-958, -682, -156, -699, 901, 51, 940, 758, +-12, 669, -932, -40, -633, -712, 420, -661, +825, -9, 166, 534, -498, 458, -264, 68, +272, -128, 455, -212, -12, -385, -414, -428, +-244, 148, 249, 822, 445, 712, 183, -359, +-141, -1105, -247, -629, -127, 534, 72, 982, +116, 328, 176, -507, 167, -624, 32, -175, +-165, 246, -178, 363, 57, 148, 249, -163, +280, -254, -144, -45, -376, 90, -65, 25, +444, -39, 469, 44, -68, 143, -525, 69, +-426, -190, 114, -302, 534, -111, 463, 284, +74, 383, -306, 113, -369, -311, -157, -396, +13, -139, 234, 168, 404, 239, 343, 219, +-26, 124, -359, -68, -390, -398, -236, -443, +88, -41, 488, 452, 664, 585, 269, 189, +-478, -382, -855, -707, -410, -398, 432, 403, +841, 751, 483, 236, -208, -474, -589, -519, +-237, 97, 152, 409, 84, 40, -84, -380, +189, -227, 506, 331, 261, 396, -332, -17, +-797, -275, -412, -260, 520, -123, 1059, -23, +405, 284, -736, 474, -970, 12, -40, -533, +818, -437, 658, 229, -134, 509, -637, 85, +-465, -386, 244, -375, 693, 115, 306, 550, +-307, 350, -448, -225, -197, -709, 27, -578, +327, 185, 468, 976, 158, 899, -299, -255, +-470, -1234, -277, -951, 139, 284, 507, 1111, +445, 813, -6, -134, -425, -766, -360, -717, +-92, -58, 179, 489, 229, 476, 275, 61, +196, -179, -73, -99, -370, -84, -504, -208, +-134, -208, 511, 134, 840, 547, 227, 356, +-641, -410, -841, -750, -218, -204, 607, 625, +788, 707, 139, -2, -466, -717, -480, -648, +-71, 101, 196, 750, 214, 573, 113, -121, +29, -675, 25, -503, -131, 46, -274, 358, +-137, 431, 293, 310, 425, -79, 0, -542, +-433, -575, -318, -85, 227, 508, 533, 672, +80, 334, -519, -491, -455, -849, 251, -329, +684, 539, 287, 815, -481, 147, -707, -638, +-100, -622, 524, 150, 663, 658, 87, 278, +-589, -373, -597, -519, 6, -143, 502, 374, +473, 526, 22, 166, -480, -377, -379, -584, +163, -240, 340, 346, 20, 628, -156, 298, +-38, -375, 92, -569, 45, -177, -26, 243, +-168, 311, -156, 153, 67, -20, 291, -131, +231, -191, -119, -184, -396, -4, -309, 330, +178, 339, 468, -171, 240, -451, -304, -184, +-417, 298, 12, 332, 349, 49, 114, -252, +-269, -296, -261, -29, 97, 235, 410, 282, +235, 45, -354, -242, -535, -286, -80, -35, +351, 164, 333, 216, 162, 163, -58, -45, +-423, -332, -444, -317, 52, 105, 515, 415, +353, 269, -106, -151, -381, -441, -261, -201, +109, 237, 299, 311, -32, 21, -337, -199, +37, -155, 397, 51, 131, 181, -287, 80, +-450, -214, -203, -241, 317, 73, 636, 317, +208, 289, -568, -118, -702, -514, -27, -407, +642, 285, 512, 702, -265, 282, -588, -474, +-149, -610, 294, -41, 233, 454, -111, 322, +-127, -176, -49, -274, 75, 50, 45, 232, +-110, 34, -168, -335, -63, -273, 277, 191, +348, 522, -170, 270, -582, -376, -318, -679, +273, -188, 546, 591, 375, 661, -188, -91, +-812, -626, -559, -270, 264, 113, 827, 203, +545, 205, -247, 244, -826, -10, -593, -495, +150, -535, 641, 67, 555, 739, 43, 722, +-621, -161, -712, -975, 46, -794, 523, 225, +401, 1091, -68, 758, -345, -330, -272, -963, +122, -579, 103, 288, -190, 629, -13, 336, +240, -190, 86, -244, -47, 98, -168, 37, +-417, -393, -178, -470, 493, 266, 545, 932, +-112, 517, -528, -524, -516, -1038, 41, -434, +536, 488, 401, 800, -228, 350, -447, -290, +-201, -423, 151, -94, 283, -102, -44, -242, +-311, 64, 58, 693, 219, 618, -132, -339, +-180, -977, 27, -587, 27, 495, 2, 985, +87, 359, -240, -626, -200, -812, 281, 12, +361, 791, -168, 398, -580, -586, -329, -637, +380, 298, 645, 750, -30, 91, -579, -581, +-300, -437, 110, 216, 285, 528, 164, 128, +-379, -380, -352, -406, 427, 165, 546, 534, +-348, 202, -651, -566, -187, -625, 214, 371, +458, 872, 306, 61, -311, -894, -442, -461, +49, 616, -3, 765, -262, -159, 50, -882, +444, -381, 305, 670, -158, 796, -569, -208, +-477, -830, 155, -307, 479, 603, 212, 589, +-41, -272, -274, -758, -187, -98, 110, 867, +-56, 593, -369, -711, -1, -1106, 573, 115, +290, 1233, -278, 680, -529, -826, -307, -1199, +249, 45, 407, 1289, -82, 755, -322, -964, +100, -1368, 292, 207, -43, 1563, -366, 769, +-449, -1140, -89, -1446, 581, 267, 540, 1521, +-137, 557, -528, -1107, -440, -1066, -73, 454, +317, 1264, 362, 371, -29, -1054, -128, -1101, +-71, 315, -229, 1209, -185, 602, 62, -665, +275, -937, 173, -34, -190, 768, -396, 339, +-50, -678, 370, -489, 117, 675, -221, 937, +-222, -233, -141, -1278, 82, -713, 253, 873, +61, 1381, -216, 85, -46, -1259, 34, -829, +-135, 672, -157, 1109, -49, 19, 93, -1197, +366, -770, 226, 861, -338, 1435, -569, 169, +-223, -1375, 227, -1271, 363, 332, 354, 1488, +27, 812, -365, -742, -544, -1114, -294, -48, +242, 682, 562, 345, 414, -299, -219, -396, +-696, 212, -478, 450, 262, 0, 720, -504, +216, -290, -524, 355, -640, 404, 84, -12, +702, -393, 242, -261, -504, 296, -536, 443, +129, 44, 439, -437, 154, -474, -361, 51, +-390, 568, 259, 493, 568, -113, -97, -632, +-733, -420, -401, 206, 286, 539, 710, 265, +367, -291, -439, -327, -861, 40, -159, 219, +641, 80, 392, -203, -361, -218, -464, 110, +234, 429, 650, 296, -17, -388, -898, -759, +-599, -153, 421, 829, 985, 881, 442, -291, +-604, -1149, -971, -534, -250, 705, 657, 1002, +517, 47, -146, -771, -352, -448, -116, 338, +168, 357, 60, -236, -232, -371, -327, 232, +233, 813, 595, 381, -92, -888, -669, -1497, +-301, -117, 461, 1804, 550, 1617, -82, -629, +-562, -2138, -486, -939, 229, 1271, 659, 1619, +320, -151, -472, -1379, -632, -460, 84, 1097, +443, 910, 25, -681, -272, -1516, -119, -316, +213, 1478, 271, 1510, -57, -297, -492, -1776, +-373, -1116, 290, 929, 435, 1669, -6, 187, +-176, -1555, 31, -958, 114, 1228, -227, 1661, +-452, -339, -219, -2165, 487, -1236, 859, 1498, +163, 2514, -758, 447, -847, -2250, -37, -2144, +623, 750, 328, 2329, -149, 781, -116, -1616, +304, -1452, 109, 920, -661, 1744, -880, -88, +-33, -2056, 1255, -1111, 1166, 1702, -468, 2320, +-1515, -233, -711, -2694, 714, -1521, 977, 1834, +78, 2649, -581, -166, -360, -2728, 498, -1533, +357, 1756, -506, 2600, -734, 0, 159, -2457, +918, -1607, 386, 1274, -651, 2047, -783, 39, +214, -1449, 816, -513, 67, 877, -770, 430, +-575, -768, 354, -670, 1019, 641, 369, 1151, +-881, 37, -1035, -1193, 275, -688, 874, 642, +113, 830, -362, -202, -142, -765, 224, 162, +216, 981, -301, 217, -597, -1247, 15, -1066, +760, 804, 427, 1716, -419, 399, -572, -1390, +-185, -1491, 415, 324, 467, 1752, -269, 806, +-669, -1153, -56, -1456, 628, 216, 425, 1320, +-87, 659, -599, -547, -681, -941, 43, -128, +793, 432, 508, 241, -72, 8, -412, 310, +-429, 370, -202, -583, 244, -1205, 313, -216, +177, 1491, 18, 1546, -183, -525, -59, -2109, +-21, -995, -269, 1306, -279, 1891, 269, 168, +594, -1613, 191, -1192, -382, 665, -664, 1499, +-321, 41, 524, -1235, 678, -503, -69, 1079, +-612, 936, -317, -852, 298, -1523, 506, 121, +132, 1960, -498, 1051, -555, -1322, 211, -2100, +664, -134, 241, 1843, -408, 1549, -450, -442, +71, -1671, 370, -789, 82, 709, -401, 962, +-290, -30, 345, -508, 525, 68, -14, 571, +-621, 18, -402, -882, 170, -684, 414, 482, +104, 1156, -251, 382, -12, -637, 377, -588, +124, 111, -670, 220, -814, -398, 243, -387, +1243, 531, 939, 1286, -560, 517, -1536, -1222, +-746, -1714, 850, -306, 1273, 1448, 199, 1520, +-863, 89, -648, -1184, 239, -956, 659, 277, +9, 751, -842, 41, -520, -623, 658, -246, +1146, 812, 158, 1054, -988, -132, -1051, -1514, +-230, -1281, 970, 548, 1104, 1724, 211, 1061, +-842, -600, -990, -1423, -120, -633, 599, 537, +830, 749, 180, 114, -641, -168, -688, 23, +18, 97, 526, -144, 344, -440, -101, -148, +-256, 482, -297, 577, -205, -202, 45, -674, +342, -158, 563, 695, 5, 596, -747, -460, +-702, -1099, 194, -229, 822, 1154, 527, 1117, +-298, -281, -656, -1382, -171, -794, 397, 672, +179, 1271, -342, 260, -54, -950, 402, -679, +360, 484, -323, 856, -737, -178, -276, -1025, +683, -463, 794, 1098, -267, 1235, -1058, -208, +-401, -1504, 794, -976, 989, 746, -334, 1328, +-1196, 410, -370, -821, 893, -515, 917, 194, +-351, 100, -920, -375, -302, -126, 754, 742, +813, 899, -459, -156, -1108, -1451, -210, -1038, +1193, 805, 810, 1861, -580, 538, -1097, -1337, +-334, -1553, 556, 56, 689, 1467, 62, 1095, +-393, -472, -309, -1241, -1, -634, -6, 516, +-80, 886, 44, 508, 301, -201, 260, -700, +-267, -701, -497, -52, 49, 925, 477, 973, +145, -136, -459, -1281, -363, -944, 452, 641, +898, 1671, 60, 683, -1389, -1391, -1130, -1958, +749, -16, 1890, 2178, 713, 1918, -1373, -767, +-1860, -2686, -325, -1465, 1467, 1500, 1387, 2747, +-160, 824, -1176, -1931, -700, -2415, 363, -188, +492, 2226, -18, 1925, -170, -549, 270, -2206, +293, -1242, -257, 992, -588, 2031, -165, 862, +558, -1247, 679, -1876, -230, -475, -1033, 1322, +-439, 1522, 1014, 257, 1199, -926, -210, -1125, +-1572, -337, -1367, 508, 453, 814, 2003, 460, +1434, -116, -726, -434, -2076, -378, -1437, -235, +382, -88, 1840, 150, 1714, 762, -20, 843, +-1654, -111, -1775, -1324, -304, -1453, 1382, 93, +1788, 1965, 533, 2107, -1201, -294, -1729, -2769, +-488, -2288, 1093, 949, 1344, 3040, 294, 1860, +-837, -1226, -1037, -2683, -337, -1230, 545, 1146, +755, 1850, 109, 643, -326, -669, -206, -827, +-73, -187, -131, 181, -315, -131, -46, -247, +500, 294, 857, 908, 378, 538, -898, -492, +-1395, -1282, -545, -813, 1158, 629, 1713, 1352, +507, 765, -1245, -515, -1605, -1130, -221, -608, +1088, 438, 966, 1065, -367, 226, -906, -824, +56, -644, 891, 344, 314, 1007, -1029, 434, +-1272, -639, 228, -1117, 1605, -473, 1155, 772, +-791, 1089, -1644, 429, -359, -427, 1133, -716, +973, -397, -623, -162, -1288, 81, 85, 455, +1714, 679, 1187, 571, -1356, -160, -2509, -1027, +-575, -1203, 2232, -188, 2443, 1305, -237, 1471, +-2600, 306, -1824, -1066, 905, -1355, 2359, -424, +952, 725, -1442, 1100, -2162, 475, -156, -598, +1972, -1008, 1749, -181, -380, 1051, -2122, 963, +-1519, -660, 550, -1552, 2038, -739, 1401, 1245, +-502, 2169, -1630, 743, -1133, -1777, 186, -2679, +1026, -585, 733, 2146, 59, 2711, -303, 434, +-308, -2255, -435, -2374, -495, -38, 54, 2109, +770, 1657, 697, -338, -117, -1620, -842, -908, +-637, 598, 300, 998, 710, 198, 226, -403, +-571, -227, -361, 103, 365, -125, 699, -349, +-80, 45, -1084, 689, -608, 742, 963, -358, +1489, -1110, -22, -740, -1679, 496, -1539, 1294, +469, 710, 2172, -495, 1547, -1210, -1142, -705, +-2504, 500, -1233, 1160, 1327, 582, 2281, -596, +907, -1150, -1104, -231, -1818, 887, -854, 974, +630, -119, 1381, -1109, 840, -758, -264, 437, +-868, 1064, -742, 694, -143, -435, 566, -959, +770, -718, 214, 295, -447, 904, -778, 600, +-179, -90, 502, -479, 665, -545, -123, -236, +-565, 83, -503, 524, 56, 657, 483, 248, +409, -573, 18, -973, -271, -398, -368, 663, +-412, 1133, -173, 440, 553, -630, 983, -1188, +482, -408, -724, 610, -1630, 1053, -665, 369, +1233, -518, 1967, -693, 328, -143, -1579, 146, +-1705, 82, -55, 52, 1523, 582, 1341, 601, +-335, -260, -1472, -1224, -840, -1265, 632, 451, +1104, 2087, 256, 1823, -688, -864, -670, -2884, +-78, -1905, 397, 1343, 538, 3126, 199, 1820, +-229, -1403, -461, -3138, -461, -1771, -84, 1219, +673, 3099, 977, 1840, 15, -1000, -1097, -2922, +-996, -1944, 60, 801, 1106, 2621, 1054, 2009, +-169, -357, -1236, -2331, -899, -2092, 197, -7, +905, 1986, 823, 2032, 41, 319, -871, -1376, +-913, -1810, -286, -728, 685, 777, 1331, 1469, +640, 1075, -1072, -201, -1761, -1086, -451, -1078, +1355, -236, 1890, 614, 360, 754, -1838, 482, +-1876, -6, 415, -213, 1989, -468, 1058, -546, +-1008, -477, -1752, 241, -321, 939, 1538, 1218, +1380, 252, -816, -1300, -1837, -1815, -606, -584, +1382, 1405, 1717, 2081, -108, 838, -1784, -1090, +-1047, -2059, 842, -1152, 1323, 752, 35, 1809, +-934, 1312, -573, -303, 721, -1374, 1063, -1273, +-312, -203, -1555, 902, -769, 1185, 1042, 505, +1763, -447, 543, -855, -1333, -492, -1819, 14, +-492, 174, 1238, 341, 1492, 507, 514, 611, +-851, 16, -1227, -1071, -569, -1264, 386, -227, +675, 1301, 624, 1598, 128, 371, -288, -1099, +-423, -1414, -388, -362, -439, 555, -35, 544, +786, 327, 1178, 452, 603, 509, -1138, -217, +-2092, -1361, -1077, -1437, 1573, -44, 2739, 1834, +1006, 2063, -1830, 386, -2876, -1661, -739, -2020, +1895, -811, 2237, 772, 119, 1454, -1645, 1185, +-1137, 510, 654, -496, 1135, -1384, -227, -1685, +-1466, -585, -500, 1300, 1391, 2276, 1967, 1463, +353, -575, -2066, -2231, -2560, -2139, -493, -433, +2213, 1695, 2980, 2489, 965, 1368, -2094, -768, +-3371, -2439, -1343, -2050, 1825, -33, 3202, 1930, +1485, 2248, -1451, 765, -2885, -1214, -1354, -2147, +1199, -1186, 2170, 695, 885, 1835, -816, 1182, +-1467, -474, -578, -1556, 560, -772, 826, 773, +517, 1294, -27, 209, -624, -1301, -1165, -1382, +-377, 274, 1053, 2030, 1895, 1772, 810, -523, +-1606, -2586, -3118, -2295, -1187, 232, 2393, 2792, +4002, 2848, 1440, 469, -2834, -2424, -4744, -3207, +-1813, -1400, 3114, 1476, 4932, 3186, 1914, 2399, +-2731, -188, -4685, -2767, -2261, -3233, 2191, -1069, +4217, 2124, 2288, 3682, -1378, 2040, -3424, -1524, +-2434, -3824, 595, -2372, 2640, 1332, 2252, 3613, +103, 2071, -1644, -1511, -1992, -3259, -1011, -1387, +632, 2051, 1709, 2837, 1795, 518, 394, -2266, +-1466, -2365, -2577, -123, -1478, 1920, 1163, 1823, +3244, 444, 2429, -782, -817, -1236, -3683, -1306, +-3256, -865, 412, 483, 3780, 2185, 3688, 2688, +122, 586, -3386, -2773, -3760, -4095, -860, -1640, +2649, 2600, 3504, 4701, 1441, 2496, -1594, -1833, +-3111, -4166, -1993, -2735, 699, 606, 2598, 2649, +2007, 2372, -138, 699, -1934, -849, -1794, -1400, +-48, -1490, 1332, -875, 1036, 286, -84, 1634, +-490, 1908, -109, 650, 58, -1197, -351, -2111, +-725, -1242, 69, 589, 1370, 1828, 1356, 1359, +-593, -236, -2426, -1521, -1710, -1075, 1346, 438, +3324, 1433, 1738, 715, -2022, -967, -3863, -1824, +-1753, -584, 2154, 1560, 3970, 2403, 1821, 871, +-1866, -1704, -3558, -2833, -1868, -1461, 1081, 1180, +2508, 2631, 1711, 2046, 107, 142, -1032, -1673, +-1390, -2402, -1333, -1796, -520, 53, 866, 2401, +2073, 3385, 1930, 1505, -118, -2080, -2484, -4034, +-2839, -2407, -495, 1253, 2195, 3507, 2893, 2563, +1120, -152, -1402, -1974, -2532, -2015, -1595, -1047, +350, 53, 1694, 1171, 1923, 1951, 819, 1629, +-898, -248, -2185, -2383, -1835, -2712, 271, -414, +2410, 2375, 2304, 2916, 86, 743, -2284, -1895, +-2290, -2339, -302, -680, 1768, 946, 1808, 1138, +237, 538, -757, 294, -772, 289, -354, -431, +-457, -1568, -426, -1493, 229, 444, 1417, 2353, +1812, 2030, 71, -193, -2160, -2230, -2813, -2101, +-649, -317, 2296, 1335, 3177, 1591, 1230, 1018, +-1705, 169, -2829, -787, -1689, -1661, 666, -1643, +1976, -102, 1517, 1876, 429, 2564, -498, 909, +-1075, -1465, -1379, -2630, -779, -1490, 447, 697, +1610, 1864, 1499, 1440, 123, 233, -1240, -392, +-1372, -924, -415, -1133, 359, -896, 465, 118, +162, 1195, 610, 1624, 1069, 1072, 483, -361, +-1514, -1820, -2566, -2330, -1208, -1006, 1745, 1486, +3615, 3326, 2133, 2422, -1662, -836, -3969, -3679, +-2642, -3415, 1016, 56, 3515, 3457, 2821, 3537, +-176, 485, -2698, -2539, -2435, -2668, -418, -593, +1375, 1051, 1498, 1018, 739, 296, 136, 558, +-328, 1073, -883, 231, -1418, -1884, -764, -2998, +705, -799, 2142, 2723, 1708, 4023, -421, 1254, +-2466, -2823, -2044, -4068, 312, -1237, 2029, 2416, +1770, 2970, -62, 711, -1537, -1497, -1200, -1385, +318, -15, 1068, 747, 375, 48, -826, -915, +-956, -453, 194, 931, 1514, 1489, 1392, 423, +-487, -1119, -2264, -1369, -2046, -510, 448, 467, +2752, 754, 2364, 535, -326, 365, -2488, 108, +-2102, -264, 87, -686, 1617, -848, 1204, -417, +28, 350, -419, 1029, 42, 1282, 55, 638, +-642, -706, -1185, -1878, -284, -1696, 1217, 6, +1643, 1792, 406, 2330, -1019, 786, -1357, -1197, +-406, -1973, 345, -1162, 442, 94, 232, 868, +270, 1004, 472, 804, 300, 456, -448, -86, +-1129, -999, -966, -1576, 196, -1157, 1180, 361, +1383, 1976, 517, 2193, -833, 831, -1562, -1270, +-927, -2644, 375, -2301, 1123, -165, 927, 2550, +-59, 3406, -546, 1448, -292, -1893, 120, -3634, +-130, -2063, -589, 1072, -355, 2799, 485, 1755, +1080, -311, 715, -1266, -466, -834, -1088, -167, +-729, -131, 167, -258, 581, 229, 251, 923, +74, 973, 175, 7, 417, -887, 140, -1048, +-700, -295, -1105, 422, -616, 445, 429, 263, +1384, 211, 1461, 393, 356, 123, -1143, -480, +-1996, -1070, -1436, -807, 288, 337, 2064, 1367, +2303, 1212, 691, 70, -1569, -961, -2499, -1126, +-1434, -519, 732, 29, 2009, 584, 1462, 797, +71, 883, -874, 242, -940, -704, -555, -1414, +-199, -1045, 17, 214, 485, 1454, 978, 1663, +910, 386, -181, -1237, -1275, -1848, -1419, -682, +-140, 817, 1263, 1482, 1345, 790, 162, -281, +-1118, -918, -978, -855, 151, -204, 1120, 493, +681, 976, -664, 525, -1404, -391, -525, -1029, +996, -714, 1659, 348, 771, 1066, -885, 905, +-1787, -233, -1137, -1147, 399, -969, 1408, 21, +1463, 969, 283, 1046, -887, 312, -1203, -575, +-696, -1059, -61, -671, 519, 151, 863, 853, +759, 890, 407, 312, -412, -312, -1323, -968, +-1371, -1078, 20, -207, 1484, 1205, 1720, 1829, +424, 501, -1341, -1612, -1718, -2257, -458, -448, +1153, 1947, 1266, 2268, 95, 261, -979, -2018, +-689, -2085, 448, 73, 865, 1956, 214, 1426, +-647, -469, -872, -1409, -285, -518, 655, 672, +929, 566, 488, -377, -216, -636, -783, 415, +-943, 1016, -454, 251, 574, -1141, 1188, -1183, +1074, 221, 1, 1544, -1235, 994, -1638, -804, +-614, -1575, 1077, -462, 1865, 1198, 1131, 1347, +-603, -34, -1843, -1338, -1498, -1036, 116, 320, +1589, 1124, 1557, 683, 241, -152, -1098, -686, +-1306, -439, -394, -60, 510, -2, 721, 39, +342, 419, 97, 763, 86, 336, -203, -669, +-681, -1275, -706, -719, 49, 698, 973, 1492, +1065, 789, 117, -468, -1070, -1165, -1044, -685, +-51, 99, 848, 543, 740, 335, -100, 170, +-647, 196, -233, 137, 393, -257, 428, -721, +-120, -625, -650, 118, -476, 946, 322, 885, +917, 57, 497, -719, -343, -792, -752, -345, +-564, 228, 67, 564, 623, 506, 497, 154, +3, -287, -279, -430, -253, -204, -33, 90, +123, 82, -119, -19, -168, -50, 21, 239, +356, 444, 308, 232, 88, -450, -328, -798, +-509, -415, -75, 297, 234, 733, 175, 652, +31, 132, 172, -301, 224, -609, 106, -708, +-290, -453, -704, 335, -518, 1075, 332, 1098, +1085, 260, 885, -882, -284, -1469, -1204, -1073, +-931, 174, 185, 1398, 1025, 1821, 730, 808, +-144, -980, -820, -2189, -421, -1637, 470, 332, +736, 2050, 9, 1958, -855, 183, -871, -1422, +154, -1503, 1247, -351, 1185, 427, -191, 441, +-1362, 227, -1239, 585, -31, 810, 1013, 2, +1057, -1310, 322, -1595, -398, -213, -630, 1518, +-485, 1702, -132, 186, 125, -1248, 304, -1094, +392, 92, 252, 658, -71, 158, -202, -425, +-68, -128, -253, 680, -520, 655, -226, -224, +473, -1007, 1061, -710, 678, 313, -366, 927, +-1228, 471, -898, -425, 54, -557, 793, 32, +878, 552, 297, 247, -236, -440, -362, -884, +-359, -305, -368, 762, -256, 1217, 41, 620, +505, -653, 803, -1463, 645, -1085, -205, 273, +-1085, 1433, -1287, 1351, -419, 187, 1052, -984, +1673, -1292, 820, -511, -712, 320, -1461, 734, +-850, 671, 267, 441, 822, -71, 436, -717, +26, -928, 141, -318, 155, 665, -240, 925, +-843, 250, -637, -555, 342, -484, 1101, 140, +707, 499, -397, -34, -871, -785, -338, -559, +342, 604, 426, 1232, -76, 518, -357, -827, +-112, -1282, 377, -478, 470, 772, 12, 1046, +-442, 243, -424, -602, -128, -571, 187, 77, +319, 416, 291, 158, 194, -322, -158, -358, +-370, -40, -358, 337, -58, 460, 287, 301, +365, -143, 91, -616, -241, -734, -138, -222, +130, 735, 207, 1112, -67, 437, -397, -658, +-451, -1093, 68, -475, 722, 415, 772, 749, +43, 232, -738, -265, -918, -120, -286, 302, +434, 212, 733, -450, 488, -919, 58, -462, +-249, 750, -238, 1433, -431, 877, -672, -631, +-284, -1688, 654, -1396, 1359, 283, 907, 1708, +-329, 1627, -1592, 76, -1582, -1394, -237, -1530, +1334, -298, 1852, 996, 832, 1075, -736, 186, +-1573, -596, -1111, -410, 86, 194, 945, 289, +859, -277, 226, -607, -147, -102, -91, 683, +-154, 861, -459, 143, -706, -757, -376, -963, +535, -241, 1408, 558, 1060, 847, -314, 388, +-1578, -288, -1484, -641, -186, -417, 1228, 93, +1495, 351, 609, 360, -532, 14, -1083, -231, +-792, -129, -115, 103, 485, 68, 658, -218, +410, -258, 102, 58, -225, 545, -343, 471, +-411, -212, -274, -911, 25, -584, 489, 414, +615, 1133, 259, 654, -377, -605, -720, -1348, +-340, -586, 389, 828, 578, 1417, -38, 427, +-479, -1093, -184, -1367, 493, -87, 634, 1346, +-80, 1144, -912, -339, -811, -1475, 174, -881, +1066, 753, 844, 1573, -105, 553, -754, -1083, +-655, -1483, -161, -292, 196, 1144, 333, 1276, +422, 141, 346, -963, 145, -1005, -469, -131, +-828, 666, -477, 731, 391, 125, 839, -459, +594, -451, 12, 24, -485, 364, -692, 238, +-419, -346, 50, -518, 601, 10, 786, 747, +292, 743, -453, -166, -858, -1120, -502, -1019, +311, 283, 878, 1384, 478, 1107, -381, -384, +-718, -1366, -244, -988, 473, 364, 656, 1147, +8, 727, -706, -275, -669, -775, 235, -557, +904, 85, 617, 563, -288, 532, -904, 61, +-578, -554, 245, -655, 729, -80, 450, 661, +-214, 777, -450, 26, -75, -742, 271, -771, +94, -3, -428, 702, -401, 577, 287, -27, +824, -364, 562, -231, -477, -121, -1096, -106, +-595, -50, 538, 306, 1069, 513, 439, 220, +-465, -456, -776, -696, -274, -232, 464, 447, +497, 573, -9, 213, -456, -276, -296, -376, +132, -148, 458, -25, 458, 126, 18, 241, +-665, 315, -764, -19, -131, -499, 696, -476, +903, 192, 503, 770, -452, 390, -1130, -576, +-744, -881, 272, -40, 988, 927, 740, 820, +1, -433, -647, -1239, -583, -563, 1, 891, +273, 1369, 148, 260, -123, -1218, 3, -1438, +318, 34, 365, 1431, -76, 1297, -558, -235, +-672, -1393, -31, -1032, 724, 286, 750, 1197, +-1, 692, -534, -382, -365, -802, 30, -241, +97, 380, -148, 298, -152, -237, 363, -274, +742, 260, 226, 535, -730, -59, -951, -695, +-202, -493, 759, 444, 823, 929, 20, 196, +-472, -854, -275, -921, 82, 186, 25, 1058, +-135, 745, -144, -335, 223, -1046, 531, -613, +65, 287, -518, 674, -337, 465, 327, 94, +435, -51, -172, -328, -748, -693, -321, -632, +863, 184, 1242, 1217, 9, 1202, -1345, -36, +-1338, -1377, 40, -1523, 1422, -247, 1339, 1260, +-70, 1522, -1224, 436, -890, -907, 142, -1202, +656, -510, 332, 489, -168, 773, -178, 370, +166, -191, 303, -387, 17, -145, -436, 143, +-542, 221, -104, -103, 470, -356, 673, -179, +308, 184, -154, 490, -590, 363, -569, -60, +-119, -467, 301, -555, 447, -293, 434, 174, +210, 645, -201, 708, -464, 197, -497, -479, +-371, -847, 174, -665, 793, 8, 834, 720, +216, 1032, -613, 560, -1208, -351, -681, -1135, +557, -1066, 1184, -85, 675, 956, -227, 1250, +-766, 426, -573, -601, 36, -971, 346, -560, +188, 94, -29, 431, 16, 423, 258, 294, +312, 192, -231, -16, -733, -503, -507, -802, +364, -374, 847, 438, 641, 1107, -228, 820, +-861, -222, -645, -1229, 231, -1117, 737, 31, +448, 1115, -199, 1155, -563, 108, -284, -914, +328, -974, 440, -97, 55, 579, -293, 571, +-268, 145, -32, -209, 105, -244, 148, -181, +159, -166, 181, 21, 18, 317, -318, 482, +-489, 76, -212, -595, 401, -706, 797, 58, +311, 888, -438, 702, -686, -343, -238, -955, +183, -480, 310, 499, 128, 796, 119, 132, +297, -527, 131, -353, -503, 270, -906, 306, +-270, -228, 771, -543, 1168, -16, 432, 729, +-789, 694, -1204, -257, -356, -1005, 675, -686, +851, 324, 160, 921, -377, 656, -332, -131, +56, -663, 134, -617, -129, -175, -228, 356, +34, 573, 348, 326, 320, -126, -26, -356, +-305, -270, -266, -86, -50, -1, 51, 59, +125, 226, 205, 363, 155, 195, 47, -301, +-136, -603, -281, -338, -299, 223, -50, 606, +368, 404, 538, -112, 220, -399, -436, -330, +-616, -66, -129, 85, 383, 186, 456, 250, +-26, 145, -259, -140, -149, -314, 178, -155, +212, 179, -127, 214, -429, -59, -151, -268, +472, -47, 498, 359, -24, 422, -486, -162, +-371, -658, 81, -483, 353, 248, 178, 693, +-75, 444, -53, -129, 51, -420, -133, -315, +-278, -202, -22, -126, 431, 159, 452, 681, +-112, 661, -628, -65, -521, -1005, 192, -1043, +814, -18, 559, 1104, -312, 1181, -794, 90, +-485, -995, 215, -1040, 551, -76, 491, 738, +87, 685, -289, -15, -546, -453, -338, -283, +140, 143, 531, 279, 406, -53, -57, -340, +-401, -149, -250, 284, 117, 419, 165, 48, +-115, -437, -152, -314, 199, 192, 457, 454, +161, -3, -515, -564, -706, -374, -20, 429, +802, 927, 693, 287, -244, -824, -860, -1156, +-423, -168, 440, 961, 693, 1055, 132, 87, +-460, -783, -356, -648, 43, 46, 219, 327, +61, -17, -39, -192, 162, 231, 150, 647, +-147, 324, -457, -573, -90, -1024, 328, -452, +308, 546, -18, 957, -208, 536, 24, -124, +216, -497, -67, -579, -576, -492, -399, -141, +456, 500, 1035, 1011, 513, 709, -719, -326, +-1260, -1196, -446, -979, 734, 53, 963, 929, +275, 930, -316, 290, -358, -399, -161, -693, +-228, -540, -327, -93, 37, 356, 727, 571, +848, 366, 78, -94, -877, -374, -1089, -343, +-244, -98, 768, 72, 1038, 141, 340, 168, +-406, 170, -750, 75, -465, -112, 85, -268, +504, -205, 366, 13, 51, 200, -210, 207, +-177, 112, 45, -58, 76, -155, -203, -208, +-263, -83, 152, 148, 532, 311, 422, 129, +-231, -279, -802, -444, -443, -40, 465, 556, +770, 549, 234, -166, -447, -817, -546, -555, +-71, 362, 444, 892, 275, 412, -164, -425, +-202, -668, 39, -156, 169, 295, -64, 182, +-223, -143, 2, -37, 428, 371, 274, 385, +-393, -250, -557, -771, -49, -477, 542, 383, +552, 830, -59, 426, -484, -320, -417, -590, +108, -241, 291, 94, 120, 100, -21, 13, +50, 197, 244, 404, -61, 191, -598, -406, +-565, -738, 304, -347, 1013, 452, 625, 823, +-413, 436, -1143, -297, -671, -702, 467, -516, +998, 36, 507, 506, -303, 534, -594, 211, +-340, -258, -35, -534, 85, -430, 148, 51, +423, 552, 460, 587, -138, 27, -761, -564, +-766, -591, 77, -75, 882, 485, 862, 542, +-22, 165, -874, -311, -754, -530, -29, -290, +556, 159, 460, 503, 125, 417, -84, -43, +-229, -434, -330, -457, -261, -57, 51, 345, +396, 333, 476, 82, 90, -139, -483, -119, +-503, -60, -45, -116, 375, -131, 381, 25, +29, 315, -302, 352, -229, -13, 140, -374, +118, -406, -16, -92, -7, 257, 39, 383, +-28, 222, -97, -78, -57, -294, 103, -276, +320, -110, 79, 86, -391, 284, -357, 299, +136, 104, 442, -235, 263, -426, -144, -228, +-359, 205, -111, 422, 277, 247, 158, -176, +-196, -286, -222, -144, 183, 56, 506, 121, +146, 64, -459, 70, -639, -16, -37, -74, +665, -81, 701, -14, -36, 81, -695, 65, +-590, 11, 106, -61, 610, -133, 512, -10, +-73, 138, -546, 232, -404, 48, 156, -267, +519, -354, 291, -86, -213, 401, -507, 452, +-137, -11, 406, -406, 464, -327, -52, 88, +-543, 205, -461, 62, 202, -77, 812, 81, +483, 260, -502, 62, -975, -396, -433, -535, +601, -77, 1072, 571, 424, 714, -697, 147, +-1000, -562, -288, -774, 479, -264, 676, 353, +231, 672, -264, 437, -308, 0, -15, -436, +-69, -653, -253, -480, -129, 187, 286, 939, +526, 862, 309, -91, -330, -1079, -743, -1014, +-465, 17, 192, 1008, 586, 980, 485, 97, +73, -763, -361, -838, -518, -273, -354, 447, +30, 710, 418, 407, 554, -199, 145, -581, +-409, -420, -629, 22, -210, 382, 443, 378, +579, 115, -1, -183, -565, -343, -419, -203, +250, 40, 613, 231, 292, 332, -385, 173, +-709, -219, -282, -606, 438, -345, 732, 399, +366, 864, -356, 391, -731, -616, -389, -1044, +291, -302, 616, 770, 329, 975, -178, 114, +-383, -694, -123, -615, 166, 32, 156, 389, +-115, 114, -190, -105, 141, 66, 442, 338, +258, 99, -298, -494, -618, -593, -228, 29, +415, 708, 712, 584, 264, -190, -446, -666, +-591, -375, -35, 340, 431, 583, 270, 40, +-126, -560, -119, -435, 107, 343, 168, 736, +3, 201, -286, -547, -244, -655, 166, -98, +565, 400, 272, 472, -297, 211, -613, -126, +-228, -340, 450, -316, 671, -57, 151, 222, +-549, 326, -636, 37, -14, -242, 627, -118, +630, 252, -55, 286, -714, -199, -640, -648, +43, -388, 744, 446, 735, 1030, 36, 586, +-796, -572, -877, -1275, -117, -853, 766, 495, +864, 1440, 133, 1028, -600, -411, -713, -1429, +-265, -941, 228, 409, 393, 1075, 339, 513, +144, -316, -94, -326, -417, -7, -616, -154, +-266, -430, 397, -99, 804, 677, 460, 786, +-339, -70, -908, -924, -733, -772, 166, 212, +900, 894, 741, 635, -171, -215, -845, -785, +-619, -570, 140, 206, 524, 703, 303, 476, +-87, -176, -210, -548, -116, -363, -109, 78, +-148, 302, 42, 267, 326, 151, 230, -59, +-159, -304, -387, -370, -191, -37, 195, 342, +387, 419, 76, 40, -356, -330, -269, -345, +193, 38, 425, 275, 104, 146, -373, -121, +-479, -169, 37, -48, 600, 76, 588, 160, +-97, 226, -719, 4, -523, -463, 187, -557, +537, 122, 472, 867, 219, 658, -178, -276, +-665, -924, -508, -671, 244, 128, 788, 742, +540, 791, -156, 187, -606, -648, -336, -908, +255, -356, 378, 625, -2, 882, -246, 211, +90, -546, 436, -535, 197, 1, -373, 261, +-497, 190, -129, 92, 349, -151, 628, -283, +381, 74, -288, 492, -737, 154, -278, -619, +307, -530, 478, 299, 302, 793, -21, 318, +-396, -508, -329, -755, 126, -166, 318, 606, +91, 635, -134, -56, -118, -524, 29, -317, +119, 85, 80, 194, -202, 161, -222, 91, +101, -49, 408, -89, 40, -25, -493, -112, +-325, -235, 347, 62, 479, 519, -24, 307, +-469, -369, -468, -570, 85, -45, 572, 477, +322, 292, -363, -233, -524, -375, -125, 99, +261, 438, 316, 151, 17, -416, -364, -480, +-256, -3, 202, 498, 305, 520, -90, 10, +-438, -512, -267, -498, 228, -4, 552, 391, +196, 348, -517, 75, -703, -155, -98, -274, +631, -151, 580, 95, -100, 163, -573, 6, +-438, -53, 98, 85, 390, 121, 277, -65, +-194, -216, -370, -161, -14, 72, 403, 273, +197, 207, -378, -80, -585, -338, 29, -237, +721, 198, 624, 472, -219, 171, -817, -504, +-579, -683, 209, 103, 857, 984, 621, 733, +-218, -505, -738, -1315, -486, -606, 169, 779, +656, 1341, 476, 476, -270, -834, -551, -1123, +-17, -271, 406, 626, 155, 731, -231, 110, +-168, -364, 149, -258, 421, 127, 122, 99, +-393, -290, -454, -284, 148, 200, 694, 557, +360, 354, -303, -288, -624, -686, -209, -361, +386, 367, 674, 607, 263, 162, -489, -305, +-657, -356, -4, -59, 583, 198, 506, 224, +-76, 1, -513, -157, -414, -174, 249, -38, +644, 136, 148, 176, -443, 150, -318, 39, +75, -277, 165, -472, 125, -153, 107, 521, +31, 708, -119, 104, -214, -627, -218, -742, +101, -54, 341, 694, 203, 565, -218, -122, +-283, -553, 9, -240, 148, 286, -82, 320, +-179, -132, -7, -399, 173, -20, 256, 424, +140, 271, -370, -191, -636, -424, -114, -177, +528, 295, 455, 374, -10, -56, -358, -425, +-270, -92, 45, 445, -28, 316, -282, -361, +-67, -625, 552, -29, 541, 672, -221, 558, +-759, -235, -584, -731, 116, -396, 683, 368, +517, 663, -132, 178, -585, -404, -300, -492, +217, -64, 224, 431, -177, 437, -225, -168, +153, -563, 297, -124, 180, 515, -117, 280, +-460, -336, -452, -353, 185, 176, 625, 424, +333, 36, -253, -427, -389, -383, -106, 154, +146, 550, 39, 377, -91, -249, 146, -663, +276, -305, 32, 377, -225, 554, -296, 44, +-100, -346, 398, -202, 407, 145, -81, 308, +-388, -85, -214, -566, 54, -358, 479, 527, +473, 997, -325, 235, -721, -863, 12, -1005, +510, -203, 292, 710, 18, 914, -182, 387, +-193, -452, 8, -887, 151, -359, -19, 356, +60, 530, 41, 109, -12, -187, 122, -114, +96, 103, -100, 233, -184, -76, -173, -527, +-14, -446, 460, 323, 554, 867, -270, 448, +-606, -442, -203, -769, 85, -391, 355, 314, +459, 569, -4, 234, -515, -349, -253, -273, +167, 416, 243, 416, 128, -517, -180, -992, +-311, 3, 131, 1181, 336, 857, 137, -474, +-211, -1106, -423, -397, -220, 592, 367, 676, +435, -24, -117, -565, -126, -324, -70, 433, +-326, 692, -123, -62, 332, -956, 235, -583, +-66, 633, -89, 1004, -235, -40, -128, -833, +286, -270, 112, 580, -311, 430, -236, -606, +169, -809, 390, 304, 163, 1194, -323, 557, +-528, -901, -137, -1167, 260, 13, 412, 949, +314, 619, -243, -444, -514, -693, -90, 217, +174, 771, -51, -14, 42, -990, 264, -599, +135, 729, -53, 1196, -309, 224, -406, -1133, +92, -1087, 481, 423, 80, 1355, -271, 299, +15, -1178, 188, -891, 75, 837, -164, 1454, +-498, -57, -210, -1727, 557, -1088, 710, 1134, +35, 1874, -499, 146, -584, -1669, -123, -1215, +409, 734, 432, 1523, -28, 165, -200, -1226, +72, -809, 188, 719, -73, 1211, -495, 98, +-317, -1209, 441, -1032, 691, 534, 125, 1442, +-329, 430, -347, -993, -173, -958, 69, 229, +171, 896, 15, 239, 132, -659, 354, -541, +96, 454, -337, 800, -520, -5, -138, -753, +354, -559, 497, 346, 130, 620, -261, 40, +-210, -385, 71, -37, 142, 495, -178, 169, +-370, -652, 46, -930, 515, -21, 459, 1378, +70, 1381, -469, -411, -724, -1910, -276, -1305, +566, 768, 623, 1942, 197, 967, -142, -1008, +-337, -1650, -375, -273, -107, 1087, 122, 859, +226, -318, 268, -823, 73, -112, -120, 682, +-114, 429, -199, -550, -249, -734, 112, 246, +317, 865, 119, 288, -45, -809, -147, -883, +-139, 405, 175, 1323, 168, 498, -423, -1199, +-438, -1479, 335, 275, 652, 1661, 144, 976, +-250, -910, -417, -1456, -369, -114, -66, 1014, +336, 622, 447, -460, 277, -637, -171, 268, +-442, 695, -313, 24, -98, -908, 134, -683, +495, 588, 353, 1242, -217, 445, -425, -1058, +-204, -1301, 82, 43, 178, 1323, 140, 896, +-162, -591, -14, -1159, 307, -125, 86, 817, +-385, 477, -331, -503, 80, -490, 318, 243, +267, 522, 118, 137, -315, -501, -469, -651, +39, 9, 562, 951, 234, 913, -482, -484, +-401, -1449, 207, -734, 422, 1008, 272, 1569, +-155, 229, -423, -1242, -358, -1133, 140, 227, +416, 976, 242, 407, 135, -400, -136, -301, +-461, 281, -430, 288, 165, -520, 596, -684, +313, 137, -77, 963, -335, 752, -278, -417, +11, -1200, 155, -575, 0, 710, 72, 1049, +295, 34, 217, -691, -401, -392, -578, 117, +-3, 304, 630, 141, 470, -3, -291, -173, +-651, -192, -179, -10, 570, 177, 601, 371, +-340, 104, -811, -503, -71, -557, 807, 145, +394, 854, -550, 330, -603, -700, 232, -724, +791, 401, 248, 1145, -903, -45, -973, -1543, +460, -932, 1532, 1418, 608, 2291, -1240, 26, +-1479, -2761, 12, -2237, 1442, 1347, 967, 3367, +-447, 1125, -1180, -2340, -427, -2660, 768, 142, +771, 2301, -313, 1489, -926, -1005, 14, -1895, +883, -86, 403, 1622, -489, 816, -583, -1157, +-240, -1345, 160, 465, 568, 1430, 527, 349, +-153, -1054, -571, -711, -463, 660, -175, 634, +435, -525, 788, -1013, 327, 410, -557, 1799, +-942, 566, -360, -2006, 734, -2274, 1154, 924, +106, 3105, -1203, 1242, -978, -2229, 459, -2840, +1413, 127, 528, 2845, -989, 1695, -1341, -1567, +76, -2479, 1386, 251, 757, 2388, -750, 786, +-1024, -1999, -15, -1931, 852, 1256, 476, 2860, +-568, 570, -765, -2846, 272, -2682, 1029, 1019, +211, 3618, -1037, 1608, -912, -2378, 537, -3143, +1382, 62, 288, 2714, -1237, 1548, -1057, -1269, +538, -1880, 1347, 52, 395, 1747, -1012, 757, +-1153, -1416, 310, -1657, 1266, 392, 459, 2188, +-932, 1142, -739, -1299, 392, -2149, 773, -389, +-49, 1700, -721, 1350, -470, -547, 741, -1177, +995, -50, -244, 864, -1268, 93, -578, -897, +855, -486, 1070, 715, 41, 1059, -968, 0, +-643, -1065, 512, -651, 808, 578, -108, 890, +-819, -174, -390, -1022, 768, -380, 917, 1021, +-138, 1370, -1265, -201, -808, -1873, 772, -1330, +1371, 1018, 400, 2114, -1080, 573, -1299, -1427, +105, -1507, 1287, 230, 858, 1428, -601, 532, +-1077, -936, -235, -965, 597, 257, 677, 1127, +-18, 458, -446, -520, -232, -759, 82, -170, +171, 175, -210, -50, -104, 165, 418, 791, +571, 647, -137, -427, -1041, -1526, -617, -1026, +612, 718, 1181, 1794, 396, 959, -941, -823, +-827, -1410, 161, -493, 602, 584, 74, 678, +-336, -145, 146, -420, 502, 469, 68, 839, +-759, -76, -660, -1326, 434, -1109, 990, 390, +189, 1502, -753, 1081, -544, -284, 436, -1060, +640, -729, -148, -309, -1037, -14, -313, 571, +1129, 1289, 1350, 1038, -400, -666, -1877, -2296, +-1071, -1521, 999, 1074, 2061, 2668, 692, 1344, +-1487, -1353, -1844, -2321, -57, -795, 1726, 1334, +1138, 1509, -588, 88, -1372, -935, -378, -528, +816, 286, 841, 315, 3, -208, -764, -138, +-590, 385, 177, 245, 531, -570, 500, -633, +43, 482, -331, 1171, -654, 397, -528, -1321, +275, -1648, 1106, 174, 840, 2166, -536, 1606, +-1442, -910, -686, -2398, 658, -1133, 1328, 1207, +667, 2184, -733, 710, -1419, -1332, -358, -1636, +1098, -218, 1037, 1104, -192, 895, -1021, -103, +-644, -572, 453, -280, 969, 94, 296, 134, +-570, -13, -822, 7, -301, -66, 688, 59, +947, 206, 116, 208, -886, -109, -896, -642, +-68, -515, 1097, 413, 1154, 1218, -333, 627, +-1501, -953, -892, -1623, 626, -442, 1356, 1468, +875, 1864, -511, 81, -1381, -2012, -914, -1881, +341, 502, 1192, 2413, 1071, 1555, 70, -1124, +-1137, -2270, -1304, -939, -322, 1132, 1011, 1578, +1544, 601, 634, -433, -1097, -792, -1761, -698, +-580, -555, 1092, -34, 1752, 1110, 672, 1716, +-1111, 517, -1584, -1650, -535, -2506, 642, -661, +1099, 1893, 980, 2662, 171, 768, -992, -1719, +-1428, -2324, -937, -806, 687, 1135, 2231, 1600, +1609, 750, -934, -195, -2709, -719, -1528, -826, +1117, -703, 2660, 76, 1241, 954, -1601, 1129, +-2201, 152, -162, -997, 1741, -914, 1254, 54, +-691, 730, -1562, 308, -605, -332, 1197, -471, +1420, 206, 140, 775, -1159, 530, -1163, -649, +-112, -1301, 699, -643, 767, 851, 554, 1617, +54, 726, -746, -796, -1149, -1588, -224, -764, +933, 759, 1037, 1344, -28, 389, -951, -898, +-609, -852, 690, 459, 1048, 1126, -304, 196, +-1608, -1360, -889, -1463, 1292, 415, 2259, 2075, +507, 1548, -1987, -648, -2320, -2253, -43, -1604, +2180, 563, 1812, 2110, -575, 1453, -1945, -546, +-759, -1539, 1152, -918, 1331, 307, -298, 910, +-1620, 479, -894, -336, 1148, -558, 2106, 12, +646, 701, -1869, 376, -2406, -569, -272, -1106, +2212, -248, 2276, 1120, -194, 1265, -2363, -93, +-1722, -1462, 992, -1025, 2445, 809, 555, 1626, +-2161, 120, -2098, -1875, 1009, -1305, 3076, 1359, +1158, 2647, -2243, 636, -3058, -2630, -281, -3079, +2671, -33, 2437, 3427, -443, 3309, -2406, -440, +-1133, -3784, 930, -3142, 1113, 778, -114, 3634, +-687, 2550, 198, -859, 918, -2960, 215, -1976, +-1265, 730, -1228, 2278, 574, 1476, 1730, -575, +881, -1778, -997, -1100, -1598, 510, -465, 1523, +1078, 881, 1170, -716, 233, -1423, -564, -556, +-777, 939, -579, 1302, -184, 156, 741, -1010, +1332, -969, 847, 138, -930, 786, -2288, 499, +-1220, -81, 1551, -275, 2789, -241, 957, -325, +-1877, -183, -2634, 360, -598, 822, 2095, 353, +2105, -687, -245, -1123, -1942, -313, -1096, 945, +945, 1327, 1563, 208, 156, -1151, -1578, -1411, +-1186, -105, 908, 1235, 1813, 1391, 546, 156, +-1445, -1169, -1636, -1473, -106, -314, 1447, 1099, +1388, 1547, 13, 448, -1348, -918, -1181, -1441, +-7, -703, 1072, 444, 1058, 1351, 209, 1192, +-920, 69, -1184, -1344, -259, -1700, 916, -426, +1126, 1296, 310, 1956, -979, 685, -1179, -1062, +-87, -1912, 1136, -937, 922, 674, -342, 1743, +-1076, 1091, -554, -384, 727, -1354, 926, -904, +-56, 16, -851, 623, -524, 697, 364, 600, +714, 45, 243, -805, -496, -1020, -616, -341, +30, 868, 557, 1122, 401, 565, -114, -808, +-547, -1275, -429, -580, 22, 800, 671, 1156, +860, 530, -76, -361, -1223, -905, -1121, -974, +381, -352, 1590, 1060, 1198, 1816, -580, 844, +-1921, -1481, -1182, -2634, 1096, -1022, 1979, 1897, +562, 3058, -1285, 1093, -1557, -2121, -67, -3124, +1363, -955, 1113, 2075, -560, 2588, -1327, 571, +-170, -1397, 866, -1491, 673, -505, -338, 291, +-763, 416, -91, 721, 766, 834, 386, 369, +-717, -1030, -786, -1716, 475, -605, 1191, 1243, +353, 1879, -1264, 465, -1387, -966, 495, -1291, +1943, -479, 940, 205, -1355, 497, -2075, 631, +-418, 753, 1938, 366, 2180, -847, -170, -1797, +-2378, -1076, -1940, 1220, 485, 2547, 2398, 1322, +1801, -1342, -509, -2681, -2219, -1467, -1708, 1143, +384, 2454, 1897, 1440, 1551, -757, -259, -1841, +-1524, -1251, -1170, 182, 208, 1034, 1060, 1105, +610, 297, -340, -379, -545, -701, 109, -486, +507, -223, -80, 0, -770, 549, -543, 813, +614, 607, 1172, -351, 359, -1280, -886, -1113, +-1166, 122, -277, 1482, 784, 1361, 969, 4, +443, -1206, -311, -1254, -871, -205, -1127, 611, +-392, 807, 1405, 481, 2149, 179, 585, -310, +-2202, -749, -2926, -730, -568, -11, 2867, 598, +3463, 743, 239, 423, -3336, 74, -3177, -428, +306, -906, 2920, -1007, 2222, -129, -564, 1321, +-1905, 1910, -933, 773, 588, -1482, 520, -2513, +-240, -1293, -301, 1215, 333, 2492, 972, 1638, +596, -306, -674, -1865, -1538, -1990, -1096, -1061, +415, 764, 1769, 2463, 1989, 2453, 363, 280, +-2103, -2639, -3050, -3400, -970, -1166, 2446, 2137, +3873, 3864, 1244, 2082, -2820, -1509, -4118, -3757, +-1067, -2534, 2946, 838, 3740, 2986, 724, 2358, +-2657, 55, -3063, -1860, -447, -1986, 2150, -750, +2252, 759, 342, 1664, -1402, 1124, -1465, -227, +-567, -1458, 455, -1212, 1055, 403, 1240, 1630, +311, 964, -1104, -1060, -1958, -2194, -867, -807, +1370, 2002, 2742, 3156, 1280, 815, -1834, -2968, +-3456, -3929, -1467, -940, 2087, 3115, 3929, 4257, +1830, 1501, -2083, -2397, -4155, -4069, -2319, -2223, +1607, 1045, 4115, 3105, 3005, 2887, -776, 799, +-3807, -1703, -3603, -3350, -316, -2644, 3184, 289, +3978, 3580, 1418, 3962, -2356, 661, -3946, -3531, +-2272, -4361, 1348, -1015, 3493, 3171, 2685, 4080, +-330, 884, -2562, -2777, -2728, -3472, -841, -542, +1467, 2636, 2704, 2954, 1884, 138, -484, -2664, +-2683, -2556, -2770, -40, -275, 2372, 2713, 2492, +3408, 564, 806, -1682, -2757, -2588, -3756, -1554, +-1086, 646, 2480, 2447, 3688, 2447, 1500, 673, +-1931, -1634, -3396, -2852, -1679, -2026, 1087, 147, +2462, 2444, 1784, 3091, 195, 1558, -1322, -1229, +-1850, -3408, -1374, -3018, 90, -347, 1781, 2698, +2277, 3808, 780, 1897, -1533, -1391, -2567, -3629, +-1281, -2924, 1232, -107, 2379, 2695, 1159, 3287, +-884, 1190, -1647, -1648, -788, -2922, 387, -1556, +849, 908, 449, 2288, 164, 1224, 22, -803, +-590, -1731, -1109, -541, -339, 1083, 1248, 1622, +1954, 179, 393, -1632, -2091, -1832, -2687, -176, +-285, 1757, 2687, 1894, 2874, 609, 361, -903, +-2327, -1467, -2589, -1381, -955, -775, 1112, 400, +1965, 2055, 1709, 2811, 724, 1107, -904, -2243, +-2521, -4424, -2652, -2743, -251, 1790, 3044, 5141, +4116, 3983, 1137, -933, -3079, -4817, -4515, -4186, +-1690, -10, 2660, 3343, 3895, 3326, 1505, 1005, +-1690, -1310, -2334, -2051, -954, -1497, 304, -442, +524, 422, 366, 1345, 835, 1786, 1300, 1047, +210, -815, -1842, -2384, -2717, -2005, -571, -43, +2637, 2116, 3524, 2619, 545, 1167, -3044, -1516, +-3422, -3084, -390, -1963, 2687, 1002, 2754, 2970, +335, 2138, -1807, -425, -1522, -2188, -330, -1785, +222, -193, 141, 816, 572, 945, 1333, 922, +1097, 818, -587, 25, -2473, -1463, -2196, -2125, +498, -1028, 2833, 1411, 2588, 2930, -33, 1878, +-2233, -935, -2330, -2835, -747, -2277, 1112, 100, +1623, 1833, 1160, 1934, 229, 966, -613, -189, +-1125, -1082, -1141, -1827, -370, -1575, 648, 58, +1267, 2223, 874, 2670, 33, 710, -434, -1861, +-555, -2577, -826, -1132, -1016, 814, -342, 1512, +1268, 915, 2504, 449, 1731, 390, -1230, -239, +-3757, -1701, -2977, -2278, 928, -550, 4228, 2350, +3605, 3603, -437, 1234, -3889, -2437, -3406, -3888, +99, -1460, 2794, 1996, 2261, 3009, 229, 1217, +-1179, -1148, -902, -1585, -359, -375, -414, 368, +-355, -248, 404, -733, 1434, 283, 1233, 2029, +-246, 1662, -1804, -871, -1720, -3012, -19, -2061, +1630, 1053, 1738, 3047, 467, 2017, -1147, -858, +-1787, -2460, -687, -1473, 981, 505, 1465, 1440, +491, 733, -888, -295, -1173, -356, 45, 186, +1291, 94, 813, -553, -961, -694, -1872, 30, +-431, 754, 1784, 798, 2333, 202, 306, -635, +-2216, -744, -2468, -133, -366, 384, 1854, 272, +2199, -111, 725, -201, -1033, 146, -1509, 523, +-1030, 463, -60, -289, 683, -1140, 1171, -1015, +762, 209, -195, 1440, -720, 1520, -574, 181, +-143, -1118, -118, -1629, -300, -858, 168, 347, +1016, 1137, 1326, 1327, 67, 774, -1436, -183, +-1961, -1370, -590, -1608, 1296, -749, 1985, 607, +848, 1644, -587, 1531, -1203, 582, -864, -742, +-284, -1763, 113, -1854, 545, -782, 915, 1399, +776, 2814, -143, 2082, -993, -643, -1063, -2907, +-53, -2623, 671, -190, 518, 2042, -165, 2305, +-19, 841, 520, -800, 413, -1404, -373, -951, +-1190, -242, -869, 337, 369, 612, 1336, 613, +1019, 307, -122, 52, -844, -148, -563, -508, +-87, -762, -47, -496, -424, 310, -33, 1043, +933, 924, 1423, -13, 478, -835, -1192, -825, +-1949, -81, -1046, 437, 653, 211, 1613, -369, +1375, -99, 509, 844, -530, 1020, -1261, -77, +-1541, -1551, -942, -1600, 487, -173, 2057, 1615, +2285, 1959, 496, 608, -1888, -1172, -2735, -1726, +-1386, -922, 1042, 345, 2354, 982, 1729, 930, +-4, 551, -1320, -81, -1537, -639, -807, -1012, +271, -779, 1042, 84, 982, 1066, 357, 1452, +-492, 468, -820, -984, -298, -1734, 241, -809, +378, 929, -24, 1761, -320, 756, -251, -950, +349, -1518, 645, -488, 317, 842, -252, 1053, +-638, 356, -731, -331, -401, -582, 443, -739, +1111, -537, 1067, 426, 85, 1402, -1071, 1322, +-1502, -238, -596, -2090, 645, -2035, 1230, 256, +779, 2467, 166, 2141, -324, -316, -684, -2107, +-949, -1676, -668, 163, 281, 1311, 1280, 898, +1380, -41, 169, -269, -1198, 14, -1364, -202, +-300, -725, 687, -586, 688, 558, 160, 1346, +-135, 557, 166, -885, 265, -1374, -254, -221, +-791, 1111, -440, 1066, 294, -145, 570, -1128, +355, -703, 116, 303, 73, 874, 23, 524, +-420, -142, -850, -439, -677, -378, 446, -290, +1372, -165, 1200, 305, -136, 804, -1333, 653, +-1360, -112, -320, -1035, 653, -1091, 1145, -127, +837, 1042, 141, 1243, -765, 278, -966, -830, +-679, -1063, 195, -249, 915, 585, 800, 592, +37, -20, -557, -296, -444, -27, -108, 262, +21, 47, 69, -337, 200, -317, 297, 123, +68, 407, -290, 113, -365, -250, -84, -239, +429, 168, 569, 446, 18, 131, -881, -496, +-813, -697, 174, -187, 1082, 699, 1049, 916, +128, 338, -1182, -644, -1474, -875, -394, -458, +1021, 225, 1525, 566, 776, 521, -599, 215, +-1464, -138, -886, -289, 354, -386, 993, -407, +593, -239, -191, 332, -450, 855, -7, 694, +334, -193, -89, -858, -663, -744, -544, -106, +372, 412, 1182, 373, 711, 265, -557, 354, +-1204, 384, -574, -312, 317, -1198, 863, -1027, +511, 305, -104, 1572, -542, 1242, -272, -182, +72, -1379, 67, -927, 117, 171, 90, 679, +15, 171, -153, -314, -11, 149, 59, 791, +137, 548, 60, -750, -181, -1480, -323, -724, +6, 766, 331, 1535, 297, 887, -28, -262, +-251, -937, -272, -868, -38, -605, 111, -56, +233, 776, 271, 1368, 3, 883, -395, -536, +-456, -1548, 19, -1262, 458, 117, 706, 1066, +90, 1085, -685, 407, -827, -213, -54, -510, +629, -664, 672, -792, 167, -358, -235, 736, +-383, 1636, -289, 1068, -266, -630, -85, -1950, +241, -1518, 725, 350, 723, 1921, -75, 1583, +-1038, -208, -1034, -1557, -198, -1235, 732, 193, +1117, 1065, 621, 669, -403, -281, -908, -600, +-435, -83, 34, 431, 56, 220, 56, -420, +252, -536, 551, 140, 722, 709, 9, 537, +-1137, -359, -1494, -942, -304, -597, 1183, 610, +1647, 1314, 797, 527, -641, -985, -1407, -1573, +-876, -434, -20, 1234, 411, 1625, 524, 382, +768, -1201, 767, -1524, 98, -407, -1112, 917, +-1669, 1266, -827, 438, 1007, -521, 1945, -881, +1246, -443, -469, 294, -1543, 515, -1369, 167, +-153, -270, 891, -135, 1136, 233, 455, 295, +-373, -74, -592, -468, -303, -478, 71, 57, +31, 592, -74, 654, -5, 35, 256, -636, +348, -665, 80, 50, -209, 593, -319, 406, +-139, -272, -26, -557, 14, -65, -8, 573, +265, 631, 485, -160, 189, -855, -392, -734, +-725, 129, -336, 862, 312, 814, 665, 107, +237, -457, -215, -717, -155, -513, 41, -84, +-21, 396, -320, 669, -273, 521, 164, 207, +563, -388, 251, -781, -303, -758, -390, -251, +118, 600, 451, 1160, -28, 943, -646, -101, +-686, -1185, 208, -1365, 1156, -423, 1080, 844, +-33, 1275, -1322, 631, -1467, -319, -405, -602, +958, -396, 1480, -186, 1064, -370, -160, -194, +-1234, 520, -1430, 1164, -477, 719, 598, -472, +1046, -1315, 816, -1087, 295, 67, -247, 993, +-675, 1067, -764, 335, -739, -308, -78, -657, +877, -653, 1411, -378, 843, 176, -435, 710, +-1373, 733, -1335, 151, -332, -516, 758, -570, +1267, -221, 829, 58, 130, 162, -511, 238, +-905, 346, -923, 170, -359, -208, 427, -509, +997, -303, 993, 198, 533, 525, -361, 226, +-1217, -300, -1525, -459, -669, -3, 1013, 466, +2174, 283, 1476, -152, -608, -396, -2101, -204, +-1702, 81, 67, 221, 1513, 188, 1328, 44, +241, 70, -630, 14, -709, -179, -303, -389, +-36, -353, 45, 119, 192, 682, 449, 882, +255, 73, -287, -1005, -412, -1280, -37, -175, +450, 1175, 213, 1248, -462, 111, -767, -1006, +84, -835, 909, 46, 821, 632, -97, 288, +-918, -340, -758, -317, 54, 237, 451, 638, +271, 197, 251, -558, 369, -788, 149, -319, +-476, 461, -926, 817, -662, 612, 448, -105, +1280, -776, 970, -792, -340, -178, -1253, 550, +-965, 696, 193, 280, 916, -237, 716, -400, +-56, -111, -486, 103, -413, -27, -77, -333, +209, -157, 238, 407, 96, 769, -71, 377, +-149, -488, -195, -959, -52, -711, 280, 205, +383, 862, 50, 973, -362, 329, -467, -505, +-252, -1154, 298, -899, 627, 264, 468, 1220, +-98, 964, -612, -267, -677, -963, -193, -548, +429, 351, 761, 586, 563, -44, -213, -523, +-798, -236, -627, 473, 88, 620, 508, 44, +498, -526, 129, -498, -286, -63, -260, 183, +-73, 178, -16, 241, -107, 311, 122, 164, +307, -294, 122, -678, -223, -463, -274, 114, +44, 806, 358, 676, 188, 111, -489, -638, +-665, -769, 161, -202, 1086, 400, 709, 563, +-527, 114, -1267, -166, -678, -174, 558, 101, +1176, 75, 554, -247, -372, -410, -680, -10, +-327, 503, -71, 538, -38, 34, 183, -498, +572, -549, 622, -56, -90, 365, -876, 287, +-824, -1, 33, 15, 746, 164, 672, -50, +5, -494, -411, -508, -160, 168, 93, 886, +-183, 701, -386, -316, -123, -1138, 515, -703, +691, 496, 207, 1135, -446, 463, -626, -542, +-325, -723, -13, -213, 245, 269, 419, 176, +479, 118, 271, 188, -268, 307, -853, -85, +-708, -705, 61, -630, 718, 228, 855, 1005, +367, 671, -361, -351, -800, -984, -513, -561, +-29, 372, 337, 781, 432, 384, 307, -360, +88, -493, -81, -121, -214, 249, -414, 127, +-413, -23, -29, 46, 455, 154, 664, -88, +403, -423, -321, -311, -637, 353, -357, 790, +-30, 451, 178, -581, 167, -1163, 191, -691, +305, 662, 432, 1586, -83, 1015, -873, -686, +-951, -1846, -36, -1219, 896, 537, 1134, 1734, +462, 1323, -647, -218, -1008, -1415, -560, -1256, +120, -15, 434, 983, 505, 857, 371, 86, +188, -470, -212, -279, -537, -24, -602, 14, +-200, -189, 302, -111, 697, 232, 513, 382, +118, 154, -313, -169, -589, -247, -626, -133, +-237, -49, 512, -23, 890, -32, 597, 126, +-170, 350, -826, 336, -714, -80, -74, -560, +450, -550, 479, -42, 237, 439, -24, 490, +-108, 206, -90, 15, -275, -113, -363, -356, +-80, -602, 348, -441, 528, 360, 288, 1116, +-154, 965, -466, -252, -323, -1386, -85, -1170, +51, 177, 218, 1228, 400, 877, 267, -151, +-36, -583, -342, -206, -538, 8, -293, -307, +290, -418, 621, 182, 400, 992, -90, 845, +-535, -372, -431, -1397, 39, -884, 445, 586, +218, 1341, -107, 588, -312, -606, -119, -981, +261, -296, 397, 467, 49, 560, -380, 145, +-450, -194, -245, -233, 240, -243, 716, -160, +497, 127, -170, 455, -615, 373, -616, -68, +-256, -519, 352, -503, 718, -125, 498, 449, +5, 643, -451, 229, -604, -315, -382, -477, +37, -270, 436, -40, 611, 144, 348, 371, +-96, 331, -474, 72, -605, -248, -447, -338, +204, -328, 809, -170, 767, 205, 1, 689, +-812, 641, -891, -148, 26, -971, 890, -845, +639, 150, -456, 995, -950, 768, -84, -227, +1044, -750, 969, -350, -461, 267, -1564, 205, +-949, -205, 872, -114, 1730, 461, 734, 586, +-901, -154, -1362, -988, -426, -769, 527, 436, +671, 1255, 246, 697, -66, -638, -2, -1132, +-49, -410, -368, 535, -448, 677, 50, 191, +557, -161, 386, -184, -80, -62, -311, -172, +-113, -300, 0, -65, -63, 444, -127, 683, +64, 154, 455, -627, 348, -802, -309, -172, +-779, 599, -277, 708, 683, 137, 796, -448, +-6, -486, -795, 40, -704, 327, 186, 73, +795, -307, 529, -167, -208, 306, -515, 484, +-366, 140, -76, -502, 152, -640, 334, -177, +414, 520, 202, 639, -315, 171, -687, -349, +-410, -435, 360, -127, 671, 88, 294, 108, +-222, 66, -366, 155, -155, 170, 33, 7, +-8, -247, -32, -267, 210, -53, 317, 131, +5, 106, -424, 33, -244, 153, 260, 250, +370, 37, -136, -476, -603, -714, -169, -90, +714, 821, 822, 966, -128, 23, -1111, -967, +-928, -894, 355, 118, 1224, 956, 756, 597, +-418, -434, -939, -815, -491, -107, 267, 760, +521, 646, 215, -361, -131, -1026, -93, -479, +55, 676, -24, 1059, -168, 271, -125, -716, +30, -797, 117, -68, 159, 536, 119, 383, +26, -203, -201, -326, -304, 97, -79, 493, +288, 212, 359, -467, -30, -690, -393, -228, +-253, 512, 227, 756, 424, 361, 128, -316, +-294, -587, -424, -414, -215, -74, 173, 160, +500, 418, 426, 466, 64, 263, -431, -244, +-768, -625, -443, -621, 450, -34, 974, 607, +583, 703, -336, 179, -851, -315, -534, -404, +236, -194, 440, -124, 57, -154, -59, 80, +303, 564, 488, 717, -151, 90, -916, -835, +-906, -1100, 232, -228, 1286, 914, 1021, 1148, +-338, 279, -1145, -768, -673, -971, 294, -201, +589, 553, 147, 606, -206, 37, 49, -249, +444, -138, 116, -45, -591, -130, -821, -106, +-6, 175, 878, 471, 833, 250, -134, -393, +-880, -837, -537, -397, 335, 708, 711, 1241, +90, 453, -590, -984, -421, -1447, 294, -425, +627, 966, 249, 1362, -369, 452, -587, -698, +-171, -1029, 321, -408, 281, 297, 43, 466, +0, 268, 35, 85, 70, 119, -127, 60, +-346, -340, -295, -680, 106, -388, 513, 423, +454, 964, 134, 602, -332, -333, -634, -949, +-525, -625, 69, 201, 694, 607, 805, 385, +204, -5, -584, -135, -800, -61, -335, -118, +137, -307, 590, -352, 566, 177, 179, 721, +-289, 686, -538, -243, -533, -1091, -137, -853, +588, 403, 867, 1379, 276, 848, -627, -661, +-961, -1495, -365, -697, 662, 824, 947, 1400, +269, 525, -563, -717, -655, -1151, -279, -480, +169, 444, 388, 764, 396, 418, 298, 4, +-78, -220, -559, -417, -743, -506, -168, -211, +648, 369, 970, 719, 378, 475, -558, -135, +-950, -647, -385, -582, 274, -137, 525, 358, +398, 409, 155, 286, -43, 156, -291, -48, +-487, -391, -402, -610, 112, -295, 647, 316, +695, 747, 38, 670, -676, -16, -681, -793, +-40, -943, 488, -211, 429, 773, 59, 987, +-233, 194, -187, -738, -52, -738, 95, 63, +45, 649, 51, 297, 3, -395, -124, -504, +-139, 101, 59, 612, 289, 368, 309, -288, +-118, -591, -596, -271, -428, 222, 219, 437, +762, 196, 368, -58, -279, -158, -631, -104, +-167, -93, 272, -61, 217, 21, -99, 74, +-164, 18, 217, 100, 423, 293, 89, 180, +-623, -374, -712, -776, 26, -342, 893, 624, +763, 1099, -142, 460, -912, -740, -588, -1190, +264, -392, 697, 711, 221, 881, -370, 150, +-327, -450, 224, -314, 465, 133, -62, 39, +-709, -318, -498, -235, 415, 370, 1022, 635, +527, 161, -656, -416, -1254, -555, -476, -261, +804, 175, 1208, 502, 372, 516, -819, 29, +-956, -683, -147, -693, 578, 175, 481, 866, +33, 444, -144, -500, -68, -688, -8, -53, +-195, 484, -289, 307, -6, -110, 418, -175, +443, 21, 109, 54, -356, -176, -615, -274, +-396, -20, 385, 422, 816, 602, 410, 178, +-373, -614, -805, -1051, -418, -465, 386, 848, +729, 1470, 293, 593, -347, -969, -546, -1531, +-294, -607, 229, 776, 617, 1268, 358, 625, +-287, -353, -711, -813, -385, -765, 312, -186, +791, 551, 447, 1021, -315, 472, -763, -674, +-474, -1120, 144, -264, 665, 855, 587, 849, +24, -121, -574, -681, -701, -416, -80, 95, +639, 366, 507, 347, -139, 77, -380, -289, +-99, -310, 120, -3, 29, 228, -78, -67, +-111, -219, 124, 215, 316, 699, 69, 152, +-336, -979, -347, -966, 89, 396, 274, 1339, +218, 557, 50, -770, -223, -961, -234, -55, +-52, 615, 246, 461, 79, -85, -141, -502, +64, -311, 263, 377, -47, 647, -465, 36, +-294, -767, 280, -588, 535, 316, 408, 875, +-258, 400, -821, -584, -517, -836, 477, -41, +882, 843, 284, 558, -312, -426, -578, -783, +-483, -168, 4, 407, 611, 436, 583, 349, +33, 91, -383, -536, -426, -839, -440, -271, +-43, 630, 629, 921, 900, 548, 148, -240, +-901, -1002, -968, -1025, -223, -41, 760, 1066, +1144, 1139, 404, 186, -893, -795, -1066, -914, +-158, -295, 575, 295, 547, 534, 376, 403, +-3, 146, -524, -168, -576, -416, -80, -360, +338, -86, 420, 250, 410, 386, -99, 281, +-583, -62, -479, -411, 74, -337, 535, 86, +459, 348, -69, 256, -501, -56, -362, -361, +186, -355, 399, 204, 71, 673, -208, 260, +-85, -582, 22, -754, 101, 3, 65, 770, +-92, 582, -265, -250, -40, -743, 363, -246, +337, 488, -57, 499, -473, -155, -470, -553, +118, -172, 648, 321, 412, 441, -322, 98, +-428, -289, -111, -322, 65, -135, 78, 108, +83, 116, 130, 197, 207, 335, -18, 19, +-416, -462, -317, -502, 226, 19, 391, 381, +100, 399, -173, 141, -268, -154, 27, -355, +324, -171, 132, 83, -396, 25, -339, -49, +157, 220, 454, 495, 280, 50, -101, -731, +-404, -657, -419, 334, 111, 888, 449, 228, +322, -547, -172, -487, -350, 123, -38, 379, +262, 151, 153, -197, -299, -300, -357, -4, +185, 357, 601, 196, 178, -268, -474, -403, +-444, 106, 74, 496, 297, 199, 184, -361, +-45, -532, -150, -94, -53, 457, 79, 617, +57, 124, -82, -575, -98, -624, -31, -9, +60, 480, 125, 338, 59, -5, -111, -70, +-114, -71, 106, -48, 139, -193, -311, -241, +-346, -98, 332, 403, 684, 683, -41, 208, +-600, -657, -296, -825, 90, -56, 194, 598, +340, 448, 110, -49, -242, -116, -176, 16, +53, -61, -1, -300, -55, -339, 0, 92, +86, 547, 288, 500, 136, -92, -429, -556, +-479, -439, 249, 50, 566, 468, 126, 257, +-250, -228, -389, -324, -193, 274, 281, 497, +548, -202, 60, -814, -505, -267, -355, 748, +187, 699, 400, -241, 0, -616, -282, -225, +-3, 248, 203, 270, 111, 173, -141, -190, +-220, -396, -245, -17, -48, 369, 429, 270, +577, -42, 175, -120, -721, -264, -967, -430, +-151, -3, 860, 621, 966, 625, 185, -31, +-655, -538, -984, -586, -359, -389, 621, 271, +821, 894, 160, 684, -446, -390, -410, -911, +148, -303, 225, 196, -174, 236, -438, 228, +215, 323, 689, 175, 304, -310, -407, -564, +-780, -490, -211, 247, 738, 912, 663, 622, +-358, -534, -651, -1049, 72, -226, 488, 710, +175, 654, -149, -94, -370, -484, -220, -317, +266, 42, 496, 325, 83, 219, -355, -210, +-255, -141, 71, 335, 179, 135, -137, -692, +-131, -586, 348, 684, 271, 1265, -261, -4, +-404, -1292, -142, -897, 203, 579, 370, 1050, +61, 230, -386, -491, -111, -452, 350, -7, +18, 250, -510, 134, -204, -209, 433, -227, +621, 305, 17, 514, -753, -93, -659, -764, +266, -422, 764, 621, 431, 813, -186, -161, +-648, -883, -417, -328, 264, 690, 349, 684, +93, -189, 210, -871, 101, -450, -505, 619, +-325, 883, 295, 15, 247, -848, -5, -504, +104, 458, -63, 583, -190, -132, 124, -535, +246, 81, -85, 600, -382, 63, -148, -687, +343, -450, 575, 430, 104, 734, -482, 172, +-433, -571, -83, -681, 239, 56, 329, 852, +113, 425, -66, -686, 125, -841, -92, 426, +-680, 1167, -316, 42, 473, -1276, 687, -760, +333, 992, -354, 1376, -867, -226, -452, -1512, +504, -691, 600, 1084, 112, 1237, -168, -238, +-348, -1273, -132, -550, 154, 830, -210, 1003, +-278, -183, 449, -1133, 812, -435, -137, 1007, +-959, 1071, -659, -547, 273, -1613, 1012, -438, +644, 1605, -511, 1611, -953, -619, -167, -2151, +639, -878, 464, 1542, -256, 1858, -498, -251, +214, -1812, 715, -868, 58, 1183, -771, 1446, +-583, -338, 362, -1680, 999, -694, 514, 1426, +-720, 1735, -1059, -386, 86, -2086, 979, -1002, +517, 1413, -340, 1797, -716, -178, -358, -1716, +533, -834, 791, 1160, -84, 1341, -740, -346, +-201, -1526, 295, -567, 159, 1196, -108, 1279, +-7, -386, 157, -1421, 73, -360, -174, 1095, +-392, 731, -211, -755, 334, -1019, 527, 379, +-78, 1349, -603, 499, -201, -1254, 381, -1438, +217, 261, -303, 1632, -333, 917, 63, -839, +409, -1336, 375, -187, -211, 1104, -694, 712, +-498, -774, 485, -1041, 1075, 417, 256, 1485, +-966, 291, -901, -1536, 384, -1294, 947, 825, +316, 1788, -437, 331, -588, -1464, 11, -1121, +631, 542, 304, 1378, -499, 406, -464, -1115, +420, -1152, 654, 371, 139, 1519, -638, 524, +-655, -1250, 234, -1183, 951, 516, 398, 1543, +-698, 116, -696, -1495, 319, -925, 750, 1213, +-92, 1796, -842, -353, -97, -2016, 809, -1127, +457, 1295, -430, 1953, -766, 121, -233, -1533, +446, -1184, 632, 615, -118, 1308, -724, 85, +-8, -1145, 698, -588, 97, 1088, -935, 1206, +-781, -632, 671, -1756, 1366, -391, 294, 1661, +-1329, 1297, -1343, -925, 431, -1633, 1530, 172, +542, 1587, -1178, 422, -1050, -1400, 607, -1094, +1187, 804, 37, 1620, -1021, 211, -583, -1367, +510, -1113, 882, 658, 103, 1245, -811, -123, +-204, -1215, 889, -89, 378, 1532, -928, 766, +-900, -1634, 558, -2029, 1414, 620, 708, 2702, +-941, 1274, -1689, -1892, -26, -2649, 1645, 142, +1013, 2673, -967, 1466, -1339, -1853, 216, -2453, +1487, 616, 785, 2837, -1214, 1073, -1731, -2271, +37, -2667, 1802, 360, 1291, 2970, -587, 1896, +-1677, -1525, -751, -2801, 645, -442, 1003, 1983, +227, 1356, -414, -800, -410, -1024, -219, 389, +135, 632, 142, -578, -101, -927, 47, 463, +104, 1464, -294, 497, -478, -1409, 292, -1845, +932, 321, 127, 2432, -1030, 1551, -1049, -1638, +299, -2719, 1303, -275, 764, 2246, -437, 1743, +-1141, -705, -541, -1747, 607, -437, 896, 1183, +-62, 612, -596, -1075, 75, -1058, 516, 1090, +118, 2166, -386, 128, -601, -2638, -22, -2137, +1020, 1165, 821, 3139, -659, 1158, -1204, -2040, +90, -2558, 1124, 73, 771, 2400, -675, 1410, +-1421, -1489, -117, -2148, 1527, 318, 1091, 2219, +-576, 1129, -1296, -1459, -670, -2080, 409, -267, +1029, 1934, 346, 1753, -547, -711, -194, -2219, +218, -627, -130, 1745, -691, 1570, -337, -805, +408, -1948, 915, -489, 547, 1458, -622, 1544, +-1066, -46, -469, -1435, 391, -1199, 606, 248, +116, 1129, -171, 598, 126, -281, 383, -240, +-413, 145, -1133, -212, -449, -891, 826, -500, +1481, 962, 626, 1767, -1056, 349, -1779, -1802, +-305, -1882, 1500, 398, 1322, 2149, -304, 1038, +-1257, -1124, -666, -1680, 778, 5, 1311, 1456, +85, 912, -1210, -895, -864, -1388, 583, -51, +1083, 1256, 356, 866, -405, -483, -534, -916, +-58, -198, 289, 479, 38, 130, -325, -385, +-7, -15, 722, 796, 586, 632, -525, -700, +-1017, -1387, -359, -439, 592, 1153, 717, 1423, +163, 78, -317, -1087, -313, -937, -191, 146, +-298, 545, 36, 155, 430, -74, 298, 365, +-201, 572, -481, -454, -123, -1273, 252, -615, +253, 1018, -217, 1453, -594, 319, 44, -1035, +595, -1267, 415, -97, -185, 927, -759, 790, +-565, -179, 333, -602, 1034, -151, 330, 194, +-784, 166, -603, -61, 137, -28, 515, 65, +330, -194, -121, -266, -428, 233, -163, 747, +438, 377, 377, -821, -68, -1259, -211, -324, +-139, 1388, -71, 1652, 31, -1, 419, -1787, +412, -1536, -153, 340, -383, 1715, -258, 1218, +28, -480, 266, -1614, 320, -868, 154, 701, +-146, 1514, -178, 554, -230, -992, -188, -1416, +43, -395, 300, 1146, 429, 1598, 108, 460, +-416, -1494, -755, -2044, -204, -214, 505, 2079, +654, 2027, 88, -295, -539, -2341, -515, -1775, +-12, 825, 240, 2611, 159, 1326, -38, -1596, +20, -2689, 17, -593, -224, 2248, -424, 2435, +67, -122, 701, -2505, 486, -1907, -625, 528, +-1160, 2267, -209, 1458, 1181, -712, 1486, -1888, +28, -859, -1777, 914, -1742, 1202, 334, -11, +2256, -886, 1873, -253, -439, 845, -2254, 612, +-2042, -835, 364, -1342, 2588, 18, 2101, 1730, +-369, 1305, -2404, -765, -1923, -2173, 319, -956, +2250, 1399, 1988, 2195, -452, 614, -2218, -1701, +-1456, -2217, 829, -344, 1892, 1941, 588, 1999, +-1028, -112, -1138, -1644, 293, -1191, 1024, 103, +119, 686, -1271, 444, -879, 155, 1199, 348, +2083, 381, 9, -311, -2512, -1405, -2228, -1278, +787, 529, 2952, 2232, 1875, 1804, -1305, -758, +-2937, -2466, -1230, -1629, 1305, 721, 2048, 2000, +518, 1031, -1019, -638, -951, -1137, 223, -75, +458, 636, -383, -67, -592, -843, 169, -356, +1002, 829, 909, 1067, -366, 219, -1397, -625, +-848, -858, 626, -541, 1110, -45, 583, 464, +-283, 999, -747, 780, -277, -258, 422, -1287, +368, -1047, -87, 397, -302, 1236, -297, 545, +203, -826, 941, -851, 561, 688, -723, 1433, +-1215, -5, -461, -2077, 733, -1659, 1290, 955, +661, 2723, -818, 1605, -1265, -1389, -231, -2731, +731, -1242, 636, 1374, -120, 2162, -612, 687, +-217, -1014, 506, -1319, 520, -234, -172, 709, +-675, 524, -630, -82, -152, -337, 630, -266, +971, -70, 570, 381, -517, 815, -1546, 238, +-1303, -1062, 591, -1453, 2054, -175, 1437, 1699, +-823, 1957, -2165, 94, -1206, -2115, 991, -2344, +1866, -93, 525, 2423, -1017, 2489, -947, 52, +154, -2352, 608, -2415, -80, -360, -480, 1935, +322, 2601, 919, 919, 308, -1642, -988, -2771, +-1240, -1548, -105, 1083, 1540, 3022, 1623, 2495, +-194, -677, -1744, -3618, -1359, -3088, 219, 807, +1304, 3936, 1337, 2853, 322, -1024, -797, -3483, +-1295, -2216, -948, 990, 186, 2551, 1594, 1515, +1547, -648, -137, -1574, -1833, -938, -1713, 125, +330, 698, 2025, 797, 1407, 470, -997, -134, +-2203, -975, -601, -1104, 1694, -96, 1928, 1422, +-330, 1636, -2444, 21, -1485, -1832, 1233, -1735, +2541, 36, 679, 1724, -1663, 1582, -2106, 218, +-221, -1002, 1684, -1333, 1395, -824, -362, -104, +-1356, 997, -383, 1679, 769, 1297, 512, -742, +-401, -2605, -669, -2106, 125, 726, 793, 3035, +445, 2350, -331, -657, -724, -2920, -207, -2268, +366, 487, 372, 2628, 147, 1788, 26, -386, +100, -1922, -217, -1315, -384, -51, -175, 1009, +333, 1305, 630, 896, 273, -415, -354, -1818, +-765, -1874, -253, 164, 574, 2604, 781, 2690, +165, -117, -644, -3295, -871, -3251, -251, 147, +776, 3634, 1254, 3229, 254, -277, -1199, -3156, +-1530, -2501, -280, 140, 1366, 1890, 1785, 1465, +308, 362, -1778, -336, -2068, -469, 133, -911, +1989, -1021, 1511, -190, -675, 1204, -1888, 1817, +-844, 653, 1046, -1207, 1724, -1903, 37, -774, +-1512, 843, -1283, 1374, 338, 706, 1571, 24, +1254, -555, -214, -831, -1592, -976, -1654, -242, +-79, 1108, 1759, 1797, 2155, 837, 353, -1352, +-1883, -2556, -2127, -1126, -471, 1735, 1641, 2974, +2013, 939, 572, -1965, -1205, -2636, -1597, -732, +-364, 1618, 847, 2024, 823, 544, 144, -1229, +-77, -1109, 126, 48, -215, 548, -842, -300, +-534, -677, 485, 314, 1428, 1613, 909, 1323, +-838, -869, -2020, -2761, -930, -2111, 1275, 1084, +1970, 3497, 662, 2626, -1080, -837, -1710, -3540, +-648, -2884, 720, 195, 855, 3048, 259, 2956, +310, 296, 439, -2231, -535, -2328, -1634, -439, +-1465, 1004, 546, 1172, 2756, 562, 2323, 116, +-864, 46, -3525, -279, -2421, -723, 983, -1106, +3321, -476, 2182, 1015, -973, 1989, -2612, 1313, +-1363, -901, 644, -2411, 1474, -1870, 825, 228, +-333, 2292, -641, 2423, -34, 554, 334, -1783, +-55, -2464, -363, -1271, -377, 518, -91, 2107, +946, 2394, 1393, 835, 244, -1814, -1712, -3131, +-2343, -1940, -402, 893, 2685, 3312, 3467, 3081, +165, 149, -3671, -3148, -3656, -3784, 251, -1045, +3851, 2264, 3478, 3610, -370, 2011, -3594, -842, +-2932, -3039, 397, -2959, 2666, -577, 2056, 2274, +-194, 3270, -1420, 1542, -994, -1378, -625, -3029, +-259, -1949, 714, 779, 1666, 2379, 888, 1593, +-1064, -525, -2177, -1578, -995, -813, 1392, 709, +2414, 1081, 549, -59, -2059, -1117, -2300, -1002, +-51, 406, 2451, 1614, 2324, 1712, -294, 18, +-2736, -2048, -2531, -2706, 179, -887, 2827, 2033, +3017, 3659, 359, 2065, -2589, -1449, -3380, -4044, +-1280, -3248, 2099, 431, 3853, 3933, 2200, 4057, +-1548, 548, -3550, -3258, -2481, -3984, 551, -1320, +2704, 2099, 2684, 3433, 572, 1792, -1411, -1213, +-2264, -2745, -1712, -1768, -9, 671, 1810, 2126, +2578, 1416, 1342, -580, -1140, -1781, -3144, -1124, +-2481, 563, 520, 1632, 3450, 1178, 3238, -342, +52, -1646, -3533, -1731, -3994, -322, -477, 1541, +3503, 2317, 4185, 1091, 805, -1008, -3321, -2400, +-4117, -1950, -1124, -34, 2640, 1826, 3562, 2412, +1322, 1321, -1738, -472, -2720, -2210, -1449, -2684, +493, -1090, 1515, 1622, 1451, 3324, 609, 2258, +-410, -584, -1124, -2827, -1440, -2733, -795, -557, +774, 1781, 1999, 2584, 1551, 1413, -448, -537, +-2112, -1790, -1813, -1637, 258, -629, 2036, 980, +1800, 1840, -1, 1165, -1786, -726, -1801, -2006, +-65, -932, 1870, 1333, 1928, 2311, 167, 114, +-1788, -2469, -2090, -2275, -452, 799, 1839, 2903, +2311, 1897, 681, -831, -1357, -2373, -1991, -1658, +-1071, 80, 303, 1029, 1336, 1111, 1358, 1015, +1065, 841, 64, -261, -1625, -2163, -2695, -2794, +-1573, -753, 1560, 2724, 3821, 4142, 2818, 1521, +-1066, -2739, -4415, -4451, -3761, -1997, 397, 1969, +4026, 3615, 3910, 2244, 293, -559, -3080, -2427, +-3401, -2368, -1025, -742, 1461, 1262, 2426, 2201, +1767, 1572, 71, -230, -1664, -1815, -2262, -1815, +-1210, -376, 962, 1139, 2404, 1556, 1874, 770, +-416, -62, -2263, -611, -1834, -1154, 3, -1202, +1632, -250, 1393, 1446, 552, 2170, -392, 1097, +-872, -1136, -966, -2650, -679, -1884, 214, 624, +1112, 2570, 1727, 2260, 821, 157, -1132, -1664, +-2160, -2016, -1337, -943, 580, 237, 1880, 1078, +1853, 1594, 432, 1299, -1277, -163, -1852, -1886, +-1207, -2131, 336, -542, 1492, 1379, 1583, 1856, +441, 1035, -936, -310, -1430, -1064, -807, -1354, +400, -678, 857, 247, 407, 888, -260, 851, +-175, 457, 320, -60, 556, -522, -347, -759, +-1529, -741, -1218, -450, 629, 371, 2323, 1479, +1709, 1788, -559, 182, -2485, -2182, -2181, -2760, +-12, -618, 2053, 2311, 2461, 3278, 805, 1033, +-1440, -2151, -2484, -3347, -1569, -1033, 671, 2045, +2371, 2643, 2182, 749, 65, -1366, -2078, -1323, +-2254, -224, -656, 385, 1445, -218, 1944, -332, +1069, 722, -179, 1862, -1013, 1004, -1354, -1484, +-1247, -3060, -141, -1593, 1564, 1751, 2436, 3620, +1379, 2058, -1225, -1391, -3053, -3434, -2046, -2001, +660, 987, 2711, 2187, 2164, 1058, -133, -434, +-1769, -482, -1218, 170, 36, 148, 347, -827, +-196, -1441, -352, -488, 378, 1283, 1483, 2110, +1311, 1046, -390, -940, -2306, -2063, -2301, -1468, +-366, 133, 1921, 1130, 2699, 1016, 1403, 516, +-905, 204, -2297, 15, -2052, -677, -460, -1215, +1000, -1070, 1771, 89, 1514, 1196, 297, 1501, +-974, 965, -1532, -228, -935, -1181, -137, -1578, +350, -1160, 777, 45, 1110, 1456, 908, 2238, +145, 1435, -1084, -446, -1733, -2226, -1279, -2416, +455, -747, 1717, 1279, 1694, 2225, 635, 1639, +-473, 384, -1309, -875, -1521, -1663, -867, -1657, +552, -865, 1592, 640, 1588, 2104, 509, 2528, +-786, 1032, -1365, -1610, -903, -3292, -140, -2389, +42, 399, 408, 2822, 1175, 3071, 1574, 946, +313, -1783, -1464, -2918, -2401, -1608, -1214, 691, +1130, 1873, 2318, 1411, 1130, 104, -612, -776, +-1013, -834, -337, -263, 4, 101, -545, -76, +-793, -353, -158, -20, 1280, 872, 1838, 1003, +805, 22, -1071, -1082, -2180, -1274, -1652, -386, +-117, 820, 1500, 1267, 2084, 421, 1505, -592, +-227, -767, -1887, -32, -2244, 261, -1025, 17, +901, -348, 1961, -130, 1734, 560, 356, 762, +-855, 140, -1364, -690, -1301, -682, -609, -131, +457, 160, 1654, 288, 1636, 588, 550, 667, +-1062, 93, -1756, -933, -1246, -1263, 182, -442, +1306, 1190, 1356, 1921, 477, 716, -428, -1402, +-868, -2197, -735, -750, -186, 1433, 473, 2211, +592, 880, 170, -1349, -314, -2098, -299, -877, +130, 938, 657, 1643, 443, 959, -679, -156, +-1390, -973, -752, -1247, 835, -841, 1751, 318, +1178, 1368, -442, 1457, -1674, 281, -1551, -1222, +-171, -1820, 997, -826, 1164, 896, 628, 1567, +65, 726, -295, -330, -770, -667, -1135, -553, +-723, -459, 419, -250, 1605, 407, 1546, 943, +107, 722, -1621, -387, -1791, -1236, -297, -750, +1130, 812, 1313, 1476, 399, 142, -622, -1571, +-784, -1358, -12, 780, 492, 2125, 212, 1063, +-342, -1125, -357, -2067, -33, -842, 273, 985, +447, 1387, 451, 578, 73, -207, -503, -249, +-766, -179, -452, -510, 390, -702, 833, -259, +594, 724, 2, 1274, -438, 775, -489, -337, +-246, -1255, -46, -1074, 108, -247, 214, 594, +365, 905, 277, 849, 48, 286, -226, -565, +-512, -1126, -412, -789, -53, 200, 218, 921, +389, 700, 420, -295, 244, -665, -73, 12, +-505, 763, -658, 280, -451, -950, 143, -1298, +523, -207, 678, 1292, 624, 1582, 51, 505, +-723, -956, -1078, -1646, -775, -938, 73, 341, +969, 1140, 1403, 919, 811, 352, -388, -267, +-1529, -654, -1495, -725, -238, -337, 1120, 218, +1436, 604, 635, 478, -310, 44, -743, -29, +-528, 202, -135, -39, -145, -823, -264, -968, +158, 26, 940, 1250, 1232, 1325, 328, 287, +-1133, -938, -1830, -1124, -886, -483, 920, 315, +1668, 434, 965, 351, -336, 519, -766, 622, +-366, -81, -198, -1131, -500, -1321, -458, -238, +326, 1074, 1210, 1547, 1339, 690, 117, -704, +-1499, -1302, -1881, -857, -355, 51, 1219, 618, +1345, 825, 348, 553, -420, -15, -515, -629, +-212, -939, -46, -595, -224, 325, -307, 1062, +-28, 889, 525, -144, 814, -903, 328, -884, +-377, -143, -829, 406, -598, 706, -192, 544, +396, 13, 677, -671, 548, -777, 127, -91, +-264, 490, -457, 498, -438, 57, -318, -89, +-45, 21, 376, 113, 792, -202, 576, -591, +-80, -360, -677, 398, -656, 944, -244, 581, +152, -301, 261, -800, 343, -588, 419, -34, +380, 333, 78, 418, -558, 433, -928, 442, +-738, 68, 277, -753, 1047, -1153, 920, -384, +415, 913, -269, 1254, -763, 418, -1051, -498, +-772, -796, 87, -517, 1145, -40, 1569, 299, +835, 443, -692, 414, -1811, 97, -1504, -399, +31, -698, 1366, -85, 1410, 668, 398, 504, +-441, -510, -820, -930, -411, -66, -108, 972, +-250, 928, -235, -110, 440, -929, 1066, -950, +618, -225, -148, 537, -885, 898, -997, 608, +-491, -43, 367, -675, 728, -899, 865, -439, +665, 505, -210, 951, -1006, 375, -1134, -481, +-367, -604, 691, 184, 1239, 696, 593, 152, +-518, -1016, -722, -1118, -101, 314, 365, 1790, +89, 1362, -447, -565, -516, -1867, 188, -1273, +813, 434, 811, 1369, 168, 1012, -674, -60, +-1109, -637, -730, -514, 174, -175, 887, -23, +1135, 82, 647, 256, -405, 303, -1136, 81, +-1070, -162, -267, -124, 641, 50, 950, 73, +601, -225, -14, -394, -223, -96, -476, 485, +-598, 615, -479, 240, 12, -444, 601, -604, +708, -332, 422, 52, -24, 154, -343, 213, +-558, 516, -670, 525, -428, 22, 51, -913, +830, -1229, 1412, -380, 958, 1066, -609, 1532, +-1801, 461, -1772, -893, -348, -1137, 1517, -395, +2241, 240, 1132, 369, -618, 359, -1628, 448, +-1524, 284, -630, -311, 602, -857, 1278, -587, +1340, 285, 664, 902, -483, 523, -1366, -336, +-1296, -587, -435, -103, 620, 295, 1240, 87, +990, -253, 213, -104, -375, 446, -630, 477, +-1026, -192, -906, -880, 70, -460, 1229, 608, +1574, 1094, 728, 342, -738, -832, -1598, -1093, +-1224, -267, -105, 696, 902, 888, 1276, 481, +847, -115, -107, -655, -883, -982, -1172, -505, +-525, 558, 543, 1287, 1043, 803, 444, -453, +-418, -1229, -557, -802, 64, 366, 573, 886, +130, 319, -795, -497, -808, -290, 272, 563, +1094, 583, 736, -469, -347, -1317, -879, -555, +-330, 979, 342, 1583, 301, 400, -293, -1179, +-393, -1319, 227, -61, 889, 1002, 669, 688, +-514, -310, -1192, -679, -725, -48, 305, 596, +904, 475, 838, -258, 117, -743, -447, -519, +-571, 179, -410, 694, -130, 690, 165, 296, +551, -317, 421, -928, -67, -1028, -319, -47, +-186, 1326, 105, 1538, -87, 133, -326, -1457, +-157, -1566, 363, 12, 520, 1424, 218, 1168, +-318, -454, -474, -1286, -43, -297, 319, 1080, +-77, 922, -644, -645, -277, -1467, 824, -487, +1366, 1159, 461, 1597, -1296, 274, -2064, -1310, +-671, -1485, 1287, -172, 2026, 1067, 986, 1101, +-660, 214, -1487, -562, -1155, -722, -170, -427, +626, 135, 1006, 574, 877, 553, 202, -96, +-616, -596, -1107, -499, -772, 232, 322, 692, +985, 366, 680, -498, -75, -880, -439, -153, +-385, 758, -46, 742, 115, -11, -71, -592, +25, -447, 311, -43, 161, 165, -253, 47, +-258, 63, 126, 484, 366, 571, 155, -278, +-475, -1212, -692, -914, 44, 606, 915, 1569, +774, 869, -308, -661, -1006, -1378, -698, -667, +421, 427, 975, 926, 421, 480, -600, -21, +-747, -396, -129, -417, 550, -376, 619, 58, +53, 556, -540, 612, -497, -17, -105, -709, +142, -631, 441, 181, 528, 828, 182, 460, +-491, -432, -790, -807, -433, -197, 418, 623, +942, 688, 448, -90, -450, -764, -711, -498, +-165, 337, 401, 647, 422, 387, -160, -230, +-577, -637, -64, -590, 589, 56, 475, 728, +-223, 723, -369, 84, -143, -543, -31, -730, +-206, -415, -260, 180, 410, 625, 1054, 701, +639, 289, -827, -341, -1648, -839, -770, -729, +919, 26, 1609, 784, 673, 782, -669, 153, +-932, -311, -285, -321, 122, -370, -147, -485, +-168, -144, 413, 609, 1050, 1042, 545, 478, +-760, -661, -1431, -1251, -524, -516, 737, 783, +848, 1086, 176, 87, -155, -981, 192, -510, +150, 698, -570, 1030, -1089, -155, -400, -1238, +989, -820, 1474, 494, 446, 1108, -992, 556, +-1220, -321, -246, -396, 587, -101, 448, -254, +-49, -723, -43, -404, 335, 1020, 308, 1763, +-260, 655, -786, -1466, -502, -2280, 353, -709, +740, 1495, 284, 2043, -130, 444, 21, -1169, +-8, -1089, -424, 53, -737, 457, -177, -169, +736, -436, 1102, 279, 365, 1030, -655, 567, +-1127, -637, -491, -1317, 395, -506, 822, 702, +438, 985, -213, 203, -299, -458, -191, -298, +9, 34, -94, 147, -139, -115, 91, -266, +248, -108, 275, 225, -15, 477, -185, 279, +-261, -91, -193, -481, 90, -560, 238, -159, +133, 407, -80, 747, -120, 354, 56, -361, +220, -677, 25, -207, -416, 283, -401, 206, +163, -131, 669, -25, 422, 419, -316, 416, +-717, -253, -371, -932, 500, -577, 758, 552, +34, 1156, -801, 477, -609, -705, 415, -968, +947, -261, 373, 593, -655, 517, -880, -13, +-123, -203, 522, 128, 416, 132, 7, -452, +-21, -739, 166, 46, 38, 1156, -577, 1061, +-796, -516, -147, -1658, 1043, -867, 1317, 1024, +156, 1630, -1283, 278, -1423, -1260, -104, -1125, +1132, 364, 1078, 1178, 5, 394, -791, -916, +-451, -913, 204, 377, 267, 1271, -198, 463, +-403, -1029, 64, -1262, 717, 117, 613, 1289, +-395, 927, -1059, -483, -524, -1199, 592, -533, +934, 637, 299, 985, -644, 310, -694, -593, +33, -803, 578, -296, 359, 399, -213, 740, +-490, 494, -271, -99, 352, -767, 489, -793, +93, -45, -328, 794, -350, 778, -156, 82, +150, -518, 358, -429, 256, -109, -148, 56, +-354, -92, -320, 51, 71, 483, 398, 599, +415, 7, -84, -743, -525, -854, -456, -203, +42, 586, 492, 892, 550, 466, 109, -202, +-509, -683, -703, -665, -239, -295, 482, 274, +661, 792, 240, 756, -282, -8, -432, -907, +-340, -842, -32, 66, 197, 699, 349, 482, +209, -35, 54, -326, -247, -247, -364, -20, +-218, 141, 99, 117, 353, -25, 211, -14, +14, -93, -122, -164, -62, 27, -197, 330, +-337, 349, -21, -130, 476, -610, 591, -473, +38, 192, -635, 764, -730, 545, 51, -241, +723, -720, 461, -447, -208, 183, -323, 459, +-141, 293, -21, -1, -40, -197, -52, -208, +209, -87, 383, 64, 84, 115, -551, 35, +-534, -19, 119, -5, 653, 97, 450, 54, +-342, -142, -808, -195, -217, 3, 702, 316, +599, 142, -296, -298, -705, -375, -169, 175, +490, 658, 353, 253, -192, -668, -389, -895, +-72, -46, 325, 994, 294, 990, -106, -74, +-543, -1074, -327, -993, 332, 23, 562, 914, +287, 900, -208, 161, -528, -604, -601, -808, +-71, -382, 737, 363, 802, 757, 69, 384, +-760, -345, -842, -645, -103, -105, 805, 550, +811, 460, -265, -400, -952, -925, -340, -210, +765, 1009, 797, 1207, -255, -67, -999, -1398, +-575, -1212, 425, 288, 949, 1372, 496, 972, +-361, -375, -735, -1038, -421, -516, 95, 435, +244, 583, 241, -89, 238, -531, 186, -132, +-77, 609, -405, 671, -408, -100, -219, -883, +101, -828, 400, 50, 528, 883, 312, 950, +-279, 232, -763, -719, -711, -1029, -7, -419, +833, 530, 813, 866, -77, 392, -705, -286, +-416, -539, 293, -247, 258, 136, -297, 161, +-503, -22, 100, -1, 838, 198, 602, 205, +-330, -212, -1025, -429, -583, -135, 392, 420, +754, 472, 185, -78, -362, -561, -167, -442, +383, 193, 230, 708, -548, 477, -779, -243, +-60, -729, 753, -465, 719, 104, 35, 445, +-432, 482, -407, 292, -119, -33, -71, -520, +-211, -774, 79, -310, 553, 545, 669, 966, +107, 452, -669, -341, -963, -770, -440, -565, +451, -18, 825, 462, 509, 545, 44, 336, +-379, -103, -606, -468, -516, -463, -73, -117, +423, 321, 609, 388, 256, 183, -204, -191, +-382, -223, -194, 9, -99, 132, -152, -105, +-34, -260, 225, -42, 438, 364, 293, 463, +-232, 7, -693, -557, -388, -566, 324, 65, +502, 581, 80, 537, -306, -27, -208, -516, +121, -524, 334, -52, 28, 450, -389, 505, +-336, 109, 67, -340, 233, -494, 193, -149, +75, 212, 5, 400, 3, 215, -117, -125, +-334, -232, -335, -123, 19, -29, 351, -95, +528, -22, 443, 263, -184, 443, -755, 212, +-840, -403, -286, -871, 627, -462, 1192, 643, +741, 1212, -477, 484, -1304, -758, -1018, -1180, +149, -473, 1127, 587, 980, 994, -34, 563, +-870, -311, -777, -857, -6, -588, 570, 198, +409, 671, -174, 426, -351, -130, -123, -409, +74, -294, 103, 85, 157, 274, 105, 142, +-43, -87, -388, -157, -570, -138, -131, 35, +730, 248, 1009, 249, 107, -91, -1006, -380, +-1168, -294, -196, 85, 967, 461, 1029, 335, +124, -125, -693, -468, -653, -304, -30, 166, +253, 482, 105, 265, -118, -354, 94, -571, +336, -54, 104, 573, -277, 578, -403, -15, +-199, -650, 107, -734, 325, -99, 205, 724, +42, 876, -74, 213, -163, -613, -326, -846, +-200, -367, 215, 298, 381, 687, 137, 531, +-258, -12, -258, -460, -34, -423, 172, -127, +73, 13, -187, 102, -233, 333, 63, 381, +366, 25, 163, -370, -261, -440, -445, -126, +-66, 229, 270, 357, 261, 157, -90, -163, +-328, -282, -103, -44, 301, 284, 279, 283, +-253, -229, -537, -603, -124, -298, 432, 542, +476, 890, -33, 273, -581, -654, -475, -907, +277, -295, 737, 396, 102, 736, -671, 516, +-610, -108, 186, -564, 751, -520, 531, -67, +-353, 181, -882, 250, -424, 378, 481, 309, +714, -144, 143, -632, -485, -517, -437, 167, +147, 611, 460, 415, 51, -44, -551, -364, +-460, -370, 233, -136, 763, 217, 485, 409, +-380, 208, -941, -207, -494, -439, 398, -206, +754, 299, 271, 488, -289, 93, -410, -417, +-152, -473, 181, 26, 105, 520, -229, 380, +-299, -261, 102, -497, 505, -37, 355, 445, +-153, 175, -694, -395, -600, -394, 135, 263, +581, 694, 432, 213, 39, -677, -312, -822, +-307, 43, -144, 907, -84, 737, -121, -312, +171, -898, 514, -442, 203, 467, -284, 674, +-544, 112, -313, -408, 164, -384, 527, 46, +240, 281, -294, 201, -441, -51, -101, -115, +419, -122, 399, -124, -126, -48, -577, 211, +-334, 373, 105, 96, 394, -369, 489, -488, +207, -16, -362, 520, -727, 347, -545, -292, +213, -445, 851, 181, 768, 576, -146, 33, +-902, -724, -855, -621, 18, 312, 842, 1005, +817, 641, -108, -418, -859, -1097, -614, -675, +191, 355, 642, 999, 314, 647, -270, -243, +-324, -753, -24, -493, -65, 88, -239, 389, +-32, 272, 438, 90, 530, -21, 73, -136, +-747, -241, -1004, -179, -127, 100, 932, 247, +1034, 159, 166, -15, -752, -96, -956, -169, +-423, -194, 415, -36, 708, 262, 475, 437, +-28, 91, -390, -428, -565, -575, -326, -94, +154, 497, 520, 589, 437, 173, -111, -372, +-485, -654, -304, -359, 126, 301, 307, 718, +134, 453, -158, -308, -287, -657, -25, -308, +221, 245, 146, 414, -50, 153, -95, -110, +-92, -181, -115, -73, -67, 62, 59, 68, +136, -27, 171, -82, 53, -26, -209, 119, +-333, 161, -153, -12, 163, -206, 318, -141, +178, 21, -159, 125, -315, 142, -111, 55, +94, -69, 85, -176, -16, -95, -60, 41, +25, 123, 76, 140, -16, 26, -107, -80, +-130, -178, -25, -182, 8, 20, 110, 302, +129, 381, -24, -25, -151, -521, -166, -512, +-27, 86, 119, 691, 169, 537, -45, -209, +-141, -677, -54, -406, 76, 243, 18, 506, +-57, 194, -89, -217, -17, -195, 173, 60, +139, 68, -78, -95, -291, -75, -174, 37, +110, -10, 312, 39, 178, 228, -132, 285, +-210, -125, -162, -590, -52, -482, 7, 229, +155, 750, 288, 481, 216, -167, -189, -483, +-610, -397, -376, -231, 295, 62, 607, 452, +337, 614, -214, 151, -505, -469, -345, -539, +52, -89, 333, 145, 216, 7, -50, 76, +-169, 454, -20, 488, 81, -191, -33, -846, +-201, -688, -240, 245, -10, 817, 510, 556, +557, -110, -215, -421, -922, -390, -522, -180, +515, 114, 856, 338, 283, 183, -526, -148, +-723, -115, -125, 175, 520, 196, 447, -313, +-82, -495, -275, -10, -217, 595, 20, 435, +117, -195, 110, -568, -40, -192, -2, 318, +90, 356, 98, -40, -177, -311, -373, -152, +-132, 10, 421, 166, 570, 344, 46, 287, +-500, -274, -527, -752, -124, -407, 329, 517, +518, 882, 274, 335, -249, -446, -467, -707, +-166, -387, 122, 148, 98, 539, 22, 521, +138, 70, 184, -433, 12, -472, -207, -111, +-384, 255, -191, 191, 242, 45, 500, 185, +193, 255, -297, -283, -341, -748, -146, -245, +76, 675, 161, 741, 228, -8, 37, -482, +-212, -465, -181, -162, 98, 126, 143, 401, +-42, 361, -111, 34, -17, -290, 122, -423, +192, -211, 12, 184, -379, 415, -326, 236, +338, -77, 632, -172, 32, -229, -558, -252, +-452, 1, 91, 432, 520, 402, 448, -125, +-125, -424, -580, -214, -279, 69, 274, 137, +422, 230, 83, 177, -271, -98, -220, -380, +133, -180, 267, 236, -31, 316, -268, -4, +-94, -207, 199, -39, 168, 99, -30, -54, +-120, -143, 0, 65, 85, 237, -83, 50, +-143, -190, 53, -151, 260, 82, 69, 143, +-144, -31, -123, -132, -17, -16, 54, 191, +128, 102, -1, -159, -169, -282, 34, -45, +285, 308, 69, 303, -280, -88, -283, -362, +79, -185, 397, 167, 184, 226, -251, 7, +-312, -92, 177, 20, 373, 116, -32, -51, +-433, -296, -288, -245, 270, 170, 612, 542, +399, 401, -352, -240, -816, -727, -451, -471, +437, 228, 877, 678, 476, 442, -279, -100, +-711, -418, -426, -340, 87, -26, 355, 64, +316, -7, 331, 191, 180, 467, -303, 284, +-703, -424, -475, -784, 349, -280, 899, 501, +589, 632, -326, 225, -774, -208, -423, -347, +225, -360, 495, -123, 284, 345, -87, 474, +-153, 39, -34, -402, -75, -255, -151, 216, +68, 281, 347, -76, 122, -292, -290, -115, +-265, 149, 228, 300, 463, 267, -1, -187, +-554, -643, -312, -327, 406, 596, 538, 787, +-14, -69, -360, -745, -183, -437, 67, 288, +286, 523, 108, 74, -229, -393, -267, -252, +176, 388, 507, 546, 254, -186, -312, -926, +-682, -579, -358, 664, 541, 1210, 1039, 444, +251, -712, -733, -1140, -786, -543, -130, 446, +508, 1047, 695, 580, 303, -260, -455, -551, +-579, -371, -55, -245, 409, -37, 317, 437, +-41, 576, -305, 174, -72, -366, 365, -403, +142, -151, -317, 47, -158, 113, 286, 234, +127, 265, -178, -110, -22, -365, 149, -93, +119, 324, -17, 223, -178, -288, -93, -358, +189, 26, 259, 429, -61, 282, -250, -142, +-82, -272, 192, -180, 342, 16, 49, 197, +-267, 212, -277, -129, 23, -378, 192, 63, +239, 574, 246, 318, 52, -483, -259, -743, +-451, -169, -97, 504, 417, 726, 486, 306, +30, -403, -271, -766, -142, -420, 77, 469, +81, 686, -34, 172, -168, -404, -50, -506, +382, 33, 486, 469, 82, 404, -520, -339, +-588, -692, -51, -46, 432, 681, 497, 472, +274, -387, 86, -561, -245, 63, -572, 478, +-453, 72, 238, -455, 797, -200, 597, 274, +-175, 429, -665, 4, -357, -306, 305, -207, +369, 93, 6, 60, -212, -213, 9, 56, +331, 539, 196, 340, -175, -530, -333, -866, +23, -64, 204, 923, 52, 912, -43, -375, +49, -1376, 267, -657, 303, 1146, -50, 1657, +-729, -123, -522, -1945, 546, -1294, 1094, 1194, +281, 2131, -793, 201, -670, -1836, 197, -1385, +629, 798, 190, 1678, -408, 378, -235, -1169, +407, -1157, 566, 328, -206, 1236, -780, 506, +-193, -902, 780, -990, 709, 493, -271, 1294, +-868, -2, -279, -1550, 628, -874, 869, 1263, +73, 1814, -774, -40, -583, -1922, 277, -1320, +577, 819, 259, 1716, -144, 446, -117, -1100, +63, -898, 41, 401, -270, 976, -330, -56, +304, -1132, 769, -503, 367, 1117, -549, 1265, +-794, -427, -57, -1551, 727, -557, 577, 1134, +-246, 1172, -539, -395, 8, -1344, 552, -396, +178, 1143, -509, 1164, -365, -380, 472, -1477, +676, -621, -8, 1047, -650, 1166, -475, -409, +283, -1129, 833, 76, 467, 1174, -450, 307, +-781, -1204, -174, -1169, 414, 454, 603, 1592, +380, 912, -176, -644, -443, -1431, -284, -814, +-78, 485, 165, 1170, 602, 577, 558, -424, +-233, -553, -790, 65, -451, 99, 453, -477, +924, -455, 261, 518, -700, 1236, -642, 464, +234, -1100, 661, -1460, 414, -101, -193, 1299, +-615, 1167, -156, -195, 415, -1150, 281, -837, +-42, 363, 20, 1002, 138, 520, -12, -478, +-147, -837, -330, -281, -67, 535, 636, 657, +543, 16, -207, -416, -578, -279, -180, 2, +245, 76, 416, 148, 136, 74, -317, 29, +-174, 17, 374, 27, 357, -155, -184, -240, +-471, -10, -180, 245, 496, 267, 643, 27, +-74, -193, -617, -157, -231, -76, 338, -17, +417, 26, 197, 189, -160, 254, -426, 73, +-146, -222, 352, -597, 378, -273, 225, 545, +-65, 912, -365, 195, -350, -889, -19, -965, +437, 23, 516, 1043, 171, 869, -247, -310, +-348, -1006, -259, -447, -80, 387, 377, 561, +620, 126, 173, -209, -309, -126, -287, 111, +-147, 19, -133, -385, 204, -347, 497, 394, +342, 875, -88, 229, -386, -943, -323, -963, +-20, 268, 355, 1136, 388, 570, 160, -643, +-190, -843, -266, -183, -66, 628, 107, 660, +200, -65, 198, -693, 27, -497, -128, 483, +-125, 772, -43, -137, 205, -868, 437, -256, +171, 944, -659, 639, -549, -758, 397, -1109, +1003, 208, 422, 1389, -705, 538, -901, -1028, +-50, -1197, 880, 262, 670, 1309, -314, 540, +-514, -939, 49, -1085, 424, 293, 28, 1385, +-474, 490, -283, -1263, 494, -1369, 1033, 529, +209, 1870, -1066, 637, -1041, -1520, 279, -1587, +1257, 580, 753, 1749, -558, 353, -812, -1479, +17, -952, 524, 1050, 50, 1524, -374, -304, +15, -1891, 570, -926, 503, 1378, -295, 1932, +-858, -48, -211, -1807, 764, -1134, 682, 903, +-266, 1456, -639, -125, -46, -1420, 607, -467, +534, 1311, -234, 1426, -789, -635, -546, -2005, +664, -1041, 1240, 1311, 408, 2130, -832, 473, +-1081, -1476, -173, -1556, 679, -82, 952, 984, +391, 886, -484, 166, -768, -449, -269, -594, +458, -349, 666, 86, 287, 676, -381, 792, +-593, -93, 5, -1392, 677, -1167, 434, 741, +-311, 2101, -452, 981, -53, -1372, 391, -2150, +307, -540, -128, 1368, -267, 1433, 185, 238, +509, -567, 16, -486, -576, -357, -519, -496, +277, -327, 1081, 666, 667, 1448, -695, 691, +-1221, -1209, -139, -1825, 1118, -274, 826, 1422, +-373, 1183, -852, -300, -69, -1018, 907, -235, +534, 690, -758, 313, -1072, -842, 337, -799, +1486, 785, 666, 1602, -795, 209, -1250, -1783, +-241, -1590, 967, 665, 965, 2136, -114, 957, +-745, -1374, 6, -1712, 585, 19, -22, 1413, +-943, 613, -408, -816, 1361, -706, 1697, 618, +-343, 946, -2251, -382, -1324, -1335, 1205, -474, +2350, 1085, 966, 1393, -1591, -117, -2033, -1474, +126, -1024, 1884, 876, 908, 1612, -917, -18, +-930, -1685, 146, -1098, 928, 1077, 608, 1899, +-670, 327, -899, -1569, 170, -1570, 962, 100, +421, 1366, -403, 1071, -476, -252, 22, -942, +607, -431, 144, 434, -636, 315, -178, -491, +667, -510, 508, 487, -176, 1106, -431, 331, +-254, -1066, 239, -1182, 554, 60, -1, 1088, +-470, 603, -22, -450, 576, -597, 436, 243, +-198, 741, -686, -122, -508, -1226, 587, -905, +1014, 924, 267, 1915, -531, 668, -520, -1403, +-88, -2014, 203, -312, 324, 1573, 67, 1451, +108, -279, 435, -1382, 160, -391, -557, 993, +-735, 841, -37, -880, 862, -1800, 987, -119, +174, 2099, -843, 2137, -857, -530, 102, -2654, +830, -1982, 428, 624, -324, 2253, -206, 1522, +461, -111, 405, -1115, -368, -1186, -761, -800, +-247, -34, 615, 848, 1104, 1258, 632, 966, +-639, -187, -1239, -1481, -595, -1687, 664, -342, +1293, 1375, 746, 1781, -485, 544, -1127, -1005, +-427, -1424, 612, -552, 888, 552, 213, 904, +-540, 390, -586, -386, 194, -633, 888, -105, +477, 510, -382, 612, -900, -122, -484, -989, +622, -860, 1273, 351, 646, 1326, -647, 926, +-1194, -324, -482, -1292, 660, -1082, 1138, 94, +539, 1136, -542, 923, -833, -49, -150, -702, +662, -535, 753, -111, -168, 244, -781, 187, +-306, 90, 777, 34, 907, -108, 17, -105, +-709, 135, -745, 229, 17, -254, 881, -499, +870, -157, -56, 465, -659, 599, -558, 129, +-27, -606, 786, -717, 906, 38, -77, 832, +-1092, 525, -861, -573, 455, -1085, 1582, -120, +1370, 1333, -541, 1202, -2156, -611, -1746, -2004, +727, -1175, 2991, 1118, 2359, 2440, -773, 1146, +-3349, -1577, -2387, -2828, 1011, -970, 3347, 1937, +2268, 2806, -964, 624, -2690, -2203, -1379, -2522, +1053, -182, 1683, 2102, 555, 1872, -570, -181, +-365, -1654, 308, -1222, 210, 172, -659, 947, +-720, 570, 794, 13, 1846, -139, 550, 4, +-1836, -312, -2185, -931, 310, -602, 2893, 854, +2374, 1868, -1029, 809, -3353, -1361, -1946, -2317, +1714, -1042, 3489, 1466, 1500, 2519, -1808, 1019, +-2615, -1521, -669, -2303, 1470, -745, 1589, 1267, +333, 1770, -651, 379, -589, -1246, 23, -1252, +345, 164, 378, 1298, 93, 846, -488, -762, +-588, -1701, 194, -714, 1348, 1374, 1219, 2122, +-384, 509, -1904, -1803, -1475, -2408, 846, -441, +2437, 2120, 1460, 2313, -1210, -57, -2237, -2351, +-415, -1734, 1907, 869, 1701, 2273, -918, 729, +-2399, -1890, -421, -2124, 2628, 419, 2645, 2674, +-708, 1710, -3379, -1376, -2058, -2982, 1606, -1260, +3425, 1750, 1295, 2646, -1776, 747, -2244, -1546, +-245, -1969, 1784, -483, 1226, 1004, -676, 1158, +-1400, 304, -71, -542, 1640, -756, 1212, -212, +-446, 477, -1717, 581, -925, -92, 914, -718, +1543, -546, 556, 184, -699, 870, -660, 852, +105, -152, 499, -1283, 237, -1250, -407, 250, +-476, 1519, 138, 1105, 1001, -422, 936, -1341, +-41, -733, -971, 444, -1108, 917, -188, 268, +866, -680, 1267, -719, 841, 186, -118, 1118, +-882, 748, -1180, -611, -711, -1865, 710, -1316, +1851, 914, 1442, 2784, -410, 1942, -1776, -1190, +-1454, -3641, 156, -2610, 1772, 1143, 1588, 4119, +170, 3194, -1211, -1021, -1237, -4445, -376, -3506, +641, 874, 1267, 4217, 1159, 3301, 303, -611, +-1183, -3539, -2125, -3031, -905, 44, 1793, 2610, +3406, 2696, 1533, 616, -2308, -1773, -4140, -2584, +-1598, -1319, 3088, 1115, 4778, 2540, 1486, 1646, +-3344, -853, -4553, -2445, -953, -1684, 3634, 687, +4438, 2065, 421, 1298, -3687, -519, -3444, -1412, +429, -1025, 3429, 93, 2806, 689, -636, 707, +-2898, 436, -1979, 16, 972, -628, 2584, -1153, +1476, -766, -814, 601, -1985, 1876, -979, 1279, +1008, -768, 1884, -2449, 855, -1515, -1056, 825, +-1758, 2298, -504, 1318, 1562, -588, 2058, -1591, +476, -958, -1717, -4, -2226, 273, -274, 344, +2298, 798, 2467, 1102, 90, 135, -2112, -1570, +-1934, -2364, 32, -646, 1864, 2157, 1793, 3185, +-33, 640, -1252, -2601, -923, -3248, -32, -460, +763, 2469, 882, 2746, 384, 260, -422, -2123, +-668, -2271, -347, -174, 403, 1693, 1064, 1666, +649, 197, -554, -1211, -1047, -1292, -264, -542, +709, 515, 1079, 1115, 353, 1004, -650, -40, +-729, -1084, 266, -1382, 799, -344, 185, 798, +-552, 1215, -379, 575, 527, -219, 1024, -698, +270, -894, -720, -640, -845, -110, -68, 978, +653, 1371, 838, 794, 542, -717, -69, -1937, +-529, -1531, -879, 173, -306, 1977, 724, 2130, +1309, 275, 770, -1804, -409, -2322, -1345, -704, +-1090, 1248, 599, 1894, 1835, 951, 1228, -593, +-580, -1295, -1624, -990, -1028, 12, 706, 400, +1633, 402, 951, 383, -329, 685, -949, 311, +-701, -736, -109, -1764, 581, -1147, 875, 749, +626, 2477, 106, 1922, -363, -568, -808, -2976, +-470, -2672, 115, 252, 678, 3090, 1035, 2847, +806, -51, 18, -2642, -1020, -2671, -1437, -315, +-852, 1890, 890, 2036, 2619, 234, 2111, -1190, +-665, -732, -3106, 132, -2653, 86, 535, -729, +3530, -853, 3071, 608, -380, 2185, -3112, 1782, +-2464, -1130, 465, -3496, 2612, -2466, 1889, 1033, +-509, 3911, -1802, 2909, -676, -623, 1134, -3558, +1268, -2977, -247, -11, -1643, 2196, -763, 2314, +1576, 776, 2471, -450, 732, -1183, -2292, -1589, +-3114, -1446, -615, -103, 3281, 2007, 3977, 2645, +444, 1052, -3658, -1686, -3913, -3157, -6, -2026, +3941, 1010, 3744, 3078, -341, 2169, -3467, -484, +-2657, -2297, 580, -1749, 2937, -42, 2226, 1186, +-651, 1015, -2348, 43, -1225, -549, 1028, -193, +1735, 493, 858, 215, -568, -699, -1314, -1096, +-623, -301, 498, 853, 1052, 1215, 1088, 803, +345, -150, -760, -1114, -1577, -1617, -974, -1141, +718, 477, 2221, 2303, 2130, 2467, -36, 349, +-2498, -2647, -3014, -3608, -755, -1337, 2706, 2455, +4458, 4222, 2020, 1918, -2727, -2111, -5160, -4142, +-2684, -2032, 2514, 1474, 5669, 3163, 3539, 1785, +-1898, -668, -5392, -2023, -3548, -1732, 1429, -141, +4618, 1294, 3630, 1636, -480, 572, -3477, -1009, +-2948, -1808, -119, -1113, 2159, 1028, 2575, 2522, +1101, 1495, -686, -1551, -1904, -3427, -1723, -1922, +-388, 1911, 1488, 4040, 2622, 2170, 1609, -1813, +-888, -3969, -2950, -2499, -2388, 819, 525, 3067, +3205, 2732, 3221, 473, 344, -1736, -2877, -2511, +-3469, -1682, -902, -68, 2466, 1593, 3553, 2309, +1578, 1586, -1480, -262, -2890, -2144, -1680, -2583, +653, -1228, 2114, 1125, 1861, 2696, 380, 2326, +-1080, 61, -1616, -2210, -723, -2701, 561, -1149, +1376, 1190, 1212, 2478, 139, 1695, -1210, -535, +-1485, -2251, -33, -1667, 1619, 563, 1823, 2172, +235, 1148, -1822, -1365, -2080, -2533, -201, -704, +2015, 2230, 2542, 3121, 760, 790, -1504, -2720, +-2480, -3971, -1252, -1454, 723, 2575, 2184, 4242, +2012, 2020, 554, -1744, -1117, -3483, -1906, -2194, +-1602, 249, -210, 1537, 1531, 1626, 2526, 1385, +1811, 824, -237, -671, -2490, -2506, -3099, -2970, +-929, -702, 2203, 2692, 3921, 4261, 2372, 2025, +-1319, -2281, -4002, -4698, -3111, -2878, 829, 1534, +3804, 4147, 3281, 2824, 52, -723, -3030, -2958, +-3035, -2371, -279, -122, 2448, 1554, 2591, 1696, +649, 644, -1364, -415, -1956, -978, -783, -1032, +723, -500, 1489, 276, 877, 976, 106, 1007, +-513, 453, -598, -505, -513, -1381, -261, -1331, +199, -305, 889, 1337, 1154, 2067, 631, 1143, +-531, -980, -1436, -2446, -1254, -1827, -32, 294, +1404, 1984, 1872, 1965, 979, 593, -675, -1012, +-1736, -1693, -1414, -1222, -50, -109, 1155, 750, +1596, 1080, 872, 1000, -28, 434, -739, -353, +-1226, -1415, -980, -1529, 30, -597, 1253, 982, +1573, 1851, 926, 1473, -438, 95, -1545, -1632, +-1337, -2261, 8, -1068, 1167, 1126, 1224, 2163, +550, 1284, -193, -409, -582, -1214, -508, -1011, +-411, -426, -228, -191, 285, 313, 1123, 1131, +1361, 1483, 221, 347, -1462, -1689, -1983, -2506, +-583, -846, 1746, 2012, 2575, 2982, 1141, 865, +-1408, -2031, -2810, -2920, -1606, -899, 1235, 1650, +2951, 2386, 1992, 790, -500, -1110, -2336, -1494, +-2103, -459, -205, 379, 1688, 118, 1822, -197, +820, 342, -171, 1233, -886, 935, -1231, -776, +-849, -2198, 20, -1570, 989, 575, 1620, 2224, +1179, 1835, -318, 43, -1531, -1488, -1406, -1615, +-289, -729, 768, 336, 1248, 809, 832, 802, +70, 657, -244, 271, -335, -458, -437, -1087, +-715, -940, -491, -140, 234, 551, 1216, 642, +1691, 567, 942, 622, -820, 349, -2225, -704, +-2049, -1679, -162, -1429, 2113, 283, 2943, 1774, +1343, 1835, -1233, 391, -2620, -921, -1676, -1241, +310, -839, 1519, -493, 1199, -289, 394, 498, +10, 1611, 123, 1954, -7, 507, -774, -1797, +-1546, -2903, -1016, -1711, 858, 670, 2566, 2437, +2198, 2489, -92, 1164, -2085, -803, -2492, -2452, +-1078, -2861, 840, -1304, 2080, 1477, 2001, 3472, +800, 2826, -780, -54, -2014, -2817, -1761, -3285, +-131, -1162, 1403, 1336, 1590, 2376, 547, 1601, +-324, 237, -334, -819, 60, -1334, -190, -1276, +-979, -560, -1138, 700, 184, 1429, 1818, 972, +2040, -208, 457, -963, -1274, -548, -1793, 263, +-1090, 373, -1, -447, 561, -999, 1217, -91, +1658, 1448, 1407, 1722, -460, 165, -2467, -1718, +-2788, -2126, -803, -709, 2118, 1198, 3292, 2006, +2053, 1156, -543, -377, -2400, -1282, -2498, -1202, +-1181, -447, 808, 125, 2215, 756, 2313, 1033, +798, 749, -1083, -183, -2095, -1066, -1420, -1087, +-104, -422, 914, 455, 1122, 921, 1109, 900, +659, 273, -193, -631, -1158, -1128, -1556, -733, +-735, 259, 770, 992, 1828, 836, 1076, 43, +-400, -714, -1005, -801, -402, -228, 258, 354, +54, 565, -405, 387, -420, 86, 400, -309, +1172, -710, 967, -738, -200, 76, -1050, 1269, +-1185, 1462, -461, -46, 313, -1914, 998, -1949, +1105, 157, 873, 2139, -75, 1947, -1214, -238, +-1759, -1816, -908, -1535, 875, 121, 1986, 1099, +1590, 855, -42, 49, -1305, -339, -1535, -253, +-770, -215, 368, -163, 1207, -50, 1065, 231, +277, 228, -369, -57, -636, -185, -458, 76, +-202, 317, 56, 81, 169, -376, 352, -487, +570, -64, 381, 301, -75, 336, -702, 133, +-749, 93, -194, 168, 703, -108, 813, -704, +27, -950, -575, -180, -134, 1187, 565, 1750, +434, 557, -513, -1377, -1099, -2101, -487, -853, +833, 1088, 1564, 1878, 693, 906, -728, -701, +-1424, -1218, -742, -529, 410, 490, 969, 515, +515, -247, -187, -730, -199, -83, 135, 1135, +122, 1217, -365, -106, -601, -1588, -105, -1450, +522, -28, 592, 1306, 169, 1164, -123, 181, +-75, -508, -97, -328, -215, -73, -474, -324, +-256, -765, 271, -504, 813, 762, 735, 1613, +145, 1133, -432, -489, -865, -1707, -879, -1593, +-398, -358, 523, 1034, 1430, 1526, 1485, 1221, +329, 218, -1426, -1011, -2160, -1850, -1123, -1347, +893, 463, 2029, 1903, 1489, 1603, 50, -178, +-1085, -1385, -1193, -933, -727, 314, -24, 529, +378, -281, 750, -677, 839, 153, 609, 1315, +-111, 1167, -943, -505, -1144, -1885, -581, -1294, +325, 594, 978, 1726, 1083, 894, 504, -654, +-274, -1041, -842, -42, -988, 771, -583, 155, +296, -895, 916, -827, 850, 457, 333, 1415, +-106, 773, -456, -668, -715, -1312, -666, -475, +-230, 496, 439, 615, 1063, -5, 1066, -120, +173, 302, -1078, 529, -1315, -347, -520, -1207, +707, -728, 1079, 839, 335, 1656, -443, 584, +-380, -1160, 323, -1672, 459, -388, -231, 1299, +-868, 1517, -782, 307, 300, -1185, 1214, -1356, +961, -346, -145, 714, -784, 1024, -526, 619, +-79, 158, -166, -572, -397, -1132, -33, -981, +952, 144, 1628, 1373, 768, 1432, -1332, 184, +-2428, -1079, -1489, -1275, 764, -457, 2263, 350, +2091, 666, 283, 652, -1222, 420, -1837, -65, +-1263, -649, -295, -815, 917, -319, 1649, 454, +1418, 796, 317, 416, -1116, -292, -1694, -604, +-1130, -203, 20, 336, 1106, 336, 1223, -164, +742, -421, -4, -136, -315, 318, -692, 490, +-1113, 82, -947, -344, -1, -472, 1373, 2, +1974, 460, 1164, 398, -851, -338, -2319, -824, +-1974, -267, -54, 852, 1756, 1268, 2210, 354, +807, -1175, -992, -1762, -1586, -767, -731, 1096, +252, 2137, 427, 1325, 185, -629, -46, -2112, +471, -1797, 879, 50, 278, 1746, -1055, 1816, +-1584, 248, -518, -1224, 907, -1223, 1708, -4, +819, 725, -682, 269, -1383, -567, -635, -547, +562, 507, 798, 1249, 233, 721, -512, -878, +-534, -1624, 128, -860, 582, 708, 477, 1387, +93, 682, -426, -293, -861, -532, -677, -94, +162, -67, 1083, -493, 1254, -562, 452, 78, +-1004, 938, -1597, 1004, -804, 340, 660, -535, +1191, -955, 743, -1001, -136, -448, -335, 523, +-129, 1441, -125, 1304, -649, 171, -751, -1277, +100, -1688, 1167, -673, 1189, 738, 309, 1288, +-676, 644, -1132, -65, -864, -216, -280, -177, +427, -432, 978, -852, 1196, -522, 837, 616, +-524, 1415, -1796, 1007, -1763, -359, -280, -1289, +1432, -1143, 2058, -96, 1139, 730, -478, 934, +-1471, 522, -1528, -212, -733, -616, 426, -490, +1337, -19, 1362, 242, 584, 67, -484, 3, +-1211, 98, -1152, 335, -401, 186, 394, -241, +962, -643, 1070, -364, 465, 341, -415, 745, +-857, 394, -870, -434, -460, -673, 170, -186, +695, 376, 856, 446, 763, 177, 100, -147, +-882, -353, -1372, -359, -855, -149, 375, 223, +1416, 605, 1365, 670, 153, 77, -1017, -885, +-1156, -1249, -596, -408, 305, 943, 799, 1548, +652, 757, 104, -626, -268, -1417, -417, -1003, +-357, 103, -17, 927, 383, 913, 334, 302, +-137, -141, -553, -399, -322, -583, 597, -545, +909, -125, 237, 541, -790, 814, -1125, 420, +-514, -247, 618, -580, 1272, -343, 759, -33, +-300, 42, -952, -24, -880, 86, -176, 450, +670, 581, 669, 92, 90, -771, -139, -985, +-69, -199, -96, 787, -133, 947, -188, 122, +-330, -609, 28, -392, 519, 311, 541, 317, +-68, -505, -413, -888, -375, 85, 49, 1306, +304, 1266, -53, -324, -474, -1658, -195, -1289, +559, 382, 944, 1530, 337, 996, -759, -394, +-1349, -1042, -691, -394, 592, 533, 1245, 454, +891, -371, 88, -710, -658, 86, -951, 1069, +-796, 893, -201, -482, 549, -1435, 1246, -830, +1035, 710, -16, 1428, -1263, 511, -1515, -745, +-415, -993, 932, -113, 1363, 677, 501, 548, +-462, -185, -760, -555, -374, -283, 70, 263, +204, 495, 74, 382, 44, -59, 13, -506, +50, -694, 138, -219, 119, 590, -107, 981, +-229, 537, -336, -531, -259, -1186, 209, -685, +535, 475, 455, 1148, 30, 672, -366, -334, +-531, -809, -373, -487, 12, 101, 283, 383, +496, 334, 491, 186, 156, -10, -572, -186, +-835, -355, -375, -225, 396, 182, 790, 480, +476, 352, -207, -269, -592, -579, -432, -259, +114, 399, 525, 673, 432, 172, -282, -431, +-729, -647, -474, -246, 480, 297, 1031, 753, +693, 560, -464, -106, -1252, -829, -1029, -787, +96, -92, 1239, 788, 1427, 959, 339, 262, +-963, -625, -1459, -841, -697, -276, 491, 380, +1102, 592, 873, 316, -7, -133, -678, -323, +-808, -271, -206, -18, 504, 232, 604, 372, +2, 163, -542, -296, -411, -631, 296, -290, +814, 578, 523, 1063, -449, 435, -1115, -810, +-826, -1291, 288, -549, 1285, 758, 1154, 1359, +33, 807, -1089, -447, -1099, -1246, -297, -895, +558, 200, 714, 1035, 299, 753, 55, -134, +21, -635, -27, -279, -410, 263, -615, 268, +-322, -154, 328, -331, 843, -11, 675, 300, +48, 248, -518, 47, -603, 152, -473, 152, +-164, -308, 245, -898, 767, -628, 847, 602, +285, 1639, -705, 1212, -1152, -566, -537, -1947, +456, -1530, 881, 280, 387, 1680, -10, 1474, +-54, 257, 100, -711, -316, -922, -752, -852, +-566, -536, 401, 339, 1166, 1427, 980, 1568, +-111, 131, -1160, -1665, -1045, -1899, -62, -180, +811, 1633, 741, 1622, 159, -33, -213, -1323, +-177, -953, -94, 434, -193, 1079, -211, 408, +-32, -701, 339, -871, 378, -81, 189, 717, +-101, 774, -222, 179, -220, -339, -160, -542, +-42, -464, 237, -218, 356, 349, 301, 830, +-32, 686, -380, -68, -447, -819, -18, -778, +445, -163, 409, 495, -42, 701, -367, 404, +-217, -37, 218, -398, 404, -375, 82, -164, +-408, 78, -380, 190, 66, 234, 452, 243, +465, 159, -28, -31, -500, -336, -407, -453, +141, -189, 455, 374, 226, 731, -169, 505, +-312, -251, -71, -879, 240, -716, 248, 218, +26, 1039, -166, 903, -231, -71, -165, -1001, +8, -951, 294, -57, 446, 850, 269, 1046, +-308, 423, -762, -497, -568, -1035, 298, -735, +1004, 174, 759, 970, -219, 980, -998, 257, +-820, -674, 112, -972, 824, -486, 723, 341, +-24, 831, -612, 631, -508, 20, 0, -397, +284, -464, 251, -238, 121, -23, -40, 271, +-226, 497, -292, 400, -104, -67, 243, -549, +428, -488, 176, 81, -296, 599, -608, 441, +-280, -110, 259, -417, 471, -250, 341, 135, +-4, 285, -287, 215, -498, 147, -452, -33, +-77, -293, 434, -496, 876, -130, 473, 621, +-552, 965, -1307, 335, -772, -870, 616, -1255, +1396, -255, 659, 1118, -846, 1309, -1398, 62, +-412, -1109, 971, -872, 1112, 380, -26, 1008, +-1168, 284, -1063, -703, 129, -635, 1148, 313, +944, 896, -182, 425, -1060, -503, -1058, -764, +-284, -215, 575, 445, 1016, 550, 641, 234, +-184, -110, -1042, -137, -1193, -134, -374, -184, +788, -199, 1252, 139, 497, 530, -746, 510, +-1221, -14, -564, -592, 361, -631, 757, -32, +296, 696, -366, 736, -604, 86, -191, -585, +224, -631, 172, -5, -201, 604, -295, 591, +-133, -60, 86, -551, 26, -359, -176, 298, +-175, 616, 20, 170, 76, -463, -155, -475, +-276, 160, -290, 657, -86, 354, 161, -318, +201, -588, -107, -117, -363, 509, -217, 528, +-58, 6, -103, -433, -230, -312, -164, 146, +127, 378, 311, 169, 53, -59, -455, -58, +-698, -2, -416, -82, 139, -156, 475, 81, +333, 408, -139, 415, -496, -117, -574, -615, +-420, -413, -42, 332, 357, 720, 327, 358, +-46, -268, -423, -499, -486, -166, -252, 242, +-7, 267, -39, -36, -174, -59, -23, 249, +196, 418, 34, -33, -486, -712, -622, -601, +-289, 330, 204, 1076, 306, 592, -18, -392, +-389, -845, -346, -274, -49, 419, -77, 382, +-432, -101, -456, -201, 193, 376, 678, 673, +183, 42, -911, -907, -1303, -1006, -349, 159, +934, 1336, 1091, 1176, -109, -230, -1304, -1228, +-1210, -853, -88, 329, 721, 915, 581, 412, +-107, -286, -564, -278, -496, 192, -367, 297, +-317, -155, -209, -494, 220, -149, 524, 491, +174, 641, -586, 125, -1099, -419, -672, -413, +209, -75, 728, 261, 405, 372, -325, 260, +-832, -19, -717, -334, -151, -410, 337, 1, +285, 678, -192, 752, -510, -69, -476, -1019, +-88, -886, 251, 381, 127, 1424, -410, 952, +-678, -638, -421, -1397, 127, -468, 358, 882, +147, 969, -343, -101, -552, -751, -422, -95, +-218, 858, -101, 571, -2, -718, 149, -1304, +139, -231, -105, 1393, -525, 1605, -830, 80, +-482, -1536, 217, -1420, 656, 148, 276, 1330, +-439, 1018, -794, -108, -516, -670, -36, -343, +145, 75, -24, 27, -210, -83, -137, 175, +56, 503, 15, 421, -431, -195, -710, -644, +-495, -444, 210, 278, 639, 706, 366, 492, +-589, -139, -1049, -573, -552, -405, 271, 199, +585, 601, 131, 341, -569, -143, -759, -419, +-142, -206, 460, 257, 133, 391, -552, 86, +-627, -262, -55, -145, 461, 261, 216, 362, +-635, -40, -988, -499, -133, -339, 857, 392, +746, 846, -477, 378, -1399, -494, -1109, -924, +263, -360, 1328, 607, 926, 1000, -425, 478, +-1380, -370, -1174, -835, -273, -552, 618, 208, +901, 761, 493, 688, -279, 67, -929, -521, +-1000, -603, -489, -131, 305, 439, 780, 476, +502, 145, -187, -156, -670, -138, -638, 25, +-342, 53, -53, -53, 153, -142, 216, 136, +177, 386, -22, 297, -372, -152, -559, -476, +-349, -226, 68, 350, 251, 541, 86, 83, +-248, -361, -293, -280, -58, 191, 128, 443, +34, 157, -275, -301, -549, -378, -410, 90, +179, 456, 585, 327, 344, -150, -190, -368, +-575, -46, -712, 418, -451, 218, 109, -339, +607, -436, 642, 219, 179, 776, -568, 471, +-1018, -455, -741, -903, 67, -294, 792, 688, +837, 815, 98, 96, -762, -520, -872, -306, +-277, 294, 217, 333, 309, -285, 127, -613, +-36, 82, -15, 986, -65, 916, -300, -295, +-494, -1267, -211, -919, 212, 437, 478, 1303, +236, 854, -263, -217, -650, -883, -431, -634, +167, 63, 498, 502, 299, 481, -360, 214, +-702, -74, -280, -302, 479, -229, 653, 49, +-34, 299, -792, 152, -763, -106, 112, -176, +929, 119, 607, 400, -498, 143, -1103, -360, +-502, -419, 564, 99, 967, 595, 251, 387, +-750, -287, -914, -579, -181, -33, 546, 674, +541, 513, 61, -351, -305, -814, -302, -212, +-185, 785, -170, 938, -134, 24, 81, -926, +444, -767, 454, 184, -61, 953, -752, 708, +-834, -211, -151, -765, 696, -455, 910, 292, +208, 612, -714, 287, -861, -211, -155, -326, +452, -24, 435, 246, -100, 129, -431, -95, +-191, -97, 445, 116, 487, 277, -272, 117, +-893, -252, -613, -364, 348, 33, 995, 504, +668, 510, -418, -131, -1008, -649, -624, -433, +213, 384, 665, 850, 404, 345, -217, -509, +-495, -789, -158, -128, 305, 677, 236, 708, +-229, -24, -533, -557, -315, -330, 334, 223, +685, 337, 282, -20, -408, -229, -648, 161, +-355, 468, 61, 164, 334, -518, 246, -604, +65, 56, 29, 760, 9, 701, -323, -115, +-619, -759, -341, -514, 391, 283, 792, 705, +382, 370, -393, -257, -811, -557, -422, -201, +206, 379, 514, 596, 159, 236, -250, -382, +-275, -658, 99, -241, 241, 503, -106, 846, +-455, 279, -308, -550, 201, -758, 494, -73, +247, 667, -316, 515, -603, -234, -282, -613, +289, -1, 535, 745, 122, 650, -491, -405, +-637, -1150, -118, -575, 524, 746, 603, 1408, +69, 611, -611, -705, -743, -1201, -287, -555, +359, 441, 623, 810, 438, 583, -157, 118, +-569, -280, -641, -543, -271, -479, 202, -22, +563, 579, 462, 727, -63, 159, -541, -570, +-565, -613, -187, 50, 262, 623, 357, 452, +21, -203, -250, -548, -169, -218, 81, 343, +52, 455, -147, 159, -301, -139, -160, -126, +111, -84, 181, -174, 43, -237, -96, 111, +-108, 644, -87, 695, -142, -52, -238, -878, +-224, -862, 109, 74, 393, 940, 246, 790, +-211, -116, -468, -627, -337, -264, -87, 310, +83, 211, 106, -349, 143, -442, 218, 248, +87, 929, -381, 625, -714, -467, -453, -1115, +239, -601, 739, 546, 533, 1046, -225, 454, +-797, -406, -649, -580, -32, -106, 450, 249, +368, 84, -24, -104, -314, 42, -263, 348, +-70, 209, 29, -247, -56, -431, -157, -12, +-116, 465, 62, 364, 155, -226, 37, -545, +-244, -134, -385, 518, -169, 592, 193, 4, +247, -564, -46, -438, -334, 118, -293, 458, +39, 254, 229, -126, 48, -129, -349, 92, +-309, 167, 43, -113, 266, -330, 54, -134, +-306, 275, -387, 447, -70, 175, 296, -147, +215, -228, -189, -108, -416, -68, -286, -112, +-33, 55, 205, 365, 264, 502, 43, 159, +-237, -423, -414, -693, -385, -354, -93, 352, +298, 716, 473, 460, 166, -72, -350, -379, +-682, -352, -472, -213, 81, -56, 459, 219, +415, 489, 33, 478, -397, -24, -549, -541, +-325, -571, 70, -61, 310, 426, 233, 484, +-63, 174, -265, -155, -220, -192, -134, -156, +-126, -71, -42, -29, 54, 163, 106, 274, +40, 183, -106, -89, -265, -264, -291, -178, +-107, 50, 143, 210, 260, 147, 47, 63, +-314, -20, -420, -67, -171, -123, 164, -105, +309, 85, 128, 278, -303, 161, -496, -125, +-232, -305, 194, -38, 316, 220, 76, 225, +-210, -38, -285, -176, -147, -24, -95, 114, +-167, 40, 21, -116, 365, 15, 326, 254, +-211, 205, -774, -262, -669, -524, 155, -139, +905, 616, 655, 807, -403, 89, -1026, -881, +-622, -986, 320, -42, 720, 1020, 254, 1071, +-397, 116, -415, -812, -25, -912, 84, -310, +-194, 344, -289, 682, 85, 623, 514, 249, +284, -329, -506, -752, -861, -692, -321, -48, +573, 681, 794, 932, 143, 457, -722, -342, +-802, -879, -98, -675, 518, -21, 470, 613, +-42, 711, -390, 323, -402, -183, -71, -500, +147, -425, 183, -142, 47, 225, -154, 404, +-323, 284, -199, -33, 148, -180, 338, -140, +129, 46, -309, -4, -604, -124, -356, -250, +383, 19, 738, 542, 301, 729, -483, 131, +-886, -925, -523, -1249, 257, -309, 816, 1173, +641, 1643, -146, 564, -843, -1101, -846, -1747, +-99, -820, 618, 792, 720, 1586, 229, 1040, +-453, -253, -762, -1091, -399, -1086, 203, -388, +468, 466, 314, 1001, 5, 989, -287, 226, +-402, -730, -280, -1286, -17, -790, 267, 334, +368, 1258, 180, 1211, -261, 215, -495, -966, +-371, -1371, 50, -717, 347, 557, 394, 1333, +138, 1104, -246, -67, -535, -1121, -479, -1301, +16, -384, 567, 907, 623, 1425, 54, 746, +-673, -667, -853, -1411, -155, -964, 709, 358, +798, 1368, -1, 1246, -685, 39, -711, -1236, +-92, -1484, 481, -435, 557, 960, 67, 1627, +-299, 939, -438, -475, -258, -1559, 18, -1413, +271, -81, 317, 1293, 105, 1675, -198, 658, +-399, -736, -177, -1580, 131, -1164, 172, 107, +-25, 1275, -67, 1422, 35, 469, 206, -752, +58, -1335, -388, -887, -522, 179, -4, 1109, +508, 1151, 448, 302, 36, -820, -331, -1215, +-420, -561, -224, 581, 50, 1144, 151, 704, +251, -337, 335, -983, 92, -769, -385, 81, +-569, 817, -263, 851, 302, 217, 575, -622, +253, -934, -279, -465, -324, 388, -47, 969, +-8, 720, -136, -111, -49, -916, 215, -904, +374, -98, 127, 824, -396, 985, -520, 210, +-36, -691, 469, -927, 341, -241, -92, 596, +-454, 880, -258, 271, 246, -562, 442, -870, +119, -284, -320, 569, -333, 925, -175, 394, +55, -493, 239, -938, 443, -563, 323, 280, +-206, 820, -805, 780, -690, 173, 204, -497, +1036, -924, 879, -740, -203, 1, -1116, 908, +-884, 1290, 311, 643, 1083, -668, 617, -1630, +-568, -1255, -960, 256, -189, 1704, 830, 1722, +837, 271, -157, -1500, -924, -1929, -795, -725, +157, 1095, 872, 1900, 783, 1064, 84, -560, +-433, -1637, -689, -1245, -608, 36, -188, 1243, +542, 1368, 984, 427, 833, -829, -53, -1369, +-1195, -780, -1314, 444, -274, 1377, 1000, 1091, +1166, -173, 551, -1435, -265, -1296, -597, 138, +-582, 1511, -527, 1378, -349, -201, 361, -1520, +1271, -1311, 1271, 207, 14, 1422, -1545, 1221, +-1837, -88, -441, -1086, 1526, -1102, 1962, -192, +548, 565, -1192, 932, -1450, 650, -413, 52, +676, -649, 862, -1065, 265, -663, -318, 339, +-481, 1306, -129, 1120, 246, 8, 461, -1199, +277, -1302, -263, -350, -763, 816, -671, 1233, +268, 689, 1298, -265, 1235, -1018, -87, -977, +-1628, -229, -1783, 767, -146, 1125, 1764, 641, +2012, -466, 433, -1174, -1406, -903, -1877, 196, +-784, 1120, 934, 1045, 1601, 107, 945, -911, +-243, -1052, -1087, -363, -1156, 540, -419, 877, +729, 625, 1323, 8, 1090, -555, -205, -795, +-1547, -558, -1781, 171, -229, 839, 1741, 944, +2373, 222, 821, -626, -1657, -1028, -2769, -576, +-1383, 321, 1196, 963, 2745, 757, 2078, -88, +-281, -697, -2363, -624, -2544, -23, -704, 342, +1502, 347, 2663, 84, 1874, -10, -428, -74, +-2504, -68, -2611, -113, -558, -91, 1940, 30, +2966, 128, 1477, 182, -1280, 23, -2844, -124, +-1886, -165, 500, -5, 2346, 144, 2189, 183, +222, -34, -1749, -183, -2132, -182, -740, 14, +1010, 202, 2029, 175, 1412, 111, -411, -73, +-1936, -104, -1820, -276, -136, -237, 1702, -10, +2298, 428, 864, 640, -1493, 271, -2705, -473, +-1431, -999, 1187, -621, 2865, 400, 2149, 1210, +-570, 892, -2916, -171, -2779, -1145, -39, -995, +2751, -84, 3225, 766, 832, 890, -2282, 403, +-3456, -180, -1560, -649, 1656, -707, 3419, -341, +2232, 388, -796, 883, -3050, 722, -2682, -131, +-105, -907, 2372, -913, 2922, -63, 1146, 876, +-1437, 961, -2875, 175, -2022, -791, 398, -910, +2588, -232, 2831, 662, 677, 870, -2171, 335, +-3232, -516, -1490, -907, 1550, -469, 3369, 417, +2229, 989, -918, 632, -3135, -325, -2557, -1054, +168, -757, 2630, 184, 2868, 997, 698, 901, +-2018, 92, -2959, -797, -1457, -1063, 1235, -454, +3023, 534, 2305, 1159, -457, 820, -2917, -167, +-2840, -1087, -293, -1105, 2521, -272, 3223, 840, +1132, 1336, -1875, 737, -3171, -478, -1802, -1403, +850, -1158, 2798, 8, 2594, 1328, 390, 1632, +-2181, 590, -3082, -1231, -1644, -2126, 1342, -1152, +3531, 1126, 2796, 2564, -528, 1656, -3603, -915, +-3438, -2785, -227, -2057, 3334, 580, 3835, 2730, +875, 2298, -2767, -115, -3693, -2333, -1323, -2330, +2002, -424, 3346, 1703, 1804, 2234, -1100, 934, +-2808, -975, -2143, -2016, 179, -1386, 2330, 285, +2654, 1763, 835, 1812, -1890, 345, -3058, -1504, +-1674, -2172, 1401, -997, 3440, 1236, 2594, 2480, +-685, 1652, -3473, -811, -3275, -2619, -188, -2281, +3125, 146, 3877, 2523, 1367, 2815, -2298, 690, +-4004, -2083, -2459, -3130, 1132, -1545, 3853, 1369, +3560, 3118, 224, 2275, -3340, -481, -4074, -2746, +-1325, -2778, 2541, -415, 4217, 2158, 2352, 2967, +-1495, 1174, -3808, -1424, -2798, -2835, 411, -1855, +3085, 573, 3187, 2509, 797, 2503, -2131, 361, +-3213, -2127, -1721, -3117, 1140, -1302, 3212, 1744, +2760, 3629, -199, 2180, -3038, -1307, -3272, -3931, +-543, -2907, 2703, 826, 3740, 3911, 1416, 3402, +-2200, -283, -3698, -3528, -1968, -3613, 1439, -357, +3536, 2803, 2756, 3554, -453, 1131, -3127, -1854, +-3059, -3306, -485, -1964, 2449, 814, 3474, 2949, +1605, 2718, -1669, 195, -3412, -2524, -2253, -3282, +815, -1073, 3209, 2031, 3028, 3572, 155, 1786, +-2802, -1522, -3308, -3621, -891, -2337, 2373, 972, +3642, 3508, 1738, 2863, -1876, -371, -3682, -3292, +-2176, -3398, 1356, -326, 3673, 2973, 2837, 3888, +-568, 1211, -3366, -2479, -3148, -4241, -209, -2212, +2796, 1746, 3523, 4317, 1424, 3157, -1850, -777, +-3509, -4016, -2404, -3845, 799, -275, 3390, 3333, +3373, 4162, 433, 1283, -2863, -2433, -3684, -4075, +-1334, -2089, 2209, 1459, 3782, 3634, 2198, 2668, +-1316, -467, -3383, -3070, -2492, -3094, 513, -461, +2901, 2490, 2865, 3449, 462, 1336, -2224, -1987, +-2942, -3775, -1173, -2126, 1636, 1516, 3122, 3962, +2134, 2840, -878, -934, -3152, -3951, -2701, -3476, +320, 162, 3073, 3679, 3241, 3949, 557, 744, +-2601, -3111, -3367, -4249, -1142, -1687, 2016, 2303, +3232, 4325, 1855, 2598, -943, -1428, -2744, -4214, +-2250, -3266, 51, 518, 2171, 3837, 2659, 3712, +1040, 430, -1451, -3184, -2781, -4007, -1771, -1489, +933, 2357, 2965, 4179, 2533, 2522, -271, -1392, +-2931, -4205, -2933, -3437, -182, 304, 2832, 3944, +3323, 4137, 910, 823, -2270, -3419, -3344, -4536, +-1559, -1884, 1460, 2596, 3274, 4634, 2464, 2747, +-305, -1574, -2831, -4372, -2992, -3437, -763, 426, +2203, 3900, 3435, 3951, 1843, 694, -1402, -3342, +-3321, -4316, -2367, -1658, 635, 2730, 3041, 4478, +2758, 2337, 128, -2050, -2471, -4334, -2699, -2817, +-627, 1194, 1944, 3910, 2661, 3130, 1171, -252, +-1343, -3296, -2453, -3292, -1488, -683, 813, 2529, +2415, 3288, 1929, 1497, -214, -1695, -2221, -3209, +-2214, -2244, -300, 847, 2006, 3203, 2574, 2934, +1003, -137, -1609, -3266, -2791, -3562, -1533, -519, +1175, 3257, 2935, 3995, 2125, 1157, -488, -2907, +-2802, -4191, -2617, -1881, -202, 2156, 2594, 4034, +3020, 2592, 964, -1125, -1978, -3564, -3156, -3064, +-1690, 1, 1221, 2778, 3194, 3146, 2433, 941, +-349, -1840, -2917, -2889, -2908, -1614, -491, 947, +2480, 2422, 3247, 1881, 1282, -265, -1824, -1851, +-3262, -1892, -1882, -235, 1110, 1242, 3121, 1743, +2346, 711, -334, -701, -2742, -1647, -2621, -1190, +-445, 171, 2277, 1561, 2944, 1745, 1160, 352, +-1735, -1485, -3200, -2256, -1752, -932, 1251, 1190, +3336, 2508, 2324, 1542, -697, -607, -3246, -2432, +-2832, -2114, 67, -223, 2971, 1962, 3196, 2489, +704, 1092, -2352, -1303, -3422, -2572, -1573, -1743, +1600, 525, 3419, 2373, 2270, 2138, -635, 125, +-3126, -2025, -2876, -2286, -254, -679, 2673, 1584, +3176, 2346, 911, 1160, -2009, -1169, -3164, -2428, +-1460, -1641, 1432, 715, 2925, 2451, 1691, 2099, +-870, -190, -2506, -2317, -1903, -2497, 282, -484, +2231, 1968, 2192, 2759, 109, 1198, -2056, -1474, +-2502, -2904, -593, -1877, 1942, 890, 3028, 2977, +953, 2484, -1976, -399, -3214, -3069, -1399, -2998, +1648, 13, 3266, 3189, 1915, 3414, -1272, 206, +-2986, -3289, -2172, -3655, 547, -445, 2430, 3211, +2330, 3730, 90, 737, -1852, -2807, -2129, -3724, +-539, -1293, 1216, 2200, 1899, 3668, 756, 1938, +-959, -1553, -1601, -3657, -656, -2476, 774, 977, +1428, 3560, 674, 2830, -906, -628, -1417, -3440, +-479, -2904, 848, 413, 1259, 3252, 623, 2786, +-700, -426, -1112, -3007, -571, -2438, 375, 408, +649, 2602, 595, 2035, 64, -408, -314, -2099, +-344, -1571, -250, 336, -156, 1520, 52, 991, +407, -291, 476, -936, 214, -373, -373, 380, +-637, 257, -409, -413, 455, -446, 815, 438, +474, 1137, -642, 394, -926, -1197, -298, -1719, +875, -124, 1138, 1889, 92, 1973, -1127, -322, +-1173, -2446, 215, -1982, 1270, 811, 1108, 2866, +-403, 1732, -1152, -1369, -852, -3056, 606, -1344, +1138, 1780, 517, 2949, -852, 857, -898, -2003, +-60, -2565, 908, -427, 889, 1900, -56, 2099, +-854, 117, -774, -1587, 96, -1681, 479, -158, +671, 1203, 377, 1418, 237, 520, -393, -813, +-847, -1433, -1037, -1013, 35, 359, 1579, 1502, +1903, 1526, 317, 93, -1936, -1574, -2326, -1957, +-500, -538, 2196, 1471, 2720, 2301, 551, 901, +-2249, -1389, -2644, -2502, -380, -1238, 2326, 1307, +2783, 2661, 461, 1458, -2378, -1238, -2904, -2753, +-489, -1626, 2513, 971, 3354, 2711, 970, 1865, +-2464, -589, -3670, -2675, -1191, -2209, 2380, 353, +3721, 2602, 1732, 2419, -1895, -340, -3410, -2657, +-1712, -2308, 1495, 470, 2789, 2591, 1738, 1980, +-623, -517, -2031, -2374, -1579, -1697, 119, 383, +1564, 1830, 1745, 1513, 575, 78, -1226, -1132, +-1992, -1484, -775, -864, 1436, 496, 2340, 1598, +1136, 1690, -1381, -102, -2385, -1984, -1172, -2251, +1314, 76, 2344, 2376, 1400, 2254, -510, -228, +-1692, -2411, -1610, -1853, -323, 178, 1284, 1758, +2083, 1334, 1353, 348, -737, -657, -2294, -1124, +-1688, -1256, 756, -311, 2519, 1201, 1844, 1980, +-708, 705, -2319, -1441, -1460, -2118, 979, -592, +2323, 1483, 1469, 1682, -807, 286, -2116, -1320, +-1498, -1182, 626, -128, 2202, 1024, 1996, 1010, +162, 155, -1752, -809, -2311, -1147, -991, -368, +1441, 598, 2838, 1256, 1969, 690, -709, -273, +-2791, -1271, -2398, -1169, 432, -83, 2803, 1276, +2566, 1521, -98, 149, -2313, -1511, -2089, -1420, +185, 351, 2094, 1662, 1990, 700, -26, -1250, +-1807, -1500, -1811, 289, -29, 1943, 2010, 1035, +2367, -1044, 443, -2037, -2148, -656, -2634, 1162, +-518, 1628, 2391, 623, 2923, -813, 880, -1299, +-2070, -780, -2722, 490, -732, 1199, 1975, 780, +2428, -548, 606, -1253, -1570, -539, -1721, 817, +33, 1282, 1599, 280, 1176, -1032, -492, -1394, +-1282, -350, -481, 1109, 979, 1618, 1296, 577, +271, -1041, -998, -1762, -929, -833, -51, 711, +1032, 1497, 1102, 1046, 79, 23, -993, -960, +-901, -1422, 210, -1039, 1269, 585, 1114, 1997, +-439, 1658, -1512, -673, -808, -2342, 996, -1587, +1694, 840, 675, 2085, -1001, 1095, -1508, -587, +-245, -1415, 1087, -965, 1277, -133, 22, 938, +-767, 1306, -630, 792, 327, -930, 701, -1709, +259, -1007, -453, 892, -400, 1740, 171, 1030, +566, -564, 460, -1498, -29, -1273, -408, 7, +-400, 1469, -59, 1592, 224, 176, 729, -1665, +491, -1562, -110, 127, -713, 1650, -554, 949, +90, -497, 729, -1160, 849, -229, 52, 576, +-653, 505, -772, -324, -17, -493, 720, -24, +942, 655, 101, 560, -848, -424, -803, -1081, +224, -552, 960, 986, 599, 1434, -293, 127, +-677, -1594, -141, -1253, 314, 584, 294, 1619, +-192, 507, 72, -944, 427, -944, 292, 298, +-452, 509, -809, -122, -102, -501, 843, 386, +1097, 897, -22, 116, -1032, -1172, -1008, -1151, +184, 325, 1152, 1485, 937, 1227, -230, -552, +-979, -1564, -697, -1313, 244, 555, 773, 1651, +581, 1354, -98, -657, -473, -1654, -272, -1133, +38, 609, 51, 1463, 39, 808, 159, -317, +429, -1212, 306, -793, -229, -60, -1017, 1168, +-594, 1022, 586, 213, 1490, -1395, 790, -1203, +-894, 49, -1821, 1472, -720, 935, 1224, -335, +1819, -1102, 661, -428, -1138, 374, -1717, 251, +-760, 72, 1031, -70, 1719, 465, 924, -59, +-898, -304, -1856, -624, -979, 139, 1121, 288, +2015, 485, 543, 45, -1520, -155, -1720, -507, +34, -462, 1726, 163, 1392, 915, -611, 787, +-1770, -519, -988, -1359, 820, -924, 1545, 879, +914, 1569, -666, 904, -1486, -831, -849, -1541, +566, -1042, 1230, 412, 596, 1450, -374, 1264, +-787, -8, -288, -1371, 280, -1353, 108, -123, +-52, 1157, 0, 1120, 341, 119, -7, -865, +-284, -769, -281, -115, 195, 626, 406, 582, +-128, -58, -590, -626, -424, -362, 612, 368, +902, 560, 345, -46, -755, -543, -1162, -258, +-528, 462, 808, 407, 1305, -271, 492, -605, +-675, -119, -1137, 602, -444, 502, 380, 17, +748, -517, 273, -517, -21, -307, -410, 332, +-406, 693, -301, 655, 462, -180, 699, -911, +57, -707, -913, 88, -893, 663, 461, 580, +1234, 222, 823, -243, -916, -515, -1255, -605, +-569, 5, 860, 602, 861, 618, 388, -125, +-375, -546, -397, -248, -413, 384, -245, 238, +66, -296, 428, -383, 564, 79, 79, 544, +-387, 240, -792, -247, -153, -543, 350, -21, +801, 302, 81, 385, -536, -170, -822, -516, +125, -166, 795, 519, 551, 722, -339, -139, +-745, -904, -339, -603, 209, 458, 494, 695, +317, 161, 245, -289, -175, 30, -622, 167, +-758, -439, 46, -820, 905, -9, 948, 1172, +-49, 1010, -937, -268, -913, -1333, -101, -733, +651, 221, 754, 778, 226, 608, -195, 280, +-614, -219, -536, -879, -185, -812, 439, 52, +807, 1355, 613, 1060, -309, -290, -1258, -1597, +-921, -1169, 498, 525, 1634, 1716, 973, 1271, +-775, -576, -1821, -1866, -724, -1400, 1028, 662, +1483, 1923, 319, 1254, -821, -725, -911, -1657, +-199, -825, 293, 651, 393, 924, 373, 379, +157, -285, -222, -187, -493, -84, -234, -374, +141, -320, 290, 215, 164, 893, 280, 458, +241, -494, -305, -1203, -1007, -390, -522, 707, +774, 1138, 1638, 491, 671, -606, -1228, -1021, +-1921, -712, -683, 186, 1190, 906, 1956, 1129, +914, 191, -807, -897, -1913, -1282, -1327, -429, +327, 848, 1949, 1169, 1654, 308, -152, -655, +-1721, -826, -1626, -117, -34, 596, 1476, 450, +1585, -170, 232, -643, -1125, -263, -1501, 467, +-433, 768, 1041, 113, 1677, -575, 459, -728, +-1104, -126, -1468, 510, -348, 462, 953, 185, +1119, -266, 286, -290, -606, -69, -552, 213, +-335, 76, 77, -301, 215, -400, 357, 125, +388, 960, 163, 702, -310, -608, -690, -1505, +-407, -789, 432, 1122, 1082, 1702, 596, 434, +-628, -1249, -1322, -1472, -472, -129, 1055, 1057, +1502, 1088, 144, 75, -1280, -724, -1156, -863, +36, -179, 1077, 598, 810, 584, 22, 146, +-362, -383, -385, -223, -616, 78, -403, -187, +378, -288, 1211, -3, 1022, 832, -354, 792, +-1542, -470, -1197, -1468, 421, -756, 1670, 1085, +1247, 1627, -449, 370, -1439, -1580, -811, -1432, +560, 403, 1104, 1649, 322, 887, -505, -941, +-549, -1677, 122, -127, 286, 1432, 26, 1323, +-129, -555, 103, -1743, 274, -733, -21, 1221, +-391, 1609, -361, 61, 104, -1492, 605, -1425, +655, 457, 184, 1655, -681, 1100, -1018, -595, +-441, -1735, 798, -1111, 1673, 723, 707, 1830, +-977, 1196, -1773, -780, -615, -2044, 1034, -1242, +1688, 974, 493, 2151, -958, 1110, -1292, -1152, +-319, -2158, 834, -817, 1134, 1242, 162, 1929, +-966, 623, -912, -1228, 246, -1779, 1242, -358, +586, 1184, -711, 1505, -1115, 119, 23, -1168, +1035, -1124, 920, 240, -524, 973, -1021, 668, +-261, -421, 719, -815, 905, -193, 113, 447, +-829, 521, -740, 68, 140, -252, 758, -388, +621, -189, -138, -94, -752, 443, -426, 598, +282, 258, 632, -549, 195, -907, -285, -378, +-424, 583, -55, 991, 304, 514, 420, -304, +153, -996, -218, -753, -346, -80, -201, 857, +274, 1059, 341, 425, 235, -609, -154, -1207, +53, -713, -16, 226, -187, 1058, -552, 1043, +-77, 355, 747, -791, 993, -1474, 35, -958, +-1243, 574, -1086, 1856, 193, 1435, 1347, -476, +960, -1843, -208, -1680, -1207, 66, -773, 1527, +108, 1843, 1106, 685, 1060, -1019, 124, -2073, +-1182, -1514, -1326, 408, -111, 2220, 1324, 2204, +1730, 223, 197, -2088, -1463, -2583, -1645, -867, +-214, 1574, 1151, 2629, 1396, 1421, 445, -773, +-642, -2238, -990, -1786, -663, -233, 16, 1354, +581, 2003, 773, 1356, 555, -314, -93, -2040, +-804, -2350, -771, -570, -295, 1877, 689, 2825, +1023, 1137, 626, -1409, -406, -2578, -961, -1541, +-726, 596, 19, 1898, 848, 1820, 1011, 269, +328, -1120, -550, -1796, -1175, -928, -843, 370, +254, 1317, 1319, 1217, 1253, 348, 184, -418, +-1232, -1093, -1775, -1106, -692, -634, 1027, 566, +2099, 1708, 1289, 1685, -517, 169, -2102, -1891, +-1853, -2659, -59, -906, 1919, 1699, 2114, 3109, +907, 1618, -1204, -1238, -2241, -2916, -1645, -1920, +403, 573, 2010, 1963, 2273, 1739, 608, 210, +-1787, -600, -2623, -924, -1262, -988, 1237, -848, +2536, -103, 1652, 1314, -718, 1902, -2132, 1068, +-1594, -850, 289, -2255, 1470, -1889, 1074, -289, +-54, 1758, -494, 2480, -233, 1706, 21, -586, +-411, -2660, -576, -2906, 27, -867, 939, 2171, +1099, 3627, 225, 2203, -928, -1057, -1388, -3662, +-561, -3146, 450, -269, 1354, 2781, 1007, 3571, +-102, 1563, -1118, -1288, -1128, -3212, -285, -2625, +581, -534, 856, 2250, 569, 3282, 115, 2152, +-360, -873, -800, -3329, -622, -3261, -36, -561, +785, 2708, 756, 3763, 230, 1668, -150, -1800, +-264, -3525, -472, -2137, -885, 1034, -496, 2638, +750, 1701, 1895, -499, 1152, -1412, -990, -692, +-2327, 408, -1471, 349, 613, -514, 1920, -735, +1500, 160, 103, 1334, -1003, 1440, -1215, 128, +-775, -1607, -174, -2120, 457, -1006, 1045, 1101, +1335, 2503, 813, 1983, -775, 51, -2251, -2101, +-2152, -2675, 137, -1554, 2679, 894, 3177, 2854, +763, 2994, -2372, 670, -3758, -2512, -1848, -3786, +1519, -1972, 3729, 1630, 2898, 3782, -450, 2617, +-3556, -591, -3628, -3022, -441, -2703, 3023, -175, +3959, 2089, 1128, 2263, -2498, 448, -3799, -1484, +-1661, -1764, 1846, -173, 3748, 1527, 2146, 1539, +-1399, -360, -3573, -2170, -2573, -1770, 1003, 753, +3496, 2949, 2756, 2480, -460, -656, -3060, -3498, +-3068, -3147, -326, -90, 2442, 3152, 3188, 3637, +1283, 1294, -1773, -1856, -3401, -3636, -2043, -2732, +1246, 139, 3318, 3170, 2326, 3746, -790, 1286, +-2924, -2176, -2275, -3776, 428, -2059, 2494, 734, +2073, 2732, -102, 2336, -1963, 677, -1922, -1189, +-201, -2178, 1647, -1670, 1862, 66, 441, 1728, +-1369, 1687, -1820, 243, -648, -1145, 861, -824, +1693, 247, 994, 648, -456, -314, -1377, -1011, +-1148, -628, -287, 936, 761, 1658, 1212, 1132, +1081, -613, 236, -1843, -1033, -1833, -1824, -377, +-1332, 1281, 552, 2049, 2421, 1515, 2351, 52, +156, -1347, -2267, -2189, -3034, -1710, -1210, -260, +1746, 1895, 3147, 2989, 2000, 2267, -649, -482, +-2651, -3239, -2499, -3877, -435, -1566, 1524, 2160, +2102, 4369, 1370, 3379, 47, -119, -1166, -3331, +-1705, -4124, -1516, -2074, -163, 1077, 1459, 3364, +2376, 3435, 1490, 1499, -586, -1367, -2114, -3304, +-2322, -3247, -799, -1168, 1184, 1619, 2504, 3479, +2108, 3368, 168, 944, -1956, -2324, -2853, -4414, +-1397, -3367, 912, 343, 2734, 4113, 2164, 4739, +184, 1596, -1869, -2813, -2389, -4678, -1041, -2733, +914, 1099, 1849, 3448, 1430, 2776, 143, 316, +-995, -1676, -1430, -1924, -808, -1095, 271, 97, +1131, 723, 1128, 1145, 260, 940, -677, 301, +-953, -817, -524, -1314, -27, -870, 536, 363, +931, 1342, 688, 1026, -172, -43, -1202, -1158, +-1341, -1071, -136, -194, 1217, 910, 1628, 1070, +694, 532, -735, -443, -1688, -1139, -1469, -1029, +-259, -167, 1538, 1021, 2455, 1559, 1306, 751, +-1037, -637, -2779, -1506, -2252, -1207, 247, -117, +2421, 742, 2499, 1085, 817, 1151, -1136, 654, +-2069, -444, -1686, -1800, -500, -2172, 931, -842, +1947, 1748, 1807, 3167, 547, 2337, -1533, -672, +-2500, -3327, -1494, -3474, 673, -849, 1986, 2390, +1629, 3780, 238, 2143, -647, -813, -625, -2810, +-837, -2729, -1083, -864, -680, 1128, 807, 2263, +2279, 1920, 1958, 647, -157, -1033, -2417, -1894, +-2679, -1721, -860, -545, 1582, 969, 2563, 1889, +1694, 1634, -296, 266, -1708, -1202, -1800, -1697, +-907, -1037, 157, 63, 1167, 737, 1642, 839, +1268, 924, -14, 764, -1553, 196, -2130, -1182, +-1145, -2016, 836, -1536, 2021, 505, 1846, 2503, +508, 2517, -1073, 602, -2281, -1953, -1700, -2770, +109, -1464, 2050, 900, 2356, 2076, 671, 1615, +-1598, 51, -2327, -870, -895, -873, 966, -485, +1690, -302, 716, -240, -467, 126, -986, 806, +-274, 1275, 527, 828, 221, -468, -537, -1820, +-624, -1975, 343, -414, 1182, 1699, 966, 2585, +-622, 1461, -1573, -916, -1069, -2389, 460, -2146, +1314, -314, 1079, 1403, 99, 2254, -535, 1612, +-877, 12, -951, -1839, -483, -2593, 447, -1360, +1463, 1129, 1475, 2913, 222, 2290, -1510, -281, +-2108, -2537, -1173, -2618, 982, -658, 2371, 1761, +1993, 2349, -231, 1255, -2231, -646, -2288, -1514, +-407, -1310, 1666, -488, 2144, 230, 585, 856, +-1142, 1273, -1401, 987, -348, -83, 803, -1281, +778, -1645, -241, -742, -1010, 508, -463, 1393, +667, 1332, 1372, 465, 838, -447, -642, -1198, +-1685, -1046, -1452, -586, -153, 136, 1390, 720, +1871, 1243, 1244, 1312, -238, 535, -1559, -1056, +-2158, -2421, -1306, -2108, 273, -33, 2191, 2416, +2776, 3307, 1403, 1570, -1215, -1207, -3156, -3299, +-2883, -2932, -398, -495, 2153, 2011, 3173, 3019, +1961, 2048, -239, 53, -2126, -1751, -2646, -2498, +-1649, -2035, 84, -118, 1904, 1793, 2549, 2573, +1922, 1581, -42, -184, -2163, -1485, -2893, -1699, +-1680, -1459, 621, -720, 2257, 611, 2289, 2128, +1195, 2718, -317, 1144, -1442, -1602, -2202, -3433, +-1846, -2461, -203, 208, 1865, 2674, 2721, 2671, +1570, 911, -302, -984, -1818, -1556, -1956, -1086, +-1257, -528, -344, -240, 780, 190, 1892, 1158, +2298, 1570, 1213, 1011, -989, -487, -2795, -1572, +-3003, -1786, -1034, -895, 1688, 264, 3515, 1650, +2853, 2111, 324, 1309, -2298, -585, -3334, -2299, +-2059, -2296, 164, -667, 2104, 1424, 2464, 2155, +1639, 1422, 95, -264, -1376, -1145, -2100, -1086, +-1762, -527, -680, -28, 907, 116, 2065, 401, +2297, 699, 1110, 698, -870, 293, -2462, -387, +-2567, -755, -1092, -875, 967, -624, 2631, -46, +2593, 788, 1199, 1535, -1054, 1186, -2640, 0, +-2820, -1423, -1102, -1866, 1155, -1235, 2840, 179, +2746, 1552, 972, 2284, -1384, 1531, -2957, -484, +-2368, -2363, -584, -2494, 1375, -843, 2211, 1303, +2079, 2113, 940, 1685, -776, 495, -2279, -748, +-2629, -1804, -1008, -1803, 1315, -632, 2711, 1249, +2022, 1952, 142, 1017, -1356, -427, -1662, -993, +-1132, -393, -276, 107, 380, -195, 750, -804, +1073, -393, 1171, 661, 659, 1647, -658, 1120, +-1948, -230, -2114, -1360, -520, -1640, 1461, -945, +2566, 179, 1573, 1530, -236, 1918, -1621, 1212, +-1659, -704, -985, -1982, 60, -1891, 770, -488, +1066, 997, 1219, 1547, 738, 1234, -132, 392, +-1370, -447, -1744, -1048, -1256, -1137, 479, -685, +1846, 63, 1893, 730, 564, 991, -754, 845, +-1385, 631, -1101, -7, -424, -891, -26, -1963, +439, -1874, 1032, -81, 1316, 2386, 766, 3291, +-318, 1581, -1564, -1410, -2065, -3265, -1121, -2681, +806, -453, 2379, 1776, 2185, 2660, 613, 1970, +-1372, 346, -2311, -1358, -1635, -2233, -234, -1850, +1058, -539, 1733, 1033, 1594, 2051, 627, 2006, +-762, 832, -1725, -1025, -1890, -2276, -846, -2127, +700, -506, 2044, 1236, 1991, 2104, 741, 1710, +-1043, 469, -1982, -1010, -1706, -1979, -458, -1748, +756, -332, 1527, 1189, 1744, 1807, 900, 1280, +-514, 157, -2000, -851, -2073, -1486, -654, -1327, +1243, -251, 2058, 1109, 1477, 1634, -161, 895, +-1285, -505, -1339, -1287, -584, -927, 302, 251, +536, 887, 439, 551, 299, -595, 328, -879, +158, 53, -182, 1214, -719, 989, -825, -508, +-345, -1520, 511, -846, 1045, 642, 777, 1088, +-34, 385, -802, -470, -825, -253, -303, 224, +458, 307, 476, -395, 60, -726, -264, -302, +-19, 584, 271, 919, 508, 355, -12, -519, +-700, -673, -930, -42, -451, 286, 561, 116, +1183, -450, 1274, -180, 55, 516, -1157, 747, +-1727, 100, -1010, -702, 335, -691, 1647, -1, +1842, 582, 741, 284, -936, -201, -1918, -422, +-1640, 22, -259, 550, 1095, 490, 1706, -29, +1354, -760, 277, -814, -789, -208, -1750, 686, +-1588, 1025, -645, 500, 928, -439, 2037, -956, +1908, -539, 551, 187, -1225, 705, -2290, 470, +-2043, -141, -449, -619, 1377, -503, 2500, 247, +2122, 962, 386, 704, -1685, -344, -2754, -1246, +-2189, -1043, -74, 49, 1948, 1101, 2892, 1334, +1823, 653, -319, -509, -2048, -1329, -2411, -1163, +-1457, -160, 107, 749, 1513, 914, 2089, 567, +1696, 275, 422, 107, -1311, -455, -2539, -1227, +-2109, -1335, -374, -53, 1785, 1512, 2532, 1960, +1621, 651, -278, -1032, -1376, -1555, -1508, -852, +-1075, 121, -465, 524, 94, 506, 1006, 422, +1679, 383, 1604, 162, 303, -199, -1354, -608, +-2331, -730, -1859, -405, -347, 282, 1417, 775, +2365, 638, 2095, 124, 513, -251, -1341, -286, +-2553, -286, -2208, -277, -549, -39, 1340, 235, +2325, 147, 1810, -265, 511, -181, -739, 543, +-1354, 1143, -1696, 535, -1503, -964, -730, -1899, +1160, -1276, 2926, 408, 2878, 1730, 609, 1957, +-2298, 989, -3694, -462, -2734, -1903, -1, -2379, +2567, -1226, 3654, 993, 2508, 2651, -147, 2402, +-2888, 420, -3794, -1742, -2252, -2412, 770, -1437, +3079, 332, 3457, 1306, 1452, 1266, -1168, 637, +-2794, 248, -2730, -117, -991, -683, 1054, -1225, +2331, -1099, 2211, -61, 942, 1003, -993, 1409, +-2086, 895, -1855, 67, -574, -617, 900, -928, +1401, -1031, 1180, -788, 583, -75, 172, 1027, +-571, 1903, -1434, 1609, -2015, -6, -1055, -2059, +1106, -2708, 2948, -1146, 2776, 1410, 301, 2572, +-2580, 1472, -3643, -564, -1984, -1281, 910, -552, +2932, 139, 2880, -127, 1132, -726, -1132, -434, +-2429, 523, -2318, 1354, -876, 1193, 766, 341, +1929, -872, 1851, -1702, 1019, -1615, -120, -318, +-1293, 1346, -1983, 2151, -1745, 1404, -367, -198, +1515, -1435, 2436, -1660, 1798, -1014, 58, -200, +-1533, 691, -1942, 1467, -1390, 1749, -215, 940, +692, -847, 1412, -2385, 1435, -2309, 940, -404, +-90, 1766, -1098, 2528, -1733, 1337, -1598, -462, +-433, -1508, 1133, -1454, 2138, -745, 1887, 64, +502, 758, -1161, 1098, -2268, 743, -2008, 20, +-560, -330, 1244, -305, 2279, -382, 1640, -877, +264, -1037, -1142, 71, -1484, 1690, -1262, 2272, +-524, 835, 280, -1412, 1089, -2602, 1385, -1699, +968, 390, 134, 1923, -905, 1992, -1595, 784, +-1502, -580, -287, -1443, 1208, -1460, 2190, -709, +1536, 419, -199, 1281, -1818, 1483, -2053, 716, +-867, -481, 782, -1426, 1780, -1434, 1567, -428, +432, 747, -945, 1315, -1552, 832, -1242, -6, +-147, -585, 931, -524, 1347, -262, 927, -205, +-15, -366, -899, -278, -1013, 481, -511, 1229, +-47, 1112, 186, -219, 338, -1576, 641, -1664, +970, -339, 513, 1090, -577, 1456, -1659, 687, +-1588, -184, -292, -748, 1311, -662, 2092, -348, +1323, 84, -252, 339, -1603, 198, -1550, 38, +-740, 0, 217, 269, 752, 315, 1017, 44, +1151, -353, 727, -539, -397, -350, -1612, -19, +-1874, 344, -455, 661, 1293, 680, 1897, 295, +975, -521, -488, -1123, -1155, -897, -789, 164, +149, 1200, 442, 1236, 121, 186, -407, -993, +-343, -1062, 419, -178, 899, 688, 584, 603, +-463, -34, -1057, -301, -881, -160, 44, 46, +619, -110, 753, -211, 400, 57, -181, 334, +-488, 342, -377, -35, -7, -213, 117, -266, +-45, -170, -135, -333, 86, -364, 325, -90, +275, 600, 28, 1211, -120, 1046, -128, -167, +-198, -1642, -419, -2097, -227, -1104, 415, 795, +1001, 2110, 578, 2261, -367, 1131, -977, -651, +-712, -2361, 92, -2760, 615, -1400, 727, 1120, +377, 2817, -153, 2501, -633, 718, -660, -1080, +-241, -1771, 337, -1593, 668, -826, 598, 117, +168, 1060, -424, 1408, -1093, 1052, -952, 226, +36, -434, 1216, -697, 1525, -650, 494, -550, +-917, -486, -1673, -156, -1071, 537, 165, 1375, +1071, 1381, 1135, 173, 506, -1400, -71, -1864, +-430, -609, -604, 1061, -780, 1464, -683, 306, +-174, -1084, 895, -1156, 1681, 87, 1429, 1332, +-4, 1235, -1598, -6, -2257, -1235, -1314, -1501, +530, -753, 2100, 179, 2279, 983, 968, 1352, +-725, 1134, -1871, 159, -1860, -1146, -992, -1900, +337, -1329, 1530, 185, 2072, 1568, 1262, 1662, +-417, 637, -1772, -672, -1857, -1085, -800, -744, +341, -89, 1118, 325, 1211, 373, 909, 430, +108, 325, -776, 123, -1305, -327, -1093, -620, +-154, -418, 720, 211, 1029, 648, 783, 587, +233, 153, -270, -105, -615, -202, -911, -317, +-773, -619, -132, -571, 965, 48, 1493, 1037, +1112, 1403, -270, 675, -1503, -628, -1651, -1417, +-525, -1113, 866, -230, 1494, 459, 1300, 607, +304, 652, -754, 566, -1385, 314, -1194, -271, +-243, -735, 868, -757, 1247, -476, 886, -176, +212, 34, -322, 435, -791, 771, -1171, 842, +-1092, 297, -183, -431, 1060, -889, 1843, -934, +1386, -538, -100, -37, -1437, 445, -1898, 694, +-1329, 607, -97, 375, 1175, 205, 1881, 65, +1554, -332, 84, -943, -1337, -1321, -1854, -795, +-1034, 493, 163, 1772, 968, 1935, 1001, 821, +659, -818, 299, -1656, -128, -1165, -476, -199, +-830, 362, -638, 211, -121, 296, 511, 752, +692, 1067, 677, 598, 321, -331, -119, -979, +-508, -1004, -626, -695, -444, -268, -61, 271, +319, 885, 420, 1266, 526, 1003, 433, 145, +-112, -952, -823, -1446, -928, -1201, -284, -191, +620, 636, 1058, 989, 464, 760, -616, 267, +-966, -152, -552, -537, 325, -580, 647, -406, +417, 11, -48, 169, -269, 52, -163, -89, +-70, 103, -207, 291, -356, 182, -113, -199, +410, -296, 808, -34, 511, 196, -165, 124, +-677, -176, -587, -299, -273, -365, 75, -109, +359, 351, 640, 871, 617, 838, 158, 97, +-458, -788, -648, -1120, -380, -733, 56, 47, +238, 845, 155, 1230, 92, 932, 77, -83, +308, -1066, 376, -1054, 7, -154, -654, 740, +-982, 669, -538, -90, 281, -517, 973, -199, +827, 484, 71, 675, -378, 199, -469, -494, +-400, -812, -502, -473, -292, 236, 97, 798, +719, 733, 820, 81, 280, -781, -424, -1130, +-678, -631, -325, 539, -20, 1353, 129, 1049, +2, -226, 85, -1219, 349, -1108, 558, -283, +274, 284, -295, 351, -636, 343, -410, 531, +8, 413, 259, -125, 277, -599, 213, -652, +140, -283, 110, -50, 114, 166, -79, 361, +-264, 585, -444, 370, -343, -1, -89, -471, +322, -532, 420, -319, 400, 117, 192, 535, +-78, 574, -428, 120, -600, -536, -468, -609, +-92, 87, 351, 962, 427, 942, 251, -85, +-5, -1153, -23, -1276, -42, -210, -56, 1120, +-248, 1507, -424, 675, -281, -656, 202, -1256, +501, -628, 590, 361, 166, 675, -449, 220, +-546, -367, -146, -400, 428, -13, 545, 347, +228, 518, -335, 348, -608, -175, -322, -762, +148, -935, 546, -529, 425, 255, 202, 788, +-35, 1059, -141, 838, -302, -13, -615, -1189, +-463, -1794, 58, -978, 725, 570, 741, 1568, +300, 1043, -363, -50, -640, -672, -597, -382, +-177, 146, 234, 247, 409, -102, 382, -505, +24, -729, -343, -394, -436, 294, -89, 1045, +258, 1333, 418, 847, 94, -137, -378, -1116, +-545, -1592, -71, -1154, 497, 34, 687, 1155, +264, 1460, -470, 881, -719, 104, -539, -289, +193, -447, 713, -588, 1081, -550, 580, -288, +-447, 8, -1406, 130, -1223, 246, -56, 682, +1129, 1035, 1312, 543, 594, -602, -54, -1363, +-470, -935, -745, 206, -913, 596, -716, 57, +-25, -510, 885, -42, 1319, 979, 935, 1306, +-129, 344, -1031, -1131, -1258, -1763, -618, -1195, +254, 185, 719, 1082, 435, 1102, -23, 422, +-148, -153, 26, -250, 223, -173, 97, -277, +-56, -423, -339, -346, -401, -46, -301, 165, +147, 249, 431, 356, 437, 499, -37, 319, +-298, -262, 49, -702, 550, -527, 413, 148, +-311, 640, -870, 441, -841, -43, -82, -370, +768, -259, 1137, 15, 623, 164, -266, 213, +-756, 132, -444, 153, 77, 166, 152, 229, +-358, -32, -510, -518, 14, -811, 882, -423, +1060, 476, 361, 1064, -680, 760, -1253, -128, +-1030, -763, -156, -586, 830, 64, 1222, 464, +765, 172, -149, -511, -828, -630, -937, -69, +-412, 636, 79, 612, 446, -12, 550, -393, +470, -157, 150, 160, -144, -56, -372, -487, +-368, -479, -341, 98, -98, 528, 251, 362, +482, -29, 434, -125, 146, -2, -6, -5, +-291, -243, -450, -284, -433, -20, 35, 214, +543, 252, 715, 150, 243, 122, -500, 21, +-826, -201, -541, -392, 203, -286, 832, 81, +947, 558, 289, 781, -617, 496, -1149, -338, +-859, -1026, -76, -915, 707, 43, 962, 851, +646, 809, 45, 183, -457, -267, -640, -108, +-550, 108, -329, 28, -101, -359, 263, -553, +640, -382, 900, 109, 548, 626, -312, 862, +-1038, 548, -1093, -232, -344, -957, 478, -941, +1074, -270, 906, 460, 229, 679, -582, 316, +-851, -73, -485, -293, 103, -195, 427, -13, +344, 53, 275, -76, 210, -200, 25, -91, +-405, 139, -670, 129, -501, -135, 212, -154, +795, 279, 891, 588, 196, 222, -575, -670, +-910, -1027, -501, -362, 120, 623, 363, 1035, +225, 447, 45, -311, 208, -560, 371, -100, +247, 378, -328, 296, -787, -287, -761, -746, +-151, -357, 637, 454, 972, 1044, 686, 666, +-129, -225, -827, -747, -842, -587, -241, -23, +542, 361, 745, 508, 480, 343, -93, -73, +-469, -639, -629, -716, -370, -151, 100, 605, +607, 771, 706, 347, 372, -103, -144, -186, +-550, -205, -547, -363, -297, -513, 82, -393, +202, -24, 188, 239, 143, 387, 320, 540, +407, 606, 131, 277, -519, -421, -983, -957, +-624, -776, 238, -121, 947, 354, 854, 277, +123, -44, -625, -122, -768, 157, -379, 507, +166, 646, 440, 400, 395, -214, 228, -861, +119, -1039, -24, -646, -358, 56, -808, 560, +-766, 714, 128, 738, 1197, 655, 1449, 341, +414, -270, -852, -938, -1362, -1045, -729, -434, +201, 461, 714, 849, 490, 502, 145, -180, +-55, -397, -44, -98, 30, 321, -35, 502, +-187, 351, -320, 32, -141, -397, 55, -781, +316, -783, 297, -232, 224, 521, -87, 934, +-270, 659, -410, 54, -294, -381, 49, -353, +383, -179, 525, -69, 179, -178, -167, -266, +-483, -135, -368, 101, -147, 384, 249, 341, +386, 70, 292, -235, -132, -295, -278, -117, +-148, 67, 43, 102, 44, 72, -53, -49, +58, -208, 329, -330, 388, -174, -46, 219, +-545, 538, -696, 528, -342, 164, 225, -273, +762, -670, 897, -736, 543, -338, -204, 450, +-944, 1069, -1144, 903, -609, 70, 299, -723, +919, -814, 1002, -329, 514, 112, -123, 208, +-601, 208, -732, 435, -566, 597, -212, 282, +143, -445, 508, -931, 747, -582, 588, 263, +40, 852, -637, 666, -764, -53, -463, -533, +-7, -428, 323, -4, 412, 189, 366, 6, +198, -161, 18, 7, -240, 327, -335, 360, +-332, 50, -66, -312, 327, -372, 486, -204, +104, -45, -519, -17, -697, -41, -46, -3, +802, 150, 1056, 336, 370, 453, -700, 278, +-1201, -277, -803, -850, 135, -994, 804, -343, +910, 596, 437, 1092, -185, 751, -549, -31, +-559, -603, -202, -632, 120, -250, 297, 144, +150, 316, -18, 158, -29, -98, 79, -207, +210, -104, -11, 112, -334, 326, -435, 458, +16, 369, 383, -159, 395, -794, 2, -916, +-282, -231, -243, 682, -112, 942, -1, 445, +170, -175, 426, -256, 399, -6, -66, 105, +-662, -136, -723, -431, -221, -478, 494, -285, +744, 64, 452, 510, -92, 839, -357, 801, +-250, 253, -21, -487, 35, -975, -212, -948, +-371, -466, -178, 185, 346, 688, 822, 693, +711, 380, 21, 5, -848, -90, -1135, -79, +-655, -227, 480, -437, 1297, -454, 1097, -170, +-103, 235, -1230, 441, -1243, 351, -169, 56, +909, -236, 1123, -238, 453, 77, -463, 345, +-893, 205, -610, -280, 162, -650, 655, -500, +512, -5, -167, 469, -551, 678, -253, 595, +330, 255, 518, -223, 212, -698, -299, -786, +-588, -483, -459, 50, 22, 459, 521, 644, +734, 638, 361, 431, -298, 79, -702, -371, +-546, -710, 75, -868, 474, -651, 378, 11, +-40, 855, -303, 1327, -227, 883, 91, -160, +315, -1056, 287, -1120, -13, -449, -299, 486, +-297, 950, -175, 643, -11, -226, 133, -801, +203, -563, 193, 148, -41, 461, -196, 198, +56, -60, 445, 146, 332, 486, -388, 226, +-954, -467, -726, -886, 246, -613, 923, 24, +914, 479, 295, 574, -261, 547, -599, 366, +-602, 17, -319, -439, 26, -658, 291, -511, +459, -105, 269, 246, -52, 416, -195, 359, +-139, 101, 23, -149, 168, -198, 126, 10, +-222, 210, -438, 162, -351, -155, 129, -450, +521, -436, 626, -15, 180, 495, -291, 542, +-458, 32, -212, -476, 6, -328, 39, 274, +-135, 564, -180, 156, 221, -399, 543, -504, +483, -276, -101, -117, -490, -108, -568, 154, +-179, 651, 126, 860, 399, 397, 361, -458, +136, -998, -226, -842, -333, -193, -151, 417, +47, 700, 117, 474, 24, 34, 115, -301, +130, -198, 170, 186, -78, 342, -293, -13, +-387, -540, -144, -600, 218, -91, 394, 519, +272, 589, -51, 182, -220, -235, -178, -199, +23, 141, 108, 277, 13, -3, -135, -394, +-191, -495, -102, -233, 173, 180, 369, 526, +307, 665, -75, 394, -480, -206, -472, -741, +-11, -684, 451, -162, 456, 341, 73, 472, +-236, 351, -227, 134, -205, -137, -129, -455, +41, -455, 288, -68, 327, 410, 65, 500, +-216, 116, -248, -320, -74, -434, 86, -150, +162, 118, 46, 175, -96, -61, -180, -178, +-66, -11, 161, 324, 143, 414, -46, 36, +-77, -450, 47, -551, 184, -145, 38, 319, +-267, 410, -280, 108, -21, -195, 204, -310, +140, -119, 27, 210, -7, 481, 40, 365, +5, -107, -22, -485, -16, -383, 23, 15, +-93, 182, -269, 61, -154, 23, 234, 212, +406, 315, 171, 128, -99, -139, -234, -230, +-92, -174, 7, -88, 38, 37, 7, 226, +-71, 246, -78, 67, -14, -164, 228, -224, +224, -131, 27, -74, -227, 7, -220, 169, +-99, 345, 116, 349, 276, 127, 220, -227, +-87, -583, -427, -788, -495, -551, -7, 216, +557, 1073, 657, 1234, 215, 424, -369, -707, +-582, -1256, -498, -923, -108, -158, 329, 532, +720, 872, 522, 729, -135, 169, -840, -455, +-752, -707, 86, -538, 834, -190, 787, 119, +66, 407, -568, 554, -711, 376, -374, 17, +211, -234, 614, -238, 524, -298, 47, -436, +-396, -319, -369, 259, -79, 827, 198, 744, +79, 16, -75, -681, -171, -656, 77, -14, +393, 658, 452, 663, -56, -3, -766, -738, +-905, -824, -160, -154, 888, 666, 1265, 923, +536, 506, -661, -141, -1259, -557, -881, -571, +104, -294, 855, 138, 1009, 437, 312, 326, +-365, -120, -713, -380, -429, -122, 62, 362, +336, 433, 199, -53, -114, -540, -72, -534, +111, -41, 299, 478, 119, 583, -155, 152, +-447, -524, -322, -793, 168, -353, 545, 434, +358, 779, -209, 433, -479, -141, -174, -455, +312, -494, 304, -422, -42, -164, -347, 366, +-158, 803, 175, 617, 328, -127, 174, -832, +-115, -844, -296, -195, -212, 551, 78, 862, +140, 535, 27, -108, -181, -612, -121, -596, +112, -190, 327, 232, 345, 341, 140, 222, +-161, 189, -500, 259, -662, 215, -418, -140, +246, -584, 771, -714, 742, -345, 218, 381, +-333, 980, -420, 1030, -255, 350, -179, -633, +-114, -1175, 93, -865, 321, 12, 259, 707, +-56, 745, -226, 265, -182, -182, 81, -207, +265, 55, 252, 102, 65, -200, -118, -497, +-214, -333, -243, 181, -169, 459, -146, 281, +40, -85, 310, -201, 474, -123, 259, -18, +-123, 18, -359, 91, -260, 98, -93, -62, +44, -271, 36, -300, 47, -17, 78, 306, +79, 350, 20, 122, -91, -139, -99, -290, +-74, -276, 126, -164, 193, 137, 191, 460, +-12, 492, -272, 125, -371, -400, -200, -647, +153, -463, 366, 2, 463, 452, 215, 642, +-232, 428, -678, -39, -567, -361, 54, -317, +735, -60, 850, 96, 293, -21, -433, -176, +-767, -144, -659, 136, -188, 451, 381, 444, +675, 36, 517, -496, 30, -561, -302, -101, +-279, 509, -7, 613, 54, 85, -162, -557, +-352, -738, -220, -258, 260, 422, 612, 791, +508, 565, -134, -22, -614, -620, -597, -750, +-120, -372, 457, 207, 680, 521, 325, 428, +-275, 209, -640, 10, -541, -220, -45, -552, +468, -579, 615, -97, 295, 586, -159, 753, +-469, 287, -373, -312, -24, -550, 292, -396, +357, -141, 201, 141, -74, 401, -330, 485, +-345, 272, -187, -178, 96, -568, 308, -618, +429, -300, 329, 259, 86, 724, -327, 768, +-611, 296, -487, -427, -62, -845, 318, -622, +470, 12, 416, 534, 207, 575, -54, 234, +-328, -169, -491, -349, -485, -236, -129, 14, +344, 183, 708, 126, 616, 22, 87, 21, +-605, 97, -892, 28, -510, -154, 303, -286, +963, -239, 784, -13, -15, 255, -791, 476, +-853, 409, -247, -14, 517, -497, 752, -608, +425, -304, -144, 155, -457, 425, -381, 515, +-49, 408, 145, 11, 130, -547, -34, -843, +-51, -541, 65, 204, 220, 787, 284, 811, +90, 339, -237, -215, -453, -542, -355, -551, +-86, -360, 216, -120, 357, 79, 423, 283, +233, 542, -26, 642, -391, 362, -512, -376, +-321, -968, 87, -933, 327, -224, 322, 572, +127, 955, 42, 783, 92, 243, 6, -420, +-299, -878, -583, -857, -425, -386, 133, 316, +768, 811, 828, 908, 337, 487, -478, -185, +-863, -681, -644, -699, 39, -405, 545, -126, +515, 101, 128, 454, -154, 785, -141, 650, +-42, -52, 32, -797, -45, -861, -53, -292, +-24, 364, 72, 561, 13, 368, -49, 115, +-173, -38, -99, -204, 119, -353, 309, -385, +293, -194, 14, 172, -270, 549, -338, 683, +-124, 362, 25, -327, 9, -884, -22, -740, +129, -40, 279, 599, 218, 635, -23, 191, +-205, -208, -164, -267, -123, -67, -140, 93, +-111, 49, 131, -139, 313, -166, 269, 56, +7, 267, -211, 170, -156, -223, -20, -464, +55, -257, -32, 239, -89, 580, -52, 500, +135, 93, 268, -336, 173, -552, -64, -541, +-292, -324, -331, 75, -182, 598, 164, 881, +407, 625, 421, -226, 125, -975, -286, -976, +-553, -165, -380, 754, 31, 892, 350, 203, +367, -567, 214, -628, 74, -26, -30, 527, +-242, 430, -444, -89, -389, -485, -50, -374, +379, 39, 541, 402, 423, 422, 94, 146, +-216, -167, -514, -323, -575, -260, -338, -129, +134, 1, 572, 81, 737, 195, 469, 272, +-141, 324, -660, 208, -727, -147, -339, -494, +223, -571, 562, -234, 487, 228, 163, 395, +-196, 256, -340, 106, -255, 111, -2, 171, +137, -29, 143, -365, 55, -515, -50, -225, +-63, 190, -71, 305, -54, 117, 14, 20, +188, 242, 211, 367, 29, -39, -215, -713, +-332, -848, -166, -149, 110, 819, 267, 1034, +191, 342, 34, -538, -57, -814, -68, -423, +-9, 77, -50, 241, -112, 173, -149, 143, +3, 158, 166, 205, 199, 139, 86, -22, +13, -289, -5, -487, -80, -378, -203, 33, +-236, 365, -85, 370, 146, 190, 352, 84, +348, 82, 151, 6, -205, -173, -486, -338, +-520, -361, -100, -286, 364, -7, 573, 472, +385, 880, 47, 757, -225, -58, -475, -1018, +-538, -1317, -356, -646, 254, 462, 816, 1201, +875, 1126, 158, 432, -663, -359, -992, -859, +-566, -899, 157, -556, 630, -79, 652, 378, +319, 741, -69, 879, -327, 578, -365, -98, +-265, -810, -51, -1025, 113, -670, 160, -25, +87, 588, 49, 887, 105, 705, 220, 125, +95, -509, -210, -779, -460, -561, -333, -100, +147, 366, 569, 643, 469, 575, -148, 108, +-631, -469, -557, -759, 96, -481, 681, 84, +715, 542, 153, 616, -445, 384, -722, -17, +-577, -431, -139, -633, 438, -480, 808, 71, +698, 590, 80, 676, -647, 218, -930, -381, +-502, -630, 236, -255, 658, 325, 578, 566, +153, 160, -148, -395, -246, -438, -171, 27, +-195, 359, -249, 119, -205, -229, 115, -130, +489, 310, 578, 389, 282, -36, -245, -465, +-552, -376, -539, 11, -225, 250, 172, 182, +507, 1, 532, -31, 162, 58, -361, 100, +-521, 23, -227, -140, 258, -259, 451, -139, +183, 78, -216, 232, -354, 153, -202, -57, +36, -165, 245, -114, 246, 27, 212, 136, +31, 154, -205, 64, -452, -136, -392, -251, +-1, -139, 497, 127, 664, 214, 298, 16, +-288, -129, -648, -20, -486, 160, -51, 99, +345, -127, 438, -149, 301, 71, 11, 147, +-195, -45, -292, -235, -188, -154, -71, 128, +82, 322, 242, 250, 341, 30, 195, -233, +-195, -338, -501, -205, -461, 62, 27, 258, +407, 229, 495, 83, 267, -9, 63, 20, +-167, 9, -357, -122, -528, -315, -453, -337, +24, -114, 568, 249, 812, 500, 489, 546, +-130, 342, -680, -105, -708, -614, -249, -925, +308, -692, 596, 59, 381, 876, -172, 1078, +-594, 477, -395, -391, 196, -685, 694, -288, +598, 166, -40, 52, -663, -398, -661, -457, +-215, 74, 258, 721, 390, 788, 287, 248, +129, -464, 13, -804, -42, -542, -143, 101, +-166, 580, -188, 560, -62, 106, 71, -361, +229, -448, 169, -207, 36, 152, -76, 354, +-67, 272, -74, -15, -207, -270, -225, -304, +106, -42, 567, 297, 558, 444, 14, 198, +-669, -274, -812, -607, -340, -528, 405, -32, +738, 498, 617, 726, 56, 483, -426, -36, +-606, -442, -270, -519, 155, -359, 356, -113, +211, 62, -51, 214, -74, 325, 3, 338, +66, 302, -99, 127, -196, -230, -199, -654, +78, -757, 343, -281, 425, 476, 171, 880, +-198, 656, -440, 46, -439, -454, -237, -610, +71, -415, 398, -28, 610, 306, 540, 367, +-21, 128, -616, -177, -851, -218, -397, 47, +227, 325, 663, 293, 561, -102, 149, -482, +-221, -482, -330, -85, -248, 397, -194, 560, +-104, 254, 75, -192, 348, -418, 437, -246, +123, 19, -347, 105, -460, 105, -96, 233, +269, 364, 213, 101, -60, -469, -137, -755, +82, -319, 177, 472, -40, 799, -274, 369, +-154, -282, 179, -493, 324, -144, 135, 208, +-155, 151, -219, -182, -90, -265, 68, 51, +102, 399, 46, 337, -93, -113, -119, -475, +-16, -428, 138, 9, 205, 442, 126, 534, +-38, 199, -190, -250, -212, -479, -125, -291, +51, 80, 165, 272, 131, 110, -14, -193, +-55, -292, 8, -21, 96, 403, 22, 541, +-60, 285, -112, -219, -92, -592, -98, -614, +-46, -292, 135, 159, 315, 437, 291, 414, +-25, 309, -337, 223, -441, 38, -216, -367, +144, -691, 401, -495, 413, 103, 107, 535, +-285, 395, -408, 6, -102, -129, 284, 74, +358, 261, -40, 132, -460, -293, -481, -623, +-9, -529, 574, 19, 747, 647, 307, 801, +-425, 341, -805, -339, -511, -623, 192, -316, +622, 196, 437, 368, -77, 74, -406, -334, +-370, -459, -84, -154, 248, 386, 463, 778, +393, 632, -14, -69, -496, -780, -701, -875, +-313, -280, 312, 376, 709, 579, 536, 336, +-39, -20, -527, -209, -531, -188, -95, -23, +352, 118, 402, 77, 28, -63, -314, -91, +-222, 5, 148, 62, 391, -58, 201, -200, +-214, -137, -504, 82, -375, 263, 63, 273, +428, 129, 533, -98, 311, -282, -72, -289, +-391, -134, -493, 20, -392, 46, -15, 73, +451, 242, 581, 403, 235, 231, -271, -268, +-461, -604, -196, -395, 181, 117, 172, 351, +-89, 194, -116, 44, 147, 98, 375, 121, +234, -88, -228, -316, -637, -261, -585, 26, +-48, 258, 615, 301, 920, 170, 543, -84, +-262, -324, -858, -332, -760, -73, -200, 221, +372, 320, 603, 244, 484, 158, 127, 25, +-274, -225, -541, -457, -373, -453, 98, -128, +441, 300, 376, 579, 12, 563, -240, 229, +-254, -281, -88, -691, -8, -651, 75, -147, +129, 468, 151, 689, 77, 376, -48, -148, +-113, -504, -144, -478, -119, -151, -146, 239, +-52, 406, 184, 259, 442, 0, 447, -75, +88, -28, -490, -172, -823, -464, -531, -488, +144, -13, 694, 620, 741, 815, 345, 447, +-216, -166, -502, -667, -454, -756, -178, -392, +95, 195, 233, 557, 148, 475, 3, 195, +20, 52, 111, -24, 128, -225, -39, -509, +-229, -501, -323, -54, -63, 509, 273, 763, +440, 488, 204, -72, -206, -595, -500, -713, +-409, -334, 26, 286, 395, 645, 487, 457, +246, -24, -86, -279, -373, -178, -356, -79, +-160, -117, 130, -110, 245, 121, 161, 317, +-74, 218, -148, -30, -29, -121, 189, -115, +199, -207, -28, -344, -319, -148, -351, 376, +21, 742, 379, 487, 392, -288, -30, -934, +-400, -857, -385, -51, 64, 797, 422, 964, +426, 320, 49, -474, -337, -808, -506, -526, +-327, -24, 87, 369, 498, 526, 603, 414, +239, 53, -264, -374, -576, -512, -458, -267, +-80, 78, 299, 141, 375, 20, 265, 59, +62, 381, -94, 537, -220, 156, -212, -527, +-159, -903, 35, -621, 203, 105, 190, 787, +-34, 988, -124, 554, 22, -254, 210, -832, +126, -769, -276, -206, -522, 354, -202, 575, +446, 422, 677, 104, 289, -221, -371, -309, +-628, -154, -335, 80, 226, 169, 429, 79, +251, -18, -86, -59, -261, -34, -172, 3, +48, 76, 188, 66, 168, -47, 82, -134, +-112, -49, -274, 145, -296, 160, -11, -78, +362, -279, 499, -148, 128, 178, -376, 283, +-506, 52, -137, -189, 310, -190, 366, -118, +32, -177, -266, -136, -166, 223, 129, 621, +227, 455, 3, -274, -285, -863, -235, -688, +133, 46, 380, 612, 192, 567, -183, 89, +-348, -239, -149, -191, 97, 29, 134, 25, +39, -192, 124, -276, 236, 0, 100, 315, +-257, 318, -490, 47, -310, -157, 158, -115, +534, -27, 444, -11, 81, 13, -318, 133, +-476, 179, -255, 16, 168, -238, 382, -229, +220, 94, -91, 371, -268, 271, -156, -83, +69, -259, 217, -99, 152, 133, 3, 132, +-216, -67, -238, -206, -9, -93, 298, 172, +265, 317, -71, 139, -396, -172, -281, -276, +154, -27, 445, 223, 309, 138, -74, -182, +-343, -357, -390, -218, -179, 47, 93, 262, +356, 330, 382, 271, 260, 56, -38, -202, +-313, -378, -496, -442, -412, -393, -56, -163, +412, 267, 626, 651, 414, 646, -24, 224, +-360, -293, -377, -551, -303, -524, -151, -380, +30, -159, 289, 176, 364, 521, 277, 572, +46, 260, -118, -136, -206, -257, -256, -199, +-280, -216, -176, -301, 111, -185, 425, 199, +519, 497, 247, 432, -254, 84, -621, -167, +-466, -206, 39, -120, 439, -84, 381, -73, +42, 52, -184, 300, -141, 400, -45, 67, +-48, -456, -42, -590, 99, -47, 201, 629, +135, 726, -82, 184, -219, -400, -215, -550, +-83, -325, 50, -45, 164, 156, 251, 275, +195, 287, 23, 173, -128, 10, -137, -111, +-150, -195, -199, -281, -213, -303, -29, -136, +270, 150, 522, 355, 461, 344, 44, 198, +-450, -51, -674, -362, -429, -628, 86, -530, +497, 47, 468, 677, 188, 812, -122, 305, +-243, -411, -247, -860, -126, -741, 64, -112, +200, 646, 144, 913, -74, 421, -188, -374, +-31, -730, 225, -421, 254, 73, -2, 273, +-371, 194, -487, 108, -182, 113, 384, 122, +774, 60, 542, -92, -186, -282, -821, -334, +-766, -108, -100, 326, 538, 579, 577, 395, +190, -62, -118, -384, -147, -387, -57, -197, +-33, 31, -96, 261, -159, 458, -92, 396, +78, 28, 227, -401, 230, -508, 96, -238, +-177, 138, -309, 358, -183, 346, 82, 189, +286, -37, 309, -185, 90, -246, -223, -300, +-386, -330, -269, -115, 15, 409, 222, 794, +262, 522, 189, -261, 162, -826, 35, -745, +-202, -244, -412, 219, -310, 455, -44, 498, +241, 314, 278, -59, 203, -390, 177, -480, +124, -317, -140, -65, -447, 179, -479, 349, +-119, 322, 391, 47, 607, -266, 364, -338, +-185, -147, -567, 91, -495, 196, 17, 235, +521, 222, 535, 19, 71, -374, -443, -575, +-519, -243, -122, 405, 344, 770, 425, 510, +169, -71, -141, -492, -302, -511, -226, -221, +-17, 161, 128, 384, 161, 321, 111, 85, +-1, -86, -69, -93, -21, -17, 54, 48, +12, 51, -127, -63, -241, -223, -158, -200, +175, 176, 419, 582, 299, 495, -90, -142, +-369, -753, -335, -725, -23, -110, 225, 568, +184, 786, 31, 468, -53, -177, -58, -705, +-29, -727, -12, -203, -26, 426, 4, 597, +77, 215, 84, -281, -29, -398, -114, -154, +-110, 138, -6, 219, 127, 90, 146, -110, +48, -251, -38, -208, -67, 16, -127, 171, +-189, 70, -151, -132, 59, -103, 340, 185, +454, 370, 243, 186, -182, -226, -529, -508, +-555, -473, -247, -126, 216, 314, 522, 613, +511, 549, 209, 178, -167, -263, -383, -520, +-358, -476, -150, -171, 130, 262, 294, 524, +242, 436, -29, 53, -323, -283, -356, -312, +-22, -54, 419, 201, 568, 223, 265, 14, +-251, -207, -585, -173, -503, 98, -123, 352, +211, 291, 353, -78, 320, -407, 226, -387, +56, -49, -101, 310, -300, 408, -348, 222, +-223, -83, 45, -330, 256, -360, 324, -131, +232, 171, 19, 261, -198, 61, -311, -179, +-241, -177, -50, 13, 247, 154, 369, 103, +246, -40, -125, -188, -405, -250, -398, -149, +14, 100, 402, 304, 418, 203, 31, -107, +-389, -327, -409, -233, -34, 41, 412, 257, +452, 255, 81, 68, -357, -176, -482, -358, +-254, -326, 186, -59, 454, 348, 388, 621, +53, 505, -290, -8, -422, -571, -222, -735, +147, -380, 362, 179, 257, 504, -45, 479, +-243, 320, -203, 212, -3, 96, 120, -197, +72, -554, -8, -671, -18, -357, 48, 236, +114, 744, 74, 909, -78, 579, -256, -132, +-295, -856, -55, -1050, 314, -501, 489, 402, +281, 972, -191, 790, -482, 58, -366, -633, +3, -771, 282, -317, 263, 277, 38, 511, +-126, 290, -73, -46, 57, -199, 104, -203, +8, -203, -72, -150, -80, 39, -37, 233, +-62, 167, -117, -137, -60, -308, 186, -124, +335, 232, 220, 346, -83, 101, -307, -264, +-284, -415, -74, -257, 119, 41, 166, 254, +94, 248, -63, 72, -141, -124, -57, -122, +187, 53, 308, 219, 174, 172, -138, -113, +-359, -374, -370, -396, -202, -98, 30, 336, +281, 589, 456, 476, 406, 75, 133, -286, +-258, -405, -488, -302, -442, -118, -166, 82, +167, 274, 346, 351, 302, 265, 123, 52, +-21, -115, -22, -173, -19, -152, -150, -132, +-353, -115, -353, -7, 12, 207, 481, 443, +642, 430, 332, 36, -287, -511, -773, -798, +-685, -529, -56, 151, 646, 783, 905, 908, +469, 405, -313, -410, -872, -939, -783, -813, +-146, -176, 534, 440, 823, 577, 488, 292, +-120, -22, -539, -108, -474, -75, -161, -125, +156, -260, 234, -272, 168, -116, 64, 78, +-60, 198, -107, 270, -33, 279, 96, 98, +82, -260, -54, -556, -192, -434, -119, 68, +94, 565, 217, 640, 84, 218, -112, -321, +-191, -544, -77, -332, 111, 45, 248, 266, +174, 261, -81, 174, -298, 127, -276, 67, +22, -33, 267, -110, 267, -114, 22, -64, +-215, -38, -267, -12, -91, 31, 168, 137, +360, 259, 317, 295, -23, 177, -423, -129, +-534, -429, -238, -483, 198, -159, 467, 288, +425, 501, 136, 318, -164, -60, -293, -253, +-230, -184, -54, -29, 71, 0, 38, -122, +-55, -188, -48, -59, 70, 224, 240, 386, +289, 179, 88, -292, -250, -603, -470, -398, +-334, 154, 95, 563, 469, 450, 422, -49, +2, -500, -368, -566, -394, -203, -122, 271, +224, 495, 466, 294, 378, -109, -26, -346, +-481, -256, -651, 13, -281, 180, 309, 144, +615, -18, 410, -168, 5, -140, -250, 70, +-227, 323, -110, 364, -46, 76, -64, -306, +-111, -452, -25, -195, 150, 207, 292, 417, +265, 327, 74, 94, -150, -89, -259, -205, +-288, -193, -248, -49, -84, 186, 245, 305, +511, 156, 445, -148, 17, -353, -428, -192, +-548, 221, -262, 492, 176, 331, 397, -185, +322, -533, 7, -427, -231, 20, -214, 376, +10, 400, 123, 194, 31, -113, -108, -353, +-116, -456, 58, -274, 224, 111, 206, 442, +-33, 434, -297, 69, -375, -320, -124, -480, +321, -310, 548, 3, 310, 201, -223, 229, +-549, 82, -388, -77, 1, -148, 288, -89, +295, 41, 130, 77, 10, -13, -4, -166, +3, -154, -74, 42, -214, 244, -295, 217, +-149, -55, 157, -279, 380, -207, 331, 118, +76, 386, -100, 332, -196, 18, -229, -293, +-244, -376, -129, -194, 119, 133, 339, 392, +305, 382, 99, 192, -97, -28, -234, -120, +-239, -168, -118, -251, 68, -234, 158, -26, +103, 313, 24, 483, 31, 377, 126, 74, +113, -216, -117, -395, -338, -444, -353, -291, +-139, 32, 207, 418, 512, 630, 567, 455, +234, -26, -314, -585, -714, -808, -635, -492, +-168, 161, 399, 675, 668, 617, 538, 115, +95, -417, -405, -556, -562, -340, -331, -21, +88, 195, 336, 242, 320, 227, 155, 99, +5, -88, -212, -294, -373, -428, -310, -351, +7, -59, 393, 356, 473, 617, 243, 543, +-79, 138, -321, -426, -395, -810, -265, -776, +-32, -217, 205, 555, 312, 1021, 272, 880, +141, 210, -37, -526, -210, -937, -298, -795, +-233, -191, -6, 559, 185, 1002, 208, 814, +182, 157, 83, -547, -78, -817, -216, -551, +-205, 43, -41, 600, 124, 707, 129, 363, +39, -169, 46, -466, 59, -376, -3, -134, +-155, 81, -158, 231, 17, 400, 146, 403, +96, 45, -56, -491, -121, -735, -87, -386, +28, 203, 120, 573, 201, 525, 148, 226, +-58, -96, -257, -400, -257, -555, -115, -497, +16, -192, 115, 218, 251, 538, 344, 642, +192, 349, -184, -235, -514, -813, -455, -890, +-22, -335, 422, 406, 499, 819, 258, 608, +-130, 74, -377, -394, -328, -557, -143, -447, +3, -200, 95, 150, 291, 479, 458, 643, +368, 404, -160, -186, -693, -725, -708, -788, +-109, -202, 526, 573, 628, 971, 265, 696, +-213, -39, -386, -688, -235, -893, 70, -487, +242, 266, 180, 888, -52, 933, -177, 371, +-104, -336, 17, -785, -9, -732, -84, -331, +16, 255, 203, 776, 262, 885, 93, 453, +-103, -327, -191, -905, -170, -889, -193, -293, +-129, 486, 77, 902, 326, 719, 393, 54, +153, -580, -159, -752, -361, -487, -344, -59, +-143, 220, 194, 410, 350, 490, 267, 370, +24, -32, -153, -538, -195, -750, -192, -555, +-163, -73, -48, 385, 234, 656, 410, 637, +275, 253, -100, -335, -359, -826, -387, -830, +-188, -310, 86, 407, 312, 896, 392, 788, +242, 150, -103, -602, -419, -870, -441, -464, +-239, 198, 138, 581, 475, 477, 566, 204, +273, -31, -209, -185, -605, -323, -608, -319, +-213, -40, 284, 307, 601, 474, 528, 269, +153, -68, -304, -256, -507, -202, -376, -13, +-43, 79, 182, 102, 288, 152, 308, 237, +189, 186, -74, -149, -401, -539, -404, -554, +-85, 29, 287, 768, 356, 979, 164, 404, +-96, -551, -157, -1119, -143, -955, -111, -176, +16, 721, 113, 1186, 122, 905, 13, -28, +-111, -974, -100, -1267, 39, -681, 89, 321, +59, 983, -49, 895, -81, 159, -26, -585, +85, -819, 145, -458, 47, 128, -129, 453, +-235, 450, -182, 217, -7, -77, 220, -379, +257, -585, 193, -472, 62, 11, -105, 643, +-226, 936, -244, 657, -175, -100, -69, -902, +96, -1206, 240, -809, 333, 170, 249, 1119, +38, 1450, -244, 933, -412, -183, -369, -1194, +-115, -1490, 262, -783, 501, 431, 404, 1316, +-9, 1259, -373, 405, -434, -478, -170, -919, +105, -821, 223, -400, 204, 263, 155, 962, +77, 1169, -79, 548, -233, -612, -271, -1384, +-118, -1158, 70, -144, 216, 882, 220, 1282, +154, 954, 1, 114, -139, -777, -251, -1270, +-210, -1053, 34, -169, 277, 857, 308, 1398, +59, 1021, -258, -77, -424, -1202, -244, -1589, +111, -965, 407, 277, 480, 1410, 348, 1740, +-27, 1025, -486, -437, -764, -1824, -640, -2186, +-35, -1141, 706, 748, 1081, 2205, 767, 2204, +-56, 804, -903, -1017, -1210, -2080, -759, -1831, +202, -553, 1038, 921, 1215, 1759, 620, 1558, +-379, 471, -1132, -840, -1135, -1651, -419, -1448, +539, -293, 1134, 1084, 962, 1809, 267, 1360, +-502, 73, -963, -1219, -922, -1784, -449, -1326, +320, -80, 1016, 1328, 1224, 2077, 682, 1630, +-381, 103, -1381, -1610, -1549, -2385, -672, -1650, +733, 243, 1770, 2056, 1643, 2533, 394, 1275, +-1160, -856, -1909, -2327, -1387, -2119, -3, -521, +1271, 1231, 1677, 2026, 1016, 1522, -165, 188, +-1096, -1187, -1288, -1844, -766, -1376, 86, -80, +773, 1241, 1001, 1746, 751, 1170, 97, -78, +-586, -1251, -979, -1718, -811, -1236, -191, 15, +609, 1337, 1066, 1909, 918, 1263, 159, -272, +-791, -1720, -1263, -2090, -920, -1074, 81, 702, +994, 2034, 1274, 2010, 761, 653, -222, -1138, +-1089, -2176, -1241, -1777, -611, -173, 388, 1561, +1103, 2233, 1077, 1354, 407, -412, -417, -1795, +-917, -1871, -877, -720, -386, 786, 285, 1688, +792, 1476, 784, 367, 364, -919, -176, -1512, +-573, -1067, -649, 51, -439, 1031, -46, 1271, +378, 723, 653, -213, 596, -994, 187, -1188, +-381, -622, -748, 424, -635, 1291, -101, 1312, +495, 407, 686, -858, 415, -1590, -19, -1240, +-343, -7, -455, 1262, -419, 1623, -213, 845, +240, -481, 632, -1398, 615, -1346, 112, -422, +-436, 756, -644, 1395, -434, 1048, -31, -118, +304, -1259, 489, -1467, 451, -525, 190, 836, +-259, 1530, -570, 1105, -534, -63, -140, -1157, +363, -1525, 660, -927, 533, 287, 6, 1393, +-536, 1614, -753, 739, -452, -696, 105, -1699, +639, -1507, 821, -261, 536, 1196, -126, 1802, +-789, 1177, -1010, -254, -554, -1526, 291, -1773, +930, -875, 987, 666, 449, 1882, -344, 1947, +-961, 684, -1016, -1217, -380, -2394, 564, -1948, +1151, -47, 983, 1970, 107, 2668, -854, 1517, +-1309, -750, -919, -2530, 138, -2562, 1204, -745, +1528, 1637, 793, 2885, -483, 2070, -1486, -199, +-1513, -2321, -608, -2835, 662, -1435, 1558, 919, +1514, 2679, 506, 2685, -875, 942, -1698, -1491, +-1406, -3019, -204, -2627, 1103, -456, 1699, 2107, +1204, 3313, -79, 2246, -1343, -399, -1718, -2761, +-916, -3152, 528, -1388, 1575, 1188, 1529, 2798, +485, 2485, -854, 611, -1629, -1576, -1342, -2664, +-140, -1977, 1178, -7, 1709, 1940, 1046, 2531, +-268, 1443, -1374, -604, -1557, -2233, -773, -2361, +457, -930, 1414, 1204, 1497, 2559, 652, 2195, +-631, 253, -1512, -1911, -1481, -2698, -485, -1603, +833, 664, 1687, 2396, 1479, 2409, 221, 685, +-1210, -1433, -1823, -2297, -1165, -1470, 220, 227, +1328, 1440, 1524, 1554, 846, 809, -278, -253, +-1089, -1053, -1290, -1304, -755, -743, 147, 328, +887, 1222, 1081, 1256, 695, 352, 38, -670, +-638, -1151, -944, -816, -791, -73, -168, 559, +466, 825, 857, 611, 787, 147, 355, -380, +-256, -689, -794, -661, -954, -281, -573, 314, +175, 719, 802, 650, 1030, 110, 707, -460, +62, -606, -712, -385, -1193, 10, -1093, 238, +-228, 311, 953, 317, 1640, 282, 1222, 146, +-103, -289, -1444, -773, -1831, -905, -926, -322, +667, 753, 1856, 1535, 1753, 1388, 409, 133, +-1235, -1422, -2099, -2187, -1524, -1529, 106, 321, +1763, 2148, 2230, 2735, 1157, 1366, -814, -1157, +-2266, -3034, -2106, -2773, -333, -392, 1685, 2329, +2432, 3498, 1378, 2143, -734, -751, -2265, -3257, +-2121, -3592, -382, -1355, 1639, 1997, 2465, 4214, +1485, 3493, -589, 219, -2275, -3430, -2328, -4828, +-686, -2823, 1455, 1287, 2625, 4739, 1882, 4861, +-163, 1478, -2145, -3093, -2700, -5543, -1318, -4000, +1049, 305, 2753, 4473, 2577, 5480, 534, 2734, +-1912, -1916, -3134, -5371, -2131, -5109, 368, -1380, +2624, 3468, 3134, 5856, 1417, 4157, -1279, -399, +-3196, -4659, -2775, -5522, -425, -2698, 2307, 1964, +3404, 5148, 2085, 4691, -744, 1027, -3177, -3377, +-3379, -5178, -1181, -3366, 1992, 766, 3864, 4227, +3074, 4605, 39, 1867, -3086, -2229, -4152, -4579, +-2304, -3712, 1114, -224, 3803, 3373, 3909, 4367, +1254, 2313, -2221, -1431, -4127, -3810, -3035, -3302, +71, -462, 3042, 2479, 3771, 3331, 1879, 1855, +-1260, -917, -3448, -2771, -3120, -2566, -634, -503, +2296, 1894, 3465, 2824, 2146, 1786, -651, -698, +-2862, -2663, -2952, -2664, -1024, -623, 1528, 1917, +2982, 2909, 2269, 1826, -21, -649, -2281, -2512, +-2819, -2559, -1247, -720, 1154, 1677, 2644, 2675, +2096, 1733, 34, -666, -1948, -2420, -2368, -2303, +-1038, -382, 988, 1842, 2122, 2452, 1606, 1280, +37, -941, -1456, -2306, -1748, -2002, -911, -268, +525, 1749, 1583, 2364, 1545, 1344, 419, -846, +-1136, -2308, -1820, -2041, -1177, -289, 397, 1744, +1628, 2306, 1673, 1287, 509, -791, -951, -2167, +-1725, -1946, -1312, -350, -51, 1571, 1299, 2163, +1716, 1237, 950, -733, -437, -1914, -1473, -1476, +-1423, 117, -523, 1474, 748, 1291, 1333, 88, +1089, -1169, 186, -1171, -820, -125, -1232, 1052, +-839, 1390, 223, 559, 1071, -693, 1091, -1566, +311, -1255, -752, -2, -1124, 1349, -666, 1776, +255, 769, 832, -839, 806, -1796, 440, -1178, +-175, 425, -612, 1546, -899, 1318, -646, -79, +-4, -1299, 768, -1501, 1197, -445, 734, 937, +-176, 1649, -1034, 1144, -1201, -289, -596, -1568, +386, -1768, 1230, -541, 1231, 1155, 422, 1989, +-727, 1190, -1572, -578, -1357, -1959, -121, -1783, +1384, -121, 2014, 1769, 1248, 2334, -436, 952, +-1935, -1299, -2211, -2678, -981, -1967, 884, 239, +2284, 2370, 2231, 2814, 719, 1229, -1353, -1317, +-2585, -3061, -2029, -2570, -87, -176, 1965, 2460, +2552, 3249, 1358, 1583, -804, -1279, -2305, -3131, +-2047, -2492, -308, 2, 1538, 2480, 2144, 2916, +1135, 1114, -553, -1575, -1778, -2963, -1598, -1911, +-335, 664, 1116, 2675, 1670, 2467, 970, 387, +-390, -1967, -1413, -2770, -1252, -1486, -191, 998, +1009, 2849, 1314, 2510, 571, 136, -671, -2548, +-1418, -3261, -923, -1329, 452, 1809, 1605, 3599, +1364, 2511, -90, -568, -1628, -3301, -1839, -3475, +-593, -1058, 1220, 2254, 2076, 3871, 1394, 2555, +-354, -741, -1930, -3507, -2015, -3507, -614, -857, +1341, 2437, 2249, 3699, 1455, 2193, -422, -984, +-2017, -3343, -2112, -3206, -711, -707, 1248, 2415, +2441, 3673, 1917, 2260, -96, -999, -2142, -3463, +-2633, -3330, -1200, -636, 1136, 2541, 2600, 3595, +2128, 2021, 95, -1153, -1854, -3229, -2321, -2896, +-1135, -322, 827, 2516, 1996, 3290, 1623, 1597, +48, -1454, -1340, -3177, -1612, -2497, -702, 139, +693, 2577, 1471, 2932, 1079, 1187, -231, -1482, +-1274, -2835, -1310, -2137, -244, 222, 1088, 2367, +1599, 2694, 822, 997, -686, -1513, -1678, -2769, +-1537, -1954, -242, 368, 1314, 2284, 2027, 2473, +1344, 892, -354, -1197, -1746, -2268, -2093, -1779, +-923, -129, 842, 1374, 2087, 1918, 1828, 1135, +253, -285, -1401, -1420, -2092, -1490, -1139, -509, +511, 623, 1769, 1150, 1649, 789, 403, 59, +-1065, -512, -1804, -704, -1204, -553, 139, -182, +1464, 310, 1710, 682, 780, 644, -621, 137, +-1598, -467, -1354, -762, -379, -495, 839, -8, +1301, 488, 929, 592, 105, 372, -689, -45, +-849, -484, -607, -506, -25, -250, 370, 344, +503, 544, 379, 304, 98, -258, -114, -606, +-315, -334, -315, 205, -218, 717, 44, 600, +297, 54, 405, -647, 251, -896, -179, -490, +-490, 372, -465, 1085, -71, 1048, 449, 90, +618, -1037, 326, -1383, -261, -543, -577, 863, +-445, 1593, -81, 1057, 280, -527, 385, -1741, +332, -1591, 139, 16, -84, 1788, -309, 2184, +-495, 785, -366, -1510, -59, -2711, 461, -1774, +786, 810, 724, 2898, -2, 2670, -959, 215, +-1336, -2564, -693, -3305, 608, -1439, 1525, 1644, +1393, 3460, 195, 2556, -1163, -375, -1771, -3167, +-1171, -3490, 313, -1101, 1742, 2371, 2005, 4036, +669, 2419, -1324, -1249, -2354, -4078, -1595, -3468, +523, -145, 2210, 3462, 2325, 4177, 501, 1590, +-1641, -2349, -2618, -4520, -1598, -2928, 679, 906, +2425, 4281, 2466, 4039, 442, 735, -1742, -3287, +-2792, -4574, -1614, -2223, 719, 1734, 2602, 4259, +2517, 3259, 330, -67, -1960, -3203, -2916, -3503, +-1366, -1034, 1117, 2075, 2853, 3168, 2260, 1544, +-178, -1180, -2448, -2622, -2894, -1741, -898, 565, +1764, 2197, 3159, 1932, 1964, 84, -747, -1631, +-2865, -1881, -2823, -677, -608, 868, 1968, 1441, +3236, 850, 2031, -180, -658, -697, -2980, -461, +-3089, -85, -791, 2, 2108, -167, 3507, -156, +2057, 321, -906, 646, -3206, 512, -2881, -395, +-309, -972, 2430, -729, 3141, 341, 1205, 1109, +-1537, 704, -2942, -339, -1739, -1196, 878, -671, +2599, 408, 2012, 1280, -492, 661, -2537, -714, +-2281, -1575, 282, -821, 2703, 1063, 2691, 2100, +91, 1165, -2843, -1273, -3220, -2821, -701, -1700, +2644, 1187, 3652, 3361, 1599, 2300, -1901, -821, +-3873, -3381, -2648, -2722, 645, 333, 3442, 2856, +3533, 2692, 1116, 137, -2157, -1817, -3767, -1905, +-2836, -384, 105, 601, 2992, 677, 3928, 430, +2149, 516, -1451, 564, -4017, -242, -3774, -1239, +-452, -1396, 3195, 64, 4497, 1674, 2188, 1859, +-1826, 179, -4273, -1710, -3278, -2046, 149, -497, +3147, 1357, 3603, 1980, 1422, 865, -1514, -759, +-3061, -1578, -2433, -1062, -193, 128, 2056, 1057, +2863, 1111, 1362, 319, -1248, -787, -2732, -1257, +-1859, -583, 637, 774, 2409, 1474, 1929, 674, +-343, -919, -2046, -1734, -1692, -714, 237, 1032, +1758, 1826, 1514, 724, -255, -1094, -1839, -1912, +-1625, -1070, 303, 693, 2105, 1929, 1971, 1748, +18, 210, -2187, -1705, -2400, -2481, -545, -1380, +1958, 1006, 2547, 2761, 897, 2232, -1426, -141, +-2438, -2439, -1118, -2412, 947, -420, 2160, 1723, +1335, 2057, -404, 687, -1696, -840, -1673, -1407, +-409, -884, 1029, -11, 1908, 702, 1414, 1184, +-85, 974, -1707, 34, -2275, -1408, -1032, -1774, +1024, -461, 2514, 1566, 2094, 2181, 65, 487, +-2057, -1588, -2658, -2037, -1259, -202, 1142, 1594, +2688, 1724, 2125, 155, -283, -1362, -2503, -1570, +-2511, -757, -156, 739, 2493, 1845, 2747, 2033, +253, 153, -2678, -2527, -3052, -3549, -481, -1118, +2687, 3081, 3348, 4696, 1181, 2018, -2114, -2874, +-3499, -5104, -2164, -2989, 922, 1498, 3270, 4451, +3085, 3807, 517, 508, -2666, -3038, -3603, -4286, +-1701, -2352, 1771, 1411, 3687, 4113, 2434, 3351, +-900, -246, -3434, -3560, -2842, -3735, 215, -594, +3018, 2923, 3147, 3808, 424, 1336, -2547, -2247, +-3317, -3724, -1185, -2040, 1846, 1292, 3306, 3288, +2076, 2595, -1057, -47, -3123, -2489, -2696, -2943, +216, -1195, 2847, 1643, 3117, 3357, 510, 2304, +-2535, -912, -3280, -3668, -1281, -3014, 1904, 418, +3306, 3585, 2144, 3216, -877, 102, -3154, -2779, +-2856, -2857, -345, -463, 2675, 1722, 3337, 2316, +1389, 806, -1973, -899, -3494, -1768, -2079, -1108, +1173, 391, 3321, 1385, 2396, 1280, -447, 75, +-2864, -853, -2377, -1090, 113, -445, 2213, 88, +1919, 408, -46, 458, -1590, 476, -1297, 422, +120, -7, 1027, -629, 722, -1119, -125, -683, +-484, 393, -240, 1348, 85, 1158, 62, -133, +-195, -1279, -332, -1425, 67, -353, 664, 957, +903, 1490, 171, 927, -1033, -465, -1634, -1524, +-563, -1510, 1199, -183, 2179, 1303, 1009, 1715, +-1263, 675, -2357, -869, -1302, -1391, 1048, -786, +2266, 296, 1518, 790, -780, 670, -2016, 111, +-1485, -308, 376, -452, 1764, -164, 1373, 238, +-129, 281, -1462, 58, -1232, -283, -62, -154, +1163, 128, 1172, 415, 236, 189, -887, -157, +-1167, -447, -383, -416, 620, 122, 1087, 589, +498, 827, -318, 200, -847, -764, -476, -1061, +-37, -396, 368, 682, 336, 939, 395, 292, +302, -308, -170, -308, -660, 43, -843, -74, +-133, -419, 805, -407, 1186, 268, 479, 880, +-797, 478, -1344, -442, -694, -1014, 560, -480, +1293, 566, 855, 966, -232, 434, -1008, -497, +-777, -975, -139, -669, 485, 88, 533, 648, +503, 938, 107, 564, -388, -202, -703, -1103, +-460, -1350, 278, -303, 768, 1113, 601, 1863, +-290, 670, -746, -1057, -432, -2077, 270, -1088, +510, 865, 219, 2005, -108, 1560, -352, -281, +-100, -1739, 86, -1929, 172, -569, 85, 1243, +-38, 2189, -41, 1348, -82, -578, -25, -2031, +-201, -1772, -94, -28, 98, 1690, 565, 1965, +534, 581, -146, -1242, -859, -1964, -859, -944, +-16, 887, 882, 1845, 993, 1302, 236, -421, +-609, -1518, -970, -1408, -530, -217, 362, 1007, +939, 1372, 767, 907, -160, -209, -1013, -1235, +-894, -1503, 192, -582, 1026, 943, 816, 1803, +-302, 1172, -955, -585, -582, -1813, 304, -1493, +806, 107, 543, 1635, -226, 1535, -693, 241, +-506, -1314, -20, -1569, 384, -631, 515, 764, +260, 1398, 58, 1005, -229, -49, -422, -1125, +-638, -1300, -361, -796, 572, 549, 1251, 1373, +793, 1286, -498, 52, -1492, -1187, -1201, -1387, +162, -465, 1365, 783, 1403, 1171, 438, 735, +-874, -373, -1454, -981, -1111, -921, 210, 11, +1475, 969, 1541, 1232, 285, 287, -1286, -972, +-1598, -1485, -737, -538, 908, 1027, 1635, 1604, +1015, 808, -512, -769, -1585, -1502, -1271, -966, +105, 282, 1444, 1227, 1478, 1185, 335, 421, +-1122, -654, -1461, -1252, -861, -984, 409, 23, +1392, 1120, 1367, 1234, 269, 387, -1164, -673, +-1573, -1064, -616, -477, 790, 253, 1298, 625, +584, 476, -359, 10, -741, -278, -325, -488, +-35, -227, 79, 101, 192, 477, 324, 348, +292, -87, -136, -434, -292, -462, -444, 3, +15, 362, 128, 482, 262, 92, 215, -406, +106, -677, -33, -290, -297, 406, -273, 841, +-249, 546, 290, -246, 305, -869, 367, -795, +-58, -268, -414, 521, -353, 972, -97, 751, +433, 19, 302, -937, 93, -1016, -329, -344, +-165, 658, -74, 907, 103, 443, 99, -269, +3, -518, 177, -374, -68, -107, -133, 218, +-197, 439, 21, 400, 202, -113, 177, -509, +-28, -450, -43, 335, 19, 608, -181, 170, +-322, -621, -188, -556, 415, 352, 731, 1021, +279, 455, -565, -832, -822, -1238, -225, -375, +483, 1133, 562, 1224, 50, 203, -200, -1053, +-51, -907, 63, 81, -274, 737, -316, 342, +-47, -440, 692, -328, 660, 264, -59, 670, +-1000, 36, -1072, -797, -48, -725, 1166, 163, +1474, 771, 465, 543, -1000, -250, -1927, -424, +-886, -95, 743, 191, 1888, -83, 1199, -462, +-437, -356, -1577, 280, -1154, 868, 166, 558, +1096, -101, 973, -854, 73, -850, -626, -200, +-734, 439, -358, 784, 187, 349, 529, -108, +594, -291, 320, -25, -405, -23, -848, -383, +-679, -631, 351, -136, 1151, 1083, 796, 1459, +-470, 351, -1412, -1573, -672, -2230, 629, -505, +1450, 2073, 506, 2766, -607, 654, -1098, -2327, +-479, -3006, 232, -605, 428, 2355, 500, 2858, +446, 587, 344, -2118, -463, -2446, -1068, -466, +-1010, 1701, 234, 2135, 1459, 503, 1442, -1386, +67, -1974, -1422, -616, -1623, 1271, -390, 1966, +1101, 656, 1454, -1330, 661, -1875, -521, -531, +-957, 1361, -782, 1695, -311, 259, 236, -1349, +849, -1443, 1054, -193, 507, 1209, -647, 1330, +-1553, 308, -1079, -971, 276, -1507, 1397, -604, +1352, 737, 342, 1536, -760, 790, -1322, -573, +-979, -1329, 12, -797, 1161, 463, 1350, 1020, +393, 588, -981, -474, -1465, -1002, -463, -508, +1035, 470, 1338, 1197, 361, 838, -952, -306, +-1223, -1337, -439, -1270, 681, -177, 1095, 1051, +676, 1404, -337, 783, -883, -224, -788, -1051, +-82, -1124, 658, -670, 791, 363, 238, 1112, +-387, 1313, -495, 508, -321, -719, 8, -1571, +111, -1300, 197, 143, 311, 1582, 424, 1970, +213, 668, -453, -1266, -994, -2311, -754, -1465, +311, 589, 1317, 2212, 1184, 2076, 33, 416, +-1364, -1484, -1373, -2302, -165, -1417, 1107, 365, +1220, 1988, 239, 2137, -760, 775, -962, -1228, +-254, -2375, 421, -1651, 594, 307, 283, 2067, +-80, 2000, -196, 389, -256, -1304, -150, -1800, +-159, -822, 28, 286, 221, 961, 374, 926, +292, 648, 45, 199, -429, -654, -662, -1342, +-498, -1284, 130, -71, 1010, 1436, 1061, 1931, +256, 977, -1041, -885, -1473, -2105, -703, -1761, +741, -29, 1500, 1808, 1114, 2160, -161, 854, +-1265, -1099, -1385, -2058, -581, -1394, 869, 154, +1588, 1363, 1198, 1590, -306, 978, -1537, -115, +-1524, -1312, -350, -2011, 998, -1357, 1369, 538, +891, 2487, -117, 2660, -671, 717, -962, -1948, +-706, -3221, -292, -1975, 478, 629, 1027, 2679, +1100, 2772, 296, 976, -842, -1172, -1481, -2590, +-968, -2240, 358, -540, 1455, 1591, 1388, 2754, +172, 1939, -1210, -280, -1485, -2462, -677, -2700, +715, -879, 1394, 1616, 963, 2791, -75, 1733, +-874, -482, -953, -2211, -643, -2321, 51, -792, +624, 1117, 1128, 2327, 906, 1859, -102, 124, +-1343, -1698, -1541, -2218, -433, -1082, 1236, 647, +1757, 1700, 747, 1208, -871, 154, -1680, -673, +-997, -695, 459, -275, 1485, -152, 1214, -105, +10, -78, -1246, 324, -1468, 650, -420, 469, +846, -152, 1526, -793, 874, -608, -508, -17, +-1269, 616, -1104, 609, 115, 49, 1009, -260, +1017, -382, 60, -68, -669, -77, -719, -113, +-158, -121, 245, 312, 240, 716, 262, 693, +411, 46, 429, -965, -307, -1376, -1197, -949, +-1265, 359, 128, 1697, 1763, 2078, 2095, 977, +415, -1071, -1865, -2743, -2815, -2534, -1127, -264, +1587, 2549, 3197, 3665, 1935, 1976, -1119, -1530, +-3261, -3944, -2536, -3425, 466, -170, 2887, 3275, +2876, 4260, 350, 2019, -2133, -1727, -2840, -4152, +-1193, -3526, 1180, -139, 2537, 3091, 1734, 3954, +-388, 1696, -2062, -1627, -1800, -3245, 94, -2196, +1543, 228, 1424, 1815, -143, 1578, -1306, 382, +-950, -379, 451, -363, 1243, -160, 898, -380, +-477, -749, -1521, -730, -1367, 113, 109, 1072, +1697, 1581, 2195, 1085, 677, -379, -1624, -1842, +-2808, -2427, -1659, -1252, 1158, 1163, 2989, 3181, +2368, 3035, -374, 425, -2605, -2900, -2721, -4251, +-453, -2235, 1841, 1607, 2411, 4356, 1243, 3640, +-806, 268, -1667, -3235, -1562, -4027, -460, -2036, +688, 1234, 1455, 3347, 1379, 2977, 422, 939, +-977, -1707, -1857, -2808, -1177, -2318, 278, -335, +1726, 1636, 1658, 2625, 401, 2054, -1273, 77, +-1777, -2043, -918, -2989, 701, -1586, 1611, 1064, +1179, 3034, -180, 2495, -1220, -23, -1186, -2372, +-247, -2660, 659, -868, 957, 1314, 657, 2268, +-56, 1445, -584, -266, -854, -1650, -616, -1708, +95, -468, 790, 1089, 1053, 1721, 582, 941, +-405, -679, -1208, -1698, -1182, -1388, -296, 108, +1047, 1538, 1611, 1825, 976, 711, -487, -866, +-1719, -1974, -1627, -1707, -248, -386, 1377, 1368, +1919, 2416, 1231, 1793, -630, -208, -1843, -2348, +-1835, -2699, -466, -1048, 1203, 1442, 1887, 2611, +1322, 1922, -114, 25, -1216, -1597, -1611, -2191, +-1001, -1513, 44, 94, 1194, 1825, 1665, 2433, +1145, 1311, -204, -774, -1488, -2247, -1899, -2062, +-1115, -625, 438, 1019, 1825, 1939, 2196, 1782, +1188, 561, -945, -1021, -2486, -2003, -2472, -1581, +-478, -93, 1776, 1197, 2750, 1561, 1605, 928, +-329, 78, -1851, -634, -2133, -1046, -975, -1032, +407, -449, 1659, 315, 1757, 992, 761, 1206, +-536, 906, -1454, 134, -1435, -1152, -779, -2049, +285, -1707, 1301, 196, 1825, 2282, 1234, 2903, +-517, 1241, -2063, -1415, -2263, -2960, -732, -2498, +1472, -218, 2384, 1932, 1710, 2769, -246, 1743, +-1762, -266, -2038, -2133, -830, -2525, 717, -1316, +1710, 864, 1504, 2549, 180, 2290, -1057, 299, +-1576, -1980, -895, -2571, 470, -1040, 1416, 1222, +1112, 2136, -124, 1241, -1070, -447, -918, -1337, +71, -1016, 673, -142, 386, 406, -180, 607, +-250, 471, 263, 235, 357, -40, -110, -499, +-812, -598, -579, -521, 315, 201, 1128, 780, +929, 1008, -244, 271, -1230, -694, -1187, -1143, +-117, -699, 953, 240, 1269, 747, 507, 798, +-372, 484, -780, 294, -743, -231, -396, -993, +-24, -1609, 392, -1069, 875, 793, 982, 2643, +386, 2692, -680, 349, -1405, -2713, -1371, -3876, +-186, -1991, 1122, 1556, 1849, 3822, 1169, 3228, +-300, 397, -1460, -2307, -1474, -3214, -539, -2040, +447, -56, 863, 1787, 649, 2354, 546, 1760, +304, 357, -46, -1121, -704, -1795, -1150, -1878, +-1023, -1053, -102, 213, 1078, 1920, 1843, 2737, +1440, 1886, -91, -626, -1825, -2986, -2435, -3203, +-1269, -1134, 858, 1680, 2361, 3016, 2155, 2263, +690, 249, -1085, -1413, -2053, -2082, -1982, -1695, +-795, -701, 877, 606, 2330, 1864, 2372, 2260, +812, 1274, -1552, -751, -2881, -2413, -2188, -2399, +50, -764, 2256, 1221, 2503, 2063, 1259, 1598, +-767, 459, -1683, -590, -1557, -1196, -633, -1458, +136, -943, 668, 133, 1117, 1297, 1108, 1554, +770, 697, -324, -362, -1258, -1003, -1697, -759, +-1111, -438, 202, -57, 1487, 239, 1939, 556, +1310, 710, -245, 499, -1523, -31, -2070, -530, +-1250, -887, 21, -719, 1419, -236, 2045, 604, +1632, 1119, 275, 1015, -1514, 211, -2463, -875, +-2088, -1334, -39, -958, 2068, 119, 3002, 1021, +1637, 1140, -817, 442, -2635, -425, -2346, -750, +-494, -417, 1400, 110, 1939, 164, 1114, -104, +66, -247, -952, 130, -1088, 487, -916, 511, +-128, -2, 697, -422, 1007, -426, 765, -300, +-41, -29, -570, -13, -872, 205, -524, 480, +-104, 654, 495, 363, 768, -447, 566, -1238, +54, -1173, -381, -87, -574, 1311, -479, 1798, +-248, 920, 123, -671, 527, -1808, 734, -1596, +420, -381, -199, 1156, -770, 1800, -875, 1226, +-277, -181, 532, -1388, 998, -1467, 767, -382, +-160, 747, -910, 1100, -908, 379, -285, -444, +542, -504, 799, -37, 476, 546, 109, 321, +-496, -219, -569, -756, -487, -611, 134, 61, +483, 781, 515, 966, 109, 318, -350, -470, +-294, -932, -119, -612, 113, 49, 33, 416, +111, 437, 10, 202, 90, 111, 79, 129, +-43, -6, -147, -372, -326, -666, -173, -460, +142, 234, 580, 815, 449, 711, 6, -78, +-613, -584, -615, -572, -202, 54, 264, 412, +562, 229, 437, -174, 91, -405, -305, -199, +-532, 262, -330, 519, 215, 405, 457, 29, +228, -536, -245, -747, -408, -447, -95, 280, +315, 921, 482, 854, 218, 184, -152, -579, +-483, -885, -597, -756, -400, -261, 124, 366, +787, 973, 1055, 1298, 695, 802, -276, -387, +-1334, -1655, -1687, -2063, -773, -1047, 792, 871, +2107, 2376, 1924, 2526, 346, 1014, -1492, -1175, +-2314, -2873, -1604, -2911, 107, -1131, 1576, 1610, +2183, 3520, 1418, 3125, -162, 609, -1635, -2321, +-2109, -3587, -1230, -2423, 312, 73, 1598, 2259, +1900, 2776, 1050, 1681, -398, -229, -1577, -1742, +-1694, -2051, -631, -1165, 763, 324, 1494, 1263, +907, 1233, -235, 366, -833, -362, -602, -506, +208, -141, 537, 106, 280, -51, -397, -363, +-722, -522, -476, -122, 194, 440, 942, 877, +1039, 711, 604, 113, -483, -538, -1398, -1017, +-1506, -950, -676, -424, 818, 607, 1867, 1417, +1898, 1368, 558, 273, -1178, -1059, -2269, -1583, +-1972, -965, -331, 216, 1447, 915, 2402, 891, +1807, 455, 173, 156, -1518, 2, -2279, -275, +-1713, -831, -101, -1096, 1505, -613, 2144, 563, +1443, 1578, 48, 1556, -1275, 441, -1709, -959, +-1261, -1634, -365, -1323, 757, -346, 1462, 561, +1610, 1175, 770, 1374, -617, 1010, -1664, -6, +-1847, -1217, -696, -1871, 753, -1307, 1765, -39, +1624, 1155, 485, 1648, -871, 1394, -1603, 595, +-1386, -601, -295, -1683, 1011, -2033, 1598, -1107, +1173, 554, -146, 2007, -1403, 2182, -1607, 1076, +-557, -632, 726, -1840, 1551, -1969, 1171, -1005, +151, 504, -843, 1577, -1423, 1640, -1222, 712, +-184, -463, 1017, -1020, 1752, -939, 1311, -445, +-96, -65, -1411, 222, -1724, 489, -932, 681, +293, 707, 1277, 267, 1285, -389, 743, -1055, +-120, -1193, -781, -549, -881, 549, -721, 1473, +-414, 1583, 64, 605, 553, -807, 1123, -1892, +1213, -1705, 598, -460, -662, 1168, -1707, 1975, +-1861, 1571, -839, 285, 868, -1144, 2054, -1826, +2127, -1485, 858, -287, -804, 1073, -2079, 1749, +-2056, 1352, -1050, 259, 595, -933, 1737, -1489, +1971, -1325, 1174, -420, -125, 707, -1147, 1556, +-1719, 1495, -1518, 418, -799, -963, 523, -1707, +1856, -1219, 2403, -7, 1456, 1090, -589, 1297, +-2489, 735, -2749, -189, -1282, -878, 990, -884, +2571, -336, 2497, 257, 898, 484, -1121, 274, +-2338, 114, -2065, 88, -451, 76, 1127, -168, +1907, -371, 1342, -304, 196, -56, -846, 282, +-1292, 256, -993, 173, -217, 60, 688, -97, +1086, -151, 837, -171, -25, -63, -831, 81, +-1017, 121, -533, -48, 379, -65, 1053, 59, +1010, 284, 147, 284, -783, -129, -1287, -592, +-730, -604, 184, 2, 938, 722, 1085, 959, +563, 319, -54, -639, -728, -962, -935, -604, +-928, 228, -184, 686, 582, 605, 1288, 285, +1119, -86, 263, -455, -843, -568, -1433, -354, +-1089, 115, -29, 497, 988, 490, 1287, 202, +881, -35, -91, -296, -848, -489, -1153, -432, +-747, -145, 82, 386, 752, 687, 1020, 603, +564, 124, -53, -434, -650, -915, -750, -785, +-439, -117, 105, 705, 532, 1082, 438, 616, +141, -181, -245, -614, -215, -646, -75, -460, +155, -272, 210, 87, 24, 749, -251, 1102, +-405, 569, -251, -577, 197, -1372, 567, -1039, +601, 214, 76, 1209, -404, 1144, -659, 110, +-496, -950, 38, -1081, 417, -211, 593, 663, +286, 834, -246, 263, -443, -255, -121, -267, +289, -129, 349, -222, -94, -378, -545, -244, +-475, 237, -53, 621, 320, 627, 624, 409, +560, -4, 303, -543, -113, -1052, -726, -985, +-936, -234, -717, 896, -27, 1398, 750, 1099, +1324, 254, 1102, -715, 184, -1238, -952, -1343, +-1716, -692, -1249, 447, 29, 1440, 1334, 1550, +1653, 759, 913, -467, -455, -1297, -1203, -1279, +-1164, -613, -385, 284, 435, 786, 578, 555, +473, 223, 305, 233, 287, 528, 85, 420, +-339, -474, -768, -1471, -745, -1492, -234, -450, +382, 865, 781, 1688, 820, 1587, 469, 813, +-108, -401, -676, -1553, -989, -1978, -629, -1281, +-53, 129, 551, 1410, 732, 1885, 656, 1342, +410, 226, 39, -910, -507, -1576, -1099, -1326, +-1022, -420, -263, 568, 868, 993, 1377, 778, +955, 325, 77, 53, -691, 42, -902, -155, +-776, -464, -509, -848, -99, -761, 640, -120, +1225, 747, 1195, 1227, 259, 895, -917, -18, +-1426, -836, -1058, -913, -57, -446, 731, 241, +907, 523, 706, 337, 390, -119, -41, -380, +-512, -251, -949, 286, -898, 567, -226, 420, +655, -64, 1061, -497, 862, -612, 229, -422, +-342, -6, -749, 476, -1048, 714, -778, 297, +-31, -274, 1000, -543, 1477, -160, 1157, 376, +-205, 368, -1380, -193, -1663, -506, -890, -359, +574, 73, 1502, 299, 1408, 201, 382, 264, +-837, 426, -1375, 266, -896, -259, 12, -844, +883, -888, 1049, -327, 603, 445, -75, 871, +-683, 918, -927, 505, -827, -201, -186, -692, +597, -844, 1366, -480, 1265, -9, 239, 133, +-1004, 117, -1613, 182, -1114, 531, -51, 939, +834, 878, 1170, 52, 969, -1189, 478, -1968, +-302, -1598, -858, -85, -1139, 1552, -884, 2240, +-183, 1656, 609, 253, 1298, -1005, 1328, -1557, +612, -1394, -651, -881, -1563, -208, -1569, 493, +-442, 1229, 874, 1634, 1476, 1314, 1087, 317, +172, -980, -684, -1811, -873, -1765, -612, -960, +-251, 222, 216, 1301, 408, 1916, 502, 1777, +349, 709, -16, -921, -309, -2176, -239, -2161, +-106, -828, -17, 871, -88, 1842, -181, 1492, +89, 484, 347, -514, 268, -902, 84, -682, +-190, -300, -214, 113, -60, 277, -83, 185, +-72, -37, -1, -118, 102, 12, 225, 339, +157, 357, -87, 20, -265, -325, -123, -370, +61, -48, 297, 172, 178, 83, -182, -236, +-317, -286, -277, -64, 177, 376, 397, 657, +277, 462, -116, -36, -336, -586, -283, -799, +3, -474, 372, 68, 289, 519, 46, 674, +-327, 391, -393, -23, -134, -369, 261, -451, +412, -171, 233, 211, -59, 268, -311, 43, +-340, -316, -286, -362, 62, 26, 465, 399, +595, 484, 453, 234, -234, -93, -782, -379, +-987, -371, -457, -370, 404, -76, 1067, 234, +1166, 437, 548, 381, -380, 102, -1170, -244, +-1209, -343, -656, -121, 225, 106, 916, 287, +1073, 3, 695, -365, 171, -464, -464, -147, +-767, 424, -719, 779, -526, 623, -110, 42, +316, -601, 626, -984, 891, -826, 694, -121, +98, 711, -627, 1180, -1083, 911, -996, -20, +-263, -827, 505, -1011, 967, -470, 966, 160, +351, 367, -271, 220, -697, 126, -668, 334, +-315, 501, 63, 293, 187, -329, 314, -864, +371, -870, 200, -318, -28, 369, -220, 783, +-304, 778, -79, 440, 69, -45, 120, -445, +149, -568, 76, -374, -102, -50, -276, 30, +-364, -105, -120, -204, 325, 49, 617, 638, +554, 1039, 163, 770, -444, -119, -727, -1062, +-606, -1432, -161, -1004, 266, -169, 442, 632, +263, 1191, 293, 1327, 319, 896, 248, -21, +-98, -1007, -580, -1395, -739, -910, -580, -155, +-91, 325, 349, 377, 865, 402, 999, 660, +513, 864, -365, 502, -1219, -294, -1073, -1028, +-145, -1142, 804, -625, 965, 15, 238, 389, +-492, 519, -575, 655, -34, 749, 348, 678, +310, 44, -55, -840, -199, -1443, 21, -1188, +149, -191, -50, 899, -386, 1336, -428, 920, +-48, 173, 420, -471, 673, -572, 553, -335, +123, -137, -370, -231, -846, -461, -885, -346, +-417, 380, 467, 1153, 1039, 1166, 1016, 252, +331, -848, -405, -1316, -882, -796, -770, -1, +-301, 601, 192, 756, 475, 549, 438, 118, +255, -311, -38, -509, -53, -314, -39, 142, +64, 249, -99, 71, -331, -254, -577, -296, +-342, 45, 269, 387, 830, 462, 937, 253, +304, -100, -416, -493, -974, -612, -819, -527, +-278, -23, 426, 681, 769, 1057, 648, 763, +83, -230, -379, -1165, -434, -1252, -98, -298, +227, 778, 86, 1113, -254, 550, -459, -305, +-117, -585, 390, -401, 767, -86, 493, 180, +-113, 234, -641, 222, -623, -11, -271, -288, +112, -315, 235, 9, 118, 454, 198, 473, +334, 92, 476, -447, 147, -640, -366, -413, +-787, 90, -759, 606, -308, 842, 293, 581, +818, -216, 856, -989, 587, -1134, -5, -401, +-588, 693, -928, 1258, -803, 799, -452, -215, +180, -995, 873, -901, 1192, -46, 976, 771, +-10, 901, -1023, 317, -1489, -563, -902, -1018, +216, -722, 1090, 8, 1096, 843, 364, 1092, +-403, 642, -778, -232, -458, -896, 116, -927, +491, -226, 510, 486, 96, 702, -436, 292, +-699, -399, -517, -657, 3, -269, 606, 394, +858, 716, 591, 455, 54, -120, -434, -330, +-664, -102, -573, 20, -367, -248, -47, -828, +262, -883, 580, -24, 653, 1156, 456, 1725, +27, 1186, -435, -133, -647, -1263, -618, -1554, +-196, -1036, 279, -82, 559, 600, 444, 734, +105, 544, -272, 374, -342, 363, -190, 220, +59, -205, 240, -692, 295, -673, 160, -213, +-139, 242, -373, 277, -461, -87, -220, -249, +148, -18, 403, 435, 464, 653, 305, 449, +54, -37, -173, -455, -335, -551, -410, -375, +-322, -143, -58, -47, 188, -83, 417, 0, +325, 317, 97, 612, -115, 620, -168, 288, +-104, -190, -43, -478, -30, -536, -21, -480, +94, -398, 57, -199, -38, 109, -149, 586, +-139, 868, 10, 734, 221, 189, 217, -461, +112, -783, 26, -602, -123, -205, -171, 71, +-229, 191, -189, 180, -27, 135, 201, 158, +399, 158, 335, 243, 13, 227, -394, -62, +-486, -407, -249, -566, 203, -351, 447, -19, +296, 254, 45, 321, -83, 451, -91, 498, +-176, 189, -294, -365, -357, -861, -91, -756, +379, -141, 670, 561, 543, 818, 31, 619, +-532, 87, -740, -460, -521, -654, 7, -429, +514, 104, 664, 479, 435, 334, -48, -146, +-490, -452, -638, -303, -325, 220, 159, 636, +597, 561, 650, 17, 276, -547, -312, -763, +-737, -427, -697, 161, -232, 537, 466, 623, +821, 368, 613, -120, -45, -620, -586, -824, +-640, -401, -150, 546, 354, 1155, 433, 830, +104, -197, -288, -1052, -318, -1022, 70, -237, +428, 505, 371, 740, -187, 502, -702, -47, +-667, -396, 26, -386, 780, -61, 1014, 294, +407, 241, -429, -172, -885, -336, -684, -28, +-71, 397, 394, 445, 492, -101, 177, -643, +-47, -629, -158, -105, -40, 504, 156, 868, +161, 651, -51, 73, -298, -613, -404, -1047, +-157, -838, 204, -22, 485, 785, 371, 1184, +121, 799, -161, -102, -265, -852, -326, -1111, +-330, -740, -204, -24, 83, 657, 512, 1052, +605, 1028, 349, 427, -178, -586, -426, -1298, +-420, -1251, -170, -307, -52, 770, -117, 1129, +-67, 736, 134, 5, 497, -509, 574, -589, +412, -384, -131, 15, -555, 327, -765, 468, +-594, 285, -101, 32, 390, -213, 673, -485, +584, -645, 228, -559, -124, 136, -266, 1007, +-312, 1413, -301, 823, -234, -446, -113, -1412, +126, -1504, 346, -702, 326, 397, 121, 1065, +-46, 1128, -69, 701, 9, 121, 10, -372, +-220, -731, -417, -930, -352, -713, 39, -67, +529, 610, 701, 956, 429, 730, -132, 125, +-593, -336, -719, -551, -350, -438, 175, -37, +555, 212, 518, 114, 81, -246, -288, -529, +-303, -113, -9, 725, 228, 1140, 169, 723, +-194, -327, -404, -1219, -280, -1261, 70, -543, +454, 313, 543, 1003, 284, 999, -155, 449, +-496, -177, -562, -591, -201, -509, 251, -50, +453, 222, 314, 128, -59, -216, -348, -613, +-283, -407, -76, 315, 218, 905, 432, 953, +346, 283, 48, -482, -352, -674, -631, -440, +-442, -235, 147, -156, 559, -162, 500, -42, +-19, 314, -505, 559, -364, 707, 190, 690, +559, 110, 389, -705, -195, -1350, -608, -1170, +-477, -186, -80, 922, 318, 1309, 495, 930, +376, 202, 132, -568, -249, -923, -578, -903, +-547, -351, 13, 511, 501, 1055, 650, 807, +194, -85, -437, -963, -542, -1061, -100, -263, +398, 773, 466, 1181, 121, 693, -337, -269, +-464, -948, -264, -874, 21, -325, 227, 287, +337, 580, 250, 503, 62, 164, -186, -144, +-244, -277, -60, -163, 116, 60, 228, 113, +-25, 69, -293, 9, -415, -27, -183, -166, +184, -242, 571, -238, 692, 16, 326, 336, +-244, 337, -833, 201, -932, 41, -460, -19, +406, -35, 912, -133, 904, -295, 296, -336, +-416, -284, -729, -196, -529, 133, -73, 613, +323, 937, 407, 791, 164, -67, -59, -1062, +-240, -1462, -215, -999, -66, 138, 114, 1278, +229, 1570, 252, 868, 52, -317, -229, -1201, +-321, -1105, -195, -369, 201, 323, 442, 606, +290, 525, -133, 184, -468, -163, -464, -437, +-153, -436, 231, 65, 383, 536, 357, 573, +265, 155, 1, -414, -182, -629, -353, -391, +-313, 8, -96, 297, 81, 342, 123, 141, +62, -67, 72, 45, 91, 206, 183, 206, +80, -105, -30, -489, -119, -460, -208, -112, +-265, 161, -162, 236, 36, 315, 369, 363, +493, 298, 195, -117, -275, -615, -520, -580, +-311, -100, 91, 381, 404, 461, 222, 177, +-55, -221, -185, -311, -132, -167, 82, 135, +106, 486, 36, 379, -28, -106, -35, -554, +-83, -635, -51, -143, -26, 468, 62, 659, +189, 357, 103, -147, -94, -646, -206, -651, +-156, -139, 9, 439, 263, 823, 260, 562, +113, -72, -125, -506, -337, -609, -305, -419, +-62, -53, 214, 236, 265, 384, 181, 368, +-76, 81, -49, -180, 36, -174, 58, -102, +-1, 20, -166, 110, -225, 57, -71, 72, +130, 19, 141, -134, 138, -181, -57, -163, +-164, -78, -38, 108, 94, 258, 121, 222, +75, 60, -62, -199, -74, -204, 75, 91, +55, 297, -133, 150, -253, -163, -197, -335, +92, -189, 380, 41, 253, -49, -39, -156, +-290, -42, -219, 336, 89, 635, 295, 496, +187, -31, -86, -565, -315, -759, -269, -573, +37, -70, 218, 468, 244, 720, 91, 568, +-94, 81, -204, -405, -120, -586, -72, -363, +94, 21, 210, 382, 148, 392, 26, 57, +-184, -320, -216, -395, -82, -41, 201, 474, +278, 610, 135, 147, -166, -494, -437, -761, +-318, -423, 22, 295, 396, 655, 473, 459, +231, -25, -172, -411, -372, -353, -354, -115, +-123, 102, 161, 213, 368, 375, 336, 371, +50, 104, -347, -433, -543, -887, -236, -647, +290, 85, 617, 780, 431, 908, -126, 407, +-553, -226, -512, -501, -148, -424, 264, -164, +440, 61, 355, 64, 84, -10, -178, 10, +-359, 128, -238, 304, 64, 267, 244, -119, +232, -452, -84, -428, -330, -29, -279, 408, +14, 399, 280, 4, 372, -249, 215, -159, +-24, 183, -119, 283, -228, -44, -185, -508, +-98, -515, 29, -21, 92, 578, 35, 756, +-144, 248, -149, -366, 97, -640, 352, -405, +502, 37, 197, 301, -274, 282, -599, 212, +-551, 168, -195, 57, 323, -157, 551, -454, +415, -528, 49, -262, -353, 257, -417, 679, +-147, 770, 187, 380, 374, -252, 313, -718, +-61, -783, -341, -379, -450, 187, -318, 502, +125, 475, 435, 229, 445, -16, 239, -130, +-109, -122, -282, -104, -165, -27, -80, 21, +-91, -57, -115, -168, -142, -213, 65, -26, +370, 289, 412, 382, 218, 144, -156, -139, +-570, -221, -569, -61, -181, 146, 420, 71, +826, -67, 650, -188, -109, -205, -807, -135, +-981, 38, -412, 194, 483, 345, 939, 315, +713, 70, 28, -156, -645, -355, -752, -398, +-262, -237, 334, 104, 711, 441, 470, 570, +-172, 208, -651, -315, -634, -594, -213, -482, +370, -80, 606, 301, 454, 491, 171, 513, +-134, 329, -319, -125, -382, -535, -352, -681, +-158, -406, 206, 100, 407, 450, 364, 465, +35, 333, -304, 132, -314, -54, -59, -236, +281, -468, 360, -527, 163, -278, -182, 256, +-382, 779, -352, 912, -153, 380, 107, -454, +235, -1034, 311, -948, 293, -226, 161, 551, +-85, 844, -379, 526, -485, -21, -233, -385, +227, -237, 549, 139, 474, 306, -9, 47, +-480, -439, -641, -678, -336, -334, 209, 324, +609, 704, 619, 602, 235, 84, -308, -350, +-613, -393, -510, -159, -123, 98, 345, 176, +526, -21, 361, -254, 5, -206, -294, 51, +-401, 370, -239, 400, -30, 16, 162, -397, +308, -445, 315, -136, 148, 378, -117, 590, +-412, 264, -407, -263, -124, -640, 232, -549, +464, 34, 361, 548, 44, 604, -271, 236, +-413, -310, -364, -525, -42, -309, 294, 90, +480, 362, 391, 361, -47, 14, -467, -307, +-545, -309, -246, -81, 271, 261, 587, 298, +413, 64, 13, -133, -370, -163, -471, -164, +-243, -131, 138, -54, 368, 182, 356, 458, +13, 370, -413, -94, -440, -473, -118, -432, +402, -74, 615, 219, 268, 123, -300, -64, +-490, -10, -247, 262, 149, 430, 272, 199, +-65, -379, -316, -807, -137, -602, 273, 138, +517, 909, 316, 1031, -195, 320, -481, -654, +-417, -1132, -162, -853, 124, 21, 342, 836, +431, 1100, 344, 685, -34, -173, -511, -918, +-663, -981, -351, -349, 213, 389, 656, 741, +649, 476, 284, 8, -175, -233, -588, -245, +-751, -173, -502, -95, 93, -43, 778, 37, +1028, 190, 534, 243, -350, 149, -948, -63, +-905, -350, -241, -398, 492, -85, 789, 306, +618, 541, 115, 393, -451, -41, -748, -418, +-589, -567, -89, -483, 574, -82, 868, 403, +606, 672, -6, 594, -619, 169, -836, -276, +-551, -495, -13, -523, 451, -467, 680, -129, +484, 324, 92, 671, -261, 680, -459, 164, +-358, -343, -101, -523, 73, -413, 140, -158, +144, 76, 128, 215, 211, 359, 192, 403, +-2, 174, -253, -197, -435, -567, -371, -721, +-40, -327, 324, 384, 458, 943, 374, 941, +23, 267, -271, -592, -330, -989, -203, -843, +-6, -323, 132, 348, 105, 816, 29, 910, +26, 496, 23, -264, 39, -784, 31, -692, +-25, -226, -78, 209, -87, 352, -75, 242, +-32, 148, 45, 69, 129, -60, 183, -117, +151, -92, -35, -100, -273, -150, -356, -147, +-150, 40, 228, 382, 513, 511, 367, 191, +-133, -318, -587, -662, -603, -565, -58, -70, +576, 496, 793, 738, 314, 514, -397, -99, +-807, -664, -516, -642, 182, -143, 590, 421, +453, 581, -65, 209, -350, -305, -184, -497, +176, -290, 223, 138, -60, 509, -381, 476, +-335, 109, 93, -307, 478, -540, 507, -385, +161, 34, -330, 287, -602, 296, -453, 122, +-22, -61, 493, 19, 682, 164, 345, 101, +-268, -140, -666, -413, -548, -452, 38, -93, +520, 287, 487, 423, 94, 378, -295, 186, +-341, -18, -64, -207, 176, -469, 188, -519, +49, -136, -123, 354, -198, 663, -125, 484, +41, -93, 235, -538, 326, -525, 131, -220, +-241, 216, -503, 447, -401, 307, 120, 110, +601, -90, 634, -231, 193, -223, -419, -174, +-718, -45, -524, 228, -19, 298, 424, 89, +580, -226, 371, -380, -23, -152, -310, 319, +-346, 508, -122, 278, 158, -73, 195, -410, +-17, -411, -282, -221, -294, -24, 29, 198, +408, 313, 491, 240, 163, 96, -289, -30, +-489, -140, -266, -139, 156, -167, 407, -173, +237, -16, -156, 177, -409, 264, -314, 233, +93, 26, 454, -192, 436, -295, 105, -327, +-287, -192, -457, 121, -252, 441, 83, 570, +272, 395, 257, -91, 80, -540, -122, -689, +-169, -518, -150, -95, -90, 385, 81, 660, +213, 721, 263, 422, 189, -163, -96, -685, +-367, -874, -413, -549, -268, 25, 88, 546, +415, 690, 498, 572, 357, 256, 33, -184, +-371, -502, -538, -636, -403, -458, -85, -84, +355, 263, 498, 438, 300, 526, -4, 429, +-292, 141, -359, -284, -159, -657, 18, -675, +115, -273, 182, 254, 101, 601, 106, 643, +149, 334, 78, -91, -86, -439, -324, -590, +-531, -443, -359, -75, 144, 228, 603, 477, +750, 549, 359, 377, -294, 34, -637, -422, +-522, -744, -128, -580, 307, -51, 357, 449, +158, 650, -50, 366, -201, -3, -114, -204, +90, -240, 172, -227, 95, -168, -81, -57, +-278, 129, -213, 311, 74, 238, 306, 72, +374, -115, 136, -321, -266, -415, -455, -315, +-336, 67, 1, 659, 367, 877, 410, 434, +141, -398, -131, -992, -234, -845, -105, -130, +120, 538, 106, 697, -110, 423, -293, -51, +-251, -332, 20, -318, 379, -142, 501, 120, +314, 304, -1, 297, -363, 93, -567, -306, +-485, -658, -141, -574, 298, -2, 653, 730, +558, 1017, 113, 572, -369, -285, -599, -899, +-369, -898, 107, -336, 434, 369, 377, 768, +79, 689, -341, 156, -432, -452, -135, -708, +231, -450, 476, 105, 344, 542, -106, 549, +-431, 174, -445, -298, -209, -537, 210, -338, +451, 119, 376, 425, 146, 297, -161, -105, +-336, -312, -236, -36, -98, 297, 0, 259, +69, -203, 66, -624, 117, -464, 214, 150, +127, 708, -24, 769, -139, 313, -221, -356, +-134, -753, -15, -652, 16, -154, 118, 397, +192, 565, 138, 269, 25, -129, -206, -339, +-353, -214, -159, 128, 195, 381, 440, 415, +405, 95, -24, -436, -502, -784, -581, -587, +-269, 81, 298, 757, 679, 928, 505, 450, +-10, -274, -477, -781, -597, -791, -235, -290, +233, 403, 394, 838, 300, 730, 19, 98, +-193, -618, -185, -913, -105, -638, -56, 8, +50, 627, 143, 879, 178, 640, 176, 94, +-39, -478, -305, -774, -377, -643, -190, -235, +200, 254, 551, 575, 472, 576, 14, 301, +-467, -77, -640, -314, -310, -396, 260, -305, +584, -149, 470, 70, 76, 341, -353, 418, +-487, 214, -310, -153, -3, -396, 290, -304, +402, 29, 236, 260, -38, 252, -271, 71, +-308, -179, -89, -273, 168, -162, 252, 61, +125, 279, -96, 293, -245, 62, -158, -129, +4, -179, 142, -152, 193, -123, 145, -154, +19, -88, -98, 223, -183, 525, -153, 494, +5, 112, 93, -495, 78, -863, -9, -658, +-28, -68, 119, 657, 275, 1057, 167, 797, +-210, 52, -606, -774, -605, -1189, -20, -838, +737, 77, 1016, 882, 520, 1068, -426, 550, +-1104, -259, -902, -653, -86, -532, 703, -208, +901, 63, 460, 103, -154, 118, -516, 275, +-515, 325, -274, 173, 52, -134, 285, -413, +390, -395, 282, -98, -10, 194, -273, 307, +-308, 225, -149, 4, 78, -129, 198, -128, +128, -96, 50, -10, -2, 88, -78, 121, +-123, 116, -122, 1, -50, -171, 106, -211, +161, -125, 59, 7, -56, 154, -79, 220, +-8, 214, 101, 163, 85, -42, -18, -269, +-68, -310, -119, -132, -153, 50, -121, 74, +-32, -89, 156, -113, 392, 192, 354, 534, +67, 542, -302, 115, -555, -496, -403, -847, +29, -700, 398, -228, 487, 423, 324, 901, +-54, 899, -301, 378, -376, -378, -336, -908, +-112, -811, 179, -235, 396, 328, 454, 583, +241, 456, -149, 115, -412, -124, -445, -213, +-232, -223, 110, -107, 294, -7, 297, 82, +188, 154, -17, 71, -102, -103, -93, -167, +-103, -80, -120, 113, -121, 264, -120, 144, +55, -72, 287, -153, 318, -150, 166, -61, +-148, 21, -370, -5, -263, 8, 14, 43, +192, 30, 219, 109, 43, 176, -101, 97, +-90, -92, -79, -308, -18, -360, 65, -41, +132, 329, 126, 413, 46, 217, -187, -206, +-270, -470, -120, -307, 98, 67, 272, 394, +235, 468, 19, 143, -148, -233, -188, -385, +-152, -368, -15, -154, 57, 170, 61, 387, +112, 467, 113, 245, 22, -290, -83, -623, +-166, -523, -112, -8, 140, 585, 255, 772, +126, 322, -160, -313, -355, -770, -257, -691, +88, -47, 293, 560, 254, 704, 94, 341, +-78, -241, -98, -528, -102, -276, -168, 106, +-159, 349, 63, 262, 282, -130, 320, -431, +30, -376, -405, -29, -478, 446, -72, 658, +426, 319, 600, -223, 255, -637, -317, -660, +-597, -199, -429, 401, 31, 730, 440, 653, +463, 103, 168, -600, -175, -872, -376, -591, +-234, 58, 72, 705, 218, 864, 129, 496, +-13, -69, -135, -605, -96, -753, 44, -428, +79, 46, 96, 423, 51, 542, -55, 313, +-166, -7, -179, -221, -82, -345, 162, -239, +305, -1, 218, 138, 12, 231, -258, 236, +-314, 81, -122, -98, 116, -307, 201, -429, +144, -159, -48, 246, -162, 481, -92, 432, +34, 103, 171, -248, 232, -325, 87, -331, +-156, -289, -335, -73, -321, 166, -8, 409, +349, 530, 434, 304, 204, -103, -170, -432, +-449, -640, -366, -441, -23, 48, 284, 451, +422, 606, 259, 405, -73, -81, -291, -381, +-295, -414, -146, -273, 54, 68, 129, 290, +125, 282, 140, 159, 116, -54, 32, -242, +-113, -221, -277, -163, -278, -37, 6, 230, +289, 376, 404, 298, 214, 43, -198, -341, +-470, -476, -323, -238, 20, 23, 324, 214, +390, 249, 139, 145, -106, 127, -234, 147, +-222, -28, -83, -240, 66, -391, 143, -343, +141, 45, 35, 418, -91, 422, -63, 183, +-11, -159, 28, -358, 51, -241, 3, -75, +-15, 59, 37, 280, 23, 355, -97, 203, +-179, -134, -159, -549, 54, -600, 372, -123, +435, 448, 169, 752, -313, 587, -637, -54, +-502, -618, 20, -751, 497, -461, 633, 142, +356, 623, -136, 604, -391, 269, -354, -160, +-137, -442, 59, -353, 74, -114, -20, 27, +-10, 140, 104, 145, 209, 101, 215, 171, +58, 135, -137, -25, -218, -185, -202, -328, +-138, -309, 6, -32, 89, 220, 129, 404, +146, 450, 121, 190, 74, -191, 23, -505, +-123, -626, -279, -366, -223, 169, -71, 561, +189, 727, 289, 532, 184, -5, 15, -513, +-98, -774, -154, -670, -163, -131, -118, 427, +-32, 641, 226, 541, 374, 195, 209, -165, +-170, -309, -546, -349, -541, -296, -14, -72, +608, 117, 761, 225, 386, 225, -334, 41, +-797, -137, -613, -108, -47, 19, 500, 193, +617, 233, 245, -48, -228, -349, -384, -391, +-198, -163, 137, 256, 257, 461, 5, 259, +-255, -58, -247, -244, 19, -222, 354, 7, +409, 139, 99, 41, -247, -89, -403, -173, +-313, -113, -7, 104, 263, 220, 339, 169, +259, 119, 35, 5, -235, -92, -334, -192, +-270, -322, -63, -282, 223, 18, 333, 318, +226, 476, 54, 372, -94, -16, -131, -346, +-100, -444, -179, -304, -250, 48, -140, 337, +128, 307, 441, 134, 488, -88, 124, -228, +-351, -212, -569, -135, -371, 5, 143, 279, +556, 421, 467, 232, 59, -134, -376, -491, +-581, -485, -315, -120, 118, 244, 432, 387, +527, 340, 320, 116, -95, -81, -432, -188, +-590, -281, -457, -259, 12, -111, 455, 98, +732, 362, 607, 463, 79, 193, -499, -218, +-777, -517, -625, -501, -123, -134, 430, 247, +593, 425, 482, 446, 200, 274, -130, -47, +-295, -346, -368, -510, -365, -414, -186, -54, +118, 280, 378, 444, 494, 401, 295, 106, +-80, -225, -352, -340, -447, -261, -292, -25, +11, 141, 248, 132, 371, 117, 347, 147, +85, 45, -215, -165, -386, -336, -338, -297, +-78, 44, 196, 383, 286, 433, 273, 240, +188, -73, 33, -378, -172, -437, -408, -266, +-486, 74, -212, 380, 319, 361, 654, 99, +575, -127, 59, -179, -531, -96, -673, 40, +-371, 26, 147, -20, 491, -48, 499, -46, +191, 31, -138, 131, -336, 79, -323, -50, +-135, -116, 20, -52, 136, 132, 143, 167, +137, -44, 141, -252, 95, -233, -84, -11, +-277, 284, -258, 341, -81, 123, 225, -189, +354, -370, 182, -253, -121, 140, -272, 386, +-192, 263, -14, -109, 104, -429, 29, -378, +-53, -10, 7, 359, 223, 524, 351, 408, +178, -32, -244, -513, -612, -677, -577, -391, +-93, 217, 504, 617, 729, 484, 449, 50, +-84, -285, -444, -325, -447, -105, -189, 104, +64, 153, 107, 104, 85, -18, 87, -143, +119, -156, 127, -92, 50, 21, -93, 168, +-170, 234, -170, 171, -103, -30, 58, -259, +201, -271, 253, -11, 126, 238, -184, 219, +-408, -35, -303, -289, 56, -229, 390, 54, +472, 274, 169, 282, -232, 122, -412, -122, +-359, -257, -85, -219, 215, -46, 344, 157, +303, 198, 88, 38, -211, -144, -348, -165, +-262, -25, -47, 203, 224, 280, 262, 137, +105, -153, 5, -368, -33, -316, -34, 22, +-66, 320, -207, 328, -267, 80, -18, -190, +306, -226, 444, -72, 279, 87, -175, 147, +-482, 125, -436, -3, -111, -159, 284, -228, +459, -128, 271, 89, -29, 236, -239, 202, +-299, 80, -97, 10, 113, -51, 135, -132, +88, -254, -11, -294, -106, -132, -53, 191, +14, 472, 21, 532, 72, 247, 61, -257, +-3, -645, -39, -618, -93, -181, -54, 358, +99, 583, 151, 386, 37, 28, -157, -236, +-284, -283, -102, -171, 295, -27, 419, 88, +190, 133, -207, 79, -508, -31, -324, -83, +132, -63, 400, 21, 360, 96, 47, 64, +-321, -14, -358, -51, -103, -1, 176, 84, +389, 61, 270, -153, -66, -317, -297, -194, +-346, 192, -169, 514, 138, 427, 283, -55, +202, -501, 83, -531, -85, -186, -131, 266, +-45, 488, -34, 376, -26, 60, 20, -282, +1, -469, -2, -362, 32, -53, -15, 288, +35, 486, 96, 411, 14, 104, -39, -250, +-86, -470, -105, -424, 16, -120, 106, 181, +26, 295, -25, 212, -69, 61, -63, 0, +93, 82, 135, 120, 41, 15, -61, -225, +-155, -465, -136, -420, 44, -34, 134, 431, +88, 649, -4, 425, -170, -87, -173, -436, +20, -422, 168, -180, 248, 67, 196, 170, +-78, 149, -271, 115, -286, 10, -233, -152, +-15, -190, 181, -38, 233, 212, 270, 346, +195, 150, -24, -220, -195, -392, -313, -266, +-331, 44, -120, 253, 85, 152, 238, -41, +371, -49, 272, 130, 15, 282, -245, 149, +-447, -273, -377, -560, 28, -433, 379, 14, +514, 501, 321, 660, -219, 378, -606, -121, +-564, -551, -175, -659, 429, -304, 798, 233, +587, 585, 32, 546, -577, 133, -883, -311, +-568, -455, 89, -297, 632, -23, 809, 176, +451, 136, -159, 39, -531, 64, -562, 191, +-275, 259, 164, 88, 367, -294, 308, -549, +124, -437, -120, -80, -206, 330, -76, 567, +38, 548, 108, 310, 113, -137, -24, -647, +-114, -814, -86, -460, -54, 240, 62, 812, +157, 791, 110, 220, 56, -422, 17, -704, +-52, -493, -70, 10, -96, 362, -126, 407, +2, 268, 169, 77, 243, -86, 205, -228, +-21, -375, -263, -347, -277, -55, -127, 290, +93, 460, 321, 331, 318, 39, 125, -153, +-96, -187, -340, -202, -374, -221, -125, -210, +195, -101, 451, 188, 446, 465, 92, 491, +-316, 218, -495, -262, -382, -619, 11, -512, +385, -57, 427, 384, 238, 509, -96, 214, +-325, -208, -266, -375, -19, -221, 159, 134, +196, 396, 50, 273, -128, -89, -96, -366, +-15, -352, 19, -87, -4, 167, -80, 220, +-43, 226, 135, 243, 207, 111, 89, -180, +-108, -485, -302, -477, -267, -33, -34, 463, +145, 570, 211, 281, 161, -161, 9, -428, +-75, -373, -111, -154, -152, 87, -118, 281, +-42, 305, 35, 192, 104, 53, 80, -131, +-33, -276, -72, -340, -34, -281, 25, -19, +85, 348, -6, 537, -166, 431, -178, 57, +-64, -389, 126, -582, 219, -442, 56, -103, +-202, 268, -264, 453, -81, 400, 203, 228, +324, -54, 92, -345, -225, -436, -331, -269, +-179, 69, 104, 323, 218, 256, 73, -13, +-92, -155, -97, -81, 21, 121, 163, 231, +119, 117, -116, -117, -269, -316, -241, -369, +-42, -151, 213, 239, 290, 479, 175, 394, +18, 33, -112, -315, -145, -356, -113, -153, +-124, 46, -135, 142, -31, 102, 153, 1, +337, -24, 367, 13, 116, 72, -219, 98, +-409, -22, -330, -202, -33, -198, 245, -10, +322, 221, 238, 294, 68, 92, -99, -191, +-178, -310, -172, -221, -75, 28, 107, 275, +237, 291, 206, 115, 60, -109, -134, -241, +-194, -171, -63, -8, 115, 76, 185, 106, +118, 76, -31, -12, -84, -63, 7, -65, +92, -14, 70, 87, -74, 92, -175, 3, +-76, -50, 199, -84, 385, -82, 292, -32, +-52, 41, -401, 134, -435, 165, -175, 7, +181, -204, 427, -223, 418, -38, 219, 241, +-69, 342, -335, 101, -433, -248, -288, -412, +52, -287, 364, 101, 464, 417, 265, 386, +-54, 114, -274, -182, -332, -290, -219, -184, +-68, -68, 107, -23, 257, 77, 301, 185, +170, 185, -76, 50, -270, -130, -302, -138, +-143, 50, 26, 124, 120, -20, 163, -210, +176, -248, 121, -17, -51, 255, -288, 300, +-373, 161, -170, -24, 196, -176, 406, -216, +264, -192, -128, -119, -416, 64, -345, 238, +-41, 274, 249, 156, 270, -63, 69, -231, +-134, -189, -205, -49, -140, 37, -38, 59, +13, 23, 4, 28, -19, 76, -35, 41, +-21, -37, 37, -38, 94, 22, 88, 77, +5, 39, -184, -105, -311, -208, -253, -178, +-43, -57, 212, 138, 325, 327, 211, 367, +0, 211, -150, -119, -230, -437, -230, -515, +-207, -322, -135, 16, 78, 383, 343, 587, +441, 494, 250, 126, -168, -373, -501, -666, +-462, -508, -151, -39, 166, 381, 292, 492, +216, 264, 118, -30, 130, -174, 75, -180, +-108, -143, -332, -111, -408, -76, -160, 55, +262, 250, 512, 279, 402, 113, 25, -144, +-365, -305, -431, -222, -163, -35, 199, 102, +410, 177, 298, 193, -59, 124, -317, -47, +-259, -251, 46, -278, 375, -22, 370, 273, +3, 296, -350, 33, -389, -277, -51, -307, +398, -35, 518, 222, 211, 260, -223, 105, +-451, -97, -308, -153, 91, -88, 390, -15, +403, 23, 221, 22, -83, -8, -267, -4, +-262, 15, -170, 29, 24, 73, 228, 78, +339, 0, 333, -101, 156, -129, -184, -24, +-424, 116, -386, 81, -119, -116, 284, -234, +511, -92, 396, 249, 116, 460, -206, 282, +-376, -133, -314, -452, -146, -480, 43, -230, +251, 110, 339, 367, 253, 465, 97, 331, +-161, 0, -313, -329, -237, -453, -104, -295, +61, 23, 170, 255, 141, 261, 100, 110, +63, -24, -42, -32, -123, 43, -165, 16, +-190, -142, -63, -272, 126, -192, 202, 105, +192, 360, 5, 332, -241, 57, -265, -235, +-107, -342, 80, -208, 195, 30, 88, 221, +-132, 287, -185, 162, -123, -95, 8, -301, +138, -289, 97, -50, -14, 257, -68, 371, +-129, 210, -137, -89, -75, -338, -65, -355, +12, -148, 124, 125, 125, 312, 65, 324, +-49, 141, -217, -110, -245, -285, -124, -287, +5, -83, 163, 147, 213, 201, 97, 81, +-32, -51, -152, -43, -249, 78, -174, 91, +-48, -62, 63, -195, 203, -157, 179, 22, +23, 181, -107, 182, -201, 101, -162, 25, +36, -85, 118, -219, 72, -288, 4, -176, +-116, 154, -94, 471, 75, 471, 161, 113, +152, -381, 24, -654, -210, -427, -267, 134, +-109, 590, 88, 597, 267, 135, 269, -403, +55, -569, -89, -310, -137, 110, -137, 405, +-2, 393, 73, 171, 64, -87, 86, -291, +46, -343, -24, -211, -8, 5, 17, 214, +39, 320, 119, 234, 65, 59, -46, -112, +-66, -220, -69, -208, 37, -111, 159, 6, +107, 117, 14, 150, -22, 73, -43, -8, +37, -40, 137, -11, 71, 43, -29, 22, +-119, -45, -179, -50, 0, -38, 271, -62, +374, -97, 285, -53, -63, 122, -437, 298, +-480, 238, -208, -62, 210, -310, 573, -303, +551, -66, 179, 147, -210, 168, -492, 103, +-452, 71, -96, 31, 208, -60, 338, -175, +288, -215, 71, -64, -68, 172, -54, 297, +-68, 237, -106, 18, -153, -252, -189, -377, +-11, -284, 243, -8, 318, 319, 228, 444, +-17, 276, -277, -53, -323, -330, -218, -379, +-70, -173, 162, 72, 296, 213, 236, 216, +68, 105, -200, -8, -351, -88, -217, -151, +16, -138, 193, -22, 230, 121, 50, 219, +-150, 172, -229, -32, -209, -258, -55, -344, +149, -215, 223, 121, 172, 434, 0, 460, +-217, 173, -303, -239, -212, -471, -75, -352, +62, -58, 145, 156, 151, 204, 178, 138, +127, 101, -53, 134, -275, 116, -411, -26, +-347, -232, -59, -382, 254, -295, 382, 27, +330, 337, 96, 447, -182, 277, -341, -41, +-337, -268, -207, -310, 21, -228, 173, -62, +220, 108, 229, 218, 134, 240, -33, 128, +-214, -62, -336, -170, -276, -164, 8, -72, +259, 44, 322, 85, 174, 55, -94, 6, +-208, -30, -122, -13, -4, 28, 56, 14, +37, -29, -8, -30, 33, 48, 83, 146, +16, 106, -79, -119, -97, -338, 2, -319, +183, -1, 206, 418, 27, 564, -158, 283, +-204, -221, -57, -565, 155, -500, 236, -94, +119, 328, -33, 453, -118, 250, -77, -97, +63, -290, 114, -200, 42, 50, -51, 216, +-86, 136, 15, -96, 206, -237, 258, -133, +124, 93, -103, 213, -302, 134, -276, -39, +-26, -127, 235, -79, 355, -1, 283, 33, +64, 28, -102, 30, -159, 28, -173, -8, +-128, -68, -29, -80, 75, -6, 193, 72, +229, 81, 135, 10, 45, -42, -32, 9, +-118, 83, -157, 56, -168, -87, -99, -234, +100, -198, 258, 23, 253, 252, 118, 302, +-101, 139, -216, -88, -142, -213, -17, -172, +43, -49, 42, 41, -8, 50, 4, -9, +96, -40, 107, 2, 11, 106, -112, 201, +-196, 151, -138, -48, 37, -268, 155, -329, +172, -145, 83, 157, -112, 319, -220, 211, +-168, -39, -52, -212, 107, -152, 158, 57, +37, 189, -51, 142, -108, -34, -135, -215, +-69, -245, -18, -117, 53, 90, 139, 274, +95, 297, -94, 124, -257, -122, -281, -263, +-91, -229, 228, -62, 343, 67, 153, 95, +-153, 95, -385, 92, -317, 82, 8, 36, +218, -64, 201, -129, 40, -116, -194, -69, +-228, -14, -35, 64, 123, 161, 218, 219, +135, 118, -179, -155, -375, -368, -346, -290, +-117, 49, 299, 388, 504, 410, 338, 90, +2, -261, -383, -384, -549, -222, -324, 73, +42, 251, 346, 224, 451, 71, 202, -111, +-143, -177, -285, -52, -232, 117, -7, 178, +178, 36, 108, -233, -58, -331, -126, -130, +-61, 219, 139, 434, 293, 337, 139, -5, +-123, -310, -294, -384, -285, -254, 19, -1, +323, 204, 358, 278, 175, 238, -123, 62, +-345, -144, -231, -232, 60, -158, 292, 16, +344, 129, 101, 75, -200, -73, -283, -94, +-132, 35, 115, 175, 317, 156, 276, -60, +80, -234, -91, -165, -215, 70, -198, 226, +-43, 128, 89, -126, 164, -272, 227, -162, +178, 101, 122, 305, 49, 334, -113, 159, +-251, -125, -266, -402, -163, -534, 92, -338, +382, 149, 467, 635, 337, 758, 4, 369, +-388, -297, -526, -767, -327, -713, 59, -241, +465, 344, 576, 672, 274, 570, -159, 164, +-485, -317, -461, -588, -71, -470, 322, -56, +434, 358, 282, 519, -20, 347, -249, -19, +-278, -318, -220, -440, -122, -357, 86, -76, +270, 261, 347, 495, 296, 468, -18, 120, +-336, -301, -452, -500, -377, -394, -49, -105, +305, 169, 415, 280, 335, 294, 68, 259, +-276, 93, -414, -170, -348, -395, -82, -407, +254, -78, 380, 326, 204, 464, -122, 248, +-384, -163, -380, -433, -83, -351, 213, -15, +320, 316, 219, 460, -36, 310, -273, -57, +-299, -397, -217, -544, -67, -370, 116, 52, +179, 445, 193, 601, 124, 419, -75, -18, +-281, -421, -350, -561, -234, -384, 68, -16, +317, 315, 301, 405, 116, 280, -146, 70, +-330, -144, -303, -258, -168, -262, -11, -156, +212, 43, 336, 223, 325, 297, 140, 212, +-263, 1, -598, -245, -625, -385, -235, -302, +386, -21, 798, 325, 679, 486, 102, 342, +-544, 0, -806, -321, -542, -438, 30, -333, +528, -91, 617, 195, 325, 411, -132, 427, +-436, 147, -401, -267, -144, -513, 161, -355, +328, 126, 277, 499, 117, 439, -77, 8, +-195, -438, -201, -532, -144, -245, -40, 180, +79, 466, 207, 518, 327, 305, 339, -63, +151, -421, -205, -637, -523, -531, -576, -91, +-251, 438, 330, 787, 800, 703, 825, 169, +340, -494, -398, -880, -886, -733, -790, -99, +-174, 614, 542, 895, 894, 591, 704, -106, +112, -724, -469, -802, -726, -366, -516, 278, +24, 727, 512, 694, 701, 261, 468, -295, +-54, -697, -475, -731, -577, -322, -328, 301, +182, 788, 552, 817, 570, 268, 250, -455, +-235, -842, -506, -665, -412, -41, -56, 522, +314, 644, 460, 362, 293, -72, -25, -387, +-262, -432, -300, -248, -155, 50, 71, 346, +184, 447, 182, 226, 139, -163, -19, -489, +-109, -461, -133, -53, -117, 392, 0, 559, +54, 300, 44, -184, 71, -505, 89, -444, +75, -82, -1, 279, -200, 437, -301, 297, +-188, 23, 93, -204, 348, -325, 359, -285, +84, -142, -288, 74, -457, 315, -334, 463, +-2, 378, 311, 4, 364, -473, 152, -768, +-128, -577, -318, 65, -266, 759, -42, 1048, +134, 655, 147, -224, -20, -1045, -198, -1272, +-162, -687, 72, 423, 263, 1373, 232, 1475, +-82, 580, -417, -773, -473, -1673, -179, -1437, +242, -225, 511, 1100, 418, 1662, -12, 1113, +-455, -96, -645, -1141, -392, -1423, 138, -840, +582, 211, 633, 1092, 240, 1285, -326, 713, +-713, -323, -670, -1179, -246, -1287, 319, -606, +731, 497, 740, 1335, 309, 1347, -319, 531, +-859, -655, -942, -1514, -429, -1483, 352, -510, +972, 828, 1004, 1756, 399, 1636, -434, 440, +-962, -1073, -945, -1970, -390, -1664, 372, -270, +901, 1310, 963, 2092, 476, 1581, -339, 47, +-977, -1546, -1022, -2161, -465, -1384, 461, 283, +1112, 1761, 1063, 2061, 414, 1029, -520, -579, +-1118, -1758, -1020, -1771, -334, -747, 555, 614, +1146, 1560, 1049, 1588, 376, 740, -517, -514, +-1116, -1511, -1024, -1673, -294, -824, 633, 605, +1180, 1724, 1027, 1799, 231, 690, -686, -925, +-1148, -1956, -912, -1744, -65, -391, 863, 1226, +1229, 2053, 867, 1581, -65, 106, -953, -1434, +-1175, -2069, -673, -1411, 264, 118, 1053, 1556, +1165, 2040, 588, 1262, -311, -296, -1027, -1675, +-1062, -2012, -465, -1051, 393, 576, 1022, 1815, +1026, 1843, 427, 662, -382, -889, -926, -1814, +-909, -1506, -343, -266, 378, 1073, 853, 1694, +853, 1222, 366, 10, -300, -1201, -786, -1656, +-828, -1047, -375, 281, 311, 1465, 766, 1651, +758, 712, 297, -746, -328, -1668, -663, -1389, +-594, -178, -182, 1137, 293, 1632, 527, 1002, +378, -287, 27, -1390, -297, -1557, -383, -636, +-186, 773, 54, 1659, 197, 1388, 193, 132, +66, -1225, -31, -1674, -66, -971, -129, 334, +-199, 1344, -219, 1372, -109, 554, 180, -518, +457, -1180, 444, -1045, 83, -279, -429, 615, +-768, 1045, -617, 747, -75, -84, 543, -817, +887, -880, 699, -278, 55, 546, -654, 925, +-1027, 570, -827, -222, -119, -889, 635, -923, +1028, -275, 861, 630, 163, 1160, -650, 909, +-1115, -39, -968, -1062, -243, -1392, 664, -767, +1164, 467, 977, 1475, 156, 1498, -819, 465, +-1297, -969, -939, -1819, 27, -1422, 999, -17, +1300, 1474, 698, 2002, -352, 1174, -1179, -488, +-1223, -1865, -455, -1993, 605, -806, 1254, 957, +1099, 2085, 223, 1848, -816, 419, -1311, -1313, +-997, -2210, -59, -1701, 943, -52, 1355, 1702, +915, 2381, -118, 1492, -1122, -465, -1419, -2159, +-724, -2416, 444, -1023, 1369, 1092, 1352, 2457, +372, 2153, -872, 400, -1495, -1606, -1072, -2504, +183, -1725, 1326, 216, 1489, 1996, 599, 2414, +-733, 1188, -1565, -856, -1252, -2289, -47, -2133, +1211, -512, 1700, 1433, 983, 2328, -412, 1624, +-1537, -137, -1613, -1717, -596, -2086, 822, -1091, +1668, 548, 1435, 1740, 358, 1782, -916, 673, +-1590, -801, -1295, -1700, -227, -1472, 975, -271, +1596, 1043, 1227, 1603, 155, 1046, -948, -174, +-1467, -1186, -1038, -1322, -25, -541, 904, 509, +1226, 1145, 794, 950, -33, 134, -638, -677, +-794, -990, -538, -597, -81, 164, 279, 730, +533, 762, 564, 252, 353, -370, -10, -688, +-419, -487, -685, 28, -580, 448, -96, 529, +492, 218, 892, -173, 741, -377, 87, -295, +-649, -5, -1028, 158, -791, 126, -70, -13, +739, -60, 1189, 121, 971, 302, 103, 226, +-995, -193, -1562, -641, -1177, -676, 93, -135, +1504, 716, 1964, 1183, 1089, 837, -651, -250, +-2075, -1373, -2140, -1631, -699, -729, 1230, 865, +2409, 2044, 2005, 1913, 237, 399, -1664, -1579, +-2605, -2660, -1885, -2020, 122, 141, 2084, 2398, +2703, 3180, 1537, 1766, -691, -1045, -2472, -3242, +-2585, -3253, -949, -916, 1287, 2124, 2628, 3724, +2159, 2683, 167, -266, -1933, -3043, -2692, -3720, +-1547, -1775, 733, 1433, 2464, 3715, 2422, 3469, +644, 772, -1649, -2578, -2754, -4265, -1833, -3001, +340, 450, 2306, 3753, 2543, 4486, 896, 2045, +-1352, -1919, -2607, -4637, -1918, -4069, 177, -642, +2132, 3340, 2498, 4978, 992, 3113, -1307, -985, +-2720, -4495, -2120, -4793, 89, -1736, 2317, 2662, +2936, 5173, 1431, 4009, -1195, 65, -3072, -3971, +-2795, -5092, -511, -2733, 2265, 1485, 3487, 4540, +2223, 4367, -665, 1274, -3203, -2646, -3444, -4518, +-1193, -3220, 1921, 284, 3746, 3440, 2953, 3949, +10, 1664, -2965, -1753, -3863, -3671, -2068, -2857, +1208, -29, 3616, 2709, 3509, 3318, 981, 1589, +-2176, -1305, -3752, -3092, -2744, -2615, 111, -227, +2844, 2276, 3579, 2963, 1797, 1428, -1170, -1217, +-3208, -2751, -2911, -2088, -607, 234, 2048, 2290, +3161, 2381, 1969, 596, -451, -1673, -2484, -2533, +-2683, -1420, -996, 777, 1292, 2381, 2619, 2188, +2058, 424, 76, -1702, -1800, -2541, -2307, -1567, +-1190, 552, 720, 2249, 1964, 2244, 1715, 623, +277, -1453, -1229, -2331, -1707, -1472, -881, 484, +535, 1987, 1427, 1925, 1197, 497, 82, -1323, +-1008, -2042, -1272, -1317, -569, 374, 537, 1814, +1251, 1879, 980, 582, -69, -1232, -1037, -2031, +-1278, -1271, -492, 465, 703, 1794, 1424, 1579, +1083, 232, -62, -1253, -1188, -1585, -1515, -679, +-786, 619, 462, 1326, 1427, 912, 1403, -128, +486, -993, -656, -938, -1363, -127, -1174, 750, +-325, 954, 652, 254, 1110, -703, 923, -1108, +257, -514, -480, 620, -890, 1373, -850, 1031, +-313, -200, 359, -1406, 850, -1642, 822, -610, +249, 960, -482, 1929, -901, 1522, -706, -87, +-135, -1729, 523, -2110, 887, -846, 717, 1099, +47, 2207, -781, 1534, -1170, -327, -744, -1889, +321, -1914, 1267, -427, 1326, 1356, 323, 2056, +-979, 1094, -1612, -699, -1129, -2021, 211, -1718, +1456, 9, 1704, 1768, 693, 2201, -814, 787, +-1810, -1283, -1590, -2423, -228, -1605, 1276, 497, +1986, 2249, 1297, 2299, -279, 570, -1707, -1605, +-2013, -2662, -901, -1770, 845, 502, 2017, 2511, +1706, 2724, 278, 901, -1338, -1740, -2049, -3148, +-1260, -2183, 374, 486, 1772, 2804, 1815, 2970, +545, 888, -1146, -1831, -1916, -3047, -1165, -1945, +363, 610, 1609, 2584, 1499, 2496, 334, 520, +-1018, -1841, -1610, -2700, -960, -1460, 401, 993, +1439, 2661, 1406, 2254, 338, 57, -980, -2326, +-1505, -2883, -893, -1218, 369, 1501, 1269, 3102, +1152, 2273, 121, -336, -895, -2739, -1094, -2963, +-344, -880, 707, 1934, 1109, 3193, 520, 1935, +-520, -844, -1155, -2986, -916, -2786, 96, -383, +1177, 2349, 1452, 3231, 687, 1671, -726, -1261, +-1738, -3148, -1471, -2651, -101, -109, 1482, 2513, +2014, 3091, 1063, 1386, -665, -1466, -1885, -3012, +-1764, -2286, -360, 239, 1339, 2564, 2006, 2761, +1261, 949, -386, -1692, -1723, -2890, -1825, -1936, +-618, 476, 1069, 2467, 2014, 2538, 1517, 851, +-125, -1466, -1672, -2554, -2016, -1843, -842, 178, +981, 2005, 2012, 2283, 1547, 928, -85, -1109, +-1526, -2239, -1910, -1667, -768, 186, 904, 1810, +1866, 2009, 1442, 694, -148, -1066, -1465, -1952, +-1735, -1396, -622, 105, 828, 1398, 1603, 1720, +1155, 797, -127, -505, -1210, -1456, -1461, -1352, +-471, -372, 804, 730, 1494, 1318, 961, 974, +-314, 131, -1294, -775, -1387, -1119, -379, -778, +751, -47, 1400, 749, 1051, 1049, 8, 764, +-998, -8, -1379, -845, -700, -1154, 319, -705, +1125, 271, 1021, 1143, 275, 1175, -623, 357, +-1080, -825, -685, -1385, 36, -885, 803, 332, +877, 1439, 384, 1379, -361, 240, -830, -1240, +-658, -1853, -217, -937, 403, 761, 600, 2060, +555, 1671, 188, -57, -273, -1839, -539, -2187, +-649, -708, -298, 1308, 140, 2359, 596, 1380, +706, -723, 352, -2279, -219, -1954, -697, 60, +-618, 2065, -247, 2452, 255, 715, 508, -1656, +438, -2780, 215, -1565, -89, 1004, -363, 2807, +-537, 2276, -428, -237, -8, -2575, 537, -2773, +808, -516, 588, 2200, -151, 3152, -916, 1345, +-1136, -1663, -497, -3398, 527, -2307, 1274, 755, +1171, 3277, 190, 3219, -916, 509, -1390, -2626, +-928, -3707, 152, -1786, 1186, 1514, 1426, 3590, +761, 2712, -540, -240, -1455, -2951, -1508, -3174, +-436, -894, 970, 1960, 1864, 3195, 1445, 1797, +-62, -850, -1480, -2809, -2014, -2385, -932, -135, +759, 2097, 1973, 2558, 1687, 875, 146, -1329, +-1447, -2342, -2024, -1370, -983, 651, 796, 1876, +2057, 1591, 1788, 8, 53, -1263, -1758, -1485, +-2372, -591, -1061, 521, 1160, 981, 2675, 824, +2122, 239, -115, -192, -2411, -547, -2978, -665, +-1076, -642, 1742, -144, 3340, 612, 2283, 1266, +-717, 978, -3230, -225, -3114, -1591, -377, -1732, +2772, -287, 3675, 1684, 1516, 2350, -1984, 854, +-3849, -1575, -2556, -2747, 967, -1449, 3626, 1192, +3336, 2855, 222, 1976, -2969, -619, -3649, -2671, +-1276, -2240, 2045, 130, 3433, 2325, 2051, 2186, +-930, 102, -2892, -2021, -2421, -1944, -92, -26, +2026, 1854, 2345, 1646, 883, -200, -1149, -1753, +-1973, -1385, -1292, 407, 324, 1585, 1469, 1137, +1409, -469, 369, -1213, -958, -731, -1580, 325, +-1014, 534, 487, 47, 1730, -104, 1695, 386, +34, 884, -1914, 38, -2408, -1374, -670, -1821, +1884, -222, 2937, 2097, 1490, 2538, -1473, 529, +-3286, -2299, -2319, -2910, 590, -838, 3090, 1963, +3011, 2838, 564, 1120, -2368, -1240, -3379, -2349, +-1895, -1376, 1074, 376, 3176, 1642, 3020, 1529, +602, 383, -2507, -949, -3822, -1561, -2248, -910, +1286, 435, 3898, 1472, 3410, 1231, -8, -68, +-3353, -1281, -3838, -1389, -1113, -303, 2249, 997, +3437, 1410, 1777, 663, -1057, -610, -2489, -1264, +-1817, -972, 115, 166, 1369, 1054, 1243, 1172, +227, 259, -549, -908, -505, -1330, 42, -569, +296, 856, -57, 1476, -395, 750, -372, -809, +157, -1545, 588, -761, 475, 652, -67, 1377, +-390, 712, -373, -393, -149, -1001, -52, -728, +14, -45, 396, 501, 786, 915, 583, 789, +-523, 46, -1648, -1291, -1408, -1877, 341, -592, +2214, 1764, 2215, 2918, 207, 1088, -2136, -2087, +-2811, -3406, -1077, -1356, 1548, 1934, 3043, 3064, +2098, 1445, -657, -1127, -3060, -2191, -2940, -1657, +-91, -158, 3028, 1457, 3514, 2293, 720, 1415, +-2831, -1289, -3658, -3223, -1212, -2184, 2356, 1559, +3604, 3945, 1787, 2373, -1375, -1716, -3200, -4033, +-2265, -2393, 288, 1286, 2631, 3571, 2683, 2662, +636, -274, -1932, -2889, -2898, -3227, -1410, -969, +1309, 2163, 2965, 3698, 2080, 2120, -642, -1261, +-2863, -3669, -2654, -3065, -37, 49, 2582, 3116, +2926, 3776, 618, 1307, -2174, -2323, -2957, -4068, +-1178, -2333, 1599, 1387, 2844, 3747, 1766, 2838, +-859, -267, -2639, -2822, -2289, -3032, 88, -1053, +2391, 1683, 2701, 3217, 641, 2215, -2030, -778, +-2819, -3329, -1230, -2739, 1445, 341, 2828, 2971, +1877, 2418, -624, -207, -2551, -2127, -2359, -1625, +-262, 165, 2082, 1275, 2581, 990, 887, -125, +-1541, -891, -2498, -808, -1214, 136, 1065, 927, +2233, 845, 1243, -209, -895, -970, -2103, -683, +-1206, 273, 906, 763, 1954, 350, 925, -314, +-1068, -505, -1823, -83, -574, 396, 1103, 432, +1370, 1, 94, -583, -1019, -572, -776, 119, +311, 801, 853, 734, 262, -279, -718, -981, +-892, -797, 6, 170, 1083, 903, 1409, 971, +168, 459, -1463, -550, -2057, -1317, -630, -1318, +1627, 42, 2562, 1594, 1152, 1837, -1385, 371, +-2560, -1384, -1414, -1742, 868, -680, 2095, 674, +1390, 1208, -360, 989, -1561, 273, -1282, -684, +-23, -1266, 1078, -957, 1008, 236, 184, 1260, +-739, 1136, -767, 96, -211, -721, 341, -825, +383, -346, -13, 11, -149, 234, -110, 345, +256, 400, 128, 239, 9, -17, -384, -195, +-267, -416, 85, -441, 347, -288, 202, 295, +-146, 730, -213, 580, 145, -128, 502, -611, +300, -414, -427, 113, -827, 257, -499, -152, +460, -348, 1115, 99, 836, 773, -181, 754, +-1055, -188, -954, -1207, -38, -1070, 865, 73, +764, 1221, 5, 1105, -616, 53, -346, -867, +185, -820, 289, -148, -147, 335, -387, 499, +6, 337, 349, 145, 346, -366, -220, -813, +-342, -504, -148, 474, 168, 1399, 107, 866, +-96, -565, 62, -1774, 68, -1216, 120, 389, +-153, 1736, -75, 1525, 69, 10, 215, -1377, +65, -1686, -169, -532, -156, 950, 11, 1663, +301, 1027, 317, -461, 113, -1537, -346, -1410, +-644, -131, -275, 1245, 676, 1681, 1103, 813, +453, -784, -903, -1738, -1502, -1408, -627, 120, +899, 1532, 1670, 1764, 867, 617, -663, -1015, +-1679, -1839, -1256, -1313, 195, 298, 1442, 1598, +1474, 1761, 22, 498, -1276, -1143, -1291, -1849, +-121, -1108, 917, 521, 823, 1707, -86, 1503, +-553, 9, -312, -1494, 160, -1753, 246, -418, +23, 1390, -146, 1886, 15, 718, 183, -1194, +158, -1862, -98, -974, -355, 676, -202, 1509, +361, 1171, 783, 225, 291, -855, -724, -1317, +-1185, -1119, -311, 59, 1191, 1363, 1526, 1704, +281, 549, -1383, -1191, -1653, -1879, -391, -1018, +1242, 765, 1607, 1807, 570, 1425, -967, -125, +-1620, -1611, -1035, -1864, 465, -447, 1558, 1345, +1308, 2069, 62, 894, -1342, -991, -1593, -1960, +-722, -1151, 738, 464, 1612, 1579, 1292, 1370, +-105, 57, -1428, -1089, -1526, -1414, -434, -492, +1075, 680, 1436, 1201, 636, 597, -493, -299, +-1004, -749, -641, -500, 101, 73, 736, 295, +748, 302, 159, 108, -646, -92, -835, -205, +-92, -206, 678, 21, 871, 202, 160, 363, +-585, 33, -680, -232, -203, -436, 78, -286, +273, 193, 363, 422, 240, 458, 131, 173, +-376, -247, -484, -544, -373, -649, 61, -159, +196, 574, 436, 1029, 289, 500, 22, -514, +-195, -1008, -590, -590, -296, 372, -34, 633, +420, 323, 414, -148, 423, -215, -5, -42, +-516, 95, -614, 138, -310, 57, 595, -227, +882, -538, 396, -327, -478, 368, -750, 998, +-280, 649, 287, -290, 556, -1075, 271, -827, +91, -114, -160, 642, -287, 998, -434, 677, +-203, -109, 263, -1233, 501, -1229, 522, -1, +66, 1436, -445, 1366, -779, -273, -588, -1478, +128, -961, 971, 762, 875, 1209, -119, 165, +-976, -1121, -993, -836, 91, 641, 884, 1366, +660, 424, -32, -1108, -453, -1455, -385, -161, +-185, 1390, -157, 1340, 37, -148, 546, -1385, +796, -1019, 331, 522, -507, 1205, -1263, 290, +-729, -859, 519, -767, 1454, 544, 1258, 1130, +-234, 229, -1703, -1188, -1686, -1252, 183, 93, +1854, 1379, 2035, 1393, 26, -84, -1969, -1373, +-1971, -1556, -231, -158, 1540, 1429, 1704, 1786, +229, 299, -1077, -1579, -1135, -1829, -251, -186, +540, 1608, 509, 1487, 92, -204, -117, -1368, +30, -735, -57, 696, -484, 1060, -687, -171, +37, -1194, 1126, -763, 1224, 828, -6, 1542, +-1477, 384, -1491, -1206, -71, -1469, 1382, 141, +1378, 1493, 247, 1014, -865, -791, -925, -1655, +-414, -502, 193, 1186, 593, 1639, 746, 320, +428, -1044, -269, -1400, -1027, -693, -911, 380, +168, 1218, 1234, 1305, 1198, 458, -143, -1088, +-1469, -1835, -1265, -936, 220, 814, 1430, 1727, +1239, 1063, -210, -237, -1371, -961, -1059, -928, +-83, -613, 729, -57, 870, 815, 524, 1270, +-34, 781, -550, -616, -1025, -1541, -696, -997, +327, 279, 1091, 1253, 1029, 1083, 57, 217, +-784, -796, -914, -1201, -438, -707, 70, 431, +525, 1382, 900, 921, 806, -310, 173, -1268, +-1062, -979, -1524, 221, -811, 1020, 807, 988, +1878, 195, 1531, -710, -303, -1284, -1855, -875, +-1887, 363, -305, 1595, 1651, 1661, 2073, 158, +715, -1551, -1353, -2109, -2090, -940, -1096, 968, +938, 2114, 1869, 1673, 1188, -16, -381, -1630, +-1498, -2029, -1159, -924, 50, 785, 902, 1786, +756, 1573, 146, 248, -412, -1111, -382, -1762, +-214, -1147, -26, 285, 148, 1460, 436, 1555, +483, 440, 32, -740, -695, -1364, -956, -994, +-191, -131, 854, 766, 1242, 1276, 613, 920, +-610, -13, -1356, -1134, -970, -1457, 189, -813, +1196, 486, 1298, 1651, 447, 1737, -829, 487, +-1398, -1540, -1031, -2501, 163, -1391, 1216, 1237, +1439, 2766, 572, 1760, -784, -797, -1570, -2356, +-1173, -1555, 283, 338, 1326, 1407, 1296, 1010, +109, 184, -907, -305, -1190, -411, -389, -570, +451, -661, 835, -171, 576, 599, -17, 1130, +-428, 775, -537, -163, -190, -1013, -38, -1126, +55, -491, 122, 405, 378, 991, 632, 848, +408, 323, -383, -303, -1095, -665, -810, -779, +70, -548, 947, 52, 944, 763, 281, 1105, +-474, 610, -480, -321, -312, -1092, -141, -1071, +-88, -330, 29, 585, 408, 1138, 588, 943, +354, 189, -461, -774, -834, -1175, -622, -931, +215, -36, 803, 917, 648, 1356, 112, 973, +-493, -262, -635, -1348, -443, -1534, 147, -456, +478, 900, 505, 1459, 129, 908, -340, -143, +-374, -894, -71, -1061, 257, -667, 84, 208, +-58, 1107, -197, 1209, -20, 233, 110, -1087, +244, -1350, 229, -298, 48, 1017, -258, 1110, +-480, 112, -329, -852, 98, -788, 523, 73, +499, 656, 324, 625, 79, 67, -417, -431, +-1033, -713, -1128, -589, -181, -16, 1587, 779, +2437, 1291, 1147, 782, -1522, -518, -3352, -1782, +-2445, -1754, 704, -240, 3583, 1735, 3489, 2464, +530, 1263, -2980, -1085, -4010, -2631, -1625, -2041, +1952, 118, 3673, 2154, 2252, 2273, -850, 677, +-2834, -1379, -2242, -1965, 57, -949, 1883, 680, +1965, 1463, 306, 785, -1227, -375, -1530, -1027, +-471, -606, 849, 369, 1313, 880, 628, 620, +-492, -283, -1187, -946, -972, -851, 108, -36, +1115, 847, 1332, 994, 359, 493, -975, -385, +-1544, -773, -657, -756, 627, -358, 1342, 130, +848, 599, -191, 919, -859, 711, -764, -59, +-219, -927, 355, -1202, 447, -625, 197, 335, +-27, 932, -122, 961, 172, 567, 212, 95, +-53, -582, -478, -1200, -600, -1355, -317, -481, +309, 1131, 826, 2132, 987, 1634, 583, -264, +-471, -1995, -1573, -2207, -1639, -848, -432, 982, +1427, 1875, 2608, 1540, 1550, 298, -739, -794, +-2796, -1414, -2622, -1277, -278, -485, 2532, 655, +3171, 1588, 1098, 1441, -1863, 158, -3099, -1356, +-1506, -1668, 1115, -585, 2468, 910, 1411, 1362, +-512, 492, -1609, -619, -1057, -990, 86, -295, +852, 682, 754, 1031, 181, 374, -151, -843, +-578, -1421, -641, -856, -443, 662, 306, 1557, +1096, 1280, 1212, 126, 230, -900, -1256, -1172, +-1753, -1035, -1046, -416, 718, 330, 1914, 1283, +1804, 1474, 388, 903, -1408, -401, -2228, -1502, +-1478, -1821, 346, -1099, 1970, 380, 2114, 1861, +819, 2197, -1001, 1112, -1965, -774, -1628, -2123, +-402, -2120, 1050, -927, 1651, 860, 1460, 2187, +326, 2356, -904, 844, -1612, -1318, -1434, -2681, +-446, -2085, 863, -90, 1741, 1739, 1465, 2331, +399, 1446, -1160, -124, -1879, -1724, -1314, -2161, +159, -1153, 1454, 780, 1712, 2055, 690, 1603, +-807, -73, -1499, -1484, -1091, -1443, 199, -273, +1121, 1077, 1072, 1325, 233, 401, -667, -930, +-889, -1572, -536, -712, 200, 753, 671, 1717, +756, 1293, 318, 7, -356, -1267, -764, -1736, +-895, -1237, -255, 83, 609, 1580, 1224, 2158, +995, 1222, -87, -625, -1275, -2057, -1499, -1938, +-496, -646, 808, 913, 1381, 1753, 949, 1520, +-115, 393, -876, -976, -936, -1497, -333, -915, +349, 303, 584, 785, 200, 340, -306, -274, +-200, -171, 440, 601, 669, 975, 196, 379, +-808, -893, -1151, -1703, -529, -1423, 378, 35, +1034, 1620, 1147, 2362, 707, 1530, -269, -362, +-1269, -2203, -1754, -2698, -842, -1516, 861, 775, +1947, 2766, 1496, 2864, -107, 1009, -1394, -1770, +-1318, -2981, -119, -1876, 715, 563, 541, 1968, +-482, 1436, -848, -2, 120, -759, 1510, -265, +1672, 277, 34, 194, -2045, -523, -2508, -922, +-815, -477, 1420, 452, 2465, 1151, 1612, 1015, +-195, 208, -1407, -694, -1600, -948, -967, -581, +122, -175, 900, 66, 1159, 180, 756, 657, +4, 1158, -720, 735, -735, -452, -302, -1617, +149, -1526, 265, -245, -26, 1014, -166, 1355, +175, 859, 557, 205, 622, -327, 104, -671, +-696, -1072, -1130, -980, -827, -207, 97, 877, +1204, 1665, 1524, 1243, 671, -17, -800, -1302, +-1560, -1487, -940, -704, 293, 372, 931, 669, +366, 455, -253, 328, -202, 474, 507, 568, +793, -24, 39, -943, -954, -1476, -1446, -1030, +-729, 245, 661, 1555, 1667, 2033, 1556, 952, +208, -849, -1416, -2174, -1848, -1749, -696, 29, +856, 1443, 1439, 1515, 665, 501, -528, -441, +-762, -644, -260, -475, 363, -319, 406, -203, +145, 165, -132, 459, -338, 566, -503, 199, +-376, -250, 245, -312, 849, -197, 972, -4, +197, -110, -794, -331, -1319, -244, -696, 359, +216, 1033, 1018, 1061, 1021, 92, 256, -1409, +-452, -1981, -747, -1107, -393, 938, 33, 2401, +303, 2131, 53, 102, -77, -1895, -89, -2440, +137, -1126, 365, 780, 436, 1797, 139, 1472, +-363, 376, -878, -698, -939, -1099, -216, -875, +848, -269, 1601, 415, 1237, 656, 29, 535, +-1398, 202, -1968, -88, -1261, -329, 162, -433, +1757, -409, 2055, 39, 1327, 502, -468, 495, +-1838, 45, -2137, -507, -917, -383, 707, 242, +1752, 550, 1458, 183, 343, -593, -525, -739, +-851, -59, -623, 822, -497, 862, -281, 111, +66, -686, 676, -787, 891, -241, 551, 186, +-82, 297, -591, 304, -641, 387, -461, 409, +-115, -32, 48, -686, 335, -956, 540, -449, +529, 543, 370, 1069, -128, 824, -793, -168, +-967, -832, -519, -776, 496, -95, 1130, 507, +816, 432, -154, -32, -831, -310, -483, -91, +170, 328, 520, 384, -15, 0, -515, -506, +-473, -579, 211, -270, 804, 334, 528, 708, +-42, 656, -621, 206, -500, -519, -184, -935, +213, -795, 257, -29, 198, 863, 60, 1195, +-92, 571, -98, -497, -55, -1167, 175, -837, +82, 159, 1, 795, -213, 646, -282, 31, +-281, -342, -37, -239, 399, 23, 812, 30, +694, -136, -190, -196, -1152, -63, -1241, 336, +-350, 536, 824, 345, 1259, -354, 790, -926, +23, -771, -497, 257, -643, 1141, -624, 1024, +-424, 8, -273, -972, 287, -1026, 800, -327, +1178, 386, 905, 748, -173, 674, -1294, 299, +-1813, -241, -1022, -780, 297, -831, 1444, -352, +1714, 435, 1156, 1010, -38, 908, -1174, 175, +-1775, -787, -1441, -1198, -138, -672, 1075, 402, +1682, 1015, 1259, 695, 336, -91, -761, -527, +-1377, -260, -1264, 92, -453, 86, 668, -205, +1256, -328, 963, -54, 13, 353, -729, 484, +-723, 329, -159, -78, 455, -320, 412, -412, +-141, -259, -555, -143, -442, 3, 77, 213, +594, 456, 675, 644, 441, 375, 59, -153, +-569, -859, -1115, -1076, -1032, -802, -172, 191, +1102, 1267, 1730, 1772, 1084, 1051, -251, -644, +-1368, -2043, -1604, -2030, -870, -457, 301, 1336, +1164, 2132, 1397, 1311, 755, -134, -244, -1303, +-882, -1408, -952, -776, -542, 118, 32, 709, +349, 895, 473, 675, 430, 210, 292, -356, +124, -746, -9, -645, -314, -126, -503, 402, +-576, 349, -383, -132, 82, -356, 547, 184, +902, 993, 967, 985, 390, -113, -683, -1526, +-1593, -1771, -1633, -739, -470, 876, 1244, 1800, +2115, 1572, 1710, 595, 114, -636, -1546, -1452, +-2123, -1617, -1355, -929, 225, 213, 1555, 1339, +1683, 1721, 821, 1049, -398, -233, -1064, -1290, +-1084, -1284, -465, -387, 157, 375, 735, 361, +818, -82, 370, -41, -286, 636, -737, 1051, +-520, 491, 89, -610, 598, -1289, 449, -1056, +-3, -361, -439, 311, -377, 854, -56, 1206, +130, 1061, 202, 204, 130, -926, 79, -1544, +73, -1217, -47, -272, -107, 690, -93, 1285, +-82, 1252, -351, 634, -347, -406, 39, -1249, +800, -1225, 1142, -405, 411, 596, -773, 869, +-1680, 368, -1127, -324, 165, -361, 1387, 220, +1620, 784, 804, 625, -497, -385, -1442, -1317, +-1345, -1494, -455, -503, 822, 954, 1266, 1999, +818, 1777, -145, 401, -789, -1292, -683, -2232, +-70, -1738, 358, -283, 468, 1252, 106, 1943, +-390, 1519, -535, 340, -298, -872, 421, -1499, +982, -1205, 883, -340, -229, 500, -1270, 759, +-1600, 551, -444, 259, 1099, 215, 1778, 262, +1091, 12, -328, -485, -1215, -998, -1228, -919, +-546, -251, 57, 716, 653, 1375, 955, 1210, +908, 330, 375, -777, -560, -1375, -1181, -1188, +-1058, -299, -347, 594, 545, 1133, 1081, 1011, +994, 344, 437, -392, -280, -866, -891, -774, +-954, -334, -599, 223, 92, 527, 716, 652, +874, 320, 611, -153, 85, -544, -403, -456, +-650, 47, -624, 403, -428, 243, -62, -228, +500, -363, 856, -75, 814, 392, 237, 444, +-623, 96, -1078, -299, -897, -471, -116, -287, +634, 82, 922, 372, 686, 373, 145, 112, +-335, -203, -710, -280, -713, -164, -379, -15, +341, 86, 872, 217, 700, 249, -42, 74, +-713, -292, -573, -423, 82, -94, 606, 313, +340, 353, -226, -58, -569, -268, -331, -41, +253, 371, 579, 273, 507, -178, -70, -581, +-543, -430, -609, 59, -187, 399, 446, 509, +598, 313, 255, 100, -245, -212, -519, -420, +-504, -527, -55, -305, 493, 85, 853, 487, +568, 608, -383, 270, -1317, -208, -1099, -406, +23, -140, 1233, 180, 1419, 86, 544, -406, +-575, -592, -1147, -127, -986, 642, -243, 960, +639, 569, 862, -229, 506, -752, -260, -781, +-417, -394, 53, 140, 430, 373, 68, 326, +-644, 194, -774, 257, -139, 427, 634, 276, +695, -303, 332, -888, 14, -931, -44, -476, +-103, 245, -481, 774, -674, 1064, -453, 927, +177, 342, 719, -471, 818, -1061, 429, -1249, +-162, -997, -501, -309, -592, 763, -363, 1818, +-199, 1887, -48, 679, 219, -1037, 476, -1952, +697, -1506, 436, -411, -56, 472, -529, 826, +-782, 916, -700, 822, -290, 528, 341, -11, +762, -654, 909, -1056, 497, -1056, 23, -435, +-376, 469, -744, 1002, -980, 773, -745, 177, +53, -80, 1046, 120, 1474, 145, 907, -420, +-88, -1104, -956, -1007, -1238, -152, -905, 875, +-197, 1196, 562, 853, 1086, 225, 914, -324, +326, -572, -313, -590, -727, -490, -837, -532, +-496, -416, 16, 95, 617, 1089, 814, 1680, +400, 1111, -214, -394, -631, -1677, -439, -1694, +55, -690, 491, 463, 384, 972, -116, 907, +-677, 536, -610, 149, 90, -182, 800, -383, +910, -436, 314, -398, -469, -316, -781, -165, +-664, 113, -307, 423, 220, 656, 636, 566, +802, 129, 468, -440, -212, -717, -703, -456, +-583, 68, -155, 273, 227, 5, 231, -269, +43, -29, -1, 597, 255, 896, 427, 458, +238, -459, -419, -1158, -914, -1145, -635, -368, +249, 700, 1020, 1365, 800, 1075, -96, -46, +-852, -1023, -673, -1072, 81, -252, 735, 552, +552, 683, -150, 223, -743, -276, -723, -465, +38, -299, 814, 138, 893, 529, 220, 567, +-607, 34, -882, -593, -296, -715, 350, -137, +489, 516, 105, 545, -242, 24, -81, -460, +331, -312, 414, 197, 20, 511, -520, 272, +-701, -220, -337, -473, 222, -321, 546, 15, +708, 190, 488, 277, 2, 247, -566, 139, +-958, -198, -713, -478, 102, -293, 734, 340, +844, 792, 304, 390, -256, -583, -489, -1135, +-307, -646, -5, 457, 291, 1182, 264, 1007, +-73, 183, -521, -699, -615, -1099, -63, -850, +779, -5, 1102, 777, 531, 935, -398, 333, +-1138, -395, -925, -552, -257, -101, 411, 381, +684, 393, 626, -63, 332, -605, 87, -779, +-173, -387, -443, 407, -579, 1078, -577, 1077, +-270, 334, 262, -565, 871, -983, 1038, -825, +629, -398, -388, -70, -1139, 237, -1139, 644, +-339, 952, 509, 904, 804, 283, 561, -593, +141, -1235, -66, -1220, -243, -618, -322, 234, +-289, 865, -42, 1109, 122, 1017, 94, 554, +-11, -195, 6, -1037, 175, -1420, 164, -1096, +-21, -210, -98, 685, 3, 1230, 102, 1263, +-109, 775, -439, -153, -374, -1020, 170, -1279, +704, -715, 657, 84, 81, 445, -541, 287, +-694, 86, -333, 327, 111, 744, 407, 859, +430, 258, 169, -819, -126, -1714, -293, -1656, +-246, -395, 45, 1267, 289, 2216, 171, 1649, +-106, 129, -361, -1246, -228, -1605, 116, -1048, +396, -169, 331, 459, 33, 667, -284, 571, +-476, 363, -278, 267, 96, 208, 570, 5, +653, -424, 189, -874, -427, -965, -841, -495, +-645, 342, -91, 1170, 494, 1430, 805, 899, +772, -224, 295, -1184, -471, -1399, -885, -843, +-804, -21, -183, 544, 394, 879, 641, 943, +424, 683, 160, -57, -202, -854, -288, -1118, +-100, -552, 222, 298, 243, 683, -224, 417, +-668, -121, -583, -261, 185, -20, 751, 320, +865, 312, 353, -6, -99, -316, -538, -363, +-780, -182, -747, -71, -224, -46, 566, 14, +938, 314, 676, 590, 12, 494, -333, -33, +-452, -566, -299, -671, -205, -370, 18, -17, +143, 170, 38, 333, -195, 469, -121, 456, +348, 56, 793, -434, 649, -574, -109, -186, +-838, 324, -1060, 404, -759, 15, -128, -455, +603, -498, 1070, -96, 1118, 415, 505, 667, +-344, 560, -953, 201, -1018, -212, -650, -650, +-109, -910, 442, -787, 729, -114, 775, 793, +391, 1285, -98, 965, -325, 53, -365, -625, +-237, -756, -352, -466, -413, -348, -249, -424, +294, -282, 854, 329, 883, 1153, 276, 1372, +-415, 693, -685, -571, -532, -1413, -215, -1349, +-77, -510, 3, 367, 265, 775, 494, 753, +388, 529, 139, 244, -43, -130, -62, -461, +-146, -543, -555, -308, -766, 2, -369, 167, +507, 130, 1100, 55, 880, -44, -4, -18, +-666, 121, -777, 401, -405, 425, 48, 19, +316, -591, 366, -785, 290, -349, 102, 279, +-203, 529, -315, 320, -280, 64, 12, -30, +293, 15, 330, 8, 128, 27, -123, -14, +-233, -207, -243, -499, -121, -503, 9, 45, +168, 735, 269, 920, 174, 393, -15, -341, +-117, -690, -43, -563, -84, -260, -199, 49, +-283, 304, -50, 472, 350, 378, 510, 36, +197, -297, -161, -386, -378, -191, -296, 75, +-118, 274, 51, 280, 190, 117, 317, -159, +146, -395, -113, -432, -191, -193, -75, 259, +73, 661, 21, 697, -144, 225, -142, -408, +58, -746, 211, -510, 221, -94, 97, 144, +-99, 165, -214, 207, -325, 379, -116, 380, +192, 142, 396, -192, 242, -333, -43, -333, +-180, -315, -188, -240, -67, -10, -196, 299, +-91, 431, 104, 378, 385, 279, 300, 163, +-52, -192, -322, -700, -266, -870, 112, -335, +289, 515, 154, 933, -289, 604, -510, -18, +-358, -445, 188, -520, 643, -406, 705, -40, +329, 473, -224, 718, -625, 330, -727, -524, +-472, -974, 3, -589, 502, 330, 711, 918, +558, 751, 109, 82, -317, -508, -521, -601, +-396, -288, -76, 156, 282, 288, 264, 96, +-66, -190, -268, -171, -130, 108, 378, 327, +550, 215, 210, -123, -400, -279, -615, -126, +-396, 195, -13, 303, 338, 52, 508, -367, +548, -538, 122, -280, -559, 208, -922, 484, +-500, 447, 367, 288, 906, 219, 657, 28, +-17, -446, -385, -926, -426, -842, -332, -56, +-276, 777, -71, 1011, 300, 593, 585, 30, +448, -365, -34, -529, -388, -549, -333, -232, +-17, 188, 136, 425, -25, 201, -361, -125, +-302, -151, 118, 66, 679, 217, 786, 94, +327, -24, -409, -58, -848, -72, -759, -182, +-303, -246, 242, -61, 559, 166, 578, 243, +359, 88, 101, -13, -101, 25, -161, 119, +-293, 101, -466, -42, -499, -247, -305, -426, +201, -362, 649, 7, 829, 482, 584, 663, +59, 362, -519, -118, -840, -379, -716, -356, +-264, -253, 220, -186, 493, -31, 535, 230, +383, 383, 236, 248, 34, 26, -200, -33, +-496, 47, -543, 5, -429, -315, -57, -585, +376, -478, 604, 84, 562, 697, 329, 916, +-58, 550, -362, -152, -547, -714, -496, -828, +-200, -460, 136, 24, 293, 373, 247, 398, +215, 271, 190, 163, 255, 123, 80, 100, +-192, -4, -414, -115, -458, -228, -368, -334, +-151, -498, 160, -494, 529, -99, 794, 653, +539, 1151, -121, 858, -753, -98, -854, -815, +-303, -645, 395, 25, 654, 293, 272, -224, +-247, -860, -443, -751, -159, 185, 274, 1180, +446, 1468, 265, 876, -60, -160, -357, -1062, +-465, -1407, -260, -981, 121, -15, 473, 862, +465, 1007, 113, 383, -266, -438, -396, -640, +-289, -92, -120, 676, 135, 881, 323, 256, +451, -721, 234, -1257, -180, -911, -439, 57, +-325, 952, -55, 1122, 103, 590, 69, -207, +24, -668, 72, -596, 76, -208, 91, 86, +139, 162, 264, 155, 126, 214, -287, 268, +-757, 105, -653, -216, 3, -401, 737, -259, +938, 41, 470, 195, -243, 109, -684, 58, +-588, 131, -240, 189, 199, 44, 308, -175, +287, -219, 140, -65, 82, 12, -56, -107, +-168, -181, -215, -15, -128, 319, 84, 444, +124, 263, 11, -38, -136, -304, -92, -521, +68, -608, 283, -336, 369, 404, 171, 1160, +-207, 1186, -645, 253, -614, -967, -118, -1476, +549, -958, 700, 40, 294, 649, -283, 678, +-374, 502, -56, 508, 183, 559, 112, 223, +-150, -528, -284, -1215, -168, -1227, 107, -545, +232, 416, 272, 1027, 88, 1075, -155, 676, +-271, 76, -100, -422, 161, -662, 278, -591, +139, -336, -142, -44, -233, 159, -236, 337, +-104, 390, 61, 305, 237, 43, 306, -261, +123, -397, -148, -284, -284, 90, -58, 433, +152, 515, 176, 83, -82, -523, -234, -810, +-204, -430, 32, 346, 162, 854, 196, 746, +196, 222, 176, -342, 19, -696, -275, -774, +-507, -513, -435, 100, 27, 717, 543, 886, +710, 489, 418, -45, -96, -302, -512, -226, +-593, -230, -442, -512, -149, -783, 238, -594, +554, 225, 600, 1211, 284, 1615, -209, 1004, +-460, -279, -278, -1403, 26, -1590, 188, -874, +-22, 133, -322, 805, -391, 907, -45, 597, +447, 166, 717, -153, 542, -262, -52, -191, +-428, -151, -545, -183, -390, -247, -341, -209, +-223, -37, 162, 250, 759, 517, 995, 588, +449, 211, -503, -514, -1043, -987, -722, -661, +0, 342, 474, 1147, 490, 1001, 306, 29, +129, -877, -101, -1148, -361, -666, -445, 115, +-170, 822, 256, 1109, 478, 744, 281, -92, +-111, -862, -358, -1003, -330, -524, -62, 207, +243, 592, 373, 548, 238, 213, -55, -95, +-358, -199, -327, -112, -85, 2, 193, -7, +219, -111, 38, -233, -180, -159, -122, -7, +153, 230, 363, 368, 338, 376, -18, 203, +-378, -81, -584, -384, -466, -600, -142, -568, +371, -227, 709, 431, 678, 926, 239, 780, +-371, 18, -643, -708, -540, -715, -118, -127, +239, 383, 439, 340, 306, 7, -16, -242, +-343, -278, -388, -215, -12, -36, 435, 378, +541, 739, 158, 579, -321, -144, -584, -854, +-396, -931, -72, -363, 264, 335, 408, 726, +398, 659, 194, 264, -90, -248, -370, -525, +-471, -387, -332, 25, 43, 266, 447, 146, +609, -106, 324, -201, -219, -100, -591, 64, +-487, 216, 3, 351, 404, 333, 419, -22, +24, -455, -353, -600, -360, -238, 32, 224, +486, 403, 492, 207, 18, -46, -518, -191, +-554, -188, -140, 30, 307, 388, 391, 639, +184, 322, 7, -484, -144, -1160, -253, -1026, +-277, -156, -17, 837, 387, 1266, 526, 971, +162, 222, -392, -585, -585, -1017, -324, -864, +121, -258, 376, 324, 342, 568, 151, 436, +-134, 189, -353, -19, -232, -153, 153, -104, +492, 57, 378, 147, -229, -85, -760, -486, +-668, -603, 23, -127, 743, 592, 944, 912, +373, 543, -413, -190, -839, -667, -633, -602, +-40, -169, 447, 205, 549, 277, 387, 86, +112, -34, -307, -9, -599, 96, -575, 63, +-9, 2, 689, 36, 848, 142, 205, 38, +-611, -321, -854, -534, -308, -260, 449, 348, +679, 656, 312, 398, -252, -141, -484, -438, +-301, -338, 107, -35, 335, 228, 303, 316, +68, 196, -226, -103, -365, -380, -279, -425, +3, -167, 342, 182, 488, 430, 313, 445, +-112, 252, -431, -54, -468, -300, -200, -317, +127, -155, 302, -79, 274, -181, 110, -257, +-46, -17, -111, 466, -29, 765, 52, 559, +8, -36, -110, -609, -227, -795, -148, -490, +62, 73, 250, 505, 281, 515, 181, 131, +-86, -247, -346, -334, -391, -94, -140, 178, +320, 331, 601, 276, 349, 65, -215, -251, +-646, -486, -570, -393, -87, -69, 442, 277, +594, 404, 385, 368, -8, 193, -374, -107, +-445, -504, -261, -602, 80, -161, 312, 508, +300, 736, 60, 261, -138, -360, -171, -490, +-85, -100, 66, 138, 79, -3, 13, -301, +-63, -208, -111, 238, -45, 571, 141, 481, +306, 36, 226, -365, -59, -499, -403, -316, +-491, -41, -221, 155, 140, 157, 420, 99, +481, 148, 373, 247, 8, 181, -405, -133, +-678, -463, -466, -441, 55, -45, 522, 335, +536, 422, 251, 223, -83, 12, -227, -102, +-268, -218, -256, -375, -141, -386, 33, -97, +225, 371, 260, 677, 221, 536, 73, 78, +-113, -396, -242, -641, -232, -535, -45, -206, +113, 182, 125, 471, -34, 507, -65, 296, +24, -43, 101, -288, 47, -307, 9, -106, +75, 74, 197, 57, 75, -108, -260, -280, +-537, -169, -448, 144, -16, 464, 475, 533, +714, 273, 558, -170, 66, -520, -525, -615, +-823, -377, -607, 71, 39, 477, 661, 639, +804, 380, 320, -130, -383, -596, -783, -597, +-514, -177, 190, 402, 703, 680, 566, 459, +-42, -45, -572, -554, -551, -688, -51, -369, +442, 241, 592, 664, 229, 525, -349, -94, +-702, -547, -532, -343, 93, 257, 665, 540, +699, 111, 213, -519, -262, -620, -450, -65, +-314, 545, -139, 679, -21, 291, 114, -206, +264, -548, 220, -642, -14, -432, -244, 79, +-272, 650, -3, 887, 270, 576, 404, -109, +251, -676, -132, -787, -540, -462, -646, 52, +-290, 384, 298, 424, 732, 244, 608, 52, +107, -22, -442, -30, -609, -48, -327, -95, +167, -143, 496, -186, 345, -172, -93, -5, +-445, 268, -324, 460, 48, 276, 349, -189, +225, -552, -101, -466, -241, -10, -82, 443, +218, 564, 310, 306, 91, -169, -265, -549, +-382, -507, -239, -39, 102, 483, 224, 499, +94, -17, -62, -558, 14, -484, 210, 130, +289, 655, 15, 602, -362, 34, -434, -510, +-169, -630, 162, -273, 273, 218, 128, 460, +-78, 221, -68, -240, 31, -449, 145, -73, +121, 549, -54, 761, -198, 223, -233, -604, +-66, -955, 84, -545, 182, 239, 87, 654, +-21, 521, -76, 110, -7, -96, 70, -53, +47, -45, -73, -269, -192, -522, -159, -367, +41, 209, 243, 785, 259, 788, 66, 207, +-147, -451, -222, -719, -159, -583, -105, -314, +-109, -20, -62, 364, 172, 780, 485, 871, +520, 384, 78, -452, -544, -1055, -837, -970, +-455, -245, 269, 573, 692, 936, 461, 630, +-121, -53, -431, -541, -241, -505, 214, -102, +353, 198, 124, 127, -236, -111, -364, -150, +-242, 114, -33, 441, 118, 480, 230, 152, +327, -399, 210, -805, -50, -805, -355, -256, +-362, 523, -139, 1039, 134, 923, 193, 237, +141, -491, 112, -822, 58, -610, -96, -153, +-329, 209, -335, 260, -4, 137, 398, 82, +468, 194, 113, 323, -335, 206, -475, -181, +-236, -534, 131, -553, 315, -215, 233, 251, +-4, 502, -156, 480, -169, 225, -32, -72, +96, -274, 88, -351, -18, -363, -164, -339, +-217, -143, -118, 279, 206, 784, 471, 894, +438, 363, -12, -529, -589, -1139, -778, -984, +-410, -231, 254, 569, 665, 939, 619, 755, +258, 213, -135, -313, -429, -578, -497, -489, +-329, -199, -4, 76, 261, 194, 295, 172, +98, 64, -48, -29, 14, 62, 136, 296, +130, 452, -126, 158, -420, -556, -484, -1108, +-171, -860, 321, 169, 629, 1193, 522, 1379, +33, 614, -462, -459, -668, -1115, -410, -1058, +59, -456, 479, 260, 492, 758, 134, 813, +-254, 434, -324, -61, -93, -401, 150, -467, +107, -408, -130, -289, -179, -54, -19, 336, +98, 655, 34, 584, -96, 84, -13, -497, +258, -675, 363, -375, 57, 101, -433, 344, +-722, 268, -476, 77, 181, 42, 772, 118, +836, 111, 249, -113, -561, -415, -900, -465, +-498, -163, 224, 312, 633, 600, 397, 530, +-131, 144, -415, -331, -249, -650, 133, -613, +327, -139, 151, 471, -233, 765, -400, 458, +-202, -206, 240, -613, 446, -442, 216, 74, +-199, 434, -404, 349, -272, -40, -33, -403, +128, -467, 204, -170, 258, 346, 229, 718, +-38, 596, -374, -2, -510, -676, -241, -876, +157, -481, 394, 183, 350, 670, 113, 724, +-103, 358, -203, -211, -235, -625, -205, -579, +-104, -54, 21, 517, 115, 585, 185, 62, +177, -524, 120, -579, 15, -49, -176, 481, +-333, 497, -334, 50, -97, -358, 218, -340, +385, -12, 239, 269, -26, 282, -162, 75, +-159, -187, -135, -369, -133, -347, -63, -76, +91, 347, 192, 599, 77, 416, -121, -94, +-149, -536, 26, -565, 150, -224, 34, 195, +-155, 422, -178, 380, 5, 158, 189, -141, +127, -312, -139, -262, -362, -19, -260, 151, +136, 73, 531, -116, 513, -165, 21, 67, +-553, 353, -692, 417, -299, 149, 189, -272, +402, -552, 301, -510, 156, -182, 75, 242, +-30, 512, -266, 520, -435, 286, -334, -60, +-16, -359, 283, -499, 361, -378, 228, -67, +25, 270, -118, 402, -226, 313, -216, 134, +-159, -28, -64, -184, 21, -368, 75, -458, +98, -252, 168, 235, 257, 684, 172, 718, +-92, 247, -478, -406, -629, -807, -374, -693, +209, -198, 633, 354, 643, 620, 267, 535, +-225, 265, -543, -19, -562, -251, -254, -450, +121, -529, 373, -352, 295, 76, 53, 510, +-130, 647, -134, 431, -57, 16, -2, -345, +26, -534, 15, -525, -39, -268, -175, 153, +-204, 540, -17, 624, 237, 330, 274, -121, +61, -442, -193, -430, -246, -215, -114, 30, +32, 129, 81, 115, 73, 82, 13, 105, +-57, 174, -126, 191, -72, 70, 73, -178, +106, -408, -31, -440, -162, -169, -129, 261, +54, 596, 233, 546, 178, 125, -78, -399, +-304, -675, -341, -492, -146, 3, 156, 504, +350, 612, 307, 284, 92, -201, -202, -416, +-384, -227, -405, 76, -145, 144, 244, -74, +533, -257, 427, -145, -50, 168, -538, 389, +-670, 334, -311, 86, 218, -165, 602, -313, +532, -304, 138, -137, -321, 124, -520, 263, +-320, 166, 45, -97, 195, -231, 26, -85, +-151, 188, -136, 326, 128, 174, 374, -103, +366, -281, 73, -239, -309, -89, -582, 35, +-528, 65, -141, 67, 338, 75, 540, 100, +327, 95, -44, 60, -261, 3, -212, -93, +-21, -187, 86, -201, 25, -59, -139, 142, +-276, 227, -232, 110, 57, -68, 368, -91, +426, 25, 127, 78, -262, -52, -410, -207, +-260, -153, -21, 69, 115, 246, 136, 228, +89, 84, 51, -45, -9, -192, -49, -316, +-82, -315, -116, -11, -102, 427, -47, 596, +32, 258, 62, -344, 36, -640, -18, -377, +45, 200, 125, 517, 49, 346, -136, -84, +-287, -358, -280, -264, -101, -2, 127, 179, +247, 163, 293, 53, 211, -19, -23, -34, +-298, -47, -433, -72, -296, -77, 52, -8, +346, 86, 344, 153, 20, 98, -361, -69, +-406, -234, -37, -216, 413, 39, 456, 288, +74, 289, -402, 15, -483, -238, -201, -214, +134, 14, 200, 138, 65, 57, 8, -118, +41, -155, 95, -79, 25, 57, -100, 223, +-205, 370, -131, 338, 8, -66, 95, -595, +40, -803, -94, -353, -143, 392, -51, 820, +125, 621, 215, 92, 148, -270, -13, -339, +-172, -289, -327, -299, -355, -265, -128, -26, +244, 354, 471, 577, 348, 418, -78, -30, +-400, -398, -345, -437, -50, -147, 163, 160, +145, 230, -37, 46, -174, -194, -135, -235, +26, -52, 237, 247, 304, 387, 136, 279, +-237, -14, -505, -278, -452, -341, -60, -227, +377, -75, 520, 9, 260, 50, -137, 121, +-329, 247, -230, 331, -1, 301, 46, 76, +-120, -270, -248, -614, -41, -671, 307, -325, +471, 279, 242, 767, -212, 800, -482, 407, +-436, -180, -175, -628, 42, -764, 257, -485, +385, 69, 419, 573, 174, 658, -263, 268, +-603, -199, -607, -343, -239, -184, 225, -24, +532, -61, 505, -90, 254, 91, -85, 307, +-330, 271, -399, -60, -320, -309, -159, -281, +17, -63, 205, 70, 326, 97, 318, 154, +111, 226, -153, 181, -349, -52, -317, -291, +-109, -337, 108, -173, 190, 55, 147, 236, +44, 292, -84, 199, -162, -17, -158, -191, +-57, -203, 80, -108, 172, -41, 139, -30, +25, 87, -63, 287, -138, 343, -222, 35, +-251, -416, -93, -557, 171, -213, 372, 306, +284, 515, -40, 306, -267, -58, -206, -238, +-41, -150, -6, 1, -128, 5, -171, -151, +44, -247, 350, -65, 388, 285, 124, 472, +-297, 248, -520, -188, -415, -411, -37, -270, +348, 39, 511, 169, 338, 132, -93, 44, +-405, 5, -410, -46, -155, -112, 95, -115, +190, -11, 148, 130, 59, 217, -14, 204, +-89, 57, -124, -234, -67, -493, 38, -401, +99, 105, 72, 656, 3, 689, -102, 111, +-202, -600, -210, -803, -38, -337, 246, 368, +360, 755, 155, 540, -230, -44, -363, -540, +-104, -591, 248, -235, 225, 182, -147, 359, +-453, 313, -291, 189, 212, 45, 538, -185, +377, -384, -56, -343, -359, -3, -334, 328, +-132, 323, -41, 70, -11, -138, 89, -85, +258, 53, 289, 80, 104, -58, -250, -223, +-464, -278, -339, -162, 25, 142, 390, 458, +488, 540, 223, 235, -257, -266, -505, -583, +-354, -520, 77, -205, 339, 144, 229, 369, +-61, 438, -166, 288, 7, 0, 146, -249, +72, -283, -181, -145, -263, -43, -113, -28, +179, -24, 307, 82, 180, 198, -122, 215, +-332, 96, -277, -89, 15, -255, 238, -301, +193, -164, 1, 129, -95, 363, 24, 326, +123, 64, 17, -209, -249, -290, -307, -230, +-120, -115, 162, -5, 275, 154, 211, 309, +109, 343, -6, 177, -133, -173, -312, -494, +-307, -569, -61, -237, 321, 346, 454, 726, +220, 550, -221, -45, -494, -549, -304, -584, +163, -223, 472, 162, 313, 324, -120, 277, +-396, 83, -225, -123, 171, -195, 327, -56, +85, 143, -297, 116, -376, -145, -48, -328, +399, -141, 484, 237, 119, 383, -386, 116, +-539, -256, -221, -343, 247, -86, 438, 229, +218, 337, -100, 172, -215, -134, -96, -375, +42, -391, 27, -127, -119, 195, -144, 352, +27, 285, 243, 116, 342, -3, 178, -121, +-141, -286, -363, -395, -279, -277, -22, 67, +186, 414, 169, 493, 78, 224, 78, -163, +126, -434, 51, -425, -164, -161, -272, 173, +-104, 415, 185, 404, 258, 97, 49, -330, +-199, -584, -219, -392, -13, 158, 162, 590, +189, 470, 113, -58, 51, -440, -22, -315, +-142, 59, -284, 135, -249, -111, 2, -239, +319, 48, 433, 448, 269, 419, -76, -61, +-310, -481, -296, -444, -114, -113, 64, 91, +160, 59, 205, 44, 204, 232, 110, 424, +-69, 284, -217, -196, -199, -661, 36, -666, +230, -187, 244, 395, 68, 627, -140, 355, +-223, -126, -110, -389, 105, -279, 245, 39, +257, 240, 81, 142, -143, -153, -283, -383, +-215, -324, 8, 20, 235, 403, 279, 494, +126, 244, -74, -161, -151, -444, -57, -476, +59, -330, 75, -43, -47, 312, -109, 555, +-12, 444, 178, -8, 281, -465, 184, -546, +-16, -237, -198, 115, -209, 229, -117, 117, +60, -16, 205, -40, 242, 19, 151, 98, +58, 96, 39, -57, 31, -266, -21, -353, +-147, -159, -254, 165, -222, 310, 10, 167, +324, -41, 567, -77, 538, -5, 207, -33, +-351, -204, -771, -298, -747, -168, -199, 76, +535, 246, 919, 265, 687, 159, 63, -22, +-429, -251, -508, -375, -252, -264, 7, 19, +104, 237, 109, 199, 160, -14, 246, -178, +257, -126, 166, 58, -10, 212, -153, 155, +-230, -134, -211, -423, -24, -448, 263, -130, +418, 278, 284, 434, 17, 270, -117, 8, +-68, -145, 31, -219, -44, -302, -136, -332, +-31, -165, 259, 178, 405, 386, 192, 266, +-184, -97, -328, -355, -87, -255, 277, 70, +330, 285, 45, 165, -253, -190, -207, -426, +81, -317, 310, 6, 247, 226, 3, 181, +-114, 29, -24, -4, 139, 72, 140, 62, +-40, -107, -182, -307, -89, -372, 168, -252, +382, -44, 382, 202, 165, 377, -105, 368, +-270, 150, -227, -177, -60, -413, 150, -474, +270, -373, 357, -144, 354, 198, 222, 482, +-87, 443, -381, 50, -390, -372, -91, -423, +272, -138, 453, 77, 367, 0, 132, -190, +-66, -160, -154, 93, -149, 276, -65, 184, +75, -98, 166, -331, 168, -375, 119, -191, +68, 135, 35, 420, -30, 402, -40, -22, +64, -548, 255, -754, 278, -430, 54, 185, +-222, 617, -210, 620, 86, 260, 401, -215, +386, -554, 83, -624, -173, -405, -161, -38, +118, 278, 334, 380, 306, 266, 14, 72, +-201, -96, -177, -173, 21, -223, 249, -278, +336, -284, 267, -174, 109, 54, -40, 238, +-122, 241, -126, 99, -42, -43, 89, -120, +173, -191, 212, -288, 156, -301, 114, -102, +54, 193, 34, 291, 7, 88, -19, -234, +-15, -336, -22, -129, 65, 125, 224, 197, +358, 58, 298, -134, 71, -234, -155, -227, +-191, -190, -33, -125, 150, -5, 267, 144, +293, 254, 222, 207, 133, -11, 71, -248, +4, -369, -76, -321, -141, -204, -106, -102, +125, 39, 451, 254, 605, 411, 373, 285, +-137, -142, -508, -581, -439, -642, 20, -261, +459, 234, 506, 454, 178, 242, -158, -163, +-162, -418, 144, -341, 434, -2, 345, 292, +-86, 278, -394, -5, -302, -331, 85, -452, +368, -329, 372, -74, 275, 191, 244, 367, +214, 330, 47, 21, -179, -382, -263, -586, +-99, -390, 182, 26, 341, 295, 347, 255, +289, 26, 207, -142, 82, -147, -93, -115, +-148, -112, -32, -114, 146, -97, 234, -82, +162, -70, 77, -28, 139, 85, 206, 202, +136, 108, -61, -206, -163, -522, -75, -526, +200, -128, 386, 360, 299, 564, 47, 347, +-144, -114, -108, -508, 55, -639, 191, -498, +225, -129, 169, 305, 92, 552, 32, 453, +32, 62, 116, -358, 191, -520, 215, -419, +133, -213, 62, -58, -13, 5, -32, 66, +44, 188, 221, 333, 434, 371, 396, 113, +74, -447, -339, -964, -382, -969, 8, -298, +571, 654, 737, 1156, 350, 829, -231, -44, +-501, -820, -315, -1013, 96, -651, 411, -81, +440, 372, 261, 531, 78, 388, 48, 59, +93, -273, 22, -413, -191, -306, -301, -106, +-80, 9, 403, -1, 681, -67, 503, -41, +43, 56, -279, 87, -205, 26, 36, -110, +191, -232, 105, -272, 53, -235, 143, -76, +353, 186, 430, 380, 240, 281, -44, -151, +-230, -631, -205, -728, 10, -308, 265, 295, +402, 655, 363, 531, 213, 66, 60, -392, +-61, -628, -111, -553, -102, -247, -8, 94, +152, 298, 314, 293, 358, 140, 197, -31, +-24, -137, -143, -199, -9, -201, 206, -173, +249, -171, 17, -204, -176, -216, -94, -67, +258, 276, 506, 555, 423, 457, 59, -87, +-231, -741, -197, -978, 53, -573, 287, 162, +285, 704, 159, 708, 62, 254, 92, -277, +122, -576, 95, -556, 46, -283, 102, 34, +287, 256, 392, 264, 193, 55, -239, -182, +-483, -261, -241, -119, 340, 95, 754, 127, +660, -90, 185, -339, -248, -384, -378, -144, +-267, 228, -58, 417, 191, 269, 361, -120, +426, -497, 300, -573, 67, -293, -116, 126, +-102, 420, 52, 384, 142, 69, 117, -283, +27, -465, 45, -376, 168, -105, 276, 145, +281, 218, 137, 108, -13, -91, -71, -188, +21, -137, 182, -10, 243, 56, 184, -41, +45, -222, -13, -295, 64, -166, 197, 110, +245, 300, 136, 192, 4, -110, -60, -339, +37, -300, 178, -55, 186, 117, 101, 50, +15, -118, 20, -181, 86, -71, 183, 98, +201, 100, 132, -43, -34, -174, -153, -194, +-106, -100, 121, -15, 354, 6, 405, 26, +222, 40, -12, -11, -131, -134, -98, -272, +7, -256, 75, -22, 129, 234, 228, 290, +358, 74, 343, -246, 173, -383, -87, -268, +-229, -50, -157, 97, 56, 82, 266, 10, +321, 1, 244, 26, 107, -8, 72, -109, +47, -217, 46, -203, 16, -68, 12, 25, +15, 11, 66, -53, 137, -37, 218, 101, +215, 160, 112, -6, -26, -289, -119, -440, +-43, -267, 99, 95, 236, 335, 237, 283, +163, 14, 56, -273, -4, -368, -21, -250, +-46, -29, 6, 167, 120, 198, 284, 55, +382, -103, 310, -172, 90, -131, -171, -78, +-352, -115, -264, -143, 58, -57, 469, 123, +644, 242, 487, 148, 68, -101, -293, -287, +-367, -313, -182, -224, 108, -93, 260, 30, +302, 176, 277, 276, 229, 177, 109, -86, +-41, -338, -167, -371, -162, -172, -45, 45, +93, 107, 247, 58, 317, 15, 256, 18, +63, 10, -77, -79, -96, -155, 47, -133, +137, -71, 111, -48, 15, -62, 12, -30, +121, 92, 222, 147, 177, 16, 82, -201, +67, -289, 86, -143, 69, 66, -68, 127, +-114, 25, 20, -69, 273, -94, 392, -77, +303, -80, 65, -58, -98, 40, -117, 123, +-108, 34, -81, -199, 7, -387, 199, -285, +424, 85, 471, 432, 205, 476, -196, 129, +-465, -389, -376, -708, -20, -582, 383, -85, +572, 468, 450, 666, 94, 371, -220, -155, +-278, -515, -93, -463, 129, -124, 173, 120, +49, 83, -22, -108, 95, -159, 296, 61, +374, 314, 155, 299, -132, -8, -264, -351, +-126, -472, 119, -298, 285, -19, 281, 194, +152, 268, 18, 162, -67, -46, -26, -224, +71, -226, 152, -16, 153, 176, 95, 109, +19, -156, -26, -365, -48, -284, -20, 42, +46, 307, 147, 306, 232, 91, 216, -158, +85, -255, -44, -215, -58, -139, 5, -53, +57, 27, -9, 93, -82, 113, -36, 33, +157, -88, 341, -142, 367, -85, 204, 24, +-18, 89, -192, 26, -273, -126, -236, -249, +-70, -267, 249, -89, 557, 214, 626, 437, +329, 380, -166, -5, -520, -464, -520, -659, +-205, -472, 214, -19, 537, 414, 575, 594, +330, 442, -38, 18, -289, -454, -325, -655, +-97, -453, 149, -1, 260, 363, 180, 378, +54, 142, 8, -80, 37, -139, 78, -101, +77, -104, 27, -175, 4, -180, 27, -50, +46, 123, 2, 203, -54, 117, -2, -43, +179, -125, 362, -106, 321, -78, 41, -94, +-275, -134, -332, -77, -73, 78, 229, 186, +349, 143, 215, -38, 35, -204, -56, -200, +-21, -77, 20, 48, 40, 77, 75, 22, +141, -51, 135, -85, 0, -98, -164, -74, +-131, 7, 128, 104, 422, 146, 426, 27, +79, -174, -320, -265, -467, -146, -256, 60, +134, 138, 430, 5, 462, -135, 275, -81, +1, 114, -221, 209, -278, 79, -161, -176, +80, -316, 231, -262, 251, -108, 176, 74, +72, 205, -2, 255, -1, 186, 24, -8, +3, -222, -81, -323, -149, -290, -79, -148, +185, 32, 457, 214, 492, 327, 149, 260, +-325, -1, -501, -295, -277, -422, 190, -296, +497, -3, 428, 221, 55, 255, -257, 108, +-282, -83, -40, -157, 256, -93, 347, 4, +172, 14, -174, -96, -357, -202, -191, -123, +193, 124, 491, 301, 446, 217, 25, -132, +-360, -414, -384, -346, -20, 27, 347, 360, +389, 320, 79, -46, -242, -359, -259, -343, +-14, -55, 281, 229, 306, 266, 157, 97, +-47, -105, -132, -205, -89, -196, 44, -107, +104, -3, 122, 101, 89, 133, 22, 73, +-14, -27, 7, -107, 68, -100, 83, -27, +43, 14, -30, -18, -56, -74, -63, -106, +44, -54, 144, 32, 183, 105, 161, 137, +77, 116, -88, -9, -200, -197, -132, -345, +62, -283, 261, 3, 238, 265, 57, 294, +-154, 103, -156, -86, 37, -99, 195, -14, +96, -41, -55, -177, -95, -260, 37, -148, +204, 85, 221, 231, 43, 215, -130, 130, +-112, 40, 29, -61, 159, -211, 91, -358, +-17, -328, -98, -74, -47, 236, 111, 389, +202, 280, 140, 36, -4, -144, -105, -198, +-122, -196, -2, -199, 100, -180, 133, -66, +89, 135, 57, 270, 53, 287, 59, 162, +-28, -34, -120, -219, -186, -353, -84, -381, +146, -217, 298, 88, 264, 380, 100, 467, +-76, 254, -182, -111, -153, -370, -99, -379, +7, -194, 161, 10, 299, 99, 312, 137, +103, 149, -162, 124, -299, 9, -240, -139, +-52, -177, 181, -67, 266, 47, 200, 19, +76, -108, -49, -158, -88, -4, -4, 216, +71, 256, 44, 53, -107, -219, -151, -317, +4, -146, 237, 104, 333, 220, 173, 115, +-163, -98, -372, -199, -250, -94, 40, 78, +273, 155, 321, 67, 170, -87, -47, -154, +-209, -124, -181, -41, -2, 62, 195, 146, +269, 157, 132, 48, -144, -167, -304, -303, +-190, -223, 71, 29, 279, 270, 321, 302, +178, 118, -35, -101, -231, -247, -318, -257, +-228, -149, 62, 9, 387, 163, 472, 230, +214, 131, -166, -51, -376, -164, -270, -142, +23, -9, 235, 58, 178, 24, -25, -51, +-163, -90, -116, -71, 105, 2, 322, 88, +320, 167, 22, 157, -351, -8, -488, -222, +-263, -291, 189, -131, 544, 127, 519, 219, +146, 69, -252, -103, -425, -113, -349, 56, +-103, 189, 156, 111, 293, -100, 246, -239, +108, -216, -26, -71, -95, 59, -49, 122, +11, 164, -35, 176, -137, 106, -115, -54, +49, -225, 222, -270, 288, -124, 168, 68, +-57, 163, -290, 111, -359, -7, -234, -37, +45, 26, 371, 82, 510, 66, 282, -32, +-165, -144, -478, -192, -425, -154, -53, -31, +331, 163, 413, 290, 170, 260, -160, 41, +-307, -233, -181, -347, 64, -218, 221, 58, +161, 263, -56, 249, -187, 40, -128, -167, +73, -223, 221, -78, 199, 131, -26, 231, +-217, 111, -248, -134, -86, -295, 142, -164, +277, 156, 255, 363, 43, 249, -233, -113, +-389, -386, -298, -337, -7, -26, 335, 280, +449, 387, 254, 232, -60, -46, -294, -305, +-340, -367, -203, -165, 31, 141, 222, 300, +277, 211, 155, -21, -30, -153, -201, -79, +-194, 44, -44, 79, 88, 3, 41, -86, +-55, -110, -88, -58, 8, 34, 170, 162, +236, 230, 114, 126, -157, -111, -350, -313, +-305, -263, -33, 31, 272, 308, 399, 332, +194, 80, -150, -218, -331, -310, -241, -153, +-16, 96, 149, 249, 146, 214, 31, 69, +-29, -73, -26, -171, 22, -173, -12, -61, +-22, 94, -11, 175, -12, 121, -48, -32, +-50, -104, -48, -46, 2, 70, 80, 112, +80, 18, 29, -94, -31, -96, -71, -21, +-125, 63, -141, 84, -48, 35, 164, 4, +289, -6, 196, -2, -101, 7, -363, 34, +-332, 50, -46, 54, 200, -26, 225, -137, +128, -168, -11, -60, -59, 172, -107, 333, +-155, 244, -183, -14, -43, -225, 171, -257, +253, -128, 115, -6, -87, 76, -173, 156, +-127, 222, -16, 197, 21, 41, -56, -172, +-96, -251, 19, -145, 144, 23, 151, 149, +32, 160, -129, 103, -208, 49, -117, 18, +19, -39, 60, -130, 29, -175, 39, -62, +83, 149, 80, 273, -2, 224, -171, 16, +-275, -175, -179, -189, 50, -84, 214, -7, +213, 12, 76, 61, -96, 197, -192, 302, +-174, 172, -66, -135, 23, -366, 80, -328, +110, -19, 78, 283, -10, 320, -119, 146, +-177, -65, -92, -145, 55, -37, 119, 89, +53, 108, -82, -5, -184, -137, -132, -155, +56, -44, 209, 113, 206, 258, 27, 267, +-231, 89, -354, -136, -237, -246, 36, -190, +269, -31, 311, 141, 156, 238, -111, 214, +-318, 34, -338, -136, -192, -190, 29, -90, +228, 92, 305, 213, 176, 198, -44, 62, +-262, -108, -369, -199, -256, -138, 33, 2, +301, 150, 333, 230, 113, 202, -190, 71, +-364, -96, -296, -216, -22, -186, 220, -26, +242, 162, 96, 256, -137, 161, -256, -32, +-153, -139, 49, -83, 135, 54, 93, 129, +-29, 65, -153, -34, -184, -92, -95, -62, +74, 76, 163, 201, 114, 184, -49, 33, +-240, -139, -267, -202, -66, -89, 162, 111, +169, 239, -2, 179, -130, 0, -117, -94, +-9, -29, 57, 50, -18, 10, -155, -99, +-175, -92, -19, 102, 139, 293, 141, 261, +-24, -2, -173, -231, -211, -243, -106, -101, +67, 85, 165, 213, 91, 285, -51, 223, +-192, -2, -242, -254, -133, -294, 90, -81, +241, 196, 180, 287, -48, 152, -264, -44, +-318, -103, -200, -17, 48, 74, 246, 111, +229, 36, 35, -79, -196, -127, -345, -41, +-237, 132, 54, 252, 239, 170, 170, -30, +-55, -145, -240, -123, -236, 21, -81, 134, +91, 99, 168, 2, 55, -22, -154, 33, +-279, 93, -201, 34, 24, -37, 191, 0, +158, 98, 16, 157, -164, 73, -260, -124, +-187, -210, -43, -72, 95, 176, 171, 303, +66, 200, -174, -7, -288, -173, -121, -134, +87, 31, 132, 107, 18, 64, -142, 13, +-205, 29, -129, 89, 10, 94, 65, 25, +33, -33, -43, -36, -118, 35, -115, 93, +-59, 27, 16, -27, -4, 28, -99, 84, +-155, 66, -105, 1, -8, -16, 61, 51, +74, 96, -34, 61, -193, -35, -200, -68, +-96, 38, -2, 140, 47, 111, 56, -27, +44, -75, -33, 3, -154, 83, -276, 123, +-275, 93, -103, -27, 175, -75, 314, -30, +201, 83, -60, 191, -343, 137, -520, -56, +-419, -194, -18, -122, 369, 99, 454, 269, +201, 262, -169, 154, -429, -51, -401, -262, +-235, -289, -79, -99, 39, 165, 130, 335, +184, 325, 119, 208, -20, 36, -181, -153, +-312, -282, -378, -299, -284, -104, -58, 214, +250, 437, 440, 403, 288, 130, -180, -164, +-559, -267, -587, -181, -269, 7, 166, 135, +403, 155, 282, 109, -61, 56, -348, 36, +-396, 56, -174, 106, 99, 83, 146, -31, +-49, -162, -224, -197, -222, -42, -66, 263, +105, 474, 138, 356, -6, -75, -225, -458, +-356, -437, -317, -38, -108, 380, 184, 475, +293, 289, 105, 10, -200, -231, -380, -310, +-365, -158, -185, 119, 89, 297, 232, 294, +112, 119, -146, -100, -299, -190, -287, -59, +-138, 164, 94, 256, 131, 134, -37, -90, +-171, -251, -236, -190, -241, 98, -89, 341, +90, 380, 58, 205, -52, -39, -84, -244, +-115, -285, -189, -141, -198, 76, -152, 243, +-121, 315, -52, 271, 59, 94, 41, -157, +-58, -264, -102, -99, -136, 132, -192, 280, +-235, 183, -182, -87, -84, -237, -7, -80, +90, 206, 91, 316, -109, 189, -286, -10, +-213, -128, -65, -108, -46, 40, -96, 140, +-209, 89, -217, -36, -31, -114, 130, -76, +38, 129, -151, 337, -195, 385, -144, 206, +-80, -108, -100, -371, -176, -469, -199, -243, +-136, 185, -7, 491, 37, 555, 7, 400, +-21, 89, -113, -241, -269, -464, -348, -407, +-242, -120, -14, 154, 183, 377, 136, 464, +-126, 340, -348, 89, -325, -140, -162, -258, +-28, -241, 77, -113, 75, 54, -34, 205, +-156, 293, -311, 288, -416, 144, -313, -67, +-9, -215, 233, -182, 193, -36, -10, 163, +-161, 289, -284, 235, -336, 59, -247, -68, +-178, -116, -109, -121, -10, -11, 55, 99, +47, 180, -9, 190, -84, 163, -189, 133, +-289, 23, -307, -140, -248, -189, -186, -165, +-67, -58, 99, 147, 263, 396, 180, 551, +-209, 293, -521, -224, -543, -539, -315, -422, +48, 9, 249, 418, 109, 467, -93, 222, +-162, -76, -240, -186, -251, -32, -185, 156, +-111, 139, -117, -16, -115, -125, -58, -116, +-66, 54, -58, 245, -39, 325, -90, 220, +-264, -53, -312, -251, -182, -202, -121, 4, +-44, 198, 50, 277, 3, 177, -111, 33, +-165, -33, -231, -63, -290, -55, -187, -13, +-57, 10, 28, 156, -39, 318, -172, 212, +-188, -58, -127, -260, -40, -158, -91, 105, +-254, 202, -286, 117, -104, 81, 43, 186, +-22, 229, -181, -58, -254, -429, -184, -333, +-26, 241, 54, 668, -70, 408, -247, -155, +-352, -384, -345, -171, -95, 90, 225, 181, +233, 178, -101, 193, -444, 124, -509, -76, +-206, -181, 145, -71, 179, 161, -88, 230, +-340, 49, -311, -81, -147, 58, 18, 203, +95, 130, -31, -89, -232, -179, -328, -16, +-257, 233, -171, 287, -118, 24, -64, -195, +26, -136, 35, 115, -57, 370, -118, 327, +-244, -34, -347, -316, -332, -260, -231, 84, +-103, 262, 102, 118, 237, 99, 97, 194, +-170, 106, -381, -66, -457, -54, -362, 67, +-107, 20, 103, -199, 70, -157, -16, 235, +-111, 483, -195, 332, -156, -55, -95, -315, +-172, -207, -316, 106, -242, 218, -119, 86, +51, -59, 193, 5, 76, 179, -296, 249, +-556, 67, -408, -223, -72, -171, 189, 160, +177, 353, -45, 141, -222, -209, -235, -203, +-206, 150, -281, 317, -372, 113, -234, -213, +112, -184, 344, 196, 262, 369, -108, 208, +-511, -31, -625, -167, -399, -205, -66, -150, +119, 18, 110, 295, 73, 420, 62, 280, +-64, 49, -300, -130, -411, -272, -352, -307, +-148, -98, -34, 279, -48, 455, -38, 208, +61, -81, 92, -31, -53, 197, -236, 92, +-406, -298, -370, -323, -261, 133, -182, 412, +106, 123, 422, -137, 261, 126, -315, 397, +-647, 95, -438, -401, -54, -338, 65, 227, +-48, 413, -111, -29, -70, -311, 72, 52, +19, 569, -297, 419, -418, -288, -178, -602, +38, -70, -103, 472, -226, 273, -77, -202, +27, -152, -10, 286, 40, 378, -27, 26, +-390, -229, -522, -187, -263, -45, 14, 145, +98, 261, 206, 212, 142, -17, -209, -186, +-377, -40, -290, 216, -280, 140, -164, -141, +76, -76, 35, 278, -144, 272, -52, -166, +87, -285, -58, 116, -284, 343, -355, 32, +-323, -240, -159, 3, 108, 356, 188, 205, +19, -135, -206, -158, -222, -7, -128, 128, +-145, 111, -265, 36, -266, 66, -117, 3, +167, -92, 254, 92, -119, 297, -321, 182, +-225, -114, -168, -200, -185, 2, -160, 22, +-107, -156, 87, 30, 179, 491, -109, 493, +-275, -9, -176, -378, -172, -285, -184, 22, +-150, 75, -72, -69, 73, 116, 63, 505, +-183, 371, -181, -109, -66, -346, -242, -226, +-194, 10, -10, 70, -85, 98, -112, 333, +-17, 280, -15, -96, -106, -228, -177, -131, +-199, 102, -109, 222, -47, 60, -90, 2, +-194, 78, -147, 27, 120, -9, 170, -54, +-185, -48, -458, 90, -292, 194, 28, 188, +86, 22, -45, -160, -87, -120, -11, 140, +4, 285, -190, 21, -359, -314, -265, -181, +-89, 179, 99, 399, 185, 341, 15, 59, +-164, -144, -292, -272, -324, -363, -120, -78, +94, 349, 62, 438, -124, 257, -307, -24, +-220, -178, 130, -140, 238, -32, 91, 115, +-221, 108, -664, -74, -615, -112, 52, 49, +506, 269, 351, 287, 60, 85, -264, -86, +-530, -161, -472, -154, -151, -99, 149, 44, +267, 313, 107, 337, -257, 14, -423, -186, +-103, -132, 248, 41, 136, 135, -240, 54, +-400, 68, -266, 85, -64, -106, 69, -143, +64, 62, 64, 240, 25, 222, -207, -13, +-391, -178, -165, -41, 70, 59, 30, 71, +-123, 107, -194, 58, -30, -52, 63, -31, +-229, 76, -260, 57, 69, -54, 181, 32, +23, 262, -296, 187, -439, -175, -83, -298, +152, -50, -52, 100, -116, 187, -11, 298, +-53, 182, -36, -94, -70, -252, -298, -243, +-140, -2, 177, 332, -21, 375, -290, 57, +-166, -260, -162, -224, -105, 13, 184, 116, +284, 191, -9, 283, -388, 80, -472, -222, +-234, -292, -37, -80, 138, 267, 222, 354, +68, 78, -118, -82, -252, -82, -448, -134, +-293, -103, 245, 134, 291, 340, -72, 210, +-173, -144, -172, -213, -406, -11, -214, -17, +250, -48, 271, 272, -9, 416, -267, -27, +-392, -447, -295, -209, 69, 255, 349, 342, +93, 95, -313, -138, -241, -121, -161, 5, +-277, -10, -17, -27, 334, 185, 88, 356, +-188, 140, -182, -293, -127, -328, -246, -85, +-189, 115, 57, 322, 50, 311, -39, -5, +32, -231, -121, -188, -272, 44, 9, 176, +78, 72, -197, 104, -149, 116, -36, -70, +-192, -205, -169, -204, 60, 15, 172, 350, +37, 407, -180, 101, -240, -222, -108, -232, +-67, -58, -122, -99, -80, 5, -65, 249, +30, 212, 66, 62, -154, -108, -150, -97, +10, 177, -113, 136, -69, -24, -28, -64, +-187, -184, -81, -80, -78, -30, -255, -45, +62, 389, 278, 524, -74, 96, -127, -196, +-83, -379, -279, -304, -194, -13, -132, 117, +-132, 237, 137, 261, 167, 40, -57, -32, +82, 30, -106, 84, -531, 61, -236, -113, +114, -251, 22, -179, 108, 26, -62, 213, +-237, 341, -77, 248, 12, -111, -93, -153, +-93, 122, -18, 29, 35, -200, -80, -189, +-294, -82, -222, 143, -146, 132, 77, 93, +440, 487, 145, 391, -422, -371, -331, -722, +-247, -324, -239, 321, 180, 484, 427, 105, +-33, 7, -309, 89, -232, -153, -161, -215, +-75, 35, -98, 199, 122, 104, 326, 61, +-54, -36, -535, -189, -341, -119, -6, 146, +124, 166, 180, 112, -62, 56, -315, -79, +-57, -98, 57, -8, -102, 197, -44, 145, +83, -232, -134, -179, -465, 137, -285, -3, +258, -14, 402, 246, -47, 256, -194, 56, +-208, -165, -294, -237, -90, -137, 123, -13, +-28, 144, -166, 138, -21, 61, 82, 206, +-160, 210, -146, -148, 151, -288, -125, -113, +-470, -33, 77, 17, 398, 293, -297, 367, +-291, -74, 201, -341, -182, -133, -367, 169, +213, 188, 145, -63, -111, -134, 56, 140, +-194, 229, -362, -4, -68, -299, -9, -225, +-52, 274, 78, 368, 95, -44, -8, -130, +-239, 17, -261, -31, 22, -165, 52, 50, +-171, 304, -56, 72, -7, -174, -192, -41, +130, -18, 260, -17, -347, 163, -419, 153, +1, -33, -31, -158, 94, -46, 298, 108, +-98, 82, -362, -21, -145, -38, -172, 79, +-191, 168, 65, -72, 132, -277, 76, 88, +92, 317, 6, 51, -361, -157, -345, -45, +-31, 21, 32, -66, -97, -51, -125, 176, +45, 250, 287, -19, 215, -164, -178, -78, +-484, -90, -377, -21, -16, 308, 114, 302, +-38, -188, 95, -324, 181, -12, -149, 119, +-33, 3, -14, 86, -414, 246, -229, 133, +203, -176, -69, -318, -253, -71, 183, 181, +277, 155, -138, 136, -150, 77, -45, -253, +-423, -231, -270, 171, 428, 308, 149, 208, +-384, -5, -46, -383, 109, -400, -124, 28, +-20, 321, 171, 459, -192, 374, -529, -211, +-106, -658, 255, -353, 96, 315, 131, 515, +167, 84, -305, -203, -560, 54, -210, 53, +206, -284, 192, -116, 72, 291, 92, 225, +-105, -44, -408, -151, -133, -63, 115, 164, +-155, 50, -12, -276, 341, 61, -195, 318, +-454, -54, 234, -178, 158, 124, -333, 33, +47, -73, 61, 66, -411, 244, -43, -21, +216, -375, -19, -98, -11, 251, -70, -20, +-139, 15, 52, 377, -130, 207, -217, -325, +15, -362, -53, 107, -67, 274, 259, -239, +96, -289, -286, 325, -224, 502, 47, -46, +15, -165, -216, 123, -147, -113, 164, -474, +196, -99, -19, 373, -224, 229, -123, -34, +-39, 69, -168, 269, 45, -83, 324, -426, +-143, -199, -464, 135, 61, 258, 281, 170, +-155, -144, -109, -84, 167, 241, -131, 6, +-285, -262, 65, 69, -47, 267, -160, -159, +285, -324, 230, 112, -325, 335, -339, 81, +39, -58, 108, -76, -74, -85, -17, -116, +84, -39, 13, 177, -77, 304, -296, 66, +-201, -166, 292, -223, 215, -125, -141, 66, +-116, 125, -157, 102, -175, 169, 53, 157, +27, -177, 46, -364, 221, -71, 63, 399, +-230, 178, -383, -367, -348, -213, 120, 340, +475, 327, 235, -103, -132, -212, -58, 14, +-297, 85, -482, -109, 146, -127, 386, -61, +-148, 50, -48, 259, 242, 330, -165, 155, +-271, -118, 191, -451, 42, -465, -358, -108, +-92, 327, 222, 447, -69, 346, -73, 192, +377, -120, 113, -517, -440, -324, -316, -90, +33, -143, -15, 216, -74, 716, 257, 457, +412, -258, -118, -525, -444, -270, -23, 102, +93, 135, -391, -46, -58, -118, 470, 236, +-15, 219, -219, -111, 224, 53, 18, 195, +-240, -119, 23, -338, -65, -298, -219, -9, +-46, 344, -3, 360, 191, 207, 402, -150, +17, -269, -377, -58, -297, -192, -28, -206, +-17, 447, 22, 557, 248, -242, 238, -674, +-116, -85, -286, 617, -188, 175, -38, -386, +173, -31, 238, 459, -90, -42, -242, -722, +75, -417, 101, 776, -148, 748, -22, -264, +137, -670, -221, 71, -121, 388, 172, -253, +90, -499, 65, 433, 151, 646, -282, -182, +-327, -569, 124, -184, 118, 383, -108, 261, +196, -209, 176, -205, -234, 204, -196, 177, +16, -111, 105, -306, 170, 98, -89, 249, +-376, -101, 184, -292, 342, 107, -218, 466, +-300, 195, 150, -658, 158, -437, -122, 596, +-136, 447, 399, -672, 239, -451, -537, 865, +-424, 666, 349, -895, 174, -739, -356, 781, +136, 530, 651, -772, -30, -511, -579, 891, +-128, 631, -47, -839, -11, -697, 314, 683, +107, 504, -50, -427, 104, -270, -227, 270, +-305, 132, 119, -343, 259, -274, 199, 288, +82, 550, -365, 56, -481, -500, 195, -443, +461, 258, -44, 417, -88, -222, 211, -363, +-89, 325, -276, 470, -46, -266, 123, -580, +112, 141, -39, 527, -51, -177, 127, -574, +148, 58, -216, 643, -251, 156, 326, -517, +370, -314, -429, 372, -381, 292, 336, -358, +243, -506, -203, 269, -22, 644, 235, -77, +84, -414, -203, 138, -202, 176, -12, -404, +166, -494, 238, 156, -74, 767, -157, 249, +130, -399, 56, -105, -300, 146, -67, -436, +323, -532, 342, 292, -108, 674, -383, 73, +-78, -146, 296, 163, -30, -309, -95, -681, +108, 207, 12, 679, -13, -256, 144, -569, +-17, 535, 36, 741, 106, -596, -256, -906, +-379, 249, 171, 698, 421, 5, 99, -438, +-76, -77, 37, 355, -40, -21, -160, -425, +7, 32, 186, 507, 58, 20, -286, -626, +-178, -358, 491, 593, 353, 631, -444, -355, +-169, -659, 543, 67, 83, 375, -602, -102, +-74, -244, 408, 195, -81, 236, -61, -279, +560, -313, 63, 319, -631, 342, -77, -455, +500, -482, -16, 629, -380, 456, 171, -915, +636, -555, -58, 997, -757, 608, -89, -718, +648, -652, 179, 415, -297, 631, -45, -291, +116, -915, 163, -69, 162, 884, -273, 614, +-272, -500, 403, -947, 130, -12, -346, 964, +103, 202, 361, -931, -2, -377, 112, 742, +-40, 374, -303, -635, -47, -413, 187, 517, +-70, 469, 128, -296, 432, -401, 102, 41, +-424, -26, -17, -247, 350, 115, -89, 353, +-345, 27, 122, -259, 349, -57, 145, 270, +-120, 13, -95, -608, 196, -308, 177, 446, +-58, 428, -276, -94, -168, -307, 365, -11, +474, 294, -336, -138, -250, -465, 570, 23, +120, 242, -620, -2, 96, -95, 530, 123, +-150, 93, -191, -69, 466, -227, 134, -83, +-552, 46, -125, -77, 439, -300, 296, 313, +26, 757, 8, -320, -103, -1015, -73, 189, +37, 713, 52, -329, 17, -586, 123, 395, +253, 690, 131, -394, -173, -784, -235, 84, +150, 524, 452, 19, 89, -98, -298, 41, +-43, -102, 170, -364, -28, -235, -107, 108, +289, 341, 499, 222, 135, 89, -399, -78, +-315, -367, 174, -451, 244, -125, -158, 230, +207, 319, 645, 187, -153, -171, -713, -132, +254, 71, 712, -61, -42, -259, -480, -143, +67, 12, 513, 202, 28, 95, -458, -151, +-17, -143, 728, 56, 479, 146, -405, 123, +-609, -194, 137, -417, 477, -71, 129, 202, +-118, 71, 149, 37, 286, 185, 145, -191, +-166, -404, -286, 53, -47, 367, 467, -159, +278, -349, -202, 171, -47, 323, 453, -394, +294, -318, -412, 452, -386, 271, 421, -681, +494, -330, -188, 729, -254, 409, 156, -797, +445, -613, 288, 648, -35, 730, -238, -558, +-86, -869, 97, 263, 68, 660, -17, -151, +352, -389, 415, 11, 2, 190, 6, 115, +14, -144, -247, -436, -130, -131, 331, 342, +244, 212, 97, -305, 112, -247, 222, 270, +194, 256, 113, -210, -266, -285, -427, -61, +113, -145, 539, -33, 442, 330, 41, 255, +-176, -420, 177, -435, 370, 231, -364, 552, +-478, -174, 476, -722, 799, -204, -113, 649, +-379, 415, 155, -492, 549, -592, 58, 200, +-336, 396, -66, -231, 412, -306, 252, 204, +-134, 369, 172, -80, 370, -473, 80, -281, +-248, 171, -136, 34, 155, -16, 357, 193, +99, 44, 174, -373, 361, -151, 259, 403, +-351, 331, -541, -519, 34, -724, 953, 130, +401, 623, -524, -19, -70, -439, 623, -16, +236, 484, -365, 190, -49, -417, 484, -564, +329, -228, -318, 310, -195, 411, 240, -105, +274, -401, 273, 139, 451, 304, 119, -176, +-251, -292, -111, 9, 21, -69, -14, -77, +346, 86, 327, 18, 23, -360, 275, -70, +434, 597, -121, 374, -496, -528, 16, -738, +575, -158, 280, 424, -82, 512, 172, -61, +185, -581, -42, -166, 132, 387, 227, -11, +131, -498, -18, 46, 137, 556, 220, 4, +-87, -579, 72, -176, 562, 378, 142, -33, +-317, -381, 28, 28, 207, 75, 293, -83, +375, 308, 142, 164, -139, -425, 80, -357, +10, 139, -141, 142, 211, -155, 614, -291, +158, -15, 142, 276, 279, 322, -126, 11, +-344, -394, 28, -243, 296, 7, 422, -88, +206, -224, -2, -34, 291, 347, 433, 372, +42, -132, -452, -370, -294, -227, 405, 23, +630, 91, 113, -163, -23, -195, 311, 179, +390, 272, -200, -79, -356, -321, 288, -134, +546, 251, -26, 40, -139, -307, 335, -114, +471, 187, 21, 52, -215, -273, 145, -258, +337, 306, 96, 377, -51, -283, 230, -459, +298, 128, 127, 154, 157, -308, 176, -20, +-221, 497, -116, -137, 539, -669, 325, 26, +-132, 524, 228, -129, 585, -473, 20, 226, +-398, 535, -11, -358, 350, -794, 118, 59, +167, 557, 327, 2, 234, -238, 200, 137, +209, 59, -51, -253, -137, -200, -141, -153, +32, -131, 581, 354, 634, 411, 0, -214, +3, -508, 270, -44, -65, 286, -365, -31, +173, -480, 393, -150, 234, 457, 473, 286, +458, -212, -326, -167, -482, -54, 376, -232, +748, -181, -141, 108, -606, 132, 451, -148, +1066, -11, 138, 357, -573, 239, 1, -416, +475, -681, 156, -292, -207, 322, 86, 490, +448, 141, 467, -212, 154, -47, -199, 45, +-57, -350, 376, -515, 111, 148, -76, 463, +257, -46, 459, -208, 21, 198, -230, 140, +374, -349, 545, -239, -185, 133, -283, -176, +472, -366, 435, 335, -174, 552, -128, -266, +458, -428, 437, 284, -30, 144, -38, -582, +263, -349, 53, 302, -19, 185, 242, -25, +332, 163, 37, 34, -79, -321, 459, -291, +379, 131, -183, 177, 9, -264, 505, -293, +-38, 271, -454, 384, 191, -282, 741, -495, +337, 218, 81, 480, 277, -231, -64, -455, +-581, -65, 126, 117, 825, -67, 225, -132, +-292, 84, 413, 421, 674, 106, -328, -329, +-507, -499, 362, -365, 616, 195, 167, 549, +38, 64, 78, -359, 135, -44, 32, 129, +54, -150, 296, -281, 264, 7, 43, 117, +184, 169, 259, 97, -39, -331, -153, -508, +275, 229, 594, 560, 168, -211, -236, -571, +-41, 166, 240, 471, 261, -216, 275, -414, +182, -17, 69, 136, 78, -85, 145, -89, +65, 70, -102, 206, 185, 33, 512, -162, +404, -273, 11, -193, -149, 20, -93, 67, +190, -66, 352, 191, 212, 420, -67, -172, +157, -814, 579, -261, 274, 675, -368, 355, +-137, -508, 361, -347, 244, 399, -79, 108, +139, -583, 532, -189, 237, 713, 82, 312, +257, -556, -104, -396, -520, 172, 272, -77, +675, -328, 61, 160, -104, 573, 581, 102, +638, -469, -247, -322, -612, 48, 74, 71, +567, -151, 213, -70, -24, 258, 299, 331, +504, -357, 61, -679, -168, 88, -49, 715, +183, 91, 213, -511, 163, -212, 229, 199, +265, -19, -133, -320, 75, -57, 587, 363, +101, 206, -293, -244, 240, -267, 294, 32, +-134, 180, 18, -43, 521, -275, 451, -291, +-39, 6, -13, 413, 110, 282, -93, -308, +-29, -336, 351, 202, 516, 179, 364, -318, +-106, -369, -241, 55, 99, 193, 337, -46, +216, 83, 50, 332, 148, -112, 317, -472, +158, 39, -99, 174, -7, -476, 240, -371, +344, 605, 126, 663, 26, -272, 124, -688, +126, -93, 172, 439, 184, 150, 149, -505, +123, -487, 89, 350, 136, 750, 266, 5, +-6, -786, -113, -388, 229, 423, 434, 294, +277, -285, 189, -99, 84, 336, -239, 24, +-164, -474, 383, -254, 345, 141, -55, 133, +392, 94, 685, 198, -221, -48, -609, -436, +280, -249, 765, 265, 96, 292, -417, -179, +106, -345, 587, 32, 196, 318, -180, 25, +234, -414, 512, -180, 76, 430, -226, 265, +-4, -413, 75, -362, 126, 152, 513, 233, +458, -87, -139, -275, -43, -59, 358, 305, +139, 139, -120, -221, -69, -162, 190, 9, +412, -63, 302, -77, -14, -12, 152, 19, +375, 35, 7, 109, -236, 53, 141, -156, +207, -185, 16, 8, 374, 33, 622, -124, +49, -42, -435, 138, -61, 89, 594, -87, +328, -119, -262, -95, 97, -60, 511, 91, +138, 162, -114, -59, 49, -215, 100, -75, +247, -20, 467, -92, 183, 72, -251, 289, +82, 55, 417, -286, 24, -263, -152, 81, +171, 161, 268, -85, 358, -179, 388, 70, +-21, 121, -276, -91, 148, -54, 430, 152, +-15, 54, -104, -314, 385, -241, 320, 148, +-88, 179, 139, -178, 419, -92, 148, 270, +-97, 250, 89, -306, 186, -515, -28, -18, +-5, 475, 367, 97, 424, -419, 158, -85, +-10, 395, 55, 66, 202, -419, 160, -144, +-97, 266, -64, 144, 309, -311, 406, -232, +204, 207, 123, 260, 90, -145, 91, -91, +82, 45, 7, -113, 36, -154, 238, 48, +234, 10, 205, -16, 230, 169, 176, 125, +-37, -183, -80, -313, 230, -63, 419, 140, +6, 85, -179, -24, 251, 53, 437, 57, +128, -47, -5, -222, 4, -184, 89, -5, +404, 228, 277, 96, -203, -154, -42, -55, +516, 273, 222, 5, -301, -535, 55, -236, +546, 426, 296, 260, -8, -306, -29, -207, +-30, 187, 249, 268, 469, 71, -75, -222, +-234, -511, 290, -248, 415, 360, 134, 506, +92, -121, 135, -401, 93, 164, 90, 429, +28, -268, 71, -677, 171, -64, 247, 474, +257, 239, 212, -196, -6, -163, -44, 54, +106, 156, 251, 70, 226, -234, 82, -385, +35, 119, 167, 341, 142, -221, 76, -265, +187, 428, 140, 385, 149, -317, 289, -471, +55, -75, -246, 133, 66, 21, 521, 18, +330, 217, -208, 82, 6, -315, 593, -122, +182, 297, -507, -65, -1, -528, 596, 35, +167, 613, -70, 105, 355, -506, 316, -189, +22, 281, -143, 97, -222, -225, 208, -108, +583, 91, 173, 90, -20, -2, 274, -49, +71, -42, -120, -5, 117, -112, 153, -112, +104, 177, 270, 272, 242, -178, -45, -540, +-27, -39, 361, 645, 359, 252, -120, -557, +-269, -284, 200, 341, 416, 6, 83, -375, +57, 108, 249, 419, 178, -57, 18, -319, +28, 48, 20, 152, 89, -166, 203, -295, +201, 39, 162, 361, 128, 253, 77, -225, +52, -410, 110, -40, 175, 308, 48, 62, +32, -337, 274, -85, 162, 400, -181, 149, +117, -399, 582, -196, 118, 317, -361, 119, +77, -394, 457, -195, 82, 310, -168, 208, +160, -161, 397, -52, 140, 128, -166, -108, +-4, -334, 307, -7, 262, 322, 81, 11, +75, -245, -125, 111, -144, 209, 394, -216, +475, -182, -122, 228, 0, 117, 322, -268, +15, -298, -165, 61, 39, 291, 242, 238, +357, -44, 61, -269, -221, -198, 231, 95, +482, 117, 4, -63, -226, -29, -30, 25, +59, -119, 187, -65, 369, 148, 242, 132, +70, -67, 7, -110, -80, 31, -19, -1, +72, -168, 48, -162, 176, 130, 336, 142, +262, -36, 36, -42, -169, 136, -26, 44, +287, -100, 119, -144, -214, -155, -4, -153, +366, 71, 342, 239, 59, 151, -47, -55, +99, -36, 174, 91, -177, -84, -280, -387, +214, -246, 505, 231, 231, 317, 57, 49, +26, -93, -90, 38, -15, 20, 27, -127, +18, -245, 95, -89, 293, 151, 252, 205, +117, -80, -78, -156, -36, 108, -25, 187, +12, -157, 139, -357, 203, 104, 68, 427, +121, -95, 134, -544, 34, 30, 47, 490, +-45, 3, -163, -372, 107, 44, 297, 310, +210, -58, 138, -368, -37, -117, 3, 193, +26, 228, -184, 0, -84, -217, 392, -112, +257, 84, 30, 98, 169, -2, 98, -21, +-248, -105, -179, -97, 106, 27, 163, 40, +178, -15, 206, 13, 87, 82, 76, 46, +10, -77, -183, -213, -180, -206, 115, 117, +437, 379, 253, 144, -326, -270, -218, -298, +453, -19, 311, 95, -293, 49, -217, -24, +265, 85, 207, 223, -157, 82, -77, -397, +231, -517, 221, 39, 12, 509, -165, 292, +52, -88, 203, -226, -80, -123, -164, -55, +195, -55, 215, -5, -33, 119, 25, 77, +159, -24, -49, -22, -251, -22, 25, -64, +233, -85, 168, 7, 69, 146, -62, 20, +-54, -217, 129, -159, -132, 110, -149, 323, +289, 199, 327, -256, -253, -490, -203, -125, +290, 294, 243, 215, -189, -25, -192, 40, +72, 129, 81, -155, 78, -424, 128, -110, +30, 362, -169, 257, 38, -290, 262, -172, +-26, 323, -331, 120, -22, -357, 218, -126, +126, 329, -31, 89, 21, -351, 73, -186, +110, 184, -112, 90, -326, -43, -110, 144, +330, 229, 320, -2, -69, -305, -173, -447, +-27, -120, 98, 192, 35, 257, -86, 220, +-85, 206, 79, -19, 40, -296, -91, -378, +12, -168, 197, 127, 176, 264, -56, 161, +-226, -61, -187, -185, -129, -10, 23, 178, +361, 159, 296, -171, -30, -349, -216, -58, +-269, 151, -105, 9, 140, 36, 36, 179, +-78, 94, 151, -87, 245, -192, 27, -100, +-287, 82, -266, -14, 72, -146, 226, 17, +-112, 99, -157, 38, 201, 133, 208, 127, +-234, -259, -171, -362, 208, 126, 190, 410, +-319, -50, -368, -485, 103, -183, 250, 439, +138, 378, 150, -175, -123, -289, -330, 15, +-77, 41, -6, -115, 15, -49, 127, 108, +57, 107, -69, -47, -63, -110, -44, -58, +37, 33, -47, 187, -91, 100, 69, -186, +55, -156, -218, -35, -211, -115, 134, -53, +259, 274, 62, 301, -103, 25, -237, -286, +-272, -314, 94, -37, 189, 282, -26, 215, +-87, -208, -51, -308, -59, 74, 65, 260, +95, 74, -91, -72, -253, -25, -136, 9, +140, -119, 107, -197, -56, 16, -86, 142, +-21, -32, -9, -18, -20, 248, -103, 202, +-23, -214, 27, -383, -125, -120, -160, 83, +105, 105, 145, 172, -93, 203, -96, -30, +-71, -298, -149, -218, 46, 94, 92, 213, +-162, 118, -85, -52, 52, -259, -45, -165, +-29, 179, -66, 218, -104, -52, 91, -42, +52, 118, -158, -29, -157, -353, -143, -216, +-50, 302, 187, 369, 206, -83, -106, -229, +-297, 48, -169, 136, 60, -232, 16, -291, +-153, 254, -105, 408, 183, -164, 236, -353, +-172, 97, -318, 276, -98, -84, -71, -293, +-111, 30, 100, 314, 157, 14, 43, -314, +-114, -110, -169, 210, -167, 139, -95, -76, +-28, 5, 51, 33, 39, -139, -77, -182, +-107, -3, 91, 201, 73, 234, -248, -40, +-258, -221, -33, -126, 24, -36, 51, 73, +47, 231, -47, 115, -53, -170, -34, -264, +-110, -44, -298, 125, -152, 74, 208, 40, +161, 171, -162, 76, -123, -240, 108, -354, +73, 9, -373, 315, -544, 134, 186, -158, +572, -67, -62, 126, -435, 83, 19, -69, +200, -130, -297, -67, -461, -30, 129, -17, +377, 20, -82, 176, -261, 224, 49, 7, +90, -211, -201, -195, -349, -180, -115, -55, +164, 218, 173, 345, -5, 102, -133, -59, +-148, -100, -204, -239, -56, -301, 41, -59, +-46, 266, -49, 425, 64, 268, -105, -116, +-187, -450, -100, -437, 23, -39, 124, 435, +66, 448, -261, 43, -354, -288, -100, -355, +173, -146, 125, 200, 7, 396, -28, 158, +-162, -238, -291, -348, -208, -147, 140, 113, +222, 303, -115, 270, -239, -38, 66, -418, +-92, -266, -245, 159, 106, 358, 164, 189, +-261, -151, -238, -402, 94, -177, 155, 290, +-97, 357, -353, -16, -201, -316, 228, -217, +282, 191, -181, 450, -313, 77, -73, -568, +-54, -548, -165, 194, 142, 753, 186, 447, +-257, -290, -341, -587, 133, -364, 262, 114, +-136, 507, -416, 304, -157, -261, 146, -319, +145, 62, -12, 288, -210, 21, -289, -355, +44, -200, 259, 317, -116, 415, -357, -65, +-91, -416, 126, -198, 18, 220, -75, 263, +-94, 0, -26, -189, -100, -107, -287, 56, +-29, 59, 340, 94, 29, 60, -439, -39, +-224, -72, 182, -85, 150, -44, -267, 62, +-332, 48, 126, 31, 239, 114, -86, 46, +-256, -141, -115, -150, 29, 9, -69, 128, +-148, -20, 2, -9, 16, 188, -104, 23, +-32, -278, -15, -233, -85, 120, -88, 299, +-47, 253, -81, 77, -199, -220, -21, -522, +155, -315, -99, 295, -169, 664, 52, 261, +-31, -405, -170, -306, -76, 227, -44, 137, +-89, -423, -165, -422, -18, 296, 228, 859, +59, 330, -294, -704, -218, -779, 30, 258, +-183, 764, -295, -56, 205, -659, 520, 44, +-44, 698, -659, 138, -406, -645, 266, -425, +311, 288, -283, 541, -299, 163, 163, -255, +146, -278, -134, -151, -172, 36, -183, 275, +-128, 260, 19, -82, 84, -245, -101, -11, +-134, 108, -26, -199, 74, -275, 27, 361, +-118, 730, -389, 162, -335, -806, 87, -907, +319, 180, 222, 990, -32, 477, -307, -351, +-458, -483, -232, -91, 165, 140, 274, 50, +-84, 26, -188, 102, 8, 25, 52, -78, +-219, -69, -268, -54, -94, 97, 132, 256, +62, 12, -45, -404, -153, -250, -154, 320, +-63, 458, -54, 111, -142, -276, 56, -578, +219, -218, -113, 582, -417, 701, -228, -163, +126, -763, 168, -255, -133, 548, -192, 425, +120, -209, 92, -340, -311, -83, -307, 88, +55, 139, 69, 120, -34, 112, -34, -68, +-170, -309, -188, -240, 132, 241, 282, 553, +-113, 279, -561, -396, -550, -830, 17, -406, +630, 664, 613, 1144, -185, 282, -967, -926, +-655, -902, 283, 185, 701, 738, 189, 289, +-470, -340, -531, -380, -43, -41, 127, 282, +24, 385, 88, 291, 87, -233, -256, -691, +-460, -391, -121, 366, 252, 686, 50, 271, +-212, -359, -22, -537, 40, -84, -189, 563, +-75, 447, 54, -303, -265, -635, -169, -248, +168, 515, -81, 679, -319, -71, 66, -754, +227, -282, -12, 625, -188, 587, -341, -313, +-289, -698, 56, -173, 294, 507, 53, 618, +-370, -69, -416, -780, 284, -362, 643, 644, +-196, 657, -1013, -233, -478, -604, 378, -106, +563, 310, 244, 216, -336, -37, -527, -116, +-205, -69, 15, -181, 130, 79, 233, 590, +-184, 351, -541, -602, -224, -896, 288, 2, +389, 863, 47, 511, -422, -159, -525, -192, +-159, -287, 283, -495, 268, 56, -236, 682, +-400, 366, 21, -472, 405, -358, 77, 483, +-566, 411, -598, -605, 155, -812, 456, 271, +-23, 924, -303, 340, -31, -398, 11, -299, +-151, -35, -304, -90, -182, -114, 268, 133, +297, 465, -265, 70, -523, -552, -104, -243, +220, 494, 176, 577, -170, -197, -342, -807, +-87, -219, 151, 745, -40, 493, -244, -549, +-131, -715, 71, 298, 64, 994, -184, 269, +-261, -864, 99, -758, 252, 403, -210, 857, +-579, -84, -288, -891, 447, -196, 653, 984, +-235, 829, -968, -529, -291, -1327, 561, -374, +275, 1124, -425, 1153, -254, -502, 186, -1304, +81, 12, -264, 1135, -463, 244, -109, -1090, +501, -496, 410, 1172, -427, 1138, -701, -800, +-201, -1642, 276, -100, 228, 1312, -38, 735, +-120, -478, -84, -557, -73, 81, -253, 272, +-359, -185, 97, -350, 356, 166, -53, 563, +-232, 278, -75, -463, -128, -661, -182, 2, +-158, 585, 90, 423, 328, -120, -26, -309, +-602, -207, -423, -41, 306, 163, 509, 287, +67, -7, -571, -411, -661, -145, 6, 339, +525, 418, 316, 117, -152, -325, -471, -436, +-435, -155, -28, 195, 209, 306, 150, 181, +205, -54, -113, -84, -549, 77, -504, -30, +109, -327, 571, -103, 302, 333, -451, 323, +-602, -186, -208, -437, 297, -29, 538, 543, +-50, 433, -756, -288, -534, -691, 361, -341, +617, 500, -1, 738, -618, -74, -210, -558, +259, -83, -270, 228, -426, 42, 401, -133, +420, -13, -271, 199, -404, 191, -107, -188, +-149, -340, 67, 19, 198, 400, -78, 199, +-335, -301, -167, -324, 186, 158, 223, 320, +-206, 27, -463, -94, -29, -57, 255, -90, +36, -92, -230, 84, -277, 205, -107, -30, +309, -192, 179, 75, -352, 207, -263, 77, +52, -113, -28, -169, -116, -177, -31, -78, +-96, 233, -127, 355, 193, 60, 178, -205, +-186, -29, -270, -17, -210, -257, -210, -97, +-17, 322, 217, 333, 144, -202, 126, -357, +-47, 32, -523, 387, -518, 332, 192, -339, +519, -562, -89, 107, -442, 525, 12, 79, +177, -432, -156, -215, -97, 373, -41, 432, +-168, -88, -29, -332, 116, -88, -95, 148, +-151, -40, -92, -402, -154, -41, 173, 637, +365, 454, -198, -126, -675, -381, -396, -441, +481, -124, 733, 364, -176, 448, -861, -157, +-323, -612, 407, -6, 485, 793, -53, 473, +-627, -495, -322, -711, 384, -94, 339, 342, +-194, 188, -571, -41, -297, 78, 468, 220, +485, -6, -182, -328, -409, -65, -290, 185, +-147, -7, 143, -179, 230, -81, 22, 142, +-81, 277, -245, 64, -276, -188, 194, -31, +208, 92, 0, -24, -240, -145, -591, -251, +-184, 12, 726, 308, 469, 404, -483, 107, +-573, -338, 38, -417, 353, 10, -80, 352, +-489, -27, -63, -321, 431, 78, 85, 452, +-396, 251, -81, -356, 363, -455, -25, 139, +-572, 437, -345, -188, 201, -491, 433, 157, +233, 604, -305, 234, -458, -330, -103, -482, +397, -143, 69, 314, -546, 368, -207, -57, +385, -316, 287, 83, -180, 275, -306, -144, +-198, -388, -54, 58, 133, 514, 275, 205, +53, -294, -490, -307, -452, -155, 253, 74, +533, 296, -49, 260, -457, -13, -154, -172, +88, -195, 57, -50, -26, -18, -31, -22, +-91, 228, -94, 340, 66, -34, 197, -415, +-278, -207, -537, 198, 201, 178, 586, -94, +8, -13, -504, 218, -184, 135, 92, -229, +-116, -362, -68, 103, 201, 365, 189, 11, +-107, -287, -241, -87, -214, 317, -87, 175, +215, -133, 153, -103, -188, -42, -210, -128, +9, -127, 117, 115, 83, 267, -153, 181, +-233, -18, 76, -61, 104, -146, -203, -367, +-142, -13, 144, 485, 193, 150, -53, -358, +-290, -228, -231, 364, 142, 456, 276, -178, +-28, -596, -351, -129, -57, 459, 85, 215, +-45, -358, 53, -291, 96, 329, -132, 494, +-206, -62, 101, -374, 123, -42, -321, 98, +-189, -273, 320, -319, 141, 375, -169, 666, +-22, 78, -89, -373, -350, -300, -11, -106, +413, 60, 219, 186, -386, 120, -405, -152, +71, -139, 289, 300, 96, 272, -142, -252, +-193, -327, 27, 114, 8, 161, -156, -165, +14, -246, 131, 348, -43, 629, -84, -244, +187, -927, -108, -42, -489, 923, 121, 319, +440, -741, -290, -434, -340, 423, 561, 402, +312, -45, -789, -289, -592, -111, 478, 186, +555, 56, 51, -114, -230, -31, -467, 179, +-277, 108, 385, -232, 398, -275, -208, 217, +-333, 436, 55, -116, 210, -346, -172, -110, +-281, 113, 128, 218, 233, 102, 43, 11, +-151, -127, -292, -267, 93, -72, 281, 268, +-401, 178, -436, -54, 680, -101, 598, -21, +-518, 90, -692, 7, -104, -165, 522, -90, +381, 227, -444, 174, -480, -199, 383, -339, +511, 169, -169, 644, -657, 95, -242, -839, +457, -484, 416, 728, -123, 616, -356, -475, +-162, -512, 20, 280, 173, 488, 59, -191, +-185, -461, 32, 231, 341, 547, -209, -196, +-582, -827, 82, -217, 440, 894, -48, 880, +-157, -528, 45, -1143, 123, -30, -107, 1082, +-221, 452, -79, -892, 138, -820, 192, 588, +-180, 1063, -272, -240, 123, -996, 304, -160, +103, 923, -150, 477, -483, -669, -243, -657, +418, 225, 462, 696, -231, 78, -607, -661, +129, -331, 844, 541, -70, 768, -1049, -100, +-271, -922, 802, -612, 469, 581, -291, 962, +-524, -60, -80, -940, 369, -230, 214, 929, +-268, 347, -367, -897, 143, -431, 293, 776, +71, 508, -192, -583, -305, -560, -19, 270, +398, 445, 269, 9, -421, -103, -428, -11, +192, -91, 269, -264, -115, 45, 8, 478, +138, 79, -74, -478, -104, -183, -106, 383, +-128, 317, -16, -241, 206, -495, 219, 15, +-32, 682, -406, 319, -121, -611, 581, -692, +84, 258, -797, 833, -235, 172, 673, -658, +232, -484, -268, 466, 4, 700, -16, -262, +-169, -851, -130, -120, 128, 713, 202, 617, +-80, -303, -175, -735, -35, -99, 91, 392, +84, 243, 62, -90, -125, -146, -125, 90, +-63, 153, 90, -33, 190, -287, -95, -245, +-393, 242, 24, 445, 507, -40, 43, -379, +-412, 32, -33, 298, 318, 9, -211, -321, +-461, -188, 225, 162, 497, 225, -70, 188, +-281, -114, -49, -191, -31, 65, -15, -29, +325, -96, -49, 59, -540, 110, -50, -32, +585, 91, 222, 161, -518, -209, -424, -550, +293, 170, 606, 816, -49, 75, -630, -712, +-319, -350, 527, 440, 526, 489, -401, -259, +-561, -472, 193, 83, 373, 265, 6, 0, +-115, 52, -16, 137, 92, -5, -76, -391, +-214, -271, -174, 353, -54, 403, 349, -82, +492, -505, -24, -238, -573, 620, -359, 684, +447, -146, 321, -948, -633, -689, -393, 523, +797, 1039, 582, 0, -569, -694, -566, -213, +298, 509, 505, 399, -272, -431, -621, -683, +-44, 70, 566, 716, 447, 335, -217, -521, +-612, -659, 47, 355, 713, 898, -52, 85, +-965, -799, -279, -730, 1039, 305, 677, 992, +-655, 255, -1009, -922, 216, -724, 1179, 724, +190, 1090, -1151, -181, -539, -1255, 868, -381, +622, 978, -600, 773, -715, -604, 395, -1073, +911, 176, 71, 1130, -816, 480, -606, -748, +290, -905, 658, 78, 90, 922, -456, 405, +-158, -775, 482, -901, 329, 640, -539, 1448, +-726, -189, 234, -1605, 749, -467, 230, 1165, +-486, 964, -385, -558, 285, -1083, 413, 82, +-164, 898, -607, 224, -125, -554, 578, -384, +555, 245, -309, 470, -636, -75, 40, -431, +357, -108, 36, 306, -159, 291, -125, -93, +185, -288, 252, -154, -172, 6, -284, 298, +11, 316, 124, -310, 210, -437, 9, 242, +-199, 642, -158, -201, -17, -944, 195, -47, +296, 989, -41, 437, -407, -695, -248, -656, +207, 394, 399, 851, 77, -177, -199, -1005, +-285, -196, -84, 798, 323, 529, 78, -427, +-212, -460, 53, 299, 81, 340, -65, -262, +-43, -416, 106, 84, -8, 361, -204, 30, +-25, -134, 247, 12, -27, 7, -161, -10, +223, 90, 162, 22, -298, -146, -324, -180, +115, -29, 362, 220, 49, 281, -233, -62, +-123, -250, 219, -34, 209, 142, -186, 7, +-433, -173, 61, -72, 469, 214, 158, 142, +-310, -38, -356, 13, 48, -226, 308, -411, +346, 219, -34, 887, -523, 240, -341, -997, +370, -900, 451, 661, -193, 1153, -337, -196, +157, -934, 308, 19, -98, 594, -361, -41, +-60, -376, 250, 133, 211, 374, -111, -168, +-282, -540, 16, -45, 259, 755, -3, 456, +-187, -650, 134, -911, 82, 192, -116, 1221, +-149, 444, -64, -1223, 76, -950, 305, 787, +107, 1116, -200, -169, -254, -905, -111, -314, +153, 575, 248, 542, 131, -186, -219, -539, +-230, -260, 102, 494, 158, 521, -65, -372, +-146, -743, 33, 129, 360, 966, 70, 264, +-476, -849, -339, -600, 288, 456, 540, 702, +90, -182, -503, -795, -304, -49, 344, 987, +263, 363, -284, -873, -239, -757, 428, 593, +416, 1012, -387, -297, -643, -1207, 3, -138, +570, 1179, 314, 521, -214, -776, -282, -488, +-21, 475, 144, 236, 143, -445, -233, -215, +-262, 289, 310, 209, 383, 8, -272, 33, +-473, -103, 259, -229, 645, 136, -209, 211, +-817, -232, -37, -274, 796, 296, 339, 350, +-577, -217, -502, -449, 232, 178, 598, 611, +132, -59, -529, -691, -539, -203, 333, 574, +734, 393, -5, -336, -666, -449, -285, 76, +355, 397, 381, 212, 11, -231, -305, -474, +-142, 84, 219, 654, 125, 89, -329, -730, +-85, -430, 306, 679, 140, 678, -157, -412, +-138, -789, 46, 180, 171, 861, -18, 91, +-170, -888, -28, -465, 36, 714, -8, 603, +36, -405, 141, -528, 42, 244, -82, 497, +-36, -170, 9, -461, -119, 69, -177, 284, +36, -71, 339, -145, 234, 41, -145, 144, +-244, 231, -134, 32, -33, -469, 144, -466, +113, 352, -33, 816, -41, 35, 19, -692, +84, -399, -41, 280, -193, 426, -34, 23, +279, -192, 91, 55, -295, 131, -177, -259, +124, -361, 193, 216, 219, 531, 50, -52, +-421, -431, -297, -15, 193, 314, 318, 76, +119, -256, -163, -205, -278, 86, 56, 233, +337, 95, -4, -168, -273, -176, -112, 237, +163, 295, 163, -280, -113, -467, -251, 171, +127, 507, 325, -144, -68, -540, -236, 181, +7, 743, 34, 100, 22, -718, -35, -494, +-216, 299, 19, 449, 550, 28, 250, -122, +-613, 56, -571, -66, 341, -237, 655, 119, +-109, 456, -562, -114, -104, -704, 398, -152, +348, 753, -27, 501, -476, -542, -344, -635, +352, 282, 436, 646, -261, 41, -408, -546, +256, -324, 444, 200, -198, 295, -432, 153, +43, 33, 288, -195, 20, -303, -101, 51, +-65, 305, -71, 130, 183, -204, 196, -182, +-181, 92, -270, 83, 28, -73, 114, -28, +58, 76, 98, 116, 51, 78, -125, -31, +-162, -180, 4, -223, 0, -5, -2, 223, +132, 177, 144, -5, -49, -66, -101, 37, +-27, -21, -121, -297, -102, -130, 188, 307, +225, 323, -162, -95, -179, -392, 223, -66, +94, 399, -290, 176, -67, -281, 232, -289, +-22, 74, -191, 293, 69, 22, 207, -238, +8, -7, -210, 238, -113, 121, 151, -149, +96, -240, -149, -86, -79, 181, 122, 216, +76, -12, -47, -160, -55, 18, -23, 91, +-47, -86, -45, -125, 150, 50, 122, 253, +-209, 98, -86, -317, 254, -343, -127, 184, +-359, 457, 334, 131, 532, -328, -363, -294, +-695, 175, 131, 246, 676, -155, 65, -266, +-470, 70, -159, 373, 340, 233, 221, -171, +-295, -462, -410, -329, 96, 254, 417, 668, +136, 227, -109, -539, -153, -484, -136, 210, +-15, 456, 106, -57, -25, -402, -70, -27, +192, 432, 135, 185, -237, -332, -288, -317, +138, 196, 406, 371, 21, -52, -445, -385, +-250, -186, 359, 261, 303, 321, -180, -117, +-263, -244, 131, 163, 222, 344, -140, -153, +-272, -537, 72, -236, 288, 366, -35, 499, +-269, 103, -79, -307, 229, -285, 231, 72, +-35, 227, -312, 55, -305, -200, 201, -265, +488, 11, 55, 336, -544, 267, -289, -112, +484, -275, 492, -1, -328, 264, -660, -107, +-14, -473, 586, -26, 327, 552, -264, 364, +-433, -331, -67, -398, 407, 192, 211, 236, +-449, -217, -365, -260, 345, 67, 576, 297, +62, 149, -583, -115, -474, -130, 306, -33, +536, 69, -112, 68, -484, -176, 39, -235, +513, 156, 107, 405, -471, 111, -235, -333, +176, -214, 123, 202, 110, 167, 97, -198, +-274, -264, -311, 78, 297, 344, 434, 130, +-185, -149, -380, -121, 35, -88, 217, -33, +-73, 97, -171, 80, 73, 3, 249, -77, +65, -37, -241, 103, -231, 21, 96, -122, +271, -31, -45, 151, -204, 149, 15, -180, +187, -272, -36, 153, -214, 225, -36, -120, +176, -82, 100, 193, -63, 60, -28, -328, +-28, -104, -192, 387, -75, 162, 253, -366, +229, -135, -163, 316, -252, 128, 49, -331, +129, -212, -78, 263, 58, 221, 149, -13, +-179, 42, -165, -100, 101, -307, 50, -136, +-94, 217, 84, 318, 202, 69, -66, -242, +-203, -109, -23, 117, 22, 75, -126, -119, +44, -159, 242, 117, 53, 207, -226, -59, +-14, -117, 234, 82, -116, 51, -435, -157, +-28, -99, 501, 222, 349, 162, -306, -301, +-506, -197, 41, 407, 345, 283, 149, -461, +-163, -481, -312, 407, 95, 689, 491, -206, +-12, -778, -653, -109, -333, 630, 565, 417, +667, -385, -230, -524, -578, 222, -38, 562, +276, -65, -13, -653, -277, -345, 1, 497, +408, 763, 271, 0, -318, -718, -411, -371, +127, 381, 323, 348, -212, -169, -357, -285, +176, 67, 500, 341, 156, 138, -473, -340, +-431, -342, 233, 220, 465, 487, -8, -46, +-432, -551, -220, -204, 314, 463, 360, 303, +-139, -308, -233, -230, 27, 266, 97, 223, +-159, -235, -206, -359, 250, 68, 390, 489, +-79, 183, -497, -402, -259, -486, 279, 90, +459, 553, 73, 277, -262, -296, -192, -219, +-21, 110, -37, -57, -100, -323, 66, -44, +161, 395, 230, 345, 233, -76, -74, -163, +-565, -97, -572, -201, 262, -197, 758, 152, +110, 361, -428, 155, -123, -197, 155, -188, +88, 26, -28, 76, -141, 69, -75, -24, +25, -116, 1, -76, -71, -4, 36, 9, +213, 130, 206, 269, -4, 124, -299, -282, +-320, -430, -33, -50, 194, 287, 94, 159, +26, -71, 145, -3, 103, 193, -184, 88, +-266, -195, 84, -251, 152, -122, -170, 91, +-167, 292, 208, 65, 297, -177, -115, 12, +-348, 161, 23, -18, 355, -228, 92, -83, +-294, 231, -333, 90, 48, -258, 341, -67, +116, 248, -255, 119, -84, -93, 291, -71, +109, -2, -269, -33, -250, -16, -63, 13, +243, -21, 310, 19, -199, 110, -374, 79, +243, -91, 509, -147, -206, -43, -755, 94, +-27, 73, 772, 49, 252, -5, -627, -101, +-371, -9, 388, 71, 442, -52, -125, -152, +-435, 13, -202, 284, 329, 248, 465, -225, +-239, -405, -697, -27, 57, 293, 805, 209, +244, -92, -674, -237, -451, -90, 401, 188, +366, 190, -284, -136, -260, -170, 235, 153, +329, 223, -111, -112, -407, -389, -83, -202, +323, 368, 175, 471, -229, -84, -202, -385, +165, -85, 230, 215, -84, 77, -274, -180, +-102, -169, 289, 70, 244, 242, -249, 179, +-297, -102, 123, -273, 242, -34, -49, 221, +-202, 61, 59, -266, 201, -182, -26, 218, +-201, 387, -107, 78, 105, -370, 203, -328, +-45, 213, -311, 321, 11, -148, 386, -291, +42, 165, -307, 325, -40, -126, 140, -324, +-125, 67, -91, 230, 165, 15, 76, -67, +-108, -49, 75, -114, 159, -40, -167, 86, +-294, 70, 73, 59, 268, 134, -49, 14, +-221, -280, 47, -229, 285, 133, 119, 229, +-273, 37, -334, -42, 59, -66, 369, -67, +50, 44, -304, 88, -83, 6, 212, -44, +179, 4, -16, -77, -225, -157, -209, 50, +94, 240, 211, 115, 22, -119, -89, -131, +-34, -20, 10, 53, 39, 15, 66, -6, +-104, -21, -146, -50, 80, 51, 83, 140, +-127, 3, 5, -169, 300, -81, -2, 160, +-420, 224, -86, -92, 408, -320, 100, -147, +-305, 148, -141, 322, 54, 160, 189, -237, +282, -292, -65, 117, -477, 311, -228, -81, +348, -403, 432, 12, -140, 516, -517, 129, +7, -530, 468, -335, 107, 491, -324, 553, +-175, -297, 119, -673, 161, -25, -20, 613, +-200, 303, -71, -429, 204, -468, 202, 257, +-83, 558, -225, -103, -33, -628, 147, -49, +-12, 639, -191, 213, 63, -534, 234, -381, +49, 286, -124, 458, -181, -2, -84, -361, +225, -210, 216, 187, -158, 321, -278, -49, +-81, -418, 193, -69, 293, 475, 40, 291, +-231, -351, -237, -488, 38, 15, 227, 399, +-13, 251, -180, -81, 117, -255, 213, -135, +-197, 170, -276, 181, 148, -177, 305, -260, +-47, 181, -214, 399, -46, -23, 53, -422, +52, -261, 34, 219, -45, 393, -63, 65, +110, -251, 137, -192, -151, 58, -229, 105, +67, -20, 229, -28, 21, 101, -105, 21, +-89, -129, -11, -23, 47, 85, 68, -2, +22, -51, -43, 95, -38, 135, -25, -133, +-50, -288, 9, 2, 109, 254, 64, 149, +-15, -18, -109, -44, -180, -111, -3, -156, +224, 30, 167, 219, -69, 83, -161, -155, +-92, -132, -9, 97, 55, 108, 84, -93, +18, -57, -62, 152, 56, 76, 88, -155, +-130, -134, -174, 96, 100, 105, 159, -49, +-29, -91, -125, -10, -102, 112, 96, 156, +238, 3, -11, -247, -257, -142, -47, 236, +236, 150, 55, -246, -337, -166, -190, 183, +413, 161, 315, -22, -301, -17, -200, 82, +255, -56, 28, -273, -309, -143, -96, 183, +180, 308, 164, 92, 19, -283, -30, -208, +-7, 260, -36, 252, -76, -201, -24, -288, +-33, 73, -60, 220, 76, -95, 185, -180, +77, 180, -99, 314, -138, -84, -21, -369, +57, -75, -11, 292, -101, 118, -17, -285, +136, -243, 208, 238, 22, 500, -272, 16, +-224, -518, 179, -244, 206, 291, -125, 249, +-87, -218, 146, -219, 50, 250, -144, 311, +-37, -165, 96, -346, 67, 8, -55, 269, +-118, 58, -17, -229, 116, -73, 27, 217, +-74, 142, 24, -137, 88, -215, 46, 17, +-96, 234, -192, 119, -34, -210, 171, -301, +160, 81, -22, 446, -145, 152, -20, -382, +138, -294, -31, 197, -161, 271, -25, -117, +63, -282, 68, 60, 97, 333, 54, 134, +-96, -209, -96, -215, 19, 18, -109, 63, +-148, -109, 258, -50, 385, 301, -129, 312, +-419, -227, -69, -412, 304, 89, 80, 334, +-223, -114, -109, -425, 146, -1, 267, 491, +106, 281, -366, -256, -397, -305, 235, 53, +516, 148, -16, -68, -505, -104, -157, 62, +381, 32, 258, -63, -150, 142, -276, 234, +-17, -131, 260, -334, 43, -2, -273, 247, +-113, 2, 208, -220, 254, -26, 6, 205, +-218, 143, -107, -52, 49, -126, -15, -26, +-78, 35, 55, -41, 240, -36, 76, 46, +-263, 16, -159, -5, 192, 115, 175, 139, +-203, -180, -289, -344, 181, 84, 408, 456, +-75, 63, -367, -455, -31, -228, 332, 349, +136, 375, -335, -168, -298, -373, 195, 3, +386, 193, 61, 27, -311, -49, -207, 87, +243, 87, 220, -115, -238, -206, -316, -19, +121, 162, 450, 156, 182, 17, -421, -175, +-435, -145, 211, 103, 514, 208, -47, 42, +-517, -192, -69, -215, 555, 27, 175, 283, +-542, 215, -263, -175, 401, -322, 312, 26, +-157, 277, -284, 35, -151, -228, 162, -95, +285, 207, 3, 184, -224, -65, -28, -102, +182, -18, -30, -94, -279, -174, -56, -15, +282, 321, 198, 335, -116, -71, -184, -263, +-15, -137, 103, -80, 27, -93, -50, 74, +-29, 321, 16, 169, -50, -247, -110, -193, +85, 162, 310, 176, 100, -42, -330, -220, +-299, -162, 99, 107, 274, 151, 30, -23, +-228, -54, -29, 131, 345, 224, 176, -52, +-408, -352, -400, -220, 253, 117, 507, 251, +-18, 97, -486, -154, -187, -127, 353, 151, +350, 241, -175, -42, -381, -338, 0, -188, +421, 180, 173, 274, -455, 59, -442, -224, +311, -178, 598, 133, -7, 189, -448, -52, +-168, -157, 248, -4, 131, 137, -166, 34, +-83, -106, 82, -31, 103, 62, 110, -30, +-143, -120, -348, -58, 98, 132, 529, 290, +138, 168, -482, -241, -422, -454, 189, -144, +409, 320, 120, 374, -174, 2, -261, -337, +1, -233, 339, 235, 122, 452, -375, -53, +-286, -566, 238, -209, 332, 484, -54, 383, +-155, -324, -30, -508, -1, 104, 104, 535, +14, 165, -193, -355, -38, -272, 192, 146, +76, 225, -72, -117, -91, -222, 39, 97, +123, 238, -44, -3, -216, -206, -89, -100, +237, 157, 249, 209, -96, -1, -229, -214, +-65, -203, 122, -14, 122, 185, -66, 207, +-118, -3, 2, -193, 73, -84, 113, 167, +-1, 141, -167, -144, -56, -257, 73, 54, +65, 331, 35, 55, -25, -331, -84, -198, +-58, 244, 91, 326, 139, -33, -41, -275, +-135, -57, 35, 123, 38, -81, -88, -195, +-29, 79, 156, 307, 130, 152, -137, -169, +-159, -214, 74, -19, 125, 46, -83, 8, +-113, 42, 88, 24, 161, -52, -71, 2, +-173, 117, 24, 61, 168, -110, 4, -87, +-212, 89, 10, -26, 283, -245, -26, -28, +-302, 383, -38, 273, 226, -240, 129, -305, +-57, 95, -132, 111, -80, -206, 65, -114, +116, 272, -28, 253, -149, -137, 70, -230, +190, 126, -47, 174, -247, -239, -38, -303, +264, 134, 165, 392, -187, 101, -236, -296, +9, -184, 130, 174, 131, 197, 60, -58, +-64, -238, -110, -126, -91, 200, -32, 259, +61, -92, 141, -277, 65, 64, -7, 344, +-82, -55, -166, -472, -48, -111, 195, 430, +148, 322, -105, -237, -115, -356, -8, 129, +34, 277, 38, -113, 6, -242, -18, 35, +50, 198, 22, 22, -86, -135, -20, 37, +56, 135, -55, -71, -52, -151, 88, -34, +163, 78, -48, 97, -181, 32, 25, -32, +108, -68, -154, -17, -63, 75, 223, 21, +67, -102, -199, -37, -55, 110, 217, 79, +42, -70, -196, -87, -59, 35, 98, 23, +-38, -32, -67, 30, 101, 69, 170, -2, +25, -59, -170, -20, -142, 28, 38, -54, +70, -123, -44, 81, 7, 307, 163, 110, +41, -340, -185, -350, -107, 137, 149, 393, +200, 85, -100, -281, -332, -187, -28, 169, +336, 269, 142, -36, -195, -350, -162, -213, +136, 278, 198, 428, -90, -65, -226, -457, +-110, -83, 81, 435, 248, 182, 142, -444, +-163, -390, -160, 309, 68, 556, 83, -78, +-100, -509, -138, -41, 126, 456, 234, 170, +-56, -419, -271, -398, -26, 164, 228, 396, +112, 84, -149, -121, -159, -28, 61, 53, +171, -4, -6, -152, -232, -198, -118, -17, +265, 266, 348, 289, -124, -67, -424, -327, +-64, -82, 326, 238, 109, 69, -229, -224, +-132, -59, 166, 239, 147, 103, -53, -225, +-75, -179, 58, 175, 75, 233, -102, -94, +-257, -255, -67, -9, 344, 246, 302, 176, +-202, -159, -330, -314, 104, -40, 248, 289, +-21, 216, -205, -189, -175, -294, 23, 112, +267, 349, 175, 20, -143, -334, -139, -129, +145, 229, 65, 123, -329, -168, -193, -79, +353, 150, 329, 103, -239, -102, -328, -146, +142, 10, 298, 175, 15, 176, -198, -97, +-179, -360, 39, -105, 198, 321, 3, 219, +-213, -191, -36, -224, 282, 165, 252, 332, +-140, -41, -378, -358, -112, -219, 217, 129, +183, 235, -101, -7, -187, -117, 117, 106, +306, 163, -15, -33, -310, -162, -89, -136, +184, -43, 72, 28, -185, 123, -96, 187, +118, 9, 146, -199, 71, -112, 17, 137, +-56, 140, -112, -109, -93, -167, -74, 81, +18, 194, 141, -53, 96, -277, -53, -49, +44, 356, 131, 255, -65, -237, -234, -349, +-105, 26, 60, 301, 74, 67, 31, -248, +79, -145, 105, 151, 4, 229, -91, 45, +-46, -188, -34, -174, -110, 75, -30, 172, +141, -18, 104, -178, -45, -40, 3, 190, +42, 118, -16, -133, -79, -117, -11, 111, +41, 122, -58, -110, -116, -251, 50, -20, +190, 288, 92, 235, -111, -93, -114, -246, +107, -74, 56, 120, -189, 37, -103, -129, +121, -43, 105, 175, -4, 188, -24, -37, +-4, -176, 22, -72, 40, 24, 17, -24, +-103, -49, -137, 58, -1, 130, 143, 78, +137, 7, 3, -80, -93, -183, -82, -93, +4, 118, 117, 158, 32, 31, -142, -71, +-94, -68, 51, -9, 132, 60, 82, 90, +-128, -45, -116, -161, 219, -19, 171, 116, +-233, 51, -341, -7, 46, 3, 360, -15, +147, -44, -190, -16, -130, 45, 31, 3, +64, -88, 50, -30, -20, 109, -53, 124, +-36, -14, 17, -151, 34, -114, 1, 56, +18, 146, 76, 30, -24, -117, -92, -72, +2, 86, 77, 106, -22, -23, -122, -115, +-34, -54, 161, 16, 186, 62, -46, 96, +-239, 7, -54, -126, 208, -80, 36, 113, +-154, 124, -49, -78, 67, -158, 51, 34, +22, 146, 23, 2, 29, -112, -13, -20, +-34, 100, -94, 45, -137, -95, 76, -111, +237, 13, 60, 116, -112, 102, -46, -22, +35, -103, -4, -8, -94, 96, -64, -48, +67, -230, 113, -51, -18, 282, -79, 257, +73, -92, 105, -231, -76, -7, -113, 103, +-6, -103, 9, -198, 5, 28, 68, 284, +117, 255, 2, -90, -168, -334, -77, -149, +168, 214, 126, 189, -165, -180, -175, -258, +162, 122, 222, 340, -149, 45, -236, -239, +84, -60, 217, 134, 11, -53, -105, -234, +-3, -12, 56, 305, -39, 202, -99, -143, +-60, -203, 33, -11, 103, 62, 58, 1, +9, -10, 25, 21, 17, 30, -82, -11, +-142, -39, -23, 33, 127, 124, 43, -7, +-14, -261, 71, -166, 41, 249, -69, 315, +-33, -99, 54, -294, -53, 37, -212, 245, +-55, -20, 223, -212, 160, -22, -14, 140, +0, 24, -28, -67, -129, 27, -87, 56, +24, -25, 109, -38, 113, 18, -27, 22, +-161, 0, -9, -57, 196, -85, 24, -40, +-186, 83, -25, 183, 159, 70, 21, -112, +-157, -148, -64, -30, 143, 91, 132, 44, +-40, -139, -73, -113, 21, 174, 32, 277, +-74, -30, -80, -276, 32, -56, 58, 209, +21, 35, 25, -288, -8, -174, 2, 253, +14, 332, -24, -26, -1, -214, -12, -52, +-39, 63, 34, -64, 51, -139, 26, 63, +32, 226, -56, 81, -61, -139, 9, -146, +7, -4, -19, 117, -18, 73, 35, -56, +117, -80, 38, 8, -88, 40, -50, -55, +52, -44, -4, 77, -91, 63, 106, 7, +179, 51, -133, -19, -211, -234, 81, -189, +131, 230, -35, 371, -64, -53, 94, -330, +69, -49, -172, 258, -89, 85, 171, -237, +77, -192, -93, 121, -8, 237, 74, 58, +14, -126, -79, -75, -31, 66, 53, 60, +6, -53, -116, -137, -108, -88, 105, 94, +243, 204, 32, 83, -127, -65, -37, -57, +23, -28, -19, -120, -43, -183, -10, 25, +-2, 268, 29, 179, 191, -80, 141, -121, +-189, -24, -219, -3, -19, -65, 103, -37, +110, 59, -46, 61, -118, -15, 70, -39, +175, 33, 65, 74, -46, 31, -86, -48, +-20, -104, -34, -105, -120, 0, -33, 143, +155, 139, 181, -23, 14, -146, -172, -47, +-123, 97, 114, 42, 171, -80, -52, -19, +-209, 73, -23, 39, 135, -77, 58, -125, +12, -21, 92, 125, 23, 165, -105, 15, +-69, -148, 45, -62, -62, 89, -162, -56, +26, -236, 224, -14, 142, 360, -49, 257, +-81, -181, 15, -255, 15, 4, -105, 74, +-11, -95, 107, -99, -23, 122, -114, 215, +80, 27, 184, -147, 23, -116, -150, 16, +-115, 116, -19, 71, 40, -107, 79, -195, +21, -11, -18, 233, 73, 193, 87, -83, +-83, -185, -121, -33, 46, 89, 101, 7, +-64, -96, -122, -39, -5, 78, 134, 144, +133, 55, -82, -121, -186, -127, 68, 19, +179, 44, -61, -12, -138, 22, 21, 75, +117, -2, 98, -97, 9, -4, -146, 88, +-109, -9, 116, -94, 115, 44, -131, 135, +-156, -66, 87, -236, 196, -26, 27, 294, +-135, 215, -43, -166, 71, -290, 70, 6, +-20, 210, -119, 23, -14, -200, 216, -67, +49, 222, -238, 220, -57, -83, 222, -256, +65, -72, -226, 132, -113, 47, 178, -135, +107, -46, -103, 186, -19, 196, 94, -45, +43, -202, -14, -105, 11, 66, -22, 48, +-106, -57, -84, -21, 112, 106, 134, 148, +-49, -2, -118, -170, 9, -145, 97, 42, +17, 175, -4, 68, 24, -146, -51, -146, +-107, 91, 15, 147, 154, -57, 126, -97, +-39, 129, -56, 171, 12, -101, -131, -309, +-190, -124, 81, 194, 234, 240, 94, 35, +-91, -91, -121, -20, 3, 23, 65, -80, +56, -139, 22, 4, -60, 131, -50, 46, +89, -42, 121, 64, -48, 109, -206, -91, +-46, -239, 224, -63, 111, 241, -218, 194, +-237, -171, 152, -261, 394, 115, 43, 304, +-335, -46, -107, -326, 215, -24, 119, 317, +-175, 69, -168, -308, 205, -148, 281, 235, +-131, 205, -295, -79, -6, -143, 174, -1, +52, 34, -130, -5, -93, -34, 134, -83, +213, 11, -25, 230, -211, 210, 21, -187, +245, -395, -13, -6, -287, 341, -98, 33, +211, -295, 186, 26, -124, 423, -250, 99, +83, -458, 343, -278, 76, 291, -312, 316, +-258, -185, 94, -365, 277, 67, 177, 452, +-65, 210, -207, -313, -42, -411, 175, 4, +40, 348, -178, 143, -45, -221, 126, -159, +1, 163, -119, 198, 27, -65, 126, -176, +31, -17, -22, 76, 5, -18, -15, -45, +-12, 60, 9, 84, -33, -46, -16, -78, +68, 42, 95, 60, -17, -88, -149, -128, +-74, 78, 100, 225, 77, 22, -10, -205, +-39, -87, -58, 98, 24, 45, 152, -97, +75, -22, -120, 135, -142, 91, 110, -48, +245, -72, -49, -56, -344, -85, -175, -2, +233, 167, 333, 137, -25, -127, -315, -183, +-109, 66, 241, 176, 213, -24, -137, -149, +-252, -1, 136, 146, 359, 45, -45, -136, +-457, -153, -186, -31, 357, 168, 375, 254, +-117, 39, -386, -261, -77, -210, 269, 95, +141, 146, -208, -73, -160, -76, 211, 177, +327, 192, -30, -96, -353, -264, -204, -114, +170, 78, 240, 146, 41, 131, -139, 34, +-136, -121, 8, -150, 113, 21, 57, 146, +-29, 33, -44, -134, -20, -62, 25, 114, +27, 75, -5, -106, 45, -85, 139, 96, +43, 110, -161, -82, -191, -161, 0, 35, +125, 186, 73, 32, 17, -175, 28, -83, +3, 164, -53, 152, -67, -111, -60, -197, +21, -25, 164, 110, 156, 84, -92, -2, +-193, -45, 20, -11, 133, 91, -4, 81, +-67, -169, -4, -277, 39, 57, 30, 359, +-74, 124, -120, -242, 28, -138, 214, 168, +108, 81, -171, -201, -123, -137, 180, 132, +123, 158, -163, 17, -148, -17, 81, 8, +127, -50, -36, -98, -122, -41, -17, 9, +91, 53, 103, 138, 55, 116, -126, -121, +-191, -263, 42, -33, 231, 235, 65, 122, +-104, -104, -25, -57, 90, 72, -5, -10, +-132, -136, -105, -49, 23, 91, 103, 104, +66, 72, 20, 41, 11, -76, -49, -201, +-128, -146, -21, 68, 174, 204, 180, 136, +-38, -2, -142, -66, -33, -38, 9, -55, +-82, -115, -45, -61, 102, 115, 153, 159, +22, 15, -159, -85, -106, -7, 120, 72, +139, -63, -80, -166, -152, -30, 58, 122, +216, 107, 45, 20, -161, -11, -75, -3, +84, -10, 28, -52, -149, -116, -117, -88, +134, 123, 245, 257, 4, 47, -181, -249, +-33, -175, 139, 112, -39, 123, -191, -49, +35, -15, 219, 112, 115, 14, -8, -137, +-122, -46, -190, 99, -73, 6, 79, -104, +146, 43, 62, 168, -46, -19, 0, -216, +16, -69, -84, 162, -13, 98, 78, -106, +6, -73, -58, 101, 28, 98, 117, -14, +41, -42, -81, -49, -73, -100, -29, -103, +-11, 31, 12, 187, 17, 191, 47, 25, +38, -186, -54, -222, -65, -43, 39, 112, +119, 69, 51, 30, -55, 144, -29, 178, +20, -89, -17, -369, -24, -248, -65, 119, +-63, 255, 101, 92, 161, -19, -31, 39, +-202, 37, -83, -128, 166, -206, 138, 2, +-64, 280, -28, 221, 90, -190, 30, -391, +-100, -56, -89, 354, 30, 251, 56, -182, +-55, -276, -67, 76, 53, 263, 95, 10, +-32, -270, -99, -144, 24, 215, 122, 256, +57, -86, -50, -256, -78, 25, 36, 221, +113, -77, -41, -323, -141, 3, -27, 401, +73, 209, 47, -223, -25, -232, -48, 73, +37, 91, 47, -175, -66, -178, -39, 177, +58, 392, 65, 133, 60, -280, 28, -325, +-50, -35, -44, 127, -10, 41, -52, 14, +-54, 165, 45, 177, 69, -82, -42, -259, +-17, -142, 56, 8, -28, 24, -93, 117, +86, 268, 180, 143, -9, -237, -198, -378, +-51, -65, 178, 300, 105, 283, -114, -22, +-106, -248, -2, -221, -8, -32, -43, 124, +22, 142, 124, 109, 112, 105, -5, 40, +-147, -142, -145, -255, 56, -161, 213, 39, +99, 191, -103, 233, -178, 118, -14, -119, +147, -268, 19, -182, -162, 23, -43, 160, +172, 207, 148, 186, -45, 48, -163, -183, +-129, -280, -29, -125, 108, 65, 162, 107, +54, 114, -72, 124, -79, 3, 45, -201, +67, -195, -75, 37, -76, 194, 90, 180, +68, 131, -71, 31, -126, -184, -56, -317, +21, -155, -9, 110, -25, 164, 148, 69, +273, 31, 102, 60, -168, 34, -218, -44, +-36, -80, 68, -15, -29, 72, -141, 7, +-56, -146, 110, -112, 202, 134, 121, 225, +-36, 8, -194, -199, -184, -138, 13, -1, +196, 27, 192, 73, 76, 215, -51, 193, +-98, -90, -116, -282, -209, -163, -130, -2, +181, 25, 299, 62, 57, 152, -136, 110, +-76, -41, 31, -94, -10, -51, -54, -29, +65, 8, 155, 97, 38, 85, -142, -72, +-168, -150, -40, -38, 61, 77, 51, 43, +77, -26, 129, -22, 14, 37, -181, 95, +-125, 97, 127, -2, 135, -110, -91, -113, +-105, -64, 69, -60, 73, -27, -50, 95, +-77, 158, 17, 46, 61, -74, 69, -33, +67, 53, 11, 46, -60, 8, -49, 2, +-89, -23, -103, -127, -2, -195, 80, -118, +69, 61, 28, 232, 52, 259, 95, 105, +13, -84, -150, -109, -131, -25, 37, -45, +123, -151, 42, -93, -21, 137, -48, 205, +-137, -23, -109, -254, 117, -178, 153, 77, +-26, 217, -32, 203, 159, 145, 162, 34, +-105, -117, -274, -213, -124, -226, 77, -154, +110, 44, 64, 234, 19, 185, -25, -35, +-73, -113, -79, 5, 14, 83, 128, 63, +129, 36, 13, 11, -78, -63, -55, -152, +-50, -158, -122, -40, -28, 110, 144, 140, +107, 35, 3, -5, 22, 116, -14, 126, +-141, -132, -115, -309, 85, -99, 187, 218, +54, 229, -55, -13, -44, -214, -125, -213, +-194, -28, 56, 200, 321, 250, 208, 106, +-87, -12, -172, -48, -104, -171, -37, -321, +36, -198, 50, 170, -23, 331, -10, 129, +60, -64, 48, -11, -41, 77, -71, -31, +46, -191, 171, -123, 71, 117, -133, 211, +-165, -1, -12, -268, 28, -241, -141, 35, +-61, 221, 342, 238, 345, 206, -233, 64, +-476, -208, 34, -347, 440, -172, 92, 93, +-296, 134, -149, 44, 143, 49, 168, 130, +-64, 66, -273, -140, -97, -203, 232, 30, +238, 245, -22, 98, -132, -214, -15, -207, +-21, 68, -211, 101, -92, -115, 323, -35, +375, 337, -75, 365, -408, -129, -200, -480, +127, -221, 106, 170, -52, 121, -46, -104, +147, -22, 254, 187, 6, 78, -306, -156, +-218, -48, 95, 256, 235, 253, 72, -58, +-151, -308, -122, -326, 41, -166, 54, 75, +-50, 200, -9, 123, 191, 70, 215, 182, +-149, 205, -409, -63, -131, -333, 282, -194, +223, 112, -129, 76, -216, -195, 58, -183, +211, 141, 45, 287, -135, 98, -22, -33, +155, 88, 52, 129, -215, -147, -249, -411, +-7, -248, 204, 174, 193, 323, 53, 89, +-77, -135, -218, -46, -203, 140, 65, 104, +299, -60, 253, -69, 54, -24, -189, -123, +-307, -231, -165, -59, 53, 266, 154, 330, +144, 78, 43, -168, -112, -188, -171, -58, +-16, 62, 152, 114, 92, 68, -10, -87, +8, -177, -13, -77, -80, 82, -40, 111, +61, 43, -19, 61, -167, 121, -71, -5, +116, -261, 78, -267, -3, 83, -3, 358, +4, 199, 11, -128, -8, -169, -36, -14, +2, -7, 31, -117, 6, -108, -77, 19, +-150, 125, -46, 183, 106, 181, 130, 46, +88, -130, 41, -148, -99, -56, -205, -70, +-89, -160, 127, -76, 97, 167, -74, 272, +-95, 90, -14, -137, 60, -110, 171, 130, +175, 249, -101, 19, -329, -348, -141, -394, +150, -59, 100, 225, -77, 188, -68, 52, +37, 119, 55, 227, 22, 53, 67, -218, +95, -209, -56, -71, -216, -151, -162, -274, +20, -32, 148, 398, 106, 470, -48, 161, +-95, -101, 20, -130, 119, -137, 107, -217, +-50, -192, -231, -34, -232, 85, -56, 69, +60, 59, 87, 143, 188, 203, 224, 116, +85, -49, -137, -157, -270, -184, -188, -142, +57, -28, 125, 39, -72, -17, -160, -52, +42, 138, 186, 380, 52, 272, -122, -136, +-88, -382, 89, -283, 126, -77, 18, 51, +-86, 150, -137, 190, -132, 86, -121, -64, +-121, -46, 135, 95, 476, 132, 271, 15, +-280, -144, -411, -253, -147, -248, -27, -91, +-78, 146, 58, 296, 302, 279, 233, 135, +-50, -48, -141, -162, -13, -109, 19, -21, +-116, -103, -258, -243, -224, -196, 17, 67, +283, 330, 267, 385, -25, 207, -165, -71, +-24, -278, 130, -278, 50, -62, -175, 149, +-293, 81, -182, -186, 29, -205, 205, 162, +229, 429, 113, 191, -8, -224, -107, -257, +-158, 34, -118, 158, -61, -23, -78, -219, +-59, -194, 33, 5, 131, 166, 158, 193, +103, 173, -66, 131, -186, -19, -80, -242, +64, -307, -57, -90, -220, 173, -83, 187, +165, -11, 162, -156, -13, -61, -57, 159, +-10, 230, 7, 59, -3, -156, -90, -155, +-196, 4, -93, 45, 80, -88, 101, -122, +40, 65, 43, 192, 74, 67, 27, -91, +-103, -39, -220, 71, -176, 34, -10, -54, +88, -43, 22, -15, -47, -78, 1, -147, +135, 4, 202, 294, 43, 325, -223, -15, +-261, -317, -133, -207, -87, 57, -21, 44, +150, -125, 260, -63, 99, 172, -149, 205, +-155, 6, 8, -79, 20, 20, -95, 54, +-190, -44, -107, -103, 124, -60, 219, -54, +34, -130, -163, -96, -89, 136, 116, 339, +119, 255, -76, -49, -210, -264, -225, -193, +-90, 28, 140, 106, 206, -44, -2, -185, +-181, -55, -64, 222, 173, 282, 138, 36, +-137, -208, -281, -175, -134, 30, 96, 129, +129, 45, 16, -65, -45, -79, -55, -44, +-64, 3, -64, 64, -65, 99, -21, 49, +62, -54, 63, -93, 3, -1, -43, 122, +-44, 65, -34, -162, -23, -237, 6, 40, +-53, 315, -194, 148, -156, -246, 38, -302, +131, 76, 104, 371, 99, 200, 84, -186, +-45, -317, -247, -81, -268, 202, -23, 171, +167, -104, 14, -211, -259, 1, -144, 182, +246, 62, 336, -123, 20, -37, -273, 184, +-210, 152, 70, -105, 80, -207, -185, -66, +-245, 48, 10, -5, 214, -62, 132, 13, +-66, 132, -102, 133, -3, -1, 2, -104, +-140, -40, -223, 46, -46, -18, 245, -111, +242, -35, -79, 115, -263, 133, -141, 26, +31, -93, 14, -145, -136, -88, -159, 47, +31, 114, 228, 71, 178, 55, -51, 64, +-146, -25, -53, -155, -83, -123, -178, 40, +-58, 83, 46, -29, -87, -78, -159, 52, +65, 162, 293, 79, 201, -82, -89, -107, +-258, -21, -176, 3, 22, -19, 1, -18, +-241, -52, -226, -61, 174, 103, 415, 294, +148, 153, -233, -228, -287, -301, -118, 13, +-29, 198, -22, 1, 6, -208, 42, -91, +34, 146, -22, 171, -36, 65, 29, 51, +74, 58, -57, -53, -309, -161, -334, -124, +4, -77, 260, -83, 143, 22, -43, 194, +10, 187, 140, 37, 19, -6, -247, 19, +-284, -51, -116, -128, -24, -83, -58, -63, +-29, -136, 121, -76, 199, 177, 122, 296, +38, 128, -31, -35, -149, 22, -243, 67, +-286, -149, -272, -388, -110, -264, 175, 97, +376, 229, 331, 51, 115, -28, -113, 219, +-291, 435, -350, 195, -200, -304, -15, -495, +-6, -244, -29, 4, 49, -66, 107, -156, +117, 95, 154, 456, 74, 510, -207, 269, +-345, -71, -155, -410, -1, -587, -54, -353, +-73, 124, 2, 306, 106, 76, 230, -57, +170, 219, -153, 480, -353, 227, -161, -307, +31, -501, -66, -295, -107, -92, 109, -18, +208, 140, 15, 344, -138, 310, -100, 70, +-97, -81, -195, -66, -122, -81, 108, -206, +223, -257, 109, -98, -151, 129, -279, 204, +-85, 100, 142, 34, 95, 163, -122, 243, +-253, -15, -149, -404, 69, -449, 135, -52, +24, 313, -57, 214, 43, -131, 146, -140, +-46, 287, -320, 510, -294, 69, -95, -557, +6, -615, 55, -76, 179, 392, 248, 322, +31, -25, -244, -157, -238, 64, -71, 319, +1, 206, -69, -248, -120, -543, -4, -298, +141, 220, 102, 388, -61, 88, -131, -138, +-4, 30, 53, 212, -181, 28, -335, -266, +-101, -218, 218, 100, 271, 219, 58, -17, +-136, -255, -118, -122, -117, 255, -177, 362, +-40, 48, 125, -268, -15, -248, -277, -56, +-151, 7, 289, -2, 351, 97, -60, 196, +-308, 140, -191, 4, -24, -39, -7, -52, +-102, -202, -136, -333, 9, -144, 179, 291, +143, 474, -70, 159, -141, -237, -1, -224, +-47, 73, -266, 170, -188, -77, 117, -294, +210, -181, 32, 87, -172, 196, -148, 145, +81, 141, 199, 170, 6, 21, -315, -273, +-353, -397, -47, -198, 143, 92, 94, 192, +121, 172, 145, 175, -51, 110, -224, -37, +-178, -49, -65, 51, -52, -85, -115, -439, +-99, -419, 65, 136, 217, 540, 172, 318, +-65, -96, -261, -117, -139, 153, 135, 212, +65, -120, -285, -502, -371, -493, -79, -57, +227, 365, 304, 416, 189, 221, -7, 91, +-235, 88, -337, 7, -168, -219, 61, -417, +48, -409, -156, -148, -181, 202, 149, 396, +415, 354, 212, 190, -194, 59, -371, -14, +-278, -124, -122, -277, -81, -353, -26, -292, +152, -65, 213, 262, 71, 442, -39, 271, +1, -37, 24, -34, -153, 173, -350, 55, +-296, -397, -97, -600, 94, -239, 250, 314, +258, 500, 85, 237, -113, -90, -182, -119, +-111, 95, -99, 174, -188, -49, -186, -368, +-24, -463, 162, -157, 237, 378, 126, 604, +-68, 221, -203, -292, -203, -281, -118, 126, +-23, 239, 55, -125, 5, -449, -148, -305, +-82, 126, 166, 400, 217, 351, 14, 132, +-200, -86, -219, -209, -109, -186, -97, -67, +-123, -12, -15, -95, 118, -111, 215, 97, +217, 314, 10, 281, -257, 49, -338, -158, +-198, -214, 26, -168, 99, -99, -2, -40, +-96, 57, -65, 144, 85, 120, 183, 57, +109, 78, -22, 124, -183, 41, -330, -136, +-293, -279, -58, -297, 155, -125, 190, 190, +73, 361, 2, 209, 16, -53, -14, -70, +-94, 117, -183, 127, -199, -208, -98, -494, +-23, -305, 4, 164, 109, 393, 243, 296, +220, 183, -80, 82, -418, -195, -377, -421, +-37, -242, 171, 97, 123, 125, 1, -44, +-53, 26, -38, 269, 32, 270, 74, -15, +-1, -224, -142, -159, -242, -12, -229, -61, +-63, -212, 168, -135, 312, 226, 202, 469, +-144, 239, -401, -220, -261, -379, 90, -74, +279, 259, 104, 174, -291, -218, -416, -401, +-49, -124, 392, 343, 404, 510, -26, 167, +-393, -318, -287, -398, 25, -20, 63, 266, +-95, 77, -143, -269, -9, -258, 146, 125, +182, 431, 104, 316, -49, -99, -219, -381, +-285, -227, -159, 130, 46, 174, 130, -125, +17, -276, -96, 17, 12, 410, 223, 350, +153, -129, -177, -403, -360, -146, -214, 202, +80, 145, 156, -116, -65, -132, -201, 30, +-11, 59, 249, -3, 224, 51, -42, 152, +-206, 96, -191, -55, -191, -138, -171, -146, +-27, -108, 156, -20, 218, 65, 90, 68, +-73, 46, -25, 134, 56, 266, -68, 152, +-294, -239, -354, -523, -84, -365, 276, 108, +276, 430, 37, 360, -38, 49, -22, -170, +-63, -170, -173, -54, -227, 7, -46, -21, +145, -29, 79, 71, -33, 209, -51, 124, +-42, -224, -67, -476, -76, -225, 55, 401, +195, 752, 57, 381, -246, -394, -356, -845, +-141, -561, 154, 171, 234, 686, 129, 640, +5, 177, -103, -313, -165, -584, -153, -480, +-71, -5, 50, 482, 80, 540, -25, 124, +-96, -379, -8, -583, 140, -319, 116, 353, +-68, 916, -158, 682, -118, -389, -122, -1279, +-161, -967, -60, 320, 197, 1253, 339, 908, +92, -238, -217, -917, -239, -531, -58, 304, +48, 631, 24, 204, -83, -399, -170, -601, +-72, -251, 186, 370, 231, 738, -87, 409, +-308, -347, -75, -727, 308, -310, 279, 402, +-176, 574, -519, 69, -383, -520, 93, -525, +487, 44, 472, 573, 52, 507, -442, -51, +-590, -495, -226, -394, 358, 96, 556, 433, +162, 257, -347, -224, -444, -500, -165, -236, +228, 311, 340, 603, 62, 308, -249, -346, +-270, -679, -82, -285, 83, 439, 138, 623, +120, 32, 29, -527, -101, -312, -113, 289, +-87, 419, -116, -62, -50, -386, 147, -181, +145, 169, -99, 259, -218, 103, -26, -115, +248, -247, 219, -120, -160, 200, -420, 315, +-208, -13, 233, -334, 397, -200, 49, 226, +-422, 308, -395, -118, 99, -430, 540, -92, +373, 565, -303, 583, -715, -232, -318, -971, +405, -614, 621, 539, 134, 1156, -462, 462, +-532, -781, -13, -1071, 555, -66, 481, 961, +-262, 759, -851, -388, -488, -1046, 467, -423, +977, 694, 375, 1015, -657, 148, -926, -864, +-175, -809, 660, 201, 692, 951, -69, 500, +-719, -589, -573, -1025, 126, -239, 601, 915, +429, 1064, -104, -11, -380, -1021, -203, -760, +12, 309, -51, 774, -120, 128, 23, -596, +207, -390, 240, 427, 24, 748, -266, 171, +-280, -587, 53, -664, 309, -25, 60, 511, +-418, 310, -409, -280, 164, -391, 573, 138, +336, 535, -249, 228, -480, -305, -97, -395, +293, -31, 82, 186, -409, -33, -352, -278, +200, -73, 614, 427, 395, 553, -243, 54, +-611, -455, -372, -476, 156, -133, 416, 172, +180, 304, -230, 242, -287, -84, -87, -381, +183, -274, 254, 223, 138, 565, -56, 354, +-270, -222, -283, -627, -12, -414, 191, 215, +110, 550, -83, 113, -184, -570, -39, -516, +240, 421, 356, 1117, 112, 626, -320, -649, +-532, -1307, -333, -649, 124, 485, 414, 848, +383, 261, 151, -265, -123, -32, -358, 351, +-415, 44, -200, -629, 280, -597, 628, 343, +387, 1032, -278, 409, -816, -975, -594, -1443, +155, -125, 737, 1634, 639, 1721, 181, -90, +-288, -1716, -633, -1421, -751, 86, -330, 991, +580, 700, 1205, 166, 758, -6, -596, -130, +-1542, -497, -1004, -637, 704, -25, 1782, 802, +949, 812, -964, -160, -1851, -1015, -722, -725, +1056, 417, 1548, 1098, 454, 586, -832, -532, +-1078, -1004, -347, -424, 457, 442, 658, 624, +273, 160, -256, -193, -443, -77, -265, 82, +66, -90, 309, -251, 351, -26, 120, 321, +-273, 205, -505, -354, -246, -571, 276, 5, +514, 814, 172, 808, -360, -199, -501, -1094, +-58, -785, 508, 452, 497, 1102, -107, 359, +-654, -800, -460, -857, 161, 240, 569, 971, +354, 400, -130, -617, -394, -677, -234, 176, +51, 605, 212, 26, 192, -633, -45, -320, +-316, 549, -311, 651, 146, -198, 584, -721, +371, -45, -327, 843, -741, 425, -353, -891, +481, -1178, 749, 182, 15, 1408, -728, 863, +-493, -681, 418, -1194, 790, -139, 104, 901, +-748, 568, -603, -606, 302, -909, 718, 126, +189, 1063, -520, 556, -469, -643, 165, -846, +486, 60, 79, 574, -299, 94, -208, -356, +132, -59, 188, 356, -15, 112, -182, -316, +-71, -215, 57, 240, 12, 263, 66, -113, +164, -225, 115, 87, -208, 171, -415, -260, +-173, -464, 326, 114, 404, 802, 23, 568, +-265, -445, -179, -1054, 137, -387, 199, 816, +-80, 1101, -379, -80, -205, -1351, 300, -976, +473, 745, 90, 1671, -429, 519, -398, -1244, +144, -1348, 478, 227, 78, 1331, -440, 615, +-346, -916, 272, -1267, 585, -58, 135, 1317, +-566, 1206, -690, -269, 46, -1387, 802, -877, +643, 558, -299, 1150, -907, 356, -435, -752, +546, -903, 778, 9, 77, 870, -682, 726, +-578, -215, 200, -840, 663, -480, 298, 298, +-340, 668, -502, 327, -67, -291, 346, -562, +251, -249, -161, 333, -354, 520, -107, 96, +258, -396, 343, -379, 100, 122, -252, 435, +-401, 129, -220, -425, 318, -421, 631, 274, +92, 772, -690, 270, -709, -749, 175, -919, +967, 74, 652, 1013, -501, 630, -1043, -491, +-365, -794, 694, 41, 796, 654, -118, 188, +-713, -561, -313, -440, 393, 272, 479, 506, +-2, 54, -359, -179, -260, 96, 113, 48, +221, -487, 4, -518, -215, 501, -152, 1034, +113, -12, 335, -1271, 206, -711, -182, 1092, +-369, 1452, -178, -308, 219, -1736, 265, -748, +-57, 1251, -347, 1443, -194, -386, 274, -1491, +512, -436, 148, 1132, -499, 876, -542, -588, +182, -1009, 668, 167, 211, 1070, -603, 241, +-753, -1052, 63, -933, 918, 506, 685, 1327, +-366, 580, -931, -744, -314, -1081, 620, -287, +566, 661, -305, 693, -659, -59, 33, -546, +740, -235, 356, 358, -669, 256, -878, -266, +228, -300, 1220, 314, 674, 615, -823, -65, +-1452, -907, -401, -638, 1072, 527, 1277, 1106, +56, 233, -955, -959, -651, -815, 340, 514, +549, 1249, -95, 231, -576, -1205, -242, -1096, +497, 455, 610, 1349, -29, 321, -603, -1085, +-371, -918, 355, 679, 611, 1512, 6, 377, +-677, -1343, -559, -1504, 212, 126, 766, 1447, +473, 833, -337, -716, -734, -1045, -320, 162, +443, 1064, 708, 414, 198, -704, -498, -708, +-638, 206, -167, 536, 336, -160, 503, -732, +232, -151, -176, 878, -369, 991, -170, -80, +213, -1079, 247, -801, -96, 286, -329, 887, +-85, 388, 254, -448, 317, -697, -17, -254, +-286, 424, -139, 740, 152, 407, 237, -312, +-1, -734, -270, -357, -324, 252, 19, 331, +402, -48, 423, -143, 21, 275, -446, 344, +-441, -209, 72, -607, 462, -54, 226, 763, +-203, 423, -317, -761, -20, -1057, 254, 251, +145, 1390, -134, 568, -120, -1093, 161, -1122, +157, 573, -211, 1403, -353, 36, 1, -1476, +405, -799, 333, 1033, -143, 1350, -356, -233, +-92, -1235, 275, -395, 209, 791, -246, 560, +-404, -425, 42, -504, 464, 205, 302, 382, +-159, -205, -344, -354, -20, 298, 250, 650, +91, -143, -288, -868, -290, -420, 178, 702, +509, 788, 205, -247, -379, -815, -400, -201, +131, 642, 427, 472, -45, -284, -494, -514, +-111, 30, 596, 474, 523, 191, -407, -497, +-821, -629, -26, 52, 905, 931, 539, 846, +-646, -294, -971, -1333, 41, -854, 1017, 800, +645, 1613, -508, 357, -867, -1581, -33, -1624, +755, 535, 470, 2248, -423, 1193, -757, -1399, +-117, -2287, 597, -354, 633, 1867, 33, 1650, +-560, -580, -476, -1945, 158, -835, 641, 1340, +295, 1788, -512, 72, -768, -1659, 44, -1264, +934, 545, 709, 1327, -440, 415, -1008, -735, +-248, -598, 767, 242, 732, 449, -266, -31, +-821, -235, -317, 145, 523, 245, 739, -339, +165, -631, -486, 10, -593, 835, -142, 520, +454, -461, 665, -689, 141, 144, -629, 717, +-768, 127, 103, -767, 1030, -620, 737, 351, +-568, 854, -1219, 239, -270, -599, 1108, -514, +1109, 317, -363, 795, -1422, 127, -670, -908, +1035, -982, 1418, 253, 53, 1343, -1277, 882, +-906, -722, 511, -1460, 1115, -344, 279, 1224, +-718, 1213, -613, -403, 164, -1481, 562, -682, +239, 927, -69, 1294, -58, 172, -143, -939, +-405, -856, -208, 23, 512, 643, 747, 551, +-22, 136, -896, -364, -518, -642, 735, -427, +1124, 424, -43, 1068, -1250, 439, -817, -961, +678, -1317, 1190, 112, 122, 1570, -910, 994, +-510, -968, 671, -1691, 767, -131, -273, 1583, +-844, 1078, -130, -881, 730, -1560, 547, 9, +-389, 1489, -751, 888, -72, -956, 729, -1443, +689, -10, -153, 1333, -755, 904, -512, -612, +355, -1190, 744, -252, 274, 900, -521, 826, +-578, -319, 213, -987, 851, -362, 362, 734, +-676, 798, -880, -184, 50, -776, 965, -372, +599, 442, -446, 509, -759, 120, 47, -284, +764, -397, 409, -270, -518, 235, -691, 681, +96, 353, 769, -657, 371, -943, -575, 94, +-656, 1122, 287, 561, 985, -829, 397, -908, +-612, 384, -804, 1059, -75, -82, 581, -1083, +483, -363, -66, 1057, -403, 827, -153, -744, +266, -1281, 498, 105, 192, 1460, -386, 873, +-695, -829, -169, -1521, 728, -465, 823, 981, +-171, 1290, -1003, 224, -349, -999, 944, -1031, +1146, 245, -356, 1263, -1491, 629, -726, -1009, +1051, -1480, 1452, -29, 83, 1518, -1068, 1156, +-729, -514, 363, -1342, 756, -459, 296, 697, +-281, 804, -341, 93, -170, -518, 61, -612, +238, -285, 276, 357, 182, 807, -112, 495, +-166, -480, -10, -939, 141, -234, 27, 823, +-168, 787, -156, -393, 154, -1192, 373, -439, +320, 960, -1, 1214, -383, -43, -346, -1134, +33, -736, 508, 557, 419, 970, -171, 85, +-660, -959, -297, -837, 598, 404, 926, 1214, +136, 639, -766, -854, -764, -1246, 157, 35, +858, 1431, 464, 818, -413, -1132, -732, -1706, +12, 116, 824, 1898, 627, 1098, -331, -1192, +-740, -1680, -175, 263, 411, 1740, 322, 622, +-130, -1468, -24, -1383, 315, 589, 120, 1678, +-449, 325, -260, -1253, 578, -954, 751, 695, +-185, 1197, -1106, 62, -578, -1014, 719, -724, +1268, 311, 304, 695, -864, 238, -885, -255, +260, -341, 993, -2, 534, 352, -585, 391, +-887, -176, -166, -701, 667, -412, 667, 429, +35, 634, -400, -52, -235, -371, 304, 140, +501, 459, 52, -175, -715, -736, -699, -261, +248, 657, 1269, 540, 850, -242, -625, -610, +-1498, -81, -456, 432, 1390, 390, 1609, 18, +-205, -317, -1907, -430, -1167, -181, 1083, 412, +1929, 516, 362, -80, -1413, -701, -1104, -221, +598, 694, 1360, 726, 257, -366, -1044, -969, +-875, -273, 460, 749, 1154, 645, 430, -364, +-679, -819, -760, -91, 162, 819, 796, 745, +374, -280, -445, -1080, -578, -561, -66, 629, +475, 1092, 536, 125, 247, -1054, -259, -813, +-521, 543, -192, 1200, 513, 269, 601, -946, +-152, -806, -819, 325, -337, 735, 790, 34, +1116, -509, 10, -134, -1058, 348, -791, 215, +471, -161, 1033, -17, 397, 179, -620, -116, +-793, -453, 18, -227, 857, 425, 763, 574, +-135, -74, -850, -602, -625, -288, 415, 579, +958, 766, 412, -198, -634, -1175, -804, -679, +102, 898, 957, 1366, 638, -27, -387, -1573, +-830, -800, -228, 1185, 569, 1578, 625, -276, +-38, -1779, -451, -811, -279, 1063, 305, 1297, +676, -159, 276, -1033, -477, -341, -807, 565, +-46, 498, 820, -196, 728, -292, -282, -14, +-802, 11, -64, -172, 858, -81, 612, 396, +-495, 418, -942, -203, -107, -653, 816, -159, +631, 647, -278, 617, -525, -385, 91, -965, +652, -307, 272, 786, -385, 886, -503, -77, +-90, -927, 387, -519, 369, 534, 115, 868, +-170, -3, -170, -903, 144, -612, 426, 467, +164, 846, -364, 120, -393, -569, 148, -308, +461, 361, 10, 360, -413, -354, -35, -641, +646, -13, 645, 804, -172, 575, -689, -506, +-437, -948, 371, 16, 577, 1105, 18, 590, +-514, -940, -221, -1270, 696, 278, 876, 1459, +-107, 649, -1044, -1054, -609, -1154, 702, 273, +1021, 1259, -8, 522, -1037, -871, -494, -1214, +854, -128, 1186, 1278, 6, 1309, -1170, -328, +-771, -1917, 679, -1158, 1236, 1353, 213, 2358, +-1041, 219, -924, -2406, 366, -1848, 1252, 1091, +715, 2406, -457, 557, -1015, -1711, -361, -1448, +603, 441, 868, 1429, 175, 610, -784, -566, +-767, -996, 238, -483, 1297, 381, 942, 889, +-588, 480, -1637, -511, -557, -904, 1237, -7, +1586, 935, -154, 619, -1589, -637, -951, -1144, +991, -188, 1837, 908, 438, 892, -1401, -53, +-1474, -725, 245, -545, 1581, 158, 917, 578, +-949, 296, -1439, -346, 32, -588, 1757, -2, +1252, 624, -876, 319, -1824, -469, -450, -585, +1475, 295, 1368, 822, -339, 152, -1516, -754, +-684, -662, 987, 163, 1583, 574, 492, 394, +-1117, 63, -1492, -253, -221, -649, 1354, -511, +1363, 650, -211, 1320, -1482, 233, -807, -1633, +922, -1474, 1463, 910, 359, 2209, -1048, 520, +-934, -1882, 134, -1618, 802, 703, 347, 1767, +-257, 407, -231, -1119, 279, -784, 229, 363, +-265, 621, -292, -69, 352, -351, 750, 119, +29, 270, -915, -209, -765, -465, 496, 79, +1286, 712, 591, 360, -689, -471, -1048, -720, +-192, 32, 855, 497, 833, 196, -11, -367, +-869, -186, -659, 442, 377, 407, 1103, -295, +575, -687, -538, -76, -994, 737, -236, 587, +760, -512, 814, -1104, -77, -311, -787, 1046, +-429, 1237, 576, -112, 1020, -1354, 209, -894, +-944, 720, -1054, 1291, 269, 151, 1438, -1224, +907, -811, -866, 596, -1534, 1057, -114, 17, +1590, -780, 1237, -293, -757, 622, -1634, 469, +-288, -371, 1417, -706, 1160, -177, -456, 405, +-1373, 394, -357, 84, 940, -105, 1073, -106, +-106, -99, -850, 74, -413, 194, 452, 11, +579, -437, 20, -534, -366, 66, -169, 763, +224, 750, 280, 6, 38, -778, -115, -818, +-32, -34, 99, 853, 109, 735, -29, -303, +13, -1165, 39, -469, 49, 942, -7, 1312, +133, 11, 96, -1248, -34, -993, -238, 348, +-24, 983, 363, 419, 450, -395, -7, -533, +-488, -84, -397, 254, 213, 242, 659, 137, +349, 103, -297, -232, -745, -575, -238, -425, +593, 579, 1036, 1112, 364, 149, -716, -1293, +-1139, -1004, -274, 928, 919, 1692, 1171, -52, +-14, -1953, -1046, -998, -678, 1408, 588, 1732, +1017, -434, 188, -1840, -625, -467, -523, 1413, +98, 1140, 426, -605, 231, -1331, 12, -260, +-62, 861, -77, 715, -117, -263, 74, -717, +330, -166, 321, 560, -153, 623, -530, -219, +-265, -769, 330, -359, 747, 540, 362, 604, +-418, -295, -794, -725, -168, 94, 691, 1008, +884, 457, 0, -909, -807, -1089, -727, 373, +273, 1255, 887, 124, 563, -1333, -227, -706, +-638, 1227, -388, 1539, 185, -440, 676, -1777, +503, -624, -241, 1234, -799, 1159, -310, -510, +677, -1266, 839, -363, -107, 882, -810, 1027, +-277, 304, 671, -721, 624, -1119, -330, -457, +-759, 908, -68, 1249, 743, -92, 547, -1490, +-252, -822, -524, 1090, -54, 1637, 453, -14, +182, -1556, -171, -1074, -230, 646, 101, 1221, +176, 247, 90, -861, -11, -671, 171, 297, +195, 746, -48, 313, -367, -335, -305, -437, +229, -252, 553, 9, 277, 218, -388, 389, +-416, 102, 134, -370, 668, -322, 429, 375, +-445, 566, -905, -308, -242, -969, 897, -107, +992, 1209, -170, 787, -1103, -1062, -450, -1598, +856, 358, 986, 2121, -161, 1040, -1009, -1703, +-357, -2297, 664, 172, 593, 2435, -294, 1512, +-531, -1439, 226, -2381, 686, -253, 187, 2304, +-507, 1825, -496, -904, 177, -2523, 428, -977, +135, 1641, -268, 2020, -60, -95, 298, -1833, +325, -1031, -25, 1023, -287, 1593, -210, 91, +6, -1462, 198, -1130, 121, 497, 141, 1428, +6, 563, 9, -907, -62, -1186, -21, 31, +146, 1258, 163, 936, -50, -457, -245, -1335, +-142, -660, 125, 567, 179, 1051, 184, 388, +198, -451, 218, -702, -240, -236, -489, 410, +-290, 653, 583, 192, 688, -557, -39, -795, +-836, -77, -485, 737, 640, 690, 980, -235, +228, -817, -808, -188, -685, 641, 147, 630, +765, -378, 268, -696, -377, -147, -536, 537, +156, 181, 551, -394, 380, -171, -223, 486, +-302, 473, 58, -258, 262, -532, -176, -31, +-534, 184, -129, -176, 707, -227, 968, 495, +24, 730, -1048, -243, -921, -1158, 455, -403, +1415, 1173, 651, 1188, -1038, -560, -1551, -1774, +-134, -616, 1567, 1447, 1453, 1591, -272, -285, +-1622, -1689, -906, -780, 827, 1042, 1457, 1263, +236, -151, -1079, -1213, -1150, -497, 331, 646, +1269, 792, 814, -200, -639, -617, -1004, -115, +-100, 637, 819, 352, 469, -529, -414, -828, +-606, 134, -40, 1050, 455, 502, 457, -886, +214, -1069, -96, 473, -349, 1430, -492, 262, +-29, -1488, 614, -1103, 569, 950, -269, 1712, +-845, 9, -227, -1644, 872, -944, 943, 999, +-133, 1433, -1029, -127, -655, -1364, 455, -732, +901, 904, 233, 1303, -663, 6, -680, -1452, +364, -1023, 1138, 843, 490, 1879, -867, 383, +-1301, -1923, -40, -1880, 1308, 722, 1066, 2666, +-486, 1202, -1410, -1793, -486, -2538, 1034, -98, +1399, 2198, 151, 1743, -1274, -729, -1247, -2081, +232, -1055, 1424, 1069, 1067, 1963, -589, 828, +-1585, -1304, -694, -2064, 1205, -540, 1851, 1734, +323, 2033, -1767, -137, -1755, -2199, 368, -1594, +2137, 861, 1261, 2267, -1163, 1065, -2038, -1267, +-328, -2040, 1961, -495, 1694, 1547, -592, 1689, +-2235, -314, -964, -1999, 1402, -1030, 2039, 1318, +90, 2047, -1802, 86, -1366, -1911, 762, -1233, +1992, 895, 842, 1563, -1259, 21, -1958, -1405, +-371, -843, 1626, 781, 1808, 1374, -8, 436, +-1723, -897, -1464, -1238, 524, -288, 1922, 963, +1154, 1082, -1007, -97, -2038, -1254, -684, -809, +1542, 694, 1916, 1340, 192, 396, -1685, -766, +-1461, -934, 409, -227, 1748, 193, 869, 370, +-884, 507, -1398, 389, -179, -336, 1077, -905, +845, -357, -221, 865, -757, 1000, -258, -346, +367, -1325, 509, -502, 10, 1081, -256, 1174, +-317, -290, -69, -1313, 199, -516, 386, 756, +213, 1028, -94, 21, -214, -779, -110, -595, +11, 161, 5, 604, 58, 131, 137, -402, +106, -344, -19, 396, -106, 716, 116, -2, +222, -789, 57, -803, -392, 228, -312, 886, +193, 686, 565, -327, 241, -928, -341, -520, +-421, 638, 73, 1105, 455, 66, 210, -1274, +-165, -988, -322, 840, -43, 1651, 121, 169, +131, -1764, 134, -1231, 228, 1042, -8, 2056, +-291, 267, -340, -1927, 90, -1725, 531, 649, +290, 2224, -244, 1154, -517, -1276, -70, -2237, +497, -418, 412, 1894, -154, 1943, -528, -623, +-82, -2502, 477, -1118, 482, 1912, -219, 2530, +-675, -206, -261, -2745, 436, -1705, 708, 1424, +261, 2534, -288, 504, -627, -1717, -358, -1690, +228, 85, 691, 1304, 460, 1194, -331, 171, +-781, -1099, -244, -1459, 720, -296, 843, 1550, +-131, 1711, -945, -303, -534, -2167, 529, -1239, +930, 1272, 188, 2212, -771, 309, -693, -1877, +293, -1693, 1002, 560, 482, 1929, -744, 945, +-959, -1058, 32, -1713, 1082, -315, 643, 1287, +-578, 1368, -1020, -56, -58, -1367, 1025, -1007, +748, 417, -319, 1276, -958, 601, -371, -789, +475, -1105, 667, -165, 248, 962, -384, 902, +-526, -62, -132, -880, 532, -708, 639, 76, +61, 632, -646, 593, -649, 42, 106, -471, +711, -592, 545, -223, -199, 484, -630, 791, +-296, 269, 434, -622, 762, -918, 223, -54, +-665, 805, -1044, 616, -164, -453, 1131, -884, +1325, -68, -21, 997, -1465, 908, -1261, -417, +608, -1325, 1837, -805, 861, 766, -1254, 1418, +-1959, 310, -224, -1203, 1827, -1109, 1676, 522, +-314, 1609, -1792, 441, -1079, -1280, 746, -1366, +1502, 311, 523, 1426, -820, 583, -1118, -850, +-262, -1014, 810, 124, 1012, 922, 306, 597, +-686, -317, -883, -614, -173, -294, 629, 19, +703, 75, -12, 69, -552, 395, -392, 527, +291, 10, 572, -862, 192, -861, -347, 291, +-496, 1334, -23, 778, 449, -963, 480, -1595, +-209, -345, -556, 1393, -219, 1500, 634, -49, +624, -1290, -103, -1143, -769, 30, -390, 963, +415, 1033, 629, 174, 7, -914, -547, -1273, +-158, -259, 364, 1289, 505, 1503, 29, 103, +-422, -1541, -493, -1488, -115, 71, 512, 1398, +720, 1202, 89, -3, -699, -1020, -705, -933, +266, -202, 949, 671, 479, 857, -610, 362, +-882, -476, 3, -753, 734, -391, 521, 205, +-214, 505, -380, 466, -253, 220, 136, -283, +319, -762, 405, -548, -25, 351, -567, 1113, +-552, 615, 254, -719, 954, -1368, 402, -346, +-589, 1199, -790, 1513, 161, -122, 641, -1753, +291, -1421, -373, 720, -179, 2138, 175, 1001, +93, -1376, -361, -2087, -220, -202, 481, 1817, +874, 1504, 39, -711, -908, -1844, -790, -512, +238, 1256, 873, 1229, 503, -370, -289, -1162, +-637, -241, -161, 781, 337, 565, 451, -464, +88, -751, -328, -3, -288, 631, 28, 500, +198, -252, 90, -508, -130, -220, 38, 406, +347, 444, 157, -118, -285, -633, -406, -365, +106, 518, 339, 785, -40, -42, -328, -857, +49, -514, 619, 700, 302, 1028, -569, -96, +-647, -1272, 275, -903, 830, 686, 220, 1401, +-724, 436, -617, -1066, 226, -987, 764, 304, +435, 1130, -223, 265, -516, -945, -232, -844, +192, 381, 308, 1111, 134, 280, -204, -725, +-165, -720, 7, 301, 315, 716, 206, 102, +-116, -548, -238, -278, -63, 361, 122, 160, +193, -461, -96, -329, -265, 696, -140, 1003, +397, -177, 625, -1342, 89, -860, -741, 725, +-870, 1346, 210, 216, 1148, -987, 727, -848, +-729, 300, -1362, 877, -152, 431, 1354, -330, +1232, -583, -561, -447, -1673, -60, -577, 426, +1195, 866, 1492, 417, -280, -670, -1560, -1416, +-842, -490, 1073, 1340, 1582, 1823, 269, 277, +-1483, -1966, -1421, -2120, 221, 16, 1713, 2262, +1261, 2214, -678, -120, -1884, -2273, -892, -2076, +1282, 166, 1955, 2059, 424, 1727, -1597, -188, +-1732, -1605, -5, -1339, 1713, 14, 1482, 999, +-295, 1199, -1607, 459, -1213, -588, 587, -1341, +1808, -921, 900, 536, -985, 1490, -1869, 943, +-422, -590, 1574, -1345, 1633, -624, -311, 498, +-1814, 949, -995, 441, 1017, -247, 1687, -646, +250, -537, -1379, 65, -1141, 507, 425, 650, +1193, 19, 427, -403, -706, -440, -719, -126, +217, 78, 721, 140, 213, 319, -548, 358, +-518, -79, 94, -603, 615, -523, 165, 276, +-325, 752, -387, 416, 303, -296, 550, -647, +-66, -473, -789, -152, -555, 491, 657, 995, +1161, 732, 360, -613, -1153, -1609, -1349, -886, +-172, 948, 1563, 1780, 1641, 583, 134, -1131, +-1786, -1474, -1981, -282, -249, 955, 2048, 1117, +2427, 284, 306, -574, -2294, -878, -2626, -505, +-102, 178, 2618, 677, 2486, 740, -222, 257, +-2656, -486, -2123, -1074, 585, -680, 2484, 502, +1671, 1557, -736, 904, -1975, -834, -1158, -1905, +612, -831, 1402, 1170, 773, 1903, -361, 653, +-852, -1189, -646, -1693, -39, -618, 584, 1042, +867, 1658, 486, 719, -575, -1101, -1371, -1951, +-787, -745, 834, 1549, 1843, 2318, 801, 506, +-1298, -2149, -2110, -2465, -433, 22, 1797, 2591, +2008, 2208, -163, -621, -2079, -2658, -1520, -1715, +734, 950, 1913, 2336, 827, 1330, -912, -715, +-1325, -1804, -319, -1371, 746, 59, 742, 1294, +134, 1708, -433, 619, -373, -971, -159, -1902, +242, -1058, 340, 746, 282, 1747, -97, 1208, +-451, -401, -263, -1446, 161, -1253, 428, -1, +145, 1102, -165, 1225, -374, 302, -47, -780, +192, -943, 524, -261, 293, 365, -429, 328, +-950, -55, -460, 86, 908, 500, 1371, 380, +184, -529, -1482, -1168, -1393, -521, 441, 853, +1881, 1588, 987, 519, -1035, -1184, -1912, -1811, +-379, -472, 1428, 1596, 1394, 1992, -390, 165, +-1412, -2039, -551, -1968, 1077, 513, 1046, 2378, +-472, 1497, -1275, -1322, -419, -2470, 1047, -783, +1038, 1846, -138, 2249, -1004, 271, -630, -1952, +140, -1925, 678, -3, 605, 1895, 299, 1627, +-395, -257, -1080, -1926, -853, -1318, 359, 687, +1653, 1867, 1398, 911, -375, -966, -1981, -1566, +-1746, -533, 290, 838, 2155, 1120, 2027, 492, +-91, -332, -2345, -940, -2331, -938, -41, -179, +2526, 1194, 2663, 1763, 150, 418, -2624, -1811, +-2742, -2439, -237, -289, 2288, 2355, 2638, 2592, +534, -34, -1827, -2401, -2593, -2167, -1086, 126, +1428, 1868, 2743, 1686, 1585, 179, -1308, -1125, +-2977, -1563, -1732, -726, 1298, 741, 2840, 1651, +1538, 1056, -1103, -638, -2392, -1658, -1435, -1062, +551, 450, 1891, 1368, 1456, 1078, 79, -40, +-1465, -966, -1746, -1209, -511, -489, 1357, 738, +1924, 1457, 642, 796, -1341, -796, -2047, -1791, +-553, -882, 1575, 1194, 2021, 2199, 114, 821, +-1996, -1760, -1614, -2577, 801, -691, 2272, 2286, +831, 2763, -1658, 415, -2075, -2512, 106, -2715, +2048, -118, 1544, 2466, -664, 2485, -1887, 46, +-1096, -2158, 684, -2245, 1632, -269, 1002, 1657, +-488, 1945, -1466, 567, -1048, -1021, 362, -1519, +1446, -647, 1035, 443, -525, 918, -1598, 531, +-903, -69, 847, -256, 1670, -336, 578, -196, +-1199, -338, -1697, 38, -269, 456, 1458, 854, +1561, 384, -107, -570, -1595, -1329, -1480, -858, +338, 494, 1535, 1596, 1081, 1239, -574, -233, +-1328, -1612, -491, -1401, 656, 49, 719, 1414, +4, 1468, -355, 37, -202, -1313, -22, -1500, +22, -138, 56, 1359, 219, 1652, -39, 208, +-340, -1488, -190, -1774, 566, -193, 796, 1667, +-103, 1784, -1153, -84, -1044, -1918, 297, -1631, +1554, 544, 1457, 2204, -169, 1384, -1840, -955, +-2020, -2358, -64, -1166, 2250, 1055, 2613, 2291, +349, 1204, -2580, -882, -3067, -2255, -635, -1502, +2608, 595, 3484, 2501, 1168, 1995, -2367, -435, +-3998, -2809, -1962, -2553, 2053, 245, 4409, 2990, +2523, 3010, -1867, 175, -4554, -2888, -2759, -3310, +1653, -669, 4177, 2546, 2546, 3366, -1332, 1026, +-3580, -2133, -2181, -3180, 868, -1190, 2567, 1700, +1550, 2820, -665, 1251, -1387, -1237, -643, -2251, +476, -1286, -22, 590, -632, 1482, -148, 1244, +1521, 265, 1697, -596, -532, -1188, -3036, -1018, +-2260, -167, 1443, 1091, 4080, 1405, 2229, 609, +-2237, -849, -4318, -1448, -1811, -868, 2513, 448, +4013, 1363, 1507, 1211, -2148, -35, -3449, -1383, +-1469, -1620, 1519, -246, 2962, 1561, 1815, 1944, +-824, 237, -2584, -1822, -2158, -1993, 321, -12, +2458, 2015, 2406, 1750, -11, -300, -2281, -1800, +-2366, -1236, -236, 285, 2037, 961, 2125, 604, +414, 370, -1497, 468, -1970, -260, -858, -1617, +919, -1799, 1935, 326, 1293, 2784, -499, 2461, +-1893, -610, -1719, -3076, 100, -2382, 1577, 539, +1630, 2506, 253, 1995, -1136, -19, -1554, -1616, +-657, -1734, 632, -509, 1431, 976, 781, 1522, +-578, 644, -1394, -624, -502, -1042, 756, -302, +980, 268, -282, 233, -1036, -282, -288, -22, +1227, 654, 1063, 911, -591, 127, -1791, -1209, +-862, -1719, 1121, -531, 1881, 1547, 730, 2478, +-1072, 1008, -1626, -1851, -808, -3043, 666, -1200, +1332, 1943, 1061, 3262, 34, 1471, -1009, -1643, +-1304, -3289, -573, -2068, 771, 1007, 1618, 3417, +1067, 2823, -579, -575, -1936, -3697, -1372, -3241, +695, 613, 2160, 4014, 1386, 3214, -834, -912, +-2233, -4137, -1194, -3126, 1074, 1031, 2065, 4132, +854, 3255, -1235, -893, -2032, -4178, -629, -3450, +1302, 838, 1905, 4337, 586, 3424, -1346, -1053, +-2033, -4305, -730, -3068, 1139, 1230, 1856, 3782, +839, 2439, -765, -913, -1571, -2619, -1041, -1780, +208, 137, 947, 1192, 848, 1267, 371, 762, +-255, -92, -549, -914, -834, -1233, -710, -632, +-44, 583, 1126, 1241, 1679, 1152, 765, 126, +-1271, -1172, -2499, -1734, -1450, -922, 1105, 1108, +2973, 2349, 2109, 1476, -760, -1005, -3102, -2539, +-2465, -1754, 371, 651, 2899, 2352, 2722, 2001, +95, -50, -2480, -2054, -2599, -2397, -517, -477, +1779, 1921, 2394, 2648, 1054, 783, -927, -1814, +-2071, -2520, -1585, -899, 93, 1473, 1881, 2280, +2046, 1055, 339, -1080, -1736, -2182, -2140, -1255, +-521, 1015, 1473, 2292, 1845, 1233, 532, -1233, +-1083, -2246, -1670, -931, -823, 1384, 864, 2018, +1812, 694, 787, -1055, -1375, -1804, -2246, -1002, +-435, 501, 2242, 1862, 2522, 1806, -410, 106, +-3163, -2097, -2570, -2578, 960, -682, 3328, 2052, +2364, 3045, -991, 1425, -3114, -1517, -2209, -3162, +601, -2234, 2442, 713, 1977, 3076, -163, 2828, +-1842, 1, -1619, -2656, -106, -2853, 1129, -498, +994, 1897, 177, 2361, -350, 918, -314, -819, +-125, -1608, -223, -1274, -413, -245, -59, 839, +611, 1479, 1034, 1092, 413, -96, -837, -1369, +-1528, -1581, -775, -571, 1035, 1092, 2041, 1833, +960, 1091, -1344, -792, -2422, -1905, -983, -1332, +1618, 624, 2702, 1830, 879, 1290, -2000, -466, +-2783, -1458, -698, -988, 2128, 248, 2721, 847, +457, 579, -2341, 73, -2671, -99, -315, -197, +2337, -433, 2605, -479, 113, 71, -2514, 941, +-2497, 840, -36, -393, 2209, -1532, 2161, -904, +161, 1197, -1679, 2247, -2004, 622, -749, -2217, +841, -2770, 1771, 3, 1370, 3164, -214, 2926, +-1570, -592, -1825, -3474, -511, -2718, 1044, 739, +1873, 3085, 1118, 2440, -424, -254, -1778, -2219, +-1632, -2175, -170, -424, 1450, 1387, 1598, 1878, +535, 895, -947, -624, -1226, -1356, -648, -934, +234, -99, 516, 572, 517, 825, 425, 816, +324, 409, -218, -525, -1001, -1301, -1207, -1280, +-311, -13, 1176, 1434, 1922, 2065, 1073, 927, +-1166, -1219, -2679, -2714, -1905, -1952, 968, 849, +3256, 3305, 2523, 2903, -1032, -400, -3723, -3573, +-2623, -3500, 999, -39, 3508, 3436, 2224, 3668, +-1074, 507, -2868, -2812, -1616, -3398, 735, -908, +1709, 2081, 874, 2887, -266, 1215, -663, -1348, +-512, -2157, -380, -1167, -209, 578, 169, 1320, +623, 976, 562, 248, -266, -413, -777, -783, +-359, -719, 412, -39, 382, 672, -316, 682, +-723, -117, -27, -581, 1000, -13, 830, 766, +-549, 487, -1470, -759, -780, -1450, 625, -299, +1362, 1405, 665, 1847, -437, 352, -1065, -1555, +-762, -1946, -98, -609, 552, 1173, 752, 1857, +586, 1132, 7, -337, -794, -1443, -1216, -1470, +-607, -524, 632, 781, 1460, 1425, 1013, 1029, +-563, 86, -1668, -763, -1131, -968, 352, -666, +1290, -196, 889, 375, -215, 939, -860, 1290, +-636, 732, -58, -859, 36, -2340, -3, -1848, +371, 711, 655, 3154, 248, 2707, -811, -435, +-1263, -3286, -366, -2958, 984, 62, 1146, 2833, +-44, 2741, -1144, 387, -812, -1941, 504, -2064, +957, -531, 5, 976, -1114, 1133, -865, 458, +614, 4, 1520, -78, 553, -278, -1246, -745, +-1887, -571, -438, 297, 1312, 1173, 1619, 676, +227, -439, -1101, -990, -1182, -166, -190, 741, +459, 524, 332, -626, -57, -1041, 34, 89, +393, 1558, 247, 1417, -543, -604, -1282, -2301, +-742, -1607, 747, 1020, 1882, 2754, 1012, 1723, +-1072, -1145, -2381, -2775, -1258, -1681, 1080, 1176, +2204, 2715, 1023, 1533, -1002, -1229, -1806, -2504, +-878, -1122, 520, 1540, 976, 2240, 391, 564, +-312, -1659, -381, -1767, 56, 0, 125, 1627, +-447, 1239, -902, -249, -375, -1322, 952, -804, +1760, 412, 452, 1158, -1787, 594, -2716, -440, +-762, -1082, 2215, -464, 3218, 622, 825, 1071, +-2639, 429, -3620, -705, -1095, -1008, 2485, -246, +3561, 918, 1092, 982, -2485, 36, -3435, -1126, +-1056, -786, 2130, 450, 2729, 1251, 465, 413, +-1910, -939, -1934, -1046, 11, 281, 1425, 1377, +944, 726, -545, -784, -1214, -1494, -589, -452, +463, 879, 856, 1406, 520, 679, -366, -377, +-913, -1225, -939, -1130, -37, -137, 760, 1267, +1014, 1527, 293, 358, -828, -1135, -1417, -1357, +-778, -250, 584, 794, 1375, 842, 881, 324, +-502, -34, -1567, -181, -1073, -452, 308, -672, +1252, -259, 687, 596, -628, 1059, -1205, 583, +-210, -355, 918, -793, 716, -586, -832, -70, +-1462, 215, -339, 390, 1431, 630, 1565, 648, +-358, 86, -2218, -1022, -1662, -1487, 730, -572, +2247, 1414, 1496, 2367, -933, 1208, -2415, -1483, +-1660, -3146, 475, -1902, 1954, 1368, 1645, 3805, +78, 2771, -1514, -913, -1855, -3963, -1107, -3355, +554, 259, 1653, 3665, 1697, 3758, 231, 638, +-1279, -2816, -2221, -3744, -1392, -1402, 266, 1763, +1794, 3355, 2135, 2011, 797, -378, -1395, -2286, +-2825, -2285, -1970, -966, 586, 1027, 2699, 2470, +2288, 2198, -357, -26, -2449, -2416, -2103, -2625, +82, -188, 1482, 2279, 914, 2156, -357, -32, +-698, -1661, 123, -935, 411, 510, -228, 846, +-1158, -299, -989, -863, 302, -51, 1469, 1328, +1178, 1327, -228, -235, -1572, -1746, -1692, -1697, +-495, 87, 1124, 1773, 1622, 1978, 733, 440, +-745, -1356, -1483, -1915, -1071, -759, -48, 813, +645, 1606, 692, 956, 596, -63, 262, -885, +-569, -903, -1477, -639, -1376, 42, 73, 799, +1768, 1402, 1910, 941, 202, -486, -1897, -1882, +-2542, -1617, -943, 328, 1492, 2089, 2482, 1906, +1252, -80, -1085, -1734, -2419, -1703, -1787, -184, +338, 1068, 1736, 1486, 1751, 841, 161, -137, +-1387, -1254, -1914, -1540, -825, -598, 903, 1207, +1601, 2014, 716, 1005, -898, -925, -1440, -1705, +-476, -802, 535, 557, 610, 880, -214, 322, +-645, -96, -77, 196, 501, 424, 446, -119, +-305, -845, -980, -860, -1122, 150, -37, 935, +1035, 918, 1438, 251, 423, -152, -1238, -527, +-2122, -810, -1114, -981, 797, -9, 2082, 1443, +1514, 2199, -484, 833, -2149, -1565, -2096, -2979, +-269, -1687, 1653, 1296, 2087, 3234, 485, 2431, +-1358, -577, -1917, -2695, -773, -2399, 686, -86, +1139, 1565, 344, 1665, -473, 719, -463, 61, +-69, -395, 72, -1084, -356, -1385, -504, -563, +-206, 1157, 393, 2012, 629, 1168, 443, -583, +-252, -1532, -1069, -1333, -1359, -399, -365, 500, +1089, 1325, 1715, 1635, 690, 791, -986, -1031, +-1945, -2402, -1312, -1690, 122, 686, 1252, 2570, +1406, 2055, 575, -177, -580, -1984, -1442, -1674, +-1420, -42, -707, 1187, 817, 1013, 1755, -15, +1295, -463, -497, -234, -1991, 378, -1846, 340, +70, -59, 1571, -622, 1258, -595, -141, -118, +-1139, 697, -805, 1176, 89, 805, 458, -338, +-80, -1560, -526, -1500, -326, -92, 301, 1724, +692, 2020, 233, 581, -570, -1388, -959, -1938, +-666, -874, 141, 811, 647, 1531, 735, 1024, +349, 1, -346, -726, -1081, -774, -1268, -568, +-359, -177, 991, 371, 1689, 1024, 713, 1093, +-1006, 189, -1933, -1107, -1285, -1645, 400, -616, +1659, 1138, 1488, 1962, 4, 1052, -1605, -1016, +-1890, -2078, -583, -1165, 1170, 981, 1875, 2186, +859, 1260, -1126, -903, -2226, -2119, -1221, -1164, +786, 842, 2094, 2072, 1339, 1310, -743, -555, +-2173, -1868, -1750, -1635, 161, 106, 1656, 1833, +1868, 2163, 344, 537, -1328, -1614, -2076, -2390, +-1257, -919, 463, 1254, 1793, 2170, 1674, 1097, +19, -561, -1660, -1366, -2116, -900, -515, -50, +1357, 551, 1636, 597, 154, 389, -1170, 86, +-1074, -3, 223, -7, 762, -286, -135, -706, +-882, -712, -575, 316, 665, 1434, 1130, 1518, +491, 3, -988, -1557, -1596, -1941, -806, -567, +650, 1122, 1485, 2010, 1019, 1363, -345, -126, +-1510, -1516, -1402, -1877, -216, -950, 1119, 687, +1430, 2088, 561, 2061, -805, 467, -1681, -1896, +-1495, -2875, 214, -1447, 1808, 1618, 2064, 3425, +190, 2162, -2053, -1157, -2518, -3271, -752, -2408, +1463, 549, 2109, 2518, 1019, 2402, -530, 503, +-1451, -1175, -1605, -2116, -1008, -1635, 337, -192, +1792, 1747, 2114, 2653, 505, 1351, -1923, -1205, +-2882, -2926, -1475, -2011, 1208, 614, 2672, 2596, +1895, 2295, -292, 217, -2087, -1772, -2315, -2181, +-783, -926, 974, 908, 1819, 1868, 1228, 1495, +-57, 18, -1169, -1319, -1307, -1649, -815, -729, +-67, 824, 798, 1696, 1149, 1118, 685, -450, +-281, -1527, -1148, -1012, -1125, 495, -289, 1417, +606, 650, 661, -749, 259, -1304, -1, -190, +-14, 1261, -82, 1433, -657, -61, -993, -1695, +-491, -1668, 763, 121, 1433, 2026, 995, 2106, +-548, 213, -1734, -1984, -1666, -2514, -183, -838, +1474, 1751, 1922, 2880, 737, 1623, -1201, -1180, +-2041, -2895, -1266, -2114, 419, 510, 1576, 2553, +1409, 2348, 149, 246, -1017, -1839, -1460, -2199, +-989, -771, 138, 1106, 1132, 1813, 1315, 1063, +476, -351, -769, -1064, -1566, -881, -1132, -253, +119, 134, 1194, 395, 1185, 717, 343, 946, +-684, 335, -1109, -869, -863, -1609, -168, -887, +691, 762, 908, 1730, 465, 1040, -359, -349, +-844, -1169, -621, -648, 153, 104, 358, 402, +9, -58, -333, -220, 43, 253, 532, 974, +659, 857, -275, -446, -1259, -1668, -1318, -1545, +-85, 232, 1358, 1899, 1832, 2016, 723, 390, +-1259, -1386, -2321, -1992, -1477, -1080, 641, 513, +2180, 1708, 1899, 1602, -118, 321, -1957, -1199, +-2161, -1599, -457, -655, 1407, 681, 2029, 1220, +796, 709, -1046, -175, -1980, -744, -1232, -633, +502, -75, 1722, 583, 1340, 673, -152, 101, +-1412, -622, -1453, -616, -405, 66, 644, 669, +1130, 483, 796, -186, 222, -395, -694, -92, +-1320, 258, -1255, -56, -195, -442, 1259, -296, +1895, 570, 1025, 1126, -819, 544, -1950, -741, +-1873, -1651, -554, -1057, 1095, 470, 2250, 1842, +2060, 1814, 149, 407, -2363, -1517, -3411, -2438, +-1503, -1494, 1887, 861, 3769, 2745, 2165, 2434, +-1234, -75, -3268, -2616, -2221, -2838, 276, -452, +1900, 2310, 1651, 2804, 413, 653, -612, -1945, +-985, -2416, -883, -523, -474, 1694, 324, 1914, +801, 227, 648, -1390, 55, -1298, -443, 138, +-596, 1125, -329, 718, -47, -334, 295, -795, +271, -364, 52, 256, -290, 484, -151, 487, +275, 262, 339, -233, -351, -982, -945, -1037, +-524, 108, 710, 1626, 1382, 1840, 613, 81, +-1078, -2032, -1792, -2353, -770, -368, 1031, 1955, +1815, 2445, 806, 809, -836, -1273, -1782, -1975, +-1037, -1152, 412, 285, 1423, 1189, 1070, 1237, +-106, 567, -1062, -404, -1083, -955, -276, -833, +508, -60, 883, 503, 541, 640, -190, 265, +-823, -125, -822, -370, -182, -270, 614, 84, +901, 422, 417, 241, -421, -328, -967, -720, +-879, -251, 2, 676, 977, 1106, 1146, 421, +227, -800, -1003, -1305, -1367, -707, -403, 583, +897, 1245, 1113, 971, 259, -50, -743, -881, +-690, -1066, -97, -457, 406, 435, 130, 925, +-176, 625, -276, -128, -44, -560, 268, -340, +354, 142, 298, 218, -264, -110, -883, -446, +-1085, -221, -11, 393, 1486, 936, 1852, 784, +276, -173, -2059, -1351, -2618, -1731, -635, -570, +2202, 1428, 2824, 2699, 811, 1674, -1847, -1007, +-2659, -3166, -1154, -2709, 952, 132, 1949, 2835, +1393, 3213, 222, 1062, -1078, -1611, -1718, -2976, +-1411, -2256, -55, -243, 1544, 2068, 2221, 3072, +1160, 2169, -867, -607, -2511, -3150, -2264, -3616, +-369, -1118, 2003, 2384, 2819, 4223, 1627, 2633, +-876, -1075, -2843, -3782, -2668, -3341, -575, -287, +2096, 2451, 2998, 2942, 1745, 1247, -1028, -734, +-2765, -1734, -2312, -1476, -42, -647, 1787, 352, +1949, 1020, 663, 1231, -584, 643, -1027, -279, +-882, -1031, -559, -971, 15, -259, 597, 462, +830, 687, 464, 375, -49, 58, -341, -96, +-426, -87, -617, -242, -657, -451, -73, -487, +833, -70, 1385, 703, 737, 1146, -623, 718, +-1671, -556, -1291, -1527, -65, -1282, 1135, 27, +1433, 1228, 807, 1401, -196, 691, -1113, -289, +-1396, -1062, -921, -1311, 293, -779, 1484, 522, +1707, 1604, 587, 1392, -1293, -77, -2123, -1502, +-1179, -1456, 893, -117, 2023, 1157, 1221, 1130, +-616, 69, -1670, -842, -983, -673, 358, 124, +1126, 641, 735, 301, -82, -323, -807, -547, +-827, -143, -161, 314, 591, 387, 748, 139, +380, -22, -229, -24, -534, -124, -544, -436, +-470, -517, -126, -26, 527, 728, 1189, 947, +902, 274, -333, -636, -1632, -975, -1563, -502, +-137, 202, 1463, 628, 1788, 561, 541, 199, +-963, -295, -1454, -398, -561, -112, 292, 257, +474, 9, 50, -608, 129, -582, 586, 465, +858, 1508, -21, 996, -1425, -776, -1814, -2048, +-545, -1258, 1461, 707, 2322, 1987, 1354, 1264, +-913, -348, -2384, -1505, -1849, -1209, 133, -167, +1781, 871, 1923, 1128, 547, 672, -1011, -263, +-1631, -917, -911, -954, 292, -398, 1059, 340, +749, 857, 163, 1029, -265, 498, -333, -482, +-294, -1407, -492, -1229, -400, 20, 332, 1307, +1000, 1461, 736, 355, -213, -879, -1025, -1258, +-839, -603, 124, 416, 865, 883, 571, 547, +-224, -220, -523, -511, -188, -202, 233, 253, +203, 125, -8, -296, -155, -356, -62, 109, +31, 534, 20, 399, -9, -75, 28, -348, +122, -345, 88, -196, -19, -82, -265, 89, +-377, 343, 5, 366, 473, 247, 613, -142, +98, -320, -556, -450, -770, -319, -175, -77, +542, 351, 745, 637, 165, 461, -553, -69, +-592, -565, 143, -495, 718, -156, 240, 80, +-674, 54, -777, 132, 250, 492, 1011, 585, +603, 29, -433, -869, -824, -1089, -361, -255, +209, 843, 299, 1112, 208, 419, 342, -471, +296, -687, -135, -463, -773, -130, -734, -66, +26, 196, 971, 599, 1035, 839, 294, 391, +-838, -664, -1368, -1401, -714, -1139, 678, 243, +1573, 1554, 1141, 1666, -375, 268, -1591, -1369, +-1290, -1783, 70, -575, 1293, 992, 1299, 1439, +320, 629, -812, -542, -1174, -933, -584, -696, +326, -37, 952, 431, 718, 873, 204, 677, +-463, -19, -639, -1089, -648, -1318, -154, -349, +429, 1187, 961, 1817, 729, 659, -253, -1189, +-978, -2137, -693, -942, 375, 1177, 777, 2211, +206, 1051, -730, -1240, -644, -2183, 462, -911, +1447, 1307, 973, 2088, -736, 603, -2174, -1430, +-1653, -2051, 562, -501, 2744, 1469, 2432, 2051, +-155, 679, -2571, -1305, -2610, -1972, -366, -944, +1804, 820, 2149, 1474, 847, 849, -576, -233, +-1297, -531, -890, -238, -171, -193, 313, -560, +362, -705, 378, 96, 531, 1178, 647, 1489, +104, 509, -1046, -1036, -1457, -1809, -635, -1244, +1039, 285, 1770, 1472, 1066, 1461, -569, 436, +-1389, -609, -966, -981, 18, -731, 740, -388, +643, 33, 201, 538, -146, 966, -4, 748, +87, -150, 10, -998, -443, -1045, -620, -219, +-76, 629, 783, 896, 944, 391, 279, -350, +-657, -727, -780, -395, -135, 405, 323, 823, +216, 294, -160, -778, 59, -1301, 552, -415, +843, 1030, 48, 1809, -1066, 891, -1447, -802, +-436, -1967, 1001, -1581, 1693, -44, 1087, 1476, +-232, 1942, -1143, 1013, -1193, -558, -657, -1636, +89, -1511, 741, -463, 1078, 645, 1053, 1247, +472, 1102, -643, 435, -1551, -500, -1493, -1190, +-363, -1141, 1223, -421, 2033, 627, 1527, 1253, +-117, 1177, -1509, 234, -2038, -956, -1255, -1608, +274, -1075, 1832, 325, 2451, 1560, 1387, 1609, +-919, 438, -2845, -1238, -2493, -1986, -121, -1149, +2424, 884, 2779, 2228, 1026, 1516, -1197, -730, +-2132, -2326, -1507, -1607, 17, 545, 1319, 2090, +1661, 1606, 846, -174, -532, -1651, -1367, -1745, +-1047, -497, -9, 1010, 897, 1791, 1215, 1195, +759, -235, -292, -1557, -1339, -1811, -1429, -747, +-157, 912, 1607, 2081, 2116, 1623, 561, -120, +-1590, -2005, -2316, -2216, -685, -607, 1510, 1529, +2224, 2234, 758, 1011, -1141, -899, -1738, -1761, +-617, -1162, 804, 139, 1259, 938, 553, 1004, +-336, 500, -479, -154, -248, -731, -105, -950, +-176, -482, -63, 360, 430, 1000, 889, 802, +595, -38, -374, -871, -1105, -957, -856, -337, +186, 565, 1055, 980, 927, 685, 181, -180, +-650, -951, -796, -1100, -220, -436, 582, 661, +748, 1312, 155, 999, -540, -170, -651, -1175, +105, -1336, 797, -493, 586, 543, -239, 1163, +-664, 976, -399, 182, 290, -726, 660, -1190, +398, -852, -127, 137, -447, 1047, -306, 1247, +126, 369, 312, -819, 222, -1459, 78, -844, +38, 451, 11, 1308, -70, 1085, -223, -5, +-158, -848, 188, -1087, 500, -567, 427, 152, +-5, 758, -506, 857, -660, 296, -223, -476, +647, -761, 1114, -288, 658, 340, -380, 318, +-1282, -247, -1039, -553, 176, -25, 1358, 739, +1274, 812, 226, -51, -822, -978, -972, -918, +-339, -48, 220, 751, 457, 634, 461, -10, +429, -393, 242, -251, -141, 36, -524, -54, +-568, -184, -190, -45, 345, 396, 870, 499, +916, -30, 59, -741, -988, -881, -1280, -177, +-250, 731, 1160, 1064, 1618, 587, 544, -283, +-874, -981, -1446, -1114, -742, -654, 470, 324, +1209, 1216, 1062, 1430, 370, 597, -485, -825, +-1107, -1795, -939, -1538, -113, -108, 976, 1458, +1465, 2023, 880, 982, -411, -876, -1364, -2044, +-1150, -1510, -104, 217, 949, 1514, 1276, 1323, +797, 111, 20, -814, -811, -750, -1080, -219, +-780, 87, 298, -47, 1259, -9, 1453, 354, +368, 595, -1047, 199, -1518, -595, -432, -926, +1101, -372, 1533, 479, 373, 833, -1084, 396, +-1250, -253, -8, -594, 1148, -508, 1107, -203, +179, 160, -627, 531, -607, 580, -272, 176, +34, -524, 181, -895, 433, -579, 619, 194, +482, 855, -46, 858, -585, 241, -562, -631, +-140, -1056, 258, -734, 399, 60, 379, 734, +381, 848, 270, 545, -15, -28, -456, -665, +-529, -1121, -243, -932, 217, 45, 550, 1120, +775, 1407, 634, 617, 70, -613, -794, -1305, +-1189, -1174, -568, -333, 710, 608, 1497, 1117, +1185, 854, 112, 41, -882, -614, -1208, -767, +-831, -509, 29, -198, 1047, 111, 1616, 489, +1079, 688, -356, 330, -1542, -402, -1354, -859, +-37, -456, 1136, 348, 1130, 731, 468, 237, +-79, -589, -230, -824, -369, -249, -500, 645, +-292, 910, 408, 371, 917, -517, 637, -921, +-100, -542, -449, 110, -287, 471, 82, 204, +58, -26, -71, 36, 114, 303, 584, 224, +781, -336, 214, -749, -596, -716, -992, -49, +-410, 543, 562, 900, 1143, 719, 810, 43, +0, -814, -614, -1394, -692, -952, -251, 344, +372, 1566, 855, 1599, 654, 187, -136, -1550, +-731, -2072, -499, -798, 352, 1207, 925, 2026, +686, 1070, -78, -778, -657, -1617, -563, -1081, +-155, 73, 457, 666, 831, 559, 869, 362, +249, 264, -654, 102, -1178, -523, -654, -1048, +711, -803, 1614, 270, 1306, 1209, -177, 995, +-1369, -173, -1492, -1063, -256, -848, 1070, 118, +1778, 664, 1238, 410, -90, -271, -1393, -528, +-1668, -252, -542, 188, 1048, 451, 1904, 292, +1289, -82, -179, -488, -1366, -628, -1181, -322, +23, 178, 1034, 671, 933, 648, 151, 213, +-386, -447, -155, -870, 247, -700, 243, -169, +-104, 482, -194, 705, 141, 549, 501, 115, +503, -339, 65, -627, -333, -765, -421, -451, +-127, 128, 381, 794, 710, 975, 675, 424, +205, -408, -298, -1089, -711, -1020, -588, -414, +7, 534, 834, 1163, 1210, 1033, 794, 112, +-151, -1025, -991, -1389, -1049, -751, -229, 364, +831, 1100, 1340, 932, 842, 261, -214, -601, +-890, -985, -639, -757, 241, -10, 763, 728, +503, 701, -106, 153, -263, -504, 18, -521, +486, -156, 493, 198, 82, 158, -395, -68, +-380, -150, -53, -51, 414, 107, 740, 60, +651, -119, 152, -192, -482, -86, -722, 117, +-331, 93, 491, -142, 987, -282, 709, -109, +55, 314, -480, 332, -429, -106, -63, -644, +230, -482, 374, 305, 445, 835, 462, 404, +195, -638, -274, -1134, -643, -538, -303, 540, +607, 1104, 1154, 702, 706, -93, -466, -783, +-1016, -1026, -483, -751, 559, -92, 1100, 762, +723, 1194, 52, 902, -617, -81, -636, -1106, +-236, -1478, 613, -856, 1025, 400, 735, 1290, +-181, 1187, -837, 176, -517, -801, 238, -1114, +758, -668, 602, 48, 215, 674, -20, 883, +-57, 515, -154, -410, -299, -1135, -50, -1136, +451, -124, 781, 957, 512, 1347, -131, 752, +-512, -399, -279, -1252, 303, -1446, 498, -622, +339, 513, -89, 1405, -117, 1223, 231, 277, +497, -749, 184, -1257, -382, -1069, -417, -430, +208, 533, 989, 1290, 838, 1270, -83, 186, +-965, -1218, -811, -1710, 161, -826, 1069, 666, +1181, 1443, 509, 1029, -317, -91, -829, -967, +-632, -1117, -72, -615, 525, 240, 805, 833, +753, 877, 350, 312, -174, -481, -484, -926, +-380, -797, -40, -130, 435, 596, 532, 824, +283, 370, -47, -397, 26, -698, 282, -338, +271, 200, 21, 258, -226, -114, -33, -302, +239, -64, 297, 292, 127, 295, -14, 33, +156, -303, 286, -435, 294, -364, 68, -3, +27, 439, 46, 579, -61, 92, -193, -633, +-170, -893, 337, -297, 851, 679, 996, 1109, +284, 471, -810, -761, -1342, -1495, -654, -1013, +885, 420, 1745, 1561, 1328, 1433, -162, 115, +-1336, -1355, -1258, -1783, -121, -910, 1126, 618, +1428, 1567, 731, 1269, -449, 36, -1043, -1130, +-697, -1282, 347, -536, 1130, 403, 939, 805, +23, 567, -768, 3, -608, -464, 103, -598, +755, -325, 718, 188, 325, 515, -131, 363, +-394, -170, -415, -578, -142, -487, 468, -15, +886, 329, 724, 337, -24, 42, -611, -129, +-529, -153, -1, 61, 462, 28, 489, -279, +317, -717, 145, -536, 156, 454, 66, 1408, +-145, 1133, -302, -533, -157, -1949, 235, -1616, +632, 257, 691, 1790, 326, 1476, -214, -118, +-579, -1331, -671, -1100, -124, -1, 724, 672, +1279, 405, 937, -176, -142, -253, -1118, 114, +-1169, 269, -178, -166, 930, -579, 1319, -383, +772, 213, -60, 540, -537, 270, -651, -89, +-386, -291, 52, -319, 611, -371, 866, -213, +605, 231, -58, 605, -567, 430, -447, -167, +-19, -663, 367, -629, 431, -184, 436, 325, +283, 623, -45, 473, -386, -94, -395, -734, +141, -768, 573, -151, 577, 583, 130, 677, +-184, 162, -117, -378, 67, -474, 41, -269, +-111, -57, 106, 78, 499, 168, 526, 203, +12, 31, -450, -139, -314, -152, 297, 19, +677, 11, 350, -254, -247, -418, -459, -159, +-156, 389, 374, 660, 639, 325, 455, -335, +-4, -762, -322, -673, -307, -75, 3, 540, +243, 702, 222, 253, 158, -425, 230, -636, +274, -256, 130, 265, -146, 337, -201, -9, +12, -291, 183, -223, 97, 76, -26, 159, +170, 27, 483, -179, 459, -129, -76, 74, +-523, 259, -387, 65, 147, -363, 436, -615, +385, -252, 203, 472, 130, 860, 109, 404, +-124, -529, -328, -1035, -268, -618, 273, 280, +600, 820, 556, 574, 60, -52, -400, -464, +-497, -536, -123, -354, 461, -125, 699, 268, +514, 615, -99, 582, -544, -10, -587, -776, +-115, -1006, 558, -469, 893, 485, 597, 1049, +-129, 839, -617, -63, -667, -910, -159, -1112, +499, -464, 785, 467, 573, 915, 26, 640, +-415, -28, -516, -525, -182, -648, 250, -479, +494, -98, 453, 383, 207, 704, -85, 491, +-343, -143, -371, -732, -30, -721, 467, -212, +696, 360, 368, 535, -301, 343, -671, -3, +-323, -240, 408, -296, 659, -277, 338, -243, +-139, -155, -165, 130, 65, 501, 116, 632, +-152, 197, -338, -590, -20, -1053, 517, -707, +823, 245, 449, 1088, -269, 1062, -862, 136, +-762, -941, -38, -1290, 801, -557, 1075, 571, +623, 1100, -194, 661, -745, -196, -728, -686, +-200, -674, 406, -389, 690, -25, 565, 518, +129, 877, -313, 560, -449, -419, -113, -1083, +324, -729, 429, 190, 80, 561, -288, 153, +-231, -154, 209, 211, 464, 700, 310, 375, +-132, -655, -351, -1390, -174, -1053, 197, 134, +382, 1268, 240, 1587, -33, 833, -255, -557, +-156, -1613, 142, -1567, 322, -429, 212, 884, +50, 1424, -3, 932, -58, -27, -242, -762, +-235, -900, 160, -529, 673, 18, 603, 440, +-164, 462, -905, 203, -647, -127, 518, -162, +1252, -11, 695, 17, -661, -211, -1217, -396, +-470, -172, 732, 300, 1066, 501, 392, 238, +-389, -173, -567, -330, -75, -298, 259, -220, +281, -121, 17, 205, -142, 535, -185, 476, +39, -84, 399, -672, 492, -737, 142, -221, +-338, 399, -476, 664, -242, 455, 167, 25, +424, -376, 425, -484, 220, -404, -80, -177, +-330, 42, -332, 345, 9, 635, 366, 591, +382, -29, 63, -941, -236, -1203, -220, -336, +25, 1004, 285, 1443, 263, 421, 36, -1064, +-169, -1414, -164, -345, 12, 933, 161, 1085, +188, 186, 47, -616, -62, -555, 28, -62, +155, 86, 60, -184, -147, -266, -204, 199, +76, 703, 373, 598, 306, -133, -59, -749, +-299, -682, -180, -123, 49, 255, 167, 169, +173, -9, 237, 183, 224, 562, -51, 511, +-463, -192, -450, -1004, 70, -1082, 640, -268, +658, 761, 140, 1130, -404, 617, -524, -240, +-241, -736, 19, -598, 174, -191, 335, 167, +574, 282, 556, 328, 22, 244, -806, -91, +-1188, -542, -605, -630, 674, -37, 1602, 791, +1313, 1003, -8, 264, -1312, -794, -1560, -1193, +-666, -694, 657, 195, 1413, 817, 1163, 928, +138, 571, -846, -68, -1111, -694, -512, -930, +326, -560, 873, 91, 783, 590, 174, 633, +-568, 308, -946, -155, -538, -463, 473, -329, +1346, 183, 1001, 520, -358, 136, -1513, -681, +-1235, -982, 181, -203, 1407, 1013, 1327, 1418, +134, 535, -906, -848, -1001, -1507, -247, -914, +451, 338, 639, 1184, 281, 964, -138, -1, +-288, -740, -131, -677, 91, -75, 185, 275, +173, 194, 86, 16, -148, 107, -317, 147, +-212, -80, 212, -371, 520, -222, 392, 234, +-159, 377, -609, -26, -416, -405, 273, -180, +727, 385, 454, 480, -291, -89, -813, -666, +-593, -515, 270, 171, 1035, 639, 869, 453, +-101, -37, -977, -323, -896, -289, -77, -195, +708, -155, 722, 17, 133, 315, -343, 458, +-258, 166, 65, -305, 127, -450, -7, -148, +-106, 229, -1, 212, 56, -54, -62, -233, +-201, -64, 21, 185, 519, 244, 654, 89, +103, -115, -747, -189, -973, -169, -361, -92, +550, 1, 897, 123, 648, 186, 85, 135, +-343, 11, -633, -100, -634, -130, -248, -139, +365, -91, 791, 41, 642, 205, 86, 203, +-492, -50, -662, -244, -404, -134, 40, 137, +456, 179, 542, -99, 288, -255, -100, -3, +-305, 422, -264, 396, -199, -125, -200, -693, +-144, -677, 278, -57, 816, 709, 843, 1032, +-16, 565, -1097, -395, -1420, -1161, -541, -993, +823, -72, 1591, 818, 1133, 892, -137, 315, +-1255, -196, -1393, -252, -506, -114, 653, -214, +1218, -434, 804, -362, -85, 106, -739, 617, +-725, 720, -284, 349, 195, -252, 449, -718, +422, -719, 217, -208, -78, 480, -265, 730, +-436, 364, -395, -257, -94, -492, 441, -205, +744, 158, 508, 223, -179, -29, -799, -145, +-741, -21, -98, 197, 496, 156, 461, -133, +160, -338, 23, -196, 148, 256, 71, 517, +-353, 281, -791, -335, -569, -701, 346, -383, +1158, 391, 960, 832, -127, 414, -1122, -440, +-1073, -831, -103, -358, 858, 446, 878, 650, +75, 180, -634, -360, -514, -327, 119, 62, +481, 246, 182, 24, -373, -235, -495, -125, +-21, 172, 469, 272, 369, -30, -62, -316, +-281, -225, -89, 232, 60, 515, -119, 256, +-421, -356, -225, -697, 479, -385, 942, 302, +457, 692, -622, 417, -1267, -167, -814, -454, +353, -211, 1207, 175, 1036, 192, 41, -109, +-898, -316, -1030, -102, -378, 281, 404, 408, +659, 155, 371, -192, -85, -298, -262, -156, +-158, 33, 27, 100, 4, 62, -144, 10, +-296, -36, -190, -6, 184, 50, 571, 174, +526, 148, -22, -39, -639, -322, -797, -405, +-358, -129, 269, 302, 623, 536, 557, 329, +200, -83, -209, -337, -500, -293, -538, -115, +-322, -62, 63, -18, 437, 96, 554, 313, +281, 369, -192, 177, -543, -116, -501, -359, +-119, -445, 342, -366, 423, -31, 97, 445, +-242, 702, -284, 467, -91, -132, 95, -563, +142, -585, 15, -267, -97, 123, -149, 445, +-40, 527, 52, 193, 91, -308, -93, -504, +-252, -112, -155, 338, 226, 253, 441, -244, +170, -409, -369, 57, -605, 558, -328, 439, +160, -181, 432, -596, 363, -446, 91, 1, +-193, 378, -351, 480, -344, 333, -122, -44, +158, -433, 219, -518, 33, -189, -43, 250, +83, 401, 145, 224, -89, -39, -426, -122, +-458, -77, -19, -13, 430, -55, 409, -102, +-9, -42, -297, 130, -192, 251, 12, 98, +22, -204, -191, -344, -315, -92, -84, 296, +408, 430, 573, 192, 95, -184, -595, -397, +-771, -423, -232, -226, 512, 166, 724, 619, +189, 701, -500, 185, -663, -556, -266, -805, +238, -313, 473, 321, 303, 424, -108, 52, +-466, -165, -419, 102, -20, 402, 362, 216, +308, -328, -129, -554, -457, -186, -319, 281, +149, 264, 412, -169, 298, -292, -61, 157, +-361, 689, -475, 548, -388, -238, -82, -865, +369, -702, 680, 11, 469, 493, -186, 437, +-745, 147, -703, 95, -207, 195, 224, 44, +320, -396, 245, -660, 282, -293, 237, 400, +-125, 714, -697, 280, -834, -404, -294, -551, +552, -4, 925, 617, 505, 602, -286, -78, +-809, -764, -689, -821, -146, -185, 394, 557, +478, 858, 208, 534, -106, 6, -225, -361, +-183, -447, -167, -426, -215, -373, -206, -108, +86, 395, 347, 840, 385, 705, 39, -21, +-356, -757, -556, -787, -319, -112, 142, 507, +399, 415, 247, -209, -169, -507, -381, -75, +-207, 631, 212, 797, 293, 229, -34, -517, +-395, -833, -361, -600, -41, -80, 261, 414, +293, 680, 82, 581, -222, 203, -395, -248, +-317, -469, 13, -437, 325, -226, 355, 36, +58, 261, -276, 354, -372, 251, -284, 52, +-217, -127, -116, -191, 221, -185, 624, -67, +615, 131, -18, 271, -817, 169, -1082, -137, +-520, -315, 355, -225, 847, 28, 626, 191, +97, 300, -290, 389, -403, 292, -385, -166, +-414, -722, -315, -779, 64, -172, 636, 604, +748, 896, 175, 575, -688, -2, -971, -506, +-383, -745, 498, -561, 741, 76, 189, 739, +-420, 799, -534, 155, -218, -593, 30, -684, +135, -121, 192, 477, 257, 508, 135, 60, +-242, -320, -578, -276, -510, 69, -63, 251, +354, 85, 481, -212, 294, -238, -36, 73, +-370, 379, -488, 356, -350, -16, -62, -373, +170, -413, 272, -108, 256, 276, 110, 402, +-105, 188, -316, -131, -373, -222, -253, -81, +-78, 42, 82, 12, 244, 21, 358, 214, +281, 295, -114, -37, -588, -577, -724, -597, +-322, 127, 292, 911, 624, 868, 463, -4, +28, -811, -316, -821, -433, -193, -400, 353, +-307, 453, -67, 273, 316, 191, 601, 180, +471, 18, -125, -361, -772, -608, -867, -400, +-270, 194, 503, 680, 764, 625, 373, 107, +-275, -372, -596, -439, -389, -140, -10, 152, +142, 178, 8, -32, -62, -184, -19, -50, +148, 282, 206, 476, 74, 232, -226, -244, +-503, -489, -521, -284, -224, 31, 356, 66, +747, -42, 556, 161, -145, 678, -728, 799, +-753, 72, -274, -995, 231, -1309, 363, -488, +233, 653, 103, 1153, 36, 800, -76, 170, +-270, -309, -462, -610, -434, -751, -75, -500, +448, 233, 741, 971, 442, 975, -371, 114, +-1074, -908, -965, -1093, -25, -225, 960, 930, +1083, 1236, 254, 385, -718, -831, -983, -1221, +-479, -446, 164, 660, 366, 1016, 170, 400, +30, -416, 134, -595, 214, -109, -64, 404, +-521, 402, -642, -21, -259, -375, 299, -333, +522, 12, 296, 287, -57, 251, -218, 42, +-262, -2, -327, 159, -316, 219, -53, -108, +332, -543, 465, -505, 186, 155, -279, 783, +-529, 644, -410, -162, -110, -746, 169, -449, +362, 359, 389, 767, 89, 348, -375, -397, +-626, -686, -433, -333, 43, 246, 397, 517, +379, 414, 98, 148, -161, -79, -296, -249, +-272, -323, -143, -231, -3, 50, 31, 328, +-1, 377, 16, 188, 129, -75, 144, -226, +-120, -221, -409, -70, -397, 137, -28, 247, +329, 158, 349, -51, 42, -125, -259, -1, +-342, 110, -246, 13, -100, -159, 50, -87, +168, 229, 179, 417, 85, 174, -52, -301, +-188, -515, -356, -242, -370, 290, -121, 619, +283, 460, 446, -70, 180, -536, -270, -520, +-443, -60, -211, 408, 57, 476, 97, 205, +-52, -37, -77, -87, 23, -110, 75, -240, +-79, -327, -249, -112, -202, 362, 69, 698, +271, 540, 143, -61, -208, -630, -440, -693, +-291, -188, 87, 397, 317, 533, 169, 220, +-152, -88, -309, -32, -160, 158, 86, 82, +189, -231, 42, -352, -179, -47, -348, 323, +-303, 292, -96, -62, 197, -247, 412, 8, +347, 378, -37, 393, -474, 0, -604, -378, +-360, -399, 38, -147, 267, 104, 299, 218, +261, 318, 191, 412, -68, 291, -497, -175, +-787, -676, -529, -643, 220, 69, 878, 861, +807, 920, 3, 80, -851, -856, -1027, -964, +-368, -126, 439, 829, 719, 1005, 339, 322, +-180, -490, -374, -696, -242, -281, -163, 214, +-275, 333, -285, 120, 16, -71, 467, 0, +638, 229, 232, 336, -461, 113, -894, -299, +-696, -523, -69, -268, 546, 273, 666, 552, +294, 322, -212, -83, -444, -159, -346, 69, +-162, 105, -137, -248, -187, -509, -23, -152, +365, 601, 588, 930, 272, 418, -462, -478, +-983, -918, -768, -570, 79, 161, 863, 665, +877, 653, 140, 266, -714, -165, -947, -361, +-437, -266, 278, -37, 556, 125, 289, 150, +-117, 102, -274, 52, -190, 11, -110, -12, +-142, 14, -178, 105, -66, 178, 137, 127, +252, -20, 154, -187, -116, -261, -405, -190, +-474, 35, -219, 346, 194, 504, 414, 366, +270, -9, -117, -318, -372, -371, -323, -240, +-131, -92, -56, 39, -21, 281, 90, 540, +178, 516, 96, 80, -172, -461, -339, -588, +-203, -258, 74, 175, 127, 369, -70, 357, +-269, 260, -226, 20, 63, -326, 262, -430, +207, -27, -51, 548, -323, 584, -429, -38, +-277, -617, 11, -487, 196, 138, 230, 499, +120, 341, -36, 67, -171, 33, -258, 53, +-279, -153, -222, -408, -84, -327, 90, 134, +270, 563, 326, 604, 89, 266, -387, -222, +-722, -597, -465, -627, 224, -177, 671, 537, +386, 936, -330, 638, -678, -152, -313, -740, +246, -702, 349, -233, -37, 256, -335, 509, +-249, 592, 35, 462, 74, 77, -57, -452, +-107, -739, 57, -491, 107, 153, -122, 685, +-404, 676, -368, 175, 5, -331, 362, -407, +358, -50, 7, 314, -349, 238, -461, -198, +-302, -478, 29, -146, 289, 533, 269, 810, +-31, 281, -364, -583, -407, -850, -71, -207, +333, 642, 304, 808, -139, 159, -573, -516, +-483, -503, 80, 49, 526, 436, 344, 260, +-219, -116, -555, -185, -347, 87, 154, 258, +336, 61, 34, -236, -356, -230, -379, 132, +-25, 416, 326, 304, 279, -87, -145, -373, +-512, -315, -428, -6, 46, 316, 448, 443, +320, 306, -173, 3, -529, -269, -422, -317, +-15, -171, 286, 29, 248, 158, 12, 229, +-182, 270, -250, 223, -237, 38, -124, -193, +10, -265, 109, -100, 69, 128, -20, 182, +-115, 37, -135, -105, -148, -15, -99, 235, +-37, 353, 2, 155, -30, -209, -67, -360, +-39, -170, 21, 147, -11, 259, -179, 127, +-276, -7, -109, 3, 163, 91, 191, 72, +-42, -40, -273, -45, -212, 89, 10, 191, +72, 29, -122, -284, -246, -360, -90, 9, +198, 539, 262, 660, -11, 224, -390, -352, +-479, -542, -189, -297, 226, 4, 423, 147, +189, 253, -286, 422, -552, 450, -323, 92, +177, -429, 424, -630, 164, -293, -340, 271, +-464, 565, -119, 427, 227, 53, 147, -238, +-204, -266, -318, -90, -4, 118, 303, 165, +177, 93, -257, 50, -483, 75, -276, 49, +102, -106, 217, -203, 67, -68, -58, 228, +-14, 391, 22, 277, -117, 0, -340, -279, +-369, -434, -82, -359, 249, 52, 344, 605, +146, 814, -150, 362, -316, -431, -305, -853, +-174, -542, -27, 176, 85, 665, 112, 594, +78, 154, 32, -228, -72, -329, -204, -203, +-314, -16, -244, 124, 37, 194, 297, 206, +255, 141, -102, -12, -402, -170, -350, -175, +-12, 4, 233, 219, 154, 236, -113, 23, +-230, -185, -109, -145, 40, 129, 6, 293, +-162, 133, -258, -207, -62, -290, 232, 39, +328, 416, 49, 388, -369, -96, -607, -493, +-382, -360, 143, 177, 542, 565, 480, 411, +-9, -73, -517, -407, -597, -299, -216, 92, +233, 364, 328, 279, 58, -91, -239, -363, +-242, -226, 0, 216, 175, 526, 100, 319, +-160, -199, -316, -479, -240, -204, -20, 275, +138, 378, 174, 35, 47, -285, -109, -145, +-205, 252, -183, 364, -85, 38, 55, -299, +77, -186, -12, 225, -118, 372, -162, 0, +-107, -482, -13, -440, 48, 176, 90, 764, +76, 709, -47, -2, -251, -701, -355, -774, +-217, -183, 79, 471, 337, 640, 310, 317, +50, -68, -274, -180, -441, -122, -391, -161, +-101, -229, 254, -74, 429, 334, 226, 592, +-198, 323, -478, -293, -357, -648, 13, -364, +258, 272, 183, 619, -43, 371, -190, -171, +-176, -431, -89, -204, -15, 200, 36, 341, +45, 124, 10, -154, -73, -193, -146, 16, +-155, 213, -89, 181, -2, -29, 68, -218, +99, -178, 38, 76, -80, 344, -167, 379, +-182, 75, -155, -337, -94, -507, 41, -246, +219, 278, 269, 614, 26, 464, -380, -61, +-515, -483, -169, -412, 318, 30, 428, 362, +9, 241, -433, -108, -379, -232, 86, 28, +364, 345, 181, 302, -248, -61, -399, -363, +-149, -304, 159, 4, 131, 250, -81, 273, +-171, 143, 13, 4, 224, -92, 119, -115, +-244, -52, -458, 53, -254, 112, 195, 44, +405, -55, 150, -57, -264, 27, -390, 94, +-95, 70, 261, 57, 288, 108, -63, 113, +-440, -70, -466, -319, -65, -312, 390, 59, +505, 469, 166, 485, -325, 57, -561, -365, +-363, -375, 61, -12, 366, 305, 316, 254, +1, -62, -303, -300, -342, -200, -93, 150, +213, 405, 215, 336, -48, -21, -256, -336, +-151, -358, 96, -111, 138, 178, -105, 292, +-315, 229, -184, 76, 196, -79, 394, -160, +199, -140, -213, -17, -494, 97, -424, 126, +-98, 81, 284, 25, 464, 12, 304, -22, +-117, -85, -417, -80, -411, 48, -145, 204, +116, 165, 191, -79, 103, -283, 33, -167, +-8, 193, -77, 387, -147, 186, -145, -176, +-66, -268, 11, -48, 14, 113, -17, -14, +-6, -189, 40, -15, 86, 416, 32, 570, +-131, 131, -294, -550, -250, -790, 23, -335, +318, 394, 321, 784, -19, 546, -363, -50, +-326, -525, 16, -521, 247, -119, 95, 298, +-206, 387, -255, 141, 48, -133, 295, -172, +171, -49, -195, 45, -365, 51, -167, 75, +163, 123, 220, 64, -31, -124, -203, -263, +-80, -129, 181, 177, 175, 349, -137, 220, +-405, -62, -247, -225, 170, -205, 411, -93, +192, 48, -224, 164, -381, 211, -157, 113, +127, -41, 170, -87, -20, -9, -137, 26, +-69, -122, 95, -269, 132, -123, -23, 297, +-218, 582, -242, 360, -77, -195, 118, -595, +226, -511, 142, -63, -6, 374, -172, 528, +-268, 340, -222, -39, -15, -358, 215, -390, +285, -134, 76, 162, -205, 265, -255, 174, +-73, 44, 102, -36, 46, -98, -142, -132, +-131, -79, 102, 59, 273, 147, 135, 83, +-209, -25, -382, -46, -204, 21, 119, 36, +244, -41, 114, -89, -46, -10, -26, 115, +36, 142, -41, 30, -250, -102, -341, -172, +-99, -121, 311, 41, 511, 240, 287, 320, +-212, 120, -547, -240, -463, -415, -77, -216, +288, 151, 376, 289, 181, 140, -58, -7, +-141, 79, -116, 180, -85, -2, -147, -352, +-161, -452, -69, -103, 140, 334, 311, 435, +271, 222, -10, -2, -323, -58, -410, -117, +-213, -279, 124, -355, 287, -125, 200, 294, +7, 509, -70, 348, -43, -20, -67, -301, +-240, -348, -262, -233, -24, -8, 357, 210, +444, 293, 143, 184, -357, -10, -544, -126, +-310, -136, 119, -107, 397, -69, 366, 36, +133, 207, -166, 245, -368, 32, -393, -287, +-136, -352, 202, -11, 424, 409, 306, 443, +-54, -8, -382, -493, -363, -462, -67, 57, +243, 504, 255, 406, 40, -79, -160, -390, +-149, -269, -32, 60, 35, 201, 25, 121, +38, 40, 77, 48, 22, 13, -140, -148, +-263, -233, -94, -68, 206, 233, 317, 332, +93, 78, -222, -271, -306, -343, -97, -40, +111, 333, 135, 373, 50, 30, 24, -371, +51, -423, -27, -65, -236, 337, -281, 428, +-11, 147, 370, -185, 441, -311, 54, -213, +-461, 1, -558, 188, -140, 271, 386, 142, +498, -156, 123, -328, -266, -168, -302, 224, +-59, 408, 117, 155, 18, -255, -133, -377, +-62, -118, 165, 176, 261, 226, 35, 71, +-267, -56, -294, -38, -7, 32, 226, 73, +198, 4, -90, -139, -247, -250, -95, -155, +177, 203, 248, 514, 13, 381, -245, -189, +-245, -659, 0, -490, 182, 151, 164, 598, +-4, 423, -86, -98, -60, -380, -36, -233, +-73, 61, -68, 159, 87, 53, 233, -36, +117, -23, -208, 44, -375, 50, -152, 2, +300, -54, 456, -96, 163, -76, -321, 41, +-483, 173, -209, 156, 228, -51, 362, -227, +187, -156, -76, 124, -177, 277, -104, 104, +-21, -210, -41, -307, -103, -79, -22, 213, +165, 294, 275, 159, 120, -59, -159, -210, +-329, -255, -206, -163, 46, 67, 216, 274, +165, 302, 33, 84, -54, -199, -36, -318, +-37, -174, -60, 109, -87, 274, -41, 193, +44, -55, 117, -226, 110, -153, 0, 53, +-118, 176, -148, 93, -33, -68, 111, -125, +176, -60, 45, 76, -160, 161, -252, 119, +-85, -65, 205, -265, 322, -243, 122, 33, +-198, 324, -351, 287, -178, -19, 131, -220, +302, -113, 208, 89, -30, 56, -244, -165, +-272, -224, -131, 7, 157, 293, 366, 322, +290, 115, -71, -110, -424, -235, -422, -272, +-41, -219, 367, -21, 438, 262, 129, 426, +-257, 307, -336, -49, -103, -377, 137, -446, +156, -203, -2, 168, -104, 386, 2, 311, +122, 34, 87, -205, -72, -252, -158, -134, +-34, 36, 127, 136, 87, 131, -75, 20, +-156, -87, -54, -69, 123, 49, 178, 127, +83, 39, -34, -138, -115, -180, -125, -52, +-120, 110, -64, 153, 56, 118, 201, 64, +249, -33, 138, -195, -118, -281, -315, -97, +-289, 261, -46, 413, 210, 148, 250, -284, +110, -395, 5, -91, -11, 243, -49, 250, +-153, -5, -206, -153, -42, -69, 188, 60, +250, 45, 76, -70, -125, -72, -150, 31, +-2, 114, 81, 83, 35, -27, -35, -108, +-52, -130, -21, -53, 0, 97, 39, 220, +66, 168, 48, -87, -26, -282, -78, -201, +-46, 94, 41, 288, 81, 153, 19, -124, +-80, -250, -112, -113, -5, 104, 156, 213, +226, 177, 76, 25, -207, -158, -385, -271, +-200, -184, 247, 57, 535, 230, 320, 200, +-199, 50, -540, -12, -394, 24, 87, -39, +433, -208, 385, -297, 53, -126, -207, 173, +-228, 344, -100, 328, -35, 174, 8, -79, +74, -402, 191, -564, 196, -293, 20, 300, +-224, 702, -254, 496, -18, -114, 237, -520, +215, -429, -54, -58, -241, 182, -150, 211, +127, 166, 292, 122, 174, 26, -106, -161, +-278, -318, -201, -268, 46, 33, 229, 402, +223, 509, 52, 184, -139, -379, -201, -660, +-96, -351, 49, 266, 161, 601, 170, 381, +76, -88, -60, -324, -191, -240, -197, -67, +-48, -6, 154, 36, 267, 145, 189, 215, +-32, 116, -212, -120, -194, -259, -38, -166, +127, 53, 136, 201, 65, 147, -23, -13, +-47, -144, -33, -127, 5, 7, 47, 123, +90, 140, 55, 32, -61, -112, -142, -181, +-131, -117, 28, 59, 181, 207, 242, 219, +151, 53, -49, -168, -293, -264, -330, -177, +-97, 35, 289, 216, 469, 261, 258, 146, +-170, -83, -431, -272, -331, -280, 11, -67, +323, 189, 410, 276, 244, 151, -106, -54, +-390, -156, -391, -132, -59, -74, 321, -32, +413, 21, 150, 136, -152, 213, -233, 136, +-75, -95, 98, -320, 93, -298, -29, -34, +-83, 288, -2, 414, 118, 230, 135, -137, +24, -448, -86, -449, -69, -104, 57, 386, +117, 636, 7, 372, -161, -250, -156, -727, +55, -611, 266, 16, 272, 614, 62, 707, +-173, 272, -276, -284, -173, -581, 46, -509, +257, -177, 288, 225, 113, 524, -148, 523, +-274, 183, -152, -297, 112, -574, 272, -431, +217, -25, 15, 313, -153, 378, -185, 203, +-107, 1, 20, -122, 111, -158, 156, -148, +186, -111, 165, -19, 12, 88, -219, 161, +-356, 152, -210, 64, 131, -51, 373, -181, +332, -239, 79, -130, -91, 144, -71, 399, +-52, 346, -190, -65, -319, -536, -156, -598, +306, -116, 698, 526, 552, 783, -85, 388, +-728, -326, -768, -777, -146, -590, 587, 44, +773, 550, 303, 520, -322, 82, -490, -266, +-160, -207, 207, 40, 211, 93, -49, -134, +-135, -283, 95, -68, 306, 304, 171, 402, +-201, 83, -391, -301, -158, -336, 239, -51, +427, 199, 251, 167, -74, -12, -264, -103, +-227, -50, -92, 6, 75, -26, 231, -19, +299, 112, 191, 209, -76, 40, -328, -319, +-314, -443, -12, -72, 348, 508, 425, 653, +116, 130, -287, -579, -395, -759, -99, -230, +319, 464, 445, 691, 159, 322, -250, -232, +-397, -498, -154, -359, 208, -9, 354, 272, +206, 315, -35, 143, -156, -116, -95, -277, +2, -226, 37, -7, 26, 225, 54, 285, +103, 117, 115, -162, 25, -322, -72, -244, +-93, 1, -20, 235, 72, 305, 120, 195, +94, -23, 26, -262, -21, -375, -47, -242, +-37, 117, -7, 420, 54, 375, 119, 2, +151, -343, 87, -319, -57, -20, -185, 192, +-155, 104, 57, -107, 258, -122, 262, 87, +43, 271, -201, 174, -220, -153, 6, -387, +262, -286, 278, 79, 7, 347, -288, 280, +-287, -17, 58, -214, 422, -127, 426, 50, +21, 53, -389, -108, -403, -158, -27, 38, +346, 265, 348, 223, 104, -84, -120, -318, +-140, -229, -39, 71, 43, 273, 56, 218, +57, -11, 66, -211, 45, -262, -2, -139, +-22, 77, 43, 269, 120, 310, 81, 132, +-48, -187, -163, -427, -99, -374, 137, -17, +314, 380, 239, 483, -59, 174, -285, -247, +-221, -389, 63, -167, 263, 111, 222, 143, +20, -19, -115, -96, -50, 34, 88, 185, +142, 132, 33, -71, -128, -210, -158, -153, +5, -13, 251, 70, 332, 84, 117, 86, +-227, 60, -334, -34, -90, -136, 290, -112, +398, 54, 124, 170, -240, 63, -335, -159, +-66, -226, 294, -28, 404, 221, 165, 228, +-164, -9, -300, -219, -154, -188, 86, 13, +240, 131, 234, 91, 126, -9, -33, -55, +-159, -60, -178, -49, -16, 13, 217, 98, +293, 104, 87, -45, -176, -198, -224, -122, +12, 122, 248, 239, 206, 42, -28, -238, +-151, -229, -9, 89, 194, 315, 195, 134, +-45, -245, -231, -360, -155, -59, 116, 306, +317, 320, 249, 4, 20, -281, -150, -246, +-144, 21, -19, 203, 66, 135, 88, -88, +84, -213, 79, -109, 43, 120, 6, 253, +20, 153, 89, -74, 117, -231, -26, -205, +-197, -87, -187, 20, 92, 115, 402, 211, +377, 225, 7, 43, -354, -238, -330, -340, +41, -144, 377, 155, 331, 232, 13, 58, +-258, -83, -243, -35, 4, 74, 235, 13, +311, -142, 227, -156, 34, 40, -178, 211, +-298, 132, -234, -114, 34, -256, 333, -130, +469, 114, 343, 224, -13, 117, -381, -96, +-485, -193, -227, -72, 258, 124, 578, 159, +461, -54, 15, -271, -358, -204, -350, 131, +-54, 375, 207, 228, 245, -146, 150, -340, +52, -173, 0, 98, -57, 136, -117, -28, +-87, -91, 75, 72, 262, 246, 271, 147, +44, -194, -222, -439, -243, -295, 16, 154, +308, 501, 299, 418, -11, -44, -248, -477, +-154, -480, 145, -84, 305, 315, 176, 365, +-40, 107, -115, -147, -80, -181, -48, -78, +-14, -8, 105, 8, 270, 43, 285, 87, +56, 42, -224, -96, -294, -177, -74, -81, +204, 131, 309, 246, 168, 157, -43, -79, +-143, -278, -71, -289, 91, -118, 171, 142, +130, 332, 34, 298, -35, 48, -72, -259, +-112, -388, -66, -247, 121, 56, 346, 306, +363, 320, 87, 133, -284, -125, -387, -288, +-154, -271, 156, -116, 288, 103, 221, 248, +144, 258, 105, 125, 42, -104, -95, -283, +-231, -296, -215, -113, -10, 141, 247, 271, +348, 195, 239, 4, 31, -113, -104, -112, +-106, -76, -84, -97, -70, -114, -20, 12, +117, 215, 256, 263, 214, 24, 4, -270, +-135, -270, -50, 59, 100, 322, 98, 152, +-83, -281, -140, -446, 59, -86, 280, 448, +247, 548, -32, 91, -224, -459, -91, -556, +190, -156, 274, 296, 41, 406, -233, 146, +-204, -164, 113, -242, 362, -99, 278, 75, +-63, 112, -278, 43, -135, -26, 176, -46, +271, -45, 73, -76, -156, -72, -138, 30, +81, 153, 208, 165, 150, 5, 33, -154, +-1, -156, 13, -28, -68, 45, -169, -26, +-98, -93, 203, 7, 461, 226, 364, 305, +-88, 53, -491, -357, -449, -534, 33, -242, +544, 324, 576, 640, 120, 382, -379, -232, +-441, -614, -42, -407, 348, 130, 358, 419, +30, 224, -212, -116, -128, -171, 131, 66, +229, 195, 81, -49, -85, -387, -111, -352, +4, 118, 109, 542, 137, 424, 125, -133, +82, -556, -2, -399, -111, 131, -150, 444, +-49, 253, 153, -166, 314, -321, 273, -111, +48, 144, -245, 147, -346, -34, -158, -103, +207, 19, 454, 145, 349, 69, -10, -144, +-297, -249, -259, -131, 0, 126, 224, 274, +200, 193, 25, -45, -86, -237, -39, -213, +102, -34, 179, 135, 122, 148, -1, 31, +-118, -53, -162, -52, -94, -28, 63, -60, +278, -111, 399, -43, 252, 133, -122, 240, +-450, 107, -418, -170, 12, -309, 447, -156, +510, 140, 188, 252, -175, 89, -276, -141, +-131, -173, 11, 6, 67, 149, 115, 100, +212, -66, 244, -148, 53, -66, -233, 37, +-328, 51, -94, -19, 285, -49, 467, 10, +261, 93, -161, 109, -418, 11, -288, -113, +139, -163, 465, -96, 384, 31, -45, 95, +-420, 64, -339, 5, 135, 6, 541, 66, +459, 70, -66, -39, -533, -207, -497, -264, +10, -91, 506, 208, 591, 378, 230, 221, +-189, -132, -360, -351, -270, -242, -75, 47, +94, 180, 235, 78, 319, -58, 262, -29, +21, 90, -230, 79, -267, -45, -81, -115, +128, -69, 154, -37, 84, -96, 86, -78, +154, 148, 110, 378, -105, 245, -265, -230, +-141, -550, 193, -342, 379, 191, 199, 463, +-165, 247, -321, -118, -120, -214, 194, -49, +320, 51, 154, -42, -81, -138, -146, -39, +-37, 174, 75, 211, 52, 3, -30, -232, +-30, -228, 74, 20, 153, 236, 128, 209, +24, -19, -43, -212, -39, -191, -44, -23, +-81, 105, -65, 89, 70, 10, 251, -4, +301, 51, 127, 64, -145, -54, -304, -186, +-238, -158, 7, 31, 248, 198, 326, 160, +195, -17, -55, -127, -220, -88, -185, 6, +9, 30, 204, 17, 236, 40, 65, 48, +-160, -54, -254, -200, -88, -157, 235, 129, +400, 386, 234, 278, -152, -141, -401, -452, +-277, -354, 95, 31, 355, 317, 306, 290, +54, 78, -166, -98, -195, -133, -78, -86, +100, -50, 209, -34, 152, -6, -21, 63, +-184, 111, -172, 64, 30, -69, 248, -141, +279, -32, 85, 140, -160, 135, -256, -89, +-132, -258, 88, -113, 233, 206, 202, 305, +56, 25, -52, -315, -78, -309, -62, 44, +-58, 340, -9, 270, 110, -55, 217, -285, +169, -246, -34, -38, -230, 119, -213, 139, +32, 75, 272, 29, 272, 40, 53, 27, +-178, -84, -212, -245, -58, -252, 124, -7, +176, 325, 95, 431, 0, 166, -37, -248, +-40, -451, -49, -288, -26, 50, 63, 269, +167, 260, 147, 113, -34, -40, -207, -143, +-173, -173, 83, -116, 304, 12, 242, 114, +-56, 99, -283, 7, -221, -41, 67, 2, +290, 39, 230, -11, -22, -94, -182, -68, +-117, 59, 47, 106, 117, -29, 56, -188, +-17, -123, -18, 160, 37, 342, 59, 171, +9, -208, -40, -397, -42, -196, -14, 166, +30, 305, 82, 115, 113, -151, 67, -181, +-36, 30, -132, 205, -127, 115, -12, -140, +136, -252, 208, -81, 124, 170, -38, 190, +-170, -26, -162, -173, -28, -55, 127, 174, +181, 187, 108, -55, -15, -262, -82, -194, +-78, 65, -51, 217, 9, 132, 88, -52, +126, -125, 89, -50, -26, 59, -132, 71, +-127, -17, 12, -96, 165, -60, 191, 60, +56, 128, -141, 32, -209, -152, -78, -193, +148, -2, 248, 247, 137, 277, -73, 42, +-200, -255, -153, -358, -10, -191, 128, 101, +201, 326, 175, 350, 22, 152, -187, -175, +-272, -422, -129, -366, 165, -18, 336, 349, +219, 417, -85, 138, -286, -213, -212, -316, +29, -115, 225, 115, 223, 122, 58, -36, +-113, -118, -150, 8, -86, 182, 22, 166, +92, -38, 100, -228, 63, -201, 21, -14, +-21, 152, -69, 177, -71, 70, -26, -41, +28, -105, 63, -96, 62, -48, 42, 6, +16, 61, 5, 107, -25, 119, -60, 12, +-54, -179, -11, -251, 51, -70, 79, 237, +57, 329, 9, 61, -19, -277, -26, -303, +-13, 10, 3, 261, -3, 178, -8, -86, +10, -189, 25, -44, 13, 97, -3, 50, +18, -76, 44, -46, 58, 116, 14, 177, +-71, 8, -114, -240, -60, -282, 27, -44, +74, 242, 125, 303, 161, 106, 104, -131, +-83, -209, -295, -124, -321, -9, -55, 32, +318, 61, 440, 126, 194, 137, -184, 12, +-352, -184, -221, -229, 10, -37, 153, 200, +161, 230, 117, 19, 50, -194, -33, -199, +-133, -10, -156, 149, -48, 139, 127, 21, +198, -78, 72, -76, -121, -30, -182, -17, +-49, -7, 152, 27, 196, 91, 9, 98, +-195, -10, -185, -138, 5, -152, 181, -10, +184, 146, 45, 155, -106, 18, -146, -137, +-74, -146, 12, -24, 81, 98, 97, 111, +69, 22, 16, -61, -35, -76, -96, -25, +-139, 13, -79, 19, 115, 38, 281, 80, +180, 73, -157, -69, -399, -224, -234, -180, +220, 99, 481, 352, 260, 252, -229, -135, +-474, -395, -249, -253, 175, 123, 363, 307, +215, 159, -62, -81, -202, -136, -125, -23, +12, 33, 37, -27, -31, -70, -37, 4, +67, 101, 164, 49, 120, -77, -62, -92, +-193, 63, -146, 192, -5, 72, 76, -202, +54, -315, 56, -85, 88, 265, 85, 358, +-15, 115, -141, -188, -173, -261, -86, -139, +36, -17, 123, 46, 157, 116, 125, 224, +23, 196, -102, -53, -197, -320, -171, -340, +-32, -59, 131, 248, 220, 339, 168, 176, +-17, -87, -224, -250, -234, -249, -16, -73, +211, 170, 203, 299, -20, 184, -227, -111, +-194, -319, 38, -266, 217, 22, 188, 306, +20, 340, -148, 110, -219, -204, -140, -341, +70, -216, 250, 33, 214, 201, -43, 186, +-268, 86, -218, 5, 79, -38, 286, -80, +174, -137, -141, -131, -292, -40, -103, 105, +202, 207, 263, 159, 13, -27, -259, -229, +-240, -222, 71, 37, 331, 295, 219, 242, +-151, -127, -359, -403, -195, -247, 125, 203, +255, 450, 126, 219, -58, -200, -61, -357, +29, -130, 0, 171, -165, 204, -205, -1, +-12, -167, 243, -95, 281, 95, 65, 145, +-186, 20, -241, -98, -91, -24, 80, 116, +116, 73, 21, -176, -44, -336, 9, -111, +94, 328, 59, 507, -102, 176, -202, -346, +-75, -495, 179, -149, 255, 276, 4, 322, +-283, -1, -251, -249, 94, -143, 353, 176, +220, 297, -165, 57, -371, -270, -162, -327, +194, -38, 284, 266, 44, 262, -218, -10, +-189, -224, 71, -130, 253, 120, 123, 205, +-159, 20, -264, -221, -80, -222, 134, 25, +142, 263, -14, 238, -71, -20, 66, -240, +177, -217, 25, 20, -269, 202, -354, 150, +-71, -51, 321, -164, 414, -79, 136, 75, +-228, 129, -344, 53, -172, -40, 101, -68, +209, -59, 94, -52, -93, -27, -119, 35, +29, 108, 176, 117, 118, 44, -128, -56, +-300, -129, -155, -131, 164, -60, 297, 54, +120, 119, -134, 91, -186, 35, -24, 5, +107, -1, 34, -64, -118, -155, -114, -144, +58, 26, 206, 200, 155, 190, -62, 32, +-239, -97, -213, -105, -19, -74, 161, -77, +199, -41, 109, 103, -16, 245, -114, 183, +-189, -98, -197, -331, -48, -268, 210, 41, +357, 292, 201, 270, -180, 50, -450, -152, +-309, -184, 111, -74, 414, 29, 315, 40, +-29, -20, -301, -45, -273, 37, -25, 169, +190, 192, 169, -3, -18, -293, -133, -378, +-53, -88, 123, 365, 138, 510, -81, 141, +-298, -401, -205, -547, 162, -134, 425, 397, +265, 496, -171, 113, -465, -294, -324, -357, +78, -127, 360, 112, 303, 188, 32, 149, +-191, 66, -199, -59, -86, -161, -7, -141, +4, 15, 22, 152, 95, 122, 164, -24, +106, -118, -98, -63, -268, 44, -201, 61, +43, -10, 228, -56, 192, -2, 14, 77, +-133, 66, -136, -52, -59, -149, 6, -77, +52, 110, 104, 208, 95, 85, -5, -156, +-143, -247, -196, -99, -77, 131, 129, 220, +239, 134, 143, 1, -73, -91, -229, -142, +-180, -161, 0, -94, 128, 77, 94, 229, +3, 223, -34, 45, 16, -154, 39, -211, +-14, -117, -102, 37, -101, 117, -16, 87, +45, 9, 64, -36, 74, -5, 63, 42, +-10, 29, -113, -42, -159, -92, -62, -50, +94, 44, 148, 89, 48, 50, -68, -22, +-70, -47, -5, -13, 13, 23, -34, -5, +-55, -72, 21, -75, 108, 40, 79, 185, +-59, 182, -161, -16, -114, -245, 39, -288, +137, -86, 83, 174, -28, 299, -58, 238, +-4, 62, 16, -146, -61, -324, -146, -332, +-90, -103, 111, 263, 247, 468, 161, 303, +-64, -98, -217, -387, -206, -345, -89, -64, +33, 178, 123, 235, 181, 158, 171, 52, +22, -54, -201, -159, -298, -192, -166, -85, +84, 123, 242, 232, 199, 112, 22, -112, +-113, -176, -127, 4, -65, 187, -26, 106, +-22, -187, -12, -342, 51, -107, 110, 320, +88, 491, -20, 194, -117, -297, -122, -506, +-31, -265, 49, 168, 32, 369, -23, 204, +-5, -77, 91, -160, 126, -1, 11, 119, +-196, -3, -286, -219, -104, -218, 217, 69, +368, 325, 188, 251, -157, -62, -373, -255, +-278, -158, 20, 21, 260, 42, 276, -19, +119, 47, -80, 219, -233, 211, -257, -101, +-124, -419, 112, -345, 296, 117, 259, 488, +-12, 379, -285, -92, -309, -419, -70, -293, +198, 78, 250, 279, 65, 149, -138, -78, +-162, -133, -43, -10, 68, 81, 62, 25, +-17, -90, -45, -96, 12, 33, 58, 171, +8, 164, -81, -7, -124, -209, -56, -269, +94, -94, 185, 189, 109, 330, -87, 179, +-222, -115, -177, -255, 19, -131, 188, 63, +167, 81, -10, -42, -138, -76, -107, 75, +17, 214, 86, 122, 30, -123, -74, -263, +-89, -156, -15, 85, 69, 206, 99, 143, +44, 1, -44, -102, -117, -126, -115, -100, +-36, -13, 83, 111, 153, 200, 99, 141, +-47, -59, -164, -248, -166, -248, -39, -36, +124, 207, 186, 263, 89, 106, -67, -102, +-163, -174, -147, -89, -34, 32, 88, 80, +120, 39, 61, -30, -18, -72, -79, -37, +-75, 60, 3, 137, 55, 107, 22, -55, +-48, -207, -80, -183, -37, 19, 46, 208, +104, 200, 66, 38, -22, -117, -98, -159, +-112, -104, -62, -17, 41, 83, 109, 184, +73, 195, -44, 12, -128, -262, -78, -344, +82, -94, 160, 301, 61, 437, -127, 152, +-238, -271, -149, -422, 80, -171, 260, 185, +230, 311, 29, 157, -202, -72, -292, -166, +-163, -113, 92, -16, 233, 48, 161, 60, +-19, 38, -130, 5, -98, 0, 6, 27, +20, 30, -59, -42, -80, -138, 33, -110, +160, 73, 133, 245, -53, 190, -229, -89, +-187, -314, 32, -231, 218, 100, 180, 346, +-30, 244, -203, -103, -178, -329, -13, -206, +126, 114, 143, 284, 60, 148, -65, -128, +-147, -232, -127, -77, -13, 148, 111, 212, +148, 64, 36, -130, -138, -196, -160, -102, +-11, 52, 147, 148, 129, 153, -31, 85, +-185, -30, -164, -163, 19, -236, 187, -143, +193, 118, 53, 349, -138, 303, -251, -49, +-177, -399, 44, -385, 240, -6, 231, 361, +18, 357, -218, 35, -238, -239, -47, -222, +179, -31, 201, 83, 16, 51, -203, -5, +-218, 30, -31, 96, 182, 70, 229, -40, +84, -136, -135, -130, -245, -30, -163, 98, +10, 164, 149, 116, 178, -19, 96, -140, +-77, -139, -171, -31, -134, 78, -9, 108, +72, 60, 94, 1, 31, -30, -14, -48, +-22, -57, -39, -39, -97, 19, -97, 69, +8, 72, 145, 28, 171, -12, 28, -30, +-148, -61, -205, -84, -87, -50, 65, 68, +136, 171, 63, 119, -35, -67, -61, -202, +12, -110, 52, 106, 18, 184, -92, 21, +-146, -182, -60, -143, 94, 108, 135, 236, +40, 61, -44, -200, -20, -201, 29, 76, +-17, 255, -137, 66, -193, -256, -14, -268, +243, 96, 293, 398, 21, 245, -275, -214, +-305, -448, -30, -182, 251, 268, 238, 398, +-35, 96, -251, -253, -171, -284, 74, -29, +196, 187, 77, 154, -94, -11, -115, -90, +0, -30, 64, 36, 0, 23, -115, -29, +-99, -38, 49, -6, 177, 23, 113, 31, +-45, 31, -160, 21, -167, -20, -60, -72, +95, -73, 191, 23, 128, 133, -24, 133, +-202, -19, -232, -205, -66, -227, 186, -26, +262, 252, 122, 343, -122, 129, -266, -232, +-218, -420, 17, -245, 224, 158, 236, 432, +49, 311, -187, -83, -264, -379, -109, -305, +156, 51, 268, 315, 132, 251, -158, -33, +-311, -223, -190, -172, 106, -6, 282, 89, +222, 76, -23, 68, -210, 94, -206, 45, +-65, -119, 27, -248, 64, -150, 81, 135, +93, 311, 79, 181, 6, -106, -116, -240, +-217, -114, -157, 72, 19, 97, 170, -7, +194, -53, 105, 30, -46, 129, -134, 94, +-128, -53, -94, -170, -90, -143, -42, -12, +95, 109, 254, 144, 265, 93, 44, 18, +-283, -34, -431, -76, -238, -125, 124, -138, +360, -57, 287, 122, 44, 275, -129, 230, +-163, -30, -138, -300, -114, -338, -54, -89, +62, 235, 210, 335, 210, 141, -15, -140, +-241, -253, -212, -118, 29, 92, 207, 174, +118, 76, -133, -83, -262, -148, -63, -64, +225, 103, 263, 204, 14, 121, -244, -109, +-246, -295, -9, -226, 218, 85, 180, 353, +-50, 287, -216, -45, -146, -286, 65, -204, +176, 56, 88, 143, -68, -10, -123, -141, +-32, -13, 37, 234, 21, 254, -74, -10, +-76, -276, 40, -262, 136, -39, 84, 118, +-58, 110, -138, 56, -90, 84, 30, 124, +85, 27, 8, -169, -80, -255, -42, -119, +64, 114, 95, 222, 13, 137, -103, -12, +-155, -72, -46, -52, 116, -25, 160, -32, +37, -32, -131, 4, -195, 44, -91, 58, +112, 52, 221, 37, 127, -10, -106, -88, +-253, -141, -155, -78, 83, 88, 226, 220, +115, 177, -107, -33, -206, -232, -69, -242, +132, -63, 159, 153, -4, 248, -140, 168, +-120, -16, -7, -170, 71, -203, 67, -92, +-7, 78, -23, 170, 7, 111, 2, -37, +-44, -123, -51, -63, -2, 60, 29, 101, +24, 18, -23, -79, -33, -81, 15, 10, +64, 66, 11, 17, -99, -50, -128, -21, +5, 73, 155, 112, 160, 23, -26, -120, +-202, -171, -208, -75, -13, 82, 182, 181, +206, 159, 46, 30, -121, -132, -159, -218, +-91, -138, 5, 72, 51, 245, 35, 206, +30, -32, 77, -251, 87, -228, -29, 17, +-177, 237, -195, 215, -44, -19, 174, -213, +248, -180, 84, 26, -160, 170, -218, 122, +-83, -29, 78, -114, 130, -62, 61, 42, +-22, 65, -45, 4, -45, -55, -59, -47, +-74, 25, 12, 85, 141, 70, 167, -18, +1, -115, -215, -121, -249, -15, -24, 119, +240, 153, 279, 47, 23, -90, -260, -144, +-271, -78, 7, 27, 237, 96, 193, 99, +-41, 43, -216, -36, -152, -95, 61, -79, +188, -7, 84, 55, -85, 53, -132, 22, +-38, 17, 54, 37, 49, 3, -37, -91, +-70, -137, 33, -47, 143, 126, 74, 193, +-108, 80, -216, -100, -109, -160, 84, -68, +192, 26, 105, 39, -46, 15, -88, 51, +-14, 109, 36, 66, -49, -97, -144, -233, +-96, -153, 84, 102, 220, 283, 172, 198, +-26, -69, -201, -247, -199, -168, -42, 52, +92, 165, 96, 82, 31, -73, -11, -112, +-11, 9, 16, 142, 15, 120, -48, -42, +-86, -182, -43, -148, 27, 32, 71, 161, +67, 128, -3, -9, -83, -98, -86, -68, +0, 0, 93, 25, 102, 11, 25, 26, +-98, 51, -153, 10, -107, -92, 33, -135, +156, -19, 194, 162, 79, 210, -113, 43, +-277, -177, -229, -212, 26, -30, 290, 172, +293, 171, 25, -21, -280, -174, -342, -125, +-68, 73, 284, 201, 357, 139, 46, -50, +-304, -194, -371, -169, -76, -10, 277, 154, +373, 186, 86, 62, -249, -112, -331, -175, +-109, -52, 147, 117, 241, 154, 119, 32, +-55, -103, -131, -104, -101, -18, -58, 17, +-32, -23, 43, -5, 148, 127, 181, 218, +25, 83, -201, -223, -297, -379, -108, -188, +198, 197, 341, 407, 142, 253, -185, -85, +-318, -285, -144, -217, 114, -11, 218, 119, +123, 122, -61, 79, -124, 27, -63, -21, +4, -93, -14, -128, -30, -64, 24, 72, +108, 183, 111, 154, 3, -3, -164, -172, +-205, -217, -59, -81, 148, 125, 220, 233, +91, 142, -96, -80, -188, -217, -102, -136, +49, 82, 125, 201, 45, 93, -49, -109, +-62, -172, 32, -45, 73, 98, 10, 96, +-110, -6, -121, -36, 8, 44, 159, 78, +141, -40, -26, -192, -147, -143, -108, 102, +20, 266, 69, 140, 36, -154, -32, -263, +5, -64, 75, 214, 70, 241, -79, -19, +-176, -262, -101, -233, 89, 44, 176, 267, +99, 224, -81, 2, -143, -178, -29, -167, +109, -39, 67, 57, -110, 51, -178, 3, +-25, 17, 221, 87, 266, 107, 50, 1, +-260, -169, -330, -223, -119, -73, 186, 162, +289, 254, 176, 121, -20, -87, -140, -176, +-176, -101, -137, -5, -60, 21, 63, 31, +197, 91, 229, 131, 71, 29, -173, -165, +-261, -223, -130, -27, 90, 231, 179, 228, +87, -54, -67, -275, -74, -158, 50, 158, +109, 273, -6, 44, -152, -243, -140, -228, +23, 61, 165, 265, 118, 158, -48, -107, +-139, -220, -33, -88, 108, 86, 124, 110, +-32, 22, -161, -36, -133, -11, 30, 31, +161, 25, 144, -22, -8, -66, -126, -81, +-92, -35, 19, 79, 85, 165, 40, 106, +-49, -93, -98, -236, -22, -131, 86, 141, +122, 266, 31, 71, -74, -225, -108, -265, +-42, 23, 43, 309, 73, 237, 12, -113, +-50, -334, -18, -183, 62, 158, 82, 283, +-5, 83, -112, -167, -133, -173, -9, 29, +131, 149, 166, 45, 32, -117, -112, -105, +-152, 65, -57, 151, 65, 31, 127, -139, +71, -126, -32, 49, -87, 169, -55, 86, +9, -113, 36, -181, 29, -53, 16, 126, +9, 180, 3, 54, -13, -104, -59, -150, +-53, -63, 21, 56, 93, 93, 67, 48, +-29, -7, -86, -3, -56, 23, 33, -11, +77, -100, 27, -140, -61, -22, -64, 170, +16, 243, 80, 91, 49, -166, -27, -274, +-76, -135, -39, 106, 27, 215, 49, 112, +2, -53, -39, -109, 12, -40, 85, 32, +70, 25, -46, -38, -135, -63, -127, -3, +14, 66, 151, 84, 168, 34, 43, -43, +-75, -87, -130, -63, -99, 9, -33, 67, +47, 54, 89, -9, 89, -43, 53, 2, +-12, 60, -87, 36, -106, -74, -29, -138, +62, -43, 93, 115, 38, 163, -42, 48, +-74, -104, -5, -131, 81, -41, 78, 57, +-21, 64, -99, 20, -89, -2, -10, -11, +75, -29, 100, -35, 57, 7, -25, 73, +-71, 69, -68, -27, -17, -122, 26, -83, +39, 52, 6, 116, -17, 51, 13, -56, +70, -48, 58, 48, -28, 71, -130, -49, +-155, -174, -41, -111, 151, 113, 250, 273, +140, 169, -93, -109, -264, -290, -211, -214, +2, 41, 213, 227, 219, 210, 48, 39, +-128, -135, -138, -177, -25, -80, 73, 66, +63, 132, -38, 72, -97, -38, -25, -90, +120, -35, 153, 38, 34, 41, -143, -9, +-187, -38, -74, 10, 117, 65, 187, 44, +98, -44, -66, -105, -135, -65, -95, 34, +0, 104, 85, 87, 112, 9, 55, -56, +-49, -91, -104, -78, -79, -10, 22, 88, +100, 146, 89, 76, -26, -90, -107, -212, +-73, -143, 56, 89, 134, 267, 97, 213, +-43, -57, -156, -295, -143, -280, 3, -26, +151, 242, 173, 291, 73, 103, -78, -132, +-161, -214, -130, -96, -6, 62, 85, 109, +102, 18, 61, -67, 20, -38, -9, 54, +-37, 98, -78, 29, -100, -63, -33, -84, +101, -21, 170, 35, 77, 12, -86, -22, +-161, 3, -66, 67, 68, 66, 113, -30, +10, -107, -83, -61, -62, 72, 59, 135, +101, 41, 22, -102, -80, -140, -92, -32, +-25, 81, 47, 85, 68, 25, 42, 3, +16, 37, 3, 23, -30, -73, -86, -156, +-70, -105, 19, 59, 119, 176, 99, 154, +-3, 31, -111, -76, -111, -104, -15, -80, +84, -37, 95, 18, 36, 66, -8, 73, +-47, 24, -83, -33, -97, -50, -9, -25, +134, 18, 226, 35, 126, 28, -127, -2, +-333, -50, -250, -77, 73, -47, 362, 48, +334, 115, 30, 84, -280, -28, -319, -99, +-89, -47, 168, 39, 221, 35, 79, -65, +-58, -106, -83, 4, -21, 151, 9, 163, +-1, -9, -27, -158, -2, -119, 52, 30, +52, 103, -21, 10, -66, -104, -25, -82, +51, 59, 81, 158, 18, 117, -67, -2, +-94, -106, -18, -156, 60, -149, 84, -54, +36, 137, -2, 285, -22, 211, -31, -80, +-48, -339, -33, -296, 1, 28, 56, 312, +80, 290, 40, 8, -24, -238, -60, -234, +-42, -28, -27, 150, -1, 154, 19, 35, +56, -73, 58, -73, 39, -2, -35, 49, +-99, 15, -91, -70, 19, -89, 118, 2, +132, 127, 35, 141, -97, 4, -153, -161, +-78, -177, 67, -15, 155, 153, 136, 156, +25, 12, -104, -118, -177, -118, -119, -37, +31, 42, 171, 87, 180, 103, 61, 65, +-95, -67, -164, -196, -103, -170, 24, 49, +97, 264, 72, 216, 22, -56, -10, -264, +-1, -177, -7, 93, -32, 215, -54, 53, +-9, -161, 65, -142, 96, 75, 1, 206, +-98, 68, -93, -171, 24, -205, 131, 1, +110, 210, -29, 177, -137, -54, -109, -204, +-1, -132, 84, 61, 84, 167, 52, 110, +6, -18, -27, -109, -60, -111, -57, -48, +-33, 47, 15, 114, 62, 87, 75, -3, +32, -76, -24, -70, -47, -16, -48, 12, +-16, -6, 21, -6, 48, 50, 30, 93, +9, 37, -11, -84, -23, -140, -25, -66, +10, 53, 39, 98, 41, 64, 4, 19, +-52, 11, -90, -21, -37, -95, 88, -127, +171, -33, 101, 125, -84, 161, -219, 32, +-166, -115, 65, -103, 222, 48, 153, 118, +-62, 4, -157, -144, -62, -104, 88, 84, +84, 180, -55, 57, -142, -135, -48, -142, +136, 37, 197, 177, 58, 97, -134, -117, +-186, -215, -77, -101, 78, 92, 149, 191, +108, 138, 3, 5, -83, -109, -110, -157, +-69, -110, 21, 12, 119, 143, 124, 167, +14, 46, -118, -113, -152, -163, -45, -57, +100, 89, 159, 145, 74, 62, -48, -67, +-112, -121, -71, -77, -15, 25, 35, 82, +58, 69, 70, 8, 41, -37, -26, -27, +-86, 0, -67, 5, 25, -19, 94, -21, +61, 2, -47, 3, -102, -26, -25, -37, +106, 49, 131, 168, 16, 144, -144, -81, +-168, -326, -21, -294, 161, 48, 179, 385, +34, 373, -114, 21, -130, -305, -24, -317, +70, -74, 58, 133, -14, 135, -21, 53, +35, 41, 62, 76, -4, 10, -79, -157, +-90, -217, -9, -56, 84, 185, 107, 251, +46, 72, -29, -145, -82, -184, -95, -57, +-52, 46, 34, 53, 131, 33, 150, 61, +42, 79, -124, -7, -194, -138, -98, -158, +87, -10, 182, 158, 110, 160, -50, 8, +-118, -129, -50, -118, 45, 4, 55, 94, +-9, 79, -54, 0, -30, -61, 35, -76, +62, -50, 34, 22, -4, 95, -13, 111, +-23, 36, -40, -79, -62, -130, -37, -85, +43, 17, 129, 92, 134, 98, 20, 56, +-132, -22, -191, -95, -93, -101, 80, -13, +183, 101, 122, 118, -16, -4, -105, -133, +-80, -110, -9, 55, 14, 176, -19, 106, +-9, -91, 54, -178, 105, -74, 64, 82, +-63, 116, -152, 16, -92, -54, 61, -4, +140, 75, 74, 30, -55, -106, -106, -147, +-32, -4, 70, 185, 77, 189, -11, -15, +-85, -214, -57, -197, 36, 21, 92, 215, +50, 194, -32, -11, -75, -187, -41, -180, +26, -25, 59, 127, 39, 153, -14, 57, +-36, -52, -25, -88, -4, -51, -2, -8, +4, 9, 26, 24, 56, 51, 36, 62, +-30, -4, -91, -94, -82, -87, 11, 24, +114, 121, 122, 82, 28, -66, -75, -155, +-103, -75, -56, 87, 14, 144, 57, 59, +68, -57, 56, -83, 9, -29, -54, 1, +-87, -17, -46, -12, 46, 43, 104, 80, +58, 37, -44, -50, -92, -89, -46, -31, +44, 45, 91, 45, 47, 3, -36, -19, +-76, 3, -59, 15, -5, -9, 48, -29, +84, -6, 69, 44, 5, 47, -83, -10, +-119, -66, -65, -52, 48, 8, 136, 39, +129, 29, 31, 25, -91, 37, -153, 16, +-112, -65, 17, -122, 141, -60, 169, 83, +51, 166, -103, 73, -156, -86, -64, -140, +78, -46, 117, 63, 23, 63, -74, -8, +-47, -30, 51, 26, 85, 54, -8, -1, +-120, -72, -99, -67, 58, 13, 184, 56, +120, 30, -83, -10, -202, -7, -122, 19, +84, 5, 194, -30, 105, -37, -72, -8, +-143, 21, -55, 23, 68, 19, 77, 33, +-21, 19, -82, -37, -19, -81, 108, -41, +133, 56, -7, 97, -182, 19, -180, -89, +17, -73, 214, 55, 201, 124, -2, 25, +-189, -130, -182, -133, -6, 23, 138, 156, +116, 101, 11, -68, -41, -127, -15, -22, +9, 87, -34, 48, -77, -84, -21, -111, +105, 32, 151, 172, 35, 116, -134, -88, +-175, -199, -29, -106, 151, 84, 172, 167, +21, 76, -140, -51, -147, -91, -2, -43, +131, 0, 125, 12, 5, 6, -88, 10, +-85, 29, -13, 40, 41, 28, 40, -18, +9, -80, 2, -102, 11, -25, 2, 113, +-34, 182, -51, 89, -5, -97, 64, -199, +78, -130, -4, 10, -91, 88, -74, 98, +51, 110, 140, 108, 76, 5, -92, -190, +-177, -289, -83, -128, 109, 186, 194, 342, +88, 181, -83, -123, -141, -256, -54, -130, +54, 56, 76, 96, 13, 9, -33, -37, +-12, 16, 40, 60, 43, 18, 0, -47, +-36, -23, -42, 61, -37, 51, -24, -91, +11, -193, 76, -73, 119, 188, 78, 298, +-52, 109, -180, -199, -171, -313, -8, -133, +183, 127, 227, 221, 84, 117, -125, -27, +-206, -90, -109, -70, 65, -50, 146, -35, +79, 17, -34, 89, -63, 105, 3, 30, +49, -77, 9, -139, -74, -95, -77, 29, +34, 133, 141, 136, 100, 34, -56, -95, +-171, -138, -111, -61, 54, 56, 170, 85, +127, 27, -13, -23, -118, -3, -126, 36, +-60, 7, 29, -68, 109, -79, 135, 15, +84, 106, -42, 69, -150, -66, -153, -132, +-34, -36, 110, 115, 160, 153, 90, 26, +-15, -131, -95, -162, -108, -48, -61, 89, +34, 138, 110, 85, 105, -18, 2, -103, +-114, -123, -124, -41, 5, 89, 153, 157, +145, 84, -17, -84, -174, -187, -167, -117, +-6, 60, 157, 171, 175, 130, 63, 7, +-62, -80, -117, -100, -109, -93, -65, -61, +14, 28, 110, 147, 164, 177, 106, 45, +-46, -151, -179, -213, -169, -71, -19, 119, +139, 164, 160, 53, 57, -75, -65, -94, +-100, -37, -42, 9, 36, 22, 53, 47, +8, 77, -22, 39, -11, -66, 15, -147, +24, -108, 10, 32, -7, 145, -12, 147, +-11, 50, -19, -62, -15, -127, 37, -118, +89, -39, 64, 49, -54, 86, -162, 59, +-122, 11, 74, 0, 253, 17, 199, 3, +-69, -77, -293, -142, -241, -76, 41, 91, +276, 210, 237, 144, -12, -53, -215, -190, +-176, -143, 24, 22, 162, 120, 109, 72, +-42, -30, -134, -49, -87, 14, 46, 47, +144, -10, 122, -71, 1, -40, -121, 62, +-161, 96, -81, 1, 65, -118, 180, -111, +155, 32, 14, 154, -136, 119, -174, -40, +-79, -148, 79, -106, 170, 27, 108, 110, +-45, 62, -138, -48, -83, -86, 54, -2, +138, 94, 69, 75, -89, -55, -152, -146, +-38, -68, 128, 105, 156, 167, 12, 26, +-140, -160, -131, -154, 25, 58, 143, 220, +86, 124, -65, -134, -122, -247, -26, -83, +92, 160, 96, 203, -15, 22, -98, -150, +-60, -112, 51, 63, 105, 138, 41, 30, +-60, -123, -93, -135, -53, 2, 17, 122, +72, 106, 89, 1, 64, -62, -2, -22, +-86, 28, -132, -3, -99, -75, 23, -97, +147, -7, 174, 121, 91, 162, -53, 69, +-173, -80, -187, -166, -76, -123, 85, 5, +207, 107, 201, 113, 57, 32, -142, -52, +-244, -69, -161, -14, 42, 45, 207, 46, +208, -16, 57, -72, -139, -54, -206, 17, +-93, 76, 93, 62, 182, -1, 108, -59, +-42, -69, -136, -15, -103, 49, 14, 57, +89, 2, 78, -57, 30, -54, -18, 15, +-49, 65, -55, 39, -29, -23, 16, -32, +46, 22, 48, 35, 3, -29, -37, -102, +-16, -67, 27, 72, 25, 169, -27, 102, +-62, -60, -36, -154, 35, -110, 87, -7, +71, 60, 6, 76, -49, 80, -71, 61, +-65, -24, -45, -127, 24, -148, 115, -19, +138, 151, 50, 176, -91, 22, -166, -150, +-100, -157, 44, -2, 135, 120, 98, 85, +-3, -37, -58, -81, -34, -2, 10, 89, +24, 58, -11, -61, -62, -128, -58, -71, +24, 46, 112, 123, 130, 102, 45, 22, +-102, -60, -177, -116, -107, -102, 58, -27, +163, 71, 112, 120, -17, 84, -91, 15, +-60, -39, 18, -70, 32, -88, -22, -78, +-52, 8, 6, 123, 89, 152, 79, 37, +-15, -130, -93, -164, -78, -24, 21, 126, +92, 125, 63, -19, -20, -126, -71, -76, +-39, 35, 24, 70, 47, 26, 27, -8, +-4, 19, -13, 38, -3, -20, -9, -108, +-30, -111, -25, 13, 17, 150, 57, 151, +55, 7, 4, -135, -57, -137, -63, -15, +-11, 104, 43, 99, 37, 2, -18, -74, +-37, -61, 12, 5, 70, 50, 47, 43, +-45, 7, -108, -13, -55, -17, 69, -32, +120, -53, 42, -46, -65, 22, -87, 122, +-5, 138, 64, 17, 44, -164, -29, -226, +-53, -75, 2, 171, 51, 274, 27, 113, +-35, -152, -49, -254, 6, -109, 54, 113, +36, 185, -30, 78, -57, -62, -9, -98, +43, -37, 37, 12, -18, 14, -45, 12, +-10, 34, 39, 47, 36, 16, -17, -37, +-56, -65, -35, -47, 28, 3, 74, 51, +45, 79, -29, 51, -73, -31, -54, -102, +12, -82, 64, 32, 56, 119, -1, 75, +-47, -57, -35, -121, 1, -34, 13, 96, +0, 111, -3, -12, 15, -117, 39, -85, +27, 34, -22, 87, -56, 37, -31, -32, +31, -34, 56, 6, 29, 1, -23, -40, +-46, -37, -23, 45, 17, 111, 37, 55, +23, -78, -7, -138, -36, -54, -50, 79, +-25, 112, 43, 30, 87, -41, 61, -27, +-32, 25, -114, 5, -99, -63, 0, -75, +97, 8, 108, 103, 35, 112, -49, 23, +-66, -83, -51, -100, -28, -52, 1, 16, +41, 66, 80, 79, 71, 40, -3, -44, +-98, -94, -119, -58, -42, 48, 74, 107, +131, 58, 77, -51, -23, -107, -92, -56, +-82, 24, -21, 55, 37, 36, 60, 17, +51, 25, 27, 15, -2, -42, -49, -92, +-85, -69, -65, 22, 25, 96, 125, 87, +139, 9, 23, -49, -140, -51, -185, -21, +-65, -4, 117, -18, 190, -12, 103, 31, +-61, 86, -158, 83, -119, -16, -21, -133, +55, -149, 113, -22, 135, 151, 72, 206, +-71, 59, -200, -162, -190, -233, -4, -83, +209, 136, 246, 202, 70, 78, -140, -76, +-191, -103, -93, -27, 25, -1, 71, -54, +66, -61, 65, 66, 64, 199, -9, 141, +-121, -109, -134, -278, -16, -147, 134, 139, +151, 254, 12, 65, -136, -178, -129, -170, +15, 63, 129, 206, 100, 66, -27, -170, +-102, -196, -57, 22, 38, 204, 71, 135, +6, -87, -61, -194, -39, -71, 43, 120, +85, 159, 42, 29, -48, -98, -100, -100, +-59, -12, 28, 42, 69, 22, 46, -14, +13, -7, -10, 46, -9, 63, -8, 10, +-27, -67, -35, -100, -2, -63, 46, 13, +44, 74, -1, 78, -31, 51, -18, 23, +13, -14, 19, -64, -11, -112, -41, -89, +-21, 27, 34, 146, 43, 147, 0, 15, +-30, -125, -19, -119, 18, 9, 37, 89, +4, 24, -44, -82, -44, -68, 2, 72, +36, 159, 32, 50, 8, -142, -6, -189, +-1, -27, -2, 171, -11, 178, -31, 9, +-23, -151, 13, -145, 18, -14, 8, 86, +12, 97, 28, 54, 22, 17, -17, -30, +-64, -89, -66, -100, 0, -29, 67, 80, +63, 124, 3, 63, -49, -29, -36, -67, +10, -40, 30, -2, 5, 8, -38, -2, +-50, -8, -8, 0, 40, 26, 74, 47, +67, 46, -10, -6, -103, -86, -118, -109, +-27, -21, 104, 105, 158, 131, 52, 20, +-114, -113, -168, -113, -54, 13, 107, 114, +157, 83, 56, -23, -83, -79, -131, -51, +-67, -8, 33, -1, 75, 9, 66, 56, +38, 95, -3, 42, -59, -75, -75, -141, +-45, -69, 11, 64, 67, 112, 71, 34, +21, -56, -30, -39, -50, 45, -40, 71, +-5, -5, 26, -92, 25, -89, 2, -6, +-6, 62, 13, 68, 23, 44, -6, 21, +-43, -19, -52, -77, -2, -103, 78, -30, +92, 99, 13, 137, -72, 21, -99, -134, +-57, -157, 31, -1, 96, 186, 86, 200, +34, 6, -46, -206, -111, -239, -96, -61, +6, 158, 111, 229, 116, 109, 9, -70, +-97, -149, -85, -94, 11, 7, 72, 46, +32, 13, -52, -7, -49, 37, 34, 86, +73, 38, 11, -90, -78, -160, -79, -66, +36, 117, 141, 189, 90, 58, -69, -143, +-171, -192, -115, -41, 50, 140, 164, 165, +125, 31, -2, -99, -96, -100, -96, -14, +-45, 41, 3, 10, 34, -21, 57, 5, +57, 51, 26, 43, -21, -21, -67, -55, +-62, -21, 4, 19, 47, 9, 40, -32, +17, -32, -13, 24, -23, 65, -17, 38, +-9, -31, 2, -51, 36, -12, 57, 24, +28, -7, -45, -60, -110, -45, -84, 37, +24, 110, 143, 89, 174, -13, 49, -103, +-136, -110, -218, -42, -135, 34, 52, 70, +203, 69, 183, 47, 23, 24, -127, -11, +-163, -73, -92, -116, 27, -83, 111, 42, +115, 165, 50, 155, -59, -1, -126, -170, +-88, -169, 29, 7, 126, 162, 90, 124, +-43, -52, -119, -142, -59, -44, 52, 114, +87, 117, 1, -39, -89, -154, -39, -74, +80, 111, 106, 166, 2, 25, -128, -137, +-142, -129, -3, 6, 142, 91, 149, 43, +31, -24, -101, 8, -135, 80, -62, 42, +39, -107, 96, -188, 71, -69, -4, 146, +-48, 216, -38, 71, -15, -114, 5, -147, +2, -34, -6, 60, 13, 40, 33, -31, +6, -31, -30, 39, -30, 81, -5, 38, +20, -48, 12, -86, -18, -50, -15, 19, +16, 65, 31, 50, 0, 3, -44, -40, +-23, -52, 31, -26, 48, 6, 10, 34, +-36, 47, -41, 44, 1, 4, 34, -82, +0, -135, -28, -75, 13, 93, 55, 223, +38, 152, -44, -84, -112, -261, -74, -185, +47, 64, 128, 223, 89, 142, -21, -52, +-99, -125, -81, -44, -22, 48, 12, 23, +20, -51, 21, -34, 52, 67, 69, 108, +7, -1, -93, -139, -122, -130, -51, 36, +70, 171, 131, 121, 62, -55, -60, -162, +-104, -92, -48, 61, 39, 127, 71, 52, +15, -59, -55, -92, -61, -26, -10, 66, +46, 93, 45, 25, 2, -77, -30, -117, +-27, -52, -3, 74, 14, 141, -6, 77, +-39, -61, -30, -139, 3, -83, 35, 44, +51, 120, 31, 85, -25, -3, -69, -78, +-84, -94, -53, -57, 32, 17, 109, 96, +109, 121, 15, 47, -98, -82, -133, -150, +-54, -99, 59, 25, 104, 112, 36, 106, +-65, 44, -78, -21, -8, -69, 57, -95, +71, -76, 9, 17, -73, 112, -92, 114, +-53, 9, 12, -102, 86, -108, 112, -3, +36, 95, -84, 77, -146, -18, -87, -73, +41, -39, 110, 20, 74, 26, -24, 0, +-77, -2, -38, 29, 14, 40, 5, -10, +-18, -78, -15, -74, 10, 10, 29, 89, +13, 75, -37, -8, -52, -67, -22, -46, +19, 7, 46, 27, 30, 5, -13, -18, +-60, 3, -69, 31, -26, 21, 39, -24, +65, -47, 25, -12, -36, 44, -68, 58, +-33, -3, 20, -69, 21, -68, -9, 7, +-26, 82, -15, 76, 10, -5, 18, -78, +-12, -67, -34, 7, -25, 60, -9, 46, +-1, -10, 6, -42, 3, -23, -1, 7, +-11, 17, -24, 15, -27, 24, -11, 13, +8, -22, 2, -60, -18, -47, -34, 42, +-14, 117, 9, 77, 17, -56, -7, -139, +-48, -81, -54, 57, -1, 123, 47, 58, +44, -52, -4, -77, -64, -13, -78, 33, +-26, -4, 43, -55, 57, -11, 18, 90, +-33, 112, -52, -13, -40, -162, -20, -153, +-4, 30, 7, 191, 23, 154, 30, -37, +-11, -164, -71, -107, -78, 41, -28, 112, +40, 48, 70, -46, 27, -61, -50, -7, +-80, 37, -61, 41, -16, 21, 30, -3, +36, -28, 18, -61, -11, -59, -44, 9, +-52, 94, -29, 109, -2, 29, 19, -92, +9, -132, -34, -55, -34, 53, 4, 110, +31, 70, 15, -19, -46, -73, -97, -55, +-58, -2, 40, 30, 94, 14, 50, -12, +-61, 4, -119, 41, -76, 49, 17, -16, +69, -92, 34, -87, -29, 15, -64, 119, +-58, 113, -35, 2, 4, -100, 45, -92, +43, -6, 1, 44, -69, 21, -116, -5, +-75, 24, 25, 69, 79, 42, 70, -68, +10, -142, -51, -82, -83, 73, -78, 158, +-47, 81, 3, -66, 50, -133, 62, -63, +21, 59, -38, 107, -78, 46, -70, -53, +-36, -95, -8, -45, 9, 38, 15, 81, +15, 55, 9, -11, -11, -50, -36, -45, +-53, -21, -65, -6, -45, -3, 7, 19, +54, 65, 57, 65, 1, -5, -81, -96, +-99, -109, -49, -8, 23, 97, 57, 94, +15, -2, -56, -69, -75, -35, -47, 43, +-3, 49, 31, -29, 20, -83, -3, -36, +-33, 71, -58, 104, -72, 21, -45, -85, +4, -98, 44, -12, 51, 74, 18, 72, +-46, 6, -90, -41, -96, -34, -57, -5, +4, -1, 58, -18, 69, -11, 24, 37, +-37, 73, -81, 46, -102, -38, -82, -108, +-22, -98, 43, 3, 76, 112, 57, 126, +-10, 35, -90, -72, -114, -98, -91, -36, +-32, 25, 40, 16, 76, -19, 65, -4, +6, 72, -88, 104, -146, 17, -115, -125, +3, -168, 113, -46, 119, 122, -3, 165, +-147, 51, -175, -78, -60, -97, 95, -26, +146, 29, 30, 14, -130, -16, -182, 12, +-91, 60, 55, 47, 120, -39, 69, -97, +-48, -46, -124, 63, -117, 105, -52, 27, +24, -84, 74, -99, 54, -3, -23, 100, +-105, 91, -113, -18, -47, -107, 42, -81, +65, 31, 2, 111, -67, 81, -85, -21, +-54, -105, 6, -100, 27, -7, 5, 85, +-17, 104, -35, 40, -44, -51, -59, -88, +-46, -63, -14, -2, 19, 54, 34, 67, +-2, 50, -61, 3, -84, -50, -66, -81, +-6, -57, 26, 21, 20, 86, -27, 86, +-60, 14, -46, -65, -7, -84, 8, -28, +-19, 33, -63, 51, -71, 22, -20, -17, +36, -20, 42, 8, -17, 31, -78, 15, +-104, -24, -60, -54, 12, -47, 56, 11, +45, 71, -18, 74, -97, 17, -110, -56, +-62, -76, 21, -35, 71, 18, 40, 41, +-50, 30, -107, 15, -85, 6, -23, -13, +36, -44, 37, -44, -19, 8, -64, 65, +-61, 49, -30, -33, 0, -89, -1, -36, +-25, 76, -49, 106, -41, 10, -21, -112, +-6, -112, 0, 16, -12, 126, -37, 93, +-57, -29, -66, -101, -38, -55, 4, 34, +36, 52, 7, 3, -64, -18, -97, 24, +-67, 65, 13, 17, 62, -89, 8, -129, +-85, -37, -114, 108, -52, 159, 47, 62, +77, -82, 15, -138, -87, -68, -120, 39, +-89, 71, -21, 13, 42, -33, 56, 12, +27, 87, -32, 82, -113, -42, -147, -174, +-91, -155, 35, 32, 127, 209, 87, 208, +-61, 18, -183, -180, -158, -197, -6, -45, +108, 114, 83, 133, -39, 40, -132, -43, +-105, -46, -14, -10, 50, -10, 19, -34, +-36, -15, -61, 46, -49, 79, -27, 25, +-20, -75, -31, -105, -15, -21, 0, 99, +-6, 120, -49, 24, -79, -101, -60, -137, +-8, -42, 44, 90, 20, 143, -49, 68, +-100, -59, -86, -129, -16, -80, 47, 29, +45, 88, -20, 60, -93, -5, -99, -34, +-53, -16, 11, 0, 35, -20, 2, -28, +-34, 6, -46, 64, -54, 66, -55, -9, +-54, -88, -23, -80, 15, 10, 31, 90, +-7, 72, -60, -9, -68, -49, -49, -27, +-38, 4, -39, -19, -31, -51, 9, -13, +66, 82, 44, 133, -73, 53, -184, -105, +-155, -184, -13, -97, 127, 85, 130, 182, +-3, 114, -133, -36, -148, -129, -70, -102, +16, -11, 34, 55, 6, 61, -25, 32, +-26, 6, -25, -19, -47, -39, -60, -39, +-52, -7, -26, 45, 2, 64, 10, 17, +-6, -57, -28, -83, -51, -23, -66, 69, +-64, 104, -18, 37, 11, -69, 16, -114, +-8, -57, -47, 51, -66, 116, -51, 80, +-36, -20, -28, -96, -14, -92, 17, -23, +25, 57, -9, 94, -86, 63, -140, -11, +-90, -71, 31, -79, 116, -24, 83, 43, +-55, 70, -172, 30, -149, -33, -23, -52, +93, -18, 88, 28, -4, 34, -108, -4, +-115, -41, -44, -25, 18, 21, 32, 42, +0, 23, -48, -17, -71, -39, -61, -31, +-21, -7, 5, 28, 15, 56, 7, 45, +-44, -6, -80, -76, -77, -99, -31, -37, +26, 75, 41, 134, -8, 83, -71, -36, +-86, -119, -42, -104, 2, -16, 13, 62, +-30, 81, -54, 49, -23, 5, 11, -25, +4, -47, -45, -57, -90, -30, -72, 23, +5, 64, 62, 58, 33, 3, -49, -53, +-99, -63, -92, -14, -21, 40, 30, 52, +26, 8, -16, -32, -48, -30, -48, 7, +-42, 38, -42, 18, -34, -37, -16, -54, +28, -7, 26, 64, -40, 81, -99, 9, +-101, -70, -31, -82, 58, -18, 62, 54, +-19, 61, -97, 13, -85, -28, -19, -21, +24, 13, 2, 15, -56, -21, -60, -45, +-6, -27, 35, 29, 5, 70, -58, 54, +-93, -4, -61, -62, -4, -69, 24, -29, +4, 27, -11, 62, -16, 47, -25, 3, +-50, -38, -78, -46, -77, -15, -18, 20, +55, 35, 71, 21, 4, -6, -82, -34, +-121, -43, -81, -8, 3, 47, 47, 73, +32, 40, -26, -42, -55, -113, -50, -85, +-29, 21, -22, 118, -23, 118, -8, 23, +6, -77, -18, -106, -50, -66, -72, -6, +-50, 54, 18, 85, 64, 83, 25, 36, +-58, -54, -121, -126, -101, -117, -22, -5, +61, 116, 77, 152, 6, 76, -62, -65, +-101, -147, -77, -107, -20, 21, 16, 122, +11, 104, -12, -6, -25, -96, -18, -77, +-5, 23, -8, 84, -54, 37, -80, -59, +-50, -89, 18, -2, 63, 99, 34, 90, +-53, -26, -113, -122, -78, -93, 15, 31, +65, 122, 33, 84, -53, -26, -103, -87, +-64, -58, 11, -1, 56, 25, 26, 18, +-34, 13, -74, 32, -66, 40, -31, -2, +-2, -64, 4, -74, 2, -15, -10, 58, +-15, 82, -21, 29, -30, -47, -35, -67, +-38, -20, -33, 36, -23, 49, -3, 6, +22, -40, 13, -30, -4, 11, -48, 42, +-84, 19, -67, -23, -29, -29, 30, -5, +66, 11, 40, 7, -33, -7, -89, 1, +-89, 23, -45, 19, 11, -22, 38, -54, +17, -24, -3, 45, -22, 78, -52, 30, +-65, -60, -47, -83, -4, -16, 35, 64, +31, 67, -21, -6, -73, -62, -57, -37, +5, 33, 34, 55, 11, -1, -43, -63, +-62, -49, -28, 30, 17, 79, 11, 40, +-28, -48, -40, -83, -5, -35, 27, 45, +10, 71, -60, 25, -85, -43, -32, -60, +41, -15, 67, 31, 9, 36, -65, 1, +-76, -29, -21, -23, 17, 9, 0, 29, +-30, 25, -42, 2, -11, -25, 34, -43, +18, -28, -35, 9, -62, 56, -38, 68, +-6, 23, 3, -55, -7, -99, -24, -61, +-6, 30, 24, 104, 16, 89, -43, 15, +-89, -59, -74, -82, -8, -54, 64, -11, +81, 28, 23, 63, -54, 76, -95, 50, +-87, -30, -34, -110, 28, -113, 61, -20, +56, 98, 2, 140, -67, 74, -101, -45, +-78, -113, -1, -97, 71, -17, 81, 56, +15, 81, -67, 55, -101, 2, -83, -47, +-6, -63, 64, -31, 73, 29, 18, 59, +-41, 24, -79, -34, -84, -52, -26, -13, +39, 46, 59, 58, 36, 7, -17, -48, +-69, -54, -73, -9, -26, 36, 17, 39, +24, 8, 11, -17, -11, -12, -18, 4, +-9, 10, -13, -3, -40, -24, -40, -31, +-7, -9, 37, 32, 55, 55, 5, 41, +-62, -17, -89, -74, -51, -72, 16, -10, +58, 64, 48, 91, 2, 44, -24, -30, +-48, -74, -68, -72, -52, -37, -2, 16, +58, 72, 86, 94, 47, 60, -59, -29, +-128, -122, -90, -130, 2, -28, 70, 109, +64, 164, 12, 78, -33, -73, -35, -155, +-19, -94, -33, 42, -34, 114, -8, 75, +26, -24, 41, -85, 17, -55, -31, 22, +-54, 63, -24, 41, 10, -10, 17, -39, +-2, -38, -24, -23, -14, -8, 4, 22, +4, 54, -9, 55, -11, 14, -6, -45, +-9, -75, -14, -44, -36, 14, -31, 49, +10, 53, 51, 33, 44, 6, -10, -30, +-56, -64, -76, -66, -31, -18, 35, 64, +54, 104, 27, 54, -12, -41, -31, -101, +-35, -73, -26, 14, -5, 66, 8, 54, +22, 9, 27, -26, 2, -26, -43, -14, +-46, -17, -6, -19, 46, -4, 55, 30, +-3, 49, -71, 34, -86, -16, -20, -60, +65, -62, 90, -21, 32, 43, -44, 73, +-68, 49, -55, -13, -23, -59, 8, -57, +22, -16, 49, 29, 65, 44, 24, 26, +-67, -3, -119, -17, -77, -14, 13, -7, +109, -13, 116, -16, 17, -3, -82, 21, +-100, 42, -46, 29, 15, -13, 61, -56, +49, -58, -1, -9, -34, 55, -33, 70, +-15, 24, 9, -45, 36, -77, 16, -38, +-23, 29, -39, 66, -35, 52, -1, -1, +32, -50, 46, -60, 20, -28, -21, 19, +-38, 46, -31, 46, -12, 18, 0, -23, +22, -50, 32, -41, 14, -3, 1, 27, +-14, 31, -27, 16, -27, -1, -1, -6, +10, -7, 2, -13, 12, -21, 10, -15, +6, 3, 6, 24, 0, 32, -24, 20, +-39, -2, -15, -27, -6, -36, 11, -31, +41, -1, 44, 50, 13, 77, -31, 48, +-69, -32, -85, -102, -27, -96, 65, -8, +113, 99, 77, 138, -27, 69, -104, -66, +-97, -153, -20, -115, 52, 6, 73, 115, +40, 132, -7, 51, -19, -54, -25, -103, +-34, -74, -34, -5, -6, 47, 45, 54, +68, 33, 40, 5, -44, -20, -98, -33, +-58, -30, 30, -6, 95, 22, 79, 37, +-9, 28, -93, -12, -94, -39, -19, -35, +56, -4, 89, 37, 58, 58, -18, 42, +-81, -14, -79, -73, -24, -82, 39, -21, +83, 68, 54, 111, -11, 58, -63, -43, +-56, -113, 4, -87, 45, 13, 34, 91, +-20, 87, -37, 12, -7, -55, 33, -63, +52, -27, 5, 11, -49, 26, -54, 26, +-4, 21, 34, 15, 31, -5, 14, -33, +-17, -41, -13, -15, 10, 26, 4, 46, +-24, 28, -28, -7, 1, -24, 18, -14, +31, 2, 11, 9, -29, -2, -21, -14, +14, -7, 27, 11, -4, 24, -40, 30, +-46, 13, 1, -18, 65, -40, 73, -47, +15, -21, -66, 30, -81, 68, -31, 65, +30, 13, 59, -56, 37, -86, 8, -52, +-19, 24, -21, 71, -19, 57, -38, 10, +-20, -26, 27, -19, 64, 0, 43, -3, +-13, -30, -62, -44, -71, -6, 1, 59, +65, 94, 54, 61, -4, -27, -36, -109, +-33, -116, -17, -36, 15, 72, 12, 131, +5, 97, 25, 1, 31, -86, -14, -105, +-62, -65, -47, 0, 3, 56, 69, 85, +89, 74, 21, 16, -61, -72, -89, -119, +-44, -74, 26, 36, 76, 127, 62, 110, +3, -10, -45, -119, -57, -113, -18, -1, +20, 103, 34, 94, 27, -8, 0, -88, +-17, -67, -17, 23, -1, 77, 7, 37, +3, -38, 8, -68, 2, -23, -4, 37, +-5, 53, -6, 27, -7, -16, 9, -34, +30, -25, 9, -12, -19, -1, -31, 19, +-24, 34, 5, 26, 38, -5, 43, -38, +10, -43, -16, -3, -37, 39, -35, 32, +0, -15, 36, -45, 40, -19, 11, 31, +-12, 46, -32, 13, -24, -34, 9, -37, +23, 5, 25, 26, 1, 1, -24, -38, +-28, -34, -1, 33, 25, 92, 34, 59, +22, -46, -16, -127, -46, -90, -36, 26, +-1, 118, 35, 101, 53, 3, 35, -72, +-12, -80, -44, -25, -47, 25, -27, 28, +19, 16, 53, 17, 49, 23, 6, 4, +-32, -34, -53, -50, -34, -31, 29, 18, +58, 57, 34, 46, -21, -5, -44, -54, +-23, -50, 20, -8, 46, 33, 17, 38, +-18, 7, -34, -23, -9, -29, 30, -10, +30, 9, 2, 16, -27, 11, -15, -3, +6, -10, 20, -10, 7, 1, -34, 18, +-29, 21, 8, 17, 33, -5, 26, -28, +-4, -27, -25, -1, -40, 31, -4, 29, +29, 1, 28, -24, 18, -15, 4, 11, +-17, 18, -45, -1, -34, -28, 2, -21, +46, 19, 79, 46, 34, 30, -54, -25, +-102, -60, -58, -38, 37, 23, 97, 62, +82, 38, -7, -11, -78, -37, -77, -24, +-12, -2, 37, 8, 40, -1, 27, 2, +14, 28, 1, 44, -21, 9, -38, -52, +-46, -73, -13, -23, 53, 59, 85, 89, +42, 34, -37, -57, -76, -94, -62, -40, +0, 43, 71, 81, 71, 43, 28, -28, +-21, -59, -48, -48, -55, -8, -28, 28, +30, 49, 55, 53, 58, 16, 21, -40, +-45, -86, -74, -65, -41, 19, 29, 89, +61, 87, 47, 8, 3, -70, -36, -77, +-33, -26, -7, 22, 7, 29, 11, 8, +19, 10, 23, 29, 21, 17, -7, -35, +-37, -87, -33, -68, -1, 29, 35, 121, +40, 108, 14, -8, -21, -122, -30, -127, +-11, -22, -1, 87, 14, 104, 27, 30, +29, -48, 11, -52, -20, -10, -42, 15, +-36, -2, 16, -19, 58, 0, 43, 45, +-4, 54, -45, 3, -49, -46, -7, -48, +38, -1, 39, 38, 8, 26, -14, -5, +-18, -11, -3, 20, 3, 36, -6, 0, +-10, -51, 4, -54, 25, 9, 26, 67, +11, 58, -22, -5, -30, -64, -5, -52, +16, 1, 18, 33, 10, 16, 7, -4, +-2, 12, -5, 29, -8, 5, -26, -54, +-13, -85, 28, -33, 45, 74, 27, 113, +-16, 39, -51, -86, -40, -136, 16, -56, +57, 67, 42, 116, 0, 44, -44, -56, +-50, -85, -16, -31, 31, 38, 53, 43, +40, -4, 2, -37, -46, -14, -63, 34, +-28, 38, 39, -3, 81, -46, 59, -46, +-17, 4, -76, 47, -62, 48, -3, 18, +57, -16, 69, -27, 20, -16, -30, -3, +-37, 9, -27, 30, -9, 40, 16, 34, +27, 6, 25, -31, 15, -43, -2, -26, +-25, 18, -28, 60, -3, 64, 15, 17, +25, -43, 22, -69, 5, -43, -6, 21, +-12, 69, -14, 60, -22, 10, -2, -50, +30, -65, 33, -37, 22, 7, -14, 42, +-35, 43, -24, 15, 4, -31, 29, -63, +20, -58, 10, -10, -2, 42, 2, 45, +6, -3, -6, -54, -15, -48, -20, 1, +4, 30, 32, 5, 33, -37, 8, -38, +-18, 10, -20, 54, -18, 27, -1, -47, +23, -83, 27, -31, 26, 53, 10, 82, +-17, 24, -37, -53, -20, -54, 17, 17, +26, 69, 18, 45, -9, -27, -24, -53, +-10, 1, 18, 74, 20, 83, -13, 20, +-25, -47, -14, -51, 15, 4, 35, 50, +17, 46, -16, 19, -34, 2, 0, 6, +21, 12, 21, -11, 2, -28, -25, -14, +-2, 26, 24, 54, 32, 28, 2, -27, +-39, -57, -33, -35, 0, 17, 54, 39, +50, 19, 6, -21, -33, -41, -49, -36, +-12, -24, 25, -16, 41, -5, 31, 16, +8, 35, -11, 11, -28, -58, -24, -106, +-14, -81, 10, 12, 48, 90, 54, 84, +18, 0, -38, -88, -57, -106, -35, -43, +16, 28, 62, 51, 49, 26, 12, -2, +-23, 2, -36, 16, -26, 8, -2, -33, +19, -58, 21, -23, 21, 56, 7, 112, +-9, 85, -14, -1, -5, -77, 0, -73, +9, -8, 11, 65, -3, 87, 2, 52, +17, 12, 19, -8, 3, -4, -20, -4, +-24, -13, -7, -5, 29, 29, 35, 61, +15, 45, -10, -1, -23, -42, -6, -39, +12, 5, 14, 34, -6, 24, -15, -12, +2, -28, 27, -15, 31, 8, -1, 7, +-39, -17, -41, -35, 7, -34, 54, -15, +57, -7, 14, -17, -41, -29, -50, -23, +-12, -9, 31, -4, 40, -13, 21, -32, +-2, -36, -22, -16, -15, 0, -10, -4, +-4, -20, 22, -23, 35, -4, 29, 19, +-1, 16, -28, -17, -39, -43, -11, -35, +36, 13, 40, 52, 29, 48, 6, 15, +-16, -14, -21, -11, -22, 3, -12, 12, +3, 6, 39, 19, 58, 58, 20, 84, +-28, 55, -70, -17, -49, -74, 23, -53, +70, 35, 74, 104, 7, 106, -49, 40, +-59, -34, -24, -60, 29, -38, 37, 7, +37, 36, 20, 48, -1, 40, -19, 9, +-37, -36, -23, -63, 6, -39, 52, 13, +55, 43, 10, 22, -33, -35, -54, -68, +-23, -46, 28, 0, 51, 21, 27, -3, +-3, -44, -11, -57, -15, -40, 5, -21, +13, -15, 7, -12, 1, -3, 3, 0, +6, -17, 3, -50, 15, -57, 14, -24, +3, 26, -7, 40, -21, 3, -5, -44, +15, -38, 36, 11, 27, 50, -7, 37, +-26, -13, -36, -38, -7, -6, 20, 50, +31, 73, 29, 44, 6, -4, 2, -35, +-16, -14, -24, 29, -17, 55, 2, 56, +44, 37, 43, 17, 24, 2, -15, 3, +-49, 14, -41, 25, -13, 24, 35, 11, +57, 1, 55, 14, 18, 30, -38, 20, +-60, -10, -47, -39, 5, -28, 58, 9, +73, 30, 33, 16, -28, -23, -50, -42, +-39, -28, -3, -11, 33, -13, 33, -27, +27, -31, 19, -11, -1, -2, -22, -30, +-31, -66, -18, -58, 14, -6, 55, 39, +52, 27, 6, -46, -38, -98, -45, -78, +-15, -3, 24, 60, 46, 51, 29, 1, +2, -41, -12, -44, -24, -21, -26, -5, +-9, 4, 25, 19, 50, 42, 52, 47, +5, 24, -54, -14, -66, -30, -20, -10, +48, 27, 77, 47, 44, 46, -20, 41, +-60, 44, -47, 38, -7, 9, 28, -30, +47, -42, 37, 6, 17, 76, -9, 105, +-40, 58, -40, -31, -6, -79, 38, -49, +64, 24, 36, 75, -23, 61, -59, -1, +-32, -45, 17, -46, 44, -20, 41, 9, +-1, 21, -23, 9, -11, -18, 8, -49, +10, -62, -4, -41, 10, 10, 13, 50, +19, 24, 14, -52, -18, -119, -22, -98, +-5, -1, 33, 83, 36, 81, 2, -16, +-22, -114, -39, -123, 0, -39, 40, 65, +43, 97, 20, 44, -29, -43, -41, -94, +-28, -78, 18, -12, 53, 67, 48, 108, +17, 86, -41, -1, -61, -90, -37, -110, +20, -30, 77, 98, 67, 164, 13, 106, +-53, -20, -65, -103, -23, -75, 22, 23, +56, 85, 36, 76, 7, 34, -3, 19, +-10, 34, -21, 21, -30, -36, -10, -78, +19, -38, 59, 66, 56, 132, 6, 80, +-42, -41, -57, -109, -20, -69, 25, 14, +53, 49, 40, 9, 0, -24, -15, -2, +-9, 27, 5, 12, -5, -57, -14, -103, +-4, -63, 25, 29, 56, 82, 33, 33, +-9, -58, -46, -96, -47, -54, 5, 11, +44, 30, 57, 1, 27, -30, -5, -29, +-23, -7, -37, 2, -12, -12, 12, -16, +38, 7, 48, 22, 25, 3, -8, -31, +-35, -37, -27, 10, 4, 56, 39, 48, +49, -8, 15, -48, -6, -27, -18, 47, +-19, 90, -2, 47, 10, -36, 26, -71, +32, -12, 24, 76, -1, 100, -32, 42, +-35, -39, 0, -63, 47, -13, 62, 51, +19, 62, -36, 15, -43, -28, -7, -19, +45, 13, 58, 28, 18, 6, -34, -24, +-38, -31, 10, -9, 43, 13, 41, 11, +9, 0, -26, 0, -16, -5, 12, -20, +23, -49, 11, -56, 1, -16, 8, 50, +15, 75, 19, 16, 3, -81, -15, -125, +-2, -69, 21, 44, 30, 105, 15, 61, +-8, -38, -11, -96, 10, -67, 34, 0, +26, 43, -3, 35, -20, 9, -7, -5, +28, -14, 45, -22, 18, -21, -8, 3, +-14, 50, -4, 64, 19, 10, 22, -63, +11, -73, 14, 1, 27, 102, 24, 116, +-3, 15, -23, -95, -22, -105, 13, -1, +56, 106, 60, 110, 18, 24, -38, -61, +-47, -67, -16, -7, 29, 43, 67, 40, +46, 14, 9, -3, -22, -7, -29, -16, +-7, -33, 21, -30, 54, 5, 49, 50, +22, 50, -13, -11, -42, -80, -21, -93, +21, -28, 64, 58, 72, 86, 30, 41, +-29, -43, -63, -97, -36, -81, 22, -16, +76, 47, 84, 63, 31, 38, -34, -3, +-67, -38, -35, -56, 23, -43, 67, -15, +70, 21, 25, 54, -12, 55, -32, 22, +-17, -34, 11, -65, 26, -46, 28, 11, +27, 58, 28, 64, 10, 32, -4, -11, +-11, -36, -4, -35, 18, -11, 31, 25, +30, 58, 11, 65, 6, 23, 7, -41, +3, -76, 7, -42, 7, 40, 24, 95, +35, 74, 31, -19, 16, -95, -10, -77, +-11, 12, 2, 84, 30, 66, 38, -6, +18, -62, 16, -50, 12, 8, 15, 35, +2, 13, -14, -29, -3, -32, 24, 7, +64, 34, 59, 16, 8, -31, -39, -53, +-49, -25, 6, 13, 66, 29, 78, 8, +41, -16, -14, -12, -29, -4, -14, -3, +13, -17, 27, -16, 29, 6, 42, 31, +40, 30, 16, -6, -22, -36, -36, -29, +-5, 11, 50, 44, 76, 35, 47, -6, +-15, -30, -39, -17, -13, 22, 35, 41, +60, 26, 36, -7, 5, -31, 0, -18, +9, 12, 21, 27, 13, 33, 10, 23, +26, 7, 43, -16, 42, -39, -4, -34, +-34, 1, -14, 60, 40, 83, 82, 33, +57, -57, -1, -117, -37, -77, -18, 39, +31, 121, 55, 93, 39, -14, 5, -102, +1, -99, 25, -23, 33, 51, 13, 60, +-11, 26, -4, -8, 36, -27, 62, -35, +45, -44, -3, -34, -23, 7, 1, 58, +36, 61, 49, 0, 23, -65, -6, -74, +3, -17, 36, 50, 44, 59, 25, 4, +-5, -38, -8, -29, 20, 8, 56, 25, +50, 6, 10, -20, -16, -10, -6, 22, +28, 39, 51, 15, 46, -22, 17, -27, +-7, 3, -2, 36, 12, 31, 31, -2, +44, -21, 41, -8, 29, 19, 7, 29, +-14, 17, -13, -5, 19, -12, 63, -6, +67, 7, 35, 9, -8, 8, -31, 10, +-2, 4, 44, -7, 66, -18, 50, -20, +20, 0, -2, 23, -2, 24, 16, -3, +23, -35, 30, -46, 45, -17, 52, 30, +35, 53, -2, 23, -26, -42, -13, -83, +41, -57, 85, 21, 75, 79, 25, 62, +-25, -12, -32, -79, 0, -73, 48, -18, +66, 34, 51, 46, 35, 20, 19, -3, +4, -10, -7, -21, -3, -40, 21, -40, +64, -1, 86, 57, 47, 75, -7, 20, +-43, -51, -25, -69, 35, -13, 75, 54, +68, 56, 24, 4, -4, -31, -3, -10, +22, 29, 39, 34, 19, -9, 12, -49, +26, -17, 44, 50, 54, 68, 32, 16, +4, -58, -14, -67, 6, -2, 42, 63, +62, 60, 58, 3, 28, -41, -2, -37, +-11, -6, 6, 10, 33, 5, 55, 9, +57, 33, 35, 33, 5, -9, -12, -65, +-2, -72, 26, -4, 56, 77, 64, 83, +37, 7, 9, -78, -4, -90, 7, -24, +36, 46, 56, 56, 43, 13, 18, -31, +9, -36, 13, -14, 35, 2, 51, 2, +36, 0, 12, 7, -1, 13, 9, 0, +34, -21, 56, -25, 59, -5, 29, 26, +8, 25, 4, -6, 4, -30, 28, -31, +50, 2, 58, 34, 47, 40, 23, 13, +-3, -24, -14, -35, 14, -20, 48, 11, +68, 32, 61, 29, 23, 18, -13, 4, +-8, -12, 16, -21, 41, -27, 56, -10, +50, 26, 30, 61, 14, 56, 4, 0, +-3, -62, 19, -79, 53, -21, 69, 57, +58, 84, 16, 39, -26, -31, -20, -64, +37, -40, 82, 7, 79, 24, 33, 16, +-17, 7, -22, 13, 25, 10, 61, -14, +57, -49, 34, -46, 8, 12, 11, 63, +32, 57, 40, -7, 24, -69, 14, -63, +31, -5, 47, 45, 39, 47, 13, 4, +0, -31, 17, -26, 63, -7, 71, 2, +28, -7, -15, -8, -21, 10, 22, 29, +74, 23, 76, -9, 28, -36, -13, -28, +-8, 5, 23, 29, 48, 24, 46, 4, +28, -8, 27, 2, 40, 6, 37, -12, +8, -31, -10, -21, 9, 23, 54, 67, +89, 56, 63, -9, -5, -72, -39, -75, +-8, -11, 49, 68, 85, 88, 66, 41, +11, -30, -3, -68, 16, -47, 31, 3, +32, 32, 29, 32, 28, 26, 39, 16, +51, -7, 34, -35, 6, -43, 7, -13, +23, 36, 45, 49, 51, 8, 32, -41, +20, -48, 35, 0, 43, 54, 27, 34, +9, -34, 3, -70, 27, -32, 65, 47, +73, 71, 40, 15, -5, -58, -17, -60, +4, 1, 39, 49, 66, 29, 63, -30, +38, -42, 18, 0, 3, 41, -9, 28, +5, -26, 41, -49, 73, -13, 79, 37, +43, 37, -18, -8, -33, -47, 10, -27, +55, 30, 73, 43, 58, 1, 22, -39, +7, -30, 22, 12, 25, 32, 17, 6, +11, -22, 28, -13, 61, 23, 73, 36, +47, -5, -1, -51, -21, -41, 1, 16, +42, 57, 72, 39, 64, -12, 32, -36, +11, -17, 7, 14, 4, 16, 11, -8, +37, -10, 48, 25, 57, 41, 46, 20, +7, -22, -16, -43, 0, -15, 35, 26, +63, 25, 58, 3, 35, -17, 10, 4, +6, 33, 21, 21, 26, -26, 29, -62, +37, -43, 43, 19, 41, 67, 32, 63, +10, 14, 0, -39, 12, -63, 36, -59, +51, -23, 49, 34, 34, 76, 16, 74, +7, 11, 10, -72, 18, -103, 35, -55, +48, 35, 48, 83, 37, 58, 22, -6, +1, -46, 5, -48, 31, -28, 44, -1, +40, 23, 29, 38, 20, 39, 14, 8, +26, -43, 25, -60, 20, -26, 29, 38, +37, 71, 39, 38, 33, -27, 16, -59, +4, -33, 19, 11, 42, 41, 41, 35, +33, 8, 20, -2, 14, -5, 23, -11, +36, -24, 33, -18, 17, 15, 16, 47, +28, 46, 40, 9, 39, -30, 24, -43, +6, -19, 13, 13, 34, 29, 44, 23, +39, 9, 26, -4, 15, -11, 20, -13, +40, -19, 41, -9, 17, 9, 4, 15, +8, 16, 30, 7, 64, -7, 61, -11, +19, -12, -13, -17, -16, -18, 18, -7, +60, 14, 71, 30, 44, 18, 7, -11, +-9, -35, 3, -42, 29, -20, 39, 15, +36, 26, 43, 11, 48, -7, 40, -17, +15, -18, -17, -13, -14, -13, 21, -7, +77, 7, 93, 22, 52, 18, -13, -2, +-50, -26, -17, -32, 48, -9, 90, 21, +71, 31, 21, 13, -11, -8, -13, -13, +14, -2, 33, 8, 34, 7, 36, -3, +43, 2, 42, 13, 22, 18, -7, 9, +-14, -8, 13, -10, 51, 5, 68, 13, +44, 4, 5, -6, -8, -1, 8, 18, +30, 29, 41, 2, 34, -39, 19, -41, +26, -6, 36, 44, 24, 58, 7, 17, +2, -38, 12, -51, 33, -20, 48, 12, +37, 24, 12, 19, 7, 3, 25, -9, +34, -17, 29, -30, 8, -27, -3, -5, +22, 25, 50, 34, 58, 15, 23, -14, +-13, -40, -18, -39, 11, -18, 44, 11, +61, 25, 51, 30, 22, 18, 0, -14, +-7, -51, 0, -57, 12, -15, 42, 41, +65, 72, 61, 45, 24, -20, -21, -68, +-39, -59, -9, -8, 54, 44, 89, 62, +68, 42, 15, 0, -34, -35, -36, -46, +2, -27, 48, 14, 68, 50, 58, 59, +25, 27, -6, -23, -22, -47, -15, -33, +21, 6, 53, 43, 68, 44, 45, 19, +1, -10, -29, -26, -13, -26, 23, -6, +54, 15, 54, 22, 24, 15, 3, -2, +-2, -15, 14, -19, 27, 0, 17, 15, +10, 12, 19, -9, 39, -26, 39, -19, +21, 4, -4, 20, -11, 15, 10, -7, +41, -25, 49, -25, 26, -9, 6, 6, +1, 6, 16, 0, 27, -4, 26, -3, +2, 6, 4, -1, 28, -15, 43, -23, +45, -14, 13, 12, -19, 27, -17, 19, +15, -6, 48, -20, 57, -15, 33, 9, +-5, 18, -21, 5, -4, -11, 23, -1, +39, 19, 41, 30, 23, 13, 5, -25, +11, -38, 19, -12, 19, 32, 10, 45, +16, 17, 20, -24, 36, -32, 37, -6, +16, 22, -4, 26, -3, 6, 13, -5, +24, -3, 34, -6, 27, -11, 14, -11, +18, 6, 27, 28, 19, 26, -4, -6, +-10, -45, 3, -46, 36, -9, 74, 29, +55, 40, 5, 16, -40, -15, -43, -29, +-6, -29, 53, -26, 76, -16, 66, 10, +16, 50, -28, 52, -44, 0, -33, -65, +13, -83, 57, -29, 84, 49, 63, 82, +3, 42, -57, -32, -59, -66, -13, -41, +52, 6, 94, 26, 73, 21, 11, 9, +-34, 4, -51, 2, -15, -20, 30, -29, +61, -10, 58, 28, 39, 44, 4, 15, +-18, -33, -25, -51, -7, -13, 31, 41, +48, 62, 52, 23, 26, -29, -10, -48, +-21, -27, -5, 17, 13, 43, 34, 37, +31, 14, 17, -10, 7, -28, 6, -24, +6, 2, 8, 29, 3, 37, 3, 14, +13, -25, 20, -34, 31, -12, 31, 24, +6, 32, -3, 2, -13, -31, 5, -40, +27, -9, 38, 20, 33, 26, 8, 6, +-3, -14, -12, -15, 3, -11, 15, -14, +33, -12, 19, 1, 16, 16, 14, 21, +6, -1, 2, -25, 2, -29, 5, -8, +19, 14, 39, 13, 30, -3, 7, -14, +-18, 3, -27, 22, 6, 14, 38, -7, +51, -23, 28, -15, -18, 15, -27, 23, +-13, 10, 23, -6, 48, -6, 42, 9, +-3, 19, -13, -1, -12, -23, 8, -17, +26, 14, 21, 40, 7, 30, 10, -5, +22, -29, 19, -21, 5, 3, -17, 13, +-13, 8, 11, 6, 46, 18, 52, 19, +15, -4, -24, -37, -33, -45, -15, -2, +33, 48, 51, 59, 28, 13, -1, -48, +-2, -66, -1, -27, 17, 23, 10, 36, +-1, 16, -2, -8, 27, -11, 45, -5, +30, -17, -7, -34, -35, -30, -23, 15, +12, 59, 60, 48, 44, -14, 11, -71, +-17, -64, -24, -4, 0, 50, 25, 50, +20, 11, 12, -22, 13, -21, 19, -7, +8, -2, -1, -18, -13, -12, -3, 22, +12, 55, 29, 44, 23, -15, 4, -58, +-2, -49, 1, 4, 9, 44, 15, 42, +9, 11, -4, -13, 17, -12, 20, -5, +24, -12, 9, -15, -10, 3, -18, 35, +-1, 40, 25, 8, 33, -32, 25, -44, +6, -9, -2, 27, -10, 34, -10, 9, +9, -21, 13, -18, 28, 3, 33, 9, +16, -1, -8, -14, -16, -10, -19, 12, +-1, 14, 35, -3, 34, -14, 34, -12, +-1, 7, -16, 10, -27, -9, -9, -26, +23, -10, 36, 23, 32, 34, 16, 8, +-10, -36, -22, -53, -2, -21, 12, 27, +20, 50, 19, 32, 10, -9, 2, -30, +1, -27, 4, -12, -3, 6, -9, 20, +4, 25, 27, 20, 36, 6, 16, -12, +-5, -26, -38, -22, -12, -4, 19, 17, +40, 32, 31, 34, 2, 23, -29, -1, +-19, -29, 15, -45, 26, -25, 20, 18, +-3, 53, -6, 57, 7, 24, 22, -16, +15, -45, -12, -51, -23, -32, 3, 7, +34, 55, 43, 81, 21, 50, -27, -27, +-45, -98, -5, -96, 30, -17, 54, 82, +22, 116, -12, 47, -24, -55, -2, -101, +21, -67, 26, 3, 10, 55, -7, 58, +2, 26, 11, -13, 31, -42, 10, -51, +-10, -36, -9, 7, 8, 51, 18, 58, +24, 16, 11, -48, 0, -77, 8, -36, +10, 28, 6, 60, -2, 37, -6, -11, +9, -33, 20, -22, 34, -1, 18, 7, +-11, 3, -23, 5, -11, 15, 10, 12, +30, -2, 43, -18, 14, -10, 1, 12, +-15, 23, -24, 6, -10, -30, 26, -32, +40, 12, 34, 59, 10, 51, -22, -2, +-29, -61, -9, -64, 26, -11, 36, 45, +22, 55, 12, 23, -5, -12, -4, -22, +2, -15, -1, -18, -5, -23, 13, -11, +27, 23, 28, 50, 23, 35, -9, -17, +-17, -63, -12, -56, 15, -1, 17, 48, +18, 44, 10, 3, 9, -25, 0, -15, +5, 5, 1, 10, -17, -11, -3, -27, +17, -14, 27, 26, 30, 43, 18, 17, +-14, -23, -22, -41, -14, -20, 1, 14, +23, 28, 36, 13, 35, -6, 15, -5, +-19, 7, -28, 3, -27, -13, 14, -22, +46, -2, 48, 30, 16, 39, -16, 16, +-40, -23, -22, -36, 22, -16, 32, 22, +24, 42, 2, 31, -11, 5, -3, -21, +14, -30, 8, -19, -8, 6, -15, 33, +10, 44, 34, 29, 29, -9, 8, -51, +-22, -57, -29, -14, 7, 45, 30, 74, +27, 46, 5, -17, -12, -62, -13, -58, +17, -10, 22, 35, 11, 48, -13, 35, +-17, -2, 12, -25, 24, -31, 27, -19, +-5, 5, -28, 28, -19, 32, 22, 12, +33, -15, 25, -33, -3, -19, -31, 18, +-14, 39, 21, 24, 32, -11, 20, -37, +-5, -27, -19, 13, -14, 46, 10, 35, +21, 0, 20, -32, 9, -30, 4, 3, +-7, 32, -17, 31, -6, 7, 4, -16, +24, -10, 30, 13, 22, 19, -13, 11, +-26, -7, -26, -12, 0, 1, 29, 18, +40, 20, 32, 5, -2, 0, -29, 3, +-40, 8, -23, 4, 16, -5, 50, -4, +45, 15, 11, 32, -31, 25, -59, -4, +-29, -27, 25, -21, 49, 15, 45, 39, +0, 28, -30, -16, -29, -35, -4, -12, +20, 25, 23, 44, 8, 18, -2, -20, +-13, -31, -4, -12, 8, 24, 0, 42, +4, 26, 6, -1, -2, -17, -10, -18, +-3, -7, -1, 8, 18, 23, 22, 38, +1, 28, -22, 1, -29, -31, -13, -32, +11, 3, 35, 36, 36, 46, 3, 23, +-26, -12, -34, -29, -20, -12, -6, 22, +24, 33, 33, 21, 19, 10, -4, 7, +-36, 9, -46, 2, -18, -7, 19, 0, +43, 13, 42, 31, -6, 31, -41, 2, +-43, -20, -11, -11, 24, 19, 29, 35, +10, 19, -11, -14, -20, -16, -11, 18, +4, 46, -5, 40, -12, -9, 0, -50, +5, -30, 17, 29, 2, 73, -24, 57, +-32, 2, -21, -36, 3, -25, 13, 10, +12, 27, -4, 19, -14, 11, -18, 22, +-11, 36, -11, 21, -11, -18, -4, -40, +4, -20, 11, 36, 6, 72, -20, 56, +-40, 2, -31, -37, -10, -28, 23, 3, +31, 33, 5, 36, -26, 21, -45, 11, +-31, 10, -2, 5, 17, -3, 18, -3, +-1, 11, -27, 35, -38, 42, -25, 22, +-9, -7, 14, -16, 13, -1, -5, 23, +-23, 35, -31, 25, -24, 15, -10, 7, +4, 6, 1, 7, -7, 6, -16, 10, +-18, 21, -20, 30, -22, 26, -13, 9, +-8, 0, -5, 8, -4, 19, -21, 24, +-33, 16, -28, 5, -14, 10, 2, 27, +6, 37, -18, 25, -35, -8, -33, -28, +-11, -14, 6, 32, -2, 66, -17, 54, +-39, 12, -38, -27, -14, -31, 7, -1, +4, 32, -11, 44, -38, 33, -47, 20, +-35, 19, -11, 10, 6, 0, 0, -6, +-15, -3, -37, 21, -46, 47, -37, 48, +-21, 26, -3, -1, -2, -4, -11, 7, +-33, 19, -48, 19, -43, 9, -23, 11, +-1, 39, 1, 55, -13, 37, -37, -10, +-42, -46, -44, -29, -21, 24, -7, 77, +-6, 81, -15, 36, -31, -20, -44, -42, +-46, -26, -34, 19, -17, 53, 0, 65, +-12, 56, -31, 20, -57, -17, -58, -39, +-32, -16, -8, 34, 2, 79, -19, 78, +-46, 21, -56, -35, -46, -44, -26, 1, +-18, 56, -18, 73, -31, 44, -36, 2, +-37, -20, -31, -11, -36, 14, -43, 33, +-36, 39, -23, 34, -15, 26, -25, 10, +-43, -5, -62, -6, -48, 12, -26, 39, +-16, 53, -24, 35, -42, 3, -57, -6, +-51, 8, -33, 33, -29, 42, -38, 24, +-47, 3, -46, 3, -34, 22, -30, 43, +-38, 44, -53, 14, -53, -5, -47, -1, +-34, 18, -30, 39, -41, 43, -49, 33, +-57, 24, -52, 21, -52, 13, -38, 1, +-38, 5, -38, 21, -41, 43, -54, 53, +-56, 33, -51, 3, -40, -11, -31, 2, +-44, 31, -63, 40, -63, 29, -54, 20, +-36, 23, -30, 37, -46, 31, -66, 10, +-73, -13, -56, -5, -41, 35, -34, 68, +-41, 62, -60, 23, -67, -14, -66, -19, +-55, 12, -59, 47, -51, 54, -45, 35, +-39, 15, -47, 15, -66, 18, -82, 17, +-82, 11, -52, 9, -32, 30, -26, 51, +-47, 50, -82, 28, -100, -2, -82, -15, +-47, 7, -31, 43, -34, 59, -59, 47, +-82, 17, -84, -2, -74, 6, -64, 26, +-55, 33, -48, 34, -59, 30, -64, 31, +-78, 32, -78, 23, -77, 13, -65, 10, +-57, 21, -59, 39, -63, 46, -77, 40, +-77, 22, -75, 8, -62, 4, -60, 12, +-67, 30, -71, 42, -75, 48, -74, 37, +-68, 14, -65, -5, -70, -1, -74, 28, +-77, 57, -83, 61, -73, 31, -71, 1, +-66, -2, -70, 23, -76, 48, -86, 43, +-88, 19, -81, 6, -68, 24, -60, 51, +-69, 55, -79, 17, -91, -20, -84, -13, +-77, 34, -65, 71, -74, 71, -83, 26, +-85, -12, -81, -5, -67, 21, -76, 44, +-89, 32, -97, 17, -90, 27, -70, 52, +-61, 59, -68, 24, -98, -19, -112, -28, +-101, 15, -76, 78, -66, 98, -68, 55, +-87, -9, -100, -37, -95, -5, -90, 44, +-83, 69, -86, 46, -78, 15, -86, 13, +-81, 27, -89, 42, -101, 36, -105, 12, +-95, 3, -78, 18, -71, 44, -79, 61, +-104, 53, -114, 23, -109, 6, -89, 2, +-71, 16, -74, 35, -84, 44, -108, 50, +-118, 43, -105, 24, -86, 12, -72, 7, +-71, 12, -85, 28, -117, 48, -122, 51, +-109, 40, -76, 22, -66, 10, -72, 5, +-100, 11, -124, 35, -123, 56, -98, 58, +-76, 38, -74, 9, -90, -7, -109, 2, +-112, 38, -110, 66, -100, 59, -92, 26, +-85, -2, -84, 0, -95, 26, -109, 47, +-123, 43, -118, 23, -91, 18, -74, 36, +-67, 44, -97, 36, -128, 5, -142, -16, +-111, 7, -75, 54, -57, 84, -80, 65, +-117, 12, -143, -27, -130, -21, -94, 24, +-68, 59, -71, 66, -100, 47, -123, 27, +-132, 19, -116, 16, -95, 6, -87, 4, +-85, 17, -94, 54, -111, 79, -125, 68, +-125, 19, -113, -25, -92, -24, -75, 21, +-84, 64, -105, 73, -135, 47, -132, 12, +-113, 1, -83, 20, -79, 38, -93, 33, +-113, 20, -125, 19, -117, 33, -108, 44, +-93, 40, -96, 23, -100, 14, -108, 24, +-116, 39, -120, 35, -110, 19, -100, 15, +-95, 32, -100, 57, -117, 61, -127, 29, +-118, -6, -96, -13, -80, 18, -95, 59, +-117, 67, -133, 43, -123, 11, -99, 5, +-81, 16, -92, 31, -120, 40, -135, 38, +-127, 35, -97, 33, -84, 27, -86, 12, +-110, 7, -119, 19, -123, 44, -113, 55, +-104, 42, -105, 21, -99, 0, -97, 10, +-104, 35, -117, 48, -127, 44, -121, 31, +-101, 20, -79, 13, -82, 16, -109, 20, +-137, 32, -139, 47, -113, 50, -78, 31, +-70, 8, -93, -4, -125, 10, -140, 40, +-123, 57, -97, 45, -75, 17, -84, 7, +-104, 19, -130, 36, -133, 38, -117, 20, +-92, 9, -75, 22, -79, 48, -110, 57, +-137, 27, -131, -10, -115, -6, -88, 30, +-70, 60, -85, 59, -118, 25, -140, 0, +-135, 9, -109, 38, -80, 50, -70, 29, +-90, 3, -119, 6, -136, 40, -130, 65, +-116, 56, -89, 10, -71, -27, -73, -8, +-99, 42, -133, 78, -151, 58, -128, 10, +-84, -17, -54, 3, -59, 35, -102, 52, +-152, 40, -160, 15, -117, 12, -67, 28, +-49, 39, -72, 26, -120, 10, -149, 8, +-133, 27, -99, 52, -76, 48, -72, 20, +-87, -4, -107, -7, -115, 22, -121, 52, +-112, 53, -95, 29, -77, 6, -79, 3, +-92, 14, -116, 33, -128, 43, -115, 33, +-85, 19, -67, 14, -81, 17, -105, 28, +-127, 34, -118, 28, -98, 19, -74, 14, +-76, 20, -93, 31, -111, 41, -119, 33, +-111, 19, -100, 11, -85, 15, -78, 30, +-90, 45, -103, 36, -117, 19, -116, 9, +-97, 14, -75, 31, -75, 36, -88, 27, +-110, 12, -120, 14, -104, 30, -81, 41, +-74, 33, -84, 7, -100, -5, -113, 11, +-101, 42, -93, 62, -87, 43, -90, 4, +-94, -11, -93, 6, -92, 39, -93, 51, +-100, 32, -100, 5, -92, 8, -80, 33, +-81, 52, -96, 38, -106, -3, -102, -27, +-84, 1, -74, 55, -75, 80, -95, 54, +-105, -2, -103, -29, -90, -13, -73, 27, +-77, 54, -92, 53, -105, 33, -96, 20, +-85, 18, -78, 13, -80, 1, -89, -4, +-96, 15, -95, 53, -87, 70, -81, 48, +-76, 0, -82, -29, -92, -16, -96, 24, +-93, 55, -80, 56, -71, 31, -69, 10, +-81, 0, -97, 5, -104, 15, -96, 27, +-80, 36, -66, 40, -66, 34, -85, 16, +-93, 1, -99, 0, -87, 17, -80, 35, +-71, 37, -71, 26, -72, 11, -79, 12, +-91, 15, -94, 16, -93, 18, -75, 21, +-59, 25, -52, 28, -72, 22, -102, 12, +-112, 3, -90, 11, -60, 31, -47, 39, +-58, 26, -89, 7, -107, 2, -95, 14, +-69, 30, -55, 31, -58, 13, -74, 3, +-89, 12, -86, 30, -80, 39, -74, 25, +-76, 4, -70, -2, -64, 15, -68, 32, +-75, 34, -91, 19, -89, 4, -73, 15, +-59, 33, -54, 33, -70, 15, -88, -7, +-94, 1, -87, 31, -63, 49, -49, 42, +-57, 14, -71, -14, -83, -11, -88, 9, +-73, 33, -66, 40, -54, 29, -60, 23, +-66, 13, -76, 5, -83, -2, -73, -1, +-67, 17, -57, 39, -61, 50, -67, 36, +-77, 4, -69, -18, -68, -10, -60, 11, +-62, 38, -72, 44, -66, 26, -61, 6, +-53, -3, -61, 4, -73, 12, -77, 19, +-70, 23, -55, 21, -46, 22, -57, 17, +-76, 11, -78, 4, -67, 3, -51, 20, +-55, 33, -61, 28, -71, 13, -73, 0, +-60, 1, -52, 18, -55, 28, -62, 23, +-62, 6, -66, 1, -55, 4, -54, 17, +-57, 25, -61, 19, -63, 12, -59, 7, +-56, 11, -56, 15, -56, 14, -63, 17, +-61, 15, -53, 13, -53, 12, -51, 9, +-61, 12, -64, 16, -64, 20, -58, 22, +-55, 16, -50, 8, -52, 7, -55, 12, +-65, 19, -62, 17, -57, 15, -50, 12, +-40, 13, -49, 14, -58, 10, -66, 3, +-61, 8, -53, 25, -48, 36, -51, 28, +-57, 6, -60, -14, -51, -8, -44, 19, +-51, 40, -54, 34, -62, 7, -52, -12, +-38, -9, -38, 16, -50, 29, -61, 17, +-62, 1, -47, -2, -33, 13, -39, 30, +-52, 23, -66, -2, -55, -14, -43, 1, +-33, 27, -41, 37, -60, 22, -67, -2, +-59, -8, -33, 4, -24, 24, -37, 26, +-62, 11, -69, -5, -60, -2, -29, 17, +-25, 33, -32, 21, -50, -4, -66, -14, +-61, -2, -46, 23, -33, 42, -33, 32, +-40, 3, -48, -18, -50, -12, -56, 11, +-44, 32, -42, 35, -37, 17, -35, -2, +-42, -9, -39, -5, -41, 9, -45, 20, +-46, 17, -47, 13, -43, 9, -31, 12, +-37, 16, -37, 11, -54, 6, -60, -1, +-45, 6, -33, 21, -18, 27, -28, 21, +-49, 3, -62, -12, -52, -8, -32, 9, +-13, 25, -29, 27, -45, 14, -57, -2, +-50, 0, -33, 11, -27, 14, -28, 7, +-42, -1, -45, 6, -44, 26, -33, 30, +-31, 15, -34, -13, -42, -26, -38, -5, +-33, 30, -28, 49, -29, 35, -46, -3, +-44, -34, -41, -24, -29, 9, -21, 40, +-26, 43, -34, 14, -39, -11, -42, -20, +-36, -6, -25, 7, -28, 20, -27, 23, +-31, 14, -29, 13, -37, 11, -34, -6, +-33, -16, -28, -12, -26, 10, -24, 39, +-29, 42, -33, 19, -39, -13, -45, -29, +-32, -13, -25, 19, -12, 40, -16, 32, +-31, 8, -52, -9, -51, -11, -35, 2, +-2, 11, 3, 14, -11, 6, -36, 2, +-58, 1, -39, 4, -20, 7, 1, 8, +-10, 12, -32, 7, -45, 7, -45, 8, +-26, 3, -9, 3, -14, 6, -23, 7, +-22, 8, -30, 9, -19, 6, -28, 0, +-29, -2, -32, 4, -18, 11, -7, 20, +-8, 19, -30, 7, -41, -12, -47, -8, +-35, 9, 0, 24, 3, 28, -5, 14, +-34, -8, -47, -18, -41, -6, -15, 11, +7, 23, 9, 19, -18, 9, -42, -1, +-48, -5, -35, 2, -3, 8, 2, 13, +1, 16, -24, 13, -36, 4, -31, -6, +-17, -10, -6, 0, -7, 14, -15, 24, +-23, 19, -17, 0, -15, -11, -12, -7, +-23, 1, -18, 13, -20, 17, -10, 14, +-6, 11, -14, 8, -25, 5, -29, 0, +-24, -2, -7, -1, 4, 10, -8, 20, +-14, 17, -25, -1, -14, -12, -7, -10, +-8, 8, -11, 19, -16, 14, -17, 5, +-12, -1, -8, 4, -13, 17, -18, 18, +-22, 5, -11, -7, -5, -10, 4, 4, +-5, 19, -23, 24, -21, 7, -17, -3, +-5, -3, 5, 4, -2, 13, -14, 8, +-19, 3, -28, 5, -5, 9, 1, 19, +7, 17, -4, 2, -19, -13, -20, -13, +-16, 5, -6, 29, 0, 38, -1, 18, +-4, -11, -8, -23, -15, -14, -5, 11, +-13, 33, -9, 28, -3, 8, -2, -8, +9, -10, 1, 0, -10, 10, -21, 9, +-20, 7, -4, 7, 22, 13, 16, 18, +2, 8, -27, -9, -35, -17, -11, -4, +15, 22, 31, 42, 10, 28, -14, -7, +-31, -31, -16, -29, 4, 9, 21, 41, +13, 39, 2, 12, -15, -16, -16, -22, +4, -9, 8, 12, 10, 20, 0, 10, +-1, 2, 1, 7, 6, 14, 5, 10, +1, -5, -13, -15, -4, -11, 6, 17, +13, 41, 17, 36, -1, 5, -8, -30, +-9, -35, -2, -2, 12, 31, 20, 40, +14, 20, 3, -6, -11, -16, -4, -7, +4, 10, 8, 13, 19, 2, 5, 1, +6, 9, 4, 20, 9, 14, 10, -4, +5, -19, -3, -14, 6, 7, 14, 28, +22, 31, 18, 7, 2, -16, -4, -18, +-10, -1, 11, 19, 23, 21, 26, 9, +14, -3, -2, -2, -7, 6, 2, 15, +14, 8, 20, -1, 20, -9, 11, -2, +11, 14, 3, 22, 3, 22, 2, 2, +11, -17, 22, -15, 24, 3, 19, 22, +6, 31, -8, 17, -4, -4, 13, -12, +23, -7, 35, 8, 17, 14, 5, 13, +-4, 8, 0, 5, 19, 5, 30, 2, +25, -2, 16, -4, 2, 4, -1, 18, +10, 26, 18, 13, 30, -6, 17, -15, +11, -10, 8, 13, 7, 29, 18, 23, +21, 3, 19, -16, 15, -14, 16, -2, +18, 17, 21, 24, 15, 12, 12, 1, +5, -6, 14, -3, 27, 1, 35, 3, +28, 7, 12, 8, 0, 8, 8, 3, +22, 0, 31, -4, 39, -3, 16, 11, +2, 21, -2, 15, 16, -1, 33, -11, +34, -5, 23, 9, 10, 18, 9, 14, +14, 5, 22, -1, 20, -2, 23, 3, +11, 13, 19, 14, 22, 13, 19, 8, +22, -2, 15, -7, 21, -8, 25, 1, +32, 9, 32, 17, 17, 21, 7, 3, +18, -15, 21, -16, 30, -2, 32, 13, +27, 21, 22, 19, 7, 7, 15, -12, +27, -17, 32, -5, 34, 8, 28, 16, +18, 12, 16, 7, 11, 3, 22, -2, +29, -2, 29, 0, 31, 1, 24, 5, +17, 12, 13, 14, 14, 7, 25, -2, +34, -6, 35, -6, 33, 3, 14, 14, +9, 15, 13, 8, 22, -1, 37, -3, +33, 1, 26, 9, 16, 13, 13, 4, +18, 1, 25, -1, 32, -1, 36, 8, +26, 10, 19, 6, 21, -3, 20, -3, +27, 8, 23, 11, 32, 2, 31, -3, +28, -7, 28, 2, 25, 14, 17, 13, +19, 6, 24, -9, 33, -9, 41, 2, +33, 12, 28, 11, 12, 2, 12, -5, +23, -3, 37, 6, 40, 16, 35, 10, +17, -5, 16, -16, 22, -10, 29, 11, +40, 20, 37, 12, 27, 0, 14, -11, +16, -8, 24, 5, 34, 11, 33, 14, +29, 3, 23, -2, 25, -1, 29, 1, +29, 1, 33, -7, 25, -3, 23, 1, +33, 6, 32, 16, 31, 10, 29, -8, +24, -13, 20, -11, 27, 0, 35, 12, +41, 15, 32, 11, 25, -3, 15, -12, +21, -9, 30, -2, 40, 12, 34, 18, +26, 8, 21, -1, 20, -4, 28, -6, +41, -7, 36, 0, 29, 5, 30, 4, +24, 11, 27, 7, 31, -8, 32, -12, +32, -9, 30, 4, 27, 18, 27, 15, +28, 1, 37, -18, 37, -21, 32, -6, +28, 9, 25, 16, 31, 10, 33, -3, +37, -15, 36, -12, 24, -3, 22, 9, +24, 8, 34, 2, 38, 1, 37, -2, +24, 4, 21, -4, 21, -6, 30, -7, +42, 0, 37, 15, 32, 12, 25, -4, +23, -14, 27, -12, 33, 0, 39, 9, +36, 9, 26, 0, 27, -9, 24, -1, +31, -2, 42, 0, 33, -1, 33, -5, +26, -3, 28, 1, 31, 4, 37, 2, +36, -4, 33, -2, 20, 1, 26, -3, +34, 2, 36, 1, 40, 1, 31, -3, +25, -5, 21, 4, 29, 3, 44, -2, +43, -1, 30, -9, 23, -3, 14, 7, +27, 8, 42, 7, 44, -5, 35, -9, +25, -8, 18, -3, 28, 6, 34, 8, +47, -3, 42, -3, 29, -11, 24, -10, +24, -3, 33, 1, 45, 7, 39, 3, +29, -3, 19, -6, 18, -6, 36, 0, +43, 4, 45, 0, 30, -1, 23, -9, +23, -7, 36, -3, 39, 0, 45, 1, +31, 0, 21, 6, 14, -2, 34, -11, +43, -10, 51, -1, 37, 6, 22, 10, +13, -6, 27, -11, 36, -7, 49, 5, +39, 11, 29, 1, 18, -5, 24, -15, +40, -8, 48, -1, 46, 0, 36, -1, +22, -1, 23, -2, 30, 2, 39, -7, +45, -6, 34, -2, 27, 0, 27, 6, +29, 1, 37, 0, 43, -7, 32, -9, +32, -8, 27, -7, 38, -1, 41, 11, +36, 8, 28, -2, 24, -13, 21, -15, +38, 0, 48, 1, 47, 8, 36, -1, +18, -5, 16, -2, 27, -3, 43, -6, +57, -10, 46, -8, 29, 0, 21, 6, +12, 4, 38, -6, 52, -15, 49, -4, +36, -2, 18, 3, 15, 2, 35, -2, +43, 0, 53, -5, 41, -11, 26, -10, +25, -5, 26, 5, 41, 4, 52, -8, +44, -8, 36, -10, 29, -3, 25, 1, +36, -6, 44, -8, 44, -3, 43, -2, +26, 7, 27, -5, 39, -16, 44, -6, +40, 1, 31, 9, 24, -2, 29, -4, +39, -6, 50, -4, 46, -2, 28, -2, +23, -7, 23, 2, 38, -1, 57, -5, +51, -6, 36, -8, 17, 5, 15, 0, +33, -1, 50, -8, 54, -7, 43, 4, +21, 5, 18, -5, 30, -8, 41, -9, +55, -3, 49, 0, 34, -6, 25, -7, +31, -12, 39, 1, 51, 1, 42, -6, +41, -14, 31, -14, 34, -4, 40, 6, +48, -2, 42, -6, 36, -6, 23, -8, +31, 1, 36, -6, 51, -4, 53, -5, +40, 2, 21, 1, 22, -7, 31, -13, +52, -6, 55, 3, 40, 8, 27, 0, +21, -10, 32, -6, 50, -9, 54, -2, +44, -8, 32, -5, 23, 1, 34, 4, +45, -2, 49, -10, 45, -14, 34, -5, +26, 6, 30, 6, 37, -1, 50, -12, +43, 0, 39, -6, 37, -4, 32, -8, +38, -10, 45, -1, 41, 4, 41, -3, +37, -7, 32, -12, 46, -7, 40, 4, +44, -3, 32, 0, 26, -7, 29, 0, +43, 1, 45, -2, 54, -8, 37, -9, +27, -3, 23, -1, 34, -6, 51, -8, +60, -3, 44, -2, 32, 3, 13, -8, +28, -9, 46, -6, 57, 1, 54, 3, +36, -6, 23, -14, 28, -4, 34, 4, +50, 0, 55, -9, 41, -16, 35, -3, +26, 4, 31, 9, 43, -9, 49, -16, +43, -7, 39, 2, 31, 4, 33, 1, +36, -9, 43, -8, 46, -4, 42, -7, +35, -3, 36, -9, 41, 1, 44, 1, +41, -1, 31, -9, 35, -15, 39, -4, +43, 8, 44, 3, 41, -7, 31, -10, +28, -2, 29, 7, 48, -6, 51, -8, +45, -12, 31, 3, 22, 10, 28, 0, +48, -13, 52, -16, 51, -10, 38, 3, +24, 4, 27, -1, 35, -4, 49, -10, +49, 0, 38, -5, 31, -2, 32, -4, +33, 1, 39, 2, 39, -5, 39, -9, +40, -2, 32, 6, 33, 3, 39, -7, +40, -16, 44, -3, 38, -2, 39, 2, +41, -9, 38, -9, 41, -3, 46, -5, +43, -7, 35, -7, 33, -12, 41, -1, +44, 10, 41, 0, 36, -4, 29, -17, +31, -5, 44, 1, 46, 7, 42, 0, +39, -13, 29, -9, 32, -3, 41, -3, +45, -3, 45, -1, 35, 0, 32, 3, +34, -12, 42, -15, 44, -12, 43, 5, +37, 8, 39, 4, 31, -9, 43, -19, +40, -8, 41, 0, 40, -2, 42, -4, +33, 0, 41, -4, 38, 1, 40, -11, +38, -10, 38, -10, 40, -2, 40, 7, +40, -1, 46, -11, 40, -8, 30, -2, +31, -1, 33, -3, 44, -8, 49, 1, +46, -3, 35, 0, 26, -9, 28, -15, +47, -6, 49, 4, 51, 2, 39, -7, +29, -14, 29, -9, 40, 2, 46, -1, +52, -4, 39, -13, 32, -2, 30, 2, +33, 2, 42, -7, 46, -12, 44, -8, +43, 1, 36, 0, 36, -8, 39, -9, +37, -8, 45, 3, 40, -3, 41, -5, +37, -10, 42, -7, 38, 2, 40, 1, +35, -8, 42, -11, 39, -6, 44, 0, +40, 2, 40, -6, 33, -2, 34, -2, +31, 5, 44, -9, 49, -10, 42, -4, +39, 0, 30, 6, 33, -7, 47, -15, +47, -10, 46, -3, 40, 0, 30, 1, +32, -8, 44, -6, 49, -4, 43, 2, +34, -8, 32, -12, 33, 2, 37, 8, +48, 3, 42, -8, 36, -15, 30, -6, +31, 8, 40, 3, 44, 4, 36, -10, +38, -6, 31, 1, 32, 2, 37, -3, +41, -7, 37, 3, 39, 6, 35, 2, +35, -10, 40, -15, 41, -11, 44, 7, +40, 3, 40, -2, 38, -11, 39, -11, +40, 0, 43, -5, 46, -10, 35, -1, +30, 4, 33, 7, 42, 2, 44, -11, +43, -8, 36, -8, 31, 5, 34, 3, +39, 1, 44, -3, 46, -3, 38, -2, +34, -5, 33, -10, 39, -7, 45, 1, +43, 3, 40, 2, 39, -10, 37, -5, +38, -4, 40, -2, 38, -6, 42, -9, +44, -5, 44, 5, 41, 2, 38, -8, +35, -15, 42, -14, 39, 5, 42, 6, +41, 2, 43, -12, 42, -10, 38, -4, +36, -3, 38, -3, 35, -6, 48, -5, +48, 2, 43, 2, 33, -5, 27, -10, +31, -7, 37, 9, 49, 2, 54, -3, +39, -5, 25, -5, 27, 1, 30, 1, +47, -3, 53, -8, 50, -3, 36, 0, +36, -4, 29, -6, 37, -1, 40, -2, +51, -1, 47, -4, 38, -5, 35, -5, +37, -1, 36, 4, 43, -3, 45, -9, +43, -7, 41, -1, 40, -2, 39, 2, +35, -2, 36, 0, 39, -2, 43, -4, +45, -7, 42, -4, 39, -2, 39, 4, +33, 3, 40, -10, 46, -15, 49, -7, +43, 6, 40, 4, 27, 4, 30, -9, +42, -10, 50, -2, 51, -1, 45, -4, +34, -10, 37, -7, 35, 5, 43, 3, +50, -12, 47, -15, 40, -7, 31, 13, +35, 9, 43, -3, 41, -13, 42, -18, +44, -5, 38, 5, 44, 5, 43, -2, +41, -5, 37, -5, 33, -2, 36, -5, +43, -1, 43, 2, 44, 8, 40, 3, +33, -3, 30, -7, 35, -10, 43, 0, +51, 4, 50, 3, 46, -5, 38, -11, +34, -15, 42, -10, 48, -6, 54, 5, +52, 2, 44, -6, 37, -15, 38, -17, +36, -2, 45, 8, 46, 9, 48, -3, +46, -12, 38, -10, 33, -1, 35, -1, +39, 1, 50, -6, 50, 3, 45, 2, +44, -9, 34, -13, 33, -12, 40, 0, +47, 12, 52, 8, 48, -7, 37, -15, +31, -12, 29, 6, 38, 11, 44, 6, +52, -9, 52, -14, 44, -7, 34, 0, +31, 0, 34, -1, 40, 3, 51, 1, +54, -1, 47, -11, 34, -11, 30, -8, +33, 8, 40, 15, 52, 4, 53, -10, +46, -19, 38, -13, 36, -2, 40, 7, +46, 7, 50, -4, 48, -13, 41, -10, +41, -9, 39, 5, 41, 5, 43, 0, +47, -11, 48, -12, 43, -4, 44, -1, +42, 0, 44, -6, 43, -1, 37, 3, +43, 3, 41, -7, 48, -16, 48, -12, +46, 5, 41, 13, 42, 1, 39, -15, +42, -20, 42, -6, 45, 15, 44, 20, +42, -1, 36, -14, 35, -20, 40, -3, +46, 7, 52, 5, 49, -5, 48, -12, +42, -8, 40, -2, 38, -3, 43, -9, +43, 1, 45, 8, 47, 12, 45, -2, +38, -16, 35, -21, 36, -6, 46, 10, +55, 16, 53, 4, 44, -14, 34, -18, +26, -7, 35, 7, 49, 10, 56, 5, +54, -8, 42, -10, 36, -11, 36, -3, +37, 3, 44, 1, 52, 0, 46, 4, +46, 1, 40, -5, 36, -11, 37, -14, +46, -1, 49, 11, 52, 14, 46, -7, +44, -21, 32, -16, 41, -3, 49, 13, +50, 12, 49, -9, 47, -22, 38, -9, +35, 10, 37, 17, 40, 3, 44, -10, +45, -12, 42, 6, 41, 9, 40, 3, +37, -8, 42, -10, 45, 1, 48, 9, +44, 3, 41, -12, 38, -12, 38, 1, +43, 16, 43, 15, 40, -4, 46, -26, +43, -16, 44, 2, 49, 13, 46, 9, +41, -7, 38, -17, 41, -13, 43, 7, +47, 9, 48, 3, 47, -11, 41, -10, +40, -5, 41, 4, 41, 2, 48, -8, +52, -10, 49, 0, 40, 11, 33, 6, +33, -9, 40, -17, 43, -2, 54, 10, +51, 22, 38, 5, 34, -19, 29, -21, +35, -3, 50, 17, 56, 18, 55, -2, +42, -19, 32, -15, 30, 1, 39, 11, +48, 4, 58, -11, 54, -11, 44, 3, +33, 11, 27, 4, 34, -9, 45, -16, +57, -2, 54, 15, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_32000_2ch_16b.c b/USDK/example_sources/i2s/src/birds_32000_2ch_16b.c new file mode 100644 index 0000000..b6d66d1 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_32000_2ch_16b.c @@ -0,0 +1,23326 @@ +#include +int sample_size=93277; + +SECTION(".sdram.data") +short sample[]={ +-1, 1, 0, 0, 1, 1, -1, 2, +-1, -1, 2, -1, 0, 2, -4, 4, +-3, 2, -1, 0, 2, -2, 1, 1, +-1, 0, 1, -2, 2, 0, 1, 1, +-3, 1, 0, -1, 2, -2, 2, 0, +-1, 2, -4, 3, -3, 3, 0, 0, +2, -2, -1, -1, 0, -1, 4, -3, +4, -4, 1, -3, 1, -3, 3, -1, +1, 0, 2, -4, 3, -5, 1, 1, +0, 1, -1, 1, -5, 2, -1, 0, +2, 0, 2, -1, -1, 0, -4, 2, +1, 0, 5, -2, -2, 2, -6, 3, +0, 0, 2, 0, -1, 1, -1, -2, +1, 0, 0, 3, 3, -4, 3, -4, +0, -1, 3, 0, 1, 2, -3, 1, +-1, -1, 4, -3, 5, -1, 0, 0, +-2, -1, 0, -1, 4, -2, 2, 0, +-2, -1, 2, -3, 3, 1, -1, 3, +-3, 0, -1, -2, 3, -2, 4, -2, +2, -1, -2, -2, 1, -1, 3, 0, +1, 0, -2, 0, 1, -2, 1, 2, +-1, 1, 1, -2, -3, 3, -3, 3, +0, 2, -1, -1, 1, -4, 1, 1, +-1, 3, 0, -1, 0, 0, -3, 1, +1, 0, 3, -2, 1, -4, 1, -2, +4, -3, 4, 0, -2, 0, 0, -3, +2, -1, 2, 1, -2, 3, -4, 3, +-3, 2, 2, 0, 0, 1, 0, -2, +1, -2, 0, 3, -3, 3, -2, 0, +-1, -1, 2, -3, 7, -4, 2, 1, +-3, 1, 1, -1, 1, 1, 0, 1, +-3, 3, -4, 1, 2, -3, 4, -2, +2, -3, 0, 0, -2, 3, -1, 0, +2, -3, 1, -2, 0, 1, -2, 4, +-3, 2, -1, -1, -1, 0, 2, -2, +3, -1, -3, 2, -2, 2, -3, 3, +-1, 3, -5, 4, -1, -1, 0, 0, +0, 0, 0, 0, -1, 1, -2, 2, +0, 1, -2, 2, -2, 1, -1, 1, +0, 0, 0, 1, -2, 1, -1, 0, +0, 1, 0, 1, -1, 1, 0, -2, +3, -3, 3, -1, 1, 0, 0, -1, +1, -2, 2, -1, 1, 0, 1, -1, +0, 0, 2, -2, 3, -2, 0, 0, +-1, 0, 1, -1, 0, 1, -2, 2, +-2, 0, -1, 0, 2, -2, 2, 0, +-3, 2, -2, 2, -2, 2, -3, 3, +-3, 1, 0, 1, -2, 3, -2, 2, +-1, 0, 0, -2, 2, -1, 0, 2, +-4, 5, -5, 4, -3, 3, -1, 1, +2, -2, 1, 0, -1, 0, 1, -1, +1, 0, -1, 0, 0, 1, -1, 1, +1, -1, 1, -1, 1, -2, 1, 2, +-3, 4, 0, -2, 1, 0, -2, 3, +-1, 1, 1, -1, 2, -2, 0, 0, +-1, 2, 0, -2, 4, -4, 2, -1, +0, 2, -1, 0, 2, -1, -4, 4, +-2, 1, 2, -1, 0, 1, -4, 3, +-2, 2, -1, 2, -2, 3, -4, 4, +-5, 4, -1, 1, 1, -1, -1, 0, +-1, -1, 3, -3, 3, -2, 0, 1, +-2, 2, -3, 3, -2, 1, -1, 1, +-3, 2, -2, 1, 0, 0, -1, 2, +-3, 1, 0, 0, 1, -2, 3, -2, +-1, 2, -3, 2, -1, 1, 2, -1, +2, -3, 1, 0, 0, 0, 4, -4, +4, -3, 2, -1, 0, 0, 1, -1, +1, -1, 2, -2, -1, 2, -2, 2, +0, 0, 1, -1, -1, 2, -3, 3, +1, -2, 3, -1, -2, 1, 1, -2, +2, 0, 0, 0, 1, 0, -3, 3, +-3, 4, -3, 3, -2, 2, -2, 0, +1, -1, -2, 4, -5, 4, -5, 4, +-4, 3, -2, 3, -4, 3, -2, 1, +-2, 3, -5, 5, -4, 4, -3, 1, +-2, 1, -3, 4, -4, 4, -3, 0, +2, -3, 4, -4, 4, -3, 2, -3, +2, -2, 2, -2, 1, -1, 2, -2, +1, -1, -2, 1, 0, 0, -1, 1, +0, 0, 1, -1, 0, 1, -3, 5, +-4, 4, -4, 3, -1, 0, 2, -1, +2, -2, 3, -3, 1, -1, 0, 3, +-3, 2, 1, -1, 1, -2, 3, -1, +0, 1, 0, 1, 0, -1, 0, 0, +0, 0, 1, 0, -2, 2, 0, -1, +2, -1, 2, -2, 1, 0, -2, 2, +-2, 1, 0, 0, 2, -2, -1, 2, +-3, 3, -3, 2, 1, -1, -1, 1, +0, -3, 3, -2, -1, 1, 0, -1, +0, 0, 2, -4, 4, -3, 1, -2, +2, -2, -1, 1, -2, 2, 0, -3, +4, -4, 4, -5, 6, -4, 1, 1, +0, -1, 1, -1, -1, 2, -2, 2, +-1, 2, -4, 4, -4, 4, -2, 1, +3, -3, 1, 0, -1, 1, 1, -2, +3, -1, 1, -1, 2, -1, 0, 0, +0, 1, -1, 2, -1, 2, -2, 2, +1, -1, 0, 1, -1, 1, -2, 2, +-1, 1, 1, -1, 2, -2, 1, 1, +-3, 2, 0, 2, -3, 3, 0, -1, +3, -2, -1, 2, -2, 1, 0, 0, +1, -2, 3, -2, 0, 1, -1, 1, +0, -1, 1, 1, -2, 0, 1, 0, +-4, 4, -2, 1, -2, 2, -2, 2, +-2, 2, -1, 0, 2, -3, 1, -1, +1, -2, 0, 2, -5, 5, -5, 3, +0, -1, 2, -3, 4, -5, 6, -5, +3, -2, 1, -3, 4, -2, -2, 3, +-4, 4, -3, 2, 0, 0, 2, -3, +4, -3, 0, 1, -2, 2, 0, 0, +3, -4, 4, -3, 2, 0, 1, 0, +0, 2, -1, -1, 2, -1, 0, 0, +1, 0, 0, 0, 1, -1, 1, 0, +1, -1, -1, 2, -3, 2, 0, -1, +2, 0, 1, -1, 2, -1, 1, -2, +1, 0, 1, -1, 1, 0, -3, 4, +-4, 3, 0, -2, 1, -2, 1, -3, +3, -3, 1, 0, 0, -1, 0, -1, +0, -1, -1, 2, -4, 3, -2, 0, +1, -3, 1, 0, -2, 1, 0, 0, +0, -1, 2, -2, 0, 0, 0, 0, +0, 0, -1, 2, -2, 1, 0, 0, +1, -2, 3, -3, 2, -1, 2, -1, +2, -2, 1, 0, 0, 0, 0, 0, +3, -2, 2, -2, 2, -2, 3, -3, +2, -1, 1, -1, 1, -1, 1, -2, +5, -5, 5, -4, 4, -4, 4, -3, +1, 1, -2, 2, -2, 3, -2, 1, +2, -2, 3, -3, 3, -2, -1, 0, +0, 0, 0, 0, 2, -2, 0, 1, +-3, 2, -1, 0, 1, 0, -3, 2, +-3, 2, -2, 1, 1, -1, -1, 0, +-2, 0, -1, 1, -2, 2, -4, 3, +-2, -1, 1, -1, -2, 2, -1, 1, +-2, 1, 1, -2, 3, -3, 3, -3, +4, -5, 3, -2, 0, 0, 0, 0, +-1, 0, -1, 3, -4, 3, 2, -2, +1, 0, -1, 1, -1, 1, 0, 1, +-1, 3, -3, 4, -2, 1, 2, -1, +2, -2, 3, -3, 3, -3, 4, -2, +0, 1, 2, -2, 4, -3, 2, 0, +0, -1, 4, -3, 3, -2, -1, 1, +-2, 3, -2, 2, -1, 1, -1, 1, +0, 0, -1, 3, -4, 3, -2, 2, +-2, 1, 2, -3, 2, -1, -1, 1, +-1, 1, -2, 2, -3, 1, 0, -2, +3, -3, 2, -1, 0, 0, -1, -1, +1, -2, 0, 1, -1, 1, 0, -1, +-1, 2, -3, 3, -2, 2, 0, -1, +0, 0, 0, -1, 0, 2, -3, 2, +0, -1, 0, 1, 0, 0, 2, -2, +1, 0, -2, 2, -2, 2, 0, -1, +1, 1, -4, 4, -2, 2, -1, 2, +-1, 1, 2, -2, 1, 0, 1, 0, +2, 0, -1, 1, 1, -2, 1, 0, +1, -2, 4, -3, 0, 1, 0, 0, +3, -3, 1, 1, -3, 3, -2, 1, +1, -1, 0, 0, -1, 1, -2, 3, +-5, 4, 0, -2, 4, -5, 2, 0, +-4, 4, -2, 1, 1, -2, 1, -2, +2, -3, 1, 0, 0, 0, -2, 1, +-2, -1, 1, -1, -2, 3, -4, 3, +-3, 1, -1, 0, -1, 2, -3, 3, +-3, 1, -1, 0, 0, 0, 0, 0, +0, -1, 2, -4, 4, -3, 2, -1, +2, -3, 1, 0, -2, 3, 0, -1, +1, 1, -2, 1, 1, -1, 1, 2, +-3, 4, -2, 0, 0, 0, 1, -2, +3, -2, 0, 0, -2, 2, -1, 1, +0, 2, -3, 4, -5, 6, -4, 2, +2, -2, 0, 2, -4, 3, -2, 1, +2, -3, 3, -1, -1, 1, -1, 0, +3, -3, 0, 2, -5, 4, -1, 0, +-2, 3, -2, 1, -2, 3, -4, 2, +-1, 1, -4, 5, -4, 2, 1, -3, +2, -2, 1, -1, 2, -3, 2, -2, +3, -4, 4, -4, 2, -2, 2, -2, +0, 0, -1, 2, -2, 1, 0, 0, +0, 0, -2, 1, 2, -3, 2, -1, +-2, 3, -2, 1, 1, 0, 1, -1, +2, -2, 3, -3, 2, 0, 0, 0, +1, -2, 2, -2, 3, -1, 0, 2, +-4, 4, -3, 2, 0, 1, 1, -1, +3, -3, 1, -1, 1, 0, 2, -1, +1, 0, 1, -2, 3, -1, 0, 1, +2, -2, 0, 0, 0, -1, 1, 1, +-1, 2, -1, 1, -2, 1, 0, -1, +3, -3, 4, -3, 2, -3, 2, -1, +-1, 3, -1, 1, -4, 5, -8, 6, +-3, 3, -2, 2, -2, 1, -2, 1, +0, -1, 2, -1, 1, -2, 1, -1, +-2, 2, -1, 1, 0, 0, 0, -1, +-1, 1, 0, 0, 1, 0, 0, 0, +-2, 2, -2, 2, 1, -2, 2, -2, +0, -1, 2, -2, 2, 1, -3, 3, +-3, 0, 2, -3, 3, -1, 0, 2, +-1, -1, 2, -3, 3, -3, 4, -2, +0, 0, 1, -2, 2, -1, 1, -1, +1, 0, -2, 2, -3, 2, 1, -1, +2, 1, -3, 2, 0, 0, -1, 3, +2, -3, 2, 1, -5, 3, 0, -1, +2, -1, 1, 0, -4, 5, -6, 4, +-1, 2, -3, 4, -4, 1, 3, -5, +6, -5, 4, -3, 3, -3, 0, 0, +-1, 1, 1, -1, -1, 2, -5, 4, +-4, 2, 1, -2, 2, -2, 1, -1, +0, 0, -1, 1, -1, 2, -5, 6, +-5, 2, 1, -1, 4, -4, 4, -2, +-1, 0, 4, -5, 5, -3, 2, -1, +2, -2, -1, 0, 1, -1, -1, 3, +-3, 2, -1, 2, -3, 3, -2, 2, +0, -1, 2, -3, 1, 1, 0, 1, +1, -1, 0, -1, 1, -2, 2, -2, +3, -3, 3, -1, -1, 1, 0, 0, +-3, 6, -6, 4, -1, 0, -1, 1, +1, -3, 2, -1, -2, 3, -2, 1, +1, -1, -1, 1, -1, 1, -2, 2, +-2, 2, -2, 2, -3, 3, -1, 1, +-1, 0, 1, -2, 0, 0, -1, 1, +-1, 1, 1, -2, 1, -1, -2, 2, +-1, 0, 0, 0, 1, -3, 2, -1, +-2, 3, -4, 4, -3, 2, -2, 2, +-3, 4, -4, 5, -3, 2, 1, -3, +4, -4, 4, -2, -1, 2, -1, -2, +5, -5, 2, 0, 1, -1, 0, 0, +-1, 0, 1, -1, 2, -1, 0, 1, +-1, -1, 3, -2, 2, -1, 1, -1, +0, 0, 0, -1, 1, 0, -1, 2, +-2, 0, 0, 0, 0, -1, 4, -2, +0, 0, 1, -3, 3, -1, 0, 1, +0, 0, 0, -1, -1, 1, -1, 2, +-3, 4, -2, -1, 4, -5, 4, -2, +2, 0, -3, 3, -4, 3, -2, 1, +1, 0, -1, 0, 1, -2, 1, 0, +0, 1, -1, 0, 1, -2, 0, 0, +1, -2, 2, -1, 0, -2, 2, -1, +-3, 4, -1, -1, 4, -3, -2, 3, +-3, 1, 2, -2, 3, -2, 0, 1, +-3, 2, -1, 1, 2, -2, 1, 0, +-3, 3, -2, 1, 1, 1, -2, 2, +-2, 0, 0, 0, 1, -2, 2, 0, +-3, 1, 2, -2, 1, -1, 3, -2, +0, 1, -3, 2, -1, 1, 1, 0, +-1, 2, -2, 0, 1, -2, 1, 0, +1, 0, -2, 2, -2, 1, 0, -1, +2, -2, 0, 1, -5, 3, -1, 1, +1, -1, 1, -1, -2, 2, -1, 0, +2, -1, 1, -2, 3, -4, 3, -2, +1, 0, 1, -1, 1, -2, 3, -3, +0, 1, -1, 0, 1, -1, 0, 0, +1, -2, 2, -1, -1, 1, 0, -1, +4, -5, 3, -2, 3, -3, 1, 1, +-3, 2, 2, -3, 2, 1, -3, 3, +-1, 0, 0, 0, -1, 2, -2, 3, +-4, 3, -1, 0, 2, -2, 4, -4, +2, 0, -1, -1, 4, -3, 0, 3, +-3, 1, 2, -2, 2, 0, -2, 3, +-2, 2, 0, -1, 1, 0, -1, 1, +-2, 2, -3, 3, -1, -1, 2, -1, +0, 0, 3, -4, 6, -6, 4, -2, +-1, 1, -2, 2, -2, 2, -1, 1, +-2, 3, -4, 4, -2, 2, -3, 3, +-2, 0, 0, 0, 2, -3, 3, -1, +-2, 2, -1, -1, 0, 0, 0, 0, +0, 0, 1, -2, 1, 0, -2, 4, +-3, 1, 1, -2, 0, 0, 0, -1, +3, -2, 0, 1, -1, 1, -1, 2, +-1, 0, 2, -1, 0, 1, -3, 3, +-2, 2, 0, 0, 0, 0, 0, -1, +1, -1, 2, -1, 1, -2, 2, -2, +2, -2, 1, -1, 1, 0, -1, 1, +-2, 1, 0, 0, 0, 1, -3, 3, +-3, 2, -1, 0, 3, -3, 3, -2, +-1, 2, -3, 3, -2, 2, -1, 2, +-4, 3, -3, 1, 0, 0, 1, -1, +0, -1, 0, -2, 2, -1, 0, 0, +0, -1, 1, -1, 1, -2, 2, -2, +0, 0, -1, 0, 0, -1, 0, 0, +0, 1, -1, 1, -3, 2, -1, 1, +-1, 2, -1, 0, 0, 0, 1, -1, +2, -1, 0, 1, -1, 1, -2, 0, +3, -3, 2, 0, 1, -2, 3, -2, +0, 1, 0, 0, 0, 1, -1, 0, +1, -1, 1, 1, 0, 0, 1, 0, +-4, 6, -4, 2, 1, -1, -1, 1, +0, 0, 0, 0, 1, -2, 1, 0, +-2, 1, -1, 1, -1, 0, 1, 0, +-3, 3, -2, 0, 1, -1, 2, -3, +2, -3, 2, -2, -1, 1, -1, 0, +0, 0, -1, 1, -2, 1, 1, -1, +-1, 4, -6, 6, -6, 5, -4, 2, +-1, 1, -2, 2, -1, 1, 0, -2, +1, 0, 0, 0, -2, 2, -2, 1, +0, 0, 0, 0, 1, -1, 2, -3, +5, -6, 4, -1, 1, -2, 4, -5, +2, -1, 2, -2, 2, 0, 0, -2, +4, -4, 0, 3, -3, 3, -2, 3, +-4, 4, -4, 4, -3, 2, -1, 0, +0, 1, -2, 2, 0, -1, 1, 1, +-1, 0, 0, 1, -4, 4, -2, 2, +-2, 3, -3, 2, -3, 2, -1, 1, +0, 1, -1, 0, 0, 0, -2, 2, +-2, 1, -1, 2, -4, 3, -2, 2, +-1, 0, 2, -2, 2, -2, 1, 0, +0, -1, 3, -3, 1, 0, -2, 2, +-1, -1, 2, -2, 0, 1, -2, 1, +0, -1, 1, 0, 0, 1, -2, 1, +-1, 2, -3, 3, -1, 1, 0, 1, +-2, 2, -3, 3, -2, 1, 0, 0, +-1, 2, -4, 3, -1, 0, 1, 0, +1, -2, 4, -4, 3, -2, 1, 0, +0, 0, 1, -2, 1, -1, 0, 0, +2, -3, 3, -2, 0, 0, 0, -1, +2, -2, 2, -1, 1, -2, 3, -3, +2, -1, 0, 1, -1, 0, 1, -2, +2, -1, 0, 0, -1, 1, 0, -2, +3, -3, 0, 1, 0, 0, -1, 1, +-1, -1, 2, -1, -3, 4, -4, 3, +-2, 1, 1, 0, -1, 1, 1, -3, +2, -1, -2, 3, -2, 1, 0, 1, +-1, 0, 0, 1, -3, 3, -1, 0, +0, -1, 2, -3, 4, -4, 4, -3, +2, 0, -1, 0, 0, 0, -1, 1, +1, -1, 2, -3, 3, -2, 0, 0, +-1, 2, -3, 2, 0, -2, 3, -3, +2, -1, 1, -1, 2, -3, 1, 1, +-2, 1, 3, -4, 4, -2, 0, 1, +0, 0, 1, -2, 2, -1, 0, 1, +-1, 0, 1, -1, 1, -1, -1, 1, +0, -1, 1, -1, 1, -1, 0, 0, +-1, 2, -2, 1, 2, -3, 1, 0, +-1, 0, -1, 1, -2, 2, -2, 3, +-4, 2, 1, -3, 3, -2, 0, 0, +0, 0, -1, 1, 0, -1, 0, 2, +-2, 1, 1, -1, -1, 1, -3, 4, +-3, 1, 2, -2, 0, 0, -1, 0, +1, -1, 1, 0, 1, -1, 1, -2, +1, -1, 1, -1, 2, -2, 1, 0, +-2, 3, 0, 0, 1, 1, -3, 3, +-2, 0, 3, -3, 2, -1, 1, -2, +2, -1, 0, 0, -1, 1, -1, 1, +-2, 2, -1, 0, 2, 0, -3, 4, +-4, 4, -5, 5, -4, 2, 0, 0, +0, -1, 1, -2, 2, -1, 0, 1, +0, 0, 1, -1, -1, 1, -1, 1, +0, 0, 0, 0, -1, 1, -1, 1, +-2, 4, -4, 2, 0, -1, -1, 1, +-1, 1, -1, 2, -1, -1, 3, -3, +2, -2, 3, -4, 4, -4, 2, -2, +2, -3, 3, -2, 1, 0, 0, -1, +2, -3, 3, -2, 0, 1, -3, 4, +-4, 4, -2, 1, 1, -1, 3, -4, +3, -1, -2, 3, -1, 1, -2, 4, +-5, 4, -1, 0, 2, -2, 1, 0, +-2, 2, -1, 1, 2, -2, 2, 0, +-2, 1, 2, -4, 4, -3, 1, 0, +0, -1, 1, -2, 3, -3, 2, -1, +2, -2, 1, -1, -1, 2, -4, 4, +-3, 3, -3, 2, -2, 1, 0, 0, +1, -1, 1, -2, 2, -3, 1, 0, +-1, 1, 0, -1, 1, -1, 0, 0, +-1, 0, 1, -1, 1, -2, 3, -4, +2, 0, -2, 3, -3, 3, -2, 1, +0, 0, -1, 1, -1, 1, -1, 1, +0, 0, 0, 1, -2, 1, 0, 0, +-1, 2, -2, 2, 0, -1, 2, -2, +1, -1, 2, -2, 0, 1, 0, 0, +0, 1, -1, 1, 0, 1, -1, 1, +0, 0, 1, -1, 1, 0, -3, 3, +-1, 0, 2, -1, -1, 2, 1, -3, +2, 0, -4, 5, -2, 1, 1, -1, +1, -1, 2, -2, 0, 1, -3, 2, +-2, 3, -3, 2, 2, -2, 2, 0, +-1, 0, 3, -5, 5, -4, 0, 1, +-2, 1, 0, 0, -1, 2, -2, 1, +2, -4, 5, -5, 4, -3, 0, 1, +-2, 1, -1, 1, -1, 0, 0, -1, +2, -1, 0, 1, -2, 1, 0, 0, +0, 1, -1, 0, 3, -5, 6, -4, +0, 3, -3, 2, 0, 0, -2, 2, +-1, 1, 1, -1, 1, 1, -2, 3, +-2, 2, -3, 4, -3, 1, 0, 0, +-1, 0, 0, 0, 1, -2, 3, -2, +-1, 2, -3, 3, -1, 0, 1, -1, +2, -4, 5, -4, 2, -1, 1, 0, +-1, 1, 0, -1, 2, -2, 2, -2, +1, -1, 1, -2, 2, -1, 0, 0, +1, -1, 0, 0, 1, -1, 0, 2, +-3, 2, 1, -2, 2, -1, -1, 2, +-1, 0, 2, -1, -3, 3, -1, 0, +-2, 4, -5, 4, -3, 3, -4, 3, +-1, 0, 1, -1, 0, 0, -2, 2, +0, 0, -2, 2, -3, 2, -1, 0, +1, 0, 0, 1, 0, -1, 2, -2, +1, 0, -1, 1, 0, 0, 0, 1, +-1, 0, 2, -2, 2, -2, 3, -3, +3, -2, 2, -1, 0, 1, -2, 1, +1, 0, 1, -1, 1, -1, 0, 0, +2, -3, 2, 0, 0, -1, 0, 1, +-3, 3, 1, -3, 4, -3, 2, -2, +2, -1, 2, -2, 3, -2, -2, 2, +0, -1, 1, -1, 1, 0, -1, 1, +-1, 0, 2, -2, 2, -3, 4, -4, +2, -1, 1, -2, 2, -3, 4, -5, +5, -4, 1, -1, 1, -2, 1, 0, +-2, 2, -1, 0, 2, -2, 2, -1, +0, -1, 1, -1, 1, -3, 5, -5, +2, 1, -3, 3, -2, 2, -2, 2, +0, 0, 1, 0, 1, -1, 0, 1, +-2, 3, -2, 1, 1, -1, 1, 0, +1, -3, 6, -5, 2, -1, -1, 1, +-2, 2, 0, 0, 0, 1, -1, 0, +2, -1, -1, 3, -4, 4, -3, 1, +0, -1, 4, -4, 1, 0, -2, 2, +-1, 0, 0, 1, -3, 4, -1, -1, +2, -1, 2, -3, 3, -2, -1, 2, +-2, 2, -1, 1, -2, 2, 0, -1, +3, -3, 1, 0, 0, 0, 0, 0, +0, 0, 2, -2, 0, 2, -4, 4, +-1, -1, 3, -2, -1, 2, 0, -1, +1, 0, -2, 0, 1, -1, -1, 1, +0, 0, 1, -2, 1, -1, 2, -2, +2, -2, 1, 0, 0, -1, 2, -1, +1, -1, 1, 0, -1, 1, -1, 2, +-1, 1, -2, 3, -3, 2, 0, 0, +-2, 4, -4, 2, 1, -1, -1, 2, +-3, 3, -1, 1, 0, 0, 0, 0, +0, -1, 1, 0, -1, 1, 0, 0, +-2, 3, -3, 2, 1, -2, 3, -3, +2, -3, 3, -2, 2, 0, -2, 3, +-4, 4, -1, 0, 1, -1, 0, 1, +-3, 2, -1, 0, 0, 0, -2, 2, +-1, 0, 1, -1, 0, 0, -1, 1, +-1, 0, -1, 2, -3, 3, -1, 2, +-3, 3, -1, -1, 1, 0, 0, -2, +4, -3, 1, 0, 0, -1, 1, -1, +1, -2, 1, -1, 0, 0, 0, 0, +2, -3, 3, -2, -2, 3, -3, 2, +0, -1, 0, 1, -2, 1, 0, 0, +0, 0, 1, -2, 1, -1, 2, -3, +2, -1, 0, 1, -2, 1, 0, -1, +1, -2, 4, -5, 4, -2, -3, 5, +-4, 3, 1, -2, 1, 0, 0, -1, +2, -1, -1, 1, -1, 0, 1, -2, +2, -1, 0, -1, 3, -3, 0, 0, +1, -1, -2, 3, -3, 2, -1, 1, +-3, 4, -2, 1, 0, 0, 0, 0, +1, -2, 2, -2, 2, -2, 0, 0, +-2, 3, -4, 3, 0, -2, 2, -1, +-1, 1, 1, -1, 1, -1, 1, -1, +-1, 1, -2, 2, -1, 1, 0, -1, +2, -2, 1, -1, 1, -1, 1, 0, +-1, 2, -3, 3, 0, -1, 0, 1, +-1, 1, 0, -1, 2, -2, 0, 1, +-2, 2, 1, -2, 1, 0, 1, -3, +5, -5, 1, 1, -2, 1, 0, -1, +1, 0, 1, -1, 1, 0, -2, 2, +-1, 1, 1, -1, 0, 1, -2, 1, +1, -2, 3, -3, 2, -1, -2, 3, +-3, 1, 1, -2, 4, -3, 0, 1, +-3, 3, -2, 2, -2, 1, 1, -3, +3, -2, 1, -1, 2, -2, 0, 1, +-2, 2, 0, 0, -1, 1, -2, 2, +-1, 0, 0, 0, 1, -1, 1, -1, +1, -2, 3, -3, 2, 0, -3, 3, +0, -2, 3, -3, 1, 1, -2, 2, +-1, 0, 0, -1, 0, 0, -1, 2, +-4, 6, -4, 3, -1, 0, 3, -3, +3, -1, -1, 3, -3, 3, -2, 2, +0, -1, 1, -1, 1, 0, -2, 1, +0, 1, -2, 2, 0, -1, 2, 0, +-3, 4, -2, 1, -1, 2, -2, 2, +-2, 2, -1, -1, 2, -2, 1, 0, +-1, 1, -1, 2, -2, 3, -3, 2, +2, -3, 3, -2, 2, -3, 3, -3, +1, -1, 1, 0, 0, 0, 1, -1, +1, -1, 2, -2, 1, 0, 1, -2, +1, 0, -2, 2, -1, 1, -2, 2, +-1, 1, -2, 3, -4, 2, 0, 0, +0, 0, 1, -1, 1, -2, 2, -2, +1, 0, -2, 2, -2, 1, -2, 3, +-3, 3, -2, 1, 0, 0, 1, -2, +2, -1, -2, 2, -2, 0, 2, -2, +-1, 3, -3, 2, 0, 0, -2, 3, +-3, 3, -1, 0, 1, -2, 1, 1, +-2, 2, 0, -1, 0, -1, 2, -3, +2, -1, 0, 0, -2, 2, -2, 2, +-1, 2, -3, 2, 1, -2, 2, -2, +2, -1, 0, 1, -1, 1, 0, 0, +1, 0, -3, 4, -3, 2, 0, 0, +-2, 2, 0, -1, 3, -3, 3, -2, +2, -1, 1, 0, -1, 1, 0, -1, +2, -2, 1, -1, 2, -3, 4, -4, +2, -2, 0, 0, -1, 1, -1, 1, +0, 0, 1, -1, 1, 0, -1, 1, +0, -2, 1, 0, -1, 0, 2, -2, +2, -2, 0, 1, -3, 3, -2, 1, +1, -1, -2, 3, -4, 3, -1, 1, +-2, 3, -4, 4, -1, -1, 3, -3, +1, 0, 0, -1, 0, 0, 0, 0, +0, 0, -1, 2, -4, 4, -3, 2, +2, -2, 0, 3, -4, 2, 1, -2, +1, 1, -1, 0, 0, 1, -2, 2, +-1, 2, -1, 0, 2, -2, 0, 1, +-1, 0, 2, -3, 4, -4, 4, -5, +5, -4, -1, 3, -3, 1, 2, -3, +3, -1, -1, 2, -1, 1, 0, 0, +0, 0, 0, 0, 0, -1, 1, -1, +1, -1, 0, 0, -2, 3, -3, 2, +-2, 2, -4, 4, -4, 2, 2, -3, +2, 0, -1, 1, 0, 0, 1, -1, +2, -2, 1, 0, 0, 0, 0, 1, +0, -2, 2, -1, 0, 1, -4, 6, +-6, 5, -3, 2, 0, 0, 1, -1, +0, -1, 2, -3, 1, 1, -2, 1, +-1, 1, -3, 3, -3, 3, -3, 3, +-2, 1, 1, -1, 0, 1, -2, 1, +2, -3, 3, -1, -2, 2, 0, -2, +4, -4, 2, -1, 0, 1, -3, 3, +-2, 1, 1, 0, 1, -1, 1, 0, +-1, 0, 2, -1, 0, 0, -1, 2, +-3, 4, -4, 2, 0, -1, 2, -2, +2, -1, 1, 0, -2, 3, -4, 3, +-1, 0, 0, 0, 0, -1, 3, -4, +5, -4, 1, 0, 1, -3, 3, -2, +-1, 0, 2, -3, 0, 1, -1, -1, +4, -5, 2, 0, -1, 0, 2, -2, +2, -2, 1, -1, 2, -2, 3, -3, +4, -3, 0, 2, -3, 3, 0, -1, +1, 0, 0, 0, 1, -1, 1, 0, +-1, 1, 0, -1, 1, -1, 0, -1, +3, -3, 3, -2, 1, -1, 0, 0, +1, -1, 0, 0, 1, -2, 1, -1, +0, 0, 0, 1, -1, 0, 1, -2, +1, 0, 0, 0, 1, -1, 0, 2, +-5, 5, -1, -2, 3, -2, -2, 3, +-5, 5, -2, 0, 2, -1, 0, 1, +-2, 2, -3, 3, -3, 3, -2, 1, +0, -1, 3, -4, 3, -1, 0, -1, +3, -3, 0, 2, -2, 2, -2, 1, +0, -1, 1, 0, -3, 3, -4, 4, +-2, 1, -1, 2, -3, 3, -3, 2, +-1, 2, -2, 1, 2, -3, 2, 0, +-1, 1, -2, 2, 0, -1, 0, 1, +-3, 3, -1, 1, -1, 1, -1, 1, +1, -1, 0, 0, -1, 1, 1, -2, +2, -2, 1, -1, 0, 1, -2, 2, +-3, 3, -3, 2, 1, -3, 4, -2, +-2, 3, -4, 5, -2, -1, 4, -3, +0, 1, -1, -1, 1, -1, 0, 0, +-1, 1, -1, 0, 3, -3, 1, 1, +-2, 2, 0, -1, 1, -1, 1, -1, +2, -2, 1, 0, -1, 2, -1, -1, +3, -3, 4, -5, 3, -1, -3, 5, +-6, 4, -2, 1, 2, -3, 3, -2, +2, -2, 3, -3, 1, 0, 1, -1, +1, -1, -1, 2, -3, 3, -1, 1, +-1, 1, 0, 0, 3, -3, 3, -2, +1, 0, -1, 1, 1, -2, 2, -2, +1, 1, -1, 0, 3, -3, 3, -2, +0, 1, -1, 0, 2, -2, 1, -1, +-1, 2, -2, 2, -2, 2, 0, 0, +1, -2, 0, 2, -4, 2, 1, -2, +3, -2, 0, 1, 1, -3, 4, -3, +1, -1, -1, 1, 0, -3, 5, -5, +2, 0, 0, -2, 3, -2, 2, -4, +5, -4, 0, 2, -2, 2, -1, 0, +2, -2, 2, -2, 1, 0, 0, -1, +3, -4, 4, -3, 2, -1, 0, 1, +-2, 2, -1, 0, 1, -1, -1, 2, +-1, 0, 1, 0, -2, 2, 0, 0, +-1, 0, 0, 1, -2, 2, 1, -2, +4, -4, 3, -1, 0, 1, 0, -1, +2, -2, 1, -1, 3, -3, 2, -2, +2, 0, -1, 1, -1, 2, 0, -1, +1, 0, -1, 0, 2, -1, -2, 2, +0, -2, 4, -3, 0, 0, 1, -1, +0, 0, 1, 0, 0, 0, -1, 3, +-3, 2, -1, 1, -1, -1, 2, -1, +0, 0, -1, 1, 0, 0, 0, 0, +0, 0, 0, -2, 3, -2, -1, 1, +-1, 1, 0, -2, 2, 0, -3, 3, +-3, 3, -3, 2, 0, -1, 2, -2, +1, -1, 0, -1, 1, -1, 0, 1, +-4, 4, -3, 2, -2, 0, 2, -3, +2, -2, 0, 1, -2, 0, 0, 0, +-1, 1, -2, 3, -2, 2, -4, 5, +-5, 3, -1, 0, 0, 1, -2, 1, +1, -2, 4, -4, 5, -3, 1, -1, +2, -2, 2, -2, 2, -1, -1, 0, +-1, 2, -2, 1, 1, -2, 4, -4, +3, -2, 1, 0, -2, 1, 2, -1, +-2, 2, -1, 1, -2, 2, -2, 1, +0, -1, -2, 3, -1, -1, 3, -2, +1, -1, 2, -2, 2, -1, -1, 2, +-1, 0, 0, 0, 0, 0, -1, 0, +0, 2, -2, 0, 2, -2, 0, 0, +0, 1, 0, -1, 2, 0, -2, 3, +-3, 2, 0, -2, 2, -1, 1, -2, +2, -2, 0, 1, 0, -1, -1, 3, +-5, 2, 5, -5, 2, -1, 0, 1, +-2, 2, -2, 2, 0, -1, 0, 1, +-2, 2, 0, -1, 2, -1, -2, 3, +-3, 2, 0, -1, 1, 1, -2, 0, +1, 1, -4, 3, -2, 1, 1, -3, +2, -2, 1, -1, 0, 1, -1, 1, +1, -3, 5, -4, 3, -3, 2, 0, +0, -2, 4, -4, 3, -3, 4, -2, +1, 0, -1, 1, 2, -4, 4, -3, +1, 0, -1, 2, -3, 2, 0, -2, +1, 0, 0, -1, 4, -3, 1, -2, +2, 0, -2, 1, 0, 1, -1, 1, +0, 0, 0, -1, 0, 1, -2, 2, +0, -2, 4, -3, 1, -1, 1, 0, +-2, 1, 0, 1, -3, 2, 2, -2, +1, 0, 0, 0, 1, -2, 1, 0, +-2, 2, -2, 3, -3, 2, -1, 1, +0, -1, 1, -3, 4, -3, 1, -1, +1, 0, -1, -2, 3, -3, 2, -3, +4, -2, 1, -2, 2, 0, -2, 2, +0, -1, -1, 3, -4, 3, 0, 0, +1, -1, 0, 1, -3, 1, 0, 0, +0, -1, 2, -1, -1, 1, 0, 0, +1, -2, 0, 1, -1, -1, 4, -3, +-1, 4, -5, 3, -1, 0, 1, -2, +4, -2, -1, 1, 0, 0, -2, 2, +-1, 1, 0, -2, 4, -2, -1, 2, +-2, 1, 2, -3, 4, -4, 5, -4, +3, -2, 2, -1, 0, 0, 1, -1, +0, 0, 2, 0, -2, 2, -1, 1, +1, -2, 3, -1, 1, -2, 1, 0, +-3, 3, -3, 2, 0, 0, -2, 2, +-2, 3, -2, 0, 2, -1, -1, 2, +-3, 4, -5, 3, 0, -1, 0, 0, +1, -2, 2, -2, 1, 0, 0, -1, +2, -3, 3, -2, 0, 0, 1, -1, +0, 1, -3, 5, -6, 4, 1, -1, +1, -2, 1, 0, 0, -3, 5, -3, +2, -2, 2, -1, -1, 0, 0, -1, +1, 0, 0, -1, 0, 2, -1, -2, +4, -2, 0, -1, 4, -4, 1, -1, +1, 0, -2, 2, -1, 0, 1, -1, +-1, 2, -2, 1, 0, -1, 3, -4, +3, -2, 1, 1, -1, 0, 3, -1, +-2, 3, -3, 5, -4, 2, 0, 2, +-5, 5, -1, 0, 1, -1, 0, 1, +-2, 1, 1, -1, 1, 1, -2, 2, +-1, 2, -2, -1, 3, -2, 0, 0, +0, 2, -3, 1, 2, 0, -1, 1, +-2, 3, -3, 1, 2, -3, 4, -4, +2, -1, 0, 1, -3, 2, 1, 0, +-2, 2, -3, 4, -3, 1, 2, -1, +-1, 0, 0, 0, 1, -3, 3, -1, +-3, 3, -2, 2, 1, -3, 4, -4, +5, -4, 1, -1, 2, -1, 0, -1, +2, 0, -1, -1, 2, 0, -2, 1, +2, -3, 3, -2, -1, 3, -3, 2, +-1, 1, -1, 2, -3, 2, 0, 0, +0, -1, 1, -1, -1, 0, 2, -2, +2, -3, 2, 0, -3, 2, -1, 1, +0, -1, 0, 1, -2, 3, -4, 3, +-2, 1, -1, 1, -2, 4, -5, 5, +-4, 4, -4, 3, -1, 3, -4, 1, +5, -5, 2, -1, 1, 0, -1, -1, +3, -4, 4, -3, 1, -2, 3, -4, +3, -1, -1, 2, -3, 3, -1, 0, +2, -4, 5, -2, -2, 1, 0, 0, +-2, 1, 0, 1, -3, 4, -5, 5, +-5, 3, -1, 1, 0, 0, -1, 0, +0, 1, -4, 3, -1, 2, -1, -1, +6, -6, 5, -4, 3, 0, -2, 2, +-1, 2, -1, -1, 4, -3, 0, 1, +-2, 3, -2, 2, 0, -1, 2, -1, +-1, 0, 0, 2, -2, 0, 3, -3, +1, -1, 2, -1, 0, -2, 2, 0, +-1, 1, -1, 2, -2, 2, -1, -1, +1, 0, -3, 2, 1, -1, -1, 0, +1, 0, -1, 0, 0, 2, -5, 4, +1, -3, 4, -4, 3, -2, 2, -2, +2, -2, 2, -1, -1, 2, 0, 0, +0, -1, 0, 1, -2, 2, -2, 3, +-2, 1, 0, 2, -5, 4, -1, 0, +-1, 1, -1, 2, -2, 2, -1, 0, +3, -3, 0, 2, -3, 4, -4, 4, +-4, 4, -4, 3, -2, 2, -2, 0, +1, 2, -4, 3, -1, 1, -1, 1, +-1, 1, 1, -1, 1, 0, 0, 0, +-2, 2, 0, 0, 0, 1, 1, -1, +2, -3, 2, 0, -1, 1, -1, 1, +0, -1, 1, 1, -2, 1, 1, -1, +2, -3, 3, -3, 1, 0, 0, -2, +4, -3, 1, -1, 3, -3, 3, -3, +3, -3, 2, -2, 1, 0, 0, -1, +1, 1, -4, 2, 0, 0, -2, 2, +0, -2, 5, -3, 1, -2, 4, -3, +3, -3, 4, -3, -1, 1, 0, 0, +1, -2, 4, -3, 3, -4, 5, -3, +-1, 2, -2, 1, -1, 0, 0, 0, +1, -1, -1, 0, 1, 0, -2, 1, +1, -1, 0, 1, -1, 2, -3, 2, +-1, 2, -3, 1, 1, 0, -1, 0, +2, -2, 1, 0, -3, 4, 0, -2, +4, -3, 2, -2, 2, -2, 1, 1, +-3, 3, -2, 2, -1, -1, 2, -1, +1, -2, 2, 0, -3, 3, 0, 0, +1, -1, -1, 1, -1, 2, -4, 4, +-4, 4, -3, 1, 2, -2, 2, 0, +-2, 4, -6, 5, -1, 1, -4, 4, +-4, 3, -2, 0, 1, -1, 0, 1, +-2, 2, 0, -1, 1, -1, -1, 1, +-1, 0, 0, 1, -1, -1, 1, 0, +-2, 2, -1, 1, -2, 1, 1, -1, +1, -2, 2, -3, 4, -4, 3, -2, +-1, 1, -2, 1, 0, 0, 0, -1, +1, 0, -2, 1, 1, -1, 1, -1, +1, -1, 0, -1, 0, 0, -2, 1, +0, -1, 2, -1, 0, 1, -1, 1, +-3, 4, -4, 4, -4, 2, -1, 1, +-1, 0, 1, -1, 1, -2, 5, -5, +4, -2, -2, 5, -6, 4, 0, -2, +1, -1, -1, 0, -1, 2, -4, 3, +-2, 4, -4, 4, -1, 1, 0, -1, +2, 0, -4, 3, -1, 0, 1, -2, +3, -2, 0, 0, 2, -2, 1, 1, +-2, 1, 0, 1, -2, 0, 3, -4, +1, -1, -1, 1, 0, -1, 1, 1, +-1, 2, 0, 1, 1, -2, 5, -5, +3, -3, 3, -4, 0, 1, -3, 2, +-1, 2, -4, 4, -2, 3, -2, 2, +2, -3, 3, -3, 0, 1, -3, 1, +-1, 1, -3, 2, -1, 2, -1, 2, +0, 0, 2, -1, 0, 0, 0, -1, +-2, 1, -3, 1, -2, 1, -1, 3, +-4, 4, -1, 1, 2, -2, 0, 2, +-2, 1, 0, 0, -2, 1, -2, 0, +1, -2, -1, 2, -2, 2, 2, -2, +3, 0, -2, 3, -4, 4, -2, -2, +3, -4, 1, -1, 1, -2, 4, -4, +5, -3, 3, -1, 2, 0, -1, 3, +-2, 1, -2, 2, -4, 2, -1, 0, +0, -1, 3, -2, 3, -2, 5, -3, +2, 0, 0, 1, -2, 1, -2, 1, +-3, 2, -2, 1, -1, 2, -2, 3, +0, 2, 1, -1, 3, -1, -1, 1, +-3, 2, -5, 4, -4, 2, 0, -2, +2, 0, 0, 1, 1, 1, 2, -1, +2, 0, -2, 2, -3, 1, -1, -1, +-1, 0, -3, 4, -4, 3, 1, 1, +1, 1, -1, 3, -3, 3, -3, 2, +-4, 2, -2, 0, -2, 0, 0, -1, +3, -1, 2, -1, 4, -2, 3, -2, +1, 2, -6, 4, -4, 1, -5, 4, +-5, 3, 0, -2, 4, -1, 0, 3, +-1, 2, -2, 3, -5, 4, -3, 1, +-2, -2, 0, 0, -4, 3, -1, 2, +-1, 3, -3, 6, -3, 4, -3, 4, +-4, 1, -2, -1, 0, -2, -2, 1, +-1, 0, 1, 1, 1, 1, 1, 1, +-1, 3, -4, 4, -5, 3, -3, -1, +0, -3, 2, -4, 3, -1, 0, 2, +3, -2, 4, 0, -3, 5, -3, 1, +-3, 2, -5, 2, -5, 2, -2, 0, +-2, 4, -3, 4, 1, 1, 3, -1, +2, -1, -1, 1, -5, 2, -3, 0, +-3, 1, -1, 1, 0, 2, 0, 1, +5, -3, 4, -2, 3, -2, -1, 0, +-4, 2, -5, 2, -2, 0, 3, -4, +4, -1, 4, -2, 6, -2, 2, 0, +0, 0, -2, 1, -5, 2, -5, 2, +-1, -1, 1, 1, 1, 2, 2, 2, +0, 1, 0, 2, -3, 1, -4, 2, +-5, 0, 1, -4, 1, -1, 1, 1, +3, -1, 4, -1, 2, 1, -2, 2, +-2, 1, -5, 2, -3, -1, -3, 2, +-3, 4, -2, 3, 3, 0, 3, 0, +1, 1, -1, 0, -2, 0, -3, -1, +-1, -2, -1, -1, 2, -2, 4, -1, +3, 1, 2, 1, 1, 0, -1, 1, +-5, 1, -2, 0, -3, 0, -2, 1, +1, -1, 5, -1, 3, 2, 2, -1, +1, 1, -3, 1, -3, 0, -3, -2, +-1, 0, -1, -1, 5, -3, 6, -2, +3, 2, 0, 0, 1, -1, -1, -1, +-3, 0, -4, 0, -3, 1, 0, 0, +1, 1, 6, -3, 5, -1, 1, -1, +1, -2, -4, 3, -6, 0, 0, -4, +2, -2, 2, 0, 3, 0, 4, 0, +4, -1, -1, 4, -6, 2, -5, 0, +-3, -1, -6, 4, -2, 0, 3, 0, +3, 1, 4, -1, 4, 0, -2, 3, +-3, -1, -2, -2, -2, -2, -1, -1, +-1, 1, 2, 1, 5, -2, 6, -1, +3, -2, 2, -4, 3, -6, -2, 0, +-6, 1, -1, -1, 2, -1, 6, -3, +7, -2, 4, 0, 0, 0, 2, -4, +-1, 0, -6, 1, -3, 0, -2, 1, +1, 1, 4, -1, 3, 3, 1, 1, +-1, 2, -4, 0, -3, -1, -2, -3, +-1, 0, 0, 0, 3, 0, 5, -1, +4, 0, 2, 0, 0, -1, -2, -1, +-5, 0, -2, -3, 2, -4, 3, -1, +3, 1, 3, 3, -1, 5, -2, 2, +-2, -2, -1, -3, -2, -2, -4, 1, +-4, 3, -2, 4, 3, 0, 7, -2, +3, 3, -4, 3, -1, -2, -4, 0, +-5, 1, -4, 1, 2, -4, 6, 0, +2, 4, 1, 2, 4, -4, 2, 0, +-4, -1, -4, 0, -5, 0, 0, -2, +2, 0, 2, 2, 5, -2, 5, 1, +1, 1, -4, 3, -7, 2, -6, 0, +-4, 1, -3, 2, 2, -2, 8, -4, +9, -3, 5, -2, 3, -2, 0, -2, +-5, 2, -5, -2, 0, -2, 3, -3, +5, -1, 6, -2, 6, 0, 2, 1, +-1, 1, -5, 1, -7, 1, -1, -6, +4, -5, 4, -2, 4, 0, 5, 0, +6, -2, 5, -2, -2, 1, -3, -3, +-1, -5, 0, -5, 2, -1, -1, 4, +-1, 5, 2, 3, 1, 3, 1, -2, +-1, 0, -8, 3, -8, 3, -8, 3, +-1, 0, 3, 1, 4, 0, 7, -1, +3, 1, -1, 1, -4, 0, -5, 0, +-4, -1, -5, 5, -3, 1, 5, 0, +5, 0, 4, 1, 4, -2, -2, 4, +-10, 5, -10, 4, -8, 2, -1, -2, +5, -2, 6, -1, 7, -1, 2, 2, +3, -2, -3, 1, -8, 3, -8, 1, +-3, -2, 1, -1, 4, -1, 8, -3, +7, 0, 2, 2, -1, 0, -2, 0, +-9, 5, -9, 2, -6, 3, -2, 1, +4, -1, 9, -4, 10, -4, 6, -3, +1, -1, -4, 0, -8, 4, -8, 0, +-2, 0, 3, -1, 4, 3, 4, -1, +6, 0, 0, 2, -1, -2, -2, -3, +-5, 0, -4, -1, 0, 0, 3, -1, +6, 0, 5, 0, 4, 0, 2, 0, +-5, 2, -6, -1, -3, -3, -4, 3, +-2, 1, 5, 0, 5, 1, 4, 1, +4, -3, 2, -1, -4, -1, -5, -1, +-3, -3, -2, 1, -1, 2, 4, -1, +10, -5, 8, -1, 1, 1, -3, 1, +-5, 0, -7, 0, -3, -2, -1, 0, +4, -2, 5, 2, 4, 1, 4, 1, +-1, 2, -6, 3, -6, -1, -5, 0, +-5, 1, -2, 3, 2, 1, 5, 1, +4, 1, 4, -1, -2, 2, -5, -1, +-5, -1, -3, -4, 0, 0, -1, 2, +4, 0, 4, 3, 1, 4, 0, 0, +-1, 1, -7, 2, -7, 2, -6, 1, +-3, 2, 2, -2, 5, 2, 5, 0, +5, -1, 2, -1, -2, -1, -4, -2, +-3, -3, -1, -1, -3, 3, 3, 0, +5, 1, 6, -1, 5, -1, 1, 0, +-6, 2, -6, -1, -6, 2, -5, 1, +2, -2, 5, -1, 8, -2, 5, 2, +1, 0, 0, -2, -2, -3, -5, -1, +-3, -2, 0, -2, 5, -3, 5, 2, +4, 1, 3, 1, 2, 0, -5, 4, +-7, -1, -3, -2, -4, 0, -1, 2, +-1, 4, 2, 3, 5, -1, 4, 1, +0, -2, -1, -2, -4, -2, -4, -1, +-2, -2, 4, -3, 3, 3, 2, 3, +4, 2, 1, 0, 1, -2, -3, -1, +-5, 1, -7, 0, 0, -2, 3, -1, +6, -1, 7, 0, 1, 5, -2, 3, +-5, 3, -6, -1, -4, -2, -1, -3, +0, 0, 4, -2, 8, -3, 10, -5, +7, -2, 2, -2, -3, 1, -4, -3, +-4, 0, -6, 3, -3, 1, 7, -5, +10, -3, 6, 0, 2, 1, -3, 2, +-6, 1, -5, -2, -4, 1, -4, 1, +3, -1, 5, -1, 8, -3, 5, 2, +-2, 4, -5, 3, -6, 0, -4, 0, +-6, 1, 0, -1, 5, -3, 8, -1, +7, -3, 4, 2, -1, -1, 0, -2, +-3, -2, -6, 2, -5, 0, 1, -1, +4, -1, 3, 3, 2, 3, 1, 1, +-2, 2, -8, 3, -5, -2, -2, -4, +3, -5, 3, -1, 5, -1, 8, -3, +6, 0, 1, -1, 2, -4, -3, 0, +-7, 2, -5, 2, -4, 3, 3, -1, +6, 0, 6, 0, 5, -1, 2, -1, +-3, 1, -6, 1, -8, 4, -7, 2, +-1, 0, 3, -1, 6, -1, 6, -2, +3, 1, -2, 0, -5, 1, -7, 0, +-6, 2, -4, 0, 0, 2, 2, 1, +5, 1, 3, 1, -1, 4, -5, 2, +-6, 3, -8, 3, -6, 2, -3, 3, +-1, 3, 3, 3, 3, 1, 5, 1, +-1, 1, -2, 1, -5, 0, -6, 2, +-4, -1, 2, -1, 3, 1, 2, 3, +4, -1, 2, 0, 1, -3, -4, 2, +-7, -1, -4, -2, 0, -3, 0, 2, +2, -1, 7, -3, 9, -6, 6, -2, +-1, 0, -2, -2, -4, 1, -5, 3, +-3, 2, 2, 0, 7, -2, 5, 2, +4, -2, 6, -3, 1, -3, 0, -4, +-3, 0, -6, 4, -3, 2, 3, -1, +4, 1, 3, 0, 2, 0, 0, -2, +-3, 0, -4, -2, -4, 0, -3, -1, +1, -2, 6, -5, 5, 2, 0, 1, +4, -3, 1, -2, -3, 1, -4, 0, +-5, 2, -1, 0, 0, 3, 3, 1, +4, 1, 5, -2, 5, -3, 1, -1, +-1, -4, 3, -6, 2, -4, 4, -4, +3, 1, 4, 0, 3, 2, -1, 3, +-1, 0, -4, 2, -5, -2, -2, -4, +3, -8, 5, -3, 2, 0, 2, 1, +3, -1, 2, 0, -2, 0, -3, -1, +-3, -1, -4, 1, 0, -2, 2, 1, +1, 3, 1, 4, 2, 1, 0, 3, +-2, 0, -3, 1, -4, 0, 0, -2, +2, -1, 2, 1, 4, -1, 6, -2, +5, -2, -1, 3, -3, 0, -2, -2, +-3, 1, -4, 1, -1, 1, 1, 0, +3, 0, 2, 0, -2, 3, -3, -1, +0, -3, -3, 0, -6, 2, -1, -3, +1, 1, 0, 2, 2, 2, 2, -1, +3, -1, 0, -1, 0, -4, 3, -4, +-2, 3, -3, 3, 2, -1, 5, 0, +3, 2, 1, 2, -3, 4, -4, 0, +-1, -2, -2, -1, -1, 0, -1, 2, +-2, 5, -1, 2, 5, -5, 7, -6, +4, -3, -5, 3, -6, 0, -3, -1, +-2, -2, 1, 0, -1, 2, 3, -1, +4, -2, 1, 0, 0, -2, -2, 1, +-4, -1, 1, -2, -1, 1, 3, -1, +5, 0, 3, 1, 5, -1, -1, 4, +-1, -1, -1, 0, 0, -2, 1, -1, +3, -3, 6, -3, 4, 1, -1, 3, +1, 0, 0, 0, -3, 1, -5, 1, +-5, 1, -5, 2, -3, 0, 1, -1, +1, 0, 2, -2, 0, 0, -2, 0, +-4, 1, -4, 0, -3, 1, -4, 3, +-2, 1, 3, -1, 3, 1, 3, -1, +2, 0, 2, -1, -2, 5, -5, 4, +-1, 3, 0, 2, 2, 2, 3, 0, +5, 0, 2, 1, 1, 0, 1, -2, +-1, 0, -4, 1, -4, 1, -2, 0, +-2, 1, -1, 1, -3, 2, -4, 3, +-7, 3, -5, 0, -5, 1, -6, 1, +-3, -2, 1, -2, 2, 0, -1, 3, +3, -4, 6, -2, 1, 0, 1, 0, +1, -1, 4, -3, 6, -3, 5, -1, +7, -2, 7, -2, 7, -1, 1, 2, +1, 0, 1, -1, 4, -5, 2, -1, +0, -2, 1, 0, -2, 1, -1, 0, +-2, -1, -3, 0, -7, 2, -7, 1, +-6, 0, -4, -1, -3, -1, -2, 0, +-3, 3, -3, 2, -1, 2, -2, 1, +0, 1, 0, 1, 1, 0, 4, -1, +2, 3, 6, -1, 5, 4, 2, 3, +5, 1, 4, -1, 3, 1, 0, 2, +0, 2, -1, 2, -2, 2, -1, 0, +1, -2, -3, 2, -8, 4, -6, 0, +-8, 1, -7, -2, -3, -5, -2, -2, +-8, 3, -3, -4, 2, -3, -2, 0, +-3, 3, -6, 5, -4, 3, -2, 3, +0, 1, 3, 0, 8, -2, 7, 2, +7, 2, 5, 4, 5, -1, 11, -5, +9, -3, 5, -1, 4, 0, 0, 4, +-1, 2, 1, 0, 1, -1, -2, 1, +-5, 0, -7, 0, -6, -3, -5, -2, +-10, 2, -13, 5, -10, 2, -6, -1, +-3, -2, -4, 1, -4, -1, -2, 0, +-5, 3, -2, 0, 3, 2, 1, 4, +7, -1, 9, 0, 7, 3, 9, 0, +8, 1, 9, -3, 9, 0, 6, -2, +9, -3, 7, -1, 5, 0, 1, 2, +-2, 3, -4, 1, -5, -1, -7, -1, +-10, 1, -12, 1, -11, 0, -9, -1, +-9, 1, -10, 1, -9, 2, -10, 3, +-9, 3, -8, 2, -4, 0, 0, 0, +-1, 4, 2, 3, 6, 2, 9, 0, +12, -1, 12, -1, 8, 4, 5, 3, +9, 0, 10, 0, 10, -2, 10, -2, +8, -1, 4, 1, 2, -2, 0, -1, +-5, -1, -8, 1, -13, 3, -14, 2, +-12, 0, -12, 2, -14, 2, -11, -1, +-6, -6, -5, -5, -7, -3, -6, -2, +-2, -3, -3, 3, -2, 3, 5, -1, +11, -1, 10, 0, 12, 0, 10, 3, +8, 3, 9, 2, 13, -3, 16, -1, +12, 1, 14, -3, 10, 2, 2, 4, +0, 0, -2, 0, -8, 2, -8, -2, +-8, -2, -9, -1, -11, 0, -9, -5, +-8, -3, -13, -1, -14, 1, -16, 0, +-12, -2, -9, -1, -5, -2, 2, -4, +5, -1, 5, 1, 8, 0, 11, -1, +10, 1, 10, 0, 14, -2, 16, -1, +16, 0, 17, -1, 17, 0, 15, 0, +13, -3, 10, -3, 6, -3, 0, -1, +-4, -1, -7, 0, -11, 1, -8, -2, +-10, -1, -13, 0, -16, 0, -19, 2, +-18, -1, -17, 0, -14, -2, -11, 0, +-6, -2, 0, -3, 4, -3, 6, -1, +8, -3, 10, -2, 11, -2, 15, -3, +17, -3, 20, -3, 22, -3, 23, -2, +19, 1, 14, 2, 9, 3, 8, -2, +4, 0, -1, 1, -1, -4, -1, -3, +-7, 1, -11, 3, -14, 2, -17, 0, +-21, 3, -25, 3, -24, 1, -18, -2, +-16, 2, -17, 4, -12, 4, -4, -2, +1, -1, 0, 1, 3, 0, 5, 0, +9, 0, 11, 2, 15, 1, 21, 1, +21, 1, 25, -2, 22, -1, 18, -2, +13, 1, 8, 0, 5, 2, 1, 1, +1, 0, 0, -2, -3, -1, -9, 1, +-13, -1, -18, 0, -23, 1, -24, 0, +-23, -1, -19, -2, -15, -1, -15, 2, +-12, 1, -9, 1, -6, 0, -5, 3, +-3, 2, 5, -2, 9, 1, 13, 0, +22, -4, 25, 0, 24, -1, 26, -3, +21, 0, 16, 0, 14, 0, 9, 3, +7, 1, 8, 0, 6, -1, 4, -3, +0, -3, -11, 3, -19, 1, -18, -3, +-23, 2, -27, 4, -24, 2, -22, 3, +-20, 3, -17, 0, -12, -1, -13, 2, +-15, 5, -9, 0, 0, -2, 4, -1, +13, -3, 18, 0, 18, 3, 22, -1, +24, 0, 20, 1, 19, -1, 20, -3, +19, -2, 17, 0, 13, 1, 14, -3, +11, -1, 1, 1, -2, -3, -8, -3, +-15, -1, -19, -1, -22, 0, -22, 1, +-20, -2, -15, -5, -16, -1, -19, 1, +-20, 2, -17, -1, -11, -3, -6, -2, +-3, 2, 3, 1, 11, 0, 15, 3, +15, 5, 18, 2, 19, 3, 15, 4, +18, 0, 21, -2, 23, -3, 21, 1, +17, 1, 14, 2, 6, 2, 0, 3, +-7, 1, -10, -1, -15, 0, -18, 1, +-21, 2, -19, -1, -17, -2, -18, -2, +-19, -1, -24, 2, -23, 0, -19, -1, +-15, 0, -8, -1, -1, 0, 4, 2, +8, 3, 11, 3, 15, 1, 17, -1, +19, -2, 20, -1, 22, -1, 24, 0, +23, 1, 22, 1, 20, 0, 16, 0, +7, 2, 2, -1, -4, -1, -10, 1, +-12, 0, -14, -1, -14, 0, -19, 2, +-19, -1, -21, -1, -25, 0, -24, -3, +-23, -1, -20, -1, -14, -2, -6, -3, +1, -2, 4, 2, 3, 4, 8, 0, +12, 0, 12, 1, 15, 0, 20, 0, +24, -2, 28, -2, 29, -2, 25, 1, +19, 1, 16, -4, 13, -4, 2, 2, +-4, 1, -5, 0, -7, 0, -11, 3, +-13, -1, -15, 1, -24, 4, -27, 1, +-25, -3, -22, -4, -21, -2, -20, 1, +-15, 1, -10, 4, -8, 4, 0, -2, +8, -5, 8, -3, 10, -3, 13, -1, +15, 1, 20, 1, 24, 0, 28, -1, +27, -2, 25, -1, 18, 1, 12, 0, +10, -1, 4, 2, -2, 4, 1, -4, +3, -5, -5, 2, -14, 3, -18, 1, +-22, 1, -24, -2, -23, -3, -23, -1, +-21, 1, -19, 3, -16, 3, -11, 2, +-9, 2, -6, 0, -2, -1, 2, -1, +6, -2, 15, -4, 20, -3, 26, -5, +27, -1, 24, 1, 23, 1, 17, 3, +14, 0, 15, -3, 14, -3, 9, 0, +6, 2, 2, 1, 1, -1, -5, 0, +-10, -1, -16, 0, -21, -1, -21, -3, +-20, -3, -20, 0, -20, 3, -18, 2, +-13, -2, -10, -2, -10, -1, -7, -3, +-1, -6, 2, 0, 4, 0, 14, -2, +18, 0, 20, 1, 22, -1, 22, -1, +20, -1, 19, -3, 18, -3, 15, 1, +12, 1, 10, 2, 8, 2, 7, -2, +4, -2, -4, -1, -11, 0, -17, 0, +-17, -3, -17, -2, -18, 1, -20, 3, +-15, -3, -11, -4, -13, -1, -13, 0, +-17, 4, -13, 0, -4, -4, 4, -3, +5, 3, 8, 2, 15, 1, 17, -1, +18, 0, 17, -1, 17, -1, 16, -1, +17, -2, 19, -4, 19, -1, 14, 1, +12, -2, 8, -2, 1, -1, -6, 0, +-9, -1, -14, 2, -15, -1, -13, 0, +-17, 4, -17, 3, -16, 0, -15, 0, +-19, 2, -19, 1, -16, 1, -13, 3, +-9, 4, -3, 3, 5, 0, 7, 3, +6, 5, 8, 4, 10, 2, 11, 3, +10, 3, 14, 1, 17, -1, 20, -2, +17, 2, 11, 3, 8, 4, -1, 5, +-2, -1, -4, 0, -8, 1, -9, 0, +-9, -1, -7, -3, -7, -3, -12, -1, +-13, -4, -14, -1, -17, -1, -15, 0, +-16, 1, -8, -2, -4, 0, 0, 0, +4, -1, 7, -1, 8, 0, 6, 1, +7, -1, 14, -5, 18, -3, 18, -1, +19, -1, 17, 0, 15, 0, 11, 0, +9, -2, 5, -1, 1, -1, 0, -1, +-5, 2, -3, -4, -1, -3, -6, 1, +-11, 2, -12, -3, -13, -3, -15, -3, +-15, -1, -13, -3, -6, -3, -4, 1, +-6, 3, -5, 4, -5, 4, -4, 5, +-2, 4, 3, 1, 6, 1, 8, 3, +8, 4, 12, 0, 18, -1, 15, 0, +15, -3, 11, 1, 1, 4, 1, -1, +4, -1, 1, 2, 0, 1, 0, -1, +-1, -3, -3, -4, -7, -2, -13, 1, +-14, 0, -13, 1, -15, 0, -11, -1, +-8, -2, -2, -3, 0, -2, -3, 0, +-2, -1, 1, -3, 0, 0, 0, 2, +5, 2, 9, 2, 12, 1, 14, -3, +15, -4, 14, -4, 10, 1, 5, 3, +4, 2, 6, -3, 7, -3, 5, -2, +4, -1, -1, 3, -5, 5, -8, 2, +-10, -2, -9, -4, -9, -3, -6, -4, +-6, -1, -6, 1, -6, -1, -2, -7, +-2, -5, -6, 0, -4, 2, -5, 3, +0, -2, 4, -3, 6, -2, 12, -5, +14, -2, 9, 4, 6, 2, 8, -2, +6, -2, 5, -2, 8, -3, 11, -2, +10, 0, 7, -2, 6, -5, 2, -4, +-1, -2, -3, -1, -4, -1, -8, 3, +-9, 1, -8, -1, -8, -1, -8, 4, +-8, 5, -9, 5, -12, 3, -11, 1, +-5, -4, 0, -3, 0, 2, 1, 5, +6, 0, 8, -4, 6, -3, 6, -3, +8, -2, 7, 1, 4, 4, 3, 2, +6, -2, 6, -1, 5, 3, 1, 5, +4, -1, 3, -1, -3, -1, -4, -4, +-4, -2, -2, 0, -2, 3, -3, 1, +-6, -1, -5, -3, -7, -2, -6, -2, +-7, 4, -7, 4, -3, 1, -4, -2, +-1, -3, 4, -2, 4, 3, 4, 0, +7, -3, 6, -5, 7, -9, 8, -6, +4, 4, 5, 4, 7, 4, 4, 1, +5, -4, 5, -7, 6, -5, 3, 2, +0, 3, 2, -4, 2, -6, 1, -6, +-1, -2, -3, 2, -6, 7, -6, 5, +-6, -1, -9, -2, -8, -2, -5, 4, +-5, 7, -4, 7, -3, 3, 1, -4, +1, -6, -1, -1, -2, 6, -1, 7, +3, 0, 5, -4, 6, -5, 4, -2, +6, 1, 2, 9, 0, 6, 3, -2, +3, -8, 4, -6, -1, 1, 1, 2, +3, 4, -1, 7, -5, 0, -6, -3, +-7, 1, -7, 6, -5, 4, -1, -1, +0, -3, 0, -7, 1, -8, 0, -1, +-2, 7, -2, 8, -3, 1, 0, -8, +0, -5, 0, -3, 5, 0, 4, 6, +2, 6, 5, -5, 5, -7, 2, -5, +2, 0, 2, 4, 3, 5, 2, 1, +0, -5, 3, -9, 3, -1, 0, 7, +-1, 5, 1, -2, 0, -2, -5, -4, +-6, -3, -5, 5, -4, 10, -2, 7, +-2, -2, -1, -8, -1, -6, -3, 1, +-5, 7, -5, 10, -2, 3, 1, -5, +1, -9, 2, -3, 0, 6, 1, 9, +0, 7, -2, 1, -2, -6, -1, -5, +2, -1, 5, 6, 4, 3, 7, -5, +8, -11, 4, -10, 0, -6, 3, 1, +3, 7, 1, 3, 1, -7, -1, -8, +0, -6, 1, 1, -4, 9, -5, 10, +-2, 0, -1, -9, -2, -9, -4, 1, +-1, 7, 0, 10, -3, 5, 0, -6, +3, -12, 3, -8, 1, 3, 0, 9, +0, 8, 1, -1, 0, -5, 1, -9, +3, -2, 3, 8, 3, 9, 2, 0, +1, -8, 2, -10, 1, -2, 1, 2, +-1, 12, -5, 10, 1, -2, -3, -8, +-6, -7, -1, 1, 0, 7, 4, 2, +-2, 2, -4, -6, 2, -12, 1, -5, +-5, 10, -3, 11, 3, 2, 2, -8, +1, -13, 2, -8, 2, 2, 2, 13, +-3, 14, -5, 4, 0, -9, 3, -9, +2, -2, -1, 9, -1, 10, 2, 7, +-1, -3, -3, -9, -3, -4, 0, 7, +1, 11, -2, 5, -1, -4, -2, -6, +-3, -7, -4, -1, -2, 7, 1, 12, +-3, 5, -7, -5, -6, -9, -1, -5, +4, 2, 1, 9, -1, 6, 0, -3, +2, -12, 2, -9, 0, 2, 0, 10, +4, 7, 4, 2, -1, -8, 2, -14, +5, -3, 5, 7, 4, 9, 0, 3, +2, -6, 2, -9, -2, -7, 0, -2, +1, 13, 1, 10, 2, -5, -2, -14, +-2, -10, 0, 0, -3, 10, -5, 9, +-3, 5, 1, -9, 3, -16, 1, -10, +-1, 7, 0, 13, 1, 9, 0, -5, +1, -12, 4, -14, 7, -1, 2, 10, +2, 9, 3, 0, 8, -12, 5, -11, +-3, -3, 0, 6, 1, 17, -2, 12, +-5, -4, -2, -14, 5, -11, 7, -1, +0, 8, -5, 11, -1, 3, -2, -8, +-2, -16, -4, -4, 0, 8, 3, 10, +2, -1, -2, -6, -1, -12, 3, -7, +-3, 6, -5, 14, 3, 5, 7, -4, +2, -9, -3, -7, 0, -2, 6, 9, +6, 11, 1, 5, -3, -9, 5, -15, +7, -5, 0, 7, -1, 9, 3, 7, +4, -1, 0, -14, -4, -13, -1, 0, +0, 16, -6, 13, -6, 0, -5, -8, +2, -12, 2, -9, -4, 7, -5, 14, +2, 5, 4, -8, -3, -12, -5, -7, +2, 2, 7, 9, 1, 13, -3, 1, +5, -14, 9, -14, 2, 0, -2, 9, +2, 10, 10, 1, 4, -2, -5, -11, +-1, -8, 3, 6, 3, 12, -2, 6, +-4, -3, -1, -9, 1, -9, -6, 0, +-10, 13, -3, 15, 1, 5, -5, -8, +-9, -12, -2, -4, 2, 5, -3, 12, +-6, 9, 0, -2, 5, -13, 4, -12, +-2, 2, -3, 14, 5, 10, 3, 5, +-2, -9, 2, -14, 8, -8, 8, 9, +0, 14, -4, 9, -1, -3, 4, -10, +0, -9, -7, 3, -3, 11, 3, 13, +1, -2, -4, -14, -2, -12, 4, -3, +3, 5, -9, 13, -11, 9, -1, -4, +1, -14, -3, -10, -5, 6, 3, 12, +5, 9, -4, 2, -7, -8, 5, -13, +8, -4, 2, 10, -4, 14, 7, -2, +12, -8, 4, -10, -1, -5, 0, 4, +6, 11, 5, 6, -1, -5, -1, -15, +3, -7, 2, 3, -6, 11, -7, 9, +-1, 5, 0, -5, -7, -12, -8, -8, +-3, 10, -1, 15, -6, 8, -7, -6, +1, -11, 8, -12, 5, -3, -4, 10, +-2, 11, 8, -2, 6, -12, 1, -12, +3, -4, 10, 4, 10, 10, -1, 8, +-1, -6, 7, -14, 9, -9, 0, 4, +-2, 7, 2, 8, 6, 0, -1, -5, +-9, -11, -2, -4, 3, 9, -2, 11, +-7, -2, -5, -5, 0, -9, 0, -6, +-7, 1, -7, 13, 3, 6, 6, -5, +-4, -11, -5, -8, 4, 0, 6, 9, +-2, 11, -3, 5, 6, -8, 12, -12, +2, -2, -4, 6, 4, 8, 8, 5, +4, -1, -5, -6, -3, -9, 9, -3, +4, 12, -6, 10, -7, 3, -1, -7, +0, -6, -9, -4, -10, 5, -4, 12, +1, 8, -2, -8, -8, -9, -4, -4, +1, 5, -1, 4, -6, 7, -1, 2, +5, -4, 2, -10, -1, -4, 2, 6, +12, 5, 11, 2, -1, -2, -2, -7, +6, -7, 8, 1, 1, 10, -4, 10, +3, -1, 9, -8, -2, -4, -8, -1, +-2, 5, 3, 10, -2, 3, -7, -8, +-3, -11, 0, -1, -2, 4, -10, 8, +-6, 4, 5, -2, 4, -11, -6, -10, +-5, -5, 7, 5, 7, 8, -5, 6, +-3, -5, 6, -7, 10, -8, 5, 1, +-2, 10, 2, 8, 10, -6, 8, -9, +-2, -5, 3, -3, 10, 5, 2, 11, +-6, 5, -4, -7, 4, -11, 2, -3, +-6, 3, -7, 6, 0, 5, 3, -3, +-3, -9, -10, -7, -4, 1, 4, 5, +-2, 5, -7, -1, -3, -1, 1, -3, +-1, -3, -2, 0, 3, 8, 9, 4, +5, -2, -1, -10, 1, -4, 7, 0, +9, 5, 1, 7, 1, 1, 10, -10, +8, -7, -4, 2, -9, 9, -2, 8, +5, 3, 0, -4, -5, -11, 0, -10, +2, 3, -5, 11, -11, 7, -6, -2, +4, -8, -1, -6, -8, -5, -6, 5, +2, 10, 4, 6, -6, 0, -8, -4, +1, -2, 5, 3, 1, 4, 0, 6, +6, 0, 10, -6, 4, -9, -1, 0, +6, 2, 11, 6, 4, 2, -2, -2, +-4, -6, 3, -7, 4, 1, -5, 9, +-5, 4, 2, 0, -2, -2, -10, -4, +-8, -6, 1, 2, 3, 8, -5, 2, +-7, -6, -2, -9, 8, -6, 1, 1, +-5, 6, -1, 7, 6, 2, 1, -5, +-7, -3, -1, 1, 9, 7, 10, 4, +2, 2, 2, -5, 9, -10, 11, -10, +1, 5, -7, 13, -4, 12, 1, -1, +-2, -4, -8, -6, 0, -3, 4, 5, +-4, 11, -10, 1, -3, -8, 1, -8, +-3, -1, -8, 3, -6, 8, 1, 6, +3, -1, -6, -7, -5, -7, 2, 4, +3, 8, -1, 6, -3, 3, 4, -3, +9, -10, 5, -6, -3, 8, 1, 12, +9, 2, 6, -5, -3, -5, -4, -1, +2, 3, 0, 10, -5, 8, -4, 3, +-1, -5, -1, -6, -7, -2, -6, 3, +1, 6, -3, 10, -8, -1, -9, -8, +-4, -4, -1, 6, -3, 7, -5, 6, +-1, 0, 3, -3, 0, -8, -2, -4, +3, 4, 9, 9, 6, 3, 1, -5, +2, -9, 5, -3, 3, 5, -2, 10, +-2, 10, 3, 0, 4, -7, -3, -6, +-4, 0, -1, 7, 0, 10, -5, 6, +-8, -4, -3, -12, 0, -5, -2, 4, +-6, 9, -3, 3, 1, 0, -2, -6, +-6, -7, -3, -5, 5, 6, 4, 9, +1, 1, -1, -7, 3, -8, 9, -5, +1, 5, -2, 11, -1, 12, 4, -2, +6, -13, 3, -11, 3, 1, 5, 8, +5, 6, -2, 2, -4, -5, -1, -8, +1, -5, -4, 6, -7, 11, -3, 7, +-3, 0, -6, -7, -6, -9, 0, -2, +3, 8, -2, 10, -4, -3, -2, -6, +-1, -4, -2, 1, -1, 4, 1, 10, +5, 5, 5, -5, 1, -13, 2, -7, +6, 4, 6, 10, 1, 7, -2, 3, +0, -5, 3, -6, -3, -1, -2, 6, +0, 10, 3, 2, -1, -6, -6, -10, +-1, -7, -1, 6, -2, 10, -4, 7, +-7, 0, -1, -12, 2, -9, -5, 0, +-5, 8, 2, 7, 6, 0, 1, -9, +0, -14, 3, -4, 1, 10, 0, 11, +-1, 5, 4, -4, 5, -6, -2, -5, +-1, 2, 2, 9, 5, 12, 0, 1, +-3, -7, -1, -12, 4, -5, 1, 8, +-6, 13, -2, 4, 2, -8, 3, -13, +-5, -5, -7, 3, -1, 8, 0, 8, +-2, 0, -4, -10, 0, -13, 4, -4, +2, 9, -3, 12, 0, 3, 2, -4, +1, -11, 2, -9, 2, 1, 8, 9, +8, 3, 6, -4, 1, -11, 5, -10, +2, 2, -4, 12, -1, 9, 1, 4, +2, -8, -1, -12, -1, -6, -1, 6, +-1, 12, -2, 6, 0, -7, -1, -13, +-2, -11, -1, 3, -5, 14, -4, 12, +-1, 0, 2, -9, 0, -11, -3, -4, +1, 6, 1, 13, 1, 7, 1, -6, +1, -10, 3, -8, 6, 1, 2, 11, +0, 11, 3, 0, 3, -12, 5, -16, +1, -3, 3, 6, 2, 13, -1, 4, +0, -8, 2, -17, 3, -10, -1, 3, +-4, 14, -5, 8, 0, -3, -1, -11, +-1, -11, -2, -2, 0, 10, 4, 8, +2, 2, -2, -9, 1, -13, 4, -5, +1, 5, 3, 9, 6, 5, 7, -6, +5, -14, -1, -8, -2, 6, -3, 17, +-1, 11, 4, -4, 4, -11, 2, -10, +0, -5, 2, 5, -2, 13, -2, 9, +-2, -7, -3, -12, -5, -8, -4, 6, +0, 11, -1, 11, -5, 2, -7, -6, +-2, -10, -1, -3, -1, 8, -2, 14, +4, 2, 6, -9, -2, -12, 1, -6, +3, 6, 3, 13, 0, 9, -1, 1, +1, -12, 4, -13, 1, -2, 0, 12, +3, 13, 2, 2, 0, -10, -1, -15, +0, -4, -4, 9, -5, 14, -3, 7, +0, -6, 5, -18, 0, -11, -2, 1, +-1, 11, 2, 10, -1, 0, -1, -13, +1, -14, 3, -5, 1, 10, -2, 14, +1, 9, 3, -8, 4, -13, -1, -11, +2, 3, 2, 14, 1, 11, 1, -1, +-2, -10, 1, -11, 2, -4, 1, 9, +0, 12, 1, 5, -2, -6, -7, -12, +-4, -7, -2, 7, 0, 14, -5, 12, +-5, 1, -6, -9, -4, -10, -3, 1, +-3, 11, 2, 12, 2, 0, 2, -9, +-3, -12, 2, -5, 2, 8, 0, 17, +1, 6, 2, -7, 4, -15, 2, -11, +4, 0, 2, 12, 4, 11, 3, 0, +0, -12, -2, -13, -1, -5, 2, 8, +1, 11, 0, 6, -1, -10, 4, -18, +-1, -8, -4, 7, -1, 14, -2, 10, +-1, -3, -1, -14, -1, -11, -4, 1, +-1, 14, 0, 16, -1, 7, -1, -10, +1, -15, 4, -9, 4, 4, 1, 17, +-4, 14, 1, -3, 1, -14, 1, -13, +2, 0, 3, 13, 2, 13, -2, -2, +2, -14, 3, -19, 5, -8, -1, 7, +-2, 16, 1, 7, 0, -6, -3, -15, +-6, -10, 1, 4, -1, 17, -4, 15, +-8, 2, 0, -14, 6, -15, 0, -1, +-4, 13, -3, 17, 5, 6, 0, -8, +-3, -16, 2, -12, 10, 3, 7, 14, +-1, 7, 3, -5, 4, -15, 5, -12, +-5, 0, -3, 13, 2, 13, 7, -1, +1, -14, -9, -11, 1, -6, 4, 9, +-2, 16, -11, 13, -4, -4, 1, -13, +-4, -10, -5, 2, -2, 15, 7, 12, +4, -3, -2, -14, -4, -14, 5, -2, +3, 11, -5, 18, -4, 8, 3, -7, +6, -15, -2, -11, -1, 6, 2, 18, +4, 14, -5, 0, -8, -14, 4, -16, +6, -1, 0, 13, -9, 19, -2, 5, +6, -14, 4, -20, -6, -6, -6, 10, +3, 14, 5, 5, -2, -6, -2, -18, +6, -13, 3, -2, 3, 12, -4, 15, +1, 3, 1, -10, -2, -17, 3, -8, +2, 11, 7, 15, 2, 7, -1, -6, +-4, -13, 2, -10, 2, 5, -2, 14, +1, 11, 2, -4, 5, -16, -3, -15, +2, -6, 2, 12, -1, 17, -2, 5, +-3, -13, 1, -19, 2, -10, 2, 8, +-3, 15, 1, 9, 2, -6, 4, -16, +-1, -12, -4, 1, 3, 11, 5, 14, +3, 3, -7, -7, -3, -14, 6, -6, +6, 8, -1, 16, -3, 9, 5, -7, +4, -17, -3, -9, -6, 4, 4, 15, +6, 12, -1, -2, -6, -14, -1, -15, +6, -2, -4, 13, -8, 16, -1, 2, +11, -13, 2, -17, -7, -9, -3, 8, +4, 18, 5, 10, -8, -3, -5, -15, +5, -14, 10, -2, -4, 13, -4, 13, +7, 4, 7, -12, -1, -15, -9, -7, +5, 10, 9, 15, 0, 9, -7, -11, +6, -20, 11, -11, -4, 8, -10, 14, +-4, 14, 7, 0, 1, -14, -8, -16, +-4, -5, 9, 9, 7, 13, -6, 6, +-10, -3, -1, -14, 8, -10, -6, 6, +-8, 18, -1, 16, 6, -2, -3, -11, +-12, -11, 6, -3, 11, 10, 5, 12, +-5, 0, 3, -13, 10, -18, 3, -5, +-6, 8, -2, 17, 4, 13, -2, -3, +-4, -17, -5, -12, 4, 1, 5, 13, +-5, 14, -7, 2, -1, -13, 5, -15, +-1, -6, -4, 13, -6, 20, 3, 6, +2, -10, -4, -14, -2, -9, 2, 6, +5, 15, -2, 11, 1, -4, 4, -16, +5, -13, -2, 1, -3, 14, -2, 18, +-2, 9, 1, -11, -1, -17, 1, -8, +3, 8, 1, 18, -7, 12, -5, -5, +1, -16, 4, -15, 2, 2, -7, 14, +-1, 13, 4, -2, 4, -13, -2, -18, +-2, -4, 2, 11, 3, 15, -4, 8, +-8, -6, 5, -15, 5, -7, 0, 3, +-4, 12, 4, 11, 4, 4, -7, -8, +-9, -11, 2, -4, 13, 9, 3, 12, +-4, 2, -2, -9, 5, -11, 0, -6, +-8, 5, -6, 17, 2, 10, 7, -5, +-8, -13, -10, -8, 2, 2, 6, 13, +-4, 10, -7, -1, 4, -10, 5, -11, +-1, -5, -9, 8, 5, 11, 12, 8, +-2, -2, -11, -11, -2, -9, 9, 8, +0, 14, -5, 9, -3, -1, 10, -12, +9, -15, -7, 1, -8, 13, 4, 15, +7, 3, -8, -7, -10, -11, 1, -6, +9, 4, -2, 11, -7, 7, 4, -7, +7, -13, -3, -8, -10, 1, 1, 9, +8, 9, 3, 3, -10, -7, 1, -18, +13, -7, 5, 7, -2, 12, -1, 1, +11, -8, 4, -12, -1, -8, -3, 4, +2, 13, 8, 6, 2, -3, -2, -12, +1, -13, 7, -2, -5, 13, -7, 14, +-4, 5, 2, -8, 1, -13, -5, -5, +-4, 7, -1, 11, 2, 8, -4, -3, +-3, -11, -3, -9, 2, 0, 2, 10, +-5, 14, -3, 3, 2, -10, 7, -14, +1, -5, -3, 9, 0, 13, 6, 5, +4, -8, -3, -11, 3, -10, 6, 3, +5, 8, -2, 6, 1, -4, 6, -12, +6, -13, -4, 0, -8, 10, 2, 12, +1, 6, -6, -2, -11, -9, -2, -2, +1, 6, 0, 8, -6, 7, -5, 1, +5, -7, -2, -6, -6, 0, -2, 9, +9, 9, 7, -1, -3, -10, -1, -12, +8, -3, 8, 6, -3, 8, -2, 5, +2, -1, 7, -10, -1, -11, -3, 0, +3, 11, 6, 8, -3, 1, -10, -10, +1, -8, 4, 0, -2, 9, -10, 8, +-2, 4, 4, -4, 1, -11, -7, -6, +-7, 6, 6, 11, 0, 9, -6, -2, +-5, -9, 8, -10, 8, 1, -3, 7, +-6, 11, 3, 2, 10, -6, -5, -7, +-4, -5, 4, 8, 5, 12, 2, 2, +-5, -5, 2, -9, 7, -7, 1, 2, +-8, 8, -2, 8, 3, 1, -1, -6, +-7, -8, -4, -3, 7, 3, 2, 10, +-6, 3, -5, -5, 2, -9, 4, -6, +-3, 5, -5, 9, 2, 3, 8, -5, +5, -12, -2, -6, 0, -2, 7, 7, +2, 8, -1, 2, -1, -5, 1, -5, +4, -3, 1, 4, -3, 11, -4, 8, +2, -3, -2, -6, -5, -3, -4, 3, +1, 6, 2, 6, -4, 0, -3, -8, +0, -9, 1, -1, -2, 5, -4, 9, +-5, 4, 3, -7, 2, -5, -5, -5, +1, 2, 2, 9, 0, 10, -4, -1, +-1, -8, 6, -9, 9, -3, 4, 2, +0, 3, 6, 1, 4, -7, 8, -15, +0, -2, -1, 6, 3, 9, -2, 5, +-4, -3, -1, -9, 6, -5, -1, 1, +-6, 8, -5, 5, 3, -2, 2, -7, +-5, -6, -4, 0, 1, 5, 4, 7, +-8, 6, -7, 0, 0, -3, 3, -2, +0, 0, -1, 4, 4, 6, 3, 1, +2, -8, -4, -6, 5, -1, 6, 9, +-2, 6, -5, 1, 0, -4, 8, -6, +-1, 0, -9, 7, -4, 6, 6, 3, +4, -5, -7, -4, -7, -1, 0, 4, +0, 8, -9, 7, -7, -1, 4, -9, +10, -9, -3, 0, -6, 3, 4, 3, +7, -2, 5, -8, -1, -9, 3, -4, +6, 2, 5, 4, -2, 2, 2, -4, +8, -5, 4, -4, -2, 1, -2, 4, +4, 6, 2, 0, 0, -4, -4, -4, +-2, 2, 2, 1, -2, 4, -2, 3, +-3, 1, -1, -6, -1, -5, 0, -1, +-2, 5, 0, 2, 2, -3, 0, -7, +2, -4, -2, 0, 1, 1, 2, 3, +4, -2, 4, -6, 2, -4, 1, -3, +3, -1, 5, 5, -2, 5, 3, -3, +2, -3, -3, 2, -3, 3, -1, 5, +-2, 6, -2, 3, 1, -3, -2, -4, +0, -3, 1, 2, 1, 1, -1, 2, +-3, 0, -5, -2, -1, -5, 2, -1, +-1, 3, -1, 5, -3, 1, -2, -3, +0, -3, 0, 0, 1, -2, 6, 1, +4, 2, -2, -1, 2, -6, 2, 0, +2, 3, 3, 2, 0, 2, 1, -3, +8, -6, 3, -5, 1, -3, 0, 6, +-1, 5, 2, -3, 0, -4, -4, -3, +-1, 1, 0, 3, -6, 7, -7, 3, +0, 0, -2, -1, -4, 1, -4, 0, +0, 1, 6, -1, 2, 1, -7, 0, +-3, -2, 7, -3, 5, 0, 2, 1, +0, 1, 2, -2, 5, -4, 3, -5, +-2, 4, 1, 4, 7, -2, 1, -4, +1, -4, 4, -4, 1, 0, 0, 3, +-5, 6, -6, 6, -5, 2, -6, 1, +-5, 0, 2, 2, -2, 3, -4, 3, +-1, -1, -1, -2, -2, -1, -2, 1, +0, 1, 1, 2, 4, -2, -2, 0, +-3, -1, 5, -2, 2, 3, -2, 6, +0, -2, 4, -6, 7, -5, 4, -2, +-1, 0, -2, 7, 1, 5, -3, 2, +-3, -4, 0, -4, 1, 1, 2, 1, +2, -3, -4, 2, -3, 3, -2, -1, +-2, -4, 0, 1, 0, 2, 1, -2, +1, -2, -5, 2, -5, 2, 1, 1, +1, 0, 1, 1, 0, 2, 0, -5, +3, -1, 0, 2, 0, 2, 1, 2, +2, 1, 2, -3, 0, 0, 0, 1, +-3, 4, 2, 0, 2, 1, -1, -4, +1, -1, -4, 3, -6, 2, 1, 1, +1, 0, 0, -4, 1, -2, 1, -3, +-3, 0, -2, 1, 0, 1, 1, 0, +3, -3, 0, -5, 1, -4, 5, 3, +-2, 4, -4, 2, 1, 0, 2, -1, +1, -3, 2, -1, 2, 1, 2, 2, +5, -3, 2, -2, -4, 1, 2, -3, +3, -3, 0, 3, 1, 0, -1, -2, +-1, -1, -4, 5, -6, 2, -1, 0, +4, -3, -3, 2, 0, -4, 1, -2, +-4, 1, 0, 2, -2, 5, -4, 1, +2, -2, -1, 0, -2, -2, 3, 1, +-1, 6, -4, 2, 2, -2, 4, -4, +4, -4, 4, 0, -1, 1, 2, 0, +3, 3, -5, 1, -4, 0, 2, 0, +2, 1, 0, -1, 0, 3, -4, 1, +0, -3, 3, -3, -7, 6, -8, 7, +-1, 2, -1, -3, 0, -1, 1, -2, +-1, -1, 0, 3, -1, 4, -3, 0, +-1, 0, 1, -3, 1, -2, 3, 0, +2, 0, 0, 1, 2, -2, 6, -7, +2, -3, 2, 2, -2, 4, -3, 2, +3, -3, 3, -3, 0, -4, 0, 1, +-1, 2, 0, 0, 3, -2, -3, 0, +-3, 0, 2, -1, 0, -2, -4, 6, +-2, 5, -1, 1, -2, -2, -2, 1, +-2, 0, 2, 2, 1, 1, -3, 2, +0, -1, 4, -3, 0, -2, 2, 2, +0, 3, -1, -2, 5, -3, 1, -1, +0, -5, 4, -2, 3, 0, 2, 0, +1, -1, -1, -2, -3, 1, 2, -3, +4, -4, -2, 1, 2, -1, 4, -5, +-2, 0, -3, 3, -4, 5, -4, 0, +3, 0, -2, 2, -6, 2, 1, -4, +2, -1, 1, 3, 1, 3, -1, -4, +2, -2, 6, -3, 1, -2, 0, -2, +1, 4, -1, 1, 3, -1, 0, -1, +-3, 0, 1, 0, 5, -1, 0, -1, +-1, 0, 0, -2, -3, 0, -2, 4, +-3, 3, -2, 0, 3, -2, 4, -2, +-1, -2, 0, -3, 2, -3, 1, 2, +2, 1, -2, -1, -2, -1, 1, 4, +-1, 0, -2, 1, 0, 4, -2, 1, +3, -6, 6, -5, 2, -2, 0, 2, +2, 1, 0, 0, 3, -5, 4, -3, +-2, -3, 0, 3, 2, 2, -1, -2, +-1, -1, 0, 2, 0, -2, 2, -2, +-1, 0, -1, 0, 4, -2, 5, -5, +-2, -1, -1, -1, 6, -4, 5, -3, +3, 1, -1, -1, -1, -2, 4, -1, +1, 2, -3, -2, 4, -2, 2, 2, +-2, 3, 0, -2, -4, 1, -3, 3, +5, 1, -1, -1, -7, 2, -2, 2, +-1, 1, 2, -4, 2, 1, -7, 6, +-3, 3, 2, -1, -6, 3, -5, 3, +1, 0, 2, -3, 4, -1, 0, 0, +-4, -1, 3, -1, 4, 2, -3, 1, +1, -2, 2, -1, 1, 0, 1, 0, +0, -4, 2, -3, 7, -2, 5, -3, +1, -6, 2, 0, -3, 3, -3, 1, +5, -3, 0, 1, -3, -3, 5, -3, +4, -3, 0, 0, 2, -3, 0, -1, +5, -4, 6, -2, -4, -3, -1, -1, +6, 1, -1, 3, -4, 0, -1, 1, +-1, 1, 3, -2, 2, 0, -7, 4, +-1, 1, 5, -2, -2, 1, -1, 0, +1, -1, 0, -1, 3, 1, 0, 1, +-6, 1, 0, -1, 2, 2, -3, 4, +-3, 3, -2, -2, 0, 1, 2, 0, +2, -4, -3, -1, 0, 3, 0, 2, +-4, 3, -1, -1, -3, 2, 0, -2, +6, -1, 0, 1, -8, 6, -2, 0, +3, -1, 3, 0, 0, 1, -5, 0, +3, 0, 6, 0, -2, -3, -1, -5, +5, -1, 4, 0, 0, 0, -5, 1, +-4, 1, 5, 0, 5, -3, -6, 2, +-3, 0, 4, -1, -1, 1, -3, 2, +-1, -1, -1, 0, 3, 1, -1, 4, +-6, 2, -2, 2, -1, 2, -1, 2, +3, -3, -2, 0, 0, -4, 8, 0, +-2, 2, -3, 0, 1, 1, 0, 2, +-2, 2, -1, 2, -5, 1, 1, -3, +7, -3, 1, -1, 0, 1, -4, 4, +-7, 4, 0, 2, 3, -1, -3, -4, +1, -2, 4, 3, -1, 1, 0, -2, +-4, 3, 1, -1, 8, -1, -1, -1, +-7, 1, 4, -3, 9, -2, 2, -3, +-2, 3, -3, 0, 5, -3, 9, -3, +-1, 2, -5, 0, 5, -1, 4, -1, +-1, 1, -3, 0, -1, 0, 4, 2, +2, 4, -4, -3, -2, -1, 3, 4, +-1, 4, -1, -2, 0, 1, -3, 3, +5, -2, 3, -1, -5, 1, -2, 4, +1, 3, 0, 0, 1, 0, -3, 4, +-4, 2, 3, 2, 5, 1, -4, 3, +-3, 0, 1, 3, -1, 2, 1, -1, +1, -4, 4, -1, 8, -1, 4, -4, +-2, -3, 1, 2, 4, 0, 3, -1, +3, -2, -3, 2, -1, 0, 6, -1, +2, -1, 0, 1, 2, 1, 4, 0, +1, 2, 0, -1, -1, -1, 2, 1, +7, 1, 2, -1, -1, -2, 3, 0, +2, 2, 2, 2, 0, 2, -2, 1, +2, 1, 6, -4, 1, 0, 0, 1, +4, 0, 2, 0, 5, 0, 1, 0, +-5, 2, 0, 1, 5, 3, 0, 5, +-4, 4, -3, 0, 4, -1, 9, -3, +0, 1, -4, 3, 6, 2, 8, -2, +3, -4, 2, -3, 2, 1, 8, 0, +7, 0, -2, 0, 0, -1, 8, -2, +5, 0, -2, 4, -1, 1, 6, -2, +8, 1, 0, 4, -6, -1, 3, -1, +10, 2, 3, 3, -1, -1, -3, 2, +3, -1, 10, -1, 3, -1, 0, 1, +5, 1, 10, -3, 5, -5, 2, 0, +1, 4, 4, 2, 10, -3, 6, -3, +4, -4, 9, -5, 11, -5, 8, -1, +6, -1, 5, -4, 8, -3, 9, -3, +6, -4, 4, -1, 5, 4, 7, -1, +9, -5, 3, 0, -2, 3, 3, 2, +10, -2, 8, -2, 1, 3, 3, 0, +4, 0, 5, 1, 4, 3, 0, 3, +6, 1, 9, -1, 1, 1, 3, -3, +8, 1, 8, 4, 6, 4, 2, -1, +2, -1, 10, -3, 12, -3, 4, 0, +3, 5, 5, 3, 5, 1, 4, 0, +2, 0, 7, -1, 13, 0, 6, 3, +3, 0, 6, -3, 6, -2, 8, 3, +6, 5, 2, 2, 5, -1, 9, 0, +9, -6, 10, -5, 8, -1, 9, 2, +13, -1, 10, -4, 4, -2, 5, 2, +10, 1, 9, 1, 6, 2, 3, 2, +7, -5, 14, -3, 5, 4, -1, 5, +5, 4, 10, 3, 6, 0, 4, -3, +7, -3, 12, 2, 12, 3, 3, 3, +0, 3, 9, -1, 14, -5, 8, -2, +8, 0, 13, -2, 13, -1, 11, -5, +5, -1, 6, 1, 14, 1, 11, 1, +9, 2, 6, 1, 8, -4, 12, -3, +10, 2, 8, 0, 10, 1, 11, -1, +5, 2, 7, -3, 8, 2, 4, 6, +10, 3, 11, 0, 5, 1, 9, -2, +12, -1, 10, 2, 11, 2, 11, 1, +8, 0, 10, -2, 10, -1, 7, 2, +10, 1, 12, 2, 11, 3, 9, 1, +6, -2, 12, -2, 16, 2, 12, 4, +7, 3, 8, 0, 12, -1, 10, 1, +9, 1, 8, 4, 11, 1, 15, -4, +13, -7, 13, -6, 15, -3, 14, 1, +11, 7, 6, 4, 11, -4, 12, 0, +10, 6, 7, 5, 12, -2, 17, -4, +16, -2, 13, -1, 9, -4, 9, 3, +11, 5, 17, 1, 11, -1, 9, 1, +10, 1, 14, 2, 11, 4, 11, 3, +13, 1, 16, -2, 14, -2, 9, 0, +12, -1, 16, -2, 17, 1, 14, -1, +11, -3, 11, -2, 16, 2, 15, 3, +12, 4, 12, 0, 16, -3, 19, -4, +14, 2, 5, 4, 15, 1, 20, -1, +14, -1, 13, -4, 13, -3, 17, -2, +17, 5, 9, 9, 6, 4, 14, -1, +19, -2, 16, 2, 12, 5, 12, 2, +18, -1, 20, -2, 12, -3, 10, -1, +14, 2, 15, 5, 12, 2, 14, 1, +11, 0, 17, -2, 17, 0, 15, 3, +17, 3, 17, 3, 15, -1, 15, 1, +15, 0, 13, 4, 12, 6, 17, 0, +19, -3, 13, -2, 16, -5, 21, -2, +24, -1, 20, -1, 17, 1, 16, 2, +19, -1, 15, 3, 13, 4, 16, 2, +20, -1, 19, -4, 18, -6, 17, -6, +21, -4, 20, 3, 15, 5, 16, -2, +18, -3, 20, 1, 15, 7, 13, 7, +14, 6, 16, 6, 17, 1, 19, -5, +16, -3, 18, -1, 20, 1, 21, -1, +19, -3, 17, -3, 22, -6, 27, -2, +19, 7, 16, 6, 17, 2, 21, -1, +22, -3, 19, -4, 19, -1, 23, 1, +21, 0, 20, -8, 21, -7, 18, -2, +24, -1, 19, 3, 15, 4, 20, 1, +23, 1, 17, 0, 21, 2, 20, 5, +21, 3, 21, 0, 19, -2, 19, -2, +24, -8, 23, -3, 19, 1, 25, 2, +20, -1, 20, -2, 18, 2, 22, 1, +26, 1, 22, 4, 15, 5, 19, 3, +21, -2, 17, 1, 17, 0, 24, -1, +21, 2, 19, 0, 14, -1, 18, -3, +29, -1, 22, 8, 16, 6, 23, 1, +26, -1, 26, -2, 24, -1, 21, -2, +29, -1, 24, -1, 22, -5, 21, -4, +21, 1, 18, 2, 24, 1, 23, 2, +21, 3, 24, -2, 25, -3, 25, 2, +23, 7, 20, 5, 22, 0, 28, -7, +27, -8, 26, -6, 23, -3, 26, -3, +27, -2, 26, -4, 24, -4, 23, 1, +22, 5, 23, 9, 24, 4, 26, 0, +25, -3, 30, -6, 28, -4, 25, 1, +20, 1, 26, -4, 28, -3, 23, -5, +20, -2, 24, 0, 28, 7, 22, 5, +28, -1, 21, 2, 29, -1, 28, 3, +19, 7, 21, 3, 26, 1, 25, -5, +26, -6, 19, -1, 22, -1, 28, 2, +26, -1, 25, -1, 25, 1, 27, 1, +24, 5, 26, 5, 25, 6, 27, 3, +26, -2, 23, -3, 27, -4, 31, -2, +25, -4, 29, -5, 29, -4, 30, -5, +26, -2, 22, 4, 26, 5, 38, 3, +26, 3, 20, -1, 29, 1, 28, 4, +26, 1, 20, 2, 21, 0, 30, -5, +32, -9, 20, -5, 25, 0, 31, 4, +29, 5, 23, 3, 25, 2, 26, 3, +33, 3, 27, 4, 26, 3, 32, -2, +29, -3, 25, -5, 26, -3, 26, -3, +30, 0, 28, 1, 26, -4, 33, -5, +30, 0, 27, 4, 27, 9, 28, 10, +24, 6, 26, 0, 26, -6, 33, -6, +32, -3, 28, -3, 27, -6, 34, -7, +28, -4, 27, -2, 25, 3, 25, 9, +29, 10, 29, 3, 29, -2, 30, 0, +33, 0, 31, 4, 30, 2, 26, -4, +29, -6, 30, -5, 27, -2, 23, 0, +29, 1, 29, 3, 35, 3, 25, 3, +23, 1, 32, 4, 36, 6, 32, 2, +27, 0, 26, -4, 34, -6, 31, -1, +19, 1, 25, -1, 36, -3, 31, -1, +24, -2, 28, 0, 30, 3, 39, 5, +31, 6, 30, 2, 31, 2, 31, -2, +28, 0, 29, 4, 27, 1, 30, -5, +32, -9, 31, -9, 35, -5, 31, 3, +22, 9, 28, 8, 33, 9, 24, 5, +25, 4, 26, 5, 35, 5, 35, 3, +25, -1, 19, -3, 34, -5, 34, -6, +24, 0, 22, 3, 32, 2, 38, -1, +32, -1, 20, 4, 29, 10, 37, 10, +32, 5, 26, 5, 26, 0, 33, -5, +35, -5, 29, -2, 27, -3, 40, -8, +34, -8, 32, -6, 32, -3, 32, 3, +30, 8, 32, 10, 30, 4, 33, -1, +30, 0, 29, 1, 36, 2, 32, 0, +25, -4, 30, -9, 36, -10, 31, -3, +28, 3, 25, 4, 36, 1, 40, 0, +30, 4, 24, 4, 34, 4, 35, 7, +33, 8, 28, -3, 32, -12, 37, -9, +36, -6, 31, -5, 32, -3, 33, -3, +35, -2, 36, -2, 27, 2, 27, 9, +35, 7, 41, 3, 34, 2, 29, -2, +27, -4, 39, -2, 33, 0, 26, -2, +30, -6, 36, -7, 32, -4, 30, -2, +25, 4, 33, 8, 39, 9, 28, 5, +27, 2, 34, 3, 35, 3, 32, 5, +29, 3, 31, -6, 41, -14, 37, -15, +31, -7, 33, 2, 33, 4, 27, 2, +33, 3, 30, 4, 32, 6, 28, 9, +26, 11, 36, 5, 42, -2, 26, -6, +26, -6, 35, -4, 35, -3, 30, -1, +26, -4, 33, -6, 42, -5, 33, 0, +21, 7, 36, 10, 39, 9, 34, 4, +29, -4, 35, -6, 38, 1, 37, 1, +26, -3, 32, -6, 38, -9, 35, -10, +30, -5, 30, 2, 34, 6, 36, 8, +27, 6, 28, 2, 36, 4, 31, 5, +30, 6, 31, 4, 33, -2, 29, -8, +32, -11, 30, -8, 38, -3, 33, 0, +29, 0, 32, 0, 35, -1, 34, 1, +33, 10, 26, 15, 32, 8, 36, 3, +26, 1, 27, -4, 34, -4, 31, -1, +33, -3, 34, -5, 27, -8, 36, -9, +39, -6, 37, 2, 32, 9, 32, 8, +32, 6, 34, 4, 27, -1, 30, 0, +34, 3, 35, 0, 31, -4, 26, -7, +29, -12, 40, -6, 33, 4, 22, 6, +30, 5, 35, 1, 36, 1, 33, 2, +32, 6, 33, 8, 38, 8, 23, 3, +28, -8, 36, -10, 34, -8, 33, -4, +36, -4, 35, -5, 32, -1, 29, -2, +30, 1, 38, 8, 29, 16, 20, 13, +34, 2, 39, -3, 27, -4, 28, -5, +29, -1, 37, -1, 36, -7, 23, -7, +23, -2, 39, 1, 30, 5, 26, 6, +28, 5, 36, 3, 39, 2, 28, 4, +23, 6, 35, 7, 37, 1, 28, -5, +27, -9, 28, -9, 35, -5, 34, 1, +24, 6, 28, 1, 35, 0, 29, -1, +35, 1, 32, 8, 31, 7, 35, 4, +33, 2, 28, -5, 30, -6, 23, -5, +31, -5, 37, -2, 29, -2, 25, -6, +35, -6, 35, 4, 30, 10, 25, 10, +24, 8, 40, 1, 37, 0, 24, 1, +27, -1, 34, 3, 32, 0, 33, -8, +25, -11, 30, -6, 33, 0, 29, 4, +25, 6, 31, 3, 29, 2, 34, 0, +32, 5, 24, 8, 31, 7, 31, 4, +30, -2, 29, -9, 23, -9, 23, -3, +34, -1, 32, -5, 30, -4, 29, -2, +34, -1, 34, 5, 27, 12, 17, 14, +32, 8, 38, -3, 31, -9, 27, -6, +29, -4, 33, -5, 38, -6, 28, -5, +27, -7, 37, -6, 28, 0, 29, 1, +32, 5, 27, 7, 26, 4, 30, 4, +26, 3, 32, 3, 28, 3, 26, -2, +33, -8, 29, -8, 18, -7, 27, -1, +29, 5, 27, 4, 25, 1, 22, 1, +33, 0, 41, 2, 25, 12, 20, 11, +36, 5, 33, -3, 27, -13, 21, -12, +26, -6, 35, -2, 30, 1, 20, 1, +32, -3, 37, -6, 32, -3, 23, 7, +21, 13, 25, 10, 30, 2, 23, -1, +29, -5, 34, -3, 24, -1, 27, -5, +28, -8, 31, -9, 28, -2, 23, 2, +25, 3, 31, 2, 23, 1, 22, 2, +29, 3, 32, 7, 27, 11, 28, 6, +30, -3, 34, -10, 24, -11, 15, -10, +27, -8, 29, 2, 24, 6, 27, 3, +28, 0, 31, -3, 27, 4, 19, 6, +26, 9, 27, 8, 23, 1, 22, -3, +27, -7, 22, -7, 26, -5, 26, -3, +28, -4, 31, -4, 27, -4, 25, 1, +28, 8, 22, 5, 18, 2, 23, 2, +29, 0, 31, 4, 29, 4, 24, 5, +27, -1, 30, -9, 17, -9, 17, -6, +22, -3, 22, 1, 25, 2, 29, 0, +30, 1, 30, 3, 21, 6, 20, 7, +27, 6, 22, 2, 22, -6, 28, -11, +24, -7, 20, -4, 21, 0, 19, 2, +32, -5, 30, -5, 22, -4, 28, 2, +28, 12, 19, 12, 15, 8, 13, 0, +22, -3, 29, -6, 27, -5, 28, -1, +33, 2, 27, -1, 20, -5, 16, -6, +15, -5, 21, -2, 18, 4, 20, 6, +31, 8, 25, 15, 15, 14, 17, 7, +15, -1, 16, -5, 18, -4, 21, -4, +25, -2, 21, 1, 15, 2, 21, 0, +27, -7, 20, -6, 19, 0, 29, 7, +31, 16, 22, 17, 9, 6, 11, -8, +24, -18, 20, -14, 15, 1, 23, 11, +31, 14, 24, 11, 18, -3, 12, -9, +18, -12, 21, -8, 11, 5, 16, 9, +29, 11, 26, 11, 26, 2, 23, -9, +24, -16, 23, -11, 15, -3, 19, 1, +25, 3, 18, 1, 17, -4, 26, -10, +27, -12, 22, -3, 16, 7, 22, 14, +27, 15, 21, 8, 12, -3, 17, -12, +17, -17, 14, -15, 17, -5, 25, 8, +32, 12, 29, 7, 12, 1, 14, -7, +21, -5, 11, 3, 10, 3, 13, 4, +18, 4, 24, 0, 24, -2, 21, -3, +23, -3, 17, -2, 15, 1, 18, 0, +18, -5, 18, -6, 17, -2, 14, 0, +17, 4, 12, 11, 13, 9, 29, 0, +29, -4, 15, 0, 11, 1, 13, -2, +13, -8, 10, -5, 6, 0, 21, 1, +32, 2, 25, 1, 20, -1, 23, 4, +11, 12, 3, 11, 4, 2, 8, -7, +19, -15, 21, -12, 18, -2, 23, 9, +17, 15, 10, 8, 13, -1, 15, -3, +12, 0, 12, 0, 12, 1, 12, 6, +14, 4, 10, 2, 16, 0, 24, -2, +21, -3, 19, -5, 19, 1, 14, 8, +8, 4, -3, -2, -2, -5, 15, -4, +24, 2, 23, 10, 20, 16, 21, 11, +16, 5, 3, 0, -3, -6, 5, -12, +13, -15, 12, -8, 19, 0, 29, 7, +26, 7, 17, 1, 8, -3, 11, -2, +12, 4, 10, 8, 11, 7, 18, -2, +15, -9, 8, -11, 11, -8, 12, 2, +18, 4, 17, 6, 17, 5, 22, 4, +14, -3, 4, -13, 3, -14, 5, -6, +11, 9, 15, 19, 22, 15, 29, 6, +23, 0, 7, -9, 1, -9, -2, -7, +-4, -7, 2, -6, 15, -5, 25, 3, +30, 6, 25, 5, 12, 9, 7, 8, +-1, 10, -6, 12, 5, 4, 17, -11, +20, -20, 17, -18, 13, -8, 13, 3, +13, 6, 7, 4, 11, 3, 17, 4, +15, 4, 11, 3, 3, 2, -4, 1, +0, -3, 8, -2, 18, 0, 31, 1, +27, 3, 16, 4, 9, 2, -4, -1, +-12, -10, -5, -23, 11, -24, 22, -9, +24, 14, 22, 29, 22, 28, 13, 14, +-1, -3, -4, -12, 3, -10, 7, -7, +6, -8, 8, -6, 14, 1, 15, 5, +8, 0, 7, -8, 14, -10, 21, -2, +14, 14, 1, 24, 1, 18, 2, 2, +-3, -18, 3, -26, 16, -16, 29, -1, +27, 13, 15, 15, 9, 8, 2, 2, +-10, -9, -13, -23, 4, -26, 12, -12, +16, 10, 20, 30, 21, 33, 18, 18, +6, 0, -3, -14, 0, -14, 4, -9, +-3, -6, -1, -7, 11, -8, 16, -5, +13, 2, 8, 5, 13, 2, 19, 2, +9, 9, -4, 16, 0, 14, 3, 0, +2, -19, 5, -24, 9, -14, 18, 1, +18, 13, 11, 10, 11, 0, 13, -5, +2, -4, -8, -3, -7, -8, -3, -11, +4, -7, 17, 5, 23, 18, 26, 21, +19, 15, 5, 5, -4, -3, -11, -10, +-16, -15, -6, -22, 13, -23, 17, -9, +18, 8, 17, 21, 12, 20, 7, 6, +-3, -2, -4, -3, 7, 3, 8, 6, +5, -3, 6, -15, 10, -19, 4, -8, +0, -1, 11, 1, 19, 4, 20, 6, +9, 10, -5, 11, -12, 1, -18, -14, +-16, -24, 5, -16, 26, 10, 34, 29, +29, 32, 15, 19, -3, -2, -20, -19, +-27, -27, -14, -27, 12, -21, 25, -7, +21, 8, 23, 17, 15, 20, -5, 14, +-17, 1, -11, -3, 2, 6, 11, 13, +8, 8, 1, -6, 1, -19, -8, -20, +-7, -11, 9, 5, 22, 13, 24, 14, +17, 6, 4, 3, -8, -4, -17, -15, +-26, -20, -9, -15, 21, 2, 30, 24, +29, 32, 20, 22, 4, 1, -13, -15, +-28, -19, -22, -18, 5, -18, 19, -15, +15, -6, 13, 9, 10, 19, 3, 23, +-6, 18, -6, 4, 5, -6, 12, -7, +2, -2, -7, -6, -5, -14, -7, -12, +0, -5, 15, 8, 20, 13, 19, 6, +10, -2, 0, -5, -12, 4, -23, 7, +-19, -2, -1, -15, 21, -21, 25, -4, +17, 19, 10, 31, 2, 22, -9, 6, +-16, -9, -5, -21, 5, -23, 6, -27, +2, -22, 1, -3, 4, 22, 3, 39, +4, 34, 10, 13, 10, -10, 4, -21, +-6, -14, -17, 0, -19, 5, -9, -1, +4, -5, 22, -5, 28, 1, 15, 4, +5, 2, -5, 5, -19, 10, -23, 11, +-13, 0, 6, -20, 17, -27, 10, -11, +6, 15, 13, 35, 7, 36, -7, 15, +-6, -14, 3, -31, 3, -31, -4, -23, +-10, -12, -5, 2, 8, 11, 11, 20, +12, 22, 20, 9, 16, -7, -2, -11, +-14, -4, -19, 7, -11, 6, -1, -8, +4, -19, 16, -20, 19, -4, 7, 16, +-3, 25, -4, 15, -5, 4, -9, -5, +-3, -15, 0, -19, 2, -21, -2, -8, +-3, 16, 10, 36, 14, 37, 12, 14, +12, -16, 8, -33, -9, -27, -25, -12, +-29, 1, -13, 2, 9, -1, 21, 3, +28, 14, 28, 20, 12, 15, -19, 6, +-30, -6, -20, -8, -6, -5, 10, -10, +19, -16, 24, -16, 15, -4, -2, 9, +-13, 17, -13, 12, -2, -5, 7, -9, +10, -2, 8, 2, -4, 1, -16, -5, +-19, -4, -8, 5, 11, 16, 25, 20, +29, 15, 19, 1, -7, -12, -30, -20, +-32, -27, -21, -30, -1, -24, 22, -1, +34, 32, 35, 54, 14, 48, -15, 12, +-24, -27, -22, -43, -15, -33, 2, -9, +20, 12, 24, 18, 15, 11, 1, 0, +-8, -9, -4, -15, -6, -15, -3, -7, +7, 12, 7, 29, -2, 23, -10, 2, +-11, -23, 1, -31, 10, -10, 6, 24, +10, 36, 17, 26, 0, 5, -16, -19, +-17, -35, -14, -36, -9, -27, 2, -6, +12, 24, 20, 50, 14, 55, 1, 30, +-1, -10, -2, -37, -14, -35, -16, -17, +-4, 1, 1, 9, 6, 1, 10, -3, +17, 1, 20, 6, 6, 7, -13, -1, +-14, -8, -13, -2, -16, 6, -8, 9, +8, 6, 22, 1, 19, 6, 3, 12, +-3, 7, -4, -2, -9, -15, -11, -20, +-2, -12, 9, 0, 9, 3, 4, -6, +-2, -10, -6, -1, -2, 16, 4, 29, +11, 30, 10, 21, 1, 1, -6, -18, +-13, -26, -19, -32, -17, -28, 1, -11, +20, 18, 28, 42, 22, 44, 4, 18, +-9, -21, -18, -46, -26, -36, -18, -4, +6, 27, 19, 36, 23, 26, 18, 9, +9, -10, -2, -21, -16, -27, -19, -25, +-4, -7, 6, 15, 6, 22, 6, 9, +4, -10, 0, -18, -4, 0, -8, 28, +-3, 37, 7, 27, 6, 4, 3, -20, +0, -30, -9, -27, -15, -17, -5, -8, +6, 7, 9, 24, 10, 29, 12, 18, +8, -3, -4, -20, -19, -16, -22, 5, +-10, 20, -4, 17, 3, 1, 11, -7, +16, -1, 10, 11, -4, 15, -16, 10, +-16, -5, -11, -17, -13, -20, -4, -16, +12, -6, 17, 9, 10, 27, 3, 40, +-2, 38, -5, 11, -5, -24, -8, -41, +-6, -32, -4, -3, -5, 20, 0, 25, +4, 13, 2, -3, 2, -10, 2, -4, +-3, 3, -7, 9, -12, 17, -9, 21, +-3, 20, -4, 4, -4, -20, 6, -34, +12, -20, 3, 13, -5, 40, -7, 42, +-8, 18, -8, -20, -8, -43, -9, -34, +1, -13, 3, 14, -3, 35, 0, 46, +3, 44, -1, 24, -2, -11, -5, -36, +-10, -35, -14, -15, -18, 11, -13, 26, +0, 21, 7, 4, 13, -6, 17, -6, +6, 6, -14, 12, -24, 7, -26, 6, +-17, 9, -2, 10, 10, 3, 23, -7, +19, -11, 0, -5, -17, 11, -24, 21, +-23, 15, -12, -3, 5, -16, 14, -8, +9, 5, -3, 9, -23, 12, -25, 12, +-16, 15, -1, 20, 15, 21, 21, 8, +14, -10, -11, -19, -32, -19, -38, -10, +-24, 1, -7, 10, 16, 13, 36, 17, +31, 23, 1, 19, -29, 4, -48, -11, +-45, -11, -22, 2, 5, 15, 27, 20, +30, 14, 12, 3, -14, 1, -32, 5, +-38, 4, -24, -7, -3, -11, 13, -7, +19, 6, 5, 21, -14, 23, -19, 12, +-20, 4, -20, 6, -5, 9, 14, 7, +14, -1, -2, -5, -17, -3, -23, 5, +-23, 7, -20, -1, -10, -11, 13, -11, +19, 9, 5, 30, -7, 38, -16, 28, +-24, 4, -28, -16, -25, -19, -11, -13, +8, -5, 14, 8, 6, 26, -3, 37, +-12, 29, -21, 2, -23, -28, -26, -36, +-21, -23, -5, 9, 1, 44, 1, 51, +2, 36, -5, 13, -13, -3, -20, -14, +-27, -18, -27, -15, -9, -6, 4, 15, +7, 33, -3, 36, -20, 14, -25, -18, +-23, -33, -23, -15, -11, 19, 8, 46, +9, 53, -8, 38, -29, 9, -37, -19, +-36, -35, -31, -33, -14, -10, 15, 30, +23, 66, 7, 67, -14, 29, -39, -24, +-53, -62, -44, -55, -27, -8, 0, 40, +19, 75, 18, 74, 9, 44, -20, 3, +-49, -38, -57, -57, -40, -45, -18, -5, +5, 46, 19, 78, 14, 66, -9, 14, +-43, -37, -62, -58, -42, -35, -11, 22, +8, 68, 13, 79, 5, 50, -18, 1, +-50, -43, -62, -66, -42, -50, -1, 2, +27, 61, 29, 95, 2, 78, -32, 10, +-63, -60, -68, -87, -47, -50, -10, 20, +22, 82, 27, 102, 4, 72, -31, 15, +-57, -39, -64, -65, -44, -56, -11, -12, +5, 53, 3, 91, -6, 71, -20, 11, +-35, -53, -43, -77, -32, -41, -7, 32, +-1, 94, -14, 102, -21, 55, -36, -14, +-54, -70, -47, -85, -19, -43, 2, 30, +11, 89, -1, 113, -23, 79, -48, -3, +-69, -84, -61, -103, -35, -49, -4, 43, +15, 120, 11, 131, -19, 67, -49, -26, +-69, -85, -61, -88, -30, -34, 1, 45, +10, 103, -4, 107, -40, 55, -67, -28, +-70, -90, -48, -96, -6, -26, 22, 81, +20, 148, -16, 130, -58, 37, -92, -69, +-89, -126, -48, -98, 6, -4, 38, 92, +32, 137, -8, 112, -59, 30, -97, -61, +-97, -109, -58, -83, -8, 0, 22, 93, +22, 140, -11, 108, -51, 13, -79, -77, +-82, -99, -53, -50, -10, 35, 17, 101, +3, 106, -39, 56, -71, -14, -78, -64, +-69, -70, -33, -33, 9, 36, 21, 94, +-2, 104, -45, 68, -82, 2, -87, -65, +-67, -85, -25, -41, 12, 31, 12, 79, +-12, 86, -46, 55, -74, 2, -78, -38, +-53, -42, -21, -19, -6, 16, -22, 55, +-50, 80, -66, 64, -69, 17, -57, -26, +-25, -40, -7, -14, -12, 33, -31, 67, +-66, 59, -86, 17, -75, -19, -45, -31, +-15, -16, -2, 17, -9, 50, -35, 64, +-76, 54, -99, 28, -82, -2, -41, -25, +-13, -20, -2, 13, -17, 45, -47, 49, +-77, 31, -93, -1, -75, -21, -38, -5, +0, 31, 12, 56, -20, 50, -73, 22, +-109, -7, -110, -24, -75, -11, -28, 22, +17, 46, 27, 58, -10, 59, -79, 36, +-127, -10, -123, -44, -81, -37, -28, 0, +11, 46, 18, 80, -15, 76, -72, 28, +-112, -16, -107, -26, -71, -10, -31, 16, +-5, 43, -10, 53, -40, 36, -75, 10, +-95, -7, -83, -21, -52, -16, -29, 23, +-11, 63, -21, 75, -60, 48, -89, 5, +-99, -33, -88, -37, -59, -1, -26, 46, +-11, 68, -20, 63, -52, 40, -78, 4, +-96, -22, -94, -24, -64, -3, -35, 24, +-31, 50, -40, 61, -52, 41, -73, 3, +-88, -13, -78, 0, -47, 27, -31, 56, +-49, 63, -70, 31, -82, -13, -93, -27, +-79, -10, -50, 22, -28, 46, -25, 58, +-41, 49, -72, 28, -103, 10, -106, -9, +-81, -12, -51, 9, -35, 35, -37, 48, +-54, 41, -72, 24, -79, 15, -75, 17, +-68, 27, -58, 28, -59, 12, -72, -9, +-80, -7, -76, 19, -64, 49, -51, 63, +-49, 50, -57, 16, -68, -15, -76, -17, +-76, 16, -79, 46, -81, 57, -79, 50, +-68, 18, -67, -16, -61, -27, -47, -6, +-40, 36, -48, 71, -78, 83, -108, 48, +-110, -14, -94, -50, -66, -30, -42, 23, +-32, 67, -39, 83, -61, 54, -91, 5, +-110, -15, -100, -3, -79, 20, -66, 32, +-63, 31, -59, 16, -49, 2, -61, 15, +-81, 40, -82, 53, -85, 49, -95, 36, +-91, 8, -69, -19, -53, -13, -54, 19, +-61, 43, -75, 52, -99, 39, -103, 6, +-76, -16, -47, 0, -45, 46, -61, 71, +-85, 56, -112, 16, -121, -24, -100, -31, +-61, 10, -32, 62, -33, 83, -58, 58, +-93, 13, -121, -17, -120, -20, -95, 9, +-70, 47, -54, 56, -50, 37, -62, 7, +-80, -11, -95, -1, -88, 32, -76, 69, +-81, 71, -85, 33, -86, -12, -86, -36, +-80, -21, -75, 32, -77, 82, -75, 76, +-75, 28, -79, -17, -82, -27, -87, 5, +-85, 56, -85, 83, -91, 53, -86, -5, +-77, -38, -70, -28, -68, 22, -83, 84, +-98, 108, -100, 70, -91, -3, -82, -51, +-75, -47, -74, -2, -85, 64, -103, 105, +-107, 82, -91, 20, -68, -26, -54, -31, +-50, 8, -79, 65, -123, 83, -138, 44, +-117, -14, -79, -46, -43, -29, -28, 31, +-44, 91, -92, 106, -142, 55, -150, -13, +-116, -48, -70, -31, -42, 20, -37, 73, +-66, 96, -102, 59, -123, -1, -124, -38, +-104, -33, -72, 8, -48, 64, -55, 94, +-86, 73, -106, 20, -106, -28, -108, -42, +-108, -15, -93, 37, -71, 79, -64, 89, +-69, 65, -74, 29, -88, -6, -110, -34, +-122, -30, -117, 0, -103, 40, -81, 77, +-52, 94, -52, 72, -75, 16, -99, -35, +-111, -47, -118, -13, -116, 47, -101, 104, +-82, 108, -65, 43, -64, -33, -71, -74, +-84, -57, -97, 19, -101, 108, -108, 146, +-107, 95, -86, -9, -68, -96, -64, -113, +-80, -37, -107, 93, -117, 178, -105, 162, +-87, 62, -66, -60, -63, -129, -79, -97, +-109, 20, -144, 137, -144, 170, -97, 115, +-50, 6, -31, -96, -49, -109, -92, -29, +-128, 78, -150, 148, -127, 138, -75, 61, +-47, -40, -53, -103, -89, -76, -132, 10, +-134, 91, -93, 138, -53, 122, -42, 44, +-68, -40, -117, -70, -163, -45, -165, 3, +-105, 63, -24, 100, 11, 88, -25, 49, +-98, 11, -167, -23, -196, -32, -155, -9, +-65, 29, 5, 55, 1, 63, -60, 57, +-129, 30, -178, -4, -170, -16, -100, -1, +-29, 26, -14, 55, -47, 76, -107, 69, +-153, 28, -161, -10, -129, -33, -78, -31, +-42, 8, -38, 73, -55, 112, -87, 92, +-121, 36, -131, -27, -124, -67, -117, -53, +-103, 19, -74, 90, -45, 118, -35, 95, +-52, 32, -93, -40, -139, -74, -165, -41, +-147, 29, -95, 93, -42, 120, -12, 90, +-29, 7, -87, -66, -144, -71, -162, -16, +-135, 60, -83, 121, -44, 129, -37, 63, +-63, -26, -103, -78, -130, -73, -135, -19, +-113, 65, -72, 135, -49, 141, -53, 73, +-72, -15, -102, -79, -123, -95, -124, -35, +-111, 67, -87, 131, -60, 127, -42, 70, +-46, -10, -82, -73, -127, -68, -146, -1, +-137, 72, -112, 112, -64, 111, -21, 58, +-22, -27, -75, -81, -136, -61, -159, 12, +-131, 90, -86, 143, -42, 117, -23, 25, +-60, -59, -115, -87, -153, -51, -149, 26, +-92, 106, -27, 138, -7, 94, -45, 15, +-121, -47, -167, -78, -156, -51, -105, 35, +-35, 118, 9, 132, -22, 79, -105, -7, +-171, -80, -183, -78, -130, 1, -41, 97, +19, 134, 7, 106, -73, 33, -159, -51, +-196, -91, -169, -53, -87, 34, 3, 111, +31, 143, -17, 106, -105, 15, -179, -77, +-190, -95, -141, -34, -64, 58, -4, 126, +13, 124, -28, 57, -102, -27, -162, -62, +-170, -33, -125, 21, -64, 70, -17, 86, +-6, 57, -40, 6, -95, -20, -146, -12, +-161, 5, -125, 35, -62, 65, -9, 63, +-1, 29, -44, -1, -106, -6, -149, 4, +-162, 26, -121, 38, -46, 27, 5, 9, +4, 11, -48, 36, -115, 51, -154, 38, +-149, 11, -103, -16, -36, -19, -4, 19, +-26, 68, -76, 76, -125, 41, -142, 3, +-112, -21, -63, -17, -27, 18, -27, 62, +-63, 74, -105, 44, -125, 2, -115, -34, +-74, -40, -43, 10, -40, 84, -54, 118, +-84, 82, -110, -1, -106, -77, -79, -82, +-57, 0, -58, 108, -80, 144, -88, 81, +-81, -24, -71, -92, -59, -70, -56, 33, +-72, 131, -86, 137, -98, 56, -103, -49, +-82, -109, -47, -83, -32, 33, -50, 156, +-80, 180, -97, 89, -101, -55, -87, -161, +-64, -138, -49, 13, -50, 184, -72, 238, +-95, 126, -100, -63, -77, -195, -46, -170, +-36, 8, -50, 196, -77, 247, -101, 131, +-109, -61, -94, -193, -58, -172, -25, -12, +-21, 167, -44, 233, -84, 150, -121, -14, +-117, -150, -84, -160, -46, -37, -20, 128, +-28, 203, -58, 129, -99, -20, -124, -132, +-100, -125, -43, 4, -11, 151, -19, 183, +-61, 74, -109, -74, -127, -145, -104, -86, +-58, 61, -9, 177, 4, 165, -26, 37, +-88, -94, -144, -134, -136, -62, -77, 72, +-26, 166, -3, 145, -9, 28, -49, -91, +-99, -129, -126, -57, -108, 78, -60, 178, +-26, 157, -23, 27, -42, -107, -72, -139, +-92, -50, -93, 95, -85, 180, -64, 128, +-34, -16, -20, -119, -33, -101, -65, 15, +-91, 128, -93, 143, -84, 50, -68, -68, +-42, -112, -20, -50, -20, 66, -38, 147, +-76, 134, -112, 27, -116, -91, -87, -131, +-40, -53, -4, 85, 4, 178, -26, 153, +-80, 14, -122, -135, -118, -167, -78, -45, +-30, 133, 3, 225, -5, 158, -45, -24, +-91, -176, -119, -177, -110, -25, -69, 149, +-14, 217, 15, 144, -6, -16, -63, -143, +-108, -150, -120, -38, -96, 106, -41, 177, +4, 130, 7, 4, -28, -113, -79, -126, +-114, -23, -104, 106, -64, 161, -22, 91, +-8, -42, -22, -127, -42, -89, -66, 43, +-86, 146, -83, 136, -61, 24, -40, -91, +-29, -112, -28, -26, -39, 92, -64, 144, +-82, 88, -74, -26, -51, -106, -34, -90, +-27, 11, -34, 116, -57, 145, -76, 74, +-80, -39, -64, -111, -26, -93, -7, 9, +-22, 116, -57, 143, -89, 67, -87, -53, +-59, -120, -33, -78, -9, 42, -9, 145, +-45, 138, -82, 25, -90, -98, -65, -131, +-35, -45, -16, 92, -18, 167, -37, 113, +-60, -19, -67, -126, -64, -124, -53, -17, +-35, 112, -28, 158, -33, 96, -48, -24, +-54, -119, -55, -110, -55, -6, -55, 118, +-53, 171, -47, 108, -42, -40, -32, -154, +-29, -131, -43, 7, -60, 147, -72, 185, +-74, 83, -49, -75, -5, -155, 12, -105, +-16, 30, -66, 146, -103, 161, -97, 61, +-56, -62, -12, -119, 20, -90, 8, 11, +-41, 111, -86, 129, -108, 63, -82, -32, +-28, -87, 12, -68, 11, 9, -34, 81, +-78, 94, -94, 51, -83, -19, -37, -58, +10, -28, 16, 32, -22, 64, -79, 46, +-116, -6, -86, -52, -18, -34, 27, 29, +14, 85, -35, 81, -81, 20, -109, -51, +-95, -72, -40, -28, 23, 41, 40, 88, +-2, 83, -75, 34, -117, -34, -108, -71, +-57, -60, 9, -2, 37, 74, 16, 103, +-36, 64, -88, -13, -106, -77, -80, -77, +-23, -16, 17, 52, 18, 77, -8, 63, +-51, 23, -75, -16, -75, -33, -66, -39, +-47, -33, -15, -5, 8, 49, 7, 95, +-21, 90, -66, 28, -97, -65, -95, -117, +-54, -74, 1, 44, 26, 145, 11, 147, +-36, 43, -73, -93, -81, -150, -74, -93, +-47, 34, -12, 143, 8, 161, 6, 72, +-25, -57, -79, -142, -101, -132, -63, -24, +0, 116, 29, 185, 0, 129, -58, -18, +-86, -160, -59, -179, -20, -48, -5, 124, +-17, 198, -43, 125, -61, -27, -53, -142, +-34, -135, -10, -27, -5, 86, -29, 126, +-53, 89, -57, 7, -48, -60, -34, -78, +-19, -51, -9, 4, -21, 64, -46, 88, +-50, 48, -35, -18, -20, -55, -12, -45, +-30, -2, -57, 38, -70, 31, -50, -4, +3, -6, 40, 30, 20, 59, -44, 39, +-113, -34, -133, -104, -77, -84, 12, 28, +79, 135, 81, 155, 9, 60, -103, -91, +-174, -181, -145, -132, -44, 10, 72, 146, +132, 199, 85, 125, -47, -32, -166, -174, +-196, -211, -116, -115, 23, 81, 127, 246, +122, 251, 15, 85, -116, -152, -185, -298, +-147, -226, -35, 22, 67, 243, 103, 286, +64, 141, -33, -92, -120, -239, -143, -208, +-100, -60, -14, 111, 62, 208, 64, 185, +0, 55, -73, -98, -104, -192, -71, -170, +-10, -22, 21, 145, -4, 199, -52, 118, +-61, -27, -26, -133, 10, -123, 10, -35, +-36, 35, -76, 52, -68, 51, -31, 55, +9, 53, 10, 25, -16, -54, -33, -123, +-40, -100, -53, 8, -64, 122, -50, 170, +-6, 101, 41, -50, 32, -160, -41, -152, +-103, -50, -82, 79, -20, 159, 25, 132, +35, 20, 0, -93, -49, -146, -71, -107, +-62, 1, -26, 112, 5, 154, 9, 92, +-6, -37, -34, -142, -46, -140, -47, -15, +-45, 129, -37, 166, -29, 55, 3, -114, +38, -175, 27, -69, -26, 112, -93, 197, +-131, 102, -89, -89, 19, -219, 110, -170, +118, 26, 20, 215, -127, 248, -199, 98, +-145, -131, -10, -281, 101, -234, 126, -8, +76, 236, -27, 326, -130, 188, -184, -92, +-149, -310, -23, -306, 114, -98, 168, 169, +104, 323, -47, 271, -185, 47, -208, -211, +-121, -337, 22, -260, 140, -1, 154, 292, +54, 403, -87, 229, -171, -126, -161, -407, +-80, -381, 27, -62, 93, 301, 98, 418, +54, 210, -44, -139, -126, -345, -142, -254, +-88, 11, 7, 207, 74, 204, 80, 55, +46, -82, -20, -105, -94, -43, -128, 8, +-92, 5, -5, -16, 65, 0, 84, 42, +44, 62, -40, 26, -91, -45, -95, -72, +-71, -32, -11, 18, 42, 26, 50, 3, +35, -9, -5, 28, -71, 82, -110, 64, +-87, -56, -11, -179, 64, -161, 85, 15, +31, 216, -69, 269, -126, 92, -95, -184, +-4, -316, 76, -198, 67, 70, 1, 279, +-58, 279, -98, 71, -79, -180, -16, -284, +42, -189, 64, 33, 42, 224, -12, 241, +-74, 77, -108, -131, -82, -231, -15, -150, +64, 47, 104, 186, 50, 155, -49, 10, +-112, -123, -110, -144, -46, -45, 28, 67, +60, 100, 63, 55, 35, -15, -18, -68, +-73, -79, -112, -39, -104, 22, -23, 72, +89, 97, 136, 55, 74, -48, -37, -137, +-137, -134, -168, -30, -90, 119, 32, 200, +121, 126, 134, -58, 60, -207, -63, -200, +-153, -36, -163, 160, -84, 229, 42, 108, +143, -90, 149, -194, 61, -144, -65, 10, +-177, 131, -197, 116, -90, 15, 87, -66, +227, -76, 204, -24, -11, 43, -226, 58, +-264, 12, -127, -46, 90, -75, 225, -46, +185, 42, 33, 121, -121, 95, -195, -20, +-171, -134, -58, -165, 95, -63, 195, 108, +173, 195, 21, 129, -173, -16, -244, -144, +-144, -183, 43, -94, 191, 52, 183, 145, +47, 159, -93, 88, -162, -60, -133, -179, +-37, -181, 60, -76, 115, 88, 125, 215, +71, 185, -66, 16, -194, -157, -180, -228, +-30, -151, 140, 50, 198, 213, 103, 197, +-57, 56, -152, -115, -144, -206, -57, -128, +50, 28, 110, 114, 98, 124, 22, 83, +-60, -20, -96, -106, -70, -110, -4, -65, +46, 17, 58, 110, 37, 109, -12, 10, +-31, -79, -11, -102, -10, -46, -18, 52, +-27, 85, -23, 14, 26, -56, 75, -53, +55, 2, -33, 74, -100, 88, -73, -5, +12, -116, 67, -138, 51, -56, 3, 88, +-11, 201, -4, 155, -5, -26, -21, -190, +-48, -233, -39, -117, 28, 93, 80, 235, +67, 220, 5, 87, -70, -101, -100, -252, +-54, -265, 32, -115, 97, 127, 99, 335, +43, 341, -48, 86, -112, -263, -91, -449, +-24, -328, 58, 28, 127, 364, 123, 443, +48, 230, -66, -123, -160, -390, -146, -411, +-26, -180, 112, 154, 193, 404, 154, 403, +7, 120, -154, -246, -196, -435, -90, -327, +65, -11, 159, 296, 135, 363, 37, 177, +-37, -78, -60, -240, -76, -233, -68, -94, +-31, 59, 37, 136, 126, 141, 153, 86, +68, -5, -82, -82, -183, -117, -152, -98, +-6, -22, 155, 61, 205, 86, 110, 60, +-41, 19, -144, -24, -121, -45, 1, -42, +74, -54, 56, -54, 11, 7, 0, 76, +43, 101, 78, 70, 32, -26, -71, -119, +-133, -116, -74, -34, 59, 45, 162, 75, +156, 56, 30, 15, -91, -4, -118, -5, +-67, -45, 18, -95, 77, -87, 82, -2, +61, 118, 28, 172, -7, 79, -24, -100, +-41, -214, -49, -167, -19, 18, 45, 193, +105, 201, 114, 28, 64, -160, -30, -196, +-122, -61, -120, 115, -22, 169, 90, 47, +154, -118, 115, -151, 13, -35, -59, 107, +-76, 137, -40, 36, 17, -100, 48, -148, +44, -73, 39, 36, 49, 92, 57, 84, +33, 32, -18, -36, -66, -80, -66, -84, +-7, -55, 62, 7, 112, 79, 120, 101, +48, 53, -52, -30, -106, -95, -96, -103, +-10, -46, 94, 35, 149, 85, 124, 84, +30, 29, -74, -56, -119, -103, -72, -75, +36, -4, 115, 64, 130, 78, 66, 26, +-28, -48, -60, -70, -32, -40, 18, 14, +57, 66, 45, 57, -1, -22, -14, -102, +3, -111, 52, -38, 105, 110, 90, 208, +-2, 120, -107, -107, -124, -291, -35, -276, +100, -27, 202, 297, 191, 410, 57, 195, +-119, -181, -229, -444, -175, -394, 39, -55, +250, 321, 304, 454, 157, 275, -91, -80, +-245, -385, -205, -428, -24, -189, 157, 154, +232, 378, 192, 348, 64, 89, -77, -212, +-158, -348, -149, -268, -31, -53, 128, 170, +205, 276, 167, 212, 44, 46, -93, -137, +-133, -268, -62, -243, 53, -60, 126, 143, +103, 252, 27, 212, -21, 27, -10, -183, +31, -262, 48, -173, 52, -3, 27, 174, +-33, 237, -55, 121, -12, -78, 83, -214, +165, -208, 142, -47, 4, 162, -139, 223, +-179, 90, -64, -112, 136, -223, 263, -148, +218, 66, 27, 212, -165, 147, -227, -43, +-114, -207, 115, -213, 269, -16, 228, 203, +47, 219, -133, 40, -166, -172, -54, -253, +88, -110, 155, 135, 115, 222, 20, 89, +-44, -102, -36, -193, 25, -105, 77, 77, +79, 154, 31, 53, -31, -94, -37, -153, +10, -82, 67, 69, 113, 154, 104, 86, +20, -59, -53, -162, -67, -144, -18, -5, +76, 133, 123, 135, 95, 1, 31, -131, +-15, -149, -11, -24, 17, 125, 27, 125, +4, -24, 0, -161, 53, -153, 114, -3, +124, 161, 64, 171, -56, 17, -141, -155, +-93, -204, 55, -107, 206, 61, 239, 168, +105, 141, -90, 22, -191, -110, -125, -170, +41, -114, 192, 6, 211, 98, 88, 100, +-60, 27, -99, -55, -20, -64, 86, -16, +115, 3, 36, -28, -43, -85, -36, -100, +48, 2, 142, 149, 156, 185, 50, 66, +-91, -137, -140, -291, -56, -245, 87, 1, +197, 244, 194, 305, 76, 155, -57, -112, +-129, -304, -108, -275, 6, -85, 128, 116, +173, 227, 138, 192, 49, 45, -35, -104, +-60, -197, -39, -214, -12, -101, 15, 77, +73, 176, 152, 162, 193, 52, 123, -99, +-50, -176, -191, -129, -174, -52, -13, 3, +195, 54, 314, 82, 239, 76, 15, 53, +-205, -22, -264, -143, -100, -191, 158, -109, +308, 46, 240, 192, 24, 208, -157, 49, +-177, -159, -24, -255, 149, -170, 194, 27, +107, 184, -18, 164, -74, -3, -12, -146, +90, -162, 120, -51, 58, 91, -31, 126, +-58, 19, 14, -124, 111, -173, 134, -89, +80, 76, 1, 195, -49, 152, -41, -47, +37, -247, 106, -282, 107, -108, 58, 156, +-3, 303, -27, 201, 23, -67, 87, -276, +94, -277, 54, -102, -9, 105, -49, 190, +-27, 121, 59, 7, 154, -69, 182, -105, +86, -109, -81, -86, -177, -46, -93, 26, +97, 118, 247, 128, 231, 34, 44, -92, +-119, -181, -132, -169, -20, -46, 108, 95, +155, 151, 101, 102, 24, -23, -10, -163, +30, -200, 87, -96, 70, 53, -20, 148, +-86, 132, -28, -19, 123, -173, 228, -175, +186, -49, 10, 94, -165, 150, -183, 56, +-38, -122, 175, -197, 293, -97, 217, 54, +15, 140, -161, 99, -188, -59, -46, -177, +155, -133, 256, 1, 186, 110, -3, 113, +-141, -21, -129, -165, 22, -153, 182, 1, +211, 150, 92, 165, -59, 3, -136, -218, +-65, -287, 99, -125, 208, 130, 189, 285, +58, 225, -82, -30, -127, -291, -41, -358, +96, -206, 190, 62, 174, 298, 67, 338, +-54, 127, -77, -192, -16, -399, 45, -358, +83, -75, 90, 256, 79, 373, 85, 202, +78, -95, 15, -308, -60, -300, -90, -102, +-20, 104, 124, 164, 233, 101, 189, 4, +37, -69, -111, -80, -163, -52, -65, -51, +129, -70, 241, -57, 181, -17, 29, 39, +-110, 90, -104, 78, 43, -10, 173, -106, +153, -159, 24, -149, -98, -62, -84, 59, +71, 138, 213, 148, 198, 75, 48, -79, +-114, -229, -174, -259, -56, -149, 155, 49, +279, 238, 222, 274, 42, 106, -150, -148, +-194, -320, -56, -323, 143, -139, 240, 130, +208, 297, 82, 266, -60, 69, -116, -187, +-70, -351, 38, -312, 140, -96, 177, 155, +101, 299, 6, 256, -39, 40, -17, -216, +41, -342, 86, -273, 65, -54, 25, 184, +32, 280, 57, 179, 69, -33, 60, -212, +33, -261, -6, -167, 1, -5, 42, 104, +98, 127, 122, 101, 82, 27, -5, -80, +-49, -161, -23, -193, 54, -149, 131, -3, +154, 156, 98, 206, -11, 112, -72, -72, +-40, -252, 68, -289, 140, -135, 120, 75, +25, 208, -28, 212, 15, 70, 97, -124, +106, -231, 27, -219, -54, -134, -49, 15, +60, 159, 194, 198, 216, 136, 67, -13, +-121, -221, -206, -336, -70, -241, 191, -6, +344, 242, 240, 346, -13, 183, -212, -145, +-201, -370, -3, -352, 204, -139, 264, 139, +164, 282, 24, 196, -75, 12, -65, -130, +10, -210, 77, -206, 71, -117, 52, -19, +55, 91, 86, 189, 118, 160, 100, -4, +14, -180, -79, -266, -86, -214, -3, -40, +140, 122, 227, 167, 190, 122, 48, 37, +-75, -82, -137, -184, -84, -218, 59, -170, +189, -31, 209, 150, 130, 236, 29, 148, +-34, -41, -32, -217, -15, -289, -6, -210, +11, -42, 83, 114, 165, 213, 232, 221, +188, 98, 12, -133, -196, -350, -270, -412, +-124, -230, 180, 143, 421, 458, 402, 458, +143, 112, -186, -351, -345, -620, -238, -484, +44, -16, 295, 429, 373, 545, 232, 276, +20, -182, -119, -510, -138, -479, -98, -150, +-19, 206, 84, 360, 181, 249, 263, -30, +246, -252, 78, -264, -155, -130, -272, 17, +-202, 90, 71, 48, 351, -35, 428, -43, +231, 12, -86, 33, -298, -26, -246, -139, +19, -209, 249, -119, 280, 90, 155, 222, +14, 156, -60, -66, -14, -266, 42, -269, +46, -63, 14, 148, 33, 173, 76, 33, +114, -125, 113, -164, 61, -61, 1, 52, +-4, 45, 15, -42, 12, -104, 49, -85, +85, -7, 107, 59, 103, 46, 70, -38, +-11, -100, -28, -105, 30, -67, 79, 6, +79, 58, 51, 35, 15, -37, 41, -105, +133, -121, 154, -61, 71, 41, -65, 91, +-136, 30, -74, -82, 122, -162, 267, -150, +260, -29, 117, 110, -50, 142, -146, 35, +-125, -124, -37, -230, 79, -195, 207, -26, +288, 131, 253, 169, 66, 83, -144, -66, +-260, -197, -189, -226, 15, -135, 262, 10, +394, 149, 334, 202, 102, 99, -175, -104, +-342, -260, -276, -270, 13, -124, 330, 92, +485, 210, 348, 158, 26, 12, -265, -129, +-331, -208, -179, -187, 93, -85, 295, 32, +346, 118, 247, 142, 72, 64, -93, -79, +-195, -187, -184, -212, -56, -139, 139, 12, +291, 140, 331, 162, 203, 75, -8, -74, +-192, -208, -234, -232, -133, -126, 84, 28, +300, 137, 369, 157, 237, 68, -8, -82, +-211, -197, -241, -228, -66, -154, 141, 19, +283, 170, 283, 181, 138, 56, -61, -117, +-147, -232, -99, -207, 31, -76, 137, 53, +153, 125, 117, 132, 87, 57, 66, -88, +5, -210, -44, -242, -33, -144, 48, 67, +117, 231, 132, 204, 89, 10, 58, -206, +28, -310, 19, -234, 16, -16, 21, 182, +58, 242, 85, 151, 84, -67, 66, -292, +40, -344, 1, -180, 33, 92, 99, 293, +134, 262, 86, 5, 4, -264, -76, -345, +-52, -212, 78, 33, 198, 206, 209, 192, +113, 41, -21, -112, -117, -190, -89, -168, +4, -75, 114, 13, 194, 47, 225, 48, +145, 29, 7, -7, -121, -45, -161, -91, +-81, -143, 104, -149, 266, -69, 295, 64, +206, 169, 12, 165, -188, 12, -251, -208, +-123, -331, 74, -251, 285, 0, 394, 257, +305, 327, 42, 138, -226, -178, -372, -392, +-261, -349, 89, -78, 410, 217, 493, 324, +324, 173, -13, -97, -344, -283, -400, -273, +-188, -109, 170, 59, 471, 120, 501, 81, +189, 14, -187, -31, -347, -60, -237, -91, +30, -127, 249, -132, 281, -70, 191, 39, +116, 140, 38, 157, -47, 54, -150, -140, +-182, -311, -68, -312, 202, -99, 412, 211, +374, 392, 96, 262, -223, -118, -370, -454, +-228, -477, 122, -164, 404, 245, 424, 441, +179, 286, -132, -75, -301, -364, -185, -401, +76, -194, 269, 92, 265, 259, 127, 215, +-34, 32, -99, -156, -41, -233, 49, -162, +110, -29, 116, 43, 74, 32, 15, 4, +16, 1, 55, 32, 90, 32, 71, -62, +6, -183, -47, -211, -3, -101, 108, 89, +186, 226, 142, 189, 4, -14, -107, -233, +-103, -326, 50, -227, 214, 16, 238, 233, +78, 273, -104, 114, -163, -133, -49, -304, +142, -286, 261, -104, 212, 96, 61, 184, +-104, 147, -185, 39, -79, -80, 115, -165, +230, -205, 201, -181, 88, -57, -30, 127, +-41, 241, 1, 177, 14, -47, -9, -281, +16, -343, 90, -166, 176, 100, 211, 250, +121, 212, -64, 26, -213, -183, -197, -277, +6, -224, 303, -75, 439, 112, 277, 236, +-82, 180, -348, -36, -325, -253, -40, -309, +278, -150, 414, 107, 301, 234, 63, 132, +-151, -64, -261, -181, -196, -160, 13, -61, +238, 6, 323, 3, 247, 3, 51, 48, +-117, 54, -169, -17, -122, -116, -18, -172, +125, -122, 243, 12, 250, 108, 137, 100, +-42, 31, -168, -61, -163, -143, -37, -166, +113, -119, 231, -23, 250, 102, 158, 169, +-12, 103, -164, -51, -201, -200, -92, -260, +113, -170, 300, 36, 312, 209, 118, 223, +-121, 73, -225, -158, -123, -302, 74, -232, +200, -19, 178, 149, 103, 166, 24, 63, +-46, -62, -63, -115, -3, -107, 76, -94, +129, -75, 111, -10, 2, 69, -57, 93, +-2, 27, 91, -82, 116, -132, 81, -90, +3, -25, -31, -15, 17, -37, 74, -6, +75, 67, 46, 89, 6, -9, -14, -168, +35, -224, 107, -85, 120, 130, 46, 191, +-57, 39, -109, -165, -10, -219, 170, -68, +250, 128, 125, 147, -93, -23, -217, -190, +-125, -188, 119, -29, 298, 134, 253, 147, +45, 6, -138, -137, -192, -170, -66, -119, +130, -30, 218, 65, 153, 112, 19, 97, +-93, 7, -74, -137, 56, -231, 147, -164, +104, 27, -9, 176, -89, 157, -51, -4, +104, -157, 202, -152, 130, -22, -27, 42, +-123, -28, -95, -118, 52, -90, 175, 71, +168, 210, 66, 129, -34, -147, -72, -344, +-35, -264, 28, 21, 57, 264, 78, 258, +105, 40, 116, -171, 66, -213, -45, -129, +-143, -54, -102, -15, 57, 38, 198, 120, +203, 158, 87, 53, -26, -179, -53, -323, +-40, -213, -44, 52, -43, 241, 29, 206, +174, 5, 265, -153, 168, -137, -87, -60, +-275, -68, -216, -117, 62, -86, 313, 82, +311, 278, 77, 265, -166, -38, -207, -391, +-49, -471, 127, -196, 159, 225, 76, 462, +-1, 330, 3, -43, 43, -347, 47, -390, +9, -200, -13, 61, -14, 215, -3, 187, +43, 74, 113, -19, 148, -86, 90, -149, +-40, -196, -146, -176, -108, -31, 37, 200, +165, 315, 186, 167, 101, -132, -15, -355, +-87, -324, -111, -69, -69, 185, 48, 242, +187, 131, 229, -4, 119, -99, -79, -163, +-228, -192, -172, -166, 60, -27, 266, 189, +272, 293, 72, 157, -158, -123, -187, -337, +-21, -337, 147, -101, 146, 209, 12, 347, +-88, 230, -30, -53, 111, -337, 157, -382, +53, -121, -82, 214, -111, 321, -2, 135, +132, -172, 149, -280, 45, -93, -64, 134, +-93, 115, -9, -104, 110, -220, 144, -34, +67, 267, -46, 296, -97, -74, -44, -478, +61, -444, 125, 63, 100, 541, 25, 483, +-24, -78, -24, -593, -2, -543, 20, 25, +37, 515, 40, 442, 41, -59, 44, -460, +42, -371, 24, 92, -23, 395, -69, 193, +-35, -245, 67, -423, 141, -135, 122, 349, +28, 498, -69, 84, -94, -478, -50, -607, +2, -171, 59, 417, 133, 602, 161, 206, +104, -349, -29, -513, -181, -210, -198, 175, +-26, 271, 186, 64, 273, -153, 170, -100, +-61, 115, -193, 161, -120, -51, 38, -293, +117, -302, 85, -15, 0, 317, -6, 372, +78, 112, 109, -220, 7, -388, -125, -288, +-177, -2, -66, 245, 155, 306, 297, 167, +240, -81, 14, -265, -229, -253, -312, -82, +-157, 85, 116, 111, 309, 29, 321, -8, +157, 69, -90, 132, -267, 26, -281, -252, +-121, -437, 145, -243, 343, 247, 315, 602, +73, 474, -203, -106, -303, -671, -162, -700, +100, -154, 257, 490, 211, 718, 47, 366, +-104, -258, -156, -616, -76, -462, 42, -4, +94, 366, 82, 378, 47, 97, 7, -166, +2, -204, 10, -69, -27, 35, -67, -6, +-40, -103, 53, -83, 156, 80, 162, 224, +-2, 159, -182, -105, -170, -317, 37, -262, +248, 16, 233, 283, -41, 302, -283, 42, +-208, -250, 94, -328, 300, -164, 214, 117, +-58, 312, -197, 243, -76, -22, 87, -258, +84, -294, -39, -127, -110, 133, -1, 238, +191, 107, 215, -66, 21, -96, -184, -23, +-197, 52, -39, -11, 125, -196, 145, -229, +56, 30, -9, 329, 11, 367, 40, 76, +0, -362, -104, -522, -112, -215, 20, 243, +155, 445, 153, 301, 18, -61, -101, -302, +-66, -235, 25, -58, 34, -6, -32, -7, +-46, 24, 45, 161, 153, 309, 137, 204, +-15, -206, -160, -534, -157, -488, -42, -33, +90, 497, 158, 643, 147, 270, 98, -258, +-14, -546, -173, -422, -241, -48, -140, 254, +93, 310, 316, 207, 313, 45, 56, -103, +-234, -175, -299, -197, -112, -154, 124, -13, +171, 138, 58, 199, -2, 186, 86, 55, +131, -138, 2, -270, -233, -241, -300, -73, +-44, 182, 296, 321, 367, 209, 111, -41, +-215, -221, -282, -274, -62, -146, 167, 66, +155, 196, -34, 203, -165, 123, -68, -93, +165, -266, 264, -207, 76, 17, -212, 220, +-311, 247, -99, 2, 220, -261, 328, -217, +123, 50, -176, 218, -271, 144, -83, -119, +160, -264, 236, -68, 93, 231, -131, 276, +-226, 45, -110, -262, 105, -353, 235, -113, +182, 203, -29, 320, -218, 214, -195, -26, +4, -256, 164, -315, 165, -178, 32, 89, +-66, 352, -46, 379, -13, 80, -49, -326, +-80, -510, -53, -277, 80, 217, 221, 541, +208, 398, -2, -52, -237, -422, -323, -406, +-172, -70, 141, 227, 357, 207, 280, 6, +28, -91, -210, 47, -261, 238, -103, 194, +54, -188, 73, -539, 58, -445, 68, 95, +102, 616, 92, 673, -30, 133, -181, -524, +-189, -700, -26, -286, 149, 275, 213, 542, +85, 316, -104, -139, -123, -347, -7, -182, +48, 55, 12, 159, -96, 68, -100, -102, +89, -89, 285, 97, 208, 190, -86, 74, +-369, -145, -383, -307, -73, -198, 333, 127, +460, 350, 271, 273, -87, 37, -392, -197, +-410, -246, -133, -122, 177, -13, 312, -23, +215, 29, 7, 172, -109, 298, -79, 230, +-5, -79, -32, -450, -110, -475, -154, -83, +-39, 365, 195, 496, 339, 243, 191, -183, +-110, -376, -374, -204, -351, 44, -35, 145, +334, 107, 371, 18, 95, 0, -240, 73, +-322, 21, -105, -131, 222, -197, 258, -106, +26, 103, -210, 316, -209, 243, 19, -48, +259, -286, 190, -311, -99, -113, -277, 207, +-181, 314, 73, 135, 271, -89, 224, -197, +-20, -123, -197, 92, -205, 158, -80, -17, +89, -165, 146, -137, 53, 34, -17, 234, +-47, 247, -1, -20, 70, -235, 59, -229, +-89, -77, -185, 105, -150, 216, 16, 113, +194, -3, 278, -46, 151, -90, -69, -122, +-274, -35, -335, 29, -153, 71, 176, 125, +358, 69, 252, -58, -63, -50, -283, -21, +-209, -53, 60, -18, 196, 8, 31, -1, +-209, 75, -191, 120, 98, 4, 350, -47, +262, -58, -120, -75, -436, -16, -359, 78, +31, 26, 352, 8, 362, 9, 100, -23, +-201, 4, -265, 99, -142, 29, -21, -91, +57, -154, 98, -114, 117, 76, 137, 315, +62, 246, -112, -90, -235, -373, -206, -365, +-71, -20, 129, 433, 275, 507, 231, 104, +54, -352, -130, -524, -301, -257, -296, 231, +-84, 499, 145, 286, 303, -89, 320, -333, +111, -244, -229, 68, -418, 279, -334, 106, +10, -167, 385, -255, 426, -42, 63, 284, +-287, 394, -353, 36, -95, -382, 214, -439, +254, -96, -19, 364, -215, 519, -150, 140, +81, -350, 204, -465, 120, -196, -133, 243, +-237, 481, -94, 280, 100, -145, 172, -377, +106, -340, -98, -25, -180, 319, -47, 389, +85, 116, 81, -196, 1, -359, -99, -196, +-106, 142, 52, 334, 164, 182, 78, -84, +-57, -248, -156, -164, -189, 51, -39, 175, +123, 89, 155, -28, 149, -46, 75, 13, +-124, 34, -246, -23, -214, -89, -79, -69, +151, 50, 329, 121, 209, 74, -49, -34, +-224, -65, -274, -30, -127, 44, 104, 27, +161, -50, 113, -96, 59, 2, -52, 127, +-117, 173, -80, 51, -56, -121, -30, -216, +62, -110, 90, 79, 36, 194, 8, 144, +-50, 18, -108, -95, -55, -109, -15, -41, +11, -11, 94, -27, 111, 10, -2, 100, +-117, 154, -158, 132, -86, -29, 81, -216, +188, -250, 72, -90, -112, 103, -173, 269, +-80, 259, 103, 75, 182, -138, 47, -261, +-112, -274, -170, -64, -118, 229, 10, 371, +126, 246, 119, -82, 39, -408, -24, -380, +-67, 6, -94, 386, -50, 433, -40, 86, +-33, -355, 43, -443, 114, -83, 87, 323, +10, 400, -104, 73, -143, -317, -52, -363, +58, 5, 45, 354, -2, 341, 2, -39, +11, -393, 11, -363, -25, 45, -99, 396, +-73, 372, 68, 11, 153, -330, 101, -335, +-106, -11, -294, 294, -244, 274, 79, -18, +345, -288, 324, -281, 18, 34, -305, 362, +-363, 355, -96, 42, 137, -331, 165, -442, +41, -173, -36, 264, 1, 454, 79, 275, +16, -128, -111, -411, -176, -311, -91, 103, +46, 395, 141, 307, 115, -95, -8, -450, +-131, -369, -132, 119, -5, 529, 140, 455, +143, -44, -33, -525, -236, -501, -261, -1, +-11, 466, 255, 433, 298, -14, 86, -413, +-187, -346, -297, 84, -146, 429, 63, 316, +180, -111, 106, -420, -55, -318, -164, 50, +-79, 354, 88, 331, 166, 33, 54, -243, +-137, -269, -240, -68, -111, 184, 80, 280, +174, 94, 120, -199, -30, -334, -134, -157, +-90, 196, -16, 438, 19, 282, 14, -131, +-19, -445, -52, -338, -5, 52, 69, 389, +61, 324, -13, -41, -97, -352, -146, -271, +-44, 77, 91, 378, 113, 334, 42, -26, +-54, -421, -125, -457, -89, -100, 1, 352, +57, 549, 48, 302, 21, -218, -42, -543, +-69, -368, -40, 103, -23, 487, -5, 397, +44, -74, 38, -472, -2, -353, -55, 86, +-123, 461, -96, 370, 65, -74, 177, -453, +94, -333, -86, 73, -216, 402, -183, 311, +23, -67, 187, -382, 110, -260, -31, 101, +-103, 366, -78, 275, 24, -70, 62, -365, +-63, -290, -157, 54, -102, 330, 49, 304, +182, 0, 201, -304, -11, -300, -241, 16, +-246, 288, -92, 298, 92, 20, 174, -276, +56, -311, -78, -4, -39, 255, 24, 296, +26, 58, -41, -218, -136, -305, -156, -66, +8, 166, 127, 271, 96, 169, 35, -61, +-16, -266, -92, -221, -61, -71, -57, 144, +-86, 302, -22, 231, 71, -47, 57, -249, +27, -279, -27, -97, -87, 198, -32, 295, +75, 103, 40, -125, -92, -203, -173, -111, +-181, 121, 14, 211, 250, 60, 261, -128, +39, -158, -190, -81, -322, 104, -195, 195, +43, 92, 175, -90, 115, -134, 42, -86, +-44, 57, -71, 164, -38, 86, -35, -112, +-105, -166, -62, -73, 21, 111, 80, 248, +86, 138, -5, -149, -145, -279, -147, -147, +-2, 108, 98, 303, 92, 204, -7, -113, +-133, -287, -140, -142, 0, 138, 45, 320, +7, 176, -47, -198, -37, -409, 31, -217, +113, 190, 18, 484, -139, 375, -214, -88, +-102, -477, 61, -439, 203, -52, 112, 353, +-104, 430, -191, 108, -73, -255, 72, -298, +136, -15, -8, 272, -206, 276, -195, -71, +19, -389, 184, -335, 156, 68, -26, 421, +-213, 423, -175, 39, 33, -331, 150, -347, +75, -43, -79, 211, -222, 192, -159, -51, +56, -201, 212, -69, 160, 196, -14, 268, +-199, 96, -234, -154, -85, -265, 101, -149, +126, 36, 23, 114, -105, 98, -141, 85, +4, 51, 157, 16, 133, -55, -54, -113, +-237, -77, -270, 59, -74, 95, 178, 23, +247, -79, 76, -74, -108, 48, -178, 179, +-84, 108, 44, -93, 28, -225, -100, -132, +-125, 115, -40, 280, 99, 145, 174, -154, +86, -327, -117, -192, -222, 158, -175, 423, +-62, 322, 93, -46, 170, -355, 81, -386, +-58, -122, -146, 193, -165, 285, -25, 160, +119, 15, 114, -70, -27, -58, -163, -30, +-197, -73, -34, -114, 173, -34, 197, 84, +-2, 159, -207, 150, -281, 31, -115, -113, +162, -137, 254, -85, 115, 0, -115, 134, +-286, 185, -241, 59, 2, -129, 180, -262, +187, -228, 42, 89, -129, 414, -205, 398, +-79, 73, 58, -323, 65, -522, -46, -287, +-140, 165, -106, 385, 117, 308, 253, 97, +120, -103, -198, -125, -406, -39, -297, -102, +75, -203, 372, -143, 308, 49, -24, 273, +-281, 392, -271, 179, -60, -165, 113, -327, +45, -266, -103, -80, -121, 156, 39, 206, +183, 127, 157, 77, -81, 36, -296, -71, +-293, -117, -79, -126, 125, -75, 238, 77, +178, 171, -2, 81, -164, -39, -236, -98, +-217, -91, -49, 25, 144, 124, 202, 89, +93, 26, -92, 2, -207, -76, -146, -127, +29, -117, 73, -46, -18, 111, -109, 304, +-81, 247, 59, -4, 179, -258, 61, -339, +-172, -191, -316, 117, -218, 247, 60, 180, +304, 81, 272, 27, 6, -7, -282, -25, +-360, -133, -188, -220, 114, -106, 246, 118, +122, 231, -79, 179, -185, 14, -108, -115, +63, -49, 103, 53, -52, 3, -212, -153, +-207, -204, 5, -75, 230, 232, 256, 407, +-7, 255, -306, -113, -349, -346, -106, -320, +212, -58, 308, 188, 64, 225, -249, 76, +-324, -16, -113, -16, 172, 17, 239, -3, +34, -86, -223, -153, -237, -67, -28, 103, +170, 200, 155, 166, -62, 26, -293, -115, +-249, -167, -4, -103, 241, -31, 277, 76, +75, 167, -224, 177, -344, 50, -226, -109, +-2, -232, 163, -175, 198, 7, 51, 170, +-93, 155, -106, 72, -68, 19, -24, 55, +-17, 47, -110, -80, -191, -276, -95, -289, +103, -17, 266, 356, 241, 498, -16, 257, +-360, -198, -431, -499, -214, -402, 129, -49, +357, 270, 287, 349, -48, 223, -279, 9, +-284, -113, -90, -153, 113, -125, 133, -65, +-61, 34, -188, 88, -94, 117, 116, 84, +225, 25, 86, -50, -258, -78, -450, -90, +-236, -62, 172, 14, 447, 105, 345, 132, +-96, 91, -502, -17, -475, -123, -110, -132, +263, -30, 374, 94, 171, 155, -189, 113, +-307, -32, -172, -133, 8, -106, 104, 20, +54, 108, -106, 95, -132, -51, -19, -142, +60, -57, 65, 130, 15, 200, -104, 93, +-171, -135, -100, -248, -23, -104, 55, 166, +111, 267, 9, 137, -146, -118, -151, -263, +-78, -146, 64, 97, 168, 210, 54, 139, +-188, -29, -258, -167, -151, -137, 42, 5, +238, 106, 198, 131, -89, 94, -274, -21, +-245, -103, -78, -80, 172, -11, 227, 61, +-10, 106, -247, 36, -251, -74, -82, -81, +186, -15, 285, 56, 48, 90, -284, 20, +-356, -92, -185, -86, 141, 16, 347, 98, +176, 114, -185, 27, -350, -107, -244, -109, +62, 17, 312, 122, 203, 125, -179, 15, +-417, -152, -293, -192, 62, -30, 402, 157, +353, 232, -82, 137, -442, -80, -426, -233, +-134, -164, 243, -2, 342, 134, 81, 172, +-218, 112, -233, -1, -63, -34, 119, -46, +119, -71, -132, -87, -347, -54, -199, -7, +116, 101, 348, 162, 324, 117, -54, 3, +-464, -96, -508, -161, -182, -125, 228, 8, +471, 129, 295, 180, -152, 130, -435, -12, +-355, -141, -81, -128, 236, -32, 269, 71, +5, 77, -219, 6, -194, -77, -36, -14, +151, 97, 113, 134, -152, -7, -329, -173, +-184, -231, 114, -19, 330, 273, 263, 372, +-103, 120, -427, -219, -396, -391, -112, -214, +192, 126, 320, 317, 140, 196, -129, -20, +-238, -123, -139, -64, -3, 34, 64, 6, +-38, -124, -187, -157, -190, 22, 1, 234, +188, 314, 266, 152, 97, -108, -223, -285, +-418, -221, -331, -70, -48, 86, 247, 157, +323, 174, 130, 110, -135, 56, -250, -62, +-197, -175, -66, -219, 39, -118, 7, 29, +-50, 213, -31, 282, 28, 186, 54, -8, +35, -172, -84, -262, -189, -187, -192, 10, +-55, 156, 106, 206, 188, 165, 86, 28, +-139, -122, -278, -154, -195, -129, 6, -25, +173, 95, 154, 130, -28, 48, -191, 13, +-204, -9, -75, 7, 59, 31, 103, 12, +20, -81, -116, -65, -182, 7, -80, 51, +77, 55, 170, 24, 55, -39, -176, -3, +-322, 76, -211, 40, 59, -62, 259, -115, +219, -95, -22, 45, -271, 219, -284, 196, +-117, 25, 76, -138, 160, -214, 57, -145, +-111, 91, -148, 224, -56, 165, 35, -3, +56, -185, -41, -245, -152, -33, -128, 216, +16, 254, 68, 96, 25, -150, -90, -295, +-182, -119, -100, 185, 110, 274, 187, 138, +99, -96, -135, -247, -352, -143, -341, 114, +-64, 181, 241, 76, 367, -64, 221, -141, +-135, -71, -403, 110, -370, 138, -144, 31, +111, -69, 230, -106, 107, -47, -45, 123, +-78, 188, -57, 81, -37, -75, -67, -196, +-179, -190, -195, 16, -36, 234, 144, 231, +185, 68, 85, -151, -110, -260, -217, -126, +-119, 129, -16, 202, -30, 105, -85, -68, +-118, -147, -43, -22, 144, 214, 215, 233, +76, 22, -169, -252, -352, -370, -345, -197, +-82, 213, 205, 465, 296, 368, 175, 12, +-49, -369, -261, -487, -263, -197, -139, 221, +-19, 418, 66, 301, 85, -34, 12, -303, +-30, -247, -18, 52, -26, 259, -50, 218, +-63, -60, -128, -314, -174, -264, -80, 69, +42, 330, 149, 305, 185, 10, 48, -301, +-173, -320, -279, -2, -251, 294, -102, 304, +97, 29, 196, -271, 99, -295, -29, 7, +-117, 310, -124, 313, -32, 42, 4, -263, +-121, -323, -200, -84, -132, 203, 49, 257, +254, 83, 260, -130, -6, -172, -279, -20, +-340, 144, -220, 121, 6, -39, 172, -139, +128, -59, 11, 135, -29, 225, -58, 73, +-56, -203, -38, -320, -109, -145, -177, 198, +-123, 394, -7, 277, 117, -82, 187, -362, +88, -352, -133, -60, -243, 227, -173, 329, +-38, 190, 86, -36, 56, -177, -94, -125, +-136, -8, -18, 80, 105, 51, 140, -50, +11, -107, -203, -14, -309, 129, -187, 180, +14, 77, 179, -120, 222, -219, 88, -103, +-113, 111, -208, 191, -226, 102, -143, -85, +28, -149, 120, -9, 80, 185, -6, 174, +-80, 0, -103, -214, -14, -262, 48, -97, +-43, 163, -157, 245, -161, 172, -76, 18, +106, -93, 189, -107, 53, -43, -151, -61, +-214, -92, -146, -41, 23, 98, 131, 262, +58, 332, -105, 131, -150, -238, -113, -462, +-20, -395, 97, -67, 108, 345, 2, 514, +-90, 310, -167, -16, -176, -271, -69, -335, +49, -201, 73, -11, 56, 87, 17, 190, +-47, 249, -60, 182, -63, 24, -129, -143, +-141, -273, -64, -189, 6, 42, 78, 178, +125, 143, 52, 22, -76, -104, -154, -82, +-184, 81, -134, 153, 23, 73, 129, -63, +74, -150, -35, -122, -140, 44, -159, 123, +6, 58, 140, -14, 50, 2, -130, 58, +-222, 136, -152, 63, 86, -167, 235, -309, +79, -206, -169, 47, -239, 323, -135, 385, +82, 146, 197, -158, 32, -283, -169, -206, +-172, -3, -67, 174, 58, 147, 101, 27, +-39, -48, -165, -61, -96, -36, 42, 39, +118, 51, 125, 34, -31, 18, -230, -9, +-243, -77, -123, -69, 30, -40, 199, 4, +197, 65, 20, 118, -133, 98, -186, 95, +-158, 63, -27, -48, 58, -178, -10, -236, +-104, -187, -111, 32, -28, 292, 146, 367, +227, 199, 61, -85, -192, -309, -315, -309, +-258, -67, -52, 152, 140, 201, 148, 100, +61, -37, 12, -88, 5, 14, 2, 93, +-25, 52, -145, -52, -264, -106, -228, -74, +-51, 52, 164, 104, 297, 7, 217, -132, +-27, -136, -230, 14, -252, 249, -130, 349, +18, 167, 65, -179, -26, -415, -109, -383, +-51, -89, 97, 263, 212, 406, 172, 271, +-54, 29, -305, -151, -370, -188, -194, -115, +105, -64, 309, -72, 254, -40, -5, 65, +-214, 176, -211, 209, -57, 110, 80, -74, +55, -168, -77, -111, -132, 17, -59, 100, +50, 71, 75, -64, -7, -161, -120, -115, +-134, 47, -6, 211, 137, 277, 141, 161, +-6, -77, -224, -272, -332, -309, -195, -169, +75, 88, 269, 276, 276, 267, 96, 112, +-149, -75, -271, -173, -207, -118, -75, 25, +40, 91, 88, 48, 23, -65, -49, -140, +-36, -101, 11, 60, 71, 166, 103, 171, +9, 86, -143, -7, -229, -61, -201, -53, +-53, -95, 157, -165, 242, -163, 140, -2, +-19, 229, -142, 378, -156, 257, -54, -81, +-2, -371, -52, -361, -78, -78, -39, 244, +49, 322, 143, 88, 122, -207, -30, -267, +-140, -39, -144, 256, -85, 357, 6, 132, +40, -202, -35, -360, -69, -215, -19, 54, +50, 230, 96, 139, 46, -66, -117, -142, +-197, 18, -108, 228, 45, 288, 128, 59, +66, -290, -120, -465, -230, -281, -140, 99, +46, 432, 202, 472, 225, 205, 38, -155, +-205, -350, -298, -314, -199, -107, 37, 116, +227, 207, 180, 150, -46, 34, -197, -58, +-147, -82, 41, -23, 213, 18, 170, 20, +-72, 2, -252, 28, -241, 74, -77, 102, +135, 3, 226, -184, 128, -293, -10, -162, +-83, 152, -101, 435, -56, 406, 3, 50, +-19, -349, -69, -456, -66, -223, -29, 131, +56, 293, 147, 160, 99, -60, -43, -111, +-128, 40, -125, 206, -35, 195, 54, -28, +-10, -270, -172, -320, -199, -147, -36, 85, +213, 221, 367, 191, 201, 84, -200, 15, +-444, 26, -360, 38, -60, -9, 227, -129, +243, -246, 21, -237, -120, -46, -44, 214, +88, 371, 120, 303, -28, 45, -249, -205, +-263, -281, -32, -170, 173, -8, 213, 74, +87, 35, -95, -28, -147, -10, -49, 88, +45, 167, 91, 171, 84, 74, -5, -72, +-125, -199, -180, -238, -136, -180, 19, -7, +220, 181, 268, 269, 109, 197, -88, 27, +-196, -107, -158, -108, -18, -35, 44, -30, +-26, -124, -84, -191, -32, -76, 94, 193, +201, 397, 171, 305, -22, -38, -205, -353, +-227, -350, -134, -63, -5, 218, 61, 222, +14, -13, -28, -231, 28, -159, 119, 120, +142, 319, 40, 223, -167, -72, -319, -300, +-257, -235, -34, 21, 173, 199, 240, 140, +129, -61, -49, -189, -122, -79, -82, 175, +-15, 306, 25, 180, -5, -111, -82, -347, +-106, -338, -46, -84, 46, 184, 140, 290, +187, 204, 117, 32, -23, -86, -134, -83, +-174, -50, -122, -49, -7, -75, 78, -67, +106, 13, 119, 141, 115, 178, 53, 70, +-42, -121, -128, -244, -160, -168, -69, 84, +101, 311, 187, 311, 125, 54, -54, -285, +-225, -445, -223, -279, -10, 100, 216, 402, +267, 413, 105, 152, -152, -160, -282, -294, +-176, -196, 15, -27, 96, 65, 46, 32, +-49, -34, -72, -18, 38, 92, 141, 182, +89, 154, -61, 4, -206, -169, -254, -241, +-127, -148, 74, 44, 183, 190, 181, 193, +98, 41, -33, -144, -94, -190, -79, -39, +-84, 165, -84, 235, -39, 80, 14, -170, +88, -285, 147, -150, 110, 75, 20, 198, +-29, 146, -51, 24, -43, -15, -10, 48, +-11, 53, -24, -71, 20, -220, 76, -223, +98, -22, 88, 231, 18, 295, -70, 119, +-71, -117, -17, -205, 19, -95, 40, 70, +34, 103, 10, -29, 5, -144, -14, -115, +-70, 64, -84, 244, -14, 262, 67, 78, +105, -178, 60, -341, -70, -290, -161, -52, +-130, 231, -30, 364, 55, 265, 76, -8, +13, -263, -57, -320, -39, -155, 33, 92, +57, 234, -6, 191, -127, 20, -194, -114, +-112, -125, 77, -36, 205, 47, 195, 61, +54, 13, -116, -31, -175, -37, -82, -3, +53, 24, 125, 34, 83, 16, -45, -9, +-130, -30, -65, -19, 97, -5, 226, 14, +196, 33, 12, 24, -155, 0, -144, 6, +-2, 23, 107, 28, 88, 0, -24, -73, +-81, -125, 14, -84, 157, 33, 172, 143, +55, 168, -88, 70, -149, -60, -82, -124, +14, -99, 25, -45, -18, 3, -26, 7, +33, 17, 110, 74, 122, 127, 24, 90, +-121, -14, -204, -139, -188, -173, -101, -77, +31, 61, 131, 126, 152, 100, 103, 8, +12, -67, -90, -55, -124, -6, -99, 19, +-72, 17, -57, 0, -37, -8, -6, 25, +73, 46, 161, 35, 149, -8, 49, -71, +-71, -122, -151, -95, -113, 6, 23, 150, +107, 244, 83, 181, -7, -37, -78, -271, +-20, -350, 159, -179, 274, 136, 196, 356, +-27, 330, -259, 96, -305, -173, -107, -294, +165, -219, 312, -52, 285, 96, 115, 169, +-81, 165, -168, 98, -147, 0, -77, -113, +13, -174, 63, -142, 63, -29, 67, 86, +73, 149, 22, 128, -39, 45, -76, -50, +-82, -106, -25, -106, 42, -44, 31, 42, +-27, 88, -82, 47, -117, -54, -97, -113, +-3, -70, 100, 67, 163, 185, 149, 172, +7, 21, -186, -149, -274, -233, -212, -157, +-33, 2, 172, 131, 254, 158, 183, 117, +56, 39, -60, -5, -143, -31, -138, -82, +-84, -142, 0, -133, 120, -34, 206, 121, +180, 201, 89, 107, -23, -87, -98, -182, +-76, -80, 6, 137, 56, 243, 78, 82, +77, -212, 53, -342, 36, -173, 47, 139, +38, 313, 25, 184, 25, -59, -5, -131, +-36, 18, -40, 161, -37, 66, -7, -267, +69, -476, 99, -258, 63, 268, -15, 668, +-105, 580, -137, 30, -53, -530, 58, -656, +87, -304, 43, 176, -38, 414, -97, 279, +-70, -14, -29, -159, -28, -72, -19, 105, +12, 155, 44, 2, 52, -219, 6, -297, +-81, -155, -109, 108, -42, 296, 53, 272, +126, 75, 119, -112, 6, -152, -106, -57, +-118, 34, -39, -3, 83, -143, 173, -235, +153, -127, 43, 172, -55, 430, -73, 400, +-12, 74, 89, -324, 141, -484, 109, -296, +32, 66, -44, 275, -67, 207, -12, -6, +84, -108, 144, 15, 126, 200, 34, 183, +-76, -72, -109, -363, -32, -393, 76, -86, +128, 312, 73, 462, -50, 243, -125, -154, +-80, -387, 27, -266, 101, 70, 71, 324, +-42, 281, -143, -4, -138, -293, -38, -335, +70, -120, 118, 185, 81, 333, -6, 224, +-79, -47, -114, -229, -134, -205, -122, -17, +-56, 133, 64, 113, 188, -47, 229, -148, +111, -89, -101, 99, -257, 230, -218, 160, +-15, -63, 187, -229, 226, -210, 100, -39, +-37, 122, -55, 137, 27, 41, 95, -41, +65, -33, -39, 24, -96, 56, -33, 16, +108, -44, 206, -69, 185, -42, 53, -12, +-70, 7, -74, 8, 10, 39, 65, 74, +40, 68, -37, -7, -71, -82, 7, -103, +134, -38, 181, 34, 119, 43, -11, -7, +-128, -36, -154, -1, -99, 77, -41, 91, +25, -5, 85, -108, 87, -99, 59, 27, +20, 151, -49, 116, -109, -93, -134, -270, +-137, -231, -71, 39, 66, 345, 160, 409, +142, 132, 35, -257, -112, -456, -177, -300, +-82, 76, 49, 351, 78, 303, 8, 29, +-95, -219, -88, -238, 80, -27, 238, 184, +217, 189, 59, 26, -121, -138, -192, -171, +-100, -53, 19, 62, 63, 48, 100, -41, +161, -57, 187, 49, 170, 204, 65, 229, +-114, 40, -214, -233, -148, -367, 2, -238, +172, 76, 270, 323, 209, 300, 49, 54, +-86, -199, -160, -247, -127, -54, -2, 188, +88, 239, 92, 48, 48, -232, -32, -340, +-73, -176, -12, 137, 59, 342, 71, 290, +32, 41, -58, -168, -138, -187, -118, -54, +-56, 48, -22, -5, 15, -169, 48, -216, +73, -31, 105, 286, 62, 468, -65, 305, +-158, -125, -164, -471, -99, -469, 22, -145, +114, 223, 131, 337, 114, 163, 73, -59, +-21, -93, -102, 37, -115, 148, -50, 54, +74, -167, 166, -291, 133, -167, 27, 75, +-45, 236, -42, 178, 36, -3, 115, -108, +107, -29, 37, 111, -13, 153, -23, 10, +-7, -215, 21, -337, 26, -218, 39, 68, +86, 349, 124, 413, 115, 199, 46, -146, +-67, -373, -151, -324, -146, -53, -54, 205, +58, 230, 126, 48, 105, -143, 45, -150, +0, 28, -14, 210, -28, 201, -72, 22, +-122, -179, -126, -223, -67, -115, 26, 24, +99, 73, 106, 53, 61, 29, 6, 70, +-53, 122, -99, 96, -99, -42, -61, -196, +-10, -246, 29, -131, 40, 77, 42, 229, +84, 219, 126, 79, 94, -73, -12, -133, +-133, -92, -187, -42, -107, -41, 48, -59, +177, -18, 240, 100, 204, 216, 80, 190, +-50, -1, -127, -229, -131, -310, -45, -173, +70, 88, 128, 263, 133, 235, 88, 68, +9, -92, -28, -136, 0, -78, 34, -11, +56, -10, 36, -50, -39, -71, -77, -15, +-33, 92, 34, 184, 78, 175, 64, 51, +-10, -138, -59, -252, -38, -213, -8, -32, +-5, 160, -11, 220, -36, 113, -26, -47, +32, -122, 41, -56, -6, 57, -47, 75, +-68, -38, -44, -155, 20, -147, 47, -6, +24, 172, -2, 221, -28, 102, -49, -70, +-32, -146, -2, -113, 31, -8, 76, 39, +88, 9, 45, -32, 5, -6, -27, 56, +-48, 123, -31, 92, 16, -34, 53, -157, +90, -175, 95, -86, 48, 71, 11, 168, +15, 135, 38, 27, 60, -62, 46, -81, +-31, -25, -86, 19, -70, -11, 7, -62, +115, -60, 184, 14, 141, 102, 20, 129, +-95, 34, -142, -84, -94, -141, 9, -88, +56, 25, 51, 121, 28, 117, 16, 24, +20, -91, 14, -139, -28, -95, -57, 29, +-48, 142, -29, 167, -10, 71, -8, -73, +-27, -168, -26, -142, 15, -30, 67, 65, +98, 84, 74, 42, -12, 3, -114, 10, +-164, 52, -134, 53, -18, -7, 116, -91, +181, -132, 155, -96, 80, 17, -4, 120, +-56, 154, -73, 94, -81, -16, -62, -115, +-5, -120, 65, -50, 128, 31, 155, 62, +112, 28, 46, -38, -9, -44, -53, 16, +-66, 81, -42, 92, -22, 25, 5, -76, +38, -116, 61, -69, 103, 1, 145, 53, +119, 43, 12, 8, -126, 1, -229, 44, +-211, 71, -52, 36, 127, -71, 219, -166, +207, -160, 93, -16, -55, 159, -134, 238, +-156, 151, -140, -40, -73, -186, -9, -171, +43, -46, 111, 74, 144, 81, 103, -9, +12, -75, -92, -39, -150, 69, -96, 145, +6, 116, 46, -11, 40, -133, 18, -176, +16, -124, 66, -21, 116, 76, 80, 129, +-11, 144, -85, 96, -106, 13, -47, -76, +58, -136, 108, -151, 103, -98, 81, -6, +29, 107, -10, 187, -7, 170, -4, 38, +4, -127, 28, -213, 18, -148, -17, 30, +-22, 157, 7, 145, 56, 31, 126, -75, +119, -89, 10, -16, -110, 25, -158, -7, +-112, -46, 23, -15, 118, 75, 101, 131, +37, 47, -28, -115, -66, -201, -41, -101, +-2, 101, -2, 230, -9, 152, -12, -64, +-23, -217, -22, -172, -9, 13, -17, 170, +0, 174, 38, 40, 46, -97, 25, -135, +-9, -78, -58, -10, -70, 41, -29, 66, +26, 81, 73, 72, 98, 23, 74, -82, +31, -157, -4, -125, -41, 11, -55, 152, +-13, 183, 42, 69, 78, -97, 98, -185, +70, -138, 19, -1, 6, 112, 17, 125, +19, 49, 12, -23, -21, -47, -28, -35, +24, -15, 84, -12, 87, -24, 41, -8, +-29, 17, -71, 36, -42, 30, 11, 8, +34, -6, 31, 7, 9, 19, -20, 3, +-19, -31, -1, -62, 10, -63, -6, -17, +-44, 35, -89, 64, -77, 74, 3, 62, +105, 31, 145, -14, 59, -65, -119, -105, +-231, -97, -172, -49, 22, 27, 209, 95, +224, 126, 47, 89, -167, 26, -231, -44, +-98, -83, 111, -87, 202, -64, 115, -36, +-29, 13, -82, 67, -34, 103, 42, 88, +46, 16, -14, -77, -22, -113, 71, -58, +174, 47, 174, 101, 29, 39, -168, -93, +-234, -174, -99, -100, 147, 78, 335, 235, +314, 231, 77, 65, -188, -162, -292, -278, +-188, -226, 43, -37, 214, 154, 205, 239, +71, 175, -59, 34, -104, -104, -44, -159, +30, -120, 29, -24, -26, 47, -65, 68, +-55, 43, 18, 6, 79, -13, 41, -12, +-57, -8, -104, -2, -68, 20, 27, 36, +102, 31, 57, -12, -68, -74, -163, -113, +-149, -76, -13, 8, 158, 113, 202, 171, +104, 132, -58, 0, -180, -143, -188, -224, +-70, -161, 75, 7, 159, 170, 148, 215, +69, 123, -19, -33, -51, -135, -28, -127, +10, -62, 34, -1, 17, 33, 10, 40, +54, 55, 109, 77, 97, 42, 24, -52, +-57, -141, -67, -144, 18, -48, 132, 99, +146, 183, 57, 150, -66, 34, -121, -89, +-65, -163, 56, -148, 132, -68, 103, 33, +16, 109, -61, 131, -61, 94, -8, 30, +17, -29, -29, -65, -71, -84, -53, -95, +33, -86, 113, -29, 100, 70, -21, 154, +-148, 168, -171, 75, -76, -66, 49, -162, +112, -148, 76, -48, -9, 54, -82, 76, +-114, 27, -68, -28, 21, -12, 85, 54, +74, 102, 8, 69, -58, -51, -69, -162, +-35, -157, 12, -30, 40, 117, 57, 165, +61, 72, 50, -69, 30, -125, -6, -35, +-32, 88, -16, 119, 19, 5, 50, -151, +76, -185, 79, -44, 57, 136, 3, 205, +-41, 93, -41, -88, 39, -168, 135, -68, +138, 90, 28, 139, -102, 30, -147, -134, +-49, -189, 111, -63, 190, 128, 145, 216, +13, 140, -106, -40, -134, -169, -72, -159, +-14, -51, 8, 50, 24, 86, 71, 47, +103, 8, 83, 0, -21, 22, -150, 22, +-207, -4, -143, -58, 24, -83, 177, -47, +187, 41, 29, 100, -148, 81, -213, -19, +-118, -120, 56, -118, 169, 12, 122, 167, +-21, 199, -150, 54, -153, -181, -29, -301, +107, -192, 141, 83, 66, 300, -33, 288, +-71, 64, -13, -177, 55, -251, 51, -128, +-18, 32, -41, 93, 25, 33, 136, -25, +145, 2, 24, 83, -126, 103, -133, 7, +20, -127, 195, -160, 216, -51, 83, 101, +-84, 158, -173, 66, -130, -79, -2, -146, +133, -77, 201, 49, 182, 128, 66, 104, +-76, 17, -183, -69, -189, -102, -88, -88, +77, -43, 162, 17, 146, 81, 78, 108, +-4, 86, -75, 16, -109, -63, -115, -101, +-81, -84, -5, -35, 45, 19, 66, 56, +54, 65, 8, 53, -55, 27, -50, -18, +-17, -65, 15, -76, 18, -41, -37, 28, +-113, 67, -112, 55, -37, -7, 89, -45, +202, -29, 197, 28, 51, 58, -123, 14, +-227, -78, -215, -116, -62, -53, 122, 71, +223, 155, 210, 121, 113, -18, -17, -150, +-67, -174, -71, -78, -96, 71, -96, 154, +-13, 129, 108, 28, 209, -74, 196, -115, +48, -70, -90, 3, -124, 55, -70, 49, +35, 6, 113, -32, 65, -29, -13, -8, +-34, 21, -5, 28, 43, 26, 76, 22, +41, 8, -19, -33, -53, -84, -61, -97, +-29, -27, 31, 94, 45, 175, 5, 132, +-8, -15, -17, -154, -8, -188, 17, -92, +16, 46, -30, 122, -37, 88, -36, 26, +-34, -11, -4, -9, 16, -7, 11, -28, +22, -60, 27, -46, -5, 6, -27, 56, +-46, 44, -48, -13, -20, -43, 25, -1, +42, 75, 59, 95, 39, 2, -17, -149, +-58, -208, -36, -96, 13, 122, 51, 272, +54, 220, 44, -9, 35, -224, 8, -263, +-51, -103, -79, 99, -20, 191, 64, 128, +125, 15, 108, -47, 32, -46, -50, -46, +-62, -73, -21, -89, 19, -22, 4, 99, +-19, 168, 3, 111, 87, -40, 158, -153, +130, -128, -7, 0, -182, 97, -251, 77, +-143, -21, 99, -76, 284, -28, 266, 77, +51, 108, -172, 38, -257, -80, -136, -129, +48, -72, 145, 30, 96, 79, -4, 53, +-58, 1, -21, -7, 39, 21, 13, 45, +-80, 12, -124, -51, -41, -91, 102, -76, +178, -11, 82, 54, -83, 86, -185, 86, +-159, 65, -25, 6, 150, -74, 204, -147, +98, -149, -67, -60, -146, 94, -99, 201, +15, 182, 78, 40, 45, -112, -4, -180, +-20, -129, 19, -24, 85, 58, 101, 75, +7, 56, -97, 31, -135, 18, -63, 14, +77, 4, 188, -24, 155, -62, 16, -96, +-126, -94, -144, -25, -7, 93, 148, 192, +154, 180, 17, 34, -121, -159, -152, -243, +-28, -149, 140, 43, 212, 165, 117, 137, +-52, -3, -179, -91, -156, -43, -7, 67, +129, 97, 128, 4, 31, -127, -51, -158, +-36, -44, 34, 122, 50, 178, -15, 77, +-110, -75, -129, -146, -33, -71, 137, 62, +209, 130, 97, 69, -100, -62, -201, -150, +-153, -118, -12, 4, 97, 128, 116, 152, +73, 75, 8, -42, -46, -109, -63, -85, +-48, -9, -32, 29, -4, -1, 20, -53, +29, -49, 25, 43, 48, 151, 60, 160, +28, 28, -50, -157, -109, -256, -96, -169, +5, 42, 107, 220, 146, 216, 115, 54, +21, -128, -77, -164, -116, -41, -70, 111, +16, 125, 87, -5, 89, -165, 49, -185, +13, -33, 12, 170, 12, 235, 11, 118, +-4, -77, -33, -176, -52, -111, -6, 4, +81, 43, 123, -11, 81, -60, -28, -17, +-94, 109, -72, 186, -4, 127, 41, -44, +71, -195, 48, -229, -13, -119, -50, 48, +-31, 178, 1, 191, 19, 95, 2, -56, +-21, -146, 4, -113, 36, 21, 15, 124, +-42, 86, -88, -75, -85, -201, 2, -143, +106, 73, 120, 263, 35, 245, -67, 31, +-142, -196, -116, -245, -14, -110, 84, 57, +116, 109, 73, 48, -28, -29, -85, -19, +-48, 56, 5, 117, 24, 85, 28, -23, +25, -146, 18, -192, 23, -132, -7, 17, +-28, 168, 12, 223, 62, 130, 50, -43, +17, -157, -13, -134, -11, -23, 17, 56, +32, 33, 4, -41, -7, -60, 15, 17, +42, 121, 89, 127, 91, 23, 6, -108, +-85, -142, -91, -60, -45, 50, 29, 79, +70, 17, 77, -67, 64, -53, 57, 46, +12, 135, -62, 110, -116, -29, -121, -176, +-50, -193, 65, -52, 131, 123, 106, 200, +45, 119, -39, -36, -115, -128, -132, -100, +-70, -21, -6, 37, 37, 42, 42, 23, +31, 17, 57, 12, 81, -25, 7, -61, +-122, -42, -176, 27, -113, 76, 35, 51, +148, -35, 144, -94, 66, -44, -10, 68, +-78, 106, -111, 24, -77, -99, -12, -127, +54, -16, 138, 118, 150, 139, 65, 16, +-49, -122, -139, -143, -127, -37, -2, 94, +118, 133, 145, 63, 122, -29, 55, -84, +-40, -73, -94, -36, -89, 18, -61, 51, +39, 52, 139, 19, 147, -22, 72, -25, +-30, 16, -113, 53, -93, 17, -9, -72, +32, -131, 43, -68, 37, 77, 17, 176, +1, 125, 19, -27, -2, -127, -38, -77, +-57, 36, -61, 63, -38, -44, 25, -155, +58, -109, 50, 98, 24, 274, -43, 238, +-99, -6, -78, -242, -11, -276, 40, -117, +58, 67, -2, 140, -52, 103, -19, 58, +36, 58, 7, 58, -42, -11, -49, -130, +-1, -181, 62, -108, 60, 40, -5, 140, +-45, 131, -21, 55, 19, 4, 39, -3, +14, -21, -22, -79, -11, -130, 59, -105, +83, 36, 35, 182, -32, 192, -58, 47, +-14, -136, 59, -201, 72, -79, 34, 102, +0, 162, 0, 48, 25, -119, 33, -160, +-14, -22, -44, 159, 0, 174, 60, 6, +66, -175, 12, -175, -48, 6, -58, 185, +-8, 154, 36, -45, 49, -196, 41, -137, +6, 74, -64, 207, -100, 108, -61, -105, +37, -190, 104, -55, 69, 138, -23, 157, +-78, -28, -62, -211, -22, -172, 2, 66, +1, 255, 5, 202, 17, -43, 39, -238, +33, -187, -29, 27, -121, 165, -123, 87, +-4, -83, 151, -137, 189, 14, 56, 215, +-129, 222, -182, -24, -60, -317, 88, -365, +107, -79, 5, 308, -61, 445, 18, 187, +141, -217, 136, -385, -8, -176, -175, 185, +-204, 307, -55, 43, 145, -309, 229, -319, +165, 73, 9, 499, -103, 470, -83, -52, +-15, -589, -5, -601, -39, -65, -53, 507, +15, 558, 142, 80, 203, -402, 100, -371, +-73, 101, -180, 454, -186, 258, -68, -316, +85, -658, 153, -354, 96, 354, -22, 775, +-94, 500, -31, -195, 93, -650, 79, -468, +-66, 97, -184, 420, -156, 207, 10, -233, +175, -346, 172, 8, 40, 466, -78, 485, +-109, -16, -67, -556, 4, -594, 15, -125, +-22, 403, -22, 526, 7, 164, 41, -261, +69, -338, 55, -69, -7, 230, -37, 279, +-45, 19, -78, -291, -72, -342, 7, -100, +106, 232, 160, 404, 95, 268, -68, -91, +-141, -369, -53, -334, 63, -36, 85, 285, +32, 327, -52, 44, -36, -278, 62, -292, +104, -8, 42, 307, -55, 324, -115, -13, +-66, -351, 87, -336, 178, 17, 98, 359, +-63, 356, -165, -37, -113, -407, 60, -375, +144, 30, 77, 416, -23, 429, -62, 34, +-45, -385, 21, -419, 49, -79, -6, 272, +-55, 322, -63, 44, -43, -236, 46, -200, +134, 91, 94, 282, -49, 176, -164, -155, +-176, -390, -31, -241, 163, 154, 170, 406, +24, 292, -118, -63, -145, -369, -33, -310, +118, 26, 107, 295, -47, 277, -133, 26, +-67, -251, 84, -293, 182, -50, 68, 214, +-134, 275, -188, 114, -69, -166, 93, -314, +181, -146, 131, 164, -12, 315, -92, 201, +-110, -125, -110, -373, -13, -254, 126, 114, +165, 363, 96, 299, -36, -28, -149, -343, +-108, -315, 72, -10, 152, 238, 82, 246, +-69, 65, -174, -151, -80, -184, 169, -38, +252, 82, 67, 87, -187, 47, -274, -24, +-101, -65, 207, -36, 294, -11, 84, 9, +-156, 76, -234, 88, -122, -1, 74, -99, +182, -147, 115, -80, 5, 104, -85, 219, +-127, 107, -55, -94, 68, -210, 71, -131, +-6, 89, -89, 220, -97, 84, 26, -160, +181, -221, 153, -48, -47, 219, -222, 318, +-244, 89, -47, -268, 211, -379, 255, -164, +48, 192, -160, 419, -186, 277, -34, -113, +134, -381, 134, -319, -33, -4, -109, 321, +-47, 356, 39, 52, 48, -279, 9, -325, +-18, -67, 16, 252, 66, 328, 21, 67, +-65, -253, -53, -303, 35, -70, 89, 211, +52, 284, -77, 88, -148, -183, -38, -261, +192, -103, 256, 127, 117, 253, -170, 164, +-338, -65, -199, -264, 141, -248, 313, -13, +173, 267, -102, 334, -237, 100, -80, -246, +192, -366, 241, -126, -9, 223, -283, 346, +-358, 111, -104, -231, 276, -321, 450, -51, +229, 268, -145, 305, -392, 34, -326, -269, +14, -312, 281, -79, 225, 207, -40, 272, +-214, 116, -136, -90, 121, -191, 269, -146, +113, 2, -188, 116, -317, 145, -201, 85, +93, -66, 286, -183, 234, -155, 0, 32, +-184, 230, -182, 254, -22, 23, 135, -266, +132, -332, -21, -71, -157, 289, -146, 399, +36, 103, 219, -354, 214, -498, 51, -144, +-135, 404, -173, 632, -82, 287, 47, -392, +55, -764, 14, -468, 17, 230, 83, 726, +140, 603, 94, -30, -73, -572, -182, -542, +-154, -49, -36, 392, 80, 394, 137, -12, +110, -391, 35, -321, -3, 127, -66, 475, +-73, 380, -25, -74, -7, -496, -44, -488, +-45, -55, -10, 374, 65, 425, 160, 153, +99, -186, -80, -299, -151, -123, -95, 113, +-12, 167, 50, 70, -2, -59, -86, -153, +-17, -133, 152, 6, 179, 159, 63, 216, +-133, 163, -310, -64, -215, -321, 90, -310, +277, -11, 234, 315, 28, 384, -196, 91, +-227, -360, 12, -471, 165, -96, 120, 394, +-1, 536, -120, 193, -108, -369, 67, -633, +155, -289, 47, 281, -72, 556, -120, 335, +-74, -143, 111, -483, 234, -274, 102, 218, +-62, 443, -205, 189, -240, -322, -84, -621, +205, -314, 321, 416, 243, 819, 19, 531, +-290, -241, -369, -851, -124, -779, 166, -8, +275, 704, 194, 757, -58, 202, -212, -427, +-111, -651, 83, -254, 125, 324, 81, 499, +-109, 209, -267, -237, -154, -497, 151, -304, +351, 222, 266, 552, -75, 414, -435, -69, +-380, -540, 38, -617, 355, -116, 312, 512, +15, 696, -269, 291, -248, -336, -6, -727, +167, -464, 130, 226, 49, 675, -72, 503, +-129, -74, -80, -602, 5, -587, 94, 7, +180, 588, 119, 602, -96, 71, -248, -549, +-161, -716, 81, -176, 297, 581, 247, 814, +-100, 269, -336, -544, -231, -934, 140, -464, +390, 514, 306, 1052, -112, 629, -442, -364, +-349, -1073, 58, -855, 401, 151, 420, 1003, +81, 936, -316, 81, -414, -797, -155, -911, +214, -212, 371, 631, 220, 791, -154, 216, +-347, -549, -231, -754, 76, -212, 312, 541, +295, 779, 21, 279, -281, -464, -343, -832, +-145, -409, 181, 349, 386, 764, 228, 484, +-159, -170, -414, -685, -300, -551, 106, 95, +469, 589, 408, 575, -66, 86, -516, -491, +-545, -680, -113, -263, 486, 304, 684, 588, +277, 442, -361, -20, -675, -447, -381, -447, +248, -107, 663, 185, 390, 306, -238, 195, +-654, -99, -431, -258, 238, -150, 753, 44, +574, 240, -115, 337, -712, 110, -709, -295, +-118, -519, 543, -403, 702, 75, 285, 623, +-245, 739, -530, 220, -308, -457, 134, -780, +405, -486, 232, 193, -141, 655, -431, 490, +-308, -76, 193, -467, 575, -399, 454, 90, +-51, 478, -553, 388, -648, -112, -193, -536, +387, -548, 618, -51, 369, 532, -101, 695, +-510, 319, -450, -323, -31, -740, 366, -586, +411, 59, 96, 635, -323, 719, -435, 216, +-130, -481, 268, -802, 409, -404, 227, 332, +-165, 794, -401, 568, -263, -182, 78, -815, +332, -698, 265, 53, -56, 741, -345, 795, +-252, 124, 88, -648, 363, -819, 322, -261, +-23, 475, -387, 781, -385, 388, -73, -311, +287, -674, 405, -453, 197, 121, -179, 541, +-357, 490, -172, 35, 131, -377, 320, -450, +190, -198, -111, 183, -314, 383, -212, 279, +57, -26, 272, -233, 292, -322, 116, -154, +-135, 147, -280, 323, -236, 237, -38, -20, +177, -292, 238, -357, 120, -51, -99, 270, +-174, 356, -60, 132, 138, -175, 189, -353, +6, -180, -264, 143, -366, 286, -78, 168, +334, -60, 491, -247, 219, -239, -256, -5, +-524, 231, -316, 294, 167, 185, 421, -110, +259, -380, -126, -391, -351, -103, -214, 276, +174, 500, 363, 375, 219, -64, -153, -416, +-402, -478, -324, -178, 77, 166, 415, 383, +383, 239, 55, 2, -343, -145, -418, -119, +-110, -38, 292, 29, 373, -4, 142, -88, +-225, -22, -375, 44, -152, 95, 230, 89, +347, 78, 165, -6, -160, -43, -368, -115, +-215, -184, 164, -115, 393, 114, 248, 271, +-72, 216, -391, 5, -370, -246, 17, -306, +382, -52, 382, 224, 112, 259, -239, 97, +-403, -155, -194, -307, 166, -170, 321, 115, +226, 280, -40, 253, -321, 28, -284, -248, +51, -333, 345, -141, 321, 135, 21, 294, +-378, 218, -456, -28, -84, -214, 360, -181, +479, -34, 220, 113, -268, 139, -528, 32, +-298, -82, 195, -70, 471, -44, 354, 25, +-97, 108, -506, 73, -382, -39, 109, -82, +473, -94, 399, -70, -43, 99, -524, 158, +-495, 65, 31, -27, 517, -49, 548, -94, +141, -40, -473, 27, -680, -53, -230, -64, +385, 90, 625, 195, 357, 153, -183, 26, +-571, -237, -369, -383, 101, -131, 389, 231, +328, 398, 23, 270, -326, -92, -330, -432, +-2, -346, 287, 83, 325, 402, 109, 375, +-237, -41, -395, -449, -167, -496, 146, -18, +336, 499, 288, 634, 13, 211, -315, -454, +-362, -752, -120, -436, 215, 291, 446, 777, +263, 677, -229, -74, -538, -706, -355, -770, +154, -219, 590, 517, 510, 855, -74, 453, +-566, -336, -526, -773, -71, -666, 418, 8, +557, 710, 149, 846, -351, 191, -478, -579, +-172, -872, 257, -464, 485, 441, 225, 1009, +-288, 627, -492, -353, -270, -987, 179, -837, +498, 72, 430, 1020, -45, 1050, -459, 145, +-490, -853, -145, -1134, 317, -528, 554, 589, +303, 1212, -201, 762, -501, -299, -367, -1068, +83, -961, 445, -59, 397, 944, -48, 1063, +-424, 270, -391, -690, 38, -1019, 445, -483, +451, 484, 7, 982, -490, 534, -553, -357, +-77, -907, 500, -637, 641, 228, 202, 931, +-416, 780, -651, -70, -284, -839, 315, -919, +567, -232, 288, 640, -235, 950, -501, 461, +-263, -323, 236, -772, 497, -585, 282, 61, +-225, 567, -524, 535, -344, 76, 162, -394, +492, -527, 379, -204, -75, 298, -414, 542, +-322, 355, 69, -88, 327, -490, 226, -526, +-97, -177, -344, 278, -235, 493, 129, 377, +386, 12, 292, -320, -23, -371, -362, -154, +-413, 147, -97, 243, 296, 119, 378, -134, +149, -200, -181, -62, -335, 221, -127, 300, +220, 80, 318, -227, 72, -351, -235, -185, +-379, 92, -176, 306, 228, 198, 449, 21, +274, -78, -107, -71, -403, -96, -380, -89, +1, -67, 385, -16, 419, 176, 74, 239, +-348, 52, -502, -225, -165, -270, 381, -136, +619, 178, 322, 408, -288, 211, -696, -210, +-517, -433, 165, -278, 667, 76, 584, 449, +-14, 403, -567, -43, -578, -405, -4, -384, +531, -59, 503, 293, 20, 423, -496, 132, +-583, -234, -132, -348, 458, -180, 592, 97, +272, 293, -241, 246, -539, -33, -405, -221, +72, -237, 382, -36, 311, 176, 36, 230, +-244, 78, -281, -154, -22, -245, 264, -108, +259, 161, 33, 219, -247, 114, -360, -103, +-163, -212, 205, -105, 374, 127, 240, 177, +-49, 3, -272, -107, -252, -106, -35, 27, +134, 144, 132, 111, 48, -134, -32, -204, +-58, -4, -23, 202, 7, 233, 52, 43, +63, -271, -11, -376, -93, -57, -77, 325, +25, 417, 76, 171, 61, -217, -44, -468, +-91, -313, 44, 117, 189, 401, 98, 346, +-118, 68, -276, -276, -221, -434, 88, -202, +388, 200, 319, 439, -57, 335, -338, -65, +-350, -492, -48, -504, 313, -49, 352, 497, +13, 621, -287, 193, -302, -424, -60, -705, +273, -343, 373, 327, 97, 740, -286, 449, +-416, -233, -222, -727, 173, -578, 475, 82, +388, 735, -79, 769, -465, 87, -491, -655, +-121, -874, 371, -398, 563, 420, 286, 970, +-215, 685, -522, -143, -418, -810, 14, -879, +420, -260, 477, 599, 141, 961, -268, 478, +-438, -337, -216, -838, 163, -660, 366, 138, +250, 814, -84, 724, -354, -63, -312, -759, +44, -834, 381, -125, 447, 782, 113, 1009, +-362, 337, -576, -649, -297, -1085, 249, -682, +570, 344, 441, 1043, -39, 895, -462, 41, +-490, -779, -106, -957, 293, -363, 438, 523, +211, 891, -165, 556, -430, -291, -319, -873, +78, -721, 383, 115, 417, 850, 127, 886, +-307, 168, -534, -782, -330, -1026, 98, -406, +478, 559, 521, 993, 132, 623, -409, -325, +-576, -930, -249, -651, 280, 163, 593, 791, +361, 696, -274, -17, -678, -752, -455, -753, +203, -134, 752, 593, 685, 823, -35, 383, +-763, -376, -840, -788, -210, -563, 572, 74, +873, 676, 440, 713, -350, 150, -760, -509, +-531, -738, 105, -372, 634, 353, 612, 791, +45, 520, -518, -181, -635, -714, -223, -699, +394, -73, 704, 625, 396, 744, -247, 254, +-657, -371, -544, -669, 44, -429, 611, 193, +634, 554, 81, 392, -534, -60, -665, -408, +-175, -429, 511, -19, 717, 435, 216, 433, +-524, 92, -782, -347, -309, -533, 458, -300, +809, 251, 440, 562, -321, 454, -773, 29, +-538, -435, 126, -586, 612, -310, 546, 214, +23, 530, -469, 492, -473, 72, -54, -402, +332, -554, 361, -242, 67, 259, -271, 526, +-326, 349, -64, -169, 235, -499, 273, -431, +101, 0, -137, 472, -233, 550, -101, 197, +105, -297, 157, -565, 34, -480, -88, 36, +-110, 496, -9, 549, 134, 192, 154, -287, +11, -520, -118, -313, -135, 247, -55, 497, +43, 284, 69, -223, 35, -565, -14, -475, +34, 165, 101, 735, 78, 642, -53, 68, +-191, -595, -209, -803, -67, -385, 190, 394, +275, 738, 116, 459, -124, -128, -201, -563, +-127, -508, 72, 40, 174, 598, 52, 538, +-147, 26, -185, -569, -67, -782, 110, -319, +247, 520, 183, 950, -39, 591, -245, -165, +-234, -830, -109, -818, 93, -147, 245, 586, +191, 688, -3, 240, -141, -300, -180, -534, +-113, -223, 52, 290, 209, 482, 144, 187, +-36, -242, -159, -536, -211, -392, -47, 129, +250, 555, 286, 561, 16, 152, -262, -395, +-327, -664, -97, -366, 299, 202, 446, 558, +125, 471, -270, 5, -412, -438, -267, -469, +101, -92, 428, 250, 367, 388, 31, 237, +-259, -141, -377, -348, -192, -228, 181, 16, +340, 231, 163, 326, -129, 63, -274, -245, +-209, -310, 82, -120, 315, 140, 234, 355, +1, 274, -230, -79, -343, -346, -165, -317, +141, -92, 283, 194, 228, 389, 17, 220, +-188, -106, -241, -290, -65, -238, 97, -54, +163, 233, 124, 312, -71, 115, -240, -179, +-196, -349, 11, -281, 250, 21, 388, 404, +182, 493, -206, 167, -462, -310, -408, -529, +-49, -390, 382, 73, 529, 484, 258, 441, +-185, 58, -465, -286, -367, -344, 65, -142, +435, 202, 346, 318, -75, 102, -437, -235, +-424, -335, 62, -144, 528, 198, 563, 486, +95, 331, -476, -158, -694, -522, -369, -460, +295, -73, 689, 437, 527, 607, -29, 225, +-534, -276, -622, -519, -135, -369, 400, 38, +570, 440, 264, 420, -271, 68, -621, -286, +-401, -417, 226, -199, 627, 221, 533, 464, +-31, 245, -610, -159, -704, -472, -144, -400, +453, 51, 656, 479, 354, 508, -241, 133, +-599, -315, -395, -544, 134, -325, 457, 103, +341, 406, -92, 374, -439, 60, -332, -248, +158, -300, 454, -51, 324, 176, -69, 224, +-412, -28, -406, -252, -66, -231, 285, 20, +364, 258, 217, 308, -28, 105, -267, -183, +-290, -266, -101, -215, 113, -38, 237, 162, +186, 260, -13, 135, -159, -55, -137, -187, +-60, -174, 20, 6, 89, 197, 127, 163, +84, -29, -17, -120, -156, -123, -180, -81, +-37, 32, 132, 98, 169, 76, 71, 115, +-52, 76, -100, -84, -63, -193, -12, -124, +13, -22, 36, 93, 52, 158, 29, 105, +-64, -28, -127, -74, -75, -69, 94, -121, +247, 1, 164, 168, -103, 166, -331, -6, +-265, -168, 2, -284, 258, -102, 271, 269, +101, 383, -102, 164, -167, -198, -162, -381, +-55, -283, 94, 82, 153, 353, 72, 307, +-139, 6, -218, -259, -30, -314, 277, -134, +349, 237, 34, 411, -379, 243, -462, -198, +-108, -516, 347, -436, 460, 88, 166, 614, +-205, 618, -344, 30, -185, -612, 87, -680, +221, -150, 183, 548, -17, 710, -186, 183, +-222, -491, -33, -653, 206, -201, 309, 412, +91, 610, -196, 229, -321, -306, -210, -515, +80, -265, 290, 143, 312, 344, 91, 268, +-170, 42, -342, -147, -268, -240, 40, -186, +336, -9, 303, 170, 26, 283, -259, 150, +-290, -185, -48, -363, 203, -150, 255, 170, +18, 389, -210, 251, -218, -190, -69, -431, +163, -250, 268, 122, 141, 323, -128, 273, +-268, 0, -234, -187, 11, -190, 282, -40, +318, -14, 27, -24, -293, 68, -334, 137, +-92, 138, 261, 36, 376, -166, 159, -254, +-183, -2, -350, 237, -276, 208, 15, -105, +272, -373, 362, -236, 168, 239, -197, 621, +-373, 365, -227, -359, 123, -786, 353, -454, +243, 280, -114, 856, -386, 581, -239, -329, +152, -840, 386, -524, 291, 286, -72, 853, +-407, 591, -353, -314, 13, -884, 301, -608, +286, 240, 86, 832, -133, 643, -217, -142, +-86, -800, 69, -600, 74, 182, 45, 721, +12, 532, -69, -184, -83, -783, 18, -531, +74, 264, 79, 744, 38, 519, -37, -211, +-109, -683, -106, -445, -26, 196, 15, 529, +109, 292, 174, -225, 102, -382, -133, -111, +-285, 219, -205, 291, 91, 1, 332, -245, +310, -135, -69, 126, -414, 179, -330, -25, +39, -262, 382, -215, 408, 170, 35, 484, +-439, 344, -477, -250, -38, -677, 418, -521, +477, 196, 73, 867, -400, 739, -416, -187, +2, -1013, 332, -883, 255, 145, -49, 1171, +-244, 1022, -107, -216, 116, -1318, 167, -1085, +26, 316, -113, 1480, -141, 1116, -6, -471, +113, -1640, 80, -1142, -22, 607, -53, 1776, +2, 1145, 69, -672, 90, -1799, -85, -1124, +-233, 646, -127, 1709, 118, 1037, 270, -606, +241, -1522, -3, -889, -327, 547, -357, 1349, +-71, 760, 229, -504, 352, -1180, 227, -695, +-171, 440, -402, 1062, -210, 600, 131, -365, +309, -896, 207, -566, -82, 331, -315, 823, +-184, 419, 88, -327, 227, -683, 178, -402, +25, 274, -159, 676, -213, 336, -121, -253, +19, -492, 167, -310, 227, 87, 130, 455, +-108, 314, -269, -124, -230, -325, 13, -257, +261, -13, 292, 354, 46, 359, -251, -76, +-283, -387, -6, -377, 306, -31, 276, 450, +-74, 520, -357, 5, -262, -498, 93, -495, +365, -24, 292, 491, -49, 472, -294, -71, +-234, -529, -55, -376, 122, 201, 209, 602, +85, 371, -74, -293, -91, -666, -27, -420, +9, 226, 23, 684, -34, 505, -90, -150, +22, -562, 160, -453, 71, -5, -45, 442, +-125, 407, -130, -71, 5, -397, 167, -257, +104, 110, -69, 449, -161, 334, -124, -211, +70, -553, 280, -348, 196, 146, -160, 529, +-381, 446, -271, -113, 102, -509, 449, -363, +382, 104, -84, 448, -413, 360, -341, -158, +30, -534, 356, -365, 243, 178, -174, 608, +-336, 519, -54, -113, 320, -692, 377, -643, +17, -14, -438, 667, -403, 754, 56, 99, +338, -660, 257, -752, -21, -117, -213, 658, +-70, 782, 158, 66, 76, -731, -161, -746, +-201, -3, -23, 751, 175, 786, 185, -17, +-35, -782, -177, -705, -14, 18, 170, 658, +100, 672, -160, 37, -298, -584, -129, -535, +240, -52, 357, 384, 113, 466, -238, 158, +-323, -285, -61, -385, 220, -164, 207, 79, +-19, 256, -194, 253, -158, 29, 49, -180, +195, -165, 143, -120, -4, 5, -124, 183, +-228, 163, -182, -22, 106, -145, 353, -176, +303, -51, -43, 238, -464, 300, -469, 32, +78, -298, 605, -381, 483, -136, -115, 291, +-675, 468, -579, 175, 182, -268, 844, -414, +589, -177, -248, 239, -859, 428, -650, 146, +256, -300, 906, -460, 531, -225, -321, 268, +-673, 581, -358, 367, 311, -162, 573, -555, +118, -510, -428, -28, -359, 484, 12, 487, +314, 67, 333, -321, 27, -347, -273, -23, +-157, 299, -28, 241, -45, -135, -10, -313, +81, -156, 122, 120, 209, 286, 78, 235, +-250, -35, -351, -205, -92, -208, 188, -161, +320, 28, 179, 285, -201, 299, -357, 16, +-111, -300, 250, -367, 332, -11, 109, 418, +-301, 386, -460, -134, -149, -532, 362, -328, +534, 281, 230, 643, -340, 309, -637, -427, +-320, -713, 351, -244, 675, 442, 346, 689, +-359, 254, -730, -429, -337, -604, 422, -179, +740, 320, 348, 480, -399, 204, -786, -261, +-435, -435, 356, -214, 783, 151, 502, 374, +-179, 347, -739, 18, -625, -358, 103, -444, +701, -186, 586, 202, -52, 493, -639, 425, +-606, -66, 57, -489, 695, -521, 597, -153, +-100, 379, -663, 674, -617, 343, 19, -316, +671, -717, 655, -514, -25, 183, -611, 780, +-602, 677, -89, -110, 511, -835, 654, -793, +170, 24, -435, 871, -587, 946, -275, 108, +260, -919, 590, -1152, 341, -308, -240, 870, +-518, 1298, -309, 573, 214, -699, 545, -1385, +300, -747, -308, 605, -597, 1326, -307, 757, +283, -528, 618, -1341, 327, -783, -252, 627, +-462, 1369, -216, 786, 144, -500, 292, -1318, +42, -921, -229, 306, -157, 1072, 132, 824, +231, 16, 178, -662, -47, -689, -247, -139, +-200, 369, 14, 445, 49, 216, 39, -203, +58, -471, 74, -286, 114, 144, 115, 482, +-82, 518, -287, 86, -198, -527, 50, -683, +221, -298, 187, 286, -8, 694, -197, 529, +-110, -114, 96, -597, 211, -508, 68, -17, +-137, 522, -221, 592, -116, 4, 10, -651, +145, -695, 140, -42, 94, 766, 91, 970, +-12, 188, -218, -855, -269, -1138, -66, -334, +140, 799, 256, 1154, 153, 390, -124, -706, +-221, -1065, 14, -340, 171, 681, 154, 925, +-34, 236, -339, -603, -342, -859, 49, -266, +459, 573, 500, 809, 117, 314, -483, -368, +-671, -752, -196, -506, 470, 224, 627, 683, +201, 575, -467, 9, -654, -568, -68, -716, +578, -131, 558, 528, 21, 697, -552, 266, +-615, -410, -41, -782, 515, -376, 465, 386, +78, 710, -223, 452, -374, -146, -215, -646, +131, -555, 254, 35, 177, 467, 121, 492, +-193, 186, -432, -305, -194, -562, 251, -274, +491, 245, 421, 587, -152, 466, -754, -100, +-570, -747, 201, -755, 716, -32, 624, 789, +-55, 947, -776, 328, -649, -671, 132, -1158, +723, -517, 654, 588, -44, 1144, -801, 664, +-788, -439, 19, -1286, 777, -848, 852, 465, +167, 1408, -723, 1074, -892, -256, -206, -1512, +529, -1438, 743, 24, 320, 1467, -384, 1578, +-651, 303, -308, -1226, 193, -1658, 493, -510, +419, 1060, -1, 1572, -418, 637, -469, -873, +-157, -1605, 214, -801, 470, 753, 374, 1623, +-91, 1035, -472, -500, -442, -1650, -74, -1258, +403, 273, 590, 1540, 214, 1398, -429, -19, +-733, -1411, -344, -1437, 336, -106, 839, 1220, +602, 1367, -252, 266, -914, -1001, -696, -1305, +114, -382, 836, 755, 787, 1099, -12, 512, +-791, -396, -780, -928, -16, -633, 710, 153, +777, 683, 135, 648, -617, 153, -819, -504, +-287, -736, 481, -289, 833, 387, 487, 679, +-255, 415, -798, -244, -712, -710, 36, -473, +754, 206, 789, 627, 158, 475, -584, -49, +-857, -548, -328, -531, 493, -32, 818, 418, +400, 434, -304, 138, -789, -225, -569, -369, +201, -140, 802, 133, 652, 193, -45, 87, +-748, 14, -841, -69, -161, -102, 687, -131, +959, -105, 377, 81, -478, 360, -1019, 382, +-645, -62, 292, -574, 1051, -660, 762, -112, +-171, 660, -996, 926, -867, 280, 107, -660, +1037, -998, 922, -404, -53, 579, -963, 1025, +-1033, 436, -111, -614, 919, -1056, 1109, -451, +271, 614, -727, 1133, -1143, 600, -470, -533, +638, -1182, 1085, -741, 475, 347, -463, 1050, +-1002, 851, -556, -101, 433, -902, 912, -833, +506, 7, -227, 715, -762, 785, -657, 126, +47, -678, 617, -844, 640, -182, 241, 613, +-310, 896, -725, 438, -483, -507, 129, -1038, +615, -602, 634, 332, 134, 955, -602, 782, +-754, -133, -190, -930, 550, -768, 795, 71, +263, 756, -561, 740, -871, 13, -307, -739, +513, -686, 871, 12, 421, 613, -397, 699, +-847, 139, -557, -588, 186, -719, 779, -195, +718, 400, 6, 700, -723, 400, -860, -316, +-207, -695, 668, -419, 1011, 139, 407, 602, +-591, 596, -1085, -6, -606, -622, 419, -628, +1084, -142, 751, 474, -222, 776, -994, 362, +-850, -469, 88, -837, 916, -451, 903, 296, +84, 879, -873, 679, -1049, -243, -196, -973, +816, -748, 1117, 92, 417, 897, -637, 957, +-1177, 122, -594, -877, 501, -1028, 1041, -280, +665, 631, -204, 1022, -945, 498, -818, -516, +92, -1034, 816, -503, 883, 431, 227, 1000, +-702, 646, -1128, -396, -519, -1136, 569, -743, +1160, 340, 809, 1110, -266, 911, -1204, -106, +-1059, -1022, 83, -977, 1071, -94, 1163, 749, +248, 894, -961, 300, -1355, -486, -486, -825, +836, -439, 1456, 250, 805, 759, -651, 634, +-1584, 14, -1060, -701, 461, -846, 1547, -305, +1234, 589, -233, 994, -1513, 570, -1345, -398, +76, -1031, 1432, -729, 1496, 238, 124, 985, +-1417, 771, -1612, -154, -282, -948, 1255, -777, +1683, 92, 512, 933, -1119, 874, -1634, 3, +-597, -916, 859, -958, 1483, -175, 762, 788, +-641, 1036, -1388, 330, -801, -675, 431, -1000, +1154, -391, 940, 520, -109, 934, -1041, 435, +-968, -478, -121, -904, 701, -417, 965, 382, +469, 853, -485, 531, -974, -263, -607, -818, +243, -567, 895, 67, 837, 611, -108, 608, +-1006, 116, -898, -416, 22, -491, 936, -189, +1056, 177, 124, 392, -970, 238, -1086, -117, +-246, -349, 743, -216, 1081, 60, 457, 362, +-574, 338, -995, -25, -521, -407, 321, -397, +854, -97, 631, 304, -197, 483, -752, 237, +-598, -209, 29, -437, 568, -336, 665, 16, +170, 423, -438, 492, -630, 129, -372, -381, +141, -621, 630, -379, 591, 301, -7, 785, +-532, 615, -638, -144, -203, -830, 486, -838, +793, -41, 283, 820, -482, 921, -832, 172, +-504, -778, 370, -991, 1069, -235, 737, 793, +-301, 1010, -1070, 302, -996, -760, 15, -1118, +1135, -383, 1189, 781, 109, 1144, -1029, 458, +-1295, -673, -366, -1239, 966, -588, 1432, 687, +500, 1261, -823, 662, -1446, -493, -777, -1263, +625, -866, 1478, 369, 904, 1185, -458, 880, +-1382, -126, -1057, -980, 291, -919, 1385, 19, +1173, 870, -182, 810, -1332, 51, -1327, -733, +-81, -853, 1254, -188, 1481, 640, 377, 844, +-1011, 377, -1505, -321, -659, -770, 750, -590, +1442, 7, 808, 518, -602, 613, -1373, 277, +-835, -312, 507, -587, 1376, -312, 982, 226, +-391, 615, -1416, 406, -1147, -319, 147, -849, +1241, -537, 1318, 316, 253, 1029, -1022, 859, +-1319, -156, -482, -1106, 612, -1024, 1213, -49, +734, 917, -448, 1069, -1149, 235, -781, -771, +281, -996, 1119, -278, 991, 613, -177, 960, +-1223, 392, -1119, -550, 17, -987, 1115, -493, +1308, 421, 232, 990, -1073, 636, -1293, -296, +-362, -970, 827, -734, 1227, 143, 490, 902, +-687, 825, -1087, 22, -504, -795, 457, -925, +944, -227, 600, 663, -272, 992, -844, 431, +-646, -474, 28, -1027, 698, -619, 754, 330, +154, 1000, -566, 745, -713, -171, -312, -1001, +390, -882, 710, 85, 359, 948, -288, 961, +-598, 94, -402, -881, 168, -1043, 585, -188, +415, 712, -79, 944, -452, 357, -430, -511, +-74, -882, 345, -378, 401, 319, 183, 636, +-164, 451, -344, -80, -282, -533, 67, -424, +321, -28, 307, 278, -1, 411, -358, 224, +-383, -178, 16, -374, 426, -251, 414, -21, +-6, 293, -524, 383, -436, 120, 94, -231, +547, -340, 387, -231, -159, 78, -598, 320, +-350, 245, 232, 6, 568, -165, 315, -175, +-210, -99, -488, 54, -294, 95, 167, 105, +372, 50, 198, -42, -134, -178, -252, -138, +-144, 46, 157, 250, 219, 269, 88, 29, +-124, -325, -202, -416, -153, -121, 40, 302, +166, 467, 200, 230, 78, -213, -88, -454, +-188, -247, -139, 165, 30, 366, 109, 223, +105, -96, 7, -337, -50, -226, -69, 82, +16, 260, 14, 203, 53, 54, 30, -144, +-23, -203, -61, -116, -57, -33, -33, 49, +51, 189, 142, 221, 72, 56, -36, -159, +-160, -297, -144, -212, 3, 118, 236, 361, +185, 245, -35, -90, -224, -315, -234, -272, +2, 18, 294, 270, 281, 243, -37, 7, +-255, -165, -276, -170, -64, -64, 217, 74, +308, 126, 87, 74, -113, -10, -227, -57, +-235, -121, -41, -92, 225, 63, 286, 198, +145, 167, -85, -13, -319, -281, -295, -342, +25, -31, 317, 370, 319, 423, 114, 127, +-257, -339, -446, -531, -203, -215, 242, 322, +439, 500, 310, 276, -143, -151, -466, -442, +-342, -329, 58, 50, 370, 284, 333, 258, +-8, 122, -311, -110, -257, -220, 12, -154, +287, 0, 243, 126, -49, 212, -314, 59, +-227, -193, 14, -268, 248, -62, 302, 252, +84, 392, -182, 140, -259, -311, -200, -483, +-31, -199, 255, 275, 302, 470, 111, 230, +-150, -214, -329, -409, -263, -203, 115, 203, +377, 368, 296, 177, -30, -188, -386, -373, +-420, -242, -7, 123, 443, 382, 454, 313, +72, 4, -456, -279, -592, -337, -119, -129, +516, 186, 625, 283, 181, 148, -493, -87, +-747, -230, -229, -148, 558, 117, 752, 242, +227, 123, -546, -108, -876, -289, -265, -210, +670, 96, 979, 336, 319, 256, -645, -3, +-1118, -294, -519, -353, 601, -95, 1190, 267, +660, 347, -406, 173, -1123, -145, -837, -379, +249, -267, 1045, 134, 862, 360, -102, 254, +-950, -30, -931, -340, 40, -325, 910, 48, +949, 348, 79, 225, -866, -23, -998, -275, +-168, -252, 762, 53, 1018, 319, 336, 140, +-665, -113, -1042, -221, -442, -149, 537, 89, +1008, 275, 593, 121, -379, -144, -977, -190, +-671, -116, 190, 74, 787, 238, 734, 177, +24, -118, -660, -240, -727, -171, -155, 62, +466, 271, 718, 249, 309, -87, -368, -297, +-700, -191, -423, 87, 179, 274, 622, 170, +601, -155, 43, -309, -537, -79, -680, 231, +-271, 325, 341, 76, 758, -252, 454, -365, +-265, -80, -736, 236, -551, 305, 134, 75, +741, -158, 657, -235, -68, -44, -699, 183, +-695, 181, -90, -28, 585, -210, 764, -216, +226, -14, -461, 282, -689, 310, -365, 45, +241, -258, 666, -344, 466, -156, -102, 235, +-528, 394, -524, 158, -104, -229, 422, -371, +570, -203, 221, 198, -299, 457, -551, 255, +-319, -222, 211, -467, 573, -309, 367, 120, +-178, 508, -558, 384, -401, -133, 88, -493, +526, -368, 482, 51, 15, 485, -441, 458, +-500, -17, -148, -468, 317, -467, 499, -113, +219, 340, -252, 530, -480, 254, -246, -233, +192, -482, 475, -325, 309, 95, -162, 478, +-494, 419, -359, -80, 74, -521, 466, -478, +438, 5, -16, 564, -438, 633, -425, 78, +-34, -588, 378, -678, 439, -176, 73, 485, +-354, 687, -428, 240, -151, -443, 233, -637, +474, -212, 261, 386, -175, 625, -411, 289, +-310, -359, 33, -685, 399, -360, 356, 255, +-47, 634, -358, 481, -344, -99, -40, -585, +359, -480, 486, 31, 115, 433, -344, 418, +-511, 38, -298, -396, 162, -393, 561, -3, +442, 367, -41, 376, -421, 96, -492, -318, +-163, -455, 357, -178, 558, 238, 240, 393, +-291, 252, -604, -86, -380, -360, 253, -263, +708, 69, 500, 282, -218, 216, -760, -12, +-599, -274, 133, -247, 749, 41, 671, 279, +-49, 232, -720, 24, -714, -234, -64, -276, +650, -46, 789, 227, 216, 229, -568, 35, +-861, -194, -363, -266, 468, -47, 886, 275, +492, 321, -365, 52, -880, -249, -581, -403, +250, -174, 857, 247, 675, 446, -155, 200, +-827, -161, -770, -405, -8, -248, 796, 189, +895, 445, 130, 212, -724, -249, -919, -520, +-318, -335, 588, 260, 968, 681, 463, 486, +-431, -165, -863, -648, -622, -628, 160, -53, +785, 552, 690, 622, 27, 127, -535, -367, +-673, -519, -230, -200, 383, 312, 593, 515, +296, 202, -210, -268, -537, -518, -417, -357, +128, 139, 554, 544, 497, 487, -32, 43, +-545, -371, -627, -505, -70, -237, 560, 194, +668, 408, 172, 233, -478, -54, -757, -258, +-286, -247, 461, -6, 782, 240, 424, 270, +-369, 101, -865, -150, -559, -379, 289, -329, +849, 29, 662, 395, -172, 483, -821, 223, +-693, -275, 117, -604, 772, -378, 714, 167, +-54, 553, -779, 480, -765, -42, -45, -601, +718, -580, 836, 27, 229, 623, -609, 695, +-829, 142, -360, -631, 384, -854, 751, -269, +468, 519, -264, 826, -649, 426, -445, -355, +141, -796, 601, -437, 510, 288, -92, 687, +-613, 465, -569, -185, -48, -714, 560, -535, +693, 154, 223, 680, -467, 590, -715, -26, +-394, -662, 275, -669, 711, 12, 542, 643, +-119, 656, -625, 35, -607, -645, -55, -755, +515, -75, 595, 670, 189, 800, -338, 202, +-520, -557, -297, -838, 143, -356, 436, 408, +415, 753, 14, 417, -400, -236, -521, -635, +-153, -435, 407, 165, 637, 568, 261, 394, +-389, -145, -717, -503, -389, -392, 338, 102, +739, 465, 518, 354, -194, -94, -729, -368, +-627, -285, 50, 39, 669, 267, 715, 211, +109, -18, -576, -129, -743, -91, -243, -68, +435, -44, 705, -17, 386, 79, -254, 204, +-655, 208, -497, -71, 89, -334, 593, -312, +606, 1, 60, 357, -575, 426, -696, 36, +-168, -420, 535, -457, 786, -56, 296, 430, +-488, 561, -822, 125, -413, -480, 382, -644, +842, -225, 535, 403, -287, 708, -819, 379, +-609, -322, 145, -711, 783, -459, 720, 195, +-28, 676, -710, 538, -741, -129, -141, -680, +594, -590, 784, 54, 239, 679, -487, 681, +-719, 48, -340, -665, 373, -767, 705, -164, +356, 604, -295, 806, -619, 290, -396, -482, +172, -819, 553, -391, 390, 372, -61, 770, +-398, 485, -403, -201, -102, -736, 302, -593, +390, 87, 199, 652, -131, 641, -406, 98, +-347, -565, 79, -735, 412, -200, 372, 481, +38, 711, -401, 351, -471, -336, -55, -762, +419, -450, 487, 240, 134, 670, -392, 542, +-559, -64, -188, -685, 368, -638, 540, 3, +268, 610, -216, 704, -495, 200, -338, -563, +54, -821, 344, -310, 366, 423, 111, 786, +-232, 499, -332, -230, -178, -762, 128, -551, +322, 85, 221, 601, -124, 597, -318, 83, +-257, -543, 60, -637, 367, -164, 351, 432, +-15, 677, -381, 349, -403, -331, -78, -732, +345, -471, 440, 167, 139, 654, -253, 585, +-383, 16, -237, -580, 110, -617, 336, -122, +292, 461, 42, 634, -252, 283, -396, -371, +-157, -709, 248, -424, 405, 238, 225, 707, +-185, 610, -451, -48, -248, -708, 210, -712, +415, -101, 244, 584, -153, 760, -419, 278, +-294, -508, 149, -782, 381, -344, 255, 385, +-55, 765, -312, 512, -294, -254, 36, -795, +275, -603, 211, 100, 6, 687, -194, 721, +-214, 87, -11, -646, 210, -746, 186, -164, +11, 517, -169, 740, -211, 282, -78, -480, +164, -749, 249, -308, 119, 378, -66, 706, +-227, 424, -215, -286, -14, -712, 179, -467, +231, 172, 132, 626, -98, 546, -263, -48, +-177, -620, 83, -580, 282, -24, 213, 536, +-89, 615, -355, 147, -274, -489, 91, -631, +386, -195, 350, 377, 15, 596, -367, 298, +-453, -267, -142, -548, 261, -314, 455, 149, +253, 448, -198, 370, -453, -18, -248, -367, +192, -372, 432, -81, 227, 240, -230, 371, +-472, 203, -234, -144, 254, -351, 501, -263, +279, 23, -201, 284, -493, 319, -321, 64, +150, -246, 462, -316, 342, -112, -71, 192, +-412, 319, -397, 144, -28, -216, 375, -354, +474, -152, 165, 212, -288, 403, -524, 238, +-297, -193, 223, -472, 519, -303, 305, 121, +-172, 445, -469, 385, -318, -2, 162, -401, +476, -388, 322, -50, -121, 297, -452, 360, +-421, 93, -3, -281, 445, -350, 496, -72, +120, 250, -333, 347, -521, 146, -261, -209, +262, -369, 501, -189, 261, 109, -175, 305, +-467, 285, -333, 44, 134, -243, 470, -302, +370, -150, -54, 135, -446, 331, -471, 257, +-70, -102, 424, -359, 521, -285, 146, 77, +-344, 414, -522, 373, -231, -72, 281, -500, +493, -443, 219, 26, -212, 521, -403, 537, +-224, 63, 166, -485, 368, -563, 198, -167, +-142, 351, -329, 522, -197, 233, 110, -215, +320, -411, 220, -242, -74, 105, -287, 321, +-232, 236, -15, -33, 205, -251, 266, -258, +116, -60, -117, 198, -258, 292, -230, 171, +-17, -99, 275, -305, 356, -269, 132, 13, +-250, 261, -455, 289, -287, 64, 207, -228, +556, -293, 366, -57, -180, 230, -565, 293, +-404, 97, 186, -240, 593, -378, 375, -179, +-230, 198, -596, 420, -370, 334, 220, -63, +602, -454, 401, -462, -148, -69, -511, 401, +-403, 547, 5, 186, 367, -398, 360, -598, +71, -204, -205, 405, -286, 655, -159, 243, +117, -465, 278, -736, 222, -249, -25, 487, +-296, 776, -332, 311, -80, -487, 274, -819, +411, -335, 198, 444, -172, 781, -385, 392, +-276, -381, 78, -787, 341, -418, 284, 319, +-16, 717, -296, 460, -303, -228, -13, -707, +300, -504, 344, 180, 70, 657, -274, 544, +-356, -68, -122, -632, 190, -636, 322, -39, +150, 553, -141, 671, -260, 221, -120, -415, +107, -685, 234, -341, 144, 282, -106, 611, +-279, 420, -199, -156, 43, -571, 272, -464, +305, 99, 77, 547, -223, 518, -327, -16, +-169, -561, 98, -629, 300, -103, 247, 534, +-24, 720, -266, 263, -266, -443, -39, -762, +259, -396, 344, 329, 83, 729, -284, 459, +-402, -234, -165, -681, 254, -486, 475, 190, +236, 659, -216, 513, -461, -125, -305, -628, +127, -572, 461, 20, 329, 560, -84, 572, +-376, 98, -328, -421, 11, -538, 336, -175, +311, 314, 5, 451, -260, 184, -265, -241, +-51, -419, 194, -200, 269, 231, 81, 417, +-149, 225, -223, -162, -129, -404, 68, -282, +218, 89, 144, 332, -38, 248, -154, -3, +-137, -198, -21, -182, 106, -11, 121, 122, +42, 85, -47, 10, -95, -46, -95, -63, +-28, -58, 104, -20, 155, 40, 71, 139, +-90, 152, -192, -1, -113, -209, 116, -254, +221, -65, 83, 209, -166, 311, -247, 101, +-75, -199, 221, -297, 322, -83, 90, 191, +-221, 259, -334, 50, -166, -203, 150, -237, +324, -25, 192, 193, -72, 192, -229, 5, +-167, -169, 11, -139, 165, 30, 138, 164, +-17, 108, -137, -51, -128, -151, -27, -114, +131, 12, 198, 126, 70, 118, -122, 19, +-216, -52, -152, -69, 73, -31, 263, 32, +182, 38, -66, -36, -250, -69, -214, -41, +37, 41, 275, 141, 230, 144, -29, -21, +-247, -174, -234, -180, -7, -54, 217, 130, +222, 195, 16, 47, -181, -145, -182, -139, +-17, 3, 156, 171, 196, 168, 45, -40, +-149, -257, -212, -202, -113, 41, 77, 245, +227, 232, 206, -8, 12, -229, -194, -194, +-250, 37, -104, 185, 134, 154, 264, -42, +152, -202, -112, -157, -271, 58, -154, 181, +122, 146, 309, -6, 182, -143, -148, -151, +-341, -10, -211, 108, 119, 113, 341, 39, +239, -73, -80, -125, -306, -54, -244, 83, +24, 141, 234, 103, 236, -57, 37, -187, +-173, -157, -221, 53, -85, 208, 95, 184, +195, -24, 141, -224, -26, -217, -161, 18, +-177, 235, -52, 205, 124, -7, 214, -206, +116, -176, -99, 28, -239, 199, -174, 110, +51, -97, 262, -215, 232, -84, -12, 157, +-233, 275, -251, 114, -50, -159, 181, -281, +234, -160, 82, 84, -133, 227, -217, 157, +-81, -40, 123, -137, 209, -86, 89, 47, +-133, 111, -234, 53, -107, -89, 112, -154, +245, -97, 153, 61, -65, 193, -214, 196, +-187, 28, 6, -177, 187, -247, 193, -121, +32, 124, -157, 256, -211, 144, -52, -120, +151, -247, 216, -131, 90, 155, -110, 313, +-227, 158, -155, -208, 50, -407, 195, -229, +179, 198, 33, 488, -124, 336, -176, -142, +-59, -527, 77, -430, 120, 66, 47, 513, +-56, 485, -92, 6, -21, -495, 78, -516, +96, -22, 14, 492, -92, 531, -128, 43, +-53, -518, 81, -582, 141, -55, 93, 544, +-31, 621, -119, 108, -109, -509, -12, -656, +77, -175, 101, 450, 24, 615, -58, 203, +-84, -349, -21, -555, 62, -213, 75, 320, +21, 499, -45, 196, -67, -273, -37, -488, +11, -252, 23, 230, 44, 479, 43, 310, +23, -109, -46, -412, -67, -369, -36, -7, +43, 321, 78, 342, 16, 83, -83, -231, +-77, -320, 35, -115, 128, 208, 101, 323, +-67, 147, -184, -182, -124, -367, 63, -214, +195, 157, 150, 396, -54, 279, -193, -92, +-154, -389, 48, -333, 194, 28, 152, 358, +-34, 343, -194, 18, -159, -302, 23, -322, +149, -46, 136, 256, 21, 292, -113, 60, +-110, -214, -9, -270, 70, -88, 66, 173, +14, 277, -66, 148, -75, -102, 1, -277, +71, -243, 52, -24, 11, 241, -22, 320, +-37, 164, -5, -127, -17, -315, -50, -270, +-21, -5, 62, 238, 96, 271, 68, 89, +-40, -137, -128, -217, -106, -104, 19, 105, +117, 195, 95, 115, -25, -81, -135, -226, +-97, -194, 77, 27, 198, 250, 114, 294, +-96, 100, -251, -204, -159, -371, 79, -218, +242, 121, 178, 354, -34, 271, -196, -56, +-154, -331, 22, -270, 168, 72, 139, 336, +-37, 265, -189, -95, -167, -392, 34, -327, +229, 89, 238, 426, 20, 387, -231, -12, +-291, -393, -82, -424, 182, -74, 284, 325, +116, 388, -144, 117, -241, -227, -98, -327, +114, -122, 196, 186, 88, 265, -107, 99, +-192, -128, -103, -215, 72, -107, 171, 94, +148, 189, -15, 111, -166, -29, -163, -138, +-16, -158, 146, -59, 190, 90, 31, 165, +-181, 132, -201, 4, -23, -149, 199, -188, +231, -43, 27, 112, -220, 154, -237, 63, +-14, -81, 211, -130, 207, -7, 4, 114, +-222, 85, -195, -41, 53, -148, 247, -107, +193, 59, -52, 182, -261, 88, -216, -81, +42, -152, 240, -48, 204, 113, -7, 160, +-177, -10, -185, -214, -26, -180, 121, 60, +146, 279, 53, 247, -72, -38, -153, -331, +-101, -280, 38, 50, 159, 321, 155, 273, +2, -56, -157, -348, -203, -264, -67, 126, +133, 396, 223, 268, 112, -134, -90, -436, +-224, -323, -144, 127, 64, 444, 200, 329, +136, -73, -53, -386, -173, -335, -124, 51, +41, 362, 162, 296, 136, -58, -13, -336, +-141, -300, -178, 34, -46, 335, 141, 295, +215, -16, 109, -280, -82, -271, -214, -37, +-151, 226, 28, 230, 161, 12, 156, -184, +22, -163, -102, -4, -130, 161, -34, 165, +75, -3, 105, -151, 38, -157, -50, -50, +-111, 82, -48, 165, 40, 102, 88, -26, +70, -112, 11, -119, -55, -42, -83, 94, +-65, 130, -15, 30, 73, -90, 130, -117, +84, -39, -81, 112, -184, 154, -142, 22, +61, -122, 247, -134, 204, -32, -62, 94, +-276, 130, -241, 2, 34, -107, 292, -84, +265, 26, -14, 88, -281, 84, -268, -9, +-12, -93, 262, -75, 292, -13, 60, 22, +-230, 39, -304, 51, -141, 17, 154, 2, +308, -8, 213, -27, -57, -26, -282, 4, +-252, -9, -6, -23, 226, 0, 237, 28, +39, 37, -194, 36, -217, 5, -30, -44, +190, -31, 212, -5, 53, -11, -178, -11, +-256, 7, -109, 27, 135, 55, 251, 44, +163, -22, -56, -70, -222, -29, -153, 11, +31, 21, 154, -2, 107, -44, -26, -40, +-128, 48, -72, 107, 58, 52, 134, -23, +63, -89, -54, -82, -136, -25, -92, 34, +41, 11, 114, 12, 80, 49, 0, 74, +-58, 44, -55, -24, -5, -104, 2, -126, +3, -35, 1, 58, 28, 93, 35, 75, +14, 30, -37, -34, -45, -47, -9, -30, +52, -18, 40, 1, -31, 18, -77, -18, +-47, -38, 58, 5, 115, 66, 62, 95, +-58, 71, -128, -39, -83, -144, 42, -121, +95, -23, 67, 69, -11, 101, -56, 77, +-32, 5, 16, -8, 38, -19, 12, -48, +-32, -63, -60, -24, -49, 18, 11, 51, +101, 58, 101, -5, 32, -40, -86, -7, +-150, 38, -73, 26, 77, 5, 120, -54, +55, -79, -49, -17, -94, 68, -26, 84, +71, 47, 86, -31, -8, -104, -80, -78, +-83, 26, -11, 111, 87, 110, 111, 15, +11, -132, -81, -183, -117, -71, -41, 111, +89, 210, 141, 156, 56, -33, -88, -183, +-156, -168, -82, -21, 70, 105, 140, 124, +67, 32, -66, -74, -89, -81, -23, 13, +71, 95, 62, 81, -42, 9, -99, -100, +-28, -134, 61, -63, 88, 50, 13, 111, +-63, 109, -43, 42, 37, -66, 82, -98, +0, -49, -96, 14, -108, 55, -5, 50, +110, -38, 133, -92, 19, -36, -87, 67, +-100, 137, -15, 120, 60, -32, 51, -198, +-13, -189, -53, -30, -23, 145, 39, 216, +54, 102, 15, -123, -7, -208, -28, -78, +-24, 113, -25, 198, -19, 88, 1, -154, +43, -249, 56, -87, 27, 159, -32, 262, +-59, 142, -48, -122, 0, -269, 61, -146, +58, 91, 17, 216, -47, 138, -92, -53, +-61, -188, 41, -113, 113, 55, 106, 150, +-16, 103, -135, -24, -144, -131, -8, -112, +145, 16, 157, 111, 17, 109, -147, 9, +-168, -105, -5, -133, 179, -27, 178, 97, +3, 134, -189, 43, -187, -86, -1, -138, +195, -54, 205, 72, 25, 118, -183, 44, +-221, -61, -72, -105, 150, -45, 254, 56, +127, 98, -102, 51, -256, -23, -184, -68, +53, -72, 243, -33, 208, 11, -20, 63, +-226, 81, -199, 61, 3, -29, 214, -102, +217, -84, -4, 7, -224, 88, -243, 89, +-41, 0, 212, -95, 289, -72, 92, 20, +-183, 88, -295, 72, -138, -1, 125, -81, +276, -67, 165, -2, -90, 32, -246, 26, +-164, 10, 58, -12, 239, -12, 208, 7, +-24, 6, -227, -7, -230, 0, -33, -1, +191, -20, 256, -21, 85, -7, -152, 19, +-247, 44, -110, 41, 117, -14, 250, -54, +141, -58, -108, -22, -265, 32, -169, 71, +101, 54, 288, 1, 208, -49, -81, -86, +-305, -59, -248, 15, 55, 94, 305, 106, +281, 44, -3, -74, -299, -140, -321, -88, +-35, 43, 276, 136, 346, 102, 104, -30, +-247, -140, -360, -103, -126, 42, 220, 158, +344, 109, 146, -54, -197, -181, -343, -145, +-142, 39, 193, 200, 320, 167, 157, -24, +-153, -182, -325, -164, -186, 10, 122, 178, +292, 159, 197, -33, -47, -188, -232, -159, +-211, 17, -9, 181, 185, 175, 193, -11, +70, -155, -105, -133, -209, 0, -138, 104, +65, 91, 206, -25, 183, -87, 0, -15, +-211, 61, -252, 54, -43, -18, 225, -68, +267, -23, 83, 75, -188, 62, -309, -61, +-113, -135, 194, -55, 299, 105, 130, 193, +-166, 77, -310, -136, -159, -201, 158, -49, +303, 152, 155, 190, -120, 21, -294, -186, +-208, -196, 83, 7, 291, 197, 237, 198, +-1, 36, -259, -154, -296, -188, -71, -59, +213, 87, 291, 130, 123, 65, -148, -54, +-280, -108, -143, -51, 136, 64, 255, 152, +129, 95, -102, -80, -254, -230, -153, -191, +97, 32, 241, 269, 166, 273, -41, 34, +-210, -233, -194, -276, -21, -51, 157, 207, +184, 252, 59, 33, -101, -225, -168, -271, +-92, -52, 76, 232, 171, 340, 114, 155, +-41, -177, -166, -373, -160, -289, -9, 35, +160, 346, 179, 364, 55, 80, -116, -262, +-178, -367, -86, -138, 92, 220, 165, 348, +92, 125, -50, -232, -148, -366, -109, -142, +48, 224, 158, 393, 127, 171, -18, -194, +-164, -362, -163, -190, -7, 136, 164, 315, +174, 174, 27, -115, -150, -255, -183, -157, +-40, 90, 141, 240, 180, 165, 53, -56, +-118, -193, -174, -172, -72, -18, 69, 136, +133, 162, 93, 50, 3, -79, -67, -110, +-86, -60, -58, 44, 9, 96, 71, 36, +83, -59, 20, -86, -56, -49, -85, 34, +-25, 106, 68, 77, 96, -9, 26, -78, +-68, -91, -120, -36, -81, 61, 54, 108, +146, 45, 128, -61, -1, -117, -138, -69, +-169, 59, -49, 164, 113, 108, 173, -71, +90, -184, -56, -146, -159, 20, -126, 173, +30, 162, 142, -7, 128, -131, 13, -121, +-131, 10, -161, 125, -30, 106, 116, -35, +155, -138, 60, -102, -84, 16, -171, 124, +-105, 121, 74, 29, 188, -72, 143, -94, +-32, -58, -203, -20, -187, 8, 22, 43, +208, 70, 193, 68, 1, 11, -189, -81, +-212, -98, -19, -16, 188, 90, 206, 97, +25, -5, -169, -134, -221, -127, -62, 27, +181, 197, 237, 198, 68, 3, -156, -216, +-240, -269, -111, -81, 141, 198, 234, 297, +102, 134, -98, -136, -199, -284, -115, -169, +75, 118, 181, 271, 106, 158, -64, -105, +-160, -279, -103, -191, 56, 105, 175, 309, +110, 218, -64, -71, -173, -308, -126, -273, +34, 14, 182, 303, 152, 296, -16, 30, +-167, -249, -159, -301, -16, -72, 135, 217, +164, 286, 18, 83, -128, -163, -132, -258, +-19, -113, 102, 134, 140, 242, 30, 111, +-113, -100, -141, -209, -33, -139, 92, 67, +161, 196, 81, 136, -99, -45, -165, -168, +-84, -141, 51, 18, 156, 163, 129, 143, +-36, -15, -147, -148, -134, -140, -10, -22, +123, 148, 168, 173, 58, 23, -115, -139, +-167, -181, -81, -77, 73, 105, 179, 205, +89, 109, -84, -51, -131, -161, -58, -140, +54, -19, 102, 99, 37, 122, -63, 48, +-54, -30, -1, -69, 23, -41, 2, 9, +7, 52, -10, 29, 22, -27, 52, -78, +-31, -78, -77, 14, -34, 119, 37, 160, +91, 66, 68, -95, -62, -217, -124, -168, +-63, 10, 55, 197, 119, 225, 103, 52, +-17, -137, -127, -202, -109, -75, -7, 108, +84, 169, 126, 41, 52, -113, -80, -172, +-117, -73, -66, 112, 55, 206, 144, 147, +93, -25, -86, -181, -182, -234, -95, -105, +80, 117, 189, 264, 121, 211, -82, -27, +-173, -266, -92, -279, 60, -22, 153, 254, +96, 302, -62, 61, -159, -268, -84, -352, +65, -73, 167, 286, 111, 374, -53, 110, +-194, -305, -125, -429, 61, -119, 175, 337, +132, 479, -60, 163, -191, -336, -109, -555, +86, -255, 186, 292, 99, 578, -94, 332, +-198, -175, -91, -524, 110, -383, 205, 97, +101, 427, -105, 321, -210, -76, -108, -380, +110, -304, 206, 107, 114, 412, -78, 332, +-197, -74, -122, -418, 44, -398, 149, -32, +116, 344, -8, 392, -104, 116, -87, -200, +-5, -279, 55, -120, 52, 109, 12, 167, +-27, 54, -49, -84, -37, -124, 18, -38, +66, 71, 67, 129, 17, 101, -73, 2, +-101, -121, -44, -165, 50, -125, 95, 38, +77, 215, -4, 204, -90, 33, -90, -174, +-13, -256, 87, -108, 89, 170, 26, 273, +-72, 121, -88, -149, -25, -291, 34, -159, +64, 132, 63, 316, 20, 178, -49, -109, +-88, -282, -79, -202, 14, 66, 119, 281, +109, 208, -14, -37, -125, -227, -108, -245, +7, -27, 87, 212, 101, 265, 26, 93, +-47, -141, -88, -263, -91, -159, -14, 81, +129, 236, 158, 176, 16, -47, -151, -199, +-199, -187, -18, 21, 204, 215, 208, 202, +-5, 2, -199, -204, -208, -253, -16, -73, +181, 189, 220, 253, 46, 125, -146, -99, +-203, -226, -89, -166, 114, 33, 207, 164, +96, 144, -93, 26, -167, -120, -101, -153, +79, -40, 138, 124, 49, 155, -55, 62, +-78, -96, -20, -187, 35, -93, 27, 78, +0, 161, 6, 101, 9, -3, -33, -118, +-42, -128, 3, -38, 73, 68, 75, 127, +-9, 91, -95, -55, -101, -178, 10, -102, +84, 82, 87, 221, 28, 129, -48, -105, +-90, -263, -41, -164, 13, 113, 62, 259, +109, 152, 25, -77, -96, -200, -126, -159, +-45, 37, 109, 148, 180, 112, 47, 12, +-147, -94, -202, -130, -39, -44, 166, 99, +217, 156, 45, 96, -206, -87, -247, -211, +-12, -160, 219, 62, 242, 241, 29, 191, +-228, -23, -215, -231, -8, -212, 159, 13, +194, 219, 53, 183, -124, -7, -191, -200, +-108, -194, 90, 16, 238, 186, 164, 193, +-106, 34, -287, -142, -183, -201, 123, -72, +292, 86, 157, 173, -133, 120, -271, -33, +-106, -158, 141, -153, 223, 0, 90, 141, +-109, 181, -187, 41, -95, -148, 72, -217, +156, -82, 139, 125, -19, 222, -168, 119, +-147, -104, -9, -192, 145, -80, 151, 118, +-3, 153, -134, 13, -112, -152, 1, -141, +94, 60, 73, 195, 6, 115, -57, -80, +-60, -160, -4, -71, 17, 100, 21, 104, +37, -24, -11, -109, -27, -51, -11, 90, +-28, 121, 24, 13, 51, -110, 17, -90, +-21, 28, -46, 123, -55, 33, -4, -104, +64, -153, 104, -39, 66, 165, -47, 194, +-158, 36, -133, -150, 58, -201, 214, -54, +135, 158, -76, 146, -228, -5, -137, -127, +118, -128, 231, 54, 93, 182, -137, 107, +-195, -71, -83, -165, 119, -115, 173, 42, +55, 128, -77, 90, -130, -16, -73, -84, +28, -37, 102, -10, 108, 37, 34, 59, +-78, 23, -140, -13, -106, -47, 39, -115, +177, -73, 153, 71, 3, 170, -170, 196, +-229, 13, -30, -227, 191, -301, 246, -106, +70, 213, -203, 379, -272, 185, -68, -214, +200, -444, 280, -263, 93, 247, -189, 539, +-282, 319, -124, -256, 157, -629, 283, -376, +131, 283, -126, 659, -254, 368, -136, -299, +108, -676, 215, -314, 133, 360, -57, 672, +-184, 297, -150, -395, -1, -718, 171, -345, +194, 356, 47, 716, -152, 441, -223, -240, +-79, -685, 151, -493, 230, 157, 57, 626, +-134, 473, -162, -154, -23, -638, 117, -454, +88, 221, -35, 691, -64, 444, 16, -251, +39, -719, 1, -460, -63, 267, -44, 687, +52, 391, 85, -269, 35, -607, -54, -294, +-95, 355, -55, 563, 31, 139, 123, -431, +103, -527, -34, -32, -163, 510, -140, 467, +49, -95, 219, -513, 161, -358, -74, 219, +-235, 510, -180, 203, 79, -343, 254, -497, +195, -88, -47, 438, -251, 497, -228, 14, +16, -497, 243, -497, 247, 26, 22, 512, +-207, 517, -229, -14, -41, -561, 175, -546, +190, -2, 41, 542, -105, 596, -131, 65, +-70, -555, 66, -607, 125, -100, 96, 490, +-10, 617, -136, 144, -152, -460, 1, -607, +177, -181, 167, 389, 12, 606, -151, 270, +-184, -308, -40, -613, 132, -353, 168, 204, +88, 583, -58, 463, -183, -101, -149, -570, +71, -516, 194, 7, 154, 538, -44, 603, +-208, 62, -150, -559, 80, -646, 195, -119, +104, 549, -53, 718, -173, 189, -119, -544, +45, -724, 170, -228, 129, 447, 6, 708, +-141, 308, -173, -396, -34, -672, 161, -316, +187, 269, 46, 652, -134, 431, -202, -226, +-57, -661, 160, -469, 205, 124, 65, 642, +-119, 592, -227, -64, -113, -648, 116, -589, +245, 9, 159, 560, -66, 616, -240, 46, +-187, -572, 59, -583, 246, -66, 193, 472, +-15, 619, -223, 191, -222, -455, 19, -639, +238, -273, 229, 302, 40, 651, -204, 438, +-277, -193, -62, -635, 177, -497, 284, 54, +182, 569, -92, 579, -316, 29, -270, -558, +51, -598, 356, -97, 368, 492, 5, 655, +-401, 190, -431, -447, -2, -643, 446, -268, +457, 312, 38, 619, -441, 359, -470, -207, +-20, -554, 446, -416, 460, 66, 48, 501, +-398, 517, -428, 52, -40, -458, 361, -580, +398, -205, 86, 362, -262, 648, -345, 343, +-138, -268, 172, -631, 333, -453, 218, 137, +-33, 622, -291, 545, -324, -55, -37, -618, +329, -646, 407, -65, 113, 621, -332, 770, +-453, 201, -101, -570, 357, -820, 459, -343, +99, 453, -332, 817, -381, 417, -71, -341, +306, -732, 371, -445, 57, 238, -221, 668, +-269, 464, -74, -148, 154, -632, 229, -530, +94, 34, -30, 567, -108, 615, -140, 132, +-86, -497, 78, -681, 244, -265, 218, 375, +-4, 700, -313, 385, -352, -288, 17, -701, +447, -450, 445, 207, 18, 677, -482, 533, +-510, -92, 11, -641, 561, -600, 525, -24, +-16, 553, -536, 666, -519, 181, 40, -510, +562, -747, 534, -282, -11, 470, -511, 838, +-519, 407, -24, -486, 474, -939, 548, -476, +102, 479, -391, 978, -486, 522, -159, -439, +304, -962, 516, -522, 255, 407, -190, 893, +-448, 519, -303, -307, 112, -849, 420, -608, +392, 166, 19, 778, -335, 752, -387, 107, +-108, -678, 248, -944, 419, -372, 207, 559, +-164, 1066, -352, 633, -243, -424, 71, -1175, +339, -841, 331, 324, 45, 1239, -253, 1030, +-329, -171, -149, -1262, 187, -1228, 402, -15, +271, 1221, -64, 1363, -329, 266, -336, -1083, +-71, -1467, 316, -504, 455, 919, 221, 1504, +-194, 762, -499, -704, -388, -1553, 136, -1029, +572, 445, 527, 1539, 44, 1296, -525, -102, +-642, -1431, -158, -1512, 478, -282, 730, 1205, +375, 1597, -318, 638, -744, -873, -506, -1613, +217, -936, 776, 538, 703, 1509, 5, 1213, +-759, -128, -829, -1409, -122, -1452, 720, -289, +975, 1145, 385, 1651, -629, 782, -1072, -812, +-512, -1751, 501, -1222, 1132, 371, 756, 1705, +-343, 1615, -1142, 100, -831, -1617, 223, -1909, +1074, -508, 975, 1410, 3, 2164, -940, 948, +-965, -1236, -152, -2322, 729, -1300, 1015, 923, +455, 2383, -484, 1665, -964, -586, -596, -2293, +205, -1903, 913, 163, 854, 2020, 42, 2058, +-782, 288, -914, -1667, -307, -2078, 627, -680, +1065, 1187, 543, 2006, -432, 1087, -1040, -745, +-741, -1863, 244, -1365, 1106, 268, 962, 1641, +-54, 1607, -1002, 169, -1049, -1366, -135, -1700, +976, -562, 1184, 987, 314, 1665, -775, 911, +-1138, -590, -503, -1512, 633, -1163, 1169, 122, +613, 1263, -399, 1360, -1008, 309, -706, -970, +208, -1457, 898, -706, 741, 656, 28, 1457, +-626, 1003, -729, -329, -245, -1343, 475, -1182, +770, 9, 419, 1137, -216, 1239, -667, 281, +-560, -819, 91, -1200, 649, -591, 632, 486, +150, 1077, -475, 801, -690, -85, -311, -877, +375, -986, 753, -272, 492, 647, -231, 1029, +-759, 561, -600, -350, 168, -983, 792, -814, +643, 100, -65, 874, -664, 898, -594, 201, +34, -658, 557, -1007, 540, -473, 109, 413, +-332, 925, -407, 743, -162, -24, 178, -781, +364, -973, 281, -370, -10, 525, -260, 1039, +-306, 751, -92, -186, 209, -1062, 359, -1053, +227, -87, -143, 964, -390, 1258, -273, 400, +123, -870, 428, -1409, 367, -690, -63, 686, +-426, 1475, -333, 964, 80, -428, 436, -1423, +383, -1203, -36, 136, -419, 1304, -352, 1301, +88, 161, 462, -1088, 353, -1330, -104, -402, +-450, 872, -312, 1279, 185, 578, 457, -611, +258, -1173, -222, -734, -430, 337, -185, 1047, +266, 783, 415, -61, 159, -785, -258, -792, +-396, -189, -117, 537, 264, 689, 433, 331, +190, -210, -190, -549, -425, -451, -229, -31, +194, 364, 440, 434, 273, 275, -101, -116, +-373, -394, -305, -403, 61, -122, 319, 218, +274, 456, 39, 391, -200, -38, -298, -465, +-134, -559, 146, -167, 278, 409, 222, 732, +30, 346, -269, -384, -361, -793, -88, -515, +283, 268, 451, 817, 288, 643, -210, -97, +-559, -707, -363, -747, 206, -146, 550, 535, +468, 764, -38, 426, -579, -282, -573, -787, +-31, -680, 513, 69, 606, 771, 213, 865, +-460, 183, -719, -731, -316, -1062, 401, -399, +692, 678, 433, 1114, -211, 646, -696, -475, +-504, -1197, 104, -839, 586, 298, 572, 1121, +128, 974, -447, -29, -614, -1069, -273, -1093, +327, -145, 632, 959, 418, 1133, -178, 336, +-655, -802, -541, -1203, 24, -473, 563, 648, +637, 1154, 162, 615, -482, -401, -734, -1102, +-405, -721, 317, 204, 831, 912, 612, 808, +-176, 47, -846, -714, -780, -840, 5, -238, +831, 461, 923, 806, 165, 434, -753, -222, +-982, -737, -341, -574, 608, 15, 1058, 586, +484, 687, -542, 183, -1050, -457, -658, -717, +333, -334, 1045, 274, 758, 710, -275, 504, +-1003, -101, -797, -641, 106, -636, 875, -94, +813, 506, -13, 718, -751, 295, -703, -355, +-126, -741, 496, -454, 696, 182, 284, 686, +-362, 602, -608, -18, -406, -630, 87, -736, +565, -135, 520, 555, 16, 828, -522, 340, +-602, -448, -222, -910, 368, -532, 624, 323, +276, 874, -340, 692, -568, -136, -336, -780, +145, -784, 511, -31, 310, 659, -126, 770, +-386, 189, -277, -510, 13, -748, 287, -330, +241, 410, 0, 703, -197, 435, -222, -249, +-127, -660, 55, -553, 198, 70, 131, 604, +-24, 606, -185, 142, -221, -468, -90, -669, +109, -365, 130, 335, 62, 674, -32, 501, +-145, -140, -154, -676, -15, -618, 82, 13, +88, 659, 6, 657, -91, 128, -90, -584, +34, -714, 58, -251, -66, 479, -116, 712, +1, 364, 123, -279, 80, -710, -111, -500, +-293, 110, -174, 645, 145, 576, 314, 83, +106, -563, -212, -667, -391, -181, -236, 464, +102, 674, 322, 278, 259, -346, -46, -676, +-345, -331, -371, 244, -84, 586, 282, 373, +403, -101, 101, -487, -306, -420, -458, 8, +-185, 330, 204, 388, 391, 129, 205, -171, +-198, -353, -476, -197, -351, 35, 34, 224, +363, 255, 344, 107, -24, -95, -368, -264, +-409, -192, -142, -38, 129, 206, 285, 274, +212, 143, 12, -151, -245, -304, -373, -200, +-259, 53, 100, 300, 413, 237, 367, 17, +-56, -261, -522, -253, -556, -60, -135, 177, +463, 229, 592, 105, 168, -77, -501, -203, +-795, -86, -417, 4, 323, 103, 781, 84, +469, 77, -300, -2, -886, -44, -673, -88, +93, -163, 772, -73, 674, 145, -17, 341, +-701, 178, -809, -120, -230, -475, 487, -399, +792, 119, 354, 619, -409, 536, -914, -78, +-616, -630, 163, -672, 790, -16, 673, 659, +-81, 753, -808, 80, -894, -593, -221, -754, +572, -251, 833, 515, 311, 798, -500, 356, +-943, -405, -531, -743, 293, -489, 796, 255, +560, 705, -227, 524, -823, -156, -716, -624, +58, -459, 720, 69, 635, 495, -51, 389, +-716, -34, -764, -390, -130, -251, 570, 14, +576, 215, 37, 155, -538, 7, -615, -50, +-174, -51, 338, -1, 421, -80, -30, -90, +-371, -22, -358, 159, -27, 161, 197, 96, +206, -75, -115, -265, -318, -210, -174, -23, +87, 256, 197, 322, 47, 206, -199, -193, +-378, -459, -154, -346, 163, 135, 312, 531, +31, 467, -269, 16, -461, -618, -315, -613, +137, -63, 422, 594, 277, 695, -196, 235, +-534, -522, -550, -810, -73, -325, 425, 378, +563, 778, 117, 475, -452, -144, -704, -716, +-434, -613, 262, -65, 719, 509, 467, 677, +-310, 356, -817, -275, -719, -744, 18, -562, +722, 19, 720, 703, 11, 826, -782, 261, +-948, -658, -387, -1052, 485, -544, 916, 508, +507, 1209, -408, 844, -1017, -270, -865, -1273, +-11, -1122, 850, -8, 943, 1180, 169, 1303, +-836, 318, -1162, -962, -526, -1401, 552, -589, +1102, 690, 634, 1374, -465, 815, -1214, -360, +-944, -1272, 106, -1047, 991, 34, 952, 1113, +11, 1206, -992, 314, -1150, -841, -383, -1346, +582, -662, 956, 547, 492, 1338, -399, 981, +-1008, -149, -796, -1231, -9, -1256, 665, -216, +802, 1017, 228, 1417, -602, 569, -982, -744, +-565, -1475, 225, -876, 809, 476, 693, 1419, +-89, 1091, -892, -160, -973, -1243, -298, -1246, +509, -151, 892, 947, 506, 1256, -412, 499, +-1061, -561, -861, -1146, -54, -815, 756, 120, +927, 932, 236, 1039, -743, 328, -1114, -617, +-584, -1178, 330, -704, 928, 328, 739, 1143, +-204, 1020, -1024, 21, -959, -1044, -185, -1243, +667, -330, 934, 829, 344, 1348, -614, 683, +-1063, -545, -709, -1403, 90, -1016, 787, 268, +854, 1291, 104, 1282, -814, 138, -1143, -1131, +-619, -1494, 406, -466, 1132, 870, 826, 1493, +-329, 834, -1250, -528, -1151, -1448, -120, -1127, +1016, 232, 1217, 1251, 246, 1271, -960, 164, +-1388, -1037, -698, -1415, 551, -460, 1283, 822, +807, 1342, -439, 770, -1331, -485, -1141, -1287, +-66, -1052, 1005, 208, 1087, 1115, 218, 1115, +-856, 207, -1262, -833, -675, -1200, 419, -515, +1077, 597, 734, 1038, -252, 728, -1089, -212, +-1018, -889, -145, -884, 770, -71, 929, 714, +275, 874, -674, 412, -1108, -408, -649, -908, +278, -724, 871, 158, 668, 813, -134, 908, +-908, 244, -928, -645, -260, -1050, 511, -584, +766, 434, 360, 1015, -400, 795, -879, -101, +-658, -878, 29, -995, 603, -181, 629, 739, +66, 971, -637, 453, -773, -442, -320, -975, +314, -738, 570, 200, 272, 908, -243, 877, +-582, 160, -475, -700, -122, -1075, 207, -516, +331, 535, 181, 1060, -164, 800, -446, -120, +-467, -1006, -193, -1107, 157, -202, 331, 851, +245, 1202, -114, 601, -473, -541, -522, -1302, +-216, -954, 238, 279, 528, 1209, 309, 1177, +-289, 140, -733, -1060, -615, -1410, -32, -506, +593, 810, 679, 1451, 89, 926, -680, -410, +-947, -1460, -474, -1339, 338, 4, 843, 1332, +557, 1600, -277, 494, -954, -1082, -903, -1794, +-161, -896, 691, 815, 895, 1780, 287, 1226, +-637, -443, -1113, -1676, -711, -1490, 285, 73, +1016, 1497, 798, 1615, -170, 365, -1102, -1166, +-1162, -1710, -239, -816, 879, 805, 1142, 1639, +337, 1177, -819, -308, -1353, -1453, -799, -1442, +450, -187, 1215, 1175, 809, 1517, -328, 624, +-1222, -766, -1117, -1475, -96, -1012, 916, 378, +1019, 1337, 187, 1237, -778, 63, -1093, -1110, +-599, -1385, 378, -498, 924, 825, 627, 1401, +-227, 828, -886, -446, -904, -1250, -237, -1132, +578, 6, 813, 1071, 306, 1239, -464, 400, +-869, -719, -673, -1241, 22, -793, 588, 380, +635, 1130, 112, 993, -486, 6, -789, -887, +-549, -1120, 115, -397, 628, 635, 627, 1092, +20, 697, -655, -257, -887, -965, -416, -995, +364, -157, 852, 756, 527, 1161, -319, 607, +-949, -440, -887, -1197, -100, -1033, 713, 57, +928, 1148, 225, 1315, -693, 312, -1124, -921, +-659, -1453, 309, -702, 989, 677, 752, 1461, +-237, 963, -999, -336, -998, -1309, -172, -1210, +686, -43, 931, 1140, 304, 1347, -575, 397, +-1021, -819, -685, -1398, 159, -803, 802, 529, +771, 1369, 2, 1042, -789, -162, -1031, -1188, +-421, -1233, 449, -164, 899, 954, 546, 1239, +-332, 472, -981, -631, -836, -1167, -56, -732, +645, 295, 836, 997, 251, 926, -601, 80, +-1019, -792, -588, -1045, 241, -395, 832, 534, +732, 1054, -119, 697, -912, -286, -959, -959, +-222, -843, 560, -17, 904, 770, 405, 941, +-551, 268, -1025, -550, -662, -874, 152, -514, +751, 280, 722, 803, -53, 675, -761, -45, +-845, -624, -280, -754, 378, -223, 695, 473, +427, 737, -315, 412, -756, -247, -617, -641, +-31, -584, 515, 31, 588, 536, 79, 613, +-503, 186, -656, -351, -284, -619, 196, -353, +380, 209, 264, 463, -82, 426, -344, 32, +-417, -296, -228, -430, 16, -230, 233, 65, +314, 330, 67, 458, -304, 207, -488, -242, +-313, -620, -6, -438, 355, 98, 447, 703, +57, 698, -446, 14, -615, -734, -363, -835, +149, -136, 617, 639, 495, 914, -149, 312, +-733, -510, -697, -899, -218, -460, 448, 312, +811, 772, 370, 636, -486, -50, -962, -663, +-678, -758, 106, -169, 870, 479, 835, 792, +-55, 446, -927, -315, -970, -804, -278, -605, +599, 128, 959, 651, 470, 714, -507, 165, +-1092, -524, -745, -754, 126, -366, 924, 263, +918, 684, -12, 656, -975, 0, -1097, -664, +-276, -800, 655, -233, 945, 507, 451, 869, +-472, 505, -1025, -365, -717, -881, 96, -643, +745, 149, 818, 737, 139, 764, -753, 130, +-1008, -624, -385, -842, 511, -322, 847, 421, +472, 799, -342, 568, -877, -207, -655, -798, +40, -706, 557, 19, 605, 646, 189, 779, +-469, 293, -774, -476, -472, -849, 194, -490, +614, 262, 495, 774, -62, 699, -627, 2, +-638, -747, -156, -819, 341, -130, 480, 606, +271, 815, -204, 333, -524, -411, -487, -818, +-84, -479, 364, 220, 484, 667, 220, 623, +-341, 77, -638, -573, -398, -787, 158, -257, +485, 455, 388, 792, -74, 441, -497, -337, +-482, -798, -130, -509, 224, 243, 350, 671, +235, 514, -121, -71, -391, -491, -406, -526, +-151, -123, 199, 323, 415, 471, 254, 313, +-219, -85, -468, -466, -377, -488, -42, -48, +333, 409, 392, 545, 91, 183, -257, -337, +-471, -575, -407, -274, -6, 276, 464, 474, +557, 330, 63, -84, -572, -396, -787, -397, +-299, -64, 527, 243, 829, 376, 256, 298, +-575, -87, -828, -405, -372, -415, 400, -65, +661, 324, 310, 519, -258, 219, -568, -294, +-398, -562, -47, -339, 285, 216, 418, 554, +222, 478, -223, -77, -548, -551, -450, -596, +65, -84, 442, 476, 466, 662, -12, 312, +-514, -384, -465, -692, -140, -462, 211, 235, +359, 702, 234, 577, -114, -47, -387, -661, +-349, -727, -140, -113, 196, 656, 432, 777, +207, 309, -238, -567, -423, -938, -324, -400, +-20, 514, 275, 968, 363, 460, 132, -453, +-255, -905, -420, -466, -415, 407, -36, 826, +494, 319, 531, -324, 43, -591, -536, -272, +-712, 279, -228, 372, 430, 135, 713, -128, +313, -160, -463, -19, -731, 11, -433, -64, +187, -25, 647, 70, 530, 201, -134, 144, +-626, -171, -618, -286, -100, -143, 466, 148, +567, 342, 219, 124, -428, -164, -597, -271, +-289, -127, 155, 190, 381, 166, 361, 5, +33, -87, -345, -50, -431, 60, -311, 73, +82, -155, 477, -203, 530, 88, 4, 268, +-620, 272, -689, -138, -165, -448, 534, -297, +776, 174, 266, 559, -608, 354, -860, -241, +-368, -571, 425, -369, 794, 144, 443, 615, +-338, 434, -851, -138, -544, -541, 207, -492, +692, 30, 499, 506, -52, 535, -656, 45, +-587, -501, 4, -582, 420, -46, 454, 480, +96, 564, -288, 119, -409, -526, -227, -559, +60, -10, 247, 482, 210, 393, 147, -38, +-111, -407, -383, -233, -344, 202, -53, 279, +338, -15, 472, -337, 144, -104, -404, 283, +-662, 337, -278, -22, 388, -468, 625, -396, +328, 231, -307, 660, -746, 319, -473, -330, +241, -755, 697, -390, 480, 408, -130, 858, +-745, 465, -651, -367, 98, -959, 731, -626, +593, 346, -130, 1037, -707, 861, -655, -288, +110, -1275, 687, -1036, 494, 304, -228, 1487, +-627, 1256, -402, -335, 165, -1752, 563, -1405, +267, 464, -316, 1983, -502, 1398, -132, -638, +279, -2082, 391, -1372, 36, 905, -410, 2217, +-368, 1101, 92, -1166, 394, -2128, 232, -842, +-199, 1409, -428, 2056, -201, 381, 228, -1618, +405, -1785, 81, 66, -311, 1783, -372, 1480, +-74, -501, 300, -1929, 321, -1211, -27, 936, +-362, 2022, -319, 881, 91, -1186, 383, -2085, +184, -682, -200, 1484, -391, 2093, -183, 485, +284, -1703, 429, -2110, 45, -326, -440, 1848, +-431, 2136, -21, 234, 488, -1965, 505, -2109, +-79, -99, -663, 1948, -578, 1987, 185, -14, +704, -1894, 530, -1777, -215, 127, -808, 1782, +-575, 1474, 294, -273, 788, -1499, 430, -1148, +-263, 252, -688, 1243, -486, 798, 171, -287, +614, -796, 396, -487, -129, 160, -422, 483, +-424, 270, -52, -72, 328, -210, 385, -167, +34, -42, -185, 42, -265, 213, -227, 153, +22, -64, 162, -213, 234, -204, 137, 110, +-58, 345, -322, 110, -405, -240, -27, -386, +443, -75, 482, 439, 64, 466, -494, -52, +-635, -528, -105, -542, 538, 47, 665, 645, +75, 581, -545, -35, -605, -642, -150, -644, +443, -43, 579, 608, 174, 752, -417, 152, +-537, -573, -202, -815, 232, -349, 551, 467, +331, 971, -319, 543, -633, -428, -298, -1012, +312, -740, 673, 270, 283, 1142, -439, 920, +-808, -211, -180, -1155, 674, -1044, 677, 61, +-21, 1178, -685, 1214, -670, 55, 137, -1198, +814, -1310, 489, -202, -321, 1162, -750, 1442, +-332, 331, 270, -1188, 675, -1532, 317, -375, +-368, 1159, -573, 1591, -209, 384, 309, -1157, +399, -1557, 158, -429, -232, 1130, -297, 1502, +-79, 325, 147, -977, 87, -1277, -25, -400, +85, 862, 79, 1110, -48, 312, -248, -680, +-164, -870, 35, -283, 359, 435, 304, 770, +-187, 295, -441, -373, -268, -534, 199, -230, +393, 118, 240, 419, -157, 207, -425, -66, +-193, -179, 185, -133, 264, -52, 146, -10, +-74, 56, -226, 170, -124, 158, 25, -51, +139, -248, 114, -258, 38, 54, -80, 354, +-179, 277, -119, -100, 120, -412, 278, -158, +90, 185, -197, 273, -369, 39, -75, -240, +363, -220, 486, 237, -85, 318, -594, -56, +-468, -362, 254, -305, 748, 179, 452, 490, +-437, 271, -949, -274, -349, -563, 654, -227, +965, 283, 252, 504, -715, 371, -994, -131, +-207, -580, 803, -538, 928, -106, 137, 601, +-722, 882, -850, 326, -199, -717, 638, -1191, +819, -460, 206, 896, -528, 1434, -704, 449, +-282, -1068, 327, -1592, 697, -361, 350, 1206, +-212, 1572, -593, 271, -422, -1241, 60, -1395, +532, -187, 502, 1098, 64, 1138, -463, 93, +-572, -883, -107, -792, 397, -27, 538, 586, +231, 515, -321, 18, -581, -315, -250, -262, +274, -19, 457, -14, 318, 38, -90, 162, +-455, 256, -407, 106, 56, -239, 373, -470, +373, -193, 118, 390, -289, 552, -488, 161, +-141, -483, 290, -557, 408, -57, 242, 524, +-195, 526, -411, -63, -310, -550, 105, -398, +445, 179, 358, 488, -44, 299, -378, -274, +-494, -453, -30, -154, 490, 330, 535, 484, +29, 65, -555, -433, -555, -487, -5, -49, +579, 511, 632, 590, -50, 9, -696, -601, +-574, -641, 155, 9, 679, 723, 564, 659, +-161, -36, -732, -817, -506, -720, 247, 120, +686, 876, 434, 692, -169, -167, -589, -868, +-469, -621, 32, 258, 599, 783, 542, 456, +91, -367, -504, -648, -751, -187, -265, 446, +618, 453, 960, -111, 339, -531, -667, -189, +-1112, 458, -419, 540, 764, -131, 1227, -854, +479, -506, -771, 539, -1279, 1161, -512, 506, +740, -929, 1259, -1473, 648, -407, -641, 1237, +-1302, 1673, -716, 312, 530, -1459, 1298, -1719, +833, -218, -365, 1542, -1312, 1737, -974, 119, +315, -1501, 1266, -1628, 1031, -153, -184, 1345, +-1175, 1513, -1043, 282, 77, -1108, 1036, -1384, +990, -423, 79, 800, -755, 1248, -928, 592, +-326, -545, 539, -1123, 914, -682, 582, 340, +-273, 929, -909, 715, -829, -105, 67, -755, +1023, -675, 938, -90, 60, 444, -907, 601, +-1075, 344, -125, -124, 841, -502, 1035, -583, +305, -246, -690, 405, -1009, 792, -477, 564, +543, -288, 1114, -1014, 600, -800, -443, 211, +-1136, 1127, -755, 1025, 521, -164, 1220, -1236, +666, -1128, -537, 102, -1190, 1303, -529, 1195, +655, -98, 1057, -1268, 318, -1214, -661, 39, +-863, 1272, -121, 1132, 688, -33, 634, -1086, +-43, -1085, -614, -39, -443, 964, 193, 958, +540, 86, 293, -766, -265, -859, -436, -184, +-100, 613, 239, 821, 314, 236, 62, -505, +-225, -747, -142, -326, 14, 399, 86, 782, +20, 365, 7, -354, 52, -719, 82, -429, +36, 310, -201, 731, -251, 402, 43, -309, +376, -710, 391, -404, -69, 337, -518, 726, +-548, 332, 108, -345, 800, -709, 597, -343, +-223, 391, -841, 681, -669, 275, 330, -397, +973, -604, 552, -223, -363, 375, -920, 558, +-421, 152, 402, -389, 737, -435, 329, -86, +-382, 320, -529, 366, -117, 23, 256, -254, +302, -223, -46, 40, -158, 149, 31, 56, +140, -100, 77, -37, -230, 96, -346, 151, +44, -38, 479, -237, 456, -204, -62, 72, +-620, 344, -629, 323, 44, -79, 830, -426, +772, -480, -87, -51, -896, 579, -862, 764, +53, 153, 1016, -727, 922, -1089, -100, -318, +-1006, 968, -878, 1425, 94, 435, 906, -1206, +842, -1716, -86, -454, -795, 1379, -670, 1918, +18, 533, 607, -1529, 572, -2011, 8, -564, +-409, 1473, -421, 2073, -70, 670, 295, -1350, +286, -2039, 55, -857, -115, 1130, -168, 2031, +-24, 1038, 53, -855, 32, -1968, -37, -1292, +-2, 581, 111, 1882, 120, 1475, -7, -245, +-173, -1716, -267, -1611, -61, -104, 309, 1452, +391, 1739, 112, 446, -363, -1165, -520, -1750, +-201, -861, 446, 867, 667, 1840, 169, 1202, +-459, -562, -619, -1896, -249, -1573, 448, 271, +630, 1963, 218, 1874, -300, -40, -517, -1979, +-262, -2082, 126, -193, 418, 1984, 352, 2217, +8, 297, -281, -1929, -385, -2251, -177, -387, +201, 1851, 385, 2242, 275, 447, -69, -1767, +-329, -2181, -286, -499, -103, 1607, 178, 2099, +364, 566, 264, -1441, -13, -1964, -356, -611, +-476, 1256, -179, 1807, 392, 635, 726, -1054, +311, -1641, -475, -665, -852, 854, -427, 1470, +507, 705, 1015, -612, 459, -1304, -602, -786, +-1024, 345, -407, 1168, 573, 930, 979, -115, +367, -1032, -566, -1076, -864, -180, -262, 997, +520, 1265, 659, 343, 198, -934, -400, -1414, +-482, -552, -131, 913, 296, 1563, 304, 659, +78, -881, -146, -1587, -164, -787, -116, 805, +46, 1645, 141, 876, 74, -739, 11, -1601, +-82, -977, -123, 571, 5, 1605, 124, 1055, +92, -457, -21, -1500, -142, -1142, -114, 304, +53, 1426, 169, 1166, 164, -170, -59, -1298, +-250, -1191, -191, 24, 87, 1155, 315, 1199, +254, 106, -91, -984, -410, -1185, -286, -285, +111, 839, 472, 1138, 308, 401, -118, -638, +-436, -1083, -376, -516, 58, 498, 433, 998, +365, 568, 42, -318, -316, -890, -448, -666, +-176, 167, 241, 811, 470, 687, 304, 13, +-132, -639, -478, -768, -444, -169, 20, 535, +490, 731, 504, 263, 100, -356, -368, -707, +-600, -350, -258, 291, 303, 612, 601, 362, +380, -178, -130, -508, -615, -383, -555, 77, +27, 405, 537, 357, 682, 34, 184, -246, +-519, -336, -774, -149, -350, 80, 430, 254, +875, 257, 496, 82, -397, -149, -917, -311, +-554, -284, 337, 53, 878, 387, 574, 435, +-261, 32, -794, -439, -487, -594, 143, -126, +572, 502, 482, 695, -6, 204, -406, -498, +-387, -730, -138, -319, 147, 437, 329, 765, +272, 406, 6, -325, -209, -716, -338, -540, +-234, 172, 92, 724, 381, 664, 415, -45, +48, -712, -447, -756, -565, -89, -175, 713, +467, 853, 734, 119, 257, -705, -524, -840, +-800, -154, -305, 672, 531, 815, 833, 108, +330, -649, -510, -714, -829, -76, -317, 586, +445, 602, 743, 84, 361, -509, -374, -506, +-721, -64, -362, 403, 305, 383, 671, 64, +399, -292, -277, -325, -641, -67, -386, 266, +272, 260, 606, 25, 269, -202, -241, -223, +-518, -6, -225, 227, 232, 183, 397, -90, +140, -237, -115, -59, -271, 168, -178, 204, +-3, -31, 152, -270, 243, -178, 207, 194, +-114, 356, -409, 37, -337, -327, 77, -354, +561, 72, 557, 437, -133, 368, -745, -195, +-679, -566, 118, -319, 906, 284, 866, 604, +-143, 332, -1088, -295, -983, -673, 131, -352, +1213, 307, 1129, 706, -94, 394, -1364, -298, +-1253, -738, 122, -496, 1393, 276, 1309, 833, +-3, 586, -1446, -237, -1414, -869, -10, -704, +1342, 136, 1436, 903, 172, 819, -1212, -50, +-1453, -887, -341, -873, 1046, -85, 1401, 797, +536, 927, -766, 192, -1355, -704, -733, -902, +486, -269, 1251, 501, 947, 832, -197, 368, +-1118, -321, -1112, -702, -95, -404, 997, 92, +1226, 456, 344, 452, -871, 173, -1241, -248, +-528, -430, 676, -377, 1219, -57, 652, 396, +-489, 623, -1098, 302, -712, -353, 222, -776, +938, -555, 807, 260, -9, 950, -750, 766, +-813, -187, -260, -1028, 518, -932, 858, 85, +494, 1023, -295, 1096, -856, 64, -667, -1027, +27, -1176, 803, -238, 888, 902, 176, 1277, +-723, 478, -1031, -773, -408, -1366, 648, -675, +1129, 610, 591, 1350, -557, 914, -1176, -410, +-676, -1349, 436, -1046, 1126, 230, 733, 1206, +-283, 1107, -1006, 2, -736, -1024, 144, -1123, +781, -190, 756, 810, 72, 1035, -592, 326, +-720, -553, -255, -953, 368, -451, 667, 429, +435, 825, -125, 454, -626, -278, -564, -687, +-71, -457, 478, 184, 744, 553, 313, 361, +-421, -113, -812, -333, -537, -270, 328, 4, +966, 151, 702, 138, -269, 64, -1031, 52, +-836, -25, 203, -124, 1101, -231, 937, -48, +-144, 199, -1111, 333, -1012, 101, 52, -231, +1131, -447, 1108, -153, 6, 315, -1105, 509, +-1173, 187, -125, -337, 1125, -569, 1273, -263, +175, 359, -1074, 656, -1305, 292, -311, -379, +1020, -647, 1371, -358, 416, 350, -920, 735, +-1359, 350, -529, -370, 772, -714, 1367, -377, +640, 345, -633, 755, -1281, 399, -741, -374, +445, -740, 1188, -391, 846, 335, -210, 743, +-1056, 438, -920, -368, -76, -749, 902, -428, +1121, 304, 309, 776, -756, 494, -1224, -279, +-650, -782, 676, -542, 1408, 198, 843, 819, +-508, 618, -1512, -142, -1078, -843, 411, -734, +1549, 80, 1243, 903, -218, 887, -1490, -19, +-1384, -963, 13, -1046, 1382, -115, 1445, 1025, +277, 1231, -1149, 193, -1506, -1023, -545, -1331, +873, -365, 1527, 1022, 860, 1440, -557, 452, +-1525, -962, -1135, -1492, 314, -601, 1496, 868, +1367, 1551, -44, 760, -1487, -762, -1486, -1569, +-128, -896, 1405, 572, 1588, 1582, 243, 1068, +-1264, -426, -1576, -1529, -406, -1207, 1150, 243, +1526, 1479, 517, 1337, -932, -39, -1455, -1364, +-626, -1446, 722, -226, 1352, 1189, 768, 1534, +-510, 506, -1226, -919, -825, -1559, 253, -823, +1084, 665, 923, 1584, -39, 1059, -917, -415, +-951, -1553, -185, -1296, 761, 254, 976, 1588, +376, 1400, -538, -146, -995, -1543, -536, -1457, +359, 65, 958, 1481, 745, 1395, -192, -43, +-937, -1286, -861, -1238, 22, -36, 957, 1084, +986, 1029, 107, 78, -927, -794, -1109, -843, +-204, -175, 918, 547, 1189, 724, 309, 319, +-861, -301, -1222, -647, -446, -512, 839, 48, +1294, 635, 510, 703, -715, 165, -1289, -600, +-618, -912, 649, -352, 1261, 578, 735, 1038, +-483, 486, -1193, -536, -820, -1130, 267, -583, +1120, 517, 967, 1123, 26, 635, -995, -468, +-1155, -1098, -282, -662, 890, 420, 1329, 1031, +597, 668, -768, -310, -1461, -968, -814, -719, +616, 231, 1525, 896, 1052, 733, -399, -85, +-1507, -843, -1228, -756, 138, 15, 1423, 751, +1486, 743, 141, 33, -1321, -666, -1621, -698, +-446, -50, 1263, 552, 1799, 616, 648, 71, +-1123, -444, -1884, -502, -815, -78, 1035, 301, +1919, 365, 941, 126, -923, -141, -1852, -235, +-997, -143, 767, -14, 1788, 71, 1070, 194, +-654, 191, -1619, 33, -1049, -227, 462, -339, +1473, -120, 1049, 248, -303, 479, -1238, 205, +-972, -325, 119, -538, 1015, -235, 912, 302, +10, 588, -761, 284, -766, -297, -121, -551, +512, -286, 660, 231, 172, 497, -328, 308, +-427, -168, -201, -433, 104, -305, 318, 90, +200, 390, 41, 314, -115, -57, -185, -347, +-187, -301, 15, 2, 187, 326, 234, 298, +153, -44, -152, -273, -312, -203, -212, 57, +102, 240, 348, 116, 329, -171, -25, -211, +-372, 37, -425, 273, 4, 169, 406, -163, +483, -367, 136, -157, -420, 302, -547, 441, +-142, 81, 364, -415, 603, -483, 261, -8, +-315, 533, -599, 516, -281, -47, 256, -631, +561, -585, 367, 75, -157, 679, -515, 643, +-318, -13, 76, -673, 412, -712, 375, -73, +-10, 635, -284, 752, -364, 150, -53, -532, +253, -759, 366, -253, 147, 490, -218, 761, +-378, 290, -124, -399, 218, -744, 379, -360, +171, 369, -237, 754, -350, 382, -129, -305, +212, -694, 323, -406, 157, 257, -164, 647, +-292, 349, -152, -210, 122, -500, 279, -270, +164, 166, -49, 357, -224, 159, -173, -115, +4, -177, 151, -71, 173, 48, 86, 21, +-42, 21, -135, 50, -169, 86, -87, -35, +161, -136, 264, -148, 185, 60, -125, 217, +-345, 121, -261, -137, 101, -218, 419, -31, +312, 195, -27, 183, -423, -106, -416, -306, +-17, -131, 438, 254, 513, 398, 134, 62, +-434, -395, -600, -500, -199, -74, 437, 515, +688, 620, 246, 90, -409, -597, -704, -745, +-275, -159, 428, 627, 687, 861, 325, 270, +-343, -672, -683, -983, -313, -367, 319, 635, +612, 1074, 401, 493, -193, -585, -596, -1126, +-444, -585, 110, 491, 582, 1109, 555, 662, +53, -342, -545, -1043, -652, -749, -154, 226, +578, 945, 765, 778, 282, -32, -524, -827, +-825, -828, -335, -94, 518, 695, 863, 839, +406, 257, -376, -526, -823, -799, -459, -372, +310, 359, 740, 700, 545, 466, -111, -121, +-678, -549, -597, -507, 20, -53, 596, 396, +668, 542, 128, 261, -555, -260, -694, -559, +-189, -395, 515, 165, 714, 610, 283, 539, +-445, -66, -757, -614, -329, -637, 406, -21, +728, 611, 439, 669, -312, 122, -771, -527, +-484, -651, 233, -182, 753, 415, 569, 576, +-172, 185, -742, -313, -605, -453, 102, -189, +741, 209, 623, 350, -94, 125, -723, -146, +-607, -226, 115, -97, 691, 66, 554, 101, +-129, 20, -651, -58, -484, 10, 170, 53, +617, 15, 378, -107, -163, -160, -511, -78, +-351, 142, 177, 247, 465, 86, 299, -151, +-109, -306, -380, -181, -278, 104, 81, 299, +328, 192, 277, -34, -3, -282, -205, -250, +-238, -21, -54, 203, 151, 242, 219, 87, +151, -147, 6, -254, -173, -127, -219, 87, +-30, 216, 192, 182, 285, -4, 137, -197, +-169, -207, -300, -36, -96, 142, 182, 234, +316, 119, 156, -88, -123, -192, -263, -134, +-146, 35, 102, 153, 252, 162, 209, 56, +16, -44, -222, -111, -227, -94, -14, -56, +236, 79, 286, 181, 62, 176, -226, 24, +-262, -182, -22, -245, 226, -87, 235, 210, +16, 332, -195, 195, -149, -112, 50, -348, +126, -306, 69, 18, -56, 363, -78, 448, +-2, 180, 88, -321, 27, -575, -83, -335, +-92, 290, -23, 714, 66, 501, 102, -248, +55, -813, -76, -616, -126, 195, -114, 871, +-5, 706, 185, -170, 211, -920, 7, -782, +-231, 66, -295, 864, -71, 851, 293, 4, +347, -837, 36, -895, -309, -153, -365, 733, +-74, 918, 292, 215, 355, -714, 72, -980, +-237, -311, -307, 662, -118, 994, 161, 341, +290, -709, 147, -1067, -95, -389, -206, 674, +-143, 1064, 29, 372, 185, -718, 159, -1073, +54, -374, -47, 669, -114, 1005, -116, 298, +-29, -680, 146, -947, 271, -231, 155, 660, +-137, 844, -335, 158, -163, -671, 219, -784, +460, -71, 244, 666, -219, 697, -449, 38, +-174, -666, 265, -643, 450, 63, 227, 696, +-180, 621, -362, -63, -176, -701, 167, -601, +328, 114, 235, 748, -42, 663, -234, -60, +-203, -724, 15, -667, 205, 64, 226, 743, +57, 732, -127, 54, -173, -672, -40, -713, +102, -78, 124, 637, 37, 729, -41, 195, +-19, -510, 12, -690, -13, -207, -79, 433, +-62, 657, 82, 311, 192, -296, 77, -587, +-197, -322, -318, 200, -66, 528, 287, 371, +375, -71, 11, -441, -438, -399, -450, -21, +53, 342, 510, 395, 415, 136, -167, -257, +-586, -434, -419, -250, 206, 136, 573, 404, +329, 342, -248, -72, -571, -436, -308, -451, +204, -46, 470, 376, 265, 473, -176, 76, +-402, -410, -228, -532, 94, -155, 289, 340, +186, 472, -45, 105, -171, -395, -103, -467, +15, -113, 53, 326, 13, 379, 46, 0, +88, -394, 116, -332, -7, 45, -214, 333, +-181, 221, 73, -162, 338, -386, 319, -152, +-43, 247, -376, 355, -310, 58, 90, -340, +481, -411, 415, -37, -56, 422, -448, 463, +-386, 58, 105, -436, 538, -515, 463, -112, +-42, 439, -527, 594, -430, 240, 137, -368, +603, -592, 496, -289, -96, 327, -600, 649, +-445, 419, 187, -216, 630, -614, 484, -424, +-124, 195, -575, 664, -464, 547, 121, -49, +574, -598, 469, -556, -43, 30, -494, 622, +-498, 658, 18, 126, 499, -520, 465, -645, +-8, -146, -459, 508, -439, 676, 6, 260, +397, -370, 344, -626, -56, -294, -343, 312, +-272, 616, 25, 397, 220, -168, 137, -567, +-50, -485, -140, 31, -100, 520, -17, 593, +8, 109, -23, -481, -3, -661, 57, -272, +32, 381, -59, 669, -144, 323, -149, -353, +18, -679, 210, -422, 184, 187, -51, 600, +-292, 419, -282, -176, 10, -602, 337, -517, +341, -2, -39, 498, -395, 525, -364, 38, +11, -532, 428, -652, 417, -214, -21, 415, +-406, 636, -388, 236, 40, -433, 423, -740, +381, -362, 23, 341, -338, 717, -326, 382, +18, -373, 316, -809, 331, -478, 91, 341, +-178, 821, -252, 507, -98, -371, 165, -884, +328, -549, 220, 360, -44, 901, -254, 559, +-230, -349, 85, -858, 350, -516, 294, 322, +0, 818, -246, 532, -236, -215, 27, -674, +265, -443, 267, 153, 56, 583, -124, 504, +-182, 22, -105, -398, 92, -402, 233, -73, +203, 316, 9, 467, -215, 236, -264, -126, +-50, -317, 250, -223, 322, 81, 71, 304, +-256, 313, -340, 100, -97, -112, 220, -236, +324, -158, 96, 49, -232, 276, -341, 334, +-134, 132, 178, -212, 280, -421, 121, -231, +-191, 223, -340, 560, -162, 385, 138, -174, +279, -636, 127, -496, -167, 123, -346, 658, +-202, 558, 126, -66, 281, -647, 150, -630, +-137, -32, -318, 546, -230, 574, 74, 55, +258, -504, 180, -610, -56, -188, -210, 344, +-217, 489, -37, 171, 139, -303, 189, -518, +116, -304, -62, 121, -187, 372, -215, 263, +-33, -103, 235, -388, 314, -344, 117, -64, +-210, 240, -391, 279, -161, 35, 290, -246, +513, -317, 258, -156, -276, 111, -544, 256, +-269, 159, 344, -78, 699, -260, 371, -278, +-294, -74, -657, 219, -346, 351, 348, 172, +730, -217, 441, -480, -229, -283, -612, 250, +-357, 619, 218, 385, 565, -262, 407, -701, +-57, -398, -366, 372, -303, 811, 15, 450, +257, -345, 281, -777, 135, -374, -52, 459, +-185, 819, -175, 391, -37, -368, 135, -693, +250, -271, 169, 444, -72, 714, -271, 301, +-241, -335, 14, -536, 266, -178, 286, 372, +54, 562, -306, 200, -366, -271, -110, -389, +225, -91, 388, 287, 153, 398, -296, 143, +-486, -188, -251, -282, 219, -110, 480, 129, +266, 271, -244, 199, -579, -18, -370, -225, +158, -261, 517, -115, 378, 178, -151, 317, +-553, 199, -463, -132, 44, -391, 473, -346, +437, 19, -31, 348, -473, 359, -451, 24, +-66, -384, 373, -477, 411, -164, 63, 275, +-308, 416, -379, 153, -129, -315, 224, -529, +362, -283, 160, 202, -168, 452, -324, 242, +-185, -251, 131, -552, 371, -362, 251, 137, +-106, 453, -331, 294, -227, -166, 123, -472, +425, -374, 323, 41, -98, 333, -397, 291, +-278, -19, 175, -278, 492, -301, 350, -117, +-117, 134, -454, 265, -268, 192, 189, -20, +475, -243, 341, -312, -87, -107, -368, 221, +-274, 426, 65, 263, 383, -139, 390, -446, +58, -360, -307, 87, -378, 515, -77, 524, +359, 92, 454, -408, 101, -553, -340, -165, +-398, 445, -52, 719, 312, 380, 364, -303, +51, -726, -253, -461, -249, 333, -86, 901, +80, 669, 195, -173, 154, -873, 14, -703, +-173, 198, -312, 964, -201, 819, 147, -63, +396, -869, 256, -741, -201, 119, -541, 864, +-421, 717, 130, -76, 568, -740, 434, -588, +-149, 149, -629, 671, -576, 471, 16, -146, +572, -538, 552, -356, 12, 142, -554, 386, +-629, 199, -177, -129, 406, -239, 597, -124, +248, 37, -312, 52, -635, -33, -431, -56, +166, 20, 609, 46, 528, -31, -59, -157, +-633, -163, -643, -51, -33, 107, 625, 128, +707, -13, 119, -182, -590, -222, -719, -115, +-149, 83, 560, 171, 723, 67, 228, -125, +-434, -244, -639, -190, -219, 6, 396, 171, +595, 129, 302, -33, -218, -199, -453, -211, +-237, -56, 177, 164, 402, 190, 261, 27, +-38, -201, -217, -268, -155, -41, 44, 281, +151, 332, 131, 13, 44, -379, 32, -412, +37, 30, -20, 513, -97, 513, -100, -27, +67, -561, 250, -517, 233, 103, -40, 662, +-336, 589, -303, -71, 96, -616, 431, -503, +366, 164, -106, 680, -512, 539, -387, -109, +156, -582, 558, -438, 357, 188, -226, 629, +-596, 487, -355, -83, 256, -493, 572, -379, +260, 107, -333, 474, -586, 410, -253, 19, +296, -297, 513, -294, 163, -36, -351, 224, +-537, 302, -188, 157, 286, -70, 422, -219, +131, -217, -307, -28, -441, 207, -157, 315, +185, 156, 307, -166, 123, -393, -154, -272, +-260, 116, -190, 413, 10, 334, 156, -101, +185, -490, 92, -428, -124, 26, -290, 434, +-199, 418, 77, -26, 329, -478, 280, -501, +-72, -74, -376, 340, -327, 409, 61, 82, +441, -358, 383, -475, -11, -192, -401, 178, +-419, 336, -16, 166, 442, -170, 521, -372, +122, -239, -382, 48, -533, 233, -177, 161, +402, -73, 678, -250, 298, -182, -337, 31, +-627, 159, -330, 86, 328, -96, 723, -170, +421, -72, -233, 108, -640, 163, -408, 31, +207, -162, 617, -182, 482, -15, -97, 205, +-519, 227, -403, 38, 32, -206, 433, -266, +449, -25, 92, 280, -301, 332, -412, 87, +-181, -241, 202, -358, 426, -77, 287, 363, +-106, 490, -429, 159, -371, -321, 19, -507, +379, -175, 385, 441, 62, 684, -328, 285, +-442, -378, -198, -670, 220, -301, 396, 425, +239, 792, -133, 419, -461, -320, -369, -722, +53, -408, 372, 298, 322, 743, -32, 503, +-358, -166, -363, -650, -56, -497, 230, 120, +233, 598, 53, 543, -140, 2, -240, -519, +-163, -546, 24, -56, 164, 433, 154, 511, +1, 129, -195, -359, -217, -509, -26, -205, +167, 253, 172, 424, -12, 211, -165, -182, +-156, -421, 6, -313, 144, 57, 127, 319, +-9, 263, -124, -39, -86, -334, 33, -334, +115, -78, 111, 215, 4, 243, -124, 30, +-89, -216, 64, -266, 168, -112, 120, 96, +-36, 150, -183, 37, -111, -95, 139, -137, +266, -75, 126, -18, -133, 33, -257, 29, +-89, 13, 228, -15, 332, -57, 71, -93, +-233, -53, -262, 65, -1, 118, 276, 55, +276, -78, -8, -159, -235, -85, -181, 114, +52, 192, 217, 68, 162, -89, -44, -151, +-165, -19, -114, 135, 58, 153, 161, 13, +67, -88, -93, -53, -145, 70, -16, 135, +107, 74, 106, -34, -31, -76, -164, 9, +-109, 106, 83, 133, 154, 33, 52, -54, +-111, -68, -201, 12, -91, 112, 128, 131, +185, 55, 48, -45, -157, -80, -244, -28, +-125, 64, 129, 121, 270, 111, 89, 24, +-197, -87, -325, -108, -169, -37, 174, 102, +342, 190, 116, 110, -251, -102, -396, -218, +-132, -122, 247, 98, 367, 253, 86, 150, +-291, -126, -362, -303, -66, -197, 266, 85, +291, 294, 14, 219, -217, -82, -213, -349, +-37, -309, 128, -2, 137, 297, 46, 310, +-4, 2, -51, -339, -111, -391, -82, -99, +33, 250, 178, 329, 187, 63, 25, -278, +-202, -371, -233, -147, 12, 175, 271, 289, +255, 104, 37, -178, -239, -309, -256, -177, +19, 97, 261, 247, 260, 133, -17, -88, +-228, -226, -163, -165, 79, 23, 242, 136, +131, 95, -98, -3, -177, -58, -44, -52, +151, -38, 168, -24, -5, 10, -141, 70, +-114, 110, 37, 44, 183, -84, 100, -134, +-74, -28, -150, 134, -87, 188, 69, 74, +167, -98, 89, -158, -87, -28, -171, 144, +-94, 192, 51, 80, 147, -68, 108, -116, +-60, -11, -164, 106, -137, 140, 2, 48, +118, -55, 145, -36, 21, 37, -150, 76, +-197, 60, -81, 0, 98, -30, 183, 23, +100, 60, -98, 34, -236, -8, -167, -20, +29, 6, 205, 55, 186, 71, -34, 12, +-227, -77, -238, -78, -27, -5, 186, 95, +210, 135, 45, 21, -168, -136, -239, -191, +-95, -53, 108, 141, 186, 205, 109, 62, +-40, -168, -165, -254, -177, -112, -47, 97, +138, 202, 230, 96, 140, -92, -118, -206, +-296, -179, -201, -40, 128, 115, 364, 152, +260, 66, -97, -99, -389, -244, -286, -212, +104, 3, 418, 217, 332, 235, -60, 10, +-385, -272, -320, -355, 47, -120, 388, 232, +371, 346, 0, 136, -330, -230, -339, -401, +-16, -219, 330, 172, 354, 393, 36, 232, +-286, -129, -283, -382, -18, -278, 246, 101, +272, 375, 32, 291, -216, -56, -204, -342, +-13, -272, 179, 76, 175, 351, 7, 297, +-145, -45, -150, -316, 8, -239, 124, 99, +137, 332, 1, 262, -151, -60, -159, -278, +-7, -177, 181, 136, 153, 316, -41, 195, +-215, -85, -193, -272, 34, -144, 238, 162, +192, 335, -82, 198, -290, -119, -220, -305, +64, -185, 270, 158, 203, 382, -80, 243, +-300, -119, -248, -360, 46, -250, 283, 123, +214, 398, -59, 284, -303, -95, -239, -365, +86, -300, 261, 60, 123, 343, -114, 297, +-211, -22, -61, -321, 129, -318, 113, -30, +-59, 235, -149, 276, -15, 51, 160, -209, +120, -284, -97, -107, -234, 115, -112, 191, +169, 75, 304, -98, 101, -188, -220, -126, +-317, 17, -104, 74, 229, 58, 352, 1, +147, -77, -202, -119, -353, -80, -168, 1, +165, 70, 356, 83, 260, 8, -66, -135, +-349, -162, -329, -58, 24, 81, 396, 159, +432, 67, 58, -111, -395, -202, -456, -113, +-47, 73, 398, 200, 464, 139, 90, -52, +-330, -197, -418, -168, -114, 26, 294, 205, +383, 187, 155, 18, -154, -167, -332, -188, +-232, -21, 80, 175, 314, 230, 299, 93, +-1, -110, -320, -195, -342, -86, -46, 126, +301, 261, 358, 150, 72, -79, -278, -207, +-367, -123, -110, 113, 219, 276, 323, 170, +115, -78, -192, -208, -291, -100, -131, 103, +85, 219, 204, 125, 132, -61, -44, -130, +-150, -55, -162, 52, -72, 105, 51, 69, +162, 24, 122, -36, -30, -58, -173, -60, +-200, -17, -48, 62, 162, 119, 226, 59, +71, -82, -182, -155, -263, -103, -106, 45, +148, 149, 272, 99, 118, -61, -158, -162, +-269, -129, -131, -1, 117, 92, 259, 90, +140, 5, -117, -103, -227, -129, -135, -71, +77, -1, 218, 83, 151, 104, -36, -25, +-201, -153, -166, -183, 40, -51, 219, 139, +175, 186, -18, 22, -180, -213, -182, -258, +20, -37, 203, 196, 184, 237, 12, 22, +-158, -226, -202, -267, -29, -36, 189, 205, +223, 246, 79, 51, -155, -181, -261, -243, +-105, -85, 176, 162, 312, 256, 120, 134, +-158, -105, -277, -228, -144, -160, 127, 60, +282, 233, 195, 228, -57, 30, -271, -147, +-245, -215, 4, -97, 264, 144, 315, 286, +44, 191, -285, -55, -343, -252, -91, -227, +238, 72, 358, 342, 143, 319, -222, -10, +-392, -343, -182, -333, 158, 21, 346, 415, +243, 448, -98, 24, -364, -429, -309, -467, +34, -35, 337, 486, 306, 552, 3, 67, +-324, -515, -313, -589, -28, -57, 205, 560, +226, 625, 91, 63, -97, -586, -246, -654, +-192, -63, -1, 597, 207, 639, 238, 47, +68, -600, -198, -660, -323, -93, -136, 568, +190, 623, 352, 58, 154, -549, -178, -634, +-344, -119, -215, 481, 126, 575, 339, 94, +251, -463, -61, -562, -315, -163, -313, 337, +2, 477, 360, 165, 337, -285, 7, -461, +-310, -236, -337, 141, -26, 374, 298, 277, +316, -81, 39, -350, -228, -328, -231, -33, +-46, 276, 159, 316, 189, 84, 91, -214, +-46, -316, -127, -141, -88, 130, -23, 267, +68, 205, 155, -30, 121, -241, -29, -236, +-156, -20, -182, 233, -21, 304, 204, 99, +241, -219, 68, -320, -207, -79, -286, 267, +-88, 362, 184, 129, 326, -240, 140, -348, +-187, -98, -340, 271, -156, 388, 165, 150, +331, -207, 180, -361, -172, -146, -320, 226, +-161, 409, 124, 206, 277, -175, 152, -390, +-107, -222, -256, 172, -142, 425, 90, 279, +206, -106, 102, -410, -98, -312, -184, 57, +-87, 388, 82, 395, 132, 39, 31, -370, +-105, -436, -107, -115, -10, 327, 63, 491, +47, 166, -29, -337, -39, -517, 14, -208, +-1, 300, -55, 500, -58, 189, 54, -309, +114, -523, 36, -208, -106, 269, -187, 454, +-44, 195, 179, -266, 217, -468, 13, -232, +-227, 197, -250, 400, -34, 208, 280, -200, +343, -409, 38, -238, -339, 162, -408, 355, +-44, 174, 402, -205, 483, -345, 71, -139, +-432, 210, -540, 298, -82, 51, 464, -261, +581, -273, 158, 24, -455, 265, -610, 196, +-176, -87, 435, -266, 631, -124, 240, 153, +-340, 228, -628, 50, -310, -169, 310, -165, +627, 28, 360, 184, -220, 128, -553, -50, +-396, -147, 107, -31, 508, 110, 451, 120, +-2, 18, -432, -86, -492, -50, -113, 74, +382, 126, 523, 51, 167, -69, -307, -96, +-495, 0, -257, 108, 210, 114, 489, 10, +332, -75, -124, -53, -482, 36, -411, 65, +36, 3, 458, -26, 478, 8, 14, 73, +-469, 54, -495, -64, -55, -143, 425, -35, +479, 161, 78, 194, -395, -6, -486, -231, +-100, -216, 333, 63, 448, 296, 111, 195, +-308, -158, -419, -364, -137, -182, 279, 205, +367, 366, 94, 136, -231, -268, -319, -404, +-108, -123, 194, 259, 237, 355, 57, 97, +-130, -276, -181, -344, -76, -96, 53, 216, +132, 279, 108, 47, -10, -212, -110, -236, +-143, -62, -33, 137, 110, 154, 158, 21, +70, -90, -84, -77, -181, -41, -125, -28, +54, -20, 242, 44, 204, 133, -70, 106, +-310, -67, -242, -256, 109, -194, 366, 109, +281, 346, -105, 245, -414, -116, -305, -411, +139, -286, 449, 161, 334, 463, -103, 313, +-456, -144, -367, -461, 85, -331, 459, 153, +424, 510, -1, 387, -457, -110, -489, -489, +-34, -416, 456, 93, 519, 530, 91, 477, +-408, -8, -527, -483, -155, -476, 341, -12, +502, 445, 246, 496, -234, 97, -487, -357, +-323, -430, 97, -131, 469, 269, 428, 405, +1, 193, -437, -158, -501, -337, -87, -237, +405, 69, 508, 292, 158, 277, -346, 42, +-518, -236, -228, -300, 246, -103, 497, 170, +260, 300, -192, 157, -447, -120, -305, -293, +91, -193, 361, 72, 314, 246, -4, 183, +-306, -54, -322, -239, -77, -198, 222, 18, +317, 185, 109, 155, -165, -19, -273, -167, +-173, -151, 56, -19, 237, 107, 219, 105, +8, 16, -216, -74, -257, -103, -70, -69, +181, 21, 256, 72, 104, 74, -148, -7, +-258, -77, -122, -86, 121, -22, 246, 62, +118, 54, -106, -24, -197, -56, -82, -8, +79, 54, 130, 48, 84, -47, 5, -111, +-98, -30, -127, 107, -21, 147, 118, 24, +151, -131, 44, -157, -114, -5, -174, 171, +-27, 173, 134, 10, 159, -149, 39, -142, +-125, 27, -153, 154, -37, 143, 113, 5, +162, -122, 62, -92, -106, 14, -139, 94, +-56, 79, 84, 8, 172, -32, 68, -28, +-65, 2, -141, 17, -77, 1, 31, 6, +104, 35, 119, 55, 28, 28, -88, -26, +-143, -83, -108, -60, 64, 42, 216, 121, +161, 90, -79, -21, -265, -132, -174, -134, +98, 2, 258, 140, 186, 154, -73, 34, +-263, -148, -207, -210, 18, -84, 256, 137, +251, 271, 10, 135, -277, -161, -309, -348, +-16, -235, 297, 143, 301, 411, -4, 289, +-302, -152, -265, -481, -8, -354, 234, 130, +238, 473, 14, 357, -182, -117, -232, -483, +-81, -372, 156, 95, 262, 431, 81, 342, +-196, -97, -248, -429, -50, -330, 225, 91, +211, 392, -52, 271, -218, -113, -114, -361, +121, -220, 169, 144, -1, 311, -164, 118, +-88, -180, 97, -248, 161, -27, 11, 213, +-110, 187, -113, -46, -24, -223, 80, -137, +104, 112, 90, 243, -34, 147, -182, -103, +-142, -270, 66, -154, 255, 125, 161, 313, +-109, 201, -247, -126, -140, -341, 114, -208, +229, 167, 149, 400, -34, 223, -204, -195, +-204, -398, -11, -184, 202, 212, 268, 391, +87, 189, -191, -162, -324, -313, -136, -190, +218, 57, 380, 249, 168, 238, -209, 55, +-371, -177, -171, -274, 209, -152, 346, 119, +164, 302, -141, 231, -311, -77, -204, -314, +101, -244, 303, 38, 205, 284, -51, 246, +-271, -9, -217, -247, 16, -263, 207, -59, +252, 196, 62, 268, -185, 101, -310, -178, +-128, -299, 216, -152, 356, 139, 141, 287, +-270, 147, -391, -144, -81, -288, 303, -155, +370, 127, 32, 245, -345, 96, -330, -129, +13, -216, 325, -94, 287, 111, -32, 174, +-273, 77, -296, -98, -44, -180, 279, -99, +326, 81, 69, 184, -307, 103, -383, -98, +-42, -197, 350, -104, 391, 87, -26, 205, +-396, 110, -319, -102, 61, -201, 368, -101, +259, 111, -89, 207, -287, 89, -210, -95, +57, -184, 203, -91, 196, 62, 39, 150, +-162, 138, -200, 10, -79, -116, 162, -182, +227, -102, 47, 128, -161, 266, -173, 179, +-1, -93, 156, -347, 111, -227, -41, 150, +-85, 399, -37, 263, 39, -175, 47, -428, +8, -217, -42, 199, -16, 443, 65, 220, +56, -225, -37, -389, -105, -189, -54, 210, +62, 394, 147, 147, 79, -195, -89, -306, +-149, -118, -103, 181, 86, 231, 199, 58, +92, -120, -108, -143, -223, -16, -60, 68, +185, 36, 173, 3, -7, 12, -178, 20, +-153, -31, 75, -118, 171, -66, 109, 108, +-90, 184, -188, 47, -60, -213, 111, -236, +161, 8, 24, 250, -134, 231, -136, -65, +5, -302, 138, -198, 110, 109, -35, 287, +-137, 134, -137, -161, 13, -254, 195, -84, +148, 160, -46, 207, -227, 39, -182, -148, +62, -170, 236, -72, 207, 105, -69, 194, +-281, 93, -236, -90, 72, -230, 351, -152, +257, 112, -163, 295, -421, 165, -221, -146, +235, -352, 445, -167, 152, 231, -280, 388, +-427, 121, -115, -280, 308, -396, 387, -54, +86, 326, -304, 371, -370, 42, -50, -352, +298, -346, 334, 27, 49, 366, -294, 358, +-345, -47, -42, -422, 315, -320, 392, 100, +44, 449, -379, 374, -413, -122, 18, -525, +424, -411, 406, 168, -41, 632, -445, 474, +-347, -222, 87, -750, 440, -508, 294, 335, +-133, 865, -371, 500, -227, -422, 144, -958, +325, -463, 155, 559, -112, 1023, -216, 383, +-139, -697, 56, -1044, 177, -263, 125, 807, +-24, 1033, -114, 123, -88, -888, 1, -946, +31, -3, 6, 947, 37, 842, 90, -187, +57, -956, -82, -672, -204, 322, -88, 935, +152, 461, 251, -489, 82, -849, -182, -270, +-253, 584, -89, 750, 150, 71, 245, -667, +117, -658, -94, 99, -232, 719, -237, 519, +22, -250, 294, -754, 322, -428, 3, 370, +-363, 776, -370, 330, 0, -476, 376, -810, +364, -292, -2, 550, -354, 834, -334, 241, +-7, -591, 279, -812, 290, -232, 4, 581, +-222, 796, -195, 208, -22, -553, 117, -764, +117, -206, 69, 540, 32, 694, -73, 174, +-195, -473, -122, -613, 98, -165, 298, 382, +182, 530, -167, 215, -359, -252, -140, -489, +219, -278, 323, 168, 96, 452, -184, 345, +-254, -85, -52, -434, 121, -359, 154, 53, +95, 431, -17, 375, -119, -68, -175, -391, +-47, -337, 192, 42, 268, 396, 73, 312, +-279, -20, -364, -309, 23, -375, 379, -51, +391, 334, -64, 410, -486, 140, -361, -328, +147, -514, 535, -181, 360, 353, -231, 609, +-567, 246, -297, -443, 281, -710, 589, -289, +259, 527, -271, 867, -579, 262, -320, -613, +290, -939, 581, -337, 373, 684, -238, 1030, +-650, 365, -416, -678, 257, -1112, 656, -452, +388, 656, -241, 1151, -605, 539, -372, -627, +205, -1177, 526, -635, 337, 511, -140, 1244, +-436, 739, -330, -498, 33, -1247, 365, -865, +329, 414, 26, 1318, -251, 908, -353, -347, +-124, -1303, 185, -1000, 294, 270, 195, 1254, +-85, 1038, -259, -163, -229, -1190, -46, -1016, +148, 49, 280, 1018, 216, 1026, -98, 68, +-378, -868, -317, -963, 71, -235, 460, 698, +391, 971, -132, 344, -497, -550, -347, -930, +156, -485, 476, 402, 310, 928, -142, 592, +-456, -279, -205, -890, 141, -679, 315, 173, +181, 856, -122, 731, -192, -64, -83, -771, +21, -749, 69, -34, 103, 721, 70, 798, +-16, 73, -162, -712, -88, -780, 97, -86, +233, 727, 57, 793, -256, 32, -260, -726, +108, -727, 400, -12, 243, 710, -254, 699, +-542, -16, -163, -665, 451, -595, 579, 9, +74, 555, -550, 545, -607, 49, 26, -454, +611, -508, 572, -142, -24, 344, -588, 564, +-585, 258, -23, -315, 569, -653, 628, -372, +62, 301, -520, 752, -617, 485, -152, -325, +476, -868, 581, -513, 158, 344, -336, 884, +-502, 532, -269, -360, 191, -852, 432, -453, +327, 320, -12, 713, -396, 407, -443, -270, +-109, -584, 356, -314, 496, 181, 197, 393, +-318, 245, -517, -36, -248, -217, 210, -222, +469, -138, 307, -2, -87, 235, -386, 364, +-364, 162, -67, -286, 260, -543, 391, -299, +254, 297, -147, 707, -436, 396, -389, -366, +-18, -748, 478, -392, 550, 342, 92, 733, +-489, 360, -672, -319, -188, -587, 517, -319, +759, 174, 293, 452, -528, 336, -858, -2, +-339, -314, 525, -385, 943, -193, 399, 177, +-563, 490, -933, 397, -391, -106, 538, -548, +928, -532, 373, -1, -481, 594, -860, 632, +-380, 63, 458, -549, 839, -661, 392, -179, +-424, 482, -830, 698, -403, 273, 450, -385, +850, -676, 393, -386, -507, 281, -839, 684, +-302, 490, 569, -171, 789, -694, 181, -620, +-543, 54, -651, 736, -125, 759, 465, 26, +564, -768, 150, -835, -396, -118, -551, 761, +-158, 899, 377, 166, 558, -724, 154, -901, +-396, -218, -496, 678, -135, 880, 312, 245, +442, -620, 140, -836, -203, -262, -374, 522, +-243, 805, 110, 314, 382, -440, 289, -753, +-72, -373, -389, 299, -330, 678, 52, 467, +399, -104, 326, -592, -103, -604, -374, -95, +-281, 488, 107, 744, 340, 334, 192, -465, +-125, -882, -245, -486, -108, 421, 70, 1008, +154, 597, 74, -428, -50, -1077, -91, -670, +-48, 422, 40, 1067, 80, 710, 20, -318, +-67, -1025, -90, -780, -15, 183, 127, 900, +123, 866, 12, 46, -180, -801, -226, -940, +43, -241, 262, 650, 274, 961, -21, 432, +-377, -489, -308, -958, 90, -573, 395, 319, +330, 888, -69, 712, -380, -116, -345, -807, +8, -826, 324, -106, 377, 674, 209, 927, +-235, 380, -526, -531, -355, -1036, 179, -636, +691, 333, 556, 1042, -163, 887, -804, -104, +-654, -991, 186, -1071, 848, -202, 719, 843, +-113, 1216, -857, 523, -734, -640, 71, -1316, +773, -842, 778, 408, 25, 1365, -705, 1152, +-771, -158, -113, -1379, 618, -1403, 727, -107, +204, 1326, -491, 1600, -648, 387, -222, -1171, +300, -1755, 483, -718, 280, 973, -72, 1805, +-294, 1070, -327, -651, -213, -1821, 86, -1398, +450, 294, 433, 1741, 25, 1704, -472, 114, +-634, -1605, -168, -1960, 488, -497, 736, 1469, +301, 2101, -444, 845, -823, -1214, -458, -2220, +358, -1157, 884, 980, 544, 2180, -247, 1468, +-842, -593, -698, -2131, 86, -1777, 780, 211, +775, 2003, 119, 2037, -654, 245, -900, -1826, +-341, -2291, 534, -637, 983, 1652, 552, 2387, +-396, 974, -1079, -1385, -721, -2444, 317, -1219, +1081, 1120, 852, 2316, -181, 1411, -1040, -756, +-936, -2178, 27, -1608, 946, 394, 1024, 1978, +192, 1756, -843, -3, -1123, -1774, -325, -1933, +764, -331, 1136, 1555, 465, 1948, -617, 629, +-1105, -1257, -550, -1919, 448, -836, 999, 924, +672, 1737, -236, 1010, -880, -542, -751, -1540, +49, -1155, 764, 181, 801, 1321, 171, 1253, +-619, 140, -862, -1086, -341, -1324, 449, -384, +855, 865, 572, 1292, -267, 612, -854, -597, +-729, -1228, 28, -773, 845, 285, 959, 1077, +148, 932, -846, 41, -1109, -876, -303, -1032, +850, -353, 1201, 672, 405, 1089, -815, 583, +-1225, -435, -474, -1072, 710, -731, 1178, 241, +559, 984, -556, 813, -1103, -45, -674, -805, +322, -833, 1032, -160, 825, 638, -117, 817, +-996, 358, -981, -370, -82, -762, 938, -535, +1106, 114, 223, 652, -886, 682, -1154, 191, +-386, -464, 784, -792, 1210, -510, 509, 271, +-665, 830, -1229, 766, -637, 11, 520, -855, +1217, -982, 764, -200, -374, 786, -1201, 1113, +-892, 423, 210, -718, 1200, -1192, 1034, -589, +-132, 576, -1164, 1179, -1088, 737, 68, -385, +1147, -1139, 1045, -870, -53, 164, -997, 970, +-960, 948, 18, 151, 831, -779, 815, -1011, +64, -455, -607, 479, -645, 1025, -174, 773, +338, -194, 542, -1018, 315, -1046, -96, -107, +-413, 974, -478, 1260, -110, 367, 370, -940, +572, -1421, 280, -580, -284, 872, -604, 1504, +-402, 720, 182, -785, 630, -1516, 526, -855, +-61, 650, -626, 1477, -615, 915, -8, -489, +605, -1343, 670, -955, 75, 299, -551, 1191, +-644, 906, -150, -133, 454, -947, 607, -804, +237, -33, -307, 695, -571, 694, -336, 143, +186, -414, 513, -508, 451, -280, -76, 117, +-502, 409, -472, 372, -22, 131, 450, -217, +484, -478, 80, -365, -351, 128, -478, 512, +-185, 528, 248, 51, 455, -476, 300, -643, +-192, -203, -454, 413, -340, 667, 96, 376, +429, -224, 373, -669, -31, -560, -401, 99, +-391, 602, -43, 675, 349, 149, 416, -551, +86, -806, -310, -301, -391, 454, -143, 847, +279, 492, 371, -332, 148, -899, -212, -655, +-364, 234, -145, 844, 177, 771, 314, -34, +165, -805, -127, -897, -261, -142, -168, 663, +36, 949, 256, 397, 189, -527, 8, -1035, +-207, -617, -222, 386, -13, 995, 186, 787, +217, -192, 58, -991, -143, -921, -211, 33, +-103, 849, 95, 984, 255, 196, 190, -745, +-71, -1051, -291, -424, -227, 578, 57, 1063, +333, 626, 287, -380, -31, -1053, -355, -831, +-360, 199, 12, 945, 404, 920, 444, 70, +46, -795, -457, -1002, -539, -325, -22, 581, +529, 989, 567, 573, 36, -303, -578, -925, +-587, -821, 5, 57, 555, 825, 551, 959, +53, 285, -474, -640, -557, -1120, -161, -588, +381, 481, 580, 1176, 279, 914, -282, -181, +-654, -1206, -417, -1213, 254, -44, 668, 1148, +475, 1418, -155, 414, -707, -1003, -553, -1607, +88, -689, 653, 828, 615, 1635, 6, 1046, +-581, -534, -671, -1672, -147, -1319, 513, 261, +685, 1572, 282, 1586, -385, 132, -745, -1475, +-433, -1810, 285, -443, 761, 1278, 564, 1895, +-162, 852, -765, -1022, -659, -2000, 29, -1125, +713, 722, 753, 1869, 115, 1428, -660, -353, +-807, -1760, -235, -1611, 584, -17, 871, 1477, +322, 1705, -500, 453, -849, -1171, -400, -1804, +392, -827, 794, 830, 445, 1707, -246, 1195, +-663, -412, -440, -1652, 59, -1473, 460, 34, +479, 1419, 152, 1614, -247, 400, -488, -1152, +-368, -1742, 78, -769, 519, 833, 528, 1639, +104, 1110, -463, -376, -653, -1540, -309, -1414, +369, -36, 760, 1281, 498, 1604, -214, 584, +-831, -992, -704, -1824, 108, -1029, 860, 683, +855, 1820, 37, 1484, -820, -252, -960, -1844, +-215, -1816, 746, -104, 993, 1646, 413, 2049, +-545, 616, -1030, -1436, -616, -2238, 321, -986, +1014, 1127, 856, 2250, -98, 1453, -1009, -742, +-1057, -2271, -118, -1735, 978, 378, 1198, 2036, +322, 1986, -875, 141, -1280, -1803, -530, -2113, +711, -544, 1298, 1379, 720, 2119, -508, 1072, +-1247, -978, -886, -2058, 242, -1377, 1136, 484, +1033, 1846, 33, 1707, -994, 56, -1137, -1599, +-334, -1905, 793, -568, 1235, 1206, 594, 2024, +-556, 1141, -1234, -823, -864, -2062, 271, -1586, +1226, 333, 1102, 1989, -4, 1989, -1153, 128, +-1303, -1843, -286, -2237, 1065, -600, 1471, 1575, +533, 2373, -914, 1050, -1548, -1247, -783, -2418, +720, -1454, 1592, 855, 979, 2354, -536, 1795, +-1542, -453, -1088, -2226, 346, -2026, 1438, 21, +1124, 1975, -138, 2125, -1214, 367, -1112, -1655, +-87, -2107, 901, -698, 1109, 1228, 383, 1903, +-603, 979, -1042, -781, -632, -1654, 293, -1133, +1008, 263, 835, 1296, -20, 1248, -923, 208, +-967, -921, -196, -1258, 755, -608, 1050, 503, +444, 1132, -576, 945, -1090, -63, -624, -916, +364, -1111, 1086, -410, 782, 559, -199, 1182, +-1003, 905, -859, -157, 21, -1153, 871, -1321, +912, -300, 175, 1061, -711, 1691, -968, 742, +-333, -935, 536, -1903, 953, -1117, 495, 694, +-375, 1993, -889, 1508, -602, -372, 183, -1941, +780, -1783, 648, -37, 3, 1719, -658, 2094, +-738, 528, -128, -1468, 542, -2232, 730, -1040, +280, 1086, -406, 2382, -748, 1508, -375, -728, +292, -2390, 670, -1885, 444, 363, -148, 2289, +-633, 2201, -517, 28, 81, -2115, 549, -2339, +522, -446, 12, 1785, -474, 2440, -535, 818, +-47, -1389, 414, -2369, 413, -1211, 92, 940, +-236, 2186, -337, 1517, -126, -472, 107, -1930, +194, -1739, 210, -1, 46, 1640, -157, 1862, +-323, 428, -136, -1286, 188, -1918, 363, -834, +211, 919, -197, 1864, -418, 1196, -187, -545, +220, -1767, 349, -1470, 184, 166, -166, 1569, +-305, 1625, -157, 180, 137, -1326, 277, -1665, +141, -496, -125, 1019, -221, 1593, -121, 778, +120, -697, 201, -1471, 38, -987, -109, 326, +-102, 1293, 14, 1224, 76, 10, 36, -1127, +-53, -1340, -49, -328, 21, 921, 102, 1401, +-9, 616, -99, -736, -92, -1338, 28, -734, +163, 445, 143, 1158, -68, 911, -256, -233, +-123, -944, 96, -874, 222, -54, 161, 665, +-72, 877, -284, 343, -155, -452, 117, -810, +268, -527, 199, 119, -120, 704, -338, 811, +-217, 102, 159, -601, 352, -884, 198, -380, +-128, 387, -366, 1013, -241, 656, 177, -301, +361, -981, 148, -808, -134, 81, -306, 942, +-140, 971, 108, 41, 227, -856, 147, -1015, +-43, -203, -139, 660, -196, 1058, -60, 454, +156, -522, 189, -1038, 64, -635, -97, 241, +-172, 966, -110, 904, 49, -11, 171, -908, +166, -1095, 22, -206, -202, 802, -238, 1219, +-56, 467, 211, -738, 270, -1327, 64, -593, +-204, 617, -228, 1264, -64, 824, 138, -490, +243, -1283, 70, -916, -124, 343, -201, 1151, +-78, 1020, 46, -125, 189, -1108, 165, -1049, +1, 13, -177, 924, -209, 998, -46, 205, +172, -853, 297, -965, 62, -239, -220, 683, +-279, 843, -53, 363, 193, -537, 323, -828, +79, -312, -263, 412, -298, 639, -50, 356, +240, -211, 266, -573, 46, -289, -251, 127, +-220, 325, 36, 223, 202, 82, 134, -191, +-18, -209, -139, -89, -120, 33, 23, 98, +56, 204, 46, 83, 49, -92, 16, -173, +-24, -159, -78, -22, -92, 175, 12, 300, +101, 77, 114, -186, -5, -310, -135, -158, +-135, 96, -9, 385, 126, 251, 161, -81, +45, -331, -160, -278, -188, -31, -80, 270, +152, 365, 216, 81, 47, -245, -123, -363, +-184, -136, -98, 171, 91, 455, 180, 191, +110, -281, -36, -462, -184, -132, -144, 281, +-12, 437, 162, 142, 149, -354, 30, -408, +-107, 6, -117, 324, -64, 222, 32, 14, +103, -287, 81, -221, 44, 83, -66, 279, +-131, 68, -129, -69, 53, -140, 218, -163, +186, 6, -81, 219, -237, 173, -202, -48, +21, -86, 243, -251, 192, -94, 5, 218, +-134, 319, -174, -27, -134, -172, 58, -248, +222, -106, 209, 220, -15, 335, -205, 52, +-272, -270, -90, -204, 219, -136, 328, 173, +136, 294, -133, 164, -319, -211, -296, -200, +87, -147, 382, 46, 331, 214, -12, 177, +-352, -12, -424, -166, -97, -99, 370, -111, +489, 65, 165, 151, -288, 195, -520, -27, +-338, -140, 203, -256, 603, -69, 413, 177, +-144, 294, -559, 111, -523, -177, 37, -239, +566, -158, 567, 95, 23, 185, -523, 216, +-582, -21, -196, -109, 445, -200, 691, -132, +267, 28, -389, 251, -691, 209, -407, 16, +290, -216, 758, -310, 441, -67, -315, 208, +-724, 369, -397, 93, 235, -162, 614, -360, +381, -214, -172, 106, -487, 390, -338, 259, +15, -50, 318, -331, 383, -331, 66, 4, +-307, 274, -363, 328, -44, 46, 249, -192, +263, -287, 10, -125, -187, 64, -117, 271, +14, 214, 6, 17, -43, -228, 60, -305, +162, -118, 62, 220, -137, 379, -185, 154, +-72, -191, 99, -378, 187, -183, 54, 91, +-54, 368, -106, 221, -90, -60, -63, -245, +89, -237, 203, -67, 42, 232, -138, 239, +-181, 62, -42, -105, 142, -199, 155, -103, +-75, -5, -118, 156, 50, 107, 115, 157, +-71, -19, -179, -222, -39, -317, 186, -12, +222, 308, -25, 383, -306, 92, -183, -389, +117, -439, 188, -40, 143, 406, -17, 327, +-92, 82, -196, -316, -170, -294, 13, -60, +262, 179, 366, 191, 12, 127, -461, 1, +-444, -162, 27, -228, 511, -98, 490, 171, +-147, 263, -550, 207, -453, -160, 128, -329, +528, -218, 357, 149, -92, 298, -448, 209, +-360, -78, 27, -258, 353, -234, 320, 22, +-4, 224, -326, 195, -248, 77, -40, -173, +195, -257, 193, -139, 24, 185, -55, 241, +-148, 165, -119, -149, -67, -246, 100, -170, +194, 81, 46, 240, -112, 131, -188, 23, +-92, -157, 132, -223, 127, -104, 1, 197, +-48, 221, -91, 156, -63, -217, -37, -292, +57, -103, 131, 240, 23, 330, -58, -38, +-146, -269, -50, -207, 143, 87, 0, 228, +-72, 147, -16, -208, 63, -138, 72, 38, +-115, 210, -186, 23, 40, -166, 227, -153, +116, 29, -186, 289, -273, 172, 34, -188, +204, -384, 151, -43, -107, 261, -199, 438, +-35, 6, 117, -443, 53, -438, -29, 142, +-27, 562, -28, 364, -6, -242, -76, -617, +5, -299, 71, 308, 93, 696, -76, 211, +-174, -401, -16, -642, 139, -192, 123, 458, +-95, 664, -223, 102, -62, -524, 161, -602, +144, -30, -13, 611, -166, 523, -118, -84, +9, -640, 100, -455, 74, 186, -18, 653, +-85, 368, -136, -250, -48, -640, 148, -357, +113, 310, -35, 656, -162, 377, -196, -316, +66, -783, 212, -448, 96, 446, -173, 897, +-251, 483, -34, -573, 210, -1085, 194, -426, +-33, 725, -324, 1179, -212, 354, 155, -908, +270, -1169, 159, -259, -196, 958, -384, 1188, +-172, 110, 261, -1023, 419, -1082, 126, -3, +-357, 1003, -487, 963, -132, -85, 386, -980, +496, -854, 17, 227, -436, 935, -480, 649, +-20, -262, 425, -922, 462, -533, -25, 436, +-517, 909, -454, 301, 54, -610, 520, -866, +377, -36, -191, 852, -566, 838, -281, -310, +329, -1208, 510, -646, 27, 770, -473, 1427, +-425, 445, 138, -1206, 550, -1672, 273, -119, +-365, 1673, -620, 1728, -156, -221, 496, -2008, +617, -1725, 22, 520, -645, 2348, -684, 1670, +51, -896, 729, -2540, 616, -1501, -144, 1154, +-756, 2682, -631, 1320, 117, -1429, 727, -2678, +563, -1046, -102, 1568, -683, 2563, -664, 856, +-39, -1659, 624, -2394, 711, -660, 115, 1668, +-671, 2211, -800, 511, -202, -1633, 609, -2032, +821, -435, 145, 1610, -638, 1878, -776, 308, +-163, -1525, 526, -1716, 645, -255, 127, 1401, +-445, 1595, -581, 195, -156, -1267, 269, -1441, +387, -234, 186, 1066, -170, 1376, -300, 283, +-224, -942, -38, -1263, 108, -411, 241, 802, +233, 1205, -75, 493, -426, -648, -417, -1138, +22, -622, 535, 469, 467, 1088, -188, 779, +-650, -312, -410, -1083, 289, -944, 549, 104, +209, 1170, -353, 1080, -496, -38, -94, -1124, +284, -1219, 315, -114, -13, 1212, -260, 1273, +-240, 152, -6, -1112, 145, -1361, 166, -283, +-5, 1106, -192, 1408, -209, 351, -47, -1033, +156, -1407, 265, -475, 76, 967, -368, 1488, +-406, 482, -45, -901, 421, -1418, 465, -588, +-52, 893, -617, 1459, -583, 539, 125, -872, +724, -1448, 499, -531, -250, 1011, -759, 1458, +-593, 347, 270, -1114, 753, -1393, 439, -134, +-279, 1254, -707, 1290, -488, -149, 131, -1326, +653, -1024, 497, 278, -158, 1315, -649, 925, +-533, -473, -1, -1291, 615, -742, 540, 458, +-113, 1298, -591, 785, -477, -583, 64, -1379, +414, -741, 336, 623, -122, 1468, -328, 838, +-191, -775, -21, -1596, 52, -806, 64, 839, +117, 1644, 112, 858, -99, -891, -346, -1735, +-286, -825, 63, 861, 468, 1659, 320, 928, +-216, -751, -600, -1684, -374, -930, 255, 560, +551, 1497, 322, 1092, -304, -288, -654, -1422, +-351, -1197, 317, -11, 547, 1163, 294, 1430, +-302, 404, -700, -1081, -305, -1631, 359, -717, +603, 873, 217, 1841, -431, 1096, -671, -787, +-224, -2027, 449, -1312, 556, 620, 68, 2093, +-434, 1647, -527, -506, -180, -2181, 345, -1733, +466, 277, 169, 2093, -305, 1973, -590, -103, +-374, -2003, 254, -2045, 743, -165, 422, 1799, +-393, 2188, -971, 485, -582, -1703, 529, -2265, +1138, -723, 505, 1452, -772, 2381, -1347, 1026, +-495, -1379, 928, -2367, 1357, -1146, 340, 1140, +-1119, 2334, -1422, 1320, -250, -1013, 1100, -2248, +1307, -1325, 114, 765, -1152, 2140, -1199, 1448, +-186, -643, 962, -2088, 1119, -1416, 123, 566, +-816, 1918, -1050, 1429, -454, -543, 607, -1867, +1048, -1139, 531, 568, -493, 1540, -1170, 947, +-796, -564, 352, -1300, 1277, -574, 822, 527, +-511, 855, -1299, 334, -882, -350, 400, -563, +1251, -137, 760, 243, -487, 145, -1091, 64, +-720, 49, 206, 9, 879, -75, 666, -204, +-165, -213, -717, 139, -660, 444, -99, 213, +488, -314, 552, -484, 138, -178, -301, 387, +-484, 585, -359, 29, -78, -504, 289, -476, +494, 78, 321, 516, -194, 396, -766, -183, +-741, -511, 77, -298, 888, 250, 970, 462, +12, 196, -1188, -246, -1266, -445, -180, -105, +1252, 238, 1479, 349, 211, 85, -1400, -200, +-1785, -239, -385, -61, 1442, 129, 1841, 93, +437, 82, -1505, 24, -2061, -29, -596, -89, +1469, -115, 2047, -79, 612, 95, -1443, 239, +-2170, 142, -805, -106, 1390, -228, 2075, -226, +729, -55, -1269, 298, -2075, 419, -881, 133, +1119, -318, 1880, -589, 793, -359, -925, 421, +-1791, 924, -949, 425, 678, -639, 1583, -1083, +936, -484, -547, 763, -1482, 1349, -1027, 442, +263, -1012, 1241, -1400, 1019, -316, -146, 1071, +-1106, 1433, -1160, 313, -171, -1196, 938, -1444, +1195, -182, 335, 1105, -981, 1339, -1407, 311, +-427, -1036, 894, -1298, 1368, -339, 395, 821, +-1039, 1160, -1339, 519, -410, -533, 895, -1106, +1210, -675, 283, 252, -831, 923, -1189, 936, +-463, 97, 717, -871, 1134, -1133, 395, -452, +-727, 738, -1182, 1430, -524, 803, 654, -713, +1176, -1647, 410, -1119, -760, 563, -1149, 1927, +-489, 1459, 553, -553, 1149, -2069, 551, -1696, +-698, 344, -1213, 2220, -657, 1976, 499, -248, +1313, -2271, 755, -2112, -733, 13, -1502, 2214, +-750, 2344, 659, 204, 1455, -2153, 755, -2433, +-788, -459, -1563, 1903, -767, 2622, 701, 782, +1409, -1770, 740, -2659, -683, -1057, -1479, 1483, +-852, 2697, 586, 1366, 1379, -1259, 772, -2633, +-606, -1525, -1398, 935, -824, 2424, 504, 1731, +1247, -538, 684, -2236, -575, -1830, -1141, 106, +-597, 1883, 373, 2049, 926, 308, 458, -1661, +-444, -2099, -751, -718, -345, 1354, 259, 2213, +347, 971, 221, -1071, -171, -2111, -242, -1197, +-82, 706, -122, 1969, -165, 1388, 46, -384, +329, -1693, 179, -1524, -156, -63, -473, 1468, +-430, 1681, 123, 312, 647, -1210, 259, -1669, +-246, -618, -599, 998, -461, 1648, 161, 715, +572, -756, 405, -1436, -278, -813, -609, 465, +-436, 1227, 126, 857, 582, -192, 387, -951, +-363, -849, -596, -135, -213, 650, 214, 868, +400, 382, 39, -361, -292, -786, -250, -649, +48, 62, 31, 744, -82, 810, -60, 200, +79, -616, 108, -933, -96, -404, -276, 497, +-228, 948, 134, 543, 273, -326, 110, -913, +-231, -683, -348, 225, -164, 795, 132, 747, +255, 9, 151, -741, -163, -850, -415, -80, +-258, 648, 144, 790, 339, 303, 233, -556, +-203, -853, -542, -264, -298, 412, 208, 694, +439, 439, 198, -236, -226, -685, -519, -491, +-335, 106, 180, 546, 483, 641, 203, 103, +-218, -593, -480, -775, -372, -135, 138, 572, +434, 859, 189, 255, -141, -671, -285, -890, +-372, -233, -89, 656, 177, 867, 318, 230, +192, -636, -115, -789, -520, -241, -522, 545, +131, 774, 564, 233, 491, -490, -140, -719, +-734, -292, -646, 401, 143, 783, 676, 343, +517, -461, -143, -763, -702, -372, -605, 366, +55, 845, 574, 481, 439, -429, -18, -851, +-499, -528, -502, 272, -139, 931, 261, 752, +365, -256, 251, -1053, -114, -919, -474, 167, +-505, 1190, -132, 1204, 443, -159, 649, -1480, +179, -1294, -631, 200, -873, 1620, -301, 1442, +621, -255, 932, -1771, 256, -1455, -786, 289, +-1052, 1784, -319, 1480, 695, -207, 1027, -1774, +277, -1531, -792, 171, -1095, 1672, -382, 1564, +644, -11, 1065, -1563, 393, -1620, -693, -74, +-1223, 1410, -530, 1566, 675, 285, 1214, -1210, +488, -1595, -822, -476, -1340, 983, -493, 1553, +898, 790, 1218, -683, 249, -1703, -957, -1139, +-1169, 536, -207, 1776, 873, 1488, 880, -264, +22, -2008, -717, -1865, -773, 237, -156, 2122, +475, 2084, 565, -30, 174, -2305, -315, -2353, +-591, 36, -393, 2405, 111, 2390, 513, 93, +426, -2432, -36, -2520, -575, -70, -672, 2429, +-75, 2418, 515, 121, 648, -2258, 158, -2429, +-601, -136, -813, 2137, -235, 2212, 486, 191, +717, -1854, 296, -2135, -448, -214, -834, 1683, +-471, 1860, 282, 311, 761, -1448, 561, -1720, +-194, -353, -920, 1241, -768, 1521, 109, 431, +808, -982, 798, -1416, -80, -525, -884, 838, +-872, 1258, -82, 584, 685, -605, 820, -1218, +212, -651, -631, 546, -926, 1110, -445, 628, +382, -405, 936, -1072, 593, -649, -422, 452, +-985, 1005, -750, 566, 179, -427, 910, -965, +770, -514, -115, 481, -836, 972, -916, 388, +-245, -554, 659, -868, 1039, -323, 442, 556, +-702, 879, -1210, 226, -771, -606, 576, -765, +1415, -219, 771, 537, -630, 774, -1501, 250, +-957, -535, 503, -754, 1451, -272, 956, 440, +-501, 823, -1432, 396, -1050, -483, 221, -888, +1342, -427, 1066, 417, -207, 996, -1274, 550, +-1186, -480, 13, -1065, 1109, -542, 1115, 413, +-11, 1098, -994, 670, -1077, -466, -213, -1077, +754, -640, 898, 338, 242, 976, -496, 750, +-848, -262, -521, -922, 266, -724, 645, 95, +565, 735, -23, 842, -638, 63, -775, -719, +-206, -779, 490, -165, 734, 542, 344, 749, +-404, 284, -891, -452, -558, -634, 296, -255, +779, 202, 627, 422, -197, 363, -875, 3, +-747, -290, 69, -347, 735, -230, 678, 58, +31, 404, -652, 459, -756, 20, -236, -378, +450, -563, 671, -256, 358, 347, -308, 741, +-792, 418, -578, -285, 128, -802, 721, -688, +655, 169, -26, 981, -792, 919, -824, -104, +-145, -1039, 666, -1163, 860, -47, 241, 1191, +-634, 1323, -1010, 146, -438, -1193, 474, -1508, +993, -292, 592, 1241, -416, 1579, -1110, 409, +-810, -1168, 223, -1617, 1109, -594, 943, 1095, +-165, 1646, -1252, 676, -1145, -870, 63, -1597, +1203, -899, 1223, 704, -85, 1583, -1311, 975, +-1267, -435, -13, -1452, 1198, -1167, 1201, 207, +-5, 1382, -1185, 1217, -1164, 33, -103, -1153, +954, -1342, 1089, -330, 121, 1026, -918, 1412, +-1027, 523, -224, -782, 687, -1472, 895, -816, +238, 692, -644, 1507, -800, 893, -272, -490, +351, -1455, 607, -1057, 336, 380, -259, 1367, +-563, 1047, -394, -155, -37, -1164, 419, -1144, +505, -54, 48, 1011, -476, 1134, -543, 292, +-124, -778, 345, -1211, 508, -547, 99, 650, +-432, 1183, -403, 723, -105, -385, 178, -1209, +319, -959, 93, 247, -196, 1196, -248, 1069, +-126, 20, 3, -1180, 140, -1292, 121, -139, +-65, 1171, -127, 1394, -54, 296, -43, -1109, +-52, -1561, -1, -451, 21, 1158, 114, 1625, +70, 491, -194, -1076, -286, -1732, -73, -587, +249, 1178, 272, 1735, -49, 556, -337, -1173, +-315, -1704, 95, -566, 335, 1223, 124, 1683, +-166, 462, -332, -1195, -121, -1556, 182, -466, +229, 1157, -30, 1544, -227, 375, -185, -1114, +19, -1440, 219, -376, 101, 1087, -216, 1452, +-243, 272, -9, -1131, 191, -1350, 233, -207, +-99, 1151, -407, 1336, -210, 58, 245, -1191, +322, -1174, 60, 18, -326, 1148, -416, 1097, +19, -107, 468, -1116, 209, -876, -279, 145, +-394, 884, -171, 756, 296, -152, 429, -760, +-32, -448, -471, 170, -353, 407, 82, 256, +373, -150, 316, -243, -80, 73, -512, 251, +-341, -102, 105, -329, 355, -230, 330, 183, +-46, 609, -413, 405, -384, -390, -30, -849, +289, -445, 341, 389, 130, 998, -220, 666, +-458, -438, -278, -1223, 147, -745, 440, 397, +372, 1304, -121, 973, -572, -378, -496, -1466, +106, -1100, 543, 355, 476, 1557, -93, 1290, +-582, -319, -514, -1718, -1, -1426, 468, 282, +508, 1819, 96, 1617, -453, -221, -611, -1907, +-235, -1779, 356, 70, 648, 1949, 353, 2013, +-435, 104, -742, -1933, -367, -2198, 297, -350, +697, 1861, 422, 2398, -284, 603, -688, -1792, +-437, -2481, 107, -822, 524, 1586, 528, 2565, +-22, 1028, -573, -1433, -486, -2482, -97, -1173, +336, 1135, 539, 2360, 168, 1385, -322, -901, +-481, -2196, -295, -1472, 83, 514, 460, 2029, +436, 1712, -82, -232, -524, -1906, -449, -1814, +-62, -107, 481, 1726, 538, 2033, -75, 379, +-492, -1688, -414, -2070, -3, -589, 362, 1447, +334, 2231, -79, 784, -282, -1402, -150, -2179, +-1, -924, 43, 1122, 72, 2203, -5, 1137, +37, -1009, 76, -2139, -123, -1230, -256, 732, +-79, 2033, 163, 1437, 261, -559, 144, -1937, +-260, -1455, -440, 289, -85, 1687, 288, 1574, +371, -65, 160, -1506, -327, -1525, -530, -197, +-169, 1210, 329, 1529, 499, 449, 259, -1010, +-334, -1486, -707, -607, -320, 798, 423, 1419, +676, 742, 313, -675, -390, -1382, -794, -730, +-322, 564, 461, 1247, 662, 719, 235, -488, +-344, -1126, -650, -637, -324, 398, 326, 973, +554, 602, 275, -274, -230, -827, -565, -571, +-401, 117, 213, 663, 577, 653, 352, 27, +-170, -576, -517, -687, -468, -225, 64, 475, +519, 830, 430, 351, 30, -495, -404, -822, +-546, -436, -218, 397, 342, 948, 550, 492, +322, -516, -193, -896, -643, -457, -527, 420, +160, 996, 658, 533, 562, -570, -77, -1020, +-783, -479, -682, 507, 183, 1109, 782, 651, +571, -615, -209, -1212, -816, -604, -575, 501, +299, 1222, 744, 791, 398, -469, -226, -1227, +-652, -772, -502, 247, 189, 1075, 601, 926, +435, -76, -41, -957, -537, -921, -631, -142, +-50, 716, 611, 976, 594, 320, 65, -575, +-523, -872, -717, -472, -154, 343, 591, 820, +647, 546, 149, -199, -472, -671, -745, -592, +-268, -24, 557, 573, 712, 634, 202, 166, +-492, -429, -726, -699, -236, -354, 511, 357, +621, 744, 134, 510, -373, -259, -522, -819, +-212, -658, 250, 202, 405, 867, 211, 787, +-92, -95, -365, -913, -324, -855, 17, 12, +297, 868, 288, 892, 101, 132, -252, -780, +-356, -934, -126, -251, 137, 629, 313, 941, +278, 415, -86, -488, -424, -954, -335, -537, +48, 348, 406, 948, 441, 655, -33, -256, +-495, -933, -423, -744, 18, 180, 388, 945, +436, 773, 85, -171, -347, -888, -477, -774, +-210, 148, 224, 898, 496, 736, 360, -214, +-156, -827, -598, -628, -425, 182, 111, 840, +498, 599, 440, -285, -63, -765, -429, -483, +-388, 192, -42, 773, 269, 533, 311, -215, +156, -767, -122, -558, -336, 115, -217, 740, +57, 736, 258, -48, 249, -808, -1, -794, +-285, -65, -251, 786, 13, 946, 213, 145, +218, -824, 1, -962, -228, -184, -208, 768, +12, 956, 186, 182, 161, -710, -3, -859, +-145, -184, -129, 599, -15, 727, 51, 183, +52, -432, 31, -606, 60, -259, 25, 277, +-109, 530, -157, 333, -70, -106, 94, -502, +225, -488, 127, -17, -139, 536, -203, 602, +-107, 91, 20, -544, 132, -729, 148, -177, +78, 582, -51, 770, -166, 234, -235, -550, +-35, -818, 291, -290, 330, 525, -24, 796, +-344, 310, -408, -449, -1, -748, 485, -287, +449, 409, -106, 639, -575, 257, -489, -314, +99, -562, 698, -230, 604, 269, -180, 470, +-822, 226, -640, -197, 137, -444, 898, -274, +789, 188, -180, 442, -970, 286, -812, -131, +125, -471, 985, -360, 900, 146, -154, 479, +-1032, 361, -844, -79, 132, -448, 963, -414, +841, 50, -127, 402, -920, 373, -750, 51, +44, -327, 781, -412, 787, -90, 24, 270, +-728, 347, -740, 175, -152, -156, 613, -397, +828, -242, 184, 137, -603, 337, -749, 336, +-244, -17, 484, -432, 751, -421, 234, 37, +-421, 394, -614, 461, -284, 105, 237, -454, +570, -553, 380, -95, -178, 410, -519, 534, +-420, 254, -14, -374, 523, -662, 568, -238, +33, 325, -513, 584, -573, 355, -178, -252, +437, -613, 686, -329, 234, 202, -440, 483, +-668, 339, -327, -36, 318, -378, 715, -372, +369, -58, -313, 203, -615, 371, -372, 278, +140, -84, 555, -452, 446, -400, -85, -12, +-494, 469, -465, 529, -30, 91, 500, -505, +555, -639, -12, -117, -558, 518, -531, 656, +33, 174, 612, -492, 552, -718, -127, -185, +-658, 472, -490, 664, 103, 247, 671, -371, +552, -650, -157, -309, -703, 304, -539, 596, +123, 352, 700, -171, 614, -569, -153, -428, +-740, 90, -524, 524, 128, 464, 616, 17, +561, -456, -126, -505, -618, -93, -451, 377, +61, 513, 491, 203, 508, -262, -20, -504, +-541, -331, -509, 123, 51, 491, 571, 441, +525, -1, -64, -462, -668, -536, -545, -121, +162, 450, 654, 594, 513, 185, -123, -389, +-653, -626, -524, -273, 88, 368, 588, 624, +551, 270, 21, -336, -542, -572, -600, -322, +-85, 307, 500, 588, 593, 262, 129, -268, +-461, -522, -590, -321, -126, 252, 409, 583, +517, 288, 135, -262, -365, -567, -485, -336, +-106, 269, 319, 679, 379, 322, 102, -370, +-221, -690, -351, -316, -121, 397, 180, 806, +234, 310, 158, -553, -48, -813, -244, -278, +-210, 575, 18, 929, 170, 305, 202, -693, +76, -991, -135, -323, -219, 689, -85, 1111, +98, 405, 125, -732, 128, -1192, 22, -501, +-177, 693, -158, 1287, -10, 650, 102, -650, +202, -1383, 111, -809, -196, 561, -263, 1477, +-60, 1010, 205, -516, 286, -1538, 70, -1121, +-294, 375, -324, 1604, 21, 1257, 312, -344, +290, -1569, -31, -1311, -343, 213, -291, 1548, +83, 1388, 304, -169, 282, -1498, -47, -1384, +-342, 64, -276, 1416, 51, 1422, 303, 6, +328, -1386, 10, -1366, -391, -83, -374, 1216, +38, 1367, 385, 196, 391, -1107, 11, -1287, +-448, -347, -427, 889, 59, 1267, 410, 528, +354, -706, 34, -1260, -389, -666, -433, 521, +-7, 1221, 358, 808, 380, -372, 106, -1202, +-330, -874, -450, 243, -109, 1120, 320, 921, +395, -160, 143, -1039, -222, -898, -404, 104, +-232, 935, 188, 815, 394, -89, 259, -842, +-87, -702, -393, 117, -324, 731, 63, 578, +357, -147, 259, -659, -18, -461, -216, 182, +-219, 564, -45, 375, 99, -171, 114, -545, +129, -347, 80, 179, -68, 486, -232, 326, +-187, -116, 54, -474, 261, -342, 285, 68, +6, 402, -363, 360, -348, 45, 1, -334, +379, -445, 443, -152, 46, 284, -512, 490, +-525, 276, 24, -262, 584, -597, 593, -322, +-53, 248, -723, 630, -631, 379, 179, -273, +792, -687, 609, -361, -241, 258, -846, 655, +-570, 401, 319, -276, 864, -645, 502, -395, +-340, 229, -834, 580, -495, 430, 375, -165, +808, -577, 436, -426, -288, 86, -781, 453, +-481, 457, 284, 50, 743, -419, 521, -474, +-188, -163, -762, 260, -633, 535, 192, 328, +818, -221, 646, -570, -137, -451, -856, 111, +-732, 630, 191, 560, 877, -79, 669, -673, +-107, -648, -788, 13, -725, 709, 56, 701, +733, -27, 681, -734, 82, -724, -570, 1, +-739, 748, -204, 746, 498, -58, 688, -744, +308, -713, -294, -7, -677, 736, -420, 741, +216, -34, 594, -699, 455, -714, -51, -75, +-504, 654, -485, 756, -11, 100, 422, -640, +445, -757, 81, -182, -282, 555, -395, 810, +-171, 244, 197, -537, 352, -771, 231, -337, +-50, 419, -342, 772, -358, 405, -10, -330, +388, -722, 448, -498, 84, 196, -406, 663, +-553, 533, -114, -96, 494, -603, 597, -575, +150, -12, -444, 514, -646, 560, -202, 72, +451, -422, 652, -546, 244, -173, -367, 364, +-624, 495, -282, 209, 312, -246, 573, -505, +278, -335, -173, 175, -448, 510, -304, 408, +102, -75, 342, -558, 258, -564, 31, 9, +-191, 596, -227, 644, -52, 45, 101, -638, +131, -774, 124, -127, 57, 668, -73, 808, +-118, 157, -110, -636, -35, -854, 174, -244, +239, 592, 23, 828, -179, 273, -208, -502, +-61, -821, 206, -344, 270, 440, 30, 745, +-191, 341, -211, -351, -70, -693, 173, -381, +313, 259, 106, 601, -151, 353, -294, -192, +-191, -503, 149, -414, 422, 73, 264, 455, +-167, 389, -422, 6, -284, -353, 164, -485, +491, -151, 320, 301, -152, 485, -424, 259, +-286, -196, 116, -555, 399, -453, 312, 105, +-72, 590, -312, 569, -246, 31, 13, -620, +268, -809, 258, -158, 44, 672, -137, 890, +-190, 309, -110, -682, 59, -1107, 226, -439, +211, 682, 40, 1172, -178, 568, -249, -627, +-104, -1305, 194, -724, 319, 554, 174, 1306, +-77, 835, -286, -415, -266, -1328, 1, -1003, +339, 266, 396, 1259, 112, 1100, -292, -68, +-496, -1244, -172, -1266, 411, -78, 600, 1140, +204, 1309, -387, 232, -594, -1103, -203, -1377, +460, -336, 659, 981, 147, 1334, -413, 435, +-538, -866, -156, -1323, 442, -548, 574, 679, +128, 1202, -366, 648, -434, -471, -114, -1169, +333, -794, 470, 239, 134, 1015, -257, 909, +-326, -7, -104, -950, 184, -1052, 335, -251, +178, 789, -107, 1157, -221, 488, -143, -686, +38, -1316, 223, -731, 238, 554, 52, 1370, +-125, 909, -194, -473, -134, -1465, 118, -1043, +315, 374, 227, 1426, -31, 1105, -304, -326, +-287, -1437, 104, -1131, 439, 238, 337, 1319, +-78, 1099, -434, -203, -331, -1246, 231, -1076, +555, 101, 295, 1085, -244, 1009, -520, -19, +-220, -988, 392, -988, 611, -106, 176, 806, +-391, 932, -517, 207, -125, -722, 452, -941, +626, -298, 163, 565, -408, 886, -543, 355, +-169, -540, 415, -876, 671, -378, 281, 422, +-341, 782, -587, 361, -289, -406, 297, -744, +665, -350, 449, 331, -177, 624, -590, 308, +-453, -310, 119, -613, 659, -292, 612, 264, +2, 499, -586, 248, -569, -255, -7, -487, +573, -225, 649, 205, 168, 376, -424, 175, +-577, -183, -211, -333, 355, -195, 669, 84, +438, 221, -162, 140, -625, -12, -493, -185, +148, -212, 678, -91, 669, 86, 69, 199, +-604, 150, -641, -81, -99, -263, 527, -220, +771, 8, 377, 235, -354, 232, -733, -15, +-453, -266, 261, -270, 840, -31, 698, 211, +-110, 252, -769, 44, -676, -228, 75, -279, +783, -97, 767, 150, 88, 287, -595, 125, +-660, -191, -102, -335, 533, -199, 708, 122, +289, 361, -343, 232, -615, -148, -277, -403, +344, -321, 667, 51, 402, 393, -173, 364, +-531, -37, -345, -426, 198, -472, 569, -119, +448, 371, 15, 536, -380, 183, -450, -359, +-44, -636, 450, -389, 555, 278, 254, 714, +-251, 462, -565, -222, -268, -784, 360, -684, +648, 102, 374, 833, -166, 749, -537, -44, +-316, -849, 258, -915, 537, -88, 343, 832, +-44, 923, -310, 128, -235, -788, 97, -1022, +313, -287, 268, 723, 87, 994, -94, 321, +-167, -643, -30, -1065, 170, -476, 252, 575, +153, 1018, -57, 504, -160, -503, -29, -1077, +199, -627, 266, 453, 81, 1034, -130, 589, +-122, -417, 71, -1055, 232, -646, 187, 413, +10, 992, -106, 527, -55, -409, 99, -950, +173, -546, 156, 411, 52, 856, -57, 380, +-68, -420, 60, -788, 215, -408, 200, 388, +19, 717, -143, 269, -85, -423, 184, -686, +331, -296, 137, 397, -161, 662, -220, 185, +47, -493, 364, -658, 344, -182, -4, 464, +-287, 645, -219, 97, 161, -551, 432, -618, +315, -124, -30, 464, -296, 590, -228, 90, +162, -477, 435, -578, 315, -179, -11, 350, +-276, 534, -223, 217, 152, -321, 416, -566, +308, -334, -14, 169, -264, 537, -188, 408, +167, -150, 430, -588, 283, -520, -95, -13, +-276, 560, -116, 619, 239, 37, 439, -605, +203, -731, -176, -210, -239, 548, -36, 812, +261, 281, 403, -561, 178, -913, -147, -463, +-240, 408, -58, 958, 247, 595, 440, -379, +252, -1012, -173, -771, -332, 154, -97, 998, +293, 892, 523, -79, 278, -976, -217, -1022, +-396, -155, -124, 880, 317, 1083, 567, 233, +350, -839, -191, -1139, -461, -418, -190, 674, +302, 1129, 616, 457, 412, -642, -179, -1111, +-474, -581, -211, 473, 278, 1075, 560, 582, +371, -471, -74, -1048, -338, -686, -190, 328, +143, 1031, 358, 686, 391, -360, 146, -1064, +-163, -771, -246, 258, -84, 1044, 232, 764, +469, -318, 333, -1073, -83, -771, -331, 226, +-206, 986, 175, 731, 528, -295, 428, -968, +-42, -684, -354, 201, -258, 837, 144, 598, +489, -248, 424, -809, 31, -552, -248, 187, +-216, 687, 19, 466, 308, -243, 395, -714, +228, -459, -20, 211, -218, 637, -210, 408, +92, -276, 419, -711, 464, -446, 160, 227, +-260, 657, -374, 453, -66, -243, 430, -733, +594, -538, 256, 128, -224, 663, -437, 587, +-160, -70, 382, -695, 607, -699, 319, -93, +-155, 588, -401, 731, -189, 184, 297, -592, +549, -840, 344, -322, -52, 452, -322, 810, +-227, 399, 170, -432, 491, -872, 439, -493, +39, 280, -307, 781, -286, 531, 87, -238, +489, -798, 476, -622, 73, 105, -256, 688, +-253, 623, 19, -40, 366, -701, 439, -714, +191, -63, -108, 580, -245, 677, -109, 127, +233, -576, 465, -730, 310, -215, -63, 417, +-261, 627, -124, 252, 215, -342, 432, -609, +280, -337, -60, 145, -190, 425, -76, 345, +188, -7, 382, -358, 260, -408, -31, -206, +-194, 121, -92, 394, 220, 342, 407, -29, +244, -416, -82, -515, -230, -190, -42, 354, +279, 583, 398, 251, 176, -351, -92, -683, +-159, -414, 6, 257, 238, 671, 317, 393, +183, -266, -39, -667, -111, -475, -3, 168, +164, 615, 288, 416, 211, -174, -11, -592, +-86, -501, 2, 58, 144, 547, 275, 474, +219, -72, 15, -572, -89, -577, -30, -43, +127, 545, 273, 592, 261, 24, 73, -593, +-99, -672, -92, -133, 53, 543, 227, 664, +320, 112, 231, -536, -6, -685, -196, -234, +-147, 408, 121, 622, 430, 244, 462, -349, +109, -625, -308, -376, -320, 177, 47, 548, +438, 403, 563, -130, 244, -571, -230, -527, +-381, -11, -145, 521, 290, 551, 624, 21, +483, -576, -80, -666, -507, -123, -358, 548, +229, 691, 731, 130, 611, -627, -70, -810, +-585, -227, -390, 588, 255, 849, 711, 255, +576, -665, -21, -976, -490, -356, -371, 597, +154, 978, 583, 389, 566, -619, 118, -1057, +-345, -475, -381, 503, 10, 960, 454, 488, +559, -473, 243, -987, -176, -542, -358, 356, +-132, 838, 263, 525, 494, -316, 386, -854, +18, -547, -259, 242, -252, 717, 43, 475, +399, -247, 470, -744, 229, -491, -117, 217, +-322, 642, -183, 412, 242, -241, 542, -680, +424, -455, 22, 199, -351, 608, -340, 407, +106, -199, 531, -666, 537, -497, 137, 155, +-292, 616, -385, 473, -57, -161, 448, -702, +619, -557, 276, 135, -226, 651, -457, 509, +-192, -163, 407, -694, 681, -539, 337, 128, +-209, 600, -447, 448, -193, -120, 343, -577, +619, -516, 351, 13, -117, 462, -334, 454, +-201, 79, 170, -412, 493, -599, 422, -263, +54, 303, -246, 609, -261, 404, 9, -246, +389, -763, 475, -628, 180, 118, -147, 793, +-263, 747, -90, -44, 250, -898, 446, -967, +300, -101, -5, 881, -225, 1028, -197, 190, +94, -905, 386, -1180, 394, -348, 132, 804, +-139, 1177, -226, 436, -57, -750, 237, -1256, +392, -610, 311, 593, 52, 1224, -237, 686, +-269, -509, 52, -1274, 434, -861, 522, 370, +180, 1233, -305, 898, -428, -312, -38, -1268, +488, -1021, 615, 221, 234, 1207, -305, 990, +-479, -202, -106, -1210, 446, -1049, 659, 122, +335, 1112, -247, 981, -552, -107, -256, -1064, +409, -1014, 787, -12, 481, 936, -226, 927, +-701, 47, -400, -854, 420, -956, 916, -174, +576, 728, -252, 868, -763, 193, -471, -665, +411, -884, 951, -276, 608, 549, -202, 771, +-752, 240, -518, -491, 324, -722, 918, -279, +667, 356, -117, 564, -701, 209, -551, -286, +198, -474, 851, -246, 718, 140, -20, 325, +-607, 183, -571, -83, 55, -265, 731, -230, +756, -24, 129, 155, -478, 171, -602, 35, +-130, -123, 582, -199, 815, -124, 315, 27, +-345, 131, -638, 124, -297, 18, 429, -151, +807, -242, 476, -121, -195, 103, -580, 249, +-393, 171, 210, -130, 707, -388, 578, -283, +11, 105, -441, 395, -457, 307, 6, -129, +540, -517, 599, -403, 190, 104, -249, 490, +-424, 396, -176, -94, 317, -555, 556, -492, +358, 48, -56, 502, -386, 472, -308, -7, +152, -535, 527, -569, 449, -60, 38, 467, +-323, 541, -339, 107, 47, -472, 455, -631, +444, -187, 134, 391, -204, 575, -337, 235, +-75, -361, 330, -648, 454, -312, 243, 281, +-117, 579, -337, 350, -154, -250, 262, -652, +448, -413, 252, 198, -87, 577, -264, 396, +-106, -188, 214, -636, 338, -439, 176, 178, +-35, 557, -111, 363, -32, -193, 127, -599, +186, -401, 131, 215, 47, 553, -15, 320, +-25, -227, 36, -599, 143, -395, 178, 227, +100, 591, -42, 362, -100, -221, 25, -648, +215, -501, 261, 152, 97, 664, -121, 518, +-176, -122, 11, -702, 260, -674, 333, 11, +156, 708, -137, 708, -280, 40, -115, -702, +270, -844, 473, -172, 288, 674, -153, 861, +-425, 225, -217, -643, 300, -958, 583, -363, +338, 586, -167, 937, -438, 385, -239, -528, +250, -971, 561, -508, 369, 429, -88, 898, +-402, 502, -292, -321, 159, -858, 543, -616, +437, 167, -48, 742, -403, 619, -319, -36, +131, -666, 524, -727, 444, -143, -12, 542, +-376, 714, -312, 253, 67, -438, 451, -774, +463, -421, 66, 292, -305, 708, -327, 504, +-15, -158, 356, -721, 437, -657, 155, -17, +-181, 639, -290, 741, -109, 147, 184, -647, +346, -878, 280, -302, 23, 592, -215, 937, +-254, 371, -21, -601, 296, -1032, 405, -477, +211, 529, -170, 1014, -360, 508, -157, -492, +234, -1030, 453, -592, 322, 360, -72, 934, +-382, 635, -280, -248, 144, -898, 436, -731, +402, 85, 46, 791, -338, 772, -329, 33, +21, -754, 352, -866, 428, -179, 185, 672, +-194, 878, -363, 273, -149, -619, 228, -965, +466, -410, 366, 518, -67, 958, -419, 506, +-316, -450, 153, -1017, 513, -638, 461, 331, +1, 978, -425, 709, -376, -240, 82, -967, +477, -813, 462, 99, 79, 882, -329, 830, +-357, 11, -20, -823, 353, -912, 413, -164, +176, 699, -136, 898, -292, 272, -157, -628, +116, -944, 334, -405, 324, 496, 96, 903, +-198, 465, -307, -418, -102, -904, 228, -561, +391, 287, 272, 833, -56, 588, -315, -201, +-274, -796, 14, -653, 356, 79, 441, 705, +171, 646, -254, -15, -454, -657, -199, -664, +310, -74, 589, 547, 335, 619, -220, 106, +-543, -476, -317, -591, 248, -168, 633, 367, +451, 507, -135, 164, -555, -297, -425, -469, +163, -204, 667, 211, 553, 385, -82, 184, +-559, -178, -451, -380, 120, -226, 624, 136, +539, 332, -29, 219, -471, -123, -409, -346, +50, -257, 499, 82, 496, 318, 43, 228, +-352, -52, -334, -295, 15, -272, 362, -22, +386, 232, 57, 251, -235, 94, -197, -178, +33, -323, 219, -184, 232, 109, 54, 320, +-121, 252, -76, -73, 50, -410, 135, -355, +118, 39, 12, 429, -97, 424, -16, -12, +129, -515, 129, -548, 32, -10, -79, 543, +-85, 596, 54, 41, 169, -611, 105, -689, +-12, -69, -79, 620, -72, 697, 5, 105, +121, -639, 171, -765, 84, -141, -54, 618, +-177, 765, -99, 154, 150, -626, 292, -826, +171, -205, -115, 615, -277, 831, -139, 233, +191, -597, 366, -876, 205, -320, -117, 533, +-292, 852, -179, 395, 158, -432, 386, -869, +271, -523, -59, 290, -307, 826, -247, 618, +108, -138, 405, -802, 331, -732, -13, -23, +-281, 701, -267, 778, 54, 166, 347, -603, +323, -838, 52, -315, -193, 458, -205, 807, +-11, 430, 206, -339, 226, -805, 90, -531, +-49, 225, -89, 752, -63, 584, 38, -137, +109, -747, 132, -646, 92, 59, -9, 708, +-104, 677, -101, 8, 60, -703, 173, -742, +133, -87, -1, 642, -123, 756, -82, 179, +53, -564, 129, -794, 72, -311, -4, 414, +-36, 751, -41, 436, 20, -222, 64, -706, +46, -590, 0, 9, -25, 577, -1, 679, +71, 217, 61, -447, -34, -758, -86, -427, +17, 267, 159, 757, 117, 620, -32, -110, +-156, -782, -80, -776, 162, -44, 241, 754, +77, 878, -131, 154, -176, -757, -21, -949, +209, -231, 253, 696, 71, 960, -142, 298, +-173, -659, -24, -955, 197, -346, 282, 555, +87, 905, -127, 389, -159, -478, -48, -847, +140, -405, 238, 358, 134, 734, -33, 424, +-132, -253, -117, -632, 44, -413, 194, 131, +198, 468, 31, 410, -130, 1, -109, -365, +-15, -391, 137, -136, 171, 203, 51, 371, +-60, 250, -92, -98, -62, -338, 53, -332, +140, -56, 81, 280, -16, 401, -84, 150, +-66, -232, -1, -425, 103, -278, 99, 140, +4, 442, -45, 346, -96, -75, -56, -414, +68, -430, 136, -38, 74, 413, -26, 467, +-135, 95, -122, -374, 47, -514, 181, -184, +163, 349, 13, 521, -136, 186, -191, -286, +-43, -494, 179, -237, 248, 233, 135, 441, +-70, 212, -237, -154, -166, -354, 114, -273, +281, 51, 253, 306, 40, 266, -223, 45, +-253, -201, -15, -324, 253, -159, 301, 149, +165, 291, -118, 226, -273, -1, -127, -274, +128, -343, 287, -98, 250, 213, 11, 358, +-236, 245, -192, -148, 20, -422, 212, -295, +246, 94, 75, 351, -147, 319, -172, -16, +-28, -320, 96, -257, 166, -17, 93, 167, +-39, 175, -106, 76, -88, -56, -13, -94, +91, -77, 160, -99, 46, -25, -143, 125, +-179, 189, -21, 109, 155, -93, 191, -295, +-42, -239, -224, 95, -120, 367, 92, 332, +166, -29, 61, -461, -89, -486, -136, 1, +-25, 539, 66, 583, 64, 63, 29, -594, +2, -705, -57, -92, -57, 622, 12, 735, +73, 154, 85, -571, 14, -785, -86, -220, +-43, 510, 70, 745, 112, 301, 54, -392, +-49, -731, -53, -376, 15, 318, 84, 635, +109, 400, 52, -194, -13, -570, -60, -413, +-60, 110, 79, 456, 182, 370, 129, 10, +-28, -352, -166, -393, -91, -90, 122, 255, +207, 365, 95, 210, -67, -146, -113, -415, +-31, -300, 50, 64, 91, 372, 72, 386, +45, 72, -38, -345, -133, -464, -98, -174, +76, 243, 186, 497, 100, 352, -101, -114, +-237, -550, -111, -488, 98, -23, 221, 512, +131, 641, -73, 155, -260, -516, -221, -740, +27, -260, 267, 443, 242, 781, -39, 385, +-277, -375, -293, -801, -30, -478, 202, 265, +250, 769, 129, 593, -90, -145, -306, -762, +-306, -674, -9, 27, 370, 699, 444, 763, +66, 103, -437, -651, -515, -809, -50, -223, +462, 560, 517, 835, 109, 343, -347, -484, +-452, -838, -169, -420, 259, 373, 490, 815, +334, 496, -118, -288, -501, -765, -387, -521, +144, 151, 585, 674, 444, 581, -120, -38, +-512, -573, -362, -593, 147, -150, 463, 453, +340, 669, -40, 291, -332, -349, -328, -673, +-27, -443, 279, 199, 370, 718, 142, 555, +-261, -111, -416, -653, -187, -617, 223, -66, +418, 605, 221, 677, -190, 141, -436, -468, +-310, -648, 72, -299, 403, 333, 393, 641, +-12, 326, -499, -185, -555, -509, -64, -390, +508, 27, 588, 431, 37, 366, -588, 42, +-641, -248, -91, -353, 514, -146, 589, 176, +102, 305, -461, 145, -628, -67, -217, -250, +392, -222, 618, 37, 284, 231, -350, 201, +-695, 29, -337, -170, 355, -255, 707, -89, +364, 143, -351, 232, -689, 169, -327, -48, +370, -259, 664, -266, 316, -15, -300, 225, +-562, 311, -293, 134, 274, -200, 537, -336, +293, -184, -166, 123, -445, 296, -285, 266, +131, -44, 408, -272, 293, -259, -23, -53, +-306, 216, -306, 289, -53, 101, 252, -208, +333, -260, 127, -118, -168, 143, -372, 273, +-233, 126, 147, -149, 360, -242, 238, -118, +-132, 78, -405, 242, -275, 151, 107, -78, +308, -208, 180, -135, -116, 8, -290, 154, +-208, 173, 6, 41, 164, -79, 130, -135, +20, -158, -146, -65, -254, 160, -141, 278, +102, 157, 248, -133, 136, -392, -169, -296, +-383, 144, -173, 478, 202, 345, 352, -115, +96, -474, -250, -420, -346, 53, -107, 474, +214, 434, 260, 11, 77, -393, -133, -439, +-210, -99, -157, 341, 57, 437, 195, 132, +202, -263, 62, -420, -173, -203, -257, 196, +-93, 428, 169, 253, 289, -141, 170, -425, +-112, -326, -307, 83, -197, 449, 92, 379, +315, -39, 262, -423, -33, -429, -345, -25, +-327, 390, 45, 459, 360, 98, 343, -322, +-44, -487, -432, -171, -383, 301, 91, 483, +410, 197, 305, -267, -129, -467, -444, -205, +-310, 270, 110, 426, 343, 150, 177, -218, +-110, -342, -301, -154, -257, 171, -5, 267, +189, 126, 167, -68, 29, -187, -184, -185, +-293, -12, -130, 164, 111, 200, 196, 82, +79, -106, -139, -256, -251, -135, -139, 147, +69, 269, 150, 112, 73, -162, -53, -285, +-161, -99, -159, 273, -6, 291, 111, -7, +114, -309, 39, -259, -147, 51, -186, 349, +-24, 250, 154, -140, 177, -324, 1, -182, +-188, 116, -191, 279, 28, 197, 227, -111, +163, -253, -56, -164, -204, 51, -170, 222, +87, 207, 246, -28, 107, -241, -115, -200, +-192, -7, -86, 210, 98, 276, 129, 66, +34, -227, -57, -316, -52, -142, -56, 203, +-83, 420, -6, 216, 77, -243, 67, -446, +-23, -227, -145, 239, -152, 460, 19, 221, +103, -232, 44, -391, -66, -176, -113, 125, +-114, 306, -41, 171, 40, -73, 53, -199, +4, -128, -94, -1, -195, 137, -128, 121, +92, -38, 177, -114, 36, -41, -170, 68, +-272, 85, -129, 15, 107, -140, 176, -101, +69, 41, -78, 147, -175, 144, -183, 40, +-68, -144, 64, -273, 161, -127, 123, 118, +-48, 355, -234, 299, -231, -47, -43, -412, +178, -412, 260, -27, 133, 386, -162, 507, +-368, 155, -225, -375, 115, -600, 402, -247, +313, 315, -129, 672, -449, 410, -298, -273, +85, -723, 340, -521, 274, 166, 5, 722, +-238, 670, -302, -7, -158, -699, 68, -824, +316, -178, 265, 665, -58, 991, -344, 417, +-314, -601, -57, -1122, 189, -629, 269, 463, +134, 1166, -110, 826, -332, -266, -354, -1126, +-79, -985, 345, 42, 429, 1037, 0, 1140, +-480, 214, -526, -920, -112, -1253, 394, -437, +451, 757, 56, 1270, -372, 659, -528, -497, +-292, -1208, 221, -861, 513, 208, 316, 1103, +-275, 1029, -628, 91, -442, -924, 145, -1183, +564, -396, 390, 709, -109, 1241, -530, 688, +-523, -398, -146, -1161, 413, -955, 558, 24, +232, 999, -370, 1178, -698, 376, -394, -747, +251, -1333, 668, -765, 430, 525, -150, 1384, +-621, 1040, -579, -195, -37, -1286, 567, -1294, +609, -162, 76, 1105, -495, 1395, -624, 530, +-146, -797, 353, -1420, 457, -810, 134, 523, +-209, 1331, -367, 994, -270, -156, 55, -1172, +248, -1131, 238, -154, -27, 939, -273, 1190, +-287, 498, -2, -632, 181, -1197, 93, -714, +-73, 334, -193, 1068, -85, 885, 9, -2, +67, -862, -22, -980, -82, -337, -126, 564, +-135, 1031, -3, 708, 123, -194, 93, -1009, +-157, -992, -262, -167, -210, 846, 71, 1167, +264, 471, 103, -571, -195, -1129, -348, -720, +-217, 260, 28, 996, 307, 880, 235, 93, +-98, -779, -411, -991, -434, -389, 20, 484, +428, 981, 397, 677, -122, -113, -549, -862, +-463, -893, 70, -208, 458, 674, 367, 1034, +-69, 537, -467, -442, -408, -1117, -111, -782, +350, 250, 410, 1099, 107, 972, -360, -13, +-504, -961, -175, -1006, 269, -169, 427, 672, +98, 914, -220, 349, -336, -394, -189, -714, +-11, -421, 162, 126, 213, 499, 60, 472, +-144, 75, -341, -225, -230, -403, 58, -288, +239, -43, 175, 312, -41, 443, -248, 271, +-314, -137, -122, -531, 91, -439, 248, 34, +70, 542, -195, 498, -293, 94, -129, -427, +101, -550, 48, -197, -39, 291, -130, 521, +-57, 312, -44, -83, -71, -406, -94, -354, +-23, -63, 20, 218, -109, 281, -128, 187, +-25, 24, 104, -142, -20, -248, -169, -238, +-219, 13, -52, 290, 113, 383, 62, 159, +-56, -278, -136, -469, -56, -299, -80, 159, +-64, 488, -25, 486, -29, 74, 16, -449, +-12, -606, -28, -310, -95, 268, -117, 662, +-93, 618, 36, 3, 134, -643, 21, -845, +-180, -323, -288, 532, -71, 989, 112, 663, +207, -299, 16, -951, -153, -864, -258, -67, +-165, 793, 42, 995, 107, 415, 116, -498, +-117, -977, -208, -732, -178, 168, 14, 937, +137, 967, 78, 194, -158, -775, -323, -1098, +-144, -559, 86, 538, 245, 1141, 49, 879, +-278, -172, -395, -1058, -189, -1081, 178, -217, +296, 893, 135, 1207, -269, 589, -461, -562, +-363, -1188, 51, -930, 349, 120, 304, 1086, +-63, 1197, -471, 390, -440, -753, -141, -1284, +237, -861, 256, 311, 114, 1243, -178, 1183, +-369, 179, -347, -993, -102, -1371, 246, -635, +328, 707, 67, 1472, -402, 1057, -414, -287, +-162, -1443, 151, -1426, 207, -194, 25, 1349, +-51, 1704, -129, 667, -260, -1038, -284, -1814, +-34, -1060, 236, 625, 286, 1770, -41, 1406, +-361, -110, -349, -1556, -185, -1659, 93, -447, +241, 1249, 227, 1840, -13, 942, -422, -741, +-527, -1768, -188, -1382, 359, 155, 474, 1588, +115, 1661, -433, 433, -598, -1196, -312, -1837, +140, -945, 461, 770, 364, 1873, -99, 1375, +-638, -251, -670, -1694, -158, -1709, 543, -294, +621, 1366, 79, 1841, -606, 803, -761, -791, +-357, -1792, 244, -1207, 636, 283, 445, 1548, +-177, 1449, -854, 237, -845, -1198, -111, -1578, +738, -565, 861, 825, 44, 1607, -862, 899, +-1052, -500, -329, -1523, 567, -1110, 909, 258, +368, 1407, -554, 1300, -1031, 24, -717, -1311, +201, -1485, 856, -221, 743, 1213, -124, 1660, +-951, 540, -995, -1039, -245, -1733, 646, -922, +942, 757, 365, 1748, -586, 1271, -1084, -254, +-773, -1608, 180, -1628, 941, -221, 843, 1383, +-83, 1819, -982, 694, -1144, -974, -278, -1780, +735, -1114, 959, 504, 341, 1603, -629, 1346, +-1046, 51, -633, -1208, 233, -1433, 770, -466, +534, 770, -197, 1216, -736, 739, -660, -210, +-33, -838, 441, -729, 325, -166, -127, 322, +-495, 506, -364, 336, 90, 81, 356, -70, +114, -167, -391, -270, -591, -297, -298, -186, +242, 147, 613, 439, 254, 515, -424, 290, +-813, -235, -641, -575, 101, -662, 692, -311, +547, 327, -66, 882, -690, 852, -807, 176, +-295, -690, 392, -1051, 609, -668, 199, 134, +-449, 890, -697, 1019, -369, 439, 201, -442, +508, -999, 156, -798, -378, 72, -597, 843, +-366, 828, 144, 99, 515, -644, 248, -790, +-309, -124, -613, 711, -431, 896, 43, 144, +354, -803, 231, -1163, -128, -434, -362, 861, +-308, 1499, -62, 801, 67, -530, 18, -1478, +-180, -1300, -188, 93, -48, 1262, 108, 1384, +-14, 350, -234, -825, -253, -1239, -90, -431, +49, 653, -23, 989, -151, 285, -182, -671, +-72, -989, 7, -335, -7, 894, -115, 1350, +-140, 600, -166, -777, -165, -1578, -65, -1183, +54, 391, 14, 1618, -220, 1551, -308, 162, +-173, -1350, 71, -1714, 233, -595, 132, 1135, +-146, 1880, -385, 952, -610, -922, -500, -2055, +41, -1434, 671, 514, 737, 2139, 76, 2027, +-685, 194, -1032, -1716, -692, -2318, 61, -1079, +653, 1034, 771, 2319, 210, 1584, -628, -396, +-981, -1926, -606, -1741, 266, -70, 726, 1603, +486, 1897, -225, 426, -859, -1301, -822, -1933, +-203, -946, 524, 870, 808, 1946, 312, 1359, +-577, -332, -982, -1570, -635, -1374, 198, -87, +724, 1127, 414, 1230, -337, 233, -879, -918, +-561, -1158, 236, -350, 764, 917, 496, 1472, +-444, 707, -1146, -697, -854, -1730, 171, -1312, +989, 169, 930, 1562, -161, 1780, -1131, 609, +-1235, -1011, -394, -1812, 733, -1187, 1116, 363, +609, 1665, -443, 1504, -1322, 210, -1190, -1269, +-202, -1783, 780, -783, 1110, 806, 462, 1873, +-443, 1474, -1088, 5, -936, -1531, -122, -1994, +510, -866, 681, 861, 171, 1847, -437, 1406, +-685, 66, -432, -1221, 77, -1442, 359, -580, +384, 599, -30, 1106, -605, 739, -781, -185, +-332, -879, 270, -738, 656, -34, 488, 768, +-191, 1008, -750, 404, -899, -565, -437, -1201, +282, -1008, 814, 63, 715, 1143, -155, 1471, +-990, 652, -1130, -599, -468, -1438, 547, -1188, +1046, -13, 632, 1078, -344, 1203, -1123, 414, +-969, -582, -246, -991, 592, -394, 866, 467, +262, 726, -533, 217, -937, -468, -564, -722, +268, -158, 678, 588, 374, 902, -342, 297, +-852, -625, -621, -1008, 48, -535, 523, 459, +515, 1161, 12, 857, -523, -217, -726, -1067, +-478, -1167, 204, -269, 593, 861, 445, 1426, +-305, 854, -938, -405, -737, -1372, 125, -1245, +868, -210, 678, 992, -100, 1377, -988, 679, +-1196, -418, -497, -1081, 680, -895, 1289, -53, +743, 760, -585, 837, -1588, 266, -1196, -405, +122, -606, 1222, -361, 1114, 143, 15, 409, +-1110, 374, -1361, 21, -485, -208, 773, -166, +1237, 38, 485, 125, -829, -89, -1540, -332, +-900, -326, 413, 211, 1431, 741, 1103, 875, +-286, 150, -1466, -825, -1548, -1316, -414, -948, +912, 306, 1401, 1458, 642, 1647, -587, 585, +-1309, -940, -1011, -1781, 22, -1340, 828, 60, +812, 1350, -75, 1602, -830, 763, -849, -586, +-155, -1398, 628, -1159, 667, -117, 26, 965, +-764, 1223, -919, 580, -396, -342, 412, -953, +860, -912, 537, -212, -262, 577, -975, 924, +-1054, 652, -376, -36, 570, -671, 1026, -797, +721, -390, -209, 247, -990, 690, -1143, 715, +-697, 214, 170, -489, 935, -883, 1000, -570, +307, 308, -509, 1010, -974, 975, -842, 27, +-441, -1006, 137, -1406, 552, -692, 645, 775, +473, 1658, -163, 1420, -684, 71, -853, -1360, +-578, -1878, -86, -1072, 418, 450, 644, 1616, +418, 1761, -62, 758, -534, -632, -744, -1618, +-557, -1513, 30, -560, 408, 703, 380, 1503, +67, 1350, -338, 346, -393, -765, -68, -1362, +202, -1004, 47, 48, -302, 908, -546, 1028, +-374, 345, 47, -460, 481, -855, 590, -427, +170, 438, -337, 942, -733, 528, -751, -450, +-374, -1150, 116, -949, 392, 167, 530, 1159, +467, 1311, 171, 538, -378, -579, -914, -1251, +-1008, -1065, -517, -119, 394, 690, 917, 964, +917, 521, 283, -30, -613, -320, -1180, -398, +-970, -205, 1, -188, 805, -74, 913, 171, +166, 379, -711, 332, -1027, 100, -541, -295, +381, -533, 966, -340, 765, 222, -159, 747, +-1144, 694, -1289, 97, -429, -764, 614, -1117, +1205, -696, 790, 339, -273, 1233, -1086, 1316, +-1060, 534, -205, -674, 677, -1421, 873, -1199, +169, -192, -833, 801, -1128, 1214, -359, 856, +716, 78, 1249, -630, 668, -810, -719, -577, +-1628, -123, -1240, 357, 123, 606, 1268, 606, +1437, 255, 353, -275, -1087, -856, -1570, -866, +-883, -99, 452, 913, 1315, 1334, 1048, 755, +-155, -566, -1212, -1535, -1301, -1433, -473, -262, +606, 1293, 1113, 1831, 746, 1090, -162, -422, +-772, -1640, -879, -1613, -504, -362, 124, 1098, +470, 1581, 386, 862, 59, -530, -227, -1498, +-334, -1050, -70, 309, 163, 1481, 149, 1312, +-146, 8, -515, -1379, -588, -1755, -300, -598, +417, 1042, 933, 1882, 734, 1277, -25, -217, +-917, -1482, -1323, -1508, -835, -483, 129, 705, +1108, 1138, 1305, 635, 473, -61, -651, -495, +-1403, -325, -1065, 126, -4, 248, 925, -142, +1008, -609, 247, -423, -675, 243, -1084, 936, +-559, 896, 366, 33, 1001, -846, 728, -1072, +-228, -345, -1147, 483, -1331, 821, -385, 575, +836, -131, 1505, -592, 1046, -447, -229, 51, +-1487, 439, -1820, 399, -856, -66, 564, -454, +1644, -470, 1667, -44, 546, 520, -985, 695, +-1898, 403, -1631, -312, -397, -956, 1003, -898, +1731, -101, 1313, 892, 135, 1332, -1007, 858, +-1641, -273, -1317, -1309, -299, -1595, 871, -835, +1465, 572, 1203, 1729, 218, 2015, -935, 925, +-1555, -965, -1338, -2412, -286, -2418, 972, -691, +1726, 1700, 1211, 3111, -153, 2439, -1374, -33, +-1798, -2546, -999, -3417, 351, -1829, 1516, 1095, +1673, 3283, 614, 3181, -890, 695, -1864, -2279, +-1507, -3582, -85, -2210, 1315, 746, 1636, 3109, +780, 3155, -611, 983, -1477, -1892, -1332, -3250, +-179, -2308, 973, 112, 1186, 2403, 621, 2943, +-559, 1528, -1179, -811, -844, -2441, 16, -2466, +861, -984, 846, 1239, 178, 2552, -631, 2038, +-1021, 229, -495, -1742, 250, -2376, 711, -1240, +705, 735, -1, 1965, -587, 1637, -732, 212, +-362, -1155, 202, -1636, 419, -755, 299, 508, +-159, 1120, -301, 889, -69, 80, 210, -624, +212, -706, -178, -193, -575, 298, -594, 459, +-71, 49, 551, -326, 935, -376, 539, -5, +-396, 569, -1088, 725, -1093, 218, -198, -484, +814, -970, 1102, -857, 546, -83, -427, 838, +-1003, 1298, -750, 910, 42, -38, 738, -1002, +680, -1395, -13, -977, -714, 120, -714, 1037, +-19, 1396, 597, 953, 622, -94, 54, -990, +-537, -1210, -724, -750, -352, 1, 331, 651, +742, 882, 518, 731, -186, 275, -842, -213, +-886, -582, -133, -838, 660, -678, 899, -190, +448, 492, -382, 1211, -789, 1198, -775, 420, +-254, -854, 390, -1811, 586, -1521, 496, -64, +72, 1557, -282, 2275, -402, 1345, -472, -704, +-420, -2225, -116, -2158, 374, -513, 714, 1420, +620, 2231, 73, 1358, -707, -264, -1159, -1480, +-852, -1461, 62, -525, 1041, 481, 1453, 956, +897, 602, -518, 131, -1668, -165, -1727, -286, +-741, -249, 922, -182, 2057, -95, 1739, 107, +271, 311, -1503, 211, -2335, -14, -1560, -292, +253, -328, 1903, 13, 2209, 398, 991, 541, +-833, 147, -2163, -418, -1976, -807, -444, -512, +1275, 165, 2136, 823, 1556, 997, -120, 416, +-1744, -428, -2173, -1144, -1131, -1223, 669, -386, +1988, 853, 1986, 1634, 512, 1467, -1322, 174, +-2176, -1412, -1622, -2241, 113, -1500, 1720, 295, +2098, 2124, 904, 2582, -973, 1240, -2101, -909, +-1706, -2552, -46, -2416, 1574, -779, 2000, 1289, +921, 2438, -792, 2055, -1912, 371, -1704, -1353, +-286, -2072, 1280, -1548, 1791, -28, 1038, 1266, +-361, 1640, -1381, 943, -1344, -330, -470, -1234, +508, -1106, 897, -75, 697, 827, 111, 1034, +-392, 203, -472, -779, -305, -1042, -88, -483, +80, 686, 134, 1314, 55, 1011, -19, -190, +-32, -1376, 12, -1524, 124, -567, 132, 865, +-143, 1648, -339, 1199, -264, -66, -75, -1116, +252, -1309, 398, -614, 282, 372, -33, 858, +-409, 681, -567, 188, -369, -246, 148, -221, +549, -18, 595, -90, 234, -279, -222, -423, +-545, -393, -691, 236, -373, 869, 182, 996, +527, 544, 643, -472, 455, -1348, -46, -1365, +-519, -418, -804, 778, -725, 1491, -163, 1229, +650, 257, 1057, -794, 701, -1125, -136, -827, +-874, -202, -1029, 354, -542, 487, 281, 484, +877, 443, 856, 309, 268, 32, -559, -349, +-996, -735, -678, -708, 90, -267, 690, 266, +804, 745, 378, 835, -387, 397, -825, -126, +-716, -548, -149, -663, 599, -526, 899, -190, +530, 312, -310, 573, -1011, 689, -885, 370, +-173, -273, 754, -638, 1224, -658, 683, -146, +-326, 439, -1156, 659, -1260, 284, -561, -400, +566, -726, 1381, -413, 1276, 476, 366, 1007, +-706, 761, -1357, -205, -1156, -1174, -420, -1305, +405, -473, 1065, 814, 1144, 1503, 720, 1208, +-67, 41, -822, -1142, -1255, -1370, -1155, -675, +-361, 374, 647, 955, 1469, 785, 1516, 30, +435, -528, -911, -462, -1717, 47, -1371, 631, +-92, 586, 1100, -158, 1437, -1052, 796, -1248, +-426, -488, -1246, 905, -985, 1915, 4, 1705, +952, 254, 1046, -1511, 249, -2355, -803, -1799, +-1293, 2, -860, 1680, 233, 2160, 1328, 1458, +1588, 89, 702, -1127, -725, -1479, -1759, -1056, +-1689, -407, -642, 164, 764, 400, 1675, 572, +1703, 863, 930, 1104, -525, 932, -1581, -75, +-1833, -1515, -1246, -2394, -42, -2070, 1175, -337, +1900, 2034, 1733, 3448, 641, 2906, -905, 552, +-1950, -2318, -2003, -3927, -1105, -3214, 375, -718, +1579, 2163, 2195, 3670, 1649, 3163, 148, 1105, +-1316, -1585, -2296, -3154, -1874, -3003, -581, -1369, +776, 924, 1981, 2483, 2140, 2657, 1196, 1452, +-397, -312, -2015, -1682, -2413, -2171, -1477, -1522, +412, -193, 2076, 1114, 2400, 1805, 1296, 1457, +-715, 351, -2107, -917, -2061, -1504, -760, -1133, +819, -159, 1786, 807, 1574, 1165, 488, 825, +-724, 20, -1488, -753, -1341, -1070, -566, -723, +438, -19, 1250, 744, 1348, 1197, 906, 952, +-94, 206, -1299, -694, -1789, -1429, -1241, -1459, +121, -726, 1358, 495, 1808, 1662, 1209, 2167, +-48, 1616, -1047, -103, -1532, -1971, -1137, -3013, +-256, -2480, 398, -364, 861, 2164, 864, 3683, +843, 3138, 644, 751, 55, -2251, -808, -3838, +-1770, -3288, -1865, -848, -860, 2045, 989, 3266, +2592, 2686, 2846, 790, 1285, -1177, -1239, -2106, +-3082, -1731, -3133, -818, -1453, 42, 1024, 630, +2822, 813, 3118, 964, 1791, 992, -442, 656, +-2299, -144, -3008, -1089, -2192, -1703, -311, -1386, +1739, -253, 2838, 1118, 2543, 1975, 919, 1647, +-1286, 348, -2680, -1203, -2707, -1953, -1166, -1448, +1013, -39, 2436, 1392, 2457, 1703, 994, 759, +-805, -653, -2013, -1420, -1889, -1022, -655, 191, +640, 1127, 1362, 987, 1100, 127, 192, -786, +-529, -864, -523, -259, -161, 531, 208, 717, +63, 99, -443, -611, -616, -732, -220, 38, +493, 882, 1042, 1194, 980, 467, 200, -879, +-882, -1621, -1475, -1299, -1153, -166, -107, 1167, +1139, 1757, 1590, 1378, 1094, 296, -18, -835, +-1075, -1572, -1470, -1572, -1043, -844, 53, 239, +1003, 1255, 1195, 1723, 740, 1396, -48, 323, +-719, -840, -731, -1637, -391, -1512, -11, -656, +398, 337, 202, 1009, -139, 1052, -89, 689, +208, 331, 740, 131, 694, -62, -159, -562, +-1149, -1170, -1480, -1592, -884, -1050, 577, 451, +1877, 2202, 2056, 2892, 943, 1647, -1019, -688, +-2559, -2880, -2409, -3251, -571, -1520, 1604, 1063, +2716, 2729, 2078, 2592, 189, 868, -1707, -1086, +-2407, -1891, -1601, -1366, 183, -172, 1567, 836, +1767, 819, 809, 226, -523, -336, -1021, -577, +-704, -121, 59, 607, 521, 849, 197, 450, +-379, -327, -750, -1148, -377, -1111, 619, -411, +1416, 677, 1287, 1376, 121, 1166, -1347, 267, +-2150, -999, -1541, -1646, 12, -1036, 1716, 372, +2525, 1663, 1828, 1850, 15, 465, -1900, -1446, +-2641, -2470, -1802, -1623, 48, 550, 1674, 2395, +2193, 2659, 1524, 996, 192, -1304, -975, -2552, +-1412, -2018, -1136, -273, -507, 1257, 72, 1681, +438, 853, 638, -164, 891, -529, 923, -35, +531, 494, -185, 256, -1047, -611, -1451, -1527, +-1277, -1521, -481, -326, 806, 1420, 1724, 2426, +1905, 2082, 1187, 564, -264, -1257, -1627, -2386, +-2109, -2195, -1642, -1163, -418, 130, 1108, 1396, +1943, 2102, 1901, 2044, 1033, 1328, -201, -57, +-1268, -1683, -1782, -2645, -1584, -2546, -811, -1172, +462, 779, 1506, 2544, 1915, 3149, 1495, 2153, +400, 283, -899, -1773, -1861, -3017, -1902, -2646, +-966, -1083, 419, 867, 1545, 2090, 1816, 2108, +1127, 1232, -52, 156, -1006, -488, -1247, -823, +-782, -879, -9, -1024, 527, -1052, 455, -724, +5, 111, -231, 1231, 57, 2064, 494, 2013, +739, 932, 492, -750, -238, -2199, -884, -2702, +-1185, -1990, -913, -220, -106, 1610, 849, 2736, +1441, 2585, 1445, 1219, 762, -648, -361, -2043, +-1379, -2495, -1817, -1781, -1345, -256, -177, 1059, +1104, 1601, 1756, 1411, 1573, 676, 723, 161, +-283, -20, -1004, -262, -1420, -721, -1242, -1302, +-683, -1630, 3, -1139, 984, 336, 1612, 1967, +1710, 2829, 1140, 2211, -269, 312, -1742, -1927, +-2493, -3103, -2020, -2671, -285, -939, 1738, 1145, +2818, 2422, 2384, 2457, 697, 1425, -1362, -14, +-2581, -1056, -2247, -1645, -809, -1635, 951, -1149, +1994, -404, 1736, 622, 650, 1456, -533, 1879, +-1095, 1504, -886, 336, -204, -1055, 263, -1936, +213, -1848, -15, -885, -302, 403, -82, 1309, +596, 1425, 878, 1090, 736, 414, -45, -251, +-961, -638, -1280, -1016, -984, -1153, -20, -937, +1003, -111, 1535, 1022, 1211, 1781, 137, 1584, +-899, 368, -1487, -1142, -1122, -1927, -168, -1423, +911, -155, 1356, 1219, 817, 1661, -85, 737, +-930, -533, -882, -1308, -112, -926, 646, 343, +788, 1254, 232, 1097, -491, 4, -890, -1220, +-600, -1601, 195, -731, 979, 685, 1170, 1668, +610, 1524, -357, 313, -1166, -1023, -1257, -1610, +-612, -1115, 356, 42, 1108, 993, 1262, 1259, +780, 654, -189, -305, -940, -935, -1111, -856, +-562, -150, 262, 620, 643, 920, 613, 448, +132, -323, -259, -918, -141, -834, 102, -82, +454, 694, 351, 914, -193, 507, -762, -124, +-973, -533, -429, -481, 488, -192, 1349, -66, +1320, -61, 392, -73, -680, 34, -1315, 431, +-1060, 726, -172, 604, 632, 3, 894, -743, +525, -1183, -61, -932, -378, -94, -196, 725, +229, 1203, 507, 1068, 343, 388, -368, -311, +-997, -828, -1096, -1004, -388, -829, 796, -481, +1717, 165, 1780, 901, 664, 1421, -930, 1306, +-2097, 406, -2112, -832, -829, -1796, 896, -1836, +2051, -788, 2048, 783, 982, 1874, -515, 1886, +-1456, 732, -1573, -799, -845, -1589, 161, -1278, +689, -217, 799, 715, 516, 881, 358, 289, +259, -449, 115, -615, -200, -19, -714, 818, +-848, 1070, -624, 483, -2, -763, 717, -1702, +1099, -1401, 962, -178, 274, 1308, -490, 1953, +-977, 1268, -889, -248, -323, -1425, 192, -1448, +599, -609, 695, 496, 551, 985, 180, 604, +-258, -156, -465, -609, -467, -388, -285, 270, +-64, 748, 197, 621, 453, -106, 597, -871, +435, -958, -63, -457, -571, 309, -794, 862, +-486, 735, 162, 276, 757, -245, 955, -449, +549, -234, -148, 93, -874, 148, -951, -152, +-469, -540, 251, -734, 792, -243, 770, 731, +537, 1566, 75, 1554, -378, 408, -536, -1328, +-639, -2457, -450, -2117, -7, -346, 350, 1632, +701, 2559, 828, 1988, 567, 305, 2, -1220, +-642, -1747, -1020, -1299, -843, -438, -206, 161, +470, 318, 924, 357, 934, 648, 506, 1122, +-18, 1247, -506, 528, -684, -818, -516, -2054, +-388, -2395, -199, -1284, 129, 694, 616, 2400, +1088, 2851, 1063, 1782, 343, -295, -718, -2136, +-1479, -2697, -1460, -1854, -549, -116, 809, 1426, +1597, 1984, 1475, 1450, 513, 374, -716, -570, +-1150, -926, -864, -719, -229, -404, 281, -150, +402, -109, 355, -119, 277, 213, 319, 630, +205, 870, -154, 669, -394, -59, -478, -814, +-224, -1084, 259, -673, 560, 80, 472, 665, +-56, 727, -506, 210, -626, -313, -215, -395, +525, -81, 931, 466, 767, 697, 94, 310, +-746, -476, -1171, -1091, -976, -1148, -187, -477, +793, 648, 1405, 1468, 1319, 1466, 552, 715, +-555, -390, -1367, -1297, -1517, -1314, -874, -829, +228, -251, 1296, 314, 1646, 704, 946, 985, +-76, 1164, -921, 933, -1044, 66, -557, -1115, +-10, -1922, 347, -1790, 289, -619, 58, 992, +-24, 2044, 230, 1936, 663, 798, 752, -551, +257, -1394, -716, -1354, -1460, -764, -1249, -69, +-256, 360, 1069, 445, 1837, 441, 1474, 499, +246, 527, -1084, 465, -1631, 142, -1127, -480, +-17, -1054, 879, -1209, 1079, -748, 609, 156, +-90, 1161, -411, 1522, -410, 1029, -59, 61, +287, -834, 205, -1173, -16, -824, -261, -201, +-341, 229, -102, 333, 182, 306, 458, 282, +499, 330, 261, 373, -91, 204, -496, -157, +-464, -458, -211, -579, 80, -514, 410, -331, +350, -75, 182, 347, -62, 766, -161, 1010, +-60, 721, 3, 51, 154, -826, 97, -1356, +-52, -1178, -80, -465, -260, 526, -190, 1232, +58, 1312, 308, 757, 563, -52, 401, -737, +34, -1040, -334, -833, -586, -370, -509, 134, +-200, 533, 235, 628, 597, 516, 670, 242, +432, 0, -28, -137, -416, -200, -535, -279, +-403, -412, -99, -558, 185, -416, 274, 32, +254, 651, 169, 1150, 283, 1028, 346, 399, +105, -594, -262, -1467, -709, -1512, -763, -745, +-289, 404, 449, 1365, 979, 1475, 993, 872, +460, -42, -332, -747, -904, -1049, -955, -935, +-452, -501, 223, 53, 769, 628, 891, 898, +358, 835, -172, 306, -459, -353, -412, -691, +-30, -622, 152, -136, 88, 180, -60, 98, +-127, -160, 63, -245, 287, 177, 360, 751, +246, 968, -5, 386, -333, -645, -494, -1488, +-260, -1287, 48, -130, 347, 1079, 537, 1609, +251, 939, -40, -323, -155, -1213, -269, -1073, +-55, -262, 105, 664, 12, 943, -4, 402, +-130, -384, 19, -805, 293, -594, 292, 61, +234, 687, -68, 829, -285, 406, -284, -231, +-169, -711, 93, -819, 241, -374, 282, 199, +215, 579, -4, 658, -134, 326, -99, -84, +-49, -361, -14, -451, 66, -203, 91, 93, +45, 240, 22, 153, -36, -8, -100, -254, +62, -231, 234, -4, 204, 246, 118, 546, +-110, 492, -309, 103, -249, -554, -50, -982, +186, -880, 367, -161, 318, 771, 106, 1258, +-104, 1084, -206, 230, -243, -722, -75, -1262, +107, -1062, 132, -252, 167, 521, 126, 967, +17, 729, -35, 110, -28, -308, -18, -367, +36, -103, 71, 143, 30, 39, 68, -301, +-37, -512, -140, -384, -82, 107, -58, 683, +216, 956, 417, 699, 275, -37, 40, -895, +-223, -1230, -351, -908, -317, 36, -143, 944, +104, 1156, 330, 684, 497, -154, 422, -664, +186, -686, -107, -183, -410, 228, -611, 181, +-557, -42, -117, -277, 521, -101, 881, 331, +798, 559, 278, 362, -340, -109, -690, -495, +-739, -560, -411, -238, 68, 75, 497, 297, +680, 306, 569, 137, 360, 70, -70, 2, +-471, -74, -675, -109, -602, -153, -49, -164, +531, -25, 769, 70, 490, 89, -25, 67, +-327, 34, -394, 13, -78, 76, 219, 87, +136, 20, 19, -130, -167, -207, -199, -128, +64, -97, 357, 69, 319, 147, 184, 134, +85, 168, -125, 97, -220, -33, -372, -125, +-343, -113, -40, -167, 311, -172, 643, -128, +595, 5, 231, 308, -165, 408, -543, 336, +-630, -55, -344, -417, 127, -427, 508, -190, +524, 141, 269, 253, -20, 108, -102, -214, +27, -213, 51, 161, -12, 570, -272, 631, +-481, 132, -397, -688, -64, -1209, 630, -981, +1171, 9, 982, 1147, 256, 1656, -800, 1158, +-1518, -241, -1264, -1544, -364, -1800, 811, -820, +1588, 685, 1432, 1597, 595, 1296, -475, 41, +-1183, -1105, -1234, -1185, -641, -250, 143, 903, +684, 1248, 916, 431, 695, -914, 196, -1658, +-164, -1111, -303, 385, -292, 1708, -231, 1925, +-163, 864, -160, -836, -163, -1963, 165, -1809, +398, -632, 567, 849, 612, 1662, 289, 1424, +-190, 470, -681, -564, -777, -1016, -566, -850, +-80, -333, 507, 71, 837, 289, 901, 232, +512, 197, -52, 351, -562, 333, -856, 197, +-641, -108, -217, -448, 184, -594, 486, -444, +617, -49, 603, 255, 465, 406, 161, 420, +-256, 334, -731, 236, -914, 101, -635, -276, +-53, -773, 677, -909, 1211, -593, 1064, 269, +503, 1141, -259, 1359, -1020, 834, -1235, -263, +-885, -1287, -10, -1475, 871, -837, 1252, 219, +1095, 1190, 342, 1315, -482, 634, -972, -276, +-941, -898, -393, -896, 316, -298, 755, 282, +659, 494, 245, 355, -134, 29, -211, -208, +-58, -236, 90, -41, 45, 163, -169, 269, +-328, 198, -253, -103, 100, -383, 521, -469, +670, -285, 415, 163, -102, 566, -503, 711, +-578, 410, -384, -166, 38, -749, 399, -900, +537, -484, 503, 193, 217, 859, -153, 943, +-398, 471, -498, -247, -354, -895, 123, -894, +588, -372, 675, 337, 308, 855, -300, 862, +-636, 278, -446, -530, 120, -987, 514, -883, +584, -8, 235, 925, -242, 1253, -413, 643, +-426, -541, -45, -1361, 365, -1229, 439, -142, +376, 1060, 4, 1518, -271, 802, -301, -472, +-79, -1291, 153, -1139, 205, -108, 129, 869, +-113, 1042, -236, 369, -86, -499, 280, -863, +557, -504, 481, 359, 41, 936, -570, 674, +-883, -219, -596, -992, 157, -1090, 885, -237, +1104, 885, 756, 1306, -61, 813, -874, -321, +-1108, -1202, -637, -1137, 151, -286, 755, 668, +890, 1094, 461, 629, -41, -224, -269, -751, +-327, -690, -137, -80, 25, 501, -7, 659, +-145, 224, -227, -349, 15, -614, 477, -430, +708, 140, 552, 529, 30, 549, -648, 156, +-838, -291, -542, -480, 41, -324, 619, 13, +788, 251, 529, 308, -27, 55, -406, -116, +-330, -153, -93, -21, 108, 144, 125, 136, +-42, 50, -181, -146, -112, -267, 131, -245, +400, -91, 520, 151, 406, 487, -92, 571, +-580, 203, -693, -337, -446, -820, 100, -828, +584, -193, 750, 672, 523, 1107, 82, 823, +-244, -18, -460, -912, -446, -1181, -262, -679, +-20, 293, 313, 1014, 511, 1044, 495, 392, +201, -508, -215, -968, -417, -770, -296, -96, +36, 583, 303, 748, 284, 412, -14, -74, +-284, -455, -255, -398, 58, -138, 476, 23, +604, 77, 249, 64, -306, 133, -617, 265, +-499, 320, -65, 73, 353, -308, 506, -619, +365, -588, 203, -81, 13, 503, -138, 845, +-181, 650, -274, 35, -238, -594, -46, -774, +116, -536, 256, -135, 440, 309, 432, 519, +207, 539, -151, 405, -561, 108, -566, -319, +-182, -647, 212, -685, 556, -401, 467, 146, +194, 719, -15, 902, -207, 506, -191, -180, +-90, -751, -20, -775, -32, -313, -71, 269, +-29, 502, 172, 319, 430, 8, 433, -149, +202, -41, -233, 61, -535, 87, -533, -103, +-208, -265, 331, -213, 641, 5, 658, 235, +181, 245, -381, 163, -522, -58, -361, -178, +63, -165, 428, -100, 410, -21, 142, 76, +-185, 270, -367, 254, -215, 52, 139, -340, +436, -652, 473, -477, 154, 234, -267, 979, +-496, 1055, -399, 359, -26, -788, 390, -1514, +561, -1155, 370, 50, -2, 1241, -336, 1588, +-405, 782, -70, -527, 257, -1233, 310, -978, +56, -74, -291, 686, -300, 590, -34, -65, +449, -467, 692, -314, 319, 345, -245, 888, +-696, 656, -728, -162, -176, -1049, 504, -1247, +830, -644, 599, 420, 55, 1265, -413, 1258, +-536, 569, -306, -399, 61, -1033, 312, -1068, +298, -519, 139, 184, -43, 658, -147, 757, +-25, 401, 67, -5, 138, -297, 160, -347, +53, -181, -77, -51, -241, -48, -239, -61, +-52, -27, 242, 75, 439, 231, 383, 229, +109, 115, -249, -44, -414, -155, -321, -146, +12, -90, 314, -58, 313, -74, 132, -70, +-123, -53, -148, 114, 80, 242, 349, 297, +291, 256, -70, 46, -435, -201, -604, -480, +-271, -588, 299, -450, 716, 28, 798, 608, +416, 964, -232, 817, -715, 135, -758, -637, +-459, -1110, 100, -954, 562, -304, 732, 477, +639, 947, 215, 858, -196, 375, -552, -233, +-695, -535, -426, -526, 40, -261, 482, -24, +640, 4, 473, -7, 132, 19, -196, 228, +-304, 464, -266, 517, -144, 237, -47, -249, +0, -665, 48, -772, 151, -503, 332, 7, +383, 512, 279, 769, -18, 731, -424, 380, +-530, -177, -325, -631, 33, -809, 339, -629, +438, -145, 307, 321, 141, 567, 48, 569, +-65, 335, -127, 131, -202, -43, -305, -218, +-301, -382, -107, -602, 247, -648, 599, -378, +681, 299, 473, 1040, -25, 1325, -581, 888, +-877, -237, -759, -1333, -198, -1684, 518, -1034, +1024, 212, 970, 1244, 417, 1513, -279, 867, +-800, -134, -815, -851, -432, -955, 68, -489, +448, 44, 531, 292, 379, 176, 218, -13, +107, 47, 17, 349, -173, 570, -433, 362, +-501, -225, -337, -843, 74, -935, 529, -379, +728, 400, 578, 922, 88, 788, -435, 188, +-598, -437, -454, -630, -76, -309, 275, 143, +356, 318, 234, 73, 73, -305, -10, -441, +-2, -55, 102, 543, 98, 820, -83, 492, +-239, -290, -289, -946, -149, -958, 158, -285, +349, 552, 355, 942, 227, 637, -39, -68, +-142, -571, -174, -509, -147, -51, -18, 350, +-65, 275, -100, -171, -74, -504, 110, -375, +470, 200, 623, 770, 361, 785, -203, 123, +-758, -715, -832, -1028, -403, -623, 215, 304, +750, 945, 882, 798, 577, 120, 69, -586, +-469, -735, -748, -332, -597, 295, -243, 575, +139, 355, 439, -107, 605, -468, 582, -415, +335, -49, -44, 372, -477, 484, -738, 240, +-696, -172, -306, -500, 354, -417, 981, -77, +1084, 360, 536, 565, -320, 337, -1029, -112, +-1032, -544, -447, -618, 294, -272, 820, 313, +848, 710, 480, 653, -31, 162, -450, -476, +-588, -819, -443, -637, -167, -23, 125, 555, +397, 744, 567, 462, 473, -94, 98, -472, +-361, -409, -604, -139, -432, 89, 1, 138, +361, -26, 437, -95, 247, 8, -26, 173, +-124, 300, -53, 250, 1, 20, 20, -294, +-107, -483, -253, -430, -132, -89, 155, 351, +393, 572, 433, 423, 151, 44, -267, -286, +-474, -365, -276, -160, 34, 19, 283, 32, +346, -71, 119, -160, -97, -56, -126, 200, +-13, 450, 119, 477, 99, 207, -68, -280, +-180, -740, -123, -811, 78, -410, 206, 312, +152, 878, 67, 984, -17, 517, -12, -266, +0, -813, -77, -898, -111, -443, -111, 170, +-4, 549, 136, 510, 223, 209, 264, -32, +165, -52, -119, 58, -354, 12, -340, -231, +-103, -506, 256, -519, 448, -100, 360, 474, +69, 830, -295, 686, -418, 72, -270, -562, +85, -834, 418, -625, 385, -48, 142, 512, +-179, 683, -378, 444, -305, -73, -52, -458, +304, -462, 530, -119, 414, 296, -56, 399, +-553, 125, -696, -272, -296, -466, 382, -261, +837, 219, 733, 529, 121, 446, -573, 45, +-947, -371, -631, -486, 117, -267, 801, 41, +945, 262, 418, 274, -300, 152, -731, 17, +-644, -63, -153, -112, 332, -114, 509, -109, +372, -84, 48, 50, -177, 176, -160, 189, +-54, 37, 47, -152, -2, -271, -117, -135, +-93, 159, 26, 355, 188, 265, 244, -73, +147, -387, 21, -467, -84, -118, -126, 328, +-149, 507, -145, 340, -112, -134, -2, -479, +219, -423, 384, -13, 450, 396, 200, 477, +-255, 121, -609, -403, -635, -580, -253, -276, +269, 328, 709, 714, 756, 546, 411, -83, +-148, -673, -665, -738, -794, -271, -446, 420, +163, 729, 634, 415, 672, -203, 335, -602, +-66, -429, -321, 142, -325, 616, -165, 506, +-47, -62, -9, -645, -26, -792, 38, -337, +254, 409, 435, 932, 372, 877, 0, 296, +-437, -540, -605, -1084, -438, -987, 29, -311, +500, 583, 668, 1135, 430, 952, -25, 193, +-383, -594, -454, -927, -253, -619, -6, 5, +149, 453, 170, 447, 157, 122, 214, -178, +222, -181, 97, 133, -110, 368, -368, 235, +-430, -219, -184, -639, 175, -612, 480, -83, +494, 572, 241, 782, -131, 471, -369, -167, +-382, -615, -224, -532, 57, -138, 241, 243, +283, 309, 220, 123, 132, -99, 26, -75, +-89, 75, -266, 162, -340, 82, -177, -154, +60, -301, 335, -236, 464, 69, 345, 333, +50, 367, -318, 124, -514, -259, -401, -446, +-50, -327, 321, 45, 451, 422, 369, 525, +149, 259, -96, -218, -248, -565, -316, -536, +-287, -124, -138, 336, 132, 531, 351, 373, +444, 29, 291, -248, -2, -310, -256, -192, +-412, -36, -310, 52, -132, 58, 117, 42, +315, 33, 366, 101, 314, 145, 101, 123, +-146, 16, -327, -155, -364, -283, -255, -273, +21, -90, 305, 133, 430, 289, 342, 258, +40, 122, -203, -8, -277, -58, -197, -46, +-34, -131, 70, -291, 104, -385, 36, -234, +-6, 227, 87, 710, 201, 809, 231, 342, +49, -438, -203, -971, -359, -867, -316, -231, +-69, 490, 207, 858, 408, 641, 399, 95, +201, -404, -93, -548, -311, -268, -371, 142, +-255, 334, -15, 110, 192, -276, 318, -447, +286, -183, 150, 392, -57, 778, -211, 631, +-194, -28, -103, -755, 33, -997, 133, -584, +95, 194, -29, 781, -134, 813, -68, 333, +193, -209, 427, -418, 352, -285, -72, -35, +-559, 12, -763, -167, -421, -307, 287, -154, +881, 254, 972, 665, 420, 725, -394, 304, +-951, -393, -890, -953, -286, -978, 406, -412, +799, 442, 672, 1026, 197, 969, -196, 334, +-373, -420, -342, -818, -202, -661, -73, -148, +46, 294, 156, 421, 281, 207, 294, -80, +172, -131, -39, 51, -264, 257, -322, 246, +-144, -46, 96, -415, 194, -532, 135, -295, +-25, 158, -49, 535, 76, 570, 197, 255, +205, -178, -30, -424, -294, -406, -406, -160, +-260, 89, 112, 185, 493, 160, 615, 72, +265, 22, -262, 24, -579, 48, -506, -15, +-79, -98, 368, -122, 548, -84, 347, 15, +-46, 68, -431, 34, -501, -38, -124, -37, +305, 23, 564, 161, 399, 267, -24, 172, +-379, -125, -563, -474, -381, -590, -15, -341, +398, 246, 708, 781, 632, 868, 160, 460, +-450, -305, -870, -944, -802, -1048, -210, -565, +536, 275, 1059, 978, 920, 1115, 159, 601, +-665, -232, -1006, -935, -602, -1053, 91, -530, +617, 237, 654, 800, 209, 814, -168, 354, +-336, -236, -211, -565, 118, -494, 219, -143, +92, 218, -129, 306, -221, 127, -79, -106, +132, -147, 241, 48, 112, 257, -54, 207, +-53, -129, 53, -437, 118, -425, 27, -56, +-169, 439, -305, 615, -200, 348, 114, -161, +425, -570, 486, -599, 205, -238, -236, 252, +-492, 552, -389, 529, -38, 206, 285, -225, +370, -498, 210, -478, -55, -212, -201, 138, +-124, 369, 65, 403, 157, 242, 119, 5, +-39, -207, -197, -282, -210, -257, -90, -198, +138, -68, 311, 118, 332, 348, 158, 471, +-112, 335, -326, -71, -386, -516, -175, -680, +132, -432, 352, 110, 339, 620, 125, 737, +-111, 370, -225, -209, -111, -623, 61, -598, +148, -154, 55, 305, -180, 473, -291, 281, +-141, -95, 218, -315, 550, -243, 564, 69, +134, 329, -503, 332, -803, 9, -561, -419, +36, -591, 616, -328, 776, 274, 446, 767, +-69, 762, -431, 183, -490, -573, -227, -937, +41, -685, 136, 17, 107, 675, 56, 844, +149, 491, 263, -119, 287, -601, 77, -659, +-310, -290, -579, 177, -480, 439, -7, 370, +499, 98, 704, -122, 445, -190, -114, -140, +-507, -68, -473, -22, -139, 16, 220, 67, +328, 113, 133, 128, -131, 62, -218, -53, +-32, -182, 272, -242, 366, -119, 156, 97, +-252, 291, -526, 349, -369, 182, 46, -139, +446, -407, 562, -472, 283, -248, -199, 168, +-498, 516, -390, 570, -7, 275, 372, -182, +419, -527, 134, -542, -207, -254, -391, 119, +-290, 367, 75, 399, 365, 278, 421, 90, +266, -112, -93, -283, -382, -362, -440, -290, +-286, -99, 28, 192, 372, 435, 514, 430, +383, 197, 48, -163, -311, -437, -464, -418, +-309, -128, 43, 149, 249, 263, 212, 205, +56, 35, -71, -33, 5, -3, 218, 17, +288, -14, 79, -108, -305, -194, -558, -153, +-435, 28, -18, 193, 468, 262, 694, 184, +529, -33, 76, -191, -385, -207, -603, -117, +-491, 8, -173, 102, 159, 62, 399, 14, +461, 55, 351, 93, 86, 100, -173, -16, +-339, -172, -357, -247, -204, -100, 17, 143, +216, 244, 238, 172, 115, -60, 51, -228, +122, -155, 188, 93, 83, 244, -224, 155, +-521, -133, -492, -363, -98, -238, 424, 118, +752, 409, 644, 391, 96, 15, -533, -402, +-797, -469, -494, -154, 128, 315, 562, 530, +524, 258, 111, -244, -254, -557, -290, -386, +-83, 126, 183, 535, 313, 521, 139, 106, +-223, -364, -445, -526, -315, -317, 69, 36, +427, 297, 486, 314, 230, 226, -84, 122, +-296, -18, -343, -187, -195, -390, 13, -408, +116, -131, 140, 316, 102, 610, 124, 509, +218, 30, 191, -495, 8, -656, -290, -356, +-501, 193, -399, 554, -45, 459, 387, 36, +666, -362, 572, -400, 172, -79, -387, 254, +-734, 303, -605, 41, -135, -254, 381, -299, +632, -42, 496, 289, 127, 371, -236, 120, +-403, -269, -305, -461, -98, -303, 137, 119, +221, 480, 167, 497, 51, 162, -87, -302, +-67, -562, 19, -470, 108, -73, 126, 367, +-16, 572, -189, 461, -283, 73, -200, -381, +147, -600, 480, -427, 476, 24, 150, 438, +-363, 494, -648, 169, -450, -222, 81, -341, +588, -70, 662, 270, 245, 301, -344, -82, +-658, -554, -436, -595, 125, -36, 550, 722, +514, 1033, 81, 515, -372, -525, -499, -1215, +-158, -1029, 299, -32, 446, 1040, 220, 1294, +-227, 553, -501, -577, -290, -1225, 224, -920, +579, 115, 501, 1014, 1, 1066, -554, 302, +-710, -688, -356, -1129, 268, -688, 744, 262, +760, 979, 259, 964, -433, 300, -788, -553, +-641, -979, -117, -740, 470, -50, 675, 622, +467, 848, 41, 517, -346, -123, -407, -604, +-182, -640, 57, -232, 146, 268, 68, 463, +-69, 254, -73, -82, 118, -263, 309, -126, +280, 156, 31, 246, -331, 52, -499, -259, +-335, -407, 37, -231, 410, 217, 556, 539, +354, 506, -9, 89, -312, -449, -439, -672, +-321, -444, -106, 73, 128, 530, 291, 645, +348, 368, 279, -103, 83, -493, -168, -599, +-380, -335, -381, 138, -182, 484, 102, 474, +387, 141, 477, -216, 309, -329, -60, -120, +-440, 129, -528, 135, -261, -81, 155, -297, +455, -218, 451, 125, 185, 486, -183, 536, +-405, 176, -339, -376, -18, -739, 309, -632, +366, -119, 137, 519, -189, 845, -344, 612, +-214, 19, 126, -551, 348, -752, 312, -477, +18, 46, -326, 436, -376, 501, -127, 318, +229, 25, 394, -187, 200, -264, -116, -267, +-270, -174, -196, -16, 47, 183, 232, 295, +178, 228, -36, 37, -245, -146, -246, -226, +53, -199, 355, -64, 344, 78, 46, 167, +-279, 175, -369, 92, -198, -34, 88, -113, +260, -129, 250, -90, 117, -42, -86, 41, +-174, 113, -116, 152, -4, 124, 75, 10, +60, -130, 20, -230, -35, -180, -49, -11, +-18, 184, 18, 259, 95, 205, 145, 34, +92, -168, -70, -272, -235, -282, -269, -126, +-79, 178, 190, 422, 362, 397, 324, 69, +13, -329, -280, -508, -340, -309, -191, 114, +97, 424, 259, 392, 184, 74, -13, -247, +-139, -338, -112, -152, 46, 135, 234, 261, +157, 136, -99, -75, -290, -198, -293, -142, +-52, 19, 274, 155, 410, 167, 267, 46, +-62, -66, -350, -110, -398, -90, -130, -44, +229, 5, 350, 28, 191, 53, -94, 100, +-274, 102, -168, 29, 124, -60, 279, -140, +195, -180, -58, -122, -278, 46, -291, 235, +-96, 301, 156, 149, 262, -137, 234, -369, +68, -323, -62, -9, -79, 294, -94, 376, +-107, 167, -180, -174, -182, -364, 23, -252, +307, 21, 482, 293, 348, 328, -90, 144, +-489, -121, -590, -331, -334, -331, 154, -86, +538, 213, 536, 385, 211, 310, -215, 13, +-400, -272, -193, -387, 82, -239, 130, 45, +-58, 285, -206, 340, -121, 153, 143, -153, +395, -311, 403, -221, 129, 42, -278, 285, +-516, 276, -435, -13, -80, -362, 313, -430, +441, -86, 292, 463, 97, 667, -41, 275, +-167, -401, -261, -795, -311, -508, -236, 187, +66, 662, 397, 568, 446, 106, 250, -351, +-98, -461, -346, -203, -330, 103, -89, 222, +94, 154, 112, -59, 58, -182, 19, -84, +113, 135, 192, 313, 87, 239, -157, -75, +-311, -490, -273, -606, 6, -221, 315, 459, +436, 890, 232, 660, -219, -136, -548, -890, +-440, -921, 79, -268, 587, 574, 592, 900, +100, 462, -467, -259, -649, -611, -281, -372, +239, 143, 537, 369, 457, 108, 79, -235, +-302, -284, -469, 22, -298, 321, 76, 315, +349, 45, 326, -211, 67, -295, -222, -158, +-264, 18, -42, 103, 141, 136, 149, 105, +48, 81, -27, 40, -28, -18, -12, -110, +-79, -199, -138, -174, -60, -27, 95, 195, +164, 296, 157, 200, 115, -61, 12, -295, +-199, -281, -355, -57, -231, 211, 100, 309, +374, 190, 351, -131, 81, -417, -163, -374, +-172, 32, -141, 507, -145, 627, -78, 181, +42, -473, 156, -746, 196, -399, 130, 229, +6, 576, -30, 472, -98, 72, -157, -252, +-133, -273, -43, -124, 48, 2, 69, -12, +91, -77, 142, -49, 206, 159, 80, 311, +-179, 212, -379, -100, -306, -375, 4, -277, +323, 30, 427, 271, 251, 210, -103, -60, +-395, -242, -418, -151, -113, 129, 343, 338, +470, 282, 174, -80, -275, -406, -467, -459, +-206, -148, 212, 337, 377, 547, 242, 281, +2, -200, -212, -460, -275, -263, -146, 208, +113, 433, 247, 143, 73, -393, -190, -545, +-248, -154, 35, 442, 373, 747, 401, 428, +53, -283, -362, -775, -517, -687, -369, -132, +74, 535, 508, 814, 552, 464, 216, -181, +-262, -655, -461, -637, -243, -159, 95, 415, +206, 640, 55, 365, -131, -168, -126, -571, +47, -502, 234, -41, 309, 426, 165, 557, +-148, 248, -468, -208, -474, -457, -95, -344, +322, -12, 421, 265, 189, 280, -72, 74, +-78, -105, 26, -136, 33, 23, -73, 133, +-173, 89, -173, -105, -175, -267, -123, -267, +143, -52, 491, 248, 623, 476, 273, 446, +-333, 74, -775, -424, -738, -765, -270, -592, +315, 18, 707, 694, 756, 914, 397, 519, +-208, -244, -563, -803, -599, -772, -343, -268, +-19, 368, 160, 636, 280, 447, 384, 31, +362, -288, 155, -321, -119, -128, -366, 75, +-475, 131, -334, 40, -42, -91, 294, -106, +507, -7, 415, 137, 33, 193, -326, 129, +-422, -45, -169, -188, 119, -229, 177, -166, +74, 20, -48, 197, -52, 275, 23, 155, +69, -70, 51, -231, 65, -197, 27, 9, +-49, 157, -197, 134, -179, -45, -64, -123, +92, -67, 235, 62, 157, 133, -2, 41, +-109, -108, -103, -118, -10, 52, 134, 205, +97, 199, -110, -73, -311, -410, -322, -474, +19, -121, 459, 428, 585, 767, 248, 582, +-237, -81, -558, -780, -515, -946, -162, -412, +199, 362, 419, 838, 400, 634, 189, 16, +-54, -389, -183, -311, -205, 9, -212, 120, +-239, -112, -130, -472, 74, -391, 326, 104, +466, 696, 292, 903, -31, 483, -334, -338, +-502, -987, -400, -1005, -8, -422, 377, 422, +481, 956, 268, 864, -110, 248, -320, -358, +-233, -673, -45, -515, 14, -68, 47, 287, +143, 265, 147, 2, 68, -175, -144, -88, +-242, 288, -119, 486, 78, 246, 234, -294, +165, -653, 52, -553, -38, -95, -165, 396, +-333, 558, -316, 417, -22, 101, 415, -179, +667, -335, 427, -336, -150, -210, -713, -14, +-746, 151, -282, 216, 358, 195, 733, 149, +514, 103, -48, -14, -410, -214, -373, -419, +-106, -369, 154, 26, 210, 499, 89, 562, +-130, 217, -256, -264, -210, -538, 174, -389, +498, -17, 356, 311, -31, 411, -431, 298, +-528, -37, -288, -337, 58, -394, 301, -195, +455, 80, 359, 294, 77, 364, -183, 220, +-292, -60, -330, -355, -367, -438, -124, -206, +280, 267, 563, 510, 431, 352, -89, -152, +-433, -542, -297, -444, 8, 63, 175, 585, +95, 619, -61, 100, -186, -572, -174, -780, +38, -407, 343, 295, 438, 825, 137, 756, +-344, 128, -586, -580, -373, -849, 64, -489, +402, 227, 405, 668, 179, 491, -127, 0, +-308, -323, -140, -272, 142, 0, 196, 134, +-23, 50, -301, -91, -353, -116, -75, -20, +332, 95, 466, 162, 315, 76, -10, -41, +-331, -132, -453, -135, -285, -39, 25, 152, +269, 205, 273, 44, 91, -223, -76, -367, +-45, -138, 120, 345, 137, 596, -134, 282, +-426, -329, -386, -752, -11, -493, 437, 187, +490, 763, 213, 680, -126, -3, -271, -655, +-262, -741, -161, -206, -36, 420, 107, 683, +107, 408, 13, -58, -15, -450, 110, -568, +229, -356, 87, 118, -199, 564, -365, 580, +-208, 127, 41, -385, 228, -483, 277, -144, +166, 262, -132, 256, -363, -78, -245, -384, +152, -279, 481, 228, 282, 713, -261, 637, +-609, -68, -430, -846, 122, -998, 545, -364, +647, 530, 282, 989, -299, 693, -729, 14, +-608, -567, -72, -761, 448, -410, 592, 249, +291, 644, -139, 437, -401, -187, -309, -640, +-35, -447, 275, 286, 292, 876, -19, 690, +-378, -130, -396, -961, -19, -1171, 383, -417, +498, 799, 229, 1436, -234, 951, -520, -263, +-417, -1325, -87, -1293, 266, -239, 438, 983, +288, 1393, 39, 633, -247, -681, -394, -1466, +-242, -1012, 103, 394, 301, 1550, 203, 1415, +-71, 92, -258, -1381, -189, -1773, 20, -778, +214, 856, 247, 1818, 155, 1353, -114, -162, +-425, -1457, -413, -1527, -27, -390, 344, 991, +445, 1421, 210, 667, -177, -590, -398, -1342, +-279, -928, -14, 308, 227, 1339, 238, 1318, +8, 157, -172, -1243, -127, -1666, 71, -769, +98, 740, 22, 1719, -76, 1376, -105, -61, +-108, -1392, -82, -1533, 20, -496, 132, 854, +240, 1391, 85, 752, -139, -431, -234, -1135, +-175, -878, -74, 51, 75, 949, 249, 1062, +181, 325, 26, -722, -177, -1137, -201, -667, +-166, 261, -78, 934, 41, 837, 197, 146, +342, -567, 192, -692, -197, -276, -519, 349, +-380, 547, -23, 144, 337, -444, 467, -614, +352, -80, -105, 581, -539, 822, -561, 365, +-206, -427, 339, -954, 552, -730, 362, 34, +-56, 769, -381, 908, -496, 259, -281, -473, +234, -779, 576, -352, 420, 297, -163, 660, +-653, 391, -648, -184, -100, -668, 544, -669, +757, -12, 525, 713, -198, 1008, -832, 436, +-877, -457, -308, -1097, 449, -920, 863, -89, +695, 794, 26, 1096, -517, 610, -715, -228, +-460, -929, 2, -833, 346, -167, 428, 584, +257, 754, 67, 325, -196, -339, -304, -714, +-224, -421, 13, 246, 146, 809, 50, 661, +-78, -56, -132, -861, 82, -989, 128, -348, +34, 618, -118, 1124, -91, 762, -2, -80, +89, -858, 23, -930, -153, -367, -149, 387, +-151, 744, 64, 513, 169, -18, 233, -456, +117, -513, -67, -151, -207, 359, -280, 586, +-229, 341, -131, -262, 66, -792, 210, -725, +383, 0, 315, 827, 92, 1105, -285, 526, +-581, -529, -480, -1206, -161, -901, 260, 77, +363, 902, 376, 871, 236, 160, 61, -505, +-201, -549, -465, -95, -429, 335, -180, 422, +125, 45, 212, -375, 218, -616, 133, -385, +212, 198, 92, 904, -182, 1067, -331, 393, +-365, -667, -270, -1513, -89, -1334, 206, -126, +432, 1331, 492, 1855, 228, 1095, -265, -519, +-547, -1755, -415, -1604, -130, -269, 63, 1145, +202, 1503, 145, 694, 108, -653, 87, -1260, +73, -717, 51, 424, -80, 1199, -254, 890, +-448, -218, -330, -1265, 38, -1296, 427, -316, +532, 1050, 336, 1682, -189, 1107, -521, -429, +-463, -1671, -195, -1639, 186, -385, 333, 1167, +200, 1738, -79, 996, -242, -515, -137, -1451, +71, -1283, 246, -93, 142, 1121, -146, 1408, +-357, 519, -296, -829, -28, -1446, 139, -880, +244, 530, 140, 1485, -28, 1176, -105, -185, +-27, -1392, 22, -1422, 7, -221, -167, 1246, +-400, 1586, -346, 569, 39, -964, 524, -1667, +706, -944, 380, 655, -290, 1669, -892, 1233, +-888, -231, -188, -1556, 578, -1502, 859, -196, +450, 1324, -262, 1594, -618, 534, -402, -933, +66, -1573, 374, -765, 294, 618, -114, 1434, +-566, 925, -608, -374, -52, -1432, 704, -1127, +910, 238, 395, 1505, -581, 1559, -1080, 47, +-717, -1618, 84, -2024, 684, -589, 684, 1482, +275, 2399, -340, 1237, -621, -1049, -424, -2455, +156, -1796, 561, 421, 413, 2229, -239, 2159, +-769, 243, -620, -1776, 94, -2340, 752, -987, +782, 1166, 276, 2346, -505, 1660, -927, -362, +-675, -2031, 48, -2136, 626, -480, 628, 1438, +133, 2137, -330, 1132, -377, -601, -146, -1763, +50, -1510, 55, -81, 64, 1169, -24, 1498, +-67, 614, -110, -565, -116, -1200, 45, -837, +22, 45, 0, 619, 68, 639, 178, 249, +143, -29, -156, -68, -513, -21, -490, -175, +-78, -503, 353, -700, 527, -321, 409, 496, +126, 1280, -313, 1351, -623, 333, -652, -1155, +-200, -2013, 393, -1456, 581, 104, 344, 1677, +-28, 2050, -348, 969, -343, -599, -24, -1504, +165, -1213, 104, -311, -210, 478, -422, 536, +-256, 154, 241, 12, 589, 239, 421, 555, +32, 522, -481, -5, -749, -917, -546, -1364, +177, -899, 695, 223, 592, 1323, 45, 1684, +-536, 861, -569, -504, -224, -1380, 249, -1310, +392, -340, 340, 679, -23, 862, -537, 246, +-662, -370, -229, -364, 385, 300, 662, 868, +455, 607, -26, -441, -504, -1300, -641, -1235, +-405, -264, -42, 928, 345, 1529, 423, 974, +196, -143, 64, -1017, 66, -986, -96, -216, +-477, 468, -682, 439, -390, -195, 230, -536, +741, -224, 793, 617, 289, 1150, -504, 731, +-936, -406, -848, -1447, -42, -1482, 758, -309, +928, 1081, 210, 1677, -568, 930, -830, -456, +-507, -1393, 293, -1161, 811, 92, 744, 1206, +-41, 1185, -897, 128, -1197, -1166, -500, -1510, +612, -493, 1228, 970, 882, 1695, -133, 1109, +-996, -304, -1065, -1411, -362, -1463, 495, -461, +766, 779, 390, 1300, -301, 793, -618, -325, +-317, -935, 264, -670, 491, 206, 226, 789, +-291, 627, -712, -173, -455, -770, 233, -744, +675, -128, 450, 626, -119, 857, -728, 369, +-701, -410, -8, -746, 632, -412, 834, 312, +428, 756, -522, 643, -1268, -301, -1087, -1142, +-16, -1095, 1116, -232, 1349, 1102, 661, 1829, +-433, 1155, -1201, -402, -1083, -1692, -421, -1830, +379, -802, 901, 784, 703, 1709, -25, 1358, +-567, 114, -550, -960, -115, -1121, 287, -393, +333, 625, 153, 897, -312, 202, -704, -732, +-544, -1117, 61, -672, 819, 582, 1008, 1575, +242, 1536, -710, 288, -1022, -1212, -643, -1826, +58, -1360, 604, -26, 614, 1255, 199, 1533, +-472, 872, -610, -122, -157, -882, 464, -818, +721, -196, 209, 259, -617, 178, -1110, -196, +-831, -350, 57, -126, 1047, 428, 1448, 900, +739, 792, -579, 89, -1560, -868, -1373, -1358, +-312, -1006, 794, 44, 1287, 1037, 723, 1367, +-229, 838, -867, -108, -616, -771, -71, -849, +444, -515, 285, -80, -294, 158, -537, 53, +-266, 265, 320, 601, 555, 790, 491, 407, +-62, -404, -606, -1206, -684, -1346, -351, -451, +182, 752, 488, 1613, 277, 1311, -100, 90, +-230, -1189, -52, -1480, 278, -690, 197, 476, +-201, 1114, -635, 838, -828, 143, -229, -735, +642, -913, 1226, -343, 844, 439, -245, 809, +-1198, 535, -1282, -130, -643, -593, 417, -381, +1135, -130, 907, 123, 240, -21, -707, -70, +-865, 104, -309, 497, 316, 807, 365, 366, +-111, -625, -548, -1470, -445, -1297, 223, -168, +822, 1445, 1016, 2109, 190, 1364, -1003, -484, +-1586, -2130, -1093, -2369, 249, -944, 1368, 1312, +1625, 2606, 678, 2092, -588, 45, -1505, -1948, +-1405, -2498, -395, -1429, 629, 629, 1090, 2183, +695, 2167, 103, 788, -395, -1085, -438, -2097, +-285, -1599, -82, -200, -271, 1031, -571, 1528, +-252, 1016, 472, 120, 1281, -616, 1114, -891, +26, -647, -1285, -264, -1905, 39, -1305, 262, +55, 505, 1559, 579, 2146, 395, 1436, -18, +-338, -358, -1889, -559, -2349, -508, -1343, -282, +389, 73, 1770, 375, 2070, 523, 1064, 426, +-355, 178, -1619, 31, -1707, -180, -994, -489, +152, -728, 1026, -692, 1108, -108, 874, 753, +260, 1384, -502, 1246, -1034, 199, -1076, -1173, +-662, -2002, 131, -1496, 844, 2, 1024, 1626, +741, 2225, 106, 1435, -639, -237, -1167, -1841, +-1024, -2278, -426, -1299, 481, 578, 1062, 2043, +986, 2060, 385, 763, -450, -985, -806, -1813, +-800, -1356, -352, -74, -68, 1098, 288, 1120, +256, 372, 179, -546, 347, -799, 374, -128, +405, 657, -163, 884, -943, 261, -1550, -809, +-1047, -1490, 342, -1073, 1674, 329, 2077, 1731, +1041, 2038, -674, 885, -2232, -1014, -2391, -2303, +-1026, -2070, 1045, -332, 2565, 1507, 2222, 2384, +350, 1639, -1797, -262, -2631, -1876, -1624, -2155, +482, -822, 2156, 897, 2128, 1972, 498, 1619, +-1393, 124, -2064, -1497, -1276, -2027, 335, -1029, +1432, 762, 1357, 2075, 410, 1774, -751, 76, +-1347, -1578, -853, -2003, 289, -1040, 1005, 586, +900, 1758, -178, 1778, -1090, 521, -1013, -1013, +-112, -1893, 914, -1613, 1130, -102, 498, 1490, +-599, 2109, -1200, 1287, -976, -290, -25, -1767, +751, -2107, 777, -1092, 287, 410, -362, 1851, +-434, 2094, -195, 1187, 94, -466, 241, -1907, +19, -2200, -387, -1178, -543, 650, -281, 2126, +175, 2159, 609, 706, 521, -1228, 283, -2239, +-152, -1515, -550, 278, -698, 1836, -591, 1960, +-80, 475, 274, -1432, 473, -2243, 554, -1426, +471, 669, 95, 2432, -457, 2513, -938, 671, +-756, -1789, -163, -3061, 399, -2277, 700, 107, +496, 2507, 199, 3142, -308, 1733, -654, -837, +-546, -2885, -145, -2809, 498, -765, 615, 1754, +283, 2762, -342, 1772, -939, -443, -835, -2212, +-212, -2244, 793, -667, 1411, 1407, 986, 2405, +-79, 1721, -1227, -221, -1754, -1982, -1339, -2371, +-126, -1296, 1324, 589, 1988, 1966, 1540, 2188, +72, 1203, -1480, -325, -2074, -1511, -1332, -1907, +-39, -1391, 1143, -460, 1493, 596, 734, 1576, +-155, 1950, -697, 1596, -549, 337, -172, -1378, +-4, -2546, -114, -2553, -451, -1114, -478, 1113, +123, 2937, 832, 3226, 1115, 1692, 685, -877, +-485, -2965, -1454, -3425, -1512, -2025, -740, 559, +549, 2624, 1521, 3283, 1586, 2153, 753, -205, +-658, -2171, -1663, -2846, -1677, -1967, -727, -158, +580, 1536, 1362, 2273, 1388, 1768, 669, 473, +-209, -954, -1005, -1747, -1401, -1539, -1143, -592, +-370, 455, 729, 1126, 1473, 1216, 1567, 826, +743, 217, -757, -421, -2032, -1165, -2101, -1489, +-824, -1104, 1185, 24, 2478, 1700, 2049, 2453, +288, 1715, -1867, -244, -2736, -2328, -1882, -3244, +317, -1930, 2534, 621, 2796, 2896, 1124, 3559, +-1368, 1799, -3095, -981, -2516, -3112, -175, -3269, +2138, -1382, 3007, 1201, 1657, 2787, -848, 2534, +-2611, 746, -2519, -1258, -680, -2016, 1460, -1393, +2379, -6, 1594, 1039, -300, 905, -1865, 174, +-1904, -557, -648, -454, 893, 141, 1560, 716, +1155, 670, 76, -5, -1127, -825, -1368, -1245, +-901, -682, 144, 366, 1092, 1328, 1132, 1585, +583, 595, -268, -940, -849, -1723, -1177, -1586, +-866, -214, 81, 1338, 1072, 1926, 1343, 1341, +675, 51, -442, -1379, -1284, -2027, -1259, -1492, +-493, -205, 507, 1341, 1249, 2249, 1197, 1930, +205, 480, -967, -1385, -1408, -2540, -755, -2178, +279, -606, 977, 1261, 952, 2346, 269, 2130, +-604, 818, -1039, -687, -641, -1892, 215, -2035, +879, -1106, 808, 210, -130, 1391, -819, 1655, +-835, 1071, -306, 135, 567, -731, 846, -940, +452, -741, -355, -313, -868, -33, -492, -18, +177, 126, 627, 480, 465, 951, -271, 968, +-761, 396, -654, -670, -6, -1621, 825, -1707, +1205, -783, 491, 764, -777, 2026, -1607, 2156, +-1287, 1010, 4, -814, 1281, -2114, 1699, -2201, +891, -1097, -472, 586, -1593, 1957, -1659, 2084, +-481, 1110, 1033, -238, 1681, -1515, 964, -1953, +-381, -1214, -1322, -118, -1350, 1068, -437, 1760, +737, 1419, 1288, 414, 944, -729, -20, -1422, +-931, -1489, -1064, -736, -596, 227, -40, 1124, +415, 1478, 610, 1150, 542, 233, 397, -849, +51, -1410, -302, -1428, -630, -628, -872, 543, +-708, 1289, -226, 1386, 667, 787, 1326, -181, +1266, -849, 409, -965, -885, -805, -1667, -355, +-1583, 148, -522, 452, 852, 695, 1673, 865, +1590, 621, 458, 16, -1056, -578, -1769, -1032, +-1213, -1004, -36, -404, 1079, 193, 1240, 760, +444, 1095, -481, 738, -937, 263, -587, -360, +182, -750, 773, -762, 692, -568, -108, -206, +-957, 134, -1144, 422, -485, 604, 683, 632, +1590, 644, 1457, 343, 231, -273, -1361, -991, +-2332, -1506, -1896, -1193, -87, -105, 2016, 1182, +3018, 1989, 2150, 1804, -253, 532, -2712, -1122, +-3652, -2133, -2234, -1872, 559, -656, 3065, 850, +3799, 1530, 2036, 1317, -885, 589, -3212, -127, +-3591, -481, -1669, -479, 1104, -418, 2897, -628, +2789, -857, 1010, -596, -1194, 309, -2438, 1461, +-1970, 2061, -246, 1434, 1474, -275, 1839, -2052, +780, -2770, -856, -1913, -1849, 229, -1261, 2208, +290, 2846, 1789, 1794, 2154, -69, 887, -1563, +-1125, -2020, -2677, -1485, -2663, -575, -851, 133, +1604, 804, 3194, 1334, 2947, 1660, 910, 1495, +-1700, 390, -3400, -1340, -3254, -2714, -1166, -2770, +1541, -1228, 3310, 1156, 3054, 3055, 1058, 3566, +-1300, 2057, -2690, -549, -2474, -3015, -1050, -3979, +750, -2639, 1718, 52, 1595, 2667, 803, 3730, +-50, 2671, -530, 317, -794, -1945, -978, -2922, +-905, -2225, -407, -534, 365, 1074, 1251, 1852, +1431, 1560, 924, 630, -202, -418, -1580, -991, +-1993, -1000, -1286, -461, 437, 183, 2038, 552, +2326, 624, 1041, 246, -1035, -226, -2506, -626, +-2414, -706, -655, -298, 1562, 492, 2782, 1229, +2188, 1355, 201, 600, -1911, -715, -2828, -2068, +-2023, -2328, -203, -1218, 1665, 789, 2712, 2649, +2249, 3245, 550, 2160, -1305, -352, -2697, -2832, +-2680, -4040, -1283, -3115, 768, -350, 2608, 2684, +2993, 4273, 1916, 3594, -301, 1031, -2206, -1953, +-3029, -3758, -2354, -3489, -508, -1590, 1395, 878, +2689, 2566, 2491, 2895, 1124, 1937, -546, 225, +-1742, -1212, -2116, -1952, -1740, -1809, -879, -1030, +365, 26, 1550, 779, 2253, 1404, 2126, 1480, +935, 909, -813, 40, -2562, -1077, -3281, -1544, +-2201, -1245, 217, -205, 2764, 951, 3923, 1363, +2727, 886, 30, -241, -2667, -1057, -3955, -910, +-2801, -138, -248, 843, 2333, 1115, 3417, 522, +2434, -299, 361, -1129, -1765, -1197, -2620, -589, +-2073, 237, -713, 952, 944, 1160, 2009, 999, +1914, 441, 968, -302, -423, -1022, -1545, -1452, +-1799, -1295, -1253, -573, -87, 479, 1123, 1512, +1670, 2043, 1335, 1611, 396, 326, -660, -1279, +-1304, -2302, -1328, -2180, -878, -964, -11, 513, +822, 1623, 1240, 1981, 1149, 1496, 539, 677, +-212, -195, -840, -1048, -1294, -1759, -1281, -2031, +-505, -1550, 396, -142, 1309, 1709, 1662, 3090, +1031, 2942, 33, 1155, -1145, -1376, -1787, -3407, +-1390, -3551, -356, -1702, 784, 944, 1523, 2930, +1394, 3105, 625, 1624, -385, -446, -1131, -1854, +-1280, -2001, -780, -1098, 59, 103, 690, 676, +910, 673, 690, 411, 202, 96, -302, 221, +-532, 331, -504, 107, -381, -319, -266, -653, +-30, -619, 329, -149, 716, 636, 1023, 767, +609, 282, -471, -549, -1500, -1135, -1876, -742, +-921, 458, 843, 1583, 2255, 1827, 2404, 745, +1084, -1095, -952, -2377, -2724, -2381, -2913, -1041, +-1450, 983, 875, 2367, 2802, 2662, 3002, 1845, +1740, 93, -411, -1656, -2221, -2813, -2748, -2702, +-2023, -1406, -478, 609, 1171, 2314, 2036, 2987, +1968, 2287, 1393, 657, 235, -1152, -903, -2347, +-1744, -2434, -2044, -1639, -1533, -319, -357, 888, +1008, 1652, 2007, 1808, 2286, 1539, 1569, 956, +169, 134, -1406, -993, -2338, -2113, -2319, -2817, +-1557, -2345, 20, -523, 1691, 1955, 2664, 4016, +2720, 4209, 1468, 2235, -569, -1172, -2428, -4261, +-3405, -5079, -2772, -3353, -716, 136, 1825, 3393, +3438, 4533, 3222, 3441, 1548, 857, -821, -1641, +-2523, -2769, -2926, -2535, -2155, -1505, -414, -486, +1280, 355, 2234, 1139, 2171, 1811, 1220, 2228, +-41, 1672, -1252, 238, -1781, -1607, -1517, -2910, +-800, -2786, 172, -1324, 938, 926, 1272, 2597, +1307, 2914, 846, 1816, -106, -96, -1027, -1604, +-1478, -2140, -1304, -1662, -482, -699, 624, 340, +1276, 958, 1354, 1200, 685, 1191, -376, 693, +-949, 43, -933, -622, -471, -1145, 110, -1196, +505, -626, 410, 121, 37, 735, -291, 942, +-274, 605, 319, 217, 749, 125, 772, 81, +37, -175, -1115, -700, -1746, -1318, -1458, -1324, +42, -312, 1869, 1268, 2804, 2515, 2069, 2387, +-44, 589, -2374, -1825, -3490, -3263, -2583, -2772, +-199, -610, 2361, 1842, 3561, 3157, 2879, 2630, +672, 779, -1802, -1340, -3051, -2471, -2772, -2065, +-1180, -784, 704, 596, 1970, 1118, 2238, 938, +1394, 593, 360, 459, -402, 586, -936, 405, +-1157, -279, -1461, -1381, -1458, -2139, -660, -1738, +675, -187, 2137, 1815, 2881, 3041, 2223, 2727, +160, 886, -2305, -1436, -3792, -3205, -3324, -3368, +-902, -1715, 2061, 769, 3828, 2869, 3574, 3325, +1313, 2001, -1577, -108, -3320, -1904, -3032, -2486, +-975, -1705, 1260, -384, 2351, 759, 1700, 1139, +48, 857, -1189, 444, -1246, 318, -168, 276, +1004, 192, 1363, -225, 504, -861, -1049, -1242, +-1903, -1107, -1581, -287, -284, 861, 1407, 1677, +2291, 1632, 1849, 680, 502, -629, -1115, -1496, +-2121, -1606, -1860, -769, -782, 450, 518, 1186, +1332, 1067, 1309, 289, 832, -678, 222, -879, +-212, -234, -443, 641, -587, 1139, -729, 784, +-761, -378, -491, -1557, 42, -1855, 769, -989, +1280, 706, 1167, 2101, 479, 2372, -447, 1254, +-1076, -590, -1183, -2029, -899, -2323, -289, -1416, +358, 153, 798, 1412, 977, 1758, 911, 1156, +496, 194, -38, -511, -694, -755, -1213, -458, +-1040, -242, -725, -258, 33, -328, 910, -372, +1224, -55, 1218, 382, 706, 907, -215, 1123, +-973, 815, -1371, 236, -1196, -747, -539, -1601, +326, -1765, 1159, -1230, 1337, 19, 929, 1449, +168, 2468, -524, 2285, -867, 939, -918, -853, +-587, -2500, -153, -2725, 253, -1729, 492, 3, +389, 1551, 445, 2272, 627, 2058, 550, 1018, +171, -57, -743, -1016, -1510, -1729, -1534, -1998, +-712, -1628, 874, -440, 2091, 1226, 2141, 2530, +899, 2628, -892, 1306, -2109, -707, -2014, -2209, +-872, -2432, 610, -1404, 1652, 223, 1705, 1240, +791, 1304, -473, 623, -1288, 29, -1315, 24, +-391, 295, 487, 510, 910, 15, 837, -977, +237, -1587, -412, -1482, -831, -314, -719, 1273, +-240, 2076, 389, 1792, 711, 534, 641, -825, +514, -1472, 116, -1215, -410, -668, -895, -80, +-1078, 198, -654, 146, 109, 421, 929, 807, +1408, 1113, 1139, 976, 338, 197, -600, -929, +-1293, -1696, -1309, -1681, -780, -955, -142, 261, +499, 1292, 1044, 1707, 1175, 1521, 986, 724, +519, -110, -310, -825, -1073, -1420, -1500, -1612, +-1478, -1413, -892, -567, 229, 672, 1489, 1852, +2285, 2432, 2172, 2014, 916, 632, -982, -1208, +-2606, -2685, -2982, -3003, -1860, -1899, 167, 89, +2108, 2028, 3024, 2993, 2404, 2564, 635, 1151, +-1155, -705, -2341, -2068, -2258, -2407, -1113, -1879, +181, -679, 1196, 527, 1532, 1506, 1082, 1871, +333, 1672, -179, 920, -358, -253, -437, -1302, +-424, -1863, -488, -1687, -649, -846, -402, 343, +88, 1415, 731, 1747, 1115, 1318, 955, 480, +390, -685, -596, -1291, -1117, -1211, -957, -674, +-406, 193, 416, 714, 643, 683, 286, 170, +-68, -238, -321, -316, 19, -19, 590, 475, +788, 668, 510, 477, -400, -136, -1247, -897, +-1409, -1427, -862, -1253, 221, -350, 1369, 1109, +1757, 2256, 1251, 2182, 168, 919, -1035, -1050, +-1514, -2624, -1226, -2640, -435, -1175, 332, 762, +662, 2185, 648, 2222, 541, 1033, 535, -293, +485, -1119, 92, -1114, -575, -540, -1064, -184, +-1075, -143, -643, -242, 201, -104, 999, 484, +1333, 1137, 988, 1246, 65, 651, -806, -506, +-1122, -1477, -677, -1669, 22, -892, 538, 282, +521, 1242, 136, 1416, -273, 790, -435, 13, +-207, -649, 292, -721, 785, -479, 836, -154, +310, -76, -562, -44, -1291, 71, -1404, 250, +-617, 603, 576, 562, 1569, 141, 1708, -386, +811, -714, -323, -645, -1259, -113, -1367, 458, +-794, 606, -70, 402, 565, -154, 654, -566, +418, -520, 163, -2, 155, 570, 398, 786, +506, 466, 76, -329, -702, -973, -1414, -1078, +-1394, -461, -512, 503, 829, 1213, 1902, 1149, +1960, 489, 1136, -512, -401, -1112, -1735, -942, +-2122, -393, -1571, 326, -258, 623, 1097, 460, +1896, 152, 1730, 51, 769, 74, -423, 127, +-1263, 29, -1370, -307, -835, -599, -64, -696, +510, -327, 659, 308, 485, 931, 351, 1133, +191, 629, 140, -274, -4, -994, -235, -1192, +-519, -759, -721, 114, -444, 757, 19, 940, +553, 612, 900, 66, 716, -296, 187, -358, +-361, -265, -692, -330, -625, -367, -273, -172, +174, 165, 334, 567, 318, 684, 221, 335, +-58, -161, -36, -503, 37, -536, 107, -222, +117, 145, -168, 244, -359, 84, -350, -99, +-75, -81, 268, 163, 470, 403, 340, 335, +28, -36, -154, -475, -223, -645, -113, -385, +29, 118, 11, 559, -45, 603, -96, 254, +-174, -242, 45, -469, 260, -261, 333, 98, +401, 366, 88, 290, -295, -141, -529, -542, +-512, -578, -136, -203, 231, 494, 478, 1021, +515, 906, 282, 149, -44, -753, -295, -1337, +-382, -1074, -253, -194, -48, 765, 86, 1344, +174, 1097, 198, 327, 156, -627, 45, -1122, +-70, -932, -28, -268, 14, 462, 8, 759, +62, 438, -77, -72, -229, -380, -232, -196, +-101, 360, 251, 649, 518, 271, 471, -589, +111, -1213, -299, -1021, -498, 38, -442, 1203, +-113, 1612, 190, 949, 318, -286, 362, -1320, +200, -1421, -6, -646, -35, 314, -133, 961, +-134, 861, -76, 310, -139, -196, 22, -418, +66, -292, 86, -14, 138, 152, 6, 42, +-19, -191, 48, -360, 223, -194, 335, 206, +146, 600, -319, 627, -746, 188, -785, -350, +-263, -770, 597, -702, 1314, -217, 1337, 408, +508, 803, -661, 686, -1645, 189, -1635, -440, +-555, -821, 641, -691, 1549, -171, 1507, 524, +567, 992, -343, 777, -950, 96, -910, -725, +-388, -1194, 111, -871, 245, -38, 140, 849, +73, 1275, 59, 968, 371, 53, 640, -820, +543, -1116, 79, -828, -702, -189, -1148, 348, +-942, 598, -170, 663, 730, 602, 1182, 352, +1006, -97, 352, -635, -333, -924, -693, -793, +-612, -249, -239, 504, -37, 938, -25, 840, +-58, 330, -76, -272, 289, -545, 804, -457, +957, -207, 592, -23, -268, -27, -1131, -124, +-1462, -96, -1021, 112, 23, 446, 1051, 744, +1603, 660, 1299, 109, 409, -657, -603, -1230, +-1219, -1273, -1099, -544, -614, 592, 129, 1529, +631, 1697, 661, 917, 552, -368, 309, -1433, +59, -1644, -96, -1060, -233, -26, -333, 908, +-311, 1282, -159, 1004, -85, 359, -1, -334, +212, -695, 324, -654, 394, -433, 434, -182, +236, 12, -82, 149, -311, 308, -566, 509, +-605, 507, -303, 283, 100, -167, 487, -576, +701, -671, 691, -396, 436, 50, 95, 353, +-433, 413, -829, 264, -821, 79, -593, -35, +44, -30, 661, -29, 1058, -89, 1089, -235, +553, -338, -248, -201, -1023, 111, -1207, 445, +-765, 497, 51, 188, 787, -214, 985, -501, +712, -366, 129, 34, -351, 389, -456, 482, +-270, 132, -74, -332, 50, -572, -8, -449, +-71, -42, 100, 438, 150, 672, 274, 566, +359, 191, 181, -321, -7, -695, -313, -678, +-535, -380, -389, 17, 78, 368, 566, 504, +651, 592, 355, 565, -171, 302, -620, -223, +-551, -836, -99, -1119, 475, -818, 817, -7, +529, 818, -142, 1142, -726, 867, -822, 247, +-272, -312, 460, -554, 875, -584, 762, -491, +96, -383, -579, -210, -720, 98, -405, 388, +190, 701, 706, 883, 649, 770, 101, 237, +-455, -636, -732, -1496, -465, -1725, 216, -974, +793, 431, 930, 1784, 556, 2200, -194, 1391, +-864, -179, -1037, -1549, -682, -1972, 109, -1265, +834, -40, 1073, 889, 850, 1108, 278, 643, +-321, 93, -679, -101, -794, 69, -612, 234, +-186, 32, 217, -507, 504, -1077, 795, -1085, +845, -318, 638, 760, 127, 1613, -652, 1664, +-1225, 631, -1233, -750, -589, -1696, 366, -1697, +1292, -685, 1638, 594, 1161, 1329, 34, 1200, +-1114, 470, -1498, -336, -1060, -723, -60, -593, +786, -160, 1041, 217, 671, 326, 29, 119, +-333, -196, -330, -353, 42, -216, 361, 122, +248, 450, -164, 552, -623, 346, -683, -40, +-186, -493, 500, -731, 1049, -580, 982, -173, +349, 366, -450, 744, -989, 697, -816, 371, +-247, -140, 349, -557, 673, -664, 503, -427, +156, 22, -74, 365, -152, 458, -13, 208, +112, -139, 88, -272, 44, -96, -124, 304, +-258, 535, -299, 271, -205, -385, 123, -992, +520, -966, 824, -176, 723, 838, 283, 1450, +-434, 1142, -1154, 64, -1178, -1051, -582, -1521, +386, -1088, 1307, 4, 1454, 1000, 884, 1274, +39, 821, -907, -8, -1297, -707, -931, -890, +-246, -582, 595, -49, 911, 435, 722, 578, +399, 397, 14, 64, -156, -233, -273, -342, +-300, -309, -246, -165, -250, 63, -127, 307, +126, 408, 418, 292, 591, -11, 501, -392, +227, -589, -191, -406, -488, 51, -487, 473, +-385, 666, -51, 430, 392, -33, 599, -417, +561, -614, 227, -491, -207, -71, -397, 345, +-358, 548, -92, 406, 231, 31, 356, -226, +236, -227, -28, -81, -222, -47, -209, -135, +34, -223, 271, -165, 387, 149, 317, 520, +72, 608, -257, 294, -466, -315, -368, -830, +-56, -807, 354, -182, 561, 488, 436, 819, +212, 637, -81, 62, -307, -394, -317, -551, +-195, -371, -24, -66, 73, 114, 198, 218, +299, 205, 326, 177, 318, 151, 119, 1, +-224, -203, -442, -331, -406, -193, -155, 47, +282, 283, 602, 321, 521, 14, 111, -300, +-244, -383, -343, -132, -192, 316, 102, 624, +231, 465, 199, -117, 66, -661, -87, -897, +-171, -526, -44, 238, 208, 904, 384, 1142, +319, 611, 4, -318, -311, -1036, -438, -1171, +-219, -577, 195, 339, 477, 906, 513, 849, +228, 374, -159, -177, -338, -409, -339, -271, +-97, -155, 155, -206, 313, -309, 354, -269, +226, 76, 160, 606, -103, 931, -400, 643, +-465, -84, -238, -915, 317, -1300, 785, -796, +814, 182, 313, 1069, -412, 1301, -904, 684, +-836, -314, -238, -997, 628, -1036, 1142, -419, +890, 415, 137, 825, -610, 641, -901, 45, +-531, -498, 138, -537, 666, -145, 686, 284, +130, 386, -438, 62, -474, -269, 61, -244, +655, 54, 749, 354, 179, 266, -631, -231, +-1050, -542, -638, -394, 306, 154, 1090, 742, +1214, 751, 496, 178, -505, -582, -982, -937, +-717, -675, -49, -40, 481, 614, 572, 832, +341, 649, 18, 199, -108, -314, -88, -655, +24, -764, 108, -519, 28, -39, -20, 442, +-5, 803, 52, 818, 11, 485, -50, -148, +-43, -735, 124, -1048, 274, -919, 284, -177, +192, 647, -18, 1173, -158, 1138, -310, 414, +-277, -538, -38, -1115, 242, -1010, 410, -365, +316, 371, 134, 710, -6, 505, 20, 134, +40, -61, -64, 31, -188, 153, -366, 40, +-336, -349, 54, -722, 525, -634, 870, -87, +768, 616, 140, 1021, -555, 848, -939, 167, +-799, -602, -139, -986, 601, -857, 911, -236, +651, 470, 92, 796, -359, 657, -326, 120, +36, -413, 220, -544, 190, -230, -167, 283, +-473, 499, -396, 195, -87, -418, 522, -799, +1013, -550, 930, 205, 359, 959, -490, 1091, +-1113, 502, -1143, -444, -527, -1128, 427, -1054, +1104, -339, 1186, 471, 605, 865, -110, 661, +-527, 118, -534, -275, -246, -301, -120, -81, +-148, 104, -121, 60, 42, -228, 360, -513, +745, -421, 798, -6, 484, 631, -58, 1011, +-768, 752, -1066, 3, -874, -851, -200, -1174, +641, -798, 1177, 12, 1165, 714, 575, 843, +-177, 470, -742, -11, -838, -196, -502, -64, +-47, 52, 201, -55, 216, -520, 300, -810, +483, -545, 622, 146, 547, 1019, 126, 1400, +-429, 950, -886, -106, -947, -1156, -496, -1594, +275, -1165, 1015, -16, 1222, 1011, 860, 1370, +157, 988, -601, 119, -950, -615, -864, -816, +-321, -524, 320, -113, 605, 154, 676, 131, +455, -55, 190, -79, 36, 162, -200, 513, +-313, 654, -352, 360, -298, -313, -44, -982, +173, -1076, 398, -511, 560, 405, 426, 1029, +169, 1052, -171, 542, -436, -209, -483, -757, +-281, -877, 111, -600, 397, -6, 600, 588, +489, 742, 85, 464, -295, -42, -574, -494, +-428, -555, 143, -180, 564, 230, 626, 475, +263, 345, -274, -67, -498, -400, -426, -450, +-10, -200, 442, 142, 620, 414, 480, 473, +-55, 250, -466, -128, -522, -434, -180, -506, +304, -253, 474, 188, 462, 444, 145, 400, +-286, 83, -426, -304, -264, -417, 208, -166, +544, 231, 453, 409, 78, 278, -288, -83, +-399, -374, -227, -385, 73, -192, 304, 75, +372, 247, 219, 394, 42, 350, -51, 119, +-17, -112, -2, -417, -107, -487, -141, -296, +-128, -20, 59, 292, 258, 425, 331, 397, +311, 248, 148, -3, 0, -236, -153, -478, +-221, -513, -294, -295, -248, 134, 28, 539, +291, 615, 553, 361, 499, -148, 255, -487, +23, -419, -299, -66, -469, 233, -528, 174, +-295, -135, 146, -364, 571, -150, 776, 368, +615, 688, 252, 573, -273, -58, -651, -785, +-697, -988, -401, -502, 87, 285, 451, 897, +644, 895, 672, 260, 467, -411, 25, -673, +-526, -456, -797, 26, -579, 330, -31, 242, +494, -76, 690, -235, 592, -88, 252, 220, +-174, 436, -388, 305, -382, -98, -217, -524, +20, -625, 229, -272, 410, 291, 402, 666, +194, 560, -117, 41, -413, -442, -379, -494, +-72, -174, 301, 206, 553, 347, 514, 140, +125, -183, -370, -338, -592, -198, -400, 142, +71, 422, 452, 421, 588, 129, 425, -268, +45, -564, -232, -519, -341, -140, -264, 360, +-20, 692, 104, 541, 109, 23, 177, -501, +202, -586, 190, -263, 246, 157, 148, 428, +-89, 242, -356, -82, -476, -276, -187, -206, +267, 170, 601, 411, 499, 276, 79, -146, +-209, -545, -293, -537, -88, -86, 162, 487, +216, 706, 42, 443, -256, -176, -270, -745, +63, -680, 380, -146, 514, 498, 264, 792, +-123, 457, -217, -189, -246, -639, -136, -589, +28, -203, 9, 278, 63, 489, 123, 342, +234, 86, 413, -56, 375, -118, 105, -160, +-330, -212, -593, -305, -573, -279, -204, 7, +385, 407, 757, 702, 793, 658, 385, 151, +-183, -585, -552, -1074, -557, -877, -279, -154, +-5, 683, 207, 1086, 254, 782, 284, 103, +350, -480, 421, -663, 337, -512, -94, -189, +-591, 44, -858, 118, -612, 222, 115, 303, +807, 343, 1121, 259, 866, 26, 113, -237, +-696, -411, -1042, -433, -755, -293, -83, -33, +522, 215, 726, 417, 635, 483, 338, 347, +3, 119, -298, -176, -469, -465, -373, -574, +-143, -491, 101, -209, 237, 233, 366, 632, +389, 773, 288, 573, 103, 69, -217, -477, +-353, -800, -372, -757, -253, -377, 85, 156, +377, 615, 507, 752, 426, 532, 153, 115, +-141, -328, -307, -526, -327, -419, -275, -207, +-94, 21, 141, 93, 429, 77, 570, 108, +427, 204, 55, 341, -380, 325, -571, 140, +-453, -217, -75, -617, 306, -763, 567, -478, +550, 175, 283, 814, -57, 1052, -366, 609, +-499, -236, -345, -877, -46, -945, 275, -415, +556, 325, 529, 724, 231, 567, -117, 77, +-441, -373, -506, -455, -264, -190, 119, 210, +482, 404, 546, 272, 327, -70, -32, -350, +-350, -395, -346, -172, -143, 164, 72, 314, +160, 265, 154, 108, 95, -35, 128, -132, +232, -95, 221, -59, 27, -71, -318, -89, +-528, -124, -410, -46, 149, 137, 663, 295, +789, 258, 415, 55, -222, -149, -611, -230, +-601, -129, -205, -6, 200, 9, 473, -113, +420, -249, 164, -108, 4, 266, -87, 626, +-24, 683, -6, 201, -122, -547, -239, -1066, +-234, -977, 34, -221, 388, 682, 566, 1194, +426, 965, 21, 190, -344, -553, -527, -914, +-403, -731, -57, -216, 328, 249, 495, 470, +385, 376, 141, 151, -83, 12, -145, -23, +-124, 37, -123, 23, -164, -122, -132, -305, +-5, -405, 186, -300, 443, 57, 561, 510, +337, 726, -189, 502, -686, -55, -730, -596, +-333, -748, 338, -419, 820, 109, 758, 422, +310, 390, -251, 155, -591, -36, -518, -22, +-146, 73, 195, 18, 358, -199, 303, -345, +82, -277, -37, 16, -55, 339, 80, 427, +206, 256, 90, -89, -190, -375, -404, -376, +-380, -108, 2, 238, 519, 374, 745, 202, +531, -158, -37, -342, -604, -260, -724, -29, +-332, 282, 166, 370, 468, 163, 459, -117, +248, -317, 10, -281, -53, -24, -76, 218, +-106, 254, -119, 83, -174, -134, -138, -268, +37, -173, 291, 105, 397, 305, 286, 276, +24, 60, -196, -168, -266, -259, -188, -224, +1, -115, 80, -34, 97, 65, 82, 229, +43, 357, 121, 355, 240, 130, 228, -254, +74, -583, -190, -641, -413, -331, -398, 176, +-145, 640, 246, 819, 568, 537, 579, -8, +308, -575, -113, -879, -430, -657, -546, -86, +-387, 501, -16, 751, 289, 478, 559, 7, +479, -304, 204, -299, -130, -73, -423, 60, +-387, -43, -162, -215, 187, -237, 359, -29, +273, 308, 42, 469, -205, 299, -243, 18, +-55, -252, 221, -363, 413, -297, 349, -168, +-38, 15, -488, 204, -648, 315, -295, 239, +279, 57, 762, -105, 782, -142, 290, -34, +-339, 59, -781, -49, -718, -259, -135, -360, +495, -159, 706, 327, 474, 711, -45, 609, +-399, 38, -349, -593, -50, -766, 220, -384, +290, 161, 44, 416, -223, 226, -279, -39, +-19, -32, 321, 241, 397, 458, 196, 221, +-137, -370, -305, -932, -217, -891, 3, -92, +112, 829, 129, 1235, 83, 794, 18, -174, +126, -966, 221, -1014, 104, -419, -129, 333, +-372, 730, -384, 553, -57, 30, 344, -352, +573, -353, 468, -78, 79, 228, -407, 292, +-670, 113, -426, -207, 66, -414, 586, -326, +684, 8, 310, 411, -202, 586, -605, 325, +-501, -187, 22, -599, 463, -545, 548, -110, +205, 386, -241, 558, -431, 248, -320, -181, +-29, -409, 262, -313, 477, 46, 459, 325, +133, 295, -307, 75, -558, -147, -485, -302, +-117, -212, 263, -8, 560, 108, 588, 220, +364, 168, -58, 33, -528, -56, -620, -134, +-374, -106, 51, 28, 351, 98, 443, -1, +268, -245, 150, -309, 66, 17, -66, 550, +-79, 722, -273, 254, -310, -550, -257, -1011, +-80, -700, 282, 136, 525, 850, 586, 912, +303, 370, -194, -363, -516, -709, -507, -524, +-256, -72, 4, 298, 173, 346, 287, 141, +333, -44, 293, -85, 164, -22, 48, 14, +-86, -4, -270, -4, -449, 9, -481, 4, +-209, -112, 306, -169, 687, -101, 694, 109, +442, 353, 10, 287, -456, 33, -736, -202, +-698, -322, -353, -246, 294, -70, 755, 27, +741, 122, 500, 274, 41, 319, -377, 229, +-589, -53, -526, -413, -289, -556, 109, -321, +398, 158, 443, 567, 394, 566, 181, 137, +-80, -327, -333, -503, -385, -306, -168, 87, +132, 341, 249, 337, 155, 146, -88, -192, +-158, -416, 3, -403, 175, -81, 309, 374, +268, 673, 15, 561, -407, 7, -540, -618, +-308, -922, 176, -607, 598, 96, 473, 707, +108, 927, -240, 579, -318, -49, -107, -588, +125, -774, 247, -487, 72, -42, -257, 351, +-462, 404, -238, 250, 328, 153, 750, 77, +689, 72, 155, -19, -485, -262, -840, -486, +-767, -506, -300, -162, 468, 378, 990, 769, +898, 705, 263, 236, -442, -376, -714, -737, +-577, -675, -253, -344, 61, 172, 316, 571, +515, 665, 469, 409, 205, -40, -105, -412, +-321, -524, -456, -364, -331, -74, -52, 201, +249, 371, 462, 359, 354, 176, 82, -82, +-194, -294, -251, -330, -159, -252, -20, 18, +68, 313, 51, 426, 69, 217, 79, -187, +56, -391, 64, -306, -14, 42, -23, 272, +-38, 216, -47, 8, 16, -141, 42, -124, +35, 21, -49, 177, -78, 100, 49, -109, +218, -225, 278, -190, 57, 38, -237, 251, +-376, 212, -224, 36, 47, -110, 291, -144, +422, -16, 317, 78, 9, 65, -362, -100, +-444, -264, -244, -233, 167, 53, 425, 469, +298, 558, 32, 277, -142, -287, -249, -710, +-148, -711, 79, -248, 239, 357, 296, 820, +92, 791, -333, 236, -495, -439, -184, -865, +263, -684, 594, -168, 522, 472, 84, 788, +-385, 588, -670, 25, -548, -555, -4, -704, +607, -373, 763, 185, 387, 586, -272, 588, +-569, 209, -394, -294, -26, -666, 318, -563, +246, -58, 114, 426, -27, 611, -145, 396, +-111, -1, 0, -300, 181, -394, 244, -341, +122, -104, -206, 114, -361, 218, -244, 227, +76, 145, 364, 117, 417, 62, 257, -89, +-138, -281, -431, -348, -403, -228, -98, 65, +287, 337, 445, 392, 222, 230, -20, -57, +-192, -288, -268, -288, -179, -121, -12, 51, +248, 129, 398, 102, 239, 34, -158, 4, +-444, -11, -354, -57, 8, -20, 386, 35, +472, 99, 268, 67, -136, -107, -443, -265, +-472, -210, -119, 73, 377, 363, 591, 394, +412, 59, -128, -340, -589, -457, -611, -196, +-143, 169, 476, 443, 757, 341, 481, -32, +-164, -319, -674, -412, -631, -188, -166, 145, +320, 400, 592, 385, 446, 135, 136, -217, +-216, -521, -484, -447, -406, 15, -72, 485, +371, 561, 457, 243, 146, -270, -214, -529, +-316, -444, -143, -38, 226, 377, 451, 534, +297, 381, -153, -113, -678, -497, -665, -577, +-47, -228, 712, 188, 963, 514, 487, 531, +-211, 265, -743, -145, -811, -499, -534, -599, +128, -402, 791, 111, 1035, 593, 565, 752, +-287, 409, -870, -199, -861, -732, -312, -710, +293, -256, 758, 323, 757, 653, 209, 505, +-401, 119, -593, -280, -326, -468, 54, -347, +231, -55, 218, 178, 139, 241, 63, 177, +-35, 49, -63, 42, -30, 31, 58, -71, +-103, -237, -118, -292, 54, -158, 153, 97, +43, 362, -64, 375, 1, 198, 187, -80, +239, -337, -26, -397, -322, -227, -359, 26, +-164, 279, 185, 326, 421, 188, 486, -16, +176, -88, -272, -74, -483, -83, -390, -127, +-66, -236, 258, -199, 466, 85, 319, 425, +4, 543, -307, 265, -281, -255, -20, -638, +183, -570, 93, -76, -21, 335, -64, 472, +-42, 391, -12, 141, 101, -132, 282, -309, +168, -330, -230, -238, -409, -48, -239, 114, +260, 231, 437, 345, 244, 400, -73, 164, +-323, -259, -340, -623, -85, -657, 320, -244, +533, 354, 258, 809, -376, 754, -583, 163, +-270, -520, 246, -785, 611, -530, 423, 114, +-46, 530, -510, 365, -592, -28, -82, -228, +500, -113, 670, 237, 202, 358, -363, 53, +-599, -333, -291, -557, 120, -398, 467, 104, +464, 592, 149, 743, -310, 318, -489, -341, +-242, -782, 154, -603, 425, 69, 307, 626, +-25, 635, -276, 125, -341, -530, -63, -680, +328, -186, 488, 505, 107, 843, -450, 402, +-555, -479, -119, -1016, 435, -664, 639, 245, +348, 1054, -224, 978, -625, 100, -606, -896, +-118, -1220, 552, -560, 789, 635, 421, 1374, +-187, 1008, -627, -146, -549, -1247, -260, -1405, +255, -448, 540, 807, 491, 1451, 69, 1017, +-260, -136, -344, -1177, -84, -1233, 84, -312, +28, 734, -47, 1081, -115, 570, -15, -394, +118, -947, 357, -599, 369, 249, 80, 940, +-402, 793, -677, -43, -392, -1001, 162, -1076, +667, -250, 615, 821, 170, 1282, -378, 704, +-611, -405, -323, -1272, 232, -1069, 580, 12, +358, 1083, -125, 1257, -600, 399, -517, -802, +-96, -1331, 518, -719, 800, 442, 586, 1261, +-91, 1038, -758, 54, -895, -1052, -475, -1240, +288, -497, 803, 630, 797, 1245, 278, 884, +-360, -65, -641, -1028, -446, -1153, 38, -405, +354, 641, 353, 1206, 7, 875, -282, -165, +-270, -1017, 1, -1030, 412, -308, 432, 605, +83, 938, -264, 574, -396, -167, -308, -664, +-96, -494, 159, 7, 311, 446, 354, 349, +145, -37, -33, -432, -121, -352, -208, 13, +-222, 437, -228, 507, 45, 258, 318, -182, +353, -529, 104, -457, -120, -168, -235, 223, +-169, 385, -36, 327, 113, 92, 275, -79, +207, -196, -14, -113, -284, 91, -353, 102, +-169, -35, 73, -276, 360, -401, 420, -124, +330, 416, -9, 739, -354, 630, -535, 132, +-445, -609, -104, -978, 291, -803, 580, -129, +503, 652, 217, 1123, -121, 879, -375, 134, +-511, -647, -412, -1046, -104, -733, 311, -26, +619, 654, 477, 885, 65, 462, -372, -276, +-514, -740, -267, -536, 146, 148, 476, 761, +328, 694, -126, -15, -534, -783, -440, -971, +-33, -388, 567, 623, 777, 1246, 370, 859, +-285, -154, -800, -1070, -773, -1133, -196, -345, +468, 670, 758, 1106, 631, 689, 107, -152, +-506, -894, -772, -922, -425, -191, 294, 684, +720, 1060, 482, 574, -158, -394, -613, -1077, +-531, -880, -21, 57, 419, 1006, 616, 1052, +405, 262, -95, -788, -572, -1090, -612, -374, +-181, 635, 250, 1067, 498, 518, 277, -501, +-42, -1073, -201, -699, -126, 321, 20, 1166, +128, 1036, 94, 15, -94, -1004, -289, -1305, +-255, -506, -38, 707, 238, 1290, 438, 932, +396, -68, 89, -993, -284, -1160, -460, -376, +-405, 633, -216, 1107, 102, 612, 293, -338, +466, -1022, 471, -647, 196, 382, -289, 1102, +-578, 817, -547, -248, -258, -1312, 219, -1337, +501, -148, 584, 1285, 221, 1875, -251, 1010, +-475, -686, -309, -1928, 90, -1741, 281, -235, +114, 1450, -192, 1976, -303, 971, -110, -680, +294, -1672, 578, -1236, 378, 275, -138, 1390, +-774, 1210, -736, -46, -209, -1305, 546, -1358, +917, -179, 598, 1290, -198, 1753, -888, 761, +-843, -860, -119, -1970, 788, -1492, 912, 264, +261, 1853, -642, 1941, -884, 402, -427, -1475, +282, -2035, 826, -834, 711, 1150, 29, 2138, +-678, 1325, -867, -689, -394, -2235, 482, -2006, +832, -17, 443, 2120, -251, 2576, -610, 993, +-366, -1311, 92, -2455, 430, -1685, 186, 227, +-174, 1705, -424, 1680, -142, 495, 282, -755, +593, -1072, 378, -413, -350, 417, -828, 602, +-791, 43, 1, -562, 813, -574, 1064, 50, +471, 652, -393, 892, -939, 428, -828, -376, +-178, -882, 446, -682, 710, -58, 316, 520, +-156, 524, -301, 170, -4, -134, 265, -30, +78, 206, -350, 145, -658, -97, -357, -441, +136, -549, 704, -176, 849, 493, 363, 923, +-393, 632, -954, -250, -771, -1030, -18, -947, +609, 29, 662, 1052, 222, 1259, -348, 394, +-489, -890, -263, -1565, 156, -1010, 498, 433, +377, 1692, -67, 1680, -523, 466, -621, -1026, +-294, -1762, 177, -1322, 522, -9, 515, 1093, +253, 1420, -42, 889, -331, 67, -474, -664, +-382, -800, -213, -593, 46, -448, 301, -26, +443, 427, 397, 880, 75, 1045, -304, 507, +-513, -495, -330, -1345, 58, -1425, 198, -344, +170, 1078, -63, 1866, -215, 1304, -133, -321, +92, -1799, 471, -1927, 479, -454, 24, 1399, +-698, 2246, -947, 1279, -518, -702, 344, -2207, +917, -1796, 829, 131, 265, 1815, -608, 2057, +-944, 456, -666, -1430, 172, -1949, 799, -701, +673, 1140, -24, 2013, -726, 1043, -754, -865, +-317, -2090, 491, -1642, 893, 326, 716, 2150, +-149, 2369, -968, 670, -994, -1550, -340, -2585, +582, -1646, 780, 566, 465, 2132, -247, 2057, +-542, 466, -442, -1255, 39, -1860, 580, -883, +476, 794, -107, 1627, -803, 976, -865, -592, +-269, -1577, 533, -1257, 909, 345, 669, 1641, +90, 1692, -504, 539, -704, -1089, -536, -1834, +-127, -1199, 83, 311, -75, 1301, -97, 1176, +244, 238, 874, -612, 943, -543, 244, 44, +-878, 527, -1639, 354, -1357, -364, -323, -976, +1039, -760, 1789, 143, 1356, 1101, 136, 1358, +-1279, 567, -1595, -438, -815, -1028, 342, -890, +949, -315, 648, 377, -245, 559, -779, 333, +-479, -41, 301, -155, 997, 199, 916, 583, +41, 525, -1201, -160, -1665, -911, -1052, -1281, +322, -734, 1481, 473, 1623, 1524, 799, 1615, +-509, 706, -1323, -661, -1387, -1577, -776, -1231, +277, -285, 934, 634, 982, 1035, 488, 661, +-190, 55, -713, -407, -736, -289, -457, 50, +59, 213, 459, 58, 566, -175, 289, -342, +-226, -182, -524, 156, -654, 355, -298, 322, +157, 91, 516, -75, 616, -236, 293, 98, +-177, 307, -625, 110, -745, -286, -587, -621, +-4, -610, 454, -47, 784, 768, 704, 1274, +78, 1057, -494, 60, -987, -1142, -814, -1724, +-270, -1186, 485, 156, 823, 1330, 533, 1669, +50, 1075, -491, -146, -540, -1083, -334, -1206, +-29, -574, 95, 217, 26, 625, -141, 417, +-22, 17, 303, -110, 406, 112, 257, 473, +-511, 585, -930, 81, -820, -754, -87, -1269, +855, -939, 1208, 204, 770, 1417, -490, 1748, +-1436, 872, -1376, -501, -385, -1519, 849, -1584, +1442, -552, 953, 769, -251, 1373, -1287, 1065, +-1421, 165, -355, -682, 849, -841, 1298, -400, +581, 144, -757, 406, -1251, 345, -886, 199, +180, 10, 1162, -183, 1191, -188, 159, -255, +-1034, -218, -1574, 226, -908, 627, 361, 723, +1245, 331, 1268, -535, 312, -1166, -668, -1089, +-1361, -112, -1069, 1117, -57, 1650, 716, 1199, +880, -124, 330, -1434, -272, -1721, -500, -905, +-361, 448, -144, 1426, 125, 1461, 26, 674, +-273, -490, -302, -1167, -57, -1089, 409, -340, +431, 631, 152, 1116, -372, 795, -597, 55, +-485, -834, -303, -1028, 160, -598, 390, 257, +355, 1120, 111, 1299, 20, 786, -163, -308, +-310, -1468, -552, -1784, -655, -1094, -244, 376, +205, 1996, 873, 2417, 861, 1488, 278, -388, +-589, -2175, -1282, -2761, -1070, -1712, -228, 353, +664, 2318, 940, 2905, 697, 1798, 0, -394, +-603, -2248, -817, -2570, -516, -1320, -9, 622, +244, 2060, 213, 2000, -111, 661, 28, -1034, +170, -1739, 237, -1074, -92, 373, -633, 1531, +-820, 1345, -472, 172, 340, -1167, 1032, -1639, +1005, -893, 81, 535, -1068, 1677, -1770, 1613, +-1115, 454, 285, -890, 1605, -1509, 1917, -1103, +822, 16, -890, 928, -2347, 1076, -2189, 411, +-733, -463, 1250, -752, 2432, -257, 2056, 655, +371, 1044, -1699, 472, -2593, -721, -2147, -1459, +-201, -1336, 1659, -120, 2382, 1362, 1614, 2173, +-158, 1666, -1722, -8, -2296, -1595, -1341, -2413, +348, -1804, 1541, -73, 1538, 1584, 461, 2445, +-784, 1922, -1218, 393, -746, -1345, 81, -2194, +654, -1682, 430, -402, -380, 917, -935, 1689, +-725, 1367, 242, 367, 1234, -494, 1360, -872, +313, -552, -1119, -37, -2071, 115, -1851, -190, +-402, -313, 1407, -147, 2366, 364, 1814, 1028, +192, 1187, -1504, 712, -2329, -519, -1940, -1713, +-702, -1997, 839, -1025, 1780, 750, 1821, 2189, +927, 2396, -370, 1203, -1399, -619, -1902, -2264, +-1506, -2482, -264, -1224, 1010, 978, 1704, 2365, +1342, 2210, 45, 695, -1206, -1409, -1634, -2285, +-977, -1607, 344, 333, 1334, 2144, 1077, 2487, +-98, 950, -1373, -1664, -1745, -3186, -699, -2539, +947, 152, 2092, 3096, 1660, 4112, -150, 2322, +-1960, -1232, -2580, -4122, -1426, -4214, 597, -1507, +2090, 2249, 2023, 4420, 508, 3469, -1210, 366, +-1853, -2829, -1093, -3682, 316, -1888, 1166, 1094, +683, 3008, -515, 2352, -1376, -96, -958, -2316, +460, -2523, 1615, -561, 1544, 1910, 30, 2950, +-1638, 1750, -2252, -728, -1362, -2789, 355, -2806, +1871, -1114, 1933, 1373, 601, 2876, -991, 2527, +-2052, 793, -1379, -1265, 141, -2380, 1213, -2037, +1373, -666, 238, 944, -1004, 1823, -1494, 1702, +-1006, 739, 247, -599, 1237, -1397, 1408, -1443, +626, -634, -618, 591, -1497, 1495, -1672, 1458, +-963, 434, 331, -1120, 1314, -1824, 1555, -1339, +867, 229, -137, 1937, -942, 2302, -1588, 1115, +-1377, -925, -581, -2573, 414, -2463, 1349, -779, +1177, 1623, 585, 2957, -99, 2423, -912, 532, +-1252, -1818, -1134, -2853, -390, -2204, 500, -376, +931, 1727, 822, 2610, 310, 2043, -325, 500, +-758, -1316, -839, -2222, -418, -1845, 213, -645, +263, 855, 45, 1855, -234, 1949, -187, 1127, +291, -434, 523, -1693, 321, -2148, -272, -1381, +-1210, 415, -1491, 1768, -791, 2199, 664, 1459, +2197, -263, 2034, -1522, 399, -2120, -1798, -1419, +-3222, 33, -2451, 1185, -112, 1914, 2556, 1664, +3695, 698, 2168, -625, -828, -1800, -3533, -2196, +-3865, -1438, -1805, 263, 1484, 1917, 3676, 2762, +3404, 2139, 884, 179, -2281, -1895, -3882, -3216, +-2999, -2616, -260, -385, 2501, 2000, 3616, 3391, +2132, 2751, -582, 595, -2828, -1808, -3390, -2991, +-1691, -2565, 703, -697, 2627, 1259, 2871, 2448, +1263, 2384, -977, 974, -2786, -537, -2766, -1828, +-1115, -2070, 869, -1208, 2383, 44, 2396, 1283, +729, 1966, -1086, 1554, -2453, 383, -2202, -1051, +-593, -2077, 1165, -1648, 2232, -307, 1479, 1253, +-158, 2230, -1515, 1626, -2067, -31, -1105, -1533, +591, -2139, 1610, -1289, 1554, 534, 265, 1738, +-1464, 1904, -1900, 765, -1136, -694, 535, -1577, +1774, -1321, 1483, -189, 262, 804, -1395, 1135, +-2125, 338, -1397, -322, 306, -542, 1820, -95, +2017, 887, 857, 978, -1136, 27, -2328, -1252, +-2017, -2057, -462, -1412, 1334, 686, 2074, 2729, +1577, 3221, -28, 1614, -1434, -1446, -1982, -3781, +-1418, -3798, -84, -1403, 1023, 2182, 1409, 4257, +1013, 3643, 117, 944, -804, -2215, -1338, -3763, +-1028, -2944, -402, -393, 408, 1780, 953, 2655, +787, 2094, 315, 272, -506, -904, -982, -1402, +-856, -1191, -318, -450, 462, 59, 657, 499, +536, 677, 12, 784, -601, 626, -815, 139, +-662, -473, 29, -990, 588, -909, 711, -328, +335, 491, -200, 1091, -678, 1030, -866, 301, +-720, -507, -132, -855, 607, -727, 967, -128, +782, 299, 91, 345, -734, 327, -1226, 327, +-1307, 225, -566, 334, 678, 118, 1530, -460, +1366, -917, 394, -1042, -956, -512, -1772, 718, +-1562, 1680, -462, 1704, 917, 876, 1648, -727, +1213, -2036, 8, -2241, -980, -1143, -1436, 620, +-1012, 2183, -179, 2477, 581, 1359, 965, -331, +730, -1834, 100, -2197, -450, -1405, -612, 16, +-791, 1353, -712, 1656, -334, 1164, 208, 261, +1050, -692, 1247, -783, 753, -549, -315, -180, +-1669, 86, -2161, -187, -1529, -185, 265, -28, +2224, 554, 2807, 1032, 1673, 946, -768, 289, +-2867, -778, -3297, -1434, -1641, -1453, 998, -513, +2908, 758, 2847, 1576, 909, 1534, -1419, 672, +-2660, -384, -2031, -1151, -202, -1222, 1449, -757, +1764, -51, 445, 541, -1084, 793, -1602, 730, +-636, 553, 1050, 189, 1911, -192, 1330, -556, +-674, -834, -2599, -738, -2994, -279, -1393, 344, +1588, 805, 3726, 1110, 3578, 779, 1017, 121, +-2494, -529, -4502, -986, -4017, -1100, -1129, -766, +2554, -82, 4725, 655, 4050, 1482, 993, 1728, +-2695, 1064, -4855, -331, -4116, -1885, -950, -2469, +2486, -1762, 4437, 32, 3525, 1963, 451, 2821, +-2618, 2134, -3921, 503, -2619, -1407, 91, -2463, +2396, -2170, 2800, -1065, 1135, 383, -1185, 1445, +-2443, 1878, -1554, 1654, 509, 1101, 2044, 92, +1821, -1135, 3, -2098, -2043, -2408, -2898, -1547, +-1586, 156, 889, 2013, 3013, 3111, 3284, 2784, +1239, 1208, -1548, -1125, -3538, -3051, -3578, -3577, +-1469, -2537, 1267, -173, 3322, 2383, 3436, 3809, +1667, 3608, -840, 1505, -2769, -1267, -3440, -3331, +-2231, -3908, 96, -2366, 2045, 108, 2865, 2314, +1981, 3485, 254, 2764, -1226, 911, -2079, -1134, +-1858, -2490, -748, -2439, 421, -1446, 1067, 209, +1087, 1419, 534, 1759, 72, 1422, 36, 334, +-433, -558, -727, -1014, -908, -957, -879, -342, +51, 261, 764, 756, 1238, 605, 1031, -136, +-315, -664, -1419, -965, -1762, -392, -776, 800, +1042, 1578, 2201, 1748, 1830, 570, -175, -1238, +-2424, -2551, -3233, -2641, -1820, -1100, 1008, 1229, +3409, 3097, 3821, 3447, 1666, 1986, -1693, -623, +-4251, -2952, -4250, -3853, -1782, -2729, 1706, -323, +4140, 2095, 3927, 3678, 1795, 3392, -1282, 1491, +-3468, -922, -3579, -3002, -2099, -3562, 274, -2373, +2160, -179, 2750, 2165, 2147, 3396, 705, 2814, +-916, 863, -2058, -1493, -2315, -2897, -1682, -2602, +-422, -839, 1074, 1118, 2152, 2319, 2307, 2086, +1327, 458, -547, -1175, -2076, -1863, -2686, -1307, +-2022, 65, -359, 1351, 1465, 1597, 2785, 905, +2639, -225, 966, -1220, -1219, -1411, -2843, -1115, +-3228, -245, -1883, 701, 503, 1360, 2753, 1899, +3850, 1484, 2523, 242, -320, -1448, -2973, -2747, +-4107, -2721, -2907, -1238, -244, 1209, 2586, 3229, +3932, 3612, 2979, 2133, 358, -526, -2325, -2922, +-3324, -3680, -2521, -2553, -752, -297, 1151, 1843, +2199, 2873, 2023, 2475, 892, 1058, -363, -424, +-1216, -1307, -1437, -1511, -1108, -1303, -593, -1019, +165, -569, 828, 141, 1165, 1081, 900, 2091, +279, 2195, -566, 1235, -1276, -405, -1172, -2332, +-529, -3081, 585, -2279, 1191, -264, 831, 2006, +128, 3089, -749, 2666, -979, 815, -741, -1312, +-162, -2524, 681, -2361, 818, -846, 620, 756, +106, 1856, -526, 1617, -743, 424, -817, -592, +-684, -1262, -115, -861, 533, 130, 967, 992, +1148, 1174, 637, 451, -237, -593, -1069, -1421, +-1709, -1302, -1285, -533, -342, 593, 600, 1446, +1401, 1503, 1533, 1092, 1157, 197, 198, -842, +-910, -1481, -1682, -1691, -1899, -1326, -1348, -261, +-302, 927, 1108, 1931, 2160, 2254, 2297, 1781, +1489, 508, -325, -1332, -1977, -2902, -2909, -3346, +-2870, -2178, -1128, 345, 1317, 2985, 3089, 4319, +3559, 3477, 2090, 780, -550, -2219, -2776, -4184, +-3782, -3951, -2827, -1694, -294, 980, 2100, 3001, +3044, 3370, 2523, 2269, 760, 450, -1179, -1218, +-2121, -2023, -1839, -2084, -797, -1544, 205, -597, +706, 503, 367, 1401, 388, 1913, 594, 1748, +723, 884, 636, -307, -161, -1325, -1018, -1968, +-1791, -1844, -1718, -921, -380, 363, 1257, 1431, +2233, 2015, 1998, 1939, 532, 1016, -1158, -310, +-2109, -1677, -2123, -2518, -955, -2291, 618, -908, +1556, 1090, 1844, 2688, 1123, 3266, 78, 2042, +-934, -473, -1638, -2827, -1576, -3714, -944, -2379, +245, 277, 1352, 2694, 1719, 3372, 1393, 1891, +255, -388, -1123, -2037, -1792, -2089, -1563, -796, +-601, 547, 438, 848, 1149, 201, 1205, -417, +870, -414, 273, 638, -430, 1769, -770, 1538, +-946, 48, -983, -2037, -731, -3239, -66, -2189, +741, 437, 1390, 2991, 1524, 3819, 661, 2240, +-486, -739, -1506, -3131, -1914, -3382, -1237, -1573, +68, 867, 1227, 2371, 1638, 2064, 1024, 614, +-196, -825, -900, -1155, -864, -294, -119, 721, +566, 869, 449, -57, -432, -1453, -1354, -2005, +-1541, -1015, -500, 864, 1490, 2510, 2911, 2930, +2822, 1637, 711, -834, -2352, -2887, -4396, -3384, +-4033, -2184, -1134, 228, 2489, 2404, 4820, 3213, +4472, 2505, 1616, 695, -2159, -1294, -4481, -2496, +-4150, -2316, -1810, -1321, 1194, 75, 2977, 1232, +2931, 1677, 1507, 1564, -189, 811, -1189, -15, +-1246, -670, -859, -1033, -735, -993, -819, -913, +-635, -537, 63, 12, 1122, 684, 2010, 1264, +1914, 1567, 794, 1225, -1060, 110, -2705, -1216, +-2878, -2174, -1376, -2153, 910, -888, 2471, 998, +2729, 2348, 1391, 2483, -629, 1231, -1963, -831, +-2220, -2176, -1038, -1961, 529, -673, 1388, 823, +1130, 1428, 155, 815, -786, -255, -986, -825, +-283, -532, 632, 455, 1251, 1221, 774, 936, +-329, -193, -1320, -1463, -1749, -1854, -1077, -899, +167, 707, 1527, 1895, 2131, 1881, 1539, 743, +147, -927, -1500, -1787, -2310, -1356, -1934, -209, +-663, 1056, 989, 1357, 2049, 459, 1892, -599, +747, -1177, -633, -726, -1357, 454, -1252, 1363, +-599, 1464, 26, 419, 245, -1050, 307, -1994, +177, -1789, 184, -381, 462, 1240, 697, 2179, +413, 1945, -266, 607, -1012, -886, -1405, -1782, +-957, -1871, -12, -876, 1037, 402, 1387, 1091, +1004, 1328, 252, 812, -608, 44, -904, -353, +-667, -368, -449, -105, -359, -36, -107, -343, +198, -807, 450, -933, 935, -320, 911, 735, +346, 1703, -361, 1861, -1271, 1065, -1413, -455, +-774, -1989, 136, -2389, 1059, -1713, 1267, -221, +689, 1329, -80, 2084, -658, 2144, -694, 1378, +-271, 128, 42, -1246, 42, -2211, -45, -2426, +-272, -1656, -310, 78, 102, 1925, 541, 3038, +792, 2630, 552, 871, -109, -1344, -706, -2737, +-1043, -2620, -937, -1315, -296, 520, 694, 1829, +1169, 1900, 928, 1078, 163, 62, -688, -544, +-926, -604, -710, -513, 30, -459, 756, -364, +858, -293, 232, -53, -763, 356, -1311, 538, +-899, 574, 296, 420, 1359, 33, 1723, -81, +1056, -53, -406, -152, -1624, -505, -2077, -823, +-1405, -792, 19, -375, 1211, 601, 1735, 1464, +1518, 1668, 789, 1065, -112, -244, -971, -1501, +-1607, -2030, -1704, -1504, -1179, -321, -52, 896, +1166, 1628, 2006, 1507, 2047, 840, 1155, -24, +-394, -594, -1873, -799, -2272, -946, -1722, -839, +-494, -630, 895, -220, 1609, 543, 1614, 1188, +1119, 1512, 350, 1303, -445, 366, -949, -876, +-1422, -1813, -1472, -2101, -833, -1353, 76, 165, +1172, 1541, 1759, 2306, 1660, 2007, 899, 679, +-548, -851, -1745, -1929, -2074, -2078, -1358, -1244, +22, 100, 1178, 1229, 1704, 1635, 1372, 1236, +404, 520, -645, -225, -1357, -804, -1234, -1022, +-402, -1013, 432, -567, 942, 171, 901, 876, +316, 1292, -471, 880, -996, 41, -980, -766, +-233, -1237, 700, -824, 1338, 82, 1103, 676, +156, 945, -799, 682, -1369, -12, -1307, -566, +-675, -839, 462, -672, 1253, -169, 1496, 400, +1043, 813, -56, 907, -665, 517, -1149, -81, +-1345, -770, -743, -1252, -93, -1045, 690, -250, +1177, 725, 1053, 1488, 740, 1503, 105, 579, +-680, -583, -1088, -1451, -1222, -1561, -727, -866, +104, 148, 781, 1157, 1114, 1539, 913, 1155, +343, 245, -398, -772, -808, -1404, -717, -1203, +-305, -521, 145, 357, 326, 1182, 149, 1271, +-125, 740, -114, -170, 2, -1043, 311, -1303, +550, -780, 394, 214, -68, 1090, -631, 1285, +-750, 572, -561, -495, -78, -1116, 330, -911, +460, -51, 474, 667, 326, 781, 202, 262, +142, -369, 40, -502, -344, -127, -803, 442, +-1075, 549, -832, 49, 94, -632, 1179, -945, +1802, -420, 1503, 476, 470, 1168, -1046, 1119, +-2113, 231, -2130, -816, -1084, -1327, 589, -1003, +1972, -57, 2240, 816, 1416, 1142, -14, 785, +-1387, 43, -1912, -491, -1550, -752, -411, -601, +796, -205, 1368, 84, 1155, 341, 287, 496, +-401, 502, -552, 319, -264, 2, 99, -473, +63, -823, -295, -753, -658, -266, -569, 640, +82, 1265, 933, 1160, 1428, 285, 948, -969, +-381, -1690, -1408, -1293, -1630, -46, -896, 1306, +540, 1876, 1501, 1129, 1509, -344, 597, -1472, +-806, -1668, -1428, -696, -1048, 708, -40, 1467, +942, 1130, 1113, 46, 498, -1023, -369, -1223, +-995, -354, -766, 670, 30, 1124, 692, 733, +815, -309, 275, -1152, -447, -1139, -638, -261, +-357, 869, 49, 1408, 584, 851, 523, -310, +33, -1135, -448, -1115, -728, -248, -269, 639, +406, 942, 690, 555, 594, -302, 71, -838, +-456, -674, -731, 54, -548, 840, -25, 904, +426, 333, 587, -474, 384, -996, 87, -866, +-120, -267, -252, 430, -283, 876, -287, 849, +-183, 424, -3, -145, 183, -563, 357, -666, +390, -532, 301, -318, -44, 12, -313, 349, +-480, 502, -489, 674, -41, 513, 289, 63, +391, -287, 408, -695, 156, -782, -63, -579, +-132, -148, -347, 384, -279, 725, -125, 877, +4, 651, 283, 183, 339, -365, 215, -840, +16, -1038, -290, -788, -337, -196, -112, 519, +148, 1090, 397, 1145, 305, 763, -33, -33, +-428, -875, -467, -1158, -201, -1041, 115, -407, +514, 375, 651, 826, 374, 930, -72, 634, +-529, 100, -752, -398, -549, -553, -90, -447, +338, -231, 783, -47, 732, -166, 367, -166, +-152, 79, -586, 534, -627, 938, -474, 809, +-9, 33, 246, -926, 224, -1369, 198, -1074, +120, -68, 342, 945, 584, 1306, 343, 877, +-188, -15, -855, -743, -1196, -831, -869, -375, +-39, 189, 995, 400, 1612, 119, 1354, -261, +453, -359, -772, -42, -1496, 415, -1319, 704, +-758, 441, 30, -230, 798, -675, 1060, -829, +1053, -461, 724, 226, 144, 722, -373, 727, +-897, 386, -1226, -204, -1066, -712, -354, -650, +687, -262, 1349, 330, 1448, 766, 774, 616, +-250, 54, -926, -640, -1089, -978, -687, -681, +-79, 110, 254, 923, 241, 1288, 165, 845, +129, -263, 455, -1209, 832, -1533, 727, -918, +62, 324, -904, 1248, -1555, 1436, -1284, 828, +-301, -235, 888, -1032, 1650, -1170, 1512, -654, +604, 69, -516, 645, -1169, 754, -1092, 458, +-517, 64, 119, -336, 320, -475, 260, -362, +184, -110, 276, 289, 548, 417, 641, 274, +321, -85, -306, -498, -1043, -572, -1278, -196, +-704, 354, 331, 745, 1280, 671, 1404, 107, +720, -527, -334, -917, -1042, -737, -924, -96, +-226, 542, 533, 854, 664, 656, 219, 35, +-375, -461, -704, -608, -275, -476, 454, -34, +926, 287, 817, 326, 108, 237, -668, -17, +-962, -185, -681, -181, -70, -83, 483, 33, +651, 128, 369, 101, 126, 43, 86, -57, +72, -149, 115, -141, -67, -101, -493, 19, +-674, 95, -544, 79, 52, 14, 739, 6, +1056, 89, 864, 199, 155, 186, -555, -99, +-1043, -442, -952, -705, -244, -581, 413, 70, +907, 774, 896, 1213, 303, 1006, -286, 29, +-715, -1021, -665, -1586, -133, -1280, 461, -193, +716, 932, 521, 1458, -13, 1139, -528, 267, +-736, -547, -403, -792, 255, -621, 678, -307, +712, -124, 343, -234, -111, -241, -347, 156, +-423, 691, -218, 1163, -21, 1046, -21, 179, +-36, -957, -4, -1798, 244, -1725, 613, -673, +682, 851, 354, 1954, -187, 1935, -778, 826, +-1003, -633, -727, -1549, -97, -1514, 683, -701, +1262, 195, 1168, 714, 560, 613, -255, 279, +-955, 99, -1084, 99, -814, 310, -198, 234, +592, -194, 928, -712, 825, -985, 408, -724, +-121, -18, -340, 785, -246, 1203, -130, 942, +-31, 223, -132, -571, -378, -967, -389, -816, +-127, -375, 486, 71, 1101, 286, 1165, 380, +630, 410, -369, 394, -1306, 317, -1460, 41, +-954, -323, 38, -698, 1104, -740, 1519, -436, +1237, 94, 441, 720, -382, 854, -833, 525, +-978, -22, -742, -554, -301, -680, 122, -414, +575, -27, 807, 204, 825, 215, 686, 91, +180, 52, -433, 135, -872, 211, -976, 120, +-531, -294, 69, -560, 650, -468, 968, -74, +896, 514, 483, 744, -154, 425, -650, -214, +-809, -790, -479, -864, 98, -333, 567, 476, +657, 997, 309, 903, -184, 119, -486, -811, +-318, -1247, 219, -923, 729, 54, 787, 1050, +197, 1328, -614, 690, -1064, -351, -819, -1174, +2, -1239, 915, -404, 1176, 570, 777, 1077, +40, 826, -505, -27, -578, -707, -187, -860, +140, -402, 73, 296, -204, 635, -517, 517, +-173, -3, 643, -528, 1319, -609, 1381, -211, +481, 360, -876, 554, -1858, 318, -1832, -188, +-658, -571, 918, -492, 1957, -68, 2073, 378, +1063, 547, -373, 371, -1395, -115, -1718, -524, +-1082, -626, 6, -385, 892, 131, 1249, 497, +1088, 624, 520, 388, -143, -94, -584, -490, +-673, -642, -453, -482, 31, -109, 319, 342, +291, 595, 312, 467, 90, 177, -7, -247, +94, -535, 150, -422, 341, -224, 134, 78, +-196, 249, -405, 235, -367, 179, -37, 55, +284, 11, 539, -112, 535, -242, 303, -317, +-48, -247, -317, 57, -299, 341, -23, 439, +174, 211, 273, -230, 135, -556, -25, -460, +-14, -85, -103, 378, 98, 550, 361, 255, +393, -147, 326, -430, -62, -399, -353, -116, +-408, 133, -345, 226, -86, 78, 294, -90, +667, -55, 839, 95, 528, 271, -10, 157, +-488, -234, -659, -588, -481, -653, -182, -143, +260, 472, 618, 836, 747, 715, 603, 44, +205, -639, -89, -901, -356, -610, -543, -58, +-460, 509, -179, 653, 197, 338, 593, -57, +720, -332, 522, -311, 223, -98, -186, 142, +-463, 132, -411, -88, -138, -256, 130, -345, +303, -90, 286, 244, 236, 440, 160, 456, +181, 128, 254, -228, 257, -491, 105, -637, +-197, -494, -457, -102, -474, 373, -172, 737, +320, 825, 816, 393, 1039, -257, 678, -848, +-114, -1124, -873, -739, -1057, 23, -605, 809, +215, 1158, 999, 831, 1171, 61, 749, -722, +-132, -1022, -830, -833, -824, -208, -186, 454, +623, 662, 932, 572, 620, 154, -5, -192, +-647, -240, -647, -230, -131, -207, 442, -287, +899, -345, 724, -164, 139, 295, -277, 722, +-540, 720, -425, 268, -128, -532, 184, -1119, +494, -1009, 547, -263, 448, 718, 286, 1296, +-114, 979, -404, -47, -397, -1029, -154, -1328, +415, -725, 678, 367, 441, 1126, -10, 1075, +-446, 242, -423, -763, 132, -1207, 763, -733, +991, 211, 493, 909, -504, 912, -1228, 201, +-962, -517, 137, -759, 1223, -471, 1498, 110, +797, 392, -369, 204, -1153, -151, -1027, -370, +-65, -92, 1007, 517, 1304, 801, 473, 362, +-629, -520, -1153, -1344, -624, -1375, 647, -343, +1495, 1000, 1403, 1834, 373, 1556, -965, 227, +-1618, -1250, -1046, -2008, 250, -1519, 1357, -223, +1583, 1044, 755, 1562, -300, 1119, -893, 206, +-698, -616, 52, -908, 571, -670, 587, -284, +76, 60, -469, 196, -514, 107, -23, 83, +767, 178, 1213, 321, 989, 350, 135, 106, +-857, -278, -1268, -635, -995, -693, -97, -345, +940, 94, 1478, 496, 1364, 672, 558, 476, +-386, 55, -925, -360, -950, -573, -455, -472, +158, -143, 483, 245, 625, 330, 540, 103, +337, -191, 315, -376, 216, -196, 99, 323, +-184, 659, -553, 543, -570, -16, -334, -712, +297, -1038, 851, -797, 955, -112, 833, 586, +246, 984, -355, 979, -474, 493, -499, -162, +-272, -800, 4, -1182, 123, -1034, 401, -492, +548, 363, 655, 1105, 675, 1309, 320, 926, +-157, 18, -668, -928, -918, -1367, -586, -1113, +80, -296, 775, 531, 1179, 927, 1037, 746, +482, 233, -186, -182, -644, -244, -735, -175, +-474, -133, 38, -256, 416, -506, 623, -499, +747, -117, 545, 473, 245, 889, -85, 839, +-413, 269, -430, -577, -210, -1034, 108, -950, +337, -342, 452, 407, 388, 768, 187, 661, +106, 183, 55, -247, 3, -380, 13, -279, +4, -129, -37, -65, 14, -127, 166, -131, +343, 64, 421, 320, 300, 410, 3, 175, +-219, -248, -213, -592, 106, -571, 453, -59, +538, 504, 341, 700, -176, 405, -546, -326, +-443, -879, 46, -795, 670, -139, 969, 722, +670, 1014, -61, 588, -643, -308, -684, -1049, +-253, -1049, 425, -293, 796, 696, 584, 1116, +158, 724, -247, -277, -313, -1154, 113, -1095, +500, -179, 548, 883, 212, 1316, -331, 753, +-651, -512, -383, -1425, 323, -1355, 943, -370, +999, 951, 464, 1560, -292, 1105, -708, -89, +-607, -1195, -194, -1406, 431, -741, 738, 283, +554, 973, 216, 874, -188, 301, -195, -335, +74, -613, 282, -415, 300, -69, 119, 213, +-54, 203, -183, -33, -62, -164, 125, -185, +354, -40, 494, 189, 380, 265, 226, 179, +50, -30, -172, -309, -326, -440, -362, -351, +-107, -24, 300, 276, 649, 407, 710, 337, +429, 66, 77, -148, -264, -339, -418, -393, +-296, -251, -53, -130, 219, 112, 321, 315, +413, 318, 477, 287, 461, 129, 305, -182, +-79, -461, -397, -536, -481, -444, -274, -66, +60, 430, 511, 656, 721, 587, 633, 194, +331, -412, -64, -761, -312, -681, -365, -251, +-316, 310, -188, 586, 156, 404, 512, 51, +699, -220, 746, -254, 413, -51, -147, 142, +-658, 32, -791, -233, -371, -461, 345, -421, +887, 56, 972, 594, 630, 807, 85, 483, +-487, -208, -718, -788, -464, -900, 16, -483, +486, 119, 640, 597, 612, 635, 432, 318, +102, -15, -230, -299, -522, -312, -505, -163, +-175, -140, 290, -166, 730, -147, 920, -61, +637, 225, 35, 420, -512, 363, -775, 83, +-521, -302, 30, -496, 613, -422, 906, -96, +800, 218, 376, 319, -215, 214, -579, -67, +-566, -220, -333, -145, 116, -5, 606, 159, +823, 208, 615, 19, 113, -188, -335, -380, +-526, -389, -316, -145, 67, 221, 390, 494, +616, 483, 411, 221, -13, -199, -257, -496, +-166, -535, 160, -345, 334, -29, 318, 228, +105, 321, -117, 301, -150, 245, 32, 123, +301, -39, 398, -292, 228, -570, -126, -577, +-240, -264, -24, 301, 235, 748, 411, 723, +330, 227, 5, -421, -365, -806, -363, -650, +56, -63, 590, 505, 800, 679, 406, 344, +-298, -323, -607, -766, -490, -628, 47, -10, +698, 670, 831, 945, 501, 512, -162, -333, +-570, -971, -374, -1006, 93, -412, 375, 375, +398, 807, 150, 689, -59, 264, 31, -129, +199, -300, 328, -310, 224, -307, -196, -403, +-530, -390, -371, -125, 192, 329, 723, 806, +922, 843, 471, 347, -126, -398, -569, -1015, +-691, -989, -243, -406, 297, 321, 609, 789, +560, 719, 257, 187, 97, -289, 76, -451, +68, -244, -49, 120, -324, 235, -456, 31, +-328, -337, 188, -530, 818, -327, 1047, 164, +774, 647, -23, 789, -789, 448, -1054, -246, +-712, -786, 113, -904, 858, -603, 1145, 65, +808, 586, 154, 733, -410, 543, -589, 137, +-451, -250, -132, -457, 234, -449, 326, -313, +332, -178, 328, 6, 269, 234, 265, 384, +100, 424, -204, 285, -373, -109, -309, -476, +-130, -565, 203, -404, 516, 6, 570, 374, +426, 494, 104, 341, -246, -25, -384, -313, +-315, -480, -120, -354, 214, 10, 480, 341, +527, 466, 333, 278, 36, -109, -193, -466, +-223, -529, -203, -247, -60, 162, 189, 422, +313, 417, 372, 128, 217, -155, -22, -232, +-59, -188, -73, -69, -79, -94, -81, -171, +-14, -152, 166, -34, 322, 300, 418, 539, +334, 455, 28, 54, -377, -469, -519, -828, +-293, -682, 203, -94, 697, 455, 798, 723, +448, 613, -147, 136, -602, -287, -663, -467, +-230, -452, 333, -222, 608, 6, 569, 118, +238, 119, -78, 73, -205, 125, -119, 200, +31, 196, 12, 41, -113, -193, -153, -417, +37, -465, 397, -250, 671, 53, 553, 393, +87, 521, -431, 394, -744, 76, -572, -255, +50, -473, 627, -525, 842, -351, 601, 19, +94, 393, -295, 592, -408, 476, -259, 35, +-65, -421, 53, -685, 76, -535, 77, -13, +261, 495, 513, 688, 586, 413, 276, -186, +-314, -668, -776, -686, -799, -268, -316, 325, +524, 743, 1097, 623, 1027, 59, 415, -502, +-459, -777, -845, -493, -640, 114, -117, 555, +357, 596, 531, 161, 377, -339, 152, -545, +11, -307, 18, 170, 174, 476, 63, 389, +-168, -64, -366, -512, -313, -586, 40, -263, +415, 255, 592, 602, 454, 548, 117, 171, +-276, -246, -419, -478, -254, -516, 30, -288, +241, 0, 277, 240, 143, 384, 26, 370, +45, 242, 114, 20, 203, -218, 159, -431, +-87, -468, -261, -310, -278, 25, -95, 397, +213, 530, 400, 407, 409, 35, 223, -351, +-66, -467, -255, -313, -234, -35, -88, 180, +77, 228, 192, 92, 181, -46, 101, -107, +38, -68, -6, 84, 101, 163, 233, 93, +147, -56, -38, -227, -213, -300, -249, -213, +-102, 4, 96, 222, 340, 355, 446, 282, +310, 68, 17, -175, -229, -342, -314, -278, +-191, -168, -83, 27, 46, 129, 250, 136, +327, 178, 363, 137, 225, 95, -8, -2, +-247, -202, -375, -303, -304, -269, -58, -86, +312, 146, 520, 318, 470, 227, 203, -12, +-191, -112, -405, -133, -361, 14, -105, 48, +229, -104, 396, -223, 300, -229, 138, -18, +-54, 291, -183, 387, -190, 249, -82, -62, +90, -345, 219, -408, 249, -170, 130, 76, +-54, 205, -169, 182, -190, 30, -21, -41, +266, -22, 455, 62, 277, 91, -154, -32, +-466, -228, -504, -359, -69, -254, 500, 86, +836, 447, 617, 601, -63, 339, -790, -189, +-952, -684, -438, -780, 431, -386, 1045, 276, +925, 753, 285, 775, -569, 351, -995, -242, +-627, -708, 165, -760, 769, -361, 735, 164, +174, 527, -417, 546, -476, 246, -119, -2, +261, -119, 482, -205, 276, -267, -161, -439, +-405, -435, -341, -27, -2, 516, 355, 907, +435, 710, 280, -60, 2, -858, -196, -1111, +-239, -617, -180, 240, -17, 936, 104, 878, +106, 342, 166, -348, 188, -679, 140, -525, +38, -192, -125, 178, -208, 338, -132, 343, +55, 143, 216, -94, 296, -247, 226, -232, +-152, -30, -379, 66, -259, 80, 48, 0, +454, -46, 537, 21, 219, 102, -197, 142, +-537, 79, -508, -133, -168, -280, 238, -274, +546, -129, 520, 214, 284, 374, -27, 351, +-312, 111, -391, -215, -268, -420, -117, -344, +25, -144, 161, 103, 349, 245, 412, 218, +339, 232, 94, 155, -239, 36, -385, -130, +-389, -408, -298, -482, -84, -270, 184, 77, +485, 462, 676, 602, 529, 436, 101, 49, +-480, -384, -841, -673, -716, -642, -219, -218, +446, 404, 803, 755, 750, 570, 312, 44, +-207, -477, -559, -595, -492, -234, -96, 232, +145, 418, 139, 164, -36, -213, -52, -404, +171, -234, 494, 212, 434, 455, 136, 309, +-322, -15, -759, -244, -705, -290, -206, -233, +520, -117, 1024, -60, 879, 100, 99, 377, +-727, 471, -1048, 177, -597, -315, 251, -575, +799, -446, 812, 61, 265, 476, -309, 439, +-632, 101, -585, -317, -127, -443, 406, -287, +704, 110, 455, 500, -31, 520, -395, 230, +-453, -232, -263, -621, -83, -744, 97, -433, +316, 194, 489, 811, 348, 1106, 44, 677, +-292, -261, -484, -1073, -387, -1283, -210, -673, +153, 276, 440, 1009, 536, 1094, 365, 599, +-14, -131, -348, -674, -461, -824, -284, -599, +-102, -59, 127, 411, 235, 538, 222, 404, +281, 61, 242, -173, 68, -134, -151, -97, +-354, -74, -534, -173, -359, -254, 8, -145, +508, 130, 849, 473, 628, 561, -6, 190, +-642, -422, -875, -733, -615, -586, 19, 24, +586, 635, 856, 764, 513, 429, -54, -229, +-454, -714, -551, -747, -277, -321, 15, 310, +200, 755, 224, 687, 171, 252, 82, -300, +31, -674, 28, -619, -29, -215, -180, 146, +-284, 361, -189, 430, 47, 395, 394, 244, +427, -85, 118, -442, -236, -641, -486, -484, +-311, -92, 91, 387, 440, 660, 508, 626, +72, 346, -419, -285, -575, -798, -331, -773, +257, -345, 662, 347, 556, 805, 121, 715, +-497, 149, -739, -491, -459, -761, 72, -468, +540, 152, 678, 608, 461, 568, -115, 101, +-598, -381, -655, -528, -349, -391, 174, 1, +512, 376, 506, 527, 310, 417, -135, 7, +-487, -360, -453, -596, -133, -469, 277, -92, +347, 337, 89, 620, -88, 531, -165, 141, +-33, -377, 85, -596, 67, -404, 41, -64, +-32, 250, -136, 326, -187, 239, -127, 113, +80, -23, 241, -109, 312, -166, 167, -193, +-136, -195, -333, -57, -426, 152, -208, 390, +188, 347, 427, -46, 433, -369, 103, -435, +-302, -191, -455, 211, -236, 373, 132, 279, +350, 47, 221, -189, -118, -321, -292, -253, +-284, -21, 15, 175, 271, 304, 436, 238, +229, 52, -210, -189, -537, -304, -469, -243, +-72, -36, 276, 139, 393, 192, 290, 226, +158, 154, 20, 27, -244, -197, -489, -374, +-432, -317, -114, -13, 350, 306, 532, 423, +351, 271, 8, -46, -286, -334, -391, -448, +-257, -189, 10, 140, 261, 337, 264, 259, +-36, 21, -315, -170, -221, -206, 169, -108, +405, 41, 227, 181, -85, 150, -367, 21, +-446, -211, -305, -292, 46, -82, 441, 140, +636, 318, 386, 341, -207, 107, -685, -230, +-706, -519, -232, -502, 367, -91, 705, 447, +506, 713, -62, 441, -546, -106, -525, -601, +-147, -610, 218, -201, 335, 248, 148, 507, +-118, 301, -144, -45, -86, -316, -27, -204, +78, 48, 79, 217, -43, 186, -134, -73, +-162, -323, -129, -357, 110, -46, 337, 300, +349, 524, -2, 396, -462, -52, -564, -510, +-328, -675, 141, -385, 469, 242, 544, 703, +367, 652, -4, 145, -559, -480, -858, -598, +-543, -267, 36, 45, 638, 186, 836, 203, +546, 203, -44, 244, -605, 177, -857, -140, +-592, -488, -34, -599, 457, -290, 673, 262, +561, 736, 191, 824, -298, 349, -725, -422, +-736, -973, -135, -945, 350, -338, 545, 504, +413, 1093, 33, 958, -236, 225, -369, -566, +-272, -963, 29, -762, 201, -134, 11, 451, +-187, 618, -96, 464, 151, 52, 240, -267, +81, -241, -31, 18, -80, 149, -234, -62, +-420, -395, -303, -521, 164, -189, 594, 501, +556, 936, 50, 710, -378, 14, -556, -751, +-535, -1039, -113, -658, 342, 55, 566, 649, +410, 795, -80, 517, -426, -3, -404, -383, +-203, -426, 60, -175, 286, -21, 223, -176, +-34, -219, -303, -84, -188, 401, 172, 777, +216, 617, -49, -75, -211, -775, -138, -969, +34, -603, 45, 241, -10, 875, 28, 923, +96, 360, -150, -416, -321, -868, -81, -675, +280, 11, 401, 679, 152, 759, -323, 137, +-587, -582, -433, -754, -18, -217, 557, 520, +633, 743, 182, 321, -393, -333, -587, -618, +-294, -444, 35, 56, 211, 459, 307, 487, +158, 125, -243, -282, -506, -474, -178, -308, +416, 172, 656, 499, 130, 460, -530, 13, +-653, -552, -314, -756, 33, -165, 293, 597, +457, 873, 402, 360, 13, -538, -429, -922, +-446, -468, -58, 390, 123, 862, -107, 593, +-247, -148, -87, -812, 303, -775, 461, -113, +300, 667, -28, 907, -397, 354, -617, -463, +-461, -825, -35, -530, 429, 192, 428, 719, +224, 589, 6, -44, -156, -635, -309, -701, +-179, -102, 56, 705, 98, 920, -156, 312, +-375, -719, -152, -1176, 337, -629, 605, 495, +278, 1228, -155, 986, -444, -95, -538, -1084, +-289, -1206, 100, -345, 432, 800, 319, 1360, +-79, 753, -336, -561, -158, -1455, 220, -1104, +271, 199, 86, 1402, -259, 1437, -385, 297, +-472, -1141, -216, -1616, 254, -709, 674, 724, +540, 1533, 30, 967, -394, -366, -550, -1313, +-437, -1053, -179, 36, 137, 1081, 378, 1175, +361, 374, 74, -757, -151, -1335, -85, -815, +-84, 314, -181, 1121, -252, 1081, -135, 278, +74, -661, 222, -1017, 299, -557, 67, 222, +-168, 781, -401, 556, -290, -211, 98, -795, +359, -483, 240, 395, -104, 1007, -243, 752, +-214, -245, -181, -1122, -36, -1234, 139, -321, +258, 856, 135, 1460, -100, 874, -238, -327, +-13, -1272, 18, -1103, -18, -77, -187, 944, +-141, 1113, -84, 368, 3, -684, 174, -1307, +337, -745, 367, 446, -99, 1404, -406, 1258, +-604, 165, -324, -1079, 23, -1601, 288, -928, +369, 308, 363, 1374, 253, 1356, -110, 439, +-339, -756, -547, -1188, -476, -667, -158, 225, +223, 701, 545, 468, 526, 35, 324, -432, +-255, -372, -602, 30, -702, 444, -308, 380, +261, -3, 678, -410, 593, -529, -21, -100, +-495, 332, -717, 481, -344, 201, 307, -119, +695, -393, 451, -366, -196, 28, -579, 385, +-552, 451, -40, 165, 382, -211, 395, -521, +170, -451, -258, -136, -469, 381, -281, 598, +283, 498, 552, 68, 360, -451, -342, -637, +-725, -437, -548, 67, -65, 431, 450, 531, +699, 267, 536, -179, -39, -394, -609, -248, +-867, 44, -420, 202, 354, 190, 662, 2, +409, -199, -205, -256, -536, -80, -340, 212, +240, 420, 631, 404, 447, -24, -284, -544, +-909, -767, -773, -377, -115, 365, 656, 979, +977, 878, 678, 52, -109, -874, -779, -1137, +-990, -528, -489, 426, 270, 1038, 735, 852, +531, 36, -25, -648, -299, -762, -336, -225, +-118, 325, 140, 456, 140, 60, 14, -341, +-252, -371, -340, 35, -131, 609, 416, 807, +588, 401, 136, -581, -483, -1373, -669, -1359, +-290, -108, 281, 1443, 648, 2052, 414, 1172, +-74, -631, -490, -1997, -607, -1851, -355, -352, +234, 1267, 628, 1789, 566, 868, 154, -632, +-486, -1365, -701, -865, -302, 425, 228, 1260, +473, 908, 132, -268, -172, -1315, -272, -1414, +-121, -304, 139, 1119, 303, 1787, 207, 1179, +-40, -313, -422, -1553, -526, -1753, -228, -627, +291, 920, 485, 1721, 224, 1129, -86, -339, +-189, -1553, -14, -1374, 102, 159, 83, 1598, +-249, 1659, -422, 283, -401, -1492, -84, -2228, +499, -1233, 855, 830, 622, 2412, -91, 2238, +-773, 450, -908, -1727, -529, -2679, 212, -1552, +614, 744, 470, 2254, 45, 1857, -196, 133, +-114, -1627, 207, -1809, 342, -309, -86, 1391, +-651, 1741, -928, 527, -581, -1293, 300, -2150, +1266, -1102, 1375, 1042, 429, 2487, -860, 1888, +-1541, -219, -1025, -2340, 38, -2622, 934, -698, +987, 1830, 313, 2850, -328, 1524, -629, -1020, +-355, -2741, 304, -2169, 629, 125, 118, 2351, +-482, 2592, -797, 812, -394, -1507, 444, -2614, +917, -1582, 613, 575, -147, 2129, -829, 1689, +-776, 50, -68, -1301, 658, -1239, 761, -72, +44, 871, -624, 715, -820, -245, -368, -889, +337, -694, 967, 326, 859, 1095, 39, 1003, +-864, 42, -1190, -1018, -442, -1162, 569, -357, +885, 661, 330, 914, -225, 403, -354, -478, +-146, -762, 159, -149, 277, 719, 140, 951, +-322, 214, -581, -945, -409, -1471, 255, -657, +764, 788, 605, 1717, -19, 1275, -545, -114, +-574, -1372, -298, -1707, 94, -700, 542, 811, +451, 1772, -64, 1238, -572, -241, -628, -1431, +-25, -1500, 501, -212, 649, 943, 276, 1331, +-77, 640, -475, -278, -764, -893, -531, -849, +6, -95, 709, 359, 766, 398, 333, 159, +-56, 1, -359, 203, -470, 463, -374, 208, +-220, -591, 144, -1165, 362, -934, 248, 254, +201, 1471, 59, 1791, -98, 655, -192, -1101, +-39, -2098, -23, -1523, -103, 236, -344, 1667, +-266, 1915, 109, 700, 513, -881, 567, -1772, +171, -1160, -232, 170, -603, 1376, -623, 1316, +-350, 26, 352, -1077, 733, -1118, 545, -74, +-59, 1058, -573, 1234, -529, 57, -192, -1211, +331, -1517, 485, -468, 398, 1280, -24, 2011, +-518, 1053, -602, -770, -262, -2060, 442, -1832, +634, -114, 419, 1513, -117, 2007, -502, 1134, +-441, -439, -76, -1572, 294, -1438, 346, -383, +89, 696, -321, 1087, -433, 486, -164, -221, +357, -543, 561, -101, 294, 407, -150, 533, +-686, 37, -472, -744, -132, -940, 272, -446, +451, 474, 165, 1140, -66, 895, -297, 96, +15, -651, 309, -697, 351, -244, -52, 237, +-672, 213, -906, -238, -388, -544, 578, -213, +1218, 540, 1190, 1180, 242, 1146, -941, 82, +-1498, -1231, -1150, -1767, 145, -1209, 1074, 193, +1296, 1477, 542, 1645, -466, 951, -917, -357, +-661, -1161, 24, -1165, 571, -372, 586, 550, +15, 727, -703, 286, -869, -381, -228, -655, +626, -223, 1198, 538, 777, 1137, -194, 864, +-963, -137, -1173, -1250, -696, -1677, 60, -908, +959, 563, 1253, 1577, 655, 1622, -2, 675, +-886, -618, -1070, -1349, -599, -1212, 101, -292, +582, 541, 870, 793, 586, 482, -62, -30, +-613, -185, -812, 7, -337, 55, 175, 90, +525, -138, 469, -433, 63, -343, -125, -12, +-293, 474, -267, 684, -286, 197, -158, -355, +65, -709, 230, -343, 540, 300, 470, 802, +50, 593, -662, -172, -799, -922, -574, -1046, +216, -201, 756, 850, 754, 1406, 374, 814, +-325, -265, -646, -1237, -481, -1323, -9, -411, +412, 650, 303, 1282, -131, 940, -362, -140, +-38, -920, 303, -918, 485, -85, 210, 707, +-292, 843, -750, 174, -579, -776, -59, -1002, +662, -472, 965, 718, 252, 1505, -465, 892, +-1134, -159, -642, -1317, 232, -1522, 970, -547, +1006, 746, 58, 1332, -986, 1026, -1112, 54, +-372, -849, 621, -684, 1158, -119, 628, 279, +-336, 73, -909, -258, -736, -406, -11, 93, +724, 743, 988, 966, 226, 513, -754, -540, +-1100, -1452, -565, -1343, 579, -157, 1330, 1209, +789, 1898, -265, 1017, -985, -519, -1047, -1556, +-289, -1601, 365, -387, 732, 914, 607, 1550, +27, 1118, -310, -106, -413, -1030, -240, -1200, +14, -641, 14, 263, -60, 844, -76, 817, +66, 529, 199, -28, 413, -514, 90, -732, +-209, -721, -555, -264, -280, 460, 235, 1070, +432, 974, 347, 200, -246, -801, -478, -1381, +-398, -940, 250, 225, 797, 1329, 807, 1655, +87, 661, -1134, -905, -1528, -1994, -767, -1688, +788, 8, 1760, 1760, 1615, 2465, 146, 1362, +-1383, -734, -1917, -2507, -1330, -2432, 258, -782, +1421, 1501, 1643, 2765, 655, 2075, -524, 97, +-1186, -1945, -921, -2596, -156, -1520, 546, 521, +462, 2233, 117, 2310, -162, 752, -141, -1114, +334, -2241, 309, -1686, 72, -108, -387, 1415, +-621, 2058, -286, 1310, 172, -228, 707, -1604, +669, -1903, 54, -911, -748, 476, -1037, 1607, +-444, 1493, 696, 636, 1357, -422, 938, -1091, +-194, -1116, -1356, -594, -1695, 156, -1039, 613, +472, 848, 1753, 572, 2038, 161, 940, -202, +-706, -486, -1934, -357, -1993, -342, -1002, -196, +323, -54, 1656, -2, 1970, 496, 1389, 838, +39, 861, -1467, 201, -1807, -784, -1635, -1488, +-253, -1466, 1058, -410, 1727, 1148, 1704, 2195, +458, 2149, -786, 430, -1700, -1749, -1569, -2982, +-490, -2304, 804, 80, 1389, 2386, 1197, 3019, +286, 1884, -642, -465, -1029, -2372, -980, -2501, +-294, -1278, 337, 652, 767, 1805, 680, 1636, +62, 690, -240, -468, -332, -885, -144, -695, +-72, -215, -105, 200, -224, 41, -319, -201, +-41, -247, 374, 104, 717, 673, 859, 934, +372, 516, -591, -190, -1311, -1015, -1311, -1279, +-539, -843, 741, 299, 1702, 1138, 1530, 1329, +508, 766, -843, -214, -1730, -957, -1330, -1116, +-248, -577, 872, 138, 1252, 911, 664, 995, +-335, 206, -974, -629, -501, -919, 319, -416, +918, 338, 576, 935, -373, 887, -1248, 135, +-1295, -619, -208, -1102, 1056, -937, 1705, -164, +1150, 781, -290, 1117, -1512, 848, -1481, 182, +-351, -401, 851, -752, 1335, -557, 610, -338, +-597, -150, -1345, -2, -791, 266, 588, 541, +1686, 668, 1622, 661, -41, 268, -1899, -391, +-2509, -1037, -1283, -1253, 953, -845, 2641, 199, +2414, 1330, 583, 1570, -1707, 993, -2754, -48, +-1776, -1107, 168, -1375, 2004, -1026, 2248, -96, +930, 733, -872, 1081, -2180, 923, -1858, 193, +-156, -600, 1608, -997, 2194, -771, 1322, 196, +-383, 1017, -1858, 1191, -2144, 235, -1035, -1069, +535, -1513, 1829, -1118, 2024, 206, 918, 1704, +-462, 2130, -1525, 1316, -1562, -544, -809, -2275, +157, -2658, 944, -1325, 994, 921, 545, 2577, +83, 2673, -272, 1234, -330, -1127, -281, -2588, +-491, -2323, -468, -816, -341, 1350, 268, 2210, +801, 1661, 746, 208, 412, -1243, -407, -1582, +-805, -936, -801, 281, -198, 1000, 511, 857, +697, 204, 417, -337, -217, -381, -628, -139, +-398, 131, 259, -57, 568, -276, 641, -319, +-37, 42, -1026, 556, -961, 847, -310, 550, +943, -337, 1657, -1075, 799, -1004, -441, -521, +-1686, 492, -1856, 1268, -565, 1084, 938, 482, +2209, -520, 1993, -1149, 224, -1070, -1670, -464, +-2549, 524, -1730, 1105, 43, 1001, 1817, 311, +2289, -597, 1371, -1151, -124, -840, -1487, 118, +-1801, 860, -1201, 1105, -99, 508, 936, -440, +1376, -1108, 1077, -976, 275, -178, -470, 702, +-902, 1043, -782, 898, -532, 151, 75, -674, +565, -952, 767, -835, 611, -314, -29, 595, +-399, 872, -786, 730, -593, 298, 57, -282, +488, -446, 691, -560, 393, -452, -361, -118, +-564, 82, -492, 372, -381, 731, 306, 546, +457, 262, 408, -326, 344, -955, -187, -859, +-219, -411, -330, 371, -466, 1102, -335, 1002, +-190, 459, 318, -359, 933, -1070, 901, -1103, +475, -389, -327, 359, -1421, 978, -1515, 962, +-689, 385, 767, -363, 1919, -703, 1715, -601, +351, -159, -1238, 166, -1908, 79, -1411, 96, +-61, 30, 1266, 421, 1674, 766, 1015, 418, +-343, -272, -1345, -975, -1357, -1494, -485, -971, +636, 496, 1139, 1734, 778, 2338, -23, 1308, +-686, -898, -776, -2570, -375, -2850, 60, -1167, +386, 1337, 569, 2979, 397, 2819, 83, 1120, +-211, -1431, -459, -2991, -456, -2787, -437, -1097, +-80, 1234, 500, 2881, 919, 2863, 899, 1136, +-30, -964, -878, -2684, -1222, -2827, -797, -1271, +82, 747, 880, 2415, 1297, 2603, 789, 1514, +-139, -341, -1096, -2029, -1248, -2494, -622, -1709, +171, 18, 820, 1596, 954, 2324, 675, 1693, +62, 324, -717, -1037, -1011, -1800, -785, -1654, +-310, -735, 454, 453, 1111, 1249, 1299, 1485, +664, 1062, -683, 151, -1640, -768, -1613, -1170, +-449, -1052, 984, -542, 1835, 311, 1721, 685, +346, 750, -1393, 609, -2232, 198, -1442, -69, +421, -210, 1825, -415, 1799, -527, 558, -549, +-1012, -483, -1789, 15, -1240, 655, 201, 1046, +1541, 1219, 1685, 646, 358, -612, -1289, -1538, +-1854, -1816, -1032, -1073, 397, 503, 1740, 1727, +1701, 2072, 437, 1334, -1110, -229, -1908, -1405, +-998, -2099, 409, -1545, 1329, -164, 1163, 1101, +-28, 1848, -770, 1559, -932, 561, -304, -679, +749, -1383, 1137, -1384, 537, -851, -757, 151, +-1531, 873, -1180, 1229, 180, 940, 1384, 241, +1737, -427, 1041, -851, -499, -730, -1630, -360, +-1784, 30, -1011, 131, 536, 263, 1429, 368, +1491, 526, 861, 597, -236, 456, -1055, -275, +-1233, -1071, -794, -1329, -66, -897, 548, 187, +659, 1282, 664, 1718, 450, 1089, -50, -20, +-261, -1099, -408, -1506, -440, -959, -349, -89, +-481, 588, -185, 576, 387, 424, 926, 319, +1202, 446, 858, 568, -194, 229, -1533, -475, +-2113, -1403, -1490, -1540, 128, -901, 2183, 441, +2734, 1856, 1598, 2212, -372, 1378, -2436, -146, +-2849, -1695, -1460, -2107, 712, -1527, 2282, -425, +2229, 800, 745, 1383, -991, 1395, -1734, 1052, +-1155, 508, 255, -233, 1163, -988, 910, -1526, +-200, -1711, -1352, -970, -1244, 358, -7, 1679, +1378, 2297, 2037, 1800, 1406, 532, -291, -1104, +-2052, -2237, -2725, -2332, -1756, -1439, 233, 118, +2198, 1718, 3088, 2454, 2243, 2149, 194, 884, +-2079, -797, -3383, -2123, -2692, -2583, -528, -1613, +1815, -17, 3157, 1485, 2677, 2435, 743, 1936, +-1445, 803, -2792, -755, -2458, -1937, -672, -2030, +1198, -1222, 2146, 246, 1748, 1463, 414, 1819, +-851, 1211, -1387, -75, -1239, -1181, -224, -1537, +611, -800, 727, 477, 828, 1186, 332, 1181, +-51, 227, -366, -1047, -1081, -1542, -1057, -1113, +-367, 244, 650, 1783, 1700, 2155, 1798, 1361, +800, -503, -943, -2302, -2702, -2714, -2986, -1854, +-1155, 212, 1516, 2386, 3666, 3115, 3761, 2483, +1408, 463, -1813, -1850, -4326, -3123, -4469, -3007, +-1806, -1382, 2010, 795, 4619, 2568, 4602, 3268, +1904, 2377, -1693, 536, -4211, -1593, -4494, -3181, +-2252, -3205, 1153, -1808, 3696, 551, 4080, 2789, +2282, 3664, -496, 2739, -2756, 324, -3453, -2364, +-2450, -3813, -179, -3085, 1897, -566, 2766, 2171, +2263, 3609, 686, 2803, -932, 272, -1871, -2249, +-1970, -3239, -1395, -2181, -161, 440, 979, 2609, +1687, 2816, 1937, 1293, 1234, -1045, -88, -2635, +-1445, -2328, -2484, -797, -2319, 1091, -890, 2137, +1166, 1790, 2912, 837, 3281, -250, 1744, -983, +-832, -1213, -3142, -1326, -4037, -1193, -2507, -594, +414, 461, 3141, 1815, 4319, 2704, 2982, 2406, +141, 610, -2723, -2030, -4064, -3837, -3265, -3848, +-859, -1635, 1908, 1608, 3531, 4095, 3195, 4598, +1420, 2448, -834, -762, -2736, -3455, -3012, -4154, +-2018, -2721, -18, -223, 1953, 1917, 2634, 2803, +2053, 2337, 413, 1202, -1199, -202, -2093, -1083, +-1828, -1359, -494, -1565, 773, -1242, 1448, -637, +1026, 278, 165, 1359, -404, 1954, -457, 1741, +-90, 626, 63, -744, -85, -1864, -501, -2075, +-711, -1202, -267, 74, 799, 1423, 1541, 1858, +1340, 1354, 42, 217, -1763, -1047, -2504, -1585, +-1710, -1066, 482, 35, 2767, 1109, 3225, 1424, +1757, 714, -1072, -554, -3458, -1605, -3642, -1722, +-1765, -581, 1202, 1075, 3579, 2246, 3742, 2237, +1830, 887, -995, -1140, -3161, -2534, -3389, -2734, +-1892, -1468, 413, 577, 2096, 2119, 2471, 2704, +1731, 2018, 476, 682, -548, -864, -1187, -1979, +-1402, -2399, -1369, -2075, -1072, -1006, -178, 649, +873, 2403, 1808, 3381, 2301, 2804, 1525, 665, +-95, -2097, -1995, -3844, -3049, -3666, -2432, -1551, +-512, 1259, 1657, 3217, 2868, 3428, 2655, 1931, +1112, -150, -824, -1689, -2242, -2194, -2460, -1819, +-1609, -1050, -124, -218, 1164, 608, 1835, 1431, +1962, 1949, 1169, 1852, -27, 865, -1283, -863, +-2223, -2366, -2081, -2895, -953, -1828, 904, 375, +2425, 2371, 2566, 3060, 1368, 2099, -593, -20, +-2296, -1880, -2544, -2492, -1420, -1656, 281, -172, +1770, 931, 2049, 1231, 1043, 840, -100, 418, +-754, 307, -864, 306, -519, 67, -343, -741, +-449, -1571, -491, -1687, -187, -713, 509, 1051, +1399, 2349, 1921, 2343, 1164, 1053, -558, -819, +-2124, -2233, -2936, -2354, -2024, -1292, 156, 155, +2282, 1363, 3246, 1630, 2504, 1349, 453, 849, +-1686, 133, -2806, -503, -2484, -1301, -1143, -1760, +644, -1657, 1883, -594, 1857, 953, 1291, 2215, +432, 2586, -338, 1475, -768, -331, -1232, -1928, +-1364, -2624, -1012, -1984, -219, -357, 800, 1140, +1596, 1830, 1694, 1730, 887, 777, -264, 31, +-1253, -376, -1462, -825, -977, -1066, -129, -1129, +320, -900, 530, -183, 297, 713, 144, 1372, +670, 1627, 974, 1310, 978, 426, 96, -774, +-1553, -1796, -2499, -2381, -2174, -1882, -567, -433, +1771, 1470, 3405, 3079, 3315, 3262, 1291, 1746, +-1677, -834, -3713, -3185, -3733, -4025, -1859, -2773, +1046, 65, 3150, 2822, 3566, 4017, 2223, 2947, +-202, 518, -2269, -2014, -2925, -3008, -2030, -2234, +-374, -634, 996, 839, 1694, 1189, 1324, 839, +685, 312, 360, 354, -191, 954, -407, 998, +-849, 220, -1447, -1284, -1162, -2825, -496, -2730, +702, -804, 1935, 1911, 2165, 3860, 1316, 3687, +-434, 1242, -2117, -1923, -2617, -3988, -1547, -3685, +317, -1232, 1768, 1685, 2144, 3181, 1433, 2563, +-97, 711, -1290, -1103, -1605, -1774, -894, -1026, +379, -50, 961, 693, 911, 583, 62, -301, +-872, -865, -999, -751, -552, 244, 598, 1225, +1526, 1455, 1577, 846, 633, -443, -1051, -1343, +-2286, -1336, -2291, -817, -1045, 59, 1202, 607, +2785, 742, 2663, 622, 1262, 419, -1109, 321, +-2483, 131, -2382, -209, -1180, -431, 694, -794, +1604, -859, 1405, -536, 668, -90, -238, 563, +-422, 1045, -36, 1239, 98, 1141, -28, 308, +-646, -719, -1184, -1613, -878, -2082, 76, -1326, +1228, 3, 1714, 1379, 1157, 2345, 10, 2101, +-1030, 770, -1403, -737, -988, -1831, -128, -1874, +341, -1162, 442, -210, 381, 585, 162, 940, +295, 1008, 439, 875, 440, 640, 181, 350, +-459, -81, -1023, -764, -1165, -1393, -762, -1560, +198, -1186, 1026, -59, 1355, 1237, 1300, 2214, +516, 2191, -545, 1270, -1296, -180, -1559, -1775, +-943, -2610, 121, -2587, 795, -1419, 1202, 555, +948, 2535, 128, 3481, -345, 2725, -586, 649, +-283, -1891, 87, -3511, 35, -3212, -216, -1312, +-630, 1074, -472, 2627, 30, 2579, 692, 1217, +1081, -301, 914, -1187, 156, -1169, -737, -630, +-1063, -175, -918, -83, -279, -236, 353, -213, +573, 243, 368, 770, 90, 1076, 103, 822, +162, -14, 369, -712, 403, -1073, -79, -956, +-674, -265, -1104, 286, -959, 513, -377, 392, +415, 263, 1211, 203, 1566, 289, 1284, 413, +362, 98, -803, -306, -1696, -812, -2012, -1128, +-1435, -800, -192, 25, 1252, 920, 2333, 1491, +2299, 1190, 1209, 397, -456, -519, -2015, -1104, +-2488, -1123, -1854, -693, -393, -217, 1217, 151, +2026, 599, 1700, 767, 810, 851, -241, 842, +-919, 222, -911, -483, -846, -1100, -407, -1478, +-185, -1043, -110, -97, 293, 839, 568, 1685, +995, 1661, 1051, 764, 409, -423, -459, -1573, +-1303, -1841, -1510, -1070, -912, 114, 259, 1090, +1287, 1503, 1449, 1026, 865, 252, -201, -512, +-1149, -906, -1129, -945, -467, -573, 436, -7, +1159, 475, 898, 928, 37, 883, -949, 278, +-1436, -366, -847, -949, 256, -1014, 1273, -468, +1690, 335, 1088, 970, -36, 1107, -1235, 699, +-1807, -238, -1400, -1016, -419, -1186, 758, -780, +1410, 19, 1533, 805, 1039, 1118, -118, 935, +-878, 298, -1173, -367, -1087, -899, -461, -1056, +-87, -664, 355, -56, 804, 535, 819, 959, +779, 878, 545, 479, 23, -1, -641, -476, +-1318, -976, -1529, -1132, -773, -766, 431, 135, +1479, 1207, 1836, 1831, 1204, 1409, -27, -58, +-1339, -1605, -1832, -2330, -1192, -1616, -54, 224, +1170, 1948, 1429, 2439, 704, 1476, -184, -406, +-1013, -2012, -905, -2339, -84, -1158, 619, 684, +895, 1963, 434, 1772, -274, 498, -758, -875, +-885, -1396, -499, -871, 222, 185, 793, 796, +943, 537, 632, -107, 140, -709, -371, -462, +-804, 445, -930, 951, -813, 830, -209, -128, +574, -1137, 1099, -1348, 1235, -591, 896, 650, +-2, 1522, -982, 1364, -1572, 66, -1539, -1143, +-606, -1572, 695, -902, 1628, 484, 1852, 1398, +1109, 1352, -142, 392, -1373, -842, -1942, -1414, +-1466, -1048, -371, -21, 996, 874, 1749, 1112, +1537, 688, 656, 38, -537, -483, -1269, -701, +-1302, -450, -689, -90, 156, -46, 605, 28, +741, 25, 453, 282, 153, 682, 115, 711, +70, 354, -92, -414, -442, -1094, -779, -1250, +-680, -716, -214, 320, 563, 1287, 1113, 1439, +1043, 778, 451, -149, -558, -963, -1211, -1146, +-1033, -671, -337, -95, 476, 404, 942, 537, +729, 342, 130, 162, -477, 206, -628, 175, +-240, 145, 295, -113, 479, -558, 344, -726, +-117, -657, -584, -94, -643, 588, -331, 1021, +325, 912, 860, 257, 814, -352, 292, -843, +-346, -775, -710, -479, -724, -69, -435, 371, +59, 544, 546, 566, 642, 351, 377, 46, +14, -298, -255, -422, -287, -361, -212, -113, +-43, 89, 133, 111, 26, 17, -182, -21, +-147, -70, -62, 154, 200, 404, 406, 396, +287, 283, 164, -308, -95, -710, -439, -739, +-500, -461, -210, 174, 137, 538, 243, 774, +180, 667, 42, 245, 74, -87, 216, -396, +218, -614, 152, -695, -46, -658, -428, -290, +-701, 333, -634, 937, -154, 1206, 577, 950, +1088, 271, 1033, -630, 387, -1277, -613, -1471, +-1197, -1073, -1105, -175, -431, 848, 483, 1601, +1018, 1826, 900, 1186, 304, -79, -350, -1389, +-840, -2181, -607, -1976, 47, -715, 614, 846, +753, 2043, 239, 2212, -471, 1149, -975, -287, +-855, -1427, -182, -1658, 791, -959, 1381, -96, +1155, 445, 255, 474, -954, 314, -1440, 249, +-1224, 581, -424, 856, 653, 508, 1088, -303, +1048, -1327, 591, -1688, -155, -1060, -457, 259, +-628, 1522, -596, 1860, -252, 1056, -96, -251, +125, -1255, 306, -1291, 305, -512, 432, 334, +242, 657, -24, 352, -127, -219, -230, -432, +-42, -137, -160, 508, -462, 829, -476, 468, +-235, -215, 268, -882, 860, -1026, 1062, -463, +670, 311, -65, 851, -909, 852, -1268, 211, +-886, -413, -199, -615, 491, -320, 884, 219, +878, 540, 474, 402, -25, -100, -296, -601, +-363, -874, -361, -570, -361, 281, -365, 940, +-248, 1220, -55, 879, 259, -13, 625, -942, +784, -1442, 764, -1336, 282, -437, -462, 624, +-1082, 1414, -1328, 1546, -994, 795, -57, -113, +1057, -990, 1650, -1348, 1418, -964, 442, -283, +-717, 319, -1396, 686, -1310, 738, -557, 624, +259, 447, 778, 80, 720, -403, 278, -840, +34, -926, 88, -539, 199, 185, 92, 853, +-233, 897, -730, 499, -886, -227, -424, -637, +338, -470, 991, -35, 1075, 411, 436, 456, +-399, -42, -843, -650, -720, -828, -114, -328, +326, 621, 471, 1190, 234, 1023, -239, 204, +-317, -855, -238, -1280, 140, -1009, 479, -171, +442, 804, 180, 1077, -275, 742, -481, -15, +-416, -610, -223, -657, 51, -276, 238, 227, +318, 414, 307, 260, 260, -85, 131, -408, +-156, -339, -357, -140, -370, 148, -327, 427, +-58, 431, 237, 386, 339, 109, 353, -294, +82, -586, -196, -785, -228, -545, -79, 0, +133, 724, 224, 1145, 97, 858, -156, 183, +-396, -663, -487, -1102, -259, -865, 256, -256, +717, 425, 844, 753, 479, 554, -194, 77, +-724, -282, -961, -194, -681, 99, -67, 349, +422, 225, 713, -286, 673, -748, 368, -912, +66, -475, -201, 464, -275, 1209, -235, 1424, +-433, 882, -665, -244, -554, -1292, -92, -1756, +650, -1404, 1287, -193, 1262, 1150, 656, 1836, +-333, 1634, -1346, 540, -1798, -799, -1338, -1552, +-228, -1541, 978, -689, 1807, 472, 1716, 1123, +829, 1088, -361, 445, -1315, -300, -1576, -640, +-1102, -408, -235, 55, 623, 352, 1022, 178, +834, -270, 418, -604, -48, -445, -162, 109, +-57, 679, -157, 910, -246, 589, -561, -109, +-726, -753, -480, -1008, -20, -688, 833, 0, +1404, 549, 1266, 840, 456, 714, -703, 182, +-1582, -263, -1648, -612, -925, -609, 194, -267, +1254, 65, 1540, 338, 1156, 377, 317, 302, +-557, 31, -997, -233, -1053, -193, -621, -68, +-112, 72, 347, 168, 659, -125, 610, -243, +408, -240, 192, -100, -79, 371, -281, 574, +-325, 463, -423, 28, -361, -667, -213, -927, +17, -577, 391, 131, 610, 899, 579, 1128, +240, 655, -195, -277, -642, -1135, -694, -1300, +-317, -584, 185, 501, 637, 1299, 455, 1316, +-42, 425, -412, -778, -445, -1447, -5, -1168, +497, -85, 668, 1091, 378, 1492, -331, 828, +-922, -336, -925, -1315, -396, -1424, 457, -480, +1083, 743, 986, 1526, 406, 1294, -324, 83, +-778, -1055, -708, -1562, -445, -1042, -41, 143, +216, 1114, 268, 1422, 422, 781, 407, -191, +329, -955, 263, -1121, -159, -617, -604, 113, +-824, 659, -647, 801, -46, 476, 574, -65, +835, -438, 707, -539, 320, -220, -144, 143, +-468, 343, -697, 355, -601, -61, -303, -457, +37, -505, 484, -192, 769, 429, 725, 839, +287, 734, -273, 129, -733, -737, -850, -1204, +-491, -1031, 88, -99, 688, 984, 876, 1428, +476, 1144, -187, -2, -648, -1043, -672, -1365, +-242, -1032, 323, 44, 656, 904, 579, 1127, +-7, 753, -572, -55, -802, -623, -522, -769, +258, -569, 807, -80, 877, 386, 430, 589, +-302, 548, -819, 200, -859, -265, -385, -640, +251, -673, 669, -246, 683, 302, 294, 778, +-228, 793, -444, 229, -318, -390, 39, -853, +291, -769, 164, -220, -146, 404, -515, 778, +-413, 562, 128, 123, 586, -244, 876, -392, +560, -199, -219, -152, -889, -111, -1093, -85, +-593, -80, 272, 230, 933, 451, 1016, 493, +441, 221, -288, -289, -704, -682, -730, -628, +-283, -231, 341, 291, 568, 621, 398, 492, +8, 218, -415, -153, -431, -427, -193, -295, +116, -167, 422, -49, 492, 56, 394, 144, +31, 254, -535, 310, -813, 212, -654, -150, +-152, -512, 547, -533, 883, -210, 844, 389, +529, 788, -218, 548, -882, -61, -1140, -783, +-755, -874, 30, -311, 705, 504, 1032, 1042, +740, 819, 179, -90, -347, -995, -735, -1207, +-581, -571, -127, 560, 181, 1337, 276, 1210, +162, 276, -100, -932, -100, -1545, 87, -1199, +295, 26, 435, 1222, 159, 1553, -201, 1024, +-549, -239, -729, -1257, -414, -1364, 180, -772, +723, 286, 843, 1113, 413, 1074, -190, 444, +-537, -389, -455, -808, -152, -588, 87, -61, +102, 388, -89, 392, -214, 20, -61, -309, +359, -288, 723, 128, 595, 479, -14, 470, +-731, -58, -1003, -607, -663, -700, 61, -313, +756, 449, 929, 928, 451, 678, -172, -87, +-464, -853, -382, -1051, -54, -432, 105, 478, +21, 1063, -100, 932, -172, 228, -96, -583, +231, -1058, 511, -805, 386, -146, -107, 449, +-539, 679, -438, 547, -14, 269, 431, 32, +466, -46, -34, -233, -481, -533, -787, -737, +-328, -627, 617, -93, 1196, 763, 1107, 1346, +-4, 1196, -1127, 348, -1501, -791, -1126, -1565, +46, -1509, 1205, -671, 1556, 599, 1099, 1476, +-73, 1507, -1090, 807, -1189, -316, -677, -1102, +154, -1191, 630, -759, 537, 24, 226, 656, +-194, 765, -222, 509, -3, 80, 217, -300, +321, -377, 111, -230, -219, 10, -508, 200, +-548, 209, -248, 14, 207, -293, 563, -342, +682, -175, 428, 81, 60, 371, -253, 515, +-607, 345, -628, 76, -357, -300, -11, -526, +311, -543, 433, -402, 445, -61, 417, 300, +204, 637, -104, 769, -353, 489, -505, 29, +-484, -471, -435, -823, -162, -805, 366, -546, +784, 5, 894, 585, 595, 925, -4, 1016, +-601, 555, -1132, -133, -1125, -764, -361, -1259, +539, -1047, 1141, -370, 1056, 461, 430, 1152, +-215, 1237, -694, 702, -769, -124, -424, -789, +38, -952, 308, -729, 319, -212, 114, 223, +-36, 419, -3, 460, 107, 354, 326, 258, +312, 213, -67, 34, -538, -215, -761, -632, +-510, -820, 143, -507, 705, -19, 845, 669, +656, 1105, 14, 983, -654, 358, -865, -522, +-668, -1229, 7, -1274, 603, -609, 703, 352, +473, 1116, -51, 1269, -456, 716, -538, -206, +-304, -907, 208, -1074, 471, -599, 362, 151, +64, 556, -241, 647, -329, 373, -208, 31, +-39, -201, 89, -268, 130, -197, 151, -182, +163, -167, 173, -44, 148, 169, -77, 381, +-307, 487, -484, 233, -419, -288, -59, -691, +381, -717, 783, -184, 655, 549, 97, 951, +-424, 713, -706, -76, -514, -773, -101, -931, +187, -486, 293, 278, 263, 787, 72, 692, +117, 139, 292, -433, 241, -544, 41, -204, +-520, 274, -895, 377, -693, 58, -22, -350, +785, -550, 1165, -216, 930, 414, 122, 804, +-788, 708, -1233, 12, -891, -739, -62, -1030, +676, -683, 908, 58, 562, 744, -28, 920, +-382, 655, -376, 89, -167, -497, 148, -674, +122, -634, -65, -307, -204, 117, -217, 436, +55, 588, 283, 418, 384, 91, 263, -204, +-39, -371, -253, -301, -329, -175, -217, -61, +-44, 15, 32, 19, 82, 140, 152, 278, +203, 343, 181, 307, 99, -65, 19, -402, +-146, -604, -249, -464, -308, -46, -280, 341, +-29, 609, 249, 517, 522, 132, 502, -215, +216, -385, -267, -402, -647, -176, -522, -20, +-134, 71, 278, 189, 505, 200, 365, 260, +-26, 154, -248, -93, -228, -226, -87, -334, +181, -147, 258, 119, 54, 228, -218, 183, +-425, -68, -303, -252, 202, -201, 548, 46, +485, 366, 152, 466, -333, 189, -499, -335, +-371, -659, -50, -590, 292, -157, 325, 433, +193, 685, -37, 557, -103, 168, -8, -259, +41, -410, -58, -361, -252, -241, -252, -190, +-18, -124, 327, 54, 531, 421, 355, 771, +-127, 642, -525, 180, -679, -573, -386, -1145, +211, -1032, 693, -338, 836, 612, 353, 1251, +-326, 1186, -720, 410, -758, -530, -303, -1127, +225, -1044, 489, -346, 588, 412, 405, 818, +81, 680, -193, 176, -455, -318, -549, -459, +-328, -279, 10, 34, 371, 285, 570, 227, +391, -59, 72, -294, -271, -316, -425, -37, +-235, 290, 30, 419, 202, 305, 112, -104, +-122, -436, -184, -400, -2, -79, 293, 315, +459, 447, 293, 169, -180, -341, -638, -606, +-712, -363, -245, 199, 450, 797, 883, 880, +702, 274, -2, -559, -656, -1164, -850, -1014, +-432, -161, 267, 742, 665, 1171, 620, 886, +138, 84, -387, -648, -467, -836, -275, -497, +49, 57, 219, 320, 148, 201, 32, -112, +-58, -197, 117, 100, 213, 485, 76, 661, +-127, 316, -432, -342, -367, -918, 77, -975, +305, -449, 355, 315, 178, 867, -124, 917, +-186, 532, -68, 28, 163, -355, 205, -544, +-81, -568, -465, -544, -621, -352, -211, 3, +458, 486, 964, 957, 941, 967, 206, 500, +-706, -321, -1261, -1070, -995, -1226, -117, -771, +728, 58, 1027, 775, 668, 1050, 91, 801, +-328, 296, -376, -255, -263, -608, -141, -690, +-220, -544, -351, -214, -195, 145, 192, 446, +728, 561, 922, 467, 532, 133, -179, -196, +-864, -359, -1168, -400, -745, -209, 37, -54, +746, 74, 1108, 135, 737, 146, 134, 185, +-398, 159, -734, 120, -665, -21, -336, -153, +82, -277, 444, -236, 505, -108, 270, 72, +62, 200, -160, 219, -252, 170, -108, 70, +33, -49, 102, -154, -35, -170, -280, -214, +-253, -81, 27, 104, 373, 228, 576, 332, +407, 113, -29, -180, -594, -409, -819, -412, +-432, -32, 243, 438, 751, 651, 689, 424, +237, -164, -310, -730, -593, -799, -459, -367, +-77, 374, 360, 845, 458, 763, 146, 199, +-164, -436, -225, -677, -104, -483, 106, 9, +168, 293, 8, 247, -181, 16, -205, -189, +-1, -25, 345, 276, 463, 459, 109, 283, +-382, -257, -602, -706, -356, -726, 129, -294, +524, 390, 645, 802, 269, 709, -215, 252, +-463, -331, -513, -589, -156, -459, 211, -138, +281, 102, 180, 115, 26, 46, -28, 25, +54, 198, 214, 384, 177, 357, -211, 67, +-602, -410, -646, -718, -220, -629, 568, -157, +1011, 448, 807, 814, 148, 697, -683, 273, +-1133, -305, -906, -656, -98, -670, 697, -404, +993, 39, 708, 424, 70, 575, -437, 479, +-595, 213, -430, -147, -165, -439, 9, -544, +87, -435, 118, -86, 261, 327, 494, 620, +454, 589, 50, 197, -495, -310, -842, -638, +-762, -587, -187, -238, 565, 247, 958, 551, +866, 547, 251, 275, -543, -76, -937, -408, +-754, -530, -228, -383, 327, -71, 604, 265, +448, 508, 208, 480, 5, 214, -130, -168, +-215, -433, -329, -492, -316, -299, -206, 70, +48, 346, 332, 367, 478, 225, 428, 9, +94, -137, -377, -143, -575, -77, -414, -61, +-50, -125, 309, -129, 425, -88, 327, 98, +19, 319, -242, 380, -324, 208, -154, -123, +162, -382, 144, -420, 35, -298, -13, 23, +-25, 251, 53, 374, 7, 347, -48, 138, +-95, -71, -82, -258, 10, -323, 160, -232, +325, -117, 192, 34, -189, 198, -439, 306, +-360, 303, 2, 167, 356, -57, 429, -314, +271, -425, -47, -311, -303, -19, -334, 301, +-121, 417, 220, 328, 284, 39, 64, -258, +-195, -278, -262, -190, -56, -46, 302, 95, +508, 125, 292, 63, -177, 78, -562, 54, +-640, -19, -248, -59, 380, -88, 736, -76, +713, -3, 186, 49, -451, 100, -732, 44, +-599, 5, -83, -22, 433, -129, 637, -110, +511, -12, 104, 100, -383, 207, -565, 217, +-399, 45, -9, -195, 422, -354, 504, -321, +288, -85, -72, 288, -442, 519, -465, 359, +-141, -9, 295, -341, 524, -439, 367, -229, +-43, 89, -469, 213, -584, 144, -335, 23, +194, -86, 735, 24, 773, 198, 265, 256, +-507, 52, -953, -273, -813, -551, -187, -466, +604, -70, 1054, 414, 877, 759, 134, 613, +-692, 151, -1050, -405, -711, -769, -67, -697, +476, -262, 700, 214, 507, 569, 80, 668, +-258, 432, -351, 109, -164, -217, 32, -532, +-87, -646, -216, -567, -239, -210, -52, 408, +302, 940, 491, 977, 485, 462, 179, -384, +-339, -1081, -694, -1147, -687, -562, -318, 306, +203, 1018, 523, 1090, 601, 592, 394, -147, +75, -775, -265, -892, -494, -603, -493, -95, +-364, 460, -72, 696, 240, 620, 482, 268, +562, -197, 288, -540, -161, -559, -494, -315, +-644, 6, -362, 343, 147, 405, 531, 344, +599, 106, 165, -116, -337, -285, -606, -349, +-423, -193, 86, -22, 505, 143, 605, 270, +278, 333, -204, 237, -645, 1, -667, -337, +-273, -608, 259, -483, 682, 17, 692, 568, +361, 865, -163, 606, -644, -131, -704, -799, +-380, -1057, 108, -571, 554, 292, 584, 915, +321, 994, -38, 367, -372, -374, -335, -762, +-121, -613, 98, -141, 228, 302, 86, 362, +-115, 112, -200, -83, -77, -67, 253, 153, +447, 334, 337, 225, 17, -210, -442, -592, +-621, -587, -364, -179, 87, 434, 552, 766, +715, 581, 424, 20, -102, -525, -571, -658, +-583, -377, -205, 165, 261, 577, 458, 498, +259, 42, -39, -451, -188, -622, -62, -260, +113, 334, 164, 732, 121, 561, -69, -12, +-298, -541, -284, -712, -78, -416, 291, 57, +578, 402, 393, 491, -19, 370, -412, 127, +-619, -133, -387, -294, 138, -372, 558, -264, +676, -52, 339, 150, -249, 324, -633, 281, +-646, 40, -205, -205, 362, -232, 696, -32, +632, 253, 155, 336, -452, 83, -775, -343, +-630, -650, -173, -530, 456, 4, 821, 651, +728, 1031, 266, 802, -434, 25, -901, -835, +-886, -1268, -348, -1081, 365, -227, 890, 832, +868, 1433, 340, 1268, -269, 364, -713, -775, +-700, -1421, -408, -1204, 6, -274, 313, 698, +380, 1060, 377, 752, 248, 26, 86, -401, +-92, -320, -330, -69, -568, -3, -582, -257, +-270, -423, 233, -254, 673, 291, 789, 817, +471, 774, -152, 202, -676, -581, -953, -998, +-738, -772, -73, -52, 604, 654, 960, 921, +745, 633, 69, 7, -593, -583, -878, -811, +-627, -563, -34, -8, 405, 548, 519, 705, +308, 477, -15, -6, -177, -441, -205, -544, +-112, -359, -94, -38, -149, 244, -121, 307, +41, 256, 270, 207, 348, 39, 135, -115, +-157, -293, -360, -415, -351, -216, -83, 54, +186, 346, 381, 451, 296, 260, -56, -70, +-358, -330, -338, -385, -58, -183, 300, 143, +428, 264, 214, 210, -142, 6, -458, -168, +-478, -160, -129, -87, 363, 18, 663, 105, +590, 153, 110, 227, -486, 167, -746, -112, +-533, -459, 21, -607, 437, -299, 537, 353, +482, 868, 289, 811, 40, 219, -294, -498, +-683, -933, -619, -805, -154, -297, 416, 322, +810, 747, 654, 831, 212, 570, -319, -35, +-609, -651, -465, -915, -24, -732, 349, -116, +376, 630, 114, 923, -191, 617, -209, -5, +90, -553, 394, -617, 394, -269, 58, 99, +-375, 273, -527, 206, -346, 149, -11, 51, +352, -158, 594, -283, 584, -167, 227, 212, +-277, 491, -707, 321, -608, -260, -85, -717, +291, -521, 480, 78, 426, 648, 217, 772, +-8, 310, -323, -324, -454, -738, -204, -680, +105, -164, 330, 457, 237, 740, 5, 503, +-118, -56, -154, -478, -43, -480, 66, -216, +107, 90, 123, 195, -48, 170, -266, 164, +-204, 79, -10, -7, 299, -93, 403, -76, +22, -20, -394, -75, -519, -198, -168, -209, +346, 60, 534, 446, 253, 513, -158, 150, +-463, -373, -539, -597, -222, -365, 235, 116, +580, 491, 458, 387, -36, 32, -470, -329, +-531, -380, -237, -39, 92, 332, 313, 429, +317, 144, 112, -285, -191, -550, -406, -386, +-249, -1, 95, 390, 325, 606, 245, 414, +-97, 17, -386, -413, -425, -598, -151, -389, +224, -10, 520, 327, 474, 431, 2, 274, +-503, 85, -749, -111, -473, -234, 120, -267, +618, -155, 696, 46, 252, 157, -261, 146, +-567, -4, -540, -54, -171, 3, 211, 115, +383, 126, 355, -16, 54, -156, -295, -226, +-365, -161, -139, 9, 236, 191, 425, 291, +196, 204, -247, 2, -563, -232, -511, -362, +28, -230, 615, 75, 773, 395, 471, 454, +-219, 171, -758, -339, -772, -721, -431, -554, +211, 91, 774, 845, 840, 1029, 450, 473, +-221, -500, -690, -1246, -678, -1139, -359, -260, +183, 782, 578, 1327, 660, 1074, 327, 110, +-285, -824, -563, -1186, -345, -787, 136, 5, +415, 617, 254, 798, -69, 468, -261, -65, +-174, -355, 71, -336, 312, -63, 414, 191, +130, 86, -309, -195, -484, -369, -368, -194, +137, 210, 659, 501, 593, 542, 213, 209, +-305, -287, -621, -643, -479, -623, -54, -172, +383, 353, 661, 641, 561, 422, 62, 27, +-472, -304, -723, -394, -382, -217, 190, 10, +571, 211, 606, 232, 227, 142, -216, -67, +-512, -151, -506, -178, -115, -138, 410, 31, +652, 117, 324, 191, -211, 159, -477, 135, +-328, 45, 9, -195, 151, -420, 153, -444, +137, -160, 94, 368, 100, 724, -17, 609, +-114, 116, -195, -495, -242, -777, -173, -646, +107, -46, 313, 563, 315, 751, 121, 414, +-232, -129, -313, -494, -145, -501, 68, -70, +154, 271, -9, 375, -190, 129, -136, -259, +-14, -388, 131, -165, 242, 258, 240, 444, +150, 273, -221, -85, -611, -355, -551, -411, +-133, -179, 430, 197, 584, 404, 344, 305, +-8, -55, -298, -388, -385, -345, -178, 67, +42, 441, 31, 430, -175, -12, -289, -500, +-74, -628, 423, -229, 669, 378, 388, 740, +-213, 556, -701, -24, -747, -575, -448, -728, +117, -390, 603, 180, 691, 625, 374, 600, +-122, 174, -546, -287, -517, -522, -158, -432, +211, -48, 295, 314, 15, 538, -235, 319, +-229, -171, 53, -527, 289, -450, 263, 77, +198, 509, -40, 428, -294, -68, -519, -404, +-441, -363, -18, 39, 511, 387, 606, 363, +327, 55, -104, -363, -425, -472, -322, -278, +-101, 141, 85, 521, 166, 514, -34, 265, +-103, -253, 107, -637, 217, -555, 272, -152, +30, 391, -202, 584, -248, 339, -306, -84, +-100, -363, 307, -259, 469, -38, 327, 223, +-87, 311, -368, 53, -330, -372, -149, -595, +41, -363, 395, 294, 567, 895, 342, 919, +-336, 233, -737, -645, -435, -1084, 209, -872, +523, -192, 357, 511, 154, 940, -43, 820, +-187, 397, -204, -245, -119, -785, 71, -827, +156, -370, 16, 227, -17, 516, 93, 474, +39, 106, -33, -163, 74, -165, 114, -81, +118, 110, -63, 232, -165, 135, -176, -207, +-181, -513, -83, -560, 208, -96, 551, 523, +572, 858, -54, 652, -574, -23, -533, -600, +-202, -760, 24, -551, 217, -26, 413, 447, +464, 555, 154, 379, -322, -89, -530, -415, +-247, -279, 96, 262, 229, 562, 245, 236, +111, -515, -79, -1009, -322, -647, -240, 367, +134, 1180, 341, 1096, 251, 204, 77, -749, +-231, -1111, -387, -658, -392, 156, -87, 721, +365, 674, 518, 178, 145, -376, -177, -580, +-138, -328, -26, 248, -216, 688, -334, 585, +-120, -57, 244, -816, 368, -954, 144, -305, +-78, 650, -70, 1041, -155, 614, -261, -359, +-115, -836, 187, -485, 314, 197, -25, 682, +-314, 428, -285, -362, -67, -890, 278, -628, +386, 311, 243, 1090, -47, 1077, -458, 190, +-501, -893, -285, -1291, 111, -652, 304, 330, +422, 944, 370, 832, 84, 69, -392, -623, +-507, -699, -223, -52, 112, 647, 149, 694, +-59, -25, -25, -820, 196, -1012, 253, -281, +138, 733, -6, 1213, -171, 871, -373, -164, +-401, -1121, -81, -1291, 389, -406, 432, 800, +87, 1351, -249, 722, -181, -580, 109, -1291, +176, -910, 121, 413, -28, 1422, -246, 1243, +-515, -66, -341, -1446, 160, -1769, 712, -555, +685, 1135, 254, 1934, -315, 1248, -547, -449, +-583, -1657, -298, -1557, 214, -266, 444, 1128, +446, 1539, 103, 600, -214, -677, -130, -1318, +62, -812, 187, 366, 119, 1179, -198, 1059, +-498, 95, -429, -972, 27, -1356, 612, -718, +682, 541, 291, 1384, -149, 1146, -388, 10, +-321, -990, -251, -1126, -34, -411, 108, 508, +177, 897, 51, 490, 19, -282, 204, -746, +369, -546, 179, 204, -110, 792, -434, 676, +-518, -7, -271, -634, 134, -796, 430, -349, +501, 334, 253, 676, -113, 359, -281, -104, +-221, -390, 16, -193, 146, 302, 100, 495, +-183, 180, -376, -467, -217, -909, 179, -826, +534, -14, 501, 1079, 297, 1653, -51, 1048, +-489, -413, -694, -1689, -613, -1906, -55, -831, +569, 755, 695, 1856, 398, 1694, 126, 479, +-172, -1001, -275, -1718, -399, -1118, -335, 169, +-96, 1076, 73, 1077, 186, 275, 243, -561, +276, -810, 131, -383, -43, 394, -135, 718, +-115, 432, -155, -307, -278, -839, -177, -544, +96, 246, 328, 811, 233, 726, 62, 1, +-32, -809, -138, -1017, -165, -335, -87, 750, +169, 1333, 256, 845, -120, -364, -532, -1491, +-418, -1482, 100, -234, 651, 1165, 552, 1708, +147, 965, -177, -456, -362, -1483, -419, -1232, +-381, -113, -150, 857, 134, 1007, 412, 342, +439, -457, 345, -728, 84, -240, -293, 480, +-433, 699, -368, 257, -200, -492, -53, -1004, +144, -691, 403, 282, 539, 1058, 208, 1192, +-227, 446, -400, -736, -374, -1414, -109, -1072, +89, 39, 143, 1128, 213, 1353, 65, 528, +-167, -565, -95, -1210, 179, -761, 313, 204, +88, 801, -296, 696, -443, -54, -228, -627, +71, -492, 296, 80, 316, 453, 230, 506, +131, 110, -200, -340, -486, -681, -376, -567, +21, 34, 498, 720, 520, 1165, 27, 622, +-468, -468, -522, -1359, -87, -1302, 318, -325, +409, 1005, 351, 1644, 72, 1045, -258, -203, +-415, -1252, -419, -1325, -148, -509, 271, 551, +414, 959, 283, 647, 196, -69, 76, -484, +-120, -277, -408, 126, -514, 429, -317, 125, +148, -534, 580, -745, 500, -356, 207, 392, +-69, 963, -302, 929, -349, 210, -209, -697, +-4, -1214, 171, -843, 79, 87, -24, 931, +86, 1059, 234, 329, 336, -462, 96, -694, +-407, -389, -618, 5, -348, 270, 181, 280, +629, 145, 611, 21, 84, -71, -436, -222, +-654, -173, -373, -74, 252, 94, 646, 221, +631, 385, -90, 219, -736, -206, -703, -597, +-92, -561, 688, -66, 775, 572, 127, 878, +-545, 315, -694, -490, -255, -881, 472, -526, +771, 403, 495, 1125, -343, 757, -1097, -493, +-957, -1564, 25, -1302, 1201, 169, 1489, 1932, +620, 2279, -857, 805, -1641, -1566, -1211, -3050, +8, -2222, 1221, 383, 1463, 2852, 611, 3181, +-452, 1121, -1098, -1641, -1017, -3032, -54, -2121, +753, 125, 903, 2032, 305, 2249, -593, 909, +-937, -994, -291, -1983, 585, -1192, 868, 492, +448, 1605, -378, 1276, -587, -261, -536, -1435, +-248, -1334, 91, -71, 326, 1276, 675, 1259, +493, 391, 45, -829, -441, -1150, -587, -348, +-454, 655, -272, 805, 89, 99, 602, -797, +777, -1001, 506, -89, -92, 1338, -776, 1764, +-894, 557, -627, -1422, 209, -2638, 953, -1705, +1139, 933, 500, 2919, -680, 2630, -1310, 349, +-978, -2230, 67, -3105, 1115, -1613, 1384, 1010, +498, 2845, -637, 2368, -1407, 1, -1124, -2128, +84, -2491, 1206, -609, 1316, 1739, 370, 2327, +-751, 748, -1122, -1377, -583, -2545, 250, -1256, +880, 1257, 666, 2806, -52, 2162, -739, -396, +-782, -2841, -20, -3168, 789, -1036, 990, 1983, +199, 3615, -802, 2511, -1191, -508, -636, -3013, +555, -3130, 1327, -933, 1060, 1810, -169, 2765, +-1226, 1544, -1311, -627, -290, -2023, 868, -1511, +1377, 24, 731, 1529, -378, 1625, -1178, 143, +-1221, -1375, -38, -1889, 942, -791, 1235, 992, +481, 2192, -711, 1664, -1043, -126, -472, -1731, +379, -2162, 824, -996, 444, 850, -297, 1869, +-700, 1363, -659, -108, 93, -1120, 996, -1023, +977, -28, 128, 752, -895, 691, -1297, -253, +-555, -890, 551, -712, 1154, 106, 920, 942, +3, 1071, -766, 315, -1033, -629, -342, -1130, +508, -667, 856, 343, 469, 863, -411, 784, +-779, -220, -634, -916, 199, -881, 968, -47, +901, 1026, 190, 1473, -788, 767, -1357, -728, +-806, -1853, 415, -1744, 1254, -186, 1277, 1517, +399, 2104, -786, 1156, -1393, -610, -1093, -1622, +132, -1547, 1112, -241, 1279, 1051, 530, 1394, +-603, 524, -1134, -640, -713, -1194, -8, -708, +609, 254, 754, 1022, 354, 1005, -163, 104, +-476, -452, -292, -835, -77, -508, 144, -7, +175, 166, -108, 6, -286, -33, 62, 316, +380, 792, 621, 804, 333, 159, -442, -722, +-997, -1556, -907, -1328, 36, -169, 846, 1079, +1165, 1840, 750, 1299, -387, 67, -1053, -1159, +-845, -1396, -63, -806, 497, 115, 554, 740, +65, 650, -316, 112, -173, -476, 300, -259, +500, 478, 239, 864, -346, 512, -905, -400, +-617, -1375, 111, -1286, 885, -458, 917, 783, +155, 1514, -562, 1299, -836, 456, -316, -620, +456, -1033, 682, -885, 339, -465, -404, -250, +-1076, -19, -623, 411, 464, 929, 1317, 1415, +1415, 989, 83, -117, -1334, -1669, -1902, -2396, +-1083, -1479, 500, 353, 1795, 2214, 1918, 2593, +740, 1353, -1092, -737, -1944, -2187, -1545, -2125, +-111, -801, 1539, 909, 1659, 1741, 753, 1212, +-584, 90, -1376, -791, -1019, -915, -17, -271, +799, 276, 971, 388, 467, 64, -259, -283, +-709, -152, -800, 308, -154, 417, 323, 62, +466, -531, 651, -823, 205, -79, -16, 729, +-332, 1155, -626, 786, -635, -526, -409, -1589, +270, -1643, 995, -441, 1115, 1379, 582, 2312, +-530, 1584, -1394, -216, -1210, -2000, -358, -2309, +648, -1126, 1306, 643, 1121, 2017, 365, 2001, +-740, 723, -1418, -928, -1047, -1772, 19, -1365, +1144, -250, 1184, 921, 476, 1183, -469, 641, +-1064, -65, -796, -585, -146, -453, 692, -172, +1001, 69, 477, 201, -124, 7, -748, 5, +-808, 9, -485, -72, 157, -6, 910, 80, +921, 229, 386, 211, -422, 109, -1041, -242, +-863, -659, -342, -621, 530, -125, 1288, 680, +1162, 1230, 71, 909, -1056, -136, -1547, -1285, +-896, -1621, 307, -877, 1089, 549, 1401, 1800, +837, 1850, -126, 670, -1109, -1103, -1383, -2266, +-918, -1861, 24, -201, 876, 1740, 1250, 2464, +1083, 1573, 364, -474, -566, -2065, -1333, -2082, +-1290, -997, -634, 746, 344, 1595, 1304, 1406, +1496, 615, 1030, -240, -253, -691, -1442, -797, +-1735, -687, -1029, -613, 339, -371, 1370, 209, +1766, 1106, 1085, 1721, -279, 1335, -1400, -5, +-1582, -1655, -878, -2538, 132, -1877, 825, 46, +1085, 1883, 1090, 2725, 640, 2001, -103, 56, +-1006, -1706, -1412, -2399, -1288, -1773, -657, -248, +704, 1126, 1985, 1644, 2245, 1282, 1078, 451, +-925, -157, -2529, -664, -2453, -793, -911, -819, +1129, -722, 2495, -151, 2358, 550, 487, 1101, +-1586, 1115, -2361, 498, -1396, -533, 501, -1104, +1679, -907, 1667, -225, 255, 519, -1080, 719, +-1526, 301, -1051, -205, 392, -475, 1438, -408, +1426, 255, 516, 659, -595, 792, -1323, 308, +-1154, -676, -395, -1241, 362, -1136, 818, -303, +714, 844, 669, 1598, 324, 1326, -120, 360, +-740, -796, -1171, -1536, -822, -1360, 105, -380, +949, 756, 1112, 1351, 631, 1027, -369, 5, +-934, -874, -823, -1053, -2, -238, 967, 766, +1042, 1103, 113, 588, -1096, -665, -1672, -1565, +-889, -1482, 771, -134, 2052, 1434, 2098, 2188, +481, 1525, -1477, -25, -2511, -1706, -1965, -2294, +-18, -1608, 1804, -31, 2356, 1595, 1325, 2105, +-588, 1523, -1854, -118, -1583, -1241, -290, -1492, +1217, -973, 1450, 88, 664, 683, -743, 909, +-1668, 502, -1203, -211, 32, -499, 1630, -512, +2091, 7, 1192, 629, -629, 636, -2329, 187, +-2380, -572, -957, -1102, 1101, -815, 2554, 80, +2263, 1161, 523, 1359, -1507, 739, -2519, -531, +-1724, -1460, 310, -1330, 2058, -153, 2300, 1213, +541, 1614, -1654, 684, -2567, -1060, -1544, -2012, +1026, -1335, 2927, 703, 2526, 2369, 317, 2431, +-2283, 674, -3215, -1987, -1985, -3327, 611, -2587, +2690, -40, 2809, 2795, 1172, 3926, -1210, 2621, +-2372, -460, -1711, -3220, 58, -4052, 1183, -2321, +1089, 767, 257, 3265, -644, 3566, -535, 1793, +188, -879, 842, -2697, 774, -2838, -173, -1362, +-1263, 756, -1455, 2080, -424, 2171, 1019, 983, +1744, -569, 1238, -1646, -42, -1662, -1362, -708, +-1591, 494, -839, 1418, 352, 1403, 1305, 518, +1165, -740, 451, -1370, -169, -1185, -723, -162, +-765, 944, -615, 1357, -479, 883, 46, -245, +722, -968, 1270, -1149, 1262, -445, 499, 385, +-933, 796, -2130, 614, -2079, 211, -617, -189, +1600, -277, 2727, -222, 2223, -306, 213, -303, +-1913, -201, -2681, 213, -1937, 644, 172, 835, +2105, 322, 2399, -419, 1057, -1036, -836, -1086, +-1976, -223, -1483, 565, -75, 1394, 1311, 1144, +1589, 177, 586, -810, -786, -1548, -1778, -1163, +-1180, -116, 418, 979, 1593, 1506, 1730, 1195, +507, 135, -1010, -880, -1859, -1520, -1344, -1288, +-103, -333, 1142, 828, 1691, 1471, 1079, 1424, +35, 456, -1097, -680, -1524, -1249, -869, -1440, +-48, -663, 876, 175, 1259, 919, 840, 1495, +249, 1161, -667, 398, -1261, -636, -994, -1607, +-284, -1726, 663, -779, 1222, 396, 950, 1665, +339, 1968, -678, 1070, -1338, -167, -931, -1453, +-120, -1901, 898, -1303, 1310, -130, 564, 1034, +-287, 1759, -1020, 1393, -984, 349, -234, -704, +728, -1362, 1022, -1135, 503, -393, -310, 182, +-887, 622, -658, 746, -108, 611, 541, 568, +739, 39, 364, -657, -86, -968, -663, -982, +-595, -320, -147, 600, 327, 1156, 625, 1012, +368, 612, 36, -490, -368, -1255, -587, -1131, +-427, -644, -95, 514, 309, 1177, 831, 1022, +855, 546, 219, -130, -693, -746, -1385, -918, +-1106, -990, -46, -624, 1125, 365, 1678, 1332, +1184, 1840, -75, 1264, -1452, -285, -1945, -1972, +-1200, -2652, 552, -1636, 1853, 450, 1802, 2469, +548, 3052, -892, 1830, -1709, -584, -1289, -2681, +-64, -3138, 1104, -1678, 1521, 639, 726, 2574, +-531, 2555, -1358, 1174, -895, -532, 201, -1695, +847, -1398, 843, -839, 196, -4, -560, 390, +-761, 365, -318, 672, 390, 819, 843, 784, +373, 383, -485, -657, -933, -1600, -578, -1588, +497, -593, 1149, 788, 953, 1857, -56, 1671, +-1234, 437, -1650, -663, -508, -1314, 955, -1166, +1964, -450, 1447, 47, -309, 420, -1676, 501, +-2160, 664, -939, 714, 835, 678, 2259, 143, +2239, -895, 464, -1610, -1435, -1753, -2591, -559, +-1938, 1231, -146, 2415, 1627, 2262, 2540, 702, +1805, -1381, 64, -2534, -1524, -2407, -2352, -847, +-1722, 1175, -110, 2304, 1254, 2245, 2056, 904, +1540, -772, 201, -1722, -1038, -1730, -1602, -931, +-1193, 212, -96, 879, 727, 1173, 1096, 998, +622, 251, -188, -218, -507, -599, -491, -705, +131, -475, 519, -268, 265, -145, -251, 107, +-792, 577, -717, 754, 9, 815, 858, 424, +1179, -357, 665, -1109, -320, -1374, -1070, -872, +-1174, 121, -564, 1220, 319, 1666, 921, 1075, +978, -7, 600, -958, 76, -1437, -484, -1042, +-873, -190, -1105, 444, -952, 804, 17, 759, +1414, 461, 2156, 276, 1660, -38, -109, -463, +-2206, -715, -3061, -840, -2057, -404, 323, 179, +2859, 594, 3753, 758, 2154, 619, -797, 330, +-3319, 63, -3693, -260, -1557, -729, 1170, -958, +2908, -1011, 2747, -473, 824, 651, -1124, 1569, +-1888, 1918, -1363, 1245, -30, -386, 722, -1897, +523, -2546, -80, -1769, -395, -60, -172, 1728, +313, 2515, 893, 1973, 927, 743, 338, -801, +-687, -1884, -1428, -2042, -1472, -1680, -827, -645, +476, 746, 1454, 2148, 2094, 2750, 1790, 2070, +294, 312, -1453, -2033, -2968, -3402, -2803, -3093, +-925, -1156, 1575, 1350, 3676, 3365, 3561, 3766, +1218, 2072, -1866, -625, -4074, -2964, -3674, -3824, +-1075, -2518, 2112, -11, 3918, 2217, 3233, 3104, +748, 2344, -2020, 675, -3324, -1060, -2593, -2093, +-476, -1973, 1719, -1123, 2529, 16, 1882, 1089, +376, 1666, -1144, 1374, -1615, 495, -1269, -598, +-616, -1446, 282, -1467, 780, -466, 1134, 823, +1303, 1605, 567, 1367, -359, -50, -1420, -1493, +-2000, -2189, -1277, -1419, 207, 644, 1873, 2539, +2779, 3150, 1880, 1729, -257, -1226, -2475, -3566, +-3507, -3932, -2212, -1977, 331, 1275, 2793, 3743, +3983, 4281, 2644, 2449, -155, -575, -2854, -3077, +-4211, -4117, -3072, -2909, -385, -582, 2445, 1741, +4180, 3111, 3577, 3150, 1277, 2006, -1719, 134, +-3871, -1674, -3919, -3131, -2277, -3331, 696, -2064, +3232, 275, 4022, 2913, 3142, 4291, 402, 3411, +-2377, 667, -3787, -2642, -3573, -4566, -1390, -3817, +1358, -1016, 3182, 2275, 3505, 4241, 2034, 3552, +-350, 890, -2160, -2034, -2933, -3642, -2431, -2988, +-805, -561, 909, 2058, 2315, 3222, 2704, 2484, +1873, 151, 187, -2219, -1758, -2962, -2931, -2120, +-2810, -17, -1024, 1939, 1329, 2734, 3180, 2181, +3441, 534, 1648, -1180, -1069, -2368, -3349, -2524, +-3795, -1524, -1942, 37, 794, 1723, 3083, 2641, +3742, 2439, 2219, 1241, -212, -526, -2607, -2097, +-3423, -2847, -2267, -2420, -299, -1019, 1650, 757, +2477, 2440, 2055, 3179, 1061, 2511, -224, 975, +-1366, -1263, -1759, -3042, -1783, -3571, -1081, -2521, +125, -332, 1344, 2022, 2341, 3619, 2024, 3602, +802, 1887, -986, -569, -2343, -2787, -2443, -3763, +-1277, -2918, 604, -887, 2148, 1427, 2246, 3124, +1150, 3300, -381, 1855, -1573, -267, -1480, -2196, +-830, -2940, 142, -2065, 765, -331, 768, 1422, +488, 2326, 159, 1640, 153, 199, -93, -1189, +-594, -1776, -1052, -931, -929, 325, 58, 1349, +1242, 1660, 1958, 645, 1464, -826, -262, -1872, +-2101, -1842, -2803, -694, -1824, 898, 583, 2017, +2688, 1871, 3134, 1007, 1836, -191, -409, -1186, +-2358, -1427, -2737, -1466, -1921, -1152, -434, -516, +1154, 376, 1849, 1659, 1953, 2675, 1527, 2629, +720, 1109, -455, -1382, -1786, -3701, -2772, -4402, +-2639, -2748, -1057, 592, 1476, 3893, 3658, 5315, +4083, 4012, 2224, 384, -1150, -3303, -3798, -5117, +-4487, -4213, -2788, -1129, 688, 2001, 3344, 3674, +3880, 3329, 2367, 1661, -283, -270, -2143, -1674, +-2310, -2053, -1395, -1693, -187, -1005, 454, -182, +495, 421, 412, 1093, 480, 1725, 1013, 1700, +1349, 1039, 571, -260, -763, -1815, -2273, -2477, +-2771, -1982, -1269, -673, 1060, 1191, 3219, 2416, +3549, 2610, 1489, 1728, -1419, -168, -3558, -2096, +-3416, -3084, -1293, -2502, 1355, -550, 3082, 1709, +2714, 2952, 1053, 2621, -955, 889, -2004, -1011, +-1483, -2195, -610, -2080, 40, -984, 264, 121, +104, 856, 404, 920, 1006, 945, 1388, 917, +1117, 810, -71, 334, -1662, -724, -2666, -1753, +-2210, -2142, -263, -1455, 1901, 112, 3047, 1989, +2593, 2940, 713, 2349, -1370, 584, -2453, -1634, +-2323, -2822, -1261, -2633, 300, -1218, 1373, 723, +1623, 1814, 1337, 2027, 720, 1562, -9, 638, +-614, -193, -1031, -838, -1215, -1541, -1036, -1878, +-342, -1566, 381, -488, 1067, 1228, 1276, 2568, +851, 2653, 254, 1389, -288, -704, -466, -2262, +-554, -2570, -749, -1648, -967, -53, -970, 1109, +-325, 1540, 813, 1096, 2066, 596, 2530, 442, +1744, 371, -391, 36, -2780, -948, -3916, -2009, +-3000, -2288, -152, -1167, 2914, 900, 4508, 2946, +3594, 3605, 716, 2100, -2533, -682, -4178, -3131, +-3403, -3863, -871, -2388, 1797, 476, 2957, 2507, +2253, 3010, 746, 1877, -650, -148, -1269, -1435, +-896, -1610, -418, -719, -368, 184, -424, 310, +-354, -264, 124, -697, 1006, -460, 1524, 757, +1230, 2049, 208, 1992, -1151, 563, -1963, -1583, +-1734, -3009, -505, -2617, 929, -561, 1821, 1760, +1755, 3058, 836, 2548, -345, 610, -1472, -1469, +-1784, -2485, -1083, -1883, 188, -475, 1267, 895, +1465, 1449, 816, 1000, -230, 155, -1115, -416, +-1186, -368, -315, 88, 769, 241, 1383, -43, +819, -557, -536, -755, -1626, -389, -1763, 228, +-419, 786, 1325, 824, 2345, 588, 2064, -19, +314, -651, -1763, -786, -2654, -499, -2132, 45, +-373, 389, 1474, 342, 2244, 80, 2006, -176, +713, -207, -702, 41, -1410, 365, -1479, 552, +-1019, 486, -306, -72, 353, -766, 831, -1219, +1177, -1045, 963, -114, 264, 879, -373, 1606, +-729, 1546, -665, 540, -335, -520, -94, -1345, +-113, -1644, -281, -1125, -187, -249, 408, 605, +988, 1133, 1386, 1345, 880, 1146, -387, 535, +-1421, -149, -1970, -1129, -1535, -1672, -39, -1437, +1298, -790, 1933, 290, 1677, 1219, 373, 1730, +-583, 1544, -1071, 850, -1242, -48, -608, -1062, +-313, -1776, -32, -1908, 417, -1504, 567, -300, +951, 1417, 918, 2615, 315, 2761, -341, 1534, +-1015, -658, -1176, -2525, -595, -3125, 171, -2145, +696, -188, 626, 1635, 164, 2443, -234, 2060, +-33, 837, 450, -463, 541, -1249, 277, -1379, +-358, -940, -1087, -411, -1171, 60, -620, 462, +364, 589, 1212, 649, 1326, 499, 779, 193, +-129, 91, -760, -119, -801, -293, -416, -604, +-96, -771, 5, -607, -235, -152, -456, 544, +-12, 1042, 689, 1049, 1296, 514, 1359, -266, +457, -850, -799, -896, -1751, -516, -1895, 116, +-1031, 449, 249, 303, 1271, -69, 1680, -441, +1347, -102, 771, 657, -14, 1058, -775, 876, +-1234, -71, -1552, -1281, -1367, -1788, -635, -1349, +474, -193, 1730, 1264, 2436, 2023, 1990, 1741, +511, 631, -1372, -820, -2599, -1634, -2573, -1632, +-1402, -929, 462, 69, 1954, 758, 2341, 1032, +1756, 910, 433, 694, -796, 236, -1451, -234, +-1575, -632, -1018, -968, -282, -979, 507, -620, +1074, 98, 1029, 830, 751, 1402, 131, 1342, +-494, 454, -810, -640, -656, -1516, -98, -1682, +213, -802, 403, 525, 238, 1532, -168, 1695, +-287, 752, -328, -588, -9, -1423, 529, -1407, +610, -485, 450, 601, 47, 1082, -407, 954, +-606, 345, -758, -210, -631, -470, -221, -652, +433, -711, 1015, -679, 1179, -123, 926, 721, +65, 1387, -814, 1502, -1420, 683, -1417, -746, +-578, -2099, 376, -2294, 1038, -1068, 1230, 932, +766, 2474, 280, 2492, -40, 1031, -479, -949, +-655, -2090, -899, -1995, -947, -803, -432, 594, +253, 1300, 1075, 1121, 1518, 391, 1164, -187, +170, -265, -914, -43, -1498, -9, -1161, -328, +-292, -747, 493, -700, 846, -115, 540, 874, +171, 1360, -104, 848, -65, -150, 280, -1182, +257, -1363, -109, -606, -543, 536, -846, 1273, +-417, 1048, 150, 210, 461, -770, 605, -1163, +313, -699, 167, 74, 96, 664, 38, 898, +61, 508, -299, -2, -690, -325, -855, -475, +-708, -357, 130, -309, 1041, -265, 1405, -69, +1240, 296, 242, 716, -875, 845, -1408, 478, +-1418, -86, -590, -855, 241, -1229, 772, -895, +1215, -158, 929, 821, 514, 1308, -26, 1076, +-852, 292, -918, -618, -891, -1086, -547, -936, +254, -254, 754, 449, 993, 694, 650, 467, +15, -12, -445, -309, -594, -182, -351, 58, +-91, 256, -22, 168, 66, -198, 80, -366, +191, -309, 325, -29, 189, 360, 5, 370, +-306, 96, -387, -148, -243, -340, 3, -147, +459, 183, 582, 385, 376, 408, -201, -50, +-894, -501, -958, -683, -346, -565, 417, 55, +1103, 705, 1160, 926, 650, 735, -162, 87, +-1212, -652, -1550, -896, -1030, -716, -58, -302, +1052, 233, 1515, 529, 1271, 571, 476, 474, +-618, 217, -1357, -78, -1352, -220, -578, -320, +354, -393, 931, -397, 908, -381, 386, -123, +-185, 334, -466, 762, -284, 891, 134, 519, +328, -204, 78, -748, -429, -902, -712, -618, +-548, -89, 103, 308, 878, 469, 1206, 319, +710, 255, -250, 345, -1023, 389, -1165, 309, +-563, -306, 121, -1067, 645, -1253, 892, -791, +494, 292, 30, 1402, -343, 1593, -578, 947, +-269, -163, 65, -1232, 30, -1334, 109, -646, +117, 160, 66, 661, 119, 515, -74, -12, +-135, -315, -58, -34, 34, 531, 82, 832, +129, 566, 112, -413, -61, -1292, -236, -1407, +-323, -752, -117, 435, 226, 1296, 344, 1507, +295, 890, 80, -15, -199, -660, -252, -1017, +-274, -836, -130, -690, 104, -400, 93, 170, +252, 745, 295, 1313, 150, 1280, -79, 579, +-397, -544, -512, -1392, -245, -1586, 156, -987, +426, 142, 740, 900, 484, 1193, -145, 964, +-656, 398, -912, -91, -504, -385, 178, -566, +611, -652, 737, -784, 457, -694, 19, -101, +-216, 711, -380, 1521, -355, 1573, -257, 675, +-278, -608, -154, -1758, 77, -1988, 340, -1117, +723, 337, 832, 1670, 361, 2032, -307, 1187, +-1050, -191, -1167, -1363, -622, -1619, 4, -907, +754, 176, 1109, 982, 948, 996, 407, 436, +-407, -273, -905, -630, -720, -389, -296, 76, +33, 429, 93, 360, 3, -131, 109, -504, +250, -557, 455, -57, 716, 507, 639, 724, +-3, 561, -859, -128, -1498, -755, -1344, -939, +-272, -607, 845, 280, 1597, 1146, 1559, 1235, +764, 536, -254, -620, -1210, -1508, -1380, -1412, +-850, -451, -240, 884, 284, 1666, 447, 1424, +501, 397, 737, -886, 807, -1570, 680, -1348, +112, -407, -839, 644, -1528, 1257, -1601, 1147, +-837, 433, 564, -321, 1688, -796, 1898, -845, +1269, -442, -47, 135, -1169, 493, -1594, 464, +-1391, 176, -488, -205, 465, -277, 1020, -34, +1140, 232, 701, 321, -41, 156, -464, -198, +-600, -468, -422, -520, -48, -278, 60, 238, +64, 581, -81, 695, -67, 434, 70, -192, +218, -618, 407, -736, 209, -382, 8, 274, +-195, 571, -350, 522, -221, 99, -108, -443, +-30, -536, 25, -243, -17, 281, 24, 680, +276, 614, 462, 97, 405, -609, 60, -893, +-410, -742, -678, -122, -632, 590, -166, 908, +332, 833, 600, 296, 582, -235, 50, -527, +-221, -737, -157, -598, -107, -293, 109, 13, +-34, 412, -281, 638, -315, 628, -230, 462, +183, 207, 519, -230, 480, -647, 115, -802, +-310, -768, -436, -421, -173, 164, 254, 794, +451, 1159, 155, 1086, -394, 496, -714, -419, +-695, -1173, -83, -1450, 782, -990, 1233, -102, +1093, 854, 306, 1281, -745, 1046, -1503, 396, +-1460, -339, -745, -591, 308, -522, 1219, -339, +1447, -167, 1276, -323, 515, -383, -511, -28, +-1199, 504, -1520, 1072, -1053, 1119, -158, 421, +581, -459, 1012, -1180, 1002, -1375, 684, -829, +305, 57, -115, 832, -503, 1156, -711, 931, +-780, 337, -760, -187, -521, -507, 173, -700, +894, -653, 1321, -457, 1324, -154, 517, 356, +-438, 700, -1180, 784, -1540, 519, -1124, -64, +-326, -500, 489, -625, 1154, -411, 1227, -126, +809, 49, 336, 153, -236, 193, -629, 262, +-890, 358, -999, 237, -680, -11, -171, -295, +415, -524, 922, -391, 1049, -64, 918, 319, +548, 523, -135, 360, -817, -62, -1363, -392, +-1546, -444, -975, -187, 124, 324, 1414, 464, +2192, 278, 1817, -24, 506, -350, -1109, -366, +-2125, -209, -1945, 14, -925, 184, 541, 220, +1532, 189, 1479, 78, 849, 26, -53, 85, +-624, 19, -753, -146, -536, -266, -194, -435, +-44, -354, 27, -8, 102, 388, 253, 814, +450, 875, 371, 350, -39, -505, -364, -1191, +-417, -1272, -168, -559, 252, 601, 470, 1339, +224, 1238, -313, 471, -702, -569, -682, -1094, +93, -827, 801, -192, 947, 438, 687, 634, +-111, 285, -803, -220, -942, -429, -596, -203, +46, 233, 461, 604, 345, 527, 252, -14, +266, -547, 311, -807, 371, -628, -11, -121, +-488, 452, -821, 799, -958, 767, -419, 483, +462, -103, 1125, -671, 1323, -855, 688, -706, +-364, -166, -1083, 402, -1308, 705, -696, 642, +205, 267, 793, -115, 955, -390, 533, -354, +-66, -112, -413, 80, -517, 85, -338, -117, +-62, -316, 131, -283, 286, 135, 194, 534, +92, 754, -9, 586, -157, -93, -128, -645, +-214, -954, -120, -877, 135, -261, 316, 409, +407, 860, 150, 1023, -180, 716, -415, 124, +-472, -519, -341, -1022, 7, -1201, 418, -645, +636, 268, 543, 1044, 218, 1307, -240, 665, +-641, -250, -679, -897, -516, -891, -27, -300, +465, 323, 657, 654, 805, 311, 375, -216, +-225, -514, -665, -396, -876, 149, -422, 571, +73, 642, 433, 203, 586, -283, 397, -580, +155, -512, -219, -152, -342, 87, -184, 200, +-94, 185, -1, 196, -63, 312, -100, 289, +128, 163, 307, -150, 236, -552, 49, -680, +-219, -453, -326, -73, -117, 506, 130, 878, +343, 660, 330, 279, -169, -261, -612, -778, +-644, -761, -156, -363, 759, 112, 1121, 506, +690, 574, -173, 223, -1077, -63, -1227, -183, +-666, -200, 224, 62, 1055, 134, 1099, 6, +553, -235, -155, -429, -660, -266, -605, 141, +-341, 495, -101, 595, -43, 330, -28, -128, +198, -487, 473, -608, 678, -338, 524, 87, +-107, 356, -723, 360, -979, 117, -671, -23, +55, 5, 613, 154, 820, 112, 546, -167, +-19, -484, -344, -587, -369, -225, -52, 380, +103, 882, -108, 861, -316, 235, -378, -587, +-124, -1130, 369, -951, 700, -95, 613, 750, +217, 1122, -317, 757, -610, -131, -582, -667, +-323, -704, -81, -415, 115, 135, 306, 263, +411, 172, 486, 138, 416, 111, 167, 244, +-270, 306, -743, 61, -901, -420, -549, -781, +76, -634, 570, -16, 886, 700, 778, 1038, +357, 687, -163, -121, -674, -749, -789, -991, +-501, -578, -157, 196, 184, 638, 398, 774, +413, 395, 377, -238, 180, -487, 45, -449, +-74, -124, -192, 216, -290, 215, -466, 84, +-406, -29, -145, 16, 213, 115, 557, 148, +656, -108, 522, -348, 68, -450, -483, -195, +-637, 384, -436, 710, -200, 755, 50, 223, +177, -591, 172, -1097, 171, -1075, 209, -401, +301, 658, 438, 1484, 278, 1488, -312, 659, +-855, -691, -1050, -1708, -571, -1749, 242, -834, +891, 543, 1160, 1567, 903, 1737, 191, 988, +-666, -206, -999, -1238, -854, -1509, -397, -1007, +143, -25, 373, 847, 492, 1042, 506, 690, +345, 102, 264, -421, 15, -430, -342, -189, +-501, -42, -651, 52, -446, -92, -49, -212, +272, -108, 659, 147, 675, 351, 397, 360, +137, 153, -213, -107, -495, -239, -599, -232, +-648, -132, -377, -60, 139, -34, 651, -22, +910, -31, 707, 61, 263, 260, -387, 374, +-822, 332, -815, 69, -421, -373, 97, -601, +441, -553, 524, -203, 360, 261, 171, 471, +-19, 511, -121, 274, -74, 81, -121, 2, +-283, -129, -358, -273, -280, -504, 38, -617, +352, -443, 505, 124, 478, 809, 161, 1184, +-143, 970, -422, 103, -463, -926, -230, -1487, +-100, -1163, 20, -202, 134, 841, 259, 1285, +406, 865, 339, 101, 96, -496, -89, -539, +-356, -198, -518, 5, -472, -108, -174, -394, +303, -417, 580, -24, 579, 628, 279, 1089, +-80, 838, -461, -20, -572, -1011, -306, -1442, +11, -877, 409, 223, 402, 1137, 102, 1287, +-86, 588, -289, -358, -288, -928, 6, -892, +240, -307, 407, 356, 295, 570, -110, 508, +-349, 143, -484, -161, -372, -206, -145, -254, +227, -238, 657, -188, 695, -58, 349, 233, +-175, 458, -540, 427, -670, 190, -558, -201, +-252, -531, 191, -535, 608, -360, 717, 13, +488, 462, 147, 643, -250, 505, -534, 75, +-583, -319, -493, -473, -158, -405, 135, -203, +428, -33, 627, 80, 505, 277, 257, 392, +-102, 327, -401, 156, -566, -103, -602, -297, +-449, -336, 14, -336, 562, -281, 870, -94, +770, 209, 232, 575, -454, 787, -931, 485, +-878, -147, -278, -810, 576, -1077, 939, -629, +628, 149, -147, 845, -902, 1062, -824, 523, +-85, -217, 812, -704, 1237, -661, 681, -150, +-463, 252, -1405, 296, -1515, -19, -517, -252, +867, -112, 1691, 320, 1439, 631, 290, 475, +-881, -158, -1428, -841, -983, -1045, -140, -529, +525, 451, 718, 1151, 478, 1156, 144, 387, +-77, -664, -22, -1111, 11, -901, -110, -135, +-374, 546, -478, 706, -259, 487, 211, 50, +565, -154, 474, -196, 160, -134, -185, -42, +-302, -181, -188, -300, -14, -216, -5, 30, +-81, 459, -93, 685, -112, 502, 185, -46, +456, -638, 424, -832, 79, -570, -503, 52, +-774, 596, -486, 762, 220, 474, 837, -39, +792, -443, 225, -549, -451, -249, -890, 161, +-697, 335, -54, 160, 582, -133, 814, -343, +533, -169, -44, 209, -436, 438, -505, 459, +-371, 140, -142, -369, 45, -653, 202, -576, +334, -177, 416, 371, 349, 679, 97, 561, +-319, 162, -641, -231, -637, -475, -247, -373, +377, -119, 657, 39, 546, 135, 157, 84, +-231, 64, -363, 138, -294, 172, -85, 156, +30, 1, 15, -190, -44, -299, 1, -226, +216, -51, 328, 99, 202, 146, -106, 76, +-437, 33, -347, 110, 27, 227, 331, 234, +385, 36, 20, -340, -445, -684, -581, -640, +-181, -88, 536, 626, 911, 1043, 662, 807, +-121, 34, -951, -806, -1193, -1075, -673, -702, +354, 113, 1135, 850, 1134, 918, 490, 363, +-425, -444, -919, -826, -789, -562, -314, 144, +276, 767, 528, 784, 396, 190, 123, -609, +-136, -1034, -143, -712, 20, 104, 39, 893, +-17, 1060, -137, 533, -191, -272, -69, -856, +17, -786, 105, -283, 148, 307, 151, 578, +123, 378, 58, -65, -76, -359, -254, -252, +-305, 98, -159, 436, 112, 454, 346, 44, +367, -473, 80, -694, -246, -538, -416, -44, +-258, 524, 120, 751, 378, 626, 400, 206, +124, -340, -207, -552, -401, -543, -406, -350, +-208, -37, 65, 66, 371, 316, 524, 457, +429, 448, 163, 368, -164, 12, -559, -361, +-765, -625, -594, -675, -29, -391, 665, 159, +969, 604, 758, 743, 138, 500, -537, 12, +-858, -310, -670, -415, -163, -326, 382, -134, +444, -132, 138, -164, -45, -71, -19, 180, +307, 567, 523, 754, 241, 483, -366, -145, +-914, -828, -1029, -1155, -430, -770, 569, 86, +1284, 902, 1233, 1229, 387, 791, -653, -5, +-1151, -762, -873, -1047, -185, -641, 470, 20, +591, 555, 269, 676, -71, 342, -217, -85, +57, -253, 395, -170, 373, -79, -54, -48, +-593, -131, -857, -145, -522, 20, 272, 257, +873, 474, 951, 371, 417, -67, -398, -538, +-888, -842, -699, -610, -114, 155, 518, 931, +719, 1247, 289, 767, -306, -294, -652, -1236, +-412, -1451, 116, -778, 549, 329, 596, 1188, +242, 1366, -224, 757, -563, -179, -532, -882, +-174, -1022, 241, -630, 363, 14, 218, 379, +40, 468, -2, 342, 16, 134, 46, 93, +75, 112, -61, 105, -257, -101, -368, -464, +-287, -679, -28, -526, 356, -12, 547, 621, +443, 968, 241, 767, -96, 159, -445, -549, +-618, -962, -615, -769, -269, -231, 259, 380, +672, 608, 868, 468, 566, 193, -12, -83, +-567, -131, -848, -75, -593, -69, -208, -157, +130, -305, 505, -390, 655, -150, 481, 353, +180, 710, -173, 784, -466, 311, -545, -530, +-537, -1084, -291, -1032, 237, -302, 724, 746, +863, 1382, 504, 1115, -215, 129, -778, -999, +-960, -1506, -605, -1010, 184, 66, 826, 1115, +951, 1408, 497, 814, -201, -116, -670, -946, +-647, -1151, -396, -707, -42, 7, 254, 606, +387, 765, 402, 527, 369, 200, 236, -76, +-83, -215, -445, -367, -723, -499, -680, -470, +-159, -213, 467, 223, 898, 607, 924, 717, +361, 469, -338, 35, -865, -443, -899, -693, +-374, -577, 149, -269, 435, 132, 542, 430, +388, 401, 205, 311, 75, 240, -122, 102, +-275, -42, -460, -291, -502, -562, -296, -575, +97, -297, 556, 157, 746, 588, 596, 779, +37, 667, -553, 206, -774, -460, -572, -898, +-30, -945, 402, -467, 529, 334, 346, 918, +62, 987, -190, 466, -248, -354, -144, -831, +-60, -746, 72, -162, 95, 457, 24, 642, +51, 304, 42, -256, -82, -549, -132, -407, +-137, 107, -24, 540, 212, 589, 306, 207, +308, -285, 44, -578, -432, -495, -607, -132, +-427, 211, 21, 436, 584, 355, 747, 107, +366, -48, -132, -154, -519, -146, -605, -81, +-159, -104, 225, -74, 269, -14, 173, 28, +-108, 89, -209, 23, 18, 28, 302, 156, +413, 289, 251, 256, -293, -59, -733, -529, +-700, -773, -230, -532, 535, 129, 977, 836, +751, 1090, 123, 724, -619, -156, -955, -963, +-573, -1194, 53, -673, 577, 214, 667, 866, +214, 884, -277, 360, -417, -226, -240, -485, +243, -317, 474, 51, 269, 171, -236, -68, +-730, -307, -634, -328, -77, 45, 638, 509, +1022, 630, 758, 326, -56, -164, -911, -499, +-1246, -556, -794, -357, 221, -46, 1011, 281, +1207, 494, 683, 563, -298, 330, -968, -153, +-963, -685, -382, -794, 292, -315, 637, 410, +477, 873, 134, 645, -100, -51, -140, -653, +-68, -684, -4, -248, -74, 293, -255, 504, +-282, 307, -112, -27, 226, -197, 472, -133, +449, 17, 199, 81, -107, -50, -466, -231, +-616, -271, -494, -116, -69, 201, 598, 517, +802, 593, 566, 349, 43, -216, -564, -793, +-796, -1039, -580, -734, -26, 191, 555, 1121, +730, 1465, 439, 945, -35, -219, -463, -1255, +-545, -1524, -377, -946, -70, 126, 376, 1025, +619, 1253, 471, 876, 58, 99, -441, -531, +-724, -801, -513, -838, -54, -528, 475, 11, +806, 536, 591, 983, 73, 894, -475, 179, +-777, -661, -590, -1140, -174, -825, 289, 60, +682, 856, 660, 974, 335, 414, -126, -355, +-595, -678, -720, -527, -484, -164, 143, 207, +642, 358, 616, 376, 195, 246, -273, -25, +-370, -288, -195, -344, 54, -180, 119, 85, +26, 230, -57, 37, -108, -225, -90, -148, +133, 208, 302, 638, 238, 593, -26, -152, +-353, -978, -388, -1123, -154, -382, 180, 764, +280, 1338, 226, 879, 171, -160, -27, -969, +-227, -956, -249, -316, -167, 382, 17, 644, +265, 463, 146, 57, -70, -343, -125, -520, +59, -318, 259, 211, 161, 616, -161, 567, +-485, 44, -377, -635, -26, -819, 397, -391, +542, 318, 458, 818, 169, 769, -486, 153, +-807, -589, -675, -878, -70, -539, 713, 231, +870, 849, 466, 739, -43, 68, -419, -617, +-578, -781, -535, -370, -295, 194, 171, 453, +625, 430, 645, 384, 343, 252, -103, -27, +-401, -547, -400, -840, -468, -647, -383, -46, +-44, 640, 463, 919, 876, 795, 796, 388, +168, -244, -721, -852, -1064, -1143, -836, -860, +-231, -46, 545, 864, 1067, 1256, 1076, 968, +393, 196, -598, -629, -1204, -958, -868, -818, +-171, -290, 458, 187, 652, 443, 467, 551, +399, 391, 122, 211, -296, 9, -586, -261, +-580, -411, -233, -398, 190, -248, 373, 4, +411, 254, 460, 369, 206, 368, -266, 218, +-563, -72, -586, -332, -211, -457, 215, -235, +526, 87, 554, 306, 202, 356, -199, 179, +-500, -52, -468, -296, -85, -428, 293, -257, +390, 205, 194, 619, -133, 587, -204, 41, +-71, -582, -15, -808, 76, -459, 110, 247, +48, 771, -19, 720, -220, 191, -249, -447, +-34, -741, 273, -449, 431, 182, 248, 561, +-53, 512, -386, 18, -555, -445, -368, -519, +131, -175, 550, 232, 659, 428, 226, 406, +-330, 87, -459, -213, -288, -353, -33, -284, +54, -141, 88, 68, 72, 134, 90, 112, +133, 195, 194, 334, 157, 235, -132, -109, +-417, -465, -399, -552, -61, -282, 334, 154, +392, 384, 176, 406, -41, 322, -230, 32, +-264, -133, -75, -333, 215, -329, 333, -63, +130, 62, -281, 69, -477, -38, -217, -27, +157, 229, 413, 470, 434, 373, 178, -154, +-101, -736, -334, -791, -482, -206, -334, 567, +133, 894, 388, 464, 457, -239, 219, -612, +-188, -490, -341, -34, -253, 344, 83, 334, +241, 166, 244, -125, -76, -302, -380, -251, +-348, -12, 12, 304, 481, 350, 573, 85, +178, -278, -355, -414, -557, -226, -336, 273, +86, 494, 270, 310, 280, -71, 115, -476, +-26, -532, -165, -225, -105, 185, -17, 563, +66, 616, 106, 288, -44, -242, -77, -685, +-114, -618, -42, -182, 7, 295, 90, 506, +115, 343, 101, 47, -30, -55, -148, -73, +-91, -77, 17, -36, 208, -109, 49, -229, +-323, -233, -400, -168, -72, 117, 517, 537, +680, 678, 195, 392, -439, -231, -579, -811, +-302, -824, 28, -280, 161, 346, 210, 643, +364, 450, 194, 45, -96, -136, -263, -82, +-186, 12, 22, -8, 60, -192, -43, -333, +-41, -348, -25, -43, 32, 361, 140, 591, +274, 500, 252, 82, -161, -396, -516, -574, +-482, -439, 47, -95, 532, 320, 499, 472, +114, 265, -165, -132, -363, -344, -372, -248, +-187, 298, 140, 527, 508, 219, 479, -401, +73, -837, -431, -494, -513, 289, -234, 862, +190, 713, 410, -21, 247, -552, -116, -556, +-289, -245, -88, 184, 136, 292, 208, 252, +106, 171, -79, -69, -212, -383, -223, -327, +-240, -28, -151, 310, 207, 392, 506, 171, +573, -25, 351, -127, -279, -150, -874, -336, +-985, -426, -400, -168, 396, 348, 996, 700, +985, 621, 383, 162, -234, -358, -830, -577, +-978, -584, -588, -480, 156, -107, 777, 465, +831, 895, 341, 840, -187, 194, -512, -641, +-419, -908, 31, -498, 270, 21, 147, 234, +-166, 235, -450, 219, -211, 275, 430, 326, +674, 178, 462, -194, -49, -480, -559, -581, +-792, -490, -419, 8, 290, 682, 861, 931, +676, 624, -133, -216, -644, -999, -542, -919, +74, -233, 484, 536, 355, 841, 97, 478, +-160, -100, -329, -428, -359, -474, -111, -215, +266, 42, 497, 261, 358, 362, -71, 97, +-341, -206, -338, -220, -71, 99, 115, 391, +196, 137, -57, -519, -230, -822, -8, -332, +332, 678, 383, 1310, -11, 794, -349, -425, +-397, -1285, -235, -1171, 39, -157, 281, 850, +352, 1055, 208, 473, -229, -206, -390, -557, +-104, -453, 273, -111, 306, 153, -165, 271, +-506, 122, -351, -120, 134, -296, 538, -137, +632, 321, 217, 527, -416, 299, -834, -303, +-669, -772, 36, -609, 623, 97, 746, 802, +430, 818, -30, 119, -469, -647, -669, -866, +-423, -337, 124, 505, 402, 840, 277, 508, +95, -179, 158, -795, 245, -802, -38, -192, +-513, 615, -465, 951, 33, 533, 344, -259, +258, -843, 13, -723, 36, 24, 109, 586, +-66, 587, -208, 76, -58, -463, 201, -450, +237, 71, 37, 571, -297, 440, -367, -158, +-146, -694, 212, -606, 546, -17, 506, 603, +121, 727, -397, 371, -528, -238, -350, -679, +-90, -681, 179, -184, 321, 539, 300, 885, +115, 426, -60, -446, 9, -952, 151, -633, +-97, 436, -579, 1157, -645, 787, -97, -375, +473, -1267, 690, -1101, 574, 138, 177, 1290, +-356, 1379, -793, 266, -809, -1094, -197, -1498, +501, -701, 675, 712, 359, 1455, 12, 945, +-158, -238, -331, -1153, -299, -1133, -24, -172, +150, 835, -80, 1100, -373, 531, -133, -539, +441, -1133, 839, -743, 474, 312, -454, 1232, +-943, 1067, -822, -94, -239, -1297, 529, -1547, +1005, -433, 851, 1192, 86, 1967, -753, 1188, +-949, -625, -422, -2001, 313, -1855, 713, -233, +446, 1527, -70, 2092, -495, 938, -404, -809, +229, -1817, 682, -1319, 513, 224, -196, 1482, +-776, 1463, -728, 159, -148, -1213, 597, -1687, +996, -678, 754, 952, -106, 1941, -944, 1372, +-1071, -398, -255, -1874, 689, -1904, 967, -380, +537, 1411, -182, 1990, -579, 956, -725, -723, +-343, -1718, 309, -1265, 822, 220, 646, 1460, +-75, 1330, -701, 134, -571, -1148, -9, -1509, +281, -542, 244, 813, -9, 1550, -118, 946, +-8, -385, 141, -1348, 136, -1124, 34, 99, +-187, 1076, -347, 1032, -379, -49, -80, -983, +327, -1042, 560, -13, 297, 1054, -272, 1304, +-599, 515, -377, -886, 158, -1640, 408, -1129, +228, 266, -205, 1444, -396, 1559, -250, 456, +53, -819, 358, -1408, 452, -895, 272, 207, +-203, 1099, -642, 1004, -681, -58, -324, -1014, +488, -1050, 1064, -15, 805, 1168, -74, 1412, +-962, 279, -1099, -1192, -283, -1746, 656, -871, +930, 862, 559, 1758, -135, 1310, -533, -211, +-577, -1481, -219, -1400, 435, -317, 624, 895, +309, 1389, -314, 775, -669, -426, -244, -1310, +407, -1162, 692, -53, 462, 1127, -64, 1503, +-628, 508, -780, -897, -245, -1519, 458, -839, +967, 524, 654, 1481, -212, 1121, -824, -454, +-703, -1461, 49, -1302, 711, 96, 625, 1667, +-88, 1763, -768, 323, -658, -1480, 237, -2026, +778, -1134, 675, 715, -27, 2029, -567, 1627, +-797, 134, -387, -1277, 118, -1641, 565, -784, +643, 615, 112, 1341, -538, 856, -684, -321, +19, -1141, 606, -919, 571, 279, -206, 1342, +-924, 1217, -989, -124, -112, -1465, 998, -1626, +1370, -424, 681, 1328, -577, 1825, -1553, 817, +-1352, -930, -40, -1742, 1196, -909, 1488, 704, +535, 1577, -839, 928, -1424, -647, -682, -1567, +607, -1078, 1234, 297, 749, 1524, -334, 1424, +-1005, 210, -835, -1091, -3, -1520, 703, -741, +873, 683, 400, 1293, -488, 727, -809, -549, +-209, -1207, 716, -558, 868, 898, 31, 1600, +-930, 783, -1084, -1091, -242, -2267, 898, -1568, +1435, 614, 983, 2479, -48, 2416, -1331, 489, +-1692, -1890, -574, -2852, 1007, -1532, 1733, 993, +1008, 2674, -512, 2130, -1485, -240, -1045, -2401, +203, -2471, 1326, -264, 1406, 2122, 321, 2798, +-1225, 1042, -1840, -1536, -1046, -3031, 608, -2112, +1794, 360, 1646, 2583, 363, 2955, -997, 1081, +-1677, -1517, -1151, -2864, 79, -1943, 792, 358, +1055, 1973, 445, 1794, -191, 230, -443, -1130, +-410, -1014, -302, 48, -13, 764, 161, 399, +159, -575, -63, -1044, -94, -336, 138, 827, +68, 1489, -145, 890, -500, -477, -364, -1741, +289, -1866, 895, -349, 689, 1609, -200, 2552, +-1033, 1552, -1192, -854, -479, -2682, 668, -2362, +1310, -257, 1001, 1812, 180, 2433, -711, 1181, +-1139, -730, -799, -1692, 56, -1348, 813, 76, +882, 1199, 247, 938, -527, -253, -485, -1331, +71, -1060, 485, 508, 407, 1976, -50, 1930, +-365, 138, -608, -2146, -434, -2907, 252, -1428, +1026, 1148, 1037, 3010, 125, 2584, -965, 283, +-1226, -2039, -283, -2775, 748, -1499, 1174, 869, +773, 2397, -286, 1965, -1279, -43, -1272, -2014, +-118, -2145, 1254, -414, 1603, 1577, 697, 2230, +-595, 1142, -1233, -895, -1132, -2137, -392, -1792, +415, -275, 950, 1515, 886, 2252, 13, 1242, +-518, -711, -380, -2100, 122, -1797, 169, 89, +-94, 1725, -640, 1913, -617, 483, -147, -1362, +397, -1927, 853, -1023, 868, 601, 297, 1711, +-644, 1538, -1049, 403, -878, -863, -224, -1577, +377, -1176, 653, -144, 386, 856, 5, 1130, +-184, 576, 25, -97, 331, -412, 294, -94, +-411, 121, -1085, -24, -933, -624, -148, -910, +834, -522, 1438, 589, 1243, 1583, 226, 1608, +-1069, 391, -1773, -1427, -1307, -2154, 270, -1489, +1482, 391, 1575, 1984, 568, 1896, -689, 471, +-1246, -1094, -947, -1825, 51, -982, 1051, 510, +1350, 1416, 440, 1297, -649, -38, -1335, -1199, +-858, -1388, 256, -491, 1000, 772, 1007, 1314, +333, 882, -253, -180, -559, -880, -462, -808, +-54, -197, 266, 384, 204, 438, -43, -64, +-360, -371, -138, -194, 374, 405, 804, 923, +609, 599, -269, -315, -901, -1255, -966, -1291, +-337, -427, 378, 783, 808, 1569, 590, 1164, +173, 87, -234, -902, -387, -1191, -243, -707, +-213, 165, -263, 532, -226, 406, 194, 37, +410, -68, 389, 215, 72, 596, -337, 430, +-461, -469, -268, -1182, 120, -1133, 283, -253, +250, 1045, -52, 1516, -510, 998, -527, -32, +60, -1065, 514, -1340, 590, -802, 290, 248, +-190, 925, -652, 938, -796, 324, -368, -360, +324, -649, 960, -232, 874, 26, -12, 240, +-781, 175, -759, -41, -218, -63, 275, 13, +526, 41, 404, -72, 126, -335, -244, -186, +-412, 276, -308, 595, 175, 787, 498, 66, +378, -826, 32, -1245, -197, -991, -178, 96, +-173, 1432, -42, 1738, -84, 1040, 133, -555, +410, -1807, 489, -1775, 151, -725, -278, 850, +-373, 1703, -307, 1502, -141, 443, 125, -918, +240, -1593, 345, -1224, 259, -57, 76, 1013, +-139, 1528, -198, 929, -176, -280, -247, -1246, +-197, -1397, -5, -785, 161, 442, 350, 1400, +461, 1584, 182, 907, -116, -565, -552, -1830, +-776, -2054, -380, -827, 188, 1068, 588, 2370, +702, 1999, 217, 404, -231, -1561, -626, -2474, +-523, -1776, -111, 122, 139, 2021, 260, 2594, +161, 1329, -20, -915, -21, -2542, 32, -2426, +19, -602, -143, 1697, -379, 2776, -372, 1958, +65, -96, 600, -2154, 726, -2592, 267, -1351, +-631, 506, -1167, 2047, -835, 2189, 164, 926, +1167, -697, 1603, -1794, 909, -1629, -454, -377, +-1805, 926, -1968, 1288, -861, 721, 923, -364, +2288, -882, 2180, -514, 853, 341, -1052, 976, +-2254, 609, -2300, -483, -1077, -1308, 1124, -1170, +2555, 21, 2501, 1433, 976, 1842, -1028, 855, +-2404, -766, -2286, -2010, -890, -1930, 906, -302, +2255, 1359, 2314, 2249, 902, 1651, -1084, -12, +-2212, -1693, -1880, -2342, -336, -1500, 1303, 294, +1909, 1967, 1035, 2220, -322, 1110, -1242, -701, +-1128, -1613, -125, -1466, 917, -536, 883, 364, +154, 670, -1009, 552, -1426, 251, -366, 159, +1133, 349, 2185, 440, 1329, 117, -740, -576, +-2502, -1414, -2644, -1501, -872, -497, 1549, 1055, +2980, 2218, 2403, 2201, 391, 606, -2034, -1362, +-2938, -2483, -1845, -2050, 103, -495, 1756, 1233, +2028, 2011, 1023, 1414, -414, 155, -1162, -924, +-953, -1144, -69, -397, 563, 462, 269, 552, +-377, -39, -645, -775, -300, -740, 425, -84, +1000, 842, 1046, 1144, 396, 701, -763, -17, +-1359, -632, -1161, -865, -92, -733, 898, -439, +1090, -29, 782, 320, 146, 750, -460, 1076, +-771, 740, -428, 79, 82, -875, 529, -1375, +347, -1048, 12, 12, -206, 1000, -354, 1198, +-266, 548, -8, -532, 642, -1103, 978, -546, +573, 694, -429, 1435, -1128, 969, -1133, -589, +-457, -2087, 457, -2054, 1138, -451, 1259, 1591, +649, 2726, -442, 2161, -1300, 139, -1071, -2008, +-247, -2721, 578, -1823, 828, 104, 458, 1846, +-108, 2157, -566, 1153, -525, -241, -14, -1280, +502, -1307, 607, -556, 213, 337, -346, 792, +-681, 501, -676, 63, -448, -266, 25, -346, +649, -259, 941, -136, 865, 112, 371, 536, +-552, 807, -1326, 506, -1672, -420, -954, -1310, +630, -1442, 1804, -638, 2078, 835, 920, 1981, +-808, 1958, -2046, 684, -1958, -1118, -674, -2439, +967, -2330, 1915, -811, 1354, 1334, 78, 2742, +-1021, 2471, -1134, 794, -397, -1348, 369, -2638, +606, -2392, 159, -1002, -455, 897, -348, 2327, +315, 2564, 871, 1563, 769, -445, -5, -2121, +-1001, -2743, -1314, -2102, -819, -240, 326, 1699, +1534, 2996, 1840, 2973, 831, 1066, -705, -1558, +-1723, -3610, -1674, -3664, -559, -1312, 556, 1819, +1299, 3941, 1465, 3551, 891, 968, 24, -1900, +-794, -3482, -1268, -2877, -1194, -580, -770, 1617, +218, 2546, 1280, 1987, 1855, 398, 1217, -1058, +-140, -1556, -1498, -1211, -2106, -365, -1289, 327, +306, 678, 1787, 845, 2041, 644, 885, 372, +-1000, -155, -2166, -766, -1694, -1203, 43, -942, +1691, -88, 2142, 1058, 1009, 1829, -1024, 1332, +-2447, 35, -2015, -1470, -131, -2122, 1798, -1350, +2542, 28, 1371, 1392, -696, 1977, -1951, 1220, +-2115, 254, -868, -750, 1008, -1346, 1766, -1208, +1423, -850, 126, -315, -1160, 442, -1198, 1221, +-435, 1701, 611, 1523, 829, 454, 249, -1337, +-359, -2634, -745, -2450, -339, -904, 351, 1511, +807, 3063, 593, 2755, 67, 1043, -493, -1458, +-745, -2939, -361, -2644, 109, -1076, 445, 1232, +351, 2666, 215, 2167, 53, 766, 38, -896, +107, -1985, -116, -1537, -361, -723, -370, 264, +-142, 1023, 140, 1286, 617, 1203, 555, 657, +279, -425, -168, -1536, -674, -2091, -707, -1556, +-253, 175, 383, 2116, 806, 3069, 689, 2176, +146, -69, -436, -2735, -901, -3773, -766, -2615, +-251, 105, 505, 3060, 1187, 3988, 1131, 2491, +250, -241, -879, -2740, -1584, -3282, -1340, -1864, +-276, 97, 1007, 1679, 1811, 1908, 1584, 1143, +295, 401, -1316, -245, -2291, -436, -1677, -503, +128, -939, 1725, -1080, 2047, -691, 1054, 107, +-679, 1226, -1814, 1823, -1578, 1420, -393, 192, +1063, -1215, 1769, -1911, 1110, -1521, -515, -326, +-1491, 813, -1505, 1421, -587, 1087, 799, 516, +1541, 38, 1486, -450, 606, -709, -634, -896, +-1590, -965, -1795, -555, -1040, 475, 449, 1351, +1760, 1821, 2241, 1246, 1523, -234, -320, -1821, +-1868, -2576, -2278, -1707, -1488, 306, 121, 2314, +1621, 2970, 2156, 1693, 1415, -663, 107, -2398, +-1209, -2631, -1698, -1379, -1080, 591, -8, 1938, +861, 2019, 936, 1036, 480, -467, 21, -1423, +-72, -1095, 81, -229, 65, 440, -396, 467, +-859, -327, -688, -723, -80, -293, 763, 657, +1455, 1615, 1179, 1638, 105, 331, -1261, -1461, +-2043, -2744, -1389, -2622, 210, -617, 1650, 1870, +1993, 3509, 1079, 3184, -253, 1019, -1385, -1713, +-1733, -3548, -994, -3374, 99, -1474, 907, 1027, +852, 3055, 376, 3325, 188, 1744, 404, -406, +427, -2271, -193, -2558, -1187, -1458, -1756, 1, +-1435, 1041, -137, 1203, 1874, 925, 2946, 400, +2307, 110, 101, 75, -2595, -76, -3590, -398, +-2439, -709, 103, -1067, 2493, -973, 3383, -109, +2186, 988, -207, 1885, -2144, 1895, -2550, 841, +-1346, -893, 203, -2221, 1259, -2397, 1427, -1426, +842, 188, -109, 1951, -612, 2618, -556, 2115, +-41, 577, 354, -1331, 149, -2351, -127, -2346, +-393, -1240, -376, 59, -300, 1369, 78, 2384, +987, 2361, 1398, 1392, 1015, -450, -226, -2427, +-1729, -3056, -2405, -2500, -1675, -615, 372, 1678, +2695, 3234, 3657, 3533, 2229, 1771, -969, -730, +-3669, -3132, -4108, -4040, -1998, -2649, 1393, -175, +3842, 2263, 3998, 3574, 1781, 3106, -1413, 1318, +-3618, -815, -3436, -2684, -1403, -3320, 1212, -2529, +2668, -603, 2430, 1695, 1001, 3072, -707, 3105, +-1415, 1526, -1146, -679, -760, -2479, -569, -3048, +-252, -1929, 407, 88, 1311, 1857, 1677, 2413, +877, 1580, -573, 2, -1840, -1287, -2128, -1565, +-977, -763, 817, 307, 2214, 1166, 2232, 897, +523, -115, -1536, -854, -2551, -1315, -1942, -718, +-13, 451, 1944, 1314, 2834, 1926, 1813, 1427, +-320, -13, -2258, -1543, -3082, -2713, -1990, -2439, +199, -903, 2271, 1332, 3383, 3160, 2524, 3596, +354, 2047, -1947, -539, -3404, -3033, -3055, -4242, +-1307, -3218, 1290, -627, 3374, 2429, 3732, 4384, +2232, 4035, -635, 1631, -2973, -1577, -3502, -3821, +-2524, -3958, -236, -2217, 1920, 524, 2846, 2699, +2747, 3427, 1176, 2449, -599, 264, -1658, -1822, +-2332, -2730, -1955, -2241, -942, -573, 457, 1208, +1828, 2128, 2550, 1776, 2206, 462, 778, -1037, +-1136, -1778, -2822, -1437, -3226, -319, -1840, 961, +482, 1621, 2934, 1434, 3842, 480, 2592, -746, +107, -1644, -2836, -1850, -4311, -1199, -3399, 189, +-490, 1519, 2716, 2313, 4402, 1934, 3639, 562, +830, -994, -2506, -2200, -4264, -2431, -3630, -1556, +-1164, -22, 1904, 1422, 3544, 2350, 3230, 2279, +1356, 1293, -1124, 41, -2545, -1452, -2572, -2465, +-1459, -2707, 66, -1659, 1150, 268, 1585, 2192, +1459, 3378, 858, 2734, 75, 927, -608, -1273, +-1147, -2868, -1395, -2953, -1298, -1840, -437, 107, +770, 1801, 1803, 2536, 2038, 2249, 1139, 905, +-454, -545, -1828, -1561, -2258, -1930, -1405, -1395, +276, -643, 1713, 546, 2229, 1650, 1408, 1773, +15, 1160, -1437, -159, -2110, -1667, -1436, -1936, +-104, -895, 1503, 693, 2230, 2262, 1551, 1984, +218, 110, -1420, -1965, -2221, -2865, -1804, -1656, +-489, 810, 1371, 2639, 2393, 2777, 2051, 1270, +667, -850, -896, -2185, -1939, -2274, -1860, -1234, +-1046, 85, -87, 893, 968, 1139, 1412, 1074, +1339, 1026, 1204, 920, 662, 460, -316, -714, +-1616, -2187, -2609, -2834, -2433, -2138, -928, 122, +1571, 2715, 3523, 4156, 3743, 3294, 2071, 430, +-1100, -2741, -3853, -4412, -4653, -3689, -2968, -952, +451, 1958, 3353, 3517, 4532, 3249, 3252, 1566, +246, -530, -2420, -2169, -3700, -2610, -2981, -2080, +-994, -764, 915, 856, 2194, 1884, 2384, 2204, +1759, 1592, 572, 223, -908, -1104, -1918, -2029, +-2291, -1807, -1612, -777, -156, 415, 1436, 1423, +2450, 1525, 2163, 1029, 881, 308, -1022, -223, +-2310, -599, -2072, -1037, -1044, -1295, 513, -1046, +1677, -271, 1525, 1042, 1014, 2047, 311, 2025, +-404, 1142, -794, -593, -952, -2098, -945, -2698, +-683, -1889, -31, -44, 683, 1807, 1310, 2737, +1740, 2245, 1222, 760, -185, -924, -1486, -1889, +-2220, -2018, -1654, -1296, -432, -267, 1011, 441, +1911, 1087, 1948, 1530, 1332, 1565, -65, 1046, +-1283, -150, -1804, -1562, -1705, -2241, -857, -1873, +350, -576, 1260, 1044, 1726, 1782, 1375, 1760, +449, 1052, -641, -31, -1341, -750, -1353, -1177, +-827, -1379, 128, -899, 782, -190, 786, 430, +431, 905, -149, 918, -325, 653, -51, 362, +318, -73, 562, -436, 281, -641, -719, -815, +-1529, -712, -1454, -569, -440, -131, 1175, 681, +2339, 1451, 2066, 1878, 674, 1236, -1147, -472, +-2519, -2144, -2450, -2912, -1253, -1958, 612, 172, +2051, 2279, 2548, 3379, 1871, 2455, 183, 220, +-1420, -2177, -2395, -3343, -2293, -2583, -1036, -159, +639, 2080, 2107, 2711, 2560, 1973, 1760, 80, +114, -1376, -1733, -1486, -2414, -811, -1979, 19, +-696, 420, 1055, -64, 1908, -424, 1822, -143, +1067, 686, 116, 1731, -672, 1728, -1134, 450, +-1351, -1472, -1348, -2916, -838, -2725, 290, -803, +1551, 1746, 2378, 3451, 2185, 3259, 774, 1239, +-1171, -1386, -2885, -3219, -2868, -3140, -1437, -1245, +631, 996, 2435, 2120, 2761, 1853, 1664, 597, +-114, -428, -1570, -591, -1735, -162, -851, 294, +-4, 111, 417, -508, 98, -1322, -332, -1339, +-314, -488, 78, 846, 998, 1931, 1622, 2004, +1281, 1048, 159, -453, -1476, -1709, -2549, -2069, +-2279, -1464, -968, -282, 851, 798, 2338, 1178, +2664, 1013, 1914, 649, 244, 305, -1411, 180, +-2271, 15, -2293, -478, -1337, -1017, -24, -1257, +989, -1064, 1657, -282, 1800, 771, 1264, 1308, +296, 1525, -690, 1181, -1391, 381, -1489, -494, +-912, -1196, -322, -1534, 133, -1486, 472, -921, +744, 51, 1092, 1119, 1077, 1997, 751, 2206, +186, 1427, -821, 65, -1524, -1433, -1712, -2479, +-1328, -2417, 16, -1260, 1245, 316, 1794, 1665, +1746, 2226, 902, 1884, 59, 1045, -696, 52, +-1338, -878, -1521, -1529, -1324, -1771, -556, -1524, +554, -870, 1426, 226, 1724, 1446, 1410, 2343, +517, 2527, -525, 1599, -1174, -298, -1357, -2174, +-906, -3316, -265, -2862, -15, -1077, 82, 1088, +422, 2870, 953, 3218, 1522, 2257, 1445, 222, +276, -1799, -1029, -2840, -2127, -2557, -2343, -1014, +-1192, 690, 559, 1733, 1990, 1825, 2241, 1121, +1124, 78, -282, -602, -977, -928, -926, -730, +-327, -236, 31, 27, -243, 100, -657, -180, +-803, -360, -420, -159, 555, 392, 1541, 1052, +1880, 998, 1141, 305, -85, -552, -1478, -1282, +-2233, -1246, -1831, -688, -1036, 241, 364, 1052, +1517, 1261, 1994, 719, 2008, -166, 1124, -713, +-235, -795, -1523, -210, -2315, 217, -2047, 221, +-1019, 20, 409, -272, 1649, -360, 1987, 45, +1733, 569, 794, 761, -417, 577, -983, -122, +-1371, -682, -1420, -763, -956, -428, -418, -7, +457, 157, 1453, 238, 1792, 429, 1460, 660, +552, 646, -697, 333, -1578, -445, -1727, -1121, +-1247, -1245, -222, -780, 899, 371, 1377, 1530, +1397, 1914, 721, 1187, -32, -373, -559, -1800, +-898, -2196, -798, -1275, -502, 407, -15, 1811, +475, 2222, 638, 1368, 401, -267, 54, -1747, +-328, -2110, -357, -1282, -104, 43, 256, 1287, +667, 1641, 610, 1194, -78, 422, -951, -423, +-1380, -971, -1061, -1220, 28, -1164, 1184, -598, +1738, 329, 1476, 1148, 406, 1596, -840, 1254, +-1667, 279, -1737, -875, -944, -1718, 212, -1700, +980, -844, 1227, 513, 932, 1438, 472, 1463, +62, 735, -206, -135, -506, -580, -912, -661, +-1113, -557, -940, -468, -180, -407, 726, -127, +1621, 421, 1723, 844, 920, 969, -321, 501, +-1660, -390, -1932, -1120, -1148, -1188, 111, -404, +1158, 810, 1373, 1506, 954, 1009, 105, -358, +-624, -1560, -847, -1665, -461, -382, 191, 1309, +495, 2109, 325, 1545, -67, -65, -433, -1544, +-346, -2067, -111, -1311, 109, 173, 353, 1239, +434, 1396, 476, 818, 324, 119, -79, -292, +-511, -245, -726, -152, -715, -328, -260, -577, +403, -729, 771, -413, 803, 193, 453, 954, +-7, 1279, -343, 971, -535, 265, -428, -630, +-251, -1259, -88, -1214, 36, -685, 139, -32, +209, 611, 336, 866, 370, 913, 201, 778, +72, 276, -166, -358, -381, -909, -532, -1160, +-426, -773, -117, -62, 71, 643, 290, 975, +381, 699, 421, -47, 382, -634, 138, -560, +-35, -6, -428, 672, -638, 696, -608, -29, +-497, -933, 23, -1377, 376, -877, 548, 180, +716, 1303, 643, 1662, 421, 1157, -144, 136, +-755, -958, -1006, -1602, -1042, -1449, -595, -610, +99, 322, 722, 1052, 1326, 1125, 1342, 781, +791, 356, -25, -117, -1069, -513, -1646, -693, +-1492, -725, -635, -486, 542, -26, 1301, 318, +1448, 610, 897, 579, 103, 224, -453, 2, +-766, -39, -615, 148, -306, 201, -100, -234, +-134, -820, -279, -1036, -124, -601, 336, 384, +953, 1244, 1244, 1440, 940, 897, -47, -50, +-1133, -934, -1782, -1205, -1586, -829, -417, -304, +903, 340, 1644, 469, 1461, 330, 634, 418, +-321, 484, -801, 657, -571, 402, -287, -391, +-201, -1108, -398, -1407, -601, -911, -305, 138, +332, 1068, 1005, 1538, 1448, 1293, 1148, 318, +104, -709, -1127, -1241, -1955, -1207, -1642, -632, +-341, 68, 922, 485, 1485, 796, 1165, 794, +322, 544, -267, 161, -560, -354, -455, -743, +-202, -934, -69, -762, -91, -166, -291, 574, +-295, 1032, -139, 1076, 240, 390, 646, -392, +824, -886, 498, -1001, -46, -529, -506, 25, +-863, 410, -676, 654, -397, 701, -88, 432, +429, 7, 637, -499, 648, -865, 483, -648, +110, -73, -184, 358, -366, 606, -505, 392, +-404, 41, -376, -58, -209, -84, 73, 85, +341, 107, 753, -97, 769, -416, 420, -633, +-61, -334, -583, 176, -752, 759, -556, 952, +-261, 571, 88, -78, 231, -641, 274, -811, +340, -583, 418, -175, 409, 188, 341, 387, +91, 398, -421, 448, -781, 435, -958, 409, +-739, 76, -9, -563, 765, -1050, 1104, -1093, +895, -379, 586, 634, 66, 1248, -428, 1139, +-739, 407, -1039, -314, -983, -727, -607, -777, +85, -513, 904, -153, 1491, 151, 1488, 355, +843, 444, -298, 439, -1391, 299, -1876, -21, +-1514, -407, -397, -672, 827, -527, 1498, 166, +1429, 671, 666, 622, -86, 79, -571, -774, +-839, -914, -550, -348, -177, 500, -126, 1115, +-258, 920, -271, 166, 5, -589, 662, -1024, +1092, -957, 761, -421, 264, 168, -350, 690, +-910, 898, -1004, 723, -838, 319, -276, -240, +379, -651, 672, -921, 807, -751, 873, -217, +665, 486, 43, 965, -677, 743, -1101, 153, +-1150, -473, -610, -696, 177, -251, 898, 384, +1255, 686, 845, 410, -2, -470, -682, -1183, +-725, -1132, -277, -119, 208, 1178, 362, 1911, +98, 1360, -348, -65, -561, -1398, -412, -1923, +188, -1256, 730, 2, 864, 1086, 736, 1377, +151, 1021, -485, 205, -953, -465, -1123, -647, +-712, -512, -61, -263, 577, -58, 1002, -8, +1140, 67, 837, 246, 150, 277, -650, 291, +-1150, 87, -1142, -150, -758, -143, -6, -105, +652, 51, 915, 119, 872, -80, 430, -284, +-25, -395, -169, -232, -350, 224, -524, 566, +-603, 617, -532, 382, -287, -114, 177, -551, +610, -613, 713, -400, 619, -157, 295, 134, +-10, 150, -286, 156, -459, 381, -590, 550, +-694, 526, -495, 213, -231, -450, 219, -1091, +838, -1224, 1325, -700, 1363, 367, 630, 1323, +-605, 1544, -1619, 809, -1936, -276, -1560, -1094, +-338, -1136, 1111, -602, 2074, -29, 2155, 330, +1108, 351, -211, 365, -1243, 395, -1728, 452, +-1502, 286, -917, -143, -11, -635, 861, -892, +1269, -579, 1372, 55, 1123, 679, 375, 917, +-484, 519, -1189, -149, -1503, -567, -1102, -521, +-436, -100, 342, 252, 1068, 253, 1227, -18, +997, -244, 436, -214, -175, 183, -420, 532, +-640, 469, -943, 29, -1068, -623, -742, -891, +74, -468, 985, 366, 1541, 976, 1474, 1024, +729, 352, -387, -610, -1300, -1094, -1629, -983, +-1217, -268, -403, 527, 444, 870, 1087, 849, +1254, 464, 1039, 40, 394, -396, -360, -775, +-848, -985, -1206, -707, -950, 5, -249, 812, +520, 1287, 1047, 1044, 839, 188, 211, -735, +-418, -1220, -615, -1038, -297, -206, 242, 586, +576, 896, 330, 532, -356, -149, -934, -567, +-800, -291, -41, 377, 806, 741, 1125, 381, +725, -456, -62, -1235, -765, -1147, -819, -152, +-326, 952, 217, 1621, 434, 1168, 169, -46, +-298, -1174, -444, -1461, -147, -773, 429, 281, +887, 1018, 842, 874, 128, 187, -800, -493, +-1181, -697, -934, -237, -219, 329, 530, 652, +899, 481, 915, -73, 547, -567, -99, -765, +-433, -513, -564, -5, -545, 489, -311, 757, +-151, 668, 84, 442, 379, -5, 578, -487, +429, -907, 40, -1122, -230, -645, -332, 310, +-174, 1320, 45, 1672, 87, 965, -185, -319, +-332, -1449, -220, -1744, 58, -889, 495, 465, +505, 1413, 311, 1426, -12, 400, -457, -816, +-456, -1288, -168, -669, 172, 490, 333, 1224, +-100, 927, -560, -234, -589, -1275, -46, -1370, +833, -495, 1354, 801, 1092, 1615, 41, 1395, +-1281, 287, -2097, -1020, -1570, -1607, -150, -1268, +1279, -168, 2029, 859, 1676, 1233, 574, 941, +-668, 210, -1392, -428, -1444, -706, -949, -686, +-151, -433, 451, 0, 874, 382, 1035, 630, +861, 556, 423, 86, -233, -413, -787, -626, +-1096, -511, -971, 34, -242, 559, 569, 676, +977, 367, 845, -267, 286, -840, -216, -776, +-433, -154, -437, 576, -230, 916, 37, 559, +108, 11, -14, -515, -96, -612, 117, -319, +306, -68, 249, 160, -56, 131, -313, 6, +-255, 72, 23, 363, 291, 637, 358, 437, +164, -272, -325, -1062, -688, -1260, -593, -597, +42, 594, 769, 1497, 992, 1395, 568, 505, +-321, -646, -922, -1372, -967, -1129, -487, -391, +447, 421, 942, 914, 801, 768, 191, 330, +-627, -11, -810, -330, -463, -455, 32, -385, +570, -397, 674, -83, 374, 355, -111, 611, +-540, 614, -587, 203, -271, -443, -45, -769, +134, -613, 395, -94, 499, 644, 514, 815, +168, 447, -329, -178, -712, -788, -777, -706, +-417, -195, 177, 430, 800, 824, 909, 519, +446, -85, -245, -645, -710, -794, -622, -269, +-167, 328, 296, 630, 502, 584, 312, 247, +-153, -233, -557, -571, -424, -678, 149, -495, +573, 79, 601, 583, 127, 844, -348, 596, +-354, 81, -207, -410, -55, -714, -49, -682, +-200, -428, -318, 40, 8, 433, 622, 688, +1047, 699, 884, 431, -52, -25, -1163, -493, +-1650, -834, -1126, -842, 82, -389, 1253, 239, +1604, 784, 1016, 879, -56, 477, -874, 15, +-923, -323, -471, -339, 5, -299, 108, -434, +-156, -466, -227, -295, 73, 215, 596, 796, +1058, 1023, 805, 731, -118, -101, -1020, -900, +-1442, -1246, -879, -827, 222, 185, 862, 987, +860, 1087, 360, 415, -109, -556, -86, -1050, +181, -479, 242, 401, -159, 1059, -774, 866, +-1080, -182, -701, -1065, 318, -1233, 1239, -516, +1480, 502, 807, 1070, -341, 945, -1195, 324, +-1229, -334, -522, -450, 263, -224, 646, -87, +453, -255, 37, -621, -114, -744, 39, -101, +330, 1022, 393, 1733, 48, 1444, -417, 134, +-782, -1457, -679, -2320, -58, -1724, 516, -124, +735, 1503, 462, 2131, -22, 1423, -116, -56, +29, -1187, 23, -1243, -166, -561, -551, 291, +-749, 464, -372, -10, 282, -402, 915, -348, +1108, 271, 618, 950, -176, 944, -845, 291, +-1135, -621, -730, -1301, 7, -1056, 535, -179, +836, 696, 608, 1046, 50, 662, -265, -22, +-313, -460, -222, -389, -83, -109, 16, 87, +-85, 145, -177, -20, -21, -259, 140, -226, +239, -120, 310, 128, 143, 411, -84, 445, +-176, 302, -255, -14, -255, -279, -134, -556, +89, -557, 230, -287, 210, 123, 78, 533, +-74, 752, -144, 512, -43, -16, 111, -497, +212, -683, 132, -372, -223, 106, -468, 308, +-400, 209, -13, -54, 490, -181, 679, 115, +427, 391, -133, 502, -605, 143, -694, -480, +-382, -911, 295, -803, 773, -15, 637, 800, +47, 1143, -659, 775, -873, -172, -368, -889, +397, -948, 931, -523, 778, 250, 103, 672, +-640, 505, -958, 125, -554, -191, 92, -154, +513, 140, 517, 190, 185, -120, -50, -597, +-4, -744, 105, -233, 191, 659, -93, 1292, +-589, 1062, -802, -65, -595, -1287, 144, -1651, +1048, -861, 1393, 567, 874, 1620, -246, 1424, +-1284, 277, -1557, -969, -869, -1469, 284, -790, +1127, 354, 1229, 1126, 593, 964, -275, 37, +-786, -918, -630, -1076, -67, -336, 275, 702, +270, 1287, -61, 795, -401, -327, -323, -1257, +50, -1273, 592, -288, 812, 852, 405, 1349, +-387, 935, -1001, -130, -936, -1019, -244, -1145, +589, -531, 961, 369, 704, 977, 52, 878, +-640, 312, -807, -395, -343, -831, 207, -707, +573, -303, 501, 233, 38, 655, -310, 717, +-479, 497, -411, 77, 66, -465, 451, -861, +474, -786, 242, -284, -171, 430, -375, 901, +-327, 761, -248, 289, 12, -280, 226, -579, +329, -406, 361, -197, 31, 8, -227, 58, +-327, -117, -401, -19, -122, 272, 169, 546, +381, 625, 489, 190, 185, -406, -216, -838, +-525, -875, -533, -391, -227, 212, 175, 721, +489, 907, 591, 605, 376, 138, -47, -354, +-507, -689, -726, -708, -528, -512, -69, -167, +495, 273, 687, 698, 486, 865, 115, 630, +-301, -12, -422, -733, -397, -1032, -305, -656, +-7, 75, 139, 605, 283, 697, 364, 339, +188, -34, 100, -277, -66, -344, -333, -178, +-354, -22, -261, 102, -100, 177, 206, 66, +352, -23, 253, -12, 127, -45, -45, -115, +-121, -170, -68, -43, -103, 189, -247, 376, +-344, 348, -138, 24, 244, -424, 557, -643, +593, -467, 224, -6, -342, 552, -725, 789, +-737, 547, -194, -38, 498, -569, 730, -719, +470, -446, -66, 32, -358, 395, -269, 444, +-142, 293, -52, 75, 3, -128, -64, -210, +-64, -210, 155, -126, 315, -5, 372, 90, +94, 112, -438, 64, -640, -6, -412, -23, +116, 2, 583, 60, 646, 120, 286, 2, +-337, -149, -793, -189, -624, -144, 33, 93, +704, 328, 748, 219, 160, -74, -478, -376, +-706, -383, -369, 17, 231, 477, 538, 663, +347, 248, -55, -458, -371, -923, -346, -769, +-66, -46, 238, 794, 389, 1167, 208, 781, +-107, -62, -455, -913, -563, -1183, -147, -796, +327, 21, 550, 767, 492, 1024, 149, 764, +-197, 159, -471, -449, -615, -795, -527, -749, +-83, -389, 585, 188, 886, 641, 677, 736, +70, 386, -598, -179, -920, -586, -721, -589, +-98, -100, 615, 436, 981, 618, 605, 298, +-270, -401, -889, -906, -801, -706, -44, 99, +767, 1013, 926, 1315, 332, 695, -529, -471, +-994, -1396, -785, -1433, -71, -526, 635, 664, +940, 1370, 702, 1213, 36, 317, -511, -658, +-734, -1039, -562, -724, -117, -24, 149, 592, +259, 581, 235, 91, 237, -383, 249, -526, +164, -125, 33, 459, -278, 752, -441, 550, +-391, -111, -300, -739, -53, -983, 180, -666, +390, 56, 539, 728, 453, 1026, 206, 837, +-284, 226, -690, -504, -801, -997, -608, -955, +2, -413, 672, 308, 957, 821, 650, 806, +-85, 385, -631, -125, -659, -498, -248, -509, +307, -231, 351, 38, -27, 225, -393, 103, +-515, -25, -111, -15, 545, 72, 881, 253, +603, 201, -76, -100, -781, -379, -1030, -401, +-585, -141, 175, 305, 691, 541, 684, 365, +189, -69, -303, -495, -336, -580, -42, -316, +386, 188, 378, 644, -179, 684, -671, 321, +-791, -245, -303, -670, 432, -686, 816, -319, +735, 106, 213, 382, -271, 510, -453, 439, +-419, 300, -184, 60, -41, -265, -118, -630, +-210, -778, -37, -488, 337, 117, 623, 724, +681, 965, 291, 651, -307, 24, -793, -485, +-986, -777, -616, -671, 7, -293, 614, 111, +844, 466, 597, 568, 292, 453, -74, 259, +-390, -107, -557, -417, -624, -498, -427, -415, +-66, -119, 298, 246, 594, 392, 561, 360, +251, 190, -95, -119, -352, -261, -356, -172, +-191, 5, -101, 136, -128, 47, -144, -180, +-38, -255, 163, -128, 349, 160, 448, 440, +297, 465, -90, 152, -510, -300, -708, -634, +-392, -569, 181, -109, 494, 376, 443, 629, +82, 541, -264, 132, -296, -322, -145, -559, +124, -536, 324, -188, 239, 232, -95, 508, +-389, 518, -401, 219, -141, -128, 149, -415, +228, -505, 211, -251, 146, 52, 38, 273, +12, 408, 6, 293, -41, 28, -158, -172, +-348, -239, -362, -157, -188, -54, 111, -40, +368, -89, 473, -75, 565, 117, 324, 327, +-192, 446, -637, 315, -881, -71, -757, -561, +-283, -876, 393, -657, 1010, 65, 1185, 892, +738, 1207, -154, 772, -1016, -167, -1337, -981, +-1020, -1171, -181, -736, 750, 95, 1201, 771, +982, 994, 253, 737, -553, 137, -927, -508, +-790, -858, -210, -724, 363, -219, 586, 386, +432, 663, -59, 546, -333, 144, -302, -243, +-147, -403, 70, -360, 79, -116, 113, 171, +174, 270, 104, 194, 67, 26, -120, -132, +-391, -151, -563, -151, -447, -81, 78, 105, +732, 244, 1043, 276, 687, 123, -220, -205, +-1004, -372, -1238, -347, -806, -141, 153, 213, +954, 452, 1144, 423, 635, 114, -136, -241, +-683, -464, -760, -400, -346, -70, 97, 273, +246, 477, 176, 389, -39, -50, -111, -471, +95, -567, 316, -242, 275, 317, -6, 639, +-263, 576, -421, 173, -322, -380, -120, -734, +93, -731, 316, -320, 288, 363, 155, 836, +51, 879, -59, 433, -110, -247, -196, -732, +-336, -856, -266, -525, 1, -21, 294, 430, +389, 690, 220, 622, -70, 277, -309, -151, +-263, -458, -79, -483, 67, -264, 196, -79, +78, 14, -155, 71, -219, 203, -214, 385, +71, 384, 338, 129, 307, -190, 76, -427, +-270, -448, -449, -211, -306, 57, 53, 293, +266, 361, 298, 221, 121, 1, -197, -230, +-317, -282, -202, -125, 111, 131, 364, 334, +268, 283, -97, -78, -485, -487, -490, -593, +-123, -303, 321, 331, 541, 847, 384, 805, +-29, 280, -483, -454, -640, -910, -315, -810, +268, -295, 721, 248, 541, 624, -151, 739, +-655, 516, -724, 56, -258, -390, 400, -599, +739, -526, 670, -182, 134, 108, -579, 191, +-870, 258, -621, 344, 38, 391, 646, 230, +705, -146, 327, -545, -216, -672, -552, -377, +-443, 171, 6, 560, 371, 577, 428, 312, +60, -55, -462, -299, -591, -416, -332, -327, +234, -130, 703, 117, 720, 368, 307, 391, +-382, 201, -892, -89, -827, -385, -279, -422, +402, -199, 751, 159, 586, 489, 103, 424, +-291, 93, -416, -303, -327, -538, -45, -382, +171, 31, 176, 423, -69, 563, -288, 228, +-295, -266, -35, -498, 360, -347, 519, 135, +355, 441, -7, 305, -453, -129, -759, -478, +-597, -390, -58, 76, 436, 568, 595, 669, +425, 206, 149, -476, -164, -900, -355, -676, +-298, 46, -188, 757, -90, 984, -93, 511, +-127, -308, 65, -858, 395, -777, 501, -221, +204, 471, -183, 723, -445, 434, -551, -48, +-304, -404, 44, -455, 380, -176, 542, 144, +232, 265, -190, 268, -415, 57, -411, -86, +-103, -108, 329, -129, 482, -117, 305, -124, +-123, -45, -528, 134, -528, 339, -212, 343, +100, 99, 338, -268, 482, -501, 446, -417, +224, -22, -232, 440, -595, 532, -730, 199, +-569, -291, 25, -495, 579, -186, 915, 353, +778, 571, 103, 242, -599, -402, -975, -803, +-858, -618, -241, 48, 505, 765, 931, 1020, +812, 639, 175, -142, -601, -873, -890, -1103, +-601, -665, -39, 86, 539, 789, 608, 1004, +314, 644, -132, -20, -412, -593, -227, -755, +-31, -492, -26, -48, -160, 293, -244, 396, +-34, 264, 346, 133, 539, 27, 477, -46, +71, -136, -553, -222, -1008, -242, -885, -122, +-123, 102, 727, 235, 1132, 226, 883, 115, +168, -12, -577, -89, -954, -120, -884, -192, +-425, -196, 228, -87, 660, 96, 672, 340, +486, 438, 101, 217, -254, -187, -428, -513, +-587, -582, -419, -250, -78, 236, 246, 576, +541, 594, 503, 300, 187, -101, -233, -491, +-506, -644, -376, -498, -93, -30, 204, 448, +321, 714, 179, 598, 3, 73, -224, -458, +-295, -660, -97, -438, 117, -16, 241, 339, +146, 413, -18, 238, -81, -3, -101, -143, +-86, -183, -113, -111, -108, 7, -33, 74, +56, 71, 124, -2, 162, -70, 158, -74, +60, -32, -154, 87, -297, 167, -320, 131, +-154, -3, 98, -185, 263, -199, 324, -100, +169, 18, -70, 108, -285, 145, -293, 129, +-108, 57, 62, -38, 111, -132, 64, -178, +-17, -96, -63, 20, -23, 77, 41, 146, +88, 137, 2, 57, -61, -26, -122, -112, +-135, -170, -45, -207, -4, -101, 22, 92, +110, 298, 148, 406, 57, 231, -61, -169, +-151, -520, -180, -577, -109, -268, 19, 276, +109, 686, 190, 663, 77, 182, -98, -383, +-137, -676, -87, -539, 18, -77, 86, 368, +19, 504, -56, 310, -60, -45, -100, -258, +-14, -195, 141, 5, 183, 110, 102, 20, +-79, -86, -262, -111, -273, -1, -108, 38, +111, -15, 283, 12, 293, 125, 100, 271, +-139, 286, -204, 15, -196, -402, -143, -628, +-43, -483, -16, 25, 67, 580, 206, 753, +278, 480, 270, -7, 50, -402, -324, -477, +-604, -400, -515, -278, -29, -104, 418, 157, +613, 452, 448, 626, 56, 456, -315, -26, +-524, -468, -400, -590, -167, -336, 147, 10, +351, 156, 250, 31, 100, -1, -112, 155, +-175, 446, -55, 566, 41, 197, 80, -388, +-36, -846, -172, -827, -233, -257, -226, 468, +-4, 810, 385, 691, 640, 225, 434, -248, +-229, -410, -809, -421, -887, -306, -264, -104, +523, 109, 855, 307, 668, 320, 56, 88, +-521, -148, -756, -161, -502, 24, 83, 230, +514, 198, 537, -173, 191, -505, -192, -413, +-259, -21, -251, 492, -123, 634, 96, 274, +90, -186, 135, -534, 52, -477, -83, -22, +22, 313, 66, 384, 103, 213, 80, -170, +-195, -300, -359, -206, -294, -66, -28, 49, +439, 166, 602, 301, 354, 380, -108, 185, +-507, -277, -575, -683, -348, -709, -8, -182, +330, 510, 513, 892, 445, 691, 155, 126, +-245, -443, -478, -712, -350, -593, -67, -261, +107, 148, 149, 476, 18, 587, 49, 443, +141, 73, 178, -343, 140, -518, -63, -407, +-200, -114, -351, 198, -365, 273, -67, 138, +234, 42, 470, 137, 440, 268, 31, 184, +-286, -284, -368, -712, -260, -613, -83, -8, +78, 677, 141, 837, 205, 395, 219, -187, +26, -470, -160, -519, -241, -320, -128, -84, +112, 119, 156, 353, 59, 432, -77, 292, +-117, 35, -41, -218, 45, -398, 159, -398, +187, -216, 93, 90, -191, 341, -434, 409, +-329, 237, 162, -15, 597, -149, 550, -179, +34, -231, -476, -262, -580, -169, -349, 111, +103, 435, 441, 473, 562, 161, 339, -252, +-129, -420, -522, -301, -526, -46, -120, 103, +268, 130, 438, 211, 297, 237, -32, 120, +-270, -92, -271, -341, -62, -353, 219, -60, +259, 230, 67, 342, -192, 187, -268, -96, +-86, -204, 138, -97, 233, 60, 119, 88, +-34, -53, -111, -157, -86, -55, 39, 123, +94, 240, -46, 128, -138, -105, -117, -200, +45, -155, 249, 22, 200, 158, -2, 107, +-143, -34, -145, -117, -67, -111, 1, 45, +57, 195, 113, 148, 103, -22, -64, -217, +-172, -283, -40, -132, 189, 148, 284, 352, +69, 305, -222, 19, -324, -271, -228, -361, +81, -187, 363, 96, 347, 245, 81, 185, +-260, 7, -353, -94, -101, -48, 286, 56, +383, 115, 82, 19, -262, -197, -466, -318, +-291, -242, 140, 38, 485, 408, 626, 559, +402, 401, -160, -53, -667, -567, -808, -727, +-455, -475, 226, 50, 756, 524, 855, 689, +469, 432, -90, 39, -577, -310, -706, -439, +-421, -327, -32, -120, 265, 84, 366, 27, +317, -3, 314, 120, 318, 342, 67, 493, +-295, 277, -644, -235, -691, -708, -301, -733, +356, -280, 824, 339, 862, 674, 391, 550, +-346, 232, -722, -125, -697, -315, -250, -350, +225, -363, 474, -221, 444, 120, 179, 426, +-80, 474, -179, 187, -81, -241, -29, -420, +-74, -256, -149, 108, -87, 332, 159, 206, +350, -78, 219, -265, -103, -258, -343, -26, +-264, 140, 93, 273, 429, 328, 407, 190, +-2, -186, -464, -577, -553, -606, -130, -118, +402, 610, 596, 844, 290, 445, -141, -321, +-376, -739, -235, -594, -61, -62, 127, 418, +299, 523, 180, 224, -71, -214, -281, -417, +-266, -265, 35, 242, 418, 576, 482, 438, +267, -193, -174, -805, -557, -925, -674, -299, +-363, 666, 308, 1205, 919, 958, 963, 136, +249, -706, -562, -1143, -874, -937, -674, -304, +-121, 448, 381, 981, 662, 946, 666, 348, +290, -259, -271, -535, -652, -494, -466, -313, +-64, -252, 336, -122, 439, 199, 223, 524, +-39, 576, -261, 311, -279, -120, 71, -446, +364, -385, 251, -232, -109, -25, -367, 68, +-146, 114, 206, 196, 289, 288, 24, 213, +-179, -125, -88, -331, 97, -307, 149, 43, +127, 310, 21, 323, -106, -41, -190, -367, +-93, -358, 122, -88, 275, 256, 207, 462, +-63, 284, -239, -65, -200, -230, -6, -283, +177, -164, 357, -46, 230, 121, -48, 222, +-265, 217, -313, -27, -140, -314, 87, -338, +200, 67, 213, 499, 271, 554, 215, 135, +43, -485, -161, -774, -416, -518, -415, 19, +-88, 498, 296, 742, 547, 573, 393, 147, +34, -417, -241, -722, -247, -703, -75, -207, +74, 463, 104, 740, 22, 459, -62, 18, +-177, -391, -114, -579, 153, -250, 470, 162, +479, 467, 223, 502, -231, 66, -621, -511, +-577, -693, -216, -268, 242, 392, 479, 733, +509, 471, 320, -187, 189, -614, 17, -451, +-238, 74, -522, 431, -587, 380, -320, -107, +228, -459, 737, -315, 775, 56, 453, 349, +-188, 442, -612, 129, -600, -214, -193, -298, +305, -228, 434, 43, 175, 136, -57, -16, +-222, -213, -90, -68, 223, 334, 325, 579, +209, 337, -87, -303, -316, -846, -278, -755, +21, -60, 208, 725, 139, 1102, 12, 675, +-36, -372, -4, -1266, 169, -1238, 298, -240, +306, 1152, 87, 1764, -403, 968, -814, -696, +-513, -1951, 270, -1718, 963, -91, 1025, 1704, +271, 2129, -603, 844, -897, -1033, -474, -1987, +193, -1388, 615, 257, 484, 1551, 23, 1505, +-419, 377, -355, -877, 97, -1415, 509, -865, +587, 337, 21, 1150, -617, 1066, -728, 136, +-210, -896, 604, -1169, 915, -325, 493, 851, +-256, 1298, -831, 469, -712, -953, 1, -1617, +589, -887, 938, 772, 563, 1876, -210, 1524, +-742, -43, -773, -1621, -125, -1976, 420, -808, +580, 817, 369, 1708, 32, 1293, -192, -28, +-106, -1103, 24, -1111, 87, -276, -9, 677, +-281, 985, -376, 292, -74, -733, 482, -1157, +772, -507, 541, 761, -87, 1489, -720, 940, +-797, -418, -281, -1468, 389, -1285, 807, -101, +575, 1139, -52, 1369, -503, 466, -468, -777, +5, -1350, 494, -769, 471, 442, -9, 1354, +-513, 1150, -501, 69, 43, -1133, 630, -1453, +671, -613, 205, 685, -400, 1405, -698, 846, +-470, -402, 78, -1159, 635, -682, 846, 467, +461, 1175, -233, 692, -738, -549, -710, -1372, +-154, -1184, 293, 5, 562, 1223, 588, 1585, +383, 916, -42, -274, -376, -1207, -426, -1401, +-292, -809, -110, 160, 4, 986, 278, 1126, +596, 584, 659, -224, 207, -632, -436, -423, +-793, 66, -612, 186, -19, -190, 655, -566, +930, -456, 504, 231, -272, 1014, -817, 1204, +-633, 449, 8, -728, 556, -1546, 642, -1228, +417, -105, -25, 1054, -490, 1461, -580, 883, +-159, -197, 338, -1018, 417, -1152, 194, -588, +-53, 385, -17, 932, 107, 897, 119, 270, +-13, -475, -111, -849, -248, -641, -322, -65, +-91, 531, 518, 731, 712, 369, 377, -143, +-192, -412, -588, -355, -420, -120, -60, 46, +247, 57, 405, 155, 342, 118, 0, 51, +-307, 36, -293, 10, 130, 34, 428, 1, +381, -150, -70, -266, -374, -131, -463, 46, +-184, 255, 348, 293, 677, 155, 534, -25, +-81, -215, -564, -163, -522, -125, -57, -50, +327, -28, 454, 20, 312, 84, 131, 233, +-165, 263, -402, 109, -350, -28, -19, -349, +363, -581, 407, -449, 295, 147, 189, 706, +-83, 915, -300, 470, -409, -409, -290, -1029, +-24, -965, 345, -284, 537, 623, 467, 1136, +161, 869, -152, 5, -350, -812, -329, -965, +-249, -453, -169, 233, 151, 562, 463, 499, +643, 120, 313, -168, -117, -205, -345, -70, +-289, 111, -165, 96, -142, -196, -102, -436, +220, -351, 454, 179, 474, 753, 250, 820, +-93, 230, -339, -692, -400, -1173, -259, -720, +-26, 278, 286, 1018, 419, 1056, 351, 235, +152, -636, -94, -907, -304, -575, -205, 40, +-80, 622, 75, 765, 165, 319, 209, -242, +195, -705, 90, -650, -80, -20, -136, 663, +-119, 795, -86, 120, 68, -610, 283, -865, +425, -252, 331, 721, -257, 1029, -778, 328, +-527, -791, 132, -1156, 820, -633, 979, 647, +420, 1386, -469, 906, -957, -300, -772, -1266, +-37, -1187, 704, -177, 961, 999, 429, 1261, +-319, 564, -558, -648, -284, -1241, 213, -837, +408, 287, 195, 1274, -286, 1185, -507, 34, +-264, -1271, 249, -1567, 903, -562, 961, 1040, +200, 1882, -803, 1137, -1286, -521, -774, -1821, +279, -1588, 1129, -4, 1198, 1474, 435, 1619, +-573, 342, -880, -1155, -456, -1586, 226, -439, +531, 1020, 214, 1680, -248, 779, -349, -849, +17, -1892, 464, -1407, 649, 270, 345, 1757, +-286, 1962, -823, 534, -680, -1138, 85, -1895, +739, -1131, 855, 427, 206, 1502, -450, 1189, +-633, -107, -263, -1299, 366, -1202, 642, 13, +560, 1301, -38, 1653, -581, 535, -824, -1172, +-540, -2005, 319, -1472, 1166, 93, 1127, 1797, +398, 2121, -529, 1007, -1193, -604, -877, -1741, +-192, -1548, 505, -467, 929, 559, 867, 1093, +402, 866, -289, 362, -752, -179, -680, -540, +-289, -598, 312, -413, 655, -182, 598, 253, +312, 662, -242, 852, -583, 482, -505, -455, +-6, -1375, 582, -1454, 679, -288, 244, 1215, +-301, 2118, -509, 1479, -259, -233, 44, -1799, +418, -2143, 375, -1103, 84, 577, -190, 1573, +-297, 1431, 69, 567, 411, -299, 473, -603, +4, -484, -468, -363, -649, -410, -378, -516, +274, -334, 961, 380, 1057, 1185, 361, 1429, +-698, 692, -1254, -744, -825, -1830, 233, -1574, +1137, -296, 1036, 1148, 236, 1573, -611, 831, +-854, -275, -346, -1013, 506, -753, 976, 59, +528, 680, -450, 558, -1138, -307, -862, -990, +358, -816, 1347, 363, 1315, 1440, 261, 1452, +-790, 210, -1274, -1405, -905, -2045, 138, -1138, +950, 682, 1111, 1973, 481, 1887, -377, 341, +-764, -1375, -228, -1886, 416, -969, 543, 489, +-17, 1438, -798, 969, -914, -203, -7, -952, +1371, -730, 1856, 311, 889, 1015, -987, 718, +-2238, -371, -1838, -1269, -45, -1100, 1715, -76, +2327, 1087, 1560, 1510, -400, 786, -1984, -571, +-2039, -1476, -524, -1317, 1286, -148, 1889, 1309, +920, 1589, -597, 533, -1153, -1050, -714, -1775, +168, -1108, 790, 555, 950, 1804, 331, 1688, +-698, 336, -977, -1236, -460, -1833, 469, -1271, +967, 128, 642, 1165, -50, 1420, -501, 790, +-472, -270, -147, -878, 381, -813, 604, -193, +162, 436, -554, 464, -542, -108, 56, -606, +666, -509, 664, 194, 119, 964, -258, 1023, +-461, 349, -310, -777, -50, -1359, 381, -940, +550, 57, 196, 944, -338, 1040, -447, 318, +4, -470, 443, -635, 640, -291, 281, 504, +-207, 733, -574, 170, -756, -727, -271, -1361, +591, -882, 1028, 426, 745, 1679, 14, 1807, +-531, 660, -588, -936, -314, -2004, 10, -1777, +199, -305, 323, 1244, 235, 1790, 1, 1114, +117, -294, 388, -1285, 379, -1113, 12, 26, +-579, 994, -768, 1058, -473, 83, 202, -1308, +871, -1808, 1053, -711, 665, 1130, -96, 2364, +-856, 2176, -975, 215, -422, -1875, 335, -2749, +860, -2007, 595, -38, 14, 1719, -402, 2262, +-207, 1533, 323, 265, 569, -735, 235, -1198, +-358, -1205, -758, -903, -595, -486, -27, 206, +599, 864, 1075, 1183, 986, 1248, 371, 734, +-658, -191, -1207, -1192, -1043, -1813, -310, -1451, +677, -357, 1243, 1017, 1149, 1816, 475, 1588, +-492, 545, -1094, -678, -908, -1413, -149, -1290, +615, -555, 921, 317, 625, 863, 2, 825, +-556, 409, -647, -232, -275, -601, 423, -567, +915, -103, 635, 393, 67, 647, -580, 510, +-900, -123, -682, -837, 47, -1086, 864, -620, +1293, 332, 897, 1220, -3, 1278, -880, 652, +-1238, -304, -690, -1171, 59, -1322, 902, -857, +1144, 83, 741, 994, 29, 1171, -773, 717, +-810, -48, -364, -624, 272, -694, 809, -427, +743, -122, 95, 194, -586, 260, -778, 139, +-297, 101, 529, 47, 1031, -23, 736, -148, +3, -85, -562, 44, -850, 257, -606, 156, +16, -272, 707, -480, 1039, -401, 672, -2, +-44, 468, -595, 637, -668, 408, -460, -28, +-41, -632, 619, -768, 977, -418, 757, 278, +-85, 838, -918, 722, -1163, -15, -594, -803, +458, -1085, 1384, -496, 1708, 708, 1012, 1480, +-531, 1222, -1930, -113, -2213, -1504, -1311, -2035, +748, -1167, 2625, 527, 3087, 2057, 1733, 2368, +-780, 1149, -2967, -923, -3352, -2549, -1633, -2650, +1007, -962, 3048, 1304, 3239, 2753, 1551, 2519, +-993, 623, -2527, -1646, -2365, -2779, -771, -2089, +1102, -229, 1697, 1776, 1270, 2280, 197, 1470, +-595, -178, -487, -1479, -25, -1632, 410, -906, +194, 157, -435, 902, -898, 835, -463, 404, +809, 48, 1759, -201, 1504, -6, -64, -45, +-1843, -304, -2395, -799, -1188, -974, 1099, -283, +2901, 851, 2850, 1753, 851, 1648, -1901, 239, +-3344, -1341, -2623, -2281, -191, -1957, 2541, -433, +3437, 1474, 2310, 2492, -263, 2051, -2363, 386, +-2575, -1552, -1327, -2327, 587, -1756, 1705, -180, +1597, 1272, 662, 1828, -250, 1262, -752, -99, +-588, -1264, -106, -1396, 205, -667, 409, 575, +346, 1288, 222, 1109, -192, 105, -619, -1152, +-545, -1698, -124, -1126, 850, 316, 1477, 1788, +1218, 2130, 90, 1044, -1289, -678, -2027, -2233, +-1481, -2380, 222, -1120, 1896, 970, 2463, 2476, +1442, 2306, -529, 653, -2149, -1415, -1959, -2540, +-440, -1720, 1471, 214, 2249, 1875, 1120, 2185, +-867, 712, -2375, -1343, -1785, -2430, 430, -1669, +2597, 407, 3081, 2371, 1159, 2609, -1608, 1023, +-3384, -1381, -2764, -2891, -245, -2481, 2379, -497, +3416, 1761, 2130, 2721, -451, 1935, -2179, 102, +-2226, -1557, -918, -2075, 1035, -1373, 1872, -32, +1246, 1020, -229, 1222, -1311, 822, -1212, 39, +-104, -546, 1375, -751, 1719, -605, 807, 34, +-413, 436, -1554, 650, -1622, 329, -424, -342, +886, -663, 1559, -711, 1229, -186, 138, 382, +-643, 850, -842, 984, -250, 426, 261, -481, +472, -1253, 409, -1463, -142, -578, -471, 667, +-493, 1493, -60, 1419, 600, 324, 1111, -738, +937, -1345, 226, -1025, -549, -82, -1118, 636, +-1102, 916, -474, 538, 376, -291, 1067, -788, +1235, -701, 1050, -131, 369, 772, -360, 1179, +-852, 701, -1193, -164, -1054, -1405, -416, -1935, +673, -1283, 1735, 235, 1829, 2116, 1076, 2859, +-374, 1926, -1661, -298, -1735, -2757, -1197, -3747, +157, -2589, 1533, 84, 1875, 3011, 1324, 4296, +179, 3180, -989, 184, -1378, -3166, -1073, -4653, +-387, -3502, 420, -347, 1022, 3005, 1304, 4382, +1189, 3321, 546, 433, -361, -2437, -1560, -3747, +-2144, -3029, -1380, -822, 348, 1599, 2450, 2868, +3398, 2693, 2316, 1277, -379, -713, -3100, -2145, +-4155, -2592, -2590, -1811, 781, -127, 3973, 1672, +4787, 2498, 2639, 2140, -1064, 416, -4150, -1418, +-4555, -2428, -2130, -2133, 1528, -509, 4342, 1179, +4438, 2098, 1677, 1636, -2004, 400, -4086, -878, +-3468, -1435, -624, -1180, 2300, -531, 3617, 355, +2847, 700, 251, 679, -2125, 672, -2957, 291, +-1990, 20, 215, -400, 2150, -1034, 2502, -1100, +1496, -787, -257, 178, -1688, 1422, -1887, 1898, +-1014, 1293, 559, -201, 1690, -1824, 1768, -2499, +886, -1498, -636, 237, -1652, 1795, -1602, 2303, +-517, 1312, 1105, -173, 2129, -1231, 1785, -1616, +509, -947, -1250, -152, -2318, 155, -1886, 316, +-341, 347, 1839, 613, 2761, 1098, 2034, 991, +109, 82, -1771, -1059, -2319, -2308, -1558, -2127, +42, -639, 1523, 1466, 2136, 3125, 1419, 2840, +-28, 620, -1110, -1913, -1231, -3391, -708, -2830, +-44, -416, 620, 1884, 915, 3039, 807, 2301, +382, 270, -230, -1718, -659, -2496, -617, -1928, +-337, -165, 151, 1410, 863, 1878, 1040, 1424, +674, 188, -263, -981, -984, -1391, -930, -1161, +-274, -556, 507, 289, 999, 886, 1019, 1159, +327, 1026, -425, 248, -870, -616, -535, -1242, +264, -1411, 787, -660, 593, 290, -49, 988, +-533, 1204, -550, 828, 73, 99, 720, -340, +1029, -684, 559, -933, -315, -753, -834, -578, +-845, -111, -317, 732, 373, 1297, 750, 1321, +806, 791, 713, -288, 196, -1487, -194, -2000, +-489, -1524, -912, -337, -664, 1191, -76, 2209, +715, 2144, 1288, 837, 1141, -863, 527, -2136, +-423, -2316, -1182, -1246, -1422, 377, -757, 1574, +579, 1860, 1718, 1351, 1722, 112, 851, -875, +-581, -1262, -1546, -1201, -1473, -482, -699, 226, +732, 333, 1577, 479, 1416, 332, 660, 421, +-327, 747, -930, 426, -840, -119, -621, -1052, +-93, -1783, 445, -1467, 758, -255, 906, 1223, +592, 2534, 247, 2280, -119, 795, -517, -1235, +-780, -3031, -660, -3026, -116, -1416, 216, 1108, +686, 3080, 1016, 3283, 953, 1502, 705, -789, +-13, -2673, -774, -2951, -1341, -1623, -1403, 304, +-844, 1944, 370, 2187, 1903, 1290, 2770, -262, +2103, -1212, 127, -945, -2120, -240, -3332, 207, +-2634, 127, -406, -569, 2304, -943, 3817, -630, +3056, 588, 590, 1949, -2085, 2285, -3290, 1261, +-2459, -1126, -323, -3213, 1828, -3373, 2714, -1764, +1890, 1037, 88, 3501, -1443, 3898, -1718, 2158, +-702, -639, 813, -3051, 1436, -3793, 1010, -2286, +-238, -31, -1479, 1820, -1490, 2547, -245, 2005, +1608, 779, 2481, -217, 1896, -845, 13, -1321, +-2332, -1593, -3224, -1557, -2204, -958, 326, 414, +3343, 2038, 4238, 2666, 2561, 2130, -673, 377, +-3717, -1689, -4288, -2999, -2288, -2951, 1153, -1334, +3988, 984, 4225, 2831, 1971, 2996, -1428, 1527, +-3484, -414, -3158, -2123, -1196, -2248, 1424, -1352, +2913, -90, 2700, 1069, 891, 1205, -1340, 838, +-2332, 41, -1718, -514, -66, -443, 1431, -22, +1726, 484, 1147, 436, 187, -305, -909, -831, +-1300, -1119, -883, -612, -55, 375, 725, 985, +1045, 1241, 1118, 967, 856, 353, 32, -401, +-744, -1108, -1436, -1588, -1552, -1489, -526, -874, +665, 508, 1948, 1922, 2484, 2668, 1702, 2166, +7, 300, -2019, -1920, -3089, -3575, -2691, -3306, +-758, -1319, 1884, 1506, 3982, 3849, 4295, 3995, +1989, 1895, -1566, -1109, -4480, -3631, -5038, -3973, +-2633, -2007, 1166, 643, 4671, 2709, 5647, 3073, +3532, 1789, -494, -114, -4219, -1532, -5442, -2115, +-3550, -1733, 174, -580, 3486, 672, 4781, 1505, +3625, 1639, 648, 938, -2401, -239, -3647, -1328, +-2960, -1799, -891, -1457, 1252, -142, 2429, 1584, +2571, 2501, 1620, 2031, 79, 54, -990, -2262, +-1935, -3436, -1946, -2600, -1064, -109, -44, 2793, +1552, 4032, 2507, 2950, 2349, 240, 1120, -2711, +-937, -3935, -2592, -3164, -3058, -893, -1821, 1600, +556, 3050, 2679, 3059, 3666, 1740, 2682, -178, +370, -1721, -2243, -2486, -3615, -2265, -3048, -1304, +-944, -79, 1783, 1225, 3392, 2131, 3304, 2255, +1612, 1582, -825, 276, -2476, -1317, -2816, -2421, +-1718, -2580, 160, -1722, 1499, -68, 2266, 1661, +1856, 2687, 757, 2635, -360, 1347, -1380, -607, +-1600, -2199, -1028, -2796, -76, -2129, 845, -564, +1375, 1189, 1342, 2331, 779, 2358, -225, 1196, +-1208, -517, -1581, -2008, -939, -2272, 469, -1173, +1602, 542, 1952, 1989, 1232, 1996, -359, 549, +-1787, -1367, -2283, -2496, -1307, -1977, 414, 73, +1992, 2236, 2676, 3183, 1843, 2330, 156, -125, +-1495, -2740, -2448, -3965, -2096, -3186, -749, -392, +726, 2571, 1908, 4165, 2369, 3602, 1689, 1021, +557, -1722, -710, -3346, -1713, -3171, -1888, -1561, +-1599, 251, -690, 1341, 765, 1701, 1836, 1544, +2527, 1405, 2215, 1028, 794, 193, -755, -1145, +-2518, -2517, -3245, -3080, -2239, -2167, -182, 170, +2206, 2689, 3796, 4185, 3513, 3622, 1582, 993, +-1333, -2306, -3618, -4410, -4030, -4369, -2336, -1831, +858, 1542, 3359, 3817, 3963, 3989, 2682, 1990, +26, -729, -2469, -2633, -3464, -3023, -2562, -1864, +-228, -109, 1907, 1238, 2906, 1860, 2241, 1474, +598, 660, -885, -197, -1941, -765, -1804, -1031, +-720, -1042, 298, -670, 1326, -119, 1437, 470, +831, 980, 346, 1076, -290, 772, -571, 258, +-587, -504, -558, -1237, -407, -1476, -158, -1168, +174, -309, 751, 954, 1096, 1892, 1107, 2000, +632, 1130, -227, -401, -1069, -1950, -1531, -2483, +-1222, -1827, -433, -293, 755, 1333, 1652, 2135, +1848, 1965, 1347, 1023, 141, -287, -1036, -1280, +-1725, -1696, -1651, -1444, -762, -660, 284, 120, +1163, 785, 1593, 1013, 1344, 1103, 624, 913, +-42, 405, -547, -98, -1058, -910, -1253, -1586, +-948, -1514, -323, -913, 719, 161, 1448, 1332, +1530, 1861, 1233, 1635, 233, 931, -754, -369, +-1547, -1659, -1559, -2207, -688, -1954, 324, -493, +1200, 1124, 1295, 2059, 928, 1976, 359, 828, +-196, -401, -539, -1117, -576, -1222, -469, -857, +-428, -420, -274, -248, -47, -7, 496, 516, +1119, 1125, 1421, 1505, 957, 1127, -218, -158, +-1461, -1685, -2029, -2516, -1509, -1986, -4, -118, +1748, 2000, 2600, 3055, 2088, 2227, 545, 79, +-1411, -2025, -2697, -2987, -2506, -2197, -988, -170, +1260, 1647, 2755, 2419, 2769, 1845, 1465, 195, +-547, -1090, -2001, -1554, -2518, -1114, -1744, -116, +-160, 353, 1265, 247, 2078, -98, 1555, -175, +834, 362, 88, 1053, -629, 1306, -955, 595, +-1264, -771, -1023, -1996, -400, -2174, 216, -1089, +1012, 554, 1549, 1990, 1527, 2294, 914, 1441, +-348, 67, -1329, -1238, -1636, -1724, -1190, -1445, +-290, -750, 561, 129, 1089, 642, 1227, 847, +863, 792, 181, 710, -98, 514, -287, 101, +-366, -437, -329, -1004, -646, -1116, -695, -772, +-488, -158, -9, 455, 749, 643, 1414, 616, +1676, 582, 1280, 587, 106, 593, -1281, 145, +-2178, -713, -2335, -1501, -1218, -1762, 434, -1119, +2078, 317, 3024, 1479, 2351, 2037, 721, 1580, +-1212, 374, -2533, -669, -2366, -1209, -1205, -1179, +281, -848, 1413, -527, 1472, -445, 998, -141, +429, 487, -18, 1357, 108, 1969, 98, 1759, +2, 518, -511, -1269, -1291, -2600, -1529, -2824, +-1042, -1713, 335, 84, 1870, 1706, 2716, 2638, +2191, 2489, 557, 1565, -1256, 236, -2364, -1305, +-2463, -2458, -1602, -2895, -31, -2372, 1218, -626, +2055, 1481, 2225, 3131, 1403, 3583, 480, 2192, +-788, -39, -1852, -2251, -2040, -3468, -1499, -2902, +-110, -1177, 1143, 793, 1633, 2122, 1470, 2305, +504, 1610, -185, 568, -391, -358, -289, -994, +107, -1341, -66, -1343, -578, -1011, -1129, -270, +-1128, 701, -281, 1356, 1116, 1339, 2048, 704, +2008, -197, 1017, -895, -584, -870, -1495, -337, +-1778, 255, -1411, 467, -436, 7, 141, -650, +554, -1021, 1085, -438, 1449, 729, 1718, 1679, +1417, 1746, 99, 646, -1576, -856, -2751, -2003, +-2799, -2140, -1469, -1158, 711, 276, 2648, 1561, +3305, 2009, 2531, 1475, 818, 403, -1145, -721, +-2435, -1260, -2575, -1319, -2022, -858, -703, -254, +859, 105, 1885, 600, 2537, 993, 2038, 987, +771, 762, -597, 106, -1822, -738, -2062, -1124, +-1395, -1104, -469, -639, 514, 61, 1044, 589, +1078, 950, 1187, 939, 915, 665, 487, 55, +-183, -653, -962, -1047, -1453, -1077, -1495, -487, +-720, 248, 385, 877, 1441, 1042, 1844, 659, +1068, 49, -89, -566, -832, -870, -969, -696, +-404, -221, 197, 222, 210, 529, -53, 541, +-390, 384, -537, 177, -40, -106, 615, -418, +1180, -700, 1145, -815, 424, -426, -486, 381, +-1035, 1263, -1242, 1590, -910, 872, -209, -565, +270, -1914, 886, -2186, 1129, -1059, 1054, 781, +889, 2125, 232, 2253, -711, 964, -1403, -798, +-1766, -1800, -1288, -1785, 14, -782, 1231, 525, +1993, 1081, 1867, 993, 802, 495, -419, -159, +-1314, -305, -1587, -292, -1236, -231, -501, -192, +370, -176, 1072, -91, 1269, 90, 887, 267, +287, 238, -250, 7, -551, -164, -627, -143, +-468, 55, -243, 324, -92, 231, 116, -21, +171, -371, 265, -535, 519, -295, 546, 46, +381, 295, 79, 377, -423, 217, -778, 117, +-754, 78, -380, 172, 264, 95, 841, -257, +834, -688, 217, -987, -333, -683, -591, 135, +-135, 1203, 474, 1748, 587, 1370, 275, 61, +-512, -1381, -1090, -2100, -890, -1697, -218, -347, +837, 1094, 1548, 1837, 1266, 1597, 354, 475, +-736, -700, -1379, -1218, -1230, -992, -435, -245, +388, 484, 952, 633, 825, 151, 325, -426, +-185, -731, -276, -361, -1, 570, 160, 1318, +134, 1196, -226, 332, -586, -969, -518, -1745, +-121, -1432, 406, -450, 650, 758, 495, 1440, +191, 1149, -114, 435, -95, -238, -85, -568, +-78, -299, -187, -104, -341, -146, -483, -428, +-280, -777, 180, -682, 510, 75, 916, 1065, +733, 1622, 260, 1383, -90, 391, -615, -888, +-851, -1730, -892, -1711, -759, -1111, -143, 52, +491, 1038, 1245, 1469, 1644, 1493, 1256, 1002, +368, 234, -1031, -718, -2019, -1537, -2038, -1876, +-1141, -1355, 404, -29, 1673, 1349, 2039, 2003, +1477, 1621, 449, 291, -645, -975, -1206, -1410, +-1169, -950, -914, 48, -341, 618, 101, 354, +366, -261, 682, -699, 833, -401, 817, 494, +603, 1294, 122, 1402, -583, 422, -1057, -958, +-1149, -1887, -781, -1637, -121, -380, 521, 1020, +980, 1725, 1124, 1267, 862, 47, 299, -881, +-264, -1056, -744, -355, -964, 527, -956, 722, +-568, 185, 50, -719, 702, -1038, 951, -582, +852, 448, 485, 1317, 64, 1289, -165, 409, +-477, -644, -665, -1318, -729, -1026, -612, -156, +-209, 455, 253, 718, 776, 313, 1175, -132, +1027, -87, 506, 149, -510, 522, -1276, 427, +-1290, -370, -810, -1075, 113, -1163, 937, -393, +1065, 846, 582, 1626, -122, 1318, -529, 141, +-371, -1169, 143, -1724, 527, -1205, 333, 78, +-229, 1302, -762, 1635, -937, 1023, -609, -96, +322, -1178, 1070, -1495, 1235, -884, 748, -78, +-180, 722, -692, 1056, -746, 827, -404, 535, +-56, 141, -121, -367, -304, -917, -382, -1179, +-39, -977, 694, -211, 1408, 851, 1589, 1519, +771, 1439, -806, 565, -2143, -553, -2348, -1226, +-1523, -1291, 205, -703, 1721, 19, 2346, 447, +2141, 694, 768, 655, -615, 575, -1410, 324, +-1885, -76, -1479, -505, -748, -831, -86, -734, +979, -328, 1541, 278, 1618, 716, 1276, 760, +264, 419, -766, -125, -1567, -537, -1657, -563, +-1112, -200, -304, 231, 634, 424, 1248, 237, +1219, -169, 883, -404, 395, -339, -166, -13, +-303, 315, -542, 499, -988, 347, -1109, -59, +-945, -337, -345, -484, 747, -316, 1611, 172, +1965, 457, 1549, 456, 181, 129, -1324, -578, +-2311, -802, -2278, -489, -1086, 265, 454, 1103, +1757, 1251, 2292, 684, 1671, -405, 338, -1485, +-1019, -1762, -1569, -1118, -1297, 102, -434, 1547, +273, 2113, 413, 1682, 360, 425, 89, -1146, +-60, -2087, 314, -2073, 756, -980, 842, 572, +279, 1740, -733, 1983, -1510, 1162, -1457, -214, +-505, -1227, 575, -1366, 1442, -689, 1684, 294, +794, 740, -348, 430, -1157, -143, -1381, -702, +-589, -555, 299, 243, 818, 966, 727, 1272, +209, 731, -338, -504, -663, -1430, -396, -1567, +136, -873, 510, 351, 599, 1223, 391, 1327, +87, 672, -274, -86, -699, -538, -888, -447, +-666, -95, -102, -3, 677, -273, 1226, -583, +1232, -539, 767, -165, -279, 569, -1304, 1050, +-1569, 988, -1132, 568, -60, -128, 951, -700, +1149, -939, 946, -1042, 300, -813, -314, -204, +-290, 492, -201, 1293, -77, 1541, -185, 1064, +-688, 204, -799, -978, -421, -1678, 381, -1533, +1186, -685, 1297, 433, 795, 1175, 65, 1216, +-688, 640, -1095, 61, -1053, -195, -754, -211, +-263, -165, 243, -339, 738, -670, 1076, -864, +1180, -539, 1031, 331, 251, 1121, -925, 1437, +-1784, 1026, -1930, -27, -1157, -929, 202, -1363, +1419, -1151, 2054, -373, 1774, 392, 731, 839, +-465, 929, -1331, 690, -1592, 135, -1424, -342, +-713, -632, 130, -561, 942, -265, 1474, 75, +1320, 263, 860, 105, 38, 7, -739, 24, +-1172, 82, -1294, 296, -792, 334, -193, 66, +375, -215, 884, -593, 1063, -615, 1005, -170, +466, 315, -237, 718, -684, 675, -903, 183, +-879, -417, -577, -719, -170, -465, 332, -40, +704, 387, 824, 474, 868, 325, 657, 102, +92, -154, -638, -314, -1247, -389, -1340, -316, +-847, -166, 31, 143, 996, 410, 1527, 674, +1358, 680, 528, 264, -547, -385, -1143, -1090, +-1154, -1247, -786, -700, -151, 263, 503, 1232, +787, 1532, 745, 1068, 406, 60, -47, -925, +-238, -1407, -415, -1219, -416, -466, -286, 370, +-40, 916, 333, 1014, 413, 618, 246, 159, +-127, -131, -507, -356, -525, -489, -147, -617, +613, -535, 941, -275, 647, 219, 1, 661, +-807, 828, -1142, 555, -899, 84, -278, -367, +634, -614, 1217, -393, 1125, -195, 538, 15, +-334, 67, -833, -57, -1010, 42, -766, 130, +-157, 455, 487, 625, 813, 374, 541, -74, +66, -800, -95, -1032, -134, -670, -58, 57, +-73, 791, -171, 1030, -103, 588, -245, -105, +-348, -612, -73, -545, 277, -3, 588, 393, +569, 329, 57, -280, -275, -852, -444, -760, +-384, 85, -59, 1071, 237, 1507, 264, 976, +-38, -324, -436, -1467, -417, -1692, -28, -948, +553, 385, 945, 1398, 744, 1449, 81, 675, +-765, -395, -1300, -1018, -1179, -831, -372, -139, +592, 537, 1178, 593, 1179, 44, 694, -532, +97, -716, -503, -199, -881, 667, -933, 1159, +-811, 887, -372, -82, 172, -1147, 738, -1422, +1253, -823, 1203, 302, 551, 1307, -318, 1308, +-1275, 512, -1607, -474, -1063, -1057, -65, -839, +931, -104, 1405, 537, 1026, 747, 220, 387, +-450, -205, -778, -498, -612, -514, -237, -133, +51, 264, 226, 462, 137, 494, 41, 287, +72, -55, -8, -411, 35, -652, 74, -652, +117, -213, 175, 400, -5, 869, -154, 962, +-207, 530, -343, -250, -315, -983, -190, -1174, +213, -679, 506, 181, 519, 942, 398, 1136, +18, 668, -291, -95, -467, -680, -536, -794, +-376, -482, -66, -38, 145, 299, 352, 392, +497, 330, 512, 233, 383, 89, 0, -62, +-587, -175, -838, -336, -670, -342, -209, -124, +424, 163, 734, 455, 723, 474, 326, 227, +-233, -256, -520, -590, -593, -460, -323, -117, +139, 387, 428, 711, 581, 464, 299, 9, +-310, -413, -649, -683, -716, -481, -286, -106, +505, 270, 954, 715, 984, 726, 472, 421, +-488, -85, -1132, -718, -1267, -907, -830, -658, +114, -98, 1003, 603, 1495, 1004, 1266, 844, +331, 262, -688, -431, -1341, -860, -1398, -749, +-690, -269, 233, 229, 877, 573, 1142, 552, +869, 311, 221, -13, -399, -296, -768, -309, +-814, -272, -402, -113, 199, 151, 589, 255, +621, 380, 175, 270, -336, -91, -564, -380, +-437, -642, 125, -467, 620, 161, 823, 745, +544, 1073, -218, 710, -862, -228, -1146, -1018, +-836, -1301, -8, -836, 858, 129, 1390, 1001, +1155, 1363, 345, 1048, -585, 193, -1241, -725, +-1085, -1252, -522, -1085, 148, -376, 710, 463, +700, 1052, 401, 912, 158, 316, 11, -317, +36, -651, 8, -414, -196, 26, -494, 324, +-631, 270, -418, -46, -40, -308, 510, -291, +839, -4, 778, 246, 393, 324, -129, 190, +-510, 43, -630, 109, -537, 206, -426, 76, +-163, -305, 143, -790, 491, -923, 870, -373, +846, 602, 461, 1473, -167, 1657, -936, 844, +-1152, -576, -740, -1724, -60, -2003, 670, -1142, +886, 288, 523, 1443, 153, 1804, -56, 1193, +-64, 262, 103, -531, -37, -913, -471, -892, +-743, -860, -694, -669, -154, -151, 677, 610, +1157, 1432, 1121, 1693, 527, 996, -448, -347, +-1156, -1674, -1182, -2055, -619, -1195, 223, 350, +803, 1640, 842, 1827, 466, 891, 11, -471, +-189, -1322, -233, -1200, -103, -276, -97, 722, +-223, 1080, -186, 666, -180, -182, 59, -866, +364, -880, 370, -299, 323, 357, 116, 825, +-116, 782, -189, 326, -245, -98, -208, -431, +-149, -547, -103, -482, 100, -390, 297, -96, +341, 352, 349, 742, 163, 866, -147, 529, +-357, -65, -496, -677, -275, -925, 129, -638, +430, -169, 489, 347, 194, 692, -155, 645, +-358, 409, -312, 81, 7, -260, 306, -423, +394, -376, 222, -226, -210, -33, -451, 117, +-383, 192, -60, 222, 298, 246, 490, 236, +475, 151, 121, 39, -317, -186, -531, -399, +-416, -447, 4, -299, 363, 83, 445, 507, +223, 727, -80, 626, -286, 164, -293, -456, +-55, -876, 164, -849, 299, -305, 204, 479, +12, 1037, -108, 1039, -232, 475, -223, -349, +-149, -1006, -74, -1065, 170, -563, 348, 203, +433, 851, 381, 1080, -14, 821, -449, 182, +-755, -481, -713, -986, -160, -987, 517, -537, +1004, 157, 930, 848, 288, 1073, -452, 856, +-1007, 267, -967, -486, -380, -924, 334, -914, +832, -494, 829, 151, 383, 653, -215, 852, +-614, 632, -597, 170, -258, -229, 105, -449, +286, -462, 275, -307, 187, -119, 88, 34, +-43, 268, -182, 478, -285, 478, -274, 330, +-97, -74, 149, -466, 385, -592, 408, -389, +170, 89, -170, 514, -508, 613, -597, 309, +-271, -107, 142, -387, 411, -385, 477, -156, +330, 134, 95, 281, -165, 257, -348, 197, +-488, 149, -515, 23, -280, -160, 40, -358, +422, -501, 834, -284, 789, 251, 244, 771, +-545, 967, -1216, 589, -1221, -279, -444, -1093, +607, -1251, 1334, -608, 1216, 495, 283, 1321, +-841, 1303, -1418, 453, -1059, -662, -30, -1189, +967, -875, 1236, 53, 631, 875, -371, 928, +-1159, 288, -1243, -520, -516, -836, 447, -436, +1142, 317, 1138, 836, 406, 789, -457, 190, +-1051, -515, -1169, -776, -708, -567, -62, -26, +570, 456, 990, 564, 910, 431, 461, 133, +-180, -120, -869, -139, -1242, -125, -1069, -151, +-375, -171, 525, -230, 1159, -71, 1180, 262, +486, 521, -455, 574, -1137, 294, -1152, -183, +-547, -587, 139, -692, 671, -393, 716, 174, +284, 690, -210, 817, -574, 454, -547, -108, +-195, -579, 168, -708, 247, -355, 98, 171, +-200, 606, -323, 675, -205, 299, -97, -225, +94, -557, 85, -465, -111, -55, -179, 453, +-181, 607, -46, 341, 112, -183, 17, -549, +-155, -465, -248, -36, -313, 496, -255, 652, +-82, 356, 99, -162, 235, -542, 144, -532, +-105, -119, -333, 394, -334, 609, -153, 427, +-60, 12, -82, -375, -163, -437, -249, -212, +-162, 146, 54, 370, 248, 304, 304, 102, +46, -65, -335, -70, -629, -20, -685, -14, +-409, -72, 3, -169, 354, -72, 495, 175, +325, 397, -9, 478, -355, 188, -543, -271, +-567, -619, -490, -538, -248, -54, 71, 488, +353, 734, 392, 486, 147, 44, -141, -387, +-425, -504, -515, -268, -377, 51, -189, 305, +-4, 263, 3, 34, -135, -103, -161, -4, +-19, 253, 151, 420, 194, 275, -91, -220, +-490, -717, -636, -726, -502, -188, -161, 577, +206, 1090, 332, 807, 174, 78, -121, -572, +-391, -859, -406, -482, -179, 150, -22, 468, +-68, 392, -346, 21, -534, -264, -337, -77, +185, 356, 642, 693, 552, 465, -73, -230, +-913, -879, -1336, -1140, -962, -519, 2, 522, +936, 1318, 1201, 1395, 601, 520, -476, -572, +-1306, -1230, -1368, -1073, -699, -270, 191, 573, +723, 919, 689, 602, 262, 12, -271, -360, +-567, -282, -533, 84, -423, 323, -347, 220, +-317, -150, -262, -473, -27, -397, 338, 11, +529, 492, 314, 678, -184, 436, -771, -37, +-1103, -421, -858, -464, -225, -257, 390, 20, +737, 255, 551, 378, 39, 331, -482, 205, +-841, -9, -801, -286, -460, -399, 3, -370, +332, 0, 365, 546, 58, 812, -310, 639, +-492, -83, -543, -840, -297, -1127, 22, -651, +238, 395, 232, 1263, -145, 1409, -520, 598, +-673, -646, -540, -1365, -140, -1106, 233, -95, +351, 891, 245, 1090, -95, 497, -445, -367, +-543, -756, -477, -346, -313, 451, -179, 939, +-100, 573, -37, -398, 81, -1192, 168, -1191, +136, -230, -16, 1059, -311, 1748, -625, 1350, +-838, 82, -629, -1253, -126, -1734, 361, -1101, +667, 143, 440, 1170, -107, 1349, -566, 759, +-800, -108, -637, -631, -248, -576, 40, -210, +140, 71, 52, 79, -157, -66, -213, -56, +-124, 186, -12, 427, 114, 551, -76, 299, +-449, -202, -650, -573, -702, -643, -339, -285, +224, 279, 567, 659, 626, 673, 157, 358, +-594, -141, -1028, -517, -895, -563, -346, -281, +279, 201, 578, 559, 437, 544, -48, 211, +-576, -135, -782, -392, -536, -379, 66, -80, +460, 245, 289, 416, -233, 272, -656, -23, +-621, -254, -230, -235, 265, 70, 488, 335, +214, 350, -415, 111, -952, -324, -875, -533, +-135, -322, 689, 168, 964, 740, 518, 806, +-481, 366, -1276, -259, -1404, -843, -851, -858, +268, -360, 1192, 374, 1296, 938, 643, 929, +-427, 487, -1255, -171, -1396, -689, -996, -829, +-273, -558, 445, 14, 841, 550, 866, 802, +491, 695, -83, 242, -642, -272, -1020, -592, +-997, -611, -653, -279, -107, 188, 489, 504, +780, 486, 626, 223, 182, -18, -360, -188, +-664, -148, -686, 12, -504, 39, -258, 46, +-57, -43, 115, -169, 201, -21, 218, 215, +170, 378, 56, 377, -199, 79, -449, -256, +-551, -480, -449, -347, -126, 75, 144, 449, +245, 548, 168, 230, -97, -193, -297, -392, +-288, -278, -134, 58, 66, 393, 136, 408, +23, 156, -174, -194, -452, -427, -562, -289, +-404, 88, 2, 407, 472, 457, 568, 222, +351, -151, -58, -367, -420, -262, -627, 83, +-718, 424, -557, 338, -180, -82, 248, -422, +610, -440, 692, 9, 452, 596, 16, 774, +-574, 476, -973, -209, -958, -827, -585, -821, +78, -307, 654, 481, 917, 914, 721, 666, +91, 103, -588, -422, -940, -536, -759, -138, +-281, 293, 137, 388, 308, 85, 275, -457, +141, -612, -30, -154, -29, 579, -4, 1103, +-85, 916, -202, 46, -456, -899, -467, -1325, +-195, -917, 90, 80, 404, 1021, 466, 1309, +227, 854, -121, 47, -513, -649, -657, -909, +-435, -630, 25, -107, 391, 336, 498, 542, +309, 474, -195, 294, -621, 64, -657, -142, +-293, -301, 320, -281, 681, -95, 537, 121, +-16, 300, -674, 230, -886, -7, -610, -136, +103, -175, 822, 2, 911, 332, 367, 372, +-498, 145, -1069, -235, -926, -501, -237, -304, +565, 89, 976, 511, 723, 613, -27, 206, +-745, -272, -984, -584, -610, -408, 42, 192, +542, 666, 620, 650, 309, 114, -51, -557, +-307, -811, -334, -444, -226, 314, -179, 947, +-171, 932, -148, 310, -64, -532, 172, -1017, +451, -761, 495, -72, 261, 644, -247, 1015, +-756, 701, -891, 18, -566, -571, 81, -783, +696, -444, 946, 114, 654, 537, -46, 588, +-715, 280, -922, -101, -569, -337, 48, -275, +450, -26, 498, 212, 204, 231, -238, 63, +-431, -93, -297, -124, 111, -3, 560, 173, +491, 279, -71, 188, -641, -66, -931, -322, +-622, -368, 122, -93, 742, 295, 1027, 568, +682, 510, -171, 60, -810, -466, -1007, -671, +-632, -428, 35, 156, 498, 741, 680, 802, +407, 341, -89, -306, -407, -775, -482, -700, +-156, -116, 238, 507, 325, 828, 158, 570, +-241, -39, -501, -468, -483, -551, -193, -181, +349, 230, 661, 351, 564, 203, 111, -124, +-415, -234, -645, 44, -545, 370, -248, 454, +60, 171, 297, -372, 333, -678, 187, -480, +71, 43, 21, 641, 40, 850, -36, 537, +-331, -104, -581, -682, -566, -740, -177, -338, +392, 282, 762, 678, 684, 609, 184, 218, +-381, -257, -785, -544, -707, -447, -240, -52, +184, 382, 511, 593, 403, 481, 14, 86, +-230, -388, -327, -642, -112, -539, 195, -52, +229, 504, 11, 831, -317, 678, -481, 42, +-300, -548, 67, -786, 407, -516, 485, 171, +248, 665, -179, 632, -527, 173, -576, -412, +-287, -615, 167, -210, 473, 423, 500, 829, +120, 650, -369, -105, -637, -912, -572, -1136, +-114, -570, 401, 414, 647, 1251, 518, 1333, +74, 613, -477, -413, -766, -1108, -663, -1127, +-303, -561, 233, 232, 546, 723, 612, 793, +453, 583, -13, 238, -407, -100, -615, -359, +-647, -540, -394, -546, -15, -278, 298, 122, +568, 582, 550, 768, 209, 502, -193, -32, +-543, -574, -619, -692, -389, -321, -79, 233, +258, 619, 402, 579, 195, 122, -59, -339, +-246, -542, -241, -369, -7, 103, 88, 417, +57, 449, -87, 265, -258, -34, -287, -156, +-166, -121, 55, -92, 180, -107, 161, -208, +39, -246, -67, -4, -119, 388, -101, 726, +-80, 705, -132, 170, -180, -512, -259, -980, +-229, -865, 16, -196, 283, 588, 409, 1013, +243, 796, -95, 110, -388, -474, -469, -608, +-332, -272, -150, 220, 15, 352, 105, 85, +99, -347, 130, -508, 185, -158, 214, 460, +94, 928, -258, 817, -598, 99, -715, -712, +-450, -1115, 55, -837, 554, -20, 767, 771, +526, 1047, -13, 677, -588, -22, -831, -528, +-644, -583, -205, -244, 270, 131, 482, 252, +368, 83, 78, -88, -203, -65, -334, 111, +-265, 362, -109, 289, -7, -22, 28, -329, +-55, -444, -150, -149, -147, 274, -88, 498, +64, 372, 159, -73, 107, -471, -9, -501, +-253, -139, -383, 387, -309, 657, -89, 487, +206, 7, 269, -475, 124, -595, -130, -312, +-340, 121, -337, 415, -143, 425, 119, 144, +226, -129, 131, -158, -160, -28, -403, 142, +-304, 168, -46, -26, 188, -264, 264, -319, +51, -137, -237, 182, -384, 413, -352, 414, +-68, 178, 241, -93, 311, -212, 130, -216, +-185, -105, -408, -57, -372, -108, -230, -88, +-41, 49, 170, 292, 251, 480, 243, 464, +44, 159, -187, -287, -324, -623, -447, -670, +-381, -350, -177, 174, 91, 619, 391, 699, +467, 461, 277, 59, -85, -280, -473, -389, +-679, -358, -577, -247, -206, -139, 212, -5, +454, 224, 470, 435, 248, 536, -83, 400, +-396, -30, -552, -446, -470, -628, -238, -489, +78, -57, 272, 340, 312, 507, 174, 436, +-72, 174, -230, -101, -273, -201, -191, -179, +-129, -162, -138, -87, -88, -50, -17, -7, +52, 174, 106, 263, 86, 250, 9, 134, +-104, -94, -233, -246, -302, -245, -265, -130, +-106, 47, 86, 198, 231, 192, 245, 121, +42, 70, -231, -9, -417, -43, -387, -75, +-167, -132, 85, -115, 274, -36, 296, 148, +126, 285, -191, 210, -465, 29, -461, -195, +-234, -309, 97, -131, 319, 129, 270, 237, +83, 230, -153, 41, -287, -161, -253, -146, +-159, -29, -77, 92, -142, 112, -159, -10, +32, -119, 281, -39, 428, 145, 225, 280, +-217, 214, -660, -142, -847, -458, -501, -490, +155, -144, 775, 448, 945, 829, 413, 700, +-400, 92, -959, -682, -953, -1089, -390, -824, +316, -42, 712, 810, 569, 1214, 70, 892, +-398, 111, -478, -630, -218, -992, 41, -796, +91, -309, -118, 195, -301, 571, -230, 699, +80, 620, 448, 377, 506, -38, 105, -466, +-505, -745, -858, -776, -689, -417, -90, 151, +572, 677, 836, 943, 546, 769, -92, 264, +-717, -341, -892, -804, -486, -871, 92, -531, +513, -19, 561, 479, 215, 755, -155, 637, +-384, 319, -448, -49, -250, -397, 12, -513, +137, -414, 200, -243, 128, 58, -3, 298, +-147, 390, -306, 363, -303, 111, -120, -90, +148, -170, 325, -185, 282, -33, 27, 62, +-310, -12, -563, -86, -570, -202, -189, -240, +384, 23, 725, 423, 604, 705, 111, 669, +-485, 130, -853, -687, -794, -1235, -344, -1130, +261, -309, 726, 841, 838, 1609, 476, 1499, +-147, 569, -713, -726, -958, -1627, -709, -1644, +-98, -825, 485, 413, 753, 1363, 649, 1561, +221, 1044, -288, 75, -689, -791, -735, -1154, +-388, -1091, 56, -609, 406, 71, 457, 630, +309, 999, 95, 1073, -164, 675, -327, -26, +-408, -716, -329, -1242, -153, -1168, 47, -526, +278, 321, 361, 1105, 313, 1376, 89, 1024, +-271, 222, -466, -714, -477, -1308, -287, -1293, +52, -724, 302, 240, 395, 1071, 362, 1364, +145, 1110, -170, 274, -394, -695, -574, -1250, +-488, -1298, -110, -718, 294, 324, 660, 1123, +629, 1418, 212, 1051, -303, 17, -816, -945, +-854, -1407, -369, -1203, 300, -332, 844, 678, +802, 1366, 216, 1406, -397, 720, -765, -315, +-719, -1240, -261, -1555, 231, -1080, 559, -75, +562, 968, 203, 1567, -161, 1454, -342, 603, +-445, -479, -330, -1359, -103, -1690, 72, -1145, +275, -79, 343, 996, 219, 1674, 41, 1529, +-194, 653, -395, -404, -325, -1281, -87, -1609, +117, -1158, 213, -240, 65, 763, -60, 1438, +-51, 1420, -23, 768, 147, -164, 209, -990, +50, -1337, -261, -1078, -552, -393, -435, 459, +-3, 1114, 417, 1232, 561, 814, 348, 14, +42, -829, -259, -1213, -423, -1003, -384, -289, +-233, 592, -2, 1091, 120, 1040, 162, 477, +254, -352, 334, -888, 264, -983, -23, -604, +-381, 97, -578, 671, -462, 942, -133, 741, +298, 213, 574, -424, 466, -890, 120, -873, +-280, -468, -379, 170, -165, 765, -18, 986, +-5, 723, -103, 119, -145, -565, 25, -1012, +211, -906, 355, -336, 325, 395, -11, 969, +-395, 987, -545, 447, -344, -275, 131, -837, +471, -935, 418, -456, 142, 208, -209, 737, +-454, 889, -364, 476, 1, -173, 342, -708, +438, -873, 244, -497, -136, 175, -371, 720, +-321, 924, -230, 610, -63, -84, 114, -651, +226, -943, 411, -740, 447, -128, 211, 447, +-193, 829, -697, 851, -876, 518, -506, -2, +194, -501, 897, -856, 1113, -925, 657, -592, +-199, 5, -972, 691, -1170, 1221, -631, 1225, +310, 635, 999, -311, 1002, -1284, 337, -1673, +-568, -1251, -993, -185, -672, 1096, 90, 1870, +827, 1720, 975, 727, 380, -683, -410, -1785, +-916, -1923, -937, -1142, -361, 207, 404, 1448, +859, 1902, 896, 1389, 457, 274, -91, -930, +-417, -1650, -660, -1453, -695, -663, -527, 384, +-197, 1251, 361, 1451, 836, 994, 1002, 107, +831, -835, 244, -1339, -682, -1201, -1356, -505, +-1304, 448, -621, 1229, 440, 1408, 1171, 831, +1157, -174, 743, -1195, 135, -1601, -423, -1002, +-591, 140, -584, 1246, -578, 1707, -488, 1052, +-354, -205, 116, -1286, 885, -1656, 1371, -994, +1278, 214, 424, 1211, -847, 1534, -1769, 942, +-1843, -95, -916, -905, 610, -1243, 1838, -931, +1962, -185, 1007, 415, -409, 798, -1438, 937, +-1448, 649, -716, 197, 184, -271, 837, -822, +861, -1071, 431, -815, -49, -236, -417, 641, +-484, 1311, -231, 1270, 69, 648, 321, -337, +467, -1200, 360, -1402, 35, -909, -410, -40, +-767, 810, -771, 1243, -290, 1042, 567, 468, +1304, -255, 1379, -905, 694, -1092, -512, -849, +-1634, -234, -1926, 555, -1133, 1052, 391, 1082, +1771, 642, 2147, -176, 1382, -939, -80, -1196, +-1411, -903, -1917, -123, -1495, 771, -349, 1195, +931, 1042, 1588, 405, 1386, -481, 664, -1039, +-233, -1047, -963, -600, -1205, 134, -1050, 683, +-433, 880, 487, 735, 1107, 333, 1352, -145, +1106, -565, 164, -764, -945, -751, -1744, -414, +-1795, 184, -732, 696, 836, 996, 2065, 837, +2383, 208, 1383, -430, -464, -916, -2127, -1002, +-2776, -570, -1935, 96, -80, 713, 1739, 1005, +2746, 762, 2468, 122, 988, -452, -901, -753, +-2362, -631, -2729, -166, -1786, 204, -119, 376, +1501, 349, 2533, 148, 2528, 5, 1387, -12, +-431, -77, -2111, -82, -2873, -61, -2256, -143, +-553, -84, 1380, 8, 2743, 64, 2826, 167, +1475, 177, -608, 69, -2345, -56, -2838, -154, +-1889, -162, -113, -57, 1596, 81, 2528, 172, +2196, 175, 781, 44, -872, -147, -2037, -189, +-2138, -171, -1174, -75, 165, 162, 1372, 196, +2030, 168, 1727, 161, 561, -7, -881, -81, +-1935, -104, -2039, -235, -1090, -296, 367, -192, +1699, -5, 2340, 299, 1808, 618, 283, 592, +-1492, 265, -2617, -256, -2369, -840, -813, -986, +1192, -618, 2630, 109, 2843, 919, 1589, 1243, +-578, 886, -2495, 132, -3235, -745, -2278, -1236, +-31, -987, 2201, -336, 3360, 391, 2868, 886, +822, 888, -1601, 542, -3220, 118, -3272, -323, +-1549, -650, 896, -729, 2843, -583, 3424, -179, +2223, 391, -15, 808, -2158, 899, -3251, 561, +-2674, -134, -833, -770, 1280, -1024, 2743, -769, +2918, -66, 1751, 705, -178, 1042, -1970, 830, +-2876, 180, -2446, -605, -897, -979, 1036, -792, +2590, -239, 3016, 473, 1987, 888, -67, 781, +-2173, 341, -3235, -310, -2666, -824, -756, -861, +1551, -470, 3157, 184, 3186, 807, 1528, 986, +-921, 629, -2806, -61, -3218, -791, -1998, -1082, +171, -753, 2166, -73, 3092, 662, 2505, 1078, +701, 897, -1435, 323, -2802, -374, -2791, -960, +-1458, -1052, 567, -672, 2367, 33, 3111, 764, +2301, 1148, 312, 1004, -1892, 355, -3190, -431, +-2832, -1087, -1065, -1210, 1249, -749, 2967, -1, +3218, 839, 1856, 1327, -442, 1145, -2435, 466, +-3173, -470, -2348, -1278, -499, -1422, 1467, -932, +2801, 1, 2875, 1061, 1655, 1651, -295, 1488, +-2180, 597, -3092, -793, -2622, -1896, -988, -2053, +1337, -1158, 3227, 534, 3552, 2103, 2142, 2560, +-518, 1654, -3084, -219, -3973, -2116, -2853, -2862, +-237, -2051, 2640, -153, 4076, 1899, 3353, 2893, +883, 2289, -2015, 575, -3688, -1410, -3355, -2581, +-1326, -2320, 1265, -1001, 3042, 737, 3207, 2039, +1802, 2230, -388, 1373, -2233, -36, -2864, -1369, +-2136, -2024, -476, -1675, 1406, -613, 2627, 720, +2638, 1781, 1474, 1944, -577, 1229, -2413, -138, +-3038, -1525, -2266, -2150, -195, -1823, 2124, -468, +3428, 1250, 3106, 2330, 1116, 2351, -1568, 1124, +-3469, -818, -3648, -2338, -1977, -2746, 759, -1833, +3126, 151, 4004, 2080, 2973, 2974, 419, 2494, +-2302, 687, -3860, -1487, -3636, -2907, -1646, -2979, +1138, -1552, 3387, 678, 4164, 2500, 2939, 3172, +222, 2289, -2618, 234, -4181, -1792, -3663, -3015, +-1325, -2785, 1663, -1119, 3806, 986, 4070, 2588, +2353, 2968, -535, 1808, -3038, -188, -3860, -1938, +-2798, -2831, -463, -2337, 1997, -658, 3379, 1146, +3185, 2505, 1556, 2764, -782, 1580, -2632, -291, +-3214, -2123, -2302, -3132, -325, -2518, 1812, -553, +3208, 1732, 3164, 3420, 1468, 3349, -1050, 1360, +-3032, -1294, -3530, -3527, -2179, -3963, 354, -2074, +2700, 825, 3788, 3358, 2964, 4238, 477, 2635, +-2197, -298, -3628, -2894, -3204, -4113, -1159, -3002, +1443, -337, 3251, 2149, 3532, 3600, 2110, 3201, +-461, 1117, -2675, -1195, -3463, -2853, -2603, -3263, +-477, -1954, 1824, 131, 3292, 2034, 3281, 3198, +1602, 2711, -894, 911, -2866, -1243, -3403, -3000, +-2251, -3286, 9, -1799, 2245, 514, 3453, 2660, +3023, 3587, 1022, 2486, -1525, 134, -3209, -2248, +-3303, -3638, -1712, -2966, 853, -729, 2951, 1761, +3639, 3519, 2502, 3375, -84, 1369, -2612, -1224, +-3676, -3288, -2843, -3745, -476, -2092, 2176, 598, +3666, 2958, 3356, 4021, 1308, 2909, -1477, 232, +-3359, -2461, -3508, -4130, -1907, -3695, 674, -1243, +2794, 1737, 3603, 3953, 2800, 4269, 589, 2291, +-1855, -781, -3324, -3423, -3327, -4479, -1714, -3165, +808, -261, 2924, 2582, 3787, 4241, 2861, 3740, +434, 1267, -2196, -1598, -3680, -3655, -3363, -3926, +-1343, -2075, 1415, 614, 3368, 2837, 3676, 3737, +2208, 2655, -446, 359, -2704, -1965, -3425, -3391, +-2500, -3090, -305, -1247, 1966, 1123, 3129, 2997, +2869, 3461, 1213, 2072, -1047, -343, -2616, -2676, +-2949, -3789, -1813, -2828, 279, -359, 2188, 2357, +3125, 3968, 2635, 3472, 737, 1084, -1634, -1891, +-3146, -3953, -3109, -3976, -1384, -1876, 1174, 1198, +3072, 3681, 3483, 4268, 2191, 2645, -343, -296, +-2599, -3116, -3462, -4334, -2581, -3345, -299, -695, +2020, 2310, 3169, 4145, 2847, 3924, 1201, 1680, +-953, -1426, -2475, -3818, -2806, -4243, -1783, -2468, +61, 507, 1745, 3258, 2679, 4279, 2438, 3091, +1035, 439, -859, -2444, -2371, -4065, -2753, -3637, +-1784, -1490, 230, 1446, 2177, 3708, 3118, 4071, +2546, 2515, 528, -338, -1804, -3193, -3243, -4361, +-2928, -3421, -1023, -813, 1498, 2431, 3262, 4368, +3317, 4120, 1707, 1916, -786, -1477, -2816, -4098, +-3346, -4520, -2209, -2846, -54, 361, 2114, 3506, +3278, 4616, 2904, 3535, 1214, 717, -1061, -2611, +-2836, -4362, -3209, -3988, -2100, -1766, -6, 1528, +2213, 3906, 3384, 4253, 2968, 2692, 1102, -431, +-1420, -3352, -3089, -4417, -3197, -3406, -1736, -568, +641, 2741, 2646, 4429, 3272, 3827, 2250, 1344, +139, -2069, -1997, -4148, -2930, -3968, -2340, -1987, +-644, 1209, 1416, 3576, 2611, 3890, 2454, 2494, +1192, -254, -768, -2807, -2184, -3656, -2368, -2853, +-1508, -700, 211, 1901, 1849, 3265, 2482, 3042, +1937, 1525, 405, -956, -1394, -2789, -2432, -3168, +-2215, -2264, -897, -11, 950, 2348, 2371, 3361, +2569, 2949, 1561, 827, -306, -2000, -2137, -3607, +-2786, -3573, -2040, -1551, -246, 1620, 1814, 3769, +2942, 3991, 2539, 2165, 956, -1033, -1207, -3582, +-2811, -4170, -2908, -2772, -1612, 179, 570, 2956, +2603, 4005, 3194, 3265, 2208, 836, 240, -2010, +-1986, -3543, -3139, -3469, -2681, -1759, -1043, 890, +1219, 2766, 2955, 3290, 3128, 2344, 1884, 149, +-350, -1842, -2472, -2805, -3262, -2578, -2495, -977, +-482, 963, 1843, 2188, 3251, 2461, 2970, 1414, +1278, -284, -1078, -1552, -2918, -2121, -3149, -1601, +-1879, -212, 321, 943, 2434, 1640, 3184, 1651, +2338, 688, 431, -382, -1764, -1246, -2983, -1728, +-2605, -1173, -1129, -173, 1007, 869, 2725, 1817, +2936, 1739, 1770, 759, -261, -544, -2360, -1875, +-3203, -2271, -2321, -1365, -334, 88, 1989, 1677, +3335, 2536, 2848, 1925, 924, 545, -1490, -1163, +-3245, -2457, -3255, -2380, -1541, -1285, 896, 343, +2967, 1981, 3478, 2568, 2140, 1964, -86, 554, +-2350, -1316, -3472, -2471, -2767, -2363, -832, -1294, +1600, 533, 3251, 2095, 3163, 2505, 1642, 1777, +-625, 131, -2715, -1633, -3382, -2421, -2373, -2022, +-268, -708, 2087, 1118, 3334, 2216, 2802, 2207, +922, 1189, -1366, -622, -2928, -2032, -2986, -2422, +-1465, -1647, 757, 79, 2476, 1813, 2873, 2565, +1692, 2096, -254, 498, -1899, -1467, -2592, -2544, +-1903, -2505, -300, -1155, 1385, 895, 2473, 2332, +2191, 2776, 713, 1793, -1079, -186, -2389, -1994, +-2509, -2915, -1214, -2375, 731, -557, 2427, 1562, +3044, 2974, 1705, 2903, -640, 1200, -2479, -1205, +-3234, -3060, -2112, -3359, 210, -1721, 2230, 928, +3267, 3182, 2571, 3744, 291, 2091, -1919, -796, +-2954, -3289, -2670, -3953, -859, -2364, 1187, 598, +2393, 3204, 2621, 3994, 1356, 2535, -542, -256, +-1826, -2790, -2258, -3858, -1518, -2827, -6, -387, +1197, 2187, 1870, 3623, 1580, 3148, 253, 1135, +-947, -1549, -1562, -3435, -1349, -3451, -234, -1751, +769, 987, 1340, 3183, 1298, 3631, 246, 2145, +-908, -638, -1407, -3000, -1132, -3622, -93, -2249, +854, 409, 1229, 2807, 1104, 3463, 295, 2152, +-711, -424, -1109, -2632, -934, -3112, -344, -1863, +390, 414, 636, 2284, 637, 2665, 528, 1517, +62, -409, -292, -1878, -313, -2093, -348, -1160, +-270, 337, -123, 1398, -145, 1423, 173, 695, +430, -294, 427, -900, 463, -759, 44, -154, +-384, 386, -569, 378, -653, -87, -208, -514, +467, -451, 772, 179, 764, 906, 235, 1112, +-651, 391, -975, -825, -679, -1696, -44, -1519, +871, -107, 1256, 1488, 677, 2259, -234, 1586, +-1099, -342, -1388, -2091, -514, -2594, 566, -1426, +1223, 817, 1374, 2610, 364, 2708, -724, 1017, +-1110, -1358, -1086, -2950, -172, -2587, 924, -538, +1107, 1751, 766, 3003, -136, 2222, -1095, 50, +-886, -1967, -236, -2762, 351, -1693, 1127, 256, +877, 1881, 124, 2335, -397, 1229, -1045, -418, +-744, -1591, -64, -1829, 276, -1048, 599, 271, +656, 1224, 444, 1436, 323, 1126, 131, 171, +-397, -846, -769, -1313, -987, -1417, -949, -714, +49, 389, 1275, 1236, 1927, 1756, 1710, 1257, +318, 82, -1494, -1187, -2418, -2044, -2052, -1716, +-532, -547, 1658, 996, 2820, 2169, 2389, 2124, +563, 919, -1695, -864, -2839, -2200, -2272, -2410, +-374, -1247, 1761, 704, 2960, 2249, 2400, 2621, +464, 1449, -1786, -566, -3059, -2289, -2513, -2723, +-492, -1620, 1871, 305, 3337, 2095, 3027, 2757, +976, 1871, -1708, 51, -3506, -1799, -3370, -2870, +-1196, -2212, 1617, -320, 3435, 1617, 3535, 2884, +1737, 2411, -1064, 426, -3073, -1718, -3247, -2883, +-1730, -2298, 760, -306, 2517, 1811, 2672, 2712, +1767, 1975, -21, 161, -1602, -1695, -2033, -2459, +-1608, -1690, -353, -143, 1000, 1270, 1707, 1950, +1758, 1490, 989, 467, -366, -599, -1564, -1343, +-1983, -1441, -1276, -1143, 379, -213, 1848, 849, +2320, 1561, 1659, 1867, -137, 968, -1870, -667, +-2365, -1976, -1668, -2414, 50, -1367, 1824, 827, +2327, 2385, 1758, 2495, 510, 1269, -971, -986, +-1680, -2427, -1713, -2160, -1157, -957, 164, 721, +1263, 1784, 1973, 1527, 2000, 859, 851, 102, +-711, -694, -2060, -1016, -2329, -1258, -1151, -1173, +749, -269, 2265, 808, 2526, 1788, 1293, 1880, +-718, 691, -2127, -963, -2190, -2060, -934, -1919, +1015, -606, 2167, 1099, 2161, 1847, 982, 1437, +-844, 292, -1941, -1031, -2053, -1493, -1064, -937, +634, -117, 1970, 748, 2313, 1264, 1676, 785, +157, 143, -1383, -515, -2218, -1214, -2181, -974, +-995, -365, 872, 309, 2354, 1099, 2861, 1190, +1983, 688, -17, 4, -1951, -839, -2976, -1383, +-2407, -1157, -354, -419, 1859, 629, 3022, 1509, +2574, 1510, 661, 600, -1457, -779, -2501, -1712, +-2084, -1421, -479, -136, 1364, 1207, 2266, 1654, +1979, 714, 600, -869, -1141, -1654, -1969, -1203, +-1791, 271, -646, 1756, 1168, 1783, 2276, 527, +2340, -1036, 1169, -2012, -1048, -1592, -2492, -125, +-2618, 1160, -1297, 1653, 1121, 1289, 2792, 230, +2906, -822, 1612, -1264, -711, -1176, -2536, -496, +-2701, 501, -1419, 1111, 732, 1147, 2389, 487, +2410, -537, 1184, -1229, -582, -1038, -1879, -203, +-1713, 793, -461, 1358, 955, 879, 1727, -62, +1182, -1014, -120, -1483, -1043, -971, -1245, 11, +-492, 1103, 700, 1666, 1298, 1231, 1164, 183, +272, -1036, -788, -1754, -1119, -1460, -763, -439, +-40, 687, 787, 1454, 1268, 1377, 906, 812, +66, 49, -759, -788, -1173, -1237, -650, -1445, +215, -1044, 1031, 129, 1465, 1424, 761, 2129, +-424, 1649, -1373, -4, -1431, -1789, -341, -2381, +970, -1574, 1705, 188, 1367, 1806, 231, 1995, +-976, 1067, -1586, -142, -1025, -1226, 183, -1386, +1045, -921, 1413, -439, 748, 469, -327, 1119, +-718, 1261, -777, 1102, -209, -39, 569, -1305, +665, -1673, 424, -1344, -99, -116, -568, 1321, +-393, 1713, 56, 1312, 372, 307, 618, -962, +479, -1481, 44, -1403, -191, -800, -483, 461, +-418, 1470, -82, 1685, 2, 1087, 378, -344, +742, -1697, 585, -1757, 235, -839, -295, 592, +-718, 1714, -658, 1242, -263, 199, 275, -742, +716, -1227, 921, -489, 526, 283, -191, 610, +-628, 546, -835, -139, -483, -552, 236, -385, +691, -34, 977, 490, 665, 797, -227, 336, +-820, -441, -932, -956, -375, -1050, 525, -180, +937, 1010, 782, 1455, 164, 1003, -488, -377, +-671, -1616, -313, -1530, 147, -393, 354, 993, +299, 1657, -91, 889, -193, -322, 229, -1092, +422, -985, 357, 39, 15, 588, -673, 364, +-805, -104, -310, -513, 355, -192, 1038, 656, +1109, 902, 296, 369, -615, -515, -1131, -1380, +-1039, -1170, -131, -21, 780, 967, 1198, 1616, +982, 1253, 35, -143, -705, -1197, -993, -1627, +-736, -1348, 53, 72, 575, 1319, 790, 1670, +604, 1390, 48, -100, -348, -1477, -460, -1569, +-299, -1145, 18, 75, 56, 1391, 27, 1318, +76, 784, 64, 100, 331, -1021, 456, -1156, +267, -745, 0, -404, -701, 682, -1064, 1269, +-569, 978, 259, 549, 1159, -619, 1505, -1618, +779, -1166, -484, -291, -1537, 778, -1771, 1652, +-707, 901, 809, -109, 1739, -714, 1692, -1176, +654, -426, -745, 379, -1637, 233, -1610, 273, +-759, 119, 601, -237, 1612, 335, 1622, 413, +929, -131, -406, -156, -1653, -567, -1754, -546, +-999, 204, 569, 263, 1927, 353, 1789, 511, +554, 7, -1073, -166, -1984, -199, -1373, -669, +49, -437, 1382, 44, 1934, 447, 929, 1113, +-635, 769, -1591, -235, -1684, -973, -512, -1463, +837, -924, 1455, 481, 1438, 1395, 543, 1537, +-683, 910, -1388, -414, -1360, -1399, -510, -1489, +589, -1049, 1161, -10, 1064, 1123, 333, 1474, +-398, 1275, -723, 410, -678, -839, -75, -1484, +296, -1361, 141, -512, 41, 645, -90, 1275, +-2, 1117, 302, 422, 240, -462, -121, -965, +-288, -744, -298, -319, -119, 285, 340, 741, +412, 546, 4, 143, -375, -402, -650, -672, +-432, -341, 371, 190, 902, 576, 815, 470, +355, -51, -482, -485, -1132, -496, -1060, -82, +-547, 458, 472, 537, 1282, 55, 1163, -401, +503, -602, -393, -329, -1082, 319, -1035, 655, +-436, 491, 183, 167, 670, -282, 700, -586, +247, -496, 50, -396, -195, -37, -490, 502, +-382, 676, -357, 708, -19, 370, 667, -479, +705, -893, 216, -816, -370, -386, -1107, 331, +-916, 646, 179, 628, 913, 453, 1291, 76, +856, -230, -558, -456, -1306, -623, -1113, -511, +-615, -3, 561, 515, 1118, 682, 651, 507, +429, -132, -158, -537, -607, -437, -249, -121, +-441, 393, -412, 386, 71, -100, 25, -340, +440, -377, 695, -114, 216, 428, 47, 516, +-375, 220, -861, -80, -461, -513, -28, -462, +319, -8, 821, 235, 528, 398, -146, 303, +-492, -160, -865, -528, -487, -376, 441, -30, +757, 515, 688, 809, 174, 338, -579, -360, +-724, -921, -461, -795, -93, -57, 352, 621, +493, 711, 344, 298, 300, -110, 186, -297, +-198, 35, -498, 233, -782, -114, -664, -576, +81, -837, 719, -319, 1069, 676, 793, 1279, +-76, 1011, -774, 100, -1044, -948, -783, -1349, +-75, -721, 497, 22, 793, 546, 683, 824, +194, 605, -82, 331, -409, 118, -683, -420, +-510, -896, -298, -865, 89, -527, 603, 411, +801, 1378, 708, 1268, 263, 454, -614, -675, +-1277, -1600, -1100, -1475, -322, -342, 895, 919, +1658, 1701, 1259, 1595, 172, 382, -1200, -1015, +-1835, -1848, -1135, -1743, 202, -426, 1314, 1147, +1496, 1903, 669, 1617, -349, 300, -949, -1159, +-918, -1630, -387, -1171, 113, -47, 341, 890, +390, 904, 394, 543, 295, 34, 63, -372, +-207, -182, -478, -22, -427, -278, -104, -377, +106, -316, 314, -2, 224, 660, 143, 890, +316, 443, 265, -220, 45, -984, -501, -1153, +-1030, -379, -755, 486, 104, 1016, 1073, 1097, +1651, 495, 1093, -393, -339, -891, -1542, -1019, +-1943, -727, -1135, -25, 331, 574, 1491, 1031, +1998, 1149, 1286, 484, 31, -410, -1153, -1067, +-1953, -1301, -1604, -735, -560, 266, 775, 1037, +1964, 1186, 1956, 577, 782, -238, -590, -782, +-1733, -831, -1861, -342, -879, 317, 373, 650, +1488, 439, 1746, 6, 979, -476, -139, -649, +-1126, -244, -1558, 287, -1097, 715, -54, 706, +1036, 86, 1684, -430, 1270, -737, -3, -652, +-1092, -119, -1529, 409, -1056, 561, 43, 381, +951, 218, 1189, -194, 790, -345, 18, -213, +-619, -115, -612, 201, -429, 197, -279, -35, +102, -263, 205, -468, 236, -192, 437, 335, +355, 953, 249, 938, -29, 54, -468, -895, +-671, -1521, -550, -1149, -35, 179, 668, 1458, +1076, 1713, 827, 849, 13, -467, -921, -1507, +-1306, -1465, -831, -517, 328, 565, 1337, 1207, +1479, 1065, 623, 386, -737, -432, -1404, -810, +-1125, -856, -351, -439, 714, 322, 1129, 639, +786, 591, 241, 292, -279, -170, -362, -417, +-370, -216, -591, 42, -582, 0, -251, -261, +366, -297, 1073, -103, 1285, 359, 757, 997, +-347, 797, -1368, -150, -1580, -1059, -862, -1516, +411, -758, 1501, 698, 1679, 1565, 881, 1484, +-435, 379, -1373, -1213, -1273, -1845, -498, -1025, +558, 380, 1132, 1517, 790, 1520, 85, 432, +-509, -920, -639, -1721, -223, -1123, 237, 407, +291, 1404, 86, 1543, -78, 540, -110, -1080, +94, -1714, 297, -1153, 148, 252, -118, 1579, +-381, 1593, -445, 519, -134, -808, 231, -1695, +596, -1424, 723, -50, 451, 1272, 2, 1663, +-669, 1119, -1066, -163, -782, -1336, -204, -1757, +785, -1115, 1645, 258, 1359, 1470, 306, 1843, +-976, 1189, -1766, -235, -1378, -1669, -184, -2015, +1046, -1256, 1672, 399, 1300, 1870, 55, 2043, +-977, 1143, -1288, -604, -993, -1978, 52, -1979, +841, -848, 1120, 805, 856, 1841, -228, 1761, +-975, 626, -990, -830, -501, -1745, 633, -1593, +1258, -339, 820, 884, -20, 1529, -987, 1328, +-1127, 94, -285, -966, 595, -1296, 1159, -913, +928, 269, -164, 932, -997, 870, -888, 502, +-275, -435, 508, -896, 977, -479, 746, -67, +140, 448, -660, 634, -964, 230, -512, 18, +101, -244, 691, -447, 787, -232, 456, -194, +-114, -116, -694, 349, -692, 564, -243, 566, +270, 279, 624, -378, 489, -811, 38, -865, +-283, -384, -424, 377, -304, 878, 70, 966, +315, 496, 388, -87, 373, -704, 26, -1059, +-228, -730, -299, -275, -361, 370, -79, 1043, +293, 1053, 326, 607, 329, -29, 159, -878, +-186, -1210, -7, -872, 98, -310, -98, 502, +-161, 1063, -479, 1096, -494, 806, 193, 68, +743, -786, 984, -1393, 729, -1391, -372, -631, +-1269, 572, -1201, 1654, -595, 1897, 588, 1051, +1384, -505, 1108, -1609, 476, -1981, -545, -1380, +-1239, 108, -929, 1239, -372, 1843, 359, 1717, +1139, 652, 1162, -602, 671, -1683, -186, -2130, +-1204, -1496, -1451, -131, -801, 1428, 245, 2456, +1341, 2193, 1810, 822, 1139, -1010, -289, -2472, +-1479, -2567, -1753, -1436, -1074, 372, 212, 2070, +1169, 2607, 1416, 1894, 1078, 343, 108, -1291, +-661, -2212, -920, -2093, -956, -1032, -479, 175, +39, 1351, 405, 1997, 799, 1783, 721, 1062, +533, -343, 174, -1685, -581, -2432, -832, -2111, +-751, -551, -523, 1324, 239, 2650, 850, 2640, +1004, 1145, 828, -866, 118, -2221, -630, -2535, +-946, -1562, -860, 132, -387, 1356, 241, 2055, +845, 1820, 1071, 692, 728, -486, 120, -1402, +-568, -1766, -1064, -1303, -1160, -197, -617, 628, +282, 1291, 1075, 1433, 1505, 711, 1028, 198, +167, -409, -847, -1029, -1762, -1111, -1610, -1075, +-675, -640, 554, 258, 1788, 1181, 2075, 1866, +1246, 1698, 24, 616, -1477, -846, -2258, -2315, +-1800, -2665, -654, -1490, 1080, 391, 2179, 2277, +2069, 3090, 1360, 2245, -142, 177, -1649, -1862, +-2222, -2884, -1947, -2455, -750, -643, 956, 1086, +2004, 1922, 2323, 2008, 1752, 994, -87, -125, +-1778, -555, -2577, -896, -2268, -980, -601, -957, +1228, -877, 2372, -352, 2426, 580, 1076, 1599, +-704, 1908, -1949, 1386, -2121, 199, -1172, -1344, +282, -2256, 1332, -2119, 1438, -1211, 810, 232, +-60, 1775, -477, 2450, -401, 2263, -139, 1282, +16, -609, -247, -2280, -629, -3034, -468, -2633, +38, -852, 698, 1475, 1216, 3203, 929, 3564, +212, 2197, -614, -207, -1371, -2606, -1252, -3883, +-547, -3153, 165, -1050, 996, 1334, 1412, 3302, +991, 3583, 202, 2179, -665, 183, -1268, -1964, +-1096, -3223, -544, -2945, 185, -1731, 744, 156, +825, 2266, 695, 3258, 335, 2936, -3, 1581, +-345, -902, -742, -2938, -788, -3591, -505, -2864, +-31, -524, 597, 2021, 933, 3586, 614, 3557, +212, 1651, -28, -1000, -294, -2997, -246, -3490, +-463, -2140, -868, 286, -766, 2154, -285, 2622, +756, 1712, 1753, 7, 1772, -1211, 692, -1332, +-995, -708, -2191, 202, -2149, 570, -998, 132, +614, -501, 1761, -792, 1895, -412, 1201, 498, +102, 1319, -812, 1568, -1205, 924, -1161, -333, +-764, -1603, -330, -2164, 136, -1731, 618, -539, +1043, 1112, 1316, 2311, 1207, 2483, 515, 1590, +-799, 55, -1962, -1644, -2472, -2664, -1789, -2497, +184, -1589, 2126, 242, 3301, 2089, 2838, 3033, +718, 3049, -1635, 1422, -3428, -1021, -3608, -3053, +-1816, -3831, 682, -2662, 2898, -216, 3870, 2416, +2875, 3807, 495, 3169, -2224, 1114, -3950, -1377, +-3615, -3042, -1408, -3028, 1459, -1605, 3593, 528, +3942, 2100, 2111, 2416, -873, 1551, -3098, -138, +-3781, -1484, -2513, -1868, 201, -1172, 2527, 373, +3739, 1511, 2929, 1725, 299, 792, -2111, -978, +-3571, -2140, -3211, -2119, -832, -686, 1818, 1488, +3497, 2919, 3292, 2908, 1239, 1132, -1264, -1576, +-3041, -3471, -3402, -3580, -1890, -1818, 488, 830, +2409, 3140, 3293, 3863, 2501, 2677, 526, 516, +-1749, -1861, -3285, -3435, -3069, -3497, -1307, -2156, +1234, 143, 3099, 2553, 3168, 3873, 1679, 3377, +-795, 1280, -2659, -1374, -2909, -3369, -1751, -3641, +438, -2043, 2211, 65, 2555, 1908, 1660, 2925, +-109, 2304, -1670, 1115, -2160, -224, -1650, -1624, +-180, -2155, 1297, -1914, 1975, -948, 1661, 590, +412, 1751, -967, 1818, -1834, 1116, -1660, -192, +-616, -1200, 484, -968, 1438, -337, 1682, 464, +964, 702, -75, -96, -1058, -729, -1428, -1040, +-1133, -664, -547, 580, 254, 1465, 967, 1625, +1194, 1155, 1170, -143, 773, -1413, -101, -1923, +-1009, -1854, -1728, -850, -1783, 575, -945, 1530, +528, 2061, 2092, 1801, 2696, 782, 1944, -293, +174, -1347, -1781, -2110, -2926, -2081, -2829, -1438, +-1213, -272, 1079, 1393, 2735, 2658, 3104, 2978, +1997, 2284, 31, 318, -1845, -2040, -2847, -3637, +-2504, -3877, -1020, -2404, 677, 340, 1804, 2932, +2118, 4363, 1624, 3967, 742, 1750, -286, -1032, +-1187, -3336, -1612, -4227, -1741, -3362, -1287, -1318, +-152, 1085, 1083, 2964, 2064, 3704, 2365, 3101, +1481, 1499, -73, -652, -1459, -2570, -2342, -3474, +-2302, -3256, -1305, -1833, 230, 269, 1622, 2206, +2478, 3480, 2429, 3634, 1225, 2384, -399, 124, +-1923, -2312, -2887, -4143, -2344, -4323, -820, -2605, +872, 333, 2477, 3362, 2769, 4950, 1684, 4248, +231, 1593, -1451, -1799, -2419, -4253, -2145, -4508, +-1088, -2721, 491, 119, 1580, 2670, 1820, 3532, +1470, 2763, 470, 1015, -499, -913, -1161, -1876, +-1455, -1913, -1034, -1399, -264, -446, 512, 303, +1142, 713, 1235, 1087, 743, 1124, 15, 813, +-684, 297, -973, -518, -772, -1234, -404, -1263, +-22, -855, 392, -35, 784, 1044, 950, 1354, +676, 1007, 94, 316, -720, -729, -1374, -1252, +-1325, -1045, -532, -503, 627, 430, 1428, 1063, +1621, 1045, 1048, 739, -62, 63, -1031, -688, +-1682, -1117, -1670, -1156, -919, -666, 131, 132, +1540, 1006, 2444, 1564, 2071, 1295, 810, 409, +-1044, -628, -2538, -1395, -2799, -1508, -1781, -958, +256, -137, 2063, 604, 2706, 949, 2231, 1117, +801, 1180, -714, 810, -1752, 186, -2106, -781, +-1678, -1835, -831, -2191, 201, -1750, 1270, -256, +1950, 1785, 1943, 2983, 1323, 3060, 66, 1763, +-1554, -706, -2435, -2834, -2220, -3768, -1017, -3061, +701, -824, 1799, 1668, 2003, 3425, 1340, 3660, +223, 2135, -529, -109, -679, -2001, -634, -3021, +-830, -2735, -1071, -1383, -991, 174, -409, 1527, +802, 2282, 2043, 2097, 2381, 1383, 1558, 237, +-149, -1058, -1987, -1765, -2861, -1938, -2365, -1522, +-883, -532, 1058, 608, 2327, 1549, 2487, 1952, +1713, 1631, 209, 672, -1170, -540, -1836, -1437, +-1813, -1705, -1176, -1275, -353, -480, 403, 286, +1175, 756, 1611, 812, 1544, 889, 1050, 924, +-20, 751, -1230, 420, -1993, -430, -2060, -1517, +-1130, -2011, 344, -1788, 1603, -700, 2106, 1133, +1833, 2509, 929, 2691, -325, 1786, -1426, -79, +-2284, -1971, -2059, -2758, -804, -2366, 571, -892, +2070, 918, 2538, 1935, 1620, 2033, 152, 1290, +-1622, 37, -2410, -756, -1732, -924, -451, -820, +982, -472, 1708, -302, 1303, -323, 419, -152, +-481, 111, -967, 615, -745, 1145, -26, 1241, +544, 835, 380, -88, -184, -1226, -639, -2011, +-650, -1966, 72, -946, 856, 709, 1237, 2092, +992, 2561, -195, 1957, -1307, 274, -1549, -1438, +-1080, -2362, 49, -2415, 1094, -1325, 1304, 187, +1078, 1391, 407, 2164, -375, 2129, -572, 1255, +-867, 8, -1057, -1386, -684, -2482, -351, -2451, +433, -1342, 1342, 436, 1542, 2300, 1326, 2990, +236, 2263, -1203, 497, -1919, -1672, -2068, -2756, +-1186, -2598, 487, -1341, 1812, 727, 2493, 2086, +2002, 2342, 379, 1681, -1377, 264, -2475, -995, +-2292, -1513, -963, -1432, 713, -947, 2004, -267, +2136, 227, 1089, 685, -398, 1153, -1378, 1255, +-1383, 997, -695, 244, 320, -749, 940, -1466, +758, -1649, 68, -1062, -761, -75, -1011, 769, +-436, 1384, 366, 1482, 1139, 909, 1383, 241, +815, -428, -233, -1108, -1306, -1203, -1767, -932, +-1420, -609, -578, -33, 688, 457, 1661, 832, +1824, 1272, 1540, 1351, 546, 1035, -643, 220, +-1509, -1087, -2168, -2169, -1893, -2532, -912, -1730, +215, -8, 1792, 1843, 2751, 3195, 2559, 3096, +1454, 1557, -567, -503, -2396, -2458, -3306, -3483, +-2912, -2934, -1110, -1176, 1011, 851, 2577, 2453, +3180, 3028, 2446, 2419, 851, 1116, -759, -466, +-2115, -1762, -2724, -2401, -2236, -2458, -1290, -1671, +68, -109, 1563, 1394, 2358, 2364, 2531, 2508, +1935, 1573, 504, 236, -1162, -920, -2538, -1665, +-2896, -1691, -2122, -1520, -587, -1221, 1177, -398, +2252, 612, 2407, 1738, 1856, 2693, 809, 2507, +-312, 1133, -1199, -873, -1890, -2828, -2251, -3451, +-1856, -2448, -682, -544, 846, 1638, 2272, 2948, +2730, 2664, 1968, 1415, 662, -105, -761, -1293, +-1827, -1567, -2038, -1204, -1646, -822, -1057, -415, +-329, -218, 471, -29, 1376, 708, 2096, 1335, +2295, 1548, 1637, 1298, 160, 284, -1532, -843, +-2799, -1544, -3151, -1868, -2258, -1431, -334, -591, +1688, 233, 3223, 1347, 3563, 2067, 2289, 1995, +331, 1329, -1699, -53, -3155, -1603, -3167, -2471, +-2071, -2297, -417, -1191, 1276, 453, 2351, 1782, +2473, 2136, 1906, 1743, 949, 607, -340, -635, +-1368, -1120, -1997, -1165, -2091, -857, -1507, -352, +-705, -36, 502, 81, 1620, 238, 2187, 488, +2316, 692, 1544, 750, 107, 533, -1322, 136, +-2460, -378, -2746, -723, -1928, -811, -619, -874, +956, -632, 2375, -180, 2806, 300, 2356, 1040, +1215, 1547, -510, 1352, -1990, 685, -2842, -370, +-2821, -1449, -1669, -1845, 75, -1672, 1653, -959, +2828, 227, 3013, 1204, 1939, 2063, 439, 2281, +-1383, 1480, -2786, 128, -2862, -1588, -2017, -2602, +-578, -2455, 962, -1421, 1944, 332, 2261, 1667, +2074, 2085, 1324, 1913, 85, 1126, -1189, 166, +-2280, -731, -2730, -1612, -2017, -1976, -430, -1593, +1328, -649, 2518, 804, 2639, 1869, 1590, 1806, +125, 1035, -1044, -95, -1699, -904, -1558, -901, +-1122, -396, -534, 41, 154, 69, 453, -374, +747, -816, 1036, -582, 1127, 94, 1143, 954, +671, 1656, -325, 1403, -1332, 433, -2161, -536, +-2127, -1361, -993, -1696, 483, -1353, 1887, -704, +2569, 160, 1980, 1263, 656, 1866, -651, 1835, +-1616, 1242, -1787, -215, -1330, -1527, -767, -2065, +35, -1906, 722, -920, 855, 362, 1168, 1216, +1251, 1538, 826, 1410, 442, 813, -479, 176, +-1388, -422, -1694, -984, -1673, -1120, -909, -1090, +491, -705, 1607, -79, 2055, 371, 1673, 878, +556, 996, -497, 855, -1139, 808, -1431, 490, +-1092, -8, -556, -623, -233, -1475, 98, -2105, +427, -1867, 881, -666, 1278, 1199, 1239, 2846, +777, 3287, -17, 2216, -966, 92, -1796, -2059, +-2071, -3277, -1483, -3026, -211, -1681, 1293, 164, +2388, 1793, 2405, 2574, 1495, 2506, 135, 1607, +-1395, 343, -2233, -958, -2122, -1973, -1336, -2227, +-206, -1867, 758, -920, 1494, 277, 1793, 1348, +1564, 2074, 967, 2109, -86, 1560, -1073, 394, +-1696, -1034, -1989, -2070, -1479, -2406, -474, -1831, +690, -511, 1803, 880, 2230, 1789, 1749, 2142, +745, 1714, -599, 792, -1717, -235, -1985, -1372, +-1712, -1970, -845, -1911, 261, -1188, 945, 140, +1527, 1162, 1820, 1761, 1387, 1698, 618, 984, +-521, 185, -1717, -636, -2248, -1241, -1847, -1526, +-638, -1339, 803, -576, 1853, 457, 2032, 1360, +1466, 1632, 305, 1181, -915, 208, -1357, -815, +-1334, -1274, -867, -1127, -32, -377, 387, 525, +538, 874, 506, 726, 311, 31, 328, -842, +322, -867, 208, -227, 35, 655, -327, 1378, +-711, 978, -863, -138, -648, -1132, -147, -1558, +507, -843, 988, 348, 1005, 998, 601, 1027, +-20, 383, -675, -356, -911, -457, -719, -129, +-324, 226, 314, 361, 584, 17, 367, -571, +68, -725, -217, -452, -223, 103, 90, 781, +273, 922, 454, 526, 407, -61, -251, -690, +-712, -674, -861, -177, -875, 151, -165, 319, +579, 114, 997, -353, 1426, -438, 1042, 0, +51, 513, -881, 768, -1583, 524, -1667, -144, +-1008, -696, -16, -779, 1034, -399, 1861, 206, +1829, 571, 1099, 431, -71, 5, -1322, -289, +-1901, -407, -1825, -178, -1062, 388, 159, 563, +1084, 487, 1622, 174, 1685, -465, 1100, -823, +277, -830, -507, -407, -1349, 262, -1836, 833, +-1579, 1047, -940, 679, 83, 41, 1324, -636, +2029, -976, 2053, -686, 1376, -181, 86, 347, +-1237, 726, -2099, 578, -2386, 170, -1736, -272, +-425, -643, 915, -583, 2115, -186, 2556, 457, +2101, 990, 938, 844, -728, 244, -2079, -629, +-2731, -1258, -2542, -1191, -1214, -569, 496, 366, +1931, 1092, 2839, 1377, 2599, 1086, 1310, 381, +-308, -504, -1721, -1213, -2432, -1369, -2261, -974, +-1464, -154, -299, 583, 878, 922, 1757, 858, +2077, 563, 1894, 327, 1152, 204, -7, 20, +-1285, -457, -2386, -1059, -2531, -1422, -1758, -1155, +-396, -36, 1325, 1177, 2404, 1935, 2426, 1801, +1631, 636, 201, -683, -1022, -1469, -1449, -1471, +-1503, -861, -1259, -66, -710, 385, -361, 546, +78, 522, 813, 404, 1362, 440, 1777, 334, +1616, 156, 679, -76, -517, -442, -1725, -659, +-2325, -734, -2101, -539, -1195, -66, 116, 435, +1410, 784, 2249, 726, 2384, 391, 1815, 2, +515, -249, -930, -301, -2053, -267, -2657, -298, +-2214, -285, -993, -101, 392, 100, 1742, 275, +2330, 142, 2019, -178, 1241, -314, 142, -53, +-748, 555, -1214, 1062, -1585, 1027, -1701, 189, +-1490, -970, -1034, -1778, 108, -1808, 1696, -887, +2924, 404, 3113, 1483, 1970, 2012, -152, 1799, +-2309, 1000, -3541, -96, -3521, -1215, -2160, -2159, +18, -2391, 2008, -1634, 3363, -187, 3593, 1541, +2482, 2663, 608, 2634, -1627, 1584, -3366, -195, +-3767, -1753, -2860, -2389, -796, -2124, 1506, -1000, +3059, 343, 3599, 1154, 2708, 1406, 735, 1131, +-1153, 631, -2515, 321, -3029, 97, -2392, -249, +-1002, -681, 583, -1117, 1850, -1298, 2426, -899, +2217, -61, 1349, 777, -19, 1321, -1395, 1357, +-2101, 893, -1999, 270, -1341, -309, -163, -731, +924, -934, 1330, -1010, 1386, -986, 1035, -644, +571, -66, 297, 709, -154, 1590, -794, 1942, +-1429, 1612, -1959, 511, -1785, -1112, -553, -2395, +1106, -2722, 2592, -1708, 3225, 166, 2307, 1894, +293, 2590, -1920, 1901, -3486, 433, -3439, -931, +-1981, -1291, 169, -768, 2166, -141, 3109, 181, +2876, -122, 1690, -646, -50, -696, -1586, -228, +-2411, 509, -2507, 1237, -1702, 1395, -430, 1015, +744, 362, 1747, -588, 2052, -1376, 1663, -1770, +1034, -1635, 185, -713, -746, 547, -1516, 1666, +-1991, 2159, -1915, 1715, -1178, 629, 100, -583, +1520, -1428, 2357, -1717, 2294, -1390, 1434, -814, +65, -201, -1242, 468, -1880, 1110, -1877, 1610, +-1404, 1741, -501, 1271, 290, 102, 870, -1315, +1434, -2374, 1497, -2541, 1216, -1502, 766, 188, +-115, 1759, -880, 2545, -1448, 2115, -1824, 880, +-1587, -465, -786, -1350, 335, -1606, 1492, -1310, +2139, -743, 2056, -138, 1319, 442, 61, 884, +-1169, 1104, -2065, 893, -2365, 374, -1710, -117, +-544, -331, 767, -321, 1995, -300, 2244, -470, +1627, -880, 669, -1099, -533, -637, -1333, 487, +-1477, 1695, -1357, 2296, -960, 1797, -293, 257, +271, -1414, 888, -2468, 1371, -2434, 1307, -1189, +975, 382, 391, 1649, -417, 2181, -1112, 1751, +-1593, 795, -1649, -274, -985, -1103, 91, -1528, +1203, -1465, 2068, -947, 2085, -161, 1142, 690, +-196, 1276, -1490, 1517, -2175, 1220, -1837, 409, +-872, -471, 376, -1251, 1445, -1590, 1820, -1242, +1569, -436, 789, 486, -316, 1154, -1177, 1281, +-1556, 838, -1410, 186, -749, -346, 151, -638, +941, -526, 1310, -298, 1242, -222, 717, -221, +-21, -359, -711, -384, -1093, 61, -902, 699, +-511, 1218, -156, 1285, 117, 538, 203, -618, +343, -1563, 556, -1817, 827, -1104, 974, 70, +502, 1076, -287, 1514, -1155, 1138, -1815, 452, +-1576, -181, -670, -661, 508, -780, 1654, -581, +2089, -345, 1621, -44, 592, 288, -671, 314, +-1608, 200, -1676, 81, -1178, -26, -510, 52, +228, 273, 668, 335, 872, 212, 1100, -57, +1134, -350, 908, -533, 243, -479, -749, -267, +-1594, -28, -1972, 264, -1345, 509, 47, 710, +1280, 679, 1893, 428, 1611, -67, 582, -740, +-481, -1119, -1089, -1035, -1098, -453, -560, 486, +147, 1196, 454, 1335, 322, 825, -7, -165, +-405, -993, -460, -1158, 18, -695, 600, 90, +885, 689, 773, 713, 78, 288, -697, -158, +-1042, -298, -1018, -218, -464, -34, 269, 44, +610, -106, 744, -233, 668, -99, 227, 139, +-177, 325, -431, 395, -516, 165, -270, -117, +-5, -202, 99, -270, 85, -227, -114, -162, +-133, -347, 31, -391, 201, -251, 366, 25, +269, 607, 79, 1122, -49, 1234, -147, 849, +-123, -161, -150, -1354, -331, -2018, -417, -1998, +-232, -1114, 229, 347, 782, 1562, 1002, 2277, +586, 2266, -154, 1492, -735, 292, -1012, -1134, +-720, -2359, -81, -2832, 382, -2284, 696, -826, +734, 1118, 477, 2584, 137, 2890, -295, 2158, +-643, 720, -686, -729, -506, -1555, -92, -1797, +346, -1599, 604, -1039, 702, -370, 507, 366, +167, 1066, -250, 1394, -797, 1300, -1164, 885, +-951, 213, -256, -306, 650, -603, 1427, -723, +1523, -636, 833, -574, -229, -528, -1209, -437, +-1673, -159, -1330, 334, -457, 981, 451, 1502, +1066, 1374, 1214, 561, 856, -654, 331, -1678, +-57, -1861, -374, -1040, -524, 301, -637, 1320, +-800, 1470, -725, 681, -500, -470, 42, -1263, +912, -1159, 1552, -276, 1713, 798, 1168, 1474, +-8, 1225, -1256, 349, -2093, -685, -2179, -1425, +-1320, -1494, 74, -992, 1395, -273, 2324, 395, +2289, 983, 1348, 1318, 137, 1314, -1114, 975, +-1878, 152, -1938, -840, -1537, -1636, -666, -1913, +338, -1315, 1253, -227, 1952, 962, 1991, 1752, +1269, 1655, 20, 946, -1214, -33, -1923, -909, +-1866, -1085, -1105, -839, -194, -478, 574, 98, +1125, 321, 1242, 336, 1091, 452, 772, 387, +102, 333, -590, 210, -1084, -106, -1351, -419, +-1099, -622, -393, -530, 311, -117, 870, 364, +1039, 633, 854, 672, 561, 369, 68, 60, +-272, -93, -507, -202, -816, -223, -913, -393, +-770, -614, -363, -644, 422, -324, 1184, 281, +1488, 1034, 1309, 1431, 512, 1141, -660, 379, +-1501, -627, -1727, -1337, -1238, -1365, -126, -931, +866, -228, 1397, 353, 1531, 561, 1091, 630, +308, 644, -512, 607, -1156, 467, -1418, 200, +-1197, -272, -526, -666, 348, -787, 1062, -715, +1239, -472, 1024, -235, 565, -83, 41, 116, +-308, 438, -677, 703, -1016, 859, -1202, 775, +-1105, 290, -471, -268, 453, -696, 1321, -953, +1850, -930, 1633, -659, 695, -289, -484, 89, +-1439, 450, -1884, 658, -1728, 694, -1060, 544, +-99, 379, 889, 240, 1632, 141, 1906, 9, +1566, -343, 498, -781, -712, -1207, -1562, -1294, +-1865, -791, -1330, 135, -397, 1199, 403, 1955, +969, 1936, 1076, 1179, 807, 4, 593, -1159, +302, -1663, -49, -1356, -277, -698, -587, 19, +-838, 367, -722, 256, -411, 193, 37, 387, +526, 756, 675, 1038, 695, 948, 644, 368, +308, -331, -18, -863, -308, -1079, -595, -926, +-616, -701, -501, -391, -295, 0, 70, 411, +314, 890, 399, 1223, 480, 1220, 532, 833, +432, 156, 70, -715, -498, -1299, -933, -1444, +-918, -1219, -506, -460, 184, 294, 804, 759, +1051, 990, 716, 877, -111, 492, -795, 168, +-960, -146, -721, -482, -123, -582, 499, -562, +640, -412, 498, -81, 208, 136, -157, 156, +-274, 53, -179, -77, -123, -33, -66, 172, +-196, 300, -379, 223, -251, 24, -17, -289, +402, -297, 789, -90, 717, 74, 369, 241, +-159, 111, -621, -112, -677, -246, -521, -332, +-278, -359, 3, -210, 212, 114, 435, 479, +646, 878, 657, 928, 442, 518, -6, -125, +-460, -798, -651, -1109, -557, -995, -270, -567, +53, 51, 235, 670, 201, 1106, 137, 1231, +94, 932, 59, 208, 171, -648, 367, -1180, +373, -1051, 136, -420, -306, 361, -811, 838, +-972, 665, -710, 103, -150, -383, 506, -516, +954, -190, 975, 323, 448, 678, -94, 608, +-359, 192, -494, -323, -415, -740, -410, -782, +-520, -472, -361, 46, -117, 574, 225, 852, +735, 725, 870, 293, 590, -367, 111, -947, +-427, -1118, -694, -848, -524, -79, -236, 826, +-23, 1346, 124, 1245, 78, 475, -17, -563, +89, -1214, 280, -1233, 476, -730, 556, -81, +267, 282, -159, 355, -513, 335, -642, 373, +-411, 528, -73, 508, 143, 154, 292, -263, +287, -589, 204, -710, 206, -471, 111, -200, +98, -67, 158, 130, 6, 251, -123, 419, +-247, 600, -444, 448, -407, 187, -291, -102, +-109, -482, 258, -566, 397, -421, 418, -258, +411, 126, 247, 471, 68, 584, -164, 534, +-422, 110, -599, -408, -557, -657, -397, -518, +-103, 99, 280, 789, 426, 1100, 399, 760, +261, -89, 31, -946, -34, -1368, -12, -1109, +-56, -209, -37, 844, -125, 1469, -320, 1406, +-413, 672, -363, -345, -57, -1110, 318, -1203, +493, -626, 596, 151, 467, 628, -20, 622, +-445, 216, -568, -252, -412, -467, 20, -322, +421, -10, 566, 265, 437, 470, 86, 509, +-322, 350, -611, -22, -506, -492, -212, -857, +142, -938, 492, -679, 539, -150, 361, 430, +199, 792, 33, 1006, -122, 1051, -153, 668, +-293, -18, -577, -882, -596, -1661, -357, -1717, +43, -967, 606, 161, 828, 1244, 645, 1576, +315, 1029, -214, 220, -576, -470, -636, -683, +-605, -372, -318, 37, 85, 260, 278, 202, +406, -115, 443, -406, 204, -659, -65, -715, +-338, -384, -479, 105, -273, 678, -1, 1192, +257, 1333, 427, 1022, 297, 403, -18, -414, +-388, -1115, -555, -1536, -370, -1515, 77, -888, +525, 31, 656, 920, 579, 1451, 78, 1367, +-500, 886, -662, 278, -717, -157, -398, -323, +222, -454, 577, -563, 945, -596, 1081, -507, +550, -288, -159, -50, -983, 86, -1525, 148, +-1201, 245, -390, 543, 584, 935, 1318, 996, +1301, 548, 789, -305, 250, -1107, -189, -1368, +-467, -945, -673, -56, -869, 554, -897, 512, +-719, 64, -244, -437, 451, -428, 1058, 221, +1318, 980, 1115, 1331, 445, 985, -409, -41, +-1022, -1138, -1289, -1705, -1027, -1637, -383, -885, +251, 198, 666, 930, 663, 1203, 300, 982, +-32, 412, -132, -50, -106, -251, 96, -234, +238, -170, 119, -232, 40, -374, -115, -419, +-356, -355, -390, -122, -382, 88, -230, 182, +165, 259, 383, 314, 468, 441, 381, 500, +-52, 320, -298, -107, -168, -535, 175, -726, +552, -529, 544, -30, 50, 459, -474, 659, +-866, 440, -943, 70, -502, -239, 138, -392, +764, -260, 1135, -33, 970, 89, 405, 197, +-257, 214, -720, 142, -676, 139, -298, 154, +68, 167, 208, 222, -73, 162, -476, -160, +-498, -514, -175, -780, 452, -732, 1042, -201, +1049, 464, 591, 992, -150, 1032, -910, 555, +-1248, -125, -1147, -667, -670, -785, 123, -434, +832, 67, 1189, 407, 1107, 428, 544, -14, +-159, -503, -682, -680, -988, -413, -845, 134, +-398, 627, -44, 718, 287, 306, 509, -148, +529, -395, 529, -264, 325, 57, 55, 153, +-124, -56, -350, -392, -385, -575, -357, -367, +-348, 101, -181, 466, 85, 522, 323, 251, +478, -24, 490, -136, 283, -70, 93, 26, +6, -12, -225, -173, -398, -320, -456, -231, +-445, -19, -111, 169, 328, 261, 613, 235, +725, 142, 421, 133, -159, 92, -625, -36, +-828, -184, -676, -381, -188, -371, 393, -214, +819, 74, 1006, 457, 689, 715, 55, 768, +-606, 496, -1099, -105, -1094, -759, -689, -1078, +-78, -925, 546, -229, 919, 541, 925, 915, +646, 816, 204, 353, -244, -112, -531, -279, +-638, -102, -597, 73, -437, 113, -279, -47, +-100, -365, 165, -540, 455, -507, 731, -291, +898, 112, 712, 518, 136, 787, -528, 851, +-1032, 545, -1176, -21, -773, -638, -121, -1047, +471, -941, 980, -457, 1100, 113, 753, 588, +234, 684, -393, 415, -834, 119, -787, -158, +-488, -294, -52, -234, 344, -106, 419, 27, +340, 47, 301, -28, 233, -160, 189, -197, +33, -89, -307, 86, -571, 186, -677, 68, +-512, -132, 24, -199, 553, 30, 867, 396, +903, 590, 413, 383, -238, -210, -700, -851, +-912, -1037, -673, -582, -142, 138, 211, 816, +356, 1043, 309, 642, 76, 41, 69, -442, +219, -560, 320, -255, 393, 192, 124, 417, +-337, 291, -689, -110, -870, -600, -646, -730, +-148, -353, 449, 243, 899, 828, 951, 1054, +679, 666, 118, -18, -564, -556, -894, -774, +-828, -595, -462, -149, 206, 193, 653, 420, +731, 518, 604, 395, 190, 179, -219, -219, +-456, -644, -631, -760, -549, -497, -252, 43, +86, 613, 508, 800, 728, 594, 644, 228, +380, -119, -14, -180, -385, -182, -592, -238, +-541, -356, -383, -498, -102, -492, 151, -316, +195, -18, 198, 186, 162, 318, 156, 425, +321, 536, 427, 620, 301, 500, 11, 125, +-522, -421, -945, -877, -889, -966, -442, -624, +237, -128, 839, 287, 999, 382, 716, 189, +124, -33, -484, -150, -777, -11, -711, 255, +-377, 498, 39, 651, 354, 571, 449, 272, +396, -205, 269, -739, 163, -1018, 96, -990, +-22, -653, -256, -109, -593, 345, -872, 631, +-773, 713, -142, 734, 698, 722, 1372, 599, +1458, 341, 744, -91, -270, -634, -1070, -1041, +-1371, -1037, -961, -649, -228, 35, 372, 628, +722, 847, 599, 650, 275, 148, 101, -295, +-58, -403, -82, -188, 32, 109, 10, 407, +-39, 504, -119, 401, -307, 219, -289, -74, +-136, -398, -13, -699, 204, -858, 342, -690, +290, -225, 257, 331, 97, 814, -167, 925, +-268, 652, -367, 218, -424, -224, -202, -411, +59, -351, 274, -225, 540, -101, 462, -76, +165, -179, -59, -264, -365, -222, -504, -81, +-345, 97, -232, 330, 43, 418, 344, 274, +356, 79, 363, -172, 103, -313, -237, -255, +-259, -122, -194, 30, -62, 110, 89, 88, +33, 76, -46, -6, -14, -143, 104, -232, +337, -340, 423, -247, 209, 22, -181, 306, +-546, 547, -712, 568, -567, 370, -207, 58, +220, -276, 657, -587, 891, -761, 854, -680, +542, -335, 4, 233, -611, 837, -1066, 1108, +-1135, 901, -812, 312, -152, -391, 502, -818, +909, -814, 1051, -473, 806, -67, 346, 166, +-112, 205, -521, 198, -703, 289, -718, 507, +-566, 599, -304, 403, -35, -46, 238, -634, +500, -927, 727, -740, 715, -182, 488, 471, +41, 844, -499, 793, -786, 323, -710, -222, +-462, -531, -129, -505, 199, -219, 359, 82, +409, 192, 399, 66, 283, -107, 155, -153, +26, 5, -191, 263, -307, 394, -338, 305, +-340, 54, -155, -245, 141, -384, 397, -340, +492, -206, 245, -71, -225, -18, -625, -21, +-701, -44, -268, -20, 419, 61, 939, 197, +1055, 339, 627, 434, -196, 423, -899, 166, +-1196, -279, -994, -724, -333, -1011, 340, -905, +805, -339, 948, 378, 721, 935, 280, 1088, +-189, 748, -489, 165, -602, -370, -498, -668, +-199, -633, 57, -358, 227, -40, 300, 218, +149, 317, -3, 217, -25, 27, -19, -148, +70, -205, 218, -147, 128, -2, -98, 170, +-319, 322, -480, 441, -242, 455, 141, 279, +375, -157, 438, -667, 230, -945, -108, -818, +-279, -232, -269, 496, -182, 916, -78, 876, +-1, 450, 108, -64, 308, -283, 463, -202, +390, -14, 94, 121, -396, 12, -748, -221, +-711, -425, -397, -502, 155, -395, 624, -217, +735, 64, 570, 405, 180, 696, -207, 883, +-351, 794, -300, 430, -137, -122, 27, -653, +32, -965, -139, -1017, -326, -740, -363, -308, +-174, 177, 195, 611, 626, 746, 870, 633, +698, 385, 242, 80, -439, -83, -1005, -76, +-1121, -84, -858, -172, -129, -340, 767, -472, +1291, -450, 1252, -268, 592, 41, -462, 313, +-1224, 441, -1357, 398, -807, 220, 166, -28, +903, -238, 1157, -271, 886, -106, 201, 166, +-461, 348, -843, 280, -853, -15, -429, -404, +160, -653, 584, -582, 674, -272, 371, 127, +-170, 472, -520, 651, -473, 672, -110, 533, +333, 253, 527, -94, 406, -479, 91, -774, +-296, -780, -565, -588, -563, -234, -372, 187, +20, 450, 427, 617, 664, 672, 716, 597, +358, 435, -155, 181, -533, -149, -741, -467, +-541, -713, -79, -853, 322, -816, 507, -531, +373, 25, 66, 639, -208, 1188, -320, 1313, +-226, 865, 6, 138, 233, -692, 331, -1162, +291, -1110, 74, -678, -184, 40, -322, 669, +-302, 944, -201, 798, -106, 231, 39, -432, +130, -800, 187, -695, 225, -212, 148, 291, +-36, 465, -193, 282, -121, 35, 171, -59, +436, 141, 438, 446, 12, 439, -586, 69, +-940, -463, -887, -848, -272, -829, 485, -460, +913, 13, 990, 415, 651, 552, 117, 567, +-254, 563, -531, 409, -666, 227, -531, -99, +-326, -447, -65, -625, 188, -641, 330, -418, +465, -104, 361, 169, 71, 361, -84, 422, +-204, 358, -176, 179, -44, -45, 48, -182, +175, -199, 173, -60, -37, 139, -301, 220, +-435, 163, -416, -59, -142, -335, 263, -476, +509, -437, 649, -155, 466, 274, 25, 559, +-284, 544, -450, 193, -387, -280, -123, -506, +7, -330, 30, 121, -2, 506, -197, 520, +-188, 153, 129, -286, 395, -520, 582, -460, +497, -274, 35, -142, -331, -106, -538, -89, +-582, 159, -283, 532, 3, 821, 178, 816, +415, 392, 401, -245, 246, -805, 76, -1025, +-239, -846, -351, -367, -239, 138, -111, 527, +46, 702, 139, 566, 49, 258, 35, -72, +126, -298, 113, -275, 167, -1, 144, 261, +-90, 339, -247, 127, -357, -310, -374, -611, +-135, -596, 141, -265, 327, 261, 405, 592, +267, 589, 22, 313, -158, -72, -234, -266, +-177, -207, -25, 62, 91, 260, 97, 236, +17, 8, -107, -325, -177, -483, -183, -464, +-108, -234, 103, 84, 296, 360, 380, 596, +311, 660, 38, 505, -303, 115, -531, -365, +-468, -746, -153, -758, 258, -447, 507, -23, +446, 350, 194, 468, -131, 429, -253, 305, +-224, 132, -214, -61, -176, -304, -100, -501, +46, -458, 224, -180, 358, 178, 281, 491, +57, 504, -148, 223, -286, -110, -202, -396, +-76, -439, 43, -224, 157, -8, 135, 165, +59, 176, -74, 2, -148, -152, -172, -166, +-77, -6, 131, 238, 178, 433, 105, 357, +-45, 31, -100, -340, -12, -577, 78, -485, +188, -142, 113, 222, -138, 428, -300, 362, +-280, 98, -101, -124, 126, -289, 212, -294, +134, -109, 56, 113, -8, 380, 1, 497, +46, 363, 14, 27, -13, -344, -21, -506, +-20, -385, 20, -78, -5, 146, -150, 167, +-266, 62, -219, 7, 27, 103, 323, 260, +399, 317, 253, 194, 22, -15, -154, -183, +-226, -231, -155, -191, -7, -137, 8, -59, +30, 34, 44, 183, -59, 274, -69, 207, +-69, 75, -70, -118, 124, -225, 257, -202, +215, -136, 102, -79, -123, -49, -254, 46, +-212, 166, -143, 311, 2, 379, 171, 308, +273, 132, 261, -139, 90, -407, -180, -663, +-430, -784, -518, -669, -321, -219, 164, 455, +560, 1065, 674, 1303, 507, 916, 47, 138, +-371, -705, -555, -1212, -583, -1173, -424, -755, +-103, -156, 214, 388, 554, 750, 751, 889, +513, 728, 52, 330, -515, -159, -936, -570, +-743, -704, -144, -606, 511, -374, 924, -102, +786, 117, 256, 334, -285, 522, -660, 536, +-720, 376, -472, 114, -111, -149, 356, -243, +627, -244, 563, -264, 346, -373, -107, -452, +-402, -309, -392, 75, -266, 603, 23, 878, +198, 739, 125, 240, -3, -403, -111, -748, +-171, -655, -18, -210, 264, 371, 433, 740, +453, 658, 133, 206, -458, -417, -862, -840, +-908, -818, -424, -376, 410, 299, 1063, 793, +1267, 927, 816, 654, -92, 172, -890, -272, +-1252, -565, -1076, -595, -396, -463, 333, -194, +846, 142, 1067, 390, 726, 442, 102, 231, +-356, -121, -674, -360, -658, -313, -283, 2, +55, 362, 293, 479, 338, 232, 102, -200, +-117, -540, -98, -592, 3, -323, 168, 103, +309, 484, 178, 604, -15, 430, -228, -13, +-456, -533, -401, -782, -90, -664, 289, -157, +546, 436, 469, 757, 71, 680, -323, 280, +-474, -138, -306, -411, 109, -496, 363, -484, +298, -421, 67, -256, -242, 77, -346, 511, +-158, 799, 105, 737, 281, 280, 318, -335, +181, -829, -59, -928, -216, -562, -311, 0, +-217, 550, 25, 853, 135, 757, 125, 393, +33, -110, -146, -528, -192, -670, -62, -521, +104, -188, 290, 145, 369, 335, 306, 316, +146, 224, -85, 182, -330, 221, -569, 273, +-665, 210, -520, -20, -124, -386, 424, -654, +769, -714, 800, -488, 532, 5, 47, 557, +-327, 985, -442, 1083, -339, 774, -223, 101, +-180, -631, -140, -1114, -31, -1128, 164, -670, +316, 9, 316, 591, 103, 809, -123, 659, +-221, 262, -221, -101, -63, -251, 148, -152, +264, 58, 273, 126, 176, -20, 9, -295, +-119, -497, -191, -426, -244, -81, -232, 290, +-163, 459, -161, 361, -82, 90, 117, -146, +301, -200, 465, -148, 418, -70, 154, 2, +-116, 15, -329, 68, -352, 121, -200, 67, +-101, -62, 17, -220, 66, -329, 19, -253, +49, -12, 84, 233, 66, 383, 83, 303, +24, 122, -87, -74, -84, -244, -113, -290, +-71, -281, 80, -203, 176, -38, 203, 230, +183, 461, 69, 520, -165, 357, -313, -13, +-363, -396, -288, -631, -5, -602, 216, -363, +359, 0, 475, 360, 373, 587, 116, 632, +-229, 427, -599, 79, -713, -237, -437, -389, +51, -314, 590, -127, 901, 47, 748, 93, +300, -22, -269, -151, -676, -188, -764, -97, +-667, 135, -333, 395, 121, 497, 481, 377, +678, 39, 605, -391, 277, -604, -75, -487, +-308, -100, -318, 377, -145, 655, 36, 528, +63, 79, -107, -411, -274, -741, -358, -668, +-227, -254, 140, 256, 474, 679, 637, 786, +516, 564, 37, 143, -433, -351, -652, -710, +-602, -751, -267, -498, 190, -84, 557, 329, +680, 522, 464, 471, 12, 323, -393, 155, +-645, 8, -613, -146, -317, -391, 94, -608, +471, -575, 626, -261, 497, 262, 180, 704, +-159, 747, -422, 443, -476, -33, -294, -420, +-23, -546, 227, -458, 365, -266, 331, -78, +198, 143, 8, 345, -228, 474, -357, 464, +-340, 268, -248, -53, -47, -406, 162, -615, +302, -620, 420, -409, 406, -35, 274, 398, +92, 729, -219, 800, -515, 596, -617, 116, +-486, -428, -184, -792, 162, -819, 371, -478, +471, 10, 452, 440, 316, 624, 150, 510, +-56, 235, -266, -77, -427, -302, -509, -341, +-489, -237, -243, -53, 113, 126, 452, 187, +710, 125, 692, 43, 384, 3, -79, 41, +-606, 98, -892, 62, -765, -58, -341, -202, +302, -280, 869, -277, 980, -136, 620, 57, +-8, 245, -653, 449, -924, 484, -745, 332, +-257, -8, 364, -407, 718, -604, 707, -568, +434, -306, -14, 54, -353, 317, -466, 460, +-387, 517, -132, 457, 84, 247, 153, -126, +132, -549, 10, -815, -80, -774, -23, -376, +70, 205, 166, 685, 295, 876, 254, 726, +81, 339, -134, -91, -399, -416, -447, -573, +-349, -554, -179, -413, 92, -242, 260, -66, +350, 85, 436, 217, 347, 421, 169, 592, +-20, 637, -307, 489, -505, 21, -480, -567, +-326, -964, -22, -1017, 260, -637, 330, -2, +330, 569, 186, 912, 40, 935, 65, 669, +91, 245, 38, -258, -111, -701, -397, -920, +-588, -856, -496, -542, -197, -34, 311, 473, +777, 808, 864, 933, 648, 757, 146, 324, +-487, -184, -823, -594, -823, -756, -507, -636, +44, -405, 471, -190, 586, -13, 443, 170, +131, 452, -125, 735, -161, 791, -122, 521, +-49, -49, 40, -660, -7, -927, -58, -762, +-47, -293, -47, 231, 30, 530, 79, 535, +6, 368, -29, 170, -104, 28, -194, -71, +-92, -207, 67, -324, 215, -387, 342, -366, +293, -191, 86, 72, -130, 371, -324, 618, +-337, 683, -180, 485, -34, 43, 40, -507, +8, -886, -31, -844, 37, -428, 177, 154, +278, 599, 258, 689, 105, 440, -82, 67, +-207, -205, -187, -289, -127, -179, -129, -14, +-139, 93, -132, 82, -19, -44, 206, -172, +310, -167, 296, -11, 169, 183, -80, 281, +-205, 168, -186, -117, -92, -393, 16, -455, +51, -255, -1, 108, -75, 457, -88, 600, +-52, 500, 78, 212, 232, -140, 260, -414, +176, -550, 1, -568, -194, -454, -323, -243, +-329, 73, -242, 475, -23, 792, 253, 877, +401, 624, 446, 19, 313, -675, 12, -1053, +-278, -975, -521, -426, -530, 358, -273, 875, +25, 892, 293, 426, 402, -240, 329, -661, +213, -626, 112, -211, 13, 315, -61, 567, +-240, 427, -424, 56, -440, -342, -337, -505, +-53, -373, 299, -74, 489, 249, 541, 444, +427, 424, 171, 226, -57, -18, -299, -226, +-515, -327, -588, -284, -491, -199, -238, -94, +137, 4, 481, 57, 697, 136, 718, 221, +466, 271, 23, 317, -441, 301, -728, 135, +-725, -149, -467, -419, -56, -585, 344, -522, +559, -232, 541, 124, 341, 365, 68, 377, +-196, 255, -330, 133, -320, 87, -204, 133, +-3, 173, 127, 46, 140, -203, 138, -429, +55, -519, -39, -331, -55, 4, -68, 251, +-74, 307, -53, 176, -41, 26, 54, 54, +193, 241, 221, 376, 145, 236, -36, -212, +-217, -715, -322, -896, -288, -587, -92, 105, +111, 822, 242, 1080, 265, 766, 143, 106, +35, -540, -37, -821, -82, -671, -50, -285, +-9, 76, -35, 238, -83, 210, -124, 160, +-154, 146, -46, 145, 100, 188, 183, 203, +203, 137, 120, 29, 31, -143, 14, -360, +-7, -484, -55, -441, -140, -194, -227, 144, +-239, 362, -130, 397, 22, 286, 206, 148, +359, 84, 363, 84, 275, 59, 74, -31, +-211, -172, -427, -309, -552, -365, -457, -352, +-97, -285, 267, -104, 506, 222, 566, 594, +387, 880, 116, 861, -82, 413, -297, -314, +-479, -1019, -532, -1337, -499, -1083, -241, -378, +262, 460, 702, 1089, 936, 1264, 766, 993, +151, 433, -488, -181, -907, -658, -962, -916, +-564, -899, -5, -662, 427, -322, 693, 41, +650, 379, 407, 661, 133, 854, -162, 850, +-327, 575, -362, 96, -344, -487, -209, -925, +-51, -1024, 76, -798, 162, -364, 144, 143, +88, 589, 52, 851, 60, 861, 139, 586, +219, 123, 155, -366, -51, -713, -289, -764, +-457, -558, -416, -228, -107, 149, 275, 459, +565, 640, 567, 637, 181, 376, -304, -40, +-625, -468, -650, -739, -267, -684, 277, -349, +675, 84, 778, 455, 480, 634, -18, 577, +-442, 382, -691, 99, -703, -243, -481, -506, +-144, -630, 296, -566, 677, -233, 825, 225, +701, 585, 271, 714, -314, 498, -771, 58, +-930, -375, -670, -629, -118, -509, 382, -100, +657, 321, 648, 565, 375, 436, 52, -4, +-143, -392, -246, -488, -215, -241, -158, 156, +-200, 359, -241, 216, -246, -85, -159, -256, +119, -133, 414, 210, 574, 426, 545, 315, +280, -33, -120, -396, -441, -493, -577, -282, +-541, 8, -321, 219, -22, 252, 263, 130, +510, 3, 567, -41, 384, 8, 35, 79, +-366, 101, -531, 51, -413, -51, -114, -183, +259, -261, 456, -186, 353, -30, 83, 127, +-214, 234, -362, 195, -290, 45, -150, -97, +32, -166, 219, -141, 257, -44, 239, 59, +219, 137, 82, 159, -82, 122, -270, 24, +-453, -139, -449, -241, -220, -223, 121, -81, +496, 131, 683, 223, 526, 135, 159, -38, +-284, -131, -615, -65, -616, 82, -391, 175, +-57, 98, 279, -76, 422, -178, 424, -107, +304, 73, 80, 156, -106, 72, -230, -105, +-294, -237, -227, -201, -119, -21, -44, 196, +79, 322, 216, 291, 295, 147, 342, -34, +199, -233, -106, -340, -360, -290, -542, -151, +-464, 64, -99, 230, 248, 265, 459, 201, +499, 81, 332, 1, 154, -2, 17, 28, +-170, 9, -319, -78, -437, -223, -560, -346, +-447, -337, -115, -187, 304, 61, 681, 333, +807, 500, 617, 551, 193, 485, -293, 244, +-676, -106, -766, -489, -509, -823, -105, -924, +303, -690, 578, -163, 541, 505, 264, 1005, +-168, 1076, -544, 687, -569, 18, -264, -541, +189, -685, 618, -423, 730, -19, 472, 200, +-35, 53, -557, -300, -745, -504, -572, -372, +-215, 72, 160, 594, 375, 847, 374, 695, +283, 251, 177, -303, 52, -708, -1, -791, +-35, -545, -131, -65, -154, 394, -173, 624, +-193, 562, -98, 241, 8, -160, 106, -424, +233, -447, 208, -287, 86, -27, 17, 229, +-79, 352, -89, 319, -36, 143, -114, -94, +-207, -268, -236, -325, -123, -205, 244, 51, +567, 295, 610, 439, 348, 374, -174, 83, +-673, -273, -835, -551, -644, -634, -157, -428, +412, -34, 701, 383, 728, 667, 520, 707, +48, 485, -335, 95, -552, -272, -588, -494, +-261, -520, 75, -410, 270, -239, 371, -56, +209, 60, -19, 173, -68, 286, -71, 333, +-1, 338, 85, 322, -15, 235, -132, 55, +-190, -228, -229, -565, -83, -768, 160, -694, +337, -280, 437, 297, 336, 752, 75, 883, +-199, 655, -394, 209, -476, -243, -402, -526, +-230, -611, -25, -492, 249, -228, 466, 68, +597, 306, 621, 386, 293, 273, -189, 48, +-605, -178, -866, -245, -689, -106, -228, 126, +219, 327, 596, 341, 688, 124, 458, -217, +155, -481, -143, -526, -323, -320, -307, 46, +-250, 395, -212, 569, -149, 452, -79, 138, +80, -191, 283, -399, 434, -374, 400, -169, +120, 20, -244, 96, -472, 106, -404, 117, +-95, 233, 211, 359, 294, 288, 146, -27, +-59, -470, -152, -746, -47, -623, 139, -124, +174, 471, 34, 795, -183, 658, -285, 198, +-154, -281, 103, -503, 289, -363, 308, -31, +135, 207, -98, 206, -218, -11, -201, -246, +-89, -264, 36, -49, 101, 251, 95, 434, +45, 338, -56, 8, -133, -330, -99, -508, +-13, -431, 92, -115, 202, 251, 191, 505, +123, 537, 17, 306, -136, -34, -202, -338, +-210, -482, -166, -369, -31, -103, 87, 155, +163, 272, 163, 180, 52, -49, -36, -247, +-52, -290, -20, -123, 64, 205, 96, 475, +16, 539, -40, 385, -91, 42, -117, -339, +-87, -591, -96, -646, -92, -488, -6, -177, +132, 157, 281, 398, 343, 456, 232, 383, +-24, 311, -275, 246, -422, 153, -418, -43, +-214, -368, 58, -648, 292, -665, 434, -366, +415, 103, 202, 476, -98, 533, -354, 296, +-410, 6, -204, -133, 110, -56, 342, 141, +362, 260, 86, 199, -287, -60, -506, -406, +-486, -621, -161, -599, 309, -302, 666, 196, +750, 644, 468, 826, -66, 634, -571, 165, +-808, -337, -642, -613, -171, -529, 349, -184, +622, 196, 534, 374, 186, 264, -191, -35, +-408, -333, -408, -470, -247, -355, 1, -27, +251, 385, 425, 719, 477, 787, 318, 495, +-17, -69, -381, -640, -662, -928, -663, -774, +-307, -280, 158, 244, 564, 544, 729, 551, +532, 335, 117, 58, -321, -141, -587, -224, +-526, -186, -226, -70, 155, 63, 417, 129, +396, 76, 145, -30, -183, -99, -338, -73, +-219, 5, 49, 61, 311, 24, 388, -105, +199, -198, -110, -174, -394, -35, -519, 138, +-377, 263, -48, 288, 266, 215, 486, 78, +534, -99, 387, -249, 129, -312, -168, -261, +-392, -133, -485, -9, -473, 48, -325, 42, +-13, 74, 348, 189, 580, 343, 532, 402, +235, 230, -158, -135, -427, -492, -432, -606, +-194, -393, 106, -7, 239, 294, 108, 337, +-90, 194, -140, 62, -9, 53, 224, 120, +378, 122, 303, -19, 29, -223, -355, -333, +-639, -262, -645, -51, -369, 163, 131, 286, +612, 302, 900, 215, 823, 55, 353, -155, +-257, -323, -764, -358, -905, -227, -634, 11, +-206, 218, 251, 320, 547, 290, 592, 220, +490, 160, 229, 67, -84, -88, -358, -294, +-542, -457, -467, -484, -136, -324, 202, -17, +442, 300, 441, 532, 194, 615, -67, 506, +-238, 228, -282, -148, -167, -524, -61, -733, +-9, -650, 54, -304, 108, 182, 138, 574, +150, 690, 108, 491, 8, 113, -69, -261, +-111, -508, -144, -516, -132, -341, -119, -50, +-150, 243, -92, 391, 56, 370, 252, 190, +442, 0, 484, -77, 304, -48, -44, -37, +-490, -172, -798, -398, -747, -535, -383, -413, +144, -14, 599, 485, 782, 794, 677, 768, +346, 447, -89, -11, -407, -449, -518, -739, +-452, -753, -261, -519, -24, -102, 142, 326, +231, 554, 194, 531, 55, 333, -6, 140, +24, 53, 81, 1, 147, -104, 99, -298, +-43, -509, -177, -549, -311, -317, -291, 93, +-61, 509, 199, 749, 388, 684, 427, 360, +203, -70, -112, -488, -375, -722, -527, -657, +-414, -335, -80, 133, 225, 531, 453, 646, +494, 458, 312, 97, 92, -208, -172, -274, +-381, -179, -377, -89, -277, -86, -93, -131, +138, -110, 232, 49, 227, 251, 113, 318, +-78, 221, -153, 24, -102, -101, 17, -116, +191, -118, 231, -168, 95, -292, -96, -339, +-318, -148, -396, 239, -183, 612, 123, 747, +376, 488, 445, -80, 204, -669, -144, -999, +-400, -857, -439, -289, -190, 419, 185, 923, +420, 965, 462, 527, 276, -108, -69, -613, +-338, -810, -482, -638, -476, -270, -226, 86, +89, 371, 396, 513, 627, 500, 540, 347, +235, 52, -132, -282, -477, -494, -584, -482, +-450, -269, -200, 11, 144, 151, 349, 113, +366, 23, 316, 16, 160, 203, 13, 459, +-81, 536, -211, 299, -223, -183, -200, -673, +-167, -903, -15, -748, 134, -287, 219, 301, +193, 785, 27, 998, -119, 844, -101, 367, +23, -254, 171, -742, 225, -882, 40, -662, +-280, -202, -496, 236, -447, 516, -40, 569, +451, 417, 673, 193, 556, -71, 124, -275, +-375, -306, -615, -209, -542, -36, -201, 127, +232, 166, 423, 110, 370, 25, 176, -36, +-87, -57, -250, -44, -236, -16, -128, 18, +48, 77, 176, 84, 184, 13, 155, -75, +87, -134, -67, -92, -198, 55, -301, 172, +-300, 160, -100, -3, 184, -214, 430, -275, +503, -151, 256, 102, -150, 281, -450, 245, +-513, 57, -257, -152, 114, -216, 367, -166, +369, -118, 130, -156, -155, -193, -279, -73, +-169, 221, 64, 554, 216, 632, 198, 305, +5, -275, -235, -771, -312, -885, -161, -529, +132, 48, 357, 515, 336, 676, 97, 463, +-181, 89, -345, -192, -282, -259, -75, -136, +97, 29, 144, 57, 85, -79, 36, -238, +123, -278, 232, -94, 196, 186, 28, 346, +-256, 320, -473, 124, -444, -87, -213, -163, +156, -116, 484, -43, 538, -10, 372, -13, +78, 13, -229, 101, -441, 179, -457, 159, +-253, 14, 63, -184, 323, -284, 376, -169, +214, 97, -9, 325, -216, 378, -267, 188, +-150, -86, 8, -242, 166, -218, 224, -29, +146, 132, 51, 155, -105, 48, -258, -123, +-230, -205, -86, -144, 154, 34, 342, 233, +260, 318, 23, 208, -253, -21, -428, -229, +-279, -276, 50, -110, 329, 129, 463, 236, +310, 137, 10, -98, -220, -312, -386, -346, +-394, -218, -234, -22, -55, 172, 171, 293, +359, 329, 390, 301, 339, 181, 202, -13, +-43, -201, -252, -344, -419, -424, -510, -441, +-412, -393, -157, -243, 175, 38, 508, 381, +631, 650, 487, 696, 218, 469, -137, 92, +-366, -296, -378, -519, -355, -560, -271, -497, +-143, -376, -35, -228, 169, -3, 332, 271, +359, 521, 316, 599, 173, 448, -14, 154, +-113, -137, -187, -257, -238, -228, -261, -191, +-281, -219, -224, -279, -45, -291, 194, -101, +422, 201, 535, 443, 420, 525, 135, 351, +-249, 87, -578, -125, -607, -212, -355, -186, +31, -124, 386, -81, 462, -88, 307, -55, +49, 53, -165, 234, -179, 396, -114, 357, +-50, 65, -31, -336, -67, -607, -15, -512, +105, -44, 178, 491, 203, 776, 83, 635, +-83, 182, -195, -282, -239, -539, -188, -515, +-83, -325, 19, -109, 109, 67, 189, 192, +253, 277, 223, 295, 115, 244, -20, 132, +-132, 7, -141, -83, -133, -158, -165, -215, +-197, -281, -221, -313, -152, -242, 47, -70, +268, 151, 474, 322, 550, 375, 378, 316, +43, 199, -333, 19, -623, -204, -651, -440, +-429, -628, -53, -605, 337, -283, 532, 224, +466, 674, 270, 848, 22, 618, -178, 123, +-237, -407, -257, -799, -207, -872, -74, -624, +60, -114, 178, 481, 206, 871, 91, 857, +-70, 420, -185, -191, -142, -640, 41, -706, +221, -420, 279, -35, 153, 221, -96, 270, +-369, 192, -501, 122, -381, 102, -52, 119, +380, 122, 731, 83, 737, -4, 391, -142, +-186, -281, -713, -345, -892, -257, -639, -10, +-100, 328, 424, 553, 639, 540, 500, 293, +189, -64, -65, -331, -164, -423, -127, -348, +-54, -200, -33, -22, -54, 141, -118, 320, +-161, 461, -119, 441, -15, 245, 124, -94, +229, -397, 241, -525, 182, -405, 36, -141, +-178, 134, -304, 332, -269, 371, -126, 321, +82, 189, 254, 17, 319, -125, 281, -205, +91, -246, -156, -284, -329, -327, -387, -312, +-273, -112, -48, 262, 128, 661, 254, 797, +263, 519, 200, -51, 177, -617, 146, -864, +30, -745, -131, -384, -332, 17, -423, 295, +-302, 457, -122, 507, 110, 434, 285, 236, +273, -62, 216, -323, 191, -471, 166, -460, +128, -315, -54, -131, -319, 62, -484, 232, +-478, 350, -248, 353, 158, 210, 479, -42, +608, -266, 472, -349, 93, -267, -308, -80, +-568, 88, -564, 185, -270, 214, 162, 243, +523, 222, 587, 92, 339, -166, -69, -466, +-448, -572, -550, -376, -359, 76, 5, 548, +349, 769, 444, 626, 319, 226, 91, -205, +-147, -493, -278, -543, -294, -390, -180, -127, +-13, 163, 98, 354, 160, 385, 155, 272, +109, 83, 32, -58, -52, -107, -67, -78, +-19, -16, 37, 35, 58, 62, -23, 35, +-127, -64, -220, -189, -240, -250, -87, -139, +175, 178, 384, 508, 412, 622, 210, 374, +-88, -144, -325, -642, -397, -837, -272, -605, +-27, -114, 194, 428, 232, 752, 146, 747, +35, 472, -47, -10, -58, -485, -53, -767, +-32, -726, -6, -370, -26, 140, -22, 526, +6, 595, 54, 348, 103, -62, 59, -351, +-29, -400, -99, -232, -126, 7, -91, 182, +-6, 221, 98, 132, 159, -7, 125, -158, +50, -249, -23, -240, -56, -108, -74, 74, +-129, 171, -179, 117, -187, -41, -117, -156, +61, -105, 275, 107, 431, 315, 435, 359, +240, 188, -69, -125, -384, -399, -571, -531, +-554, -475, -349, -229, -18, 96, 321, 411, +520, 615, 546, 600, 388, 389, 110, 64, +-168, -263, -349, -484, -402, -534, -317, -423, +-150, -170, 61, 156, 240, 433, 300, 536, +241, 435, 57, 164, -197, -150, -362, -318, +-354, -314, -137, -134, 220, 99, 492, 225, +568, 227, 382, 79, 1, -117, -361, -225, +-583, -175, -569, 20, -321, 248, -27, 374, +207, 292, 345, 27, 343, -272, 304, -440, +229, -388, 95, -147, -19, 148, -149, 365, +-302, 409, -356, 286, -302, 75, -168, -158, +43, -331, 224, -376, 298, -274, 322, -48, +234, 170, 68, 267, -85, 191, -247, -13, +-315, -177, -262, -204, -172, -91, 24, 62, +251, 152, 356, 134, 344, 31, 171, -75, +-128, -190, -356, -249, -445, -219, -334, -100, +19, 101, 335, 274, 458, 295, 359, 133, +29, -106, -316, -299, -450, -319, -351, -170, +-33, 40, 328, 221, 492, 285, 390, 223, +81, 64, -268, -111, -468, -288, -455, -374, +-255, -323, 78, -150, 362, 146, 467, 437, +387, 622, 154, 577, -140, 282, -345, -162, +-422, -572, -306, -745, -30, -611, 220, -240, +362, 179, 316, 460, 105, 525, -110, 442, +-242, 320, -241, 233, -102, 168, 38, 40, +121, -196, 98, -477, 20, -658, -13, -633, +-19, -359, 23, 86, 96, 518, 109, 826, +78, 911, -31, 702, -177, 258, -281, -334, +-300, -857, -137, -1071, 136, -860, 383, -280, +493, 399, 367, 896, 53, 976, -295, 638, +-486, 59, -425, -500, -197, -785, 94, -705, +286, -314, 288, 146, 166, 458, -20, 491, +-131, 287, -93, 30, -13, -152, 84, -206, +108, -204, 29, -202, -35, -191, -84, -115, +-82, 39, -41, 200, -42, 243, -77, 100, +-116, -135, -97, -298, 53, -258, 244, -36, +337, 231, 270, 358, 81, 255, -159, 10, +-309, -265, -308, -411, -196, -363, -13, -191, +120, 43, 162, 220, 148, 277, 57, 218, +-66, 70, -129, -85, -128, -156, -4, -87, +189, 53, 298, 189, 273, 234, 105, 115, +-139, -113, -323, -325, -390, -424, -342, -352, +-203, -95, -28, 230, 151, 503, 341, 598, +457, 473, 438, 190, 298, -135, 36, -336, +-259, -406, -454, -342, -500, -209, -390, -74, +-165, 85, 90, 231, 287, 333, 353, 344, +303, 265, 171, 108, 34, -47, -32, -137, +-23, -175, -9, -160, -67, -137, -202, -131, +-352, -116, -388, -44, -208, 88, 136, 272, +481, 443, 648, 470, 541, 273, 195, -102, +-288, -510, -694, -775, -812, -735, -565, -382, +-56, 150, 495, 659, 857, 927, 859, 835, +471, 407, -121, -211, -650, -743, -920, -972, +-786, -815, -325, -355, 214, 170, 659, 528, +826, 576, 614, 383, 189, 116, -258, -68, +-541, -106, -527, -82, -328, -83, -77, -157, +158, -260, 240, -290, 199, -206, 152, -68, +63, 79, -37, 177, -90, 233, -105, 287, +-34, 276, 75, 165, 106, -68, 59, -356, +-54, -555, -173, -513, -184, -208, -70, 209, +94, 566, 208, 674, 179, 473, 28, 76, +-113, -321, -185, -532, -160, -481, -26, -239, +111, 46, 222, 235, 252, 286, 113, 240, +-80, 174, -254, 136, -335, 105, -215, 43, +22, -33, 221, -96, 307, -124, 220, -101, +22, -65, -168, -42, -271, -27, -243, -4, +-90, 33, 104, 101, 281, 208, 379, 276, +316, 295, 80, 227, -238, 39, -489, -214, +-535, -429, -338, -503, -16, -363, 289, -40, +469, 286, 463, 484, 300, 457, 53, 224, +-166, -58, -277, -234, -285, -242, -191, -145, +-52, -27, 50, 8, 75, -50, 11, -153, +-56, -189, -59, -109, -3, 71, 114, 294, +240, 384, 297, 267, 221, -44, 6, -407, +-249, -601, -441, -499, -454, -136, -241, 289, +93, 563, 404, 530, 511, 221, 335, -181, +4, -500, -303, -596, -430, -423, -343, -80, +-125, 271, 142, 478, 371, 444, 482, 195, +381, -108, 88, -317, -263, -341, -565, -193, +-654, 11, -412, 159, 19, 184, 427, 111, +617, -18, 496, -142, 205, -180, -81, -102, +-252, 72, -252, 266, -164, 389, -89, 318, +-46, 75, -51, -219, -97, -429, -105, -420, +-24, -198, 103, 117, 235, 347, 305, 421, +263, 329, 133, 148, -46, -3, -191, -128, +-258, -203, -286, -210, -281, -136, -220, 5, +-85, 187, 153, 299, 409, 261, 530, 88, +445, -150, 147, -327, -234, -324, -494, -98, +-547, 222, -368, 455, -30, 476, 258, 218, +394, -185, 374, -486, 175, -537, -72, -334, +-229, 18, -248, 321, -109, 424, 61, 366, +122, 196, 67, -41, -45, -243, -128, -398, +-116, -457, 6, -347, 157, -91, 240, 210, +209, 442, 38, 478, -178, 276, -340, -37, +-378, -322, -215, -468, 98, -433, 413, -234, +549, 6, 410, 163, 53, 243, -344, 203, +-551, 83, -463, -45, -199, -125, 93, -146, +289, -91, 317, 14, 220, 73, 90, 67, +9, -13, -6, -135, 4, -191, -7, -115, +-74, 42, -179, 205, -273, 272, -283, 162, +-151, -54, 82, -245, 291, -286, 397, -139, +334, 118, 137, 343, -27, 404, -128, 269, +-199, 17, -223, -229, -241, -372, -236, -352, +-126, -194, 51, 47, 245, 288, 364, 417, +301, 381, 153, 248, -1, 76, -144, -67, +-230, -119, -252, -151, -194, -211, -70, -262, +65, -233, 154, -99, 141, 145, 80, 382, +26, 482, 15, 429, 78, 238, 142, -7, +111, -216, -46, -360, -250, -442, -363, -425, +-351, -292, -214, -61, 32, 229, 293, 498, +510, 631, 593, 534, 442, 241, 107, -170, +-314, -585, -653, -803, -736, -712, -546, -346, +-168, 160, 270, 592, 589, 721, 669, 519, +537, 116, 229, -310, -179, -547, -486, -524, +-560, -340, -420, -99, -123, 112, 178, 218, +333, 240, 346, 240, 244, 178, 113, 54, +8, -87, -151, -243, -319, -381, -377, -430, +-311, -352, -96, -151, 221, 148, 447, 448, +473, 617, 320, 595, 78, 376, -150, 1, +-321, -428, -398, -744, -349, -858, -213, -683, +-32, -216, 153, 372, 280, 853, 313, 1047, +272, 881, 181, 404, 55, -181, -83, -670, +-210, -939, -289, -883, -288, -533, -188, -3, +-6, 559, 154, 946, 211, 986, 204, 681, +181, 156, 117, -394, 3, -756, -118, -795, +-216, -550, -228, -122, -131, 359, 6, 677, +124, 705, 146, 481, 78, 94, 32, -280, +45, -466, 61, -424, 41, -259, -37, -74, +-155, 81, -183, 195, -76, 314, 59, 431, +144, 402, 129, 164, 16, -225, -83, -601, +-119, -734, -109, -518, -32, -88, 56, 328, +116, 573, 189, 574, 199, 386, 104, 146, +-56, -97, -222, -332, -286, -504, -226, -561, +-117, -498, -12, -287, 66, 15, 143, 311, +251, 538, 338, 648, 304, 547, 112, 219, +-184, -234, -458, -695, -545, -942, -371, -797, +-22, -337, 336, 233, 514, 682, 460, 825, +258, 607, -30, 213, -293, -184, -388, -470, +-327, -556, -195, -490, -54, -340, 23, -118, +93, 149, 239, 405, 390, 596, 470, 628, +371, 403, -2, -25, -468, -490, -755, -800, +-709, -789, -295, -393, 257, 204, 606, 724, +629, 972, 385, 827, 9, 351, -294, -227, +-385, -690, -295, -895, -87, -763, 137, -312, +241, 266, 215, 770, 76, 1003, -109, 834, +-176, 371, -131, -168, -42, -616, 33, -820, +-11, -730, -80, -453, -53, -53, 59, 408, +205, 775, 273, 908, 195, 735, 39, 272, +-103, -327, -183, -808, -185, -979, -170, -786, +-193, -292, -165, 306, -35, 763, 138, 914, +326, 718, 411, 242, 296, -306, 74, -672, +-159, -752, -331, -584, -378, -267, -310, 29, +-143, 220, 113, 366, 311, 473, 345, 480, +268, 370, 93, 96, -92, -304, -167, -626, +-194, -752, -201, -640, -173, -330, -152, 52, +-49, 387, 165, 607, 349, 694, 410, 572, +277, 253, -7, -181, -257, -619, -389, -884, +-387, -830, -252, -473, -49, 48, 150, 570, +311, 895, 394, 877, 345, 514, 170, -50, +-100, -601, -366, -875, -466, -729, -406, -303, +-242, 198, 38, 535, 327, 575, 525, 413, +569, 204, 376, 21, 34, -116, -324, -218, +-607, -322, -654, -349, -440, -204, -90, 48, +284, 309, 557, 464, 612, 415, 457, 181, +153, -67, -202, -228, -450, -261, -502, -155, +-376, -12, -129, 66, 96, 93, 213, 108, +287, 153, 319, 218, 261, 244, 139, 127, +-71, -148, -340, -461, -454, -618, -343, -461, +-90, 29, 215, 612, 367, 968, 321, 907, +169, 404, -44, -323, -157, -917, -145, -1149, +-147, -953, -129, -407, -51, 297, 45, 894, +113, 1187, 131, 1051, 79, 489, -24, -295, +-110, -974, -121, -1279, -33, -1070, 66, -438, +87, 321, 74, 879, 11, 1041, -73, 752, +-80, 160, -42, -436, 19, -778, 116, -779, +145, -458, 80, -7, -35, 335, -171, 480, +-236, 451, -203, 286, -114, 71, 55, -153, +222, -378, 262, -558, 231, -576, 169, -383, +60, 10, -63, 498, -175, 858, -242, 919, +-243, 658, -197, 116, -128, -534, -34, -1039, +98, -1206, 208, -975, 297, -363, 336, 439, +247, 1121, 98, 1442, -97, 1298, -310, 686, +-410, -184, -396, -986, -274, -1463, -18, -1403, +261, -783, 464, 127, 506, 963, 317, 1402, +-9, 1261, -303, 648, -452, -71, -390, -640, +-169, -919, 50, -885, 183, -641, 229, -256, +204, 262, 164, 812, 128, 1157, 44, 1094, +-81, 549, -197, -320, -277, -1102, -249, -1427, +-114, -1158, 21, -432, 156, 420, 232, 1052, +216, 1282, 178, 1096, 88, 574, -43, -124, +-137, -779, -227, -1202, -266, -1261, -158, -880, +34, -168, 224, 621, 335, 1227, 264, 1394, +58, 1021, -179, 231, -380, -687, -410, -1392, +-243, -1591, 18, -1200, 280, -382, 447, 602, +481, 1411, 400, 1754, 192, 1509, -147, 705, +-488, -438, -719, -1540, -771, -2178, -525, -2051, +-33, -1140, 530, 260, 974, 1616, 1067, 2360, +765, 2204, 179, 1243, -518, -134, -1046, -1391, +-1209, -2081, -939, -2013, -305, -1277, 448, -166, +1038, 921, 1247, 1639, 1001, 1794, 387, 1350, +-380, 470, -1001, -533, -1241, -1348, -1009, -1706, +-419, -1449, 307, -638, 919, 425, 1165, 1358, +962, 1810, 465, 1579, -133, 771, -659, -282, +-965, -1220, -976, -1736, -734, -1680, -276, -1069, +322, -80, 871, 1006, 1204, 1831, 1162, 2085, +680, 1630, -94, 549, -936, -807, -1528, -1928, +-1549, -2384, -968, -1975, 12, -784, 1068, 762, +1771, 2054, 1795, 2584, 1124, 2094, -12, 767, +-1161, -856, -1838, -2097, -1799, -2448, -1091, -1811, +-1, -521, 1012, 851, 1610, 1791, 1605, 2015, +1015, 1521, 132, 557, -700, -545, -1224, -1444, +-1289, -1845, -941, -1593, -355, -790, 293, 287, +776, 1240, 984, 1726, 940, 1579, 614, 895, +93, -76, -427, -1008, -841, -1596, -994, -1688, +-808, -1238, -378, -336, 215, 720, 777, 1579, +1064, 1909, 1014, 1535, 607, 553, -93, -686, +-790, -1721, -1213, -2133, -1202, -1735, -706, -659, +81, 701, 812, 1808, 1231, 2211, 1216, 1775, +762, 652, 35, -718, -707, -1813, -1213, -2220, +-1242, -1778, -819, -637, -128, 760, 626, 1865, +1103, 2233, 1152, 1701, 805, 505, 187, -841, +-415, -1796, -835, -1990, -972, -1404, -781, -335, +-388, 785, 114, 1561, 591, 1722, 839, 1261, +786, 368, 491, -632, 91, -1343, -297, -1493, +-575, -1068, -660, -250, -573, 609, -355, 1171, +-45, 1271, 279, 919, 546, 267, 675, -441, +597, -993, 312, -1213, -94, -991, -509, -385, +-749, 423, -709, 1137, -408, 1427, 65, 1161, +495, 407, 687, -557, 594, -1342, 307, -1609, +-19, -1240, -281, -359, -424, 690, -457, 1463, +-419, 1623, -289, 1124, -7, 191, 362, -784, +631, -1397, 669, -1454, 408, -966, -45, -116, +-437, 755, -629, 1320, -590, 1351, -333, 810, +-31, -117, 227, -1034, 427, -1515, 498, -1327, +451, -525, 281, 521, -30, 1316, -360, 1526, +-572, 1105, -579, 255, -372, -669, -13, -1333, +366, -1526, 616, -1158, 660, -355, 428, 606, +3, 1393, -416, 1670, -705, 1292, -725, 399, +-448, -694, -43, -1547, 393, -1762, 733, -1272, +818, -261, 648, 877, 240, 1651, -317, 1756, +-786, 1178, -1014, 130, -868, -977, -352, -1702, +289, -1773, 814, -1188, 1045, -133, 896, 1042, +451, 1883, -144, 2059, -702, 1465, -1039, 217, +-1016, -1218, -593, -2232, 97, -2394, 766, -1575, +1150, -47, 1104, 1544, 604, 2544, -155, 2547, +-853, 1517, -1267, -164, -1227, -1800, -694, -2729, +137, -2562, 978, -1322, 1500, 491, 1435, 2112, +794, 2885, -156, 2462, -1072, 1024, -1600, -810, +-1513, -2320, -892, -2903, 22, -2332, 954, -884, +1556, 919, 1624, 2379, 1110, 2926, 159, 2390, +-874, 943, -1586, -911, -1699, -2453, -1165, -3118, +-204, -2628, 816, -1106, 1528, 894, 1679, 2593, +1202, 3315, 278, 2715, -773, 1020, -1548, -1097, +-1716, -2763, -1213, -3279, -211, -2481, 866, -749, +1574, 1190, 1653, 2559, 1097, 2889, 144, 2125, +-854, 611, -1527, -1083, -1623, -2326, -1108, -2660, +-138, -1975, 890, -560, 1584, 1066, 1652, 2252, +1044, 2528, 71, 1850, -893, 461, -1529, -1109, +-1555, -2231, -1033, -2490, -178, -1807, 757, -410, +1412, 1205, 1569, 2364, 1177, 2609, 338, 1824, +-629, 255, -1365, -1455, -1628, -2536, -1309, -2595, +-485, -1606, 521, 79, 1358, 1697, 1753, 2580, +1478, 2411, 595, 1225, -539, -443, -1471, -1809, +-1825, -2299, -1432, -1808, -500, -643, 557, 618, +1330, 1441, 1566, 1621, 1275, 1262, 583, 549, +-281, -255, -941, -893, -1270, -1267, -1230, -1244, +-753, -742, -76, 49, 555, 841, 1005, 1335, +1081, 1255, 822, 626, 396, -195, -148, -860, +-640, -1149, -904, -967, -935, -451, -670, 106, +-165, 558, 324, 809, 703, 765, 891, 510, +786, 149, 481, -259, 67, -575, -416, -712, +-795, -663, -956, -406, -839, 13, -401, 448, +180, 721, 665, 716, 988, 423, 997, -54, +701, -462, 250, -610, -334, -532, -879, -292, +-1185, 11, -1193, 204, -746, 280, 73, 322, +948, 315, 1560, 292, 1581, 246, 944, 63, +-99, -288, -1166, -670, -1802, -909, -1713, -833, +-930, -322, 262, 480, 1383, 1225, 1967, 1606, +1758, 1387, 815, 522, -448, -685, -1557, -1720, +-2106, -2188, -1793, -1836, -786, -689, 562, 833, +1770, 2149, 2262, 2760, 1863, 2290, 710, 775, +-821, -1158, -2025, -2717, -2415, -3225, -1788, -2324, +-329, -392, 1255, 1728, 2272, 3204, 2338, 3394, +1376, 2141, -197, 12, -1663, -2173, -2406, -3599, +-2122, -3592, -907, -2095, 698, 311, 2000, 2753, +2467, 4213, 1879, 3968, 499, 2065, -1108, -764, +-2275, -3431, -2498, -4795, -1663, -4220, -137, -1899, +1455, 1286, 2494, 4109, 2497, 5304, 1434, 4282, +-161, 1477, -1732, -2018, -2676, -4776, -2515, -5530, +-1320, -4002, 449, -888, 2091, 2620, 2903, 5102, +2578, 5480, 1160, 3695, -761, 475, -2379, -3024, +-3132, -5373, -2596, -5553, -945, -3571, 1014, -139, +2619, 3470, 3245, 5640, 2490, 5487, 773, 3195, +-1271, -400, -2911, -3832, -3294, -5600, -2317, -5120, +-432, -2697, 1709, 798, 3156, 3943, 3286, 5395, +2087, 4688, 11, 2147, -2149, -1315, -3478, -4163, +-3379, -5177, -1901, -4119, 420, -1434, 2671, 1832, +3859, 4225, 3532, 4833, 1736, 3563, -841, 853, +-3083, -2227, -4153, -4284, -3569, -4544, -1498, -3025, +1112, -228, 3309, 2653, 4262, 4268, 3447, 4120, +1254, 2314, -1404, -502, -3514, -2956, -4135, -3952, +-3035, -3304, -786, -1298, 1724, 1182, 3491, 2923, +3773, 3331, 2538, 2415, 343, 499, -1987, -1545, +-3451, -2772, -3441, -2812, -2071, -1713, 145, 154, +2302, 1895, 3405, 2770, 3091, 2555, 1516, 1242, +-656, -699, -2470, -2326, -3207, -2944, -2622, -2317, +-1020, -623, 924, 1369, 2492, 2673, 3014, 2828, +2269, 1825, 617, 2, -1266, -1778, -2628, -2704, +-2820, -2559, -1780, -1321, -44, 561, 1678, 2098, +2646, 2673, 2420, 2155, 1169, 605, -539, -1249, +-1950, -2419, -2443, -2516, -1880, -1523, -535, 244, +987, 1841, 1992, 2481, 2054, 2066, 1273, 764, +37, -942, -1162, -2126, -1781, -2347, -1620, -1689, +-910, -268, 148, 1336, 1178, 2268, 1680, 2260, +1539, 1344, 797, -279, -401, -1786, -1424, -2397, +-1811, -2041, -1469, -832, -430, 832, 789, 2053, +1618, 2304, 1802, 1678, 1197, 294, 123, -1277, +-943, -2166, -1643, -2138, -1659, -1298, -1049, 181, +-54, 1570, 1014, 2165, 1670, 1881, 1620, 794, +949, -734, -77, -1780, -1069, -1871, -1567, -1161, +-1417, 115, -815, 1270, 128, 1560, 994, 1057, +1329, 89, 1213, -935, 713, -1359, -102, -966, +-815, -128, -1196, 795, -1153, 1384, -604, 1269, +220, 559, 923, -380, 1200, -1238, 956, -1614, +312, -1253, -512, -359, -1068, 718, -1069, 1586, +-665, 1773, 11, 1127, 646, -38, 858, -1189, +805, -1793, 577, -1483, 121, -401, -299, 801, +-612, 1541, -862, 1523, -851, 690, -503, -454, +-4, -1295, 574, -1573, 1082, -1104, 1161, -71, +732, 934, 68, 1566, -650, 1570, -1162, 827, +-1201, -288, -795, -1313, -132, -1859, 643, -1574, +1228, -541, 1324, 760, 899, 1756, 146, 1941, +-726, 1189, -1438, -118, -1620, -1403, -1119, -2088, +-123, -1785, 1044, -612, 1873, 890, 1942, 2090, +1252, 2336, 16, 1437, -1289, -167, -2142, -1794, +-2215, -2681, -1397, -2333, -48, -961, 1312, 845, +2286, 2372, 2409, 2910, 1603, 2226, 212, 626, +-1349, -1319, -2444, -2801, -2519, -3117, -1641, -2101, +-94, -174, 1553, 1898, 2488, 3182, 2404, 3036, +1368, 1580, -271, -561, -1729, -2476, -2419, -3211, +-2056, -2490, -803, -712, 691, 1393, 1844, 2829, +2152, 2913, 1491, 1720, 307, -247, -948, -2130, +-1783, -2962, -1775, -2379, -1048, -704, 48, 1314, +1118, 2676, 1660, 2737, 1446, 1580, 664, -252, +-390, -1969, -1256, -2773, -1483, -2358, -1047, -921, +-192, 1000, 759, 2555, 1313, 2987, 1211, 2065, +568, 135, -354, -1983, -1183, -3251, -1414, -3001, +-917, -1326, 66, 1044, 1153, 3024, 1697, 3602, +1356, 2508, 345, 278, -950, -2150, -1843, -3631, +-1833, -3472, -1009, -1834, 333, 642, 1580, 2912, +2074, 3869, 1689, 3135, 605, 1030, -835, -1601, +-1929, -3508, -2149, -3798, -1466, -2426, -117, 20, +1343, 2438, 2180, 3657, 2050, 3254, 1042, 1479, +-422, -983, -1728, -2966, -2283, -3602, -1875, -2773, +-711, -709, 776, 1737, 2022, 3366, 2484, 3571, +1919, 2260, 480, -144, -1230, -2496, -2452, -3697, +-2633, -3329, -1702, -1479, -38, 1095, 1650, 3060, +2600, 3592, 2431, 2641, 1227, 484, -478, -1878, +-1856, -3226, -2366, -3207, -1911, -1831, -656, 490, +826, 2514, 1838, 3327, 2007, 2741, 1303, 859, +47, -1453, -1083, -2968, -1629, -3135, -1487, -1970, +-702, 135, 369, 2133, 1205, 3036, 1493, 2674, +1079, 1190, 121, -865, -853, -2412, -1388, -2848, +-1313, -2142, -584, -441, 471, 1467, 1319, 2638, +1601, 2698, 1128, 1577, 75, -302, -1016, -1998, +-1683, -2773, -1687, -2346, -1001, -880, 169, 962, +1322, 2287, 1958, 2604, 1874, 1860, 967, 345, +-361, -1203, -1468, -2131, -2094, -2229, -1939, -1431, +-919, -122, 416, 1059, 1586, 1806, 2196, 1843, +1830, 1129, 689, 78, -617, -940, -1714, -1564, +-2095, -1487, -1489, -807, -328, 92, 901, 836, +1774, 1148, 1818, 945, 1104, 426, 28, -111, +-1069, -511, -1743, -697, -1651, -659, -909, -479, +142, -184, 1190, 191, 1771, 526, 1559, 721, +777, 647, -259, 287, -1244, -177, -1648, -586, +-1351, -764, -667, -599, 250, -259, 1064, 124, +1298, 487, 1068, 617, 569, 495, -140, 294, +-687, -42, -854, -415, -778, -535, -478, -470, +-29, -254, 311, 200, 453, 527, 505, 506, +384, 305, 153, -95, -1, -523, -174, -577, +-321, -333, -320, 46, -285, 515, -168, 752, +49, 597, 240, 219, 376, -306, 399, -779, +247, -894, -60, -643, -376, -97, -516, 602, +-462, 1084, -205, 1142, 212, 672, 535, -228, +616, -1038, 444, -1393, 36, -1117, -388, -186, +-572, 867, -513, 1505, -276, 1511, 21, 713, +278, -531, 385, -1535, 369, -1874, 299, -1297, +143, 17, -40, 1426, -182, 2216, -375, 1989, +-498, 787, -417, -959, -237, -2358, 55, -2678, +464, -1775, 740, 104, 812, 2081, 615, 3078, +-1, 2672, -758, 966, -1243, -1315, -1284, -2992, +-697, -3308, 294, -2109, 1152, 109, 1615, 2302, +1397, 3464, 540, 3033, -516, 1229, -1418, -1187, +-1777, -3170, -1416, -3699, -504, -2559, 725, -245, +1749, 2372, 2081, 3931, 1523, 3598, 165, 1614, +-1332, -1249, -2237, -3646, -2221, -4225, -1135, -2816, +530, -144, 1899, 2717, 2516, 4310, 2028, 3775, +496, 1584, -1180, -1375, -2325, -3879, -2573, -4457, +-1598, -2918, 111, -148, 1686, 2888, 2645, 4625, +2471, 4029, 1044, 1730, -738, -1373, -2148, -4002, +-2795, -4567, -2108, -3043, -450, -304, 1266, 2650, +2602, 4261, 2805, 3794, 1545, 1769, -288, -1000, +-1955, -3208, -2911, -3730, -2407, -2520, -742, -205, +1113, 2083, 2578, 3162, 2910, 2637, 1729, 875, +-175, -1187, -1979, -2469, -3009, -2459, -2575, -1230, +-898, 571, 1144, 1945, 2740, 2315, 3107, 1576, +1965, 80, -49, -1314, -1994, -1958, -3099, -1698, +-2825, -674, -1274, 537, 747, 1312, 2469, 1389, +3238, 850, 2548, 58, 745, -539, -1339, -696, +-2979, -462, -3338, -155, -2135, -4, -49, -23, +2104, -166, 3423, -212, 3100, 57, 1374, 436, +-903, 647, -2824, 612, -3421, 129, -2372, -629, +-311, -979, 1853, -845, 3149, -298, 2859, 645, +1204, 1124, -897, 849, -2528, 271, -2887, -643, +-1736, -1216, 223, -868, 1970, -173, 2694, 690, +2010, 1301, 200, 932, -1731, -23, -2723, -1008, +-2279, -1594, -479, -1167, 1712, 105, 2964, 1456, +2689, 2119, 913, 1579, -1562, 23, -3238, -1846, +-3216, -2839, -1536, -2200, 1090, -358, 3201, 1915, +3649, 3377, 2342, 2852, -141, 830, -2655, -1613, +-3871, -3393, -3229, -3225, -1119, -1285, 1504, 1097, +3440, 2861, 3795, 3048, 2553, 1519, 288, -497, +-2156, -1817, -3621, -2078, -3587, -1236, -2252, -8, +101, 601, 2431, 690, 3738, 582, 3765, 384, +2158, 511, -563, 651, -2986, 221, -4271, -498, +-3786, -1227, -1434, -1534, 1526, -801, 3814, 531, +4509, 1658, 3052, 2024, 169, 1179, -2682, -369, +-4283, -1692, -3848, -2178, -1690, -1435, 1037, 24, +3156, 1341, 3771, 2006, 2751, 1597, 672, 430, +-1521, -745, -2873, -1500, -3009, -1477, -1980, -774, +-189, 121, 1582, 889, 2712, 1218, 2710, 968, +1362, 323, -631, -524, -2228, -1168, -2757, -1185, +-1860, -582, -4, 425, 1736, 1309, 2529, 1403, +1933, 671, 265, -513, -1401, -1545, -2167, -1639, +-1692, -709, -292, 615, 1173, 1650, 1880, 1721, +1511, 721, 258, -678, -1205, -1699, -1984, -1855, +-1619, -1068, -270, 248, 1375, 1453, 2283, 2031, +1964, 1751, 624, 679, -1212, -790, -2484, -2059, +-2394, -2487, -1143, -1813, 769, -261, 2377, 1595, +2544, 2770, 1424, 2574, -269, 1193, -1900, -823, +-2440, -2449, -1582, -2657, -84, -1556, 1399, 175, +2163, 1733, 1701, 2184, 465, 1478, -797, 278, +-1704, -849, -1826, -1385, -1124, -1233, -41, -681, +1037, -2, 1787, 539, 1849, 985, 1099, 1222, +-97, 967, -1326, 333, -2225, -678, -2116, -1684, +-1021, -1771, 490, -894, 1950, 547, 2613, 1961, +2084, 2183, 661, 1021, -1104, -618, -2398, -1935, +-2651, -2040, -1774, -760, -65, 842, 1674, 1813, +2690, 1722, 2482, 633, 1052, -741, -948, -1540, +-2514, -1562, -2756, -1055, -1548, -33, 586, 1092, +2512, 1833, 2962, 2142, 1755, 1372, -557, -569, +-2703, -2516, -3254, -3563, -2045, -2805, 382, -40, +2713, 3080, 3465, 4677, 2555, 3880, 362, 815, +-2129, -2879, -3423, -4965, -3124, -4528, -1504, -1963, +928, 1509, 2903, 4029, 3495, 4563, 2649, 3168, +517, 495, -2003, -2277, -3502, -4058, -3377, -4093, +-1705, -2339, 921, 431, 3101, 3098, 3662, 4290, +2438, 3342, -9, 779, -2473, -2162, -3604, -3965, +-2842, -3729, -650, -1572, 1840, 1358, 3358, 3460, +3139, 3803, 1272, 2205, -1240, -556, -3000, -2898, +-3307, -3717, -1946, -2730, 433, -381, 2410, 2014, +3291, 3278, 2682, 3022, 536, 1396, -1761, -777, +-3110, -2474, -3097, -3070, -1415, -2296, 1027, -509, +2839, 1623, 3334, 3182, 2107, 3178, -366, 1629, +-2534, -890, -3350, -3250, -2605, -3808, -462, -2317, +1901, 400, 3200, 3056, 3038, 3902, 1488, 2573, +-870, 113, -2812, -2250, -3327, -3249, -2399, -2383, +-351, -467, 2054, 1293, 3390, 2278, 3051, 2105, +1394, 809, -1153, -563, -3161, -1438, -3360, -1788, +-2078, -1114, 283, 70, 2652, 943, 3330, 1513, +2393, 1291, 378, 361, -1961, -430, -3012, -1007, +-2375, -1100, -599, -614, 1410, -148, 2366, 186, +1925, 413, 494, 456, -1009, 460, -1688, 484, +-1306, 423, -237, 129, 715, -309, 1054, -785, +732, -1126, 60, -885, -393, -167, -459, 665, +-252, 1356, 42, 1348, 114, 564, 5, -464, +-182, -1286, -354, -1515, -189, -996, 225, -4, +654, 963, 927, 1454, 660, 1346, -133, 629, +-1026, -471, -1616, -1343, -1313, -1673, -102, -1298, +1192, -176, 2083, 1006, 1909, 1671, 416, 1600, +-1259, 668, -2250, -541, -2134, -1287, -722, -1338, +1044, -778, 2131, 40, 2163, 650, 1006, 805, +-775, 662, -1909, 284, -1924, -165, -1124, -355, +369, -442, 1613, -308, 1726, 107, 1091, 260, +-124, 274, -1279, 172, -1505, -176, -1010, -277, +-61, -153, 941, 35, 1336, 319, 998, 400, +230, 197, -635, -86, -1190, -305, -1049, -488, +-367, -430, 370, -8, 984, 366, 1036, 683, +473, 843, -104, 421, -669, -311, -849, -921, +-455, -1072, -139, -629, 166, 161, 429, 863, +330, 943, 334, 477, 458, -54, 169, -380, +-173, -304, -504, -25, -891, 56, -718, -163, +-123, -427, 556, -459, 1157, -148, 1087, 482, +471, 889, -459, 651, -1273, 39, -1250, -658, +-693, -1018, 214, -704, 1109, 56, 1253, 760, +862, 964, 72, 633, -760, -31, -1017, -694, +-779, -969, -325, -813, 229, -303, 544, 264, +533, 644, 517, 907, 375, 849, -41, 380, +-392, -204, -634, -875, -704, -1405, -278, -1182, +287, -297, 663, 758, 828, 1685, 397, 1745, +-295, 664, -693, -665, -694, -1715, -251, -2064, +269, -1087, 511, 438, 405, 1549, 123, 2095, +-103, 1565, -321, 178, -292, -1100, -2, -1947, +76, -1938, 145, -984, 185, 341, 16, 1623, +-30, 2195, -26, 1698, -89, 445, -53, -1057, +-27, -2033, -162, -2005, -191, -1018, -42, 478, +97, 1691, 432, 2064, 692, 1437, 377, 97, +-146, -1245, -688, -1938, -1031, -1659, -670, -493, +-23, 897, 677, 1727, 1116, 1777, 819, 936, +253, -433, -415, -1360, -908, -1601, -904, -1208, +-548, -208, 137, 773, 750, 1289, 945, 1342, +790, 904, 107, 90, -683, -775, -1067, -1399, +-921, -1508, -101, -905, 728, 177, 1052, 1264, +849, 1815, -23, 1460, -770, 357, -920, -1009, +-613, -1826, 103, -1697, 651, -818, 785, 580, +578, 1645, -55, 1694, -534, 998, -688, -180, +-534, -1318, -114, -1655, 186, -1191, 450, -294, +535, 757, 309, 1376, 163, 1274, 2, 804, +-245, -33, -366, -959, -534, -1288, -661, -1249, +-340, -814, 302, 220, 1017, 1079, 1268, 1433, +772, 1296, -135, 431, -1120, -678, -1561, -1336, +-1188, -1386, -235, -793, 879, 229, 1496, 973, +1394, 1159, 757, 941, -250, 198, -1115, -617, +-1451, -962, -1288, -1017, -552, -556, 599, 319, +1478, 949, 1645, 1265, 1064, 921, -156, -87, +-1294, -953, -1639, -1464, -1304, -1229, -358, -96, +910, 1014, 1609, 1577, 1445, 1399, 709, 404, +-515, -758, -1461, -1446, -1563, -1380, -1026, -674, +109, 273, 1220, 1078, 1619, 1332, 1296, 1036, +338, 429, -834, -397, -1446, -1064, -1380, -1255, +-864, -992, 66, -275, 1014, 640, 1482, 1258, +1364, 1241, 638, 645, -512, -166, -1394, -867, +-1567, -1068, -970, -671, 145, -84, 1026, 389, +1298, 625, 847, 562, 54, 246, -512, -88, +-740, -273, -483, -460, -88, -429, -36, -116, +77, 94, 199, 382, 208, 535, 381, 208, +296, -82, -65, -334, -208, -559, -354, -344, +-446, 1, -118, 272, 153, 497, 115, 413, +264, 93, 286, -281, 96, -610, 123, -640, +-27, -292, -294, 238, -252, 690, -304, 843, +-260, 551, 188, -47, 348, -614, 303, -923, +362, -802, 117, -410, -339, 94, -406, 706, +-329, 982, -253, 830, 241, 478, 457, -250, +273, -947, 200, -1071, -153, -764, -353, -90, +-150, 663, -83, 934, -22, 727, 157, 272, +98, -267, -26, -529, 123, -445, 152, -329, +-84, -117, -118, 169, -167, 319, -193, 479, +43, 413, 169, 5, 210, -330, 150, -560, +-43, -462, -61, 145, 19, 587, -20, 544, +-175, 176, -306, -444, -311, -766, -66, -354, +408, 356, 734, 918, 583, 942, 75, 120, +-555, -843, -873, -1229, -573, -990, -33, 24, +474, 1145, 642, 1344, 308, 793, -57, -130, +-189, -1061, -128, -1105, 69, -388, 9, 278, +-289, 738, -331, 571, -230, -157, 101, -475, +703, -323, 781, 71, 314, 591, -269, 597, +-999, 26, -1220, -623, -593, -926, 245, -535, +1157, 174, 1580, 669, 1035, 788, 137, 351, +-983, -259, -1897, -446, -1587, -287, -469, -1, +720, 196, 1751, 30, 1784, -318, 787, -483, +-417, -359, -1414, 84, -1589, 658, -820, 873, +151, 558, 940, 73, 1202, -489, 757, -967, +86, -850, -500, -358, -772, 108, -654, 593, +-373, 784, 61, 489, 403, 93, 557, -188, +603, -291, 436, -108, -23, 58, -562, -106, +-859, -386, -786, -596, -255, -534, 637, 155, +1168, 1090, 963, 1494, 256, 1088, -817, -114, +-1435, -1584, -942, -2279, -37, -1633, 930, 163, +1469, 2087, 847, 2857, -152, 2006, -766, -130, +-1110, -2342, -734, -3144, 3, -2100, 273, 220, +425, 2368, 539, 3020, 418, 1981, 476, -179, +357, -2124, -268, -2633, -806, -1633, -1143, 152, +-1025, 1701, -130, 2246, 941, 1502, 1598, -38, +1445, -1380, 485, -2003, -770, -1515, -1627, -91, +-1619, 1265, -791, 1960, 434, 1563, 1324, 106, +1449, -1328, 938, -1914, 44, -1420, -732, -6, +-952, 1364, -853, 1795, -586, 1142, -163, -219, +233, -1354, 692, -1568, 1064, -937, 970, 212, +505, 1212, -308, 1437, -1253, 907, -1556, -23, +-1079, -970, -101, -1507, 962, -1208, 1492, -253, +1359, 732, 642, 1447, -260, 1374, -952, 419, +-1334, -568, -1143, -1222, -528, -1269, 299, -462, +1175, 462, 1433, 957, 958, 952, 76, 326, +-1003, -475, -1487, -953, -1103, -886, -95, -264, +1058, 471, 1409, 1072, 938, 1200, 46, 569, +-978, -307, -1283, -1123, -892, -1511, -193, -1036, +706, -174, 1087, 758, 944, 1420, 497, 1289, +-367, 777, -829, 75, -864, -755, -711, -1114, +-60, -1118, 532, -871, 776, -159, 747, 594, +223, 1105, -291, 1352, -464, 1028, -499, 199, +-313, -715, -52, -1433, 67, -1619, 139, -1012, +194, 144, 276, 1282, 385, 1969, 415, 1800, +210, 663, -260, -814, -794, -1974, -1022, -2298, +-749, -1460, -7, 57, 912, 1543, 1408, 2383, +1177, 2070, 395, 900, -732, -573, -1550, -1852, +-1363, -2295, -514, -1764, 525, -581, 1299, 842, +1206, 1983, 523, 2275, -298, 1591, -932, 293, +-947, -1224, -472, -2265, 130, -2223, 528, -1239, +580, 306, 397, 1760, 73, 2291, -137, 1695, +-180, 385, -266, -950, -209, -1757, -131, -1666, +-170, -814, -37, 46, 151, 681, 248, 1036, +378, 916, 349, 710, 165, 495, -37, -6, +-428, -647, -673, -1213, -587, -1458, -417, -1072, +122, -76, 864, 1112, 1134, 1866, 944, 1820, +266, 979, -763, -410, -1409, -1674, -1384, -2168, +-713, -1760, 402, -552, 1263, 1007, 1506, 2064, +1116, 2158, 197, 1308, -819, -156, -1389, -1481, +-1383, -2058, -876, -1693, 138, -646, 1166, 523, +1584, 1367, 1402, 1625, 551, 1363, -722, 744, +-1538, -122, -1629, -1024, -1074, -1782, 44, -2001, +1009, -1347, 1344, -10, 1246, 1622, 658, 2760, +-142, 2650, -549, 1349, -856, -651, -975, -2485, +-672, -3215, -435, -2492, 45, -721, 701, 1268, +990, 2674, 1160, 2967, 828, 2025, -38, 414, +-808, -1170, -1418, -2365, -1400, -2666, -639, -1887, +329, -541, 1270, 1065, 1611, 2419, 1140, 2719, +193, 1935, -935, 365, -1529, -1530, -1346, -2741, +-688, -2693, 367, -1485, 1235, 422, 1351, 2101, +966, 2781, 219, 2191, -589, 644, -937, -1010, +-943, -2199, -786, -2498, -295, -1673, 212, -308, +605, 1107, 1058, 2174, 1133, 2301, 700, 1506, +-78, 129, -1101, -1323, -1624, -2176, -1354, -2068, +-457, -1082, 874, 233, 1718, 1331, 1607, 1725, +763, 1205, -493, 400, -1459, -299, -1632, -786, +-1004, -694, 91, -343, 1101, -209, 1549, -123, +1209, -104, 356, -122, -675, 94, -1446, 437, +-1453, 644, -764, 575, 253, 191, 1107, -344, +1506, -783, 1192, -749, 150, -301, -782, 138, +-1246, 601, -1287, 737, -546, 288, 423, -37, +993, -245, 1127, -429, 611, -210, -202, -37, +-662, -85, -762, -98, -505, -144, 9, -61, +249, 312, 227, 661, 265, 752, 274, 604, +397, 57, 516, -759, 118, -1257, -549, -1353, +-1177, -967, -1416, 7, -695, 1077, 588, 1914, +1737, 2096, 2235, 1355, 1443, 20, -182, -1590, +-1843, -2759, -2834, -2780, -2255, -1616, -441, 481, +1575, 2562, 3020, 3614, 2955, 3187, 1218, 1164, +-1118, -1537, -2929, -3565, -3324, -4104, -1890, -2797, +477, -172, 2439, 2566, 3271, 4181, 2409, 3974, +340, 2026, -1629, -819, -2776, -3248, -2635, -4310, +-1185, -3536, 635, -1097, 2059, 1685, 2565, 3568, +1738, 3967, 138, 2490, -1351, -53, -2235, -2249, +-1812, -3250, -378, -2684, 936, -990, 1697, 760, +1442, 1814, 255, 1803, -852, 977, -1378, 129, +-969, -376, 132, -435, 961, -210, 1273, -183, +910, -385, -118, -653, -1114, -849, -1609, -580, +-1372, 116, -334, 853, 983, 1418, 1963, 1568, +2190, 1086, 1240, 31, -540, -1172, -2068, -2102, +-2797, -2433, -2216, -1713, -262, -103, 1782, 1771, +2975, 3184, 2812, 3334, 1092, 1960, -1067, -433, +-2595, -2900, -2958, -4230, -1777, -3622, 228, -1343, +1840, 1607, 2443, 3941, 2026, 4465, 740, 2949, +-813, 271, -1586, -2514, -1687, -4076, -1405, -3717, +-451, -2038, 469, 397, 1077, 2621, 1583, 3449, +1372, 2974, 681, 1588, -196, -468, -1348, -2168, +-1858, -2803, -1427, -2586, -541, -1471, 711, 244, +1737, 1635, 1806, 2472, 1141, 2602, -20, 1620, +-1288, 77, -1798, -1537, -1472, -2803, -569, -2831, +720, -1592, 1516, 378, 1528, 2286, 919, 3157, +-194, 2501, -1063, 678, -1315, -1362, -1040, -2675, +-237, -2670, 499, -1417, 854, 285, 966, 1709, +648, 2283, 113, 1766, -336, 633, -697, -688, +-846, -1663, -728, -1821, -307, -1218, 306, -54, +779, 1098, 1048, 1682, 922, 1507, 348, 567, +-395, -689, -1071, -1549, -1321, -1722, -1025, -1103, +-303, 123, 731, 1251, 1499, 1864, 1543, 1669, +980, 702, -80, -483, -1234, -1531, -1832, -2067, +-1624, -1699, -686, -770, 649, 464, 1629, 1776, +1920, 2408, 1533, 2096, 371, 930, -1070, -817, +-1847, -2350, -1931, -2817, -1339, -2080, 18, -431, +1217, 1451, 1784, 2508, 1814, 2460, 979, 1532, +-138, 15, -946, -1287, -1577, -2015, -1529, -2167, +-975, -1505, -288, -342, 683, 981, 1399, 2161, +1633, 2423, 1420, 1717, 492, 328, -563, -1289, +-1459, -2238, -1957, -2248, -1606, -1464, -777, -169, +407, 1014, 1606, 1792, 2117, 2028, 2099, 1540, +1218, 573, -451, -643, -1827, -1659, -2672, -2027, +-2496, -1597, -1054, -486, 711, 643, 2190, 1378, +2771, 1577, 2018, 1133, 645, 485, -776, -100, +-1857, -651, -2214, -969, -1671, -1101, -613, -949, +408, -432, 1389, 117, 1928, 679, 1549, 1116, +763, 1193, -193, 1026, -1126, 596, -1514, -164, +-1434, -1144, -1009, -1924, -253, -2069, 551, -1356, +1295, 185, 1793, 1869, 1683, 2832, 881, 2706, +-508, 1254, -1800, -825, -2346, -2373, -2047, -3064, +-746, -2512, 1017, -831, 2114, 957, 2369, 2296, +1723, 2786, 260, 2124, -1138, 798, -1957, -793, +-2046, -2146, -1228, -2589, -4, -2088, 1023, -832, +1712, 870, 1707, 2274, 889, 2688, -163, 1917, +-1052, 298, -1563, -1499, -1370, -2573, -579, -2352, +459, -1042, 1295, 708, 1419, 1943, 851, 2043, +-112, 1246, -942, -33, -1124, -1080, -715, -1334, +58, -1022, 641, -368, 588, 216, 250, 464, +-169, 606, -338, 553, 21, 314, 341, 204, +349, -37, 73, -423, -516, -572, -863, -605, +-579, -531, 76, -6, 779, 556, 1204, 859, +940, 1019, 58, 549, -810, -293, -1337, -834, +-1206, -1149, -400, -925, 454, -174, 1127, 388, +1293, 749, 727, 854, 39, 619, -518, 444, +-804, 296, -755, -73, -619, -590, -291, -1192, +-4, -1613, 236, -1348, 682, -246, 944, 1323, +964, 2651, 644, 2912, -180, 1766, -896, -452, +-1396, -2722, -1515, -3859, -860, -3292, 163, -1154, +1120, 1564, 1777, 3496, 1691, 3894, 825, 2665, +-309, 386, -1233, -1758, -1651, -3032, -1290, -3096, +-519, -2036, 199, -559, 788, 931, 832, 2094, +630, 2358, 597, 1959, 430, 1182, 227, -80, +-25, -1131, -553, -1650, -975, -1965, -1181, -1739, +-1034, -1040, -379, -175, 500, 1078, 1330, 2269, +1850, 2724, 1668, 2281, 767, 776, -548, -1341, +-1827, -2978, -2452, -3391, -2050, -2397, -771, -407, +852, 1684, 2137, 2883, 2466, 2874, 1870, 1824, +695, 242, -681, -1084, -1713, -1873, -2119, -2089, +-1993, -1685, -1173, -982, 39, -90, 1281, 969, +2334, 1851, 2546, 2285, 1730, 1951, 265, 815, +-1554, -739, -2760, -2130, -2741, -2648, -1763, -2101, +49, -777, 1868, 800, 2612, 1827, 2312, 2044, +1262, 1608, -295, 754, -1426, -112, -1712, -775, +-1551, -1208, -930, -1430, -132, -1324, 235, -701, +657, 145, 1094, 1017, 1101, 1626, 1093, 1400, +792, 682, -68, -79, -815, -814, -1432, -1003, +-1723, -739, -1318, -538, -525, -242, 559, 34, +1513, 222, 1890, 493, 1792, 669, 975, 684, +-269, 519, -1236, 94, -1942, -290, -1997, -632, +-1238, -906, -305, -790, 713, -511, 1709, -69, +2043, 621, 1795, 1048, 1107, 1131, -203, 903, +-1525, 196, -2301, -633, -2516, -1202, -1695, -1332, +-21, -946, 1590, -185, 2774, 653, 2892, 1136, +1620, 1131, -199, 683, -1899, -42, -2808, -563, +-2334, -747, -1009, -558, 519, -114, 1723, 170, +1934, 164, 1358, -25, 618, -233, -229, -194, +-952, 127, -1117, 429, -1020, 549, -802, 430, +-129, 8, 561, -388, 880, -428, 1028, -420, +774, -307, 136, -62, -329, -20, -674, 15, +-889, 207, -633, 417, -304, 592, 4, 643, +518, 367, 750, -227, 694, -885, 490, -1336, +27, -1176, -289, -414, -492, 630, -608, 1569, +-451, 1806, -326, 1221, -93, 174, 257, -1062, +498, -1817, 738, -1744, 648, -1106, 255, 29, +-172, 1155, -670, 1753, -909, 1659, -766, 918, +-308, -178, 378, -1171, 813, -1597, 1012, -1275, +797, -386, 58, 526, -589, 1044, -981, 1011, +-939, 389, -435, -323, 109, -543, 694, -433, +829, -50, 511, 474, 364, 518, -53, 190, +-519, -211, -551, -661, -579, -796, -383, -458, +149, 59, 437, 612, 522, 1004, 472, 848, +111, 325, -299, -287, -347, -782, -263, -922, +-126, -619, 91, -96, 85, 278, 28, 449, +120, 444, 41, 260, 6, 120, 129, 131, +80, 112, -38, 63, -60, -170, -203, -485, +-342, -642, -208, -593, -57, -133, 258, 422, +599, 794, 512, 848, 257, 330, -134, -261, +-637, -568, -670, -651, -417, -300, -102, 217, +275, 398, 524, 315, 539, 36, 372, -274, +85, -396, -209, -294, -455, 28, -532, 361, +-329, 521, 82, 456, 403, 257, 434, -111, +232, -537, -134, -745, -397, -656, -360, -298, +-99, 279, 225, 817, 451, 980, 446, 732, +228, 182, -76, -417, -315, -799, -547, -890, +-602, -751, -463, -418, -196, 61, 304, 518, +791, 969, 1031, 1286, 974, 1157, 491, 551, +-278, -381, -1094, -1386, -1661, -2020, -1570, -1936, +-771, -1061, 384, 392, 1553, 1740, 2247, 2564, +1916, 2540, 809, 1494, -607, -68, -1852, -1686, +-2304, -2883, -1908, -3083, -817, -2210, 558, -493, +1564, 1623, 2137, 3220, 1996, 3639, 1029, 2660, +-151, 595, -1311, -1661, -2076, -3264, -1976, -3509, +-1238, -2417, -98, -594, 1066, 1312, 1762, 2570, +1907, 2776, 1361, 2063, 325, 768, -733, -700, +-1582, -1740, -1802, -2091, -1250, -1745, -291, -804, +770, 326, 1434, 1116, 1339, 1371, 632, 1078, +-241, 356, -762, -231, -813, -504, -433, -457, +215, -136, 532, 90, 450, 55, 154, -117, +-401, -362, -724, -536, -622, -373, -373, 16, +197, 442, 821, 803, 1045, 886, 1000, 580, +603, 107, -191, -365, -1012, -840, -1517, -1049, +-1503, -947, -969, -611, 40, 54, 1172, 871, +1861, 1413, 2009, 1480, 1393, 937, 86, -101, +-1174, -1049, -2083, -1564, -2354, -1408, -1630, -674, +-334, 211, 1034, 819, 2104, 977, 2397, 804, +1800, 453, 638, 204, -741, 84, -1825, -49, +-2269, -277, -1990, -678, -976, -1057, 350, -1043, +1494, -610, 2124, 220, 1932, 1186, 1122, 1669, +58, 1559, -1009, 804, -1627, -319, -1656, -1204, +-1266, -1636, -620, -1494, 203, -859, 987, -97, +1471, 556, 1628, 1065, 1344, 1325, 418, 1348, +-621, 1012, -1438, 288, -1936, -623, -1658, -1473, +-692, -1866, 403, -1558, 1364, -698, 1854, 288, +1625, 1154, 818, 1614, -217, 1584, -1140, 1251, +-1609, 595, -1516, -295, -943, -1186, 61, -1867, +1015, -2041, 1531, -1435, 1528, -315, 904, 974, +-156, 2017, -1143, 2272, -1688, 1754, -1436, 673, +-549, -637, 421, -1634, 1240, -2037, 1593, -1833, +1158, -1000, 415, 136, -355, 1135, -1063, 1709, +-1413, 1631, -1355, 1011, -794, 90, 147, -680, +1012, -1018, 1641, -1007, 1723, -720, 995, -321, +-95, -60, -1132, 131, -1749, 386, -1595, 532, +-926, 676, -43, 755, 897, 523, 1363, 117, +1282, -382, 919, -926, 329, -1215, -332, -1097, +-777, -564, -900, 284, -813, 1060, -663, 1601, +-417, 1597, -57, 904, 301, -78, 694, -1149, +1124, -1901, 1264, -1870, 984, -1177, 338, -57, +-663, 1176, -1527, 1895, -1900, 1899, -1728, 1325, +-847, 279, 471, -832, 1556, -1604, 2200, -1840, +2141, -1486, 1239, -632, 29, 425, -1187, 1333, +-2096, 1756, -2169, 1530, -1647, 864, -688, -60, +610, -935, 1543, -1422, 1951, -1494, 1890, -1167, +1167, -418, 178, 442, -660, 1185, -1364, 1663, +-1717, 1492, -1620, 741, -1231, -277, -520, -1255, +528, -1709, 1564, -1431, 2279, -663, 2322, 316, +1454, 1097, -39, 1325, -1649, 1092, -2757, 520, +-2746, -195, -1758, -753, -182, -979, 1526, -779, +2571, -335, 2663, 128, 1864, 435, 357, 461, +-1121, 270, -2136, 136, -2438, 94, -1727, 87, +-451, 78, 777, -88, 1671, -309, 1886, -372, +1341, -301, 485, -147, -357, 143, -1038, 308, +-1292, 256, -1114, 188, -664, 132, 34, 19, +682, -103, 1048, -135, 1048, -172, 661, -161, +-20, -53, -685, 38, -1007, 134, -955, 92, +-542, -54, 158, -77, 773, -11, 1130, 100, +1009, 293, 403, 323, -348, 112, -975, -250, +-1277, -605, -971, -653, -236, -365, 387, 199, +918, 727, 1171, 968, 826, 750, 421, 61, +-26, -644, -636, -946, -846, -864, -961, -424, +-956, 240, -382, 628, 216, 689, 751, 546, +1320, 275, 1243, 14, 727, -280, 21, -523, +-867, -564, -1370, -434, -1355, -147, -900, 247, +-8, 490, 784, 529, 1224, 365, 1265, 123, +870, -28, 170, -227, -533, -421, -967, -498, +-1153, -425, -923, -255, -330, 118, 271, 502, +748, 679, 1027, 672, 856, 396, 404, -21, +-49, -431, -522, -825, -791, -959, -683, -634, +-444, -129, -50, 509, 387, 1007, 544, 1023, +437, 628, 237, 1, -73, -467, -286, -643, +-210, -650, -108, -517, 16, -353, 218, -222, +202, 87, 73, 588, -88, 1003, -337, 1069, +-389, 565, -322, -285, -60, -1076, 329, -1413, +557, -1039, 637, -122, 408, 813, -97, 1301, +-395, 1151, -604, 407, -680, -480, -347, -1097, +28, -1081, 331, -473, 565, 288, 548, 783, +296, 834, -126, 444, -420, -64, -393, -292, +-129, -270, 212, -152, 379, -138, 282, -276, +-94, -379, -473, -309, -578, -39, -385, 369, +-53, 624, 237, 643, 485, 552, 662, 318, +552, -6, 371, -390, 143, -842, -278, -1099, +-718, -988, -937, -478, -874, 338, -586, 1113, +-32, 1402, 578, 1219, 1075, 745, 1371, -11, +1109, -723, 424, -1132, -351, -1369, -1231, -1260, +-1726, -679, -1452, 134, -684, 1021, 397, 1570, +1347, 1540, 1665, 1031, 1417, 151, 586, -749, +-459, -1285, -1104, -1370, -1263, -998, -1044, -390, +-380, 277, 295, 741, 564, 732, 566, 451, +473, 228, 336, 187, 287, 376, 269, 575, +84, 413, -224, -192, -572, -1038, -824, -1594, +-746, -1492, -380, -770, 76, 225, 512, 1143, +791, 1688, 831, 1692, 704, 1263, 331, 543, +-121, -401, -517, -1315, -922, -1884, -949, -1917, +-624, -1279, -213, -237, 273, 822, 647, 1636, +729, 1880, 685, 1552, 561, 825, 323, -81, +34, -907, -334, -1482, -853, -1575, -1160, -1132, +-1009, -419, -525, 341, 318, 893, 1092, 970, +1365, 785, 1141, 440, 525, 135, -143, 50, +-689, 38, -908, -85, -845, -301, -732, -561, +-505, -848, -222, -852, 228, -484, 838, 91, +1228, 738, 1261, 1196, 860, 1144, -84, 707, +-915, -8, -1359, -711, -1383, -948, -815, -842, +-63, -453, 578, 98, 912, 443, 858, 514, +712, 344, 488, -12, 169, -291, -140, -384, +-521, -262, -863, 153, -1006, 490, -787, 560, +-218, 424, 449, 76, 946, -322, 1063, -552, +854, -607, 418, -510, -104, -216, -439, 104, +-747, 476, -1018, 719, -988, 568, -622, 141, +-44, -267, 767, -534, 1346, -430, 1461, 6, +1178, 362, 180, 448, -914, 113, -1512, -328, +-1677, -498, -1192, -433, -146, -164, 871, 182, +1516, 291, 1530, 228, 972, 204, 70, 301, +-848, 438, -1335, 339, -1236, 37, -694, -412, +30, -855, 682, -936, 1098, -666, 966, -135, +589, 450, 134, 805, -445, 932, -768, 874, +-909, 498, -936, -29, -527, -484, -1, -774, +578, -837, 1247, -617, 1438, -206, 1082, 52, +242, 135, -732, 123, -1425, 121, -1595, 241, +-1117, 533, -312, 858, 431, 999, 986, 743, +1171, 49, 1042, -881, 773, -1696, 292, -1995, +-302, -1598, -749, -530, -1038, 805, -1134, 1837, +-893, 2238, -360, 1917, 195, 992, 814, -107, +1305, -1002, 1383, -1502, 1070, -1538, 318, -1288, +-649, -884, -1411, -378, -1697, 134, -1391, 680, +-439, 1228, 602, 1594, 1275, 1569, 1483, 1121, +1085, 318, 401, -668, -280, -1498, -826, -1880, +-874, -1768, -664, -1214, -484, -384, -110, 514, +216, 1305, 363, 1817, 485, 1963, 483, 1592, +351, 711, 90, -507, -207, -1662, -319, -2313, +-238, -2161, -134, -1244, -55, 53, -11, 1217, +-91, 1843, -183, 1686, -88, 1006, 183, 224, +345, -519, 309, -885, 180, -822, 24, -602, +-193, -300, -248, 30, -113, 226, -65, 279, +-70, 186, -92, 10, -38, -97, 29, -112, +87, 15, 219, 260, 212, 415, 108, 290, +-81, 17, -260, -247, -212, -411, -80, -306, +63, -47, 246, 140, 308, 171, 82, 13, +-185, -242, -292, -304, -339, -198, -199, 20, +184, 386, 384, 624, 364, 615, 206, 357, +-119, -36, -325, -464, -315, -756, -253, -767, +5, -472, 321, -66, 369, 312, 239, 602, +47, 666, -241, 498, -421, 174, -345, -116, +-133, -368, 159, -472, 403, -342, 375, -70, +237, 208, 26, 298, -224, 171, -318, -42, +-355, -306, -307, -422, -157, -176, 177, 128, +472, 389, 573, 522, 585, 363, 327, 163, +-241, -87, -679, -347, -933, -386, -944, -368, +-457, -378, 214, -168, 751, 103, 1182, 284, +1166, 445, 731, 423, 125, 253, -631, 18, +-1175, -239, -1253, -371, -1004, -234, -449, -70, +236, 103, 766, 281, 1090, 195, 1010, -105, +687, -364, 325, -472, -157, -364, -591, -6, +-758, 420, -756, 734, -637, 770, -446, 504, +-111, 42, 230, -452, 467, -844, 711, -1004, +888, -824, 798, -332, 421, 314, -80, 880, +-623, 1177, -1023, 1062, -1110, 484, -869, -263, +-268, -827, 361, -1037, 752, -811, 1037, -285, +971, 160, 515, 353, 30, 325, -402, 166, +-711, 126, -699, 271, -528, 444, -207, 495, +76, 296, 152, -163, 251, -638, 345, -927, +364, -870, 267, -488, 73, 39, -75, 508, +-214, 783, -320, 815, -210, 642, -18, 322, +63, -43, 110, -366, 146, -549, 133, -544, +89, -380, -63, -115, -191, 28, -306, 6, +-377, -104, -204, -201, 100, -138, 415, 183, +631, 634, 588, 992, 406, 1000, 19, 588, +-454, -115, -692, -864, -713, -1343, -521, -1395, +-159, -1005, 180, -383, 391, 249, 429, 803, +257, 1192, 254, 1339, 351, 1187, 285, 703, +254, -26, 37, -782, -388, -1320, -633, -1344, +-744, -903, -668, -342, -335, 148, 16, 367, +349, 377, 750, 375, 1007, 508, 935, 736, +509, 867, -119, 650, -852, 127, -1308, -501, +-1065, -1033, -406, -1184, 366, -936, 957, -452, +958, 9, 457, 335, -174, 460, -595, 550, +-570, 658, -187, 727, 213, 762, 377, 578, +307, 44, 50, -631, -197, -1204, -157, -1483, +24, -1186, 134, -469, 102, 375, -146, 1107, +-386, 1333, -453, 1072, -288, 568, 82, -21, +425, -474, 626, -591, 679, -473, 457, -271, +119, -130, -230, -188, -642, -350, -906, -488, +-882, -345, -587, 159, 7, 821, 672, 1245, +1034, 1171, 1082, 534, 748, -335, 108, -1045, +-396, -1323, -794, -987, -929, -383, -642, 170, +-307, 602, 63, 770, 400, 670, 474, 470, +434, 116, 337, -230, 75, -431, -60, -516, +-48, -312, -57, 50, 22, 240, 57, 229, +-102, 70, -275, -179, -460, -335, -592, -235, +-342, 45, 125, 322, 552, 463, 935, 435, +941, 250, 482, 1, -53, -310, -591, -558, +-978, -607, -915, -574, -569, -341, -115, 164, +429, 682, 743, 1005, 746, 1024, 556, 554, +84, -229, -325, -981, -422, -1356, -409, -1088, +-96, -298, 207, 555, 175, 1065, 32, 1046, +-260, 550, -462, -120, -332, -539, 2, -559, +389, -403, 721, -171, 714, 74, 346, 207, +-112, 234, -538, 238, -720, 136, -536, -91, +-271, -291, 14, -335, 242, -200, 197, 132, +115, 458, 179, 511, 245, 321, 391, -42, +476, -450, 268, -638, -114, -566, -489, -312, +-783, 92, -829, 497, -552, 767, -172, 836, +288, 579, 735, 8, 887, -647, 811, -1104, +596, -1133, 150, -655, -312, 162, -708, 911, +-928, 1262, -871, 997, -645, 309, -325, -460, +169, -995, 743, -1022, 1073, -520, 1202, 194, +993, 766, 255, 955, -547, 669, -1209, 105, +-1503, -560, -1123, -988, -359, -938, 479, -571, +1101, 2, 1178, 672, 781, 1062, 157, 1034, +-411, 650, -733, -14, -709, -623, -301, -971, +115, -933, 415, -436, 571, 181, 429, 588, +102, 704, -313, 452, -627, -75, -685, -517, +-525, -660, -145, -418, 321, 76, 713, 519, +865, 720, 690, 569, 339, 166, -83, -229, +-440, -328, -630, -173, -659, 2, -520, -9, +-367, -245, -143, -690, 128, -981, 329, -734, +582, -30, 679, 884, 562, 1570, 386, 1691, +27, 1188, -354, 223, -551, -788, -680, -1416, +-620, -1556, -313, -1231, 44, -565, 382, 133, +560, 604, 501, 741, 292, 659, 5, 489, +-276, 370, -357, 367, -274, 323, -143, 140, +68, -206, 205, -596, 280, -768, 291, -578, +153, -213, -59, 147, -271, 338, -417, 198, +-457, -88, -314, -244, -22, -181, 222, 88, +402, 439, 477, 634, 396, 603, 254, 343, +51, -39, -125, -373, -254, -548, -374, -524, +-402, -374, -367, -195, -204, -71, 17, -50, +180, -84, 380, -44, 424, 139, 254, 405, +105, 615, -66, 648, -181, 492, -141, 170, +-111, -195, -59, -427, -18, -531, -44, -530, +-18, -475, 71, -430, 98, -315, 26, -130, +-30, 103, -132, 468, -166, 781, -104, 867, +-4, 740, 190, 353, 249, -159, 182, -579, +125, -787, 40, -686, -39, -397, -148, -125, +-180, 75, -195, 175, -252, 197, -143, 168, +-23, 134, 120, 149, 344, 164, 397, 163, +335, 246, 127, 261, -226, 102, -440, -149, +-490, -407, -341, -563, -20, -494, 293, -268, +452, -21, 359, 205, 155, 304, 8, 338, +-93, 448, -84, 524, -117, 378, -216, 70, +-283, -361, -368, -784, -274, -890, 29, -637, +372, -144, 635, 414, 665, 758, 441, 802, +33, 620, -412, 240, -695, -217, -722, -545, +-519, -657, -145, -523, 295, -179, 589, 235, +661, 479, 529, 418, 205, 106, -174, -260, +-486, -449, -649, -388, -525, -64, -209, 357, +159, 636, 508, 632, 689, 328, 590, -144, +270, -547, -152, -754, -581, -667, -773, -275, +-687, 160, -399, 467, 131, 623, 606, 590, +810, 366, 733, 16, 303, -388, -215, -712, +-575, -822, -697, -578, -433, 53, 1, 766, +346, 1154, 468, 1003, 296, 357, -3, -463, +-286, -1052, -364, -1122, -149, -679, 179, -18, +427, 505, 439, 728, 134, 676, -350, 379, +-700, -47, -743, -347, -383, -428, 243, -335, +780, -61, 1026, 235, 811, 327, 176, 157, +-430, -170, -810, -352, -890, -216, -531, 82, +-70, 393, 291, 502, 520, 215, 428, -267, +176, -637, -1, -703, -122, -398, -154, 53, +-36, 496, 116, 833, 189, 826, 129, 524, +-58, 79, -238, -451, -383, -889, -382, -1061, +-149, -845, 114, -245, 367, 414, 509, 932, +363, 1190, 181, 968, -7, 364, -228, -318, +-257, -855, -298, -1105, -367, -995, -290, -579, +-209, -21, -25, 502, 327, 901, 564, 1092, +608, 1023, 453, 641, 81, -73, -273, -818, +-433, -1294, -434, -1355, -323, -866, -109, -3, +-41, 768, -126, 1120, -90, 1009, -42, 559, +123, 9, 438, -426, 561, -596, 560, -558, +420, -388, 11, -86, -380, 192, -618, 381, +-773, 468, -680, 359, -358, 140, 21, -17, +397, -213, 633, -432, 670, -569, 517, -669, +224, -560, -52, -81, -216, 591, -286, 1175, +-305, 1415, -318, 1066, -267, 210, -211, -746, +-119, -1416, 67, -1570, 247, -1194, 372, -420, +328, 398, 170, 955, 32, 1170, -73, 1057, +-67, 701, -8, 261, 28, -139, -21, -477, +-223, -729, -392, -907, -416, -891, -290, -577, +40, -67, 428, 458, 662, 846, 680, 955, +427, 729, 13, 284, -391, -146, -665, -407, +-721, -551, -476, -508, -78, -243, 287, 51, +560, 213, 575, 170, 322, -47, -31, -347, +-292, -527, -333, -294, -178, 317, 71, 891, +231, 1137, 214, 915, 10, 228, -283, -597, +-408, -1217, -326, -1348, -137, -950, 179, -327, +461, 310, 542, 879, 464, 1105, 175, 885, +-161, 455, -417, -32, -591, -430, -502, -621, +-197, -511, 144, -167, 404, 136, 444, 226, +313, 128, 51, -107, -251, -447, -355, -637, +-286, -407, -133, 126, 64, 655, 288, 982, +438, 955, 387, 493, 219, -143, -46, -592, +-358, -675, -586, -509, -615, -320, -310, -206, +149, -155, 492, -159, 598, -139, 403, 40, +-20, 308, -426, 521, -524, 630, -238, 737, +191, 694, 506, 294, 552, -294, 262, -901, +-196, -1351, -550, -1313, -606, -735, -388, 107, +-75, 924, 221, 1309, 453, 1172, 489, 780, +365, 201, 218, -409, -54, -796, -351, -955, +-563, -906, -629, -535, -294, 78, 165, 700, +489, 1059, 674, 943, 490, 411, 16, -339, +-430, -964, -587, -1133, -359, -745, 41, 8, +397, 772, 501, 1170, 322, 1031, 8, 475, +-341, -272, -475, -844, -379, -1000, -203, -763, +27, -325, 184, 151, 293, 489, 343, 588, +245, 505, 114, 260, -55, -12, -239, -193, +-241, -276, -107, -218, 23, -37, 166, 90, +225, 109, 65, 91, -185, 29, -335, 5, +-414, -26, -280, -129, 18, -217, 267, -249, +570, -237, 727, -79, 532, 210, 208, 361, +-243, 338, -724, 240, -948, 116, -873, 14, +-461, -19, 197, -25, 731, -72, 955, -171, +903, -297, 499, -341, -106, -309, -531, -273, +-726, -196, -637, 27, -285, 373, 24, 720, +324, 937, 442, 891, 280, 441, 117, -343, +-62, -1060, -214, -1437, -243, -1345, -195, -753, +-59, 136, 71, 1043, 178, 1566, 253, 1471, +243, 866, 131, -8, -106, -862, -274, -1271, +-313, -1103, -263, -577, -9, 22, 297, 431, +436, 607, 368, 575, 90, 374, -240, 88, +-467, -162, -499, -377, -338, -500, -48, -347, +228, 64, 373, 455, 377, 611, 343, 511, +270, 152, 67, -289, -107, -583, -219, -609, +-356, -386, -354, -92, -200, 178, -50, 335, +81, 341, 135, 208, 83, 11, 61, -71, +75, 45, 72, 182, 146, 226, 180, 169, +77, -109, -11, -422, -65, -530, -151, -392, +-204, -111, -259, 118, -242, 207, -112, 254, +34, 315, 276, 354, 499, 362, 442, 229, +195, -113, -149, -526, -469, -677, -493, -481, +-312, -106, -25, 292, 303, 478, 396, 415, +227, 180, -4, -138, -137, -317, -189, -282, +-141, -168, 44, 36, 120, 344, 83, 507, +46, 382, -26, 26, -30, -358, -40, -619, +-91, -638, -59, -306, -35, 194, -19, 565, +66, 658, 169, 468, 176, 109, 53, -280, +-92, -646, -194, -722, -199, -416, -124, 1, +6, 440, 212, 778, 304, 774, 222, 413, +114, -71, -52, -433, -260, -592, -350, -590, +-302, -421, -145, -142, 102, 106, 245, 288, +262, 382, 227, 396, 51, 255, -110, -9, +-45, -178, 29, -189, 39, -141, 65, -79, +-4, 22, -130, 100, -211, 94, -212, 47, +-71, 71, 102, 54, 142, -69, 145, -153, +139, -182, 3, -173, -148, -130, -145, -42, +-37, 107, 66, 239, 124, 258, 115, 194, +71, 62, -16, -143, -111, -253, -35, -146, +78, 92, 73, 273, -22, 268, -181, 74, +-257, -166, -218, -312, -94, -307, 193, -116, +383, 44, 306, -10, 120, -123, -120, -150, +-290, -45, -268, 231, -77, 527, 167, 643, +291, 501, 243, 115, 55, -324, -157, -651, +-310, -761, -322, -650, -119, -353, 104, 77, +214, 470, 255, 690, 188, 698, 35, 469, +-86, 77, -198, -298, -179, -551, -93, -565, +-79, -358, 40, -84, 189, 224, 194, 429, +153, 389, 68, 158, -87, -147, -210, -381, +-220, -394, -128, -160, 53, 224, 253, 569, +283, 606, 174, 304, 16, -189, -260, -612, +-443, -761, -367, -561, -175, -71, 129, 444, +398, 658, 484, 539, 390, 243, 133, -156, +-174, -412, -346, -394, -385, -242, -320, -52, +-120, 103, 96, 184, 277, 291, 394, 404, +334, 370, 135, 194, -141, -131, -438, -588, +-541, -886, -351, -774, 26, -310, 407, 284, +618, 780, 527, 946, 171, 713, -265, 237, +-554, -226, -564, -474, -350, -493, -42, -372, +269, -165, 421, 26, 425, 84, 302, 44, +82, -9, -119, -7, -285, 60, -368, 170, +-240, 303, 1, 317, 165, 97, 270, -226, +233, -449, 4, -475, -236, -263, -348, 100, +-279, 404, -67, 458, 163, 214, 324, -90, +370, -246, 277, -218, 81, 6, -59, 251, +-118, 281, -204, 68, -235, -292, -153, -574, +-101, -513, -10, -168, 87, 289, 81, 688, +34, 756, -90, 411, -203, -82, -93, -477, +103, -642, 274, -501, 480, -181, 465, 130, +191, 301, -151, 305, -481, 237, -621, 203, +-548, 171, -315, 87, 73, -28, 419, -233, +552, -458, 473, -537, 255, -440, -62, -147, +-356, 260, -439, 596, -308, 777, -63, 722, +195, 375, 338, -95, 389, -523, 243, -782, +-69, -779, -285, -517, -415, -84, -452, 300, +-312, 499, 0, 511, 327, 367, 460, 157, +442, -12, 317, -119, 61, -133, -180, -116, +-279, -108, -214, -47, -94, 11, -83, 10, +-95, -55, -95, -145, -152, -208, -113, -192, +67, -28, 303, 221, 438, 379, 376, 346, +213, 148, -36, -89, -398, -206, -616, -203, +-565, -66, -313, 123, 117, 134, 558, 31, +824, -64, 762, -165, 312, -214, -318, -190, +-806, -140, -1001, -9, -789, 124, -181, 227, +482, 347, 887, 353, 910, 197, 566, 11, +29, -155, -509, -317, -794, -400, -667, -377, +-259, -238, 188, 13, 579, 283, 716, 504, +470, 571, -7, 338, -459, -72, -699, -412, +-634, -595, -343, -550, 79, -292, 485, 24, +604, 301, 506, 466, 331, 515, 84, 495, +-133, 331, -282, -5, -369, -352, -378, -602, +-354, -685, -231, -508, 25, -157, 280, 215, +406, 452, 402, 483, 228, 407, -67, 291, +-305, 131, -342, -14, -212, -135, 29, -295, +281, -468, 373, -539, 285, -444, 85, -166, +-181, 256, -363, 671, -381, 917, -325, 843, +-150, 381, 53, -255, 181, -799, 260, -1090, +310, -948, 309, -434, 243, 190, 107, 687, +-82, 845, -314, 641, -471, 258, -455, -147, +-233, -388, 111, -314, 427, -46, 572, 213, +476, 307, 130, 148, -276, -197, -551, -540, +-645, -678, -451, -474, -63, 0, 331, 460, +611, 705, 660, 675, 461, 373, 105, -56, +-311, -351, -577, -413, -604, -300, -437, -84, +-123, 98, 243, 178, 484, 112, 512, -96, +362, -255, 98, -240, -166, -99, -339, 137, +-404, 371, -296, 435, -123, 247, 11, -107, +167, -397, 283, -470, 328, -330, 293, -14, +146, 378, -46, 593, -268, 477, -459, 138, +-403, -263, -204, -578, 45, -668, 321, -436, +462, 35, 412, 458, 222, 635, -49, 547, +-269, 237, -392, -188, -423, -479, -304, -503, +-42, -310, 223, -9, 409, 256, 491, 390, +393, 360, 78, 124, -286, -187, -523, -333, +-548, -308, -347, -162, 3, 103, 390, 311, +588, 295, 490, 132, 222, -55, -90, -155, +-373, -160, -479, -165, -390, -155, -153, -114, +138, -56, 335, 105, 392, 344, 306, 478, +13, 371, -336, 37, -480, -329, -388, -503, +-119, -433, 277, -177, 580, 113, 575, 229, +266, 124, -170, -35, -468, -73, -457, 45, +-244, 262, 47, 421, 284, 369, 213, 76, +-66, -378, -285, -751, -284, -789, -38, -452, +277, 136, 483, 756, 488, 1081, 194, 919, +-197, 323, -440, -437, -490, -983, -362, -1133, +-160, -854, 50, -221, 252, 480, 373, 961, +432, 1101, 392, 849, 188, 277, -159, -393, +-511, -919, -673, -1046, -555, -717, -221, -152, +211, 389, 584, 711, 711, 675, 582, 352, +283, 9, -60, -199, -395, -260, -663, -229, +-753, -173, -600, -114, -240, -64, 275, -31, +776, 36, 1034, 154, 867, 237, 323, 232, +-350, 149, -852, 2, -1015, -210, -785, -399, +-242, -398, 342, -182, 702, 117, 787, 388, +620, 543, 255, 468, -178, 190, -565, -150, +-748, -419, -666, -550, -375, -559, 73, -412, +578, -82, 849, 298, 796, 571, 476, 692, +-6, 594, -491, 291, -792, -71, -809, -356, +-550, -495, -151, -522, 241, -517, 537, -413, +681, -129, 568, 219, 286, 515, 2, 722, +-263, 681, -435, 317, -442, -126, -299, -418, +-101, -525, 45, -461, 111, -291, 151, -94, +141, 78, 127, 184, 162, 281, 227, 394, +193, 402, 55, 252, -125, -4, -311, -296, +-439, -565, -411, -726, -233, -596, 62, -155, +326, 382, 444, 841, 448, 1035, 310, 824, +20, 268, -219, -400, -325, -871, -317, -993, +-200, -844, -55, -483, 77, 20, 143, 492, +105, 817, 37, 931, 28, 767, 22, 322, +25, -264, 34, -709, 43, -810, 20, -595, +-24, -226, -69, 121, -87, 322, -85, 339, +-76, 242, -46, 163, 3, 118, 67, 36, +130, -59, 172, -113, 184, -109, 118, -86, +-36, -101, -219, -139, -348, -162, -331, -123, +-151, 40, 131, 300, 403, 498, 527, 471, +365, 190, 5, -195, -391, -529, -645, -687, +-605, -564, -226, -215, 284, 228, 686, 601, +794, 738, 487, 610, -58, 245, -541, -274, +-807, -664, -662, -704, -159, -430, 323, 12, +590, 421, 545, 596, 199, 446, -174, 71, +-350, -305, -264, -491, 10, -433, 227, -196, +224, 137, 26, 444, -238, 552, -419, 402, +-334, 111, -27, -211, 316, -462, 524, -541, +511, -387, 268, -70, -83, 198, -434, 307, +-605, 296, -519, 180, -266, 7, 112, -66, +495, 19, 681, 142, 576, 163, 199, 51, +-269, -139, -606, -354, -681, -483, -430, -392, +39, -95, 444, 217, 566, 379, 412, 429, +91, 380, -217, 239, -373, 79, -290, -61, +-65, -208, 137, -401, 207, -551, 165, -457, +47, -134, -83, 235, -181, 552, -192, 672, +-124, 484, -6, 61, 140, -364, 275, -578, +327, -525, 207, -312, -51, -8, -327, 314, +-503, 446, -472, 358, -174, 206, 266, 62, +602, -91, 672, -209, 464, -241, 35, -211, +-418, -173, -691, -97, -677, 91, -415, 277, +-16, 298, 333, 157, 547, -67, 561, -294, +370, -380, 75, -243, -191, 78, -347, 415, +-344, 507, -197, 354, 33, 111, 198, -170, +193, -410, 53, -445, -163, -316, -319, -177, +-294, -24, -72, 148, 234, 276, 469, 313, +489, 241, 275, 126, -76, 37, -372, -64, +-492, -142, -354, -141, -56, -145, 248, -178, +407, -173, 318, -68, 40, 90, -240, 209, +-410, 264, -375, 256, -130, 149, 204, -39, +454, -192, 480, -275, 292, -324, 2, -314, +-284, -192, -455, 33, -389, 294, -169, 498, +81, 567, 248, 474, 285, 176, 227, -225, +83, -538, -88, -684, -159, -642, -170, -430, +-148, -96, -116, 277, -14, 555, 126, 694, +212, 721, 254, 539, 255, 138, 131, -307, +-94, -685, -316, -877, -421, -764, -389, -416, +-271, 24, -13, 443, 280, 670, 456, 674, +500, 571, 413, 359, 211, 30, -64, -278, +-376, -500, -528, -632, -496, -585, -344, -373, +-84, -86, 254, 193, 483, 368, 471, 466, +296, 528, 82, 476, -165, 301, -336, 49, +-356, -285, -226, -589, -47, -719, 40, -611, +113, -273, 184, 135, 146, 455, 86, 646, +109, 645, 143, 430, 131, 122, 43, -190, +-87, -442, -257, -573, -453, -560, -535, -360, +-358, -73, 8, 159, 399, 359, 678, 522, +752, 547, 503, 437, 25, 227, -424, -78, +-637, -421, -585, -699, -348, -732, -9, -465, +308, -51, 387, 340, 260, 608, 111, 619, +-52, 364, -182, 74, -186, -123, -65, -229, +90, -239, 172, -229, 144, -210, 64, -141, +-83, -56, -242, 68, -289, 247, -151, 314, +76, 237, 258, 116, 369, -17, 349, -167, +132, -321, -169, -409, -404, -391, -450, -250, +-334, 66, -100, 521, 205, 849, 417, 825, +409, 434, 222, -183, -12, -770, -176, -1031, +-232, -844, -162, -334, 22, 252, 145, 631, +107, 696, -50, 522, -219, 189, -309, -154, +-250, -331, -64, -339, 206, -249, 443, -77, +502, 119, 375, 274, 171, 328, -95, 262, +-363, 94, -541, -194, -564, -517, -419, -686, +-140, -574, 186, -181, 506, 381, 684, 865, +558, 1017, 235, 744, -134, 155, -466, -484, +-600, -900, -458, -958, -145, -670, 222, -151, +434, 370, 419, 707, 254, 795, -26, 590, +-343, 156, -457, -319, -309, -643, -42, -690, +230, -450, 443, -39, 464, 362, 248, 590, +-106, 549, -381, 288, -471, -69, -409, -393, +-211, -539, 109, -424, 373, -119, 455, 225, +380, 427, 208, 366, -1, 106, -231, -196, +-337, -312, -273, -135, -161, 161, -72, 329, +2, 259, 55, -62, 76, -466, 64, -644, +118, -464, 201, -22, 196, 472, 85, 778, +-23, 769, -111, 464, -193, -25, -217, -497, +-134, -752, -34, -723, 2, -437, 32, -3, +118, 396, 187, 573, 174, 457, 117, 163, +23, -130, -139, -312, -317, -322, -334, -135, +-160, 129, 108, 332, 342, 436, 465, 370, +403, 95, 112, -303, -298, -660, -563, -794, +-582, -586, -378, -108, 0, 453, 434, 863, +679, 928, 597, 613, 263, 86, -144, -435, +-478, -782, -613, -841, -466, -592, -106, -117, +235, 403, 381, 772, 376, 861, 242, 610, +19, 99, -162, -464, -209, -836, -167, -895, +-103, -638, -71, -166, -12, 346, 80, 734, +144, 880, 168, 739, 193, 387, 144, -56, +-39, -480, -252, -738, -371, -758, -355, -559, +-190, -234, 93, 135, 404, 453, 583, 606, +471, 575, 142, 391, -242, 105, -554, -154, +-640, -313, -430, -392, -26, -369, 382, -266, +583, -150, 533, 4, 295, 213, -41, 387, +-354, 418, -488, 288, -426, 35, -239, -237, +-4, -396, 227, -360, 378, -147, 385, 107, +237, 262, 28, 271, -165, 181, -307, 7, +-308, -180, -157, -270, 50, -239, 210, -113, +254, 61, 168, 234, 20, 323, -149, 250, +-247, 62, -195, -96, -74, -167, 39, -178, +145, -152, 189, -125, 180, -136, 121, -156, +17, -88, -73, 130, -144, 402, -195, 553, +-151, 495, -35, 237, 65, -183, 98, -632, +77, -864, 15, -755, -39, -396, -5, 113, +118, 658, 251, 1014, 264, 1008, 91, 642, +-211, 51, -524, -585, -683, -1065, -506, -1178, +-20, -837, 567, -172, 970, 537, 961, 996, +518, 1067, -180, 735, -852, 133, -1142, -414, +-901, -652, -311, -593, 349, -379, 826, -125, +900, 63, 607, 110, 144, 92, -281, 149, +-516, 276, -541, 333, -418, 271, -192, 109, +53, -135, 236, -363, 359, -449, 385, -339, +284, -97, 68, 136, -160, 274, -307, 306, +-309, 224, -199, 60, -37, -85, 126, -136, +199, -128, 152, -108, 83, -61, 37, 18, +-2, 87, -59, 118, -108, 123, -126, 102, +-122, 1, -80, -135, 27, -212, 137, -198, +160, -125, 94, -30, -8, 85, -71, 180, +-79, 221, -33, 216, 50, 203, 115, 127, +84, -43, 6, -224, -48, -320, -79, -282, +-119, -132, -151, 16, -145, 86, -104, 48, +-33, -90, 98, -143, 286, 13, 418, 289, +355, 533, 148, 587, -111, 370, -391, -35, +-558, -494, -475, -811, -204, -824, 141, -607, +402, -229, 484, 262, 443, 707, 239, 951, +-55, 901, -262, 544, -348, 3, -384, -550, +-333, -909, -183, -896, 36, -551, 244, -77, +395, 328, 462, 555, 384, 563, 148, 378, +-149, 116, -369, -83, -456, -178, -416, -225, +-231, -224, 30, -142, 231, -47, 308, 11, +296, 84, 228, 147, 87, 133, -58, 30, +-102, -104, -94, -167, -99, -137, -105, -41, +-123, 115, -120, 247, -126, 238, -100, 85, +55, -73, 246, -144, 325, -159, 299, -137, +165, -60, -66, 11, -290, 15, -378, -9, +-260, 6, -54, 43, 120, 33, 217, 38, +215, 111, 103, 170, -57, 155, -106, 58, +-86, -93, -88, -257, -54, -374, 4, -314, +61, -40, 126, 258, 135, 408, 114, 391, +51, 217, -131, -95, -266, -388, -244, -466, +-123, -307, 44, -30, 201, 249, 285, 446, +236, 468, 76, 252, -82, -70, -166, -289, +-190, -383, -168, -391, -93, -283, 17, -75, +59, 169, 53, 350, 87, 443, 120, 451, +112, 248, 53, -158, -37, -504, -105, -640, +-163, -526, -154, -159, 9, 307, 194, 688, +252, 775, 181, 475, -12, -5, -228, -451, +-353, -771, -315, -778, -94, -405, 166, 131, +293, 560, 277, 721, 187, 574, 43, 199, +-80, -240, -101, -512, -91, -451, -117, -175, +-166, 105, -183, 309, -69, 359, 131, 179, +280, -130, 336, -383, 222, -452, -88, -309, +-403, -29, -512, 329, -319, 620, 65, 618, +425, 318, 603, -89, 491, -462, 108, -689, +-315, -660, -570, -347, -566, 116, -329, 518, +29, 730, 366, 715, 507, 433, 408, -84, +168, -600, -95, -859, -308, -792, -376, -454, +-233, 60, 1, 572, 176, 865, 215, 810, +129, 494, 20, 81, -79, -360, -148, -693, +-97, -751, 20, -538, 67, -190, 85, 156, +96, 422, 70, 546, 4, 464, -87, 227, +-166, -6, -186, -175, -147, -302, -33, -344, +162, -241, 296, -55, 279, 81, 177, 162, +14, 232, -201, 250, -324, 171, -282, 36, +-125, -100, 70, -248, 180, -405, 197, -400, +147, -156, 3, 153, -131, 393, -156, 501, +-94, 431, 1, 203, 103, -95, 198, -294, +234, -324, 139, -324, -35, -334, -210, -245, +-337, -73, -350, 105, -198, 289, 94, 461, +349, 529, 443, 393, 353, 99, 115, -194, +-172, -431, -401, -615, -463, -602, -289, -326, +-21, 47, 213, 368, 390, 569, 407, 591, +258, 405, 13, 45, -214, -280, -306, -402, +-296, -413, -195, -335, -37, -108, 85, 145, +131, 290, 125, 302, 131, 227, 143, 116, +113, -54, 59, -215, -31, -250, -161, -204, +-272, -164, -309, -85, -160, 91, 92, 289, +285, 376, 400, 333, 354, 196, 116, -51, +-194, -340, -439, -486, -448, -383, -237, -163, +16, 21, 260, 176, 405, 259, 344, 225, +143, 147, -60, 117, -182, 151, -245, 125, +-225, -30, -120, -193, -6, -322, 93, -411, +146, -340, 145, -71, 105, 265, -3, 457, +-96, 420, -73, 256, -36, 19, -2, -240, +32, -356, 46, -288, 38, -149, -12, -44, +-18, 57, 30, 226, 41, 353, 1, 332, +-94, 205, -175, -32, -177, -356, -132, -612, +52, -601, 312, -273, 440, 183, 402, 555, +170, 752, -194, 683, -515, 299, -655, -227, +-502, -619, -122, -758, 286, -658, 572, -329, +632, 142, 459, 543, 111, 676, -238, 536, +-388, 269, -382, -52, -264, -344, -71, -452, +56, -353, 86, -170, 31, -29, -38, 54, +-8, 140, 75, 162, 158, 107, 229, 113, +214, 171, 106, 160, -42, 62, -176, -67, +-216, -187, -209, -295, -183, -357, -103, -255, +3, -31, 80, 167, 107, 317, 137, 438, +148, 450, 128, 278, 100, -1, 63, -278, +19, -506, -69, -625, -224, -550, -285, -242, +-218, 170, -125, 487, 56, 671, 243, 724, +285, 530, 224, 139, 100, -279, -24, -609, +-96, -773, -144, -739, -168, -444, -153, 33, +-119, 426, -65, 618, 80, 630, 290, 470, +375, 196, 272, -90, 42, -266, -281, -319, +-546, -350, -592, -329, -333, -192, 162, -16, +610, 117, 773, 205, 636, 245, 222, 195, +-335, 41, -739, -110, -781, -145, -489, -81, +-48, 19, 389, 149, 631, 252, 558, 188, +246, -48, -128, -293, -358, -406, -362, -358, +-198, -163, 55, 151, 250, 414, 218, 441, +5, 259, -209, 15, -292, -175, -198, -260, +17, -221, 282, -60, 436, 109, 355, 128, +100, 39, -175, -56, -354, -144, -404, -175, +-314, -112, -92, 43, 150, 194, 298, 213, +341, 167, 290, 137, 165, 68, -36, -25, +-236, -90, -326, -163, -318, -261, -234, -337, +-63, -283, 158, -68, 312, 183, 321, 373, +227, 476, 97, 432, -28, 196, -116, -118, +-131, -346, -103, -440, -123, -406, -209, -229, +-250, 47, -184, 292, -24, 359, 213, 266, +439, 135, 519, -30, 346, -183, -2, -232, +-351, -212, -552, -159, -523, -77, -262, 62, +143, 278, 493, 422, 576, 356, 379, 153, +58, -132, -275, -427, -532, -544, -555, -417, +-316, -121, 16, 173, 295, 341, 481, 393, +528, 341, 398, 180, 123, 1, -196, -110, +-434, -189, -566, -263, -576, -290, -360, -231, +14, -111, 354, 41, 625, 228, 749, 417, +606, 465, 231, 286, -228, -14, -607, -310, +-777, -518, -700, -542, -410, -347, 32, -26, +429, 249, 591, 395, 555, 456, 430, 424, +201, 271, -63, 40, -228, -210, -321, -403, +-367, -509, -378, -471, -303, -250, -111, 43, +117, 279, 322, 421, 466, 453, 475, 348, +296, 109, 11, -161, -237, -309, -393, -337, +-450, -263, -352, -86, -144, 81, 79, 151, +252, 132, 347, 112, 388, 136, 303, 139, +82, 44, -147, -111, -323, -263, -399, -355, +-336, -297, -156, -59, 74, 240, 240, 425, +284, 433, 283, 303, 242, 93, 152, -159, +35, -377, -116, -450, -294, -372, -452, -196, +-486, 73, -316, 331, 48, 412, 436, 309, +656, 100, 634, -90, 366, -170, -108, -171, +-534, -97, -682, 18, -571, 51, -248, 10, +149, -18, 432, -42, 542, -56, 445, -32, +190, 30, -67, 114, -254, 129, -359, 44, +-321, -51, -184, -106, -50, -108, 54, -9, +135, 134, 152, 181, 131, 85, 143, -110, +141, -254, 113, -257, 28, -145, -145, 67, +-278, 286, -277, 357, -192, 256, -9, 48, +226, -192, 352, -346, 298, -355, 109, -172, +-121, 143, -260, 357, -252, 366, -152, 187, +-14, -110, 93, -375, 84, -457, 0, -306, +-54, -9, -23, 281, 103, 472, 278, 526, +351, 406, 248, 100, -11, -296, -360, -592, +-611, -675, -631, -507, -381, -99, 67, 359, +504, 616, 721, 563, 646, 277, 322, -56, +-84, -284, -385, -347, -490, -233, -397, -40, +-190, 103, 18, 154, 110, 137, 98, 80, +87, -17, 83, -120, 99, -165, 128, -144, +126, -93, 78, -12, -19, 97, -125, 195, +-169, 235, -174, 198, -152, 87, -66, -93, +56, -260, 175, -295, 242, -166, 242, 68, +127, 240, -102, 248, -328, 114, -415, -113, +-303, -290, -43, -274, 243, -97, 442, 124, +473, 275, 272, 298, -50, 220, -298, 63, +-414, -122, -393, -242, -243, -256, -3, -188, +217, -47, 328, 117, 344, 204, 267, 174, +86, 39, -140, -112, -311, -175, -344, -144, +-259, -26, -115, 152, 98, 271, 265, 262, +261, 138, 146, -77, 42, -287, -8, -383, +-33, -317, -36, -77, -38, 204, -91, 348, +-209, 329, -276, 159, -177, -76, 70, -222, +309, -227, 428, -119, 411, 19, 180, 110, +-177, 148, -436, 139, -503, 72, -376, -44, +-110, -160, 193, -223, 417, -201, 443, -79, +269, 90, 42, 214, -147, 241, -274, 173, +-298, 78, -166, 26, 32, -19, 133, -69, +135, -129, 105, -226, 44, -294, -42, -274, +-105, -134, -80, 106, -5, 349, 14, 512, +20, 534, 63, 349, 77, 2, 47, -377, +-3, -647, -32, -669, -62, -436, -102, -41, +-53, 359, 64, 571, 145, 524, 138, 301, +36, 27, -108, -188, -241, -286, -278, -266, +-101, -170, 205, -63, 409, 37, 389, 108, +188, 132, -100, 102, -399, 23, -515, -52, +-322, -83, 23, -73, 304, -28, 420, 46, +360, 96, 144, 80, -156, 24, -372, -30, +-356, -52, -175, -20, 38, 45, 245, 94, +387, 62, 338, -91, 101, -262, -138, -315, +-296, -195, -356, 84, -283, 389, -97, 537, +137, 427, 277, 85, 254, -318, 175, -551, +85, -531, -47, -297, -133, 51, -113, 352, +-46, 488, -28, 432, -42, 231, -12, -30, +19, -281, 10, -448, -10, -451, 8, -297, +32, -53, -2, 209, -13, 415, 64, 495, +96, 411, 36, 194, -17, -80, -50, -324, +-85, -468, -111, -466, -61, -290, 55, -33, +105, 179, 51, 288, -9, 272, -33, 173, +-69, 61, -82, 0, 8, 30, 124, 106, +134, 119, 68, 54, -10, -89, -88, -298, +-153, -465, -161, -467, -53, -260, 85, 90, +133, 431, 104, 632, 52, 595, -42, 307, +-170, -87, -200, -382, -82, -471, 66, -373, +168, -181, 235, 16, 250, 140, 144, 171, +-79, 149, -246, 124, -286, 79, -284, -33, +-231, -152, -82, -198, 104, -137, 202, 22, +233, 212, 263, 338, 256, 293, 148, 57, +-25, -219, -159, -379, -258, -363, -335, -197, +-330, 43, -187, 228, 1, 237, 119, 98, +238, -41, 354, -68, 353, 26, 214, 182, +15, 281, -184, 217, -361, -44, -467, -378, +-377, -559, -83, -501, 229, -238, 434, 148, +513, 501, 412, 664, 69, 567, -352, 260, +-606, -121, -612, -463, -408, -663, -33, -610, +429, -303, 757, 105, 760, 448, 466, 616, +34, 546, -436, 256, -798, -111, -862, -381, +-570, -455, -76, -355, 391, -164, 720, 42, +810, 177, 583, 165, 143, 76, -286, 34, +-533, 64, -581, 155, -459, 249, -164, 241, +166, 88, 344, -192, 361, -464, 271, -553, +123, -437, -60, -183, -200, 134, -184, 412, +-75, 568, 16, 574, 76, 455, 121, 218, +113, -137, 18, -535, -90, -796, -112, -772, +-84, -460, -69, 53, -7, 579, 97, 870, +156, 791, 131, 392, 74, -126, 50, -536, +18, -704, -39, -589, -66, -249, -72, 127, +-96, 361, -127, 420, -84, 351, 52, 221, +169, 77, 231, -50, 247, -155, 162, -267, +-20, -375, -218, -381, -303, -225, -246, 37, +-128, 291, 32, 443, 221, 433, 348, 261, +319, 39, 178, -122, 19, -182, -158, -188, +-342, -201, -397, -220, -272, -219, -45, -198, +197, -101, 399, 107, 497, 346, 384, 501, +91, 491, -228, 311, -441, -9, -495, -381, +-380, -620, -105, -583, 232, -307, 428, 68, +425, 384, 304, 519, 78, 406, -177, 102, +-323, -208, -307, -366, -150, -333, 40, -143, +158, 134, 201, 361, 148, 385, -8, 190, +-127, -89, -119, -319, -49, -401, -3, -301, +18, -87, 11, 120, -44, 217, -88, 216, +-41, 226, 88, 250, 199, 199, 191, 51, +87, -180, -51, -425, -219, -538, -322, -401, +-265, -33, -98, 365, 74, 575, 170, 528, +211, 281, 188, -53, 86, -335, -22, -441, +-75, -372, -101, -214, -136, -33, -151, 145, +-119, 280, -60, 319, -6, 255, 56, 158, +104, 55, 97, -86, 27, -214, -56, -299, +-71, -342, -45, -312, -10, -177, 45, 73, +85, 349, 33, 516, -95, 520, -185, 360, +-179, 56, -100, -290, 25, -531, 169, -574, +219, -441, 115, -199, -79, 92, -245, 340, +-263, 452, -141, 429, 59, 325, 264, 168, +323, -53, 174, -286, -79, -422, -278, -417, +-330, -270, -238, -19, -39, 225, 161, 340, +217, 257, 122, 53, -23, -112, -110, -155, +-96, -82, -15, 69, 99, 202, 178, 222, +119, 118, -56, -57, -213, -227, -280, -347, +-240, -370, -104, -231, 92, 43, 258, 323, +289, 479, 213, 446, 96, 236, -20, -71, +-111, -315, -148, -377, -129, -268, -109, -96, +-125, 47, -141, 129, -99, 140, 10, 76, +155, 1, 296, -25, 386, -11, 328, 27, +115, 72, -141, 102, -342, 60, -417, -72, +-330, -202, -117, -222, 124, -119, 286, 50, +321, 220, 269, 303, 160, 221, 20, 17, +-99, -190, -167, -302, -185, -288, -158, -171, +-74, 26, 59, 231, 190, 315, 245, 258, +205, 117, 106, -57, -40, -196, -169, -243, +-194, -172, -107, -44, 31, 45, 147, 86, +184, 106, 146, 91, 46, 33, -62, -31, +-84, -63, -20, -68, 58, -49, 99, 11, +70, 87, -34, 105, -142, 49, -172, -15, +-77, -50, 127, -76, 321, -90, 390, -73, +292, -32, 48, 19, -249, 88, -445, 154, +-435, 165, -256, 63, 2, -111, 262, -231, +427, -223, 442, -99, 337, 103, 150, 296, +-69, 341, -278, 186, -413, -83, -419, -314, +-289, -412, -41, -348, 226, -113, 413, 205, +465, 417, 338, 424, 100, 267, -121, 33, +-274, -182, -337, -286, -289, -254, -182, -148, +-67, -68, 61, -35, 192, 18, 281, 110, +300, 185, 221, 198, 48, 133, -134, 1, +-269, -130, -316, -161, -237, -52, -95, 91, +26, 124, 103, 27, 146, -121, 168, -242, +177, -249, 144, -92, 50, 136, -110, 291, +-289, 301, -377, 203, -307, 69, -83, -69, +197, -175, 384, -217, 379, -206, 179, -181, +-128, -119, -375, 12, -424, 163, -282, 262, +-41, 274, 194, 198, 300, 52, 230, -118, +70, -232, -91, -217, -192, -117, -196, -21, +-140, 38, -61, 60, -2, 44, 14, 16, +3, 29, -12, 68, -30, 71, -35, 20, +-19, -37, 17, -46, 73, -12, 97, 39, +88, 77, 37, 62, -83, -26, -230, -142, +-311, -208, -284, -197, -162, -126, 23, -15, +212, 137, 317, 291, 293, 370, 160, 348, +-2, 211, -118, -28, -200, -296, -236, -485, +-230, -515, -214, -389, -185, -164, -96, 111, +79, 383, 283, 562, 425, 578, 421, 426, +249, 126, -54, -253, -372, -568, -528, -671, +-462, -508, -240, -166, 22, 198, 220, 442, +291, 493, 247, 341, 155, 105, 113, -81, +130, -175, 103, -186, -6, -162, -164, -135, +-332, -111, -417, -89, -322, -28, -59, 107, +262, 249, 483, 294, 500, 215, 326, 52, +26, -144, -287, -287, -450, -290, -386, -177, +-164, -34, 114, 74, 338, 147, 414, 187, +299, 194, 35, 150, -221, 50, -334, -100, +-259, -252, -44, -298, 228, -179, 418, 64, +370, 274, 110, 321, -198, 191, -397, -54, +-389, -278, -161, -334, 188, -193, 472, 44, +518, 223, 314, 271, -12, 201, -310, 50, +-451, -98, -378, -154, -121, -127, 189, -67, +391, -14, 422, 16, 333, 28, 150, 15, +-84, -8, -243, -9, -278, 7, -248, 17, +-170, 29, -31, 62, 133, 86, 267, 64, +339, 1, 347, -79, 271, -130, 79, -115, +-184, -24, -389, 91, -438, 128, -338, 40, +-119, -116, 185, -226, 440, -199, 510, -16, +396, 250, 194, 440, -48, 421, -271, 186, +-375, -133, -345, -395, -236, -506, -99, -439, +44, -230, 201, 29, 323, 254, 328, 409, +254, 465, 146, 388, -25, 179, -221, -92, +-313, -330, -267, -448, -172, -407, -65, -222, +61, 24, 156, 216, 168, 286, 126, 232, +100, 109, 78, 2, 16, -46, -69, -14, +-122, 43, -154, 38, -187, -54, -175, -185, +-63, -272, 88, -236, 177, -59, 208, 186, +192, 361, 71, 368, -134, 214, -272, -24, +-264, -235, -155, -338, -9, -300, 120, -150, +196, 30, 138, 182, -31, 275, -163, 273, +-186, 162, -143, -29, -67, -217, 47, -322, +139, -290, 122, -124, 38, 110, -31, 313, +-70, 371, -111, 270, -149, 67, -122, -164, +-74, -337, -67, -377, -41, -271, 45, -79, +124, 125, 134, 280, 99, 344, 44, 295, +-50, 142, -179, -52, -259, -212, -221, -306, +-123, -288, -30, -146, 84, 44, 194, 181, +213, 201, 133, 119, 28, 5, -60, -66, +-152, -43, -236, 50, -235, 109, -138, 64, +-48, -61, 28, -175, 141, -198, 217, -121, +178, 22, 64, 154, -48, 201, -134, 164, +-200, 101, -194, 45, -66, -24, 75, -118, +118, -221, 85, -282, 45, -262, -25, -110, +-116, 155, -122, 412, -12, 521, 109, 409, +161, 114, 162, -264, 109, -569, -33, -647, +-209, -427, -281, -14, -201, 401, -61, 643, +88, 596, 231, 278, 302, -158, 227, -490, +56, -569, -69, -401, -113, -102, -148, 207, +-137, 404, -40, 425, 53, 295, 73, 106, +63, -87, 83, -252, 78, -340, 24, -326, +-24, -211, -18, -50, 11, 114, 18, 256, +38, 320, 103, 270, 117, 149, 30, 15, +-45, -112, -64, -203, -72, -230, -56, -188, +37, -112, 144, -24, 151, 65, 80, 136, +14, 151, -15, 97, -38, 28, -36, -21, +37, -41, 127, -24, 121, 19, 42, 47, +-29, 23, -95, -32, -166, -55, -161, -45, +1, -38, 214, -52, 346, -83, 371, -97, +286, -54, 43, 70, -275, 225, -484, 312, +-481, 238, -295, 20, -8, -211, 318, -335, +573, -303, 602, -135, 384, 62, 76, 170, +-210, 168, -441, 119, -526, 82, -379, 66, +-95, 31, 149, -34, 292, -117, 345, -198, +288, -215, 130, -118, -24, 57, -71, 219, +-53, 297, -59, 269, -88, 144, -114, -51, +-153, -252, -193, -367, -131, -356, 59, -230, +243, -9, 316, 247, 294, 418, 180, 427, +-17, 276, -225, 32, -332, -211, -301, -368, +-219, -379, -115, -239, 42, -41, 214, 117, +297, 213, 263, 229, 165, 167, 7, 75, +-200, -9, -341, -69, -312, -123, -159, -159, +16, -138, 157, -57, 237, 51, 204, 152, +49, 219, -111, 200, -201, 84, -236, -93, +-207, -259, -106, -339, 54, -310, 185, -146, +221, 121, 196, 375, 102, 490, -58, 413, +-216, 173, -301, -140, -274, -395, -176, -473, +-76, -352, 28, -131, 118, 68, 148, 184, +151, 204, 172, 157, 170, 108, 93, 106, +-54, 134, -221, 133, -363, 59, -417, -74, +-346, -232, -147, -359, 114, -377, 306, -229, +381, 28, 362, 273, 231, 426, 22, 431, +-181, 277, -317, 38, -357, -176, -315, -296, +-207, -309, -38, -258, 118, -153, 189, -14, +221, 108, 234, 197, 194, 243, 97, 225, +-33, 128, -170, -16, -289, -134, -343, -177, +-276, -164, -73, -102, 156, -9, 292, 62, +322, 86, 231, 66, 36, 30, -144, -5, +-209, -30, -154, -24, -57, 12, 17, 30, +56, 14, 49, -20, 8, -39, -7, -16, +33, 47, 79, 127, 64, 153, -12, 63, +-80, -119, -100, -299, -66, -367, 48, -265, +183, 0, 224, 324, 130, 545, -27, 531, +-157, 282, -211, -93, -151, -437, -1, -589, +153, -500, 237, -213, 195, 141, 77, 393, +-32, 453, -106, 324, -117, 76, -45, -170, +63, -291, 115, -244, 88, -82, 17, 109, +-51, 217, -86, 176, -56, 26, 63, -149, +206, -237, 266, -178, 208, -21, 72, 140, +-103, 213, -267, 169, -324, 47, -228, -74, +-27, -128, 179, -97, 317, -37, 356, 12, +283, 34, 122, 29, -36, 27, -123, 31, +-160, 28, -173, 5, -160, -39, -107, -79, +-28, -80, 47, -28, 135, 39, 216, 82, +227, 81, 164, 32, 83, -27, 28, -38, +-31, 9, -102, 70, -142, 86, -161, 28, +-169, -87, -129, -208, -10, -246, 153, -153, +259, 22, 267, 206, 202, 307, 66, 278, +-102, 139, -206, -36, -197, -171, -108, -217, +-17, -172, 34, -79, 51, 4, 31, 52, +-8, 50, -10, 7, 49, -33, 112, -36, +107, 2, 40, 76, -51, 164, -140, 204, +-197, 152, -169, 9, -54, -167, 76, -304, +156, -330, 175, -209, 146, 6, 39, 221, +-112, 319, -209, 259, -209, 91, -143, -99, +-52, -212, 68, -189, 160, -52, 136, 104, +37, 190, -37, 169, -78, 63, -122, -85, +-136, -216, -89, -255, -38, -195, -7, -70, +54, 91, 125, 239, 139, 312, 57, 270, +-95, 124, -228, -64, -290, -213, -257, -271, +-90, -229, 155, -108, 327, 18, 320, 80, +151, 95, -75, 95, -292, 94, -403, 91, +-317, 83, -77, 52, 145, -10, 231, -89, +201, -129, 92, -123, -81, -96, -233, -54, +-229, -14, -87, 41, 54, 114, 153, 182, +218, 220, 184, 164, -11, -9, -253, -225, +-375, -368, -368, -341, -264, -139, -20, 146, +298, 389, 491, 445, 456, 275, 263, -7, +3, -261, -293, -382, -515, -333, -524, -152, +-325, 73, -46, 228, 206, 258, 400, 195, +451, 70, 290, -70, 14, -167, -200, -162, +-286, -52, -261, 82, -136, 167, 57, 164, +179, 35, 144, -170, 21, -319, -87, -308, +-126, -130, -90, 133, 25, 360, 197, 441, +293, 337, 202, 89, 1, -180, -176, -352, +-293, -384, -316, -302, -161, -134, 112, 62, +323, 203, 374, 271, 287, 274, 106, 205, +-123, 63, -314, -101, -332, -207, -160, -228, +60, -159, 244, -27, 353, 89, 308, 132, +100, 76, -138, -42, -277, -106, -263, -71, +-131, 34, 49, 150, 236, 194, 333, 115, +277, -60, 129, -211, -10, -231, -128, -114, +-216, 69, -218, 209, -129, 209, -3, 70, +90, -125, 144, -259, 204, -247, 226, -102, +177, 101, 132, 269, 98, 345, 13, 309, +-112, 158, -226, -52, -275, -269, -250, -458, +-164, -533, 15, -421, 251, -117, 426, 286, +468, 635, 387, 775, 194, 622, -101, 211, +-388, -297, -525, -692, -461, -809, -241, -622, +59, -241, 376, 207, 578, 561, 531, 684, +273, 571, -52, 284, -350, -86, -520, -414, +-460, -588, -186, -536, 151, -282, 380, 58, +434, 359, 340, 510, 139, 471, -95, 265, +-249, -21, -285, -259, -252, -402, -203, -441, +-123, -356, 28, -160, 194, 96, 297, 336, +347, 494, 331, 509, 167, 325, -113, 7, +-336, -299, -438, -482, -445, -480, -316, -331, +-49, -107, 234, 115, 393, 245, 409, 286, +335, 296, 155, 276, -117, 196, -334, 31, +-414, -171, -382, -349, -238, -443, 5, -354, +255, -77, 377, 240, 325, 440, 128, 442, +-123, 247, -334, -58, -426, -337, -326, -447, +-83, -350, 154, -110, 292, 168, 315, 374, +219, 459, 35, 377, -172, 136, -302, -152, +-298, -396, -240, -535, -157, -499, -16, -279, +116, 52, 172, 364, 189, 559, 189, 589, +124, 419, -18, 100, -188, -241, -314, -486, +-351, -561, -281, -453, -99, -212, 151, 81, +317, 316, 325, 407, 224, 361, 54, 231, +-146, 69, -301, -95, -342, -219, -272, -266, +-168, -262, -57, -195, 99, -60, 260, 92, +336, 224, 338, 293, 265, 273, 52, 169, +-263, 0, -536, -187, -660, -337, -566, -388, +-235, -301, 232, -105, 646, 157, 822, 394, +679, 484, 270, 404, -242, 184, -659, -93, +-806, -320, -648, -432, -275, -409, 179, -281, +528, -93, 637, 126, 506, 319, 216, 439, +-132, 429, -391, 240, -458, -62, -350, -355, +-143, -515, 90, -435, 272, -132, 334, 247, +277, 500, 162, 495, 20, 254, -119, -118, +-195, -440, -207, -548, -180, -426, -121, -140, +-41, 182, 49, 413, 141, 526, 240, 489, +329, 304, 351, 35, 273, -252, 72, -495, +-205, -636, -460, -596, -594, -339, -530, 44, +-251, 437, 179, 733, 605, 809, 855, 604, +825, 170, 501, -341, -27, -743, -563, -898, +-886, -734, -872, -284, -528, 282, 17, 740, +542, 896, 855, 714, 865, 270, 581, -293, +113, -725, -346, -838, -648, -633, -720, -209, +-517, 278, -119, 653, 294, 776, 594, 612, +701, 261, 565, -159, 221, -532, -183, -745, +-476, -731, -583, -459, -498, -13, -213, 447, +183, 788, 491, 870, 605, 598, 521, 81, +250, -456, -119, -794, -415, -826, -514, -537, +-412, -39, -157, 415, 145, 643, 378, 605, +461, 361, 360, 36, 136, -257, -97, -427, +-263, -431, -310, -309, -245, -107, -101, 130, +71, 345, 173, 452, 186, 373, 179, 134, +139, -161, 23, -430, -82, -535, -115, -382, +-134, -54, -133, 297, -62, 526, 24, 531, +53, 301, 46, -65, 53, -385, 79, -527, +90, -445, 79, -183, 54, 115, -43, 341, +-201, 438, -296, 354, -270, 160, -130, -39, +94, -206, 301, -308, 391, -324, 314, -257, +84, -141, -205, 12, -410, 198, -452, 366, +-334, 462, -95, 430, 176, 218, 353, -116, +364, -472, 220, -732, 9, -741, -189, -447, +-318, 63, -306, 608, -158, 978, 12, 1017, +133, 656, 166, 13, 77, -677, -72, -1175, +-198, -1272, -199, -901, -54, -163, 132, 708, +262, 1373, 270, 1548, 100, 1135, -179, 250, +-417, -773, -495, -1538, -360, -1713, -75, -1197, +242, -225, 471, 810, 517, 1518, 332, 1623, +-14, 1113, -359, 223, -596, -687, -626, -1296, +-391, -1423, 1, -1052, 390, -333, 642, 470, +633, 1094, 367, 1313, -41, 1082, -455, 480, +-712, -325, -724, -1021, -493, -1341, -107, -1184, +318, -605, 659, 215, 795, 995, 668, 1427, +310, 1346, -159, 794, -619, -56, -938, -930, +-943, -1513, -598, -1589, -47, -1091, 540, -178, +973, 826, 1062, 1602, 763, 1851, 190, 1417, +-435, 441, -877, -719, -1025, -1648, -852, -2016, +-390, -1665, 190, -680, 683, 567, 967, 1609, +963, 2093, 643, 1830, 83, 893, -538, -391, +-978, -1548, -1071, -2136, -811, -1935, -251, -1015, +460, 285, 1012, 1471, 1173, 2095, 949, 1911, +415, 1027, -294, -176, -896, -1284, -1161, -1883, +-1022, -1770, -540, -1067, 114, -59, 751, 917, +1147, 1559, 1138, 1676, 765, 1250, 157, 440, +-517, -513, -1022, -1324, -1163, -1718, -891, -1550, +-293, -825, 417, 241, 981, 1258, 1213, 1860, +1027, 1800, 468, 1053, -256, -121, -858, -1277, +-1148, -1955, -1039, -1921, -542, -1172, 188, 36, +864, 1225, 1207, 1960, 1134, 1982, 674, 1275, +-65, 107, -780, -1102, -1161, -1909, -1113, -2021, +-673, -1412, 18, -297, 717, 914, 1156, 1789, +1166, 2041, 778, 1562, 152, 523, -531, -695, +-1027, -1676, -1125, -2055, -821, -1672, -259, -668, +393, 577, 914, 1597, 1111, 2004, 923, 1639, +426, 661, -188, -523, -712, -1483, -980, -1860, +-909, -1504, -518, -620, 28, 445, 530, 1324, +854, 1692, 904, 1434, 657, 667, 202, -326, +-301, -1199, -697, -1643, -873, -1476, -756, -755, +-374, 280, 141, 1239, 592, 1710, 808, 1509, +758, 713, 448, -390, -30, -1337, -449, -1714, +-662, -1390, -649, -527, -418, 529, -54, 1365, +292, 1633, 505, 1247, 496, 394, 298, -617, +28, -1391, -230, -1623, -382, -1213, -352, -290, +-187, 774, 1, 1532, 141, 1678, 211, 1141, +193, 131, 101, -937, 6, -1605, -41, -1594, +-67, -970, -109, -4, -168, 937, -211, 1452, +-217, 1371, -156, 810, 20, 5, 263, -744, +455, -1180, 486, -1154, 296, -712, -41, -45, +-427, 616, -723, 1005, -757, 984, -507, 573, +-76, -84, 402, -685, 770, -942, 893, -782, +700, -279, 238, 359, -319, 823, -791, 903, +-1028, 570, -934, -13, -514, -607, 86, -971, +636, -923, 975, -483, 1023, 182, 726, 824, +162, 1159, -463, 1049, -949, 496, -1141, -323, +-967, -1062, -464, -1399, 226, -1192, 847, -489, +1163, 467, 1091, 1293, 628, 1634, -102, 1323, +-819, 465, -1251, -625, -1223, -1526, -733, -1844, +27, -1422, 793, -420, 1268, 789, 1224, 1728, +698, 2002, -82, 1492, -836, 387, -1276, -908, +-1223, -1867, -702, -2096, 85, -1534, 829, -376, +1254, 958, 1217, 1918, 728, 2145, -52, 1579, +-815, 418, -1263, -916, -1252, -1922, -804, -2219, +-62, -1699, 729, -527, 1250, 896, 1322, 2007, +918, 2380, 160, 1855, -665, 574, -1286, -972, +-1423, -2157, -968, -2521, -156, -1892, 725, -505, +1373, 1090, 1460, 2257, 949, 2525, 53, 1816, +-875, 401, -1431, -1166, -1415, -2252, -814, -2465, +185, -1726, 1111, -311, 1550, 1215, 1354, 2260, +598, 2415, -411, 1620, -1265, 184, -1604, -1327, +-1253, -2288, -385, -2334, 627, -1454, 1436, 3, +1701, 1433, 1258, 2251, 313, 2166, -756, 1241, +-1538, -137, -1710, -1407, -1210, -2087, -242, -1949, +823, -1091, 1552, 138, 1684, 1260, 1225, 1871, +358, 1783, -626, 1027, -1365, -85, -1607, -1108, +-1296, -1700, -536, -1642, 405, -948, 1208, 85, +1596, 1044, 1409, 1566, 737, 1455, -143, 771, +-948, -174, -1422, -996, -1367, -1386, -812, -1196, +-25, -541, 711, 263, 1164, 912, 1182, 1181, +794, 949, 176, 362, -393, -305, -715, -819, +-795, -987, -636, -753, -307, -225, 20, 343, +281, 727, 483, 815, 584, 554, 530, 87, +352, -368, 92, -656, -220, -651, -507, -370, +-684, 28, -650, 368, -369, 541, 52, 482, +492, 219, 832, -88, 897, -305, 610, -386, +87, -295, -482, -77, -908, 105, -1028, 164, +-791, 127, -277, 23, 353, -64, 900, -31, +1189, 120, 1094, 275, 602, 306, -176, 151, +-994, -192, -1504, -556, -1492, -726, -930, -596, +93, -135, 1207, 512, 1895, 1035, 1867, 1179, +1089, 837, -195, 64, -1481, -872, -2246, -1544, +-2140, -1631, -1159, -1051, 290, 43, 1636, 1244, +2407, 2045, 2271, 2088, 1220, 1295, -275, -105, +-1661, -1580, -2513, -2531, -2460, -2574, -1460, -1583, +120, 141, 1681, 1919, 2613, 3046, 2570, 3031, +1539, 1768, -116, -318, -1731, -2344, -2683, -3483, +-2587, -3256, -1472, -1652, 190, 661, 1758, 2727, +2628, 3726, 2453, 3187, 1283, 1327, -413, -1061, +-1934, -3044, -2678, -3813, -2343, -3023, -1023, -1010, +735, 1433, 2166, 3343, 2695, 3946, 2111, 2980, +641, 772, -1120, -1815, -2443, -3747, -2707, -4237, +-1830, -3000, -249, -502, 1455, 2288, 2570, 4248, +2540, 4485, 1428, 2889, -255, 93, -1818, -2828, +-2605, -4636, -2271, -4539, -959, -2598, 746, 420, +2131, 3340, 2600, 4900, 1934, 4449, 429, 2209, +-1307, -985, -2535, -3849, -2683, -5119, -1671, -4294, +91, -1735, 1858, 1611, 2896, 4337, 2745, 5228, +1429, 4009, -530, 1190, -2345, -2161, -3229, -4598, +-2793, -5093, -1208, -3588, 949, -689, 2787, 2485, +3485, 4540, 2752, 4723, 875, 3103, -1424, 247, +-3202, -2646, -3651, -4341, -2554, -4252, -413, -2471, +1921, 284, 3511, 2839, 3694, 4091, 2359, 3600, +9, 1663, -2355, -936, -3752, -3039, -3654, -3719, +-2067, -2854, 376, -837, 2658, 1521, 3857, 3099, +3508, 3314, 1766, 2209, -668, 148, -2788, -1936, +-3751, -3090, -3227, -2951, -1440, -1580, 891, 481, +2843, 2277, 3643, 3008, 2959, 2444, 1085, 792, +-1171, -1219, -2886, -2564, -3377, -2693, -2472, -1612, +-604, 235, 1457, 1923, 2895, 2614, 3062, 2075, +1966, 596, 185, -1173, -1621, -2359, -2743, -2422, +-2681, -1421, -1536, 212, 173, 1761, 1769, 2515, +2618, 2188, 2374, 961, 1161, -703, -467, -2083, +-1801, -2539, -2339, -1960, -1926, -572, -732, 1089, +722, 2247, 1778, 2422, 2033, 1587, 1433, 77, +275, -1451, -913, -2281, -1640, -2099, -1609, -1038, +-880, 483, 187, 1743, 1107, 2158, 1478, 1674, +1196, 498, 402, -921, -533, -1879, -1166, -1980, +-1272, -1320, -816, -87, -11, 1227, 778, 1969, +1251, 1884, 1151, 1004, 496, -357, -347, -1573, +-1037, -2037, -1316, -1583, -996, -462, -193, 902, +703, 1798, 1329, 1766, 1397, 997, 840, -177, +-61, -1254, -953, -1642, -1492, -1237, -1418, -357, +-788, 619, 142, 1256, 1037, 1241, 1524, 684, +1406, -129, 763, -844, -101, -1095, -896, -782, +-1368, -125, -1300, 564, -801, 975, -71, 849, +656, 252, 1062, -482, 1083, -1023, 797, -1052, +255, -512, -320, 333, -731, 1105, -931, 1401, +-849, 1029, -477, 147, 29, -872, 511, -1586, +850, -1640, 891, -963, 582, 180, 64, 1302, +-482, 1926, -852, 1767, -874, 811, -585, -554, +-135, -1724, 368, -2183, 769, -1647, 895, -365, +717, 1095, 253, 2087, -388, 2091, -938, 1127, +-1170, -325, -931, -1611, -249, -2128, 600, -1651, +1268, -426, 1421, 962, 925, 1909, -15, 1961, +-981, 1093, -1551, -243, -1513, -1502, -847, -2123, +213, -1720, 1208, -481, 1743, 973, 1557, 2045, +692, 2205, -450, 1264, -1429, -270, -1886, -1709, +-1591, -2428, -625, -1984, 572, -614, 1559, 1027, +1988, 2251, 1593, 2481, 549, 1592, -685, 3, +-1710, -1605, -2080, -2572, -1600, -2457, -484, -1279, +848, 502, 1844, 2135, 2052, 2892, 1421, 2436, +274, 901, -969, -1116, -1877, -2711, -1984, -3134, +-1255, -2182, -63, -243, 1186, 1835, 1935, 3082, +1813, 2970, 946, 1558, -326, -541, -1478, -2337, +-1916, -3049, -1464, -2415, -438, -737, 750, 1240, +1610, 2588, 1662, 2722, 986, 1682, -14, -115, +-1021, -1845, -1582, -2682, -1420, -2324, -655, -892, +402, 994, 1268, 2417, 1566, 2732, 1221, 1831, +339, 59, -696, -1840, -1379, -2906, -1454, -2649, +-897, -1219, 53, 834, 915, 2572, 1347, 3125, +1155, 2273, 416, 392, -450, -1717, -1039, -3042, +-1098, -2961, -593, -1555, 205, 584, 898, 2469, +1113, 3192, 737, 2459, 5, 613, -747, -1527, +-1156, -2987, -1058, -3083, -482, -1774, 403, 366, +1176, 2351, 1481, 3247, 1194, 2727, 359, 985, +-723, -1260, -1588, -2889, -1779, -3202, -1204, -2164, +-105, -114, 1139, 2007, 1941, 3101, 1899, 2862, +1066, 1390, -229, -790, -1416, -2514, -1989, -3040, +-1767, -2287, -795, -480, 548, 1596, 1637, 2837, +2006, 2757, 1565, 1552, 487, -404, -803, -2205, +-1721, -2886, -1934, -2349, -1357, -833, -188, 1111, +1065, 2466, 1902, 2701, 1957, 1881, 1172, 253, +-120, -1468, -1371, -2450, -2035, -2414, -1851, -1420, +-848, 181, 556, 1657, 1659, 2373, 2042, 2077, +1552, 926, 356, -620, -900, -1873, -1744, -2256, +-1913, -1666, -1170, -330, 108, 1135, 1234, 2010, +1866, 2007, 1703, 1132, 698, -235, -545, -1402, +-1463, -1947, -1803, -1676, -1318, -678, -233, 481, +827, 1391, 1505, 1777, 1549, 1367, 864, 469, +-129, -500, -985, -1298, -1491, -1555, -1313, -1157, +-469, -372, 514, 476, 1265, 1132, 1490, 1314, +958, 972, 4, 364, -875, -347, -1429, -938, +-1384, -1118, -690, -906, 228, -453, 974, 169, +1397, 751, 1246, 1030, 549, 976, -261, 612, +-994, -12, -1396, -660, -1132, -1093, -451, -1113, +316, -700, 989, 0, 1200, 778, 865, 1245, +274, 1172, -402, 625, -964, -244, -1046, -1062, +-682, -1383, -166, -1097, 455, -333, 909, 669, +874, 1437, 536, 1521, 33, 902, -542, -136, +-829, -1237, -734, -1850, -472, -1555, -60, -545, +402, 759, 597, 1860, 586, 2101, 511, 1315, +188, -56, -190, -1468, -403, -2273, -605, -1953, +-648, -706, -406, 831, -83, 2055, 259, 2306, +595, 1377, 732, -185, 569, -1668, 222, -2406, +-216, -1955, -624, -515, -724, 1173, -536, 2363, +-250, 2456, 133, 1287, 440, -519, 504, -2114, +441, -2784, 286, -2072, 58, -314, -157, 1602, +-363, 2806, -519, 2655, -519, 1147, -352, -929, +-10, -2572, 415, -2991, 721, -1862, 807, 224, +590, 2195, 61, 3173, -569, 2559, -1042, 595, +-1136, -1659, -724, -3194, 16, -3229, 762, -1629, +1271, 754, 1302, 2822, 746, 3650, -110, 2723, +-908, 509, -1370, -1946, -1260, -3547, -694, -3481, +142, -1787, 994, 703, 1418, 2858, 1339, 3662, +773, 2714, -218, 567, -1091, -1776, -1554, -3301, +-1517, -3177, -780, -1591, 298, 586, 1259, 2507, +1868, 3198, 1699, 2330, 738, 519, -451, -1486, +-1478, -2814, -2030, -2722, -1647, -1376, -507, 493, +754, 2103, 1774, 2667, 2058, 1909, 1360, 299, +153, -1338, -1099, -2259, -1938, -2097, -1894, -890, +-990, 661, 358, 1692, 1567, 1940, 2153, 1277, +1796, 1, 551, -1040, -934, -1507, -2062, -1364, +-2378, -591, -1540, 303, 48, 823, 1658, 1006, +2679, 828, 2478, 376, 1105, 7, -742, -286, +-2411, -554, -3091, -649, -2266, -679, -377, -581, +1739, -138, 3168, 422, 3150, 977, 1639, 1329, +-713, 972, -2798, 112, -3557, -933, -2619, -1819, +-382, -1727, 2116, -732, 3613, 700, 3396, 2073, +1521, 2348, -1155, 1364, -3271, -339, -3827, -2095, +-2560, -2751, 34, -1948, 2596, -196, 3855, 1811, +3339, 2867, 1154, 2391, -1590, 802, -3417, -1295, +-3649, -2690, -2102, -2555, 503, -1219, 2628, 806, +3431, 2344, 2645, 2430, 581, 1311, -1594, -526, +-2893, -2037, -2778, -2181, -1363, -1118, 535, 534, +2030, 1865, 2463, 1917, 1777, 806, 366, -686, +-1153, -1756, -1932, -1684, -1778, -526, -954, 817, +328, 1582, 1309, 1419, 1557, 353, 1246, -797, +365, -1208, -674, -938, -1377, -205, -1573, 513, +-1014, 528, 98, 154, 1197, -81, 1884, -61, +1698, 393, 543, 859, -1014, 625, -2235, -319, +-2411, -1379, -1267, -1876, 659, -1275, 2358, 406, +2942, 2099, 2063, 2672, 55, 1794, -2141, -220, +-3292, -2296, -2799, -3062, -992, -2105, 1364, -110, +3097, 1958, 3294, 2915, 1996, 2188, -223, 512, +-2373, -1236, -3373, -2283, -2912, -2064, -1222, -950, +1074, 376, 2851, 1430, 3387, 1775, 2613, 1300, +606, 380, -1831, -633, -3480, -1419, -3714, -1502, +-2252, -906, 381, 72, 2872, 1080, 4116, 1542, +3414, 1227, 977, 310, -1903, -773, -3809, -1432, +-3841, -1383, -1987, -657, 699, 411, 2822, 1209, +3434, 1401, 2406, 955, 328, 6, -1621, -863, +-2482, -1252, -2160, -1154, -902, -452, 568, 457, +1362, 1045, 1383, 1236, 800, 835, -48, -69, +-545, -906, -576, -1318, -269, -1114, 180, -211, +294, 859, 46, 1435, -244, 1290, -442, 380, +-373, -811, 8, -1504, 422, -1318, 618, -410, +478, 651, 70, 1322, -282, 1197, -408, 416, +-376, -389, -210, -921, -64, -980, -59, -552, +17, -47, 280, 366, 621, 753, 821, 942, +579, 787, -186, 301, -1179, -594, -1754, -1586, +-1406, -1873, -186, -1075, 1399, 566, 2441, 2275, +2219, 2916, 812, 1795, -1048, -543, -2526, -2697, +-2821, -3406, -1665, -2130, 250, 384, 2097, 2499, +3056, 3066, 2551, 2036, 840, 107, -1388, -1595, +-3073, -2193, -3251, -1884, -1766, -1013, 797, 294, +3041, 1457, 3710, 2184, 2457, 2155, -258, 836, +-2837, -1293, -3781, -2952, -2775, -3150, -285, -1402, +2357, 1572, 3614, 3689, 2999, 3642, 1030, 1468, +-1372, -1736, -3006, -3817, -3037, -3645, -1710, -1555, +280, 1310, 2203, 3272, 3001, 3496, 2302, 2044, +648, -294, -1359, -2371, -2736, -3425, -2721, -2870, +-1420, -955, 636, 1418, 2418, 3289, 2980, 3593, +2087, 2114, 96, -388, -1979, -2762, -3069, -3832, +-2657, -3060, -819, -846, 1467, 1768, 2925, 3573, +2922, 3769, 1379, 2165, -930, -574, -2606, -3036, +-2951, -4060, -1834, -3084, 281, -495, 2114, 2215, +2835, 3741, 2259, 3380, 502, 1373, -1471, -1048, +-2629, -2816, -2605, -3240, -1264, -2224, 779, -377, +2388, 1673, 2855, 3069, 1923, 3025, -89, 1593, +-2035, -762, -2849, -2943, -2292, -3458, -568, -2102, +1450, 319, 2686, 2577, 2643, 3106, 1326, 1838, +-627, -190, -2232, -1864, -2752, -2167, -1967, -1207, +-262, 161, 1597, 1127, 2651, 1296, 2318, 747, +892, -131, -986, -766, -2323, -968, -2346, -640, +-1227, 148, 520, 791, 1910, 1014, 2165, 661, +1258, -220, -375, -878, -1732, -938, -2072, -488, +-1215, 277, 394, 748, 1684, 617, 1873, 193, +932, -317, -604, -540, -1716, -320, -1660, 37, +-580, 401, 766, 485, 1475, 242, 1147, -135, +97, -591, -856, -665, -1067, -255, -534, 302, +310, 808, 831, 863, 674, 275, 4, -524, +-712, -984, -973, -928, -529, -368, 301, 421, +1071, 906, 1473, 996, 961, 807, -286, 227, +-1451, -554, -2078, -1168, -1603, -1464, -27, -1107, +1614, 54, 2533, 1282, 2154, 1930, 500, 1626, +-1371, 353, -2485, -1024, -2261, -1779, -848, -1588, +855, -665, 1975, 371, 1963, 1075, 982, 1205, +-351, 980, -1393, 511, -1605, -227, -1014, -881, +-28, -1260, 893, -1150, 1197, -408, 838, 552, +182, 1258, -544, 1297, -906, 651, -636, -160, +-199, -720, 196, -874, 486, -613, 284, -229, +-38, 13, -92, 178, -200, 311, -33, 360, +294, 392, 146, 322, 81, 81, -46, -56, +-420, -183, -333, -394, -73, -433, 138, -433, +370, -297, 277, 145, 1, 562, -181, 760, +-222, 580, 19, 64, 389, -445, 497, -629, +303, -403, -222, -24, -743, 278, -792, 189, +-501, -166, 175, -338, 933, -213, 1101, 282, +843, 787, 129, 835, -750, 387, -1095, -498, +-967, -1212, -322, -1218, 520, -583, 920, 417, +780, 1221, 212, 1268, -391, 617, -624, -220, +-359, -871, 94, -934, 297, -483, 220, -11, +-134, 343, -419, 494, -212, 430, 110, 305, +339, 130, 424, -193, 72, -665, -317, -818, +-342, -489, -202, 166, 0, 1055, 216, 1426, +113, 855, -103, -177, -10, -1290, 76, -1847, +56, -1205, 141, -14, 0, 1138, -199, 1903, +-60, 1512, 41, 404, 128, -723, 242, -1628, +52, -1671, -142, -897, -165, 222, -148, 1265, +13, 1642, 255, 1313, 332, 322, 292, -832, +117, -1519, -232, -1579, -543, -866, -632, 260, +-277, 1238, 443, 1697, 1018, 1401, 1036, 434, +461, -785, -572, -1612, -1393, -1742, -1393, -1116, +-644, 125, 545, 1269, 1461, 1815, 1602, 1605, +884, 611, -308, -645, -1287, -1572, -1730, -1848, +-1266, -1311, -170, -135, 887, 1067, 1611, 1756, +1484, 1767, 429, 916, -738, -389, -1417, -1424, +-1301, -1861, -448, -1417, 496, -315, 1010, 891, +832, 1724, 137, 1694, -425, 850, -536, -410, +-324, -1518, 67, -1822, 270, -1266, 190, 61, +40, 1412, -143, 1903, -99, 1504, 85, 233, +167, -1201, 198, -1856, 50, -1577, -182, -586, +-349, 679, -296, 1439, 54, 1431, 512, 988, +783, 225, 507, -633, -224, -1163, -930, -1343, +-1183, -1120, -657, -301, 482, 776, 1442, 1577, +1513, 1690, 713, 978, -628, -377, -1635, -1506, +-1637, -1857, -813, -1398, 492, -119, 1501, 1146, +1599, 1791, 922, 1678, -213, 720, -1268, -556, +-1613, -1599, -1280, -1981, -363, -1308, 862, 36, +1552, 1340, 1475, 2058, 794, 1700, -343, 405, +-1341, -991, -1650, -1858, -1276, -1784, -375, -742, +738, 468, 1499, 1372, 1608, 1704, 1018, 1073, +-96, 58, -1204, -841, -1635, -1420, -1352, -1274, +-445, -491, 770, 417, 1436, 1070, 1315, 1153, +640, 589, -239, -101, -866, -593, -983, -766, +-638, -491, -97, -54, 471, 227, 805, 318, +751, 291, 344, 180, -257, -9, -786, -135, +-838, -183, -318, -256, 340, -87, 798, 72, +870, 186, 402, 374, -294, 240, -663, -68, +-683, -221, -347, -395, 10, -446, 91, -151, +282, 180, 383, 393, 276, 469, 247, 414, +121, 178, -245, -153, -506, -412, -460, -595, +-366, -655, -75, -331, 210, 221, 205, 725, +424, 1039, 438, 728, 37, -37, 46, -695, +-187, -1017, -599, -785, -432, -89, -256, 523, +-35, 640, 347, 417, 446, 89, 415, -226, +420, -220, 159, -61, -322, 3, -567, 140, +-606, 134, -472, 73, 140, -27, 763, -346, +874, -533, 582, -427, -48, -39, -636, 586, +-754, 991, -421, 830, 14, 203, 394, -536, +575, -1072, 338, -989, 163, -456, 56, 58, +-180, 641, -252, 1000, -359, 871, -450, 550, +-184, -111, 155, -1010, 404, -1416, 545, -1017, +511, 7, 221, 1144, -220, 1670, -546, 1041, +-776, -283, -709, -1301, -261, -1464, 344, -569, +973, 781, 1036, 1271, 394, 793, -357, -175, +-978, -1146, -1122, -1083, -508, -106, 363, 933, +889, 1383, 794, 788, 312, -409, -173, -1333, +-462, -1470, -429, -588, -271, 730, -170, 1555, +-146, 1350, -64, 267, 287, -904, 663, -1471, +782, -1016, 526, 131, -89, 1084, -722, 1093, +-1261, 291, -1020, -644, -58, -1025, 768, -492, +1462, 537, 1479, 1144, 570, 823, -635, -140, +-1706, -1183, -1917, -1431, -858, -648, 691, 469, +1843, 1364, 2210, 1585, 1239, 736, -612, -487, +-1954, -1352, -2176, -1680, -1246, -1004, 306, 305, +1529, 1413, 1852, 1877, 1096, 1244, -208, -246, +-1066, -1565, -1231, -1975, -775, -1181, 20, 357, +530, 1599, 581, 1733, 313, 713, -8, -625, +-110, -1369, -13, -1043, 41, 12, -139, 934, +-494, 1075, -697, 198, -447, -832, 316, -1226, +1155, -772, 1303, 417, 760, 1436, -419, 1389, +-1506, 388, -1619, -868, -921, -1602, 368, -1191, +1397, 135, 1503, 1314, 904, 1487, -88, 627, +-875, -791, -992, -1650, -691, -1261, -277, -58, +212, 1184, 505, 1716, 705, 1128, 733, -107, +409, -1023, -59, -1432, -685, -1153, -1129, -409, +-896, 358, -149, 1074, 765, 1377, 1384, 1169, +1173, 476, 280, -712, -928, -1668, -1605, -1737, +-1239, -957, -217, 400, 970, 1467, 1536, 1685, +1220, 1074, 231, 61, -971, -711, -1418, -1002, +-1049, -934, -354, -701, 400, -384, 825, 144, +867, 820, 649, 1230, 242, 1161, -160, 490, +-555, -616, -938, -1447, -1007, -1429, -462, -701, +335, 271, 942, 1107, 1210, 1307, 836, 896, +53, 226, -620, -571, -962, -1118, -818, -1149, +-447, -712, -44, 114, 303, 1028, 619, 1411, +928, 921, 854, 1, 580, -877, -90, -1344, +-1090, -980, -1513, -72, -1300, 704, -480, 1104, +827, 986, 1731, 429, 1884, -274, 1209, -904, +-321, -1287, -1606, -1081, -2042, -308, -1667, 702, +-287, 1604, 1261, 1802, 2084, 1050, 1904, -317, +706, -1554, -896, -2122, -1951, -1729, -1998, -456, +-1089, 965, 431, 1952, 1659, 2119, 1809, 1306, +1181, -4, 64, -1308, -1133, -2035, -1526, -1861, +-1156, -943, -297, 396, 629, 1420, 928, 1850, +753, 1581, 337, 626, -210, -492, -447, -1357, +-375, -1763, -266, -1425, -113, -450, 18, 631, +136, 1456, 378, 1679, 510, 1077, 416, 111, +38, -730, -529, -1304, -932, -1287, -862, -796, +-188, -133, 632, 553, 1156, 1114, 1191, 1268, +605, 918, -304, 260, -1100, -602, -1378, -1322, +-961, -1460, -129, -1037, 768, -230, 1330, 844, +1286, 1654, 742, 1827, -210, 1289, -1071, -12, +-1398, -1544, -1203, -2434, -511, -2219, 490, -804, +1231, 1244, 1448, 2613, 1171, 2559, 214, 1194, +-797, -804, -1427, -2188, -1587, -2206, -845, -1114, +296, 346, 1126, 1289, 1495, 1342, 1074, 806, +92, 175, -695, -219, -1177, -387, -1085, -436, +-378, -557, 285, -702, 694, -470, 847, 7, +580, 597, 103, 1069, -223, 1064, -512, 573, +-539, -171, -266, -839, -94, -1194, -10, -1016, +52, -488, 98, 175, 220, 787, 460, 1017, +637, 842, 517, 483, 66, -7, -609, -423, +-1106, -663, -962, -777, -401, -714, 306, -432, +964, 62, 1031, 583, 644, 1034, 94, 1053, +-494, 610, -539, -76, -351, -776, -308, -1166, +-127, -1083, -71, -540, -103, 132, 140, 777, +404, 1151, 553, 1042, 577, 629, 164, -54, +-460, -790, -798, -1126, -810, -1139, -452, -765, +205, -26, 747, 705, 782, 1224, 543, 1350, +123, 971, -392, 85, -606, -894, -623, -1493, +-446, -1535, -3, -822, 372, 292, 503, 1127, +504, 1455, 269, 1153, -153, 357, -388, -364, +-368, -885, -181, -1104, 142, -895, 265, -507, +65, 201, -16, 959, -135, 1258, -205, 1080, +2, 237, 81, -835, 164, -1374, 279, -1206, +225, -304, 93, 785, -74, 1226, -348, 941, +-490, 110, -372, -693, -170, -953, 239, -618, +534, 74, 510, 581, 440, 698, 260, 534, +78, 68, -247, -352, -769, -569, -1115, -757, +-1132, -587, -539, -167, 702, 337, 1947, 993, +2449, 1287, 1660, 992, -142, 216, -2140, -904, +-3372, -1776, -2932, -1912, -1030, -1155, 1567, 288, +3600, 1726, 3828, 2468, 2258, 2090, -413, 713, +-2984, -1074, -4101, -2436, -3151, -2603, -727, -1587, +1959, 99, 3537, 1796, 3312, 2484, 1546, 1986, +-868, 695, -2554, -949, -2856, -1924, -1760, -1813, +72, -960, 1554, 290, 2176, 1273, 1678, 1394, +294, 793, -947, -102, -1536, -817, -1398, -1024, +-462, -602, 584, 130, 1198, 725, 1265, 889, +620, 609, -243, -16, -900, -725, -1256, -981, +-967, -846, -182, -307, 653, 492, 1285, 944, +1324, 993, 687, 688, -336, 31, -1236, -537, +-1538, -775, -992, -790, 38, -602, 870, -230, +1343, 141, 1096, 463, 283, 825, -381, 916, +-867, 702, -876, 193, -473, -555, -101, -1053, +370, -1202, 497, -853, 289, -114, 174, 515, +-40, 941, -149, 1010, 31, 777, 203, 468, +226, 85, 31, -394, -271, -924, -543, -1309, +-615, -1340, -405, -826, -44, 326, 472, 1488, +841, 2118, 957, 1943, 905, 763, 356, -770, +-481, -1998, -1325, -2330, -1817, -1661, -1421, -391, +-422, 995, 919, 1773, 2270, 1840, 2545, 1301, +1540, 286, -109, -573, -1933, -1145, -3013, -1494, +-2621, -1255, -985, -726, 1215, 42, 2992, 966, +3173, 1572, 1769, 1603, -400, 912, -2450, -262, +-3101, -1355, -2078, -1738, -196, -1262, 1668, -191, +2472, 909, 1833, 1398, 440, 1035, -918, 190, +-1616, -619, -1306, -1003, -477, -748, 334, -35, +850, 685, 866, 1028, 454, 832, 75, 76, +-139, -841, -491, -1379, -668, -1291, -602, -524, +-453, 654, 73, 1472, 767, 1526, 1194, 1064, +1212, 137, 592, -748, -574, -1074, -1497, -1188, +-1748, -1050, -1354, -564, -220, -89, 1143, 569, +1907, 1301, 1954, 1500, 1253, 1275, -108, 651, +-1392, -421, -2165, -1290, -2058, -1758, -1062, -1768, +331, -1081, 1670, -23, 2266, 1167, 1890, 2119, +819, 2177, -564, 1494, -1669, 218, -1984, -1246, +-1618, -2102, -792, -2251, 394, -1659, 1289, -480, +1644, 845, 1602, 1949, 986, 2460, -25, 2128, +-893, 852, -1505, -819, -1658, -2163, -1228, -2754, +-461, -2083, 547, -611, 1420, 898, 1777, 2056, +1474, 2322, 714, 1761, -357, 718, -1491, -570, +-1877, -1717, -1539, -2205, -680, -1812, 582, -719, +1446, 778, 1745, 1900, 1384, 2023, 270, 1273, +-802, -83, -1406, -1251, -1472, -1637, -791, -1247, +195, -250, 966, 781, 1236, 1393, 903, 1180, +234, 382, -480, -583, -885, -1443, -838, -1483, +-529, -700, -9, 373, 522, 1384, 713, 1745, +740, 1286, 520, 366, -86, -691, -456, -1477, +-753, -1742, -961, -1436, -619, -670, -56, 488, +608, 1586, 1144, 2132, 1218, 1892, 799, 782, +-87, -623, -1040, -1805, -1543, -2229, -1350, -1665, +-497, -653, 531, 538, 1208, 1498, 1370, 1764, +950, 1529, 153, 751, -573, -364, -960, -1186, +-939, -1512, -521, -1155, 50, -297, 446, 520, +602, 802, 328, 482, -93, 9, -340, -343, +-224, -182, 305, 422, 635, 877, 609, 926, +216, 389, -582, -590, -1121, -1399, -1054, -1753, +-545, -1430, 174, -384, 754, 878, 1117, 1922, +1156, 2357, 855, 1891, 284, 635, -554, -869, +-1265, -2195, -1721, -2767, -1517, -2262, -398, -1030, +843, 771, 1793, 2428, 1952, 3063, 1128, 2575, +-94, 1019, -1173, -1144, -1563, -2668, -1063, -2905, +-123, -1883, 595, -40, 764, 1518, 332, 1993, +-485, 1434, -897, 364, -486, -561, 473, -720, +1516, -258, 1822, 183, 1012, 332, -507, 60, +-2059, -536, -2617, -892, -1852, -794, -238, -277, +1433, 472, 2367, 1021, 2265, 1210, 1178, 855, +-196, 195, -1199, -478, -1627, -960, -1505, -867, +-971, -586, -150, -279, 587, 1, 1003, 63, +1166, 201, 914, 491, 382, 966, -179, 1179, +-733, 706, -811, -95, -506, -1119, -216, -1761, +171, -1500, 285, -638, 122, 477, -71, 1201, +-189, 1343, 68, 1043, 405, 503, 590, 70, +642, -329, 280, -596, -316, -859, -839, -1140, +-1150, -979, -962, -427, -422, 296, 375, 1155, +1219, 1670, 1549, 1447, 1230, 681, 322, -380, +-804, -1312, -1500, -1551, -1398, -1178, -640, -435, +287, 386, 897, 676, 751, 562, 161, 420, +-249, 319, -288, 412, 105, 592, 681, 475, +790, -15, 283, -723, -468, -1310, -1165, -1455, +-1439, -1044, -1024, -101, -39, 945, 981, 1786, +1663, 2045, 1724, 1338, 988, 59, -219, -1262, +-1422, -2188, -1908, -2038, -1409, -910, -299, 457, +868, 1460, 1421, 1623, 1191, 1077, 351, 224, +-539, -453, -803, -644, -550, -570, -105, -437, +373, -306, 456, -257, 261, -47, 98, 275, +-142, 440, -298, 583, -412, 446, -532, 49, +-374, -237, 77, -331, 568, -266, 951, -146, +979, -6, 439, -48, -312, -243, -1003, -349, +-1317, -241, -937, 163, -211, 744, 431, 1122, +1000, 1051, 1166, 439, 630, -687, 71, -1692, +-428, -1965, -791, -1476, -574, -156, -291, 1459, +7, 2371, 329, 2402, 180, 1271, -8, -515, +-44, -1860, -146, -2502, 29, -1981, 203, -614, +336, 765, 491, 1674, 293, 1792, 39, 1231, +-351, 372, -799, -457, -967, -1018, -847, -1079, +-218, -863, 605, -476, 1288, 130, 1649, 515, +1243, 638, 343, 627, -670, 343, -1691, 138, +-1978, -78, -1484, -311, -666, -357, 617, -476, +1769, -400, 2082, -99, 1822, 298, 970, 565, +-489, 482, -1593, 196, -2119, -264, -2012, -567, +-887, -377, 341, 89, 1305, 464, 1872, 533, +1428, 176, 615, -412, -111, -796, -706, -627, +-831, -55, -686, 631, -560, 1003, -440, 700, +-296, 119, -36, -517, 359, -874, 788, -657, +910, -256, 644, 113, 279, 284, -253, 279, +-605, 321, -627, 351, -607, 429, -365, 363, +-107, -52, -6, -519, 183, -913, 409, -907, +532, -441, 555, 288, 468, 925, 283, 1060, +-118, 840, -667, 106, -949, -627, -919, -842, +-522, -804, 235, -295, 921, 298, 1140, 519, +814, 461, 113, 77, -610, -234, -828, -279, +-487, -117, 23, 258, 420, 416, 469, 314, +-7, 15, -469, -418, -531, -602, -379, -528, +200, -276, 772, 179, 709, 586, 413, 723, +-27, 658, -554, 364, -617, -163, -419, -668, +-204, -934, 151, -893, 272, -476, 233, 218, +210, 853, 94, 1205, -22, 994, -111, 300, +-93, -480, -83, -1094, 50, -1129, 212, -606, +63, 142, 18, 731, -62, 794, -295, 518, +-256, 40, -285, -319, -237, -313, 111, -184, +367, 20, 734, 77, 883, -80, 493, -148, +-159, -196, -976, -141, -1347, 144, -1074, 409, +-365, 537, 570, 446, 1179, 35, 1203, -543, +790, -922, 215, -902, -298, -334, -557, 553, +-637, 1134, -658, 1157, -523, 591, -385, -294, +-283, -971, 124, -1104, 584, -731, 891, -123, +1188, 390, 1073, 684, 408, 779, -464, 586, +-1294, 303, -1799, -85, -1563, -555, -692, -838, +286, -840, 1219, -508, 1714, 28, 1626, 619, +1168, 1017, 290, 995, -670, 607, -1371, -69, +-1779, -793, -1644, -1174, -843, -1053, 206, -416, +1069, 399, 1622, 949, 1592, 964, 1037, 499, +351, -72, -502, -508, -1181, -446, -1388, -148, +-1286, 77, -706, 146, 133, -66, 870, -262, +1281, -325, 1099, -162, 536, 174, -228, 414, +-741, 482, -772, 402, -505, 131, 31, -165, +454, -319, 489, -404, 166, -366, -288, -212, +-551, -137, -522, -65, -214, 133, 232, 251, +587, 454, 705, 648, 574, 544, 359, 273, +72, -154, -412, -703, -882, -1050, -1164, -1044, +-1052, -809, -425, -114, 443, 792, 1373, 1450, +1745, 1776, 1315, 1375, 474, 230, -595, -1062, +-1382, -2030, -1609, -2233, -1376, -1346, -567, 20, +311, 1319, 964, 2116, 1420, 1864, 1290, 966, +755, -120, 14, -1107, -666, -1486, -925, -1287, +-961, -791, -689, -85, -222, 467, 123, 789, +358, 899, 456, 762, 466, 459, 406, 72, +291, -347, 159, -704, 67, -745, -69, -555, +-315, -128, -477, 321, -542, 444, -573, 261, +-381, -141, -34, -363, 308, -172, 665, 396, +896, 1002, 992, 1096, 787, 544, 125, -483, +-668, -1538, -1424, -1851, -1770, -1366, -1432, -370, +-489, 891, 856, 1685, 1846, 1794, 2113, 1400, +1733, 582, 571, -343, -812, -1113, -1790, -1571, +-2153, -1607, -1636, -1179, -609, -373, 613, 516, +1583, 1331, 1745, 1749, 1349, 1477, 525, 775, +-418, -234, -952, -1119, -1155, -1415, -990, -1135, +-450, -372, 11, 249, 444, 453, 849, 277, +804, -99, 506, -120, 71, 262, -464, 799, +-728, 1059, -626, 713, -248, -54, 262, -851, +596, -1291, 538, -1188, 232, -721, -122, -184, +-445, 307, -445, 739, -198, 1059, -10, 1235, +141, 1068, 195, 457, 172, -360, 118, -1166, +68, -1544, 90, -1370, 22, -797, -80, -1, +-100, 683, -108, 1186, -65, 1360, -126, 1137, +-349, 639, -404, -128, -182, -913, 192, -1330, +792, -1225, 1185, -667, 854, 143, 150, 748, +-769, 872, -1578, 540, -1570, -12, -835, -409, +172, -373, 1127, 66, 1677, 535, 1487, 838, +793, 637, -139, -119, -1107, -898, -1504, -1458, +-1335, -1506, -767, -822, 229, 218, 1036, 1288, +1261, 2009, 1003, 1956, 355, 1195, -369, -36, +-789, -1288, -772, -2125, -405, -2159, 78, -1424, +362, -293, 459, 925, 369, 1738, -48, 1931, +-395, 1526, -511, 663, -501, -306, -140, -1099, +425, -1505, 874, -1353, 1062, -805, 682, -110, +-235, 508, -1062, 750, -1561, 687, -1472, 474, +-440, 258, 789, 198, 1549, 262, 1769, 231, +1088, 10, -15, -339, -837, -779, -1332, -1050, +-1227, -918, -710, -456, -253, 217, 225, 946, +649, 1373, 910, 1327, 986, 845, 819, 39, +382, -771, -328, -1302, -955, -1379, -1215, -1020, +-1066, -296, -552, 404, 104, 911, 732, 1188, +1085, 1003, 1062, 533, 765, -32, 254, -554, +-276, -866, -771, -842, -1011, -579, -877, -198, +-611, 230, -102, 472, 466, 612, 780, 633, +892, 308, 702, -44, 360, -355, -40, -608, +-417, -441, -604, -84, -671, 258, -590, 436, +-418, 232, -190, -122, 223, -350, 622, -332, +851, -73, 877, 294, 588, 487, 24, 380, +-621, 95, -1028, -211, -1065, -425, -747, -461, +-122, -281, 497, -18, 828, 254, 917, 408, +694, 363, 263, 204, -86, -66, -455, -251, +-716, -274, -730, -209, -612, -80, -212, 13, +332, 82, 798, 191, 886, 250, 536, 233, +-23, 70, -618, -197, -749, -417, -418, -383, +58, -82, 556, 217, 561, 411, 184, 273, +-206, -64, -544, -253, -521, -209, -189, 70, +246, 369, 543, 359, 594, 51, 409, -291, +-71, -580, -473, -538, -611, -166, -566, 153, +-183, 395, 318, 530, 592, 415, 553, 265, +257, 104, -137, -142, -415, -330, -543, -457, +-512, -533, -192, -387, 235, -112, 599, 182, +869, 493, 707, 621, 146, 483, -648, 147, +-1337, -206, -1265, -405, -593, -316, 339, -39, +1249, 173, 1495, 168, 1058, -147, 265, -515, +-581, -582, -1082, -305, -1139, 269, -852, 792, +-250, 950, 473, 736, 833, 172, 819, -406, +518, -751, -93, -817, -458, -632, -319, -255, +41, 141, 394, 348, 352, 373, -126, 290, +-637, 195, -824, 215, -532, 357, 86, 434, +633, 274, 749, -130, 523, -636, 240, -964, +14, -921, -54, -634, -32, -121, -179, 414, +-483, 764, -662, 1025, -620, 1064, -326, 807, +178, 351, 621, -273, 827, -819, 765, -1139, +432, -1253, -33, -1104, -363, -701, -549, -76, +-596, 760, -429, 1616, -257, 2014, -177, 1697, +-44, 676, 150, -633, 345, -1661, 548, -1959, +696, -1505, 550, -691, 183, 94, -174, 602, +-527, 835, -761, 894, -768, 909, -636, 760, +-296, 524, 202, 159, 575, -357, 834, -781, +916, -1048, 628, -1125, 239, -807, -72, -211, +-380, 456, -660, 959, -888, 956, -986, 642, +-744, 177, -179, -81, 555, 7, 1247, 161, +1473, 146, 1115, -226, 425, -821, -336, -1167, +-961, -1008, -1227, -414, -1136, 401, -756, 1039, +-188, 1202, 372, 965, 888, 569, 1119, 54, +907, -323, 489, -528, 0, -618, -451, -556, +-725, -493, -842, -519, -730, -514, -357, -334, +10, 96, 466, 824, 827, 1513, 731, 1650, +413, 1106, -58, 33, -494, -1167, -628, -1806, +-448, -1689, -72, -1005, 307, -58, 527, 661, +386, 962, 20, 977, -410, 730, -757, 435, +-607, 157, -98, -122, 462, -287, 924, -420, +900, -431, 500, -410, -81, -371, -631, -277, +-763, -174, -720, 38, -526, 274, -167, 487, +209, 666, 556, 621, 763, 380, 773, -10, +465, -445, -34, -694, -520, -650, -733, -327, +-577, 66, -272, 278, 65, 174, 268, -84, +235, -269, 78, -149, -3, 282, 35, 726, +249, 896, 432, 636, 365, 15, 128, -677, +-419, -1160, -872, -1226, -847, -832, -474, -105, +252, 706, 913, 1266, 1023, 1364, 623, 836, +-100, -40, -737, -853, -878, -1180, -514, -924, +85, -255, 622, 409, 769, 704, 385, 611, +-152, 223, -616, -179, -859, -410, -569, -456, +34, -307, 658, 32, 978, 345, 766, 591, +226, 569, -423, 197, -860, -301, -799, -697, +-295, -708, 228, -330, 488, 242, 440, 590, +95, 547, -191, 178, -223, -268, 11, -494, +345, -308, 430, 69, 268, 404, -114, 511, +-535, 267, -693, -104, -585, -394, -197, -472, +239, -323, 463, -58, 667, 122, 698, 215, +474, 282, 151, 259, -290, 210, -700, 82, +-947, -202, -862, -442, -324, -451, 305, -168, +720, 342, 896, 745, 625, 704, 130, 167, +-241, -582, -482, -1091, -433, -1014, -229, -391, +-9, 453, 232, 1085, 335, 1202, 199, 839, +-81, 192, -402, -521, -664, -968, -526, -1101, +-54, -858, 560, -233, 1078, 432, 1019, 892, +524, 936, -137, 530, -866, -70, -1174, -502, +-920, -552, -439, -244, 102, 179, 527, 438, +683, 390, 659, 83, 506, -358, 248, -698, +86, -771, -83, -548, -344, -3, -471, 604, +-584, 1076, -609, 1167, -447, 758, -168, 107, +270, -575, 734, -935, 1035, -960, 985, -732, +633, -393, -108, -142, -869, 70, -1193, 335, +-1152, 643, -589, 897, 156, 994, 621, 800, +811, 285, 668, -381, 320, -971, 84, -1302, +-69, -1225, -208, -797, -286, -208, -340, 438, +-280, 862, -119, 1073, 73, 1117, 130, 929, +88, 552, 25, 22, -43, -645, 52, -1189, +176, -1421, 186, -1244, 81, -692, -59, 33, +-105, 687, -21, 1132, 64, 1321, 85, 1182, +-97, 778, -398, 105, -453, -646, -283, -1144, +164, -1293, 631, -906, 740, -289, 567, 224, +77, 451, -426, 353, -675, 149, -656, 103, +-327, 325, 19, 652, 265, 869, 462, 782, +422, 262, 245, -547, 23, -1329, -196, -1820, +-285, -1661, -284, -781, -125, 443, 134, 1625, +287, 2213, 227, 1924, 41, 937, -183, -268, +-361, -1250, -301, -1621, -54, -1402, 196, -839, +396, -166, 391, 343, 177, 608, -38, 667, +-283, 574, -471, 404, -405, 305, -204, 254, +98, 207, 463, 83, 690, -193, 578, -544, +187, -875, -276, -997, -689, -792, -857, -310, +-641, 343, -241, 996, 213, 1396, 609, 1372, +805, 897, 813, 82, 597, -781, 114, -1313, +-486, -1399, -815, -1039, -915, -415, -702, 148, +-159, 543, 257, 819, 578, 947, 632, 912, +406, 689, 240, 156, -17, -489, -274, -988, +-283, -1118, -156, -759, 46, -97, 289, 448, +245, 688, -100, 532, -468, 135, -720, -208, +-595, -259, -7, -101, 519, 160, 819, 370, +885, 306, 492, 86, 98, -180, -187, -359, +-555, -368, -741, -223, -798, -116, -678, -60, +-224, -38, 394, -32, 822, 151, 930, 392, +693, 598, 148, 558, -199, 273, -370, -192, +-474, -565, -323, -691, -251, -554, -178, -270, +37, -19, 121, 134, 121, 247, -15, 375, +-203, 470, -182, 486, 84, 310, 482, -87, +793, -432, 760, -584, 310, -445, -321, -35, +-832, 323, -1069, 429, -957, 262, -624, -126, +-139, -453, 448, -535, 871, -340, 1131, 41, +1128, 415, 695, 636, 80, 660, -535, 482, +-956, 203, -1051, -106, -870, -434, -525, -744, +-108, -909, 319, -866, 622, -516, 766, 114, +769, 799, 535, 1220, 106, 1244, -169, 757, +-323, 54, -387, -503, -286, -766, -243, -698, +-351, -476, -422, -331, -358, -401, -160, -418, +300, -278, 752, 120, 943, 776, 797, 1288, +261, 1365, -267, 953, -606, 70, -691, -858, +-521, -1406, -294, -1463, -117, -982, -61, -268, +-6, 370, 194, 719, 408, 804, 495, 711, +400, 522, 182, 331, 45, 60, -65, -227, +-73, -453, -72, -565, -348, -448, -644, -227, +-760, -3, -545, 157, 62, 157, 706, 116, +1099, 53, 1026, -21, 465, -56, -220, 13, +-663, 115, -803, 335, -634, 475, -279, 355, +46, 19, 271, -443, 365, -784, 356, -721, +286, -341, 171, 119, -54, 497, -264, 491, +-300, 320, -320, 130, -162, -27, 112, -9, +275, 11, 363, 7, 242, 23, 58, 20, +-113, -11, -232, -139, -236, -366, -232, -534, +-123, -516, -10, -120, 66, 408, 220, 853, +268, 918, 202, 572, 96, 10, -66, -482, +-119, -684, -54, -631, -50, -410, -108, -187, +-196, 52, -284, 246, -214, 405, 60, 483, +339, 376, 523, 132, 399, -148, 83, -346, +-146, -392, -355, -247, -374, -63, -239, 139, +-126, 275, 11, 293, 128, 222, 218, 50, +323, -156, 224, -351, -18, -447, -131, -395, +-202, -199, -121, 143, 28, 483, 63, 718, +35, 697, -113, 377, -182, -102, -90, -536, +46, -746, 193, -612, 234, -285, 194, -17, +110, 144, -66, 175, -156, 158, -246, 249, +-330, 382, -194, 397, 48, 295, 260, 53, +389, -193, 329, -315, 70, -343, -86, -325, +-168, -317, -231, -270, -92, -145, -88, 67, +-203, 301, -131, 421, -1, 415, 171, 358, +385, 275, 372, 208, 118, 26, -130, -324, +-315, -697, -340, -890, -70, -688, 188, -119, +272, 513, 249, 897, -76, 854, -378, 443, +-498, -13, -455, -372, -98, -524, 322, -498, +645, -409, 734, -162, 560, 230, 195, 568, +-229, 722, -543, 495, -725, -91, -691, -703, +-474, -975, -126, -760, 266, -147, 595, 539, +708, 919, 627, 857, 362, 445, -22, -93, +-308, -516, -502, -616, -497, -487, -326, -174, +-76, 164, 205, 283, 343, 230, 191, 11, +-76, -185, -225, -219, -272, -38, -14, 179, +385, 323, 550, 287, 445, 37, 60, -185, +-402, -279, -614, -196, -537, 41, -312, 254, +-11, 297, 265, 152, 441, -169, 533, -445, +552, -535, 276, -388, -231, -29, -690, 305, +-934, 485, -671, 479, -70, 362, 552, 264, +917, 217, 780, 104, 324, -180, -154, -591, +-386, -917, -430, -949, -392, -503, -305, 183, +-282, 765, -146, 1041, 114, 843, 384, 451, +591, 35, 529, -299, 218, -459, -149, -556, +-388, -550, -389, -336, -178, -12, 50, 271, +130, 428, 51, 294, -207, 6, -401, -157, +-297, -153, -11, 0, 404, 181, 782, 202, +777, 94, 481, -2, -27, -54, -583, -53, +-837, -77, -824, -144, -569, -239, -154, -228, +241, -52, 505, 110, 609, 236, 540, 225, +351, 79, 176, 3, -27, -10, -121, 47, +-157, 124, -258, 118, -377, 40, -501, -87, +-493, -250, -383, -393, -83, -436, 342, -295, +645, 9, 814, 372, 771, 636, 459, 625, +59, 363, -374, -6, -748, -292, -837, -391, +-718, -360, -403, -273, 9, -220, 301, -161, +493, -31, 554, 164, 463, 337, 343, 374, +245, 251, 78, 68, -70, -26, -270, -20, +-509, 44, -543, 49, -507, -137, -370, -402, +-48, -584, 277, -554, 521, -238, 623, 253, +556, 698, 406, 913, 148, 804, -156, 386, +-359, -154, -511, -603, -568, -844, -431, -768, +-201, -461, 56, -91, 254, 229, 288, 410, +244, 402, 228, 295, 191, 221, 202, 139, +262, 125, 145, 116, -65, 50, -246, -30, +-421, -116, -463, -202, -420, -279, -335, -367, +-147, -505, 79, -520, 331, -354, 629, 65, +791, 660, 655, 1082, 238, 1118, -307, 656, +-747, -99, -903, -711, -636, -837, -114, -494, +390, 29, 659, 302, 520, 112, 130, -411, +-244, -863, -442, -867, -353, -354, -40, 467, +269, 1181, 441, 1480, 392, 1270, 182, 633, +-52, -162, -299, -869, -444, -1331, -441, -1370, +-264, -979, 26, -282, 312, 489, 521, 979, +463, 1006, 213, 591, -87, -60, -335, -570, +-393, -638, -325, -279, -214, 314, -60, 807, +133, 880, 286, 474, 399, -236, 446, -926, +232, -1257, -87, -1075, -334, -469, -459, 319, +-319, 954, -112, 1155, 33, 921, 124, 394, +63, -210, 19, -605, 56, -690, 69, -516, +79, -206, 88, 38, 98, 139, 175, 166, +260, 153, 198, 190, -59, 260, -416, 249, +-752, 105, -762, -135, -347, -346, 189, -398, +734, -253, 977, -39, 745, 157, 306, 189, +-238, 104, -644, 65, -670, 77, -523, 159, +-250, 189, 127, 95, 281, -71, 310, -210, +295, -218, 168, -108, 105, 0, 64, -3, +-58, -108, -155, -182, -187, -129, -223, 61, +-123, 322, 42, 445, 122, 379, 119, 194, +-1, -41, -101, -243, -143, -418, -61, -562, +80, -609, 214, -447, 372, -15, 341, 622, +163, 1163, -82, 1270, -458, 823, -695, -69, +-606, -971, -284, -1442, 238, -1335, 659, -714, +693, 43, 434, 551, -11, 726, -373, 628, +-373, 504, -137, 489, 84, 551, 203, 530, +113, 216, -96, -316, -233, -924, -287, -1298, +-168, -1224, 52, -764, 182, -63, 253, 624, +272, 1026, 152, 1106, -45, 928, -198, 524, +-274, 81, -168, -319, 46, -582, 202, -669, +282, -593, 201, -408, -14, -186, -182, 19, +-236, 155, -240, 299, -191, 387, -59, 378, +64, 307, 186, 124, 307, -124, 280, -312, +117, -398, -72, -341, -260, -116, -261, 191, +-46, 432, 105, 535, 198, 365, 141, -85, +-96, -517, -208, -791, -241, -715, -171, -236, +44, 340, 145, 780, 173, 882, 213, 631, +185, 226, 188, -212, 131, -559, -61, -736, +-266, -776, -470, -618, -526, -232, -345, 268, +24, 718, 434, 905, 687, 736, 676, 350, +415, -48, 42, -273, -342, -289, -562, -200, +-593, -230, -495, -429, -310, -674, -60, -798, +242, -592, 490, -23, 622, 744, 554, 1394, +282, 1617, -89, 1242, -390, 403, -449, -615, +-277, -1400, -45, -1648, 140, -1308, 175, -621, +-25, 128, -261, 699, -397, 914, -347, 864, +-45, 595, 339, 266, 620, -10, 720, -206, +555, -261, 86, -211, -281, -162, -469, -152, +-563, -181, -420, -238, -347, -244, -342, -179, +-210, -36, 30, 171, 458, 398, 886, 561, +990, 588, 651, 355, -22, -141, -712, -681, +-1042, -987, -868, -827, -366, -200, 160, 602, +477, 1143, 514, 1141, 407, 567, 258, -240, +128, -873, -30, -1160, -247, -981, -400, -479, +-452, 116, -267, 665, 53, 1046, 333, 1078, +490, 738, 356, 148, 88, -538, -193, -962, +-364, -1000, -355, -695, -227, -145, 30, 350, +236, 588, 366, 598, 340, 400, 165, 120, +-43, -91, -310, -198, -389, -167, -271, -83, +-90, 8, 135, 1, 251, -48, 181, -141, +35, -244, -127, -183, -212, -92, -50, 41, +156, 238, 309, 344, 413, 386, 262, 358, +-20, 197, -288, -4, -524, -232, -578, -457, +-465, -598, -248, -603, 111, -443, 483, -82, +713, 429, 719, 852, 509, 945, 84, 630, +-380, 22, -604, -584, -643, -808, -454, -605, +-114, -127, 162, 305, 366, 423, 441, 270, +311, 4, 58, -197, -177, -283, -402, -268, +-393, -212, -115, -107, 212, 152, 519, 491, +542, 738, 272, 684, -84, 258, -423, -348, +-587, -858, -468, -982, -233, -703, 4, -178, +277, 336, 383, 668, 417, 750, 379, 579, +177, 268, -5, -129, -242, -437, -424, -527, +-461, -388, -399, -83, -161, 196, 150, 261, +447, 146, 605, -47, 522, -187, 198, -187, +-225, -100, -526, 20, -613, 145, -383, 252, +8, 347, 324, 373, 481, 186, 341, -137, +25, -451, -282, -616, -420, -467, -282, -110, +22, 223, 406, 396, 562, 341, 399, 134, +33, -48, -429, -158, -603, -222, -478, -150, +-147, 34, 229, 284, 391, 568, 364, 618, +175, 321, 48, -259, -65, -897, -187, -1210, +-240, -1029, -301, -413, -181, 375, 85, 1012, +386, 1271, 538, 1094, 399, 637, 24, 5, +-402, -588, -573, -955, -507, -1022, -214, -734, +128, -262, 330, 206, 399, 495, 296, 566, +153, 435, -54, 247, -280, 83, -352, -67, +-237, -151, 48, -134, 356, -26, 516, 95, +382, 149, -59, 3, -547, -293, -806, -559, +-670, -603, -176, -297, 416, 250, 862, 727, +942, 913, 572, 695, -45, 177, -565, -350, +-835, -670, -753, -665, -336, -407, 96, -54, +448, 203, 569, 293, 467, 197, 347, 35, +104, -31, -201, -26, -480, 41, -638, 112, +-568, 57, -200, 8, 380, 13, 792, 53, +851, 149, 423, 96, -249, -135, -733, -400, +-861, -537, -498, -379, 104, 42, 568, 472, +679, 658, 445, 507, 18, 128, -360, -251, +-471, -441, -391, -390, -96, -196, 200, 40, +317, 232, 351, 308, 193, 286, -7, 135, +-214, -111, -371, -315, -328, -451, -238, -380, +3, -165, 278, 93, 433, 335, 493, 453, +304, 447, -1, 315, -297, 104, -478, -129, +-460, -300, -293, -336, -19, -245, 185, -116, +303, -81, 302, -146, 193, -241, 77, -238, +-57, -11, -100, 339, -88, 669, -5, 767, +65, 553, 12, 136, -30, -359, -152, -698, +-232, -794, -175, -608, -62, -212, 127, 205, +247, 504, 285, 563, 253, 348, 125, 22, +-84, -246, -299, -349, -400, -239, -359, -17, +-140, 177, 204, 308, 510, 334, 594, 230, +346, 68, -69, -168, -474, -401, -685, -495, +-568, -391, -226, -163, 197, 119, 527, 335, +597, 401, 450, 389, 214, 300, -121, 127, +-379, -103, -443, -412, -395, -622, -172, -535, +77, -164, 271, 355, 349, 715, 244, 673, +69, 257, -112, -228, -169, -512, -158, -422, +-90, -94, 41, 112, 89, 110, 65, -79, +14, -304, -45, -280, -97, 4, -106, 343, +-47, 575, 89, 547, 244, 278, 309, -82, +232, -363, 19, -501, -236, -435, -459, -248, +-501, -41, -295, 122, -46, 179, 220, 140, +436, 95, 465, 132, 463, 196, 308, 258, +-9, 182, -286, -45, -594, -313, -677, -506, +-453, -442, -100, -155, 334, 164, 573, 394, +532, 421, 339, 283, 73, 109, -143, -29, +-225, -98, -258, -186, -281, -297, -227, -402, +-149, -385, -12, -195, 139, 132, 245, 479, +271, 675, 223, 616, 176, 324, 18, -48, +-120, -394, -201, -615, -282, -626, -185, -467, +-44, -207, 72, 91, 159, 346, 85, 510, +-35, 507, -69, 365, -32, 134, 51, -124, +105, -288, 64, -322, 18, -230, 17, -44, +70, 75, 182, 73, 177, -5, -2, -165, +-256, -281, -495, -222, -548, -25, -361, 230, +-19, 469, 366, 543, 640, 443, 713, 167, +556, -170, 214, -451, -242, -610, -644, -583, +-817, -382, -718, -40, -311, 288, 216, 551, +657, 640, 835, 477, 620, 141, 146, -265, +-386, -596, -734, -649, -738, -420, -354, -36, +192, 399, 619, 667, 731, 613, 428, 353, +-37, -42, -477, -459, -651, -670, -442, -657, +-62, -366, 347, 86, 575, 504, 543, 693, +237, 521, -222, 79, -568, -389, -719, -561, +-534, -342, -74, 106, 413, 483, 743, 495, +697, 109, 353, -389, -48, -663, -346, -530, +-446, -64, -370, 427, -210, 682, -111, 627, +-22, 286, 80, -92, 189, -398, 287, -606, +215, -636, 50, -518, -136, -207, -284, 236, +-270, 646, -83, 877, 148, 801, 319, 419, +408, -104, 315, -576, 77, -790, -240, -742, +-543, -464, -661, -69, -520, 251, -149, 423, +296, 421, 666, 303, 745, 132, 498, 26, +111, -23, -324, -30, -596, -32, -567, -62, +-331, -92, 39, -132, 386, -168, 500, -190, +348, -175, 24, -59, -308, 126, -464, 332, +-323, 464, -46, 356, 224, 58, 372, -307, +220, -551, -30, -536, -198, -261, -236, 118, +-80, 441, 153, 578, 301, 468, 282, 204, +98, -171, -195, -487, -359, -585, -363, -427, +-252, -35, 32, 380, 202, 574, 204, 407, +101, -20, -45, -455, -51, -623, 60, -354, +211, 129, 294, 564, 201, 718, -94, 487, +-363, 34, -446, -401, -342, -638, -68, -578, +156, -270, 271, 100, 232, 396, 60, 444, +-68, 220, -96, -129, -16, -404, 63, -413, +134, -70, 163, 408, 26, 740, -93, 698, +-190, 220, -260, -415, -149, -874, -28, -918, +81, -548, 179, 57, 148, 520, 57, 665, +-25, 524, -66, 208, -64, -36, 25, -98, +70, -53, 54, -30, 10, -126, -125, -350, +-180, -523, -189, -452, -79, -115, 112, 376, +227, 789, 291, 849, 172, 548, 5, 26, +-139, -453, -230, -693, -189, -691, -147, -515, +-102, -317, -105, -99, -107, 160, -17, 471, +167, 785, 421, 896, 559, 699, 451, 189, +79, -455, -401, -954, -760, -1114, -809, -830, +-452, -248, 92, 397, 551, 834, 698, 920, +460, 631, 20, 119, -336, -349, -428, -586, +-243, -504, 110, -214, 345, 90, 319, 213, +125, 128, -150, -60, -349, -171, -344, -107, +-242, 112, -91, 377, 65, 508, 136, 428, +232, 155, 321, -260, 292, -643, 157, -845, +-49, -811, -295, -432, -408, 138, -312, 690, +-145, 1044, 78, 1017, 200, 623, 172, 38, +146, -492, 119, -790, 88, -775, 35, -502, +-93, -153, -285, 140, -370, 279, -284, 230, +-5, 138, 321, 83, 482, 115, 420, 241, +108, 322, -238, 264, -456, 37, -449, -290, +-232, -534, 42, -582, 261, -424, 314, -94, +237, 254, 54, 462, -100, 527, -168, 431, +-174, 225, -71, -2, 45, -192, 105, -301, +90, -355, 13, -358, -92, -364, -189, -311, +-219, -140, -159, 151, 19, 548, 297, 866, +471, 895, 476, 546, 274, -71, -178, -737, +-584, -1140, -781, -1094, -667, -653, -242, -11, +247, 570, 608, 898, 695, 914, 548, 637, +257, 214, -44, -199, -299, -489, -476, -586, +-490, -492, -396, -274, -174, -51, 80, 125, +256, 194, 319, 184, 208, 130, 45, 28, +-47, -28, -18, 21, 82, 169, 152, 358, +130, 452, -44, 284, -291, -175, -466, -738, +-482, -1108, -286, -1012, 83, -405, 426, 462, +625, 1195, 602, 1433, 297, 1087, -102, 343, +-457, -461, -666, -1013, -583, -1175, -300, -943, +55, -454, 402, 88, 549, 554, 421, 818, +139, 814, -179, 555, -341, 178, -280, -164, +-99, -406, 110, -468, 173, -444, 47, -387, +-125, -287, -199, -129, -108, 128, 25, 436, +94, 658, 71, 643, -44, 377, -102, -75, +-10, -500, 186, -677, 359, -575, 322, -255, +57, 104, -313, 313, -629, 341, -715, 218, +-479, 76, 6, 35, 514, 77, 853, 131, +837, 110, 439, -37, -167, -277, -718, -460, +-895, -466, -655, -265, -138, 74, 382, 415, +626, 601, 515, 579, 126, 370, -240, 19, +-410, -331, -335, -592, -48, -693, 207, -526, +326, -141, 235, 331, -50, 686, -303, 743, +-401, 460, -288, -43, 17, -474, 330, -624, +447, -442, 304, -60, 8, 302, -285, 456, +-404, 349, -325, 68, -153, -245, 22, -453, +124, -467, 191, -272, 234, 77, 262, 471, +236, 717, 41, 680, -214, 339, -434, -185, +-516, -677, -334, -886, -34, -738, 234, -324, +398, 185, 385, 582, 241, 756, 53, 667, +-106, 358, -184, -67, -225, -461, -235, -663, +-204, -580, -135, -213, -38, 266, 46, 593, +118, 589, 170, 224, 194, -266, 166, -601, +115, -582, 58, -207, -81, 257, -223, 543, +-329, 497, -363, 181, -234, -193, -19, -398, +216, -340, 376, -104, 342, 155, 174, 300, +-27, 282, -146, 139, -167, -59, -156, -243, +-130, -371, -140, -374, -110, -241, -27, 23, +86, 350, 190, 568, 156, 568, 27, 306, +-122, -95, -166, -453, -74, -612, 70, -503, +155, -224, 77, 98, -66, 346, -183, 432, +-180, 380, -48, 228, 111, 5, 204, -202, +126, -311, -68, -296, -271, -154, -379, 45, +-258, 150, 25, 113, 354, -23, 585, -152, +508, -164, 172, -11, -287, 227, -648, 395, +-688, 418, -429, 244, -35, -65, 274, -362, +405, -554, 340, -553, 219, -369, 135, -80, +68, 246, 15, 467, -141, 549, -326, 482, +-433, 286, -390, 27, -186, -221, 69, -414, +285, -501, 365, -429, 312, -240, 178, 25, +24, 271, -88, 394, -175, 378, -241, 272, +-214, 134, -173, 9, -123, -102, -33, -229, +18, -369, 63, -456, 93, -400, 104, -149, +166, 237, 251, 595, 235, 773, 123, 639, +-88, 248, -394, -250, -598, -663, -606, -828, +-376, -694, 57, -340, 470, 92, 672, 459, +645, 619, 387, 580, 7, 415, -321, 187, +-549, -17, -588, -197, -438, -358, -157, -485, +124, -532, 329, -422, 384, -160, 230, 197, +55, 511, -94, 647, -163, 578, -107, 336, +-60, 15, -18, -269, 25, -461, 20, -554, +17, -524, -13, -355, -109, -67, -197, 262, +-206, 539, -81, 643, 122, 514, 274, 221, +275, -120, 127, -392, -76, -477, -236, -385, +-240, -218, -160, -22, -31, 102, 58, 129, +73, 116, 88, 88, 42, 81, -2, 123, +-55, 174, -119, 195, -116, 153, -39, 15, +74, -179, 116, -360, 50, -461, -72, -399, +-162, -169, -156, 150, -49, 462, 108, 625, +234, 547, 218, 252, 60, -144, -145, -504, +-304, -677, -354, -574, -271, -270, -69, 144, +152, 505, 325, 631, 357, 490, 262, 161, +98, -200, -139, -406, -310, -359, -406, -147, +-410, 75, -230, 163, 49, 52, 333, -134, +535, -258, 499, -202, 212, 5, -184, 242, +-539, 390, -688, 373, -537, 221, -180, 18, +216, -164, 541, -290, 629, -329, 449, -276, +141, -138, -217, 62, -474, 221, -502, 260, +-319, 167, -44, -30, 169, -199, 175, -217, +21, -85, -114, 121, -181, 290, -89, 315, +132, 171, 326, -32, 413, -217, 315, -292, +71, -236, -213, -130, -475, -17, -605, 52, +-525, 62, -262, 67, 112, 69, 426, 79, +540, 102, 410, 100, 136, 78, -119, 50, +-265, 3, -243, -67, -122, -143, 21, -202, +88, -202, 50, -106, -47, 45, -185, 180, +-274, 228, -266, 154, -113, 13, 148, -94, +366, -90, 445, -7, 316, 72, 19, 62, +-261, -53, -403, -179, -367, -213, -193, -104, +-24, 69, 94, 217, 140, 264, 125, 196, +91, 84, 57, -13, 27, -114, -26, -230, +-46, -314, -72, -339, -105, -204, -114, 104, +-106, 425, -61, 598, -10, 490, 47, 109, +63, -343, 45, -617, 8, -576, -19, -241, +45, 199, 121, 485, 102, 484, 12, 248, +-135, -83, -266, -325, -299, -350, -255, -203, +-99, -3, 79, 153, 197, 194, 268, 135, +290, 56, 251, -10, 106, -30, -93, -34, +-298, -49, -422, -63, -399, -82, -223, -68, +54, -7, 292, 62, 391, 129, 287, 155, +20, 97, -283, -23, -443, -160, -344, -255, +-38, -215, 323, -38, 504, 184, 386, 317, +76, 290, -301, 96, -514, -138, -427, -259, +-204, -215, 62, -44, 219, 104, 165, 134, +66, 57, 16, -77, 9, -164, 61, -139, +97, -78, 46, 11, -30, 148, -135, 258, +-208, 370, -159, 383, -62, 171, 39, -199, +96, -596, 67, -810, -29, -653, -119, -170, +-143, 393, -87, 768, 37, 796, 160, 497, +217, 92, 175, -208, 74, -336, -56, -327, +-173, -290, -290, -292, -373, -301, -318, -227, +-129, -26, 151, 260, 396, 506, 474, 574, +348, 420, 40, 90, -285, -246, -419, -441, +-345, -437, -132, -238, 90, 29, 175, 202, +147, 230, 16, 111, -129, -89, -177, -226, +-135, -235, -25, -117, 136, 100, 277, 307, +299, 386, 206, 327, -41, 147, -329, -94, +-499, -277, -506, -345, -284, -300, 61, -187, +374, -74, 526, -7, 430, 31, 158, 62, +-136, 119, -311, 217, -309, 298, -175, 337, +-1, 302, 62, 149, -25, -89, -166, -364, +-250, -614, -124, -698, 144, -541, 372, -189, +470, 277, 340, 685, 10, 842, -307, 737, +-478, 408, -484, -39, -308, -432, -113, -698, +36, -764, 213, -590, 330, -225, 405, 215, +422, 573, 263, 688, -40, 505, -365, 138, +-605, -199, -646, -344, -455, -286, -122, -131, +227, -25, 482, -38, 562, -98, 454, -64, +256, 92, 0, 266, -232, 334, -360, 208, +-401, -62, -351, -271, -243, -328, -116, -238, +14, -61, 163, 53, 277, 84, 338, 108, +321, 154, 173, 210, -24, 231, -213, 136, +-350, -53, -350, -240, -219, -349, -54, -308, +111, -174, 185, -3, 174, 159, 132, 261, +39, 292, -50, 237, -133, 98, -171, -71, +-156, -192, -92, -215, 15, -160, 109, -85, +174, -40, 159, -37, 84, 8, -1, 138, +-62, 285, -119, 360, -181, 235, -238, -86, +-255, -414, -146, -568, 36, -438, 233, -77, +375, 305, 337, 505, 131, 453, -116, 214, +-271, -58, -242, -219, -117, -221, -19, -106, +0, 1, -97, 22, -176, -60, -139, -195, +40, -245, 292, -138, 411, 108, 346, 363, +125, 469, -194, 343, -455, 26, -520, -276, +-416, -408, -149, -338, 181, -110, 408, 95, +513, 167, 418, 151, 128, 87, -192, 27, +-406, 8, -441, -30, -298, -83, -83, -119, +95, -117, 183, -44, 179, 63, 129, 157, +57, 219, 5, 217, -52, 149, -106, -3, +-122, -236, -92, -449, -12, -504, 59, -306, +100, 105, 85, 547, 40, 760, -20, 590, +-102, 110, -183, -446, -224, -794, -185, -739, +-41, -336, 184, 199, 337, 633, 339, 756, +157, 538, -142, 114, -348, -333, -330, -602, +-104, -589, 179, -348, 301, -8, 147, 253, +-145, 358, -408, 339, -443, 252, -173, 158, +210, 44, 498, -121, 519, -303, 275, -402, +-56, -343, -309, -107, -390, 194, -286, 360, +-130, 323, -55, 142, -26, -61, 3, -148, +87, -85, 222, 26, 300, 86, 262, 60, +106, -58, -160, -191, -396, -265, -462, -270, +-342, -163, -75, 58, 225, 312, 448, 511, +489, 541, 320, 341, -13, -13, -358, -376, +-504, -584, -425, -566, -156, -381, 180, -113, +340, 146, 280, 325, 93, 428, -122, 422, +-169, 287, -38, 76, 88, -142, 154, -282, +75, -284, -126, -182, -252, -83, -244, -32, +-117, -27, 113, -34, 277, 18, 294, 116, +184, 199, -46, 223, -255, 171, -344, 51, +-279, -89, -66, -219, 158, -302, 249, -283, +193, -163, 52, 47, -77, 274, -79, 380, +23, 325, 115, 144, 99, -91, -46, -247, +-248, -290, -326, -254, -229, -172, -55, -89, +163, -5, 276, 109, 245, 242, 193, 332, +109, 342, 16, 242, -56, 14, -181, -266, +-315, -493, -327, -586, -217, -454, 35, -99, +324, 344, 455, 677, 379, 713, 118, 423, +-221, -45, -466, -459, -456, -632, -198, -518, +164, -224, 433, 82, 452, 274, 214, 329, +-121, 276, -361, 140, -370, -30, -124, -158, +169, -194, 327, -110, 250, 58, -18, 164, +-295, 115, -400, -70, -250, -273, 69, -319, +401, -140, 512, 146, 343, 363, -9, 351, +-388, 115, -550, -176, -422, -350, -104, -304, +248, -85, 435, 162, 363, 319, 135, 320, +-101, 171, -213, -55, -173, -275, -56, -404, +43, -391, 47, -212, -42, 47, -146, 253, +-144, 353, -24, 321, 138, 198, 287, 81, +343, -3, 242, -88, 22, -199, -214, -327, +-368, -393, -324, -333, -157, -124, 39, 166, +192, 412, 188, 510, 117, 392, 70, 127, +76, -163, 119, -388, 114, -470, 1, -375, +-163, -161, -268, 91, -223, 318, -26, 440, +181, 404, 273, 195, 178, -119, -24, -421, +-195, -584, -246, -487, -127, -136, 43, 298, +159, 591, 198, 556, 155, 222, 91, -187, +55, -441, -3, -392, -75, -119, -177, 118, +-289, 136, -278, -40, -144, -220, 82, -205, +321, 48, 432, 371, 382, 507, 193, 325, +-75, -61, -278, -412, -326, -523, -266, -370, +-113, -115, 32, 67, 115, 93, 179, 41, +205, 44, 206, 171, 177, 352, 67, 429, +-71, 283, -184, -58, -246, -463, -151, -717, +37, -663, 194, -337, 267, 123, 212, 500, +69, 626, -95, 462, -205, 110, -211, -225, +-112, -389, 54, -337, 190, -127, 261, 113, +258, 240, 138, 193, -39, 6, -187, -229, +-285, -383, -254, -371, -108, -178, 67, 127, +236, 403, 294, 509, 214, 402, 79, 148, +-75, -160, -155, -399, -111, -486, -31, -454, +62, -330, 87, -124, 19, 133, -72, 394, +-114, 555, -46, 510, 78, 246, 220, -139, +283, -465, 220, -570, 92, -423, -70, -137, +-199, 115, -220, 227, -170, 190, -83, 77, +63, -15, 178, -46, 236, -16, 233, 40, +150, 96, 71, 113, 45, 35, 37, -109, +28, -266, 5, -356, -84, -290, -178, -78, +-252, 165, -255, 302, -120, 267, 82, 107, +325, -41, 526, -86, 592, -41, 483, 4, +206, -33, -204, -158, -608, -277, -809, -285, +-750, -169, -375, 16, 183, 177, 677, 266, +922, 264, 798, 194, 391, 77, -88, -78, +-430, -250, -528, -366, -402, -348, -177, -203, +9, 18, 90, 205, 110, 249, 116, 155, +155, -13, 235, -157, 259, -177, 246, -87, +168, 58, 31, 188, -86, 218, -180, 99, +-230, -134, -227, -366, -142, -481, 46, -396, +266, -131, 400, 190, 388, 400, 217, 418, +14, 270, -96, 67, -116, -84, -38, -168, +35, -218, -17, -282, -103, -333, -132, -312, +-36, -167, 190, 91, 369, 319, 384, 387, +196, 268, -103, 0, -299, -265, -303, -363, +-88, -257, 205, -14, 353, 212, 283, 287, +45, 167, -202, -98, -280, -344, -143, -432, +79, -318, 274, -77, 321, 147, 188, 239, +4, 181, -105, 62, -92, -8, 20, 12, +139, 71, 161, 82, 64, -8, -93, -162, +-179, -306, -137, -376, 32, -329, 237, -205, +376, -45, 413, 142, 287, 307, 97, 395, +-102, 368, -252, 221, -268, -12, -195, -251, +-60, -413, 103, -476, 222, -442, 290, -327, +360, -144, 367, 107, 303, 368, 166, 509, +-92, 443, -325, 170, -427, -189, -343, -426, +-87, -424, 191, -220, 391, 4, 460, 83, +364, 1, 195, -152, 23, -215, -104, -107, +-148, 93, -162, 252, -116, 267, -30, 121, +69, -98, 160, -287, 170, -382, 161, -349, +122, -192, 73, 48, 59, 299, 19, 454, +-31, 403, -44, 110, -7, -301, 110, -643, +257, -755, 297, -556, 190, -128, -22, 325, +-224, 617, -248, 660, -82, 472, 174, 141, +403, -216, 429, -490, 246, -627, 6, -594, +-173, -405, -197, -133, -36, 138, 190, 328, +331, 379, 344, 307, 178, 172, -63, 23, +-199, -95, -203, -161, -94, -195, 84, -239, +248, -278, 330, -289, 319, -249, 230, -122, +110, 54, -8, 206, -92, 266, -128, 213, +-129, 100, -69, -14, 23, -89, 117, -133, +175, -192, 206, -266, 198, -315, 135, -273, +117, -101, 72, 126, 29, 281, 39, 267, +6, 88, -21, -161, -8, -329, -22, -306, +-24, -128, 41, 72, 132, 191, 271, 179, +360, 57, 327, -90, 204, -200, 2, -240, +-155, -225, -201, -201, -131, -164, 19, -100, +151, -5, 240, 106, 299, 212, 279, 260, +221, 208, 159, 52, 93, -138, 61, -292, +4, -371, -60, -344, -106, -263, -154, -178, +-102, -102, 51, -5, 287, 141, 521, 308, +602, 410, 470, 351, 131, 95, -261, -266, +-507, -580, -501, -677, -241, -490, 154, -133, +458, 235, 537, 441, 373, 394, 76, 144, +-158, -163, -196, -383, -35, -423, 236, -272, +434, -3, 408, 244, 151, 326, -197, 226, +-391, -5, -363, -262, -126, -424, 184, -442, +365, -328, 391, -144, 323, 64, 258, 248, +244, 367, 233, 366, 147, 203, -10, -82, +-179, -381, -266, -570, -207, -538, -31, -290, +182, 25, 320, 256, 357, 312, 334, 205, +293, 27, 225, -116, 156, -160, 41, -137, +-100, -114, -144, -113, -112, -112, 14, -113, +149, -97, 221, -84, 221, -80, 128, -61, +77, -30, 116, 49, 182, 158, 204, 203, +138, 109, -15, -117, -133, -383, -158, -562, +-78, -527, 128, -252, 323, 131, 389, 448, +299, 565, 114, 434, -73, 128, -157, -230, +-108, -509, 11, -632, 135, -600, 208, -424, +227, -128, 186, 203, 132, 467, 74, 562, +31, 452, 26, 178, 64, -167, 143, -428, +188, -519, 218, -462, 186, -318, 106, -166, +65, -57, 8, -7, -40, 30, -17, 90, +44, 188, 162, 300, 345, 377, 453, 341, +395, 112, 178, -292, -150, -743, -400, -1027, +-379, -969, -121, -518, 296, 188, 676, 848, +732, 1156, 483, 982, 56, 424, -349, -273, +-498, -819, -394, -1028, -122, -880, 201, -514, +409, -81, 458, 283, 369, 491, 203, 522, +81, 387, 42, 150, 72, -120, 93, -332, +22, -413, -136, -351, -276, -204, -282, -66, +-82, 9, 284, 12, 592, -36, 681, -73, +501, -40, 163, 33, -159, 84, -302, 80, +-198, 26, -29, -72, 139, -180, 195, -250, +98, -272, 55, -254, 82, -173, 183, -15, +358, 185, 437, 353, 356, 375, 176, 199, +-49, -152, -200, -532, -243, -747, -169, -666, +13, -308, 205, 152, 355, 527, 409, 672, +362, 531, 254, 194, 134, -180, 26, -478, +-62, -628, -104, -600, -115, -418, -85, -157, +-11, 94, 113, 267, 238, 321, 339, 264, +366, 140, 242, 7, 88, -92, -71, -155, +-149, -200, -55, -206, 102, -184, 242, -171, +252, -170, 85, -195, -106, -221, -183, -198, +-97, -68, 162, 183, 421, 447, 514, 573, +425, 458, 163, 79, -125, -435, -251, -855, +-194, -980, -24, -724, 196, -213, 309, 333, +282, 705, 198, 760, 94, 517, 61, 114, +93, -279, 118, -529, 116, -607, 81, -505, +45, -282, 73, -41, 187, 164, 332, 283, +390, 264, 276, 118, -16, -73, -336, -222, +-480, -260, -350, -171, 37, -4, 479, 127, +754, 127, 732, -20, 446, -229, 58, -375, +-250, -384, -371, -228, -345, 46, -218, 303, +-58, 416, 128, 337, 296, 90, 383, -227, +429, -497, 351, -591, 180, -466, 16, -192, +-118, 126, -129, 372, -22, 447, 80, 323, +143, 68, 137, -204, 65, -405, 21, -469, +42, -376, 135, -179, 230, 35, 288, 183, +283, 216, 180, 150, 54, 8, -39, -133, +-69, -187, -19, -160, 108, -77, 210, 20, +239, 56, 215, -4, 111, -131, 20, -259, +-14, -294, 33, -217, 134, -37, 220, 179, +247, 299, 172, 247, 65, 49, -21, -185, +-59, -339, -3, -337, 121, -188, 193, 8, +184, 116, 131, 87, 47, -37, 8, -149, +23, -181, 61, -114, 139, 22, 199, 119, +197, 100, 163, -3, 54, -117, -77, -193, +-149, -193, -141, -128, -7, -50, 188, -4, +352, 5, 419, 20, 334, 38, 158, 34, +-10, -10, -118, -98, -131, -209, -73, -289, +5, -257, 63, -92, 98, 119, 149, 273, +229, 290, 331, 148, 378, -92, 311, -306, +172, -384, -18, -312, -190, -161, -228, 0, +-152, 98, -14, 96, 183, 44, 293, 0, +316, 1, 284, 23, 162, 18, 91, -27, +76, -109, 47, -197, 48, -230, 43, -176, +12, -68, 14, 12, 12, 29, 19, -4, +69, -54, 116, -54, 179, 25, 230, 132, +216, 161, 141, 53, 47, -145, -59, -350, +-122, -441, -69, -338, 23, -92, 138, 177, +237, 336, 248, 321, 204, 166, 138, -66, +58, -273, -1, -367, -6, -329, -31, -200, +-48, -28, -11, 128, 52, 209, 160, 174, +285, 54, 370, -69, 371, -152, 265, -171, +88, -131, -106, -84, -285, -87, -360, -130, +-263, -143, -39, -90, 268, 27, 548, 167, +643, 242, 554, 192, 302, 30, -48, -162, +-292, -287, -372, -319, -308, -280, -104, -191, +107, -93, 233, -2, 294, 100, 298, 212, +278, 276, 246, 222, 177, 56, 73, -158, +-43, -338, -140, -391, -188, -288, -138, -112, +-41, 46, 50, 107, 177, 86, 275, 46, +316, 14, 290, 15, 165, 22, 17, -6, +-76, -77, -106, -146, -40, -155, 89, -118, +133, -72, 126, -47, 69, -55, -7, -62, +15, -29, 91, 58, 178, 142, 229, 131, +178, 15, 94, -148, 73, -275, 68, -272, +83, -142, 93, 19, 0, 125, -94, 111, +-112, 24, -35, -50, 149, -91, 322, -91, +391, -76, 344, -80, 193, -77, 6, -40, +-95, 39, -120, 116, -113, 103, -104, -15, +-84, -199, -21, -360, 88, -380, 261, -208, +423, 84, 488, 365, 375, 504, 103, 423, +-194, 129, -425, -263, -471, -594, -299, -723, +-22, -580, 290, -231, 522, 212, 565, 565, +452, 665, 195, 482, -94, 112, -256, -275, +-279, -514, -157, -515, 35, -307, 157, -40, +173, 120, 89, 116, -13, -10, -7, -145, +97, -159, 241, -10, 374, 205, 343, 343, +152, 299, -63, 83, -232, -193, -252, -409, +-125, -472, 57, -361, 223, -158, 299, 44, +283, 194, 187, 267, 80, 234, -8, 115, +-70, -46, -44, -191, 20, -254, 94, -189, +153, -17, 160, 148, 128, 178, 77, 53, +20, -156, -21, -335, -36, -367, -50, -215, +-20, 42, 30, 264, 86, 341, 179, 266, +231, 91, 230, -106, 165, -230, 43, -252, +-43, -217, -62, -158, -34, -98, 25, -31, +58, 28, 13, 77, -52, 114, -86, 102, +-35, 32, 102, -59, 262, -129, 366, -137, +366, -85, 259, -3, 88, 69, -66, 86, +-193, 26, -264, -88, -267, -196, -211, -267, +-67, -268, 157, -152, 422, 60, 603, 285, +625, 437, 437, 429, 81, 218, -278, -126, +-520, -464, -558, -646, -388, -610, -102, -375, +211, -18, 480, 324, 596, 542, 534, 588, +334, 441, 46, 141, -184, -232, -321, -541, +-328, -654, -166, -537, 39, -240, 191, 114, +262, 363, 214, 407, 107, 274, 38, 76, +5, -79, 24, -139, 64, -122, 78, -94, +81, -105, 39, -156, 5, -196, 12, -158, +22, -49, 48, 82, 32, 184, -18, 195, +-51, 116, -31, -4, 77, -102, 233, -126, +362, -105, 359, -83, 201, -77, -46, -106, +-274, -135, -355, -103, -227, -5, 11, 116, +225, 186, 348, 169, 303, 64, 164, -89, +38, -204, -49, -216, -49, -146, -4, -42, +18, 48, 36, 79, 56, 56, 87, 2, +144, -50, 148, -80, 78, -91, -42, -98, +-169, -74, -161, -15, -22, 56, 208, 125, +425, 146, 462, 70, 283, -76, -30, -214, +-319, -266, -466, -191, -399, -40, -165, 98, +134, 140, 378, 49, 479, -81, 433, -141, +272, -82, 73, 66, -127, 187, -253, 197, +-275, 80, -210, -114, -42, -272, 132, -317, +230, -262, 256, -153, 224, -15, 148, 114, +73, 204, 11, 252, -13, 238, 10, 147, +22, -8, 15, -176, -33, -290, -106, -326, +-148, -290, -115, -191, 35, -58, 263, 77, +459, 214, 513, 313, 368, 319, 23, 211, +-327, -1, -491, -232, -441, -387, -166, -416, +190, -296, 452, -78, 514, 129, 351, 249, +56, 255, -204, 156, -306, 7, -243, -116, +-40, -157, 197, -117, 333, -41, 330, 18, +171, 15, -87, -63, -307, -161, -347, -205, +-191, -123, 90, 60, 376, 235, 516, 310, +448, 217, 148, -34, -204, -308, -402, -433, +-384, -346, -135, -81, 197, 226, 391, 389, +386, 320, 185, 58, -119, -235, -272, -388, +-255, -343, -103, -140, 163, 109, 311, 265, +304, 265, 209, 151, 47, -12, -83, -143, +-130, -204, -114, -209, -24, -158, 73, -79, +99, -5, 122, 78, 115, 132, 69, 123, +25, 74, -12, 0, -10, -75, 19, -113, +70, -100, 84, -46, 69, 4, 27, 11, +-33, -18, -50, -59, -65, -98, -49, -101, +44, -53, 131, 11, 164, 72, 188, 118, +163, 137, 98, 129, 12, 68, -136, -55, +-200, -197, -156, -319, -56, -351, 126, -224, +262, 3, 260, 214, 164, 316, -1, 259, +-158, 103, -175, -51, -75, -119, 91, -77, +200, -14, 134, -20, 13, -102, -78, -211, +-96, -260, -7, -194, 131, -34, 227, 137, +220, 231, 101, 229, -65, 175, -143, 108, +-111, 40, -15, -32, 112, -129, 160, -253, +91, -359, 6, -359, -61, -221, -105, 6, +-47, 237, 75, 374, 168, 365, 204, 224, +141, 35, 27, -110, -58, -186, -121, -199, +-126, -195, -33, -200, 57, -194, 112, -163, +140, -67, 97, 88, 71, 216, 56, 286, +48, 288, 69, 204, 22, 66, -54, -83, +-119, -219, -178, -326, -164, -385, -28, -360, +147, -217, 272, 7, 310, 247, 225, 428, +102, 467, -33, 331, -148, 75, -182, -195, +-156, -370, -111, -399, -58, -301, 45, -137, +161, 11, 268, 85, 334, 120, 278, 144, +104, 148, -103, 137, -253, 79, -305, -32, +-236, -138, -109, -182, 69, -137, 226, -29, +262, 47, 227, 38, 141, -40, 42, -137, +-48, -158, -91, -58, -56, 113, 22, 250, +71, 256, 62, 118, -20, -89, -144, -269, +-147, -318, -47, -207, 118, -15, 289, 151, +328, 220, 238, 160, 15, 7, -245, -140, +-370, -200, -307, -134, -112, -3, 113, 110, +272, 156, 329, 103, 267, -14, 113, -115, +-44, -153, -182, -140, -226, -86, -141, -16, +-5, 61, 153, 130, 258, 163, 251, 143, +135, 49, -76, -112, -256, -258, -298, -303, +-191, -224, 4, -42, 193, 165, 306, 301, +323, 303, 227, 174, 71, 2, -84, -145, +-235, -248, -309, -269, -297, -212, -176, -114, +66, 10, 315, 129, 474, 213, 437, 223, +213, 131, -77, -8, -305, -121, -380, -173, +-270, -143, -51, -42, 152, 40, 251, 57, +176, 25, 26, -33, -109, -78, -174, -91, +-115, -71, 41, -20, 228, 47, 348, 108, +322, 168, 114, 176, -175, 88, -417, -63, +-491, -223, -345, -297, -53, -235, 305, -68, +544, 128, 563, 224, 364, 163, 32, 19, +-250, -103, -407, -131, -416, -41, -298, 103, +-102, 189, 96, 150, 247, 9, 298, -148, +243, -239, 150, -236, 32, -153, -51, -31, +-93, 59, -73, 109, -5, 145, 8, 171, +-35, 176, -113, 134, -153, 33, -81, -100, +51, -224, 179, -279, 281, -215, 273, -73, +165, 67, 11, 154, -189, 154, -325, 80, +-359, -6, -285, -42, -106, -11, 126, 45, +372, 81, 508, 80, 440, 24, 178, -62, +-163, -143, -432, -189, -500, -183, -353, -131, +-57, -32, 261, 114, 413, 244, 378, 298, +172, 260, -92, 111, -261, -105, -303, -281, +-182, -347, 9, -272, 158, -84, 232, 124, +162, 262, -5, 277, -139, 158, -191, -20, +-130, -166, 25, -230, 160, -172, 236, -23, +201, 130, 35, 225, -137, 199, -241, 53, +-248, -132, -140, -276, 33, -271, 187, -88, +277, 155, 279, 335, 168, 352, -26, 169, +-234, -113, -369, -343, -375, -407, -241, -274, +-5, -26, 255, 216, 440, 367, 422, 370, +253, 232, 22, 27, -202, -186, -321, -347, +-341, -367, -253, -234, -87, -11, 86, 203, +219, 300, 284, 252, 231, 101, 109, -74, +-25, -154, -173, -108, -222, -13, -163, 64, +-47, 80, 71, 27, 84, -46, 13, -100, +-55, -111, -87, -75, -61, -17, 52, 64, +170, 163, 233, 226, 205, 201, 50, 75, +-154, -112, -321, -278, -361, -328, -253, -205, +-33, 32, 206, 255, 369, 360, 381, 289, +192, 80, -69, -156, -274, -299, -332, -290, +-241, -153, -72, 36, 83, 193, 164, 258, +149, 214, 55, 106, -7, -5, -34, -103, +-29, -172, 16, -183, 14, -130, -24, -21, +-20, 94, -11, 166, -13, 167, -14, 86, +-50, -33, -55, -99, -42, -88, -49, -19, +5, 71, 69, 115, 85, 78, 75, -14, +27, -94, -21, -106, -47, -62, -86, 1, +-125, 63, -142, 89, -116, 61, 1, 25, +164, 4, 275, -6, 274, -5, 134, -1, +-99, 7, -320, 28, -390, 44, -273, 52, +-51, 56, 163, 2, 235, -88, 207, -154, +134, -168, 13, -102, -43, 49, -65, 228, +-111, 332, -142, 291, -178, 120, -171, -78, +-40, -224, 125, -270, 232, -201, 243, -93, +112, -6, -44, 57, -144, 115, -177, 176, +-125, 222, -41, 216, 17, 134, 12, -12, +-56, -171, -102, -253, -50, -214, 55, -105, +143, 23, 164, 127, 101, 168, -7, 148, +-131, 104, -201, 59, -182, 33, -79, 9, +20, -40, 57, -107, 50, -166, 22, -164, +41, -62, 73, 98, 88, 229, 69, 279, +-3, 223, -126, 76, -245, -97, -270, -196, +-180, -189, -9, -113, 152, -35, 229, 0, +212, 12, 121, 41, -15, 120, -130, 236, +-190, 302, -193, 229, -123, 25, -39, -210, +21, -366, 71, -368, 99, -195, 110, 71, +79, 283, 13, 338, -62, 248, -143, 91, +-178, -66, -124, -145, -17, -107, 82, 1, +122, 89, 77, 117, -9, 65, -116, -45, +-187, -136, -158, -165, -49, -112, 106, -4, +211, 113, 220, 227, 140, 290, -40, 235, +-233, 89, -342, -85, -328, -214, -175, -246, +36, -189, 222, -78, 321, 62, 287, 173, +155, 237, -40, 237, -238, 136, -340, -16, +-338, -136, -242, -190, -80, -158, 82, -47, +228, 92, 306, 193, 260, 224, 125, 173, +-44, 60, -214, -67, -338, -172, -363, -196, +-257, -137, -45, -37, 184, 80, 336, 180, +335, 229, 181, 220, -39, 147, -254, 28, +-364, -96, -335, -197, -177, -223, 55, -153, +220, -27, 255, 119, 186, 230, 41, 250, +-138, 161, -245, 15, -230, -105, -102, -140, +50, -82, 127, 19, 126, 108, 68, 124, +-29, 64, -129, -12, -181, -70, -174, -96, +-95, -63, 34, 36, 134, 150, 165, 213, +112, 184, 1, 77, -152, -58, -270, -170, +-264, -203, -133, -130, 67, 9, 188, 156, +168, 239, 47, 211, -84, 92, -139, -39, +-116, -94, -39, -54, 40, 20, 52, 53, +-21, 11, -122, -76, -191, -120, -149, -57, +-16, 101, 106, 261, 167, 311, 111, 211, +-27, -1, -142, -195, -211, -262, -198, -219, +-104, -102, 22, 42, 136, 157, 163, 237, +89, 286, -14, 255, -124, 126, -220, -72, +-240, -255, -176, -312, -27, -210, 144, -8, +241, 196, 215, 290, 78, 238, -111, 101, +-265, -43, -320, -108, -281, -66, -147, 7, +50, 74, 210, 112, 270, 85, 191, 7, +34, -79, -138, -125, -294, -101, -344, -1, +-238, 132, -19, 237, 174, 240, 247, 122, +169, -30, 6, -128, -166, -153, -260, -96, +-233, 21, -129, 119, 13, 133, 121, 75, +169, 1, 100, -23, -52, -2, -197, 53, +-281, 94, -239, 58, -95, -13, 79, -37, +191, -1, 183, 73, 92, 140, -26, 151, +-164, 74, -256, -75, -236, -195, -158, -194, +-41, -73, 64, 115, 145, 269, 170, 296, +62, 199, -111, 47, -264, -106, -271, -186, +-120, -133, 48, -9, 130, 88, 118, 104, +17, 64, -108, 21, -187, 12, -202, 43, +-126, 90, -23, 101, 51, 64, 65, 7, +30, -33, -19, -42, -88, -8, -126, 58, +-112, 93, -80, 50, -16, -13, 24, -21, +-5, 28, -75, 76, -137, 84, -155, 51, +-103, 1, -32, -20, 31, 11, 75, 69, +70, 97, 9, 76, -124, 16, -212, -55, +-200, -68, -126, 5, -43, 99, 14, 148, +47, 111, 56, 7, 55, -73, 33, -61, +-34, 2, -122, 68, -219, 107, -293, 125, +-275, 93, -159, 4, 32, -69, 236, -67, +314, -31, 244, 49, 87, 150, -139, 195, +-341, 137, -493, -3, -517, -147, -336, -197, +-20, -122, 293, 39, 459, 204, 417, 282, +200, 262, -77, 188, -329, 64, -449, -112, +-402, -261, -276, -305, -155, -215, -47, -33, +42, 165, 104, 308, 169, 352, 181, 300, +113, 208, 26, 84, -106, -63, -216, -193, +-309, -280, -379, -314, -347, -227, -240, -28, +-59, 213, 176, 401, 375, 457, 438, 349, +291, 131, -57, -105, -403, -243, -601, -261, +-591, -181, -368, -41, -49, 88, 255, 147, +404, 156, 341, 124, 123, 78, -150, 50, +-347, 35, -412, 46, -312, 83, -96, 111, +98, 82, 163, 4, 65, -101, -105, -185, +-226, -197, -237, -99, -161, 102, -14, 337, +102, 473, 147, 421, 88, 163, -64, -193, +-222, -459, -341, -485, -357, -269, -280, 84, +-107, 379, 116, 486, 278, 404, 269, 222, +106, 10, -127, -181, -316, -297, -391, -293, +-365, -159, -245, 53, -46, 229, 144, 313, +233, 294, 162, 174, -16, 4, -200, -140, +-300, -189, -301, -111, -234, 58, -77, 205, +92, 256, 151, 182, 54, 23, -79, -143, +-171, -249, -223, -235, -251, -58, -220, 173, +-89, 340, 60, 393, 101, 313, 26, 142, +-51, -37, -81, -204, -93, -291, -131, -263, +-191, -141, -205, 20, -174, 173, -145, 268, +-118, 315, -79, 296, 11, 196, 70, 33, +42, -157, -37, -266, -86, -205, -108, -39, +-138, 131, -175, 261, -223, 266, -229, 122, +-184, -87, -103, -225, -48, -197, 17, -5, +89, 205, 109, 313, 10, 276, -171, 138, +-284, -11, -252, -106, -128, -141, -47, -76, +-48, 39, -76, 129, -149, 130, -231, 60, +-217, -37, -87, -102, 71, -116, 133, -38, +39, 129, -116, 297, -188, 386, -191, 364, +-141, 205, -93, -29, -77, -252, -117, -418, +-179, -468, -198, -331, -183, -31, -103, 281, +-8, 492, 37, 561, 23, 503, 1, 332, +-21, 88, -80, -163, -190, -376, -303, -482, +-348, -406, -285, -199, -135, 26, 47, 213, +181, 379, 178, 461, 15, 427, -194, 283, +-348, 91, -357, -94, -241, -212, -129, -268, +-25, -241, 55, -151, 95, -32, 53, 95, +-32, 206, -126, 276, -226, 307, -351, 265, +-416, 143, -360, -13, -179, -159, 74, -226, +230, -181, 229, -79, 97, 59, -59, 210, +-159, 288, -253, 264, -332, 153, -320, 17, +-249, -71, -188, -102, -151, -133, -84, -101, +-10, -10, 44, 74, 61, 144, 35, 193, +-10, 187, -61, 171, -134, 151, -219, 117, +-284, 23, -318, -103, -276, -184, -235, -185, +-188, -166, -100, -97, 9, 39, 146, 206, +265, 395, 234, 543, 7, 477, -310, 170, +-524, -224, -560, -499, -460, -534, -227, -334, +49, 9, 228, 340, 216, 495, 48, 421, +-96, 223, -144, -10, -204, -167, -250, -167, +-252, -31, -205, 121, -143, 179, -105, 103, +-116, -15, -126, -107, -82, -139, -55, -87, +-65, 56, -65, 203, -43, 304, -44, 318, +-87, 222, -220, 19, -322, -178, -284, -262, +-184, -203, -129, -52, -93, 110, -16, 233, +52, 278, 26, 214, -57, 97, -131, 10, +-167, -33, -206, -57, -276, -66, -278, -44, +-187, -13, -84, 1, -8, 60, 33, 211, +-43, 318, -145, 264, -195, 83, -178, -124, +-128, -262, -56, -212, -40, -23, -132, 152, +-252, 201, -303, 145, -211, 77, -51, 100, +43, 185, 10, 242, -102, 129, -214, -167, +-253, -430, -214, -412, -109, -80, 10, 394, +54, 668, -26, 530, -164, 117, -282, -259, +-351, -385, -367, -247, -251, -21, -4, 127, +222, 182, 274, 180, 89, 183, -199, 192, +-445, 125, -529, -27, -395, -151, -101, -175, +142, -71, 207, 107, 68, 231, -169, 200, +-339, 51, -343, -76, -230, -36, -106, 107, +18, 203, 95, 169, 53, 25, -82, -136, +-231, -178, -323, -74, -305, 114, -232, 276, +-169, 288, -132, 102, -91, -116, -46, -206, +26, -137, 49, 43, -13, 260, -73, 398, +-119, 328, -207, 65, -311, -209, -352, -338, +-335, -261, -257, -9, -173, 225, -60, 243, +104, 117, 226, 81, 198, 154, 34, 194, +-172, 106, -336, -32, -441, -89, -450, -22, +-361, 66, -182, 56, 27, -90, 114, -229, +71, -159, 2, 132, -56, 404, -140, 482, +-194, 333, -177, 44, -115, -222, -101, -324, +-169, -207, -296, 34, -305, 201, -204, 201, +-121, 86, 0, -36, 147, -57, 189, 50, +76, 180, -190, 249, -478, 195, -549, -15, +-410, -223, -159, -224, 86, -15, 212, 235, +179, 355, 16, 225, -155, -52, -236, -253, +-239, -204, -204, 57, -230, 285, -313, 294, +-369, 115, -300, -146, -66, -266, 193, -100, +343, 197, 315, 361, 103, 319, -222, 143, +-506, -31, -637, -143, -540, -199, -315, -200, +-69, -149, 99, -38, 126, 155, 98, 353, +75, 419, 64, 332, 25, 162, -122, -1, +-304, -130, -395, -239, -408, -314, -307, -278, +-148, -99, -47, 186, -33, 419, -53, 428, +-40, 207, 36, -32, 97, -103, 70, 28, +-54, 198, -190, 164, -329, -107, -427, -359, +-366, -324, -280, 4, -235, 341, -132, 385, +105, 122, 370, -119, 422, -59, 130, 227, +-312, 397, -617, 220, -600, -183, -333, -456, +-58, -338, 69, 84, 17, 417, -77, 340, +-109, -29, -93, -299, -2, -201, 96, 202, +15, 570, -213, 535, -409, 82, -383, -441, +-177, -603, 14, -253, 3, 275, -157, 491, +-229, 274, -120, -110, -3, -264, 22, -49, +-6, 287, 13, 408, 57, 230, -106, -68, +-392, -230, -529, -211, -426, -125, -178, 1, +18, 145, 79, 245, 150, 262, 222, 168, +141, -17, -116, -170, -343, -151, -363, 31, +-288, 217, -280, 197, -254, -13, -100, -171, +75, -77, 79, 199, -74, 350, -147, 182, +-55, -169, 77, -315, 46, -117, -122, 220, +-282, 343, -353, 138, -348, -157, -299, -226, +-160, 3, 49, 302, 185, 349, 162, 106, +22, -135, -164, -180, -245, -88, -196, 32, +-129, 129, -126, 129, -203, 64, -286, 36, +-264, 66, -169, 36, 15, -68, 231, -73, +254, 92, -12, 271, -277, 281, -306, 112, +-229, -115, -169, -214, -177, -111, -184, 41, +-160, 23, -125, -127, -34, -128, 146, 146, +176, 490, -23, 558, -238, 266, -263, -137, +-173, -377, -163, -348, -189, -123, -174, 70, +-152, 74, -100, -44, 3, -38, 94, 224, +67, 506, -127, 463, -232, 127, -134, -201, +-66, -348, -195, -279, -270, -100, -137, 47, +-7, 69, -58, 71, -123, 206, -90, 371, +-20, 280, 3, -10, -62, -204, -125, -218, +-176, -133, -205, 40, -162, 200, -82, 199, +-50, 61, -67, -10, -144, 49, -209, 75, +-144, 28, 49, -7, 205, -22, 108, -68, +-188, -47, -424, 53, -429, 152, -204, 205, +28, 188, 98, 74, 28, -84, -74, -176, +-84, -120, -35, 68, 18, 255, -24, 256, +-192, 23, -340, -266, -337, -309, -224, -90, +-86, 177, 49, 367, 173, 409, 165, 281, +10, 58, -123, -107, -232, -205, -319, -310, +-320, -360, -193, -192, 14, 166, 110, 401, +58, 443, -65, 316, -234, 117, -320, -83, +-218, -179, 42, -158, 236, -95, 213, 8, +88, 111, -114, 140, -462, 14, -723, -103, +-609, -113, -144, -4, 370, 166, 506, 301, +350, 289, 135, 139, -97, -11, -346, -114, +-529, -161, -525, -162, -323, -132, -64, -75, +144, 42, 267, 250, 218, 381, 28, 275, +-257, 12, -430, -162, -306, -183, 7, -96, +249, 44, 209, 127, -56, 107, -308, 37, +-404, 70, -312, 101, -162, 2, -23, -148, +72, -139, 71, -1, 54, 170, 72, 258, +22, 220, -134, 59, -334, -133, -379, -166, +-156, -40, 32, 50, 77, 62, -1, 82, +-127, 106, -194, 81, -137, 1, 21, -67, +66, -29, -148, 54, -321, 89, -182, 28, +66, -53, 186, -19, 128, 160, -47, 282, +-297, 189, -449, -86, -308, -295, 25, -257, +150, -48, 8, 81, -125, 131, -89, 224, +-11, 296, -34, 238, -65, 43, -22, -150, +-66, -256, -259, -257, -285, -161, -38, 93, +172, 330, 78, 404, -207, 248, -284, -42, +-161, -263, -151, -262, -170, -109, -41, 59, +182, 115, 297, 160, 179, 259, -119, 264, +-383, 77, -492, -158, -373, -296, -166, -263, +-43, -77, 94, 182, 211, 372, 198, 303, +72, 77, -83, -66, -179, -84, -301, -89, +-446, -134, -394, -131, -15, -4, 325, 207, +290, 336, 13, 283, -171, 25, -156, -201, +-173, -214, -353, -57, -398, 23, -84, -46, +254, -49, 301, 176, 153, 415, -89, 351, +-268, -25, -368, -397, -389, -405, -219, -84, +73, 259, 308, 357, 302, 246, -36, 17, +-317, -135, -280, -149, -172, -49, -185, 15, +-277, -7, -131, -45, 218, 56, 325, 253, +82, 349, -143, 241, -214, -96, -157, -349, +-127, -329, -211, -143, -268, 16, -120, 168, +54, 323, 78, 348, -11, 175, -33, -88, +36, -230, -55, -220, -247, -88, -230, 107, +9, 171, 112, 102, -60, 59, -232, 128, +-146, 117, -33, -22, -106, -151, -213, -221, +-177, -204, 12, -62, 136, 190, 167, 405, +33, 406, -133, 198, -236, -88, -222, -254, +-104, -239, -60, -81, -101, -61, -118, -106, +-81, 7, -66, 205, -38, 266, 67, 175, +61, 64, -91, -69, -208, -148, -96, -37, +11, 179, -78, 182, -129, 34, -34, -36, +-26, -59, -167, -170, -158, -156, -54, -47, +-68, -24, -248, -83, -157, 137, 178, 491, +269, 524, 29, 210, -171, -81, -91, -242, +-73, -384, -257, -357, -261, -154, -161, 35, +-134, 120, -151, 198, -19, 287, 190, 216, +176, 41, -41, -38, -7, 0, 99, 41, +-112, 87, -465, 82, -478, -15, -104, -159, +121, -253, 34, -215, 56, -82, 107, 77, +-64, 212, -232, 323, -172, 333, -40, 176, +16, -118, -64, -190, -120, -9, -68, 146, +-22, 28, 27, -164, 14, -216, -143, -169, +-299, -84, -250, 92, -176, 184, -124, 92, +80, 90, 379, 390, 398, 558, -21, 229, +-430, -375, -385, -709, -247, -597, -265, -161, +-243, 328, 58, 506, 379, 320, 373, 27, +-41, 5, -294, 103, -270, -15, -224, -206, +-156, -215, -85, -36, -89, 149, -76, 198, +124, 95, 318, 71, 209, 33, -207, -86, +-536, -181, -440, -173, -138, 21, 31, 183, +127, 166, 185, 113, 100, 106, -156, 15, +-311, -74, -156, -107, 75, -68, 12, 37, +-108, 201, -64, 200, 17, -41, 88, -285, +-142, -178, -417, 94, -443, 109, -167, -46, +262, -18, 443, 197, 195, 284, -134, 224, +-190, 50, -190, -112, -268, -231, -275, -220, +-87, -139, 99, -44, 85, 65, -84, 167, +-174, 140, -62, 56, 58, 120, 54, 240, +-160, 210, -214, -47, 44, -286, 138, -250, +-119, -115, -454, -40, -294, -24, 260, 64, +399, 292, -118, 408, -455, 177, -134, -189, +197, -332, -24, -226, -411, 47, -241, 203, +209, 185, 244, 14, -53, -163, -81, -73, +65, 135, -109, 245, -336, 140, -323, -87, +-56, -297, 2, -303, -53, 20, -25, 356, +72, 384, 114, 39, 47, -139, -45, -96, +-248, 13, -294, 13, -121, -128, 61, -143, +68, 43, -147, 286, -146, 236, -14, -16, +-1, -176, -179, -86, -90, 7, 233, -41, +263, -12, -189, 120, -518, 194, -292, 116, +-21, -40, 26, -136, -51, -141, 190, 15, +303, 98, 17, 110, -288, 22, -344, -30, +-140, -46, -128, 49, -241, 142, -125, 145, +63, -68, 132, -285, 109, -135, 68, 187, +87, 326, 73, 128, -187, -85, -408, -161, +-348, -36, -99, 21, 42, -20, 4, -74, +-96, -61, -139, 124, -60, 251, 107, 212, +291, -27, 275, -155, 31, -128, -272, -68, +-492, -85, -435, -76, -205, 144, 60, 357, +109, 308, -1, -66, -25, -343, 163, -256, +179, -22, -77, 133, -163, 53, 35, 4, +-17, 78, -337, 232, -417, 223, -98, 66, +208, -175, 47, -324, -258, -228, -170, 11, +181, 181, 323, 176, 86, 128, -216, 139, +-136, 87, -31, -184, -208, -310, -480, -149, +-277, 180, 311, 302, 428, 272, -33, 168, +-390, -5, -164, -292, 117, -478, 54, -300, +-124, 14, -83, 284, 120, 391, 131, 477, +-181, 382, -529, -52, -374, -496, 26, -671, +257, -337, 150, 146, 56, 528, 183, 429, +165, 101, -168, -203, -510, -101, -521, 114, +-209, 43, 135, -208, 251, -296, 147, 11, +75, 287, 89, 285, 39, 79, -199, -82, +-410, -161, -250, -94, 74, 48, 62, 187, +-145, 59, -125, -249, 242, -183, 283, 193, +-188, 302, -519, 76, -126, -213, 339, -106, +147, 129, -266, 86, -233, -60, 161, -46, +56, 58, -348, 222, -320, 193, 93, -166, +211, -349, 33, -239, -39, 153, -16, 230, +-46, -28, -180, -56, -24, 226, 53, 390, +-145, 216, -227, -212, -108, -443, 38, -256, +-46, 98, -121, 307, 107, 64, 289, -361, +83, -275, -206, 166, -324, 517, -150, 418, +54, -60, 48, -209, -99, 8, -245, 118, +-149, -112, 104, -429, 218, -389, 163, 69, +-25, 372, -188, 295, -219, 85, -64, -63, +-52, 76, -135, 257, -132, 155, 155, -208, +324, -429, 22, -290, -417, -10, -386, 184, +61, 256, 310, 225, 85, 8, -232, -177, +-95, -100, 135, 212, 75, 182, -221, -94, +-298, -263, -1, -50, 82, 256, -129, 197, +-154, -157, 166, -357, 378, -133, 93, 208, +-329, 352, -395, 138, -151, -11, 100, -65, +113, -83, -46, -73, -74, -107, 20, -113, +81, -35, 40, 112, -29, 279, -122, 278, +-289, 60, -300, -123, 69, -213, 343, -214, +211, -129, -77, 30, -164, 110, -108, 125, +-141, 97, -225, 146, -43, 202, 77, 92, +9, -170, 38, -370, 126, -266, 229, 54, +74, 398, -195, 322, -294, -154, -415, -393, +-357, -221, 1, 224, 341, 438, 476, 218, +249, -102, -110, -225, -94, -114, -72, 56, +-307, 107, -490, -93, -257, -120, 324, -124, +381, -62, -35, 21, -201, 139, 59, 307, +245, 335, -32, 199, -336, 45, -161, -213, +191, -450, 150, -502, -207, -318, -359, 3, +-92, 340, 204, 437, 120, 415, -143, 311, +-67, 187, 284, -10, 376, -357, -69, -534, +-428, -321, -409, -106, -114, -126, 70, -110, +-28, 223, -84, 628, 50, 709, 353, 275, +410, -260, 50, -513, -386, -446, -383, -168, +-25, 109, 149, 152, -150, 56, -433, -88, +-46, -129, 426, 150, 305, 317, -143, 124, +-239, -113, 155, -19, 208, 174, -96, 156, +-237, -125, -48, -313, 55, -338, -145, -261, +-210, 0, -95, 275, -5, 392, 14, 334, +186, 200, 404, -42, 265, -292, -109, -210, +-387, -60, -343, -130, -162, -282, 11, -82, +-18, 439, -23, 655, 150, 195, 269, -440, +246, -651, -19, -338, -261, 389, -261, 608, +-196, 164, -79, -305, 64, -323, 223, 135, +227, 478, 26, 141, -250, -443, -187, -755, +94, -445, 115, 534, -8, 983, -179, 504, +-22, -250, 163, -690, -34, -394, -268, 280, +-114, 381, 128, -81, 163, -492, 64, -379, +54, 455, 176, 750, -21, 230, -385, -334, +-319, -570, 28, -356, 196, 170, 45, 420, +-104, 244, 83, -73, 309, -334, 52, -86, +-237, 210, -228, 206, -100, 63, 60, -192, +110, -325, 147, -5, 123, 247, -214, 188, +-391, -95, 35, -302, 380, -154, 230, 250, +-209, 447, -377, 358, -60, -239, 209, -773, +153, -428, -50, 390, -202, 720, -37, 195, +408, -681, 388, -699, -184, 257, -618, 1014, +-431, 674, 194, -547, 424, -1163, -11, -345, +-358, 787, -55, 787, 500, -171, 593, -912, +-28, -524, -571, 624, -384, 1039, -51, 272, +-44, -841, -69, -954, 172, 49, 326, 824, +102, 520, -62, -289, 48, -466, 71, -131, +-228, 281, -362, 233, -91, -134, 185, -388, +269, -280, 203, 145, 176, 504, -7, 495, +-360, 48, -546, -397, -186, -570, 352, -311, +460, 272, 91, 472, -181, 130, 17, -354, +201, -361, 32, 137, -266, 551, -231, 323, +-46, -264, 88, -606, 154, -306, 67, 348, +-33, 522, -72, 41, 21, -511, 180, -486, +130, 45, -97, 602, -345, 505, -132, -49, +333, -518, 455, -456, 3, 60, -562, 444, +-384, 305, 217, -223, 388, -530, 125, -396, +-200, 274, -136, 684, 181, 331, 217, -238, +75, -432, -114, -1, -287, 281, -134, 54, +-4, -424, 84, -524, 286, -261, 161, 376, +-75, 777, -165, 445, -49, -151, 190, -423, +57, -97, -260, 169, -248, -96, 50, -563, +304, -536, 412, 72, 136, 615, -232, 593, +-355, 64, -237, -179, 204, 34, 260, 144, +-38, -320, -125, -696, 24, -352, 108, 462, +20, 685, -46, 8, 83, -614, 142, -384, +-31, 549, -5, 876, 127, 138, 31, -875, +-238, -893, -436, -65, -138, 663, 300, 595, +423, -14, 190, -387, -37, -350, -56, 76, +29, 363, 19, 121, -144, -299, -134, -392, +11, 31, 147, 470, 187, 369, -37, -186, +-289, -620, -267, -533, 133, 119, 604, 753, +343, 620, -299, -98, -464, -677, 38, -538, +550, 80, 304, 386, -377, 176, -575, -205, +-72, -256, 384, 96, 234, 305, -201, 129, +-49, -271, 455, -407, 477, -4, -180, 433, +-645, 326, -279, -230, 315, -687, 469, -233, +-16, 632, -396, 700, -164, -273, 340, -1051, +639, -577, 215, 726, -566, 1094, -696, 230, +-89, -695, 557, -847, 551, -110, -17, 604, +-306, 620, -108, -6, 54, -760, 129, -839, +177, -58, 171, 736, 7, 908, -375, 379, +-292, -509, 306, -973, 388, -600, -49, 294, +-318, 991, -98, 522, 380, -498, 278, -962, +-29, -383, 100, 556, 87, 774, -139, 82, +-278, -631, -183, -600, 163, 79, 139, 643, +-86, 461, 45, -121, 320, -472, 419, -299, +108, 42, -359, 52, -336, -198, 160, -199, +339, 110, 59, 357, -311, 236, -278, -85, +122, -245, 357, -163, 263, 157, 74, 266, +-105, 20, -173, -493, 85, -618, 220, -82, +165, 434, 36, 519, -219, 166, -269, -186, +-175, -329, 210, -90, 574, 176, 297, 270, +-326, -131, -425, -495, 226, -246, 603, 131, +121, 235, -555, 86, -407, -117, 338, -47, +526, 134, 30, 110, -327, 27, -30, -119, +466, -234, 336, -135, -310, 13, -547, 31, +-119, -64, 352, -294, 448, -118, 201, 549, +25, 743, 17, 41, -44, -899, -113, -856, +-82, 198, 28, 780, 50, 255, 39, -556, +33, -564, 54, 99, 235, 770, 235, 493, +127, -413, -77, -813, -295, -444, -146, 315, +139, 524, 422, 150, 365, -126, -73, -46, +-288, 32, -139, -32, 111, -251, 157, -389, +-32, -221, -136, 14, 58, 256, 392, 353, +495, 209, 273, 116, -166, 35, -453, -160, +-317, -354, 67, -478, 293, -323, 155, -20, +-156, 235, 13, 310, 576, 293, 525, 106, +-141, -178, -719, -182, -365, -3, 537, 71, +697, -63, 175, -226, -365, -246, -441, -84, +79, 4, 491, 157, 350, 221, -144, 1, +-448, -139, -229, -169, 432, -61, 781, 108, +461, 143, -171, 136, -682, 22, -465, -304, +148, -422, 458, -167, 361, 102, 19, 202, +-124, 85, 73, -19, 264, 164, 259, 138, +164, -206, -107, -398, -261, -247, -261, 191, +-58, 390, 375, -23, 486, -358, 134, -249, +-211, 146, -133, 419, 202, -29, 518, -500, +297, -319, -276, 303, -521, 521, -226, 57, +422, -707, 611, -565, 126, 284, -271, 787, +-258, 446, 44, -580, 347, -940, 455, -304, +270, 632, 66, 907, -187, 123, -228, -817, +-79, -859, 56, -53, 125, 677, 17, 507, +-7, -150, 229, -432, 492, -191, 317, 82, +-11, 193, -12, 154, 41, -1, -38, -219, +-243, -453, -233, -254, 137, 150, 361, 372, +248, 217, 102, -196, 108, -385, 118, -122, +234, 277, 211, 319, 155, 32, 64, -288, +-269, -294, -471, -82, -193, -88, 260, -159, +527, -27, 532, 242, 233, 393, -46, 116, +-164, -436, 23, -518, 413, -128, 235, 384, +-372, 553, -568, 74, -66, -592, 697, -667, +800, -208, 131, 474, -410, 741, -270, 150, +149, -474, 517, -677, 410, -253, -123, 387, +-334, 382, -158, -79, 166, -379, 478, -199, +252, 193, -121, 416, -9, 175, 248, -216, +368, -449, 202, -427, -146, 20, -249, 171, +-131, 37, 61, -40, 317, 83, 319, 222, +97, 28, 108, -281, 307, -381, 357, 13, +265, 400, -173, 430, -586, -34, -432, -723, +27, -701, 761, -123, 964, 514, 28, 553, +-504, -21, -253, -439, 309, -279, 682, 132, +228, 475, -324, 369, -256, -184, 73, -479, +481, -562, 493, -377, -70, 88, -354, 380, +-184, 401, 123, 87, 349, -399, 223, -298, +268, 144, 462, 328, 320, 109, 13, -282, +-253, -303, -191, -23, 17, -8, -8, -98, +-22, -62, 265, 27, 416, 126, 234, -74, +34, -377, 151, -205, 462, 290, 338, 658, +-127, 384, -462, -343, -361, -744, 234, -658, +560, -144, 417, 306, 31, 548, -69, 431, +179, -73, 237, -511, 37, -500, -31, 39, +135, 372, 223, 175, 200, -359, 84, -457, +-15, 56, 70, 508, 236, 404, 169, -222, +-107, -563, -23, -364, 359, 192, 549, 363, +170, -34, -331, -389, -156, -197, 104, 87, +188, 101, 294, -118, 329, 96, 357, 371, +163, 149, -150, -294, -32, -510, 111, -223, +-7, 133, -117, 201, -49, -12, 360, -215, +627, -284, 288, -128, 32, 183, 239, 293, +264, 328, -5, 134, -298, -249, -310, -402, +41, -240, 259, -37, 350, 10, 440, -147, +187, -226, 1, -103, 118, 145, 361, 424, +435, 364, 186, 5, -252, -319, -494, -356, +-281, -224, 210, -43, 652, 110, 535, 41, +96, -161, -34, -238, 111, -23, 387, 252, +403, 277, -51, 18, -398, -248, -235, -304, +278, -158, 592, 210, 292, 219, -146, -83, +-129, -290, 205, -225, 494, 91, 392, 187, +22, 54, -225, -204, -71, -335, 238, -169, +339, 336, 172, 430, -29, 83, -11, -409, +229, -487, 330, 15, 196, 239, 118, 45, +154, -308, 208, -188, 5, 343, -286, 440, +-129, -131, 434, -664, 554, -415, 156, 235, +-104, 537, 43, 75, 531, -445, 515, -363, +-2, 223, -340, 587, -307, 172, 144, -589, +355, -802, 169, -190, 92, 451, 223, 487, +323, 5, 271, -277, 196, -43, 201, 173, +232, 66, 0, -208, -131, -257, -110, -178, +-180, -140, -15, -189, 267, 82, 686, 463, +656, 394, 107, -27, -77, -479, 77, -430, +279, -58, 67, 281, -309, 180, -293, -157, +174, -485, 421, -318, 271, 225, 279, 480, +453, 299, 559, -128, 103, -255, -494, -115, +-473, -41, 135, -207, 720, -242, 620, -117, +-139, 98, -657, 192, -176, -29, 728, -169, +1077, 4, 439, 262, -383, 412, -511, 87, +-15, -419, 457, -674, 370, -561, 35, -127, +-200, 319, -54, 512, 337, 351, 460, 32, +471, -218, 276, -123, -86, 75, -197, -38, +-66, -333, 293, -564, 360, -248, -24, 328, +-72, 455, 186, 101, 375, -229, 445, -130, +13, 200, -284, 233, 61, -128, 483, -394, +552, -240, 30, 82, -436, 69, -89, -310, +474, -353, 525, 120, 141, 613, -268, 395, +-135, -268, 358, -512, 523, -84, 348, 393, +-39, 122, -109, -428, 162, -631, 240, -146, +66, 295, -59, 273, 109, 23, 295, 2, +329, 167, 138, 113, -111, -165, 19, -357, +464, -299, 499, 32, 51, 240, -209, 86, +-8, -266, 459, -360, 362, -31, -252, 375, +-441, 401, -22, -117, 556, -516, 739, -369, +318, 203, 73, 553, 205, 154, 243, -384, +-44, -437, -540, -192, -390, 100, 417, 87, +812, -76, 450, -126, -159, -77, -226, 190, +423, 420, 764, 243, 217, -161, -522, -379, +-501, -502, 135, -454, 638, -97, 522, 319, +161, 568, 42, 231, 55, -245, 90, -322, +139, -51, 68, 144, -7, 15, 119, -224, +293, -278, 307, -77, 145, 109, 26, 113, +197, 171, 279, 159, 127, -102, -103, -431, +-161, -507, 141, -11, 513, 576, 552, 421, +164, -218, -186, -575, -203, -309, 57, 378, +233, 466, 270, -44, 265, -420, 263, -341, +194, -25, 70, 167, 74, 17, 90, -112, +137, -83, 125, 13, -59, 168, -76, 194, +195, 25, 451, -117, 525, -230, 316, -282, +-3, -187, -121, -35, -151, 85, -47, 29, +205, -60, 327, 78, 324, 391, 139, 348, +-76, -180, 50, -723, 411, -711, 588, 21, +274, 687, -255, 535, -380, -111, 21, -600, +367, -355, 308, 282, 72, 397, -104, -100, +143, -571, 493, -423, 445, 352, 143, 750, +82, 317, 237, -413, 160, -611, -259, -229, +-535, 168, 19, 61, 651, -314, 559, -240, +64, 147, -158, 544, 190, 442, 722, -92, +645, -470, -37, -405, -551, -123, -523, 93, +60, 85, 568, -129, 414, -143, 122, -5, +-16, 254, 160, 395, 513, 40, 421, -533, +53, -679, -137, -160, -153, 527, 15, 677, +192, 79, 211, -444, 191, -445, 165, -79, +216, 198, 314, 91, 73, -235, -183, -295, +85, -64, 522, 291, 464, 379, -87, 77, +-290, -239, 87, -310, 397, -125, 176, 91, +-133, 198, -83, 10, 282, -164, 585, -310, +452, -296, 54, -84, -95, 218, 45, 461, +108, 283, -36, -186, -131, -419, 63, -231, +347, 214, 507, 263, 484, -81, 262, -388, +-98, -372, -285, -58, -75, 204, 172, 138, +343, -48, 276, 9, 94, 256, 65, 289, +137, -104, 297, -482, 290, -270, 72, 171, +-99, 159, -53, -294, 107, -624, 303, -128, +335, 600, 199, 782, 31, 237, 44, -484, +133, -686, 120, -288, 144, 256, 190, 442, +173, 158, 167, -378, 131, -615, 112, -333, +101, 357, 91, 763, 232, 479, 242, -243, +-16, -801, -134, -579, 33, 67, 309, 506, +445, 286, 317, -174, 213, -311, 183, 45, +82, 340, -161, 157, -292, -269, -41, -502, +389, -250, 434, 83, 96, 167, -32, 114, +389, 95, 738, 173, 315, 157, -452, -187, +-604, -421, 10, -361, 687, 16, 674, 352, +94, 278, -379, -46, -264, -348, 305, -284, +577, 34, 353, 292, -79, 246, -142, -113, +236, -408, 518, -320, 347, 161, -56, 487, +-216, 263, -88, -271, 93, -517, 56, -220, +117, 141, 436, 274, 571, 91, 334, -171, +-145, -267, -160, -156, 230, 151, 340, 334, +146, 127, -82, -152, -135, -247, -14, -108, +193, 16, 370, -42, 418, -89, 215, -59, +-21, -14, 74, 16, 314, 25, 339, 45, +6, 114, -247, 88, -75, -52, 213, -189, +217, -188, 16, -39, 138, 58, 495, -2, +618, -129, 247, -85, -292, 61, -419, 151, +-55, 91, 466, -53, 616, -122, 130, -112, +-268, -94, -46, -78, 376, 1, 488, 137, +141, 153, -125, 22, -23, -185, 65, -197, +98, -69, 201, -21, 367, -52, 468, -90, +186, 75, -212, 270, -157, 220, 211, -35, +416, -300, 165, -297, -177, -114, -65, 157, +156, 158, 272, -25, 291, -168, 387, -147, +399, 72, 94, 158, -219, -1, -227, -106, +146, -55, 441, 104, 250, 174, -118, -47, +-103, -311, 275, -314, 458, -41, 205, 208, +-94, 180, 36, -96, 341, -230, 390, 24, +156, 249, -87, 330, -33, -2, 146, -436, +183, -508, 32, -185, -81, 300, 74, 466, +371, 109, 454, -380, 301, -325, 100, 57, +-16, 398, 27, 229, 135, -265, 214, -406, +169, -148, -46, 199, -141, 284, 21, 36, +302, -327, 434, -299, 305, -14, 165, 276, +131, 272, 90, -68, 86, -188, 101, -23, +69, 39, 40, -64, -17, -174, 80, -111, +250, 42, 240, 58, 212, -56, 212, 32, +223, 178, 214, 150, 74, 3, -80, -260, +-81, -325, 138, -113, 385, 39, 370, 169, +0, 81, -207, -25, 10, 20, 347, 55, +442, 66, 212, -16, 17, -134, -2, -247, +14, -175, 24, -62, 261, 116, 436, 259, +270, 76, -93, -104, -255, -158, 128, 22, +511, 285, 378, 139, -112, -319, -300, -552, +57, -237, 483, 305, 501, 471, 180, 101, +1, -312, -34, -287, -38, 3, 6, 241, +244, 279, 488, 118, 255, -52, -208, -314, +-237, -515, 169, -370, 428, 60, 360, 471, +136, 504, 65, 68, 144, -396, 115, -301, +94, 158, 102, 460, 53, 162, 24, -467, +78, -678, 137, -259, 222, 286, 258, 483, +244, 247, 256, -133, 99, -227, -43, -107, +-40, 45, 55, 160, 198, 127, 256, 18, +234, -231, 111, -416, 37, -178, 60, 245, +159, 350, 184, -73, 67, -385, 108, -105, +184, 418, 162, 518, 117, 14, 186, -420, +290, -479, 156, -181, -149, 90, -231, 109, +73, 36, 439, -24, 531, 129, 181, 230, +-210, 83, -130, -241, 350, -319, 610, 18, +181, 292, -425, 96, -394, -383, 224, -492, +593, 44, 327, 558, -68, 472, 11, -94, +361, -519, 380, -323, 152, 98, -21, 300, +-147, 97, -232, -183, -76, -209, 359, -51, +584, 99, 309, 95, -22, 55, 49, -28, +273, -46, 171, -47, -97, -25, -78, -8, +119, -119, 168, -144, 110, 19, 130, 241, +266, 272, 297, -27, 89, -445, -85, -496, +-23, -36, 259, 535, 457, 614, 256, 3, +-130, -550, -282, -457, -94, 101, 326, 355, +426, 4, 143, -364, 32, -203, 93, 254, +252, 422, 233, 91, 62, -283, 26, -262, +19, 51, 24, 182, 40, 5, 118, -227, +204, -312, 213, -54, 174, 229, 160, 382, +126, 260, 86, -114, 66, -382, 44, -370, +123, -28, 164, 257, 133, 265, 19, -61, +20, -347, 236, -196, 277, 190, 67, 428, +-178, 152, -35, -319, 434, -391, 551, -59, +117, 322, -322, 246, -232, -187, 234, -417, +462, -201, 203, 223, -114, 347, -130, 101, +160, -161, 388, -120, 310, 84, 48, 99, +-172, -100, -85, -328, 182, -231, 325, 118, +273, 318, 101, 135, 75, -199, 56, -194, +-130, 111, -199, 255, 97, 6, 503, -281, +477, -182, 10, 149, -193, 257, 138, 9, +314, -261, 116, -344, -129, -137, -147, 150, +49, 288, 192, 276, 323, 118, 335, -123, +57, -268, -215, -244, -60, -58, 366, 143, +480, 124, 148, -44, -201, -60, -182, -7, +-38, 18, 53, -61, 99, -165, 239, 18, +378, 136, 287, 160, 143, 49, 48, -119, +6, -101, -62, -3, -77, 51, 16, -51, +72, -150, 48, -216, 85, -13, 232, 183, +331, 120, 307, 27, 155, -91, -28, 3, +-162, 147, -113, 77, 167, -36, 297, -119, +115, -147, -157, -145, -192, -171, 112, -119, +370, 71, 374, 228, 222, 215, -7, 105, +-51, -53, 68, -79, 155, 61, 139, 70, +-179, -80, -340, -327, -43, -403, 318, -121, +511, 229, 332, 345, 78, 197, 73, -13, +26, -97, -86, 6, -56, 63, 3, -21, +17, -117, 38, -241, 15, -200, 151, -22, +302, 151, 267, 220, 201, 95, 67, -152, +-86, -157, -57, 52, -7, 181, -42, 148, +23, -159, 103, -381, 187, -168, 195, 231, +55, 431, 92, 96, 168, -441, 95, -473, +38, 23, 47, 473, 20, 324, -90, -151, +-154, -381, -3, -87, 272, 260, 277, 255, +199, -42, 187, -363, 28, -279, -48, -27, +13, 190, 29, 257, -52, 125, -223, -60, +-91, -227, 315, -160, 402, 2, 163, 100, +39, 107, 117, 12, 199, -15, 14, -32, +-257, -107, -235, -119, -24, -31, 141, 48, +169, 31, 159, 8, 212, -26, 186, 37, +82, 90, 72, 50, 70, 9, -40, -125, +-179, -211, -216, -227, -57, -90, 210, 225, +438, 377, 366, 238, -54, -74, -392, -330, +-226, -301, 326, -77, 514, 60, 145, 94, +-288, 56, -317, -30, 44, 18, 322, 125, +203, 220, -88, 164, -181, -148, -2, -495, +244, -510, 244, -143, 130, 354, -43, 512, +-177, 289, -19, -6, 178, -195, 165, -215, +-83, -124, -197, -54, 3, -66, 251, -37, +228, -17, -7, 100, -28, 130, 65, 32, +156, -8, 44, -42, -215, -3, -214, -42, +30, -54, 205, -95, 222, -54, 148, 52, +53, 134, -7, 99, -115, -138, 2, -219, +142, -167, -61, 37, -216, 250, -56, 321, +284, 210, 404, -143, 46, -440, -341, -448, +-201, -128, 201, 235, 343, 307, 149, 151, +-192, -30, -252, 1, -34, 120, 94, 90, +75, -151, 79, -405, 98, -337, 126, 27, +42, 362, -159, 354, -108, -27, 126, -354, +251, -173, 100, 246, -250, 316, -306, -21, +-11, -351, 187, -266, 201, 170, 87, 330, +-43, 88, 6, -272, 56, -362, 75, -66, +125, 185, -40, 140, -261, -7, -307, -23, +-119, 141, 243, 251, 408, 132, 226, -81, +-66, -294, -186, -467, -109, -320, 11, -14, +102, 180, 63, 272, -31, 228, -102, 221, +-86, 212, 39, 51, 104, -168, -9, -343, +-88, -374, -30, -250, 109, 2, 225, 167, +172, 274, 9, 204, -165, 43, -234, -93, +-186, -206, -138, -55, -89, 96, 107, 198, +364, 164, 359, -79, 128, -319, -92, -310, +-216, -56, -271, 135, -220, 103, -30, -22, +136, 37, 98, 166, -71, 155, -41, 56, +155, -89, 250, -185, 167, -166, -52, -57, +-297, 88, -307, 36, -110, -117, 140, -122, +247, 14, -33, 105, -213, 61, -65, 46, +177, 130, 293, 171, -26, -43, -292, -349, +-158, -355, 116, -27, 285, 362, 82, 352, +-318, -49, -440, -436, -128, -425, 182, -20, +251, 442, 163, 475, 132, 93, 134, -263, +-132, -292, -332, -57, -218, 84, -32, -5, +-2, -117, -10, -79, 82, 30, 126, 131, +63, 109, -55, -16, -72, -90, -61, -110, +-44, -55, 20, 2, 23, 112, -82, 201, +-96, 104, 39, -138, 93, -213, 6, -109, +-220, -44, -267, -74, -35, -144, 194, 30, +262, 272, 125, 335, -45, 182, -124, -60, +-238, -285, -306, -347, -108, -193, 167, 45, +191, 289, 20, 282, -79, 6, -80, -280, +-51, -317, -58, -25, -20, 223, 104, 237, +92, 73, -41, -56, -185, -64, -262, -8, +-135, 14, 90, -84, 167, -182, 58, -171, +-48, 16, -101, 151, -52, 62, -5, -58, +-24, -20, 4, 187, -70, 295, -109, 108, +-10, -211, 22, -391, -26, -281, -163, -45, +-167, 85, 45, 97, 176, 134, 93, 191, +-91, 202, -124, 55, -53, -198, -98, -310, +-154, -221, -11, 20, 122, 194, 34, 200, +-157, 113, -150, 8, 33, -175, 26, -274, +-42, -160, -38, 92, -34, 271, -85, 150, +-109, -50, 42, -79, 127, 55, -11, 117, +-158, -26, -166, -292, -148, -371, -135, -84, +-50, 292, 128, 433, 252, 151, 141, -171, +-101, -229, -284, -33, -266, 159, -102, 67, +53, -225, 66, -359, -90, -37, -165, 367, +-101, 408, 97, 0, 287, -380, 157, -258, +-179, 89, -324, 295, -222, 134, -63, -184, +-59, -292, -143, -78, -6, 229, 141, 289, +147, 23, 93, -291, -51, -257, -134, -19, +-167, 206, -178, 206, -133, -7, -79, -71, +-26, 3, 30, 49, 68, -40, 11, -177, +-76, -183, -120, -55, -27, 103, 133, 235, +74, 238, -181, 38, -305, -172, -206, -206, +-35, -139, 30, -37, 19, -10, 70, 126, +43, 231, -29, 169, -56, -24, -54, -227, +-26, -263, -79, -113, -210, 72, -307, 125, +-158, 77, 147, 28, 243, 101, 83, 189, +-157, 72, -185, -162, 19, -347, 126, -310, +73, 14, -230, 284, -586, 270, -409, 55, +175, -165, 589, -119, 333, 52, -250, 137, +-423, 80, -131, -28, 218, -125, 113, -120, +-302, -60, -499, -45, -219, -15, 277, -16, +376, 14, 44, 143, -252, 224, -208, 196, +50, 6, 131, -181, -50, -220, -264, -186, +-349, -179, -203, -111, 57, 85, 188, 269, +173, 353, 51, 178, -96, -22, -136, -52, +-145, -114, -204, -192, -155, -301, -3, -274, +33, -53, -16, 191, -72, 376, -26, 420, +77, 270, -53, -18, -188, -302, -156, -492, +-115, -440, -3, -155, 87, 210, 120, 507, +82, 445, -187, 146, -364, -141, -305, -341, +-108, -353, 133, -215, 187, 18, 85, 281, +3, 400, -6, 246, -89, -48, -204, -302, +-280, -355, -276, -201, -32, -24, 206, 176, +213, 306, -4, 298, -263, 153, -170, -146, +70, -428, -10, -347, -239, -51, -181, 240, +100, 362, 220, 255, -44, 25, -325, -234, +-235, -403, 26, -285, 167, 80, 118, 350, +-95, 366, -322, 88, -331, -206, -101, -331, +225, -218, 341, 78, 64, 380, -273, 422, +-307, 74, -137, -433, -14, -683, -92, -401, +-174, 195, 51, 678, 256, 714, 81, 263, +-242, -295, -401, -563, -124, -531, 236, -254, +252, 113, -12, 444, -335, 501, -400, 156, +-153, -260, 100, -366, 171, -147, 122, 158, +-19, 283, -157, 134, -287, -211, -248, -368, +49, -210, 262, 205, 120, 453, -228, 329, +-351, -60, -186, -387, 63, -364, 123, -90, +9, 221, -50, 298, -102, 139, -78, -61, +-27, -193, -57, -147, -211, -13, -282, 72, +-23, 53, 291, 86, 273, 95, -119, 31, +-443, -35, -329, -73, 11, -76, 221, -87, +155, -43, -165, 39, -390, 77, -235, 27, +120, 35, 280, 94, 84, 111, -154, -3, +-259, -142, -168, -169, -12, -83, 15, 56, +-58, 124, -163, 35, -80, -74, 33, 55, +11, 186, -79, 97, -96, -145, -5, -311, +-16, -235, -78, 35, -87, 244, -86, 305, +-46, 249, -51, 137, -163, -62, -180, -305, +-27, -525, 153, -430, 66, -14, -175, 427, +-154, 669, -3, 432, 61, -124, -81, -465, +-182, -306, -88, 115, -57, 299, -45, -4, +-85, -423, -165, -503, -120, -117, 48, 496, +229, 866, 152, 556, -154, -217, -313, -854, +-229, -788, 4, -17, -20, 675, -271, 660, +-284, -56, 41, -637, 464, -421, 452, 284, +-43, 702, -572, 366, -646, -338, -230, -690, +258, -430, 401, 133, 16, 498, -379, 497, +-292, 162, 61, -188, 232, -303, 77, -254, +-149, -146, -163, -24, -175, 163, -193, 313, +-108, 252, -42, 20, 97, -226, 51, -211, +-110, -7, -138, 113, -93, -2, 8, -287, +74, -269, 49, 170, -29, 658, -184, 668, +-382, 166, -411, -594, -126, -1039, 182, -702, +302, 169, 293, 915, 83, 869, -96, 235, +-293, -345, -478, -528, -364, -306, -145, 1, +160, 143, 319, 77, 99, 17, -152, 45, +-182, 101, -55, 63, 82, -48, 4, -76, +-233, -72, -273, -61, -204, -5, -34, 157, +141, 252, 96, 118, -6, -225, -59, -440, +-158, -247, -176, 188, -92, 472, -64, 403, +-45, 100, -128, -170, -102, -467, 150, -576, +209, -207, -4, 395, -303, 786, -431, 555, +-217, -173, 52, -704, 196, -634, 121, -25, +-142, 554, -225, 547, -42, 92, 167, -304, +92, -341, -217, -153, -394, 31, -218, 98, +60, 152, 93, 115, 6, 123, -38, 96, +-34, -79, -124, -253, -229, -343, -127, -141, +132, 238, 293, 527, 144, 488, -255, 128, +-558, -390, -608, -796, -325, -731, 206, -166, +623, 658, 702, 1164, 284, 837, -431, -39, +-970, -937, -839, -1054, -179, -390, 458, 419, +715, 742, 365, 456, -187, -63, -544, -423, +-546, -368, -158, -144, 112, 143, 95, 333, +32, 377, 56, 351, 124, 82, 34, -402, +-261, -681, -457, -544, -346, -14, 4, 520, +250, 681, 149, 430, -136, -72, -198, -453, +-14, -550, 56, -232, -65, 267, -215, 629, +-74, 466, 79, -151, -100, -529, -301, -623, +-175, -242, 126, 346, 116, 711, -192, 570, +-314, -79, -58, -667, 231, -668, 178, -28, +-14, 620, -143, 716, -276, 170, -354, -518, +-290, -678, -43, -372, 223, 213, 281, 604, +48, 612, -271, 168, -482, -525, -304, -788, +293, -368, 661, 437, 341, 828, -477, 464, +-1018, -234, -711, -608, 17, -417, 481, 42, +568, 316, 363, 261, -51, 95, -439, -88, +-535, -115, -290, -66, -66, -120, 41, -186, +130, 98, 236, 478, 99, 618, -338, 134, +-528, -610, -359, -933, 57, -566, 365, 301, +388, 859, 159, 694, -200, 117, -497, -223, +-533, -189, -263, -223, 69, -443, 355, -440, +260, 58, -105, 595, -400, 650, -344, 161, +34, -481, 345, -507, 350, 84, -103, 588, +-565, 421, -673, -361, -281, -900, 344, -623, +447, 280, 113, 879, -224, 751, -288, 109, +-17, -401, 45, -381, -95, -126, -162, -31, +-326, -88, -254, -128, 53, -33, 323, 239, +317, 464, -123, 248, -485, -313, -462, -572, +-103, -244, 178, 340, 234, 653, 121, 452, +-182, -209, -338, -735, -247, -674, -12, 65, +166, 747, 23, 682, -172, -29, -240, -733, +-138, -704, 41, -9, 95, 807, 25, 934, +-192, 279, -282, -657, -116, -1008, 193, -506, +254, 396, -67, 901, -460, 491, -571, -373, +-289, -898, 263, -490, 696, 466, 500, 1113, +-216, 824, -920, -163, -777, -1113, -4, -1261, +541, -357, 470, 805, -150, 1419, -463, 826, +-259, -498, 119, -1325, 203, -823, -13, 441, +-249, 1119, -465, 640, -356, -572, 55, -1152, +498, -491, 535, 804, 15, 1504, -604, 722, +-685, -780, -367, -1697, 89, -1060, 324, 390, +210, 1308, 39, 1037, -124, 50, -101, -616, +-93, -570, -60, -55, -134, 257, -321, 213, +-349, -197, -60, -382, 333, -134, 286, 302, +-50, 574, -241, 406, -151, -79, -66, -612, +-124, -651, -186, -213, -176, 382, -124, 603, +78, 436, 332, -5, 210, -276, -176, -284, +-600, -224, -576, -70, -27, 46, 410, 216, +520, 294, 217, 97, -275, -241, -668, -430, +-664, -136, -194, 244, 352, 432, 536, 378, +311, 114, -34, -224, -345, -449, -509, -380, +-423, -172, -154, 139, 157, 277, 203, 291, +136, 195, 220, -22, 97, -88, -239, -61, +-545, 84, -582, 37, -240, -209, 278, -327, +567, -108, 445, 255, -78, 399, -577, 229, +-605, -187, -313, -443, 28, -293, 414, 127, +549, 541, 138, 555, -450, 80, -818, -443, +-536, -688, 162, -510, 610, 84, 527, 657, +2, 739, -545, 173, -539, -461, -11, -493, +243, -81, -78, 204, -513, 173, -268, -23, +423, -136, 517, -61, 77, 100, -381, 226, +-412, 200, -153, -93, -105, -327, -144, -291, +70, 18, 222, 346, 69, 378, -145, 76, +-342, -313, -256, -370, 39, -117, 228, 270, +221, 316, -58, 100, -443, -66, -388, -92, +-30, -54, 229, -76, 200, -109, -56, -68, +-228, 94, -276, 193, -237, 135, -11, -109, +319, -199, 276, 8, -104, 174, -405, 195, +-270, 81, 21, -84, 34, -143, -58, -186, +-119, -161, -57, -139, -23, 75, -145, 300, +-118, 349, 107, 170, 263, -135, 97, -182, +-196, -40, -271, 35, -235, -160, -215, -264, +-199, -95, -103, 224, 145, 425, 216, 215, +141, -191, 129, -400, 83, -184, -147, 140, +-533, 379, -597, 424, -203, 23, 357, -484, +523, -563, 99, -93, -388, 426, -363, 480, +-4, 78, 225, -355, 3, -425, -200, -62, +-75, 368, -46, 496, -97, 195, -173, -205, +-30, -328, 124, -173, 23, 67, -134, 145, +-159, -38, -82, -349, -139, -343, -122, 167, +181, 624, 383, 596, 153, 136, -371, -226, +-677, -361, -537, -479, 12, -304, 671, -24, +727, 386, 102, 480, -647, 213, -841, -335, +-313, -627, 273, -217, 529, 449, 406, 863, +-58, 453, -540, -268, -600, -746, -125, -611, +376, -77, 442, 275, 69, 331, -311, 109, +-570, -49, -456, 38, 115, 168, 565, 209, +492, -4, -23, -294, -387, -260, -375, 41, +-299, 180, -192, 65, -9, -128, 198, -175, +238, -84, 64, 89, -29, 234, -127, 266, +-221, 62, -343, -166, -54, -135, 288, 6, +171, 116, 77, -10, -113, -74, -331, -176, +-586, -272, -403, -56, 340, 163, 791, 367, +484, 397, -299, 224, -660, -141, -450, -403, +35, -413, 352, -140, 202, 275, -227, 298, +-494, -11, -227, -327, 260, -178, 427, 214, +81, 444, -330, 366, -342, -49, 81, -469, +356, -447, 146, -34, -367, 397, -593, 361, +-338, -205, 68, -508, 388, -242, 403, 346, +257, 597, -193, 386, -458, -81, -397, -415, +-122, -478, 330, -269, 354, 118, -119, 372, +-554, 372, -362, 72, 138, -273, 430, -255, +301, 73, -99, 307, -278, 98, -297, -256, +-198, -385, -83, -110, 18, 372, 198, 493, +263, 217, 164, -214, -224, -353, -573, -264, +-447, -160, 68, 8, 510, 209, 449, 311, +-51, 264, -434, 60, -352, -127, -63, -174, +90, -208, 76, -87, 12, -3, -35, -36, +-33, -25, -64, 162, -122, 330, -60, 291, +64, -26, 198, -384, 45, -360, -440, -112, +-531, 208, -17, 231, 523, 19, 509, -105, +14, -23, -464, 185, -411, 222, -68, 58, +89, -228, -49, -388, -165, -179, 17, 233, +190, 362, 235, 127, 51, -188, -172, -289, +-238, -84, -225, 242, -176, 330, -23, 72, +229, -131, 203, -127, -17, -60, -236, -48, +-219, -131, -25, -154, 62, -16, 141, 168, +71, 275, -78, 215, -251, 82, -177, -48, +79, -67, 146, -88, -49, -290, -249, -346, +-126, -10, 68, 413, 221, 429, 151, -20, +-59, -353, -241, -324, -318, 51, -148, 485, +139, 444, 292, 12, 161, -485, -134, -554, +-350, -138, -177, 390, 112, 425, 20, 71, +-29, -362, 18, -395, 87, 23, 88, 432, +-160, 508, -214, 93, -76, -311, 160, -325, +133, -49, -231, 129, -365, -63, -43, -357, +317, -315, 250, 174, -76, 654, -155, 576, +-27, 67, -24, -301, -250, -394, -345, -240, +8, -106, 337, 11, 409, 146, 80, 186, +-402, 122, -463, -82, -185, -220, 176, -48, +281, 310, 172, 343, -42, 16, -182, -332, +-180, -352, -56, 39, 106, 191, -77, 101, +-141, -158, -46, -305, 99, 11, 125, 495, +-59, 639, -106, 38, 51, -745, 199, -843, +-115, -46, -471, 817, -282, 795, 307, 25, +444, -762, -99, -625, -491, 48, -145, 509, +571, 408, 533, 52, -293, -200, -896, -295, +-603, -105, 261, 141, 677, 170, 419, -6, +61, -117, -176, -65, -360, 68, -478, 216, +-290, 97, 249, -145, 511, -325, 267, -193, +-212, 224, -374, 460, -151, 213, 128, -254, +230, -337, -77, -183, -307, 13, -199, 154, +120, 223, 269, 136, 127, 45, 8, -3, +-153, -141, -298, -236, -154, -237, 208, 42, +287, 254, -210, 250, -616, 36, -194, -83, +678, -92, 806, -70, 3, 69, -671, 67, +-697, 28, -273, -149, 242, -166, 598, -16, +371, 221, -245, 255, -632, -34, -303, -246, +405, -370, 565, 16, 231, 486, -362, 610, +-649, 107, -426, -686, 154, -861, 541, -190, +397, 745, 33, 799, -330, 55, -320, -627, +-160, -519, -30, 105, 115, 498, 178, 387, +57, -198, -144, -507, -150, -164, 146, 397, +350, 549, -23, 52, -522, -640, -491, -786, +87, -223, 452, 662, 232, 1112, -142, 594, +-167, -516, 22, -1189, 83, -718, 121, 335, +-122, 1076, -231, 789, -143, -319, -52, -1026, +151, -838, 221, 227, 27, 1088, -260, 838, +-266, -234, 4, -978, 287, -716, 271, 154, +92, 941, -57, 730, -352, -160, -490, -792, +-248, -675, 274, 14, 566, 565, 318, 651, +-215, 69, -627, -554, -349, -632, 395, -123, +834, 553, 304, 807, -765, 448, -988, -390, +-281, -912, 632, -809, 830, -54, 213, 844, +-252, 939, -553, 275, -369, -646, 89, -934, +345, -214, 323, 733, -36, 898, -355, -28, +-369, -895, 9, -716, 302, 251, 249, 890, +66, 499, -117, -350, -300, -771, -267, -348, +-13, 256, 301, 505, 457, 230, 99, -70, +-419, -94, -523, -35, -119, -13, 291, -149, +275, -258, -51, -95, -117, 337, 79, 453, +136, 86, -17, -404, -130, -443, -79, -6, +-122, 362, -121, 428, -96, 26, 30, -337, +222, -518, 227, -159, 138, 414, -140, 694, +-404, 354, -284, -461, 286, -762, 608, -558, +73, 279, -661, 809, -720, 603, 75, -56, +660, -682, 443, -619, -135, -40, -247, 664, +27, 684, 2, 40, -84, -732, -202, -767, +-114, -114, 49, 556, 218, 825, 165, 402, +-110, -272, -150, -777, -146, -466, 23, 71, +88, 394, 82, 329, 93, 46, 19, -115, +-115, -177, -163, 60, -64, 134, -68, 144, +111, -47, 189, -231, 87, -320, -187, -176, +-408, 279, -130, 425, 343, 292, 491, -203, +25, -380, -358, -88, -314, 223, 110, 283, +334, -4, -56, -262, -451, -325, -358, -87, +230, 155, 535, 235, 247, 216, -191, 137, +-283, -100, -99, -254, -9, -22, -44, 61, +-29, -27, 275, -99, 252, -41, -228, 102, +-548, 111, -233, -11, 339, -10, 594, 152, +245, 141, -417, -61, -566, -471, -279, -484, +280, 190, 655, 756, 330, 604, -237, -213, +-625, -705, -507, -530, 146, 69, 630, 564, +539, 476, -171, -48, -671, -521, -381, -347, +176, 71, 427, 291, 189, 141, -62, -48, +-108, 81, -56, 111, 57, 114, 83, -93, +-82, -398, -204, -375, -190, 44, -180, 452, +-28, 392, 213, 67, 519, -349, 416, -520, +-45, -235, -451, 410, -621, 836, -149, 491, +453, -115, 467, -825, -146, -999, -774, -403, +-375, 491, 555, 1098, 920, 625, 310, -294, +-597, -686, -679, -403, -155, 185, 462, 601, +511, 387, -62, -223, -572, -690, -551, -581, +-29, 89, 450, 621, 621, 664, 306, 111, +-231, -516, -570, -747, -437, -241, 320, 629, +705, 884, 238, 369, -625, -447, -975, -881, +-275, -737, 805, 14, 1112, 798, 336, 936, +-640, 263, -1095, -711, -529, -1044, 596, -421, +1166, 741, 603, 1178, -645, 577, -1194, -561, +-549, -1259, 616, -758, 995, 420, 308, 1099, +-589, 766, -853, -240, -213, -1090, 655, -881, +902, 202, 363, 997, -474, 1020, -884, 136, +-589, -756, 46, -978, 624, -523, 570, 387, +92, 919, -377, 650, -430, -197, 37, -977, +464, -901, 483, 193, -97, 1336, -706, 1229, +-718, -182, -54, -1486, 661, -1299, 673, 21, +243, 1167, -350, 1206, -582, 237, -201, -875, +262, -1074, 480, -284, 166, 676, -331, 852, +-604, 208, -327, -421, 293, -597, 640, -226, +577, 249, -85, 477, -638, 282, -501, -254, +18, -415, 381, -225, 214, 115, -42, 376, +-150, 268, -167, 24, 11, -249, 260, -275, +246, -146, -56, -52, -308, 150, -227, 348, +17, 334, 107, -160, 160, -492, 220, -319, +-17, 245, -162, 644, -190, 358, -156, -492, +20, -953, 102, -370, 311, 596, 248, 1023, +-55, 430, -327, -478, -429, -857, -111, -445, +188, 397, 406, 881, 294, 470, -48, -503, +-167, -1001, -302, -512, -227, 421, 27, 853, +321, 534, 205, -220, -154, -621, -164, -280, +43, 300, 124, 423, -19, 54, -60, -379, +-60, -417, 86, -54, 98, 297, -91, 329, +-179, 20, -131, -136, 171, -63, 223, 28, +-27, 8, -193, -20, 17, 38, 284, 100, +155, 23, -189, -118, -406, -174, -222, -174, +99, -17, 367, 155, 251, 298, -62, 231, +-216, -71, -203, -244, 61, -174, 267, 37, +204, 133, -68, 76, -381, -119, -379, -169, +63, -75, 445, 147, 366, 258, 46, 49, +-327, -12, -390, -12, -180, -45, 142, -320, +314, -419, 349, 12, 238, 634, -205, 891, +-504, 219, -477, -735, 14, -1197, 496, -591, +443, 683, -26, 1229, -383, 601, -240, -549, +157, -934, 341, -285, 133, 489, -200, 504, +-371, -39, -161, -391, 132, -174, 272, 266, +213, 375, -22, -1, -249, -447, -253, -493, +29, -52, 231, 615, 183, 792, -87, 183, +-205, -640, 70, -993, 179, -484, -5, 555, +-81, 1207, -186, 833, -98, -474, -32, -1411, +51, -940, 299, 379, 240, 1241, 31, 870, +-213, -172, -253, -853, -208, -741, -52, -55, +167, 568, 227, 663, 238, 187, 43, -341, +-212, -525, -289, -408, -57, 121, 155, 621, +151, 511, 9, -122, -163, -721, -100, -618, +14, 124, 309, 879, 331, 805, -117, -74, +-450, -841, -462, -810, -34, -49, 427, 625, +525, 715, 264, 77, -259, -632, -553, -724, +-294, -67, 205, 852, 434, 895, 115, 3, +-278, -858, -336, -968, 77, -114, 551, 867, +398, 1017, -171, 99, -658, -968, -537, -1103, +5, -161, 489, 1026, 551, 1073, 149, 158, +-193, -780, -332, -725, -148, 86, 33, 528, +139, 253, 183, -348, -21, -440, -312, -65, +-266, 293, 174, 270, 459, 76, 262, 12, +-275, 18, -527, -26, -169, -233, 454, -166, +644, 134, 74, 263, -681, -1, -733, -306, +-32, -287, 678, 166, 739, 437, 76, 228, +-582, -206, -614, -484, -159, -206, 402, 365, +591, 614, 313, 172, -241, -484, -614, -675, +-539, -204, 78, 444, 711, 617, 603, 217, +17, -343, -602, -497, -589, -223, -92, 211, +348, 392, 440, 296, 203, 7, -72, -346, +-329, -465, -204, -128, 44, 478, 258, 623, +136, 80, -264, -583, -297, -766, 44, -158, +312, 681, 210, 834, -18, 163, -198, -643, +-131, -776, 1, -142, 122, 705, 170, 782, +-29, 86, -165, -716, -107, -910, -5, -127, +46, 696, -3, 793, -7, 83, 74, -567, +131, -519, 94, 33, -48, 520, -79, 373, +-33, -161, 3, -495, -23, -234, -172, 196, +-164, 276, -45, 36, 202, -189, 375, -87, +222, 34, -53, 118, -246, 206, -219, 211, +-136, 43, -61, -359, 51, -584, 171, -308, +116, 341, -19, 829, -34, 533, -50, -220, +34, -693, 73, -547, 44, -40, -78, 386, +-215, 434, -84, 125, 126, -139, 303, -164, +96, 49, -250, 180, -280, -56, -108, -336, +128, -362, 199, 33, 187, 504, 228, 432, +46, -40, -329, -427, -455, -282, -173, 116, +195, 313, 330, 170, 237, -117, 56, -287, +-169, -206, -284, 20, -157, 184, 157, 235, +356, 87, 95, -107, -186, -225, -263, -111, +-123, 255, 119, 343, 204, 46, 104, -407, +-99, -477, -276, -4, -108, 445, 252, 432, +291, -155, 87, -550, -260, -267, -178, 390, +24, 765, 12, 327, 58, -387, -12, -766, +-12, -514, -189, 152, -192, 466, 186, 375, +527, 29, 448, -146, -222, -16, -722, 53, +-570, -57, 106, -238, 656, -123, 532, 257, +-110, 449, -551, 106, -397, -525, 44, -667, +410, -160, 399, 595, 181, 816, -133, 236, +-496, -528, -441, -764, -11, -200, 476, 473, +441, 645, -91, 245, -462, -335, -290, -563, +267, -328, 488, 96, 171, 310, -346, 256, +-433, 162, -84, 58, 232, -60, 264, -256, +8, -307, -96, -54, -73, 230, -78, 296, +-66, 132, 103, -134, 271, -262, 105, -103, +-171, 80, -306, 128, -130, -14, 86, -82, +112, -22, 64, 45, 72, 117, 108, 100, +41, 91, -68, -7, -192, -102, -121, -204, +7, -238, 9, -58, -13, 115, 16, 252, +140, 172, 161, 32, 59, -48, -92, -65, +-98, 51, -37, 21, -54, -170, -149, -307, +-99, -144, 111, 235, 274, 372, 151, 250, +-170, -89, -229, -385, 15, -281, 283, 57, +75, 413, -223, 293, -254, -99, 28, -309, +264, -314, 35, -10, -139, 234, -162, 259, +57, 40, 238, -240, 101, -150, -35, 66, +-218, 244, -182, 181, 55, -26, 155, -185, +108, -253, -100, -130, -177, 41, -1, 232, +110, 213, 107, 51, 15, -114, -76, -150, +-41, 27, -34, 102, -30, 10, -48, -121, +-58, -120, 107, -16, 196, 180, 35, 253, +-198, 101, -187, -221, 135, -420, 244, -235, +-149, 176, -377, 462, -83, 338, 490, 12, +562, -332, -156, -369, -662, -57, -583, 246, +128, 255, 676, -60, 438, -278, -107, -210, +-492, 69, -282, 332, 130, 360, 377, 140, +229, -172, -186, -416, -428, -464, -339, -214, +109, 258, 393, 624, 320, 561, 58, 18, +-129, -551, -123, -578, -178, -163, -104, 355, +-13, 461, 76, 90, 97, -304, -97, -374, +-53, -30, 127, 376, 221, 391, 65, 46, +-255, -331, -316, -394, -113, -71, 249, 298, +416, 374, 153, 76, -257, -273, -470, -389, +-255, -181, 237, 156, 446, 373, 172, 242, +-168, -129, -310, -263, -89, -81, 223, 267, +206, 350, -28, -4, -283, -413, -213, -529, +71, -235, 285, 232, 174, 521, -137, 428, +-263, 108, -160, -236, 97, -361, 256, -206, +248, 69, 21, 228, -168, 164, -362, -4, +-311, -209, 72, -272, 407, -170, 462, 113, +41, 336, -432, 325, -557, 91, -86, -199, +483, -270, 595, -99, 126, 180, -524, 244, +-643, -118, -240, -442, 380, -341, 602, 150, +320, 560, -127, 482, -432, 22, -378, -452, +-70, -394, 324, 55, 422, 319, 44, 141, +-454, -230, -478, -291, -17, -119, 477, 152, +584, 298, 225, 214, -290, 2, -661, -149, +-471, -125, 116, -62, 547, 21, 435, 85, +-120, 70, -475, -111, -308, -262, 223, -172, +503, 161, 286, 389, -253, 319, -497, -11, +-222, -343, 101, -293, 201, 6, 90, 258, +106, 161, 146, -109, -77, -296, -348, -205, +-307, 83, 124, 311, 507, 298, 305, 31, +-185, -146, -403, -142, -212, -94, 142, -85, +214, -31, 7, 69, -173, 112, -135, 59, +77, -2, 232, -48, 200, -101, -17, 19, +-245, 90, -270, 69, -85, -66, 173, -134, +279, -16, 50, 96, -194, 202, -152, 85, +-10, -182, 195, -303, 113, -94, -127, 253, +-185, 208, -133, -33, 119, -176, 177, -9, +93, 205, -19, 125, -86, -135, 3, -373, +-29, -88, -167, 306, -178, 366, 7, 32, +245, -394, 302, -242, 23, 133, -224, 332, +-254, 138, -40, -255, 164, -361, 65, -84, +-69, 255, -11, 297, 163, 60, 91, -10, +-184, 44, -219, -41, -10, -224, 117, -317, +56, -122, -84, 126, -44, 323, 151, 283, +198, 62, 18, -177, -186, -254, -176, -12, +-20, 103, 39, 110, -55, -11, -131, -167, +50, -155, 228, 40, 179, 218, -13, 157, +-250, -55, -95, -151, 169, -6, 185, 101, +-91, 50, -444, -106, -290, -190, 126, -18, +496, 223, 476, 232, 12, -68, -420, -362, +-513, -204, -119, 296, 284, 465, 315, 118, +152, -464, -80, -596, -297, -68, -260, 595, +100, 685, 447, 73, 366, -654, -236, -701, +-647, -108, -500, 509, 103, 665, 741, 213, +641, -372, 24, -608, -557, -193, -497, 403, +-20, 549, 241, 160, 199, -464, -122, -649, +-279, -356, -101, 299, 228, 770, 446, 641, +271, 11, -182, -633, -471, -667, -302, -172, +119, 387, 365, 438, 94, 81, -341, -250, +-339, -290, 7, -36, 424, 251, 478, 337, +141, 139, -320, -232, -598, -447, -273, -213, +237, 202, 468, 510, 304, 291, -170, -230, +-432, -537, -316, -385, 35, 192, 417, 508, +354, 313, -24, -194, -255, -384, -188, -86, +36, 244, 112, 325, -10, -24, -215, -312, +-211, -352, 127, -89, 417, 357, 298, 477, +-60, 182, -457, -274, -458, -542, -113, -390, +258, 98, 496, 487, 294, 513, -37, 122, +-260, -309, -243, -288, -86, -31, -10, 126, +-37, -59, -98, -297, -44, -253, 114, 85, +164, 394, 192, 410, 285, 146, 164, -166, +-59, -137, -455, -118, -694, -128, -401, -220, +240, -219, 765, 80, 523, 281, -100, 367, +-422, 141, -246, -121, 77, -247, 152, -143, +91, 47, 1, 50, -92, 99, -147, 42, +-73, -20, 13, -98, 23, -123, -14, -41, +-76, -14, -7, 8, 135, 49, 235, 175, +200, 272, 72, 193, -165, -70, -346, -366, +-308, -434, -132, -166, 131, 164, 187, 298, +96, 159, 23, -38, 73, -71, 171, 44, +97, 201, -105, 144, -286, -64, -205, -231, +86, -260, 193, -151, -8, -39, -217, 164, +-168, 290, 111, 157, 329, -105, 222, -166, +-115, 19, -346, 146, -223, 112, 154, -92, +350, -226, 202, -153, -130, 88, -343, 263, +-332, 79, -75, -196, 261, -241, 318, 40, +128, 250, -199, 174, -255, 1, 43, -123, +275, -57, 220, -19, -116, -9, -310, -35, +-234, -27, -135, 30, 89, -21, 310, -8, +301, 11, -36, 93, -419, 124, -254, 32, +237, -78, 540, -166, 242, -94, -434, -15, +-749, 101, -304, 90, 500, 43, 764, 59, +257, -16, -486, -82, -654, -81, -163, 28, +383, 72, 516, -13, 182, -123, -258, -143, +-431, 20, -305, 222, 57, 333, 434, 156, +469, -229, -26, -423, -598, -252, -610, 79, +48, 298, 740, 260, 660, 60, -11, -149, +-682, -247, -629, -137, 21, 44, 487, 235, +387, 195, -165, -68, -379, -204, -137, -117, +224, 165, 381, 246, 133, 83, -224, -202, +-410, -398, -209, -289, 173, 62, 334, 487, +186, 459, -155, 75, -287, -314, -112, -365, +155, -67, 273, 157, 85, 212, -162, -9, +-265, -176, -192, -198, 110, -69, 339, 138, +243, 238, -127, 219, -377, 56, -194, -174, +112, -279, 272, -110, 114, 118, -123, 233, +-199, 57, -30, -206, 193, -286, 155, -97, +-15, 226, -190, 377, -178, 301, -56, -66, +103, -348, 208, -424, 122, -62, -143, 321, +-308, 302, -118, 3, 260, -337, 379, -193, +24, 157, -262, 355, -235, 144, 45, -249, +158, -314, -81, -54, -155, 225, -27, 187, +159, 15, 149, -66, -67, -51, -80, -61, +69, -113, 181, -80, 30, 42, -255, 89, +-289, 72, -38, 52, 240, 95, 221, 137, +-45, 15, -235, -222, -107, -316, 120, -146, +291, 129, 202, 254, -95, 129, -319, 8, +-356, -44, -43, -60, 261, -72, 351, -57, +59, 55, -287, 82, -227, 63, -8, -22, +222, -41, 215, -6, 76, -15, -54, -109, +-242, -167, -239, -8, -70, 166, 151, 245, +225, 115, 62, -79, -49, -147, -91, -115, +-34, -11, 10, 36, 10, 50, 62, -1, +61, -6, -49, -8, -173, -50, -100, -33, +82, 49, 116, 135, -28, 102, -144, -56, +7, -166, 262, -128, 231, 37, -141, 210, +-426, 221, -227, 9, 220, -257, 415, -310, +99, -143, -264, 71, -261, 269, -84, 317, +59, 159, 147, -139, 266, -347, 246, -206, +-68, 110, -420, 323, -439, 171, -86, -215, +354, -394, 480, -158, 197, 345, -299, 504, +-521, 135, -173, -421, 332, -563, 444, -142, +108, 488, -263, 666, -318, 153, -78, -477, +108, -681, 183, -240, 91, 381, -88, 632, +-184, 299, -151, -270, 91, -580, 236, -331, +195, 272, 8, 563, -212, 327, -195, -321, +-29, -625, 116, -266, 124, 383, -93, 652, +-190, 208, -17, -406, 190, -582, 217, -219, +46, 283, -98, 496, -157, 263, -183, -129, +-85, -359, 157, -293, 285, -6, 139, 260, +-161, 322, -288, 78, -198, -294, -17, -407, +197, -63, 299, 378, 203, 497, -48, 130, +-226, -349, -270, -529, -119, -281, 116, 161, +224, 392, 79, 332, -164, 76, -128, -146, +109, -252, 255, -201, 30, 26, -285, 216, +-268, 178, 26, -77, 310, -301, 242, -177, +-45, 182, -219, 403, -142, 253, -6, -171, +52, -411, 59, -358, 38, -20, 32, 314, +-57, 389, -69, 178, 6, -140, 147, -262, +147, -202, -85, 10, -238, 114, -182, 78, +68, -16, 230, -54, 150, 47, -39, 103, +-97, 28, -105, -119, -56, -97, 16, 17, +35, 84, 78, 33, 47, -55, 5, -26, +-41, 96, -49, 152, -20, 31, -35, -210, +-48, -288, -17, -92, 69, 169, 113, 257, +65, 148, -2, 12, -50, -44, -140, -44, +-183, -117, -62, -158, 122, -91, 250, 90, +162, 228, -14, 133, -138, -41, -162, -189, +-79, -128, -40, 45, 34, 146, 64, 64, +82, -96, 51, -96, -46, 56, -43, 172, +49, 74, 116, -108, -16, -188, -170, -81, +-179, 96, 32, 135, 182, 20, 114, -67, +-23, -97, -120, -35, -124, 54, -75, 129, +101, 167, 232, 48, 159, -122, -102, -279, +-259, -137, -131, 160, 125, 269, 246, 55, +49, -257, -258, -229, -364, 19, -43, 224, +416, 161, 434, 8, -19, -39, -367, 3, +-198, 89, 180, 2, 235, -191, -100, -274, +-305, -148, -184, 110, 68, 289, 211, 279, +154, 102, 62, -216, -31, -326, -20, -94, +-7, 254, -27, 332, -56, 17, -82, -272, +-12, -292, -28, -27, -59, 218, -38, 163, +71, -90, 183, -218, 150, -18, 34, 261, +-101, 315, -146, 42, -90, -296, 10, -341, +60, -78, 12, 240, -64, 279, -104, 4, +-14, -281, 102, -312, 186, -27, 200, 359, +13, 496, -208, 195, -314, -328, -136, -527, +180, -243, 261, 188, 29, 365, -162, 138, +-85, -218, 103, -288, 152, 9, -19, 334, +-140, 308, -86, -34, 51, -341, 100, -288, +68, 10, -22, 239, -107, 224, -105, -45, +-20, -220, 99, -155, 101, 97, -16, 243, +-72, 132, -8, -61, 70, -230, 88, -172, +44, 14, -53, 204, -171, 225, -176, 37, +-35, -205, 136, -327, 195, -153, 126, 204, +-23, 449, -135, 283, -110, -149, 30, -435, +146, -294, 26, 88, -132, 313, -142, 198, +-29, -119, 60, -292, 59, -153, 78, 165, +95, 334, 79, 218, -18, -54, -122, -252, +-96, -216, 7, -34, -18, 77, -152, 30, +-151, -111, 144, -107, 414, 125, 294, 357, +-126, 316, -416, -83, -296, -425, 51, -323, +309, 86, 179, 348, -121, 164, -220, -247, +-119, -427, 96, -152, 229, 299, 258, 515, +114, 280, -259, -146, -481, -361, -278, -229, +239, 52, 527, 171, 321, 43, -188, -105, +-513, -104, -299, 22, 154, 91, 427, -16, +251, -53, -59, 64, -260, 250, -250, 177, +-9, -139, 219, -326, 220, -226, -64, 113, +-272, 237, -189, 95, 60, -154, 256, -213, +251, -16, 84, 160, -135, 218, -227, 89, +-99, -50, 24, -125, 40, -92, -42, 6, +-82, 33, 10, -20, 161, -58, 246, -15, +74, 46, -204, 36, -277, -17, -69, 22, +193, 108, 228, 169, -3, 9, -278, -269, +-291, -339, 46, -65, 385, 349, 339, 424, +-77, 68, -361, -382, -248, -439, 83, -75, +338, 342, 237, 455, -117, 114, -393, -278, +-298, -374, 73, -110, 361, 168, 345, 158, +57, 36, -242, -59, -338, 7, -97, 120, +246, 80, 290, -56, -5, -197, -317, -180, +-316, -18, -6, 136, 342, 177, 444, 133, +183, 18, -290, -140, -543, -197, -304, -95, +211, 106, 522, 209, 313, 152, -229, -23, +-519, -190, -246, -240, 309, -117, 572, 108, +179, 274, -440, 285, -524, 22, -84, -253, +407, -321, 410, -90, 54, 221, -219, 245, +-291, 42, -196, -198, -14, -211, 242, -13, +275, 206, 99, 229, -156, 54, -219, -101, +-16, -104, 151, -26, 133, -38, -121, -125, +-282, -176, -143, -79, 137, 151, 311, 381, +199, 329, -52, 42, -187, -227, -159, -246, +-11, -131, 91, -88, 81, -84, 0, -85, +-51, 81, -39, 277, -2, 309, 14, 68, +-50, -256, -114, -254, -46, -6, 162, 208, +305, 179, 205, 11, -141, -142, -378, -237, +-298, -165, -3, 51, 245, 168, 245, 118, +29, -24, -193, -75, -192, 31, 76, 171, +352, 232, 277, 39, -115, -239, -500, -359, +-399, -226, 90, 48, 477, 216, 440, 240, +-22, 98, -434, -107, -422, -185, -39, -70, +354, 153, 421, 256, 105, 133, -287, -136, +-381, -340, -128, -265, 254, 5, 441, 241, +169, 272, -321, 132, -568, -97, -297, -260, +320, -171, 621, 53, 360, 219, -179, 141, +-449, -55, -283, -153, 75, -107, 281, 50, +124, 136, -114, 76, -172, -52, -30, -109, +85, -32, 95, 59, 121, 28, 79, -57, +-146, -124, -346, -86, -200, 28, 258, 179, +530, 298, 299, 224, -213, -13, -550, -342, +-422, -452, 39, -257, 388, 103, 362, 394, +121, 365, -115, 117, -253, -203, -230, -364, +2, -227, 286, 106, 317, 424, -16, 391, +-374, -59, -379, -498, -22, -503, 328, -16, +332, 489, 43, 497, -167, 39, -120, -458, +-31, -507, -11, -79, 46, 411, 117, 511, +10, 164, -163, -265, -163, -398, 35, -168, +199, 145, 121, 257, -15, 77, -84, -198, +-100, -216, 6, 5, 105, 222, 101, 209, +-38, -14, -201, -169, -190, -200, -12, -32, +235, 160, 300, 217, 80, 138, -162, -81, +-228, -201, -123, -238, 49, -117, 137, 43, +128, 179, -19, 236, -129, 112, -87, -59, +-5, -199, 68, -138, 92, 52, 110, 197, +-4, 140, -145, -69, -141, -250, -14, -215, +79, 58, 63, 300, 60, 266, 16, -75, +-21, -321, -73, -291, -91, 29, -24, 322, +85, 317, 158, 83, 61, -218, -87, -249, +-136, -62, -12, 119, 79, 51, -1, -144, +-88, -192, -62, -13, 62, 238, 185, 299, +132, 157, -80, -105, -193, -239, -112, -173, +74, -20, 147, 50, 28, 22, -122, 11, +-111, 42, 32, 40, 164, -21, 127, -52, +-77, -2, -179, 101, -94, 114, 76, 17, +176, -106, 63, -127, -130, 19, -207, 92, +10, -24, 266, -215, 183, -206, -129, 95, +-310, 375, -125, 371, 130, 12, 233, -326, +131, -298, -24, -10, -104, 194, -138, 22, +-76, -202, 26, -188, 116, 84, 96, 331, +-28, 245, -145, -36, -76, -258, 141, -163, +186, 126, 30, 226, -180, -23, -240, -315, +-34, -301, 215, 8, 268, 332, 86, 362, +-192, 104, -267, -232, -115, -312, 53, -87, +136, 174, 131, 228, 110, 83, 29, -122, +-66, -240, -105, -181, -106, 29, -81, 264, +-30, 257, 34, 7, 112, -243, 141, -241, +59, 71, 8, 327, -35, 221, -112, -205, +-163, -474, -102, -259, 84, 204, 223, 477, +149, 322, -55, -105, -146, -394, -85, -266, +-10, 130, 30, 311, 40, 99, 31, -190, +10, -247, -23, -40, 11, 157, 65, 180, +16, 26, -64, -132, -78, -73, 9, 87, +63, 136, -32, -10, -76, -151, -24, -126, +87, -36, 168, 55, 88, 106, -114, 81, +-182, 35, -34, -19, 111, -58, 66, -64, +-160, -18, -137, 61, 120, 72, 221, -14, +72, -103, -160, -72, -186, 46, 33, 123, +218, 82, 119, -40, -112, -102, -195, -63, +-60, 36, 90, 43, 49, -22, -72, -20, +-66, 27, 57, 71, 162, 46, 153, -29, +24, -54, -133, -39, -193, 13, -97, 26, +36, -59, 85, -121, 13, -59, -59, 159, +13, 307, 133, 202, 149, -121, -28, -412, +-188, -344, -152, 2, 18, 338, 197, 361, +200, 83, -9, -220, -262, -298, -312, -101, +-27, 170, 291, 283, 301, 155, 45, -138, +-195, -351, -210, -293, -17, 19, 192, 381, +196, 425, -8, 90, -205, -335, -208, -440, +-112, -77, 28, 352, 184, 420, 253, 13, +143, -444, -97, -491, -219, -63, -101, 459, +69, 552, 103, 123, 5, -406, -145, -460, +-134, -40, 48, 391, 234, 414, 191, 5, +-60, -416, -254, -481, -200, -132, 68, 286, +225, 392, 169, 183, -23, -69, -191, -112, +-153, -27, 0, 43, 149, 45, 152, -40, +-5, -150, -197, -207, -230, -135, -27, 55, +257, 267, 395, 323, 145, 143, -250, -170, +-422, -324, -200, -182, 194, 118, 325, 250, +110, 62, -177, -175, -237, -208, -54, 36, +168, 240, 184, 175, 41, -73, -82, -266, +-73, -175, 23, 87, 97, 273, 44, 166, +-105, -89, -234, -260, -222, -167, 43, 77, +343, 239, 376, 238, 64, 11, -303, -228, +-328, -317, -13, -135, 253, 155, 198, 314, +-21, 221, -179, -94, -216, -312, -138, -229, +23, 116, 220, 342, 283, 239, 88, -98, +-140, -338, -183, -222, 3, 81, 183, 255, +63, 122, -251, -118, -357, -177, -55, -10, +348, 149, 424, 142, 43, 0, -335, -139, +-327, -144, 17, -38, 304, 102, 242, 198, +19, 175, -166, -9, -220, -268, -134, -355, +35, -101, 188, 245, 143, 347, -79, 119, +-206, -195, -121, -265, 146, -52, 317, 256, +253, 334, -30, 77, -319, -250, -351, -362, +-116, -223, 167, 53, 244, 232, 126, 196, +-104, -5, -205, -132, -65, -18, 202, 151, +307, 165, 96, 19, -218, -116, -298, -171, +-88, -134, 146, -68, 177, -5, -2, 49, +-184, 118, -155, 195, 32, 123, 140, -55, +146, -200, 93, -163, 36, 20, 8, 171, +-56, 142, -109, -48, -102, -183, -90, -123, +-75, 83, -12, 201, 86, 103, 152, -135, +98, -277, -34, -148, -35, 179, 89, 395, +128, 254, 4, -121, -182, -375, -228, -279, +-101, 22, 29, 278, 87, 241, 60, -38, +32, -244, 60, -212, 108, 13, 91, 199, +2, 227, -76, 109, -86, -87, -29, -214, +-31, -176, -102, 12, -93, 163, 16, 145, +138, -19, 144, -162, 12, -144, -49, 24, +4, 193, 44, 166, 19, -15, -34, -163, +-82, -121, -38, 66, 37, 153, 22, 79, +-53, -109, -125, -250, -55, -175, 105, 69, +187, 289, 137, 288, -12, 77, -145, -162, +-110, -247, 54, -136, 139, 47, -14, 126, +-188, 38, -157, -104, 25, -122, 143, 14, +104, 174, 18, 216, -27, 87, -16, -91, +-8, -178, 20, -109, 30, -6, 42, 22, +18, -23, -72, -58, -143, -4, -114, 86, +-3, 133, 117, 94, 163, 42, 108, -12, +7, -81, -84, -165, -95, -173, -70, -35, +4, 115, 100, 170, 104, 104, -15, -4, +-146, -70, -123, -77, -17, -42, 76, 9, +137, 59, 108, 95, -13, 43, -168, -92, +-117, -159, 146, -71, 270, 74, 79, 114, +-235, 51, -363, -2, -193, -3, 167, 3, +358, -15, 238, -40, -47, -40, -222, 2, +-123, 43, 1, 28, 56, -53, 67, -89, +48, -30, -1, 78, -47, 143, -50, 96, +-39, -11, 7, -131, 32, -158, 30, -75, +0, 52, 4, 147, 56, 107, 68, -15, +-23, -115, -97, -106, -52, 13, 27, 108, +77, 108, 18, 14, -95, -88, -116, -109, +-33, -58, 110, 9, 218, 32, 140, 78, +-46, 96, -214, 39, -203, -64, 38, -142, +207, -76, 105, 66, -91, 158, -155, 81, +-46, -77, 51, -165, 68, -84, 44, 90, +17, 143, 26, 52, 24, -80, 27, -105, +-15, -20, -32, 83, -50, 94, -121, 11, +-135, -96, 5, -124, 197, -58, 216, 46, +63, 118, -96, 115, -96, 51, -18, -59, +34, -99, 19, -48, -56, 65, -101, 86, +-64, -50, 33, -208, 113, -192, 93, 42, +-20, 280, -85, 309, -19, 90, 109, -163, +104, -235, -30, -72, -127, 91, -88, 71, +-5, -101, 12, -211, 2, -110, 13, 102, +70, 285, 113, 300, 85, 103, -49, -181, +-170, -333, -126, -234, 52, 49, 198, 259, +126, 188, -98, -89, -229, -288, -107, -191, +163, 124, 262, 334, 52, 239, -223, -55, +-237, -242, 2, -131, 200, 76, 187, 121, +10, -52, -104, -223, -63, -168, 23, 81, +58, 308, -9, 271, -87, 22, -93, -197, +-60, -203, 4, -59, 85, 52, 98, 53, +59, -2, 15, -12, 11, 5, 31, 26, +18, 32, -56, -1, -127, -32, -131, -32, +-24, 32, 110, 115, 107, 93, 13, -75, +-16, -260, 54, -238, 77, 40, 12, 322, +-69, 315, -59, 17, 26, -269, 47, -247, +-53, 37, -190, 242, -183, 148, 27, -99, +224, -215, 203, -86, 58, 92, -28, 130, +1, 28, -5, -70, -89, -26, -132, 47, +-90, 56, 0, -3, 71, -50, 121, -22, +114, 16, 17, 26, -113, 12, -157, -11, +-7, -57, 171, -85, 156, -70, -51, -17, +-188, 83, -88, 174, 96, 153, 157, 20, +18, -113, -131, -154, -145, -104, -10, 11, +146, 89, 157, 77, 48, -48, -70, -168, +-72, -110, -2, 96, 46, 280, 11, 229, +-74, -28, -97, -257, -23, -214, 51, 35, +57, 207, 31, 121, 16, -155, 27, -311, +-12, -174, -6, 152, 20, 368, 2, 264, +-23, -27, -10, -205, 4, -160, -27, 1, +-35, 59, 6, -19, 64, -133, 37, -114, +26, 68, 41, 206, -10, 193, -69, 12, +-62, -136, -3, -167, 17, -83, -2, 37, +-18, 113, -22, 105, -1, 0, 59, -73, +116, -81, 76, -18, -42, 46, -92, 19, +-51, -54, 33, -66, 51, 19, -41, 93, +-91, 61, 42, 12, 198, 24, 121, 53, +-131, -17, -245, -188, -71, -269, 132, -104, +131, 229, 3, 399, -77, 198, -37, -169, +98, -328, 108, -156, -58, 153, -194, 260, +-92, 85, 132, -176, 167, -274, 22, -119, +-97, 120, -40, 242, 51, 170, 69, -1, +16, -126, -66, -108, -75, 5, -3, 79, +52, 61, 29, -25, -53, -106, -139, -139, +-104, -90, 41, 47, 212, 174, 221, 193, +31, 86, -118, -45, -94, -74, -13, -45, +23, -30, -2, -84, -45, -180, -31, -155, +-14, 25, 2, 229, -1, 271, 59, 110, +195, -78, 192, -137, -24, -71, -239, -8, +-220, -2, -63, -49, 51, -74, 121, -7, +108, 55, 1, 74, -115, 24, -90, -33, +72, -36, 174, 8, 135, 68, 30, 67, +-42, 32, -90, -29, -58, -81, -6, -112, +-38, -103, -104, -40, -107, 82, 18, 160, +155, 136, 196, 28, 116, -110, -42, -140, +-170, -46, -165, 73, -6, 99, 161, 3, +166, -81, 21, -46, -171, 36, -192, 79, +-18, 37, 115, -46, 118, -120, 31, -111, +10, -20, 78, 92, 83, 169, -18, 141, +-104, 19, -95, -129, -3, -134, 47, -14, +-65, 88, -163, 10, -94, -183, 89, -220, +227, -15, 186, 290, 36, 391, -74, 147, +-81, -182, -10, -283, 40, -137, -13, 59, +-107, 71, -54, -50, 77, -136, 91, -56, +-19, 125, -121, 217, -40, 149, 136, -36, +181, -143, 78, -141, -80, -53, -165, 50, +-112, 112, -38, 103, 9, -15, 56, -147, +79, -194, 40, -80, -12, 133, -5, 254, +72, 195, 109, -15, 6, -176, -114, -159, +-124, -35, 3, 77, 106, 70, 71, -29, +-62, -97, -133, -62, -70, 17, 29, 105, +135, 145, 157, 91, 39, -35, -135, -150, +-186, -124, -13, -17, 184, 55, 132, 29, +-60, -13, -149, 7, -71, 56, 62, 71, +114, -4, 110, -87, 65, -73, -29, 33, +-148, 89, -146, 25, 3, -72, 152, -80, +114, 45, -73, 140, -190, 62, -109, -130, +91, -237, 194, -110, 137, 159, -28, 322, +-139, 215, -77, -73, 27, -289, 78, -243, +75, 4, 5, 200, -77, 152, -121, -49, +-14, -199, 179, -136, 194, 95, -45, 255, +-238, 224, -139, -2, 115, -213, 231, -239, +63, -71, -178, 104, -228, 125, -30, -5, +176, -140, 165, -92, -23, 75, -110, 221, +-16, 196, 79, 22, 86, -155, 18, -199, +-10, -105, 0, 33, 12, 88, -47, 14, +-105, -54, -107, -47, 2, 43, 156, 132, +127, 147, -1, 50, -110, -102, -102, -186, +9, -142, 95, -15, 64, 135, 0, 171, +-3, 65, 22, -96, 2, -194, -80, -91, +-105, 88, -28, 169, 99, 54, 165, -97, +127, -98, -2, 71, -77, 198, -31, 119, +12, -95, -81, -294, -206, -260, -141, -38, +79, 193, 231, 263, 185, 148, 42, -16, +-89, -90, -138, -47, -61, 22, 28, 8, +65, -82, 63, -140, 40, -92, 9, 54, +-64, 129, -67, 82, 16, -18, 115, -31, +123, 64, 3, 124, -148, 28, -204, -150, +-43, -237, 178, -139, 225, 109, 27, 272, +-218, 195, -278, -80, -72, -286, 257, -194, +392, 114, 172, 314, -205, 173, -335, -154, +-106, -327, 169, -140, 215, 201, 50, 311, +-179, 71, -213, -253, 5, -298, 277, -42, +284, 233, -23, 260, -281, 55, -251, -123, +-4, -144, 161, -37, 139, 41, 2, 20, +-133, -4, -127, -22, 14, -67, 182, -77, +213, 10, 52, 181, -161, 274, -191, 134, +23, -186, 229, -400, 169, -257, -112, 124, +-288, 343, -177, 152, 75, -193, 247, -275, +184, 26, -42, 377, -242, 354, -204, -64, +85, -459, 324, -399, 266, 28, -35, 369, +-315, 317, -316, -54, -85, -364, 165, -296, +282, 64, 217, 406, 66, 411, -124, 73, +-207, -312, -106, -447, 92, -241, 179, 125, +39, 349, -150, 236, -154, -64, 20, -257, +121, -156, 55, 88, -93, 238, -102, 143, +28, -65, 121, -177, 92, -117, 4, 31, +-21, 71, 1, 14, 0, -57, -21, -22, +-11, 60, 7, 96, -6, 29, -43, -77, +-14, -75, 48, 10, 94, 77, 83, 32, +-20, -88, -127, -144, -143, -43, -27, 136, +103, 227, 98, 97, 26, -125, -18, -206, +-41, -88, -56, 72, -36, 100, 62, 6, +152, -100, 116, -61, -29, 68, -147, 147, +-146, 90, 38, -18, 226, -78, 203, -64, +-44, -54, -313, -84, -314, -63, -77, 39, +234, 168, 359, 175, 188, 11, -131, -179, +-314, -181, -200, -5, 90, 166, 280, 147, +210, -26, -41, -143, -266, -101, -186, 53, +134, 144, 363, 92, 218, -57, -187, -158, +-454, -154, -317, -69, 115, 64, 427, 211, +376, 256, 17, 115, -325, -126, -355, -295, +-75, -208, 216, 25, 267, 171, 51, 102, +-212, -75, -217, -110, 20, 47, 281, 220, +331, 190, 79, -16, -236, -220, -360, -253, +-208, -110, 94, 39, 255, 127, 203, 149, +41, 130, -107, 69, -165, -46, -105, -148, +7, -149, 100, -32, 104, 110, 28, 139, +-26, 33, -47, -106, -36, -135, -10, -10, +26, 111, 31, 111, 10, -21, -5, -129, +46, -85, 125, 56, 121, 136, -10, 72, +-162, -80, -207, -174, -114, -82, 55, 91, +121, 187, 94, 93, 36, -96, 14, -184, +30, -83, 16, 112, -28, 207, -61, 95, +-66, -113, -68, -204, -30, -130, 53, 26, +165, 109, 185, 101, 45, 42, -149, -20, +-195, -45, -43, -27, 114, 36, 112, 111, +-3, 81, -70, -100, -39, -271, 12, -233, +37, 60, 43, 325, -16, 305, -100, 13, +-119, -243, -25, -208, 139, 35, 222, 195, +108, 79, -115, -146, -205, -225, -49, -67, +180, 132, 184, 180, -35, 86, -194, -6, +-149, -18, 27, 8, 144, -11, 93, -70, +-35, -98, -120, -61, -86, -8, 18, 13, +92, 56, 102, 115, 94, 156, 22, 72, +-129, -122, -201, -260, -104, -189, 116, 55, +231, 234, 128, 184, -50, -13, -102, -118, +-26, -58, 76, 55, 70, 58, -51, -53, +-129, -136, -127, -88, -47, 34, 54, 106, +104, 105, 79, 77, 39, 62, 16, 21, +9, -76, -22, -180, -105, -202, -120, -99, +-21, 67, 131, 189, 215, 192, 136, 98, +-37, 0, -143, -62, -98, -57, -7, -30, +9, -58, -60, -103, -92, -111, -6, -22, +99, 118, 158, 169, 108, 100, -31, -25, +-158, -85, -149, -38, 11, 52, 154, 59, +141, -66, -24, -161, -154, -121, -121, 19, +61, 123, 203, 124, 167, 62, -23, 5, +-164, -12, -115, -4, 16, -3, 96, -17, +28, -52, -113, -104, -172, -122, -63, -52, +130, 125, 256, 251, 153, 192, -70, -39, +-178, -251, -96, -232, 87, -23, 126, 152, +-38, 122, -191, -15, -110, -65, 106, 24, +219, 112, 155, 60, 43, -82, -33, -139, +-120, -46, -193, 79, -148, 83, -32, -40, +78, -102, 144, -12, 120, 139, 29, 149, +-47, -19, -20, -192, 29, -185, -6, 3, +-86, 161, -47, 144, 53, -15, 68, -128, +10, -72, -58, 65, -30, 128, 60, 70, +115, -16, 74, -41, -30, -42, -93, -57, +-71, -100, -37, -116, -19, -48, -5, 73, +10, 190, 16, 205, 27, 126, 55, -31, +38, -188, -32, -235, -79, -150, -45, 11, +36, 112, 114, 91, 101, 30, 20, 49, +-55, 141, -48, 198, 9, 75, 13, -177, +-15, -369, -26, -321, -34, -60, -80, 185, +-62, 257, 55, 141, 164, 11, 131, -13, +-30, 38, -182, 57, -180, -36, -15, -168, +162, -206, 184, -71, 21, 160, -79, 309, +-29, 222, 74, -82, 84, -354, -7, -351, +-99, -58, -110, 287, -28, 376, 49, 147, +59, -179, -28, -311, -85, -122, -40, 162, +51, 263, 104, 101, 43, -165, -67, -280, +-98, -146, -16, 136, 93, 299, 119, 190, +59, -85, -29, -261, -79, -153, -62, 112, +34, 221, 118, 27, 53, -260, -83, -293, +-144, 2, -64, 345, 38, 382, 76, 88, +48, -220, -9, -282, -49, -77, -35, 121, +37, 90, 62, -110, -11, -237, -79, -107, +-38, 177, 40, 381, 71, 317, 61, 20, +62, -281, 42, -358, -13, -195, -56, 34, +-49, 127, -6, 70, -30, 3, -61, 40, +-52, 168, 13, 203, 86, 66, 43, -150, +-42, -260, -39, -189, 32, -50, 50, 20, +-26, 23, -100, 79, -25, 206, 138, 272, +177, 143, 56, -144, -130, -368, -198, -333, +-47, -68, 140, 237, 182, 345, 49, 219, +-116, -20, -132, -217, -43, -262, 4, -183, +-7, -32, -38, 99, -29, 146, 53, 134, +124, 108, 125, 105, 65, 91, -44, -1, +-149, -140, -163, -247, -64, -232, 114, -113, +214, 37, 145, 164, -6, 225, -141, 223, +-179, 117, -71, -57, 95, -219, 141, -270, +20, -180, -138, -28, -143, 107, 21, 178, +171, 207, 178, 199, 59, 135, -92, -7, +-161, -182, -149, -281, -85, -227, 6, -69, +104, 64, 170, 109, 118, 104, 20, 123, +-73, 122, -93, 50, -22, -105, 68, -231, +68, -192, -42, -28, -108, 142, -39, 202, +92, 179, 96, 145, -7, 94, -93, -14, +-128, -185, -82, -308, -4, -271, 20, -84, +-8, 111, -36, 172, 40, 120, 202, 50, +273, 30, 165, 55, -40, 56, -211, 17, +-220, -45, -81, -80, 37, -59, 61, 10, +-27, 74, -131, 38, -120, -75, -14, -162, +107, -114, 198, 73, 178, 220, 84, 192, +-33, 10, -166, -172, -217, -197, -149, -98, +18, -3, 159, 30, 224, 33, 164, 106, +75, 216, -17, 226, -96, 71, -89, -165, +-122, -282, -186, -210, -208, -68, -65, 16, +182, 24, 309, 44, 203, 111, -14, 159, +-135, 111, -109, -7, -10, -84, 35, -89, +-10, -49, -56, -32, -10, -21, 102, 32, +157, 93, 80, 109, -57, 12, -170, -109, +-167, -147, -77, -80, 24, 38, 67, 81, +50, 41, 62, -11, 114, -38, 121, -8, +12, 37, -142, 81, -199, 112, -62, 77, +126, 2, 168, -92, 23, -125, -127, -100, +-106, -66, 32, -56, 102, -58, 42, 0, +-45, 93, -91, 160, -30, 119, 35, 5, +62, -71, 67, -58, 72, 19, 60, 61, +9, 44, -46, 17, -64, 0, -46, 1, +-91, -21, -114, -100, -57, -173, 23, -191, +79, -118, 82, 15, 41, 153, 29, 259, +53, 259, 88, 155, 79, 2, -33, -112, +-150, -108, -157, -42, -51, -16, 72, -71, +126, -151, 65, -132, 2, 19, -25, 183, +-50, 203, -111, 53, -158, -165, -60, -267, +118, -175, 175, 13, 67, 174, -54, 223, +-33, 201, 115, 166, 202, 95, 112, -3, +-107, -116, -261, -200, -231, -225, -64, -220, +78, -154, 112, -13, 92, 155, 49, 250, +21, 184, -14, 18, -50, -105, -81, -96, +-81, 6, -15, 76, 77, 78, 143, 56, +128, 35, 46, 21, -45, -19, -83, -88, +-53, -152, -42, -169, -87, -112, -122, 0, +-30, 111, 118, 147, 148, 97, 79, 9, +1, -5, 11, 83, 27, 155, -49, 81, +-140, -131, -143, -300, -25, -245, 133, -12, +188, 219, 95, 262, -18, 118, -57, -74, +-44, -215, -90, -234, -189, -136, -162, 32, +57, 201, 282, 261, 313, 189, 135, 68, +-90, -14, -172, -36, -143, -93, -87, -217, +-35, -321, 15, -263, 60, -19, 34, 246, +-22, 332, -25, 195, 29, 7, 68, -73, +46, -10, -14, 70, -77, 46, -51, -78, +45, -192, 153, -165, 156, -6, 13, 166, +-130, 212, -182, 73, -98, -155, 21, -295, +29, -243, -103, -37, -159, 154, 30, 235, +339, 240, 421, 217, 80, 159, -363, 2, +-475, -210, -134, -339, 324, -295, 415, -98, +90, 94, -243, 145, -281, 89, -65, 31, +144, 48, 189, 117, 75, 123, -136, 20, +-274, -140, -177, -217, 85, -113, 271, 104, +240, 247, 43, 166, -114, -69, -114, -255, +-15, -207, 9, 5, -119, 134, -229, 55, +-91, -117, 227, -99, 425, 152, 295, 397, +-77, 369, -372, 12, -364, -372, -99, -467, +124, -224, 143, 106, 17, 202, -71, 57, +-44, -103, 87, -76, 241, 103, 221, 194, +9, 78, -255, -117, -319, -154, -140, 31, +94, 256, 228, 295, 188, 112, 4, -138, +-150, -310, -153, -341, -37, -263, 65, -109, +54, 78, -29, 188, -58, 179, 37, 96, +187, 67, 253, 151, 62, 225, -251, 163, +-407, -62, -245, -297, 110, -315, 318, -110, +223, 112, -48, 127, -228, -66, -171, -232, +61, -183, 204, 55, 156, 265, -16, 259, +-134, 98, -76, -27, 91, 7, 158, 125, +51, 127, -152, -58, -284, -316, -198, -416, +-12, -249, 171, 75, 228, 306, 160, 289, +55, 92, -45, -107, -149, -127, -242, 9, +-200, 137, -18, 139, 212, 15, 314, -82, +251, -66, 113, -27, -70, -53, -239, -163, +-306, -232, -220, -129, -46, 111, 89, 320, +156, 330, 153, 155, 105, -66, 6, -197, +-113, -187, -173, -96, -120, 9, 42, 83, +150, 113, 125, 93, 27, -3, -14, -124, +10, -177, 1, -117, -51, 11, -83, 105, +-41, 112, 45, 58, 51, 36, -67, 82, +-164, 119, -122, 51, 41, -139, 127, -300, +79, -266, 7, -22, -8, 267, 1, 358, +-1, 200, 15, -60, 1, -197, -15, -130, +-35, -16, -15, 11, 29, -62, 24, -134, +9, -107, -51, -15, -130, 78, -141, 144, +-47, 181, 77, 193, 134, 130, 121, -2, +85, -130, 61, -161, -19, -101, -140, -45, +-202, -68, -143, -148, 33, -147, 149, -21, +96, 165, -38, 276, -109, 207, -76, 23, +-15, -136, 41, -147, 111, 3, 194, 184, +175, 248, -16, 107, -254, -180, -322, -401, +-142, -395, 103, -158, 166, 118, 51, 244, +-77, 188, -89, 73, -11, 57, 50, 160, +57, 226, 26, 123, 34, -100, 86, -248, +94, -209, -5, -93, -155, -79, -224, -198, +-162, -273, -27, -131, 101, 197, 155, 464, +108, 468, -13, 253, -95, 0, -77, -126, +18, -129, 107, -126, 126, -176, 84, -228, +-52, -191, -198, -76, -257, 40, -200, 94, +-54, 67, 46, 52, 69, 95, 107, 164, +186, 206, 232, 148, 172, 34, 31, -84, +-137, -159, -254, -181, -257, -175, -135, -116, +59, -30, 138, 35, 41, 22, -120, -38, +-160, -52, -22, 69, 148, 282, 176, 395, +49, 271, -89, -30, -140, -305, -44, -384, +90, -283, 135, -125, 81, -2, -13, 73, +-87, 152, -128, 192, -142, 154, -125, 46, +-120, -66, -135, -68, -34, 25, 237, 118, +478, 134, 382, 51, -13, -66, -371, -177, +-410, -255, -216, -262, -51, -188, -36, -33, +-81, 147, 1, 273, 194, 308, 324, 251, +232, 136, 14, -4, -132, -122, -121, -164, +-11, -110, 31, -29, -39, -42, -155, -142, +-261, -243, -253, -235, -123, -79, 91, 141, +285, 332, 306, 396, 133, 318, -92, 141, +-162, -72, -76, -241, 74, -309, 135, -241, +50, -61, -118, 114, -261, 158, -284, 18, +-185, -187, -21, -242, 125, -50, 232, 264, +229, 428, 144, 292, 51, -37, -36, -280, +-108, -257, -151, -42, -151, 140, -99, 134, +-57, -23, -76, -186, -75, -237, -43, -154, +33, 6, 114, 139, 152, 193, 155, 188, +103, 174, -17, 148, -150, 72, -179, -74, +-81, -243, 46, -317, 38, -228, -115, -14, +-219, 174, -144, 210, 54, 100, 196, -63, +160, -157, 29, -104, -60, 50, -44, 200, +-11, 231, 5, 116, 8, -61, -18, -183, +-86, -154, -186, -35, -171, 52, -44, 22, +80, -89, 110, -137, 70, -45, 32, 117, +43, 191, 72, 115, 61, -30, 2, -99, +-104, -38, -201, 54, -222, 70, -139, 10, +-11, -56, 81, -53, 69, -21, -2, -22, +-47, -77, -22, -144, 65, -105, 164, 76, +206, 294, 100, 358, -97, 185, -262, -115, +-264, -317, -157, -269, -104, -59, -77, 85, +-21, 45, 99, -93, 234, -135, 244, -5, +100, 171, -101, 229, -189, 114, -117, -38, +9, -79, 36, -9, -33, 59, -123, 36, +-194, -43, -146, -101, 4, -88, 172, -49, +220, -55, 96, -110, -87, -141, -173, -52, +-88, 137, 72, 307, 156, 340, 77, 188, +-76, -49, -189, -233, -232, -266, -208, -138, +-90, 28, 87, 110, 208, 52, 176, -96, +-3, -184, -160, -115, -159, 89, -1, 269, +174, 281, 180, 115, 7, -112, -197, -228, +-281, -175, -192, -21, -7, 104, 128, 121, +130, 45, 45, -46, -27, -84, -47, -72, +-56, -44, -61, -11, -65, 33, -66, 78, +-63, 99, -41, 69, 25, -1, 72, -75, +63, -92, 20, -34, -25, 69, -48, 131, +-42, 64, -36, -104, -30, -241, -16, -196, +6, 39, -23, 279, -130, 291, -207, 48, +-157, -246, -7, -339, 104, -143, 132, 182, +102, 371, 96, 283, 102, 1, 62, -256, +-42, -316, -205, -163, -294, 84, -227, 230, +-22, 170, 145, -33, 133, -202, -64, -180, +-262, 1, -216, 162, 53, 157, 314, 3, +337, -123, 116, -86, -159, 83, -294, 210, +-210, 151, 7, -40, 129, -193, 21, -187, +-185, -67, -265, 36, -140, 37, 83, -28, +214, -62, 175, -18, 29, 79, -98, 147, +-101, 133, -27, 38, 19, -71, -22, -103, +-142, -39, -223, 36, -168, 32, 29, -48, +248, -111, 282, -69, 97, 45, -155, 136, +-263, 134, -188, 57, -42, -37, 50, -116, +12, -144, -98, -112, -179, -23, -125, 77, +28, 114, 197, 85, 240, 55, 125, 59, +-47, 65, -151, 7, -101, -98, -42, -167, +-82, -124, -171, 2, -143, 87, -14, 64, +46, -29, -43, -84, -157, -29, -126, 93, +62, 163, 264, 116, 286, -6, 137, -107, +-90, -106, -240, -41, -244, 2, -129, -1, +24, -20, 38, -17, -118, -28, -279, -65, +-226, -59, 62, 46, 354, 220, 392, 299, +145, 153, -156, -141, -310, -329, -250, -244, +-118, 13, -41, 190, -21, 135, -22, -71, +9, -207, 33, -148, 47, 40, 23, 177, +-23, 170, -39, 88, -11, 43, 49, 59, +73, 59, -3, -17, -188, -122, -350, -164, +-335, -125, -96, -79, 176, -84, 261, -72, +144, 22, -15, 158, -46, 223, 50, 152, +141, 37, 76, -9, -120, 11, -289, 12, +-282, -51, -161, -120, -50, -116, -24, -67, +-61, -63, -47, -118, 37, -137, 156, -22, +199, 177, 147, 296, 76, 236, 20, 72, +-30, -36, -119, -6, -203, 70, -258, 37, +-285, -149, -286, -352, -214, -378, -43, -178, +172, 96, 350, 233, 381, 158, 289, 4, +114, -28, -62, 138, -207, 368, -325, 422, +-347, 195, -254, -189, -91, -464, 4, -463, +-5, -244, -34, -29, 4, 2, 71, -107, +106, -156, 116, 2, 131, 295, 158, 507, +72, 510, -131, 345, -320, 104, -321, -159, +-154, -410, -17, -575, -13, -526, -71, -237, +-72, 124, -21, 308, 50, 218, 138, 10, +230, -58, 216, 125, 24, 393, -233, 471, +-354, 228, -232, -185, -30, -468, 26, -474, +-64, -295, -126, -126, -15, -50, 163, 6, +207, 140, 76, 306, -87, 366, -142, 259, +-99, 70, -83, -62, -148, -84, -201, -58, +-123, -81, 54, -172, 189, -256, 219, -236, +107, -98, -85, 80, -251, 194, -259, 190, +-84, 100, 106, 32, 155, 80, 45, 203, +-118, 243, -246, 79, -225, -225, -97, -461, +69, -450, 144, -172, 85, 172, -3, 336, +-62, 213, 6, -56, 118, -204, 128, -58, +-46, 288, -271, 513, -349, 364, -246, -106, +-94, -557, -11, -672, 29, -386, 75, 77, +181, 391, 253, 386, 173, 149, -49, -91, +-245, -157, -265, -12, -155, 217, -38, 333, +2, 207, -44, -127, -111, -451, -106, -534, +-4, -299, 117, 101, 149, 375, 64, 342, +-60, 87, -135, -118, -83, -93, 34, 98, +51, 212, -105, 104, -304, -139, -308, -295, +-102, -217, 155, 21, 286, 208, 235, 187, +58, -17, -107, -222, -146, -241, -106, -33, +-114, 255, -177, 381, -132, 240, 13, -51, +125, -269, 51, -283, -169, -150, -292, -24, +-153, 7, 188, -7, 400, 34, 273, 131, +-62, 196, -285, 169, -280, 70, -141, -19, +-22, -39, 1, -40, -45, -110, -127, -250, +-134, -333, -41, -227, 108, 69, 196, 381, +141, 474, -14, 270, -144, -69, -113, -281, +-3, -224, -2, -1, -168, 170, -285, 133, +-187, -78, 44, -266, 209, -279, 180, -114, +35, 87, -136, 190, -198, 177, -97, 133, +78, 142, 199, 171, 138, 126, -77, -49, +-315, -274, -387, -397, -218, -331, 30, -119, +143, 92, 110, 187, 90, 184, 140, 171, +148, 175, 9, 140, -161, 34, -231, -60, +-179, -48, -85, 33, -45, 30, -65, -172, +-114, -438, -120, -485, -29, -177, 114, 285, +214, 539, 208, 421, 65, 87, -130, -148, +-260, -117, -205, 87, 17, 234, 160, 159, +66, -120, -202, -430, -387, -563, -321, -412, +-80, -56, 169, 287, 297, 440, 289, 376, +187, 221, 49, 107, -124, 83, -282, 84, +-335, 7, -233, -156, -33, -335, 83, -440, +50, -409, -106, -231, -215, 33, -123, 272, +148, 396, 388, 383, 369, 276, 110, 150, +-196, 59, -355, 4, -350, -60, -234, -163, +-122, -277, -83, -346, -69, -342, 9, -251, +155, -65, 219, 183, 156, 389, 31, 433, +-40, 271, -17, 23, 31, -86, -1, 19, +-153, 173, -320, 130, -355, -161, -249, -495, +-99, -600, 49, -372, 181, 54, 270, 410, +261, 500, 135, 328, -20, 52, -147, -131, +-184, -119, -129, 39, -89, 172, -117, 143, +-187, -49, -206, -299, -116, -460, 25, -425, +161, -157, 237, 250, 201, 564, 79, 560, +-68, 220, -181, -195, -219, -368, -186, -191, +-119, 127, -47, 263, 24, 94, 58, -235, +7, -449, -120, -384, -155, -97, -20, 223, +164, 399, 238, 388, 130, 249, -45, 73, +-203, -86, -234, -192, -164, -215, -94, -161, +-94, -67, -130, -10, -81, -44, 20, -116, +119, -112, 193, 30, 239, 226, 184, 333, +11, 282, -201, 113, -330, -70, -319, -187, +-201, -214, -23, -184, 91, -133, 83, -84, +1, -41, -84, 29, -98, 110, -34, 148, +83, 121, 178, 68, 161, 55, 77, 94, +-20, 124, -141, 76, -267, -44, -344, -178, +-295, -281, -122, -308, 63, -237, 184, -53, +191, 192, 105, 347, 23, 321, 2, 139, +16, -54, 0, -95, -50, 20, -118, 150, +-181, 129, -209, -107, -156, -394, -70, -495, +-25, -307, -4, 53, 40, 329, 149, 389, +241, 296, 251, 202, 101, 147, -181, 30, +-416, -195, -431, -396, -216, -382, 39, -150, +172, 96, 149, 154, 59, 33, -22, -59, +-52, 27, -48, 216, -8, 318, 53, 214, +70, -15, 32, -196, -72, -223, -174, -115, +-241, -13, -248, -27, -162, -146, -6, -225, +168, -133, 294, 123, 297, 397, 128, 456, +-142, 239, -370, -113, -382, -363, -174, -336, +86, -75, 266, 206, 237, 277, 10, 86, +-289, -218, -436, -400, -277, -311, 77, -7, +392, 343, 452, 519, 221, 389, -149, 37, +-392, -319, -356, -433, -119, -238, 69, 84, +61, 267, -55, 161, -145, -115, -123, -311, +-9, -259, 117, 17, 180, 318, 172, 446, +104, 316, -6, 10, -137, -285, -252, -386, +-285, -226, -206, 53, -52, 211, 84, 117, +131, -125, 57, -277, -59, -180, -92, 131, +10, 410, 185, 419, 237, 130, 80, -244, +-177, -402, -345, -246, -324, 61, -141, 231, +80, 144, 171, -62, 67, -165, -127, -94, +-200, 30, -82, 69, 137, 23, 278, -3, +223, 49, 30, 137, -154, 147, -211, 59, +-191, -54, -186, -127, -195, -147, -146, -143, +-28, -107, 116, -46, 212, 29, 200, 76, +92, 67, -48, 47, -76, 72, 7, 173, +55, 267, -19, 213, -184, -27, -335, -338, +-354, -523, -176, -448, 116, -141, 320, 221, +275, 428, 89, 412, -26, 214, -34, -27, +-22, -168, -46, -188, -112, -115, -202, -28, +-227, 6, -108, -10, 75, -35, 152, -16, +79, 71, -16, 185, -49, 207, -50, 54, +-41, -224, -57, -449, -84, -424, -57, -83, +53, 402, 179, 725, 167, 656, -18, 197, +-246, -395, -359, -793, -283, -796, -59, -394, +154, 173, 236, 603, 194, 736, 95, 549, +4, 176, -76, -202, -147, -487, -166, -598, +-154, -479, -99, -146, -6, 270, 68, 549, +81, 538, 7, 257, -79, -148, -89, -467, +-7, -581, 109, -435, 161, -10, 75, 532, +-70, 917, -148, 838, -148, 206, -107, -680, +-120, -1279, -162, -1172, -131, -374, -7, 642, +197, 1254, 340, 1110, 255, 359, 1, -496, +-217, -919, -263, -707, -154, -105, -17, 462, +48, 631, 38, 356, -20, -120, -115, -501, +-170, -601, -117, -382, 52, 56, 235, 508, +231, 738, 5, 558, -242, 34, -294, -506, +-75, -728, 235, -477, 362, 70, 190, 517, +-175, 573, -476, 235, -511, -268, -282, -589, +90, -525, 424, -124, 533, 359, 400, 622, +52, 507, -340, 104, -573, -324, -548, -528, +-225, -392, 227, -36, 533, 317, 506, 440, +163, 255, -251, -101, -452, -418, -402, -487, +-166, -234, 142, 176, 338, 518, 301, 588, +61, 306, -191, -182, -300, -595, -233, -647, +-81, -285, 50, 275, 124, 642, 138, 528, +119, 32, 61, -446, -42, -521, -119, -160, +-111, 289, -88, 457, -101, 219, -114, -193, +-54, -385, 105, -265, 188, 6, 93, 226, +-96, 259, -221, 151, -153, -4, 49, -165, +247, -248, 269, -175, 51, 31, -259, 269, +-418, 315, -302, 92, 17, -211, 319, -351, +394, -199, 177, 125, -220, 343, -475, 235, +-392, -120, -47, -402, 369, -346, 567, 76, +371, 569, -122, 671, -596, 240, -691, -470, +-319, -976, 245, -814, 609, -62, 553, 794, +134, 1159, -348, 738, -580, -187, -445, -991, +-15, -1071, 456, -384, 620, 546, 338, 1048, +-259, 756, -781, -85, -793, -864, -267, -1005, +464, -421, 949, 443, 804, 1015, 103, 889, +-654, 149, -971, -681, -638, -1000, 76, -607, +655, 198, 781, 864, 367, 876, -286, 237, +-715, -587, -688, -1033, -246, -761, 296, 71, +599, 918, 528, 1162, 169, 624, -219, -334, +-378, -1024, -273, -946, -68, -239, 21, 529, +-52, 777, -122, 349, -69, -309, 74, -644, +208, -393, 253, 231, 161, 702, -55, 676, +-265, 171, -316, -439, -141, -736, 148, -550, +309, -24, 169, 437, -197, 502, -483, 168, +-409, -282, 3, -438, 437, -167, 576, 281, +335, 540, -108, 358, -445, -65, -432, -379, +-95, -399, 239, -133, 268, 134, -48, 163, +-411, -32, -433, -247, -98, -243, 340, 50, +614, 425, 514, 586, 82, 360, -382, -107, +-610, -452, -484, -518, -104, -327, 262, -36, +414, 168, 282, 287, -47, 307, -285, 178, +-285, -79, -151, -339, 53, -387, 230, -172, +253, 219, 173, 533, 55, 522, -118, 230, +-269, -220, -309, -580, -174, -596, 67, -277, +189, 214, 149, 539, 18, 415, -128, -73, +-182, -570, -97, -636, 99, -102, 298, 669, +355, 1119, 203, 864, -104, 5, -409, -923, +-531, -1309, -419, -909, -114, -55, 230, 683, +413, 847, 414, 451, 285, -81, 79, -276, +-122, -31, -306, 299, -422, 297, -386, -131, +-200, -630, 144, -708, 514, -192, 626, 600, +383, 1031, -91, 688, -615, -284, -842, -1246, +-591, -1438, -48, -589, 513, 853, 781, 1869, +636, 1716, 302, 457, -57, -1093, -394, -1830, +-631, -1422, -755, -303, -631, 706, -121, 1001, +579, 705, 1123, 267, 1144, 42, 460, -19, +-595, -134, -1418, -392, -1484, -648, -631, -555, +702, -22, 1674, 632, 1604, 956, 496, 635, +-964, -163, -1822, -881, -1500, -1033, -250, -477, +1056, 421, 1600, 1029, 1134, 986, 82, 317, +-830, -537, -1133, -986, -785, -822, -115, -188, +456, 445, 674, 656, 516, 432, 134, 32, +-258, -194, -437, -133, -385, 34, -190, 68, +69, -88, 263, -245, 358, -183, 322, 73, +118, 317, -175, 301, -434, -67, -491, -470, +-248, -569, 157, -206, 454, 457, 484, 915, +173, 809, -254, 104, -494, -757, -446, -1142, +-58, -788, 406, 130, 588, 949, 390, 1029, +-106, 363, -577, -566, -650, -1025, -317, -641, +159, 236, 521, 906, 535, 834, 231, 122, +-128, -615, -366, -785, -363, -289, -152, 375, +49, 604, 183, 234, 236, -381, 146, -661, +-44, -319, -257, 356, -374, 753, -231, 494, +147, -198, 516, -697, 576, -514, 213, 228, +-328, 845, -699, 671, -656, -236, -146, -1128, +481, -1179, 779, -239, 481, 956, -233, 1456, +-725, 859, -648, -317, -59, -1161, 613, -1043, +788, -135, 341, 741, -384, 922, -831, 292, +-605, -609, 81, -976, 626, -500, 664, 443, +192, 1066, -398, 812, -601, -75, -336, -831, +161, -847, 487, -195, 337, 453, -52, 523, +-296, 94, -273, -308, -35, -290, 186, 81, +188, 352, 40, 232, -117, -144, -185, -350, +-73, -212, 55, 131, 29, 346, 17, 171, +68, -111, 137, -241, 181, -104, 49, 170, +-208, 166, -397, -137, -357, -442, -46, -396, +325, 116, 446, 691, 235, 821, -74, 355, +-266, -444, -236, -1014, -20, -868, 189, -79, +201, 815, 4, 1180, -254, 647, -395, -471, +-206, -1352, 186, -1254, 451, -165, 430, 1135, +88, 1678, -332, 958, -500, -451, -292, -1476, +147, -1357, 456, -208, 359, 970, -81, 1323, +-442, 621, -432, -584, -68, -1314, 420, -1077, +585, -62, 298, 1069, -231, 1493, -683, 910, +-690, -267, -184, -1240, 493, -1341, 865, -534, +648, 557, -51, 1145, -713, 884, -890, 48, +-443, -752, 339, -988, 798, -525, 667, 281, +83, 871, -557, 865, -753, 295, -414, -446, +198, -843, 628, -643, 566, -86, 131, 452, +-340, 670, -527, 464, -333, 9, 69, -408, +346, -564, 321, -374, 55, 49, -253, 439, +-351, 522, -199, 234, 91, -185, 316, -452, +341, -380, 184, -15, -84, 345, -316, 415, +-403, 129, -299, -309, 19, -531, 453, -288, +636, 272, 286, 727, -336, 652, -793, 12, +-715, -748, -80, -1008, 655, -513, 1014, 375, +655, 1017, -217, 854, -921, 52, -978, -680, +-366, -803, 476, -209, 916, 474, 620, 622, +-117, 199, -659, -433, -618, -632, -120, -270, +390, 266, 537, 534, 264, 318, -127, -60, +-355, -182, -332, 25, -70, 155, 179, -67, +219, -481, 75, -627, -130, -78, -227, 757, +-153, 1036, 42, 357, 248, -768, 343, -1338, +210, -720, -94, 687, -316, 1573, -358, 1155, +-182, -300, 138, -1590, 303, -1525, 206, -229, +-56, 1248, -306, 1656, -335, 627, -87, -835, +275, -1492, 499, -855, 411, 467, -23, 1278, +-498, 877, -619, -247, -234, -1022, 378, -829, +664, 169, 401, 996, -220, 846, -737, -126, +-748, -1052, -205, -1137, 579, -274, 979, 850, +684, 1321, -93, 890, -790, -121, -875, -964, +-319, -1075, 445, -551, 751, 248, 378, 778, +-302, 695, -681, 141, -404, -388, 265, -541, +741, -240, 560, 256, -166, 407, -848, 127, +-879, -262, -118, -374, 862, -26, 1245, 461, +671, 617, -456, 176, -1345, -562, -1334, -967, +-394, -644, 765, 235, 1397, 976, 1065, 1020, +48, 233, -805, -746, -970, -1090, -410, -549, +343, 521, 605, 1220, 273, 931, -268, -178, +-574, -1212, -405, -1302, 150, -397, 611, 833, +609, 1354, 169, 704, -391, -484, -626, -1231, +-372, -922, 180, 258, 596, 1326, 524, 1397, +10, 379, -565, -992, -733, -1699, -401, -1210, +210, 126, 699, 1276, 725, 1379, 290, 447, +-342, -718, -710, -1144, -615, -544, -133, 499, +448, 1066, 717, 694, 531, -208, 6, -842, +-499, -705, -673, -29, -448, 521, -20, 433, +334, -166, 503, -670, 415, -597, 123, 133, +-176, 878, -353, 1082, -322, 568, -70, -418, +215, -1071, 282, -993, 100, -282, -186, 534, +-334, 881, -174, 595, 103, -64, 302, -581, +322, -700, 85, -408, -198, 93, -284, 555, +-139, 743, 87, 541, 236, 65, 205, -481, +-6, -733, -212, -510, -339, -23, -278, 339, +24, 326, 328, 58, 470, -179, 357, -64, +22, 279, -358, 393, -521, 117, -343, -369, +65, -604, 427, -279, 406, 428, 112, 818, +-201, 417, -337, -469, -198, -1129, 68, -845, +258, 248, 204, 1258, -4, 1234, -168, 118, +-125, -1081, 102, -1347, 217, -349, 83, 971, +-208, 1396, -374, 527, -216, -913, 118, -1529, +408, -804, 407, 628, 105, 1496, -242, 1058, +-359, -223, -184, -1179, 110, -982, 318, -49, +207, 789, -132, 774, -400, 16, -343, -546, +47, -513, 403, 25, 456, 431, 192, 263, +-161, -201, -347, -410, -228, -81, 85, 468, +246, 658, 167, 115, -99, -619, -352, -870, +-284, -429, 43, 459, 403, 947, 501, 579, +202, -250, -257, -781, -489, -635, -293, 51, +129, 650, 424, 604, 268, 98, -212, -423, +-492, -522, -279, -128, 275, 316, 684, 479, +524, 194, -161, -346, -768, -672, -715, -524, +-32, 51, 762, 758, 911, 1062, 250, 620, +-640, -289, -1039, -1171, -574, -1333, 360, -471, +1017, 790, 869, 1597, 61, 1225, -719, -178, +-871, -1576, -296, -1872, 458, -700, 793, 1135, +472, 2253, -214, 1709, -712, -113, -677, -1887, +-113, -2295, 469, -997, 707, 938, 533, 2088, +29, 1654, -458, 11, -615, -1538, -346, -1895, +155, -835, 585, 861, 579, 1894, 93, 1501, +-504, 72, -812, -1369, -466, -1775, 324, -840, +929, 544, 893, 1306, 169, 1031, -701, 68, +-1005, -738, -526, -751, 330, -169, 885, 381, +732, 456, 2, 93, -681, -211, -778, -178, +-321, 143, 343, 303, 746, -11, 651, -480, +166, -636, -361, -218, -620, 493, -524, 891, +-139, 517, 318, -244, 641, -718, 603, -565, +136, 155, -461, 675, -825, 545, -634, -120, +105, -776, 878, -772, 1071, -158, 452, 565, +-565, 855, -1210, 474, -912, -249, 117, -684, +1101, -507, 1298, 83, 456, 685, -748, 732, +-1420, 121, -1030, -684, 215, -1137, 1320, -759, +1421, 248, 476, 1189, -754, 1333, -1367, 518, +-909, -710, 176, -1472, 990, -1076, 1028, 87, +274, 1221, -553, 1430, -802, 475, -449, -798, +174, -1490, 532, -1036, 464, 164, 127, 1188, +-71, 1296, -63, 517, -75, -483, -198, -1055, +-413, -841, -326, -221, 140, 420, 653, 691, +752, 531, 233, 273, -543, -132, -949, -464, +-516, -636, 434, -555, 1128, -45, 956, 648, +-47, 1078, -1063, 715, -1264, -265, -467, -1213, +678, -1327, 1234, -336, 784, 990, -222, 1660, +-907, 992, -750, -496, 105, -1616, 852, -1489, +763, -123, 10, 1307, -710, 1644, -775, 627, +-127, -884, 590, -1622, 783, -971, 341, 516, +-387, 1483, -777, 1236, -497, -29, 165, -1302, +718, -1434, 816, -458, 298, 817, -362, 1415, +-747, 904, -674, -253, -81, -1106, 528, -1068, +746, -263, 457, 706, -151, 1039, -633, 598, +-586, -313, -7, -956, 618, -798, 854, -86, +364, 738, -464, 928, -917, 342, -748, -414, +59, -770, 831, -564, 945, 71, 352, 558, +-454, 488, -794, 245, -451, -104, 300, -355, +762, -379, 595, -346, -62, -57, -680, 389, +-686, 674, -143, 531, 523, -135, 788, -858, +365, -944, -368, -235, -779, 728, -483, 1155, +289, 570, 913, -551, 848, -1093, 114, -658, +-605, 375, -863, 1082, -510, 639, 146, -447, +579, -1080, 572, -695, 227, 419, -196, 1215, +-408, 826, -249, -365, 60, -1253, 355, -1091, +498, 106, 318, 1280, -100, 1407, -510, 478, +-692, -827, -387, -1537, 321, -1144, 859, -75, +816, 979, 148, 1374, -737, 862, -985, -120, +-337, -1001, 642, -1179, 1289, -476, 888, 592, +-364, 1269, -1359, 946, -1351, -193, -288, -1314, +1049, -1482, 1570, -499, 876, 888, -304, 1648, +-1063, 1145, -956, -88, -158, -1144, 550, -1265, +758, -446, 461, 469, -43, 908, -338, 662, +-350, 96, -208, -411, -69, -631, 121, -557, +243, -299, 263, 200, 271, 641, 107, 815, +-108, 501, -187, -238, -96, -843, 37, -868, +137, -231, 90, 610, -99, 1001, -180, 552, +-160, -394, 57, -1115, 316, -1015, 367, -64, +328, 955, 105, 1315, -227, 711, -417, -424, +-344, -1126, -89, -976, 294, -99, 569, 807, +403, 968, 7, 373, -480, -504, -676, -1072, +-278, -849, 368, 89, 905, 937, 822, 1212, +125, 655, -590, -527, -915, -1265, -585, -1063, +149, 38, 784, 1215, 788, 1416, 235, 368, +-390, -1151, -781, -1784, -443, -1029, 263, 713, +813, 1911, 807, 1520, 142, -35, -510, -1612, +-752, -1675, -364, -303, 192, 1241, 439, 1730, +343, 613, -56, -1059, -161, -1783, 83, -967, +307, 579, 240, 1641, -191, 1249, -495, -199, +-279, -1222, 403, -1245, 798, -152, 598, 1030, +-157, 1169, -1021, 439, -1000, -608, -275, -1083, +708, -718, 1299, 65, 912, 636, -32, 632, +-863, 243, -1025, -173, -377, -346, 547, -297, +991, -1, 746, 293, -16, 416, -799, 322, +-880, -185, -388, -637, 283, -653, 789, -234, +655, 438, 197, 696, -227, 327, -435, -209, +-231, -370, 181, -32, 470, 412, 450, 384, +64, -192, -571, -658, -839, -646, -526, -12, +232, 673, 1117, 660, 1271, 171, 515, -417, +-614, -606, -1441, -266, -1216, 247, 34, 472, +1391, 376, 1778, 147, 869, -198, -754, -355, +-1921, -424, -1576, -314, -62, 142, 1531, 497, +1932, 519, 884, 120, -675, -478, -1584, -698, +-1082, -218, 157, 509, 1224, 867, 1237, 536, +243, -379, -802, -947, -1194, -739, -574, -3, +444, 763, 1134, 802, 930, 154, 115, -568, +-655, -828, -903, -350, -321, 445, 383, 904, +789, 750, 590, 17, -99, -811, -542, -1077, +-581, -562, -235, 348, 260, 1028, 532, 978, +533, 117, 355, -843, -5, -1152, -370, -516, +-512, 546, -343, 1180, 172, 906, 634, -104, +588, -934, 89, -998, -583, -254, -830, 555, +-321, 725, 514, 267, 1139, -356, 958, -482, +-5, -138, -883, 277, -1110, 360, -526, 106, +488, -157, 1011, -106, 829, 146, 137, 137, +-624, -113, -868, -400, -455, -436, 268, -67, +849, 424, 911, 620, 335, 318, -355, -271, +-850, -598, -798, -447, -123, 134, 639, 749, +956, 756, 643, 115, -134, -799, -809, -1217, +-789, -686, -189, 526, 633, 1385, 1006, 1147, +628, 0, -127, -1366, -751, -1498, -759, -292, +-228, 1171, 412, 1741, 722, 811, 489, -803, +-29, -1798, -417, -1234, -424, 194, -153, 1327, +285, 1322, 680, 212, 537, -767, 104, -998, +-465, -343, -847, 429, -511, 636, 201, 364, +828, -213, 864, -346, 267, -122, -515, 2, +-812, 21, -317, -123, 468, -206, 939, 31, +612, 404, -231, 471, -867, 166, -852, -373, +-94, -674, 664, -331, 868, 264, 438, 751, +-297, 642, -557, -148, -278, -783, 273, -924, +663, -321, 438, 596, -100, 967, -469, 741, +-505, -86, -228, -818, 192, -870, 432, -276, +364, 545, 190, 899, -37, 550, -218, -303, +-157, -890, 39, -816, 328, -76, 427, 685, +151, 827, -242, 381, -477, -339, -292, -582, +156, -311, 445, 214, 316, 500, -148, 197, +-419, -342, -186, -669, 324, -415, 743, 221, +651, 803, 42, 761, -518, 46, -697, -725, +-444, -954, 179, -318, 607, 684, 475, 1154, +20, 588, -427, -581, -510, -1371, 6, -1014, +695, 287, 946, 1328, 500, 1294, -430, 217, +-1034, -1066, -857, -1331, 40, -507, 953, 624, +1001, 1269, 330, 847, -641, -232, -1086, -1084, +-477, -1219, 544, -499, 1226, 659, 1006, 1459, +10, 1302, -1003, 188, -1175, -1307, -445, -1999, +674, -1140, 1282, 704, 840, 2259, -127, 2077, +-1056, 210, -1111, -1928, -322, -2638, 674, -1170, +1260, 1084, 966, 2388, 115, 1797, -698, -141, +-994, -1709, -647, -1759, 202, -540, 741, 848, +846, 1442, 474, 909, -417, -29, -865, -757, +-763, -1007, -104, -669, 902, -48, 1348, 562, +944, 895, -158, 670, -1326, -15, -1572, -704, +-549, -916, 853, -304, 1682, 573, 1326, 988, +-181, 623, -1392, -322, -1528, -1085, -526, -1020, +1007, -174, 1836, 692, 1362, 1080, -93, 696, +-1391, -62, -1686, -614, -718, -760, 707, -371, +1577, 147, 1285, 538, -35, 523, -1272, 138, +-1448, -341, -441, -611, 1018, -372, 1910, 193, +1249, 639, -368, 467, -1611, -79, -1696, -597, +-447, -600, 1125, 60, 1719, 679, 1014, 768, +-327, 148, -1404, -596, -1332, -846, -252, -493, +972, 177, 1617, 532, 1201, 532, 66, 314, +-1109, 58, -1584, -161, -998, -461, 215, -701, +1355, -517, 1562, 324, 667, 1175, -636, 1206, +-1484, 248, -1165, -1258, 86, -1935, 1230, -976, +1456, 893, 748, 2178, -440, 1672, -1212, -165, +-904, -1886, -161, -1991, 589, -493, 807, 1175, +313, 1792, -127, 864, -347, -511, -118, -1222, +287, -791, 315, 135, -26, 623, -346, 532, +-275, -101, 136, -358, 689, -148, 668, 206, +9, 302, -708, -102, -1057, -401, -493, -410, +504, 73, 1194, 636, 1142, 654, 234, 157, +-680, -472, -1079, -761, -751, -423, 129, 242, +846, 488, 952, 320, 458, -94, -251, -443, +-882, -172, -826, 321, -163, 517, 611, 295, +1132, -317, 799, -669, 4, -486, -737, 149, +-1017, 756, -490, 724, 319, 101, 887, -781, +814, -1101, 181, -616, -532, 396, -815, 1268, +-409, 1230, 303, 304, 963, -886, 920, -1410, +199, -913, -684, 346, -1223, 1239, -802, 1119, +252, 187, 1280, -1032, 1418, -1249, 490, -463, +-839, 578, -1611, 1124, -995, 636, 384, -280, +1577, -782, 1593, -509, 244, 211, -1153, 719, +-1638, 473, -783, -190, 727, -625, 1558, -660, +1163, -175, -35, 328, -1125, 440, -1299, 347, +-337, 80, 690, -98, 1181, -89, 890, -126, +-132, -94, -780, 27, -734, 150, -212, 191, +461, 9, 654, -330, 303, -572, -100, -435, +-366, 53, -286, 648, 81, 860, 253, 609, +283, 25, 128, -655, -104, -894, -85, -694, +-39, -41, 58, 708, 150, 934, 65, 539, +-33, -304, 3, -1059, 29, -1031, 36, -93, +69, 932, -25, 1386, 58, 825, 161, -420, +78, -1235, 21, -1206, -152, -368, -240, 648, +-24, 983, 293, 610, 450, 0, 394, -531, +0, -536, -433, -185, -498, 97, -291, 301, +205, 243, 638, 130, 565, 157, 199, 44, +-272, -246, -739, -487, -584, -628, -14, -230, +560, 594, 1049, 1085, 813, 832, 82, -273, +-700, -1285, -1166, -1299, -836, -103, 54, 1359, +917, 1672, 1245, 562, 721, -1236, -392, -2021, +-1035, -993, -891, 883, -88, 1971, 869, 1329, +996, -423, 447, -1761, -281, -1429, -720, 98, +-503, 1400, -58, 1455, 318, 267, 436, -946, +214, -1333, 54, -636, -32, 448, -73, 927, +-78, 731, -107, -14, -70, -640, 150, -635, +350, -182, 328, 424, 168, 712, -311, 476, +-546, -219, -337, -730, -32, -658, 508, -161, +750, 559, 498, 708, 7, 188, -607, -484, +-794, -749, -380, -175, 285, 654, 839, 1035, +886, 459, 274, -615, -499, -1227, -868, -847, +-742, 395, -1, 1207, 719, 905, 862, -320, +578, -1345, -33, -1069, -532, 267, -618, 1570, +-386, 1520, 16, 154, 497, -1401, 698, -1716, +500, -594, -20, 833, -626, 1550, -777, 780, +-310, -524, 457, -1213, 923, -1011, 679, 17, +-118, 881, -730, 1084, -691, 755, -24, 40, +693, -725, 733, -1107, 200, -925, -545, -145, +-773, 926, -280, 1328, 386, 730, 822, -519, +550, -1515, -86, -1180, -472, 143, -473, 1431, +-60, 1657, 404, 493, 387, -969, 63, -1640, +-154, -1081, -271, 243, -83, 1174, 176, 1082, +158, 239, 125, -652, 31, -971, -8, -432, +183, 309, 228, 689, 76, 659, -115, 101, +-370, -333, -394, -436, -39, -391, 343, -160, +547, -7, 429, 171, -90, 328, -473, 372, +-409, 100, -41, -280, 463, -434, 697, -206, +423, 403, -210, 606, -803, 232, -843, -569, +-239, -979, 646, -435, 1154, 631, 767, 1336, +-160, 774, -996, -599, -982, -1658, -92, -1298, +846, 361, 1117, 1896, 486, 1964, -464, 371, +-1025, -1698, -618, -2504, 228, -1286, 758, 914, +620, 2426, -109, 2079, -536, 26, -420, -1993, +231, -2363, 676, -994, 506, 1242, 19, 2538, +-538, 1812, -562, -184, -195, -2054, 315, -2432, +441, -978, 209, 1113, -58, 2199, -323, 1664, +-41, -95, 245, -1627, 331, -1714, 295, -553, +-35, 1038, -268, 1686, -259, 988, -169, -365, +-14, -1486, 213, -1393, 141, -352, 120, 858, +167, 1437, 3, 916, 18, -233, 0, -1132, +-77, -1180, -30, -368, 48, 786, 178, 1339, +172, 928, 1, -77, -163, -1074, -249, -1309, +-157, -648, 88, 276, 171, 967, 167, 973, +209, 382, 160, -276, 253, -675, 154, -637, +-260, -248, -456, 285, -464, 596, -126, 604, +590, 211, 797, -422, 335, -750, -233, -717, +-843, -83, -741, 627, 145, 800, 800, 553, +976, -248, 535, -799, -404, -596, -894, 36, +-656, 643, -127, 759, 597, 168, 738, -598, +237, -663, -210, -356, -576, 258, -429, 585, +178, 150, 502, -295, 525, -386, 267, -20, +-240, 496, -356, 576, -111, 119, 123, -401, +268, -536, -6, -184, -470, 184, -481, 116, +-123, -182, 468, -275, 1028, 58, 804, 681, +13, 734, -812, 43, -1230, -796, -622, -1182, +464, -393, 1277, 862, 1301, 1436, 206, 879, +-1042, -567, -1585, -1678, -1069, -1466, 386, -70, +1578, 1439, 1651, 1827, 722, 754, -744, -786, +-1651, -1670, -1219, -1241, -58, 244, 1156, 1285, +1497, 1246, 583, 304, -488, -914, -1245, -1171, +-1192, -487, -36, 390, 951, 920, 1278, 595, +843, -208, -314, -610, -1044, -448, -834, 84, +-115, 649, 672, 538, 840, -120, 198, -671, +-393, -846, -640, -192, -405, 756, 159, 1030, +433, 522, 494, -568, 363, -1252, 123, -773, +-89, 470, -288, 1373, -460, 1095, -454, -242, +-8, -1502, 471, -1425, 722, -127, 418, 1375, +-295, 1722, -760, 548, -723, -1013, 94, -1724, +863, -939, 1051, 566, 509, 1506, -470, 1189, +-995, -148, -895, -1200, -84, -1280, 669, -344, +893, 918, 487, 1382, -287, 805, -756, -435, +-703, -1444, 73, -1356, 889, -116, 1108, 1267, +504, 1861, -570, 1011, -1275, -951, -1136, -2175, +-35, -1879, 1093, -64, 1402, 2080, 759, 2594, +-494, 1209, -1350, -1108, -1141, -2643, -83, -2137, +1029, -89, 1484, 1816, 915, 2365, -266, 1207, +-1269, -747, -1438, -1953, -589, -1841, 620, -537, +1435, 1074, 1307, 1934, 315, 1618, -987, 320, +-1597, -1312, -1052, -2105, 228, -1520, 1592, 32, +1845, 1760, 841, 2226, -802, 1135, -2058, -779, +-1748, -2219, -226, -2003, 1450, -424, 2221, 1417, +1264, 2266, -624, 1583, -1897, -151, -1844, -1680, +-339, -2036, 1573, -1044, 2187, 654, 1224, 1804, +-576, 1702, -2079, 278, -1940, -1403, -333, -2018, +1387, -1041, 2150, 790, 1300, 2016, -552, 1779, +-1783, 78, -1707, -1617, -386, -1913, 1279, -727, +1979, 905, 1315, 1627, -246, 978, -1638, -473, +-1970, -1397, -901, -1162, 745, -36, 1877, 1114, +1839, 1337, 504, 798, -1012, -291, -1874, -1127, +-1493, -1201, 18, -660, 1411, 443, 1961, 1114, +1163, 1079, -495, 290, -1776, -832, -1934, -1290, +-672, -830, 1071, 337, 2051, 1223, 1638, 1221, +175, 409, -1325, -565, -1914, -975, -1053, -823, +414, -215, 1560, 147, 1625, 248, 370, 454, +-876, 475, -1419, 480, -995, 98, 273, -565, +1059, -890, 1019, -610, 358, 269, -474, 1057, +-756, 1022, -422, 14, 84, -991, 447, -1298, +551, -530, 100, 802, -154, 1343, -262, 919, +-375, -280, -81, -1256, 24, -1061, 279, -199, +402, 771, 252, 1104, 90, 602, -183, -242, +-191, -805, -158, -692, -33, -270, 20, 359, +3, 606, 39, 284, 96, -158, 163, -495, +72, -304, 54, 157, -114, 707, -78, 630, +143, -52, 182, -573, 215, -997, -65, -582, +-390, 232, -395, 785, -78, 923, 326, 461, +557, -300, 398, -908, -92, -812, -420, -291, +-410, 633, -99, 1170, 356, 689, 441, -283, +192, -1280, -50, -1294, -322, -85, -271, 1204, +-37, 1660, 91, 723, 146, -993, 118, -1885, +137, -1252, 216, 485, 164, 1875, -106, 1846, +-285, 269, -359, -1546, -197, -2177, 253, -1264, +526, 661, 401, 2058, 29, 2005, -361, 563, +-525, -1258, -223, -2289, 254, -1591, 553, 260, +415, 1857, -13, 2272, -398, 810, -517, -1306, +-63, -2490, 374, -1782, 556, 476, 384, 2399, +-243, 2547, -632, 633, -560, -1783, -77, -2862, +428, -1709, 720, 697, 549, 2400, 89, 2276, +-252, 480, -622, -1311, -550, -2027, -219, -1332, +208, 92, 647, 1129, 657, 1394, 303, 998, +-339, 189, -750, -843, -627, -1443, -5, -1306, +736, -321, 921, 1186, 449, 1931, -415, 1357, +-952, -282, -733, -1928, -12, -2066, 742, -631, +931, 1256, 442, 2275, -347, 1523, -884, -363, +-688, -1859, 23, -2021, 756, -658, 1006, 1098, +481, 1930, -472, 1367, -1045, -74, -786, -1425, +26, -1729, 915, -750, 1081, 567, 323, 1513, +-570, 1349, -1035, 373, -698, -842, 300, -1479, +1024, -976, 926, 28, 258, 1026, -584, 1246, +-954, 605, -595, -484, 90, -1149, 617, -944, +639, -180, 418, 758, -96, 1118, -495, 685, +-498, -46, -308, -750, 239, -941, 620, -508, +647, 55, 245, 552, -337, 694, -719, 480, +-680, 49, -71, -378, 454, -586, 760, -547, +558, -224, -37, 311, -468, 739, -642, 729, +-289, 275, 269, -417, 672, -911, 730, -789, +210, -66, -462, 688, -954, 841, -979, 402, +-138, -448, 857, -932, 1412, -554, 1145, 198, +-58, 1011, -1183, 1090, -1636, 292, -899, -729, +625, -1334, 1706, -1076, 1629, -51, 331, 1103, +-1230, 1404, -2055, 716, -1304, -536, 386, -1395, +1803, -1085, 2000, 45, 731, 1301, -798, 1534, +-1795, 422, -1476, -934, -111, -1601, 1062, -1055, +1514, 310, 893, 1340, -251, 1199, -993, 199, +-1121, -841, -569, -1159, 364, -488, 938, 395, +1012, 927, 568, 780, -256, 124, -815, -475, +-892, -614, -407, -395, 299, -110, 713, 60, +719, 69, 191, 55, -370, 190, -566, 485, +-403, 527, 120, 192, 534, -435, 524, -994, +179, -871, -206, -25, -520, 905, -426, 1396, +1, 784, 325, -572, 574, -1491, 359, -1463, +-232, -334, -517, 1050, -479, 1707, -35, 1222, +660, -61, 724, -1097, 281, -1387, -281, -917, +-795, 36, -577, 808, 62, 1107, 523, 903, +638, 178, 222, -694, -385, -1219, -525, -1160, +-138, -275, 228, 1001, 530, 1595, 432, 1291, +5, 112, -305, -1258, -546, -1754, -415, -1189, +-123, 63, 354, 1203, 737, 1489, 606, 936, +114, 27, -566, -885, -828, -1099, -533, -765, +262, -244, 893, 527, 834, 857, 235, 769, +-622, 401, -944, -323, -516, -701, 255, -697, +731, -421, 661, 101, 149, 385, -345, 524, +-357, 478, -314, 282, -85, 20, 236, -442, +301, -763, 406, -676, 284, -152, -200, 595, +-579, 1130, -592, 851, -271, -31, 520, -996, +980, -1393, 581, -701, -68, 467, -781, 1453, +-807, 1523, -62, 392, 496, -1107, 625, -1877, +308, -1433, -276, 129, -385, 1719, -34, 2067, +139, 1032, 189, -851, -135, -2078, -438, -1799, +-183, -226, 266, 1505, 801, 1975, 789, 1059, +26, -720, -747, -1815, -995, -1393, -587, -18, +231, 1271, 837, 1438, 762, 497, 331, -736, +-284, -1158, -663, -566, -432, 383, -30, 858, +342, 560, 476, -208, 305, -783, -31, -617, +-325, -5, -354, 531, -120, 678, 90, 337, +189, -254, 164, -520, -62, -397, -122, -97, +41, 416, 283, 535, 348, 153, 19, -230, +-270, -664, -433, -525, -223, 100, 272, 645, +306, 822, 92, 205, -239, -546, -322, -888, +73, -527, 506, 412, 618, 1072, 67, 848, +-556, -97, -753, -1074, -253, -1328, 532, -554, +794, 704, 499, 1366, -339, 1111, -816, 29, +-600, -1089, -21, -1158, 623, -409, 727, 638, +462, 1117, -88, 625, -447, -458, -464, -1064, +-282, -824, 166, 6, 248, 968, 304, 1006, +159, 279, -188, -527, -183, -900, -157, -515, +17, 313, 252, 717, 328, 497, 122, -104, +-125, -559, -216, -417, -207, 74, 24, 422, +103, 149, 198, -334, 113, -535, -219, -128, +-223, 707, -226, 1075, 84, 540, 554, -545, +592, -1351, 301, -1149, -351, -72, -880, 1029, +-875, 1364, -118, 584, 814, -511, 1159, -1076, +769, -875, -398, 26, -1250, 727, -1198, 835, +-198, 445, 1142, -179, 1502, -528, 905, -573, +-539, -441, -1660, -190, -1286, 198, -153, 540, +1205, 871, 1667, 647, 718, -145, -738, -897, +-1566, -1437, -1203, -905, 108, 504, 1438, 1612, +1553, 1842, 722, 825, -681, -955, -1730, -2260, +-1387, -2132, -257, -622, 1095, 1286, 1848, 2541, +1245, 2197, -181, 572, -1480, -1395, -1878, -2498, +-887, -2050, 797, -502, 1900, 1347, 1760, 2194, +422, 1723, -1206, 345, -1961, -1095, -1417, -1687, +-13, -1339, 1422, -355, 1887, 635, 1098, 1097, +-275, 1212, -1433, 725, -1634, -113, -841, -784, +571, -1370, 1710, -1165, 1579, -216, 453, 862, +-987, 1495, -1854, 1237, -1404, 177, 152, -907, +1577, -1334, 1843, -927, 816, 5, -861, 680, +-1809, 945, -1394, 652, 7, 34, 1411, -358, +1676, -635, 729, -667, -693, -210, -1550, 179, +-1119, 499, 18, 708, 1010, 374, 1134, -136, +409, -399, -466, -463, -908, -324, -515, -24, +217, 61, 687, 121, 580, 231, -10, 340, +-546, 380, -608, 51, -243, -370, 267, -662, +616, -527, 352, 62, -159, 610, -375, 751, +-371, 392, 52, -98, 628, -569, 417, -640, +-91, -442, -575, -299, -941, 175, -237, 643, +677, 985, 1081, 935, 1008, 117, -67, -952, +-1169, -1622, -1405, -1228, -951, 16, 299, 1321, +1580, 1796, 1793, 1003, 1029, -340, -363, -1397, +-1810, -1470, -2140, -652, -1278, 426, 325, 1121, +2074, 1105, 2601, 553, 1568, -214, -380, -701, +-2315, -877, -2854, -663, -1591, -151, 680, 326, +2634, 671, 2842, 790, 1283, 547, -963, 77, +-2670, -463, -2567, -1020, -837, -1001, 1224, -433, +2492, 488, 2134, 1420, 466, 1469, -1229, 497, +-1967, -831, -1541, -1797, -250, -1656, 961, -296, +1379, 1167, 1057, 1894, 163, 1513, -569, 141, +-828, -1198, -781, -1703, -342, -1349, 120, -174, +573, 1047, 873, 1629, 749, 1400, 280, 263, +-568, -1088, -1295, -1924, -1252, -1602, -433, -176, +816, 1538, 1788, 2395, 1555, 1668, 288, -189, +-1273, -2151, -2183, -2717, -1493, -1425, 180, 781, +1784, 2594, 2253, 2646, 1067, 887, -768, -1317, +-2091, -2653, -1906, -2247, -427, -372, 1209, 1499, +1936, 2317, 1232, 1802, -95, 258, -1192, -1118, +-1325, -1778, -627, -1659, 280, -658, 886, 401, +714, 1279, 312, 1768, -183, 1298, -512, 223, +-337, -965, -236, -1816, 16, -1706, 343, -620, +314, 742, 313, 1635, 158, 1671, -237, 859, +-456, -411, -324, -1293, -82, -1507, 266, -1014, +457, -3, 195, 916, 16, 1285, -249, 1089, +-397, 308, -113, -596, 62, -963, 281, -856, +516, -247, 437, 270, -63, 407, -609, 261, +-923, -77, -753, -3, 258, 322, 1151, 539, +1363, 378, 635, -253, -772, -991, -1663, -1133, +-1394, -497, -90, 470, 1379, 1438, 1905, 1482, +961, 498, -536, -772, -1741, -1740, -1766, -1657, +-333, -449, 1073, 1122, 1697, 2127, 1066, 1710, +-424, 130, -1314, -1561, -1200, -2436, -124, -1479, +1070, 547, 1286, 2076, 316, 2355, -818, 859, +-1234, -1370, -830, -2412, 435, -1950, 1218, -103, +996, 1909, 253, 2355, -760, 1497, -1000, -369, +-604, -2004, -97, -2107, 522, -1140, 686, 573, +601, 1927, 423, 1870, -24, 809, -584, -783, +-1089, -1949, -1023, -1668, -322, -357, 717, 1144, +1666, 1860, 1653, 1342, 592, -84, -845, -1288, +-1999, -1552, -2016, -921, -846, 257, 850, 1007, +2166, 1130, 2279, 694, 1131, 57, -737, -497, +-2350, -959, -2604, -999, -1358, -654, 668, 119, +2528, 1216, 2948, 1771, 1597, 1330, -625, -146, +-2618, -1813, -3066, -2544, -1622, -1658, 465, 492, +2289, 2323, 2853, 2871, 1739, 1498, -88, -817, +-1848, -2374, -2615, -2503, -2080, -1135, -484, 727, +1444, 1853, 2614, 1906, 2494, 1015, 927, -232, +-1295, -1114, -2839, -1553, -2692, -1325, -1041, -339, +1280, 727, 2776, 1528, 2441, 1590, 942, 649, +-1105, -626, -2337, -1542, -2081, -1570, -1023, -696, +568, 445, 1729, 1246, 1839, 1375, 1188, 842, +68, -47, -1135, -782, -1832, -1192, -1545, -1133, +-522, -470, 932, 418, 1920, 1243, 1716, 1431, +673, 791, -896, -374, -1977, -1492, -1830, -1742, +-586, -897, 1151, 695, 2096, 1961, 1727, 2065, +129, 848, -1656, -1194, -2157, -2518, -1122, -2319, +809, -721, 2155, 1667, 1888, 2979, 169, 2341, +-1663, 448, -2248, -1932, -1206, -3093, 777, -2207, +2022, -135, 1921, 1980, 500, 2901, -1176, 1997, +-1862, 50, -1467, -1745, -206, -2550, 1049, -1848, +1650, -302, 1261, 1319, 303, 2034, -833, 1714, +-1493, 591, -1235, -730, -447, -1415, 754, -1433, +1446, -642, 1260, 232, 354, 756, -946, 908, +-1586, 546, -1229, 9, -65, -166, 1236, -286, +1659, -373, 993, -167, -352, -288, -1502, -324, +-1709, 81, -733, 320, 704, 695, 1658, 871, +1605, 345, 338, -308, -975, -1021, -1731, -1385, +-1530, -830, -111, 133, 1114, 1136, 1565, 1700, +1115, 1222, -187, 164, -1158, -996, -1239, -1780, +-493, -1390, 435, -325, 857, 769, 560, 1634, +-3, 1460, -306, 429, -342, -696, -117, -1530, +-36, -1494, 18, -554, 41, 682, 71, 1594, +240, 1650, 62, 681, -246, -749, -335, -1717, +-203, -1791, 355, -700, 856, 860, 636, 1893, +-103, 1804, -933, 467, -1326, -1157, -760, -2096, +296, -1626, 1303, -61, 1763, 1598, 1129, 2277, +-160, 1352, -1502, -341, -2213, -1916, -1693, -2351, +-68, -1096, 1781, 477, 2778, 1908, 2257, 2298, +357, 1112, -1979, -295, -3247, -1785, -2669, -2325, +-649, -1419, 1910, -59, 3490, 1754, 3142, 2661, +1183, 1954, -1541, 290, -3614, -1806, -3804, -3075, +-1988, -2536, 1076, -567, 3662, 1794, 4346, 3356, +2545, 2974, -798, 1051, -3645, -1530, -4556, -3341, +-2779, -3275, 603, -1546, 3339, 1098, 4175, 3058, +2566, 3352, -422, 1842, -2807, -683, -3599, -2664, +-2187, -3177, 183, -1914, 1961, 362, 2601, 2206, +1561, 2815, -230, 1857, -1220, -76, -1319, -1687, +-673, -2220, 345, -1721, 397, -313, -278, 974, +-586, 1415, -443, 1467, 648, 756, 1862, -2, +1644, -525, 206, -1177, -1975, -1149, -3278, -870, +-2224, -212, 427, 874, 3164, 1370, 4106, 1301, +2213, 642, -1170, -549, -3802, -1287, -4120, -1410, +-1808, -874, 1565, 116, 3774, 1016, 3729, 1438, +1500, 1203, -1360, 361, -3202, -811, -3250, -1557, +-1447, -1635, 837, -710, 2526, 748, 2932, 1824, +1809, 1962, -163, 795, -1927, -924, -2700, -2086, +-2179, -1996, -358, -630, 1577, 1192, 2689, 2198, +2416, 1746, 699, 269, -1343, -1279, -2546, -1842, +-2348, -1242, -925, -69, 1099, 801, 2292, 908, +2106, 637, 962, 336, -661, 465, -1779, 401, +-1961, -287, -1261, -1268, 41, -2013, 1307, -1448, +1912, 329, 1632, 2316, 444, 3099, -966, 1834, +-1845, -606, -2001, -2702, -892, -3165, 596, -1742, +1525, 543, 1829, 2230, 1021, 2547, -156, 1560, +-1105, -29, -1611, -1328, -1220, -1875, -317, -1541, +606, -481, 1359, 625, 1299, 1435, 415, 1440, +-532, 602, -1352, -303, -1157, -1023, -88, -938, +701, -268, 1100, 147, 480, 355, -664, 118, +-981, -298, -626, -166, 487, 341, 1469, 764, +1015, 925, -130, 426, -1357, -576, -1808, -1441, +-855, -1739, 693, -970, 1711, 521, 1763, 1959, +770, 2477, -762, 1602, -1481, -432, -1560, -2419, +-840, -3030, 399, -1913, 1066, 429, 1387, 2528, +1060, 3279, 298, 2143, -499, -103, -1203, -2280, +-1301, -3300, -821, -2612, 49, -637, 1097, 1797, +1625, 3404, 1313, 3316, 345, 1317, -1027, -1530, +-1959, -3692, -1673, -3776, -447, -1532, 1216, 1673, +2189, 4025, 1733, 3855, 380, 1312, -1384, -1960, +-2242, -4151, -1626, -3804, -93, -1185, 1553, 2058, +2063, 4139, 1295, 3884, -179, 1375, -1663, -1977, +-2023, -4171, -1113, -4060, 395, -1548, 1637, 1999, +1904, 4330, 1047, 4102, -432, 1395, -1680, -2201, +-2059, -4297, -1165, -3788, 248, -1059, 1467, 2247, +1879, 3757, 1188, 3080, 25, 820, -1081, -1655, +-1584, -2588, -1267, -2158, -439, -866, 476, 581, +965, 1164, 898, 1290, 659, 1132, 215, 508, +-280, -59, -464, -727, -706, -1210, -874, -1128, +-684, -663, -292, 289, 532, 1051, 1381, 1245, +1669, 1180, 1146, 460, -209, -596, -1741, -1375, +-2508, -1754, -1907, -1280, -249, 47, 1728, 1575, +2999, 2341, 2565, 1914, 796, 304, -1498, -1600, +-3136, -2504, -2884, -2191, -1192, -624, 1137, 1258, +2914, 2308, 3050, 2331, 1589, 1077, -668, -634, +-2481, -2029, -2843, -2567, -1708, -1631, 115, 161, +1778, 1931, 2464, 2704, 1887, 1993, 568, 90, +-927, -1842, -1940, -2550, -2010, -1967, -1260, -277, +101, 1496, 1518, 2252, 2243, 1909, 1753, 524, +339, -1089, -1299, -2063, -2240, -1998, -1879, -724, +-520, 1008, 1058, 2180, 1933, 2052, 1633, 652, +509, -1229, -697, -2247, -1591, -1812, -1575, -365, +-798, 1378, 382, 2128, 1608, 1459, 1705, 268, +791, -1044, -817, -1821, -2179, -1495, -1980, -701, +-463, 505, 1682, 1635, 2853, 2025, 2000, 1541, +-404, 100, -2716, -1634, -3355, -2646, -1862, -2296, +990, -699, 3013, 1461, 3259, 2867, 1671, 2866, +-1027, 1438, -2845, -817, -3011, -2627, -1617, -3176, +626, -2241, 2190, -92, 2468, 2160, 1572, 3270, +-187, 2850, -1587, 825, -1940, -1567, -1346, -2944, +-73, -2881, 919, -1210, 1223, 888, 820, 2202, +153, 2369, -246, 1394, -413, -43, -242, -1117, +-125, -1590, -182, -1488, -326, -766, -416, 34, +-37, 803, 440, 1464, 886, 1363, 1026, 869, +381, -69, -516, -1169, -1318, -1593, -1509, -1449, +-754, -597, 558, 749, 1772, 1612, 1969, 1789, +962, 1128, -781, -356, -2182, -1518, -2281, -1920, +-992, -1368, 1016, 148, 2492, 1426, 2511, 1838, +877, 1330, -1376, -50, -2777, -1149, -2495, -1442, +-687, -1024, 1521, -20, 2838, 670, 2361, 833, +460, 596, -1773, 165, -2934, -49, -2243, -111, +-332, -198, 1816, -374, 2884, -506, 2158, -409, +133, 69, -2044, 768, -2911, 1064, -2014, 612, +-61, -401, 1841, -1347, 2500, -1507, 1770, -432, +185, 1203, -1373, 2202, -2027, 1775, -1828, -113, +-758, -2218, 516, -2971, 1387, -1701, 1844, 938, +1373, 3164, 192, 3381, -968, 1391, -1764, -1566, +-1858, -3455, -893, -3277, 307, -1118, 1324, 1599, +1931, 3042, 1382, 2906, 392, 1176, -796, -920, +-1835, -2197, -1781, -2398, -1021, -1423, 261, 87, +1498, 1407, 1674, 1879, 1178, 1559, 177, 508, +-985, -653, -1269, -1239, -968, -1309, -480, -701, +276, -88, 502, 390, 479, 816, 560, 786, +387, 833, 367, 594, 162, -75, -464, -712, +-984, -1331, -1233, -1395, -937, -760, 92, 375, +1162, 1443, 1850, 2033, 1753, 1743, 562, 397, +-1157, -1209, -2478, -2492, -2627, -2693, -1310, -1347, +966, 833, 2906, 2884, 3339, 3560, 1797, 2258, +-1016, -396, -3384, -2993, -3641, -4050, -1833, -2870, +981, -24, 3224, 2766, 3310, 4074, 1450, 3109, +-1067, 495, -2721, -2144, -2553, -3557, -1017, -2988, +735, -921, 1665, 1474, 1443, 2837, 554, 2645, +-274, 1246, -627, -812, -626, -2045, -459, -2014, +-376, -1197, -284, 185, -26, 1147, 276, 1280, +625, 988, 672, 445, 183, -131, -461, -520, +-780, -781, -541, -813, 67, -413, 501, 155, +387, 670, -133, 789, -621, 314, -653, -307, +-42, -579, 831, -239, 1102, 452, 548, 825, +-524, 474, -1419, -405, -1279, -1311, -441, -1330, +601, -286, 1349, 1026, 1128, 1875, 384, 1634, +-422, 345, -1016, -1159, -993, -2006, -610, -1738, +-101, -611, 419, 781, 719, 1714, 734, 1780, +585, 1146, 203, 32, -415, -999, -950, -1553, +-1217, -1481, -872, -813, 26, 130, 892, 1050, +1469, 1423, 1276, 1196, 265, 606, -935, -187, +-1678, -737, -1414, -1001, -399, -848, 679, -542, +1291, -230, 1114, 267, 328, 634, -440, 1073, +-861, 1307, -772, 954, -310, 54, 11, -1325, +38, -2348, -21, -2189, 134, -750, 488, 1460, +659, 3161, 418, 3135, -237, 1325, -1052, -1310, +-1264, -3299, -674, -3370, 333, -1618, 1204, 890, +1144, 2860, 292, 3038, -676, 1707, -1251, -270, +-797, -1980, 194, -2232, 902, -1394, 852, -110, +-17, 1004, -906, 1205, -1209, 819, -561, 308, +621, -3, 1444, -66, 1271, -131, 92, -388, +-1243, -755, -1919, -694, -1388, -190, 99, 551, +1291, 1190, 1722, 925, 1088, 87, -232, -649, +-1071, -996, -1296, -487, -763, 435, 78, 777, +453, 515, 398, -279, 144, -1093, -102, -854, +6, 117, 383, 1193, 358, 1863, 112, 992, +-498, -641, -1267, -1947, -1111, -2417, -456, -971, +725, 1034, 1809, 2461, 1644, 2711, 573, 997, +-1076, -1144, -2273, -2550, -2095, -2646, -700, -988, +1077, 1190, 2151, 2526, 1856, 2507, 494, 868, +-979, -1261, -1814, -2382, -1488, -2166, -502, -453, +493, 1578, 1024, 2283, 726, 1645, 203, -42, +-298, -1699, -472, -1943, -136, -1020, 118, 496, +116, 1667, -242, 1481, -791, 534, -864, -598, +-359, -1345, 561, -1055, 1581, -180, 1641, 660, +422, 1167, -1225, 856, -2583, 17, -2502, -618, +-729, -1104, 1514, -751, 3140, 177, 2921, 752, +801, 1107, -1860, 692, -3612, -203, -3267, -856, +-1085, -1025, 1682, -523, 3519, 391, 3210, 1076, +1102, 965, -1706, 352, -3458, -620, -3066, -1245, +-1073, -751, 1467, 120, 2892, 983, 2335, 1238, +468, 383, -1462, -660, -2292, -1197, -1537, -822, +20, 281, 1215, 1253, 1429, 1260, 597, 346, +-576, -749, -1142, -1516, -1051, -1131, -331, -48, +517, 822, 767, 1443, 819, 1148, 332, 378, +-423, -316, -749, -1133, -1070, -1286, -789, -948, +9, -170, 552, 996, 1016, 1589, 927, 1344, +267, 361, -530, -827, -1266, -1467, -1380, -1157, +-761, -246, 225, 600, 1136, 961, 1377, 717, +862, 325, -101, 36, -1193, -128, -1605, -217, +-1051, -452, -69, -671, 927, -542, 1280, -68, +653, 593, -283, 1040, -1107, 915, -1106, 367, +-174, -358, 692, -765, 1047, -734, 403, -484, +-850, -62, -1478, 179, -1072, 277, 104, 459, +1439, 635, 1781, 668, 728, 477, -896, -172, +-2247, -1037, -2061, -1464, -495, -1238, 1233, -114, +2297, 1422, 1870, 2311, 363, 2056, -1480, 611, +-2456, -1482, -1983, -2986, -697, -2880, 998, -1198, +1983, 1369, 1820, 3467, 1003, 3754, -387, 1999, +-1557, -916, -1822, -3467, -1658, -4179, -750, -2627, +613, 264, 1400, 3026, 1887, 4228, 1460, 3192, +182, 623, -894, -2074, -1901, -3733, -2219, -3421, +-1362, -1369, -162, 1008, 1070, 2896, 2072, 3300, +2115, 1967, 1250, 241, -249, -1474, -1928, -2528, +-2817, -2245, -2392, -1381, -815, -35, 1274, 1544, +2695, 2442, 2656, 2460, 1121, 1301, -1068, -744, +-2442, -2410, -2419, -2831, -1121, -1670, 632, 587, +1472, 2298, 1184, 2401, 271, 1238, -590, -639, +-699, -1677, -94, -1232, 411, -219, 299, 790, +-194, 834, -1003, 15, -1263, -743, -706, -801, +258, -23, 1320, 1007, 1511, 1610, 879, 1021, +-202, -251, -1344, -1430, -1805, -2016, -1496, -1348, +-509, 98, 786, 1432, 1561, 2128, 1512, 1731, +732, 415, -392, -949, -1273, -1869, -1474, -1777, +-1064, -723, -325, 421, 406, 1386, 695, 1581, +682, 923, 644, 207, 470, -534, 100, -996, +-551, -872, -1328, -736, -1587, -369, -1123, 270, +51, 785, 1463, 1295, 2078, 1373, 1624, 625, +226, -512, -1487, -1559, -2453, -2102, -2357, -1195, +-957, 365, 984, 1678, 2219, 2416, 2397, 1435, +1253, -84, -543, -1375, -1946, -2065, -2471, -1330, +-1788, -202, -203, 797, 1216, 1451, 1864, 1378, +1762, 846, 652, 139, -758, -728, -1589, -1445, +-1936, -1530, -1254, -957, 136, 283, 1161, 1591, +1628, 2002, 1080, 1401, -156, 52, -1146, -1320, +-1466, -1692, -792, -1124, 141, -96, 627, 793, +623, 869, 28, 473, -586, 65, -561, -106, +-66, 196, 377, 458, 595, 206, 303, -307, +-330, -832, -807, -996, -1194, -403, -963, 419, +-12, 906, 804, 1037, 1352, 597, 1356, 86, +398, -105, -842, -474, -1845, -667, -2088, -859, +-1090, -1033, 332, -316, 1577, 728, 2169, 1732, +1506, 2232, 36, 1345, -1431, -378, -2351, -2074, +-2106, -2982, -778, -2287, 756, -200, 1973, 1955, +2095, 3218, 974, 2957, -504, 988, -1675, -1284, +-1907, -2677, -1167, -2753, 26, -1322, 929, 470, +1125, 1563, 633, 1770, -183, 1252, -521, 483, +-472, 55, -175, -227, 90, -772, -17, -1202, +-340, -1390, -540, -914, -375, 311, -95, 1492, +406, 2025, 633, 1519, 545, 291, 370, -938, +-292, -1535, -878, -1465, -1311, -925, -1282, -135, +-324, 490, 744, 1127, 1566, 1619, 1638, 1519, +672, 805, -595, -540, -1604, -1913, -1962, -2433, +-1312, -1701, -207, 43, 726, 1850, 1432, 2687, +1408, 2058, 805, 424, 47, -1270, -881, -2127, +-1448, -1675, -1465, -462, -1199, 698, -360, 1291, +818, 1022, 1636, 215, 1719, -339, 939, -452, +-496, -254, -1753, 267, -2143, 458, -1517, 232, +88, -36, 1371, -509, 1591, -721, 998, -476, +-168, -130, -1002, 469, -1109, 1068, -604, 1135, +106, 808, 449, 26, 269, -1065, -250, -1677, +-525, -1495, -425, -562, -46, 906, 467, 1989, +686, 2011, 421, 1068, -187, -468, -718, -1715, +-968, -1931, -797, -1248, -285, -20, 316, 1139, +663, 1531, 722, 1215, 634, 546, 176, -246, +-356, -740, -883, -775, -1336, -712, -1119, -485, +-348, -154, 634, 176, 1541, 748, 1593, 1116, +701, 1076, -573, 527, -1667, -514, -1912, -1342, +-1275, -1634, -67, -1042, 1197, 325, 1752, 1455, +1478, 1957, 479, 1477, -925, -1, -1814, -1423, +-1891, -2085, -1037, -1574, 380, -114, 1454, 1448, +1894, 2186, 1264, 1676, -138, 211, -1536, -1397, +-2244, -2095, -1635, -1602, -223, -156, 1237, 1291, +2091, 2048, 1742, 1717, 316, 353, -1225, -958, +-2150, -1863, -2090, -1897, -827, -841, 617, 587, +1641, 1824, 2009, 2296, 1244, 1526, -127, -33, +-1327, -1592, -2011, -2442, -1880, -1862, -836, -356, +452, 1240, 1554, 2157, 1980, 1817, 1344, 665, +31, -555, -1318, -1296, -2115, -1260, -1898, -672, +-516, -63, 1012, 455, 1725, 637, 1408, 551, +152, 388, -981, 161, -1278, -1, -844, -5, +221, 25, 833, -234, 354, -468, -359, -784, +-879, -746, -809, 47, 65, 899, 879, 1611, +1132, 1531, 760, 441, -227, -856, -1290, -1805, +-1595, -1942, -1091, -1024, -111, 355, 988, 1434, +1476, 2006, 1242, 1686, 409, 606, -717, -484, +-1516, -1507, -1545, -1969, -905, -1483, 146, -617, +1142, 677, 1449, 1887, 1133, 2228, 225, 1830, +-822, 480, -1514, -1392, -1789, -2627, -1186, -2763, +223, -1468, 1506, 881, 2149, 2828, 1816, 3408, +170, 2192, -1616, -349, -2541, -2520, -2302, -3336, +-722, -2449, 1006, -171, 2012, 1772, 1997, 2672, +1000, 2438, -179, 1011, -1077, -439, -1570, -1467, +-1607, -2135, -1217, -1892, -428, -959, 737, 235, +1810, 1756, 2171, 2659, 1570, 2202, -126, 808, +-1944, -1215, -2823, -2736, -2494, -2762, -821, -1465, +1227, 625, 2477, 2298, 2581, 2721, 1403, 1903, +-309, 211, -1719, -1399, -2474, -2192, -2052, -2014, +-770, -924, 572, 496, 1572, 1538, 1804, 1906, +1213, 1502, 292, 420, -697, -741, -1314, -1506, +-1294, -1663, -969, -1046, -476, 38, 161, 1155, +796, 1705, 1138, 1381, 1011, 392, 471, -837, +-286, -1529, -979, -1278, -1282, -300, -964, 850, +-281, 1420, 416, 968, 776, -80, 551, -1007, +252, -1312, 70, -588, -70, 639, 22, 1444, +-78, 1443, -516, 423, -885, -1024, -974, -1860, +-491, -1680, 452, -429, 1232, 1215, 1428, 2254, +998, 2106, -112, 808, -1304, -993, -1814, -2330, +-1686, -2498, -650, -1446, 768, 510, 1691, 2244, +1949, 2865, 1162, 2168, -271, 258, -1551, -1810, +-2055, -2890, -1579, -2543, -460, -909, 816, 1179, +1571, 2557, 1583, 2610, 856, 1452, -206, -370, +-1009, -1855, -1430, -2275, -1346, -1675, -737, -265, +137, 1128, 934, 1749, 1362, 1622, 1186, 713, +476, -376, -460, -947, -1291, -1087, -1577, -740, +-1138, -222, -210, 25, 743, 286, 1303, 473, +1202, 680, 567, 993, -167, 725, -881, 64, +-1127, -846, -926, -1580, -616, -1400, 85, -527, +704, 761, 889, 1656, 795, 1546, 258, 714, +-374, -350, -748, -1088, -866, -1044, -433, -419, +165, 95, 361, 392, 233, 254, -105, -200, +-348, -211, -90, 112, 320, 592, 600, 1107, +682, 848, 29, -89, -870, -1118, -1353, -1835, +-1334, -1537, -488, -279, 736, 1189, 1571, 2109, +1833, 2023, 1171, 881, -311, -591, -1650, -1663, +-2310, -2012, -1906, -1402, -418, -303, 1119, 884, +2172, 1719, 2208, 1756, 968, 1063, -648, -84, +-1957, -1203, -2328, -1649, -1455, -1239, 67, -322, +1401, 691, 2050, 1197, 1614, 1053, 308, 504, +-1035, -186, -1892, -653, -1821, -775, -823, -518, +498, -76, 1538, 440, 1754, 739, 1012, 565, +-157, 110, -1168, -478, -1630, -750, -1247, -468, +-396, 56, 403, 571, 999, 702, 1112, 304, +783, -174, 399, -409, -204, -288, -926, 29, +-1302, 246, -1359, 91, -857, -317, 200, -457, +1244, -289, 1867, 295, 1663, 1011, 582, 1062, +-810, 541, -1790, -373, -2061, -1371, -1649, -1635, +-561, -1052, 727, 36, 1750, 1279, 2382, 1991, +2064, 1803, 724, 868, -1115, -589, -2876, -1898, +-3405, -2429, -2216, -1918, 173, -392, 2629, 1460, +3760, 2743, 2867, 2760, 472, 1357, -1970, -817, +-3272, -2618, -2739, -3058, -961, -1884, 812, 331, +1905, 2309, 1881, 2964, 1038, 1972, 126, -79, +-611, -1943, -972, -2560, -943, -1673, -830, 108, +-484, 1694, 145, 2093, 622, 1199, 822, -269, +667, -1386, 185, -1509, -207, -635, -522, 490, +-617, 1119, -382, 945, -206, 171, 39, -530, +313, -794, 292, -534, 184, -12, -29, 346, +-299, 483, -243, 508, 86, 404, 330, 165, +349, -225, -123, -819, -770, -1160, -914, -849, +-549, 104, 395, 1304, 1221, 1989, 1304, 1559, +635, 76, -673, -1597, -1667, -2511, -1672, -2032, +-771, -365, 593, 1482, 1664, 2500, 1707, 2199, +788, 806, -412, -831, -1508, -1848, -1747, -1887, +-1023, -1147, 35, -71, 1057, 858, 1466, 1270, +1075, 1237, 193, 794, -656, 63, -1174, -596, +-1092, -955, -488, -937, 135, -493, 662, 144, +885, 490, 678, 651, 201, 520, -385, 118, +-819, -102, -898, -331, -556, -392, 29, -165, +609, 63, 914, 368, 731, 431, 221, 89, +-420, -313, -890, -679, -1006, -621, -737, -3, +3, 671, 793, 1077, 1181, 926, 1023, 97, +222, -804, -744, -1260, -1337, -1167, -1247, -390, +-405, 586, 645, 1163, 1169, 1228, 968, 764, +277, -57, -581, -727, -848, -1058, -546, -1001, +-116, -438, 351, 219, 351, 761, 11, 938, +-174, 612, -255, 69, -234, -430, 69, -557, +276, -344, 308, 42, 410, 252, 177, 154, +-261, -100, -728, -406, -1116, -413, -929, -82, +-21, 389, 1172, 841, 1884, 981, 1638, 600, +283, -171, -1563, -1082, -2664, -1719, -2337, -1581, +-639, -568, 1599, 921, 2907, 2279, 2508, 2684, +811, 1672, -1263, -290, -2595, -2304, -2452, -3343, +-1142, -2718, 457, -665, 1676, 1664, 1931, 3191, +1372, 3233, 568, 1720, -470, -336, -1327, -2120, +-1703, -2995, -1602, -2585, -836, -1356, 377, 347, +1533, 2085, 2205, 2992, 1905, 2858, 672, 1640, +-853, -632, -2230, -2665, -2676, -3690, -1882, -3303, +-377, -1086, 1461, 1584, 2724, 3612, 2663, 4217, +1621, 2605, -167, -139, -2123, -2689, -2987, -4041, +-2656, -3333, -1279, -1119, 897, 1258, 2520, 2835, +2986, 2954, 2282, 1750, 395, 211, -1657, -1114, +-2749, -1747, -2649, -1597, -1304, -1124, 575, -386, +1761, 357, 2078, 881, 1434, 1212, 255, 1157, +-562, 643, -983, -53, -1024, -703, -781, -1121, +-576, -968, -157, -450, 362, 116, 668, 595, +847, 683, 606, 465, 163, 211, -123, -8, +-346, -94, -424, -82, -475, -142, -684, -297, +-667, -452, -238, -508, 338, -347, 1059, 111, +1396, 703, 974, 1103, 118, 1059, -983, 455, +-1673, -558, -1503, -1385, -726, -1563, 270, -1034, +1137, 35, 1468, 1008, 1190, 1449, 586, 1292, +-207, 685, -920, -48, -1354, -721, -1350, -1184, +-918, -1316, -60, -989, 974, -195, 1641, 869, +1718, 1612, 982, 1571, -362, 775, -1654, -515, +-2137, -1507, -1548, -1612, -199, -891, 1359, 275, +2032, 1164, 1545, 1259, 366, 670, -1051, -224, +-1672, -853, -1251, -798, -338, -300, 665, 310, +1125, 653, 899, 438, 347, -26, -294, -430, +-811, -557, -900, -273, -546, 122, 40, 367, +605, 393, 762, 209, 613, 24, 242, -23, +-242, -27, -489, -78, -558, -262, -535, -509, +-470, -512, -246, -195, 171, 355, 715, 872, +1199, 941, 1082, 503, 361, -209, -700, -798, +-1634, -975, -1749, -673, -946, -134, 302, 343, +1447, 631, 1907, 616, 1273, 403, 134, 78, +-940, -292, -1516, -434, -1083, -271, -296, -14, +274, 247, 528, 171, 262, -351, -4, -679, +133, -570, 466, 103, 795, 1138, 773, 1543, +-13, 975, -1145, -256, -1783, -1648, -1668, -2045, +-551, -1233, 1032, 164, 2079, 1590, 2270, 1983, +1360, 1246, -347, 83, -1857, -1079, -2445, -1578, +-1863, -1192, -386, -458, 1089, 391, 1974, 1049, +1942, 1106, 949, 847, -289, 245, -1277, -511, +-1650, -895, -1165, -1008, -311, -750, 554, -187, +1071, 327, 893, 753, 431, 1017, 51, 958, +-271, 502, -358, -218, -269, -1007, -346, -1505, +-487, -1226, -477, -337, -112, 725, 569, 1500, +992, 1454, 889, 692, 314, -314, -484, -1087, +-1009, -1253, -1002, -835, -391, -86, 376, 623, +853, 874, 756, 695, 139, 177, -354, -386, +-525, -493, -318, -321, 73, 44, 261, 312, +205, 107, 45, -201, -103, -389, -158, -288, +-54, 112, 15, 478, 32, 531, 19, 291, +-20, -62, 18, -335, 75, -351, 127, -320, +97, -216, 3, -68, -114, -56, -332, 174, +-386, 358, -105, 339, 245, 372, 559, 147, +620, -147, 261, -276, -248, -405, -673, -445, +-772, -316, -378, -148, 233, 107, 644, 472, +751, 627, 372, 548, -261, 233, -622, -234, +-608, -554, -75, -570, 542, -322, 687, -77, +251, 72, -483, 87, -885, 36, -595, 214, +250, 500, 925, 602, 947, 403, 353, -199, +-426, -879, -837, -1125, -650, -787, -192, 41, +189, 859, 351, 1129, 206, 867, 233, 175, +361, -491, 308, -669, 163, -623, -313, -372, +-786, -117, -805, -93, -439, 29, 286, 299, +983, 597, 1104, 820, 740, 731, 34, 148, +-854, -663, -1333, -1286, -1182, -1433, -407, -866, +692, 236, 1449, 1316, 1536, 1800, 833, 1437, +-384, 280, -1399, -1055, -1641, -1763, -1007, -1622, +77, -588, 1062, 698, 1480, 1364, 1109, 1347, +314, 643, -552, -326, -1144, -822, -1093, -926, +-570, -712, 78, -181, 737, 212, 981, 539, +687, 892, 378, 786, -148, 366, -585, -245, +-603, -1112, -695, -1394, -468, -924, 26, -16, +409, 1212, 859, 1831, 1003, 1403, 498, 226, +-253, -1208, -847, -2074, -1019, -1793, -430, -414, +379, 1185, 758, 2126, 616, 1919, -54, 476, +-733, -1238, -786, -2156, -162, -1801, 772, -342, +1455, 1295, 1247, 2132, 187, 1561, -1180, 48, +-2189, -1416, -1989, -2118, -659, -1487, 1188, 55, +2759, 1462, 2802, 2092, 1264, 1581, -858, 144, +-2580, -1305, -2882, -1969, -1628, -1649, 269, -500, +1801, 824, 2277, 1454, 1596, 1275, 458, 584, +-565, -238, -1238, -558, -1195, -376, -704, -202, +-175, -186, 234, -442, 377, -744, 355, -578, +367, 89, 501, 942, 609, 1490, 598, 1354, +124, 512, -805, -675, -1380, -1582, -1373, -1793, +-650, -1242, 657, -131, 1590, 1014, 1718, 1583, +1070, 1456, -159, 756, -1179, -171, -1362, -756, +-962, -981, -263, -842, 499, -522, 770, -327, +639, 44, 340, 423, -43, 757, -136, 1025, +-5, 733, 79, 93, 81, -609, -70, -1128, +-441, -1038, -656, -455, -411, 235, 129, 779, +785, 894, 1015, 561, 662, 16, 55, -503, +-656, -727, -882, -540, -453, -12, 3, 583, +316, 826, 329, 504, -35, -230, -158, -1007, +71, -1312, 400, -737, 801, 323, 757, 1322, +30, 1827, -808, 1254, -1410, 33, -1331, -1164, +-420, -1986, 670, -1829, 1487, -864, 1675, 358, +1080, 1490, 95, 1965, -781, 1612, -1242, 649, +-1194, -563, -812, -1473, -309, -1718, 287, -1314, +738, -462, 1018, 411, 1133, 1015, 954, 1294, +482, 1099, -350, 625, -1185, -3, -1639, -738, +-1496, -1186, -724, -1217, 443, -865, 1547, -158, +2023, 630, 1791, 1151, 782, 1319, -551, 1021, +-1501, 224, -2006, -675, -1829, -1394, -885, -1609, +276, -1060, 1455, -62, 2370, 1034, 2320, 1719, +1382, 1593, -261, 826, -2116, -415, -2980, -1575, +-2488, -1974, -851, -1510, 1327, -203, 2757, 1383, +2771, 2222, 1600, 1884, -167, 491, -1590, -1304, +-2126, -2326, -1790, -1981, -791, -604, 410, 1079, +1312, 2093, 1689, 1897, 1387, 787, 501, -636, +-518, -1652, -1271, -1863, -1344, -1246, -813, -88, +-24, 1006, 734, 1706, 1131, 1675, 1179, 863, +767, -233, -15, -1279, -857, -1879, -1492, -1643, +-1437, -739, -560, 473, 750, 1662, 1920, 2135, +2134, 1607, 1062, 408, -554, -1171, -1977, -2273, +-2336, -2196, -1220, -1142, 476, 521, 1890, 1914, +2233, 2212, 1251, 1465, -276, 22, -1450, -1274, +-1740, -1741, -1010, -1436, 183, -515, 1016, 427, +1264, 925, 816, 1058, 21, 804, -424, 329, +-487, -149, -314, -602, -134, -919, -124, -895, +-167, -478, -133, 138, 147, 755, 580, 1044, +885, 794, 760, 205, 139, -508, -610, -984, +-1112, -950, -1016, -543, -380, 120, 454, 745, +1070, 978, 1035, 815, 595, 309, -36, -422, +-661, -954, -839, -1118, -570, -888, -17, -157, +582, 666, 805, 1208, 496, 1314, -28, 747, +-536, -175, -727, -970, -329, -1404, 321, -1195, +798, -490, 737, 301, 175, 938, -405, 1197, +-666, 976, -523, 408, -70, -285, 444, -910, +659, -1189, 504, -1009, 144, -413, -250, 413, +-441, 1042, -384, 1290, -99, 938, 220, 40, +302, -811, 262, -1389, 146, -1335, 52, -513, +43, 446, 21, 1164, -22, 1373, -104, 837, +-221, -5, -216, -679, 6, -1069, 278, -1017, +498, -559, 500, -32, 223, 489, -126, 853, +-505, 848, -685, 490, -500, -114, -40, -615, +650, -760, 1091, -460, 976, 72, 443, 406, +-379, 324, -1142, -100, -1321, -483, -793, -500, +167, -28, 1154, 593, 1498, 887, 1053, 678, +238, -53, -622, -820, -1039, -1081, -847, -755, +-346, -45, 118, 618, 370, 814, 478, 486, +456, -11, 443, -344, 371, -383, 150, -163, +-130, 36, -455, -5, -602, -146, -503, -176, +-194, -47, 211, 280, 620, 544, 957, 404, +917, -22, 335, -586, -511, -931, -1156, -761, +-1287, -183, -606, 535, 517, 1004, 1386, 1011, +1634, 588, 913, -60, -239, -687, -1101, -1074, +-1462, -1111, -1017, -828, -107, -205, 705, 586, +1219, 1215, 1180, 1465, 734, 1147, 177, 254, +-486, -828, -1024, -1640, -1113, -1852, -787, -1259, +-121, -104, 740, 1112, 1333, 1935, 1421, 1908, +893, 977, -95, -411, -984, -1640, -1434, -2081, +-1160, -1506, -376, -249, 452, 1024, 1127, 1612, +1288, 1322, 936, 443, 451, -465, -203, -887, +-831, -748, -1044, -354, -1029, -6, -579, 84, +316, -50, 1060, -61, 1491, 160, 1310, 443, +359, 596, -747, 370, -1444, -211, -1406, -743, +-424, -928, 787, -582, 1489, 88, 1402, 623, +361, 840, -811, 564, -1350, 37, -1060, -360, +2, -603, 969, -565, 1259, -353, 945, -133, +177, 167, -514, 454, -684, 607, -540, 528, +-276, 171, -13, -349, 101, -791, 234, -880, +439, -576, 587, -18, 608, 584, 381, 927, +-54, 856, -475, 441, -666, -202, -468, -806, +-134, -1056, 161, -874, 381, -367, 388, 267, +378, 734, 395, 867, 335, 739, 221, 420, +-7, -27, -370, -512, -552, -939, -475, -1152, +-258, -936, 118, -242, 398, 627, 613, 1294, +785, 1412, 704, 887, 405, 0, -133, -871, +-794, -1305, -1186, -1274, -994, -830, -281, -65, +708, 603, 1416, 1045, 1452, 1104, 978, 662, +108, 46, -695, -487, -1120, -767, -1190, -719, +-828, -511, -206, -276, 532, -43, 1274, 196, +1618, 489, 1313, 685, 433, 577, -740, 165, +-1547, -403, -1528, -816, -782, -760, 331, -258, +1146, 350, 1218, 709, 830, 590, 302, 18, +-91, -591, -197, -839, -292, -632, -416, -15, +-490, 645, -406, 927, 28, 723, 590, 152, +914, -516, 782, -903, 269, -803, -248, -383, +-448, 110, -361, 442, -98, 392, 134, 113, +53, -27, -68, 3, -10, 154, 203, 351, +588, 224, 805, -198, 570, -571, 9, -803, +-591, -717, -982, -238, -813, 286, -158, 652, +551, 899, 1080, 835, 1089, 405, 612, -153, +8, -815, -507, -1333, -729, -1304, -620, -690, +-250, 346, 212, 1338, 664, 1773, 890, 1365, +646, 185, 85, -1179, -513, -2031, -764, -1909, +-489, -803, 117, 755, 734, 1844, 943, 1936, +678, 1079, 137, -345, -446, -1403, -693, -1577, +-556, -1088, -283, -210, 142, 501, 594, 666, +827, 562, 901, 412, 659, 285, 6, 258, +-654, 105, -1105, -348, -1095, -846, -335, -1075, +717, -811, 1467, -29, 1654, 833, 1004, 1281, +-189, 1003, -1142, 135, -1602, -720, -1300, -1123, +-241, -852, 784, -121, 1520, 491, 1794, 668, +1230, 413, 251, -110, -768, -491, -1621, -488, +-1671, -255, -886, 78, 233, 372, 1397, 445, +1913, 292, 1530, 24, 635, -299, -577, -561, +-1371, -625, -1338, -434, -667, -78, 364, 313, +1034, 669, 1044, 721, 587, 446, -51, 76, +-388, -446, -255, -837, 67, -824, 297, -610, +248, -168, -27, 353, -203, 644, -142, 703, +137, 546, 443, 237, 553, -126, 430, -428, +66, -626, -270, -759, -407, -674, -394, -314, +-128, 131, 267, 629, 572, 1003, 746, 883, +680, 419, 333, -176, -51, -829, -416, -1142, +-720, -1014, -671, -615, -332, 52, 200, 750, +841, 1160, 1193, 1146, 1084, 656, 597, -194, +-152, -1024, -842, -1400, -1130, -1176, -919, -485, +-231, 365, 602, 995, 1181, 1120, 1321, 791, +846, 261, 34, -393, -630, -896, -930, -969, +-644, -754, 33, -249, 579, 444, 775, 790, +509, 693, 13, 339, -247, -226, -227, -578, +13, -514, 394, -265, 567, 50, 407, 234, +90, 154, -305, -19, -468, -129, -297, -145, +-63, -51, 290, 82, 633, 111, 746, 18, +656, -117, 313, -195, -194, -156, -587, -37, +-722, 114, -497, 137, 80, -26, 667, -193, +990, -277, 845, -200, 380, 116, -94, 375, +-490, 325, -498, 40, -237, -410, 7, -700, +239, -473, 351, 91, 402, 657, 470, 835, +462, 395, 285, -378, -20, -1016, -399, -1086, +-646, -530, -463, 276, 131, 941, 814, 1088, +1159, 697, 911, 111, 144, -472, -711, -899, +-1025, -1024, -676, -859, 13, -467, 788, 122, +1109, 763, 848, 1149, 421, 1145, -141, 708, +-624, -81, -680, -893, -483, -1401, -64, -1418, +621, -862, 1005, 89, 939, 940, 576, 1367, +-189, 1197, -777, 456, -754, -368, -360, -949, +240, -1125, 702, -818, 732, -317, 515, 218, +219, 684, -1, 874, -30, 782, -77, 322, +-157, -414, -267, -1011, -259, -1246, 90, -975, +447, -125, 729, 755, 754, 1235, 340, 1312, +-125, 755, -457, -137, -495, -860, -123, -1397, +304, -1452, 482, -876, 468, -67, 239, 791, +-93, 1411, -161, 1369, 39, 794, 323, 11, +498, -752, 322, -1204, -130, -1227, -457, -953, +-413, -429, -4, 287, 655, 973, 1066, 1380, +833, 1269, 181, 536, -590, -558, -1053, -1467, +-808, -1708, -102, -1156, 663, -68, 1198, 968, +1184, 1439, 700, 1233, 99, 499, -499, -369, +-839, -962, -720, -1152, -384, -934, 86, -413, +537, 237, 755, 740, 829, 921, 684, 796, +340, 312, -39, -304, -381, -759, -497, -959, +-371, -795, -153, -324, 207, 261, 518, 719, +522, 825, 368, 534, 106, -17, -91, -542, +38, -702, 233, -461, 307, -56, 238, 280, +10, 265, -189, -31, -183, -245, 48, -284, +245, -74, 294, 244, 246, 325, 64, 251, +-15, 41, 107, -247, 234, -384, 304, -442, +294, -370, 130, -105, 2, 220, 51, 524, +45, 582, -36, 258, -116, -281, -226, -769, +-170, -893, 188, -514, 620, 201, 938, 872, +998, 1109, 540, 723, -284, -137, -1024, -1031, +-1341, -1496, -956, -1253, 108, -350, 1211, 785, +1741, 1563, 1562, 1594, 654, 880, -551, -293, +-1334, -1358, -1397, -1802, -785, -1492, 234, -545, +1126, 618, 1455, 1438, 1187, 1576, 444, 1016, +-450, 38, -987, -912, -977, -1351, -482, -1153, +346, -540, 1023, 198, 1147, 696, 761, 794, +22, 569, -649, 151, -802, -266, -455, -532, +102, -595, 638, -434, 834, -69, 618, 304, +332, 509, -17, 458, -316, 113, -399, -309, +-426, -567, -251, -574, 155, -262, 602, 105, +894, 313, 829, 389, 388, 195, -214, -28, +-618, -113, -603, -184, -290, -53, 133, 102, +477, 15, 502, -176, 415, -507, 275, -774, +126, -527, 165, 168, 129, 1000, 13, 1506, +-133, 1128, -296, -62, -267, -1386, -72, -2066, +227, -1612, 559, -265, 717, 1194, 630, 1908, +333, 1470, -93, 310, -424, -865, -632, -1424, +-680, -1093, -312, -283, 307, 446, 904, 691, +1287, 400, 1117, -54, 434, -296, -422, -185, +-1124, 118, -1272, 282, -753, 110, 121, -307, +937, -583, 1312, -483, 1140, -104, 557, 349, +-66, 542, -449, 366, -643, 75, -617, -155, +-385, -293, -70, -317, 327, -339, 728, -372, +865, -210, 710, 112, 314, 452, -241, 632, +-564, 428, -522, -13, -253, -450, 99, -721, +367, -627, 433, -304, 430, 66, 428, 441, +278, 621, 46, 548, -224, 241, -442, -279, +-392, -734, -17, -829, 412, -521, 611, 52, +582, 586, 261, 727, -90, 462, -184, 7, +-124, -381, 29, -492, 99, -384, -12, -212, +-110, -56, 17, 52, 313, 123, 559, 188, +529, 205, 164, 85, -271, -71, -480, -156, +-316, -156, 135, -25, 563, 63, 659, -48, +352, -250, -118, -408, -420, -351, -427, -27, +-158, 389, 251, 643, 560, 567, 632, 169, +456, -339, 113, -691, -202, -796, -348, -561, +-309, -69, -86, 408, 160, 702, 253, 644, +225, 247, 163, -266, 179, -623, 257, -583, +272, -249, 185, 146, -7, 388, -195, 267, +-203, -17, -44, -231, 116, -323, 190, -146, +100, 85, -26, 148, 40, 129, 250, -34, +483, -185, 523, -156, 225, -43, -220, 134, +-528, 264, -475, 146, -130, -145, 255, -456, +446, -621, 404, -400, 308, 112, 164, 620, +122, 867, 147, 594, -3, -64, -183, -720, +-323, -1042, -340, -796, -24, -173, 402, 473, +595, 824, 603, 697, 363, 264, -96, -189, +-397, -461, -502, -551, -388, -461, 43, -296, +462, -131, 666, 160, 682, 472, 379, 651, +-101, 584, -462, 182, -630, -420, -513, -904, +-115, -1004, 401, -670, 797, 6, 879, 691, +600, 1046, 53, 971, -430, 443, -670, -319, +-669, -906, -331, -1139, 203, -888, 609, -212, +786, 462, 676, 869, 306, 868, -102, 477, +-417, -22, -535, -435, -388, -636, -68, -622, +251, -484, 457, -209, 511, 146, 402, 488, +208, 708, -11, 599, -227, 196, -381, -311, +-371, -735, -144, -791, 223, -492, 568, -65, +693, 363, 504, 544, 39, 455, -449, 275, +-667, -6, -480, -210, 54, -266, 537, -309, +659, -273, 451, -244, 82, -231, -202, -92, +-169, 127, 25, 411, 114, 632, 84, 573, +-149, 198, -348, -391, -220, -912, 102, -1043, +515, -706, 812, -22, 709, 742, 281, 1178, +-262, 1060, -767, 425, -912, -450, -618, -1122, +-46, -1288, 626, -827, 1036, 36, 1019, 783, +626, 1097, 9, 855, -536, 215, -792, -364, +-729, -684, -364, -723, 132, -536, 511, -313, +690, -26, 637, 380, 365, 753, 6, 876, +-309, 561, -467, -157, -324, -861, 9, -1090, +318, -731, 458, -30, 289, 498, -30, 504, +-287, 155, -298, -135, -25, -49, 307, 366, +468, 698, 379, 550, 107, -107, -233, -908, +-352, -1389, -238, -1246, -5, -513, 286, 458, +381, 1268, 289, 1610, 119, 1334, -109, 513, +-257, -558, -205, -1434, -18, -1749, 211, -1364, +327, -428, 249, 601, 127, 1285, 23, 1389, +-5, 932, -26, 210, -151, -451, -271, -859, +-236, -904, 32, -643, 442, -267, 734, 149, +604, 448, 59, 482, -599, 363, -963, 114, +-648, -135, 215, -176, 1014, -92, 1246, 15, +695, 24, -336, -147, -1113, -335, -1138, -381, +-463, -180, 458, 197, 1067, 453, 962, 474, +380, 244, -210, -94, -598, -282, -480, -333, +-62, -303, 193, -231, 318, -191, 234, -65, +7, 212, -108, 470, -182, 574, -166, 380, +47, -94, 316, -550, 497, -792, 448, -654, +137, -212, -234, 254, -463, 599, -446, 653, +-242, 446, 65, 149, 333, -204, 441, -435, +430, -478, 284, -444, 71, -300, -148, -117, +-337, 40, -360, 258, -198, 516, 117, 664, +369, 591, 411, 183, 255, -507, -36, -1100, +-234, -1202, -251, -647, -118, 364, 103, 1244, +284, 1441, 300, 788, 158, -377, -25, -1301, +-169, -1414, -191, -696, -81, 371, 55, 1105, +160, 1085, 200, 450, 130, -298, 7, -687, +-62, -555, -10, -173, 108, 77, 155, 44, +61, -185, -100, -300, -211, -83, -165, 349, +75, 704, 329, 699, 388, 273, 231, -330, +-55, -750, -280, -763, -270, -426, -121, 13, +43, 257, 162, 218, 164, 59, 184, -5, +241, 183, 240, 488, 130, 616, -163, 393, +-463, -194, -510, -842, -233, -1165, 233, -951, +641, -265, 719, 535, 435, 1064, -13, 1076, +-405, 612, -546, -31, -405, -569, -162, -756, +17, -594, 141, -300, 244, 11, 392, 219, +576, 281, 606, 317, 351, 321, -178, 179, +-804, -91, -1180, -435, -1015, -675, -324, -535, +674, -38, 1471, 603, 1617, 1028, 1056, 890, +-11, 266, -1057, -554, -1597, -1124, -1425, -1132, +-668, -697, 346, -27, 1152, 575, 1443, 885, +1168, 932, 422, 700, -411, 263, -996, -233, +-1111, -696, -719, -932, -73, -805, 500, -408, +872, 91, 879, 503, 505, 670, -4, 578, +-571, 307, -923, -40, -832, -349, -333, -477, +477, -329, 1209, 44, 1352, 418, 718, 499, +-360, 138, -1321, -489, -1586, -951, -935, -888, +183, -203, 1185, 743, 1570, 1374, 1083, 1309, +131, 535, -709, -530, -1100, -1323, -859, -1473, +-245, -914, 312, 26, 623, 867, 589, 1238, +280, 965, -53, 254, -251, -451, -276, -804, +-130, -681, 47, -225, 149, 163, 195, 282, +170, 202, 118, 36, -10, 33, -217, 147, +-311, 138, -270, 3, -32, -247, 331, -396, +515, -214, 466, 123, 160, 374, -320, 324, +-606, -32, -523, -354, -108, -371, 452, -47, +723, 390, 582, 528, 112, 249, -482, -264, +-807, -670, -723, -627, -212, -189, 512, 331, +1036, 643, 1007, 553, 439, 202, -369, -134, +-985, -327, -1004, -316, -538, -228, 156, -191, +713, -151, 795, -46, 460, 162, -22, 384, +-346, 453, -325, 281, -83, -84, 108, -388, +133, -445, 26, -258, -72, 73, -97, 268, +-6, 208, 72, 21, 2, -179, -100, -225, +-199, -62, -91, 136, 286, 242, 603, 226, +650, 87, 311, -74, -355, -166, -885, -192, +-967, -168, -586, -114, 127, -49, 706, 31, +894, 122, 757, 182, 376, 172, -46, 109, +-343, 12, -570, -82, -695, -120, -561, -133, +-251, -139, 202, -110, 646, -35, 802, 84, +645, 206, 247, 231, -236, 96, -581, -119, +-660, -244, -501, -188, -186, 4, 154, 184, +454, 179, 567, -20, 436, -222, 200, -229, +-99, -4, -290, 335, -292, 491, -249, 295, +-202, -124, -185, -581, -212, -787, -72, -557, +281, -56, 695, 528, 942, 972, 701, 983, +-18, 564, -861, -133, -1405, -866, -1306, -1216, +-539, -990, 500, -341, 1337, 442, 1598, 927, +1132, 888, 203, 485, -772, 9, -1405, -253, +-1393, -249, -786, -142, 91, -122, 883, -276, +1217, -436, 979, -416, 375, -170, -298, 254, +-738, 618, -787, 738, -529, 589, -155, 203, +192, -251, 418, -633, 462, -794, 382, -629, +223, -209, -16, 323, -181, 692, -305, 686, +-443, 365, -428, -110, -277, -459, 24, -451, +441, -205, 722, 79, 688, 249, 369, 173, +-172, -31, -707, -139, -853, -110, -623, 37, +-103, 198, 410, 200, 542, 22, 389, -204, +165, -337, 20, -273, 77, 18, 171, 361, +60, 514, -215, 391, -617, -8, -821, -482, +-561, -696, 78, -528, 838, -13, 1220, 571, +961, 827, 179, 594, -707, -15, -1228, -615, +-1074, -826, -380, -547, 438, 68, 980, 579, +875, 646, 301, 334, -343, -129, -699, -419, +-514, -325, -31, -32, 359, 200, 476, 227, +187, 25, -270, -204, -494, -221, -436, -55, +-21, 168, 405, 294, 475, 151, 284, -124, +-64, -311, -278, -297, -205, -13, -34, 344, +59, 512, -38, 374, -301, -42, -434, -493, +-222, -695, 283, -522, 805, -48, 915, 454, +456, 690, -349, 541, -1062, 121, -1260, -286, +-813, -452, 48, -313, 881, 6, 1271, 224, +1033, 189, 326, -20, -495, -256, -1025, -305, +-1023, -97, -592, 191, 51, 396, 535, 377, +649, 150, 488, -113, 126, -288, -166, -280, +-255, -151, -208, -14, -52, 91, 47, 96, +-1, 57, -100, 31, -229, -25, -310, -35, +-184, 0, 75, 23, 398, 116, 623, 191, +519, 143, 145, 24, -356, -180, -741, -379, +-796, -402, -504, -225, -39, 84, 398, 398, +624, 532, 604, 418, 407, 125, 88, -176, +-207, -331, -445, -333, -559, -197, -502, -86, +-322, -68, -45, -29, 273, 24, 495, 143, +552, 316, 388, 380, 38, 295, -295, 109, +-544, -118, -558, -312, -328, -421, -5, -444, +345, -365, 458, -139, 278, 210, 4, 545, +-240, 701, -316, 575, -186, 181, -46, -274, +92, -563, 162, -616, 75, -456, -10, -165, +-96, 123, -156, 374, -102, 537, -11, 479, +49, 191, 100, -188, 25, -478, -156, -455, +-247, -108, -210, 258, 12, 377, 324, 144, +439, -247, 275, -430, -89, -235, -486, 212, +-602, 560, -427, 534, -95, 153, 274, -332, +425, -597, 404, -526, 249, -236, 4, 114, +-187, 378, -326, 479, -376, 438, -304, 257, +-124, -44, 97, -354, 231, -528, 183, -471, +36, -189, -50, 157, 8, 373, 118, 381, +143, 224, -3, 16, -275, -107, -474, -116, +-459, -78, -158, -23, 250, -18, 472, -76, +412, -102, 108, -66, -205, 30, -299, 179, +-193, 252, -30, 157, 53, -47, -19, -270, +-189, -344, -312, -183, -249, 110, 30, 366, +407, 429, 596, 278, 399, 0, -84, -260, +-596, -395, -803, -436, -567, -356, -39, -140, +513, 163, 750, 521, 523, 738, 2, 619, +-503, 187, -686, -389, -507, -783, -134, -736, +241, -314, 449, 194, 437, 459, 211, 352, +-109, 53, -401, -155, -507, -82, -336, 205, +-22, 402, 293, 312, 406, -46, 216, -443, +-131, -555, -407, -310, -458, 73, -211, 339, +151, 265, 378, -64, 405, -301, 216, -228, +-58, 158, -305, 596, -441, 727, -471, 389, +-392, -239, -173, -768, 132, -892, 481, -546, +677, 11, 579, 423, 169, 524, -363, 364, +-741, 148, -780, 76, -474, 156, -78, 191, +224, 42, 327, -274, 278, -594, 241, -629, +285, -291, 270, 232, 101, 647, -262, 671, +-705, 279, -861, -256, -639, -577, -87, -465, +556, -2, 907, 499, 800, 713, 317, 477, +-285, -81, -737, -630, -824, -895, -579, -712, +-146, -182, 289, 394, 503, 787, 429, 830, +206, 531, -34, 131, -202, -207, -218, -412, +-182, -444, -170, -428, -180, -418, -231, -328, +-209, -111, 2, 255, 239, 662, 380, 872, +389, 708, 150, 189, -180, -437, -425, -847, +-557, -791, -426, -304, -72, 253, 228, 563, +397, 418, 337, -56, 28, -440, -248, -465, +-378, -77, -299, 482, 18, 811, 277, 713, +288, 230, 79, -357, -251, -746, -427, -821, +-358, -601, -137, -216, 136, 182, 297, 509, +293, 681, 151, 636, -72, 418, -286, 87, +-394, -250, -364, -440, -174, -478, 109, -400, +323, -224, 382, -27, 237, 155, -38, 304, +-276, 353, -370, 290, -341, 158, -259, -2, +-216, -126, -163, -185, 27, -196, 328, -167, +625, -70, 680, 84, 359, 217, -228, 275, +-818, 170, -1096, -63, -887, -255, -302, -318, +356, -226, 788, -32, 816, 126, 499, 218, +93, 300, -210, 376, -386, 378, -397, 212, +-380, -166, -417, -610, -385, -838, -255, -681, +62, -173, 511, 438, 781, 832, 662, 865, +176, 576, -491, 142, -950, -274, -890, -599, +-385, -746, 302, -651, 745, -288, 652, 268, +187, 740, -296, 856, -557, 545, -476, -59, +-215, -595, -20, -734, 99, -456, 147, 57, +192, 477, 249, 561, 231, 313, 60, -64, +-243, -319, -519, -329, -607, -114, -420, 147, +-62, 251, 273, 152, 458, -72, 462, -257, +292, -238, 52, -19, -212, 250, -433, 412, +-483, 357, -407, 91, -214, -220, 11, -419, +168, -414, 258, -204, 281, 96, 231, 342, +108, 402, -44, 264, -223, 20, -349, -186, +-371, -221, -297, -125, -161, -4, -38, 48, +82, 11, 206, -1, 312, 106, 366, 260, +282, 296, 7, 87, -367, -323, -668, -656, +-725, -599, -462, -95, -7, 573, 415, 999, +626, 870, 543, 244, 255, -473, -77, -900, +-317, -823, -421, -364, -429, 123, -382, 423, +-307, 455, -145, 316, 119, 213, 408, 191, +601, 178, 554, 86, 214, -159, -306, -454, +-770, -606, -918, -500, -631, -127, -66, 350, +504, 678, 769, 695, 629, 398, 215, -39, +-275, -370, -571, -467, -542, -316, -292, -49, +-13, 150, 143, 201, 86, 89, -26, -90, +-58, -184, -46, -110, 59, 108, 183, 360, +206, 478, 120, 330, -55, -6, -312, -342, +-506, -490, -537, -365, -424, -108, -90, 71, +356, 67, 692, -28, 737, 1, 409, 280, +-145, 678, -627, 847, -817, 532, -670, -203, +-272, -994, 131, -1348, 347, -1008, 344, -187, +232, 650, 128, 1121, 66, 1055, 17, 641, +-77, 173, -215, -212, -379, -475, -484, -663, +-434, -755, -191, -610, 187, -179, 560, 445, +742, 975, 577, 1062, 73, 626, -590, -167, +-1074, -912, -1085, -1153, -565, -763, 259, 82, +960, 933, 1156, 1276, 751, 927, -16, 70, +-718, -833, -1002, -1241, -796, -947, -301, -155, +163, 661, 367, 1029, 290, 796, 114, 174, +29, -416, 94, -629, 205, -400, 181, 45, +-62, 403, -423, 459, -645, 212, -588, -133, +-261, -376, 176, -384, 471, -175, 501, 101, +296, 287, 19, 290, -166, 145, -231, 6, +-262, -1, -311, 112, -344, 228, -278, 175, +-52, -109, 245, -457, 448, -611, 434, -386, +183, 156, -167, 679, -450, 828, -532, 480, +-406, -163, -192, -671, 41, -709, 226, -262, +359, 361, 413, 740, 276, 650, -23, 159, +-376, -400, -602, -676, -583, -575, -327, -186, +44, 250, 338, 487, 437, 503, 322, 354, +98, 146, -106, -27, -246, -171, -306, -280, +-272, -322, -179, -274, -68, -109, 20, 132, +31, 327, 3, 390, -1, 306, 36, 120, +128, -73, 169, -204, 36, -242, -203, -195, +-409, -73, -440, 91, -240, 210, 80, 246, +330, 159, 381, -5, 222, -115, -51, -110, +-257, -1, -342, 99, -311, 87, -206, -35, +-105, -160, 16, -137, 117, 60, 183, 304, +180, 417, 114, 273, 18, -67, -86, -395, +-186, -515, -320, -352, -396, 23, -330, 406, +-123, 620, 187, 547, 421, 216, 414, -210, +181, -538, -164, -575, -417, -323, -412, 75, +-210, 410, 4, 502, 112, 360, 67, 130, +-54, -38, -87, -86, -32, -87, 46, -134, +78, -239, -25, -325, -184, -266, -261, -5, +-202, 360, -11, 652, 206, 690, 271, 416, +141, -59, -110, -524, -368, -741, -439, -608, +-288, -190, -15, 283, 250, 532, 313, 485, +166, 221, -70, -43, -273, -101, -295, 19, +-157, 159, 25, 135, 171, -70, 172, -295, +40, -353, -122, -152, -281, 167, -362, 361, +-300, 291, -160, 32, 45, -206, 270, -221, +409, 9, 397, 304, 186, 448, -159, 322, +-474, 0, -610, -310, -520, -438, -262, -351, +39, -148, 232, 54, 298, 174, 293, 237, +260, 319, 218, 399, 94, 392, -169, 205, +-496, -175, -752, -581, -742, -751, -369, -519, +221, 70, 760, 706, 959, 1015, 655, 779, +0, 78, -672, -672, -1060, -1045, -924, -825, +-363, -124, 261, 637, 674, 1043, 674, 897, +336, 321, -65, -324, -333, -688, -360, -634, +-239, -282, -164, 116, -206, 328, -301, 299, +-287, 121, -84, -46, 245, -68, 554, 52, +641, 229, 377, 337, -111, 265, -612, 16, +-898, -300, -798, -505, -411, -458, 104, -139, +550, 275, 690, 527, 523, 495, 165, 214, +-213, -84, -424, -179, -421, -58, -298, 116, +-163, 105, -121, -143, -178, -432, -171, -486, +-23, -152, 260, 420, 535, 864, 560, 877, +274, 418, -266, -268, -799, -794, -1001, -900, +-769, -571, -163, -20, 537, 468, 951, 713, +877, 652, 367, 379, -327, 37, -849, -245, +-946, -359, -613, -311, -58, -156, 405, 17, +554, 124, 391, 156, 71, 129, -187, 88, +-272, 52, -223, 21, -134, -5, -111, -11, +-141, 14, -179, 78, -146, 154, -13, 176, +133, 128, 243, 22, 230, -108, 96, -217, +-112, -264, -347, -219, -479, -99, -439, 112, +-219, 349, 96, 486, 347, 477, 411, 285, +270, -11, -15, -260, -285, -379, -384, -348, +-323, -240, -178, -125, -70, -31, -57, 86, +-20, 280, 62, 492, 141, 578, 183, 442, +94, 83, -102, -352, -285, -591, -336, -538, +-203, -260, 15, 84, 139, 306, 93, 378, +-69, 357, -236, 291, -286, 165, -168, -67, +62, -325, 239, -449, 261, -288, 159, 129, +-50, 547, -270, 650, -399, 323, -421, -220, +-276, -618, -54, -590, 117, -188, 223, 276, +228, 501, 155, 411, 43, 188, -74, 32, +-172, 33, -241, 65, -279, -23, -273, -226, +-220, -410, -128, -390, 4, -125, 136, 264, +266, 564, 342, 634, 241, 471, -14, 147, +-384, -222, -690, -527, -669, -668, -315, -558, +222, -177, 625, 364, 615, 811, 221, 931, +-329, 637, -665, 58, -562, -514, -162, -791, +243, -699, 389, -372, 182, 36, -143, 342, +-330, 507, -310, 589, -97, 559, 78, 389, +69, 77, -19, -324, -107, -655, -84, -728, +61, -491, 123, -22, 17, 472, -198, 738, +-406, 677, -419, 325, -201, -115, 108, -397, +363, -409, 403, -162, 202, 167, -91, 343, +-350, 239, -463, -80, -407, -395, -233, -459, +30, -145, 248, 371, 315, 764, 218, 753, +-31, 278, -300, -388, -431, -837, -356, -761, +-71, -207, 259, 467, 386, 844, 219, 703, +-138, 160, -499, -399, -610, -605, -366, -393, +77, 49, 465, 393, 519, 407, 213, 164, +-218, -117, -518, -209, -519, -68, -226, 157, +156, 260, 339, 135, 230, -104, -75, -274, +-359, -231, -413, 27, -233, 315, 83, 427, +329, 305, 332, 18, 96, -268, -264, -390, +-513, -317, -495, -94, -219, 170, 176, 369, +450, 445, 402, 360, 88, 164, -291, -76, +-533, -272, -489, -327, -231, -260, 82, -121, +291, 31, 283, 132, 138, 197, -44, 244, +-187, 270, -236, 248, -256, 147, -220, -24, +-118, -193, -27, -270, 72, -208, 115, -38, +65, 128, 5, 191, -70, 126, -132, -12, +-133, -103, -144, -65, -140, 109, -74, 288, +-39, 351, -9, 236, 6, -33, -53, -277, +-65, -361, -47, -243, -17, -3, 35, 202, +-13, 260, -138, 171, -245, 46, -265, -19, +-110, 2, 114, 73, 210, 102, 154, 45, +-40, -41, -243, -59, -275, 10, -162, 128, +7, 191, 92, 95, -15, -131, -172, -340, +-244, -359, -159, -120, 66, 291, 243, 627, +262, 659, 85, 370, -219, -84, -448, -450, +-479, -540, -288, -381, 26, -129, 307, 54, +422, 146, 288, 222, -47, 334, -389, 456, +-550, 451, -428, 214, -70, -180, 279, -525, +422, -632, 277, -418, -101, -5, -424, 382, +-461, 567, -231, 493, 92, 251, 253, -40, +145, -239, -116, -282, -320, -197, -271, -31, +-3, 118, 257, 170, 302, 134, 81, 75, +-260, 50, -467, 67, -426, 79, -181, 19, +106, -106, 220, -198, 157, -166, 24, 1, +-61, 227, -32, 379, 21, 362, 4, 217, +-116, 1, -291, -220, -396, -375, -322, -445, +-81, -360, 181, -77, 334, 336, 319, 711, +145, 814, -81, 530, -257, -35, -329, -598, +-304, -853, -213, -680, -97, -194, 4, 342, +87, 665, 113, 660, 97, 395, 70, 38, +30, -228, -38, -329, -140, -287, -236, -154, +-314, -18, -288, 95, -117, 168, 114, 200, +296, 208, 306, 165, 94, 73, -198, -57, +-400, -170, -404, -194, -193, -102, 73, 64, +232, 217, 206, 261, 21, 145, -168, -39, +-227, -184, -156, -187, -18, -16, 53, 192, +1, 294, -111, 202, -241, -40, -238, -266, +-57, -293, 163, -66, 324, 252, 293, 460, +46, 389, -269, 41, -529, -343, -602, -515, +-380, -360, 9, 32, 378, 427, 583, 579, +477, 411, 134, 52, -288, -286, -594, -423, +-594, -299, -336, -9, 28, 264, 303, 380, +328, 279, 142, 10, -108, -265, -276, -372, +-242, -225, -63, 98, 109, 419, 184, 529, +102, 317, -98, -69, -261, -400, -319, -462, +-243, -202, -71, 172, 70, 394, 161, 322, +177, 35, 86, -241, -35, -276, -140, -48, +-206, 251, -198, 384, -141, 237, -52, -68, +57, -300, 87, -261, 36, 19, -35, 305, +-120, 374, -162, 128, -141, -272, -88, -535, +-11, -443, 37, -2, 68, 519, 98, 825, +75, 710, -8, 204, -144, -400, -296, -791, +-357, -775, -268, -365, -82, 182, 158, 568, +341, 642, 340, 422, 203, 102, -33, -123, +-277, -183, -416, -133, -446, -124, -340, -187, +-99, -227, 172, -143, 379, 115, 418, 435, +224, 590, -91, 442, -376, 24, -490, -431, +-355, -647, -81, -491, 168, -50, 271, 409, +182, 618, 10, 482, -132, 101, -205, -282, +-174, -429, -109, -296, -53, 6, 4, 273, +35, 339, 46, 200, 36, -32, -9, -192, +-73, -193, -131, -48, -162, 136, -144, 228, +-88, 182, -25, 29, 37, -141, 80, -234, +98, -179, 64, 3, -22, 221, -105, 385, +-167, 379, -186, 174, -169, -139, -145, -416, +-95, -506, 3, -350, 130, 9, 254, 397, +271, 614, 111, 549, -178, 224, -458, -197, +-517, -483, -285, -477, 88, -212, 397, 144, +432, 363, 138, 309, -248, 66, -475, -175, +-383, -232, -31, -61, 276, 211, 361, 377, +184, 302, -150, 41, -382, -245, -364, -386, +-151, -304, 105, -78, 193, 150, 77, 278, +-79, 274, -171, 180, -114, 71, 85, -25, +222, -93, 177, -116, -47, -95, -333, -26, +-456, 53, -340, 107, -37, 95, 293, 14, +404, -55, 245, -66, -65, -22, -338, 50, +-391, 95, -191, 80, 103, 55, 308, 66, +290, 107, 42, 129, -273, 45, -491, -138, +-467, -318, -187, -353, 184, -158, 461, 177, +507, 467, 281, 533, -88, 304, -419, -70, +-563, -364, -445, -418, -158, -218, 160, 89, +368, 305, 361, 303, 176, 108, -85, -143, +-306, -300, -360, -259, -245, -35, -9, 236, +216, 404, 248, 388, 98, 177, -117, -119, +-258, -336, -204, -384, -20, -257, 135, -32, +138, 178, -28, 283, -244, 277, -316, 196, +-184, 76, 97, -45, 347, -131, 376, -164, +199, -140, -105, -53, -395, 49, -508, 112, +-423, 127, -197, 96, 106, 49, 356, 19, +462, 12, 380, -7, 103, -56, -217, -93, +-417, -80, -442, 5, -299, 137, -65, 219, +114, 165, 191, -10, 160, -205, 74, -290, +36, -166, 5, 102, -42, 333, -94, 374, +-149, 185, -155, -97, -109, -271, -45, -233, +11, -47, 22, 97, -6, 82, -18, -71, +-5, -190, 23, -97, 71, 198, 84, 502, +32, 570, -82, 288, -227, -225, -308, -672, +-249, -791, -59, -499, 188, 37, 357, 541, +319, 787, 85, 656, -220, 261, -399, -197, +-324, -526, -77, -570, 170, -347, 247, -1, +93, 299, -141, 404, -278, 288, -206, 64, +50, -134, 264, -186, 278, -115, 91, -20, +-196, 47, -361, 54, -300, 53, -85, 93, +163, 121, 248, 93, 106, -18, -94, -175, +-201, -262, -141, -189, 64, 21, 215, 244, +172, 349, -41, 276, -311, 80, -409, -121, +-244, -226, 63, -221, 341, -157, 400, -57, +191, 48, -128, 138, -353, 203, -356, 200, +-155, 114, 71, -8, 185, -84, 138, -75, +-23, -9, -128, 34, -120, -29, -34, -172, +97, -270, 145, -192, 68, 71, -73, 402, +-219, 583, -260, 462, -170, 96, -29, -328, +118, -595, 218, -578, 202, -311, 105, 63, +-3, 373, -134, 524, -236, 471, -270, 254, +-225, -39, -75, -299, 109, -417, 254, -347, +285, -133, 151, 99, -81, 244, -243, 255, +-255, 173, -131, 74, 37, -3, 110, -52, +47, -97, -102, -131, -176, -118, -83, -51, +101, 59, 253, 140, 248, 130, 55, 55, +-209, -25, -370, -53, -334, -15, -122, 35, +120, 35, 239, -18, 202, -79, 65, -82, +-48, -8, -44, 86, 15, 149, 32, 124, +-39, 29, -198, -72, -330, -150, -312, -172, +-100, -120, 215, -7, 456, 143, 496, 280, +287, 319, -84, 196, -426, -61, -566, -314, +-462, -414, -186, -297, 130, -26, 341, 218, +376, 288, 246, 192, 48, 43, -95, -7, +-140, 80, -127, 174, -93, 129, -91, -89, +-148, -353, -170, -471, -126, -323, -30, 20, +142, 334, 286, 448, 318, 351, 223, 155, +-10, -3, -263, -54, -398, -72, -388, -152, +-216, -277, 50, -360, 235, -283, 286, -23, +205, 292, 44, 492, -48, 470, -68, 263, +-47, -18, -39, -253, -151, -351, -274, -331, +-257, -234, -109, -69, 171, 112, 426, 246, +439, 294, 249, 226, -106, 85, -457, -49, +-542, -127, -392, -140, -110, -121, 223, -100, +398, -67, 389, -1, 278, 123, 50, 238, +-168, 245, -322, 106, -421, -134, -349, -341, +-133, -353, 116, -122, 348, 220, 430, 468, +303, 443, 50, 131, -247, -285, -417, -547, +-360, -462, -156, -91, 108, 327, 282, 539, +253, 405, 100, 47, -74, -283, -183, -400, +-148, -269, -57, -17, 6, 167, 43, 193, +25, 121, 24, 51, 69, 38, 71, 51, +22, 12, -89, -102, -230, -218, -249, -215, +-92, -67, 135, 161, 305, 329, 289, 296, +91, 78, -152, -196, -307, -360, -274, -295, +-96, -40, 74, 257, 144, 411, 119, 314, +48, 30, 22, -288, 40, -459, 45, -361, +-24, -64, -187, 254, -299, 436, -239, 384, +-12, 146, 287, -115, 467, -279, 380, -304, +55, -212, -351, -56, -586, 104, -490, 222, +-140, 271, 273, 199, 518, -2, 435, -223, +121, -327, -192, -242, -337, 23, -254, 307, +-58, 407, 94, 252, 101, -62, -32, -325, +-135, -377, -99, -205, 42, 52, 216, 214, +263, 226, 111, 119, -129, -12, -311, -63, +-295, -38, -87, 13, 135, 62, 246, 67, +199, 3, -11, -100, -211, -208, -231, -253, +-96, -154, 113, 99, 258, 394, 209, 532, +14, 380, -196, -27, -289, -482, -196, -685, +0, -490, 153, -20, 199, 441, 129, 615, +-5, 423, -81, 31, -78, -294, -51, -379, +-37, -231, -58, -4, -90, 145, -41, 145, +90, 51, 210, -21, 219, -42, 42, -7, +-211, 46, -361, 55, -318, 29, -42, -12, +304, -54, 458, -88, 359, -97, 42, -56, +-325, 41, -486, 148, -390, 191, -99, 118, +230, -51, 368, -201, 294, -228, 125, -97, +-77, 124, -179, 269, -144, 227, -84, 26, +-22, -210, -19, -317, -88, -222, -95, 0, +-21, 213, 110, 299, 252, 245, 259, 106, +117, -59, -85, -184, -278, -244, -325, -249, +-202, -164, -21, 7, 156, 182, 225, 305, +161, 302, 67, 154, -22, -65, -60, -252, +-33, -317, -32, -232, -51, -33, -64, 170, +-88, 274, -63, 236, 7, 76, 60, -115, +116, -227, 129, -191, 56, -54, -28, 99, +-116, 177, -161, 129, -97, 9, 2, -95, +109, -126, 181, -85, 129, 4, -7, 108, +-157, 162, -255, 142, -197, 44, -12, -123, +202, -266, 327, -274, 252, -129, 41, 120, +-195, 326, -346, 331, -299, 148, -100, -94, +129, -221, 286, -162, 284, -1, 155, 111, +-29, 57, -204, -113, -285, -231, -250, -190, +-132, 7, 78, 238, 294, 347, 374, 284, +291, 115, 37, -61, -279, -186, -461, -251, +-422, -273, -160, -243, 193, -140, 421, 49, +438, 263, 234, 406, -88, 407, -311, 233, +-335, -50, -179, -311, 41, -454, 162, -411, +155, -203, 46, 79, -81, 311, -92, 395, +3, 311, 102, 110, 129, -105, 53, -236, +-74, -251, -152, -175, -122, -46, 16, 70, +129, 135, 113, 144, 10, 85, -110, -14, +-157, -86, -92, -88, 37, -15, 154, 79, +179, 126, 112, 78, 23, -53, -59, -169, +-117, -178, -125, -95, -123, 37, -115, 136, +-62, 151, 20, 130, 130, 95, 229, 44, +248, -31, 182, -154, 22, -262, -185, -263, +-314, -97, -317, 175, -189, 386, 31, 384, +210, 148, 261, -189, 193, -402, 71, -347, +4, -91, -7, 181, -25, 296, -68, 197, +-152, -5, -213, -140, -146, -133, 18, -30, +187, 59, 261, 65, 183, -14, 18, -87, +-125, -72, -165, 3, -85, 81, 34, 120, +81, 83, 52, 0, -1, -72, -47, -121, +-52, -130, -28, -81, -12, 17, 9, 136, +39, 220, 62, 204, 65, 54, 33, -155, +-25, -281, -72, -249, -72, -66, -26, 167, +40, 288, 80, 212, 61, 12, -7, -178, +-79, -250, -117, -165, -74, 1, 37, 145, +155, 213, 227, 199, 180, 112, 8, -22, +-206, -157, -368, -258, -345, -257, -97, -129, +247, 56, 502, 205, 495, 240, 198, 165, +-200, 50, -491, -12, -535, 7, -286, 23, +88, -39, 375, -164, 463, -277, 315, -281, +51, -126, -158, 104, -250, 282, -200, 357, +-96, 327, -48, 222, -14, 61, 22, -158, +71, -402, 165, -557, 218, -487, 165, -160, +22, 301, -173, 650, -281, 680, -211, 359, +-19, -116, 189, -462, 274, -535, 158, -346, +-54, -56, -215, 144, -234, 216, -87, 201, +128, 164, 274, 136, 270, 85, 108, -14, +-107, -160, -255, -293, -273, -325, -147, -213, +48, 32, 197, 323, 254, 505, 191, 468, +51, 186, -96, -244, -195, -585, -186, -638, +-95, -352, 13, 118, 114, 498, 175, 596, +170, 381, 106, 22, 11, -251, -97, -327, +-190, -241, -213, -101, -136, -22, 3, -1, +152, 37, 257, 115, 251, 195, 142, 210, +-31, 115, -185, -59, -227, -216, -163, -257, +-40, -165, 98, -4, 153, 149, 119, 206, +67, 146, -3, 30, -48, -90, -41, -157, +-33, -126, -9, -29, 31, 73, 55, 140, +88, 140, 80, 68, -7, -43, -84, -140, +-140, -180, -154, -146, -58, -36, 71, 105, +179, 206, 244, 233, 212, 156, 109, -7, +-46, -167, -242, -257, -349, -244, -292, -130, +-99, 35, 196, 181, 429, 259, 447, 246, +259, 147, -61, -22, -346, -194, -437, -294, +-330, -281, -86, -134, 193, 72, 366, 232, +409, 276, 312, 198, 74, 45, -191, -93, +-389, -157, -428, -146, -253, -101, 47, -62, +319, -33, 430, 3, 311, 71, 63, 166, +-150, 213, -241, 170, -174, 36, -22, -164, +97, -319, 113, -332, 35, -187, -55, 51, +-82, 287, -32, 413, 63, 355, 136, 148, +135, -137, 59, -391, -42, -496, -96, -390, +-69, -103, 23, 268, 106, 567, 105, 619, +6, 372, -126, -85, -191, -543, -116, -761, +56, -610, 225, -163, 303, 357, 234, 695, +62, 707, -120, 413, -249, -22, -270, -390, +-171, -580, -14, -560, 162, -362, 289, -77, +286, 225, 171, 472, -17, 568, -202, 466, +-272, 183, -203, -183, -25, -481, 173, -578, +271, -431, 249, -132, 127, 170, -39, 358, +-153, 378, -188, 258, -160, 94, -75, -37, +20, -123, 93, -156, 138, -155, 165, -144, +186, -110, 182, -47, 105, 37, -43, 111, +-219, 160, -344, 165, -321, 113, -132, 37, +131, -51, 336, -151, 391, -226, 278, -230, +80, -130, -70, 67, -96, 293, -56, 423, +-54, 346, -142, 60, -277, -322, -313, -606, +-155, -599, 174, -272, 547, 219, 722, 645, +550, 784, 101, 537, -448, 35, -813, -485, +-767, -778, -340, -696, 252, -296, 703, 205, +772, 551, 461, 580, -33, 324, -423, -33, +-490, -266, -265, -256, 49, -80, 251, 81, +211, 94, 14, -66, -132, -247, -102, -263, +94, -69, 282, 221, 283, 409, 88, 354, +-201, 84, -385, -228, -318, -372, -59, -283, +238, -51, 417, 160, 377, 217, 170, 125, +-73, -11, -240, -95, -269, -89, -196, -28, +-94, 6, 33, -15, 159, -37, 258, 3, +300, 113, 235, 203, 70, 164, -149, -45, +-330, -320, -349, -456, -188, -316, 84, 77, +348, 508, 446, 684, 307, 457, 7, -59, +-287, -580, -410, -789, -286, -560, 10, -43, +318, 464, 457, 696, 341, 564, 52, 180, +-249, -233, -401, -472, -313, -472, -59, -281, +206, -8, 350, 221, 306, 326, 145, 289, +-33, 143, -147, -53, -141, -220, -67, -285, +0, -225, 37, -70, 32, 120, 27, 262, +55, 285, 91, 176, 118, -22, 103, -222, +24, -321, -55, -285, -91, -133, -85, 69, +-19, 234, 53, 307, 101, 269, 122, 148, +95, -24, 40, -207, 1, -345, -30, -367, +-48, -242, -39, 16, -27, 301, 6, 445, +55, 375, 101, 112, 145, -205, 145, -374, +87, -320, -17, -100, -133, 119, -196, 197, +-155, 105, -5, -63, 173, -149, 282, -84, +262, 88, 112, 243, -96, 265, -232, 103, +-220, -153, -66, -354, 150, -384, 296, -208, +278, 80, 92, 307, -161, 358, -325, 216, +-286, -17, -48, -191, 266, -201, 467, -78, +426, 50, 145, 75, -217, -21, -437, -142, +-402, -159, -142, -25, 193, 169, 386, 287, +346, 224, 174, 0, -26, -232, -147, -328, +-139, -230, -67, -6, 8, 200, 53, 284, +55, 219, 54, 50, 65, -125, 63, -240, +46, -264, 11, -182, -22, -35, -13, 131, +42, 271, 107, 319, 119, 247, 53, 59, +-48, -189, -144, -387, -163, -446, -48, -307, +136, -16, 287, 295, 315, 485, 176, 439, +-59, 174, -252, -155, -293, -368, -160, -361, +63, -167, 234, 58, 272, 163, 180, 112, +20, -20, -100, -97, -103, -51, -15, 81, +88, 187, 144, 166, 106, 37, -11, -119, +-128, -211, -168, -183, -99, -81, 67, 15, +251, 71, 338, 83, 259, 84, 30, 86, +-228, 60, -342, -6, -248, -91, 6, -147, +291, -112, 413, 8, 295, 133, 27, 167, +-240, 62, -351, -108, -233, -226, 30, -199, +293, -27, 414, 172, 315, 264, 78, 184, +-162, -9, -296, -185, -254, -237, -93, -145, +84, 13, 217, 118, 255, 126, 213, 67, +128, -10, 6, -49, -106, -58, -175, -61, +-180, -48, -71, -8, 107, 57, 257, 113, +295, 103, 157, 3, -60, -139, -213, -205, +-225, -122, -65, 60, 157, 216, 264, 218, +206, 42, 35, -184, -125, -282, -136, -169, +-9, 89, 152, 292, 234, 274, 149, 40, +-44, -245, -205, -373, -228, -249, -98, 48, +117, 305, 288, 358, 317, 183, 198, -86, +18, -281, -119, -288, -172, -121, -117, 85, +-19, 203, 51, 175, 83, 27, 87, -138, +84, -213, 82, -154, 66, 3, 31, 171, +6, 253, 10, 198, 50, 43, 108, -126, +116, -230, 23, -227, -125, -147, -218, -59, +-186, 20, 1, 91, 273, 164, 434, 229, +377, 225, 118, 106, -206, -101, -391, -291, +-329, -341, -68, -214, 244, 13, 406, 205, +331, 232, 101, 109, -148, -31, -285, -90, +-243, -35, -65, 57, 134, 68, 271, -27, +311, -142, 260, -175, 140, -75, -21, 98, +-179, 211, -281, 176, -294, 14, -182, -170, +35, -255, 268, -184, 430, -4, 465, 160, +343, 224, 89, 162, -214, 10, -441, -139, +-485, -194, -322, -119, 7, 32, 370, 156, +578, 159, 530, 15, 259, -185, -103, -286, +-359, -204, -387, 37, -221, 293, 29, 376, +208, 229, 253, -54, 206, -288, 121, -328, +52, -174, 12, 43, -26, 155, -75, 103, +-117, -28, -108, -98, -19, -31, 127, 128, +261, 246, 294, 202, 179, -11, -31, -279, +-222, -440, -270, -370, -137, -87, 99, 268, +308, 501, 340, 484, 160, 215, -92, -175, +-248, -476, -209, -527, -7, -311, 209, 33, +305, 314, 230, 390, 58, 256, -74, 32, +-114, -147, -92, -193, -59, -133, -43, -55, +-15, -7, 68, 5, 191, 20, 296, 58, +286, 87, 128, 65, -95, -22, -269, -130, +-295, -177, -145, -123, 75, 23, 252, 177, +310, 246, 218, 197, 56, 48, -81, -141, +-144, -278, -104, -305, 11, -223, 122, -56, +172, 142, 148, 301, 83, 347, 13, 251, +-36, 48, -62, -189, -94, -358, -114, -376, +-65, -247, 63, -25, 242, 204, 380, 334, +362, 320, 177, 192, -109, 3, -347, -180, +-387, -288, -231, -290, 9, -207, 214, -63, +288, 103, 245, 224, 176, 270, 132, 239, +105, 125, 64, -45, -18, -209, -135, -305, +-231, -296, -238, -174, -132, 19, 58, 191, +248, 271, 344, 231, 316, 101, 189, -38, +30, -113, -83, -120, -116, -92, -98, -74, +-83, -97, -77, -120, -52, -71, 5, 64, +116, 214, 234, 279, 262, 173, 171, -60, +5, -269, -123, -308, -115, -130, -9, 152, +99, 321, 123, 236, 14, -63, -122, -368, +-139, -445, -7, -217, 187, 200, 302, 531, +246, 547, 46, 238, -163, -213, -222, -539, +-90, -557, 125, -281, 274, 95, 241, 364, +39, 407, -182, 231, -267, -25, -141, -211, +114, -241, 324, -147, 367, -2, 205, 100, +-63, 111, -256, 65, -249, 4, -57, -36, +177, -46, 280, -43, 196, -57, 6, -84, +-157, -72, -171, -2, -35, 97, 130, 171, +209, 165, 176, 54, 88, -89, 14, -171, +-2, -157, 15, -63, -14, 27, -99, 37, +-169, -25, -140, -89, 33, -67, 288, 58, +461, 225, 428, 314, 166, 219, -215, -50, +-491, -357, -509, -530, -247, -447, 182, -107, +544, 324, 623, 610, 388, 584, -23, 241, +-379, -233, -479, -569, -276, -583, 78, -281, +348, 130, 398, 394, 215, 371, -56, 132, +-213, -115, -175, -194, -2, -69, 184, 126, +229, 195, 127, 40, -10, -240, -110, -426, +-111, -352, -29, -20, 65, 376, 123, 572, +137, 424, 129, 19, 110, -400, 65, -576, +-2, -398, -84, -3, -149, 345, -137, 442, +-48, 253, 98, -70, 253, -296, 325, -295, +272, -111, 118, 97, -105, 182, -299, 109, +-346, -35, -229, -106, 16, -58, 295, 60, +453, 145, 408, 109, 185, -37, -103, -188, +-298, -249, -298, -181, -142, -5, 70, 182, +224, 273, 229, 234, 115, 84, -13, -108, +-86, -236, -65, -240, 31, -133, 131, 16, +179, 135, 147, 163, 62, 95, -32, 2, +-118, -54, -162, -58, -140, -37, -63, -29, +61, -59, 227, -105, 362, -96, 391, -5, +253, 134, -22, 230, -311, 206, -486, 40, +-418, -170, -115, -299, 258, -269, 506, -82, +511, 140, 289, 252, -13, 198, -231, 25, +-277, -141, -176, -189, -48, -97, 31, 56, +68, 149, 98, 128, 159, 20, 235, -102, +244, -149, 120, -95, -96, -8, -285, 51, +-328, 51, -179, 0, 100, -46, 362, -41, +466, 10, 348, 75, 52, 115, -254, 94, +-417, 11, -359, -87, -91, -151, 247, -157, +464, -97, 446, 2, 194, 75, -164, 95, +-420, 65, -409, 17, -126, -5, 264, 18, +540, 66, 534, 79, 225, 28, -212, -80, +-532, -207, -563, -271, -277, -204, 158, -20, +505, 208, 619, 363, 449, 341, 112, 139, +-188, -132, -345, -324, -341, -338, -222, -172, +-76, 46, 56, 172, 168, 150, 264, 36, +320, -58, 295, -54, 159, 36, -51, 104, +-230, 79, -283, -12, -192, -95, -22, -112, +130, -69, 164, -34, 117, -62, 77, -108, +85, -78, 140, 76, 157, 288, 66, 388, +-105, 245, -246, -103, -243, -444, -65, -550, +193, -342, 366, 59, 332, 390, 110, 447, +-165, 248, -317, -41, -257, -211, -38, -186, +195, -50, 316, 46, 268, 22, 87, -76, +-81, -138, -150, -83, -107, 71, 0, 210, +75, 211, 68, 68, 10, -129, -42, -260, +-30, -228, 45, -51, 124, 149, 158, 256, +128, 208, 51, 45, -21, -136, -46, -230, +-40, -190, -38, -69, -63, 56, -86, 115, +-65, 89, 25, 27, 166, -9, 282, 6, +301, 51, 189, 72, -11, 19, -201, -94, +-304, -186, -276, -183, -128, -75, 75, 85, +248, 198, 327, 189, 285, 76, 137, -58, +-55, -127, -196, -109, -227, -39, -149, 21, +10, 29, 166, 19, 247, 24, 210, 48, +65, 48, -110, -18, -233, -135, -239, -215, +-88, -156, 158, 44, 353, 287, 391, 400, +234, 278, -54, -28, -315, -337, -406, -468, +-277, -354, -2, -71, 258, 208, 373, 339, +305, 291, 123, 135, -74, -25, -193, -120, +-195, -133, -116, -98, 9, -65, 141, -44, +209, -34, 180, -17, 74, 26, -70, 80, +-184, 111, -195, 87, -88, 2, 93, -101, +248, -140, 294, -74, 204, 63, 19, 163, +-160, 135, -252, -23, -218, -204, -78, -253, +89, -113, 210, 131, 241, 304, 170, 265, +55, 25, -31, -251, -76, -367, -75, -242, +-61, 44, -61, 295, -42, 354, 15, 201, +109, -56, 201, -251, 217, -298, 129, -202, +-34, -38, -195, 93, -257, 145, -167, 127, +31, 74, 229, 34, 308, 31, 231, 43, +53, 27, -133, -46, -226, -169, -184, -270, +-58, -251, 86, -87, 172, 167, 164, 384, +95, 431, 19, 261, -27, -46, -38, -330, +-40, -451, -47, -357, -45, -120, -9, 124, +63, 270, 146, 281, 181, 194, 113, 72, +-34, -40, -176, -123, -224, -169, -123, -167, +83, -117, 269, -23, 314, 74, 180, 122, +-56, 98, -249, 32, -291, -30, -162, -37, +67, 2, 258, 36, 297, 26, 175, -35, +-22, -94, -163, -88, -173, -8, -78, 86, +47, 107, 115, 18, 96, -123, 34, -199, +-17, -123, -25, 83, 7, 287, 49, 334, +58, 171, 26, -115, -21, -348, -44, -382, +-42, -196, -23, 84, 7, 280, 42, 284, +82, 115, 110, -98, 101, -205, 45, -142, +-36, 30, -114, 181, -147, 196, -106, 55, +-12, -140, 100, -251, 190, -197, 201, -12, +123, 170, 6, 214, -116, 97, -184, -82, +-162, -173, -69, -106, 55, 66, 154, 208, +180, 187, 135, 16, 46, -183, -40, -275, +-82, -194, -83, -1, -68, 169, -40, 216, +9, 132, 69, -10, 115, -110, 125, -118, +89, -50, 7, 37, -88, 82, -144, 55, +-126, -17, -32, -83, 99, -95, 187, -32, +190, 60, 104, 123, -49, 103, -174, -15, +-209, -151, -127, -206, 37, -122, 192, 67, +248, 247, 181, 298, 34, 184, -120, -37, +-199, -255, -180, -359, -85, -303, 27, -122, +129, 100, 191, 285, 202, 367, 149, 319, +21, 152, -139, -91, -255, -325, -259, -441, +-130, -366, 92, -120, 282, 185, 334, 402, +218, 417, -5, 228, -217, -50, -292, -271, +-211, -316, -37, -182, 147, 18, 244, 141, +223, 122, 106, 6, -38, -101, -137, -104, +-149, 7, -109, 150, -33, 204, 46, 127, +91, -38, 104, -196, 85, -245, 52, -162, +21, -13, -8, 120, -48, 186, -74, 158, +-71, 70, -40, -16, 2, -81, 39, -110, +63, -96, 65, -61, 53, -23, 36, 20, +16, 61, 6, 96, -4, 123, -37, 105, +-59, 12, -58, -133, -38, -244, 5, -230, +51, -69, 77, 165, 74, 330, 46, 290, +8, 61, -14, -209, -25, -344, -24, -245, +-13, 10, 1, 227, 2, 260, -6, 116, +-9, -85, 5, -191, 20, -135, 24, 3, +14, 97, -4, 79, 6, -21, 24, -88, +44, -46, 57, 75, 45, 173, -6, 155, +-71, 8, -110, -187, -99, -300, -36, -244, +26, -44, 65, 184, 96, 310, 139, 273, +159, 106, 132, -83, 24, -194, -141, -200, +-294, -123, -343, -32, -220, 19, 41, 36, +319, 61, 446, 109, 355, 146, 97, 119, +-182, 11, -343, -139, -313, -239, -163, -199, +9, -36, 133, 151, 168, 251, 153, 194, +116, 19, 69, -156, 10, -227, -57, -163, +-134, -10, -162, 124, -116, 164, -6, 115, +127, 21, 198, -61, 156, -90, 21, -64, +-120, -29, -187, -18, -133, -13, 1, -1, +154, 26, 209, 75, 123, 109, -51, 80, +-196, -10, -210, -112, -102, -166, 58, -129, +180, -11, 203, 118, 122, 173, 5, 131, +-107, 18, -150, -108, -116, -164, -52, -123, +12, -23, 67, 74, 97, 122, 92, 95, +71, 22, 28, -45, -8, -79, -49, -68, +-96, -25, -134, 8, -127, 17, -41, 21, +115, 38, 258, 70, 270, 91, 110, 50, +-159, -69, -367, -197, -374, -235, -130, -127, +220, 99, 456, 314, 430, 354, 143, 169, +-228, -135, -457, -363, -412, -375, -145, -165, +176, 124, 350, 295, 323, 265, 147, 94, +-61, -81, -190, -145, -184, -86, -88, 3, +11, 34, 46, -7, 3, -60, -41, -63, +-39, 3, 36, 87, 126, 95, 171, 17, +119, -76, -10, -107, -148, -29, -198, 110, +-144, 193, -43, 126, 54, -64, 74, -257, +55, -315, 49, -169, 73, 101, 92, 323, +87, 359, 16, 196, -84, -52, -160, -233, +-174, -262, -114, -175, -24, -71, 63, 3, +121, 46, 156, 93, 149, 172, 107, 238, +23, 196, -72, 22, -157, -203, -206, -355, +-171, -341, -72, -145, 51, 112, 164, 295, +221, 341, 193, 234, 92, 43, -77, -142, +-223, -251, -256, -266, -145, -181, 53, -11, +211, 170, 232, 286, 106, 275, -83, 118, +-228, -111, -226, -287, -90, -329, 99, -210, +217, 22, 214, 252, 112, 362, -28, 302, +-147, 110, -215, -133, -197, -308, -99, -330, +73, -217, 218, -29, 266, 139, 165, 213, +-44, 186, -231, 111, -284, 41, -158, -8, +79, -39, 263, -67, 268, -111, 105, -144, +-144, -131, -285, -70, -234, 30, -23, 140, +202, 207, 282, 187, 163, 78, -68, -84, +-258, -230, -282, -252, -101, -113, 155, 114, +333, 295, 284, 293, 41, 77, -234, -224, +-358, -404, -267, -328, -29, -31, 186, 303, +252, 451, 179, 313, 18, 2, -77, -277, +-61, -356, 11, -211, 37, 39, -35, 210, +-167, 204, -218, 58, -130, -107, 53, -173, +247, -96, 298, 54, 195, 145, -6, 126, +-186, 20, -253, -83, -180, -85, -44, 16, +80, 116, 125, 107, 74, -38, -3, -241, +-45, -336, -12, -203, 57, 110, 103, 415, +57, 507, -56, 298, -176, -100, -193, -434, +-74, -495, 117, -264, 259, 88, 218, 333, +5, 322, -232, 91, -317, -161, -186, -257, +97, -143, 318, 98, 338, 283, 133, 265, +-166, 57, -357, -201, -313, -348, -67, -279, +193, -38, 299, 211, 190, 309, -33, 210, +-220, -10, -225, -195, -72, -216, 136, -69, +255, 119, 181, 211, -20, 140, -213, -48, +-263, -221, -145, -251, 47, -116, 156, 98, +143, 263, 28, 273, -71, 124, -49, -90, +65, -240, 167, -249, 138, -112, -49, 82, +-272, 202, -364, 185, -257, 54, 38, -96, +320, -164, 428, -114, 312, 1, 37, 102, +-229, 129, -344, 79, -288, 1, -103, -54, +104, -68, 201, -61, 178, -56, 42, -48, +-93, -27, -133, 16, -58, 74, 75, 119, +176, 118, 157, 67, 4, -5, -188, -79, +-302, -129, -219, -138, 6, -104, 227, -33, +296, 53, 187, 112, -20, 114, -171, 76, +-186, 35, -75, 8, 65, 3, 105, -9, +36, -64, -88, -137, -144, -169, -81, -115, +59, 26, 182, 169, 211, 221, 109, 159, +-63, 32, -208, -76, -257, -114, -171, -96, +-22, -73, 128, -76, 200, -71, 186, -14, +108, 103, 15, 221, -70, 248, -135, 126, +-187, -98, -210, -294, -142, -342, 11, -205, +211, 41, 344, 251, 321, 317, 115, 226, +-178, 49, -417, -113, -433, -192, -216, -164, +109, -74, 374, 10, 414, 47, 240, 28, +-30, -20, -254, -47, -331, -17, -219, 70, +-27, 169, 153, 205, 215, 121, 126, -78, +-17, -293, -121, -391, -118, -277, -9, 27, +126, 365, 156, 524, 53, 380, -151, -1, +-299, -401, -261, -569, -39, -393, 256, 13, +425, 397, 344, 526, 57, 342, -274, -7, +-468, -294, -394, -377, -133, -262, 174, -57, +361, 112, 346, 184, 178, 176, -37, 132, +-191, 66, -217, -27, -144, -119, -63, -171, +-4, -141, 3, -30, 7, 99, 36, 161, +94, 122, 154, 14, 158, -87, 64, -117, +-98, -63, -242, 22, -270, 68, -146, 48, +40, -10, 201, -54, 237, -40, 153, 21, +15, 77, -108, 81, -153, 15, -119, -85, +-59, -149, -10, -113, 32, 14, 62, 151, +106, 208, 107, 136, 53, -37, -39, -202, +-143, -247, -200, -153, -154, 21, -28, 173, +128, 219, 233, 165, 211, 65, 97, -27, +-74, -91, -206, -132, -230, -157, -140, -156, +-1, -93, 111, 29, 128, 165, 68, 247, +6, 223, -38, 100, -13, -66, 29, -184, +39, -211, 5, -151, -60, -39, -115, 68, +-101, 118, -37, 101, 19, 49, 54, -9, +63, -36, 72, -18, 74, 22, 52, 46, +-12, 30, -86, -23, -152, -75, -149, -91, +-62, -49, 58, 22, 143, 77, 133, 87, +50, 49, -49, -5, -83, -45, -56, -43, +-4, -13, 15, 18, -6, 20, -45, -23, +-55, -72, -4, -85, 72, -31, 115, 80, +79, 185, -20, 203, -126, 101, -163, -79, +-115, -245, 0, -302, 104, -211, 137, -17, +83, 175, -4, 284, -57, 291, -50, 200, +-2, 61, 18, -93, -11, -248, -89, -347, +-144, -332, -123, -181, 3, 79, 161, 343, +247, 467, 203, 378, 52, 111, -116, -194, +-218, -387, -222, -387, -156, -219, -54, 10, +32, 178, 103, 237, 157, 207, 187, 130, +170, 52, 74, -27, -93, -110, -245, -177, +-297, -192, -221, -126, -40, 16, 138, 169, +242, 232, 229, 161, 115, -4, -22, -152, +-113, -176, -134, -55, -99, 117, -49, 196, +-28, 106, -19, -112, -23, -305, -1, -321, +51, -106, 100, 220, 111, 461, 67, 459, +-20, 194, -100, -185, -132, -458, -107, -485, +-30, -265, 36, 67, 53, 317, 17, 357, +-23, 204, -21, -16, 41, -155, 111, -136, +126, -1, 54, 109, -92, 87, -238, -60, +-287, -219, -172, -250, 57, -96, 282, 152, +368, 325, 260, 303, 17, 104, -234, -135, +-372, -255, -331, -203, -137, -59, 93, 45, +261, 42, 293, -9, 210, -9, 69, 88, +-80, 218, -204, 245, -265, 82, -238, -198, +-125, -419, 51, -411, 222, -139, 313, 240, +258, 489, 69, 454, -168, 162, -319, -209, +-310, -419, -144, -363, 79, -112, 237, 158, +250, 279, 124, 204, -51, 27, -165, -113, +-161, -133, -79, -46, 23, 52, 79, 81, +62, 25, 3, -66, -43, -113, -36, -73, +11, 33, 55, 145, 43, 192, -14, 132, +-82, -7, -121, -165, -106, -267, -22, -246, +94, -95, 175, 122, 170, 292, 66, 319, +-87, 179, -203, -46, -223, -219, -138, -245, +21, -131, 159, 25, 205, 100, 131, 55, +-11, -42, -120, -86, -141, -17, -80, 122, +17, 214, 82, 168, 70, 3, 4, -177, +-75, -263, -97, -205, -57, -35, 7, 134, +69, 206, 100, 171, 79, 74, 23, -31, +-43, -103, -105, -124, -127, -120, -102, -85, +-36, -13, 53, 79, 131, 168, 151, 202, +100, 140, -8, -2, -117, -167, -176, -271, +-167, -247, -80, -102, 47, 97, 153, 244, +186, 262, 125, 158, 8, -5, -98, -138, +-163, -173, -163, -120, -98, -25, 0, 54, +88, 80, 123, 54, 98, 4, 41, -45, +-18, -73, -69, -53, -88, 8, -60, 85, +3, 137, 50, 128, 46, 37, 5, -102, +-48, -207, -79, -208, -67, -96, -17, 77, +45, 208, 99, 221, 96, 129, 45, -7, +-21, -117, -84, -161, -114, -139, -105, -83, +-62, -17, 13, 56, 87, 136, 109, 201, +74, 195, -12, 76, -99, -131, -129, -311, +-78, -344, 41, -183, 144, 110, 149, 373, +61, 437, -79, 253, -204, -70, -235, -345, +-149, -423, 19, -260, 190, 20, 275, 245, +228, 311, 90, 212, -95, 36, -243, -113, +-291, -165, -217, -134, -36, -64, 146, 6, +233, 47, 196, 62, 73, 52, -59, 29, +-129, 5, -118, -4, -45, 12, 23, 33, +20, 29, -39, -16, -84, -96, -64, -147, +33, -110, 140, 19, 169, 176, 99, 258, +-53, 190, -201, -11, -238, -229, -143, -326, +32, -231, 188, 11, 230, 256, 137, 357, +-30, 244, -175, -13, -218, -253, -143, -332, +-12, -206, 100, 36, 151, 234, 128, 279, +59, 148, -33, -65, -118, -215, -151, -214, +-126, -77, -48, 99, 57, 209, 130, 191, +147, 63, 80, -88, -60, -185, -163, -186, +-159, -101, -58, 16, 82, 111, 162, 157, +129, 152, 15, 108, -119, 31, -202, -63, +-164, -163, -32, -230, 115, -214, 207, -89, +193, 118, 95, 310, -41, 370, -181, 237, +-251, -49, -212, -335, -78, -449, 104, -315, +240, -5, 255, 294, 144, 414, -49, 294, +-219, 35, -256, -194, -160, -267, 15, -180, +181, -31, 220, 70, 125, 80, -44, 32, +-204, -5, -240, 13, -137, 69, 26, 101, +182, 69, 240, -8, 171, -97, 33, -146, +-134, -129, -239, -60, -221, 36, -125, 124, +8, 164, 127, 138, 173, 55, 170, -57, +99, -140, -37, -153, -139, -93, -173, 1, +-136, 78, -39, 109, 41, 91, 82, 43, +97, 1, 50, -24, -1, -41, -15, -50, +-23, -57, -33, -47, -62, -13, -110, 34, +-97, 69, -22, 76, 75, 54, 171, 14, +171, -11, 71, -25, -62, -43, -181, -69, +-206, -85, -124, -67, -9, 1, 95, 102, +138, 171, 87, 148, 10, 34, -51, -115, +-62, -202, -7, -153, 43, 0, 49, 147, +20, 184, -62, 78, -138, -97, -135, -201, +-61, -143, 58, 42, 139, 208, 118, 219, +41, 61, -29, -148, -48, -246, -1, -147, +28, 77, 2, 240, -71, 205, -167, -21, +-193, -256, -77, -307, 123, -115, 284, 200, +295, 398, 107, 328, -148, 23, -312, -314, +-306, -447, -116, -286, 137, 55, 279, 345, +239, 398, 44, 196, -175, -103, -258, -296, +-172, -285, 13, -104, 166, 105, 185, 202, +76, 154, -59, 29, -130, -71, -93, -84, +1, -29, 60, 26, 47, 40, -31, 10, +-115, -29, -120, -40, -32, -25, 90, 3, +177, 23, 148, 31, 31, 31, -78, 30, +-160, 22, -180, -8, -121, -47, -24, -81, +93, -73, 184, -8, 174, 85, 96, 147, +-22, 133, -167, 30, -242, -121, -206, -232, +-67, -227, 131, -92, 257, 120, 241, 302, +124, 343, -63, 208, -219, -52, -270, -308, +-219, -420, -53, -321, 145, -52, 244, 254, +236, 432, 113, 379, -84, 127, -223, -181, +-264, -379, -170, -361, 32, -141, 204, 140, +266, 315, 193, 298, -14, 118, -219, -101, +-308, -223, -249, -204, -44, -90, 171, 29, +280, 89, 260, 84, 112, 65, -87, 75, +-208, 94, -226, 69, -143, -28, -29, -163, +25, -248, 56, -200, 77, -15, 81, 201, +93, 311, 89, 240, 46, 37, -18, -163, +-116, -241, -205, -162, -207, -10, -120, 96, +18, 97, 143, 20, 198, -47, 181, -42, +106, 29, -11, 113, -103, 132, -138, 61, +-130, -52, -99, -152, -90, -177, -87, -115, +-42, -13, 55, 85, 180, 140, 279, 137, +264, 94, 118, 36, -122, -12, -350, -44, +-430, -77, -313, -114, -59, -140, 206, -129, +360, -56, 332, 73, 170, 214, -13, 287, +-127, 229, -166, 47, -150, -181, -133, -337, +-116, -338, -72, -171, -5, 85, 100, 289, +211, 335, 233, 209, 117, -6, -83, -191, +-243, -253, -246, -168, -104, -7, 91, 128, +208, 174, 163, 113, -3, -7, -189, -111, +-262, -148, -139, -96, 99, 18, 263, 140, +263, 204, 93, 160, -139, 15, -271, -170, +-245, -295, -83, -272, 129, -87, 235, 171, +179, 352, 15, 339, -160, 134, -221, -127, +-145, -286, 11, -254, 147, -73, 171, 104, +86, 143, -31, 39, -118, -99, -110, -136, +-30, -13, 25, 182, 42, 286, 1, 208, +-76, -10, -91, -229, -24, -308, 71, -215, +137, -39, 113, 95, 11, 131, -86, 94, +-139, 56, -114, 69, -29, 114, 54, 116, +85, 27, 38, -122, -49, -238, -83, -241, +-41, -120, 37, 60, 97, 193, 82, 216, +13, 137, -73, 19, -147, -56, -143, -72, +-44, -51, 80, -30, 161, -25, 143, -35, +37, -33, -93, -6, -184, 25, -184, 50, +-92, 59, 62, 53, 189, 47, 218, 28, +127, -11, -45, -66, -206, -125, -252, -137, +-154, -79, 21, 44, 183, 169, 222, 229, +114, 178, -54, 27, -183, -148, -194, -256, +-67, -242, 89, -118, 176, 51, 131, 193, +-6, 247, -118, 203, -149, 82, -95, -63, +-8, -169, 60, -209, 79, -162, 54, -50, +-7, 78, -29, 161, -4, 159, 9, 76, +2, -37, -31, -115, -60, -110, -40, -32, +0, 59, 20, 104, 36, 70, 12, -11, +-25, -79, -35, -92, -17, -40, 31, 33, +67, 65, 32, 37, -44, -24, -119, -53, +-132, -21, -35, 49, 88, 107, 174, 101, +163, 22, 28, -87, -129, -164, -221, -159, +-210, -75, -72, 44, 101, 144, 204, 188, +208, 160, 96, 69, -51, -53, -142, -165, +-160, -218, -115, -175, -39, -40, 21, 126, +51, 246, 43, 240, 24, 100, 40, -99, +76, -252, 95, -261, 44, -120, -71, 85, +-178, 237, -205, 246, -139, 111, 12, -82, +175, -213, 249, -210, 194, -86, 18, 77, +-160, 169, -225, 149, -166, 49, -38, -63, +80, -113, 128, -86, 107, -7, 36, 59, +-23, 64, -41, 22, -46, -31, -46, -61, +-59, -47, -77, 5, -45, 62, 47, 90, +139, 69, 180, 8, 105, -72, -59, -128, +-214, -121, -268, -49, -160, 57, 51, 141, +241, 153, 299, 82, 181, -27, -63, -114, +-260, -144, -300, -103, -155, -24, 87, 49, +236, 97, 228, 105, 89, 76, -103, 24, +-216, -36, -187, -86, -54, -97, 112, -64, +188, -7, 124, 44, -6, 63, -113, 44, +-132, 22, -66, 14, 16, 28, 62, 37, +52, 3, -17, -67, -68, -128, -56, -129, +31, -47, 130, 85, 132, 182, 33, 180, +-107, 80, -208, -60, -188, -153, -59, -147, +83, -68, 181, 10, 173, 42, 62, 34, +-46, 15, -90, 35, -62, 86, 11, 110, +35, 66, -21, -51, -105, -183, -151, -238, +-96, -152, 36, 34, 168, 218, 228, 289, +173, 198, 28, 2, -127, -186, -221, -252, +-200, -168, -85, -1, 35, 134, 107, 161, +96, 82, 46, -39, 6, -115, -15, -94, +-11, 9, 10, 119, 23, 154, 4, 88, +-47, -42, -86, -159, -70, -191, -26, -110, +26, 33, 66, 143, 74, 165, 56, 98, +-1, -8, -71, -88, -95, -95, -72, -50, +-2, -1, 79, 25, 106, 18, 92, 10, +26, 27, -72, 49, -137, 42, -151, -12, +-109, -92, -4, -138, 102, -96, 175, 27, +196, 162, 119, 218, -14, 149, -160, -18, +-278, -177, -267, -228, -114, -139, 99, 30, +291, 172, 327, 195, 176, 86, -55, -72, +-280, -175, -364, -158, -233, -33, 26, 120, +282, 201, 385, 170, 229, 51, -53, -98, +-300, -194, -397, -191, -252, -100, 22, 37, +275, 154, 390, 194, 265, 140, -13, 16, +-245, -112, -344, -177, -247, -133, -33, -5, +145, 115, 237, 163, 205, 106, 68, -9, +-56, -103, -119, -118, -131, -62, -83, -1, +-58, 18, -45, -11, 3, -31, 66, 20, +148, 128, 193, 211, 121, 184, -32, 12, +-199, -223, -301, -371, -232, -326, -32, -97, +197, 197, 336, 388, 280, 372, 57, 173, +-185, -84, -314, -261, -263, -280, -73, -170, +114, -12, 210, 101, 195, 131, 76, 114, +-63, 79, -121, 39, -104, 4, -42, -37, +5, -93, -6, -128, -29, -109, -23, -34, +24, 72, 91, 165, 126, 189, 93, 123, +3, -3, -125, -138, -213, -216, -181, -199, +-58, -80, 98, 78, 214, 199, 202, 231, +90, 141, -49, -23, -165, -172, -181, -218, +-101, -136, 11, 27, 106, 168, 119, 194, +43, 94, -30, -65, -68, -167, -48, -154, +35, -45, 74, 73, 50, 117, -16, 74, +-111, -6, -137, -42, -64, -2, 47, 64, +159, 78, 171, 2, 57, -128, -64, -205, +-147, -143, -138, 35, -36, 213, 40, 263, +67, 140, 57, -84, -7, -250, -34, -237, +8, -64, 56, 157, 93, 272, 44, 195, +-82, -19, -164, -220, -161, -288, -59, -178, +91, 44, 170, 233, 155, 279, 60, 177, +-83, 2, -149, -148, -98, -197, 9, -140, +109, -39, 101, 42, -25, 66, -143, 39, +-177, 3, -87, 7, 110, 50, 258, 102, +262, 108, 128, 38, -118, -84, -310, -201, +-327, -223, -194, -126, 43, 47, 239, 207, +287, 254, 219, 169, 78, 14, -63, -126, +-138, -176, -173, -129, -167, -46, -117, 8, +-61, 21, 26, 25, 138, 55, 217, 109, +229, 131, 130, 69, -60, -69, -214, -202, +-260, -222, -182, -94, -14, 117, 129, 264, +179, 227, 123, 28, 3, -197, -87, -279, +-74, -158, 19, 83, 98, 261, 96, 243, +-5, 44, -126, -190, -170, -283, -108, -171, +21, 61, 146, 241, 166, 249, 79, 94, +-46, -107, -136, -217, -105, -177, 9, -37, +106, 86, 139, 119, 60, 71, -79, -1, +-159, -35, -156, -22, -63, 13, 75, 35, +160, 25, 163, -9, 81, -47, -51, -73, +-126, -81, -110, -54, -42, 18, 47, 108, +85, 166, 57, 137, -1, 16, -70, -144, +-99, -236, -48, -182, 36, 1, 104, 199, +124, 266, 61, 144, -29, -89, -89, -269, +-109, -265, -67, -67, 7, 195, 55, 330, +72, 237, 37, -22, -32, -263, -49, -331, +-17, -184, 39, 80, 90, 265, 67, 257, +-7, 83, -84, -120, -145, -207, -112, -132, +-6, 28, 98, 141, 172, 119, 145, 0, +29, -116, -80, -130, -152, -25, -139, 103, +-55, 151, 36, 75, 110, -65, 124, -157, +70, -127, -8, 2, -69, 128, -87, 170, +-54, 85, -5, -66, 27, -175, 37, -164, +28, -52, 20, 86, 12, 178, 7, 162, +3, 54, -6, -71, -34, -145, -67, -139, +-53, -63, 1, 32, 63, 87, 99, 87, +67, 48, -7, 3, -64, -13, -89, 5, +-56, 23, 12, 6, 65, -53, 74, -119, +27, -141, -43, -66, -77, 78, -49, 205, +15, 244, 73, 148, 76, -41, 30, -214, +-27, -274, -71, -188, -68, -12, -22, 154, +28, 215, 48, 152, 34, 24, -14, -81, +-40, -109, -5, -63, 52, 4, 92, 38, +71, 25, -17, -22, -98, -62, -143, -54, +-129, -3, -27, 53, 94, 83, 167, 78, +171, 34, 80, -25, -26, -72, -91, -88, +-133, -62, -114, -11, -63, 44, -18, 71, +49, 53, 85, 7, 88, -35, 88, -39, +52, 3, 4, 50, -47, 61, -105, 14, +-105, -75, -51, -135, 17, -110, 80, -2, +92, 115, 57, 167, -2, 123, -59, 5, +-73, -104, -30, -138, 43, -96, 91, -12, +77, 58, 8, 70, -71, 43, -104, 12, +-88, -2, -35, -7, 39, -19, 87, -33, +99, -35, 76, -9, 14, 43, -41, 81, +-70, 69, -76, 2, -44, -84, -4, -128, +25, -83, 42, 20, 25, 100, -4, 111, +-16, 52, -1, -37, 44, -69, 76, -26, +58, 48, -3, 80, -81, 24, -149, -88, +-155, -174, -81, -149, 54, -7, 193, 169, +250, 273, 184, 221, 30, 34, -151, -172, +-264, -291, -244, -257, -115, -93, 62, 103, +213, 227, 241, 233, 143, 136, -1, -11, +-128, -135, -156, -182, -83, -142, 2, -43, +73, 65, 81, 129, 12, 113, -59, 45, +-96, -37, -59, -87, 54, -72, 142, -15, +152, 39, 79, 48, -63, 18, -171, -21, +-185, -40, -117, -7, 24, 44, 153, 67, +184, 46, 134, -21, 14, -84, -99, -104, +-133, -66, -113, 9, -52, 77, 27, 109, +84, 87, 112, 29, 96, -27, 28, -68, +-49, -91, -96, -86, -104, -50, -59, 13, +23, 88, 86, 141, 109, 128, 68, 39, +-28, -91, -97, -194, -105, -206, -48, -94, +57, 89, 126, 239, 128, 274, 72, 158, +-44, -56, -139, -254, -165, -324, -120, -233, +4, -26, 125, 189, 177, 301, 161, 261, +72, 103, -45, -81, -130, -200, -167, -199, +-130, -97, -38, 30, 48, 104, 97, 96, +101, 19, 74, -57, 38, -65, 12, -19, +-8, 54, -31, 98, -54, 74, -89, 3, +-102, -64, -57, -88, 31, -60, 130, -1, +172, 35, 110, 24, -5, -10, -118, -22, +-164, 3, -98, 52, 4, 81, 91, 48, +116, -29, 42, -97, -48, -101, -87, -31, +-64, 72, 29, 134, 101, 105, 86, 3, +25, -102, -59, -145, -103, -99, -77, 4, +-26, 81, 31, 93, 68, 57, 62, 12, +42, 3, 22, 29, 8, 40, -1, 5, +-30, -74, -76, -144, -89, -151, -54, -70, +19, 59, 101, 159, 128, 183, 76, 130, +-2, 31, -88, -56, -132, -100, -90, -102, +-15, -80, 61, -49, 107, -10, 80, 32, +34, 66, 6, 77, -32, 54, -54, 8, +-81, -32, -105, -50, -63, -42, 25, -14, +131, 19, 220, 33, 201, 34, 70, 23, +-124, -3, -306, -38, -331, -69, -182, -76, +70, -47, 314, 23, 393, 92, 274, 117, +31, 84, -221, 2, -342, -78, -279, -96, +-89, -47, 117, 21, 226, 54, 197, 15, +79, -65, -33, -109, -85, -67, -73, 45, +-22, 151, 9, 179, 5, 93, -5, -60, +-27, -158, -17, -145, 31, -48, 57, 63, +53, 103, 2, 43, -58, -57, -60, -114, +-24, -83, 30, 21, 81, 124, 71, 160, +17, 117, -45, 28, -97, -60, -81, -124, +-17, -157, 42, -156, 84, -116, 77, -13, +33, 138, 7, 262, -15, 283, -25, 152, +-30, -80, -46, -295, -45, -364, -26, -232, +1, 29, 40, 263, 78, 345, 74, 234, +39, 8, -6, -196, -52, -270, -59, -193, +-39, -28, -33, 121, -13, 173, 5, 132, +17, 35, 49, -55, 62, -87, 54, -59, +41, -2, -14, 42, -76, 44, -103, -5, +-93, -70, -14, -95, 80, -55, 128, 34, +134, 127, 68, 153, -37, 86, -119, -42, +-153, -162, -110, -192, -2, -110, 95, 35, +156, 153, 152, 174, 86, 93, -7, -28, +-105, -118, -170, -130, -164, -81, -87, -15, +31, 42, 144, 80, 196, 97, 159, 101, +60, 65, -57, -29, -148, -142, -159, -209, +-102, -170, -11, -17, 76, 176, 97, 282, +71, 216, 38, 19, -1, -188, -10, -273, +1, -177, -6, 27, -16, 189, -39, 198, +-57, 53, -23, -123, 27, -186, 80, -98, +99, 75, 31, 196, -58, 168, -107, 4, +-94, -171, -11, -224, 90, -121, 138, 65, +111, 210, 10, 212, -99, 69, -142, -109, +-109, -204, -30, -168, 51, -38, 91, 103, +84, 167, 62, 136, 30, 48, -4, -48, +-27, -109, -52, -118, -66, -85, -51, -26, +-34, 47, -1, 105, 45, 113, 67, 67, +74, -3, 49, -64, -3, -83, -31, -58, +-45, -17, -55, 11, -30, 5, -8, -10, +19, -6, 49, 33, 39, 80, 25, 89, +10, 38, -9, -55, -16, -127, -26, -133, +-27, -67, 1, 28, 26, 88, 43, 95, +42, 65, 15, 26, -23, 13, -66, 9, +-90, -21, -60, -76, 23, -122, 118, -117, +170, -32, 135, 90, 14, 167, -129, 141, +-217, 31, -203, -88, -59, -135, 122, -70, +220, 47, 193, 118, 47, 80, -107, -40, +-156, -144, -98, -135, 18, -14, 108, 126, +83, 180, -19, 104, -113, -49, -139, -160, +-47, -142, 95, -15, 190, 128, 181, 180, +57, 97, -95, -66, -181, -192, -172, -204, +-77, -101, 44, 48, 127, 160, 150, 192, +108, 137, 30, 40, -46, -58, -96, -129, +-110, -157, -84, -131, -30, -55, 49, 47, +118, 144, 136, 175, 79, 121, -23, 4, +-116, -113, -160, -166, -110, -125, -7, -18, +98, 89, 162, 144, 129, 118, 41, 28, +-46, -67, -107, -117, -101, -111, -53, -54, +-17, 25, 25, 75, 51, 83, 59, 56, +73, 8, 53, -31, 8, -37, -42, -20, +-87, 0, -82, 8, -23, -7, 46, -22, +95, -22, 81, -3, 7, 6, -68, -3, +-104, -26, -55, -42, 46, -6, 126, 82, +132, 168, 55, 170, -69, 50, -168, -152, +-169, -326, -68, -337, 78, -148, 187, 148, +179, 386, 76, 416, -48, 221, -134, -79, +-131, -305, -53, -347, 30, -210, 79, -7, +59, 133, -2, 150, -26, 91, -11, 41, +33, 40, 66, 71, 35, 63, -25, -29, +-78, -156, -99, -223, -57, -161, 17, 7, +84, 184, 111, 262, 83, 183, 27, 11, +-29, -145, -72, -196, -95, -129, -89, -23, +-52, 45, 10, 59, 86, 40, 147, 35, +150, 62, 79, 82, -42, 50, -157, -42, +-194, -139, -136, -170, -7, -100, 127, 40, +181, 159, 142, 178, 31, 94, -83, -35, +-118, -130, -74, -135, 1, -62, 59, 35, +55, 94, 7, 92, -36, 43, -57, -20, +-30, -61, 21, -76, 55, -69, 61, -36, +34, 22, 2, 80, -9, 113, -16, 101, +-24, 36, -34, -53, -54, -117, -61, -127, +-37, -84, 19, -10, 91, 63, 141, 100, +134, 98, 57, 71, -60, 20, -160, -44, +-192, -94, -129, -109, -8, -66, 118, 18, +184, 100, 150, 128, 53, 70, -45, -44, +-106, -132, -94, -134, -42, -36, 2, 97, +15, 176, -11, 143, -25, 10, 5, -132, +53, -178, 97, -112, 101, 9, 35, 107, +-62, 115, -140, 45, -144, -32, -53, -52, +60, -3, 134, 61, 124, 72, 40, -2, +-54, -106, -106, -154, -81, -95, -3, 48, +71, 185, 85, 213, 41, 102, -37, -75, +-84, -215, -73, -226, -14, -101, 59, 81, +91, 215, 69, 222, 8, 102, -49, -66, +-74, -188, -57, -199, -6, -113, 40, 20, +58, 127, 50, 160, 12, 115, -24, 25, +-34, -52, -32, -87, -12, -75, -2, -38, +-3, -9, 2, 6, 12, 15, 34, 30, +57, 50, 47, 66, 4, 39, -46, -30, +-93, -93, -92, -101, -42, -38, 39, 55, +115, 121, 131, 106, 84, 12, -1, -100, +-75, -155, -105, -110, -86, 9, -38, 116, +14, 144, 50, 89, 65, -5, 68, -74, +55, -82, 25, -44, -25, -6, -67, -1, +-87, -17, -64, -19, 0, 12, 66, 57, +105, 79, 79, 55, 5, -7, -64, -68, +-91, -88, -66, -52, 0, 13, 62, 53, +91, 44, 67, 14, 2, -14, -50, -16, +-77, 3, -68, 15, -33, 6, 9, -17, +48, -29, 79, -17, 83, 20, 57, 52, +6, 47, -63, 7, -112, -43, -114, -71, +-66, -51, 17, -7, 101, 30, 143, 39, +129, 29, 61, 25, -32, 31, -115, 37, +-152, 16, -132, -41, -54, -105, 53, -118, +141, -60, 175, 46, 126, 143, 9, 159, +-103, 73, -156, -52, -128, -133, -25, -128, +78, -47, 121, 45, 83, 77, -9, 48, +-74, -8, -63, -34, 0, -6, 71, 40, +86, 54, 22, 19, -70, -41, -133, -80, +-99, -67, 14, -8, 136, 44, 190, 55, +119, 30, -31, -2, -165, -15, -201, 1, +-122, 19, 33, 12, 163, -13, 188, -36, +106, -38, -32, -17, -129, 9, -134, 25, +-54, 24, 42, 17, 93, 26, 57, 34, +-21, 19, -76, -20, -68, -66, 15, -81, +107, -40, 144, 32, 79, 91, -54, 88, +-183, 19, -203, -68, -96, -102, 75, -46, +216, 55, 227, 121, 113, 95, -61, -18, +-188, -130, -206, -151, -103, -66, 40, 67, +138, 156, 136, 134, 61, 16, -8, -100, +-44, -126, -23, -58, 3, 45, 4, 93, +-34, 47, -73, -52, -63, -122, 8, -87, +105, 32, 154, 150, 112, 174, -12, 70, +-132, -88, -186, -190, -118, -176, 21, -59, +151, 84, 189, 165, 108, 137, -23, 41, +-142, -51, -162, -92, -86, -72, 41, -29, +129, 1, 143, 11, 70, 10, -26, 4, +-86, 10, -97, 24, -51, 36, 4, 40, +42, 28, 45, -4, 26, -49, 3, -92, +2, -102, 10, -53, 10, 44, -4, 143, +-35, 181, -51, 127, -36, -3, 14, -137, +63, -198, 84, -160, 46, -59, -31, 38, +-90, 88, -92, 98, -18, 101, 84, 114, +141, 108, 106, 43, -5, -89, -129, -233, +-176, -289, -121, -192, 12, 28, 148, 251, +194, 342, 127, 246, -1, 26, -114, -182, +-141, -257, -83, -177, 4, -28, 72, 84, +75, 96, 32, 33, -18, -27, -33, -31, +-13, 16, 30, 56, 50, 49, 33, -1, +1, -47, -32, -39, -40, 20, -43, 72, +-35, 51, -30, -50, -10, -162, 25, -186, +76, -73, 115, 124, 110, 278, 54, 277, +-53, 109, -154, -129, -199, -295, -139, -291, +-10, -133, 144, 71, 230, 203, 205, 209, +86, 117, -79, 4, -188, -72, -197, -90, +-107, -70, 21, -53, 129, -46, 138, -25, +80, 16, -8, 73, -67, 109, -48, 93, +0, 31, 47, -51, 38, -118, -10, -139, +-75, -95, -87, -5, -32, 90, 67, 145, +143, 135, 123, 68, 30, -36, -98, -117, +-169, -137, -144, -91, -30, 2, 92, 75, +171, 85, 153, 46, 59, -5, -44, -25, +-120, -3, -131, 31, -101, 32, -35, -11, +26, -68, 95, -88, 129, -40, 129, 44, +87, 105, -12, 93, -101, 4, -165, -94, +-152, -132, -72, -73, 44, 45, 134, 139, +161, 154, 114, 69, 36, -62, -38, -154, +-98, -162, -109, -85, -94, 27, -39, 111, +34, 138, 97, 106, 119, 34, 88, -42, +2, -103, -92, -127, -135, -93, -105, -9, +7, 89, 125, 151, 174, 139, 114, 45, +-17, -83, -147, -176, -195, -174, -136, -76, +-6, 60, 127, 157, 187, 168, 156, 102, +61, 7, -33, -66, -101, -96, -118, -100, +-109, -93, -80, -73, -28, -25, 36, 59, +110, 146, 160, 184, 150, 130, 73, -5, +-46, -150, -157, -218, -194, -162, -142, -18, +-19, 119, 108, 170, 170, 121, 143, 16, +56, -75, -38, -100, -99, -69, -90, -23, +-44, 10, 22, 19, 54, 31, 45, 57, +8, 76, -19, 58, -21, -10, -5, -92, +16, -147, 24, -131, 21, -42, 3, 66, +-4, 145, -15, 158, -8, 106, -14, 20, +-18, -63, -19, -117, 3, -133, 57, -103, +86, -39, 82, 31, 11, 75, -86, 85, +-164, 59, -146, 21, -38, -1, 131, 3, +255, 18, 236, 13, 83, -31, -146, -100, +-290, -142, -286, -105, -113, 3, 115, 133, +276, 210, 274, 179, 123, 51, -75, -101, +-219, -190, -204, -172, -85, -63, 76, 59, +160, 120, 140, 95, 33, 17, -76, -45, +-132, -49, -114, -3, -20, 41, 75, 40, +147, -10, 139, -63, 69, -69, -35, -18, +-120, 63, -163, 101, -134, 61, -46, -32, +62, -118, 165, -129, 184, -49, 130, 72, +12, 154, -104, 144, -175, 46, -160, -79, +-79, -148, 38, -130, 145, -43, 166, 58, +111, 110, -8, 85, -107, 7, -138, -69, +-83, -86, 19, -31, 111, 55, 137, 103, +69, 75, -49, -18, -144, -117, -136, -143, +-41, -68, 95, 63, 166, 162, 132, 149, +13, 26, -114, -124, -159, -190, -101, -114, +25, 58, 127, 199, 138, 207, 48, 64, +-64, -134, -125, -246, -87, -193, 8, -17, +92, 160, 109, 218, 47, 129, -44, -32, +-98, -151, -79, -142, -7, -26, 76, 98, +104, 137, 66, 69, -14, -55, -75, -144, +-94, -134, -67, -39, -20, 76, 33, 132, +73, 106, 87, 28, 84, -43, 50, -60, +0, -22, -68, 22, -115, 22, -133, -20, +-98, -75, -12, -101, 92, -64, 167, 27, +172, 121, 123, 165, 19, 130, -87, 32, +-174, -79, -195, -156, -145, -161, -36, -95, +86, 5, 183, 89, 226, 123, 172, 98, +60, 32, -97, -35, -213, -71, -241, -60, +-160, -14, -12, 34, 140, 55, 225, 35, +206, -16, 108, -64, -49, -73, -172, -39, +-208, 16, -133, 68, 0, 78, 131, 49, +181, -1, 138, -48, 36, -72, -78, -61, +-133, -14, -126, 36, -44, 63, 38, 47, +90, 2, 85, -46, 56, -67, 19, -40, +-20, 15, -40, 59, -59, 61, -47, 23, +-33, -23, 7, -38, 33, -7, 50, 33, +48, 35, 15, -7, -21, -72, -40, -107, +-13, -67, 14, 35, 37, 136, 13, 168, +-27, 102, -58, -21, -58, -122, -19, -156, +34, -110, 80, -31, 87, 32, 59, 69, +3, 75, -35, 79, -67, 79, -70, 45, +-64, -23, -55, -105, -15, -155, 45, -128, +118, -20, 140, 115, 108, 189, 14, 151, +-90, 22, -160, -117, -150, -180, -66, -127, +42, -2, 125, 102, 129, 122, 76, 56, +-4, -37, -51, -83, -54, -53, -21, 25, +9, 89, 25, 78, 14, 0, -26, -87, +-61, -128, -68, -95, -23, -13, 49, 72, +113, 123, 134, 116, 102, 64, 9, 1, +-102, -60, -171, -108, -160, -118, -69, -88, +58, -27, 151, 47, 156, 106, 81, 118, +-17, 84, -81, 32, -89, -16, -40, -48, +17, -70, 38, -85, 8, -90, -35, -64, +-52, 8, -16, 98, 54, 155, 96, 136, +81, 37, 10, -95, -61, -172, -101, -142, +-78, -24, -7, 99, 68, 148, 94, 97, +62, -19, 3, -113, -57, -119, -68, -47, +-42, 35, 12, 71, 40, 53, 46, 13, +27, -7, 3, 8, -11, 37, -13, 31, +0, -20, -8, -89, -17, -127, -35, -89, +-23, 13, 4, 124, 39, 173, 62, 124, +53, 7, 21, -110, -32, -157, -63, -114, +-65, -15, -24, 83, 18, 119, 50, 79, +38, 1, -7, -61, -34, -80, -33, -45, +14, 5, 59, 43, 73, 53, 26, 34, +-43, 8, -103, -11, -97, -15, -25, -19, +68, -31, 122, -49, 91, -56, 15, -36, +-68, 22, -91, 100, -55, 147, 19, 119, +65, 17, 55, -122, 10, -221, -46, -207, +-51, -75, -17, 113, 35, 255, 50, 257, +29, 114, -23, -91, -51, -235, -40, -237, +4, -110, 50, 65, 51, 176, 25, 170, +-32, 79, -57, -34, -40, -96, 7, -88, +43, -37, 44, 5, 12, 18, -32, 12, +-43, 12, -25, 28, 20, 44, 44, 44, +36, 16, -2, -24, -43, -56, -56, -66, +-36, -47, 12, -10, 57, 28, 75, 62, +44, 78, -9, 65, -59, 13, -74, -53, +-54, -101, -5, -99, 43, -30, 68, 62, +56, 120, 15, 99, -30, 11, -50, -85, +-35, -121, -7, -66, 11, 36, 11, 116, +-1, 112, -4, 25, 4, -78, 21, -123, +39, -85, 36, 4, 4, 76, -34, 81, +-57, 37, -42, -19, 0, -43, 43, -24, +54, 6, 41, 8, 2, -20, -32, -46, +-47, -37, -31, 21, -2, 89, 24, 110, +38, 55, 27, -45, 10, -125, -17, -129, +-34, -54, -51, 50, -43, 113, -11, 100, +42, 29, 83, -30, 81, -45, 45, -13, +-34, 25, -99, 19, -121, -30, -79, -74, +-1, -75, 79, -19, 115, 62, 94, 115, +38, 112, -36, 51, -63, -36, -65, -97, +-49, -100, -36, -68, -13, -18, 9, 32, +41, 66, 74, 80, 83, 67, 60, 21, +-5, -45, -76, -88, -124, -88, -106, -35, +-42, 49, 45, 102, 117, 95, 125, 33, +80, -51, -1, -104, -63, -92, -100, -35, +-80, 23, -39, 54, 11, 50, 47, 29, +58, 17, 57, 21, 38, 27, 22, 5, +-4, -42, -35, -84, -72, -93, -86, -50, +-65, 22, -3, 84, 82, 103, 138, 71, +140, 9, 61, -40, -63, -56, -167, -46, +-184, -20, -108, -5, 29, -10, 151, -20, +188, -13, 138, 18, 21, 60, -95, 95, +-160, 83, -138, 15, -71, -80, 1, -150, +55, -148, 99, -65, 133, 69, 127, 182, +73, 206, -32, 112, -146, -58, -214, -200, +-191, -233, -60, -136, 113, 34, 241, 173, +245, 201, 128, 120, -47, -8, -170, -97, +-192, -102, -124, -48, -29, 0, 44, -11, +72, -53, 67, -71, 64, -12, 66, 109, +63, 198, 19, 178, -71, 29, -136, -173, +-134, -278, -54, -206, 66, -4, 155, 195, +152, 253, 54, 132, -73, -73, -153, -205, +-129, -170, -26, -1, 87, 167, 136, 196, +100, 67, 6, -122, -79, -220, -101, -157, +-58, 22, 16, 179, 67, 202, 62, 85, +6, -88, -51, -190, -62, -156, -21, -19, +45, 120, 80, 169, 75, 106, 19, -10, +-46, -98, -97, -112, -90, -59, -38, 9, +28, 42, 67, 31, 61, 2, 38, -18, +12, -7, -5, 33, -13, 64, -7, 56, +-9, 10, -23, -49, -34, -92, -32, -97, +0, -63, 35, -8, 55, 50, 33, 81, +1, 78, -29, 58, -28, 37, -11, 15, +12, -14, 23, -50, 5, -92, -19, -116, +-43, -89, -30, -8, 6, 95, 44, 160, +43, 147, 11, 56, -19, -65, -33, -140, +-17, -119, 7, -26, 34, 65, 33, 86, +4, 24, -34, -62, -54, -95, -33, -40, +0, 72, 34, 154, 36, 128, 28, 1, +6, -143, -3, -199, -5, -128, 1, 30, +-2, 172, -8, 197, -20, 105, -35, -40, +-22, -152, 6, -164, 20, -84, 16, 17, +7, 86, 10, 102, 19, 77, 31, 44, +20, 17, -3, -15, -44, -61, -70, -99, +-67, -101, -20, -53, 40, 27, 74, 101, +64, 125, 20, 84, -27, 15, -54, -45, +-35, -68, -3, -49, 26, -20, 28, 4, +4, 7, -26, 1, -52, -6, -42, -7, +-8, 0, 30, 19, 59, 39, 77, 49, +68, 46, 12, 13, -59, -48, -118, -100, +-116, -109, -58, -52, 41, 47, 129, 124, +158, 131, 91, 57, -36, -56, -143, -129, +-168, -113, -94, -23, 32, 76, 134, 119, +157, 84, 90, 2, -17, -63, -109, -79, +-128, -51, -93, -15, -12, -2, 49, -1, +75, 9, 72, 41, 53, 84, 30, 91, +-3, 42, -47, -45, -75, -123, -70, -136, +-46, -69, -5, 33, 42, 105, 73, 102, +72, 34, 35, -42, -6, -61, -40, -20, +-48, 44, -47, 76, -23, 41, 5, -29, +24, -92, 31, -101, 11, -52, 0, 15, +-8, 63, 9, 71, 22, 56, 20, 39, +-6, 21, -35, -7, -52, -47, -47, -89, +-1, -103, 60, -57, 99, 36, 79, 122, +12, 137, -54, 60, -96, -63, -93, -158, +-59, -157, 10, -51, 69, 102, 103, 212, +84, 201, 51, 65, -5, -112, -67, -236, +-110, -240, -111, -118, -52, 57, 36, 194, +111, 229, 126, 151, 72, 15, -24, -103, +-97, -149, -99, -116, -42, -42, 36, 25, +70, 45, 53, 24, -15, -4, -61, -1, +-50, 37, 13, 79, 66, 78, 64, 9, +13, -90, -63, -155, -92, -134, -61, -20, +37, 117, 125, 190, 137, 145, 55, 5, +-70, -143, -157, -201, -165, -134, -77, 10, +49, 140, 150, 177, 163, 110, 96, -9, +-1, -99, -82, -113, -105, -60, -87, 6, +-43, 42, -10, 22, 23, -12, 38, -19, +59, 4, 60, 42, 44, 56, 16, 29, +-21, -20, -58, -54, -74, -44, -49, -8, +4, 19, 41, 16, 49, -12, 34, -38, +19, -33, -8, 9, -20, 51, -23, 65, +-17, 39, -11, -17, -5, -50, 7, -45, +37, -13, 56, 21, 48, 17, 14, -22, +-47, -60, -98, -57, -111, -9, -63, 60, +25, 111, 115, 105, 177, 42, 156, -40, +49, -103, -94, -117, -198, -81, -212, -22, +-135, 34, 2, 65, 143, 72, 217, 65, +181, 47, 71, 30, -64, 10, -147, -25, +-164, -72, -116, -111, -34, -112, 54, -60, +112, 42, 121, 142, 91, 181, 25, 127, +-59, 0, -117, -138, -121, -196, -62, -136, +27, 7, 113, 138, 125, 169, 63, 85, +-45, -52, -111, -137, -105, -112, -29, -2, +52, 115, 89, 136, 57, 48, -31, -80, +-87, -154, -66, -112, 24, 20, 99, 144, +106, 165, 38, 73, -71, -69, -145, -154, +-144, -128, -44, -30, 80, 64, 159, 90, +149, 43, 67, -14, -42, -21, -121, 27, +-133, 80, -89, 65, -7, -27, 57, -141, +98, -189, 83, -116, 36, 42, -21, 184, +-49, 217, -42, 120, -27, -31, -10, -140, +5, -147, 5, -66, -5, 25, -4, 66, +14, 40, 30, -16, 28, -44, -8, -17, +-28, 39, -35, 77, -18, 70, 1, 17, +21, -48, 16, -85, -3, -75, -22, -34, +-15, 19, 9, 59, 26, 64, 29, 39, +-1, 3, -37, -31, -42, -52, -10, -48, +32, -26, 49, -2, 35, 21, -5, 40, +-33, 47, -47, 48, -23, 30, 13, -15, +34, -82, 14, -131, -24, -121, -21, -41, +12, 94, 50, 205, 55, 217, 22, 102, +-45, -84, -103, -237, -109, -257, -48, -129, +47, 64, 118, 204, 124, 211, 64, 94, +-21, -52, -88, -124, -102, -97, -64, -14, +-24, 48, 8, 41, 17, -19, 21, -59, +19, -33, 43, 40, 67, 106, 62, 94, +8, -1, -72, -112, -121, -160, -113, -98, +-51, 36, 41, 152, 115, 171, 127, 82, +60, -55, -31, -151, -98, -147, -96, -54, +-50, 61, 21, 124, 65, 103, 64, 22, +16, -58, -42, -94, -66, -69, -53, -1, +-8, 66, 34, 95, 55, 69, 36, -1, +2, -77, -24, -116, -34, -97, -21, -22, +-4, 74, 13, 135, 9, 125, -16, 45, +-39, -61, -37, -131, -14, -127, 10, -53, +36, 44, 48, 111, 48, 115, 17, 63, +-23, -3, -63, -64, -78, -95, -83, -88, +-53, -57, 9, -3, 75, 60, 120, 109, +108, 121, 45, 74, -45, -18, -118, -108, +-133, -150, -83, -123, 6, -39, 77, 54, +107, 111, 59, 116, -17, 78, -82, 28, +-77, -22, -29, -59, 29, -85, 67, -96, +70, -76, 32, -11, -38, 71, -83, 123, +-93, 114, -65, 41, -23, -54, 30, -115, +86, -108, 114, -35, 87, 56, 5, 102, +-83, 77, -143, 7, -131, -56, -57, -71, +41, -40, 103, 9, 102, 30, 54, 20, +-27, 1, -71, -6, -68, 12, -21, 36, +14, 40, 12, 8, -9, -49, -19, -86, +-16, -75, 3, -15, 23, 57, 28, 96, +13, 74, -24, 14, -54, -46, -45, -70, +-24, -45, 10, -6, 36, 23, 46, 25, +30, 4, 0, -15, -39, -13, -67, 13, +-70, 30, -41, 28, 7, 1, 52, -35, +65, -47, 39, -24, -7, 17, -48, 54, +-69, 59, -46, 15, -4, -40, 27, -77, +20, -67, -1, -15, -20, 51, -26, 90, +-14, 75, 3, 19, 19, -49, 13, -84, +-11, -67, -33, -13, -31, 40, -22, 63, +-9, 46, -2, 5, 3, -32, 7, -42, +2, -22, 0, 0, -5, 15, -15, 16, +-25, 14, -27, 22, -22, 23, -6, 5, +11, -22, 3, -52, -4, -64, -26, -30, +-33, 41, -22, 106, 0, 114, 12, 49, +18, -56, 3, -130, -29, -127, -54, -48, +-55, 57, -16, 119, 29, 105, 51, 30, +45, -52, 11, -82, -35, -51, -76, 5, +-77, 33, -45, 12, 13, -36, 52, -55, +57, -11, 30, 66, -9, 119, -42, 93, +-52, -13, -43, -134, -32, -184, -14, -119, +-6, 30, 4, 166, 14, 200, 27, 114, +30, -37, 4, -149, -44, -156, -80, -72, +-77, 42, -45, 108, 7, 92, 53, 23, +70, -46, 45, -67, -15, -37, -62, 7, +-81, 38, -67, 43, -42, 32, -2, 15, +29, -3, 39, -20, 27, -46, 12, -66, +-10, -58, -37, -14, -52, 55, -49, 107, +-30, 109, -7, 56, 9, -34, 22, -115, +8, -132, -24, -81, -41, 1, -26, 75, +3, 109, 28, 89, 28, 25, 5, -37, +-47, -73, -90, -66, -90, -29, -35, 9, +40, 31, 88, 22, 85, -3, 25, -13, +-61, 5, -114, 32, -108, 53, -54, 40, +17, -16, 65, -79, 60, -103, 18, -69, +-30, 15, -59, 100, -65, 133, -54, 92, +-34, 1, -9, -82, 29, -111, 48, -74, +43, -5, 15, 39, -32, 39, -86, 12, +-115, -6, -95, 13, -25, 49, 46, 72, +78, 42, 79, -40, 44, -117, -8, -141, +-50, -83, -79, 34, -85, 134, -73, 153, +-46, 81, -12, -32, 30, -116, 56, -128, +63, -63, 34, 32, -10, 97, -50, 101, +-79, 46, -76, -31, -53, -85, -28, -91, +-9, -44, 6, 19, 13, 67, 15, 81, +16, 55, 10, 6, 3, -37, -20, -52, +-35, -45, -49, -27, -61, -11, -64, -5, +-45, -3, -7, 10, 33, 42, 61, 73, +56, 64, 21, 17, -43, -53, -93, -112, +-100, -107, -65, -40, -13, 53, 37, 110, +58, 92, 30, 26, -21, -46, -67, -71, +-76, -34, -54, 25, -28, 61, 10, 34, +31, -30, 26, -76, 9, -75, -9, -9, +-35, 71, -50, 107, -69, 74, -69, -10, +-44, -85, -9, -106, 27, -63, 50, 14, +50, 74, 30, 81, -13, 42, -61, -11, +-89, -41, -98, -40, -83, -19, -40, 0, +3, -2, 48, -13, 71, -21, 63, -3, +24, 39, -23, 67, -62, 69, -90, 28, +-101, -39, -93, -95, -54, -117, -6, -79, +43, 3, 73, 90, 73, 135, 45, 110, +-10, 34, -74, -49, -110, -100, -112, -88, +-92, -37, -49, 15, 5, 29, 53, 6, +77, -19, 70, -16, 43, 31, -17, 91, +-88, 102, -138, 50, -143, -56, -92, -151, +3, -167, 92, -90, 132, 46, 99, 148, +-3, 165, -119, 89, -179, -23, -159, -94, +-60, -98, 61, -47, 141, 11, 131, 30, +31, 14, -98, -12, -173, -11, -173, 27, +-91, 59, 23, 60, 102, 10, 118, -62, +70, -96, -20, -69, -96, 9, -129, 84, +-118, 104, -69, 56, -14, -35, 41, -99, +74, -98, 65, -34, 20, 58, -47, 110, +-105, 91, -120, 13, -86, -74, -25, -112, +43, -81, 69, 2, 40, 83, -17, 114, +-68, 82, -84, 6, -75, -71, -40, -114, +5, -101, 29, -33, 17, 44, -1, 98, +-17, 105, -32, 61, -38, -7, -47, -68, +-60, -88, -52, -72, -30, -36, -6, 15, +20, 53, 33, 67, 23, 62, -16, 40, +-64, 4, -80, -38, -82, -70, -54, -80, +-5, -58, 22, 0, 27, 59, 13, 93, +-28, 87, -57, 35, -57, -29, -38, -76, +-7, -85, 10, -45, -3, 6, -28, 41, +-63, 52, -77, 31, -49, 1, -4, -23, +35, -20, 49, 0, 17, 22, -34, 32, +-76, 14, -106, -14, -89, -41, -42, -58, +11, -46, 50, -6, 57, 45, 33, 79, +-17, 73, -81, 36, -114, -22, -101, -69, +-62, -75, 0, -50, 56, -7, 70, 28, +41, 40, -26, 35, -89, 21, -108, 12, +-84, 6, -42, -7, 12, -27, 41, -49, +38, -44, -2, -7, -48, 40, -66, 72, +-61, 49, -40, -12, -12, -70, 3, -88, +-2, -35, -16, 50, -41, 107, -50, 93, +-40, 9, -27, -88, -11, -132, -4, -88, +0, 16, -8, 109, -24, 128, -43, 65, +-57, -30, -66, -94, -57, -92, -26, -31, +4, 34, 31, 56, 32, 31, -11, -9, +-65, -18, -93, 10, -91, 50, -49, 64, +13, 16, 57, -63, 49, -124, -17, -120, +-85, -35, -114, 74, -94, 153, -27, 148, +48, 60, 78, -48, 57, -128, -11, -130, +-88, -67, -119, 14, -111, 70, -74, 62, +-20, 13, 30, -28, 56, -22, 53, 34, +26, 86, -14, 94, -72, 33, -130, -83, +-146, -172, -114, -179, -34, -76, 67, 88, +126, 207, 111, 229, 20, 130, -100, -43, +-184, -178, -179, -214, -91, -133, 33, 3, +109, 112, 100, 145, 30, 92, -71, 14, +-132, -43, -120, -54, -63, -26, 9, -5, +51, -11, 33, -28, -12, -34, -45, -1, +-62, 46, -54, 77, -37, 65, -24, -2, +-18, -74, -30, -108, -28, -76, -8, 13, +0, 98, -2, 129, -22, 83, -63, -9, +-78, -100, -67, -143, -39, -101, 9, -7, +44, 89, 32, 144, -12, 117, -66, 37, +-100, -59, -96, -123, -56, -118, 3, -55, +48, 30, 51, 81, 21, 83, -42, 45, +-92, -7, -104, -31, -80, -29, -38, -11, +11, 1, 35, -15, 22, -28, -8, -23, +-35, 4, -43, 53, -50, 76, -56, 52, +-54, -8, -57, -75, -42, -97, -13, -63, +16, 9, 30, 79, 20, 93, -23, 54, +-60, -9, -70, -47, -61, -42, -44, -18, +-38, 4, -39, -8, -37, -41, -24, -48, +8, -14, 58, 57, 68, 121, 22, 125, +-72, 54, -167, -68, -188, -163, -126, -177, +-13, -99, 101, 43, 151, 152, 104, 180, +-3, 115, -109, -1, -158, -95, -132, -135, +-71, -102, 0, -34, 34, 27, 29, 63, +5, 60, -18, 40, -30, 20, -23, -2, +-25, -18, -42, -36, -54, -42, -61, -33, +-52, -9, -33, 33, -12, 61, 7, 57, +11, 18, -2, -42, -16, -79, -33, -76, +-53, -23, -61, 50, -71, 97, -55, 97, +-17, 37, 6, -47, 16, -102, 13, -110, +-8, -56, -38, 26, -60, 92, -65, 119, +-50, 79, -39, 6, -33, -64, -25, -104, +-14, -90, 8, -43, 28, 18, 20, 73, +-10, 92, -63, 78, -126, 28, -137, -31, +-90, -69, -3, -85, 88, -57, 118, -6, +84, 41, -15, 71, -128, 56, -180, 14, +-149, -32, -60, -54, 47, -38, 104, -7, +86, 28, 25, 37, -62, 18, -123, -15, +-113, -41, -65, -34, -8, -2, 26, 29, +32, 43, 11, 30, -25, 4, -58, -25, +-71, -40, -67, -34, -44, -22, -10, 2, +4, 29, 13, 51, 17, 58, -3, 34, +-44, -6, -75, -58, -83, -100, -70, -89, +-30, -39, 13, 47, 41, 119, 34, 129, +-9, 85, -57, -6, -88, -89, -79, -123, +-41, -105, -7, -40, 13, 30, 7, 72, +-31, 82, -54, 59, -43, 26, -13, -3, +10, -26, 12, -42, -19, -55, -58, -55, +-90, -30, -86, 8, -35, 48, 23, 67, +62, 58, 50, 19, -9, -30, -65, -59, +-98, -65, -101, -28, -61, 17, -2, 47, +28, 54, 33, 21, 6, -16, -27, -34, +-48, -31, -50, -3, -43, 26, -42, 38, +-43, 19, -36, -25, -28, -53, -7, -48, +28, -7, 34, 48, -4, 83, -57, 71, +-99, 8, -107, -56, -74, -85, -6, -73, +59, -17, 72, 41, 26, 66, -43, 53, +-96, 11, -98, -21, -51, -31, -6, -13, +24, 14, 15, 18, -30, -1, -63, -30, +-60, -46, -22, -35, 23, -2, 34, 43, +4, 71, -41, 62, -84, 29, -91, -22, +-61, -62, -18, -73, 17, -54, 23, -14, +4, 27, -9, 57, -12, 62, -19, 37, +-24, 3, -43, -30, -67, -49, -80, -40, +-77, -16, -37, 13, 23, 31, 66, 33, +72, 22, 27, 0, -43, -20, -97, -39, +-120, -44, -100, -19, -38, 19, 19, 58, +47, 74, 43, 52, 3, 5, -38, -65, +-53, -113, -55, -101, -39, -39, -25, 52, +-23, 117, -23, 130, -19, 79, -3, -7, +6, -75, -10, -108, -34, -91, -58, -50, +-71, -8, -61, 42, -18, 73, 35, 87, +64, 83, 43, 52, -18, -6, -76, -77, +-122, -126, -113, -129, -65, -71, 0, 30, +61, 117, 84, 152, 45, 129, -13, 42, +-60, -64, -98, -136, -95, -143, -63, -78, +-21, 20, 12, 106, 17, 130, 6, 80, +-12, -5, -24, -83, -24, -101, -14, -56, +-6, 22, -2, 80, -28, 73, -66, 13, +-79, -58, -63, -95, -19, -56, 35, 28, +63, 99, 48, 106, -6, 38, -75, -58, +-114, -122, -95, -114, -33, -35, 35, 62, +66, 122, 47, 105, -7, 29, -73, -48, +-104, -88, -79, -71, -28, -28, 28, 9, +56, 27, 38, 20, -3, 14, -49, 16, +-74, 31, -72, 44, -49, 24, -23, -18, +-2, -63, 4, -80, 3, -50, 0, 3, +-11, 58, -15, 83, -16, 62, -24, 10, +-30, -48, -34, -68, -38, -49, -36, -5, +-34, 38, -25, 49, -14, 34, 3, -9, +23, -41, 17, -35, 5, -12, -12, 22, +-48, 42, -81, 29, -80, -3, -59, -29, +-30, -29, 15, -11, 54, 5, 66, 13, +40, 7, -15, -5, -66, -6, -95, 7, +-89, 23, -58, 24, -17, 1, 23, -34, +37, -54, 24, -38, 5, 11, -7, 59, +-22, 79, -45, 49, -61, -17, -64, -75, +-47, -83, -16, -37, 19, 28, 39, 75, +32, 67, -6, 15, -52, -42, -77, -64, +-58, -37, -8, 17, 25, 55, 33, 47, +11, -1, -31, -53, -60, -67, -58, -33, +-29, 31, 9, 74, 21, 70, 1, 20, +-27, -49, -42, -82, -27, -68, 6, -16, +27, 46, 21, 71, -22, 55, -75, 7, +-84, -44, -50, -62, 5, -43, 55, -1, +66, 31, 29, 39, -33, 22, -76, -9, +-77, -28, -36, -29, 6, -9, 17, 17, +1, 29, -24, 28, -39, 16, -39, -6, +-10, -24, 26, -41, 35, -41, 5, -19, +-36, 8, -59, 46, -57, 70, -27, 61, +-6, 23, 3, -35, 0, -86, -12, -97, +-25, -60, -14, 5, 11, 76, 27, 110, +17, 89, -27, 36, -72, -26, -91, -71, +-74, -82, -27, -64, 30, -33, 76, -1, +81, 27, 42, 56, -18, 73, -68, 73, +-95, 51, -93, -7, -66, -76, -17, -120, +28, -114, 55, -49, 65, 43, 46, 119, +2, 140, -51, 99, -90, 14, -101, -70, +-78, -113, -23, -108, 41, -62, 81, 6, +80, 56, 38, 80, -30, 75, -80, 42, +-101, 2, -94, -36, -49, -62, 16, -58, +64, -31, 78, 14, 50, 52, 2, 55, +-41, 25, -71, -22, -89, -51, -75, -47, +-26, -13, 26, 34, 55, 61, 57, 49, +36, 7, -2, -38, -46, -58, -76, -47, +-72, -9, -40, 29, 0, 43, 22, 33, +24, 9, 15, -14, 0, -17, -16, -8, +-16, 4, -13, 11, -7, 4, -19, -7, +-40, -24, -44, -31, -26, -24, 4, 1, +38, 32, 56, 52, 38, 54, -13, 30, +-62, -17, -88, -64, -77, -81, -34, -62, +17, -9, 51, 48, 62, 86, 36, 86, +2, 42, -19, -13, -35, -58, -54, -78, +-68, -71, -59, -49, -31, -12, 13, 30, +60, 73, 83, 94, 78, 84, 24, 43, +-58, -29, -121, -103, -120, -141, -69, -113, +3, -28, 59, 78, 76, 153, 53, 156, +12, 78, -24, -36, -41, -129, -29, -153, +-19, -93, -29, 8, -38, 93, -30, 114, +-7, 76, 17, 1, 39, -66, 38, -86, +17, -55, -18, 3, -50, 51, -49, 62, +-24, 42, 3, 2, 17, -29, 14, -41, +-2, -39, -20, -27, -23, -16, -8, -2, +3, 22, 5, 48, -2, 60, -12, 49, +-11, 14, -5, -31, -8, -67, -9, -73, +-14, -44, -30, 0, -40, 35, -22, 53, +10, 52, 44, 39, 55, 20, 32, -2, +-11, -30, -46, -58, -71, -71, -72, -59, +-31, -18, 22, 44, 51, 94, 51, 99, +26, 55, -2, -18, -25, -80, -33, -103, +-34, -73, -30, -8, -15, 48, 0, 68, +7, 54, 19, 21, 27, -12, 24, -29, +2, -26, -34, -16, -52, -14, -38, -19, +-6, -19, 34, -10, 60, 12, 46, 38, +-3, 48, -56, 42, -89, 11, -75, -30, +-20, -60, 48, -66, 87, -46, 83, -6, +31, 44, -29, 70, -62, 68, -68, 35, +-54, -13, -33, -51, -5, -64, 12, -50, +23, -16, 41, 20, 63, 41, 61, 42, +24, 26, -44, 4, -105, -13, -116, -17, +-78, -14, -13, -8, 65, -8, 122, -15, +117, -16, 45, -7, -39, 7, -96, 28, +-100, 43, -62, 35, -14, 11, 28, -26, +61, -56, 58, -63, 24, -39, -12, 8, +-33, 55, -37, 73, -24, 53, -10, 8, +10, -46, 31, -75, 34, -66, 5, -20, +-22, 29, -37, 61, -40, 66, -29, 41, +-1, -1, 24, -41, 44, -61, 43, -55, +21, -28, -13, 8, -33, 36, -39, 49, +-31, 46, -17, 27, -5, -3, 3, -32, +22, -50, 32, -47, 24, -24, 10, 7, +1, 27, -10, 32, -21, 25, -30, 11, +-26, -1, -9, -5, 10, -6, 8, -8, +1, -13, 10, -21, 13, -20, 8, -11, +5, 3, 6, 19, 4, 31, -4, 30, +-24, 20, -40, 4, -28, -16, -10, -31, +-6, -37, 4, -34, 27, -20, 46, 11, +43, 50, 24, 74, -10, 71, -41, 31, +-69, -32, -86, -89, -66, -111, -3, -81, +65, -8, 108, 76, 107, 131, 55, 131, +-27, 69, -91, -31, -112, -123, -81, -156, +-21, -115, 40, -28, 68, 68, 70, 130, +39, 133, 3, 77, -17, -4, -19, -73, +-25, -104, -32, -87, -35, -41, -30, 11, +-6, 47, 34, 56, 61, 46, 68, 25, +40, 6, -21, -15, -81, -28, -96, -33, +-58, -30, 8, -13, 69, 9, 100, 28, +78, 37, 17, 33, -59, 10, -103, -22, +-95, -38, -41, -39, 23, -23, 69, 7, +89, 36, 71, 56, 22, 55, -38, 31, +-81, -15, -86, -61, -55, -86, -8, -73, +38, -21, 78, 47, 77, 101, 38, 106, +-11, 58, -53, -18, -70, -86, -44, -117, +5, -87, 38, -13, 48, 59, 22, 99, +-20, 86, -40, 34, -24, -27, 3, -63, +34, -63, 52, -37, 36, -7, -11, 17, +-50, 26, -58, 26, -34, 24, 9, 19, +35, 15, 32, 2, 27, -21, 5, -37, +-17, -42, -18, -24, 0, 6, 12, 34, +5, 46, -18, 35, -30, 11, -24, -13, +2, -24, 14, -17, 24, -6, 31, 5, +11, 10, -22, 2, -31, -9, -14, -15, +14, -7, 28, 6, 16, 18, -15, 27, +-38, 30, -50, 21, -29, -4, 18, -24, +65, -40, 78, -48, 51, -38, -6, -11, +-66, 31, -87, 62, -58, 72, -16, 58, +31, 13, 57, -40, 52, -78, 29, -84, +7, -51, -13, 4, -25, 56, -18, 73, +-19, 57, -35, 23, -35, -12, -10, -28, +27, -20, 58, -3, 62, 1, 30, -8, +-14, -30, -51, -45, -77, -30, -59, 9, +2, 59, 54, 91, 69, 87, 40, 43, +-4, -28, -32, -93, -36, -125, -30, -103, +-18, -36, 9, 46, 19, 113, 8, 131, +5, 96, 19, 28, 32, -50, 26, -98, +-16, -105, -55, -79, -63, -33, -37, 15, +3, 56, 53, 82, 91, 85, 80, 64, +21, 16, -43, -51, -86, -105, -83, -117, +-45, -74, 10, 6, 56, 91, 80, 134, +62, 110, 18, 24, -25, -75, -52, -130, +-58, -113, -29, -33, 4, 61, 25, 113, +34, 95, 32, 20, 13, -58, -5, -93, +-17, -66, -18, -1, -10, 61, 4, 75, +6, 37, 3, -21, 5, -62, 8, -62, +1, -23, -3, 26, -5, 52, -5, 50, +-6, 27, -7, -6, -2, -29, 17, -33, +30, -25, 17, -15, -8, -7, -23, 3, +-31, 18, -29, 33, -11, 33, 14, 19, +38, -4, 47, -31, 28, -45, 2, -37, +-16, -4, -33, 33, -40, 42, -28, 23, +0, -15, 29, -43, 43, -38, 34, -6, +12, 32, -8, 48, -21, 34, -35, 1, +-24, -34, 2, -42, 18, -17, 25, 14, +26, 27, 8, 10, -13, -21, -28, -43, +-28, -33, -9, 12, 15, 71, 27, 93, +35, 59, 26, -16, 6, -98, -26, -129, +-46, -90, -43, -5, -19, 81, 8, 126, +35, 102, 51, 28, 49, -41, 24, -82, +-11, -80, -40, -41, -48, 5, -45, 29, +-26, 28, 7, 18, 40, 15, 56, 19, +50, 23, 18, 12, -15, -15, -38, -42, +-53, -50, -45, -39, -3, -9, 41, 31, +58, 58, 43, 53, 8, 24, -33, -19, +-44, -55, -31, -56, -3, -31, 31, 3, +47, 33, 27, 41, -2, 25, -24, -2, +-34, -23, -19, -30, 13, -22, 34, -5, +30, 9, 11, 15, -16, 15, -28, 8, +-15, -3, 2, -8, 14, -11, 21, -9, +7, 1, -25, 15, -39, 21, -20, 21, +8, 17, 29, 2, 35, -19, 19, -31, +-5, -27, -20, -9, -37, 16, -36, 35, +-5, 29, 26, 9, 29, -14, 28, -26, +17, -15, 8, 5, -4, 18, -25, 16, +-45, -2, -40, -23, -17, -30, 12, -13, +46, 20, 77, 42, 67, 45, 13, 18, +-54, -25, -97, -56, -93, -57, -35, -25, +37, 23, 88, 58, 100, 57, 65, 25, +-7, -10, -66, -35, -88, -34, -65, -18, +-12, -2, 31, 7, 41, 6, 38, -4, +28, 2, 16, 21, 10, 39, -5, 42, +-21, 8, -34, -38, -46, -70, -42, -68, +-14, -22, 37, 40, 78, 85, 81, 83, +43, 34, -19, -35, -64, -87, -77, -87, +-62, -40, -20, 24, 41, 71, 77, 79, +71, 43, 40, -11, 3, -51, -31, -58, +-48, -48, -54, -19, -49, 13, -13, 33, +30, 50, 51, 55, 60, 39, 53, 3, +21, -41, -30, -78, -66, -87, -72, -46, +-41, 18, 12, 76, 52, 100, 61, 73, +47, 9, 16, -56, -21, -83, -39, -68, +-33, -26, -14, 13, 4, 32, 8, 25, +12, 8, 17, 6, 21, 21, 23, 30, +22, 16, 2, -19, -25, -66, -39, -91, +-33, -68, -10, 1, 19, 83, 40, 130, +41, 109, 22, 26, -4, -73, -27, -135, +-29, -127, -16, -54, -5, 40, 1, 101, +14, 104, 25, 53, 29, -16, 27, -57, +11, -52, -13, -21, -32, 8, -45, 14, +-36, -2, 1, -18, 43, -14, 58, 11, +44, 44, 7, 60, -26, 32, -50, -11, +-50, -46, -19, -54, 18, -28, 44, 12, +38, 38, 16, 33, -5, 10, -17, -10, +-18, -12, -7, 11, 3, 34, 2, 32, +-7, 0, -10, -40, -7, -61, 11, -44, +24, 9, 27, 58, 21, 71, 4, 45, +-22, -5, -32, -55, -19, -67, 1, -39, +16, 1, 19, 30, 13, 29, 10, 8, +7, -3, 1, 5, -5, 24, -4, 28, +-8, 5, -23, -39, -26, -77, -3, -81, +28, -33, 45, 49, 40, 108, 18, 104, +-16, 39, -45, -56, -52, -128, -28, -126, +15, -56, 52, 39, 56, 106, 32, 109, +-1, 44, -34, -35, -54, -82, -43, -78, +-17, -30, 20, 24, 47, 50, 52, 34, +40, -4, 14, -33, -23, -33, -54, -2, +-63, 35, -41, 43, 5, 21, 54, -16, +81, -47, 70, -51, 25, -25, -37, 19, +-76, 47, -72, 51, -36, 36, 14, 8, +58, -16, 72, -26, 49, -24, 4, -12, +-30, -3, -38, 4, -33, 20, -23, 33, +-9, 41, 10, 38, 24, 23, 26, -4, +25, -31, 18, -43, 8, -38, -8, -17, +-25, 18, -31, 51, -16, 68, 2, 57, +16, 17, 23, -29, 26, -62, 18, -67, +6, -43, -4, 4, -10, 51, -13, 72, +-14, 61, -20, 25, -17, -22, 8, -60, +31, -65, 33, -47, 30, -16, 15, 18, +-13, 41, -34, 47, -31, 31, -18, 5, +3, -31, 26, -59, 27, -65, 17, -51, +10, -10, 0, 33, -2, 51, 5, 37, +7, -3, -4, -45, -10, -60, -17, -37, +-20, 1, -5, 27, 21, 24, 35, -7, +33, -37, 16, -43, -7, -19, -21, 24, +-20, 55, -19, 41, -12, -9, 6, -63, +23, -83, 27, -50, 27, 13, 25, 68, +9, 82, -10, 44, -29, -20, -38, -62, +-20, -54, 10, -3, 24, 51, 26, 70, +18, 46, -2, -10, -20, -50, -23, -45, +-10, 0, 11, 59, 24, 90, 14, 72, +-14, 21, -25, -34, -21, -59, -9, -40, +15, 4, 34, 42, 29, 55, 10, 39, +-16, 19, -34, 5, -21, 1, 9, 9, +20, 11, 22, -3, 17, -23, -8, -27, +-25, -14, -10, 15, 13, 45, 29, 52, +32, 29, 14, -14, -22, -48, -42, -56, +-33, -36, -11, 5, 28, 34, 62, 37, +49, 20, 18, -13, -13, -35, -42, -41, +-48, -37, -24, -27, 10, -20, 32, -14, +41, -5, 36, 10, 19, 27, 4, 35, +-11, 11, -25, -39, -28, -89, -21, -108, +-14, -81, 1, -14, 30, 59, 54, 98, +54, 84, 31, 25, -11, -49, -48, -101, +-58, -106, -43, -63, -13, -3, 31, 39, +62, 51, 56, 35, 31, 9, 2, -4, +-23, 1, -36, 14, -32, 16, -21, 1, +-2, -33, 16, -57, 20, -48, 22, -6, +21, 56, 11, 105, -2, 108, -12, 67, +-15, -1, -7, -64, -1, -86, 1, -60, +10, -8, 13, 49, 3, 84, -4, 82, +2, 52, 14, 20, 20, -1, 17, -9, +4, -4, -16, -2, -25, -9, -22, -13, +-7, -5, 21, 19, 37, 48, 31, 62, +15, 45, -3, 11, -21, -24, -21, -47, +-6, -39, 8, -7, 15, 23, 11, 36, +-7, 25, -15, -4, -8, -23, 8, -28, +27, -14, 33, 3, 18, 12, -12, 2, +-39, -18, -45, -32, -21, -38, 22, -31, +53, -14, 61, -8, 41, -10, -2, -21, +-40, -30, -54, -25, -35, -16, 0, -7, +31, -3, 41, -10, 32, -22, 16, -35, +-2, -36, -19, -22, -21, -6, -12, 1, +-9, -5, -8, -16, 9, -25, 27, -20, +35, -4, 33, 15, 16, 23, -9, 9, +-27, -17, -38, -39, -31, -46, 3, -26, +36, 13, 43, 46, 34, 55, 25, 42, +6, 15, -12, -10, -19, -16, -23, -7, +-21, 3, -14, 12, -6, 10, 10, 6, +39, 19, 59, 48, 44, 76, 8, 83, +-28, 55, -62, 2, -71, -51, -32, -78, +23, -54, 61, 12, 81, 75, 63, 112, +7, 106, -39, 61, -59, -1, -55, -46, +-24, -59, 19, -47, 38, -16, 36, 17, +37, 35, 27, 47, 8, 47, -4, 34, +-19, 9, -35, -25, -33, -55, -17, -61, +6, -39, 41, 1, 62, 33, 46, 43, +9, 22, -23, -21, -49, -58, -51, -67, +-23, -46, 16, -12, 45, 16, 49, 19, +27, -3, 2, -35, -8, -56, -13, -55, +-16, -40, -1, -26, 12, -16, 12, -16, +8, -12, 1, -5, 1, -1, 4, 0, +6, -18, 3, -42, 8, -59, 18, -53, +13, -23, 6, 14, -1, 40, -12, 34, +-20, 3, -11, -35, 6, -49, 20, -27, +37, 10, 34, 45, 8, 51, -12, 25, +-27, -12, -37, -37, -25, -28, 2, 9, +20, 50, 28, 72, 34, 65, 24, 32, +7, -4, 2, -32, -4, -32, -21, -2, +-24, 28, -18, 51, -13, 59, 14, 51, +44, 37, 47, 21, 34, 8, 18, 1, +-15, 3, -45, 11, -48, 20, -36, 26, +-12, 24, 23, 14, 51, 4, 57, 3, +55, 13, 32, 29, -12, 28, -47, 14, +-61, -10, -54, -35, -25, -39, 20, -19, +57, 9, 74, 27, 60, 28, 17, 7, +-28, -23, -49, -40, -47, -38, -33, -22, +-3, -11, 28, -10, 35, -19, 31, -31, +27, -30, 23, -18, 10, -2, -7, -5, +-22, -30, -32, -59, -27, -69, -12, -47, +14, -5, 47, 31, 61, 42, 42, 13, +7, -47, -29, -90, -47, -97, -40, -62, +-15, -2, 16, 50, 38, 66, 45, 40, +29, 1, 7, -33, -5, -48, -15, -38, +-24, -21, -27, -8, -21, 0, -1, 6, +25, 19, 45, 37, 55, 48, 45, 44, +5, 25, -43, -5, -67, -27, -60, -27, +-20, -10, 33, 18, 69, 40, 75, 48, +44, 47, -4, 42, -46, 42, -62, 44, +-47, 38, -17, 18, 12, -10, 35, -37, +47, -43, 42, -10, 27, 42, 13, 89, +-9, 106, -34, 76, -45, 14, -34, -49, +-6, -79, 27, -62, 56, -15, 62, 42, +36, 75, -8, 71, -48, 32, -58, -16, +-33, -44, 7, -50, 34, -35, 47, -12, +41, 9, 10, 21, -18, 17, -21, 3, +-12, -18, 3, -43, 13, -59, 5, -60, +-3, -41, 5, -4, 15, 35, 13, 50, +19, 24, 20, -31, -3, -92, -23, -124, +-21, -99, -12, -27, 14, 47, 40, 93, +35, 81, 11, 13, -11, -71, -28, -128, +-39, -122, -15, -65, 27, 17, 42, 83, +43, 97, 31, 63, -6, 1, -37, -61, +-41, -93, -34, -87, -8, -49, 30, 9, +53, 67, 51, 103, 37, 105, 2, 69, +-41, -1, -62, -72, -53, -113, -25, -99, +20, -30, 68, 68, 80, 145, 57, 161, +12, 106, -38, 12, -70, -73, -56, -107, +-23, -75, 10, -2, 44, 63, 56, 89, +37, 75, 11, 45, 0, 20, -5, 22, +-11, 35, -16, 29, -29, -4, -26, -52, +-10, -78, 10, -56, 40, 11, 65, 91, +56, 132, 20, 104, -20, 20, -51, -68, +-57, -109, -32, -87, 4, -27, 34, 31, +53, 49, 48, 22, 19, -14, -6, -23, +-15, -2, -13, 22, 0, 28, 5, -2, +-4, -58, -14, -98, -10, -95, 1, -42, +24, 29, 53, 77, 50, 69, 23, 9, +-9, -57, -38, -94, -54, -84, -36, -35, +5, 10, 38, 31, 53, 20, 54, -10, +27, -30, 0, -33, -13, -19, -30, -2, +-37, 2, -20, -8, 1, -16, 18, -13, +39, 7, 49, 22, 39, 16, 17, -5, +-9, -32, -31, -41, -36, -18, -21, 25, +5, 56, 31, 56, 51, 22, 43, -23, +14, -47, -3, -39, -12, 8, -20, 65, +-18, 89, -7, 65, 5, 5, 14, -52, +26, -71, 32, -35, 29, 36, 20, 90, +-1, 100, -26, 62, -38, -1, -29, -52, +0, -63, 36, -30, 61, 23, 56, 61, +19, 62, -26, 30, -46, -12, -37, -30, +-7, -19, 33, 5, 60, 25, 51, 26, +18, 6, -23, -18, -45, -31, -28, -27, +10, -9, 38, 10, 45, 15, 36, 8, +9, 0, -21, 0, -28, -1, -8, -8, +12, -20, 22, -42, 21, -58, 6, -50, +1, -16, 5, 35, 11, 72, 17, 68, +18, 17, 9, -59, -9, -114, -15, -120, +-2, -70, 15, 17, 28, 87, 29, 104, +14, 61, -3, -14, -13, -77, -7, -96, +10, -67, 30, -17, 35, 27, 18, 46, +-2, 34, -18, 15, -18, 0, 2, -8, +28, -13, 46, -21, 36, -23, 9, -17, +-8, 3, -14, 38, -12, 65, 2, 56, +19, 11, 24, -48, 16, -79, 10, -61, +14, 1, 24, 81, 29, 126, 19, 99, +-3, 15, -19, -75, -26, -116, -17, -87, +13, -1, 48, 87, 65, 122, 54, 94, +19, 24, -27, -45, -50, -76, -41, -55, +-16, -7, 17, 35, 52, 48, 68, 33, +46, 14, 17, -1, -6, -6, -28, -7, +-28, -16, -13, -29, 5, -36, 31, -24, +53, 6, 55, 40, 36, 59, 15, 38, +-13, -11, -39, -66, -37, -97, -11, -83, +20, -28, 55, 39, 76, 82, 65, 81, +30, 41, -15, -22, -52, -78, -62, -100, +-36, -81, 7, -34, 52, 19, 84, 57, +84, 62, 48, 48, -4, 18, -46, -13, +-68, -37, -48, -55, -5, -53, 36, -37, +68, -15, 75, 12, 50, 40, 14, 58, +-12, 55, -29, 34, -29, -6, -9, -46, +11, -65, 23, -56, 29, -20, 27, 26, +27, 58, 29, 67, 20, 52, 5, 21, +-4, -11, -10, -32, -11, -39, 1, -31, +18, -11, 28, 16, 34, 43, 26, 64, +11, 65, 6, 37, 8, -9, 6, -56, +2, -75, 7, -58, 7, -2, 9, 58, +25, 95, 33, 88, 35, 32, 29, -43, +16, -95, -5, -90, -15, -37, -8, 36, +2, 84, 22, 78, 40, 32, 32, -23, +19, -62, 16, -60, 14, -22, 12, 20, +14, 35, 8, 22, -10, -9, -13, -36, +-3, -32, 15, -4, 45, 25, 70, 33, +59, 16, 22, -20, -17, -48, -47, -49, +-49, -25, -12, 5, 41, 25, 73, 27, +77, 8, 56, -13, 10, -16, -22, -10, +-29, -3, -19, -2, -1, -9, 19, -19, +28, -17, 27, 1, 36, 19, 44, 35, +39, 31, 25, 4, -3, -24, -30, -38, +-35, -29, -17, 1, 22, 30, 61, 47, +75, 35, 60, 4, 15, -22, -26, -31, +-39, -17, -23, 12, 11, 37, 46, 40, +60, 27, 45, 1, 18, -23, 1, -30, +0, -19, 6, 6, 17, 21, 22, 29, +13, 33, 9, 26, 17, 15, 30, 2, +43, -15, 47, -35, 23, -41, -16, -28, +-34, 1, -22, 46, 10, 81, 55, 77, +82, 34, 69, -34, 29, -96, -14, -117, +-36, -78, -28, 8, 7, 91, 41, 126, +55, 93, 47, 15, 21, -66, 1, -111, +0, -99, 19, -46, 33, 20, 29, 60, +14, 60, -7, 36, -14, 8, 4, -15, +36, -26, 59, -33, 60, -41, 34, -44, +-2, -34, -23, -5, -15, 34, 11, 66, +36, 61, 50, 17, 39, -36, 13, -74, +-5, -74, -4, -34, 20, 18, 41, 61, +44, 59, 33, 19, 9, -22, -9, -41, +-8, -29, 11, -1, 40, 20, 59, 23, +50, 6, 20, -15, -7, -20, -17, -3, +-6, 22, 20, 37, 42, 32, 53, 4, +46, -21, 25, -30, 3, -15, -9, 13, +-1, 35, 9, 36, 21, 15, 36, -10, +44, -20, 43, -14, 37, 6, 23, 25, +7, 28, -10, 22, -18, 5, -7, -9, +18, -11, 54, -9, 72, 0, 60, 10, +35, 9, 3, 7, -26, 10, -29, 8, +-1, 4, 33, -4, 61, -14, 64, -18, +50, -21, 28, -6, 6, 13, -4, 25, +-2, 25, 12, 5, 22, -20, 23, -41, +30, -46, 42, -27, 50, 7, 51, 40, +35, 53, 8, 34, -17, -8, -28, -58, +-12, -84, 24, -69, 69, -21, 87, 40, +75, 79, 40, 73, -4, 29, -32, -32, +-32, -79, -11, -81, 24, -49, 58, -3, +65, 35, 56, 47, 43, 36, 30, 12, +20, -4, 7, -8, -3, -15, -8, -25, +-3, -41, 13, -44, 40, -25, 75, 13, +86, 58, 60, 78, 20, 55, -19, 1, +-42, -52, -36, -72, 4, -49, 49, 6, +74, 54, 75, 62, 47, 33, 13, -9, +-4, -31, -6, -19, 7, 11, 29, 35, +39, 33, 25, 5, 11, -35, 15, -49, +26, -17, 39, 36, 52, 68, 52, 60, +32, 16, 11, -43, -8, -74, -13, -55, +6, -2, 35, 51, 54, 72, 64, 48, +58, 3, 37, -34, 11, -45, -7, -31, +-11, -5, 0, 8, 20, 9, 39, 4, +56, 9, 59, 28, 49, 38, 28, 27, +5, -9, -9, -54, -11, -78, 4, -61, +27, -4, 48, 61, 65, 91, 59, 70, +37, 7, 15, -61, 0, -96, -4, -79, +7, -24, 29, 32, 50, 60, 56, 48, +43, 13, 22, -22, 11, -40, 9, -32, +13, -14, 29, -1, 46, 3, 50, 1, +36, 0, 17, 5, 3, 12, -1, 12, +9, 1, 27, -17, 46, -25, 59, -22, +59, -5, 37, 19, 15, 32, 7, 19, +4, -6, 3, -26, 14, -35, 35, -25, +50, 2, 57, 28, 56, 41, 41, 36, +23, 12, 4, -16, -13, -34, -9, -34, +14, -19, 40, 3, 60, 25, 69, 33, +62, 29, 33, 21, 2, 11, -16, 0, +-8, -13, 11, -19, 28, -24, 47, -26, +56, -10, 53, 16, 42, 45, 24, 66, +14, 55, 8, 17, -2, -33, 1, -74, +19, -79, 45, -41, 64, 22, 68, 70, +58, 84, 28, 56, -8, 3, -31, -44, +-20, -64, 21, -50, 65, -15, 86, 15, +79, 24, 47, 19, 4, 10, -23, 6, +-22, 13, 10, 12, 49, 0, 63, -23, +57, -49, 41, -53, 19, -21, 5, 28, +10, 63, 27, 65, 39, 30, 38, -26, +24, -69, 14, -70, 20, -37, 37, 11, +47, 45, 45, 51, 25, 30, 7, -9, +0, -31, 9, -30, 41, -16, 70, -3, +72, 2, 41, -4, 4, -10, -21, -5, +-20, 9, 8, 26, 51, 30, 81, 17, +75, -9, 42, -32, 2, -36, -15, -21, +-8, 5, 15, 25, 38, 30, 51, 19, +46, 4, 32, -7, 25, -5, 30, 4, +40, 6, 41, -7, 24, -23, 1, -31, +-9, -21, 1, 11, 30, 49, 66, 71, +88, 56, 77, 9, 29, -45, -19, -80, +-39, -76, -22, -31, 21, 31, 62, 81, +84, 88, 78, 56, 37, 6, 2, -45, +-3, -68, 10, -56, 26, -23, 32, 14, +32, 31, 30, 33, 28, 29, 30, 24, +39, 16, 50, 0, 47, -22, 26, -40, +5, -42, 5, -25, 14, 13, 27, 44, +46, 49, 52, 23, 43, -20, 27, -48, +20, -48, 31, -16, 43, 33, 41, 57, +27, 34, 13, -17, 3, -60, 6, -69, +26, -31, 56, 28, 75, 71, 68, 64, +41, 14, 4, -42, -15, -71, -15, -47, +4, 0, 31, 43, 55, 49, 69, 14, +63, -30, 44, -45, 27, -26, 15, 13, +2, 41, -7, 37, -7, 2, 13, -38, +41, -48, 66, -26, 80, 15, 74, 43, +43, 37, -4, 5, -35, -32, -25, -50, +10, -27, 45, 17, 69, 45, 72, 36, +58, 1, 31, -32, 10, -41, 9, -21, +22, 12, 26, 32, 21, 23, 15, -4, +11, -21, 20, -19, 45, 3, 67, 30, +72, 36, 57, 9, 22, -32, -10, -55, +-21, -41, -8, 1, 21, 42, 51, 59, +72, 39, 69, 0, 49, -30, 25, -34, +11, -17, 7, 8, 6, 20, 5, 10, +11, -8, 31, -15, 45, 6, 49, 32, +58, 41, 52, 29, 28, -1, -2, -32, +-16, -43, -7, -25, 17, 8, 44, 30, +62, 25, 63, 9, 47, -9, 29, -17, +10, 4, 4, 28, 15, 32, 23, 12, +25, -26, 29, -58, 32, -60, 39, -30, +43, 19, 42, 60, 38, 71, 27, 54, +9, 15, 1, -29, 4, -54, 17, -65, +37, -60, 48, -34, 52, 4, 46, 48, +34, 76, 21, 80, 9, 49, 8, -11, +10, -72, 15, -102, 26, -89, 40, -33, +48, 35, 50, 79, 44, 79, 34, 43, +22, -6, 6, -41, -2, -51, 12, -45, +31, -27, 43, -8, 44, 11, 37, 28, +29, 39, 23, 41, 15, 29, 16, -5, +26, -43, 27, -60, 21, -49, 21, -11, +29, 38, 36, 68, 39, 62, 38, 23, +33, -28, 20, -57, 8, -52, 5, -22, +19, 11, 39, 36, 43, 44, 39, 28, +33, 8, 23, -1, 15, -3, 15, -6, +23, -11, 33, -21, 38, -25, 29, -11, +17, 15, 15, 40, 20, 53, 32, 39, +41, 9, 40, -21, 34, -42, 18, -38, +7, -20, 9, 6, 23, 24, 39, 29, +44, 23, 41, 13, 33, 2, 22, -7, +14, -11, 17, -12, 30, -16, 44, -19, +42, -9, 23, 5, 8, 13, 4, 16, +7, 17, 22, 10, 48, 0, 68, -9, +62, -12, 30, -11, 0, -15, -17, -18, +-16, -18, 7, -11, 41, 3, 66, 20, +71, 30, 53, 24, 24, 4, 1, -18, +-9, -35, -2, -43, 16, -35, 34, -11, +40, 16, 36, 27, 39, 20, 45, 6, +48, -7, 44, -16, 30, -18, 6, -17, +-17, -12, -19, -14, 0, -12, 33, -3, +78, 6, 94, 21, 78, 22, 37, 14, +-13, -3, -47, -20, -41, -33, -2, -29, +48, -9, 86, 14, 87, 30, 59, 28, +21, 14, -6, -4, -16, -13, -9, -11, +14, -2, 30, 6, 35, 10, 33, 4, +36, -4, 41, 0, 45, 7, 39, 15, +22, 18, 0, 13, -16, 1, -10, -11, +13, -10, 42, 1, 64, 12, 66, 12, +44, 3, 13, -3, -6, -6, -6, 3, +8, 18, 26, 28, 37, 21, 41, -10, +34, -39, 21, -45, 20, -27, 30, 7, +35, 44, 29, 60, 15, 42, 5, 2, +2, -38, 8, -52, 22, -38, 38, -11, +47, 12, 42, 23, 23, 24, 8, 15, +7, 3, 20, -7, 32, -13, 34, -20, +29, -30, 15, -30, -2, -18, 1, 2, +22, 25, 43, 35, 59, 27, 53, 9, +22, -14, -7, -35, -19, -43, -14, -35, +11, -18, 38, 4, 54, 20, 62, 27, +51, 30, 29, 23, 10, 4, -4, -23, +-7, -51, -1, -61, 4, -40, 18, -1, +42, 41, 60, 70, 68, 65, 54, 30, +23, -20, -11, -61, -35, -71, -36, -49, +-8, -8, 38, 33, 79, 58, 88, 61, +68, 42, 29, 12, -12, -21, -40, -39, +-35, -46, -9, -34, 25, -7, 58, 23, +68, 50, 63, 60, 44, 48, 15, 14, +-6, -23, -20, -45, -23, -45, -8, -25, +21, 5, 46, 36, 64, 48, 67, 38, +44, 19, 13, -4, -19, -19, -29, -28, +-13, -26, 13, -12, 41, 6, 57, 19, +54, 22, 32, 19, 10, 7, 1, -7, +-3, -14, 8, -21, 23, -11, 25, 5, +18, 15, 10, 15, 12, 3, 24, -15, +39, -25, 41, -23, 31, -8, 15, 10, +-4, 19, -13, 18, -3, 5, 18, -13, +41, -24, 51, -27, 39, -18, 19, -4, +7, 6, 0, 8, 7, 3, 21, -1, +25, -4, 30, -5, 14, 2, -2, 6, +5, 0, 22, -12, 37, -21, 46, -22, +45, -15, 24, 6, -6, 22, -22, 28, +-18, 20, 6, 0, 33, -15, 52, -21, +58, -16, 41, 4, 14, 17, -13, 16, +-21, 5, -9, -9, 10, -10, 29, 5, +39, 18, 42, 29, 35, 26, 16, 4, +5, -25, 9, -38, 15, -29, 20, -1, +19, 32, 11, 45, 12, 36, 18, 6, +19, -24, 32, -34, 41, -21, 31, 2, +17, 22, 0, 27, -7, 17, 0, 1, +14, -5, 21, -3, 31, -5, 34, -7, +26, -11, 17, -12, 12, -4, 21, 12, +27, 28, 22, 29, 9, 14, -9, -17, +-10, -45, -1, -50, 15, -30, 48, 3, +74, 29, 65, 41, 31, 32, -8, 6, +-40, -14, -47, -28, -27, -31, 6, -28, +54, -27, 75, -18, 72, -6, 60, 20, +14, 51, -20, 56, -37, 32, -46, -18, +-32, -65, 0, -86, 36, -63, 66, -9, +85, 49, 72, 81, 37, 69, -14, 24, +-58, -32, -63, -63, -41, -58, 3, -30, +53, 7, 87, 25, 94, 25, 58, 18, +11, 10, -24, 4, -49, 4, -46, -1, +-15, -21, 20, -29, 47, -23, 64, -2, +58, 29, 44, 44, 26, 34, -6, 4, +-18, -33, -23, -52, -24, -37, 5, 2, +30, 41, 45, 63, 53, 49, 48, 8, +27, -28, -3, -47, -19, -42, -19, -17, +-4, 17, 7, 40, 23, 43, 37, 32, +29, 13, 22, -4, 11, -20, 6, -30, +7, -24, 4, -6, 8, 17, 8, 33, +3, 37, 2, 22, 7, -7, 16, -31, +20, -35, 29, -19, 34, 6, 26, 31, +6, 32, -4, 11, -6, -15, -15, -37, +6, -40, 24, -18, 30, 7, 42, 25, +31, 26, 13, 12, 1, -6, -7, -16, +-11, -14, -2, -12, 10, -12, 18, -14, +35, -13, 24, -3, 13, 8, 20, 19, +11, 21, 8, 6, 5, -15, 0, -28, +3, -29, 3, -14, 10, 5, 25, 15, +39, 13, 35, 1, 18, -11, 2, -13, +-20, 4, -26, 18, -16, 21, 16, 9, +41, -7, 46, -20, 49, -24, 14, -7, +-17, 14, -26, 24, -24, 18, -3, 6, +22, -6, 45, -8, 50, 1, 33, 12, +-2, 19, -15, 6, -9, -15, -13, -24, +10, -17, 25, 4, 23, 30, 20, 41, +6, 29, 6, 6, 18, -21, 21, -29, +19, -20, 10, -4, -8, 12, -19, 11, +-11, 8, 1, 6, 29, 10, 54, 22, +49, 18, 31, 3, -11, -20, -28, -44, +-31, -44, -26, -16, 12, 25, 41, 56, +51, 59, 38, 28, 9, -19, -2, -58, +-3, -66, -2, -40, 7, 0, 20, 31, +11, 36, -2, 23, 0, 3, 0, -12, +29, -11, 46, -5, 38, -9, 25, -21, +-9, -35, -33, -34, -32, -12, -17, 29, +13, 59, 52, 56, 61, 21, 33, -32, +13, -71, -11, -73, -26, -37, -18, 12, +-3, 50, 23, 55, 25, 32, 16, 1, +15, -23, 10, -24, 18, -14, 18, -4, +8, -2, 1, -15, -7, -21, -13, -5, +-5, 22, 11, 48, 18, 58, 32, 32, +25, -15, 4, -52, 4, -61, -5, -38, +1, 4, 9, 38, 9, 48, 19, 35, +8, 11, -4, -9, 5, -15, 20, -10, +20, -5, 22, -10, 23, -16, 0, -13, +-7, 3, -18, 27, -16, 43, 10, 34, +22, 7, 35, -23, 31, -45, 20, -38, +7, -9, -2, 20, -4, 35, -13, 29, +-9, 9, 5, -17, 12, -24, 16, -13, +26, 3, 38, 10, 24, 4, 10, -4, +-6, -14, -20, -13, -13, 1, -21, 16, +-1, 14, 31, 1, 34, -10, 37, -15, +32, -12, 10, 3, -14, 13, -17, 6, +-27, -9, -19, -23, 13, -23, 23, -1, +38, 23, 36, 34, 22, 26, 14, -3, +-13, -36, -21, -54, -14, -42, 2, -9, +13, 28, 18, 47, 23, 46, 15, 22, +12, -10, 1, -27, 1, -31, 4, -24, +0, -12, 4, 1, -11, 15, -7, 22, +7, 25, 16, 23, 40, 13, 30, 3, +16, -11, 4, -25, -26, -26, -36, -19, +-13, -4, 14, 13, 28, 25, 43, 35, +30, 34, 8, 26, -11, 12, -36, -9, +-17, -29, 9, -44, 20, -40, 30, -15, +17, 18, 4, 45, -9, 61, -4, 50, +8, 24, 17, -6, 25, -33, 6, -48, +-9, -51, -25, -39, -14, -14, 15, 19, +30, 55, 47, 79, 34, 73, 11, 34, +-25, -27, -50, -86, -25, -108, 3, -82, +31, -17, 51, 60, 45, 112, 12, 108, +-15, 46, -19, -32, -21, -88, 8, -99, +21, -67, 22, -16, 26, 34, -2, 60, +-5, 58, 0, 35, 3, 6, 19, -21, +30, -42, 19, -50, -5, -48, -10, -28, +-10, 7, 3, 42, 16, 62, 17, 51, +27, 17, 15, -33, 2, -70, 3, -72, +5, -37, 13, 14, 6, 50, 5, 59, +-1, 38, -9, 0, 2, -27, 10, -32, +22, -22, 29, -5, 31, 5, 11, 7, +-15, 4, -17, 3, -25, 11, -4, 16, +12, 12, 20, 2, 46, -12, 34, -19, +15, -10, 4, 8, -7, 19, -18, 22, +-26, 6, -14, -22, 5, -37, 35, -25, +39, 11, 35, 51, 29, 63, -2, 41, +-19, -2, -31, -49, -23, -72, 2, -54, +23, -12, 40, 33, 28, 57, 20, 49, +13, 23, -3, -5, -6, -21, -4, -21, +5, -15, -2, -15, -3, -22, -1, -21, +9, -11, 31, 13, 22, 41, 31, 50, +24, 36, -5, -2, -13, -44, -20, -67, +-11, -56, 8, -17, 20, 28, 16, 53, +16, 44, 16, 15, 5, -16, 11, -26, +0, -15, -1, 1, 12, 11, -9, 7, +-15, -11, -9, -25, 5, -25, 23, -6, +24, 27, 31, 43, 27, 34, 10, 8, +-14, -23, -23, -41, -18, -34, -14, -12, +3, 14, 15, 28, 33, 23, 38, 8, +32, -6, 26, -7, -6, 1, -22, 8, +-27, 3, -31, -10, -9, -20, 24, -21, +48, -3, 49, 23, 37, 38, 6, 37, +-18, 16, -33, -15, -42, -34, -7, -34, +21, -16, 30, 12, 34, 37, 16, 42, +4, 30, -10, 12, -10, -10, 4, -25, +13, -30, 13, -24, -2, -7, -10, 14, +-15, 33, 1, 43, 28, 40, 33, 22, +32, -9, 13, -43, -7, -60, -26, -51, +-31, -14, -1, 32, 22, 65, 32, 73, +28, 46, 11, -1, -4, -44, -16, -66, +-11, -57, 7, -25, 26, 16, 19, 41, +9, 47, -2, 41, -26, 18, -7, -10, +13, -25, 19, -30, 33, -28, 18, -13, +-4, 5, -25, 23, -28, 33, -10, 29, +21, 12, 36, -8, 27, -27, 23, -33, +-4, -19, -28, 8, -26, 32, -8, 38, +24, 24, 30, -1, 28, -28, 16, -39, +-8, -26, -15, 1, -21, 34, -9, 48, +11, 34, 20, 11, 22, -19, 17, -36, +10, -30, 2, -7, 2, 21, -12, 35, +-19, 31, -6, 14, -5, -6, 11, -18, +25, -10, 28, 8, 31, 18, 13, 19, +-12, 11, -25, -2, -27, -13, -23, -10, +-1, 2, 26, 14, 33, 22, 42, 17, +31, 5, 5, 0, -15, 1, -35, 5, +-39, 9, -31, 6, -5, 0, 26, -6, +49, -4, 51, 10, 29, 25, 2, 34, +-32, 25, -55, 4, -52, -18, -15, -30, +26, -20, 44, 5, 53, 31, 37, 39, +-1, 28, -24, -4, -34, -32, -24, -31, +-4, -12, 16, 15, 24, 40, 20, 40, +10, 18, -2, -12, -5, -30, -14, -29, +-5, -12, 10, 15, 1, 38, 1, 40, +4, 26, 4, 7, 5, -12, -7, -19, +-10, -18, -5, -12, -3, 2, 2, 11, +18, 23, 25, 36, 12, 36, -4, 23, +-23, 1, -29, -25, -22, -37, -9, -25, +13, 3, 28, 29, 41, 45, 30, 44, +2, 24, -19, -5, -35, -24, -31, -28, +-20, -12, -11, 14, 8, 31, 29, 32, +35, 21, 21, 12, 11, 8, -12, 7, +-37, 9, -45, 5, -37, -3, -7, -7, +20, -1, 37, 10, 50, 21, 31, 34, +-5, 30, -36, 10, -45, -13, -37, -21, +-12, -11, 19, 11, 28, 31, 28, 34, +9, 20, -7, -7, -16, -22, -21, -10, +-9, 17, 1, 41, 2, 48, -9, 31, +-13, -9, -2, -44, 2, -47, 8, -17, +16, 28, 10, 67, -13, 73, -27, 44, +-31, 3, -27, -31, -7, -36, 6, -17, +13, 10, 15, 26, 3, 25, -7, 16, +-15, 11, -18, 18, -15, 30, -10, 36, +-11, 21, -13, -8, -7, -33, -3, -40, +4, -20, 11, 21, 9, 60, 3, 72, +-20, 56, -38, 17, -37, -24, -29, -39, +-9, -29, 14, -5, 33, 20, 27, 37, +5, 36, -18, 24, -38, 15, -44, 11, +-31, 9, -9, 7, 9, 0, 19, -4, +18, -3, 5, 5, -14, 24, -32, 38, +-38, 42, -28, 29, -18, 7, -3, -11, +14, -17, 16, -6, 4, 11, -9, 28, +-23, 35, -32, 28, -27, 19, -21, 13, +-10, 7, 3, 6, 3, 7, 0, 6, +-8, 6, -15, 8, -18, 15, -19, 24, +-20, 30, -23, 28, -17, 19, -11, 5, +-8, 0, -6, 5, -3, 13, -6, 21, +-22, 25, -32, 19, -32, 9, -26, 4, +-13, 10, -2, 23, 8, 34, 1, 37, +-17, 24, -33, 1, -36, -22, -29, -28, +-13, -13, 6, 19, 3, 55, -5, 66, +-16, 54, -36, 24, -42, -10, -33, -32, +-14, -30, 5, -10, 7, 17, 1, 38, +-11, 44, -31, 38, -47, 25, -45, 19, +-35, 19, -18, 12, 2, 5, 6, -1, +1, -7, -11, -5, -26, 6, -41, 29, +-46, 47, -40, 50, -30, 40, -16, 18, +-3, -1, 0, -6, -5, 0, -15, 10, +-33, 19, -48, 21, -46, 13, -39, 7, +-24, 11, -3, 30, 1, 52, 0, 52, +-12, 37, -34, 4, -40, -34, -44, -46, +-44, -30, -27, 8, -10, 54, -6, 84, +-6, 81, -11, 51, -24, 6, -34, -30, +-43, -42, -48, -33, -40, -5, -31, 31, +-18, 53, -1, 63, -4, 65, -17, 48, +-30, 20, -52, -8, -62, -33, -52, -38, +-33, -16, -13, 21, 0, 60, -1, 85, +-19, 78, -41, 37, -53, -11, -55, -43, +-47, -44, -29, -14, -21, 31, -17, 65, +-17, 73, -28, 54, -35, 22, -36, -6, +-37, -20, -33, -16, -30, 1, -39, 20, +-44, 33, -38, 39, -30, 38, -19, 33, +-14, 26, -23, 15, -32, 1, -49, -7, +-63, -6, -53, 5, -36, 26, -23, 44, +-16, 53, -20, 42, -33, 18, -46, -3, +-57, -6, -55, 3, -40, 20, -30, 39, +-29, 42, -34, 30, -44, 13, -47, 0, +-47, 4, -38, 16, -30, 34, -31, 46, +-37, 43, -50, 23, -56, 1, -51, -6, +-47, -1, -38, 12, -29, 30, -33, 41, +-41, 43, -47, 36, -55, 27, -56, 23, +-51, 20, -53, 17, -46, 5, -35, 0, +-40, 5, -38, 16, -37, 32, -45, 47, +-53, 54, -57, 40, -54, 17, -49, -2, +-40, -11, -31, -3, -34, 17, -50, 37, +-63, 39, -64, 32, -60, 24, -50, 19, +-36, 24, -30, 34, -36, 38, -51, 26, +-66, 10, -74, -9, -67, -15, -50, 4, +-41, 35, -35, 63, -35, 71, -46, 53, +-60, 24, -66, -7, -68, -22, -64, -13, +-55, 12, -58, 40, -58, 55, -48, 51, +-45, 35, -41, 18, -38, 13, -53, 17, +-66, 18, -77, 17, -87, 15, -75, 9, +-52, 9, -35, 23, -27, 43, -29, 53, +-47, 50, -74, 35, -94, 13, -100, -7, +-81, -16, -56, -1, -36, 26, -29, 50, +-35, 59, -50, 52, -74, 33, -83, 9, +-85, -2, -77, 0, -67, 17, -64, 29, +-55, 33, -48, 35, -52, 32, -61, 29, +-64, 31, -74, 33, -80, 27, -77, 21, +-77, 12, -70, 10, -58, 12, -58, 26, +-60, 39, -59, 45, -73, 46, -77, 35, +-76, 23, -78, 11, -68, 4, -60, 5, +-60, 11, -64, 26, -70, 37, -72, 44, +-75, 48, -76, 42, -70, 26, -66, 8, +-66, -5, -67, -5, -75, 12, -74, 36, +-77, 57, -83, 63, -78, 49, -72, 22, +-71, 0, -67, -5, -67, 8, -72, 30, +-76, 49, -83, 47, -90, 32, -86, 15, +-81, 5, -73, 18, -60, 38, -62, 55, +-70, 55, -75, 28, -87, -5, -91, -23, +-83, -13, -79, 21, -71, 56, -64, 75, +-75, 71, -83, 41, -83, 1, -86, -13, +-81, -5, -69, 13, -70, 36, -80, 43, +-89, 32, -95, 19, -96, 19, -85, 33, +-69, 51, -62, 61, -62, 46, -74, 12, +-98, -18, -111, -31, -108, -12, -96, 31, +-76, 78, -65, 99, -68, 83, -70, 38, +-87, -9, -101, -36, -95, -28, -96, 8, +-90, 44, -82, 68, -87, 63, -83, 37, +-78, 15, -85, 11, -85, 19, -80, 31, +-89, 42, -98, 40, -103, 24, -105, 7, +-94, 3, -82, 12, -73, 31, -71, 51, +-79, 60, -97, 59, -112, 38, -114, 16, +-109, 6, -94, 1, -77, 7, -70, 21, +-73, 35, -81, 43, -94, 47, -114, 50, +-118, 43, -108, 28, -98, 18, -81, 10, +-72, 7, -72, 9, -73, 18, -93, 34, +-118, 48, -122, 51, -118, 47, -103, 36, +-75, 22, -66, 12, -69, 7, -75, 4, +-101, 11, -121, 28, -125, 47, -120, 58, +-98, 58, -79, 45, -74, 24, -75, 3, +-90, -6, -106, -3, -110, 19, -112, 48, +-110, 66, -102, 64, -97, 45, -90, 17, +-84, -2, -85, -3, -87, 11, -98, 33, +-110, 48, -118, 45, -127, 34, -112, 18, +-90, 18, -80, 33, -66, 41, -71, 44, +-98, 37, -120, 13, -139, -9, -139, -15, +-109, 7, -83, 42, -63, 73, -58, 85, +-81, 66, -109, 26, -132, -11, -145, -31, +-129, -21, -103, 13, -80, 44, -64, 64, +-72, 67, -93, 52, -112, 37, -128, 23, +-132, 19, -122, 18, -105, 11, -92, 5, +-86, 4, -85, 11, -87, 34, -98, 63, +-111, 79, -122, 75, -128, 46, -122, 5, +-112, -24, -99, -29, -80, -5, -75, 34, +-84, 64, -98, 74, -121, 64, -138, 37, +-132, 12, -119, 1, -98, 8, -78, 27, +-80, 38, -90, 36, -101, 26, -118, 18, +-125, 20, -118, 28, -114, 40, -103, 45, +-92, 40, -95, 27, -97, 16, -101, 15, +-108, 24, -113, 36, -120, 40, -119, 30, +-109, 19, -103, 14, -97, 21, -95, 38, +-101, 57, -113, 64, -124, 48, -127, 19, +-118, -6, -102, -15, -86, -1, -81, 29, +-95, 59, -112, 68, -126, 57, -135, 35, +-122, 11, -104, 4, -90, 10, -79, 19, +-92, 31, -115, 39, -129, 39, -137, 37, +-128, 36, -103, 34, -90, 32, -82, 24, +-86, 12, -105, 6, -116, 10, -119, 24, +-124, 44, -117, 55, -107, 51, -105, 37, +-104, 21, -102, 3, -97, 0, -98, 17, +-105, 34, -114, 46, -124, 48, -127, 41, +-121, 31, -106, 22, -89, 15, -77, 13, +-82, 16, -102, 19, -123, 25, -142, 36, +-139, 47, -120, 51, -97, 43, -71, 25, +-70, 8, -87, -4, -108, 0, -132, 17, +-140, 39, -128, 56, -111, 54, -90, 38, +-74, 17, -80, 7, -94, 11, -110, 23, +-130, 36, -135, 40, -126, 30, -113, 15, +-91, 9, -77, 17, -74, 34, -84, 53, +-110, 56, -134, 39, -136, 5, -128, -14, +-115, -6, -94, 20, -77, 48, -70, 63, +-84, 60, -111, 35, -131, 8, -142, -1, +-136, 8, -115, 31, -94, 48, -74, 47, +-70, 29, -85, 8, -104, -1, -126, 14, +-136, 39, -132, 62, -125, 66, -110, 46, +-89, 11, -74, -23, -69, -24, -77, 4, +-99, 41, -124, 75, -146, 75, -150, 47, +-128, 11, -94, -14, -67, -12, -51, 12, +-59, 35, -89, 49, -129, 50, -160, 34, +-160, 15, -130, 10, -90, 19, -58, 32, +-49, 39, -63, 30, -95, 17, -131, 7, +-149, 8, -141, 21, -116, 41, -92, 55, +-75, 48, -72, 28, -77, 6, -93, -8, +-107, -7, -113, 13, -118, 40, -121, 56, +-111, 53, -99, 36, -86, 15, -74, 4, +-80, 4, -88, 9, -103, 24, -122, 37, +-128, 43, -120, 37, -103, 25, -77, 16, +-66, 14, -77, 16, -91, 22, -113, 31, +-127, 34, -122, 30, -109, 23, -92, 17, +-73, 14, -73, 18, -85, 25, -97, 34, +-111, 41, -119, 36, -116, 25, -109, 16, +-100, 11, -89, 13, -79, 22, -79, 34, +-90, 45, -100, 40, -110, 26, -120, 16, +-116, 9, -103, 11, -85, 22, -72, 34, +-75, 36, -84, 31, -98, 18, -115, 10, +-121, 14, -109, 26, -93, 36, -76, 41, +-74, 34, -81, 13, -90, -2, -105, -4, +-113, 11, -105, 35, -95, 55, -92, 61, +-87, 43, -89, 12, -94, -7, -93, -10, +-94, 7, -93, 32, -91, 49, -95, 49, +-99, 31, -101, 10, -97, 1, -89, 13, +-80, 33, -79, 49, -88, 50, -100, 30, +-107, -4, -104, -25, -95, -19, -79, 14, +-74, 55, -74, 77, -82, 74, -101, 41, +-105, -2, -104, -25, -99, -26, -83, -5, +-74, 28, -75, 49, -83, 57, -98, 49, +-105, 32, -100, 22, -90, 18, -83, 18, +-78, 14, -78, 4, -85, -3, -91, -2, +-96, 15, -96, 45, -92, 66, -85, 68, +-82, 49, -76, 12, -77, -19, -85, -30, +-91, -16, -96, 14, -96, 42, -90, 58, +-81, 56, -72, 37, -70, 20, -70, 5, +-81, 1, -95, 3, -101, 10, -105, 18, +-96, 27, -83, 35, -74, 39, -63, 40, +-66, 35, -81, 21, -90, 7, -95, -1, +-99, 1, -91, 11, -81, 27, -79, 38, +-71, 37, -69, 31, -74, 18, -71, 9, +-79, 12, -90, 15, -91, 16, -96, 17, +-93, 18, -80, 21, -67, 23, -56, 26, +-52, 28, -65, 23, -87, 18, -108, 9, +-112, 2, -97, 7, -74, 20, -54, 35, +-48, 39, -53, 31, -72, 17, -96, 4, +-107, 1, -100, 11, -84, 22, -62, 32, +-56, 31, -56, 17, -65, 5, -80, 4, +-89, 12, -88, 26, -82, 36, -79, 38, +-73, 25, -75, 9, -75, -1, -67, 0, +-64, 15, -68, 29, -69, 34, -80, 32, +-90, 19, -92, 7, -82, 6, -69, 21, +-59, 33, -55, 34, -60, 26, -74, 8, +-89, -7, -91, -5, -95, 16, -81, 37, +-62, 50, -51, 46, -50, 30, -61, 6, +-72, -15, -79, -14, -89, -2, -84, 15, +-74, 33, -68, 41, -60, 35, -53, 27, +-60, 24, -66, 15, -69, 9, -81, 3, +-82, -2, -76, -4, -70, 6, -65, 22, +-56, 38, -60, 49, -63, 46, -70, 30, +-78, 4, -72, -15, -67, -17, -68, -6, +-61, 11, -58, 31, -71, 46, -69, 41, +-67, 27, -63, 11, -56, -1, -54, -2, +-61, 3, -72, 10, -76, 16, -76, 20, +-70, 23, -59, 22, -49, 21, -47, 22, +-56, 17, -74, 12, -78, 8, -77, 2, +-67, 3, -53, 15, -50, 28, -57, 33, +-61, 28, -68, 16, -76, 6, -69, -1, +-61, 1, -51, 13, -53, 25, -56, 29, +-62, 23, -61, 11, -64, 1, -65, 2, +-55, 3, -51, 12, -59, 24, -56, 23, +-62, 20, -64, 14, -59, 7, -60, 8, +-55, 11, -56, 14, -57, 15, -57, 14, +-63, 17, -66, 17, -53, 12, -55, 14, +-53, 12, -49, 9, -57, 10, -61, 14, +-65, 16, -63, 19, -62, 22, -57, 21, +-55, 17, -51, 9, -51, 7, -52, 8, +-57, 11, -61, 19, -68, 19, -59, 16, +-57, 16, -55, 12, -41, 12, -43, 14, +-49, 13, -56, 12, -64, 6, -66, 3, +-61, 8, -56, 20, -49, 33, -49, 35, +-51, 28, -56, 12, -59, -6, -60, -16, +-49, -9, -45, 12, -47, 31, -52, 42, +-56, 34, -58, 13, -62, -4, -45, -15, +-38, -10, -38, 11, -40, 25, -55, 29, +-61, 17, -60, 4, -60, -2, -40, -1, +-35, 14, -37, 26, -43, 31, -59, 17, +-64, -2, -60, -13, -47, -9, -41, 8, +-32, 27, -37, 37, -52, 33, -63, 15, +-66, -2, -65, -8, -46, -4, -27, 9, +-26, 24, -29, 27, -52, 20, -66, 6, +-68, -6, -65, -4, -45, 6, -23, 23, +-27, 33, -27, 26, -40, 8, -55, -9, +-65, -14, -65, -7, -53, 10, -43, 29, +-33, 42, -32, 37, -36, 18, -43, -4, +-47, -18, -51, -16, -52, -2, -56, 18, +-43, 32, -42, 37, -43, 27, -34, 12, +-36, -2, -41, -8, -40, -8, -40, -2, +-41, 10, -43, 18, -48, 19, -43, 17, +-48, 13, -45, 10, -36, 9, -31, 13, +-37, 17, -38, 12, -42, 8, -59, 4, +-61, -2, -47, 3, -41, 14, -29, 23, +-16, 28, -27, 23, -35, 14, -55, -2, +-61, -13, -55, -10, -43, -1, -26, 14, +-12, 25, -24, 27, -38, 22, -47, 9, +-59, -2, -53, -2, -42, 6, -30, 13, +-27, 15, -26, 9, -35, 2, -43, -1, +-46, 7, -43, 21, -42, 31, -29, 27, +-32, 15, -35, -6, -34, -24, -47, -24, +-36, -6, -33, 22, -33, 43, -25, 48, +-29, 35, -45, 8, -44, -23, -45, -35, +-39, -24, -33, 0, -24, 26, -20, 44, +-27, 44, -31, 21, -37, 1, -40, -15, +-42, -21, -39, -10, -30, 1, -22, 9, +-31, 21, -24, 24, -31, 18, -31, 13, +-27, 14, -37, 12, -37, 3, -33, -10, +-33, -16, -29, -14, -25, -5, -27, 19, +-22, 38, -29, 44, -31, 34, -33, 10, +-39, -12, -46, -28, -39, -25, -30, -5, +-25, 19, -15, 37, -11, 40, -19, 25, +-32, 9, -46, -6, -58, -12, -45, -8, +-36, 2, -10, 9, 8, 13, -2, 13, +-11, 6, -26, 2, -55, 1, -54, 2, +-40, 4, -26, 7, -6, 8, 0, 9, +-8, 12, -29, 9, -38, 6, -47, 8, +-45, 9, -31, 4, -15, 2, -10, 5, +-11, 5, -25, 7, -20, 6, -23, 8, +-32, 9, -19, 6, -23, 3, -30, -1, +-28, -3, -32, 3, -29, 7, -11, 13, +-10, 21, -3, 20, -18, 15, -36, 2, +-40, -12, -46, -11, -45, 0, -26, 13, +0, 24, 4, 29, 0, 24, -10, 9, +-33, -8, -50, -18, -42, -14, -40, -1, +-13, 11, 4, 21, 9, 22, 7, 17, +-19, 9, -40, 2, -44, -4, -50, -4, +-34, 2, -8, 7, -1, 11, 5, 14, +-2, 16, -15, 14, -35, 9, -35, 1, +-31, -6, -22, -10, -9, -7, -5, 5, +-8, 13, -11, 22, -22, 24, -23, 14, +-14, 0, -20, -10, -9, -10, -15, -5, +-24, 0, -19, 10, -17, 16, -21, 16, +-8, 14, -7, 12, -9, 9, -16, 7, +-26, 5, -28, 0, -28, -2, -21, -2, +-8, -2, 5, 7, -3, 16, -8, 20, +-16, 18, -21, 3, -25, -8, -9, -13, +-7, -11, -10, 3, -7, 16, -14, 18, +-16, 14, -16, 7, -17, 1, -9, -2, +-7, 4, -14, 14, -11, 20, -24, 16, +-20, 4, -15, -3, -8, -11, -3, -8, +2, 4, 2, 15, -17, 25, -24, 21, +-20, 7, -19, -1, -13, -4, 1, -3, +2, 4, 5, 11, -12, 12, -15, 6, +-18, 3, -30, 5, -18, 6, 1, 11, +-1, 19, 6, 18, 6, 11, -12, -2, +-16, -14, -23, -14, -18, -7, -14, 11, +-6, 29, 0, 38, 0, 32, -2, 10, +-3, -11, -8, -22, -11, -21, -15, -9, +-5, 11, -8, 29, -18, 34, -3, 23, +-4, 8, -4, -5, 6, -11, 8, -8, +-1, 0, -5, 8, -20, 11, -20, 8, +-21, 7, -10, 6, 12, 9, 22, 15, +17, 18, 5, 11, -10, 0, -34, -13, +-35, -17, -17, -9, 2, 8, 19, 29, +34, 42, 15, 35, -1, 11, -19, -15, +-32, -32, -21, -33, -5, -13, 8, 20, +21, 41, 18, 42, 5, 29, 2, 3, +-17, -15, -18, -23, -5, -17, 6, -3, +9, 11, 10, 21, 6, 17, -2, 7, +-1, 2, 0, 6, 3, 11, 6, 15, +6, 10, 1, -1, -3, -11, -16, -16, +-2, -11, 5, 9, 7, 31, 16, 44, +17, 36, 3, 14, -5, -14, -9, -36, +-9, -34, -4, -13, 3, 17, 17, 36, +19, 40, 17, 27, 9, 6, 0, -10, +-11, -16, -8, -10, 1, 2, 5, 13, +6, 13, 20, 4, 13, 1, 2, 3, +9, 9, 3, 18, 6, 20, 10, 10, +10, -4, 6, -16, 1, -19, -5, -9, +8, 6, 12, 25, 17, 33, 24, 26, +17, 8, 5, -13, -1, -19, -7, -15, +-10, -1, 4, 15, 19, 22, 25, 19, +24, 9, 20, -2, 3, -3, -3, -1, +-7, 5, -3, 14, 11, 13, 14, 6, +20, -1, 23, -7, 13, -8, 11, 2, +11, 15, 4, 20, 4, 25, 1, 18, +4, 2, 6, -14, 19, -20, 22, -10, +24, 2, 22, 18, 12, 29, 2, 29, +-7, 17, -8, 1, 5, -11, 17, -11, +21, -7, 36, 4, 27, 13, 13, 13, +5, 13, -2, 10, -6, 6, 6, 6, +18, 5, 29, 2, 29, 1, 22, -4, +17, -4, 5, 1, -1, 10, 1, 22, +11, 25, 15, 18, 25, 3, 28, -11, +17, -15, 9, -13, 13, 0, 5, 19, +7, 29, 16, 27, 19, 14, 23, -3, +18, -16, 16, -16, 15, -9, 17, 3, +17, 18, 23, 24, 17, 19, 14, 9, +11, 1, 6, -5, 7, -5, 18, -1, +27, 1, 34, 2, 34, 5, 23, 7, +13, 8, 1, 9, 2, 6, 11, 2, +24, 0, 26, -3, 39, -6, 35, 0, +16, 11, 4, 20, -1, 20, 1, 11, +15, -1, 32, -10, 34, -9, 33, -2, +22, 9, 12, 18, 8, 16, 10, 13, +13, 4, 23, 0, 20, -2, 21, -2, +24, 3, 14, 12, 12, 15, 22, 13, +22, 13, 17, 10, 23, 3, 19, -3, +16, -7, 18, -8, 23, -4, 25, 4, +33, 10, 33, 14, 26, 21, 12, 19, +7, 2, 15, -11, 20, -18, 23, -14, +29, -1, 35, 9, 27, 19, 28, 21, +21, 19, 9, 11, 8, -3, 20, -16, +26, -16, 32, -9, 33, 1, 33, 11, +28, 16, 19, 14, 17, 10, 15, 6, +12, 3, 17, -1, 30, -3, 27, -1, +30, -1, 31, 2, 29, 2, 21, 7, +17, 12, 13, 14, 12, 12, 16, 4, +25, -2, 34, -6, 34, -7, 36, -4, +32, 4, 19, 11, 8, 16, 11, 14, +12, 8, 19, 2, 30, -4, 38, -2, +32, 1, 28, 7, 22, 13, 13, 11, +14, 5, 15, 1, 22, 1, 27, -2, +33, -1, 36, 6, 33, 10, 22, 9, +19, 6, 20, -2, 20, -5, 21, 0, +27, 8, 24, 13, 25, 6, 36, 1, +29, -3, 29, -7, 29, -5, 27, 5, +25, 14, 19, 13, 15, 12, 22, 2, +24, -10, 29, -10, 40, -4, 39, 5, +32, 12, 31, 12, 20, 7, 9, 0, +14, -6, 18, -4, 32, 1, 39, 9, +40, 15, 39, 13, 26, 2, 14, -8, +17, -16, 20, -13, 24, 1, 32, 14, +40, 21, 39, 15, 32, 6, 24, -3, +13, -11, 16, -11, 19, -1, 27, 7, +35, 11, 35, 13, 30, 10, 28, 0, +22, -2, 24, -1, 28, -1, 28, 3, +31, 1, 30, -4, 32, -7, 23, -1, +23, 2, 32, 3, 33, 12, 30, 16, +32, 10, 27, -4, 28, -12, 23, -13, +18, -11, 27, -3, 29, 8, 38, 13, +42, 16, 33, 14, 30, 4, 23, -6, +14, -13, 21, -10, 24, -7, 32, 0, +42, 12, 34, 18, 30, 14, 26, 5, +20, 0, 22, -4, 20, -4, 32, -8, +41, -6, 37, -3, 33, 4, 27, 5, +32, 3, 25, 11, 24, 11, 29, 4, +30, -9, 32, -11, 33, -11, 31, -8, +30, 5, 28, 15, 26, 20, 29, 12, +27, 2, 35, -15, 39, -23, 35, -18, +32, -7, 30, 6, 24, 13, 28, 16, +30, 10, 33, 1, 35, -10, 37, -16, +37, -13, 26, -5, 22, 2, 23, 11, +24, 8, 32, 2, 39, 3, 36, -2, +40, -1, 26, 3, 21, 2, 23, -6, +19, -6, 28, -7, 37, -6, 42, 4, +37, 14, 32, 15, 30, 4, 23, -7, +22, -14, 27, -13, 28, -7, 36, 3, +39, 9, 37, 10, 32, 6, 24, -4, +28, -8, 25, -4, 24, 1, 36, -3, +42, 1, 34, 1, 33, -5, 32, -4, +26, -4, 26, 0, 30, 4, 32, 4, +37, 1, 36, -2, 35, -6, 31, 0, +20, 0, 22, -3, 33, 0, 33, 2, +35, 2, 42, -1, 34, 1, 29, -6, +26, -4, 20, 2, 25, 4, 33, 3, +42, -3, 49, 0, 34, -5, 29, -9, +26, -4, 11, 7, 22, 6, 31, 10, +40, 7, 48, -3, 37, -8, 34, -10, +26, -8, 15, -5, 27, 2, 27, 7, +34, 9, 45, -1, 45, -4, 40, -3, +27, -12, 26, -10, 23, -6, 24, -2, +34, 0, 42, 7, 45, 5, 38, 3, +26, -3, 24, -6, 13, -5, 22, -7, +38, 1, 39, 2, 48, 3, 42, -1, +28, -1, 25, -7, 22, -10, 23, -5, +39, -3, 36, 0, 43, 1, 46, 1, +27, -1, 27, 6, 16, 3, 13, -5, +39, -11, 38, -12, 48, -6, 53, 1, +32, 6, 30, 10, 14, 5, 13, -12, +31, -10, 30, -8, 45, -2, 50, 9, +36, 11, 35, 4, 22, -3, 16, -7, +25, -17, 34, -10, 47, -5, 48, 0, +46, 1, 40, -1, 28, -1, 21, -2, +23, -1, 28, 0, 34, 0, 41, -10, +45, -5, 37, -2, 29, -3, 28, 2, +27, 6, 28, 2, 33, 0, 39, 0, +42, -8, 37, -7, 29, -9, 34, -7, +27, -8, 32, -3, 46, 5, 36, 12, +37, 9, 32, -2, 21, -5, 27, -18, +19, -13, 31, -4, 50, 1, 43, 2, +50, 8, 40, 3, 24, -8, 19, -2, +14, -3, 24, -2, 35, -4, 46, -7, +58, -10, 52, -8, 35, -5, 27, 3, +21, 7, 11, 3, 22, 2, 46, -11, +51, -14, 52, -7, 44, -2, 30, -2, +20, 3, 11, 4, 25, -1, 39, 0, +42, -1, 53, -3, 51, -10, 35, -11, +27, -11, 24, -5, 25, -1, 28, 7, +41, 5, 51, -8, 49, -7, 41, -10, +36, -9, 31, -7, 25, 2, 28, -2, +34, -6, 44, -9, 44, -6, 43, -2, +46, -3, 28, 7, 24, 3, 32, -9, +35, -17, 48, -7, 41, -3, 37, 4, +34, 10, 20, 1, 30, -4, 30, -4, +36, -5, 52, -7, 45, 0, 45, -4, +29, -1, 18, -7, 29, -5, 20, 5, +39, -3, 57, -4, 52, -5, 52, -6, +34, -9, 20, 5, 16, 3, 17, -2, +32, 0, 49, -7, 51, -8, 54, -6, +43, 6, 24, 4, 20, 2, 19, -8, +30, -8, 40, -9, 45, -8, 59, 1, +48, -2, 35, -4, 32, -7, 21, -8, +34, -13, 38, -2, 41, 4, 57, -1, +38, -6, 41, -13, 41, -15, 22, -12, +41, -3, 36, 3, 42, 5, 54, -6, +36, -5, 41, -4, 30, -10, 19, -5, +35, 1, 32, -3, 41, -7, 57, -1, +50, -7, 46, 2, 31, 3, 17, -1, +24, -7, 28, -13, 38, -11, 58, -4, +54, 4, 43, 5, 36, 9, 20, -6, +23, -9, 27, -6, 40, -8, 56, -8, +52, -2, 48, -5, 38, -10, 28, -1, +26, -1, 27, 5, 44, 1, 46, -3, +47, -11, 51, -13, 35, -12, 34, -1, +27, 7, 25, 4, 38, 7, 36, -7, +50, -11, 50, -4, 33, 0, 45, -8, +36, -4, 29, -6, 39, -13, 36, -7, +46, -3, 44, 5, 37, 0, 43, -4, +37, -9, 28, -9, 42, -13, 45, -3, +38, 6, 46, -4, 37, 1, 28, -2, +29, -6, 24, -4, 38, 3, 45, -1, +42, -2, 58, -5, 46, -12, 32, -6, +29, -4, 20, 0, 28, -3, 38, -6, +50, -9, 61, -3, 54, -4, 40, -1, +32, 4, 18, -6, 13, -10, 36, -10, +46, -5, 52, -3, 63, 5, 46, 0, +37, -7, 27, -11, 19, -13, 35, 1, +31, 3, 45, 2, 60, -3, 48, -11, +44, -18, 36, -5, 29, 0, 28, 5, +28, 10, 42, -5, 47, -15, 48, -16, +46, -5, 37, -2, 38, 6, 29, 3, +32, 0, 38, -5, 36, -12, 47, -5, +46, -4, 41, -7, 41, -5, 32, -2, +36, -11, 42, -1, 40, 2, 46, -1, +42, 0, 30, -6, 34, -14, 37, -14, +36, -2, 47, 4, 40, 10, 45, -2, +45, -7, 26, -9, 34, -10, 27, 3, +25, 7, 50, -2, 46, -9, 52, -7, +48, -14, 28, 0, 32, 9, 18, 8, +27, 1, 49, -11, 45, -15, 57, -17, +51, -8, 40, -3, 34, 8, 19, 1, +29, 0, 34, -1, 38, -10, 54, -8, +47, 0, 39, -3, 36, -7, 29, 1, +33, -7, 35, 0, 32, 4, 43, 0, +38, -4, 36, -9, 45, -7, 35, 0, +33, 7, 34, 2, 33, 2, 42, -12, +39, -16, 41, -6, 47, -1, 33, -1, +41, 2, 41, -5, 36, -14, 42, -5, +38, -6, 47, -3, 47, -7, 38, -7, +39, -7, 30, -11, 36, -9, 44, 3, +41, 12, 45, 1, 37, 0, 34, -8, +30, -17, 26, -10, 39, 1, 46, 1, +46, 8, 44, 5, 39, -10, 38, -11, +29, -10, 28, -3, 39, -2, 42, -3, +44, -5, 48, 1, 39, -2, 33, 1, +35, 5, 30, -10, 40, -13, 44, -16, +41, -11, 48, -1, 37, 10, 37, 6, +43, 3, 28, -3, 39, -19, 45, -15, +37, -9, 43, -1, 38, 0, 41, -3, +43, -5, 33, 2, 37, -4, 41, -2, +39, 2, 39, -9, 41, -11, 37, -11, +36, -8, 43, -8, 37, 7, 41, 4, +42, -1, 41, -8, 50, -13, 34, -5, +30, -3, 35, -1, 27, 0, 39, -4, +44, -10, 46, 1, 51, 0, 42, -4, +35, 1, 30, -7, 23, -13, 33, -14, +47, -5, 49, 1, 51, 7, 50, -1, +37, -7, 31, -12, 27, -15, 30, -4, +42, 2, 42, 0, 51, -3, 52, -5, +38, -15, 34, -5, 31, 2, 30, 1, +34, 3, 39, -4, 45, -12, 44, -12, +45, -7, 43, -4, 40, 5, 37, -4, +32, -8, 44, -8, 35, -12, 38, -4, +48, 2, 37, 0, 42, -6, 42, -4, +32, -11, 46, -9, 38, -1, 37, 3, +43, 2, 30, -5, 41, -10, 42, -11, +38, -5, 45, -4, 42, 5, 39, -2, +42, -6, 34, -3, 31, -2, 35, -1, +29, 5, 40, -3, 51, -16, 44, -5, +45, -7, 38, -1, 34, 4, 31, 5, +30, -7, 48, -15, 47, -13, 46, -9, +48, -1, 40, -3, 36, 3, 28, -2, +31, -7, 43, -7, 45, -5, 50, -2, +42, 1, 34, -3, 34, -14, 29, -8, +35, 1, 35, 8, 41, 7, 51, 1, +40, -9, 38, -13, 34, -14, 27, -1, +33, 9, 37, 2, 43, 5, 44, 1, +35, -9, 39, -10, 36, 1, 28, 1, +32, 2, 37, 1, 38, -10, 42, -3, +37, 2, 37, 6, 40, 5, 32, 0, +35, -10, 41, -14, 38, -15, 45, -8, +43, 8, 41, 4, 41, 1, 37, -5, +41, -10, 36, -14, 41, -3, 42, 0, +40, -6, 50, -9, 39, -9, 33, 2, +31, 3, 29, 7, 39, 7, 43, -1, +43, -12, 45, -8, 38, -9, 35, -7, +31, 7, 31, 3, 38, 2, 38, 0, +45, -2, 46, -6, 43, 0, 36, -3, +34, -5, 34, -8, 35, -12, 41, -3, +45, 0, 43, 3, 42, 4, 38, 0, +40, -11, 37, -6, 37, -4, 39, -5, +40, -1, 39, -5, 38, -7, 44, -9, +43, -4, 45, 1, 43, 7, 39, -2, +40, -7, 34, -12, 38, -19, 44, -9, +37, 4, 41, 8, 44, 3, 38, 1, +46, -14, 41, -11, 41, -6, 39, -4, +34, -2, 40, -3, 34, -5, 37, -7, +48, -4, 49, -2, 45, 5, 42, -1, +32, -5, 28, -9, 29, -11, 32, -2, +36, 9, 47, 7, 52, -4, 52, -1, +40, -7, 25, -5, 25, -2, 28, 2, +27, 1, 45, -3, 50, -5, 53, -9, +51, -1, 37, -1, 35, -1, 36, -6, +29, -6, 33, -3, 41, -1, 39, -2, +52, -2, 51, -2, 39, -7, 41, -3, +33, -6, 36, -2, 39, 3, 34, 3, +44, -2, 46, -9, 41, -9, 45, -6, +39, 0, 39, -3, 43, 2, 35, 2, +37, -2, 35, -1, 37, 1, 41, -3, +43, -4, 44, -5, 45, -9, 39, -1, +39, -3, 39, 3, 36, 7, 32, -1, +41, -9, 44, -15, 49, -12, 48, -4, +43, 7, 41, 4, 34, 5, 25, 2, +29, -8, 41, -12, 44, -4, 54, -2, +50, -1, 46, -2, 41, -9, 32, -8, +37, -8, 37, 3, 34, 6, 48, -1, +50, -12, 46, -16, 48, -13, 34, -2, +32, 13, 35, 12, 36, 3, 48, -6, +40, -11, 40, -20, 47, -11, 38, -2, +41, 4, 41, 8, 45, -1, 42, -2, +41, -7, 39, -4, 33, -5, 35, -2, +35, -6, 43, -3, 42, 2, 44, 2, +41, 10, 44, 4, 34, 0, 32, -4, +30, -5, 32, -12, 42, -4, 44, 1, +51, 3, 51, 5, 47, -3, 46, -6, +37, -11, 32, -14, 38, -14, 43, -8, +48, -6, 54, 3, 53, 6, 50, -2, +47, -4, 33, -13, 41, -18, 36, -15, +36, -1, 44, 5, 44, 11, 47, 7, +48, -3, 46, -9, 43, -14, 36, -7, +33, -1, 35, -1, 36, 0, 41, 1, +52, -7, 49, 1, 48, 6, 42, -2, +47, -8, 35, -14, 32, -13, 35, -10, +39, 0, 46, 9, 49, 13, 53, 4, +48, -7, 40, -13, 33, -17, 31, -7, +28, 5, 36, 12, 41, 9, 46, 4, +52, -9, 55, -15, 47, -10, 43, -5, +32, 0, 32, 1, 31, -1, 36, -1, +39, 4, 50, 1, 53, 1, 54, -3, +46, -11, 38, -12, 31, -10, 28, -6, +36, 8, 33, 17, 50, 8, 51, 3, +52, -11, 50, -19, 38, -17, 40, -11, +34, -1, 39, 6, 44, 8, 47, 4, +49, -3, 51, -13, 43, -11, 42, -10, +41, -9, 40, 2, 39, 7, 43, 4, +42, 0, 48, -7, 47, -15, 48, -9, +43, -4, 44, -2, 43, 1, 41, -2, +45, -6, 43, -4, 41, 3, 34, 2, +48, 3, 37, -4, 47, -13, 48, -16, +49, -11, 46, -1, 44, 12, 40, 11, +43, 0, 40, -10, 39, -23, 43, -17, +42, -6, 43, 10, 47, 23, 41, 15, +43, 0, 39, -12, 33, -18, 37, -18, +41, -2, 42, 7, 52, 6, 52, 4, +46, -5, 53, -12, 40, -11, 44, -7, +39, -3, 37, -1, 41, -8, 41, -7, +45, 1, 42, 6, 47, 11, 46, 10, +45, -2, 41, -13, 34, -19, 37, -20, +33, -5, 46, 6, 49, 14, 57, 15, +52, 4, 48, -10, 38, -18, 31, -17, +27, -7, 30, 5, 44, 9, 50, 11, +56, 4, 56, -4, 48, -11, 40, -10, +36, -12, 37, -6, 35, 3, 40, 2, +41, 2, 53, -1, 50, 2, 44, 4, +50, 1, 38, -4, 40, -7, 35, -13, +36, -14, 47, -5, 46, 5, 51, 14, +51, 14, 48, 0, 44, -18, 44, -20, +29, -15, 38, -8, 47, 6, 47, 14, +53, 12, 45, -2, 51, -19, 43, -20, +41, -9, 32, 5, 39, 17, 35, 15, +42, 3, 42, -7, 45, -14, 44, -8, +43, 6, 39, 10, 43, 5, 36, 1, +40, -8, 37, -12, 47, -4, 44, 3, +49, 9, 46, 6, 39, -5, 44, -14, +33, -12, 41, -4, 36, 10, 47, 18, +40, 15, 43, 3, 40, -17, 49, -26, +42, -16, 43, -1, 49, 9, 47, 14, +47, 10, 41, -4, 39, -12, 39, -18, +41, -13, 43, 4, 44, 9, 49, 9, +46, 3, 49, -9, 43, -12, 40, -8, +41, -5, 38, 1, 44, 6, 39, -1, +51, -8, 51, -9, 50, -8, 49, 4, +37, 12, 38, 7, 29, 1, 37, -13, +37, -17, 44, -5, 46, 4, 57, 14, +50, 22, 40, 12, 37, -9, 30, -21, +32, -22, 30, -9, 45, 9, 51, 19, +56, 19, 57, 3, 49, -13, 40, -19, +31, -16, 31, -3, 33, 8, 42, 11, +49, 4, 53, -8, 62, -14, 47, -8, +47, 2, 34, 11, 30, 9, 27, 1, +34, -9, 40, -17, 53, -11, 57, 3, +54, 15, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_44100_2ch_16b.c b/USDK/example_sources/i2s/src/birds_44100_2ch_16b.c new file mode 100644 index 0000000..960ed33 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_44100_2ch_16b.c @@ -0,0 +1,32143 @@ +#include +int sample_size=128547; + +SECTION(".sdram.data") +short sample[]={ +1, 1, -2, 0, 1, 1, 0, 0, +-1, 3, -2, 0, 1, -1, 1, -1, +2, 2, -4, 3, -3, 5, -4, 1, +-1, 2, 0, -2, 3, -1, 1, 0, +-1, 2, -1, -2, 2, -1, 1, -1, +2, 1, -1, 1, -2, 2, -3, -1, +3, -1, 1, -2, 3, 0, 0, 0, +-2, 3, -4, 2, -3, 4, -3, 1, +2, 0, 1, -2, 1, -1, -2, -1, +1, 0, 3, -4, 5, -3, 3, -4, +2, -2, 0, -3, 3, -2, 2, -1, +2, 1, 0, -3, 4, -5, 2, -5, +3, 1, -1, 1, 1, 2, -1, 0, +-4, 3, -4, 0, 1, 0, 1, -1, +3, 0, 0, -2, 0, 1, -4, 1, +-2, 2, 2, -2, 5, -1, 0, 0, +-4, 4, -6, 2, 0, 1, 2, -1, +2, 2, -2, 0, -1, 0, -1, -3, +2, 2, -1, 2, 2, -1, 4, -6, +3, -3, 0, -2, 2, 0, 2, 0, +2, 3, -4, 1, -2, 0, -1, -2, +4, -3, 5, -3, 4, 1, -1, -1, +-1, 0, -2, -1, 2, -1, 4, -2, +4, 0, -1, -1, -1, -1, 0, -4, +5, 0, 0, 2, -1, 4, -3, 0, +-2, 0, -1, -3, 4, -1, 3, -3, +5, -1, 0, -2, -1, -1, -1, -2, +3, 0, 2, -1, 3, 1, -3, -1, +-1, 0, 0, -3, 2, 1, 0, 2, +0, 1, 0, -3, 0, 1, -6, 3, +-1, 4, -1, 1, 0, 2, -1, -3, +1, -3, 1, -1, 1, 3, -2, 2, +1, 0, 0, -2, -1, 1, -3, 1, +1, 0, 2, -1, 4, -2, 0, -4, +2, -2, 1, -3, 5, -3, 4, -1, +1, 2, -3, -2, 2, -2, 1, -3, +3, 1, 1, 1, -2, 4, -4, 2, +-4, 3, -4, 1, 3, 0, 1, 0, +0, 2, -1, -3, 2, -2, 0, 0, +1, 4, -4, 3, -1, 2, -2, -1, +0, 0, 0, -3, 6, -4, 6, -4, +3, 1, -5, 1, 0, 0, 0, -2, +2, 2, 0, 0, -1, 2, -4, 3, +-4, 3, -2, -2, 5, -2, 3, -3, +3, -2, 1, -3, 0, 1, -2, 2, +-1, 3, -1, -2, 3, -2, 0, -3, +1, 0, 0, 1, -2, 4, -4, 3, +-1, 1, -2, -2, 1, 1, -1, -2, +4, -2, 3, -1, -2, 2, -3, 1, +-1, 3, -4, 2, 0, 3, -3, 3, +-5, 4, -2, -1, 1, 0, -1, 0, +2, 1, -1, -1, 1, 1, -2, 0, +-2, 3, -1, 1, 0, 2, -3, 2, +-1, 2, -3, 0, 0, 2, 0, -1, +1, 1, -1, 1, -1, 1, -2, 0, +1, 1, -1, 0, 1, 2, -1, 0, +-1, 0, 1, -3, 4, -2, 2, -2, +3, 0, -1, -1, 1, 0, 0, -2, +2, -1, 2, -2, 2, 1, -1, -2, +2, 0, -1, -1, 2, -1, 3, -3, +3, -1, 0, -1, 0, 1, -2, -1, +3, 0, 0, -1, -1, 3, -2, 1, +-2, 1, -1, 0, 1, 0, 1, -3, +4, 0, -3, 1, -3, 3, -2, 2, +-2, 2, -2, 2, -2, 4, -5, 0, +1, 1, -2, 1, -2, 4, -2, 1, +-2, 2, -1, -1, 1, -1, 0, -2, +3, 1, -2, 2, -4, 5, -5, 4, +-5, 4, -3, 2, 0, 2, -2, -2, +4, -1, 0, -1, -1, 1, 1, -1, +1, 0, 1, -1, 1, 1, -3, 0, +1, 1, -1, 1, 0, 0, 2, -2, +1, 0, -1, -2, 4, -1, -2, 2, +-2, 5, -2, -1, 1, -1, 1, 0, +-2, 3, -3, 2, 2, 1, -2, -2, +4, -1, 0, -2, 0, 2, 0, 1, +-1, 1, 1, -4, 6, -4, 1, -2, +2, 1, -1, 1, -1, 1, 2, -3, +1, 2, -6, 4, -1, 2, -1, -2, +3, 0, 0, 0, -4, 4, -3, 2, +-1, 2, -3, 1, 1, 3, -5, 2, +-3, 5, -5, 3, -4, 3, 0, -1, +2, 0, -2, -1, 1, 1, -2, -2, +3, -2, 4, -4, 1, 0, 0, 0, +-1, 2, -5, 2, 0, 3, -4, 1, +0, 1, -1, 1, -4, 3, -3, 1, +1, 1, -2, 0, 1, 3, -5, 1, +-1, 1, 0, -1, 1, -1, 2, -3, +4, 0, -4, 2, -1, 3, -4, 1, +0, 1, 2, -2, 2, -2, 1, -2, +2, 1, -3, -1, 5, -2, 3, -5, +4, -2, 3, -2, -1, 1, 0, -1, +3, 0, -1, -1, 4, -1, 0, -2, +-1, 3, -1, 2, -2, 2, 0, -1, +3, 0, -3, 0, 0, 4, -4, 2, +-1, 0, 4, -3, 2, 0, -3, 1, +2, 0, -1, -3, 4, 2, -1, -1, +0, 0, 1, 0, -3, 4, -4, 3, +-1, 4, -5, 2, -1, 3, -3, 1, +-2, 0, 2, -1, -1, 4, -5, 4, +-3, 5, -7, 3, -3, 4, -3, 2, +-3, 4, -3, 3, -3, 2, -3, 0, +0, 4, -7, 4, -3, 5, -4, 3, +-4, 2, -1, 0, -2, 3, -5, 3, +-1, 5, -6, 1, 0, 0, 2, -4, +2, -4, 5, -4, 4, -2, 0, -3, +5, -2, -1, -3, 3, -1, 2, -2, +0, 0, 3, -3, 2, 0, -4, 1, +2, 1, -2, 0, 0, 2, 0, 0, +-1, 0, 1, -2, 2, 1, -4, 3, +-1, 6, -6, 3, -4, 5, -2, 1, +-2, 0, 2, -1, 3, -1, 0, -3, +6, -2, 0, -2, 1, 2, 0, 2, +-4, 3, 0, -1, 3, -1, -1, -3, +5, -1, 0, 0, -1, 2, 1, 0, +-1, 0, 0, -1, 2, 1, -3, 0, +3, 0, -1, 1, -2, 2, 0, -1, +1, -1, 1, -2, 4, -1, -1, -1, +1, 2, -3, 1, -2, 2, 0, 0, +0, -1, 1, -2, 2, 2, -6, 2, +-1, 4, -4, 1, -1, 0, 2, -1, +-2, 2, -2, -3, 6, -3, -1, -1, +1, 2, -1, -2, -1, 1, 1, -2, +2, -4, 3, -4, 5, -1, -2, -3, +4, -1, 0, -1, -2, 2, -1, 1, +0, -1, 1, -5, 7, -3, 1, -6, +7, -5, 4, -2, -1, 1, 0, -1, +2, -1, -1, -1, 2, 3, -5, 1, +0, 2, -1, 2, -5, 5, -4, 4, +-3, 4, -4, -1, 6, -2, 0, -2, +1, 2, 0, 0, -1, -1, 4, -3, +3, 0, -2, -1, 5, -1, -1, -1, +1, 1, 1, 0, -2, 3, -1, 1, +0, 3, -5, 2, 2, 1, -1, -1, +0, 2, 0, 1, -2, 2, -2, 2, +0, 2, -3, -1, 4, 0, 0, -3, +2, 1, 0, 2, -4, 2, 0, 1, +-1, 4, -6, 1, 3, -1, 1, -3, +1, 1, -1, 2, -3, 1, 0, -1, +2, 0, -2, -3, 6, -2, -1, -1, +-1, 2, 0, 0, -2, 0, 1, -2, +2, 2, -5, -1, 3, 0, -2, 2, +-5, 4, -1, 0, -2, 2, -4, 2, +0, 2, -5, 1, 0, 2, -1, -2, +1, -2, 3, -2, 0, -1, 0, -2, +3, 2, -7, 4, -3, 6, -6, 2, +-2, 1, 3, -4, 2, -2, 3, -6, +8, -5, 2, -4, 4, -1, 1, -3, +2, -2, 4, -1, -2, 4, -6, 4, +-1, 4, -5, 1, 1, 1, 1, -2, +2, -3, 5, -3, 2, 1, -4, 2, +2, 2, -3, -1, 4, -2, 4, -5, +3, -2, 3, -1, 1, 0, -1, 0, +2, 3, -4, -1, 3, -1, 2, -1, +-1, 1, 2, -1, 1, 1, -2, -1, +4, 0, -2, -1, 2, 0, 2, -1, +-2, 2, -1, 2, -2, 2, -2, -2, +5, 0, -2, -1, 2, -1, 2, -2, +0, -1, 2, -3, 2, 1, -2, -2, +4, -1, -2, 0, -2, 4, -4, 3, +-4, 2, 1, -3, 3, -1, -2, -2, +5, -3, 1, -4, 2, 0, 1, -1, +-1, 0, 0, -2, 2, 0, -3, -1, +2, 3, -5, 2, -3, 3, 0, -2, +0, -2, 2, -2, 1, 2, -4, 0, +2, 1, -1, -2, 0, -1, 3, -2, +0, 0, -1, 1, 2, 0, -3, -1, +2, 2, -3, 1, -2, 2, 1, 0, +0, -1, 1, -3, 5, -2, -1, -2, +4, 0, 1, -2, 2, -2, 3, -1, +0, 0, -1, 0, 3, 1, -2, -2, +6, -2, 1, -2, 1, -1, 4, -3, +3, -2, 1, -1, 4, 0, -2, -2, +3, 0, 1, -2, 2, -3, 7, -6, +5, -3, 2, -4, 7, -4, 1, -3, +3, 2, -1, 1, -3, 3, -1, 2, +-3, 2, -1, -2, 5, -2, 1, -4, +5, -2, 1, -1, -2, 1, 1, -1, +0, 1, -1, -2, 5, -2, -2, 0, +-1, 3, -3, 1, -2, 1, 2, -2, +0, 2, -5, 2, 0, 2, -5, 1, +0, 1, 1, -2, -1, 1, -1, 0, +-1, 1, -3, 0, 1, 3, -5, 2, +-3, 4, -2, -1, -1, -1, 1, 0, +-1, 3, -4, 0, 2, 2, -4, -1, +1, -1, 4, -4, 1, -2, 4, -4, +5, -4, 1, -4, 5, 0, -2, -1, +1, 1, 1, 0, -2, 1, -1, 2, +-2, 4, -5, 0, 5, -1, 0, -1, +0, 2, 0, 0, -2, 2, 0, 0, +1, 2, -4, 3, -1, 4, -4, 2, +-1, 0, 3, -2, 2, -1, 2, -3, +5, -2, 1, -4, 6, -2, 1, -1, +0, 2, 2, -3, 3, -3, 3, -3, +3, 1, -2, -1, 4, -2, 3, -4, +3, -1, 1, 0, -2, 3, -3, 2, +0, 3, -4, 0, 1, 2, -2, 0, +-1, 0, 2, 1, -3, 4, -5, 2, +0, 3, -5, 1, 0, 1, 1, -3, +2, -2, 2, -1, -1, 1, -3, 0, +2, 2, -5, 2, -1, 2, -1, -2, +1, -2, 3, -4, 3, -1, -1, -1, +2, 1, -3, -2, 2, -1, 1, -2, +-1, 2, -1, 0, 0, 0, -1, -1, +0, 3, -5, 2, -2, 4, -2, 0, +-1, 0, 1, -1, 0, 0, -1, -1, +2, 2, -4, 2, -1, 1, 1, -2, +-1, 1, 0, 0, 1, 0, 0, -2, +4, 0, -3, 1, -1, 3, -2, 2, +-2, 1, 2, -2, 2, 2, -5, 3, +-1, 3, -3, 1, 0, 3, -1, 1, +-1, 0, 2, -2, 2, 0, -2, 0, +4, 0, 0, -1, 0, 2, 0, -1, +1, -1, 1, 0, 2, 0, 1, -4, +6, -2, -1, 0, -1, 2, 1, -2, +3, -2, 2, -1, 0, 3, -5, 2, +-1, 2, -1, -1, 2, 0, 0, 0, +-1, 1, -2, 1, -2, 5, -7, 3, +1, 1, 1, -5, 4, -4, 3, -1, +-3, 4, -5, 3, 0, 1, -1, -3, +3, -1, 0, -3, 2, -2, 2, -1, +0, 1, -1, -1, 0, 2, -4, 0, +1, -1, 1, -1, -1, 3, -3, 3, +-4, 3, -4, 1, 0, 1, -2, 0, +0, 3, -3, 2, -4, 3, -2, 0, +0, 0, -1, 0, 2, 1, -2, -1, +1, 0, 1, -4, 3, -3, 4, -3, +3, -1, 0, -2, 4, -2, -1, 0, +-1, 4, -2, 0, 1, 0, 1, 0, +-1, 2, -3, 0, 3, 0, -1, 0, +0, 5, -4, 2, -2, 1, 0, 0, +1, 0, 1, -3, 5, -1, 0, -1, +0, 2, -2, 1, -1, 2, 0, 0, +0, 3, -4, 3, -3, 6, -7, 4, +-2, 2, 2, -3, 1, 2, -2, 2, +-3, 4, -4, 1, 2, -1, 2, -4, +3, 0, 0, 0, -2, 2, -1, -2, +4, -2, 1, -1, -1, 5, -6, 3, +-2, 1, -1, 1, -3, 4, -3, 1, +0, 2, -5, 3, -2, 2, -2, 0, +-2, 5, -5, 4, -4, 2, 0, -3, +3, -2, 0, -2, 2, 0, 1, -4, +3, -2, 2, -3, 2, -3, 4, -5, +4, -2, 1, -3, 3, -1, 0, -2, +0, 1, -1, 1, -1, 2, -2, 0, +1, 0, -1, -1, 0, 2, -2, 0, +2, -2, 3, -3, 0, 2, -3, 2, +-1, 1, -1, 0, 2, 0, 0, -2, +2, -1, 2, -4, 4, -2, 1, 0, +1, 1, -1, -2, 3, -1, 1, -3, +3, -1, 2, -1, 0, 3, -4, 4, +-3, 3, -3, 1, 1, 2, -1, -1, +3, -2, 3, -3, 2, -1, 0, -1, +2, 0, 1, -2, 3, 0, -1, -1, +2, -2, 2, -2, 1, 2, -1, -1, +3, -1, 0, -1, 0, 1, 0, -2, +1, 2, -1, 1, -1, 2, -2, 0, +-1, 2, -2, -1, 2, -1, 3, -4, +4, -3, 2, -3, 2, -2, 1, -2, +1, 3, -3, 1, 0, 2, -4, 4, +-8, 8, -7, 4, -2, 3, -3, 2, +-1, 2, -3, 0, -1, 2, -2, -1, +2, -1, 2, -2, 2, -1, 0, -3, +1, 1, -3, 1, 0, 2, -1, 0, +0, 0, 0, -2, 0, 1, -2, 0, +2, 0, 0, -1, 1, 1, -1, -1, +-2, 3, -3, 2, 0, 1, 1, -3, +3, -1, 0, -2, 1, -1, 2, -3, +3, 1, -1, 2, -3, 4, -3, -1, +2, -2, 3, -4, 3, 1, 0, 1, +-1, 1, 0, -3, 3, -2, 2, -3, +5, -2, 2, -2, 1, 1, 0, -3, +2, -1, 1, -1, 2, 0, 1, -1, +1, 1, -3, 2, -3, 3, -2, 0, +3, -1, 1, 0, -1, 3, -3, -1, +1, 1, -2, 2, 0, 0, 3, -4, +2, 2, -5, 3, -2, 1, 0, -2, +3, 0, 1, -2, 0, 3, -6, 5, +-6, 5, -3, 1, 0, 3, -4, 4, +-4, 3, -2, -3, 5, -5, 5, -6, +5, -2, 3, -4, 3, -2, 0, -1, +-1, 2, -1, -1, 2, 0, -1, 1, +-3, 4, -5, 3, -4, 3, -1, -1, +3, -2, 1, -2, 2, 0, -1, -2, +0, 2, -1, 0, 0, 2, -3, 4, +-6, 7, -6, 2, -1, 0, 2, -3, +4, -4, 4, -3, 1, 1, -2, -2, +5, -5, 5, -5, 4, -1, 1, -2, +2, -1, 0, -1, 0, 1, 1, -2, +1, 3, -4, 3, -2, 2, -2, 1, +-2, 4, -3, 2, -2, 3, -1, -1, +2, -2, 2, -2, 1, 1, -1, 1, +1, 0, 0, -1, 1, 0, 0, -2, +3, -1, 1, -3, 4, -2, 3, -4, +2, 1, -1, 0, 0, 1, -1, 2, +-4, 7, -7, 4, -2, 1, 0, 0, +-1, 2, 0, -3, 4, -2, 0, 0, +-1, 3, -3, 1, 0, 0, 1, -2, +0, 2, -2, 0, 0, 2, -3, 2, +-2, 3, -2, 1, -2, 3, -4, 2, +-1, 2, -2, 0, 0, 1, 0, -3, +2, 0, -1, 0, -1, 2, -1, 0, +0, 0, 1, -3, 2, 0, -2, 1, +-1, 2, -1, -1, 0, 1, 1, -3, +2, -2, 1, -1, 0, 3, -4, 3, +-3, 4, -3, 1, -2, 2, -2, 2, +-3, 5, -5, 4, -3, 4, -3, -1, +2, -2, 3, -5, 4, -2, 3, -2, +0, 3, -3, -1, 3, -4, 5, -5, +3, 0, 1, -1, 1, 0, 0, -1, +0, 1, -1, -1, 2, 0, 1, -2, +2, 1, -2, 0, 0, -1, 2, -3, +3, 0, 1, -2, 2, 0, -1, 0, +0, 0, 0, -1, 1, 1, 0, 1, +-2, 3, -2, -1, 1, 0, -1, 0, +2, -2, 4, -3, 1, 1, -1, -2, +3, -3, 2, -2, 2, 1, -1, 0, +0, 1, 0, -2, 0, 1, -1, 0, +0, 3, -3, 3, -3, 3, -2, -3, +4, -4, 4, -4, 3, -1, 1, 0, +-1, 3, -5, 2, -2, 3, -3, 0, +1, 1, 0, 0, -1, 1, 0, -3, +2, -1, -1, 0, 1, 2, -2, 0, +0, 0, 1, -3, 0, 1, 0, -2, +3, -1, 1, -1, 1, -1, 1, -3, +1, 1, -3, 4, -3, 2, 2, -4, +4, -1, -3, 2, -3, 3, -1, -1, +3, -2, 3, -3, 2, 0, -2, 1, +-2, 3, -3, 1, 1, 0, 2, -3, +2, 0, -2, 2, -3, 3, -2, 0, +2, 1, -1, 1, -2, 3, -2, -1, +0, 1, 0, -1, 2, -1, 2, -1, +-1, 3, -3, -1, 3, -2, 1, -1, +2, -1, 3, -3, 1, 2, -4, 2, +-1, 2, -2, 0, 2, 0, 0, 0, +-2, 3, -2, -1, 1, -1, 1, -1, +1, 1, 0, -1, 0, 2, -3, 1, +-2, 2, 0, -1, 2, -2, 2, -2, +1, 2, -5, 3, -3, 3, -1, -1, +1, 0, 1, -2, 1, 1, -3, 1, +-1, 1, 0, -2, 2, 0, 1, -3, +2, -3, 4, -5, 3, -1, 0, -1, +2, 0, 0, -2, 2, -2, 3, -4, +1, 0, 0, 1, -1, 1, 0, -2, +2, 0, -1, -1, 1, -1, 2, -2, +1, 1, -1, 0, 0, 0, 1, -4, +5, -4, 3, -3, 3, -2, 3, -3, +0, 3, -4, 2, 0, -1, 2, -3, +2, 2, -3, 2, -2, 2, 0, -1, +0, 1, -1, 1, -1, 3, -3, 2, +-3, 5, -3, 0, 0, 0, 2, -3, +3, -3, 4, -3, 1, 1, -1, -1, +3, -3, 3, -2, -1, 4, -3, 1, +0, -1, 2, -3, 2, 1, -2, 1, +-2, 4, -2, 0, 0, 0, 1, -1, +0, 1, -1, 1, -2, 3, -3, 2, +-2, 3, -1, -2, 2, -1, 1, -1, +0, 0, 2, -5, 6, -5, 5, -6, +4, -1, 0, 0, -2, 3, -2, 1, +-2, 3, -2, 0, 0, 2, -4, 3, +-4, 5, -3, 1, -2, 3, -3, 3, +-2, 1, -1, -1, 1, 0, 1, -4, +4, -2, 1, 0, -2, 2, -1, -1, +1, 0, -1, 0, 1, 1, -1, -1, +1, 0, 1, -3, 1, 1, -1, 2, +-3, 4, -3, 0, 2, -1, 0, -1, +0, 1, 0, -2, 3, -2, 2, -1, +-1, 2, -2, 0, 0, 2, -2, 1, +0, 0, 2, -2, 1, 0, -1, 1, +-2, 4, -4, 2, 0, 1, 0, -1, +0, 1, 0, -1, 0, 0, 1, -2, +3, 0, 0, -2, 2, -1, 1, -3, +2, -1, 2, -2, 1, 0, 1, -1, +0, 1, -2, 1, -1, 1, -1, 0, +1, 1, -1, 1, -3, 4, -4, 2, +-1, 1, -1, -1, 3, -2, 3, -4, +2, 0, -2, 1, -2, 3, -3, 2, +-1, 2, -2, 1, -2, 4, -5, 2, +-2, 2, 0, -1, 1, 0, 0, -1, +1, 0, -1, -2, 2, -1, 1, -1, +0, 1, 0, -1, 1, -1, 0, -2, +2, -1, 1, -3, 3, 0, 0, -1, +-1, 1, 0, -1, 0, 0, 0, 0, +1, 1, -2, 0, 0, 2, -3, 1, +-2, 2, 0, 0, -1, 3, -2, 0, +1, 0, -1, -1, 1, 0, 2, -3, +1, 1, 0, 0, -1, 2, -3, 1, +0, 0, 2, -4, 4, 0, 0, -1, +1, -2, 3, -3, 1, 1, -1, 0, +1, 1, -1, 0, 0, 1, -1, -1, +1, 0, 1, -1, 0, 2, -1, -1, +2, 0, -3, 3, -5, 7, -4, 1, +0, 0, 1, 0, -1, 1, -1, -1, +1, 1, -1, -1, 2, -1, 2, -1, +-2, 2, -1, 0, -1, 2, -2, 0, +2, -1, 0, 0, -2, 4, -3, 0, +-1, 1, 1, -2, 2, -2, 2, -3, +3, -2, 1, -3, 1, 2, -2, 0, +0, 1, 0, -1, 0, 1, -2, 1, +-1, 1, 0, -2, 1, 2, -3, 4, +-6, 6, -6, 5, -5, 5, -4, 1, +0, 2, -2, 1, -2, 2, -1, 0, +0, -1, 1, -2, 2, 1, -1, -1, +0, 2, -3, 2, -2, 1, 0, 0, +0, 1, -1, -1, 2, 0, 0, -3, +4, -4, 5, -6, 4, -1, 1, -1, +2, -3, 4, -5, 4, -1, 0, -2, +3, -1, 1, -1, 0, 0, 3, -5, +4, -2, 0, 2, -3, 4, -3, 2, +-2, 4, -4, 3, -4, 5, -4, 3, +-3, 3, -1, 0, 0, 1, -1, 0, +-1, 3, -2, -1, 1, 0, 1, 0, +-1, 1, 0, -1, 0, 3, -5, 3, +-2, 3, -2, 2, -3, 3, -2, 2, +-3, 3, -3, 1, 0, 1, -1, 0, +0, 1, -1, 0, 0, 0, -1, 1, +-2, 3, -2, 0, 0, 3, -4, 2, +-3, 3, -2, 1, -2, 1, 1, -2, +2, -1, 1, -3, 2, 0, -1, -1, +1, -1, 3, -4, 3, -1, 0, 0, +-2, 3, -2, -1, 1, -1, 2, -2, +1, 1, -2, 1, -1, 1, 0, -2, +1, 0, 0, 0, 0, 2, -2, 0, +-1, 2, -2, 2, -3, 3, -1, 0, +1, 1, -2, 1, -1, 3, -4, 2, +-2, 3, -1, 0, 0, 1, -1, 1, +-2, 4, -5, 2, 0, 1, 0, -1, +1, 1, 1, -3, 3, -3, 4, -4, +2, 0, 1, -1, 1, 1, -1, -1, +2, -1, 1, -2, 0, 2, 0, -2, +3, -2, 3, -4, 2, 0, 0, -1, +0, 0, 2, -2, 2, -1, 1, -2, +2, -1, 1, -4, 4, -2, 2, -2, +0, 2, -1, 0, -1, 0, 1, -3, +3, -1, 0, -1, 1, 1, -1, 0, +-1, 0, 2, -4, 3, -2, 1, 0, +0, 1, -1, -1, 0, 2, -2, -1, +1, -1, 2, -1, -2, 4, -4, 3, +-3, 3, -3, 0, 1, 0, 0, 0, +-1, 1, 1, -3, 3, -2, 0, 0, +-2, 4, -3, 1, 0, 1, -1, 0, +-1, 1, 0, -1, -1, 3, -3, 2, +-1, 1, 0, -1, 1, -1, 2, -4, +4, -3, 3, -4, 4, -2, 1, -1, +0, 1, -1, -1, 1, 1, -1, 0, +0, 1, 1, -2, 2, -2, 2, -3, +3, 0, -1, 0, -1, 3, -2, 2, +-3, 2, 1, -3, 3, -2, 2, -2, +2, 0, 0, -1, 2, -2, 3, -3, +0, 3, -2, 0, 1, -2, 4, -5, +4, -1, -1, 0, 0, 1, 0, -1, +1, -1, 3, -3, 1, 1, -1, 0, +0, 1, -1, -1, 2, -1, 1, -1, +-1, 2, -1, -1, 1, 0, 0, -2, +2, 0, 0, -1, 0, 1, -1, 1, +-3, 3, -1, -2, 3, -2, 1, -1, +0, 1, -1, 0, -1, 2, -2, 1, +-2, 3, -3, 3, -3, 3, -2, -2, +4, -3, 2, -3, 1, 1, 0, -1, +0, 1, -1, 0, 0, 0, 0, -1, +0, 3, -3, 1, 0, 0, 1, -1, +-1, 2, -3, 3, -3, 4, -3, -1, +3, -1, 1, -1, -1, 1, 0, -1, +1, 0, 1, -2, 1, 1, 0, -2, +2, -1, 1, -2, 1, 0, 2, -2, +1, -1, 2, -2, 1, 1, -3, 2, +-1, 2, 0, -2, 1, 2, -2, 2, +-3, 3, -1, -2, 3, -2, 2, -2, +2, 0, 1, -3, 2, -1, 1, -1, +0, 1, -1, 1, -1, 2, -2, 1, +-1, 2, -2, 0, 1, -1, 1, 1, +-3, 5, -5, 3, -3, 5, -6, 4, +-3, 3, -1, -1, 1, 1, 0, -2, +1, -1, 1, -2, 2, 0, -1, 0, +0, 1, 0, -2, 1, 0, -1, 0, +-1, 2, -1, 0, 0, 1, -1, -1, +0, 1, -1, 0, -1, 2, -2, 2, +-3, 5, -4, 0, 1, 0, -1, 0, +-1, 2, -1, 0, -1, 3, -2, -1, +1, -1, 2, -4, 3, -1, 2, -4, +4, -3, 4, -5, 3, -2, 2, -3, +3, -2, 2, -3, 3, 0, -1, -1, +1, 0, 1, -3, 3, -2, 2, -2, +1, 2, -3, 2, -3, 5, -5, 3, +-2, 2, 0, -1, 1, -1, 3, -5, +4, -2, 0, 1, -2, 3, -2, 1, +-1, 3, -4, 4, -4, 4, -3, 0, +2, -1, 1, -2, 2, 1, -2, 1, +-2, 3, -1, -1, 1, -1, 3, -3, +1, 2, -2, 0, 1, -2, 4, -5, +4, -2, 1, -1, 1, 0, 0, -2, +2, -1, 2, -4, 3, -1, 1, -2, +2, -1, 1, -2, 1, 1, -2, 2, +-3, 5, -5, 3, -2, 3, -3, 1, +-2, 3, -1, -1, 0, 1, 0, -2, +2, -1, 1, -3, 3, -2, 1, -1, +-1, 2, -1, -1, 1, 0, 0, -2, +2, 0, -1, 0, 0, 1, 0, -2, +1, 0, 1, -3, 3, -3, 3, -3, +1, 2, -3, 2, -3, 4, -3, 1, +-1, 1, 0, -1, 0, 2, -2, 0, +0, 2, -2, 0, 0, 1, 0, -1, +0, 2, -2, 1, -1, 1, 0, -1, +0, 3, -3, 1, -1, 2, 0, -2, +2, -2, 2, -1, 1, -1, 2, -3, +2, 1, -2, 0, 1, 0, 0, 0, +-1, 2, -1, 0, 0, 2, -2, 0, +0, 1, 0, -1, 1, 0, 1, -1, +-1, 3, -3, 2, -2, 1, 2, -3, +1, 1, -1, 1, 0, -2, 3, -3, +1, 2, -4, 4, -3, 3, -1, -2, +2, 0, 0, -2, 2, -1, 1, -2, +1, 2, -3, 2, -2, 3, -3, 2, +-3, 3, 0, -3, 3, -1, 1, -1, +-1, 1, 1, -4, 5, -5, 4, -4, +3, 1, -3, 1, 0, 1, -1, -1, +0, 2, -2, 1, -1, 1, 1, -4, +5, -4, 4, -6, 4, -1, 1, -1, +-1, 3, -2, 0, -1, 2, -1, -1, +0, 1, 0, -2, 2, 0, 1, -2, +-1, 3, -2, 0, 0, 1, -1, 0, +0, 2, -1, -1, 1, -2, 5, -7, +5, -2, 1, 1, -3, 4, -3, 1, +0, 1, -1, 0, -2, 3, 0, -1, +1, 0, 0, -1, 1, 2, -4, 2, +-1, 3, -3, 2, -3, 5, -3, 0, +0, 1, -1, 0, 0, 1, 0, -1, +1, 0, 2, -4, 3, -1, 0, 1, +-3, 4, -3, 2, -1, 1, 0, -2, +2, -1, 2, -5, 6, -4, 3, -3, +2, 0, 0, -1, 0, 2, -2, -1, +2, -1, 2, -3, 2, -1, 2, -2, +0, 0, 1, -2, 2, -1, 1, -1, +0, 1, 0, -2, 1, 0, 0, -1, +1, 0, 0, -1, 0, 4, -5, 1, +1, -1, 2, -3, 1, 1, -1, 1, +-2, 2, 0, -3, 2, 1, -3, 2, +-2, 2, 0, 0, -3, 5, -5, 4, +-4, 4, -4, 3, -3, 4, -3, 0, +1, 0, 0, -2, 1, 1, -2, 1, +-1, 2, -1, -1, 0, 3, -4, 2, +-2, 3, -1, -1, 0, 1, 1, -1, +-1, 2, 0, -2, 2, -2, 2, -2, +1, 1, -1, 0, 0, 1, -1, -1, +1, 2, -2, 0, 1, 0, 1, -3, +3, -1, 2, -4, 3, -2, 3, -3, +2, -1, 1, -1, 0, 2, -2, 0, +0, 1, 1, -2, 1, 0, 1, -2, +1, 1, -1, -2, 3, -2, 2, -2, +1, 1, 0, -2, 1, 2, -3, 2, +-2, 2, 1, -4, 4, -3, 3, -3, +2, -2, 2, -2, 1, -1, 3, -4, +3, 0, -2, 1, -1, 2, 0, -3, +2, 0, 0, -1, 1, 1, -2, 0, +0, 1, 0, -3, 3, -1, 2, -4, +4, -3, 3, -3, 1, 0, 1, -3, +2, -1, 3, -5, 5, -4, 4, -5, +3, 0, 0, -2, 2, -1, 1, -1, +0, 3, -4, 1, 0, 1, 0, -3, +3, -1, 1, -1, 0, 0, 1, -2, +1, 0, 1, -4, 5, -4, 4, -3, +0, 3, -3, 2, -3, 3, -2, 1, +-1, 2, -1, -1, 2, 0, -1, -1, +2, 0, -1, 0, -1, 4, -3, 1, +-1, 2, -1, -2, 2, 0, 0, -1, +1, -2, 5, -6, 5, -3, 2, -2, +0, 2, -2, 1, -1, 2, -1, -1, +1, 1, -2, 0, 1, 0, 0, -2, +2, 2, -4, 3, -3, 5, -4, 1, +-1, 1, 1, -3, 4, -3, 3, -2, +-1, 3, -2, 0, -1, 2, 0, -1, +-1, 3, -3, 3, -2, 1, 0, -3, +3, 0, 0, -4, 5, -2, 1, -1, +-1, 3, -3, 1, -1, 2, -2, 1, +-1, 3, -2, -1, 2, -2, 3, -4, +1, 1, 0, -1, 0, 1, 0, -1, +0, 1, 0, -3, 3, -1, -1, 1, +-2, 5, -5, 1, 1, -1, 1, -3, +2, 2, -3, 0, 1, 0, 1, -1, +-1, 2, -1, -1, 1, 0, 0, 0, +-1, 2, 0, -2, 1, 0, 1, -3, +2, 0, 1, -3, 3, -1, 1, -2, +1, 2, -2, -2, 3, 0, 0, -2, +2, 0, 0, -1, 0, 2, -2, 0, +-1, 3, -1, 0, -2, 3, -2, 2, +-3, 3, -1, -1, 0, 2, -3, 3, +-3, 4, -2, -2, 2, 1, -2, 1, +-2, 4, -3, 1, 0, 1, -1, -1, +1, 1, -1, -1, 1, 0, 1, -1, +-1, 2, 0, -1, 0, 1, -1, 1, +-3, 5, -3, 0, 1, -1, 2, -4, +4, -2, 1, -3, 4, -2, 1, -2, +2, 1, -3, 2, -3, 5, -4, 1, +0, 0, 1, -2, 1, 1, -1, 1, +-3, 3, -1, 0, 0, 0, 0, 0, +-1, 3, -3, 0, 1, 0, 0, -2, +2, 1, -2, 0, 0, 2, -2, -1, +1, 2, -3, 2, -2, 3, -2, 1, +-2, 4, -3, 1, -1, 0, 2, -2, +0, 1, 1, -4, 4, -2, 1, -1, +0, 1, 0, -2, 2, 0, 0, -2, +3, -1, -1, -1, 2, 1, -2, -1, +2, 0, 1, -4, 4, -2, 1, 0, +-3, 5, -3, 1, -1, 1, 1, -2, +0, 2, -2, 1, -1, 1, 0, -1, +1, 1, 0, -3, 3, 0, -1, -2, +4, -2, 1, -3, 3, 1, -2, 0, +-1, 3, -2, -1, 1, 0, 1, -3, +3, -3, 6, -6, 2, 1, -2, 3, +-5, 6, -3, -1, 2, -1, 1, -2, +1, 1, 0, -3, 3, 0, -1, 0, +0, 2, -2, -1, 2, -1, 1, -3, +2, 1, 0, -2, 2, -2, 3, -2, +-1, 1, 1, -2, 0, 3, -4, 3, +-2, 2, -1, 0, -2, 4, -4, 2, +-1, 2, -2, -1, 2, 1, -2, -1, +2, -1, 1, -3, 3, -1, 2, -3, +1, 1, -1, 1, -3, 4, -3, 2, +-2, 0, 3, -3, 1, 1, -2, 0, +1, 0, 0, -2, 2, 0, 0, -2, +2, 1, -3, 1, -1, 3, -3, 0, +1, 1, -1, -2, 3, -1, 1, -2, +0, 0, 2, -2, 0, 1, 0, 0, +-2, 4, -4, 2, -1, 1, 0, -2, +1, 2, -2, 0, 1, 0, -1, -2, +4, -1, -1, -1, 0, 4, -3, -1, +2, -1, 1, -2, 0, 1, 2, -5, +5, -4, 4, -2, -2, 3, -1, 0, +-1, 0, 1, -1, 1, 0, 0, -2, +3, 0, -2, 0, 0, 3, -3, 0, +1, 1, 0, -2, 1, 2, -3, 1, +0, 0, 1, -3, 3, -2, 3, -3, +0, 2, -2, 2, -3, 3, -1, -2, +3, -2, 3, -4, 2, 1, -3, 2, +-2, 4, -4, 1, 0, 3, -3, -1, +3, -2, 2, -4, 3, 0, 0, -2, +2, -1, 2, -1, -2, 3, -2, 0, +0, 1, 0, -1, -1, 3, -2, 1, +-1, 1, -1, -1, 1, 1, -1, -2, +3, 0, -1, -2, 3, -1, 1, -4, +4, -1, -1, 1, -2, 4, -2, -2, +3, -2, 3, -4, 1, 2, -1, 1, +-3, 3, 0, -1, 0, 0, 0, -1, +1, 1, -2, 1, -2, 6, -7, 4, +-2, 3, -3, -1, 3, -1, 2, -5, +3, 1, -1, 1, -3, 4, -3, 2, +-3, 3, 0, -1, 0, 0, 1, -2, +1, 1, -1, 0, -1, 2, -1, 0, +0, 3, -4, 0, 3, -1, 0, -2, +0, 5, -5, 1, 0, 2, -2, 1, +-2, 3, -2, 1, -2, 3, -1, -1, +1, -1, 3, -3, 0, 1, 0, 0, +-1, 2, -2, 1, -1, 4, -5, 2, +0, 1, 0, -4, 5, -1, 0, -3, +4, -2, 2, -4, 3, 0, 0, -2, +1, 1, 0, -1, 0, 0, 2, -2, +0, 0, 2, -3, 2, 0, 0, -1, +1, 0, 1, -3, 1, 3, -4, 1, +0, 2, -3, 1, 0, 2, -3, 0, +0, 4, -5, 2, -2, 3, -1, -1, +0, 1, 0, -2, 1, 0, 2, -3, +1, -1, 3, -3, 1, 1, -2, 1, +-1, 3, -3, 0, 0, 4, -5, 2, +-1, 3, -3, 0, 1, 1, -1, -2, +3, -1, 1, -2, 0, 3, -3, 1, +-1, 1, 2, -3, 0, 2, -2, 2, +-3, 3, -1, -2, 1, 3, -4, 2, +-2, 4, -3, 0, 1, 0, 0, -3, +3, 2, -4, 1, 0, 2, -1, -2, +1, 1, 1, -3, 2, -2, 3, -2, +0, 1, 0, 0, -2, 3, -2, 1, +-1, 2, -2, 2, -2, 3, -2, -2, +4, -1, 0, -3, 4, 0, -1, -1, +1, 2, -2, 0, 0, 1, 0, -2, +1, 2, -3, 3, -4, 4, -1, -1, +-1, 2, -1, 1, -2, 2, 1, -3, +3, -2, 2, -3, 3, -1, 0, -2, +2, 1, -2, 0, 1, 1, -1, -2, +3, -1, 0, -2, 2, 0, 2, -5, +4, -3, 4, -4, 1, 0, 1, -1, +-1, 2, -1, 0, -1, 2, -1, -1, +1, 0, 0, -2, 2, 1, -2, 0, +1, 1, -1, -3, 3, 1, -2, 0, +0, 0, 2, -3, 2, -1, 1, -2, +0, 3, -3, 2, -3, 3, 0, -2, +1, 1, -2, 2, -4, 5, -3, 0, +0, 3, -3, 1, -2, 5, -5, 2, +0, 0, 1, -4, 4, -1, 0, -1, +1, 0, 0, -1, 0, 1, 0, -1, +0, 1, 0, 0, -2, 4, -4, 3, +-4, 4, -1, -2, 3, -1, -1, 1, +-2, 5, -4, -1, 3, -1, 0, -1, +1, 2, -2, -1, 1, 2, -2, 1, +-2, 2, -1, 1, -1, 1, 1, -3, +2, 0, 0, 0, -2, 2, 1, -3, +3, -2, 3, -5, 5, -3, 3, -6, +6, -2, -1, 1, -2, 4, -2, -2, +3, -2, 2, -3, 2, 1, -2, 1, +-1, 2, 0, -1, -1, 1, 1, -1, +-1, 1, 0, -1, 1, 0, 0, -2, +2, 0, 0, -2, 1, 2, -3, 2, +-2, 4, -4, 1, 0, 3, -5, 3, +-3, 5, -3, -1, 2, -2, 3, -2, +-1, 2, -1, 0, 0, 0, 0, -1, +2, -1, 1, -3, 2, 1, -1, -1, +1, 1, -2, 0, 2, 0, -1, -3, +4, 0, -1, -1, -1, 5, -6, 5, +-5, 6, -4, 1, -1, 2, 0, -2, +1, 0, 1, -1, 0, -1, 3, -4, +2, 1, -2, 1, 0, 1, -2, 1, +-1, 4, -5, 2, -1, 4, -5, 2, +-1, 3, -2, -1, 2, 0, -1, 0, +-1, 3, -1, -2, 2, -2, 4, -3, +0, 2, -2, 1, 0, -1, 3, -5, +5, -2, 1, -2, 1, 2, -3, 2, +-2, 4, -4, 0, 2, 1, -1, -2, +2, 0, 0, -1, 0, 2, -1, -2, +2, 0, 1, -1, -1, 2, -1, 1, +-3, 5, -4, 2, -2, 2, 0, -2, +2, -1, 1, -3, 3, 0, -1, -1, +1, 3, -5, 3, -2, 3, -2, -1, +1, 1, -1, -1, 1, 0, 2, -5, +5, -4, 4, -3, 0, 1, 1, -3, +3, -2, 2, -2, 0, 1, 0, -3, +4, -1, -2, 1, 0, 1, 1, -6, +6, -2, 0, -1, 1, 1, -1, -2, +3, -1, 2, -3, 1, 0, 1, -2, +2, -2, 3, -4, 4, -3, 3, -3, +0, 3, -3, 2, -2, 2, 0, -3, +3, 1, -2, -1, 2, 0, -1, -1, +2, 0, -1, 0, 0, 2, -1, -2, +2, 0, 0, -1, 1, -1, 3, -4, +3, -2, 2, -2, 1, 0, 0, -1, +1, 0, 0, -1, 1, 1, -1, -2, +3, -1, 0, -1, 1, 1, -1, -1, +1, 2, -2, -1, 2, -1, 1, -2, +1, 1, 0, -1, 0, 0, 2, -2, +-1, 4, -5, 4, -3, 2, 1, -4, +4, -1, -1, 1, -3, 6, -6, 3, +-1, 1, 0, -3, 3, 1, -2, 0, +-1, 3, -3, 2, -3, 4, -3, 2, +-2, 2, -1, -1, 1, -1, 3, -5, +4, -2, 1, -1, 1, -1, 2, -4, +3, 1, -3, 1, -1, 3, -3, 1, +0, 1, -1, -2, 2, 1, -2, 1, +-3, 5, -4, 3, -3, 2, -1, 1, +-2, 3, -3, 2, -3, 4, -2, 0, +-1, 3, -3, 1, 1, -1, 2, -4, +3, 1, -2, 0, 0, 3, -4, 1, +1, 0, 0, -1, -1, 4, -3, 1, +-1, 2, -1, 0, -1, 2, -1, 0, +0, 0, 1, -1, 0, 1, -1, 0, +1, 0, 0, -3, 4, -1, 0, -2, +2, 1, -2, 0, 0, 3, -4, 2, +-2, 4, -3, 0, 1, -2, 4, -4, +2, 1, -3, 3, -4, 6, -4, 1, +0, -2, 4, -4, 2, 1, -2, 0, +1, 0, 0, -2, 2, 1, -2, 0, +0, 2, -3, 0, 3, -2, 1, -3, +2, 2, -3, 1, -1, 2, 0, -2, +1, 0, 1, -2, 1, -1, 2, -2, +1, 0, -1, 1, -1, 3, -2, -2, +3, -2, 3, -5, 6, -4, 2, -3, +2, 4, -7, 5, -4, 5, -4, 1, +0, 0, 2, -4, 3, -1, 1, -3, +3, -2, 3, -3, 1, 0, 1, -1, +1, -1, 1, -1, 0, 2, -3, 2, +-2, 3, -3, 1, 1, 1, -3, 0, +2, 0, 1, -4, 4, -2, 2, -3, +2, 1, -2, 0, 0, 1, 1, -3, +2, -1, 2, -1, -1, 2, -1, -1, +2, -2, 3, -4, 3, 0, -1, 0, +0, 2, -2, -2, 4, -1, 0, -2, +1, 2, -2, 1, -1, 3, -4, 1, +0, 2, -1, -2, 2, -1, 1, 0, +-2, 4, -4, 1, 1, -1, 2, -4, +3, 0, -1, 0, 1, -1, 2, -5, +5, -1, 0, -2, 1, 2, -2, 0, +2, -3, 4, -6, 5, -1, 0, -1, +1, -1, 2, -3, 3, -2, 2, -5, +6, -3, 1, -1, -1, 4, -3, 1, +-1, 1, 0, -2, 3, -2, 1, -2, +2, 0, 0, -1, 1, -1, 2, -5, +6, -3, 2, -3, 2, 0, 0, 1, +-2, 2, -2, 1, 0, 1, -1, -2, +3, 1, -3, 1, 0, 1, 0, -2, +1, 2, -3, 1, 0, 1, -1, 0, +0, 0, 0, 0, -1, 3, -3, 0, +2, -2, 4, -5, 3, -2, 2, -1, +0, 1, -1, -1, 3, -2, 1, -2, +2, -1, 1, -3, 4, -2, 0, -2, +4, 0, -2, 0, 0, 2, -2, 1, +0, 0, 0, -2, 2, 2, -2, -1, +1, -1, 2, 0, -3, 3, -1, -2, +4, -3, 2, -2, 1, 0, 0, -1, +2, 0, -2, -1, 3, 1, -2, -1, +1, 2, -3, 2, -2, 3, -3, 1, +1, 1, -2, -1, 2, -1, 2, -1, +-1, 1, -1, 1, 0, 1, -1, -1, +1, 0, 0, 0, 0, 0, 0, -3, +5, -1, -2, -1, 1, 3, -3, 0, +1, -1, 1, -2, 2, 2, -5, 3, +-2, 4, -4, 2, -2, 2, 0, -2, +2, -1, 1, -2, 1, 0, 1, -1, +0, -1, 2, -1, 0, 2, -4, 3, +-2, 4, -4, 1, 0, 1, -1, -2, +5, -3, 0, -2, 2, 2, -3, 0, +0, 1, 0, -1, 0, 1, -2, 2, +-2, 3, -2, 1, -3, 5, -5, 5, +-4, 3, -2, 0, 1, 1, -2, 1, +-1, 2, -1, -2, 4, -3, 2, -5, +7, -3, 0, -2, 2, 0, 1, -3, +3, -2, 1, -2, 3, 0, -2, 0, +0, 2, -2, 2, -2, 1, 0, -2, +4, -3, 3, -5, 4, -1, 1, -1, +-1, 2, -2, 0, 3, -1, -2, 1, +-1, 3, -2, 0, 0, 2, -4, 2, +1, 0, -1, -1, 0, 3, -3, 1, +0, -1, 2, -3, 3, -1, 0, -2, +3, -2, 2, -2, 0, 2, -2, 1, +0, 1, -1, -1, 1, 1, -1, 0, +0, 0, -1, 1, 0, 2, -3, -1, +4, -1, 0, -2, 1, 1, -1, 0, +1, 0, -1, -2, 3, 1, -3, 2, +-3, 4, -2, 0, 1, -1, 1, -2, +2, 0, 1, -3, 2, -1, 1, 0, +0, 0, 0, -1, 1, 3, -6, 4, +-1, -1, 4, -6, 5, -1, -2, 0, +2, 2, -4, 1, -1, 3, -2, 0, +1, 0, -1, 0, 0, 3, -4, 1, +1, -1, 2, -2, 0, 2, -3, 3, +-2, 3, -2, -2, 2, 0, 0, 1, +-1, 0, -1, 0, 2, 2, -6, 3, +-1, 3, -2, -2, 4, -2, 0, -2, +4, -1, -1, -1, 1, 1, -1, 1, +-1, -1, 3, -4, 5, -4, 3, -4, +3, -1, 1, 0, -1, -1, 3, -4, +5, -3, 1, -4, 5, -2, 1, -2, +1, 1, -2, 0, 3, -2, 1, -5, +6, -1, -1, -1, 1, 1, -2, 2, +-2, 2, -1, -2, 2, 0, 0, 0, +-1, -1, 4, -3, 2, -2, 1, -2, +3, 0, -1, 0, -1, 2, -1, 0, +1, 1, -3, 0, 3, 0, -2, -1, +2, 1, -2, 1, -1, 2, -2, -2, +5, -3, 2, -3, 1, 0, 2, -1, +-1, 1, -1, 1, 0, 1, -2, 2, +-2, 1, 2, -3, 2, 0, -2, 0, +3, -1, -1, -2, 3, 0, -1, 0, +-1, 3, -4, 2, 0, 3, -5, 1, +1, 1, 0, -1, 0, -1, 3, -4, +4, -2, 1, -2, 1, 0, 1, 0, +-1, -1, 2, -3, 4, -2, 1, -4, +5, -2, 1, -2, 2, -1, 0, -1, +1, 3, -5, 0, 3, 0, -2, 2, +-3, 4, -4, 2, 1, 0, -1, -2, +2, 1, -1, 1, -3, 2, 0, 0, +0, 0, 0, -2, 3, -1, 0, 0, +-1, 1, 0, -1, 2, -1, -1, -1, +2, 2, -3, -2, 4, -3, 2, -1, +-1, 5, -7, 3, 0, 2, -2, -1, +2, -2, 3, -3, 2, 0, -2, 1, +1, 0, -1, 0, -2, 3, 0, -1, +0, -1, 2, -3, 4, -1, -2, 2, +-2, 2, 0, -2, 3, -3, 2, -5, +8, -4, 1, -4, 5, -2, 1, -1, +1, 0, -1, -1, 3, 0, -2, -1, +2, 0, 1, -1, -2, 3, -2, 1, +0, 0, 1, -3, 2, -1, 3, -2, +0, -1, 1, 0, 0, 3, -6, 3, +0, 1, -1, 0, 0, 1, -3, 2, +0, 3, -5, 0, 3, -1, 1, -1, +-1, 2, -2, 3, -4, 5, -5, 2, +0, 0, 1, -1, -1, 0, 2, -2, +2, -2, 1, -1, 1, 1, -1, -1, +2, -2, 2, -3, 4, -1, -2, -1, +3, 0, -1, -1, 1, 1, -3, 4, +-4, 6, -7, 2, 2, 0, 1, -3, +0, 0, 2, 0, -1, -2, 3, -4, +5, -2, 1, -3, 2, -1, 2, 0, +-1, 0, -1, -1, 4, 0, -3, -1, +3, 0, -2, 1, 0, 1, -1, -3, +6, -2, -1, -1, 2, -2, 4, -4, +2, -1, 0, 0, 1, 1, -3, 2, +-2, 1, 2, -2, 0, 0, -1, 2, +-1, 2, -3, 0, 2, -1, 2, -4, +4, -3, 1, -1, 3, 1, -5, 0, +4, -1, 0, -1, -1, 3, -4, 4, +-3, 4, -4, 1, 0, 2, -3, 4, +-6, 4, 0, -1, 1, -1, 0, 0, +0, 2, -2, 1, -1, 0, 2, -2, +1, 2, -4, 1, 1, 2, -4, 2, +0, -1, 1, -2, 4, -1, -3, 0, +2, 3, -4, 1, -1, 0, 2, 0, +-1, 1, -2, 2, -2, 4, -3, 0, +0, -2, 5, -4, 3, -3, 1, -2, +3, 1, -3, 1, -1, 2, -1, 0, +1, 1, -5, 3, 0, 4, -6, 1, +1, 0, 1, -2, 1, 1, -2, 0, +2, -1, 1, -3, 2, -1, 2, 1, +-5, 4, -2, 1, 1, -1, 1, -4, +5, -4, 5, -4, 2, -2, 1, -1, +3, -1, -2, -2, 4, 0, -1, -1, +1, 0, 0, -1, 2, 1, -3, 0, +2, -2, 4, -4, 1, 0, -1, 3, +-3, 3, -3, 1, -1, 2, 0, 1, +-4, 3, -1, 1, 0, 0, -1, -1, +2, 0, 0, -1, 0, 0, 0, -1, +4, -3, 0, -3, 5, 0, -3, 2, +-2, 2, -1, 0, 1, 0, -1, -1, +1, 2, -2, 2, -5, 4, -1, 2, +-3, 1, 0, 0, -1, 3, -4, 4, +-5, 5, -4, 4, -4, 4, -5, 2, +1, 3, -6, 2, 1, -2, 4, -5, +4, -1, -2, 0, 3, 0, -2, -1, +2, -3, 6, -5, 2, -2, 2, -2, +3, -3, 3, -4, 2, 0, 1, 1, +-4, 3, -2, 2, 0, 0, 0, -4, +6, -4, 2, -1, 0, 1, -2, 0, +2, 1, -4, 1, 1, 1, -2, 2, +-4, 6, -6, 5, -4, 4, -4, 2, +-1, 1, 1, 0, -3, 1, 2, 0, +-1, 2, -4, 3, -2, 3, -2, 1, +-1, -1, 3, -5, 8, -6, 2, -4, +5, 0, -2, 0, -1, 3, -2, 1, +0, 0, 0, -3, 5, -2, 0, 1, +-3, 3, -1, 2, -3, 2, 0, -2, +2, -1, 2, -1, -2, 1, 1, 1, +-2, 2, -2, -1, 4, -2, 1, -2, +1, 0, 1, -1, 2, -2, -1, -1, +4, 0, -3, 1, -1, 2, -1, 2, +-3, 2, -1, -1, 2, 0, -1, 1, +-3, 2, 2, -1, -1, 0, 0, 0, +1, 0, -1, 0, 0, 1, -1, 2, +-4, 5, -4, -1, 6, -4, 1, -4, +5, -2, 2, -3, 2, -1, 1, -3, +4, -1, -1, 0, -1, 2, 0, 0, +-1, -1, 2, 0, -1, 1, -1, 1, +-2, 3, -2, 2, -3, 1, 0, 1, +-2, 4, -6, 3, 0, 1, -1, 0, +-1, 2, -2, 1, 0, 2, -4, 1, +2, -1, 2, -3, 1, 0, -1, 3, +-4, 4, -4, 3, -4, 5, -3, 3, +-5, 3, -1, 3, -3, 1, -1, 0, +1, 2, -3, 2, -3, 3, -1, 0, +0, 1, -3, 1, 2, 0, -1, -2, +2, 0, 0, -1, 1, 1, -3, 2, +0, 1, 0, -1, -1, 1, 2, -1, +0, -3, 4, -2, 1, 0, 0, 0, +-2, 2, 0, 0, 0, -1, 0, 0, +1, 2, -3, 0, 1, 0, 1, -2, +3, -3, 2, -3, 4, 0, -2, -1, +2, -2, 4, -4, 1, -1, 2, -2, +2, -3, 4, -4, 2, -2, 4, -3, +1, -2, 2, 0, 0, 0, 0, -2, +2, 1, -2, 2, -3, 2, -1, 0, +1, 2, -5, 1, 3, -3, 4, -4, +2, -1, 2, -3, 4, -3, 2, -3, +4, -4, 4, -2, -2, 1, 1, 0, +0, -1, 1, -3, 4, -3, 4, -4, +3, -4, 5, -3, 1, 2, -4, 2, +1, 1, -2, 0, 0, 1, 0, -1, +1, 0, -2, 0, 2, 0, -1, 0, +-2, 2, 2, -2, 0, 0, 0, 1, +-1, 2, -2, 2, -3, 2, 0, 2, +-4, 2, 0, -1, 1, 1, -2, 0, +1, -2, 3, -2, 0, 2, -4, 3, +0, 1, 0, -4, 5, -2, 2, -2, +1, -2, 3, -2, 0, 2, -3, 2, +-3, 3, -1, 1, -2, -1, 3, -2, +1, -1, 2, -3, 2, 0, 0, 2, +-4, 2, 0, 0, 2, -1, -2, 0, +1, 1, -2, 1, -3, 4, -5, 4, +-3, 4, -4, 1, 1, -1, 3, -3, +1, 0, 0, 3, -5, 5, -5, 4, +-2, 1, -1, 2, -6, 5, -2, 2, +-3, 1, 0, -1, 2, -1, 0, 1, +-2, 2, -1, 1, 1, -1, 0, -1, +2, 1, -3, 1, 0, 0, 0, 0, +-1, 1, 0, -2, 1, 1, -1, 1, +-3, 2, 1, 1, -3, 2, 1, -1, +1, -1, 2, -2, 1, -2, 4, -4, +3, -4, 3, -2, 1, 1, -3, 1, +0, 1, -1, 0, 1, 0, 0, -1, +2, 1, -2, 1, -1, 1, 2, -2, +0, -1, 2, -1, 0, -1, 1, -1, +-1, 0, 1, 1, -3, 1, 1, -1, +2, -1, 0, 0, 0, 2, -1, 1, +-2, 3, -4, 4, -3, 4, -6, 2, +-1, 2, -2, 0, -1, 0, 1, -1, +1, -1, 2, -3, 4, -4, 7, -5, +1, 1, -1, 5, -7, 5, -3, 0, +1, -2, 2, -1, -2, 1, 0, 0, +-1, 3, -5, 3, -1, 3, -4, 4, +-3, 4, -2, 1, 0, 1, 0, -2, +2, 0, -2, 3, -5, 2, 1, -1, +-1, -2, 3, -3, 2, -1, 1, 0, +0, -2, 5, -1, -1, 2, -2, 1, +1, 1, -3, 1, 0, -1, 2, -4, +3, -2, -1, 0, 0, 1, -1, -1, +1, 0, 1, 1, -2, 2, 0, 1, +0, 0, 2, -3, 4, -5, 6, -4, +1, -3, 4, -4, 1, 0, -2, 2, +-3, 2, -1, 2, -3, 4, -4, 4, +-1, 3, -3, 2, 0, 0, 3, -4, +3, -3, 1, 0, -2, 2, -3, 1, +-2, 1, -1, 2, -4, 2, 0, 2, +-2, 2, -1, 1, 1, 0, 2, -1, +0, 0, 1, -1, 0, 0, -2, 1, +-2, 2, -3, 1, -2, 1, -1, 2, +-3, 4, -4, 4, -1, 1, 2, -2, +2, 0, 0, 2, -2, 1, -1, 0, +0, 0, -2, 1, -3, 1, 1, -2, +0, -1, 0, 2, -2, 3, -1, 0, +2, -2, 4, -1, 0, 2, -3, 4, +-4, 4, -4, 0, 2, -4, 3, -4, +1, -1, 0, -1, 2, -3, 4, -4, +5, -4, 5, -2, 2, -1, 3, -1, +-1, 3, -2, 2, -3, 1, -1, 2, +-5, 2, -2, 1, -2, 0, 0, -1, +2, -2, 3, -2, 3, -2, 4, -3, +5, -2, 1, 0, 0, 1, -1, 1, +-3, 1, -2, 1, -3, 2, -3, 1, +-2, 1, 0, 2, -3, 2, 0, 3, +-1, 1, 1, -1, 3, -1, 2, -1, +-2, 2, -2, 2, -4, 3, -6, 4, +-4, 2, -2, -1, 2, -2, 1, 0, +1, 1, 0, 1, 1, 1, 2, -1, +1, -1, 1, 2, -4, 2, -3, 1, +-2, 0, 0, -2, -2, 1, -1, 3, +-5, 4, -2, 2, 1, 1, 0, 1, +1, 2, -2, 3, -3, 3, -3, 2, +-3, 2, -4, 2, -3, 0, -1, 0, +-2, 0, 1, -1, 2, -2, 3, 0, +1, -1, 5, -2, 2, -2, 4, -2, +0, 2, -5, 5, -6, 2, -3, 2, +-5, 4, -6, 4, -2, 1, 0, -2, +5, -2, 2, 2, -2, 3, 0, 2, +-1, 3, -4, 4, -5, 3, -2, 1, +-4, -1, 1, -2, -1, 1, -3, 3, +-3, 2, 0, 2, -1, 3, -2, 6, +-3, 5, -4, 4, -2, 4, -5, 2, +-2, 0, -2, -1, 0, -2, -1, -1, +-2, 2, 0, -1, 0, 0, 2, 2, +0, 1, 2, 1, -1, 3, -1, 3, +-5, 4, -5, 4, -4, 0, -2, -2, +1, -2, 1, -5, 3, -2, 3, -1, +0, 2, 1, 0, 5, -3, 3, 1, +-2, 5, -3, 2, -3, 1, -2, 2, +-5, 2, -5, 3, -5, 2, -1, 0, +-2, 3, -2, 5, -3, 4, 0, 1, +2, 0, 3, -1, 1, -1, 1, 0, +-3, 2, -5, 2, -3, 0, -2, 0, +-3, 2, -1, 1, 0, 1, -1, 3, +1, 0, 5, -3, 4, -2, 4, -2, +2, -2, 0, -1, -3, 2, -4, 2, +-6, 2, -2, 0, 0, -2, 4, -4, +4, -1, 4, -1, 4, -3, 6, -2, +3, 0, 0, -1, 0, 0, -2, 1, +-5, 1, -4, 3, -5, 1, -2, -1, +2, 0, 0, 1, 1, 2, 2, 2, +0, 2, 1, 1, -1, 3, -2, 1, +-4, 1, -3, 3, -6, 0, -1, -3, +2, -3, 1, -1, 1, 1, 2, 0, +3, -1, 4, -1, 4, 0, 0, 1, +-2, 2, -1, 0, -5, 2, -4, 1, +-3, -1, -2, 1, -4, 4, -2, 3, +-3, 3, 2, 1, 3, -1, 3, 1, +1, 1, 0, 0, -1, 0, -2, 0, +-3, -1, -3, -1, 0, -2, -1, -1, +1, -1, 4, -3, 4, 0, 3, 1, +2, 1, 2, 1, 0, 0, 1, 0, +-4, 2, -4, 0, -3, -1, -2, 1, +-4, 0, -1, 1, 1, 0, 3, -3, +6, 0, 2, 2, 2, -1, 3, 0, +0, 1, -3, 0, -3, 1, -3, -1, +-3, -2, -1, 0, -2, 0, 1, -2, +4, -2, 7, -3, 4, 0, 3, 3, +0, 0, 1, -1, 1, -1, -2, -1, +-3, 0, -4, 1, -4, 0, -3, 1, +0, 1, 0, 0, 2, 1, 6, -3, +6, -3, 4, 1, 1, -1, 2, -3, +-1, 1, -5, 3, -7, 0, -1, -3, +1, -4, 2, -2, 2, 0, 3, -1, +4, 0, 4, 0, 5, -2, 2, 2, +-3, 5, -5, 2, -6, 1, -3, -1, +-3, -1, -5, 4, -5, 2, 1, -2, +2, 1, 4, 0, 3, 0, 5, -1, +4, -1, 1, 2, -4, 2, -2, -2, +-2, -2, -3, -1, -1, -3, -1, 0, +-1, 1, 0, 1, 2, 1, 5, -2, +6, -2, 5, 0, 2, -2, 3, -4, +2, -5, 3, -6, -2, 0, -5, 3, +-5, -1, 0, 0, 1, 0, 4, -3, +7, -2, 7, -2, 5, -1, 2, 2, +0, -2, 2, -5, 1, -1, -4, 0, +-6, 1, -3, 1, -3, -1, 0, 2, +1, 1, 4, -1, 4, 1, 3, 3, +1, 0, 0, 2, -2, 2, -4, -1, +-4, 0, -2, -3, -2, -3, -1, 1, +-1, 0, 1, 0, 3, 1, 5, -1, +4, 0, 4, 1, 2, -1, 0, 0, +-1, -1, -3, -1, -5, 0, -3, -2, +0, -5, 3, -3, 3, -1, 3, 0, +3, 2, 3, 3, 0, 4, -2, 5, +-2, 1, -2, -2, -1, -2, -1, -4, +-3, -1, -4, 2, -4, 1, -3, 4, +-2, 4, 2, 0, 5, -1, 7, -1, +3, 2, -3, 5, -3, -1, -1, -2, +-3, 0, -5, 0, -5, 1, -4, 1, +0, -4, 6, -3, 5, 1, 2, 3, +1, 4, 2, 0, 5, -5, 3, 0, +-2, 0, -4, -2, -4, 1, -5, 0, +-4, -2, 1, -1, 2, -1, 2, 2, +3, 1, 6, -2, 5, 0, 3, 2, +-1, 1, -4, 3, -6, 3, -7, 0, +-6, 1, -4, 1, -4, 1, -2, 2, +3, -2, 7, -5, 9, -2, 8, -3, +5, -2, 4, -1, 2, -4, -1, -1, +-5, 2, -6, -1, -4, -2, 0, -2, +2, -4, 4, -2, 6, -1, 6, -2, +6, 0, 5, 1, 1, 0, -1, 2, +-3, 1, -6, 1, -7, 1, -2, -5, +2, -8, 4, -3, 4, -3, 4, 0, +4, 1, 6, -1, 5, -1, 6, -2, +3, -2, -2, 2, -4, -2, -1, -5, +-1, -4, 0, -5, 2, -4, 1, 2, +-1, 4, -1, 5, 1, 5, 2, 2, +1, 3, 1, 0, 1, -3, -2, 2, +-8, 3, -8, 2, -8, 4, -7, 3, +-3, -1, 3, 1, 3, 0, 4, 0, +7, 0, 5, -1, 2, 1, 0, 2, +-3, -1, -5, 1, -5, 0, -5, -2, +-4, 2, -5, 5, -4, 1, 3, 0, +6, 0, 5, 0, 4, 1, 5, -1, +2, -2, -2, 5, -9, 5, -11, 4, +-9, 5, -9, 2, -4, -1, 2, -2, +5, -3, 5, -1, 8, -1, 6, 0, +2, 2, 3, -1, 1, -2, -4, 3, +-8, 3, -8, 1, -7, 1, -2, -2, +0, -2, 2, 1, 5, -3, 8, -3, +8, 0, 5, 0, 1, 2, -1, 1, +-1, -2, -5, 3, -10, 5, -9, 2, +-7, 3, -5, 3, -2, 0, 3, 1, +6, -3, 10, -5, 10, -3, 7, -4, +5, -3, 1, 0, -4, -1, -6, 3, +-9, 4, -8, 0, -3, 0, 0, 0, +3, -2, 4, 3, 3, 2, 6, -3, +6, 1, 1, 2, -2, -1, -1, -1, +-2, -4, -4, -1, -5, 1, -4, -2, +-1, 0, 2, 1, 3, -2, 6, 1, +6, 1, 4, -1, 4, 0, 2, 0, +-3, 0, -6, 3, -6, -2, -3, -4, +-3, 2, -4, 2, -2, 0, 3, 1, +6, -1, 4, 2, 4, 2, 5, -3, +3, -2, 2, -1, -3, -2, -6, 1, +-4, -2, -3, -3, -3, 1, -1, 2, +-1, 1, 3, 1, 9, -5, 10, -4, +7, 0, 3, 0, -2, 1, -4, 2, +-5, -1, -7, 1, -5, -1, -2, -3, +-1, 0, 2, -1, 5, -2, 5, 3, +4, 1, 4, 0, 3, 2, -1, 2, +-5, 3, -7, 2, -5, -2, -5, -1, +-5, 2, -4, 0, -2, 3, 1, 2, +4, -1, 5, 3, 4, 1, 4, -2, +3, 2, -3, 2, -5, -1, -4, 0, +-5, -3, -2, -4, 0, -1, -1, 1, +-1, 2, 4, 1, 5, 0, 3, 5, +1, 4, 0, 0, 0, 1, -3, 1, +-7, 1, -8, 3, -6, 0, -6, 1, +-4, 3, 1, -1, 3, -1, 5, 3, +5, 0, 5, -1, 5, 0, 2, -1, +-2, -1, -3, 0, -4, -3, -4, -3, +-1, -2, -2, 0, -3, 3, 2, 1, +4, -1, 5, 3, 6, -2, 6, -2, +3, 0, 0, 0, -5, 1, -7, 2, +-5, -2, -6, 2, -7, 3, 0, -3, +3, -1, 5, 0, 8, -4, 7, 1, +4, 2, 2, -1, 0, 0, 0, -3, +-2, -3, -5, 0, -4, -3, -2, -2, +-1, -1, 4, -4, 6, -2, 5, 3, +4, 0, 4, 2, 3, 0, 2, -1, +-3, 4, -8, 3, -6, -3, -3, -1, +-4, -1, -3, 0, -1, 3, -1, 4, +0, 3, 4, 3, 5, -2, 5, 0, +2, 2, -1, -3, -1, -2, -3, 0, +-5, -4, -3, 0, -3, -1, 1, -5, +5, 0, 3, 3, 1, 2, 4, 4, +3, 1, 1, 0, 2, 0, -1, -3, +-3, -1, -5, 1, -6, 0, -6, 0, +0, -1, 3, -3, 3, 0, 7, -1, +8, -2, 3, 5, 0, 4, -2, 2, +-5, 4, -5, 1, -6, -2, -4, 0, +-2, -4, -1, -1, 0, 1, 3, -3, +7, -2, 8, -3, 11, -6, 8, -2, +4, -1, 1, -2, -3, 1, -5, -1, +-3, -4, -5, 2, -6, 3, -5, 2, +-1, 1, 7, -6, 11, -5, 8, 0, +5, -1, 3, 1, -2, 3, -4, 1, +-6, 1, -6, 0, -4, -3, -5, 3, +-4, 1, 0, -2, 5, 0, 5, -1, +8, -4, 8, 1, 2, 2, -2, 4, +-4, 4, -7, 1, -5, -1, -4, 1, +-6, 0, -4, 1, 1, -1, 4, -4, +7, -1, 8, -2, 7, -3, 6, 2, +1, 1, -1, -2, 0, -2, -2, -2, +-5, -1, -6, 3, -5, 0, -3, -1, +3, 0, 4, -1, 3, 2, 3, 5, +1, 1, 1, 1, 0, 2, -5, 2, +-8, 3, -5, -1, -4, -5, 0, -3, +3, -6, 3, -2, 4, 1, 5, -2, +8, -3, 7, 0, 5, -1, 1, -1, +2, -3, 1, -3, -5, 2, -7, 2, +-5, 0, -5, 4, -3, 2, 2, -1, +5, 0, 6, 0, 6, -1, 5, 0, +4, -2, 1, 0, -3, 2, -6, 0, +-6, 2, -9, 5, -7, 1, -3, 1, +1, 0, 3, -2, 6, 0, 6, -2, +6, -2, 3, 2, -1, 0, -3, 0, +-5, 2, -7, 0, -7, 1, -5, 2, +-4, -1, -1, 2, 1, 2, 2, 0, +5, 1, 4, 2, 2, 1, -2, 5, +-4, 3, -6, 1, -6, 4, -8, 3, +-7, 1, -4, 4, -3, 2, -1, 3, +2, 4, 3, 2, 3, 1, 5, 2, +2, 0, -2, 2, -2, 1, -4, -1, +-6, 2, -6, 2, -4, -2, -1, -1, +4, -1, 2, 0, 2, 4, 3, 0, +4, -1, 2, 1, 2, -3, -1, -1, +-5, 3, -7, -1, -5, -2, -2, -2, +0, -4, 1, 1, 0, 2, 4, -3, +7, -2, 8, -4, 9, -7, 5, 0, +0, -1, -2, -2, -2, 0, -5, 0, +-5, 2, -5, 4, -2, 0, 1, 1, +6, -2, 7, -1, 5, 2, 4, -1, +6, -5, 5, -2, 1, -3, 0, -5, +0, -1, -4, 1, -6, 3, -5, 5, +-1, -1, 3, -1, 5, 2, 3, -1, +4, 0, 2, 1, 1, -3, -1, 0, +-4, 0, -4, -3, -4, 0, -4, 0, +-3, -2, 0, 0, 4, -5, 7, -4, +5, 3, 0, 2, 2, -2, 4, -2, +2, -3, -3, 0, -3, 1, -5, -1, +-5, 2, -3, 1, 0, -1, -1, 4, +2, 2, 4, 0, 4, 1, 6, -1, +5, -4, 4, -1, 1, -2, -1, -3, +1, -5, 3, -6, 2, -4, 3, -3, +5, -3, 2, 2, 4, 1, 4, -1, +2, 4, -1, 3, 0, -1, -3, 2, +-4, 1, -5, -2, -3, -2, 0, -6, +4, -8, 5, -3, 3, -1, 2, 0, +2, 2, 3, -1, 2, -1, 2, 1, +-2, -1, -3, 0, -2, -2, -4, -1, +-4, 1, -2, -1, 1, -3, 2, 2, +2, 2, 0, 3, 2, 4, 1, 1, +1, 2, -1, 3, -2, -1, -2, 1, +-4, 2, -3, -2, 0, -2, 2, -1, +2, -1, 2, 2, 4, 0, 5, -3, +7, -1, 5, -2, 0, 1, -3, 4, +-3, -3, -2, -2, -2, 1, -5, 0, +-3, 1, -2, 2, 0, -1, 2, 1, +3, 0, 3, -1, 0, 3, -2, 3, +-3, -2, -1, -2, 0, -3, -4, 0, +-6, 3, -4, -1, 1, -3, 1, 2, +1, 1, 0, 2, 3, 2, 1, -1, +4, -1, 1, 0, 0, -2, 0, -3, +2, -5, 2, -3, -2, 3, -4, 4, +-1, 0, 3, 0, 5, -1, 4, 1, +2, 3, 1, 2, -1, 4, -5, 4, +-2, -2, -1, -1, -1, -1, -2, -2, +0, 1, -2, 2, -1, 3, -3, 6, +-1, 1, 4, -4, 7, -5, 6, -6, +4, -4, -2, 3, -7, 2, -6, 0, +-3, 0, -3, -2, 0, -2, 1, 1, +-1, 1, 0, 1, 4, -2, 3, -3, +3, 0, 0, -1, 0, -2, -2, 1, +-3, 0, -3, -2, 1, -1, 0, 0, +-1, 0, 5, -1, 4, -1, 3, 2, +4, -1, 5, -1, 0, 4, -2, 2, +0, -2, -1, 1, -1, -1, 1, -3, +1, 0, 2, -2, 6, -5, 5, 0, +4, 1, -1, 3, 0, 3, 1, -2, +0, 0, -2, 2, -4, 0, -5, 2, +-5, 1, -4, 1, -5, 3, -2, -1, +1, -2, 1, 1, 1, -2, 2, -2, +1, 0, -2, 0, -2, 0, -5, 2, +-4, 0, -4, 0, -3, 2, -4, 2, +-3, 3, -1, 1, 3, -2, 4, 1, +2, 0, 4, -1, 2, 1, 2, -1, +1, 0, -2, 6, -6, 4, -3, 3, +-1, 3, -1, 2, 2, 1, 2, 2, +4, -1, 4, 0, 4, 1, 1, 0, +1, 0, 1, -1, 0, -2, -2, 2, +-4, 1, -4, 1, -3, 1, -1, 0, +-3, 1, -1, 2, -1, 0, -3, 2, +-3, 3, -6, 3, -7, 3, -6, 1, +-4, -1, -7, 3, -5, 1, -4, -2, +0, -1, 1, -2, 2, -1, -1, 4, +0, -1, 4, -4, 6, -3, 3, 0, +0, 0, 1, 1, 1, -1, 1, -1, +5, -3, 6, -3, 5, -1, 6, -1, +8, -3, 6, -1, 9, -3, 5, 0, +2, 3, 0, 0, 2, -1, 0, -1, +4, -6, 3, -2, 0, 0, 0, -2, +1, -1, -1, 2, -2, -1, -1, 1, +-2, -1, -2, -2, -3, 1, -7, 2, +-7, 0, -7, 2, -6, -1, -5, -1, +-3, 0, -4, -1, -1, 0, -3, 3, +-3, 2, -3, 2, -1, 2, -2, 1, +-1, 1, 0, 1, 0, 0, 0, 2, +2, -1, 4, -1, 3, 3, 3, 1, +6, -1, 6, 4, 2, 4, 3, 2, +5, 1, 4, 0, 5, -1, 2, 2, +1, 1, -1, 2, 0, 2, -2, 2, +-1, 2, -2, 2, 0, -2, 1, -1, +-1, 1, -6, 4, -8, 3, -6, 0, +-7, 0, -8, 2, -7, -3, -4, -5, +-1, -4, -4, -1, -7, 3, -6, -2, +2, -6, 0, -1, -1, 0, -3, 1, +-4, 5, -7, 5, -4, 2, -3, 4, +-2, 2, 1, 1, 2, 1, 6, -2, +8, -1, 7, 2, 6, 1, 7, 3, +4, 4, 5, 0, 9, -4, 11, -5, +10, -3, 4, 0, 6, -1, 2, 1, +1, 4, -2, 3, 0, 1, 0, 0, +2, -2, -1, 0, -3, 1, -5, 0, +-6, 0, -7, -1, -6, -4, -5, -3, +-8, 1, -11, 3, -13, 5, -11, 3, +-8, -1, -5, -1, -2, -3, -4, 0, +-4, 1, -5, -1, -1, -1, -4, 3, +-4, 2, -2, 0, 3, 1, 1, 3, +1, 3, 7, 0, 9, -2, 9, 3, +7, 2, 9, 0, 9, 1, 8, 0, +10, -3, 9, -1, 8, 0, 6, -3, +10, -3, 8, -2, 6, -1, 4, 1, +3, 1, -2, 3, -2, 3, -5, 1, +-5, 0, -5, -1, -8, -1, -9, 2, +-12, 0, -11, 1, -11, 0, -9, -1, +-9, 0, -10, 2, -9, 1, -10, 2, +-9, 3, -11, 3, -9, 3, -9, 2, +-6, 1, -5, 0, 0, 0, -1, 2, +0, 4, 2, 3, 5, 2, 7, 2, +10, -1, 12, -1, 12, -1, 12, 0, +8, 4, 5, 5, 7, 0, 9, 0, +10, 0, 9, -2, 11, -1, 9, -2, +10, -2, 5, 1, 4, 0, 1, -2, +1, -1, -3, -1, -6, -1, -8, 1, +-11, 2, -15, 4, -14, 2, -12, 0, +-12, 1, -12, 3, -14, 2, -12, 0, +-8, -4, -6, -6, -5, -5, -6, -3, +-7, -3, -6, -2, -2, -3, -3, 0, +-2, 5, -3, 3, 4, 0, 8, -1, +11, -1, 10, 0, 11, 0, 12, 0, +9, 3, 8, 4, 8, 2, 10, 2, +12, -3, 17, -3, 13, 1, 12, 0, +14, -4, 13, 0, 7, 3, 1, 4, +1, 1, -1, -1, -2, 1, -9, 2, +-8, -1, -8, -2, -8, -2, -9, -2, +-10, 0, -11, -1, -9, -6, -7, -3, +-11, -2, -13, -1, -14, 1, -16, 1, +-15, -1, -11, -1, -10, -2, -7, -1, +-3, -3, 1, -4, 6, -2, 3, 1, +7, 0, 7, 0, 11, -1, 10, -1, +11, 2, 9, 1, 12, -2, 15, -1, +16, -2, 16, 0, 16, 0, 18, -1, +17, -1, 16, 1, 14, -2, 13, -3, +12, -3, 7, -4, 5, -2, -1, -1, +-3, -1, -6, -1, -6, 1, -12, 1, +-8, -1, -9, -2, -10, -1, -13, 1, +-14, -1, -17, 1, -19, 2, -19, -1, +-18, -1, -17, 0, -15, -2, -12, -1, +-10, 0, -6, -2, -1, -3, 2, -2, +5, -3, 5, -1, 8, -2, 8, -3, +12, -2, 9, -1, 14, -4, 15, -2, +18, -3, 19, -3, 22, -2, 22, -3, +23, -2, 21, 1, 16, 1, 15, 3, +9, 3, 8, 0, 8, -2, 4, 0, +0, 1, -2, -1, 0, -4, -1, -3, +-3, 0, -10, 2, -10, 2, -15, 3, +-15, 0, -18, 1, -20, 3, -25, 3, +-25, 3, -23, 0, -19, -3, -16, 0, +-17, 3, -16, 4, -14, 5, -8, 0, +-2, -3, 1, 0, 0, 0, 0, 1, +4, 0, 4, 0, 8, 0, 9, 1, +13, 2, 12, 2, 20, 0, 20, 1, +22, 1, 23, -2, 25, -2, 21, -1, +19, -2, 16, 0, 10, 1, 9, 0, +5, 1, 3, 3, 1, 0, 1, 0, +1, -1, -1, -2, -3, -1, -9, 1, +-11, -1, -15, -1, -17, 0, -23, 1, +-23, 1, -25, 0, -22, -1, -21, -1, +-17, -3, -14, -1, -15, 2, -13, 2, +-11, 0, -8, 2, -7, -1, -4, 1, +-5, 3, -4, 2, 2, -1, 7, -1, +10, 1, 11, 2, 19, -3, 23, -3, +26, 0, 22, 0, 26, -3, 25, -2, +23, -1, 17, 1, 16, 0, 14, 0, +10, 3, 8, 3, 7, 0, 9, 0, +6, 0, 5, -2, 3, -3, 1, -3, +-6, 0, -14, 4, -19, 1, -19, -3, +-18, -1, -26, 3, -26, 3, -27, 3, +-22, 1, -23, 3, -19, 3, -19, 1, +-15, 0, -12, -1, -12, 0, -14, 5, +-15, 4, -9, 0, -3, -2, 2, -1, +5, -1, 11, -2, 17, -2, 17, 2, +19, 3, 20, 0, 25, -1, 22, 1, +22, 1, 17, 1, 21, -2, 19, -3, +20, -2, 17, -1, 16, 1, 13, 1, +13, -2, 15, -3, 8, 0, 3, 1, +-2, -2, -3, -3, -9, -3, -14, -1, +-17, -2, -20, -1, -21, 0, -23, 1, +-21, 0, -21, -2, -14, -5, -16, -3, +-16, 0, -20, 1, -19, 2, -20, 1, +-16, -2, -11, -3, -8, -3, -4, -1, +-3, 2, 2, 2, 7, 0, 13, 1, +15, 3, 15, 4, 16, 4, 18, 1, +20, 2, 15, 5, 17, 2, 17, 0, +22, -1, 21, -3, 24, -2, 20, 2, +18, 1, 15, 2, 13, 2, 7, 3, +2, 2, -2, 3, -9, 1, -9, -1, +-13, -1, -16, 0, -18, 1, -20, 2, +-21, 1, -18, -2, -16, -2, -19, -2, +-17, -2, -21, -1, -21, 1, -26, 2, +-21, -1, -20, -1, -16, 0, -13, -1, +-7, -1, -2, 0, 2, 0, 6, 3, +7, 3, 11, 3, 12, 2, 16, 0, +17, -1, 18, -1, 20, -2, 20, -1, +22, -1, 22, -1, 25, 1, 22, 1, +24, 1, 20, 2, 21, -1, 15, 1, +11, 1, 4, 1, 1, -1, -2, -1, +-8, 0, -10, 1, -13, 0, -13, 0, +-14, -1, -14, 1, -19, 2, -19, 0, +-19, -1, -22, -1, -23, 0, -26, -1, +-22, -3, -24, -1, -20, 0, -19, -2, +-11, -1, -8, -3, 0, -3, 2, -1, +4, 2, 3, 4, 4, 3, 11, -2, +11, 0, 13, 2, 12, 0, 17, 0, +19, 0, 23, -2, 26, -2, 28, -2, +30, -3, 26, 0, 25, 1, 17, 1, +18, -2, 14, -5, 13, -3, 2, 2, +-2, 1, -4, 1, -6, 0, -6, 0, +-9, 1, -11, 3, -14, -1, -13, 0, +-19, 3, -24, 3, -27, 2, -26, -1, +-24, -4, -23, -4, -20, -3, -22, 0, +-17, 1, -17, 1, -9, 2, -11, 5, +-6, 3, -3, -1, 6, -5, 8, -5, +8, -3, 10, -3, 11, -3, 15, 0, +14, 1, 19, 1, 21, 1, 25, 0, +27, -1, 28, -1, 27, -2, 24, -1, +21, 1, 13, 1, 13, -1, 9, -1, +8, 0, 0, 4, -1, 3, -1, -2, +4, -6, 2, -3, -5, 1, -12, 4, +-17, 2, -18, 1, -23, 1, -23, -1, +-25, -3, -23, -2, -23, -2, -23, 0, +-20, 1, -20, 3, -16, 3, -15, 2, +-9, 2, -11, 2, -5, 1, -6, 0, +-1, -1, 1, -1, 3, -1, 8, -2, +14, -5, 19, -3, 22, -4, 27, -4, +27, -2, 26, 2, 23, 0, 23, 1, +19, 3, 14, 2, 15, -1, 14, -3, +16, -4, 11, -1, 10, 0, 5, 2, +5, 2, 0, 1, 2, -1, -4, 0, +-7, -1, -11, -1, -16, 0, -19, -1, +-22, -2, -20, -3, -21, -4, -19, -1, +-21, 1, -20, 3, -19, 3, -16, 0, +-11, -2, -11, -1, -8, -2, -11, -1, +-5, -3, -4, -6, 3, -3, 0, 1, +5, 0, 10, -2, 17, -2, 18, 0, +19, 1, 22, 0, 21, -1, 23, -1, +20, -1, 20, -2, 18, -3, 19, -3, +16, -1, 13, 2, 12, 1, 10, 2, +10, 3, 6, 1, 9, -2, 3, -2, +2, -2, -7, -1, -10, 0, -16, 1, +-18, -1, -17, -3, -17, -3, -17, 0, +-19, 1, -19, 3, -18, -1, -11, -5, +-12, -3, -13, -1, -13, -2, -15, 2, +-16, 4, -16, 1, -7, -2, -4, -4, +6, -4, 3, 2, 7, 3, 8, 1, +16, 1, 15, 0, 18, -1, 18, 0, +16, -1, 18, -2, 15, -1, 17, -1, +16, -2, 19, -2, 19, -4, 20, -2, +16, 1, 12, 0, 13, -2, 8, -1, +6, -2, -2, 0, -4, 0, -10, -1, +-9, 0, -16, 2, -15, -1, -14, -1, +-14, 1, -17, 4, -18, 4, -16, 1, +-17, 0, -14, 0, -19, 2, -19, 2, +-19, 1, -16, 1, -15, 2, -12, 3, +-8, 4, -6, 4, 2, 1, 4, 1, +9, 2, 5, 5, 8, 4, 7, 4, +10, 2, 10, 2, 11, 3, 10, 3, +12, 1, 17, 0, 16, -2, 21, -2, +18, 0, 15, 3, 11, 3, 9, 4, +3, 5, -3, 4, -1, -1, -4, -1, +-5, 1, -10, 1, -7, 0, -11, 0, +-7, -2, -8, -3, -6, -4, -10, -1, +-13, -2, -13, -4, -13, -3, -16, 0, +-17, -1, -14, -1, -17, 2, -13, 0, +-8, -2, -4, 0, -2, 0, 1, 0, +5, -1, 5, -1, 9, -1, 6, 0, +8, 0, 5, 1, 10, -3, 13, -5, +18, -4, 17, -1, 18, -2, 19, 0, +18, -1, 17, 0, 14, 0, 13, 0, +9, -1, 9, -2, 5, -2, 2, 0, +1, -2, -1, 0, -4, 2, -6, -2, +0, -5, -3, -3, -3, 0, -10, 2, +-11, 1, -12, -3, -12, -3, -15, -2, +-14, -3, -15, -1, -15, -1, -10, -4, +-7, -3, -3, 0, -6, 2, -5, 4, +-6, 4, -5, 4, -5, 5, -4, 5, +-1, 4, -1, 2, 6, 1, 4, 1, +9, 2, 7, 4, 9, 4, 11, 1, +17, -2, 17, 0, 15, 0, 15, -2, +13, -2, 9, 3, 0, 3, 1, 1, +2, -2, 4, 0, 1, 2, 0, 2, +0, 0, -1, -1, 0, -3, -3, -4, +-2, -4, -9, -2, -10, 0, -16, 1, +-12, 0, -14, 1, -14, 2, -14, -1, +-11, -1, -8, -1, -6, -3, 0, -3, +-1, -2, -1, -1, -4, 1, -1, -2, +0, -4, 1, -1, 0, 0, -1, 2, +5, 2, 6, 1, 12, 2, 10, 1, +15, -2, 13, -3, 16, -4, 13, -4, +12, -1, 8, 2, 5, 3, 4, 3, +4, -1, 8, -3, 6, -3, 7, -2, +4, -3, 4, 0, 0, 2, -4, 5, +-5, 4, -9, 2, -8, -1, -11, -4, +-8, -3, -11, -3, -6, -4, -6, -3, +-5, -1, -7, 1, -6, 0, -5, -2, +-2, -7, 0, -6, -5, -2, -5, 0, +-5, 2, -4, 4, -4, 1, 1, -2, +4, -3, 5, -2, 8, -3, 11, -5, +15, -4, 11, 2, 9, 4, 5, 3, +9, -1, 7, -2, 7, -2, 4, -1, +7, -3, 9, -3, 11, -2, 11, -1, +8, 0, 8, -3, 5, -5, 5, -4, +0, -4, 0, -2, -3, -1, -4, -2, +-4, 0, -9, 3, -8, 2, -10, 0, +-7, -1, -9, -1, -6, 1, -9, 6, +-7, 4, -9, 6, -10, 4, -12, 3, +-11, 1, -7, -2, -3, -5, 1, -2, +0, 1, 1, 4, 2, 4, 6, 0, +8, -4, 7, -3, 7, -4, 5, -3, +9, -2, 7, -1, 8, 2, 4, 4, +4, 3, 2, 1, 7, -2, 5, -2, +6, 1, 4, 4, 1, 5, 3, 2, +4, -3, 4, 0, -4, 0, -3, -4, +-5, -4, -4, -2, -2, -2, -2, 2, +-1, 3, -4, 1, -4, 1, -7, -2, +-4, -3, -7, -1, -6, -3, -6, -1, +-6, 4, -8, 5, -5, 2, -3, 1, +-4, -2, -2, -3, 0, -3, 4, -2, +4, 3, 3, 3, 4, -1, 8, -3, +6, -4, 6, -7, 8, -9, 8, -7, +7, 0, 2, 5, 7, 4, 5, 4, +7, 4, 3, -1, 6, -4, 4, -5, +5, -8, 6, -4, 3, 1, 1, 4, +-1, 1, 3, -4, 1, -6, 2, -5, +1, -6, -1, -2, -2, 1, -4, 4, +-6, 7, -7, 7, -5, 0, -8, 0, +-8, -3, -10, -3, -5, 0, -6, 5, +-4, 6, -5, 8, -4, 6, -3, 2, +0, -2, 2, -6, 0, -5, 0, 0, +-3, 3, -1, 8, -1, 6, 3, 1, +5, -3, 5, -5, 7, -6, 3, -2, +6, -1, 4, 3, 4, 9, -2, 8, +3, 2, 2, -3, 4, -8, 4, -8, +2, -4, 0, 1, -1, 1, 4, 3, +2, 5, -1, 7, -4, 3, -6, -3, +-5, -3, -7, 0, -7, 4, -7, 7, +-5, 4, -3, 0, 1, -2, -1, -4, +1, -7, 0, -8, 2, -7, -1, 0, +-1, 6, -2, 8, -2, 7, -3, 1, +-1, -7, 2, -7, -1, -5, 1, -3, +2, -1, 6, 2, 4, 6, 2, 7, +4, 0, 5, -7, 6, -7, 2, -6, +3, -3, 1, 1, 4, 4, 1, 5, +4, 4, 2, 0, 0, -3, 2, -8, +3, -9, 4, -1, 1, 5, -1, 7, +-1, 5, 1, -1, 1, -3, -2, -2, +-5, -4, -6, -4, -6, 1, -5, 6, +-4, 10, -2, 9, -1, 3, -3, -3, +0, -8, -2, -8, 0, -4, -4, 2, +-4, 5, -5, 10, -5, 9, -2, 4, +0, -2, 2, -7, 0, -9, 3, -4, +0, 2, 1, 7, 1, 9, 0, 8, +-1, 5, -3, 0, -1, -6, -2, -5, +1, -4, 2, 0, 5, 5, 4, 6, +5, 1, 7, -4, 9, -10, 6, -11, +4, -9, 0, -7, 1, -2, 4, 4, +2, 7, 2, 5, 0, -3, 1, -8, +-1, -8, 0, -6, 1, -4, 0, 3, +-2, 8, -7, 10, -3, 8, -3, 0, +0, -8, -3, -9, -2, -8, -5, 1, +-2, 6, 1, 8, -1, 10, -2, 7, +-2, -3, 2, -8, 3, -12, 4, -10, +2, -2, 0, 5, 1, 8, -1, 11, +1, 4, 1, -2, 1, -4, 0, -8, +2, -8, 3, -1, 3, 5, 2, 10, +4, 8, 1, 0, 2, -5, 0, -10, +2, -10, 2, -3, 0, 0, 2, 4, +-2, 12, -4, 13, -3, 4, 2, -3, +-3, -8, -6, -8, -4, -5, -2, 2, +1, 7, 1, 5, 5, 0, -3, 3, +-4, -3, -2, -10, 3, -11, 2, -6, +-3, 4, -5, 13, -3, 10, 2, 3, +4, -2, 1, -10, 2, -13, 1, -9, +2, -5, 2, 4, 2, 12, -1, 14, +-5, 13, -4, 4, -2, -8, 2, -10, +4, -8, 1, -3, 2, 7, -3, 10, +1, 10, 1, 8, 2, 1, -2, -6, +-3, -9, -2, -7, -3, 2, 2, 9, +0, 10, -1, 9, -2, 1, -1, -5, +-1, -5, -3, -7, -2, -7, -5, 0, +-2, 5, -1, 10, 1, 12, -2, 6, +-6, -2, -7, -7, -6, -10, -2, -6, +3, -2, 3, 4, 2, 9, -2, 9, +0, 1, 0, -4, 2, -12, 3, -12, +1, -5, 1, 3, -2, 9, 3, 11, +4, 5, 4, 2, 1, -4, -2, -13, +4, -13, 3, -5, 6, 3, 4, 9, +5, 9, 1, 4, 0, -1, 4, -7, +1, -10, 1, -7, -3, -7, 1, 0, +1, 11, 0, 14, 2, 5, 1, -4, +0, -14, -4, -12, 0, -8, 0, -1, +-2, 8, -4, 11, -5, 8, -3, 7, +-1, -2, 2, -13, 4, -16, 0, -13, +1, -3, -2, 10, 0, 12, 1, 11, +0, 5, 0, -6, 0, -12, 3, -13, +4, -13, 8, -1, 3, 9, 1, 10, +3, 9, 1, 2, 8, -10, 7, -12, +6, -11, -3, -5, -2, 2, 1, 9, +1, 16, 0, 17, -4, 4, -4, -6, +-3, -13, 3, -15, 7, -8, 6, 0, +3, 4, -5, 13, -4, 9, -2, 3, +-1, -3, -2, -14, -3, -16, -3, -5, +-3, 3, 2, 10, 4, 10, 1, 1, +2, -4, -5, -7, 0, -13, 1, -10, +2, -2, -4, 7, -6, 14, 0, 10, +4, 1, 9, -3, 3, -9, 0, -9, +-3, -6, -2, -3, 6, 4, 5, 12, +7, 10, 1, 7, -1, -1, -2, -13, +5, -15, 8, -8, 3, 0, 0, 9, +-2, 9, 2, 7, 4, 6, 3, -2, +2, -13, -3, -14, -3, -12, -2, 0, +1, 13, -2, 17, -7, 11, -5, 3, +-7, -7, -2, -9, 2, -12, 3, -11, +0, -1, -7, 10, -4, 13, -2, 10, +6, -1, 2, -10, -2, -11, -5, -10, +-4, -4, 4, 3, 5, 7, 6, 12, +-2, 12, -3, 2, 2, -10, 7, -16, +10, -14, 1, -1, 0, 6, -3, 10, +2, 11, 9, 3, 9, -1, 2, -2, +-6, -11, -2, -12, 1, -2, 2, 7, +5, 12, -1, 11, -1, 2, -6, -2, +-1, -7, 1, -11, 0, -8, -4, 0, +-12, 7, -7, 17, -3, 13, 2, 7, +-1, -2, -8, -11, -7, -13, -7, -6, +3, -1, 0, 7, 0, 13, -7, 10, +-5, 6, 1, -2, 3, -13, 7, -13, +2, -10, -1, 1, -4, 13, 0, 13, +7, 8, 2, 8, 1, -4, -3, -12, +3, -13, 6, -11, 9, 0, 7, 13, +-1, 13, -2, 12, -4, 5, 0, -5, +4, -9, 2, -10, -1, -7, -9, 4, +-3, 10, 0, 12, 3, 12, 2, -1, +-4, -13, -3, -13, -3, -13, 4, -5, +4, 2, 0, 6, -8, 13, -14, 13, +-4, 2, -2, -5, 3, -13, -3, -15, +-4, -3, -5, 7, 1, 11, 6, 13, +2, 6, -3, 2, -9, -3, -2, -13, +7, -12, 7, -4, 7, 3, -3, 15, +-2, 13, 3, 0, 12, -6, 11, -9, +3, -11, 1, -7, -2, -2, 2, 5, +5, 11, 7, 9, 4, 3, -3, -5, +0, -15, -1, -12, 5, -5, 2, 2, +-4, 9, -7, 12, -8, 7, 0, 7, +-1, 0, -1, -9, -8, -12, -9, -10, +-4, -1, -4, 14, 1, 15, -6, 11, +-7, 4, -7, -8, -1, -11, 7, -11, +7, -12, 6, -2, -4, 8, -4, 12, +0, 9, 7, 0, 10, -11, 2, -12, +3, -12, 1, -7, 7, 2, 11, 5, +10, 9, 3, 12, -4, 1, 1, -8, +5, -13, 10, -14, 7, -3, -2, 5, +-1, 5, -2, 9, 5, 6, 5, -1, +3, -3, -7, -8, -9, -12, -2, -4, +1, 4, 3, 11, -4, 11, -6, 0, +-7, -5, -5, -5, 2, -10, -1, -7, +0, -3, -9, 2, -7, 12, -1, 12, +5, 1, 8, -4, -3, -10, -5, -12, +-4, -6, 3, 0, 7, 5, 2, 12, +-1, 10, -5, 6, 3, -1, 8, -12, +12, -12, 6, -3, -4, 1, -1, 8, +1, 9, 9, 5, 7, 4, 3, -1, +-3, -7, -8, -6, 3, -10, 6, -3, +9, 10, -3, 12, -6, 8, -7, 5, +-5, -5, 3, -7, -2, -5, -6, -6, +-11, 0, -9, 8, -3, 11, -2, 12, +3, 0, -5, -10, -6, -9, -7, -7, +-1, -2, 2, 6, -1, 4, -3, 5, +-7, 8, -1, 1, 4, -3, 4, -6, +2, -12, -2, -5, 2, 3, 3, 6, +14, 5, 12, 3, 4, -1, -1, -2, +-4, -7, 5, -8, 7, -4, 8, 2, +2, 8, -4, 13, -1, 6, 1, -1, +11, -7, 3, -8, -3, -3, -9, -1, +-5, 1, 1, 9, 1, 10, 1, 4, +-8, -2, -6, -11, -3, -12, -2, -2, +2, 0, -6, 5, -7, 9, -11, 5, +-1, 2, 6, -2, 4, -11, 0, -10, +-9, -9, -3, -5, 3, 3, 9, 8, +6, 7, -6, 8, -3, -2, -2, -7, +8, -6, 9, -9, 9, -5, 3, 5, +-3, 9, 2, 10, 4, 4, 12, -8, +8, -10, 1, -5, -2, -6, 2, -2, +12, 3, 5, 8, 2, 11, -7, 6, +-6, -5, 0, -9, 4, -11, 4, -5, +-4, 2, -6, 3, -8, 6, -2, 7, +4, 0, 1, -4, -1, -9, -10, -10, +-8, -3, -4, 2, 4, 3, 3, 7, +-6, 3, -5, -2, -6, 0, 0, -2, +1, -4, -1, -2, -1, -3, -3, 4, +6, 9, 7, 5, 9, 1, 2, -4, +-1, -11, 1, -6, 2, -1, 10, 0, +8, 4, 6, 8, -1, 5, 1, 1, +10, -9, 9, -11, 8, -4, -6, 2, +-8, 7, -8, 11, -1, 6, 5, 3, +2, 0, -1, -8, -6, -11, -1, -10, +2, -6, 1, 7, -3, 11, -12, 8, +-9, 5, -6, -4, 4, -9, 3, -5, +-5, -7, -7, -4, -9, 3, -1, 8, +2, 10, 4, 7, -2, 0, -10, -1, +-5, -4, -2, -3, 7, 2, 3, 3, +2, 3, -1, 7, 2, 3, 9, -2, +8, -5, 9, -10, 0, -6, -1, 1, +5, 1, 9, 4, 12, 6, 2, 2, +1, -2, -5, -3, -3, -7, 3, -7, +5, -3, 2, 4, -7, 9, -5, 6, +-2, 0, 2, 1, -1, -3, -10, -4, +-8, -5, -9, -6, 2, 0, 3, 8, +0, 6, -4, 2, -9, -4, -4, -9, +-1, -8, 9, -6, 4, -3, -3, 5, +-3, 6, -4, 7, 6, 6, 4, -2, +2, -5, -7, -3, -6, -3, 2, 3, +7, 7, 12, 4, 6, 3, 2, 2, +1, -5, 5, -7, 12, -11, 9, -11, +6, 2, -6, 10, -6, 13, -4, 14, +-1, 3, 2, -4, -4, -4, -7, -6, +-5, -6, 3, 0, 4, 4, -2, 10, +-6, 9, -12, -2, -2, -8, -1, -8, +1, -7, -4, 0, -8, 2, -7, 5, +-6, 10, 3, 6, 2, 0, 0, -3, +-7, -9, -7, -7, 1, 0, 1, 6, +5, 8, -1, 8, -2, 3, -2, 3, +3, -3, 9, -9, 8, -9, 5, -4, +-3, 6, -2, 14, 4, 9, 8, 1, +9, -3, -1, -7, -3, -4, -5, 0, +1, 0, 2, 7, -2, 10, -3, 8, +-6, 6, -2, 1, -2, -6, -1, -6, +-3, -5, -10, -1, -4, 3, -3, 4, +3, 8, -5, 10, -7, 0, -9, -6, +-9, -7, -2, -5, -3, 4, 0, 8, +-4, 6, -5, 7, -2, 2, -1, -2, +5, -3, -1, -7, -1, -8, -2, 0, +3, 4, 8, 8, 8, 9, 6, 0, +0, -5, 1, -7, 3, -9, 5, -2, +5, 5, -2, 6, -1, 12, -4, 10, +2, 2, 5, -3, 3, -8, -1, -7, +-6, -2, -2, 2, -2, 7, 1, 11, +-2, 8, -7, 4, -7, -3, -7, -12, +2, -10, -2, -3, 0, 2, -5, 8, +-6, 8, -2, 2, -1, 1, 2, -3, +-4, -8, -5, -6, -5, -7, -1, -1, +7, 8, 3, 9, 4, 4, -1, -1, +0, -8, 0, -8, 7, -7, 9, -4, +0, 5, 0, 10, -3, 11, -1, 12, +4, 1, 5, -11, 7, -13, 1, -11, +5, -3, 2, 7, 6, 8, 5, 6, +0, 5, -2, -1, -5, -6, 0, -7, +0, -9, 0, -1, -3, 6, -8, 10, +-4, 11, -5, 6, -1, 0, -7, -3, +-6, -10, -6, -9, -2, -3, 4, 2, +1, 10, -1, 10, -5, 0, -3, -6, +-1, -6, -2, -5, 0, -1, -3, 2, +0, 3, -1, 10, 3, 9, 6, 3, +4, -4, 3, -11, -1, -13, 3, -5, +5, 2, 6, 8, 6, 11, -1, 6, +1, 4, -4, 0, 3, -7, 2, -7, +-1, -1, -3, 0, -2, 8, 1, 11, +0, 5, 4, 1, -2, -6, -6, -10, +-3, -9, -2, -5, 1, 4, -4, 12, +0, 7, -6, 7, -7, 3, -4, -9, +0, -12, 3, -9, -4, -3, -6, 5, +-4, 9, 1, 7, 7, 4, 4, -3, +2, -10, -2, -13, 3, -11, 3, 1, +1, 10, 1, 11, -2, 9, 1, 4, +2, -4, 7, -6, 3, -5, -3, -6, +0, 1, -2, 6, 5, 10, 4, 12, +3, 6, -2, -4, -3, -7, -1, -12, +1, -10, 6, 0, -1, 8, -5, 13, +-5, 11, -2, 1, 3, -8, 2, -12, +2, -12, -7, -3, -7, 2, -3, 5, +-1, 10, 1, 8, -2, 2, -3, -4, +-4, -12, 0, -14, 4, -7, 3, 0, +3, 10, -5, 13, 0, 6, 0, 1, +3, -3, 1, -11, 1, -11, 4, -7, +0, -1, 7, 9, 8, 8, 8, 2, +8, -2, 2, -9, 3, -12, 3, -10, +6, -2, -3, 7, -3, 13, -1, 9, +0, 7, 2, 0, 1, -9, 0, -12, +-1, -9, -1, -5, 0, 6, -2, 11, +0, 10, -3, 5, 1, -6, -1, -12, +-2, -12, -1, -11, -2, -1, -2, 10, +-7, 14, -4, 12, -2, 6, -1, -6, +4, -9, -1, -11, -1, -8, -3, -1, +2, 7, 1, 11, 1, 14, 2, 3, +0, -6, 2, -8, 0, -11, 4, -7, +5, 0, 4, 7, 1, 13, -2, 12, +4, 2, 1, -5, 4, -14, 5, -18, +3, -7, 1, 0, 3, 7, 3, 13, +-1, 10, 0, 0, 0, -7, 0, -17, +5, -16, 1, -7, 1, 1, -4, 11, +-4, 14, -5, 7, -1, -1, 1, -7, +-2, -13, 0, -11, -2, -5, -2, 3, +1, 12, 2, 8, 5, 5, -2, -1, +0, -9, -2, -15, 4, -8, 3, -4, +1, 5, 3, 9, 3, 8, 7, 5, +6, -4, 7, -12, 4, -14, -2, -7, +-1, 1, -4, 14, -2, 17, -2, 11, +3, 2, 4, -9, 3, -11, 3, -11, +0, -8, 1, -3, 2, 6, -1, 10, +-2, 15, -3, 5, 0, -6, -4, -11, +-2, -12, -6, -7, -5, 4, -1, 10, +-1, 10, 0, 13, -4, 4, -6, -2, +-6, -6, -3, -11, 0, -7, -3, 1, +1, 9, -3, 13, 1, 11, 5, -3, +6, -8, 0, -12, -2, -11, 2, -4, +2, 5, 4, 11, 2, 14, -1, 8, +0, 2, -2, -4, 3, -15, 3, -13, +4, -6, -1, 3, 0, 14, 3, 14, +2, 7, 2, -2, 0, -10, -1, -17, +0, -9, -1, -2, -2, 9, -7, 13, +-2, 13, -4, 5, 0, -3, 3, -15, +4, -18, 0, -10, -3, -3, -1, 8, +-1, 12, 2, 10, 1, 5, -3, -5, +0, -14, 0, -15, 3, -10, 2, -2, +2, 12, -2, 13, -1, 14, 2, 6, +2, -6, 5, -14, 2, -11, -1, -11, +2, 0, 2, 12, 3, 13, 0, 12, +3, 3, -2, -7, -1, -10, 1, -10, +2, -9, 3, 2, 0, 9, 1, 11, +0, 11, 1, 1, -1, -5, -8, -11, +-4, -11, -5, -6, -1, 7, -1, 11, +0, 16, -5, 11, -6, 3, -4, -4, +-7, -10, -3, -10, -3, -3, -4, 6, +-2, 11, 1, 14, 3, 4, 2, -3, +3, -9, -3, -13, -2, -9, 3, -3, +2, 8, 0, 15, 0, 16, 1, 3, +2, -3, 3, -14, 4, -15, 0, -11, +5, -3, 2, 6, 3, 14, 3, 12, +4, 4, 2, -4, -1, -13, 0, -13, +-3, -9, 1, -2, 2, 8, 1, 11, +1, 10, -1, 4, 0, -8, 1, -19, +5, -14, -3, -8, -4, 5, -2, 12, +-2, 14, -1, 10, -1, 3, -1, -10, +-1, -15, -1, -11, -2, -6, -5, 7, +1, 14, -1, 16, 0, 13, -1, 3, +-1, -9, 0, -15, 2, -13, 5, -9, +3, 4, 3, 11, -1, 19, -5, 13, +1, 2, 1, -10, 2, -14, -1, -14, +3, -4, 2, 6, 3, 13, 4, 15, +-2, 5, 0, -6, 1, -14, 3, -19, +5, -16, 4, -4, 1, 6, -4, 13, +1, 16, 0, 4, 1, -3, -1, -12, +-5, -15, -6, -11, -1, 1, 1, 9, +-2, 19, -4, 16, -6, 7, -8, -3, +2, -16, 5, -16, 4, -8, -2, 3, +-4, 13, -4, 18, 0, 13, 6, 4, +0, -6, -2, -16, -2, -15, 2, -12, +9, 0, 10, 10, 6, 15, -2, 6, +3, 0, 3, -11, 4, -15, 6, -13, +-1, -6, -7, 5, -3, 13, 2, 15, +4, 7, 7, -4, 3, -15, -9, -12, +-5, -10, 1, -6, 5, 8, 1, 13, +-5, 17, -11, 12, -8, 2, 1, -12, +0, -11, -4, -12, -4, -3, -6, 9, +0, 15, 5, 14, 8, 5, 0, -7, +-1, -14, -5, -14, 0, -11, 6, 2, +3, 10, -3, 16, -6, 18, -4, 6, +2, -4, 6, -12, 5, -15, -3, -13, +0, 3, -1, 10, 3, 20, 4, 14, +0, 5, -8, -5, -8, -14, 2, -18, +6, -9, 5, 3, 1, 12, -8, 20, +-7, 14, -1, 2, 6, -12, 5, -21, +2, -17, -7, -5, -8, 8, 0, 13, +4, 14, 5, 3, 1, 0, -5, -13, +0, -18, 5, -15, 6, -5, 2, 1, +4, 13, -3, 16, -3, 10, 2, 1, +1, -10, -2, -16, 0, -15, 3, -6, +1, 9, 5, 16, 7, 13, 1, 7, +0, -2, -3, -12, -3, -11, 1, -12, +4, 0, -1, 9, -2, 15, 2, 11, +0, 6, 4, -9, 5, -16, -1, -14, +-2, -14, 2, -2, 3, 11, -2, 17, +0, 15, -3, 4, -4, -11, 0, -17, +1, -18, 2, -12, 3, 5, 0, 11, +-3, 16, 0, 9, 3, 1, 1, -12, +5, -14, 0, -16, -4, -5, -3, 4, +3, 10, 5, 15, 5, 10, 2, 1, +-6, -6, -7, -12, 1, -14, 6, -5, +7, 5, 2, 12, -1, 17, -5, 8, +3, -1, 6, -14, 3, -16, -1, -13, +-7, 1, -4, 6, 4, 17, 7, 14, +3, 5, -3, -4, -5, -13, -6, -17, +4, -10, 5, -1, -2, 10, -7, 18, +-7, 12, -1, 2, 9, -9, 10, -18, +-1, -15, -7, -10, -4, 1, -2, 13, +5, 19, 6, 10, -1, 5, -10, -8, +-4, -15, 2, -15, 9, -10, 9, 1, +-2, 13, -7, 14, 1, 10, 7, 4, +8, -10, 4, -15, -4, -14, -10, -8, +1, 6, 8, 13, 8, 15, 2, 10, +-6, -1, -5, -18, 7, -18, 13, -16, +4, 0, -7, 10, -9, 15, -8, 14, +2, 12, 6, -3, 4, -13, -6, -16, +-8, -15, -4, -4, 6, 6, 12, 12, +4, 13, -5, 7, -10, 0, -9, -7, +2, -14, 7, -14, 3, 2, -10, 8, +-7, 19, -3, 18, 3, 8, 6, -5, +-1, -9, -12, -13, -7, -8, 7, -2, +12, 7, 8, 15, 3, 9, -6, 0, +0, -9, 7, -18, 10, -17, 4, -7, +-3, 4, -7, 11, -2, 18, 5, 14, +1, 7, -3, -8, -4, -16, -6, -16, +-1, -5, 4, 2, 7, 13, -3, 15, +-6, 11, -7, 2, -3, -10, 4, -16, +4, -14, 0, -7, -3, 6, -5, 20, +-6, 18, 1, 8, 6, -3, -3, -14, +-3, -13, -3, -12, 0, -1, 3, 8, +5, 16, 0, 12, -2, 8, 1, -6, +4, -16, 5, -15, 5, -10, -3, 1, +-3, 12, -3, 16, -1, 18, -4, 11, +2, -6, 0, -15, -1, -16, 1, -12, +2, 2, 3, 10, 1, 19, -5, 15, +-7, 5, -5, -9, 1, -13, 2, -19, +6, -9, 0, 3, -5, 12, -6, 16, +2, 10, 4, -2, 4, -10, 2, -17, +-3, -18, -3, -5, 2, 6, 2, 13, +4, 15, -2, 10, -8, 2, -6, -9, +6, -15, 6, -12, 3, -1, -1, 3, +-4, 13, 0, 12, 7, 10, 3, 4, +-4, -5, -10, -12, -7, -10, 0, -5, +13, 4, 10, 13, 2, 11, -4, 3, +-4, -4, 1, -12, 4, -10, 3, -7, +-4, -2, -9, 8, -5, 18, -3, 12, +7, 6, 5, -8, -5, -12, -13, -11, +-6, -5, 2, 1, 7, 12, 3, 13, +-6, 8, -8, 1, 0, -9, 5, -11, +5, -10, 0, -8, -5, 3, -9, 10, +5, 11, 13, 8, 6, 6, -4, -6, +-11, -9, -8, -13, 4, -3, 9, 8, +3, 15, -4, 11, -5, 8, -4, -2, +6, -9, 12, -15, 7, -14, -6, -1, +-9, 9, -5, 14, 4, 15, 9, 6, +0, -3, -11, -8, -10, -10, -4, -10, +6, -1, 8, 4, 1, 11, -9, 10, +-3, 3, 4, -9, 8, -11, 4, -13, +-6, -6, -10, 0, -3, 6, 5, 11, +9, 8, 4, 3, -5, -1, -11, -11, +1, -18, 12, -11, 10, 0, 3, 8, +-1, 14, -4, 5, 4, -2, 11, -9, +6, -11, 0, -13, -1, -4, -4, 2, +0, 13, 6, 12, 8, 4, 2, -2, +0, -9, -3, -14, 2, -12, 7, -5, +2, 6, -7, 16, -7, 14, -5, 8, +-2, 1, 2, -11, 3, -12, -4, -10, +-4, -1, -4, 7, -2, 12, 2, 9, +1, 8, -4, -3, -4, -9, -3, -11, +-2, -8, 1, -2, 5, 7, -1, 12, +-4, 14, -5, 7, 0, -5, 3, -11, +7, -13, 4, -11, -2, 3, -2, 9, +-1, 13, 3, 10, 7, 1, 4, -9, +-2, -9, -2, -13, 5, -7, 5, 2, +6, 7, 3, 8, -2, 6, -1, -2, +5, -9, 6, -13, 6, -14, 0, -4, +-9, 6, -7, 10, 2, 13, 2, 8, +0, 3, -8, -3, -11, -8, -8, -8, +0, 3, 1, 5, 0, 9, -2, 8, +-7, 6, -6, 1, 3, -4, 3, -9, +-2, -5, -7, -1, -4, 3, -1, 12, +9, 9, 9, 2, 2, -4, -4, -12, +-2, -12, 4, -7, 10, 0, 7, 6, +-1, 10, -5, 5, 0, 6, 1, -1, +7, -7, 5, -12, -2, -9, -4, -4, +1, 9, 4, 11, 6, 8, 0, 4, +-9, -5, -9, -11, 1, -7, 4, -4, +3, 4, -4, 10, -9, 9, -8, 5, +2, 4, 3, -6, 2, -9, -2, -11, +-8, -3, -8, 5, 3, 11, 5, 10, +0, 9, -6, -1, -6, -7, -3, -10, +9, -10, 9, -3, 3, 5, -5, 7, +-6, 12, -2, 7, 8, -3, 9, -6, +-2, -5, -8, -9, -1, 0, 3, 6, +5, 13, 4, 8, 1, 1, -5, -6, +-2, -6, 5, -11, 7, -6, 3, 1, +-4, 5, -9, 9, -1, 9, 2, 3, +2, -1, -2, -7, -6, -9, -8, -5, +0, -1, 7, 2, 4, 10, -3, 7, +-6, 1, -6, -5, 0, -8, 4, -10, +4, -3, -2, 2, -5, 10, -4, 7, +2, 3, 7, -2, 8, -10, 3, -11, +-1, -6, -2, -3, 3, 1, 7, 8, +4, 9, -1, 4, -1, 2, -2, -6, +0, -5, 2, -4, 4, -2, 1, 2, +-1, 11, -5, 10, -3, 8, 1, -1, +1, -6, -3, -5, -5, -3, -4, 0, +-2, 6, 1, 6, 3, 6, -3, 4, +-4, -4, -3, -8, 0, -8, 1, -7, +1, 3, -2, 4, -3, 8, -6, 9, +-4, 3, 2, -8, 5, -4, -2, -6, +-5, -5, -1, 0, 3, 6, 1, 10, +0, 11, -3, 2, -4, -4, -1, -8, +6, -10, 8, -6, 9, 0, 4, 1, +0, 4, 3, 2, 6, 1, 4, -6, +7, -13, 6, -13, -1, 1, -3, 4, +4, 8, 1, 9, -2, 5, -4, -2, +-4, -5, 0, -10, 6, -5, 2, -1, +-3, 3, -7, 9, -5, 7, -1, 0, +5, -2, 2, -8, -4, -7, -5, -4, +-4, 1, 0, 3, 5, 8, 0, 6, +-8, 6, -10, 1, -2, -3, 0, -3, +3, -1, 1, -2, -2, 3, -1, 4, +4, 6, 3, 5, 4, -3, 2, -9, +-3, -6, -1, -5, 7, 2, 7, 9, +0, 8, -3, 3, -5, 2, -2, -5, +7, -5, 6, -5, 0, 1, -9, 5, +-8, 8, -2, 4, 5, 5, 7, -3, +-1, -7, -8, -3, -7, -2, -4, 1, +2, 7, -1, 7, -7, 8, -10, 5, +-5, -4, 3, -9, 9, -9, 7, -8, +-4, 2, -8, 2, 1, 3, 4, 3, +8, -1, 6, -8, 2, -7, -1, -10, +3, -5, 5, 1, 6, 3, 4, 4, +0, 4, -3, -2, 5, -4, 7, -5, +6, -6, 1, -2, -2, 2, -2, 2, +2, 8, 4, 3, 2, 0, 0, -3, +-1, -5, -5, -3, -2, 4, 2, 0, +1, 3, -2, 4, -2, 3, -3, 2, +-2, -1, -2, -7, 0, -5, -2, -3, +1, 0, -2, 5, -2, 5, 2, -2, +1, -2, 0, -7, 2, -6, 1, -3, +-2, 1, -1, -1, 3, 4, 2, 1, +4, -1, 5, -6, 3, -6, 2, -4, +2, -2, 1, -3, 5, 1, 5, 5, +0, 5, -2, 2, 5, -4, 2, -4, +-1, 2, -4, 1, -3, 4, -2, 5, +0, 6, -3, 5, -2, 5, 0, -4, +0, -2, -3, -5, 0, -3, 1, 1, +0, 2, 2, 0, -1, 3, -3, 1, +-3, 0, -6, -1, -2, -5, 1, -4, +2, 0, -1, 2, -1, 5, -1, 4, +-3, 1, -3, -3, 1, -3, -1, -4, +1, 1, -1, -2, 4, -1, 6, 1, +5, 3, 0, -1, -2, -2, 3, -6, +2, -3, 1, 4, 3, 2, 2, 2, +2, 3, -2, 0, 2, -3, 7, -5, +6, -6, 1, -5, 1, -2, 0, 2, +0, 10, -2, 2, 4, -2, 0, -4, +-1, -4, -4, -3, -2, 2, 1, 0, +-1, 5, -6, 7, -8, 4, -5, 2, +1, 0, -2, -2, -4, 1, -4, 0, +-4, 0, -1, 1, 3, 0, 7, -2, +2, 2, -5, 0, -7, 0, -3, -3, +8, -3, 5, -2, 4, 2, 2, 0, +0, 2, 1, 0, 3, -3, 4, -3, +5, -6, 0, -3, -1, 6, -1, 4, +6, 0, 6, -2, 1, -4, 1, -5, +3, -3, 4, -5, 1, 1, 0, 2, +-1, 4, -6, 6, -5, 8, -6, 1, +-4, 3, -7, 0, -6, 0, -2, 1, +3, 2, -2, 3, -4, 4, -4, 1, +0, -2, -2, -1, -1, -2, -3, 0, +-2, 2, 0, 0, -1, 3, 2, 1, +4, -2, 1, -2, -3, 1, -3, -3, +5, -1, 4, -1, 1, 5, -2, 6, +-1, 1, 2, -5, 5, -5, 6, -6, +7, -3, 1, -1, 1, 0, -4, 6, +1, 7, 0, 3, -3, 3, -3, -2, +-2, -5, 1, -3, 1, 1, 1, 0, +3, 1, 1, -4, -2, 1, -5, 4, +-2, 2, -2, -1, -3, -3, 0, -4, +0, 2, -1, 3, 2, -1, 0, -2, +3, -2, -5, 0, -6, 4, -4, 1, +1, 1, 2, 1, 1, 0, 1, 0, +1, 5, -1, -4, 2, -4, 2, -2, +1, 2, -1, 2, -1, 3, 2, 1, +0, 3, 4, -1, 2, -4, -1, 0, +2, 0, -2, 1, -2, 5, -1, 0, +4, 0, 1, 1, -1, -3, 1, -4, +0, 3, -5, 1, -5, 4, -4, 1, +4, 1, 0, 0, 0, -2, 1, -5, +0, -1, 2, -3, -2, -2, -3, 2, +-1, 0, -1, 0, 2, 2, 0, -2, +4, -3, 1, -4, 0, -5, 2, -4, +5, 3, 1, 3, -3, 5, -5, 2, +2, 0, 0, -1, 3, -1, 0, -4, +2, 0, 3, -1, 1, 1, 2, 3, +3, -1, 5, -4, 2, -1, -4, 1, +-1, 0, 2, -3, 4, -4, 1, 2, +0, 3, 2, -1, -1, 0, -2, -3, +0, 1, -6, 5, -3, 4, -7, 0, +2, 1, 3, -4, 0, 1, -4, 2, +0, -5, 3, -4, -3, 2, -4, 0, +1, 3, -1, 5, -3, 3, -4, 1, +1, -1, 2, -2, -4, 2, -1, -3, +2, 0, 2, 5, -2, 6, -5, 1, +2, 1, 2, -5, 5, -3, 3, -4, +5, -3, 2, 1, -1, 2, 0, -2, +5, 3, 0, 3, -3, 0, -7, 1, +-1, -1, 2, -1, 1, 3, 2, -2, +-1, 0, 1, 3, -4, 2, -4, -2, +2, -2, 2, -5, -2, 4, -10, 8, +-6, 7, -3, 3, 0, 0, -1, -4, +0, 0, 1, -2, 1, -2, -3, 0, +2, 2, -2, 4, 0, 4, -3, -1, +-2, 1, 2, -1, -1, -3, 3, -3, +2, 1, 4, -2, 2, 2, 0, 1, +1, 0, 4, -4, 6, -7, 3, -6, +1, 2, 2, 1, -1, 4, -5, 4, +1, -1, 2, -3, 6, -2, -1, -5, +1, -2, 0, 1, -1, 2, -1, 1, +1, 0, 3, -4, -1, 1, -5, -1, +-2, 1, 1, -1, 2, -3, -1, -1, +-5, 7, -2, 5, -2, 3, -1, 0, +-2, -2, -3, 0, 0, 2, -5, -1, +4, 2, 0, 2, 1, 1, -3, 2, +-2, 1, 3, -4, 4, -1, 0, -3, +2, 0, 1, 3, 1, 3, -2, -3, +3, -1, 6, -4, 0, 0, 1, -3, +0, -6, 6, -1, 3, 1, 2, -2, +3, 1, -1, -1, 2, -3, -4, 1, +-2, 0, 2, -4, 5, -2, 1, -4, +-1, 2, 0, 0, 6, -5, 0, -4, +0, 2, -4, 0, -3, 6, -4, 4, +-6, 0, 4, 0, 1, 1, -2, 2, +-6, 4, -3, -2, 3, -4, 1, -1, +2, 2, 1, 4, 0, 3, 0, -5, +0, -3, 4, -2, 7, -3, 0, -2, +2, -1, -2, -2, 4, 5, -3, 2, +2, -1, 3, -1, 0, -1, -2, -2, +-3, 2, 2, -1, 5, -1, 2, -1, +-1, -1, -1, 0, 0, 0, 0, -3, +-4, 2, -1, 4, -3, 3, -4, 2, +-1, 0, 0, -3, 7, 0, 0, -4, +1, -2, -3, -2, 3, -4, 2, -2, +1, 3, 2, 1, 1, 1, -3, -1, +-1, -2, -1, 2, 2, 4, -1, -1, +-3, 1, 1, 2, -2, 4, 0, 2, +-1, -3, 5, -8, 7, -3, 2, -5, +2, 1, -2, 2, 4, 1, -1, 0, +1, -1, 4, -6, 5, -3, 0, -3, +-2, -2, -2, 3, 4, 3, -2, -1, +0, -1, -1, -1, -1, 1, 1, 1, +-2, -2, 4, -4, 0, 1, -1, -1, +-1, 0, 2, -1, 7, -4, 3, -6, +-1, 0, -3, -2, 2, -1, 6, -4, +5, -4, 3, 0, 4, 2, -4, -2, +1, -1, -1, -3, 6, 0, 1, 2, +-3, 0, 0, -3, 3, -1, 5, -1, +-2, 5, -1, 1, 1, -2, -3, -1, +-4, 4, -2, 1, 4, 3, 5, -1, +-6, 0, -6, 3, -3, 2, -2, 2, +1, 1, -1, -5, 7, -2, -4, 4, +-5, 6, -6, 3, 2, 1, 1, -2, +-7, 4, -6, 3, -2, 1, 1, -1, +3, -2, 3, -4, 4, 2, 0, -1, +-5, -1, 0, -1, 3, -1, 5, 1, +-2, 4, -3, -3, 3, -1, 0, -1, +3, -1, -1, 1, 2, 1, 0, -5, +1, -2, 3, -4, 8, -2, 6, -2, +4, -5, 0, -6, 3, 1, -2, 1, +-4, 4, -2, 1, 3, -4, 6, -1, +-4, 1, -1, -4, 2, -2, 6, -3, +4, -3, -2, 0, 3, -2, 0, -4, +1, 0, 3, -4, 7, -4, 4, -1, +-3, -3, -5, -3, 5, 2, 3, 0, +3, 4, -6, 2, -2, -1, -1, 1, +-3, 2, 3, -2, 2, -1, 4, 0, +-5, 2, -7, 5, 1, 0, 5, -3, +2, 2, -3, -1, -1, 0, 2, 0, +0, -2, 0, -1, 4, 2, 1, -1, +0, 3, -9, 0, 1, -2, 0, 1, +2, 3, -3, 3, -4, 5, -2, -1, +-2, -2, 0, 1, 2, 1, 2, -2, +2, -3, -2, -4, -3, 3, 2, 3, +-1, 2, -2, 4, -5, 2, 1, -2, +-3, 3, -4, -1, 6, -2, 3, -1, +5, 1, -8, 3, -7, 7, -3, -1, +2, -1, 3, -1, 3, 0, 0, 0, +-3, 2, -5, -2, 4, 1, 7, 1, +1, -2, -1, -3, -4, -4, 6, -4, +3, 2, 4, -1, 1, 0, -4, 2, +-4, 1, -6, 0, 4, 2, 7, -4, +3, -1, -6, 2, -5, 1, 0, -1, +6, 0, -2, 0, -1, 3, -4, 1, +0, -2, -2, 0, 1, 1, 4, 1, +-2, 5, -4, 2, -7, 2, -1, 2, +-1, 2, -2, 2, 1, 2, 2, -4, +1, 0, -4, -1, 2, -4, 9, -1, +2, 4, -5, -1, -1, 1, -2, 0, +4, 1, -4, 3, 0, 2, -2, 0, +-2, 4, -4, -1, -2, -2, 8, -3, +5, -3, 1, -1, 0, 2, -1, 0, +-5, 6, -7, 4, -3, 2, 4, 2, +1, -1, -1, -5, -2, -2, 3, -2, +5, 3, -3, 4, 2, -3, -3, -1, +-1, 4, -4, -1, 6, 0, 7, -1, +1, -1, -7, 1, -5, 1, 3, -4, +11, -1, 5, -4, 2, -2, -1, 2, +-5, 3, 1, -3, 3, -2, 11, -5, +3, 0, -4, 2, -4, 0, 0, -2, +9, 0, 1, -2, 1, 2, -3, 0, +-3, 0, -1, -1, 4, 2, 3, 2, +2, 4, -6, -3, -2, -3, -1, 2, +3, 4, 0, 3, -4, 2, 2, -4, +-2, 2, -1, 4, -1, -1, 7, -2, +4, 0, -4, -1, -4, 4, -2, 4, +1, 3, 0, 2, 1, -1, 1, -1, +-1, 5, -7, 2, -1, 2, 0, 2, +8, 0, 0, 2, -4, 4, -4, 0, +0, 2, 2, 4, -3, 2, 2, 0, +1, -3, 1, -5, 4, -1, 7, -1, +8, -2, 4, -4, -2, -3, -1, -1, +2, 3, 4, -1, 4, 0, 2, -2, +4, -1, -5, 1, 0, 3, -1, -2, +8, 0, 2, -1, 0, -1, 1, 2, +1, 1, 4, -2, 3, 2, 0, 1, +1, -1, -1, -1, -1, -1, 4, 1, +5, 3, 7, -2, -1, 0, 0, -2, +2, -2, 2, 2, 3, 2, 1, 0, +3, 4, -3, 0, 0, 1, 0, 3, +6, -3, 5, -4, 2, 1, -3, 0, +4, 1, 2, 0, 4, 0, 3, 0, +5, 1, 2, -1, -7, 3, -1, 1, +-1, 1, 7, 2, 2, 5, -3, 4, +-3, 5, -4, 0, 1, 0, 6, -1, +10, -3, 3, -1, -3, 3, -4, 2, +6, 3, 7, 0, 8, -4, 0, -4, +4, -3, 0, -2, 4, 3, 9, -1, +7, 0, 5, 1, -4, 0, 0, -2, +5, 0, 9, -4, 5, 1, -1, 4, +-2, 2, 1, 0, 5, -1, 9, -2, +6, 4, -2, 3, -4, -1, -4, -2, +10, 0, 7, 1, 7, 5, -1, 0, +-1, 0, -2, 2, -1, 1, 7, -2, +10, 0, 4, -2, 1, 0, 1, 2, +5, 1, 11, -3, 7, -4, 5, -5, +1, 0, 3, 4, 0, 3, 5, 2, +10, -2, 7, -4, 7, -2, 1, -5, +10, -5, 8, -5, 12, -5, 8, -2, +7, 2, 5, -4, 6, -3, 6, -4, +10, -3, 8, -3, 6, -4, 5, -3, +3, 3, 7, 3, 5, 0, 10, -4, +7, -4, 3, 0, -1, 3, -1, 2, +7, 2, 8, -2, 11, -3, 3, 1, +2, 4, 2, -1, 5, 0, 3, 0, +7, 1, 3, 3, 3, 3, -1, 3, +6, 2, 10, -1, 6, 0, 1, 1, +1, -3, 7, -2, 8, 3, 8, 3, +7, 5, 3, 1, 2, -2, 1, -1, +7, -1, 12, -5, 11, -2, 5, -1, +3, 3, 3, 5, 6, 3, 3, 0, +7, 2, 1, -1, 4, 0, 3, 0, +10, -2, 13, 0, 7, 4, 3, 1, +3, 0, 6, -3, 5, -3, 7, 1, +7, 4, 7, 4, 2, 5, 3, -1, +5, -1, 9, 0, 10, -3, 8, -7, +12, -4, 7, -4, 10, 2, 8, 1, +14, -1, 11, -3, 9, -4, 3, -2, +4, 2, 8, 1, 11, 1, 9, 1, +7, 2, 4, 2, 3, 2, 7, -5, +11, -4, 14, -1, 3, 4, 0, 5, +2, 5, 6, 3, 11, 4, 6, 0, +6, -1, 3, -4, 8, -3, 9, -1, +13, 4, 12, 3, 6, 3, -1, 4, +2, 2, 6, -1, 16, -3, 11, -5, +8, -1, 7, 0, 10, -2, 14, -1, +13, -1, 12, -5, 8, -3, 5, 0, +5, 1, 12, 1, 14, 1, 10, 0, +9, 2, 8, 2, 6, 0, 8, -3, +13, -5, 10, 0, 12, 2, 6, 0, +11, 1, 10, 0, 12, -1, 6, 2, +5, 0, 9, -4, 7, 3, 6, 5, +5, 5, 11, 2, 12, 0, 7, 0, +4, 1, 11, -3, 11, -2, 11, 1, +10, 2, 10, 2, 13, 2, 8, -1, +10, 1, 7, -2, 13, -2, 7, 0, +8, 3, 9, 0, 11, 2, 12, 1, +10, 3, 10, 2, 7, 0, 6, -3, +11, -2, 16, -1, 15, 3, 12, 4, +7, 3, 7, 2, 9, 0, 12, -2, +11, 1, 9, 1, 10, 1, 7, 3, +10, 4, 12, -1, 16, -3, 13, -7, +13, -6, 12, -6, 16, -3, 13, -1, +15, 4, 9, 7, 8, 6, 7, -1, +12, -4, 13, 0, 9, 5, 10, 6, +5, 5, 12, -2, 16, -4, 17, -3, +17, -2, 13, -1, 11, -2, 8, -4, +10, 4, 8, 5, 16, 3, 15, 0, +14, 0, 7, -1, 11, 3, 8, 1, +14, 1, 13, 4, 10, 4, 12, 2, +11, 3, 15, -1, 15, -2, 16, -2, +9, -1, 10, 0, 12, -1, 15, -3, +18, 0, 15, 1, 15, -1, 11, -3, +11, -3, 10, -2, 16, 2, 15, 2, +15, 4, 11, 4, 12, 1, 13, -1, +18, -3, 18, -5, 18, 0, 10, 4, +6, 4, 11, 2, 21, 0, 18, -2, +15, 0, 13, -4, 12, -4, 15, -3, +15, -2, 19, 1, 14, 9, 9, 8, +6, 6, 9, 1, 17, -2, 17, -3, +19, 1, 12, 3, 13, 5, 11, 3, +16, 0, 19, -1, 21, -2, 13, -4, +11, -2, 11, -1, 13, 2, 17, 5, +12, 4, 14, 1, 12, 2, 14, -1, +11, 0, 18, -2, 19, -1, 14, 2, +17, 3, 16, 2, 18, 4, 15, 1, +16, -1, 13, 1, 17, 0, 13, 0, +13, 4, 12, 6, 13, 4, 18, -1, +20, -3, 15, -3, 13, -2, 17, -6, +19, -2, 23, -1, 24, -1, 19, -1, +19, 1, 15, 1, 17, 2, 19, -1, +17, 1, 13, 4, 13, 4, 15, 2, +18, 1, 21, -2, 20, -4, 17, -6, +19, -6, 15, -6, 22, -3, 21, -1, +19, 6, 14, 4, 17, -1, 16, -3, +19, -2, 20, 0, 16, 7, 14, 7, +12, 7, 14, 6, 14, 7, 17, 5, +16, 1, 20, -5, 18, -4, 15, -2, +20, -1, 18, 1, 23, 1, 19, -2, +22, -2, 15, -4, 19, -3, 21, -6, +27, -4, 24, 2, 17, 8, 16, 5, +16, 4, 19, 1, 20, -1, 24, -2, +19, -4, 19, -4, 19, -1, 21, 1, +24, 1, 19, 0, 21, -7, 20, -9, +21, -4, 17, -3, 24, -1, 23, 1, +17, 4, 16, 4, 18, 3, 22, 0, +23, 2, 16, 0, 19, 0, 21, 3, +21, 5, 19, 3, 23, 3, 19, -1, +19, -2, 19, -1, 19, -5, 25, -8, +24, -4, 19, 0, 20, 2, 26, 2, +20, 0, 20, -3, 21, -1, 17, 1, +22, 2, 23, 0, 28, 2, 21, 4, +20, 5, 13, 4, 21, 4, 21, -1, +19, -1, 17, 2, 15, 0, 23, -2, +23, 1, 22, 2, 18, 1, 19, -1, +12, -1, 18, -3, 28, -2, 26, 2, +22, 9, 15, 6, 21, 2, 23, 0, +28, -1, 23, -3, 28, -1, 21, -1, +21, -2, 28, -1, 27, 0, 24, -1, +22, -5, 22, -6, 20, -2, 21, 1, +19, 2, 19, 1, 27, 1, 22, 2, +22, 4, 22, 1, 24, -2, 24, -4, +26, 0, 24, 4, 23, 8, 22, 5, +19, 3, 24, -2, 28, -7, 27, -8, +28, -8, 25, -6, 24, -3, 22, -3, +29, -3, 24, -2, 29, -3, 23, -6, +24, -2, 24, 0, 21, 4, 23, 6, +22, 9, 25, 5, 24, 2, 27, -1, +24, -3, 29, -6, 31, -5, 26, -3, +27, 0, 21, 2, 22, -1, 25, -4, +32, -3, 22, -4, 25, -5, 19, -2, +22, 0, 28, 2, 26, 8, 23, 5, +25, 0, 28, 0, 19, 2, 28, -1, +31, 0, 25, 4, 21, 7, 18, 4, +25, 2, 25, 0, 26, -4, 24, -7, +26, -4, 18, -1, 20, -1, 27, 1, +27, 2, 26, -1, 26, -1, 24, 0, +26, 1, 27, 0, 25, 4, 24, 5, +28, 6, 23, 5, 28, 6, 26, 1, +27, -1, 23, -4, 23, -3, 28, -4, +31, -2, 29, -3, 23, -5, 31, -5, +28, -4, 29, -5, 31, -4, 25, -2, +24, 2, 20, 5, 29, 5, 34, 2, +38, 4, 19, 2, 22, -1, 27, -1, +29, 3, 27, 3, 27, 2, 22, 1, +19, 2, 24, 0, 25, -4, 36, -8, +28, -8, 20, -5, 24, -1, 27, 2, +33, 4, 28, 5, 27, 4, 21, 2, +28, 2, 23, 2, 31, 3, 33, 3, +27, 4, 24, 4, 29, 1, 32, -3, +29, -2, 27, -4, 24, -5, 26, -2, +26, -3, 26, -2, 32, 1, 27, 1, +26, -2, 28, -5, 35, -5, 29, -1, +29, 3, 27, 5, 26, 10, 30, 9, +24, 9, 24, 5, 26, 1, 25, -5, +29, -6, 33, -6, 34, -3, 28, -3, +30, -4, 25, -6, 34, -7, 32, -6, +27, -3, 26, -2, 27, 1, 24, 6, +25, 9, 31, 10, 26, 7, 31, 1, +28, -2, 29, -1, 33, 0, 31, 0, +32, 4, 29, 3, 31, 0, 23, -4, +31, -6, 28, -6, 31, -4, 27, -2, +24, 0, 25, 0, 29, 1, 30, 3, +31, 3, 36, 3, 23, 3, 22, 1, +28, 2, 32, 5, 37, 7, 33, 3, +30, 2, 25, -1, 28, -3, 27, -6, +38, -5, 30, -1, 20, 1, 21, 0, +27, -2, 36, -3, 34, -2, 27, -1, +24, -2, 28, -1, 29, 2, 31, 3, +41, 5, 32, 6, 30, 4, 30, 2, +32, 2, 30, -1, 31, -2, 27, 0, +29, 4, 30, 3, 25, 0, 31, -5, +31, -8, 31, -10, 32, -9, 35, -6, +34, 0, 26, 6, 24, 9, 22, 8, +37, 9, 28, 9, 25, 5, 24, 3, +25, 5, 26, 5, 34, 6, 37, 4, +31, 2, 26, -1, 16, -2, 27, -4, +36, -5, 34, -6, 27, -2, 22, 2, +23, 3, 28, 2, 40, 0, 34, -2, +35, -1, 20, 3, 22, 7, 32, 11, +37, 11, 34, 6, 29, 5, 27, 5, +23, 1, 32, -3, 34, -6, 34, -5, +33, -2, 23, -2, 32, -4, 38, -8, +39, -9, 31, -7, 33, -6, 32, -3, +32, 0, 32, 5, 30, 8, 32, 11, +32, 8, 30, 2, 32, 0, 33, -1, +27, 1, 29, 1, 37, 2, 32, 1, +33, 0, 23, -4, 29, -7, 33, -11, +37, -9, 30, -5, 30, 2, 27, 3, +23, 4, 36, 2, 38, 0, 40, 1, +30, 4, 24, 4, 28, 4, 35, 4, +36, 7, 33, 9, 34, 6, 25, -4, +33, -10, 34, -12, 39, -8, 35, -6, +33, -5, 30, -4, 32, -3, 35, -3, +30, -2, 39, -2, 34, -2, 29, 0, +26, 6, 27, 9, 35, 8, 40, 4, +40, 3, 31, 2, 32, -1, 24, -4, +31, -3, 39, -3, 36, 0, 28, -1, +26, -3, 29, -6, 34, -7, 37, -7, +30, -3, 30, -3, 28, 1, 23, 6, +35, 8, 39, 9, 36, 8, 25, 4, +29, 2, 29, 2, 37, 3, 35, 3, +31, 5, 33, 5, 26, 1, 32, -6, +39, -11, 41, -16, 35, -14, 32, -9, +32, -1, 33, 3, 35, 4, 25, 2, +32, 2, 31, 3, 32, 4, 29, 5, +33, 7, 26, 9, 25, 12, 32, 8, +37, 3, 44, -3, 28, -5, 24, -7, +28, -6, 36, -4, 35, -3, 33, -2, +31, -1, 22, -4, 33, -5, 33, -6, +44, -5, 37, -2, 24, 4, 23, 8, +35, 10, 39, 10, 37, 7, 35, 3, +28, -3, 32, -7, 36, -4, 38, 1, +39, 2, 32, -1, 26, -4, 29, -6, +40, -8, 34, -10, 37, -10, 30, -6, +29, -1, 32, 3, 33, 7, 36, 7, +33, 8, 27, 5, 25, 2, 36, 3, +35, 5, 30, 5, 32, 6, 28, 6, +34, 3, 32, -2, 31, -6, 29, -10, +34, -11, 28, -9, 35, -4, 39, -2, +31, 0, 30, 0, 29, -1, 34, 0, +34, -1, 36, -1, 32, 4, 32, 11, +29, 15, 24, 12, 39, 6, 33, 3, +30, 2, 23, -1, 30, -4, 32, -4, +34, -1, 30, -1, 33, -3, 37, -5, +27, -6, 30, -9, 36, -9, 39, -8, +38, -3, 37, 4, 32, 9, 30, 9, +34, 7, 29, 6, 37, 5, 29, 1, +27, -1, 29, 0, 34, 3, 34, 2, +34, -1, 33, -4, 25, -5, 27, -9, +29, -12, 37, -9, 41, 0, 27, 5, +23, 6, 26, 6, 34, 4, 34, 0, +38, 1, 32, 1, 33, 3, 32, 6, +31, 8, 38, 8, 35, 8, 24, 4, +22, -5, 35, -10, 34, -10, 35, -8, +34, -7, 31, -3, 39, -4, 33, -6, +35, -2, 29, -2, 32, -2, 26, -1, +35, 4, 38, 9, 30, 15, 23, 16, +20, 10, 35, 2, 40, -3, 33, -3, +26, -4, 29, -5, 28, -2, 31, 0, +39, -2, 35, -6, 32, -8, 18, -6, +25, -2, 34, -1, 39, 3, 27, 6, +26, 6, 29, 6, 28, 4, 39, 3, +39, 2, 34, 3, 26, 4, 22, 6, +31, 7, 38, 5, 37, 0, 27, -4, +29, -7, 26, -10, 29, -8, 33, -7, +36, -2, 31, 3, 25, 6, 24, 3, +32, 0, 36, 0, 27, 0, 33, -1, +35, 4, 31, 8, 32, 8, 32, 5, +37, 4, 32, 2, 31, -3, 27, -7, +31, -6, 23, -5, 24, -5, 36, -4, +36, -2, 32, -2, 25, -4, 27, -7, +33, -6, 38, 0, 32, 7, 29, 10, +28, 10, 20, 9, 29, 7, 38, 0, +42, 0, 28, 1, 25, 0, 24, -1, +34, 2, 34, 3, 30, 0, 35, -7, +27, -10, 25, -10, 29, -7, 34, -1, +31, 1, 28, 5, 26, 7, 26, 3, +34, 3, 27, 2, 33, 0, 36, 2, +29, 6, 23, 8, 30, 8, 31, 6, +31, 4, 31, -1, 28, -7, 29, -10, +23, -9, 21, -5, 30, -1, 34, -2, +33, -4, 29, -5, 31, -2, 27, -2, +36, -1, 33, 2, 33, 7, 28, 12, +17, 15, 23, 12, 35, 6, 39, -2, +32, -8, 30, -8, 26, -6, 28, -5, +32, -4, 34, -6, 39, -6, 31, -5, +25, -5, 28, -8, 40, -6, 29, -2, +28, 1, 29, 1, 32, 4, 31, 7, +25, 6, 27, 4, 29, 4, 29, 3, +25, 3, 32, 3, 31, 4, 24, 2, +28, -2, 30, -7, 35, -8, 25, -8, +19, -7, 22, -4, 31, 2, 27, 5, +27, 5, 27, 2, 23, 1, 22, 1, +30, 1, 40, -1, 39, 5, 26, 11, +17, 13, 26, 9, 38, 4, 32, -1, +31, -9, 24, -14, 22, -12, 23, -8, +32, -4, 35, -1, 31, 1, 22, 1, +22, 0, 35, -4, 37, -6, 34, -5, +31, -1, 22, 7, 21, 12, 22, 13, +27, 9, 29, 3, 28, 0, 21, -2, +32, -5, 34, -4, 28, 0, 23, -3, +27, -5, 28, -7, 28, -9, 33, -9, +26, -3, 26, 1, 22, 3, 25, 3, +33, 2, 26, 1, 23, 2, 20, 2, +29, 3, 30, 4, 33, 8, 26, 11, +27, 9, 29, 3, 30, -3, 33, -9, +32, -11, 20, -11, 14, -10, 24, -10, +29, -4, 29, 3, 25, 6, 24, 4, +30, 3, 27, -1, 31, -3, 30, 0, +26, 6, 18, 6, 24, 8, 28, 10, +26, 8, 25, 2, 21, -1, 24, -5, +28, -7, 23, -7, 23, -6, 26, -5, +27, -3, 25, -4, 32, -4, 29, -4, +29, -4, 24, -2, 26, 4, 27, 7, +25, 8, 18, 2, 18, 2, 24, 2, +25, 0, 32, 1, 30, 4, 30, 4, +27, 5, 22, 4, 28, -1, 30, -7, +26, -10, 14, -8, 18, -7, 20, -4, +23, -1, 22, 1, 24, 3, 27, 1, +30, 0, 30, 1, 30, 3, 29, 4, +19, 7, 20, 7, 25, 7, 26, 5, +22, 2, 20, -4, 26, -10, 27, -10, +26, -7, 18, -5, 23, -3, 20, 0, +18, 3, 26, -2, 34, -6, 30, -5, +23, -4, 24, -3, 29, 5, 28, 12, +22, 13, 16, 11, 15, 7, 12, 1, +17, -2, 25, -4, 29, -6, 27, -6, +28, -3, 28, 0, 33, 2, 31, 0, +23, -3, 20, -5, 16, -6, 14, -6, +17, -4, 20, -2, 20, 3, 16, 5, +24, 6, 28, 7, 32, 13, 19, 15, +16, 14, 17, 8, 16, 4, 15, -3, +16, -5, 18, -5, 18, -4, 23, -4, +24, -2, 24, 0, 18, 1, 15, 2, +19, 1, 26, -4, 27, -7, 19, -6, +19, -2, 21, 3, 32, 8, 30, 15, +27, 18, 18, 14, 8, 6, 9, -5, +18, -14, 25, -18, 20, -15, 16, -5, +17, 6, 24, 11, 32, 14, 27, 14, +22, 8, 18, -4, 14, -8, 12, -10, +21, -12, 21, -9, 14, 1, 10, 8, +18, 9, 27, 10, 29, 12, 25, 10, +26, 2, 25, -6, 22, -13, 24, -17, +24, -12, 16, -6, 17, -1, 19, 1, +25, 3, 22, 2, 16, 1, 17, -4, +24, -8, 27, -12, 26, -11, 24, -4, +17, 4, 17, 9, 23, 15, 26, 15, +27, 12, 18, 6, 12, -2, 14, -10, +19, -14, 15, -18, 16, -15, 14, -10, +20, 0, 25, 8, 31, 13, 33, 9, +25, 7, 14, 1, 9, -4, 20, -8, +20, -4, 13, 2, 9, 4, 10, 3, +14, 4, 15, 4, 22, 2, 24, -1, +25, -2, 20, -3, 22, -3, 22, -3, +19, -2, 14, -1, 17, 2, 17, 0, +18, -3, 19, -6, 17, -5, 18, -3, +15, 0, 14, 1, 18, 5, 13, 10, +11, 12, 16, 7, 29, 0, 31, -4, +24, -2, 13, 0, 11, 2, 13, -1, +13, -4, 13, -9, 12, -6, 6, -2, +8, 1, 21, 1, 31, 2, 30, 2, +24, 1, 19, -2, 24, 1, 20, 6, +11, 12, 4, 12, 3, 7, 4, 0, +8, -7, 16, -13, 21, -15, 21, -11, +17, -3, 21, 4, 24, 12, 16, 15, +12, 10, 10, 3, 15, -2, 14, -3, +14, 0, 10, 0, 13, 1, 11, 0, +12, 5, 12, 6, 15, 4, 11, 2, +11, 2, 18, -1, 23, -2, 23, -3, +19, -4, 19, -5, 20, 0, 16, 5, +13, 8, 7, 4, 1, -1, -7, -4, +1, -5, 12, -5, 23, 0, 24, 4, +24, 11, 20, 15, 21, 15, 20, 9, +16, 6, 7, 1, -1, -2, -3, -7, +4, -11, 11, -15, 13, -13, 12, -8, +17, -1, 25, 3, 30, 8, 26, 7, +21, 3, 13, -1, 8, -3, 10, -3, +13, 2, 11, 5, 10, 9, 10, 8, +15, 4, 18, -4, 17, -9, 8, -11, +10, -11, 10, -8, 12, 1, 16, 4, +19, 4, 17, 6, 16, 5, 20, 4, +22, 4, 15, -2, 7, -10, 3, -14, +3, -14, 4, -9, 9, 3, 11, 12, +16, 19, 18, 17, 27, 11, 28, 5, +26, 1, 11, -7, 4, -10, 1, -9, +-1, -7, -4, -6, -3, -7, 2, -6, +11, -6, 20, -2, 26, 4, 29, 6, +29, 5, 20, 6, 11, 9, 8, 8, +4, 9, -4, 11, -5, 12, 0, 7, +12, -1, 17, -13, 21, -19, 18, -20, +16, -16, 12, -8, 13, 2, 14, 5, +12, 6, 7, 4, 9, 3, 14, 3, +18, 4, 15, 3, 13, 4, 9, 2, +2, 3, -3, 1, -4, -1, 2, -4, +7, -2, 13, 0, 24, 0, 31, 1, +30, 3, 20, 3, 15, 4, 8, 2, +1, 0, -10, -4, -11, -12, -7, -22, +6, -25, 15, -21, 23, -7, 24, 10, +23, 24, 22, 30, 22, 28, 17, 18, +6, 7, -3, -6, -4, -11, 0, -13, +6, -8, 7, -8, 7, -7, 6, -8, +10, -4, 13, 1, 17, 5, 12, 3, +8, -1, 6, -8, 11, -10, 17, -8, +22, -1, 16, 10, 7, 21, 0, 23, +0, 19, 3, 7, 0, -6, -3, -21, +2, -26, 10, -22, 21, -11, 29, -1, +30, 10, 21, 16, 14, 14, 9, 8, +5, 5, -3, -2, -11, -10, -15, -21, +-3, -27, 7, -24, 13, -11, 14, 3, +19, 21, 20, 32, 21, 34, 20, 24, +15, 12, 5, -2, -2, -12, -3, -15, +2, -12, 4, -9, -1, -6, -4, -7, +1, -7, 10, -8, 15, -6, 15, -3, +13, 3, 8, 5, 10, 4, 14, 1, +20, 3, 13, 6, 3, 13, -5, 16, +-1, 15, 3, 7, 3, -6, 1, -20, +5, -24, 6, -20, 11, -10, 18, 0, +19, 11, 16, 14, 10, 8, 10, 1, +14, -4, 10, -5, 2, -4, -8, -3, +-7, -5, -7, -10, -2, -11, 0, -10, +10, -3, 17, 6, 23, 17, 24, 20, +26, 21, 18, 14, 9, 8, 0, 0, +-5, -4, -10, -10, -15, -13, -14, -17, +-4, -22, 10, -24, 17, -16, 17, -4, +18, 8, 17, 18, 15, 23, 11, 17, +8, 8, 0, -1, -5, -3, -4, -3, +6, 2, 8, 6, 8, 5, 4, -3, +6, -11, 7, -19, 11, -18, 5, -10, +0, -2, 3, -1, 12, 2, 18, 3, +21, 5, 18, 6, 9, 10, -1, 11, +-9, 9, -13, -1, -17, -12, -20, -21, +-10, -24, 5, -15, 23, 4, 31, 21, +35, 32, 28, 32, 22, 25, 7, 10, +-5, -4, -18, -17, -26, -24, -25, -28, +-13, -27, 5, -24, 22, -15, 24, -4, +21, 8, 23, 14, 22, 20, 13, 19, +-2, 16, -14, 6, -17, -1, -11, -4, +-1, 4, 6, 10, 12, 13, 8, 8, +3, 0, 1, -12, 1, -19, -7, -21, +-10, -16, -4, -7, 9, 5, 19, 11, +25, 15, 23, 13, 18, 7, 9, 3, +-1, 2, -9, -5, -15, -12, -23, -19, +-25, -19, -10, -16, 13, -4, 27, 12, +31, 27, 29, 32, 26, 28, 14, 15, +4, 0, -10, -13, -21, -18, -30, -19, +-22, -18, -5, -18, 15, -17, 19, -15, +16, -7, 14, 2, 12, 13, 10, 19, +5, 23, -1, 21, -7, 16, -6, 4, +1, -3, 9, -7, 12, -6, 4, -3, +-4, -2, -8, -9, -4, -14, -7, -14, +-5, -9, 2, -3, 15, 7, 18, 13, +21, 12, 18, 5, 12, 0, 4, -6, +-3, -3, -12, 4, -21, 8, -23, 3, +-17, -3, -4, -14, 14, -20, 25, -18, +25, -2, 18, 15, 14, 28, 8, 30, +2, 23, -6, 10, -13, 0, -16, -12, +-5, -20, 1, -23, 7, -24, 5, -28, +4, -24, 0, -14, 2, 3, 4, 20, +4, 36, 2, 39, 5, 32, 9, 16, +11, -1, 9, -16, 4, -20, -3, -17, +-12, -6, -19, 2, -19, 5, -13, 1, +-4, -3, 5, -6, 21, -5, 27, -3, +27, 3, 14, 4, 8, 3, 1, 2, +-8, 6, -19, 9, -23, 12, -22, 9, +-11, -2, 2, -17, 14, -26, 17, -25, +9, -10, 6, 7, 9, 26, 14, 37, +9, 37, -3, 25, -8, 5, -6, -16, +3, -29, 3, -33, 3, -29, -5, -24, +-8, -15, -11, -6, -2, 4, 6, 10, +12, 17, 10, 21, 13, 23, 18, 12, +21, 1, 12, -10, -1, -11, -11, -8, +-18, 1, -18, 8, -13, 8, -4, -2, +0, -12, 4, -20, 13, -21, 20, -14, +18, 1, 7, 15, 0, 25, -5, 22, +-3, 14, -5, 5, -8, 0, -8, -9, +-2, -15, -1, -18, 2, -21, 1, -20, +-1, -9, -5, 7, 1, 26, 11, 37, +14, 39, 13, 26, 12, 5, 12, -17, +10, -30, 1, -33, -12, -24, -24, -14, +-29, -2, -27, 2, -10, 2, 5, -1, +17, 1, 22, 5, 29, 14, 28, 19, +24, 19, 6, 14, -15, 8, -30, -2, +-28, -8, -19, -8, -9, -5, 3, -7, +13, -12, 19, -16, 23, -17, 22, -13, +13, -1, 0, 7, -9, 15, -15, 17, +-12, 11, -5, -2, 4, -9, 7, -8, +11, -2, 8, 1, 5, 3, -6, 0, +-14, -4, -19, -6, -17, -2, -8, 5, +8, 14, 18, 18, 28, 20, 28, 15, +24, 7, 11, -5, -11, -12, -27, -19, +-34, -24, -29, -29, -21, -30, -7, -27, +11, -16, 24, 5, 34, 30, 35, 48, +31, 56, 10, 45, -10, 20, -23, -12, +-23, -34, -23, -43, -18, -37, -9, -23, +6, -4, 18, 10, 24, 18, 22, 16, +14, 11, 4, 2, -6, -5, -7, -11, +-4, -14, -5, -16, -6, -12, -2, -6, +7, 10, 8, 24, 5, 30, -4, 22, +-7, 8, -13, -12, -8, -26, -1, -32, +10, -19, 9, 4, 6, 28, 9, 36, +16, 32, 14, 20, -2, 4, -14, -14, +-18, -28, -17, -37, -14, -36, -12, -32, +-4, -20, 2, -3, 11, 20, 17, 40, +21, 55, 13, 54, 4, 39, -2, 11, +0, -17, -3, -37, -8, -38, -18, -29, +-15, -14, -6, -2, 0, 8, 2, 8, +7, 1, 9, -3, 13, -1, 18, 2, +20, 6, 13, 7, -2, 5, -14, -2, +-15, -8, -12, -6, -15, 1, -16, 6, +-11, 9, -3, 8, 12, 5, 19, 1, +24, 3, 12, 8, 3, 12, -4, 8, +-2, 3, -6, -5, -8, -14, -12, -20, +-8, -17, 0, -11, 9, -1, 10, 3, +7, 2, 4, -7, -1, -9, -4, -8, +-6, 3, -2, 15, 3, 27, 6, 30, +13, 30, 10, 22, 6, 11, -3, -6, +-5, -18, -12, -25, -16, -29, -20, -33, +-18, -28, -7, -19, 9, 0, 21, 21, +27, 39, 27, 46, 17, 40, 4, 17, +-7, -10, -13, -37, -20, -46, -26, -38, +-24, -16, -10, 8, 8, 29, 17, 36, +22, 33, 22, 22, 19, 9, 11, -5, +6, -16, -5, -23, -14, -26, -21, -28, +-14, -20, -4, -6, 6, 11, 6, 21, +6, 20, 6, 9, 5, -4, 2, -16, +-1, -17, -3, -4, -7, 18, -8, 33, +-2, 38, 6, 30, 8, 17, 5, -3, +3, -19, 1, -29, -2, -29, -11, -27, +-14, -18, -13, -12, 1, -4, 5, 8, +10, 21, 9, 28, 11, 29, 12, 18, +10, 5, 4, -11, -6, -21, -16, -18, +-24, -4, -19, 10, -10, 21, -5, 19, +-1, 10, 4, -2, 11, -6, 15, -5, +16, 4, 8, 11, 0, 15, -12, 13, +-16, 7, -17, -5, -11, -14, -13, -20, +-12, -19, -6, -17, 7, -9, 15, -2, +17, 11, 12, 23, 6, 36, 2, 40, +-2, 39, -5, 20, -5, -5, -5, -29, +-8, -40, -8, -39, -4, -23, -5, -2, +-5, 17, -3, 25, 2, 24, 3, 13, +4, 2, 0, -8, 3, -9, 2, -6, +0, 1, -5, 4, -6, 10, -12, 15, +-11, 20, -8, 21, -3, 21, -3, 11, +-5, -5, -3, -23, 4, -33, 12, -30, +10, -11, 3, 13, -3, 36, -7, 44, +-6, 39, -9, 20, -8, -6, -9, -33, +-7, -43, -11, -37, -2, -23, 2, -6, +4, 14, -3, 30, -2, 42, 1, 46, +3, 46, 1, 33, -2, 13, -2, -14, +-5, -33, -7, -39, -11, -31, -14, -16, +-17, 5, -18, 19, -10, 27, -2, 22, +6, 11, 8, -1, 14, -6, 16, -7, +15, 0, 0, 9, -12, 13, -24, 8, +-25, 7, -26, 6, -19, 9, -7, 10, +2, 9, 10, 2, 21, -4, 23, -11, +15, -10, 1, -6, -13, 6, -21, 16, +-24, 21, -24, 16, -18, 6, -7, -9, +5, -16, 13, -12, 13, 0, 7, 6, +-1, 9, -18, 11, -25, 13, -25, 11, +-16, 15, -10, 18, 5, 21, 14, 21, +21, 14, 20, -2, 11, -12, -9, -19, +-26, -20, -36, -17, -38, -8, -26, -1, +-15, 7, -2, 11, 16, 13, 31, 15, +38, 21, 26, 23, 6, 21, -20, 10, +-36, -2, -50, -12, -46, -12, -35, -6, +-14, 6, 4, 14, 22, 20, 31, 19, +28, 13, 15, 3, -4, 1, -21, 2, +-33, 6, -38, 5, -33, 0, -19, -10, +-4, -10, 9, -10, 17, -3, 18, 8, +9, 20, -8, 24, -16, 21, -20, 11, +-19, 5, -22, 4, -18, 7, -7, 9, +10, 9, 16, 4, 13, -1, 0, -5, +-11, -4, -20, -1, -22, 6, -24, 7, +-22, 4, -19, -4, -11, -10, 5, -14, +18, -5, 18, 11, 7, 28, -2, 36, +-9, 38, -17, 27, -22, 11, -27, -7, +-27, -17, -26, -20, -17, -15, -5, -11, +11, -4, 13, 5, 12, 18, 3, 30, +-2, 38, -9, 33, -17, 20, -21, -4, +-23, -25, -24, -36, -27, -34, -20, -22, +-9, 1, 0, 28, 1, 49, 1, 51, +3, 42, -1, 26, -6, 10, -13, -2, +-16, -9, -24, -17, -26, -17, -30, -16, +-18, -12, -5, -2, 4, 14, 7, 28, +5, 37, -5, 34, -18, 19, -25, -5, +-24, -25, -23, -33, -23, -22, -20, 0, +-7, 26, 7, 44, 12, 54, 4, 49, +-10, 36, -26, 14, -35, -8, -38, -25, +-36, -35, -34, -36, -25, -25, -10, -4, +13, 26, 23, 56, 19, 72, 4, 65, +-9, 39, -29, 0, -44, -36, -53, -62, +-48, -62, -37, -37, -23, 1, -3, 34, +15, 65, 20, 79, 17, 73, 12, 51, +-4, 24, -29, -9, -47, -36, -58, -55, +-51, -55, -38, -41, -20, -11, -6, 26, +13, 60, 18, 78, 18, 73, 4, 42, +-16, 1, -42, -36, -59, -55, -58, -54, +-38, -28, -14, 13, 1, 53, 12, 75, +13, 79, 7, 59, -3, 27, -25, -9, +-48, -41, -62, -62, -57, -64, -39, -46, +-6, -8, 16, 36, 32, 75, 28, 95, +10, 89, -14, 49, -38, -4, -62, -56, +-70, -85, -63, -80, -44, -44, -17, 6, +10, 58, 26, 92, 28, 103, 12, 84, +-12, 48, -37, 4, -55, -34, -64, -60, +-60, -66, -42, -54, -17, -23, 0, 22, +6, 67, 2, 90, -2, 83, -12, 48, +-22, 0, -35, -47, -40, -75, -43, -72, +-29, -36, -13, 14, 1, 69, -4, 101, +-14, 103, -19, 74, -26, 27, -39, -24, +-53, -64, -53, -86, -39, -77, -18, -40, +-2, 13, 8, 63, 11, 98, -1, 113, +-15, 97, -34, 50, -50, -13, -69, -75, +-66, -105, -56, -94, -33, -47, -12, 18, +7, 86, 16, 128, 13, 133, -7, 96, +-32, 32, -51, -35, -67, -79, -69, -94, +-53, -78, -30, -34, -6, 24, 8, 76, +10, 109, -2, 109, -24, 80, -54, 26, +-67, -35, -71, -82, -62, -101, -38, -86, +-6, -26, 15, 51, 27, 119, 15, 151, +-11, 137, -42, 78, -72, 0, -94, -76, +-93, -120, -72, -123, -35, -79, 4, -8, +32, 67, 40, 118, 28, 139, -2, 119, +-38, 68, -74, -1, -98, -64, -101, -105, +-80, -105, -47, -69, -10, -4, 15, 65, +27, 120, 19, 140, -4, 118, -36, 57, +-60, -19, -80, -79, -84, -100, -72, -83, +-44, -33, -13, 29, 11, 84, 17, 111, +-2, 103, -31, 66, -60, 17, -75, -32, +-77, -64, -74, -73, -55, -57, -25, -22, +7, 30, 20, 77, 17, 104, -7, 102, +-36, 78, -69, 35, -86, -17, -88, -65, +-74, -86, -51, -73, -17, -29, 10, 23, +16, 66, 6, 85, -14, 86, -40, 64, +-62, 28, -79, -11, -78, -37, -63, -45, +-38, -34, -18, -15, -6, 12, -13, 39, +-31, 67, -52, 80, -63, 71, -69, 42, +-68, 6, -58, -25, -35, -40, -15, -34, +-6, -8, -11, 26, -20, 57, -42, 69, +-67, 58, -85, 27, -83, -3, -70, -24, +-46, -31, -24, -24, -8, -4, -2, 21, +-7, 46, -22, 61, -46, 64, -78, 53, +-96, 36, -96, 14, -74, -7, -45, -25, +-20, -25, -8, -10, -1, 17, -13, 41, +-33, 51, -55, 45, -77, 31, -92, 8, +-88, -13, -70, -21, -42, -7, -12, 17, +8, 43, 11, 56, -10, 54, -49, 36, +-84, 14, -109, -7, -113, -21, -99, -23, +-67, -6, -35, 18, 3, 39, 24, 50, +27, 59, 1, 60, -44, 51, -95, 26, +-126, -8, -130, -38, -109, -46, -74, -34, +-35, -5, -2, 27, 18, 59, 17, 80, +-4, 82, -43, 55, -83, 17, -112, -15, +-113, -26, -95, -22, -65, -7, -37, 11, +-12, 32, -3, 48, -10, 53, -32, 42, +-57, 24, -81, 5, -94, -6, -92, -17, +-71, -23, -50, -14, -31, 16, -19, 47, +-9, 71, -22, 74, -49, 59, -76, 28, +-92, -3, -99, -31, -94, -41, -80, -27, +-55, 3, -32, 38, -15, 63, -11, 67, +-19, 64, -43, 48, -64, 25, -83, -2, +-93, -19, -100, -28, -85, -18, -62, -2, +-39, 19, -30, 38, -32, 55, -40, 61, +-47, 51, -61, 24, -76, -1, -87, -14, +-85, -7, -69, 7, -45, 29, -32, 50, +-37, 65, -55, 59, -68, 33, -79, -1, +-86, -23, -94, -27, -82, -13, -63, 8, +-41, 31, -28, 46, -23, 57, -32, 56, +-46, 46, -70, 29, -95, 17, -108, 2, +-104, -10, -86, -13, -62, -2, -45, 17, +-35, 35, -35, 46, -43, 47, -59, 38, +-70, 25, -79, 16, -78, 15, -75, 17, +-69, 26, -63, 29, -56, 26, -59, 12, +-68, -4, -77, -12, -80, -4, -77, 16, +-68, 39, -60, 56, -49, 63, -49, 55, +-52, 34, -60, 6, -67, -14, -75, -21, +-76, -5, -76, 21, -79, 44, -80, 54, +-81, 58, -79, 49, -69, 27, -67, -1, +-66, -21, -62, -28, -51, -15, -44, 10, +-39, 42, -47, 67, -63, 83, -90, 77, +-108, 46, -112, 0, -104, -37, -89, -51, +-67, -32, -49, 4, -36, 43, -32, 70, +-37, 84, -50, 71, -70, 40, -92, 4, +-107, -14, -109, -12, -95, 2, -81, 18, +-68, 30, -65, 32, -62, 30, -61, 20, +-52, 6, -50, 3, -61, 16, -78, 33, +-82, 49, -83, 53, -84, 50, -92, 42, +-96, 28, -90, 5, -73, -15, -59, -21, +-51, -5, -54, 18, -58, 38, -66, 49, +-78, 52, -98, 42, -105, 20, -97, -5, +-73, -16, -52, -8, -42, 23, -49, 55, +-60, 71, -77, 64, -96, 42, -116, 9, +-121, -19, -113, -35, -88, -22, -59, 12, +-36, 52, -29, 78, -37, 81, -57, 60, +-81, 28, -107, -2, -123, -19, -122, -22, +-106, -6, -87, 21, -68, 48, -58, 57, +-49, 50, -52, 31, -60, 10, -74, -8, +-86, -10, -97, 1, -90, 26, -80, 55, +-76, 75, -81, 70, -84, 46, -85, 11, +-86, -19, -86, -35, -83, -31, -77, -5, +-75, 38, -77, 75, -76, 87, -75, 65, +-74, 29, -79, -7, -79, -27, -84, -24, +-86, 1, -87, 36, -84, 71, -86, 82, +-89, 63, -91, 22, -83, -17, -78, -38, +-72, -34, -68, -12, -69, 33, -81, 77, +-92, 106, -101, 102, -99, 67, -94, 12, +-86, -33, -81, -55, -75, -48, -74, -20, +-77, 24, -88, 72, -101, 103, -109, 99, +-103, 65, -91, 18, -72, -18, -61, -34, +-51, -26, -50, 4, -64, 48, -98, 79, +-125, 82, -139, 53, -129, 11, -107, -28, +-78, -46, -51, -39, -32, -3, -29, 44, +-41, 88, -72, 108, -113, 94, -146, 48, +-152, -2, -136, -38, -102, -48, -71, -32, +-47, 5, -37, 45, -38, 81, -63, 97, +-89, 79, -112, 37, -123, -5, -126, -34, +-115, -40, -97, -26, -73, 7, -53, 48, +-47, 83, -59, 94, -82, 78, -102, 42, +-107, 2, -106, -30, -106, -42, -110, -33, +-105, -3, -95, 35, -76, 69, -66, 87, +-64, 88, -69, 69, -71, 44, -77, 18, +-89, -7, -106, -30, -118, -37, -122, -25, +-117, -2, -108, 26, -95, 56, -78, 80, +-55, 93, -48, 87, -58, 58, -76, 14, +-93, -25, -107, -47, -112, -44, -118, -17, +-118, 25, -112, 71, -99, 108, -86, 112, +-70, 78, -64, 20, -63, -33, -69, -68, +-76, -74, -88, -47, -95, 11, -101, 77, +-102, 132, -109, 145, -109, 111, -98, 41, +-80, -36, -69, -95, -63, -117, -69, -91, +-84, -17, -104, 79, -116, 157, -115, 184, +-103, 158, -92, 87, -75, -3, -64, -85, +-62, -128, -74, -118, -88, -54, -116, 39, +-140, 126, -151, 168, -132, 161, -95, 110, +-58, 33, -37, -52, -31, -108, -47, -111, +-78, -61, -108, 14, -131, 91, -149, 142, +-143, 153, -112, 119, -73, 59, -51, -16, +-45, -79, -59, -105, -86, -80, -120, -22, +-139, 44, -132, 98, -100, 134, -69, 138, +-45, 105, -42, 42, -58, -21, -89, -62, +-127, -68, -161, -49, -171, -16, -150, 24, +-97, 68, -38, 96, 4, 99, 7, 78, +-24, 50, -77, 21, -131, -5, -176, -27, +-195, -32, -180, -21, -126, 5, -59, 31, +-4, 52, 12, 60, -10, 64, -59, 57, +-108, 40, -155, 14, -180, -7, -176, -17, +-132, -8, -74, 7, -26, 28, -13, 49, +-25, 68, -60, 78, -105, 70, -142, 42, +-161, 11, -160, -15, -135, -30, -100, -36, +-63, -23, -42, 10, -36, 57, -45, 99, +-60, 113, -86, 94, -110, 57, -129, 10, +-130, -33, -126, -64, -120, -67, -115, -36, +-102, 21, -83, 75, -59, 110, -41, 117, +-34, 99, -43, 57, -64, 5, -99, -46, +-131, -72, -158, -64, -164, -23, -148, 28, +-110, 78, -71, 111, -34, 120, -14, 95, +-16, 41, -47, -25, -91, -69, -136, -76, +-159, -46, -159, 3, -135, 59, -99, 107, +-62, 134, -42, 123, -35, 74, -50, 6, +-76, -49, -106, -80, -126, -78, -136, -51, +-132, 0, -114, 62, -85, 118, -59, 147, +-48, 135, -52, 84, -61, 20, -82, -39, +-103, -81, -120, -98, -125, -74, -123, -14, +-111, 62, -97, 117, -75, 138, -57, 122, +-44, 82, -41, 24, -54, -33, -84, -74, +-117, -76, -141, -41, -146, 15, -138, 67, +-123, 103, -96, 116, -58, 108, -27, 71, +-14, 11, -34, -48, -74, -80, -123, -75, +-152, -30, -158, 26, -134, 84, -103, 130, +-70, 144, -39, 110, -21, 45, -38, -26, +-74, -72, -115, -88, -145, -66, -158, -20, +-143, 41, -100, 98, -48, 135, -14, 131, +-7, 89, -33, 31, -83, -20, -138, -58, +-166, -77, -165, -67, -137, -19, -96, 49, +-43, 111, -2, 136, 9, 121, -26, 75, +-85, 14, -144, -50, -178, -87, -185, -81, +-153, -30, -95, 42, -30, 106, 13, 133, +23, 124, -14, 87, -75, 31, -142, -33, +-184, -78, -196, -90, -173, -57, -119, 3, +-49, 67, 10, 117, 33, 142, 11, 131, +-39, 84, -107, 14, -164, -57, -194, -98, +-184, -88, -148, -42, -91, 25, -39, 89, +0, 129, 14, 130, -3, 94, -47, 33, +-101, -27, -149, -60, -173, -55, -166, -25, +-130, 16, -87, 54, -44, 81, -15, 85, +-4, 66, -20, 30, -52, -4, -94, -20, +-132, -16, -160, -6, -158, 9, -132, 30, +-87, 56, -42, 69, -6, 62, 2, 37, +-17, 11, -59, -5, -103, -6, -139, -1, +-159, 13, -160, 28, -130, 38, -77, 33, +-25, 22, 5, 8, 10, 8, -17, 22, +-62, 42, -112, 50, -146, 45, -158, 28, +-145, 8, -113, -12, -63, -23, -21, -12, +-4, 20, -17, 58, -47, 79, -88, 71, +-121, 44, -143, 15, -135, -8, -108, -22, +-71, -19, -40, -1, -23, 32, -27, 62, +-51, 76, -84, 64, -110, 37, -125, 6, +-122, -22, -103, -42, -70, -37, -47, -4, +-38, 51, -43, 98, -53, 119, -76, 99, +-97, 49, -113, -16, -108, -71, -91, -92, +-70, -62, -57, 7, -55, 88, -70, 140, +-84, 137, -88, 84, -83, 8, -78, -61, +-69, -94, -61, -79, -55, -14, -60, 70, +-72, 134, -84, 145, -91, 104, -102, 32, +-103, -44, -92, -98, -67, -110, -44, -73, +-31, 12, -40, 111, -59, 177, -81, 179, +-93, 120, -101, 21, -99, -83, -89, -158, +-71, -163, -58, -92, -48, 33, -49, 160, +-60, 236, -80, 221, -95, 125, -102, -14, +-92, -138, -71, -204, -47, -179, -37, -68, +-38, 85, -53, 207, -71, 251, -92, 202, +-105, 82, -110, -60, -100, -168, -81, -205, +-50, -152, -28, -33, -19, 106, -27, 207, +-46, 232, -76, 176, -106, 69, -125, -55, +-118, -148, -95, -173, -68, -120, -41, -12, +-21, 110, -22, 191, -36, 194, -61, 122, +-89, 14, -117, -88, -122, -142, -103, -129, +-60, -46, -25, 70, -10, 164, -16, 188, +-40, 132, -78, 26, -110, -78, -127, -139, +-120, -132, -96, -59, -61, 51, -24, 149, +2, 190, 2, 155, -18, 61, -59, -45, +-107, -117, -146, -134, -144, -90, -112, -2, +-65, 97, -30, 161, -8, 167, -2, 108, +-11, 16, -41, -74, -77, -125, -110, -120, +-125, -57, -118, 39, -87, 134, -53, 184, +-27, 166, -21, 82, -27, -26, -45, -115, +-66, -143, -85, -105, -93, -14, -93, 92, +-88, 168, -79, 175, -59, 109, -38, 1, +-22, -91, -22, -128, -34, -96, -58, -14, +-80, 81, -94, 142, -92, 145, -88, 87, +-78, -2, -66, -80, -45, -112, -28, -87, +-17, -15, -21, 70, -32, 135, -55, 154, +-85, 117, -111, 34, -117, -57, -109, -120, +-81, -127, -48, -72, -16, 26, 2, 121, +4, 179, -16, 172, -50, 97, -92, -20, +-119, -127, -126, -174, -104, -136, -74, -28, +-37, 106, -8, 201, 6, 223, -5, 157, +-32, 29, -67, -106, -98, -190, -119, -185, +-117, -92, -99, 43, -64, 160, -25, 215, +8, 195, 14, 106, -5, -14, -46, -117, +-86, -163, -113, -139, -120, -54, -111, 54, +-78, 143, -38, 177, -2, 149, 11, 70, +2, -29, -27, -111, -63, -136, -98, -93, +-115, -3, -108, 92, -81, 153, -50, 151, +-20, 85, -8, -12, -13, -96, -27, -131, +-40, -93, -58, -3, -75, 95, -88, 152, +-85, 145, -71, 78, -53, -16, -40, -94, +-30, -117, -29, -81, -28, 0, -38, 85, +-54, 138, -73, 134, -82, 77, -77, -7, +-61, -80, -45, -113, -34, -89, -28, -20, +-28, 64, -38, 129, -54, 147, -71, 109, +-78, 33, -80, -48, -68, -104, -46, -114, +-16, -71, -8, 8, -14, 92, -37, 141, +-63, 137, -87, 78, -92, -9, -79, -87, +-57, -121, -38, -95, -19, -20, -6, 74, +-8, 144, -33, 154, -63, 99, -86, 4, +-91, -86, -78, -133, -54, -114, -34, -38, +-18, 63, -15, 145, -21, 166, -36, 117, +-53, 26, -66, -72, -66, -133, -65, -132, +-59, -70, -47, 26, -34, 115, -30, 158, +-28, 139, -37, 73, -47, -16, -54, -96, +-54, -129, -56, -102, -54, -26, -55, 68, +-54, 145, -53, 171, -48, 135, -45, 43, +-40, -69, -33, -149, -27, -156, -33, -88, +-44, 22, -58, 128, -66, 185, -75, 170, +-73, 83, -60, -35, -28, -126, 0, -156, +13, -115, -2, -24, -32, 79, -71, 151, +-98, 168, -107, 118, -88, 27, -57, -61, +-24, -111, 4, -118, 22, -78, 11, -2, +-20, 78, -58, 128, -88, 127, -108, 81, +-100, 14, -71, -51, -29, -86, 3, -82, +18, -40, 6, 21, -27, 74, -64, 97, +-85, 85, -95, 48, -88, -3, -65, -47, +-24, -57, 8, -31, 20, 13, 5, 51, +-28, 64, -71, 51, -106, 19, -116, -24, +-84, -52, -35, -45, 10, -6, 29, 43, +18, 82, -18, 91, -53, 62, -86, 12, +-106, -41, -108, -71, -82, -65, -40, -28, +10, 23, 38, 68, 37, 91, 3, 85, +-48, 56, -97, 9, -117, -39, -114, -68, +-85, -71, -39, -49, 9, -2, 34, 54, +34, 96, 8, 100, -29, 71, -71, 18, +-98, -39, -106, -80, -88, -83, -52, -51, +-9, 3, 16, 50, 21, 75, 10, 75, +-13, 58, -47, 29, -68, -3, -77, -24, +-75, -33, -69, -38, -58, -38, -41, -29, +-16, -7, 2, 30, 12, 72, 4, 97, +-15, 95, -48, 60, -78, 1, -98, -68, +-98, -112, -80, -109, -42, -53, -2, 35, +23, 119, 24, 159, 8, 140, -29, 65, +-60, -37, -78, -121, -81, -150, -78, -118, +-63, -38, -41, 59, -14, 137, 3, 168, +11, 139, 4, 60, -16, -35, -55, -113, +-90, -150, -102, -133, -78, -61, -35, 40, +10, 136, 28, 183, 17, 165, -20, 84, +-61, -30, -86, -138, -76, -190, -49, -158, +-20, -52, -7, 77, -7, 174, -21, 196, +-39, 140, -57, 35, -60, -75, -53, -145, +-38, -147, -22, -88, -5, 3, -5, 83, +-19, 123, -41, 119, -54, 79, -59, 19, +-51, -37, -45, -72, -32, -77, -23, -61, +-12, -26, -10, 17, -19, 61, -39, 87, +-51, 79, -49, 40, -36, -8, -27, -45, +-15, -57, -13, -45, -23, -14, -44, 20, +-61, 41, -70, 33, -61, 7, -33, -11, +9, -4, 36, 23, 37, 50, 5, 59, +-43, 39, -97, -11, -130, -72, -129, -109, +-84, -91, -22, -19, 41, 72, 82, 141, +87, 160, 50, 117, -18, 22, -102, -89, +-162, -168, -174, -177, -132, -112, -58, -7, +30, 99, 101, 176, 133, 199, 104, 150, +23, 49, -82, -72, -163, -170, -199, -214, +-174, -187, -98, -92, 6, 54, 94, 193, +140, 268, 118, 247, 46, 135, -53, -34, +-139, -197, -184, -295, -170, -275, -108, -138, +-19, 55, 55, 219, 97, 294, 99, 259, +62, 135, -8, -35, -80, -183, -131, -247, +-143, -215, -122, -119, -70, 9, -5, 126, +54, 200, 74, 211, 51, 156, -2, 53, +-55, -60, -96, -152, -102, -198, -77, -177, +-31, -86, 6, 44, 22, 156, 4, 200, +-31, 169, -61, 81, -60, -26, -39, -113, +-7, -143, 13, -111, 13, -44, -16, 14, +-53, 46, -78, 52, -72, 51, -51, 52, +-19, 56, 8, 53, 16, 39, -2, -4, +-19, -68, -32, -118, -37, -122, -44, -71, +-53, 15, -64, 100, -59, 158, -43, 165, +-8, 107, 29, 0, 47, -106, 24, -166, +-28, -160, -87, -100, -105, -9, -81, 83, +-34, 149, 5, 160, 31, 113, 35, 28, +17, -60, -22, -123, -52, -146, -71, -120, +-69, -50, -55, 36, -25, 114, -1, 152, +10, 138, 7, 70, -4, -26, -24, -113, +-41, -157, -47, -133, -46, -43, -48, 71, +-42, 153, -38, 166, -31, 98, -19, -25, +12, -136, 35, -177, 38, -125, 11, -6, +-30, 125, -81, 194, -120, 167, -130, 56, +-90, -85, -16, -196, 66, -222, 117, -146, +123, 0, 69, 153, -29, 248, -135, 244, +-193, 142, -188, -19, -116, -179, -17, -279, +75, -272, 121, -155, 124, 29, 86, 208, +20, 316, -63, 306, -133, 178, -179, -24, +-179, -220, -128, -330, -31, -312, 74, -182, +149, 10, 166, 196, 122, 312, 23, 319, +-94, 217, -188, 41, -214, -153, -178, -294, +-94, -338, 10, -273, 109, -105, 159, 117, +149, 315, 76, 404, -26, 340, -120, 138, +-171, -128, -173, -355, -130, -440, -62, -340, +18, -98, 76, 183, 101, 382, 95, 412, +68, 269, 4, 22, -70, -217, -126, -344, +-145, -308, -127, -145, -73, 53, -4, 195, +56, 229, 81, 163, 79, 44, 55, -61, +16, -109, -40, -94, -91, -45, -125, -2, +-122, 13, -82, 1, -16, -15, 42, -12, +78, 13, 82, 44, 60, 61, 3, 52, +-56, 11, -90, -42, -96, -71, -91, -62, +-64, -25, -22, 13, 25, 28, 48, 20, +51, 3, 39, -10, 21, 3, -19, 40, +-66, 80, -103, 83, -108, 27, -81, -72, +-24, -165, 34, -192, 78, -123, 84, 17, +53, 171, -15, 268, -85, 252, -125, 114, +-115, -89, -67, -259, 6, -315, 66, -236, +84, -59, 50, 140, 2, 278, -43, 303, +-79, 206, -101, 25, -83, -158, -43, -268, +7, -272, 45, -176, 64, -15, 57, 148, +32, 248, -11, 243, -56, 138, -95, -16, +-107, -156, -89, -228, -43, -203, 10, -90, +69, 58, 102, 168, 88, 192, 27, 126, +-45, 17, -99, -90, -119, -148, -105, -136, +-57, -63, 0, 27, 43, 88, 60, 99, +65, 70, 53, 20, 26, -28, -15, -66, +-54, -81, -92, -69, -114, -32, -111, 13, +-66, 52, 10, 83, 91, 97, 134, 73, +120, 11, 53, -69, -28, -133, -106, -148, +-160, -105, -165, -17, -109, 94, -23, 180, +63, 196, 120, 126, 140, -4, 110, -139, +40, -219, -52, -209, -126, -109, -168, 39, +-159, 172, -106, 231, -17, 185, 72, 57, +143, -86, 158, -180, 120, -190, 42, -124, +-49, -9, -140, 97, -197, 142, -195, 111, +-121, 38, -2, -34, 129, -75, 224, -77, +235, -45, 130, 6, -47, 49, -206, 61, +-272, 35, -238, -8, -117, -48, 40, -73, +178, -69, 230, -31, 192, 37, 88, 103, +-34, 126, -136, 84, -190, 0, -194, -91, +-145, -156, -55, -164, 59, -100, 154, 19, +202, 137, 179, 194, 86, 166, -57, 77, +-188, -31, -246, -127, -205, -181, -96, -171, +45, -93, 162, 14, 210, 105, 164, 153, +62, 161, -48, 124, -128, 40, -164, -73, +-144, -165, -87, -195, -8, -162, 58, -78, +104, 39, 125, 156, 122, 223, 80, 197, +-6, 89, -120, -49, -198, -166, -197, -224, +-112, -207, 14, -109, 137, 44, 197, 180, +175, 228, 80, 181, -37, 77, -128, -49, +-159, -160, -142, -207, -80, -158, -2, -49, +70, 57, 108, 112, 111, 126, 72, 115, +11, 73, -51, -4, -87, -79, -96, -116, +-67, -109, -21, -79, 26, -31, 51, 38, +59, 106, 47, 124, 20, 77, -18, -2, +-31, -68, -21, -102, -7, -94, -11, -45, +-15, 27, -22, 82, -28, 78, -26, 21, +5, -38, 47, -63, 78, -50, 64, -10, +12, 43, -58, 87, -99, 88, -91, 28, +-36, -61, 25, -128, 65, -141, 65, -97, +34, -9, 0, 99, -11, 188, -8, 200, +-2, 117, -6, -22, -14, -151, -34, -227, +-50, -225, -44, -139, -1, 9, 50, 155, +82, 239, 74, 235, 40, 164, -14, 45, +-67, -93, -99, -215, -90, -278, -44, -253, +21, -143, 76, 23, 106, 204, 97, 340, +61, 365, 0, 242, -67, 10, -111, -245, +-105, -418, -68, -439, -14, -294, 44, -34, +104, 241, 135, 420, 123, 442, 71, 305, +-2, 67, -90, -189, -155, -377, -167, -436, +-108, -348, -12, -149, 91, 97, 168, 314, +196, 434, 153, 403, 55, 217, -73, -53, +-173, -299, -200, -430, -141, -399, -35, -229, +77, 18, 149, 250, 161, 370, 112, 333, +39, 181, -23, -8, -49, -167, -64, -251, +-74, -242, -76, -157, -57, -37, -29, 66, +20, 126, 84, 146, 142, 133, 153, 89, +106, 24, 7, -42, -101, -89, -177, -115, +-181, -113, -115, -79, 2, -17, 124, 45, +200, 82, 194, 83, 118, 62, 7, 33, +-92, 1, -150, -28, -133, -44, -54, -43, +34, -43, 74, -54, 67, -59, 33, -31, +5, 23, -2, 73, 25, 98, 62, 97, +78, 62, 44, -7, -23, -85, -99, -130, +-132, -115, -102, -59, -15, 7, 83, 55, +157, 75, 173, 67, 121, 42, 16, 12, +-74, -3, -119, -3, -110, -11, -68, -45, +-5, -85, 50, -101, 82, -78, 83, -14, +71, 74, 51, 150, 26, 171, -2, 109, +-17, -13, -28, -139, -40, -213, -50, -199, +-41, -99, -12, 49, 37, 178, 84, 223, +116, 159, 112, 17, 81, -127, 20, -202, +-54, -177, -120, -70, -133, 65, -88, 158, +-6, 162, 75, 72, 138, -57, 153, -147, +112, -149, 37, -71, -28, 41, -68, 125, +-76, 140, -58, 81, -17, -20, 22, -112, +47, -150, 48, -117, 42, -39, 38, 37, +46, 84, 55, 95, 56, 76, 36, 37, +2, -12, -39, -57, -68, -82, -72, -86, +-37, -71, 12, -42, 63, 7, 100, 61, +124, 99, 113, 97, 59, 60, -18, 2, +-77, -58, -108, -98, -104, -107, -59, -80, +19, -25, 91, 34, 142, 75, 148, 91, +113, 79, 42, 38, -36, -23, -99, -80, +-118, -103, -91, -87, -18, -41, 59, 14, +114, 62, 132, 81, 114, 63, 52, 15, +-17, -39, -57, -70, -54, -64, -31, -39, +7, 0, 40, 43, 60, 71, 47, 59, +14, 9, -12, -59, -13, -107, -2, -115, +27, -80, 70, 1, 106, 114, 101, 198, +55, 192, -27, 81, -100, -89, -132, -244, +-100, -314, -22, -261, 77, -82, 165, 162, +214, 360, 189, 410, 102, 280, -25, 27, +-147, -244, -225, -431, -217, -453, -111, -296, +60, -20, 218, 261, 305, 434, 283, 434, +160, 280, -21, 28, -180, -235, -252, -414, +-218, -439, -104, -306, 46, -72, 165, 175, +227, 350, 224, 397, 168, 301, 68, 99, +-37, -130, -122, -297, -162, -349, -157, -288, +-89, -148, 22, 24, 135, 179, 198, 267, +200, 264, 145, 180, 52, 55, -55, -79, +-124, -202, -129, -275, -77, -259, 4, -149, +85, 6, 126, 148, 118, 237, 67, 253, +13, 184, -20, 42, -19, -119, 5, -235, +35, -260, 46, -195, 51, -83, 49, 50, +27, 176, -19, 238, -50, 203, -53, 85, +-18, -62, 45, -179, 120, -230, 168, -199, +158, -86, 75, 74, -38, 199, -139, 223, +-182, 141, -147, -1, -31, -141, 115, -220, +233, -199, 268, -81, 209, 82, 70, 198, +-83, 203, -196, 105, -227, -38, -166, -169, +-20, -235, 147, -195, 261, -46, 266, 131, +179, 236, 36, 213, -102, 88, -173, -74, +-149, -208, -61, -254, 49, -177, 127, -7, +156, 161, 125, 225, 61, 163, -7, 27, +-45, -108, -45, -187, -9, -172, 38, -68, +76, 67, 84, 150, 66, 132, 23, 35, +-23, -74, -44, -143, -26, -146, 10, -80, +54, 30, 91, 126, 118, 153, 108, 96, +54, -7, -14, -107, -56, -167, -70, -158, +-48, -77, 6, 39, 77, 133, 118, 151, +118, 85, 85, -27, 38, -122, -5, -160, +-18, -119, -10, -11, 12, 105, 26, 148, +24, 96, 4, -21, -4, -133, 17, -178, +64, -137, 108, -25, 128, 108, 111, 187, +59, 165, -29, 57, -112, -80, -143, -181, +-97, -205, 3, -150, 124, -38, 220, 82, +245, 161, 175, 167, 43, 110, -98, 16, +-182, -83, -178, -154, -93, -167, 31, -119, +153, -35, 219, 50, 203, 104, 111, 105, +-3, 64, -87, -1, -97, -56, -47, -70, +34, -42, 100, -8, 118, 3, 70, -13, +0, -49, -48, -90, -43, -104, 3, -58, +78, 46, 142, 150, 165, 192, 119, 147, +23, 32, -81, -118, -137, -251, -124, -303, +-44, -230, 59, -53, 156, 147, 209, 281, +195, 306, 115, 216, 14, 42, -75, -155, +-124, -293, -129, -313, -76, -220, 15, -71, +109, 80, 161, 189, 172, 233, 139, 195, +80, 95, 8, -24, -42, -121, -60, -189, +-50, -220, -30, -192, -10, -92, 6, 40, +41, 141, 90, 183, 149, 165, 188, 96, +181, -10, 104, -116, -22, -173, -148, -160, +-204, -103, -171, -50, -60, -9, 89, 29, +233, 63, 311, 81, 287, 80, 162, 69, +-12, 48, -178, -5, -264, -91, -239, -170, +-96, -191, 94, -141, 251, -41, 312, 77, +255, 183, 105, 224, -54, 166, -168, 29, +-188, -126, -108, -233, 29, -249, 148, -171, +198, -31, 165, 112, 86, 195, -8, 175, +-66, 66, -65, -64, -4, -152, 73, -170, +119, -116, 110, -12, 62, 88, -9, 132, +-53, 94, -54, -5, 2, -110, 78, -169, +129, -159, 132, -81, 98, 39, 37, 152, +-13, 202, -49, 157, -51, 25, -15, -141, +49, -264, 100, -291, 115, -201, 94, -26, +57, 166, 8, 289, -22, 285, -23, 150, +18, -51, 71, -226, 97, -303, 90, -263, +64, -135, 16, 22, -24, 148, -50, 189, +-40, 148, 9, 65, 79, -12, 148, -65, +186, -96, 159, -110, 72, -108, -54, -92, +-152, -66, -172, -31, -93, 27, 44, 96, +178, 138, 258, 117, 244, 46, 120, -46, +-26, -131, -126, -185, -142, -181, -81, -114, +16, -6, 106, 93, 155, 147, 139, 141, +89, 86, 31, -6, -5, -114, -4, -192, +34, -197, 79, -126, 91, -17, 51, 83, +-14, 147, -78, 152, -78, 82, -10, -46, +102, -159, 200, -195, 233, -144, 179, -42, +59, 65, -91, 138, -184, 143, -187, 64, +-99, -66, 47, -174, 199, -193, 286, -119, +273, -7, 162, 90, 11, 141, -129, 123, +-196, 31, -171, -93, -60, -174, 90, -165, +212, -85, 255, 15, 212, 97, 83, 130, +-53, 87, -141, -23, -149, -137, -71, -183, +57, -131, 170, -14, 222, 106, 179, 176, +79, 157, -35, 43, -115, -123, -133, -259, +-66, -287, 53, -190, 161, -11, 213, 167, +199, 278, 114, 276, 6, 153, -89, -51, +-130, -249, -95, -357, -7, -337, 91, -212, +173, -23, 196, 176, 163, 320, 83, 348, +-12, 236, -76, 23, -75, -207, -32, -372, +18, -413, 55, -311, 83, -91, 90, 162, +86, 340, 79, 365, 83, 239, 87, 30, +65, -178, 10, -312, -42, -324, -86, -219, +-84, -52, -27, 94, 73, 163, 178, 148, +238, 91, 206, 19, 109, -43, -11, -79, +-112, -80, -164, -59, -135, -46, -31, -55, +114, -69, 221, -67, 237, -44, 168, -12, +60, 28, -59, 71, -126, 95, -104, 78, +-3, 18, 114, -57, 183, -119, 160, -156, +79, -161, -27, -127, -103, -52, -102, 36, +-10, 109, 114, 147, 212, 149, 221, 106, +143, 16, 20, -106, -97, -215, -171, -266, +-153, -236, -45, -139, 111, 3, 239, 156, +282, 265, 226, 277, 107, 176, -45, 0, +-167, -180, -201, -306, -128, -345, 7, -284, +150, -128, 231, 70, 237, 235, 187, 307, +92, 273, -21, 148, -93, -33, -117, -215, +-82, -338, -11, -356, 72, -261, 141, -90, +179, 98, 151, 243, 81, 306, 11, 266, +-29, 129, -40, -62, -11, -237, 31, -335, +70, -326, 88, -223, 66, -53, 29, 128, +26, 252, 35, 275, 55, 196, 69, 48, +66, -108, 58, -222, 42, -264, 7, -226, +-8, -126, -1, -8, 28, 83, 66, 122, +106, 126, 122, 106, 105, 61, 54, -8, +-9, -87, -49, -149, -39, -183, -10, -192, +51, -152, 114, -56, 147, 70, 152, 172, +112, 208, 29, 164, -37, 59, -74, -82, +-57, -218, 11, -296, 90, -268, 138, -146, +138, 11, 84, 141, 15, 217, -29, 221, +-11, 145, 40, 9, 98, -128, 116, -217, +73, -237, 7, -207, -48, -142, -67, -42, +-14, 78, 74, 169, 174, 200, 231, 173, +186, 103, 65, -15, -74, -168, -184, -297, +-196, -334, -91, -257, 98, -99, 271, 90, +345, 260, 277, 346, 107, 291, -80, 101, +-209, -143, -233, -330, -123, -391, 36, -327, +186, -167, 267, 38, 240, 214, 153, 283, +54, 228, -42, 100, -81, -29, -67, -128, +-16, -193, 45, -221, 80, -196, 74, -130, +57, -57, 50, 14, 58, 98, 74, 174, +109, 195, 119, 131, 100, 4, 50, -131, +-31, -229, -87, -268, -87, -230, -52, -120, +42, 19, 145, 126, 214, 168, 228, 151, +165, 107, 56, 43, -38, -40, -110, -128, +-136, -192, -102, -218, -7, -202, 104, -139, +190, -28, 217, 106, 179, 211, 109, 232, +40, 161, -23, 29, -37, -112, -30, -231, +-20, -287, -7, -263, -5, -168, 9, -42, +63, 76, 118, 166, 181, 223, 228, 225, +222, 160, 137, 24, -5, -153, -160, -316, +-261, -409, -255, -391, -126, -235, 82, 26, +310, 305, 437, 484, 416, 478, 267, 278, +28, -46, -205, -377, -329, -592, -325, -605, +-178, -392, 34, -35, 229, 317, 355, 526, +366, 529, 258, 329, 105, 8, -37, -315, +-121, -517, -143, -520, -121, -339, -85, -64, +-25, 191, 52, 339, 123, 346, 191, 220, +258, 15, 268, -179, 212, -278, 73, -262, +-103, -169, -231, -56, -273, 40, -217, 89, +-36, 74, 190, 13, 371, -40, 435, -49, +348, -14, 142, 25, -87, 33, -262, -3, +-311, -75, -207, -159, -6, -208, 181, -174, +287, -48, 273, 107, 182, 211, 76, 212, +-15, 107, -62, -63, -32, -223, 15, -298, +46, -246, 49, -91, 25, 83, 11, 181, +38, 167, 67, 68, 97, -57, 120, -150, +115, -165, 78, -102, 35, -4, -6, 60, +-7, 53, 12, -5, 13, -69, 12, -106, +41, -96, 68, -50, 92, 13, 107, 57, +107, 61, 94, 16, 63, -49, 0, -95, +-35, -108, -12, -98, 32, -65, 70, -13, +88, 39, 72, 60, 54, 39, 26, -10, +11, -66, 50, -111, 121, -123, 156, -96, +141, -32, 69, 42, -31, 88, -112, 75, +-135, 10, -87, -73, 46, -141, 191, -171, +273, -142, 271, -56, 197, 54, 66, 133, +-48, 142, -129, 75, -152, -36, -112, -149, +-46, -224, 28, -228, 129, -146, 213, -12, +278, 108, 291, 168, 217, 158, 71, 86, +-86, -20, -213, -130, -261, -210, -208, -230, +-73, -181, 96, -90, 275, 19, 383, 122, +385, 193, 294, 192, 115, 106, -98, -38, +-260, -181, -352, -271, -302, -278, -120, -201, +117, -56, 341, 99, 475, 198, 451, 203, +290, 131, 45, 21, -185, -86, -323, -170, +-323, -211, -213, -197, -29, -135, 168, -49, +299, 35, 343, 100, 321, 140, 212, 135, +85, 74, -36, -28, -145, -128, -199, -194, +-192, -214, -131, -185, 0, -101, 138, 12, +258, 114, 329, 165, 319, 154, 221, 86, +73, -15, -84, -129, -200, -215, -242, -239, +-193, -188, -88, -86, 79, 26, 251, 113, +351, 159, 361, 149, 264, 83, 85, -23, +-84, -128, -221, -202, -256, -229, -164, -205, +-15, -118, 134, 12, 253, 136, 301, 194, +272, 170, 161, 77, 16, -48, -107, -165, +-148, -234, -117, -226, -42, -148, 61, -44, +137, 48, 151, 108, 146, 136, 110, 128, +87, 74, 82, -24, 49, -131, 2, -213, +-33, -244, -53, -214, -18, -107, 41, 51, +98, 192, 131, 246, 129, 190, 98, 48, +69, -117, 50, -251, 30, -310, 14, -273, +23, -143, 14, 28, 17, 170, 47, 238, +68, 227, 85, 136, 91, -20, 68, -200, +65, -328, 41, -345, 5, -243, 8, -64, +43, 136, 91, 281, 131, 306, 124, 191, +83, -16, 19, -221, -41, -335, -84, -330, +-56, -217, 37, -43, 135, 126, 207, 216, +219, 204, 155, 109, 74, -14, -27, -118, +-108, -181, -114, -192, -71, -150, -3, -80, +84, -10, 148, 33, 203, 48, 226, 49, +191, 40, 104, 18, 2, -8, -95, -36, +-155, -65, -155, -102, -87, -140, 32, -156, +182, -127, 276, -56, 297, 43, 261, 132, +158, 183, 6, 164, -140, 64, -245, -92, +-238, -244, -137, -328, 0, -304, 154, -172, +303, 28, 386, 220, 373, 327, 245, 299, +43, 139, -162, -92, -312, -299, -376, -405, +-286, -366, -53, -195, 219, 36, 425, 234, +502, 325, 427, 271, 252, 107, -5, -92, +-268, -246, -408, -304, -381, -254, -225, -132, +25, 2, 288, 93, 483, 120, 525, 94, +375, 46, 90, 1, -175, -29, -326, -52, +-332, -72, -205, -96, -6, -122, 175, -137, +283, -119, 278, -66, 212, 12, 152, 94, +101, 153, 41, 159, -15, 101, -89, -16, +-160, -165, -185, -293, -138, -339, -1, -269, +210, -92, 378, 135, 428, 329, 335, 393, +122, 283, -125, 27, -305, -268, -370, -474, +-274, -500, -42, -335, 219, -45, 404, 247, +451, 422, 334, 411, 122, 228, -106, -41, +-269, -281, -292, -411, -163, -391, 25, -246, +199, -37, 288, 154, 266, 259, 172, 247, +55, 145, -56, -3, -98, -139, -72, -222, +-11, -224, 55, -153, 103, -55, 118, 20, +111, 46, 75, 33, 30, 11, 6, -2, +22, 4, 49, 27, 79, 42, 92, 11, +68, -68, 21, -160, -25, -213, -50, -198, +-7, -108, 72, 25, 147, 159, 190, 233, +158, 207, 63, 84, -35, -87, -111, -239, +-119, -319, -43, -303, 89, -184, 206, -2, +253, 173, 193, 274, 56, 265, -82, 150, +-155, -24, -150, -197, -46, -305, 94, -311, +212, -215, 266, -63, 223, 83, 116, 168, +3, 183, -119, 139, -183, 62, -147, -28, +-30, -107, 114, -165, 214, -198, 231, -205, +188, -167, 100, -75, 8, 58, -48, 181, +-38, 243, -5, 205, 12, 72, 10, -112, +-8, -276, -3, -351, 49, -292, 100, -126, +166, 71, 212, 212, 194, 259, 113, 204, +-19, 75, -157, -87, -223, -218, -204, -277, +-76, -254, 129, -172, 335, -51, 438, 86, +379, 201, 175, 240, -94, 174, -310, 22, +-373, -153, -283, -282, -61, -312, 186, -224, +358, -49, 413, 132, 334, 230, 165, 199, +-2, 76, -156, -67, -249, -164, -251, -187, +-165, -143, -6, -69, 170, -9, 288, 11, +324, 2, 269, -1, 148, 26, -6, 58, +-117, 53, -164, 8, -159, -62, -107, -131, +-28, -170, 65, -155, 179, -79, 247, 23, +258, 98, 206, 115, 92, 86, -40, 32, +-140, -33, -187, -101, -147, -151, -56, -168, +56, -144, 159, -92, 235, -16, 256, 76, +215, 152, 122, 165, -3, 108, -129, 0, +-194, -119, -195, -216, -115, -260, 27, -226, +180, -111, 305, 45, 334, 181, 230, 239, +65, 202, -111, 84, -215, -82, -205, -237, +-102, -305, 44, -256, 166, -115, 205, 43, +179, 152, 120, 175, 67, 127, 8, 36, +-43, -54, -64, -107, -48, -115, 5, -106, +67, -95, 107, -88, 137, -62, 110, -10, +31, 51, -38, 90, -55, 88, -12, 36, +63, -44, 108, -111, 116, -131, 91, -103, +42, -51, -15, -16, -31, -15, -1, -33, +46, -32, 78, 5, 79, 60, 56, 93, +36, 70, 2, -19, -16, -138, 5, -220, +54, -207, 104, -92, 129, 72, 94, 184, +32, 180, -44, 66, -103, -91, -95, -206, +-1, -215, 131, -114, 235, 41, 238, 153, +135, 152, -26, 42, -163, -103, -219, -201, +-152, -200, 11, -107, 191, 29, 300, 137, +287, 162, 159, 90, 1, -29, -130, -131, +-193, -172, -163, -157, -43, -110, 100, -47, +201, 27, 211, 84, 153, 113, 55, 107, +-41, 65, -103, -19, -81, -124, 6, -212, +102, -227, 148, -149, 122, -10, 42, 124, +-36, 190, -90, 157, -77, 48, 12, -85, +131, -170, 199, -161, 177, -74, 75, 16, +-37, 41, -114, -8, -125, -83, -67, -126, +50, -91, 150, 15, 189, 148, 156, 215, +81, 153, -1, -30, -54, -236, -73, -348, +-48, -305, -1, -132, 39, 92, 55, 259, +71, 290, 89, 184, 109, 6, 117, -151, +97, -217, 35, -194, -48, -125, -129, -67, +-144, -33, -73, -6, 47, 34, 161, 92, +221, 147, 191, 154, 110, 81, 14, -75, +-43, -242, -52, -324, -42, -263, -40, -94, +-45, 102, -46, 234, -7, 244, 79, 141, +189, -16, 260, -138, 239, -163, 106, -113, +-87, -60, -245, -56, -282, -93, -179, -121, +33, -94, 241, 6, 346, 161, 298, 287, +131, 292, -69, 131, -199, -139, -210, -387, +-105, -486, 37, -389, 144, -129, 163, 181, +114, 410, 44, 459, -3, 311, -6, 39, +27, -224, 47, -384, 48, -393, 22, -274, +-6, -89, -13, 93, -13, 206, -13, 216, +10, 154, 44, 68, 98, -1, 140, -54, +144, -100, 95, -146, 7, -184, -94, -200, +-149, -165, -125, -61, -28, 102, 82, 258, +168, 315, 193, 225, 154, 30, 77, -191, +-8, -346, -70, -367, -99, -243, -112, -38, +-81, 154, -11, 245, 88, 221, 189, 130, +234, 29, 193, -54, 88, -112, -63, -159, +-191, -186, -236, -192, -156, -159, 12, -63, +189, 92, 290, 235, 274, 294, 141, 219, +-40, 38, -182, -169, -195, -322, -97, -369, +47, -276, 154, -79, 162, 153, 82, 314, +-21, 340, -89, 235, -64, 43, 31, -188, +126, -364, 161, -394, 108, -253, 2, -3, +-85, 228, -120, 323, -68, 260, 33, 64, +127, -161, 160, -281, 116, -231, 28, -58, +-51, 114, -96, 158, -77, 57, -6, -111, +87, -217, 141, -166, 136, 34, 74, 251, +-11, 335, -78, 189, -95, -129, -61, -433, +17, -529, 86, -332, 125, 74, 115, 455, +65, 594, 11, 402, -20, -25, -31, -457, +-15, -652, -1, -505, 16, -91, 32, 346, +39, 557, 40, 442, 42, 95, 41, -285, +46, -483, 42, -403, 34, -96, 11, 247, +-27, 398, -64, 266, -63, -42, -13, -332, +66, -423, 126, -261, 146, 80, 110, 406, +41, 512, -36, 298, -88, -120, -93, -502, +-60, -632, -24, -439, 15, -23, 56, 398, +111, 612, 154, 496, 159, 124, 116, -288, +35, -511, -82, -456, -185, -191, -213, 101, +-130, 269, 23, 245, 177, 80, 263, -103, +256, -168, 145, -77, -25, 86, -163, 176, +-189, 119, -118, -58, 2, -245, 91, -337, +118, -264, 90, -43, 29, 220, -19, 380, +2, 357, 62, 170, 111, -81, 92, -291, +7, -388, -95, -341, -162, -167, -173, 51, +-82, 229, 73, 309, 223, 277, 301, 147, +268, -32, 130, -200, -54, -282, -227, -254, +-313, -139, -270, 2, -115, 101, 85, 114, +256, 65, 332, 3, 316, -6, 203, 48, +29, 115, -144, 125, -263, 34, -298, -161, +-231, -362, -87, -435, 110, -291, 285, 38, +362, 399, 307, 607, 141, 552, -77, 220, +-245, -256, -304, -653, -231, -765, -58, -531, +131, -64, 245, 411, 255, 693, 165, 667, +43, 349, -73, -112, -146, -489, -150, -626, +-83, -486, 4, -171, 73, 169, 95, 386, +86, 403, 64, 238, 35, 7, 5, -168, +1, -216, 8, -152, 8, -40, -23, 31, +-58, 24, -67, -45, -33, -108, 32, -101, +114, -4, 171, 129, 164, 224, 56, 203, +-95, 55, -197, -153, -181, -305, -56, -318, +124, -180, 255, 39, 262, 244, 109, 333, +-119, 258, -281, 49, -265, -177, -90, -317, +140, -316, 289, -194, 284, 3, 131, 201, +-71, 317, -192, 280, -158, 120, -32, -88, +83, -251, 106, -308, 39, -246, -57, -95, +-107, 101, -71, 227, 64, 216, 196, 100, +231, -33, 140, -102, -31, -83, -178, -29, +-214, 34, -151, 52, -16, -30, 108, -170, +155, -248, 125, -181, 56, 37, -3, 271, +-5, 386, 18, 335, 39, 111, 26, -219, +-38, -472, -113, -511, -121, -296, -51, 52, +65, 333, 155, 443, 170, 375, 101, 145, +-8, -123, -97, -291, -94, -292, -31, -168, +30, -46, 40, -11, 2, -5, -47, -5, +-45, 21, 10, 111, 98, 240, 162, 313, +147, 238, 53, -30, -72, -348, -166, -542, +-170, -535, -105, -296, -9, 108, 86, 481, +148, 657, 158, 541, 144, 192, 106, -196, +42, -471, -65, -555, -178, -407, -241, -138, +-210, 125, -98, 290, 79, 314, 259, 246, +350, 152, 291, 22, 106, -87, -128, -149, +-284, -188, -296, -198, -175, -170, 12, -102, +154, 24, 173, 132, 105, 183, 16, 207, +2, 180, 68, 81, 130, -47, 112, -189, +3, -272, -175, -262, -301, -181, -275, -31, +-77, 164, 187, 294, 365, 310, 354, 191, +176, 3, -79, -152, -267, -248, -283, -278, +-140, -197, 56, -52, 186, 95, 168, 190, +44, 210, -96, 187, -167, 115, -107, -44, +54, -206, 209, -273, 267, -213, 158, -57, +-53, 117, -243, 236, -315, 261, -218, 126, +13, -104, 230, -267, 333, -256, 259, -93, +50, 109, -165, 214, -272, 195, -225, 50, +-46, -154, 132, -265, 230, -183, 214, 30, +86, 239, -84, 296, -199, 187, -221, -21, +-123, -245, 35, -365, 171, -289, 239, -76, +207, 160, 70, 302, -93, 308, -220, 211, +-227, 46, -109, -149, 43, -281, 153, -318, +189, -248, 122, -89, 19, 117, -55, 312, +-68, 413, -31, 323, -11, 81, -39, -219, +-64, -455, -82, -500, -62, -316, 21, 21, +137, 376, 226, 547, 231, 460, 112, 178, +-67, -169, -232, -420, -321, -452, -288, -286, +-128, -11, 100, 208, 304, 250, 363, 145, +268, -2, 88, -94, -105, -43, -245, 98, +-262, 231, -166, 249, -25, 67, 64, -252, +76, -507, 61, -552, 59, -309, 68, 121, +94, 521, 110, 721, 75, 603, -22, 172, +-136, -335, -211, -669, -175, -679, -56, -375, +81, 52, 184, 395, 214, 545, 131, 414, +-12, 95, -126, -209, -129, -345, -48, -271, +27, -80, 46, 70, 27, 153, -47, 136, +-117, 15, -99, -103, 25, -113, 195, -17, +298, 130, 226, 192, 33, 132, -200, 4, +-385, -162, -410, -296, -246, -283, 34, -126, +330, 120, 465, 318, 403, 348, 223, 239, +-42, 71, -304, -123, -431, -239, -401, -240, +-208, -157, 46, -50, 226, -7, 309, -26, +274, 1, 121, 83, -17, 193, -98, 290, +-113, 290, -47, 151, -1, -94, -25, -382, +-62, -527, -129, -413, -159, -109, -90, 237, +45, 471, 222, 480, 341, 300, 280, -3, +108, -285, -115, -376, -333, -264, -405, -79, +-302, 81, -69, 144, 233, 127, 398, 76, +349, 11, 157, -11, -106, 47, -302, 76, +-315, 19, -190, -90, 56, -181, 263, -193, +266, -116, 123, 13, -68, 196, -227, 325, +-229, 281, -102, 93, 91, -123, 260, -287, +249, -327, 62, -248, -139, -63, -270, 176, +-253, 318, -95, 269, 90, 120, 241, -49, +290, -167, 167, -196, -14, -126, -156, 23, +-226, 160, -192, 141, -96, 7, 17, -121, +133, -177, 145, -133, 71, -7, 16, 137, +-28, 265, -52, 256, -17, 76, 27, -131, +75, -244, 75, -246, -24, -146, -132, -21, +-182, 109, -176, 210, -78, 188, 58, 78, +181, 5, 271, -35, 255, -61, 123, -94, +-30, -124, -193, -86, -316, -2, -332, 27, +-223, 55, -3, 106, 235, 123, 351, 77, +322, -15, 150, -80, -96, -42, -264, -16, +-276, -47, -149, -47, 63, -16, 189, 1, +152, 7, -14, 2, -193, 61, -241, 130, +-104, 86, 120, -7, 321, -39, 355, -55, +179, -63, -111, -72, -373, -50, -461, 36, +-307, 82, -20, 29, 255, 7, 395, 15, +352, 4, 169, -14, -66, -23, -246, 23, +-266, 102, -185, 67, -89, -30, -6, -99, +50, -150, 82, -152, 108, -64, 116, 83, +134, 273, 121, 337, 26, 179, -103, -70, +-205, -295, -247, -421, -191, -336, -96, -87, +35, 249, 191, 519, 276, 503, 255, 221, +160, -122, 12, -420, -117, -530, -244, -387, +-335, -82, -280, 274, -121, 495, 41, 421, +204, 183, 304, -87, 329, -300, 261, -334, +50, -193, -205, 31, -369, 245, -427, 258, +-314, 77, -63, -122, 224, -247, 442, -232, +433, -41, 179, 195, -110, 380, -321, 370, +-369, 89, -216, -256, 22, -443, 223, -432, +285, -192, 127, 160, -89, 440, -208, 522, +-201, 306, -58, -100, 115, -390, 194, -472, +183, -349, 48, -51, -148, 263, -237, 456, +-184, 442, -51, 183, 97, -129, 162, -326, +162, -400, 88, -315, -68, -76, -180, 186, +-151, 382, -45, 388, 64, 195, 102, -43, +65, -245, 7, -362, -63, -284, -126, -68, +-93, 173, 22, 328, 136, 285, 159, 99, +77, -82, -28, -225, -102, -244, -174, -121, +-194, 32, -108, 149, 33, 171, 129, 72, +157, -14, 150, -45, 143, -40, 76, 12, +-66, 43, -199, 7, -248, -32, -225, -82, +-140, -99, -9, -27, 169, 59, 312, 109, +305, 119, 143, 43, -42, -34, -183, -59, +-266, -62, -265, -20, -154, 43, 21, 42, +149, 6, 158, -52, 123, -100, 92, -60, +37, 37, -48, 118, -107, 177, -112, 142, +-72, 25, -56, -97, -52, -194, -4, -209, +67, -99, 91, 36, 69, 150, 25, 200, +9, 151, -21, 57, -84, -26, -108, -107, +-64, -116, -27, -67, -10, -28, 12, -12, +71, -19, 121, -27, 97, 30, 7, 95, +-80, 136, -145, 163, -156, 123, -106, 2, +-1, -135, 126, -250, 190, -252, 120, -140, +-18, -4, -134, 135, -175, 262, -130, 286, +-18, 207, 114, 59, 187, -104, 127, -216, +0, -276, -109, -279, -166, -145, -160, 71, +-99, 264, -10, 368, 93, 329, 139, 148, +113, -103, 58, -357, 2, -455, -37, -307, +-62, -9, -95, 288, -81, 462, -43, 402, +-39, 146, -44, -191, -13, -440, 44, -437, +107, -184, 112, 137, 71, 378, 16, 409, +-65, 208, -140, -99, -135, -346, -71, -392, +18, -178, 71, 133, 44, 358, 1, 387, +1, 189, 1, -130, 10, -375, 16, -428, +1, -236, -33, 94, -84, 359, -111, 432, +-35, 297, 70, 6, 138, -264, 153, -380, +73, -295, -90, -47, -236, 215, -316, 325, +-226, 258, 15, 46, 248, -189, 370, -318, +330, -281, 118, -80, -140, 207, -337, 387, +-379, 372, -217, 188, 8, -97, 141, -351, +178, -448, 109, -348, 7, -65, -33, 254, +-20, 436, 35, 419, 86, 225, 29, -78, +-66, -333, -139, -426, -179, -296, -123, 3, +-13, 292, 66, 407, 140, 321, 143, 52, +64, -272, -22, -469, -115, -411, -160, -113, +-94, 281, -2, 534, 106, 521, 176, 248, +113, -166, -22, -507, -166, -575, -287, -345, +-243, 64, -57, 419, 149, 516, 300, 329, +300, -19, 148, -346, -39, -447, -229, -280, +-303, 44, -213, 346, -68, 448, 77, 280, +179, -28, 154, -320, 66, -436, -51, -319, +-155, -57, -147, 210, -48, 380, 67, 351, +162, 157, 145, -79, 38, -254, -96, -290, +-217, -176, -231, -5, -111, 178, 27, 285, +136, 228, 178, 47, 131, -162, 34, -320, +-77, -307, -139, -137, -105, 112, -49, 358, +-6, 442, 20, 290, 19, 11, 2, -297, +-22, -460, -54, -374, -34, -123, 23, 178, +69, 401, 72, 376, 29, 160, -33, -123, +-89, -345, -144, -347, -125, -141, -23, 116, +75, 348, 118, 409, 101, 245, 37, -34, +-28, -334, -96, -508, -129, -404, -94, -133, +-30, 196, 27, 480, 61, 544, 50, 366, +35, 34, 9, -356, -43, -546, -71, -450, +-55, -179, -38, 192, -22, 476, -16, 480, +10, 261, 47, -114, 46, -438, 13, -467, +-10, -253, -55, 70, -108, 396, -128, 484, +-78, 308, 43, -10, 158, -354, 167, -476, +85, -303, -47, -23, -169, 277, -226, 430, +-185, 316, -55, 60, 118, -224, 190, -404, +128, -296, 22, -43, -63, 201, -106, 376, +-91, 333, -32, 105, 45, -142, 64, -358, +-12, -369, -119, -153, -156, 94, -120, 297, +-19, 373, 96, 220, 185, -9, 214, -237, +128, -366, -71, -246, -232, -2, -267, 203, +-201, 340, -72, 279, 68, 67, 155, -151, +163, -328, 55, -316, -62, -86, -74, 131, +-23, 280, 17, 313, 38, 158, 6, -51, +-50, -230, -116, -324, -170, -197, -128, 13, +10, 158, 107, 262, 127, 256, 85, 127, +38, -27, 8, -209, -43, -285, -97, -205, +-72, -105, -44, 27, -71, 207, -86, 296, +-49, 278, 20, 133, 80, -95, 63, -235, +32, -279, 20, -256, -32, -78, -85, 144, +-69, 278, -9, 277, 71, 117, 77, -75, +-20, -166, -106, -205, -159, -141, -202, 32, +-140, 171, 25, 207, 202, 119, 295, -53, +228, -145, 50, -156, -113, -127, -263, -13, +-325, 126, -227, 188, -58, 164, 97, 34, +181, -95, 137, -132, 75, -121, 32, -69, +-40, 48, -75, 141, -55, 159, -41, 71, +-27, -82, -70, -168, -115, -147, -60, -77, +7, 56, 41, 195, 94, 248, 90, 161, +33, -39, -48, -231, -154, -275, -170, -187, +-65, -21, 26, 175, 96, 302, 113, 266, +50, 78, -26, -160, -113, -284, -173, -229, +-91, -51, 8, 153, 38, 304, 38, 291, +-8, 96, -52, -184, -38, -383, -22, -377, +43, -164, 117, 134, 72, 398, -35, 502, +-138, 361, -220, 30, -174, -316, -64, -512, +47, -453, 173, -198, 204, 125, 80, 384, +-70, 452, -180, 274, -177, -15, -65, -259, +41, -328, 115, -186, 132, 54, 6, 253, +-154, 324, -228, 173, -182, -114, -24, -354, +138, -414, 190, -247, 156, 74, 37, 350, +-131, 475, -224, 378, -187, 80, -52, -227, +102, -380, 149, -334, 96, -108, 0, 124, +-125, 231, -224, 195, -199, 30, -73, -154, +91, -194, 205, -96, 203, 96, 107, 258, +-25, 262, -168, 140, -244, -30, -210, -206, +-91, -266, 52, -197, 139, -73, 114, 58, +39, 117, -53, 99, -137, 99, -139, 84, +-36, 55, 91, 40, 172, 3, 140, -55, +12, -95, -135, -118, -251, -64, -284, 45, +-175, 95, 7, 80, 182, 24, 258, -64, +182, -92, 31, -56, -96, 34, -173, 150, +-159, 182, -67, 84, 29, -56, 57, -189, +-5, -226, -103, -127, -132, 46, -93, 217, +-18, 283, 88, 165, 166, -48, 159, -243, +72, -330, -80, -241, -199, -8, -219, 248, +-175, 424, -103, 391, 9, 168, 115, -109, +169, -332, 133, -417, 28, -317, -67, -98, +-129, 140, -175, 280, -143, 265, -29, 162, +87, 57, 137, -35, 101, -73, -10, -63, +-115, -36, -191, -35, -195, -76, -83, -116, +83, -86, 198, -5, 203, 79, 74, 143, +-98, 168, -226, 140, -280, 54, -219, -64, +-20, -134, 169, -137, 253, -98, 212, -51, +66, 27, -103, 126, -240, 188, -305, 153, +-218, 38, -35, -101, 119, -216, 201, -277, +189, -225, 82, -13, -38, 271, -156, 440, +-209, 414, -137, 209, -16, -80, 62, -357, +78, -513, 10, -449, -80, -161, -138, 165, +-136, 357, -23, 379, 162, 276, 248, 117, +199, -37, 20, -139, -226, -118, -388, -47, +-387, -53, -222, -136, 69, -199, 318, -183, +389, -67, 267, 85, 20, 245, -215, 380, +-303, 359, -263, 155, -115, -97, 57, -282, +117, -330, 48, -269, -60, -150, -137, 22, +-107, 183, 16, 208, 137, 161, 198, 108, +154, 73, -20, 52, -206, -11, -316, -94, +-302, -115, -159, -121, 14, -124, 142, -58, +231, 54, 228, 146, 127, 167, -6, 75, +-129, -18, -214, -68, -237, -106, -224, -98, +-124, -17, 37, 69, 156, 127, 202, 107, +164, 41, 38, 23, -94, 4, -186, -59, +-209, -103, -115, -130, 20, -124, 72, -75, +53, -3, -28, 126, -102, 285, -107, 308, +-54, 189, 54, 3, 167, -200, 155, -321, +23, -327, -145, -222, -285, 2, -314, 196, +-199, 244, -7, 200, 211, 129, 327, 58, +275, 32, 101, 1, -127, -16, -313, -30, +-364, -114, -283, -209, -93, -202, 128, -97, +244, 67, 203, 202, 80, 229, -72, 182, +-170, 81, -175, -63, -87, -115, 40, -64, +116, 17, 69, 60, -58, 1, -182, -124, +-238, -194, -177, -194, -10, -95, 164, 127, +276, 332, 239, 404, 49, 307, -196, 49, +-350, -206, -347, -346, -190, -353, 52, -220, +255, 4, 312, 171, 183, 239, -67, 185, +-268, 58, -333, -9, -238, -19, -29, -12, +173, 18, 247, 14, 176, -40, -16, -100, +-207, -148, -264, -127, -179, 0, -12, 112, +148, 187, 189, 206, 116, 133, -54, 28, +-246, -72, -313, -159, -216, -162, -40, -108, +159, -66, 285, 2, 268, 86, 135, 145, +-79, 193, -280, 157, -341, 54, -282, -56, +-139, -171, 28, -240, 148, -190, 200, -75, +173, 66, 43, 177, -76, 170, -106, 111, +-103, 60, -72, 16, -31, 37, -19, 69, +-20, 35, -88, -54, -177, -190, -180, -317, +-89, -284, 44, -103, 199, 159, 279, 417, +247, 502, 104, 374, -156, 101, -386, -243, +-438, -477, -342, -487, -122, -321, 131, -51, +317, 211, 368, 330, 242, 341, -18, 245, +-221, 79, -303, -46, -278, -117, -135, -155, +35, -141, 137, -112, 138, -70, 5, 9, +-145, 65, -185, 90, -112, 121, 29, 101, +180, 64, 223, 22, 135, -36, -76, -73, +-339, -77, -452, -92, -333, -79, -75, -30, +229, 24, 431, 95, 434, 135, 230, 120, +-117, 90, -443, 13, -545, -81, -412, -133, +-135, -132, 165, -78, 345, 29, 363, 104, +223, 148, -47, 153, -262, 71, -305, -36, +-217, -115, -83, -142, 40, -83, 100, 13, +90, 83, -3, 120, -121, 87, -142, -28, +-71, -118, 8, -137, 63, -58, 68, 86, +50, 184, -3, 192, -91, 111, -167, -51, +-154, -204, -91, -243, -37, -149, 18, 44, +77, 221, 110, 264, 58, 194, -73, 30, +-156, -158, -158, -260, -110, -216, -39, -66, +77, 113, 160, 205, 138, 187, -4, 106, +-184, -24, -263, -141, -224, -173, -129, -121, +15, -12, 174, 77, 262, 121, 184, 130, +-17, 112, -217, 39, -281, -46, -248, -101, +-150, -98, 28, -52, 196, -2, 238, 50, +113, 98, -101, 97, -252, 32, -269, -54, +-186, -91, -32, -71, 175, -17, 285, 31, +229, 80, 9, 87, -245, 38, -361, -48, +-326, -108, -182, -84, 52, -12, 277, 60, +344, 108, 202, 116, -59, 70, -285, -27, +-347, -114, -281, -125, -94, -43, 155, 51, +311, 121, 271, 138, 46, 87, -244, -14, +-411, -136, -374, -206, -187, -151, 91, -12, +359, 124, 435, 217, 267, 226, -71, 137, +-374, -7, -478, -171, -394, -237, -180, -179, +109, -68, 322, 49, 334, 142, 155, 171, +-93, 152, -253, 88, -235, -1, -125, -31, +18, -33, 137, -54, 135, -65, -11, -85, +-223, -83, -350, -51, -264, -20, -41, 35, +178, 128, 336, 161, 379, 137, 203, 83, +-110, -15, -415, -85, -551, -132, -435, -171, +-172, -121, 126, -23, 386, 65, 472, 148, +320, 185, 10, 150, -299, 92, -447, -29, +-381, -134, -223, -142, 14, -110, 240, -34, +296, 57, 169, 81, -48, 68, -210, 21, +-227, -63, -145, -72, -21, 2, 123, 70, +176, 140, 49, 114, -144, -10, -308, -127, +-307, -222, -134, -220, 81, -48, 266, 171, +351, 336, 245, 371, -19, 191, -299, -70, +-457, -276, -405, -395, -202, -304, 16, -64, +231, 165, 323, 308, 238, 284, 51, 112, +-139, -26, -237, -107, -203, -123, -105, -30, +-12, 33, 60, 23, 43, -32, -63, -142, +-165, -172, -220, -62, -145, 87, 8, 235, +149, 327, 245, 253, 256, 102, 116, -85, +-116, -257, -322, -281, -425, -203, -364, -104, +-182, 28, 40, 117, 252, 152, 333, 182, +257, 150, 78, 92, -114, 69, -236, -16, +-242, -112, -187, -178, -95, -223, 8, -181, +43, -74, 5, 25, -36, 161, -55, 275, +-21, 269, 25, 202, 46, 76, 56, -82, +31, -176, -58, -251, -148, -255, -201, -136, +-195, 7, -106, 114, 21, 198, 122, 202, +189, 170, 151, 102, 14, -37, -149, -127, +-265, -148, -264, -155, -151, -109, -3, -28, +131, 56, 196, 128, 136, 126, -4, 53, +-130, 26, -219, 6, -200, -13, -109, 4, +-6, 19, 80, 32, 105, 20, 58, -54, +-32, -95, -129, -53, -185, -3, -139, 33, +-31, 62, 75, 50, 167, 38, 140, -6, +12, -46, -157, -9, -294, 59, -313, 75, +-187, 32, 11, -43, 188, -105, 279, -114, +218, -94, 53, -11, -145, 141, -300, 229, +-291, 208, -188, 96, -47, -40, 88, -149, +161, -204, 122, -205, 12, -93, -105, 89, +-162, 205, -110, 218, -40, 144, 22, 17, +68, -117, 29, -230, -47, -239, -134, -96, +-164, 117, -98, 243, 15, 259, 63, 161, +58, -5, 16, -181, -78, -291, -155, -231, +-180, -14, -95, 195, 70, 275, 170, 230, +181, 89, 108, -86, -46, -215, -240, -244, +-363, -111, -364, 82, -205, 184, 40, 158, +244, 75, 359, -33, 336, -115, 157, -138, +-106, -85, -341, 52, -426, 150, -353, 127, +-186, 53, 0, -30, 169, -88, 230, -107, +154, -73, 26, 21, -60, 153, -79, 191, +-65, 128, -50, 30, -35, -90, -55, -182, +-124, -212, -202, -157, -196, 12, -92, 194, +52, 258, 162, 211, 189, 96, 135, -76, +26, -206, -124, -259, -213, -178, -183, 18, +-84, 169, -19, 200, -14, 150, -54, 33, +-94, -93, -114, -143, -96, -100, 15, 56, +155, 227, 214, 250, 172, 147, 22, -40, +-157, -242, -308, -360, -379, -336, -326, -155, +-128, 154, 102, 405, 255, 466, 299, 363, +215, 113, 75, -192, -98, -420, -256, -493, +-285, -335, -220, -23, -124, 257, -40, 403, +39, 396, 76, 212, 86, -39, 38, -253, +-25, -328, -23, -196, -21, 28, -22, 206, +-31, 279, -54, 200, -58, -3, -89, -221, +-151, -336, -178, -269, -109, -28, -28, 211, +63, 349, 143, 324, 182, 139, 163, -114, +30, -314, -136, -350, -245, -177, -285, 92, +-252, 289, -157, 336, -13, 213, 119, -27, +200, -242, 149, -332, 52, -220, -32, 28, +-105, 265, -133, 353, -109, 268, -37, 56, +12, -184, -35, -326, -140, -306, -200, -128, +-172, 102, -90, 250, 61, 255, 213, 134, +294, -29, 222, -160, 12, -175, -207, -84, +-329, 57, -334, 153, -248, 139, -97, 33, +72, -82, 173, -138, 157, -99, 65, 33, +-1, 168, -28, 224, -47, 157, -65, -34, +-52, -225, -37, -319, -66, -259, -137, -55, +-176, 202, -150, 366, -72, 383, 15, 225, +105, -50, 176, -284, 174, -396, 72, -339, +-91, -123, -219, 109, -237, 274, -176, 331, +-79, 251, 22, 86, 98, -64, 66, -173, +-35, -166, -129, -80, -134, -5, -46, 68, +51, 86, 125, 24, 142, -46, 67, -99, +-78, -92, -230, 10, -306, 118, -263, 167, +-117, 173, 19, 67, 149, -81, 225, -185, +203, -216, 101, -116, -55, 54, -167, 160, +-213, 188, -226, 131, -197, -14, -93, -124, +36, -144, 104, -66, 121, 103, 58, 201, +0, 178, -53, 75, -104, -88, -96, -233, +-33, -265, 36, -195, 36, -23, -41, 170, +-140, 241, -170, 223, -149, 151, -96, 28, +45, -62, 156, -108, 186, -105, 93, -53, +-69, -35, -183, -81, -214, -89, -178, -63, +-79, 6, 54, 131, 125, 245, 107, 325, +3, 302, -119, 105, -147, -168, -138, -383, +-96, -476, -23, -403, 67, -180, 120, 109, +97, 397, 17, 518, -59, 419, -113, 207, +-172, -32, -186, -230, -130, -328, -41, -319, +48, -213, 73, -61, 66, 36, 53, 97, +26, 178, -24, 235, -56, 243, -61, 178, +-57, 65, -89, -58, -142, -177, -144, -270, +-91, -247, -37, -100, 15, 64, 65, 169, +115, 177, 118, 111, 50, 21, -47, -78, +-118, -121, -166, -56, -181, 71, -167, 144, +-84, 140, 39, 60, 123, -42, 113, -118, +45, -158, -35, -123, -114, -3, -168, 102, +-142, 117, -15, 68, 116, 5, 129, -20, +40, 9, -100, 42, -194, 104, -223, 141, +-155, 66, 7, -99, 183, -250, 231, -311, +107, -230, -81, -58, -219, 141, -237, 336, +-167, 404, -35, 285, 135, 72, 194, -148, +107, -272, -68, -268, -181, -183, -182, -39, +-114, 126, -27, 185, 59, 140, 112, 59, +46, -24, -77, -54, -160, -58, -142, -56, +-32, -5, 51, 47, 112, 50, 135, 42, +99, 31, -37, 13, -191, 8, -262, -44, +-227, -86, -129, -68, -32, -50, 100, -30, +212, 13, 211, 52, 111, 99, -35, 122, +-131, 95, -182, 91, -183, 97, -143, 42, +-40, -33, 47, -132, 45, -214, -16, -234, +-93, -206, -119, -96, -97, 111, -32, 290, +94, 367, 208, 326, 218, 152, 86, -56, +-97, -234, -257, -348, -316, -297, -283, -122, +-166, 61, 8, 182, 135, 205, 164, 135, +114, 44, 50, -53, 15, -95, 6, -32, +5, 49, 0, 92, -10, 75, -75, -3, +-178, -70, -262, -103, -259, -99, -169, -29, +-22, 70, 133, 103, 262, 65, 298, -39, +210, -137, 38, -149, -143, -81, -251, 59, +-256, 236, -182, 344, -69, 311, 29, 134, +70, -123, 23, -341, -57, -433, -112, -384, +-78, -183, 13, 85, 125, 311, 208, 406, +209, 344, 108, 182, -80, 10, -267, -127, +-371, -191, -345, -173, -194, -116, 18, -71, +224, -63, 317, -74, 275, -45, 102, 19, +-97, 107, -220, 182, -230, 212, -137, 174, +-16, 67, 79, -70, 81, -158, 0, -158, +-92, -94, -136, 2, -96, 80, -24, 102, +57, 68, 78, -31, 44, -129, -34, -163, +-119, -119, -144, -13, -98, 123, 18, 226, +122, 276, 160, 235, 110, 89, -16, -85, +-170, -235, -308, -317, -319, -291, -212, -182, +-15, -4, 169, 183, 278, 286, 291, 277, +189, 195, 25, 52, -154, -79, -258, -157, +-258, -171, -185, -91, -82, 17, -1, 77, +74, 89, 83, 40, 41, -48, -26, -115, +-54, -143, -35, -105, -4, 18, 37, 120, +81, 172, 106, 178, 58, 123, -47, 49, +-151, -11, -223, -58, -227, -60, -176, -53, +-55, -96, 97, -148, 221, -176, 235, -153, +157, -25, 43, 141, -68, 295, -147, 381, +-165, 310, -111, 91, -30, -162, -1, -365, +-34, -405, -71, -260, -75, -31, -50, 207, +11, 338, 81, 269, 147, 75, 142, -147, +54, -282, -65, -235, -136, -52, -153, 162, +-126, 338, -73, 346, -9, 177, 42, -61, +24, -281, -38, -362, -69, -267, -53, -92, +-3, 104, 44, 229, 88, 195, 91, 59, +34, -80, -90, -151, -184, -73, -184, 84, +-109, 226, 8, 299, 97, 218, 128, -8, +79, -259, -49, -438, -179, -441, -232, -249, +-165, 25, -46, 297, 97, 483, 199, 471, +238, 301, 168, 45, -8, -206, -182, -342, +-287, -348, -285, -261, -186, -89, -17, 81, +159, 179, 238, 207, 189, 154, 23, 64, +-129, -5, -204, -69, -164, -87, -41, -47, +106, -6, 220, 17, 201, 26, 60, 6, +-128, 4, -248, 29, -262, 55, -192, 94, +-45, 99, 103, 24, 216, -103, 210, -235, +124, -294, 19, -216, -55, -22, -89, 221, +-104, 426, -75, 460, -30, 295, 6, 3, +-9, -298, -54, -458, -71, -416, -69, -219, +-38, 44, 0, 248, 80, 286, 142, 178, +136, 12, 48, -110, -56, -102, -118, 5, +-138, 142, -108, 227, -36, 197, 39, 45, +49, -148, -38, -297, -156, -328, -216, -229, +-157, -64, -21, 99, 165, 208, 322, 222, +360, 166, 208, 86, -79, 27, -344, 12, +-451, 32, -385, 38, -193, 18, 52, -41, +236, -137, 267, -228, 143, -263, -32, -208, +-118, -56, -85, 137, 16, 299, 99, 376, +128, 328, 52, 161, -101, -43, -255, -212, +-289, -284, -164, -242, 22, -134, 166, -17, +219, 62, 181, 70, 65, 25, -73, -20, +-146, -32, -131, 14, -43, 92, 24, 151, +72, 181, 95, 160, 87, 84, 36, -20, +-53, -125, -133, -209, -178, -237, -168, -219, +-104, -144, 18, -6, 175, 137, 267, 236, +255, 270, 126, 210, -21, 91, -140, -30, +-200, -112, -176, -120, -87, -65, 14, -26, +42, -29, 2, -89, -62, -170, -85, -187, +-39, -97, 37, 78, 142, 286, 201, 402, +195, 349, 84, 147, -77, -130, -199, -349, +-239, -388, -194, -253, -119, -15, -19, 195, +48, 258, 55, 163, 13, -24, -30, -202, +-7, -236, 45, -104, 119, 103, 144, 281, +118, 319, 18, 190, -135, -24, -273, -230, +-327, -316, -250, -229, -96, -43, 78, 128, +201, 209, 240, 151, 186, 9, 56, -128, +-61, -191, -122, -115, -106, 65, -64, 233, +-14, 306, 19, 239, 21, 52, -18, -165, +-77, -333, -107, -379, -92, -262, -38, -57, +29, 142, 97, 269, 162, 282, 187, 205, +149, 83, 56, -36, -44, -93, -128, -86, +-166, -61, -170, -46, -114, -49, -31, -72, +45, -77, 89, -55, 105, 9, 115, 105, +122, 175, 110, 170, 63, 91, -3, -43, +-72, -178, -134, -245, -159, -204, -134, -55, +-29, 149, 93, 304, 176, 342, 179, 232, +107, 8, -24, -242, -167, -414, -248, -430, +-220, -268, -73, 5, 115, 273, 242, 432, +273, 422, 177, 259, 7, 23, -178, -187, +-277, -290, -247, -260, -119, -145, 19, -26, +88, 54, 86, 62, 27, 17, -43, -31, +-78, -36, -47, 15, 56, 104, 128, 173, +135, 183, 50, 123, -60, 5, -171, -128, +-248, -218, -242, -238, -149, -164, 6, -29, +125, 107, 187, 196, 188, 208, 145, 126, +69, -10, -35, -140, -83, -200, -95, -144, +-74, -5, -83, 143, -90, 234, -71, 206, +-38, 65, 5, -119, 45, -258, 110, -275, +145, -157, 132, 8, 74, 145, 7, 202, +-21, 161, -47, 71, -50, -1, -44, -15, +-15, 31, -6, 69, -16, 34, -24, -62, +-2, -177, 48, -248, 78, -207, 97, -62, +99, 131, 73, 279, 17, 294, -54, 176, +-82, 2, -62, -152, -19, -207, 7, -148, +31, -29, 39, 82, 38, 113, 20, 39, +6, -70, 5, -144, -4, -141, -39, -46, +-79, 103, -86, 231, -47, 281, 19, 216, +72, 55, 101, -131, 97, -287, 29, -351, +-66, -291, -148, -133, -161, 77, -117, 268, +-40, 361, 26, 329, 72, 186, 75, -29, +29, -223, -29, -321, -63, -299, -42, -163, +14, 22, 51, 171, 54, 240, 6, 208, +-77, 92, -162, -33, -192, -117, -146, -136, +-21, -85, 117, -14, 200, 44, 216, 66, +151, 46, 29, 5, -93, -25, -172, -41, +-158, -30, -80, 0, 25, 18, 98, 32, +128, 34, 90, 17, 0, 0, -89, -19, +-134, -31, -84, -22, 21, -9, 142, -3, +229, 15, 220, 31, 126, 31, -31, 21, +-142, 2, -174, -2, -96, 15, 11, 23, +94, 27, 117, 21, 58, -18, -20, -73, +-81, -116, -56, -122, 41, -67, 145, 21, +188, 106, 139, 166, 49, 165, -68, 95, +-131, 0, -146, -85, -84, -125, -8, -111, +28, -77, 23, -38, -16, 1, -29, 8, +-14, 6, 39, 20, 95, 58, 128, 108, +111, 129, 27, 92, -73, 24, -170, -66, +-205, -153, -196, -177, -144, -128, -63, -34, +36, 66, 114, 120, 150, 122, 148, 85, +106, 14, 47, -52, -30, -70, -99, -50, +-124, -14, -113, 14, -89, 20, -72, 16, +-59, 7, -50, -9, -30, -4, -11, 23, +40, 41, 111, 46, 166, 33, 159, 0, +101, -40, 16, -90, -72, -122, -137, -110, +-152, -57, -93, 29, 10, 137, 88, 223, +110, 242, 77, 168, 14, 13, -56, -171, +-77, -311, -23, -351, 103, -253, 230, -47, +275, 183, 214, 341, 71, 372, -115, 267, +-268, 79, -318, -123, -226, -262, -41, -291, +158, -224, 285, -107, 321, 17, 269, 112, +141, 163, -8, 176, -124, 149, -169, 93, +-156, 26, -118, -58, -55, -134, 6, -172, +57, -163, 63, -104, 65, -12, 63, 71, +76, 131, 65, 153, 17, 126, -23, 68, +-62, 0, -78, -67, -85, -104, -50, -112, +6, -91, 43, -35, 42, 30, -5, 74, +-38, 87, -87, 47, -109, -30, -118, -89, +-85, -114, -11, -80, 64, 14, 131, 118, +163, 190, 164, 189, 85, 100, -45, -27, +-183, -146, -268, -226, -259, -217, -194, -132, +-53, -18, 99, 93, 221, 152, 252, 155, +207, 131, 117, 77, 24, 22, -54, -3, +-129, -21, -149, -51, -132, -90, -93, -138, +-37, -149, 35, -108, 127, -28, 194, 86, +208, 183, 160, 193, 96, 115, 11, -23, +-62, -150, -101, -178, -85, -105, -29, 42, +27, 196, 57, 241, 74, 142, 82, -59, +73, -263, 55, -344, 39, -256, 38, -57, +49, 171, 41, 307, 28, 271, 25, 112, +26, -61, 3, -139, -21, -78, -40, 54, +-40, 155, -38, 136, -32, -41, -1, -300, +57, -465, 95, -414, 94, -132, 64, 267, +10, 595, -58, 699, -116, 510, -139, 96, +-96, -353, -9, -636, 63, -644, 88, -399, +71, -39, 24, 268, -35, 414, -88, 352, +-94, 151, -63, -50, -30, -155, -28, -129, +-26, -11, -19, 112, 4, 162, 32, 99, +47, -52, 55, -212, 26, -295, -29, -264, +-91, -122, -112, 71, -76, 239, -15, 314, +60, 267, 109, 128, 141, -29, 99, -135, +15, -154, -77, -97, -126, -12, -109, 38, +-59, 12, 32, -78, 114, -183, 176, -236, +169, -176, 105, -1, 22, 236, -54, 419, +-72, 449, -62, 305, 1, 33, 70, -264, +130, -456, 140, -463, 107, -296, 57, -29, +-9, 195, -50, 281, -70, 224, -39, 74, +21, -68, 90, -105, 140, -22, 142, 123, +111, 223, 33, 185, -45, 17, -107, -210, +-102, -393, -45, -409, 36, -232, 104, 54, +127, 332, 94, 464, 10, 387, -76, 153, +-125, -140, -106, -354, -36, -375, 41, -225, +97, 22, 96, 253, 41, 343, -49, 271, +-125, 75, -158, -168, -120, -328, -44, -338, +38, -213, 100, 6, 118, 217, 90, 325, +34, 302, -33, 149, -80, -56, -107, -201, +-126, -244, -136, -177, -124, -30, -87, 97, +-15, 147, 78, 102, 170, -20, 228, -123, +213, -146, 108, -89, -42, 45, -191, 181, +-266, 232, -231, 174, -97, 26, 67, -143, +199, -234, 234, -227, 169, -131, 58, 15, +-37, 121, -64, 146, -25, 104, 43, 21, +91, -37, 90, -43, 33, -17, -48, 28, +-90, 58, -82, 40, 2, 1, 102, -41, +188, -70, 213, -60, 170, -36, 73, -17, +-33, 4, -84, 7, -73, 7, -8, 31, +45, 59, 66, 77, 44, 72, -14, 20, +-59, -42, -71, -87, -7, -107, 81, -73, +164, -10, 179, 34, 142, 47, 62, 24, +-43, -19, -120, -35, -160, -19, -135, 26, +-93, 86, -49, 97, -6, 44, 45, -39, +88, -109, 87, -116, 79, -48, 49, 55, +26, 145, -23, 155, -76, 49, -111, -115, +-132, -250, -139, -282, -130, -175, -69, 39, +25, 273, 121, 418, 166, 382, 146, 169, +86, -118, -19, -362, -120, -457, -179, -356, +-141, -110, -46, 168, 48, 349, 81, 351, +57, 198, -8, -17, -86, -199, -112, -265, +-45, -184, 92, -12, 216, 152, 251, 217, +188, 159, 65, 33, -69, -95, -172, -173, +-187, -162, -118, -73, -22, 26, 40, 73, +65, 45, 86, -22, 133, -64, 170, -44, +187, 40, 182, 157, 143, 239, 44, 216, +-86, 80, -191, -120, -210, -297, -144, -367, +-40, -294, 84, -100, 202, 140, 268, 313, +248, 340, 153, 225, 34, 25, -69, -167, +-134, -258, -167, -214, -124, -53, -38, 134, +50, 243, 94, 220, 94, 74, 69, -137, +22, -301, -37, -335, -76, -226, -47, -11, +9, 211, 58, 340, 75, 333, 58, 194, +23, -4, -49, -152, -114, -204, -145, -153, +-111, -42, -69, 37, -34, 41, -14, -40, +12, -165, 43, -227, 54, -163, 81, 10, +102, 246, 94, 431, 26, 454, -72, 289, +-144, -18, -173, -334, -152, -502, -108, -477, +-15, -275, 64, 21, 122, 255, 132, 339, +121, 263, 108, 84, 69, -64, 6, -102, +-69, -44, -109, 69, -117, 149, -81, 107, +-5, -26, 85, -189, 161, -289, 160, -248, +108, -100, 24, 76, -31, 214, -54, 237, +-33, 145, 29, 14, 93, -91, 125, -99, +101, -14, 51, 87, 4, 154, -19, 134, +-22, 10, -16, -155, 9, -291, 22, -337, +28, -240, 29, -48, 54, 174, 89, 364, +120, 426, 126, 327, 103, 119, 49, -138, +-32, -333, -112, -384, -156, -294, -153, -93, +-97, 126, -16, 241, 63, 224, 119, 100, +126, -66, 91, -163, 48, -153, 10, -43, +-9, 118, -15, 222, -24, 214, -52, 111, +-87, -48, -126, -185, -129, -228, -105, -184, +-48, -83, 20, 19, 81, 67, 110, 69, +101, 50, 72, 29, 28, 44, -9, 90, +-54, 121, -92, 115, -104, 43, -95, -77, +-63, -185, -29, -245, 9, -223, 29, -112, +43, 40, 37, 175, 50, 246, 84, 219, +118, 123, 124, 6, 78, -94, 1, -133, +-92, -113, -164, -72, -186, -39, -132, -38, +-25, -54, 84, -57, 178, -19, 228, 59, +240, 160, 187, 224, 98, 203, -5, 88, +-82, -83, -129, -240, -139, -311, -95, -264, +-18, -115, 69, 79, 116, 230, 136, 275, +130, 218, 96, 93, 43, -37, -13, -120, +-25, -134, -12, -97, 21, -39, 38, -4, +56, -9, 50, -35, 8, -65, -46, -69, +-79, -27, -57, 44, -14, 125, 36, 186, +70, 188, 80, 128, 54, 16, -6, -126, +-48, -229, -60, -255, -32, -201, -12, -68, +-4, 86, -5, 193, -11, 220, -29, 155, +-41, 35, -16, -69, 28, -120, 47, -96, +28, -10, -11, 64, -40, 81, -63, 28, +-67, -77, -45, -155, 3, -162, 40, -101, +45, 26, 27, 159, 7, 221, -11, 197, +-29, 91, -49, -42, -43, -122, -26, -148, +-2, -117, 18, -38, 50, 24, 81, 37, +90, 17, 67, -22, 28, -32, 4, -1, +-20, 38, -42, 94, -47, 129, -34, 95, +2, 12, 31, -90, 60, -168, 82, -180, +103, -133, 82, -43, 47, 77, 17, 157, +7, 164, 21, 118, 36, 34, 53, -40, +63, -77, 40, -79, -18, -38, -70, 11, +-87, 15, -72, -12, -15, -49, 54, -74, +136, -49, 181, 8, 170, 70, 100, 126, +9, 125, -79, 55, -132, -32, -137, -108, +-96, -143, -16, -111, 39, -41, 57, 44, +53, 117, 37, 131, 21, 92, 15, 16, +21, -71, 18, -128, 10, -135, -29, -98, +-52, -12, -56, 86, -46, 152, -31, 171, +-17, 122, -6, 21, -10, -80, -21, -155, +-33, -174, -19, -118, 14, -34, 50, 39, +87, 86, 96, 79, 84, 48, 27, 18, +-44, -3, -119, 12, -159, 45, -160, 59, +-117, 45, -25, -1, 75, -66, 153, -114, +182, -132, 163, -109, 116, -35, 53, 52, +-4, 121, -49, 155, -64, 136, -77, 74, +-81, -6, -73, -87, -44, -131, 2, -114, +54, -65, 101, -4, 142, 48, 154, 61, +129, 43, 80, -2, 36, -46, -5, -48, +-38, -8, -63, 40, -65, 85, -46, 98, +-31, 62, -17, 0, 4, -74, 29, -117, +49, -100, 65, -58, 99, -8, 131, 41, +148, 56, 112, 40, 40, 17, -60, -4, +-157, 8, -226, 43, -234, 67, -156, 66, +-25, 25, 108, -56, 194, -135, 226, -178, +205, -158, 125, -57, 17, 77, -82, 187, +-130, 239, -154, 196, -155, 79, -135, -63, +-85, -173, -32, -199, 5, -138, 46, -42, +94, 50, 136, 97, 141, 66, 108, -3, +48, -60, -29, -76, -101, -29, -148, 51, +-133, 120, -67, 150, 8, 116, 40, 25, +48, -72, 36, -148, 21, -177, 11, -150, +28, -90, 72, -12, 111, 62, 110, 109, +56, 137, -9, 145, -68, 114, -104, 61, +-101, -2, -59, -68, 21, -118, 83, -147, +111, -150, 103, -113, 97, -53, 70, 20, +30, 104, -2, 172, -14, 193, -4, 158, +-4, 60, -3, -67, 13, -167, 28, -214, +25, -177, -1, -62, -21, 69, -25, 153, +-1, 165, 21, 105, 66, 14, 118, -63, +136, -99, 94, -71, 5, -13, -86, 21, +-144, 17, -157, -18, -118, -46, -28, -34, +75, 17, 120, 84, 110, 131, 66, 101, +17, 1, -29, -116, -61, -195, -62, -178, +-31, -64, -3, 85, 1, 203, -6, 228, +-8, 133, -13, -24, -15, -166, -27, -227, +-21, -172, -11, -42, -12, 95, -17, 185, +-4, 182, 26, 97, 45, -14, 45, -104, +30, -139, 8, -110, -19, -60, -59, -12, +-71, 30, -58, 53, -20, 69, 19, 81, +57, 79, 85, 62, 98, 18, 84, -58, +50, -132, 23, -159, -3, -129, -31, -38, +-51, 77, -54, 164, -20, 188, 21, 131, +55, 14, 78, -103, 98, -175, 89, -180, +59, -111, 21, -9, 5, 82, 10, 132, +18, 118, 18, 62, 18, 3, 5, -35, +-22, -48, -32, -39, -9, -25, 37, -13, +82, -11, 92, -22, 75, -22, 34, -5, +-16, 13, -62, 29, -68, 38, -43, 29, +-1, 14, 26, 0, 34, -7, 33, 6, +19, 18, -2, 15, -22, 1, -21, -24, +-10, -51, 2, -66, 12, -63, -1, -35, +-18, 10, -54, 40, -85, 61, -92, 74, +-55, 72, 10, 60, 85, 40, 140, 7, +135, -26, 65, -62, -63, -98, -184, -107, +-232, -92, -190, -59, -65, -4, 91, 51, +216, 97, 239, 126, 154, 115, -6, 75, +-159, 30, -232, -23, -198, -66, -71, -84, +84, -89, 186, -76, 192, -54, 110, -36, +2, -1, -71, 42, -78, 75, -40, 102, +20, 102, 56, 64, 40, 6, -3, -62, +-32, -111, -4, -104, 73, -57, 152, 18, +192, 87, 156, 97, 47, 47, -104, -41, +-214, -138, -230, -174, -136, -122, 30, -12, +210, 129, 335, 236, 345, 249, 228, 175, +27, 27, -167, -143, -276, -253, -279, -279, +-173, -217, -6, -79, 153, 71, 228, 187, +208, 240, 115, 206, 9, 118, -72, 13, +-105, -91, -77, -150, -15, -154, 31, -116, +37, -46, 3, 20, -38, 54, -65, 68, +-64, 56, -32, 24, 31, 3, 75, -11, +70, -16, 11, -8, -59, -8, -102, -7, +-94, 10, -52, 24, 20, 34, 88, 39, +99, 16, 45, -18, -47, -62, -133, -106, +-172, -109, -147, -74, -57, -18, 73, 58, +182, 131, 203, 169, 152, 159, 45, 90, +-73, -15, -165, -119, -201, -201, -166, -223, +-71, -160, 40, -43, 121, 87, 165, 190, +153, 217, 101, 169, 37, 71, -26, -46, +-50, -124, -42, -141, -18, -114, 8, -63, +33, -16, 29, 16, 13, 36, 10, 40, +30, 44, 76, 66, 111, 77, 105, 55, +66, -1, 2, -77, -55, -140, -75, -154, +-41, -115, 34, -29, 120, 82, 157, 162, +125, 184, 52, 148, -39, 63, -108, -30, +-116, -111, -71, -162, 15, -163, 98, -121, +134, -57, 111, 18, 58, 83, -13, 121, +-62, 131, -67, 108, -40, 63, 3, 18, +18, -25, -9, -56, -49, -73, -73, -86, +-61, -95, -12, -93, 63, -76, 111, -29, +117, 43, 54, 113, -48, 163, -140, 172, +-177, 119, -148, 24, -64, -77, 28, -152, +94, -169, 113, -126, 77, -50, 15, 30, +-43, 76, -92, 71, -113, 34, -95, -11, +-38, -34, 26, -8, 78, 40, 88, 84, +62, 105, 10, 71, -41, -11, -71, -105, +-66, -171, -41, -167, -7, -89, 24, 20, +41, 122, 53, 169, 63, 131, 58, 40, +51, -62, 38, -125, 17, -102, -12, -17, +-29, 73, -29, 124, -5, 98, 20, -1, +42, -118, 65, -190, 78, -169, 79, -55, +68, 81, 39, 182, -3, 202, -36, 120, +-48, -13, -28, -126, 42, -168, 115, -108, +152, 12, 124, 110, 40, 141, -61, 85, +-132, -35, -144, -145, -76, -192, 42, -141, +143, -8, 190, 127, 171, 206, 90, 203, +-11, 112, -97, -22, -136, -133, -119, -183, +-66, -153, -23, -73, 1, 6, 11, 67, +23, 87, 55, 61, 91, 27, 103, 5, +90, -2, 29, 14, -67, 27, -156, 20, +-203, 5, -192, -30, -109, -70, 17, -82, +138, -65, 205, -15, 173, 54, 55, 96, +-82, 98, -185, 58, -212, -25, -153, -103, +-32, -134, 88, -101, 168, 2, 154, 124, +70, 198, -38, 191, -136, 88, -172, -84, +-125, -236, -26, -301, 78, -243, 141, -69, +133, 138, 72, 289, 1, 323, -60, 220, +-68, 36, -27, -142, 30, -246, 63, -232, +52, -127, 0, -6, -39, 77, -35, 90, +14, 40, 99, -12, 158, -25, 138, 7, +55, 68, -63, 109, -147, 87, -134, 9, +-33, -91, 103, -162, 213, -149, 224, -68, +144, 45, 26, 138, -93, 156, -167, 93, +-163, -9, -105, -107, -8, -147, 99, -109, +169, -26, 205, 65, 192, 124, 120, 125, +20, 79, -82, 13, -166, -54, -201, -93, +-174, -101, -97, -90, 25, -60, 127, -20, +164, 24, 153, 73, 112, 103, 52, 106, +-6, 84, -59, 37, -98, -26, -112, -74, +-114, -100, -103, -97, -51, -66, 2, -30, +38, 10, 61, 44, 66, 60, 53, 65, +26, 59, -25, 42, -60, 21, -52, -12, +-28, -52, -6, -73, 18, -75, 21, -53, +-5, -3, -59, 43, -113, 66, -123, 65, +-84, 30, -20, -17, 74, -43, 169, -41, +216, -13, 190, 33, 90, 57, -48, 44, +-155, -6, -226, -76, -235, -116, -163, -99, +-32, -38, 101, 55, 198, 135, 230, 157, +206, 116, 141, 18, 44, -96, -39, -165, +-66, -175, -68, -121, -79, -15, -100, 88, +-100, 147, -59, 154, 25, 102, 111, 24, +190, -52, 224, -106, 172, -112, 58, -73, +-52, -23, -117, 29, -121, 58, -83, 53, +-15, 27, 66, -7, 114, -34, 86, -32, +24, -20, -22, -3, -34, 19, -20, 29, +13, 25, 46, 27, 75, 23, 65, 15, +23, 1, -19, -33, -45, -72, -62, -96, +-58, -92, -34, -38, 8, 50, 46, 131, +43, 177, 11, 153, -4, 59, -11, -54, +-17, -152, -14, -195, 4, -158, 19, -71, +20, 30, -12, 107, -39, 120, -36, 84, +-34, 39, -40, 2, -27, -14, -5, -8, +12, -6, 17, -13, 11, -32, 17, -58, +33, -59, 17, -31, -6, 8, -22, 48, +-38, 60, -49, 32, -47, -10, -35, -39, +0, -37, 29, 9, 39, 65, 52, 97, +60, 80, 37, -1, -2, -115, -42, -195, +-60, -200, -39, -110, -2, 45, 28, 195, +54, 277, 56, 246, 47, 103, 42, -79, +36, -224, 17, -275, -14, -208, -62, -63, +-81, 82, -47, 177, 10, 184, 70, 118, +120, 35, 125, -27, 92, -52, 34, -46, +-31, -42, -66, -56, -56, -77, -28, -90, +8, -60, 21, 20, 2, 105, -18, 162, +-13, 157, 17, 78, 84, -35, 146, -129, +159, -162, 117, -113, 17, -17, -119, 69, +-220, 105, -250, 74, -185, 0, -28, -59, +154, -75, 277, -33, 300, 46, 194, 103, +19, 103, -145, 54, -245, -32, -241, -108, +-129, -128, 7, -94, 110, -22, 148, 48, +102, 77, 27, 68, -32, 32, -60, -3, +-33, -10, 20, 8, 41, 29, 11, 45, +-53, 27, -117, -19, -116, -60, -52, -88, +49, -91, 146, -54, 177, -5, 108, 43, +-8, 78, -120, 87, -186, 85, -179, 76, +-110, 41, 4, -7, 136, -64, 205, -126, +182, -157, 86, -145, -35, -86, -127, 19, +-143, 130, -102, 199, -21, 204, 56, 132, +77, 13, 50, -96, 15, -167, -15, -176, +-20, -123, 8, -48, 52, 23, 97, 69, +104, 75, 43, 63, -40, 46, -107, 27, +-137, 19, -106, 17, -21, 11, 81, 4, +173, -15, 192, -43, 130, -69, 25, -94, +-84, -102, -156, -74, -134, -13, -34, 73, +89, 159, 171, 203, 153, 178, 55, 82, +-53, -61, -140, -188, -156, -242, -84, -201, +38, -80, 152, 61, 213, 153, 176, 169, +73, 104, -52, -3, -156, -81, -190, -84, +-135, -25, -24, 58, 90, 101, 147, 75, +122, -6, 51, -105, -20, -164, -59, -140, +-37, -48, 16, 78, 50, 168, 44, 171, +-3, 93, -78, -17, -127, -114, -126, -145, +-63, -96, 54, -2, 170, 88, 208, 130, +150, 100, 14, 17, -123, -79, -197, -146, +-188, -145, -114, -85, -5, 10, 80, 106, +116, 155, 111, 141, 78, 81, 27, -4, +-14, -79, -51, -110, -64, -94, -55, -43, +-43, 11, -32, 29, -10, 10, 8, -26, +23, -60, 30, -53, 25, 6, 30, 87, +52, 158, 59, 171, 49, 99, 9, -23, +-50, -158, -100, -248, -113, -238, -84, -136, +-6, 20, 77, 172, 128, 242, 146, 206, +127, 92, 68, -54, -7, -156, -76, -163, +-115, -88, -104, 34, -56, 126, 5, 131, +67, 56, 95, -64, 87, -173, 59, -197, +27, -122, 9, 19, 13, 165, 13, 238, +11, 202, 11, 91, 0, -54, -22, -159, +-41, -169, -52, -105, -23, -20, 40, 40, +96, 36, 122, -9, 106, -50, 38, -58, +-40, -4, -90, 92, -91, 166, -53, 185, +-1, 124, 31, 0, 58, -126, 72, -214, +51, -233, 7, -168, -32, -56, -51, 65, +-37, 164, -11, 201, 8, 172, 18, 94, +12, -18, -15, -112, -19, -149, 1, -121, +28, -33, 36, 72, 11, 126, -33, 104, +-69, 8, -95, -123, -86, -201, -28, -178, +53, -59, 117, 115, 125, 252, 72, 279, +-1, 187, -74, 12, -134, -162, -143, -248, +-93, -224, -18, -115, 60, 16, 108, 96, +114, 105, 82, 60, 16, -6, -59, -37, +-84, -15, -60, 37, -19, 95, 14, 120, +24, 87, 26, 16, 30, -76, 23, -159, +17, -192, 23, -169, 18, -94, -10, 25, +-26, 138, -17, 211, 26, 216, 61, 139, +60, 14, 36, -100, 14, -162, -10, -147, +-17, -73, -3, 8, 17, 56, 31, 49, +24, -3, -4, -51, -7, -61, 8, -20, +23, 61, 46, 128, 83, 135, 100, 80, +76, -16, 6, -109, -68, -145, -98, -115, +-85, -40, -52, 43, 3, 80, 50, 65, +71, 10, 78, -56, 71, -76, 61, -31, +58, 44, 31, 116, -21, 143, -73, 92, +-111, -11, -129, -126, -104, -203, -44, -188, +40, -89, 112, 42, 132, 155, 107, 201, +68, 157, 11, 56, -52, -56, -107, -124, +-136, -122, -118, -76, -66, -18, -19, 29, +19, 45, 41, 38, 43, 24, 31, 17, +37, 17, 62, 10, 82, -18, 52, -50, +-33, -62, -125, -41, -172, 8, -161, 59, +-86, 77, 24, 55, 121, -2, 160, -67, +138, -94, 79, -60, 22, 19, -30, 92, +-78, 105, -109, 54, -102, -35, -66, -115, +-17, -131, 28, -66, 85, 38, 143, 125, +158, 148, 110, 84, 36, -26, -48, -120, +-122, -153, -149, -107, -112, -13, -18, 82, +83, 133, 136, 118, 145, 55, 130, -10, +94, -66, 31, -87, -35, -73, -88, -49, +-95, -14, -87, 26, -68, 49, -9, 55, +79, 46, 141, 16, 154, -16, 117, -28, +49, -20, -26, 13, -92, 48, -122, 47, +-81, 7, -20, -57, 20, -119, 37, -125, +44, -63, 38, 40, 30, 140, 11, 179, +0, 132, 13, 27, 18, -81, -8, -129, +-33, -93, -50, -11, -60, 57, -61, 63, +-47, -9, -13, -107, 37, -161, 57, -121, +53, 16, 45, 180, 20, 280, -31, 264, +-79, 120, -103, -83, -79, -241, -28, -290, +14, -221, 47, -80, 61, 52, 26, 128, +-28, 136, -52, 98, -31, 62, 16, 55, +39, 60, 7, 59, -31, 19, -51, -64, +-45, -145, -10, -181, 43, -152, 69, -60, +58, 49, 12, 126, -36, 149, -43, 115, +-22, 57, 5, 15, 33, -2, 37, -4, +19, -15, -9, -53, -27, -99, -10, -130, +44, -122, 81, -46, 77, 74, 39, 176, +-12, 208, -50, 150, -55, 23, -26, -112, +32, -195, 71, -184, 72, -74, 45, 62, +15, 153, -4, 152, -1, 61, 16, -68, +33, -155, 31, -153, -4, -56, -40, 90, +-37, 185, -1, 174, 47, 62, 71, -89, +61, -192, 17, -184, -28, -72, -61, 83, +-56, 193, -19, 177, 19, 55, 42, -97, +49, -196, 45, -177, 31, -51, -5, 107, +-56, 203, -96, 173, -94, 35, -57, -116, +16, -191, 83, -143, 105, -3, 71, 134, +7, 177, -56, 97, -79, -62, -66, -197, +-38, -219, -11, -108, 3, 79, 0, 231, +3, 261, 6, 157, 16, -29, 33, -197, +43, -249, 27, -164, -15, -7, -86, 131, +-136, 163, -121, 82, -41, -45, 74, -133, +175, -122, 192, 0, 116, 158, -19, 249, +-144, 207, -188, 28, -127, -204, -13, -365, +90, -364, 118, -178, 67, 111, -16, 362, +-60, 449, -27, 318, 70, 33, 147, -246, +149, -383, 71, -313, -58, -77, -175, 184, +-214, 312, -156, 230, -19, -24, 128, -284, +216, -369, 221, -218, 157, 109, 41, 438, +-64, 557, -110, 374, -85, -36, -32, -464, +-1, -676, -10, -545, -34, -146, -55, 319, +-41, 597, 21, 542, 115, 208, 190, -204, +195, -450, 106, -384, -21, -65, -128, 293, +-187, 463, -193, 320, -129, -69, -17, -476, +90, -660, 148, -484, 140, -19, 71, 491, +-14, 768, -82, 667, -87, 243, -16, -273, +80, -617, 106, -625, 44, -315, -69, 107, +-166, 387, -191, 381, -132, 121, -6, -204, +131, -365, 196, -258, 163, 56, 65, 405, +-33, 553, -97, 385, -107, -16, -85, -440, +-33, -653, 12, -537, 17, -181, -9, 232, +-28, 510, -20, 512, 1, 255, 24, -86, +51, -322, 68, -341, 67, -165, 29, 76, +-15, 259, -37, 292, -38, 146, -56, -98, +-80, -303, -80, -359, -39, -245, 31, -19, +104, 220, 151, 381, 152, 386, 74, 225, +-48, -39, -132, -287, -126, -394, -49, -325, +44, -118, 85, 140, 78, 326, 37, 334, +-29, 159, -63, -101, -24, -302, 47, -314, +100, -150, 95, 98, 40, 312, -33, 361, +-91, 191, -117, -95, -75, -334, 32, -392, +138, -225, 177, 60, 123, 316, 7, 415, +-101, 274, -166, -41, -145, -337, -37, -452, +89, -321, 143, -11, 114, 304, 37, 474, +-29, 409, -59, 125, -60, -222, -32, -438, +21, -422, 50, -196, 32, 99, -17, 305, +-52, 336, -63, 175, -60, -74, -41, -245, +24, -236, 102, -61, 139, 161, 97, 281, +-2, 238, -108, 53, -173, -207, -183, -380, +-107, -346, 39, -123, 170, 173, 187, 382, +105, 391, -13, 224, -114, -43, -153, -301, +-113, -395, -13, -274, 103, -27, 138, 211, +66, 323, -52, 271, -125, 99, -119, -120, +-37, -288, 73, -299, 167, -152, 165, 66, +45, 233, -108, 281, -188, 208, -168, 38, +-66, -170, 55, -305, 148, -272, 183, -89, +142, 142, 37, 290, -52, 304, -95, 178, +-107, -60, -116, -295, -96, -380, -14, -254, +95, 6, 158, 260, 160, 374, 107, 320, +17, 115, -84, -162, -152, -355, -135, -351, +-14, -168, 109, 69, 152, 236, 115, 267, +23, 186, -94, 29, -168, -132, -147, -199, +-2, -146, 182, -29, 260, 67, 181, 96, +6, 79, -180, 50, -274, 0, -232, -51, +-61, -63, 169, -42, 305, -17, 247, -8, +74, 11, -109, 58, -221, 98, -223, 74, +-131, 5, 7, -69, 139, -127, 182, -146, +132, -100, 51, 19, -23, 156, -88, 220, +-123, 152, -110, 11, -28, -127, 61, -208, +86, -182, 45, -55, -14, 111, -78, 214, +-109, 178, -75, 12, 27, -160, 147, -230, +201, -166, 123, -1, -27, 196, -169, 318, +-254, 271, -237, 60, -96, -209, 100, -372, +252, -349, 257, -169, 121, 88, -58, 325, +-177, 424, -195, 311, -105, 45, 31, -234, +140, -387, 153, -359, 56, -175, -70, 85, +-107, 313, -74, 388, -8, 257, 47, -3, +52, -248, 23, -349, -1, -268, -18, -51, +1, 190, 50, 335, 65, 294, 24, 85, +-38, -166, -79, -315, -42, -285, 24, -115, +72, 105, 90, 263, 52, 282, -47, 154, +-126, -51, -142, -220, -54, -265, 120, -174, +245, -15, 247, 149, 155, 246, -37, 229, +-245, 107, -338, -67, -264, -226, -52, -290, +200, -216, 311, -39, 250, 177, 78, 328, +-124, 324, -236, 160, -181, -93, -8, -313, +190, -368, 266, -219, 152, 35, -61, 268, +-257, 351, -369, 234, -303, -15, -77, -249, +204, -335, 412, -214, 431, 41, 237, 261, +-36, 332, -276, 217, -406, -18, -355, -242, +-133, -333, 125, -260, 287, -63, 266, 157, +97, 274, -97, 251, -209, 125, -192, -29, +-38, -149, 153, -193, 264, -160, 215, -65, +19, 48, -198, 118, -307, 145, -291, 130, +-148, 58, 75, -57, 248, -155, 293, -193, +216, -141, 40, -2, -125, 154, -202, 262, +-181, 252, -73, 100, 68, -125, 147, -302, +140, -340, 43, -194, -85, 71, -163, 314, +-159, 410, -66, 282, 100, -25, 219, -355, +232, -508, 157, -394, 15, -48, -124, 358, +-175, 608, -154, 577, -72, 239, 30, -261, +67, -665, 42, -750, 17, -481, 8, 18, +40, 502, 96, 751, 137, 653, 127, 246, +49, -255, -85, -589, -170, -600, -181, -321, +-133, 81, -42, 382, 51, 447, 109, 259, +140, -80, 120, -359, 61, -413, 21, -201, +-3, 146, -54, 429, -80, 487, -64, 301, +-27, -43, -7, -391, -17, -555, -49, -454, +-48, -134, -26, 223, 4, 435, 68, 420, +145, 239, 155, -18, 67, -235, -68, -301, +-146, -207, -138, -24, -85, 128, -29, 174, +34, 121, 47, 35, -3, -59, -72, -137, +-79, -159, 12, -116, 141, -9, 190, 110, +148, 192, 50, 215, -91, 186, -247, 62, +-317, -141, -220, -318, 3, -350, 200, -201, +285, 48, 249, 289, 119, 399, -56, 324, +-205, 61, -249, -277, -120, -485, 72, -417, +164, -110, 144, 261, 78, 516, -23, 513, +-109, 257, -135, -145, -64, -514, 75, -631, +159, -407, 112, 5, 17, 380, -67, 557, +-115, 451, -115, 154, -56, -203, 75, -461, +216, -433, 213, -122, 95, 231, -24, 427, +-134, 382, -228, 87, -241, -289, -161, -569, +23, -588, 232, -244, 321, 302, 289, 717, +200, 809, 15, 527, -220, -30, -369, -580, +-344, -900, -154, -820, 82, -327, 225, 307, +276, 737, 226, 803, 65, 505, -123, 12, +-209, -421, -163, -650, -16, -544, 104, -145, +125, 277, 108, 493, 36, 443, -129, 177, +-254, -156, -241, -411, -89, -501, 143, -315, +323, 64, 345, 410, 231, 562, -23, 458, +-324, 140, -473, -243, -362, -555, -65, -657, +241, -418, 376, 43, 319, 489, 127, 709, +-124, 588, -289, 208, -266, -249, -118, -626, +69, -725, 170, -439, 148, 58, 91, 511, +29, 694, -67, 529, -125, 136, -116, -312, +-73, -637, -10, -639, 57, -287, 119, 207, +183, 596, 156, 664, 24, 394, -137, -59, +-242, -508, -223, -741, -75, -586, 105, -97, +268, 464, 321, 812, 167, 730, -102, 268, +-298, -333, -337, -811, -176, -916, 105, -544, +330, 150, 402, 800, 285, 1056, -21, 777, +-331, 122, -459, -607, -355, -1069, -74, -1024, +239, -473, 427, 325, 437, 944, 247, 1083, +-70, 705, -333, 20, -422, -657, -321, -976, +-60, -801, 204, -247, 351, 413, 349, 806, +175, 745, -109, 317, -307, -260, -340, -706, +-222, -744, 1, -378, 219, 176, 330, 662, +305, 788, 130, 498, -116, -19, -304, -541, +-352, -829, -257, -672, -50, -182, 187, 364, +364, 724, 359, 711, 156, 364, -132, -122, +-359, -555, -420, -730, -265, -494, 29, -19, +339, 417, 506, 646, 407, 573, 77, 243, +-302, -194, -562, -569, -564, -692, -311, -464, +110, -45, 526, 342, 701, 567, 520, 561, +111, 340, -352, -15, -650, -354, -611, -512, +-287, -401, 174, -148, 576, 92, 646, 248, +350, 306, -107, 240, -514, 48, -668, -162, +-443, -259, 21, -200, 510, -71, 779, 73, +637, 217, 181, 326, -343, 304, -730, 90, +-775, -210, -455, -445, 46, -525, 516, -419, +734, -108, 574, 316, 214, 672, -172, 765, +-469, 495, -514, 0, -292, -475, 26, -751, +311, -719, 408, -355, 252, 150, -14, 555, +-274, 673, -448, 435, -363, 15, -41, -341, +336, -500, 577, -397, 541, -50, 239, 315, +-156, 501, -519, 418, -688, 86, -527, -302, +-134, -557, 292, -584, 581, -331, 589, 129, +369, 529, 42, 703, -318, 590, -542, 212, +-476, -261, -207, -634, 128, -762, 386, -551, +436, -79, 275, 401, -11, 714, -317, 726, +-452, 409, -339, -91, -66, -569, 228, -801, +398, -638, 377, -162, 210, 368, -75, 745, +-333, 773, -398, 418, -272, -148, -40, -674, +216, -876, 343, -619, 291, -61, 98, 504, +-172, 848, -352, 780, -305, 320, -98, -291, +163, -753, 355, -832, 376, -501, 212, 46, +-71, 542, -350, 781, -439, 632, -311, 182, +-66, -323, 206, -637, 389, -638, 385, -354, +222, 77, -45, 438, -292, 584, -352, 456, +-218, 128, -8, -229, 208, -433, 320, -448, +253, -295, 58, -19, -161, 239, -308, 376, +-284, 354, -120, 177, 78, -51, 242, -203, +313, -298, 260, -311, 121, -157, -64, 66, +-221, 246, -286, 329, -248, 263, -131, 81, +46, -111, 186, -306, 239, -382, 200, -224, +69, 38, -94, 260, -174, 366, -145, 292, +-33, 84, 115, -134, 201, -314, 149, -341, +-4, -161, -206, 75, -357, 246, -335, 282, +-100, 178, 213, 13, 443, -142, 480, -263, +284, -258, -59, -117, -375, 74, -525, 238, +-413, 296, -85, 262, 251, 139, 414, -84, +360, -314, 116, -416, -164, -373, -334, -171, +-323, 124, -114, 358, 180, 499, 346, 456, +334, 184, 162, -147, -120, -389, -349, -506, +-410, -399, -302, -140, -10, 102, 303, 316, +441, 384, 383, 239, 176, 58, -142, -71, +-385, -159, -428, -130, -264, -57, 44, -23, +313, 35, 384, 21, 283, -70, 54, -79, +-217, -21, -371, 19, -319, 75, -98, 97, +191, 85, 347, 93, 309, 54, 151, -12, +-83, -36, -306, -69, -364, -141, -228, -180, +36, -157, 300, -36, 394, 149, 282, 260, +74, 261, -183, 166, -399, -5, -417, -195, +-206, -312, 109, -277, 370, -73, 424, 156, +295, 264, 75, 251, -185, 132, -378, -45, +-375, -219, -189, -307, 80, -234, 278, -32, +318, 160, 238, 271, 76, 290, -165, 186, +-334, 1, -317, -205, -122, -333, 152, -303, +347, -140, 357, 62, 215, 231, -50, 300, +-347, 233, -486, 73, -363, -114, -48, -220, +293, -200, 473, -109, 446, 7, 229, 112, +-123, 148, -438, 103, -521, 12, -348, -76, +1, -86, 332, -57, 474, -43, 409, 2, +158, 80, -224, 111, -499, 75, -479, -1, +-197, -73, 177, -81, 450, -89, 481, -102, +291, -24, -65, 106, -441, 161, -593, 122, +-406, 41, -5, -27, 395, -41, 591, -66, +519, -96, 225, -56, -214, 17, -610, 13, +-675, -55, -382, -79, 78, -4, 475, 124, +629, 192, 492, 178, 171, 118, -239, 4, +-544, -187, -527, -363, -238, -349, 100, -130, +346, 147, 403, 338, 285, 399, 57, 294, +-214, 56, -386, -238, -308, -445, -71, -404, +174, -126, 327, 190, 327, 397, 189, 432, +-36, 223, -289, -121, -399, -415, -284, -541, +-55, -383, 162, 23, 315, 419, 342, 625, +239, 588, 24, 232, -230, -272, -383, -641, +-338, -746, -161, -516, 78, -4, 317, 497, +449, 784, 345, 770, 28, 349, -333, -260, +-532, -685, -467, -815, -168, -618, 223, -118, +549, 425, 625, 782, 364, 822, -95, 430, +-485, -160, -620, -605, -454, -801, -106, -697, +269, -259, 535, 310, 538, 760, 239, 885, +-159, 548, -435, -58, -477, -584, -282, -854, +36, -779, 323, -309, 482, 364, 379, 895, +30, 989, -325, 547, -486, -174, -420, -783, +-157, -1030, 177, -841, 437, -233, 528, 557, +371, 1105, 9, 1100, -339, 553, -517, -242, +-476, -904, -236, -1151, 106, -917, 408, -267, +554, 563, 428, 1136, 86, 1142, -268, 618, +-484, -164, -478, -854, -233, -1135, 109, -928, +390, -303, 486, 508, 317, 1072, -30, 1079, +-336, 582, -470, -151, -351, -786, -32, -1026, +310, -795, 499, -193, 443, 518, 137, 949, +-264, 867, -550, 353, -567, -304, -280, -804, +173, -902, 544, -556, 661, 79, 449, 702, +11, 989, -426, 769, -647, 172, -547, -487, +-164, -922, 275, -944, 538, -538, 521, 115, +241, 704, -151, 957, -436, 762, -487, 243, +-263, -322, 105, -707, 406, -768, 493, -491, +325, -4, -36, 430, -377, 623, -527, 510, +-417, 179, -87, -197, 284, -471, 487, -529, +460, -337, 204, 21, -150, 362, -396, 537, +-407, 473, -208, 220, 95, -116, 303, -426, +314, -566, 161, -470, -83, -192, -300, 146, +-344, 412, -192, 494, 77, 408, 320, 181, +394, -117, 280, -329, 62, -382, -207, -294, +-408, -84, -421, 138, -228, 235, 72, 220, +330, 92, 391, -103, 269, -204, 52, -175, +-188, -57, -332, 149, -274, 311, -57, 269, +199, 101, 331, -121, 252, -316, 37, -344, +-187, -222, -351, -43, -359, 175, -173, 309, +123, 246, 372, 109, 447, -2, 303, -75, +35, -79, -236, -71, -416, -100, -417, -98, +-202, -66, 120, -69, 383, -17, 454, 122, +302, 232, -1, 225, -309, 84, -495, -134, +-441, -272, -129, -264, 282, -176, 564, 6, +596, 264, 338, 406, -102, 312, -512, 36, +-710, -264, -580, -429, -128, -373, 379, -179, +677, 97, 657, 386, 324, 498, -170, 320, +-549, -20, -647, -322, -398, -449, 86, -352, +486, -113, 582, 155, 392, 372, 2, 420, +-400, 231, -606, -67, -528, -281, -176, -351, +291, -262, 575, -73, 574, 126, 347, 270, +-18, 309, -367, 175, -538, -37, -484, -188, +-203, -252, 162, -214, 373, -59, 366, 118, +228, 214, 5, 225, -206, 121, -302, -59, +-237, -195, -25, -244, 209, -173, 299, 20, +231, 193, 63, 220, -149, 169, -318, 46, +-355, -119, -228, -210, 34, -177, 278, -53, +374, 122, 304, 200, 125, 106, -96, -20, +-255, -98, -292, -126, -192, -71, -21, 37, +112, 124, 150, 158, 117, 67, 51, -127, +-10, -220, -52, -139, -55, 29, -30, 179, +-2, 251, 16, 193, 55, 33, 70, -198, +33, -378, -31, -337, -89, -82, -100, 218, +-37, 406, 35, 404, 72, 224, 78, -48, +38, -320, -48, -470, -94, -392, -47, -119, +82, 197, 185, 390, 158, 401, 17, 258, +-137, 35, -258, -220, -283, -407, -154, -407, +90, -200, 329, 95, 416, 344, 262, 447, +-21, 360, -261, 105, -378, -236, -338, -514, +-122, -546, 163, -299, 366, 103, 355, 489, +131, 652, -150, 485, -308, 94, -315, -358, +-180, -672, 59, -648, 290, -301, 382, 184, +272, 614, -4, 737, -276, 468, -411, -18, +-372, -491, -174, -754, 121, -635, 383, -214, +500, 318, 373, 754, 39, 840, -309, 482, +-504, -97, -501, -625, -276, -885, 88, -755, +418, -304, 563, 296, 457, 819, 136, 978, +-227, 666, -480, 70, -527, -515, -347, -883, +-19, -896, 305, -536, 495, 80, 456, 673, +213, 962, -102, 778, -350, 248, -439, -346, +-306, -757, -37, -855, 221, -544, 359, 61, +330, 634, 139, 886, -114, 674, -321, 102, +-380, -498, -238, -850, 42, -836, 304, -392, +455, 318, 418, 881, 164, 1030, -195, 681, +-479, -19, -574, -708, -393, -1057, -10, -985, +364, -458, 565, 317, 532, 916, 258, 1085, +-117, 802, -424, 166, -539, -513, -396, -917, +-79, -945, 219, -555, 409, 112, 418, 668, +227, 888, -49, 740, -297, 239, -444, -403, +-362, -828, -91, -884, 191, -514, 389, 147, +442, 732, 308, 960, 39, 796, -281, 232, +-506, -506, -501, -988, -286, -993, 23, -553, +340, 158, 535, 769, 517, 991, 266, 792, +-134, 213, -485, -504, -581, -914, -408, -837, +-57, -382, 327, 244, 571, 730, 539, 828, +208, 552, -274, -15, -623, -603, -656, -858, +-359, -673, 132, -213, 598, 350, 813, 755, +649, 809, 134, 512, -472, -17, -858, -541, +-846, -786, -446, -685, 153, -322, 662, 187, +875, 628, 691, 781, 177, 576, -392, 106, +-725, -391, -718, -697, -401, -704, 80, -397, +512, 126, 705, 605, 559, 798, 135, 594, +-324, 120, -613, -392, -628, -725, -356, -763, +89, -448, 503, 102, 703, 597, 563, 785, +147, 603, -318, 175, -623, -289, -664, -599, +-403, -657, 59, -418, 505, 34, 707, 431, +559, 560, 132, 417, -352, 108, -660, -224, +-640, -425, -293, -455, 228, -249, 639, 135, +717, 439, 404, 474, -138, 309, -624, 10, +-789, -314, -553, -508, -29, -501, 512, -262, +797, 147, 694, 477, 254, 566, -312, 459, +-708, 177, -753, -200, -444, -484, 49, -589, +482, -468, 655, -136, 522, 247, 150, 488, +-274, 563, -522, 419, -480, 89, -204, -279, +141, -518, 361, -537, 379, -303, 212, 67, +-55, 383, -284, 529, -344, 432, -225, 103, +14, -277, 226, -492, 292, -495, 219, -295, +73, 70, -106, 421, -222, 576, -212, 480, +-95, 185, 60, -190, 160, -462, 140, -583, +45, -500, -54, -172, -111, 255, -105, 521, +-32, 568, 75, 395, 160, 44, 153, -293, +55, -489, -61, -493, -130, -218, -138, 206, +-91, 464, -16, 466, 49, 248, 70, -129, +57, -454, 19, -589, -13, -477, 8, -56, +74, 492, 103, 762, 85, 679, 9, 326, +-110, -183, -198, -632, -213, -807, -161, -664, +-4, -196, 186, 379, 277, 709, 231, 679, +80, 381, -103, -55, -193, -440, -190, -604, +-120, -490, 25, -109, 156, 375, 160, 645, +61, 554, -89, 211, -193, -225, -174, -633, +-85, -792, 27, -588, 170, -67, 249, 546, +214, 926, 90, 854, -93, 448, -241, -114, +-256, -659, -194, -925, -90, -764, 60, -278, +199, 312, 251, 699, 190, 682, 46, 377, +-82, -21, -155, -386, -181, -536, -150, -382, +-59, -27, 69, 329, 194, 491, 205, 358, +93, 70, -36, -243, -129, -485, -200, -539, +-200, -313, -74, 73, 148, 435, 309, 613, +273, 541, 77, 254, -146, -145, -307, -509, +-328, -664, -192, -505, 73, -120, 351, 281, +457, 537, 287, 562, -24, 343, -287, -29, +-407, -367, -372, -521, -194, -401, 85, -110, +358, 169, 456, 329, 328, 389, 77, 277, +-156, 14, -322, -241, -375, -347, -265, -280, +-5, -104, 245, 66, 341, 217, 249, 331, +44, 260, -158, 16, -265, -209, -265, -317, +-141, -276, 90, -112, 286, 78, 309, 253, +193, 376, 18, 291, -155, 50, -298, -205, +-338, -357, -216, -347, 15, -196, 202, -20, +282, 195, 263, 372, 143, 351, -28, 161, +-172, -77, -250, -254, -198, -293, -46, -225, +77, -102, 137, 102, 170, 289, 125, 310, +-8, 191, -162, -14, -250, -222, -213, -344, +-74, -331, 91, -207, 266, 51, 383, 337, +326, 504, 88, 447, -194, 181, -412, -179, +-482, -447, -371, -530, -106, -428, 223, -138, +477, 240, 523, 495, 347, 490, 35, 270, +-273, -37, -459, -277, -444, -355, -218, -293, +129, -99, 403, 156, 445, 317, 233, 277, +-89, 94, -372, -163, -496, -328, -354, -313, +25, -160, 407, 68, 602, 341, 533, 494, +196, 389, -254, 70, -584, -296, -693, -524, +-509, -516, -63, -309, 408, 24, 673, 399, +652, 618, 345, 514, -86, 176, -461, -197, +-657, -454, -538, -518, -135, -367, 279, -92, +529, 245, 552, 473, 314, 446, -74, 210, +-432, -63, -629, -308, -498, -420, -74, -339, +365, -103, 621, 211, 623, 440, 328, 418, +-134, 185, -555, -110, -754, -378, -574, -503, +-102, -381, 350, -62, 613, 301, 633, 528, +375, 518, -56, 273, -442, -58, -608, -368, +-455, -534, -85, -469, 275, -191, 460, 118, +409, 356, 145, 442, -189, 320, -428, 79, +-429, -158, -158, -313, 215, -284, 436, -92, +426, 92, 225, 215, -78, 225, -351, 50, +-459, -162, -359, -266, -97, -241, 185, -89, +350, 133, 356, 268, 253, 316, 88, 230, +-102, 14, -268, -185, -312, -257, -219, -260, +-60, -191, 94, -56, 210, 90, 240, 219, +173, 259, 30, 171, -112, 29, -168, -95, +-136, -186, -85, -199, -24, -107, 32, 40, +81, 185, 120, 209, 123, 101, 77, -42, +10, -108, -90, -130, -180, -117, -182, -84, +-92, -8, 39, 76, 150, 97, 173, 75, +120, 96, 30, 121, -56, 68, -100, -43, +-85, -157, -52, -193, -14, -128, 8, -53, +20, 20, 39, 107, 53, 159, 43, 136, +9, 72, -66, -32, -124, -78, -114, -60, +-49, -80, 76, -125, 218, -58, 244, 73, +141, 178, -50, 183, -258, 77, -346, -57, +-259, -168, -81, -269, 138, -251, 284, -30, +278, 243, 174, 382, 24, 339, -117, 132, +-164, -137, -167, -331, -150, -383, -56, -287, +62, -31, 128, 237, 155, 369, 90, 323, +-61, 141, -192, -111, -213, -269, -90, -317, +140, -258, 328, -47, 352, 230, 162, 392, +-158, 382, -421, 190, -475, -143, -292, -428, +57, -539, 365, -420, 473, -52, 349, 396, +73, 670, -195, 632, -329, 265, -314, -275, +-149, -657, 56, -713, 184, -426, 228, 79, +182, 568, 33, 740, -111, 519, -206, 27, +-228, -459, -116, -676, 70, -534, 224, -128, +313, 327, 224, 602, -8, 547, -199, 220, +-302, -184, -311, -463, -156, -497, 59, -299, +227, 10, 330, 249, 301, 351, 136, 295, +-53, 152, -232, -20, -343, -145, -315, -227, +-149, -236, 102, -161, 321, -27, 357, 106, +220, 224, 3, 285, -215, 198, -321, -20, +-243, -262, -56, -363, 142, -243, 261, -5, +234, 215, 54, 373, -146, 367, -236, 108, +-211, -212, -115, -413, 51, -389, 207, -164, +267, 114, 206, 280, 33, 339, -162, 244, +-258, 37, -270, -132, -181, -207, 25, -188, +235, -74, 336, -1, 283, -27, 49, -27, +-215, 37, -342, 99, -320, 143, -148, 144, +125, 92, 329, -15, 373, -169, 241, -267, +-12, -162, -236, 59, -342, 229, -335, 251, +-181, 118, 48, -145, 237, -351, 349, -351, +342, -126, 164, 240, -103, 567, -316, 595, +-371, 249, -252, -290, -11, -712, 236, -749, +359, -398, 288, 134, 67, 653, -211, 887, +-386, 591, -324, -69, -70, -644, 208, -847, +377, -594, 367, -39, 188, 544, -99, 863, +-361, 726, -437, 143, -277, -517, -1, -880, +242, -779, 331, -282, 263, 363, 115, 797, +-49, 813, -185, 432, -214, -184, -128, -713, +5, -816, 84, -446, 76, 142, 50, 616, +40, 737, 2, 457, -58, -64, -93, -603, +-60, -810, 21, -513, 71, 76, 76, 565, +77, 762, 44, 557, -14, 49, -64, -461, +-113, -692, -120, -531, -54, -86, -14, 348, +13, 527, 84, 406, 150, 48, 171, -298, +120, -388, -44, -235, -212, 21, -286, 240, +-241, 311, -59, 159, 176, -87, 329, -248, +353, -195, 179, -15, -150, 157, -397, 188, +-407, 71, -223, -120, 71, -270, 332, -259, +444, -36, 351, 275, 49, 478, -325, 448, +-525, 120, -434, -345, -104, -652, 270, -659, +492, -333, 464, 242, 191, 773, -200, 920, +-455, 578, -426, -142, -151, -831, 179, -1092, +347, -785, 283, -32, 87, 838, -139, 1279, +-246, 989, -160, 122, 13, -862, 144, -1403, +173, -1142, 83, -209, -39, 889, -122, 1530, +-147, 1288, -82, 269, 46, -931, 112, -1649, +99, -1441, 34, -377, -38, 942, -56, 1741, +-17, 1579, 23, 515, 76, -843, 100, -1723, +13, -1645, -145, -679, -232, 648, -181, 1578, +-17, 1615, 156, 771, 263, -452, 274, -1357, +181, -1464, -30, -787, -276, 272, -394, 1134, +-302, 1325, -78, 781, 156, -144, 307, -928, +352, -1179, 257, -804, 0, -7, -297, 758, +-400, 1065, -274, 771, -33, 107, 197, -562, +310, -889, 262, -760, 103, -215, -127, 449, +-304, 812, -278, 670, -92, 180, 95, -353, +213, -661, 223, -614, 149, -271, 34, 236, +-101, 625, -207, 619, -205, 261, -138, -176, +-47, -450, 68, -474, 171, -297, 222, -29, +207, 299, 87, 476, -91, 343, -233, 17, +-280, -237, -214, -330, -35, -280, 167, -145, +298, 88, 291, 358, 132, 418, -108, 179, +-281, -155, -295, -372, -132, -420, 125, -289, +321, 12, 313, 372, 107, 573, -173, 423, +-355, 15, -330, -398, -117, -565, 152, -444, +350, -86, 366, 328, 189, 564, -74, 446, +-267, 57, -297, -363, -190, -556, -60, -389, +67, 17, 183, 425, 204, 613, 106, 438, +-19, -23, -99, -475, -89, -667, -38, -528, +-8, -112, 14, 367, 27, 676, -12, 637, +-66, 263, -86, -234, -7, -535, 126, -553, +155, -341, 64, 12, -21, 364, -86, 501, +-138, 328, -132, -38, -54, -338, 77, -391, +176, -222, 129, 44, 1, 328, -104, 480, +-162, 329, -151, -64, -47, -428, 115, -557, +270, -383, 274, -35, 75, 317, -192, 544, +-362, 511, -365, 163, -186, -262, 100, -508, +378, -455, 487, -167, 318, 185, -35, 426, +-332, 458, -434, 207, -321, -201, -55, -498, +238, -513, 376, -248, 252, 166, -54, 522, +-300, 646, -318, 450, -103, -24, 193, -521, +387, -753, 365, -621, 124, -179, -243, 370, +-488, 760, -416, 764, -95, 363, 217, -257, +348, -720, 283, -790, 104, -441, -108, 150, +-214, 680, -130, 838, 64, 507, 170, -135, +91, -701, -93, -847, -209, -512, -188, 103, +-59, 667, 102, 888, 205, 615, 181, -39, +33, -651, -138, -861, -166, -591, -31, -47, +126, 490, 177, 748, 81, 634, -117, 174, +-268, -368, -284, -643, -129, -533, 145, -197, +348, 174, 332, 431, 147, 475, -118, 309, +-317, -9, -310, -311, -124, -402, 109, -282, +253, -98, 208, 74, 50, 221, -111, 280, +-206, 232, -176, 60, -33, -124, 113, -195, +199, -160, 170, -131, 64, -75, -34, 54, +-118, 179, -206, 195, -236, 92, -154, -46, +60, -137, 285, -171, 371, -162, 291, -41, +62, 179, -276, 315, -516, 263, -482, 51, +-141, -206, 340, -373, 632, -364, 539, -194, +169, 113, -317, 392, -685, 465, -680, 281, +-262, -49, 356, -333, 825, -415, 787, -294, +286, -21, -335, 279, -799, 429, -868, 320, +-427, 14, 265, -304, 814, -457, 868, -397, +371, -144, -263, 223, -619, 523, -635, 563, +-306, 327, 200, -61, 540, -416, 512, -592, +129, -511, -330, -195, -471, 235, -300, 526, +-33, 516, 224, 246, 364, -90, 314, -338, +113, -377, -170, -204, -285, 74, -158, 294, +-44, 309, -36, 93, -40, -186, -23, -311, +47, -247, 102, -68, 122, 134, 192, 265, +195, 291, -3, 187, -235, -21, -357, -182, +-284, -209, -45, -210, 161, -174, 276, -69, +324, 111, 167, 291, -119, 332, -319, 180, +-338, -55, -140, -282, 156, -395, 315, -269, +322, 44, 169, 368, -129, 478, -391, 264, +-454, -143, -275, -478, 104, -516, 434, -226, +535, 234, 389, 579, 27, 608, -393, 242, +-622, -304, -541, -683, -147, -647, 352, -247, +649, 274, 601, 635, 237, 658, -295, 323, +-674, -199, -674, -573, -283, -587, 285, -288, +684, 110, 698, 402, 364, 480, -183, 324, +-650, 0, -778, -320, -510, -434, 38, -337, +580, -91, 783, 170, 609, 346, 181, 395, +-348, 297, -728, 33, -743, -262, -370, -437, +215, -428, 658, -235, 719, 45, 419, 312, +-81, 500, -545, 488, -716, 211, -502, -183, +12, -473, 542, -560, 760, -415, 531, -91, +19, 301, -482, 608, -720, 647, -609, 327, +-174, -155, 376, -564, 735, -732, 684, -552, +249, -82, -303, 454, -638, 811, -646, 756, +-362, 286, 95, -355, 515, -836, 679, -899, +498, -480, 46, 201, -395, 816, -592, 1038, +-519, 728, -236, 15, 161, -759, 492, -1187, +586, -1021, 349, -325, -81, 565, -423, 1198, +-513, 1254, -356, 697, 4, -211, 377, -1057, +548, -1384, 398, -982, -9, -48, -433, 882, +-596, 1324, -446, 1055, -70, 240, 362, -704, +611, -1304, 510, -1181, 140, -349, -274, 690, +-467, 1316, -373, 1229, -133, 518, 123, -439, +294, -1166, 226, -1315, -4, -785, -203, 120, +-237, 876, -73, 1091, 144, 806, 223, 228, +220, -369, 150, -729, -32, -709, -202, -361, +-256, 98, -185, 400, -14, 455, 64, 349, +32, 107, 41, -208, 61, -439, 52, -441, +88, -210, 111, 107, 122, 385, 77, 541, +-109, 501, -276, 194, -263, -265, -144, -634, +47, -682, 201, -441, 222, -43, 165, 380, +25, 673, -160, 669, -193, 333, -94, -164, +48, -542, 188, -620, 199, -411, 67, -30, +-76, 383, -199, 638, -217, 540, -130, 92, +-40, -431, 54, -755, 154, -675, 152, -223, +106, 394, 97, 892, 91, 986, 35, 516, +-90, -273, -243, -952, -280, -1170, -164, -773, +5, 42, 145, 829, 244, 1179, 239, 895, +100, 142, -109, -652, -230, -1069, -154, -894, +45, -211, 163, 550, 173, 951, 124, 798, +-38, 219, -277, -426, -393, -821, -291, -808, +9, -338, 346, 318, 525, 752, 478, 786, +217, 442, -224, -86, -602, -512, -669, -749, +-378, -655, 128, -184, 551, 343, 638, 654, +412, 692, -36, 404, -512, -46, -686, -466, +-406, -740, 127, -627, 574, -139, 640, 370, +356, 674, -78, 670, -499, 336, -685, -153, +-466, -593, 1, -786, 435, -522, 573, 34, +378, 517, 88, 708, -136, 588, -318, 220, +-372, -233, -251, -603, -10, -684, 210, -389, +256, 61, 184, 401, 167, 529, 77, 450, +-175, 207, -398, -139, -392, -466, -144, -557, +195, -339, 420, 20, 509, 384, 415, 591, +30, 543, -500, 239, -789, -243, -615, -716, +-76, -852, 462, -540, 735, 63, 683, 678, +307, 988, -300, 838, -777, 318, -780, -401, +-318, -1028, 276, -1121, 693, -605, 764, 192, +458, 900, -121, 1145, -694, 817, -923, 106, +-623, -733, 8, -1290, 612, -1107, 912, -304, +786, 675, 264, 1363, -417, 1363, -899, 680, +-865, -354, -380, -1326, 219, -1694, 639, -1164, +748, -27, 504, 1124, 18, 1720, -466, 1456, +-657, 508, -493, -672, -140, -1542, 214, -1637, +457, -861, 505, 330, 348, 1305, 23, 1585, +-313, 1059, -492, 21, -443, -1037, -216, -1596, +71, -1307, 308, -335, 474, 795, 445, 1538, +168, 1520, -194, 750, -454, -391, -507, -1398, +-324, -1702, -21, -1119, 327, 3, 580, 1107, +535, 1673, 200, 1383, -258, 409, -658, -761, +-708, -1550, -390, -1501, 83, -659, 572, 458, +859, 1295, 702, 1453, 172, 866, -488, -116, +-916, -992, -843, -1363, -363, -1003, 260, -162, +792, 663, 918, 1092, 559, 981, -81, 441, +-680, -222, -912, -761, -628, -939, -39, -644, +544, -86, 839, 442, 714, 718, 233, 677, +-355, 391, -770, -70, -804, -537, -450, -746, +122, -576, 619, -130, 831, 369, 666, 645, +196, 636, -355, 342, -749, -148, -845, -588, +-528, -715, 72, -452, 630, 45, 872, 481, +699, 639, 200, 498, -360, 146, -776, -277, +-838, -579, -451, -577, 163, -273, 661, 129, +820, 424, 557, 471, 66, 315, -430, 64, +-771, -198, -744, -368, -302, -314, 278, -108, +739, 96, 827, 198, 484, 171, -51, 86, +-579, 31, -910, -20, -762, -83, -236, -101, +390, -114, 891, -142, 945, -93, 517, 34, +-70, 229, -677, 411, -1026, 388, -834, 93, +-267, -303, 443, -630, 1019, -685, 999, -383, +469, 157, -226, 700, -877, 948, -1086, 689, +-667, 42, 63, -634, 816, -993, 1159, -853, +804, -264, 83, 462, -637, 960, -1123, 945, +-1007, 393, -360, -398, 439, -956, 1066, -1008, +1136, -506, 596, 288, -146, 929, -825, 1123, +-1155, 748, -867, -55, -127, -824, 657, -1180, +1088, -954, 892, -230, 279, 552, -399, 1019, +-906, 1038, -961, 535, -451, -215, 276, -812, +810, -992, 878, -644, 499, 22, -42, 576, +-515, 838, -808, 717, -700, 198, -227, -427, +300, -837, 641, -818, 685, -343, 447, 290, +106, 748, -302, 897, -665, 648, -702, 27, +-385, -646, 57, -1027, 474, -874, 685, -288, +612, 394, 275, 878, -265, 985, -726, 600, +-758, -106, -405, -764, 136, -996, 637, -661, +811, -39, 545, 540, -6, 847, -599, 715, +-883, 207, -671, -421, -112, -816, 480, -711, +842, -225, 778, 291, 318, 664, -290, 730, +-739, 432, -838, -103, -536, -606, 0, -767, +528, -508, 831, -60, 750, 367, 280, 655, +-312, 661, -776, 328, -898, -202, -565, -616, +63, -671, 675, -412, 1014, -7, 836, 387, +212, 650, -515, 621, -1011, 254, -1024, -278, +-513, -652, 233, -676, 883, -397, 1100, 26, +751, 472, 60, 758, -638, 680, -1052, 224, +-911, -391, -299, -799, 436, -770, 950, -401, +987, 140, 530, 669, -177, 919, -857, 689, +-1125, 63, -767, -649, -20, -1005, 715, -819, +1128, -267, 976, 396, 354, 928, -422, 1033, +-1031, 609, -1145, -137, -630, -847, 176, -1109, +831, -782, 1042, -149, 760, 519, 170, 970, +-481, 951, -963, 456, -947, -276, -404, -902, +292, -999, 789, -548, 949, 125, 696, 739, +116, 1014, -570, 761, -1059, 81, -1055, -699, +-494, -1143, 309, -946, 954, -248, 1168, 544, +869, 1082, 146, 1104, -694, 583, -1250, -225, +-1177, -911, -484, -1144, 424, -778, 1071, -86, +1244, 566, 851, 926, 15, 832, -869, 367, +-1355, -211, -1176, -689, -371, -824, 611, -544, +1306, -81, 1414, 419, 823, 764, -228, 730, +-1197, 404, -1608, -108, -1190, -643, -151, -884, +945, -721, 1572, -258, 1428, 414, 545, 911, +-621, 954, -1489, 596, -1578, -80, -832, -772, +313, -1042, 1304, -811, 1679, -200, 1168, 564, +38, 1001, -1136, 892, -1745, 369, -1413, -387, +-360, -935, 818, -930, 1620, -480, 1618, 215, +752, 861, -487, 1023, -1444, 666, -1628, -22, +-945, -750, 143, -1071, 1084, -840, 1484, -247, +1147, 492, 229, 1013, -773, 994, -1356, 491, +-1210, -255, -455, -878, 444, -996, 1047, -608, +1180, 37, 789, 660, -3, 940, -799, 697, +-1141, 108, -912, -547, -299, -904, 374, -724, +839, -200, 962, 371, 688, 795, 47, 810, +-625, 404, -962, -172, -836, -688, -334, -827, +308, -516, 804, -67, 982, 386, 670, 683, +-80, 613, -823, 283, -1092, -125, -796, -473, +-107, -513, 633, -316, 1091, -79, 1029, 198, +395, 382, -504, 345, -1102, 169, -1104, -97, +-575, -323, 193, -325, 841, -181, 1089, 8, +823, 261, 128, 401, -606, 326, -982, 82, +-855, -239, -349, -448, 277, -403, 740, -217, +870, 56, 554, 349, -62, 481, -593, 389, +-776, 112, -593, -218, -143, -414, 322, -422, +627, -287, 680, -18, 400, 301, -88, 501, +-475, 476, -632, 214, -536, -160, -244, -489, +142, -619, 521, -501, 709, -100, 508, 424, +56, 764, -373, 758, -629, 395, -625, -213, +-320, -742, 163, -933, 631, -703, 796, -61, +499, 633, -70, 968, -573, 855, -825, 293, +-717, -461, -247, -957, 429, -967, 985, -467, +1047, 348, 512, 939, -264, 1015, -898, 605, +-1166, -156, -904, -878, -148, -1132, 744, -796, +1307, -4, 1163, 825, 403, 1165, -513, 904, +-1184, 223, -1319, -620, -770, -1179, 185, -1118, +1089, -442, 1462, 505, 1027, 1173, 78, 1182, +-845, 638, -1404, -199, -1290, -975, -509, -1284, +525, -934, 1319, -84, 1437, 797, 770, 1205, +-230, 1000, -1083, 359, -1440, -423, -1051, -985, +-96, -1040, 896, -557, 1465, 220, 1257, 825, +361, 943, -685, 583, -1383, -26, -1441, -619, +-758, -909, 324, -739, 1243, -197, 1565, 438, +1124, 834, 125, 802, -888, 445, -1468, -51, +-1358, -532, -566, -781, 488, -672, 1251, -305, +1415, 161, 846, 508, -184, 631, -1070, 521, +-1373, 197, -976, -243, -44, -546, 898, -549, +1385, -287, 1191, 101, 345, 471, -710, 632, +-1387, 429, -1389, -63, -688, -606, 331, -863, +1132, -628, 1432, -65, 1100, 582, 202, 1042, +-768, 1003, -1325, 423, -1222, -392, -554, -1070, +271, -1193, 929, -701, 1225, 73, 891, 793, +70, 1146, -737, 904, -1151, 216, -983, -545, +-310, -1018, 481, -915, 1075, -352, 1186, 318, +638, 839, -305, 948, -1096, 545, -1337, -133, +-876, -745, 13, -995, 868, -702, 1353, -88, +1208, 560, 379, 974, -661, 878, -1303, 330, +-1256, -361, -607, -898, 310, -971, 1030, -537, +1232, 118, 808, 735, -38, 999, -822, 727, +-1097, 133, -821, -513, -186, -947, 503, -905, +912, -416, 862, 242, 422, 820, -235, 999, +-750, 675, -844, 63, -571, -585, -85, -1005, +472, -901, 798, -336, 737, 363, 339, 911, +-237, 1004, -661, 573, -716, -110, -497, -786, +-48, -1105, 467, -792, 708, -78, 572, 636, +179, 1069, -304, 950, -574, 354, -555, -403, +-316, -1006, 117, -1078, 510, -545, 577, 193, +375, 770, 16, 972, -335, 697, -483, 110, +-425, -508, -205, -876, 147, -738, 385, -239, +406, 263, 291, 575, 61, 630, -193, 411, +-324, 35, -347, -368, -215, -568, 63, -427, +280, -138, 341, 117, 282, 318, 46, 411, +-250, 334, -410, 98, -367, -202, -99, -368, +275, -329, 462, -207, 417, -30, 170, 200, +-259, 378, -562, 363, -476, 168, -147, -103, +276, -299, 561, -340, 474, -270, 130, -101, +-279, 155, -595, 320, -510, 291, -105, 162, +289, -23, 546, -158, 507, -175, 141, -166, +-220, -99, -448, 28, -472, 85, -197, 93, +146, 114, 330, 70, 359, 20, 162, -52, +-98, -166, -218, -185, -250, -89, -149, 44, +95, 204, 220, 298, 200, 236, 111, 61, +-54, -202, -176, -413, -195, -399, -178, -195, +-59, 112, 92, 389, 162, 468, 198, 325, +175, 47, 41, -284, -74, -452, -153, -366, +-201, -111, -128, 190, 6, 360, 75, 320, +120, 156, 109, -84, 32, -301, -21, -330, +-54, -184, -79, 41, -16, 226, 28, 258, +11, 196, 41, 96, 62, -50, 8, -177, +-20, -202, -44, -151, -74, -76, -51, -24, +-32, 32, -6, 131, 98, 221, 143, 218, +90, 107, 28, -51, -64, -198, -161, -294, +-160, -273, -107, -102, 28, 159, 211, 343, +251, 340, 119, 155, -35, -94, -184, -282, +-265, -329, -203, -231, -22, -11, 201, 210, +346, 292, 256, 226, 20, 55, -178, -113, +-281, -178, -279, -169, -137, -105, 67, 6, +254, 92, 316, 121, 190, 109, -3, 37, +-120, -15, -209, -44, -256, -95, -202, -128, +-46, -91, 153, 7, 291, 137, 270, 207, +165, 175, 19, 78, -177, -102, -329, -297, +-326, -358, -160, -224, 114, 73, 313, 362, +342, 451, 258, 332, 72, 71, -211, -284, +-415, -514, -414, -479, -187, -196, 148, 210, +385, 478, 435, 472, 329, 296, 27, 3, +-323, -313, -472, -447, -383, -369, -134, -127, +183, 157, 373, 285, 372, 272, 202, 214, +-88, 78, -305, -98, -304, -198, -176, -217, +44, -140, 260, -23, 305, 70, 175, 160, +-46, 213, -273, 124, -317, -66, -183, -223, +-10, -274, 166, -167, 306, 56, 289, 273, +139, 390, -70, 311, -226, 20, -260, -308, +-219, -475, -153, -414, 17, -120, 230, 232, +322, 444, 253, 435, 96, 204, -99, -133, +-262, -363, -343, -393, -270, -218, -17, 88, +270, 319, 383, 358, 322, 220, 125, -43, +-160, -282, -399, -372, -450, -298, -262, -76, +116, 208, 431, 376, 499, 368, 340, 209, +7, -41, -394, -251, -609, -341, -505, -304, +-101, -120, 391, 122, 655, 266, 567, 271, +225, 163, -270, -9, -681, -160, -724, -234, +-353, -179, 234, -4, 705, 180, 749, 242, +407, 170, -130, 22, -668, -152, -890, -283, +-569, -273, 91, -112, 734, 123, 1003, 317, +713, 329, 52, 194, -635, 2, -1084, -223, +-984, -366, -331, -325, 493, -133, 1082, 141, +1136, 343, 584, 336, -200, 220, -864, 23, +-1167, -231, -861, -377, -86, -336, 672, -117, +1090, 194, 946, 359, 312, 314, -433, 184, +-972, -48, -1044, -297, -500, -379, 292, -263, +882, 24, 1050, 305, 678, 335, -74, 189, +-763, 22, -1076, -190, -822, -309, -125, -240, +583, -37, 994, 221, 954, 323, 395, 155, +-364, -49, -917, -163, -1023, -230, -592, -175, +141, -18, 748, 157, 1009, 277, 787, 197, +146, -30, -552, -167, -955, -188, -888, -163, +-365, -50, 272, 95, 718, 215, 855, 250, +589, 104, 18, -122, -514, -228, -784, -227, +-663, -144, -221, 39, 264, 211, 610, 296, +715, 235, 434, -13, -70, -248, -498, -289, +-699, -196, -569, -5, -160, 206, 265, 273, +586, 194, 689, -13, 453, -256, -1, -305, +-432, -141, -690, 83, -623, 286, -289, 332, +146, 171, 572, -64, 768, -287, 531, -379, +31, -225, -465, 38, -745, 242, -656, 321, +-238, 217, 294, 9, 723, -146, 782, -234, +407, -194, -165, -6, -633, 161, -792, 209, +-555, 137, -71, -35, 440, -184, 763, -230, +706, -196, 277, -38, -251, 199, -619, 331, +-679, 293, -449, 105, -38, -143, 402, -309, +669, -340, 578, -239, 215, 21, -202, 296, +-504, 395, -585, 282, -407, 14, -58, -256, +337, -370, 573, -313, 516, -116, 225, 195, +-154, 428, -470, 421, -544, 185, -363, -171, +-6, -429, 385, -449, 580, -286, 448, 13, +99, 369, -308, 531, -556, 393, -501, 39, +-212, -340, 163, -505, 492, -402, 571, -141, +354, 211, -11, 502, -361, 512, -537, 251, +-444, -139, -171, -457, 176, -521, 448, -348, +486, -56, 278, 280, -54, 511, -370, 486, +-480, 241, -334, -119, -39, -409, 275, -478, +472, -344, 415, -68, 143, 275, -214, 499, +-469, 462, -475, 172, -247, -242, 78, -526, +391, -535, 522, -297, 373, 123, 28, 533, +-322, 685, -495, 488, -398, 11, -118, -500, +212, -724, 442, -586, 441, -182, 199, 324, +-137, 661, -400, 648, -441, 309, -278, -206, +-20, -596, 259, -620, 459, -327, 418, 113, +152, 501, -166, 625, -375, 439, -408, 22, +-268, -449, -17, -684, 279, -547, 446, -165, +339, 287, 45, 597, -235, 621, -389, 373, +-351, -70, -155, -488, 127, -615, 402, -423, +503, -49, 308, 314, -43, 474, -357, 406, +-508, 155, -450, -206, -211, -442, 130, -403, +469, -156, 587, 170, 393, 392, 36, 395, +-286, 244, -482, -22, -487, -329, -282, -464, +88, -362, 437, -97, 563, 212, 397, 384, +45, 363, -340, 227, -582, -16, -553, -279, +-226, -368, 255, -261, 639, -30, 703, 205, +394, 287, -147, 227, -624, 93, -794, -120, +-553, -289, -24, -275, 524, -112, 805, 122, +679, 280, 192, 268, -397, 153, -773, -15, +-753, -213, -364, -299, 208, -218, 679, -30, +826, 185, 562, 270, 19, 189, -546, 43, +-854, -124, -740, -263, -245, -250, 367, -86, +805, 150, 848, 338, 459, 314, -172, 120, +-707, -99, -887, -306, -615, -408, -34, -283, +561, -8, 882, 291, 759, 450, 228, 341, +-412, 86, -836, -168, -861, -371, -466, -392, +183, -163, 755, 158, 969, 402, 681, 418, +25, 162, -618, -179, -932, -437, -824, -526, +-310, -332, 371, 97, 865, 508, 938, 697, +541, 533, -130, 79, -664, -384, -867, -667, +-720, -682, -235, -364, 380, 137, 778, 544, +797, 675, 431, 446, -93, 24, -492, -325, +-679, -512, -589, -464, -180, -160, 281, 218, +553, 478, 566, 485, 311, 214, -70, -142, +-380, -408, -556, -527, -467, -403, -103, -70, +303, 300, 561, 555, 566, 549, 260, 280, +-170, -65, -525, -355, -674, -510, -465, -437, +31, -181, 490, 135, 704, 369, 569, 388, +147, 222, -338, 12, -688, -170, -725, -279, +-333, -254, 236, -103, 653, 104, 778, 257, +530, 281, -21, 190, -572, 34, -866, -155, +-721, -336, -177, -403, 442, -278, 824, -4, +829, 284, 394, 470, -259, 473, -752, 291, +-858, -36, -518, -406, 118, -604, 652, -492, +843, -142, 622, 257, 39, 534, -581, 567, +-864, 337, -731, -91, -224, -522, 416, -683, +819, -462, 837, 13, 477, 485, -165, 735, +-698, 645, -840, 232, -610, -350, -112, -800, +427, -839, 720, -440, 690, 159, 315, 652, +-240, 828, -600, 617, -620, 113, -385, -454, +55, -783, 470, -671, 633, -210, 494, 314, +76, 646, -413, 656, -649, 343, -585, -144, +-263, -595, 221, -742, 610, -465, 709, 44, +493, 509, 5, 728, -481, 582, -706, 150, +-628, -360, -276, -733, 230, -702, 616, -257, +724, 293, 491, 676, 3, 713, -458, 357, +-674, -179, -608, -643, -239, -816, 250, -514, +570, 86, 608, 616, 386, 847, -20, 654, +-370, 130, -516, -431, -448, -796, -189, -785, +141, -363, 375, 207, 476, 636, 373, 746, +66, 480, -265, 11, -482, -421, -516, -643, +-265, -529, 153, -134, 506, 300, 638, 563, +440, 512, -23, 177, -465, -218, -705, -478, +-609, -501, -159, -254, 372, 128, 693, 417, +716, 474, 382, 267, -160, -74, -611, -319, +-774, -374, -567, -253, -60, -13, 456, 206, +756, 277, 708, 206, 295, 41, -260, -104, +-662, -125, -756, -92, -472, -78, 38, -57, +490, -40, 699, -28, 597, 31, 209, 116, +-261, 202, -596, 237, -657, 105, -406, -136, +36, -319, 449, -358, 670, -226, 576, 40, +186, 302, -317, 449, -675, 364, -698, 37, +-361, -321, 162, -499, 625, -416, 794, -109, +558, 266, 14, 533, -535, 549, -814, 249, +-693, -218, -225, -576, 366, -649, 774, -397, +809, 51, 426, 481, -187, 702, -688, 587, +-832, 155, -580, -356, -36, -678, 529, -662, +842, -324, 739, 166, 248, 577, -366, 705, +-755, 469, -779, -24, -447, -512, 109, -729, +615, -574, 807, -124, 595, 406, 69, 745, +-454, 701, -711, 306, -638, -263, -265, -719, +269, -805, 646, -486, 666, 76, 345, 616, +-136, 833, -517, 630, -614, 141, -432, -427, +-42, -789, 369, -737, 561, -321, 449, 245, +153, 674, -181, 755, -398, 484, -434, 0, +-300, -502, -28, -767, 274, -639, 403, -190, +341, 334, 178, 674, -60, 693, -307, 400, +-428, -85, -353, -555, -64, -766, 269, -569, +429, -81, 390, 417, 204, 695, -123, 651, +-420, 312, -500, -186, -304, -632, 75, -757, +411, -471, 513, 29, 385, 475, 61, 689, +-333, 591, -560, 221, -489, -293, -167, -702, +259, -722, 521, -354, 509, 158, 291, 588, +-52, 746, -381, 564, -495, 108, -384, -457, +-123, -820, 167, -728, 350, -291, 382, 251, +282, 674, 34, 780, -215, 537, -328, 45, +-300, -501, -152, -778, 80, -629, 262, -216, +328, 263, 221, 606, -31, 653, -249, 411, +-321, -42, -276, -502, -78, -686, 196, -508, +380, -113, 382, 334, 188, 633, -135, 643, +-378, 356, -433, -132, -298, -583, -3, -733, +312, -524, 454, -92, 374, 380, 112, 670, +-189, 646, -359, 333, -369, -154, -248, -571, +2, -676, 239, -450, 344, -31, 311, 404, +161, 632, -61, 571, -262, 255, -391, -226, +-329, -620, -59, -693, 234, -449, 388, 12, +376, 488, 178, 728, -126, 659, -383, 282, +-443, -294, -237, -721, 112, -774, 354, -474, +409, 60, 267, 556, -15, 768, -290, 652, +-424, 194, -348, -401, -51, -754, 258, -717, +380, -339, 312, 210, 124, 632, -120, 765, +-297, 563, -342, 40, -198, -525, 70, -805, +259, -693, 264, -247, 166, 298, 7, 683, +-152, 782, -230, 507, -193, -61, -41, -591, +151, -801, 229, -602, 175, -106, 52, 406, +-93, 711, -198, 690, -210, 299, -136, -276, +25, -686, 194, -722, 253, -389, 183, 125, +61, 545, -78, 707, -201, 539, -250, 78, +-180, -439, -24, -707, 133, -610, 217, -221, +228, 257, 154, 592, 5, 650, -170, 402, +-264, -75, -220, -531, -58, -685, 139, -490, +278, -65, 269, 388, 112, 637, -129, 585, +-330, 248, -360, -240, -180, -604, 98, -624, +337, -341, 416, 91, 301, 462, 45, 597, +-247, 455, -451, 93, -436, -318, -214, -538, +91, -470, 345, -193, 456, 151, 346, 400, +56, 460, -272, 319, -447, 23, -374, -269, +-94, -413, 224, -357, 419, -149, 376, 104, +116, 297, -224, 372, -446, 282, -427, 54, +-159, -193, 202, -343, 458, -331, 476, -178, +253, 42, -102, 242, -400, 340, -497, 280, +-334, 76, -1, -167, 325, -313, 471, -300, +383, -151, 108, 76, -205, 263, -420, 316, +-438, 211, -243, -34, 74, -280, 358, -356, +490, -246, 392, -13, 108, 254, -227, 398, +-470, 348, -509, 127, -283, -205, 95, -446, +421, -439, 516, -228, 335, 87, -10, 373, +-324, 468, -477, 355, -376, 79, -61, -259, +289, -446, 476, -384, 409, -155, 127, 129, +-200, 338, -435, 367, -483, 221, -304, -50, +44, -306, 381, -369, 537, -224, 426, 21, +125, 248, -220, 353, -463, 289, -511, 91, +-308, -173, 65, -353, 402, -336, 497, -168, +338, 49, 35, 235, -273, 322, -465, 286, +-422, 137, -153, -93, 205, -271, 450, -306, +463, -233, 251, -65, -77, 151, -384, 306, +-515, 333, -412, 195, -94, -85, 289, -314, +530, -365, 492, -253, 218, 15, -157, 310, +-447, 447, -519, 363, -337, 62, 20, -326, +368, -532, 495, -458, 351, -165, 45, 250, +-251, 554, -399, 571, -342, 312, -119, -114, +173, -495, 353, -596, 328, -419, 136, -65, +-114, 318, -301, 520, -313, 456, -172, 192, +53, -143, 257, -373, 325, -394, 219, -244, +13, 7, -197, 238, -297, 326, -248, 256, +-103, 76, 68, -128, 218, -260, 272, -273, +207, -175, 57, 10, -112, 194, -235, 287, +-266, 265, -210, 135, -51, -66, 170, -246, +337, -324, 349, -259, 204, -57, -64, 163, +-326, 288, -453, 293, -383, 158, -107, -70, +280, -255, 536, -301, 509, -185, 211, 48, +-203, 239, -518, 299, -559, 230, -298, 25, +151, -224, 520, -368, 582, -337, 311, -138, +-135, 145, -507, 358, -589, 428, -358, 330, +65, 54, 464, -279, 610, -491, 432, -478, +52, -237, -334, 124, -522, 434, -449, 558, +-196, 405, 128, 19, 370, -399, 399, -607, +246, -479, 13, -92, -187, 354, -281, 636, +-263, 581, -141, 184, 66, -342, 231, -704, +282, -675, 225, -258, 62, 294, -161, 699, +-320, 752, -344, 392, -206, -194, 46, -684, +292, -812, 411, -488, 341, 87, 108, 584, +-161, 782, -350, 582, -381, 71, -234, -479, +31, -776, 266, -654, 360, -181, 273, 351, +61, 679, -176, 673, -327, 323, -312, -194, +-126, -612, 129, -715, 325, -432, 360, 79, +214, 516, -44, 690, -280, 534, -371, 101, +-270, -384, -55, -689, 172, -659, 310, -281, +289, 227, 117, 592, -97, 692, -242, 479, +-242, 28, -117, -421, 51, -668, 186, -602, +237, -224, 159, 237, -11, 543, -192, 607, +-283, 379, -232, -50, -75, -429, 112, -600, +271, -469, 325, -72, 229, 345, 23, 578, +-196, 550, -324, 224, -295, -240, -151, -582, +43, -667, 226, -414, 315, 77, 250, 521, +68, 729, -148, 601, -283, 152, -281, -369, +-148, -706, 62, -721, 273, -358, 356, 179, +247, 601, -7, 730, -271, 485, -406, -13, +-342, -476, -113, -695, 197, -558, 435, -104, +449, 388, 219, 663, -112, 609, -382, 230, +-462, -267, -324, -610, -30, -662, 295, -385, +474, 102, 379, 504, 101, 637, -195, 473, +-379, 87, -376, -316, -189, -537, 87, -501, +321, -218, 367, 166, 212, 416, -28, 440, +-227, 255, -301, -58, -219, -328, -51, -418, +133, -297, 262, -6, 252, 294, 104, 416, +-74, 331, -198, 97, -221, -192, -157, -384, +-31, -383, 120, -200, 218, 81, 186, 298, +65, 328, -63, 215, -147, 29, -160, -145, +-104, -217, -13, -173, 85, -55, 132, 78, +106, 127, 45, 85, -19, 33, -76, -17, +-97, -52, -97, -61, -68, -63, 13, -51, +110, -16, 153, 23, 130, 86, 38, 157, +-83, 155, -173, 63, -187, -87, -90, -228, +84, -265, 206, -165, 203, 17, 77, 214, +-109, 318, -239, 241, -229, 38, -95, -180, +121, -301, 302, -245, 311, -51, 143, 153, +-92, 264, -283, 224, -334, 48, -233, -150, +-25, -253, 202, -213, 323, -50, 268, 133, +99, 221, -92, 181, -217, 48, -219, -108, +-125, -183, 7, -140, 135, -24, 179, 105, +116, 170, 1, 122, -103, 10, -150, -97, +-122, -154, -54, -131, 53, -53, 165, 44, +199, 125, 123, 136, -13, 78, -146, 5, +-213, -46, -197, -70, -94, -62, 86, -28, +242, 19, 255, 48, 133, 25, -54, -33, +-210, -67, -266, -63, -190, -34, -7, 27, +200, 103, 296, 159, 224, 141, 40, 29, +-154, -112, -268, -187, -242, -183, -98, -112, +94, 21, 231, 146, 239, 197, 120, 136, +-52, -18, -183, -148, -202, -158, -117, -83, +21, 36, 144, 162, 204, 197, 159, 108, +26, -63, -121, -232, -204, -268, -200, -141, +-113, 40, 22, 200, 158, 278, 238, 200, +218, 19, 96, -163, -68, -254, -205, -181, +-256, -7, -195, 132, -45, 196, 128, 159, +249, 22, 245, -127, 115, -210, -79, -177, +-238, -30, -263, 119, -139, 181, 59, 166, +246, 78, 311, -47, 193, -139, -43, -166, +-260, -107, -344, 13, -246, 101, -22, 119, +215, 99, 343, 35, 293, -51, 90, -108, +-146, -122, -300, -64, -298, 44, -149, 116, +57, 141, 212, 120, 265, 19, 192, -107, +32, -187, -131, -186, -221, -70, -207, 97, +-98, 202, 36, 213, 146, 126, 197, -51, +163, -202, 53, -248, -71, -172, -161, 18, +-188, 201, -135, 249, -20, 177, 108, 20, +201, -156, 201, -223, 100, -162, -57, -21, +-194, 145, -244, 202, -176, 111, -23, -36, +159, -171, 278, -214, 250, -108, 92, 68, +-99, 219, -242, 276, -269, 168, -166, -36, +13, -206, 174, -281, 244, -223, 189, -57, +51, 114, -107, 218, -211, 215, -194, 94, +-70, -48, 80, -128, 190, -129, 200, -59, +99, 42, -62, 102, -199, 103, -230, 38, +-136, -70, 20, -142, 168, -148, 246, -95, +196, 17, 49, 138, -105, 204, -209, 201, +-220, 103, -126, -61, 30, -191, 165, -247, +217, -203, 159, -53, 30, 127, -113, 240, +-209, 238, -196, 99, -71, -101, 86, -227, +197, -233, 212, -111, 125, 102, -21, 275, +-154, 302, -227, 162, -197, -102, -69, -340, +84, -402, 186, -265, 206, 26, 137, 338, +20, 493, -96, 402, -172, 108, -161, -267, +-62, -522, 43, -514, 109, -247, 116, 149, +60, 478, -20, 563, -77, 363, -92, -24, +-44, -411, 35, -584, 91, -436, 97, -50, +50, 362, -35, 581, -102, 492, -128, 130, +-99, -316, -11, -610, 86, -572, 135, -214, +132, 270, 71, 617, -24, 637, -98, 323, +-127, -154, -103, -557, -28, -679, 44, -442, +92, 23, 102, 457, 50, 636, -22, 476, +-66, 90, -85, -312, -55, -543, 17, -487, +66, -160, 76, 239, 55, 481, -1, 458, +-46, 198, -63, -155, -62, -419, -27, -480, +10, -294, 17, 53, 31, 363, 46, 480, +43, 374, 38, 97, 9, -211, -46, -409, +-68, -422, -57, -239, -28, 58, 33, 297, +79, 372, 64, 280, 11, 63, -64, -176, +-102, -313, -54, -296, 31, -128, 104, 117, +140, 293, 83, 314, -44, 186, -152, -46, +-186, -271, -119, -367, 19, -278, 144, -40, +203, 234, 159, 391, 18, 356, -128, 148, +-197, -139, -174, -363, -48, -404, 109, -247, +195, 37, 179, 301, 76, 400, -77, 295, +-188, 48, -194, -215, -99, -352, 42, -304, +139, -106, 155, 141, 114, 300, 21, 290, +-87, 140, -131, -78, -95, -245, -21, -276, +51, -174, 77, 7, 63, 192, 28, 277, +-30, 231, -80, 89, -75, -98, -25, -247, +38, -287, 75, -219, 58, -55, 22, 151, +2, 296, -24, 315, -40, 215, -19, 15, +-2, -191, -16, -312, -42, -311, -49, -177, +-11, 40, 54, 217, 90, 284, 94, 233, +66, 77, -12, -96, -96, -198, -132, -210, +-110, -114, -28, 43, 72, 161, 121, 193, +105, 139, 35, 5, -69, -138, -137, -227, +-121, -222, -24, -104, 115, 82, 197, 238, +162, 306, 42, 246, -119, 67, -241, -156, +-229, -330, -95, -362, 81, -214, 219, 31, +242, 258, 142, 366, -14, 292, -156, 71, +-207, -179, -140, -342, -12, -312, 114, -97, +183, 165, 140, 334, 16, 326, -116, 121, +-201, -161, -180, -373, -52, -405, 112, -206, +237, 123, 258, 383, 142, 459, -49, 312, +-225, 0, -304, -308, -227, -455, -38, -393, +154, -129, 274, 194, 257, 389, 101, 380, +-94, 196, -223, -72, -228, -279, -108, -329, +56, -214, 168, 12, 193, 216, 113, 271, +-31, 187, -151, 25, -192, -135, -139, -214, +-16, -182, 103, -67, 168, 83, 172, 179, +98, 174, -38, 96, -151, -6, -185, -100, +-132, -154, -13, -157, 112, -95, 187, 14, +176, 113, 50, 162, -121, 157, -215, 93, +-191, -11, -65, -126, 111, -194, 234, -163, +229, -42, 101, 78, -98, 147, -246, 147, +-247, 77, -114, -32, 81, -116, 222, -126, +226, -40, 116, 74, -62, 120, -221, 86, +-236, 2, -98, -101, 93, -152, 235, -119, +247, -14, 121, 117, -68, 184, -231, 121, +-278, -3, -163, -111, 32, -153, 198, -97, +258, 25, 181, 129, 21, 165, -121, 84, +-201, -90, -182, -218, -68, -210, 59, -78, +137, 121, 149, 273, 92, 289, 2, 157, +-85, -81, -147, -304, -142, -351, -61, -195, +42, 58, 134, 277, 181, 344, 132, 221, +14, -28, -108, -276, -195, -370, -198, -231, +-99, 56, 47, 316, 176, 404, 224, 266, +157, -20, 20, -308, -124, -451, -220, -354, +-200, -48, -71, 280, 80, 452, 187, 383, +193, 125, 89, -179, -51, -384, -153, -394, +-175, -187, -100, 121, 24, 344, 128, 368, +173, 192, 129, -84, 19, -301, -88, -361, +-161, -239, -180, 22, -101, 275, 39, 362, +160, 261, 216, 30, 171, -203, 47, -308, +-91, -262, -197, -104, -210, 113, -112, 256, +20, 235, 127, 93, 182, -84, 143, -196, +42, -178, -55, -78, -126, 51, -130, 165, +-61, 187, 23, 92, 89, -40, 108, -145, +65, -174, 4, -122, -58, -35, -110, 58, +-89, 146, -17, 161, 40, 100, 80, 8, +90, -76, 59, -120, 16, -120, -31, -81, +-74, 8, -83, 105, -68, 135, -46, 86, +8, -5, 74, -91, 119, -120, 129, -94, +61, -16, -65, 98, -160, 164, -187, 120, +-133, 10, 14, -100, 178, -149, 261, -114, +209, -34, 27, 57, -179, 131, -287, 119, +-260, 20, -94, -78, 141, -114, 299, -80, +296, 3, 145, 67, -91, 92, -276, 86, +-303, 29, -184, -56, 30, -95, 237, -82, +315, -40, 241, 4, 49, 23, -175, 32, +-300, 51, -286, 46, -157, 19, 56, 4, +247, 0, 308, -11, 241, -23, 73, -32, +-143, -17, -284, 4, -284, -1, -154, -22, +51, -20, 217, -2, 259, 19, 184, 34, +14, 37, -166, 36, -237, 26, -181, -11, +-31, -44, 144, -40, 230, -16, 192, -5, +75, -9, -96, -15, -236, -5, -250, 8, +-150, 22, 20, 43, 188, 59, 251, 44, +203, 0, 80, -51, -95, -69, -216, -36, +-202, 2, -96, 15, 42, 21, 144, 7, +147, -27, 78, -49, -19, -40, -111, 12, +-124, 89, -53, 104, 40, 60, 118, 9, +128, -47, 56, -93, -29, -88, -101, -59, +-143, -9, -98, 34, 1, 23, 80, 1, +116, 18, 92, 44, 31, 65, -19, 74, +-59, 42, -66, -8, -27, -59, 0, -119, +0, -129, 5, -72, 0, 4, 2, 65, +24, 93, 36, 85, 31, 66, 15, 30, +-25, -20, -49, -48, -39, -44, -14, -32, +31, -22, 62, -13, 34, 3, -19, 18, +-60, 4, -80, -30, -48, -38, 29, -12, +94, 33, 114, 74, 74, 95, -14, 88, +-92, 43, -129, -48, -103, -133, -17, -147, +66, -100, 95, -27, 82, 48, 38, 89, +-23, 100, -56, 85, -46, 32, -18, -9, +18, -6, 39, -14, 27, -35, 3, -52, +-29, -63, -56, -43, -59, -1, -44, 20, +-3, 45, 69, 67, 113, 41, 98, -8, +54, -36, -22, -33, -111, 6, -149, 37, +-114, 33, -15, 19, 91, 1, 123, -44, +89, -79, 28, -69, -51, -16, -96, 49, +-70, 87, -8, 78, 64, 52, 98, 2, +56, -66, -18, -106, -71, -89, -92, -27, +-70, 56, -10, 111, 61, 119, 114, 79, +101, -10, 22, -120, -53, -182, -100, -161, +-117, -57, -65, 78, 32, 180, 112, 211, +141, 159, 95, 28, -10, -115, -105, -192, +-153, -179, -130, -87, -30, 32, 78, 108, +135, 129, 122, 89, 34, 2, -64, -72, +-94, -90, -69, -52, -11, 30, 62, 90, +83, 95, 32, 64, -45, 6, -97, -77, +-78, -131, -4, -126, 57, -69, 88, 14, +72, 84, 0, 113, -59, 112, -60, 81, +-24, 9, 38, -69, 85, -99, 53, -81, +-23, -35, -89, 10, -119, 44, -79, 62, +10, 45, 93, -21, 141, -82, 113, -86, +17, -36, -67, 39, -104, 108, -92, 141, +-25, 127, 43, 38, 64, -103, 47, -205, +2, -205, -45, -116, -50, 21, -23, 143, +20, 212, 58, 191, 49, 67, 18, -102, +2, -202, -16, -184, -29, -65, -24, 78, +-24, 177, -25, 190, -19, 96, -8, -83, +18, -226, 49, -239, 56, -118, 43, 66, +10, 216, -35, 261, -59, 188, -55, 16, +-43, -176, -4, -269, 48, -209, 67, -51, +54, 117, 26, 211, -20, 193, -66, 85, +-91, -58, -79, -172, -15, -177, 62, -78, +109, 44, 121, 131, 71, 150, -34, 90, +-121, -2, -157, -92, -120, -143, -6, -112, +116, -17, 170, 68, 141, 120, 33, 115, +-99, 50, -176, -36, -160, -112, -46, -141, +111, -86, 199, 10, 178, 95, 64, 138, +-95, 107, -206, 19, -198, -73, -84, -134, +77, -123, 204, -44, 222, 51, 126, 110, +-32, 111, -179, 46, -234, -33, -174, -90, +-40, -103, 124, -57, 241, 20, 235, 78, +115, 98, -51, 68, -202, 10, -262, -36, +-190, -66, -29, -78, 149, -58, 254, -28, +227, 4, 87, 43, -99, 74, -230, 80, +-227, 71, -112, 25, 53, -51, 205, -100, +250, -99, 145, -56, -34, 20, -198, 80, +-268, 98, -201, 72, -36, -1, 153, -81, +284, -98, 269, -56, 113, 12, -92, 73, +-255, 92, -291, 66, -180, 16, 8, -52, +186, -89, 277, -66, 220, -18, 52, 18, +-130, 35, -241, 27, -222, 16, -90, 3, +75, -14, 215, -16, 258, 0, 159, 8, +-20, 6, -181, -4, -260, -8, -209, 2, +-60, 2, 111, -15, 239, -22, 253, -21, +133, -12, -42, 6, -194, 26, -249, 42, +-172, 49, -15, 22, 144, -22, 245, -51, +215, -60, 64, -52, -117, -19, -248, 20, +-252, 56, -115, 73, 86, 58, 249, 17, +293, -17, 179, -55, -35, -84, -234, -78, +-323, -40, -243, 17, -28, 79, 199, 110, +325, 99, 293, 51, 113, -31, -132, -114, +-317, -139, -343, -105, -187, -20, 65, 79, +277, 137, 358, 122, 270, 50, 36, -58, +-221, -135, -361, -134, -310, -58, -95, 55, +164, 148, 327, 153, 321, 71, 150, -52, +-105, -157, -303, -189, -332, -121, -177, 16, +74, 155, 272, 214, 317, 157, 210, 19, +-1, -121, -220, -197, -324, -167, -257, -51, +-60, 94, 163, 190, 286, 175, 262, 52, +126, -97, -59, -191, -207, -183, -249, -80, +-177, 62, -21, 176, 140, 202, 211, 112, +182, -37, 93, -145, -32, -161, -152, -100, +-209, 5, -173, 88, -46, 114, 107, 72, +201, -16, 210, -84, 129, -69, -27, -4, +-184, 53, -263, 69, -216, 37, -39, -20, +170, -61, 278, -61, 246, -4, 105, 69, +-94, 85, -264, 22, -303, -71, -169, -133, +65, -109, 250, -14, 299, 104, 201, 185, +-3, 169, -209, 39, -308, -117, -249, -204, +-52, -169, 179, -32, 300, 121, 254, 199, +89, 165, -114, 26, -266, -137, -291, -222, +-171, -174, 45, -23, 238, 141, 301, 220, +227, 192, 61, 80, -146, -70, -294, -180, +-299, -190, -162, -110, 56, 8, 240, 100, +296, 132, 216, 102, 40, 30, -158, -58, +-272, -106, -244, -91, -86, -29, 122, 56, +247, 136, 227, 149, 104, 79, -65, -50, +-214, -180, -252, -243, -148, -187, 33, -36, +192, 158, 243, 294, 177, 284, 38, 133, +-119, -76, -219, -251, -210, -291, -110, -173, +35, 29, 158, 207, 195, 271, 140, 175, +29, -18, -89, -207, -160, -288, -157, -217, +-80, -27, 44, 184, 146, 324, 170, 319, +116, 160, 9, -84, -108, -292, -175, -380, +-168, -312, -82, -108, 58, 159, 167, 357, +188, 390, 130, 244, 12, -9, -112, -253, +-175, -371, -158, -308, -63, -86, 71, 179, +156, 341, 153, 309, 87, 109, -17, -157, +-112, -344, -152, -344, -115, -159, -8, 108, +108, 335, 162, 385, 139, 223, 54, -47, +-71, -276, -166, -362, -179, -259, -103, -33, +34, 193, 156, 311, 192, 259, 131, 60, +7, -139, -126, -247, -194, -230, -156, -93, +-39, 93, 100, 219, 184, 235, 166, 128, +68, -38, -61, -162, -158, -203, -170, -164, +-98, -52, 7, 76, 97, 157, 133, 162, +112, 92, 55, -16, -11, -91, -63, -111, +-84, -87, -82, -27, -55, 52, -5, 94, +45, 77, 80, 11, 85, -57, 44, -87, +-15, -75, -64, -40, -86, 22, -59, 86, +8, 108, 71, 73, 98, 11, 71, -50, +2, -86, -65, -92, -109, -61, -120, 2, +-66, 73, 35, 107, 119, 83, 153, 11, +126, -64, 36, -111, -75, -108, -156, -47, +-172, 52, -102, 139, 19, 167, 127, 91, +173, -43, 141, -150, 48, -189, -58, -146, +-141, -27, -165, 103, -101, 186, 17, 172, +115, 59, 152, -68, 121, -135, 38, -134, +-70, -58, -157, 50, -162, 125, -74, 126, +43, 52, 133, -62, 158, -134, 108, -130, +9, -66, -94, 26, -164, 111, -158, 137, +-63, 104, 71, 31, 169, -47, 189, -94, +122, -89, -8, -63, -149, -34, -225, -10, +-179, 10, -29, 33, 135, 62, 225, 71, +198, 69, 70, 37, -89, -29, -205, -90, +-224, -101, -116, -61, 59, 22, 192, 93, +223, 107, 134, 57, -25, -35, -161, -130, +-224, -149, -184, -78, -31, 50, 151, 178, +244, 227, 206, 154, 63, -1, -108, -170, +-219, -271, -232, -249, -128, -102, 56, 108, +207, 269, 228, 290, 135, 177, -12, -18, +-143, -199, -199, -284, -154, -227, -32, -43, +106, 165, 179, 267, 152, 227, 47, 70, +-77, -126, -154, -264, -147, -266, -67, -126, +53, 102, 157, 278, 170, 305, 84, 179, +-44, -36, -148, -242, -175, -331, -117, -261, +-4, -57, 124, 186, 195, 335, 156, 301, +40, 125, -90, -100, -179, -275, -171, -313, +-80, -187, 36, 28, 141, 228, 176, 299, +105, 207, -22, 22, -123, -152, -149, -253, +-94, -227, -2, -82, 87, 102, 141, 224, +121, 226, 24, 104, -84, -53, -146, -171, +-127, -210, -42, -151, 53, -5, 128, 135, +162, 199, 107, 158, -23, 39, -135, -93, +-164, -168, -115, -163, -22, -78, 75, 52, +150, 157, 161, 170, 76, 95, -51, -31, +-135, -133, -155, -161, -110, -117, -10, -24, +92, 106, 157, 187, 162, 156, 76, 41, +-57, -84, -150, -174, -165, -177, -107, -107, +-3, 15, 111, 146, 178, 206, 138, 152, +8, 41, -102, -74, -132, -153, -98, -166, +-20, -105, 60, -12, 99, 79, 84, 126, +11, 111, -62, 51, -67, -7, -31, -53, +4, -69, 24, -48, 12, -11, -1, 24, +8, 53, -5, 41, -8, 1, 37, -38, +55, -74, 0, -91, -59, -48, -76, 27, +-45, 104, 8, 157, 55, 146, 90, 62, +88, -51, 11, -167, -85, -223, -123, -179, +-97, -59, -20, 84, 66, 211, 112, 238, +122, 144, 81, -6, -18, -136, -108, -204, +-134, -164, -95, -41, -18, 93, 56, 169, +105, 141, 125, 26, 78, -89, -25, -159, +-100, -164, -116, -76, -90, 63, -18, 168, +76, 208, 138, 162, 134, 47, 39, -84, +-97, -188, -177, -238, -156, -189, -57, -54, +74, 109, 171, 235, 185, 271, 96, 185, +-55, 11, -162, -184, -160, -303, -86, -273, +23, -94, 124, 131, 153, 290, 101, 306, +-5, 167, -120, -79, -159, -297, -102, -364, +-2, -226, 107, 45, 169, 293, 138, 385, +40, 288, -89, 26, -191, -280, -174, -439, +-54, -353, 77, -71, 165, 270, 175, 477, +87, 430, -61, 159, -174, -208, -180, -499, +-75, -536, 69, -299, 170, 95, 175, 451, +84, 578, -58, 410, -173, 65, -190, -299, +-93, -522, 56, -477, 174, -183, 201, 173, +121, 411, -27, 414, -161, 199, -209, -105, +-145, -340, 6, -399, 152, -220, 206, 94, +157, 354, 38, 429, -105, 287, -193, -17, +-172, -314, -70, -457, 52, -386, 137, -131, +150, 184, 92, 388, -1, 399, -84, 227, +-111, -28, -78, -227, -17, -284, 36, -209, +61, -44, 51, 114, 22, 175, -8, 123, +-33, 24, -49, -77, -46, -127, -20, -101, +25, -24, 62, 54, 72, 115, 58, 129, +16, 101, -51, 33, -99, -58, -95, -138, +-51, -164, 17, -150, 76, -81, 95, 58, +84, 195, 42, 233, -33, 170, -91, 33, +-97, -122, -65, -235, 6, -247, 81, -134, +99, 71, 71, 237, 20, 270, -55, 166, +-97, -19, -74, -208, -27, -290, 18, -224, +52, -41, 65, 175, 65, 311, 44, 266, +-4, 85, -52, -124, -81, -263, -93, -275, +-64, -149, 10, 54, 93, 237, 133, 289, +97, 178, 4, -5, -89, -161, -136, -259, +-105, -240, -20, -91, 54, 105, 96, 242, +103, 270, 57, 168, -9, -4, -52, -164, +-83, -257, -99, -234, -76, -91, -12, 85, +93, 213, 170, 238, 139, 138, 28, -31, +-96, -161, -194, -218, -191, -174, -60, -24, +118, 150, 233, 233, 209, 203, 60, 67, +-108, -104, -216, -227, -219, -256, -100, -167, +65, 30, 191, 204, 230, 258, 148, 204, +-13, 70, -144, -97, -200, -207, -177, -223, +-56, -140, 95, 8, 191, 135, 193, 169, +84, 140, -61, 57, -147, -56, -165, -142, +-107, -154, 25, -89, 129, 35, 130, 138, +65, 161, -18, 109, -75, 17, -76, -104, +-37, -182, 12, -160, 40, -55, 28, 69, +6, 153, 0, 148, 7, 89, 11, 14, +-12, -73, -44, -138, -41, -125, -11, -64, +36, 13, 83, 86, 80, 127, 22, 114, +-44, 48, -101, -74, -111, -170, -44, -159, +40, -54, 83, 82, 93, 202, 66, 211, +13, 89, -41, -85, -83, -226, -83, -264, +-34, -141, 7, 64, 33, 221, 81, 255, +110, 155, 59, -18, -34, -149, -109, -206, +-129, -172, -87, -44, 4, 98, 119, 148, +184, 127, 131, 66, -4, -17, -142, -93, +-210, -129, -154, -111, -4, -21, 145, 85, +223, 146, 184, 151, 31, 90, -159, -44, +-266, -168, -212, -216, -25, -166, 163, -21, +256, 159, 227, 247, 70, 211, -140, 78, +-259, -99, -210, -236, -60, -240, 86, -119, +179, 68, 197, 212, 116, 223, -24, 116, +-138, -30, -189, -176, -164, -233, -56, -143, +94, 20, 215, 153, 238, 215, 120, 171, +-83, 50, -250, -86, -285, -185, -158, -197, +68, -102, 252, 21, 283, 119, 158, 172, +-54, 152, -232, 53, -261, -59, -132, -150, +58, -177, 196, -109, 219, 14, 129, 117, +-22, 182, -145, 162, -187, 45, -138, -100, +-21, -198, 93, -211, 151, -106, 159, 50, +102, 174, -31, 221, -150, 161, -176, 1, +-123, -143, -16, -193, 107, -134, 171, 5, +136, 138, 22, 160, -97, 83, -144, -45, +-108, -156, -29, -168, 58, -50, 100, 103, +76, 192, 28, 165, -20, 38, -63, -100, +-65, -158, -28, -129, 7, -18, 17, 103, +18, 125, 31, 44, 33, -47, -6, -107, +-33, -91, -15, 6, -12, 101, -30, 125, +-4, 76, 39, -30, 50, -110, 30, -109, +-2, -43, -27, 52, -42, 122, -58, 84, +-44, -23, 3, -112, 52, -152, 91, -118, +105, 18, 66, 162, -10, 210, -102, 140, +-168, 3, -145, -134, -25, -203, 128, -173, +217, -38, 170, 125, 28, 187, -125, 110, +-225, 0, -197, -96, -30, -151, 149, -111, +229, 29, 177, 152, 13, 180, -146, 99, +-199, -32, -157, -136, -40, -165, 112, -121, +182, -11, 135, 95, 37, 129, -61, 100, +-123, 36, -121, -50, -70, -84, 2, -51, +72, -19, 109, -5, 110, 35, 69, 60, +-10, 48, -89, 18, -134, -7, -136, -30, +-74, -63, 42, -116, 151, -102, 189, -5, +131, 94, 17, 162, -109, 207, -218, 153, +-222, -11, -78, -191, 106, -297, 224, -276, +248, -107, 141, 127, -60, 322, -235, 373, +-279, 223, -169, -67, 34, -327, 214, -448, +285, -337, 213, -6, 18, 362, -184, 537, +-282, 438, -242, 92, -84, -342, 126, -615, +267, -551, 259, -176, 118, 318, -75, 633, +-218, 589, -249, 226, -146, -269, 35, -633, +177, -610, 214, -225, 154, 273, 26, 620, +-112, 628, -186, 271, -170, -240, -89, -632, +40, -696, 163, -385, 209, 131, 152, 563, +24, 718, -124, 524, -219, 67, -201, -424, +-75, -686, 97, -604, 221, -211, 212, 284, +75, 610, -81, 600, -166, 271, -155, -220, +-55, -594, 70, -626, 127, -292, 88, 220, +-2, 625, -69, 670, -53, 336, 9, -183, +41, -613, 30, -719, -3, -409, -53, 125, +-69, 571, -20, 678, 50, 402, 85, -83, +73, -486, 21, -602, -44, -360, -89, 113, +-90, 505, -51, 551, 10, 263, 83, -177, +133, -515, 106, -537, 13, -223, -96, 228, +-172, 550, -156, 515, -38, 155, 116, -273, +222, -518, 199, -451, 50, -84, -124, 331, +-230, 510, -228, 358, -89, -19, 112, -395, +241, -514, 248, -312, 136, 86, -55, 447, +-217, 545, -272, 308, -193, -106, -5, -472, +185, -573, 273, -336, 233, 90, 70, 454, +-125, 590, -236, 409, -227, -18, -108, -455, +74, -638, 196, -474, 196, -60, 106, 380, +-22, 634, -114, 570, -132, 195, -110, -309, +-38, -637, 66, -610, 121, -277, 118, 183, +86, 556, 4, 636, -96, 375, -157, -82, +-147, -489, -42, -631, 110, -436, 193, -34, +170, 376, 68, 599, -65, 525, -167, 187, +-189, -239, -116, -553, 25, -589, 138, -328, +170, 81, 140, 439, 59, 607, -53, 481, +-150, 100, -198, -335, -128, -596, 40, -561, +166, -244, 195, 193, 152, 550, 13, 647, +-147, 400, -214, -89, -161, -530, -5, -694, +157, -500, 191, -39, 124, 461, 23, 732, +-101, 629, -175, 178, -146, -381, -51, -725, +78, -670, 167, -286, 158, 227, 89, 615, +-6, 699, -120, 421, -181, -84, -149, -539, +-37, -672, 115, -458, 202, -56, 169, 362, +65, 637, -68, 591, -181, 220, -198, -275, +-99, -620, 64, -638, 195, -337, 207, 109, +115, 526, -12, 713, -145, 519, -226, 26, +-183, -473, -39, -711, 127, -565, 235, -138, +228, 329, 112, 628, -55, 628, -204, 271, +-251, -252, -160, -616, 21, -621, 193, -314, +256, 125, 186, 486, 40, 634, -129, 477, +-248, 44, -230, -425, -74, -649, 123, -546, +251, -207, 246, 215, 135, 558, -33, 651, +-208, 428, -290, -25, -199, -462, -8, -656, +163, -525, 265, -163, 274, 280, 160, 598, +-41, 624, -237, 322, -337, -160, -270, -560, +-49, -653, 211, -415, 386, 18, 384, 446, +171, 672, -161, 550, -421, 134, -465, -344, +-243, -629, 138, -593, 442, -276, 504, 152, +315, 505, -51, 616, -403, 414, -528, 11, +-354, -368, 15, -562, 376, -484, 521, -188, +388, 191, 66, 490, -288, 573, -477, 363, +-390, -31, -102, -406, 226, -593, 423, -508, +389, -179, 172, 239, -103, 568, -311, 632, +-349, 372, -225, -74, -15, -465, 205, -642, +329, -514, 291, -135, 151, 321, -40, 627, +-239, 627, -348, 294, -287, -193, -66, -592, +220, -713, 406, -481, 391, 17, 183, 529, +-145, 798, -419, 671, -450, 195, -225, -394, +126, -776, 414, -783, 471, -407, 265, 175, +-77, 670, -356, 810, -408, 540, -239, 4, +36, -506, 302, -732, 405, -587, 254, -159, +-3, 348, -199, 651, -284, 612, -223, 275, +-54, -193, 114, -574, 221, -657, 212, -418, +98, 17, -3, 442, -61, 662, -120, 570, +-142, 213, -115, -268, -49, -629, 89, -673, +223, -393, 253, 60, 185, 498, 12, 698, +-228, 550, -379, 122, -323, -370, -55, -681, +301, -632, 504, -265, 434, 229, 147, 611, +-249, 691, -544, 425, -526, -47, -202, -504, +260, -708, 595, -554, 577, -130, 247, 335, +-191, 649, -542, 662, -592, 352, -292, -158, +162, -608, 534, -756, 625, -512, 365, -2, +-71, 533, -446, 825, -594, 702, -418, 174, +-23, -483, 363, -903, 577, -838, 502, -321, +157, 390, -239, 896, -477, 923, -476, 454, +-246, -253, 95, -825, 395, -940, 517, -539, +374, 140, 56, 714, -248, 891, -435, 599, +-414, 25, -172, -555, 136, -857, 373, -728, +460, -234, 325, 348, 34, 765, -246, 839, +-402, 541, -365, -8, -156, -586, 109, -936, +334, -846, 419, -335, 286, 352, 17, 905, +-226, 1058, -350, 680, -311, -57, -130, -813, +111, -1199, 311, -970, 378, -210, 265, 672, +37, 1248, -192, 1205, -324, 527, -312, -438, +-169, -1209, 64, -1402, 302, -864, 405, 134, +315, 1066, 94, 1470, -156, 1159, -331, 257, +-362, -772, -246, -1428, -1, -1383, 285, -636, +451, 437, 406, 1272, 190, 1492, -114, 994, +-393, -16, -519, -1036, -393, -1549, -34, -1320, +374, -431, 599, 687, 557, 1477, 268, 1560, +-168, 908, -552, -209, -672, -1232, -449, -1660, +7, -1311, 461, -333, 715, 818, 652, 1548, +283, 1531, -231, 817, -639, -279, -745, -1256, +-478, -1610, 42, -1201, 556, -222, 822, 843, +723, 1491, 277, 1449, -342, 759, -818, -326, +-876, -1282, -483, -1610, 158, -1195, 738, -246, +992, 841, 788, 1558, 182, 1579, -566, 876, +-1039, -265, -959, -1324, -408, -1765, 336, -1408, +957, -389, 1136, 847, 745, 1715, -34, 1797, +-819, 1046, -1176, -263, -899, -1509, -182, -2023, +605, -1553, 1112, -333, 1076, 1100, 507, 2050, +-296, 2025, -936, 960, -1070, -644, -661, -1964, +13, -2292, 654, -1492, 1011, 56, 906, 1621, +389, 2410, -302, 1985, -842, 556, -944, -1148, +-610, -2272, -53, -2258, 558, -1130, 968, 509, +911, 1872, 413, 2304, -267, 1620, -813, 166, +-958, -1322, -678, -2132, -99, -1884, 590, -761, +1034, 647, 951, 1713, 422, 1984, -296, 1306, +-885, 17, -1047, -1236, -712, -1873, -21, -1631, +748, -628, 1176, 630, 1001, 1590, 332, 1808, +-489, 1160, -1066, -36, -1113, -1176, -617, -1752, +220, -1494, 992, -531, 1252, 632, 868, 1469, +86, 1631, -706, 1014, -1128, -62, -1006, -1058, +-400, -1535, 440, -1320, 1069, -507, 1110, 496, +612, 1263, -124, 1465, -772, 989, -1024, 64, +-769, -867, -159, -1415, 527, -1326, 920, -605, +832, 402, 393, 1211, -168, 1470, -621, 1020, +-766, 85, -578, -877, -134, -1404, 402, -1269, +740, -518, 709, 457, 384, 1179, -79, 1322, +-501, 837, -699, -10, -574, -788, -143, -1186, +381, -1059, 683, -446, 663, 356, 391, 933, +-59, 1085, -498, 771, -693, 140, -570, -534, +-168, -972, 342, -1004, 693, -573, 726, 119, +420, 733, -116, 1024, -603, 858, -790, 297, +-587, -372, -49, -883, 542, -1023, 827, -670, +679, 31, 208, 672, -347, 984, -693, 853, +-657, 350, -279, -301, 223, -834, 559, -1007, +596, -688, 375, -54, 14, 548, -305, 903, +-426, 900, -345, 504, -133, -97, 120, -668, +309, -983, 368, -885, 284, -379, 81, 282, +-140, 831, -283, 1052, -313, 823, -202, 211, +19, -538, 225, -1097, 346, -1150, 334, -625, +146, 202, -133, 939, -347, 1291, -390, 1021, +-225, 209, 70, -732, 339, -1330, 455, -1313, +353, -626, 48, 390, -290, 1218, -448, 1480, +-347, 1018, -67, 37, 254, -941, 457, -1471, +419, -1320, 163, -499, -179, 584, -426, 1321, +-415, 1424, -162, 851, 188, -139, 449, -1032, +452, -1387, 191, -1091, -156, -253, -418, 702, +-445, 1247, -180, 1176, 193, 564, 427, -321, +424, -999, 174, -1162, -187, -802, -411, -72, +-385, 704, -147, 1060, 193, 891, 408, 358, +375, -303, 160, -784, -145, -864, -383, -577, +-370, -53, -153, 482, 123, 716, 367, 597, +430, 297, 257, -103, -10, -442, -275, -564, +-426, -454, -330, -181, -48, 175, 249, 394, +432, 436, 386, 370, 151, 161, -119, -141, +-334, -355, -394, -433, -231, -362, 46, -137, +267, 123, 338, 328, 248, 476, 74, 426, +-107, 160, -256, -188, -297, -475, -192, -586, +6, -414, 193, -45, 278, 376, 253, 690, +166, 668, -3, 261, -228, -277, -368, -686, +-312, -789, -82, -504, 202, 65, 397, 595, +448, 848, 316, 682, -19, 186, -393, -374, +-564, -741, -438, -790, -60, -475, 346, 69, +550, 537, 529, 754, 289, 683, -156, 311, +-547, -214, -648, -656, -425, -831, 22, -641, +442, -95, 620, 496, 552, 866, 225, 869, +-279, 446, -655, -243, -694, -840, -392, -1070, +136, -769, 574, -18, 688, 734, 524, 1093, +135, 989, -377, 406, -691, -436, -626, -1081, +-275, -1179, 194, -708, 552, 141, 634, 894, +470, 1180, 103, 945, -338, 251, -599, -627, +-575, -1179, -304, -1119, 137, -525, 512, 344, +630, 1049, 481, 1177, 101, 760, -369, -13, +-659, -827, -625, -1225, -303, -958, 155, -245, +537, 575, 677, 1107, 512, 1050, 90, 515, +-390, -224, -693, -900, -698, -1107, -400, -713, +115, -41, 623, 588, 852, 972, 661, 852, +139, 350, -474, -256, -875, -759, -858, -892, +-414, -557, 257, -44, 827, 451, 995, 784, +666, 716, -5, 325, -676, -146, -1008, -597, +-842, -769, -274, -537, 428, -109, 955, 329, +1012, 681, 510, 693, -252, 368, -857, -94, +-1050, -536, -753, -726, -84, -538, 642, -141, +1058, 303, 914, 660, 269, 692, -506, 377, +-989, -68, -966, -506, -474, -725, 234, -586, +809, -182, 955, 272, 612, 638, -45, 713, +-636, 437, -827, -22, -606, -476, -170, -735, +310, -621, 647, -216, 677, 255, 383, 628, +-97, 736, -493, 448, -608, -29, -487, -497, +-208, -776, 200, -666, 544, -193, 602, 334, +370, 728, -42, 818, -452, 471, -634, -103, +-534, -625, -224, -911, 211, -725, 559, -146, +602, 456, 331, 840, -118, 873, -491, 429, +-562, -202, -401, -689, -108, -888, 278, -647, +513, -46, 412, 507, 125, 786, -186, 724, +-379, 282, -353, -280, -190, -645, 29, -746, +249, -476, 310, 69, 187, 533, 11, 698, +-147, 584, -234, 168, -211, -338, -143, -634, +-33, -662, 120, -403, 200, 100, 156, 529, +63, 664, -63, 543, -180, 183, -225, -301, +-190, -602, -67, -662, 89, -450, 143, 32, +109, 502, 63, 673, -5, 589, -91, 245, +-157, -287, -162, -656, -69, -702, 37, -443, +83, 96, 93, 592, 54, 734, -29, 554, +-89, 131, -104, -430, -43, -734, 55, -664, +65, -315, -21, 223, -99, 655, -113, 696, +-31, 456, 85, 46, 127, -448, 80, -710, +-42, -609, -214, -271, -298, 225, -201, 614, +18, 669, 238, 443, 313, 44, 170, -453, +-66, -713, -274, -584, -390, -202, -322, 281, +-91, 640, 144, 645, 306, 349, 327, -91, +174, -518, -63, -677, -289, -447, -409, -43, +-326, 359, -100, 580, 168, 498, 383, 184, +386, -159, 159, -448, -143, -522, -395, -299, +-458, 21, -277, 267, 12, 404, 265, 353, +392, 150, 308, -75, 57, -265, -240, -357, +-454, -236, -459, -57, -251, 90, 39, 225, +297, 276, 412, 190, 292, 75, 9, -72, +-265, -232, -429, -258, -395, -178, -196, -78, +15, 97, 185, 251, 287, 275, 252, 193, +130, 30, -27, -203, -221, -302, -355, -255, +-358, -132, -242, 76, 15, 276, 301, 298, +437, 192, 373, 26, 103, -193, -288, -304, +-560, -225, -577, -89, -351, 86, 73, 227, +488, 227, 619, 129, 429, 30, 19, -127, +-474, -206, -781, -128, -708, -44, -329, 15, +214, 96, 679, 104, 763, 73, 443, 77, +-101, 28, -661, -47, -915, -38, -705, -82, +-190, -156, 410, -143, 810, -53, 746, 96, +310, 295, -239, 328, -710, 170, -864, -32, +-589, -298, -84, -513, 435, -425, 769, -85, +706, 332, 282, 644, -273, 611, -763, 214, +-920, -248, -614, -631, -59, -742, 498, -431, +839, 125, 723, 609, 226, 816, -370, 581, +-846, 12, -951, -497, -593, -749, -3, -694, +560, -263, 845, 318, 683, 721, 184, 774, +-410, 444, -861, -134, -899, -581, -483, -744, +124, -599, 624, -129, 815, 420, 581, 699, +32, 644, -536, 281, -857, -257, -778, -604, +-300, -581, 325, -322, 733, 96, 724, 442, +339, 503, -225, 310, -692, -3, -835, -323, +-574, -388, -28, -213, 496, -24, 672, 144, +446, 235, 19, 149, -417, 29, -663, -19, +-554, -59, -210, -60, 176, 2, 450, -28, +393, -85, 49, -94, -256, -67, -405, 24, +-361, 161, -120, 182, 107, 123, 211, 82, +221, -50, 30, -228, -240, -263, -313, -200, +-212, -72, -43, 136, 149, 302, 200, 318, +97, 267, -46, 57, -244, -264, -382, -451, +-272, -428, -38, -220, 178, 173, 316, 494, +210, 539, -64, 397, -260, 41, -414, -469, +-468, -710, -251, -555, 85, -150, 338, 357, +438, 714, 257, 678, -96, 372, -388, -132, +-577, -667, -565, -819, -255, -523, 154, -49, +468, 462, 579, 769, 364, 665, -80, 301, +-464, -160, -680, -626, -654, -760, -304, -513, +219, -104, 624, 330, 719, 649, 394, 658, +-185, 431, -661, 31, -856, -467, -715, -747, +-210, -655, 408, -333, 782, 159, 752, 660, +320, 871, -321, 684, -828, 185, -977, -504, +-719, -989, -152, -994, 482, -546, 876, 196, +835, 936, 364, 1223, -315, 922, -866, 200, +-1057, -698, -821, -1311, -213, -1249, 504, -608, +962, 330, 950, 1161, 468, 1415, -295, 967, +-948, 120, -1174, -828, -877, -1397, -171, -1240, +607, -519, 1063, 417, 989, 1188, 402, 1347, +-422, 852, -1071, 28, -1236, -825, -831, -1323, +-51, -1143, 708, -464, 1095, 418, 929, 1141, +278, 1301, -541, 840, -1115, 67, -1171, -779, +-706, -1317, 23, -1195, 669, -529, 954, 356, +781, 1119, 243, 1354, -417, 963, -918, 169, +-1018, -727, -665, -1347, -70, -1297, 471, -653, +796, 274, 777, 1111, 365, 1446, -245, 1068, +-776, 208, -985, -747, -742, -1396, -213, -1367, +357, -653, 779, 346, 835, 1189, 461, 1462, +-163, 1011, -774, 96, -1055, -817, -847, -1377, +-312, -1257, 295, -519, 759, 386, 883, 1064, +587, 1279, -36, 889, -707, 121, -1075, -617, +-971, -1087, -485, -1101, 166, -610, 735, 86, +972, 727, 727, 1093, 92, 979, -632, 441, +-1078, -234, -1029, -881, -545, -1183, 124, -893, +704, -207, 964, 551, 770, 1120, 148, 1186, +-611, 683, -1069, -126, -1024, -914, -566, -1319, +98, -1052, 686, -298, 946, 570, 750, 1210, +149, 1307, -557, 758, -999, -119, -1015, -967, +-635, -1431, -49, -1178, 524, -324, 892, 621, +852, 1295, 355, 1417, -352, 848, -935, -127, +-1149, -1036, -899, -1531, -268, -1254, 495, -337, +1060, 658, 1113, 1334, 565, 1454, -320, 845, +-1073, -152, -1347, -1034, -1029, -1498, -252, -1237, +642, -307, 1231, 669, 1182, 1288, 502, 1372, +-429, 790, -1164, -177, -1393, -1007, -1006, -1434, +-175, -1159, 717, -244, 1255, 697, 1140, 1242, +432, 1291, -502, 712, -1216, -220, -1380, -984, +-947, -1343, -125, -1097, 735, -223, 1186, 682, +1011, 1166, 374, 1173, -439, 674, -1089, -159, +-1256, -857, -890, -1194, -157, -1007, 629, -263, +1066, 546, 950, 969, 393, 1014, -372, 643, +-1004, -56, -1176, -671, -819, -962, -129, -881, +582, -329, 964, 370, 853, 790, 348, 880, +-348, 656, -938, 104, -1099, -477, -783, -853, +-155, -921, 507, -522, 871, 160, 797, 684, +359, 934, -297, 849, -859, 338, -1022, -351, +-747, -857, -197, -1052, 386, -752, 732, -39, +719, 647, 373, 1007, -173, 956, -680, 449, +-891, -251, -717, -811, -261, -1058, 262, -816, +623, -113, 677, 588, 402, 952, -116, 914, +-618, 487, -810, -176, -635, -732, -233, -996, +237, -824, 542, -218, 521, 492, 253, 921, +-122, 953, -460, 589, -595, -42, -491, -661, +-247, -1034, 22, -978, 236, -390, 330, 389, +278, 930, 90, 1064, -171, 788, -397, 141, +-493, -597, -433, -1107, -222, -1138, 50, -598, +248, 243, 334, 925, 285, 1207, 66, 984, +-230, 297, -472, -549, -551, -1178, -416, -1307, +-136, -763, 194, 161, 470, 960, 515, 1323, +265, 1126, -167, 383, -582, -556, -762, -1264, +-619, -1415, -229, -869, 271, 102, 658, 978, +707, 1433, 373, 1273, -187, 511, -720, -503, +-956, -1309, -780, -1584, -285, -1092, 313, -44, +761, 1004, 824, 1609, 454, 1521, -162, 693, +-745, -484, -1031, -1459, -879, -1788, -365, -1232, +299, -31, 815, 1137, 906, 1764, 548, 1582, +-84, 610, -740, -659, -1097, -1566, -981, -1771, +-443, -1116, 316, 128, 915, 1250, 1033, 1736, +641, 1455, -93, 479, -850, -712, -1254, -1528, +-1101, -1681, -437, -1061, 441, 119, 1072, 1165, +1138, 1638, 624, 1432, -217, 550, -992, -596, +-1348, -1392, -1120, -1598, -370, -1103, 558, -41, +1161, 988, 1131, 1506, 541, 1397, -320, 634, +-1054, -413, -1315, -1201, -990, -1486, -225, -1127, +610, -167, 1076, 814, 982, 1366, 402, 1356, +-370, 714, -933, -287, -1092, -1088, -830, -1417, +-192, -1145, 512, -288, 900, 692, 841, 1295, +378, 1347, -278, 767, -788, -175, -983, -954, +-806, -1313, -273, -1165, 358, -418, 764, 528, +786, 1148, 410, 1276, -163, 855, -645, 20, +-873, -751, -780, -1187, -363, -1166, 175, -567, +566, 316, 687, 962, 485, 1197, 32, 913, +-408, 183, -703, -569, -789, -1032, -539, -1118, +-57, -663, 397, 129, 679, 779, 654, 1081, +275, 946, -256, 354, -703, -347, -897, -872, +-705, -1100, -204, -834, 364, -151, 781, 535, +818, 1032, 390, 1140, -239, 697, -769, -57, +-1028, -766, -847, -1228, -276, -1159, 369, -514, +848, 374, 935, 1132, 497, 1409, -203, 979, +-803, 105, -1117, -798, -949, -1383, -342, -1343, +365, -619, 899, 395, 1011, 1217, 546, 1464, +-202, 1003, -822, 79, -1115, -832, -922, -1372, +-302, -1298, 383, -595, 850, 392, 922, 1172, +508, 1415, -159, 984, -722, 113, -1013, -766, +-890, -1315, -362, -1315, 260, -655, 731, 333, +898, 1130, 590, 1402, -24, 1022, -620, 159, +-1006, -729, -973, -1295, -482, -1274, 169, -610, +693, 324, 904, 1028, 663, 1268, 71, 923, +-566, 144, -983, -638, -965, -1105, -510, -1098, +96, -556, 594, 206, 854, 812, 706, 1076, +175, 879, -456, 264, -917, -434, -990, -939, +-597, -1048, 12, -652, 551, 36, 877, 657, +790, 1035, 248, 952, -439, 380, -943, -350, +-1030, -873, -632, -1013, -7, -683, 541, -45, +872, 577, 806, 941, 268, 892, -442, 382, +-929, -265, -997, -719, -627, -873, -27, -658, +505, -120, 813, 440, 746, 790, 237, 801, +-398, 420, -809, -144, -879, -563, -574, -768, +-53, -663, 392, -199, 658, 338, 658, 661, +286, 724, -269, 452, -670, -35, -770, -443, +-569, -658, -139, -641, 316, -273, 596, 220, +586, 537, 249, 639, -227, 473, -571, 68, +-664, -313, -466, -565, -83, -598, 227, -302, +367, 128, 359, 382, 181, 486, -82, 429, +-286, 155, -407, -144, -403, -329, -253, -432, +-69, -343, 92, -115, 249, 84, 323, 272, +219, 446, -27, 424, -297, 214, -471, -92, +-450, -448, -268, -636, -45, -482, 213, -140, +443, 314, 436, 727, 166, 776, -212, 394, +-529, -177, -619, -709, -473, -913, -180, -605, +228, -17, 580, 542, 628, 907, 328, 807, +-177, 276, -641, -336, -798, -786, -617, -879, +-253, -503, 221, 74, 672, 543, 802, 792, +483, 709, -115, 269, -698, -260, -966, -670, +-809, -808, -348, -538, 282, -22, 833, 437, +966, 739, 568, 751, -159, 377, -823, -190, +-1067, -645, -830, -832, -276, -604, 381, -74, +865, 414, 930, 700, 548, 737, -136, 424, +-812, -104, -1097, -567, -872, -756, -309, -616, +368, -201, 914, 256, 1035, 591, 587, 751, +-195, 587, -895, 87, -1181, -448, -897, -786, +-207, -783, 495, -396, 906, 177, 893, 639, +477, 865, -184, 709, -795, 149, -1034, -478, +-799, -848, -250, -841, 348, -413, 763, 186, +866, 645, 564, 833, -76, 675, -718, 172, +-1023, -415, -852, -797, -267, -814, 400, -438, +795, 136, 804, 582, 454, 802, -135, 695, +-680, 224, -894, -366, -693, -774, -212, -831, +289, -471, 584, 103, 630, 574, 428, 786, +3, 709, -474, 285, -752, -289, -706, -724, +-359, -840, 134, -550, 525, -5, 630, 493, +459, 796, 65, 769, -414, 374, -694, -225, +-638, -739, -321, -897, 96, -572, 392, 12, +481, 543, 393, 821, 121, 718, -237, 277, +-489, -264, -549, -704, -419, -806, -101, -495, +260, 16, 456, 459, 470, 697, 280, 658, +-117, 339, -492, -152, -637, -598, -497, -806, +-122, -596, 269, -80, 479, 429, 464, 744, +233, 743, -145, 345, -461, -232, -543, -680, +-396, -795, -117, -490, 159, 73, 313, 516, +347, 687, 253, 544, 8, 136, -254, -279, +-405, -512, -423, -553, -290, -340, -46, 31, +204, 327, 384, 460, 401, 439, 172, 246, +-183, -49, -424, -351, -466, -535, -356, -463, +-113, -140, 183, 224, 390, 491, 394, 544, +192, 325, -77, -65, -305, -407, -461, -572, +-472, -452, -297, -70, 32, 310, 389, 463, +585, 438, 481, 244, 77, -77, -410, -334, +-738, -435, -760, -368, -388, -109, 220, 151, +721, 297, 819, 380, 434, 348, -199, 117, +-703, -180, -835, -397, -575, -455, -50, -302, +483, -3, 674, 276, 494, 483, 142, 484, +-280, 198, -549, -190, -521, -467, -332, -564, +-69, -367, 194, 39, 365, 390, 415, 568, +278, 531, -28, 189, -346, -254, -550, -555, +-529, -638, -226, -411, 167, 51, 424, 444, +507, 645, 344, 604, -80, 247, -464, -280, +-545, -621, -389, -682, -137, -463, 127, 35, +313, 522, 357, 718, 255, 616, 29, 219, +-242, -307, -397, -692, -372, -765, -254, -476, +-64, 116, 194, 651, 398, 811, 396, 637, +134, 184, -200, -477, -387, -913, -420, -837, +-309, -344, -90, 327, 147, 866, 323, 925, +362, 484, 238, -181, -36, -743, -300, -899, +-406, -556, -442, 49, -349, 639, -3, 823, +398, 479, 591, -36, 459, -422, 71, -591, +-368, -439, -681, -28, -684, 324, -330, 383, +178, 257, 572, 43, 709, -135, 482, -175, +-77, -98, -579, 4, -729, 17, -588, -48, +-215, -60, 259, -19, 600, 54, 668, 143, +375, 219, -144, 144, -546, -93, -683, -265, +-558, -272, -160, -165, 311, 37, 555, 252, +552, 342, 324, 185, -145, -53, -545, -209, +-593, -272, -403, -200, -91, 24, 222, 217, +367, 186, 394, 51, 291, -26, -6, -95, +-290, -71, -417, 17, -427, 72, -314, 79, +-57, -70, 272, -241, 518, -163, 550, 51, +276, 214, -236, 300, -642, 262, -727, -27, +-487, -355, 8, -447, 510, -313, 773, 3, +661, 383, 148, 565, -502, 423, -867, 9, +-767, -397, -339, -574, 239, -454, 706, -142, +769, 266, 478, 604, -52, 575, -629, 212, +-854, -193, -636, -505, -136, -582, 415, -371, +693, 40, 597, 419, 270, 586, -184, 475, +-621, 95, -717, -344, -376, -600, 58, -559, +366, -162, 502, 292, 381, 546, 94, 566, +-195, 294, -390, -204, -394, -590, -249, -589, +-52, -246, 153, 207, 252, 503, 220, 447, +184, 182, 107, -155, -106, -408, -331, -344, +-404, -26, -313, 242, -97, 294, 195, 131, +430, -152, 464, -344, 249, -194, -141, 125, +-511, 328, -662, 343, -465, 130, 15, -240, +455, -497, 627, -444, 506, -60, 143, 434, +-331, 667, -702, 442, -703, 3, -326, -458, +196, -758, 622, -594, 687, -74, 412, 486, +-17, 849, -529, 727, -818, 224, -632, -383, +-113, -877, 464, -937, 777, -444, 631, 274, +137, 867, -397, 1103, -736, 775, -728, -65, +-273, -944, 338, -1355, 684, -1026, 623, -105, +184, 959, -353, 1575, -618, 1343, -540, 330, +-221, -968, 216, -1810, 537, -1616, 484, -496, +107, 992, -307, 1981, -517, 1788, -385, 563, +-48, -970, 242, -2016, 398, -1924, 323, -655, +-4, 1055, -345, 2134, -461, 1924, -279, 552, +80, -1109, 350, -2073, 377, -1836, 179, -513, +-146, 1163, -391, 2111, -397, 1707, -184, 264, +139, -1271, 377, -2007, 369, -1493, 105, -39, +-216, 1399, -379, 1938, -352, 1287, -135, -192, +170, -1547, 351, -1951, 316, -1155, 75, 409, +-222, 1741, -386, 1947, -340, 1005, -65, -505, +253, -1784, 381, -2038, 247, -1028, -44, 609, +-284, 1894, -389, 2083, -284, 1061, 39, -621, +350, -1970, 439, -2173, 229, -1133, -163, 560, +-461, 1984, -477, 2274, -235, 1283, 123, -436, +482, -1961, 585, -2343, 279, -1367, -197, 315, +-617, 1809, -729, 2273, -339, 1433, 243, -190, +646, -1642, 710, -2127, 374, -1403, -199, 77, +-694, 1451, -828, 1919, -462, 1254, 192, -56, +693, -1180, 752, -1562, 395, -1086, -123, -72, +-537, 903, -704, 1270, -510, 840, -41, 27, +414, -595, 624, -800, 465, -566, 72, -98, +-250, 317, -426, 483, -461, 356, -276, 83, +47, -121, 310, -204, 417, -202, 280, -117, +-13, -25, -171, 15, -222, 145, -290, 236, +-218, 141, -38, -9, 99, -143, 187, -237, +229, -207, 193, -31, 69, 245, -83, 344, +-271, 169, -426, -93, -338, -310, -25, -389, +338, -204, 535, 177, 429, 494, 117, 493, +-299, 170, -628, -260, -610, -546, -240, -591, +268, -287, 642, 245, 667, 635, 294, 676, +-247, 356, -595, -159, -627, -587, -375, -739, +69, -485, 468, 7, 602, 490, 423, 781, +25, 665, -400, 177, -573, -380, -420, -755, +-144, -790, 171, -446, 469, 139, 549, 693, +305, 975, -166, 729, -564, 55, -606, -609, +-322, -1001, 106, -939, 527, -380, 669, 402, +377, 1068, -135, 1174, -620, 624, -810, -241, +-413, -997, 298, -1262, 751, -872, 707, -33, +259, 868, -322, 1359, -726, 1136, -730, 290, +-288, -720, 401, -1381, 824, -1305, 651, -566, +126, 469, -450, 1334, -759, 1484, -543, 841, +-101, -241, 311, -1293, 646, -1605, 589, -1024, +114, 43, -361, 1150, -573, 1659, -479, 1199, +-109, 108, 274, -1027, 410, -1603, 349, -1308, +132, -312, -168, 855, -318, 1553, -258, 1316, +-86, 362, 97, -655, 162, -1259, 62, -1215, +-31, -552, 39, 402, 106, 1102, 69, 1087, +-3, 531, -161, -217, -263, -828, -169, -888, +-35, -494, 152, 2, 395, 520, 357, 780, +10, 560, -299, 70, -442, -381, -360, -569, +-33, -400, 271, -154, 389, 81, 332, 369, +98, 396, -202, 154, -411, -22, -355, -151, +-63, -187, 186, -121, 270, -75, 226, -31, +107, 5, -53, 40, -199, 137, -213, 192, +-108, 140, 3, -3, 93, -174, 149, -281, +119, -251, 50, -64, 2, 227, -104, 374, +-185, 291, -149, 72, -59, -252, 137, -424, +290, -226, 196, 44, 22, 230, -183, 285, +-370, 123, -290, -97, 0, -259, 311, -258, +518, 48, 363, 348, -133, 298, -532, 30, +-611, -232, -345, -401, 228, -314, 678, 15, +711, 360, 360, 495, -308, 330, -872, -47, +-861, -419, -311, -565, 442, -347, 951, 48, +879, 357, 306, 501, -422, 461, -956, 202, +-952, -197, -369, -541, 422, -616, 963, -443, +922, -92, 372, 422, -313, 844, -824, 830, +-877, 391, -475, -344, 131, -1034, 699, -1169, +864, -651, 531, 281, -15, 1203, -527, 1434, +-740, 816, -551, -255, -175, -1284, 261, -1629, +644, -951, 646, 259, 292, 1297, -100, 1643, +-467, 1032, -615, -193, -414, -1225, -97, -1520, +289, -982, 583, 64, 523, 1005, 257, 1292, +-114, 858, -500, 12, -603, -751, -370, -978, +25, -628, 391, -54, 545, 455, 454, 650, +162, 451, -254, 79, -550, -217, -525, -345, +-229, -251, 173, -57, 423, 7, 440, -21, +336, 36, 64, 121, -277, 209, -469, 257, +-449, 147, -165, -92, 200, -335, 373, -472, +391, -318, 292, 104, 33, 472, -267, 556, +-463, 356, -425, -100, -84, -530, 253, -598, +371, -314, 404, 124, 244, 528, -98, 609, +-325, 283, -418, -184, -340, -520, -53, -547, +259, -189, 455, 228, 415, 454, 144, 465, +-146, 156, -374, -280, -511, -454, -358, -366, +85, -77, 453, 290, 579, 494, 425, 390, +-29, 28, -471, -364, -636, -527, -463, -415, +-15, -68, 436, 372, 690, 633, 575, 531, +50, 108, -512, -414, -745, -691, -549, -616, +-18, -186, 495, 440, 708, 790, 583, 667, +111, 241, -479, -403, -748, -874, -577, -789, +-92, -269, 464, 405, 690, 895, 532, 828, +167, 299, -299, -352, -584, -847, -551, -832, +-318, -279, 105, 345, 547, 747, 644, 719, +428, 210, 88, -378, -360, -651, -706, -510, +-706, -44, -335, 410, 316, 540, 861, 280, +932, -173, 506, -505, -226, -436, -887, 0, +-1108, 461, -712, 596, 134, 314, 926, -291, +1236, -820, 879, -777, 25, -149, -850, 613, +-1283, 1123, -1009, 992, -181, 143, 719, -903, +1228, -1481, 1124, -1192, 464, -131, -495, 1073, +-1199, 1731, -1225, 1387, -651, 188, 260, -1155, +1065, -1851, 1293, -1489, 871, -283, 31, 1084, +-859, 1887, -1353, 1594, -1103, 377, -238, -964, +706, -1736, 1282, -1598, 1207, -567, 482, 705, +-464, 1511, -1144, 1548, -1232, 790, -664, -352, +231, -1209, 943, -1434, 1149, -944, 774, -19, +50, 822, -598, 1236, -932, 1067, -868, 361, +-387, -474, 267, -1025, 759, -1079, 914, -587, +689, 180, 130, 755, -508, 953, -910, 714, +-934, 130, -504, -472, 283, -797, 967, -716, +1104, -319, 671, 129, -32, 474, -750, 609, +-1161, 503, -901, 229, -138, -115, 623, -423, +1045, -578, 970, -558, 420, -308, -352, 156, +-901, 595, -994, 794, -651, 674, 42, 169, +768, -521, 1108, -1002, 861, -978, 165, -429, +-585, 379, -1092, 1049, -1069, 1226, -375, 717, +581, -232, 1174, -1079, 1083, -1351, 411, -922, +-479, 30, -1116, 1019, -1071, 1449, -372, 1070, +505, 121, 1040, -887, 929, -1404, 283, -1187, +-467, -329, -891, 747, -770, 1376, -187, 1182, +485, 407, 780, -510, 576, -1152, 81, -1175, +-427, -565, -653, 307, -436, 975, 32, 1071, +418, 609, 540, -105, 337, -717, -79, -935, +-397, -671, -420, -104, -179, 494, 115, 832, +286, 728, 314, 237, 162, -327, -102, -697, +-235, -720, -161, -389, -34, 127, 48, 606, +88, 783, 39, 496, -10, -28, 27, -494, +48, -720, 70, -586, 93, -125, 0, 413, +-167, 721, -280, 613, -184, 173, 71, -345, +312, -677, 448, -646, 319, -241, -51, 306, +-404, 688, -601, 648, -500, 238, -12, -258, +593, -628, 843, -682, 570, -313, -17, 234, +-597, 620, -886, 648, -702, 315, -48, -197, +709, -557, 974, -584, 663, -312, 52, 130, +-615, 498, -924, 551, -621, 296, -7, -132, +518, -449, 740, -452, 548, -226, 45, 73, +-428, 349, -562, 400, -328, 189, 10, -73, +254, -250, 338, -275, 169, -102, -106, 78, +-166, 143, -39, 115, 82, -9, 144, -110, +113, -58, -75, 37, -302, 121, -346, 156, +-109, 37, 272, -152, 514, -242, 481, -225, +187, -57, -285, 189, -642, 348, -682, 363, +-359, 152, 266, -195, 814, -413, 900, -501, +473, -374, -231, 51, -824, 510, -1002, 769, +-641, 661, 106, 108, 855, -552, 1137, -1006, +740, -1032, -43, -386, -785, 598, -1110, 1290, +-781, 1386, -61, 674, 629, -567, 1006, -1534, +825, -1699, 167, -908, -515, 495, -838, 1635, +-705, 1936, -243, 1208, 292, -315, 635, -1688, +631, -2073, 280, -1391, -152, 41, -407, 1495, +-458, 2122, -296, 1626, 19, 284, 271, -1211, +335, -2015, 209, -1796, 32, -694, -89, 791, +-165, 1852, -148, 1931, -22, 1058, 49, -328, +44, -1536, 27, -1982, -30, -1448, -43, -168, +49, 1187, 112, 1908, 127, 1702, 75, 660, +-56, -705, -169, -1691, -252, -1830, -233, -1081, +0, 169, 277, 1303, 397, 1831, 341, 1458, +92, 352, -275, -864, -499, -1632, -485, -1678, +-233, -929, 247, 319, 632, 1434, 628, 1849, +275, 1388, -236, 223, -572, -1100, -609, -1916, +-390, -1820, 93, -795, 558, 714, 638, 1900, +389, 2142, 12, 1286, -350, -302, -520, -1766, +-408, -2310, -152, -1700, 132, -157, 369, 1547, +438, 2405, 296, 1977, 39, 505, -199, -1270, +-343, -2339, -382, -2148, -238, -823, 38, 956, +277, 2203, 385, 2240, 336, 1091, 135, -647, +-131, -2015, -318, -2246, -330, -1292, -230, 304, +-85, 1727, 117, 2182, 312, 1471, 362, 18, +268, -1414, 84, -2031, -167, -1555, -397, -308, +-482, 1076, -346, 1825, 1, 1565, 423, 533, +710, -730, 610, -1570, 125, -1527, -447, -720, +-812, 407, -777, 1289, -309, 1436, 381, 861, +921, -72, 954, -954, 419, -1308, -377, -989, +-941, -254, -968, 585, -464, 1149, 275, 1130, +844, 569, 954, -252, 519, -937, -210, -1184, +-745, -892, -855, -154, -486, 744, 166, 1292, +608, 1158, 663, 438, 420, -520, -59, -1267, +-441, -1383, -500, -779, -328, 272, 2, 1235, +304, 1562, 338, 1029, 207, -61, 39, -1106, +-137, -1583, -180, -1243, -139, -229, -117, 925, +10, 1603, 133, 1424, 121, 472, 80, -720, +33, -1499, -34, -1504, -90, -757, -128, 396, +-64, 1366, 67, 1599, 123, 973, 105, -140, +47, -1132, -60, -1555, -139, -1179, -140, -172, +-55, 898, 80, 1480, 161, 1287, 182, 417, +121, -620, -75, -1322, -231, -1347, -246, -656, +-148, 334, 69, 1112, 275, 1341, 321, 847, +225, -64, -23, -861, -323, -1240, -419, -1016, +-272, -242, -7, 609, 327, 1119, 490, 1064, +327, 469, 30, -312, -263, -912, -459, -1075, +-413, -667, -159, 69, 193, 722, 439, 999, +421, 762, 226, 158, -24, -466, -291, -866, +-448, -852, -387, -390, -140, 246, 169, 736, +410, 853, 463, 531, 308, 14, -3, -478, +-320, -797, -502, -710, -472, -243, -190, 296, +217, 685, 504, 719, 547, 383, 322, -71, +-26, -483, -354, -711, -582, -525, -527, -60, +-166, 365, 240, 602, 533, 532, 592, 181, +354, -202, -14, -466, -395, -513, -676, -288, +-573, 60, -163, 330, 253, 439, 588, 323, +704, 77, 450, -140, -42, -303, -540, -339, +-779, -201, -639, -34, -195, 121, 382, 252, +812, 277, 824, 203, 405, 61, -253, -121, +-794, -252, -901, -330, -536, -286, 99, -47, +690, 234, 885, 420, 620, 453, 57, 212, +-549, -168, -803, -468, -578, -608, -145, -414, +298, 74, 576, 499, 556, 700, 288, 562, +-97, 64, -389, -449, -434, -705, -311, -667, +-118, -263, 97, 312, 266, 686, 338, 738, +280, 426, 86, -130, -101, -555, -232, -726, +-333, -601, -313, -130, -132, 415, 108, 732, +336, 743, 446, 355, 360, -247, 70, -692, +-315, -822, -562, -557, -535, 44, -255, 628, +211, 906, 625, 703, 726, 73, 425, -562, +-144, -872, -653, -757, -802, -203, -541, 454, +31, 829, 615, 770, 842, 253, 622, -399, +83, -745, -532, -703, -834, -288, -663, 308, +-161, 645, 400, 611, 722, 321, 666, -183, +293, -547, -254, -537, -660, -299, -679, 88, +-357, 416, 126, 425, 548, 256, 668, 0, +445, -278, -19, -356, -482, -249, -644, -46, +-467, 223, -58, 319, 431, 196, 612, 34, +395, -146, 49, -257, -314, -189, -525, -38, +-382, 150, -60, 262, 250, 162, 411, -34, +291, -196, 59, -229, -100, -64, -246, 118, +-268, 205, -141, 190, -28, 12, 89, -212, +201, -274, 236, -165, 238, 99, 84, 347, +-212, 314, -398, 52, -399, -222, -213, -403, +154, -320, 505, 5, 648, 318, 406, 474, +-164, 360, -651, -45, -804, -446, -571, -562, +56, -353, 709, 75, 1006, 476, 798, 600, +62, 410, -785, -5, -1170, -465, -973, -674, +-226, -490, 740, -53, 1299, 423, 1180, 698, +443, 584, -654, 146, -1427, -357, -1385, -701, +-598, -702, 546, -313, 1397, 272, 1474, 743, +835, 834, -287, 463, -1352, -148, -1642, -700, +-1010, -919, 106, -655, 1149, -52, 1590, 603, +1211, 984, 211, 831, -880, 245, -1498, -466, +-1353, -954, -523, -930, 569, -442, 1314, 233, +1379, 830, 801, 996, -144, 616, -1007, -33, +-1351, -668, -1043, -964, -243, -697, 640, -155, +1199, 395, 1212, 802, 640, 758, -248, 331, +-968, -157, -1252, -585, -965, -697, -169, -424, +702, -70, 1212, 257, 1179, 487, 539, 470, +-402, 314, -1095, 62, -1235, -263, -800, -417, +54, -415, 865, -352, 1216, -87, 965, 253, +235, 513, -592, 627, -1064, 402, -994, -70, +-477, -502, 225, -779, 811, -699, 996, -215, +693, 413, 77, 909, -534, 966, -862, 466, +-786, -274, -398, -909, 163, -1136, 673, -721, +862, 74, 654, 800, 180, 1206, -423, 993, +-833, 203, -816, -673, -473, -1211, 77, -1148, +678, -487, 963, 394, 771, 1089, 212, 1285, +-477, 829, -962, -63, -993, -919, -538, -1356, +235, -1104, 906, -259, 1124, 662, 797, 1262, +37, 1305, -785, 654, -1169, -343, -946, -1148, +-256, -1398, 570, -920, 1088, 32, 1021, 895, +455, 1303, -315, 1092, -903, 314, -1008, -573, +-576, -1126, 86, -1161, 620, -584, 863, 256, +711, 870, 203, 1072, -345, 729, -692, 43, +-721, -554, -417, -918, 49, -846, 455, -274, +665, 367, 575, 751, 249, 790, -176, 390, +-563, -164, -679, -549, -449, -702, -78, -469, +328, 23, 669, 392, 719, 563, 386, 419, +-152, 37, -620, -215, -815, -332, -654, -323, +-124, -118, 548, 58, 961, 140, 878, 169, +339, 96, -425, 54, -982, 70, -1038, 1, +-559, -55, 264, -119, 980, -238, 1162, -170, +746, 24, -86, 174, -894, 329, -1216, 285, +-913, 42, -133, -176, 767, -394, 1270, -428, +1083, -126, 322, 218, -612, 450, -1229, 497, +-1204, 219, -566, -187, 412, -464, 1217, -570, +1350, -355, 747, 106, -228, 491, -1091, 656, +-1377, 457, -957, -50, -42, -466, 932, -643, +1417, -535, 1134, -108, 286, 412, -712, 719, +-1335, 615, -1237, 151, -529, -369, 425, -682, +1200, -646, 1329, -262, 752, 279, -168, 676, +-983, 721, -1285, 347, -923, -237, -132, -651, +718, -715, 1187, -409, 1049, 130, 432, 580, +-380, 745, -1007, 516, -1088, -52, -688, -579, +-19, -747, 724, -544, 1162, -76, 998, 470, +355, 775, -455, 654, -1060, 202, -1208, -384, +-792, -762, 111, -717, 1041, -345, 1408, 229, +1073, 739, 223, 825, -808, 479, -1491, -92, +-1387, -668, -549, -922, 596, -657, 1456, -64, +1565, 598, 878, 1023, -251, 872, -1273, 245, +-1640, -512, -1178, -1078, -113, -1081, 1012, -510, +1588, 342, 1367, 1109, 534, 1302, -570, 752, +-1401, -180, -1503, -1026, -892, -1383, 112, -1023, +1085, -101, 1523, 908, 1236, 1469, 389, 1217, +-675, 325, -1437, -717, -1490, -1428, -821, -1386, +291, -612, 1270, 458, 1619, 1339, 1207, 1522, +152, 900, -1054, -173, -1675, -1186, -1427, -1573, +-482, -1134, 752, -165, 1616, 911, 1604, 1574, +756, 1389, -467, 477, -1407, -637, -1622, -1455, +-1020, -1532, 139, -799, 1209, 314, 1575, 1290, +1156, 1618, 183, 1091, -875, 44, -1444, -1026, +-1255, -1588, -461, -1344, 545, -452, 1231, 656, +1295, 1452, 737, 1521, -198, 843, -996, -209, +-1225, -1148, -883, -1561, -145, -1214, 662, -274, +1119, 815, 1019, 1525, 440, 1466, -348, 683, +-922, -432, -1032, -1358, -673, -1638, 7, -1074, +701, 107, 1009, 1239, 828, 1722, 298, 1304, +-378, 176, -896, -1030, -953, -1691, -543, -1468, +110, -431, 700, 818, 987, 1589, 811, 1485, +200, 577, -524, -582, -960, -1331, -949, -1358, +-474, -700, 297, 315, 944, 1072, 1090, 1167, +693, 688, -66, -88, -830, -728, -1182, -927, +-905, -681, -140, -129, 717, 425, 1205, 715, +1073, 677, 363, 343, -539, -115, -1144, -494, +-1179, -658, -615, -562, 333, -219, 1121, 258, +1283, 645, 778, 752, -100, 500, -929, -2, +-1286, -551, -971, -908, -120, -786, 774, -242, +1239, 432, 1094, 956, 406, 978, -506, 463, +-1115, -274, -1142, -928, -642, -1119, 171, -661, +919, 142, 1184, 840, 900, 1129, 227, 800, +-591, 23, -1156, -720, -1151, -1097, -597, -895, +276, -175, 1047, 584, 1336, 1011, 995, 919, +127, 341, -867, -384, -1427, -900, -1273, -963, +-478, -508, 592, 213, 1389, 781, 1492, 927, +862, 637, -220, 23, -1209, -618, -1580, -921, +-1166, -726, -191, -167, 891, 444, 1577, 832, +1514, 765, 651, 280, -548, -296, -1449, -721, +-1669, -752, -1080, -345, 126, 175, 1318, 565, +1838, 671, 1402, 388, 253, -69, -1038, -424, +-1830, -546, -1663, -374, -590, -13, 776, 263, +1751, 373, 1819, 327, 895, 113, -484, -91, +-1565, -201, -1824, -239, -1108, -150, 163, -47, +1317, 10, 1800, 89, 1312, 175, 112, 214, +-1059, 163, -1620, 29, -1344, -156, -389, -318, +729, -321, 1431, -151, 1376, 113, 597, 368, +-420, 477, -1141, 298, -1250, -94, -726, -426, +110, -537, 831, -371, 1116, 8, 795, 375, +112, 582, -528, 473, -865, 74, -740, -327, +-266, -539, 238, -477, 609, -159, 671, 217, +353, 461, -77, 474, -364, 246, -444, -112, +-311, -374, -100, -431, 114, -293, 299, -3, +296, 277, 149, 407, 53, 331, -63, 70, +-166, -205, -183, -361, -193, -330, -105, -142, +101, 113, 187, 333, 217, 349, 242, 141, +93, -109, -139, -269, -275, -259, -315, -111, +-184, 86, 56, 228, 254, 211, 380, 31, +333, -175, 73, -235, -201, -117, -413, 93, +-447, 267, -179, 247, 187, 55, 421, -191, +503, -358, 348, -307, -23, -36, -413, 300, +-580, 459, -410, 326, -44, -8, 311, -377, +575, -532, 551, -361, 212, 36, -206, 455, +-528, 615, -580, 406, -287, -30, 106, -496, +428, -714, 572, -509, 416, -12, 54, 487, +-314, 757, -523, 622, -402, 147, -105, -386, +158, -753, 399, -735, 459, -305, 213, 244, +-55, 695, -246, 796, -384, 441, -296, -83, +-33, -547, 189, -779, 345, -585, 349, -84, +164, 447, -101, 761, -323, 650, -371, 199, +-180, -295, 86, -671, 289, -714, 379, -337, +265, 188, -36, 627, -289, 750, -355, 422, +-237, -71, 5, -505, 239, -707, 324, -497, +262, -41, 72, 411, -165, 653, -291, 489, +-250, 78, -111, -286, 96, -492, 256, -420, +261, -97, 147, 192, -4, 342, -163, 306, +-234, 66, -176, -116, -48, -164, 77, -163, +166, -39, 177, 50, 128, 24, 44, 24, +-49, 23, -122, 30, -158, 90, -167, 67, +-93, -34, 84, -107, 235, -160, 260, -136, +208, 32, 23, 180, -232, 210, -348, 117, +-300, -84, -118, -218, 201, -189, 415, -50, +379, 139, 200, 230, -78, 155, -384, -54, +-481, -262, -322, -293, -6, -121, 347, 160, +540, 383, 463, 363, 174, 98, -250, -259, +-576, -495, -578, -478, -293, -176, 155, 281, +583, 613, 685, 617, 408, 275, -62, -253, +-509, -680, -708, -766, -501, -433, -10, 145, +477, 678, 690, 884, 556, 629, 156, 17, +-337, -664, -660, -1003, -595, -799, -206, -206, +261, 536, 560, 1033, 596, 974, 366, 423, +-60, -369, -470, -1001, -608, -1085, -453, -607, +-80, 161, 358, 870, 616, 1112, 581, 758, +303, 76, -166, -647, -570, -1062, -678, -893, +-470, -289, 18, 443, 559, 939, 783, 919, +638, 496, 185, -150, -423, -755, -805, -943, +-741, -650, -312, -68, 324, 546, 800, 872, +818, 761, 450, 310, -107, -285, -638, -726, +-819, -776, -564, -479, -27, 45, 498, 529, +743, 695, 646, 571, 279, 218, -253, -242, +-654, -527, -704, -575, -408, -379, 86, 3, +526, 336, 708, 515, 578, 516, 131, 262, +-404, -128, -702, -435, -645, -568, -265, -441, +285, -53, 663, 356, 698, 624, 412, 612, +-108, 249, -593, -234, -754, -603, -523, -709, +-3, -426, 498, 99, 721, 559, 622, 729, +220, 540, -360, 79, -736, -416, -704, -676, +-337, -583, 205, -206, 657, 254, 766, 554, +490, 551, -61, 257, -583, -133, -778, -406, +-583, -451, -92, -274, 484, 14, 788, 273, +650, 356, 173, 221, -397, 6, -758, -169, +-677, -229, -225, -169, 336, -43, 699, 70, +660, 104, 259, 72, -268, 0, -636, -60, +-622, -23, -262, 40, 237, 51, 586, 27, +564, -45, 227, -138, -164, -161, -455, -109, +-514, 6, -265, 182, 132, 256, 410, 155, +456, 8, 268, -168, -31, -304, -292, -265, +-391, -115, -285, 95, -23, 279, 218, 279, +342, 158, 299, -1, 112, -203, -92, -314, +-210, -234, -249, -74, -167, 102, 7, 241, +147, 242, 210, 146, 210, -4, 130, -182, +28, -254, -100, -196, -217, -64, -215, 100, +-80, 201, 85, 216, 230, 155, 287, 6, +209, -149, 20, -226, -201, -194, -309, -67, +-204, 78, -9, 181, 188, 233, 311, 171, +272, 9, 95, -119, -102, -186, -246, -181, +-246, -66, -119, 52, 60, 135, 210, 181, +259, 136, 204, 53, 82, -15, -107, -87, +-247, -113, -237, -95, -103, -77, 81, -18, +255, 94, 299, 170, 189, 190, -21, 154, +-225, 24, -288, -134, -173, -231, 26, -238, +209, -112, 267, 101, 174, 283, -4, 332, +-165, 239, -212, 45, -98, -189, 46, -347, +119, -350, 117, -196, 52, 79, -45, 333, +-85, 452, -60, 401, 4, 156, 75, -216, +81, -506, -6, -564, -79, -357, -99, 78, +-72, 527, -11, 723, 59, 573, 91, 95, +102, -488, 51, -818, -47, -734, -114, -266, +-126, 386, -118, 850, -57, 863, 70, 415, +202, -284, 223, -852, 116, -959, -72, -578, +-233, 82, -304, 716, -227, 984, 1, 732, +271, 88, 380, -606, 259, -967, -3, -850, +-260, -323, -390, 378, -311, 879, -75, 916, +207, 472, 373, -237, 324, -829, 103, -997, +-137, -646, -299, 52, -299, 723, -167, 1007, +31, 755, 218, 66, 292, -695, 207, -1077, +41, -878, -126, -222, -205, 569, -182, 1044, +-94, 937, 39, 306, 169, -514, 190, -1043, +136, -986, 60, -412, -20, 374, -81, 943, +-117, 960, -124, 430, -74, -316, 19, -878, +152, -935, 261, -451, 246, 254, 96, 780, +-116, 860, -307, 448, -312, -211, -118, -735, +159, -828, 400, -440, 450, 194, 230, 679, +-106, 763, -383, 445, -435, -129, -206, -637, +130, -748, 373, -425, 450, 146, 289, 633, +-8, 749, -264, 470, -361, -67, -260, -586, +-10, -761, 214, -497, 323, 40, 300, 575, +144, 818, -68, 615, -211, 97, -249, -475, +-157, -797, 12, -669, 166, -178, 237, 417, +211, 802, 79, 768, -68, 365, -161, -231, +-170, -706, -78, -770, 50, -438, 116, 117, +126, 626, 73, 783, -9, 555, -44, 91, +-21, -435, -1, -718, 15, -580, -16, -175, +-69, 304, -85, 630, -38, 617, 71, 336, +179, -97, 173, -491, 45, -577, -155, -381, +-313, -32, -277, 350, -50, 531, 207, 441, +386, 180, 333, -171, 41, -431, -311, -458, +-512, -280, -417, 25, -42, 306, 358, 409, +548, 349, 412, 136, -2, -169, -424, -378, +-599, -424, -460, -284, -31, 3, 411, 259, +574, 411, 408, 391, 29, 135, -391, -194, +-570, -430, -425, -498, -82, -306, 281, 42, +467, 341, 386, 492, 120, 388, -207, 31, +-393, -333, -347, -532, -148, -485, 84, -166, +264, 219, 277, 451, 151, 450, -17, 169, +-146, -231, -167, -475, -94, -456, -9, -215, +50, 133, 45, 385, 14, 385, 26, 148, +70, -193, 90, -419, 117, -367, 72, -122, +-82, 161, -219, 339, -212, 286, -76, 40, +140, -237, 329, -384, 368, -278, 206, 19, +-92, 281, -350, 363, -388, 231, -218, -74, +100, -348, 410, -431, 522, -286, 339, 67, +-14, 404, -350, 500, -488, 357, -350, 6, +4, -376, 390, -541, 576, -444, 459, -116, +121, 316, -305, 575, -562, 561, -468, 298, +-90, -157, 342, -519, 622, -578, 567, -387, +209, 31, -261, 469, -596, 642, -569, 539, +-184, 172, 284, -324, 604, -596, 620, -558, +302, -252, -166, 241, -515, 613, -601, 670, +-347, 442, 100, -25, 484, -484, 603, -655, +412, -500, 29, -69, -345, 437, -558, 699, +-485, 643, -124, 289, 307, -234, 538, -605, +483, -651, 169, -366, -222, 143, -487, 564, +-476, 687, -209, 498, 156, 64, 401, -388, +402, -614, 170, -536, -139, -175, -335, 278, +-333, 566, -172, 592, 59, 350, 205, -75, +203, -439, 82, -595, -51, -485, -131, -124, +-133, 290, -85, 570, -23, 612, 10, 333, +-2, -131, -24, -516, -12, -670, 32, -519, +63, -96, 30, 377, -30, 648, -102, 593, +-152, 215, -157, -289, -62, -624, 96, -652, +218, -386, 210, 58, 77, 465, -120, 613, +-289, 431, -320, 15, -182, -410, 63, -623, +310, -555, 392, -241, 248, 194, -64, 513, +-343, 567, -434, 330, -299, -110, -12, -515, +321, -675, 494, -534, 373, -129, 50, 340, +-280, 618, -454, 574, -376, 216, -84, -286, +269, -659, 451, -716, 396, -405, 161, 114, +-138, 555, -361, 714, -358, 487, -148, -45, +123, -561, 320, -806, 357, -644, 238, -103, +35, 485, -164, 803, -253, 721, -218, 204, +-74, -454, 117, -846, 284, -808, 324, -329, +222, 363, 30, 832, -156, 854, -270, 424, +-249, -264, -51, -768, 208, -823, 355, -465, +333, 156, 150, 681, -78, 811, -244, 547, +-269, 15, -145, -497, 78, -677, 246, -499, +298, -93, 213, 344, 40, 593, -97, 563, +-164, 288, -181, -105, -110, -390, 27, -444, +166, -295, 239, -15, 222, 274, 98, 446, +-64, 434, -224, 222, -278, -53, -185, -247, +18, -324, 236, -239, 339, -20, 251, 187, +30, 318, -215, 331, -348, 204, -296, 28, +-87, -114, 147, -220, 313, -228, 300, -120, +122, 32, -130, 200, -311, 333, -333, 322, +-187, 180, 49, -50, 236, -303, 278, -422, +187, -316, -18, -42, -240, 307, -343, 549, +-254, 510, -57, 208, 162, -222, 273, -587, +230, -645, 54, -359, -164, 111, -321, 552, +-325, 708, -153, 475, 95, 13, 254, -467, +267, -728, 133, -602, -76, -177, -261, 308, +-320, 618, -241, 583, -21, 244, 184, -206, +260, -557, 204, -631, 44, -400, -126, -4, +-212, 363, -230, 504, -149, 371, 15, 66, +136, -282, 177, -499, 186, -475, 91, -255, +-37, 59, -141, 310, -212, 374, -213, 254, +-94, -2, 101, -278, 275, -405, 319, -354, +208, -179, -4, 68, -242, 263, -390, 292, +-309, 168, -38, -56, 297, -250, 496, -320, +455, -268, 164, -108, -232, 92, -508, 227, +-505, 249, -221, 141, 229, -36, 613, -190, +677, -284, 373, -280, -109, -148, -530, 59, +-650, 258, -409, 353, 86, 274, 546, 47, +732, -243, 547, -461, 97, -438, -376, -164, +-610, 233, -491, 563, -117, 599, 297, 298, +549, -178, 526, -598, 269, -692, -85, -359, +-326, 203, -381, 680, -241, 801, 0, 479, +205, -96, 290, -604, 270, -774, 162, -477, +20, 125, -101, 652, -187, 818, -197, 550, +-112, 12, -5, -495, 126, -696, 229, -481, +244, 18, 145, 509, -26, 721, -209, 546, +-289, 105, -236, -343, -67, -546, 154, -420, +291, -69, 290, 332, 169, 567, -89, 475, +-330, 149, -386, -203, -245, -397, -21, -339, +228, -89, 377, 195, 332, 386, 77, 377, +-258, 175, -466, -79, -446, -256, -219, -280, +128, -152, 412, 19, 471, 179, 271, 274, +-84, 239, -447, 114, -581, -53, -420, -212, +-54, -268, 320, -231, 524, -103, 452, 119, +127, 286, -278, 306, -547, 210, -548, -17, +-281, -273, 120, -402, 443, -372, 510, -159, +325, 156, -56, 353, -406, 385, -523, 236, +-388, -81, -93, -368, 254, -487, 452, -402, +380, -105, 128, 223, -170, 401, -372, 381, +-373, 143, -213, -209, 45, -467, 278, -517, +366, -317, 256, 42, 37, 343, -198, 451, +-319, 312, -277, -30, -108, -374, 134, -550, +336, -464, 363, -140, 194, 223, -75, 439, +-281, 411, -335, 137, -201, -205, 46, -439, +320, -476, 444, -281, 327, 39, 30, 280, +-270, 357, -409, 254, -313, 17, -13, -204, +325, -311, 497, -296, 417, -166, 123, 19, +-231, 182, -455, 264, -373, 235, -80, 112, +251, -55, 459, -218, 449, -316, 214, -274, +-108, -90, -336, 148, -366, 358, -210, 426, +47, 278, 300, -5, 438, -292, 358, -462, +120, -401, -177, -122, -368, 239, -375, 523, +-176, 573, 145, 348, 421, -21, 464, -380, +253, -568, -85, -457, -372, -98, -426, 351, +-225, 676, 64, 679, 318, 371, 391, -120, +248, -572, -23, -732, -236, -507, -286, 23, +-192, 617, -70, 917, 48, 766, 161, 254, +199, -416, 152, -876, 62, -841, -70, -353, +-203, 368, -307, 928, -280, 984, -94, 562, +177, -134, 368, -773, 381, -930, 157, -561, +-192, 92, -474, 716, -558, 925, -356, 613, +58, 31, 447, -546, 596, -799, 408, -551, +-8, -18, -443, 481, -670, 699, -593, 490, +-201, 46, 291, -357, 608, -553, 593, -415, +272, -54, -191, 258, -569, 388, -666, 277, +-455, 21, -46, -173, 381, -238, 596, -184, +515, -48, 182, 48, -228, 56, -553, 10, +-632, -54, -422, -57, 5, 5, 428, 41, +638, 39, 556, -19, 183, -122, -315, -176, +-663, -155, -694, -80, -359, 43, 178, 133, +629, 126, 754, 36, 509, -97, -25, -203, +-541, -224, -759, -170, -582, -49, -85, 98, +453, 171, 735, 133, 649, 22, 240, -122, +-268, -227, -603, -240, -606, -166, -295, -21, +187, 129, 523, 179, 588, 120, 399, 6, +30, -128, -318, -221, -451, -212, -342, -118, +-67, 40, 231, 186, 393, 201, 354, 104, +171, -42, -55, -212, -192, -280, -219, -183, +-113, 32, 35, 267, 131, 365, 156, 234, +122, -40, 56, -330, 24, -469, 40, -314, +36, 47, -5, 417, -54, 599, -112, 434, +-103, 15, -7, -415, 151, -634, 259, -472, +257, -12, 104, 463, -139, 720, -337, 588, +-357, 121, -145, -378, 179, -651, 415, -546, +445, -99, 227, 407, -152, 694, -475, 622, +-512, 211, -270, -282, 152, -576, 498, -550, +545, -187, 271, 297, -162, 604, -519, 612, +-584, 317, -316, -129, 132, -446, 496, -500, +552, -280, 270, 95, -158, 403, -516, 500, +-569, 367, -317, 72, 86, -205, 427, -330, +509, -286, 273, -105, -110, 114, -436, 258, +-543, 304, -343, 225, 27, 59, 325, -94, +433, -204, 293, -245, -10, -173, -320, -20, +-450, 154, -342, 288, -73, 304, 169, 173, +296, -53, 272, -282, 88, -400, -119, -317, +-234, -63, -260, 227, -186, 416, -45, 397, +96, 157, 167, -196, 190, -471, 138, -511, +23, -285, -146, 75, -278, 384, -272, 490, +-135, 328, 75, -27, 279, -380, 356, -558, +232, -450, -33, -123, -291, 215, -409, 410, +-303, 398, -34, 168, 298, -167, 475, -429, +388, -479, 119, -301, -199, -21, -437, 221, +-444, 336, -203, 268, 152, 57, 460, -187, +553, -355, 356, -345, -2, -170, -368, 36, +-543, 197, -439, 239, -99, 130, 325, -40, +640, -196, 625, -262, 270, -173, -199, -16, +-549, 111, -613, 164, -358, 97, 101, -43, +557, -142, 723, -167, 507, -100, 48, 38, +-402, 143, -645, 160, -523, 82, -125, -72, +319, -184, 605, -186, 597, -92, 290, 76, +-157, 221, -485, 240, -515, 141, -300, -33, +36, -207, 347, -281, 504, -186, 400, 36, +134, 260, -175, 352, -386, 271, -403, 59, +-243, -186, 21, -349, 290, -321, 426, -84, +361, 251, 132, 477, -172, 463, -413, 212, +-439, -150, -266, -435, 50, -501, 328, -286, +431, 149, 330, 557, 76, 686, -227, 462, +-421, 2, -426, -457, -248, -669, 57, -522, +321, -76, 392, 457, 300, 774, 70, 688, +-225, 262, -454, -285, -449, -667, -219, -677, +110, -327, 345, 194, 390, 627, 237, 745, +-45, 487, -301, 3, -407, -458, -320, -677, +-78, -528, 156, -105, 268, 348, 217, 622, +89, 595, -62, 272, -182, -175, -241, -523, +-199, -599, -80, -360, 58, 56, 158, 403, +176, 540, 111, 417, -16, 80, -167, -286, +-237, -497, -182, -469, -25, -206, 123, 138, +201, 379, 148, 412, 10, 247, -123, -33, +-183, -297, -147, -426, -33, -363, 96, -133, +155, 148, 128, 316, 41, 311, -75, 156, +-126, -93, -99, -312, -14, -373, 66, -269, +119, -61, 118, 166, 70, 272, -30, 205, +-123, 43, -118, -149, -31, -271, 82, -252, +165, -141, 155, 14, 81, 140, -43, 147, +-160, 69, -185, -30, -61, -116, 122, -140, +254, -97, 241, -52, 95, -12, -93, 29, +-235, 36, -239, 23, -81, 15, 150, -7, +325, -33, 304, -66, 101, -92, -149, -80, +-281, -11, -250, 75, -57, 118, 172, 95, +309, 22, 278, -78, 82, -150, -141, -148, +-245, -54, -198, 94, -40, 193, 131, 163, +222, 53, 187, -60, 61, -145, -95, -134, +-163, -21, -145, 99, -49, 164, 86, 140, +161, 31, 120, -66, 13, -89, -101, -47, +-152, 42, -93, 122, 23, 129, 101, 76, +125, 2, 60, -70, -54, -70, -156, -3, +-157, 68, -53, 127, 91, 133, 157, 59, +117, -18, 20, -63, -104, -70, -190, -23, +-181, 58, -67, 118, 101, 135, 189, 97, +160, 22, 41, -47, -106, -79, -226, -67, +-235, -8, -138, 57, 34, 108, 217, 127, +266, 104, 135, 44, -75, -43, -258, -105, +-326, -107, -238, -65, -16, 22, 227, 128, +348, 188, 231, 160, -19, 40, -275, -119, +-403, -214, -295, -187, -24, -71, 242, 95, +375, 232, 287, 240, 15, 110, -259, -94, +-382, -267, -296, -297, -36, -181, 213, 23, +328, 221, 241, 304, 24, 226, -172, 20, +-241, -217, -195, -367, -66, -333, 80, -140, +147, 110, 133, 306, 70, 341, 8, 181, +-7, -84, -48, -329, -100, -417, -110, -304, +-70, -49, 8, 210, 127, 342, 200, 277, +183, 52, 80, -210, -92, -365, -233, -348, +-238, -167, -94, 75, 133, 255, 284, 283, +278, 147, 146, -61, -43, -239, -244, -310, +-290, -234, -142, -52, 74, 143, 248, 246, +299, 198, 177, 52, -45, -107, -209, -213, +-225, -221, -107, -117, 79, 22, 219, 119, +228, 135, 89, 77, -77, 6, -174, -43, +-151, -63, -29, -49, 121, -39, 191, -35, +134, -15, 0, 8, -117, 50, -149, 97, +-95, 107, 12, 57, 146, -33, 182, -118, +91, -132, -43, -61, -127, 58, -149, 160, +-92, 192, 20, 121, 123, 2, 169, -116, +110, -163, -17, -97, -128, 31, -172, 147, +-123, 199, -23, 151, 80, 46, 141, -60, +144, -119, 46, -88, -80, 6, -155, 93, +-167, 138, -104, 127, 7, 44, 95, -40, +145, -59, 134, -23, 35, 32, -100, 70, +-184, 74, -196, 57, -108, 11, 21, -27, +135, -21, 183, 23, 139, 57, 15, 53, +-133, 26, -230, -5, -217, -21, -103, -14, +47, 9, 178, 46, 231, 72, 138, 62, +-29, 15, -184, -57, -261, -91, -217, -70, +-55, -14, 119, 54, 219, 124, 205, 133, +88, 53, -70, -64, -204, -162, -242, -195, +-155, -109, -6, 33, 131, 160, 184, 210, +156, 141, 62, -14, -45, -175, -145, -258, +-189, -204, -158, -64, -58, 87, 82, 189, +193, 185, 229, 72, 167, -67, 0, -170, +-193, -216, -299, -175, -250, -80, -61, 38, +199, 138, 358, 154, 332, 104, 143, 14, +-139, -121, -364, -228, -382, -252, -191, -167, +107, 7, 366, 174, 434, 256, 271, 210, +-20, 37, -303, -184, -411, -334, -296, -347, +-29, -186, 256, 84, 430, 295, 373, 344, +119, 228, -173, -30, -359, -280, -356, -399, +-163, -329, 121, -90, 347, 199, 380, 377, +217, 355, -61, 147, -280, -118, -322, -336, +-187, -388, 27, -231, 223, 52, 300, 301, +214, 390, 17, 278, -178, 27, -246, -229, +-167, -362, -24, -286, 130, -42, 208, 214, +159, 364, 31, 332, -88, 108, -171, -152, +-146, -319, -32, -294, 75, -84, 137, 167, +141, 324, 60, 324, -69, 151, -161, -97, +-168, -263, -92, -259, 58, -96, 181, 141, +186, 300, 69, 290, -80, 150, -206, -64, +-231, -235, -123, -263, 58, -118, 214, 109, +252, 290, 130, 328, -81, 201, -255, -36, +-296, -231, -180, -309, 36, -211, 218, 23, +281, 269, 186, 385, -19, 299, -223, 56, +-315, -204, -252, -359, -53, -321, 179, -104, +293, 183, 236, 382, 60, 378, -159, 169, +-309, -120, -287, -328, -80, -381, 154, -233, +262, 48, 190, 283, 21, 367, -140, 267, +-213, 24, -146, -219, 11, -361, 132, -312, +138, -105, 34, 119, -94, 267, -151, 283, +-77, 145, 65, -65, 170, -229, 143, -290, +2, -208, -158, -30, -235, 118, -167, 188, +19, 161, 218, 34, 305, -86, 206, -169, +-29, -187, -245, -110, -322, -3, -234, 58, +-7, 78, 230, 56, 351, 20, 295, -34, +85, -89, -174, -120, -337, -101, -321, -54, +-142, 7, 106, 62, 298, 84, 359, 74, +265, 11, 36, -100, -213, -167, -371, -151, +-350, -73, -138, 30, 171, 119, 410, 161, +462, 98, 278, -26, -65, -145, -385, -203, +-496, -157, -325, -37, 29, 97, 356, 194, +497, 187, 380, 83, 67, -62, -258, -176, +-423, -209, -382, -134, -136, 16, 183, 161, +378, 226, 367, 171, 200, 46, -30, -95, +-230, -200, -333, -186, -285, -68, -92, 76, +145, 206, 302, 233, 340, 154, 210, 15, +-43, -128, -282, -197, -377, -151, -284, -32, +-40, 129, 226, 247, 376, 240, 326, 106, +104, -58, -168, -185, -352, -201, -358, -103, +-173, 63, 82, 231, 278, 275, 322, 168, +200, -6, -32, -166, -229, -206, -294, -116, +-213, 23, -50, 164, 98, 219, 191, 158, +195, 24, 86, -94, -40, -132, -127, -85, +-169, -8, -155, 65, -84, 105, -2, 89, +95, 52, 166, 24, 144, -25, 50, -55, +-67, -55, -169, -64, -210, -37, -157, 16, +-19, 70, 137, 117, 227, 103, 198, 14, +64, -85, -129, -149, -255, -146, -246, -77, +-120, 38, 64, 125, 226, 152, 268, 83, +158, -36, -44, -133, -217, -167, -269, -128, +-183, -34, -17, 51, 162, 101, 256, 92, +212, 43, 43, -38, -137, -113, -225, -130, +-196, -104, -84, -52, 76, 1, 200, 57, +210, 112, 123, 91, -15, -12, -157, -111, +-215, -181, -154, -178, -5, -88, 153, 58, +233, 169, 177, 188, 41, 88, -98, -87, +-195, -237, -194, -269, -72, -144, 97, 57, +209, 202, 205, 251, 106, 154, -35, -51, +-152, -215, -212, -287, -154, -198, 6, 7, +168, 183, 235, 255, 193, 210, 70, 38, +-102, -140, -239, -236, -248, -226, -118, -102, +85, 95, 264, 220, 307, 253, 163, 169, +-50, -10, -216, -159, -277, -226, -201, -202, +-14, -59, 173, 103, 278, 223, 254, 259, +107, 165, -85, 7, -246, -125, -295, -200, +-188, -205, 6, -95, 205, 81, 327, 232, +288, 288, 75, 209, -182, 37, -347, -138, +-332, -264, -151, -254, 95, -88, 300, 161, +360, 342, 231, 359, -17, 203, -273, -78, +-392, -321, -299, -384, -61, -242, 176, 52, +328, 353, 333, 493, 172, 380, -87, 38, +-311, -322, -386, -508, -271, -428, -17, -109, +247, 308, 367, 574, 296, 539, 84, 208, +-181, -255, -361, -594, -321, -597, -127, -276, +85, 226, 221, 610, 237, 657, 156, 354, +38, -163, -103, -602, -226, -705, -245, -428, +-158, 97, -17, 570, 148, 710, 247, 464, +227, -36, 105, -522, -80, -727, -264, -543, +-321, -85, -209, 431, 15, 694, 244, 546, +352, 117, 260, -365, 27, -665, -204, -602, +-333, -240, -314, 240, -131, 575, 124, 573, +309, 264, 337, -184, 208, -523, -27, -578, +-244, -351, -347, 26, -301, 365, -81, 490, +220, 355, 396, 47, 342, -275, 118, -457, +-149, -401, -340, -182, -352, 99, -176, 315, +103, 381, 309, 261, 342, 4, 198, -252, +-39, -369, -223, -338, -257, -144, -169, 115, +-15, 298, 138, 331, 202, 203, 164, -16, +87, -223, -14, -318, -102, -259, -127, -81, +-91, 117, -47, 242, 9, 267, 80, 186, +146, 9, 156, -166, 82, -268, -32, -233, +-130, -86, -188, 107, -165, 269, -40, 308, +138, 197, 245, -21, 233, -247, 110, -327, +-86, -221, -262, 21, -286, 270, -156, 370, +36, 292, 226, 63, 327, -209, 243, -358, +21, -289, -210, -68, -335, 206, -281, 385, +-70, 354, 159, 151, 311, -102, 309, -324, +126, -348, -136, -181, -303, 80, -295, 329, +-144, 409, 66, 270, 235, 15, 271, -257, +160, -390, -29, -309, -195, -68, -258, 225, +-168, 416, -1, 382, 147, 166, 206, -121, +143, -371, -2, -416, -132, -239, -183, 33, +-137, 303, -16, 444, 98, 363, 134, 110, +90, -220, -16, -438, -108, -430, -121, -219, +-64, 103, 9, 397, 62, 495, 63, 323, +19, -34, -35, -378, -46, -524, -7, -394, +19, -63, -2, 302, -40, 502, -70, 406, +-44, 98, 42, -271, 112, -504, 95, -463, +26, -164, -78, 194, -172, 422, -171, 425, +-46, 203, 125, -149, 229, -403, 196, -458, +42, -276, -151, 44, -266, 306, -242, 398, +-92, 280, 134, -8, 334, -283, 346, -407, +154, -330, -135, -72, -377, 216, -427, 350, +-225, 286, 116, 56, 418, -226, 513, -346, +321, -274, -58, -63, -413, 200, -572, 316, +-409, 221, 0, 11, 406, -229, 598, -321, +505, -196, 136, 34, -329, 229, -613, 276, +-560, 143, -214, -70, 248, -233, 586, -253, +613, -92, 328, 119, -96, 226, -474, 199, +-627, 48, -446, -132, -17, -195, 409, -140, +622, 10, 518, 151, 150, 186, -271, 113, +-527, -15, -528, -131, -278, -131, 107, -33, +433, 83, 546, 131, 392, 109, 48, 30, +-300, -58, -506, -92, -477, -43, -212, 52, +167, 116, 465, 117, 526, 55, 308, -40, +-53, -96, -362, -87, -494, -18, -399, 77, +-105, 121, 235, 112, 463, 38, 465, -47, +239, -78, -107, -55, -404, 5, -514, 65, +-364, 58, -32, 12, 314, -22, 522, -22, +468, 10, 146, 62, -259, 79, -522, 32, +-509, -54, -232, -136, 161, -124, 458, -10, +507, 133, 285, 213, -78, 154, -402, -15, +-517, -183, -343, -269, -1, -173, 307, 40, +460, 241, 367, 305, 62, 166, -254, -99, +-414, -311, -381, -354, -134, -180, 186, 107, +372, 326, 338, 350, 128, 174, -130, -129, +-296, -367, -312, -391, -167, -202, 70, 100, +237, 322, 237, 352, 119, 203, -35, -79, +-150, -319, -184, -351, -128, -218, -29, 19, +61, 232, 120, 294, 137, 182, 84, -25, +-7, -208, -83, -257, -137, -176, -137, -31, +-52, 118, 59, 177, 139, 115, 158, 16, +100, -74, -8, -101, -114, -61, -180, -44, +-161, -33, -62, -22, 80, -19, 222, 28, +260, 107, 133, 137, -78, 106, -271, -15, +-327, -174, -182, -270, 86, -206, 307, -9, +381, 230, 249, 353, -35, 285, -316, 59, +-432, -225, -302, -414, 16, -362, 326, -95, +461, 245, 361, 453, 70, 419, -268, 162, +-467, -188, -422, -430, -141, -452, 212, -222, +457, 152, 481, 450, 269, 519, -91, 320, +-422, -57, -544, -387, -371, -522, 8, -391, +381, -26, 558, 372, 450, 565, 104, 484, +-283, 166, -521, -250, -498, -518, -219, -504, +168, -231, 441, 168, 499, 461, 334, 524, +5, 342, -328, -29, -484, -344, -414, -452, +-168, -344, 158, -75, 436, 225, 505, 391, +323, 373, -18, 180, -354, -81, -533, -279, +-446, -337, -121, -255, 267, -38, 504, 181, +488, 301, 235, 298, -141, 163, -448, -49, +-516, -236, -335, -316, -5, -229, 326, -48, +495, 148, 392, 286, 91, 275, -230, 132, +-429, -72, -419, -243, -205, -294, 91, -192, +315, -2, 381, 175, 273, 253, 31, 199, +-218, 41, -350, -137, -309, -247, -137, -223, +92, -93, 275, 74, 319, 187, 191, 181, +-21, 90, -196, -48, -271, -160, -235, -174, +-102, -114, 70, -12, 213, 93, 256, 119, +182, 89, 17, 20, -158, -52, -263, -95, +-243, -101, -104, -80, 88, -16, 231, 45, +254, 73, 155, 78, -21, 46, -193, -33, +-258, -72, -188, -89, -26, -73, 147, -7, +244, 52, 198, 69, 49, 36, -111, -28, +-195, -56, -162, -39, -45, 4, 70, 52, +127, 62, 120, 18, 77, -58, 20, -109, +-52, -84, -121, 11, -126, 108, -59, 151, +48, 109, 135, -9, 156, -122, 94, -166, +-13, -123, -126, 15, -180, 148, -114, 195, +25, 145, 133, 10, 167, -115, 122, -171, +10, -122, -112, 7, -163, 123, -126, 163, +-26, 138, 86, 40, 158, -78, 150, -129, +67, -92, -60, -23, -144, 59, -131, 97, +-68, 85, 20, 39, 131, -12, 171, -34, +100, -27, -3, -20, -88, 12, -142, 17, +-110, 3, -29, 2, 41, 7, 96, 30, +126, 53, 100, 50, 26, 27, -64, -10, +-124, -59, -144, -87, -115, -63, -6, 3, +141, 82, 220, 126, 186, 99, 38, 35, +-152, -58, -267, -135, -224, -146, -54, -85, +145, 34, 254, 135, 237, 162, 105, 126, +-98, 18, -249, -121, -258, -203, -160, -195, +16, -84, 207, 75, 291, 222, 221, 268, +43, 162, -184, -51, -330, -249, -295, -351, +-90, -287, 172, -49, 335, 240, 303, 404, +106, 375, -158, 117, -322, -224, -286, -459, +-117, -466, 83, -213, 244, 161, 264, 430, +134, 477, -41, 265, -176, -98, -239, -409, +-191, -501, -50, -321, 126, 28, 249, 336, +235, 452, 69, 330, -143, 18, -259, -306, +-223, -444, -66, -349, 147, -63, 269, 254, +186, 397, -11, 317, -172, 61, -219, -221, +-109, -360, 71, -293, 176, -51, 148, 205, +19, 312, -131, 217, -163, -1, -69, -202, +66, -260, 161, -150, 136, 54, 9, 212, +-91, 225, -121, 90, -106, -88, -35, -217, +52, -202, 93, -50, 107, 130, 97, 234, +40, 222, -80, 86, -181, -95, -177, -249, +-63, -255, 104, -111, 243, 91, 238, 268, +70, 314, -124, 183, -235, -54, -225, -271, +-80, -343, 106, -220, 218, 49, 214, 303, +129, 402, -10, 270, -146, -28, -229, -300, +-200, -397, -63, -264, 103, 18, 235, 281, +272, 392, 168, 291, -27, 42, -220, -195, +-322, -311, -257, -269, -28, -118, 225, 61, +373, 219, 324, 271, 91, 211, -187, 72, +-353, -103, -337, -239, -132, -271, 154, -186, +330, -8, 321, 191, 162, 305, -63, 273, +-249, 112, -313, -142, -224, -306, -18, -299, +206, -159, 305, 66, 242, 259, 75, 297, +-123, 194, -270, -6, -264, -198, -117, -284, +54, -241, 190, -89, 263, 112, 208, 248, +43, 263, -139, 153, -277, -47, -299, -234, +-136, -296, 120, -224, 314, -31, 347, 180, +187, 280, -113, 238, -362, 53, -384, -159, +-172, -277, 132, -256, 357, -92, 377, 116, +170, 238, -148, 210, -370, 66, -359, -103, +-147, -205, 130, -199, 331, -88, 333, 69, +144, 167, -98, 162, -263, 89, -318, -40, +-229, -151, -4, -176, 240, -122, 348, -2, +278, 132, 63, 179, -220, 144, -403, 12, +-342, -133, -78, -196, 232, -155, 424, -38, +368, 105, 64, 198, -273, 179, -421, 54, +-319, -100, -56, -197, 235, -176, 382, -69, +288, 91, 39, 200, -187, 183, -291, 76, +-248, -62, -72, -164, 114, -175, 202, -96, +211, 22, 148, 111, 4, 154, -147, 148, +-203, 67, -179, -38, -67, -120, 114, -178, +234, -164, 199, -56, 56, 120, -108, 246, +-199, 256, -155, 151, -29, -50, 107, -270, +169, -359, 104, -214, -11, 63, -78, 304, +-80, 411, -43, 279, 19, -23, 52, -324, +43, -428, 17, -273, -24, 23, -46, 304, +-14, 446, 50, 319, 75, -2, 43, -288, +-30, -390, -93, -296, -99, -43, -45, 247, +44, 394, 118, 298, 149, 42, 78, -199, +-49, -301, -132, -258, -148, -60, -113, 162, +6, 246, 154, 186, 197, 39, 123, -95, +-10, -155, -158, -121, -223, -16, -132, 58, +63, 63, 203, 28, 190, 5, 65, 5, +-71, 18, -184, 20, -186, -15, -36, -81, +117, -123, 170, -72, 144, 58, 36, 161, +-120, 178, -190, 79, -127, -117, -3, -261, +119, -225, 166, -61, 110, 149, -18, 274, +-129, 241, -157, 45, -89, -191, 25, -308, +126, -235, 146, -23, 69, 191, -38, 286, +-121, 202, -153, -19, -118, -201, -2, -258, +149, -164, 208, 17, 131, 178, -13, 217, +-158, 129, -247, -23, -180, -149, -2, -182, +159, -134, 250, -44, 223, 88, 42, 189, +-172, 171, -287, 78, -268, -51, -92, -188, +170, -231, 349, -154, 329, 30, 88, 225, +-234, 296, -416, 190, -343, -23, -73, -245, +267, -357, 446, -233, 339, 46, 39, 304, +-271, 395, -432, 231, -342, -59, -43, -324, +269, -410, 409, -228, 321, 96, 62, 336, +-232, 397, -396, 243, -320, -64, -67, -341, +210, -401, 359, -219, 312, 84, 99, 334, +-168, 415, -353, 265, -341, -64, -130, -371, +145, -431, 365, -247, 401, 74, 194, 365, +-141, 481, -410, 335, -444, -36, -204, -398, +168, -552, 426, -406, 458, 4, 233, 441, +-145, 658, -429, 511, -438, 51, -205, -484, +132, -764, 408, -610, 425, -73, 181, 556, +-132, 866, -341, 681, -354, 108, -168, -576, +112, -951, 298, -755, 301, -109, 132, 629, +-69, 1023, -191, 800, -213, 103, -142, -682, +-3, -1068, 129, -817, 179, -80, 140, 708, +35, 1096, -68, 826, -114, 47, -104, -730, +-42, -1065, 16, -794, 32, -41, 10, 728, +11, 1059, 45, 732, 87, -36, 85, -750, +21, -985, -88, -638, -192, 82, -180, 744, +-34, 923, 141, 508, 245, -197, 216, -744, +48, -825, -152, -401, -251, 257, -227, 734, +-83, 744, 98, 283, 221, -333, 236, -741, +134, -690, -28, -203, -155, 405, -240, 742, +-257, 608, -117, 116, 114, -457, 293, -758, +349, -587, 213, -75, -77, 501, -341, 775, +-417, 577, -271, 35, 42, -533, 327, -814, +425, -623, 293, -64, 2, 542, -281, 846, +-398, 664, -293, 91, -47, -519, 194, -830, +320, -689, 278, -175, 75, 441, -148, 801, +-234, 716, -199, 229, -82, -352, 54, -738, +125, -726, 120, -304, 90, 276, 56, 677, +28, 681, -37, 326, -152, -179, -198, -567, +-127, -619, 15, -351, 200, 80, 307, 430, +219, 541, -15, 388, -259, 70, -362, -265, +-221, -471, 45, -440, 268, -190, 330, 141, +196, 392, -24, 462, -204, 308, -264, -7, +-161, -321, 18, -463, 121, -352, 153, -72, +142, 263, 72, 460, -7, 400, -82, 106, +-153, -226, -173, -401, -82, -376, 83, -159, +239, 165, 270, 393, 148, 381, -79, 166, +-329, -74, -382, -287, -149, -393, 175, -301, +393, -18, 428, 277, 197, 419, -208, 372, +-480, 151, -456, -194, -165, -471, 230, -492, +514, -241, 503, 149, 182, 493, -263, 604, +-547, 378, -495, -115, -172, -563, 259, -714, +559, -487, 520, 36, 185, 623, -207, 882, +-497, 596, -573, -25, -297, -641, 158, -944, +492, -751, 580, -119, 401, 636, -20, 1035, +-463, 869, -655, 243, -497, -530, -44, -1057, +436, -1021, 655, -431, 513, 395, 99, 1018, +-353, 1117, -597, 618, -517, -228, -168, -957, +260, -1169, 507, -795, 477, -21, 218, 803, +-142, 1248, -396, 992, -431, 196, -279, -699, +-8, -1222, 275, -1143, 399, -467, 309, 524, +91, 1239, -137, 1257, -300, 626, -354, -327, +-220, -1129, 29, -1345, 218, -829, 289, 112, +264, 989, 109, 1330, -104, 980, -238, 125, +-269, -802, -195, -1272, -52, -1040, 92, -317, +214, 522, 288, 1094, 241, 1091, 46, 520, +-208, -286, -386, -896, -364, -1024, -152, -678, +174, -13, 448, 658, 480, 993, 208, 804, +-199, 229, -474, -431, -474, -870, -211, -876, +168, -463, 444, 182, 450, 751, 230, 927, +-105, 643, -406, 33, -419, -585, -160, -911, +97, -774, 257, -238, 320, 423, 178, 858, +-60, 850, -182, 410, -182, -228, -98, -733, +-2, -855, 37, -545, 72, 44, 107, 614, +86, 877, 55, 664, -10, 84, -138, -544, +-159, -848, -56, -707, 75, -184, 202, 468, +218, 860, 30, 761, -207, 221, -309, -428, +-199, -809, 98, -739, 354, -268, 388, 344, +184, 769, -188, 746, -501, 315, -487, -279, +-128, -683, 332, -674, 608, -322, 506, 160, +104, 541, -379, 618, -674, 377, -553, -28, +-81, -402, 424, -554, 674, -423, 560, -128, +142, 235, -344, 511, -643, 544, -608, 286, +-246, -117, 238, -505, 611, -656, 667, -453, +358, -7, -139, 485, -526, 757, -647, 623, +-463, 137, -19, -482, 438, -854, 622, -738, +463, -208, 107, 420, -264, 846, -481, 807, +-473, 302, -271, -357, 66, -800, 349, -776, +434, -317, 346, 252, 141, 638, -165, 688, +-416, 359, -464, -149, -308, -508, 15, -568, +350, -322, 503, 46, 414, 324, 121, 389, +-263, 275, -505, 73, -465, -117, -225, -220, +114, -234, 392, -183, 466, -111, 319, -13, +43, 161, -241, 316, -404, 359, -385, 210, +-212, -95, 48, -412, 270, -542, 381, -401, +364, -24, 181, 426, -122, 701, -378, 583, +-455, 104, -363, -447, -93, -737, 285, -625, +564, -182, 545, 355, 238, 706, -198, 641, +-574, 224, -682, -278, -419, -562, 94, -536, +571, -274, 768, 95, 582, 376, 66, 455, +-530, 335, -859, 96, -708, -161, -187, -351, +451, -388, 891, -291, 856, -74, 318, 211, +-399, 452, -878, 504, -872, 292, -400, -99, +283, -456, 825, -609, 897, -476, 464, -76, +-172, 405, -693, 686, -856, 610, -541, 209, +70, -291, 614, -636, 840, -663, 608, -380, +42, 119, -522, 553, -820, 705, -676, 512, +-128, 52, 488, -412, 826, -657, 731, -606, +194, -249, -472, 248, -828, 617, -716, 676, +-191, 428, 462, -67, 817, -533, 665, -741, +160, -609, -403, -146, -696, 436, -576, 805, +-172, 784, 297, 338, 578, -331, 537, -817, +239, -882, -171, -511, -502, 164, -550, 767, +-292, 959, 99, 639, 454, -18, 567, -670, +351, -945, -67, -731, -428, -135, -523, 549, +-334, 904, -7, 775, 307, 254, 459, -412, +341, -829, 73, -783, -171, -342, -340, 244, +-366, 711, -221, 791, 35, 458, 283, -96, +400, -582, 294, -754, 47, -544, -232, -87, +-411, 389, -361, 662, -115, 618, 188, 297, +408, -137, 390, -514, 117, -673, -193, -524, +-367, -119, -357, 320, -136, 654, 157, 733, +331, 430, 292, -137, 96, -667, -136, -882, +-245, -652, -196, -61, -69, 606, 62, 994, +142, 853, 141, 210, 58, -540, -36, -1032, +-84, -989, -87, -370, -46, 444, 18, 985, +71, 1029, 74, 536, 29, -239, -42, -863, +-84, -1055, -87, -708, -38, 8, 69, 654, +145, 974, 124, 867, 48, 322, -65, -400, +-212, -882, -239, -967, -71, -579, 140, 109, +272, 699, 293, 962, 156, 784, -131, 193, +-372, -475, -380, -898, -150, -900, 155, -447, +374, 227, 409, 734, 216, 924, -95, 677, +-340, 73, -409, -533, -282, -881, -8, -845, +255, -376, 372, 259, 370, 746, 249, 938, +-36, 696, -372, 85, -528, -563, -432, -988, +-125, -960, 319, -440, 676, 285, 687, 872, +309, 1112, -261, 797, -745, 59, -837, -677, +-439, -1122, 208, -1062, 744, -473, 898, 333, +591, 993, -45, 1225, -670, 870, -928, 77, +-669, -745, -79, -1272, 518, -1205, 863, -520, +775, 417, 265, 1191, -368, 1447, -775, 965, +-798, -25, -413, -1021, 194, -1565, 655, -1336, +761, -402, 507, 737, 7, 1552, -487, 1607, +-675, 837, -509, -348, -128, -1360, 256, -1771, +465, -1284, 448, -120, 258, 1067, -3, 1752, +-215, 1623, -315, 682, -328, -601, -266, -1605, +-109, -1857, 143, -1201, 417, 63, 503, 1284, +327, 1928, -1, 1656, -367, 544, -632, -842, +-578, -1842, -197, -1988, 293, -1120, 667, 358, +718, 1653, 396, 2131, -136, 1568, -627, 213, +-825, -1271, -608, -2155, -80, -1954, 518, -733, +878, 855, 748, 1965, 250, 2138, -331, 1281, +-783, -240, -872, -1643, -506, -2245, 98, -1759, +646, -377, 885, 1196, 684, 2169, 185, 2111, +-398, 1035, -842, -606, -879, -1957, -483, -2371, +139, -1610, 728, 23, 987, 1647, 747, 2403, +154, 1991, -559, 576, -1053, -1172, -982, -2308, +-384, -2257, 393, -1059, 993, 681, 1103, 2002, +632, 2277, -155, 1452, -860, -88, -1136, -1578, +-823, -2221, -107, -1777, 651, -469, 1088, 1071, +998, 2017, 422, 1964, -370, 987, -1006, -492, +-1135, -1728, -660, -2098, 152, -1437, 873, -47, +1150, 1362, 846, 2015, 122, 1688, -653, 558, +-1083, -865, -949, -1816, -337, -1811, 394, -937, +904, 367, 978, 1429, 580, 1724, -91, 1205, +-682, 149, -930, -960, -740, -1545, -183, -1375, +451, -585, 831, 464, 824, 1274, 449, 1425, +-148, 921, -678, 5, -875, -920, -655, -1381, +-115, -1158, 452, -382, 803, 568, 822, 1204, +447, 1244, -187, 711, -712, -151, -893, -946, +-689, -1228, -146, -928, 510, -238, 964, 555, +966, 1074, 450, 1070, -328, 604, -954, -128, +-1132, -803, -726, -1081, 116, -881, 905, -292, +1224, 477, 916, 1009, 101, 1042, -783, 611, +-1228, -109, -1032, -809, -305, -1081, 577, -824, +1124, -186, 1085, 554, 514, 998, -316, 931, +-951, 433, -1086, -254, -715, -782, -21, -913, +695, -627, 1059, -54, 914, 550, 334, 833, +-437, 731, -1011, 341, -1082, -198, -627, -634, +149, -762, 887, -570, 1181, -130, 866, 366, +96, 681, -738, 715, -1177, 463, -1025, -6, +-375, -469, 496, -754, 1133, -749, 1152, -387, +601, 203, -244, 688, -999, 888, -1222, 726, +-812, 187, -26, -506, 795, -983, 1219, -985, +995, -486, 292, 270, -562, 906, -1165, 1122, +-1144, 799, -558, 19, 293, -785, 1065, -1181, +1294, -1003, 793, -313, -96, 550, -931, 1104, +-1305, 1114, -960, 594, -98, -242, 807, -948, +1274, -1165, 1004, -830, 213, -87, -608, 663, +-1094, 1041, -992, 963, -330, 475, 425, -277, +879, -858, 876, -1025, 424, -774, -196, -171, +-617, 511, -696, 953, -456, 1017, -50, 610, +311, -130, 518, -808, 504, -1141, 268, -988, +-33, -297, -291, 563, -472, 1163, -476, 1256, +-233, 696, 127, -286, 441, -1121, 573, -1428, +439, -1024, 75, -29, -332, 987, -582, 1487, +-560, 1247, -264, 317, 181, -785, 550, -1446, +660, -1387, 448, -620, 6, 511, -458, 1324, +-704, 1429, -586, 826, -149, -211, 358, -1089, +688, -1356, 677, -975, 293, -104, -240, 813, +-606, 1223, -666, 988, -398, 318, 77, -490, +480, -967, 620, -904, 474, -455, 104, 172, +-291, 683, -534, 776, -538, 501, -271, 56, +123, -361, 414, -531, 545, -452, 440, -270, +64, 16, -339, 305, -532, 424, -488, 377, +-204, 235, 199, -7, 480, -257, 512, -450, +290, -481, -70, -236, -358, 142, -481, 439, +-391, 581, -92, 468, 225, 94, 410, -320, +453, -594, 260, -630, -112, -313, -386, 166, +-456, 528, -341, 667, -34, 510, 293, 103, +446, -325, 395, -641, 145, -692, -200, -350, +-414, 158, -422, 531, -238, 711, 74, 594, +347, 157, 437, -373, 313, -743, 12, -778, +-282, -383, -398, 185, -343, 645, -119, 850, +206, 633, 383, 68, 334, -514, 159, -888, +-101, -839, -329, -301, -348, 360, -186, 790, +52, 906, 255, 569, 313, -84, 216, -670, +25, -961, -183, -792, -263, -185, -207, 448, +-103, 852, 68, 932, 242, 529, 246, -163, +136, -743, 4, -1037, -160, -820, -257, -128, +-185, 563, -31, 967, 128, 980, 227, 456, +206, -310, 90, -897, -58, -1092, -185, -707, +-210, 53, -141, 685, -20, 1015, 135, 908, +251, 285, 240, -462, 111, -941, -97, -1040, +-269, -602, -293, 151, -165, 775, 53, 1060, +279, 853, 361, 180, 244, -534, 8, -1010, +-251, -1054, -408, -512, -342, 279, -78, 843, +241, 1048, 458, 771, 449, 91, 196, -586, +-184, -982, -510, -959, -565, -439, -274, 259, +192, 784, 546, 991, 613, 736, 352, 127, +-127, -483, -562, -908, -668, -965, -388, -511, +97, 188, 505, 743, 629, 1006, 431, 825, +31, 248, -377, -435, -585, -971, -505, -1101, +-194, -645, 213, 131, 522, 830, 567, 1203, +352, 1032, -30, 337, -436, -529, -657, -1216, +-537, -1350, -119, -752, 376, 230, 658, 1072, +606, 1473, 275, 1176, -224, 269, -653, -779, +-715, -1503, -400, -1506, 87, -687, 539, 445, +731, 1327, 532, 1644, 74, 1171, -400, 72, +-688, -1052, -648, -1705, -282, -1525, 233, -538, +619, 679, 687, 1552, 445, 1757, -2, 1087, +-479, -162, -738, -1330, -629, -1892, -210, -1513, +328, -322, 711, 971, 747, 1783, 422, 1800, +-131, 916, -641, -466, -814, -1615, -586, -1993, +-80, -1341, 484, -21, 813, 1216, 735, 1883, +303, 1696, -303, 617, -766, -758, -820, -1713, +-477, -1861, 96, -1088, 666, 213, 888, 1312, +630, 1798, 71, 1467, -517, 406, -841, -821, +-718, -1649, -245, -1739, 337, -943, 741, 297, +741, 1295, 375, 1723, -129, 1395, -550, 345, +-662, -859, -435, -1653, -74, -1689, 269, -875, +502, 349, 496, 1328, 289, 1717, 9, 1314, +-278, 253, -470, -903, -468, -1645, -277, -1637, +71, -786, 427, 416, 585, 1330, 482, 1648, +168, 1237, -266, 221, -590, -870, -644, -1577, +-421, -1572, 32, -782, 520, 346, 756, 1250, +640, 1647, 232, 1326, -330, 351, -785, -808, +-861, -1652, -489, -1757, 155, -950, 739, 309, +976, 1389, 724, 1895, 86, 1544, -600, 375, +-985, -1011, -909, -1951, -364, -1950, 392, -938, +919, 513, 984, 1681, 616, 2123, -52, 1558, +-714, 167, -1025, -1324, -848, -2185, -279, -1986, +426, -753, 948, 815, 1046, 1956, 638, 2235, +-114, 1432, -832, -151, -1165, -1652, -943, -2342, +-219, -1868, 645, -433, 1193, 1139, 1158, 2108, +540, 2149, -370, 1136, -1096, -475, -1280, -1795, +-835, -2232, 35, -1596, 887, -174, 1290, 1224, +1064, 2023, 310, 1969, -594, 930, -1183, -601, +-1192, -1745, -643, -2054, 216, -1417, 956, -88, +1227, 1213, 923, 1929, 177, 1823, -660, 815, +-1161, -587, -1113, -1656, -567, -1985, 260, -1397, +992, -120, 1239, 1147, 891, 1918, 129, 1890, +-697, 897, -1200, -565, -1142, -1716, -558, -2122, +319, -1533, 1077, -160, 1321, 1282, 923, 2157, +75, 2055, -840, 871, -1368, -755, -1234, -1989, +-498, -2317, 526, -1507, 1331, 94, 1463, 1608, +866, 2362, -166, 2002, -1141, 599, -1552, -1094, +-1188, -2220, -244, -2319, 859, -1253, 1544, 458, +1428, 1891, 596, 2423, -537, 1796, -1401, 210, +-1518, -1448, -869, -2349, 198, -2143, 1169, -860, +1499, 858, 1038, 2063, 128, 2262, -809, 1366, +-1323, -229, -1122, -1635, -416, -2176, 391, -1688, +1006, -365, 1141, 1057, 738, 1833, 38, 1758, +-653, 881, -1028, -437, -920, -1414, -437, -1641, +255, -1173, 871, -196, 1047, 815, 740, 1353, +118, 1318, -617, 718, -1057, -209, -942, -958, +-414, -1259, 300, -1060, 907, -359, 1058, 457, +715, 997, 49, 1176, -690, 855, -1082, 97, +-916, -621, -355, -1055, 391, -1107, 993, -648, +1070, 81, 609, 721, -122, 1160, -809, 1134, +-1075, 536, -785, -279, -147, -1013, 553, -1411, +989, -1127, 907, -282, 410, 716, -254, 1520, +-831, 1638, -988, 869, -627, -333, -9, -1439, +600, -1913, 941, -1387, 803, -158, 269, 1142, +-365, 1991, -819, 1854, -861, 743, -486, -700, +95, -1832, 620, -2101, 825, -1280, 612, 107, +150, 1422, -371, 2173, -756, 1861, -748, 577, +-347, -929, 183, -2015, 612, -2180, 747, -1270, +516, 239, 55, 1681, -435, 2400, -735, 1885, +-638, 422, -222, -1223, 263, -2353, 608, -2323, +653, -1061, 375, 676, -59, 2100, -476, 2557, +-678, 1676, -501, -65, -69, -1715, 350, -2535, +594, -2079, 542, -591, 208, 1120, -207, 2310, +-507, 2364, -568, 1176, -304, -498, 125, -1854, +417, -2371, 453, -1696, 287, -185, 18, 1287, +-216, 2146, -335, 1995, -291, 829, -99, -661, +83, -1761, 158, -2074, 212, -1366, 212, 0, +100, 1283, -44, 1964, -193, 1715, -321, 607, +-250, -715, -10, -1680, 206, -1898, 346, -1160, +338, 130, 111, 1271, -190, 1859, -391, 1575, +-378, 474, -119, -805, 186, -1682, 332, -1806, +328, -1004, 167, 276, -99, 1349, -278, 1810, +-290, 1393, -170, 242, 48, -942, 230, -1644, +271, -1589, 175, -716, -20, 470, -185, 1327, +-218, 1589, -159, 1086, -12, 28, 167, -955, +206, -1453, 97, -1297, -28, -495, -119, 482, +-117, 1190, -32, 1420, 40, 948, 74, -29, +61, -905, -15, -1373, -61, -1233, -49, -428, +-14, 547, 62, 1215, 103, 1386, 16, 838, +-77, -174, -102, -1009, -93, -1333, -18, -1016, +106, -179, 170, 626, 152, 1115, 32, 1154, +-165, 541, -257, -333, -163, -863, -1, -1008, +141, -722, 223, -60, 199, 512, 74, 816, +-116, 855, -275, 435, -246, -189, -56, -624, +131, -813, 248, -649, 272, -182, 134, 265, +-110, 681, -301, 892, -333, 565, -171, -21, +111, -514, 320, -863, 333, -801, 184, -335, +-49, 205, -279, 759, -374, 1049, -257, 692, +38, 1, 307, -627, 351, -1023, 188, -902, +-17, -316, -210, 367, -307, 958, -206, 1089, +-6, 572, 142, -174, 224, -801, 202, -1097, +68, -776, -58, -91, -124, 531, -184, 981, +-181, 997, -58, 435, 111, -287, 198, -846, +175, -1043, 76, -702, -42, -68, -139, 536, +-173, 1007, -130, 1007, -30, 445, 91, -278, +172, -897, 179, -1172, 121, -787, -16, -12, +-184, 708, -257, 1180, -192, 1093, -39, 372, +164, -515, 284, -1178, 236, -1275, 70, -624, +-134, 300, -257, 977, -207, 1285, -83, 955, +50, 32, 202, -854, 242, -1289, 115, -1117, +-35, -302, -157, 611, -205, 1128, -127, 1183, +-21, 645, 60, -308, 173, -1025, 208, -1207, +114, -804, -5, 60, -135, 794, -230, 1046, +-181, 912, -56, 282, 89, -580, 257, -1019, +289, -911, 110, -405, -113, 344, -268, 823, +-279, 831, -123, 546, 74, -49, 230, -684, +325, -837, 210, -545, -74, -40, -280, 471, +-313, 653, -193, 509, 46, 235, 240, -211, +284, -554, 196, -490, -12, -212, -234, 82, +-275, 307, -136, 301, 54, 208, 188, 129, +192, -69, 93, -235, -15, -203, -110, -128, +-158, -37, -98, 53, 10, 86, 57, 164, +50, 207, 47, 64, 51, -72, 36, -127, +7, -191, -24, -166, -58, -58, -98, 39, +-83, 208, -4, 311, 74, 187, 114, -13, +112, -190, 32, -314, -83, -256, -147, -106, +-137, 74, -62, 315, 55, 397, 137, 204, +162, -32, 119, -240, -20, -361, -166, -272, +-196, -90, -152, 98, -41, 328, 137, 377, +232, 191, 162, -44, 28, -270, -98, -380, +-178, -252, -172, -56, -95, 169, 36, 419, +161, 410, 174, 91, 116, -241, 31, -449, +-103, -401, -191, -86, -158, 223, -84, 397, +36, 418, 163, 148, 173, -245, 97, -442, +10, -364, -96, -55, -135, 268, -93, 314, +-61, 207, 3, 76, 91, -158, 97, -320, +80, -222, 68, -15, -2, 200, -81, 276, +-120, 104, -151, -53, -87, -72, 67, -148, +192, -185, 235, -82, 142, 52, -69, 204, +-215, 247, -237, 57, -187, -60, -22, -63, +182, -194, 251, -253, 187, -75, 55, 142, +-80, 320, -148, 280, -170, -8, -169, -164, +-71, -179, 83, -260, 202, -163, 246, 107, +160, 271, -21, 330, -166, 182, -254, -165, +-262, -272, -115, -198, 120, -192, 290, -37, +323, 207, 187, 281, -21, 265, -190, 74, +-317, -218, -346, -240, -150, -146, 159, -148, +365, 15, 393, 201, 235, 196, -43, 172, +-299, 54, -434, -153, -380, -142, -108, -91, +251, -137, 479, -39, 465, 92, 219, 130, +-121, 207, -401, 146, -521, -48, -419, -120, +-84, -195, 333, -263, 596, -77, 538, 128, +196, 224, -218, 301, -521, 166, -610, -105, +-389, -199, 63, -238, 480, -216, 643, -15, +488, 126, 63, 169, -386, 243, -606, 138, +-558, -52, -283, -96, 172, -156, 589, -216, +688, -121, 420, -16, -51, 125, -492, 284, +-689, 225, -570, 66, -172, -44, 360, -244, +730, -334, 676, -178, 243, 2, -316, 202, +-687, 381, -654, 270, -286, 34, 176, -132, +535, -312, 604, -359, 338, -181, -70, 38, +-393, 279, -492, 412, -342, 262, -86, 27, +158, -165, 352, -370, 399, -360, 217, -122, +-74, 102, -323, 284, -391, 360, -224, 193, +45, -22, 242, -180, 293, -290, 179, -242, +-33, -91, -176, 33, -169, 198, -70, 295, +19, 202, 19, 62, -29, -93, -34, -280, +52, -308, 147, -192, 148, -1, 36, 262, +-111, 391, -192, 268, -162, 59, -66, -197, +54, -379, 169, -309, 175, -127, 64, 61, +-28, 305, -77, 369, -109, 182, -97, -18, +-74, -173, -42, -274, 91, -232, 204, -124, +148, 63, 2, 273, -123, 259, -192, 107, +-146, 19, -23, -121, 109, -213, 189, -139, +106, -85, -77, -16, -137, 140, -51, 141, +74, 102, 122, 162, 17, 79, -141, -112, +-174, -225, -81, -319, 80, -218, 225, 102, +225, 304, 68, 370, -164, 336, -320, 8, +-224, -356, 23, -464, 161, -361, 186, -17, +170, 364, 61, 404, -44, 279, -87, 107, +-161, -209, -218, -377, -148, -254, -17, -98, +150, 83, 334, 225, 361, 183, 130, 131, +-243, 100, -511, -50, -465, -158, -151, -203, +235, -226, 543, -65, 553, 149, 152, 224, +-318, 279, -551, 209, -529, -70, -224, -280, +251, -322, 519, -247, 461, 17, 213, 253, +-139, 290, -417, 240, -450, 75, -273, -163, +25, -255, 296, -252, 383, -158, 278, 82, +40, 225, -245, 200, -342, 182, -230, 61, +-82, -140, 85, -233, 234, -251, 196, -153, +60, 109, -7, 244, -72, 230, -145, 190, +-137, -11, -105, -236, -62, -237, 57, -188, +181, -81, 173, 158, 55, 246, -71, 153, +-155, 105, -187, -1, -119, -147, 49, -200, +165, -219, 121, -100, 23, 153, -26, 233, +-59, 211, -90, 174, -77, -81, -51, -322, +-32, -265, 36, -135, 124, 64, 109, 341, +22, 326, -42, 45, -99, -165, -152, -289, +-69, -233, 107, 1, 121, 156, -20, 228, +-77, 202, -39, -68, -1, -244, 64, -130, +95, -5, -4, 117, -146, 222, -192, 53, +-67, -147, 137, -155, 231, -151, 154, -40, +-36, 217, -252, 288, -278, 169, -60, -58, +144, -349, 206, -358, 170, -75, 3, 147, +-181, 353, -191, 439, -74, 129, 56, -283, +127, -478, 57, -452, -24, -78, -22, 408, +-30, 560, -37, 412, 3, 43, -30, -447, +-79, -617, -19, -398, 48, -26, 78, 450, +98, 707, -2, 424, -156, -63, -160, -453, +-43, -652, 81, -457, 164, 29, 118, 466, +-39, 683, -184, 478, -214, -64, -82, -497, +108, -637, 181, -464, 130, 60, 20, 554, +-116, 643, -176, 387, -114, -87, -23, -559, +58, -646, 107, -349, 81, 122, 10, 558, +-41, 639, -92, 309, -133, -138, -113, -518, +6, -644, 146, -360, 153, 136, 39, 524, +-55, 659, -145, 435, -222, -48, -126, -535, +89, -789, 203, -593, 180, 22, 36, 628, +-169, 893, -265, 705, -180, 58, 7, -722, +192, -1085, 236, -805, 134, -48, -49, 779, +-274, 1190, -342, 899, -120, 46, 145, -868, +256, -1240, 258, -898, 123, -89, -147, 813, +-351, 1286, -359, 947, -159, 58, 164, -815, +399, -1228, 388, -921, 154, -76, -205, 748, +-476, 1137, -466, 882, -207, 103, 169, -689, +490, -1062, 492, -844, 161, -79, -230, 691, +-484, 946, -500, 699, -215, 101, 180, -610, +448, -931, 494, -664, 248, -17, -199, 665, +-516, 915, -526, 537, -263, -131, 161, -726, +498, -898, 505, -427, 196, 343, -236, 887, +-540, 939, -497, 327, -123, -650, 318, -1205, +534, -945, 359, -62, -74, 972, -439, 1442, +-518, 984, -274, -114, 177, -1285, 517, -1765, +488, -1054, 129, 378, -342, 1624, -624, 1969, +-497, 1080, -57, -551, 424, -1862, 667, -2135, +487, -1155, -14, 633, -524, 2113, -773, 2349, +-574, 1195, 4, -753, 576, -2278, 788, -2437, +547, -1218, -16, 742, -569, 2360, -802, 2564, +-618, 1252, -96, -767, 486, -2371, 758, -2565, +598, -1226, 150, 729, -364, 2244, -717, 2508, +-717, 1287, -364, -643, 174, -2113, 628, -2392, +761, -1303, 507, 515, -40, 1944, -617, 2260, +-858, 1329, -643, -360, -131, -1756, 472, -2121, +851, -1369, 706, 163, 153, 1600, -452, 2028, +-808, 1342, -716, -30, -244, -1383, 300, -1895, +651, -1333, 628, -133, 257, 1128, -200, 1759, +-531, 1348, -588, 242, -318, -904, 60, -1553, +303, -1326, 387, -416, 309, 607, 62, 1320, +-183, 1355, -293, 598, -283, -411, -186, -1107, +-46, -1275, 66, -796, 161, 124, 255, 912, +253, 1214, 82, 916, -197, 128, -433, -681, +-464, -1101, -246, -1018, 143, -407, 512, 407, +583, 968, 245, 1089, -263, 687, -615, -126, +-610, -849, -218, -1137, 298, -937, 551, -232, +445, 694, 104, 1254, -311, 1138, -529, 426, +-381, -508, -49, -1184, 232, -1293, 358, -743, +249, 298, -15, 1210, -215, 1407, -285, 863, +-211, -88, -28, -1015, 109, -1437, 163, -1106, +164, -172, 43, 880, -126, 1458, -209, 1243, +-211, 386, -114, -676, 53, -1370, 178, -1336, +259, -636, 209, 419, -78, 1314, -387, 1467, +-440, 785, -257, -265, 69, -1131, 408, -1425, +523, -977, 299, 26, -140, 1056, -561, 1479, +-699, 1055, -409, 83, 158, -916, 641, -1445, +727, -1170, 353, -192, -209, 934, -644, 1504, +-795, 1165, -517, 159, 131, -928, 655, -1488, +726, -1144, 428, -100, -89, 987, -566, 1491, +-707, 1090, -521, -20, -115, -1065, 381, -1384, +672, -922, 571, 24, 164, 984, -343, 1366, +-651, 919, -616, -76, -331, -1006, 121, -1289, +576, -834, 675, -2, 328, 858, -166, 1317, +-534, 991, -617, 67, -350, -892, 58, -1380, +348, -1063, 442, -149, 278, 821, -72, 1430, +-306, 1286, -299, 308, -180, -868, -52, -1546, +34, -1389, 53, -424, 63, 794, 100, 1549, +131, 1512, 96, 633, -60, -676, -271, -1602, +-366, -1616, -275, -757, -38, 502, 294, 1444, +498, 1622, 343, 1000, -40, -187, -409, -1319, +-612, -1673, -457, -1122, 2, -76, 394, 955, +549, 1506, 436, 1314, 33, 492, -421, -587, +-645, -1381, -533, -1436, -94, -798, 376, 129, +547, 1004, 451, 1478, 157, 1254, -312, 389, +-664, -719, -605, -1523, -179, -1561, 313, -838, +587, 290, 528, 1374, 164, 1853, -326, 1360, +-644, 118, -612, -1257, -233, -2025, 290, -1708, +593, -504, 500, 942, 134, 2008, -279, 2093, +-522, 1004, -514, -670, -282, -1983, 108, -2233, +430, -1317, 468, 221, 284, 1674, -21, 2350, +-374, 1750, -581, 187, -518, -1396, -203, -2267, +291, -1990, 695, -662, 683, 943, 253, 2063, +-354, 2225, -864, 1200, -950, -493, -454, -1895, +371, -2326, 1019, -1566, 1076, -14, 464, 1510, +-479, 2348, -1212, 2007, -1284, 511, -582, -1251, +492, -2279, 1272, -2138, 1308, -901, 575, 796, +-539, 2058, -1380, 2271, -1413, 1289, -635, -421, +456, -1852, 1256, -2227, 1350, -1466, 643, -2, +-445, 1463, -1216, 2169, -1287, 1721, -729, 360, +163, -1191, 959, -2088, 1217, -1809, 756, -569, +-82, 896, -753, 1856, -1048, 1851, -944, 820, +-374, -699, 417, -1762, 963, -1715, 1000, -721, +548, 537, -185, 1402, -882, 1479, -1188, 731, +-895, -393, -136, -1193, 750, -1193, 1295, -503, +1049, 332, 145, 820, -781, 791, -1287, 362, +-1153, -166, -389, -518, 576, -536, 1201, -216, +1133, 152, 374, 245, -534, 138, -1040, 70, +-1016, 60, -544, 40, 156, 13, 733, -40, +911, -125, 584, -216, -39, -233, -553, -50, +-760, 271, -655, 445, -267, 319, 219, -38, +549, -393, 570, -494, 309, -320, -48, 19, +-331, 438, -477, 618, -446, 328, -288, -159, +-77, -500, 189, -555, 427, -256, 489, 190, +352, 491, 30, 516, -426, 213, -797, -235, +-812, -488, -370, -459, 330, -170, 884, 245, +1042, 465, 675, 378, -211, 133, -1101, -198, +-1392, -440, -1004, -368, -86, -78, 1009, 183, +1588, 335, 1273, 317, 269, 99, -969, -143, +-1789, -240, -1674, -226, -637, -97, 790, 84, +1789, 131, 1805, 87, 870, 87, -586, 61, +-1813, 6, -2081, -23, -1238, -69, 284, -110, +1665, -110, 2099, -93, 1401, 5, -36, 161, +-1496, 238, -2190, 187, -1739, 28, -347, -152, +1268, -225, 2106, -233, 1738, -196, 514, -19, +-971, 246, -1974, 413, -1914, 376, -858, 129, +629, -207, 1727, -482, 1792, -594, 928, -408, +-320, 117, -1420, 693, -1786, 922, -1205, 591, +-65, -159, 1045, -859, 1586, -1082, 1257, -749, +295, 47, -778, 954, -1446, 1360, -1359, 930, +-611, -84, 357, -1093, 1118, -1460, 1301, -959, +771, 59, -117, 1041, -887, 1492, -1270, 1105, +-1066, 63, -321, -1048, 559, -1567, 1144, -1141, +1178, -95, 600, 889, -354, 1386, -1204, 1203, +-1422, 371, -843, -675, 150, -1317, 1026, -1228, +1387, -514, 956, 395, -94, 1041, -1075, 1151, +-1399, 739, -1002, 5, -120, -726, 830, -1099, +1274, -918, 946, -322, 141, 353, -683, 850, +-1170, 1036, -1079, 767, -441, 77, 437, -671, +1070, -1105, 1067, -1074, 479, -537, -351, 321, +-1023, 1109, -1167, 1432, -701, 1016, 124, -15, +915, -1084, 1179, -1645, 714, -1419, -149, -433, +-907, 882, -1167, 1856, -819, 1887, -122, 831, +625, -720, 1116, -1898, 988, -2133, 231, -1284, +-675, 304, -1187, 1828, -1082, 2430, -494, 1715, +355, 48, 1122, -1668, 1298, -2502, 672, -2025, +-415, -519, -1314, 1279, -1451, 2490, -792, 2389, +226, 1007, 1134, -897, 1456, -2353, 926, -2559, +-160, -1427, -1184, 348, -1563, 1978, -1067, 2698, +-23, 1970, 957, 180, 1407, -1652, 1101, -2651, +189, -2285, -839, -742, -1444, 1132, -1290, 2458, +-441, 2570, 620, 1301, 1305, -633, 1258, -2189, +514, -2613, -511, -1678, -1262, 87, -1341, 1712, +-698, 2460, 286, 2006, 1059, 541, 1222, -1173, +678, -2238, -256, -2152, -981, -1032, -1110, 496, +-681, 1766, 26, 2240, 665, 1589, 923, 110, +622, -1368, -59, -2143, -605, -1891, -746, -737, +-522, 798, -47, 1983, 317, 2145, 351, 1175, +287, -318, 119, -1614, -201, -2116, -279, -1522, +-123, -217, -89, 1126, -122, 1958, -152, 1770, +-134, 673, 104, -634, 325, -1591, 268, -1803, +85, -1133, -170, 24, -432, 1185, -504, 1818, +-348, 1469, 80, 387, 570, -781, 583, -1579, +174, -1614, -183, -834, -468, 348, -643, 1361, +-442, 1645, 13, 1043, 404, -21, 600, -995, +440, -1436, -48, -1149, -474, -334, -611, 591, +-496, 1181, -149, 1148, 302, 582, 583, -204, +513, -832, 57, -1009, -480, -742, -612, -210, +-365, 405, -56, 822, 249, 846, 414, 509, +242, -30, -80, -527, -288, -782, -306, -751, +-115, -385, 79, 208, 47, 699, -62, 866, +-81, 667, -55, 136, 42, -477, 140, -875, +64, -879, -94, -427, -225, 252, -309, 777, +-184, 941, 99, 639, 258, 11, 246, -579, +99, -919, -165, -828, -338, -234, -321, 417, +-180, 775, 45, 844, 218, 511, 247, -122, +180, -658, -12, -913, -277, -692, -414, -35, +-332, 532, -65, 776, 218, 754, 335, 346, +300, -292, 100, -774, -266, -827, -528, -392, +-463, 175, -154, 529, 217, 694, 432, 573, +367, 123, 120, -358, -192, -663, -459, -649, +-512, -268, -290, 164, 87, 476, 412, 676, +460, 551, 201, 94, -120, -420, -358, -781, +-498, -714, -409, -207, -58, 345, 299, 739, +430, 853, 270, 437, -20, -289, -186, -810, +-278, -894, -380, -498, -288, 198, -28, 748, +153, 885, 276, 565, 320, -97, 172, -675, +-46, -823, -313, -574, -596, -48, -538, 526, +-80, 796, 366, 617, 586, 126, 539, -415, +158, -712, -375, -640, -745, -265, -745, 248, +-297, 673, 323, 758, 666, 386, 632, -225, +300, -668, -238, -746, -659, -469, -726, 49, +-450, 571, 73, 843, 514, 663, 570, 43, +362, -582, 26, -842, -371, -715, -567, -256, +-470, 369, -216, 857, 106, 965, 329, 520, +361, -272, 301, -913, 118, -1124, -201, -778, +-453, 60, -533, 901, -423, 1343, -80, 1139, +351, 161, 625, -1023, 594, -1585, 187, -1302, +-426, -305, -843, 960, -827, 1722, -395, 1543, +289, 500, 842, -919, 913, -1820, 457, -1668, +-313, -640, -961, 760, -1060, 1771, -605, 1767, +126, 857, 813, -491, 1052, -1656, 671, -1885, +-91, -1049, -833, 265, -1132, 1437, -825, 1870, +-142, 1280, 599, 69, 1054, -1158, 905, -1835, +250, -1480, -547, -326, -1133, 895, -1140, 1635, +-487, 1548, 409, 663, 1073, -503, 1170, -1416, +566, -1626, -411, -967, -1171, 136, -1312, 1102, +-709, 1557, 342, 1267, 1149, 384, 1209, -702, +576, -1560, -369, -1664, -1104, -850, -1202, 393, +-634, 1467, 255, 1882, 932, 1367, 971, 103, +447, -1346, -220, -2217, -716, -1867, -842, -428, +-546, 1245, -25, 2281, 430, 2193, 607, 925, +461, -956, 135, -2410, -223, -2571, -511, -1284, +-587, 767, -400, 2379, -48, 2679, 324, 1598, +536, -359, 462, -2224, 168, -2863, -223, -1890, +-600, 107, -720, 2041, -419, 2808, 93, 2008, +498, 224, 668, -1649, 522, -2695, 49, -2220, +-512, -506, -830, 1378, -700, 2450, -201, 2165, +348, 742, 678, -941, 681, -2110, 334, -2193, +-209, -991, -677, 691, -831, 1801, -571, 1958, +-40, 1134, 477, -300, 764, -1472, 680, -1820, +244, -1234, -368, 17, -885, 1163, -950, 1593, +-466, 1244, 201, 278, 720, -790, 925, -1381, +618, -1291, -88, -525, -731, 529, -994, 1182, +-774, 1202, -168, 688, 463, -177, 815, -948, +798, -1209, 374, -847, -272, -6, -779, 799, +-926, 1104, -653, 856, -82, 199, 508, -572, +903, -1041, 860, -947, 262, -294, -486, 521, +-926, 973, -971, 887, -570, 348, 152, -400, +763, -904, 966, -884, 678, -387, 9, 356, +-618, 905, -933, 884, -903, 344, -454, -367, +242, -829, 804, -808, 1039, -363, 756, 283, +-34, 805, -816, 843, -1188, 361, -1090, -303, +-422, -743, 619, -758, 1344, -394, 1270, 161, +505, 651, -537, 785, -1341, 493, -1465, -64, +-821, -597, 257, -781, 1186, -536, 1464, -72, +942, 443, -103, 798, -1082, 724, -1459, 236, +-1126, -405, -291, -853, 728, -803, 1384, -351, +1229, 251, 415, 826, -555, 992, -1269, 548, +-1359, -188, -725, -853, 242, -1060, 1031, -631, +1280, 60, 803, 707, -106, 1119, -859, 862, +-1162, 57, -940, -690, -240, -1071, 530, -888, +931, -211, 838, 468, 347, 924, -245, 987, +-659, 446, -848, -322, -669, -831, -108, -945, +404, -561, 633, 69, 649, 566, 376, 872, +-124, 792, -568, 197, -800, -469, -670, -814, +-173, -772, 355, -350, 676, 222, 709, 632, +385, 758, -157, 512, -655, -27, -903, -509, +-674, -652, -63, -461, 494, -106, 780, 207, +743, 391, 290, 434, -375, 310, -845, 37, +-893, -219, -493, -332, 159, -341, 665, -269, +793, -85, 546, 156, 30, 400, -506, 505, +-786, 295, -703, -70, -305, -345, 224, -532, +598, -524, 663, -208, 454, 233, 28, 612, +-480, 741, -790, 430, -711, -93, -303, -542, +247, -842, 681, -756, 769, -200, 477, 486, +-78, 1005, -667, 1045, -928, 447, -704, -372, +-175, -1006, 440, -1264, 863, -824, 812, 167, +349, 1067, -284, 1443, -850, 1068, -1007, 73, +-627, -942, 18, -1524, 644, -1369, 990, -383, +825, 830, 216, 1548, -534, 1515, -1064, 664, +-1065, -580, -540, -1450, 249, -1606, 961, -981, +1187, 250, 768, 1341, -71, 1658, -956, 1148, +-1393, 80, -1051, -1010, -166, -1567, 771, -1382, +1364, -485, 1219, 718, 326, 1498, -754, 1463, +-1414, 748, -1335, -304, -546, -1206, 509, -1512, +1253, -1080, 1314, -87, 645, 968, -386, 1480, +-1175, 1225, -1310, 421, -772, -556, 104, -1274, +871, -1384, 1182, -826, 854, 164, 36, 1096, +-763, 1450, -1110, 1067, -896, 202, -254, -749, +461, -1385, 884, -1369, 848, -615, 357, 507, +-338, 1347, -796, 1452, -785, 834, -420, -175, +63, -1101, 452, -1499, 606, -1110, 478, -108, +106, 913, -328, 1399, -555, 1171, -499, 390, +-301, -535, -23, -1180, 319, -1266, 538, -704, +444, 218, 86, 965, -327, 1214, -575, 901, +-514, 165, -207, -631, 158, -1138, 439, -1136, +507, -532, 253, 367, -190, 1020, -474, 1169, +-425, 798, -210, 32, 0, -775, 202, -1237, +321, -1098, 232, -357, 2, 586, -195, 1192, +-260, 1215, -202, 686, -102, -212, -11, -1088, +93, -1428, 162, -992, 110, -26, -30, 961, +-123, 1476, -113, 1217, -56, 327, -36, -735, +-56, -1484, -45, -1489, -6, -643, 10, 581, +44, 1496, 118, 1601, 108, 829, -62, -347, +-242, -1353, -288, -1739, -168, -1124, 69, 200, +278, 1349, 295, 1758, 103, 1231, -159, -32, +-345, -1228, -358, -1719, -143, -1346, 186, -165, +338, 1150, 218, 1730, 7, 1366, -196, 259, +-330, -1000, -254, -1606, -16, -1353, 184, -443, +250, 797, 133, 1579, -91, 1397, -221, 500, +-217, -651, -129, -1436, 46, -1377, 203, -624, +197, 463, 14, 1367, -215, 1449, -282, 678, +-140, -425, 31, -1290, 171, -1402, 260, -720, +152, 321, -138, 1226, -375, 1444, -372, 756, +-89, -335, 244, -1176, 345, -1339, 233, -736, +3, 244, -289, 1060, -447, 1295, -315, 770, +55, -198, 418, -988, 429, -1156, 69, -660, +-267, 115, -393, 725, -348, 955, -109, 661, +241, -28, 449, -618, 333, -748, -58, -425, +-417, 56, -478, 344, -267, 400, 57, 279, +318, -22, 390, -256, 284, -212, 0, 14, +-376, 236, -533, 193, -327, -118, 6, -316, +253, -302, 378, -182, 342, 144, 111, 519, +-216, 613, -432, 341, -418, -240, -206, -767, +80, -803, 292, -434, 354, 144, 272, 761, +71, 1017, -191, 726, -406, 12, -447, -842, +-245, -1238, 73, -903, 334, -159, 466, 701, +378, 1309, 38, 1205, -360, 435, -602, -613, +-540, -1414, -145, -1428, 309, -651, 552, 458, +536, 1404, 224, 1643, -256, 964, -575, -266, +-590, -1427, -335, -1841, 90, -1222, 433, 41, +543, 1337, 422, 1996, 67, 1547, -356, 242, +-596, -1210, -569, -2077, -265, -1833, 185, -613, +527, 939, 646, 2091, 444, 2156, -107, 1034, +-620, -609, -734, -1976, -501, -2364, -55, -1483, +429, 164, 688, 1747, 588, 2500, 168, 1928, +-362, 308, -669, -1466, -610, -2493, -290, -2206, +117, -776, 446, 1014, 591, 2338, 462, 2459, +36, 1219, -439, -618, -611, -2073, -454, -2461, +-171, -1545, 140, 119, 436, 1639, 540, 2361, +313, 1876, -78, 373, -376, -1251, -483, -2154, +-397, -1971, -174, -832, 115, 671, 402, 1843, +524, 2132, 334, 1312, -70, -191, -440, -1555, +-554, -2116, -401, -1627, -117, -347, 270, 1108, +600, 2058, 514, 1985, 64, 848, -346, -777, +-517, -1977, -428, -2099, -141, -1179, 174, 277, +386, 1673, 373, 2264, 99, 1596, -191, 59, +-277, -1468, -197, -2198, -62, -1765, 17, -482, +38, 1011, 71, 2060, 53, 2039, -15, 887, +19, -696, 92, -1884, 31, -2079, -127, -1188, +-247, 241, -210, 1519, -20, 2089, 151, 1552, +239, 167, 258, -1248, 112, -1978, -189, -1675, +-425, -535, -385, 774, -84, 1687, 220, 1797, +355, 933, 359, -399, 198, -1419, -147, -1707, +-464, -1160, -517, -56, -270, 1002, 122, 1556, +413, 1371, 496, 469, 375, -649, 22, -1382, +-433, -1430, -697, -758, -558, 293, -60, 1140, +463, 1414, 680, 986, 550, 11, 160, -962, +-370, -1379, -754, -1054, -697, -191, -203, 729, +382, 1224, 674, 1070, 572, 348, 208, -543, +-224, -1081, -558, -1006, -636, -418, -357, 350, +136, 888, 490, 929, 539, 503, 341, -146, +-15, -682, -370, -832, -565, -554, -499, -55, +-128, 423, 336, 718, 570, 678, 483, 277, +164, -245, -226, -615, -484, -710, -546, -489, +-360, -23, 72, 481, 454, 805, 532, 717, +372, 186, 72, -436, -270, -787, -501, -760, +-536, -372, -316, 240, 102, 788, 446, 935, +548, 501, 425, -259, 114, -800, -290, -869, +-612, -534, -661, 75, -323, 704, 215, 998, +601, 716, 682, -49, 449, -785, -59, -1020, +-620, -719, -871, -72, -581, 648, 73, 1084, +633, 974, 801, 269, 541, -680, -23, -1201, +-593, -1012, -845, -366, -606, 452, 15, 1101, +586, 1193, 734, 647, 478, -283, 33, -1064, +-400, -1198, -657, -737, -603, -11, -193, 730, +331, 1144, 595, 963, 535, 303, 277, -493, +-107, -1010, -476, -989, -664, -528, -529, 128, +-36, 732, 496, 998, 690, 762, 518, 132, +118, -522, -340, -852, -666, -795, -694, -405, +-304, 201, 313, 695, 686, 815, 643, 548, +321, 12, -145, -486, -562, -692, -742, -622, +-540, -283, 43, 230, 606, 600, 744, 665, +495, 441, 22, 1, -486, -424, -734, -666, +-589, -637, -116, -248, 446, 289, 683, 650, +486, 745, 101, 478, -282, -92, -518, -614, +-479, -854, -229, -686, 115, -90, 375, 555, +390, 901, 242, 851, 45, 332, -198, -427, +-373, -927, -363, -952, -180, -500, 99, 247, +294, 840, 310, 982, 238, 667, 65, 7, +-205, -675, -364, -988, -306, -797, -122, -228, +80, 438, 236, 882, 327, 897, 295, 476, +65, -185, -249, -756, -434, -952, -382, -662, +-136, -53, 164, 577, 405, 948, 484, 829, +273, 259, -145, -422, -470, -898, -513, -933, +-285, -454, 61, 269, 337, 851, 463, 995, +380, 562, 89, -165, -243, -746, -451, -961, +-460, -664, -253, 41, 63, 694, 347, 958, +503, 693, 427, -7, 118, -639, -295, -843, +-592, -646, -548, -101, -202, 548, 184, 863, +465, 678, 538, 93, 300, -539, -90, -767, +-378, -584, -461, -185, -327, 366, -59, 766, +193, 693, 319, 255, 300, -311, 185, -732, +7, -736, -211, -372, -339, 135, -271, 623, +-85, 852, 108, 618, 251, 16, 281, -614, +175, -911, -36, -738, -254, -213, -314, 449, +-180, 937, 16, 939, 175, 416, 247, -355, +190, -935, 24, -991, -164, -530, -257, 196, +-192, 831, -31, 1006, 125, 612, 201, -91, +162, -707, 46, -916, -77, -627, -156, -31, +-139, 539, -55, 779, 15, 587, 53, 130, +58, -332, 35, -597, 36, -559, 60, -270, +49, 125, -29, 443, -126, 527, -160, 373, +-115, 82, -22, -261, 104, -516, 212, -534, +210, -292, 67, 126, -128, 521, -216, 654, +-166, 442, -92, 0, -3, -471, 100, -740, +145, -627, 144, -146, 108, 434, 11, 773, +-77, 707, -155, 280, -236, -310, -193, -752, +8, -793, 245, -412, 373, 196, 254, 690, +-36, 793, -279, 484, -418, -57, -370, -567, +-43, -755, 356, -514, 543, -13, 414, 461, +7, 650, -424, 482, -607, 95, -488, -315, +-96, -554, 421, -472, 744, -135, 649, 229, +152, 446, -481, 431, -840, 191, -735, -121, +-270, -366, 369, -447, 892, -281, 937, 57, +421, 345, -348, 444, -922, 323, -996, 41, +-548, -274, 192, -479, 861, -432, 1091, -114, +705, 262, -112, 473, -858, 446, -1090, 197, +-734, -148, -12, -415, 711, -491, 1045, -296, +808, 75, 127, 357, -618, 428, -970, 325, +-777, 72, -243, -223, 385, -409, 835, -392, +844, -156, 403, 149, -247, 322, -742, 344, +-809, 241, -505, 23, 4, -224, 568, -388, +864, -349, 656, -93, 91, 171, -501, 313, +-788, 373, -652, 274, -237, -24, 299, -346, +714, -497, 702, -360, 295, -5, -212, 301, +-563, 450, -603, 452, -367, 207, -7, -222, +362, -540, 572, -555, 487, -261, 148, 164, +-264, 458, -509, 538, -495, 415, -313, 54, +22, -416, 435, -666, 637, -505, 471, -85, +54, 313, -388, 549, -608, 554, -536, 277, +-247, -175, 193, -540, 595, -587, 677, -302, +379, 96, -124, 391, -550, 487, -672, 355, +-482, 88, -83, -191, 402, -403, 702, -405, +595, -192, 157, 33, -332, 207, -600, 352, +-549, 364, -276, 217, 105, -52, 458, -362, +586, -490, 397, -364, 8, -91, -362, 276, +-534, 554, -459, 522, -172, 234, 240, -193, +565, -592, 576, -657, 233, -345, -259, 135, +-585, 562, -580, 688, -268, 441, 220, -8, +614, -489, 645, -742, 289, -545, -255, -56, +-639, 417, -625, 671, -307, 575, 152, 196, +597, -257, 717, -592, 397, -622, -139, -317, +-602, 130, -730, 495, -450, 593, 38, 399, +519, 46, 772, -341, 581, -581, 30, -503, +-531, -181, -766, 215, -546, 518, -75, 542, +367, 302, 651, -53, 616, -407, 189, -559, +-345, -404, -622, -74, -540, 282, -212, 509, +175, 474, 473, 228, 568, -112, 349, -406, +-100, -504, -490, -380, -601, -91, -383, 264, +67, 496, 483, 495, 628, 268, 442, -108, +-9, -440, -512, -563, -726, -433, -487, -61, +33, 373, 503, 601, 682, 527, 510, 185, +70, -255, -424, -559, -684, -605, -563, -333, +-157, 150, 310, 529, 609, 613, 603, 381, +307, -72, -147, -449, -537, -568, -652, -448, +-425, -64, 24, 403, 452, 589, 633, 436, +484, 85, 87, -301, -358, -508, -612, -470, +-520, -209, -145, 233, 275, 556, 520, 516, +488, 214, 202, -190, -185, -511, -462, -546, +-476, -311, -219, 114, 138, 556, 369, 666, +385, 350, 213, -151, -40, -577, -253, -682, +-351, -402, -260, 90, -10, 588, 186, 809, +235, 506, 212, -133, 126, -672, -34, -826, +-192, -531, -266, 54, -191, 650, -19, 938, +120, 688, 190, 4, 203, -699, 125, -1017, +-25, -779, -165, -129, -221, 609, -155, 1083, +-6, 976, 105, 298, 128, -544, 125, -1117, +120, -1116, 25, -506, -135, 375, -200, 1085, +-133, 1271, -26, 767, 64, -163, 140, -1021, +204, -1389, 158, -1027, -51, -107, -249, 875, +-264, 1467, -136, 1316, 57, 402, 237, -742, +292, -1481, 187, -1467, -50, -695, -310, 466, +-364, 1434, -165, 1660, 105, 945, 303, -276, +342, -1306, 179, -1667, -82, -1160, -310, -23, +-376, 1118, -185, 1690, 99, 1353, 270, 248, +329, -951, 238, -1608, -25, -1442, -277, -497, +-359, 699, -250, 1495, -2, 1533, 220, 734, +334, -496, 328, -1398, 123, -1519, -209, -865, +-426, 219, -394, 1146, -129, 1477, 202, 1056, +400, 46, 417, -945, 228, -1362, -137, -1121, +-449, -350, -491, 601, -238, 1205, 150, 1208, +398, 642, 408, -267, 270, -1032, 1, -1250, +-323, -859, -482, -45, -354, 791, -18, 1215, +290, 1042, 405, 338, 355, -562, 155, -1158, +-172, -1140, -426, -543, -438, 318, -210, 1005, +136, 1171, 379, 712, 397, -119, 245, -852, +-9, -1120, -268, -793, -398, -44, -346, 686, +-110, 1010, 206, 789, 383, 146, 357, -546, +199, -895, -65, -734, -326, -176, -415, 435, +-288, 755, -5, 652, 278, 189, 365, -362, +252, -662, 53, -573, -134, -172, -235, 303, +-223, 557, -118, 496, 28, 191, 106, -229, +111, -522, 124, -500, 127, -211, 77, 180, +-18, 454, -155, 461, -247, 257, -200, -68, +-43, -391, 142, -485, 275, -309, 298, -15, +174, 280, -103, 434, -363, 360, -397, 149, +-217, -126, 68, -384, 350, -455, 472, -296, +354, -4, 8, 310, -421, 484, -615, 427, +-420, 165, 4, -243, 446, -562, 683, -544, +529, -245, 47, 171, -505, 540, -804, 623, +-601, 348, -17, -119, 561, -558, 829, -679, +640, -387, 55, 67, -570, 465, -863, 668, +-665, 484, -74, 1, 570, -441, 865, -647, +664, -517, 104, -92, -498, 339, -825, 569, +-704, 547, -176, 229, 462, -236, 798, -544, +674, -559, 240, -297, -298, 96, -716, 390, +-746, 502, -345, 412, 223, 95, 648, -286, +744, -492, 467, -458, -50, -236, -559, 71, +-812, 361, -636, 534, -63, 443, 555, 87, +847, -306, 699, -552, 197, -560, -443, -289, +-882, 160, -839, 559, -293, 685, 432, 434, +872, -64, 815, -541, 372, -756, -237, -579, +-736, -82, -859, 482, -516, 808, 106, 676, +640, 157, 801, -440, 573, -810, 111, -745, +-392, -266, -725, 352, -703, 803, -307, 811, +243, 317, 628, -331, 682, -754, 432, -795, +15, -425, -413, 183, -669, 703, -580, 850, +-175, 492, 283, -141, 567, -631, 579, -795, +328, -585, -64, -55, -419, 507, -570, 803, +-415, 679, -51, 164, 304, -430, 488, -770, +422, -728, 155, -316, -141, 254, -344, 694, +-395, 809, -262, 468, 3, -152, 246, -627, +352, -774, 300, -575, 143, -62, -76, 474, +-298, 752, -401, 668, -295, 219, -17, -325, +294, -661, 471, -707, 414, -408, 140, 121, +-230, 542, -517, 688, -541, 510, -245, 46, +227, -412, 580, -646, 605, -591, 324, -216, +-108, 254, -510, 549, -658, 589, -444, 316, +19, -123, 473, -434, 668, -553, 506, -430, +106, -36, -337, 345, -609, 498, -550, 429, +-208, 152, 228, -187, 537, -430, 531, -510, +263, -326, -67, 52, -343, 378, -459, 527, +-325, 435, -39, 110, 229, -284, 349, -586, +288, -615, 134, -285, -35, 204, -194, 595, +-245, 707, -158, 425, -17, -101, 92, -588, +132, -821, 126, -617, 123, -44, 79, 549, +-18, 854, -95, 699, -118, 161, -116, -444, +-92, -831, -8, -808, 151, -334, 255, 310, +184, 764, 4, 814, -150, 430, -217, -156, +-188, -641, -67, -824, 127, -563, 279, 10, +248, 527, 63, 746, -121, 578, -221, 108, +-208, -382, -109, -667, 43, -619, 228, -236, +317, 235, 195, 546, -10, 574, -176, 286, +-285, -126, -273, -412, -98, -525, 160, -406, +386, -54, 409, 304, 177, 478, -141, 411, +-371, 144, -422, -149, -242, -381, 87, -496, +394, -347, 498, -3, 315, 304, -35, 473, +-323, 433, -431, 174, -313, -157, -32, -458, +252, -591, 408, -411, 360, -4, 111, 409, +-168, 648, -311, 570, -290, 208, -145, -274, +67, -707, 249, -830, 300, -475, 191, 165, +26, 716, -108, 913, -184, 672, -182, 64, +-110, -663, -1, -1096, 144, -938, 239, -265, +222, 563, 120, 1109, -34, 1084, -190, 504, +-251, -370, -202, -1111, -41, -1282, 184, -765, +316, 153, 279, 992, 145, 1316, -41, 964, +-221, 127, -308, -796, -259, -1343, -81, -1197, +183, -426, 384, 548, 403, 1231, 232, 1293, +-48, 718, -336, -235, -493, -1115, -378, -1440, +6, -998, 422, -46, 611, 902, 472, 1389, +83, 1179, -352, 339, -589, -703, -512, -1377, +-138, -1322, 358, -576, 670, 452, 569, 1211, +145, 1332, -297, 770, -532, -190, -505, -1040, +-211, -1335, 242, -947, 570, -95, 552, 763, +237, 1189, -171, 1021, -432, 377, -436, -457, +-232, -1069, 86, -1135, 390, -647, 481, 121, +299, 800, -18, 1090, -273, 868, -344, 221, +-231, -558, -34, -1072, 176, -1064, 318, -563, +306, 210, 136, 903, -75, 1170, -204, 866, +-211, 119, -136, -737, -8, -1273, 140, -1172, +247, -464, 242, 491, 124, 1224, -32, 1349, +-139, 762, -190, -259, -183, -1183, -74, -1500, +127, -1009, 290, 8, 306, 1007, 181, 1487, +-11, 1175, -224, 208, -350, -874, -258, -1479, +29, -1285, 331, -413, 460, 638, 333, 1323, +40, 1300, -274, 560, -460, -464, -365, -1196, +16, -1291, 413, -713, 554, 220, 379, 971, +4, 1189, -366, 801, -519, -12, -360, -794, +53, -1123, 476, -885, 622, -218, 394, 526, +-41, 957, -420, 904, -538, 401, -363, -321, +22, -866, 439, -947, 648, -552, 487, 93, +66, 664, -355, 892, -557, 657, -467, 54, +-138, -580, 293, -879, 621, -707, 634, -192, +308, 393, -162, 750, -508, 697, -577, 261, +-357, -309, 49, -693, 460, -692, 668, -326, +556, 184, 159, 550, -303, 604, -581, 341, +-557, -106, -266, -499, 196, -605, 603, -376, +719, 36, 472, 382, -10, 498, -480, 352, +-665, 14, -489, -339, -61, -487, 404, -362, +678, -59, 620, 239, 279, 375, -184, 303, +-525, 78, -576, -183, -347, -325, 44, -299, +444, -150, 660, 57, 586, 204, 246, 206, +-211, 129, -573, 24, -640, -113, -358, -211, +136, -212, 569, -138, 751, -14, 609, 112, +159, 191, -392, 195, -701, 87, -620, -98, +-238, -241, 243, -270, 635, -178, 771, -1, +565, 181, 74, 269, -442, 209, -720, 25, +-642, -183, -253, -300, 296, -263, 752, -97, +880, 106, 556, 241, -62, 257, -621, 134, +-831, -75, -612, -249, -57, -290, 543, -193, +868, -22, 756, 155, 289, 276, -286, 249, +-668, 61, -681, -171, -337, -316, 164, -315, +580, -170, 723, 64, 536, 287, 106, 367, +-346, 230, -603, -45, -528, -298, -167, -416, +293, -343, 612, -102, 637, 199, 356, 408, +-66, 405, -422, 174, -538, -159, -351, -423, +39, -503, 410, -358, 585, -35, 483, 325, +192, 536, -139, 466, -397, 146, -478, -257, +-285, -557, 92, -629, 439, -404, 574, 63, +467, 534, 185, 721, -184, 528, -500, 72, +-539, -447, -238, -799, 228, -778, 577, -344, +631, 308, 394, 813, 14, 878, -365, 480, +-546, -165, -385, -763, 21, -1011, 394, -735, +538, -54, 421, 658, 158, 1010, -118, 812, +-301, 193, -305, -519, -116, -992, 132, -985, +296, -455, 315, 322, 222, 907, 83, 990, +-50, 560, -153, -144, -156, -788, -47, -1066, +106, -795, 218, -81, 252, 655, 182, 1010, +42, 844, -106, 245, -159, -499, -86, -1010, +77, -1005, 228, -458, 273, 347, 170, 934, +-6, 987, -139, 523, -143, -213, -31, -861, +125, -1056, 229, -666, 224, 96, 114, 781, +-15, 986, -100, 625, -97, -42, -6, -670, +107, -955, 165, -713, 175, -61, 139, 594, +58, 857, -31, 607, -75, 40, -60, -508, +37, -779, 163, -655, 233, -164, 195, 415, +69, 716, -79, 573, -152, 115, -97, -389, +87, -672, 278, -603, 326, -217, 182, 297, +-43, 643, -216, 586, -217, 171, -42, -347, +218, -661, 394, -606, 362, -231, 132, 257, +-138, 618, -299, 620, -260, 226, -28, -306, +269, -639, 430, -618, 383, -291, 168, 166, +-92, 534, -283, 608, -300, 324, -111, -144, +198, -506, 412, -603, 415, -413, 239, -33, +-5, 344, -222, 532, -302, 452, -177, 131, +106, -267, 356, -528, 419, -537, 290, -307, +60, 60, -173, 403, -279, 559, -197, 422, +47, 39, 313, -382, 437, -611, 323, -559, +57, -255, -190, 191, -275, 578, -179, 671, +54, 385, 311, -127, 440, -580, 322, -765, +36, -590, -205, -114, -252, 449, -141, 798, +51, 728, 267, 258, 403, -371, 333, -829, +106, -882, -130, -516, -243, 104, -198, 699, +-27, 967, 194, 720, 390, 68, 431, -631, +249, -1013, -67, -921, -300, -395, -314, 347, +-127, 953, 150, 1063, 417, 597, 522, -177, +360, -858, 1, -1132, -311, -862, -398, -165, +-233, 634, 72, 1114, 382, 1001, 559, 353, +493, -477, 173, -1064, -225, -1118, -453, -626, +-374, 169, -73, 882, 290, 1133, 562, 756, +604, -27, 333, -771, -106, -1108, -428, -899, +-439, -251, -188, 524, 174, 1029, 470, 958, +560, 349, 388, -427, 68, -958, -225, -1017, +-341, -573, -234, 176, 10, 843, 225, 1043, +363, 657, 406, -100, 304, -804, 71, -1091, +-147, -818, -249, -119, -208, 654, -54, 1072, +179, 885, 397, 186, 476, -623, 326, -1078, +27, -945, -244, -341, -334, 422, -229, 956, +24, 952, 332, 387, 544, -391, 485, -916, +183, -926, -161, -472, -353, 198, -326, 736, +-97, 845, 220, 471, 471, -160, 503, -687, +303, -810, -1, -503, -218, 37, -266, 525, +-170, 704, 12, 476, 232, -23, 382, -518, +383, -725, 254, -523, 79, -56, -99, 407, +-224, 644, -238, 514, -84, 75, 182, -427, +412, -706, 486, -602, 378, -178, 98, 314, +-213, 632, -381, 620, -317, 261, -48, -273, +325, -673, 579, -725, 556, -414, 283, 88, +-76, 537, -360, 719, -429, 531, -233, 47, +155, -479, 504, -774, 606, -691, 425, -279, +92, 263, -235, 673, -397, 747, -314, 435, +-12, -122, 341, -652, 541, -857, 480, -626, +238, -100, -55, 454, -277, 787, -332, 714, +-167, 257, 129, -358, 406, -803, 522, -824, +416, -432, 124, 134, -180, 622, -342, 796, +-288, 539, -45, -6, 291, -549, 522, -827, +503, -679, 246, -196, -69, 351, -268, 706, +-279, 700, -139, 323, 110, -228, 357, -687, +460, -801, 359, -489, 145, 49, -76, 518, +-218, 724, -233, 558, -95, 90, 151, -443, +388, -750, 465, -660, 327, -247, 54, 237, +-179, 572, -262, 610, -162, 333, 65, -102, +311, -477, 432, -610, 352, -441, 110, -101, +-111, 228, -191, 418, -134, 411, 12, 230, +220, -50, 368, -317, 352, -428, 179, -367, +-33, -203, -176, 28, -181, 275, -44, 413, +192, 362, 378, 127, 386, -189, 215, -441, +-24, -525, -205, -392, -208, -44, -44, 351, +195, 575, 375, 499, 382, 154, 207, -293, +-6, -618, -143, -661, -154, -372, -42, 120, +138, 549, 276, 667, 318, 408, 242, -71, +85, -497, -65, -679, -113, -532, -61, -106, +51, 372, 172, 620, 273, 513, 281, 130, +162, -304, -4, -583, -85, -592, -62, -309, +20, 144, 122, 506, 233, 581, 284, 336, +214, -95, 61, -486, -56, -650, -90, -501, +-36, -84, 69, 386, 194, 647, 281, 552, +279, 138, 165, -368, 12, -685, -101, -667, +-111, -313, -34, 215, 89, 626, 213, 681, +306, 359, 309, -159, 213, -579, 39, -705, +-132, -497, -210, -49, -145, 409, 31, 626, +274, 512, 464, 138, 478, -298, 272, -583, +-57, -593, -330, -339, -357, 68, -149, 427, +158, 563, 432, 410, 572, 41, 473, -364, +166, -601, -186, -562, -375, -247, -337, 197, +-120, 541, 191, 598, 503, 329, 641, -141, +498, -560, 111, -713, -309, -501, -525, -19, +-410, 479, -36, 722, 429, 579, 741, 95, +706, -479, 306, -822, -226, -737, -575, -272, +-531, 346, -152, 792, 333, 819, 674, 388, +713, -295, 423, -858, -36, -971, -420, -576, +-510, 113, -282, 745, 115, 985, 471, 685, +640, 3, 534, -707, 211, -1057, -172, -840, +-408, -196, -381, 509, -116, 926, 232, 853, +509, 322, 568, -391, 392, -902, 83, -933, +-204, -468, -356, 198, -281, 705, -28, 834, +260, 533, 456, -67, 494, -641, 334, -863, +61, -618, -183, -64, -291, 475, -241, 723, +-34, 582, 244, 121, 452, -420, 472, -739, +325, -645, 81, -205, -162, 314, -313, 622, +-285, 581, -63, 220, 266, -274, 507, -633, +536, -652, 347, -323, 44, 169, -258, 537, +-408, 600, -302, 342, 30, -105, 388, -528, +586, -691, 528, -482, 256, -11, -97, 440, +-345, 640, -393, 501, -209, 81, 143, -423, +493, -725, 627, -633, 476, -191, 124, 333, +-231, 654, -439, 613, -399, 231, -89, -300, +361, -672, 657, -679, 615, -321, 285, 192, +-121, 558, -399, 593, -424, 317, -196, -118, +195, -491, 530, -623, 610, -447, 396, -50, +49, 342, -236, 511, -334, 436, -252, 174, +-23, -190, 272, -505, 490, -599, 488, -411, +280, -16, -6, 377, -223, 595, -293, 553, +-199, 219, 29, -287, 318, -694, 490, -789, +431, -493, 194, 84, -59, 638, -229, 878, +-256, 676, -130, 90, 108, -601, 342, -1030, +448, -948, 359, -359, 153, 440, -66, 1002, +-216, 1049, -242, 551, -103, -274, 134, -998, +355, -1215, 433, -813, 336, 13, 125, 823, +-81, 1193, -211, 946, -212, 203, -78, -672, +137, -1209, 321, -1137, 395, -498, 339, 393, +186, 1075, -37, 1188, -237, 684, -300, -180, +-155, -972, 126, -1293, 407, -950, 539, -110, +445, 783, 139, 1254, -226, 1058, -439, 297, +-368, -633, -48, -1261, 358, -1233, 612, -539, +583, 434, 294, 1145, -111, 1232, -428, 649, +-469, -286, -218, -1074, 192, -1296, 544, -825, +662, 79, 482, 900, 95, 1212, -321, 866, +-544, 55, -447, -767, -56, -1174, 436, -986, +759, -283, 715, 544, 340, 1029, -189, 953, +-615, 389, -683, -370, -309, -920, 296, -1003, +796, -583, 903, 137, 557, 746, -48, 920, +-578, 621, -776, 3, -517, -619, 90, -912, +711, -730, 955, -184, 717, 437, 167, 778, +-414, 681, -755, 233, -661, -321, -163, -690, +482, -682, 897, -336, 854, 147, 406, 504, +-186, 552, -641, 301, -719, -73, -388, -379, +191, -474, 724, -342, 906, -72, 615, 193, +65, 323, -442, 266, -675, 93, -543, -101, +-99, -242, 449, -277, 818, -187, 766, -30, +348, 115, -168, 185, -533, 158, -622, 55, +-378, -64, 109, -162, 612, -198, 834, -153, +629, -48, 151, 58, -319, 129, -606, 139, +-580, 90, -209, -2, 330, -126, 730, -228, +778, -226, 453, -114, -38, 50, -447, 194, +-589, 255, -422, 183, -13, -13, 451, -258, +729, -398, 642, -327, 273, -76, -151, 216, +-444, 398, -505, 369, -284, 131, 122, -225, +509, -501, 648, -509, 481, -235, 142, 153, +-183, 452, -391, 503, -400, 288, -177, -92, +185, -463, 480, -608, 550, -418, 390, -12, +108, 377, -200, 554, -397, 448, -363, 108, +-88, -317, 276, -607, 524, -574, 520, -240, +292, 199, -31, 516, -294, 562, -385, 322, +-245, -97, 76, -498, 396, -653, 506, -460, +386, -39, 147, 374, -106, 577, -302, 491, +-323, 157, -131, -285, 179, -603, 410, -604, +451, -288, 313, 151, 71, 489, -190, 575, +-333, 376, -260, -39, 9, -470, 304, -659, +448, -487, 371, -70, 152, 359, -94, 580, +-248, 493, -230, 143, -42, -309, 192, -623, +332, -584, 301, -220, 153, 237, -7, 530, +-96, 519, -104, 224, -31, -195, 87, -536, +174, -594, 180, -301, 139, 160, 77, 493, +20, 531, -18, 279, -27, -121, -4, -480, +65, -608, 141, -402, 180, 44, 156, 453, +79, 594, -28, 412, -97, 15, -78, -411, +39, -658, 181, -586, 267, -194, 237, 318, +106, 658, -64, 634, -172, 282, -163, -225, +-23, -652, 170, -780, 311, -504, 328, 50, +217, 594, 6, 814, -191, 600, -278, 80, +-205, -496, 32, -863, 316, -798, 465, -304, +412, 357, 167, 826, -166, 853, -400, 432, +-384, -214, -123, -777, 267, -965, 544, -654, +547, 15, 287, 667, -86, 946, -376, 718, +-426, 124, -235, -537, 115, -938, 449, -865, +563, -339, 400, 354, 82, 830, -240, 843, +-411, 434, -345, -170, -69, -691, 289, -876, +544, -619, 521, -66, 239, 492, -131, 774, +-384, 664, -407, 242, -187, -288, 167, -696, +476, -774, 548, -477, 350, 46, 0, 529, +-304, 736, -405, 579, -266, 149, 13, -361, +323, -717, 511, -733, 449, -385, 168, 138, +-152, 573, -347, 717, -333, 524, -137, 74, +151, -438, 390, -755, 452, -708, 300, -324, +40, 217, -191, 656, -291, 784, -233, 523, +-46, -32, 167, -609, 316, -893, 348, -738, +258, -199, 69, 466, -129, 900, -253, 857, +-251, 355, -103, -367, 141, -922, 339, -997, +407, -550, 314, 183, 75, 817, -205, 1007, +-353, 658, -294, -41, -52, -723, 234, -1030, +425, -798, 438, -172, 266, 513, -33, 914, +-302, 847, -401, 351, -253, -319, 58, -826, +338, -919, 458, -559, 407, 70, 174, 642, +-148, 889, -368, 692, -353, 138, -135, -498, +153, -888, 364, -844, 439, -370, 340, 297, +94, 799, -183, 885, -349, 529, -318, -112, +-96, -718, 181, -972, 398, -729, 479, -113, +353, 554, 43, 931, -280, 841, -442, 310, +-335, -401, -13, -924, 334, -981, 531, -536, +501, 184, 227, 794, -158, 1001, -431, 691, +-438, 13, -186, -670, 185, -1015, 460, -858, +518, -255, 348, 465, 29, 921, -280, 905, +-401, 434, -289, -264, -16, -826, 273, -981, +429, -646, 385, 16, 204, 642, -27, 924, +-223, 756, -292, 192, -199, -484, -15, -905, +187, -878, 332, -416, 354, 256, 242, 774, +48, 886, -171, 548, -302, -81, -269, -668, +-79, -906, 164, -696, 348, -136, 387, 480, +279, 827, 53, 744, -194, 286, -330, -321, +-294, -756, -123, -805, 134, -453, 369, 120, +455, 614, 342, 771, 77, 534, -237, 22, +-436, -500, -404, -751, -138, -612, 238, -178, +531, 327, 567, 643, 320, 610, -87, 261, +-434, -206, -543, -550, -346, -602, 48, -352, +448, 57, 643, 409, 521, 522, 135, 355, +-297, 23, -557, -303, -516, -467, -184, -392, +287, -122, 643, 181, 678, 366, 349, 350, +-145, 153, -511, -117, -575, -323, -327, -376, +118, -227, 528, 39, 671, 259, 461, 334, +34, 246, -356, 13, -508, -233, -386, -350, +-56, -299, 320, -95, 552, 170, 502, 316, +199, 282, -166, 122, -378, -100, -358, -279, +-144, -314, 149, -207, 375, -5, 415, 193, +247, 273, -34, 225, -230, 104, -241, -89, +-111, -272, 64, -319, 204, -215, 249, -20, +195, 199, 45, 323, -99, 293, -123, 119, +-48, -159, 41, -400, 117, -423, 142, -224, +108, 92, 34, 387, -63, 490, -98, 328, +-12, -22, 103, -411, 146, -616, 116, -474, +41, -60, -47, 384, -98, 641, -78, 564, +24, 166, 137, -355, 168, -710, 104, -688, +18, -281, -51, 286, -83, 690, -77, 722, +-30, 380, 45, -185, 130, -681, 172, -809, +138, -496, 50, 75, -51, 609, -152, 812, +-178, 568, -63, 19, 123, -554, 263, -853, +283, -692, 155, -148, -55, 471, -230, 835, +-272, 751, -150, 261, 91, -368, 300, -814, +363, -844, 242, -429, 11, 212, -200, 720, +-293, 848, -232, 555, -23, -15, 232, -588, +381, -865, 345, -715, 150, -217, -101, 387, +-285, 791, -317, 796, -161, 425, 120, -161, +360, -691, 420, -874, 273, -622, 11, -83, +-214, 498, -315, 829, -245, 738, -12, 297, +251, -288, 372, -751, 322, -836, 136, -506, +-84, 53, -215, 573, -212, 806, -100, 640, +81, 164, 218, -403, 237, -770, 164, -748, +47, -351, -50, 218, -84, 666, -86, 768, +-51, 489, 27, -50, 91, -579, 119, -803, +134, -609, 106, -108, 42, 456, -35, 775, +-102, 686, -122, 250, -42, -335, 84, -765, +169, -781, 164, -400, 96, 180, -8, 668, +-107, 801, -125, 525, -53, -1, 48, -537, +118, -807, 121, -666, 59, -216, 3, 320, +-23, 691, -45, 716, -40, 416, 3, -58, +49, -513, 65, -738, 50, -615, 14, -218, +-13, 262, -26, 618, -9, 703, 40, 474, +83, 20, 59, -457, -7, -735, -72, -680, +-80, -304, 4, 211, 123, 638, 166, 792, +105, 570, -4, 38, -112, -533, -162, -863, +-81, -778, 98, -290, 232, 360, 226, 837, +101, 908, -65, 499, -170, -199, -171, -805, +-64, -991, 107, -656, 247, 26, 253, 681, +139, 982, -32, 772, -163, 141, -181, -567, +-97, -955, 47, -837, 209, -292, 289, 383, +207, 840, 26, 855, -122, 422, -168, -226, +-127, -727, -25, -830, 115, -502, 221, 57, +225, 544, 126, 733, 3, 553, -94, 93, +-140, -381, -122, -626, -19, -547, 116, -206, +204, 191, 207, 441, 121, 484, -32, 316, +-132, -9, -124, -304, -72, -417, 12, -360, +127, -162, 184, 96, 134, 293, 38, 372, +-46, 296, -88, 63, -89, -187, -62, -338, +15, -362, 110, -235, 139, 11, 89, 253, +20, 396, -49, 353, -85, 116, -75, -169, +-35, -368, 23, -425, 102, -283, 119, 14, +54, 308, -6, 457, -39, 380, -80, 99, +-98, -217, -48, -426, 41, -462, 119, -269, +132, 89, 76, 403, 5, 503, -73, 351, +-145, 22, -137, -325, -26, -514, 100, -456, +185, -159, 182, 240, 96, 507, -25, 480, +-129, 210, -193, -145, -156, -420, -13, -487, +152, -299, 244, 40, 229, 342, 130, 440, +-18, 297, -166, 27, -249, -214, -180, -348, +15, -336, 203, -165, 287, 89, 269, 283, +156, 319, -45, 212, -225, 43, -276, -140, +-166, -286, 42, -316, 239, -183, 309, 44, +270, 229, 144, 292, -63, 250, -243, 121, +-257, -79, -128, -274, 57, -355, 222, -267, +294, -40, 264, 188, 122, 326, -94, 356, +-245, 224, -221, -63, -87, -334, 74, -428, +210, -304, 258, -26, 194, 238, 37, 364, +-126, 341, -195, 144, -130, -148, -21, -326, +73, -296, 142, -142, 164, 39, 98, 163, +-2, 189, -75, 142, -109, 59, -95, -41, +-47, -94, 17, -85, 94, -78, 159, -97, +127, -81, 3, 6, -133, 117, -194, 183, +-132, 175, 3, 91, 132, -55, 205, -224, +148, -315, -49, -235, -205, 0, -204, 252, +-79, 388, 76, 347, 167, 129, 139, -207, +46, -488, -64, -525, -140, -262, -115, 171, +-25, 539, 50, 635, 75, 402, 59, -62, +30, -543, 16, -761, -17, -549, -62, -28, +-64, 512, -23, 783, 30, 638, 73, 167, +89, -384, 64, -760, -2, -742, -81, -310, +-79, 260, -3, 662, 75, 737, 110, 440, +97, -68, 26, -522, -46, -729, -63, -561, +-29, -78, 26, 395, 76, 624, 109, 561, +98, 228, 49, -221, -2, -526, -36, -559, +-69, -315, -64, 82, 25, 392, 136, 466, +185, 338, 144, 73, 48, -222, -82, -406, +-166, -389, -133, -185, 11, 94, 155, 299, +209, 367, 149, 292, 29, 89, -78, -186, +-118, -393, -74, -400, -5, -208, 51, 67, +85, 310, 89, 424, 66, 350, 48, 109, +4, -204, -82, -441, -136, -453, -117, -247, +-14, 53, 121, 337, 188, 498, 137, 434, +22, 172, -136, -202, -236, -522, -184, -580, +-36, -354, 109, 14, 211, 415, 202, 663, +82, 569, -65, 173, -216, -328, -282, -700, +-191, -708, -7, -345, 184, 172, 302, 619, +232, 781, 26, 528, -172, 5, -308, -523, +-300, -798, -128, -659, 84, -187, 217, 354, +257, 732, 195, 760, 69, 400, -96, -171, +-266, -662, -345, -823, -265, -560, -35, -25, +255, 514, 454, 818, 420, 720, 151, 239, +-239, -363, -522, -777, -512, -805, -202, -427, +220, 166, 516, 667, 534, 841, 285, 597, +-78, 33, -377, -548, -465, -833, -335, -695, +-53, -214, 256, 369, 464, 763, 467, 765, +271, 375, -66, -209, -399, -665, -526, -758, +-358, -478, 27, 9, 426, 483, 614, 718, +453, 590, 57, 169, -340, -315, -527, -614, +-409, -618, -61, -366, 296, 56, 466, 481, +401, 676, 155, 539, -126, 145, -327, -326, +-365, -632, -230, -642, 23, -373, 247, 98, +365, 571, 336, 746, 127, 534, -175, 62, +-386, -434, -396, -699, -211, -633, 93, -294, +342, 223, 415, 657, 273, 716, -10, 412, +-296, -54, -437, -478, -375, -659, -147, -536, +154, -185, 385, 285, 447, 614, 279, 576, +-65, 276, -433, -97, -605, -413, -463, -521, +-61, -387, 381, -105, 629, 244, 529, 461, +104, 390, -399, 162, -690, -66, -613, -269, +-224, -358, 271, -272, 597, -64, 594, 171, +277, 305, -167, 256, -523, 110, -640, -42, +-434, -191, 0, -275, 423, -209, 616, -24, +511, 162, 138, 244, -329, 205, -657, 90, +-629, -56, -242, -195, 272, -257, 638, -183, +674, -6, 336, 151, -199, 224, -599, 221, +-668, 132, -361, -36, 155, -204, 566, -296, +651, -246, 401, -61, -49, 142, -438, 268, +-559, 310, -403, 208, -27, -33, 372, -251, +539, -334, 415, -270, 128, -66, -214, 152, +-429, 278, -403, 313, -180, 202, 134, -48, +373, -241, 397, -286, 240, -238, 10, -80, +-228, 136, -344, 268, -291, 283, -111, 158, +121, -82, 307, -252, 333, -259, 202, -174, +0, -10, -217, 185, -361, 273, -334, 208, +-107, 34, 171, -166, 344, -248, 337, -189, +162, -76, -122, 71, -358, 215, -402, 235, +-224, 119, 63, -49, 268, -182, 299, -203, +166, -127, -49, -27, -236, 86, -291, 177, +-216, 175, -67, 89, 90, -15, 169, -91, +144, -128, 68, -154, -23, -149, -153, -58, +-246, 106, -226, 245, -93, 273, 85, 170, +227, -25, 235, -254, 107, -404, -113, -342, +-333, -65, -366, 274, -167, 480, 115, 427, +317, 144, 334, -204, 126, -457, -147, -499, +-321, -276, -338, 105, -171, 427, 92, 516, +258, 343, 258, 12, 145, -307, -32, -467, +-155, -403, -207, -144, -198, 195, -94, 429, +76, 425, 179, 209, 211, -87, 186, -336, +65, -422, -108, -299, -238, -35, -247, 252, +-123, 422, 74, 366, 231, 128, 290, -163, +215, -389, 33, -430, -176, -244, -305, 65, +-264, 366, -83, 485, 132, 332, 295, 22, +326, -289, 183, -481, -46, -419, -287, -133, +-397, 201, -263, 445, 23, 471, 280, 243, +404, -81, 314, -359, 26, -494, -296, -358, +-477, -19, -376, 307, -37, 480, 292, 403, +421, 99, 329, -238, 39, -443, -293, -426, +-449, -156, -364, 201, -87, 414, 216, 385, +343, 149, 246, -138, 46, -311, -157, -331, +-291, -185, -305, 64, -181, 241, 18, 261, +168, 164, 200, 17, 138, -109, 33, -185, +-121, -204, -261, -127, -285, 25, -156, 150, +27, 205, 164, 177, 194, 69, 116, -66, +-32, -200, -186, -260, -249, -143, -195, 69, +-48, 226, 92, 264, 151, 148, 115, -62, +34, -225, -60, -282, -141, -177, -182, 102, +-134, 320, -15, 297, 88, 107, 122, -149, +108, -328, 61, -290, -68, -91, -186, 155, +-183, 354, -71, 324, 69, 58, 178, -203, +184, -320, 73, -268, -80, -64, -201, 143, +-208, 263, -85, 273, 102, 118, 226, -116, +208, -242, 62, -233, -93, -131, -195, 32, +-213, 178, -92, 241, 112, 195, 239, 25, +199, -172, 44, -253, -116, -201, -188, -70, +-166, 97, -55, 237, 84, 281, 141, 175, +101, -45, 26, -243, -43, -318, -69, -257, +-42, -64, -56, 196, -84, 389, -60, 390, +11, 151, 69, -194, 85, -415, 43, -418, +-32, -205, -117, 139, -179, 409, -120, 441, +13, 238, 94, -95, 91, -356, 32, -378, +-56, -214, -100, -2, -117, 209, -114, 308, +-63, 223, 6, 49, 48, -114, 54, -199, +29, -166, -33, -79, -104, 14, -187, 119, +-187, 159, -67, 76, 96, -41, 178, -107, +133, -98, -5, -15, -157, 64, -256, 85, +-251, 74, -103, 1, 74, -120, 169, -149, +160, -59, 71, 40, -45, 123, -126, 167, +-186, 129, -191, 52, -116, -64, -21, -217, +73, -270, 151, -169, 161, -2, 88, 187, +-42, 353, -193, 356, -262, 168, -210, -111, +-68, -381, 98, -475, 228, -305, 260, 0, +174, 309, -3, 508, -236, 461, -367, 172, +-301, -218, -96, -535, 167, -584, 379, -316, +408, 90, 193, 469, -150, 677, -412, 531, +-431, 79, -219, -410, 68, -712, 282, -668, +358, -271, 246, 253, 46, 665, -143, 788, +-285, 512, -300, -30, -202, -557, -61, -858, +122, -749, 308, -238, 324, 399, 159, 880, +-96, 975, -312, 570, -373, -157, -250, -832, +-55, -1123, 130, -856, 258, -143, 256, 649, +153, 1139, -14, 1079, -203, 470, -345, -364, +-368, -1024, -247, -1196, 37, -770, 342, 30, +462, 812, 288, 1226, -93, 1046, -446, 342, +-569, -531, -426, -1163, -76, -1234, 315, -672, +495, 210, 382, 976, 70, 1274, -261, 945, +-482, 177, -518, -649, -344, -1172, 8, -1129, +366, -552, 513, 266, 404, 964, 42, 1211, +-404, 867, -623, 141, -552, -636, -240, -1164, +228, -1134, 544, -547, 519, 263, 259, 972, +-125, 1243, -465, 904, -579, 173, -471, -609, +-185, -1138, 242, -1144, 540, -628, 537, 147, +312, 874, -94, 1238, -527, 1025, -697, 360, +-521, -468, -114, -1141, 374, -1318, 656, -852, +581, 48, 231, 952, -206, 1407, -564, 1191, +-676, 420, -468, -550, -41, -1285, 432, -1424, +679, -888, 546, 83, 138, 1010, -304, 1433, +-615, 1204, -605, 435, -266, -556, 154, -1271, +421, -1379, 462, -836, 255, 122, -37, 1001, +-243, 1353, -358, 1087, -350, 350, -170, -569, +75, -1204, 218, -1234, 276, -715, 196, 131, +-16, 910, -213, 1224, -315, 1000, -263, 354, +-49, -487, 150, -1092, 170, -1147, 86, -679, +-26, 79, -159, 791, -186, 1108, -90, 920, +-17, 335, 38, -394, 68, -921, -3, -1019, +-73, -683, -85, -67, -129, 579, -151, 985, +-78, 975, 24, 562, 115, -118, 140, -789, +6, -1118, -178, -940, -258, -344, -252, 422, +-159, 1037, 75, 1170, 249, 728, 223, -10, +53, -727, -166, -1119, -330, -975, -324, -395, +-199, 339, -30, 912, 197, 1047, 331, 719, +241, 107, 1, -559, -244, -990, -445, -937, +-461, -480, -187, 149, 193, 731, 438, 987, +453, 796, 166, 303, -261, -323, -542, -846, +-547, -979, -272, -666, 147, -81, 444, 572, +445, 994, 260, 957, -89, 500, -422, -209, +-480, -879, -357, -1134, -139, -825, 218, -111, +444, 665, 380, 1145, 169, 1064, -159, 456, +-470, -348, -497, -976, -276, -1103, 36, -662, +345, 28, 437, 628, 233, 925, -43, 778, +-242, 262, -339, -292, -274, -641, -132, -692, +-11, -418, 118, -6, 216, 326, 194, 533, +77, 499, -64, 222, -229, -52, -347, -243, +-276, -391, -72, -375, 123, -225, 237, -48, +222, 209, 81, 427, -78, 424, -225, 298, +-328, 53, -262, -313, -109, -542, 50, -491, +194, -232, 240, 183, 81, 538, -136, 567, +-255, 349, -287, 22, -171, -375, 48, -577, +102, -463, 41, -176, -13, 188, -99, 469, +-126, 501, -63, 328, -29, 53, -65, -246, +-70, -423, -91, -380, -75, -198, 15, 36, +19, 226, -86, 285, -132, 246, -117, 159, +-39, 34, 86, -92, 81, -190, -42, -256, +-151, -256, -214, -119, -196, 104, -48, 294, +95, 382, 106, 325, 41, 79, -41, -248, +-132, -445, -112, -444, -51, -267, -71, 74, +-88, 380, -44, 519, -26, 488, -35, 226, +-5, -189, 16, -507, -8, -610, -22, -474, +-45, -116, -98, 312, -124, 609, -104, 711, +-75, 509, 29, 15, 136, -485, 97, -800, +-5, -817, -152, -417, -287, 215, -240, 750, +-55, 994, 81, 811, 177, 193, 194, -510, +26, -939, -126, -976, -185, -601, -271, 71, +-201, 705, -11, 1011, 57, 888, 112, 381, +141, -303, 8, -817, -158, -989, -202, -768, +-206, -166, -117, 540, 39, 984, 132, 1017, +120, 605, 28, -120, -165, -795, -318, -1092, +-263, -953, -98, -358, 71, 465, 214, 1028, +220, 1143, 13, 805, -236, 33, -373, -759, +-374, -1152, -191, -1078, 100, -528, 265, 342, +289, 1024, 166, 1214, -121, 921, -379, 186, +-462, -651, -404, -1133, -173, -1162, 170, -717, +346, 105, 343, 882, 190, 1248, -148, 1126, +-447, 516, -495, -348, -362, -1028, -116, -1286, +178, -1034, 298, -293, 218, 599, 125, 1228, +-76, 1321, -299, 845, -370, -4, -357, -871, +-242, -1354, 29, -1247, 256, -579, 332, 411, +253, 1223, -45, 1484, -388, 1102, -463, 200, +-320, -853, -127, -1517, 111, -1507, 237, -837, +151, 317, 21, 1388, -36, 1756, -86, 1353, +-149, 329, -253, -936, -307, -1732, -211, -1682, +-2, -906, 204, 333, 303, 1442, 231, 1815, +-48, 1391, -310, 359, -385, -901, -327, -1690, +-206, -1703, -6, -1012, 171, 203, 247, 1370, +238, 1850, 138, 1510, -126, 520, -419, -732, +-545, -1619, -425, -1764, -97, -1188, 313, -30, +507, 1171, 381, 1781, 83, 1612, -334, 755, +-600, -466, -547, -1488, -324, -1842, -4, -1352, +323, -236, 473, 1015, 394, 1815, 126, 1769, +-298, 906, -663, -349, -708, -1463, -472, -1924, +11, -1477, 529, -364, 681, 898, 447, 1768, +-12, 1777, -531, 1001, -789, -125, -668, -1230, +-343, -1804, 102, -1473, 498, -518, 643, 609, +473, 1501, 65, 1662, -475, 1044, -898, 69, +-909, -997, -480, -1632, 155, -1373, 753, -538, +933, 469, 555, 1360, -156, 1580, -810, 993, +-1097, 9, -868, -987, -232, -1559, 434, -1287, +853, -391, 848, 635, 370, 1409, -323, 1487, +-850, 798, -1038, -236, -786, -1212, -156, -1624, +503, -1146, 875, -94, 837, 974, 341, 1643, +-382, 1508, -942, 566, -1078, -623, -739, -1500, +-96, -1712, 572, -1083, 920, 98, 844, 1232, +311, 1763, -407, 1490, -924, 554, -1089, -644, +-805, -1577, -132, -1801, 564, -1169, 989, 32, +917, 1210, 347, 1842, -414, 1607, -1008, 621, +-1200, -621, -821, -1543, -18, -1760, 698, -1184, +983, -49, 805, 1082, 225, 1644, -503, 1471, +-968, 673, -1004, -389, -615, -1229, 19, -1499, +571, -1090, 788, -193, 575, 701, 69, 1175, +-456, 1129, -763, 652, -718, -53, -349, -640, +152, -882, 445, -727, 398, -325, 144, 87, +-220, 381, -479, 506, -473, 428, -210, 236, +123, 63, 346, -45, 285, -127, -17, -192, +-382, -268, -592, -306, -511, -265, -213, -147, +173, 101, 543, 362, 574, 480, 206, 513, +-293, 376, -682, 18, -831, -345, -657, -566, +-150, -673, 419, -573, 721, -223, 602, 242, +204, 697, -288, 961, -713, 827, -845, 364, +-606, -272, -134, -842, 365, -1053, 620, -850, +499, -378, 119, 249, -363, 812, -678, 1057, +-641, 906, -351, 416, 56, -242, 432, -781, +480, -1027, 194, -841, -216, -254, -513, 428, +-595, 885, -428, 898, -95, 460, 291, -144, +518, -650, 375, -836, -20, -561, -394, 53, +-606, 655, -553, 941, -264, 712, 87, 46, +322, -661, 345, -1104, 138, -1086, -132, -438, +-312, 523, -385, 1284, -267, 1476, -82, 930, +33, -46, 77, -932, 5, -1511, -147, -1468, +-217, -631, -158, 464, -51, 1236, 72, 1490, +105, 1044, -58, 140, -220, -705, -261, -1213, +-226, -1100, -73, -357, 38, 462, 28, 941, +-52, 916, -145, 331, -197, -429, -139, -888, +-61, -964, 3, -497, 14, 422, -39, 1160, +-116, 1335, -144, 887, -141, -85, -176, -1029, +-170, -1552, -100, -1482, -19, -646, 64, 593, +41, 1499, -121, 1754, -268, 1259, -310, 123, +-221, -1049, -63, -1693, 118, -1613, 228, -723, +200, 574, 35, 1585, -175, 1864, -342, 1230, +-522, -80, -631, -1372, -500, -2052, -131, -1790, +344, -625, 746, 885, 770, 2035, 363, 2323, +-212, 1503, -734, 9, -1022, -1412, -924, -2261, +-521, -2168, 53, -1103, 523, 427, 773, 1794, +732, 2347, 302, 1763, -330, 402, -821, -1037, +-981, -1973, -745, -1947, -169, -971, 447, 388, +722, 1556, 620, 2026, 233, 1433, -344, 151, +-806, -1113, -925, -1865, -671, -1789, -166, -866, +377, 462, 750, 1583, 771, 1967, 350, 1427, +-299, 247, -831, -961, -981, -1633, -722, -1492, +-183, -700, 439, 346, 725, 1149, 551, 1328, +78, 845, -494, -29, -865, -859, -766, -1210, +-270, -952, 321, -218, 713, 714, 736, 1395, +262, 1373, -454, 691, -1034, -308, -1153, -1300, +-690, -1780, 79, -1402, 761, -420, 1099, 745, +869, 1643, 73, 1857, -778, 1276, -1246, 171, +-1240, -999, -713, -1728, 147, -1700, 863, -967, +1120, 181, 893, 1300, 281, 1793, -525, 1438, +-1199, 518, -1407, -599, -992, -1536, -226, -1791, +517, -1201, 1043, -115, 1067, 1027, 573, 1810, +-95, 1817, -700, 1060, -1108, -85, -1053, -1234, +-548, -1973, 58, -1858, 488, -936, 698, 324, +544, 1419, 78, 1874, -372, 1536, -628, 684, +-671, -391, -412, -1254, -32, -1503, 244, -1122, +391, -325, 394, 538, 156, 1044, -269, 1051, +-650, 653, -801, -20, -584, -676, -145, -918, +276, -728, 593, -253, 668, 372, 377, 877, +-131, 1015, -590, 707, -864, 43, -884, -651, +-555, -1129, -38, -1228, 456, -780, 816, 67, +832, 887, 387, 1423, -334, 1411, -928, 766, +-1180, -144, -979, -971, -389, -1469, 357, -1334, +924, -620, 1025, 312, 641, 1063, -27, 1293, +-768, 930, -1165, 254, -1027, -473, -562, -960, +40, -885, 635, -333, 891, 299, 631, 715, +65, 661, -507, 236, -882, -264, -883, -664, +-454, -695, 158, -259, 604, 305, 650, 757, +347, 900, -160, 511, -671, -195, -867, -764, +-650, -1009, -182, -790, 287, -154, 549, 574, +551, 1098, 271, 1141, -175, 564, -530, -245, +-710, -898, -678, -1244, -362, -1060, 157, -348, +519, 491, 602, 1178, 393, 1430, -146, 1023, +-749, 177, -965, -739, -731, -1383, -149, -1393, +556, -841, 907, 16, 721, 902, 233, 1382, +-444, 1219, -1045, 593, -1228, -217, -922, -875, +-202, -1113, 663, -899, 1234, -341, 1181, 368, +560, 831, -423, 861, -1342, 541, -1616, 12, +-1123, -441, -180, -599, 801, -532, 1322, -248, +1135, 133, 403, 364, -514, 426, -1214, 346, +-1400, 71, -944, -163, -62, -208, 818, -162, +1248, -20, 990, 133, 197, 89, -757, -77, +-1460, -257, -1427, -391, -746, -284, 209, 121, +1115, 547, 1501, 843, 1070, 869, 79, 397, +-945, -363, -1592, -968, -1591, -1306, -884, -1201, +136, -525, 1019, 454, 1413, 1315, 1099, 1725, +288, 1454, -601, 569, -1205, -564, -1308, -1468, +-846, -1802, -69, -1425, 610, -496, 937, 608, +760, 1424, 115, 1647, -570, 1256, -906, 415, +-852, -579, -407, -1274, 253, -1415, 694, -1025, +699, -247, 329, 622, -279, 1168, -800, 1203, +-956, 758, -704, 82, -204, -536, 393, -944, +805, -1010, 809, -665, 433, -83, -154, 498, +-747, 860, -1086, 900, -1035, 622, -577, 130, +124, -399, 737, -754, 1022, -805, 903, -561, +385, -136, -341, 327, -919, 650, -1153, 764, +-1066, 614, -674, 188, -44, -336, 590, -743, +1026, -888, 1024, -611, 583, -2, -25, 637, +-592, 1054, -938, 1049, -961, 512, -737, -310, +-430, -1023, -24, -1388, 389, -1229, 586, -424, +638, 668, 599, 1463, 264, 1709, -226, 1334, +-618, 352, -824, -788, -824, -1616, -576, -1879, +-224, -1417, 145, -395, 493, 702, 645, 1537, +539, 1860, 271, 1508, -106, 646, -459, -362, +-681, -1264, -745, -1706, -563, -1519, -152, -896, +252, -17, 426, 889, 398, 1452, 221, 1529, +-82, 1087, -356, 268, -419, -559, -256, -1159, +24, -1380, 200, -1033, 134, -291, -93, 462, +-352, 980, -529, 1070, -503, 679, -245, 72, +66, -488, 386, -829, 613, -748, 530, -241, +194, 392, -171, 861, -523, 897, -759, 418, +-778, -303, -569, -925, -223, -1212, 129, -926, +343, -148, 468, 718, 542, 1270, 480, 1330, +297, 891, -6, 106, -444, -684, -851, -1184, +-1027, -1273, -936, -843, -515, -110, 162, 519, +709, 894, 951, 936, 944, 581, 583, 130, +-51, -149, -680, -337, -1115, -418, -1193, -290, +-758, -181, -5, -191, 627, -128, 960, 32, +844, 208, 267, 369, -418, 384, -897, 263, +-1026, 82, -697, -207, -67, -475, 581, -518, +958, -353, 918, 22, 438, 495, -324, 778, +-1046, 733, -1373, 397, -1092, -187, -368, -799, +396, -1109, 1006, -995, 1213, -504, 826, 285, +83, 1022, -673, 1370, -1138, 1263, -1126, 694, +-623, -179, 106, -983, 693, -1431, 913, -1348, +629, -763, -54, 42, -775, 749, -1158, 1161, +-933, 1159, -234, 781, 557, 210, 1128, -360, +1207, -747, 653, -810, -350, -655, -1274, -396, +-1662, -21, -1323, 331, -406, 534, 629, 647, +1330, 589, 1500, 330, 984, -11, -70, -443, +-1084, -859, -1556, -947, -1397, -599, -669, 80, +318, 824, 1106, 1287, 1360, 1246, 981, 673, +116, -287, -808, -1197, -1334, -1614, -1311, -1443, +-788, -713, 16, 450, 736, 1469, 1096, 1835, +995, 1515, 461, 634, -208, -515, -688, -1455, +-882, -1810, -835, -1408, -531, -422, -60, 696, +317, 1456, 480, 1549, 424, 1013, 197, 75, +-40, -948, -232, -1510, -346, -1274, -234, -433, +-2, 620, 159, 1441, 177, 1545, 70, 872, +-193, -172, -478, -1194, -592, -1794, -549, -1547, +-293, -561, 225, 652, 731, 1604, 954, 1878, +775, 1362, 279, 349, -368, -785, -994, -1551, +-1314, -1598, -1152, -1019, -592, -132, 133, 710, +874, 1130, 1348, 987, 1213, 505, 573, -1, +-237, -390, -1009, -510, -1420, -288, -1214, 53, +-531, 250, 280, 197, 914, -134, 1096, -521, +740, -617, 92, -337, -581, 158, -1033, 705, +-1001, 1040, -502, 860, 171, 239, 776, -458, +1029, -986, 756, -1083, 89, -632, -649, 46, +-1238, 563, -1378, 809, -866, 751, 27, 373, +881, -163, 1437, -539, 1429, -589, 801, -352, +-157, 25, -1127, 349, -1786, 483, -1761, 360, +-1051, 12, -39, -331, 961, -498, 1661, -467, +1782, -186, 1240, 252, 234, 592, -886, 700, +-1709, 556, -1936, 167, -1536, -397, -642, -887, +427, -1028, 1304, -732, 1733, -92, 1534, 656, +806, 1197, -95, 1315, -920, 933, -1505, 170, +-1641, -701, -1243, -1373, -518, -1617, 355, -1311, +1117, -488, 1461, 563, 1358, 1463, 844, 2000, +7, 1934, -827, 1098, -1404, -234, -1589, -1568, +-1284, -2473, -544, -2565, 390, -1695, 1236, -100, +1720, 1645, 1509, 2872, 662, 3105, -359, 2154, +-1250, 317, -1775, -1660, -1654, -3075, -938, -3395, +49, -2370, 1003, -384, 1671, 1729, 1699, 3222, +1040, 3519, 10, 2382, -1073, 276, -1800, -1908, +-1823, -3352, -1143, -3436, -29, -2118, 1051, -1, +1635, 2105, 1542, 3344, 857, 3222, -145, 1894, +-1060, -168, -1511, -2163, -1428, -3193, -775, -2963, +228, -1706, 985, 158, 1209, 1935, 1023, 2919, +419, 2806, -466, 1699, -1086, 21, -1138, -1571, +-780, -2516, -163, -2584, 548, -1813, 955, -394, +847, 1231, 392, 2371, -189, 2533, -756, 1788, +-1020, 445, -778, -1091, -208, -2176, 298, -2341, +638, -1581, 805, -199, 573, 1178, 13, 1949, +-463, 1894, -701, 1094, -713, -38, -430, -1022, +8, -1601, 317, -1484, 420, -672, 363, 278, +77, 915, -247, 1147, -303, 915, -155, 346, +50, -253, 240, -680, 239, -748, 6, -427, +-320, -17, -585, 308, -646, 480, -382, 306, +74, -66, 514, -308, 869, -398, 892, -291, +433, 72, -250, 491, -853, 738, -1183, 640, +-1080, 198, -484, -319, 341, -755, 937, -1013, +1114, -893, 821, -395, 185, 274, -514, 917, +-964, 1281, -958, 1177, -558, 681, 43, -39, +607, -783, 822, -1273, 583, -1380, 64, -1057, +-504, -311, -821, 512, -674, 1085, -167, 1381, +362, 1274, 672, 703, 627, -76, 249, -784, +-238, -1190, -600, -1169, -731, -823, -559, -302, +-125, 258, 372, 680, 704, 868, 709, 849, +374, 642, -163, 291, -679, -77, -967, -376, +-816, -632, -254, -820, 391, -802, 806, -540, +894, -160, 610, 313, 24, 894, -526, 1293, +-780, 1216, -821, 739, -634, -52, -159, -1024, +324, -1734, 545, -1814, 590, -1171, 491, -11, +188, 1210, -133, 2068, -319, 2232, -398, 1461, +-451, 17, -477, -1427, -399, -2304, -185, -2299, +152, -1366, 507, 83, 712, 1435, 695, 2184, +416, 2011, -70, 1064, -640, -125, -1078, -1150, +-1136, -1639, -788, -1395, -132, -718, 630, 41, +1227, 695, 1453, 954, 1164, 748, 324, 371, +-768, 69, -1597, -141, -1835, -264, -1497, -285, +-632, -243, 581, -196, 1672, -143, 2119, -59, +1762, 100, 789, 275, -514, 304, -1725, 179, +-2316, 15, -2047, -182, -1029, -352, 364, -319, +1617, -72, 2275, 215, 2039, 467, 1060, 550, +-250, 313, -1505, -88, -2239, -485, -2103, -788, +-1174, -724, 127, -306, 1326, 187, 2053, 681, +2037, 1017, 1258, 919, -4, 463, -1290, -136, +-2091, -752, -2123, -1197, -1374, -1267, -126, -854, +1156, -20, 2002, 877, 2136, 1503, 1443, 1703, +128, 1294, -1203, 298, -2022, -884, -2145, -1863, +-1491, -2246, -228, -1738, 1103, -573, 1972, 836, +2100, 2126, 1363, 2663, 44, 2142, -1257, 891, +-2053, -694, -2045, -2112, -1206, -2723, 102, -2330, +1325, -1173, 1995, 354, 1851, 1717, 949, 2430, +-305, 2327, -1407, 1436, -1978, 57, -1800, -1198, +-931, -1927, 292, -2047, 1353, -1472, 1797, -376, +1536, 730, 731, 1448, -312, 1645, -1164, 1263, +-1498, 428, -1260, -500, -610, -1160, 151, -1307, +712, -832, 896, -26, 786, 666, 438, 1045, +-32, 938, -374, 264, -485, -524, -424, -971, +-275, -1023, -121, -629, 19, 188, 111, 971, +133, 1318, 81, 1176, 11, 528, -24, -481, +-35, -1319, -10, -1605, 49, -1278, 134, -419, +153, 641, 0, 1434, -226, 1652, -340, 1191, +-298, 291, -193, -626, -22, -1225, 224, -1334, +385, -943, 376, -248, 265, 442, 41, 825, +-251, 825, -477, 567, -566, 196, -471, -158, +-157, -296, 232, -181, 522, -30, 626, -32, +511, -155, 200, -291, -140, -395, -402, -461, +-607, -296, -694, 211, -518, 734, -134, 976, +250, 974, 499, 643, 622, -38, 623, -809, +437, -1372, 74, -1463, -302, -970, -602, -141, +-798, 725, -802, 1358, -553, 1504, -61, 1129, +539, 422, 979, -401, 1023, -994, 679, -1122, +86, -930, -549, -561, -959, -53, -1041, 332, +-771, 469, -232, 493, 366, 482, 818, 450, +948, 391, 731, 239, 260, 26, -355, -236, +-848, -553, -993, -773, -729, -728, -198, -451, +359, -70, 723, 316, 821, 673, 641, 869, +181, 755, -387, 399, -759, 13, -838, -335, +-649, -595, -223, -670, 335, -589, 781, -445, +894, -152, 649, 225, 124, 478, -538, 615, +-1002, 690, -1009, 527, -623, 90, -34, -355, +644, -610, 1157, -705, 1146, -545, 627, -107, +-97, 338, -811, 605, -1259, 634, -1271, 310, +-853, -204, -115, -594, 716, -727, 1314, -505, +1442, 94, 1052, 720, 323, 1012, -473, 888, +-1110, 358, -1392, -455, -1189, -1135, -684, -1371, +-101, -1086, 501, -325, 996, 630, 1184, 1322, +1063, 1520, 709, 1191, 149, 390, -457, -595, +-933, -1275, -1240, -1390, -1271, -997, -924, -280, +-262, 466, 480, 907, 1145, 952, 1596, 614, +1516, 28, 801, -443, -202, -562, -1113, -401, +-1683, -16, -1650, 457, -970, 709, 21, 545, +921, 23, 1411, -673, 1355, -1196, 813, -1252, +-58, -797, -902, 82, -1274, 1129, -1064, 1854, +-423, 1946, 377, 1333, 988, 136, 1114, -1189, +715, -2101, -13, -2361, -770, -1842, -1243, -621, +-1215, 810, -734, 1830, 70, 2172, 945, 1861, +1531, 1058, 1571, 22, 989, -904, -3, -1431, +-1018, -1430, -1728, -1086, -1848, -625, -1353, -151, +-471, 214, 557, 378, 1406, 483, 1765, 652, +1689, 871, 1213, 1062, 257, 1109, -807, 797, +-1528, 21, -1840, -1033, -1710, -1962, -1135, -2425, +-262, -2221, 671, -1261, 1453, 337, 1901, 2055, +1876, 3241, 1329, 3461, 363, 2582, -775, 802, +-1681, -1329, -2083, -3134, -1961, -3961, -1340, -3515, +-317, -2009, 743, 79, 1574, 2144, 2104, 3456, +2130, 3670, 1433, 2912, 313, 1382, -783, -602, +-1752, -2321, -2323, -3198, -2073, -3162, -1224, -2313, +-254, -804, 742, 865, 1686, 2146, 2210, 2739, +2059, 2554, 1351, 1656, 299, 386, -984, -833, +-2076, -1732, -2455, -2161, -2082, -1975, -1109, -1249, +319, -256, 1668, 732, 2382, 1506, 2333, 1819, +1540, 1566, 137, 868, -1275, -57, -2129, -954, +-2210, -1458, -1538, -1425, -410, -963, 729, -230, +1570, 533, 1857, 1030, 1478, 1161, 683, 922, +-209, 396, -1028, -229, -1492, -761, -1457, -1053, +-1031, -981, -378, -602, 355, -81, 1022, 480, +1379, 979, 1320, 1203, 1018, 1045, 439, 579, +-448, -33, -1297, -693, -1750, -1273, -1679, -1553, +-1038, -1377, -26, -825, 966, 3, 1625, 951, +1799, 1731, 1408, 2134, 561, 2039, -349, 1265, +-1030, -63, -1461, -1475, -1483, -2563, -1003, -3052, +-351, -2639, 162, -1320, 588, 504, 872, 2295, +891, 3513, 831, 3677, 837, 2711, 665, 865, +256, -1370, -253, -3171, -950, -3883, -1681, -3480, +-1957, -2040, -1663, 141, -802, 2139, 535, 3156, +1891, 3182, 2785, 2359, 2888, 913, 1978, -607, +310, -1697, -1522, -2129, -2905, -1850, -3353, -1210, +-2781, -556, -1407, 60, 411, 533, 2039, 738, +3008, 842, 3155, 954, 2419, 1011, 981, 921, +-665, 596, -2044, 14, -2870, -674, -2933, -1321, +-2182, -1704, -878, -1576, 670, -931, 2038, -8, +2795, 999, 2809, 1780, 2105, 1999, 733, 1567, +-895, 644, -2185, -519, -2832, -1512, -2717, -1953, +-1746, -1709, -192, -906, 1323, 227, 2336, 1272, +2647, 1755, 2088, 1493, 871, 670, -460, -376, +-1544, -1188, -2132, -1430, -1915, -1048, -1076, -217, +-83, 695, 796, 1174, 1325, 1057, 1315, 525, +847, -206, 145, -816, -427, -929, -605, -609, +-455, -81, -183, 496, 116, 774, 235, 521, +0, 2, -378, -522, -606, -805, -558, -567, +-200, 70, 319, 703, 803, 1134, 1091, 1140, +1014, 546, 523, -429, -211, -1282, -985, -1640, +-1447, -1415, -1392, -738, -920, 236, -96, 1181, +861, 1704, 1476, 1687, 1562, 1218, 1168, 401, +418, -464, -454, -1159, -1142, -1608, -1458, -1642, +-1343, -1233, -793, -581, 46, 230, 803, 1016, +1186, 1542, 1155, 1729, 809, 1479, 266, 770, +-326, -96, -747, -914, -779, -1539, -554, -1701, +-310, -1336, -22, -686, 314, 56, 397, 691, +135, 1054, -124, 1079, -137, 853, -24, 553, +231, 320, 641, 161, 837, 57, 545, -147, +-107, -536, -877, -983, -1394, -1393, -1450, -1595, +-1031, -1202, -94, -237, 1070, 1004, 1902, 2254, +2130, 2916, 1672, 2485, 560, 1206, -898, -529, +-2176, -2277, -2748, -3304, -2261, -3138, -924, -1902, +716, -39, 2093, 1712, 2721, 2740, 2396, 2806, +1283, 1925, -227, 442, -1588, -958, -2336, -1775, +-2273, -1828, -1453, -1264, -145, -395, 1076, 466, +1744, 950, 1766, 818, 1168, 389, 161, -33, +-687, -419, -1015, -589, -893, -352, -461, 141, +121, 651, 494, 868, 424, 688, 48, 285, +-368, -304, -693, -972, -702, -1251, -241, -1028, +500, -517, 1178, 233, 1504, 1015, 1241, 1383, +424, 1273, -650, 789, -1637, -32, -2146, -959, +-1872, -1566, -961, -1548, 261, -863, 1513, 173, +2375, 1206, 2458, 1892, 1768, 1822, 496, 883, +-1013, -505, -2195, -1794, -2639, -2459, -2242, -2115, +-1122, -829, 284, 823, 1485, 2196, 2131, 2791, +2102, 2337, 1494, 937, 544, -778, -433, -2099, +-1131, -2590, -1405, -2116, -1295, -920, -915, 395, +-436, 1363, -18, 1708, 308, 1329, 501, 528, +637, -168, 826, -516, 960, -392, 877, 101, +583, 479, 110, 424, -506, 5, -1107, -702, +-1426, -1404, -1419, -1673, -1138, -1312, -496, -350, +441, 947, 1292, 2013, 1808, 2463, 1925, 2187, +1574, 1241, 741, -84, -371, -1362, -1400, -2254, +-2009, -2449, -2074, -1982, -1664, -1197, -861, -284, +250, 705, 1291, 1544, 1890, 2053, 2015, 2157, +1707, 1879, 973, 1272, 69, 312, -772, -912, +-1451, -1979, -1778, -2618, -1704, -2721, -1352, -2126, +-664, -927, 276, 489, 1135, 1878, 1705, 2904, +1919, 3139, 1672, 2506, 1022, 1316, 132, -159, +-821, -1649, -1612, -2758, -2005, -3066, -1843, -2517, +-1163, -1383, -200, 27, 803, 1344, 1556, 2100, +1844, 2201, 1598, 1788, 919, 1013, 47, 225, +-730, -295, -1189, -648, -1229, -840, -904, -869, +-366, -941, 181, -1067, 528, -1048, 533, -859, +268, -420, -68, 303, -232, 1121, -99, 1817, +219, 2177, 521, 1962, 717, 1210, 690, 84, +334, -1179, -222, -2180, -721, -2660, -1067, -2564, +-1186, -1766, -980, -451, -465, 936, 217, 2092, +898, 2770, 1360, 2730, 1520, 2012, 1350, 792, +803, -580, 1, -1694, -814, -2354, -1485, -2474, +-1810, -1943, -1645, -921, -1033, 221, -127, 1097, +840, 1544, 1529, 1593, 1784, 1284, 1607, 720, +1055, 272, 309, 82, -383, -42, -912, -217, +-1291, -485, -1440, -899, -1232, -1313, -830, -1594, +-396, -1541, 182, -910, 914, 211, 1463, 1429, +1699, 2432, 1693, 2841, 1308, 2424, 429, 1279, +-709, -330, -1748, -1938, -2392, -2940, -2451, -3098, +-1787, -2442, -485, -1138, 1048, 420, 2276, 1729, +2843, 2476, 2585, 2544, 1594, 2010, 156, 1054, +-1333, 8, -2381, -812, -2617, -1361, -2071, -1693, +-1002, -1671, 289, -1360, 1438, -939, 2016, -346, +1883, 412, 1234, 1090, 346, 1606, -502, 1877, +-1010, 1719, -1090, 1085, -808, 137, -297, -890, +144, -1680, 285, -2019, 209, -1822, 45, -1159, +-171, -240, -320, 659, -114, 1284, 391, 1460, +772, 1326, 880, 1025, 793, 534, 364, -16, +-362, -379, -976, -648, -1257, -935, -1227, -1122, +-828, -1141, -105, -973, 693, -463, 1281, 325, +1544, 1131, 1339, 1705, 648, 1818, -186, 1319, +-903, 355, -1412, -769, -1441, -1654, -965, -1927, +-263, -1507, 534, -662, 1203, 373, 1337, 1313, +960, 1697, 356, 1279, -347, 389, -926, -525, +-1004, -1179, -580, -1306, 32, -742, 582, 204, +838, 1015, 646, 1330, 182, 1046, -351, 268, +-775, -680, -884, -1426, -614, -1608, -75, -1099, +569, -133, 1055, 878, 1188, 1600, 911, 1736, +314, 1211, -410, 237, -1030, -768, -1323, -1448, +-1160, -1589, -651, -1160, 41, -342, 720, 490, +1167, 1075, 1275, 1273, 1063, 1001, 507, 353, +-224, -334, -808, -836, -1102, -1000, -1059, -743, +-612, -198, 13, 381, 470, 826, 659, 902, +648, 560, 384, 13, -32, -531, -260, -926, +-195, -936, -39, -530, 169, 86, 430, 645, +473, 921, 163, 816, -248, 452, -664, -16, +-972, -400, -890, -564, -427, -480, 210, -270, +931, -103, 1428, -64, 1370, -61, 798, -66, +-1, -67, -755, 54, -1247, 348, -1302, 626, +-863, 742, -190, 612, 435, 218, 830, -331, +871, -840, 590, -1163, 162, -1125, -219, -688, +-378, -39, -273, 569, 20, 1028, 319, 1234, +501, 1087, 462, 625, 94, 81, -481, -396, +-935, -770, -1138, -988, -968, -972, -341, -819, +522, -584, 1314, -200, 1830, 333, 1808, 861, +1136, 1295, 37, 1477, -1109, 1235, -1978, 578, +-2278, -294, -1846, -1181, -788, -1808, 481, -1935, +1562, -1457, 2153, -486, 2089, 672, 1444, 1597, +419, 2022, -654, 1817, -1354, 994, -1618, -155, +-1455, -1123, -840, -1592, -72, -1462, 459, -840, +743, -11, 808, 654, 637, 924, 425, 733, +354, 222, 287, -337, 178, -636, 67, -526, +-191, -29, -589, 604, -828, 1033, -833, 1030, +-668, 587, -284, -243, 262, -1187, 752, -1725, +1058, -1558, 1105, -849, 833, 195, 301, 1268, +-277, 1903, -743, 1811, -1005, 1081, -942, -42, +-565, -1075, -142, -1557, 213, -1421, 525, -853, +694, -34, 674, 684, 564, 983, 329, 800, +-15, 307, -298, -247, -445, -580, -496, -562, +-422, -209, -278, 290, -122, 679, 57, 770, +255, 514, 435, -48, 574, -660, 580, -999, +392, -924, 33, -565, -370, -40, -678, 520, +-789, 867, -625, 820, -195, 540, 287, 176, +710, -204, 963, -438, 861, -400, 491, -205, +1, 40, -583, 180, -977, 90, -951, -153, +-633, -426, -171, -688, 380, -705, 761, -324, +824, 342, 703, 1071, 512, 1605, 185, 1646, +-198, 1083, -440, -10, -531, -1287, -621, -2251, +-612, -2511, -386, -1926, -59, -604, 215, 924, +468, 2087, 715, 2567, 838, 2243, 737, 1200, +461, -107, 31, -1174, -454, -1699, -844, -1660, +-1033, -1190, -907, -558, -492, -26, 11, 246, +494, 319, 849, 335, 993, 458, 871, 745, +539, 1100, 152, 1280, -216, 1078, -551, 390, +-690, -593, -598, -1579, -470, -2283, -388, -2391, +-258, -1691, -64, -394, 211, 1085, 574, 2300, +951, 2873, 1159, 2616, 1023, 1611, 508, 96, +-234, -1426, -985, -2437, -1479, -2696, -1555, -2212, +-1152, -1118, -315, 201, 690, 1313, 1411, 1912, +1655, 1905, 1427, 1372, 756, 594, -186, -179, +-925, -728, -1150, -926, -993, -808, -617, -579, +-120, -356, 243, -174, 385, -91, 401, -136, +348, -108, 284, 119, 292, 442, 319, 707, +217, 868, -42, 797, -277, 411, -416, -179, +-477, -730, -382, -1059, -70, -1019, 279, -645, +514, -95, 581, 415, 384, 734, -30, 738, +-386, 421, -601, -39, -611, -347, -311, -411, +214, -259, 702, 75, 938, 481, 856, 695, +503, 587, -82, 168, -695, -416, -1092, -933, +-1171, -1186, -921, -1115, -350, -641, 374, 139, +1021, 942, 1408, 1468, 1417, 1559, 1036, 1187, +360, 528, -459, -285, -1138, -1047, -1505, -1413, +-1494, -1277, -1049, -932, -299, -527, 528, -90, +1287, 308, 1666, 607, 1432, 839, 780, 1023, +34, 1157, -652, 1096, -1064, 702, -1024, -12, +-671, -873, -268, -1630, 110, -1987, 342, -1809, +343, -1065, 190, 67, 32, 1206, -32, 1964, +88, 2135, 373, 1645, 680, 727, 782, -270, +577, -1072, 64, -1465, -663, -1369, -1312, -984, +-1493, -476, -1155, 10, -435, 324, 521, 433, +1410, 446, 1840, 439, 1664, 482, 951, 524, +-58, 523, -1011, 471, -1568, 300, -1551, -82, +-1016, -552, -210, -977, 564, -1217, 1012, -1136, +1074, -734, 786, -116, 262, 655, -188, 1300, +-395, 1527, -448, 1284, -320, 704, -15, -39, +256, -699, 283, -1108, 148, -1139, -16, -827, +-193, -367, -339, 28, -317, 271, -133, 331, +79, 317, 280, 297, 476, 283, 519, 311, +390, 374, 187, 352, -83, 211, -400, -41, +-546, -309, -428, -490, -232, -568, -62, -568, +213, -455, 420, -318, 383, -149, 265, 128, +136, 454, -55, 745, -164, 981, -121, 960, +-51, 644, -11, 160, 93, -457, 171, -1070, +90, -1359, -35, -1273, -58, -890, -110, -257, +-249, 473, -262, 1052, -82, 1351, 80, 1274, +260, 872, 487, 299, 562, -278, 393, -751, +131, -1008, -143, -1001, -400, -749, -578, -407, +-572, -45, -412, 311, -161, 560, 154, 625, +465, 591, 647, 452, 671, 240, 525, 53, +238, -70, -113, -157, -389, -192, -524, -244, +-514, -321, -382, -426, -164, -539, 70, -537, +229, -316, 271, 22, 272, 458, 213, 923, +168, 1178, 261, 1068, 364, 696, 286, 93, +86, -662, -172, -1334, -504, -1612, -778, -1388, +-768, -776, -479, 32, 8, 877, 552, 1440, +935, 1512, 1053, 1173, 882, 595, 420, -85, +-152, -623, -667, -942, -970, -1063, -965, -954, +-660, -654, -180, -298, 305, 132, 698, 556, +927, 826, 781, 915, 339, 830, -71, 472, +-330, -34, -490, -452, -430, -678, -163, -704, +78, -461, 154, -86, 109, 164, 6, 166, +-95, 35, -129, -162, -5, -270, 183, -106, +311, 291, 361, 704, 311, 970, 162, 850, +-28, 304, -274, -451, -468, -1170, -462, -1569, +-264, -1294, -32, -492, 174, 435, 396, 1237, +541, 1616, 400, 1310, 118, 524, -49, -408, +-126, -1110, -238, -1265, -247, -906, -65, -293, +99, 418, 67, 901, 7, 901, -1, 495, +-74, -78, -136, -592, 38, -806, 260, -691, +307, -298, 287, 229, 243, 669, 44, 844, +-191, 720, -293, 321, -288, -146, -240, -538, +-93, -799, 101, -816, 222, -510, 266, -83, +283, 298, 223, 564, 76, 677, -80, 568, +-135, 279, -109, -33, -66, -249, -40, -419, +-13, -451, 42, -286, 95, -50, 80, 133, +51, 241, 27, 201, 10, 98, -45, -28, +-101, -212, -40, -301, 129, -163, 232, -6, +224, 158, 171, 404, 93, 568, -84, 509, +-261, 292, -314, -116, -238, -602, -93, -937, +74, -999, 241, -758, 369, -177, 355, 520, +236, 1054, 70, 1278, -86, 1145, -176, 618, +-226, -110, -242, -771, -126, -1194, 42, -1270, +121, -899, 129, -287, 160, 305, 162, 763, +112, 982, 33, 799, -27, 362, -34, -57, +-25, -316, -28, -392, 7, -258, 48, -35, +71, 138, 43, 116, 36, -88, 69, -341, +-5, -495, -132, -491, -119, -267, -84, 120, +-79, 552, 42, 869, 282, 952, 415, 733, +349, 265, 188, -384, 16, -960, -182, -1222, +-319, -1130, -354, -700, -316, 43, -206, 758, +-27, 1131, 145, 1117, 308, 757, 457, 143, +502, -393, 403, -685, 240, -724, 32, -464, +-188, -28, -405, 223, -573, 223, -629, 98, +-511, -88, -186, -266, 288, -225, 689, 42, +891, 358, 853, 541, 573, 514, 116, 256, +-324, -93, -614, -401, -751, -574, -717, -534, +-466, -285, -126, -35, 217, 154, 515, 303, +670, 335, 644, 215, 533, 115, 372, 71, +92, 29, -261, -33, -504, -78, -655, -109, +-692, -126, -474, -171, -29, -162, 413, -64, +702, 37, 755, 74, 525, 93, 136, 75, +-167, 55, -350, 29, -405, 13, -259, 38, +42, 95, 222, 85, 173, 43, 77, -38, +-5, -159, -154, -213, -226, -149, -127, -121, +95, -87, 320, 33, 383, 140, 268, 137, +186, 136, 129, 163, -12, 153, -151, 75, +-207, -17, -312, -105, -404, -124, -325, -116, +-110, -149, 138, -189, 408, -157, 633, -129, +665, -62, 450, 135, 171, 344, -112, 404, +-413, 392, -615, 244, -621, -81, -435, -373, +-110, -452, 233, -396, 498, -204, 563, 52, +435, 218, 227, 246, 18, 150, -111, -92, +-65, -266, 30, -203, 55, 56, 33, 376, +-46, 629, -255, 640, -444, 358, -476, -179, +-375, -776, -141, -1173, 300, -1179, 840, -760, +1179, 33, 1092, 892, 693, 1494, 68, 1644, +-717, 1241, -1363, 304, -1533, -799, -1199, -1626, +-548, -1850, 272, -1391, 1106, -408, 1587, 682, +1559, 1459, 1117, 1616, 405, 1122, -379, 179, +-989, -770, -1283, -1278, -1205, -1138, -795, -484, +-206, 406, 309, 1100, 676, 1254, 890, 766, +878, -148, 621, -1103, 256, -1631, -57, -1481, +-229, -667, -306, 483, -303, 1501, -260, 1983, +-216, 1781, -167, 919, -143, -311, -189, -1439, +-134, -2020, 111, -1904, 339, -1193, 436, -153, +577, 906, 641, 1571, 478, 1662, 198, 1257, +-160, 534, -552, -271, -769, -825, -766, -1025, +-611, -908, -324, -565, 108, -184, 520, 75, +778, 258, 909, 295, 863, 204, 550, 188, +137, 308, -249, 365, -610, 325, -843, 228, +-788, 51, -526, -216, -215, -447, 83, -582, +342, -566, 520, -382, 617, -84, 617, 165, +572, 324, 447, 411, 224, 431, -48, 375, +-382, 310, -731, 236, -907, 154, -843, -26, +-554, -362, -126, -734, 392, -907, 912, -858, +1226, -550, 1146, 58, 795, 782, 338, 1261, +-232, 1366, -832, 1067, -1185, 416, -1219, -442, +-960, -1189, -406, -1524, 313, -1334, 903, -792, +1212, -36, 1248, 769, 972, 1311, 382, 1328, +-245, 909, -727, 260, -1004, -382, -982, -842, +-664, -983, -177, -759, 340, -273, 693, 172, +773, 431, 585, 491, 275, 376, -30, 137, +-205, -78, -200, -225, -88, -249, 37, -142, +106, 27, 40, 162, -107, 256, -263, 264, +-336, 156, -272, -75, -49, -302, 264, -440, +552, -463, 672, -347, 579, -53, 288, 286, +-98, 565, -426, 709, -572, 634, -564, 318, +-417, -100, -133, -552, 189, -875, 413, -885, +528, -593, 541, -153, 457, 386, 227, 846, +-56, 996, -272, 782, -424, 374, -499, -156, +-445, -689, -231, -981, 157, -873, 514, -510, +684, -17, 631, 491, 332, 847, -118, 917, +-490, 694, -644, 164, -504, -434, -123, -852, +282, -1029, 520, -866, 601, -254, 467, 499, +118, 1059, -221, 1256, -379, 956, -444, 187, +-401, -668, -132, -1286, 238, -1426, 408, -981, +436, -113, 422, 793, 227, 1415, -77, 1465, +-255, 892, -318, -34, -246, -868, -49, -1326, +129, -1241, 193, -635, 204, 216, 128, 870, +-46, 1090, -199, 817, -228, 203, -116, -435, +139, -804, 405, -823, 566, -443, 528, 187, +284, 753, -115, 953, -559, 687, -854, 60, +-828, -609, -500, -1066, 61, -1124, 647, -667, +1025, 177, 1098, 937, 876, 1294, 373, 1162, +-281, 575, -856, -283, -1113, -1012, -987, -1303, +-529, -1048, 49, -421, 553, 314, 862, 887, +882, 1094, 590, 801, 183, 198, -115, -385, +-258, -734, -334, -787, -276, -484, -106, 5, +15, 437, 22, 659, -39, 588, -151, 204, +-229, -230, -159, -520, 106, -619, 445, -463, +678, -61, 689, 328, 514, 551, 145, 573, +-374, 373, -771, 9, -832, -292, -656, -460, +-301, -453, 166, -263, 579, -11, 783, 173, +740, 309, 484, 294, 87, 111, -294, -68, +-420, -130, -332, -155, -163, -78, 10, 73, +128, 153, 132, 138, 34, 101, -107, -14, +-184, -158, -144, -255, 2, -272, 201, -220, +397, -94, 502, 64, 511, 292, 357, 527, +-17, 590, -427, 385, -654, 36, -693, -369, +-532, -735, -189, -911, 229, -731, 569, -232, +738, 413, 703, 930, 472, 1112, 139, 901, +-123, 382, -324, -327, -464, -932, -475, -1192, +-361, -1023, -219, -495, -40, 233, 203, 839, +417, 1113, 517, 1000, 518, 535, 360, -139, +77, -705, -220, -972, -398, -878, -398, -492, +-241, 55, 5, 539, 237, 765, 332, 660, +267, 369, 49, 14, -191, -319, -309, -489, +-254, -396, -54, -205, 256, -52, 529, 39, +614, 79, 429, 63, 53, 78, -344, 140, +-588, 239, -608, 320, -408, 290, -75, 78, +251, -196, 458, -460, 502, -646, 386, -623, +260, -312, 150, 123, -1, 534, -121, 807, +-156, 821, -203, 526, -270, 64, -274, -427, +-165, -738, -21, -758, 102, -577, 189, -320, +317, 17, 446, 322, 458, 494, 336, 544, +145, 527, -131, 415, -442, 226, -633, -54, +-533, -369, -243, -616, 42, -704, 330, -637, +564, -390, 528, -7, 327, 438, 153, 798, +1, 913, -158, 694, -225, 264, -182, -252, +-106, -682, -45, -843, -13, -678, -34, -312, +-63, 129, -69, 438, -4, 493, 146, 342, +351, 124, 468, -85, 420, -147, 261, -69, +-13, 23, -347, 76, -531, 91, -559, -33, +-442, -201, -120, -270, 280, -224, 552, -101, +690, 103, 641, 240, 316, 255, -151, 214, +-453, 123, -524, -53, -439, -164, -208, -178, +132, -158, 400, -115, 462, -42, 338, -6, +128, 86, -117, 235, -309, 296, -363, 219, +-230, 68, 21, -199, 276, -504, 459, -662, +494, -537, 319, -118, 22, 498, -279, 992, +-467, 1112, -492, 807, -338, 140, -57, -715, +262, -1369, 496, -1513, 559, -1051, 419, -176, +169, 782, -109, 1452, -339, 1586, -428, 1087, +-286, 166, 7, -733, 243, -1209, 319, -1172, +258, -690, 19, 15, -247, 602, -339, 746, +-252, 435, -37, -62, 307, -406, 629, -471, +669, -229, 374, 263, -34, 759, -425, 898, +-716, 612, -774, 29, -492, -666, 5, -1187, +489, -1252, 788, -889, 798, -221, 522, 585, +128, 1207, -259, 1359, -499, 1093, -529, 517, +-378, -194, -122, -792, 140, -1095, 303, -1081, +331, -739, 237, -217, 116, 265, -18, 606, +-130, 781, -128, 679, -19, 385, 55, 81, +95, -163, 154, -336, 168, -350, 88, -245, +11, -115, -97, -46, -223, -41, -265, -65, +-201, -52, -49, -28, 169, 39, 359, 154, +450, 248, 396, 234, 225, 161, -28, 60, +-276, -58, -407, -148, -390, -158, -253, -135, +12, -89, 261, -60, 345, -65, 291, -75, +158, -69, -40, -72, -168, -9, -137, 128, +25, 231, 237, 268, 380, 307, 293, 258, +45, 112, -235, -54, -485, -245, -607, -456, +-458, -571, -80, -574, 333, -430, 646, -98, +816, 340, 746, 720, 438, 959, -27, 932, +-479, 577, -748, 20, -775, -542, -619, -982, +-299, -1132, 123, -935, 487, -477, 673, 88, +740, 626, 656, 936, 371, 942, 36, 702, +-237, 300, -505, -154, -683, -453, -652, -559, +-416, -521, -82, -346, 269, -115, 543, -10, +643, 5, 556, 0, 358, -12, 91, 30, +-152, 186, -285, 368, -301, 507, -267, 515, +-180, 344, -88, 21, -39, -337, -4, -639, +32, -778, 69, -714, 169, -465, 299, -99, +385, 301, 368, 607, 280, 769, 93, 771, +-208, 617, -472, 294, -534, -115, -431, -487, +-211, -725, 58, -811, 291, -696, 419, -400, +425, -14, 313, 309, 180, 518, 100, 600, +34, 547, -55, 368, -106, 199, -145, 80, +-208, -52, -285, -187, -325, -288, -276, -435, +-117, -592, 117, -664, 409, -583, 628, -314, +688, 185, 594, 760, 351, 1192, -45, 1322, +-462, 1071, -767, 397, -891, -497, -782, -1280, +-423, -1673, 78, -1548, 594, -910, 971, 3, +1074, 863, 845, 1415, 408, 1512, -100, 1101, +-566, 398, -848, -306, -831, -810, -595, -1001, +-251, -825, 114, -435, 397, -37, 532, 226, +506, 292, 377, 176, 259, 24, 163, -26, +91, 88, 28, 313, -82, 526, -271, 552, +-447, 329, -508, -92, -442, -580, -259, -936, +66, -940, 409, -590, 654, -44, 730, 509, +615, 892, 311, 919, -105, 619, -458, 149, +-592, -322, -557, -612, -383, -588, -94, -328, +191, 13, 339, 267, 350, 308, 257, 121, +132, -155, 38, -393, -10, -436, -18, -188, +49, 251, 117, 641, 104, 820, -14, 671, +-158, 212, -250, -387, -289, -875, -243, -1052, +-61, -813, 161, -268, 322, 361, 369, 820, +341, 936, 244, 679, 54, 191, -108, -312, +-141, -590, -165, -559, -185, -280, -106, 88, +-17, 352, -43, 347, -92, 92, -99, -253, +-79, -489, 11, -486, 236, -204, 494, 253, +627, 691, 532, 869, 236, 669, -193, 137, +-627, -501, -869, -941, -786, -1008, -468, -704, +-30, -77, 421, 600, 774, 960, 895, 883, +766, 494, 465, -76, 88, -569, -313, -758, +-637, -620, -752, -246, -633, 223, -398, 529, +-118, 549, 155, 336, 382, 6, 540, -328, +620, -494, 588, -427, 436, -189, 194, 132, +-96, 410, -418, 493, -662, 374, -758, 125, +-690, -182, -436, -452, -8, -511, 497, -360, +950, -105, 1130, 209, 936, 492, 452, 557, +-171, 397, -776, 102, -1114, -251, -1029, -548, +-631, -641, -107, -506, 423, -171, 791, 262, +897, 615, 747, 743, 437, 627, 64, 277, +-282, -195, -519, -610, -588, -817, -505, -747, +-327, -394, -119, 90, 96, 509, 296, 728, +476, 698, 571, 426, 518, 22, 304, -343, +-18, -494, -352, -416, -568, -221, -584, -31, +-375, 112, -54, 147, 243, 49, 422, -74, +434, -91, 301, -24, 107, 88, -73, 211, +-125, 298, -76, 287, -29, 176, 6, -20, +26, -252, -37, -431, -165, -494, -254, -424, +-187, -192, 4, 134, 215, 424, 380, 568, +456, 514, 357, 285, 105, 1, -205, -245, +-432, -372, -455, -325, -269, -155, -41, -12, +159, 44, 318, 18, 353, -60, 218, -145, +22, -146, -110, -37, -132, 150, -77, 350, +29, 488, 119, 477, 124, 308, 32, 6, +-97, -372, -176, -709, -164, -841, -64, -721, +96, -362, 196, 164, 192, 662, 130, 952, +68, 987, 5, 713, -29, 180, -7, -376, +8, -768, -50, -933, -93, -796, -112, -405, +-117, 49, -71, 407, 33, 581, 131, 518, +201, 309, 248, 90, 263, -50, 190, -64, +12, 19, -215, 68, -359, 5, -364, -163, +-249, -378, -28, -543, 239, -529, 416, -279, +444, 133, 333, 534, 126, 802, -151, 820, +-367, 536, -418, 55, -326, -425, -126, -751, +170, -830, 403, -656, 436, -272, 305, 192, +113, 551, -125, 684, -322, 598, -382, 315, +-304, -76, -136, -390, 109, -506, 361, -423, +522, -160, 502, 165, 277, 380, -103, 388, +-477, 199, -692, -97, -642, -352, -307, -465, +193, -364, 631, -59, 864, 293, 777, 511, +389, 528, -126, 333, -611, 13, -922, -300, +-869, -480, -468, -457, 92, -275, 626, -51, +953, 153, 902, 278, 511, 284, -24, 206, +-487, 108, -739, 11, -709, -51, -429, -88, +-26, -118, 313, -117, 490, -104, 487, -113, +336, -72, 98, 29, -112, 129, -194, 197, +-155, 188, -84, 82, 4, -55, 53, -187, +6, -270, -89, -214, -125, -24, -84, 188, +3, 338, 117, 347, 224, 181, 242, -77, +181, -316, 87, -471, -2, -432, -77, -160, +-117, 190, -134, 428, -150, 508, -151, 400, +-127, 99, -97, -259, -3, -478, 157, -481, +303, -271, 405, 69, 455, 366, 338, 494, +45, 403, -288, 81, -553, -312, -682, -557, +-569, -547, -265, -289, 109, 144, 485, 550, +749, 726, 773, 596, 583, 199, 242, -315, +-180, -691, -575, -775, -792, -557, -753, -111, +-469, 394, -35, 702, 395, 666, 667, 339, +696, -116, 500, -498, 205, -611, -79, -412, +-280, -8, -356, 423, -296, 649, -176, 529, +-76, 152, -25, -312, -8, -693, -25, -812, +-10, -595, 90, -129, 258, 423, 406, 847, +445, 981, 319, 800, 39, 357, -303, -246, +-538, -806, -603, -1104, -493, -1051, -207, -672, +176, -64, 499, 582, 663, 1048, 607, 1149, +355, 845, 19, 277, -275, -332, -448, -783, +-445, -925, -303, -720, -115, -293, 45, 153, +148, 449, 174, 495, 160, 325, 161, 64, +207, -154, 235, -226, 192, -97, 86, 154, +-59, 345, -247, 349, -411, 148, -436, -200, +-280, -542, -40, -695, 226, -564, 453, -174, +530, 332, 434, 702, 227, 779, -46, 581, +-281, 175, -388, -305, -384, -605, -298, -607, +-115, -398, 88, -83, 223, 203, 280, 322, +273, 271, 216, 117, 156, -58, 83, -124, +4, -44, -79, 65, -199, 142, -324, 161, +-331, 60, -214, -115, -51, -255, 136, -310, +338, -235, 454, -23, 436, 214, 303, 357, +82, 375, -190, 244, -420, -16, -518, -286, +-443, -434, -233, -419, 60, -248, 318, 40, +442, 334, 433, 511, 342, 506, 177, 304, +-11, -32, -159, -367, -254, -577, -311, -578, +-311, -354, -265, 1, -144, 326, 46, 509, +239, 505, 374, 327, 443, 73, 385, -157, +197, -295, -17, -307, -200, -225, -362, -112, +-410, -7, -318, 51, -191, 60, -44, 54, +154, 39, 297, 30, 355, 66, 366, 123, +310, 145, 161, 133, -21, 86, -193, -19, +-318, -145, -369, -248, -340, -302, -233, -260, +-31, -126, 196, 37, 359, 191, 430, 290, +391, 283, 214, 198, -18, 95, -191, 1, +-267, -54, -267, -52, -182, -48, -62, -107, +31, -217, 87, -329, 104, -386, 62, -310, +2, -57, 1, 321, 76, 673, 161, 836, +229, 708, 225, 288, 100, -284, -91, -783, +-254, -1010, -358, -877, -356, -450, -225, 95, +-24, 580, 174, 844, 348, 790, 432, 475, +392, 63, 256, -315, 56, -537, -159, -513, +-304, -284, -369, 20, -347, 266, -226, 328, +-47, 160, 113, -125, 245, -365, 319, -446, +307, -286, 227, 88, 112, 508, -45, 769, +-178, 746, -221, 418, -185, -122, -121, -663, +-29, -974, 72, -939, 134, -570, 116, -8, +42, 526, -56, 836, -129, 831, -119, 538, +15, 108, 222, -248, 402, -408, 435, -378, +262, -213, -75, -34, -439, 28, -708, -53, +-744, -204, -477, -304, 14, -250, 534, -27, +913, 292, 1006, 602, 745, 759, 211, 657, +-381, 313, -842, -183, -1010, -684, -819, -999, +-368, -1007, 154, -691, 589, -130, 806, 493, +742, 950, 442, 1083, 83, 857, -186, 361, +-340, -208, -385, -648, -323, -830, -221, -710, +-124, -371, -33, 18, 52, 307, 128, 425, +222, 348, 298, 135, 297, -70, 222, -146, +98, -77, -71, 81, -236, 235, -328, 287, +-290, 183, -137, -57, 46, -336, 164, -517, +195, -510, 143, -321, 31, -7, -63, 330, +-38, 558, 53, 591, 148, 429, 220, 129, +204, -182, 48, -385, -164, -448, -329, -374, +-404, -186, -348, 15, -139, 140, 148, 188, +432, 172, 613, 113, 565, 53, 269, 22, +-122, 18, -442, 38, -596, 45, -535, -4, +-264, -75, 91, -111, 393, -122, 542, -99, +486, -33, 257, 36, -35, 67, -329, 53, +-522, 0, -467, -44, -181, -41, 145, -7, +419, 58, 567, 170, 475, 258, 186, 246, +-113, 120, -366, -108, -539, -376, -532, -561, +-336, -580, -71, -400, 223, -24, 519, 443, +714, 792, 691, 894, 442, 729, 30, 317, +-414, -254, -769, -777, -915, -1056, -757, -1021, +-326, -677, 216, -105, 731, 516, 1062, 986, +1033, 1147, 610, 942, -13, 452, -608, -163, +-972, -730, -932, -1064, -537, -1027, -30, -654, +419, -113, 688, 430, 655, 799, 347, 868, +10, 648, -211, 249, -328, -183, -302, -490, +-93, -582, 137, -474, 224, -225, 169, 70, +40, 271, -126, 307, -221, 198, -181, 17, +-46, -130, 109, -156, 224, -47, 221, 131, +101, 264, -32, 246, -72, 57, -33, -218, +48, -431, 113, -469, 100, -310, 2, 14, +-140, 382, -272, 601, -301, 572, -191, 331, +32, -37, 284, -399, 467, -613, 491, -609, +331, -390, 31, -38, -283, 302, -476, 525, +-474, 581, -301, 458, -28, 196, 221, -121, +360, -388, 355, -518, 229, -488, 34, -326, +-134, -78, -204, 170, -151, 342, -19, 415, +106, 375, 157, 241, 141, 70, 60, -100, +-73, -234, -189, -281, -220, -269, -183, -243, +-74, -189, 93, -97, 247, 23, 332, 177, +333, 345, 226, 458, 40, 448, -154, 285, +-306, -18, -393, -363, -342, -615, -155, -677, +71, -515, 265, -171, 376, 252, 343, 609, +200, 757, 22, 633, -139, 290, -224, -136, +-177, -498, -52, -670, 68, -584, 139, -274, +130, 101, 5, 372, -168, 472, -283, 380, +-262, 130, -104, -137, 159, -299, 434, -312, +599, -163, 556, 79, 277, 285, -181, 369, +-608, 291, -801, 39, -697, -287, -358, -528, +109, -586, 541, -403, 773, -7, 723, 448, +442, 770, 61, 824, -266, 552, -469, 35, +-499, -517, -345, -874, -110, -915, 56, -634, +129, -126, 134, 416, 86, 778, 55, 844, +113, 631, 206, 229, 276, -221, 293, -567, +190, -696, -53, -567, -336, -254, -548, 92, +-583, 352, -387, 454, -20, 375, 366, 184, +638, -12, 695, -143, 501, -189, 115, -168, +-283, -114, -517, -65, -513, -30, -326, -4, +-47, 27, 208, 65, 331, 100, 276, 125, +96, 124, -101, 77, -213, -4, -189, -92, +-20, -187, 208, -243, 358, -203, 344, -76, +177, 83, -108, 235, -400, 337, -531, 342, +-418, 223, -147, 6, 176, -232, 451, -410, +571, -481, 474, -403, 195, -174, -163, 134, +-436, 416, -504, 579, -360, 555, -85, 346, +225, 27, 427, -300, 419, -527, 229, -574, +-28, -438, -256, -188, -383, 86, -366, 299, +-178, 402, 106, 394, 329, 309, 418, 183, +404, 37, 272, -108, 19, -239, -244, -334, +-406, -361, -446, -306, -368, -186, -195, -10, +50, 211, 309, 401, 481, 466, 505, 392, +393, 209, 165, -49, -113, -302, -350, -455, +-460, -440, -410, -264, -203, -25, 57, 157, +226, 250, 253, 258, 185, 170, 64, 43, +-45, -27, -70, -25, 29, 1, 187, 17, +291, 8, 254, -37, 70, -110, -206, -180, +-464, -196, -566, -124, -454, 13, -185, 147, +175, 231, 509, 262, 684, 211, 647, 69, +423, -92, 71, -191, -278, -216, -524, -175, +-606, -95, -514, -4, -296, 79, -50, 104, +185, 54, 367, 14, 455, 33, 448, 66, +354, 92, 169, 108, -39, 64, -207, -44, +-327, -157, -374, -237, -318, -225, -191, -82, +-30, 101, 132, 216, 243, 244, 239, 177, +156, 16, 71, -154, 54, -233, 109, -178, +176, -12, 176, 166, 73, 245, -144, 196, +-397, 27, -550, -205, -503, -359, -254, -317, +116, -105, 484, 165, 728, 381, 750, 447, +513, 306, 75, 0, -399, -323, -727, -489, +-780, -429, -530, -183, -85, 161, 340, 452, +584, 522, 563, 329, 315, -23, -20, -372, +-256, -558, -312, -478, -213, -165, -31, 226, +163, 514, 295, 583, 287, 401, 108, 57, +-157, -293, -381, -504, -447, -499, -316, -318, +-48, -63, 250, 178, 465, 318, 497, 321, +349, 259, 114, 195, -103, 112, -265, 10, +-345, -98, -323, -241, -200, -387, -42, -433, +72, -324, 123, -67, 142, 263, 120, 534, +94, 625, 129, 491, 203, 154, 225, -262, +161, -574, 18, -658, -192, -494, -405, -138, +-507, 263, -433, 530, -209, 553, 90, 347, +402, 18, 630, -291, 668, -437, 506, -352, +203, -102, -201, 165, -574, 316, -744, 285, +-653, 94, -364, -146, 29, -301, 390, -296, +604, -129, 613, 128, 433, 332, 157, 377, +-120, 239, -332, -26, -404, -303, -333, -451, +-198, -417, -31, -203, 139, 121, 218, 409, +204, 536, 152, 460, 66, 204, -49, -139, +-98, -431, -61, -568, 3, -516, 65, -285, +127, 51, 126, 361, 36, 544, -97, 563, +-211, 414, -279, 127, -263, -218, -108, -494, +174, -601, 433, -495, 524, -212, 424, 141, +166, 428, -206, 526, -536, 391, -649, 108, +-500, -179, -157, -343, 269, -290, 602, -52, +695, 208, 502, 339, 114, 248, -317, -55, +-609, -425, -635, -644, -375, -555, 38, -148, +415, 419, 593, 889, 507, 1030, 206, 718, +-158, 31, -433, -722, -506, -1192, -317, -1201, +34, -720, 333, 98, 449, 899, 362, 1315, +102, 1171, -232, 543, -469, -292, -467, -977, +-202, -1244, 178, -985, 492, -298, 606, 508, +472, 1057, 113, 1129, -325, 727, -647, 28, +-711, -681, -500, -1094, -90, -1035, 370, -546, +712, 158, 818, 778, 639, 1063, 209, 935, +-304, 470, -683, -162, -795, -718, -651, -977, +-301, -874, 153, -480, 533, 66, 675, 557, +587, 825, 342, 798, 18, 488, -282, 20, +-424, -409, -372, -656, -195, -651, -6, -394, +114, -14, 144, 317, 87, 463, -18, 378, +-92, 147, -68, -91, 60, -245, 229, -237, +325, -65, 287, 142, 137, 247, -110, 201, +-366, 17, -496, -215, -441, -375, -242, -394, +45, -226, 327, 97, 519, 406, 543, 562, +382, 524, 119, 274, -133, -123, -334, -488, +-437, -666, -396, -599, -266, -319, -107, 72, +66, 429, 215, 634, 308, 622, 348, 409, +323, 78, 220, -262, 66, -513, -118, -607, +-295, -502, -406, -222, -383, 129, -253, 413, +-67, 529, 150, 438, 361, 188, 474, -94, +448, -289, 292, -325, 31, -184, -273, 29, +-495, 155, -532, 139, -373, 2, -91, -191, +209, -307, 431, -248, 492, -35, 389, 253, +171, 496, -101, 564, -325, 401, -416, 61, +-349, -346, -145, -664, 133, -756, 332, -588, +378, -215, 263, 257, 37, 669, -196, 845, +-328, 718, -321, 353, -155, -109, 102, -517, +299, -738, 364, -698, 294, -429, 83, -45, +-194, 299, -376, 486, -376, 501, -214, 385, +38, 187, 282, -24, 395, -174, 305, -246, +82, -274, -138, -263, -258, -199, -259, -95, +-142, 34, 43, 181, 201, 282, 238, 286, +150, 203, -10, 62, -177, -87, -280, -184, +-234, -227, -24, -216, 235, -137, 387, -26, +349, 73, 155, 148, -106, 182, -311, 168, +-373, 108, -292, 15, -107, -67, 100, -114, +239, -131, 273, -114, 231, -79, 126, -45, +-22, 10, -144, 77, -172, 119, -130, 148, +-54, 150, 29, 94, 75, 6, 69, -93, +41, -193, 10, -233, -31, -187, -53, -79, +-37, 69, -15, 201, 9, 256, 58, 243, +117, 168, 144, 31, 119, -122, 25, -229, +-105, -282, -224, -286, -280, -206, -225, -23, +-53, 206, 145, 393, 300, 450, 380, 333, +325, 71, 115, -228, -140, -450, -307, -501, +-344, -346, -270, -51, -98, 250, 117, 435, +247, 428, 243, 245, 141, -18, -8, -241, +-119, -342, -143, -288, -96, -108, 18, 104, +179, 242, 244, 244, 145, 124, -42, -32, +-212, -156, -313, -202, -297, -148, -151, -34, +87, 82, 309, 166, 407, 176, 357, 103, +177, 4, -76, -68, -297, -107, -411, -106, +-366, -80, -153, -48, 124, -9, 313, 18, +345, 29, 230, 47, 31, 80, -168, 109, +-275, 101, -225, 52, -33, -15, 173, -76, +276, -135, 249, -175, 114, -171, -85, -111, +-252, 11, -313, 157, -256, 270, -96, 301, +97, 211, 225, 25, 266, -188, 243, -355, +141, -383, 4, -229, -65, 20, -78, 246, +-88, 375, -96, 348, -106, 171, -156, -75, +-203, -291, -163, -366, -8, -275, 199, -96, +388, 123, 484, 305, 409, 344, 144, 250, +-203, 86, -479, -112, -597, -284, -526, -361, +-273, -310, 86, -128, 419, 101, 583, 285, +528, 388, 304, 355, -4, 175, -290, -57, +-401, -259, -289, -378, -70, -357, 103, -207, +142, 0, 36, 198, -121, 326, -207, 338, +-164, 219, -9, 6, 203, -205, 383, -308, +435, -277, 328, -135, 88, 73, -212, 257, +-449, 318, -525, 218, -433, -16, -194, -283, +118, -443, 361, -397, 443, -132, 366, 270, +215, 604, 83, 655, -15, 383, -113, -85, +-195, -558, -259, -795, -305, -655, -302, -216, +-200, 296, 23, 638, 294, 667, 450, 431, +438, 71, 308, -276, 77, -466, -181, -421, +-342, -214, -364, 24, -246, 180, -49, 222, +83, 172, 114, 35, 102, -125, 54, -182, +15, -119, 55, 16, 140, 189, 190, 310, +147, 292, -9, 138, -187, -129, -297, -438, +-320, -618, -209, -538, 18, -203, 251, 293, +406, 736, 424, 901, 255, 695, -59, 173, +-381, -480, -562, -936, -491, -971, -179, -612, +252, -15, 591, 584, 651, 895, 402, 772, +-17, 325, -428, -204, -652, -557, -565, -583, +-231, -328, 154, 53, 442, 334, 555, 336, +458, 109, 197, -156, -107, -308, -350, -252, +-467, -15, -400, 235, -175, 358, 103, 302, +315, 106, 376, -107, 276, -251, 74, -296, +-149, -216, -284, -70, -240, 35, -72, 95, +88, 132, 163, 129, 145, 103, 71, 86, +2, 64, -33, 28, -30, -15, -10, -76, +-29, -155, -93, -204, -136, -185, -109, -102, +-12, 41, 101, 203, 158, 291, 164, 271, +152, 156, 118, -43, 57, -241, -59, -320, +-227, -263, -347, -102, -319, 107, -146, 263, +108, 308, 327, 243, 404, 56, 311, -202, +105, -403, -101, -436, -191, -256, -166, 84, +-141, 437, -148, 641, -135, 557, -77, 179, +6, -312, 99, -670, 170, -728, 195, -453, +169, 5, 83, 403, -1, 584, -27, 523, +-54, 275, -123, -35, -157, -250, -145, -294, +-104, -217, -24, -98, 44, -6, 62, 9, +76, -36, 94, -79, 123, -69, 188, 41, +198, 215, 86, 310, -96, 267, -281, 103, +-390, -152, -333, -358, -135, -361, 114, -186, +335, 44, 429, 236, 369, 284, 182, 156, +-83, -46, -326, -206, -440, -243, -399, -121, +-179, 87, 165, 270, 431, 358, 467, 276, +275, 21, -45, -262, -350, -442, -467, -466, +-338, -295, -38, 42, 246, 379, 374, 545, +326, 452, 177, 146, 0, -205, -165, -429, +-265, -429, -265, -182, -163, 170, 14, 406, +194, 386, 243, 98, 121, -307, -78, -550, +-235, -484, -250, -160, -70, 280, 205, 643, +405, 738, 419, 490, 217, -4, -106, -507, +-383, -788, -510, -752, -480, -438, -282, 41, +59, 519, 408, 797, 583, 733, 521, 373, +274, -101, -81, -511, -376, -712, -459, -621, +-315, -289, -64, 147, 150, 511, 208, 642, +119, 496, -30, 161, -145, -238, -142, -538, +-33, -594, 108, -386, 238, -23, 312, 335, +264, 546, 111, 524, -125, 277, -379, -65, +-522, -342, -446, -462, -171, -386, 165, -163, +392, 84, 417, 267, 270, 308, 45, 193, +-95, 31, -85, -92, -6, -151, 44, -91, +28, 41, -50, 123, -140, 128, -179, 50, +-176, -106, -169, -237, -173, -289, -93, -246, +110, -82, 368, 142, 580, 339, 615, 486, +377, 485, -47, 277, -474, -49, -771, -413, +-806, -709, -570, -759, -178, -518, 248, -67, +595, 456, 761, 839, 747, 906, 513, 649, +82, 147, -325, -419, -555, -792, -620, -842, +-525, -609, -291, -176, -57, 294, 102, 589, +199, 617, 284, 433, 366, 132, 398, -157, +330, -320, 170, -326, -28, -206, -225, -35, +-388, 91, -476, 132, -421, 94, -257, -3, +-35, -94, 212, -114, 425, -71, 515, 22, +434, 129, 184, 188, -125, 182, -349, 116, +-431, -12, -316, -138, -71, -207, 121, -229, +178, -198, 148, -89, 47, 55, -43, 184, +-60, 265, -32, 256, 29, 137, 70, -29, +57, -172, 51, -245, 68, -200, 40, -53, +2, 90, -69, 167, -185, 147, -214, 28, +-136, -94, -58, -121, 50, -85, 192, -7, +232, 94, 163, 134, 47, 81, -60, -23, +-115, -123, -107, -131, -61, -24, 40, 110, +139, 209, 126, 224, 3, 92, -162, -156, +-302, -397, -356, -499, -222, -378, 78, -53, +405, 350, 590, 675, 525, 773, 233, 568, +-126, 106, -423, -450, -586, -874, -530, -959, +-297, -653, -13, -111, 230, 437, 400, 800, +437, 811, 354, 470, 187, 8, 1, -324, +-130, -412, -193, -254, -205, -13, -205, 117, +-224, 74, -239, -145, -160, -427, -24, -500, +137, -282, 324, 99, 458, 543, 423, 868, +241, 871, 6, 551, -231, -6, -412, -621, +-506, -1012, -448, -1051, -218, -766, 104, -212, +369, 405, 486, 851, 425, 1002, 213, 794, +-65, 330, -276, -143, -317, -502, -224, -679, +-80, -588, 3, -297, 16, 33, 42, 279, +119, 318, 157, 161, 141, -30, 88, -161, +-48, -171, -203, 15, -241, 302, -156, 477, +-32, 424, 125, 144, 230, -261, 207, -582, +114, -666, 42, -514, -22, -183, -103, 211, +-214, 482, -336, 557, -349, 477, -206, 279, +59, 37, 378, -161, 631, -295, 633, -355, +380, -327, -34, -238, -498, -108, -788, 42, +-746, 151, -439, 207, 3, 217, 462, 186, +720, 152, 660, 127, 327, 71, -90, -27, +-375, -168, -430, -338, -319, -440, -113, -372, +98, -118, 203, 253, 202, 545, 111, 581, +-45, 380, -190, 59, -257, -291, -246, -516, +-51, -506, 285, -310, 495, -32, 439, 231, +212, 381, -92, 407, -392, 327, -534, 117, +-482, -154, -272, -344, -17, -405, 192, -323, +343, -131, 451, 68, 426, 230, 251, 350, +44, 357, -150, 249, -269, 75, -299, -158, +-330, -362, -379, -441, -288, -372, -46, -119, +250, 237, 499, 472, 574, 495, 388, 314, +6, -57, -338, -423, -439, -562, -292, -442, +-71, -99, 115, 340, 177, 635, 109, 640, +-7, 341, -111, -162, -193, -615, -194, -788, +-78, -642, 115, -238, 341, 287, 451, 723, +348, 878, 59, 682, -293, 210, -549, -337, +-557, -740, -346, -844, -31, -609, 275, -124, +435, 384, 409, 664, 260, 601, 54, 291, +-172, -67, -300, -302, -247, -335, -39, -190, +153, 12, 209, 128, 113, 109, -93, 17, +-292, -85, -372, -128, -277, -84, -24, -4, +286, 76, 452, 151, 443, 150, 308, 71, +77, -14, -181, -90, -376, -143, -454, -137, +-373, -84, -165, 28, 55, 171, 243, 215, +307, 130, 229, -25, 87, -227, -42, -363, +-95, -306, -15, -56, 111, 303, 157, 571, +71, 539, -168, 230, -395, -212, -448, -625, +-313, -755, -17, -493, 342, -14, 517, 490, +455, 809, 253, 726, -13, 282, -204, -263, +-272, -687, -272, -785, -219, -506, -126, -36, +-42, 407, 69, 665, 135, 619, 91, 337, +21, -2, -14, -316, 5, -530, 120, -563, +227, -427, 182, -141, 29, 244, -187, 553, +-349, 630, -332, 439, -172, 47, 7, -334, +165, -502, 261, -415, 274, -127, 212, 194, +35, 318, -201, 199, -358, -54, -323, -312, +-112, -406, 208, -232, 454, 136, 441, 543, +132, 768, -274, 627, -559, 146, -599, -470, +-333, -944, 81, -1017, 427, -650, 628, -23, +635, 606, 371, 965, -37, 906, -447, 520, +-732, 12, -703, -438, -384, -716, 31, -738, +407, -466, 606, 7, 516, 447, 258, 651, +-57, 524, -323, 123, -407, -347, -310, -636, +-129, -578, 113, -163, 308, 413, 306, 840, +129, 865, -155, 455, -393, -190, -432, -816, +-231, -1184, 89, -1075, 374, -454, 503, 435, +428, 1189, 168, 1436, -178, 1069, -445, 270, +-529, -671, -405, -1354, -169, -1412, 95, -850, +328, 52, 440, 933, 359, 1393, 191, 1212, +7, 480, -207, -491, -366, -1265, -378, -1466, +-233, -982, 14, 13, 240, 1067, 299, 1641, +218, 1469, 32, 634, -172, -529, -262, -1492, +-213, -1808, -83, -1364, 86, -326, 218, 872, +249, 1689, 223, 1785, 120, 1121, -85, -18, +-330, -1097, -472, -1644, -392, -1468, -109, -660, +198, 414, 400, 1229, 448, 1423, 304, 972, +38, 115, -233, -778, -390, -1314, -360, -1225, +-188, -548, 4, 401, 186, 1195, 278, 1488, +191, 1117, 15, 198, -134, -877, -188, -1590, +-99, -1608, 54, -936, 109, 136, 77, 1171, +17, 1737, -56, 1573, -103, 728, -103, -428, +-107, -1353, -103, -1639, -41, -1219, 32, -311, +114, 688, 212, 1317, 226, 1305, 75, 714, +-97, -152, -200, -887, -235, -1159, -184, -919, +-102, -303, -33, 454, 97, 1010, 240, 1107, +231, 729, 141, 13, 24, -737, -132, -1124, +-217, -1006, -189, -507, -169, 183, -125, 775, +-26, 988, 50, 790, 159, 294, 305, -293, +333, -669, 189, -692, -70, -431, -387, 12, +-529, 432, -406, 559, -166, 342, 113, -67, +360, -481, 462, -643, 438, -393, 272, 104, +-96, 570, -452, 819, -594, 707, -531, 246, +-268, -338, 142, -813, 460, -975, 550, -695, +432, -140, 156, 439, -151, 880, -372, 924, +-486, 503, -459, -68, -217, -549, 160, -783, +487, -599, 587, -135, 401, 318, -10, 622, +-453, 612, -700, 265, -663, -153, -327, -526, +184, -765, 597, -614, 751, -128, 687, 419, +351, 876, -217, 1007, -721, 641, -932, 8, +-809, -619, -366, -1073, 209, -1090, 656, -643, +878, 5, 772, 662, 346, 1075, -159, 1020, +-518, 606, -702, 15, -655, -616, -376, -979, +-39, -872, 241, -447, 415, 122, 420, 631, +293, 781, 161, 568, 3, 165, -192, -330, +-300, -677, -284, -654, -195, -327, -19, 162, +135, 655, 124, 849, 40, 623, -45, 124, +-139, -509, -99, -980, 81, -996, 141, -602, +92, 50, 17, 744, -103, 1111, -134, 990, +-51, 524, 2, -124, 61, -730, 105, -994, +-31, -844, -154, -406, -142, 160, -166, 605, +-137, 743, 36, 576, 143, 217, 185, -179, +237, -464, 166, -541, 14, -383, -92, -43, +-196, 330, -279, 557, -260, 548, -224, 289, +-158, -154, -16, -604, 108, -850, 212, -721, +347, -228, 392, 412, 276, 938, 115, 1116, +-127, 824, -436, 155, -587, -620, -515, -1148, +-337, -1165, -41, -673, 260, 71, 360, 734, +366, 1012, 372, 778, 259, 242, 114, -299, +1, -607, -228, -527, -440, -194, -471, 151, +-388, 402, -192, 428, 60, 182, 180, -149, +214, -426, 231, -608, 155, -539, 142, -214, +219, 233, 147, 762, -61, 1109, -222, 966, +-328, 433, -373, -312, -333, -1094, -254, -1558, +-123, -1429, 82, -720, 289, 358, 438, 1375, +502, 1850, 409, 1631, 131, 796, -238, -418, +-499, -1470, -538, -1873, -383, -1497, -168, -523, +-14, 615, 115, 1384, 201, 1497, 175, 991, +108, 57, 110, -867, 94, -1258, 63, -1011, +83, -324, 43, 535, -61, 1137, -158, 1160, +-319, 638, -452, -215, -391, -1054, -185, -1428, +113, -1181, 401, -446, 530, 568, 496, 1409, +308, 1678, -80, 1311, -430, 360, -526, -843, +-469, -1660, -297, -1782, -20, -1224, 229, -119, +332, 1027, 281, 1665, 110, 1634, -95, 916, +-228, -205, -218, -1123, -89, -1513, 65, -1313, +205, -529, 249, 485, 104, 1226, -113, 1439, +-285, 1010, -380, 72, -287, -876, -81, -1401, +63, -1321, 169, -605, 245, 454, 194, 1294, +65, 1523, -40, 1051, -108, 48, -71, -988, +2, -1542, 19, -1405, 18, -604, -45, 545, +-226, 1434, -390, 1612, -404, 1040, -236, -23, +93, -1097, 454, -1649, 680, -1429, 668, -532, +377, 665, -101, 1536, -602, 1641, -953, 1016, +-923, -78, -488, -1191, 114, -1719, 628, -1427, +859, -501, 715, 695, 262, 1558, -253, 1600, +-580, 919, -582, -121, -328, -1133, 14, -1581, +298, -1202, 393, -300, 272, 704, -10, 1369, +-373, 1326, -631, 642, -613, -334, -275, -1212, +289, -1502, 783, -962, 925, 53, 680, 1069, +100, 1714, -628, 1516, -1054, 456, -978, -866, +-560, -1863, 44, -2049, 559, -1211, 745, 281, +650, 1699, 359, 2387, -94, 1969, -481, 560, +-618, -1118, -518, -2276, -168, -2417, 281, -1404, +547, 268, 529, 1774, 205, 2466, -323, 2015, +-723, 622, -771, -1010, -455, -2127, 104, -2331, +634, -1498, 845, 41, 720, 1506, 338, 2310, +-233, 2132, -733, 982, -930, -557, -769, -1818, +-308, -2332, 248, -1826, 624, -490, 689, 984, +447, 1951, 31, 2080, -300, 1298, -405, 32, +-315, -1114, -125, -1802, 29, -1695, 63, -809, +56, 290, 64, 1146, 13, 1535, -62, 1238, +-66, 418, -98, -441, -145, -1047, -61, -1201, +49, -788, 40, -136, -8, 391, 13, 682, +63, 649, 144, 378, 200, 107, 113, -49, +-104, -74, -383, -30, -566, -41, -478, -185, +-187, -423, 146, -645, 421, -676, 529, -361, +465, 207, 322, 833, 80, 1344, -249, 1415, +-516, 880, -669, -98, -650, -1185, -354, -1917, +106, -1925, 470, -1200, 583, -29, 461, 1199, +205, 2010, -64, 1995, -304, 1227, -406, 89, +-263, -962, -24, -1503, 137, -1391, 173, -831, +60, -140, -174, 424, -385, 614, -408, 400, +-223, 129, 131, 13, 492, 88, 586, 337, +424, 553, 162, 575, -190, 363, -552, -142, +-742, -818, -687, -1298, -347, -1302, 228, -844, +646, -39, 700, 845, 499, 1498, 72, 1692, +-409, 1231, -614, 281, -534, -673, -291, -1311, +79, -1470, 339, -1069, 386, -284, 370, 493, +213, 903, -152, 771, -512, 280, -684, -210, +-551, -464, -147, -312, 306, 190, 602, 693, +648, 895, 445, 590, 98, -160, -268, -940, +-573, -1368, -650, -1279, -502, -665, -283, 213, +4, 1030, 296, 1507, 438, 1352, 376, 665, +195, -149, 72, -848, 70, -1142, 55, -870, +-75, -290, -326, 269, -601, 566, -680, 396, +-472, -81, -78, -449, 397, -520, 744, -235, +825, 371, 644, 946, 158, 1148, -434, 826, +-826, 61, -975, -824, -817, -1488, -241, -1592, +439, -972, 865, 61, 937, 1048, 500, 1631, +-192, 1518, -631, 728, -819, -289, -736, -1123, +-250, -1472, 332, -1110, 730, -219, 879, 745, +615, 1324, -4, 1211, -651, 534, -1121, -424, +-1168, -1296, -642, -1554, 162, -1035, 885, -37, +1238, 1015, 1049, 1639, 424, 1564, -352, 848, +-964, -210, -1145, -1141, -856, -1568, -261, -1393, +384, -675, 745, 291, 706, 1030, 384, 1292, +-127, 1028, -539, 273, -595, -513, -360, -909, +59, -868, 423, -377, 480, 294, 292, 731, +-28, 800, -447, 451, -716, -170, -587, -673, +-166, -826, 347, -677, 667, -216, 594, 393, +273, 776, -166, 842, -637, 527, -828, -78, +-557, -546, -27, -742, 480, -590, 785, -93, +811, 406, 513, 723, -118, 788, -846, 402, +-1283, -368, -1217, -1032, -617, -1224, 292, -967, +1083, -274, 1396, 689, 1148, 1542, 522, 1830, +-285, 1315, -979, 274, -1259, -888, -1064, -1732, +-594, -1907, -31, -1448, 539, -470, 890, 703, +848, 1538, 448, 1719, -116, 1238, -521, 328, +-619, -595, -454, -1112, -102, -1108, 220, -650, +344, 126, 315, 765, 177, 907, -126, 530, +-505, -180, -713, -807, -613, -1096, -246, -996, +276, -373, 821, 591, 1060, 1391, 748, 1706, +52, 1394, -640, 438, -1003, -732, -948, -1552, +-589, -1829, -83, -1533, 407, -705, 662, 358, +612, 1243, 363, 1578, -97, 1316, -557, 722, +-629, -11, -367, -667, 47, -959, 505, -789, +730, -331, 535, 95, 13, 289, -593, 190, +-1034, -89, -1089, -302, -730, -343, -78, -177, +679, 184, 1277, 615, 1439, 915, 991, 872, +95, 503, -863, -122, -1530, -830, -1581, -1284, +-992, -1319, -158, -904, 641, -128, 1213, 679, +1213, 1222, 687, 1361, 11, 1043, -629, 378, +-891, -284, -643, -736, -261, -898, 145, -742, +476, -466, 372, -160, -67, 119, -400, 135, +-535, 50, -405, 178, 29, 430, 394, 653, +541, 790, 569, 627, 338, 126, -127, -482, +-533, -1075, -710, -1428, -630, -1183, -351, -456, +31, 414, 375, 1232, 489, 1659, 314, 1395, +27, 611, -179, -398, -232, -1257, -108, -1526, +133, -1156, 311, -407, 208, 451, -82, 1030, +-378, 1079, -698, 750, -847, 249, -545, -413, +64, -909, 684, -893, 1157, -501, 1180, 56, +615, 587, -196, 811, -954, 671, -1365, 295, +-1221, -219, -756, -585, -64, -505, 747, -289, +1142, -130, 1006, 91, 641, 103, 39, -74, +-668, -72, -928, 38, -686, 214, -235, 557, +241, 808, 443, 640, 247, 116, -119, -638, +-462, -1342, -602, -1521, -335, -1140, 169, -299, +630, 912, 981, 1865, 983, 2090, 400, 1594, +-501, 433, -1249, -1035, -1582, -2129, -1351, -2464, +-528, -1928, 493, -553, 1282, 1116, 1674, 2309, +1406, 2648, 572, 1974, -358, 493, -1147, -1130, +-1606, -2254, -1421, -2507, -714, -1879, 73, -594, +757, 955, 1093, 2080, 906, 2359, 495, 1830, +71, 673, -323, -715, -473, -1781, -402, -2113, +-295, -1638, -134, -662, -84, 378, -336, 1153, +-564, 1519, -443, 1333, -65, 723, 514, 88, +1140, -469, 1362, -839, 923, -861, 93, -670, +-868, -390, -1680, -124, -1890, 65, -1455, 225, +-592, 409, 539, 556, 1590, 572, 2119, 472, +1970, 213, 1139, -110, -198, -326, -1461, -517, +-2207, -574, -2317, -481, -1611, -340, -369, -90, +831, 175, 1775, 372, 2149, 506, 1710, 511, +815, 384, -213, 194, -1254, 80, -1804, -27, +-1660, -208, -1164, -426, -419, -641, 463, -757, +1021, -692, 1127, -333, 1045, 277, 798, 882, +339, 1342, -214, 1423, -732, 965, -1053, 110, +-1104, -900, -919, -1740, -491, -2008, 105, -1529, +674, -507, 992, 731, 1003, 1808, 803, 2232, +389, 1889, -138, 962, -673, -333, -1097, -1556, +-1182, -2238, -916, -2179, -459, -1370, 171, -55, +807, 1300, 1085, 2138, 1018, 2150, 715, 1427, +109, 216, -477, -1035, -748, -1741, -860, -1726, +-736, -1138, -375, -170, -146, 802, 48, 1250, +324, 1059, 300, 521, 139, -167, 250, -730, +345, -791, 348, -353, 437, 273, 344, 758, +-102, 898, -661, 572, -1222, -124, -1568, -898, +-1234, -1438, -324, -1417, 729, -757, 1674, 315, +2117, 1418, 1756, 2047, 774, 1934, -493, 1064, +-1741, -303, -2495, -1594, -2333, -2344, -1377, -2261, +31, -1271, 1551, 182, 2549, 1476, 2526, 2261, +1545, 2287, -2, 1384, -1583, -31, -2530, -1339, +-2481, -2164, -1525, -2120, 0, -1189, 1494, 78, +2322, 1236, 2164, 1957, 1124, 1894, -351, 1085, +-1577, -109, -2061, -1312, -1757, -2007, -806, -1854, +399, -969, 1275, 326, 1535, 1561, 1209, 2161, +479, 1838, -390, 725, -1094, -671, -1345, -1705, +-1004, -2028, -201, -1606, 574, -571, 1009, 618, +1027, 1544, 476, 1947, -423, 1609, -1055, 646, +-1143, -517, -759, -1449, 5, -1920, 782, -1770, +1146, -875, 1034, 390, 496, 1492, -312, 2081, +-975, 1899, -1218, 1031, -1033, -138, -426, -1283, +337, -2074, 777, -2071, 814, -1332, 578, -336, +96, 830, -353, 1844, -475, 2161, -337, 1811, +-149, 962, 56, -267, 230, -1454, 202, -2152, +-7, -2171, -300, -1497, -531, -264, -508, 1083, +-291, 2090, 13, 2346, 396, 1679, 631, 430, +553, -987, 378, -2040, 180, -2180, -175, -1448, +-495, -170, -630, 1178, -715, 2012, -613, 1994, +-249, 1093, 94, -340, 299, -1614, 455, -2218, +533, -1977, 550, -877, 471, 736, 205, 2117, +-154, 2722, -576, 2281, -923, 839, -902, -998, +-537, -2482, -100, -3086, 308, -2544, 636, -1062, +678, 869, 491, 2527, 290, 3192, -8, 2705, +-408, 1307, -643, -602, -621, -2335, -440, -3135, +-92, -2688, 396, -1245, 654, 676, 545, 2230, +288, 2755, -130, 2230, -670, 865, -972, -829, +-873, -2090, -506, -2458, 112, -1843, 863, -518, +1364, 1025, 1312, 2134, 758, 2387, -48, 1763, +-910, 425, -1566, -1091, -1750, -2136, -1436, -2411, +-691, -1877, 375, -711, 1386, 686, 1935, 1754, +1902, 2229, 1281, 2067, 146, 1263, -1050, 158, +-1873, -874, -2053, -1623, -1496, -1903, -581, -1697, +352, -1122, 1176, -423, 1534, 327, 1202, 1121, +531, 1715, -103, 1947, -583, 1808, -719, 1215, +-500, 148, -223, -1119, -50, -2149, 1, -2690, +-122, -2543, -365, -1603, -539, -101, -407, 1534, +60, 2833, 614, 3344, 997, 2849, 1113, 1470, +827, -403, 93, -2180, -815, -3272, -1456, -3424, +-1585, -2588, -1259, -913, -536, 1003, 421, 2473, +1248, 3228, 1655, 3099, 1552, 1993, 982, 278, +28, -1374, -994, -2484, -1652, -2846, -1779, -2373, +-1373, -1233, -517, 136, 441, 1372, 1144, 2139, +1459, 2226, 1364, 1709, 863, 787, 206, -288, +-403, -1221, -977, -1737, -1355, -1703, -1359, -1208, +-1066, -436, -510, 328, 286, 911, 1025, 1223, +1488, 1206, 1620, 945, 1281, 538, 448, 79, +-667, -382, -1704, -922, -2237, -1384, -2012, -1479, +-1088, -1197, 306, -575, 1723, 518, 2491, 1740, +2301, 2399, 1348, 2284, -162, 1407, -1735, -85, +-2641, -1666, -2598, -2881, -1710, -3223, -125, -2299, +1695, -544, 2847, 1321, 2790, 2907, 1707, 3632, +11, 3002, -1797, 1317, -3017, -724, -3018, -2506, +-1785, -3435, 45, -3175, 1769, -1851, 2862, 31, +2863, 1769, 1686, 2772, -128, 2803, -1799, 1882, +-2739, 382, -2628, -1073, -1526, -1918, 107, -1931, +1570, -1312, 2328, -323, 2173, 672, 1189, 1107, +-235, 918, -1518, 429, -2086, -181, -1781, -608, +-852, -515, 319, -103, 1242, 337, 1561, 735, +1315, 768, 686, 354, -224, -174, -1085, -784, +-1406, -1224, -1232, -1112, -804, -565, -40, 199, +798, 978, 1188, 1508, 1121, 1573, 768, 951, +168, -182, -419, -1184, -814, -1689, -1108, -1766, +-1159, -1196, -781, -12, -96, 1127, 675, 1811, +1258, 1879, 1339, 1320, 915, 428, 182, -631, +-651, -1598, -1244, -2022, -1368, -1788, -1047, -1095, +-402, -65, 332, 1083, 967, 1959, 1340, 2294, +1200, 1943, 542, 958, -351, -352, -1116, -1664, +-1417, -2495, -1102, -2485, -389, -1734, 344, -472, +887, 928, 1066, 1969, 825, 2422, 293, 2157, +-358, 1265, -883, 163, -1029, -899, -729, -1789, +-135, -2142, 483, -1806, 897, -1042, 913, -93, +393, 881, -359, 1548, -805, 1666, -880, 1313, +-699, 711, -188, 3, 463, -642, 830, -938, +781, -895, 428, -734, -149, -426, -709, -120, +-852, -28, -536, -20, -35, 59, 396, 232, +645, 537, 549, 894, 65, 1039, -472, 855, +-760, 386, -744, -375, -401, -1189, 160, -1714, +762, -1746, 1178, -1208, 1070, -241, 372, 912, +-562, 1876, -1337, 2258, -1654, 1959, -1288, 1012, +-387, -317, 633, -1528, 1441, -2223, 1716, -2252, +1304, -1618, 425, -522, -577, 718, -1435, 1763, +-1800, 2212, -1452, 1898, -512, 1135, 634, 172, +1476, -842, 1652, -1659, 1104, -1970, 140, -1602, +-777, -846, -1352, -50, -1434, 817, -971, 1556, +-145, 1761, 702, 1442, 1216, 780, 1245, -93, +836, -860, 124, -1355, -623, -1566, -1072, -1324, +-1050, -689, -725, 4, -317, 694, 75, 1274, +395, 1476, 582, 1318, 602, 862, 528, 85, +427, -711, 225, -1234, -71, -1484, -310, -1417, +-537, -900, -791, -56, -868, 743, -729, 1255, +-442, 1432, 81, 1235, 762, 694, 1263, -22, +1385, -622, 1108, -929, 402, -966, -558, -868, +-1340, -639, -1723, -250, -1631, 114, -1003, 351, +-5, 547, 953, 713, 1577, 851, 1762, 806, +1385, 474, 472, 23, -652, -413, -1529, -813, +-1757, -1072, -1316, -1038, -516, -671, 393, -177, +1131, 234, 1309, 630, 889, 1023, 205, 1059, +-458, 746, -882, 416, -879, 19, -486, -454, +84, -723, 592, -781, 838, -729, 665, -548, +107, -290, -581, -32, -1075, 209, -1153, 408, +-781, 563, -39, 629, 837, 633, 1507, 647, +1668, 533, 1174, 167, 179, -296, -991, -805, +-1970, -1317, -2372, -1520, -1970, -1234, -810, -542, +773, 412, 2203, 1309, 2972, 1904, 2770, 2039, +1565, 1529, -293, 503, -2159, -701, -3418, -1738, +-3562, -2182, -2430, -1933, -483, -1174, 1588, -78, +3232, 966, 3861, 1485, 3098, 1491, 1279, 1164, +-870, 589, -2711, 36, -3681, -323, -3403, -513, +-1941, -488, 95, -411, 1910, -469, 2959, -646, +2972, -834, 1994, -810, 436, -416, -1151, 283, +-2234, 1131, -2449, 1841, -1760, 2053, -481, 1572, +894, 485, 1787, -925, 1809, -2133, 1090, -2730, +-38, -2549, -1203, -1488, -1838, 142, -1601, 1683, +-680, 2677, 519, 2799, 1624, 2013, 2204, 713, +1914, -617, 813, -1607, -650, -2012, -2015, -1852, +-2838, -1296, -2719, -623, -1602, -80, 124, 386, +1864, 884, 3052, 1269, 3305, 1539, 2497, 1698, +857, 1482, -1074, 749, -2686, -389, -3536, -1682, +-3342, -2649, -2061, -2928, -130, -2373, 1779, -1004, +3129, 749, 3445, 2318, 2620, 3379, 1052, 3565, +-702, 2640, -2118, 922, -2767, -1030, -2556, -2822, +-1675, -3892, -389, -3740, 875, -2452, 1627, -506, +1760, 1554, 1437, 3137, 818, 3734, 161, 3164, +-301, 1726, -582, -90, -770, -1738, -918, -2742, +-1000, -2861, -886, -2136, -536, -914, -46, 359, +593, 1359, 1226, 1843, 1478, 1747, 1272, 1217, +809, 474, -11, -296, -1088, -839, -1842, -1047, +-1983, -987, -1551, -627, -515, -101, 862, 280, +1981, 537, 2407, 658, 1988, 509, 796, 185, +-733, -154, -2028, -480, -2673, -698, -2386, -699, +-1191, -446, 445, 52, 1933, 669, 2752, 1186, +2599, 1414, 1533, 1163, -43, 475, -1609, -470, +-2636, -1530, -2762, -2299, -2009, -2322, -726, -1619, +702, -368, 1950, 1193, 2674, 2529, 2604, 3202, +1721, 3063, 378, 1981, -979, 157, -2164, -1786, +-2865, -3316, -2690, -4044, -1761, -3605, -434, -2043, +1132, 188, 2473, 2409, 3033, 3916, 2776, 4298, +1792, 3468, 180, 1641, -1422, -582, -2511, -2560, +-3026, -3737, -2736, -3785, -1629, -2823, -212, -1227, +1170, 584, 2319, 2057, 2801, 2817, 2439, 2873, +1486, 2257, 266, 1090, -885, -153, -1703, -1156, +-2088, -1814, -2041, -1992, -1647, -1734, -1029, -1173, +-185, -403, 769, 299, 1583, 801, 2139, 1266, +2331, 1560, 1951, 1386, 1034, 950, -193, 390, +-1535, -414, -2718, -1176, -3283, -1522, -2886, -1466, +-1591, -1013, 260, -183, 2179, 703, 3568, 1254, +3877, 1342, 2904, 955, 1057, 187, -1034, -639, +-2876, -1085, -3901, -996, -3599, -540, -2177, 134, +-253, 841, 1694, 1154, 3098, 905, 3373, 388, +2594, -208, 1209, -865, -453, -1267, -1891, -1165, +-2578, -731, -2464, -171, -1789, 454, -742, 942, +470, 1145, 1531, 1133, 2072, 940, 1976, 522, +1414, -7, 529, -551, -506, -1059, -1371, -1405, +-1784, -1448, -1739, -1170, -1287, -611, -493, 137, +454, 930, 1249, 1627, 1650, 2027, 1567, 1906, +1085, 1281, 351, 264, -434, -926, -1053, -1905, +-1359, -2380, -1340, -2222, -1076, -1446, -575, -360, +104, 672, 719, 1487, 1114, 1949, 1273, 1903, +1143, 1479, 719, 896, 179, 261, -351, -368, +-799, -984, -1161, -1548, -1376, -1927, -1233, -2022, +-667, -1702, 6, -870, 646, 366, 1313, 1716, +1682, 2830, 1453, 3255, 869, 2719, 139, 1368, +-725, -428, -1484, -2245, -1791, -3504, -1536, -3701, +-875, -2747, -52, -1030, 770, 909, 1387, 2510, +1578, 3257, 1297, 2950, 730, 1841, 6, 339, +-697, -1054, -1160, -1902, -1301, -2071, -1100, -1635, +-582, -789, 34, 71, 534, 585, 840, 715, +903, 651, 737, 456, 419, 192, 25, 85, +-321, 232, -508, 344, -540, 245, -480, 26, +-386, -291, -308, -591, -194, -675, 11, -588, +277, -259, 542, 335, 843, 772, 1023, 755, +797, 439, 124, -88, -707, -727, -1441, -1122, +-1874, -992, -1675, -344, -745, 607, 548, 1442, +1740, 1862, 2459, 1661, 2396, 725, 1536, -620, +181, -1814, -1347, -2489, -2616, -2437, -3074, -1654, +-2525, -316, -1264, 1150, 425, 2206, 2087, 2645, +3039, 2564, 3003, 1860, 2212, 614, 841, -723, +-786, -1907, -2087, -2752, -2706, -2901, -2626, -2365, +-1931, -1280, -820, 194, 425, 1608, 1491, 2589, +2032, 2990, 2042, 2636, 1794, 1648, 1249, 380, +388, -942, -490, -2011, -1209, -2485, -1782, -2411, +-2046, -1884, -1882, -989, -1310, -12, -417, 839, +599, 1480, 1476, 1781, 2097, 1791, 2308, 1601, +1976, 1227, 1185, 727, 111, 101, -1057, -710, +-1986, -1565, -2404, -2314, -2342, -2799, -1904, -2677, +-1024, -1757, 230, -258, 1466, 1553, 2337, 3279, +2795, 4307, 2709, 4192, 1906, 2919, 539, 733, +-967, -1873, -2303, -4084, -3214, -5100, -3375, -4707, +-2621, -3070, -1146, -537, 700, 2117, 2425, 3947, +3438, 4534, 3452, 3933, 2611, 2382, 1147, 354, +-597, -1447, -2045, -2533, -2803, -2818, -2910, -2472, +-2398, -1730, -1300, -926, 70, -265, 1254, 338, +2050, 928, 2342, 1434, 2066, 1912, 1353, 2218, +466, 2023, -478, 1261, -1312, 132, -1746, -1215, +-1717, -2427, -1382, -3015, -831, -2815, -133, -1906, +542, -416, 1009, 1226, 1247, 2450, 1332, 2955, +1229, 2713, 812, 1742, 133, 347, -601, -945, +-1174, -1813, -1473, -2141, -1430, -1904, -1054, -1308, +-346, -568, 473, 194, 1074, 771, 1359, 1045, +1348, 1204, 925, 1243, 163, 997, -545, 563, +-929, 94, -997, -398, -797, -851, -410, -1178, +18, -1236, 372, -936, 535, -410, 407, 124, +136, 595, -125, 904, -330, 912, -307, 648, +80, 330, 522, 151, 768, 127, 808, 101, +492, -25, -277, -286, -1105, -693, -1637, -1168, +-1767, -1440, -1285, -1224, -160, -461, 1215, 646, +2342, 1788, 2811, 2559, 2362, 2561, 1079, 1622, +-646, -8, -2318, -1762, -3355, -3007, -3349, -3307, +-2298, -2534, -546, -936, 1423, 928, 2952, 2446, +3572, 3175, 3184, 2900, 1914, 1800, 67, 281, +-1705, -1248, -2819, -2287, -3118, -2462, -2628, -1932, +-1461, -1000, -39, 77, 1172, 871, 1997, 1116, +2289, 1011, 1926, 773, 1162, 532, 415, 456, +-160, 550, -650, 573, -970, 357, -1126, -135, +-1313, -875, -1533, -1685, -1451, -2144, -934, -1963, +-88, -1136, 963, 194, 2031, 1664, 2751, 2753, +2820, 3125, 2083, 2610, 604, 1294, -1224, -396, +-2854, -2005, -3790, -3200, -3677, -3532, -2426, -2801, +-373, -1315, 1789, 507, 3378, 2220, 3985, 3252, +3468, 3279, 1877, 2369, -260, 910, -2177, -629, +-3298, -1870, -3348, -2479, -2290, -2278, -597, -1512, +1033, -550, 2113, 375, 2329, 987, 1617, 1130, +413, 953, -694, 628, -1325, 383, -1269, 322, +-577, 294, 368, 249, 1115, 167, 1380, -141, +1007, -615, 26, -1015, -1100, -1248, -1815, -1208, +-1877, -773, -1378, -50, -380, 792, 872, 1491, +1909, 1771, 2303, 1561, 1995, 881, 1152, -89, +21, -949, -1144, -1505, -1980, -1670, -2147, -1316, +-1688, -525, -880, 361, 74, 1022, 922, 1240, +1363, 1011, 1358, 459, 1081, -276, 661, -848, +223, -875, -122, -454, -331, 163, -476, 781, +-572, 1126, -678, 1019, -766, 444, -752, -491, +-564, -1383, -238, -1850, 219, -1745, 758, -1015, +1186, 197, 1313, 1412, 1089, 2233, 578, 2415, +-94, 1831, -715, 652, -1098, -701, -1198, -1810, +-1079, -2341, -779, -2203, -311, -1465, 174, -343, +573, 768, 837, 1521, 971, 1773, 969, 1490, +818, 846, 471, 154, 82, -381, -333, -708, +-855, -723, -1207, -478, -1138, -271, -920, -241, +-669, -262, -114, -310, 599, -386, 1054, -315, +1230, -40, 1253, 268, 1050, 626, 533, 1001, +-148, 1127, -754, 953, -1169, 637, -1386, 147, +-1269, -566, -861, -1294, -312, -1721, 332, -1766, +985, -1443, 1335, -727, 1295, 292, 982, 1336, +467, 2186, -122, 2578, -567, 2205, -823, 1226, +-942, 17, -861, -1360, -591, -2495, -271, -2818, +29, -2393, 314, -1481, 488, -193, 441, 1056, +369, 1888, 459, 2292, 608, 2193, 616, 1559, +497, 741, 185, -30, -428, -744, -1149, -1360, +-1562, -1801, -1570, -1996, -1162, -1866, -237, -1330, +960, -358, 1906, 856, 2282, 1987, 1962, 2681, +975, 2659, -333, 1852, -1509, 507, -2180, -958, +-2108, -2068, -1426, -2503, -419, -2232, 654, -1356, +1489, -150, 1804, 841, 1586, 1327, 871, 1327, +-73, 900, -861, 322, -1336, 5, -1387, -2, +-862, 155, -82, 392, 495, 510, 836, 222, +960, -445, 747, -1142, 293, -1562, -191, -1622, +-614, -1178, -846, -159, -773, 1028, -489, 1839, +-70, 2110, 386, 1795, 680, 937, 695, -126, +626, -1003, 534, -1454, 301, -1386, -73, -1025, +-448, -624, -808, -195, -1062, 145, -1023, 182, +-667, 144, -132, 311, 471, 591, 1041, 863, +1387, 1094, 1333, 1107, 907, 781, 282, 136, +-401, -690, -1019, -1412, -1363, -1760, -1323, -1698, +-972, -1253, -517, -481, -52, 432, 409, 1186, +856, 1610, 1136, 1716, 1172, 1500, 1047, 941, +807, 283, 360, -266, -259, -781, -853, -1266, +-1286, -1539, -1524, -1611, -1518, -1484, -1214, -1007, +-605, -214, 256, 698, 1198, 1590, 1951, 2237, +2350, 2431, 2220, 2082, 1469, 1204, 228, -53, +-1175, -1388, -2393, -2493, -3010, -3044, -2804, -2825, +-1851, -1890, -418, -486, 1130, 1044, 2371, 2296, +2998, 2962, 2816, 2872, 1841, 2138, 470, 1002, +-844, -351, -1906, -1565, -2462, -2246, -2268, -2407, +-1489, -2123, -534, -1396, 378, -467, 1108, 398, +1505, 1178, 1451, 1715, 1036, 1868, 479, 1752, +22, 1365, -246, 648, -355, -213, -417, -1017, +-445, -1617, -420, -1885, -463, -1750, -612, -1251, +-621, -480, -380, 403, -35, 1213, 395, 1701, +868, 1700, 1109, 1346, 1048, 806, 789, 13, +279, -812, -457, -1256, -1001, -1296, -1118, -1104, +-946, -650, -584, -11, 2, 513, 535, 752, +657, 705, 421, 370, 146, -30, -106, -260, +-309, -323, -212, -206, 200, 131, 595, 480, +773, 651, 738, 633, 381, 393, -312, -76, +-1005, -625, -1394, -1144, -1386, -1448, -1012, -1342, +-319, -845, 551, -1, 1365, 1103, 1753, 2036, +1617, 2387, 1102, 2044, 303, 1096, -630, -279, +-1304, -1712, -1514, -2686, -1334, -2782, -851, -1996, +-214, -696, 317, 713, 609, 1879, 687, 2393, +629, 2096, 550, 1209, 529, 190, 536, -635, +477, -1141, 211, -1195, -236, -833, -722, -424, +-1051, -193, -1125, -130, -949, -182, -552, -250, +69, -149, 714, 197, 1159, 710, 1333, 1156, +1142, 1284, 571, 1041, -146, 441, -761, -435, +-1109, -1221, -1022, -1660, -594, -1629, -89, -1066, +363, -219, 597, 600, 515, 1254, 243, 1476, +-62, 1170, -339, 640, -434, 81, -326, -470, +-45, -747, 348, -701, 721, -534, 883, -295, +747, -95, 310, -80, -317, -71, -936, 17, +-1371, 86, -1433, 219, -998, 490, -202, 650, +669, 539, 1417, 238, 1795, -142, 1548, -502, +833, -710, 0, -714, -780, -463, -1348, -7, +-1404, 413, -1047, 594, -563, 578, -26, 377, +472, -24, 676, -420, 612, -595, 431, -531, +225, -201, 119, 267, 181, 625, 360, 779, +514, 680, 432, 236, 46, -366, -512, -859, +-1097, -1113, -1496, -1003, -1419, -504, -872, 181, +-10, 852, 994, 1252, 1802, 1207, 2055, 821, +1801, 211, 1103, -538, 14, -1047, -1136, -1096, +-1892, -857, -2125, -446, -1869, 98, -1132, 508, +-104, 622, 893, 509, 1639, 282, 1957, 94, +1725, 53, 1070, 66, 220, 94, -623, 131, +-1215, 53, -1418, -180, -1235, -422, -774, -619, +-199, -709, 283, -555, 598, -169, 661, 299, +539, 772, 419, 1103, 330, 1096, 204, 710, +148, 85, 119, -570, -23, -1025, -190, -1197, +-362, -1052, -601, -562, -722, 91, -565, 607, +-256, 894, 92, 923, 488, 677, 813, 276, +901, -79, 693, -308, 317, -370, -102, -305, +-461, -264, -688, -324, -685, -379, -509, -314, +-213, -132, 118, 107, 314, 408, 327, 653, +318, 679, 272, 449, 77, 90, -84, -252, +-45, -488, 29, -568, 48, -446, 119, -178, +142, 100, -33, 239, -243, 217, -361, 81, +-375, -65, -254, -122, -3, -48, 241, 137, +426, 343, 467, 420, 312, 312, 76, 44, +-85, -287, -186, -560, -224, -645, -158, -494, +-37, -173, 38, 208, 20, 529, -33, 641, +-53, 517, -105, 217, -174, -148, -98, -422, +124, -450, 256, -267, 305, -11, 384, 238, +383, 385, 139, 318, -164, 55, -385, -301, +-538, -556, -553, -603, -344, -440, -39, -59, +219, 467, 414, 908, 529, 1065, 496, 833, +325, 277, 89, -397, -136, -992, -302, -1345, +-379, -1221, -345, -671, -205, 15, -60, 709, +50, 1243, 124, 1334, 182, 1026, 197, 472, +183, -232, 129, -848, 43, -1122, -53, -1036, +-68, -661, -11, -110, 16, 416, 0, 726, +32, 704, 60, 383, -40, 9, -183, -281, +-238, -392, -233, -194, -160, 211, 41, 555, +318, 637, 503, 336, 530, -259, 370, -876, +76, -1231, -236, -1138, -432, -529, -513, 370, +-444, 1187, -224, 1606, 43, 1443, 219, 765, +307, -139, 361, -996, 334, -1482, 183, -1390, +21, -845, -30, -143, -48, 520, -129, 949, +-159, 971, -91, 648, -83, 229, -143, -142, +-58, -373, 65, -410, 65, -280, 62, -80, +140, 101, 115, 150, 12, 52, -25, -113, +-1, -280, 63, -363, 194, -241, 315, 27, +313, 335, 137, 607, -193, 676, -554, 449, +-792, 80, -803, -313, -500, -663, 49, -813, +690, -662, 1226, -316, 1445, 134, 1171, 564, +500, 804, -348, 762, -1178, 492, -1744, 71, +-1689, -387, -1007, -737, -101, -832, 738, -658, +1426, -286, 1685, 197, 1302, 697, 574, 990, +-108, 906, -666, 508, -996, -39, -947, -643, +-607, -1100, -195, -1170, 137, -822, 249, -229, +193, 450, 120, 1015, 77, 1273, 37, 1138, +154, 629, 430, -102, 629, -738, 618, -1073, +442, -1081, 41, -801, -532, -336, -1005, 115, +-1157, 430, -965, 592, -461, 655, 219, 656, +823, 582, 1155, 399, 1155, 114, 837, -267, +328, -650, -191, -893, -558, -911, -715, -713, +-628, -293, -371, 259, -121, 734, -33, 952, +-24, 889, -33, 588, -80, 145, -74, -281, +157, -515, 551, -538, 870, -415, 963, -228, +786, -68, 316, -4, -360, -34, -1006, -111, +-1397, -133, -1424, -56, -1022, 113, -292, 343, +521, 607, 1191, 765, 1585, 690, 1512, 360, +1022, -156, 330, -715, -411, -1146, -1024, -1343, +-1246, -1159, -1106, -565, -787, 254, -311, 1052, +242, 1620, 602, 1731, 679, 1314, 635, 514, +542, -444, 369, -1268, 171, -1655, 14, -1567, +-89, -1095, -193, -367, -282, 406, -340, 998, +-323, 1274, -227, 1183, -119, 824, -85, 328, +-36, -186, 101, -574, 250, -711, 320, -662, +366, -518, 426, -329, 425, -154, 282, -17, +48, 99, -158, 185, -316, 313, -504, 470, +-635, 540, -565, 478, -329, 309, -48, 7, +260, -348, 517, -602, 680, -679, 728, -564, +640, -269, 433, 51, 199, 293, -122, 413, +-534, 397, -814, 281, -848, 145, -776, 24, +-555, -38, -95, -36, 409, -21, 780, -40, +1054, -86, 1143, -186, 909, -302, 432, -332, +-151, -227, -765, -23, -1171, 236, -1194, 458, +-893, 524, -375, 365, 266, 91, 770, -202, +983, -445, 920, -503, 641, -313, 207, -18, +-196, 260, -428, 463, -452, 477, -323, 236, +-162, -111, -40, -413, 47, -569, 35, -527, +-63, -310, -58, 20, 77, 378, 143, 616, +167, 673, 278, 558, 371, 305, 284, -54, +145, -419, 6, -681, -195, -730, -433, -582, +-537, -339, -440, -54, -155, 240, 237, 424, +569, 505, 675, 570, 548, 607, 270, 533, +-121, 335, -504, -6, -659, -458, -522, -882, +-195, -1105, 209, -1035, 614, -635, 815, -14, +672, 622, 245, 1040, -257, 1134, -682, 918, +-866, 498, -692, 24, -216, -339, 327, -529, +734, -586, 903, -570, 772, -494, 332, -412, +-236, -329, -641, -169, -730, 62, -574, 272, +-230, 490, 225, 717, 630, 866, 761, 868, +550, 689, 125, 268, -297, -340, -617, -1017, +-732, -1578, -538, -1755, -82, -1391, 427, -583, +807, 488, 945, 1519, 808, 2142, 417, 2124, +-143, 1472, -687, 375, -995, -791, -1023, -1655, +-773, -1984, -265, -1689, 358, -915, 841, -20, +1062, 709, 1019, 1093, 760, 1058, 330, 692, +-131, 259, -485, -30, -699, -96, -796, 24, +-732, 193, -512, 219, -185, 33, 121, -338, +351, -791, 556, -1138, 773, -1120, 866, -672, +794, 58, 611, 842, 260, 1490, -283, 1777, +-835, 1491, -1218, 653, -1305, -366, -1019, -1244, +-448, -1771, 248, -1757, 968, -1161, 1498, -240, +1634, 662, 1323, 1245, 645, 1365, -276, 1062, +-1083, 504, -1475, -116, -1407, -562, -943, -733, +-202, -636, 505, -350, 933, -18, 1038, 226, +805, 332, 342, 256, -82, 48, -323, -182, +-375, -329, -217, -337, 100, -180, 335, 67, +349, 324, 144, 514, -176, 551, -526, 417, +-727, 181, -620, -134, -231, -463, 260, -692, +748, -715, 1078, -547, 1045, -254, 669, 120, +129, 509, -456, 744, -907, 746, -996, 573, +-722, 288, -305, -93, 145, -437, 517, -633, +678, -657, 561, -498, 312, -188, 80, 130, +-71, 363, -152, 464, -113, 388, 19, 145, +108, -108, 101, -254, 79, -249, 36, -73, +-82, 221, -213, 472, -270, 522, -300, 284, +-260, -166, -88, -682, 182, -1039, 468, -1019, +736, -556, 843, 160, 708, 883, 402, 1380, +-38, 1425, -625, 940, -1132, 125, -1258, -737, +-989, -1345, -476, -1514, 233, -1204, 980, -495, +1454, 362, 1442, 1020, 1060, 1283, 499, 1129, +-162, 663, -853, 47, -1268, -513, -1216, -849, +-866, -875, -379, -654, 246, -294, 766, 110, +910, 441, 786, 577, 593, 525, 319, 339, +41, 95, -118, -146, -193, -294, -286, -345, +-307, -323, -264, -245, -246, -109, -250, 61, +-178, 246, -24, 378, 176, 404, 389, 311, +554, 124, 588, -148, 486, -416, 294, -576, +17, -542, -295, -306, -483, 43, -506, 361, +-452, 599, -356, 660, -103, 478, 233, 149, +492, -174, 602, -436, 593, -593, 426, -598, +119, -411, -193, -91, -368, 234, -404, 459, +-336, 553, -140, 448, 114, 188, 295, -74, +357, -230, 283, -252, 113, -153, -84, -60, +-212, -44, -246, -100, -129, -175, 66, -229, +242, -189, 353, -15, 391, 270, 312, 526, +145, 624, -78, 508, -319, 191, -461, -268, +-433, -689, -273, -902, -15, -767, 285, -314, +516, 220, 549, 618, 438, 821, 275, 743, +90, 393, -136, -40, -294, -361, -334, -533, +-285, -522, -181, -346, -52, -118, 34, 44, +99, 148, 195, 215, 282, 222, 311, 182, +332, 179, 324, 160, 226, 71, 5, -66, +-242, -215, -419, -325, -451, -289, -366, -136, +-167, 39, 139, 214, 454, 345, 617, 292, +555, 65, 297, -194, -28, -357, -255, -379, +-339, -217, -304, 86, -126, 410, 88, 615, +214, 581, 229, 256, 190, -194, 87, -594, +-24, -853, -125, -857, -171, -507, -96, 45, +77, 586, 254, 1001, 377, 1151, 379, 873, +214, 266, -34, -413, -265, -947, -420, -1203, +-411, -1070, -218, -570, 90, 106, 350, 674, +507, 942, 520, 874, 368, 575, 74, 161, +-183, -215, -319, -402, -365, -357, -296, -225, +-101, -154, 100, -181, 228, -254, 334, -319, +363, -286, 272, -91, 203, 254, 149, 641, +-27, 908, -288, 859, -434, 489, -468, -63, +-349, -675, -25, -1179, 406, -1278, 743, -898, +871, -226, 701, 508, 275, 1103, -253, 1326, +-717, 1081, -943, 462, -849, -271, -478, -844, +110, -1094, 730, -991, 1116, -536, 1080, 89, +690, 605, 107, 828, -455, 735, -832, 380, +-874, -93, -570, -477, -88, -587, 377, -416, +701, -90, 730, 227, 414, 401, -64, 325, +-442, 55, -532, -211, -270, -304, 189, -202, +621, 27, 795, 269, 606, 386, 100, 228, +-495, -137, -948, -457, -1024, -546, -640, -395, +35, -28, 712, 455, 1171, 797, 1242, 780, +844, 441, 129, -96, -566, -630, -953, -921, +-918, -860, -567, -540, -60, -55, 365, 453, +575, 772, 550, 822, 380, 689, 133, 398, +-52, 19, -109, -339, -98, -599, -44, -747, +57, -739, 110, -536, 57, -194, -2, 164, +-19, 505, -15, 769, 35, 860, 50, 746, +10, 465, -43, 14, -56, -470, -24, -826, +113, -1037, 245, -1038, 286, -678, 281, -70, +219, 535, 69, 997, -67, 1237, -160, 1127, +-277, 645, -333, -51, -237, -698, -59, -1094, +146, -1124, 332, -810, 414, -284, 341, 259, +219, 633, 83, 697, -5, 503, -1, 227, +49, 11, 26, -65, -53, 17, -136, 126, +-251, 146, -376, 16, -373, -260, -157, -586, +181, -752, 517, -639, 801, -277, 899, 226, +696, 716, 219, 1002, -306, 987, -735, 659, +-947, 114, -878, -464, -504, -862, 56, -1004, +584, -869, 879, -464, 863, 87, 580, 544, +165, 781, -217, 768, -410, 516, -314, 90, +-38, -319, 155, -539, 235, -508, 197, -254, +-21, 126, -337, 429, -478, 490, -424, 267, +-251, -149, 72, -588, 541, -801, 940, -670, +1046, -227, 846, 383, 410, 924, -193, 1134, +-786, 938, -1149, 406, -1180, -287, -875, -904, +-257, -1191, 435, -1050, 976, -560, 1228, 60, +1121, 588, 669, 855, 123, 797, -302, 474, +-547, 72, -565, -232, -384, -331, -184, -256, +-120, -83, -141, 71, -147, 118, -106, 25, +19, -189, 220, -437, 504, -528, 761, -401, +831, -110, 656, 314, 376, 779, -40, 1009, +-575, 890, -966, 480, -1064, -135, -922, -767, +-522, -1132, 91, -1122, 679, -761, 1096, -179, +1257, 420, 1065, 800, 609, 852, 54, 619, +-447, 263, -788, -59, -853, -196, -679, -135, +-354, -13, -33, 51, 170, 7, 220, -254, +219, -623, 290, -809, 421, -686, 548, -323, +629, 250, 583, 893, 343, 1335, -36, 1352, +-436, 935, -797, 193, -979, -644, -897, -1303, +-545, -1588, -20, -1422, 584, -787, 1063, 104, +1235, 875, 1075, 1296, 694, 1341, 158, 987, +-420, 369, -820, -261, -964, -695, -893, -825, +-569, -665, -69, -376, 358, -83, 568, 122, +673, 179, 646, 85, 463, -50, 245, -103, +129, -1, 2, 217, -175, 476, -290, 645, +-325, 607, -354, 325, -330, -147, -178, -699, +16, -1070, 165, -1084, 322, -745, 491, -142, +561, 528, 453, 979, 282, 1113, 68, 941, +-184, 512, -398, -42, -482, -523, -465, -825, +-300, -882, -14, -728, 239, -396, 426, 77, +581, 524, 591, 735, 379, 698, 75, 453, +-204, 90, -456, -284, -588, -547, -462, -571, +-64, -333, 341, -12, 590, 266, 641, 453, +478, 459, 102, 238, -277, -68, -471, -333, +-502, -466, -374, -422, -59, -229, 307, 17, +536, 257, 623, 428, 544, 485, 215, 384, +-195, 157, -466, -124, -538, -364, -427, -503, +-89, -486, 263, -296, 442, 22, 487, 310, +452, 451, 239, 430, -102, 267, -350, -22, +-426, -295, -351, -422, -88, -351, 280, -108, +526, 189, 533, 374, 354, 400, 53, 263, +-221, 6, -383, -261, -381, -399, -242, -391, +-21, -270, 179, -82, 324, 104, 378, 225, +301, 338, 158, 412, 37, 345, -38, 172, +-50, 17, -3, -175, 4, -400, -75, -505, +-127, -427, -145, -271, -136, -69, -48, 163, +133, 355, 259, 425, 317, 413, 342, 346, +287, 205, 162, 16, 51, -150, -57, -331, +-165, -493, -213, -530, -254, -418, -311, -201, +-247, 133, -55, 455, 149, 615, 338, 595, +537, 405, 566, 49, 412, -307, 238, -496, +81, -462, -152, -252, -361, 33, -465, 228, +-529, 232, -474, 54, -231, -186, 92, -354, +411, -296, 680, 15, 777, 397, 667, 648, +459, 697, 134, 466, -250, -26, -568, -589, +-709, -955, -679, -960, -459, -598, -115, -44, +222, 517, 463, 911, 610, 966, 684, 631, +649, 98, 485, -382, 197, -640, -197, -641, +-580, -404, -789, -49, -725, 246, -442, 342, +-15, 238, 383, 4, 633, -190, 689, -228, +609, -106, 397, 105, 84, 331, -207, 440, +-370, 353, -405, 102, -352, -226, -216, -527, +-43, -643, 116, -514, 268, -175, 395, 239, +438, 574, 340, 689, 174, 530, -52, 155, +-297, -254, -444, -504, -381, -496, -175, -289, +92, 4, 356, 250, 537, 351, 571, 252, +419, 27, 92, -201, -279, -327, -533, -304, +-583, -124, -415, 129, -78, 359, 254, 462, +490, 394, 584, 177, 531, -106, 311, -387, +29, -569, -186, -567, -304, -358, -343, -33, +-275, 335, -99, 627, 55, 695, 105, 489, +107, 112, 140, -309, 199, -585, 199, -582, +187, -357, 216, -66, 248, 239, 160, 423, +-1, 349, -189, 108, -383, -109, -482, -256, +-359, -284, -59, -118, 271, 175, 542, 381, +621, 396, 428, 212, 114, -103, -128, -431, +-266, -601, -289, -513, -139, -191, 64, 238, +199, 596, 215, 705, 118, 560, -98, 202, +-287, -294, -289, -710, -83, -783, 189, -527, +396, -100, 511, 375, 438, 731, 154, 761, +-116, 473, -209, 9, -228, -433, -247, -664, +-158, -617, -20, -384, 36, -41, 7, 299, +43, 479, 102, 445, 135, 285, 224, 94, +371, -25, 429, -84, 351, -125, 159, -156, +-147, -181, -444, -242, -596, -306, -604, -308, +-444, -170, -82, 90, 353, 384, 663, 625, +820, 741, 767, 622, 477, 257, 52, -261, +-318, -778, -555, -1078, -596, -992, -439, -582, +-222, 13, -27, 622, 147, 1026, 243, 1046, +254, 727, 273, 229, 323, -255, 365, -573, +424, -662, 393, -578, 178, -375, -188, -135, +-547, 32, -803, 93, -842, 150, -567, 230, +-44, 292, 516, 329, 930, 341, 1119, 261, +1006, 104, 581, -90, -23, -273, -616, -399, +-984, -441, -1011, -407, -719, -279, -244, -91, +270, 99, 605, 267, 726, 413, 688, 483, +531, 448, 289, 318, 45, 153, -177, -46, +-379, -277, -469, -475, -413, -565, -269, -557, +-85, -447, 88, -231, 202, 79, 283, 410, +382, 666, 396, 771, 337, 703, 249, 447, +98, 56, -144, -354, -313, -667, -357, -825, +-374, -772, -324, -538, -139, -182, 119, 210, +339, 555, 470, 739, 508, 722, 426, 530, +237, 238, 9, -99, -181, -389, -302, -525, +-327, -478, -320, -350, -264, -187, -137, -15, +29, 85, 211, 87, 425, 79, 563, 93, +535, 140, 381, 227, 107, 332, -232, 354, +-477, 280, -573, 121, -506, -129, -275, -439, +28, -684, 291, -765, 512, -614, 599, -232, +522, 280, 326, 745, 81, 1029, -165, 985, +-378, 573, -493, -43, -455, -610, -282, -951, +-61, -956, 166, -636, 408, -110, 572, 403, +558, 703, 369, 691, 129, 438, -130, 62, +-373, -290, -520, -466, -474, -421, -287, -218, +-21, 80, 277, 323, 506, 405, 561, 312, +445, 94, 234, -171, -35, -351, -292, -408, +-390, -325, -315, -107, -162, 142, 1, 284, +125, 317, 159, 254, 161, 137, 123, 27, +87, -68, 126, -134, 211, -114, 244, -69, +203, -60, 60, -72, -190, -74, -417, -107, +-531, -123, -474, -73, -153, 43, 306, 185, +655, 294, 796, 291, 697, 183, 316, 20, +-149, -128, -501, -220, -657, -213, -588, -122, +-307, -24, 17, 15, 276, -5, 467, -107, +480, -223, 311, -235, 138, -64, 23, 208, +-65, 494, -81, 693, -20, 675, 3, 359, +-52, -162, -153, -693, -232, -1046, -262, -1093, +-159, -741, 77, -111, 339, 553, 522, 1047, +561, 1211, 422, 953, 132, 407, -170, -191, +-394, -661, -525, -906, -482, -852, -288, -556, +-19, -163, 267, 181, 463, 408, 482, 474, +387, 377, 214, 207, 24, 77, -106, -4, +-144, -24, -134, 11, -117, 50, -125, 14, +-159, -87, -161, -222, -106, -344, -9, -405, +124, -356, 294, -175, 479, 132, 563, 463, +468, 689, 183, 701, -223, 475, -612, 75, +-772, -359, -669, -679, -357, -750, 124, -563, +593, -197, 844, 173, 795, 402, 521, 437, +131, 329, -274, 143, -547, -8, -607, -54, +-451, 1, -169, 69, 104, 62, 279, -61, +366, -225, 328, -336, 176, -335, 31, -210, +-38, 27, -61, 272, -12, 419, 119, 410, +205, 276, 156, 39, -5, -221, -221, -391, +-381, -396, -428, -254, -311, -5, 5, 240, +399, 368, 669, 331, 742, 143, 568, -128, +193, -312, -266, -334, -638, -245, -748, -86, +-555, 147, -193, 337, 159, 372, 413, 239, +501, 38, 432, -160, 278, -303, 88, -331, +-33, -206, -53, -5, -65, 181, -102, 269, +-102, 226, -120, 88, -160, -70, -174, -211, +-123, -270, 9, -200, 192, -11, 351, 189, +397, 311, 325, 301, 167, 183, -39, 1, +-189, -160, -257, -246, -256, -257, -166, -214, +-22, -130, 62, -64, 86, -11, 97, 68, +92, 190, 56, 300, 48, 372, 113, 360, +207, 233, 255, -10, 217, -296, 107, -544, +-64, -659, -272, -588, -414, -324, -427, 40, +-306, 409, -76, 705, 213, 823, 477, 682, +616, 354, 562, -65, 373, -479, 85, -799, +-221, -870, -429, -660, -533, -259, -518, 193, +-328, 579, -51, 750, 177, 630, 396, 311, +571, -23, 524, -267, 335, -342, 132, -252, +-121, -78, -369, 45, -441, 41, -363, -73, +-198, -197, 50, -257, 277, -191, 362, -13, +304, 238, 172, 432, -23, 455, -200, 309, +-256, 107, -190, -99, -19, -280, 186, -363, +352, -334, 429, -264, 341, -161, 69, -30, +-271, 110, -560, 239, -653, 315, -460, 282, +-72, 174, 345, 33, 706, -84, 853, -148, +672, -120, 277, -32, -181, 51, -596, 35, +-815, -90, -741, -245, -382, -348, 131, -330, +540, -117, 698, 234, 633, 583, 342, 740, +-48, 608, -339, 221, -425, -273, -305, -671, +-80, -776, 135, -571, 277, -182, 282, 197, +106, 405, -121, 355, -258, 145, -282, -36, +-124, -67, 150, 65, 353, 294, 402, 450, +305, 375, 81, 42, -155, -411, -290, -843, +-291, -1020, -165, -752, -4, -124, 94, 573, +125, 1092, 127, 1224, 95, 895, 30, 239, +34, -480, 133, -988, 217, -1074, 186, -770, +58, -247, -115, 298, -304, 666, -420, 720, +-357, 500, -121, 111, 186, -236, 439, -390, +573, -348, 530, -164, 304, 89, -19, 264, +-373, 295, -636, 199, -629, -2, -379, -242, +-25, -395, 375, -405, 678, -250, 680, 12, +434, 312, 81, 540, -298, 573, -585, 359, +-609, 10, -333, -371, 69, -617, 405, -592, +561, -337, 495, 28, 211, 384, -136, 562, +-360, 466, -435, 172, -344, -140, -146, -358, +75, -413, 280, -296, 447, -33, 506, 224, +404, 347, 147, 298, -185, 150, -447, -25, +-569, -177, -516, -291, -281, -283, 15, -138, +282, 1, 507, 80, 620, 174, 551, 226, +377, 174, 104, 71, -274, -5, -566, -70, +-629, -123, -511, -139, -248, -68, 64, 33, +299, 93, 425, 75, 426, -46, 284, -233, +163, -327, 139, -228, 47, 74, -60, 473, +-60, 726, -121, 645, -277, 244, -324, -347, +-278, -849, -247, -1013, -103, -750, 157, -188, +389, 455, 543, 888, 595, 952, 478, 671, +172, 166, -192, -363, -461, -671, -551, -679, +-474, -455, -288, -119, -79, 191, 69, 354, +184, 338, 270, 187, 319, 28, 334, -70, +294, -83, 205, -47, 109, 5, 31, 13, +-67, -4, -196, -5, -333, -2, -458, 10, +-496, 15, -384, -48, -100, -137, 286, -171, +606, -132, 732, -36, 671, 150, 488, 333, +205, 356, -145, 211, -472, 25, -697, -155, +-757, -282, -651, -323, -380, -255, 63, -126, +536, -20, 776, 35, 758, 100, 632, 213, +381, 304, 28, 316, -287, 269, -509, 118, +-598, -127, -539, -392, -385, -545, -157, -513, +152, -277, 374, 70, 433, 416, 445, 618, +393, 566, 247, 273, 65, -94, -129, -385, +-316, -504, -400, -415, -332, -170, -144, 116, +86, 318, 223, 361, 243, 308, 158, 149, +-17, -93, -159, -318, -141, -430, -14, -419, +107, -240, 232, 77, 315, 400, 290, 634, +171, 683, -85, 455, -396, 28, -548, -442, +-475, -808, -253, -918, 102, -678, 482, -203, +615, 323, 456, 727, 194, 926, -78, 818, +-292, 446, -323, -19, -187, -436, -10, -723, +152, -761, 245, -546, 182, -232, -25, 92, +-268, 361, -438, 425, -422, 329, -133, 226, +291, 159, 644, 95, 797, 72, 646, 68, +263, 12, -217, -148, -630, -335, -841, -488, +-825, -533, -601, -392, -169, -65, 404, 333, +866, 668, 1030, 806, 861, 677, 403, 339, +-153, -96, -564, -517, -714, -735, -644, -724, +-442, -558, -196, -265, 32, 120, 223, 450, +396, 642, 525, 658, 500, 485, 345, 178, +128, -148, -102, -406, -264, -523, -393, -482, +-460, -324, -360, -113, -163, 103, 41, 270, +265, 377, 444, 378, 440, 282, 298, 119, +99, -69, -126, -245, -247, -327, -241, -326, +-179, -272, -78, -117, 21, 123, 66, 321, +59, 421, 51, 372, 74, 132, 85, -168, +54, -350, 63, -398, 63, -273, -7, -19, +-28, 212, -19, 279, -40, 215, -53, 65, +-19, -83, 26, -148, 39, -131, 47, -44, +9, 94, -58, 180, -83, 133, -25, -18, +100, -154, 217, -226, 285, -218, 212, -109, +-1, 90, -214, 238, -349, 256, -359, 153, +-203, 23, 1, -87, 173, -149, 348, -122, +423, -20, 364, 65, 213, 85, -58, 48, +-330, -71, -450, -224, -406, -274, -223, -223, +75, -34, 349, 283, 423, 531, 309, 558, +111, 405, -56, 60, -157, -368, -245, -675, +-221, -767, -72, -610, 85, -220, 210, 225, +289, 616, 278, 871, 112, 813, -193, 443, +-460, -28, -476, -517, -251, -839, 75, -824, +388, -550, 595, -155, 590, 323, 333, 690, +-16, 784, -352, 617, -611, 248, -676, -224, +-510, -595, -115, -715, 366, -570, 709, -222, +765, 190, 528, 509, 90, 646, -373, 538, +-570, 255, -482, -114, -284, -459, 12, -680, +284, -625, 319, -311, 200, 85, 116, 421, +22, 601, -98, 558, -147, 335, -119, 41, +-54, -210, 60, -353, 194, -394, 242, -368, +209, -234, 57, -39, -201, 112, -347, 189, +-336, 242, -211, 215, 31, 153, 276, 124, +404, 107, 413, 57, 319, -46, 73, -191, +-230, -312, -420, -349, -451, -286, -304, -127, +-45, 110, 234, 307, 431, 399, 407, 363, +211, 223, 29, 14, -104, -187, -226, -311, +-265, -294, -223, -185, -125, -50, 16, 66, +200, 125, 369, 123, 383, 84, 235, 32, +-45, 7, -333, 1, -454, -18, -376, -58, +-139, -40, 164, 1, 409, 40, 483, 88, +389, 105, 173, 28, -134, -105, -386, -234, +-491, -277, -443, -173, -171, 41, 213, 268, +489, 417, 593, 380, 486, 144, 148, -169, +-269, -404, -582, -462, -662, -296, -456, -39, +-47, 223, 413, 423, 710, 438, 724, 223, +454, -52, -19, -268, -473, -403, -720, -386, +-645, -200, -328, 42, 43, 269, 378, 417, +576, 407, 552, 252, 350, 36, 121, -234, +-123, -472, -386, -546, -496, -370, -415, -19, +-212, 360, 111, 570, 411, 541, 473, 314, +309, -52, 30, -390, -225, -530, -315, -494, +-267, -288, -81, 59, 200, 360, 410, 499, +437, 530, 263, 342, -57, -26, -469, -355, +-751, -554, -663, -581, -251, -348, 315, -25, +813, 250, 977, 493, 718, 575, 238, 450, +-262, 239, -675, -58, -836, -367, -765, -546, +-544, -596, -94, -507, 457, -194, 861, 199, +1038, 546, 841, 752, 270, 687, -333, 371, +-782, -58, -963, -518, -752, -789, -335, -717, +111, -421, 522, -17, 793, 400, 792, 636, +477, 612, -9, 394, -425, 100, -589, -201, +-507, -409, -237, -469, 46, -358, 190, -155, +248, 55, 212, 196, 142, 241, 106, 217, +31, 139, -43, 45, -52, 33, -64, 52, +-13, 14, 68, -63, -37, -174, -153, -289, +-94, -282, 19, -189, 131, -32, 147, 185, +37, 366, -52, 393, -51, 311, 27, 153, +170, -57, 263, -255, 166, -389, -55, -392, +-278, -265, -385, -98, -320, 100, -168, 279, +79, 338, 322, 278, 440, 158, 489, -1, +353, -81, -3, -82, -296, -74, -451, -82, +-491, -94, -313, -153, -69, -235, 149, -237, +391, -104, 465, 139, 344, 391, 149, 535, +-117, 499, -319, 239, -313, -138, -162, -488, +39, -670, 187, -586, 141, -250, 29, 124, +-20, 368, -69, 464, -57, 452, -25, 325, +-19, 130, 65, -69, 201, -238, 288, -326, +194, -331, -99, -283, -346, -170, -401, -27, +-299, 95, 31, 179, 380, 267, 429, 345, +307, 404, 114, 334, -144, 86, -310, -225, +-356, -510, -287, -694, -46, -634, 259, -338, +469, 76, 523, 510, 263, 811, -222, 827, +-542, 542, -557, 31, -321, -466, 56, -747, +411, -752, 617, -493, 507, -16, 172, 404, +-167, 535, -497, 375, -650, 79, -412, -151, +21, -229, 432, -146, 696, 97, 564, 329, +158, 348, -246, 139, -556, -152, -569, -411, +-301, -551, -6, -500, 276, -212, 502, 180, +485, 537, 299, 745, 19, 669, -335, 291, +-492, -194, -395, -608, -170, -809, 137, -631, +374, -167, 419, 328, 277, 664, 24, 674, +-190, 386, -316, -79, -341, -539, -164, -721, +140, -495, 383, -51, 493, 454, 306, 811, +-136, 764, -482, 319, -577, -322, -372, -877, +56, -1007, 439, -655, 622, -27, 576, 679, +250, 1125, -181, 1022, -504, 478, -683, -284, +-585, -962, -226, -1235, 240, -974, 683, -270, +799, 623, 552, 1265, 176, 1347, -284, 857, +-617, -5, -611, -893, -471, -1435, -242, -1374, +159, -706, 450, 230, 550, 1046, 509, 1446, +213, 1263, -111, 572, -278, -312, -353, -1083, +-226, -1362, 21, -1004, 80, -257, 33, 531, +13, 1030, -82, 1029, -117, 608, -45, -70, +19, -724, 150, -950, 328, -688, 404, -143, +311, 520, 67, 951, -281, 905, -596, 452, +-662, -258, -426, -959, -36, -1179, 384, -828, +695, -136, 670, 662, 377, 1211, 22, 1208, +-382, 695, -616, -101, -517, -896, -233, -1328, +175, -1132, 532, -425, 547, 457, 316, 1143, +-12, 1318, -433, 883, -641, 73, -509, -793, +-247, -1305, 173, -1178, 612, -535, 790, 316, +721, 1056, 402, 1308, -155, 981, -661, 291, +-894, -573, -849, -1220, -488, -1244, 62, -781, +559, -32, 843, 787, 825, 1230, 529, 1112, +56, 626, -391, -127, -619, -871, -598, -1215, +-346, -1045, 19, -451, 289, 332, 391, 962, +326, 1216, 67, 982, -207, 300, -299, -496, +-267, -1029, -93, -1113, 222, -740, 457, -104, +447, 556, 217, 923, -70, 859, -292, 497, +-391, -37, -368, -535, -255, -674, -90, -480, +96, -143, 248, 262, 329, 477, 356, 365, +247, 119, 49, -203, -40, -456, -96, -399, +-189, -158, -209, 123, -217, 443, -254, 540, +-133, 403, 109, 203, 294, -131, 381, -460, +289, -532, 75, -442, -81, -247, -197, 59, +-240, 289, -169, 380, -71, 375, 15, 228, +148, 57, 264, -60, 260, -162, 146, -201, +-35, -96, -230, 54, -361, 127, -326, 80, +-171, -32, -15, -192, 200, -367, 389, -390, +422, -179, 383, 188, 257, 565, -30, 745, +-295, 685, -455, 437, -553, -26, -459, -580, +-218, -915, 39, -973, 344, -747, 560, -248, +570, 337, 435, 841, 208, 1130, -44, 1010, +-252, 546, -415, -26, -511, -598, -472, -988, +-315, -1000, -66, -673, 243, -153, 518, 382, +631, 780, 476, 885, 179, 630, -140, 125, +-432, -397, -526, -724, -378, -690, -134, -317, +180, 212, 453, 681, 450, 832, 224, 546, +-113, -6, -463, -593, -555, -969, -383, -923, +-93, -476, 338, 219, 723, 937, 762, 1252, +483, 1008, 46, 374, -448, -422, -792, -1055, +-842, -1219, -587, -877, -84, -192, 401, 561, +688, 1038, 768, 1050, 612, 656, 246, 43, +-215, -573, -612, -980, -774, -944, -599, -471, +-148, 182, 381, 770, 700, 1064, 655, 870, +307, 296, -181, -420, -546, -986, -643, -1098, +-448, -726, -56, -20, 299, 754, 525, 1153, +616, 993, 473, 429, 130, -352, -246, -1000, +-572, -1081, -674, -623, -428, 107, -91, 791, +208, 1069, 465, 807, 462, 156, 238, -590, +14, -1039, -159, -978, -205, -465, -120, 317, +-23, 1009, 76, 1245, 141, 906, 99, 136, +-8, -679, -173, -1216, -300, -1281, -278, -746, +-154, 172, 28, 933, 234, 1282, 397, 1142, +454, 535, 366, -235, 134, -901, -151, -1230, +-368, -979, -466, -311, -428, 424, -325, 991, +-152, 1077, 94, 637, 249, -24, 354, -703, +490, -1048, 489, -756, 334, -53, 64, 674, +-309, 1119, -554, 979, -579, 341, -518, -501, +-288, -1271, 80, -1495, 348, -963, 524, 25, +601, 1088, 423, 1795, 67, 1761, -254, 979, +-455, -239, -449, -1415, -228, -2014, 53, -1809, +263, -865, 256, 460, 76, 1570, -134, 1998, +-299, 1583, -279, 517, -100, -686, 163, -1522, +478, -1668, 580, -1010, 405, 127, 94, 1106, +-386, 1485, -810, 1139, -798, 238, -482, -807, +-35, -1461, 538, -1372, 895, -598, 837, 498, +502, 1462, -91, 1786, -704, 1272, -950, 233, +-814, -956, -329, -1850, 409, -1941, 903, -1139, +919, 194, 530, 1480, -143, 2116, -732, 1799, +-902, 667, -664, -795, -211, -1854, 313, -2011, +749, -1237, 862, 163, 593, 1515, 71, 2126, +-485, 1776, -832, 592, -845, -951, -503, -2096, +113, -2350, 681, -1553, 833, 54, 578, 1698, +123, 2607, -375, 2402, -614, 1152, -484, -570, +-206, -1955, 138, -2464, 420, -1934, 345, -655, +71, 753, -169, 1712, -396, 1843, -367, 1209, +-46, 234, 249, -667, 495, -1105, 618, -904, +321, -332, -228, 283, -644, 640, -891, 499, +-799, 44, -260, -419, 400, -673, 905, -500, +1081, -17, 775, 445, 161, 794, -445, 892, +-870, 566, -979, 9, -692, -546, -197, -885, +279, -806, 630, -438, 690, 38, 387, 476, +-3, 600, -242, 414, -297, 155, -101, -89, +191, -147, 255, 46, 91, 200, -194, 185, +-532, 73, -655, -144, -419, -400, -77, -550, +307, -492, 725, -156, 881, 336, 665, 762, +219, 934, -345, 675, -832, 71, -979, -606, +-704, -1075, -153, -1039, 398, -455, 685, 363, +656, 1060, 374, 1322, -70, 960, -417, 149, +-493, -790, -371, -1459, -125, -1502, 199, -895, +466, 144, 491, 1236, 275, 1837, -67, 1675, +-416, 884, -630, -242, -587, -1235, -337, -1733, +-1, -1630, 330, -913, 534, 102, 545, 928, +392, 1374, 175, 1361, -34, 900, -252, 307, +-422, -272, -473, -743, -399, -820, -284, -652, +-140, -565, 65, -430, 254, -125, 387, 205, +458, 535, 402, 868, 198, 1052, -91, 915, +-349, 384, -502, -360, -460, -1046, -200, -1489, +69, -1405, 186, -668, 203, 384, 136, 1331, +-45, 1854, -201, 1653, -198, 728, -113, -533, +36, -1631, 322, -2095, 533, -1620, 467, -408, +182, 975, -320, 2003, -813, 2197, -951, 1405, +-731, 10, -224, -1410, 434, -2268, 873, -2026, +927, -790, 724, 684, 264, 1816, -398, 2195, +-852, 1497, -933, 71, -720, -1290, -173, -1979, +479, -1674, 815, -541, 746, 820, 355, 1810, +-247, 1940, -724, 1065, -804, -328, -615, -1553, +-202, -2151, 406, -1786, 824, -518, 886, 1051, +684, 2227, 80, 2496, -673, 1675, -1036, 104, +-1001, -1494, -620, -2460, 91, -2436, 663, -1363, +788, 280, 647, 1674, 261, 2299, -283, 2011, +-533, 903, -506, -482, -389, -1512, 7, -1864, +472, -1362, 602, -188, 431, 971, 4, 1585, +-556, 1440, -903, 525, -855, -640, -460, -1434, +135, -1615, 662, -1002, 903, 227, 809, 1330, +469, 1804, 17, 1626, -420, 798, -679, -415, +-684, -1429, -528, -1837, -249, -1494, 36, -527, +69, 573, -70, 1262, -113, 1339, -29, 896, +294, 140, 783, -518, 1014, -685, 819, -404, +256, 39, -560, 437, -1321, 549, -1664, 254, +-1435, -284, -772, -804, 143, -1018, 1125, -710, +1743, -55, 1683, 669, 1111, 1269, 178, 1370, +-921, 863, -1593, 121, -1523, -565, -948, -998, +-109, -1019, 648, -730, 952, -280, 779, 249, +233, 556, -446, 520, -776, 348, -636, 85, +-205, -161, 418, -123, 944, 140, 1048, 441, +725, 642, 1, 510, -941, 27, -1571, -544, +-1612, -1040, -1123, -1284, -175, -1025, 871, -297, +1547, 616, 1676, 1408, 1257, 1720, 422, 1429, +-525, 686, -1200, -308, -1430, -1224, -1322, -1606, +-855, -1297, -86, -629, 598, 74, 960, 707, +1021, 1030, 762, 892, 297, 497, -184, 58, +-610, -327, -792, -429, -693, -222, -497, 22, +-156, 180, 248, 199, 472, 34, 563, -138, +490, -272, 143, -349, -216, -190, -448, 79, +-625, 250, -627, 372, -360, 351, 0, 166, +284, 40, 530, -82, 642, -243, 480, -113, +189, 198, -155, 300, -516, 201, -714, -34, +-740, -353, -633, -587, -273, -670, 182, -498, +469, -9, 707, 593, 851, 1078, 581, 1305, +108, 1092, -298, 442, -733, -432, -1008, -1263, +-876, -1709, -526, -1544, -59, -836, 503, 192, +821, 1110, 719, 1600, 451, 1626, 96, 1151, +-343, 288, -572, -576, -519, -1136, -382, -1251, +-164, -915, 38, -337, 93, 218, 56, 579, +-49, 595, -154, 335, -54, 49, 209, -107, +359, -68, 404, 146, 340, 408, -120, 595, +-700, 517, -924, 88, -894, -520, -597, -1055, +94, -1284, 777, -1021, 1142, -292, 1175, 660, +701, 1476, -217, 1787, -1085, 1412, -1523, 545, +-1395, -463, -750, -1288, 159, -1687, 993, -1494, +1429, -724, 1270, 283, 602, 1070, -311, 1379, +-1117, 1200, -1502, 657, -1270, -61, -426, -655, +535, -875, 1133, -708, 1279, -325, 767, 77, +-245, 343, -1021, 413, -1247, 340, -1051, 236, +-431, 118, 433, -37, 1118, -177, 1316, -198, +890, -192, 10, -269, -867, -255, -1457, 5, +-1517, 365, -890, 633, 49, 732, 839, 618, +1337, 187, 1314, -461, 703, -1009, -76, -1234, +-748, -1035, -1283, -345, -1359, 605, -811, 1350, +-61, 1647, 541, 1434, 894, 676, 821, -386, +400, -1331, -75, -1767, -406, -1536, -496, -810, +-403, 169, -253, 1075, -72, 1522, 117, 1466, +115, 985, -127, 168, -295, -647, -306, -1120, +-205, -1211, 107, -907, 427, -278, 464, 431, +314, 978, 48, 1111, -349, 810, -597, 325, +-548, -327, -472, -924, -355, -1051, -29, -814, +271, -389, 389, 302, 392, 971, 239, 1291, +73, 1250, 24, 838, -82, 91, -243, -796, +-326, -1565, -493, -1819, -695, -1479, -559, -744, +-227, 407, 57, 1670, 534, 2373, 954, 2330, +885, 1608, 514, 320, -9, -1134, -687, -2296, +-1218, -2787, -1274, -2361, -879, -1197, -227, 353, +466, 1878, 874, 2807, 927, 2814, 742, 1973, +292, 464, -264, -1183, -633, -2333, -806, -2649, +-730, -2060, -371, -832, -11, 587, 185, 1771, +288, 2239, 167, 1845, -96, 853, -74, -413, +112, -1446, 164, -1730, 236, -1297, 151, -386, +-248, 740, -614, 1513, -804, 1538, -763, 938, +-365, -35, 229, -1022, 797, -1598, 1135, -1521, +980, -837, 333, 194, -494, 1207, -1297, 1786, +-1767, 1649, -1470, 901, -578, -118, 460, -1019, +1445, -1485, 1978, -1390, 1700, -809, 783, 46, +-446, 773, -1713, 1097, -2467, 1002, -2260, 482, +-1317, -212, 0, -655, 1444, -735, 2357, -398, +2382, 270, 1709, 850, 355, 1037, -1237, 727, +-2274, -71, -2618, -919, -2256, -1420, -1013, -1503, +590, -1013, 1765, 28, 2348, 1116, 2173, 1918, +1173, 2199, -140, 1671, -1336, 509, -2162, -771, +-2231, -1807, -1501, -2378, -303, -2226, 874, -1270, +1580, 60, 1640, 1288, 1073, 2178, 118, 2454, +-757, 1950, -1196, 911, -1104, -370, -629, -1561, +-19, -2169, 494, -2015, 682, -1318, 398, -326, +-199, 656, -732, 1407, -962, 1725, -761, 1406, +-109, 689, 694, -12, 1313, -583, 1427, -866, +852, -745, -136, -385, -1159, -26, -1932, 137, +-2136, -13, -1629, -250, -519, -313, 835, -232, +1939, -1, 2378, 448, 2000, 940, 967, 1198, +-341, 1120, -1524, 696, -2237, -149, -2284, -1160, +-1750, -1852, -828, -2012, 314, -1524, 1296, -394, +1817, 921, 1884, 1991, 1441, 2505, 567, 2183, +-361, 1199, -1156, -80, -1716, -1461, -1900, -2434, +-1596, -2525, -783, -1848, 227, -501, 1085, 1148, +1637, 2222, 1667, 2444, 1066, 1963, 74, 734, +-896, -856, -1521, -1984, -1601, -2281, -1100, -1763, +-202, -514, 772, 1040, 1360, 2214, 1234, 2567, +541, 1933, -420, 358, -1337, -1574, -1783, -2926, +-1461, -3194, -481, -2272, 730, -286, 1755, 2027, +2161, 3689, 1604, 4098, 322, 2972, -1118, 647, +-2236, -2005, -2591, -4018, -1976, -4554, -650, -3397, +833, -1066, 1940, 1696, 2276, 3859, 1677, 4450, +464, 3410, -832, 1266, -1706, -1314, -1797, -3238, +-1183, -3714, -183, -2751, 776, -792, 1174, 1383, +848, 2838, 42, 2969, -839, 1769, -1373, -116, +-1216, -1851, -360, -2727, 727, -2300, 1541, -787, +1762, 1067, 1126, 2530, -131, 2940, -1374, 2111, +-2146, 491, -2160, -1382, -1380, -2785, -163, -3014, +1111, -2218, 2010, -739, 2021, 1116, 1185, 2524, +62, 2938, -1089, 2457, -1955, 1231, -1920, -335, +-1014, -1647, 94, -2367, 960, -2298, 1429, -1528, +1281, -432, 428, 751, -586, 1617, -1245, 1868, +-1498, 1673, -1216, 1040, -406, 32, 518, -835, +1206, -1366, 1461, -1536, 1195, -1201, 477, -484, +-440, 400, -1207, 1216, -1628, 1592, -1666, 1433, +-1221, 781, -354, -333, 582, -1378, 1266, -1805, +1576, -1637, 1391, -853, 752, 449, 16, 1711, +-598, 2355, -1166, 2104, -1588, 1087, -1532, -356, +-1025, -1840, -417, -2710, 313, -2542, 1107, -1521, +1417, 82, 1122, 1822, 687, 2863, 256, 2858, +-332, 2039, -910, 547, -1204, -1228, -1262, -2501, +-1054, -2853, -489, -2334, 201, -1169, 709, 398, +943, 1849, 883, 2566, 587, 2454, 151, 1739, +-310, 546, -665, -822, -839, -1862, -812, -2241, +-499, -1950, 3, -1182, 303, -157, 250, 929, +97, 1719, -91, 2005, -280, 1847, -201, 1188, +140, 73, 437, -1028, 520, -1803, 373, -2150, +27, -1871, -553, -872, -1235, 478, -1538, 1541, +-1234, 2084, -548, 2161, 548, 1548, 1812, 320, +2372, -848, 1893, -1622, 724, -2093, -842, -1908, +-2384, -991, -3221, 55, -2862, 915, -1462, 1622, +430, 1945, 2358, 1718, 3610, 1093, 3401, 231, +1907, -759, -249, -1634, -2507, -2143, -3915, -2113, +-3855, -1437, -2559, -244, -364, 1070, 2033, 2145, +3564, 2733, 3790, 2572, 2738, 1538, 617, 6, +-1735, -1526, -3408, -2759, -3907, -3279, -3034, -2651, +-1142, -1101, 1031, 691, 2833, 2318, 3619, 3333, +2979, 3237, 1249, 2138, -746, 443, -2444, -1361, +-3414, -2623, -3157, -3029, -1776, -2611, -21, -1376, +1608, 202, 2794, 1472, 2972, 2335, 2053, 2628, +579, 2015, -1070, 903, -2497, -192, -3042, -1243, +-2493, -2002, -1231, -2088, 247, -1566, 1566, -731, +2484, 205, 2538, 1114, 1539, 1788, 152, 1965, +-1122, 1528, -2213, 710, -2593, -282, -1927, -1336, +-724, -2044, 569, -1961, 1738, -1189, 2238, -145, +1720, 988, 574, 1960, -590, 2227, -1521, 1612, +-2049, 448, -1818, -799, -792, -1731, 449, -2130, +1355, -1789, 1726, -652, 1488, 680, 593, 1586, +-736, 1974, -1744, 1727, -1900, 782, -1448, -326, +-493, -1167, 836, -1635, 1719, -1416, 1728, -631, +1161, 179, 149, 858, -1083, 1173, -1958, 800, +-2074, 116, -1436, -307, -257, -513, 1054, -476, +1943, 51, 2074, 786, 1469, 1096, 242, 754, +-1228, -39, -2204, -973, -2337, -1777, -1762, -2067, +-561, -1481, 845, -73, 1777, 1620, 2077, 2902, +1744, 3276, 702, 2542, -539, 751, -1457, -1542, +-1947, -3403, -1857, -4104, -1163, -3483, -181, -1622, +720, 998, 1268, 3285, 1397, 4318, 1129, 3912, +536, 2305, -164, -22, -812, -2252, -1275, -3583, +-1288, -3675, -911, -2539, -457, -625, 91, 1158, +700, 2239, 959, 2673, 842, 2330, 579, 1135, +111, -161, -503, -899, -919, -1304, -982, -1434, +-793, -1064, -393, -517, 194, -121, 616, 230, +650, 522, 569, 654, 339, 739, -182, 787, +-593, 631, -769, 303, -828, -112, -580, -573, +-53, -951, 407, -1023, 686, -754, 707, -283, +437, 305, 67, 866, -319, 1142, -671, 1043, +-838, 585, -848, -74, -675, -584, -229, -827, +323, -853, 769, -570, 980, -99, 867, 237, +497, 349, -92, 342, -701, 319, -1096, 345, +-1322, 286, -1275, 220, -730, 320, 138, 292, +1004, -52, 1543, -468, 1503, -819, 978, -1042, +143, -996, -858, -579, -1608, 239, -1802, 1183, +-1489, 1723, -709, 1752, 341, 1372, 1208, 478, +1646, -737, 1459, -1763, 683, -2295, -199, -2134, +-900, -1287, -1364, -56, -1380, 1251, -947, 2270, +-343, 2551, 249, 2001, 734, 949, 963, -303, +856, -1482, 480, -2161, -9, -2134, -410, -1533, +-571, -580, -663, 534, -798, 1410, -773, 1682, +-520, 1458, -236, 987, 178, 295, 815, -460, +1247, -840, 1204, -749, 849, -573, 198, -371, +-774, -32, -1713, 85, -2154, -131, -1987, -229, +-1223, -158, 146, -45, 1691, 318, 2659, 821, +2758, 1043, 1954, 986, 337, 661, -1523, -38, +-2901, -802, -3388, -1322, -2740, -1549, -1117, -1336, +817, -604, 2420, 348, 3162, 1145, 2704, 1620, +1305, 1612, -441, 1113, -1940, 369, -2662, -391, +-2364, -1007, -1259, -1274, 163, -1164, 1341, -813, +1859, -316, 1431, 199, 290, 577, -857, 773, +-1525, 789, -1495, 688, -651, 555, 609, 314, +1581, 0, 1923, -246, 1476, -511, 183, -771, +-1444, -842, -2684, -715, -3074, -406, -2408, 61, +-714, 473, 1501, 787, 3302, 1068, 3963, 1056, +3336, 679, 1448, 208, -1165, -275, -3392, -718, +-4537, -997, -4361, -1107, -2794, -1001, -268, -619, +2400, -117, 4315, 405, 4808, 1003, 3750, 1564, +1522, 1754, -1225, 1438, -3618, 701, -4878, -385, +-4573, -1565, -2767, -2334, -167, -2421, 2294, -1846, +4041, -654, 4463, 844, 3236, 2127, 998, 2792, +-1396, 2601, -3259, 1720, -3914, 473, -3165, -937, +-1417, -2086, 624, -2495, 2262, -2226, 2926, -1535, +2374, -525, 910, 512, -798, 1294, -2110, 1772, +-2414, 1873, -1558, 1651, -70, 1289, 1349, 713, +2152, -129, 1939, -1018, 779, -1785, -758, -2317, +-2165, -2384, -2906, -1805, -2443, -708, -1000, 644, +831, 1979, 2520, 2925, 3432, 3148, 3089, 2608, +1568, 1449, -496, -179, -2352, -1884, -3602, -3122, +-3788, -3599, -2683, -3239, -822, -2072, 1163, -281, +2839, 1662, 3647, 3149, 3278, 3884, 1981, 3752, +193, 2560, -1566, 609, -2820, -1369, -3429, -2945, +-3097, -3873, -1747, -3739, -33, -2494, 1477, -717, +2564, 1044, 2841, 2533, 2206, 3418, 1014, 3296, +-243, 2268, -1251, 865, -1945, -634, -2130, -1942, +-1678, -2585, -842, -2481, 50, -1885, 742, -864, +1099, 376, 1122, 1285, 838, 1679, 346, 1751, +70, 1418, 68, 651, -127, -142, -529, -666, +-714, -986, -813, -1063, -992, -769, -824, -285, +-150, 151, 506, 560, 890, 806, 1229, 613, +1243, 77, 503, -402, -540, -733, -1330, -957, +-1749, -752, -1598, 16, -662, 869, 674, 1452, +1791, 1787, 2276, 1600, 1869, 622, 552, -708, +-1197, -1879, -2664, -2664, -3249, -2727, -2645, -1879, +-981, -380, 1150, 1340, 2991, 2781, 3936, 3496, +3546, 3272, 1815, 2097, -597, 260, -2929, -1667, +-4418, -3165, -4437, -3846, -3031, -3436, -758, -2065, +1806, -249, 3776, 1548, 4352, 3026, 3607, 3796, +1985, 3476, -214, 2243, -2343, 587, -3576, -1186, +-3690, -2735, -2910, -3555, -1460, -3374, 296, -2352, +1788, -811, 2590, 957, 2724, 2520, 2241, 3363, +1279, 3219, 99, 2218, -1048, 649, -1912, -1093, +-2312, -2446, -2227, -2990, -1689, -2611, -816, -1419, +244, 90, 1308, 1388, 2081, 2247, 2366, 2385, +2108, 1617, 1208, 321, -156, -899, -1455, -1690, +-2318, -1837, -2688, -1331, -2364, -388, -1375, 693, +-80, 1469, 1253, 1629, 2388, 1253, 2929, 565, +2583, -291, 1420, -1062, -155, -1411, -1671, -1374, +-2797, -1137, -3280, -582, -2885, 192, -1596, 794, +161, 1262, 1881, 1745, 3294, 1894, 3845, 1447, +3053, 590, 1199, -551, -945, -1806, -2837, -2697, +-3985, -2897, -3896, -2310, -2646, -981, -717, 807, +1442, 2504, 3205, 3540, 3931, 3601, 3426, 2665, +1880, 957, -230, -1067, -2154, -2782, -3214, -3639, +-3189, -3458, -2379, -2365, -1101, -722, 343, 969, +1557, 2263, 2200, 2874, 2186, 2714, 1592, 1911, +653, 771, -258, -302, -954, -1061, -1381, -1452, +-1426, -1503, -1186, -1354, -865, -1159, -416, -929, +155, -578, 657, -89, 1033, 515, 1165, 1256, +961, 1997, 537, 2314, 28, 1957, -624, 1151, +-1189, 6, -1313, -1449, -1061, -2661, -563, -3081, +225, -2675, 974, -1563, 1181, 80, 907, 1748, +452, 2834, -163, 3117, -774, 2612, -1002, 1333, +-873, -309, -665, -1674, -209, -2487, 452, -2598, +827, -1860, 797, -630, 662, 535, 381, 1488, +-112, 1962, -534, 1590, -718, 722, -784, -85, +-818, -776, -710, -1244, -349, -1124, 150, -497, +588, 232, 903, 873, 1128, 1220, 1082, 1040, +634, 444, -12, -307, -610, -1051, -1227, -1480, +-1686, -1350, -1567, -854, -944, -163, -262, 694, +413, 1354, 1100, 1547, 1499, 1440, 1533, 1101, +1321, 490, 799, -278, 5, -983, -804, -1439, +-1433, -1652, -1841, -1654, -1882, -1276, -1514, -503, +-855, 363, 20, 1201, 1068, 1916, 1934, 2243, +2323, 2144, 2246, 1651, 1654, 709, 471, -571, +-944, -1915, -2039, -2961, -2753, -3376, -3080, -2969, +-2618, -1695, -1243, 212, 560, 2216, 2152, 3746, +3240, 4343, 3600, 3739, 2943, 2047, 1320, -178, +-632, -2305, -2324, -3868, -3462, -4393, -3760, -3598, +-2953, -1867, -1233, 96, 742, 1894, 2287, 3138, +3001, 3433, 2912, 2874, 2126, 1792, 730, 423, +-747, -860, -1764, -1697, -2159, -2086, -1911, -2108, +-1188, -1789, -408, -1235, 283, -499, 690, 317, +565, 1024, 295, 1586, 387, 1918, 569, 1865, +625, 1437, 756, 688, 685, -192, 173, -973, +-464, -1608, -1083, -1992, -1669, -1941, -1920, -1434, +-1477, -611, -422, 335, 814, 1162, 1789, 1741, +2288, 2058, 2102, 1994, 1208, 1461, -68, 598, +-1234, -391, -1980, -1395, -2248, -2219, -1954, -2570, +-1024, -2320, 174, -1458, 1085, -97, 1634, 1349, +1866, 2509, 1523, 3207, 784, 3094, 41, 1956, +-693, 156, -1374, -1727, -1679, -3188, -1599, -3722, +-1222, -3044, -524, -1409, 397, 608, 1222, 2394, +1656, 3368, 1693, 3123, 1377, 1844, 615, 179, +-443, -1316, -1327, -2192, -1768, -2145, -1752, -1327, +-1256, -228, -491, 635, 272, 888, 893, 542, +1238, -5, 1201, -416, 980, -513, 644, -56, +133, 893, -374, 1704, -683, 1805, -840, 1120, +-955, -116, -996, -1637, -895, -2917, -596, -3192, +-81, -2218, 519, -397, 1051, 1664, 1462, 3280, +1565, 3844, 1082, 3112, 264, 1299, -555, -935, +-1312, -2766, -1849, -3571, -1843, -3094, -1272, -1649, +-361, 139, 617, 1692, 1341, 2442, 1634, 2189, +1404, 1267, 640, 97, -247, -874, -805, -1203, +-973, -824, -755, -40, -160, 686, 411, 947, +627, 610, 373, -226, -272, -1262, -1022, -1958, +-1510, -1855, -1529, -970, -889, 375, 423, 1755, +1872, 2717, 2851, 2955, 3069, 2275, 2248, 755, +390, -1102, -1865, -2635, -3718, -3383, -4585, -3208, +-4012, -2165, -2070, -463, 582, 1360, 3072, 2671, +4710, 3202, 4940, 2929, 3661, 1931, 1288, 510, +-1493, -951, -3732, -2106, -4642, -2577, -4161, -2318, +-2620, -1655, -445, -734, 1620, 315, 2874, 1141, +3149, 1577, 2552, 1709, 1382, 1527, 116, 998, +-822, 351, -1290, -190, -1253, -650, -966, -982, +-763, -1038, -743, -979, -812, -939, -770, -726, +-459, -361, 112, 37, 872, 533, 1650, 1009, +2091, 1356, 1943, 1568, 1248, 1433, 100, 834, +-1317, -61, -2545, -1038, -3019, -1860, -2576, -2295, +-1303, -2130, 379, -1290, 1818, 25, 2642, 1362, +2757, 2293, 2008, 2595, 584, 2154, -826, 1013, +-1808, -501, -2281, -1775, -2010, -2268, -1010, -1944, +167, -1068, 1050, 69, 1433, 1039, 1185, 1425, +532, 1142, -230, 414, -849, -345, -1032, -781, +-666, -775, -36, -311, 629, 456, 1163, 1096, +1186, 1230, 593, 786, -221, -65, -975, -1029, +-1581, -1751, -1736, -1829, -1275, -1166, -458, -67, +525, 1091, 1500, 1885, 2090, 2016, 1997, 1507, +1367, 493, 342, -746, -895, -1621, -1906, -1757, +-2317, -1305, -2103, -494, -1376, 486, -275, 1249, +928, 1373, 1838, 811, 2134, -14, 1778, -715, +940, -1147, -105, -1057, -957, -374, -1371, 499, +-1334, 1204, -976, 1551, -433, 1326, 2, 502, +201, -586, 284, -1523, 303, -2040, 200, -1913, +137, -1081, 252, 131, 468, 1270, 669, 2038, +644, 2233, 290, 1744, -211, 727, -754, -414, +-1244, -1306, -1400, -1834, -1076, -1930, -479, -1438, +300, -486, 1042, 408, 1387, 953, 1267, 1265, +896, 1298, 334, 885, -326, 293, -798, -140, +-900, -374, -723, -394, -525, -233, -426, -55, +-358, -30, -205, -227, 46, -550, 231, -865, +411, -958, 747, -635, 1028, 14, 880, 807, +470, 1547, 21, 1917, -587, 1743, -1252, 1103, +-1485, 68, -1194, -1178, -659, -2130, 10, -2410, +729, -2090, 1230, -1308, 1258, -139, 852, 1039, +304, 1804, -239, 2156, -640, 2162, -752, 1707, +-548, 904, -217, -44, 23, -1052, 61, -1893, +23, -2356, -49, -2419, -211, -1957, -350, -893, +-253, 479, 69, 1809, 406, 2803, 670, 3077, +798, 2490, 631, 1225, 201, -394, -302, -1881, +-710, -2743, -991, -2789, -1057, -2130, -860, -984, +-369, 367, 342, 1486, 970, 2000, 1171, 1852, +1009, 1262, 578, 511, -101, -161, -685, -543, +-913, -619, -886, -563, -620, -501, -64, -467, +542, -403, 868, -334, 840, -288, 410, -126, +-297, 172, -969, 425, -1306, 539, -1136, 569, +-433, 548, 486, 369, 1260, 72, 1685, -79, +1627, -63, 990, -57, -71, -112, -1104, -298, +-1805, -606, -2081, -815, -1745, -833, -852, -689, +209, -269, 1076, 447, 1614, 1174, 1738, 1605, +1499, 1659, 991, 1292, 353, 475, -305, -545, +-919, -1437, -1443, -1968, -1719, -1944, -1673, -1387, +-1310, -524, -592, 395, 326, 1186, 1182, 1634, +1850, 1609, 2149, 1236, 1939, 677, 1253, 40, +205, -452, -1022, -687, -1964, -818, -2289, -932, +-2057, -921, -1447, -781, -496, -630, 560, -377, +1318, 106, 1654, 677, 1641, 1139, 1344, 1435, +869, 1519, 284, 1254, -310, 594, -741, -300, +-1063, -1162, -1418, -1800, -1543, -2108, -1247, -1916, +-704, -1140, -47, -18, 761, 1060, 1458, 1884, +1768, 2323, 1728, 2175, 1373, 1408, 593, 302, +-491, -800, -1457, -1675, -1997, -2123, -2038, -2012, +-1513, -1399, -556, -465, 442, 516, 1212, 1262, +1659, 1619, 1644, 1520, 1197, 1082, 462, 562, +-319, 19, -993, -500, -1394, -843, -1317, -1008, +-792, -1051, -130, -932, 448, -554, 861, -11, +1000, 514, 818, 1001, 374, 1290, -209, 1110, +-718, 570, -1024, -45, -1035, -639, -640, -1111, +47, -1218, 702, -819, 1225, -149, 1370, 407, +952, 747, 248, 935, -466, 859, -1079, 444, +-1385, -70, -1358, -479, -1053, -758, -397, -842, +450, -674, 1093, -333, 1417, 88, 1484, 487, +1140, 777, 358, 926, -338, 825, -696, 475, +-1030, 51, -1366, -430, -1246, -935, -759, -1244, +-295, -1186, 219, -759, 806, -106, 1149, 603, +1149, 1237, 967, 1603, 713, 1476, 288, 837, +-319, -19, -811, -818, -1068, -1422, -1230, -1632, +-1109, -1347, -620, -745, -10, -9, 520, 771, +938, 1367, 1115, 1535, 1001, 1307, 678, 764, +189, 21, -355, -710, -728, -1266, -825, -1431, +-683, -1135, -384, -642, -34, -60, 232, 640, +329, 1188, 219, 1321, 5, 1084, -148, 588, +-122, -87, -46, -775, 84, -1231, 346, -1286, +542, -924, 499, -263, 303, 489, -64, 1086, +-508, 1325, -741, 1063, -733, 387, -595, -396, +-283, -969, 101, -1145, 347, -861, 441, -240, +491, 393, 445, 755, 332, 788, 229, 466, +171, -47, 136, -425, 63, -517, -159, -326, +-507, 73, -827, 462, -1039, 589, -1048, 347, +-666, -113, 54, -604, 853, -931, 1528, -825, +1823, -300, 1586, 352, 979, 939, 20, 1258, +-1108, 1096, -1949, 485, -2254, -310, -1995, -991, +-1167, -1318, 16, -1202, 1218, -675, 2074, 65, +2283, 710, 1867, 1079, 1041, 1110, -46, 771, +-1101, 227, -1755, -248, -1906, -564, -1612, -745, +-868, -705, 85, -454, 886, -171, 1323, 39, +1354, 228, 953, 399, 285, 497, -273, 515, +-526, 445, -531, 269, -306, 37, 1, -281, +134, -643, 43, -832, -210, -793, -521, -561, +-690, -53, -576, 626, -149, 1153, 458, 1314, +1055, 1069, 1408, 418, 1277, -494, 542, -1316, +-468, -1700, -1256, -1469, -1625, -712, -1552, 299, +-936, 1269, 90, 1835, 1054, 1716, 1561, 938, +1557, -152, 1076, -1105, 147, -1654, -865, -1651, +-1385, -1001, -1337, 28, -869, 957, -98, 1454, +686, 1357, 1122, 741, 1074, -102, 617, -897, +-3, -1293, -609, -1039, -1004, -325, -910, 452, +-397, 985, 187, 1112, 658, 791, 858, 77, +670, -706, 192, -1194, -342, -1210, -650, -730, +-575, 73, -352, 876, -87, 1365, 318, 1284, +636, 650, 553, -211, 217, -914, -141, -1241, +-492, -1067, -719, -440, -571, 286, -69, 781, +405, 945, 642, 732, 706, 194, 529, -435, +135, -816, -279, -812, -585, -475, -738, 116, +-624, 723, -289, 979, 104, 803, 417, 354, +580, -231, 536, -767, 336, -1016, 120, -916, +-47, -541, -174, -30, -254, 461, -284, 813, +-286, 927, -278, 776, -191, 448, -58, 36, +67, -350, 209, -595, 344, -667, 386, -608, +384, -469, 292, -309, 51, -83, -206, 200, +-347, 390, -467, 491, -541, 628, -350, 672, +17, 467, 257, 129, 355, -136, 414, -403, +404, -702, 240, -804, 21, -701, -78, -524, +-117, -192, -276, 215, -370, 526, -258, 752, +-137, 875, -83, 797, 80, 540, 285, 183, +348, -213, 294, -599, 190, -900, 37, -1038, +-173, -934, -360, -606, -326, -143, -154, 376, +12, 869, 224, 1156, 401, 1150, 362, 913, +182, 471, -97, -183, -396, -802, -507, -1110, +-390, -1157, -187, -1023, 41, -582, 319, 24, +586, 509, 657, 817, 488, 941, 199, 848, +-135, 573, -479, 174, -703, -220, -735, -489, +-535, -554, -194, -480, 119, -356, 439, -176, +770, -47, 815, -112, 592, -205, 320, -146, +-60, 31, -459, 311, -621, 689, -627, 942, +-546, 901, -270, 515, 77, -172, 240, -870, +239, -1287, 217, -1356, 191, -998, 124, -265, +194, 545, 443, 1126, 586, 1308, 444, 1057, +129, 494, -306, -179, -799, -699, -1142, -879, +-1154, -709, -817, -326, -220, 98, 515, 367, +1228, 366, 1611, 125, 1507, -169, 1022, -352, +265, -334, -647, -92, -1330, 248, -1516, 545, +-1292, 709, -887, 552, -381, 94, 241, -368, +786, -665, 1023, -824, 1077, -747, 1035, -366, +787, 140, 378, 567, -27, 785, -402, 713, +-778, 482, -1111, 125, -1238, -355, -1086, -699, +-644, -720, 61, -523, 806, -193, 1288, 236, +1478, 642, 1335, 785, 744, 603, -25, 213, +-623, -285, -1011, -760, -1100, -974, -865, -850, +-456, -420, -23, 209, 237, 813, 258, 1201, +226, 1260, 165, 834, 110, 44, 235, -758, +544, -1327, 811, -1541, 837, -1250, 541, -488, +-21, 433, -724, 1131, -1349, 1447, -1582, 1347, +-1285, 838, -621, 61, 235, -654, 1070, -1106, +1607, -1193, 1674, -901, 1265, -401, 516, 116, +-305, 560, -949, 771, -1216, 702, -1097, 468, +-723, 187, -217, -119, 186, -378, 315, -479, +292, -419, 233, -301, 180, -90, 233, 208, +413, 406, 597, 397, 647, 285, 465, 55, +93, -275, -407, -533, -949, -588, -1288, -401, +-1172, -21, -671, 372, 62, 679, 860, 787, +1389, 579, 1422, 144, 1017, -322, 320, -731, +-450, -929, -982, -804, -1071, -403, -762, 111, +-208, 553, 373, 812, 697, 836, 605, 553, +262, 87, -163, -327, -566, -551, -698, -608, +-393, -523, 134, -257, 622, 91, 928, 286, +916, 329, 548, 307, -41, 201, -611, 8, +-924, -145, -920, -199, -641, -176, -196, -106, +254, -20, 571, 60, 655, 129, 473, 119, +229, 72, 114, 33, 89, -41, 69, -130, +88, -149, 113, -141, 5, -116, -287, -44, +-570, 46, -672, 93, -623, 94, -359, 51, +165, 9, 665, 0, 973, 48, 1066, 125, +840, 203, 335, 213, -215, 73, -690, -181, +-1026, -423, -1070, -639, -710, -727, -150, -523, +327, -44, 719, 493, 986, 946, 886, 1217, +465, 1142, 8, 604, -389, -201, -700, -961, +-748, -1465, -501, -1591, -67, -1193, 379, -400, +657, 472, 704, 1161, 522, 1462, 142, 1292, +-272, 781, -595, 90, -738, -495, -590, -768, +-169, -760, 305, -599, 629, -363, 746, -173, +651, -130, 347, -232, 0, -281, -239, -106, +-372, 244, -426, 630, -326, 1016, -125, 1219, +-15, 1007, -20, 395, -26, -407, -39, -1219, +-10, -1783, 146, -1862, 405, -1381, 650, -461, +703, 664, 515, 1618, 200, 2088, -218, 1901, +-665, 1139, -956, 76, -980, -912, -752, -1527, +-324, -1629, 212, -1249, 780, -572, 1214, 82, +1295, 561, 1014, 750, 538, 603, -49, 344, +-645, 181, -1032, 74, -1093, 90, -936, 244, +-625, 336, -109, 197, 485, -109, 850, -493, +931, -834, 823, -985, 543, -845, 147, -435, +-193, 144, -340, 723, -293, 1129, -199, 1182, +-121, 888, -42, 371, -48, -228, -203, -737, +-376, -965, -416, -901, -307, -638, -48, -289, +412, 35, 915, 230, 1197, 326, 1145, 383, +781, 413, 142, 400, -644, 389, -1293, 321, +-1503, 139, -1301, -110, -834, -383, -101, -665, +735, -779, 1326, -664, 1521, -412, 1350, -47, +875, 440, 227, 808, -355, 860, -730, 657, +-928, 322, -971, -107, -797, -495, -481, -690, +-171, -626, 138, -399, 479, -114, 727, 117, +820, 224, 829, 217, 764, 139, 530, 51, +106, 60, -351, 122, -703, 182, -956, 216, +-973, 117, -677, -182, -245, -466, 186, -567, +611, -484, 905, -251, 980, 150, 870, 560, +582, 750, 132, 621, -316, 270, -649, -217, +-815, -669, -715, -901, -380, -809, 40, -406, +427, 185, 653, 716, 641, 1017, 401, 978, +40, 554, -294, -143, -481, -797, -424, -1192, +-104, -1205, 314, -798, 682, -71, 848, 711, +649, 1255, 143, 1309, -451, 882, -925, 161, +-1071, -590, -836, -1156, -296, -1326, 418, -972, +1006, -250, 1184, 461, 997, 947, 561, 1090, +5, 797, -421, 177, -600, -420, -528, -792, +-212, -867, 86, -610, 142, -110, 51, 362, +-146, 618, -429, 618, -498, 396, -154, -20, +437, -431, 1010, -632, 1400, -561, 1408, -254, +886, 186, -32, 493, -1010, 547, -1751, 381, +-1996, 53, -1599, -335, -644, -570, 524, -559, +1496, -322, 2057, 24, 2108, 347, 1542, 524, +528, 526, -487, 335, -1245, -12, -1685, -375, +-1638, -578, -1088, -627, -305, -495, 448, -165, +996, 212, 1233, 467, 1207, 610, 929, 588, +468, 359, -16, 3, -414, -320, -641, -558, +-672, -641, -553, -559, -265, -342, 102, -43, +309, 292, 304, 536, 300, 591, 308, 453, +155, 249, -12, -20, 21, -345, 92, -535, +113, -478, 234, -348, 345, -190, 189, 33, +-83, 214, -265, 249, -410, 237, -419, 200, +-211, 117, 30, 38, 262, 15, 479, -58, +567, -173, 519, -253, 354, -305, 104, -316, +-142, -171, -321, 62, -339, 280, -180, 420, +27, 424, 163, 237, 252, -63, 258, -387, +110, -567, -17, -506, -10, -273, -39, 37, +-100, 381, 5, 554, 248, 457, 380, 183, +388, -109, 384, -352, 222, -459, -101, -385, +-316, -174, -397, 28, -410, 177, -342, 225, +-185, 143, 72, -16, 358, -95, 623, -69, +823, 27, 788, 161, 497, 277, 106, 214, +-272, -30, -567, -330, -662, -575, -553, -692, +-373, -501, -129, -50, 200, 404, 495, 721, +684, 871, 748, 695, 665, 223, 420, -323, +122, -741, -76, -906, -257, -749, -463, -410, +-544, 15, -487, 438, -321, 666, -69, 587, +204, 332, 501, 35, 711, -214, 693, -354, +541, -321, 342, -184, 74, 1, -226, 155, +-436, 161, -476, 8, -347, -138, -134, -258, +62, -345, 227, -275, 317, -18, 287, 218, +254, 379, 215, 481, 151, 441, 168, 204, +229, -76, 258, -304, 261, -485, 170, -622, +-22, -611, -245, -444, -438, -152, -509, 193, +-401, 518, -145, 752, 209, 847, 592, 661, +909, 236, 1038, -239, 857, -675, 371, -1038, +-240, -1106, -792, -820, -1080, -305, -963, 291, +-568, 841, 0, 1137, 664, 1073, 1098, 682, +1172, 106, 954, -505, 424, -911, -250, -1024, +-761, -886, -922, -520, -682, 27, -159, 467, +445, 645, 865, 653, 908, 514, 650, 184, +237, -112, -285, -232, -688, -240, -699, -234, +-379, -211, 30, -220, 450, -286, 819, -350, +913, -296, 622, -97, 184, 250, -147, 605, +-395, 779, -551, 694, -472, 387, -260, -149, +-55, -739, 184, -1118, 425, -1113, 551, -741, +535, -95, 458, 621, 369, 1168, 171, 1294, +-145, 922, -377, 181, -422, -615, -368, -1186, +-166, -1330, 242, -992, 602, -269, 663, 521, +488, 1074, 184, 1200, -176, 871, -457, 182, +-485, -568, -186, -1094, 294, -1176, 737, -771, +991, -85, 879, 550, 372, 960, -355, 963, +-1022, 544, -1266, -57, -929, -534, -162, -754, +728, -678, 1369, -356, 1509, 77, 1122, 358, +353, 360, -498, 163, -1081, -90, -1203, -322, +-813, -347, -42, -82, 775, 364, 1286, 730, +1222, 775, 564, 415, -280, -183, -915, -868, +-1156, -1395, -801, -1456, 64, -904, 957, 33, +1497, 1003, 1530, 1692, 1032, 1870, 132, 1377, +-851, 379, -1509, -745, -1551, -1637, -959, -2020, +-12, -1702, 908, -876, 1522, 135, 1591, 1026, +1066, 1520, 269, 1465, -434, 993, -861, 315, +-876, -338, -467, -787, 96, -904, 501, -748, +647, -469, 507, -197, 100, 50, -342, 187, +-555, 170, -476, 92, -116, 81, 448, 125, +973, 225, 1217, 326, 1102, 366, 630, 261, +-102, 28, -814, -260, -1215, -529, -1237, -716, +-915, -666, -265, -410, 537, -91, 1165, 220, +1483, 508, 1463, 659, 1047, 624, 352, 401, +-327, 87, -795, -230, -998, -473, -920, -581, +-565, -505, -89, -313, 279, -25, 484, 247, +603, 349, 621, 245, 499, 52, 349, -168, +313, -335, 299, -365, 203, -158, 119, 220, +-9, 559, -302, 669, -550, 550, -592, 180, +-506, -340, -255, -801, 217, -1028, 695, -959, +924, -591, 953, -63, 888, 464, 587, 835, +61, 1026, -345, 985, -465, 680, -490, 214, +-488, -255, -317, -725, -74, -1088, 37, -1190, +134, -1013, 336, -648, 502, -84, 565, 562, +647, 1081, 710, 1308, 568, 1227, 258, 830, +-82, 172, -459, -575, -795, -1128, -915, -1370, +-715, -1240, -280, -760, 230, -101, 733, 483, +1101, 861, 1186, 919, 993, 697, 589, 322, +96, -38, -349, -237, -651, -239, -745, -196, +-656, -147, -390, -138, -2, -237, 311, -428, +497, -546, 643, -481, 742, -207, 677, 197, +458, 622, 245, 887, 22, 906, -259, 645, +-438, 128, -443, -501, -312, -931, -99, -1062, +127, -921, 306, -500, 409, 85, 457, 538, +396, 766, 236, 743, 139, 481, 101, 101, +59, -207, 21, -367, -2, -362, 14, -271, +15, -157, -25, -81, -33, -69, 8, -127, +110, -147, 244, -74, 359, 101, 423, 289, +376, 408, 216, 370, -5, 163, -189, -149, +-247, -439, -171, -631, 79, -586, 369, -266, +512, 190, 534, 548, 399, 702, 61, 596, +-321, 219, -552, -342, -512, -794, -248, -921, +168, -703, 631, -209, 925, 451, 927, 925, +612, 999, 71, 705, -436, 126, -712, -568, +-684, -1047, -406, -1134, 46, -782, 535, -108, +788, 618, 708, 1055, 442, 1068, 117, 656, +-178, -60, -352, -827, -239, -1242, 110, -1105, +416, -494, 566, 312, 523, 1015, 262, 1313, +-117, 1091, -489, 361, -655, -591, -487, -1312, +-47, -1510, 503, -1196, 929, -414, 1053, 575, +834, 1335, 355, 1555, -198, 1222, -611, 438, +-721, -501, -592, -1227, -319, -1449, 116, -1157, +549, -520, 734, 227, 647, 833, 429, 1021, +165, 818, -137, 400, -264, -83, -111, -477, +81, -610, 234, -493, 335, -249, 265, -1, +132, 201, 11, 248, -126, 120, -181, -58, +-93, -148, 43, -191, 183, -164, 356, -38, +484, 138, 462, 246, 350, 263, 238, 188, +123, 63, -30, -134, -192, -330, -302, -433, +-370, -420, -329, -287, -107, -25, 183, 210, +469, 351, 691, 414, 720, 360, 558, 170, +309, -15, 48, -164, -198, -301, -385, -401, +-408, -366, -300, -257, -137, -166, 73, -51, +246, 158, 316, 302, 366, 328, 447, 310, +480, 286, 463, 177, 419, -14, 231, -260, +-68, -452, -308, -532, -470, -520, -472, -416, +-306, -134, -101, 237, 196, 538, 529, 658, +700, 630, 706, 440, 590, 73, 352, -380, +64, -690, -185, -779, -328, -647, -365, -338, +-342, 77, -294, 434, -183, 590, 50, 479, +343, 241, 559, -13, 686, -204, 761, -276, +674, -195, 361, -30, -43, 128, -447, 120, +-751, -37, -789, -234, -532, -406, -63, -502, +470, -361, 850, -4, 996, 415, 895, 720, +589, 804, 201, 586, -229, 136, -599, -386, +-716, -779, -574, -928, -275, -770, 100, -392, +443, 52, 618, 440, 639, 674, 606, 620, +491, 393, 266, 147, 26, -92, -218, -295, +-451, -338, -562, -251, -475, -149, -230, -136, +92, -161, 440, -164, 746, -143, 910, -101, +844, 65, 519, 288, 68, 417, -347, 403, +-667, 283, -774, 33, -586, -248, -223, -447, +210, -502, 626, -418, 874, -190, 897, 74, +742, 258, 417, 315, -15, 279, -395, 116, +-594, -94, -589, -214, -457, -194, -232, -111, +119, -1, 493, 112, 748, 213, 820, 187, +654, 41, 303, -118, -63, -257, -365, -395, +-522, -408, -455, -282, -219, -56, 63, 215, +303, 445, 515, 521, 620, 458, 456, 260, +138, -34, -120, -328, -264, -504, -219, -551, +6, -458, 221, -275, 332, -38, 345, 165, +248, 288, 67, 320, -97, 310, -164, 269, +-113, 216, 45, 115, 247, 1, 381, -148, +384, -362, 241, -564, -12, -607, -224, -491, +-226, -201, -61, 213, 127, 605, 305, 795, +417, 717, 372, 375, 199, -90, -79, -536, +-351, -794, -418, -769, -239, -452, 114, 6, +513, 434, 775, 662, 750, 636, 398, 337, +-125, -142, -513, -593, -611, -784, -510, -665, +-203, -266, 320, 258, 738, 719, 839, 941, +711, 800, 341, 295, -163, -325, -510, -841, +-553, -1075, -300, -943, 53, -490, 296, 88, +415, 591, 389, 814, 211, 749, 7, 482, +-61, 153, 26, -125, 152, -268, 263, -319, +334, -304, 258, -303, -10, -359, -342, -427, +-535, -379, -455, -204, -109, 86, 332, 451, +702, 792, 923, 898, 811, 691, 378, 252, +-51, -285, -398, -816, -670, -1086, -679, -975, +-382, -572, 39, -47, 389, 459, 596, 771, +623, 811, 448, 542, 226, 119, 109, -234, +79, -420, 76, -433, 67, -235, 1, 38, +-173, 217, -372, 217, -452, 58, -410, -211, +-185, -445, 257, -530, 725, -389, 1005, -77, +1027, 314, 771, 645, 230, 800, -419, 691, +-875, 343, -1051, -177, -918, -635, -446, -873, +181, -895, 739, -703, 1088, -262, 1113, 230, +820, 581, 350, 726, -121, 690, -468, 485, +-592, 191, -524, -118, -367, -342, -107, -463, +176, -466, 311, -386, 326, -277, 330, -186, +338, -59, 303, 101, 263, 263, 270, 369, +199, 424, 2, 404, -212, 275, -358, -6, +-365, -318, -274, -521, -146, -565, 78, -489, +352, -260, 535, 59, 577, 336, 509, 471, +347, 481, 93, 333, -170, 69, -346, -182, +-384, -354, -320, -477, -208, -439, -3, -226, +253, 49, 444, 292, 540, 451, 495, 439, +328, 278, 120, 2, -91, -294, -213, -506, +-223, -536, -214, -384, -176, -94, -38, 191, +149, 392, 269, 457, 335, 364, 374, 130, +287, -93, 95, -212, -40, -231, -62, -199, +-60, -110, -81, -56, -80, -99, -77, -168, +-69, -165, 27, -141, 162, -41, 275, 188, +379, 437, 418, 544, 356, 488, 178, 243, +-111, -115, -392, -494, -522, -780, -446, -833, +-198, -568, 174, -127, 568, 306, 796, 601, +775, 734, 524, 654, 106, 362, -317, -23, +-610, -294, -696, -440, -505, -489, -104, -418, +304, -238, 551, -62, 630, 65, 545, 122, +301, 127, 37, 87, -132, 77, -207, 124, +-160, 189, -36, 209, 41, 181, 21, 59, +-67, -109, -149, -280, -145, -430, -15, -484, +225, -363, 494, -177, 671, 51, 631, 308, +369, 489, -5, 511, -385, 420, -668, 209, +-749, -49, -538, -276, -86, -438, 388, -529, +720, -500, 844, -359, 716, -103, 391, 193, +21, 439, -264, 578, -398, 573, -381, 350, +-247, 8, -100, -333, 3, -591, 69, -695, +77, -548, 62, -197, 130, 221, 297, 543, +483, 689, 593, 582, 534, 244, 257, -212, +-171, -587, -582, -744, -823, -623, -813, -302, +-530, 129, -5, 532, 620, 763, 1052, 679, +1128, 328, 900, -124, 399, -510, -257, -752, +-731, -716, -841, -381, -671, 72, -319, 432, +89, 631, 388, 570, 525, 258, 480, -139, +305, -432, 150, -548, 47, -411, -21, -94, +47, 247, 168, 461, 136, 475, -20, 253, +-186, -105, -337, -449, -387, -606, -239, -536, +34, -268, 316, 102, 530, 451, 590, 620, +480, 574, 266, 341, -22, 19, -297, -269, +-417, -441, -362, -530, -190, -483, 22, -299, +192, -81, 278, 102, 268, 273, 164, 373, +56, 392, 22, 340, 46, 235, 95, 73, +161, -96, 212, -273, 168, -421, 0, -483, +-178, -423, -270, -280, -286, -33, -202, 256, +-1, 468, 220, 528, 370, 463, 429, 253, +386, -54, 241, -333, 34, -460, -161, -436, +-263, -285, -250, -82, -160, 103, -40, 212, +79, 230, 171, 135, 204, 19, 166, -63, +108, -103, 60, -101, 15, -17, -4, 95, +69, 163, 193, 138, 231, 60, 148, -57, +17, -180, -122, -281, -232, -295, -256, -231, +-170, -87, -36, 84, 111, 237, 293, 337, +428, 351, 430, 232, 318, 74, 111, -98, +-106, -272, -251, -347, -315, -288, -258, -219, +-140, -113, -80, 37, 1, 125, 161, 124, +277, 151, 323, 175, 363, 158, 332, 116, +193, 89, 28, 20, -150, -116, -309, -253, +-372, -302, -340, -290, -207, -197, 19, -37, +287, 135, 485, 272, 526, 327, 449, 198, +265, 17, -28, -79, -281, -128, -404, -136, +-398, -25, -261, 61, -40, 25, 203, -89, +372, -191, 382, -245, 285, -216, 168, -76, +37, 165, -103, 344, -184, 386, -196, 307, +-159, 125, -52, -124, 76, -321, 175, -422, +248, -351, 245, -146, 160, 41, 35, 151, +-95, 223, -168, 183, -195, 72, -148, -13, +24, -43, 234, -32, 406, 31, 448, 83, +255, 89, -67, 7, -333, -133, -509, -272, +-514, -353, -241, -324, 177, -126, 565, 139, +820, 402, 782, 583, 432, 564, -92, 317, +-650, -52, -970, -463, -883, -748, -483, -789, +131, -561, 751, -137, 1067, 356, 986, 704, +607, 827, 31, 689, -585, 338, -964, -97, +-909, -491, -483, -764, 104, -772, 617, -533, +839, -161, 695, 212, 289, 487, -190, 584, +-500, 486, -475, 243, -225, 45, 58, -59, +322, -138, 478, -203, 400, -231, 121, -323, +-193, -451, -384, -468, -407, -255, -276, 113, +-8, 512, 276, 830, 426, 917, 423, 609, +306, 35, 112, -582, -84, -1030, -202, -1103, +-240, -760, -222, -196, -147, 452, -24, 926, +85, 973, 109, 681, 107, 250, 159, -269, +192, -621, 174, -660, 140, -513, 67, -282, +-44, 13, -154, 230, -210, 336, -172, 360, +-64, 287, 78, 108, 200, -63, 268, -195, +303, -267, 219, -229, -48, -77, -314, 35, +-374, 73, -273, 79, -80, 40, 212, -39, +487, -39, 555, 7, 390, 66, 100, 121, +-204, 145, -467, 105, -585, -2, -456, -177, +-199, -277, 85, -282, 382, -249, 558, -107, +544, 161, 409, 330, 203, 381, -26, 355, +-243, 198, -383, -42, -378, -258, -283, -414, +-174, -403, -65, -275, 34, -129, 129, 49, +260, 214, 384, 238, 413, 220, 371, 231, +265, 213, 39, 135, -206, 53, -350, -52, +-398, -215, -386, -422, -328, -497, -205, -396, +-22, -200, 170, 57, 388, 357, 595, 557, +675, 598, 571, 474, 305, 228, -75, -92, +-498, -396, -801, -630, -835, -705, -636, -584, +-260, -253, 236, 199, 639, 601, 815, 758, +786, 633, 540, 291, 149, -125, -216, -484, +-492, -618, -598, -468, -423, -136, -121, 198, +83, 406, 174, 365, 128, 126, -14, -155, +-72, -351, -14, -401, 167, -231, 429, 87, +525, 373, 384, 454, 171, 336, -126, 107, +-514, -116, -773, -256, -756, -288, -486, -273, +-27, -203, 507, -119, 929, -73, 1056, -19, +787, 145, 205, 347, -442, 475, -911, 417, +-1043, 149, -752, -221, -159, -490, 424, -585, +788, -456, 874, -119, 634, 281, 170, 497, +-248, 467, -528, 262, -672, -38, -572, -333, +-249, -445, 141, -393, 507, -221, 703, 83, +588, 407, 263, 551, -85, 501, -357, 289, +-471, -29, -408, -367, -258, -625, -123, -753, +-3, -650, 138, -322, 300, 145, 452, 615, +478, 985, 318, 1097, 95, 807, -137, 171, +-379, -522, -485, -1077, -422, -1311, -322, -1089, +-157, -502, 118, 188, 362, 801, 493, 1125, +535, 1069, 422, 719, 165, 214, -111, -314, +-345, -667, -466, -819, -400, -774, -251, -524, +-122, -121, 35, 264, 192, 495, 236, 534, +216, 451, 253, 242, 287, -24, 243, -173, +134, -152, -27, -116, -182, -91, -323, -74, +-488, -117, -523, -218, -340, -251, -81, -186, +239, -26, 625, 210, 845, 461, 755, 578, +407, 467, -100, 112, -573, -339, -832, -662, +-851, -734, -601, -574, -140, -154, 317, 366, +675, 705, 857, 766, 692, 599, 280, 187, +-105, -301, -403, -661, -566, -794, -494, -668, +-274, -308, -52, 142, 119, 569, 216, 785, +228, 711, 193, 430, 142, 54, 75, -352, +32, -632, 33, -701, 21, -531, -30, -217, +-129, 67, -251, 252, -280, 389, -204, 429, +-64, 413, 172, 365, 413, 226, 459, -16, +282, -274, 29, -521, -227, -640, -445, -563, +-467, -335, -251, -21, 43, 338, 316, 591, +514, 677, 495, 618, 195, 437, -209, 57, +-488, -441, -576, -791, -456, -828, -109, -643, +335, -259, 639, 252, 652, 677, 447, 835, +101, 704, -361, 306, -697, -187, -708, -591, +-487, -760, -119, -625, 289, -233, 572, 220, +679, 566, 606, 652, 316, 460, -128, 88, +-512, -281, -677, -499, -621, -518, -382, -411, +-14, -159, 344, 166, 526, 403, 519, 510, +426, 516, 210, 319, -141, 5, -425, -270, +-516, -492, -417, -609, -167, -494, 137, -242, +359, 59, 336, 371, 135, 595, -19, 614, +-118, 458, -168, 147, -86, -237, 41, -531, +85, -586, 72, -440, 52, -198, 23, 53, +-37, 265, -117, 332, -173, 287, -185, 211, +-132, 121, 9, 9, 164, -60, 255, -121, +308, -162, 266, -182, 66, -201, -147, -195, +-292, -95, -406, 39, -408, 207, -227, 381, +63, 414, 312, 207, 442, -94, 450, -338, +282, -441, -35, -395, -312, -180, -446, 120, +-397, 334, -159, 367, 113, 292, 297, 137, +353, -52, 188, -211, -75, -305, -231, -318, +-315, -191, -287, -19, -71, 126, 150, 250, +306, 311, 435, 247, 358, 130, 66, -35, +-242, -207, -496, -299, -568, -287, -372, -204, +-76, -36, 189, 106, 371, 167, 383, 200, +301, 228, 213, 190, 111, 118, 6, 13, +-173, -145, -408, -314, -501, -383, -434, -323, +-242, -121, 91, 139, 405, 340, 529, 419, +458, 368, 245, 170, -12, -62, -231, -275, +-371, -433, -380, -420, -265, -202, -83, 44, +125, 242, 282, 345, 284, 288, 112, 118, +-144, -43, -321, -177, -281, -215, -44, -165, +246, -81, 406, 28, 320, 152, 104, 185, +-116, 141, -332, 48, -446, -103, -420, -270, +-304, -288, -61, -150, 246, 32, 497, 176, +635, 307, 536, 363, 179, 280, -263, 75, +-624, -166, -770, -410, -614, -554, -232, -504, +210, -231, 575, 156, 713, 527, 545, 708, +170, 600, -268, 259, -568, -150, -568, -527, +-342, -685, -45, -527, 216, -205, 333, 114, +285, 412, 104, 504, -99, 338, -161, 90, +-118, -154, -86, -327, -44, -256, 29, -64, +91, 93, 83, 212, -1, 234, -92, 86, +-139, -109, -159, -294, -162, -392, -75, -284, +123, -28, 300, 221, 377, 441, 307, 532, +26, 415, -337, 113, -550, -249, -552, -553, +-385, -675, -69, -568, 269, -216, 473, 255, +545, 633, 494, 741, 305, 584, 29, 193, +-352, -290, -745, -605, -850, -575, -622, -333, +-243, -74, 218, 100, 642, 189, 834, 202, +756, 201, 455, 207, 14, 241, -423, 230, +-743, 88, -857, -175, -680, -430, -299, -595, +109, -558, 451, -297, 650, 100, 657, 493, +516, 788, 245, 840, -113, 592, -457, 95, +-743, -470, -798, -900, -461, -1038, 18, -845, +338, -361, 511, 248, 540, 814, 362, 1124, +80, 1022, -146, 554, -294, -45, -371, -599, +-318, -925, -132, -934, 93, -645, 203, -172, +99, 305, -96, 565, -191, 615, -127, 505, +47, 244, 209, -78, 237, -269, 128, -279, +8, -127, -39, 69, -75, 153, -168, 38, +-316, -191, -429, -426, -352, -526, -63, -398, +310, -8, 599, 507, 624, 884, 350, 908, +-50, 607, -355, 82, -508, -502, -584, -937, +-515, -1028, -209, -768, 160, -281, 424, 242, +566, 647, 503, 803, 205, 715, -160, 436, +-406, 55, -452, -282, -340, -433, -185, -416, +-2, -239, 207, -46, 299, -44, 225, -177, +59, -221, -168, -193, -321, -34, -223, 332, +40, 688, 234, 782, 210, 595, 10, 107, +-161, -481, -210, -867, -149, -968, -11, -793, +64, -280, 32, 352, -4, 817, -2, 983, +58, 806, 96, 328, -68, -240, -291, -706, +-294, -885, -103, -704, 164, -245, 377, 304, +389, 732, 208, 797, -104, 466, -448, -98, +-591, -592, -492, -782, -279, -573, 96, -66, +527, 478, 681, 743, 505, 649, 130, 258, +-311, -232, -570, -556, -536, -607, -301, -447, +-32, -94, 125, 279, 231, 492, 312, 500, +246, 298, 33, -43, -271, -304, -501, -453, +-401, -449, -23, -196, 402, 169, 662, 428, +512, 541, 4, 412, -475, 74, -674, -338, +-575, -694, -287, -747, -25, -333, 163, 258, +352, 720, 456, 878, 442, 601, 290, -26, +-62, -634, -395, -925, -492, -741, -354, -200, +-43, 422, 140, 818, 17, 817, -154, 451, +-241, -101, -188, -649, 71, -898, 343, -717, +454, -234, 404, 356, 211, 829, -42, 899, +-300, 546, -545, -48, -619, -591, -477, -824, +-211, -693, 165, -288, 461, 273, 452, 674, +312, 724, 172, 446, -3, -46, -115, -522, +-227, -739, -324, -641, -200, -181, -7, 450, +87, 874, 95, 895, -88, 490, -330, -258, +-349, -930, -159, -1173, 186, -882, 531, -152, +582, 674, 328, 1184, -2, 1208, -273, 676, +-459, -182, -542, -932, -451, -1278, -195, -1078, +92, -372, 351, 476, 460, 1150, 265, 1352, +-40, 889, -256, -25, -341, -943, -144, -1476, +172, -1295, 273, -506, 249, 519, 113, 1364, +-173, 1590, -330, 1068, -389, 108, -481, -958, +-372, -1611, -71, -1453, 260, -662, 607, 375, +702, 1278, 431, 1523, 68, 1033, -267, 112, +-503, -846, -540, -1352, -467, -1164, -314, -498, +-78, 388, 138, 1096, 327, 1253, 422, 881, +314, 169, 101, -677, -96, -1245, -159, -1264, +-74, -725, -63, 110, -150, 843, -198, 1196, +-249, 1089, -204, 546, -19, -174, 97, -777, +196, -1023, 317, -804, 236, -286, 42, 273, +-111, 720, -311, 775, -420, 380, -288, -193, +-28, -683, 247, -796, 374, -354, 264, 295, +35, 829, -184, 1046, -251, 711, -209, -24, +-212, -736, -160, -1244, -33, -1258, 74, -674, +208, 177, 264, 986, 153, 1453, 7, 1241, +-170, 519, -243, -370, -67, -1128, 46, -1351, +-4, -917, -11, -149, -115, 658, -228, 1150, +-115, 1059, -72, 515, -86, -221, 79, -966, +179, -1306, 263, -986, 438, -205, 291, 682, +-75, 1361, -300, 1459, -513, 913, -605, 33, +-388, -880, -117, -1523, 97, -1516, 295, -923, +367, -49, 357, 873, 369, 1469, 274, 1404, +25, 843, -207, 5, -361, -836, -509, -1200, +-566, -980, -404, -456, -155, 212, 93, 659, +402, 644, 567, 407, 526, 100, 448, -293, +159, -479, -300, -350, -554, -68, -679, 270, +-674, 489, -323, 387, 109, 120, 443, -172, +722, -460, 651, -551, 226, -306, -186, 58, +-515, 347, -715, 484, -598, 383, -204, 117, +274, -105, 631, -308, 677, -447, 377, -329, +-98, -29, -475, 246, -614, 452, -540, 450, +-203, 245, 230, -6, 408, -287, 392, -518, +295, -507, 3, -357, -301, -90, -445, 303, +-437, 563, -136, 585, 297, 501, 518, 217, +530, -204, 264, -509, -285, -633, -669, -567, +-698, -259, -524, 107, -169, 381, 242, 527, +539, 496, 701, 269, 638, -57, 304, -324, +-140, -390, -557, -275, -837, -65, -796, 121, +-366, 208, 216, 202, 596, 116, 644, -59, +423, -197, -12, -254, -420, -217, -534, -37, +-387, 185, -20, 343, 431, 459, 634, 393, +532, 90, 139, -297, -482, -634, -901, -776, +-881, -558, -558, -92, -8, 462, 571, 927, +908, 1028, 956, 674, 661, 23, 86, -690, +-474, -1119, -870, -1068, -1002, -587, -723, 110, +-183, 741, 339, 1056, 701, 944, 709, 421, +361, -209, -26, -652, -260, -801, -344, -572, +-309, -90, -150, 292, 77, 466, 168, 367, +126, 8, 54, -302, -129, -393, -311, -315, +-334, 33, -228, 482, 91, 750, 504, 787, +605, 483, 344, -201, -81, -913, -523, -1405, +-694, -1466, -502, -824, -158, 323, 266, 1410, +608, 2025, 604, 1852, 343, 916, -9, -410, +-361, -1602, -564, -2143, -599, -1786, -453, -737, +-67, 548, 368, 1524, 616, 1794, 632, 1281, +436, 238, 65, -809, -398, -1334, -711, -1211, +-619, -499, -273, 481, 102, 1166, 425, 1228, +442, 698, 149, -197, -97, -1044, -228, -1496, +-277, -1339, -154, -533, 33, 564, 197, 1422, +312, 1789, 251, 1460, 98, 504, -101, -610, +-399, -1484, -551, -1848, -442, -1456, -185, -465, +199, 674, 486, 1520, 430, 1699, 218, 1118, +3, 86, -190, -1001, -168, -1649, -19, -1460, +54, -484, 131, 771, 72, 1669, -195, 1772, +-371, 1055, -428, -199, -411, -1473, -208, -2189, +162, -1994, 582, -936, 850, 597, 780, 1964, +415, 2576, -139, 2161, -673, 904, -915, -729, +-857, -2127, -552, -2684, -16, -2094, 461, -625, +618, 1056, 510, 2165, 230, 2235, -80, 1391, +-198, 41, -149, -1320, 16, -1977, 286, -1576, +353, -404, 84, 926, -313, 1750, -714, 1658, +-927, 772, -797, -537, -365, -1735, 332, -2148, +1077, -1508, 1464, -116, 1253, 1467, 512, 2449, +-437, 2320, -1246, 1189, -1542, -482, -1175, -2074, +-438, -2806, 336, -2250, 940, -669, 1079, 1231, +707, 2593, 176, 2765, -277, 1713, -585, -87, +-596, -1855, -299, -2792, 172, -2445, 587, -1039, +561, 816, 115, 2341, -333, 2778, -671, 1968, +-798, 411, -467, -1288, 137, -2446, 672, -2478, +929, -1439, 731, 122, 228, 1590, -338, 2217, +-820, 1718, -896, 570, -503, -635, 50, -1404, +583, -1330, 847, -576, 576, 316, -3, 895, +-504, 858, -805, 248, -768, -449, -392, -876, +105, -867, 630, -333, 1013, 471, 931, 1035, +418, 1151, -253, 786, -893, -2, -1212, -830, +-932, -1221, -210, -1057, 521, -426, 891, 374, +738, 872, 248, 883, -171, 529, -339, -105, +-326, -666, -145, -756, 103, -361, 233, 276, +276, 843, 173, 972, -158, 558, -464, -210, +-580, -1045, -484, -1478, -80, -1164, 451, -279, +760, 790, 712, 1578, 356, 1697, -142, 1065, +-513, 30, -616, -973, -496, -1637, -270, -1671, +6, -978, 354, 116, 591, 1152, 460, 1759, +91, 1567, -295, 614, -628, -469, -669, -1323, +-287, -1678, 185, -1157, 519, -117, 669, 748, +498, 1264, 170, 1263, -62, 672, -332, -30, +-653, -560, -758, -953, -582, -911, -252, -413, +240, 102, 732, 371, 828, 418, 558, 298, +244, 104, -37, -2, -279, 104, -427, 334, +-468, 467, -399, 293, -290, -224, -140, -826, +151, -1169, 362, -1088, 307, -459, 233, 541, +213, 1408, 111, 1819, 0, 1539, -111, 470, +-199, -837, -120, -1796, -4, -2122, -28, -1520, +-73, -242, -194, 985, -381, 1822, -295, 1969, +-21, 1251, 241, 108, 546, -990, 614, -1720, +354, -1613, 75, -822, -226, 146, -533, 1101, +-645, 1574, -603, 1140, -405, 181, 67, -739, +560, -1245, 733, -1073, 619, -328, 274, 563, +-231, 1233, -567, 1252, -580, 496, -423, -550, +-116, -1331, 275, -1548, 477, -1048, 470, 101, +385, 1359, 110, 1994, -317, 1719, -573, 666, +-598, -687, -442, -1775, 27, -2184, 515, -1673, +633, -402, 546, 947, 291, 1797, -146, 2000, +-448, 1463, -516, 373, -392, -739, -100, -1528, +196, -1648, 351, -1072, 336, -253, 149, 534, +-154, 1066, -394, 982, -434, 467, -268, -48, +72, -455, 438, -519, 570, -144, 412, 260, +158, 501, -204, 525, -627, 170, -664, -420, +-349, -867, -133, -948, 128, -637, 451, -59, +409, 629, 181, 1115, 47, 1088, -185, 641, +-298, 36, -61, -545, 199, -779, 342, -600, +362, -258, 111, 116, -329, 322, -740, 148, +-921, -182, -681, -466, -73, -527, 621, -172, +1134, 381, 1306, 892, 1043, 1267, 304, 1174, +-626, 486, -1258, -486, -1506, -1363, -1282, -1774, +-421, -1547, 527, -843, 1086, 246, 1323, 1279, +1050, 1682, 290, 1561, -417, 1025, -831, 76, +-916, -781, -584, -1194, -76, -1219, 362, -803, +658, -47, 582, 553, 178, 757, -323, 580, +-811, 147, -900, -328, -489, -643, 76, -569, +707, -147, 1170, 395, 1079, 936, 525, 1170, +-189, 860, -810, 167, -1137, -659, -1129, -1409, +-773, -1688, -222, -1313, 369, -417, 1016, 682, +1306, 1461, 960, 1713, 491, 1475, 21, 696, +-657, -284, -1097, -1020, -1009, -1394, -675, -1285, +-177, -681, 316, 36, 594, 571, 832, 802, +836, 680, 412, 356, -36, -7, -442, -208, +-798, -105, -764, 29, -414, 43, -22, 90, +320, 60, 529, -164, 527, -384, 277, -439, +-9, -287, -121, -24, -229, 301, -326, 638, +-256, 662, -264, 282, -280, -136, -58, -494, +75, -718, 142, -495, 417, -15, 559, 409, +470, 786, 267, 777, -238, 308, -723, -252, +-797, -807, -724, -1140, -417, -870, 240, -186, +682, 572, 781, 1238, 738, 1381, 417, 887, +-83, 149, -496, -665, -661, -1297, -534, -1393, +-248, -907, 122, -113, 419, 646, 387, 1175, +114, 1272, -190, 786, -370, -29, -208, -699, +115, -1018, 313, -890, 469, -281, 420, 393, +75, 804, -278, 858, -631, 448, -793, -266, +-498, -863, -112, -1027, 318, -763, 899, -140, +955, 781, 405, 1458, -88, 1327, -648, 655, +-1143, -102, -902, -976, -263, -1591, 320, -1435, +898, -723, 1130, 220, 778, 1054, 30, 1333, +-793, 1149, -1200, 644, -992, -200, -438, -833, +287, -816, 948, -480, 1141, -59, 773, 264, +77, 214, -575, -37, -904, -253, -856, -420, +-435, -259, 150, 246, 667, 698, 998, 946, +822, 899, 115, 424, -614, -337, -1035, -1110, +-1052, -1557, -567, -1346, 257, -535, 1031, 474, +1336, 1412, 896, 1897, 92, 1512, -552, 468, +-1021, -625, -1126, -1408, -680, -1749, -92, -1388, +349, -412, 666, 585, 754, 1287, 527, 1564, +104, 1230, -236, 391, -354, -486, -405, -1060, +-322, -1236, -67, -985, 31, -439, 2, 227, +-13, 740, -101, 882, -64, 792, 64, 581, +113, 225, 287, -214, 418, -529, 189, -693, +-84, -775, -270, -659, -543, -300, -481, 209, +-11, 748, 258, 1103, 396, 1046, 485, 580, +171, -91, -256, -823, -446, -1323, -501, -1299, +-308, -744, 192, 130, 668, 999, 864, 1583, +772, 1613, 278, 915, -615, -221, -1370, -1292, +-1523, -1990, -1080, -1956, -93, -1005, 1051, 361, +1716, 1614, 1804, 2410, 1236, 2267, -13, 1196, +-1179, -307, -1768, -1834, -1902, -2704, -1356, -2438, +-196, -1360, 861, 200, 1525, 1840, 1697, 2725, +1126, 2532, 212, 1511, -572, -55, -1128, -1607, +-1161, -2493, -742, -2486, -194, -1579, 389, -118, +624, 1347, 392, 2372, 153, 2423, -35, 1479, +-240, 137, -117, -1192, 254, -2122, 379, -2171, +266, -1368, 86, -201, -220, 983, -554, 1829, +-605, 2029, -346, 1507, -35, 443, 340, -706, +722, -1622, 750, -1982, 413, -1528, -106, -631, +-700, 374, -1045, 1321, -899, 1730, -336, 1409, +499, 795, 1209, 57, 1333, -701, 922, -1088, +159, -1152, -803, -961, -1496, -433, -1693, 101, +-1409, 465, -541, 747, 622, 843, 1567, 647, +2073, 340, 1877, 66, 940, -203, -251, -438, +-1344, -468, -2054, -334, -2040, -329, -1444, -307, +-575, -96, 440, -55, 1428, -63, 1985, 247, +1884, 611, 1401, 823, 547, 920, -709, 665, +-1592, 46, -1796, -660, -1793, -1274, -1327, -1588, +-157, -1425, 867, -730, 1405, 390, 1842, 1467, +1743, 2157, 887, 2339, -69, 1634, -935, 111, +-1630, -1471, -1761, -2646, -1308, -3019, -448, -2230, +544, -557, 1198, 1332, 1404, 2696, 1238, 3036, +645, 2425, -135, 1067, -706, -756, -998, -2192, +-1073, -2633, -832, -2273, -281, -1245, 212, 177, +550, 1360, 818, 1867, 721, 1686, 266, 1080, +-91, 238, -256, -551, -335, -884, -252, -806, +-91, -595, -75, -226, -100, 160, -129, 169, +-265, -13, -323, -168, -176, -285, 100, -164, +410, 154, 658, 550, 837, 904, 813, 883, +385, 516, -308, 47, -964, -561, -1370, -1122, +-1354, -1275, -915, -1103, -148, -524, 825, 385, +1583, 1021, 1753, 1296, 1347, 1288, 551, 794, +-423, 71, -1332, -550, -1757, -1034, -1445, -1150, +-714, -827, 125, -373, 910, 173, 1271, 767, +1041, 1075, 461, 878, -273, 262, -887, -405, +-897, -824, -394, -898, 190, -537, 736, 40, +938, 536, 548, 940, -125, 1003, -825, 553, +-1363, -27, -1334, -559, -657, -1007, 295, -1118, +1170, -873, 1669, -343, 1550, 408, 799, 957, +-305, 1102, -1275, 984, -1680, 563, -1330, 48, +-466, -340, 453, -683, 1149, -742, 1321, -519, +816, -371, -47, -252, -874, -91, -1341, -8, +-1095, 159, -201, 429, 810, 555, 1596, 653, +1859, 718, 1187, 552, -185, 237, -1574, -238, +-2441, -769, -2372, -1132, -1335, -1255, 252, -1048, +1833, -462, 2745, 385, 2552, 1211, 1438, 1618, +-172, 1436, -1809, 945, -2710, 236, -2461, -661, +-1385, -1238, 71, -1370, 1517, -1217, 2350, -694, +2141, 38, 1166, 637, -103, 993, -1391, 1098, +-2199, 901, -2097, 409, -1139, -224, 258, -728, +1520, -976, 2167, -952, 2012, -452, 1156, 319, +-90, 912, -1312, 1225, -2094, 1044, -2136, 208, +-1417, -788, -300, -1389, 819, -1507, 1745, -1182, +2139, -360, 1716, 814, 784, 1805, -214, 2147, +-1128, 1833, -1655, 897, -1560, -538, -1058, -1897, +-386, -2644, 324, -2553, 891, -1528, 1069, 75, +857, 1627, 512, 2647, 166, 2792, -128, 2075, +-316, 682, -339, -1074, -262, -2359, -362, -2640, +-513, -2169, -478, -1069, -411, 555, -211, 1840, +314, 2202, 754, 1873, 801, 1008, 707, -192, +443, -1198, -155, -1604, -650, -1416, -816, -788, +-831, 114, -527, 823, 75, 1031, 522, 836, +693, 383, 630, -125, 287, -386, -179, -378, +-543, -255, -633, 1, -322, 142, 167, -23, +481, -197, 615, -309, 635, -325, 234, -81, +-587, 299, -1101, 633, -992, 843, -594, 744, +95, 252, 1075, -428, 1659, -999, 1310, -1131, +455, -888, -443, -524, -1384, 167, -1986, 978, +-1696, 1283, -713, 1122, 393, 762, 1455, 142, +2267, -598, 2196, -1085, 1144, -1182, -300, -963, +-1644, -474, -2470, 232, -2378, 875, -1480, 1130, +-180, 1036, 1211, 648, 2176, -10, 2257, -652, +1635, -1078, 641, -1131, -508, -628, -1451, 94, +-1830, 660, -1631, 1053, -1063, 1076, -260, 614, +574, -53, 1151, -710, 1376, -1130, 1213, -1075, +699, -631, 91, 27, -433, 678, -824, 991, +-905, 1035, -750, 851, -582, 284, -231, -379, +280, -809, 572, -961, 718, -889, 790, -653, +490, -140, 3, 540, -279, 880, -552, 814, +-813, 711, -676, 413, -226, -87, 204, -347, +497, -447, 661, -546, 644, -542, 262, -401, +-306, -150, -578, 36, -514, 145, -497, 408, +-453, 711, -26, 675, 433, 464, 458, 276, +384, -123, 449, -662, 267, -986, -146, -907, +-262, -593, -202, -194, -353, 433, -473, 1022, +-394, 1138, -314, 889, -197, 485, 125, -100, +612, -714, 978, -1121, 946, -1157, 652, -718, +289, -119, -384, 385, -1236, 875, -1619, 1080, +-1387, 850, -745, 421, 266, -128, 1357, -589, +1975, -700, 1829, -628, 1016, -395, -178, 9, +-1280, 168, -1859, 83, -1801, 100, -1177, 79, +-159, 19, 892, 244, 1556, 620, 1649, 757, +1189, 518, 274, 32, -720, -476, -1352, -984, +-1450, -1423, -1037, -1422, -258, -722, 559, 372, +1063, 1351, 1094, 2067, 711, 2323, 123, 1637, +-433, 113, -780, -1451, -776, -2558, -505, -2977, +-168, -2306, 126, -730, 356, 1093, 533, 2561, +552, 3132, 370, 2731, 143, 1561, -69, -219, +-290, -2000, -455, -2976, -471, -3007, -449, -2231, +-417, -729, -148, 975, 291, 2374, 653, 3111, +939, 2793, 985, 1582, 499, 56, -278, -1438, +-856, -2638, -1172, -3011, -1159, -2315, -680, -1000, +-30, 475, 556, 1846, 1096, 2666, 1296, 2580, +963, 1838, 360, 680, -363, -782, -1060, -1968, +-1316, -2471, -1048, -2341, -533, -1534, 50, -258, +590, 987, 917, 1930, 953, 2331, 774, 1958, +429, 1075, -98, 41, -667, -953, -990, -1635, +-959, -1844, -750, -1597, -415, -931, 95, -57, +667, 726, 1116, 1255, 1310, 1481, 1133, 1374, +451, 925, -562, 241, -1387, -464, -1757, -989, +-1559, -1177, -731, -1097, 366, -844, 1271, -326, +1828, 303, 1891, 641, 1246, 713, 48, 757, +-1220, 645, -2087, 352, -2148, 89, -1335, -85, +12, -179, 1300, -305, 1958, -465, 1817, -526, +1029, -536, -130, -559, -1199, -441, -1757, -65, +-1616, 412, -831, 810, 281, 1064, 1300, 1208, +1819, 1073, 1493, 383, 440, -556, -813, -1296, +-1701, -1745, -1817, -1788, -1206, -1250, -244, -196, +865, 960, 1766, 1755, 1870, 2066, 1165, 1876, +125, 1042, -1010, -136, -1826, -1056, -1726, -1744, +-841, -2122, 198, -1728, 1017, -779, 1420, 213, +1156, 1118, 297, 1747, -478, 1831, -830, 1415, +-940, 665, -647, -256, 110, -1026, 819, -1409, +1129, -1423, 950, -1168, 212, -607, -755, 145, +-1408, 721, -1530, 1069, -1004, 1240, 31, 1008, +1013, 496, 1607, 14, 1733, -471, 1267, -822, +272, -828, -864, -655, -1621, -379, -1823, -49, +-1584, 94, -805, 136, 359, 256, 1210, 325, +1508, 408, 1481, 544, 1067, 587, 304, 573, +-463, 351, -1031, -240, -1262, -870, -1102, -1240, +-709, -1320, -180, -1009, 356, -297, 625, 551, +655, 1315, 670, 1716, 612, 1517, 347, 873, +-18, 47, -232, -771, -299, -1378, -427, -1488, +-464, -1080, -351, -473, -387, 158, -484, 594, +-308, 630, 82, 481, 494, 406, 890, 331, +1163, 348, 1153, 548, 790, 554, 33, 300, +-959, -85, -1805, -753, -2118, -1406, -1764, -1592, +-876, -1334, 500, -718, 2021, 292, 2786, 1406, +2455, 2131, 1470, 2191, 66, 1605, -1576, 626, +-2745, -581, -2859, -1682, -1999, -2126, -541, -1926, +1040, -1390, 2172, -573, 2459, 371, 1847, 1077, +629, 1398, -673, 1428, -1540, 1250, -1712, 940, +-1194, 531, -201, 13, 768, -563, 1195, -1079, +998, -1466, 330, -1714, -630, -1591, -1383, -917, +-1398, 40, -713, 1037, 317, 1911, 1317, 2295, +1946, 2061, 1950, 1378, 1242, 338, 0, -869, +-1373, -1863, -2412, -2381, -2720, -2324, -2136, -1732, +-867, -759, 662, 468, 2079, 1629, 2967, 2318, +2964, 2457, 2069, 2061, 585, 1149, -1109, -55, +-2602, -1226, -3388, -2133, -3071, -2586, -1802, -2306, +-75, -1327, 1626, -153, 2854, 944, 3205, 1958, +2551, 2455, 1165, 2105, -479, 1364, -1923, 440, +-2782, -743, -2747, -1711, -1777, -2092, -330, -1963, +1025, -1352, 1933, -338, 2162, 733, 1675, 1517, +719, 1831, -315, 1612, -1053, 936, -1382, -33, +-1368, -918, -901, -1435, -48, -1505, 564, -955, +693, -1, 779, 784, 823, 1203, 478, 1261, +66, 815, -79, -84, -339, -993, -877, -1497, +-1195, -1473, -993, -985, -482, -7, 177, 1230, +1012, 2044, 1724, 2141, 1886, 1660, 1430, 566, +486, -953, -816, -2218, -2188, -2735, -3066, -2526, +-2875, -1676, -1559, -188, 347, 1556, 2244, 2766, +3684, 3111, 4012, 2778, 2885, 1701, 810, -19, +-1544, -1687, -3622, -2806, -4720, -3268, -4327, -2910, +-2448, -1754, 291, -193, 2915, 1342, 4611, 2562, +4908, 3225, 3658, 3057, 1277, 2096, -1350, 742, +-3472, -784, -4611, -2282, -4403, -3242, -2857, -3325, +-471, -2623, 1949, -1277, 3657, 496, 4220, 2219, +3530, 3378, 1874, 3640, -161, 2939, -2012, 1398, +-3187, -618, -3437, -2493, -2803, -3662, -1389, -3734, +391, -2608, 1834, -681, 2630, 1382, 2736, 2994, +2090, 3642, 926, 3041, -313, 1429, -1321, -607, +-1893, -2328, -2004, -3179, -1781, -2981, -1175, -1703, +-235, 278, 651, 2071, 1295, 2936, 1755, 2716, +1946, 1611, 1662, -24, 872, -1670, -121, -2651, +-1101, -2568, -2029, -1691, -2570, -431, -2381, 959, +-1500, 1947, -155, 2129, 1375, 1714, 2679, 1023, +3341, 224, 3039, -507, 1737, -985, -117, -1178, +-1967, -1266, -3451, -1334, -4053, -1227, -3331, -863, +-1529, -275, 663, 567, 2688, 1565, 4059, 2398, +4209, 2762, 3016, 2425, 1027, 1270, -1189, -528, +-3083, -2417, -4024, -3717, -3801, -4088, -2592, -3344, +-676, -1438, 1381, 955, 2955, 3045, 3638, 4453, +3242, 4636, 2041, 3315, 512, 1129, -1160, -1204, +-2569, -3198, -3102, -4165, -2796, -3877, -1955, -2632, +-538, -809, 1085, 967, 2218, 2230, 2635, 2797, +2380, 2605, 1478, 1922, 191, 1038, -1002, 6, +-1818, -838, -2160, -1176, -1804, -1367, -854, -1558, +166, -1467, 973, -1136, 1433, -687, 1288, -78, +680, 703, 88, 1456, -330, 1907, -523, 1949, +-360, 1502, -85, 618, 47, -401, 39, -1310, +-150, -1996, -468, -2120, -689, -1579, -643, -778, +-190, 196, 593, 1224, 1301, 1800, 1585, 1794, +1348, 1366, 517, 584, -789, -381, -1994, -1203, +-2501, -1584, -2187, -1370, -1089, -713, 667, 112, +2411, 929, 3275, 1411, 3023, 1326, 1819, 750, +-152, -158, -2286, -1077, -3639, -1692, -3748, -1781, +-2711, -1165, -849, -35, 1359, 1153, 3205, 2065, +3977, 2424, 3447, 2032, 1947, 969, -76, -491, +-2057, -1849, -3312, -2630, -3476, -2780, -2679, -2186, +-1206, -835, 489, 643, 1808, 1809, 2435, 2567, +2398, 2655, 1801, 2082, 899, 1178, 33, 80, +-639, -1031, -1114, -1841, -1356, -2301, -1405, -2392, +-1369, -2054, -1199, -1352, -720, -288, 31, 1009, +797, 2269, 1482, 3185, 2098, 3371, 2288, 2656, +1748, 1136, 700, -870, -608, -2736, -1992, -3840, +-2921, -3922, -2969, -2920, -2171, -1052, -740, 999, +914, 2648, 2225, 3525, 2904, 3358, 2822, 2314, +1954, 825, 614, -630, -784, -1667, -1932, -2150, +-2495, -2118, -2383, -1712, -1754, -1143, -741, -550, +377, 61, 1216, 661, 1730, 1256, 1996, 1768, +1856, 1986, 1214, 1866, 349, 1291, -535, 185, +-1453, -1106, -2152, -2199, -2274, -2849, -1821, -2741, +-889, -1747, 446, -176, 1788, 1468, 2583, 2661, +2600, 3059, 1885, 2596, 639, 1334, -835, -292, +-2107, -1657, -2651, -2412, -2309, -2383, -1388, -1622, +-165, -539, 1081, 433, 1944, 1064, 2081, 1238, +1479, 1015, 564, 654, -189, 390, -674, 310, +-895, 314, -789, 280, -514, 66, -357, -480, +-372, -1176, -471, -1656, -503, -1718, -343, -1209, +23, -112, 576, 1196, 1239, 2188, 1782, 2528, +1869, 2110, 1189, 1076, -49, -277, -1293, -1560, +-2329, -2352, -2923, -2409, -2594, -1793, -1352, -808, +307, 250, 1902, 1169, 2985, 1631, 3219, 1577, +2553, 1355, 1158, 1050, -516, 539, -1928, 38, +-2738, -405, -2783, -987, -2124, -1508, -1064, -1764, +232, -1753, 1423, -1254, 1970, -245, 1875, 877, +1509, 1860, 972, 2531, 316, 2520, -251, 1712, +-600, 446, -904, -872, -1242, -1963, -1387, -2572, +-1241, -2484, -887, -1696, -290, -481, 463, 713, +1149, 1497, 1647, 1858, 1756, 1817, 1315, 1252, +569, 492, -270, 27, -1056, -258, -1458, -602, +-1409, -886, -1048, -1050, -423, -1135, 103, -1088, +337, -856, 508, -352, 482, 326, 179, 915, +144, 1366, 517, 1616, 847, 1553, 1000, 1199, +1007, 546, 570, -325, -457, -1160, -1660, -1855, +-2415, -2336, -2482, -2273, -1892, -1581, -625, -483, +1084, 886, 2628, 2265, 3516, 3216, 3439, 3340, +2288, 2523, 334, 963, -1825, -980, -3432, -2765, +-3977, -3854, -3454, -3922, -1974, -2871, 126, -914, +2089, 1302, 3304, 3092, 3618, 3990, 2979, 3639, +1517, 2267, -290, 424, -1878, -1488, -2801, -2774, +-2846, -2951, -2120, -2310, -939, -1228, 230, 41, +1115, 942, 1648, 1192, 1609, 1046, 1093, 675, +681, 300, 461, 267, 103, 626, -268, 1035, +-397, 1033, -614, 569, -1134, -253, -1459, -1457, +-1259, -2637, -827, -3033, -236, -2347, 700, -810, +1678, 1175, 2175, 2985, 2092, 4004, 1449, 3823, +273, 2340, -1103, 97, -2208, -2141, -2652, -3749, +-2217, -4156, -1093, -3205, 281, -1289, 1447, 906, +2069, 2594, 2100, 3212, 1573, 2723, 533, 1499, +-592, 34, -1334, -1184, -1612, -1768, -1384, -1510, +-585, -768, 341, -83, 865, 502, 1011, 806, +845, 473, 214, -190, -579, -695, -990, -925, +-990, -727, -721, -24, -42, 798, 868, 1344, +1497, 1471, 1658, 1135, 1335, 379, 446, -596, +-792, -1281, -1888, -1411, -2425, -1231, -2277, -802, +-1470, -151, -38, 388, 1645, 655, 2735, 746, +2858, 687, 2286, 533, 1041, 411, -720, 330, +-2095, 245, -2564, 42, -2380, -219, -1618, -365, +-302, -580, 967, -856, 1580, -874, 1557, -663, +1191, -404, 585, -37, -95, 442, -462, 860, +-332, 1120, -38, 1239, 88, 1222, 81, 871, +-90, 122, -564, -623, -1061, -1264, -1175, -1886, +-831, -2070, -156, -1558, 698, -658, 1441, 343, +1716, 1345, 1416, 2144, 708, 2417, -169, 1957, +-926, 957, -1350, -145, -1352, -1170, -947, -1867, +-316, -1952, 186, -1568, 378, -959, 434, -253, +439, 374, 276, 775, 154, 964, 264, 1011, +403, 949, 447, 812, 440, 627, 285, 430, +-103, 171, -600, -209, -997, -710, -1174, -1224, +-1081, -1516, -678, -1546, 23, -1302, 735, -623, +1158, 331, 1356, 1253, 1378, 2020, 1022, 2364, +308, 2058, -464, 1363, -1073, 410, -1468, -816, +-1543, -1892, -1120, -2516, -343, -2725, 346, -2387, +794, -1424, 1121, -34, 1208, 1495, 816, 2806, +203, 3458, -210, 3202, -455, 2114, -586, 457, +-388, -1404, -26, -2954, 100, -3626, 34, -3235, +-102, -1992, -417, -265, -656, 1398, -516, 2515, +-185, 2801, 232, 2222, 734, 1122, 1044, -6, +1060, -857, 795, -1265, 195, -1182, -506, -813, +-937, -412, -1071, -135, -970, -77, -583, -166, +-47, -267, 367, -206, 564, 113, 516, 520, +292, 858, 101, 1070, 77, 993, 127, 525, +177, -114, 324, -628, 461, -957, 299, -1104, +-93, -948, -522, -459, -927, 48, -1128, 349, +-989, 508, -611, 469, -101, 316, 501, 260, +1093, 218, 1481, 205, 1555, 355, 1282, 418, +662, 200, -174, -79, -992, -384, -1631, -771, +-1986, -1064, -1915, -1094, -1348, -750, -460, -141, +576, 505, 1604, 1125, 2321, 1493, 2439, 1356, +1924, 869, 964, 256, -250, -423, -1497, -950, +-2323, -1162, -2474, -1112, -2064, -806, -1184, -417, +25, -138, 1171, 141, 1899, 473, 2013, 710, +1590, 776, 934, 830, 195, 905, -545, 706, +-932, 185, -924, -342, -897, -782, -787, -1233, +-429, -1478, -196, -1269, -198, -692, -65, 26, +235, 702, 455, 1366, 679, 1812, 1004, 1644, +1117, 1015, 796, 232, 243, -687, -394, -1519, +-1051, -1872, -1485, -1649, -1481, -955, -1060, -68, +-301, 693, 611, 1288, 1293, 1511, 1491, 1203, +1257, 676, 693, 108, -98, -461, -885, -816, +-1267, -949, -1084, -937, -607, -674, -10, -250, +691, 114, 1156, 475, 1067, 827, 551, 990, +-127, 813, -852, 349, -1370, -131, -1344, -577, +-776, -982, 25, -1065, 822, -773, 1458, -286, +1694, 311, 1356, 835, 639, 1081, -220, 1085, +-1101, 794, -1707, 154, -1762, -541, -1361, -1038, +-673, -1211, 196, -1036, 972, -624, 1393, -25, +1537, 598, 1439, 993, 906, 1120, 47, 998, +-650, 594, -994, 75, -1177, -381, -1174, -793, +-802, -1048, -346, -1007, -105, -706, 165, -259, +579, 178, 821, 593, 828, 925, 800, 975, +744, 775, 537, 475, 179, 123, -277, -224, +-778, -570, -1268, -942, -1558, -1144, -1356, -1048, +-660, -707, 212, -60, 1052, 751, 1672, 1437, +1834, 1832, 1462, 1660, 697, 823, -272, -349, +-1227, -1471, -1799, -2213, -1705, -2249, -1116, -1499, +-301, -183, 635, 1247, 1369, 2212, 1438, 2438, +951, 1903, 336, 711, -333, -709, -950, -1869, +-1085, -2407, -657, -2088, -34, -1052, 492, 289, +841, 1485, 851, 2063, 461, 1801, -70, 956, +-504, -114, -804, -1020, -897, -1390, -717, -1189, +-289, -561, 251, 230, 696, 738, 923, 749, +912, 417, 660, -68, 300, -562, -54, -745, +-432, -365, -761, 314, -904, 812, -927, 986, +-809, 819, -400, 173, 179, -683, 701, -1248, +1077, -1365, 1234, -960, 1169, -122, 832, 766, +177, 1421, -580, 1609, -1189, 1076, -1576, 55, +-1633, -878, -1214, -1455, -371, -1541, 582, -1006, +1353, -34, 1808, 914, 1826, 1434, 1315, 1433, +456, 935, -480, 52, -1356, -830, -1896, -1343, +-1836, -1367, -1321, -911, -518, -140, 489, 591, +1363, 1035, 1760, 1108, 1648, 809, 1149, 349, +369, -103, -502, -476, -1127, -677, -1360, -650, +-1251, -390, -802, -115, -153, -45, 347, -35, +616, 33, 745, 29, 645, 87, 358, 394, +163, 671, 116, 734, 104, 630, 61, 270, +-59, -294, -275, -848, -564, -1213, -787, -1245, +-745, -902, -492, -258, -78, 552, 509, 1245, +999, 1496, 1146, 1253, 1007, 685, 589, 0, +-105, -644, -818, -1102, -1211, -1147, -1154, -817, +-744, -404, -182, 10, 407, 375, 854, 539, +936, 487, 680, 322, 258, 175, -232, 172, +-577, 217, -626, 172, -391, 153, 17, 88, +359, -199, 474, -520, 430, -689, 222, -742, +-161, -631, -519, -241, -664, 288, -602, 724, +-342, 1014, 110, 1025, 607, 659, 894, 154, +851, -282, 536, -685, 75, -896, -377, -756, +-662, -538, -756, -312, -684, 57, -453, 359, +-109, 499, 277, 585, 590, 549, 659, 384, +506, 188, 270, -67, 1, -313, -215, -407, +-292, -415, -277, -326, -219, -124, -111, 38, +41, 118, 138, 105, 65, 28, -117, -9, +-193, -36, -143, -70, -92, 62, 32, 317, +266, 408, 401, 396, 346, 371, 236, 104, +149, -368, -31, -681, -302, -745, -493, -711, +-499, -464, -316, 11, -32, 378, 174, 582, +241, 759, 219, 770, 130, 521, 34, 215, +50, -25, 159, -257, 230, -463, 220, -611, +176, -685, 93, -697, -97, -629, -384, -353, +-627, 84, -722, 546, -617, 967, -288, 1197, +216, 1131, 736, 824, 1080, 306, 1116, -361, +833, -947, 255, -1331, -486, -1483, -1049, -1306, +-1231, -828, -1089, -134, -633, 629, 37, 1268, +649, 1707, 1003, 1837, 1016, 1492, 690, 723, +222, -245, -250, -1211, -689, -1943, -860, -2238, +-590, -1958, -117, -1095, 339, 47, 695, 1129, +767, 1983, 466, 2314, -31, 1914, -542, 1002, +-924, -50, -995, -996, -709, -1605, -176, -1656, +530, -1195, 1161, -543, 1397, 37, 1202, 416, +662, 514, -200, 414, -1036, 302, -1417, 242, +-1383, 373, -1082, 703, -434, 858, 382, 656, +938, 209, 1102, -476, 1065, -1236, 833, -1668, +325, -1575, -194, -991, -426, -35, -535, 982, +-664, 1713, -604, 1873, -347, 1388, -166, 518, +-75, -434, 89, -1175, 268, -1406, 305, -1092, +310, -467, 408, 176, 396, 583, 160, 634, +-21, 379, -80, -46, -195, -375, -220, -417, +-63, -208, -49, 222, -269, 684, -465, 825, +-500, 597, -391, 162, -149, -372, 226, -851, +677, -1058, 1010, -880, 1044, -376, 764, 199, +287, 653, -316, 927, -918, 849, -1255, 404, +-1160, -117, -765, -489, -261, -619, 262, -475, +684, -124, 898, 262, 911, 517, 700, 523, +326, 288, -22, -94, -244, -482, -346, -763, +-362, -873, -361, -642, -361, -48, -364, 555, +-362, 971, -285, 1206, -146, 1132, 4, 685, +248, 12, 538, -695, 713, -1226, 796, -1467, +788, -1390, 529, -870, 39, -54, -501, 674, +-971, 1269, -1270, 1616, -1304, 1422, -1022, 830, +-402, 176, 423, -493, 1179, -1085, 1616, -1344, +1617, -1192, 1175, -759, 397, -253, -470, 190, +-1134, 539, -1447, 723, -1337, 739, -849, 670, +-212, 567, 339, 414, 727, 152, 828, -193, +597, -546, 269, -844, 68, -956, 27, -792, +119, -416, 198, 118, 154, 677, -2, 945, +-279, 869, -650, 599, -895, 115, -812, -410, +-421, -634, 123, -552, 676, -298, 1060, 58, +1101, 380, 735, 503, 121, 335, -455, -98, +-798, -557, -855, -815, -589, -771, -125, -341, +241, 351, 414, 952, 468, 1214, 288, 1077, +-86, 587, -309, -170, -312, -907, -270, -1263, +-86, -1205, 256, -861, 474, -211, 477, 559, +368, 1012, 117, 1057, -219, 820, -444, 313, +-478, -258, -410, -621, -278, -693, -87, -509, +105, -156, 231, 204, 302, 400, 324, 383, +301, 225, 267, -24, 208, -304, 54, -432, +-164, -331, -329, -188, -375, -27, -368, 224, +-334, 415, -179, 445, 79, 420, 254, 371, +326, 177, 371, -130, 307, -382, 76, -590, +-145, -761, -238, -738, -214, -456, -96, -55, +61, 451, 187, 958, 224, 1144, 134, 948, +-34, 533, -225, -44, -395, -657, -488, -1050, +-431, -1067, -186, -781, 197, -327, 571, 178, +808, 600, 835, 757, 595, 624, 132, 322, +-348, -42, -713, -282, -933, -256, -913, -78, +-595, 144, -143, 332, 251, 337, 541, 79, +721, -313, 715, -667, 531, -883, 295, -874, +80, -512, -126, 153, -263, 822, -268, 1269, +-230, 1436, -319, 1207, -525, 567, -667, -283, +-617, -1081, -370, -1609, 47, -1754, 598, -1455, +1129, -671, 1366, 374, 1217, 1266, 782, 1780, +133, 1844, -652, 1392, -1359, 518, -1762, -484, +-1698, -1251, -1156, -1609, -326, -1570, 561, -1083, +1363, -235, 1843, 563, 1803, 1053, 1298, 1196, +516, 959, -359, 443, -1107, -113, -1531, -527, +-1540, -638, -1174, -445, -578, -122, 87, 198, +677, 361, 998, 243, 972, -49, 740, -380, +428, -603, 74, -551, -159, -228, -143, 203, +-58, 623, -108, 883, -187, 860, -257, 556, +-475, 53, -713, -474, -688, -854, -492, -1010, +-208, -851, 305, -413, 949, 91, 1367, 489, +1407, 757, 1078, 857, 412, 697, -436, 315, +-1208, -62, -1678, -345, -1670, -595, -1223, -674, +-516, -481, 340, -226, 1129, 10, 1525, 248, +1478, 372, 1140, 373, 563, 338, -141, 198, +-679, -40, -975, -219, -1090, -238, -936, -141, +-563, -54, -193, 35, 141, 168, 466, 116, +660, -129, 649, -246, 524, -226, 369, -245, +213, -133, 28, 201, -175, 491, -289, 575, +-313, 505, -379, 280, -430, -148, -363, -659, +-252, -927, -140, -828, 76, -482, 354, 38, +552, 639, 632, 1058, 566, 1117, 326, 805, +19, 202, -309, -519, -631, -1114, -745, -1352, +-558, -1088, -253, -432, 112, 364, 505, 1047, +657, 1409, 431, 1291, 66, 688, -250, -195, +-462, -998, -455, -1434, -181, -1365, 217, -801, +544, 81, 669, 947, 561, 1459, 194, 1389, +-354, 796, -825, -44, -999, -870, -855, -1433, +-446, -1452, 154, -884, 764, 5, 1108, 860, +1049, 1451, 692, 1550, 201, 1009, -331, 67, +-716, -807, -791, -1388, -665, -1552, -475, -1129, +-192, -289, 92, 545, 222, 1177, 255, 1440, +347, 1169, 445, 519, 410, -184, 333, -782, +328, -1126, 217, -1072, -105, -689, -460, -161, +-708, 341, -829, 683, -724, 811, -364, 684, +125, 342, 561, -54, 806, -349, 816, -526, +663, -517, 378, -273, 27, 26, -264, 217, +-482, 352, -666, 388, -697, 185, -536, -179, +-315, -445, -87, -527, 218, -426, 537, -119, +747, 339, 791, 729, 627, 861, 265, 720, +-145, 318, -517, -303, -800, -886, -859, -1194, +-647, -1168, -282, -753, 162, 42, 608, 848, +871, 1318, 811, 1433, 466, 1130, -21, 337, +-450, -580, -690, -1157, -688, -1359, -435, -1249, +-20, -684, 368, 154, 621, 804, 681, 1093, +457, 1091, -7, 753, -449, 167, -719, -367, +-799, -676, -580, -773, -45, -681, 509, -421, +829, -37, 900, 316, 706, 524, 246, 604, +-289, 553, -708, 326, -907, -4, -813, -334, +-456, -608, 10, -722, 431, -566, 682, -215, +716, 189, 526, 569, 164, 842, -213, 807, +-419, 432, -426, -40, -278, -467, -15, -815, +234, -885, 284, -619, 154, -194, -62, 263, +-345, 656, -553, 776, -435, 585, -54, 263, +325, -34, 634, -280, 861, -395, 785, -297, +344, -154, -239, -153, -751, -138, -1068, -71, +-1046, -100, -649, -96, -30, 113, 571, 338, +974, 461, 1053, 506, 757, 387, 221, 86, +-292, -289, -629, -614, -770, -719, -683, -570, +-339, -276, 134, 97, 485, 461, 565, 624, +448, 540, 214, 348, -120, 133, -413, -147, +-470, -392, -335, -404, -148, -260, 78, -178, +325, -104, 474, -1, 489, 60, 428, 119, +250, 210, -107, 271, -520, 309, -779, 274, +-791, 81, -602, -214, -233, -476, 275, -579, +718, -458, 887, -184, 867, 239, 743, 667, +388, 785, -182, 564, -703, 172, -1047, -377, +-1131, -847, -849, -909, -305, -597, 258, -75, +725, 533, 1004, 969, 964, 1037, 625, 674, +214, -22, -168, -744, -536, -1174, -749, -1180, +-642, -725, -324, 56, -15, 856, 184, 1343, +271, 1335, 251, 852, 115, 44, -82, -843, +-145, -1433, -30, -1530, 104, -1116, 248, -236, +415, 767, 397, 1398, 160, 1552, -107, 1265, +-353, 508, -606, -468, -731, -1190, -586, -1426, +-220, -1223, 226, -703, 636, 59, 860, 815, +779, 1186, 426, 1080, -21, 674, -388, 80, +-551, -498, -483, -794, -275, -733, -57, -432, +96, -26, 120, 316, 17, 457, -135, 325, +-214, 34, -143, -230, 89, -355, 422, -252, +697, 65, 718, 368, 443, 523, -43, 460, +-583, 100, -946, -377, -975, -664, -697, -707, +-202, -502, 367, -28, 812, 535, 947, 895, +719, 878, 250, 482, -182, -104, -424, -688, +-472, -1051, -326, -986, -77, -498, 84, 167, +91, 762, 8, 1085, -81, 1008, -149, 583, +-173, -2, -97, -587, 127, -991, 392, -1034, +522, -698, 417, -210, 100, 255, -302, 585, +-551, 679, -498, 586, -226, 412, 109, 192, +424, 33, 529, -24, 277, -103, -119, -282, +-434, -496, -712, -687, -748, -744, -269, -603, +437, -245, 970, 336, 1261, 958, 1128, 1335, +409, 1327, -549, 913, -1225, 188, -1494, -648, +-1380, -1334, -820, -1648, 107, -1484, 999, -920, +1488, -53, 1521, 862, 1144, 1451, 354, 1582, +-569, 1312, -1151, 675, -1224, -149, -949, -852, +-439, -1198, 174, -1185, 581, -905, 625, -409, +490, 188, 256, 629, -69, 780, -266, 699, +-200, 470, -40, 153, 118, -155, 274, -358, +321, -377, 188, -278, -37, -129, -281, 56, +-489, 194, -574, 222, -474, 168, -210, -12, +125, -250, 420, -358, 625, -308, 682, -182, +532, 5, 254, 210, 9, 411, -215, 519, +-486, 433, -668, 255, -613, 57, -420, -224, +-185, -457, 80, -539, 305, -545, 415, -473, +442, -266, 445, -9, 428, 255, 315, 513, +101, 715, -120, 765, -300, 582, -453, 258, +-512, -79, -485, -449, -458, -752, -369, -852, +-98, -784, 288, -602, 641, -253, 856, 202, +891, 599, 705, 863, 320, 1016, -136, 968, +-563, 602, -977, 81, -1231, -370, -1068, -837, +-509, -1221, 164, -1228, 762, -874, 1146, -360, +1152, 244, 792, 834, 299, 1222, -167, 1259, +-555, 944, -780, 407, -750, -199, -505, -708, +-163, -937, 138, -922, 309, -733, 340, -367, +246, 21, 73, 266, -32, 408, -24, 466, +23, 431, 120, 345, 288, 270, 370, 238, +242, 185, -57, 38, -410, -133, -684, -372, +-754, -697, -567, -833, -137, -656, 371, -367, +724, 17, 843, 523, 796, 954, 544, 1126, +45, 1001, -490, 593, -793, 6, -864, -642, +-725, -1165, -309, -1353, 243, -1125, 616, -574, +714, 130, 630, 782, 377, 1211, -20, 1282, +-361, 964, -521, 363, -529, -310, -367, -834, +-14, -1074, 333, -1000, 472, -584, 412, -16, +238, 392, -6, 595, -224, 655, -328, 500, +-300, 228, -191, 5, -65, -168, 39, -269, +110, -247, 131, -199, 142, -181, 163, -180, +162, -156, 169, -61, 180, 90, 85, 244, +-99, 399, -268, 488, -411, 402, -504, 108, +-422, -280, -176, -605, 125, -762, 459, -669, +756, -265, 784, 285, 483, 740, 58, 957, +-326, 825, -620, 334, -704, -277, -525, -757, +-224, -953, 43, -808, 213, -382, 286, 178, +297, 651, 209, 822, 66, 672, 72, 289, +230, -182, 295, -508, 245, -548, 141, -352, +-151, 0, -596, 319, -876, 393, -841, 222, +-533, -68, 3, -364, 612, -540, 1039, -461, +1170, -90, 967, 377, 442, 714, -249, 836, +-867, 661, -1212, 149, -1135, -448, -676, -878, +-51, -1031, 516, -832, 864, -358, 881, 202, +607, 701, 183, 928, -205, 855, -395, 616, +-392, 217, -291, -275, -77, -579, 148, -672, +168, -671, 29, -524, -87, -230, -191, 75, +-249, 330, -142, 516, 76, 586, 249, 476, +352, 248, 381, 11, 270, -195, 50, -348, +-147, -364, -274, -278, -329, -191, -282, -107, +-154, -24, -38, 12, 22, 18, 55, 59, +97, 180, 149, 277, 193, 321, 205, 360, +172, 277, 110, -6, 57, -285, -24, -476, +-151, -609, -238, -541, -272, -261, -320, 37, +-291, 319, -123, 552, 79, 619, 282, 483, +493, 202, 556, -92, 436, -276, 209, -387, +-129, -424, -499, -313, -660, -129, -546, -29, +-283, 32, 26, 122, 313, 193, 488, 200, +477, 228, 266, 261, -26, 156, -218, -40, +-256, -157, -213, -251, -107, -334, 80, -253, +249, -36, 249, 131, 104, 217, -90, 232, +-284, 131, -424, -62, -387, -221, -109, -259, +283, -171, 532, 8, 546, 251, 403, 438, +124, 460, -242, 278, -474, -73, -484, -447, +-378, -654, -173, -650, 119, -454, 315, -72, +334, 367, 261, 636, 124, 679, -47, 544, +-111, 276, -58, -65, 10, -319, 41, -409, +-3, -389, -141, -316, -266, -229, -269, -193, +-141, -166, 82, -84, 337, 62, 508, 308, +501, 631, 271, 786, -91, 664, -412, 372, +-618, -78, -674, -656, -470, -1092, -57, -1166, +366, -886, 695, -333, 855, 367, 686, 973, +220, 1300, -274, 1225, -611, 749, -785, 56, +-737, -600, -415, -1058, 12, -1179, 316, -901, +487, -354, 581, 216, 546, 653, 351, 832, +114, 719, -91, 390, -286, -14, -470, -342, +-556, -462, -466, -391, -247, -210, -1, 24, +262, 234, 497, 302, 565, 193, 427, -21, +204, -218, -40, -332, -285, -309, -425, -119, +-359, 147, -172, 337, 18, 418, 167, 377, +203, 165, 81, -163, -92, -409, -190, -459, +-151, -324, 6, -66, 224, 231, 404, 428, +456, 423, 315, 197, 0, -166, -381, -501, +-670, -602, -738, -431, -506, -71, -45, 387, +459, 804, 818, 934, 886, 661, 593, 118, +63, -491, -461, -1009, -793, -1215, -837, -957, +-546, -338, -43, 362, 418, 921, 664, 1171, +679, 1034, 450, 562, 31, -65, -351, -596, +-486, -835, -418, -768, -254, -457, -18, -45, +181, 253, 212, 318, 150, 208, 73, -19, +-28, -204, -49, -170, 90, 56, 213, 337, +179, 588, 67, 657, -70, 431, -289, -5, +-469, -498, -382, -904, -60, -1028, 209, -813, +318, -350, 356, 212, 290, 693, 73, 938, +-132, 910, -192, 647, -147, 278, -23, -68, +152, -337, 231, -507, 122, -562, -126, -569, +-409, -554, -612, -462, -559, -258, -199, 11, +294, 351, 732, 738, 1017, 1005, 971, 985, +519, 709, -148, 225, -785, -410, -1214, -977, +-1226, -1236, -783, -1157, -114, -770, 531, -176, +957, 423, 1001, 861, 718, 1050, 304, 940, +-94, 634, -347, 251, -388, -155, -322, -483, +-227, -648, -143, -692, -170, -611, -302, -411, +-346, -156, -224, 104, 14, 347, 372, 507, +758, 563, 931, 507, 784, 318, 377, 39, +-154, -188, -674, -320, -1063, -399, -1154, -386, +-836, -239, -280, -100, 277, -19, 773, 79, +1089, 137, 1000, 128, 599, 159, 163, 187, +-231, 165, -576, 152, -746, 110, -698, -2, +-494, -97, -213, -194, 94, -281, 371, -261, +526, -175, 469, -80, 288, 61, 128, 172, +-18, 213, -183, 219, -257, 185, -184, 113, +-61, 42, 34, -50, 97, -138, 71, -162, +-84, -178, -265, -215, -304, -154, -169, -2, +58, 116, 309, 199, 522, 311, 568, 307, +410, 116, 115, -108, -279, -286, -673, -437, +-827, -433, -635, -206, -211, 138, 290, 464, +688, 646, 790, 584, 599, 306, 252, -144, +-153, -601, -486, -827, -595, -763, -493, -447, +-251, 74, 77, 585, 377, 854, 479, 827, +332, 528, 58, 33, -155, -412, -231, -649, +-193, -651, -79, -426, 80, -61, 174, 224, +135, 305, 1, 241, -144, 86, -222, -117, +-179, -186, -21, -44, 229, 182, 445, 368, +444, 464, 187, 343, -181, -4, -489, -416, +-601, -711, -459, -768, -133, -572, 217, -172, +499, 338, 652, 716, 561, 819, 216, 679, +-147, 356, -371, -84, -505, -445, -514, -588, +-284, -524, 44, -323, 242, -81, 283, 87, +233, 132, 122, 91, 18, 42, -28, 18, +-2, 92, 94, 259, 212, 383, 226, 387, +42, 269, -285, -2, -571, -357, -679, -636, +-561, -736, -179, -613, 400, -277, 878, 154, +1015, 571, 823, 812, 394, 775, -205, 549, +-780, 199, -1109, -233, -1085, -559, -695, -690, +-59, -666, 547, -492, 916, -189, 978, 132, +738, 408, 288, 558, -166, 558, -475, 457, +-595, 264, -530, 6, -347, -245, -161, -445, +-23, -537, 56, -520, 93, -384, 115, -119, +190, 194, 354, 457, 509, 636, 489, 628, +265, 398, -102, 58, -497, -309, -786, -591, +-865, -655, -694, -544, -257, -282, 309, 76, +762, 389, 968, 560, 924, 577, 595, 421, +34, 184, -534, -68, -883, -326, -922, -499, +-681, -518, -293, -414, 127, -199, 471, 47, +605, 284, 502, 476, 315, 533, 158, 429, +12, 227, -104, -50, -159, -308, -233, -452, +-320, -496, -337, -414, -290, -182, -199, 85, +-21, 303, 201, 390, 378, 342, 475, 233, +473, 85, 327, -72, 35, -143, -316, -145, +-543, -113, -556, -57, -405, -60, -151, -119, +145, -128, 354, -127, 424, -97, 387, 22, +227, 190, -18, 334, -211, 389, -309, 308, +-309, 122, -151, -124, 99, -338, 198, -422, +116, -407, 38, -322, 9, -99, -33, 131, +-19, 261, 45, 357, 42, 392, -14, 296, +-47, 142, -82, -14, -104, -161, -69, -280, +-1, -324, 90, -279, 231, -187, 328, -110, +249, -1, 0, 127, -276, 229, -437, 304, +-419, 322, -230, 255, 66, 140, 326, -25, +434, -220, 398, -374, 258, -423, 27, -357, +-201, -177, -331, 61, -336, 289, -217, 410, +25, 399, 251, 300, 298, 94, 172, -167, +-21, -289, -203, -274, -273, -217, -190, -126, +14, -10, 280, 86, 482, 134, 472, 101, +244, 57, -100, 75, -423, 79, -626, 27, +-636, -16, -393, -53, 56, -74, 480, -89, +720, -81, 773, -30, 574, 21, 115, 53, +-359, 95, -654, 86, -741, 20, -599, 4, +-244, 2, 175, -78, 496, -135, 632, -118, +593, -52, 396, 28, 63, 109, -303, 188, +-531, 236, -549, 188, -404, 49, -142, -126, +197, -282, 464, -365, 516, -333, 389, -202, +185, 35, -99, 310, -383, 499, -508, 485, +-411, 278, -157, 3, 166, -250, 434, -423, +525, -425, 406, -269, 143, -34, -193, 158, +-481, 216, -595, 162, -498, 93, -240, -9, +159, -88, 593, -31, 826, 100, 734, 211, +371, 266, -180, 168, -701, -43, -956, -281, +-898, -500, -567, -573, -22, -397, 553, -102, +960, 238, 1068, 591, 821, 767, 281, 666, +-351, 382, -861, -8, -1050, -408, -855, -708, +-421, -796, 47, -637, 438, -306, 666, 49, +675, 361, 475, 592, 163, 676, -129, 572, +-308, 346, -352, 110, -239, -115, -48, -373, +33, -566, -66, -643, -184, -623, -233, -483, +-235, -172, -117, 270, 140, 726, 367, 1005, +488, 983, 513, 667, 398, 126, 107, -513, +-273, -1018, -593, -1212, -733, -1015, -675, -520, +-429, 107, -49, 716, 301, 1102, 511, 1101, +606, 791, 549, 309, 353, -246, 121, -712, +-119, -907, -362, -835, -496, -589, -505, -235, +-450, 191, -315, 543, -92, 693, 140, 672, +343, 519, 503, 215, 569, -127, 452, -414, +158, -586, -168, -560, -419, -381, -600, -182, +-628, 78, -402, 327, -29, 407, 308, 391, +556, 334, 626, 156, 408, -32, 14, -158, +-335, -285, -564, -360, -591, -289, -345, -164, +35, -38, 369, 84, 591, 191, 594, 278, +363, 332, 31, 303, -329, 189, -640, 7, +-718, -229, -528, -483, -197, -619, 194, -524, +555, -204, 733, 209, 682, 595, 453, 838, +110, 815, -294, 458, -631, -98, -740, -622, +-599, -973, -322, -1040, 35, -679, 403, -56, +615, 526, 577, 929, 392, 1048, 158, 748, +-124, 193, -361, -335, -388, -689, -251, -767, +-96, -564, 62, -224, 203, 139, 210, 370, +81, 358, -72, 180, -174, 3, -196, -101, +-95, -77, 129, 66, 363, 239, 448, 339, +371, 273, 188, 6, -108, -340, -445, -594, +-620, -631, -545, -447, -292, -72, 41, 379, +395, 704, 662, 755, 708, 546, 505, 144, +158, -307, -245, -605, -567, -657, -634, -498, +-445, -154, -130, 253, 214, 551, 436, 591, +422, 369, 240, 7, 20, -360, -150, -604, +-180, -580, -69, -278, 71, 153, 148, 548, +165, 749, 132, 615, 29, 237, -155, -202, +-304, -559, -310, -718, -198, -611, -11, -314, +270, 35, 528, 315, 560, 469, 345, 484, +44, 399, -253, 238, -508, 44, -620, -139, +-485, -263, -147, -345, 243, -368, 537, -279, +679, -121, 605, 21, 280, 174, -158, 306, +-501, 333, -681, 225, -644, 39, -355, -157, +71, -250, 447, -208, 681, -57, 709, 156, +497, 323, 100, 323, -347, 153, -687, -143, +-777, -450, -633, -649, -329, -615, 103, -331, +549, 115, 806, 586, 808, 945, 610, 1029, +221, 760, -296, 209, -729, -450, -947, -997, +-894, -1261, -551, -1211, -39, -790, 462, -62, +847, 716, 960, 1273, 727, 1472, 307, 1237, +-136, 608, -538, -227, -752, -989, -710, -1412, +-516, -1364, -251, -890, 61, -128, 287, 589, +366, 994, 386, 1032, 376, 732, 288, 200, +167, -255, 53, -416, -79, -334, -245, -153, +-430, 1, -586, -22, -604, -208, -438, -388, +-135, -411, 241, -248, 585, 124, 775, 584, +764, 860, 514, 799, 77, 453, -371, -91, +-713, -646, -932, -970, -911, -950, -583, -613, +-76, -51, 436, 492, 823, 839, 966, 911, +794, 683, 347, 253, -190, -219, -631, -618, +-862, -808, -812, -729, -488, -443, -46, -23, +311, 417, 493, 671, 507, 691, 346, 521, +99, 200, -89, -177, -181, -456, -212, -553, +-164, -475, -93, -291, -91, -50, -138, 173, +-150, 301, -108, 298, 10, 263, 182, 235, +321, 166, 344, 32, 206, -86, -20, -190, +-209, -338, -350, -419, -393, -303, -260, -109, +-46, 88, 146, 304, 318, 450, 394, 416, +289, 255, 43, 17, -227, -218, -385, -357, +-349, -388, -175, -287, 81, -50, 330, 166, +434, 259, 338, 252, 123, 168, -145, 3, +-392, -138, -516, -183, -439, -149, -173, -94, +189, -25, 506, 56, 673, 111, 636, 139, +377, 197, -56, 232, -480, 170, -719, -16, +-710, -268, -457, -507, -42, -609, 320, -476, +496, -96, 538, 397, 506, 798, 395, 920, +231, 705, 48, 239, -175, -288, -475, -739, +-712, -950, -661, -850, -359, -526, 21, -99, +443, 350, 767, 682, 792, 828, 568, 806, +239, 594, -153, 181, -486, -304, -613, -710, +-510, -904, -229, -863, 119, -587, 354, -93, +402, 471, 276, 851, 42, 903, -177, 651, +-245, 223, -121, -251, 131, -586, 359, -648, +441, -443, 327, -154, 52, 102, -275, 256, +-495, 259, -513, 188, -368, 153, -143, 104, +127, -21, 381, -176, 563, -273, 631, -261, +520, -81, 229, 208, -132, 449, -498, 479, +-740, 243, -651, -192, -284, -606, 70, -727, +310, -483, 460, -53, 483, 405, 378, 736, +224, 778, 64, 488, -133, 35, -367, -410, +-463, -709, -328, -767, -98, -550, 119, -129, +301, 337, 327, 661, 178, 732, 13, 521, +-86, 132, -149, -272, -146, -502, -64, -503, +32, -342, 82, -114, 109, 98, 128, 194, +70, 180, -107, 169, -259, 169, -252, 110, +-136, 45, 20, -18, 247, -83, 422, -101, +329, -52, 12, -21, -305, -50, -505, -132, +-488, -217, -210, -218, 183, -65, 470, 210, +525, 475, 327, 536, 15, 355, -252, 5, +-462, -372, -561, -587, -432, -537, -144, -291, +190, 65, 489, 398, 601, 510, 426, 361, +69, 108, -298, -174, -529, -386, -534, -384, +-340, -158, -86, 138, 137, 373, 296, 439, +347, 290, 265, 0, 96, -309, -124, -526, +-335, -517, -406, -301, -260, -14, -9, 270, +215, 524, 337, 602, 277, 457, 52, 191, +-205, -124, -395, -430, -445, -592, -320, -535, +-68, -311, 205, -31, 443, 233, 561, 405, +435, 424, 85, 304, -304, 163, -617, 28, +-749, -116, -591, -216, -199, -257, 237, -262, +592, -169, 738, -17, 571, 99, 192, 161, +-184, 164, -464, 64, -600, -35, -538, -53, +-288, -20, 25, 52, 259, 133, 374, 132, +394, 44, 277, -72, 19, -165, -246, -223, +-373, -208, -331, -124, -143, 7, 131, 142, +364, 252, 415, 291, 239, 221, -78, 84, +-381, -76, -574, -248, -563, -353, -278, -326, +195, -165, 603, 64, 776, 312, 701, 465, +387, 431, -124, 222, -604, -120, -814, -504, +-762, -727, -537, -642, -135, -274, 367, 272, +757, 819, 875, 1059, 731, 878, 371, 361, +-121, -353, -554, -1016, -731, -1313, -671, -1120, +-462, -519, -109, 272, 293, 954, 561, 1310, +669, 1262, 591, 754, 262, -11, -194, -701, +-506, -1117, -546, -1148, -339, -776, 9, -201, +320, 331, 414, 690, 280, 804, 43, 632, +-166, 270, -264, -108, -210, -328, -44, -377, +139, -285, 309, -64, 420, 151, 335, 186, +50, 42, -272, -167, -456, -333, -478, -355, +-343, -164, 6, 128, 468, 389, 699, 540, +599, 544, 342, 344, 1, -7, -382, -357, +-607, -612, -581, -694, -359, -506, -26, -141, +299, 247, 550, 552, 684, 635, 575, 437, +237, 145, -168, -118, -532, -338, -723, -404, +-586, -300, -199, -151, 210, 20, 506, 178, +644, 241, 552, 220, 256, 153, -82, 3, +-353, -125, -532, -152, -536, -170, -318, -183, +42, -88, 418, 34, 645, 98, 559, 157, +215, 196, -173, 162, -432, 139, -467, 123, +-293, 25, -47, -150, 123, -331, 155, -455, +150, -444, 151, -267, 110, 64, 93, 459, +107, 713, 36, 699, -64, 472, -117, 65, +-179, -395, -233, -696, -236, -784, -177, -653, +11, -252, 232, 258, 321, 625, 319, 755, +236, 603, -7, 221, -248, -158, -321, -436, +-246, -564, -91, -423, 64, -84, 148, 193, +117, 344, -44, 366, -182, 180, -175, -120, +-98, -334, -10, -388, 98, -246, 198, 48, +249, 332, 245, 443, 196, 362, 41, 137, +-280, -129, -582, -326, -627, -418, -456, -373, +-122, -168, 312, 109, 575, 331, 550, 409, +371, 324, 114, 83, -137, -206, -315, -405, +-393, -388, -299, -136, -95, 196, 40, 442, +57, 483, -48, 262, -217, -113, -291, -467, +-191, -641, 87, -540, 467, -175, 668, 272, +567, 626, 251, 751, -206, 560, -611, 153, +-766, -292, -721, -639, -499, -737, -108, -562, +312, -204, 623, 219, 717, 568, 557, 676, +262, 519, -105, 191, -456, -169, -596, -420, +-473, -530, -212, -468, 83, -212, 285, 81, +284, 330, 94, 515, -140, 494, -261, 210, +-230, -150, -62, -441, 184, -569, 300, -397, +265, -4, 239, 371, 147, 552, -57, 414, +-231, 56, -414, -274, -544, -428, -454, -378, +-188, -120, 194, 212, 557, 402, 628, 389, +462, 220, 223, -74, -112, -366, -389, -484, +-410, -407, -282, -215, -121, 100, 30, 428, +134, 558, 158, 499, 19, 330, -134, 4, +-48, -398, 110, -636, 183, -616, 266, -408, +255, -55, 57, 343, -141, 576, -226, 534, +-256, 308, -297, 3, -252, -278, 4, -368, +307, -261, 447, -108, 449, 72, 278, 259, +-42, 319, -294, 188, -383, -83, -328, -397, +-180, -581, -66, -537, 107, -239, 388, 266, +551, 754, 525, 990, 277, 863, -240, 358, +-666, -316, -700, -845, -415, -1086, 58, -984, +451, -561, 505, -30, 369, 472, 224, 857, +70, 953, -64, 778, -167, 477, -221, 50, +-183, -443, -113, -792, 10, -866, 154, -664, +136, -241, 21, 190, -22, 454, 17, 542, +97, 447, 71, 181, -38, -87, -7, -180, +80, -162, 98, -119, 134, 1, 101, 144, +-51, 226, -146, 206, -167, 30, -184, -240, +-179, -468, -151, -588, -30, -492, 210, -104, +460, 366, 630, 713, 515, 872, 24, 706, +-443, 253, -607, -252, -523, -625, -271, -763, +-57, -690, 55, -449, 215, -48, 366, 346, +454, 527, 451, 546, 215, 427, -150, 109, +-426, -233, -529, -416, -349, -362, -35, -26, +133, 377, 219, 558, 272, 409, 191, -42, +90, -612, -33, -982, -246, -910, -342, -379, +-224, 402, 27, 1048, 288, 1264, 339, 963, +249, 272, 164, -464, -39, -979, -266, -1103, +-363, -774, -418, -201, -346, 362, -74, 726, +252, 746, 499, 473, 488, 68, 179, -335, +-105, -568, -191, -531, -131, -285, -26, 128, +-92, 550, -288, 714, -330, 585, -203, 173, +33, -436, 301, -896, 375, -974, 243, -634, +56, 41, -88, 708, -83, 1024, -76, 919, +-206, 395, -263, -341, -171, -792, -7, -758, +235, -395, 333, 116, 131, 554, -148, 689, +-317, 396, -322, -185, -186, -708, 6, -906, +258, -658, 407, -17, 330, 701, 215, 1138, +23, 1136, -323, 641, -513, -177, -489, -922, +-369, -1290, -88, -1093, 181, -433, 288, 278, +390, 796, 439, 1009, 340, 764, 151, 201, +-183, -368, -498, -729, -496, -695, -308, -253, +-65, 319, 165, 722, 159, 726, -1, 280, +-74, -355, -14, -872, 160, -1048, 267, -706, +220, 16, 142, 731, 38, 1157, -83, 1169, +-199, 721, -356, -51, -434, -829, -321, -1299, +-44, -1256, 309, -643, 494, 269, 358, 1033, +89, 1347, -163, 1032, -293, 157, -133, -758, +99, -1256, 156, -1203, 175, -530, 123, 505, +-11, 1291, -107, 1493, -320, 1016, -526, -12, +-430, -1091, -165, -1751, 239, -1690, 674, -785, +769, 505, 568, 1517, 239, 1936, -200, 1550, +-488, 432, -552, -799, -588, -1616, -453, -1760, +-69, -1134, 253, -73, 421, 950, 490, 1544, +368, 1374, 93, 562, -165, -388, -225, -1102, +-81, -1317, 52, -880, 146, -47, 205, 757, +90, 1220, -140, 1149, -382, 588, -533, -230, +-426, -982, -116, -1348, 303, -1187, 684, -508, +709, 430, 438, 1184, 140, 1432, -182, 1074, +-386, 250, -351, -616, -308, -1116, -261, -1130, +-89, -680, 40, 27, 119, 618, 189, 892, +108, 734, 6, 222, 36, -328, 147, -693, +320, -740, 363, -389, 179, 183, -21, 670, +-239, 841, -481, 601, -525, 83, -393, -417, +-157, -752, 160, -792, 386, -484, 487, -4, +484, 462, 270, 679, -18, 508, -197, 159, +-292, -154, -250, -369, -77, -351, 67, -36, +148, 314, 138, 488, -22, 414, -245, 52, +-372, -427, -311, -802, -79, -959, 229, -769, +494, -187, 566, 619, 444, 1332, 289, 1654, +72, 1326, -277, 410, -549, -700, -677, -1612, +-701, -1991, -456, -1633, 19, -688, 471, 474, +723, 1476, 634, 1952, 391, 1695, 211, 881, +-16, -203, -210, -1212, -263, -1705, -348, -1478, +-421, -692, -315, 263, -138, 962, -6, 1195, +113, 932, 185, 300, 219, -366, 276, -746, +265, -787, 150, -471, 24, 107, -89, 575, +-136, 714, -119, 545, -119, 86, -183, -486, +-276, -830, -242, -724, -67, -238, 132, 352, +311, 764, 317, 852, 159, 553, 61, -36, +-4, -650, -97, -1017, -146, -944, -165, -392, +-137, 399, 4, 1086, 199, 1334, 270, 987, +91, 196, -272, -747, -539, -1506, -493, -1632, +-208, -986, 223, 66, 631, 1075, 664, 1667, +391, 1565, 118, 837, -129, -202, -307, -1147, +-377, -1553, -424, -1228, -411, -442, -290, 395, +-103, 957, 107, 1034, 325, 646, 455, 34, +433, -507, 365, -736, 244, -547, -23, -40, +-288, 470, -417, 711, -427, 572, -343, 145, +-219, -407, -110, -877, 4, -1007, 159, -641, +348, 67, 513, 747, 506, 1157, 225, 1203, +-123, 763, -322, -51, -411, -883, -394, -1378, +-229, -1337, -24, -767, 93, 98, 131, 924, +182, 1389, 209, 1243, 80, 581, -117, -221, +-177, -922, -66, -1218, 137, -892, 297, -189, +281, 441, 77, 806, -206, 805, -418, 372, +-422, -215, -247, -603, -30, -626, 172, -281, +310, 135, 326, 411, 265, 533, 213, 435, +129, 106, -93, -237, -372, -511, -496, -712, +-399, -609, -148, -195, 207, 270, 527, 782, +567, 1147, 284, 993, -123, 349, -466, -457, +-568, -1173, -364, -1479, -4, -1184, 292, -457, +402, 505, 401, 1370, 342, 1636, 145, 1243, +-120, 431, -310, -521, -414, -1237, -440, -1412, +-341, -1062, -85, -344, 227, 444, 406, 899, +384, 918, 275, 621, 212, 91, 149, -363, +35, -477, -107, -295, -316, -8, -495, 288, +-499, 431, -362, 210, -76, -277, 320, -668, +584, -740, 560, -495, 356, -12, 149, 550, +-51, 939, -239, 1024, -345, 718, -342, 101, +-238, -563, -95, -1073, 56, -1209, 175, -829, +126, -163, -1, 521, -10, 1033, 72, 1093, +180, 635, 291, 4, 330, -512, 172, -710, +-182, -556, -513, -278, -617, -2, -462, 228, +-123, 300, 275, 259, 601, 167, 689, 52, +462, -6, 40, -75, -358, -210, -596, -219, +-637, -141, -389, -83, 79, 42, 461, 160, +676, 237, 673, 375, 252, 348, -373, 74, +-751, -229, -762, -523, -458, -672, 111, -459, +668, -87, 846, 358, 563, 802, 19, 847, +-481, 417, -704, -170, -616, -686, -229, -886, +320, -666, 697, -114, 757, 614, 527, 1120, +-20, 999, -715, 328, -1134, -653, -1038, -1479, +-476, -1591, 405, -960, 1223, 203, 1530, 1562, +1206, 2350, 341, 2104, -756, 964, -1512, -727, +-1603, -2351, -1114, -3072, -232, -2529, 753, -904, +1413, 1195, 1458, 2855, 911, 3358, 90, 2474, +-607, 598, -1055, -1409, -1171, -2780, -735, -2960, +39, -1956, 646, -326, 920, 1290, 820, 2283, +315, 2258, -358, 1394, -853, 80, -897, -1265, +-400, -1969, 302, -1666, 754, -656, 861, 598, +602, 1487, -7, 1619, -500, 977, -586, -204, +-556, -1218, -465, -1535, -183, -1216, 65, -292, +202, 868, 456, 1422, 684, 1218, 577, 653, +276, -238, -62, -1032, -424, -1152, -594, -688, +-536, 90, -439, 749, -308, 842, -87, 459, +239, -182, 615, -823, 791, -1059, 679, -679, +414, 195, -36, 1257, -593, 1820, -887, 1454, +-878, 363, -710, -1097, -214, -2323, 479, -2604, +955, -1687, 1149, 190, 972, 2090, 280, 3046, +-589, 2744, -1182, 1328, -1306, -687, -904, -2403, +-142, -3119, 676, -2561, 1300, -935, 1391, 1003, +815, 2495, -28, 2977, -802, 2043, -1367, 258, +-1384, -1447, -756, -2522, 178, -2429, 1036, -1094, +1429, 717, 1148, 2109, 399, 2353, -453, 1353, +-1044, -186, -1086, -1647, -671, -2529, -93, -2058, +516, -423, 896, 1370, 779, 2623, 324, 2801, +-227, 1670, -721, -267, -873, -2214, -531, -3310, +101, -3000, 700, -1435, 1020, 759, 840, 2748, +159, 3622, -606, 3010, -1088, 1155, -1160, -1180, +-699, -2921, 155, -3382, 953, -2494, 1355, -589, +1184, 1450, 422, 2649, -553, 2596, -1236, 1509, +-1402, -76, -939, -1484, -31, -2073, 795, -1611, +1299, -552, 1286, 638, 616, 1624, -209, 1767, +-846, 894, -1321, -318, -1223, -1370, -404, -1915, +491, -1564, 1043, -481, 1247, 814, 892, 1909, +19, 2228, -774, 1540, -1062, 257, -825, -1077, +-244, -1990, 363, -2159, 768, -1484, 766, -179, +319, 1101, -221, 1819, -589, 1743, -751, 909, +-630, -205, -123, -983, 621, -1218, 1096, -843, +991, -58, 445, 585, -315, 838, -1013, 611, +-1305, -120, -976, -744, -185, -898, 593, -695, +1075, -126, 1160, 590, 748, 1036, 54, 1084, +-555, 651, -959, -103, -1001, -722, -496, -1083, +210, -1028, 660, -340, 854, 370, 661, 757, +24, 955, -536, 635, -764, -151, -762, -758, +-386, -985, 308, -838, 885, -230, 1038, 589, +750, 1232, 180, 1484, -525, 1068, -1159, 105, +-1348, -983, -895, -1802, -37, -1963, 799, -1308, +1294, -29, 1338, 1272, 905, 2002, 74, 2006, +-781, 1181, -1294, -136, -1394, -1192, -941, -1682, +-8, -1624, 831, -842, 1257, 296, 1264, 1098, +751, 1417, -87, 1088, -811, 193, -1134, -608, +-920, -1107, -398, -1137, 86, -561, 537, 151, +798, 731, 647, 1165, 327, 977, -33, 281, +-397, -207, -463, -553, -296, -846, -152, -674, +18, -272, 168, 25, 184, 173, 43, 96, +-210, -53, -286, -21, -39, 204, 240, 554, +432, 861, 616, 826, 525, 416, 37, -152, +-516, -838, -936, -1460, -1070, -1598, -688, -1045, +46, -143, 690, 759, 1053, 1560, 1155, 1847, +832, 1376, 26, 541, -739, -425, -1060, -1240, +-949, -1443, -442, -1117, 143, -590, 487, 110, +598, 657, 388, 754, -40, 590, -300, 193, +-278, -331, -29, -497, 334, -208, 512, 322, +393, 780, 127, 839, -322, 518, -819, -68, +-879, -890, -513, -1446, 4, -1345, 621, -840, +1017, -80, 881, 858, 349, 1447, -253, 1487, +-679, 1163, -834, 500, -565, -327, 41, -880, +524, -1042, 683, -927, 546, -641, 137, -365, +-439, -243, -980, -103, -1026, 188, -391, 509, +410, 889, 1059, 1322, 1518, 1370, 1327, 884, +333, 87, -800, -981, -1606, -2058, -1910, -2393, +-1412, -1819, -346, -701, 793, 769, 1734, 2114, +2046, 2666, 1596, 2291, 577, 1164, -793, -372, +-1771, -1711, -1914, -2318, -1546, -2126, -615, -1251, +765, 9, 1679, 1150, 1703, 1724, 1167, 1538, +289, 819, -689, 5, -1308, -667, -1317, -977, +-789, -795, -28, -281, 614, 162, 964, 377, +934, 366, 542, 113, 8, -189, -444, -299, +-735, -129, -828, 220, -545, 436, 25, 364, +328, 74, 381, -330, 601, -757, 625, -779, +258, -204, 37, 454, -70, 901, -363, 1166, +-587, 977, -644, 187, -627, -827, -424, -1550, +10, -1766, 590, -1304, 1059, -218, 1139, 1118, +880, 2119, 302, 2255, -568, 1541, -1273, 285, +-1423, -1173, -1076, -2213, -428, -2349, 315, -1638, +971, -480, 1329, 831, 1211, 1870, 740, 2194, +80, 1741, -745, 706, -1355, -524, -1348, -1472, +-893, -1787, -104, -1433, 830, -704, 1296, 218, +1134, 993, 643, 1220, -33, 933, -699, 459, +-1056, -56, -946, -500, -527, -596, -14, -394, +601, -202, 1018, -25, 866, 149, 432, 195, +9, 50, -477, -35, -833, 30, -812, 12, +-597, -67, -277, -50, 293, 4, 846, 65, +1008, 175, 791, 249, 343, 202, -228, 144, +-811, -23, -1077, -361, -875, -644, -531, -690, +-45, -471, 670, -26, 1220, 558, 1340, 1087, +913, 1231, 21, 883, -834, 154, -1392, -735, +-1523, -1451, -972, -1635, -59, -1226, 653, -376, +1153, 724, 1416, 1664, 1168, 1997, 572, 1618, +-133, 640, -899, -646, -1357, -1807, -1328, -2317, +-986, -1951, -341, -886, 396, 559, 922, 1883, +1224, 2464, 1238, 2154, 924, 1093, 373, -464, +-307, -1792, -972, -2235, -1391, -1964, -1337, -1158, +-912, 117, -332, 1205, 430, 1601, 1166, 1502, +1501, 1046, 1441, 366, 1046, -224, 188, -595, +-863, -783, -1548, -782, -1743, -700, -1442, -646, +-585, -562, 418, -347, 1187, 49, 1684, 652, +1709, 1307, 1127, 1715, 166, 1576, -822, 869, +-1490, -233, -1619, -1451, -1240, -2337, -562, -2506, +169, -1820, 714, -447, 985, 1040, 1112, 2170, +1104, 2712, 833, 2435, 374, 1300, -208, -193, +-880, -1484, -1334, -2269, -1406, -2345, -1281, -1740, +-898, -674, -66, 497, 1000, 1300, 1910, 1634, +2321, 1505, 1959, 971, 892, 375, -561, -63, +-1967, -456, -2703, -750, -2444, -792, -1420, -795, +23, -839, 1463, -640, 2420, -218, 2618, 293, +1854, 788, 286, 1123, -1272, 1165, -2193, 860, +-2286, 244, -1420, -518, -17, -1034, 1143, -1087, +1772, -826, 1744, -315, 903, 272, -299, 666, +-1134, 706, -1491, 421, -1434, 11, -751, -293, +346, -463, 1225, -502, 1563, -171, 1338, 356, +664, 623, -170, 766, -896, 743, -1333, 260, +-1283, -470, -788, -1028, -217, -1285, 317, -1163, +753, -627, 806, 148, 694, 978, 690, 1556, +513, 1551, 177, 1084, -128, 328, -569, -531, +-1037, -1240, -1158, -1585, -867, -1402, -256, -770, +495, 76, 1003, 860, 1121, 1310, 936, 1289, +366, 771, -387, -2, -851, -700, -963, -1069, +-728, -967, -87, -346, 674, 475, 1129, 971, +995, 1087, 328, 775, -563, -78, -1352, -977, +-1672, -1555, -1248, -1645, -180, -1006, 1046, 162, +1960, 1291, 2281, 2047, 1698, 2127, 323, 1425, +-1134, 317, -2172, -940, -2548, -2013, -2000, -2295, +-660, -1900, 860, -1049, 1985, 263, 2380, 1456, +1901, 2022, 726, 2056, -682, 1455, -1711, 255, +-1890, -826, -1346, -1351, -366, -1502, 817, -1234, +1508, -537, 1374, 200, 814, 635, -103, 854, +-1182, 871, -1670, 478, -1394, -81, -695, -390, +385, -529, 1553, -527, 2114, -221, 1869, 293, +1025, 661, -306, 682, -1730, 416, -2539, -11, +-2369, -579, -1410, -1048, -13, -1059, 1480, -674, +2501, -21, 2570, 839, 1733, 1366, 320, 1319, +-1194, 905, -2256, 91, -2488, -887, -1728, -1454, +-277, -1470, 1213, -919, 2240, 123, 2375, 1117, +1367, 1597, -306, 1453, -1781, 556, -2531, -743, +-2284, -1733, -965, -2011, 974, -1365, 2584, 63, +3044, 1572, 2264, 2501, 630, 2517, -1358, 1559, +-2861, -224, -3194, -2127, -2394, -3223, -743, -3193, +1245, -2122, 2649, -155, 2976, 2034, 2320, 3536, +839, 3888, -930, 2944, -2123, 875, -2346, -1466, +-1651, -3295, -358, -4101, 786, -3477, 1245, -1684, +1118, 588, 591, 2639, -167, 3683, -693, 3437, +-616, 2158, -137, 265, 413, -1591, 852, -2718, +891, -2957, 395, -2322, -411, -922, -1201, 619, +-1546, 1743, -1175, 2284, -273, 2092, 789, 1247, +1578, 97, 1714, -947, 1228, -1648, 349, -1782, +-716, -1296, -1511, -489, -1619, 386, -1181, 1160, +-447, 1538, 465, 1356, 1195, 728, 1364, -163, +993, -1007, 454, -1368, 7, -1307, -438, -844, +-778, 60, -781, 861, -651, 1270, -598, 1324, +-453, 815, -89, -32, 398, -683, 882, -1068, +1258, -1168, 1344, -719, 1034, -49, 320, 462, +-735, 788, -1766, 746, -2269, 475, -2038, 201, +-1059, -116, 511, -290, 2006, -250, 2713, -219, +2552, -288, 1570, -309, -107, -300, -1683, -239, +-2528, 19, -2631, 354, -1888, 655, -391, 843, +1239, 670, 2328, 164, 2442, -384, 1631, -835, +329, -1181, -1025, -1026, -1900, -367, -1879, 227, +-1120, 812, -56, 1406, 1010, 1348, 1637, 683, +1465, 5, 698, -714, -290, -1409, -1264, -1520, +-1795, -1081, -1421, -341, -314, 534, 809, 1187, +1581, 1498, 1845, 1390, 1310, 760, 223, -62, +-864, -783, -1678, -1354, -1841, -1558, -1253, -1226, +-364, -561, 573, 294, 1396, 1069, 1689, 1458, +1340, 1519, 658, 1129, -145, 244, -976, -575, +-1503, -1058, -1390, -1388, -820, -1420, -224, -886, +409, -182, 1060, 330, 1267, 884, 994, 1404, +631, 1454, 141, 1070, -541, 519, -1110, -179, +-1263, -985, -974, -1628, -467, -1812, 158, -1349, +854, -522, 1220, 322, 1089, 1262, 751, 1986, +242, 1896, -515, 1239, -1176, 408, -1312, -582, +-922, -1474, -335, -1890, 343, -1735, 1072, -1094, +1337, -220, 881, 643, 229, 1395, -362, 1782, +-931, 1526, -1126, 845, -815, 48, -238, -713, +488, -1254, 1000, -1374, 962, -1017, 571, -455, +13, -10, -601, 353, -892, 650, -745, 756, +-386, 667, 64, 604, 530, 567, 762, 259, +608, -306, 293, -733, -23, -937, -460, -1043, +-746, -838, -565, -252, -232, 409, 73, 974, +451, 1177, 627, 1018, 469, 781, 234, 243, +-17, -669, -320, -1230, -540, -1208, -574, -1048, +-416, -607, -168, 254, 82, 958, 424, 1198, +815, 1045, 930, 713, 657, 307, 119, -225, +-558, -683, -1171, -880, -1418, -943, -1091, -989, +-332, -792, 534, -183, 1312, 573, 1684, 1279, +1450, 1755, 776, 1766, -229, 1142, -1273, -2, +-1865, -1268, -1864, -2320, -1195, -2661, 67, -2036, +1297, -758, 1946, 876, 1867, 2338, 1091, 3053, +-15, 2803, -995, 1649, -1632, -107, -1656, -1865, +-987, -2991, -73, -3145, 799, -2244, 1449, -676, +1458, 1023, 843, 2441, -41, 2829, -928, 2131, +-1371, 1064, -1082, -166, -318, -1332, 425, -1723, +839, -1407, 912, -1024, 639, -515, 65, 120, +-487, 378, -763, 350, -678, 443, -283, 682, +235, 817, 694, 812, 827, 746, 415, 417, +-244, -284, -729, -1112, -940, -1665, -701, -1657, +42, -1096, 785, -174, 1147, 830, 1092, 1683, +537, 1962, -326, 1448, -1158, 528, -1681, -345, +-1367, -979, -319, -1338, 739, -1262, 1616, -756, +2036, -279, 1418, 50, 139, 348, -1014, 485, +-1873, 514, -2182, 646, -1530, 731, -267, 696, +994, 661, 2061, 315, 2523, -451, 1865, -1121, +467, -1603, -950, -1837, -2111, -1374, -2626, -245, +-2080, 1057, -846, 2106, 504, 2533, 1745, 2183, +2489, 1100, 2340, -437, 1411, -1802, 104, -2521, +-1124, -2584, -2001, -1906, -2364, -509, -1887, 972, +-741, 1986, 385, 2438, 1317, 2194, 1986, 1268, +1960, 9, 1252, -1086, 263, -1702, -707, -1821, +-1377, -1489, -1602, -771, -1312, 70, -563, 679, +224, 992, 748, 1180, 1063, 1111, 989, 646, +420, 111, -157, -199, -433, -467, -563, -710, +-445, -683, 21, -509, 444, -357, 491, -216, +257, -143, -105, 4, -538, 344, -846, 641, +-749, 742, -286, 817, 344, 747, 929, 345, +1184, -210, 984, -799, 413, -1261, -328, -1367, +-923, -1075, -1205, -459, -1116, 327, -642, 1133, +8, 1626, 582, 1557, 951, 997, 1011, 195, +805, -549, 473, -1147, 85, -1439, -334, -1236, +-680, -677, -919, -59, -1092, 384, -1091, 701, +-718, 846, 103, 733, 1145, 526, 1933, 351, +2156, 223, 1700, -17, 534, -359, -1045, -576, +-2434, -750, -3061, -848, -2668, -646, -1398, -195, +452, 204, 2367, 505, 3607, 731, 3597, 741, +2284, 627, 190, 442, -1957, 199, -3518, 38, +-3822, -193, -2662, -550, -693, -823, 1239, -960, +2630, -1032, 3105, -856, 2450, -260, 978, 566, +-562, 1315, -1576, 1785, -1890, 1897, -1532, 1455, +-635, 373, 299, -869, 724, -1906, 633, -2507, +263, -2359, -187, -1489, -395, -223, -286, 1136, +-28, 2190, 370, 2510, 813, 2138, 998, 1374, +825, 331, 342, -786, -385, -1676, -1103, -2053, +-1480, -2004, -1494, -1749, -1175, -1118, -405, -167, +568, 847, 1296, 1890, 1829, 2636, 2156, 2685, +1817, 2095, 794, 958, -438, -709, -1724, -2341, +-2845, -3311, -3132, -3438, -2310, -2604, -801, -1013, +1010, 801, 2804, 2497, 3893, 3648, 3624, 3787, +2108, 2796, -29, 1005, -2254, -987, -3901, -2693, +-4185, -3722, -3027, -3638, -961, -2436, 1402, -630, +3284, 1182, 3974, 2549, 3341, 3099, 1700, 2747, +-405, 1751, -2271, 460, -3259, -811, -3133, -1777, +-2071, -2178, -433, -1957, 1246, -1381, 2315, -609, +2497, 249, 1970, 1013, 972, 1549, -259, 1664, +-1245, 1302, -1613, 672, -1474, -94, -1123, -887, +-613, -1448, 43, -1560, 579, -1129, 831, -223, +1087, 718, 1342, 1390, 1125, 1679, 488, 1288, +-173, 264, -906, -875, -1672, -1766, -1999, -2189, +-1603, -1822, -687, -602, 474, 987, 1692, 2375, +2607, 3117, 2688, 2916, 1772, 1581, 235, -581, +-1444, -2622, -2892, -3853, -3510, -3966, -2835, -2803, +-1204, -665, 699, 1712, 2503, 3511, 3767, 4338, +3831, 3947, 2539, 2325, 522, 122, -1565, -1937, +-3326, -3470, -4198, -4118, -3705, -3523, -2093, -2021, +-25, -293, 2044, 1425, 3687, 2706, 4252, 3240, +3533, 3142, 1949, 2396, -124, 1137, -2292, -242, +-3783, -1549, -4124, -2718, -3478, -3398, -2013, -3255, +151, -2372, 2304, -866, 3625, 1047, 4021, 2924, +3573, 4135, 2057, 4168, -183, 3017, -2178, 967, +-3433, -1488, -3936, -3597, -3455, -4612, -1906, -4154, +144, -2472, 1959, -126, 3169, 2240, 3594, 3923, +3064, 4275, 1656, 3199, -99, 1225, -1587, -991, +-2545, -2805, -2944, -3669, -2652, -3310, -1661, -1860, +-364, 135, 864, 1996, 1949, 3076, 2651, 3133, +2648, 2225, 2025, 498, 956, -1414, -475, -2658, +-1845, -2954, -2756, -2438, -3077, -1167, -2539, 508, +-1129, 1866, 589, 2615, 2181, 2688, 3335, 2003, +3541, 803, 2593, -504, 853, -1623, -1157, -2386, +-2914, -2610, -3865, -2150, -3573, -1226, -2112, -77, +-127, 1184, 1776, 2215, 3263, 2670, 3802, 2540, +3081, 1881, 1558, 753, -246, -556, -2063, -1734, +-3273, -2589, -3321, -2857, -2408, -2491, -1047, -1608, +477, -372, 1789, 928, 2437, 2160, 2354, 3038, +1825, 3110, 1065, 2512, 152, 1494, -804, 13, +-1487, -1645, -1745, -2909, -1811, -3540, -1654, -3394, +-996, -2377, -105, -809, 742, 936, 1664, 2545, +2337, 3593, 2245, 3802, 1576, 3040, 559, 1521, +-769, -271, -1946, -1994, -2514, -3307, -2414, -3762, +-1624, -3232, -343, -1980, 1034, -338, 2107, 1343, +2401, 2707, 1869, 3425, 963, 3181, -154, 2116, +-1226, 635, -1666, -937, -1457, -2252, -1014, -2918, +-377, -2685, 341, -1729, 748, -440, 804, 880, +693, 1939, 438, 2332, 188, 1826, 142, 838, +128, -229, -102, -1220, -464, -1759, -833, -1523, +-1098, -676, -976, 241, -348, 1016, 513, 1612, +1345, 1610, 1905, 893, 1865, -181, 1076, -1188, +-262, -1869, -1678, -1987, -2606, -1418, -2755, -422, +-1999, 746, -383, 1740, 1475, 2098, 2789, 1821, +3197, 1197, 2627, 402, 1298, -508, -371, -1181, +-1913, -1399, -2745, -1457, -2654, -1451, -2044, -1210, +-1093, -780, 165, -261, 1229, 447, 1762, 1383, +1965, 2268, 1901, 2788, 1544, 2655, 1007, 1721, +276, 133, -651, -1758, -1614, -3458, -2461, -4393, +-2889, -4124, -2594, -2621, -1534, -246, 143, 2370, +2054, 4417, 3576, 5305, 4189, 4748, 3613, 2748, +1847, -127, -633, -2845, -2890, -4639, -4227, -5153, +-4473, -4151, -3446, -1973, -1196, 478, 1375, 2495, +3223, 3623, 3940, 3655, 3526, 2785, 2106, 1451, +158, 37, -1524, -1166, -2351, -1887, -2305, -2052, +-1698, -1831, -824, -1406, -2, -853, 430, -247, +508, 226, 471, 630, 405, 1165, 434, 1647, +724, 1799, 1173, 1585, 1352, 1044, 891, 173, +5, -981, -1009, -2016, -2123, -2468, -2829, -2276, +-2434, -1620, -1117, -551, 564, 820, 2293, 1974, +3541, 2546, 3573, 2621, 2283, 2124, 260, 999, +-1831, -481, -3391, -1891, -3785, -2854, -2866, -3080, +-1153, -2425, 783, -1059, 2453, 639, 3185, 2125, +2764, 2922, 1658, 2909, 231, 2038, -1189, 615, +-1959, -772, -1824, -1821, -1201, -2320, -579, -2055, +-95, -1266, 225, -429, 241, 323, 103, 839, +235, 933, 643, 912, 1063, 953, 1358, 929, +1350, 864, 854, 740, -94, 320, -1265, -429, +-2270, -1243, -2708, -1899, -2311, -2150, -1070, -1815, +601, -963, 2066, 298, 2945, 1679, 3019, 2700, +2184, 2925, 714, 2347, -851, 1171, -2024, -446, +-2509, -1949, -2375, -2770, -1762, -2848, -719, -2269, +415, -1073, 1224, 385, 1599, 1434, 1589, 1932, +1341, 2037, 933, 1759, 399, 1193, -117, 490, +-545, -115, -901, -576, -1116, -1078, -1215, -1574, +-1128, -1862, -719, -1799, -159, -1389, 351, -549, +868, 679, 1251, 1890, 1241, 2666, 925, 2727, +511, 2051, 56, 771, -301, -791, -450, -2008, +-497, -2566, -588, -2473, -738, -1730, -899, -573, +-1020, 487, -934, 1201, -463, 1535, 286, 1364, +1200, 902, 2091, 592, 2529, 467, 2317, 404, +1423, 348, -200, 85, -2040, -554, -3397, -1383, +-3929, -2088, -3329, -2334, -1563, -1836, 762, -646, +2924, 912, 4310, 2466, 4406, 3504, 3177, 3488, +1034, 2312, -1430, 394, -3393, -1686, -4199, -3275, +-3723, -3888, -2182, -3344, -105, -1693, 1763, 439, +2835, 2089, 2836, 2905, 2023, 2943, 920, 2083, +-163, 604, -987, -705, -1265, -1478, -1022, -1681, +-600, -1233, -370, -450, -368, 160, -414, 371, +-419, 116, -321, -360, 32, -669, 643, -660, +1250, -174, 1529, 832, 1366, 1848, 800, 2214, +-94, 1774, -1090, 665, -1804, -893, -2004, -2327, +-1624, -3068, -728, -2806, 367, -1552, 1274, 187, +1833, 1819, 1877, 2888, 1371, 3052, 603, 2228, +-256, 754, -1141, -812, -1721, -2047, -1749, -2496, +-1256, -2061, -397, -1135, 556, -45, 1273, 909, +1511, 1410, 1244, 1340, 635, 847, -137, 227, +-858, -277, -1264, -470, -1138, -335, -518, 4, +296, 243, 1008, 194, 1382, -39, 1108, -409, +238, -729, -760, -721, -1539, -441, -1885, -27, +-1444, 460, -283, 811, 1010, 844, 1985, 729, +2423, 481, 2087, -6, 950, -502, -636, -771, +-2000, -769, -2625, -551, -2495, -179, -1672, 205, +-255, 392, 1149, 380, 1996, 222, 2283, 11, +2039, -166, 1202, -235, 76, -128, -842, 83, +-1352, 326, -1522, 498, -1384, 565, -995, 481, +-481, 92, 38, -428, 468, -886, 804, -1208, +1095, -1201, 1184, -741, 895, 11, 377, 736, +-119, 1340, -516, 1707, -735, 1530, -714, 842, +-525, 7, -273, -699, -98, -1287, -86, -1640, +-169, -1527, -290, -1048, -253, -411, 113, 247, +584, 787, 983, 1134, 1331, 1315, 1310, 1323, +675, 1055, -263, 598, -1087, 127, -1686, -468, +-1979, -1203, -1723, -1645, -810, -1601, 369, -1317, +1281, -808, 1812, -35, 1975, 736, 1516, 1331, +534, 1703, -312, 1706, -754, 1339, -1101, 803, +-1281, 159, -962, -576, -474, -1274, -315, -1763, +-179, -1924, 196, -1810, 445, -1393, 534, -508, +789, 724, 1024, 1890, 898, 2647, 471, 2839, +-9, 2331, -495, 1096, -982, -538, -1222, -2018, +-1005, -2947, -500, -3089, 58, -2381, 532, -1070, +742, 421, 615, 1671, 294, 2360, -68, 2395, +-254, 1861, -67, 943, 311, -60, 534, -829, +531, -1294, 344, -1412, -29, -1169, -586, -787, +-1091, -408, -1227, -61, -976, 262, -468, 510, +267, 584, 977, 627, 1339, 641, 1303, 470, +926, 232, 294, 131, -344, 54, -755, -121, +-850, -242, -656, -403, -347, -666, -121, -766, +-3, -697, -34, -496, -261, -103, -458, 400, +-300, 852, 159, 1096, 672, 1059, 1133, 717, +1435, 192, 1282, -374, 608, -808, -304, -935, +-1163, -814, -1784, -488, -1953, -22, -1568, 353, +-747, 449, 191, 313, 992, 74, 1529, -258, +1674, -448, 1422, -199, 1022, 352, 562, 834, +-42, 1059, -626, 991, -1013, 505, -1320, -338, +-1543, -1211, -1500, -1736, -1137, -1712, -530, -1254, +275, -424, 1194, 655, 2029, 1588, 2439, 2029, +2220, 1899, 1404, 1317, 156, 351, -1227, -714, +-2293, -1445, -2736, -1720, -2509, -1591, -1686, -1103, +-416, -372, 951, 299, 1951, 749, 2341, 1010, +2189, 1005, 1567, 874, 581, 728, -403, 433, +-1079, 52, -1483, -262, -1606, -548, -1346, -840, +-829, -1005, -299, -980, 265, -775, 822, -337, +1102, 218, 1051, 745, 887, 1217, 586, 1482, +90, 1309, -387, 690, -690, -113, -831, -876, +-676, -1489, -265, -1746, 66, -1430, 241, -627, +388, 346, 371, 1192, 99, 1696, -178, 1679, +-274, 1052, -318, 72, -305, -826, -44, -1396, +384, -1521, 617, -1132, 598, -343, 484, 462, +260, 958, -110, 1104, -412, 943, -565, 525, +-688, 38, -764, -278, -654, -450, -388, -605, +-4, -682, 504, -714, 946, -711, 1147, -449, +1164, 114, 925, 723, 334, 1235, -370, 1547, +-941, 1421, -1379, 795, -1529, -180, -1186, -1293, +-492, -2170, 209, -2380, 772, -1785, 1146, -588, +1232, 901, 945, 2159, 510, 2687, 231, 2344, +8, 1248, -325, -216, -567, -1473, -664, -2121, +-835, -2113, -1001, -1490, -860, -432, -453, 554, +26, 1172, 591, 1336, 1182, 1028, 1502, 493, +1403, -4, 897, -271, 117, -256, -692, -93, +-1299, 19, -1508, -54, -1199, -300, -583, -640, +47, -803, 568, -649, 844, -241, 717, 444, +410, 1129, 166, 1355, -49, 1041, -152, 406, +7, -380, 257, -1129, 326, -1430, 135, -1154, +-156, -493, -463, 348, -774, 1057, -805, 1304, +-408, 1040, 35, 469, 301, -261, 514, -914, +613, -1162, 437, -944, 221, -417, 166, 138, +119, 573, 37, 858, 60, 852, 59, 515, +-161, 113, -504, -152, -730, -370, -843, -480, +-838, -404, -491, -330, 207, -308, 892, -282, +1297, -188, 1422, 10, 1253, 283, 619, 600, +-295, 832, -989, 817, -1362, 540, -1511, 157, +-1224, -318, -536, -896, 100, -1218, 505, -1119, +905, -764, 1206, -198, 1089, 522, 727, 1112, +470, 1315, 90, 1145, -558, 673, -959, -11, +-910, -642, -884, -1028, -828, -1094, -378, -825, +210, -305, 611, 248, 894, 609, 985, 688, +742, 529, 286, 205, -145, -140, -451, -309, +-593, -241, -520, -68, -284, 103, -104, 243, +-41, 253, 9, 35, 72, -226, 80, -356, +114, -358, 246, -258, 326, -31, 238, 272, +113, 427, -42, 327, -274, 125, -410, -59, +-336, -233, -231, -343, -73, -216, 252, 48, +538, 238, 579, 383, 470, 448, 180, 257, +-324, -138, -830, -465, -1035, -634, -806, -695, +-296, -539, 247, -108, 803, 428, 1195, 798, +1170, 925, 836, 842, 368, 518, -312, -27, +-1087, -573, -1542, -865, -1452, -869, -998, -705, +-318, -417, 520, -35, 1228, 330, 1511, 519, +1411, 572, 1024, 553, 350, 448, -463, 267, +-1111, 36, -1447, -139, -1344, -220, -813, -294, +-116, -364, 506, -399, 911, -392, 984, -403, +751, -322, 322, -77, -103, 246, -389, 593, +-463, 841, -284, 887, 30, 674, 267, 199, +320, -327, 118, -716, -245, -891, -575, -852, +-717, -579, -619, -182, -249, 145, 317, 380, +871, 470, 1185, 374, 1094, 259, 561, 266, +-144, 340, -774, 372, -1167, 397, -1142, 287, +-721, -135, -185, -741, 260, -1176, 626, -1257, +884, -1002, 789, -401, 411, 479, 79, 1295, +-184, 1649, -466, 1447, -572, 905, -376, 116, +-52, -768, 76, -1356, 34, -1356, 62, -904, +147, -314, 103, 251, 56, 626, 119, 651, +82, 371, -85, -30, -140, -288, -100, -251, +-43, 80, 32, 498, 70, 776, 94, 817, +138, 489, 124, -227, 26, -986, -116, -1407, +-238, -1400, -320, -1003, -270, -218, -49, 644, +205, 1245, 327, 1518, 342, 1376, 282, 803, +136, 133, -91, -388, -233, -800, -252, -1017, +-267, -913, -250, -745, -80, -669, 93, -453, +102, -43, 120, 358, 268, 792, 314, 1229, +219, 1392, 110, 1159, -70, 603, -316, -196, +-479, -983, -500, -1465, -297, -1595, 20, -1337, +243, -621, 441, 197, 699, 777, 703, 1104, +341, 1189, -121, 984, -504, 584, -821, 176, +-897, -141, -596, -354, -90, -499, 346, -604, +622, -653, 739, -751, 652, -806, 357, -601, +41, -146, -154, 422, -285, 1058, -392, 1582, +-374, 1641, -283, 1141, -258, 321, -281, -634, +-202, -1519, -48, -2019, 122, -1891, 314, -1216, +586, -205, 829, 895, 811, 1759, 466, 2065, +9, 1685, -517, 825, -1051, -189, -1233, -1107, +-948, -1619, -517, -1551, -65, -999, 486, -234, +953, 531, 1109, 1018, 1011, 1048, 711, 745, +207, 252, -392, -266, -830, -585, -898, -590, +-648, -315, -347, 22, -72, 321, 90, 470, +87, 336, 11, -19, 36, -358, 146, -551, +248, -563, 371, -265, 578, 223, 735, 551, +681, 713, 318, 697, -279, 381, -893, -160, +-1394, -647, -1564, -904, -1159, -915, -341, -640, +512, -53, 1200, 678, 1645, 1209, 1628, 1276, +1151, 914, 471, 214, -278, -649, -1022, -1365, +-1413, -1594, -1307, -1275, -894, -541, -449, 430, +-19, 1296, 322, 1686, 444, 1529, 450, 928, +562, 27, 737, -898, 813, -1472, 775, -1580, +619, -1217, 190, -505, -494, 288, -1141, 934, +-1561, 1280, -1650, 1225, -1294, 806, -507, 215, +550, -311, 1451, -699, 1892, -877, 1850, -806, +1378, -500, 495, -80, -503, 298, -1223, 505, +-1548, 495, -1586, 339, -1221, 81, -516, -200, +209, -299, 753, -194, 1067, 9, 1152, 204, +948, 317, 458, 293, -73, 142, -404, -113, +-557, -363, -595, -496, -440, -522, -151, -401, +29, -76, 59, 297, 75, 550, -12, 672, +-110, 673, -64, 415, 49, -38, 117, -442, +273, -669, 405, -737, 307, -570, 108, -122, +-6, 333, -154, 547, -320, 585, -329, 440, +-222, 92, -126, -330, -75, -552, -15, -502, +26, -278, 2, 80, -25, 470, 40, 695, +225, 661, 403, 383, 473, -98, 403, -611, +188, -863, -164, -874, -471, -672, -666, -201, +-696, 360, -511, 745, -123, 918, 254, 887, +493, 592, 638, 136, 590, -223, 228, -452, +-146, -634, -212, -746, -162, -633, -148, -405, +-36, -205, 113, 36, 36, 330, -194, 559, +-298, 656, -315, 630, -289, 527, -93, 367, +250, 163, 489, -164, 545, -502, 391, -720, +98, -807, -227, -795, -422, -644, -410, -307, +-196, 128, 116, 590, 381, 992, 442, 1169, +231, 1130, -162, 816, -525, 236, -714, -438, +-746, -1013, -487, -1387, 98, -1418, 723, -1044, +1138, -439, 1256, 268, 1042, 936, 477, 1258, +-274, 1213, -1013, 903, -1500, 393, -1562, -172, +-1187, -520, -579, -590, 204, -534, 952, -421, +1372, -255, 1446, -168, 1340, -274, 959, -414, +235, -318, -499, -38, -1026, 337, -1410, 769, +-1505, 1133, -1139, 1157, -509, 748, 123, 118, +620, -512, 951, -1054, 1068, -1375, 936, -1306, +702, -851, 421, -229, 137, 421, -177, 911, +-461, 1143, -650, 1087, -741, 760, -786, 308, +-768, -87, -694, -364, -403, -562, 134, -697, +687, -693, 1099, -583, 1352, -427, 1374, -216, +939, 132, 200, 495, -458, 704, -1010, 785, +-1443, 717, -1512, 409, -1173, -22, -615, -383, +-5, -586, 567, -619, 1077, -459, 1283, -242, +1134, -66, 802, 50, 473, 132, 74, 176, +-331, 199, -605, 253, -794, 337, -972, 344, +-985, 219, -764, 31, -414, -151, -20, -380, +405, -523, 815, -461, 1025, -257, 1037, -1, +944, 279, 725, 488, 340, 506, -188, 334, +-692, 35, -1118, -274, -1462, -424, -1555, -448, +-1214, -307, -559, 33, 321, 379, 1258, 475, +2003, 363, 2201, 197, 1766, -43, 851, -301, +-321, -394, -1432, -340, -2103, -214, -2123, -65, +-1606, 103, -744, 194, 326, 219, 1256, 213, +1607, 160, 1463, 75, 1045, 25, 406, 52, +-216, 90, -604, 26, -747, -93, -711, -194, +-490, -281, -245, -416, -82, -439, -26, -263, +30, -4, 80, 279, 157, 599, 294, 868, +441, 895, 447, 592, 240, 53, -78, -591, +-329, -1100, -423, -1331, -383, -1156, -169, -559, +142, 282, 393, 1032, 464, 1380, 269, 1281, +-112, 822, -479, 98, -717, -633, -748, -1065, +-341, -1024, 325, -685, 797, -206, 935, 280, +907, 594, 587, 611, -5, 344, -591, -37, +-912, -337, -934, -429, -704, -276, -282, 7, +189, 342, 458, 593, 409, 617, 277, 335, +255, -100, 268, -485, 273, -747, 353, -801, +366, -610, 111, -256, -267, 171, -572, 556, +-796, 793, -977, 807, -828, 687, -315, 427, +332, 0, 882, -466, 1254, -767, 1311, -854, +932, -780, 175, -492, -545, -33, -1037, 364, +-1318, 636, -1170, 730, -600, 614, 66, 337, +575, 48, 891, -208, 954, -393, 692, -396, +242, -249, -150, -71, -391, 72, -511, 108, +-481, 31, -320, -140, -100, -287, 37, -346, +186, -205, 283, 129, 241, 443, 131, 648, +85, 767, 9, 637, -120, 189, -157, -319, +-128, -667, -191, -914, -215, -984, -50, -766, +126, -286, 261, 229, 385, 622, 391, 906, +197, 1030, -60, 890, -263, 543, -427, 92, +-474, -377, -430, -799, -283, -1099, -16, -1211, +302, -904, 530, -274, 651, 374, 570, 947, +375, 1306, 94, 1192, -259, 640, -569, -40, +-701, -614, -660, -964, -532, -912, -236, -532, +204, -45, 496, 382, 620, 638, 780, 540, +751, 142, 366, -223, -90, -455, -434, -539, +-739, -306, -889, 101, -632, 448, -215, 651, +110, 625, 367, 301, 572, -83, 551, -380, +402, -583, 231, -577, -1, -356, -273, -103, +-351, 75, -242, 166, -149, 211, -85, 180, +-16, 181, -8, 260, -94, 324, -102, 291, +46, 210, 231, 63, 312, -217, 252, -513, +133, -673, -34, -642, -231, -429, -338, -173, +-238, 199, -62, 641, 126, 874, 278, 768, +393, 509, 288, 221, -84, -175, -478, -608, +-663, -836, -638, -755, -332, -465, 290, -138, +911, 213, 1128, 489, 892, 601, 397, 473, +-291, 175, -968, -38, -1277, -128, -1113, -217, +-650, -197, -27, -8, 676, 141, 1132, 111, +1131, 25, 771, -139, 302, -336, -225, -427, +-611, -324, -686, -52, -533, 255, -345, 493, +-152, 604, -48, 517, -51, 255, -34, -88, +92, -371, 302, -570, 493, -599, 651, -417, +668, -106, 392, 179, -95, 350, -570, 394, +-891, 269, -973, 76, -735, -11, -243, -27, +286, 51, 631, 160, 813, 150, 744, -20, +417, -242, -4, -473, -275, -606, -395, -486, +-341, -146, -102, 293, 100, 723, 55, 943, +-120, 847, -273, 416, -379, -180, -351, -746, +-147, -1115, 201, -1107, 544, -658, 713, 24, +649, 643, 415, 1040, 61, 1101, -334, 732, +-567, 97, -632, -472, -544, -701, -344, -708, +-148, -567, -17, -201, 145, 177, 275, 275, +372, 201, 439, 165, 482, 138, 458, 102, +320, 162, 101, 266, -221, 315, -593, 187, +-850, -100, -890, -460, -655, -746, -207, -774, +221, -503, 564, -27, 830, 515, 896, 920, +724, 1032, 403, 755, 52, 202, -360, -380, +-696, -778, -809, -981, -665, -873, -416, -383, +-163, 177, 77, 538, 308, 740, 407, 754, +411, 474, 409, -9, 325, -366, 171, -493, +63, -473, -2, -326, -110, -27, -190, 212, +-242, 238, -370, 169, -475, 68, -434, -27, +-266, -13, -46, 42, 227, 120, 488, 161, +643, 57, 641, -176, 545, -338, 256, -428, +-165, -422, -522, -133, -648, 301, -542, 599, +-363, 763, -200, 748, -10, 422, 135, -170, +178, -719, 177, -1072, 165, -1159, 181, -897, +215, -312, 277, 462, 384, 1185, 441, 1575, +283, 1493, -134, 959, -581, 86, -924, -923, +-1055, -1645, -833, -1853, -283, -1528, 295, -736, +785, 274, 1096, 1166, 1144, 1703, 912, 1745, +447, 1285, -202, 493, -763, -388, -988, -1151, +-951, -1506, -736, -1413, -363, -964, 45, -255, +297, 481, 399, 958, 487, 1047, 529, 837, +443, 466, 327, 13, 278, -367, 152, -499, +-106, -347, -356, -182, -465, -78, -587, 27, +-650, 39, -470, -81, -163, -195, 66, -197, +321, -82, 610, 102, 731, 287, 601, 372, +390, 361, 208, 220, -18, 20, -283, -143, +-482, -236, -570, -249, -630, -199, -640, -123, +-453, -66, -100, -46, 288, -26, 648, -25, +893, -29, 859, -12, 643, 95, 316, 242, +-139, 348, -597, 379, -832, 319, -853, 141, +-645, -166, -280, -467, 87, -597, 366, -594, +514, -441, 508, -123, 385, 222, 240, 413, +109, 505, -29, 507, -118, 336, -100, 144, +-69, 66, -118, 3, -232, -87, -335, -182, +-354, -301, -306, -477, -112, -598, 157, -600, +363, -425, 477, -34, 533, 481, 423, 930, +182, 1176, -55, 1119, -254, 687, -449, -33, +-485, -784, -328, -1347, -178, -1484, -98, -1143, +-12, -469, 79, 325, 155, 1002, 248, 1285, +367, 1080, 415, 582, 318, 22, 132, -430, +-8, -593, -154, -460, -358, -193, -503, -20, +-512, -9, -447, -158, -209, -374, 138, -459, +434, -316, 594, 26, 602, 503, 442, 942, +183, 1102, -80, 840, -354, 264, -574, -480, +-544, -1143, -333, -1441, -127, -1199, 155, -516, +430, 301, 445, 994, 243, 1339, 45, 1175, +-80, 614, -232, -91, -334, -668, -255, -965, +-33, -927, 160, -592, 304, -61, 407, 382, +365, 552, 88, 568, -183, 454, -340, 160, +-458, -101, -474, -191, -342, -210, -179, -251, +39, -251, 380, -226, 667, -186, 723, -103, +570, 67, 241, 299, -146, 452, -443, 461, +-618, 361, -671, 148, -588, -130, -408, -421, +-131, -565, 196, -534, 521, -416, 709, -218, +692, 106, 514, 435, 274, 612, 3, 631, +-283, 477, -507, 156, -577, -162, -576, -387, +-496, -473, -260, -441, -9, -323, 177, -166, +398, -44, 591, 31, 612, 141, 488, 293, +315, 386, 75, 371, -191, 297, -398, 157, +-527, -21, -603, -207, -591, -313, -483, -333, +-202, -338, 209, -329, 591, -273, 828, -147, +884, 51, 674, 291, 256, 563, -241, 763, +-701, 731, -960, 405, -917, -54, -585, -551, +-4, -969, 605, -1070, 923, -783, 853, -257, +494, 321, -95, 811, -715, 1076, -989, 923, +-755, 431, -222, -118, 441, -537, 1025, -762, +1235, -655, 905, -284, 165, 74, -693, 293, +-1355, 312, -1605, 105, -1254, -140, -375, -256, +650, -164, 1432, 111, 1741, 442, 1436, 630, +636, 571, -286, 231, -1042, -298, -1421, -790, +-1241, -1047, -681, -947, -73, -452, 424, 260, +704, 903, 679, 1224, 482, 1161, 241, 678, +16, -101, -87, -791, -29, -1097, 14, -1052, +-12, -691, -122, -77, -321, 452, -469, 677, +-450, 692, -275, 497, 57, 175, 406, -73, +577, -164, 507, -194, 296, -177, 43, -90, +-196, -44, -307, -135, -257, -266, -151, -298, +-21, -220, 20, -78, -49, 196, -82, 508, +-84, 677, -129, 628, -55, 368, 195, -65, +421, -520, 471, -792, 384, -813, 115, -604, +-311, -178, -669, 294, -769, 636, -572, 763, +-117, 655, 436, 329, 841, -46, 875, -354, +563, -546, 97, -520, -394, -282, -793, 22, +-897, 268, -651, 331, -184, 210, 319, 1, +698, -206, 812, -344, 658, -261, 287, 8, +-136, 258, -413, 423, -505, 487, -482, 386, +-352, 108, -188, -274, -38, -563, 88, -666, +196, -581, 298, -328, 380, 62, 416, 443, +370, 661, 218, 659, -27, 445, -342, 136, +-597, -149, -681, -389, -584, -484, -274, -384, +194, -191, 550, -46, 661, 57, 579, 129, +344, 119, 13, 62, -239, 65, -352, 123, +-353, 160, -255, 173, -96, 164, 10, 64, +35, -77, 9, -209, -36, -292, -45, -281, +56, -177, 219, -48, 324, 66, 295, 140, +155, 139, -76, 80, -346, 40, -467, 45, +-312, 124, -40, 211, 210, 250, 384, 203, +383, 36, 152, -228, -206, -518, -505, -715, +-587, -669, -395, -337, 69, 172, 587, 673, +884, 1010, 856, 1002, 503, 645, -107, 51, +-746, -596, -1151, -1015, -1159, -1052, -768, -771, +-68, -240, 687, 411, 1159, 878, 1197, 959, +868, 700, 273, 169, -393, -420, -844, -779, +-922, -788, -739, -483, -392, 41, 51, 566, +409, 848, 528, 770, 446, 366, 269, -217, +58, -752, -128, -1031, -174, -895, -78, -419, +32, 213, 47, 799, 8, 1091, -43, 956, +-139, 513, -202, -67, -137, -617, -47, -898, +10, -807, 76, -486, 130, -49, 148, 358, +153, 567, 140, 515, 109, 263, 57, -68, +-30, -318, -163, -357, -277, -197, -308, 61, +-234, 335, -69, 493, 138, 434, 310, 143, +399, -252, 316, -569, 83, -694, -164, -618, +-347, -357, -418, 58, -291, 476, -24, 712, +230, 742, 389, 607, 420, 317, 285, -95, +36, -430, -201, -552, -356, -553, -433, -498, +-388, -300, -237, -63, -52, 30, 165, 122, +387, 333, 509, 450, 507, 449, 378, 449, +176, 379, -50, 142, -321, -148, -606, -402, +-757, -598, -713, -687, -461, -627, -6, -378, +518, 23, 877, 405, 965, 662, 787, 744, +378, 627, -142, 318, -594, -37, -843, -276, +-806, -388, -546, -413, -155, -323, 265, -173, +493, -107, 392, -147, 162, -164, 0, -120, +-67, 0, -2, 213, 239, 499, 475, 718, +497, 728, 244, 485, -187, 51, -640, -466, +-975, -923, -1050, -1153, -735, -997, -92, -497, +641, 155, 1191, 761, 1369, 1167, 1081, 1186, +411, 806, -373, 241, -962, -352, -1157, -852, +-935, -1051, -477, -863, 60, -425, 496, 55, +619, 465, 447, 682, 186, 630, -61, 361, +-211, 33, -151, -194, 112, -252, 366, -186, +434, -109, 276, -62, -74, -47, -481, -107, +-775, -163, -844, -120, -562, 8, 1, 171, +557, 359, 912, 484, 981, 415, 711, 143, +180, -213, -414, -548, -824, -797, -878, -821, +-600, -486, -164, 90, 313, 687, 674, 1128, +701, 1237, 387, 906, -44, 215, -447, -599, +-653, -1239, -528, -1483, -177, -1242, 206, -592, +521, 229, 638, 930, 499, 1346, 205, 1345, +-135, 917, -441, 260, -593, -401, -536, -877, +-299, -1041, 23, -907, 287, -530, 366, -54, +290, 288, 151, 424, 33, 469, -6, 389, +11, 216, 17, 113, 44, 93, 80, 101, +39, 124, -91, 90, -232, -61, -342, -314, +-365, -564, -278, -683, -103, -593, 159, -309, +431, 132, 544, 593, 493, 907, 374, 956, +206, 709, -37, 260, -313, -253, -518, -730, +-618, -966, -642, -862, -497, -536, -161, -103, +224, 347, 545, 588, 789, 576, 861, 446, +651, 245, 247, 18, -174, -118, -572, -132, +-827, -87, -783, -62, -517, -78, -237, -146, +1, -248, 269, -356, 534, -385, 653, -225, +590, 118, 408, 472, 180, 708, -67, 803, +-325, 656, -496, 175, -539, -444, -554, -933, +-493, -1144, -258, -1001, 119, -496, 518, 247, +802, 971, 863, 1376, 666, 1290, 216, 757, +-321, -48, -729, -878, -936, -1420, -914, -1447, +-570, -962, 4, -191, 555, 641, 908, 1273, +962, 1419, 687, 1064, 218, 453, -285, -241, +-636, -857, -704, -1160, -579, -1065, -389, -688, +-130, -167, 123, 336, 293, 681, 382, 772, +409, 630, 389, 398, 364, 166, 271, -42, +70, -166, -190, -250, -449, -369, -671, -481, +-761, -505, -612, -443, -215, -244, 264, 64, +653, 380, 923, 634, 969, 728, 666, 614, +164, 365, -335, 36, -752, -320, -964, -601, +-834, -696, -438, -602, -15, -395, 269, -136, +451, 162, 541, 398, 487, 445, 331, 371, +207, 314, 121, 267, -7, 185, -150, 80, +-256, -23, -386, -176, -505, -395, -494, -573, +-356, -598, -120, -464, 214, -200, 541, 140, +724, 470, 728, 703, 542, 784, 131, 698, +-348, 442, -665, -3, -773, -486, -663, -827, +-319, -977, 86, -890, 384, -506, 526, 68, +486, 613, 311, 958, 106, 1015, -94, 754, +-236, 227, -246, -372, -169, -765, -106, -858, +-37, -664, 64, -215, 108, 279, 64, 586, +23, 631, 41, 394, 66, -18, 11, -377, +-83, -547, -128, -495, -135, -196, -132, 206, +-42, 512, 131, 626, 266, 494, 308, 162, +319, -199, 216, -479, -82, -598, -426, -499, +-600, -243, -563, 27, -371, 261, -42, 422, +384, 427, 709, 269, 735, 93, 472, -21, +98, -109, -238, -167, -509, -147, -638, -94, +-464, -83, -82, -106, 201, -84, 270, -31, +257, -4, 164, 30, -43, 84, -207, 68, +-176, 7, -1, 25, 224, 111, 373, 212, +409, 301, 302, 278, -34, 105, -472, -197, +-736, -541, -749, -757, -531, -716, -80, -424, +485, 75, 900, 628, 963, 1001, 695, 1080, +242, 832, -302, 261, -785, -423, -956, -969, +-720, -1207, -284, -1038, 165, -513, 546, 139, +706, 690, 545, 957, 165, 852, -213, 475, +-395, 21, -400, -339, -244, -484, 101, -400, +413, -153, 460, 100, 305, 180, -11, 42, +-448, -166, -745, -317, -701, -353, -381, -179, +101, 176, 622, 500, 970, 640, 990, 547, +664, 254, 58, -110, -610, -394, -1096, -551, +-1244, -552, -962, -413, -303, -209, 447, 32, +991, 271, 1214, 438, 1085, 546, 564, 553, +-166, 382, -763, 66, -1042, -327, -952, -700, +-546, -831, -35, -613, 403, -169, 632, 365, +575, 789, 340, 865, 100, 579, -75, 71, +-147, -445, -123, -728, -64, -677, -18, -387, +-9, 20, -108, 373, -247, 503, -293, 408, +-243, 184, -88, -57, 169, -186, 387, -182, +494, -94, 452, 17, 275, 83, 67, 42, +-168, -85, -436, -217, -599, -279, -596, -238, +-474, -95, -187, 130, 300, 388, 713, 564, +802, 595, 662, 456, 379, 134, -65, -318, +-505, -740, -763, -994, -770, -1011, -553, -693, +-161, -33, 298, 715, 647, 1270, 732, 1466, +564, 1202, 250, 500, -104, -392, -420, -1152, +-561, -1527, -502, -1421, -368, -905, -161, -137, +153, 640, 457, 1136, 616, 1256, 560, 1059, +326, 592, -1, 0, -368, -461, -659, -717, +-708, -839, -504, -834, -175, -639, 193, -280, +575, 121, 800, 498, 721, 857, 410, 1040, +14, 841, -389, 321, -698, -299, -772, -857, +-586, -1142, -291, -986, 31, -454, 379, 234, +658, 808, 722, 1023, 561, 832, 298, 347, +-25, -228, -406, -608, -668, -667, -718, -530, +-594, -283, -243, 20, 257, 247, 612, 348, +683, 384, 507, 351, 158, 230, -201, 39, +-373, -178, -343, -327, -203, -344, -14, -249, +115, -70, 107, 122, 41, 228, -28, 152, +-78, -67, -108, -232, -111, -195, 0, 5, +193, 311, 298, 623, 280, 694, 157, 353, +-74, -271, -317, -887, -416, -1177, -338, -979, +-142, -348, 106, 499, 272, 1170, 267, 1320, +227, 934, 204, 213, 108, -547, -54, -1012, +-202, -1011, -265, -641, -227, -93, -165, 391, +-51, 625, 155, 602, 275, 398, 168, 92, +-11, -214, -110, -444, -118, -520, 6, -385, +202, -48, 260, 353, 160, 616, -50, 629, +-340, 386, -501, -79, -403, -581, -174, -832, +125, -725, 422, -345, 546, 179, 502, 637, +423, 863, 183, 778, -294, 379, -693, -191, +-809, -671, -715, -877, -369, -744, 216, -310, +742, 277, 902, 764, 701, 895, 343, 611, +-22, 100, -325, -434, -509, -770, -584, -751, +-552, -445, -420, -27, -173, 324, 193, 456, +548, 438, 693, 414, 600, 365, 363, 260, +53, 98, -263, -216, -412, -607, -399, -826, +-431, -785, -478, -509, -376, -29, -148, 491, +179, 833, 569, 921, 859, 815, 888, 561, +624, 170, 78, -313, -584, -761, -1007, -1070, +-1039, -1129, -834, -858, -434, -300, 134, 392, +665, 987, 1032, 1251, 1158, 1140, 901, 737, +315, 122, -410, -502, -1025, -872, -1203, -963, +-877, -824, -370, -464, 120, -46, 533, 237, +664, 419, 531, 541, 440, 520, 392, 377, +202, 245, -96, 121, -383, -57, -583, -252, +-619, -384, -469, -423, -169, -384, 146, -275, +332, -105, 384, 92, 416, 262, 460, 356, +388, 381, 102, 350, -245, 232, -490, 24, +-616, -184, -560, -359, -282, -458, 52, -369, +319, -127, 532, 93, 593, 260, 409, 364, +118, 332, -171, 193, -423, 32, -537, -148, +-439, -319, -162, -422, 155, -379, 351, -146, +390, 211, 272, 537, 36, 678, -174, 517, +-211, 99, -117, -382, -43, -726, -11, -802, +57, -560, 114, -93, 94, 427, 49, 771, +11, 792, -99, 527, -247, 81, -264, -391, +-128, -691, 64, -707, 293, -410, 432, 59, +363, 433, 179, 589, -43, 521, -293, 197, +-490, -221, -553, -481, -414, -531, -83, -357, +293, -18, 566, 248, 674, 393, 509, 462, +78, 351, -317, 99, -456, -127, -418, -296, +-254, -357, -57, -296, 33, -210, 65, -81, +92, 78, 75, 134, 72, 116, 101, 122, +129, 184, 171, 296, 208, 340, 134, 201, +-76, -48, -317, -322, -450, -533, -397, -550, +-167, -374, 141, -83, 380, 227, 404, 379, +258, 399, 94, 404, -60, 300, -206, 78, +-274, -71, -235, -178, -76, -334, 143, -374, +302, -209, 321, -29, 166, 58, -127, 79, +-397, 40, -472, -45, -293, -52, -8, 90, +234, 306, 409, 467, 464, 452, 343, 186, +131, -257, -72, -685, -246, -857, -401, -651, +-484, -158, -401, 415, -106, 828, 226, 855, +386, 489, 444, -33, 418, -452, 156, -626, +-151, -530, -298, -242, -350, 119, -244, 352, +12, 361, 187, 260, 254, 115, 252, -108, +63, -277, -235, -299, -393, -234, -370, -65, +-187, 189, 167, 352, 492, 346, 591, 178, +443, -101, 63, -330, -329, -411, -528, -339, +-525, -53, -297, 321, 30, 492, 216, 421, +287, 224, 282, -76, 165, -388, 41, -556, +-49, -498, -156, -260, -158, 33, -54, 332, +-13, 586, 35, 642, 128, 472, 68, 165, +-47, -233, -65, -601, -99, -721, -113, -562, +-45, -240, -12, 128, 29, 409, 98, 504, +115, 403, 110, 179, 88, 0, -26, -52, +-135, -66, -133, -84, -81, -69, -6, -39, +145, -61, 211, -154, 31, -232, -253, -240, +-410, -211, -364, -131, -97, 96, 334, 415, +671, 642, 648, 665, 291, 461, -198, 55, +-552, -437, -576, -822, -379, -886, -141, -604, +81, -142, 163, 309, 168, 598, 282, 621, +366, 407, 240, 106, 23, -98, -160, -135, +-264, -79, -232, -11, -83, 29, 46, -34, +65, -177, -6, -292, -59, -361, -38, -337, +-21, -119, -13, 192, 63, 442, 142, 591, +227, 568, 317, 339, 204, -3, -117, -353, +-409, -558, -563, -549, -460, -420, -78, -186, +351, 143, 576, 389, 507, 469, 234, 368, +-28, 91, -197, -184, -341, -326, -408, -346, +-319, -101, -172, 331, 45, 534, 359, 413, +543, 103, 484, -374, 239, -776, -155, -784, +-474, -402, -527, 174, -378, 697, -108, 901, +206, 691, 393, 173, 371, -354, 177, -590, +-93, -561, -281, -385, -239, -62, -55, 220, +107, 291, 200, 270, 196, 241, 100, 165, +-27, 13, -158, -233, -223, -412, -220, -345, +-233, -139, -236, 95, -125, 338, 133, 412, +404, 276, 544, 113, 573, -24, 456, -119, +101, -126, -404, -171, -832, -318, -1023, -426, +-848, -377, -338, -135, 255, 248, 752, 581, +1073, 722, 997, 628, 568, 322, 116, -84, +-332, -415, -780, -569, -991, -591, -897, -568, +-554, -467, -9, -210, 527, 180, 846, 593, +843, 888, 523, 921, 99, 635, -245, 72, +-484, -550, -528, -898, -285, -828, 50, -475, +247, -77, 249, 168, 89, 242, -152, 238, +-380, 219, -445, 230, -139, 287, 350, 326, +633, 275, 650, 82, 455, -204, 87, -431, +-308, -542, -638, -586, -797, -509, -614, -210, +-159, 276, 362, 735, 800, 932, 881, 824, +467, 438, -139, -222, -562, -861, -681, -1072, +-453, -820, 14, -309, 403, 282, 482, 725, +334, 832, 142, 585, -40, 152, -219, -217, +-330, -424, -367, -494, -293, -388, -47, -162, +234, 19, 431, 170, 506, 333, 335, 354, +8, 170, -237, -81, -370, -244, -348, -225, +-152, -19, 23, 259, 134, 396, 202, 204, +81, -255, -161, -690, -224, -817, -77, -509, +164, 156, 388, 893, 395, 1302, 131, 1087, +-176, 322, -371, -577, -410, -1210, -316, -1355, +-162, -926, 47, -117, 241, 658, 331, 1071, +348, 981, 230, 520, -76, -1, -355, -389, +-375, -569, -165, -498, 120, -260, 339, -24, +305, 155, -26, 266, -378, 230, -513, 75, +-383, -100, -51, -254, 311, -292, 560, -100, +651, 243, 467, 487, 42, 508, -412, 302, +-758, -118, -854, -573, -569, -792, -40, -657, +446, -207, 725, 384, 737, 833, 510, 885, +194, 505, -147, -98, -464, -634, -647, -879, +-622, -723, -351, -206, 68, 417, 347, 799, +392, 789, 267, 475, 115, -15, 97, -540, +196, -864, 244, -815, 100, -431, -250, 151, +-550, 704, -512, 952, -181, 781, 170, 300, +349, -289, 309, -756, 126, -887, -11, -594, +29, -24, 111, 463, 63, 649, -92, 550, +-204, 181, -156, -284, 26, -523, 203, -441, +256, -95, 166, 363, -25, 602, -274, 468, +-394, 81, -298, -402, -117, -722, 137, -665, +433, -316, 574, 173, 505, 608, 257, 751, +-131, 607, -458, 276, -535, -180, -428, -566, +-267, -728, -66, -661, 135, -317, 272, 217, +334, 684, 302, 885, 178, 644, 22, 37, +-68, -565, -14, -925, 125, -880, 120, -312, +-128, 508, -488, 1082, -701, 1111, -555, 548, +-118, -338, 329, -1077, 609, -1351, 693, -978, +606, -47, 365, 918, 11, 1453, -380, 1355, +-716, 595, -878, -475, -721, -1287, -239, -1508, +316, -1078, 643, -142, 656, 866, 422, 1424, +132, 1297, -49, 614, -161, -272, -297, -995, +-356, -1284, -254, -995, -47, -254, 129, 549, +111, 1039, -123, 1077, -351, 678, -312, -57, +20, -801, 447, -1133, 783, -931, 792, -307, +311, 529, -378, 1185, -847, 1274, -960, 720, +-785, -215, -378, -1120, 187, -1601, 701, -1371, +1002, -449, 970, 767, 566, 1703, -72, 1946, +-680, 1346, -981, 95, -824, -1223, -370, -2044, +168, -2034, 603, -1125, 702, 252, 458, 1487, +87, 2107, -280, 1783, -526, 670, -456, -613, +-44, -1560, 430, -1838, 688, -1253, 613, -131, +189, 958, -370, 1619, -759, 1502, -819, 639, +-536, -450, -50, -1344, 498, -1712, 903, -1255, +992, -171, 733, 999, 136, 1820, -574, 1886, +-1042, 1049, -1092, -279, -613, -1492, 169, -2099, +757, -1795, 967, -686, 808, 705, 318, 1751, +-195, 1987, -498, 1337, -690, 168, -702, -1003, +-387, -1690, 74, -1590, 535, -780, 847, 373, +736, 1320, 270, 1576, -274, 1068, -704, 136, +-696, -838, -301, -1484, 60, -1421, 265, -674, +305, 329, 153, 1192, -24, 1553, -112, 1166, +-87, 249, 41, -698, 142, -1335, 144, -1343, +108, -643, 8, 296, -166, 998, -295, 1206, +-377, 742, -378, -124, -164, -841, 137, -1146, +404, -889, 561, -61, 440, 800, 60, 1258, +-338, 1267, -583, 685, -541, -329, -207, -1235, +178, -1646, 385, -1365, 375, -481, 139, 577, +-185, 1394, -375, 1681, -369, 1227, -220, 283, +4, -647, 240, -1281, 415, -1371, 452, -868, +344, -82, 77, 702, -312, 1182, -623, 1053, +-709, 359, -601, -485, -258, -1070, 335, -1129, +900, -571, 1075, 354, 802, 1173, 197, 1483, +-529, 1040, -1060, -11, -1128, -1084, -663, -1689, +104, -1607, 707, -737, 931, 554, 804, 1513, +381, 1763, -124, 1327, -466, 282, -587, -905, +-550, -1559, -289, -1473, 204, -804, 573, 134, +612, 953, 410, 1377, 4, 1201, -460, 498, +-667, -389, -442, -1121, 51, -1399, 477, -1045, +685, -217, 609, 695, 309, 1380, -91, 1490, +-514, 821, -794, -233, -707, -1132, -282, -1520, +239, -1189, 711, -305, 985, 688, 762, 1399, +149, 1481, -444, 699, -830, -502, -822, -1324, +-367, -1529, 215, -1114, 677, -27, 767, 1243, +380, 1912, -178, 1669, -676, 635, -859, -768, +-428, -1802, 253, -2022, 689, -1489, 820, -339, +578, 1065, 30, 1982, -414, 1952, -686, 1151, +-798, -16, -500, -1078, -70, -1633, 216, -1520, +567, -792, 710, 239, 431, 1082, 10, 1341, +-473, 953, -760, 144, -486, -699, 76, -1163, +520, -1055, 695, -368, 430, 616, -190, 1329, +-755, 1399, -1056, 752, -920, -368, -251, -1358, +607, -1724, 1226, -1372, 1365, -334, 909, 1005, +59, 1797, -857, 1699, -1531, 891, -1578, -388, +-884, -1470, 152, -1711, 1064, -1102, 1522, 27, +1309, 1129, 484, 1580, -544, 1199, -1281, 204, +-1372, -959, -757, -1560, 202, -1359, 973, -620, +1237, 476, 890, 1411, 139, 1636, -607, 1150, +-1011, 189, -958, -824, -489, -1429, 172, -1460, +667, -855, 873, 212, 786, 1058, 315, 1275, +-343, 914, -782, 39, -729, -856, -205, -1194, +491, -866, 931, 75, 776, 1132, 129, 1590, +-619, 1255, -1114, 185, -1048, -1246, -454, -2176, +380, -2123, 1128, -1114, 1435, 574, 1192, 2103, +592, 2706, -253, 2220, -1199, 777, -1746, -1050, +-1448, -2437, -473, -2833, 695, -1994, 1560, -239, +1686, 1534, 1048, 2635, -20, 2581, -1069, 1250, +-1511, -610, -1163, -2183, -351, -2792, 621, -1933, +1361, -142, 1496, 1653, 993, 2770, -24, 2599, +-1154, 1170, -1805, -724, -1673, -2349, -870, -3068, +342, -2395, 1444, -749, 1890, 1112, 1619, 2632, +757, 3098, -360, 2267, -1198, 560, -1649, -1355, +-1507, -2643, -661, -2769, 185, -1740, 687, -42, +1035, 1459, 965, 2104, 431, 1785, -61, 717, +-340, -542, -464, -1224, -413, -1077, -347, -376, +-230, 413, 20, 778, 154, 534, 161, -108, +136, -797, -59, -1051, -153, -626, 41, 178, +142, 993, 74, 1478, -24, 1262, -282, 455, +-515, -572, -439, -1534, -69, -2021, 475, -1622, +889, -406, 850, 1061, 355, 2203, -343, 2537, +-954, 1783, -1238, 172, -1045, -1618, -428, -2723, +420, -2634, 1111, -1430, 1311, 285, 1034, 1736, +470, 2442, -198, 2128, -801, 924, -1129, -487, +-1025, -1448, -570, -1725, 84, -1317, 681, -312, +944, 765, 799, 1258, 303, 995, -318, 198, +-628, -754, -431, -1384, -17, -1219, 338, -258, +530, 1010, 401, 1991, 63, 2129, -212, 1267, +-419, -318, -597, -1988, -567, -2906, -226, -2588, +331, -1206, 914, 672, 1173, 2379, 855, 3151, +129, 2585, -694, 1017, -1247, -870, -1132, -2311, +-400, -2792, 413, -2190, 976, -705, 1180, 1037, +916, 2238, 262, 2417, -577, 1565, -1271, 11, +-1408, -1563, -883, -2346, 112, -1971, 1124, -674, +1636, 885, 1413, 1989, 621, 2212, -338, 1507, +-1034, 125, -1268, -1319, -1140, -2117, -687, -2055, +-15, -1276, 504, -18, 880, 1300, 1053, 2151, +649, 2114, -29, 1178, -444, -252, -537, -1546, +-279, -2198, 109, -1878, 205, -610, 89, 862, +-140, 1828, -566, 2001, -746, 1257, -472, -108, +-139, -1392, 234, -1940, 676, -1647, 884, -730, +874, 484, 598, 1448, -81, 1800, -720, 1458, +-1006, 628, -1043, -321, -724, -1150, -211, -1575, +222, -1390, 569, -733, 646, 56, 416, 771, +138, 1162, -96, 986, -187, 511, -37, 33, +210, -356, 366, -374, 303, -91, -152, 89, +-789, 109, -1112, -88, -991, -559, -508, -884, +198, -846, 883, -478, 1370, 316, 1454, 1206, +1057, 1681, 274, 1623, -693, 913, -1481, -413, +-1784, -1624, -1447, -2129, -433, -1938, 778, -979, +1509, 491, 1646, 1736, 1204, 2173, 251, 1652, +-642, 557, -1141, -628, -1247, -1546, -847, -1804, +-106, -1199, 655, -85, 1262, 863, 1345, 1426, +724, 1462, -115, 746, -830, -338, -1323, -1149, +-1168, -1440, -420, -1168, 354, -351, 915, 600, +1125, 1184, 845, 1295, 327, 876, -121, 100, +-437, -589, -576, -926, -482, -843, -223, -446, +101, 47, 278, 415, 231, 483, 93, 197, +-138, -198, -359, -366, -266, -290, 95, 25, +456, 528, 766, 899, 811, 826, 326, 322, +-331, -390, -802, -1104, -1033, -1429, -860, -1130, +-353, -456, 176, 407, 619, 1241, 820, 1586, +643, 1263, 326, 550, 49, -280, -255, -945, +-399, -1190, -308, -1037, -228, -515, -214, 139, +-234, 485, -291, 517, -188, 371, 133, 87, +368, -92, 414, 1, 388, 225, 179, 515, +-157, 643, -384, 268, -462, -407, -375, -1005, +-111, -1274, 154, -1068, 272, -444, 287, 498, +199, 1316, -65, 1517, -402, 1180, -610, 574, +-448, -256, 12, -1019, 398, -1324, 581, -1237, +581, -725, 364, 87, 30, 683, -320, 996, +-653, 954, -816, 511, -659, 2, -260, -449, +253, -666, 765, -421, 1043, -88, 829, 29, +183, 195, -494, 285, -854, 86, -772, -35, +-385, -53, 13, -63, 334, 39, 518, 52, +485, -30, 320, -136, 106, -346, -165, -293, +-374, 93, -410, 342, -314, 570, -14, 824, +385, 580, 498, -77, 400, -716, 207, -1153, +-89, -1246, -202, -955, -165, -235, -204, 819, +-144, 1614, -36, 1741, -81, 1378, -41, 498, +181, -775, 369, -1688, 494, -1929, 442, -1570, +132, -678, -194, 464, -357, 1403, -372, 1742, +-309, 1539, -217, 904, -43, -99, 150, -1032, +227, -1543, 292, -1524, 360, -945, 255, -46, +116, 764, -3, 1343, -182, 1520, -204, 1022, +-155, 163, -218, -674, -243, -1307, -214, -1435, +-115, -1144, 55, -521, 162, 426, 272, 1219, +451, 1552, 437, 1548, 209, 1044, 10, 18, +-246, -1054, -591, -1881, -768, -2147, -642, -1557, +-236, -389, 184, 1002, 468, 2136, 704, 2417, +669, 1818, 281, 660, -69, -809, -358, -2038, +-647, -2466, -603, -2066, -294, -932, -56, 616, +135, 1942, 247, 2607, 235, 2299, 145, 1058, +0, -586, -52, -2018, 11, -2722, 31, -2394, +23, -1148, -24, 544, -200, 2072, -373, 2770, +-406, 2413, -264, 1275, 130, -354, 543, -1895, +720, -2648, 668, -2366, 264, -1332, -407, 10, +-960, 1326, -1177, 2203, -906, 2249, -220, 1474, +556, 322, 1234, -822, 1610, -1684, 1354, -1870, +576, -1366, -435, -396, -1499, 640, -2076, 1216, +-1840, 1248, -1025, 820, 215, 43, 1530, -657, +2326, -881, 2320, -635, 1609, -104, 385, 565, +-1003, 973, -2026, 822, -2406, 189, -2202, -656, +-1308, -1253, 244, -1352, 1752, -884, 2585, 107, +2650, 1176, 1881, 1813, 498, 1728, -947, 921, +-2088, -258, -2571, -1363, -2147, -2098, -1121, -2058, +147, -1075, 1430, 274, 2288, 1406, 2424, 2144, +1801, 2169, 468, 1339, -987, 95, -1965, -1173, +-2278, -2140, -1748, -2312, -607, -1705, 643, -567, +1639, 877, 1908, 1989, 1349, 2295, 391, 1850, +-556, 772, -1206, -576, -1294, -1446, -825, -1643, +-9, -1419, 793, -732, 1044, 43, 715, 484, +157, 679, -674, 622, -1411, 401, -1314, 221, +-498, 154, 556, 254, 1647, 425, 2196, 434, +1644, 198, 273, -194, -1273, -805, -2480, -1414, +-2828, -1579, -2055, -1192, -488, -267, 1283, 891, +2647, 1850, 3003, 2389, 2308, 2149, 903, 1028, +-911, -452, -2456, -1734, -2944, -2472, -2330, -2352, +-1079, -1476, 382, -247, 1605, 1032, 2102, 1879, +1815, 1940, 967, 1369, -113, 465, -911, -457, +-1188, -1062, -989, -1152, -390, -727, 278, 6, +576, 525, 356, 577, -113, 288, -518, -293, +-647, -792, -433, -819, 24, -484, 570, 96, +979, 786, 1094, 1155, 894, 1022, 285, 639, +-580, 114, -1205, -410, -1378, -728, -1158, -868, +-440, -800, 466, -600, 981, -377, 1091, -70, +956, 213, 563, 443, 88, 791, -348, 1075, +-706, 951, -737, 590, -427, 100, -69, -617, +312, -1193, 557, -1372, 390, -1132, 105, -442, +-49, 414, -226, 1040, -351, 1228, -315, 959, +-233, 289, -28, -505, 443, -1030, 864, -1016, +962, -376, 676, 542, -9, 1256, -732, 1435, +-1139, 907, -1197, -185, -866, -1454, -245, -2248, +418, -2094, 957, -1081, 1279, 399, 1220, 1816, +769, 2660, 53, 2613, -786, 1656, -1315, 65, +-1209, -1579, -702, -2576, -61, -2650, 539, -1922, +831, -609, 729, 886, 404, 1961, -16, 2217, +-406, 1697, -615, 751, -523, -258, -167, -1087, +256, -1434, 562, -1198, 620, -633, 395, 33, +4, 590, -394, 794, -644, 583, -715, 247, +-634, -31, -445, -273, -142, -349, 317, -309, +736, -249, 923, -145, 937, -8, 750, 247, +310, 570, -356, 787, -1010, 737, -1462, 316, +-1671, -391, -1314, -1110, -291, -1475, 856, -1377, +1702, -789, 2120, 235, 1850, 1303, 822, 2014, +-451, 2085, -1542, 1431, -2173, 276, -1992, -1047, +-1141, -2143, -10, -2595, 1171, -2192, 1882, -1080, +1727, 445, 987, 1929, 32, 2763, -838, 2683, +-1215, 1783, -1022, 327, -453, -1234, 160, -2368, +539, -2721, 585, -2277, 269, -1264, -242, 62, +-516, 1421, -335, 2347, 130, 2613, 628, 2258, +919, 1214, 800, -285, 325, -1645, -391, -2480, +-1082, -2742, -1325, -2322, -1118, -1161, -571, 336, +336, 1705, 1262, 2733, 1822, 3211, 1756, 2761, +972, 1301, -165, -600, -1153, -2412, -1764, -3714, +-1794, -3865, -1143, -2627, -235, -501, 534, 1773, +1134, 3537, 1462, 4120, 1413, 3238, 988, 1315, +358, -873, -266, -2636, -834, -3515, -1224, -3191, +-1279, -1798, -1125, 21, -799, 1565, -130, 2414, +695, 2489, 1401, 1802, 1838, 620, 1634, -553, +800, -1335, -204, -1556, -1201, -1344, -1981, -827, +-2033, -170, -1351, 302, -264, 576, 986, 784, +1905, 838, 2089, 683, 1533, 496, 333, 253, +-1054, -177, -2008, -625, -2158, -1014, -1406, -1229, +-89, -986, 1213, -411, 2045, 313, 2093, 1185, +1296, 1789, -105, 1686, -1558, 1022, -2452, 24, +-2325, -1109, -1237, -1941, 260, -2075, 1660, -1463, +2484, -479, 2325, 540, 1200, 1491, -343, 1987, +-1518, 1672, -2098, 943, -2122, 270, -1368, -467, +16, -1123, 1231, -1352, 1748, -1247, 1664, -997, +1072, -690, 16, -273, -988, 280, -1328, 862, +-1059, 1383, -464, 1693, 326, 1665, 857, 1185, +767, 211, 325, -1101, -116, -2279, -541, -2738, +-750, -2398, -480, -1361, 18, 295, 486, 2011, +806, 3035, 729, 3033, 378, 2204, 2, 736, +-418, -1117, -725, -2555, -673, -3008, -344, -2611, +3, -1557, 307, 32, 465, 1672, 362, 2631, +246, 2517, 171, 1658, 31, 588, 17, -618, +114, -1700, 64, -1984, -124, -1520, -303, -934, +-413, -295, -337, 461, -152, 982, 3, 1222, +323, 1314, 648, 1165, 603, 791, 392, 129, +201, -768, -171, -1534, -576, -2009, -744, -2032, +-667, -1318, -316, -17, 165, 1427, 560, 2635, +824, 3073, 767, 2473, 410, 1122, 4, -772, +-421, -2697, -818, -3718, -916, -3499, -699, -2281, +-328, -270, 186, 2036, 779, 3666, 1203, 3959, +1230, 2968, 753, 1162, -23, -913, -833, -2672, +-1454, -3381, -1608, -2843, -1225, -1603, -456, -166, +504, 1145, 1342, 1921, 1823, 1889, 1747, 1338, +1048, 762, -63, 248, -1230, -216, -2107, -434, +-2264, -420, -1493, -542, -171, -873, 1148, -1090, +1984, -1013, 2032, -676, 1405, -136, 265, 630, +-1006, 1422, -1779, 1812, -1791, 1667, -1219, 1037, +-241, 38, 843, -1003, 1594, -1725, 1736, -1914, +1104, -1518, -79, -675, -1103, 239, -1554, 974, +-1536, 1403, -1044, 1304, -69, 852, 895, 479, +1458, 143, 1619, -255, 1328, -531, 620, -704, +-278, -855, -1122, -945, -1683, -948, -1817, -641, +-1447, 56, -580, 814, 551, 1398, 1546, 1779, +2129, 1692, 2195, 928, 1568, -183, 287, -1360, +-1085, -2320, -2005, -2546, -2290, -1902, -1946, -587, +-1019, 1030, 208, 2381, 1331, 2990, 2058, 2561, +2086, 1195, 1470, -547, 556, -1983, -456, -2685, +-1336, -2547, -1708, -1637, -1433, -242, -776, 1121, +26, 1960, 710, 2109, 999, 1657, 866, 739, +515, -367, 152, -1231, -68, -1438, -59, -1004, +59, -367, 113, 188, -16, 544, -406, 462, +-787, -97, -858, -629, -598, -692, -141, -354, +441, 270, 1078, 1058, 1480, 1669, 1308, 1734, +655, 1070, -250, -155, -1253, -1454, -1958, -2471, +-1925, -2935, -1157, -2396, 29, -876, 1197, 969, +1923, 2592, 1960, 3563, 1337, 3432, 369, 2199, +-563, 341, -1361, -1648, -1761, -3189, -1513, -3729, +-832, -3173, -33, -1766, 668, 42, 991, 1797, +825, 3126, 473, 3466, 225, 2664, 207, 1266, +399, -310, 481, -1797, 250, -2619, -315, -2464, +-1055, -1653, -1620, -600, -1752, 409, -1406, 1063, +-545, 1224, 838, 1100, 2238, 831, 2931, 427, +2701, 156, 1619, 99, -228, 61, -2237, -36, +-3445, -246, -3451, -498, -2402, -712, -606, -981, +1351, -1133, 2813, -851, 3384, -188, 2838, 592, +1333, 1380, -439, 1940, -1882, 1966, -2608, 1440, +-2338, 401, -1340, -902, -202, -1950, 774, -2458, +1361, -2303, 1441, -1550, 1136, -467, 508, 844, +-177, 2064, -565, 2600, -637, 2459, -465, 1832, +-54, 611, 313, -841, 305, -1893, 103, -2424, +-93, -2413, -309, -1753, -419, -783, -373, 130, +-309, 1089, -199, 1992, 277, 2474, 960, 2386, +1357, 1783, 1335, 725, 893, -754, -22, -2225, +-1164, -2983, -2070, -2986, -2405, -2449, -1982, -1165, +-779, 596, 910, 2081, 2590, 3167, 3585, 3671, +3383, 3031, 1897, 1475, -446, -342, -2740, -2178, +-4070, -3646, -4082, -4031, -2733, -3152, -396, -1529, +2026, 353, 3726, 2113, 4249, 3306, 3385, 3608, +1455, 2963, -877, 1666, -2889, 139, -3824, -1403, +-3419, -2693, -2068, -3307, -177, -3109, 1617, -2253, +2611, -817, 2677, 913, 2030, 2334, 842, 3128, +-440, 3226, -1239, 2427, -1413, 941, -1151, -650, +-839, -2046, -676, -2943, -527, -2964, -303, -2118, +106, -717, 719, 782, 1360, 1938, 1695, 2422, +1397, 2126, 546, 1225, -530, 49, -1519, -982, +-2131, -1549, -2043, -1505, -1183, -897, 96, -112, +1356, 633, 2259, 1189, 2393, 1082, 1535, 370, +24, -298, -1458, -821, -2382, -1250, -2512, -1215, +-1747, -571, -321, 293, 1195, 987, 2378, 1544, +2834, 1931, 2226, 1684, 815, 766, -764, -333, +-2154, -1438, -3004, -2439, -2877, -2802, -1776, -2311, +-172, -1224, 1426, 323, 2742, 1965, 3383, 3169, +2942, 3666, 1581, 3114, -99, 1575, -1759, -313, +-3078, -2198, -3480, -3724, -2936, -4234, -1717, -3547, +72, -1947, 1972, 216, 3368, 2417, 3826, 4035, +3281, 4541, 1800, 3736, -325, 1935, -2293, -373, +-3354, -2568, -3478, -3908, -2838, -4092, -1428, -3244, +402, -1562, 1881, 465, 2682, 2182, 2951, 3210, +2599, 3390, 1423, 2648, -3, 1193, -997, -505, +-1704, -1914, -2267, -2653, -2268, -2650, -1748, -1939, +-996, -650, -13, 715, 1070, 1714, 1969, 2164, +2508, 1899, 2498, 1065, 1849, -20, 711, -1091, +-675, -1711, -2052, -1720, -3052, -1258, -3256, -397, +-2460, 580, -990, 1310, 786, 1648, 2596, 1522, +3755, 958, 3653, 120, 2542, -768, 843, -1476, +-1336, -1837, -3305, -1793, -4271, -1285, -3999, -334, +-2479, 731, -143, 1624, 2221, 2244, 3918, 2276, +4448, 1607, 3633, 564, 1723, -584, -738, -1627, +-2996, -2319, -4203, -2468, -4109, -1986, -2929, -1044, +-906, 101, 1373, 1185, 3032, 1999, 3638, 2446, +3246, 2298, 2028, 1610, 247, 783, -1460, -189, +-2458, -1299, -2706, -2157, -2311, -2644, -1358, -2688, +-236, -1992, 700, -696, 1317, 742, 1582, 2132, +1547, 3183, 1263, 3330, 746, 2519, 168, 1197, +-336, -374, -809, -1921, -1165, -2904, -1359, -3055, +-1416, -2531, -1181, -1456, -493, 0, 380, 1349, +1221, 2207, 1899, 2563, 2076, 2369, 1637, 1557, +705, 431, -506, -580, -1557, -1351, -2178, -1855, +-2192, -1880, -1508, -1448, -317, -914, 891, -265, +1824, 694, 2241, 1536, 1905, 1821, 1030, 1671, +5, 1155, -1077, 243, -1920, -903, -2070, -1848, +-1530, -1987, -641, -1343, 486, -383, 1623, 853, +2217, 2068, 1985, 2393, 1245, 1576, 228, 129, +-975, -1427, -1948, -2600, -2222, -2808, -1885, -1870, +-1105, -165, 155, 1604, 1489, 2710, 2293, 2886, +2377, 2171, 1782, 733, 707, -803, -453, -1897, +-1436, -2392, -2013, -2174, -1927, -1396, -1395, -418, +-757, 429, -26, 916, 757, 1116, 1300, 1131, +1411, 1049, 1345, 1026, 1269, 986, 1050, 788, +555, 354, -157, -498, -1049, -1624, -2010, -2506, +-2624, -2832, -2595, -2461, -1873, -1194, -445, 705, +1406, 2567, 3035, 3880, 3828, 4134, 3650, 3036, +2471, 964, 365, -1443, -2040, -3454, -3883, -4414, +-4674, -4107, -4180, -2583, -2381, -330, 162, 1758, +2488, 3154, 4022, 3643, 4527, 3129, 3665, 1920, +1673, 425, -571, -1068, -2417, -2166, -3533, -2603, +-3622, -2472, -2680, -1905, -1204, -923, 255, 281, +1461, 1307, 2249, 1933, 2437, 2201, 2114, 2017, +1520, 1278, 599, 253, -497, -737, -1417, -1591, +-2024, -2082, -2294, -1900, -2014, -1207, -1171, -396, +-62, 486, 1107, 1274, 2095, 1586, 2497, 1441, +2201, 1057, 1362, 531, 136, 49, -1282, -275, +-2228, -543, -2314, -859, -1808, -1157, -988, -1293, +125, -1158, 1237, -730, 1745, -19, 1551, 954, +1182, 1835, 781, 2145, 208, 1961, -318, 1354, +-651, 193, -871, -1115, -952, -2116, -954, -2667, +-879, -2502, -576, -1566, -80, -195, 436, 1217, +931, 2315, 1374, 2751, 1698, 2416, 1622, 1506, +867, 266, -197, -935, -1161, -1714, -1946, -2049, +-2220, -1952, -1748, -1387, -907, -621, 67, 19, +1130, 498, 1823, 961, 1993, 1378, 1876, 1578, +1344, 1564, 368, 1274, -676, 590, -1413, -390, +-1783, -1419, -1815, -2119, -1505, -2218, -783, -1814, +120, -920, 861, 321, 1427, 1322, 1728, 1770, +1563, 1833, 1030, 1553, 294, 895, -511, 100, +-1143, -518, -1410, -903, -1343, -1192, -991, -1385, +-373, -1223, 330, -729, 771, -223, 830, 227, +683, 665, 364, 932, -76, 941, -329, 777, +-263, 566, -47, 349, 234, 50, 470, -286, +560, -479, 330, -622, -336, -787, -1117, -799, +-1564, -694, -1532, -602, -997, -384, -6, 82, +1198, 690, 2141, 1266, 2412, 1726, 1860, 1862, +815, 1345, -472, 197, -1777, -1136, -2578, -2267, +-2560, -2880, -1916, -2620, -789, -1446, 604, 163, +1743, 1730, 2383, 2977, 2536, 3374, 1998, 2628, +871, 1147, -425, -655, -1518, -2325, -2268, -3255, +-2504, -3189, -2067, -2097, -1075, -227, 135, 1568, +1330, 2536, 2262, 2682, 2581, 2144, 2195, 890, +1301, -539, 6, -1408, -1387, -1561, -2264, -1196, +-2386, -609, -2010, -20, -1208, 393, 45, 304, +1244, -154, 1853, -414, 1946, -318, 1653, 44, +1025, 731, 335, 1532, -295, 1911, -805, 1546, +-1116, 554, -1288, -812, -1397, -2172, -1320, -2990, +-956, -2885, -266, -1800, 682, -51, 1575, 1787, +2224, 3167, 2465, 3628, 1985, 2979, 910, 1442, +-447, -480, -1916, -2232, -2980, -3307, -3007, -3313, +-2181, -2247, -922, -588, 634, 995, 2058, 1960, +2785, 2158, 2656, 1678, 1817, 737, 561, -156, +-721, -570, -1637, -571, -1825, -285, -1311, 146, +-606, 310, -21, 110, 370, -277, 357, -886, +9, -1406, -302, -1385, -366, -893, -234, -80, +124, 938, 777, 1770, 1436, 2105, 1620, 1865, +1308, 1094, 588, 22, -503, -1044, -1691, -1826, +-2479, -2084, -2548, -1803, -1949, -1129, -895, -229, +420, 606, 1697, 1073, 2523, 1174, 2670, 1035, +2277, 769, 1335, 501, 12, 279, -1207, 179, +-2000, 134, -2378, -108, -2279, -497, -1647, -890, +-699, -1190, 212, -1253, 929, -1089, 1466, -635, +1792, 147, 1773, 856, 1397, 1244, 752, 1469, +6, 1502, -698, 1175, -1246, 610, -1533, -19, +-1422, -648, -973, -1150, -511, -1446, -155, -1573, +173, -1459, 421, -1061, 603, -436, 844, 339, +1086, 1111, 1133, 1779, 948, 2215, 683, 2138, +275, 1547, -420, 630, -1136, -460, -1547, -1526, +-1704, -2335, -1629, -2610, -1072, -2211, -27, -1303, +953, -167, 1541, 949, 1831, 1809, 1804, 2207, +1296, 2110, 591, 1645, 27, 994, -522, 280, +-1069, -439, -1414, -1057, -1524, -1502, -1436, -1750, +-1088, -1725, -419, -1460, 397, -994, 1119, -279, +1583, 613, 1725, 1479, 1541, 2175, 1039, 2550, +288, 2432, -469, 1697, -1002, 401, -1309, -1076, +-1339, -2349, -1015, -3213, -514, -3293, -150, -2425, +-15, -1045, 43, 508, 204, 2051, 511, 3056, +908, 3242, 1334, 2742, 1627, 1601, 1374, 10, +526, -1494, -462, -2506, -1349, -2908, -2127, -2566, +-2428, -1508, -1966, -208, -904, 928, 376, 1675, +1553, 1894, 2244, 1655, 2196, 1049, 1424, 269, +322, -338, -534, -712, -964, -924, -1025, -855, +-695, -504, -235, -180, 22, 1, -79, 111, +-395, 39, -676, -203, -802, -351, -696, -301, +-231, -66, 511, 368, 1269, 880, 1799, 1145, +1840, 930, 1292, 408, 440, -180, -512, -829, +-1525, -1300, -2184, -1317, -2119, -1018, -1687, -517, +-1103, 182, -143, 840, 915, 1213, 1596, 1236, +1945, 853, 2093, 191, 1840, -368, 1101, -717, +113, -846, -868, -570, -1741, -80, -2288, 201, +-2262, 246, -1718, 171, -892, -11, 144, -227, +1188, -366, 1829, -302, 1988, 47, 1855, 458, +1402, 692, 564, 765, -329, 620, -834, 165, +-1115, -375, -1401, -707, -1464, -780, -1196, -630, +-826, -303, -429, -11, 161, 128, 926, 189, +1564, 259, 1797, 397, 1648, 591, 1224, 687, +478, 634, -447, 438, -1228, -23, -1683, -653, +-1736, -1105, -1449, -1262, -883, -1138, -48, -651, +789, 200, 1251, 1119, 1433, 1761, 1386, 1908, +924, 1448, 295, 467, -149, -740, -533, -1750, +-842, -2208, -893, -1978, -770, -1087, -563, 152, +-233, 1302, 143, 2064, 485, 2215, 647, 1681, +552, 632, 334, -618, 86, -1669, -219, -2145, +-393, -1899, -337, -1152, -151, -192, 76, 800, +384, 1503, 671, 1637, 692, 1354, 355, 871, +-244, 255, -888, -356, -1298, -813, -1363, -1091, +-990, -1228, -210, -1209, 705, -927, 1401, -367, +1735, 322, 1646, 942, 1075, 1414, 187, 1603, +-717, 1330, -1428, 689, -1790, -114, -1706, -954, +-1164, -1606, -329, -1824, 455, -1559, 965, -878, +1209, 102, 1160, 1011, 860, 1497, 525, 1507, +221, 1092, -47, 423, -220, -170, -413, -517, +-728, -658, -979, -646, -1106, -559, -1067, -493, +-683, -447, -58, -388, 588, -194, 1283, 189, +1781, 578, 1702, 851, 1160, 985, 373, 825, +-633, 327, -1593, -331, -1998, -925, -1710, -1249, +-1021, -1137, -105, -580, 794, 283, 1304, 1112, +1369, 1507, 1117, 1252, 585, 423, -67, -637, +-577, -1494, -839, -1793, -773, -1329, -396, -215, +82, 1048, 426, 1902, 487, 2095, 322, 1550, +57, 419, -265, -812, -454, -1716, -372, -2073, +-183, -1734, -48, -811, 132, 281, 319, 1098, +407, 1437, 447, 1298, 479, 835, 396, 303, +175, -106, -153, -313, -471, -270, -668, -150, +-752, -193, -705, -344, -396, -516, 95, -698, +522, -700, 763, -431, 835, -19, 697, 504, +389, 1045, 46, 1279, -215, 1148, -428, 793, +-537, 228, -472, -432, -333, -997, -218, -1318, +-98, -1236, 5, -874, 73, -446, 150, 54, +203, 536, 263, 801, 380, 889, 367, 915, +238, 842, 147, 581, 31, 150, -147, -317, +-314, -727, -449, -1066, -538, -1151, -470, -875, +-249, -393, -54, 145, 72, 648, 231, 942, +358, 924, 384, 589, 413, 28, 432, -488, +298, -680, 121, -530, 7, -135, -220, 385, +-529, 768, -637, 703, -610, 220, -602, -433, +-434, -1057, -38, -1376, 286, -1166, 431, -555, +562, 258, 698, 1103, 704, 1624, 604, 1597, +432, 1183, 67, 489, -437, -356, -811, -1086, +-987, -1554, -1064, -1626, -962, -1218, -561, -564, +-49, 113, 404, 743, 875, 1134, 1302, 1133, +1426, 907, 1156, 619, 703, 295, 118, -47, +-638, -367, -1325, -593, -1650, -694, -1593, -732, +-1165, -658, -389, -394, 470, -55, 1105, 210, +1439, 441, 1418, 628, 1027, 620, 433, 385, +-81, 137, -458, 2, -720, -50, -754, 25, +-550, 190, -330, 213, -159, -30, -75, -460, +-149, -862, -271, -1040, -235, -886, -29, -373, +330, 377, 793, 1058, 1147, 1425, 1236, 1395, +1010, 984, 383, 321, -455, -387, -1196, -981, +-1702, -1221, -1819, -1045, -1361, -708, -454, -322, +545, 169, 1321, 484, 1675, 439, 1531, 332, +1003, 379, 309, 436, -363, 493, -769, 626, +-737, 623, -488, 242, -296, -355, -203, -910, +-245, -1304, -439, -1392, -598, -1028, -490, -318, +-126, 463, 357, 1096, 853, 1479, 1278, 1523, +1461, 1134, 1194, 385, 499, -405, -380, -983, +-1258, -1268, -1886, -1250, -1939, -934, -1323, -411, +-315, 80, 653, 395, 1290, 645, 1493, 829, +1220, 810, 623, 637, 53, 429, -306, 113, +-529, -271, -558, -585, -374, -820, -200, -938, +-103, -848, -41, -542, -124, -31, -281, 514, +-314, 899, -259, 1112, -120, 1051, 158, 562, +468, -69, 723, -536, 828, -880, 641, -1036, +254, -843, -121, -435, -452, -32, -770, 281, +-860, 505, -656, 663, -437, 720, -282, 594, +36, 338, 416, 25, 606, -338, 652, -697, +643, -874, 516, -713, 274, -305, -5, 84, +-194, 373, -320, 579, -458, 564, -501, 298, +-408, 54, -375, -38, -350, -83, -171, -72, +42, 55, 197, 139, 470, 58, 761, -106, +812, -322, 626, -574, 334, -612, -24, -366, +-417, -11, -707, 398, -743, 811, -597, 967, +-404, 788, -160, 406, 91, -83, 215, -526, +246, -769, 287, -798, 333, -617, 390, -322, +432, -36, 403, 213, 355, 373, 254, 395, +-36, 407, -415, 450, -699, 442, -885, 428, +-958, 390, -791, 133, -327, -316, 282, -759, +804, -1073, 1087, -1141, 1037, -809, 817, -126, +597, 610, 253, 1126, -183, 1301, -474, 1058, +-695, 512, -947, -58, -1065, -483, -969, -740, +-720, -798, -296, -671, 274, -432, 865, -171, +1354, 65, 1574, 245, 1435, 374, 976, 438, +217, 450, -674, 416, -1414, 292, -1831, 67, +-1815, -207, -1326, -481, -483, -663, 449, -645, +1171, -302, 1527, 248, 1495, 633, 1054, 696, +412, 526, -94, 68, -451, -582, -753, -964, +-824, -839, -587, -411, -279, 183, -122, 799, +-133, 1132, -237, 1014, -292, 542, -231, -59, +3, -585, 458, -946, 945, -1066, 1079, -888, +815, -484, 446, -46, 77, 363, -402, 720, +-835, 895, -1006, 836, -984, 644, -847, 331, +-482, -79, 35, -439, 447, -702, 652, -905, +757, -885, 842, -593, 873, -181, 743, 323, +394, 812, -137, 969, -654, 761, -1002, 359, +-1179, -122, -1113, -540, -714, -702, -143, -504, +413, -36, 921, 406, 1239, 653, 1142, 643, +678, 257, 54, -419, -517, -1008, -780, -1275, +-687, -1061, -364, -320, 25, 647, 298, 1485, +357, 1916, 201, 1628, -120, 721, -417, -356, +-554, -1311, -516, -1884, -231, -1790, 259, -1143, +668, -232, 838, 678, 861, 1253, 735, 1373, +343, 1175, -164, 685, -578, 50, -914, -423, +-1127, -625, -1033, -629, -661, -492, -191, -309, +292, -144, 715, -27, 996, -6, 1136, 19, +1072, 159, 742, 258, 239, 274, -346, 296, +-879, 254, -1161, 66, -1176, -121, -996, -165, +-601, -133, -35, -108, 493, -10, 802, 116, +929, 103, 899, -50, 649, -208, 253, -335, +-36, -396, -146, -302, -242, -21, -399, 322, +-518, 559, -586, 626, -599, 562, -511, 332, +-332, -37, -49, -396, 339, -615, 617, -613, +707, -453, 696, -294, 568, -95, 319, 121, +85, 177, -115, 120, -312, 175, -442, 341, +-518, 492, -641, 567, -693, 526, -566, 327, +-375, -53, -170, -591, 168, -1053, 617, -1243, +1041, -1116, 1353, -622, 1411, 157, 1060, 940, +325, 1475, -594, 1546, -1397, 1090, -1845, 325, +-1924, -444, -1640, -1036, -887, -1226, 190, -977, +1198, -560, 1931, -142, 2265, 211, 1982, 354, +1145, 352, 163, 356, -691, 376, -1360, 403, +-1712, 451, -1652, 395, -1342, 162, -878, -169, +-231, -528, 474, -828, 996, -869, 1260, -604, +1363, -160, 1332, 327, 1049, 743, 501, 921, +-141, 752, -721, 313, -1209, -170, -1492, -506, +-1384, -604, -964, -455, -480, -128, 58, 168, +669, 295, 1115, 232, 1237, 32, 1131, -171, +870, -267, 426, -212, -50, 57, -325, 392, +-450, 551, -617, 486, -840, 232, -1025, -217, +-1059, -676, -842, -890, -338, -744, 335, -257, +982, 368, 1443, 851, 1598, 1081, 1388, 959, +831, 443, 33, -273, -755, -853, -1349, -1108, +-1625, -1049, -1492, -672, -1027, -36, -422, 518, +203, 807, 766, 909, 1146, 810, 1258, 514, +1166, 202, 873, -99, 346, -425, -224, -703, +-625, -915, -954, -979, -1200, -725, -1109, -240, +-676, 341, -146, 912, 415, 1263, 907, 1230, +1059, 826, 817, 147, 372, -551, -126, -1041, +-510, -1244, -619, -1075, -443, -511, -91, 147, +304, 650, 558, 895, 510, 762, 153, 330, +-373, -158, -838, -520, -975, -527, -682, -163, +-108, 328, 538, 684, 1017, 695, 1113, 307, +831, -301, 315, -938, -296, -1331, -768, -1147, +-876, -452, -632, 363, -219, 1128, 176, 1603, +408, 1465, 391, 774, 130, -154, -220, -1007, +-437, -1464, -404, -1358, -152, -785, 251, -22, +674, 688, 921, 1058, 878, 930, 477, 471, +-212, -63, -847, -527, -1156, -718, -1125, -513, +-793, -86, -243, 311, 330, 596, 737, 649, +922, 412, 929, 5, 752, -395, 341, -674, +-125, -760, -392, -610, -499, -266, -586, 111, +-553, 467, -385, 714, -240, 751, -129, 645, +42, 486, 256, 210, 461, -162, 578, -502, +505, -802, 243, -1077, -31, -1084, -215, -697, +-324, -46, -301, 721, -144, 1406, 13, 1688, +106, 1389, 35, 623, -189, -332, -330, -1209, +-292, -1723, -188, -1666, 21, -999, 360, -11, +560, 889, 486, 1459, 347, 1514, 174, 960, +-146, 48, -454, -811, -506, -1264, -339, -1137, +-112, -482, 134, 374, 333, 1046, 244, 1250, +-145, 864, -499, 25, -633, -862, -514, -1403, +-67, -1381, 581, -835, 1129, 55, 1371, 978, +1174, 1569, 523, 1607, -394, 1107, -1346, 213, +-2018, -770, -2005, -1439, -1280, -1605, -217, -1303, +864, -562, 1710, 319, 2042, 946, 1785, 1220, +1085, 1144, 169, 732, -705, 184, -1287, -304, +-1490, -613, -1382, -721, -995, -691, -414, -550, +118, -270, 506, 51, 818, 326, 1012, 549, +1011, 653, 857, 547, 563, 235, 124, -178, +-358, -479, -752, -617, -1018, -603, -1120, -348, +-923, 99, -398, 491, 238, 679, 730, 632, +976, 368, 939, -77, 619, -570, 179, -886, +-178, -816, -383, -416, -457, 110, -427, 625, +-287, 912, -74, 784, 80, 421, 105, 20, +36, -379, -79, -637, -82, -575, 87, -351, +259, -166, 314, 20, 238, 169, 20, 157, +-222, 56, -328, -2, -261, 66, -78, 255, +153, 506, 314, 646, 360, 497, 286, 59, +30, -542, -350, -1090, -636, -1290, -709, -1031, +-496, -360, 1, 529, 566, 1292, 932, 1584, +977, 1318, 672, 667, 74, -157, -565, -949, +-929, -1377, -997, -1267, -820, -798, -313, -228, +384, 365, 858, 816, 944, 924, 760, 726, +328, 405, -296, 123, -764, -96, -809, -332, +-574, -459, -256, -414, 139, -388, 533, -405, +702, -241, 594, 89, 338, 384, -12, 576, +-376, 659, -596, 545, -589, 211, -375, -266, +-140, -655, -24, -770, 104, -646, 311, -342, +443, 169, 504, 680, 532, 845, 384, 654, +41, 322, -316, -157, -612, -657, -799, -843, +-745, -645, -476, -268, -87, 175, 402, 615, +822, 828, 942, 635, 729, 219, 296, -221, +-215, -623, -613, -827, -741, -640, -577, -182, +-238, 259, 118, 542, 398, 655, 502, 577, +391, 349, 107, 18, -258, -323, -543, -560, +-543, -660, -222, -659, 211, -447, 528, -21, +649, 391, 510, 687, 119, 848, -270, 710, +-396, 354, -328, -11, -221, -371, -104, -651, +-26, -728, -61, -669, -166, -496, -292, -181, +-287, 163, 7, 429, 457, 637, 851, 730, +1077, 670, 939, 471, 364, 159, -462, -198, +-1230, -521, -1633, -786, -1491, -896, -863, -766, +52, -402, 962, 51, 1531, 499, 1567, 839, +1122, 901, 384, 664, -397, 318, -898, -11, +-972, -270, -725, -373, -344, -314, -10, -296, +131, -391, 18, -468, -191, -457, -241, -338, +-84, -33, 217, 414, 620, 815, 991, 1009, +1049, 957, 641, 585, -60, -45, -751, -674, +-1272, -1103, -1433, -1241, -1030, -950, -239, -270, +481, 476, 868, 992, 918, 1147, 665, 845, +241, 224, -87, -482, -148, -995, 12, -946, +204, -384, 260, 254, 78, 815, -331, 1127, +-778, 864, -1049, 122, -1009, -642, -552, -1161, +215, -1259, 956, -858, 1422, -144, 1461, 571, +997, 1021, 202, 1077, -616, 821, -1187, 338, +-1316, -185, -976, -458, -384, -421, 187, -253, +565, -111, 640, -106, 427, -275, 112, -547, +-85, -752, -101, -669, 31, -137, 242, 683, +409, 1410, 365, 1760, 106, 1552, -230, 749, +-556, -390, -792, -1519, -760, -2241, -404, -2206, +92, -1419, 495, -217, 711, 1035, 687, 1921, +401, 2109, 32, 1597, -132, 607, -73, -494, +30, -1202, 44, -1318, -44, -980, -232, -375, +-521, 246, -744, 509, -665, 317, -308, -66, +167, -359, 659, -444, 1037, -222, 1106, 279, +801, 814, 257, 1052, -317, 859, -797, 361, +-1097, -278, -1072, -939, -667, -1321, -118, -1172, +318, -611, 644, 72, 836, 691, 733, 1027, +361, 949, -29, 553, -247, 48, -316, -353, +-293, -486, -212, -372, -114, -163, -15, 7, +12, 117, -82, 146, -175, 54, -132, -139, +8, -272, 127, -243, 197, -159, 275, -69, +309, 146, 199, 373, 13, 450, -114, 429, +-172, 318, -232, 84, -271, -127, -244, -312, +-161, -528, -8, -606, 152, -486, 230, -281, +227, 17, 157, 338, 42, 598, -66, 752, +-135, 650, -127, 310, -22, -72, 89, -430, +175, -665, 221, -636, 127, -362, -124, -9, +-373, 252, -480, 306, -418, 221, -184, 55, +184, -149, 526, -170, 680, 55, 590, 282, +295, 444, -132, 504, -509, 295, -693, -143, +-670, -574, -434, -884, 26, -936, 522, -579, +784, 58, 709, 664, 365, 1060, -143, 1123, +-646, 787, -894, 129, -723, -559, -252, -940, +309, -964, 783, -750, 967, -279, 747, 294, +267, 638, -291, 637, -777, 424, -960, 138, +-737, -116, -281, -229, 169, -118, 479, 105, +569, 219, 432, 123, 173, -136, -27, -493, +-47, -747, 20, -685, 96, -278, 185, 356, +138, 983, -156, 1315, -523, 1167, -756, 491, +-793, -469, -583, -1306, -84, -1671, 598, -1407, +1182, -597, 1397, 458, 1147, 1367, 493, 1706, +-369, 1336, -1145, 501, -1557, -449, -1453, -1223, +-865, -1468, -24, -1060, 742, -268, 1206, 541, +1255, 1090, 888, 1141, 274, 686, -338, -55, +-737, -775, -786, -1138, -495, -948, -76, -349, +219, 409, 310, 1068, 238, 1285, -11, 892, +-312, 127, -420, -704, -306, -1295, -49, -1364, +330, -848, 698, 12, 815, 827, 587, 1287, +95, 1287, -505, 806, -954, 15, -1052, -734, +-766, -1151, -202, -1132, 425, -714, 855, -82, +954, 551, 729, 963, 287, 985, -248, 680, +-702, 227, -832, -295, -580, -716, -166, -844, +222, -698, 512, -417, 609, -53, 421, 341, +71, 638, -220, 735, -387, 659, -489, 460, +-453, 159, -173, -225, 213, -609, 453, -865, +493, -855, 401, -594, 169, -158, -138, 370, +-343, 797, -369, 914, -321, 728, -272, 385, +-129, -19, 90, -409, 226, -579, 294, -476, +378, -302, 329, -167, 71, -11, -165, 79, +-259, -1, -338, -123, -407, -68, -294, 133, +-31, 343, 165, 539, 310, 651, 469, 495, +468, 96, 234, -340, -63, -694, -333, -912, +-537, -859, -564, -524, -402, -79, -137, 342, +160, 703, 408, 904, 561, 831, 583, 542, +425, 207, 137, -152, -191, -490, -523, -694, +-716, -728, -670, -634, -450, -448, -104, -193, +324, 121, 633, 451, 677, 736, 531, 863, +295, 785, -18, 478, -306, -25, -421, -572, +-407, -950, -394, -1011, -322, -708, -114, -183, +75, 314, 146, 634, 249, 721, 368, 533, +326, 219, 189, -32, 115, -220, 53, -343, +-116, -323, -316, -199, -376, -70, -320, 21, +-253, 111, -147, 176, 60, 136, 271, 28, +352, -22, 292, -15, 197, -19, 104, -55, +-24, -105, -118, -162, -104, -152, -66, -29, +-87, 140, -166, 297, -285, 398, -347, 354, +-232, 150, 15, -165, 296, -476, 528, -639, +624, -579, 518, -347, 202, 18, -218, 438, +-568, 730, -766, 773, -751, 573, -426, 170, +108, -281, 555, -610, 731, -726, 632, -607, +319, -307, -79, 42, -331, 331, -341, 458, +-238, 422, -150, 306, -82, 157, -21, -14, +1, -141, -47, -204, -94, -219, -16, -195, +157, -125, 284, -37, 357, 45, 356, 100, +140, 115, -259, 86, -564, 39, -635, -11, +-486, -26, -147, -9, 264, 11, 578, 58, +678, 117, 532, 90, 193, -28, -265, -138, +-679, -183, -812, -188, -589, -134, -125, 29, +423, 246, 791, 335, 758, 227, 370, 20, +-134, -209, -546, -406, -709, -409, -562, -171, +-177, 175, 258, 496, 517, 669, 490, 528, +263, 91, -36, -427, -297, -824, -409, -950, +-317, -698, -112, -169, 117, 461, 313, 986, +388, 1167, 275, 930, 58, 409, -177, -260, +-434, -870, -587, -1175, -450, -1099, -87, -722, +267, -124, 482, 490, 568, 894, 488, 1025, +251, 878, -25, 502, -253, 36, -451, -407, +-588, -714, -613, -822, -503, -727, -195, -475, +292, -87, 720, 339, 885, 641, 781, 749, +444, 636, -57, 289, -540, -125, -855, -463, +-913, -649, -685, -567, -242, -218, 290, 208, +761, 525, 979, 619, 796, 446, 249, 20, +-401, -509, -848, -879, -929, -874, -607, -487, +10, 153, 628, 842, 952, 1281, 845, 1246, +366, 737, -274, -90, -795, -928, -1006, -1460, +-852, -1492, -398, -985, 177, -140, 656, 703, +913, 1274, 897, 1409, 579, 1066, 77, 379, +-366, -373, -636, -900, -736, -1033, -619, -807, +-306, -350, -13, 196, 152, 599, 243, 649, +262, 376, 225, -16, 233, -354, 260, -534, +221, -435, 155, -65, 70, 370, -128, 671, +-355, 753, -441, 549, -408, 89, -364, -430, +-265, -815, -82, -983, 107, -850, 250, -432, +407, 119, 531, 620, 515, 947, 406, 1023, +213, 844, -129, 434, -498, -102, -725, -608, +-801, -962, -733, -1046, -440, -810, 47, -369, +553, 157, 885, 628, 940, 869, 670, 813, +153, 540, -370, 166, -666, -192, -683, -464, +-460, -558, -56, -433, 325, -216, 398, -23, +180, 158, -116, 225, -376, 114, -526, -9, +-416, -23, -31, -13, 454, 48, 808, 187, +861, 271, 587, 195, 109, -15, -437, -257, +-886, -406, -1036, -410, -802, -260, -300, 22, +250, 348, 637, 533, 757, 485, 582, 261, +184, -73, -211, -407, -374, -583, -300, -555, +-77, -350, 243, -11, 467, 383, 343, 667, +-65, 712, -478, 527, -749, 180, -793, -240, +-497, -585, 37, -733, 529, -645, 796, -370, +825, -38, 591, 216, 170, 396, -199, 503, +-394, 490, -467, 407, -423, 307, -261, 144, +-95, -71, -41, -319, -101, -588, -192, -769, +-190, -729, -20, -462, 255, -32, 500, 448, +665, 823, 687, 964, 463, 810, 44, 403, +-379, -55, -734, -422, -967, -692, -929, -793, +-596, -658, -147, -393, 317, -96, 711, 196, +848, 449, 702, 569, 477, 536, 255, 436, +-11, 300, -274, 69, -448, -219, -559, -421, +-625, -491, -569, -484, -362, -374, -96, -149, +169, 128, 427, 334, 609, 394, 594, 371, +407, 295, 155, 108, -94, -118, -302, -249, +-388, -241, -332, -144, -207, -12, -117, 103, +-102, 136, -132, 31, -148, -142, -106, -247, +9, -240, 158, -133, 300, 66, 409, 297, +446, 466, 330, 481, 76, 307, -235, 2, +-531, -325, -704, -586, -611, -664, -257, -485, +161, -128, 438, 240, 514, 518, 408, 638, +143, 574, -156, 328, -305, -25, -292, -338, +-192, -523, -22, -588, 184, -485, 319, -213, +302, 105, 125, 362, -139, 528, -360, 539, +-434, 370, -346, 110, -134, -135, 93, -352, +212, -499, 226, -478, 214, -276, 178, -41, +102, 139, 31, 294, 11, 400, 14, 376, +-3, 224, -42, 27, -114, -130, -249, -221, +-370, -233, -371, -170, -266, -82, -94, -40, +139, -43, 335, -77, 429, -103, 502, -39, +566, 115, 439, 271, 104, 398, -273, 446, +-595, 345, -824, 97, -883, -234, -736, -592, +-405, -847, 55, -838, 562, -517, 994, 36, +1199, 667, 1069, 1114, 628, 1189, -27, 866, +-713, 239, -1192, -479, -1334, -1005, -1146, -1188, +-649, -1024, 43, -569, 710, 53, 1130, 598, +1189, 916, 910, 988, 381, 803, -245, 412, +-723, -67, -930, -525, -870, -817, -551, -851, +-70, -644, 334, -262, 547, 198, 579, 545, +388, 666, 23, 590, -265, 343, -341, 13, +-301, -245, -203, -381, -34, -410, 88, -327, +85, -142, 79, 79, 153, 236, 171, 268, +115, 215, 87, 113, 40, -25, -120, -133, +-320, -152, -486, -150, -572, -149, -478, -95, +-158, 30, 313, 165, 773, 251, 1028, 279, +947, 228, 493, 47, -195, -197, -822, -350, +-1176, -377, -1219, -331, -898, -179, -249, 73, +465, 314, 982, 457, 1167, 458, 958, 289, +456, 27, -105, -227, -550, -417, -783, -480, +-726, -366, -420, -123, -56, 143, 174, 356, +247, 480, 209, 446, 78, 204, -79, -158, +-116, -453, 8, -578, 197, -491, 328, -180, +305, 234, 125, 547, -89, 659, -267, 571, +-399, 303, -409, -90, -279, -474, -136, -719, +7, -775, 191, -628, 326, -259, 309, 244, +211, 673, 126, 893, 51, 879, -33, 600, +-88, 123, -118, -355, -182, -697, -295, -864, +-344, -785, -250, -485, -56, -118, 163, 230, +348, 525, 389, 687, 287, 677, 103, 498, +-119, 208, -294, -105, -314, -363, -201, -505, +-69, -474, 35, -316, 146, -154, 197, -51, +89, 12, -100, 51, -195, 111, -224, 230, +-227, 366, -79, 418, 187, 325, 341, 115, +333, -121, 218, -323, 0, -456, -254, -456, +-421, -303, -434, -100, -266, 88, 0, 263, +205, 365, 289, 333, 298, 217, 189, 61, +-37, -118, -243, -260, -318, -286, -266, -196, +-100, -33, 146, 158, 344, 312, 354, 346, +185, 208, -100, -82, -404, -396, -550, -585, +-439, -569, -165, -345, 168, 77, 443, 566, +541, 868, 438, 854, 183, 571, -158, 89, +-478, -446, -644, -833, -551, -935, -227, -744, +203, -359, 595, 56, 749, 398, 502, 642, +-6, 743, -462, 662, -716, 418, -730, 71, +-448, -274, 35, -512, 475, -607, 718, -553, +750, -338, 546, -63, 97, 116, -439, 179, +-799, 220, -857, 277, -643, 340, -203, 390, +331, 358, 687, 190, 730, -84, 521, -392, +165, -626, -233, -670, -508, -482, -557, -122, +-366, 279, -25, 547, 279, 608, 433, 501, +411, 272, 148, -2, -261, -209, -548, -347, +-588, -416, -435, -370, -93, -236, 349, -91, +679, 94, 767, 295, 615, 408, 249, 380, +-254, 246, -716, 51, -936, -177, -829, -384, +-461, -448, 35, -340, 499, -146, 740, 116, +700, 398, 436, 516, 66, 403, -239, 168, +-381, -116, -416, -392, -333, -535, -133, -468, +68, -219, 187, 99, 191, 384, 45, 557, +-162, 505, -294, 198, -313, -174, -200, -424, +61, -501, 346, -363, 507, -24, 485, 310, +314, 448, 50, 348, -266, 66, -582, -270, +-762, -482, -682, -455, -355, -190, 66, 195, +415, 546, 585, 700, 556, 545, 394, 126, +194, -375, -27, -779, -246, -909, -356, -665, +-325, -154, -245, 410, -167, 855, -95, 993, +-76, 743, -119, 214, -119, -384, 12, -807, +252, -887, 463, -660, 500, -219, 313, 302, +15, 666, -239, 701, -423, 475, -547, 132, +-501, -204, -274, -421, -19, -472, 219, -340, +459, -78, 542, 141, 358, 242, 32, 287, +-241, 248, -401, 84, -443, -57, -343, -94, +-74, -110, 251, -130, 455, -119, 466, -120, +316, -125, 27, -81, -323, 19, -557, 165, +-552, 319, -357, 375, -101, 287, 111, 84, +288, -183, 429, -420, 489, -510, 452, -429, +324, -179, 60, 182, -290, 478, -560, 548, +-692, 380, -729, 49, -558, -303, -137, -492, +319, -405, 665, -78, 904, 321, 900, 558, +560, 506, 21, 181, -498, -294, -863, -692, +-995, -811, -856, -614, -439, -158, 119, 409, +619, 859, 912, 1022, 925, 846, 629, 378, +102, -216, -475, -760, -845, -1085, -855, -1044, +-602, -668, -221, -139, 250, 427, 594, 871, +625, 1012, 445, 833, 175, 434, -165, -70, +-397, -505, -351, -734, -161, -725, -35, -504, +-8, -178, -72, 117, -184, 327, -246, 401, +-156, 328, 90, 214, 364, 128, 518, 48, +542, -14, 419, -61, 96, -132, -354, -201, +-779, -239, -1034, -238, -948, -150, -490, 11, +160, 158, 750, 237, 1094, 241, 1089, 178, +758, 87, 219, -4, -351, -72, -780, -100, +-966, -126, -924, -181, -666, -210, -239, -173, +237, -84, 591, 40, 708, 211, 646, 379, +507, 442, 259, 330, -59, 74, -275, -225, +-395, -468, -535, -596, -581, -530, -420, -252, +-168, 110, 62, 416, 308, 607, 522, 611, +564, 429, 411, 166, 156, -132, -149, -429, +-422, -608, -509, -636, -379, -505, -180, -189, +37, 198, 243, 504, 325, 697, 247, 705, +123, 451, -10, 37, -175, -361, -301, -619, +-264, -641, -106, -451, 57, -154, 185, 154, +243, 370, 170, 419, 38, 330, -46, 159, +-82, -12, -102, -121, -92, -174, -88, -179, +-112, -117, -119, -28, -83, 40, -24, 78, +44, 78, 98, 33, 138, -26, 164, -71, +164, -78, 129, -61, 24, -14, -139, 76, +-262, 156, -320, 163, -313, 122, -198, 29, +-6, -114, 151, -210, 263, -198, 327, -131, +277, -46, 126, 39, -46, 102, -219, 137, +-321, 147, -282, 124, -146, 74, -8, 6, +89, -63, 111, -131, 81, -175, 32, -158, +-30, -74, -65, 10, -42, 57, -4, 99, +45, 149, 90, 149, 55, 96, -23, 38, +-58, -22, -100, -90, -146, -137, -124, -178, +-56, -208, -14, -163, 2, -40, 24, 101, +86, 253, 148, 379, 136, 394, 62, 246, +-23, -29, -103, -334, -159, -547, -180, -591, +-153, -442, -70, -114, 24, 293, 85, 616, +158, 740, 188, 594, 91, 222, -53, -208, +-125, -538, -136, -684, -101, -591, -29, -300, +46, 68, 85, 371, 49, 505, -31, 447, +-56, 248, -58, -15, -90, -216, -90, -262, +2, -178, 117, -34, 181, 91, 172, 99, +103, 20, -22, -60, -171, -113, -279, -100, +-282, -13, -183, 43, -33, 18, 126, -16, +259, -1, 313, 61, 263, 164, 106, 268, +-80, 307, -189, 207, -202, -48, -198, -357, +-175, -576, -107, -626, -40, -463, -20, -106, +11, 331, 100, 663, 201, 757, 262, 601, +290, 292, 255, -73, 97, -365, -168, -480, +-432, -457, -609, -398, -582, -312, -304, -200, +83, -58, 397, 138, 583, 360, 594, 544, +408, 628, 119, 512, -161, 198, -406, -174, +-524, -472, -453, -601, -293, -504, -115, -265, +120, -15, 318, 142, 336, 128, 235, 17, +130, -12, -13, 68, -157, 223, -175, 446, +-88, 582, -8, 450, 56, 99, 83, -331, +22, -715, -93, -908, -178, -799, -226, -400, +-245, 149, -194, 605, -11, 809, 271, 766, +532, 522, 645, 136, 488, -208, 54, -377, +-461, -423, -832, -419, -927, -342, -645, -204, +-56, -55, 501, 101, 807, 256, 843, 344, +601, 300, 145, 126, -316, -71, -641, -180, +-757, -155, -604, -30, -224, 139, 205, 252, +501, 209, 576, -27, 434, -341, 135, -519, +-152, -450, -263, -215, -251, 134, -251, 502, +-180, 659, 2, 497, 109, 182, 91, -155, +112, -443, 137, -574, 30, -440, -79, -107, +-37, 206, 49, 353, 66, 383, 86, 293, +122, 36, 43, -224, -166, -300, -335, -250, +-353, -159, -280, -53, -103, 31, 227, 105, +531, 204, 601, 299, 455, 372, 167, 342, +-190, 118, -477, -225, -591, -551, -523, -755, +-325, -689, -81, -321, 174, 189, 397, 648, +512, 890, 489, 808, 349, 473, 98, 35, +-199, -381, -422, -656, -475, -708, -338, -581, +-121, -346, 33, -57, 132, 235, 153, 465, +60, 579, -2, 559, 67, 407, 134, 136, +160, -183, 187, -430, 135, -519, -15, -454, +-137, -282, -228, -42, -342, 184, -398, 280, +-274, 233, -30, 121, 194, 45, 373, 76, +508, 183, 437, 268, 147, 242, -148, 6, +-316, -391, -371, -695, -313, -713, -196, -438, +-67, 63, 55, 580, 125, 849, 149, 765, +206, 400, 236, -48, 150, -352, -13, -492, +-145, -526, -227, -419, -229, -224, -111, -71, +72, 72, 166, 251, 137, 393, 61, 432, +-36, 355, -118, 185, -108, -6, -50, -188, +6, -345, 83, -421, 165, -390, 188, -272, +160, -66, 43, 161, -178, 333, -385, 413, +-442, 365, -281, 200, 83, 16, 463, -112, +641, -164, 537, -180, 181, -215, -258, -259, +-533, -254, -583, -179, -460, -3, -182, 253, +156, 459, 402, 491, 540, 330, 539, 31, +330, -258, -7, -408, -340, -392, -564, -255, +-545, -65, -281, 73, 44, 115, 296, 135, +431, 196, 397, 243, 212, 217, -32, 119, +-228, -25, -300, -212, -246, -369, -90, -369, +127, -185, 272, 57, 248, 247, 114, 339, +-74, 294, -242, 112, -269, -92, -151, -199, +16, -176, 167, -70, 235, 46, 179, 99, +62, 54, -41, -64, -103, -152, -112, -126, +-62, -12, 34, 117, 101, 220, 50, 226, +-68, 94, -134, -81, -136, -179, -85, -201, +57, -150, 218, -24, 260, 110, 159, 162, +9, 115, -112, 10, -160, -77, -138, -122, +-79, -120, -25, -38, 18, 106, 58, 196, +102, 175, 124, 76, 81, -63, -51, -206, +-161, -284, -147, -250, -15, -105, 151, 100, +277, 286, 252, 368, 66, 304, -159, 106, +-294, -130, -323, -307, -244, -363, -49, -277, +208, -81, 374, 117, 374, 233, 225, 237, +-13, 142, -258, 8, -365, -81, -277, -89, +-35, -31, 249, 45, 406, 105, 306, 103, +57, 6, -199, -154, -399, -282, -465, -319, +-300, -247, 8, -66, 306, 202, 521, 450, +626, 559, 541, 498, 243, 284, -192, -82, +-580, -475, -794, -702, -772, -702, -483, -496, +4, -128, 480, 267, 798, 567, 873, 692, +675, 580, 297, 308, -108, 27, -479, -235, +-703, -415, -671, -427, -443, -336, -163, -204, +104, -20, 288, 91, 361, 45, 348, -15, +303, 23, 313, 122, 339, 278, 229, 445, +-1, 483, -263, 309, -535, -34, -715, -440, +-671, -733, -398, -770, 47, -529, 523, -110, +824, 338, 894, 631, 721, 663, 261, 500, +-285, 268, -631, 3, -759, -221, -677, -320, +-358, -343, 29, -367, 307, -347, 472, -226, +489, 8, 340, 274, 135, 455, -53, 483, +-172, 339, -156, 38, -74, -263, -31, -410, +-43, -375, -93, -180, -149, 97, -129, 296, +1, 320, 195, 170, 341, -44, 313, -206, +122, -288, -115, -254, -308, -84, -353, 74, +-200, 164, 71, 266, 340, 333, 478, 295, +373, 159, 72, -114, -284, -441, -549, -631, +-549, -599, -265, -293, 138, 249, 479, 712, +603, 848, 434, 650, 120, 168, -177, -393, +-362, -710, -334, -716, -171, -475, -61, -59, +61, 325, 237, 511, 297, 499, 197, 268, +30, -74, -164, -317, -290, -419, -289, -334, +-139, -5, 145, 366, 418, 572, 497, 537, +417, 204, 209, -314, -122, -754, -438, -959, +-628, -798, -672, -235, -467, 480, -35, 1028, +479, 1223, 905, 976, 1042, 412, 728, -240, +118, -804, -479, -1124, -818, -1090, -859, -764, +-652, -269, -262, 283, 163, 765, 459, 1031, +651, 965, 711, 574, 553, 72, 221, -313, +-182, -515, -555, -546, -651, -437, -452, -310, +-166, -259, 137, -217, 398, -68, 443, 175, +310, 430, 125, 587, -68, 561, -234, 368, +-310, 82, -215, -244, 76, -448, 329, -425, +352, -311, 196, -200, -71, -43, -327, 59, +-335, 72, -109, 121, 150, 187, 301, 238, +244, 304, 23, 218, -151, -36, -168, -239, +-57, -344, 85, -332, 145, -104, 143, 165, +125, 316, 48, 350, -52, 173, -131, -157, +-190, -360, -147, -389, 2, -274, 151, -30, +262, 220, 275, 405, 122, 458, -78, 264, +-214, -9, -252, -159, -160, -255, -11, -290, +113, -202, 265, -117, 364, -30, 266, 102, +61, 191, -120, 233, -274, 217, -326, 48, +-245, -186, -92, -346, 74, -350, 184, -108, +202, 272, 219, 525, 265, 574, 261, 377, +169, -55, 41, -496, -103, -744, -285, -724, +-447, -418, -431, -19, -220, 336, 57, 636, +330, 746, 529, 619, 512, 372, 297, -8, +35, -421, -185, -670, -283, -756, -221, -657, +-91, -271, 24, 237, 105, 622, 100, 739, +37, 545, -17, 213, -92, -83, -177, -385, +-157, -581, -17, -481, 207, -179, 442, 119, +525, 365, 408, 525, 202, 489, -118, 190, +-479, -249, -650, -607, -581, -696, -359, -455, +-12, 14, 293, 470, 458, 718, 526, 654, +467, 278, 307, -217, 214, -560, 124, -609, +-39, -347, -225, 48, -428, 351, -599, 467, +-567, 341, -376, -24, -40, -369, 418, -460, +747, -307, 796, -39, 674, 216, 339, 389, +-145, 447, -515, 280, -653, -36, -580, -232, +-278, -288, 105, -293, 391, -159, 434, 47, +258, 138, 50, 89, -88, -56, -215, -208, +-188, -169, 35, 71, 241, 365, 319, 563, +296, 520, 138, 187, -85, -293, -268, -735, +-343, -905, -241, -667, -9, -148, 166, 442, +207, 929, 131, 1100, 29, 829, -20, 171, +-37, -642, -10, -1253, 112, -1359, 240, -917, +304, -36, 315, 993, 212, 1682, -51, 1652, +-430, 897, -766, -307, -768, -1465, -349, -2046, +232, -1765, 775, -712, 1100, 711, 964, 1861, +404, 2183, -270, 1544, -779, 257, -894, -1086, +-617, -1894, -152, -1885, 316, -1094, 607, 143, +582, 1240, 327, 1701, -34, 1419, -371, 599, +-461, -379, -238, -1131, 102, -1412, 417, -1112, +617, -320, 525, 548, 83, 1112, -432, 1209, +-731, 798, -704, 26, -348, -742, 249, -1181, +765, -1042, 914, -330, 666, 562, 170, 1185, +-385, 1250, -795, 606, -858, -447, -491, -1320, +55, -1611, 491, -1147, 819, -37, 932, 1158, +581, 1863, -1, 1791, -468, 946, -794, -325, +-817, -1475, -412, -2034, 99, -1729, 435, -713, +583, 494, 509, 1410, 288, 1736, 48, 1332, +-151, 418, -194, -563, -78, -1175, 10, -1176, +64, -673, 90, 41, -19, 707, -223, 1008, +-362, 746, -352, 65, -102, -679, 302, -1130, +650, -1026, 772, -369, 613, 565, 209, 1316, +-295, 1461, -729, 914, -849, -51, -599, -1027, +-147, -1542, 337, -1343, 726, -578, 798, 416, +520, 1222, 59, 1426, -350, 967, -549, 116, +-462, -779, -154, -1313, 265, -1211, 536, -576, +497, 322, 198, 1122, -213, 1420, -541, 1084, +-552, 315, -253, -618, 216, -1336, 625, -1458, +730, -942, 502, -50, 111, 871, -338, 1386, +-648, 1202, -671, 444, -441, -476, -54, -1095, +391, -1062, 729, -424, 846, 430, 643, 1061, +173, 1131, -327, 532, -689, -390, -811, -1139, +-560, -1437, -125, -1149, 209, -314, 445, 680, +596, 1393, 590, 1592, 473, 1232, 237, 454, +-101, -417, -347, -1106, -427, -1427, -406, -1292, +-287, -783, -142, -91, -64, 614, 44, 1081, +255, 1140, 497, 828, 670, 275, 637, -300, +310, -610, -164, -577, -581, -289, -794, 69, +-715, 219, -368, 44, 110, -275, 603, -544, +912, -577, 848, -254, 440, 308, -123, 887, +-640, 1237, -844, 1086, -637, 455, -186, -391, +289, -1190, 608, -1584, 653, -1313, 523, -573, +293, 325, -62, 1118, -420, 1469, -595, 1254, +-522, 641, -178, -167, 229, -844, 420, -1154, +396, -1113, 237, -701, 15, 12, -71, 632, +-6, 941, 80, 960, 136, 641, 100, 80, +-12, -443, -80, -787, -156, -838, -271, -574, +-321, -155, -242, 298, 75, 661, 539, 725, +735, 486, 578, 113, 278, -230, -152, -408, +-526, -399, -570, -278, -381, -92, -126, 38, +139, 48, 305, 78, 402, 158, 398, 142, +198, 73, -76, 50, -281, 39, -362, 12, +-162, 18, 177, 34, 393, 16, 454, -69, +292, -199, -76, -266, -322, -184, -428, -49, +-456, 80, -235, 234, 167, 318, 487, 246, +692, 143, 616, 23, 225, -150, -235, -223, +-554, -161, -606, -134, -334, -101, 16, -37, +290, -28, 446, -12, 425, 48, 296, 88, +181, 191, -8, 294, -240, 226, -396, 110, +-400, 37, -245, -149, 46, -396, 320, -561, +436, -568, 368, -297, 289, 179, 231, 597, +68, 868, -146, 885, -285, 511, -393, -117, +-394, -713, -259, -1064, -73, -1023, 181, -627, +442, -17, 534, 641, 503, 1081, 353, 1101, +85, 732, -136, 80, -287, -587, -382, -958, +-316, -937, -244, -577, -244, -46, -92, 368, +159, 560, 372, 556, 593, 347, 626, 46, +350, -150, 25, -215, -224, -175, -358, -51, +-311, 83, -210, 140, -156, 42, -135, -194, +-138, -393, 7, -448, 283, -295, 441, 104, +479, 574, 440, 844, 224, 801, -33, 404, +-226, -254, -382, -879, -406, -1168, -301, -958, +-186, -313, 20, 416, 258, 951, 386, 1153, +418, 866, 349, 183, 192, -481, 43, -854, +-155, -879, -307, -601, -254, -166, -145, 291, +-70, 677, 56, 788, 143, 547, 172, 146, +215, -258, 209, -620, 149, -768, 63, -553, +-71, -70, -140, 457, -120, 814, -122, 753, +-102, 261, -7, -331, 124, -746, 284, -863, +407, -497, 423, 231, 261, 850, -189, 1037, +-676, 694, -766, -107, -474, -867, -9, -1156, +538, -984, 935, -339, 977, 641, 640, 1311, +23, 1296, -601, 737, -933, -161, -922, -1011, +-561, -1358, 27, -1139, 582, -438, 921, 509, +906, 1169, 447, 1262, -135, 865, -489, 51, +-547, -808, -342, -1223, 32, -1102, 321, -528, +408, 360, 275, 1130, -41, 1381, -383, 998, +-506, 95, -378, -925, -84, -1550, 337, -1504, +826, -766, 1054, 389, 790, 1445, 160, 1882, +-575, 1447, -1158, 359, -1256, -871, -827, -1774, +-90, -1875, 675, -1054, 1187, 205, 1244, 1297, +850, 1771, 119, 1352, -588, 306, -888, -818, +-741, -1562, -330, -1471, 178, -555, 503, 551, +466, 1404, 166, 1670, -179, 1039, -372, -135, +-281, -1227, 17, -1893, 354, -1720, 600, -698, +632, 577, 394, 1644, -36, 2112, -516, 1587, +-843, 385, -776, -848, -303, -1716, 286, -1845, +731, -1147, 901, -39, 647, 1024, 76, 1558, +-402, 1289, -613, 450, -580, -577, -225, -1344, +258, -1350, 550, -644, 660, 342, 577, 1265, +175, 1707, -305, 1340, -629, 299, -814, -964, +-744, -1842, -306, -1967, 359, -1422, 1021, -339, +1286, 1029, 993, 2019, 440, 2144, -203, 1479, +-889, 374, -1206, -793, -967, -1637, -490, -1806, +18, -1263, 525, -433, 867, 327, 955, 907, +806, 1106, 445, 892, -48, 546, -517, 158, +-771, -236, -722, -497, -491, -608, -135, -567, +316, -407, 618, -254, 652, -15, 568, 347, +355, 636, -39, 810, -411, 815, -591, 415, +-557, -270, -279, -983, 167, -1524, 574, -1466, +721, -692, 530, 381, 147, 1433, -248, 2092, +-495, 1908, -456, 950, -235, -352, -24, -1553, +244, -2168, 467, -1995, 385, -1152, 156, 79, +-16, 1148, -233, 1611, -319, 1500, -99, 967, +198, 239, 418, -327, 511, -581, 284, -577, +-128, -439, -448, -364, -629, -386, -607, -452, +-302, -520, 164, -400, 702, 39, 1085, 643, +1045, 1203, 581, 1458, -142, 1193, -892, 425, +-1250, -642, -1061, -1589, -466, -1899, 360, -1465, +1054, -546, 1201, 572, 848, 1419, 225, 1565, +-427, 1092, -826, 321, -804, -472, -415, -984, +205, -957, 766, -471, 973, 136, 673, 604, +8, 735, -699, 368, -1132, -304, -1063, -865, +-376, -1045, 582, -672, 1286, 223, 1464, 1135, +1033, 1582, 165, 1401, -626, 538, -1117, -699, +-1282, -1692, -927, -2045, -174, -1567, 540, -377, +1027, 947, 1141, 1873, 793, 2123, 189, 1498, +-415, 227, -763, -1065, -580, -1834, -44, -1781, +396, -1019, 570, 31, 399, 1006, -136, 1467, +-715, 1108, -979, 270, -743, -508, 47, -967, +1082, -887, 1782, -252, 1769, 526, 983, 999, +-347, 936, -1639, 340, -2284, -509, -2012, -1187, +-918, -1317, 554, -854, 1741, -49, 2293, 822, +2152, 1432, 1236, 1452, -241, 871, -1573, -80, +-2204, -1021, -1950, -1512, -864, -1414, 561, -788, +1607, 292, 1888, 1317, 1313, 1662, 185, 1241, +-789, 257, -1148, -919, -962, -1672, -413, -1686, +237, -1000, 706, 211, 940, 1376, 883, 1904, +346, 1700, -441, 825, -938, -423, -939, -1410, +-549, -1819, 104, -1633, 730, -837, 969, 219, +759, 1010, 294, 1395, -201, 1355, -497, 821, +-516, 40, -371, -603, -79, -913, 318, -856, +586, -488, 535, 42, 130, 456, -424, 522, +-668, 223, -431, -252, 23, -594, 493, -613, +777, -287, 606, 304, 193, 883, -117, 1101, +-345, 886, -465, 322, -364, -500, -195, -1192, +22, -1341, 352, -993, 562, -322, 456, 461, +144, 998, -258, 1085, -493, 713, -348, 51, +10, -477, 337, -641, 590, -546, 615, -163, +328, 442, -51, 768, -342, 585, -607, 103, +-761, -550, -585, -1176, -44, -1350, 585, -891, +978, 15, 984, 1054, 642, 1802, 92, 1863, +-380, 1203, -602, 110, -576, -1041, -386, -1874, +-130, -2072, 67, -1499, 195, -353, 296, 854, +325, 1626, 196, 1763, 21, 1259, 18, 285, +219, -717, 397, -1306, 408, -1260, 244, -601, +-122, 308, -559, 968, -769, 1148, -695, 782, +-405, -103, 91, -1138, 637, -1777, 986, -1636, +1049, -653, 806, 709, 320, 1853, -274, 2472, +-817, 2249, -1038, 1003, -806, -696, -339, -2041, +205, -2710, 716, -2542, 862, -1500, 582, -6, +165, 1357, -226, 2154, -425, 2204, -243, 1625, +144, 722, 465, -166, 567, -803, 332, -1148, +-99, -1256, -495, -1141, -758, -901, -710, -625, +-350, -207, 77, 342, 532, 813, 957, 1095, +1107, 1244, 955, 1232, 543, 886, -170, 263, +-880, -444, -1198, -1173, -1153, -1721, -796, -1778, +-151, -1315, 570, -512, 1097, 490, 1288, 1394, +1120, 1827, 661, 1719, -15, 1131, -697, 239, +-1083, -634, -1047, -1265, -638, -1472, -27, -1210, +532, -670, 866, -36, 890, 551, 604, 875, +152, 869, -303, 665, -626, 277, -659, -203, +-432, -523, -33, -636, 511, -535, 895, -189, +823, 208, 476, 492, 56, 650, -429, 598, +-800, 253, -896, -276, -718, -792, -252, -1082, +381, -987, 929, -539, 1268, 148, 1186, 892, +659, 1335, -9, 1274, -656, 861, -1165, 247, +-1190, -492, -756, -1114, -226, -1357, 364, -1212, +960, -794, 1169, -123, 961, 638, 595, 1118, +41, 1173, -597, 896, -891, 395, -754, -169, +-423, -586, 8, -723, 498, -623, 824, -407, +816, -184, 454, 45, -94, 247, -571, 264, +-787, 165, -657, 122, -181, 93, 426, 54, +908, 15, 1028, -67, 705, -151, 164, -115, +-307, -19, -657, 81, -849, 249, -744, 256, +-380, -23, 103, -312, 616, -465, 978, -478, +997, -307, 654, 14, 133, 364, -358, 607, +-649, 618, -678, 424, -543, 153, -339, -263, +25, -687, 516, -784, 885, -613, 978, -254, +751, 290, 174, 749, -526, 871, -1016, 622, +-1171, 66, -895, -566, -222, -978, 554, -1068, +1237, -688, 1678, 160, 1624, 989, 1016, 1471, +-48, 1432, -1258, 710, -2065, -379, -2234, -1381, +-1806, -1988, -693, -1890, 918, -1055, 2337, 168, +3078, 1411, 2925, 2290, 1783, 2378, 7, 1642, +-1840, 314, -3174, -1241, -3432, -2419, -2501, -2825, +-799, -2275, 1148, -835, 2733, 849, 3403, 2186, +2995, 2879, 1654, 2574, -211, 1326, -1823, -337, +-2599, -1892, -2483, -2744, -1569, -2555, -122, -1602, +1150, -158, 1677, 1398, 1580, 2245, 1083, 2181, +270, 1556, -441, 422, -630, -823, -443, -1543, +-113, -1676, 273, -1312, 425, -587, 184, 173, +-269, 768, -710, 985, -908, 745, -538, 426, +335, 193, 1256, -96, 1800, -203, 1654, -29, +760, 12, -599, -106, -1844, -292, -2418, -663, +-2054, -973, -826, -906, 871, -390, 2395, 428, +3130, 1232, 2755, 1789, 1354, 1786, -644, 1011, +-2468, -204, -3340, -1317, -3036, -2101, -1735, -2332, +282, -1773, 2292, -643, 3361, 746, 3255, 1988, +2185, 2501, 337, 2249, -1558, 1337, -2577, -124, +-2592, -1499, -1849, -2232, -522, -2250, 818, -1579, +1628, -405, 1778, 763, 1354, 1556, 613, 1838, +-68, 1480, -562, 638, -782, -407, -608, -1236, +-251, -1460, 30, -1193, 242, -536, 391, 397, +398, 1104, 312, 1316, 214, 1093, -51, 428, +-452, -541, -641, -1338, -557, -1687, -333, -1466, +201, -634, 954, 488, 1436, 1574, 1435, 2194, +988, 1929, 79, 1031, -961, -180, -1738, -1500, +-2042, -2388, -1597, -2429, -453, -1713, 885, -416, +1999, 1154, 2490, 2308, 2079, 2598, 978, 1994, +-501, 670, -1837, -861, -2304, -2102, -1766, -2551, +-641, -1891, 764, -547, 1962, 858, 2222, 1955, +1463, 2282, 127, 1588, -1355, 199, -2353, -1286, +-2210, -2287, -948, -2331, 792, -1415, 2376, 107, +3191, 1720, 2680, 2684, 1019, 2560, -1013, 1502, +-2729, -177, -3479, -1869, -2849, -2856, -1150, -2823, +897, -1819, 2638, -179, 3413, 1483, 2921, 2540, +1389, 2649, -530, 1889, -1927, 577, -2381, -798, +-2060, -1774, -1044, -2087, 421, -1717, 1550, -888, +1864, 115, 1431, 910, 453, 1223, -644, 1162, +-1316, 811, -1345, 252, -809, -289, 194, -610, +1272, -738, 1788, -728, 1471, -397, 693, 94, +-178, 384, -1094, 573, -1727, 643, -1618, 334, +-828, -187, 213, -520, 1063, -693, 1524, -740, +1489, -427, 878, 40, 57, 409, -532, 773, +-832, 997, -764, 903, -267, 449, 174, -211, +344, -847, 502, -1339, 457, -1489, 74, -1047, +-286, -141, -477, 731, -531, 1355, -321, 1623, +89, 1216, 567, 372, 1008, -438, 1136, -1068, +856, -1363, 338, -1128, -238, -480, -770, 186, +-1124, 655, -1175, 901, -849, 819, -292, 377, +320, -249, 888, -690, 1196, -812, 1223, -665, +1111, -245, 719, 378, 118, 987, -366, 1183, +-734, 864, -1056, 345, -1207, -393, -1081, -1317, +-699, -1903, -52, -1800, 799, -1168, 1593, -93, +1935, 1326, 1680, 2487, 1070, 2854, 84, 2338, +-1093, 1031, -1756, -767, -1754, -2557, -1474, -3642, +-811, -3558, 297, -2414, 1331, -507, 1852, 1739, +1806, 3562, 1333, 4295, 553, 3735, -382, 2046, +-1120, -394, -1375, -2842, -1244, -4394, -880, -4545, +-331, -3347, 259, -1113, 764, 1518, 1125, 3570, +1298, 4372, 1279, 3892, 979, 2262, 424, -37, +-225, -2128, -1059, -3448, -1888, -3744, -2139, -2947, +-1645, -1398, -631, 443, 826, 2018, 2365, 2842, +3287, 2886, 3221, 2270, 2046, 1036, 66, -440, +-2056, -1636, -3661, -2397, -4151, -2598, -3202, -2096, +-1093, -1089, 1519, 266, 3807, 1579, 4867, 2338, +4266, 2515, 2285, 2020, -422, 760, -3022, -697, +-4587, -1792, -4546, -2430, -2975, -2385, -474, -1466, +2179, -169, 4184, 1043, 4782, 1919, 3696, 2078, +1351, 1542, -1374, 656, -3446, -334, -4185, -1122, +-3488, -1435, -1556, -1299, 809, -943, 2649, -382, +3565, 273, 3415, 657, 2077, 689, 44, 681, +-1740, 701, -2783, 503, -2885, 194, -2033, 28, +-505, -221, 1173, -700, 2318, -1085, 2546, -1120, +2015, -956, 976, -564, -355, 248, -1468, 1188, +-1939, 1789, -1775, 1858, -1074, 1344, 41, 335, +1135, -901, 1760, -1989, 1816, -2510, 1368, -2087, +443, -974, -688, 289, -1503, 1477, -1759, 2241, +-1457, 2194, -612, 1409, 567, 303, 1634, -651, +2163, -1315, 1922, -1619, 1141, -1350, 24, -662, +-1276, -139, -2194, 85, -2274, 258, -1668, 327, +-515, 329, 1108, 488, 2406, 790, 2746, 1123, +2267, 1098, 1089, 531, -492, -202, -1766, -1048, +-2306, -2041, -2130, -2465, -1311, -1920, -125, -821, +1032, 631, 1874, 2207, 2130, 3177, 1650, 3072, +674, 1840, -376, -77, -1099, -1875, -1291, -3105, +-1045, -3464, -609, -2529, -125, -716, 379, 1067, +774, 2441, 920, 3060, 852, 2601, 634, 1349, +240, -252, -209, -1667, -565, -2401, -702, -2419, +-583, -1747, -377, -436, -100, 898, 383, 1661, +890, 1878, 1051, 1622, 924, 863, 518, -101, +-209, -930, -832, -1355, -1044, -1344, -881, -1110, +-403, -677, 206, -64, 681, 502, 1005, 896, +1091, 1117, 748, 1170, 158, 916, -371, 323, +-781, -350, -850, -872, -457, -1289, 129, -1452, +620, -1080, 815, -374, 591, 288, 121, 837, +-302, 1165, -585, 1173, -580, 889, -197, 367, +332, -115, 762, -359, 1016, -608, 889, -878, +322, -908, -300, -758, -734, -632, -909, -439, +-791, 14, -392, 641, 122, 1143, 551, 1367, +762, 1299, 799, 956, 800, 286, 623, -600, +213, -1448, -117, -1961, -283, -1904, -560, -1385, +-884, -531, -850, 592, -481, 1610, -45, 2233, +519, 2277, 1090, 1615, 1309, 450, 1158, -787, +777, -1803, 163, -2379, -546, -2241, -1090, -1451, +-1412, -326, -1327, 837, -719, 1596, 228, 1856, +1222, 1731, 1828, 1131, 1756, 200, 1215, -616, +353, -1076, -742, -1281, -1471, -1257, -1588, -861, +-1337, -230, -687, 233, 359, 325, 1261, 387, +1607, 491, 1466, 353, 975, 299, 301, 593, +-402, 743, -886, 510, -929, 159, -780, -324, +-628, -1053, -274, -1658, 189, -1786, 501, -1311, +728, -394, 903, 644, 835, 1753, 562, 2586, +312, 2478, 67, 1568, -220, 343, -511, -1173, +-721, -2651, -800, -3265, -590, -2863, -177, -1693, +107, 87, 334, 1894, 715, 3135, 997, 3440, +994, 2553, 929, 960, 726, -693, 243, -2176, +-340, -3050, -864, -2836, -1285, -1852, -1456, -544, +-1290, 921, -816, 1986, 28, 2239, 1131, 1878, +2178, 984, 2760, -179, 2509, -1026, 1436, -1232, +-140, -868, -1801, -335, -3015, 53, -3331, 258, +-2605, 119, -1071, -379, 894, -835, 2754, -934, +3775, -684, 3578, 56, 2271, 1172, 310, 2032, +-1680, 2309, -3002, 1927, -3249, 694, -2462, -1123, +-967, -2793, 731, -3553, 2105, -3194, 2707, -1984, +2369, -84, 1300, 2070, -57, 3618, -1225, 4006, +-1771, 3192, -1560, 1485, -731, -596, 408, -2455, +1243, -3652, 1425, -3695, 1099, -2525, 336, -899, +-742, 659, -1522, 1917, -1595, 2502, -998, 2400, +193, 1748, 1556, 821, 2369, 33, 2403, -495, +1709, -923, 322, -1276, -1443, -1499, -2841, -1630, +-3216, -1552, -2581, -1144, -1125, -391, 1030, 801, +3215, 1977, 4276, 2584, 3812, 2601, 2235, 1978, +-132, 695, -2624, -856, -4195, -2189, -4267, -3017, +-2977, -3122, -729, -2338, 1856, -889, 3858, 821, +4472, 2327, 3607, 3131, 1635, 2905, -870, 1831, +-2880, 466, -3603, -965, -3147, -2137, -1849, -2381, +35, -1874, 1826, -1157, 2846, -224, 2973, 757, +2212, 1219, 680, 1181, -976, 949, -2081, 438, +-2318, -172, -1729, -500, -587, -522, 698, -285, +1571, 72, 1754, 433, 1418, 571, 861, 213, +111, -356, -718, -747, -1231, -1021, -1258, -1095, +-901, -646, -329, 114, 316, 669, 803, 1049, +1023, 1246, 1106, 1123, 1096, 800, 823, 320, +239, -241, -389, -757, -902, -1257, -1403, -1577, +-1657, -1579, -1227, -1314, -364, -737, 490, 272, +1414, 1401, 2259, 2229, 2476, 2674, 1983, 2449, +987, 1361, -431, -156, -1907, -1778, -2877, -3175, +-3121, -3730, -2551, -3153, -1149, -1718, 721, 222, +2597, 2319, 4004, 3873, 4459, 4203, 3520, 3234, +1338, 1345, -1273, -858, -3610, -2882, -5048, -4089, +-4928, -3863, -3221, -2457, -637, -569, 2225, 1316, +4665, 2700, 5711, 3169, 5026, 2649, 2932, 1471, +-53, 72, -3025, -1098, -4993, -1827, -5406, -2126, +-4144, -1889, -1665, -1175, 1125, -257, 3425, 654, +4665, 1319, 4562, 1659, 3256, 1588, 1061, 1056, +-1351, 244, -3051, -637, -3651, -1374, -3259, -1766, +-2018, -1733, -333, -1236, 1172, -220, 2182, 1089, +2609, 2100, 2505, 2524, 1817, 2202, 693, 999, +-310, -713, -1029, -2333, -1735, -3330, -2136, -3282, +-1775, -2173, -1111, -282, -458, 1901, 559, 3578, +1725, 4013, 2434, 3239, 2541, 1562, 2108, -712, +1080, -2759, -397, -3822, -1836, -3802, -2796, -2805, +-3074, -1096, -2457, 800, -982, 2299, 801, 3118, +2359, 3165, 3436, 2461, 3596, 1226, 2674, -184, +1070, -1374, -848, -2170, -2633, -2529, -3574, -2324, +-3448, -1705, -2464, -891, -716, 33, 1302, 984, +2844, 1793, 3534, 2244, 3320, 2258, 2238, 1853, +546, 1075, -1171, 27, -2362, -1149, -2836, -2095, +-2611, -2583, -1610, -2560, -207, -1981, 926, -934, +1743, 373, 2259, 1614, 2117, 2470, 1405, 2815, +604, 2522, -207, 1578, -1030, 194, -1554, -1197, +-1587, -2246, -1213, -2774, -570, -2615, 142, -1831, +803, -663, 1266, 654, 1425, 1755, 1301, 2400, +898, 2439, 231, 1803, -552, 700, -1227, -565, +-1576, -1713, -1407, -2337, -686, -2137, 366, -1272, +1295, -83, 1834, 1200, 1934, 2075, 1435, 2107, +386, 1323, -821, -2, -1793, -1387, -2290, -2327, +-2005, -2491, -1002, -1682, 257, -136, 1474, 1541, +2399, 2762, 2660, 3186, 2098, 2632, 969, 1136, +-313, -881, -1482, -2722, -2295, -3807, -2463, -3889, +-1915, -2837, -911, -740, 185, 1566, 1181, 3304, +1971, 4208, 2369, 3927, 2134, 2393, 1415, 293, +591, -1657, -316, -3030, -1226, -3501, -1788, -2991, +-1898, -1808, -1763, -411, -1392, 702, -618, 1371, +446, 1683, 1377, 1652, 2023, 1496, 2506, 1417, +2486, 1202, 1695, 738, 590, 49, -512, -927, +-1804, -2010, -2935, -2803, -3229, -3075, -2610, -2553, +-1331, -1137, 330, 730, 2057, 2541, 3439, 3878, +3925, 4238, 3361, 3412, 1982, 1518, -17, -927, +-2153, -3098, -3642, -4426, -4111, -4628, -3514, -3448, +-1780, -1165, 598, 1292, 2658, 3197, 3817, 4174, +3920, 3873, 3034, 2450, 1327, 485, -745, -1379, +-2470, -2629, -3364, -3077, -3302, -2669, -2221, -1557, +-471, -272, 1210, 799, 2416, 1562, 2921, 1868, +2495, 1606, 1392, 1057, 195, 443, -861, -186, +-1715, -641, -2060, -897, -1667, -1063, -850, -1057, +-94, -852, 654, -497, 1372, -82, 1525, 342, +1119, 758, 717, 1052, 371, 1082, -104, 889, +-469, 588, -573, 168, -594, -396, -577, -969, +-524, -1380, -405, -1477, -211, -1278, -25, -826, +284, -48, 722, 889, 1028, 1650, 1132, 2055, +1084, 1945, 745, 1315, 148, 308, -483, -905, +-1086, -1978, -1490, -2473, -1463, -2299, -1097, -1580, +-511, -426, 326, 834, 1174, 1749, 1699, 2162, +1862, 2060, 1670, 1515, 1060, 671, 136, -291, +-763, -1077, -1419, -1533, -1780, -1709, -1700, -1501, +-1144, -962, -376, -373, 366, 182, 1017, 690, +1476, 955, 1590, 1034, 1354, 1105, 850, 1021, +298, 692, -124, 331, -492, -33, -871, -563, +-1182, -1202, -1245, -1606, -1041, -1585, -671, -1254, +-100, -697, 681, 121, 1318, 1017, 1523, 1656, +1519, 1867, 1316, 1698, 686, 1270, -118, 579, +-795, -440, -1398, -1431, -1707, -2016, -1405, -2238, +-737, -1998, -13, -1061, 733, 220, 1262, 1284, +1326, 1970, 1105, 2171, 778, 1700, 339, 789, +-81, -136, -386, -824, -579, -1186, -583, -1232, +-492, -1018, -459, -667, -417, -390, -301, -265, +-170, -153, 69, 122, 508, 522, 969, 968, +1323, 1363, 1407, 1505, 1029, 1199, 250, 384, +-702, -743, -1551, -1799, -2005, -2452, -1881, -2421, +-1190, -1588, -16, -133, 1306, 1463, 2286, 2667, +2608, 3054, 2200, 2398, 1213, 955, -128, -715, +-1543, -2148, -2551, -2927, -2781, -2790, -2240, -1759, +-1040, -223, 594, 1199, 2071, 2118, 2849, 2428, +2843, 1993, 2125, 889, 817, -325, -648, -1133, +-1762, -1519, -2391, -1458, -2465, -887, -1806, -154, +-666, 285, 456, 358, 1425, 205, 2049, -48, +1890, -219, 1289, -64, 818, 390, 293, 906, +-325, 1271, -710, 1243, -935, 664, -1193, -290, +-1253, -1312, -956, -2087, -501, -2244, -59, -1669, +432, -637, 1023, 584, 1474, 1701, 1594, 2305, +1465, 2198, 996, 1538, 119, 577, -791, -468, +-1385, -1329, -1636, -1712, -1483, -1629, -958, -1294, +-293, -752, 351, -91, 851, 415, 1139, 694, +1233, 839, 1068, 836, 613, 751, 141, 706, +-72, 576, -182, 305, -337, -18, -371, -426, +-302, -870, -445, -1120, -690, -1087, -707, -828, +-582, -419, -376, 72, 36, 479, 586, 641, +1118, 626, 1526, 611, 1680, 586, 1480, 567, +882, 618, -100, 566, -1125, 233, -1872, -338, +-2342, -997, -2316, -1527, -1564, -1767, -408, -1578, +799, -841, 1996, 239, 2877, 1168, 2940, 1775, +2184, 2049, 997, 1726, -387, 899, -1734, 30, +-2549, -692, -2533, -1138, -1888, -1244, -915, -1132, +175, -879, 1123, -604, 1560, -487, 1432, -432, +1080, -219, 702, 174, 259, 712, -23, 1366, +57, 1870, 146, 1992, 75, 1611, 18, 666, +-240, -622, -824, -1841, -1336, -2673, -1527, -2885, +-1386, -2371, -749, -1264, 319, 63, 1463, 1292, +2379, 2232, 2733, 2690, 2312, 2554, 1260, 1973, +-95, 1153, -1362, 134, -2219, -1000, -2534, -1983, +-2344, -2635, -1639, -2895, -521, -2660, 575, -1762, +1358, -308, 1963, 1233, 2301, 2549, 2024, 3469, +1353, 3555, 698, 2624, -100, 1105, -1098, -563, +-1821, -2158, -2054, -3264, -1930, -3441, -1355, -2723, +-337, -1463, 710, -3, 1366, 1304, 1637, 2147, +1591, 2362, 1063, 2043, 296, 1406, -164, 636, +-333, -77, -418, -633, -246, -1050, 72, -1306, +83, -1383, -200, -1284, -582, -1003, -1011, -502, +-1235, 183, -1026, 867, -382, 1325, 603, 1427, +1574, 1163, 2081, 626, 2078, -35, 1603, -639, +587, -970, -578, -872, -1331, -501, -1671, -65, +-1777, 337, -1491, 480, -801, 233, -168, -224, +168, -695, 453, -1006, 846, -847, 1191, -155, +1443, 701, 1660, 1451, 1706, 1864, 1276, 1637, +294, 818, -936, -268, -2054, -1312, -2789, -2041, +-2908, -2219, -2282, -1747, -1000, -837, 617, 218, +2140, 1210, 3107, 1881, 3274, 1986, 2708, 1586, +1599, 890, 190, 21, -1214, -758, -2238, -1184, +-2625, -1342, -2504, -1268, -2071, -896, -1232, -424, +-44, -103, 1007, 153, 1744, 514, 2342, 872, +2536, 1025, 2015, 986, 1102, 843, 145, 521, +-878, -74, -1756, -687, -2110, -1043, -1881, -1160, +-1309, -1079, -634, -751, 81, -247, 735, 230, +1049, 589, 1062, 879, 1136, 996, 1178, 902, +953, 702, 647, 327, 299, -224, -254, -697, +-836, -991, -1252, -1134, -1532, -978, -1503, -497, +-1005, 44, -250, 542, 565, 952, 1341, 1056, +1818, 844, 1703, 474, 993, 4, 128, -453, +-533, -774, -931, -875, -980, -710, -625, -372, +-102, -27, 234, 278, 240, 505, 57, 571, +-150, 497, -402, 378, -562, 229, -352, 45, +112, -175, 580, -404, 1026, -613, 1273, -786, +1079, -798, 556, -519, -111, 9, -709, 659, +-1044, 1281, -1215, 1605, -1183, 1370, -762, 616, +-246, -452, 97, -1529, 498, -2183, 944, -2128, +1123, -1330, 1090, -38, 1035, 1255, 881, 2134, +463, 2360, -209, 1812, -867, 624, -1352, -666, +-1693, -1551, -1724, -1914, -1193, -1735, -244, -1022, +716, -36, 1490, 767, 1989, 1081, 2017, 1052, +1473, 832, 585, 375, -299, -112, -1029, -301, +-1491, -294, -1579, -295, -1344, -249, -890, -194, +-284, -199, 347, -174, 896, -123, 1237, -32, +1241, 126, 954, 254, 532, 276, 92, 179, +-272, -5, -506, -149, -616, -168, -611, -116, +-479, 35, -303, 270, -184, 330, -66, 196, +89, 26, 173, -221, 173, -468, 272, -527, +470, -380, 567, -122, 521, 110, 395, 280, +204, 381, -101, 333, -478, 196, -750, 126, +-806, 90, -681, 88, -375, 173, 91, 158, +570, -62, 898, -332, 869, -646, 457, -942, +-15, -945, -370, -621, -590, -50, -432, 736, +69, 1434, 470, 1743, 596, 1580, 512, 872, +161, -219, -427, -1258, -956, -1947, -1103, -2099, +-851, -1614, -378, -652, 305, 461, 1099, 1374, +1549, 1828, 1428, 1774, 931, 1194, 182, 264, +-628, -590, -1203, -1103, -1426, -1225, -1199, -958, +-620, -423, 0, 165, 556, 587, 946, 645, +936, 334, 627, -100, 255, -489, -129, -727, +-319, -604, -191, -99, 7, 605, 132, 1213, +188, 1373, 79, 1058, -202, 400, -498, -533, +-618, -1405, -483, -1758, -191, -1534, 178, -930, +531, -85, 654, 783, 545, 1357, 372, 1411, +118, 1013, -107, 487, -120, -13, -76, -437, +-91, -563, -75, -360, -115, -150, -239, -101, +-338, -146, -454, -324, -463, -616, -191, -802, +146, -719, 375, -271, 670, 447, 934, 1134, +818, 1569, 456, 1606, 175, 1181, -86, 408, +-465, -527, -775, -1358, -859, -1782, -884, -1745, +-872, -1409, -585, -766, -98, 134, 358, 889, +865, 1304, 1413, 1522, 1646, 1502, 1431, 1188, +952, 709, 187, 104, -847, -597, -1736, -1243, +-2125, -1717, -2016, -1875, -1425, -1556, -399, -760, +745, 309, 1628, 1296, 2034, 1894, 1903, 1983, +1361, 1493, 615, 514, -209, -525, -899, -1202, +-1211, -1409, -1202, -1142, -1080, -480, -818, 231, +-382, 605, -10, 519, 198, 126, 401, -328, +637, -660, 791, -646, 843, -172, 817, 509, +681, 1116, 418, 1478, -1, 1294, -526, 532, +-935, -469, -1130, -1394, -1139, -1922, -884, -1777, +-429, -1028, 56, 16, 516, 1013, 884, 1638, +1084, 1663, 1111, 1087, 914, 179, 518, -615, +100, -1031, -301, -1033, -669, -556, -890, 170, +-983, 646, -965, 723, -720, 424, -318, -215, +150, -824, 636, -1039, 918, -849, 937, -288, +841, 513, 594, 1185, 236, 1432, 8, 1145, +-152, 451, -383, -327, -575, -996, -677, -1346, +-730, -1128, -693, -509, -512, 69, -194, 471, +148, 711, 490, 595, 892, 182, 1168, -117, +1125, -139, 870, -12, 415, 192, -335, 467, +-1046, 578, -1339, 238, -1289, -389, -982, -936, +-409, -1216, 304, -1081, 893, -480, 1111, 408, +932, 1239, 517, 1649, -1, 1450, -418, 740, +-536, -244, -370, -1170, -14, -1680, 373, -1613, +538, -1018, 371, -61, 0, 921, -442, 1542, +-794, 1616, -934, 1200, -844, 459, -415, -404, +306, -1161, 916, -1519, 1204, -1303, 1210, -754, +842, -173, 169, 426, -417, 919, -706, 1051, +-769, 891, -612, 679, -295, 454, -62, 158, +-68, -199, -202, -603, -325, -981, -388, -1171, +-246, -1118, 171, -801, 729, -166, 1266, 620, +1606, 1258, 1499, 1574, 839, 1465, -251, 917, +-1437, 105, -2234, -668, -2389, -1163, -1995, -1342, +-1079, -1177, 254, -682, 1435, -133, 2104, 249, +2391, 514, 2198, 686, 1329, 690, 167, 621, +-717, 563, -1293, 387, -1746, 99, -1870, -187, +-1474, -508, -915, -783, -484, -834, 90, -679, +888, -378, 1432, 54, 1587, 476, 1616, 734, +1402, 785, 773, 618, -23, 282, -754, -118, +-1386, -452, -1716, -603, -1595, -525, -1186, -250, +-642, 82, 20, 334, 692, 425, 1171, 305, +1306, 27, 1146, -253, 892, -403, 573, -389, +130, -224, -216, 43, -296, 281, -393, 447, +-699, 499, -1001, 330, -1114, 26, -1059, -216, +-859, -383, -389, -483, 381, -417, 1161, -132, +1683, 228, 1947, 442, 1855, 476, 1206, 410, +129, 111, -988, -419, -1894, -781, -2408, -766, +-2316, -521, -1585, -45, -484, 634, 618, 1161, +1572, 1277, 2203, 1013, 2221, 409, 1652, -425, +726, -1247, -350, -1749, -1202, -1699, -1555, -1191, +-1476, -399, -1028, 660, -344, 1654, 194, 2096, +389, 1976, 416, 1427, 359, 430, 180, -744, +-31, -1669, -32, -2161, 262, -2127, 620, -1494, +838, -442, 826, 680, 449, 1570, -246, 2005, +-974, 1867, -1499, 1193, -1588, 194, -1118, -739, +-328, -1306, 453, -1401, 1137, -1030, 1634, -356, +1658, 338, 1060, 722, 171, 644, -564, 307, +-1126, -116, -1430, -565, -1145, -762, -448, -464, +194, 126, 659, 699, 868, 1127, 708, 1269, +340, 944, -60, 159, -446, -763, -661, -1399, +-540, -1607, -191, -1397, 194, -741, 470, 166, +597, 930, 566, 1340, 384, 1323, 163, 878, +-65, 285, -362, -201, -671, -523, -864, -544, +-854, -305, -623, -73, -220, 8, 317, -112, +879, -382, 1227, -583, 1275, -582, 1089, -418, +620, -53, -166, 498, -992, 944, -1494, 1076, +-1559, 967, -1266, 677, -625, 211, 258, -305, +943, -694, 1155, -892, 1095, -998, 878, -1038, +392, -865, -151, -456, -357, 18, -281, 543, +-214, 1139, -148, 1534, -56, 1473, -170, 1085, +-540, 519, -811, -283, -767, -1130, -496, -1634, +10, -1686, 683, -1330, 1206, -633, 1341, 189, +1097, 876, 642, 1251, 107, 1231, -459, 863, +-914, 374, -1108, 12, -1078, -174, -910, -228, +-619, -188, -248, -167, 119, -272, 485, -494, +828, -733, 1060, -862, 1164, -729, 1171, -244, +982, 431, 430, 1016, -409, 1369, -1222, 1408, +-1787, 1017, -1981, 272, -1683, -500, -927, -1046, +77, -1344, 1031, -1319, 1733, -903, 2069, -296, +1902, 266, 1264, 684, 406, 894, -452, 927, +-1149, 800, -1511, 463, -1590, 38, -1470, -298, +-1035, -551, -408, -657, 184, -541, 776, -329, +1305, -93, 1488, 154, 1330, 264, 1029, 166, +553, 38, -100, 9, -664, 20, -1025, 44, +-1266, 140, -1281, 304, -941, 366, -465, 210, +-72, 2, 344, -196, 761, -481, 985, -677, +1071, -571, 1041, -245, 745, 118, 237, 460, +-255, 724, -603, 740, -813, 468, -922, 54, +-890, -381, -699, -684, -426, -672, -119, -417, +250, -113, 582, 217, 753, 462, 826, 472, +869, 365, 816, 240, 573, 46, 147, -139, +-374, -260, -898, -360, -1283, -389, -1371, -329, +-1130, -255, -639, -94, 29, 146, 751, 338, +1314, 531, 1549, 709, 1407, 698, 901, 456, +141, 60, -618, -445, -1080, -972, -1203, -1274, +-1094, -1163, -797, -714, -354, -51, 151, 723, +579, 1335, 777, 1540, 786, 1329, 673, 775, +376, -7, 28, -748, -164, -1244, -276, -1429, +-411, -1240, -444, -732, -361, -106, -268, 468, +-86, 868, 195, 1033, 397, 934, 413, 599, +298, 242, 89, 11, -225, -187, -497, -352, +-559, -440, -431, -550, -69, -624, 500, -556, +901, -413, 894, -152, 637, 235, 200, 570, +-405, 782, -925, 813, -1138, 588, -1037, 242, +-705, -83, -193, -411, 472, -612, 1049, -519, +1249, -322, 1119, -197, 750, -44, 130, 83, +-464, 39, -801, -51, -978, -9, -987, 75, +-719, 146, -285, 373, 197, 621, 627, 579, +809, 375, 670, 100, 318, -396, 11, -892, +-88, -1039, -121, -861, -129, -457, -49, 114, +-46, 664, -150, 999, -157, 982, -102, 607, +-180, 100, -327, -356, -327, -649, -126, -594, +149, -231, 380, 158, 596, 402, 636, 400, +330, 69, -50, -441, -260, -832, -402, -886, +-464, -488, -348, 222, -116, 943, 134, 1427, +284, 1457, 256, 943, 62, 24, -249, -959, +-480, -1599, -433, -1708, -183, -1299, 175, -466, +619, 530, 921, 1291, 898, 1548, 596, 1295, +72, 663, -555, -128, -1075, -778, -1336, -1043, +-1220, -874, -716, -415, -2, 141, 664, 575, +1113, 643, 1254, 332, 1081, -128, 701, -528, +262, -730, -172, -571, -591, -54, -865, 581, +-930, 1053, -919, 1157, -792, 835, -477, 152, +-85, -692, 305, -1311, 726, -1426, 1130, -1073, +1325, -386, 1133, 489, 643, 1228, 51, 1442, +-643, 1097, -1320, 460, -1618, -269, -1414, -861, +-859, -1076, -110, -864, 649, -356, 1212, 198, +1407, 593, 1124, 749, 553, 603, -10, 193, +-470, -223, -747, -454, -748, -546, -536, -467, +-259, -161, -33, 160, 138, 354, 229, 479, +170, 507, 50, 397, 54, 199, 75, -62, +5, -330, -4, -540, 52, -679, 70, -670, +92, -409, 154, 17, 166, 455, 40, 808, +-115, 982, -164, 894, -205, 531, -315, -23, +-352, -616, -299, -1069, -212, -1188, 34, -927, +367, -395, 511, 252, 519, 826, 494, 1135, +313, 1070, 24, 680, -215, 130, -382, -396, +-486, -732, -535, -807, -474, -638, -270, -332, +-49, -14, 104, 246, 248, 379, 400, 382, +492, 334, 520, 267, 482, 178, 345, 67, +71, -45, -353, -128, -726, -221, -837, -341, +-732, -369, -486, -245, -66, -68, 396, 145, +675, 379, 764, 501, 699, 457, 410, 281, +-15, -33, -350, -400, -524, -593, -598, -522, +-515, -315, -228, -27, 110, 350, 346, 658, +508, 679, 578, 416, 389, 83, -48, -225, +-442, -524, -649, -682, -730, -575, -600, -302, +-143, -43, 438, 227, 849, 575, 1008, 785, +966, 704, 620, 487, -39, 188, -711, -264, +-1129, -712, -1276, -909, -1158, -838, -697, -587, +7, -170, 695, 343, 1231, 796, 1506, 1012, +1382, 919, 837, 576, 62, 89, -663, -413, +-1192, -780, -1458, -881, -1337, -691, -809, -336, +-115, 39, 477, 368, 902, 582, 1125, 588, +1073, 440, 741, 247, 254, 4, -223, -233, +-581, -325, -795, -304, -834, -277, -626, -209, +-213, -25, 216, 158, 521, 234, 662, 313, +563, 392, 213, 289, -189, 30, -459, -208, +-570, -413, -493, -614, -150, -624, 298, -307, +623, 170, 802, 609, 774, 951, 419, 1069, +-151, 774, -668, 123, -1015, -562, -1148, -1069, +-941, -1302, -418, -1142, 237, -599, 857, 124, +1302, 796, 1390, 1242, 1040, 1357, 435, 1111, +-234, 553, -882, -149, -1260, -782, -1172, -1196, +-800, -1257, -368, -938, 133, -395, 592, 217, +776, 782, 659, 1081, 437, 966, 244, 568, +94, 100, 9, -348, 21, -628, 48, -588, +-27, -312, -187, 9, -395, 261, -595, 350, +-619, 236, -459, 0, -218, -222, 121, -341, +532, -283, 801, -79, 849, 137, 724, 278, +422, 326, 37, 253, -300, 113, -542, 40, +-630, 89, -585, 180, -508, 198, -423, 70, +-244, -190, -12, -540, 200, -863, 460, -937, +762, -636, 921, -34, 819, 704, 542, 1355, +153, 1691, -390, 1531, -938, 840, -1173, -181, +-1013, -1176, -635, -1850, -131, -2025, 426, -1580, +832, -643, 871, 400, 610, 1266, 303, 1766, +86, 1723, -54, 1208, -91, 526, 11, -113, +114, -628, 0, -898, -300, -916, -595, -878, +-750, -856, -738, -737, -484, -439, 44, 13, +652, 581, 1066, 1202, 1202, 1651, 1072, 1650, +638, 1135, -47, 240, -733, -817, -1174, -1718, +-1236, -2084, -961, -1760, -440, -882, 180, 266, +673, 1313, 880, 1869, 814, 1763, 540, 1081, +181, 96, -77, -818, -191, -1332, -237, -1321, +-186, -824, -77, -48, -87, 668, -198, 1048, +-216, 1005, -185, 586, -185, -35, -90, -623, +167, -950, 367, -877, 381, -479, 352, 15, +303, 465, 139, 800, -51, 870, -154, 634, +-193, 285, -238, -26, -239, -293, -186, -489, +-149, -547, -127, -505, -33, -450, 143, -360, +284, -139, 332, 180, 350, 500, 344, 763, +224, 878, -8, 741, -205, 395, -352, -48, +-477, -508, -455, -853, -213, -910, 84, -691, +324, -362, 490, -4, 481, 373, 275, 649, +8, 709, -218, 599, -355, 422, -359, 195, +-205, -68, 54, -294, 279, -414, 379, -415, +377, -336, 212, -220, -108, -79, -370, 51, +-459, 138, -397, 189, -190, 216, 94, 230, +329, 249, 468, 244, 521, 193, 403, 123, +114, 37, -218, -119, -453, -302, -536, -421, +-440, -450, -162, -380, 165, -179, 383, 125, +453, 441, 355, 662, 135, 735, -81, 626, +-238, 323, -329, -118, -262, -552, -80, -851, +90, -922, 226, -710, 303, -247, 240, 327, +93, 830, -21, 1097, -106, 1045, -201, 686, +-249, 129, -212, -476, -152, -953, -121, -1125, +-7, -944, 185, -522, 325, 32, 392, 576, +446, 947, 391, 1078, 132, 957, -207, 581, +-499, 85, -727, -395, -795, -817, -584, -1054, +-130, -974, 367, -665, 800, -223, 1049, 328, +954, 820, 531, 1054, -10, 1034, -535, 804, +-950, 379, -1073, -175, -829, -665, -364, -929, +161, -954, 620, -765, 875, -369, 846, 105, +575, 507, 155, 771, -270, 850, -572, 696, +-658, 383, -523, 44, -256, -231, 20, -410, +215, -480, 296, -445, 282, -324, 220, -184, +155, -65, 77, 50, -15, 216, -120, 403, +-214, 497, -283, 478, -297, 395, -212, 182, +-59, -152, 120, -436, 306, -575, 427, -566, +399, -363, 231, -16, 3, 333, -260, 577, +-499, 619, -615, 428, -501, 131, -206, -160, +96, -366, 320, -422, 460, -327, 474, -143, +373, 75, 221, 234, 36, 285, -155, 260, +-296, 215, -408, 179, -502, 139, -527, 48, +-405, -83, -182, -216, 50, -364, 314, -490, +644, -451, 876, -190, 810, 211, 469, 614, +-41, 901, -637, 956, -1136, 694, -1327, 135, +-1065, -548, -431, -1100, 339, -1291, 1019, -1043, +1388, -416, 1265, 399, 678, 1105, -144, 1423, +-925, 1256, -1382, 655, -1333, -178, -827, -887, +-37, -1187, 738, -1042, 1201, -508, 1188, 226, +725, 820, 11, 1006, -695, 765, -1193, 226, +-1302, -378, -934, -776, -272, -797, 422, -453, +990, 92, 1246, 594, 1062, 870, 515, 827, +-135, 477, -692, -64, -1070, -543, -1198, -765, +-991, -720, -557, -464, -91, -52, 374, 341, +792, 542, 1008, 556, 951, 462, 676, 269, +279, 34, -207, -124, -716, -149, -1115, -122, +-1252, -131, -1095, -152, -656, -156, -18, -200, +620, -227, 1089, -116, 1267, 117, 1038, 350, +469, 524, -222, 590, -833, 482, -1204, 208, +-1178, -144, -797, -470, -282, -669, 201, -681, +600, -472, 776, -96, 625, 336, 283, 690, +-78, 835, -407, 702, -603, 359, -568, -55, +-345, -428, -51, -680, 190, -696, 253, -451, +190, -74, 32, 298, -196, 600, -326, 708, +-277, 552, -189, 216, -114, -165, 20, -475, +130, -573, 72, -446, -73, -162, -165, 220, +-182, 537, -182, 608, -107, 459, 41, 141, +115, -258, 40, -528, -93, -545, -191, -363, +-252, -12, -303, 393, -306, 637, -222, 619, +-90, 383, 36, 9, 170, -348, 238, -564, +173, -563, 7, -332, -183, 46, -337, 403, +-361, 597, -251, 564, -123, 355, -62, 45, +-65, -266, -108, -445, -172, -422, -243, -264, +-227, -18, -106, 238, 57, 370, 200, 341, +306, 220, 281, 61, 78, -56, -200, -84, +-456, -49, -648, -18, -700, -10, -571, -35, +-303, -101, -2, -168, 268, -127, 452, 35, +488, 215, 354, 373, 127, 486, -133, 419, +-375, 158, -522, -178, -566, -484, -561, -650, +-494, -548, -336, -221, -115, 185, 117, 553, +327, 733, 418, 628, 333, 351, 131, 20, +-77, -304, -289, -503, -472, -470, -518, -283, +-431, -53, -306, 175, -162, 320, -25, 287, +30, 133, -37, -27, -137, -103, -176, -51, +-104, 116, 19, 303, 140, 416, 210, 369, +124, 115, -139, -286, -436, -657, -612, -802, +-622, -615, -500, -177, -262, 376, 23, 889, +256, 1103, 333, 857, 255, 345, 73, -182, +-150, -620, -355, -855, -441, -727, -357, -306, +-180, 148, -48, 422, -13, 478, -103, 343, +-312, 66, -505, -205, -508, -250, -308, -49, +67, 266, 474, 573, 679, 704, 560, 477, +157, -12, -439, -529, -1023, -958, -1326, -1152, +-1202, -864, -685, -176, 65, 578, 771, 1184, +1181, 1486, 1132, 1259, 640, 566, -129, -254, +-886, -920, -1365, -1263, -1410, -1143, -1037, -642, +-414, 17, 221, 599, 651, 902, 770, 830, +623, 480, 292, 44, -103, -283, -432, -383, +-576, -246, -551, 23, -465, 260, -398, 328, +-346, 214, -321, -42, -306, -337, -233, -494, +-51, -416, 208, -157, 451, 201, 525, 529, +379, 680, 60, 587, -346, 317, -774, -39, +-1063, -346, -1065, -484, -761, -439, -289, -283, +181, -81, 559, 111, 745, 272, 626, 367, +291, 372, -100, 301, -473, 207, -774, 68, +-873, -137, -761, -318, -508, -393, -177, -406, +142, -293, 343, 34, 386, 447, 243, 726, +-43, 820, -301, 655, -447, 178, -539, -434, +-526, -916, -343, -1128, -93, -944, 100, -344, +245, 444, 270, 1111, 75, 1453, -243, 1307, +-506, 659, -650, -255, -659, -1039, -501, -1388, +-206, -1203, 99, -577, 298, 251, 349, 908, +293, 1127, 107, 880, -179, 320, -428, -314, +-535, -714, -531, -684, -464, -267, -343, 318, +-227, 809, -156, 929, -98, 566, -57, -126, +9, -830, 105, -1266, 167, -1231, 157, -667, +100, 253, -38, 1155, -252, 1697, -482, 1671, +-702, 1073, -838, 94, -737, -926, -416, -1610, +-40, -1698, 312, -1210, 599, -353, 653, 565, +407, 1215, 4, 1385, -366, 1112, -652, 547, +-799, -87, -727, -536, -476, -669, -194, -532, +15, -257, 121, -12, 133, 104, 42, 72, +-113, -35, -218, -98, -194, -13, -129, 175, +-55, 356, 53, 503, 113, 545, -26, 359, +-305, 8, -531, -341, -654, -581, -716, -664, +-586, -519, -216, -169, 195, 246, 475, 568, +637, 710, 602, 651, 266, 427, -274, 81, +-772, -277, -1032, -521, -978, -583, -673, -470, +-219, -195, 236, 162, 525, 466, 572, 602, +405, 523, 53, 278, -359, 12, -674, -217, +-781, -391, -652, -422, -284, -262, 169, -21, +446, 216, 413, 385, 126, 401, -276, 249, +-603, 37, -698, -164, -544, -280, -240, -239, +128, -34, 417, 209, 478, 355, 269, 360, +-147, 239, -635, -27, -969, -347, -955, -528, +-557, -467, 81, -230, 668, 145, 951, 587, +870, 853, 401, 764, -338, 440, -1024, 14, +-1388, -472, -1396, -858, -1043, -914, -337, -655, +519, -213, 1160, 331, 1357, 808, 1114, 1002, +527, 894, -260, 575, -974, 119, -1371, -359, +-1390, -695, -1136, -834, -678, -751, -116, -459, +400, -33, 745, 388, 895, 685, 845, 807, +580, 743, 177, 473, -243, 89, -645, -274, +-953, -530, -1061, -646, -953, -574, -696, -320, +-325, 21, 117, 331, 530, 518, 762, 515, +744, 357, 531, 152, 190, -15, -215, -152, +-535, -205, -684, -120, -693, 1, -596, 38, +-415, 41, -245, 44, -98, -10, 40, -130, +145, -159, 198, -30, 221, 153, 204, 290, +159, 394, 79, 395, -82, 222, -293, -38, +-456, -269, -544, -451, -532, -470, -390, -263, +-143, 54, 76, 344, 203, 539, 247, 528, +194, 294, 25, -29, -178, -285, -301, -395, +-305, -329, -229, -136, -90, 139, 54, 379, +136, 445, 108, 330, 6, 122, -136, -136, +-328, -361, -515, -427, -561, -285, -466, -18, +-251, 260, 101, 439, 444, 465, 579, 333, +517, 89, 319, -182, 24, -350, -278, -348, +-484, -187, -627, 79, -711, 356, -682, 451, +-504, 278, -224, -37, 87, -319, 389, -477, +629, -423, 705, -112, 595, 341, 360, 689, +31, 778, -398, 608, -791, 221, -997, -326, +-979, -782, -777, -899, -386, -696, 116, -270, +552, 312, 831, 788, 921, 908, 739, 686, +317, 293, -203, -137, -662, -469, -923, -555, +-892, -343, -624, 20, -262, 305, 56, 398, +254, 294, 312, -28, 281, -429, 196, -633, +67, -493, -41, -76, -40, 464, 2, 937, +-23, 1137, -88, 904, -156, 304, -318, -431, +-492, -1037, -481, -1321, -298, -1154, -92, -584, +122, 185, 355, 889, 488, 1283, 418, 1245, +227, 855, -16, 274, -305, -304, -567, -734, +-658, -907, -556, -787, -286, -450, 63, -67, +341, 263, 477, 484, 484, 546, 315, 475, +-34, 355, -417, 196, -654, 28, -676, -119, +-478, -250, -97, -323, 355, -271, 648, -140, +665, 14, 437, 174, 11, 297, -499, 283, +-830, 132, -873, -35, -673, -124, -231, -172, +371, -152, 840, 16, 956, 270, 706, 398, +188, 338, -452, 161, -954, -98, -1098, -386, +-863, -501, -362, -357, 244, -84, 749, 217, +978, 521, 847, 644, 400, 458, -194, 102, +-705, -239, -973, -513, -905, -589, -546, -356, +-66, 84, 357, 500, 615, 721, 619, 646, +409, 294, 136, -212, -109, -649, -292, -814, +-352, -641, -298, -196, -218, 383, -183, 867, +-173, 1032, -168, 812, -148, 321, -100, -300, +20, -826, 223, -1025, 429, -819, 513, -356, +445, 185, 235, 685, -126, 991, -543, 932, +-829, 545, -895, 37, -709, -418, -315, -726, +183, -765, 632, -510, 906, -107, 912, 277, +625, 550, 126, 616, -417, 460, -814, 191, +-924, -83, -735, -292, -322, -346, 120, -249, +415, -66, 518, 128, 445, 248, 189, 227, +-141, 109, -376, -23, -428, -112, -314, -127, +-54, -56, 309, 64, 587, 192, 547, 272, +202, 255, -251, 125, -646, -70, -903, -267, +-871, -382, -495, -339, 58, -124, 553, 159, +895, 419, 1026, 580, 801, 554, 230, 299, +-385, -92, -809, -464, -1002, -660, -914, -614, +-517, -346, -29, 85, 355, 560, 600, 836, +676, 782, 497, 458, 138, 3, -190, -459, +-401, -769, -497, -790, -388, -488, -84, -11, +207, 444, 323, 755, 299, 815, 139, 538, +-149, 89, -415, -293, -515, -524, -489, -559, +-323, -330, 23, 15, 415, 263, 643, 351, +650, 297, 455, 105, 90, -134, -311, -248, +-572, -131, -650, 124, -558, 356, -356, 462, +-123, 391, 93, 113, 269, -288, 349, -607, +299, -667, 184, -472, 94, -109, 39, 340, +21, 727, 37, 855, 20, 694, -131, 323, +-362, -174, -553, -614, -615, -783, -496, -666, +-175, -337, 243, 115, 603, 517, 786, 697, +714, 635, 395, 385, -25, 45, -424, -291, +-733, -516, -819, -542, -600, -363, -248, -60, +69, 269, 350, 512, 532, 598, 441, 508, +157, 266, -86, -83, -241, -413, -328, -614, +-255, -641, -29, -452, 190, -71, 250, 346, +163, 681, -35, 845, -276, 733, -454, 327, +-458, -175, -286, -568, -21, -768, 253, -725, +455, -383, 488, 135, 354, 558, 89, 714, +-233, 595, -493, 258, -594, -178, -525, -537, +-275, -611, 60, -353, 341, 97, 506, 537, +512, 816, 289, 791, -81, 409, -410, -202, +-610, -801, -654, -1141, -473, -1046, -110, -562, +283, 141, 558, 859, 652, 1337, 544, 1362, +262, 942, -131, 243, -518, -497, -746, -1028, +-748, -1201, -592, -1026, -307, -566, 83, 17, +419, 507, 566, 760, 612, 801, 557, 688, +312, 471, -48, 212, -343, -35, -534, -248, +-644, -410, -649, -537, -498, -574, -231, -459, +37, -224, 259, 67, 476, 404, 608, 694, +538, 765, 296, 589, 7, 258, -285, -173, +-530, -556, -637, -715, -549, -587, -349, -251, +-125, 158, 120, 497, 342, 660, 398, 569, +264, 251, 61, -128, -103, -405, -237, -540, +-279, -475, -158, -198, 16, 154, 86, 388, +78, 463, 31, 418, -91, 261, -226, 36, +-288, -123, -277, -155, -182, -124, -22, -100, +119, -88, 183, -113, 175, -187, 99, -255, +5, -209, -67, -6, -110, 279, -121, 557, +-92, 761, -79, 733, -109, 412, -150, -74, +-185, -559, -244, -925, -272, -1005, -183, -732, +12, -213, 210, 374, 366, 841, 403, 1022, +277, 855, 41, 401, -205, -124, -402, -496, +-474, -619, -416, -490, -288, -146, -158, 206, +-31, 360, 65, 280, 109, 28, 100, -294, +109, -502, 149, -449, 188, -135, 211, 313, +188, 739, 31, 963, -236, 843, -501, 377, +-682, -244, -706, -789, -512, -1094, -173, -1043, +214, -628, 563, -1, 756, 608, 703, 982, +436, 1022, 32, 722, -406, 224, -734, -257, +-830, -556, -699, -608, -420, -425, -64, -126, +273, 134, 460, 249, 463, 202, 323, 40, +108, -81, -112, -90, -272, -23, -335, 133, +-291, 329, -179, 374, -76, 216, -9, -18, +30, -245, 4, -425, -74, -421, -145, -197, +-155, 122, -135, 382, -80, 501, 27, 431, +136, 164, 154, -191, 110, -462, 39, -539, +-101, -389, -288, -65, -379, 325, -355, 601, +-256, 647, -76, 469, 152, 131, 273, -260, +250, -541, 134, -600, -40, -435, -234, -139, +-352, 172, -351, 387, -243, 461, -60, 364, +126, 134, 219, -83, 205, -171, 85, -141, +-136, -40, -354, 90, -403, 179, -278, 155, +-89, 17, 94, -173, 235, -304, 263, -318, +129, -205, -94, 5, -277, 240, -377, 401, +-391, 444, -274, 350, -35, 150, 198, -54, +313, -174, 285, -224, 132, -217, -95, -141, +-310, -64, -421, -64, -384, -105, -285, -108, +-174, -55, -25, 64, 139, 241, 224, 408, +260, 500, 244, 467, 123, 279, -70, -32, +-209, -350, -308, -593, -409, -697, -452, -601, +-371, -324, -226, 52, -52, 433, 164, 674, +384, 704, 474, 560, 417, 309, 236, 3, +-27, -246, -324, -367, -564, -391, -682, -355, +-629, -275, -420, -192, -111, -116, 189, -17, +399, 142, 487, 315, 457, 454, 296, 531, +62, 500, -180, 296, -400, -39, -537, -359, +-537, -563, -435, -631, -262, -512, -30, -226, +172, 113, 282, 367, 316, 495, 262, 497, +107, 378, -72, 174, -197, -38, -266, -172, +-265, -199, -202, -183, -139, -170, -132, -143, +-137, -80, -103, -49, -48, -46, -1, 32, +52, 171, 95, 253, 108, 264, 75, 241, +21, 157, -57, -5, -148, -160, -241, -251, +-294, -257, -299, -196, -236, -92, -115, 41, +32, 164, 151, 216, 246, 182, 255, 127, +147, 95, -48, 45, -240, -11, -390, -41, +-433, -52, -350, -89, -180, -131, 5, -128, +174, -92, 287, -20, 306, 116, 220, 250, +43, 283, -200, 205, -417, 80, -501, -77, +-428, -236, -256, -310, -20, -221, 210, -21, +325, 148, 293, 227, 175, 250, 18, 196, +-155, 40, -271, -127, -285, -177, -238, -128, +-169, -40, -95, 53, -83, 117, -151, 107, +-174, 18, -73, -85, 97, -118, 278, -42, +414, 95, 386, 214, 160, 290, -167, 238, +-500, 12, -774, -274, -840, -470, -612, -511, +-173, -360, 321, -7, 763, 432, 967, 759, +796, 843, 294, 635, -302, 188, -790, -384, +-1027, -880, -937, -1092, -545, -940, -24, -473, +448, 165, 703, 776, 672, 1160, 388, 1168, +0, 807, -349, 230, -502, -347, -419, -795, +-208, -996, -10, -885, 101, -573, 63, -201, +-101, 165, -263, 468, -305, 651, -207, 698, +18, 645, 303, 503, 511, 273, 503, -44, +246, -367, -180, -616, -606, -776, -847, -789, +-810, -585, -505, -217, -24, 206, 471, 592, +785, 871, 809, 940, 549, 771, 101, 425, +-398, -8, -791, -439, -904, -772, -687, -902, +-279, -787, 131, -497, 451, -123, 598, 254, +500, 581, 223, 754, -58, 706, -270, 510, +-407, 265, -455, -3, -354, -276, -154, -469, +24, -511, 115, -444, 180, -338, 197, -184, +135, 45, 34, 244, -53, 344, -173, 397, +-288, 381, -331, 230, -260, 28, -112, -95, +87, -153, 256, -197, 337, -163, 290, -45, +131, 55, -106, 43, -347, -23, -535, -73, +-610, -145, -498, -236, -178, -237, 244, -69, +596, 214, 739, 493, 629, 693, 312, 732, +-117, 527, -538, 52, -817, -550, -875, -1053, +-703, -1281, -342, -1129, 99, -589, 503, 210, +778, 1029, 848, 1570, 659, 1649, 265, 1245, +-199, 467, -620, -482, -900, -1302, -942, -1721, +-716, -1651, -292, -1132, 185, -297, 552, 603, +741, 1290, 734, 1578, 532, 1457, 187, 991, +-183, 293, -522, -423, -741, -926, -743, -1148, +-517, -1154, -204, -939, 118, -513, 372, -16, +477, 426, 417, 770, 303, 1010, 151, 1093, +-37, 936, -212, 531, -319, 11, -395, -498, +-398, -966, -310, -1274, -178, -1225, -47, -839, +122, -282, 282, 344, 357, 944, 351, 1318, +287, 1350, 112, 1067, -152, 534, -373, -145, +-474, -801, -486, -1250, -401, -1374, -195, -1185, +55, -715, 252, -32, 361, 679, 400, 1168, +370, 1359, 248, 1272, 27, 864, -194, 183, +-357, -536, -502, -1059, -591, -1313, -490, -1301, +-226, -950, 67, -275, 364, 492, 632, 1063, +706, 1365, 507, 1384, 178, 994, -190, 249, +-595, -536, -888, -1111, -860, -1401, -548, -1347, +-93, -891, 400, -175, 802, 563, 902, 1151, +649, 1464, 179, 1387, -278, 919, -621, 214, +-797, -554, -734, -1209, -427, -1542, -50, -1450, +287, -969, 526, -235, 614, 565, 477, 1216, +190, 1576, -94, 1557, -262, 1111, -372, 372, +-443, -414, -398, -1101, -236, -1580, -83, -1673, +42, -1284, 189, -568, 318, 248, 342, 1013, +261, 1563, 139, 1722, 2, 1402, -173, 737, +-345, -34, -405, -766, -305, -1342, -129, -1610, +31, -1446, 162, -936, 212, -243, 124, 499, +-18, 1135, -61, 1490, -51, 1455, -48, 1064, +25, 454, 160, -238, 217, -853, 145, -1251, +-15, -1325, -255, -1087, -494, -626, -561, -28, +-378, 586, -59, 1061, 271, 1258, 508, 1144, +558, 776, 410, 206, 193, -445, -32, -975, +-247, -1209, -400, -1127, -422, -761, -371, -162, +-259, 484, -97, 953, 56, 1133, 121, 1026, +151, 651, 200, 65, 279, -508, 330, -871, +314, -998, 171, -895, -66, -528, -332, -10, +-527, 455, -577, 790, -456, 945, -229, 833, +67, 514, 378, 89, 567, -377, 541, -775, +355, -942, 78, -846, -222, -560, -390, -130, +-333, 356, -164, 767, -42, 975, 2, 921, +-16, 633, -91, 182, -156, -322, -101, -773, +42, -1027, 180, -970, 294, -638, 375, -150, +327, 386, 107, 845, -194, 1060, -441, 927, +-544, 524, -465, -1, -198, -499, 162, -861, +433, -967, 485, -742, 364, -294, 151, 189, +-100, 600, -342, 867, -463, 863, -398, 551, +-159, 90, 126, -369, 355, -727, 441, -882, +376, -749, 165, -355, -115, 141, -334, 574, +-370, 852, -310, 915, -243, 693, -149, 217, +3, -282, 116, -664, 195, -906, 310, -920, +443, -631, 453, -171, 314, 266, 75, 624, +-247, 853, -622, 874, -867, 700, -820, 378, +-499, -8, -7, -381, 548, -688, 989, -897, +1122, -936, 888, -752, 368, -394, -280, 65, +-862, 568, -1171, 1020, -1094, 1287, -635, 1227, +41, 847, 685, 245, 1052, -490, 1036, -1199, +652, -1625, 13, -1611, -623, -1192, -971, -439, +-905, 508, -507, 1360, 69, 1862, 643, 1866, +990, 1380, 924, 525, 478, -510, -116, -1440, +-616, -1949, -933, -1900, -984, -1377, -710, -499, +-174, 537, 374, 1406, 760, 1866, 927, 1800, +865, 1262, 538, 446, 114, -450, -213, -1239, +-426, -1660, -614, -1572, -711, -1115, -672, -453, +-539, 321, -338, 1018, 5, 1419, 427, 1428, +781, 1101, 968, 526, 990, -186, 824, -849, +437, -1270, -174, -1353, -858, -1102, -1328, -576, +-1404, 110, -1114, 780, -527, 1280, 252, 1435, +932, 1169, 1233, 581, 1157, -174, 879, -944, +487, -1497, 20, -1565, -385, -1095, -571, -307, +-588, 562, -584, 1315, -586, 1702, -535, 1488, +-463, 750, -358, -182, -72, -1021, 446, -1564, +994, -1619, 1340, -1115, 1398, -265, 1076, 598, +350, 1256, -583, 1541, -1402, 1335, -1877, 705, +-1857, -60, -1300, -696, -309, -1114, 822, -1240, +1730, -1010, 2062, -501, 1753, 39, 949, 434, +-81, 724, -1025, 915, -1531, 908, -1474, 672, +-996, 343, -358, 23, 288, -338, 772, -744, +934, -1031, 755, -1039, 420, -802, 64, -413, +-247, 160, -462, 819, -491, 1285, -339, 1364, +-110, 1090, 97, 558, 281, -160, 427, -874, +464, -1335, 359, -1402, 138, -1092, -163, -535, +-491, 131, -746, 744, -823, 1156, -654, 1239, +-227, 1001, 396, 590, 1020, 93, 1401, -453, +1382, -899, 960, -1092, 201, -1028, -726, -774, +-1541, -316, -1944, 264, -1770, 775, -1045, 1070, +54, 1113, 1192, 912, 1976, 466, 2153, -151, +1717, -747, 808, -1120, -306, -1184, -1281, -970, +-1829, -483, -1878, 187, -1450, 806, -647, 1154, +330, 1182, 1153, 938, 1579, 444, 1528, -203, +1134, -772, 551, -1070, -101, -1074, -708, -841, +-1089, -387, -1207, 157, -1121, 583, -820, 819, +-244, 879, 429, 755, 948, 484, 1238, 152, +1358, -197, 1196, -511, 641, -704, -170, -783, +-959, -749, -1583, -539, -1900, -146, -1674, 295, +-854, 660, 279, 923, 1359, 1008, 2143, 792, +2418, 335, 1999, -157, 925, -579, -456, -915, +-1734, -1036, -2584, -859, -2740, -464, -2083, 26, +-830, 504, 609, 866, 1850, 1007, 2637, 854, +2774, 446, 2186, -45, 1030, -441, -352, -699, +-1621, -762, -2505, -570, -2757, -225, -2291, 86, +-1271, 280, -20, 380, 1183, 375, 2129, 255, +2639, 102, 2550, 6, 1852, -8, 678, -31, +-685, -86, -1920, -89, -2709, -54, -2835, -85, +-2203, -145, -1009, -111, 419, -27, 1747, 16, +2694, 61, 2968, 133, 2445, 190, 1245, 169, +-277, 89, -1709, -3, -2644, -90, -2833, -155, +-2242, -172, -1098, -123, 257, -28, 1484, 70, +2327, 150, 2562, 185, 2092, 169, 1070, 78, +-154, -71, -1269, -176, -2040, -190, -2235, -174, +-1796, -151, -941, -36, 38, 145, 965, 211, +1696, 174, 2045, 170, 1864, 176, 1183, 81, +186, -45, -859, -80, -1707, -86, -2119, -154, +-1949, -255, -1237, -300, -213, -245, 857, -137, +1768, 10, 2292, 223, 2221, 486, 1508, 651, +345, 599, -971, 385, -2092, 74, -2676, -346, +-2486, -778, -1559, -1000, -166, -913, 1274, -593, +2393, -81, 2914, 535, 2689, 1050, 1683, 1244, +159, 1062, -1437, 616, -2665, 23, -3227, -622, +-2893, -1116, -1685, -1233, 39, -971, 1719, -514, +2935, 18, 3404, 524, 2962, 866, 1643, 943, +-134, 779, -1829, 498, -3038, 190, -3484, -130, +-2939, -437, -1527, -653, 256, -730, 1909, -691, +3080, -528, 3446, -225, 2840, 184, 1467, 576, +-223, 830, -1811, 911, -2936, 776, -3265, 396, +-2686, -127, -1426, -620, 125, -940, 1594, -1019, +2641, -820, 3021, -370, 2650, 220, 1629, 748, +233, 1020, -1183, 993, -2300, 706, -2869, 201, +-2718, -388, -1887, -838, -611, -982, 800, -840, +2066, -492, 2883, -7, 2998, 506, 2329, 845, +1029, 888, -588, 704, -2091, 367, -3063, -95, +-3203, -561, -2477, -860, -1076, -884, 611, -675, +2172, -288, 3186, 209, 3348, 683, 2556, 968, +1033, 949, -771, 663, -2304, 196, -3168, -365, +-3155, -853, -2288, -1081, -814, -958, 813, -577, +2193, -62, 2991, 486, 3006, 922, 2231, 1090, +876, 933, -709, 549, -2080, 73, -2864, -442, +-2899, -883, -2200, -1082, -937, -986, 562, -673, +1942, -185, 2876, 388, 3084, 862, 2447, 1130, +1138, 1129, -494, 816, -2039, 295, -3055, -278, +-3214, -815, -2488, -1185, -1109, -1213, 576, -925, +2128, -453, 3116, 133, 3276, 748, 2559, 1209, +1135, 1341, -582, 1115, -2088, 640, -3006, 7, +-3113, -695, -2405, -1259, -1128, -1457, 343, -1282, +1708, -827, 2682, -144, 3020, 649, 2609, 1321, +1587, 1660, 184, 1592, -1288, 1137, -2491, 317, +-3075, -712, -2924, -1618, -2096, -2085, -731, -2000, +974, -1361, 2561, -243, 3514, 1067, 3538, 2127, +2644, 2578, 978, 2287, -1096, 1337, -2938, -65, +-3902, -1531, -3769, -2580, -2641, -2847, -755, -2287, +1441, -1087, 3242, 457, 4079, 1907, 3752, 2782, +2385, 2803, 337, 2037, -1775, 761, -3293, -715, +-3803, -1979, -3238, -2615, -1798, -2470, 84, -1706, +1853, -560, 3028, 715, 3338, 1761, 2754, 2271, +1467, 2153, -141, 1504, -1633, 534, -2607, -531, +-2855, -1439, -2384, -1968, -1354, -1963, -7, -1462, +1353, -653, 2371, 308, 2785, 1243, 2537, 1867, +1687, 1979, 305, 1607, -1261, 845, -2476, -213, +-3014, -1259, -2836, -1951, -1893, -2164, -317, -1863, +1438, -1001, 2815, 246, 3486, 1437, 3265, 2230, +2123, 2491, 302, 2106, -1641, 1072, -3142, -340, +-3796, -1663, -3444, -2524, -2137, -2759, -213, -2296, +1789, -1153, 3306, 389, 3989, 1819, 3660, 2736, +2354, 2988, 384, 2479, -1656, 1252, -3221, -354, +-3963, -1836, -3731, -2832, -2525, -3132, -646, -2616, +1381, -1365, 3060, 265, 4040, 1779, 4034, 2811, +2952, 3173, 1062, 2696, -1116, 1449, -3007, -142, +-4110, -1608, -4112, -2687, -3013, -3127, -1111, -2702, +1083, -1526, 2978, -3, 4068, 1464, 4089, 2559, +3044, 3018, 1184, 2645, -983, 1528, -2808, 59, +-3771, -1320, -3703, -2352, -2694, -2844, -1034, -2576, +851, -1570, 2445, -219, 3353, 1077, 3416, 2150, +2670, 2792, 1259, 2679, -456, 1810, -1990, 514, +-2967, -893, -3208, -2181, -2643, -3020, -1420, -3051, +150, -2179, 1694, -692, 2873, 987, 3389, 2520, +3049, 3524, 1825, 3509, 52, 2384, -1739, 598, +-3055, -1342, -3580, -3065, -3111, -4038, -1738, -3753, +143, -2282, 1968, -218, 3296, 1873, 3797, 3540, +3258, 4262, 1726, 3636, -313, 1876, -2197, -298, +-3409, -2274, -3672, -3685, -2939, -4096, -1404, -3209, +503, -1381, 2231, 621, 3333, 2312, 3610, 3437, +2983, 3655, 1508, 2776, -414, 1160, -2149, -566, +-3217, -2020, -3436, -3023, -2781, -3305, -1398, -2638, +338, -1268, 1946, 257, 3085, 1663, 3503, 2789, +3019, 3249, 1684, 2757, -115, 1543, -1844, 22, +-3041, -1538, -3431, -2827, -2908, -3403, -1603, -2977, +115, -1707, 1788, -38, 3021, 1652, 3510, 3012, +3092, 3588, 1808, 3054, -5, 1622, -1803, -174, +-3046, -1920, -3476, -3252, -2991, -3671, -1655, -2923, +204, -1352, 1985, 481, 3223, 2214, 3646, 3444, +3108, 3680, 1626, 2771, -381, 1102, -2260, -793, +-3431, -2502, -3633, -3626, -2831, -3741, -1203, -2703, +804, -888, 2570, 1086, 3602, 2783, 3687, 3853, +2792, 3884, 1073, 2716, -977, 776, -2683, -1287, +-3576, -3043, -3517, -4121, -2518, -4068, -808, -2787, +1093, -743, 2618, 1430, 3473, 3268, 3517, 4327, +2687, 4202, 1113, 2845, -744, 723, -2335, -1516, +-3301, -3363, -3497, -4393, -2831, -4212, -1367, -2796, +486, -655, 2189, 1529, 3373, 3301, 3786, 4274, +3229, 4063, 1763, 2657, -199, 595, -2089, -1473, +-3384, -3137, -3779, -4035, -3186, -3791, -1716, -2437, +273, -510, 2156, 1381, 3407, 2892, 3764, 3694, +3181, 3450, 1706, 2229, -264, 519, -2081, -1224, +-3182, -2678, -3402, -3452, -2756, -3262, -1363, -2187, +410, -567, 1991, 1155, 2961, 2607, 3188, 3440, +2653, 3331, 1394, 2245, -260, 562, -1751, -1262, +-2703, -2853, -2995, -3734, -2508, -3517, -1295, -2261, +271, -370, 1726, 1652, 2763, 3293, 3149, 4046, +2757, 3625, 1579, 2134, -111, 31, -1792, -2094, +-2954, -3679, -3343, -4258, -2822, -3618, -1437, -1941, +419, 277, 2139, 2423, 3242, 3919, 3522, 4321, +2901, 3510, 1428, 1751, -495, -474, -2205, -2594, +-3242, -4004, -3418, -4296, -2649, -3423, -1098, -1642, +739, 590, 2259, 2657, 3100, 4002, 3154, 4287, +2456, 3405, 1117, 1564, -467, -704, -1828, -2778, +-2656, -4105, -2827, -4285, -2258, -3256, -1101, -1370, +285, 875, 1521, 2910, 2398, 4120, 2744, 4139, +2421, 3048, 1470, 1190, 151, -986, -1216, -2908, +-2289, -4010, -2772, -4019, -2545, -2994, -1619, -1213, +-153, 936, 1390, 2879, 2562, 4020, 3117, 4070, +2875, 3098, 1753, 1328, 96, -904, -1604, -2974, +-2884, -4187, -3351, -4250, -2820, -3261, -1476, -1416, +326, 958, 2084, 3126, 3246, 4355, 3489, 4408, +2791, 3378, 1333, 1410, -501, -1089, -2166, -3305, +-3192, -4502, -3320, -4472, -2563, -3349, -1166, -1323, +508, 1216, 2051, 3426, 3075, 4533, 3310, 4399, +2732, 3228, 1487, 1160, -130, -1349, -1741, -3410, +-2885, -4387, -3267, -4246, -2818, -3098, -1698, -1068, +-126, 1361, 1549, 3342, 2862, 4288, 3419, 4159, +3129, 3045, 2044, 1005, 343, -1441, -1484, -3410, +-2815, -4350, -3343, -4189, -3020, -2954, -1882, -806, +-201, 1688, 1515, 3658, 2793, 4469, 3285, 4068, +2885, 2647, 1723, 386, 120, -2097, -1508, -3828, +-2624, -4313, -2928, -3730, -2442, -2227, -1356, 16, +125, 2281, 1572, 3686, 2496, 3972, 2679, 3335, +2219, 1862, 1207, -230, -204, -2223, -1537, -3414, +-2299, -3624, -2399, -3008, -1956, -1651, -982, 235, +345, 2053, 1578, 3132, 2328, 3312, 2455, 2791, +1967, 1584, 939, -193, -387, -1905, -1622, -2934, +-2366, -3190, -2454, -2793, -1885, -1653, -808, 127, +541, 1916, 1783, 3046, 2538, 3394, 2587, 3003, +1996, 1682, 877, -369, -578, -2304, -1930, -3477, +-2695, -3801, -2693, -3172, -1995, -1449, -741, 878, +793, 2886, 2166, 3983, 2917, 4036, 2832, 3002, +2037, 992, 724, -1395, -858, -3291, -2271, -4169, +-3002, -3961, -2900, -2735, -2054, -658, -660, 1635, +1020, 3307, 2475, 3988, 3193, 3733, 2978, 2536, +2055, 548, 641, -1567, -1027, -3056, -2457, -3678, +-3137, -3471, -2948, -2388, -2064, -580, -669, 1313, +992, 2642, 2459, 3249, 3206, 3142, 3076, 2204, +2223, 617, 782, -1017, -963, -2188, -2442, -2797, +-3193, -2793, -3118, -2028, -2244, -656, -760, 765, +975, 1807, 2470, 2404, 3286, 2438, 3171, 1738, +2240, 543, 748, -642, -988, -1514, -2486, -2037, +-3227, -2059, -3050, -1437, -2121, -408, -647, 537, +1065, 1204, 2499, 1659, 3164, 1746, 2938, 1259, +1992, 433, 555, -330, -1077, -969, -2431, -1531, +-3016, -1717, -2751, -1315, -1864, -599, -539, 121, +1059, 893, 2410, 1643, 3030, 1938, 2794, 1588, +1896, 847, 508, -63, -1110, -1079, -2525, -1978, +-3189, -2306, -2894, -1888, -1848, -985, -324, 96, +1398, 1265, 2808, 2241, 3384, 2527, 2968, 2027, +1742, 1099, 58, -44, -1680, -1307, -3022, -2304, +-3502, -2589, -2940, -2162, -1570, -1303, 180, -166, +1922, 1123, 3182, 2170, 3524, 2571, 2821, 2303, +1434, 1569, -245, 436, -1922, -940, -3157, -2075, +-3456, -2550, -2811, -2382, -1516, -1718, 186, -585, +1924, 810, 3129, 1951, 3409, 2487, 2796, 2387, +1543, 1717, -82, 555, -1773, -811, -3023, -1921, +-3391, -2414, -2851, -2258, -1623, -1599, 42, -484, +1779, 865, 3015, 1901, 3358, 2316, 2759, 2190, +1464, 1542, -201, 349, -1781, -984, -2866, -1966, +-3157, -2413, -2564, -2267, -1232, -1493, 397, -238, +1843, 1126, 2752, 2154, 2868, 2568, 2127, 2332, +811, 1483, -609, 110, -1788, -1321, -2490, -2289, +-2500, -2661, -1783, -2440, -618, -1497, 639, -29, +1772, 1368, 2468, 2325, 2424, 2775, 1628, 2528, +409, 1493, -905, 27, -1996, -1379, -2597, -2449, +-2457, -2928, -1564, -2609, -206, -1529, 1202, -13, +2394, 1515, 3044, 2677, 2709, 3157, 1364, 2737, +-365, 1471, -1848, -253, -2885, -1928, -3225, -3125, +-2521, -3464, -972, -2743, 737, -1144, 2158, 813, +3092, 2592, 3222, 3678, 2333, 3644, 651, 2432, +-1120, 448, -2376, -1690, -2966, -3353, -2885, -4007, +-1936, -3432, -379, -1797, 1086, 409, 2079, 2478, +2634, 3779, 2552, 3934, 1641, 2897, 252, 1009, +-1003, -1086, -1842, -2824, -2243, -3780, -2068, -3624, +-1246, -2420, -124, -603, 834, 1341, 1513, 2920, +1898, 3663, 1725, 3363, 913, 2188, -135, 412, +-945, -1548, -1455, -3085, -1599, -3684, -1199, -3261, +-351, -1979, 454, -68, 1012, 1919, 1367, 3288, +1390, 3697, 833, 3073, -91, 1498, -893, -590, +-1334, -2451, -1396, -3522, -1007, -3531, -228, -2493, +552, -697, 1037, 1335, 1237, 2907, 1184, 3499, +769, 3010, 35, 1609, -681, -325, -1065, -2100, +-1085, -3061, -879, -3032, -443, -2112, 121, -557, +532, 1125, 634, 2334, 637, 2726, 622, 2258, +452, 1119, 89, -305, -221, -1516, -321, -2123, +-313, -2032, -341, -1358, -335, -310, -210, 747, +-123, 1412, -152, 1505, -45, 1142, 259, 498, +428, -227, 415, -771, 463, -930, 443, -709, +141, -269, -241, 192, -441, 450, -574, 374, +-663, 56, -526, -319, -75, -549, 416, -485, +708, -93, 801, 462, 746, 953, 384, 1140, +-260, 833, -816, 83, -976, -812, -800, -1524, +-445, -1784, 99, -1357, 777, -292, 1233, 935, +1143, 1879, 618, 2264, -43, 1860, -705, 661, +-1260, -845, -1397, -2053, -869, -2610, -8, -2303, +686, -1130, 1150, 523, 1436, 2044, 1162, 2861, +297, 2662, -550, 1504, -972, -178, -1153, -1841, +-1102, -2912, -561, -2940, 342, -1887, 1004, -224, +1126, 1456, 953, 2685, 564, 2994, -174, 2166, +-947, 611, -1140, -1014, -739, -2268, -272, -2769, +115, -2234, 676, -961, 1169, 467, 1000, 1671, +407, 2338, -19, 2151, -402, 1206, -930, -6, +-1046, -1058, -596, -1718, -104, -1850, 164, -1429, +403, -580, 618, 388, 676, 1111, 549, 1412, +392, 1405, 325, 1128, 223, 490, -85, -341, +-485, -962, -745, -1281, -902, -1441, -1047, -1279, +-909, -630, -213, 187, 748, 860, 1499, 1419, +1920, 1755, 1897, 1517, 1243, 783, 28, -112, +-1297, -1039, -2219, -1823, -2426, -2072, -1996, -1666, +-961, -844, 596, 217, 2078, 1346, 2803, 2142, +2683, 2281, 1791, 1745, 240, 692, -1422, -621, +-2562, -1762, -2849, -2404, -2217, -2391, -884, -1634, +713, -310, 2139, 1105, 2937, 2183, 2780, 2666, +1753, 2333, 190, 1229, -1465, -242, -2711, -1653, +-3092, -2585, -2486, -2715, -1086, -2013, 658, -758, +2269, 702, 3280, 1988, 3363, 2700, 2421, 2594, +713, 1715, -1264, 391, -2893, -1008, -3688, -2220, +-3367, -2870, -1933, -2571, 121, -1418, 2046, 44, +3329, 1447, 3724, 2565, 3096, 2949, 1522, 2288, +-528, 861, -2338, -773, -3299, -2156, -3261, -2878, +-2316, -2651, -684, -1541, 1145, 68, 2400, 1611, +2769, 2562, 2468, 2631, 1677, 1883, 395, 585, +-962, -866, -1807, -2014, -2033, -2460, -1829, -2062, +-1170, -1075, -137, 82, 854, 1113, 1501, 1805, +1799, 1920, 1742, 1447, 1237, 713, 346, -70, +-673, -813, -1518, -1322, -1957, -1462, -1848, -1373, +-1104, -1067, 108, -386, 1330, 445, 2101, 1088, +2320, 1578, 1939, 1877, 901, 1605, -554, 649, +-1782, -553, -2345, -1598, -2229, -2279, -1527, -2380, +-286, -1656, 1143, -181, 2116, 1407, 2325, 2393, +1978, 2593, 1264, 2105, 219, 891, -862, -790, +-1533, -2113, -1741, -2495, -1694, -2081, -1332, -1230, +-486, -65, 511, 1124, 1259, 1781, 1797, 1691, +2134, 1230, 1875, 748, 1009, 193, -113, -431, +-1233, -856, -2129, -1031, -2396, -1201, -1868, -1320, +-707, -1008, 700, -298, 1910, 487, 2560, 1258, +2433, 1887, 1513, 1947, 89, 1276, -1302, 154, +-2167, -1043, -2295, -1913, -1708, -2151, -500, -1709, +935, -683, 1939, 600, 2289, 1568, 2077, 1846, +1227, 1548, -114, 839, -1291, -146, -1961, -1066, +-2121, -1494, -1713, -1306, -728, -765, 523, -169, +1620, 451, 2226, 1047, 2287, 1258, 1848, 902, +892, 390, -342, -16, -1402, -527, -2075, -1099, +-2333, -1223, -2041, -851, -1131, -411, 197, 31, +1513, 630, 2449, 1147, 2860, 1235, 2570, 949, +1505, 520, -16, 3, -1475, -603, -2570, -1166, +-3005, -1399, -2544, -1208, -1224, -737, 482, -77, +1999, 714, 2906, 1391, 3003, 1637, 2193, 1353, +705, 625, -903, -371, -2080, -1297, -2533, -1756, +-2205, -1520, -1206, -705, 176, 357, 1453, 1267, +2178, 1671, 2257, 1337, 1749, 341, 667, -815, +-649, -1546, -1628, -1609, -1994, -1050, -1869, 31, +-1244, 1262, -89, 1952, 1237, 1750, 2122, 879, +2425, -255, 2212, -1335, 1278, -1989, -310, -1896, +-1786, -1072, -2571, 62, -2682, 1009, -2064, 1545, +-619, 1636, 1173, 1271, 2518, 531, 3031, -324, +2757, -962, 1754, -1254, 142, -1260, -1558, -998, +-2631, -396, -2790, 345, -2140, 904, -867, 1185, +745, 1146, 2082, 726, 2608, 25, 2254, -708, +1332, -1197, 80, -1217, -1171, -778, -1928, -123, +-1856, 610, -1115, 1211, -76, 1328, 938, 891, +1623, 215, 1655, -488, 986, -1148, 19, -1480, +-766, -1261, -1202, -663, -1226, 84, -724, 886, +152, 1517, 917, 1644, 1292, 1256, 1282, 544, +877, -339, 100, -1190, -680, -1714, -1090, -1700, +-1060, -1178, -737, -382, -221, 444, 378, 1152, +949, 1516, 1262, 1396, 1112, 1013, 584, 537, +-44, -64, -647, -686, -1100, -1091, -1107, -1323, +-625, -1447, 12, -1227, 609, -542, 1184, 410, +1470, 1348, 1114, 1997, 306, 2104, -547, 1516, +-1252, 320, -1570, -1091, -1204, -2112, -326, -2379, +655, -1901, 1421, -835, 1731, 553, 1434, 1714, +687, 2108, -238, 1727, -1067, 963, -1552, 86, +-1430, -793, -712, -1384, 177, -1387, 848, -1051, +1291, -734, 1386, -315, 866, 367, 18, 960, +-532, 1192, -731, 1266, -796, 1199, -577, 622, +19, -411, 556, -1284, 699, -1646, 581, -1620, +369, -1217, -23, -311, -443, 835, -583, 1579, +-368, 1705, -36, 1446, 231, 888, 437, -3, +612, -919, 584, -1412, 294, -1490, 1, -1365, +-159, -932, -360, -97, -532, 849, -404, 1492, +-137, 1705, -37, 1503, 46, 842, 345, -244, +677, -1350, 730, -1890, 550, -1685, 297, -1020, +-41, -78, -461, 1032, -720, 1722, -714, 1486, +-504, 734, -162, 15, 236, -668, 575, -1192, +837, -1065, 913, -390, 642, 190, 116, 490, +-342, 656, -629, 545, -812, 70, -766, -413, +-357, -552, 174, -412, 550, -181, 815, 133, +985, 535, 793, 789, 203, 645, -430, 132, +-812, -430, -956, -833, -782, -1081, -232, -983, +439, -325, 850, 601, 944, 1259, 754, 1452, +321, 1186, -208, 376, -583, -748, -675, -1591, +-465, -1706, -99, -1139, 192, -194, 338, 823, +366, 1549, 199, 1554, -108, 834, -232, -70, +-4, -772, 308, -1169, 424, -1020, 388, -321, +281, 379, -63, 587, -581, 421, -858, 114, +-691, -262, -297, -515, 179, -358, 704, 216, +1127, 783, 1138, 916, 639, 608, -86, 66, +-687, -620, -1076, -1281, -1186, -1440, -848, -885, +-124, -12, 585, 734, 1029, 1324, 1219, 1655, +1040, 1343, 413, 399, -298, -613, -745, -1254, +-965, -1578, -953, -1620, -545, -1062, 43, 53, +469, 1069, 697, 1547, 798, 1680, 648, 1475, +270, 586, -125, -703, -363, -1518, -458, -1614, +-413, -1403, -221, -938, 12, 28, 77, 1109, +23, 1525, 38, 1230, 77, 844, 50, 454, +120, -272, 346, -1060, 470, -1236, 367, -914, +226, -699, 20, -437, -446, 293, -959, 1069, +-1037, 1257, -672, 1027, -110, 779, 543, 281, +1185, -665, 1513, -1502, 1281, -1549, 527, -978, +-403, -345, -1233, 360, -1768, 1245, -1715, 1653, +-948, 1101, 177, 246, 1161, -281, 1746, -726, +1811, -1141, 1307, -978, 388, -205, -637, 355, +-1418, 323, -1734, 196, -1561, 285, -968, 202, +-38, -159, 952, -161, 1611, 334, 1707, 521, +1385, 132, 742, -162, -246, -150, -1294, -362, +-1820, -697, -1723, -497, -1211, 88, -258, 319, +1010, 235, 1911, 346, 1981, 534, 1352, 341, +309, -67, -890, -179, -1792, -116, -1944, -354, +-1302, -681, -273, -560, 769, -145, 1619, 110, +1942, 419, 1390, 951, 253, 1137, -809, 636, +-1497, -107, -1794, -694, -1437, -1174, -451, -1466, +582, -1173, 1221, -253, 1512, 752, 1461, 1364, +931, 1564, 39, 1397, -801, 778, -1324, -199, +-1471, -1085, -1188, -1505, -488, -1486, 343, -1206, +941, -638, 1196, 246, 1099, 1062, 632, 1435, +18, 1452, -448, 1224, -687, 616, -765, -305, +-555, -1100, -74, -1486, 270, -1465, 244, -1060, +118, -304, 47, 548, -38, 1136, -107, 1300, +23, 1077, 258, 580, 332, -51, 153, -659, +-115, -963, -269, -856, -296, -561, -293, -240, +-159, 206, 164, 641, 440, 732, 393, 522, +101, 238, -207, -126, -453, -521, -646, -673, +-582, -485, -128, -123, 486, 265, 868, 545, +909, 585, 704, 327, 324, -78, -270, -414, +-889, -553, -1173, -435, -1074, -109, -767, 300, +-191, 576, 611, 496, 1218, 139, 1311, -235, +1001, -493, 478, -602, -164, -450, -792, -26, +-1139, 434, -1062, 648, -667, 584, -187, 376, +244, 124, 604, -198, 776, -510, 585, -586, +246, -492, 73, -431, -19, -284, -269, 70, +-485, 466, -437, 653, -353, 690, -356, 705, +-129, 488, 376, -83, 763, -658, 709, -894, +363, -862, -18, -687, -495, -269, -1049, 266, +-1159, 588, -562, 655, 252, 625, 798, 505, +1157, 270, 1295, -15, 885, -226, -115, -384, +-1041, -549, -1309, -629, -1149, -546, -888, -245, +-283, 199, 619, 530, 1127, 671, 907, 652, +570, 391, 442, -99, 93, -480, -457, -529, +-580, -409, -293, -186, -278, 193, -536, 477, +-395, 372, 4, 12, 70, -259, 49, -358, +402, -379, 721, -258, 534, 102, 173, 470, +62, 545, -112, 353, -576, 140, -862, -86, +-615, -414, -209, -585, 21, -377, 276, -39, +685, 168, 831, 302, 459, 408, -54, 349, +-345, 79, -599, -299, -865, -529, -704, -455, +-42, -230, 546, 47, 753, 456, 742, 791, +576, 712, 114, 284, -463, -221, -744, -705, +-670, -973, -470, -804, -213, -297, 104, 277, +406, 685, 499, 735, 405, 481, 312, 150, +299, -133, 238, -294, 5, -181, -288, 133, +-484, 240, -701, 19, -826, -301, -583, -639, +-29, -838, 496, -633, 863, -16, 1073, 715, +935, 1208, 386, 1257, -258, 851, -749, 157, +-1003, -621, -1013, -1238, -714, -1319, -186, -848, +292, -262, 609, 190, 799, 559, 762, 797, +459, 772, 113, 535, -66, 343, -266, 220, +-562, -49, -681, -483, -552, -850, -391, -930, +-220, -800, 89, -527, 487, 99, 738, 942, +803, 1443, 727, 1321, 483, 795, -18, 76, +-691, -773, -1212, -1489, -1280, -1687, -946, -1249, +-334, -361, 527, 593, 1367, 1335, 1665, 1761, +1344, 1668, 651, 938, -297, -128, -1281, -1092, +-1813, -1733, -1616, -1947, -830, -1522, 161, -477, +1042, 722, 1534, 1588, 1426, 1929, 803, 1715, +35, 928, -605, -228, -960, -1209, -984, -1619, +-685, -1497, -253, -965, 92, -109, 294, 684, +376, 990, 387, 865, 402, 603, 354, 269, +232, -133, 59, -376, -142, -266, -347, -42, +-506, -56, -448, -260, -205, -375, -17, -362, +132, -301, 289, -89, 309, 368, 166, 804, +143, 887, 282, 598, 323, 150, 235, -362, +76, -926, -267, -1222, -743, -939, -1049, -295, +-865, 352, -322, 818, 361, 1091, 1073, 1101, +1574, 725, 1563, 84, 887, -512, -192, -864, +-1154, -1002, -1797, -981, -1929, -684, -1384, -170, +-373, 316, 666, 697, 1470, 1021, 1951, 1187, +1848, 956, 1094, 336, 180, -310, -684, -835, +-1510, -1218, -1965, -1287, -1767, -925, -1122, -235, +-271, 486, 713, 1008, 1670, 1231, 2144, 1009, +1847, 463, 975, -132, -30, -606, -994, -859, +-1761, -821, -1960, -494, -1461, -8, -618, 428, +296, 649, 1168, 555, 1729, 276, 1700, -44, +1142, -408, 350, -649, -456, -573, -1142, -240, +-1525, 165, -1453, 505, -918, 764, -144, 740, +668, 327, 1368, -142, 1696, -466, 1428, -700, +615, -761, -363, -534, -1085, -116, -1491, 284, +-1439, 541, -878, 541, -72, 393, 678, 297, +1124, 98, 1172, -230, 912, -354, 402, -266, +-188, -201, -613, -115, -670, 108, -510, 264, +-418, 160, -308, -15, -48, -156, 183, -364, +207, -465, 197, -285, 359, 62, 442, 485, +359, 933, 280, 1064, 175, 627, -93, -90, +-418, -775, -625, -1347, -669, -1537, -541, -1105, +-178, -168, 312, 891, 802, 1624, 1073, 1731, +979, 1220, 557, 342, -107, -627, -804, -1403, +-1236, -1638, -1260, -1237, -806, -488, 12, 312, +887, 962, 1447, 1239, 1502, 1097, 1024, 662, +104, 60, -858, -500, -1369, -779, -1329, -862, +-951, -807, -346, -435, 448, 143, 1035, 534, +1099, 648, 828, 607, 458, 430, 22, 129, +-302, -203, -376, -410, -332, -348, -421, -131, +-589, 38, -624, 50, -466, -113, -173, -293, +290, -306, 827, -194, 1225, 8, 1274, 406, +921, 900, 230, 1039, -641, 594, -1351, -121, +-1615, -804, -1384, -1354, -691, -1489, 242, -926, +1139, 131, 1683, 1080, 1657, 1580, 1127, 1595, +243, 1049, -724, 15, -1347, -1141, -1411, -1825, +-1009, -1645, -372, -855, 412, 168, 1011, 1140, +1104, 1661, 774, 1498, 259, 755, -242, -241, +-576, -1160, -659, -1708, -396, -1499, -16, -551, +261, 557, 319, 1308, 174, 1590, 33, 1386, +-77, 524, -130, -711, -34, -1540, 142, -1687, +292, -1244, 241, -306, 40, 824, -136, 1646, +-336, 1704, -472, 1073, -380, 167, -142, -806, +135, -1543, 396, -1735, 647, -1251, 732, -208, +583, 864, 311, 1517, -37, 1661, -533, 1293, +-963, 498, -1048, -506, -792, -1323, -405, -1722, +164, -1625, 959, -928, 1595, 93, 1608, 1049, +1057, 1720, 237, 1829, -703, 1402, -1505, 546, +-1782, -626, -1415, -1625, -600, -2038, 360, -1829, +1177, -1069, 1638, 137, 1592, 1396, 962, 2068, +9, 2020, -810, 1450, -1199, 346, -1283, -992, +-1038, -1928, -331, -2132, 452, -1643, 882, -660, +1104, 555, 1080, 1534, 588, 1929, -247, 1748, +-876, 994, -1037, -97, -944, -1063, -568, -1707, +213, -1804, 1000, -1198, 1255, -201, 939, 713, +388, 1316, -297, 1580, -991, 1330, -1219, 475, +-804, -485, -113, -1068, 522, -1292, 1008, -1168, +1200, -536, 857, 360, 75, 891, -723, 927, +-1050, 823, -893, 514, -484, -150, 65, -766, +625, -868, 955, -540, 910, -208, 562, 79, +96, 483, -497, 667, -938, 435, -895, 157, +-535, 21, -94, -141, 374, -374, 741, -440, +812, -260, 613, -169, 306, -219, -145, -95, +-600, 238, -774, 509, -616, 573, -269, 562, +109, 439, 446, 22, 642, -453, 538, -765, +234, -903, -82, -776, -288, -365, -407, 196, +-410, 670, -239, 929, 44, 982, 259, 706, +351, 255, 392, -140, 399, -600, 209, -993, +-83, -1010, -227, -734, -274, -391, -351, -22, +-337, 514, -118, 1012, 189, 1125, 341, 919, +320, 562, 326, 105, 292, -484, 48, -1058, +-182, -1210, -102, -993, 107, -662, 65, -178, +-85, 411, -127, 915, -240, 1128, -503, 1077, +-560, 904, -180, 471, 375, -160, 725, -757, +942, -1259, 976, -1490, 605, -1316, -207, -764, +-1032, 72, -1334, 974, -1176, 1692, -785, 1939, +-42, 1599, 859, 726, 1374, -438, 1269, -1351, +873, -1831, 373, -1979, -391, -1540, -1077, -532, +-1221, 524, -919, 1273, -499, 1737, -65, 1913, +548, 1557, 1112, 726, 1241, -187, 1003, -1054, +601, -1782, -23, -2125, -798, -1900, -1389, -1147, +-1444, -105, -1026, 1036, -338, 2038, 464, 2512, +1264, 2267, 1765, 1395, 1692, 163, 1024, -1180, +-21, -2295, -1033, -2714, -1651, -2349, -1756, -1444, +-1348, -162, -523, 1223, 428, 2263, 1112, 2619, +1387, 2281, 1374, 1416, 1023, 210, 315, -1012, +-378, -1891, -757, -2290, -916, -2107, -990, -1394, +-807, -501, -385, 361, 0, 1221, 243, 1862, +559, 1996, 811, 1752, 770, 1278, 608, 406, +495, -704, 194, -1641, -352, -2279, -777, -2471, +-823, -1951, -755, -808, -683, 578, -322, 1841, +273, 2678, 754, 2791, 968, 2051, 999, 701, +851, -760, 401, -1883, -220, -2478, -692, -2489, +-920, -1793, -954, -583, -748, 563, -375, 1378, +77, 1938, 547, 2095, 935, 1639, 1073, 782, +902, -94, 507, -874, 57, -1473, -456, -1751, +-885, -1627, -1134, -1023, -1165, -187, -824, 441, +-207, 932, 431, 1391, 1014, 1465, 1431, 1005, +1438, 479, 960, 162, 326, -262, -332, -808, +-1144, -1085, -1756, -1114, -1766, -1099, -1257, -960, +-486, -515, 403, 156, 1367, 834, 2037, 1463, +2047, 1893, 1467, 1818, 650, 1217, -328, 284, +-1432, -802, -2175, -1913, -2168, -2671, -1681, -2574, +-838, -1693, 360, -418, 1574, 1049, 2202, 2348, +2152, 3045, 1795, 2876, 1097, 1847, -62, 293, +-1241, -1284, -1997, -2425, -2234, -2912, -2037, -2629, +-1375, -1500, -228, -30, 1001, 1116, 1832, 1789, +2228, 2077, 2305, 1884, 1839, 1093, 618, 164, +-838, -333, -1905, -592, -2504, -851, -2590, -979, +-1893, -969, -584, -955, 805, -930, 1857, -699, +2483, -198, 2483, 484, 1683, 1272, 404, 1829, +-843, 1885, -1792, 1535, -2196, 825, -1960, -219, +-1181, -1329, -125, -2113, 849, -2311, 1421, -2009, +1464, -1337, 1111, -361, 502, 801, -118, 1863, +-438, 2407, -478, 2421, -347, 2120, -141, 1318, +0, -8, -41, -1412, -314, -2462, -609, -2994, +-598, -2957, -321, -2189, 72, -722, 537, 980, +1034, 2476, 1225, 3436, 956, 3581, 448, 2798, +-104, 1276, -736, -552, -1300, -2303, -1429, -3576, +-1045, -3872, -523, -3091, -14, -1608, 570, 118, +1146, 1822, 1414, 3216, 1202, 3733, 699, 3159, +104, 1969, -530, 523, -1085, -1066, -1299, -2478, +-1086, -3234, -699, -3136, -224, -2452, 331, -1423, +720, -12, 826, 1578, 804, 2817, 665, 3278, +409, 3057, 130, 2351, -81, 977, -349, -906, +-649, -2516, -821, -3391, -754, -3577, -538, -3010, +-235, -1526, 187, 451, 646, 2186, 915, 3379, +831, 3824, 486, 3217, 213, 1699, 58, -239, +-169, -2014, -304, -3185, -253, -3529, -314, -2873, +-625, -1360, -880, 427, -823, 1869, -571, 2577, +-93, 2519, 712, 1769, 1524, 544, 1894, -624, +1691, -1290, 883, -1372, -296, -1023, -1479, -422, +-2221, 237, -2271, 571, -1685, 417, -658, -9, +538, -473, 1480, -763, 1938, -723, 1851, -324, +1336, 352, 593, 1018, -223, 1468, -830, 1568, +-1145, 1163, -1243, 363, -1096, -605, -799, -1530, +-477, -2086, -162, -2104, 186, -1640, 542, -789, +860, 370, 1145, 1537, 1321, 2317, 1275, 2544, +987, 2195, 300, 1336, -669, 207, -1603, -1039, +-2237, -2153, -2468, -2688, -2043, -2592, -812, -2109, +752, -1189, 2099, 214, 3089, 1651, 3352, 2605, +2563, 3113, 990, 3122, -778, 2231, -2344, 590, +-3506, -1177, -3758, -2702, -2850, -3684, -1223, -3718, +613, -2720, 2305, -1030, 3524, 946, 3851, 2735, +3098, 3744, 1547, 3647, -399, 2613, -2355, 988, +-3716, -841, -4061, -2396, -3247, -3192, -1537, -3064, +554, -2182, 2475, -771, 3761, 795, 4024, 1947, +3122, 2431, 1227, 2277, -965, 1503, -2690, 289, +-3639, -896, -3691, -1648, -2658, -1871, -762, -1543, +1211, -617, 2723, 543, 3648, 1388, 3591, 1748, +2267, 1591, 262, 770, -1568, -520, -2932, -1657, +-3681, -2230, -3338, -2174, -1811, -1357, 196, 115, +2033, 1669, 3305, 2755, 3661, 3121, 2874, 2598, +1250, 1145, -605, -836, -2190, -2605, -3229, -3630, +-3446, -3662, -2658, -2657, -1063, -924, 656, 1028, +2085, 2768, 3059, 3784, 3254, 3714, 2536, 2718, +1178, 1212, -460, -526, -2067, -2186, -3185, -3321, +-3372, -3657, -2625, -3192, -1175, -2043, 678, -407, +2372, 1430, 3282, 3000, 3199, 3852, 2290, 3735, +720, 2664, -1131, 922, -2493, -1021, -2991, -2697, +-2691, -3681, -1681, -3609, -104, -2523, 1459, -993, +2410, 490, 2571, 1810, 2081, 2758, 1028, 2854, +-328, 2164, -1496, 1296, -2076, 405, -2113, -680, +-1632, -1645, -603, -2109, 591, -2121, 1500, -1786, +1958, -1048, 1896, 31, 1271, 1131, 265, 1806, +-752, 1878, -1539, 1503, -1911, 809, -1656, -195, +-931, -1051, -105, -1212, 677, -862, 1358, -404, +1725, 163, 1506, 683, 881, 665, 134, 79, +-636, -497, -1238, -829, -1420, -1039, -1267, -892, +-901, -163, -430, 773, 153, 1409, 743, 1628, +1095, 1553, 1195, 1096, 1194, 173, 1036, -881, +592, -1600, -68, -1916, -743, -1951, -1347, -1562, +-1794, -639, -1827, 408, -1378, 1200, -531, 1752, +608, 2069, 1777, 1949, 2567, 1342, 2638, 531, +2012, -238, 825, -1004, -651, -1727, -1982, -2152, +-2823, -2133, -3053, -1768, -2489, -1149, -1157, -232, +539, 975, 1999, 2111, 2929, 2798, 3133, 2984, +2516, 2667, 1300, 1667, -189, 58, -1579, -1676, +-2546, -3069, -2899, -3865, -2495, -3871, -1473, -2960, +-210, -1221, 948, 877, 1734, 2744, 2102, 4016, +2024, 4465, 1548, 3832, 922, 2244, 200, 241, +-562, -1728, -1180, -3323, -1529, -4159, -1708, -4041, +-1716, -3079, -1380, -1568, -624, 187, 285, 1832, +1165, 3059, 1900, 3662, 2348, 3547, 2260, 2777, +1520, 1553, 400, 18, -702, -1557, -1633, -2776, +-2277, -3424, -2442, -3483, -2069, -2917, -1233, -1734, +-121, -202, 985, 1296, 1873, 2576, 2454, 3445, +2577, 3728, 2053, 3298, 1017, 2124, -174, 473, +-1304, -1316, -2333, -2993, -2896, -4179, -2614, -4468, +-1645, -3694, -478, -2056, 766, 129, 2007, 2427, +2809, 4224, 2693, 4987, 1895, 4517, 899, 2924, +-253, 614, -1477, -1850, -2298, -3803, -2416, -4669, +-1994, -4296, -1201, -2922, -81, -937, 1009, 1182, +1630, 2841, 1820, 3519, 1716, 3262, 1245, 2367, +475, 1018, -273, -440, -819, -1494, -1254, -1933, +-1456, -1933, -1265, -1659, -773, -1088, -206, -373, +366, 195, 882, 532, 1233, 814, 1238, 1082, +929, 1163, 440, 1013, -102, 751, -617, 372, +-928, -172, -946, -806, -753, -1257, -484, -1312, +-211, -1084, 71, -714, 377, -76, 671, 747, +897, 1295, 940, 1327, 735, 1073, 363, 657, +-143, -3, -755, -767, -1273, -1215, -1451, -1203, +-1208, -956, -597, -547, 254, 106, 1012, 765, +1484, 1088, 1635, 1071, 1396, 905, 736, 579, +-82, 44, -819, -525, -1386, -933, -1749, -1163, +-1702, -1168, -1228, -893, -556, -384, 258, 223, +1294, 856, 2190, 1401, 2458, 1577, 2068, 1288, +1222, 686, 4, -75, -1381, -798, -2445, -1345, +-2857, -1559, -2579, -1366, -1637, -895, -164, -298, +1347, 297, 2346, 732, 2704, 949, 2483, 1063, +1686, 1185, 529, 1151, -564, 866, -1420, 452, +-1962, -92, -2102, -860, -1813, -1651, -1272, -2127, +-592, -2158, 165, -1776, 961, -836, 1630, 627, +1994, 2031, 1978, 2892, 1646, 3170, 990, 2810, +-11, 1665, -1207, -120, -2145, -1893, -2470, -3158, +-2254, -3758, -1513, -3493, -317, -2285, 890, -494, +1696, 1332, 2022, 2818, 1888, 3696, 1311, 3636, +487, 2628, -218, 1063, -600, -552, -687, -1895, +-628, -2799, -682, -3080, -860, -2623, -1047, -1642, +-1079, -497, -886, 592, -396, 1540, 433, 2174, +1444, 2300, 2191, 1988, 2398, 1459, 1981, 704, +1008, -265, -326, -1153, -1689, -1681, -2637, -1916, +-2850, -1896, -2370, -1525, -1380, -844, -16, -22, +1352, 793, 2248, 1468, 2541, 1883, 2324, 1922, +1621, 1581, 534, 902, -585, 31, -1409, -810, +-1824, -1423, -1893, -1699, -1600, -1597, -1049, -1168, +-447, -575, 99, -5, 665, 491, 1209, 770, +1565, 810, 1626, 835, 1474, 916, 1083, 925, +370, 821, -539, 647, -1366, 345, -1920, -277, +-2141, -1102, -1880, -1753, -1077, -2016, -13, -1906, +1022, -1384, 1788, -345, 2098, 1024, 1996, 2169, +1556, 2721, 784, 2642, -125, 1997, -974, 817, +-1720, -697, -2294, -2000, -2257, -2671, -1518, -2718, +-540, -2154, 452, -1038, 1574, 324, 2439, 1421, +2495, 1978, 1833, 2076, 872, 1732, -336, 953, +-1623, 42, -2362, -621, -2233, -878, -1531, -923, +-589, -845, 473, -609, 1373, -369, 1712, -304, +1443, -328, 853, -256, 178, -90, -469, 104, +-893, 439, -958, 879, -650, 1193, -119, 1254, +395, 1059, 571, 574, 352, -154, -66, -995, +-444, -1709, -703, -2086, -661, -1987, -207, -1358, +442, -292, 933, 942, 1209, 1958, 1211, 2486, +694, 2500, -255, 1901, -1123, 720, -1529, -653, +-1504, -1712, -1122, -2330, -373, -2521, 543, -2107, +1163, -1137, 1314, -31, 1209, 925, 935, 1678, +385, 2177, -233, 2227, -516, 1791, -603, 1020, +-834, 103, -1070, -896, -944, -1887, -647, -2542, +-413, -2544, -6, -1937, 740, -897, 1344, 451, +1539, 1866, 1503, 2817, 1208, 2947, 370, 2372, +-735, 1253, -1547, -320, -1955, -1823, -2093, -2665, +-1757, -2793, -766, -2386, 469, -1363, 1492, 143, +2211, 1480, 2509, 2190, 2122, 2362, 1075, 2045, +-257, 1247, -1478, 164, -2337, -794, -2560, -1353, +-2040, -1539, -1015, -1443, 215, -1125, 1350, -664, +2111, -173, 2195, 173, 1610, 482, 609, 860, +-463, 1165, -1250, 1267, -1484, 1175, -1280, 871, +-738, 294, -3, -447, 660, -1084, 959, -1527, +826, -1670, 396, -1394, -194, -770, -782, -46, +-1041, 588, -798, 1098, -274, 1466, 315, 1499, +898, 1147, 1333, 637, 1356, 172, 950, -307, +262, -848, -569, -1213, -1318, -1195, -1731, -1007, +-1687, -803, -1293, -516, -663, -87, 204, 316, +1144, 583, 1701, 875, 1835, 1208, 1732, 1372, +1349, 1302, 550, 1033, -348, 518, -1051, -343, +-1649, -1310, -2132, -2083, -2129, -2510, -1578, -2397, +-834, -1621, -44, -383, 1019, 987, 2154, 2264, +2741, 3179, 2705, 3307, 2218, 2559, 1181, 1253, +-306, -249, -1770, -1745, -2812, -2947, -3321, -3497, +-3136, -3184, -2121, -2133, -594, -695, 929, 774, +2171, 2030, 2966, 2843, 3163, 3008, 2619, 2554, +1548, 1712, 327, 627, -818, -524, -1835, -1514, +-2552, -2154, -2701, -2462, -2281, -2476, -1634, -2044, +-822, -1109, 259, 85, 1364, 1195, 2111, 2018, +2465, 2517, 2526, 2498, 2181, 1886, 1328, 938, +176, -13, -1038, -840, -2131, -1480, -2823, -1751, +-2861, -1667, -2321, -1546, -1349, -1411, -83, -1040, +1183, -397, 2056, 334, 2423, 1101, 2355, 1946, +1934, 2641, 1230, 2739, 394, 2122, -396, 986, +-1046, -460, -1589, -1999, -2033, -3161, -2249, -3456, +-2064, -2860, -1416, -1698, -448, -185, 667, 1406, +1780, 2624, 2577, 3020, 2713, 2600, 2194, 1719, +1330, 635, 316, -453, -713, -1262, -1578, -1588, +-2022, -1443, -2008, -1147, -1708, -871, -1318, -578, +-832, -314, -296, -213, 279, -120, 914, 288, +1570, 890, 2067, 1310, 2306, 1515, 2153, 1529, +1485, 1211, 414, 468, -833, -412, -1986, -1096, +-2822, -1557, -3169, -1844, -2890, -1762, -1920, -1263, +-486, -646, 1031, -78, 2352, 636, 3334, 1461, +3629, 2009, 3003, 2101, 1764, 1875, 307, 1316, +-1170, 371, -2514, -806, -3273, -1836, -3222, -2433, +-2551, -2484, -1521, -1987, -252, -1058, 984, 136, +1971, 1281, 2475, 1965, 2475, 2141, 2111, 1922, +1533, 1328, 746, 372, -203, -539, -1038, -1013, +-1619, -1167, -2027, -1159, -2141, -946, -1831, -591, +-1330, -246, -728, -42, 99, 53, 1044, 132, +1736, 273, 2134, 457, 2346, 622, 2176, 733, +1477, 748, 443, 600, -635, 349, -1624, 27, +-2416, -357, -2793, -652, -2514, -767, -1774, -826, +-820, -870, 270, -786, 1458, -492, 2406, -164, +2804, 161, 2666, 639, 2181, 1193, 1307, 1536, +92, 1488, -1154, 1133, -2120, 590, -2748, -183, +-2972, -1030, -2592, -1647, -1643, -1848, -383, -1753, +858, -1428, 1917, -746, 2754, 135, 3117, 882, +2717, 1536, 1806, 2126, 726, 2329, -527, 1931, +-1866, 1162, -2788, 132, -2956, -1126, -2571, -2200, +-1799, -2647, -739, -2511, 425, -1916, 1388, -846, +1993, 466, 2237, 1485, 2228, 1976, 1938, 2093, +1347, 1925, 473, 1403, -479, 702, -1376, 26, +-2169, -622, -2680, -1293, -2623, -1819, -1941, -1971, +-814, -1726, 496, -1183, 1682, -336, 2491, 742, +2736, 1658, 2324, 1963, 1386, 1731, 313, 1169, +-611, 379, -1325, -423, -1708, -921, -1646, -966, +-1343, -678, -1022, -280, -573, 31, -43, 108, +314, -54, 478, -445, 691, -786, 941, -765, +1075, -406, 1126, 110, 1165, 727, 1004, 1357, +499, 1699, -246, 1457, -995, 794, -1683, 54, +-2213, -628, -2228, -1241, -1584, -1633, -592, -1661, +491, -1346, 1543, -894, 2340, -351, 2555, 358, +2081, 1165, 1166, 1744, 168, 1902, -753, 1810, +-1479, 1433, -1824, 524, -1697, -619, -1337, -1516, +-944, -1980, -449, -2090, 178, -1801, 677, -1058, +831, -110, 917, 717, 1195, 1256, 1300, 1502, +1032, 1539, 744, 1297, 457, 835, -139, 355, +-931, -62, -1465, -518, -1670, -931, -1739, -1110, +-1528, -1116, -851, -1084, 168, -839, 1125, -374, +1769, 29, 2047, 346, 1904, 728, 1268, 993, +407, 980, -375, 863, -904, 841, -1276, 748, +-1432, 474, -1224, 120, -809, -276, -480, -785, +-251, -1413, -19, -1967, 222, -2130, 470, -1784, +792, -921, 1148, 338, 1312, 1743, 1238, 2861, +935, 3316, 441, 2971, -189, 1870, -885, 288, +-1536, -1343, -1985, -2659, -2055, -3314, -1653, -3176, +-849, -2388, 185, -1215, 1290, 152, 2162, 1410, +2549, 2251, 2296, 2621, 1615, 2556, 693, 2023, +-409, 1181, -1495, 248, -2144, -699, -2275, -1570, +-1981, -2108, -1362, -2230, -544, -2031, 239, -1533, +882, -737, 1423, 137, 1746, 942, 1764, 1649, +1542, 2094, 1138, 2156, 474, 1903, -345, 1342, +-1044, 459, -1518, -605, -1884, -1523, -1973, -2161, +-1594, -2414, -915, -2178, -128, -1479, 734, -456, +1579, 586, 2126, 1385, 2199, 1920, 1793, 2137, +1125, 1947, 248, 1374, -756, 679, -1599, -57, +-1956, -899, -1954, -1630, -1700, -1972, -1126, -1977, +-294, -1676, 427, -951, 902, 37, 1318, 860, +1711, 1429, 1810, 1792, 1497, 1776, 995, 1336, +349, 768, -521, 184, -1434, -420, -2061, -948, +-2250, -1317, -1925, -1513, -1151, -1480, -121, -1126, +909, -495, 1707, 247, 2065, 990, 1942, 1502, +1484, 1634, 693, 1377, -283, 805, -1042, 32, +-1340, -720, -1376, -1175, -1243, -1285, -824, -1102, +-188, -575, 245, 124, 431, 667, 535, 872, +548, 820, 417, 512, 300, -107, 315, -760, +350, -979, 286, -701, 202, -192, 94, 432, +-129, 1103, -416, 1401, -695, 1028, -854, 238, +-818, -564, -602, -1231, -237, -1558, 226, -1282, +687, -473, 997, 375, 1046, 895, 851, 1091, +492, 950, 23, 442, -463, -150, -839, -479, +-903, -431, -762, -197, -540, 81, -153, 300, +321, 357, 572, 161, 519, -267, 310, -647, +97, -729, -125, -587, -271, -285, -201, 163, +30, 675, 212, 951, 310, 847, 448, 532, +494, 128, 157, -369, -364, -746, -686, -717, +-806, -364, -912, -41, -850, 168, -361, 304, +292, 274, 682, -1, 984, -339, 1341, -481, +1392, -294, 911, 83, 177, 456, -522, 714, +-1149, 752, -1607, 495, -1716, 20, -1413, -473, +-794, -756, -63, -789, 691, -562, 1437, -157, +1914, 275, 1886, 551, 1465, 547, 782, 308, +-112, -5, -1062, -242, -1702, -362, -1932, -404, +-1846, -208, -1410, 206, -594, 519, 280, 558, +968, 502, 1426, 372, 1704, -3, 1682, -475, +1298, -766, 716, -870, 128, -785, -440, -459, +-1051, 25, -1607, 491, -1843, 876, -1664, 1051, +-1266, 907, -709, 518, 75, 45, 1005, -457, +1733, -864, 2076, -965, 2082, -734, 1719, -372, +973, 1, -21, 383, -1000, 691, -1761, 708, +-2229, 482, -2394, 181, -2031, -137, -1205, -462, +-213, -667, 752, -615, 1696, -367, 2370, -3, +2553, 501, 2259, 920, 1601, 1001, 569, 732, +-661, 273, -1727, -339, -2432, -964, -2762, -1290, +-2638, -1233, -1875, -889, -667, -283, 559, 400, +1620, 957, 2485, 1295, 2895, 1365, 2650, 1116, +1811, 645, 677, 43, -493, -606, -1536, -1137, +-2237, -1371, -2466, -1309, -2247, -961, -1715, -377, +-937, 236, -58, 680, 798, 916, 1498, 917, +1951, 760, 2075, 533, 1964, 356, 1559, 255, +853, 169, -11, 19, -930, -297, -1855, -743, +-2496, -1146, -2567, -1410, -2116, -1357, -1340, -833, +-262, 73, 1013, 974, 2034, 1652, 2502, 2012, +2433, 1813, 1940, 1032, 1055, 29, -40, -858, +-925, -1418, -1357, -1561, -1489, -1315, -1499, -812, +-1346, -217, -984, 222, -593, 438, -375, 542, +-101, 556, 380, 459, 907, 403, 1301, 437, +1634, 404, 1821, 270, 1592, 151, 924, -8, +107, -257, -801, -510, -1674, -651, -2223, -726, +-2327, -702, -2023, -488, -1365, -144, -462, 228, +528, 571, 1441, 786, 2106, 781, 2400, 579, +2326, 314, 1885, 26, 1019, -189, -62, -285, +-1063, -300, -1895, -272, -2487, -271, -2650, -314, +-2207, -282, -1343, -157, -368, -7, 659, 138, +1645, 269, 2239, 233, 2295, 23, 1964, -201, +1418, -312, 662, -234, -141, 92, -741, 549, +-1103, 954, -1386, 1140, -1630, 940, -1712, 306, +-1587, -540, -1379, -1315, -981, -1807, -183, -1887, +931, -1423, 2062, -570, 2904, 368, 3192, 1202, +2787, 1794, 1695, 2025, 139, 1866, -1518, 1368, +-2841, 662, -3572, -158, -3641, -971, -2995, -1737, +-1691, -2300, -86, -2402, 1431, -1968, 2653, -1114, +3471, 41, 3651, 1305, 3074, 2330, 1961, 2773, +536, 2615, -1090, 1922, -2608, 767, -3569, -582, +-3782, -1679, -3308, -2281, -2170, -2392, -522, -2036, +1175, -1222, 2493, -203, 3337, 645, 3594, 1161, +3084, 1394, 1844, 1335, 339, 1038, -1020, 665, +-2098, 408, -2836, 243, -3014, 70, -2580, -177, +-1687, -481, -569, -804, 579, -1115, 1559, -1300, +2206, -1192, 2445, -775, 2270, -148, 1742, 485, +911, 1014, -133, 1344, -1163, 1397, -1874, 1155, +-2143, 737, -2007, 282, -1587, -147, -888, -520, +41, -773, 832, -922, 1233, -986, 1379, -1023, +1381, -976, 1139, -747, 776, -364, 494, 91, +313, 675, 15, 1343, -409, 1824, -885, 1934, +-1343, 1698, -1780, 1062, -2016, 17, -1757, -1178, +-905, -2160, 254, -2712, 1461, -2614, 2525, -1799, +3164, -486, 3056, 919, 2100, 2047, 634, 2578, +-992, 2342, -2506, 1504, -3505, 401, -3613, -657, +-2875, -1253, -1585, -1230, -1, -817, 1558, -343, +2669, 38, 3133, 180, 2995, -31, 2315, -442, +1237, -720, -61, -698, -1235, -386, -2053, 83, +-2485, 656, -2537, 1186, -2092, 1422, -1259, 1294, +-321, 974, 524, 511, 1329, -128, 1916, -831, +2051, -1368, 1813, -1695, 1409, -1801, 909, -1536, +290, -842, -398, 57, -1032, 964, -1557, 1722, +-1931, 2135, -2032, 2037, -1796, 1491, -1209, 670, +-333, -234, 716, -1000, 1696, -1504, 2297, -1721, +2424, -1578, 2096, -1211, 1375, -786, 395, -347, +-638, 131, -1459, 617, -1862, 1080, -1932, 1477, +-1746, 1721, -1307, 1717, -642, 1390, 0, 661, +470, -332, 888, -1355, 1323, -2176, 1542, -2601, +1448, -2419, 1235, -1605, 970, -408, 462, 837, +-216, 1896, -775, 2497, -1204, 2444, -1596, 1811, +-1824, 866, -1715, -140, -1269, -951, -593, -1447, +232, -1606, 1103, -1470, 1814, -1114, 2160, -688, +2120, -252, 1738, 190, 1016, 576, 67, 879, +-851, 1082, -1616, 1064, -2171, 819, -2378, 431, +-2058, 47, -1328, -229, -453, -335, 489, -329, +1478, -300, 2172, -317, 2253, -460, 1853, -753, +1261, -1029, 491, -1082, -392, -734, -1104, -10, +-1436, 911, -1475, 1749, -1397, 2246, -1207, 2197, +-813, 1511, -322, 332, 105, -928, 503, -1943, +976, -2537, 1337, -2523, 1387, -1806, 1220, -691, +960, 437, 558, 1391, 6, 2035, -585, 2160, +-1075, 1798, -1459, 1146, -1691, 371, -1608, -388, +-1133, -996, -392, -1400, 422, -1561, 1220, -1462, +1905, -1109, 2211, -603, 1962, 10, 1242, 629, +288, 1108, -703, 1409, -1593, 1517, -2133, 1319, +-2097, 809, -1616, 160, -871, -468, 23, -1062, +923, -1485, 1567, -1576, 1816, -1302, 1721, -767, +1357, -104, 702, 551, -99, 1062, -833, 1297, +-1321, 1215, -1550, 848, -1515, 371, -1172, -66, +-613, -412, 43, -626, 675, -610, 1116, -439, +1317, -288, 1297, -231, 1022, -209, 547, -241, +5, -353, -511, -421, -932, -252, -1101, 148, +-947, 621, -669, 1030, -395, 1317, -142, 1270, +72, 772, 171, -26, 224, -861, 328, -1527, +489, -1837, 648, -1642, 865, -966, 985, -110, +777, 693, 275, 1287, -308, 1514, -931, 1290, +-1547, 811, -1849, 319, -1623, -136, -1024, -531, +-250, -751, 642, -771, 1489, -625, 2018, -444, +2036, -277, 1615, -43, 905, 225, 17, 335, +-889, 296, -1557, 210, -1750, 128, -1529, 33, +-1125, -28, -649, 18, -98, 174, 382, 311, +668, 338, 809, 259, 979, 113, 1124, -111, +1144, -322, 1029, -481, 743, -548, 178, -467, +-544, -310, -1223, -155, -1749, 45, -1972, 254, +-1654, 439, -793, 606, 256, 725, 1153, 698, +1740, 549, 1908, 302, 1572, -99, 843, -600, +11, -986, -667, -1141, -1072, -1049, -1164, -698, +-932, -88, -466, 603, 59, 1128, 394, 1350, +446, 1252, 312, 797, 91, 89, -214, -629, +-458, -1088, -474, -1170, -188, -905, 263, -409, +649, 178, 860, 626, 888, 776, 627, 619, +67, 283, -534, -68, -905, -261, -1068, -295, +-1039, -230, -719, -103, -173, 23, 319, 37, +577, -69, 689, -202, 762, -221, 669, -102, +366, 80, 21, 226, -227, 352, -409, 401, +-520, 282, -462, 48, -244, -127, -44, -195, +63, -234, 111, -280, 88, -230, -52, -155, +-164, -224, -111, -375, 13, -400, 124, -313, +272, -187, 367, 49, 311, 469, 164, 907, +46, 1188, -43, 1239, -127, 1035, -151, 504, +-115, -329, -137, -1214, -249, -1822, -382, -2091, +-416, -1981, -301, -1401, -36, -416, 352, 649, +756, 1505, 991, 2099, 916, 2380, 501, 2204, +-41, 1650, -515, 848, -859, -117, -1011, -1162, +-852, -2100, -420, -2703, 32, -2804, 350, -2363, +605, -1422, 755, -117, 715, 1306, 533, 2406, +296, 2897, 26, 2779, -295, 2156, -578, 1146, +-696, 15, -670, -932, -532, -1505, -268, -1760, +81, -1777, 374, -1564, 565, -1161, 684, -689, +683, -187, 509, 353, 271, 889, 2, 1266, +-332, 1404, -736, 1326, -1074, 1086, -1166, 671, +-916, 172, -427, -223, 198, -472, 870, -656, +1409, -722, 1586, -670, 1313, -601, 692, -569, +-87, -535, -847, -487, -1436, -374, -1675, -141, +-1473, 207, -929, 640, -244, 1130, 409, 1486, +910, 1502, 1187, 1118, 1196, 424, 931, -467, +544, -1316, 199, -1842, -65, -1850, -307, -1322, +-469, -409, -541, 558, -623, 1274, -762, 1533, +-801, 1263, -707, 560, -547, -284, -260, -998, +279, -1336, 920, -1155, 1423, -549, 1697, 224, +1672, 976, 1247, 1449, 460, 1420, -483, 948, +-1353, 261, -1984, -501, -2253, -1154, -2040, -1513, +-1330, -1495, -333, -1175, 687, -677, 1590, -156, +2261, 328, 2440, 775, 2030, 1140, 1265, 1326, +397, 1340, -536, 1189, -1371, 816, -1869, 179, +-1974, -553, -1823, -1212, -1433, -1723, -793, -1927, +-50, -1645, 642, -988, 1300, -164, 1839, 706, +2072, 1458, 1888, 1808, 1315, 1678, 450, 1211, +-520, 570, -1345, -170, -1863, -816, -1994, -1105, +-1685, -1019, -1073, -831, -402, -591, 197, -197, +716, 191, 1101, 319, 1252, 315, 1195, 385, +1069, 456, 846, 403, 428, 346, -119, 319, +-598, 207, -972, -20, -1253, -258, -1351, -472, +-1141, -614, -667, -605, -116, -405, 371, -70, +788, 292, 1028, 538, 1005, 670, 853, 672, +664, 478, 350, 200, -12, 30, -251, -79, +-405, -175, -620, -210, -833, -227, -917, -348, +-861, -520, -700, -648, -373, -647, 162, -455, +793, -90, 1264, 393, 1477, 953, 1443, 1357, +1116, 1403, 446, 1107, -412, 575, -1164, -131, +-1609, -844, -1731, -1324, -1476, -1420, -819, -1228, +36, -844, 761, -330, 1224, 162, 1489, 450, +1527, 566, 1239, 618, 723, 645, 126, 639, +-467, 614, -979, 524, -1311, 382, -1419, 154, +-1264, -192, -856, -535, -273, -723, 366, -790, +926, -751, 1215, -613, 1217, -418, 1048, -250, +752, -130, 352, -26, 0, 147, -253, 379, +-502, 602, -785, 755, -1017, 860, -1169, 838, +-1212, 592, -1031, 181, -549, -220, 109, -555, +781, -813, 1385, -965, 1797, -955, 1839, -809, +1443, -565, 711, -294, -151, -21, -951, 255, +-1551, 500, -1865, 641, -1856, 703, -1550, 661, +-1003, 531, -310, 407, 426, 311, 1102, 205, +1617, 145, 1876, 70, 1854, -115, 1450, -405, +663, -722, -258, -1051, -1028, -1293, -1592, -1284, +-1867, -949, -1695, -368, -1127, 377, -443, 1147, +167, 1778, 666, 2053, 1013, 1873, 1096, 1324, +931, 532, 730, -383, 588, -1184, 390, -1626, +119, -1591, -102, -1235, -261, -748, -468, -213, +-713, 224, -846, 367, -761, 286, -558, 190, +-302, 223, 42, 389, 422, 656, 638, 915, +678, 1058, 690, 975, 696, 620, 544, 99, +274, -385, 31, -783, -165, -1034, -397, -1062, +-593, -928, -637, -767, -567, -579, -479, -328, +-325, -38, -72, 245, 181, 576, 324, 923, +384, 1179, 440, 1269, 500, 1158, 531, 845, +488, 388, 310, -211, -8, -836, -427, -1258, +-805, -1419, -981, -1427, -902, -1189, -628, -652, +-174, -39, 349, 421, 784, 745, 1024, 948, +996, 990, 622, 835, 13, 550, -568, 283, +-901, 85, -959, -162, -808, -418, -471, -559, +32, -582, 474, -566, 644, -486, 599, -294, +475, -43, 264, 116, -10, 165, -227, 137, +-273, 52, -205, -55, -146, -83, -113, -2, +-68, 156, -118, 278, -289, 292, -381, 208, +-285, 71, -134, -153, 74, -338, 402, -298, +721, -136, 812, -26, 668, 114, 409, 234, +56, 193, -358, 23, -640, -125, -693, -225, +-604, -296, -468, -348, -283, -358, -74, -281, +102, -76, 242, 167, 407, 433, 578, 735, +678, 955, 649, 912, 509, 631, 235, 208, +-127, -295, -448, -780, -622, -1063, -645, -1106, +-524, -951, -315, -640, -72, -210, 134, 254, +238, 695, 218, 1029, 163, 1213, 128, 1205, +97, 962, 61, 477, 81, -136, 195, -742, +344, -1138, 403, -1187, 324, -897, 127, -402, +-177, 176, -564, 656, -881, 858, -977, 695, +-839, 310, -528, -109, -80, -417, 402, -527, +794, -381, 1013, -49, 975, 329, 620, 613, +163, 709, -158, 547, -339, 235, -468, -131, +-484, -503, -406, -762, -391, -803, -485, -652, +-507, -347, -366, 38, -180, 438, -1, 742, +309, 859, 690, 756, 882, 489, 804, 85, +564, -413, 221, -860, -178, -1087, -532, -1097, +-693, -864, -609, -353, -393, 323, -202, 934, +-48, 1314, 83, 1366, 132, 1063, 70, 423, +-7, -344, 9, -965, 134, -1273, 270, -1246, +412, -931, 542, -457, 540, -10, 325, 250, +16, 348, -279, 350, -521, 335, -646, 351, +-566, 444, -338, 551, -91, 522, 82, 295, +207, -12, 302, -306, 302, -543, 228, -699, +203, -673, 205, -468, 143, -249, 77, -140, +116, -33, 160, 114, 77, 219, -58, 292, +-129, 444, -214, 586, -367, 557, -462, 372, +-407, 189, -318, -6, -238, -279, -51, -528, +226, -574, 379, -477, 400, -374, 421, -240, +427, 38, 334, 340, 202, 515, 72, 583, +-87, 580, -278, 397, -456, 24, -589, -361, +-598, -592, -510, -666, -386, -495, -185, -60, +106, 473, 339, 908, 426, 1101, 416, 937, +361, 450, 230, -219, 60, -844, -36, -1268, +-21, -1366, -13, -1084, -49, -460, -51, 329, +-38, 1031, -116, 1446, -259, 1513, -373, 1183, +-415, 555, -385, -188, -220, -845, 66, -1219, +324, -1194, 460, -819, 549, -245, 600, 278, +493, 608, 169, 680, -209, 503, -472, 165, +-566, -181, -520, -416, -313, -458, 20, -324, +338, -92, 517, 120, 565, 309, 461, 457, +229, 517, -58, 476, -353, 329, -583, 61, +-601, -271, -434, -606, -217, -852, 28, -951, +316, -863, 523, -610, 551, -217, 437, 219, +300, 582, 190, 807, 72, 967, -61, 1069, +-138, 1002, -152, 686, -222, 215, -418, -361, +-602, -1012, -616, -1589, -467, -1806, -255, -1547, +68, -920, 485, -113, 787, 746, 806, 1404, +660, 1586, 444, 1265, 119, 710, -279, 121, +-546, -387, -628, -672, -637, -626, -603, -363, +-415, -50, -111, 173, 142, 273, 270, 218, +359, 6, 448, -240, 430, -430, 253, -623, +47, -737, -138, -655, -340, -379, -477, -33, +-415, 359, -219, 789, -23, 1158, 161, 1337, +345, 1268, 426, 974, 344, 541, 138, -31, +-116, -626, -385, -1109, -546, -1448, -511, -1602, +-310, -1446, 20, -979, 387, -327, 602, 353, +658, 974, 618, 1392, 379, 1478, -94, 1271, +-491, 903, -637, 457, -697, 57, -706, -197, +-466, -306, -13, -400, 369, -496, 592, -566, +854, -597, 1096, -571, 1007, -463, 581, -302, +72, -116, -478, 18, -1090, 97, -1499, 140, +-1429, 191, -978, 309, -358, 558, 347, 855, +1014, 1027, 1381, 943, 1324, 592, 979, 6, +572, -655, 193, -1171, -128, -1370, -366, -1212, +-526, -708, -677, -42, -827, 461, -910, 604, +-877, 450, -744, 107, -450, -285, 3, -521, +518, -387, 968, 77, 1256, 662, 1309, 1130, +1117, 1332, 669, 1158, 53, 587, -540, -254, +-974, -1046, -1240, -1567, -1264, -1756, -985, -1603, +-518, -1081, -33, -306, 387, 436, 660, 917, +713, 1171, 532, 1173, 235, 904, -5, 481, +-113, 100, -137, -146, -99, -254, 40, -251, +206, -190, 223, -173, 126, -224, 55, -335, +3, -408, -152, -416, -334, -373, -397, -236, +-383, -35, -383, 90, -294, 163, -43, 224, +238, 269, 378, 309, 441, 395, 478, 484, +342, 495, 17, 364, -245, 98, -290, -251, +-162, -541, 74, -709, 372, -686, 594, -443, +565, -70, 251, 305, -164, 586, -519, 651, +-809, 501, -974, 231, -864, -24, -499, -240, +-37, -377, 433, -365, 862, -215, 1120, -51, +1095, 53, 795, 126, 349, 206, -136, 222, +-554, 174, -762, 132, -678, 140, -418, 152, +-123, 156, 113, 173, 213, 217, 80, 215, +-228, 77, -493, -187, -528, -446, -366, -667, +-51, -812, 429, -743, 910, -395, 1121, 79, +1005, 557, 667, 942, 175, 1093, -417, 919, +-938, 525, -1216, 31, -1242, -436, -1075, -737, +-703, -789, -148, -589, 443, -222, 897, 119, +1163, 372, 1203, 476, 980, 334, 523, -30, +1, -406, -435, -637, -766, -661, -981, -448, +-950, -57, -681, 341, -352, 665, -97, 746, +140, 520, 374, 163, 510, -151, 530, -363, +535, -382, 512, -206, 353, 36, 133, 155, +-7, 107, -144, -85, -317, -333, -396, -530, +-370, -560, -358, -373, -360, -30, -296, 290, +-138, 502, 57, 535, 242, 374, 386, 139, +486, -36, 505, -130, 403, -119, 220, -41, +97, 27, 39, 12, -74, -67, -264, -203, +-387, -314, -433, -294, -474, -163, -437, -10, +-208, 136, 124, 228, 409, 267, 603, 237, +722, 169, 659, 126, 349, 135, -80, 107, +-457, 17, -723, -76, -828, -189, -747, -346, +-470, -407, -60, -344, 361, -224, 696, -46, +934, 229, 998, 495, 773, 685, 338, 778, +-137, 727, -618, 485, -1013, 74, -1162, -436, +-1039, -855, -731, -1068, -308, -1043, 166, -720, +598, -144, 879, 426, 967, 805, 870, 935, +647, 817, 333, 495, -9, 123, -310, -170, +-512, -281, -617, -189, -639, -21, -589, 77, +-470, 119, -350, 59, -240, -125, -104, -359, +81, -514, 291, -547, 501, -484, 700, -329, +861, -56, 885, 257, 686, 540, 278, 742, +-215, 857, -668, 815, -1018, 562, -1188, 166, +-1070, -278, -685, -720, -206, -1017, 236, -1049, +649, -811, 997, -433, 1122, -18, 966, 376, +649, 651, 263, 689, -181, 522, -621, 290, +-853, 86, -818, -119, -631, -267, -373, -289, +-38, -231, 269, -144, 421, -33, 404, 40, +344, 51, 314, 6, 280, -76, 226, -172, +196, -203, 133, -149, -54, -43, -310, 86, +-515, 181, -641, 154, -674, 32, -543, -117, +-199, -204, 240, -152, 588, 62, 821, 331, +944, 540, 823, 580, 421, 388, -67, -17, +-465, -514, -758, -927, -907, -1049, -822, -814, +-497, -344, -110, 188, 163, 696, 300, 1019, +371, 992, 313, 657, 142, 222, 30, -192, +92, -487, 202, -572, 279, -415, 358, -107, +390, 212, 218, 396, -114, 396, -427, 219, +-673, -84, -848, -460, -831, -719, -590, -705, +-230, -430, 196, -16, 621, 435, 906, 842, +974, 1057, 854, 933, 586, 531, 162, 25, +-348, -405, -752, -682, -901, -775, -857, -652, +-669, -350, -286, -32, 217, 199, 580, 364, +718, 496, 725, 508, 626, 409, 361, 270, +18, 58, -247, -266, -416, -581, -568, -758, +-642, -723, -551, -499, -339, -125, -110, 319, +156, 682, 467, 803, 688, 699, 723, 477, +631, 199, 446, -71, 179, -182, -115, -172, +-377, -181, -558, -220, -596, -274, -520, -384, +-406, -486, -230, -515, 5, -453, 157, -302, +194, -81, 198, 103, 194, 218, 163, 313, +143, 396, 205, 464, 349, 554, 427, 616, +374, 581, 231, 408, -5, 107, -385, -291, +-779, -673, -974, -936, -904, -974, -626, -772, +-190, -431, 319, -72, 768, 238, 994, 390, +954, 342, 707, 183, 294, 20, -189, -114, +-571, -143, -768, -30, -772, 163, -608, 348, +-336, 521, -32, 638, 237, 639, 402, 507, +449, 271, 420, -60, 344, -457, 245, -817, +171, -1005, 122, -1033, 63, -908, -36, -612, +-200, -213, -431, 153, -679, 437, -871, 628, +-858, 706, -553, 718, -9, 740, 605, 728, +1154, 660, 1490, 530, 1435, 320, 942, 12, +218, -365, -494, -760, -1048, -1033, -1352, -1083, +-1280, -918, -860, -565, -321, -60, 151, 427, +522, 741, 727, 846, 666, 733, 426, 416, +225, 33, 109, -279, -8, -413, -97, -341, +-69, -152, 19, 61, 38, 291, -12, 466, +-40, 504, -83, 433, -212, 328, -328, 166, +-297, -51, -185, -287, -92, -518, 5, -727, +165, -850, 308, -811, 339, -579, 288, -221, +267, 183, 213, 577, 45, 873, -151, 933, +-245, 778, -294, 507, -379, 176, -431, -155, +-334, -365, -122, -411, 58, -351, 201, -263, +404, -166, 561, -87, 489, -71, 271, -132, +87, -218, -79, -267, -300, -240, -486, -157, +-479, -40, -350, 91, -263, 261, -153, 401, +102, 407, 325, 295, 364, 163, 358, 0, +361, -184, 189, -303, -100, -300, -267, -229, +-262, -129, -216, -16, -154, 78, -38, 110, +79, 94, 78, 77, -4, 67, -46, -11, +-27, -116, 27, -184, 148, -257, 323, -337, +428, -310, 372, -150, 171, 55, -115, 258, +-402, 460, -621, 580, -712, 567, -633, 436, +-412, 233, -129, -8, 183, -247, 512, -485, +778, -676, 898, -765, 880, -715, 719, -523, +412, -199, 5, 231, -442, 689, -856, 1016, +-1106, 1106, -1147, 940, -979, 567, -607, 56, +-95, -438, 391, -768, 747, -868, 975, -752, +1052, -480, 915, -177, 616, 62, 272, 182, +-58, 207, -378, 195, -611, 213, -707, 298, +-725, 460, -667, 588, -506, 578, -314, 415, +-123, 121, 82, -293, 273, -701, 462, -918, +654, -868, 753, -598, 709, -154, 558, 334, +297, 703, -82, 871, -472, 810, -734, 508, +-792, 93, -685, -275, -505, -503, -283, -559, +-19, -436, 204, -212, 334, 18, 390, 167, +413, 183, 402, 79, 334, -53, 227, -146, +145, -147, 56, -35, -92, 151, -242, 319, +-306, 395, -329, 347, -353, 207, -322, -2, +-180, -221, 31, -360, 242, -383, 413, -332, +497, -235, 405, -126, 131, -49, -218, -19, +-531, -15, -715, -33, -665, -44, -337, -26, +156, 23, 629, 101, 961, 208, 1072, 312, +903, 396, 446, 446, -169, 427, -724, 272, +-1075, -9, -1202, -348, -1051, -671, -630, -929, +-97, -1030, 367, -888, 722, -494, 926, 22, +926, 526, 738, 914, 437, 1096, 81, 1002, +-239, 681, -457, 252, -576, -163, -598, -494, +-491, -671, -278, -671, -60, -517, 96, -291, +216, -60, 298, 140, 265, 282, 126, 314, +12, 243, -23, 114, -25, -28, -19, -151, +33, -202, 148, -190, 226, -126, 146, -17, +-20, 111, -174, 227, -340, 336, -476, 424, +-400, 467, -132, 431, 139, 282, 324, -14, +432, -395, 422, -737, 264, -932, 14, -923, +-195, -660, -282, -178, -279, 363, -230, 771, +-154, 949, -81, 882, -23, 606, 37, 214, +133, -121, 281, -278, 423, -255, 466, -146, +379, -3, 179, 109, -141, 97, -508, -41, +-741, -210, -758, -368, -614, -480, -335, -497, +72, -416, 468, -298, 696, -143, 733, 75, +632, 328, 400, 553, 86, 750, -190, 878, +-330, 859, -348, 680, -286, 374, -168, -29, +-32, -444, 49, -770, 30, -967, -86, -1035, +-237, -923, -348, -660, -368, -344, -266, -1, +-52, 361, 237, 639, 554, 746, 805, 704, +864, 577, 698, 384, 390, 159, -44, -22, +-564, -89, -970, -79, -1124, -71, -1075, -107, +-817, -182, -302, -304, 366, -426, 950, -482, +1287, -451, 1325, -339, 1043, -141, 436, 90, +-342, 289, -998, 411, -1340, 446, -1344, 390, +-979, 266, -317, 97, 382, -87, 884, -234, +1132, -283, 1110, -225, 806, -70, 301, 130, +-219, 299, -616, 355, -851, 272, -892, 67, +-689, -208, -299, -481, 130, -647, 476, -641, +665, -477, 657, -226, 441, 66, 64, 341, +-314, 545, -524, 653, -519, 682, -331, 626, +-15, 486, 306, 276, 499, 31, 513, -238, +381, -518, 152, -743, -123, -812, -395, -741, +-566, -585, -586, -347, -496, -30, -316, 249, +-21, 432, 297, 563, 529, 655, 678, 669, +733, 619, 573, 520, 217, 378, -150, 184, +-436, -51, -659, -297, -740, -513, -583, -690, +-261, -817, 74, -863, 343, -805, 494, -616, +475, -264, 304, 177, 75, 622, -137, 1042, +-280, 1320, -319, 1276, -247, 942, -96, 454, +89, -136, 241, -730, 321, -1106, 330, -1189, +258, -1044, 87, -707, -111, -203, -257, 327, +-329, 727, -315, 928, -241, 916, -175, 661, +-102, 210, 3, -288, 95, -662, 141, -819, +183, -716, 222, -400, 210, 2, 132, 330, +-2, 467, -143, 389, -201, 205, -118, 32, +85, -58, 314, -4, 463, 206, 454, 428, +210, 489, -217, 337, -633, 23, -901, -368, +-976, -712, -774, -888, -275, -829, 298, -583, +721, -250, 952, 93, 1000, 384, 824, 532, +463, 555, 81, 569, -193, 577, -404, 493, +-589, 365, -667, 232, -588, 16, -444, -267, +-291, -484, -100, -611, 104, -661, 240, -591, +338, -400, 444, -171, 457, 42, 293, 223, +80, 356, -46, 417, -135, 411, -214, 340, +-192, 209, -93, 43, -15, -101, 52, -185, +148, -206, 202, -152, 143, -13, -22, 129, +-221, 209, -373, 215, -441, 146, -431, -15, +-297, -225, -18, -395, 271, -477, 457, -468, +594, -336, 648, -74, 495, 244, 178, 488, +-113, 593, -306, 523, -432, 274, -453, -79, +-320, -379, -122, -506, -7, -415, 17, -142, +34, 206, 9, 481, -121, 568, -241, 421, +-169, 115, 63, -212, 286, -446, 450, -531, +580, -462, 571, -327, 318, -206, -42, -129, +-301, -104, -465, -112, -587, -36, -572, 182, +-362, 456, -109, 700, 44, 858, 169, 823, +353, 559, 451, 136, 378, -337, 262, -748, +165, -984, -20, -1010, -251, -829, -355, -490, +-305, -103, -211, 234, -118, 511, -8, 680, +103, 681, 136, 533, 66, 309, 14, 61, +67, -157, 126, -302, 118, -310, 126, -162, +181, 63, 155, 247, -4, 339, -167, 298, +-258, 86, -339, -237, -396, -513, -329, -640, +-132, -594, 77, -383, 235, -26, 353, 348, +406, 578, 341, 623, 179, 518, 2, 278, +-131, -8, -214, -209, -232, -275, -178, -209, +-71, -23, 38, 177, 100, 270, 100, 247, +56, 121, -26, -112, -114, -343, -170, -468, +-185, -493, -176, -429, -113, -243, 33, -6, +197, 203, 315, 400, 376, 575, 363, 659, +241, 636, 21, 490, -231, 216, -444, -127, +-546, -469, -478, -735, -270, -802, 12, -654, +307, -395, 492, -87, 501, 220, 385, 414, +183, 468, -63, 446, -224, 380, -250, 269, +-225, 144, -218, 9, -203, -150, -170, -333, +-117, -480, -25, -514, 97, -393, 227, -174, +337, 83, 354, 344, 242, 524, 75, 516, +-77, 340, -217, 98, -288, -141, -229, -356, +-124, -462, -49, -395, 43, -224, 139, -64, +160, 78, 124, 183, 69, 187, -23, 75, +-112, -63, -150, -159, -170, -178, -149, -99, +-22, 53, 128, 232, 183, 394, 156, 442, +86, 317, -27, 75, -103, -199, -76, -446, +-7, -581, 55, -534, 140, -326, 195, -51, +121, 210, -59, 389, -225, 436, -308, 332, +-294, 136, -189, -44, -27, -180, 133, -295, +212, -316, 183, -213, 114, -63, 60, 98, +11, 295, -18, 456, 8, 493, 44, 398, +34, 191, 1, -94, -13, -350, -19, -492, +-25, -483, -14, -332, 18, -101, 19, 90, +-51, 177, -166, 159, -255, 82, -265, 14, +-169, 20, 28, 103, 257, 221, 393, 307, +385, 307, 272, 211, 108, 63, -54, -85, +-164, -192, -221, -232, -209, -213, -113, -179, +-8, -137, 14, -83, 6, -22, 40, 54, +50, 165, -18, 259, -78, 264, -67, 199, +-61, 109, -89, -23, -39, -159, 117, -224, +240, -215, 250, -178, 204, -125, 123, -84, +-25, -64, -189, -27, -255, 52, -227, 137, +-181, 236, -119, 339, -7, 380, 122, 341, +222, 253, 279, 100, 273, -97, 179, -295, +14, -488, -188, -669, -380, -774, -500, -763, +-505, -605, -346, -261, -15, 220, 348, 709, +585, 1116, 672, 1306, 622, 1156, 396, 718, +41, 129, -284, -498, -480, -1006, -571, -1245, +-586, -1194, -507, -938, -316, -545, -73, -101, +157, 300, 394, 609, 639, 813, 751, 888, +617, 805, 319, 570, -36, 250, -454, -108, +-833, -440, -943, -652, -707, -702, -277, -639, +207, -497, 652, -305, 920, -107, 886, 55, +583, 207, 167, 368, -226, 505, -540, 556, +-722, 498, -713, 363, -540, 179, -302, -33, +-9, -188, 336, -242, 586, -244, 626, -247, +544, -272, 391, -354, 96, -440, -240, -434, +-406, -299, -405, -39, -351, 335, -214, 696, +5, 874, 171, 827, 190, 584, 109, 164, +16, -311, -65, -653, -140, -763, -171, -650, +-81, -348, 118, 65, 309, 471, 424, 727, +471, 738, 385, 523, 81, 149, -357, -309, +-720, -699, -915, -880, -908, -817, -613, -535, +-55, -75, 550, 410, 1015, 760, 1259, 923, +1186, 876, 753, 618, 94, 267, -560, -73, +-1029, -369, -1250, -563, -1189, -608, -824, -553, +-269, -430, 260, -232, 670, 15, 967, 240, +1064, 401, 842, 452, 402, 365, -27, 151, +-342, -109, -594, -312, -726, -378, -618, -282, +-337, -48, -67, 229, 140, 437, 300, 475, +356, 316, 244, 23, 38, -291, -111, -528, +-124, -614, -59, -517, 18, -275, 137, 35, +276, 344, 297, 553, 173, 603, 28, 498, +-103, 250, -282, -125, -446, -501, -459, -736, +-302, -782, -51, -628, 227, -262, 462, 192, +564, 562, 467, 758, 193, 742, -131, 519, +-371, 197, -473, -105, -408, -332, -168, -462, +144, -497, 343, -489, 357, -460, 250, -390, +71, -259, -160, -37, -330, 270, -331, 574, +-185, 782, 8, 811, 180, 618, 289, 240, +322, -210, 271, -624, 123, -899, -54, -933, +-176, -707, -265, -333, -314, 86, -243, 488, +-68, 778, 81, 863, 137, 744, 132, 490, +94, 149, -5, -224, -138, -513, -204, -658, +-150, -642, -41, -484, 77, -240, 216, 15, +332, 225, 369, 337, 331, 336, 240, 269, +101, 210, -69, 182, -245, 199, -428, 248, +-589, 273, -665, 229, -613, 105, -432, -120, +-116, -390, 286, -604, 627, -709, 796, -696, +808, -520, 665, -188, 363, 211, 3, 604, +-277, 928, -423, 1086, -430, 1041, -340, 776, +-246, 311, -199, -242, -175, -738, -146, -1083, +-85, -1186, 33, -1011, 178, -622, 295, -131, +342, 351, 280, 684, 109, 809, -70, 737, +-177, 506, -229, 196, -229, -67, -142, -221, +11, -245, 157, -141, 249, 18, 281, 119, +260, 111, 182, -10, 62, -206, -53, -400, +-130, -506, -183, -456, -226, -244, -251, 46, +-229, 302, -176, 443, -155, 442, -159, 312, +-92, 107, 50, -85, 190, -189, 323, -197, +448, -157, 474, -108, 352, -44, 149, 3, +-52, 13, -228, 31, -354, 84, -360, 120, +-254, 98, -156, 24, -92, -76, -5, -194, +65, -295, 53, -331, 19, -253, 34, -83, +73, 105, 82, 270, 68, 379, 74, 357, +80, 239, 14, 107, -75, -34, -91, -179, +-85, -266, -113, -291, -101, -288, -7, -258, +101, -182, 169, -62, 200, 118, 200, 324, +180, 470, 106, 523, -48, 469, -215, 280, +-310, 1, -353, -287, -358, -520, -257, -644, +-45, -620, 146, -479, 261, -257, 366, 18, +463, 288, 454, 491, 324, 616, 131, 635, +-106, 519, -386, 293, -634, 35, -723, -197, +-593, -352, -303, -388, 66, -310, 463, -176, +791, -36, 907, 71, 771, 96, 474, 28, +88, -78, -327, -160, -632, -189, -754, -156, +-754, -44, -665, 138, -444, 335, -122, 469, +198, 492, 455, 396, 632, 185, 688, -122, +584, -423, 347, -590, 77, -579, -152, -407, +-306, -104, -342, 250, -252, 540, -112, 665, +21, 562, 82, 268, 18, -96, -121, -442, +-245, -699, -333, -761, -353, -586, -234, -267, +20, 101, 299, 461, 511, 719, 628, 793, +611, 684, 390, 443, 8, 118, -350, -244, +-573, -564, -668, -750, -611, -756, -397, -603, +-84, -341, 248, -25, 517, 279, 665, 477, +652, 526, 451, 467, 124, 362, -200, 241, +-461, 122, -636, 16, -661, -86, -520, -231, +-275, -422, 25, -586, 325, -626, 544, -511, +627, -254, 554, 117, 361, 506, 113, 746, +-133, 760, -344, 579, -473, 276, -467, -78, +-338, -369, -148, -520, 50, -540, 226, -459, +344, -320, 369, -182, 312, -42, 213, 121, +88, 277, -75, 399, -244, 480, -346, 481, +-360, 380, -324, 196, -251, -45, -115, -310, +52, -521, 187, -629, 287, -630, 380, -518, +435, -296, 401, -10, 304, 306, 195, 593, +30, 771, -207, 802, -437, 692, -585, 425, +-613, 38, -515, -361, -323, -674, -70, -844, +174, -811, 336, -580, 429, -241, 480, 115, +458, 421, 365, 598, 255, 609, 127, 483, +-23, 282, -178, 55, -322, -160, -430, -306, +-494, -347, -521, -305, -460, -205, -267, -68, +-10, 73, 242, 166, 485, 185, 680, 140, +742, 77, 630, 26, 381, 4, 57, 23, +-323, 74, -687, 99, -884, 69, -852, -7, +-643, -112, -293, -212, 173, -270, 644, -292, +950, -255, 982, -139, 759, 5, 367, 134, +-122, 281, -594, 431, -880, 497, -904, 450, +-722, 316, -380, 77, 72, -228, 487, -478, +713, -602, 741, -603, 623, -483, 374, -255, +44, 10, -245, 228, -411, 374, -467, 465, +-424, 513, -272, 504, -71, 424, 77, 261, +142, 10, 156, -302, 122, -596, 31, -792, +-59, -835, -76, -688, -20, -360, 50, 62, +110, 464, 194, 752, 288, 874, 295, 812, +190, 596, 61, 291, -90, -25, -294, -292, +-442, -479, -446, -574, -378, -574, -287, -498, +-131, -381, 70, -257, 218, -130, 292, -5, +360, 96, 429, 188, 414, 320, 298, 477, +170, 591, 43, 637, -141, 606, -354, 431, +-495, 82, -511, -354, -439, -736, -309, -981, +-93, -1040, 152, -869, 293, -489, 329, -18, +339, 418, 289, 748, 155, 938, 48, 950, +43, 800, 81, 542, 90, 219, 56, -146, +-20, -501, -167, -776, -385, -916, -558, -905, +-581, -756, -467, -483, -252, -112, 81, 279, +483, 598, 788, 816, 877, 928, 789, 887, +567, 681, 185, 354, -291, -17, -666, -365, +-838, -628, -842, -751, -686, -714, -356, -571, +53, -401, 390, -241, 563, -102, 576, 19, +462, 153, 250, 341, 13, 571, -137, 753, +-167, 804, -139, 684, -109, 389, -49, -49, +26, -514, 35, -837, -23, -927, -57, -795, +-49, -490, -49, -98, -44, 266, 10, 496, +73, 564, 67, 502, 7, 372, -24, 225, +-47, 99, -124, 12, -193, -58, -151, -150, +-36, -253, 76, -330, 182, -377, 292, -394, +351, -337, 299, -199, 155, -15, -5, 194, +-160, 413, -304, 593, -364, 686, -294, 650, +-173, 471, -63, 162, 15, -229, 41, -617, +11, -875, -26, -907, -19, -714, 53, -360, +156, 67, 245, 445, 288, 667, 256, 686, +150, 525, 14, 261, -115, 0, -203, -191, +-208, -284, -158, -266, -126, -161, -126, -40, +-136, 56, -140, 104, -131, 81, -66, -5, +83, -111, 240, -185, 307, -174, 308, -79, +271, 61, 150, 197, -36, 277, -171, 248, +-210, 104, -187, -114, -124, -328, -40, -455, +28, -438, 52, -287, 26, -41, -29, 241, +-78, 475, -91, 590, -76, 576, -31, 443, +72, 222, 196, -35, 260, -272, 254, -442, +192, -539, 79, -576, -64, -545, -202, -445, +-304, -297, -340, -101, -317, 161, -248, 457, +-110, 709, 96, 861, 280, 865, 387, 683, +440, 307, 430, -205, 305, -693, 89, -1002, +-134, -1074, -335, -898, -509, -474, -566, 98, +-448, 610, -239, 902, -24, 925, 186, 679, +347, 234, 402, -248, 358, -593, 274, -702, +192, -570, 122, -255, 45, 139, -14, 456, +-71, 568, -199, 475, -359, 242, -442, -60, +-440, -340, -381, -493, -233, -476, 11, -329, +268, -108, 439, 135, 519, 338, 540, 450, +467, 446, 296, 334, 109, 164, -51, -13, +-224, -171, -403, -288, -537, -328, -589, -294, +-549, -233, -423, -168, -220, -87, 52, -13, +326, 33, 544, 71, 691, 132, 741, 199, +645, 243, 414, 277, 90, 312, -260, 322, +-558, 267, -733, 126, -753, -80, -624, -289, +-388, -467, -82, -581, 226, -573, 456, -427, +569, -190, 559, 71, 441, 287, 264, 392, +62, 375, -137, 290, -281, 193, -337, 116, +-325, 87, -257, 109, -133, 158, 16, 170, +115, 82, 140, -88, 140, -271, 138, -430, +86, -519, 2, -468, -46, -273, -54, -27, +-62, 179, -73, 295, -73, 303, -57, 210, +-48, 83, -29, 12, 51, 52, 162, 181, +219, 321, 216, 376, 160, 269, 41, -12, +-103, -395, -226, -739, -308, -898, -328, -796, +-252, -446, -100, 78, 56, 631, 175, 1004, +253, 1066, 272, 833, 201, 395, 100, -122, +32, -563, -20, -798, -69, -792, -80, -596, +-53, -306, -17, -25, -10, 169, -41, 243, +-78, 220, -103, 175, -141, 154, -154, 145, +-84, 142, 31, 162, 121, 197, 179, 205, +207, 166, 182, 100, 108, 14, 40, -109, +17, -267, 11, -410, -8, -485, -39, -471, +-90, -352, -158, -131, -221, 117, -249, 304, +-212, 396, -116, 392, -7, 313, 116, 206, +257, 122, 358, 84, 374, 82, 334, 81, +251, 48, 102, -19, -104, -114, -296, -225, +-440, -316, -537, -360, -543, -365, -385, -342, +-107, -288, 169, -176, 385, 21, 530, 278, +571, 550, 484, 788, 296, 919, 103, 848, +-41, 544, -183, 66, -350, -491, -473, -993, +-525, -1295, -532, -1303, -482, -1011, -297, -494, +40, 117, 418, 692, 713, 1103, 905, 1267, +921, 1180, 663, 892, 194, 472, -291, 18, +-683, -388, -935, -699, -984, -892, -783, -940, +-399, -847, 4, -657, 328, -415, 580, -152, +712, 109, 665, 353, 499, 569, 311, 746, +104, 865, -114, 871, -275, 730, -343, 462, +-362, 97, -358, -327, -298, -719, -178, -969, +-65, -1030, 29, -915, 116, -662, 164, -325, +153, 43, 114, 396, 76, 677, 52, 848, +51, 888, 86, 775, 155, 522, 216, 182, +201, -181, 97, -507, -65, -725, -240, -779, +-391, -681, -471, -488, -424, -242, -223, 32, +54, 291, 323, 492, 536, 623, 617, 668, +478, 581, 161, 361, -200, 63, -490, -257, +-662, -548, -659, -731, -432, -740, -48, -576, +336, -298, 629, 18, 781, 313, 729, 533, +468, 635, 109, 609, -239, 495, -507, 333, +-679, 123, -730, -125, -641, -358, -450, -525, +-210, -619, 91, -625, 420, -499, 678, -230, +810, 104, 806, 410, 644, 630, 322, 715, +-100, 617, -505, 352, -798, 18, -929, -300, +-846, -548, -539, -638, -126, -513, 257, -230, +534, 95, 677, 378, 663, 553, 503, 537, +256, 305, 35, -35, -110, -330, -209, -486, +-253, -457, -216, -253, -166, 40, -167, 281, +-208, 358, -238, 250, -248, 35, -235, -165, +-151, -257, 45, -189, 280, 29, 463, 283, +570, 422, 581, 385, 464, 193, 233, -85, +-60, -353, -328, -497, -501, -452, -578, -273, +-568, -60, -455, 126, -261, 243, -42, 256, +167, 180, 368, 75, 528, -6, 577, -41, +488, -22, 299, 31, 30, 79, -272, 102, +-485, 86, -526, 35, -431, -40, -239, -135, +26, -226, 288, -260, 443, -210, 433, -103, +289, 13, 85, 126, -136, 215, -310, 237, +-362, 174, -303, 63, -205, -50, -94, -130, +47, -168, 190, -154, 259, -95, 250, -17, +238, 56, 235, 118, 173, 155, 56, 157, +-62, 129, -189, 73, -340, -26, -458, -148, +-472, -229, -354, -246, -147, -202, 105, -89, +383, 67, 612, 192, 680, 221, 565, 155, +326, 34, 24, -83, -300, -131, -561, -92, +-659, 4, -579, 112, -408, 174, -180, 143, +88, 32, 307, -95, 411, -172, 436, -160, +403, -57, 301, 76, 139, 152, -18, 134, +-134, 42, -221, -90, -284, -206, -284, -245, +-216, -189, -134, -59, -79, 102, -16, 245, +79, 322, 184, 314, 256, 234, 307, 117, +342, -15, 285, -161, 94, -290, -129, -341, +-315, -308, -473, -226, -557, -101, -468, 60, +-219, 195, 69, 260, 290, 260, 441, 213, +511, 128, 460, 46, 318, -1, 185, -7, +87, 15, -24, 30, -163, 10, -282, -44, +-364, -133, -457, -245, -553, -335, -530, -360, +-356, -302, -99, -178, 203, -3, 511, 201, +734, 382, 809, 494, 712, 545, 467, 543, +134, 465, -221, 291, -538, 49, -741, -219, +-764, -498, -597, -754, -322, -910, -20, -904, +274, -718, 514, -372, 601, 87, 521, 572, +324, 946, 37, 1104, -296, 1010, -544, 682, +-603, 204, -458, -276, -187, -603, 145, -690, +483, -553, 707, -275, 720, 12, 543, 185, +222, 166, -187, -35, -553, -296, -734, -476, +-704, -491, -521, -316, -258, 14, 26, 408, +259, 726, 382, 849, 386, 755, 330, 491, +259, 116, 180, -287, 87, -615, 18, -785, +-3, -774, -25, -593, -95, -272, -149, 100, +-154, 411, -163, 597, -195, 630, -180, 508, +-104, 260, -21, -36, 42, -293, 123, -440, +219, -458, 244, -370, 168, -215, 83, -18, +35, 176, -28, 308, -94, 358, -92, 325, +-45, 216, -50, 51, -127, -118, -197, -246, +-230, -318, -227, -310, -120, -202, 137, -20, +422, 172, 598, 333, 617, 433, 478, 427, +176, 286, -227, 51, -602, -212, -811, -440, +-814, -599, -646, -635, -318, -511, 114, -265, +487, 41, 687, 344, 739, 585, 690, 711, +491, 699, 149, 549, -185, 288, -398, -6, +-547, -265, -616, -448, -481, -528, -198, -509, +45, -427, 200, -313, 322, -175, 370, -47, +264, 39, 76, 113, -45, 203, -68, 282, +-71, 325, -58, 338, 16, 337, 84, 327, +43, 282, -61, 188, -135, 46, -176, -152, +-220, -397, -217, -626, -98, -762, 86, -756, +236, -569, 354, -214, 432, 209, 407, 586, +269, 830, 69, 881, -135, 741, -303, 460, +-421, 112, -475, -213, -446, -450, -342, -581, +-212, -608, -65, -526, 122, -357, 322, -145, +467, 68, 564, 253, 638, 367, 591, 379, +337, 290, -17, 137, -343, -40, -636, -191, +-844, -250, -830, -190, -581, -50, -235, 122, +94, 282, 400, 362, 637, 320, 699, 158, +567, -83, 356, -325, 136, -491, -84, -538, +-262, -449, -333, -240, -311, 33, -262, 299, +-237, 497, -204, 571, -157, 482, -112, 276, +-41, 28, 90, -204, 238, -369, 370, -417, +449, -338, 408, -181, 230, -30, -26, 63, +-285, 100, -454, 106, -471, 105, -327, 139, +-86, 238, 151, 341, 285, 356, 279, 242, +161, 2, 6, -320, -115, -612, -150, -754, +-78, -674, 65, -378, 169, 52, 173, 476, +84, 752, -66, 788, -218, 588, -284, 243, +-226, -124, -64, -403, 124, -505, 266, -411, +323, -189, 280, 52, 137, 206, -39, 231, +-168, 130, -224, -57, -209, -229, -137, -289, +-44, -211, 43, -28, 95, 192, 104, 374, +86, 440, 48, 344, -23, 120, -99, -147, +-135, -370, -109, -498, -48, -496, 18, -347, +97, -95, 186, 176, 213, 399, 175, 536, +127, 542, 61, 402, -48, 170, -151, -78, +-199, -301, -209, -452, -206, -473, -163, -362, +-67, -172, 34, 33, 105, 195, 159, 271, +178, 233, 128, 98, 38, -76, -27, -224, +-52, -295, -48, -264, -19, -119, 41, 116, +95, 352, 87, 505, 23, 542, -26, 465, +-55, 275, -97, 4, -119, -277, -100, -499, +-85, -626, -95, -646, -101, -551, -63, -360, +16, -117, 117, 127, 228, 326, 320, 441, +341, 453, 268, 400, 108, 342, -95, 295, +-272, 248, -389, 187, -446, 87, -398, -87, +-244, -328, -48, -559, 143, -690, 304, -656, +413, -452, 450, -133, 380, 210, 213, 467, +-3, 553, -217, 460, -378, 253, -418, 40, +-314, -101, -106, -131, 122, -49, 302, 96, +386, 218, 326, 264, 107, 207, -173, 45, +-397, -198, -518, -443, -509, -602, -333, -640, +-23, -540, 319, -292, 597, 65, 748, 430, +722, 707, 502, 825, 130, 743, -274, 478, +-611, 111, -795, -260, -766, -532, -531, -625, +-169, -528, 223, -291, 518, 1, 631, 249, +556, 370, 331, 335, 40, 169, -216, -63, +-383, -285, -434, -434, -377, -465, -250, -358, +-76, -136, 118, 151, 285, 450, 410, 692, +478, 801, 449, 728, 299, 465, 60, 59, +-210, -383, -462, -746, -656, -926, -705, -868, +-546, -593, -240, -198, 98, 186, 416, 458, +655, 577, 727, 545, 603, 396, 339, 194, +14, 4, -302, -134, -533, -210, -603, -223, +-497, -174, -278, -90, -7, 9, 260, 95, +421, 129, 426, 97, 298, 26, 76, -51, +-164, -97, -316, -92, -321, -44, -194, 13, +1, 57, 207, 55, 360, -8, 388, -107, +267, -184, 61, -203, -169, -156, -374, -50, +-501, 78, -499, 192, -352, 270, -112, 292, +131, 258, 336, 184, 485, 79, 543, -49, +487, -173, 350, -267, 159, -310, -58, -293, +-260, -221, -402, -123, -476, -30, -491, 32, +-452, 49, -331, 42, -118, 56, 145, 113, +396, 213, 566, 326, 587, 401, 455, 374, +215, 214, -74, -47, -323, -332, -452, -547, +-438, -608, -287, -491, -65, -242, 137, 44, +237, 266, 189, 352, 38, 303, -94, 188, +-145, 84, -97, 41, 38, 65, 210, 116, +347, 136, 379, 83, 279, -43, 83, -193, +-184, -306, -462, -332, -642, -258, -670, -112, +-551, 58, -283, 195, 88, 280, 458, 310, +749, 280, 912, 202, 869, 88, 600, -58, +187, -210, -257, -324, -650, -364, -886, -320, +-881, -189, -671, -12, -372, 151, -42, 269, +283, 322, 513, 303, 592, 251, 579, 205, +494, 161, 317, 100, 91, 9, -130, -119, +-331, -270, -489, -406, -554, -485, -452, -480, +-214, -374, 46, -177, 270, 63, 438, 289, +474, 473, 356, 588, 154, 611, -38, 531, +-179, 358, -270, 115, -280, -165, -200, -446, +-104, -659, -48, -741, -12, -661, 33, -442, +78, -117, 113, 240, 134, 529, 149, 680, +145, 661, 107, 483, 34, 212, -35, -73, +-79, -326, -109, -498, -135, -540, -146, -466, +-129, -315, -116, -105, -138, 126, -147, 301, +-91, 391, 13, 393, 139, 301, 292, 150, +429, 13, 493, -64, 445, -75, 279, -44, +31, -29, -280, -91, -599, -229, -796, -396, +-798, -517, -619, -519, -301, -363, 87, -67, +448, 301, 698, 625, 783, 803, 718, 801, +530, 631, 240, 339, -78, 3, -330, -325, +-480, -599, -517, -759, -468, -767, -350, -638, +-182, -399, -13, -79, 112, 243, 197, 472, +236, 571, 200, 537, 99, 406, 15, 244, +-5, 123, 18, 61, 53, 26, 105, -23, +147, -109, 126, -244, 31, -408, -72, -538, +-167, -555, -272, -424, -332, -171, -273, 142, +-107, 448, 93, 677, 262, 764, 389, 681, +442, 461, 351, 165, 141, -154, -86, -458, +-288, -671, -452, -733, -528, -637, -458, -409, +-242, -87, 12, 258, 223, 530, 400, 647, +506, 594, 473, 402, 334, 136, 177, -116, +6, -260, -192, -270, -356, -201, -402, -124, +-355, -79, -280, -86, -161, -119, 14, -137, +163, -94, 229, 24, 237, 180, 206, 292, +102, 317, -41, 254, -137, 125, -149, -19, +-106, -99, -28, -116, 88, -116, 209, -120, +240, -156, 161, -238, 40, -325, -104, -337, +-269, -215, -390, 27, -373, 329, -202, 595, +26, 741, 231, 695, 398, 432, 457, 17, +336, -431, 101, -805, -150, -1001, -352, -941, +-451, -628, -412, -149, -218, 368, 60, 788, +296, 1001, 432, 940, 470, 629, 389, 177, +187, -271, -69, -614, -281, -794, -415, -773, +-497, -578, -487, -307, -339, -39, -111, 199, +114, 389, 336, 499, 547, 523, 639, 475, +543, 351, 333, 148, 81, -98, -195, -329, +-445, -480, -579, -514, -557, -428, -436, -251, +-264, -43, -25, 109, 217, 154, 345, 116, +369, 49, 356, 0, 298, 31, 185, 169, +61, 364, -17, 513, -86, 533, -185, 381, +-237, 78, -212, -301, -201, -652, -192, -869, +-115, -886, 5, -704, 115, -369, 193, 51, +225, 468, 191, 795, 75, 978, -60, 971, +-128, 769, -107, 407, -26, -39, 81, -472, +184, -775, 231, -885, 152, -800, -48, -546, +-282, -197, -459, 133, -516, 388, -396, 545, +-87, 575, 293, 486, 570, 341, 676, 171, +605, -21, 352, -200, -19, -300, -370, -307, +-584, -245, -617, -139, -502, -4, -250, 115, +83, 166, 334, 153, 424, 105, 396, 41, +282, -11, 112, -45, -79, -57, -223, -51, +-260, -32, -223, -12, -148, 12, -24, 53, +103, 90, 178, 81, 191, 32, 169, -32, +146, -93, 94, -133, -16, -120, -127, -39, +-211, 76, -289, 162, -324, 183, -257, 124, +-92, -10, 117, -172, 313, -268, 467, -263, +508, -164, 372, 11, 100, 194, -192, 287, +-415, 264, -523, 151, -469, -10, -250, -155, +24, -215, 255, -199, 391, -154, 380, -119, +231, -132, 20, -181, -177, -189, -275, -109, +-243, 70, -111, 319, 64, 554, 192, 650, +228, 533, 178, 213, 30, -215, -157, -618, +-286, -864, -309, -873, -208, -629, -10, -226, +204, 186, 355, 508, 372, 670, 248, 623, +53, 407, -151, 132, -305, -103, -349, -241, +-272, -256, -122, -172, 26, -45, 120, 53, +145, 60, 110, -27, 53, -150, 40, -254, +104, -284, 200, -195, 238, -3, 191, 196, +80, 324, -103, 358, -320, 289, -466, 137, +-481, -27, -373, -137, -173, -162, 93, -127, +370, -72, 532, -28, 534, -9, 430, -13, +244, -8, 12, 26, -207, 94, -385, 159, +-476, 186, -443, 150, -302, 47, -81, -98, +150, -228, 322, -285, 388, -221, 320, -55, +173, 146, 13, 309, -149, 387, -260, 335, +-261, 165, -179, -39, -67, -190, 52, -255, +163, -220, 225, -91, 199, 58, 129, 145, +63, 159, -34, 104, -170, -11, -262, -133, +-250, -199, -165, -191, -37, -109, 145, 28, +310, 178, 339, 289, 231, 315, 58, 231, +-142, 77, -333, -98, -429, -236, -342, -286, +-116, -214, 120, -55, 316, 119, 449, 224, +435, 219, 273, 113, 54, -60, -135, -237, +-277, -344, -388, -345, -415, -258, -325, -128, +-197, 21, -70, 160, 90, 262, 257, 315, +369, 330, 396, 310, 365, 247, 314, 129, +201, -15, 22, -155, -147, -274, -285, -365, +-407, -419, -494, -442, -499, -431, -394, -385, +-211, -280, 15, -106, 271, 129, 506, 379, +628, 591, 591, 706, 447, 675, 251, 501, +-1, 244, -246, -51, -372, -319, -383, -492, +-367, -556, -342, -553, -275, -500, -177, -414, +-100, -319, -12, -200, 142, -34, 287, 160, +350, 361, 360, 531, 332, 604, 256, 546, +129, 389, -9, 168, -91, -57, -140, -211, +-199, -259, -234, -236, -249, -199, -272, -194, +-279, -221, -249, -265, -152, -301, 6, -271, +179, -118, 350, 102, 490, 307, 533, 464, +452, 530, 274, 451, 29, 273, -256, 82, +-515, -79, -636, -185, -573, -213, -382, -190, +-113, -147, 182, -102, 407, -80, 472, -87, +393, -79, 243, -33, 50, 54, -126, 179, +-193, 322, -167, 408, -122, 373, -71, 198, +-34, -76, -35, -366, -60, -576, -58, -612, +16, -418, 105, -55, 158, 349, 201, 659, +195, 784, 101, 672, -23, 376, -126, 14, +-202, -305, -236, -509, -225, -558, -166, -479, +-86, -333, -13, -174, 58, -29, 121, 87, +178, 178, 234, 248, 257, 292, 218, 293, +144, 262, 50, 195, -50, 103, -128, 13, +-148, -56, -132, -115, -136, -165, -161, -207, +-182, -251, -208, -299, -221, -313, -183, -270, +-69, -171, 94, -26, 253, 136, 406, 273, +530, 358, 543, 373, 422, 331, 205, 257, +-64, 156, -335, 18, -564, -143, -676, -311, +-624, -482, -456, -618, -204, -647, 99, -523, +363, -243, 516, 125, 525, 489, 419, 754, +272, 849, 98, 722, -85, 417, -195, 33, +-234, -352, -253, -680, -251, -864, -200, -865, +-105, -698, -1, -386, 90, 36, 176, 465, +214, 789, 170, 921, 68, 816, -50, 492, +-152, 53, -192, -369, -136, -653, -4, -728, +139, -593, 248, -331, 282, -51, 211, 160, +62, 265, -131, 263, -336, 206, -473, 145, +-491, 111, -375, 102, -144, 113, 151, 126, +468, 117, 718, 86, 779, 33, 639, -54, +337, -158, -87, -261, -512, -333, -807, -337, +-893, -254, -741, -89, -407, 146, 10, 386, +390, 544, 607, 572, 622, 474, 476, 261, +246, -1, 33, -229, -107, -374, -165, -424, +-146, -380, -91, -287, -47, -170, -32, -40, +-42, 82, -72, 199, -123, 335, -160, 443, +-147, 472, -98, 408, -19, 252, 83, 12, +177, -238, 237, -431, 245, -522, 211, -481, +147, -323, 25, -125, -135, 76, -260, 253, +-310, 355, -274, 371, -178, 344, -47, 277, +111, 165, 238, 40, 301, -72, 322, -158, +277, -207, 145, -237, -32, -264, -202, -294, +-323, -324, -381, -334, -367, -258, -248, -75, +-80, 197, 58, 503, 172, 742, 256, 795, +272, 626, 234, 272, 191, -175, 177, -583, +167, -822, 111, -858, 15, -717, -99, -456, +-241, -153, -378, 108, -423, 296, -347, 422, +-223, 496, -85, 502, 87, 446, 242, 325, +298, 136, 268, -88, 223, -280, 202, -419, +185, -485, 166, -462, 148, -364, 72, -237, +-98, -99, -290, 40, -438, 171, -505, 280, +-469, 354, -317, 364, -47, 297, 253, 156, +470, -32, 590, -210, 591, -319, 427, -348, +149, -286, -153, -159, -415, -20, -573, 94, +-593, 171, -449, 202, -177, 220, 139, 242, +428, 240, 594, 183, 569, 67, 390, -120, +114, -349, -200, -527, -455, -570, -557, -453, +-488, -181, -295, 181, -23, 520, 251, 732, +420, 757, 438, 591, 350, 301, 200, -24, +19, -307, -148, -495, -256, -553, -299, -492, +-283, -347, -195, -153, -68, 63, 34, 249, +105, 364, 155, 391, 164, 339, 145, 224, +111, 85, 56, -28, -8, -90, -60, -107, +-71, -84, -38, -40, 0, 4, 39, 37, +63, 60, 25, 56, -50, 17, -123, -61, +-195, -153, -245, -229, -228, -247, -117, -166, +70, 36, 256, 297, 390, 521, 428, 624, +333, 545, 144, 269, -74, -118, -264, -503, +-378, -772, -391, -829, -299, -659, -136, -337, +53, 60, 199, 444, 241, 706, 195, 786, +124, 711, 42, 497, -29, 165, -56, -208, +-58, -529, -55, -741, -44, -788, -23, -650, +-6, -362, -18, 8, -32, 354, -16, 565, +4, 602, 31, 467, 80, 201, 103, -99, +72, -316, 13, -409, -52, -372, -99, -233, +-123, -56, -120, 97, -78, 201, -15, 223, +58, 175, 130, 87, 159, -19, 137, -131, +88, -217, 29, -258, -21, -241, -51, -159, +-62, -26, -79, 97, -122, 167, -164, 156, +-186, 70, -187, -51, -141, -142, -37, -154, +111, -65, 268, 97, 393, 263, 456, 358, +421, 349, 274, 223, 66, 10, -173, -224, +-397, -407, -544, -516, -589, -529, -524, -436, +-363, -246, -137, -13, 124, 225, 356, 444, +499, 597, 557, 634, 519, 555, 381, 382, +186, 151, -29, -99, -215, -318, -338, -474, +-400, -535, -385, -510, -302, -403, -183, -222, +-37, 9, 120, 244, 240, 434, 296, 529, +288, 514, 217, 396, 79, 195, -106, -45, +-274, -231, -368, -324, -371, -328, -265, -238, +-49, -68, 215, 96, 432, 202, 552, 243, +557, 213, 416, 100, 156, -46, -132, -168, +-381, -226, -554, -201, -609, -85, -526, 77, +-331, 242, -110, 354, 77, 367, 235, 261, +337, 68, 354, -161, 331, -346, 302, -443, +251, -420, 166, -284, 66, -80, -14, 134, +-99, 311, -216, 406, -316, 401, -355, 311, +-336, 170, -270, 3, -162, -164, -13, -299, +145, -370, 246, -368, 295, -285, 322, -134, +305, 46, 217, 187, 96, 263, -18, 247, +-131, 139, -248, -15, -313, -145, -297, -209, +-248, -191, -183, -105, -59, 12, 114, 105, +267, 155, 346, 146, 364, 82, 317, 2, +172, -73, -44, -160, -246, -228, -382, -249, +-442, -226, -409, -158, -231, -35, 48, 116, +287, 249, 422, 309, 459, 270, 363, 138, +143, -33, -132, -202, -354, -315, -446, -329, +-417, -241, -269, -104, -11, 52, 259, 189, +443, 270, 493, 281, 400, 229, 192, 119, +-67, -7, -307, -135, -453, -265, -484, -358, +-412, -369, -245, -320, -5, -205, 234, -14, +401, 213, 466, 421, 433, 580, 311, 637, +120, 554, -97, 342, -272, 40, -381, -297, +-422, -577, -358, -730, -183, -719, 25, -553, +203, -273, 329, 38, 371, 307, 300, 475, +148, 528, -22, 489, -156, 409, -241, 319, +-259, 253, -188, 205, -73, 153, 25, 57, +100, -96, 127, -298, 91, -496, 34, -638, +-4, -674, -16, -587, -18, -366, 2, -51, +58, 284, 103, 576, 110, 800, 96, 912, +52, 873, -41, 680, -148, 369, -237, -37, +-297, -475, -302, -843, -207, -1046, -28, -1039, +175, -795, 354, -370, 474, 130, 479, 588, +357, 910, 135, 999, -127, 852, -357, 523, +-482, 93, -470, -338, -348, -653, -162, -796, +51, -740, 228, -506, 305, -171, 286, 156, +206, 403, 78, 511, -53, 464, -129, 305, +-117, 117, -63, -54, -4, -163, 68, -204, +116, -205, 90, -204, 29, -202, -20, -198, +-60, -168, -89, -91, -84, 24, -55, 146, +-34, 237, -45, 237, -69, 139, -99, -25, +-121, -192, -98, -298, 0, -291, 141, -177, +270, 11, 334, 205, 314, 337, 216, 346, +65, 242, -112, 66, -256, -137, -322, -320, +-309, -408, -242, -395, -121, -302, 13, -159, +109, 15, 153, 162, 165, 252, 145, 276, +85, 242, -9, 149, -87, 33, -127, -79, +-138, -147, -96, -144, 22, -70, 163, 31, +268, 137, 306, 217, 270, 234, 157, 157, +-11, 12, -187, -164, -314, -313, -381, -407, +-384, -419, -330, -332, -230, -144, -105, 87, +23, 320, 154, 505, 294, 597, 411, 563, +463, 430, 444, 217, 363, -26, 213, -228, +8, -347, -210, -404, -382, -387, -482, -308, +-500, -209, -436, -115, -298, -3, -121, 111, +65, 219, 225, 302, 326, 349, 352, 341, +321, 288, 241, 189, 133, 65, 37, -45, +-21, -115, -36, -161, -18, -175, -8, -164, +-34, -144, -105, -134, -210, -130, -325, -124, +-393, -86, -367, -19, -219, 82, 19, 209, +288, 352, 517, 457, 641, 480, 617, 381, +455, 170, 178, -119, -172, -419, -512, -671, +-748, -794, -816, -747, -685, -527, -385, -185, +11, 217, 416, 589, 738, 853, 899, 938, +855, 830, 599, 542, 200, 125, -238, -333, +-616, -710, -867, -935, -919, -957, -751, -780, +-417, -446, -25, -58, 353, 295, 659, 528, +820, 595, 771, 506, 547, 337, 232, 139, +-100, -18, -390, -96, -551, -104, -551, -88, +-432, -74, -266, -96, -80, -154, 99, -234, +219, -286, 237, -284, 205, -218, 172, -125, +128, -16, 56, 86, -19, 163, -70, 205, +-98, 248, -106, 285, -66, 290, 16, 242, +86, 140, 106, -32, 87, -241, 29, -438, +-59, -558, -152, -550, -196, -385, -168, -120, +-78, 188, 40, 467, 152, 648, 213, 664, +194, 521, 98, 255, -20, -53, -116, -331, +-174, -503, -189, -540, -139, -442, -38, -260, +69, -46, 154, 133, 232, 247, 259, 285, +191, 268, 57, 219, -81, 175, -213, 142, +-311, 125, -329, 95, -233, 50, -65, -7, +104, -57, 234, -101, 304, -122, 280, -118, +174, -90, 23, -66, -120, -47, -228, -36, +-275, -23, -253, -9, -158, 19, -24, 50, +118, 109, 248, 186, 349, 252, 380, 284, +321, 297, 166, 259, -53, 161, -284, 2, +-466, -181, -548, -356, -494, -472, -323, -503, +-90, -413, 146, -214, 346, 42, 463, 273, +486, 441, 412, 503, 270, 437, 89, 262, +-85, 56, -213, -131, -278, -236, -293, -253, +-250, -203, -162, -120, -60, -31, 22, 7, +72, -4, 71, -62, 25, -137, -33, -189, +-63, -175, -59, -108, -23, 17, 44, 179, +141, 327, 231, 383, 289, 333, 287, 170, +206, -79, 50, -350, -135, -544, -312, -606, +-440, -499, -475, -253, -381, 62, -188, 352, +59, 550, 301, 580, 474, 446, 507, 190, +388, -103, 167, -371, -82, -548, -299, -599, +-416, -497, -415, -288, -315, -20, -155, 234, +38, 423, 226, 494, 382, 435, 472, 259, +461, 37, 324, -171, 101, -311, -154, -356, +-400, -294, -596, -166, -660, -14, -548, 110, +-285, 182, 37, 181, 345, 135, 559, 51, +616, -47, 509, -139, 309, -178, 84, -165, +-109, -84, -237, 41, -271, 187, -229, 314, +-162, 391, -106, 355, -63, 217, -43, 16, +-48, -196, -80, -378, -110, -453, -101, -407, +-42, -247, 43, -24, 142, 197, 235, 347, +297, 418, 299, 398, 246, 300, 147, 163, +22, 50, -108, -52, -199, -136, -250, -195, +-276, -215, -289, -200, -281, -136, -244, -43, +-172, 85, -54, 213, 124, 295, 319, 292, +471, 217, 531, 71, 482, -100, 313, -258, +54, -346, -224, -329, -434, -185, -543, 35, +-535, 266, -404, 433, -172, 501, 77, 421, +269, 200, 375, -95, 407, -359, 343, -523, +189, -540, 1, -424, -147, -200, -241, 63, +-255, 288, -183, 404, -52, 421, 64, 360, +120, 249, 106, 82, 47, -86, -38, -232, +-107, -349, -137, -439, -108, -452, -20, -378, +95, -215, 189, -6, 241, 215, 230, 393, +145, 492, -4, 454, -160, 301, -291, 78, +-373, -150, -372, -343, -259, -454, -57, -473, +191, -392, 410, -237, 538, -53, 521, 85, +361, 184, 95, 238, -203, 234, -448, 164, +-554, 75, -501, -22, -335, -95, -125, -136, +87, -145, 246, -119, 322, -44, 307, 26, +236, 71, 139, 77, 56, 50, 6, -21, +-6, -108, -2, -180, 6, -183, -6, -122, +-46, -11, -115, 112, -193, 223, -264, 272, +-293, 229, -259, 98, -143, -61, 23, -210, +194, -289, 324, -270, 395, -151, 375, 25, +265, 221, 113, 358, -6, 409, -89, 348, +-152, 202, -200, 11, -219, -170, -230, -316, +-244, -379, -240, -361, -176, -261, -65, -111, +71, 73, 211, 249, 331, 381, 363, 421, +302, 383, 194, 288, 85, 174, -29, 44, +-131, -56, -207, -109, -245, -126, -251, -157, +-212, -197, -133, -245, -34, -263, 62, -235, +139, -149, 159, -6, 133, 190, 87, 359, +45, 462, 14, 480, 17, 422, 60, 285, +119, 114, 145, -64, 115, -209, 14, -322, +-133, -402, -274, -448, -355, -432, -371, -361, +-321, -226, -206, -50, -29, 161, 163, 370, +347, 545, 500, 628, 590, 594, 560, 434, +410, 197, 165, -104, -131, -420, -435, -681, +-658, -803, -744, -766, -675, -563, -482, -251, +-198, 124, 121, 467, 415, 685, 608, 712, +673, 574, 618, 308, 468, -9, 225, -314, +-70, -509, -345, -566, -517, -497, -563, -362, +-493, -186, -326, -17, -93, 127, 130, 206, +283, 235, 348, 242, 347, 242, 281, 202, +183, 129, 94, 30, 21, -70, -83, -183, +-215, -295, -328, -390, -375, -428, -359, -407, +-272, -312, -105, -159, 126, 51, 337, 282, +465, 485, 480, 603, 399, 631, 245, 543, +66, 361, -104, 95, -243, -218, -350, -516, +-397, -731, -378, -850, -301, -825, -192, -638, +-58, -295, 77, 124, 202, 542, 282, 862, +314, 1034, 300, 1010, 257, 804, 187, 440, +101, 16, 1, -389, -97, -711, -192, -918, +-262, -947, -298, -809, -286, -526, -225, -152, +-108, 267, 29, 651, 145, 928, 201, 1013, +213, 911, 201, 638, 188, 260, 153, -156, +91, -517, 3, -757, -84, -815, -168, -716, +-226, -485, -233, -172, -175, 185, -86, 498, +17, 691, 105, 720, 152, 616, 133, 393, +80, 104, 37, -183, 34, -388, 48, -475, +62, -436, 53, -332, 24, -195, -44, -65, +-131, 52, -189, 141, -166, 222, -83, 306, +21, 404, 102, 443, 150, 382, 138, 207, +69, -52, -23, -357, -84, -610, -115, -736, +-120, -667, -98, -436, -37, -114, 31, 202, +81, 452, 123, 584, 180, 591, 208, 479, +181, 317, 100, 140, -10, -34, -141, -212, +-245, -371, -287, -497, -256, -552, -187, -554, +-105, -483, -29, -335, 35, -123, 84, 99, +145, 314, 219, 483, 300, 609, 343, 647, +314, 569, 199, 359, 14, 69, -211, -276, +-414, -613, -537, -871, -523, -943, -376, -803, +-132, -490, 143, -90, 382, 322, 505, 641, +505, 816, 403, 786, 242, 585, 34, 298, +-179, 5, -335, -271, -387, -462, -357, -551, +-276, -541, -174, -474, -69, -363, -1, -218, +41, -32, 97, 159, 202, 352, 319, 511, +417, 622, 468, 631, 433, 507, 251, 246, +-61, -83, -405, -427, -666, -698, -783, -838, +-701, -782, -425, -522, -24, -111, 353, 321, +593, 696, 655, 926, 563, 965, 346, 788, +74, 446, -183, 23, -342, -375, -386, -695, +-332, -870, -211, -880, -40, -698, 120, -361, +222, 58, 243, 465, 208, 807, 109, 988, +-28, 961, -143, 730, -175, 377, -150, -21, +-95, -384, -26, -673, 31, -812, 18, -794, +-41, -650, -83, -430, -65, -141, -4, 186, +96, 516, 200, 766, 268, 899, 255, 873, +175, 683, 58, 340, -50, -85, -139, -512, +-184, -824, -190, -973, -172, -926, -174, -695, +-191, -317, -187, 116, -120, 524, -14, 801, +112, 914, 249, 840, 372, 595, 409, 222, +340, -180, 193, -520, 25, -710, -146, -756, +-284, -663, -366, -471, -374, -228, -328, -14, +-229, 150, -75, 262, 118, 370, 275, 453, +346, 490, 336, 468, 279, 386, 163, 212, +18, -44, -105, -343, -160, -580, -183, -723, +-199, -745, -202, -642, -180, -426, -166, -163, +-143, 119, -67, 358, 81, 539, 239, 655, +360, 695, 410, 612, 368, 425, 211, 148, +0, -171, -195, -500, -328, -764, -399, -900, +-393, -851, -319, -644, -187, -308, -37, 80, +110, 468, 238, 772, 341, 926, 392, 882, +376, 661, 285, 291, 138, -131, -61, -536, +-268, -812, -420, -873, -465, -714, -430, -420, +-340, -49, -190, 292, 21, 525, 239, 592, +419, 526, 539, 386, 578, 237, 485, 92, +283, -23, 25, -120, -235, -193, -478, -269, +-639, -337, -662, -356, -536, -269, -318, -118, +-50, 77, 222, 268, 458, 415, 595, 472, +612, 417, 515, 250, 334, 62, 87, -105, +-170, -218, -381, -267, -491, -235, -499, -145, +-411, -33, -253, 36, -60, 78, 92, 92, +188, 103, 246, 122, 298, 166, 319, 208, +294, 248, 225, 222, 130, 114, -19, -83, +-214, -316, -391, -522, -453, -615, -396, -550, +-251, -286, -46, 115, 181, 544, 333, 866, +369, 1000, 315, 890, 212, 552, 62, 45, +-83, -478, -157, -896, -151, -1120, -143, -1122, +-147, -898, -136, -506, -89, 0, -22, 500, +49, 908, 99, 1150, 131, 1181, 126, 964, +85, 540, 13, -24, -62, -583, -117, -1030, +-125, -1262, -83, -1226, 2, -921, 66, -432, +88, 132, 83, 618, 68, 945, 18, 1044, +-47, 905, -87, 555, -76, 104, -50, -343, +-15, -660, 44, -814, 116, -780, 147, -574, +125, -255, 62, 61, -20, 312, -123, 445, +-206, 489, -237, 442, -214, 327, -165, 173, +-78, 18, 49, -150, 184, -310, 254, -467, +260, -573, 235, -586, 200, -483, 136, -276, +55, 39, -38, 391, -122, 712, -197, 901, +-240, 924, -250, 773, -228, 467, -190, 27, +-137, -444, -79, -863, 5, -1132, 103, -1205, +186, -1066, 251, -720, 315, -195, 336, 388, +289, 924, 191, 1297, 79, 1451, -63, 1352, +-224, 1003, -355, 440, -410, -198, -408, -803, +-355, -1265, -234, -1499, -40, -1429, 167, -1056, +350, -455, 476, 215, 516, 838, 428, 1269, +235, 1423, -10, 1260, -232, 845, -394, 313, +-456, -184, -406, -598, -259, -855, -85, -938, +65, -871, 164, -702, 218, -451, 227, -138, +206, 254, 173, 661, 152, 1001, 118, 1178, +57, 1127, -32, 813, -122, 279, -205, -378, +-265, -964, -282, -1340, -221, -1416, -120, -1178, +-19, -686, 76, -75, 174, 532, 227, 988, +230, 1241, 205, 1266, 176, 1080, 115, 715, +22, 241, -68, -282, -132, -746, -198, -1098, +-255, -1276, -262, -1239, -182, -962, -51, -499, +94, 75, 228, 638, 322, 1108, 325, 1373, +230, 1362, 74, 1063, -96, 539, -267, -123, +-393, -775, -422, -1302, -335, -1577, -176, -1537, +21, -1194, 215, -632, 374, 71, 462, 773, +484, 1354, 441, 1694, 343, 1736, 166, 1458, +-77, 894, -341, 107, -561, -747, -718, -1530, +-781, -2065, -703, -2225, -455, -1949, -93, -1272, +317, -301, 707, 758, 995, 1693, 1081, 2276, +954, 2393, 642, 2031, 200, 1281, -312, 293, +-776, -706, -1096, -1538, -1211, -2033, -1100, -2131, +-764, -1836, -268, -1228, 285, -425, 780, 404, +1125, 1128, 1247, 1616, 1128, 1811, 787, 1682, +291, 1256, -273, 610, -775, -115, -1123, -818, +-1240, -1366, -1106, -1673, -755, -1661, -271, -1319, +262, -701, 740, 57, 1069, 823, 1162, 1436, +1021, 1781, 704, 1765, 296, 1393, -143, 754, +-537, -1, -836, -756, -989, -1357, -987, -1714, +-845, -1768, -591, -1515, -222, -987, 211, -279, +639, 523, 989, 1269, 1204, 1829, 1218, 2083, +997, 1971, 560, 1480, -7, 682, -629, -299, +-1191, -1249, -1552, -1990, -1595, -2359, -1309, -2279, +-747, -1737, -13, -819, 771, 305, 1437, 1378, +1824, 2197, 1830, 2573, 1463, 2408, 780, 1724, +-81, 679, -938, -515, -1586, -1572, -1897, -2271, +-1814, -2453, -1374, -2105, -664, -1328, 150, -328, +893, 680, 1426, 1477, 1680, 1946, 1591, 2008, +1194, 1692, 596, 1086, -61, 322, -658, -485, +-1094, -1184, -1308, -1676, -1265, -1849, -1016, -1674, +-626, -1188, -161, -486, 306, 312, 678, 1029, +908, 1544, 994, 1747, 954, 1612, 760, 1181, +431, 551, 38, -179, -340, -861, -677, -1390, +-917, -1673, -994, -1688, -887, -1413, -639, -872, +-280, -145, 154, 620, 593, 1309, 917, 1771, +1073, 1906, 1050, 1661, 844, 1072, 444, 237, +-80, -664, -608, -1471, -1018, -1994, -1245, -2124, +-1228, -1819, -950, -1137, -455, -204, 132, 783, +678, 1624, 1076, 2118, 1271, 2182, 1223, 1802, +943, 1051, 476, 77, -76, -901, -618, -1703, +-1054, -2154, -1281, -2170, -1230, -1738, -946, -942, +-499, 62, 44, 1047, 591, 1825, 993, 2211, +1173, 2124, 1129, 1579, 881, 708, 463, -291, +-7, -1190, -431, -1815, -752, -2018, -945, -1795, +-956, -1211, -804, -418, -538, 421, -206, 1138, +170, 1613, 522, 1740, 767, 1533, 853, 1040, +785, 359, 584, -381, 312, -1015, 15, -1419, +-265, -1503, -494, -1282, -628, -801, -660, -170, +-598, 466, -471, 962, -278, 1248, -48, 1270, +191, 1059, 408, 654, 581, 145, 669, -371, +655, -810, 518, -1118, 287, -1209, -6, -1073, +-319, -713, -593, -195, -745, 402, -750, 952, +-610, 1327, -345, 1421, 4, 1226, 342, 752, +591, 97, 688, -607, 637, -1201, 464, -1558, +231, -1577, -5, -1271, -207, -679, -356, 72, +-432, 817, -458, 1383, -442, 1644, -393, 1530, +-282, 1100, -89, 436, 173, -305, 432, -954, +621, -1372, 687, -1502, 604, -1321, 361, -884, +31, -263, -288, 396, -515, 963, -630, 1324, +-624, 1403, -490, 1160, -271, 654, -55, -36, +140, -739, 312, -1280, 440, -1527, 494, -1413, +486, -944, 418, -246, 283, 520, 64, 1146, +-185, 1492, -409, 1494, -558, 1173, -604, 600, +-527, -78, -349, -735, -90, -1234, 196, -1503, +446, -1485, 611, -1172, 675, -618, 594, 54, +370, 752, 56, 1320, -262, 1637, -533, 1615, +-715, 1252, -751, 618, -610, -155, -359, -938, +-59, -1524, 257, -1774, 557, -1639, 761, -1157, +823, -415, 745, 424, 546, 1183, 218, 1668, +-185, 1796, -573, 1549, -859, 978, -1011, 194, +-963, -630, -698, -1333, -275, -1746, 192, -1808, +617, -1511, 919, -911, 1047, -104, 966, 758, +714, 1511, 338, 1975, -98, 2073, -525, 1759, +-863, 1054, -1056, 68, -1048, -982, -828, -1868, +-416, -2372, 100, -2393, 606, -1885, 987, -932, +1177, 259, 1128, 1411, 834, 2281, 344, 2668, +-219, 2499, -739, 1780, -1119, 658, -1307, -626, +-1230, -1780, -890, -2566, -351, -2798, 282, -2427, +896, -1499, 1356, -228, 1552, 1102, 1407, 2193, +964, 2820, 319, 2815, -395, 2189, -1048, 1078, +-1497, -251, -1642, -1523, -1450, -2472, -994, -2897, +-366, -2689, 337, -1941, 994, -799, 1461, 514, +1663, 1734, 1558, 2593, 1148, 2928, 495, 2674, +-269, 1900, -992, 714, -1513, -640, -1734, -1883, +-1600, -2766, -1141, -3123, -459, -2853, 303, -2002, +1000, -706, 1494, 758, 1701, 2092, 1565, 3014, +1118, 3317, 448, 2900, -318, 1866, -1042, 419, +-1553, -1119, -1738, -2416, -1562, -3169, -1053, -3225, +-306, -2592, 499, -1442, 1187, -18, 1609, 1347, +1689, 2378, 1419, 2880, 868, 2784, 149, 2131, +-589, 1083, -1215, -161, -1587, -1341, -1642, -2234, +-1371, -2656, -807, -2531, -58, -1889, 698, -883, +1317, 308, 1668, 1427, 1660, 2233, 1282, 2550, +651, 2348, -85, 1673, -786, 655, -1339, -509, +-1610, -1552, -1539, -2271, -1181, -2517, -632, -2254, +47, -1532, 719, -481, 1252, 713, 1542, 1765, +1548, 2457, 1263, 2637, 725, 2269, 30, 1396, +-661, 192, -1227, -1082, -1562, -2094, -1610, -2640, +-1344, -2622, -802, -2044, -91, -993, 632, 284, +1248, 1479, 1653, 2313, 1748, 2648, 1465, 2397, +864, 1604, 64, 452, -751, -756, -1414, -1730, +-1783, -2240, -1764, -2223, -1357, -1715, -688, -874, +94, 78, 812, 903, 1330, 1443, 1558, 1631, +1492, 1516, 1177, 1154, 664, 628, 34, 33, +-552, -506, -980, -935, -1230, -1218, -1305, -1316, +-1144, -1157, -765, -755, -275, -193, 210, 407, +644, 949, 967, 1301, 1104, 1365, 1019, 1090, +800, 578, 498, -25, 125, -571, -279, -970, +-625, -1146, -850, -1072, -944, -775, -919, -371, +-723, 38, -383, 389, 1, 667, 342, 812, +628, 800, 828, 655, 894, 439, 797, 169, +595, -125, 329, -406, 11, -600, -346, -704, +-656, -708, -868, -609, -957, -396, -898, -102, +-665, 231, -287, 520, 143, 711, 510, 751, +813, 638, 1007, 377, 1021, 32, 858, -309, +589, -530, 245, -611, -168, -569, -607, -440, +-955, -234, -1169, -16, -1234, 154, -1090, 238, +-685, 285, -95, 317, 556, 325, 1149, 306, +1557, 294, 1645, 265, 1374, 190, 789, 13, +23, -244, -783, -533, -1455, -775, -1820, -918, +-1792, -881, -1382, -623, -657, -138, 225, 455, +1082, 1026, 1716, 1445, 1988, 1617, 1830, 1451, +1261, 938, 414, 142, -510, -744, -1343, -1527, +-1928, -2043, -2114, -2187, -1825, -1871, -1165, -1127, +-262, -85, 741, 1026, 1628, 1992, 2165, 2617, +2232, 2743, 1834, 2253, 1048, 1214, -25, -159, +-1123, -1538, -1967, -2641, -2390, -3205, -2298, -3042, +-1655, -2144, -599, -746, 600, 836, 1627, 2251, +2281, 3217, 2423, 3490, 2006, 2972, 1102, 1776, +-59, 205, -1195, -1437, -2044, -2828, -2426, -3667, +-2249, -3712, -1553, -2935, -480, -1500, 691, 297, +1701, 2130, 2337, 3583, 2439, 4303, 1982, 4077, +1082, 2940, -73, 1130, -1217, -982, -2106, -2974, +-2529, -4369, -2380, -4841, -1691, -4255, -627, -2727, +577, -572, 1664, 1777, 2419, 3838, 2636, 5087, +2245, 5209, 1351, 4162, 202, 2191, -995, -298, +-2034, -2783, -2657, -4699, -2690, -5547, -2131, -5155, +-1097, -3648, 192, -1372, 1481, 1216, 2458, 3572, +2912, 5163, 2762, 5599, 1999, 4843, 757, 3089, +-648, 686, -1913, -1916, -2805, -4157, -3141, -5519, +-2768, -5677, -1746, -4656, -363, -2666, 1052, -61, +2277, 2631, 3077, 4754, 3204, 5803, 2588, 5578, +1445, 4206, 14, 1936, -1469, -779, -2695, -3319, +-3308, -5075, -3142, -5693, -2311, -5113, -1007, -3512, +565, -1168, 2044, 1434, 3070, 3701, 3404, 5108, +2995, 5387, 1940, 4538, 447, 2750, -1191, 326, +-2604, -2175, -3469, -4131, -3562, -5102, -2881, -4958, +-1563, -3774, 140, -1796, 1877, 592, 3227, 2803, +3885, 4321, 3731, 4867, 2767, 4399, 1143, 3011, +-751, 962, -2486, -1328, -3708, -3276, -4176, -4437, +-3744, -4617, -2466, -3836, -668, -2225, 1225, -90, +2887, 2068, 3986, 3666, 4235, 4388, 3529, 4171, +2067, 3063, 193, 1242, -1718, -856, -3275, -2669, +-4090, -3734, -3970, -3923, -2982, -3265, -1404, -1884, +445, -88, 2177, 1626, 3408, 2844, 3863, 3345, +3459, 3130, 2334, 2247, 748, 858, -1007, -697, +-2529, -2001, -3458, -2782, -3592, -2916, -2953, -2438, +-1701, -1402, -64, -19, 1600, 1339, 2857, 2329, +3437, 2799, 3254, 2678, 2369, 1970, 957, 751, +-637, -683, -2042, -1948, -2956, -2744, -3199, -2930, +-2741, -2439, -1712, -1360, -348, 86, 1054, 1493, +2239, 2495, 2925, 2902, 2940, 2685, 2305, 1863, +1173, 596, -200, -820, -1520, -1983, -2515, -2647, +-2905, -2748, -2597, -2272, -1701, -1228, -454, 136, +873, 1436, 1991, 2323, 2627, 2670, 2622, 2443, +2010, 1630, 953, 351, -293, -1006, -1448, -2055, +-2217, -2567, -2439, -2500, -2104, -1855, -1293, -716, +-202, 635, 896, 1762, 1750, 2390, 2132, 2437, +2002, 1959, 1442, 1021, 601, -207, -340, -1379, +-1177, -2135, -1700, -2380, -1791, -2144, -1519, -1467, +-982, -403, -254, 804, 564, 1791, 1254, 2305, +1639, 2330, 1678, 1869, 1397, 950, 798, -276, +-52, -1439, -927, -2190, -1539, -2398, -1805, -2118, +-1689, -1371, -1166, -259, -334, 954, 567, 1884, +1298, 2307, 1732, 2221, 1808, 1701, 1447, 760, +759, -416, -53, -1477, -829, -2111, -1438, -2250, +-1730, -1945, -1639, -1226, -1220, -161, -576, 958, +210, 1795, 975, 2159, 1537, 2059, 1737, 1522, +1558, 593, 1070, -535, 365, -1460, -417, -1910, +-1099, -1856, -1516, -1389, -1561, -574, -1320, 409, +-861, 1227, -205, 1568, 515, 1436, 1064, 959, +1314, 257, 1304, -533, 1110, -1147, 696, -1360, +112, -1123, -477, -600, -919, 61, -1180, 731, +-1226, 1248, -1001, 1427, -524, 1220, 74, 705, +650, 49, 1050, -644, 1200, -1241, 1069, -1584, +700, -1536, 167, -1122, -438, -453, -928, 321, +-1126, 1081, -1050, 1633, -765, 1805, -327, 1519, +201, 855, 641, -23, 839, -890, 850, -1551, +785, -1808, 614, -1564, 311, -873, -40, 29, +-320, 870, -551, 1439, -757, 1641, -892, 1386, +-858, 725, -634, -116, -302, -863, 72, -1377, +501, -1574, 906, -1389, 1169, -804, 1152, -18, +858, 732, 416, 1308, -93, 1634, -619, 1586, +-1037, 1136, -1242, 392, -1169, -430, -875, -1182, +-435, -1714, 102, -1869, 665, -1550, 1122, -842, +1345, 89, 1273, 1009, 943, 1710, 424, 1989, +-184, 1752, -819, 1062, -1349, 115, -1623, -881, +-1544, -1682, -1111, -2091, -414, -1965, 418, -1323, +1247, -334, 1828, 761, 2011, 1739, 1772, 2315, +1157, 2300, 266, 1673, -720, 614, -1580, -632, +-2137, -1783, -2288, -2550, -1950, -2680, -1190, -2159, +-196, -1135, 821, 153, 1717, 1448, 2329, 2450, +2466, 2905, 2082, 2691, 1299, 1896, 247, 672, +-895, -747, -1917, -2058, -2527, -2935, -2565, -3155, +-2086, -2645, -1191, -1538, 4, -55, 1225, 1477, +2151, 2702, 2558, 3283, 2428, 3074, 1790, 2149, +732, 747, -494, -855, -1561, -2261, -2249, -3088, +-2423, -3132, -2025, -2441, -1147, -1195, -67, 329, +984, 1791, 1794, 2776, 2163, 3043, 1993, 2578, +1371, 1520, 507, 84, -418, -1390, -1266, -2517, +-1790, -2963, -1858, -2653, -1503, -1691, -851, -307, +-44, 1167, 772, 2321, 1407, 2864, 1670, 2670, +1534, 1852, 1068, 612, 387, -773, -391, -1971, +-1068, -2669, -1450, -2736, -1448, -2165, -1112, -1095, +-540, 280, 155, 1639, 827, 2639, 1253, 3008, +1339, 2659, 1090, 1638, 581, 175, -74, -1407, +-753, -2692, -1273, -3320, -1424, -3109, -1186, -2116, +-627, -556, 136, 1188, 944, 2693, 1538, 3537, +1694, 3482, 1382, 2570, 712, 1044, -192, -774, +-1116, -2440, -1775, -3523, -1946, -3741, -1649, -3088, +-959, -1737, 4, 40, 1010, 1872, 1767, 3261, +2074, 3861, 1898, 3554, 1334, 2429, 435, 712, +-621, -1215, -1550, -2863, -2097, -3779, -2143, -3783, +-1709, -2901, -885, -1338, 196, 554, 1249, 2290, +1994, 3419, 2247, 3687, 1981, 3126, 1260, 1855, +249, 127, -834, -1642, -1734, -2974, -2231, -3582, +-2208, -3394, -1710, -2474, -835, -930, 229, 883, +1284, 2467, 2101, 3442, 2472, 3652, 2307, 3042, +1610, 1699, 496, -115, -757, -1906, -1870, -3206, +-2563, -3747, -2670, -3448, -2174, -2330, -1185, -617, +86, 1264, 1340, 2760, 2273, 3527, 2664, 3491, +2454, 2690, 1677, 1220, 522, -569, -719, -2161, +-1725, -3131, -2277, -3377, -2322, -2908, -1867, -1730, +-979, -51, 104, 1619, 1118, 2821, 1809, 3319, +2050, 3085, 1821, 2111, 1159, 556, 236, -1146, +-663, -2482, -1323, -3170, -1634, -3117, -1587, -2363, +-1175, -1021, -484, 605, 301, 2032, 971, 2873, +1392, 3043, 1482, 2559, 1196, 1495, 575, 38, +-182, -1407, -866, -2428, -1304, -2842, -1434, -2664, +-1223, -1879, -664, -607, 93, 830, 827, 2015, +1377, 2694, 1602, 2774, 1438, 2228, 883, 1107, +79, -293, -740, -1595, -1385, -2485, -1736, -2787, +-1718, -2442, -1334, -1525, -627, -229, 263, 1088, +1124, 2096, 1738, 2591, 2011, 2513, 1887, 1886, +1311, 840, 405, -367, -555, -1394, -1361, -2061, +-1916, -2298, -2149, -2058, -1902, -1362, -1189, -416, +-243, 523, 716, 1278, 1548, 1788, 2093, 1923, +2175, 1621, 1705, 995, 869, 230, -85, -547, +-1001, -1195, -1746, -1576, -2097, -1570, -1907, -1207, +-1264, -617, -404, 38, 509, 628, 1315, 1018, +1829, 1151, 1871, 1005, 1476, 667, 811, 260, +4, -120, -813, -429, -1465, -626, -1792, -707, +-1683, -667, -1221, -554, -537, -383, 254, -150, +1026, 128, 1599, 384, 1793, 601, 1556, 720, +1025, 700, 326, 510, -453, 206, -1168, -135, +-1590, -448, -1607, -689, -1306, -762, -820, -652, +-197, -427, 493, -164, 1058, 119, 1290, 393, +1236, 586, 1006, 607, 638, 515, 144, 381, +-365, 200, -710, -69, -841, -349, -843, -516, +-726, -526, -492, -475, -169, -349, 141, -81, +340, 267, 440, 504, 497, 549, 488, 455, +376, 293, 199, 14, 71, -335, -34, -574, +-164, -582, -288, -431, -335, -196, -316, 102, +-290, 450, -238, 702, -104, 741, 53, 588, +198, 329, 314, -21, 392, -417, 403, -756, +321, -901, 142, -835, -95, -597, -334, -208, +-480, 299, -520, 773, -460, 1088, -296, 1172, +-19, 997, 287, 524, 515, -143, 615, -789, +585, -1226, 413, -1399, 126, -1224, -214, -673, +-464, 112, -570, 858, -553, 1382, -425, 1597, +-225, 1435, -14, 830, 196, -52, 334, -932, +386, -1584, 378, -1876, 339, -1688, 269, -1023, +149, -22, 8, 1036, -99, 1871, -208, 2250, +-347, 2076, -475, 1365, -490, 242, -409, -1052, +-284, -2124, -110, -2674, 145, -2576, 445, -1842, +679, -563, 788, 963, 809, 2287, 668, 3018, +299, 3015, -242, 2266, -782, 893, -1162, -780, +-1328, -2266, -1218, -3187, -749, -3332, -49, -2668, +662, -1317, 1228, 379, 1579, 1997, 1588, 3134, +1196, 3511, 524, 3011, -245, 1789, -980, 119, +-1539, -1639, -1778, -3053, -1617, -3712, -1133, -3455, +-396, -2376, 503, -714, 1350, 1231, 1917, 2957, +2084, 3930, 1767, 3878, 987, 2876, -113, 1145, +-1203, -958, -1993, -2908, -2349, -4095, -2175, -4181, +-1421, -3220, -268, -1503, 934, 621, 1876, 2667, +2433, 4051, 2459, 4336, 1841, 3519, 705, 1898, +-566, -184, -1637, -2344, -2368, -3976, -2623, -4534, +-2217, -3885, -1227, -2343, 43, -266, 1244, 1992, +2179, 3863, 2702, 4679, 2578, 4235, 1735, 2815, +472, 799, -807, -1503, -1867, -3529, -2603, -4587, +-2769, -4381, -2182, -3171, -1041, -1296, 250, 917, +1457, 2945, 2446, 4149, 2912, 4229, 2556, 3320, +1507, 1712, 173, -297, -1122, -2208, -2229, -3463, +-2885, -3755, -2761, -3110, -1858, -1726, -551, 51, +809, 1750, 2009, 2876, 2822, 3173, 2909, 2631, +2163, 1428, 888, -102, -525, -1500, -1833, -2403, +-2774, -2618, -3037, -2138, -2469, -1086, -1273, 233, +204, 1413, 1635, 2146, 2725, 2319, 3163, 1893, +2773, 970, 1667, -180, 189, -1190, -1309, -1817, +-2495, -1969, -3127, -1652, -3006, -926, -2137, -25, +-792, 782, 685, 1298, 2013, 1442, 2945, 1221, +3235, 741, 2715, 156, 1551, -343, 69, -642, +-1436, -692, -2689, -536, -3362, -295, -3192, -107, +-2221, -6, -770, -1, 853, -72, 2340, -184, +3322, -223, 3448, -93, 2685, 180, 1311, 444, +-342, 616, -1936, 670, -3080, 555, -3437, 177, +-2888, -383, -1652, -836, -63, -981, 1529, -892, +2748, -604, 3239, -44, 2847, 655, 1722, 1086, +230, 1058, -1268, 758, -2427, 335, -2941, -294, +-2622, -953, -1576, -1218, -150, -977, 1255, -508, +2291, 42, 2691, 682, 2345, 1214, 1296, 1259, +-154, 789, -1558, 83, -2503, -649, -2740, -1294, +-2187, -1600, -920, -1343, 716, -559, 2149, 465, +2952, 1428, 2939, 2034, 2092, 2043, 547, 1393, +-1274, 249, -2752, -1136, -3429, -2331, -3165, -2847, +-2022, -2469, -248, -1373, 1685, 164, 3140, 1822, +3709, 3100, 3308, 3413, 2057, 2642, 242, 1160, +-1700, -605, -3223, -2307, -3877, -3425, -3543, -3467, +-2333, -2419, -563, -772, 1351, 960, 2938, 2399, +3789, 3165, 3723, 2943, 2836, 1836, 1349, 338, +-457, -983, -2196, -1831, -3388, -2120, -3783, -1803, +-3423, -985, -2402, -92, -800, 473, 1044, 665, +2612, 688, 3592, 615, 3935, 459, 3493, 376, +2157, 513, 211, 659, -1762, 526, -3313, 101, +-4212, -426, -4212, -968, -3122, -1425, -1201, -1518, +971, -1019, 2883, -108, 4180, 861, 4515, 1643, +3684, 2034, 1891, 1802, -319, 955, -2399, -189, +-3872, -1244, -4378, -1978, -3755, -2168, -2237, -1686, +-288, -711, 1639, 371, 3102, 1303, 3765, 1901, +3527, 1972, 2500, 1460, 981, 599, -682, -298, +-2073, -1047, -2903, -1519, -3087, -1557, -2633, -1183, +-1625, -579, -294, 73, 1049, 669, 2132, 1088, +2784, 1218, 2799, 1036, 2078, 634, 781, 79, +-682, -545, -1908, -1057, -2645, -1262, -2693, -1109, +-1966, -641, -692, 52, 725, 817, 1875, 1363, +2485, 1454, 2374, 1075, 1532, 366, 251, -523, +-1016, -1332, -1898, -1735, -2173, -1530, -1783, -820, +-862, 130, 279, 1058, 1273, 1703, 1827, 1798, +1814, 1285, 1248, 355, 276, -663, -822, -1481, +-1674, -1889, -2005, -1786, -1714, -1189, -870, -278, +311, 705, 1470, 1516, 2196, 1979, 2262, 1995, +1719, 1552, 673, 717, -658, -335, -1885, -1390, +-2562, -2187, -2480, -2495, -1753, -2208, -567, -1387, +870, -167, 2114, 1199, 2667, 2334, 2372, 2850, +1495, 2614, 307, 1738, -990, 413, -2051, -1085, +-2459, -2286, -2072, -2763, -1152, -2427, -37, -1507, +1077, -266, 1906, 1014, 2167, 1940, 1766, 2194, +916, 1809, -43, 1039, -921, 139, -1600, -694, +-1888, -1244, -1693, -1401, -1110, -1226, -337, -850, +481, -360, 1215, 115, 1746, 500, 1924, 831, +1656, 1119, 998, 1219, 131, 1048, -779, 662, +-1626, 99, -2224, -674, -2268, -1463, -1710, -1867, +-778, -1674, 328, -1016, 1452, -40, 2308, 1100, +2615, 2032, 2276, 2268, 1414, 1692, 222, 617, +-1066, -580, -2110, -1630, -2643, -2173, -2591, -1915, +-1933, -956, -793, 248, 551, 1264, 1757, 1837, +2560, 1841, 2754, 1261, 2242, 302, 1127, -693, +-313, -1380, -1707, -1628, -2634, -1520, -2817, -1157, +-2197, -506, -940, 343, 673, 1129, 2160, 1691, +2956, 2063, 2828, 2095, 1866, 1458, 274, 141, +-1514, -1394, -2869, -2702, -3293, -3493, -2754, -3409, +-1421, -2154, 438, 27, 2232, 2375, 3299, 4098, +3404, 4722, 2674, 4031, 1245, 2081, -626, -625, +-2329, -3188, -3318, -4781, -3438, -5028, -2795, -3996, +-1498, -1953, 249, 582, 1964, 2867, 3118, 4277, +3502, 4602, 3125, 3880, 2013, 2307, 304, 254, +-1558, -1792, -2994, -3406, -3626, -4253, -3392, -4109, +-2331, -2994, -608, -1198, 1345, 904, 2921, 2845, +3668, 4075, 3431, 4201, 2310, 3218, 556, 1399, +-1369, -787, -2908, -2752, -3595, -3935, -3269, -4032, +-2046, -3019, -279, -1162, 1542, 991, 2928, 2787, +3492, 3784, 3083, 3771, 1811, 2721, 8, 884, +-1734, -1167, -2941, -2810, -3388, -3646, -2957, -3536, +-1677, -2491, 71, -773, 1689, 1088, 2802, 2545, +3299, 3293, 2995, 3227, 1789, 2381, 23, 960, +-1625, -630, -2773, -1989, -3298, -2855, -2992, -3053, +-1791, -2512, -46, -1382, 1649, 91, 2848, 1642, +3360, 2892, 2989, 3400, 1700, 2991, -137, 1812, +-1875, 90, -3006, -1860, -3348, -3390, -2865, -3877, +-1572, -3210, 212, -1676, 1885, 376, 2974, 2419, +3314, 3725, 2866, 3810, 1707, 2789, 56, 1106, +-1658, -779, -2902, -2380, -3347, -3200, -3004, -3005, +-1982, -1955, -415, -521, 1375, 829, 2823, 1825, +3443, 2337, 3170, 2199, 2198, 1407, 616, 314, +-1290, -620, -2852, -1279, -3493, -1712, -3173, -1733, +-2159, -1164, -563, -292, 1363, 466, 2855, 1038, +3352, 1464, 2930, 1511, 1874, 1035, 296, 328, +-1461, -264, -2700, -738, -3002, -1085, -2455, -1116, +-1285, -804, 227, -409, 1592, -106, 2309, 136, +2272, 338, 1583, 441, 465, 456, -673, 456, +-1458, 472, -1696, 484, -1369, 437, -650, 259, +170, -26, 776, -353, 1044, -699, 951, -1019, +559, -1128, 62, -887, -310, -385, -464, 202, +-439, 809, -282, 1310, -55, 1459, 99, 1137, +110, 487, 31, -267, -82, -948, -240, -1414, +-353, -1518, -279, -1216, -21, -600, 293, 163, +606, 869, 863, 1332, 912, 1485, 622, 1320, +63, 832, -602, 79, -1210, -718, -1606, -1320, +-1531, -1633, -879, -1619, 89, -1178, 1033, -352, +1795, 566, 2183, 1282, 1871, 1685, 829, 1696, +-461, 1231, -1549, 395, -2218, -480, -2325, -1114, +-1706, -1391, -499, -1299, 799, -891, 1780, -312, +2264, 263, 2147, 659, 1400, 803, 162, 763, +-1089, 607, -1865, 319, -2024, -28, -1712, -268, +-999, -365, 89, -431, 1179, -420, 1754, -198, +1727, 110, 1315, 250, 602, 263, -375, 275, +-1208, 196, -1529, -49, -1391, -258, -945, -271, +-264, -178, 513, -70, 1123, 109, 1335, 316, +1154, 411, 696, 336, 86, 150, -548, -58, +-1041, -226, -1230, -373, -1015, -495, -524, -479, +21, -234, 539, 99, 971, 358, 1104, 581, +839, 803, 381, 820, -32, 504, -446, -11, +-804, -536, -839, -942, -556, -1091, -271, -916, +-84, -469, 149, 119, 381, 682, 419, 986, +315, 903, 307, 558, 441, 159, 415, -187, +154, -384, -102, -357, -310, -167, -597, 17, +-874, 61, -858, -65, -503, -278, -55, -445, +437, -475, 944, -333, 1218, 13, 1083, 488, +664, 843, 76, 850, -651, 553, -1232, 99, +-1351, -417, -1085, -857, -624, -1017, 20, -808, +765, -317, 1229, 273, 1252, 757, 1011, 968, +559, 872, -90, 537, -691, 47, -999, -474, +-971, -842, -751, -971, -429, -877, -32, -579, +347, -150, 540, 251, 549, 546, 520, 773, +512, 928, 410, 882, 139, 596, -179, 192, +-404, -237, -585, -721, -717, -1202, -651, -1435, +-303, -1209, 128, -613, 457, 128, 704, 899, +833, 1587, 652, 1876, 172, 1502, -318, 613, +-628, -369, -755, -1220, -629, -1877, -285, -2080, +114, -1544, 407, -479, 514, 594, 442, 1406, +246, 1953, 48, 2072, -104, 1545, -274, 552, +-359, -467, -241, -1306, -20, -1904, 74, -2067, +82, -1665, 159, -863, 197, 99, 96, 1084, +-15, 1883, -33, 2195, -14, 1927, -58, 1201, +-92, 178, -60, -922, -19, -1775, -62, -2144, +-174, -1959, -206, -1271, -115, -239, -10, 846, +96, 1677, 309, 2057, 601, 1912, 679, 1257, +435, 266, 56, -770, -322, -1573, -722, -1951, +-1010, -1802, -927, -1145, -518, -147, -46, 854, +453, 1551, 938, 1846, 1117, 1715, 883, 1096, +495, 124, 52, -808, -446, -1383, -835, -1597, +-962, -1495, -854, -1027, -573, -267, -115, 494, +426, 1037, 794, 1320, 937, 1365, 911, 1150, +640, 687, 84, 67, -517, -571, -920, -1118, +-1090, -1472, -955, -1524, -437, -1190, 260, -526, +790, 300, 1024, 1100, 1027, 1672, 658, 1808, +-34, 1455, -629, 704, -901, -281, -902, -1226, +-657, -1791, -181, -1844, 355, -1458, 676, -711, +781, 308, 732, 1264, 439, 1757, -48, 1698, +-440, 1254, -628, 523, -690, -395, -571, -1224, +-273, -1640, 4, -1565, 206, -1140, 396, -505, +541, 264, 497, 974, 314, 1369, 192, 1361, +117, 1107, -38, 708, -218, 95, -328, -635, +-405, -1138, -546, -1291, -661, -1274, -563, -1116, +-209, -614, 267, 167, 801, 864, 1215, 1271, +1239, 1449, 877, 1360, 280, 872, -454, 76, +-1144, -708, -1532, -1233, -1472, -1436, -1027, -1316, +-307, -851, 522, -126, 1205, 584, 1519, 1018, +1449, 1157, 1095, 1092, 491, 781, -268, 184, +-931, -445, -1342, -830, -1457, -992, -1320, -1027, +-889, -799, -143, -242, 703, 394, 1366, 861, +1664, 1166, 1560, 1261, 1070, 925, 218, 208, +-735, -519, -1416, -1069, -1639, -1435, -1497, -1443, +-1047, -899, -263, 0, 674, 833, 1394, 1384, +1639, 1615, 1453, 1413, 988, 755, 219, -121, +-707, -905, -1393, -1401, -1610, -1499, -1453, -1199, +-976, -623, -169, 65, 737, 727, 1384, 1197, +1619, 1334, 1468, 1169, 972, 820, 172, 325, +-690, -280, -1290, -840, -1483, -1176, -1368, -1253, +-1026, -1095, -447, -693, 290, -78, 969, 589, +1393, 1112, 1503, 1335, 1314, 1195, 788, 761, +-2, 188, -832, -400, -1407, -877, -1592, -1081, +-1382, -935, -770, -557, 61, -126, 776, 243, +1209, 511, 1285, 632, 971, 594, 403, 409, +-135, 142, -513, -89, -722, -228, -681, -358, +-401, -482, -112, -450, -29, -233, -27, -27, +97, 111, 192, 316, 189, 526, 245, 482, +376, 215, 372, -19, 136, -175, -109, -386, +-198, -552, -280, -475, -419, -216, -437, 18, +-208, 214, 71, 409, 156, 511, 115, 421, +196, 201, 326, -60, 256, -335, 108, -579, +103, -677, 112, -564, -40, -270, -257, 114, +-300, 488, -240, 756, -296, 846, -333, 694, +-95, 329, 235, -125, 350, -540, 310, -839, +321, -932, 359, -794, 223, -516, -123, -189, +-390, 218, -413, 668, -340, 950, -329, 953, +-220, 804, 147, 559, 451, 114, 405, -487, +274, -951, 231, -1091, 75, -972, -229, -667, +-356, -161, -232, 423, -100, 832, -82, 931, +-51, 789, 84, 504, 175, 126, 95, -264, +-11, -499, 12, -515, 153, -423, 170, -342, +-1, -220, -122, -10, -116, 184, -145, 291, +-214, 402, -151, 501, 38, 421, 150, 136, +186, -157, 213, -370, 170, -538, 28, -572, +-76, -299, -56, 179, 7, 535, 19, 612, +-48, 488, -170, 199, -272, -240, -330, -655, +-296, -751, -120, -446, 201, 62, 547, 557, +738, 932, 662, 1015, 366, 629, -57, -109, +-517, -797, -836, -1167, -817, -1218, -517, -914, +-119, -179, 268, 730, 578, 1313, 640, 1339, +419, 976, 113, 401, -100, -333, -186, -1008, +-171, -1219, -60, -875, 84, -315, 50, 172, +-163, 570, -331, 778, -333, 573, -262, 40, +-136, -384, 203, -469, 655, -348, 843, -111, +647, 268, 271, 617, -138, 655, -658, 334, +-1142, -149, -1223, -612, -829, -901, -235, -841, +384, -425, 1052, 96, 1539, 511, 1481, 762, +987, 778, 343, 485, -404, 13, -1260, -350, +-1881, -447, -1825, -356, -1156, -177, -306, 39, +557, 188, 1395, 142, 1905, -80, 1757, -330, +1066, -469, 185, -460, -665, -290, -1372, 51, +-1659, 483, -1360, 810, -700, 859, 7, 627, +641, 284, 1093, -81, 1199, -503, 914, -889, +437, -994, -44, -762, -460, -394, -732, -55, +-758, 294, -629, 634, -437, 791, -141, 661, +181, 371, 399, 91, 532, -124, 591, -268, +593, -277, 467, -133, 170, 31, -224, 34, +-599, -129, -832, -337, -867, -511, -698, -624, +-265, -538, 378, -104, 961, 587, 1178, 1206, +1015, 1488, 582, 1343, -88, 759, -883, -214, +-1402, -1307, -1291, -2097, -727, -2248, -70, -1674, +638, -464, 1270, 1038, 1449, 2293, 980, 2848, +213, 2539, -387, 1419, -788, -247, -1077, -1923, +-1030, -2975, -558, -3063, -25, -2190, 229, -597, +321, 1201, 449, 2548, 543, 3036, 471, 2604, +408, 1396, 480, -249, 443, -1751, 86, -2580, +-400, -2533, -779, -1737, -1048, -484, -1188, 826, +-960, 1819, -312, 2243, 497, 1980, 1188, 1097, +1602, -56, 1576, -1084, 1076, -1780, 252, -2007, +-667, -1604, -1407, -651, -1728, 459, -1577, 1359, +-989, 1900, -133, 1906, 734, 1244, 1322, 116, +1488, -992, 1287, -1714, 805, -1909, 142, -1524, +-492, -602, -873, 536, -948, 1433, -885, 1799, +-740, 1578, -486, 839, -174, -183, 117, -1098, +415, -1565, 765, -1520, 1041, -1050, 1064, -273, +851, 599, 469, 1246, -95, 1462, -819, 1243, +-1403, 714, -1559, 18, -1297, -690, -726, -1268, +52, -1520, 832, -1303, 1359, -684, 1517, 70, +1343, 765, 853, 1322, 188, 1548, -429, 1219, +-915, 488, -1260, -273, -1333, -866, -1085, -1269, +-642, -1323, -85, -887, 575, -161, 1185, 474, +1454, 872, 1271, 1030, 815, 874, 161, 391, +-643, -212, -1292, -704, -1483, -973, -1223, -946, +-612, -589, 248, -56, 1058, 472, 1417, 930, +1264, 1224, 806, 1136, 151, 651, -637, 15, +-1200, -607, -1266, -1180, -995, -1501, -564, -1351, +43, -826, 689, -190, 1058, 484, 1054, 1123, +901, 1452, 578, 1336, -24, 990, -603, 574, +-835, 23, -864, -603, -839, -1012, -595, -1130, +-87, -1120, 392, -997, 663, -620, 792, -43, +780, 509, 483, 921, 21, 1224, -302, 1352, +-440, 1161, -501, 653, -477, -7, -331, -669, +-124, -1236, 10, -1593, 76, -1587, 129, -1152, +172, -379, 211, 510, 280, 1307, 360, 1861, +418, 2019, 398, 1636, 235, 768, -76, -314, +-471, -1316, -841, -2058, -1017, -2325, -932, -1962, +-584, -1067, 0, 68, 682, 1182, 1224, 2049, +1420, 2417, 1224, 2143, 732, 1385, 10, 383, +-828, -701, -1467, -1659, -1571, -2219, -1177, -2241, +-526, -1773, 227, -964, 942, 44, 1350, 1067, +1258, 1892, 811, 2288, 250, 2136, -355, 1517, +-843, 594, -1022, -503, -862, -1556, -489, -2250, +-45, -2352, 339, -1900, 557, -1037, 589, 96, +494, 1249, 298, 2059, 59, 2287, -114, 1911, +-159, 1087, -197, 60, -264, -895, -247, -1581, +-158, -1841, -135, -1585, -168, -954, -121, -282, +32, 259, 154, 698, 224, 995, 311, 1024, +394, 864, 358, 720, 227, 593, 99, 335, +-70, -74, -359, -545, -616, -985, -668, -1332, +-585, -1458, -480, -1240, -229, -667, 271, 153, +815, 1022, 1102, 1679, 1108, 1947, 906, 1773, +431, 1185, -296, 257, -1000, -798, -1410, -1670, +-1453, -2123, -1165, -2093, -536, -1602, 288, -705, +1006, 434, 1419, 1471, 1499, 2106, 1243, 2218, +678, 1818, -73, 972, -799, -120, -1286, -1148, +-1446, -1838, -1340, -2064, -965, -1782, -304, -1105, +516, -246, 1210, 583, 1550, 1228, 1561, 1575, +1272, 1603, 597, 1379, -331, 974, -1149, 405, +-1590, -247, -1653, -902, -1386, -1505, -763, -1933, +91, -1992, 837, -1577, 1243, -755, 1354, 333, +1265, 1530, 909, 2498, 326, 2879, -214, 2551, +-507, 1614, -712, 249, -941, -1255, -972, -2514, +-755, -3167, -551, -3046, -375, -2201, -8, -876, +503, 599, 846, 1897, 1010, 2760, 1144, 3009, +1078, 2581, 607, 1607, -40, 410, -613, -764, +-1119, -1785, -1479, -2500, -1441, -2689, -970, -2273, +-300, -1445, 410, -418, 1113, 750, 1565, 1878, +1553, 2615, 1151, 2724, 507, 2253, -313, 1333, +-1086, 60, -1505, -1332, -1487, -2409, -1172, -2869, +-628, -2647, 126, -1822, 897, -538, 1331, 885, +1356, 2057, 1126, 2703, 694, 2689, 92, 2009, +-500, 873, -863, -377, -954, -1457, -942, -2236, +-849, -2534, -577, -2206, -167, -1389, 192, -383, +468, 657, 792, 1612, 1100, 2249, 1159, 2348, +928, 1934, 504, 1135, -104, 86, -861, -997, +-1458, -1838, -1625, -2237, -1394, -2106, -838, -1495, +38, -583, 1005, 369, 1646, 1180, 1761, 1672, +1434, 1655, 752, 1197, -156, 606, -1018, 65, +-1556, -416, -1652, -764, -1309, -795, -634, -557, +192, -322, 944, -223, 1436, -164, 1533, -105, +1215, -102, 625, -134, -92, -59, -842, 151, +-1396, 404, -1546, 592, -1279, 656, -697, 557, +44, 290, 744, -84, 1255, -473, 1502, -777, +1381, -822, 800, -578, -18, -231, -697, 85, +-1099, 418, -1325, 715, -1270, 726, -765, 401, +-24, 81, 590, -76, 978, -234, 1143, -406, +999, -381, 503, -171, -100, -40, -524, -63, +-724, -91, -760, -100, -604, -132, -257, -140, +98, -3, 245, 285, 236, 570, 234, 724, +269, 750, 273, 647, 315, 354, 460, -178, +515, -771, 267, -1174, -190, -1344, -677, -1327, +-1131, -1024, -1423, -381, -1265, 418, -583, 1169, +356, 1797, 1258, 2129, 1970, 1977, 2235, 1358, +1789, 430, 754, -697, -484, -1853, -1692, -2691, +-2613, -2916, -2827, -2501, -2144, -1481, -845, 29, +652, 1663, 2030, 2950, 3002, 3608, 3174, 3485, +2362, 2488, 859, 747, -850, -1231, -2344, -2913, +-3255, -3940, -3288, -4077, -2330, -3223, -700, -1554, +1010, 514, 2380, 2473, 3175, 3857, 3129, 4326, +2164, 3797, 642, 2371, -895, 372, -2102, -1687, +-2796, -3323, -2805, -4216, -2039, -4171, -781, -3118, +536, -1260, 1660, 823, 2405, 2571, 2533, 3707, +1944, 4026, 848, 3334, -340, 1777, -1379, -113, +-2110, -1784, -2222, -2909, -1566, -3263, -492, -2776, +529, -1644, 1304, -283, 1727, 908, 1572, 1700, +838, 1948, -99, 1618, -856, 974, -1311, 329, +-1325, -151, -792, -421, 30, -449, 719, -293, +1133, -160, 1272, -196, 1043, -338, 405, -523, +-409, -725, -1104, -849, -1529, -716, -1612, -303, +-1249, 241, -476, 776, 489, 1235, 1376, 1528, +2006, 1559, 2229, 1240, 1855, 592, 842, -268, +-482, -1139, -1674, -1861, -2489, -2342, -2810, -2403, +-2383, -1865, -1148, -822, 455, 504, 1863, 1857, +2802, 2948, 3101, 3454, 2542, 3151, 1199, 2057, +-404, 404, -1787, -1483, -2718, -3156, -3001, -4149, +-2447, -4121, -1193, -3068, 287, -1260, 1528, 892, +2267, 2891, 2434, 4224, 2085, 4502, 1259, 3651, +113, 2003, -947, -48, -1525, -2101, -1680, -3622, +-1663, -4157, -1399, -3704, -740, -2569, 31, -973, +593, 879, 1024, 2474, 1449, 3333, 1608, 3394, +1318, 2884, 813, 1909, 254, 507, -502, -1010, +-1342, -2158, -1826, -2725, -1749, -2801, -1303, -2466, +-650, -1630, 209, -411, 1147, 795, 1777, 1713, +1867, 2346, 1523, 2664, 896, 2460, 12, 1653, +-952, 552, -1629, -608, -1792, -1776, -1542, -2701, +-998, -2994, -155, -2541, 787, -1496, 1415, -85, +1602, 1416, 1446, 2609, 957, 3150, 176, 2870, +-621, 1850, -1131, 395, -1309, -1100, -1226, -2269, +-831, -2826, -204, -2645, 364, -1791, 704, -588, +902, 630, 970, 1641, 802, 2218, 439, 2193, +56, 1657, -272, 832, -555, -117, -770, -1041, +-846, -1674, -784, -1858, -571, -1625, -191, -1023, +260, -155, 634, 734, 908, 1399, 1057, 1698, +984, 1598, 643, 1071, 151, 220, -395, -688, +-912, -1378, -1255, -1718, -1303, -1671, -1075, -1202, +-617, -358, 44, 565, 812, 1320, 1403, 1799, +1610, 1876, 1450, 1474, 996, 725, 266, -143, +-609, -966, -1378, -1666, -1805, -2049, -1798, -1943, +-1383, -1423, -610, -702, 370, 174, 1235, 1174, +1759, 2013, 1921, 2399, 1735, 2292, 1137, 1708, +163, 706, -902, -573, -1637, -1818, -1929, -2636, +-1923, -2808, -1558, -2347, -719, -1350, 330, -1, +1171, 1363, 1652, 2292, 1877, 2605, 1761, 2392, +1153, 1724, 302, 686, -402, -431, -965, -1314, +-1461, -1879, -1659, -2178, -1432, -2099, -1021, -1577, +-556, -769, 60, 145, 781, 1124, 1320, 2006, +1570, 2449, 1635, 2302, 1418, 1711, 785, 753, +-16, -442, -736, -1534, -1385, -2193, -1867, -2344, +-1920, -2048, -1547, -1366, -955, -421, -187, 512, +759, 1260, 1595, 1785, 2040, 2033, 2168, 1896, +2032, 1404, 1370, 693, 201, -165, -985, -1049, +-1900, -1705, -2555, -2013, -2756, -1911, -2234, -1366, +-1107, -523, 194, 335, 1390, 1009, 2352, 1444, +2778, 1592, 2446, 1369, 1600, 918, 573, 455, +-472, 31, -1389, -393, -2010, -747, -2219, -960, +-1934, -1074, -1263, -1093, -475, -895, 264, -517, +990, -106, 1636, 284, 1931, 695, 1706, 1043, +1184, 1193, 583, 1173, -126, 1046, -854, 775, +-1347, 343, -1525, -267, -1468, -985, -1242, -1639, +-816, -2044, -241, -2066, 349, -1629, 904, -721, +1422, 528, 1771, 1746, 1801, 2599, 1469, 2929, +772, 2626, -238, 1604, -1280, 110, -2029, -1322, +-2346, -2365, -2224, -2977, -1588, -2993, -441, -2277, +856, -1026, 1809, 325, 2291, 1487, 2355, 2368, +1933, 2785, 1006, 2559, -133, 1831, -1113, 831, +-1778, -311, -2103, -1450, -1976, -2283, -1364, -2590, +-483, -2383, 369, -1750, 1073, -740, 1604, 493, +1824, 1676, 1573, 2475, 932, 2694, 157, 2277, +-555, 1321, -1152, 46, -1528, -1271, -1541, -2275, +-1169, -2643, -541, -2320, 212, -1419, 932, -184, +1392, 1050, 1432, 1901, 1101, 2133, 499, 1811, +-231, 1113, -848, 174, -1133, -714, -1055, -1236, +-701, -1332, -153, -1141, 406, -740, 676, -229, +608, 185, 380, 400, 97, 525, -207, 612, +-351, 587, -180, 417, 141, 269, 340, 205, +372, 58, 268, -223, -17, -469, -459, -570, +-805, -588, -829, -614, -533, -506, -63, -133, +463, 331, 932, 648, 1202, 855, 1100, 1012, +597, 912, -98, 411, -725, -207, -1188, -661, +-1385, -966, -1170, -1155, -593, -1037, 60, -553, +636, -5, 1109, 371, 1328, 653, 1120, 842, +621, 834, 119, 655, -306, 493, -656, 412, +-806, 285, -777, 27, -703, -315, -563, -721, +-310, -1160, -76, -1529, 73, -1611, 283, -1252, +616, -455, 874, 640, 967, 1790, 961, 2674, +780, 2980, 281, 2531, -352, 1379, -855, -278, +-1240, -2019, -1522, -3335, -1479, -3883, -1014, -3512, +-295, -2246, 449, -383, 1128, 1589, 1657, 3118, +1851, 3885, 1577, 3783, 921, 2830, 97, 1259, +-685, -461, -1296, -1913, -1627, -2877, -1551, -3232, +-1094, -2899, -525, -2048, -2, -986, 498, 108, +842, 1166, 851, 2006, 690, 2372, 610, 2261, +592, 1921, 479, 1383, 312, 558, 183, -394, +-11, -1112, -385, -1522, -765, -1814, -1016, -1978, +-1168, -1802, -1157, -1341, -866, -783, -337, -120, +302, 774, 937, 1742, 1490, 2448, 1838, 2722, +1818, 2533, 1370, 1795, 610, 512, -347, -1046, +-1342, -2415, -2114, -3255, -2454, -3382, -2246, -2750, +-1506, -1509, -438, 61, 750, 1573, 1792, 2613, +2391, 3018, 2438, 2803, 2016, 2048, 1254, 941, +295, -195, -701, -1102, -1508, -1718, -1973, -2056, +-2137, -2053, -2030, -1736, -1540, -1247, -739, -681, +157, 7, 1060, 784, 1920, 1492, 2498, 2024, +2549, 2288, 2035, 2129, 1137, 1524, -42, 559, +-1380, -582, -2453, -1676, -2879, -2439, -2698, -2642, +-2028, -2279, -881, -1477, 564, -366, 1840, 770, +2525, 1613, 2581, 2011, 2197, 2015, 1424, 1688, +324, 1113, -768, 449, -1462, -157, -1703, -654, +-1672, -1022, -1452, -1280, -964, -1426, -346, -1410, +65, -1123, 272, -588, 585, 30, 962, 656, +1130, 1274, 1100, 1633, 1091, 1525, 1029, 1063, +634, 518, -18, -34, -596, -600, -1063, -979, +-1497, -980, -1726, -781, -1559, -618, -1113, -468, +-504, -233, 271, -19, 1072, 117, 1633, 272, +1881, 473, 1886, 628, 1583, 692, 852, 675, +-66, 570, -843, 301, -1461, -30, -1946, -290, +-2076, -533, -1717, -793, -1066, -913, -391, -816, +317, -615, 1107, -390, 1769, -15, 2038, 494, +1956, 905, 1669, 1093, 1122, 1132, 216, 1016, +-834, 645, -1691, 52, -2240, -548, -2521, -1027, +-2376, -1304, -1601, -1321, -388, -1065, 851, -585, +1931, 29, 2748, 628, 3016, 1045, 2494, 1186, +1366, 1094, 38, 766, -1258, 251, -2325, -249, +-2815, -579, -2550, -736, -1725, -702, -671, -468, +445, -133, 1418, 111, 1941, 198, 1889, 148, +1463, 8, 935, -158, 376, -257, -257, -190, +-818, 42, -1101, 289, -1100, 471, -1026, 549, +-919, 503, -595, 299, -40, -46, 473, -350, +773, -438, 937, -420, 1029, -419, 896, -363, +489, -184, 26, -36, -299, -18, -547, -18, +-792, 74, -886, 226, -703, 382, -433, 516, +-239, 627, 2, 643, 377, 484, 679, 128, +750, -342, 702, -820, 604, -1215, 343, -1366, +-5, -1134, -246, -600, -391, 115, -543, 898, +-609, 1551, -509, 1832, -385, 1637, -308, 1082, +-134, 321, 129, -583, 342, -1401, 512, -1833, +697, -1815, 754, -1487, 567, -880, 272, -24, +-26, 842, -379, 1473, -724, 1785, -903, 1715, +-861, 1288, -661, 598, -286, -220, 223, -973, +636, -1467, 867, -1593, 1008, -1314, 943, -718, +540, -1, -31, 610, -505, 995, -843, 1102, +-1030, 881, -933, 374, -579, -177, -180, -492, +224, -536, 652, -450, 870, -225, 715, 163, +488, 506, 394, 553, 189, 351, -216, 87, +-516, -209, -564, -552, -551, -783, -577, -766, +-427, -505, -44, -136, 293, 251, 445, 654, +514, 966, 525, 990, 410, 734, 120, 335, +-209, -107, -364, -533, -332, -832, -272, -928, +-199, -785, -46, -446, 99, -65, 104, 215, +36, 389, 43, 464, 119, 447, 87, 328, +-8, 179, 24, 116, 119, 130, 122, 123, +39, 104, -42, 57, -55, -95, -103, -340, +-253, -533, -343, -637, -265, -649, -147, -457, +-33, -58, 195, 348, 492, 659, 617, 860, +509, 842, 319, 497, 107, 14, -243, -342, +-614, -552, -718, -662, -579, -571, -392, -244, +-160, 147, 111, 364, 364, 392, 527, 314, +556, 127, 479, -123, 328, -311, 111, -394, +-106, -360, -305, -196, -471, 61, -539, 307, +-456, 476, -233, 523, 76, 457, 342, 326, +449, 120, 414, -188, 268, -497, 9, -701, +-250, -748, -403, -639, -394, -393, -239, -17, +-20, 432, 213, 804, 408, 979, 476, 920, +426, 666, 266, 261, 41, -192, -159, -572, +-326, -810, -501, -894, -609, -843, -580, -694, +-471, -438, -308, -98, -14, 253, 375, 575, +734, 904, 964, 1194, 1049, 1302, 966, 1143, +647, 737, 135, 128, -448, -597, -1045, -1326, +-1525, -1876, -1717, -2080, -1513, -1878, -937, -1257, +-138, -274, 732, 820, 1569, 1757, 2152, 2411, +2225, 2686, 1746, 2411, 918, 1609, -87, 515, +-1123, -675, -1934, -1827, -2291, -2726, -2182, -3136, +-1674, -2943, -824, -2216, 194, -1041, 1068, 454, +1692, 1962, 2103, 3104, 2163, 3640, 1723, 3456, +943, 2535, 82, 1051, -771, -626, -1570, -2158, +-2067, -3241, -2090, -3596, -1718, -3171, -1084, -2168, +-248, -830, 645, 598, 1359, 1834, 1783, 2610, +1931, 2821, 1719, 2507, 1142, 1800, 371, 828, +-413, -256, -1125, -1208, -1658, -1827, -1825, -2085, +-1548, -1972, -979, -1500, -249, -760, 533, 73, +1180, 780, 1479, 1214, 1365, 1371, 913, 1240, +276, 818, -329, 269, -713, -162, -844, -420, +-746, -529, -421, -452, 58, -224, 433, 2, +535, 103, 463, 64, 293, -47, -40, -201, +-453, -388, -706, -525, -696, -490, -567, -276, +-373, 18, 8, 325, 516, 626, 890, 844, +1039, 895, 1044, 731, 911, 413, 549, 68, +-22, -270, -651, -632, -1183, -929, -1514, -1050, +-1563, -998, -1332, -836, -835, -526, -94, -36, +764, 564, 1467, 1102, 1885, 1433, 2030, 1509, +1805, 1287, 1115, 712, 136, -65, -823, -792, +-1599, -1330, -2174, -1587, -2376, -1468, -2030, -1015, +-1246, -385, -271, 246, 731, 722, 1633, 947, +2250, 963, 2405, 820, 2076, 569, 1383, 329, +470, 187, -539, 99, -1436, 15, -2029, -103, +-2271, -285, -2135, -567, -1578, -889, -713, -1093, +258, -1059, 1142, -801, 1815, -340, 2144, 326, +2022, 1047, 1523, 1533, 840, 1696, 48, 1555, +-753, 1065, -1369, 290, -1673, -513, -1675, -1143, +-1442, -1539, -1057, -1656, -554, -1453, 45, -1000, +652, -440, 1149, 89, 1470, 550, 1615, 942, +1578, 1213, 1231, 1344, 533, 1360, -253, 1193, +-922, 796, -1492, 227, -1882, -431, -1904, -1098, +-1463, -1627, -720, -1865, 80, -1724, 838, -1237, +1480, -548, 1831, 168, 1800, 837, 1411, 1365, +767, 1623, 12, 1620, -714, 1453, -1300, 1130, +-1602, 632, -1595, 1, -1346, -669, -831, -1293, +-90, -1792, 656, -2056, 1228, -1936, 1542, -1403, +1578, -607, 1307, 304, 700, 1238, -88, 1972, +-840, 2283, -1429, 2151, -1705, 1656, -1532, 875, +-975, -73, -259, -981, 437, -1645, 1051, -1991, +1498, -2021, 1566, -1718, 1214, -1087, 680, -269, +139, 536, -433, 1213, -956, 1653, -1305, 1746, +-1440, 1508, -1356, 1012, -1001, 352, -392, -304, +315, -770, 936, -1001, 1441, -1047, 1761, -933, +1693, -689, 1186, -396, 430, -159, -375, -16, +-1114, 126, -1640, 316, -1777, 464, -1512, 549, +-1017, 656, -413, 755, 286, 712, 944, 501, +1319, 212, 1367, -123, 1219, -515, 936, -907, +534, -1168, 48, -1215, -413, -1048, -737, -663, +-883, -76, -888, 550, -806, 1087, -702, 1507, +-560, 1694, -344, 1493, -77, 955, 183, 262, +447, -500, 747, -1270, 1066, -1830, 1261, -1983, +1218, -1719, 973, -1155, 541, -369, -113, 550, +-867, 1378, -1478, 1868, -1828, 1968, -1907, 1748, +-1671, 1236, -1049, 478, -124, -360, 817, -1092, +1560, -1607, 2077, -1836, 2287, -1749, 2029, -1363, +1346, -726, 477, 38, -410, 784, -1285, 1392, +-1978, 1727, -2243, 1706, -2070, 1390, -1657, 875, +-1019, 220, -122, -476, 804, -1046, 1468, -1389, +1843, -1511, 1994, -1431, 1863, -1129, 1363, -599, +645, 39, -40, 633, -635, 1164, -1171, 1572, +-1570, 1680, -1727, 1411, -1653, 858, -1418, 150, +-1044, -618, -476, -1293, 277, -1672, 1069, -1652, +1761, -1291, 2257, -708, 2406, -4, 2076, 683, +1289, 1158, 200, 1325, -989, 1236, -2074, 950, +-2774, 500, -2858, -26, -2361, -495, -1474, -832, +-300, -978, 978, -889, 2038, -622, 2626, -284, +2710, 58, 2324, 330, 1482, 473, 338, 460, +-773, 326, -1654, 189, -2262, 125, -2452, 97, +-2086, 83, -1287, 94, -333, 71, 571, -47, +1321, -217, 1810, -345, 1888, -373, 1547, -326, +971, -249, 338, -106, -276, 113, -814, 278, +-1186, 304, -1293, 250, -1170, 198, -915, 162, +-507, 111, 17, 22, 511, -74, 878, -126, +1075, -138, 1067, -166, 860, -183, 460, -129, +-61, -47, -560, 17, -898, 91, -1027, 142, +-962, 98, -716, -14, -273, -82, 254, -71, +699, -22, 1022, 43, 1157, 157, 992, 299, +572, 343, 38, 240, -501, 47, -943, -224, +-1229, -510, -1241, -666, -895, -636, -353, -433, +138, -65, 547, 374, 927, 734, 1164, 941, +1065, 936, 732, 643, 447, 124, 171, -427, +-267, -812, -680, -952, -832, -901, -893, -672, +-1002, -243, -955, 240, -576, 562, -80, 684, +303, 678, 687, 568, 1153, 379, 1382, 181, +1208, -7, 839, -221, 389, -429, -208, -554, +-852, -565, -1285, -486, -1415, -331, -1314, -86, +-980, 205, -380, 424, 296, 523, 822, 524, +1157, 417, 1305, 231, 1205, 81, 890, -21, +410, -159, -148, -317, -611, -440, -922, -498, +-1115, -468, -1133, -383, -900, -244, -483, 16, +-15, 332, 384, 556, 725, 673, 975, 702, +1018, 593, 805, 347, 476, 44, 143, -258, +-191, -554, -532, -832, -763, -973, -773, -847, +-639, -538, -465, -170, -210, 278, 134, 744, +417, 1031, 542, 1053, 504, 847, 387, 460, +235, -3, 18, -374, -209, -575, -288, -655, +-223, -656, -138, -578, -76, -453, 33, -342, +189, -253, 243, -90, 167, 211, 72, 582, +-23, 908, -207, 1092, -363, 1026, -391, 645, +-358, 52, -266, -580, -31, -1118, 256, -1400, +470, -1306, 592, -849, 636, -153, 524, 563, +199, 1087, -160, 1322, -371, 1210, -511, 752, +-670, 111, -670, -520, -442, -1003, -142, -1182, +97, -981, 319, -509, 508, 54, 593, 538, +527, 815, 344, 856, 62, 652, -249, 275, +-424, -77, -424, -264, -290, -305, -57, -247, +197, -159, 345, -122, 379, -180, 251, -293, +-23, -373, -331, -363, -535, -252, -579, -34, +-456, 265, -234, 522, 7, 640, 218, 647, +394, 597, 572, 484, 665, 290, 589, 54, +442, -202, 329, -512, 142, -841, -148, -1061, +-486, -1098, -778, -929, -930, -547, -921, 11, +-804, 638, -553, 1156, -155, 1391, 298, 1346, +716, 1127, 1064, 760, 1326, 229, 1339, -348, +1019, -804, 509, -1095, -28, -1296, -643, -1388, +-1276, -1239, -1683, -831, -1672, -287, -1306, 344, +-720, 989, 35, 1458, 846, 1623, 1431, 1498, +1654, 1126, 1590, 544, 1216, -152, 544, -779, +-231, -1198, -844, -1386, -1175, -1325, -1261, -1028, +-1169, -604, -827, -128, -287, 351, 213, 699, +496, 790, 582, 661, 565, 445, 502, 268, +409, 183, 313, 207, 288, 354, 288, 533, +222, 566, 56, 372, -165, -57, -417, -660, +-660, -1245, -826, -1594, -804, -1591, -601, -1225, +-302, -599, 32, 129, 361, 831, 637, 1395, +802, 1709, 840, 1731, 784, 1505, 635, 1102, +338, 556, -1, -113, -289, -827, -587, -1435, +-890, -1843, -998, -1982, -859, -1773, -601, -1220, +-304, -467, 32, 322, 385, 1052, 640, 1617, +728, 1874, 715, 1801, 676, 1469, 583, 938, +431, 287, 233, -362, 20, -940, -236, -1385, +-583, -1601, -959, -1516, -1156, -1166, -1097, -663, +-858, -113, -437, 429, 180, 840, 814, 989, +1231, 929, 1366, 779, 1239, 535, 878, 267, +382, 103, -99, 51, -523, 46, -823, 11, +-909, -107, -859, -264, -793, -434, -679, -650, +-502, -850, -305, -891, -46, -719, 339, -388, +787, 36, 1131, 505, 1278, 948, 1246, 1215, +983, 1190, 388, 942, -346, 544, -910, -1, +-1262, -550, -1445, -875, -1322, -948, -893, -865, +-345, -637, 178, -261, 615, 133, 879, 397, +917, 509, 821, 496, 715, 351, 574, 101, +352, -155, 123, -316, -98, -381, -363, -348, +-647, -150, -875, 178, -1001, 441, -948, 551, +-679, 548, -250, 436, 242, 202, 687, -93, +984, -365, 1072, -534, 970, -597, 742, -599, +401, -504, 8, -293, -290, -62, -497, 177, +-727, 453, -950, 675, -1049, 708, -963, 529, +-696, 215, -323, -104, 173, -363, 780, -536, +1252, -505, 1436, -238, 1450, 89, 1229, 340, +597, 463, -265, 370, -993, 65, -1440, -264, +-1660, -458, -1621, -500, -1196, -433, -452, -258, +339, 3, 1018, 224, 1478, 292, 1604, 254, +1385, 210, 914, 206, 260, 270, -443, 389, +-1025, 440, -1333, 344, -1319, 139, -1044, -138, +-586, -492, -53, -817, 442, -955, 862, -877, +1109, -642, 1034, -265, 773, 179, 499, 559, +156, 797, -277, 910, -618, 937, -792, 843, +-891, 565, -963, 185, -856, -184, -504, -499, +-113, -727, 252, -833, 735, -816, 1221, -639, +1438, -339, 1361, -76, 1004, 67, 393, 131, +-332, 135, -977, 115, -1438, 123, -1612, 195, +-1441, 360, -966, 604, -371, 837, 187, 984, +670, 959, 1025, 690, 1168, 192, 1120, -454, +984, -1140, 769, -1699, 446, -1979, 16, -1905, +-398, -1449, -715, -648, -947, 322, -1105, 1234, +-1126, 1898, -969, 2216, -625, 2155, -211, 1722, +186, 1006, 629, 200, 1072, -537, 1347, -1115, +1391, -1470, 1245, -1571, 858, -1475, 258, -1265, +-451, -980, -1093, -627, -1529, -253, -1694, 118, +-1560, 508, -1052, 918, -274, 1298, 485, 1565, +1052, 1633, 1402, 1468, 1478, 1089, 1217, 526, +752, -171, 244, -881, -244, -1466, -691, -1813, +-910, -1891, -850, -1720, -689, -1320, -574, -750, +-390, -112, -98, 540, 159, 1134, 296, 1590, +390, 1882, 480, 1969, 500, 1780, 447, 1309, +327, 590, 144, -297, -91, -1194, -261, -1915, +-320, -2317, -268, -2285, -186, -1813, -118, -1014, +-63, -61, -14, 843, -26, 1525, -103, 1862, +-173, 1771, -164, 1345, -22, 800, 180, 230, +324, -333, 345, -745, 294, -898, 192, -840, +91, -694, -49, -507, -205, -276, -263, -29, +-177, 154, -91, 250, -65, 279, -65, 230, +-83, 109, -89, -12, -51, -89, 12, -120, +38, -88, 96, 27, 192, 204, 242, 368, +188, 411, 115, 301, -9, 105, -174, -94, +-267, -279, -228, -402, -135, -384, -40, -228, +72, -39, 199, 109, 312, 177, 280, 154, +101, 27, -113, -164, -240, -299, -303, -297, +-333, -218, -303, -98, -96, 120, 192, 394, +361, 584, 389, 652, 348, 583, 227, 384, +0, 111, -224, -196, -334, -504, -319, -722, +-293, -801, -207, -713, 3, -472, 257, -174, +375, 107, 356, 374, 253, 584, 128, 670, +-46, 632, -265, 477, -408, 237, -405, 12, +-299, -183, -140, -365, 72, -468, 284, -439, +420, -307, 389, -104, 291, 112, 181, 266, +12, 295, -187, 210, -284, 67, -330, -101, +-357, -297, -329, -426, -263, -354, -121, -128, +127, 92, 379, 284, 516, 460, 580, 520, +591, 414, 511, 259, 216, 119, -210, -71, +-565, -281, -791, -387, -957, -381, -971, -365, +-718, -387, -252, -343, 232, -161, 623, 49, +983, 189, 1226, 322, 1188, 439, 901, 454, +526, 369, 47, 232, -503, 60, -987, -127, +-1242, -299, -1253, -372, -1095, -287, -790, -147, +-321, -46, 182, 84, 588, 236, 918, 286, +1100, 174, 1054, -44, 843, -263, 600, -407, +327, -472, -7, -424, -376, -229, -637, 66, +-749, 375, -772, 639, -727, 783, -626, 761, +-494, 579, -291, 279, -15, -83, 220, -438, +399, -743, 568, -949, 746, -999, 875, -866, +878, -560, 697, -127, 399, 345, 38, 771, +-355, 1072, -735, 1192, -1010, 1079, -1117, 709, +-1056, 177, -809, -350, -371, -765, 128, -1000, +498, -1014, 763, -797, 986, -420, 1069, -39, +895, 220, 551, 347, 184, 359, -139, 267, +-447, 151, -682, 119, -738, 192, -659, 326, +-525, 447, -305, 499, -45, 441, 99, 225, +148, -122, 209, -480, 293, -775, 349, -939, +369, -908, 328, -692, 219, -352, 74, 37, +-42, 393, -131, 660, -241, 806, -318, 823, +-276, 726, -137, 545, -9, 294, 56, 27, +84, -222, 123, -430, 147, -548, 137, -560, +123, -495, 73, -341, -44, -143, -150, -5, +-223, 35, -315, 3, -378, -78, -319, -163, +-138, -206, 87, -146, 318, 58, 529, 365, +641, 693, 606, 958, 494, 1051, 315, 911, +-1, 565, -359, 68, -602, -499, -713, -997, +-718, -1326, -608, -1431, -391, -1287, -114, -938, +137, -485, 313, -17, 428, 423, 428, 813, +301, 1114, 217, 1295, 282, 1334, 349, 1211, +315, 909, 268, 449, 247, -104, 101, -658, +-203, -1126, -480, -1386, -632, -1344, -724, -1046, +-746, -650, -621, -244, -373, 111, -104, 322, +128, 382, 380, 377, 675, 367, 923, 425, +1022, 566, 940, 732, 661, 854, 251, 826, +-232, 578, -771, 194, -1206, -253, -1301, -709, +-1030, -1056, -561, -1187, -9, -1100, 541, -831, +946, -468, 1027, -123, 788, 166, 366, 366, +-95, 449, -472, 506, -637, 589, -559, 661, +-291, 712, 33, 757, 272, 748, 375, 597, +353, 249, 222, -227, 10, -711, -172, -1130, +-213, -1423, -100, -1458, 28, -1170, 115, -664, +146, -72, 67, 547, -127, 1068, -319, 1323, +-435, 1275, -449, 1026, -332, 663, -95, 237, +193, -175, 427, -476, 585, -594, 676, -551, +661, -439, 484, -291, 240, -158, -1, -131, +-265, -201, -569, -314, -817, -444, -928, -487, +-883, -347, -699, -14, -360, 454, 128, 920, +610, 1220, 940, 1267, 1082, 1009, 1074, 474, +852, -164, 423, -737, -40, -1169, -384, -1325, +-682, -1138, -910, -737, -906, -294, -687, 108, +-436, 449, -197, 695, 86, 770, 342, 703, +471, 583, 464, 404, 437, 134, 386, -136, +243, -324, 40, -451, -54, -518, -53, -436, +-51, -199, -57, 61, -4, 216, 62, 255, +36, 208, -88, 83, -224, -94, -337, -262, +-486, -338, -590, -267, -503, -87, -208, 132, +130, 326, 445, 442, 747, 471, 980, 410, +962, 268, 672, 94, 280, -106, -104, -341, +-495, -530, -849, -601, -1006, -605, -918, -575, +-673, -436, -384, -137, -19, 262, 377, 640, +673, 910, 766, 1057, 740, 1007, 614, 682, +333, 155, -48, -434, -321, -970, -409, -1306, +-435, -1322, -383, -990, -148, -404, 135, 245, +219, 776, 171, 1080, 72, 1097, -102, 837, +-333, 392, -458, -96, -407, -456, -206, -585, +55, -542, 335, -430, 608, -274, 767, -88, +705, 81, 448, 191, 123, 226, -214, 237, +-515, 241, -707, 187, -678, 55, -503, -119, +-310, -270, -117, -337, 104, -315, 243, -195, +228, 35, 140, 310, 118, 493, 175, 517, +219, 409, 288, 202, 407, -86, 483, -388, +392, -593, 172, -638, -117, -565, -394, -398, +-638, -139, -816, 170, -843, 463, -675, 689, +-421, 819, -139, 829, 197, 657, 546, 300, +811, -165, 887, -639, 843, -1009, 743, -1177, +539, -1089, 202, -731, -141, -168, -455, 444, +-730, 949, -906, 1237, -927, 1201, -827, 853, +-653, 333, -434, -233, -146, -734, 258, -1033, +676, -1051, 975, -773, 1130, -291, 1204, 227, +1090, 660, 672, 923, 61, 927, -509, 692, +-1013, 307, -1401, -162, -1490, -638, -1214, -954, +-702, -1012, -103, -851, 504, -556, 989, -157, +1215, 332, 1124, 789, 819, 1049, 379, 1084, +-83, 930, -461, 586, -697, 103, -775, -383, +-620, -753, -295, -972, 20, -992, 263, -748, +462, -314, 569, 133, 510, 473, 325, 668, +65, 697, -234, 527, -515, 179, -665, -215, +-686, -516, -592, -655, -379, -601, -67, -343, +274, 24, 582, 369, 803, 625, 862, 722, +746, 624, 518, 377, 239, 53, -74, -223, +-348, -334, -542, -280, -644, -142, -667, -12, +-585, 23, -467, -62, -358, -265, -204, -585, +4, -893, 176, -974, 319, -755, 503, -291, +656, 339, 671, 1000, 581, 1502, 473, 1719, +296, 1599, 12, 1158, -281, 477, -466, -297, +-583, -963, -674, -1391, -675, -1563, -518, -1482, +-272, -1167, -13, -681, 245, -154, 458, 303, +562, 610, 533, 734, 417, 719, 240, 630, +30, 503, -189, 397, -336, 361, -353, 368, +-290, 340, -214, 242, -89, 61, 68, -206, +178, -499, 241, -715, 290, -760, 297, -608, +218, -352, 82, -81, -77, 173, -234, 326, +-359, 301, -439, 126, -458, -83, -377, -221, +-194, -244, 23, -151, 198, 48, 337, 310, +447, 530, 475, 638, 422, 629, 329, 497, +210, 254, 59, -25, -80, -282, -178, -471, +-273, -555, -363, -537, -400, -445, -398, -315, +-364, -189, -254, -91, -88, -48, 55, -57, +170, -83, 315, -72, 432, 12, 409, 169, +282, 365, 164, 542, 59, 646, -70, 647, +-169, 547, -172, 356, -131, 93, -113, -172, +-83, -364, -34, -478, -18, -536, -41, -536, +-40, -499, 4, -463, 71, -429, 105, -356, +69, -233, 14, -94, -23, 76, -90, 324, +-163, 602, -161, 798, -117, 866, -63, 829, +43, 663, 188, 358, 254, -15, 221, -362, +172, -632, 133, -778, 73, -761, 13, -595, +-46, -376, -126, -177, -180, -10, -177, 109, +-192, 172, -248, 197, -225, 189, -121, 162, +-34, 136, 45, 137, 196, 158, 351, 164, +402, 157, 372, 197, 308, 264, 143, 265, +-117, 167, -336, 8, -455, -184, -493, -373, +-432, -519, -252, -569, -10, -488, 226, -326, +398, -150, 453, 32, 371, 193, 221, 286, +92, 314, -6, 346, -82, 426, -99, 512, +-78, 506, -120, 374, -194, 161, -245, -115, +-301, -453, -365, -757, -338, -898, -178, -832, +63, -599, 311, -245, 536, 169, 670, 538, +665, 757, 525, 815, 275, 746, -47, 568, +-372, 286, -616, -50, -735, -355, -713, -560, +-575, -654, -340, -617, -33, -453, 287, -188, +525, 118, 645, 374, 655, 490, 555, 441, +350, 250, 77, -23, -194, -277, -426, -427, +-597, -452, -648, -334, -534, -81, -318, 230, +-60, 499, 209, 654, 467, 651, 644, 485, +689, 188, 581, -163, 357, -468, 73, -676, +-251, -765, -560, -682, -746, -426, -763, -94, +-665, 204, -461, 429, -117, 576, 296, 635, +612, 587, 783, 437, 816, 213, 674, -62, +344, -359, -47, -615, -370, -785, -601, -816, +-701, -651, -596, -266, -313, 262, 1, 768, +269, 1096, 438, 1157, 457, 917, 320, 432, +112, -167, -114, -719, -302, -1079, -374, -1154, +-277, -936, -66, -513, 174, -28, 374, 383, +469, 639, 411, 737, 182, 695, -161, 520, +-497, 238, -712, -72, -765, -304, -609, -412, +-243, -422, 221, -341, 638, -160, 927, 75, +1027, 264, 869, 330, 459, 255, -43, 58, +-451, -184, -743, -338, -903, -319, -844, -157, +-556, 65, -209, 299, 83, 479, 330, 488, +505, 279, 505, -61, 353, -401, 170, -643, +35, -723, -64, -595, -140, -308, -156, 22, +-90, 345, 27, 652, 129, 851, 184, 853, +175, 680, 84, 411, -61, 74, -193, -310, +-311, -678, -401, -945, -392, -1059, -250, -975, +-48, -660, 135, -183, 321, 300, 477, 714, +494, 1037, 364, 1189, 225, 1082, 110, 730, +-48, 247, -213, -249, -263, -678, -256, -979, +-305, -1109, -365, -1046, -338, -808, -267, -446, +-211, -36, -104, 355, 118, 691, 376, 945, +546, 1082, 611, 1083, 583, 938, 439, 611, +171, 103, -116, -469, -328, -957, -430, -1280, +-445, -1392, -404, -1223, -298, -764, -138, -132, +-36, 486, -68, 928, -127, 1123, -108, 1074, +-62, 819, -28, 443, 106, 42, 339, -303, +516, -526, 563, -599, 563, -572, 515, -481, +323, -309, 3, -80, -296, 129, -503, 290, +-657, 408, -766, 467, -750, 422, -574, 278, +-323, 121, -49, 9, 235, -112, 480, -278, +633, -432, 680, -536, 624, -622, 473, -673, +255, -587, 39, -298, -122, 149, -225, 643, +-277, 1078, -299, 1363, -309, 1388, -319, 1079, +-287, 493, -239, -215, -203, -878, -136, -1361, +-9, -1576, 129, -1500, 257, -1157, 355, -605, +374, 18, 293, 558, 176, 940, 72, 1140, +-18, 1159, -80, 1020, -75, 759, -30, 440, +6, 129, 28, -154, 6, -406, -109, -611, +-271, -775, -385, -900, -423, -929, -388, -800, +-260, -523, -23, -151, 274, 242, 517, 594, +665, 852, 700, 960, 592, 886, 350, 651, +47, 320, -261, -13, -514, -263, -683, -426, +-732, -535, -620, -560, -368, -450, -76, -241, +193, -21, 432, 148, 586, 220, 586, 183, +437, 48, 197, -152, -60, -371, -257, -518, +-343, -464, -308, -157, -181, 308, 0, 753, +161, 1047, 240, 1136, 225, 965, 110, 531, +-92, -57, -299, -647, -402, -1119, -383, -1359, +-289, -1292, -145, -967, 73, -524, 318, -59, +486, 401, 540, 817, 519, 1074, 392, 1073, +158, 867, -93, 562, -294, 211, -469, -135, +-587, -414, -564, -589, -394, -616, -153, -475, +95, -223, 315, 30, 441, 188, 442, 226, +356, 165, 204, 33, -17, -173, -235, -424, +-346, -612, -342, -601, -273, -358, -163, 31, +-26, 439, 125, 775, 291, 983, 416, 1006, +438, 788, 361, 374, 237, -91, 62, -469, +-162, -666, -384, -666, -553, -546, -639, -400, +-565, -281, -313, -206, 23, -164, 325, -150, +529, -162, 600, -148, 512, -47, 273, 131, +-54, 327, -361, 488, -529, 585, -483, 655, +-248, 734, 66, 743, 349, 563, 534, 211, +565, -219, 411, -665, 117, -1082, -221, -1364, +-493, -1374, -620, -1072, -574, -553, -401, 69, +-174, 691, 49, 1153, 259, 1315, 429, 1212, +504, 965, 457, 618, 360, 177, 260, -277, +104, -632, -124, -846, -335, -950, -498, -953, +-623, -803, -612, -472, -369, -26, -19, 445, +271, 846, 494, 1062, 653, 1018, 640, 735, +411, 273, 56, -279, -293, -782, -534, -1091, +-580, -1119, -420, -849, -144, -355, 150, 234, +397, 771, 506, 1115, 445, 1170, 274, 957, +44, 542, -223, 6, -423, -513, -474, -872, +-406, -1005, -295, -913, -145, -661, 23, -334, +149, 17, 230, 326, 309, 519, 346, 587, +295, 558, 200, 438, 106, 242, -14, 39, +-160, -117, -261, -222, -245, -275, -150, -254, +-53, -150, 42, -11, 149, 81, 222, 108, +199, 107, 54, 89, -133, 44, -272, 9, +-359, 4, -413, -22, -356, -92, -163, -171, +51, -224, 228, -247, 435, -251, 651, -211, +726, -73, 602, 142, 386, 310, 131, 367, +-206, 343, -576, 280, -845, 193, -955, 104, +-907, 27, -688, -14, -287, -19, 201, -25, +619, -55, 870, -109, 967, -195, 921, -288, +688, -338, 282, -334, -153, -305, -473, -280, +-660, -244, -737, -154, -641, 23, -390, 269, +-139, 533, 72, 769, 294, 924, 439, 949, +403, 787, 267, 394, 148, -172, 30, -749, +-109, -1189, -212, -1431, -244, -1430, -232, -1147, +-180, -635, -78, 15, 25, 701, 105, 1274, +184, 1576, 244, 1545, 258, 1216, 229, 683, +141, 36, -26, -614, -193, -1101, -284, -1279, +-312, -1155, -303, -825, -208, -387, 1, 40, +235, 354, 388, 544, 440, 617, 380, 582, +201, 458, -42, 267, -272, 56, -442, -125, +-511, -285, -470, -431, -335, -500, -129, -418, +93, -175, 267, 150, 367, 430, 387, 585, +362, 605, 341, 488, 293, 231, 169, -95, +10, -389, -107, -582, -184, -632, -283, -530, +-371, -336, -365, -122, -263, 84, -145, 250, +-39, 340, 58, 351, 125, 287, 128, 158, +85, 15, 58, -68, 71, -40, 74, 71, +69, 171, 109, 216, 173, 225, 177, 160, +105, -34, 22, -284, -23, -469, -61, -531, +-125, -459, -178, -282, -210, -73, -252, 95, +-267, 184, -207, 220, -106, 256, -5, 303, +138, 336, 337, 360, 493, 364, 493, 296, +357, 118, 159, -164, -89, -471, -356, -660, +-511, -648, -490, -475, -367, -211, -192, 94, +45, 351, 283, 474, 400, 459, 354, 345, +203, 149, 32, -86, -92, -266, -157, -324, +-189, -282, -172, -203, -63, -94, 73, 88, +121, 317, 97, 479, 73, 495, 40, 360, +-14, 104, -39, -189, -25, -440, -39, -616, +-82, -668, -87, -532, -50, -228, -35, 139, +-32, 450, 2, 630, 73, 653, 150, 528, +192, 293, 155, 16, 58, -266, -50, -547, +-142, -732, -202, -696, -204, -468, -160, -171, +-91, 140, 14, 459, 165, 723, 285, 828, +295, 719, 227, 437, 151, 83, 59, -239, +-79, -464, -233, -579, -333, -609, -347, -557, +-299, -414, -197, -212, -28, -15, 145, 149, +241, 278, 261, 359, 259, 398, 215, 390, +89, 292, -64, 108, -111, -74, -44, -179, +21, -197, 31, -168, 46, -131, 65, -86, +35, -17, -51, 58, -140, 103, -201, 102, +-226, 65, -189, 46, -73, 71, 64, 74, +136, 4, 141, -88, 143, -147, 152, -175, +107, -183, -10, -171, -128, -141, -167, -92, +-122, -10, -41, 103, 40, 209, 97, 262, +127, 252, 119, 204, 90, 126, 50, -2, +-22, -153, -102, -246, -94, -225, -2, -97, +76, 81, 85, 232, 46, 297, -42, 251, +-159, 109, -244, -73, -253, -224, -216, -314, +-139, -327, 31, -231, 255, -68, 380, 40, +352, 26, 242, -58, 94, -132, -81, -153, +-235, -111, -305, 19, -266, 236, -138, 463, +41, 610, 204, 637, 288, 524, 278, 270, +186, -53, 33, -361, -122, -606, -251, -742, +-333, -750, -323, -651, -188, -453, -7, -168, +130, 154, 207, 438, 248, 631, 247, 719, +178, 689, 63, 532, -32, 270, -116, -26, +-197, -292, -202, -495, -134, -592, -88, -542, +-83, -388, -24, -196, 100, 17, 193, 241, +202, 404, 173, 439, 141, 348, 73, 169, +-37, -52, -148, -261, -218, -399, -227, -408, +-174, -280, -82, -49, 63, 240, 216, 508, +295, 635, 264, 565, 182, 329, 78, -19, +-80, -380, -294, -647, -434, -759, -421, -691, +-319, -437, -170, -58, 46, 332, 276, 595, +429, 655, 485, 555, 442, 363, 309, 96, +101, -194, -127, -389, -292, -429, -365, -359, +-385, -241, -353, -104, -239, 29, -79, 122, +78, 177, 213, 243, 333, 340, 396, 408, +361, 389, 237, 290, 71, 126, -137, -125, +-362, -456, -519, -759, -528, -898, -385, -807, +-129, -517, 164, -111, 427, 322, 597, 697, +610, 918, 459, 922, 185, 725, -137, 394, +-416, 26, -572, -278, -580, -456, -453, -507, +-257, -466, -28, -363, 209, -216, 369, -58, +432, 52, 428, 84, 358, 63, 217, 20, +55, -13, -93, -12, -218, 26, -326, 89, +-366, 174, -292, 274, -121, 336, 42, 290, +156, 118, 242, -118, 281, -331, 215, -463, +50, -487, -143, -385, -284, -166, -348, 104, +-317, 341, -190, 469, -22, 431, 145, 242, +278, 8, 355, -167, 368, -251, 305, -239, +175, -115, 32, 81, -58, 250, -102, 300, +-152, 212, -218, 13, -238, -252, -188, -498, +-128, -597, -99, -495, -34, -251, 53, 65, +93, 404, 82, 681, 54, 784, -8, 649, +-113, 337, -199, -24, -163, -340, -24, -563, +112, -642, 231, -554, 384, -348, 507, -103, +472, 119, 292, 266, 55, 319, -199, 297, +-441, 246, -595, 212, -616, 198, -542, 168, +-388, 110, -137, 37, 160, -62, 402, -218, +536, -393, 541, -510, 454, -535, 297, -468, +84, -297, -161, -31, -358, 267, -443, 523, +-396, 704, -267, 788, -84, 738, 112, 524, +263, 203, 347, -140, 388, -455, 344, -696, +160, -808, -69, -779, -238, -613, -350, -331, +-431, -6, -455, 270, -387, 449, -217, 523, +29, 505, 274, 404, 425, 255, 463, 108, +444, -9, 368, -97, 218, -136, 16, -129, +-158, -116, -261, -115, -273, -93, -206, -43, +-113, 3, -75, 19, -90, 0, -96, -52, +-88, -118, -117, -176, -157, -212, -127, -202, +-19, -113, 141, 49, 312, 231, 425, 358, +428, 387, 346, 314, 223, 162, 62, -19, +-174, -153, -439, -212, -601, -210, -613, -143, +-510, -3, -305, 126, 1, 150, 338, 87, +631, 12, 814, -57, 830, -131, 631, -194, +250, -214, -216, -196, -618, -168, -895, -112, +-1002, -7, -890, 95, -545, 169, -51, 250, +430, 339, 779, 371, 943, 311, 893, 180, +650, 43, 290, -78, -122, -200, -503, -316, +-753, -387, -788, -403, -611, -363, -309, -260, +21, -91, 333, 107, 600, 301, 720, 465, +630, 571, 365, 543, 8, 349, -340, 53, +-592, -232, -711, -450, -657, -582, -477, -600, +-219, -483, 103, -277, 413, -45, 585, 172, +593, 351, 512, 461, 397, 508, 236, 516, +52, 485, -106, 367, -226, 149, -316, -119, +-372, -361, -379, -553, -371, -671, -342, -670, +-242, -526, -72, -287, 133, -8, 303, 251, +393, 428, 421, 491, 373, 466, 222, 405, +14, 326, -198, 219, -328, 100, -348, -3, +-271, -90, -135, -188, 55, -312, 245, -441, +355, -525, 364, -531, 287, -445, 148, -261, +-30, 12, -224, 333, -355, 634, -383, 853, +-372, 936, -317, 820, -192, 497, -37, 47, +93, -407, 179, -789, 239, -1042, 286, -1088, +314, -886, 311, -507, 278, -53, 204, 380, +98, 707, -37, 845, -197, 777, -365, 560, +-466, 275, -482, -27, -389, -278, -189, -397, +62, -340, 308, -166, 498, 44, 572, 220, +522, 307, 334, 260, 36, 85, -255, -175, +-475, -439, -617, -629, -638, -672, -498, -529, +-242, -220, 59, 149, 339, 468, 556, 667, +669, 727, 638, 635, 482, 404, 244, 93, +-52, -193, -350, -368, -546, -416, -620, -369, +-575, -245, -436, -84, -219, 58, 45, 148, +302, 180, 469, 125, 526, -12, 477, -170, +342, -260, 154, -255, -51, -177, -220, -47, +-337, 133, -400, 314, -379, 428, -266, 421, +-140, 280, -42, 36, 61, -223, 177, -409, +264, -474, 314, -422, 330, -268, 294, -27, +203, 263, 65, 504, -74, 597, -236, 509, +-403, 291, -471, 9, -393, -280, -255, -522, +-87, -658, 107, -646, 309, -455, 438, -129, +462, 226, 396, 495, 257, 627, 70, 613, +-127, 475, -274, 226, -368, -85, -422, -359, +-412, -505, -317, -510, -143, -395, 69, -200, +245, 24, 384, 219, 473, 350, 484, 400, +393, 359, 176, 204, -98, -27, -343, -231, +-509, -328, -568, -331, -496, -270, -322, -143, +-69, 50, 219, 238, 472, 329, 585, 295, +545, 186, 382, 46, 169, -80, -54, -151, +-280, -162, -434, -161, -477, -165, -423, -161, +-281, -134, -79, -104, 129, -58, 293, 42, +374, 207, 390, 375, 328, 474, 152, 445, +-109, 281, -351, 16, -469, -258, -460, -448, +-340, -507, -135, -441, 146, -272, 428, -51, +600, 143, 594, 227, 427, 188, 131, 70, +-183, -38, -422, -79, -502, -33, -421, 86, +-260, 248, -57, 385, 162, 431, 294, 347, +245, 138, 62, -173, -145, -508, -287, -755, +-311, -818, -192, -672, 23, -353, 255, 82, +427, 553, 514, 926, 474, 1088, 262, 983, +-29, 635, -282, 116, -440, -435, -497, -869, +-448, -1102, -331, -1116, -179, -900, -31, -486, +126, 36, 265, 527, 356, 891, 409, 1081, +437, 1075, 394, 857, 264, 467, 53, -13, +-221, -491, -476, -874, -640, -1055, -665, -980, +-541, -687, -303, -280, -7, 141, 313, 491, +574, 705, 700, 726, 685, 562, 548, 300, +328, 50, 81, -133, -167, -232, -411, -260, +-609, -240, -738, -203, -739, -160, -614, -118, +-380, -78, -50, -51, 342, -26, 708, 21, +969, 103, 1031, 186, 859, 238, 483, 241, +1, 201, -472, 124, -827, 16, -999, -132, +-977, -293, -740, -410, -346, -415, 94, -299, +473, -100, 703, 118, 787, 322, 744, 480, +563, 549, 293, 485, -15, 307, -332, 67, +-588, -177, -735, -379, -734, -505, -608, -565, +-379, -559, -71, -475, 303, -286, 646, -18, +836, 260, 849, 481, 717, 632, 445, 693, +101, 635, -267, 454, -590, 203, -783, -61, +-837, -283, -729, -433, -495, -503, -206, -522, +91, -522, 350, -502, 547, -403, 668, -206, +659, 48, 512, 291, 299, 502, 93, 671, +-108, 747, -295, 650, -415, 384, -465, 50, +-409, -234, -293, -424, -151, -515, -17, -514, +63, -431, 105, -305, 146, -161, 150, -22, +139, 93, 127, 169, 137, 235, 183, 315, +226, 395, 216, 415, 136, 350, 24, 210, +-109, 21, -247, -192, -368, -399, -445, -587, +-429, -712, -329, -702, -165, -500, 62, -159, +267, 233, 393, 605, 455, 899, 450, 1033, +385, 952, 219, 661, -2, 220, -184, -273, +-286, -687, -336, -934, -318, -993, -241, -912, +-138, -714, -34, -412, 65, -42, 127, 318, +141, 618, 103, 829, 45, 928, 29, 885, +28, 687, 21, 345, 23, -78, 29, -480, +34, -743, 43, -818, 35, -713, 6, -488, +-25, -211, -60, 48, -82, 243, -87, 340, +-84, 343, -83, 278, -64, 205, -43, 157, +-5, 127, 38, 77, 86, 7, 131, -61, +165, -104, 182, -118, 180, -103, 128, -88, +24, -90, -103, -115, -235, -142, -335, -161, +-359, -152, -296, -93, -153, 40, 53, 226, +260, 409, 440, 512, 529, 487, 455, 316, +252, 57, -27, -226, -320, -473, -554, -644, +-667, -683, -610, -570, -362, -331, -5, -28, +361, 298, 648, 567, 803, 718, 732, 723, +457, 595, 63, 340, -328, -15, -628, -392, +-803, -655, -761, -731, -472, -621, -84, -374, +269, -49, 515, 271, 611, 510, 537, 595, +293, 508, -2, 275, -233, -19, -347, -289, +-321, -457, -167, -496, 46, -411, 205, -241, +255, -10, 181, 239, 18, 451, -172, 550, +-346, 508, -430, 350, -345, 134, -151, -102, +111, -320, 347, -481, 500, -542, 549, -485, +462, -305, 265, -68, 16, 142, -253, 266, +-485, 313, -601, 301, -574, 235, -444, 116, +-240, -5, 38, -66, 328, -34, 571, 53, +681, 142, 633, 171, 441, 128, 119, 23, +-222, -116, -500, -274, -669, -416, -673, -485, +-505, -430, -202, -256, 160, -10, 433, 209, +563, 346, 529, 410, 372, 429, 134, 391, +-105, 303, -290, 185, -376, 72, -326, -32, +-183, -130, -14, -249, 132, -391, 200, -522, +199, -549, 156, -425, 64, -186, -30, 82, +-117, 343, -184, 559, -198, 671, -166, 619, +-104, 410, -16, 91, 91, -235, 194, -479, +287, -584, 329, -549, 281, -417, 141, -234, +-52, -3, -264, 239, -424, 409, -518, 441, +-486, 371, -306, 259, -17, 154, 306, 47, +560, -63, 675, -165, 643, -226, 467, -242, +166, -221, -178, -194, -482, -165, -676, -110, +-716, 10, -608, 167, -390, 286, -96, 308, +183, 239, 399, 105, 546, -61, 580, -234, +500, -356, 328, -374, 112, -270, -98, -65, +-256, 203, -352, 428, -358, 513, -284, 449, +-146, 302, 21, 121, 167, -78, 213, -284, +181, -428, 81, -455, -75, -376, -223, -271, +-322, -171, -321, -64, -202, 62, -9, 181, +216, 271, 411, 312, 505, 297, 476, 227, +321, 144, 80, 73, -177, 11, -377, -67, +-482, -130, -461, -148, -298, -138, -83, -144, +148, -166, 335, -186, 408, -167, 351, -93, +179, 20, -48, 129, -237, 210, -382, 254, +-424, 270, -343, 244, -161, 165, 81, 32, +311, -102, 467, -202, 492, -262, 401, -306, +223, -329, 4, -315, -204, -239, -383, -104, +-464, 76, -403, 265, -267, 433, -81, 538, +98, 567, 219, 509, 286, 346, 275, 80, +231, -211, 137, -459, 4, -620, -105, -690, +-154, -657, -170, -534, -164, -333, -149, -80, +-123, 196, -81, 432, 20, 597, 121, 689, +187, 729, 237, 680, 255, 498, 261, 204, +205, -122, 65, -432, -99, -693, -267, -856, +-390, -861, -420, -708, -396, -444, -325, -133, +-188, 195, 19, 479, 238, 650, 394, 691, +483, 654, 497, 569, 452, 430, 329, 215, +164, -33, -35, -256, -271, -427, -459, -563, +-528, -635, -515, -609, -425, -484, -285, -302, +-88, -88, 161, 121, 381, 286, 498, 386, +483, 457, 372, 512, 224, 527, 66, 466, +-115, 344, -274, 179, -354, -27, -357, -276, +-281, -511, -142, -671, -28, -719, 31, -639, +82, -427, 140, -138, 187, 156, 163, 394, +107, 570, 85, 666, 109, 651, 133, 515, +148, 310, 123, 79, 59, -146, -30, -350, +-133, -496, -265, -576, -407, -579, -520, -486, +-521, -299, -374, -91, -129, 89, 167, 237, +438, 382, 643, 502, 754, 557, 714, 526, +496, 435, 156, 291, -203, 95, -487, -144, +-631, -392, -628, -619, -515, -748, -320, -718, +-70, -529, 177, -244, 363, 63, 385, 338, +301, 554, 194, 651, 83, 590, -36, 395, +-143, 173, -202, -5, -179, -134, -96, -217, +20, -242, 121, -236, 171, -229, 161, -221, +113, -185, 48, -129, -65, -65, -186, 8, +-274, 128, -289, 256, -192, 316, -35, 285, +124, 211, 255, 120, 342, 26, 383, -77, +332, -189, 167, -303, -42, -384, -260, -416, +-408, -388, -459, -297, -407, -119, -293, 159, +-117, 496, 106, 772, 310, 888, 427, 795, +428, 515, 312, 94, 153, -374, -15, -781, +-150, -1007, -211, -995, -233, -760, -172, -379, +-44, 59, 82, 430, 151, 652, 124, 704, +27, 625, -99, 440, -221, 188, -297, -73, +-302, -260, -225, -343, -84, -342, 99, -293, +308, -195, 453, -61, 510, 84, 450, 209, +325, 301, 176, 327, -13, 292, -220, 202, +-397, 56, -530, -158, -575, -399, -532, -602, +-406, -687, -204, -623, 26, -401, 268, -53, +495, 364, 660, 742, 667, 980, 517, 1003, +283, 802, 14, 415, -251, -60, -477, -511, +-598, -835, -557, -976, -398, -920, -166, -692, +114, -331, 333, 71, 445, 426, 432, 672, +338, 792, 181, 763, -35, 580, -276, 273, +-434, -79, -444, -405, -325, -628, -138, -708, +66, -628, 257, -411, 417, -110, 487, 198, +422, 452, 246, 590, -12, 586, -256, 448, +-411, 225, -470, -38, -447, -288, -353, -475, +-186, -538, 46, -464, 274, -272, 411, -25, +455, 224, 415, 395, 309, 433, 174, 332, +26, 139, -152, -91, -287, -268, -338, -309, +-295, -189, -212, 23, -137, 222, -74, 327, +-18, 308, 28, 148, 61, -125, 76, -424, +67, -615, 71, -623, 123, -445, 188, -132, +211, 238, 180, 566, 88, 772, 6, 806, +-56, 676, -126, 406, -181, 48, -219, -319, +-203, -605, -129, -757, -52, -754, -11, -612, +7, -351, 27, -31, 86, 280, 152, 499, +192, 575, 178, 491, 147, 301, 95, 70, +18, -134, -87, -281, -233, -341, -338, -301, +-338, -155, -241, 38, -63, 215, 136, 347, +304, 428, 431, 425, 468, 315, 404, 94, +214, -190, -75, -480, -360, -705, -550, -796, +-601, -702, -535, -440, -354, -63, -82, 347, +236, 705, 525, 917, 679, 932, 649, 736, +478, 398, 196, -2, -98, -381, -362, -677, +-555, -837, -610, -834, -520, -668, -297, -368, +-11, 12, 225, 386, 356, 683, 393, 848, +365, 847, 268, 661, 112, 329, -48, -87, +-169, -485, -207, -777, -195, -906, -154, -865, +-103, -658, -82, -335, -54, 42, 0, 403, +66, 689, 123, 851, 154, 868, 167, 731, +191, 488, 185, 181, 118, -148, -24, -453, +-183, -674, -312, -775, -376, -745, -367, -606, +-283, -387, -118, -132, 96, 138, 324, 380, +517, 548, 586, 612, 491, 585, 278, 474, +2, 295, -273, 79, -507, -112, -638, -251, +-611, -341, -434, -392, -152, -387, 167, -329, +435, -247, 573, -164, 580, -62, 468, 72, +275, 228, 31, 360, -216, 424, -410, 400, +-485, 295, -463, 119, -357, -85, -206, -271, +-35, -385, 139, -400, 289, -305, 383, -134, +397, 55, 328, 203, 189, 276, 38, 273, +-104, 220, -234, 119, -317, -19, -317, -158, +-236, -247, -93, -273, 56, -236, 178, -150, +251, -31, 243, 99, 178, 225, 73, 308, +-44, 316, -167, 232, -241, 95, -234, -39, +-161, -124, -73, -168, 10, -179, 90, -169, +162, -145, 186, -126, 187, -127, 167, -147, +110, -155, 39, -112, -37, 14, -93, 205, +-142, 401, -188, 530, -189, 554, -133, 463, +-49, 272, 35, -11, 83, -349, 99, -660, +84, -844, 48, -847, -1, -682, -42, -407, +-22, -49, 37, 354, 142, 731, 241, 988, +278, 1059, 228, 921, 78, 614, -144, 190, +-373, -279, -586, -719, -681, -1051, -600, -1192, +-336, -1089, 62, -761, 489, -273, 845, 260, +1018, 719, 951, 1006, 655, 1088, 192, 951, +-339, 619, -819, 170, -1107, -259, -1104, -550, +-846, -658, -414, -617, 73, -481, 518, -304, +835, -120, 920, 27, 797, 102, 522, 106, +181, 92, -148, 116, -394, 196, -529, 286, +-548, 333, -490, 311, -362, 237, -193, 108, +-8, -64, 144, -249, 261, -391, 353, -450, +387, -400, 365, -262, 270, -75, 113, 97, +-58, 223, -208, 292, -307, 307, -321, 259, +-271, 158, -175, 32, -56, -72, 67, -128, +167, -135, 198, -128, 169, -112, 112, -89, +72, -43, 37, 15, 11, 70, -23, 104, +-67, 120, -105, 123, -119, 118, -130, 79, +-119, -5, -95, -108, -35, -183, 56, -218, +133, -200, 164, -152, 142, -89, 83, -17, +5, 68, -50, 145, -80, 199, -79, 221, +-48, 219, 4, 211, 68, 196, 114, 135, +105, 23, 54, -117, -1, -239, -43, -313, +-65, -316, -90, -247, -118, -130, -147, -17, +-151, 60, -141, 88, -107, 57, -64, -38, +6, -130, 113, -138, 251, -29, 374, 156, +424, 364, 356, 531, 213, 600, 40, 522, +-160, 312, -361, 12, -521, -322, -558, -633, +-460, -822, -269, -845, -26, -731, 221, -529, +398, -241, 474, 110, 482, 467, 424, 759, +273, 936, 60, 959, -136, 815, -272, 518, +-331, 131, -375, -286, -382, -658, -337, -901, +-242, -943, -99, -787, 67, -491, 216, -145, +341, 177, 426, 420, 463, 559, 419, 581, +285, 493, 87, 323, -133, 132, -307, -29, +-419, -130, -458, -185, -431, -219, -330, -234, +-156, -207, 34, -141, 189, -67, 283, -18, +310, 22, 299, 77, 262, 131, 181, 152, +74, 128, -40, 53, -93, -46, -101, -132, +-93, -167, -97, -153, -101, -102, -107, -18, +-121, 99, -124, 208, -117, 264, -129, 230, +-114, 121, -32, -7, 106, -99, 245, -144, +314, -157, 325, -157, 287, -128, 187, -71, +31, -10, -147, 19, -300, 14, -377, -6, +-340, -8, -213, 15, -61, 43, 72, 40, +173, 27, 221, 45, 224, 100, 160, 152, +51, 175, -62, 152, -107, 88, -95, -13, +-86, -129, -89, -249, -70, -347, -31, -379, +10, -290, 52, -90, 100, 143, 137, 321, +134, 410, 120, 410, 97, 328, 23, 163, +-116, -69, -237, -303, -273, -448, -236, -460, +-148, -346, -33, -160, 92, 52, 201, 250, +275, 406, 280, 484, 214, 446, 91, 279, +-30, 45, -122, -167, -169, -301, -190, -372, +-183, -400, -155, -375, -94, -285, -12, -143, +47, 34, 58, 204, 52, 336, 70, 415, +102, 460, 121, 446, 116, 313, 90, 48, +30, -257, -33, -497, -87, -622, -131, -626, +-169, -486, -164, -217, -71, 120, 76, 448, +201, 701, 250, 790, 233, 666, 147, 372, +0, 19, -165, -315, -292, -603, -361, -794, +-331, -803, -205, -599, -9, -246, 173, 146, +277, 476, 299, 676, 263, 715, 195, 592, +96, 344, -13, 27, -87, -282, -103, -489, +-93, -518, -93, -383, -119, -171, -151, 37, +-185, 212, -173, 334, -83, 364, 58, 268, +197, 71, 288, -158, 335, -348, 302, -448, +153, -432, -87, -311, -326, -117, -488, 125, +-498, 390, -354, 600, -87, 661, 201, 539, +446, 290, 588, -7, 583, -295, 416, -538, +118, -686, -200, -700, -451, -558, -588, -281, +-581, 59, -443, 376, -221, 612, 52, 735, +302, 740, 470, 608, 503, 329, 415, -60, +252, -455, 58, -746, -127, -868, -285, -820, +-373, -622, -352, -307, -225, 80, -54, 462, +101, 754, 195, 883, 219, 823, 163, 617, +86, 340, 8, 29, -65, -292, -126, -576, +-149, -742, -94, -750, -6, -612, 52, -382, +70, -119, 84, 131, 95, 340, 91, 489, +64, 548, 19, 493, -46, 343, -111, 156, +-166, -6, -189, -133, -173, -238, -135, -318, +-48, -345, 86, -296, 226, -176, 299, -41, +293, 61, 230, 126, 144, 181, 16, 231, +-139, 255, -276, 227, -327, 152, -294, 52, +-196, -48, -57, -146, 79, -259, 167, -377, +195, -435, 193, -360, 150, -167, 54, 61, +-63, 265, -141, 418, -160, 496, -125, 481, +-66, 373, 6, 190, 80, -28, 152, -217, +215, -312, 234, -325, 186, -319, 72, -333, +-56, -330, -185, -266, -293, -150, -356, -19, +-347, 110, -254, 242, -66, 377, 154, 486, +336, 531, 431, 465, 430, 291, 334, 66, +161, -149, -45, -330, -248, -491, -401, -616, +-470, -634, -409, -501, -240, -259, -45, 14, +131, 262, 288, 457, 398, 579, 419, 602, +343, 518, 199, 322, 17, 49, -162, -206, +-270, -357, -311, -408, -300, -415, -246, -382, +-142, -271, -27, -90, 66, 99, 118, 237, +132, 304, 124, 303, 127, 254, 139, 185, +141, 95, 120, -30, 81, -161, 38, -242, +-38, -248, -131, -215, -221, -183, -291, -153, +-311, -91, -229, 25, -58, 177, 122, 308, +261, 373, 364, 363, 409, 302, 348, 189, +187, 18, -35, -196, -254, -388, -430, -484, +-477, -442, -382, -300, -209, -140, -25, -6, +158, 112, 318, 211, 407, 260, 377, 242, +260, 188, 101, 135, -47, 117, -146, 136, +-213, 157, -246, 114, -238, 3, -173, -125, +-88, -229, -7, -322, 69, -397, 124, -406, +148, -306, 148, -106, 126, 145, 75, 358, +-11, 462, -89, 442, -93, 343, -62, 203, +-36, 25, -14, -171, 16, -315, 34, -356, +45, -303, 46, -204, 24, -108, -15, -39, +-24, 30, 6, 137, 38, 266, 42, 350, +18, 353, -31, 290, -110, 180, -168, 8, +-183, -219, -170, -454, -129, -617, -6, -635, +185, -472, 354, -177, 437, 157, 433, 447, +336, 657, 130, 760, -136, 715, -392, 497, +-580, 146, -657, -237, -567, -542, -340, -716, +-37, -756, 257, -674, 493, -468, 624, -160, +624, 190, 504, 488, 282, 656, 3, 659, +-239, 535, -368, 348, -399, 128, -369, -111, +-282, -321, -140, -440, -14, -435, 62, -339, +87, -205, 66, -85, 9, -5, -38, 53, +-27, 116, 27, 163, 89, 155, 148, 112, +208, 99, 235, 134, 211, 173, 132, 171, +34, 117, -80, 31, -172, -62, -213, -152, +-214, -233, -207, -309, -190, -356, -140, -319, +-70, -189, 8, -21, 68, 127, 96, 245, +112, 347, 137, 433, 148, 466, 143, 402, +124, 246, 104, 42, 81, -165, 50, -354, +18, -511, -40, -610, -141, -618, -250, -505, +-286, -269, -247, 30, -186, 308, -112, 512, +22, 647, 172, 724, 272, 697, 284, 527, +247, 252, 173, -58, 74, -350, -15, -586, +-74, -734, -115, -786, -147, -724, -166, -519, +-165, -192, -143, 155, -121, 424, -85, 582, +-17, 645, 116, 615, 270, 494, 367, 308, +358, 93, 258, -108, 100, -243, -122, -302, +-359, -327, -541, -349, -607, -347, -522, -284, +-267, -165, 94, -37, 459, 70, 697, 150, +774, 208, 691, 242, 459, 235, 98, 167, +-312, 49, -642, -71, -805, -140, -758, -141, +-544, -93, -240, -25, 95, 56, 403, 153, +599, 238, 635, 247, 506, 149, 270, -31, +-8, -220, -244, -357, -368, -408, -375, -376, +-285, -266, -130, -80, 60, 157, 216, 364, +268, 460, 185, 418, 26, 278, -143, 100, +-259, -65, -291, -188, -225, -253, -92, -255, +88, -187, 283, -60, 414, 73, 429, 139, +319, 116, 129, 49, -80, -20, -251, -89, +-363, -149, -404, -176, -376, -154, -267, -80, +-98, 40, 86, 160, 227, 219, 311, 207, +342, 171, 319, 150, 258, 121, 153, 62, +13, -7, -149, -61, -268, -105, -326, -160, +-328, -229, -294, -301, -215, -340, -91, -301, +68, -169, 219, 14, 316, 192, 331, 335, +282, 437, 201, 482, 103, 440, 12, 291, +-70, 71, -122, -152, -133, -320, -114, -416, +-101, -444, -124, -404, -187, -286, -241, -104, +-245, 104, -193, 278, -89, 360, 58, 335, +240, 254, 405, 159, 512, 49, 496, -80, +345, -183, 99, -229, -171, -228, -402, -205, +-542, -165, -563, -111, -453, -37, -231, 78, +62, 236, 354, 378, 544, 424, 578, 358, +455, 220, 245, 38, 3, -184, -239, -400, +-452, -528, -573, -526, -546, -401, -380, -189, +-144, 43, 92, 227, 288, 338, 435, 387, +523, 385, 518, 323, 426, 205, 246, 67, +19, -43, -210, -114, -390, -171, -512, -228, +-581, -275, -581, -291, -456, -258, -216, -188, +62, -93, 309, 16, 520, 145, 687, 290, +747, 421, 668, 474, 446, 404, 138, 228, +-197, 7, -496, -214, -702, -406, -780, -531, +-729, -554, -561, -457, -293, -260, 37, -22, +344, 189, 535, 331, 597, 411, 561, 454, +486, 450, 359, 381, 176, 253, -21, 86, +-165, -98, -258, -270, -320, -402, -359, -490, +-376, -515, -374, -445, -318, -279, -192, -67, +-33, 135, 134, 292, 283, 401, 409, 453, +484, 440, 478, 352, 367, 191, 179, -13, +-32, -194, -212, -299, -341, -337, -425, -326, +-449, -255, -387, -129, -252, 7, -93, 107, +72, 150, 205, 143, 299, 119, 355, 113, +388, 132, 359, 147, 244, 121, 73, 39, +-96, -72, -241, -188, -350, -291, -398, -353, +-373, -337, -276, -223, -131, -24, 39, 197, +182, 366, 264, 445, 283, 432, 285, 346, +271, 212, 227, 46, 160, -138, 80, -312, +-17, -425, -133, -448, -261, -393, -390, -287, +-477, -130, -487, 73, -385, 273, -170, 394, +123, 405, 402, 325, 602, 184, 676, 23, +622, -100, 438, -163, 129, -178, -235, -160, +-529, -99, -668, -13, -663, 47, -531, 46, +-294, 15, 1, -10, 261, -25, 445, -44, +534, -56, 519, -49, 393, -21, 200, 27, +7, 90, -154, 134, -274, 122, -353, 58, +-354, -16, -283, -73, -177, -107, -80, -115, +6, -73, 73, 24, 133, 128, 154, 181, +143, 160, 131, 64, 140, -79, 147, -209, +134, -269, 113, -256, 58, -183, -48, -55, +-181, 116, -272, 273, -291, 354, -252, 335, +-179, 238, -46, 88, 125, -89, 278, -248, +353, -347, 328, -369, 224, -297, 65, -118, +-101, 115, -227, 302, -271, 384, -247, 357, +-174, 234, -80, 33, 22, -190, 92, -373, +100, -458, 49, -416, -13, -263, -51, -43, +-47, 179, 10, 360, 114, 480, 245, 528, +338, 488, 342, 347, 253, 111, 84, -177, +-158, -443, -407, -619, -591, -678, -655, -607, +-579, -396, -362, -75, -40, 266, 302, 524, +579, 631, 717, 572, 702, 384, 538, 137, +270, -93, -30, -260, -278, -343, -441, -329, +-489, -227, -435, -86, -304, 41, -143, 121, +7, 153, 96, 148, 110, 120, 96, 71, +87, 1, 85, -79, 83, -141, 100, -165, +122, -153, 133, -123, 120, -80, 85, -21, +20, 57, -61, 137, -132, 202, -166, 234, +-172, 224, -174, 175, -151, 88, -96, -39, +-13, -178, 77, -278, 165, -299, 223, -232, +251, -89, 238, 85, 162, 218, 14, 264, +-164, 227, -324, 118, -410, -43, -390, -206, +-271, -302, -77, -287, 135, -178, 323, -23, +448, 135, 486, 253, 398, 302, 200, 287, +-38, 225, -234, 119, -362, -14, -419, -144, +-404, -232, -320, -262, -173, -242, 6, -184, +175, -85, 284, 36, 339, 145, 345, 202, +305, 197, 207, 131, 60, 19, -107, -92, +-250, -161, -338, -175, -343, -142, -287, -65, +-199, 56, -77, 184, 80, 266, 225, 279, +283, 229, 253, 120, 168, -36, 82, -202, +24, -327, -8, -383, -29, -353, -36, -227, +-35, -23, -37, 181, -62, 315, -130, 359, +-218, 320, -276, 201, -245, 31, -124, -127, +67, -221, 250, -239, 376, -190, 436, -96, +423, 5, 295, 82, 62, 128, -199, 149, +-396, 146, -495, 112, -490, 48, -382, -40, +-202, -128, 19, -195, 233, -226, 396, -210, +461, -138, 403, -26, 259, 98, 92, 193, +-59, 241, -181, 233, -270, 178, -306, 106, +-263, 52, -142, 21, 7, -12, 105, -49, +141, -84, 133, -131, 115, -201, 80, -268, +28, -298, -36, -279, -90, -196, -108, -50, +-72, 134, -15, 312, 14, 454, 13, 536, +20, 533, 52, 418, 75, 202, 75, -70, +50, -345, 15, -573, -17, -687, -34, -658, +-54, -495, -89, -235, -100, 74, -54, 356, +31, 538, 108, 580, 152, 496, 143, 329, +84, 130, -13, -58, -118, -200, -218, -276, +-281, -289, -256, -246, -108, -173, 113, -95, +315, -19, 421, 50, 403, 102, 284, 128, +100, 129, -116, 99, -340, 42, -494, -19, +-497, -63, -336, -83, -89, -79, 153, -60, +330, -19, 414, 35, 405, 83, 308, 97, +135, 79, -84, 38, -283, -4, -391, -38, +-363, -52, -245, -37, -92, 4, 61, 52, +214, 90, 340, 90, 398, 29, 335, -94, +170, -225, -20, -307, -175, -306, -286, -212, +-350, -28, -344, 204, -270, 412, -136, 528, +33, 510, 191, 352, 276, 86, 273, -215, +218, -453, 161, -565, 96, -543, 3, -405, +-87, -179, -136, 78, -123, 304, -77, 448, +-34, 491, -28, 434, -40, 301, -35, 121, +-4, -71, 16, -254, 19, -399, 1, -469, +-10, -446, 1, -340, 25, -179, 30, 9, +0, 200, -20, 361, 13, 467, 75, 493, +98, 431, 66, 295, 14, 110, -17, -92, +-43, -274, -66, -411, -93, -482, -111, -471, +-88, -365, -17, -190, 67, -3, 105, 152, +82, 257, 29, 295, -9, 271, -28, 202, +-46, 117, -78, 43, -83, 2, -35, 8, +59, 60, 131, 111, 140, 123, 101, 92, +46, 23, -10, -90, -68, -240, -120, -388, +-161, -480, -165, -476, -105, -359, 2, -144, +93, 121, 133, 373, 122, 563, 92, 648, +53, 598, -9, 409, -100, 135, -186, -147, +-205, -359, -139, -462, -29, -455, 74, -362, +151, -224, 205, -74, 247, 55, 249, 137, +194, 170, 56, 165, -111, 145, -233, 127, +-279, 105, -288, 49, -283, -39, -251, -130, +-168, -187, -38, -194, 96, -142, 183, -37, +216, 100, 237, 234, 259, 328, 269, 338, +235, 237, 143, 48, 16, -158, -97, -316, +-181, -390, -252, -370, -313, -267, -348, -108, +-321, 69, -219, 208, -75, 257, 41, 207, +121, 96, 203, -13, 300, -70, 365, -59, +359, 14, 276, 125, 144, 232, -3, 283, +-148, 244, -284, 96, -400, -136, -467, -376, +-428, -532, -262, -562, -26, -469, 200, -273, +372, -4, 476, 284, 513, 521, 451, 651, +259, 645, -40, 505, -342, 269, -556, -7, +-637, -277, -593, -506, -442, -650, -200, -665, +118, -532, 452, -282, 709, 16, 803, 294, +713, 506, 482, 613, 178, 596, -158, 448, +-496, 207, -761, -62, -880, -290, -806, -426, +-554, -454, -198, -390, 165, -268, 475, -119, +706, 31, 814, 146, 758, 190, 539, 155, +219, 89, -117, 43, -380, 36, -536, 65, +-584, 128, -547, 205, -412, 258, -193, 246, +61, 159, 254, -5, 352, -223, 367, -426, +322, -541, 234, -540, 123, -437, -9, -263, +-137, -42, -209, 189, -192, 390, -117, 527, +-39, 587, 22, 568, 65, 488, 103, 344, +126, 137, 114, -130, 52, -423, -34, -677, +-101, -813, -115, -790, -93, -612, -80, -304, +-66, 88, -27, 479, 48, 771, 116, 886, +157, 800, 145, 540, 107, 177, 68, -195, +53, -493, 35, -669, 1, -698, -42, -578, +-63, -339, -69, -54, -75, 194, -94, 353, +-121, 418, -123, 404, -72, 337, 30, 242, +127, 138, 192, 36, 232, -53, 251, -130, +221, -206, 132, -292, -5, -369, -156, -397, +-269, -340, -303, -201, -261, -10, -186, 186, +-87, 347, 32, 443, 172, 454, 293, 369, +356, 220, 327, 58, 236, -75, 119, -155, +6, -183, -123, -187, -262, -193, -375, -207, +-397, -220, -322, -221, -180, -213, -4, -190, +172, -117, 329, 17, 450, 191, 498, 360, +425, 481, 246, 518, 9, 462, -220, 318, +-392, 100, -485, -169, -489, -429, -404, -604, +-232, -632, 6, -514, 247, -289, 403, -16, +447, 243, 405, 434, 313, 518, 160, 469, +-29, 298, -205, 57, -310, -170, -335, -323, +-270, -375, -144, -329, -1, -200, 108, -14, +173, 192, 200, 351, 181, 405, 94, 330, +-26, 160, -116, -44, -137, -231, -100, -361, +-48, -401, -12, -342, 9, -209, 20, -43, +13, 106, -21, 197, -67, 223, -89, 215, +-57, 221, 23, 243, 126, 246, 199, 199, +206, 102, 151, -44, 65, -224, -36, -404, +-155, -520, -271, -521, -323, -380, -289, -117, +-184, 189, -51, 441, 71, 573, 149, 567, +193, 441, 212, 231, 197, -13, 131, -240, +47, -393, -27, -441, -68, -398, -88, -298, +-108, -172, -135, -40, -151, 91, -144, 209, +-111, 292, -68, 320, -28, 291, 12, 224, +58, 155, 97, 82, 109, -11, 87, -117, +32, -207, -33, -275, -71, -322, -69, -343, +-49, -322, -27, -250, 5, -113, 46, 78, +81, 285, 74, 447, 11, 530, -86, 526, +-163, 435, -195, 260, -172, 21, -118, -233, +-35, -444, 65, -564, 171, -574, 220, -491, +190, -341, 83, -148, -59, 65, -197, 260, +-271, 398, -258, 454, -172, 442, -41, 381, +116, 290, 262, 171, 328, 17, 281, -160, +135, -316, -50, -414, -216, -436, -313, -383, +-329, -256, -267, -75, -145, 116, 16, 269, +156, 339, 218, 302, 192, 177, 101, 24, +-4, -97, -88, -153, -115, -143, -95, -76, +-36, 32, 38, 145, 126, 218, 175, 224, +157, 164, 55, 52, -78, -80, -195, -205, +-264, -304, -280, -368, -238, -368, -145, -282, +-15, -110, 133, 104, 250, 307, 295, 445, +267, 490, 203, 431, 116, 281, 30, 67, +-50, -154, -111, -317, -145, -380, -143, -343, +-123, -237, -110, -111, -115, 2, -135, 84, +-139, 133, -113, 144, -46, 112, 45, 53, +155, 1, 256, -23, 349, -22, 387, -6, +345, 23, 206, 55, 27, 86, -159, 102, +-309, 77, -401, -2, -410, -109, -335, -200, +-189, -230, -11, -190, 155, -96, 273, 27, +320, 157, 312, 262, 264, 303, 190, 253, +89, 127, -10, -35, -95, -182, -151, -280, +-180, -311, -184, -278, -164, -193, -117, -63, +-36, 95, 63, 236, 164, 310, 229, 301, +244, 234, 208, 127, 147, 1, 51, -118, +-56, -207, -155, -244, -197, -215, -180, -136, +-104, -42, -7, 28, 93, 68, 160, 91, +185, 106, 167, 102, 115, 74, 35, 26, +-47, -21, -87, -53, -73, -67, -20, -68, +38, -58, 83, -28, 100, 25, 77, 81, +10, 109, -76, 90, -149, 44, -175, -5, +-139, -36, -33, -57, 123, -76, 272, -89, +371, -87, 385, -68, 313, -37, 156, -2, +-51, 40, -266, 92, -418, 142, -468, 170, +-403, 152, -267, 69, -81, -57, 113, -173, +294, -238, 412, -232, 454, -161, 419, -42, +331, 112, 198, 259, 44, 343, -117, 324, +-268, 199, -381, 9, -432, -185, -410, -334, +-318, -406, -156, -397, 42, -295, 232, -106, +376, 128, 459, 328, 454, 435, 353, 430, +187, 335, 10, 183, -140, 9, -254, -151, +-322, -257, -335, -290, -287, -253, -214, -178, +-129, -104, -47, -60, 50, -38, 145, -8, +232, 49, 284, 117, 304, 175, 271, 201, +183, 189, 50, 135, -84, 43, -201, -62, +-284, -144, -317, -165, -280, -107, -190, 1, +-86, 98, 5, 129, 70, 86, 117, -7, +145, -117, 163, -213, 174, -264, 176, -236, +151, -119, 96, 45, 6, 200, -119, 295, +-252, 311, -351, 260, -375, 175, -315, 76, +-167, -26, 30, -118, 230, -184, 365, -215, +409, -214, 335, -200, 173, -180, -53, -141, +-264, -63, -405, 44, -426, 154, -348, 236, +-195, 278, -13, 270, 161, 216, 276, 123, +296, 3, 229, -120, 114, -213, -8, -241, +-117, -201, -187, -127, -205, -52, -179, 5, +-135, 41, -75, 58, -24, 56, 6, 35, +14, 16, 7, 20, -3, 47, -15, 72, +-28, 74, -37, 44, -30, -3, -19, -40, +9, -48, 45, -32, 86, 0, 95, 38, +95, 70, 72, 79, 24, 53, -66, -13, +-173, -98, -269, -172, -311, -209, -299, -205, +-233, -167, -123, -104, 14, -20, 158, 85, +269, 204, 322, 307, 303, 365, 226, 369, +106, 319, -6, 203, -95, 35, -161, -161, +-213, -347, -235, -478, -235, -524, -224, -482, +-211, -366, -193, -204, -144, -12, -54, 194, +84, 387, 231, 530, 365, 592, 435, 560, +430, 444, 326, 247, 150, -12, -89, -289, +-322, -524, -487, -658, -529, -651, -463, -508, +-309, -269, -120, 6, 64, 253, 206, 426, +280, 500, 286, 458, 240, 323, 173, 150, +121, -4, 116, -115, 129, -174, 122, -189, +63, -177, -28, -157, -145, -138, -270, -119, +-376, -105, -418, -87, -358, -47, -204, 33, +19, 145, 250, 245, 435, 294, 515, 274, +487, 196, 356, 77, 160, -64, -82, -201, +-296, -290, -434, -302, -444, -244, -348, -145, +-177, -41, 22, 43, 217, 107, 356, 153, +415, 183, 372, 196, 230, 187, 28, 148, +-167, 80, -297, -16, -334, -134, -269, -244, +-130, -299, 58, -273, 255, -157, 400, 20, +423, 195, 313, 306, 107, 321, -121, 240, +-310, 87, -414, -102, -398, -263, -267, -338, +-40, -303, 217, -174, 435, 0, 530, 154, +486, 249, 315, 271, 86, 232, -157, 141, +-346, 22, -447, -86, -430, -145, -307, -152, +-98, -124, 128, -80, 315, -37, 413, -5, +423, 16, 370, 26, 267, 26, 117, 11, +-56, -6, -194, -12, -267, -4, -277, 8, +-259, 16, -216, 21, -144, 35, -38, 60, +80, 83, 194, 83, 280, 58, 332, 12, +352, -46, 334, -100, 268, -130, 135, -126, +-45, -79, -238, 1, -378, 85, -442, 129, +-413, 108, -321, 23, -161, -90, 46, -191, +273, -234, 441, -197, 514, -77, 473, 106, +362, 297, 212, 430, 42, 456, -139, 354, +-287, 158, -367, -76, -373, -290, -320, -443, +-237, -506, -137, -475, -38, -358, 71, -186, +184, 3, 289, 176, 338, 318, 324, 417, +271, 464, 202, 442, 110, 346, -21, 185, +-167, -10, -281, -204, -312, -357, -278, -442, +-209, -442, -141, -359, -57, -208, 32, -29, +120, 134, 165, 244, 171, 286, 138, 260, +114, 185, 96, 92, 84, 14, 47, -36, +-11, -44, -71, -12, -114, 33, -137, 52, +-162, 25, -185, -47, -190, -142, -142, -229, +-46, -276, 68, -252, 147, -150, 191, 11, +208, 191, 204, 330, 150, 387, 33, 349, +-118, 230, -240, 61, -284, -111, -258, -251, +-177, -330, -76, -335, 31, -267, 118, -149, +187, -18, 187, 104, 114, 205, -17, 269, +-124, 287, -185, 246, -183, 149, -155, 11, +-107, -135, -41, -255, 46, -321, 121, -315, +146, -231, 110, -89, 47, 83, -8, 246, +-47, 353, -71, 368, -102, 302, -135, 174, +-150, 11, -123, -157, -86, -295, -67, -373, +-67, -369, -49, -292, 6, -162, 75, -12, +127, 133, 137, 251, 120, 325, 87, 343, +50, 300, -16, 200, -98, 65, -196, -75, +-253, -191, -252, -277, -192, -314, -122, -286, +-52, -189, 19, -55, 111, 79, 188, 175, +220, 209, 191, 178, 121, 108, 45, 23, +-23, -44, -84, -70, -154, -43, -218, 24, +-251, 88, -221, 109, -148, 72, -75, -12, +-23, -109, 37, -182, 119, -202, 194, -168, +219, -87, 179, 20, 99, 123, 10, 187, +-63, 200, -127, 170, -177, 124, -212, 81, +-187, 41, -100, -8, 17, -70, 95, -144, +120, -218, 96, -271, 70, -286, 36, -249, +-12, -136, -84, 42, -131, 247, -119, 422, +-41, 516, 55, 492, 127, 355, 160, 130, +165, -143, 150, -406, 95, -595, -8, -655, +-141, -552, -247, -311, -281, 1, -229, 311, +-135, 549, -30, 659, 79, 608, 185, 409, +273, 111, 300, -205, 250, -451, 132, -570, +11, -541, -72, -397, -103, -185, -131, 48, +-151, 257, -144, 394, -78, 438, -1, 390, +60, 278, 73, 140, 66, 0, 65, -137, +84, -251, 84, -326, 59, -347, 13, -312, +-21, -225, -26, -112, -8, 8, 13, 126, +17, 233, 23, 303, 52, 318, 103, 272, +124, 188, 88, 91, 13, -6, -39, -99, +-61, -173, -67, -220, -72, -229, -66, -201, +-17, -151, 64, -92, 143, -27, 159, 38, +128, 99, 67, 142, 22, 154, -7, 124, +-21, 74, -40, 25, -40, -12, -11, -35, +61, -40, 122, -26, 137, 4, 92, 35, +33, 47, -19, 29, -65, -8, -117, -45, +-167, -55, -176, -48, -102, -40, 46, -39, +199, -50, 314, -73, 366, -92, 369, -96, +310, -67, 171, 6, -46, 114, -277, 226, +-446, 302, -511, 301, -457, 206, -319, 43, +-120, -133, 107, -272, 346, -338, 536, -321, +626, -225, 562, -81, 390, 60, 163, 151, +-52, 180, -255, 161, -419, 125, -520, 92, +-500, 76, -364, 64, -155, 41, 43, 0, +193, -52, 289, -115, 339, -176, 336, -218, +269, -208, 154, -136, 27, -18, -51, 115, +-72, 225, -57, 288, -51, 297, -65, 248, +-86, 152, -106, 17, -127, -137, -160, -273, +-190, -358, -177, -376, -81, -329, 64, -224, +209, -70, 291, 117, 319, 293, 297, 411, +231, 444, 110, 385, -39, 252, -196, 75, +-302, -110, -336, -268, -299, -369, -243, -393, +-175, -329, -91, -202, 27, -57, 157, 67, +259, 160, 298, 218, 275, 233, 217, 202, +129, 144, 9, 75, -142, 12, -280, -38, +-349, -78, -323, -118, -224, -150, -98, -159, +29, -134, 132, -77, 210, -1, 241, 77, +207, 150, 102, 206, -25, 224, -131, 188, +-192, 102, -230, -19, -233, -153, -205, -267, +-132, -330, -31, -340, 93, -284, 180, -156, +219, 31, 217, 234, 189, 401, 119, 485, +13, 468, -112, 353, -221, 162, -290, -66, +-302, -280, -255, -430, -183, -474, -109, -411, +-36, -270, 40, -105, 107, 42, 142, 145, +149, 200, 151, 203, 167, 172, 177, 130, +162, 104, 101, 104, 4, 124, -117, 140, +-236, 129, -344, 77, -406, -9, -412, -117, +-344, -232, -214, -332, -27, -385, 155, -363, +294, -250, 363, -72, 387, 121, 354, 289, +267, 406, 123, 449, -33, 405, -178, 280, +-287, 110, -346, -64, -355, -202, -323, -288, +-258, -314, -155, -297, -27, -253, 91, -180, +164, -82, 197, 17, 220, 104, 234, 173, +226, 223, 183, 245, 113, 232, 21, 176, +-76, 85, -177, -23, -264, -113, -328, -164, +-340, -178, -285, -166, -149, -128, 21, -66, +181, 2, 276, 54, 325, 82, 306, 83, +229, 65, 88, 39, -59, 13, -169, -12, +-208, -29, -183, -31, -117, -12, -48, 15, +7, 30, 44, 24, 59, 6, 49, -20, +19, -38, -5, -34, -3, -8, 28, 40, +67, 100, 82, 147, 60, 150, 3, 88, +-53, -28, -90, -171, -100, -297, -84, -364, +-25, -344, 71, -232, 172, -34, 223, 203, +208, 420, 118, 552, 8, 556, -103, 425, +-177, 197, -213, -82, -180, -347, -95, -530, +25, -591, 135, -524, 217, -345, 237, -97, +190, 158, 104, 351, 19, 449, -52, 439, +-104, 334, -122, 162, -97, -31, -32, -195, +50, -284, 103, -283, 115, -202, 85, -76, +36, 66, -19, 178, -62, 221, -86, 183, +-76, 85, -20, -45, 80, -165, 185, -233, +256, -221, 258, -139, 209, -18, 110, 103, +-3, 189, -140, 213, -254, 177, -323, 94, +-304, -1, -213, -83, -66, -125, 91, -119, +225, -81, 316, -38, 356, 1, 337, 26, +260, 34, 140, 30, 16, 27, -75, 28, +-126, 32, -156, 29, -168, 19, -174, -5, +-160, -38, -127, -70, -74, -85, -16, -76, +38, -36, 98, 14, 166, 56, 218, 83, +233, 86, 201, 60, 146, 17, 84, -25, +46, -42, 4, -24, -39, 18, -95, 63, +-128, 88, -151, 76, -160, 25, -172, -57, +-156, -150, -111, -227, -19, -247, 100, -197, +206, -90, 265, 45, 271, 181, 238, 278, +170, 312, 61, 276, -60, 181, -165, 56, +-213, -68, -202, -163, -144, -212, -70, -209, +-10, -164, 28, -96, 47, -29, 49, 21, +32, 52, 0, 56, -15, 34, -5, -2, +43, -30, 92, -41, 121, -26, 101, 6, +58, 59, -10, 125, -72, 182, -141, 204, +-185, 178, -198, 98, -155, -18, -69, -148, +29, -260, 111, -329, 159, -327, 174, -245, +168, -105, 127, 62, 46, 215, -69, 306, +-162, 312, -216, 240, -214, 116, -173, -26, +-117, -147, -47, -215, 39, -206, 124, -130, +166, -15, 140, 97, 71, 173, 1, 194, +-42, 160, -73, 82, -102, -19, -135, -131, +-132, -218, -107, -256, -58, -236, -34, -174, +-7, -80, 27, 34, 84, 152, 130, 251, +142, 307, 106, 303, 18, 237, -97, 122, +-197, -15, -268, -142, -290, -231, -267, -270, +-165, -255, -4, -192, 176, -95, 306, -2, +348, 60, 287, 87, 153, 95, -10, 95, +-176, 95, -322, 93, -400, 91, -374, 88, +-244, 76, -59, 48, 110, 6, 206, -52, +235, -104, 200, -129, 136, -127, 21, -114, +-106, -90, -222, -60, -252, -30, -191, 1, +-78, 44, 27, 98, 108, 150, 171, 194, +218, 220, 210, 195, 124, 106, -46, -37, +-222, -196, -343, -325, -383, -380, -367, -337, +-299, -199, -165, -5, 49, 206, 279, 377, +451, 454, 504, 401, 439, 247, 301, 39, +121, -162, -81, -313, -298, -382, -475, -361, +-547, -260, -502, -109, -343, 56, -149, 186, +55, 253, 226, 255, 374, 212, 452, 132, +428, 31, 290, -70, 91, -148, -98, -181, +-223, -148, -284, -66, -281, 35, -230, 119, +-121, 170, 18, 174, 141, 112, 182, -15, +148, -166, 58, -289, -30, -336, -100, -290, +-125, -157, -113, 27, -61, 219, 35, 369, +159, 440, 267, 410, 288, 288, 208, 100, +68, -102, -82, -268, -193, -365, -283, -387, +-322, -347, -290, -258, -149, -126, 46, 19, +234, 141, 348, 223, 376, 269, 328, 280, +226, 256, 79, 191, -86, 88, -247, -34, +-342, -141, -331, -209, -213, -231, -55, -207, +103, -135, 229, -38, 331, 55, 356, 116, +295, 131, 142, 92, -38, 12, -189, -70, +-279, -106, -280, -89, -213, -29, -101, 57, +32, 141, 170, 190, 289, 181, 331, 103, +301, -24, 199, -153, 92, -230, -9, -232, +-95, -158, -174, -37, -222, 99, -224, 199, +-170, 228, -88, 174, 6, 58, 75, -86, +119, -209, 158, -271, 203, -249, 226, -157, +214, -19, 165, 129, 139, 252, 112, 326, +79, 347, 6, 304, -83, 201, -173, 56, +-246, -101, -273, -259, -266, -404, -223, -507, +-147, -530, -19, -450, 154, -265, 314, 1, +431, 298, 469, 563, 444, 737, 356, 768, +212, 642, 6, 373, -219, 16, -414, -349, +-515, -643, -514, -798, -410, -783, -238, -619, +-25, -353, 210, -34, 429, 286, 568, 539, +581, 669, 450, 667, 249, 551, 4, 346, +-219, 86, -416, -183, -519, -412, -502, -560, +-359, -594, -127, -505, 118, -314, 314, -73, +418, 173, 431, 376, 370, 495, 244, 512, +80, 434, -90, 271, -215, 65, -278, -133, +-281, -287, -259, -389, -221, -440, -185, -427, +-114, -348, -12, -210, 117, -33, 224, 156, +293, 327, 336, 455, 353, 522, 318, 496, +202, 362, 3, 145, -192, -95, -346, -309, +-419, -454, -457, -504, -430, -458, -329, -343, +-149, -186, 69, -15, 260, 136, 378, 232, +416, 275, 395, 291, 333, 296, 213, 285, +31, 248, -169, 170, -322, 47, -401, -100, +-413, -242, -376, -364, -269, -437, -116, -421, +82, -293, 253, -77, 361, 159, 375, 351, +298, 456, 152, 451, -31, 338, -206, 145, +-346, -83, -425, -292, -394, -422, -275, -440, +-84, -353, 90, -190, 229, 13, 303, 207, +319, 356, 269, 443, 165, 453, 21, 366, +-129, 196, -256, -13, -311, -216, -299, -389, +-260, -508, -211, -544, -140, -478, -37, -317, +72, -89, 139, 159, 177, 376, 182, 527, +197, 598, 179, 569, 131, 433, 36, 214, +-87, -40, -206, -278, -301, -458, -348, -553, +-340, -546, -280, -448, -152, -280, 16, -73, +199, 137, 308, 303, 340, 393, 295, 403, +210, 351, 85, 256, -56, 143, -200, 22, +-300, -96, -345, -193, -320, -249, -252, -269, +-179, -264, -100, -229, -7, -152, 114, -47, +236, 64, 310, 168, 346, 250, 334, 292, +301, 288, 188, 237, 5, 145, -228, 20, +-446, -116, -598, -246, -662, -344, -606, -389, +-419, -359, -128, -262, 220, -112, 536, 74, +759, 269, 820, 418, 716, 483, 456, 455, +108, 345, -270, 170, -581, -32, -776, -218, +-792, -357, -663, -430, -411, -430, -90, -367, +233, -259, 492, -123, 622, 34, 620, 191, +500, 324, 294, 419, 50, 455, -203, 404, +-376, 257, -460, 46, -432, -182, -331, -382, +-181, -503, -10, -502, 151, -366, 274, -127, +332, 152, 317, 392, 259, 521, 172, 505, +74, 362, -36, 124, -128, -154, -188, -394, +-205, -529, -206, -536, -177, -426, -144, -231, +-83, 10, -28, 230, 41, 395, 107, 498, +173, 532, 250, 479, 313, 350, 352, 168, +343, -38, 274, -246, 146, -431, -47, -572, +-245, -644, -437, -613, -560, -462, -598, -220, +-520, 67, -328, 355, -43, 608, 285, 774, +591, 811, 802, 698, 881, 447, 797, 100, +562, -272, 205, -601, -205, -822, -582, -898, +-836, -802, -927, -542, -819, -164, -560, 249, +-170, 614, 235, 843, 594, 891, 826, 762, +898, 487, 811, 107, 571, -304, 239, -642, +-116, -821, -423, -821, -630, -658, -728, -374, +-673, -24, -485, 323, -193, 603, 115, 758, +393, 757, 594, 611, 696, 368, 668, 73, +517, -233, 258, -503, -38, -689, -307, -770, +-492, -718, -576, -529, -563, -233, -443, 111, +-217, 441, 65, 709, 343, 865, 518, 849, +606, 645, 574, 297, 450, -110, 227, -486, +-41, -747, -291, -851, -460, -784, -514, -552, +-463, -200, -321, 169, -111, 464, 105, 628, +300, 651, 422, 544, 461, 347, 397, 110, +257, -119, 80, -309, -84, -422, -223, -446, +-294, -394, -309, -288, -260, -140, -169, 28, +-49, 201, 77, 350, 156, 441, 186, 439, +186, 334, 177, 153, 166, -58, 97, -273, +13, -451, -73, -535, -104, -479, -120, -301, +-134, -50, -138, 210, -109, 426, -44, 546, +19, 541, 49, 408, 53, 176, 44, -98, +50, -336, 66, -488, 85, -527, 89, -447, +84, -268, 70, -47, 47, 160, -32, 322, +-138, 422, -248, 429, -297, 343, -284, 202, +-212, 54, -78, -85, 86, -202, 248, -286, +358, -325, 389, -319, 336, -268, 186, -192, +-7, -96, -222, 22, -375, 156, -454, 289, +-437, 396, -343, 459, -180, 459, 17, 365, +208, 179, 336, -65, 382, -327, 332, -570, +214, -737, 60, -768, -92, -633, -225, -352, +-312, 28, -330, 434, -257, 783, -141, 1001, +-9, 1038, 84, 859, 156, 488, 165, 1, +108, -508, 12, -949, -103, -1229, -190, -1283, +-217, -1083, -160, -661, -33, -80, 98, 557, +217, 1119, 277, 1477, 272, 1549, 162, 1305, +-20, 780, -228, 69, -397, -676, -492, -1306, +-469, -1679, -344, -1696, -136, -1346, 96, -717, +313, 49, 468, 791, 526, 1364, 465, 1644, +286, 1580, 28, 1199, -229, 596, -458, -97, +-601, -734, -646, -1202, -533, -1426, -307, -1378, +-16, -1074, 279, -580, 517, 5, 659, 573, +651, 1029, 499, 1280, 250, 1286, -61, 1064, +-365, 648, -611, 91, -735, -497, -732, -990, +-591, -1286, -354, -1336, -53, -1134, 252, -716, +535, -149, 723, 466, 797, 1010, 724, 1364, +521, 1454, 221, 1269, -124, 848, -466, 259, +-765, -400, -957, -1008, -966, -1444, -792, -1627, +-453, -1505, -47, -1087, 390, -447, 769, 289, +1018, 993, 1072, 1548, 913, 1837, 580, 1773, +136, 1352, -325, 653, -703, -184, -947, -1000, +-1024, -1638, -936, -1981, -677, -1952, -298, -1541, +128, -811, 511, 87, 810, 965, 973, 1661, +993, 2051, 832, 2052, 526, 1656, 102, 929, +-356, 12, -756, -920, -1016, -1677, -1079, -2103, +-956, -2113, -661, -1706, -215, -957, 297, -19, +779, 922, 1082, 1673, 1177, 2083, 1058, 2060, +768, 1621, 330, 883, -189, 5, -674, -856, +-1017, -1536, -1163, -1890, -1091, -1860, -825, -1490, +-412, -872, 67, -130, 548, 607, 944, 1217, +1167, 1599, 1167, 1696, 968, 1497, 605, 1047, +154, 429, -350, -263, -784, -925, -1081, -1437, +-1168, -1705, -1032, -1679, -703, -1344, -229, -737, +291, 37, 754, 824, 1083, 1473, 1210, 1857, +1124, 1891, 813, 1542, 351, 873, -183, 9, +-659, -874, -1001, -1584, -1154, -1978, -1095, -1989, +-819, -1608, -374, -897, 171, 5, 686, 900, +1061, 1614, 1223, 2013, 1164, 2021, 900, 1630, +451, 923, -110, 37, -641, -856, -1028, -1585, +-1184, -2002, -1126, -2032, -847, -1675, -410, -998, +117, -130, 630, 755, 1019, 1489, 1208, 1943, +1158, 2037, 898, 1738, 494, 1104, 2, 264, +-490, -623, -900, -1398, -1116, -1911, -1109, -2050, +-890, -1781, -525, -1158, -67, -308, 402, 599, +809, 1382, 1051, 1881, 1106, 1993, 950, 1694, +626, 1055, 201, 219, -247, -633, -634, -1347, +-898, -1780, -997, -1832, -907, -1504, -653, -896, +-273, -140, 121, 625, 491, 1257, 759, 1628, +907, 1670, 895, 1388, 725, 846, 432, 145, +71, -574, -294, -1187, -598, -1572, -807, -1648, +-874, -1394, -786, -860, -547, -139, -208, 633, +174, 1286, 511, 1665, 739, 1691, 817, 1366, +767, 750, 567, -41, 260, -830, -98, -1432, +-404, -1705, -601, -1602, -684, -1161, -642, -483, +-489, 290, -246, 995, 30, 1481, 273, 1636, +459, 1438, 527, 949, 481, 271, 334, -469, +146, -1114, -54, -1526, -236, -1620, -360, -1373, +-390, -819, -327, -71, -200, 702, -62, 1328, +62, 1669, 151, 1653, 205, 1275, 212, 614, +173, -184, 99, -944, 29, -1487, -24, -1688, +-43, -1518, -67, -1045, -89, -376, -131, 361, +-173, 1003, -205, 1400, -221, 1480, -209, 1261, +-157, 819, -43, 242, 127, -348, 299, -844, +442, -1153, 497, -1221, 446, -1041, 276, -671, +36, -191, -242, 316, -515, 745, -719, 999, +-778, 1034, -683, 853, -450, 486, -137, 3, +215, -473, 541, -815, 783, -944, 892, -852, +837, -564, 613, -135, 266, 330, -144, 708, +-526, 908, -841, 881, -1010, 639, -1018, 246, +-836, -205, -496, -623, -65, -916, 372, -1003, +727, -859, 960, -521, 1046, -56, 947, 449, +675, 881, 262, 1133, -194, 1155, -626, 931, +-953, 486, -1126, -102, -1104, -699, -895, -1164, +-514, -1391, -30, -1330, 480, -982, 890, -405, +1134, 292, 1173, 958, 1003, 1445, 631, 1634, +114, 1474, -443, 991, -918, 283, -1229, -516, +-1290, -1237, -1100, -1719, -680, -1838, -135, -1561, +448, -947, 953, -117, 1262, 763, 1295, 1505, +1047, 1942, 587, 1973, 17, 1591, -563, 871, +-1027, -46, -1288, -977, -1277, -1711, -1008, -2086, +-531, -2031, 51, -1571, 619, -784, 1052, 183, +1280, 1121, 1248, 1824, 980, 2150, 501, 2049, +-84, 1543, -655, 725, -1087, -246, -1300, -1177, +-1266, -1880, -995, -2212, -536, -2108, 33, -1589, +619, -740, 1072, 288, 1323, 1280, 1317, 2023, +1064, 2369, 588, 2243, -7, 1651, -605, 689, +-1108, -439, -1408, -1488, -1401, -2236, -1084, -2528, +-542, -2292, 91, -1563, 728, -500, 1241, 672, +1494, 1708, 1407, 2379, 1020, 2544, 407, 2181, +-294, 1370, -942, 269, -1364, -884, -1499, -1837, +-1313, -2399, -827, -2470, -122, -2029, 629, -1163, +1221, -55, 1531, 1056, 1507, 1944, 1148, 2423, +540, 2391, -200, 1855, -893, 929, -1406, -199, +-1603, -1281, -1431, -2080, -933, -2427, -241, -2261, +500, -1612, 1153, -622, 1596, 495, 1695, 1487, +1417, 2139, 829, 2326, 72, 2024, -704, 1305, +-1338, 328, -1691, -689, -1681, -1532, -1324, -2035, +-686, -2108, 87, -1754, 852, -1060, 1421, -174, +1696, 718, 1634, 1435, 1273, 1850, 687, 1895, +-23, 1563, -723, 917, -1271, 106, -1571, -692, +-1572, -1332, -1292, -1703, -767, -1726, -106, -1388, +575, -769, 1150, -9, 1519, 730, 1595, 1299, +1367, 1583, 885, 1525, 270, 1141, -376, 529, +-941, -166, -1336, -796, -1468, -1235, -1303, -1395, +-887, -1243, -333, -827, 248, -263, 753, 317, +1107, 804, 1227, 1112, 1121, 1170, 807, 961, +372, 559, -88, 74, -459, -398, -689, -771, +-790, -969, -770, -953, -620, -731, -387, -356, +-133, 74, 84, 452, 271, 715, 425, 825, +541, 748, 585, 499, 547, 157, 437, -191, +281, -481, 80, -661, -142, -681, -369, -541, +-556, -290, -678, 3, -691, 268, -566, 459, +-326, 547, -20, 508, 305, 350, 607, 126, +838, -93, 912, -260, 805, -362, 521, -383, +135, -309, -287, -160, -666, 3, -935, 116, +-1033, 161, -941, 154, -672, 104, -280, 23, +181, -49, 619, -67, 975, -11, 1175, 102, +1179, 226, 962, 304, 551, 301, -11, 198, +-624, -13, -1168, -293, -1497, -550, -1555, -704, +-1315, -710, -795, -545, -43, -204, 795, 255, +1504, 715, 1915, 1056, 1940, 1188, 1555, 1066, +818, 687, -144, 99, -1111, -587, -1887, -1205, +-2287, -1595, -2210, -1658, -1649, -1366, -726, -747, +352, 94, 1357, 982, 2113, 1716, 2461, 2126, +2307, 2108, 1646, 1642, 649, 791, -457, -292, +-1472, -1374, -2242, -2218, -2602, -2650, -2448, -2562, +-1784, -1922, -752, -820, 456, 516, 1579, 1802, +2389, 2764, 2719, 3190, 2507, 2957, 1777, 2063, +660, 664, -601, -931, -1737, -2353, -2521, -3297, +-2778, -3564, -2453, -3057, -1606, -1845, -445, -209, +798, 1477, 1865, 2862, 2538, 3648, 2671, 3633, +2233, 2803, 1302, 1358, 91, -375, -1144, -2032, +-2120, -3270, -2647, -3805, -2603, -3504, -1987, -2442, +-912, -852, 370, 936, 1561, 2546, 2391, 3630, +2697, 3951, 2401, 3434, 1576, 2166, 385, 394, +-901, -1497, -2009, -3105, -2663, -4090, -2688, -4216, +-2111, -3419, -1095, -1858, 147, 138, 1377, 2160, +2319, 3770, 2705, 4577, 2452, 4376, 1642, 3221, +483, 1358, -777, -840, -1854, -2904, -2511, -4353, +-2587, -4844, -2067, -4272, -1067, -2775, 162, -668, +1354, 1624, 2234, 3596, 2602, 4776, 2357, 4897, +1567, 3964, 409, 2175, -868, -119, -1984, -2438, +-2654, -4240, -2720, -5091, -2151, -4824, -1081, -3522, +264, -1446, 1569, 998, 2549, 3260, 2982, 4785, +2750, 5229, 1892, 4545, 594, 2902, -874, 620, +-2186, -1829, -3043, -3869, -3228, -5013, -2712, -5046, +-1597, -4029, -98, -2185, 1475, 132, 2751, 2414, +3427, 4108, 3341, 4856, 2528, 4584, 1142, 3383, +-519, 1463, -2113, -770, -3266, -2778, -3690, -4113, +-3270, -4528, -2124, -3974, -513, -2574, 1216, -629, +2710, 1423, 3624, 3101, 3765, 4019, 3077, 4009, +1697, 3124, -85, 1573, -1849, -316, -3202, -2096, +-3864, -3320, -3706, -3724, -2737, -3298, -1163, -2171, +671, -560, 2347, 1172, 3515, 2569, 3919, 3307, +3487, 3305, 2313, 2605, 650, 1316, -1140, -294, +-2653, -1795, -3576, -2822, -3728, -3194, -3101, -2867, +-1819, -1895, -168, -477, 1504, 1044, 2843, 2277, +3568, 2936, 3515, 2910, 2696, 2218, 1297, 984, +-347, -499, -1886, -1815, -2974, -2621, -3396, -2768, +-3055, -2254, -2056, -1180, -641, 201, 882, 1506, +2205, 2373, 3015, 2608, 3116, 2194, 2511, 1251, +1412, -8, 67, -1272, -1269, -2192, -2326, -2540, +-2841, -2269, -2704, -1471, -1981, -324, -858, 912, +422, 1928, 1587, 2476, 2395, 2448, 2662, 1879, +2340, 893, 1503, -314, 363, -1471, -809, -2275, +-1746, -2542, -2267, -2255, -2286, -1485, -1816, -368, +-944, 851, 113, 1858, 1107, 2411, 1794, 2412, +2054, 1878, 1843, 918, 1229, -255, 366, -1357, +-530, -2105, -1266, -2330, -1674, -2024, -1671, -1267, +-1271, -209, -595, 898, 195, 1749, 902, 2141, +1359, 2037, 1473, 1501, 1247, 624, 733, -419, +56, -1354, -606, -1922, -1082, -2025, -1296, -1709, +-1203, -1039, -824, -103, -255, 886, 358, 1650, +886, 2013, 1224, 1934, 1267, 1423, 973, 565, +442, -452, -178, -1368, -739, -1932, -1155, -2004, +-1315, -1607, -1158, -852, -695, 120, -57, 1082, +598, 1735, 1129, 1887, 1424, 1581, 1382, 945, +1009, 100, 407, -772, -276, -1417, -916, -1643, +-1378, -1438, -1541, -917, -1362, -228, -905, 488, +-264, 1059, 437, 1323, 1062, 1230, 1457, 854, +1545, 304, 1307, -300, 815, -808, 197, -1076, +-428, -1034, -970, -720, -1325, -242, -1397, 278, +-1188, 725, -793, 978, -272, 938, 287, 611, +766, 112, 1043, -424, 1114, -873, 1012, -1105, +756, -1023, 363, -642, -70, -68, -451, 566, +-729, 1102, -901, 1384, -933, 1315, -803, 905, +-524, 250, -166, -500, 207, -1178, 542, -1616, +802, -1690, 916, -1365, 844, -702, 591, 153, +229, 1002, -177, 1653, -556, 1956, -824, 1831, +-909, 1267, -806, 374, -562, -631, -242, -1514, +122, -2074, 477, -2147, 758, -1687, 888, -816, +858, 249, 669, 1272, 333, 2001, -119, 2222, +-582, 1876, -956, 1076, -1152, 27, -1119, -1019, +-814, -1802, -297, -2125, 320, -1914, 904, -1231, +1319, -257, 1440, 761, 1213, 1589, 677, 2031, +-35, 1951, -761, 1380, -1316, 487, -1596, -515, +-1537, -1421, -1146, -2011, -473, -2097, 323, -1625, +1059, -731, 1580, 335, 1770, 1331, 1555, 2047, +975, 2276, 179, 1898, -648, 1011, -1354, -118, +-1796, -1228, -1873, -2080, -1532, -2437, -846, -2159, +17, -1330, 861, -188, 1548, 1003, 1940, 1979, +1921, 2494, 1456, 2409, 685, 1739, -210, 660, +-1076, -573, -1758, -1692, -2073, -2449, -1933, -2658, +-1375, -2259, -530, -1333, 448, -70, 1336, 1249, +1930, 2310, 2075, 2860, 1763, 2769, 1090, 2043, +217, 814, -697, -658, -1493, -2017, -1982, -2924, +-2001, -3146, -1564, -2630, -813, -1487, 99, 30, +1016, 1556, 1714, 2703, 1992, 3199, 1797, 2947, +1214, 2003, 360, 581, -590, -965, -1416, -2240, +-1869, -2954, -1839, -2962, -1373, -2275, -632, -1062, +232, 389, 1052, 1724, 1616, 2595, 1734, 2811, +1416, 2371, 813, 1385, 81, 55, -682, -1287, +-1299, -2279, -1598, -2699, -1502, -2481, -1066, -1657, +-385, -398, 393, 979, 1071, 2108, 1479, 2712, +1553, 2661, 1287, 1977, 721, 798, -29, -632, +-760, -1953, -1285, -2791, -1499, -2938, -1373, -2390, +-918, -1269, -247, 201, 457, 1671, 1012, 2745, +1325, 3135, 1311, 2768, 958, 1741, 369, 278, +-270, -1282, -801, -2538, -1104, -3155, -1109, -2996, +-803, -2121, -284, -727, 313, 871, 819, 2256, +1099, 3066, 1053, 3117, 717, 2411, 196, 1120, +-381, -451, -873, -1923, -1144, -2931, -1148, -3220, +-887, -2722, -392, -1557, 256, 4, 882, 1576, +1322, 2751, 1481, 3250, 1327, 2993, 858, 2036, +158, 559, -637, -1085, -1336, -2441, -1755, -3170, +-1753, -3158, -1354, -2439, -648, -1125, 241, 510, +1137, 2004, 1796, 2933, 2032, 3154, 1803, 2689, +1177, 1583, 276, 38, -690, -1505, -1487, -2600, +-1936, -3040, -1974, -2795, -1582, -1908, -820, -522, +151, 1025, 1082, 2284, 1750, 2911, 2005, 2831, +1828, 2140, 1261, 953, 410, -528, -538, -1890, +-1347, -2717, -1841, -2860, -1940, -2390, -1619, -1392, +-919, -26, -8, 1356, 911, 2345, 1635, 2741, +2016, 2549, 1939, 1827, 1418, 676, 568, -644, +-417, -1764, -1312, -2421, -1903, -2538, -2068, -2127, +-1770, -1247, -1045, -77, -47, 1089, 942, 1969, +1677, 2377, 2023, 2244, 1923, 1615, 1352, 630, +457, -506, -496, -1514, -1278, -2135, -1799, -2239, +-1946, -1831, -1609, -989, -834, 102, 115, 1141, +970, 1857, 1599, 2122, 1905, 1908, 1758, 1244, +1137, 279, 239, -708, -638, -1476, -1327, -1901, +-1734, -1911, -1761, -1468, -1329, -694, -568, 163, +264, 922, 969, 1501, 1457, 1772, 1622, 1613, +1387, 1089, 801, 405, 76, -302, -603, -957, +-1150, -1423, -1485, -1557, -1453, -1337, -1015, -854, +-320, -247, 394, 372, 1007, 909, 1412, 1254, +1483, 1309, 1136, 1082, 498, 688, -211, 209, +-837, -312, -1301, -781, -1497, -1067, -1327, -1109, +-819, -954, -154, -669, 483, -276, 990, 189, +1337, 629, 1409, 931, 1134, 1044, 604, 989, +11, 772, -556, 393, -1062, -87, -1373, -562, +-1327, -944, -959, -1147, -442, -1111, 113, -842, +660, -403, 1074, 151, 1207, 717, 1030, 1136, +667, 1281, 213, 1140, -275, 756, -748, 177, +-1042, -489, -1048, -1058, -808, -1357, -465, -1325, +-66, -996, 390, -429, 788, 287, 951, 991, +856, 1469, 616, 1567, 295, 1269, -117, 670, +-529, -108, -790, -930, -822, -1595, -701, -1866, +-510, -1638, -244, -1003, 104, -130, 421, 831, +582, 1671, 598, 2120, 579, 2000, 518, 1365, +317, 409, 16, -660, -225, -1627, -377, -2222, +-521, -2228, -651, -1636, -642, -651, -481, 471, +-248, 1507, -14, 2210, 238, 2327, 493, 1796, +683, 802, 727, -374, 612, -1466, 385, -2216, +102, -2403, -225, -1936, -538, -940, -721, 297, +-700, 1466, -556, 2302, -361, 2575, -117, 2151, +172, 1124, 403, -194, 501, -1469, 494, -2419, +441, -2784, 339, -2401, 186, -1359, 18, 41, +-137, 1434, -287, 2491, -430, 2927, -526, 2579, +-532, 1517, -452, 49, -280, -1428, -19, -2552, +297, -3029, 570, -2679, 752, -1568, 810, -31, +716, 1502, 440, 2672, 23, 3184, -441, 2828, +-845, 1661, -1107, 42, -1141, -1585, -902, -2847, +-437, -3423, 127, -3092, 673, -1912, 1105, -238, +1345, 1491, 1289, 2890, 918, 3610, 333, 3406, +-299, 2312, -871, 645, -1275, -1181, -1397, -2742, +-1210, -3637, -800, -3608, -239, -2667, 416, -1074, +1012, 767, 1363, 2414, 1437, 3455, 1266, 3608, +833, 2834, 143, 1385, -592, -352, -1160, -1993, +-1504, -3144, -1615, -3452, -1378, -2844, -773, -1576, +11, -8, 765, 1557, 1409, 2752, 1838, 3204, +1870, 2799, 1418, 1745, 636, 342, -234, -1131, +-1036, -2347, -1692, -2939, -2027, -2731, -1860, -1847, +-1197, -573, -294, 800, 623, 1967, 1437, 2611, +1983, 2545, 2039, 1818, 1566, 662, 761, -602, +-164, -1651, -1066, -2246, -1761, -2268, -2040, -1691, +-1806, -658, -1142, 481, -199, 1369, 792, 1863, +1615, 1929, 2094, 1504, 2104, 660, 1575, -280, +622, -1003, -474, -1418, -1456, -1530, -2160, -1294, +-2401, -728, -2026, -40, -1096, 506, 102, 833, +1298, 990, 2267, 970, 2753, 744, 2532, 406, +1663, 113, 411, -104, -949, -320, -2183, -520, +-2969, -627, -3004, -657, -2246, -679, -925, -638, +631, -413, 2094, -30, 3098, 376, 3342, 778, +2747, 1161, 1439, 1329, -269, 1090, -1960, 534, +-3163, -155, -3558, -928, -3040, -1641, -1731, -1923, +69, -1602, 1887, -858, 3230, 126, 3744, 1237, +3307, 2142, 1997, 2409, 127, 1950, -1794, 985, +-3237, -296, -3854, -1636, -3498, -2565, -2222, -2713, +-306, -2105, 1689, -965, 3196, 492, 3874, 1908, +3609, 2769, 2395, 2799, 501, 2101, -1489, 881, +-2997, -641, -3725, -2032, -3541, -2762, -2410, -2657, +-599, -1887, 1281, -622, 2688, 885, 3377, 2100, +3252, 2569, 2275, 2275, 719, 1402, -930, 119, +-2246, -1237, -2960, -2133, -2895, -2253, -2088, -1684, +-811, -662, 572, 569, 1732, 1623, 2387, 2071, +2406, 1766, 1860, 915, 915, -168, -238, -1180, +-1274, -1809, -1872, -1791, -1940, -1131, -1612, -130, +-950, 820, -30, 1456, 860, 1635, 1404, 1283, +1559, 475, 1426, -433, 991, -1040, 276, -1207, +-492, -1031, -1102, -591, -1486, 17, -1576, 507, +-1255, 597, -563, 368, 290, 102, 1085, -64, +1695, -113, 1939, 45, 1650, 431, 844, 803, +-255, 846, -1367, 447, -2207, -281, -2500, -1083, +-2080, -1690, -1019, -1867, 398, -1426, 1761, -356, +2698, 1014, 2933, 2155, 2387, 2667, 1160, 2414, +-460, 1418, -2044, -102, -3091, -1704, -3288, -2815, +-2633, -3030, -1320, -2336, 366, -1025, 2010, 558, +3125, 2004, 3399, 2839, 2832, 2753, 1592, 1888, +-54, 640, -1719, -669, -2927, -1765, -3392, -2321, +-3083, -2183, -2097, -1504, -588, -573, 1094, 388, +2489, 1203, 3262, 1697, 3342, 1742, 2735, 1367, +1448, 736, -299, 12, -2023, -719, -3270, -1315, +-3806, -1566, -3493, -1396, -2270, -913, -410, -229, +1576, 547, 3192, 1210, 4069, 1530, 3926, 1433, +2719, 962, 769, 232, -1354, -569, -3090, -1199, +-4011, -1488, -3867, -1393, -2696, -936, -865, -210, +1085, 562, 2627, 1141, 3398, 1401, 3262, 1325, +2316, 914, 824, 235, -750, -484, -1930, -994, +-2470, -1245, -2380, -1247, -1737, -937, -697, -328, +387, 342, 1137, 847, 1441, 1151, 1372, 1235, +986, 992, 379, 428, -196, -270, -530, -864, +-605, -1236, -495, -1325, -217, -1044, 119, -388, +305, 424, 243, 1094, 41, 1438, -175, 1403, +-356, 948, -456, 146, -392, -724, -149, -1349, +175, -1542, 453, -1255, 605, -602, 586, 189, +383, 892, 70, 1321, -206, 1319, -365, 890, +-411, 262, -386, -319, -284, -764, -142, -1008, +-61, -960, -57, -656, -42, -272, 68, 64, +274, 358, 521, 648, 743, 874, 818, 940, +637, 822, 166, 537, -518, 47, -1233, -657, +-1698, -1405, -1701, -1863, -1185, -1781, -244, -1124, +914, -3, 1951, 1328, 2493, 2452, 2330, 2928, +1493, 2464, 234, 1129, -1121, -644, -2260, -2286, +-2860, -3285, -2680, -3292, -1759, -2250, -413, -487, +1029, 1354, 2276, 2660, 2999, 3093, 2946, 2639, +2142, 1511, 792, 62, -831, -1254, -2329, -2026, +-3246, -2185, -3298, -1927, -2452, -1381, -867, -547, +1069, 429, 2743, 1287, 3645, 1918, 3551, 2282, +2447, 2152, 542, 1315, -1568, -109, -3153, -1665, +-3777, -2849, -3357, -3290, -2003, -2749, -43, -1174, +1924, 1005, 3265, 2937, 3624, 3898, 3018, 3658, +1688, 2276, -36, 71, -1724, -2208, -2898, -3694, +-3221, -3975, -2702, -3110, -1592, -1373, -159, 736, +1348, 2520, 2537, 3493, 2999, 3516, 2648, 2636, +1690, 1099, 361, -633, -1110, -2148, -2328, -3167, +-2890, -3435, -2686, -2802, -1807, -1461, -436, 225, +1103, 1922, 2353, 3227, 2960, 3705, 2789, 3185, +1880, 1830, 425, 3, -1174, -1858, -2448, -3269, +-3081, -3836, -2905, -3411, -1912, -2122, -336, -296, +1326, 1603, 2572, 3109, 3113, 3863, 2824, 3679, +1722, 2538, 86, 686, -1525, -1370, -2617, -3057, +-2999, -3971, -2614, -3866, -1478, -2685, 91, -745, +1560, 1322, 2522, 2958, 2837, 3792, 2466, 3595, +1412, 2427, -61, 712, -1459, -1035, -2415, -2430, +-2778, -3199, -2467, -3157, -1456, -2381, -1, -1133, +1436, 347, 2465, 1810, 2871, 2889, 2540, 3241, +1489, 2781, -34, 1643, -1541, -6, -2549, -1812, +-2852, -3154, -2431, -3507, -1353, -2819, 122, -1377, +1547, 460, 2514, 2186, 2837, 3115, 2439, 2936, +1401, 1916, 2, 473, -1376, -989, -2375, -1995, +-2759, -2217, -2439, -1706, -1504, -783, -190, 208, +1190, 964, 2268, 1312, 2698, 1231, 2375, 796, +1456, 161, 168, -429, -1191, -812, -2192, -966, +-2500, -859, -2119, -434, -1199, 162, 61, 666, +1285, 950, 2058, 999, 2189, 715, 1698, 109, +690, -530, -538, -908, -1553, -969, -2067, -748, +-1953, -290, -1214, 276, -65, 683, 1081, 749, +1808, 554, 1908, 243, 1392, -136, 410, -451, +-722, -536, -1579, -382, -1843, -136, -1457, 136, +-605, 395, 403, 507, 1193, 400, 1490, 193, +1236, -83, 544, -428, -278, -681, -893, -651, +-1094, -364, -866, 26, -339, 435, 280, 796, +738, 918, 848, 684, 602, 161, 109, -429, +-451, -858, -863, -1021, -969, -916, -688, -535, +-129, 29, 482, 566, 1036, 892, 1417, 997, +1396, 959, 833, 759, -87, 337, -999, -224, +-1715, -766, -2084, -1180, -1847, -1432, -936, -1404, +333, -925, 1515, -43, 2329, 902, 2571, 1614, +2027, 1949, 830, 1759, -583, 994, -1796, -66, +-2487, -1032, -2462, -1661, -1716, -1815, -524, -1454, +710, -762, 1681, 11, 2112, 683, 1906, 1110, +1215, 1217, 268, 1110, -682, 885, -1383, 518, +-1643, -7, -1419, -545, -867, -965, -144, -1235, +589, -1273, 1083, -954, 1191, -344, 947, 361, +516, 978, 3, 1342, -528, 1307, -865, 893, +-852, 295, -571, -263, -247, -670, 33, -866, +322, -828, 492, -593, 364, -306, 91, -89, +-64, 51, -92, 172, -160, 275, -197, 341, +21, 364, 276, 387, 241, 379, 95, 255, +80, 73, 28, -35, -245, -101, -451, -227, +-350, -385, -147, -438, -2, -427, 170, -432, +345, -344, 365, -68, 198, 280, -4, 568, +-143, 736, -226, 732, -201, 499, -11, 111, +270, -286, 471, -563, 489, -624, 363, -462, +55, -201, -394, 77, -740, 278, -823, 261, +-697, 30, -414, -214, 87, -335, 696, -300, +1065, -78, 1092, 327, 923, 716, 533, 876, +-113, 768, -734, 405, -1052, -216, -1092, -873, +-905, -1262, -423, -1255, 215, -896, 716, -270, +927, 473, 852, 1099, 528, 1354, 55, 1160, +-373, 651, -603, 38, -572, -532, -295, -920, +41, -970, 251, -692, 302, -325, 211, 5, +-34, 275, -323, 447, -415, 494, -232, 439, +17, 345, 204, 250, 364, 100, 436, -129, +271, -463, -71, -769, -321, -815, -362, -601, +-284, -228, -167, 341, -20, 991, 159, 1406, +226, 1308, 84, 761, -84, 17, -81, -802, +31, -1546, 79, -1844, 50, -1481, 93, -674, +144, 200, 24, 1031, -160, 1725, -178, 1909, +-47, 1430, 38, 629, 64, -203, 174, -1001, +243, -1617, 129, -1767, -56, -1400, -155, -730, +-164, 85, -162, 916, -118, 1481, 32, 1639, +210, 1440, 319, 874, 331, 24, 291, -796, +198, -1370, -19, -1632, -286, -1523, -506, -998, +-642, -204, -572, 609, -248, 1270, 266, 1658, +786, 1644, 1074, 1235, 1049, 497, 714, -404, +78, -1190, -703, -1666, -1318, -1772, -1498, -1473, +-1234, -785, -617, 162, 245, 1037, 1065, 1611, +1556, 1841, 1623, 1650, 1218, 1015, 444, 129, +-430, -770, -1154, -1455, -1623, -1819, -1701, -1783, +-1258, -1301, -473, -479, 338, 456, 1060, 1245, +1573, 1718, 1656, 1856, 1178, 1559, 316, 804, +-549, -150, -1182, -1006, -1478, -1613, -1304, -1859, +-731, -1635, -4, -975, 623, -107, 985, 771, +985, 1488, 622, 1824, 83, 1656, -345, 1071, +-534, 216, -509, -728, -332, -1497, -52, -1827, +198, -1685, 270, -1110, 204, -132, 110, 951, +-26, 1677, -148, 1903, -134, 1672, 1, 953, +112, -126, 164, -1147, 200, -1756, 164, -1845, +17, -1481, -150, -759, -294, 166, -367, 1001, +-287, 1448, -49, 1486, 276, 1256, 601, 853, +776, 280, 671, -363, 253, -889, -316, -1199, +-834, -1334, -1156, -1285, -1117, -942, -639, -282, +163, 503, 1014, 1214, 1533, 1663, 1541, 1710, +1085, 1326, 247, 521, -757, -515, -1522, -1357, +-1761, -1793, -1479, -1822, -818, -1398, 120, -519, +1039, 510, 1585, 1308, 1631, 1754, 1245, 1829, +555, 1420, -303, 624, -1107, -308, -1550, -1163, +-1582, -1779, -1295, -1982, -691, -1614, 173, -760, +1022, 254, 1518, 1206, 1577, 1886, 1317, 2068, +735, 1645, -87, 724, -912, -350, -1487, -1254, +-1652, -1843, -1452, -1928, -964, -1434, -217, -567, +595, 321, 1256, 1043, 1612, 1565, 1595, 1700, +1214, 1285, 513, 571, -367, -150, -1151, -796, +-1587, -1292, -1594, -1460, -1276, -1206, -626, -631, +273, 42, 1052, 650, 1441, 1080, 1410, 1201, +1043, 942, 470, 444, -179, -58, -698, -446, +-972, -709, -968, -758, -717, -560, -349, -243, +63, 44, 478, 233, 750, 303, 828, 319, +703, 279, 391, 189, -27, 68, -474, -72, +-816, -144, -877, -161, -610, -242, -139, -237, +331, -86, 697, 40, 891, 109, 829, 221, +477, 358, -42, 345, -469, 123, -671, -82, +-708, -192, -550, -307, -235, -431, 3, -451, +72, -268, 150, 8, 313, 212, 391, 374, +317, 458, 258, 460, 246, 412, 172, 248, +-42, 5, -330, -213, -504, -407, -488, -541, +-427, -645, -346, -642, -131, -402, 131, -11, +219, 378, 209, 743, 348, 1002, 516, 981, +358, 586, 54, 15, 11, -499, 35, -868, +-247, -1024, -568, -863, -554, -423, -359, 122, +-255, 528, -123, 656, 153, 557, 393, 364, +448, 118, 419, -133, 421, -269, 415, -206, +233, -79, -105, -29, -421, 32, -569, 144, +-599, 152, -591, 98, -404, 71, 65, -9, +573, -213, 862, -445, 866, -538, 666, -462, +287, -269, -224, 108, -628, 574, -770, 917, +-657, 1000, -348, 756, -35, 288, 244, -242, +501, -760, 568, -1085, 406, -1064, 219, -738, +145, -329, 69, 34, -116, 450, -230, 853, +-254, 1001, -338, 909, -444, 704, -403, 393, +-173, -140, 89, -816, 279, -1305, 451, -1394, +541, -1067, 542, -377, 438, 473, 167, 1251, +-155, 1660, -416, 1452, -630, 678, -773, -306, +-771, -1111, -532, -1501, -147, -1373, 286, -672, +779, 341, 1098, 1107, 991, 1258, 537, 918, +-34, 310, -545, -484, -976, -1149, -1165, -1223, +-919, -700, -353, 93, 284, 849, 765, 1325, +921, 1292, 768, 704, 413, -176, 40, -972, +-270, -1461, -464, -1475, -463, -936, -357, -8, +-256, 913, -171, 1505, -153, 1566, -140, 1050, +-46, 186, 189, -681, 507, -1310, 718, -1457, +779, -1048, 662, -252, 288, 607, -180, 1151, +-637, 1151, -1086, 675, -1302, -27, -987, -673, +-287, -1019, 380, -867, 931, -278, 1436, 481, +1593, 1045, 1195, 1122, 430, 727, -452, 35, +-1302, -788, -1897, -1375, -1907, -1419, -1211, -911, +-113, -109, 971, 679, 1782, 1311, 2206, 1631, +2016, 1372, 1062, 608, -303, -296, -1478, -1022, +-2140, -1514, -2172, -1681, -1590, -1287, -555, -417, +582, 534, 1451, 1337, 1855, 1813, 1701, 1785, +988, 1141, 27, 51, -760, -1038, -1173, -1777, +-1232, -1982, -963, -1519, -429, -538, 139, 610, +497, 1511, 608, 1837, 516, 1484, 289, 622, +46, -376, -94, -1126, -99, -1393, -15, -1068, +44, -330, -2, 460, -186, 1016, -449, 1120, +-659, 636, -674, -177, -420, -869, 111, -1205, +782, -1116, 1265, -544, 1312, 353, 1003, 1198, +352, 1565, -596, 1298, -1403, 567, -1687, -357, +-1485, -1189, -884, -1604, 33, -1406, 966, -607, +1497, 434, 1518, 1259, 1171, 1560, 544, 1260, +-202, 480, -784, -556, -1025, -1426, -924, -1657, +-685, -1246, -400, -415, -41, 571, 287, 1358, +487, 1708, 636, 1472, 755, 682, 717, -213, +481, -892, 171, -1319, -212, -1428, -685, -1157, +-1060, -628, -1113, -62, -795, 487, -233, 1017, +417, 1329, 1052, 1353, 1402, 1139, 1277, 658, +770, -116, -16, -1012, -906, -1660, -1510, -1807, +-1564, -1502, -1112, -771, -359, 234, 528, 1136, +1262, 1637, 1539, 1673, 1350, 1263, 793, 565, +-69, -159, -930, -687, -1389, -962, -1332, -1003, +-965, -909, -462, -739, 108, -528, 583, -250, +831, 169, 885, 673, 789, 1071, 572, 1262, +268, 1179, -33, 783, -309, 78, -604, -747, +-889, -1365, -1042, -1547, -911, -1269, -444, -678, +143, 17, 650, 715, 1032, 1211, 1209, 1316, +1042, 1084, 559, 668, -26, 146, -521, -432, +-863, -936, -969, -1176, -818, -1147, -550, -878, +-270, -372, 29, 285, 275, 950, 490, 1376, +752, 1321, 939, 856, 894, 185, 725, -493, +465, -1056, -74, -1343, -828, -1173, -1371, -603, +-1514, 71, -1351, 635, -882, 1000, -55, 1128, +905, 960, 1608, 567, 1894, 70, 1813, -438, +1249, -886, 189, -1212, -955, -1292, -1719, -994, +-2026, -429, -1939, 278, -1323, 1031, -207, 1631, +951, 1842, 1783, 1541, 2141, 774, 1936, -239, +1187, -1210, 61, -1877, -1078, -2129, -1849, -1858, +-2107, -1060, -1816, -7, -1051, 997, 36, 1774, +1129, 2154, 1781, 2027, 1829, 1388, 1458, 464, +806, -524, -74, -1425, -972, -1979, -1475, -2037, +-1476, -1673, -1153, -930, -561, 42, 176, 940, +736, 1545, 933, 1837, 841, 1771, 633, 1294, +292, 524, -125, -295, -389, -1005, -445, -1520, +-380, -1763, -292, -1605, -212, -1041, -82, -263, +9, 523, 73, 1192, 216, 1620, 392, 1664, +501, 1251, 493, 575, 348, -115, 56, -711, +-362, -1177, -739, -1380, -956, -1234, -910, -867, +-509, -413, 95, 100, 666, 586, 1079, 1009, +1245, 1266, 1111, 1221, 643, 941, -10, 503, +-659, -82, -1178, -712, -1383, -1249, -1204, -1487, +-736, -1373, -93, -1018, 564, -458, 1108, 285, +1375, 1054, 1302, 1625, 978, 1840, 409, 1711, +-330, 1179, -961, 233, -1326, -908, -1393, -1899, +-1195, -2443, -735, -2387, -51, -1701, 670, -421, +1191, 1085, 1422, 2274, 1414, 2765, 1110, 2480, +415, 1512, -386, 107, -998, -1295, -1429, -2185, +-1621, -2337, -1362, -1815, -648, -860, 195, 211, +860, 1039, 1322, 1402, 1495, 1315, 1223, 935, +570, 453, -143, 50, -684, -217, -1069, -353, +-1238, -414, -998, -446, -471, -532, 57, -673, +447, -675, 711, -442, 845, -108, 765, 298, +466, 738, 120, 1056, -135, 1125, -344, 912, +-543, 475, -562, -65, -382, -592, -195, -996, +-89, -1198, -27, -1103, 22, -776, 65, -355, +92, 136, 166, 616, 306, 931, 489, 1017, +626, 885, 612, 651, 414, 350, 54, -20, +-434, -340, -904, -549, -1133, -700, -992, -773, +-617, -757, -151, -638, 385, -389, 879, -28, +1088, 351, 947, 726, 639, 1036, 265, 1105, +-207, 888, -552, 503, -555, -8, -401, -542, +-334, -961, -297, -1180, -169, -1140, -58, -830, +-95, -367, -104, 125, 51, 599, 271, 999, +435, 1163, 539, 1071, 601, 819, 496, 426, +119, -107, -342, -658, -680, -1023, -831, -1148, +-813, -1145, -605, -934, -196, -473, 305, 85, +700, 619, 829, 1055, 715, 1310, 529, 1348, +242, 1104, -156, 578, -468, -147, -603, -854, +-631, -1351, -584, -1589, -403, -1489, -73, -967, +245, -178, 431, 596, 507, 1145, 516, 1426, +431, 1396, 187, 1011, -129, 414, -339, -144, +-405, -584, -356, -928, -223, -1103, -6, -1021, +219, -800, 263, -501, 120, -18, 6, 591, +-26, 1053, -117, 1251, -221, 1210, -142, 852, +20, 133, 75, -663, 109, -1213, 205, -1402, +276, -1207, 257, -617, 166, 217, 69, 921, +-50, 1213, -240, 1127, -430, 699, -487, 37, +-406, -565, -280, -906, -90, -926, 229, -628, +488, -143, 542, 342, 502, 622, 453, 697, +342, 639, 196, 407, 66, 38, -148, -281, +-513, -472, -872, -617, -1106, -754, -1175, -691, +-981, -417, -403, -111, 509, 252, 1482, 731, +2213, 1145, 2446, 1289, 1966, 1107, 857, 671, +-578, -6, -2029, -836, -3117, -1552, -3414, -1928, +-2774, -1873, -1398, -1333, 418, -383, 2294, 744, +3622, 1747, 3959, 2376, 3281, 2436, 1793, 1885, +-186, 848, -2177, -443, -3629, -1681, -4097, -2511, +-3457, -2675, -1929, -2156, 43, -1171, 1958, 98, +3278, 1392, 3656, 2272, 3094, 2469, 1769, 2074, +11, 1250, -1604, 110, -2631, -1067, -2912, -1823, +-2429, -1981, -1312, -1653, 39, -978, 1199, -85, +1944, 796, 2178, 1359, 1795, 1421, 879, 1089, +-187, 503, -1002, -158, -1465, -698, -1573, -1001, +-1234, -979, -503, -623, 297, -102, 896, 415, +1245, 779, 1299, 896, 952, 768, 335, 445, +-275, -49, -767, -586, -1135, -921, -1254, -974, +-1002, -864, -460, -538, 156, 17, 748, 572, +1219, 907, 1397, 1011, 1195, 943, 664, 677, +-71, 206, -813, -278, -1358, -610, -1542, -767, +-1274, -806, -613, -745, 142, -569, 750, -299, +1192, -13, 1365, 231, 1089, 463, 507, 739, +-54, 917, -483, 892, -834, 732, -951, 425, +-741, -77, -440, -610, -178, -991, 155, -1177, +459, -1168, 499, -862, 344, -327, 233, 188, +149, 600, -13, 911, -148, 1031, -107, 951, +45, 757, 179, 536, 238, 282, 200, -24, +38, -379, -179, -766, -395, -1120, -573, -1338, +-623, -1363, -512, -1114, -306, -507, -19, 390, +351, 1267, 700, 1880, 880, 2165, 952, 1977, +963, 1222, 748, 142, 252, -959, -356, -1861, +-980, -2329, -1545, -2213, -1819, -1627, -1594, -737, +-982, 313, -172, 1226, 823, 1742, 1875, 1887, +2549, 1706, 2488, 1201, 1759, 462, 665, -251, +-645, -753, -1960, -1149, -2857, -1457, -3020, -1449, +-2388, -1164, -1150, -777, 409, -269, 1990, 390, +3090, 1042, 3276, 1500, 2554, 1673, 1227, 1489, +-391, 914, -1964, 86, -2975, -802, -3023, -1487, +-2237, -1739, -953, -1530, 511, -936, 1775, -97, +2434, 719, 2288, 1272, 1514, 1383, 476, 1050, +-556, 457, -1334, -184, -1630, -717, -1387, -989, +-819, -922, -192, -543, 373, 10, 779, 553, +922, 918, 798, 1036, 474, 852, 163, 359, +-8, -317, -180, -945, -441, -1340, -639, -1408, +-658, -1123, -597, -481, -513, 377, -249, 1147, +229, 1544, 731, 1539, 1091, 1269, 1261, 750, +1176, 9, 737, -644, -48, -988, -908, -1116, +-1509, -1187, -1742, -1129, -1651, -839, -1186, -463, +-325, -130, 699, 304, 1521, 872, 1943, 1348, +1991, 1510, 1674, 1407, 915, 1157, -113, 651, +-1083, -124, -1823, -869, -2223, -1400, -2112, -1729, +-1502, -1839, -589, -1599, 451, -1002, 1449, -236, +2115, 597, 2253, 1471, 1903, 2109, 1181, 2255, +224, 1951, -778, 1328, -1580, 389, -1962, -717, +-1917, -1623, -1579, -2130, -1006, -2278, -194, -2041, +663, -1412, 1269, -525, 1576, 442, 1683, 1356, +1551, 2065, 1100, 2436, 395, 2378, -335, 1813, +-926, 777, -1390, -446, -1663, -1554, -1603, -2379, +-1260, -2751, -744, -2439, -74, -1532, 674, -417, +1315, 680, 1704, 1651, 1753, 2241, 1458, 2316, +929, 1955, 242, 1306, -608, 467, -1428, -478, +-1852, -1372, -1805, -2003, -1475, -2205, -867, -1931, +25, -1276, 894, -314, 1451, 793, 1715, 1690, +1685, 2082, 1220, 1944, 379, 1367, -466, 444, +-1072, -581, -1438, -1319, -1515, -1623, -1185, -1524, +-530, -1022, 189, -258, 784, 512, 1165, 1132, +1218, 1419, 959, 1242, 512, 715, -25, 63, +-523, -654, -840, -1313, -909, -1595, -777, -1342, +-540, -728, -187, 40, 245, 838, 572, 1494, +705, 1751, 737, 1544, 716, 1021, 497, 312, +47, -468, -320, -1140, -508, -1590, -739, -1742, +-948, -1589, -879, -1178, -552, -536, -139, 311, +320, 1178, 810, 1825, 1156, 2137, 1242, 2038, +1081, 1437, 643, 486, -24, -536, -745, -1458, +-1312, -2094, -1557, -2207, -1431, -1802, -931, -1119, +-184, -320, 544, 558, 1079, 1311, 1356, 1705, +1331, 1752, 1006, 1565, 450, 1097, -146, 341, +-624, -463, -922, -1071, -1000, -1438, -859, -1487, +-526, -1156, -96, -553, 254, 107, 493, 619, +607, 806, 476, 645, 169, 313, -117, -24, +-312, -301, -343, -342, -111, -44, 294, 409, +585, 779, 655, 959, 579, 882, 291, 488, +-257, -194, -824, -903, -1134, -1433, -1112, -1723, +-838, -1691, -382, -1234, 148, -434, 597, 493, +930, 1354, 1148, 2029, 1173, 2348, 1009, 2195, +711, 1561, 252, 574, -353, -524, -939, -1567, +-1389, -2411, -1703, -2766, -1703, -2525, -1149, -1852, +-239, -839, 665, 477, 1443, 1807, 1953, 2742, +1941, 3063, 1399, 2798, 562, 1965, -339, 602, +-1109, -991, -1533, -2274, -1467, -2911, -975, -2857, +-286, -2140, 334, -901, 701, 473, 764, 1524, +506, 1981, -32, 1841, -615, 1259, -893, 468, +-721, -284, -187, -723, 568, -696, 1347, -359, +1821, 5, 1710, 256, 1028, 332, -28, 186, +-1242, -188, -2243, -626, -2624, -877, -2280, -878, +-1367, -669, -119, -228, 1126, 321, 2037, 794, +2442, 1107, 2285, 1210, 1584, 1019, 584, 588, +-371, 95, -1101, -389, -1528, -826, -1638, -989, +-1490, -852, -1123, -647, -579, -446, 37, -200, +561, -9, 896, 53, 1103, 95, 1163, 230, +976, 438, 615, 751, 217, 1097, -200, 1174, +-618, 865, -854, 350, -758, -295, -523, -1050, +-328, -1641, -68, -1758, 205, -1429, 294, -809, +205, -8, 68, 750, -73, 1205, -186, 1350, +-118, 1257, 144, 946, 382, 545, 531, 216, +640, -79, 626, -361, 379, -557, -43, -720, +-468, -952, -833, -1137, -1107, -1081, -1130, -759, +-885, -316, -492, 211, 44, 835, 693, 1406, +1263, 1678, 1540, 1547, 1456, 1093, 1054, 437, +352, -354, -488, -1088, -1182, -1510, -1539, -1525, +-1457, -1244, -985, -767, -333, -143, 333, 422, +822, 663, 918, 635, 628, 529, 186, 425, +-158, 338, -311, 328, -263, 438, 27, 579, +463, 573, 788, 358, 782, -39, 439, -548, +-74, -1051, -630, -1383, -1132, -1461, -1416, -1250, +-1362, -723, -933, 26, -211, 787, 567, 1461, +1223, 1949, 1673, 2040, 1784, 1601, 1466, 767, +776, -207, -119, -1163, -1035, -1952, -1724, -2279, +-1900, -1960, -1551, -1145, -850, -149, 50, 794, +869, 1460, 1348, 1666, 1411, 1438, 1077, 938, +447, 306, -254, -254, -720, -573, -794, -644, +-618, -591, -336, -505, 32, -398, 366, -307, +482, -273, 376, -200, 232, 7, 121, 247, +-45, 385, -214, 492, -302, 587, -382, 511, +-490, 245, -526, -34, -388, -231, -78, -322, +288, -316, 631, -252, 913, -165, 1035, -55, +861, 9, 408, -54, -141, -201, -670, -314, +-1123, -349, -1319, -254, -1127, 0, -658, 389, +-125, 810, 342, 1092, 768, 1139, 1125, 933, +1160, 414, 795, -382, 335, -1233, -22, -1813, +-389, -1971, -725, -1735, -765, -1072, -537, 21, +-328, 1214, -154, 2078, 123, 2473, 330, 2397, +254, 1691, 61, 448, -15, -811, -36, -1761, +-123, -2378, -121, -2461, 53, -1882, 187, -891, +252, 160, 398, 1069, 490, 1667, 373, 1840, +176, 1609, -9, 1098, -296, 466, -655, -155, +-888, -697, -968, -1038, -911, -1102, -579, -980, +-11, -793, 580, -491, 1101, -54, 1507, 342, +1642, 541, 1339, 628, 719, 663, 32, 556, +-724, 328, -1499, 168, -1961, 54, -1912, -145, +-1515, -308, -971, -338, -202, -402, 801, -485, +1649, -429, 2045, -240, 2050, 15, 1803, 312, +1251, 532, 293, 562, -782, 435, -1540, 221, +-1985, -99, -2194, -429, -1929, -570, -1112, -438, +-148, -123, 632, 220, 1315, 465, 1816, 556, +1778, 418, 1271, 69, 681, -363, 144, -711, +-364, -803, -739, -584, -845, -175, -754, 322, +-650, 789, -561, 1003, -472, 835, -386, 450, +-261, 11, -68, -454, 194, -810, 521, -850, +811, -629, 924, -335, 798, -51, 556, 183, +290, 283, -84, 281, -462, 292, -617, 327, +-629, 347, -630, 393, -552, 444, -349, 349, +-144, 52, -51, -295, 23, -623, 176, -903, +344, -969, 473, -755, 543, -356, 555, 180, +519, 715, 422, 1018, 271, 1058, 6, 929, +-399, 543, -758, -88, -941, -601, -963, -804, +-815, -864, -446, -771, 107, -401, 668, 82, +1042, 398, 1140, 521, 942, 507, 513, 309, +-43, -8, -568, -221, -829, -283, -744, -250, +-440, -85, -62, 196, 268, 390, 481, 404, +471, 313, 155, 123, -266, -190, -502, -475, +-537, -599, -469, -575, -226, -462, 260, -245, +710, 84, 803, 425, 635, 646, 420, 724, +127, 695, -281, 565, -603, 290, -635, -99, +-491, -493, -361, -789, -185, -942, 83, -929, +257, -729, 261, -321, 234, 194, 225, 678, +170, 1049, 76, 1215, -9, 1057, -82, 611, +-117, 47, -91, -513, -83, -991, -51, -1200, +106, -1048, 212, -641, 123, -109, 18, 427, +20, 768, -30, 813, -214, 662, -312, 390, +-252, 25, -260, -267, -313, -348, -173, -291, +85, -196, 283, -52, 489, 77, 770, 66, +904, -56, 708, -132, 331, -158, -162, -197, +-776, -181, -1236, -26, -1335, 202, -1120, 392, +-665, 507, -28, 539, 645, 422, 1112, 133, +1257, -279, 1127, -677, 794, -920, 378, -956, +-29, -724, -365, -188, -542, 464, -611, 974, +-659, 1209, -651, 1135, -561, 748, -436, 137, +-367, -501, -291, -958, -29, -1127, 345, -993, +632, -646, 854, -201, 1087, 214, 1218, 507, +1051, 694, 584, 784, -24, 710, -664, 522, +-1263, 316, -1698, 60, -1808, -285, -1473, -606, +-829, -813, -123, -879, 588, -771, 1247, -491, +1655, -111, 1726, 319, 1560, 731, 1208, 1003, +625, 1049, -104, 883, -764, 543, -1274, 54, +-1650, -500, -1809, -950, -1636, -1178, -1099, -1135, +-345, -810, 391, -257, 1009, 340, 1476, 802, +1690, 1026, 1556, 937, 1151, 596, 674, 187, +138, -219, -502, -509, -1043, -511, -1318, -307, +-1397, -105, -1311, 59, -982, 154, -415, 94, +199, -86, 736, -234, 1155, -313, 1290, -311, +1104, -167, 733, 75, 215, 298, -341, 437, +-706, 480, -804, 454, -714, 333, -479, 111, +-95, -113, 293, -256, 496, -345, 495, -402, +299, -397, -30, -305, -338, -194, -532, -140, +-571, -113, -449, -7, -199, 140, 129, 228, +431, 327, 634, 514, 707, 644, 636, 606, +489, 451, 334, 231, 127, -76, -186, -469, +-566, -844, -893, -1053, -1115, -1069, -1180, -968, +-962, -714, -480, -181, 120, 495, 808, 1071, +1451, 1502, 1744, 1761, 1580, 1663, 1112, 1111, +467, 223, -305, -732, -1026, -1563, -1460, -2142, +-1605, -2261, -1529, -1776, -1141, -867, -484, 136, +165, 1087, 676, 1860, 1116, 2151, 1417, 1873, +1391, 1254, 1081, 503, 649, -303, 104, -1019, +-450, -1429, -794, -1462, -934, -1263, -971, -917, +-866, -433, -578, 76, -234, 454, 31, 707, +233, 868, 384, 893, 447, 788, 470, 600, +456, 336, 398, 53, 323, -248, 223, -553, +133, -743, 74, -749, -13, -638, -161, -413, +-343, -63, -466, 274, -513, 432, -563, 419, +-573, 252, -449, -42, -220, -295, 38, -356, +285, -201, 545, 172, 778, 656, 910, 1043, +986, 1129, 940, 856, 631, 289, 117, -495, +-458, -1306, -1037, -1802, -1534, -1809, -1769, -1429, +-1626, -782, -1155, 93, -378, 993, 612, 1597, +1483, 1812, 1981, 1737, 2116, 1403, 1914, 839, +1303, 163, 326, -489, -685, -1045, -1474, -1444, +-2006, -1634, -2146, -1592, -1798, -1303, -1132, -784, +-316, -151, 583, 495, 1366, 1105, 1751, 1588, +1710, 1750, 1418, 1539, 902, 1092, 192, 471, +-459, -293, -870, -968, -1088, -1344, -1157, -1402, +-1007, -1158, -635, -636, -236, -65, 62, 298, +375, 444, 720, 401, 886, 152, 795, -108, +585, -159, 319, 28, -45, 375, -436, 769, +-684, 1033, -726, 997, -596, 637, -322, 82, +42, -529, 392, -1032, 600, -1293, 587, -1262, +408, -994, 166, -614, -95, -227, -349, 141, +-495, 476, -426, 776, -239, 1013, -88, 1179, +36, 1236, 142, 1068, 190, 655, 190, 103, +165, -514, 124, -1099, 80, -1476, 71, -1536, +90, -1338, 47, -936, -45, -378, -88, 193, +-100, 672, -111, 1063, -91, 1314, -63, 1348, +-107, 1177, -259, 866, -405, 408, -395, -181, +-243, -766, -15, -1189, 318, -1353, 768, -1235, +1135, -882, 1129, -339, 765, 253, 255, 692, +-369, 882, -1078, 811, -1596, 517, -1654, 115, +-1266, -249, -623, -445, 115, -387, 839, -100, +1417, 264, 1696, 585, 1562, 812, 1119, 810, +540, 446, -165, -140, -899, -720, -1386, -1202, +-1505, -1523, -1359, -1528, -1019, -1126, -422, -444, +337, 332, 940, 1116, 1225, 1768, 1236, 2078, +999, 1952, 553, 1456, 8, 668, -480, -281, +-768, -1186, -826, -1893, -673, -2246, -361, -2119, +-6, -1602, 265, -849, 400, 39, 457, 912, +431, 1569, 212, 1899, -124, 1903, -371, 1598, +-480, 1026, -530, 325, -489, -367, -246, -961, +156, -1372, 550, -1520, 864, -1366, 1050, -992, +986, -522, 570, -5, -110, 448, -773, 701, +-1257, 753, -1577, 679, -1575, 529, -1049, 353, +-140, 228, 742, 197, 1355, 239, 1721, 273, +1737, 212, 1236, 50, 433, -177, -300, -470, +-861, -793, -1253, -1017, -1367, -1038, -1132, -843, +-742, -494, -403, -30, -76, 508, 280, 1014, +590, 1337, 816, 1403, 955, 1231, 984, 837, +887, 262, 654, -356, 263, -901, -265, -1275, +-768, -1403, -1096, -1296, -1219, -965, -1125, -439, +-817, 112, -382, 555, 102, 909, 572, 1153, +939, 1161, 1106, 933, 1077, 588, 908, 185, +603, -229, 211, -585, -172, -830, -546, -896, +-872, -789, -1009, -588, -939, -323, -779, -6, +-551, 282, -178, 455, 268, 555, 597, 650, +790, 623, 892, 396, 831, 113, 625, -112, +377, -341, 92, -561, -212, -593, -453, -393, +-589, -132, -655, 119, -665, 349, -585, 435, +-458, 307, -326, 57, -115, -188, 196, -343, +506, -367, 732, -256, 866, -31, 892, 241, +754, 441, 443, 484, 12, 376, -467, 174, +-860, -55, -1062, -263, -1076, -415, -900, -474, +-538, -415, -54, -256, 409, -64, 715, 133, +874, 317, 919, 409, 788, 386, 500, 307, +195, 161, -57, -42, -311, -203, -578, -273, +-726, -272, -735, -227, -693, -144, -539, -48, +-218, 12, 172, 56, 559, 130, 847, 205, +900, 247, 707, 251, 366, 197, -65, 55, +-512, -141, -768, -327, -693, -440, -431, -391, +-106, -184, 291, 50, 596, 254, 594, 400, +348, 375, 58, 166, -223, -77, -489, -228, +-588, -263, -463, -164, -212, 53, 105, 291, +398, 414, 558, 332, 601, 101, 525, -147, +285, -391, -83, -587, -405, -590, -561, -376, +-619, -90, -583, 136, -347, 313, 18, 472, +359, 529, 572, 443, 605, 324, 490, 229, +256, 101, -40, -76, -284, -241, -448, -355, +-539, -446, -549, -522, -431, -510, -153, -365, +164, -162, 431, 39, 694, 270, 868, 491, +804, 612, 494, 592, 25, 437, -556, 187, +-1136, -81, -1413, -301, -1228, -409, -756, -358, +-134, -177, 593, 27, 1229, 168, 1510, 203, +1370, 67, 954, -211, 377, -480, -267, -599, +-795, -528, -1094, -280, -1162, 126, -1032, 571, +-742, 862, -285, 950, 263, 849, 678, 536, +847, 88, 837, -335, 688, -640, 347, -801, +-112, -815, -424, -696, -435, -468, -254, -164, +14, 121, 300, 301, 442, 376, 313, 368, +-34, 306, -439, 231, -735, 184, -823, 216, +-652, 319, -262, 413, 210, 425, 601, 298, +764, 33, 686, -316, 496, -680, 289, -934, +102, -980, -22, -863, -55, -635, -32, -281, +-65, 139, -230, 487, -453, 734, -621, 940, +-673, 1075, -606, 1053, -407, 875, -70, 590, +309, 204, 612, -261, 796, -682, 833, -982, +729, -1172, 486, -1253, 143, -1195, -165, -996, +-375, -669, -519, -229, -597, 328, -574, 976, +-438, 1589, -295, 1963, -223, 1973, -164, 1593, +-66, 847, 65, -103, 215, -1010, 352, -1690, +498, -1969, 645, -1804, 693, -1345, 567, -742, +312, -138, 36, 328, -215, 644, -475, 817, +-690, 875, -782, 906, -767, 909, -683, 812, +-506, 652, -201, 468, 168, 194, 465, -177, +680, -535, 856, -815, 928, -1013, 794, -1126, +513, -1081, 236, -806, 11, -380, -213, 87, +-434, 573, -635, 933, -813, 1009, -948, 866, +-980, 607, -823, 264, -467, -13, -1, -80, +544, 5, 1079, 122, 1422, 192, 1450, 110, +1178, -168, 709, -591, 166, -991, -384, -1172, +-855, -1079, -1149, -749, -1234, -222, -1144, 377, +-900, 884, -529, 1172, -103, 1185, 301, 1006, +692, 747, 1012, 408, 1117, 31, 983, -259, +712, -435, 383, -563, 25, -618, -320, -584, +-584, -523, -747, -491, -835, -511, -817, -534, +-632, -479, -346, -326, -78, -39, 209, 419, +568, 988, 817, 1479, 804, 1684, 624, 1515, +370, 1012, 26, 235, -329, -670, -567, -1431, +-628, -1808, -522, -1782, -286, -1431, 4, -832, +279, -136, 480, 450, 521, 815, 357, 973, +92, 994, -205, 869, -529, 643, -756, 436, +-704, 243, -398, 19, -4, -156, 403, -271, +787, -378, 981, -440, 880, -428, 594, -412, +219, -400, -242, -348, -623, -279, -759, -214, +-750, -96, -706, 75, -562, 248, -315, 401, +-45, 557, 230, 671, 489, 653, 680, 516, +788, 305, 778, 9, 596, -318, 270, -577, +-103, -706, -461, -676, -696, -484, -715, -200, +-567, 79, -352, 255, -103, 264, 126, 122, +263, -68, 270, -229, 176, -269, 62, -111, +2, 205, 1, 551, 79, 816, 253, 895, +411, 744, 423, 376, 335, -125, 158, -628, +-199, -1026, -637, -1242, -889, -1207, -880, -929, +-685, -463, -305, 124, 252, 708, 777, 1147, +1037, 1382, 984, 1316, 681, 909, 186, 298, +-362, -355, -769, -904, -896, -1165, -733, -1107, +-370, -783, 73, -268, 490, 247, 753, 584, +739, 716, 447, 640, 49, 392, -316, 76, +-641, -199, -848, -378, -774, -454, -439, -442, +11, -316, 477, -81, 852, 174, 978, 384, +820, 566, 470, 630, 21, 478, -450, 175, +-797, -182, -898, -533, -716, -737, -327, -717, +82, -491, 363, -106, 502, 306, 470, 561, +260, 611, -13, 465, -196, 165, -239, -167, +-143, -418, 82, -492, 329, -331, 434, -62, +393, 205, 239, 432, -37, 521, -368, 406, +-610, 167, -695, -108, -638, -333, -441, -459, +-107, -461, 210, -344, 393, -154, 535, 23, +683, 132, 715, 198, 596, 260, 397, 284, +156, 260, -157, 224, -486, 174, -754, 42, +-931, -168, -952, -372, -718, -475, -279, -442, +190, -250, 547, 84, 790, 468, 896, 738, +756, 773, 411, 529, 68, 59, -200, -491, +-411, -942, -501, -1139, -424, -993, -276, -563, +-124, 29, 46, 632, 224, 1066, 326, 1223, +308, 1104, 168, 765, -39, 297, -262, -235, +-502, -697, -669, -977, -600, -1094, -321, -1045, +63, -748, 519, -278, 948, 218, 1133, 646, +979, 922, 615, 961, 175, 754, -357, 359, +-876, -78, -1155, -420, -1107, -578, -838, -516, +-481, -277, -94, 31, 287, 306, 553, 447, +671, 419, 686, 250, 632, -31, 506, -358, +321, -625, 156, -767, 68, -755, -59, -586, +-254, -236, -403, 219, -479, 647, -560, 998, +-623, 1196, -583, 1100, -449, 770, -269, 318, +5, -204, 346, -658, 681, -911, 952, -984, +1060, -909, 970, -713, 741, -463, 302, -252, +-313, -93, -845, 59, -1132, 246, -1227, 460, +-1106, 683, -695, 869, -128, 981, 334, 969, +633, 787, 795, 426, 783, -36, 598, -521, +342, -944, 141, -1229, 27, -1324, -88, -1191, +-193, -873, -254, -481, -307, -13, -341, 453, +-305, 779, -215, 979, -78, 1100, 61, 1118, +130, 1024, 116, 805, 83, 505, 40, 129, +-23, -341, -36, -822, 54, -1188, 152, -1396, +195, -1395, 177, -1167, 94, -756, -13, -239, +-89, 287, -105, 731, -40, 1065, 30, 1271, +77, 1316, 87, 1187, -17, 921, -241, 516, +-426, -20, -463, -574, -373, -984, -166, -1243, +198, -1287, 562, -1024, 727, -585, 723, -154, +581, 213, 249, 420, -156, 438, -477, 327, +-658, 171, -702, 87, -578, 152, -310, 337, +-45, 581, 141, 786, 321, 881, 456, 798, +461, 477, 357, -46, 220, -650, 60, -1225, +-114, -1668, -238, -1855, -284, -1646, -296, -1045, +-232, -214, -72, 701, 116, 1556, 256, 2107, +290, 2204, 208, 1846, 77, 1132, -81, 257, +-248, -583, -361, -1258, -344, -1593, -197, -1572, +-3, -1320, 173, -899, 338, -398, 426, 42, +377, 379, 223, 577, 57, 658, -97, 658, +-278, 576, -444, 446, -469, 352, -376, 293, +-231, 259, -29, 227, 225, 179, 485, 68, +670, -126, 675, -375, 499, -631, 201, -869, +-139, -994, -463, -948, -736, -735, -860, -384, +-762, 73, -521, 565, -218, 1026, 111, 1342, +431, 1439, 674, 1302, 800, 929, 830, 362, +758, -283, 546, -877, 199, -1267, -248, -1413, +-627, -1336, -820, -1021, -906, -564, -873, -127, +-596, 247, -195, 523, 137, 734, 390, 894, +603, 950, 654, 922, 508, 826, 350, 561, +240, 145, 60, -325, -158, -757, -295, -1049, +-293, -1122, -205, -944, -95, -525, 69, -34, +260, 368, 313, 625, 170, 686, -98, 530, +-375, 254, -603, -45, -735, -241, -635, -266, +-250, -174, 208, -21, 549, 184, 771, 346, +905, 370, 823, 257, 502, 90, 185, -101, +-12, -277, -246, -373, -517, -372, -693, -293, +-769, -171, -798, -111, -731, -78, -487, -32, +-78, -45, 370, -40, 725, 85, 902, 246, +920, 425, 751, 584, 378, 608, -2, 490, +-204, 260, -330, -82, -450, -404, -457, -612, +-335, -693, -253, -626, -245, -444, -156, -239, +11, -49, 101, 80, 127, 165, 121, 251, +33, 343, -116, 425, -219, 484, -195, 487, +-29, 403, 226, 176, 522, -131, 759, -384, +827, -543, 672, -583, 308, -441, -156, -157, +-578, 154, -900, 363, -1062, 429, -1033, 357, +-855, 139, -589, -163, -244, -405, 178, -531, +583, -511, 865, -343, 1070, -77, 1183, 216, +1082, 466, 758, 619, 324, 676, -138, 620, +-569, 464, -896, 264, -1044, 47, -1028, -187, +-880, -421, -639, -659, -357, -838, -46, -915, +272, -887, 518, -701, 685, -332, 771, 146, +782, 657, 691, 1057, 445, 1261, 123, 1254, +-101, 968, -236, 466, -340, -25, -388, -435, +-340, -704, -255, -770, -243, -692, -321, -538, +-400, -374, -420, -335, -366, -395, -252, -429, +-14, -384, 359, -251, 696, 32, 888, 475, +947, 958, 792, 1291, 420, 1389, -5, 1240, +-346, 817, -585, 155, -695, -553, -650, -1112, +-498, -1431, -336, -1495, -185, -1258, -89, -796, +-63, -272, -33, 210, 68, 571, 234, 745, +393, 803, 478, 769, 486, 644, 387, 509, +222, 377, 100, 195, 19, -12, -65, -221, +-86, -395, -50, -521, -97, -562, -304, -476, +-546, -310, -704, -157, -758, 8, -634, 139, +-266, 168, 221, 147, 681, 122, 1017, 71, +1134, 25, 974, -30, 565, -60, 46, -21, +-389, 41, -674, 118, -799, 278, -756, 433, +-566, 469, -302, 370, -51, 153, 145, -158, +290, -493, 358, -753, 368, -803, 341, -628, +284, -333, 207, -2, 82, 329, -108, 528, +-253, 505, -297, 376, -309, 259, -316, 108, +-209, -14, -1, -28, 166, 2, 273, 9, +357, 10, 333, 10, 207, 25, 75, 25, +-48, 2, -170, -39, -234, -153, -239, -327, +-236, -464, -218, -557, -126, -522, -31, -264, +15, 111, 87, 486, 205, 818, 268, 952, +253, 835, 197, 543, 123, 136, 14, -276, +-96, -554, -121, -683, -71, -673, -43, -547, +-55, -378, -99, -217, -157, -45, -228, 121, +-285, 255, -254, 368, -91, 465, 125, 475, +326, 386, 484, 223, 519, 17, 362, -179, +126, -322, -55, -399, -212, -363, -361, -242, +-392, -109, -313, 30, -215, 179, -134, 269, +-40, 296, 63, 279, 138, 207, 198, 83, +287, -62, 324, -217, 222, -350, 39, -437, +-85, -441, -146, -370, -198, -224, -177, 8, +-55, 276, 34, 506, 60, 688, 62, 749, +5, 636, -113, 382, -181, 41, -155, -313, +-68, -588, 30, -739, 142, -704, 224, -504, +233, -264, 202, -66, 165, 84, 69, 162, +-61, 176, -140, 158, -182, 178, -266, 271, +-329, 372, -274, 404, -117, 379, 59, 285, +218, 115, 339, -83, 397, -231, 337, -312, +158, -341, -18, -339, -94, -322, -152, -319, +-227, -299, -204, -240, -86, -140, -64, 8, +-156, 188, -204, 337, -139, 419, -45, 426, +54, 397, 196, 349, 358, 288, 419, 237, +313, 177, 112, 21, -71, -224, -225, -504, +-339, -755, -349, -888, -191, -809, 49, -511, +202, -56, 259, 411, 290, 766, 189, 932, +-74, 857, -319, 573, -443, 232, -509, -84, +-474, -343, -259, -496, 57, -525, 350, -496, +593, -432, 730, -307, 710, -69, 566, 222, +321, 481, 5, 666, -285, 718, -511, 543, +-675, 166, -740, -312, -682, -730, -534, -957, +-309, -925, -34, -645, 251, -175, 507, 341, +673, 747, 705, 936, 647, 891, 499, 644, +241, 280, -37, -114, -248, -440, -420, -607, +-521, -602, -503, -499, -393, -299, -237, -24, +-41, 192, 164, 274, 316, 276, 328, 178, +186, 5, -17, -146, -159, -226, -246, -200, +-275, -54, -146, 110, 147, 242, 414, 331, +540, 314, 527, 160, 364, -34, 57, -186, +-288, -268, -542, -266, -617, -160, -552, 14, +-408, 193, -209, 290, 15, 293, 218, 196, +374, -6, 469, -256, 533, -441, 565, -530, +478, -504, 200, -340, -173, -72, -525, 190, +-812, 386, -934, 491, -768, 494, -378, 423, +86, 334, 532, 265, 855, 233, 917, 186, +728, 75, 391, -132, 22, -420, -261, -716, +-390, -926, -427, -981, -423, -785, -372, -355, +-306, 150, -291, 595, -251, 930, -116, 1039, +73, 895, 269, 621, 463, 328, 592, 23, +575, -234, 399, -392, 142, -481, -125, -551, +-330, -572, -418, -494, -373, -302, -223, -66, +-35, 156, 88, 335, 130, 429, 92, 358, +-53, 159, -260, -38, -394, -148, -367, -175, +-205, -111, 19, 17, 318, 155, 641, 217, +822, 179, 778, 94, 585, 23, 283, -34, +-127, -55, -536, -54, -780, -61, -857, -97, +-815, -150, -640, -222, -359, -258, -51, -194, +233, -56, 442, 66, 568, 169, 611, 247, +558, 239, 428, 137, 294, 43, 165, 1, +18, -11, -98, 8, -124, 69, -153, 120, +-225, 131, -301, 92, -395, 26, -491, -66, +-511, -180, -471, -301, -377, -396, -176, -441, +127, -392, 420, -242, 631, -12, 772, 249, +832, 499, 746, 650, 521, 648, 235, 499, +-62, 260, -381, -13, -673, -235, -828, -360, +-825, -392, -735, -366, -540, -303, -246, -248, +44, -216, 257, -177, 419, -98, 525, 16, +555, 165, 498, 299, 404, 375, 327, 363, +257, 269, 145, 131, 21, 23, -82, -30, +-218, -26, -414, 10, -537, 59, -543, 50, +-519, -64, -473, -254, -327, -438, -91, -572, +160, -598, 368, -479, 532, -211, 618, 143, +603, 500, 527, 773, 414, 911, 240, 874, +18, 663, -192, 312, -337, -82, -450, -438, +-549, -707, -567, -848, -474, -813, -325, -634, +-145, -381, 41, -113, 204, 137, 288, 320, +283, 420, 249, 414, 235, 340, 219, 270, +191, 220, 188, 156, 238, 122, 257, 127, +160, 120, 4, 75, -132, 22, -267, -39, +-396, -102, -465, -163, -453, -225, -419, -280, +-368, -335, -260, -432, -105, -521, 56, -528, +233, -436, 436, -239, 651, 113, 782, 551, +756, 925, 570, 1134, 246, 1123, -154, 834, +-521, 338, -798, -221, -906, -664, -785, -853, +-471, -761, -78, -463, 297, -72, 573, 223, +665, 298, 529, 124, 257, -235, -39, -638, +-288, -895, -431, -898, -424, -615, -268, -106, +-22, 508, 208, 1048, 376, 1392, 452, 1477, +400, 1292, 255, 871, 91, 316, -85, -261, +-265, -775, -402, -1179, -458, -1392, -438, -1364, +-324, -1108, -128, -673, 87, -117, 292, 441, +473, 860, 533, 1045, 441, 982, 260, 683, +47, 233, -172, -238, -335, -573, -397, -668, +-368, -514, -307, -179, -225, 263, -121, 665, +9, 892, 149, 862, 265, 579, 345, 107, +428, -437, 446, -924, 316, -1213, 85, -1240, +-134, -996, -312, -546, -437, 20, -441, 574, +-301, 986, -147, 1153, -34, 1079, 67, 810, +124, 410, 90, -41, 31, -414, 21, -638, +53, -694, 67, -611, 71, -419, 80, -191, +88, -1, 88, 101, 110, 152, 170, 165, +243, 157, 259, 157, 173, 201, -14, 253, +-262, 269, -533, 218, -759, 99, -807, -76, +-593, -249, -236, -375, 155, -401, 562, -317, +889, -171, 970, -15, 803, 134, 510, 201, +155, 166, -248, 102, -576, 71, -696, 61, +-647, 90, -538, 152, -368, 194, -105, 166, +155, 82, 272, -41, 294, -159, 318, -228, +295, -218, 202, -145, 128, -50, 100, 8, +71, 4, -6, -65, -103, -145, -158, -183, +-179, -149, -213, -46, -214, 129, -128, 317, +3, 433, 85, 433, 128, 358, 127, 219, +52, 50, -43, -114, -104, -253, -143, -384, +-119, -497, -26, -587, 75, -610, 167, -526, +287, -300, 383, 65, 359, 535, 239, 979, +100, 1254, -97, 1262, -370, 975, -614, 416, +-701, -285, -618, -932, -413, -1347, -95, -1471, +305, -1282, 619, -830, 722, -264, 641, 229, +425, 561, 106, 712, -217, 703, -406, 595, +-384, 509, -226, 483, -45, 507, 103, 557, +195, 554, 181, 390, 56, 83, -98, -321, +-203, -768, -272, -1147, -281, -1317, -187, -1250, +-24, -968, 111, -529, 190, 3, 241, 509, +277, 887, 255, 1073, 154, 1107, 10, 1006, +-119, 769, -218, 447, -272, 129, -234, -176, +-94, -429, 59, -594, 174, -663, 258, -650, +280, -553, 205, -414, 56, -255, -100, -92, +-195, 43, -233, 137, -242, 242, -233, 339, +-185, 388, -93, 385, 9, 353, 87, 275, +180, 137, 278, -48, 319, -210, 264, -330, +144, -392, 8, -387, -133, -287, -265, -108, +-289, 119, -165, 321, -5, 468, 98, 533, +171, 465, 207, 209, 119, -138, -61, -456, +-180, -698, -219, -817, -241, -709, -209, -385, +-73, 38, 76, 439, 144, 754, 157, 892, +193, 822, 213, 596, 191, 305, 181, -16, +188, -319, 131, -559, -1, -700, -154, -772, +-302, -765, -452, -646, -534, -398, -488, -64, +-323, 308, -61, 641, 251, 862, 517, 893, +684, 743, 711, 476, 586, 169, 362, -99, +90, -256, -201, -305, -439, -260, -569, -198, +-598, -205, -558, -318, -458, -486, -318, -665, +-147, -786, 63, -761, 282, -533, 460, -121, +587, 424, 626, 975, 546, 1412, 360, 1617, +104, 1507, -168, 1091, -377, 462, -462, -281, +-400, -973, -250, -1461, -79, -1649, 70, -1519, +173, -1125, 173, -606, 41, -56, -147, 437, +-296, 771, -391, 906, -396, 909, -257, 785, +-7, 561, 274, 320, 516, 109, 666, -77, +720, -205, 636, -261, 362, -245, 0, -200, +-258, -164, -405, -154, -525, -156, -559, -186, +-454, -229, -356, -250, -353, -233, -343, -182, +-258, -84, -125, 47, 88, 209, 402, 374, +744, 510, 969, 589, 982, 583, 757, 429, +331, 123, -203, -279, -692, -664, -994, -935, +-1026, -984, -809, -763, -439, -300, -39, 283, +293, 824, 483, 1155, 525, 1197, 469, 915, +376, 390, 266, -201, 167, -696, 75, -1039, +-56, -1162, -217, -1036, -344, -713, -431, -302, +-450, 133, -336, 539, -113, 879, 114, 1085, +315, 1091, 464, 887, 473, 539, 328, 73, +135, -431, -70, -826, -262, -1008, -365, -1000, +-368, -807, -315, -457, -184, -38, 6, 315, +174, 534, 291, 614, 373, 589, 361, 449, +251, 245, 115, 54, -40, -88, -242, -185, +-380, -196, -377, -156, -287, -93, -168, -22, +-11, 21, 149, -4, 243, -38, 233, -85, +147, -175, 39, -244, -77, -212, -187, -142, +-203, -78, -80, 18, 86, 163, 205, 285, +318, 348, 407, 378, 370, 389, 198, 330, +-6, 207, -203, 60, -394, -91, -544, -265, +-584, -428, -524, -553, -412, -615, -238, -602, +17, -496, 301, -297, 548, 20, 704, 397, +743, 736, 662, 936, 471, 930, 164, 703, +-197, 312, -474, -175, -605, -591, -650, -796, +-589, -758, -391, -529, -141, -169, 73, 180, +247, 388, 379, 418, 442, 312, 395, 124, +247, -61, 58, -198, -112, -270, -286, -287, +-426, -258, -411, -219, -231, -159, -4, -36, +239, 178, 471, 425, 579, 646, 491, 760, +279, 691, 24, 412, -239, 6, -466, -444, +-582, -814, -544, -988, -390, -926, -220, -677, +-53, -299, 150, 101, 323, 434, 381, 658, +404, 757, 425, 701, 357, 543, 205, 317, +69, 37, -71, -247, -252, -443, -398, -528, +-452, -485, -460, -332, -407, -101, -256, 120, +-40, 252, 188, 253, 407, 172, 564, 39, +607, -101, 517, -190, 299, -196, -7, -154, +-299, -76, -510, 10, -614, 102, -565, 188, +-344, 263, -57, 330, 196, 383, 390, 343, +481, 186, 406, -48, 205, -287, -35, -499, +-257, -612, -402, -559, -398, -349, -262, -79, +-46, 170, 231, 341, 483, 405, 562, 342, +468, 199, 264, 42, -45, -69, -386, -148, +-582, -207, -585, -217, -462, -139, -232, -9, +67, 153, 289, 356, 389, 562, 393, 640, +295, 533, 147, 252, 59, -172, -9, -660, +-113, -1046, -191, -1214, -225, -1113, -279, -764, +-295, -238, -192, 336, -8, 839, 206, 1169, +420, 1272, 534, 1141, 490, 855, 307, 458, +11, -14, -315, -462, -521, -794, -577, -999, +-518, -1029, -337, -865, -70, -563, 156, -208, +305, 139, 391, 395, 384, 538, 293, 565, +193, 484, 70, 343, -102, 217, -265, 96, +-347, -18, -333, -107, -216, -153, -12, -147, +225, -80, 419, 6, 516, 95, 455, 148, +213, 113, -148, -43, -503, -259, -748, -474, +-807, -609, -644, -594, -293, -384, 139, -24, +550, 389, 854, 717, 967, 896, 833, 871, +486, 629, 31, 244, -386, -153, -684, -488, +-840, -678, -808, -693, -563, -557, -229, -327, +80, -66, 349, 137, 538, 262, 562, 290, +484, 220, 403, 94, 288, 5, 92, -33, +-129, -31, -343, -3, -529, 62, -634, 111, +-620, 87, -465, 26, -137, 9, 290, 11, +652, 25, 851, 81, 848, 151, 576, 130, +104, 2, -365, -189, -705, -380, -870, -517, +-780, -516, -443, -347, 0, -41, 393, 296, +639, 555, 679, 657, 535, 581, 266, 350, +-62, 56, -335, -221, -458, -399, -463, -448, +-376, -377, -166, -240, 86, -70, 241, 97, +317, 231, 356, 296, 305, 311, 158, 271, +13, 162, -126, -16, -287, -186, -374, -326, +-344, -434, -289, -446, -198, -333, -8, -175, +207, 10, 351, 204, 450, 360, 497, 444, +410, 466, 208, 416, -14, 308, -232, 156, +-412, -12, -489, -177, -465, -293, -365, -342, +-188, -311, 12, -229, 161, -132, 261, -81, +320, -92, 300, -150, 221, -218, 140, -265, +49, -209, -50, -34, -96, 214, -98, 474, +-84, 695, -25, 774, 52, 680, 56, 452, +12, 134, -17, -234, -73, -543, -179, -735, +-232, -796, -203, -711, -143, -477, -48, -176, +93, 133, 205, 388, 263, 548, 285, 563, +271, 431, 208, 204, 96, -28, -59, -224, +-224, -335, -350, -333, -401, -225, -381, -66, +-269, 94, -61, 214, 194, 306, 431, 342, +585, 302, 577, 208, 392, 94, 103, -67, +-208, -251, -491, -410, -665, -491, -665, -467, +-504, -345, -246, -177, 61, 29, 353, 223, +553, 351, 604, 398, 527, 402, 386, 371, +205, 297, -36, 172, -271, 26, -405, -164, +-442, -391, -429, -580, -328, -625, -141, -508, +42, -239, 191, 126, 313, 491, 349, 717, +282, 728, 168, 511, 32, 160, -101, -193, +-163, -445, -167, -528, -155, -395, -111, -153, +-16, 45, 65, 131, 89, 112, 75, -13, +45, -192, 3, -324, -38, -298, -80, -120, +-107, 126, -104, 364, -64, 548, 15, 595, +132, 498, 240, 286, 304, 23, 295, -219, +206, -393, 48, -497, -135, -483, -318, -379, +-467, -235, -517, -87, -416, 55, -234, 144, +-56, 179, 132, 160, 329, 114, 448, 94, +467, 126, 465, 166, 444, 220, 297, 258, +63, 218, -145, 80, -352, -100, -579, -299, +-692, -462, -613, -517, -417, -415, -164, -207, +151, 33, 438, 245, 574, 398, 560, 435, +456, 367, 288, 248, 94, 124, -81, 9, +-189, -58, -228, -105, -251, -167, -279, -247, +-272, -328, -227, -403, -172, -408, -97, -318, +18, -145, 127, 96, 211, 363, 267, 571, +269, 682, 230, 648, 205, 480, 147, 229, +21, -41, -92, -303, -151, -512, -219, -632, +-279, -635, -243, -543, -130, -388, -37, -190, +46, 32, 132, 229, 156, 397, 89, 507, +-4, 527, -61, 459, -67, 338, -40, 167, +15, -24, 77, -192, 105, -292, 78, -326, +35, -292, 14, -193, 17, -53, 42, 51, +115, 86, 192, 66, 191, 14, 88, -93, +-73, -212, -264, -282, -446, -253, -553, -140, +-527, 25, -380, 209, -148, 400, 131, 520, +403, 541, 607, 471, 709, 310, 691, 68, +554, -172, 319, -384, 12, -546, -328, -619, +-616, -590, -784, -478, -815, -266, -694, -9, +-405, 231, -23, 441, 347, 600, 654, 639, +826, 547, 783, 343, 554, 75, 203, -223, +-192, -492, -538, -654, -747, -639, -770, -483, +-578, -234, -221, 73, 179, 390, 513, 617, +719, 683, 709, 582, 481, 393, 151, 132, +-189, -189, -496, -478, -649, -641, -581, -695, +-364, -615, -81, -385, 226, -61, 471, 267, +586, 548, 563, 687, 399, 635, 97, 404, +-236, 63, -500, -295, -672, -522, -713, -545, +-556, -365, -243, -55, 122, 280, 462, 505, +711, 525, 768, 312, 615, -40, 346, -396, +53, -627, -210, -655, -380, -457, -445, -110, +-414, 272, -311, 554, -197, 691, -124, 660, +-67, 465, 7, 175, 81, -90, 154, -319, +245, -511, 289, -624, 229, -638, 114, -583, +-12, -431, -151, -176, -264, 146, -301, 466, +-236, 729, -88, 874, 85, 861, 228, 665, +341, 342, 404, -41, 376, -411, 246, -683, +60, -792, -167, -772, -409, -628, -592, -373, +-661, -82, -594, 163, -386, 345, -89, 432, +237, 430, 536, 362, 732, 250, 741, 125, +574, 44, 318, -3, 17, -28, -302, -31, +-538, -27, -618, -44, -547, -64, -377, -88, +-130, -114, 156, -145, 392, -167, 497, -187, +458, -190, 292, -162, 51, -71, -203, 58, +-398, 203, -464, 351, -364, 458, -172, 434, +31, 288, 225, 56, 359, -211, 336, -446, +173, -569, -11, -550, -146, -385, -233, -126, +-230, 150, -121, 388, 46, 548, 205, 569, +301, 471, 304, 293, 222, 48, 52, -234, +-164, -460, -323, -577, -370, -561, -361, -408, +-292, -127, -114, 193, 95, 456, 199, 572, +214, 497, 176, 244, 77, -88, -32, -408, +-67, -606, -25, -581, 68, -332, 178, 15, +269, 366, 291, 630, 211, 721, 14, 596, +-221, 320, -384, -28, -443, -346, -413, -571, +-268, -653, -60, -573, 113, -356, 224, -92, +280, 173, 240, 381, 122, 463, -1, 383, +-76, 186, -100, -72, -59, -305, 11, -442, +64, -410, 112, -188, 166, 156, 147, 487, +40, 723, -61, 769, -123, 564, -201, 163, +-259, -301, -217, -706, -109, -930, -29, -919, +46, -687, 136, -289, 184, 157, 155, 486, +94, 646, 25, 646, -29, 505, -60, 272, +-74, 60, -48, -69, 22, -98, 69, -70, +63, -34, 52, -36, 23, -105, -72, -255, +-156, -423, -181, -527, -191, -492, -157, -310, +-31, -8, 105, 354, 195, 687, 266, 863, +287, 828, 198, 606, 67, 257, -38, -143, +-144, -466, -224, -659, -217, -721, -178, -663, +-149, -526, -116, -384, -95, -236, -108, -71, +-112, 117, -68, 328, 27, 571, 171, 788, +358, 897, 512, 843, 559, 623, 469, 238, +236, -231, -102, -669, -444, -986, -714, -1119, +-838, -1007, -748, -690, -452, -248, -59, 229, +324, 634, 605, 875, 702, 929, 585, 778, +314, 460, -16, 77, -285, -270, -421, -515, +-405, -593, -249, -508, 6, -309, 242, -71, +357, 125, 333, 210, 215, 182, 36, 68, +-166, -70, -324, -162, -368, -159, -324, -68, +-246, 103, -145, 301, -18, 456, 79, 509, +128, 452, 185, 287, 269, 34, 322, -279, +309, -568, 236, -769, 117, -861, -37, -822, +-216, -591, -369, -214, -404, 210, -334, 612, +-222, 934, -82, 1077, 83, 1012, 189, 748, +195, 353, 164, -81, 148, -459, 129, -721, +108, -821, 85, -757, 47, -558, -24, -307, +-146, -61, -287, 141, -364, 263, -352, 272, +-247, 212, -37, 145, 215, 98, 401, 80, +488, 124, 452, 215, 275, 299, 9, 321, +-235, 266, -411, 117, -486, -104, -423, -342, +-259, -516, -64, -589, 132, -550, 270, -407, +316, -170, 288, 98, 200, 320, 59, 457, +-64, 524, -135, 506, -174, 406, -180, 252, +-122, 89, -29, -72, 50, -199, 97, -282, +108, -334, 76, -360, 18, -357, -57, -363, +-136, -356, -198, -296, -220, -171, -196, 11, +-119, 268, 26, 560, 231, 809, 405, 926, +484, 853, 480, 578, 376, 158, 117, -338, +-231, -800, -532, -1104, -723, -1169, -787, -1002, +-662, -644, -369, -184, -9, 282, 331, 655, +588, 882, 695, 944, 663, 842, 525, 600, +315, 294, 86, -20, -115, -293, -298, -489, +-442, -578, -501, -566, -480, -459, -411, -298, +-271, -131, -79, 17, 96, 135, 227, 189, +310, 194, 305, 175, 213, 132, 88, 58, +-6, -6, -51, -28, -27, 10, 42, 100, +112, 233, 153, 366, 148, 450, 59, 406, +-101, 199, -281, -153, -425, -566, -495, -932, +-468, -1126, -327, -1059, -78, -705, 202, -145, +437, 496, 593, 1056, 650, 1388, 557, 1403, +321, 1122, 28, 615, -248, 15, -494, -544, +-651, -950, -654, -1157, -512, -1144, -294, -936, +-38, -590, 229, -196, 454, 191, 548, 523, +491, 756, 327, 848, 107, 799, -129, 614, +-298, 349, -343, 77, -279, -164, -156, -357, +2, -454, 137, -466, 177, -447, 107, -414, +-16, -355, -138, -278, -197, -166, -167, -4, +-71, 208, 23, 431, 82, 614, 97, 684, +57, 617, -31, 418, -96, 114, -87, -237, +0, -519, 140, -665, 291, -657, 374, -514, +329, -268, 155, 3, -91, 215, -367, 327, +-597, 348, -717, 280, -675, 167, -461, 70, +-115, 37, 268, 48, 611, 92, 842, 130, +889, 129, 716, 67, 370, -63, -72, -242, +-514, -398, -821, -484, -893, -463, -747, -332, +-429, -113, -20, 148, 353, 395, 581, 560, +627, 616, 482, 565, 199, 418, -100, 183, +-308, -86, -411, -335, -382, -533, -216, -668, +8, -683, 190, -552, 301, -298, 322, 28, +216, 371, 7, 639, -202, 759, -347, 700, +-400, 465, -344, 104, -169, -257, 75, -523, +303, -624, 434, -546, 425, -322, 286, -31, +74, 240, -157, 415, -335, 453, -404, 354, +-363, 164, -259, -71, -124, -285, 3, -437, +92, -488, 146, -425, 195, -256, 227, -11, +247, 282, 266, 547, 241, 712, 118, 726, +-63, 575, -247, 276, -406, -106, -512, -494, +-486, -780, -324, -888, -106, -801, 104, -563, +281, -216, 391, 154, 410, 469, 338, 680, +221, 760, 83, 697, -46, 515, -136, 240, +-185, -74, -217, -372, -235, -587, -233, -671, +-207, -598, -165, -371, -100, -33, -29, 307, +32, 556, 87, 639, 135, 520, 169, 225, +192, -136, 188, -450, 157, -626, 119, -603, +86, -374, 18, -39, -93, 289, -199, 510, +-281, 562, -351, 435, -363, 189, -287, -91, +-146, -312, 18, -406, 189, -358, 332, -209, +388, -12, 334, 167, 217, 283, 69, 310, +-66, 257, -144, 145, -166, 5, -166, -140, +-152, -265, -132, -359, -133, -391, -140, -346, +-107, -232, -48, -51, 23, 188, 115, 412, +187, 561, 183, 597, 112, 493, 8, 261, +-101, -31, -169, -316, -148, -527, -71, -613, +33, -551, 129, -384, 152, -159, 86, 74, +-15, 276, -118, 398, -189, 433, -193, 396, +-116, 308, -3, 169, 111, 5, 194, -154, +191, -267, 95, -318, -47, -303, -201, -220, +-328, -81, -379, 58, -298, 142, -117, 145, +109, 85, 350, -22, 544, -123, 592, -176, +468, -150, 217, -36, -105, 137, -437, 297, +-662, 402, -708, 429, -584, 353, -338, 175, +-46, -54, 195, -280, 354, -460, 406, -568, +356, -565, 263, -459, 190, -285, 131, -65, +80, 178, 46, 374, -8, 497, -132, 548, +-272, 522, -381, 414, -438, 256, -408, 66, +-284, -123, -111, -286, 77, -418, 241, -495, +344, -484, 362, -399, 320, -255, 229, -71, +117, 129, 10, 291, -73, 384, -137, 399, +-199, 355, -242, 269, -227, 171, -191, 72, +-167, -12, -129, -92, -64, -180, -9, -281, +22, -380, 53, -449, 85, -447, 94, -353, +104, -151, 142, 124, 209, 409, 258, 642, +242, 768, 173, 727, 66, 525, -109, 213, +-333, -149, -524, -491, -619, -730, -608, -828, +-472, -763, -206, -561, 128, -276, 428, 39, +622, 333, 687, 537, 637, 622, 462, 601, +196, 509, -76, 364, -309, 196, -493, 43, +-590, -91, -578, -221, -468, -337, -284, -438, +-62, -512, 133, -531, 287, -463, 385, -312, +365, -88, 241, 174, 110, 422, -6, 588, +-108, 650, -163, 602, -138, 458, -88, 244, +-60, 10, -32, -205, 8, -371, 26, -488, +22, -550, 15, -551, 14, -476, -20, -332, +-91, -123, -163, 115, -210, 348, -207, 539, +-127, 639, 8, 610, 157, 472, 263, 253, +296, 5, 235, -230, 111, -406, -35, -478, +-176, -441, -253, -348, -239, -221, -189, -77, +-108, 46, -11, 111, 53, 129, 68, 123, +81, 108, 87, 86, 56, 79, 13, 98, +-9, 137, -53, 172, -104, 194, -126, 188, +-110, 139, -53, 38, 31, -97, 98, -241, +117, -366, 72, -451, -8, -453, -98, -361, +-160, -184, -169, 41, -124, 282, -31, 492, +84, 616, 190, 610, 249, 478, 214, 242, +108, -44, -37, -328, -184, -559, -296, -675, +-350, -637, -340, -478, -253, -229, -109, 72, +58, 365, 208, 568, 326, 632, 366, 550, +321, 356, 239, 91, 118, -171, -53, -358, +-212, -417, -321, -345, -391, -191, -428, -21, +-380, 117, -233, 163, -34, 98, 176, -30, +377, -162, 521, -253, 549, -247, 422, -142, +187, 22, -100, 196, -384, 338, -600, 401, +-688, 377, -613, 276, -399, 137, -122, -11, +168, -144, 428, -248, 603, -313, 626, -329, +504, -295, 305, -218, 62, -96, -202, 52, +-412, 181, -516, 252, -488, 256, -354, 188, +-161, 60, 36, -93, 173, -202, 194, -228, +109, -169, -13, -45, -106, 108, -170, 243, +-169, 322, -67, 306, 95, 202, 250, 58, +366, -90, 412, -220, 360, -287, 211, -277, +18, -218, -189, -140, -389, -55, -545, 16, +-607, 55, -555, 62, -401, 64, -168, 69, +112, 69, 354, 73, 507, 91, 535, 103, +433, 102, 244, 87, 40, 69, -135, 47, +-248, 15, -274, -32, -216, -86, -126, -142, +-19, -188, 66, -213, 87, -193, 57, -123, +0, -16, -93, 94, -191, 186, -263, 228, +-284, 204, -245, 123, -123, 19, 64, -71, +250, -105, 386, -82, 446, -20, 395, 45, +235, 82, 6, 59, -206, -21, -350, -121, +-411, -197, -375, -216, -256, -153, -122, -38, +-6, 89, 78, 198, 131, 261, 139, 252, +124, 194, 102, 112, 73, 35, 52, -31, +32, -105, -10, -192, -37, -265, -48, -321, +-65, -342, -93, -291, -109, -131, -113, 105, +-112, 347, -89, 530, -50, 602, -17, 514, +29, 272, 59, -58, 61, -374, 50, -588, +28, -636, -4, -513, -19, -247, 17, 77, +88, 355, 124, 505, 109, 499, 53, 359, +-33, 139, -145, -104, -246, -290, -294, -366, +-295, -326, -260, -210, -156, -63, -19, 71, +99, 167, 185, 196, 245, 165, 280, 110, +290, 53, 267, 1, 193, -24, 62, -31, +-81, -33, -234, -44, -365, -54, -426, -66, +-412, -79, -317, -82, -142, -52, 60, -5, +244, 45, 362, 95, 387, 140, 301, 154, +123, 128, -100, 55, -310, -37, -435, -138, +-418, -225, -274, -260, -34, -213, 234, -95, +442, 68, 504, 218, 407, 311, 202, 320, +-60, 236, -332, 73, -497, -99, -497, -223, +-374, -264, -206, -217, -13, -97, 158, 33, +222, 118, 175, 136, 100, 97, 42, 13, +15, -86, 5, -155, 31, -162, 77, -125, +97, -78, 68, -24, 14, 69, -44, 167, +-119, 244, -194, 326, -203, 396, -154, 377, +-85, 237, -10, -3, 58, -293, 95, -580, +86, -776, 32, -796, -42, -603, -110, -251, +-142, 167, -134, 539, -84, 775, 5, 823, +102, 682, 178, 410, 218, 117, 197, -125, +141, -278, 60, -340, -35, -333, -124, -304, +-205, -285, -292, -293, -361, -303, -368, -281, +-290, -198, -150, -47, 47, 155, 255, 364, +411, 523, 475, 577, 432, 517, 278, 342, +42, 91, -208, -164, -374, -355, -419, -457, +-360, -447, -223, -330, -45, -142, 102, 47, +169, 180, 171, 234, 124, 214, 18, 114, +-94, -30, -162, -163, -176, -236, -144, -241, +-75, -177, 24, -53, 147, 114, 254, 270, +305, 366, 287, 384, 213, 332, 52, 214, +-169, 48, -361, -126, -483, -258, -530, -332, +-458, -342, -272, -296, -20, -215, 227, -128, +426, -55, 524, -10, 488, 20, 335, 43, +122, 67, -97, 106, -256, 174, -329, 244, +-307, 300, -217, 332, -89, 334, 25, 281, +64, 164, 15, -1, -75, -189, -181, -393, +-247, -578, -209, -690, -54, -677, 146, -540, +320, -299, 438, 16, 467, 363, 362, 655, +143, 818, -117, 831, -327, 718, -457, 485, +-505, 171, -452, -152, -311, -427, -161, -638, +-48, -756, 63, -752, 196, -619, 294, -383, +357, -76, 410, 243, 429, 514, 364, 670, +198, 670, -31, 514, -268, 258, -484, -20, +-625, -234, -655, -338, -556, -328, -356, -240, +-105, -123, 152, -39, 372, -18, 516, -53, +564, -96, 503, -91, 381, -11, 227, 115, +39, 245, -146, 325, -281, 318, -363, 201, +-398, 7, -388, -181, -331, -295, -252, -329, +-160, -284, -67, -173, 30, -43, 138, 41, +236, 76, 297, 88, 340, 109, 338, 139, +266, 181, 137, 218, -7, 233, -147, 186, +-273, 72, -357, -72, -361, -208, -290, -317, +-175, -352, -56, -309, 68, -216, 161, -101, +186, 28, 176, 144, 155, 231, 102, 280, +33, 292, -34, 255, -95, 173, -149, 55, +-171, -67, -164, -165, -137, -214, -77, -211, +3, -168, 72, -115, 137, -64, 175, -39, +169, -37, 125, -26, 63, 32, 2, 131, +-45, 242, -84, 330, -126, 358, -174, 267, +-214, 61, -252, -197, -254, -424, -182, -555, +-61, -542, 77, -375, 222, -102, 341, 189, +386, 413, 319, 511, 170, 477, -12, 332, +-177, 130, -272, -63, -265, -192, -185, -240, +-93, -204, -26, -117, 8, -28, -26, 19, +-109, 19, -170, -39, -171, -136, -105, -222, +40, -244, 228, -184, 371, -38, 411, 157, +361, 343, 223, 454, 17, 453, -219, 322, +-417, 95, -515, -151, -506, -328, -420, -408, +-242, -380, -1, -250, 226, -70, 388, 78, +490, 154, 508, 168, 405, 149, 197, 103, +-41, 51, -257, 19, -400, 10, -451, -15, +-399, -53, -269, -90, -111, -115, 31, -126, +135, -101, 184, -40, 186, 39, 158, 111, +114, 175, 60, 217, 20, 226, -15, 198, +-59, 136, -101, 26, -119, -130, -120, -309, +-90, -452, -34, -513, 25, -442, 70, -237, +99, 72, 97, 406, 69, 668, 35, 760, +-7, 646, -65, 349, -126, -51, -183, -450, +-220, -736, -217, -823, -167, -685, -60, -382, +102, 3, 254, 379, 344, 658, 351, 761, +266, 675, 81, 439, -139, 120, -309, -216, +-370, -482, -305, -620, -134, -603, 76, -461, +251, -234, 299, 14, 197, 213, 1, 324, +-219, 364, -403, 340, -467, 281, -359, 212, +-118, 144, 162, 61, 406, -48, 539, -183, +512, -311, 344, -392, 109, -395, -125, -304, +-300, -121, -387, 103, -366, 286, -265, 365, +-148, 340, -77, 229, -44, 76, -25, -67, +-6, -141, 33, -133, 115, -61, 213, 19, +286, 74, 299, 87, 251, 51, 140, -35, +-35, -138, -241, -220, -398, -265, -464, -278, +-428, -236, -300, -128, -100, 37, 121, 222, +321, 397, 461, 522, 498, 553, 420, 458, +244, 256, -12, -12, -275, -284, -454, -496, +-505, -596, -442, -578, -276, -464, -34, -293, +202, -92, 327, 99, 330, 251, 241, 357, +98, 427, -67, 437, -172, 378, -156, 257, +-55, 104, 44, -61, 120, -200, 154, -287, +109, -295, -25, -239, -168, -154, -250, -87, +-259, -42, -208, -25, -89, -28, 80, -36, +229, -12, 296, 47, 293, 120, 223, 183, +80, 220, -99, 218, -245, 177, -330, 96, +-338, -4, -261, -106, -104, -199, 71, -277, +203, -307, 249, -282, 218, -202, 132, -74, +22, 95, -71, 259, -94, 363, -48, 375, +35, 313, 104, 182, 123, 13, 71, -147, +-46, -247, -197, -288, -309, -282, -319, -242, +-242, -180, -127, -119, 22, -60, 178, 3, +269, 84, 267, 181, 232, 272, 193, 331, +138, 349, 64, 314, 5, 213, -47, 44, +-123, -158, -234, -353, -320, -503, -336, -583, +-285, -550, -171, -385, 25, -113, 244, 209, +404, 510, 456, 702, 401, 729, 240, 573, +11, 283, -236, -67, -427, -380, -498, -582, +-415, -629, -216, -530, 46, -328, 294, -95, +451, 115, 467, 254, 340, 320, 112, 323, +-129, 274, -319, 179, -401, 59, -337, -63, +-145, -151, 77, -194, 252, -177, 330, -94, +281, 30, 112, 133, -103, 168, -298, 113, +-397, -12, -360, -172, -199, -298, 37, -325, +294, -225, 476, -40, 507, 171, 390, 336, +170, 390, -118, 304, -385, 118, -536, -100, +-525, -275, -379, -359, -142, -319, 121, -180, +341, 5, 437, 176, 396, 299, 253, 340, +72, 295, -96, 176, -197, 17, -212, -155, +-157, -301, -72, -396, 13, -415, 56, -350, +45, -198, -17, -10, -100, 162, -159, 286, +-147, 352, -71, 344, 40, 277, 159, 180, +270, 96, 336, 29, 330, -27, 236, -92, +80, -168, -96, -263, -257, -349, -364, -393, +-360, -369, -265, -269, -135, -92, 6, 119, +142, 318, 206, 460, 187, 510, 134, 441, +91, 279, 65, 69, 74, -140, 104, -321, +128, -438, 108, -469, 29, -403, -91, -268, +-201, -93, -268, 90, -254, 263, -147, 389, +15, 447, 163, 415, 259, 292, 261, 90, +164, -144, 16, -369, -123, -533, -224, -588, +-246, -491, -175, -258, -50, 54, 65, 358, +150, 572, 193, 613, 191, 469, 151, 197, +103, -104, 71, -350, 46, -458, -1, -400, +-51, -213, -111, -3, -195, 136, -279, 147, +-300, 46, -247, -108, -136, -224, 22, -233, +209, -103, 359, 121, 430, 356, 415, 495, +323, 472, 162, 285, -33, 3, -210, -282, +-307, -475, -326, -523, -289, -425, -203, -251, +-78, -67, 23, 58, 89, 100, 142, 74, +184, 38, 203, 34, 208, 101, 203, 221, +177, 353, 104, 427, 1, 392, -93, 232, +-174, -20, -237, -319, -231, -583, -137, -726, +2, -697, 127, -516, 224, -221, 266, 116, +240, 413, 156, 590, 42, 619, -79, 492, +-173, 255, -220, -15, -207, -242, -141, -374, +-28, -386, 92, -298, 187, -134, 245, 45, +272, 186, 248, 244, 160, 208, 31, 93, +-91, -70, -193, -240, -270, -360, -290, -400, +-227, -342, -117, -191, 9, 24, 139, 249, +253, 429, 295, 506, 259, 471, 176, 336, +74, 140, -39, -87, -130, -291, -154, -430, +-115, -484, -61, -476, 6, -417, 70, -312, +91, -162, 55, 15, -6, 212, -74, 396, +-113, 530, -95, 563, -24, 475, 65, 275, +171, 4, 258, -276, 282, -484, 238, -572, +157, -516, 50, -353, -68, -139, -173, 55, +-222, 185, -215, 230, -176, 200, -124, 120, +-36, 40, 73, -20, 161, -45, 213, -36, +244, -3, 233, 38, 180, 81, 110, 112, +65, 108, 46, 48, 41, -47, 33, -163, +28, -273, 14, -348, -32, -344, -109, -252, +-174, -88, -230, 93, -269, 241, -244, 307, +-144, 283, -8, 180, 156, 54, 333, -45, +489, -85, 577, -72, 585, -27, 494, 2, +316, -9, 58, -75, -255, -174, -556, -264, +-751, -297, -822, -263, -746, -165, -499, -33, +-118, 100, 290, 200, 646, 263, 874, 274, +920, 245, 767, 184, 475, 101, 121, -5, +-202, -124, -431, -251, -525, -345, -494, -376, +-365, -330, -199, -223, -49, -66, 49, 94, +94, 215, 107, 253, 114, 213, 119, 116, +154, -9, 214, -126, 254, -182, 257, -169, +251, -100, 209, -2, 124, 109, 22, 192, +-63, 224, -138, 175, -197, 51, -230, -126, +-234, -301, -206, -435, -120, -481, 16, -420, +181, -254, 322, -28, 403, 203, 406, 367, +320, 434, 167, 396, 24, 281, -72, 131, +-114, -1, -112, -98, -53, -158, 16, -198, +33, -234, -20, -285, -84, -324, -127, -336, +-125, -293, -49, -183, 107, -3, 273, 190, +379, 335, 395, 388, 305, 344, 112, 202, +-104, -1, -265, -207, -327, -335, -280, -359, +-114, -273, 106, -111, 282, 79, 356, 225, +313, 288, 167, 246, -26, 106, -201, -96, +-281, -285, -241, -408, -108, -426, 54, -339, +210, -174, 312, 8, 317, 159, 224, 232, +91, 225, -34, 152, -103, 66, -109, 2, +-53, -8, 40, 19, 129, 65, 166, 88, +142, 65, 56, -16, -59, -125, -152, -240, +-180, -330, -143, -376, -33, -355, 118, -285, +260, -185, 359, -71, 417, 64, 390, 196, +282, 312, 143, 382, 3, 398, -143, 346, +-246, 235, -276, 72, -247, -108, -184, -275, +-85, -392, 32, -461, 145, -475, 223, -441, +274, -363, 323, -252, 370, -100, 369, 83, +331, 281, 266, 440, 147, 513, -42, 471, +-232, 317, -368, 72, -426, -187, -389, -383, +-241, -455, -37, -400, 166, -245, 327, -70, +434, 52, 458, 81, 393, 28, 276, -81, +152, -182, 26, -216, -75, -154, -131, -26, +-151, 124, -163, 238, -143, 283, -88, 233, +-24, 110, 44, -50, 124, -202, 168, -320, +171, -379, 163, -375, 152, -297, 113, -163, +77, 13, 64, 200, 51, 364, 16, 455, +-21, 439, -44, 285, -40, 26, -12, -277, +62, -547, 172, -723, 269, -746, 300, -607, +253, -327, 135, 12, -26, 334, -185, 564, +-263, 671, -227, 638, -99, 493, 79, 266, +273, 5, 416, -250, 444, -450, 343, -586, +181, -635, 5, -594, -136, -467, -207, -288, +-180, -81, -58, 114, 112, 272, 253, 363, +338, 378, 353, 327, 278, 241, 113, 132, +-60, 26, -174, -66, -216, -130, -193, -168, +-111, -190, 11, -221, 147, -254, 255, -280, +321, -289, 335, -279, 304, -225, 234, -129, +148, 0, 59, 124, -22, 222, -85, 264, +-117, 247, -134, 179, -127, 95, -88, 9, +-24, -56, 44, -101, 113, -130, 160, -171, +189, -220, 208, -275, 205, -311, 160, -307, +125, -233, 116, -95, 89, 73, 42, 216, +31, 294, 38, 273, 23, 164, -12, -6, +-20, -185, -11, -313, -11, -340, -29, -268, +-23, -125, 19, 23, 80, 142, 153, 199, +259, 186, 342, 108, 360, 3, 320, -103, +235, -183, 98, -232, -49, -239, -155, -226, +-199, -208, -186, -188, -108, -154, 1, -109, +108, -43, 184, 31, 246, 115, 291, 192, +300, 249, 264, 256, 223, 212, 179, 106, +128, -30, 86, -165, 65, -275, 32, -353, +-20, -372, -63, -341, -93, -282, -137, -220, +-153, -159, -107, -106, -7, -40, 137, 48, +323, 164, 494, 285, 593, 383, 584, 412, +462, 346, 225, 171, -66, -75, -331, -343, +-498, -564, -533, -678, -426, -633, -200, -456, +92, -195, 348, 84, 507, 319, 536, 441, +435, 430, 239, 294, 20, 85, -146, -140, +-207, -321, -158, -423, -10, -415, 186, -311, +367, -132, 451, 73, 409, 244, 240, 322, +-9, 302, -248, 192, -381, 22, -400, -173, +-300, -333, -103, -432, 130, -449, 301, -395, +385, -284, 391, -149, 348, 4, 288, 148, +254, 273, 243, 357, 244, 386, 214, 329, +139, 190, 27, -16, -99, -240, -211, -441, +-265, -565, -242, -576, -144, -454, -2, -247, +156, -15, 276, 178, 341, 296, 357, 310, +342, 241, 315, 119, 282, -10, 228, -111, +180, -155, 120, -156, 23, -132, -83, -117, +-137, -112, -142, -114, -110, -111, -26, -114, +87, -108, 167, -93, 218, -83, 234, -84, +192, -73, 118, -60, 79, -37, 90, 7, +136, 80, 182, 158, 206, 203, 186, 178, +116, 77, 0, -94, -101, -288, -152, -465, +-156, -568, -106, -554, 24, -403, 186, -156, +322, 127, 386, 371, 368, 531, 272, 559, +137, 460, -7, 258, -117, 6, -158, -253, +-125, -462, -52, -594, 44, -637, 131, -604, +192, -493, 223, -311, 225, -79, 192, 161, +154, 376, 113, 519, 73, 562, 36, 492, +25, 333, 29, 100, 60, -150, 118, -362, +167, -485, 191, -520, 217, -477, 210, -385, +161, -268, 104, -163, 73, -77, 42, -28, +-6, 0, -40, 26, -30, 67, 2, 122, +54, 201, 135, 282, 264, 352, 391, 382, +453, 341, 426, 191, 314, -57, 120, -380, +-120, -707, -336, -958, -426, -1051, -364, -945, +-182, -626, 91, -150, 416, 384, 674, 844, +755, 1118, 649, 1136, 421, 910, 104, 493, +-217, -12, -435, -493, -497, -846, -431, -1018, +-267, -987, -40, -803, 194, -524, 364, -210, +448, 91, 452, 325, 387, 476, 269, 531, +154, 494, 76, 375, 44, 209, 51, 11, +83, -177, 93, -326, 57, -402, -37, -404, +-158, -333, -263, -226, -301, -117, -244, -35, +-70, 11, 191, 16, 457, -7, 631, -49, +684, -72, 589, -59, 376, -12, 122, 41, +-114, 80, -275, 88, -290, 70, -196, 23, +-71, -43, 51, -126, 165, -196, 199, -247, +135, -268, 69, -271, 57, -249, 73, -194, +125, -94, 228, 37, 358, 186, 433, 316, +417, 387, 330, 358, 197, 226, 32, -8, +-115, -293, -208, -558, -242, -725, -221, -745, +-129, -595, 10, -316, 152, 20, 277, 334, +372, 569, 407, 669, 391, 618, 329, 431, +247, 171, 158, -105, 77, -346, 2, -530, +-59, -625, -96, -628, -111, -539, -115, -385, +-91, -192, -48, -3, 24, 160, 118, 271, +212, 320, 290, 303, 357, 241, 368, 147, +294, 49, 178, -38, 71, -101, -48, -148, +-137, -182, -135, -208, -52, -205, 62, -190, +177, -176, 257, -170, 259, -168, 155, -185, +6, -206, -121, -223, -180, -207, -158, -143, +-38, -6, 164, 184, 366, 385, 485, 528, +513, 573, 440, 479, 273, 244, 51, -103, +-144, -477, -244, -795, -237, -967, -160, -949, +-26, -728, 136, -372, 267, 36, 311, 411, +289, 680, 235, 778, 161, 706, 87, 492, +61, 203, 74, -103, 102, -355, 117, -525, +120, -601, 105, -586, 74, -476, 47, -314, +52, -135, 100, 31, 195, 173, 302, 266, +380, 293, 381, 239, 286, 128, 92, -13, +-155, -142, -369, -235, -474, -262, -442, -223, +-251, -123, 51, 1, 381, 106, 643, 146, +776, 108, 743, -8, 564, -159, 297, -299, +18, -383, -214, -395, -339, -314, -377, -158, +-344, 51, -257, 246, -145, 378, -25, 416, +112, 352, 244, 191, 336, -23, 388, -257, +427, -457, 406, -577, 307, -577, 181, -468, +61, -277, -53, -49, -130, 178, -136, 353, +-67, 444, 18, 424, 86, 308, 134, 123, +152, -79, 121, -265, 67, -401, 27, -468, +22, -446, 51, -351, 123, -204, 197, -47, +253, 96, 290, 188, 294, 219, 239, 193, +150, 123, 58, 14, -14, -94, -61, -168, +-67, -187, -31, -168, 51, -116, 148, -46, +213, 24, 235, 55, 238, 39, 197, -28, +118, -122, 43, -223, 0, -286, -13, -291, +20, -235, 90, -127, 163, 30, 220, 182, +251, 284, 221, 296, 151, 217, 72, 67, +6, -106, -44, -258, -58, -346, -21, -349, +65, -268, 149, -133, 194, 9, 190, 99, +166, 120, 117, 68, 54, -23, 13, -116, +11, -170, 24, -180, 52, -133, 98, -45, +161, 57, 199, 118, 201, 118, 188, 60, +151, -21, 70, -106, -31, -170, -110, -203, +-150, -190, -154, -145, -86, -86, 39, -35, +182, -4, 308, 2, 397, 10, 415, 23, +354, 37, 232, 39, 101, 25, -17, -14, +-101, -74, -136, -154, -122, -231, -77, -288, +-19, -283, 32, -204, 69, -65, 92, 88, +124, 222, 170, 294, 231, 289, 306, 196, +367, 39, 372, -143, 320, -293, 225, -377, +105, -370, -40, -300, -168, -188, -231, -69, +-213, 38, -152, 98, -58, 105, 76, 74, +215, 34, 288, 1, 311, -4, 315, 9, +276, 25, 185, 21, 111, -1, 86, -47, +77, -107, 53, -176, 45, -221, 49, -228, +46, -185, 22, -111, 9, -33, 14, 15, +15, 31, 9, 16, 30, -16, 67, -54, +103, -62, 138, -29, 191, 42, 226, 120, +230, 166, 196, 139, 137, 45, 67, -98, +-4, -254, -82, -386, -122, -440, -95, -392, +-33, -248, 36, -55, 121, 143, 204, 290, +251, 350, 245, 317, 219, 214, 173, 56, +123, -114, 63, -263, 12, -350, -6, -367, +-7, -317, -25, -226, -47, -104, -42, 21, +-9, 131, 32, 198, 97, 208, 184, 154, +276, 66, 346, -30, 383, -105, 364, -157, +292, -172, 173, -154, 36, -115, -105, -85, +-241, -79, -339, -106, -354, -135, -280, -145, +-133, -118, 60, -56, 295, 39, 503, 141, +625, 221, 635, 241, 557, 195, 393, 85, +152, -55, -99, -188, -272, -276, -358, -317, +-367, -312, -300, -277, -154, -212, 12, -140, +146, -71, 228, -6, 283, 67, 300, 146, +296, 227, 281, 272, 262, 261, 229, 179, +173, 48, 99, -108, 16, -256, -68, -364, +-134, -392, -182, -336, -179, -221, -127, -91, +-55, 27, 8, 94, 85, 107, 180, 85, +257, 57, 299, 27, 318, 12, 295, 13, +217, 23, 106, 16, 5, -11, -66, -64, +-100, -120, -101, -156, -39, -154, 58, -130, +122, -96, 133, -65, 127, -48, 99, -50, +36, -59, -10, -62, 5, -39, 52, 12, +114, 85, 176, 141, 225, 147, 218, 89, +163, -9, 100, -131, 75, -236, 72, -292, +67, -266, 77, -175, 98, -56, 79, 52, +4, 124, -74, 127, -109, 77, -109, 11, +-51, -42, 67, -80, 213, -95, 327, -91, +387, -77, 381, -77, 318, -81, 203, -78, +61, -56, -48, -14, -100, 52, -120, 108, +-117, 123, -110, 76, -102, -19, -94, -153, +-57, -286, -4, -380, 78, -384, 198, -287, +330, -102, 436, 117, 487, 326, 450, 467, +308, 505, 99, 420, -118, 223, -316, -52, +-450, -334, -478, -572, -378, -707, -206, -701, +6, -555, 234, -306, 436, 8, 552, 323, +565, 564, 498, 666, 354, 616, 141, 427, +-67, 155, -213, -138, -278, -381, -276, -524, +-191, -533, -55, -426, 76, -238, 155, -46, +179, 89, 148, 137, 71, 103, -5, 8, +-25, -98, 20, -169, 105, -154, 205, -54, +320, 100, 384, 248, 350, 341, 220, 334, +63, 228, -90, 46, -216, -155, -266, -334, +-224, -448, -119, -472, 13, -399, 144, -268, +249, -111, 296, 32, 299, 151, 252, 233, +175, 270, 94, 245, 31, 175, -33, 69, +-71, -48, -57, -160, -15, -234, 34, -253, +88, -198, 137, -85, 163, 54, 157, 157, +137, 186, 99, 124, 63, 1, 19, -157, +-13, -295, -28, -373, -40, -352, -49, -237, +-38, -57, -1, 131, 34, 277, 71, 338, +136, 318, 197, 228, 232, 95, 233, -52, +214, -172, 146, -241, 57, -252, -18, -236, +-57, -197, -61, -155, -44, -110, -6, -65, +39, -15, 58, 25, 34, 63, -17, 95, +-58, 117, -87, 107, -68, 67, 1, 2, +109, -62, 227, -118, 325, -141, 376, -131, +368, -88, 305, -32, 193, 30, 67, 74, +-44, 89, -143, 60, -221, -4, -266, -91, +-269, -172, -251, -236, -189, -274, -80, -272, +71, -205, 259, -80, 447, 85, 583, 249, +638, 384, 595, 454, 436, 429, 182, 291, +-90, 70, -336, -194, -504, -438, -572, -605, +-516, -658, -366, -598, -160, -431, 68, -191, +290, 80, 478, 320, 583, 497, 587, 585, +511, 578, 361, 465, 159, 270, -46, 15, +-195, -256, -301, -491, -347, -627, -301, -647, +-172, -543, -19, -344, 110, -88, 208, 160, +259, 343, 247, 414, 180, 380, 101, 264, +51, 120, 15, -13, 6, -101, 21, -139, +55, -131, 72, -110, 79, -91, 84, -101, +61, -131, 24, -174, 5, -195, 9, -176, +16, -110, 26, -23, 48, 74, 43, 156, +14, 202, -24, 189, -47, 134, -50, 49, +-9, -37, 80, -103, 191, -126, 303, -119, +374, -99, 365, -86, 273, -75, 114, -85, +-68, -109, -242, -134, -341, -126, -341, -83, +-227, -5, -56, 84, 113, 158, 256, 189, +342, 176, 340, 112, 257, 13, 153, -101, +62, -188, -17, -224, -56, -204, -52, -149, +-15, -73, 7, 1, 21, 58, 33, 78, +48, 71, 63, 39, 89, 0, 133, -41, +157, -68, 137, -85, 82, -90, 1, -98, +-100, -93, -180, -68, -170, -24, -92, 25, +42, 80, 218, 126, 385, 150, 472, 121, +440, 43, 299, -67, 79, -173, -155, -249, +-345, -263, -457, -211, -453, -107, -344, 5, +-158, 101, 57, 142, 265, 111, 410, 22, +476, -72, 466, -133, 381, -133, 254, -70, +108, 39, -41, 143, -172, 203, -255, 196, +-275, 123, -260, -5, -185, -148, -61, -262, +76, -314, 176, -307, 235, -254, 256, -177, +245, -81, 208, 21, 149, 113, 93, 181, +46, 232, 2, 254, -12, 244, -2, 191, +19, 101, 20, -20, 20, -142, -3, -245, +-51, -305, -103, -327, -142, -307, -146, -256, +-102, -172, 9, -76, 168, 23, 334, 121, +467, 221, 515, 296, 471, 330, 304, 304, +44, 220, -229, 75, -418, -96, -496, -258, +-465, -370, -304, -422, -58, -394, 199, -292, +403, -134, 510, 28, 499, 163, 367, 243, +164, 267, -58, 227, -223, 141, -301, 32, +-290, -69, -197, -138, -39, -156, 141, -134, +275, -82, 343, -28, 337, 15, 244, 25, +84, -6, -112, -72, -275, -144, -358, -197, +-321, -196, -193, -125, 3, 5, 227, 144, +411, 258, 511, 309, 501, 275, 367, 143, +122, -54, -142, -260, -330, -398, -422, -432, +-386, -350, -231, -174, 11, 57, 238, 263, +378, 382, 411, 375, 341, 251, 171, 41, +-57, -177, -224, -337, -279, -394, -259, -350, +-169, -215, 1, -37, 195, 138, 300, 252, +320, 283, 284, 238, 204, 146, 88, 27, +-27, -83, -98, -162, -130, -201, -126, -214, +-87, -194, -12, -150, 64, -91, 91, -38, +106, 19, 121, 79, 124, 124, 93, 134, +61, 117, 29, 78, -4, 29, -15, -31, +-9, -80, 12, -111, 48, -112, 79, -89, +85, -46, 72, -7, 58, 14, 14, 7, +-28, -14, -48, -44, -54, -74, -66, -101, +-60, -104, -5, -81, 70, -36, 130, 9, +157, 55, 174, 94, 191, 123, 167, 135, +125, 137, 74, 115, 6, 63, -106, -27, +-188, -126, -194, -230, -160, -315, -95, -357, +12, -317, 152, -196, 252, -29, 275, 135, +239, 263, 157, 316, 44, 286, -91, 187, +-174, 67, -178, -44, -117, -109, -14, -113, +110, -67, 196, -21, 178, -6, 97, -39, +11, -104, -60, -186, -98, -246, -88, -257, +-15, -202, 81, -97, 178, 35, 231, 150, +229, 223, 167, 239, 52, 218, -64, 174, +-136, 127, -138, 76, -98, 28, -27, -25, +69, -89, 143, -173, 160, -263, 107, -345, +43, -376, -12, -336, -60, -223, -99, -64, +-95, 113, -27, 267, 61, 367, 138, 385, +189, 330, 202, 211, 163, 73, 79, -49, +5, -134, -57, -185, -103, -199, -136, -197, +-117, -195, -47, -200, 26, -198, 77, -189, +113, -160, 140, -97, 124, 8, 86, 121, +72, 211, 62, 269, 49, 298, 49, 281, +70, 221, 51, 127, -2, 21, -55, -88, +-104, -187, -150, -276, -185, -342, -168, -384, +-86, -381, 41, -319, 165, -194, 253, -34, +311, 144, 295, 308, 225, 430, 134, 474, +42, 425, -59, 288, -142, 100, -178, -105, +-178, -273, -152, -380, -119, -404, -87, -359, +-34, -260, 42, -139, 132, -23, 208, 52, +286, 93, 331, 116, 315, 137, 228, 147, +88, 148, -64, 141, -192, 116, -276, 54, +-305, -28, -267, -112, -185, -166, -88, -182, +47, -146, 175, -75, 251, 5, 260, 48, +240, 48, 189, 5, 116, -63, 47, -134, +-22, -164, -74, -131, -91, -36, -65, 87, +-10, 206, 42, 268, 74, 254, 67, 160, +35, 21, -49, -134, -139, -260, -162, -321, +-116, -290, -31, -187, 86, -46, 226, 87, +316, 185, 327, 219, 275, 188, 147, 93, +-38, -24, -229, -132, -346, -192, -368, -190, +-292, -122, -151, -27, 14, 65, 167, 131, +271, 157, 325, 125, 317, 55, 243, -36, +130, -107, 11, -146, -95, -153, -192, -137, +-227, -98, -193, -50, -108, 4, -8, 59, +106, 114, 212, 149, 263, 165, 258, 148, +194, 96, 70, -1, -88, -122, -229, -234, +-296, -296, -287, -296, -195, -228, -62, -106, +89, 48, 214, 190, 296, 291, 329, 319, +304, 274, 221, 166, 106, 42, -5, -76, +-119, -172, -230, -245, -294, -272, -316, -254, +-288, -201, -205, -131, -45, -44, 145, 47, +320, 133, 450, 196, 484, 231, 404, 211, +233, 141, 23, 40, -176, -56, -323, -130, +-379, -169, -342, -169, -211, -118, -51, -42, +104, 25, 217, 54, 249, 55, 189, 29, +80, -11, -26, -53, -119, -80, -171, -92, +-156, -83, -83, -62, 41, -20, 175, 27, +296, 75, 355, 117, 334, 163, 212, 183, +15, 156, -193, 79, -377, -28, -484, -151, +-473, -252, -352, -298, -152, -266, 97, -175, +354, -37, 524, 105, 583, 205, 521, 219, +349, 157, 107, 52, -124, -49, -297, -120, +-404, -132, -428, -81, -381, 18, -276, 119, +-131, 184, 16, 181, 150, 115, 249, 3, +300, -113, 278, -204, 226, -245, 157, -240, +71, -188, -5, -107, -58, -18, -88, 47, +-93, 91, -53, 120, -3, 146, 10, 165, +-5, 178, -50, 171, -105, 141, -152, 74, +-138, -14, -70, -113, 26, -204, 123, -268, +211, -273, 282, -216, 289, -114, 231, -7, +143, 88, 28, 148, -113, 165, -251, 134, +-329, 74, -360, 8, -335, -33, -247, -40, +-111, -12, 53, 29, 235, 64, 405, 83, +501, 84, 493, 51, 372, -3, 158, -68, +-88, -127, -320, -173, -467, -191, -503, -185, +-417, -151, -245, -98, -11, -13, 225, 92, +374, 199, 422, 269, 373, 299, 233, 278, +38, 201, -139, 66, -253, -92, -308, -233, +-272, -322, -161, -347, -18, -292, 100, -174, +190, -19, 233, 127, 193, 238, 88, 286, +-38, 264, -132, 170, -183, 43, -185, -82, +-116, -176, -5, -228, 108, -212, 186, -137, +237, -22, 226, 91, 136, 185, 2, 230, +-124, 208, -211, 115, -257, -12, -244, -148, +-168, -256, -52, -299, 79, -237, 183, -92, +260, 87, 290, 246, 270, 352, 185, 360, +55, 261, -98, 76, -247, -130, -350, -306, +-390, -400, -355, -392, -247, -281, -84, -107, +106, 82, 288, 244, 427, 355, 454, 388, +379, 339, 243, 223, 79, 76, -98, -81, +-240, -229, -316, -342, -346, -378, -319, -330, +-234, -209, -115, -47, 18, 122, 130, 248, +224, 301, 276, 275, 275, 190, 207, 63, +118, -63, 25, -143, -85, -147, -184, -100, +-224, -29, -197, 35, -135, 77, -47, 79, +48, 46, 91, -8, 76, -58, 19, -97, +-33, -112, -72, -103, -88, -70, -72, -30, +-9, 24, 88, 89, 168, 163, 222, 215, +237, 228, 186, 186, 72, 93, -78, -38, +-219, -176, -331, -287, -364, -331, -322, -285, +-207, -151, -40, 24, 139, 197, 288, 318, +383, 362, 392, 307, 286, 174, 106, -1, +-81, -166, -240, -280, -323, -313, -324, -269, +-246, -160, -130, -25, -2, 109, 99, 207, +157, 257, 170, 243, 123, 185, 52, 102, +3, 21, -22, -55, -36, -121, -32, -170, +3, -185, 23, -171, 11, -119, -20, -42, +-27, 48, -14, 120, -12, 167, -13, 174, +-11, 139, -18, 63, -47, -24, -61, -86, +-46, -102, -44, -84, -50, -34, -29, 31, +27, 91, 68, 115, 84, 96, 84, 39, +69, -30, 34, -90, -7, -109, -30, -96, +-50, -57, -78, -12, -108, 36, -133, 74, +-140, 90, -133, 72, -77, 44, 26, 20, +146, 7, 242, -4, 289, -6, 270, -5, +174, -1, 22, 1, -157, 11, -314, 26, +-389, 41, -362, 46, -245, 54, -85, 57, +88, 33, 203, -27, 235, -90, 216, -143, +179, -169, 109, -162, 18, -108, -34, -9, +-49, 123, -71, 246, -103, 325, -131, 327, +-150, 251, -180, 115, -182, -31, -124, -157, +-5, -242, 115, -272, 202, -234, 253, -161, +235, -82, 141, -20, 19, 31, -78, 72, +-143, 116, -178, 159, -160, 201, -111, 225, +-48, 221, 1, 172, 24, 88, 8, -27, +-42, -144, -90, -230, -99, -253, -51, -215, +25, -139, 98, -50, 154, 44, 165, 118, +134, 161, 67, 166, -14, 146, -107, 113, +-178, 80, -205, 50, -184, 34, -116, 18, +-30, -8, 29, -49, 55, -97, 58, -147, +40, -174, 20, -162, 34, -92, 58, 16, +79, 133, 88, 224, 81, 274, 47, 269, +-16, 209, -105, 101, -202, -27, -265, -139, +-269, -196, -212, -200, -102, -157, 27, -95, +144, -39, 213, -8, 234, 5, 204, 13, +140, 34, 47, 78, -53, 152, -131, 237, +-179, 296, -200, 287, -184, 199, -131, 45, +-65, -129, -16, -281, 27, -373, 62, -382, +89, -292, 103, -128, 110, 70, 93, 236, +51, 329, 2, 331, -54, 262, -114, 153, +-164, 34, -177, -76, -140, -137, -71, -139, +12, -82, 79, -2, 120, 69, 111, 108, +65, 115, 3, 76, -73, 1, -148, -80, +-188, -139, -172, -166, -112, -147, -15, -91, +100, -9, 187, 76, 226, 161, 214, 240, +158, 288, 43, 272, -104, 197, -239, 82, +-325, -44, -353, -158, -306, -229, -187, -247, +-34, -215, 114, -152, 241, -62, 313, 39, +318, 132, 255, 196, 153, 238, 14, 246, +-139, 202, -267, 106, -336, -4, -349, -101, +-314, -164, -228, -192, -110, -170, 10, -105, +125, -8, 228, 91, 297, 173, 300, 215, +241, 222, 139, 181, 21, 106, -106, 15, +-226, -76, -319, -157, -367, -197, -349, -188, +-260, -138, -114, -69, 59, 14, 215, 97, +326, 171, 356, 216, 297, 233, 168, 217, +10, 168, -156, 88, -293, -1, -362, -92, +-358, -170, -285, -221, -146, -218, 25, -167, +168, -82, 244, 19, 255, 125, 208, 211, +124, 254, 0, 238, -129, 169, -223, 63, +-254, -39, -220, -116, -127, -140, -9, -116, +82, -53, 128, 21, 133, 91, 104, 127, +52, 117, -22, 69, -97, 14, -157, -38, +-183, -74, -180, -95, -140, -86, -60, -41, +35, 38, 113, 121, 159, 189, 161, 214, +120, 191, 47, 122, -50, 29, -166, -69, +-256, -153, -284, -201, -240, -193, -136, -132, +11, -34, 138, 76, 194, 177, 176, 235, +101, 235, -4, 177, -90, 83, -135, -17, +-135, -80, -102, -93, -41, -55, 19, -2, +57, 43, 46, 51, -9, 20, -81, -41, +-152, -99, -192, -120, -169, -81, -87, 14, +16, 143, 101, 254, 158, 312, 160, 288, +96, 188, -7, 32, -99, -126, -168, -230, +-212, -261, -210, -238, -159, -169, -79, -72, +14, 34, 103, 122, 160, 191, 158, 244, +106, 283, 30, 280, -43, 228, -126, 123, +-200, -16, -240, -167, -235, -277, -184, -314, +-88, -262, 39, -143, 158, 13, 231, 164, +243, 267, 186, 288, 80, 239, -58, 143, +-189, 33, -283, -63, -318, -106, -307, -91, +-245, -40, -133, 12, 11, 62, 144, 100, +236, 112, 270, 86, 228, 34, 126, -33, +9, -89, -118, -123, -240, -121, -327, -75, +-342, 7, -274, 102, -133, 194, 33, 249, +168, 242, 240, 168, 232, 57, 149, -48, +31, -118, -98, -153, -208, -143, -262, -92, +-247, -8, -191, 77, -99, 130, 5, 134, +91, 101, 149, 42, 169, -5, 119, -23, +16, -15, -97, 10, -200, 55, -270, 89, +-277, 87, -218, 44, -107, -8, 19, -37, +133, -29, 196, 5, 192, 59, 138, 114, +61, 151, -27, 150, -126, 105, -218, 10, +-260, -102, -242, -188, -190, -210, -121, -163, +-30, -58, 46, 77, 109, 210, 161, 289, +171, 297, 104, 236, -11, 136, -140, 21, +-252, -90, -292, -171, -231, -182, -109, -126, +18, -36, 103, 49, 136, 101, 119, 104, +57, 80, -39, 43, -123, 17, -179, 10, +-207, 27, -186, 58, -121, 92, -45, 103, +20, 87, 60, 52, 66, 10, 43, -24, +13, -40, -27, -41, -77, -16, -119, 29, +-125, 75, -111, 93, -91, 67, -52, 15, +-3, -20, 23, -23, 12, 7, -29, 50, +-82, 79, -130, 85, -154, 71, -147, 36, +-102, 1, -49, -20, -4, -12, 42, 21, +73, 65, 76, 92, 57, 95, -1, 72, +-99, 30, -185, -25, -217, -67, -201, -70, +-149, -20, -88, 48, -31, 112, 9, 147, +38, 136, 52, 79, 56, 1, 55, -65, +49, -76, 20, -49, -31, 0, -95, 50, +-162, 89, -234, 110, -288, 126, -296, 114, +-246, 68, -152, -1, -15, -59, 141, -76, +269, -60, 315, -34, 277, 18, 190, 93, +61, 161, -107, 194, -263, 176, -394, 98, +-496, -8, -531, -117, -452, -188, -277, -190, +-41, -129, 198, -23, 380, 110, 465, 218, +438, 277, 308, 281, 122, 244, -82, 186, +-271, 104, -408, -17, -450, -145, -411, -252, +-323, -305, -229, -287, -144, -200, -65, -70, +6, 80, 60, 211, 104, 307, 152, 352, +187, 337, 173, 285, 121, 220, 62, 134, +-15, 34, -118, -74, -198, -171, -263, -244, +-333, -295, -379, -316, -366, -266, -309, -152, +-217, 9, -84, 186, 82, 340, 251, 437, +385, 456, 439, 384, 394, 247, 222, 73, +-42, -97, -309, -215, -505, -262, -614, -256, +-606, -196, -478, -101, -273, 4, -35, 92, +193, 140, 355, 154, 407, 154, 349, 127, +208, 91, 14, 66, -179, 47, -325, 35, +-402, 39, -400, 54, -308, 84, -153, 109, +6, 104, 124, 70, 165, 12, 113, -66, +3, -137, -122, -190, -213, -203, -244, -157, +-224, -52, -161, 103, -56, 279, 49, 418, +115, 479, 146, 436, 126, 278, 37, 37, +-78, -221, -192, -425, -296, -505, -356, -449, +-357, -273, -313, -21, -215, 232, -72, 410, +92, 485, 232, 453, 297, 348, 262, 209, +149, 55, -12, -97, -182, -217, -312, -296, +-380, -309, -392, -251, -353, -131, -266, 24, +-131, 170, 21, 265, 152, 315, 226, 309, +218, 244, 128, 138, -7, 13, -145, -103, +-255, -172, -305, -187, -304, -131, -273, -16, +-194, 109, -72, 207, 57, 257, 140, 233, +142, 154, 63, 36, -37, -91, -119, -193, +-179, -254, -217, -251, -241, -150, -253, 9, +-219, 175, -130, 306, -14, 381, 79, 387, +104, 326, 59, 207, -6, 76, -56, -52, +-79, -177, -86, -267, -99, -293, -131, -265, +-175, -181, -206, -70, -201, 47, -177, 160, +-155, 240, -136, 287, -115, 318, -92, 307, +-36, 251, 33, 162, 70, 38, 58, -104, +11, -219, -48, -269, -83, -221, -98, -107, +-118, 17, -140, 139, -163, 242, -203, 282, +-229, 245, -230, 131, -205, -24, -152, -158, +-93, -232, -55, -214, -14, -95, 42, 65, +91, 211, 113, 301, 79, 312, -27, 252, +-160, 149, -261, 33, -289, -54, -240, -114, +-148, -142, -71, -116, -41, -43, -48, 40, +-67, 114, -103, 142, -168, 120, -227, 68, +-236, -3, -180, -68, -70, -104, 47, -119, +123, -88, 122, 3, 40, 129, -79, 255, +-161, 351, -192, 389, -193, 372, -164, 280, +-120, 124, -91, -48, -77, -210, -90, -352, +-135, -443, -179, -469, -194, -393, -198, -212, +-174, 21, -115, 248, -42, 428, 15, 529, +38, 561, 28, 526, 10, 427, -3, 278, +-20, 99, -57, -90, -120, -257, -209, -400, +-290, -479, -341, -458, -340, -349, -280, -190, +-174, -20, -45, 120, 84, 252, 177, 372, +198, 446, 129, 461, -11, 416, -165, 308, +-293, 175, -370, 32, -355, -99, -272, -190, +-185, -245, -109, -272, -31, -245, 30, -186, +77, -109, 96, -18, 64, 75, 7, 159, +-57, 232, -128, 276, -197, 303, -282, 301, +-372, 247, -416, 156, -393, 47, -311, -72, +-158, -168, 30, -221, 177, -215, 245, -156, +230, -79, 142, 13, 24, 131, -79, 229, +-150, 283, -215, 287, -286, 233, -335, 142, +-329, 46, -286, -41, -232, -80, -189, -100, +-164, -128, -127, -130, -72, -89, -18, -24, +24, 45, 55, 97, 61, 146, 42, 188, +15, 195, -22, 182, -59, 173, -106, 157, +-171, 141, -228, 110, -275, 39, -313, -52, +-312, -135, -274, -186, -243, -188, -218, -176, +-171, -159, -107, -104, -31, -11, 59, 99, +162, 227, 252, 363, 274, 493, 186, 554, +2, 474, -229, 265, -433, -13, -543, -293, +-561, -485, -513, -549, -387, -486, -201, -306, +2, -56, 167, 199, 246, 407, 215, 495, +103, 458, -31, 343, -109, 183, -139, 11, +-179, -122, -226, -188, -251, -161, -256, -63, +-233, 54, -188, 148, -144, 181, -113, 134, +-102, 52, -121, -31, -128, -99, -101, -135, +-69, -132, -55, -83, -61, 22, -70, 135, +-60, 231, -43, 302, -41, 325, -54, 291, +-99, 201, -200, 49, -295, -107, -324, -218, +-281, -263, -206, -229, -148, -133, -124, -17, +-96, 101, -45, 199, 16, 261, 55, 276, +36, 231, -21, 146, -80, 68, -132, 9, +-161, -26, -179, -44, -220, -61, -273, -68, +-289, -53, -252, -33, -177, -11, -98, -1, +-42, 20, 11, 96, 34, 212, -14, 301, +-93, 316, -158, 237, -193, 102, -191, -49, +-161, -188, -123, -267, -70, -235, -32, -120, +-56, 30, -130, 151, -219, 200, -290, 185, +-298, 133, -227, 80, -112, 80, -7, 126, +46, 190, 25, 240, -42, 213, -132, 68, +-211, -155, -250, -370, -245, -465, -203, -381, +-125, -137, -35, 203, 37, 522, 53, 670, +2, 595, -94, 341, -193, 19, -277, -245, +-333, -375, -366, -357, -362, -218, -280, -52, +-115, 76, 73, 153, 226, 183, 285, 180, +209, 180, 32, 185, -177, 193, -374, 162, +-501, 71, -525, -44, -432, -134, -239, -181, +-17, -158, 143, -69, 210, 58, 166, 180, +25, 239, -149, 208, -292, 113, -362, -8, +-335, -80, -253, -55, -163, 39, -73, 142, +18, 204, 82, 191, 93, 115, 35, -4, +-66, -123, -176, -182, -274, -155, -326, -64, +-315, 74, -269, 210, -214, 297, -170, 291, +-142, 173, -117, -1, -84, -138, -53, -204, +-5, -182, 46, -87, 47, 54, 3, 212, +-46, 350, -83, 402, -116, 336, -172, 162, +-253, -57, -321, -236, -348, -330, -351, -321, +-316, -194, -254, 1, -193, 183, -127, 265, +-27, 220, 92, 123, 198, 78, 236, 102, +184, 164, 66, 196, -83, 158, -227, 64, +-338, -33, -421, -88, -460, -69, -439, -2, +-371, 61, -257, 76, -98, 16, 42, -109, +109, -214, 101, -225, 50, -95, 1, 132, +-37, 344, -93, 466, -154, 473, -191, 356, +-192, 158, -156, -60, -110, -237, -98, -322, +-126, -287, -200, -151, -294, 30, -322, 169, +-263, 220, -190, 188, -131, 103, -55, 4, +52, -58, 153, -54, 194, 20, 150, 121, +27, 203, -177, 247, -403, 231, -539, 122, +-540, -49, -438, -204, -269, -255, -74, -174, +94, -3, 196, 181, 216, 322, 151, 348, +27, 238, -106, 43, -199, -153, -239, -263, +-242, -228, -218, -68, -201, 141, -232, 289, +-293, 312, -347, 227, -369, 65, -313, -129, +-158, -255, 36, -235, 215, -71, 329, 149, +351, 315, 273, 367, 102, 320, -133, 196, +-365, 56, -544, -56, -635, -134, -600, -186, +-465, -204, -295, -198, -114, -163, 39, -98, +117, 4, 126, 151, 108, 306, 85, 401, +73, 415, 66, 348, 49, 231, -11, 103, +-135, -10, -273, -107, -361, -187, -406, -263, +-409, -314, -350, -304, -239, -220, -128, -63, +-54, 149, -31, 343, -40, 452, -53, 422, +-49, 268, -7, 75, 55, -66, 95, -105, +91, -30, 29, 107, -72, 208, -172, 187, +-266, 25, -372, -203, -427, -362, -391, -366, +-318, -190, -270, 85, -238, 325, -181, 412, +-57, 309, 137, 86, 334, -96, 439, -126, +373, 12, 124, 230, -199, 383, -484, 358, +-642, 153, -615, -149, -441, -395, -224, -462, +-38, -307, 61, -2, 57, 305, -11, 440, +-75, 342, -107, 82, -107, -184, -84, -311, +-16, -228, 73, 30, 92, 357, 0, 584, +-161, 581, -336, 333, -427, -59, -386, -432, +-248, -609, -81, -508, 29, -171, 16, 220, +-90, 462, -201, 459, -227, 255, -154, -34, +-49, -235, 9, -243, 22, -63, 5, 190, +-11, 375, 22, 399, 59, 269, -9, 52, +-196, -141, -401, -232, -518, -224, -507, -174, +-379, -101, -194, -8, -31, 99, 52, 192, +83, 252, 135, 265, 202, 224, 218, 119, +138, -20, -42, -143, -243, -186, -363, -125, +-368, 14, -312, 165, -276, 241, -281, 182, +-267, 28, -183, -122, -45, -174, 74, -78, +102, 123, 15, 299, -99, 345, -148, 212, +-104, -42, -1, -261, 83, -310, 68, -178, +-37, 68, -168, 284, -280, 344, -344, 222, +-355, 1, -344, -189, -309, -235, -226, -112, +-93, 113, 61, 314, 169, 370, 191, 245, +138, 37, 28, -129, -110, -187, -218, -151, +-243, -71, -207, 16, -152, 98, -119, 141, +-129, 127, -180, 78, -252, 42, -292, 39, +-266, 65, -207, 60, -109, -5, 44, -77, +205, -83, 282, 5, 199, 156, -20, 273, +-232, 297, -316, 218, -292, 65, -237, -101, +-181, -202, -166, -196, -180, -92, -184, 23, +-174, 58, -152, -16, -124, -127, -71, -157, +48, -30, 171, 214, 185, 466, 64, 581, +-111, 485, -250, 231, -275, -66, -212, -300, +-161, -394, -163, -351, -184, -196, -188, -19, +-169, 84, -154, 82, -129, 4, -67, -71, +11, -27, 78, 156, 106, 393, 29, 533, +-122, 471, -224, 240, -208, -25, -115, -237, +-62, -343, -129, -328, -242, -226, -267, -92, +-177, 25, -54, 71, -3, 65, -53, 69, +-114, 147, -117, 286, -82, 378, -31, 312, +7, 115, -12, -89, -64, -206, -112, -228, +-150, -185, -186, -105, -205, 27, -186, 160, +-130, 220, -76, 188, -51, 86, -54, -2, +-83, 2, -146, 49, -201, 76, -198, 59, +-115, 18, 31, -7, 170, -11, 203, -40, +86, -71, -131, -57, -339, 2, -451, 82, +-429, 154, -280, 194, -84, 210, 52, 176, +98, 88, 66, -24, -13, -131, -79, -178, +-89, -142, -62, -34, -19, 125, 17, 252, +5, 282, -88, 180, -219, -25, -331, -240, +-357, -331, -306, -255, -217, -75, -115, 123, +-18, 288, 81, 391, 170, 413, 188, 335, +111, 194, -13, 29, -107, -92, -186, -163, +-266, -238, -320, -315, -331, -359, -275, -316, +-148, -120, 1, 145, 100, 347, 101, 438, +47, 436, -41, 344, -162, 204, -275, 57, +-320, -86, -263, -172, -105, -174, 94, -151, +231, -101, 239, -29, 172, 47, 73, 119, +-69, 148, -292, 82, -561, -28, -723, -102, +-679, -122, -432, -79, -40, 28, 333, 148, +508, 263, 465, 319, 334, 278, 179, 173, +12, 53, -159, -43, -343, -112, -492, -154, +-552, -164, -505, -160, -352, -136, -160, -102, +12, -46, 155, 54, 255, 203, 263, 344, +183, 378, 38, 281, -168, 98, -360, -85, +-430, -171, -339, -187, -127, -144, 105, -50, +254, 50, 245, 115, 91, 132, -121, 90, +-298, 37, -394, 50, -386, 95, -294, 93, +-182, 29, -83, -96, 16, -167, 73, -133, +76, -44, 60, 84, 55, 200, 71, 253, +54, 250, -30, 171, -154, 37, -304, -108, +-396, -178, -335, -139, -153, -38, -1, 37, +66, 59, 74, 64, 8, 78, -85, 100, +-159, 106, -198, 73, -157, 21, -54, -47, +55, -69, 68, -26, -71, 29, -256, 81, +-319, 87, -207, 35, -23, -26, 127, -62, +189, -10, 148, 120, 51, 246, -105, 281, +-292, 194, -427, 5, -429, -200, -263, -306, +-12, -274, 142, -138, 121, 14, -1, 82, +-109, 117, -127, 175, -65, 245, -13, 295, +-19, 276, -54, 168, -62, 14, -30, -125, +-22, -225, -121, -268, -265, -252, -308, -202, +-186, -52, 22, 156, 167, 315, 145, 404, +-30, 372, -232, 214, -295, 9, -213, -190, +-141, -287, -153, -259, -173, -155, -132, -25, +0, 82, 166, 113, 279, 133, 283, 199, +156, 265, -62, 276, -279, 185, -431, 4, +-492, -154, -427, -272, -272, -308, -142, -236, +-52, -101, 37, 81, 145, 272, 217, 374, +209, 338, 143, 185, 30, 26, -82, -65, +-152, -85, -224, -83, -325, -93, -434, -129, +-455, -147, -296, -101, 12, 6, 279, 161, +355, 295, 235, 338, 23, 292, -139, 119, +-179, -92, -151, -213, -159, -226, -271, -132, +-402, -7, -391, 20, -178, -28, 109, -68, +291, -20, 305, 157, 216, 364, 64, 430, +-118, 319, -249, 48, -328, -273, -391, -441, +-387, -399, -278, -187, -87, 105, 131, 298, +298, 357, 341, 307, 206, 162, -78, -5, +-295, -118, -322, -160, -246, -129, -173, -49, +-162, 9, -236, 10, -277, -14, -156, -45, +91, -4, 304, 129, 317, 267, 134, 342, +-55, 326, -175, 168, -217, -92, -177, -303, +-132, -371, -134, -307, -198, -162, -266, -39, +-239, 62, -107, 182, 31, 295, 83, 359, +64, 325, -8, 180, -45, -10, 1, -170, +35, -237, -31, -227, -178, -156, -277, -24, +-220, 116, -49, 172, 99, 144, 92, 85, +-49, 57, -198, 102, -227, 147, -125, 100, +-36, 3, -61, -103, -143, -181, -214, -220, +-207, -220, -90, -153, 48, -14, 129, 169, +171, 351, 136, 435, 10, 391, -110, 243, +-196, 34, -253, -155, -218, -253, -134, -263, +-71, -171, -62, -58, -98, -55, -121, -107, +-105, -80, -79, 22, -67, 171, -60, 269, +-14, 247, 65, 173, 86, 102, -2, 1, +-118, -89, -204, -143, -167, -111, -32, 47, +8, 191, -57, 196, -120, 111, -118, 3, +-37, -39, 0, -38, -88, -105, -181, -183, +-164, -163, -97, -91, -35, -24, -72, -25, +-220, -83, -254, -19, -81, 231, 161, 477, +289, 562, 193, 422, -12, 159, -157, -50, +-150, -179, -55, -293, -76, -385, -221, -386, +-288, -268, -238, -107, -167, 27, -132, 98, +-143, 145, -149, 210, -50, 280, 111, 272, +216, 165, 177, 38, 6, -32, -71, -29, +33, 12, 96, 37, 0, 70, -249, 97, +-492, 77, -511, 5, -290, -91, -6, -195, +122, -255, 65, -235, 14, -164, 76, -56, +114, 69, 14, 158, -137, 258, -238, 332, +-200, 336, -92, 279, -20, 104, 17, -119, +-28, -200, -111, -130, -113, 24, -73, 144, +-42, 103, -3, -49, 31, -167, 22, -220, +-45, -198, -193, -149, -301, -94, -274, 36, +-215, 158, -172, 173, -130, 115, -35, 51, +184, 159, 390, 409, 431, 555, 236, 458, +-137, 104, -423, -349, -434, -648, -316, -713, +-244, -559, -254, -239, -281, 141, -183, 422, +73, 508, 315, 389, 433, 168, 317, -4, +-13, -7, -254, 89, -293, 85, -270, -41, +-230, -175, -189, -247, -135, -174, -84, -32, +-80, 102, -102, 202, -53, 183, 103, 101, +267, 72, 324, 67, 184, 27, -124, -64, +-422, -144, -556, -193, -444, -175, -216, -46, +-47, 115, 50, 189, 117, 174, 173, 127, +179, 109, 85, 104, -98, 43, -272, -47, +-300, -80, -163, -108, 25, -93, 87, -24, +-14, 53, -105, 183, -89, 242, -42, 132, +21, -50, 92, -250, 12, -289, -221, -105, +-407, 85, -465, 132, -370, 53, -112, -61, +207, -45, 416, 114, 409, 240, 183, 282, +-79, 258, -188, 140, -184, 16, -189, -101, +-235, -205, -294, -240, -262, -214, -125, -153, +34, -86, 119, -17, 83, 71, -38, 143, +-149, 179, -167, 119, -73, 57, 25, 83, +76, 166, 43, 248, -116, 234, -242, 88, +-158, -126, 43, -288, 147, -281, 61, -186, +-185, -97, -438, -45, -428, -27, -109, -10, +292, 75, 438, 249, 168, 386, -259, 383, +-453, 191, -275, -101, 61, -279, 199, -332, +26, -254, -294, -59, -431, 119, -217, 208, +135, 200, 292, 116, 183, -37, -39, -165, +-125, -124, 1, 11, 64, 160, -77, 242, +-255, 207, -369, 76, -317, -99, -114, -254, +13, -342, -16, -259, -51, 2, -40, 261, +2, 421, 88, 356, 118, 96, 74, -107, +33, -136, -53, -90, -194, -23, -306, 48, +-274, -12, -131, -129, 1, -145, 97, -107, +56, 70, -120, 269, -182, 287, -107, 181, +-16, -15, 19, -166, -74, -150, -198, -64, +-120, 4, 130, -13, 293, -53, 239, -6, +-72, 102, -448, 168, -493, 189, -293, 128, +-92, -12, 43, -81, 6, -142, -57, -165, +71, -34, 275, 49, 296, 96, 89, 127, +-155, 61, -334, 6, -348, -27, -204, -54, +-96, -15, -145, 64, -240, 137, -196, 158, +-58, 106, 65, -82, 134, -265, 122, -252, +100, -68, 73, 174, 67, 319, 107, 275, +54, 99, -143, -68, -341, -142, -421, -147, +-344, -32, -160, 33, -4, -11, 43, -19, +13, -70, -63, -97, -127, 10, -133, 137, +-84, 241, 26, 260, 166, 154, 287, -28, +313, -143, 176, -151, -25, -119, -242, -69, +-443, -68, -502, -104, -419, -59, -256, 87, +-51, 285, 102, 376, 110, 307, 28, 62, +-31, -239, -11, -347, 143, -276, 224, -119, +93, 59, -86, 129, -179, 82, -72, 5, +73, 14, -16, 76, -243, 183, -420, 266, +-393, 199, -150, 87, 130, -63, 208, -259, +26, -319, -208, -264, -276, -121, -96, 70, +173, 179, 310, 184, 273, 159, 37, 127, +-199, 127, -201, 144, -84, 16, -33, -201, +-138, -295, -364, -274, -490, -83, -310, 171, +124, 281, 447, 302, 393, 267, 57, 184, +-298, 87, -380, -80, -156, -297, 76, -462, +123, -435, 17, -241, -112, -9, -136, 200, +-5, 342, 136, 400, 146, 456, 2, 478, +-300, 288, -533, -60, -460, -375, -196, -637, +86, -650, 253, -373, 217, -42, 88, 310, +64, 548, 152, 475, 216, 262, 106, 15, +-164, -203, -430, -180, -565, 27, -489, 117, +-250, 60, 13, -92, 208, -289, 248, -286, +175, -62, 95, 171, 75, 320, 87, 292, +73, 141, -37, 7, -242, -100, -397, -161, +-364, -134, -140, -56, 87, 55, 95, 167, +-43, 172, -170, -13, -141, -235, 114, -263, +339, -39, 241, 231, -103, 310, -445, 200, +-482, -21, -110, -220, 281, -171, 317, 32, +62, 141, -245, 96, -320, -16, -77, -79, +182, -38, 118, 41, -187, 141, -400, 254, +-320, 198, -15, -76, 211, -283, 183, -349, +50, -272, -31, 11, -36, 246, -13, 208, +-28, 22, -127, -96, -175, 0, -28, 222, +79, 377, -34, 354, -167, 157, -227, -161, +-181, -413, -36, -411, 36, -236, -15, 20, +-111, 257, -97, 286, 100, 82, 273, -258, +242, -409, 35, -213, -172, 106, -309, 405, +-302, 555, -129, 396, 17, 42, 78, -201, +29, -175, -101, -8, -202, 122, -249, 61, +-120, -160, 80, -389, 183, -477, 224, -272, +160, 87, 19, 331, -108, 377, -212, 250, +-225, 101, -119, -32, -29, -51, -64, 109, +-122, 241, -155, 238, -84, 72, 163, -216, +328, -407, 226, -400, -60, -238, -393, -37, +-475, 136, -231, 220, 95, 253, 298, 254, +245, 116, -27, -57, -231, -168, -169, -169, +30, 48, 147, 240, 100, 204, -107, 14, +-297, -182, -284, -258, -67, -128, 103, 146, +35, 280, -123, 194, -186, -27, -49, -305, +225, -343, 376, -167, 258, 67, -63, 304, +-343, 346, -418, 192, -292, 41, -79, -27, +87, -61, 147, -87, 47, -72, -66, -79, +-72, -99, -33, -119, 54, -102, 83, -24, +49, 66, 14, 202, -49, 304, -114, 277, +-226, 154, -341, -35, -270, -135, -2, -198, +274, -237, 342, -186, 206, -131, -10, -15, +-155, 94, -151, 104, -113, 129, -113, 112, +-179, 93, -228, 158, -84, 206, 63, 156, +55, 36, 16, -165, 17, -354, 72, -349, +150, -222, 222, 5, 175, 311, -39, 425, +-205, 293, -280, -49, -356, -355, -431, -371, +-365, -227, -112, 76, 163, 395, 379, 416, +479, 252, 378, 26, 115, -187, -123, -224, +-123, -136, -42, -41, -116, 95, -297, 121, +-457, -46, -467, -125, -178, -110, 260, -137, +451, -88, 264, -34, -52, 18, -205, 113, +-107, 219, 130, 333, 249, 343, 94, 243, +-187, 146, -343, 19, -218, -169, 68, -367, +230, -486, 142, -504, -114, -381, -336, -173, +-333, 71, -118, 326, 131, 432, 222, 425, +93, 418, -114, 330, -155, 237, 23, 155, +285, -16, 409, -263, 216, -481, -164, -524, +-413, -348, -450, -151, -329, -99, -85, -130, +67, -129, 24, 22, -50, 350, -86, 623, +-17, 730, 185, 584, 389, 168, 426, -215, +227, -443, -122, -538, -403, -425, -427, -229, +-208, -17, 53, 154, 152, 154, -21, 79, +-327, 14, -418, -115, -124, -149, 293, 28, +457, 234, 281, 314, -43, 198, -276, -34, +-172, -116, 145, -27, 250, 118, 96, 210, +-128, 127, -245, -83, -147, -259, 17, -333, +53, -336, -91, -297, -215, -154, -189, 65, +-107, 261, -23, 373, 3, 388, 19, 320, +147, 227, 332, 83, 410, -132, 258, -292, +-8, -260, -267, -120, -409, -54, -350, -121, +-231, -238, -94, -271, 27, -41, -6, 353, +-50, 628, 20, 596, 144, 202, 250, -302, +284, -588, 216, -640, 16, -401, -201, 122, +-279, 564, -260, 588, -208, 278, -144, -118, +-44, -366, 64, -325, 174, -28, 261, 345, +205, 475, 54, 205, -145, -226, -293, -589, +-167, -760, 53, -585, 130, 24, 98, 735, +1, 987, -147, 712, -161, 199, 20, -346, +156, -668, 86, -605, -130, -180, -274, 300, +-175, 434, 23, 178, 153, -188, 167, -473, +100, -518, 35, -90, 67, 549, 168, 772, +119, 500, -144, 45, -388, -343, -385, -552, +-155, -525, 83, -261, 196, 125, 124, 401, +-41, 383, -98, 209, 27, 4, 248, -272, +291, -316, 46, -75, -189, 149, -257, 242, +-214, 190, -113, 71, 6, -77, 93, -286, +109, -318, 136, -77, 166, 170, 59, 253, +-201, 199, -411, -7, -254, -221, 122, -296, +359, -199, 348, 97, 89, 359, -235, 438, +-386, 420, -254, 110, 37, -426, 200, -759, +199, -631, 76, -87, -84, 489, -188, 723, +-163, 501, 104, -100, 426, -708, 455, -814, +137, -275, -319, 482, -608, 996, -566, 930, +-195, 218, 263, -687, 439, -1163, 219, -838, +-166, 56, -361, 800, -179, 914, 224, 381, +576, -381, 614, -888, 235, -802, -306, -98, +-584, 725, -449, 1062, -164, 722, -20, -67, +-42, -843, -88, -1076, 16, -553, 226, 253, +327, 788, 210, 762, 7, 205, -62, -340, +23, -482, 98, -323, 16, -7, -224, 279, +-377, 305, -269, 73, -34, -188, 160, -374, +267, -378, 250, -144, 198, 173, 186, 451, +113, 566, -89, 407, -350, 68, -536, -291, +-463, -509, -97, -561, 305, -376, 479, 47, +380, 407, 68, 463, -170, 240, -114, -136, +79, -415, 197, -376, 129, -43, -110, 352, +-284, 565, -252, 396, -121, -26, 1, -412, +94, -609, 148, -443, 130, 29, 40, 441, +-29, 534, -65, 254, -59, -213, 41, -543, +166, -530, 179, -227, 78, 235, -100, 610, +-307, 599, -320, 261, -34, -154, 298, -499, +474, -553, 355, -286, -67, 109, -495, 407, +-574, 444, -220, 173, 220, -221, 393, -486, +307, -535, 59, -310, -180, 198, -217, 629, +-22, 627, 199, 282, 234, -129, 144, -430, +38, -366, -113, -3, -258, 246, -260, 240, +-99, -12, -5, -386, 19, -540, 165, -467, +288, -238, 213, 222, 30, 677, -115, 749, +-160, 467, -117, 34, 62, -343, 204, -404, +96, -155, -148, 109, -303, 149, -239, -120, +-24, -475, 189, -638, 347, -442, 410, 37, +275, 481, -37, 685, -260, 551, -340, 144, +-343, -150, -116, -140, 216, 39, 299, 161, +122, -10, -82, -442, -131, -694, -36, -544, +78, -68, 104, 534, 42, 736, -37, 353, +-29, -202, 85, -617, 156, -559, 69, 37, +-49, 682, -23, 893, 101, 511, 119, -272, +12, -925, -176, -983, -389, -490, -409, 166, +-143, 660, 195, 706, 403, 338, 404, -100, +226, -367, 20, -416, -59, -235, -53, 107, +6, 348, 58, 291, -22, 18, -140, -293, +-160, -419, -81, -264, 37, 109, 128, 443, +198, 480, 144, 220, -55, -213, -247, -565, +-323, -645, -210, -434, 105, 81, 497, 612, +609, 799, 255, 551, -218, 17, -480, -499, +-373, -719, 62, -523, 478, -70, 534, 298, +170, 381, -337, 195, -601, -80, -438, -289, +0, -234, 341, 41, 380, 252, 100, 294, +-208, 131, -156, -177, 198, -391, 512, -370, +508, -54, 98, 327, -435, 462, -644, 287, +-388, -108, 65, -553, 418, -671, 473, -234, +153, 424, -256, 806, -392, 598, -213, -161, +148, -871, 497, -1040, 634, -499, 364, 485, +-224, 1120, -684, 948, -702, 258, -315, -469, +232, -888, 608, -781, 593, -215, 226, 380, +-179, 696, -305, 605, -161, 158, -6, -413, +73, -866, 127, -863, 167, -346, 181, 310, +164, 802, 47, 933, -219, 668, -437, 111, +-273, -535, 175, -945, 448, -882, 313, -434, +-22, 226, -274, 862, -297, 957, -42, 396, +326, -340, 412, -884, 155, -899, -31, -357, +54, 344, 139, 791, 48, 696, -122, 149, +-246, -439, -281, -722, -154, -551, 109, -63, +222, 465, 59, 670, -86, 458, -19, 42, +170, -340, 360, -478, 427, -332, 268, -66, +-71, 97, -384, 33, -395, -150, -82, -255, +260, -134, 341, 105, 167, 310, -116, 359, +-344, 183, -312, -52, -37, -206, 235, -255, +361, -142, 302, 83, 159, 267, 36, 237, +-99, 29, -189, -321, -88, -649, 120, -569, +222, -160, 189, 251, 142, 525, 27, 511, +-170, 259, -274, -24, -257, -240, -185, -336, +46, -194, 407, 36, 579, 193, 375, 285, +-66, 102, -451, -304, -417, -486, 45, -349, +502, -49, 572, 183, 177, 234, -378, 157, +-618, 0, -342, -128, 225, -82, 556, 76, +424, 145, 28, 105, -291, 59, -267, -37, +75, -146, 437, -230, 479, -198, 117, -64, +-357, 15, -565, 36, -365, 4, 27, -127, +347, -286, 467, -249, 362, 169, 155, 639, +34, 764, 16, 401, 6, -322, -51, -935, +-104, -979, -113, -356, -56, 447, 25, 774, +55, 504, 40, -128, 40, -624, 36, -613, +26, -205, 104, 355, 244, 785, 256, 662, +178, 19, 99, -565, -64, -805, -258, -656, +-274, -117, -111, 383, 97, 538, 315, 346, +464, 16, 352, -123, 37, -78, -231, 2, +-281, 38, -153, -29, 32, -161, 167, -337, +144, -386, 0, -257, -119, -88, -114, 83, +64, 260, 314, 356, 483, 300, 477, 181, +302, 121, 0, 75, -315, -25, -458, -183, +-368, -320, -117, -441, 163, -473, 291, -320, +228, -105, 6, 104, -180, 268, -37, 305, +389, 308, 658, 258, 489, 83, 11, -139, +-512, -219, -741, -141, -382, -12, 303, 78, +728, 29, 645, -95, 246, -203, -181, -275, +-461, -195, -428, -76, -52, -14, 349, 68, +506, 195, 367, 228, 18, 78, -323, -80, +-450, -143, -294, -175, 140, -124, 618, -2, +778, 112, 575, 145, 175, 138, -319, 130, +-666, 35, -622, -189, -224, -404, 211, -406, +436, -215, 447, -1, 273, 156, 9, 199, +-124, 132, -57, 6, 122, -3, 259, 151, +274, 202, 235, 19, 147, -236, -57, -388, +-226, -359, -264, -145, -262, 197, -152, 395, +143, 256, 431, -110, 498, -357, 298, -320, +-24, -137, -222, 176, -174, 431, 27, 243, +302, -192, 518, -490, 428, -452, 41, -53, +-346, 388, -522, 525, -406, 315, -13, -217, +454, -742, 646, -693, 402, -129, -8, 452, +-259, 788, -306, 659, -153, 32, 98, -698, +310, -964, 448, -639, 423, 1, 254, 667, +114, 950, -53, 609, -234, -112, -231, -788, +-122, -970, -34, -591, 79, 60, 127, 615, +69, 698, -8, 307, -7, -164, 148, -417, +390, -363, 494, -120, 344, 75, 75, 158, +-50, 208, 0, 139, 42, 19, 12, -95, +-85, -309, -246, -455, -282, -343, -80, -69, +204, 216, 356, 364, 315, 320, 178, 75, +97, -229, 106, -386, 108, -290, 137, -4, +237, 272, 238, 356, 169, 214, 157, -32, +86, -255, -131, -351, -376, -212, -470, -70, +-284, -78, 59, -131, 344, -153, 522, -36, +571, 169, 424, 329, 184, 390, -19, 180, +-142, -238, -146, -533, 44, -505, 347, -239, +426, 139, 98, 474, -348, 557, -579, 289, +-445, -226, 41, -648, 610, -695, 875, -444, +646, -3, 103, 494, -340, 763, -415, 528, +-186, -14, 120, -441, 418, -668, 558, -597, +356, -164, -43, 306, -306, 482, -309, 264, +-153, -91, 69, -337, 345, -357, 485, -123, +293, 166, -39, 371, -128, 390, 18, 131, +205, -161, 344, -353, 355, -488, 200, -430, +-54, -104, -241, 153, -234, 151, -143, 54, +-29, -29, 159, -24, 331, 103, 345, 213, +203, 162, 63, -56, 103, -275, 260, -396, +347, -268, 352, 98, 294, 372, 37, 459, +-357, 347, -590, -83, -507, -609, -224, -821, +181, -591, 728, -149, 1050, 342, 649, 639, +-107, 491, -489, 66, -409, -326, -101, -454, +337, -259, 661, 35, 548, 322, 74, 509, +-310, 395, -333, -6, -135, -345, 117, -493, +426, -563, 581, -503, 352, -248, -80, 93, +-340, 342, -306, 415, -127, 373, 96, 126, +309, -265, 330, -447, 209, -255, 230, 78, +406, 291, 456, 309, 317, 108, 104, -198, +-133, -351, -272, -262, -207, -42, -46, 29, +39, -60, -16, -94, -46, -74, 112, -27, +341, 67, 414, 121, 307, 23, 126, -237, +24, -388, 121, -249, 361, 91, 486, 454, +315, 664, -35, 506, -331, 6, -490, -487, +-378, -737, 45, -741, 440, -472, 558, -65, +460, 265, 187, 470, -61, 569, -57, 414, +121, 46, 250, -318, 207, -564, 45, -518, +-43, -149, 26, 229, 154, 381, 220, 231, +219, -130, 173, -469, 82, -455, -8, -80, +5, 312, 106, 541, 227, 446, 237, -10, +56, -415, -122, -560, -69, -443, 184, -52, +456, 316, 546, 351, 325, 106, -117, -250, +-352, -402, -187, -217, 47, 6, 131, 124, +201, 97, 279, -101, 314, -72, 343, 215, +356, 363, 250, 252, 2, -40, -168, -367, +-58, -509, 99, -373, 80, -80, -15, 149, +-100, 217, -126, 107, 30, -72, 346, -213, +608, -280, 542, -252, 216, -83, 32, 154, +141, 273, 290, 302, 256, 333, 64, 202, +-166, -66, -339, -311, -319, -408, -82, -310, +167, -144, 269, -22, 331, 19, 430, -69, +398, -197, 174, -225, 12, -140, 34, -5, +164, 217, 346, 413, 453, 430, 365, 245, +143, -44, -180, -281, -450, -376, -469, -328, +-274, -214, 66, -102, 465, 52, 678, 116, +566, 49, 241, -81, -3, -226, -28, -228, +75, -71, 255, 137, 446, 298, 404, 274, +89, 103, -254, -118, -410, -276, -275, -307, +82, -241, 440, -38, 593, 232, 391, 267, +17, 51, -186, -146, -133, -282, 92, -298, +365, -77, 506, 124, 425, 184, 174, 138, +-94, -36, -228, -217, -133, -321, 99, -308, +287, -58, 340, 317, 245, 476, 71, 308, +-41, 20, -29, -345, 120, -561, 297, -344, +328, 33, 228, 228, 144, 191, 116, -42, +149, -292, 208, -306, 165, 20, -38, 394, +-257, 472, -275, 167, 30, -342, 446, -670, +595, -546, 384, -105, 79, 344, -97, 540, +-65, 305, 221, -181, 569, -461, 574, -422, +232, -74, -127, 398, -341, 581, -367, 348, +-123, -179, 222, -702, 359, -817, 249, -471, +111, 85, 98, 484, 193, 532, 295, 254, +322, -120, 270, -277, 214, -137, 183, 87, +212, 178, 240, 89, 112, -106, -84, -265, +-128, -249, -102, -191, -157, -152, -165, -145, +-21, -190, 169, -53, 438, 286, 732, 480, +707, 424, 321, 178, -10, -202, -75, -495, +27, -478, 199, -264, 279, 35, 85, 278, +-215, 257, -362, 51, -253, -203, 98, -455, +394, -473, 383, -155, 269, 245, 257, 450, +347, 452, 498, 215, 567, -115, 321, -248, +-165, -216, -529, -105, -526, -21, -174, -134, +342, -243, 725, -234, 727, -166, 311, -22, +-291, 140, -653, 191, -450, 75, 165, -118, +795, -168, 1090, -35, 829, 141, 179, 325, +-379, 420, -555, 216, -339, -151, 93, -482, +433, -671, 459, -644, 258, -436, 9, -92, +-173, 251, -184, 455, 46, 508, 332, 356, +449, 126, 467, -93, 465, -235, 315, -152, +44, 29, -157, 67, -196, -49, -115, -262, +102, -490, 364, -550, 370, -269, 95, 169, +-109, 454, -45, 428, 155, 160, 302, -131, +425, -249, 441, -119, 146, 133, -220, 274, +-247, 181, 30, -108, 364, -345, 575, -382, +518, -203, 137, 47, -315, 134, -418, -27, +-74, -314, 366, -408, 569, -165, 476, 234, +177, 593, -161, 574, -297, 139, -92, -320, +287, -514, 502, -350, 500, 94, 350, 398, +62, 252, -142, -137, -64, -499, 136, -653, +249, -372, 198, 68, 47, 300, -56, 313, +4, 141, 168, -26, 296, 7, 335, 125, +278, 180, 90, 80, -98, -133, -88, -311, +163, -365, 484, -288, 555, -47, 279, 190, +-46, 227, -205, 98, -125, -155, 198, -372, +498, -326, 419, -90, -2, 226, -392, 452, +-433, 384, -150, 22, 277, -374, 652, -532, +747, -390, 484, -4, 155, 423, 79, 537, +185, 251, 252, -202, 201, -454, -57, -428, +-443, -271, -590, -35, -247, 132, 360, 94, +772, -28, 746, -107, 382, -128, -71, -97, +-307, 49, -87, 279, 434, 424, 757, 328, +605, 54, 62, -217, -484, -373, -611, -455, +-301, -522, 191, -439, 591, -163, 647, 121, +418, 421, 167, 575, 49, 369, 44, -6, +61, -288, 81, -342, 130, -166, 130, 45, +58, 145, -4, 63, 35, -119, 168, -263, +291, -279, 322, -156, 255, 27, 115, 117, +24, 113, 107, 137, 257, 192, 275, 150, +171, -27, 14, -278, -146, -484, -167, -517, +19, -225, 306, 279, 545, 602, 578, 495, +353, 51, 28, -387, -191, -571, -233, -441, +-93, 31, 113, 478, 228, 483, 261, 143, +275, -231, 262, -439, 263, -380, 244, -162, +150, 53, 70, 168, 67, 82, 82, -83, +96, -105, 131, -86, 153, -42, 66, 83, +-74, 175, -100, 201, 54, 126, 277, -34, +451, -115, 529, -190, 468, -282, 255, -269, +23, -195, -100, -106, -134, 30, -151, 86, +-87, 44, 89, -22, 253, -60, 325, 69, +339, 320, 270, 432, 96, 295, -64, -103, +-45, -555, 163, -797, 432, -687, 586, -174, +490, 447, 144, 723, -239, 556, -408, 106, +-255, -374, 88, -616, 345, -431, 370, 38, +242, 402, 61, 387, -89, 39, -42, -378, +238, -605, 483, -456, 504, 79, 334, 612, +115, 737, 62, 421, 184, -117, 246, -556, +154, -608, -128, -344, -473, -13, -490, 199, +-39, 94, 496, -220, 704, -341, 516, -211, +145, 67, -126, 400, -113, 580, 189, 441, +612, 60, 793, -315, 544, -487, 34, -430, +-421, -224, -609, -33, -490, 104, -80, 113, +410, -33, 582, -160, 418, -144, 193, -54, +38, 93, -15, 298, 122, 404, 401, 229, +546, -159, 397, -562, 123, -710, -74, -472, +-154, 18, -155, 509, -53, 724, 107, 484, +204, -25, 212, -407, 201, -498, 181, -357, +165, -56, 192, 168, 283, 187, 296, 27, +94, -223, -151, -325, -135, -217, 147, -26, +473, 240, 578, 409, 316, 307, -106, 64, +-301, -168, -154, -323, 182, -284, 396, -133, +295, 8, 31, 166, -145, 195, -122, 38, +102, -91, 398, -207, 585, -317, 533, -317, +267, -216, -6, -35, -95, 197, -18, 398, +94, 459, 103, 247, -4, -110, -116, -358, +-107, -411, 60, -238, 279, 106, 434, 308, +519, 216, 496, -37, 367, -299, 146, -430, +-124, -352, -283, -134, -205, 113, -6, 219, +168, 143, 303, -6, 355, -63, 244, 43, +107, 227, 65, 327, 75, 203, 143, -137, +269, -434, 325, -455, 251, -158, 84, 164, +-68, 219, -104, 9, -33, -361, 77, -627, +229, -423, 340, 126, 329, 616, 241, 808, +110, 595, 10, 63, 41, -448, 113, -692, +133, -590, 121, -218, 133, 185, 177, 417, +190, 410, 171, 145, 169, -246, 156, -552, +122, -602, 111, -372, 113, 95, 85, 586, +98, 766, 205, 565, 278, 116, 184, -453, +-14, -803, -137, -707, -83, -303, 80, 177, +281, 493, 431, 434, 420, 112, 302, -200, +226, -325, 197, -168, 169, 163, 86, 337, +-84, 249, -257, -15, -277, -335, -90, -502, +237, -388, 469, -122, 417, 97, 172, 168, +-32, 143, 21, 101, 371, 96, 698, 140, +657, 202, 206, 126, -368, -136, -655, -366, +-466, -429, 43, -353, 572, -92, 788, 229, +571, 368, 126, 289, -268, 80, -421, -196, +-205, -362, 222, -316, 527, -114, 554, 131, +344, 297, 16, 289, -182, 101, -87, -195, +205, -398, 463, -400, 509, -170, 306, 216, +5, 472, -189, 420, -201, 128, -87, -275, +61, -514, 99, -422, 44, -145, 95, 114, +319, 264, 522, 238, 566, 66, 410, -130, +68, -247, -220, -260, -162, -156, 126, 53, +330, 277, 322, 323, 175, 161, -10, -61, +-123, -209, -131, -245, -50, -148, 91, -19, +243, 14, 365, -41, 427, -82, 362, -85, +171, -50, -6, -19, -4, 5, 156, 23, +324, 24, 365, 34, 205, 81, -83, 119, +-245, 95, -164, -4, 53, -114, 234, -199, +242, -202, 86, -106, 6, 6, 149, 56, +412, 30, 609, -74, 582, -138, 281, -91, +-130, 11, -409, 107, -398, 156, -136, 108, +249, 10, 574, -84, 613, -124, 291, -115, +-125, -102, -270, -94, -78, -76, 236, -43, +476, 55, 471, 147, 218, 159, -54, 101, +-122, -34, -24, -188, 56, -216, 72, -140, +112, -54, 188, -20, 297, -33, 428, -76, +464, -83, 270, 22, -54, 204, -249, 282, +-167, 220, 102, 60, 343, -170, 406, -322, +220, -303, -88, -208, -186, -22, -48, 171, +114, 184, 229, 64, 284, -59, 288, -170, +347, -179, 428, -66, 373, 96, 145, 167, +-112, 77, -266, -55, -219, -102, 41, -83, +340, 16, 441, 139, 273, 175, -17, 54, +-174, -167, -70, -332, 215, -330, 434, -183, +422, 53, 197, 214, -49, 212, -90, 69, +102, -149, 324, -242, 410, -78, 327, 124, +127, 263, -64, 341, -92, 201, 19, -145, +145, -433, 195, -531, 131, -406, -2, -96, +-78, 262, -17, 463, 183, 396, 391, 63, +461, -317, 388, -425, 250, -235, 100, 49, +4, 328, -16, 408, 43, 149, 124, -222, +189, -403, 220, -357, 160, -124, 0, 144, +-127, 281, -123, 254, 13, 54, 216, -244, +393, -369, 428, -265, 329, -57, 207, 172, +147, 326, 129, 258, 102, 13, 76, -182, +94, -162, 101, -31, 79, 41, 61, 9, +33, -78, -13, -169, 12, -160, 141, -62, +253, 43, 252, 76, 219, 0, 212, -64, +213, 23, 216, 143, 230, 184, 206, 142, +103, 36, -23, -141, -99, -315, -83, -326, +67, -170, 266, -34, 409, 65, 389, 162, +153, 145, -128, 16, -201, -22, -51, 12, +200, 36, 409, 66, 444, 67, 289, 10, +104, -61, 4, -160, -6, -242, 15, -222, +7, -130, 30, -55, 201, 70, 391, 226, +424, 239, 278, 83, 21, -65, -222, -142, +-228, -149, 62, -18, 408, 211, 528, 290, +359, 120, -4, -216, -283, -499, -254, -526, +35, -261, 374, 145, 555, 446, 466, 445, +227, 174, 44, -178, -14, -355, -35, -280, +-40, -68, -28, 134, 35, 271, 223, 283, +444, 181, 460, 51, 203, -74, -150, -266, +-300, -461, -140, -512, 176, -362, 396, -69, +430, 282, 321, 515, 154, 518, 57, 265, +97, -141, 145, -418, 127, -355, 93, -66, +98, 279, 103, 461, 69, 305, 31, -127, +30, -550, 68, -690, 119, -465, 160, -50, +229, 318, 261, 479, 242, 405, 253, 142, +257, -126, 158, -236, 20, -184, -52, -85, +-43, 27, 5, 130, 105, 165, 205, 121, +251, 52, 256, -92, 213, -298, 115, -417, +47, -294, 37, 3, 70, 290, 142, 369, +202, 141, 148, -227, 64, -383, 85, -214, +158, 163, 184, 497, 167, 534, 125, 208, +126, -198, 203, -447, 284, -495, 249, -340, +68, -72, -155, 92, -250, 117, -123, 82, +156, 17, 415, -29, 549, 61, 445, 194, +130, 225, -167, 126, -235, -91, -19, -314, +355, -315, 600, -92, 495, 184, 55, 297, +-387, 135, -500, -216, -205, -495, 278, -470, +575, -85, 510, 379, 208, 598, -67, 476, +-66, 93, 174, -349, 394, -525, 399, -368, +241, -56, 83, 207, -29, 298, -123, 165, +-203, -71, -228, -216, -85, -208, 218, -114, +512, 30, 573, 107, 361, 99, 77, 74, +-46, 33, 60, -34, 242, -48, 269, -42, +108, -49, -89, -28, -122, 4, 5, -47, +135, -130, 173, -154, 135, -68, 99, 91, +136, 246, 227, 294, 314, 167, 269, -121, +104, -420, -46, -546, -93, -365, -2, 31, +208, 457, 407, 675, 443, 492, 251, -8, +-39, -456, -242, -594, -273, -370, -122, 53, +175, 344, 429, 274, 409, -38, 191, -329, +52, -348, 36, -82, 92, 251, 209, 426, +282, 327, 203, 9, 74, -258, 27, -320, +27, -168, 16, 72, 24, 190, 29, 106, +51, -52, 117, -223, 185, -322, 217, -234, +210, -2, 177, 200, 164, 342, 154, 382, +124, 245, 90, -33, 80, -275, 58, -410, +42, -379, 93, -153, 153, 119, 160, 272, +145, 287, 71, 105, -10, -185, 26, -349, +185, -265, 295, -19, 248, 272, 83, 425, +-115, 301, -189, -51, 16, -353, 365, -414, +577, -233, 468, 69, 106, 327, -249, 320, +-353, 50, -154, -262, 198, -413, 441, -327, +410, -36, 164, 252, -74, 359, -168, 239, +-73, 12, 162, -161, 355, -162, 386, -25, +275, 108, 74, 107, -114, -8, -182, -194, +-66, -336, 135, -283, 281, -46, 330, 193, +277, 320, 145, 226, 67, -26, 81, -227, +70, -216, -52, -19, -184, 204, -191, 247, +6, 83, 330, -173, 551, -299, 486, -191, +170, 51, -153, 239, -167, 243, 87, 49, +296, -167, 280, -312, 103, -342, -85, -207, +-174, 21, -115, 190, 41, 287, 152, 297, +241, 228, 338, 91, 352, -86, 203, -232, +-48, -273, -218, -244, -143, -117, 145, 56, +431, 160, 487, 131, 296, 14, -14, -79, +-219, -51, -203, -11, -97, 6, -9, 16, +55, -60, 84, -168, 144, -101, 275, 54, +376, 132, 339, 156, 231, 145, 133, 30, +60, -99, 24, -130, -6, -76, -64, -7, +-84, 53, -43, 18, 32, -71, 72, -140, +59, -205, 47, -187, 93, 11, 199, 169, +299, 162, 335, 101, 312, 31, 210, -68, +74, -81, -51, 29, -152, 142, -168, 123, +-33, 37, 179, -41, 301, -102, 233, -144, +51, -143, -146, -147, -225, -162, -94, -168, +158, -101, 348, 39, 399, 182, 339, 238, +216, 216, 43, 135, -64, 30, -29, -78, +61, -85, 128, 14, 177, 91, 117, 57, +-117, -45, -334, -218, -286, -384, -38, -402, +234, -216, 443, 55, 507, 276, 359, 345, +140, 271, 56, 115, 77, -28, 43, -98, +-42, -54, -95, 37, -57, 66, -3, 3, +6, -60, 23, -138, 40, -232, 16, -244, +41, -140, 165, -11, 290, 123, 296, 208, +250, 208, 204, 100, 116, -84, -10, -204, +-94, -126, -70, 27, -8, 143, -22, 197, +-40, 138, 2, -81, 67, -315, 121, -371, +182, -182, 215, 109, 140, 361, 43, 419, +77, 175, 155, -252, 155, -521, 91, -462, +44, -118, 38, 297, 48, 497, 25, 345, +-50, 7, -131, -299, -148, -371, -47, -156, +170, 149, 308, 293, 273, 253, 207, 54, +203, -225, 166, -382, 44, -296, -49, -114, +-26, 60, 17, 206, 30, 266, 4, 194, +-102, 79, -223, -61, -173, -198, 94, -229, +368, -127, 413, -13, 260, 73, 90, 116, +40, 102, 94, 29, 178, -14, 183, -14, +19, -29, -201, -88, -285, -124, -209, -112, +-47, -43, 92, 28, 163, 50, 169, 28, +154, 15, 183, -13, 221, -22, 186, 31, +112, 91, 63, 72, 76, 47, 77, 19, +14, -65, -87, -166, -184, -210, -224, -232, +-159, -189, -4, -26, 198, 209, 379, 362, +462, 353, 327, 203, 15, -20, -290, -250, +-406, -353, -215, -296, 196, -134, 497, 9, +474, 73, 178, 90, -166, 86, -361, 15, +-291, -32, -23, 3, 239, 77, 329, 154, +202, 224, -23, 201, -163, 49, -168, -222, +-26, -475, 174, -554, 273, -412, 236, -100, +152, 277, 48, 500, -95, 477, -180, 291, +-83, 73, 84, -111, 193, -208, 181, -221, +23, -164, -162, -90, -190, -53, -54, -65, +149, -54, 279, -33, 235, -15, 54, 52, +-49, 145, -14, 115, 52, 39, 126, 10, +156, -25, 28, -44, -168, -5, -258, -17, +-169, -50, 17, -53, 171, -79, 225, -100, +216, -37, 164, 38, 85, 101, 35, 149, +-7, 94, -101, -85, -95, -205, 52, -216, +141, -172, 33, -52, -155, 139, -214, 262, +-98, 318, 130, 294, 367, 122, 401, -150, +169, -382, -175, -491, -362, -406, -231, -163, +71, 128, 293, 301, 340, 299, 202, 185, +-45, 41, -251, -50, -252, 2, -97, 98, +47, 128, 97, 63, 79, -117, 69, -340, +90, -421, 97, -318, 122, -56, 110, 235, +-13, 399, -156, 356, -157, 112, -10, -216, +159, -361, 247, -217, 199, 94, -16, 326, +-265, 307, -337, 63, -169, -215, 56, -380, +182, -281, 212, 37, 169, 295, 62, 313, +-32, 140, -35, -137, 35, -346, 57, -355, +60, -152, 114, 93, 110, 199, -27, 145, +-200, 39, -306, -39, -297, -10, -165, 112, +86, 228, 330, 237, 407, 130, 293, -31, +83, -176, -111, -340, -184, -463, -148, -411, +-63, -199, 22, 9, 94, 157, 97, 244, +35, 272, -30, 228, -87, 212, -113, 233, +-66, 194, 24, 67, 102, -84, 79, -244, +-22, -351, -84, -380, -70, -329, -1, -191, +107, 1, 205, 129, 224, 220, 148, 280, +31, 224, -104, 94, -206, 5, -232, -106, +-201, -202, -156, -153, -130, -5, -94, 90, +30, 170, 225, 214, 386, 138, 378, -44, +229, -236, 50, -356, -101, -300, -197, -118, +-249, 62, -275, 148, -225, 112, -100, 4, +51, -23, 145, 56, 118, 152, -5, 178, +-93, 130, -36, 50, 110, -48, 220, -154, +249, -187, 176, -168, 35, -109, -155, 8, +-314, 95, -325, 57, -206, -54, -44, -141, +145, -121, 254, -25, 152, 72, -94, 104, +-214, 70, -137, 34, 18, 72, 199, 139, +304, 175, 160, 93, -132, -136, -294, -351, +-220, -386, -41, -246, 161, 49, 283, 336, +204, 414, -59, 240, -340, -81, -457, -385, +-309, -487, -33, -354, 178, -33, 252, 330, +224, 527, 150, 432, 125, 149, 158, -152, +75, -314, -152, -283, -314, -114, -306, 45, +-169, 81, -37, -1, 4, -92, -15, -122, +-2, -65, 68, 15, 123, 94, 115, 144, +61, 107, -33, 9, -79, -56, -64, -101, +-62, -111, -57, -76, -18, -32, 24, 9, +32, 93, -31, 176, -107, 197, -95, 100, +6, -78, 81, -209, 88, -198, 20, -118, +-138, -58, -280, -43, -251, -81, -84, -146, +105, -81, 233, 108, 262, 271, 176, 338, +38, 293, -64, 137, -118, -34, -187, -208, +-282, -338, -303, -340, -162, -231, 53, -78, +204, 118, 194, 284, 70, 320, -39, 182, +-82, -47, -85, -255, -58, -346, -51, -246, +-59, -1, -38, 188, 43, 257, 121, 210, +96, 79, 2, -33, -98, -66, -206, -62, +-261, -16, -211, 21, -63, -9, 98, -90, +170, -163, 124, -201, 30, -141, -45, 4, +-90, 132, -96, 137, -41, 44, -5, -49, +-20, -60, -16, 29, 4, 194, -42, 295, +-112, 239, -94, 45, -15, -188, 20, -361, +15, -380, -39, -258, -139, -82, -201, 47, +-119, 95, 47, 96, 161, 119, 163, 161, +61, 200, -81, 204, -134, 134, -97, -39, +-51, -216, -78, -305, -148, -286, -135, -168, +-12, 20, 102, 160, 113, 216, 0, 189, +-139, 123, -190, 53, -87, -45, 42, -189, +43, -271, -21, -238, -43, -107, -40, 83, +-31, 247, -47, 252, -96, 118, -116, -32, +-31, -93, 93, -46, 125, 63, 30, 120, +-99, 70, -172, -84, -166, -279, -151, -390, +-146, -288, -130, -33, -68, 244, 46, 424, +184, 386, 252, 137, 189, -113, 26, -235, +-149, -205, -278, -52, -297, 122, -210, 156, +-82, 42, 33, -175, 87, -353, 29, -308, +-91, -30, -163, 283, -148, 448, -76, 357, +77, 45, 244, -293, 282, -392, 129, -228, +-122, 29, -298, 236, -312, 291, -224, 134, +-100, -106, -33, -270, -78, -277, -142, -113, +-81, 132, 63, 285, 146, 281, 148, 95, +133, -171, 60, -318, -47, -261, -120, -96, +-149, 90, -171, 225, -180, 226, -155, 75, +-113, -54, -77, -68, -37, -16, 1, 38, +43, 43, 69, -37, 38, -140, -29, -201, +-84, -172, -121, -75, -85, 39, 29, 148, +137, 242, 113, 253, -45, 161, -229, -15, +-305, -167, -255, -210, -138, -187, -19, -130, +31, -44, 17, -22, 32, 12, 70, 132, +62, 222, 4, 216, -37, 145, -54, -9, +-60, -169, -43, -262, -24, -257, -65, -149, +-145, 3, -249, 98, -308, 127, -226, 95, +-16, 46, 187, 32, 248, 88, 161, 172, +-5, 175, -173, 51, -206, -114, -82, -276, +63, -368, 126, -311, 107, -96, -23, 162, +-298, 303, -567, 280, -551, 157, -230, -36, +213, -173, 547, -148, 547, -28, 187, 82, +-234, 140, -429, 106, -342, 36, -71, -42, +192, -117, 219, -139, -11, -96, -320, -62, +-492, -46, -419, -32, -105, -11, 257, -14, +407, -10, 270, 60, -2, 160, -228, 216, +-269, 227, -135, 153, 55, 0, 142, -149, +63, -215, -98, -216, -250, -187, -344, -180, +-320, -170, -177, -95, 18, 50, 153, 194, +195, 311, 171, 351, 94, 248, -27, 60, +-111, -34, -137, -50, -136, -85, -164, -142, +-207, -199, -179, -284, -68, -316, 20, -227, +34, -55, 0, 124, -43, 286, -75, 394, +-39, 425, 54, 349, 62, 179, -70, -40, +-176, -248, -180, -422, -147, -505, -116, -446, +-44, -253, 47, -5, 94, 265, 114, 485, +123, 519, 14, 354, -203, 132, -349, -82, +-353, -260, -273, -361, -118, -356, 66, -271, +184, -129, 179, 53, 102, 248, 25, 380, +-2, 381, -8, 236, -57, 25, -153, -186, +-220, -334, -276, -361, -302, -261, -205, -132, +2, -3, 182, 145, 240, 268, 170, 315, +-6, 300, -220, 204, -271, 30, -115, -212, +58, -417, 60, -421, -104, -241, -252, -24, +-215, 195, -33, 341, 165, 349, 221, 255, +57, 99, -205, -98, -336, -272, -258, -395, +-69, -374, 97, -165, 170, 108, 141, 311, +23, 400, -164, 315, -318, 96, -357, -135, +-256, -283, -51, -331, 190, -244, 342, -48, +286, 189, 40, 391, -220, 452, -333, 281, +-274, -44, -145, -413, -34, -661, -22, -627, +-114, -326, -178, 106, -72, 525, 145, 745, +259, 702, 146, 402, -79, -35, -302, -384, +-404, -552, -257, -578, 46, -441, 256, -210, +273, 51, 124, 322, -116, 503, -341, 492, +-419, 276, -308, -67, -91, -312, 87, -366, +164, -255, 164, -23, 112, 185, 7, 272, +-98, 244, -195, 41, -286, -216, -291, -352, +-128, -338, 105, -149, 255, 171, 216, 402, +-5, 448, -252, 306, -354, 20, -288, -269, +-117, -414, 59, -370, 136, -179, 76, 55, +-6, 255, -44, 308, -84, 210, -108, 71, +-72, -70, -34, -184, -29, -186, -83, -118, +-206, -19, -293, 62, -208, 68, 29, 51, +265, 82, 333, 102, 176, 78, -141, 28, +-404, -21, -440, -60, -256, -74, -7, -77, +181, -83, 230, -81, 124, -31, -111, 27, +-337, 71, -382, 69, -225, 26, 33, 21, +246, 69, 261, 100, 103, 113, -85, 54, +-213, -69, -259, -150, -196, -169, -70, -140, +11, -38, 12, 58, -27, 115, -117, 108, +-165, 4, -92, -77, 8, -7, 37, 118, +6, 188, -63, 133, -109, -31, -73, -206, +-5, -308, 0, -288, -47, -121, -84, 80, +-85, 228, -89, 299, -77, 296, -42, 240, +-39, 168, -106, 42, -183, -120, -184, -298, +-84, -475, 61, -541, 163, -377, 96, -71, +-98, 261, -200, 545, -146, 671, -36, 525, +53, 160, 44, -242, -71, -460, -179, -405, +-152, -138, -77, 163, -58, 305, -52, 167, +-45, -149, -89, -433, -153, -527, -162, -367, +-93, 10, 36, 459, 183, 804, 241, 833, +122, 479, -108, -90, -275, -630, -312, -929, +-225, -778, -51, -240, 48, 366, -70, 739, +-253, 695, -321, 234, -198, -341, 87, -654, +406, -515, 534, -46, 349, 460, -44, 700, +-453, 529, -682, 44, -598, -441, -280, -681, +94, -591, 369, -235, 388, 175, 114, 452, +-237, 548, -407, 434, -296, 169, -41, -106, +177, -267, 226, -304, 107, -262, -79, -193, +-176, -106, -161, -15, -163, 118, -201, 261, +-176, 319, -109, 257, -69, 106, 12, -99, +111, -242, 70, -231, -55, -93, -132, 50, +-138, 114, -109, 49, -46, -145, 28, -328, +75, -281, 64, -4, 24, 387, -43, 694, +-155, 706, -302, 423, -422, -46, -407, -614, +-217, -998, 42, -969, 220, -555, 295, 99, +320, 728, 230, 998, 59, 821, -74, 356, +-186, -127, -366, -441, -478, -527, -415, -393, +-268, -150, -97, 40, 131, 140, 306, 118, +273, 39, 72, 18, -119, 39, -195, 71, +-159, 110, -56, 64, 54, -25, 84, -66, +-32, -77, -217, -76, -280, -61, -255, -56, +-197, 4, -79, 123, 77, 226, 150, 244, +100, 128, 17, -118, -28, -353, -71, -439, +-145, -293, -189, 12, -150, 312, -89, 476, +-68, 451, -52, 257, -51, 34, -126, -158, +-143, -369, -7, -563, 177, -553, 220, -286, +107, 142, -96, 559, -312, 790, -432, 674, +-361, 227, -152, -324, 37, -686, 163, -730, +203, -443, 94, 54, -101, 495, -228, 627, +-193, 442, -38, 85, 130, -233, 176, -365, +44, -313, -195, -173, -364, -20, -371, 64, +-189, 103, 26, 145, 106, 144, 73, 102, +6, 123, -35, 125, -34, 22, -40, -110, +-110, -233, -205, -338, -220, -306, -112, -115, +82, 159, 244, 421, 290, 555, 150, 489, +-130, 263, -414, -88, -582, -471, -617, -763, +-481, -827, -159, -590, 235, -119, 555, 473, +717, 1008, 652, 1163, 308, 861, -200, 272, +-704, -450, -1002, -1016, -897, -1094, -478, -719, +43, -122, 478, 445, 708, 731, 609, 654, +242, 353, -160, -34, -452, -347, -602, -444, +-515, -344, -224, -184, 37, 16, 128, 221, +93, 335, 41, 369, 31, 384, 71, 320, +122, 115, 94, -230, -62, -553, -294, -686, +-440, -598, -438, -290, -262, 161, 4, 520, +215, 677, 247, 619, 99, 346, -111, -26, +-220, -337, -141, -532, 1, -537, 58, -321, +11, 35, -114, 387, -216, 624, -143, 587, +29, 209, 67, -242, -66, -498, -253, -627, +-299, -558, -156, -200, 75, 233, 178, 572, +52, 742, -181, 581, -320, 144, -242, -363, +-7, -716, 210, -711, 239, -330, 112, 209, +-20, 644, -116, 753, -208, 509, -304, 3, +-351, -495, -333, -692, -208, -595, -7, -315, +193, 127, 292, 492, 238, 639, 38, 610, +-198, 325, -395, -182, -492, -625, -332, -795, +73, -586, 498, -65, 664, 509, 440, 819, +-92, 705, -700, 267, -1019, -235, -867, -570, +-376, -580, 134, -335, 460, -2, 570, 263, +527, 325, 332, 242, 31, 137, -279, -16, +-504, -117, -535, -109, -376, -80, -169, -72, +-45, -135, 32, -199, 95, -45, 167, 242, +241, 495, 161, 632, -123, 451, -427, -66, +-525, -589, -443, -900, -201, -872, 123, -448, +342, 192, 408, 716, 342, 886, 141, 665, +-123, 247, -364, -113, -540, -237, -539, -191, +-364, -184, -133, -307, 116, -464, 328, -474, +359, -193, 152, 253, -115, 605, -350, 690, +-432, 471, -277, 10, 9, -449, 261, -595, +399, -314, 321, 160, -15, 538, -396, 598, +-639, 228, -671, -378, -431, -824, 32, -884, +419, -476, 461, 207, 248, 748, -26, 910, +-245, 709, -312, 234, -148, -231, 37, -443, +47, -383, -64, -193, -124, -50, -182, -39, +-315, -80, -327, -121, -152, -118, 76, -17, +279, 180, 381, 386, 233, 464, -115, 258, +-412, -151, -528, -493, -420, -556, -153, -309, +104, 121, 211, 491, 235, 657, 166, 545, +-28, 144, -243, -372, -338, -723, -294, -771, +-164, -432, 27, 188, 157, 697, 115, 799, +-51, 512, -180, -64, -231, -623, -220, -820, +-92, -596, 33, -64, 89, 583, 87, 965, +6, 888, -161, 417, -273, -275, -258, -860, +-110, -1002, 121, -695, 275, -88, 215, 559, +-39, 895, -336, 723, -551, 179, -559, -457, +-359, -865, -6, -789, 427, -240, 695, 472, +621, 1012, 213, 1111, -366, 676, -882, -66, +-950, -809, -518, -1300, 57, -1220, 477, -573, +596, 285, 334, 1050, -142, 1422, -438, 1115, +-418, 266, -198, -698, 81, -1295, 228, -1175, +140, -405, -31, 512, -190, 1073, -388, 1013, +-473, 370, -366, -534, -91, -1115, 260, -1005, +538, -318, 565, 634, 274, 1389, -209, 1404, +-624, 654, -718, -441, -550, -1395, -272, -1697, +66, -1121, 301, -74, 298, 876, 188, 1344, +72, 1150, -77, 475, -131, -216, -100, -625, +-90, -648, -87, -336, -54, 42, -123, 245, +-266, 273, -357, 85, -339, -242, -127, -392, +189, -270, 374, -25, 283, 306, 37, 551, +-173, 538, -244, 337, -162, -22, -78, -462, +-76, -692, -133, -625, -177, -324, -191, 130, +-163, 492, -126, 598, -1, 520, 216, 257, +340, -80, 243, -264, -18, -290, -331, -278, +-622, -212, -640, -102, -309, -7, 108, 82, +404, 211, 527, 299, 441, 240, 141, 48, +-211, -197, -543, -405, -725, -383, -647, -111, +-322, 179, 104, 359, 438, 448, 538, 385, +408, 208, 173, -18, -81, -269, -305, -437, +-470, -432, -508, -330, -415, -161, -232, 68, +13, 239, 192, 282, 213, 291, 135, 252, +166, 106, 223, -41, 136, -84, -84, -87, +-341, -27, -550, 87, -610, 82, -461, -79, +-143, -246, 242, -330, 509, -225, 571, 38, +411, 280, 31, 394, -397, 351, -635, 123, +-602, -185, -409, -412, -157, -424, 90, -231, +380, 81, 564, 411, 454, 612, 94, 529, +-342, 194, -700, -221, -819, -539, -546, -686, +-40, -614, 411, -287, 636, 194, 564, 605, +239, 789, -208, 610, -564, 125, -605, -363, +-283, -563, 97, -416, 248, -93, 66, 149, +-292, 225, -532, 151, -351, 2, 168, -113, +539, -128, 506, -58, 195, 65, -175, 171, +-436, 239, -424, 210, -228, 20, -103, -217, +-111, -335, -152, -316, -48, -140, 148, 135, +223, 351, 117, 402, -28, 272, -193, -12, +-335, -292, -326, -395, -148, -302, 67, -78, +207, 214, 255, 358, 170, 258, -60, 97, +-362, -26, -491, -105, -324, -80, -64, -52, +159, -71, 259, -83, 184, -109, -11, -96, +-164, 24, -252, 128, -277, 189, -257, 181, +-171, 33, 49, -147, 295, -200, 351, -96, +163, 90, -130, 181, -374, 193, -391, 163, +-186, 33, 14, -86, 57, -121, -8, -172, +-67, -186, -119, -159, -94, -162, -27, -94, +-27, 92, -117, 262, -167, 349, -76, 332, +95, 183, 241, -49, 238, -194, 56, -168, +-164, -61, -266, 27, -262, 4, -235, -169, +-216, -271, -211, -202, -188, -41, -118, 200, +61, 404, 208, 383, 209, 176, 147, -125, +133, -364, 125, -371, 78, -179, -56, 60, +-336, 266, -582, 408, -610, 437, -387, 215, +11, -190, 398, -513, 543, -592, 343, -361, +-56, 78, -389, 422, -423, 518, -216, 343, +59, -13, 218, -324, 133, -449, -113, -343, +-199, -22, -97, 301, -45, 482, -52, 462, +-95, 205, -163, -113, -144, -290, 7, -324, +120, -204, 81, -13, -31, 113, -143, 142, +-167, 29, -116, -212, -80, -389, -136, -353, +-160, -29, -20, 405, 226, 651, 378, 625, +303, 361, 0, -21, -391, -235, -644, -320, +-663, -447, -450, -466, -30, -314, 485, -135, +794, 134, 676, 426, 229, 496, -358, 358, +-786, 81, -836, -348, -485, -627, -2, -495, +351, -92, 520, 395, 498, 801, 260, 800, +-114, 379, -471, -149, -652, -585, -507, -783, +-122, -607, 267, -221, 476, 118, 396, 310, +112, 339, -189, 207, -416, 26, -584, -52, +-522, 12, -177, 112, 266, 191, 562, 211, +574, 85, 294, -151, -110, -314, -366, -286, +-406, -79, -346, 123, -292, 177, -225, 102, +-103, -37, 43, -161, 191, -174, 259, -121, +174, -21, 38, 116, -15, 222, -87, 269, +-155, 233, -226, 47, -331, -137, -269, -173, +56, -110, 287, -4, 222, 105, 127, 84, +62, -26, -80, -73, -238, -107, -409, -231, +-589, -271, -524, -121, -64, 58, 478, 203, +783, 358, 679, 414, 193, 350, -372, 195, +-646, -73, -594, -327, -327, -422, 41, -413, +311, -248, 338, 75, 131, 315, -186, 312, +-452, 126, -459, -154, -180, -335, 176, -243, +419, 42, 376, 295, 85, 444, -241, 429, +-398, 211, -295, -134, 31, -436, 308, -523, +334, -328, 115, 2, -261, 324, -560, 470, +-561, 247, -345, -195, -64, -472, 238, -462, +408, -164, 407, 283, 347, 562, 136, 566, +-217, 371, -443, 24, -441, -289, -365, -447, +-141, -483, 207, -370, 411, -109, 314, 159, +-36, 351, -429, 409, -566, 306, -345, 60, +24, -211, 322, -323, 442, -198, 323, 49, +30, 268, -205, 279, -282, 54, -301, -211, +-256, -364, -158, -355, -79, -103, -22, 268, +105, 487, 224, 465, 260, 253, 229, -75, +51, -313, -270, -348, -539, -282, -569, -212, +-331, -121, 67, 6, 427, 158, 553, 273, +384, 314, 3, 274, -341, 152, -455, -25, +-330, -134, -118, -166, 47, -200, 95, -195, +77, -89, 33, -8, -16, -15, -35, -41, +-35, -32, -43, 67, -88, 241, -124, 333, +-82, 316, -1, 170, 99, -130, 194, -380, +149, -398, -152, -280, -492, -66, -561, 176, +-273, 269, 185, 170, 537, 13, 568, -94, +299, -92, -112, 21, -449, 176, -491, 238, +-275, 176, -34, 28, 83, -181, 39, -361, +-111, -363, -167, -171, -37, 136, 111, 354, +213, 334, 238, 149, 138, -83, -48, -269, +-186, -278, -234, -133, -236, 97, -215, 310, +-175, 330, -84, 150, 101, -44, 254, -145, +218, -134, 69, -80, -101, -47, -250, -52, +-247, -109, -109, -169, 7, -127, 58, -19, +128, 115, 131, 235, 48, 275, -60, 226, +-191, 139, -269, 30, -162, -52, 37, -73, +143, -58, 122, -123, -37, -284, -223, -371, +-227, -243, -95, 55, 42, 375, 174, 493, +231, 312, 138, -41, -9, -313, -157, -380, +-273, -267, -320, 20, -228, 385, -32, 533, +170, 400, 287, 95, 248, -302, 79, -571, +-143, -540, -324, -277, -322, 143, -101, 454, +104, 435, 77, 213, -26, -99, -25, -401, +16, -429, 43, -182, 114, 152, 87, 439, +-97, 540, -224, 356, -194, 0, -95, -294, +76, -363, 209, -242, 103, -24, -162, 126, +-361, 63, -320, -153, -43, -351, 247, -383, +347, -134, 199, 277, -46, 619, -170, 688, +-112, 415, -21, 27, -4, -243, -123, -390, +-310, -372, -349, -241, -122, -139, 178, -64, +365, 37, 417, 129, 264, 186, -98, 177, +-419, 112, -488, -27, -348, -184, -99, -212, +167, -56, 281, 199, 252, 390, 147, 312, +-8, 63, -149, -195, -189, -397, -178, -347, +-105, -45, 52, 156, 94, 185, -64, 115, +-156, -61, -102, -259, -36, -289, 72, -69, +156, 301, 73, 596, -61, 632, -113, 256, +-57, -377, 96, -836, 205, -864, 40, -412, +-285, 345, -480, 861, -362, 859, 40, 439, +426, -238, 443, -768, 76, -749, -347, -335, +-488, 158, -211, 491, 336, 505, 685, 279, +485, 31, -118, -163, -699, -279, -917, -272, +-614, -112, 11, 86, 541, 186, 668, 149, +466, 20, 184, -101, -28, -109, -187, -59, +-326, 29, -435, 163, -474, 216, -306, 103, +80, -70, 421, -238, 505, -332, 321, -236, +-19, 49, -321, 338, -370, 460, -214, 312, +-10, -36, 178, -315, 239, -340, 46, -240, +-209, -108, -308, 36, -236, 140, -24, 200, +204, 219, 266, 132, 170, 51, 63, 38, +-16, -28, -139, -136, -268, -201, -286, -265, +-118, -220, 148, -12, 325, 189, 194, 272, +-215, 251, -573, 102, -534, -50, -36, -83, +614, -87, 897, -101, 578, -16, -75, 75, +-594, 74, -759, 53, -615, -4, -280, -148, +102, -193, 437, -104, 611, 16, 427, 190, +-10, 305, -428, 161, -634, -53, -440, -199, +96, -351, 507, -329, 566, 4, 374, 370, +-13, 591, -440, 584, -641, 206, -569, -404, +-264, -833, 186, -849, 506, -400, 515, 325, +326, 859, 53, 821, -240, 329, -377, -277, +-295, -665, -181, -591, -88, -155, 19, 265, +117, 502, 177, 474, 145, 126, 10, -315, +-133, -503, -184, -342, -65, 65, 187, 445, +352, 567, 203, 338, -190, -163, -528, -651, +-564, -818, -259, -601, 200, -60, 447, 595, +356, 1049, 81, 1035, -161, 505, -199, -318, +-50, -1002, 47, -1175, 78, -724, 134, 45, +41, 747, -171, 1114, -233, 880, -174, 105, +-123, -652, -38, -1043, 111, -961, 219, -341, +198, 522, 32, 1076, -188, 1035, -310, 423, +-236, -403, -35, -940, 195, -925, 323, -469, +262, 212, 124, 827, 29, 983, -115, 540, +-340, -126, -486, -653, -436, -851, -188, -600, +202, -79, 510, 373, 540, 661, 300, 641, +-79, 242, -473, -284, -636, -622, -384, -647, +143, -341, 646, 160, 832, 612, 453, 806, +-336, 682, -955, 224, -984, -405, -507, -845, +174, -933, 755, -716, 858, -132, 449, 592, +2, 988, -286, 900, -520, 432, -534, -257, +-230, -824, 88, -933, 293, -481, 389, 257, +272, 844, 2, 932, -258, 399, -411, -429, +-348, -923, -76, -829, 209, -247, 317, 502, +251, 892, 120, 690, -12, 140, -151, -471, +-283, -773, -320, -578, -193, -127, 6, 283, +233, 502, 433, 409, 419, 135, 116, -64, +-281, -104, -534, -73, -491, -24, -185, -9, +162, -78, 338, -203, 266, -257, 19, -165, +-140, 112, -79, 411, 70, 464, 143, 234, +94, -118, -42, -446, -126, -484, -103, -203, +-78, 124, -124, 366, -132, 465, -103, 267, +-88, -64, 14, -317, 176, -491, 239, -460, +224, -92, 163, 337, 4, 612, -234, 683, +-405, 352, -369, -275, -53, -674, 395, -760, +615, -605, 345, -65, -226, 575, -703, 810, +-784, 679, -353, 298, 306, -269, 659, -680, +566, -698, 191, -418, -208, 93, -273, 610, +-52, 780, 45, 512, -4, -19, -64, -605, +-152, -879, -206, -638, -119, -128, 5, 366, +118, 756, 235, 801, 198, 474, -19, 8, +-145, -489, -148, -787, -157, -591, -79, -166, +63, 159, 88, 385, 73, 408, 99, 196, +85, 24, 31, -90, -49, -193, -158, -119, +-158, 69, -79, 131, -67, 143, -50, 128, +96, -28, 198, -196, 157, -260, 68, -327, +-126, -237, -369, 96, -373, 360, -121, 422, +223, 366, 494, 83, 439, -289, 68, -389, +-268, -208, -392, 33, -287, 248, 23, 303, +313, 146, 272, -88, -53, -262, -379, -338, +-485, -247, -277, -34, 167, 142, 504, 215, +482, 240, 210, 211, -114, 159, -305, 37, +-240, -172, -100, -258, -26, -98, -6, 52, +-56, 51, -52, -16, 153, -77, 335, -102, +231, -30, -114, 76, -453, 130, -534, 88, +-254, -6, 177, -40, 500, 59, 586, 164, +331, 157, -173, 46, -534, -176, -559, -487, +-372, -557, -31, -196, 410, 352, 650, 737, +500, 756, 101, 315, -299, -308, -586, -679, +-643, -669, -345, -386, 165, 86, 551, 488, +672, 594, 437, 397, -113, -1, -586, -414, +-638, -531, -327, -305, 90, 10, 379, 226, +399, 291, 187, 139, -19, -35, -99, -5, +-104, 102, -67, 109, 19, 118, 85, 79, +74, -123, -40, -358, -175, -435, -205, -302, +-185, 40, -197, 375, -130, 479, 8, 351, +176, 110, 418, -194, 554, -452, 386, -519, +56, -328, -268, 71, -532, 570, -623, 836, +-354, 654, 146, 244, 499, -212, 502, -743, +162, -1046, -407, -861, -782, -364, -559, 276, +107, 903, 710, 1086, 924, 670, 603, -21, +-101, -543, -664, -682, -720, -473, -413, -74, +46, 358, 475, 602, 578, 501, 267, 104, +-189, -346, -552, -670, -633, -704, -380, -357, +31, 169, 389, 558, 597, 721, 580, 559, +303, 101, -102, -379, -423, -688, -593, -720, +-481, -311, 23, 346, 565, 820, 691, 867, +374, 507, -227, -86, -815, -616, -976, -883, +-554, -837, 224, -466, 943, 170, 1138, 744, +708, 974, -24, 789, -700, 196, -1073, -551, +-930, -994, -256, -978, 574, -454, 1098, 419, +1072, 1070, 427, 1137, -507, 701, -1124, -100, +-1098, -898, -491, -1258, 386, -969, 967, -170, +905, 663, 349, 1082, -337, 979, -811, 398, +-812, -390, -339, -1012, 331, -1127, 824, -586, +895, 250, 542, 862, -51, 1126, -620, 900, +-880, 198, -748, -522, -360, -919, 125, -967, +563, -635, 683, -17, 444, 616, 82, 925, +-271, 786, -489, 295, -361, -378, -5, -944, +340, -1051, 541, -589, 449, 324, 31, 1203, +-479, 1471, -784, 931, -717, -175, -283, -1251, +325, -1603, 719, -1112, 701, -126, 426, 845, +42, 1324, -393, 1153, -597, 480, -420, -417, +-75, -1039, 254, -1078, 468, -580, 402, 175, +86, 776, -280, 881, -544, 509, -584, -42, +-291, -447, 172, -604, 517, -464, 668, -99, +593, 240, 162, 430, -390, 470, -657, 210, +-551, -195, -213, -409, 183, -378, 383, -215, +283, 33, 67, 278, -74, 384, -147, 281, +-177, 105, -122, -86, 44, -271, 232, -298, +297, -184, 174, -127, -65, -50, -271, 102, +-312, 245, -178, 376, 5, 358, 93, 32, +118, -342, 172, -495, 226, -384, 117, -31, +-89, 409, -164, 642, -172, 509, -208, -1, +-122, -642, 11, -957, 63, -677, 170, -16, +326, 667, 290, 1020, 86, 812, -128, 173, +-326, -468, -443, -828, -323, -770, -51, -314, +166, 310, 330, 782, 428, 851, 271, 410, +1, -308, -119, -877, -198, -969, -303, -539, +-276, 157, -133, 697, 73, 851, 295, 609, +322, 93, 73, -430, -164, -619, -192, -403, +-68, 30, 85, 384, 129, 433, 26, 197, +-51, -136, -61, -415, -65, -447, 8, -224, +129, 69, 93, 302, -53, 368, -142, 190, +-189, -38, -144, -133, 66, -101, 244, -20, +205, 34, 15, 14, -152, -15, -175, -13, +20, 39, 251, 93, 269, 84, 95, -7, +-154, -108, -375, -163, -377, -181, -191, -168, +37, -54, 271, 86, 385, 195, 250, 297, +15, 290, -150, 97, -230, -114, -216, -236, +-55, -231, 159, -100, 274, 51, 233, 124, +82, 127, -154, 31, -378, -114, -429, -179, +-228, -137, 142, -50, 427, 114, 440, 263, +276, 204, 25, 36, -261, -11, -410, -9, +-355, -15, -192, -39, 40, -212, 245, -430, +322, -383, 341, -68, 332, 377, 118, 797, +-224, 881, -459, 440, -540, -271, -411, -899, +-21, -1191, 385, -927, 541, -91, 404, 809, +57, 1222, -286, 997, -389, 263, -233, -574, +56, -949, 297, -714, 325, -109, 155, 453, +-83, 598, -303, 320, -365, -89, -217, -370, +17, -337, 187, -43, 271, 265, 253, 396, +117, 256, -70, -98, -230, -416, -295, -534, +-170, -390, 55, 3, 210, 501, 237, 810, +130, 700, -85, 194, -216, -423, -112, -884, +115, -972, 190, -583, 66, 148, -44, 859, +-84, 1220, -169, 1008, -174, 220, -60, -797, +-32, -1401, -10, -1227, 170, -421, 312, 560, +262, 1197, 124, 1157, -50, 557, -223, -217, +-260, -764, -229, -896, -193, -619, -65, -97, +114, 412, 201, 679, 232, 630, 246, 281, +152, -156, -42, -429, -216, -525, -298, -476, +-209, -195, 4, 250, 149, 603, 166, 627, +117, 308, -15, -202, -149, -654, -148, -771, +-70, -448, 14, 132, 222, 724, 400, 985, +264, 677, -77, 9, -357, -623, -504, -947, +-440, -762, -133, -205, 247, 365, 492, 720, +527, 720, 371, 304, 48, -281, -342, -700, +-549, -751, -445, -396, -124, 277, 234, 894, +436, 989, 317, 485, 1, -245, -271, -843, +-366, -1043, -215, -697, 166, 55, 519, 777, +540, 1093, 231, 814, -203, 37, -586, -792, +-688, -1179, -426, -971, -19, -223, 356, 722, +591, 1217, 513, 983, 211, 316, -73, -455, +-262, -902, -333, -700, -209, -107, -37, 383, +51, 533, 133, 286, 193, -168, 131, -467, +-55, -412, -275, -135, -352, 168, -159, 330, +184, 271, 423, 111, 433, 36, 171, 10, +-235, 11, -504, 18, -459, -99, -114, -251, +357, -200, 649, -7, 557, 200, 77, 268, +-514, 96, -821, -163, -649, -328, -117, -316, +463, -28, 793, 323, 708, 432, 238, 294, +-331, 14, -655, -319, -616, -481, -327, -342, +100, 36, 466, 444, 594, 619, 469, 414, +142, -61, -274, -517, -568, -689, -639, -505, +-441, -38, 46, 428, 577, 629, 758, 509, +539, 136, 111, -286, -386, -494, -688, -447, +-572, -209, -214, 121, 148, 346, 407, 385, +450, 311, 288, 120, 102, -142, -109, -376, +-311, -475, -302, -332, -124, 54, 48, 486, +215, 664, 269, 424, 54, -64, -243, -543, +-339, -788, -197, -623, 84, -64, 294, 564, +289, 884, 147, 710, -17, 159, -170, -467, +-198, -812, -101, -710, -10, -221, 72, 431, +166, 858, 160, 743, 17, 241, -130, -363, +-164, -862, -108, -917, -33, -406, 29, 289, +43, 772, 4, 830, -20, 413, 17, -201, +80, -584, 122, -584, 133, -270, 61, 188, +-43, 513, -87, 486, -60, 162, -26, -236, +-4, -482, 8, -405, -68, -74, -179, 209, +-180, 291, -113, 185, -3, -35, 187, -187, +356, -140, 344, -25, 189, 43, -12, 103, +-190, 178, -258, 216, -215, 211, -155, 109, +-101, -136, -43, -438, 42, -584, 140, -458, +176, -84, 101, 415, -8, 794, -32, 764, +-38, 328, -52, -229, 7, -622, 68, -703, +69, -463, 47, -84, -14, 259, -150, 461, +-215, 416, -120, 187, 28, -40, 185, -173, +304, -166, 198, -21, -85, 145, -277, 163, +-289, -17, -190, -255, -21, -381, 140, -346, +200, -82, 186, 327, 198, 544, 227, 436, +139, 123, -118, -254, -372, -443, -463, -322, +-323, -38, -38, 216, 209, 316, 322, 222, +304, 25, 199, -173, 63, -286, -95, -258, +-245, -116, -281, 46, -185, 168, 9, 232, +260, 210, 354, 80, 181, -69, -70, -175, +-216, -231, -265, -130, -196, 139, -21, 341, +139, 326, 204, 111, 167, -219, 51, -493, +-104, -473, -248, -146, -255, 242, -32, 490, +235, 458, 312, 86, 241, -376, 55, -550, +-213, -355, -285, 76, -93, 561, 22, 763, +9, 511, 39, -9, 52, -490, -8, -752, +-11, -688, -46, -286, -208, 199, -232, 443, +-7, 455, 287, 305, 524, 34, 544, -141, +199, -99, -337, 2, -693, 53, -710, 11, +-380, -130, 154, -242, 585, -179, 684, 60, +407, 342, -89, 449, -475, 271, -551, -162, +-344, -592, -16, -691, 292, -424, 453, 79, +391, 623, 233, 848, 50, 596, -225, 60, +-484, -493, -516, -786, -298, -609, 53, -106, +421, 393, 547, 650, 302, 574, -104, 230, +-411, -206, -458, -509, -187, -547, 230, -357, +480, -46, 420, 218, 117, 313, -271, 272, +-475, 204, -354, 134, -82, 58, 164, -23, +297, -143, 226, -289, 31, -316, -89, -169, +-87, 62, -73, 246, -76, 304, -80, 229, +-42, 64, 99, -130, 253, -258, 235, -217, +57, -64, -144, 63, -286, 134, -280, 95, +-110, -25, 58, -85, 117, -53, 103, -8, +66, 41, 57, 106, 98, 115, 103, 98, +53, 95, -19, 43, -114, -45, -193, -107, +-157, -175, -40, -251, 16, -209, 7, -67, +-3, 62, -16, 181, 29, 258, 126, 195, +170, 79, 139, 7, 57, -50, -63, -79, +-118, -10, -82, 64, -39, 29, -38, -99, +-86, -243, -157, -309, -124, -193, 17, 72, +169, 313, 276, 371, 220, 300, -7, 120, +-209, -167, -238, -376, -98, -356, 141, -175, +288, 94, 142, 373, -120, 420, -255, 183, +-255, -95, -81, -270, 191, -346, 247, -280, +65, -48, -98, 174, -162, 262, -156, 252, +-4, 107, 198, -140, 220, -252, 106, -153, +5, 2, -111, 154, -236, 257, -207, 202, +-29, 51, 104, -82, 158, -194, 134, -256, +10, -205, -143, -94, -181, 35, -65, 178, +66, 261, 113, 192, 112, 71, 66, -43, +-26, -156, -76, -146, -53, -15, -30, 87, +-36, 94, -32, 20, -32, -88, -68, -139, +-47, -110, 76, -42, 190, 93, 170, 228, +31, 249, -149, 160, -241, -39, -138, -285, +109, -419, 269, -338, 135, -94, -193, 217, +-377, 441, -270, 437, 68, 257, 491, 11, +642, -252, 281, -407, -287, -329, -640, -90, +-684, 153, -391, 297, 198, 238, 638, 6, +618, -210, 310, -286, -98, -214, -435, -22, +-467, 202, -213, 355, 88, 373, 312, 245, +383, 37, 203, -193, -103, -375, -343, -475, +-445, -432, -348, -227, -43, 104, 278, 448, +401, 646, 340, 600, 180, 280, -31, -196, +-131, -566, -121, -623, -150, -405, -176, -44, +-112, 336, -31, 495, 12, 343, 89, 36, +115, -260, -19, -399, -119, -305, -49, -17, +88, 298, 188, 446, 217, 339, 87, 74, +-160, -217, -316, -409, -305, -374, -163, -137, +86, 152, 335, 361, 416, 374, 254, 174, +-42, -98, -319, -319, -468, -392, -386, -286, +-82, -59, 274, 185, 451, 351, 335, 355, +72, 146, -167, -127, -299, -261, -259, -217, +-26, -25, 205, 231, 248, 381, 142, 260, +-49, -36, -247, -343, -296, -528, -148, -488, +65, -249, 240, 96, 290, 395, 128, 532, +-107, 458, -239, 247, -255, -11, -151, -250, +45, -363, 195, -307, 271, -147, 256, 56, +102, 206, -69, 221, -188, 145, -338, 27, +-391, -132, -206, -249, 85, -269, 340, -213, +492, -50, 408, 180, 73, 325, -296, 355, +-539, 261, -536, 50, -189, -158, 274, -276, +571, -241, 592, -94, 297, 111, -210, 262, +-599, 202, -653, -81, -431, -369, -7, -457, +430, -310, 605, 50, 489, 426, 202, 585, +-126, 486, -381, 172, -451, -226, -336, -488, +-110, -429, 188, -116, 414, 189, 405, 322, +150, 208, -248, -70, -520, -284, -483, -291, +-178, -184, 220, -8, 526, 192, 601, 295, +401, 265, 57, 155, -319, -12, -619, -135, +-642, -147, -349, -113, 96, -64, 455, -6, +579, 52, 375, 91, -46, 81, -383, -20, +-481, -178, -293, -263, 102, -219, 421, -26, +496, 236, 311, 383, -70, 373, -422, 214, +-484, -57, -277, -317, -21, -359, 162, -217, +200, 9, 117, 225, 73, 254, 124, 109, +152, -88, 26, -253, -195, -301, -362, -179, +-347, 32, -100, 227, 265, 340, 509, 298, +416, 108, 73, -76, -253, -156, -401, -145, +-323, -110, -78, -87, 163, -84, 229, -49, +119, 25, -53, 90, -173, 108, -170, 87, +-52, 22, 113, -8, 224, -36, 235, -100, +145, -73, -36, 27, -209, 87, -288, 86, +-242, 50, -92, -62, 97, -141, 253, -89, +265, -3, 93, 84, -128, 170, -207, 196, +-144, 76, -52, -130, 100, -270, 214, -290, +125, -113, -67, 168, -168, 288, -184, 179, +-158, 0, 7, -140, 175, -164, 170, 2, +115, 178, 48, 196, -48, 84, -87, -112, +-29, -333, 16, -327, -45, -38, -145, 266, +-201, 379, -142, 314, 14, 30, 183, -329, +316, -394, 270, -167, 50, 101, -158, 298, +-262, 311, -242, 102, -96, -194, 105, -364, +164, -320, 62, -85, -40, 180, -76, 318, +20, 272, 152, 80, 158, -16, -1, 16, +-201, 41, -240, -12, -118, -132, 37, -268, +118, -319, 89, -199, -6, -11, -97, 162, +-61, 305, 76, 338, 192, 215, 196, 47, +67, -122, -100, -264, -206, -216, -183, -18, +-66, 86, 21, 111, 36, 107, -38, 13, +-123, -118, -100, -180, 57, -156, 210, -12, +224, 147, 151, 226, 4, 168, -196, 18, +-243, -122, -58, -145, 145, -34, 205, 74, +141, 103, -98, 44, -390, -59, -437, -173, +-215, -179, 93, -33, 386, 145, 555, 268, +445, 217, 102, -8, -250, -257, -493, -378, +-513, -205, -258, 168, 101, 440, 317, 435, +323, 174, 224, -263, 75, -596, -100, -570, +-264, -209, -327, 318, -187, 694, 89, 688, +374, 301, 487, -278, 293, -724, -155, -735, +-560, -377, -651, 124, -475, 538, -59, 686, +491, 490, 792, 64, 659, -356, 236, -595, +-256, -513, -597, -99, -549, 344, -206, 555, +92, 479, 248, 138, 241, -344, 51, -627, +-183, -616, -284, -389, -183, 71, 21, 545, +267, 787, 438, 698, 392, 323, 152, -217, +-196, -644, -439, -720, -443, -475, -229, -43, +93, 358, 325, 492, 327, 322, 43, 39, +-292, -206, -397, -321, -267, -237, 12, -31, +328, 181, 514, 329, 438, 320, 175, 163, +-142, -86, -475, -355, -594, -447, -368, -276, +19, 0, 333, 314, 465, 507, 397, 414, +108, 58, -244, -302, -421, -521, -396, -513, +-216, -204, 64, 226, 361, 491, 455, 461, +267, 202, -12, -176, -215, -401, -262, -283, +-157, -35, 11, 207, 109, 350, 88, 242, +-17, -44, -178, -273, -258, -358, -155, -327, +104, -106, 365, 225, 415, 463, 259, 460, +0, 240, -310, -83, -516, -392, -451, -544, +-200, -467, 63, -173, 333, 201, 495, 476, +400, 546, 161, 411, -70, 62, -235, -266, +-286, -348, -198, -222, -82, -28, -23, 115, +-6, 79, -54, -116, -96, -287, -79, -304, +9, -158, 128, 127, 165, 354, 162, 442, +224, 364, 285, 147, 217, -105, 71, -191, +-109, -117, -412, -116, -664, -130, -645, -139, +-364, -231, 101, -253, 582, -67, 784, 145, +536, 275, 73, 368, -293, 307, -430, 90, +-283, -96, -31, -214, 129, -247, 154, -129, +104, 24, 50, 55, -23, 56, -88, 98, +-139, 74, -135, 5, -54, -25, 4, -82, +26, -139, 18, -92, -18, -43, -66, -16, +-65, -4, 26, 15, 125, 41, 212, 130, +242, 226, 184, 271, 101, 224, -52, 54, +-239, -162, -346, -369, -334, -456, -241, -334, +-82, -98, 117, 145, 198, 283, 154, 273, +90, 136, 27, -13, 32, -78, 107, -54, +171, 48, 136, 165, 13, 213, -143, 109, +-280, -46, -272, -176, -107, -265, 104, -254, +204, -171, 107, -98, -75, 4, -215, 163, +-215, 275, -60, 266, 159, 114, 319, -79, +305, -182, 119, -117, -137, 32, -322, 132, +-331, 151, -143, 75, 143, -84, 327, -209, +325, -218, 160, -125, -88, 44, -284, 237, +-364, 234, -325, 68, -155, -144, 110, -264, +304, -198, 320, 20, 215, 219, -2, 243, +-231, 156, -276, 28, -99, -90, 136, -119, +277, -55, 268, -17, 74, -20, -183, -6, +-306, -30, -273, -49, -196, 8, -120, 26, +42, -14, 236, -20, 333, -2, 301, 11, +83, 66, -251, 127, -436, 114, -291, 39, +59, -34, 390, -121, 545, -169, 345, -109, +-126, -53, -577, 14, -752, 97, -501, 117, +64, 49, 601, 50, 776, 63, 518, 13, +-13, -39, -528, -88, -684, -92, -446, -27, +-11, 48, 376, 76, 528, 18, 420, -61, +111, -136, -215, -150, -399, -63, -422, 91, +-288, 232, -38, 323, 268, 293, 486, 68, +477, -211, 180, -399, -296, -395, -639, -209, +-652, 35, -288, 229, 310, 319, 750, 254, +756, 110, 372, -40, -176, -189, -653, -246, +-754, -189, -396, -72, 92, 69, 443, 211, +516, 256, 240, 125, -171, -72, -382, -190, +-298, -193, -69, -71, 196, 141, 375, 263, +325, 195, 100, 67, -167, -149, -363, -345, +-396, -395, -212, -290, 80, -59, 281, 276, +331, 525, 214, 484, -30, 235, -242, -76, +-283, -334, -160, -394, 31, -221, 210, 8, +274, 151, 162, 224, -33, 144, -189, -53, +-260, -165, -250, -199, -110, -181, 130, -54, +315, 103, 332, 198, 172, 251, -110, 221, +-346, 118, -345, -36, -148, -204, 72, -282, +240, -202, 256, -33, 102, 124, -79, 231, +-185, 178, -184, -3, -48, -199, 145, -284, +207, -245, 137, -62, 17, 189, -130, 335, +-209, 382, -176, 301, -89, 30, 14, -225, +134, -383, 208, -429, 173, -240, 38, 131, +-171, 332, -307, 324, -240, 176, -20, -121, +262, -335, 402, -274, 250, -31, -48, 212, +-251, 351, -278, 271, -154, -8, 70, -273, +175, -330, 39, -202, -127, 34, -158, 225, +-73, 227, 57, 108, 177, -5, 170, -64, +8, -63, -102, -44, -72, -65, 34, -106, +148, -109, 172, -57, 41, 41, -183, 88, +-311, 79, -265, 75, -83, 47, 153, 72, +272, 116, 211, 136, 25, 58, -176, -102, +-231, -266, -120, -318, 51, -222, 201, -37, +299, 161, 239, 254, 27, 198, -172, 84, +-324, 2, -382, -31, -233, -58, 33, -61, +248, -67, 352, -79, 289, -16, 10, 66, +-258, 82, -291, 75, -172, 48, -6, -27, +175, -45, 255, -22, 188, -4, 86, -12, +3, -63, -126, -153, -252, -160, -258, -44, +-157, 92, -13, 204, 149, 240, 236, 176, +164, 16, 34, -101, -41, -141, -83, -144, +-83, -79, -28, -3, 10, 27, 4, 52, +21, 41, 61, 2, 72, -16, 28, 7, +-73, -19, -165, -44, -156, -49, -38, -14, +90, 57, 127, 121, 58, 138, -69, 73, +-143, -50, -71, -147, 122, -167, 282, -114, +259, 11, 37, 148, -266, 237, -429, 218, +-313, 74, -10, -133, 299, -292, 418, -315, +247, -211, -76, -59, -283, 96, -279, 243, +-166, 325, -33, 287, 62, 157, 120, -59, +205, -271, 280, -346, 259, -232, 70, 2, +-220, 212, -439, 329, -468, 227, -278, -43, +44, -300, 353, -391, 491, -269, 394, 70, +116, 416, -253, 512, -506, 320, -453, -68, +-131, -458, 251, -583, 460, -394, 388, 21, +116, 479, -178, 696, -334, 502, -294, 45, +-108, -418, 54, -679, 141, -594, 185, -201, +126, 269, -8, 576, -117, 605, -183, 318, +-186, -103, -65, -451, 126, -581, 229, -401, +228, 32, 154, 420, -5, 559, -175, 436, +-237, 20, -164, -447, -37, -625, 74, -442, +147, -12, 107, 452, -56, 661, -188, 461, +-158, 9, -10, -418, 147, -598, 235, -455, +193, -117, 59, 256, -59, 471, -127, 454, +-161, 222, -183, -69, -153, -287, -23, -373, +159, -293, 276, -88, 252, 130, 87, 290, +-136, 332, -275, 196, -271, -59, -185, -318, +-58, -424, 103, -265, 240, 65, 298, 373, +254, 514, 98, 387, -87, 41, -213, -306, +-271, -507, -243, -494, -103, -248, 74, 75, +196, 320, 215, 402, 87, 337, -109, 162, +-189, -35, -99, -166, 76, -247, 231, -245, +224, -141, 12, 41, -238, 187, -322, 232, +-218, 134, 8, -65, 248, -254, 329, -301, +210, -137, -4, 134, -176, 342, -218, 405, +-138, 242, -30, -71, 28, -326, 58, -422, +62, -373, 40, -156, 41, 132, 26, 336, +-43, 396, -81, 303, -52, 80, 8, -144, +107, -249, 186, -258, 112, -167, -68, -10, +-201, 104, -247, 107, -165, 71, 22, 7, +183, -62, 233, -31, 150, 47, 7, 95, +-84, 91, -97, 1, -104, -110, -89, -127, +-21, -57, 17, 23, 28, 80, 63, 73, +77, 4, 49, -50, 15, -54, -13, 26, +-47, 112, -53, 154, -27, 101, -21, -46, +-36, -223, -47, -296, -42, -215, 2, -26, +64, 161, 110, 255, 102, 228, 54, 127, +7, 26, -29, -32, -72, -44, -144, -46, +-188, -94, -140, -153, -24, -152, 112, -96, +225, 17, 243, 169, 141, 230, 10, 153, +-90, 41, -161, -97, -162, -190, -98, -164, +-58, -46, -30, 74, 28, 143, 62, 116, +66, -5, 84, -103, 68, -112, -10, -21, +-57, 102, -42, 172, 16, 120, 99, -14, +107, -133, 1, -187, -124, -143, -196, -11, +-170, 105, -17, 143, 144, 82, 179, -11, +115, -68, 19, -91, -79, -87, -125, -17, +-124, 48, -108, 94, -27, 157, 114, 165, +218, 78, 223, -34, 107, -168, -92, -280, +-242, -216, -234, -7, -97, 192, 92, 272, +234, 180, 214, -60, 35, -266, -194, -266, +-356, -115, -330, 77, -68, 220, 291, 210, +496, 90, 394, -4, 60, -34, -275, -31, +-369, 35, -187, 91, 98, 38, 271, -88, +185, -225, -73, -274, -276, -213, -288, -55, +-158, 135, 25, 275, 178, 301, 207, 249, +153, 99, 88, -135, 14, -313, -38, -304, +-25, -124, -2, 136, -17, 334, -29, 316, +-44, 88, -84, -167, -68, -307, -11, -292, +-15, -122, -48, 112, -59, 230, -43, 182, +17, 15, 122, -170, 186, -212, 164, -78, +98, 141, -3, 303, -98, 319, -144, 150, +-133, -119, -75, -325, -3, -357, 52, -206, +53, 36, 8, 252, -47, 304, -95, 163, +-95, -72, -20, -273, 72, -339, 136, -227, +195, 25, 211, 312, 109, 487, -62, 450, +-213, 178, -310, -211, -267, -493, -66, -499, +163, -270, 274, 53, 196, 304, -3, 358, +-151, 194, -144, -75, -33, -282, 105, -286, +166, -87, 85, 184, -55, 364, -136, 325, +-123, 104, -36, -173, 62, -355, 99, -326, +89, -131, 50, 88, -23, 238, -91, 262, +-116, 117, -96, -92, -32, -213, 60, -208, +119, -78, 94, 116, 9, 239, -63, 205, +-65, 85, -9, -55, 51, -198, 87, -235, +85, -146, 51, -9, -7, 134, -96, 242, +-175, 217, -189, 86, -117, -86, 9, -255, +130, -329, 194, -235, 177, -16, 109, 254, +-1, 437, -105, 402, -141, 157, -107, -166, +-9, -403, 108, -419, 140, -217, 37, 68, +-95, 272, -152, 309, -135, 165, -50, -73, +38, -252, 62, -284, 60, -146, 72, 85, +88, 281, 96, 331, 82, 234, 25, 46, +-67, -152, -125, -259, -112, -238, -35, -119, +20, 12, -20, 77, -116, 57, -186, -33, +-117, -129, 110, -119, 349, 25, 422, 223, +265, 367, -40, 356, -328, 130, -423, -200, +-299, -424, -56, -398, 198, -159, 318, 153, +210, 339, -17, 285, -183, 25, -219, -269, +-154, -428, -11, -334, 142, -40, 227, 285, +258, 495, 231, 468, 69, 218, -210, -96, +-436, -315, -465, -354, -258, -216, 120, -6, +443, 144, 521, 160, 340, 53, -12, -73, +-375, -121, -515, -95, -356, 1, -39, 87, +275, 68, 429, -19, 325, -60, 91, -13, +-110, 104, -251, 241, -288, 246, -171, 62, +20, -171, 190, -310, 262, -314, 157, -136, +-68, 117, -244, 239, -268, 191, -148, 53, +38, -135, 205, -233, 279, -153, 241, 3, +122, 133, -38, 216, -180, 197, -229, 90, +-146, -19, -30, -91, 32, -130, 45, -101, +-5, -27, -71, 25, -79, 32, -15, -6, +85, -50, 197, -54, 248, -15, 150, 29, +-51, 55, -233, 28, -287, -16, -174, -2, +27, 48, 202, 112, 248, 169, 134, 122, +-74, -59, -269, -259, -330, -353, -184, -268, +102, -7, 355, 302, 415, 453, 233, 350, +-94, 49, -331, -294, -347, -479, -189, -385, +62, -102, 283, 218, 345, 441, 203, 437, +-58, 184, -305, -131, -411, -345, -292, -373, +-28, -200, 237, 50, 386, 187, 358, 166, +175, 80, -67, -9, -263, -61, -344, -16, +-245, 83, 8, 125, 245, 79, 318, -13, +186, -128, -72, -210, -297, -189, -361, -87, +-231, 45, 25, 144, 286, 177, 439, 161, +411, 112, 192, 21, -154, -98, -453, -183, +-538, -192, -355, -114, 8, 27, 361, 160, +525, 209, 401, 176, 42, 72, -342, -69, +-518, -187, -385, -239, -19, -212, 378, -87, +572, 80, 413, 217, -36, 303, -458, 280, +-565, 97, -346, -133, 39, -289, 390, -324, +475, -199, 279, 53, 11, 241, -187, 260, +-289, 147, -273, -39, -191, -201, -74, -235, +116, -130, 274, 35, 281, 194, 174, 254, +4, 173, -177, 34, -235, -82, -116, -125, +42, -81, 151, -25, 166, -26, 33, -72, +-170, -141, -279, -178, -223, -132, -46, -8, +160, 173, 298, 354, 285, 396, 134, 265, +-50, 46, -166, -168, -193, -272, -141, -226, +-28, -142, 67, -97, 97, -83, 79, -84, +18, -95, -37, -20, -51, 138, -40, 273, +-15, 323, 13, 244, 10, 13, -41, -229, +-96, -299, -111, -187, -39, 6, 114, 179, +254, 224, 308, 144, 217, 20, -20, -98, +-272, -192, -385, -240, -327, -188, -140, -42, +92, 106, 250, 169, 267, 142, 160, 53, +-27, -49, -185, -77, -223, -14, -115, 85, +114, 185, 326, 237, 359, 153, 187, -47, +-121, -243, -430, -348, -529, -332, -319, -175, +47, 27, 374, 172, 525, 243, 409, 234, +75, 134, -285, -19, -478, -147, -423, -185, +-165, -120, 160, 29, 394, 185, 434, 257, +256, 202, -46, 49, -307, -156, -394, -320, +-280, -336, -33, -208, 246, -1, 427, 188, +380, 282, 96, 259, -269, 155, -521, -1, +-542, -171, -266, -262, 191, -209, 545, -61, +606, 105, 379, 216, -12, 194, -349, 56, +-448, -76, -322, -146, -79, -147, 177, -61, +281, 56, 183, 128, -4, 124, -146, 50, +-175, -47, -88, -103, 32, -94, 89, -17, +95, 51, 108, 55, 124, 4, 77, -58, +-78, -114, -266, -122, -351, -66, -227, 18, +88, 121, 411, 239, 529, 300, 371, 250, +23, 111, -342, -102, -551, -344, -502, -458, +-232, -390, 123, -203, 372, 66, 410, 319, +288, 420, 99, 351, -76, 176, -203, -58, +-266, -270, -232, -364, -83, -295, 137, -96, +315, 166, 334, 399, 143, 463, -159, 271, +-386, -93, -414, -431, -224, -571, 81, -420, +320, -38, 373, 371, 229, 564, -1, 452, +-156, 114, -160, -288, -84, -538, -30, -495, +-13, -202, 7, 189, 67, 477, 118, 520, +65, 307, -67, -21, -175, -304, -178, -405, +-64, -295, 104, -68, 200, 153, 157, 257, +47, 203, -32, 17, -80, -185, -106, -248, +-72, -146, 20, 32, 95, 196, 116, 253, +76, 154, -40, -16, -171, -140, -220, -202, +-168, -184, -33, -53, 151, 107, 294, 193, +290, 216, 133, 169, -68, 21, -198, -128, +-228, -199, -167, -239, -44, -207, 71, -84, +132, 27, 146, 126, 91, 220, -31, 232, +-123, 143, -116, 27, -70, -103, -8, -198, +53, -178, 80, -62, 96, 80, 113, 188, +60, 191, -61, 79, -149, -82, -154, -220, +-87, -272, 19, -166, 78, 45, 70, 241, +61, 332, 58, 233, 24, -23, -9, -251, +-33, -341, -75, -285, -97, -65, -63, 206, +-5, 343, 77, 324, 150, 186, 138, -48, +43, -239, -66, -264, -135, -157, -116, 4, +-9, 120, 74, 96, 55, -47, -22, -169, +-85, -196, -85, -102, -24, 90, 76, 255, +170, 302, 187, 246, 80, 89, -80, -104, +-181, -225, -179, -227, -82, -150, 58, -33, +144, 40, 123, 44, 15, 21, -102, 8, +-140, 25, -81, 49, 28, 40, 135, -2, +177, -42, 101, -50, -53, -12, -164, 63, +-168, 121, -85, 111, 38, 43, 149, -48, +168, -126, 70, -131, -73, -33, -188, 72, +-196, 86, -34, 0, 191, -142, 280, -249, +172, -197, -52, 12, -261, 256, -298, 406, +-141, 380, 59, 157, 192, -155, 232, -343, +157, -325, 33, -148, -52, 80, -105, 195, +-138, 90, -118, -106, -57, -220, 18, -199, +92, -32, 125, 207, 86, 337, -4, 282, +-104, 98, -152, -116, -75, -259, 88, -222, +194, -31, 169, 168, 48, 232, -107, 98, +-232, -148, -232, -328, -86, -330, 114, -161, +253, 107, 269, 330, 159, 388, -41, 275, +-224, 48, -274, -203, -186, -325, -52, -259, +61, -68, 129, 132, 139, 234, 127, 206, +111, 89, 61, -61, -17, -191, -74, -242, +-103, -198, -110, -70, -100, 115, -80, 271, +-44, 287, 1, 149, 50, -59, 108, -232, +146, -284, 115, -138, 48, 116, 13, 307, +-12, 318, -57, 110, -114, -218, -157, -451, +-154, -427, -70, -169, 70, 174, 194, 428, +222, 468, 129, 283, -24, -32, -129, -310, +-139, -402, -84, -262, -26, 26, 12, 267, +34, 295, 41, 126, 34, -101, 26, -248, +7, -236, -20, -88, -16, 86, 31, 181, +64, 180, 40, 83, -24, -64, -73, -138, +-81, -88, -32, 30, 44, 125, 60, 132, +-9, 27, -72, -102, -68, -159, -26, -129, +49, -63, 136, 3, 167, 67, 107, 105, +-32, 95, -165, 67, -178, 31, -74, -6, +52, -43, 123, -62, 74, -65, -93, -39, +-200, 15, -106, 68, 86, 78, 211, 28, +198, -48, 63, -104, -115, -93, -210, -16, +-154, 70, 17, 120, 182, 111, 214, 35, +92, -53, -79, -98, -189, -93, -174, -35, +-56, 38, 65, 55, 96, 10, 23, -28, +-66, -23, -87, 8, -28, 47, 71, 72, +150, 57, 174, 3, 127, -43, 24, -53, +-95, -48, -179, -18, -186, 21, -111, 30, +-8, -23, 67, -90, 83, -122, 35, -84, +-41, 44, -54, 217, 11, 307, 101, 258, +162, 82, 133, -180, -3, -395, -146, -415, +-197, -247, -144, 26, -25, 285, 121, 398, +219, 313, 205, 96, 70, -141, -122, -289, +-287, -284, -326, -138, -173, 69, 93, 230, +299, 283, 330, 205, 192, 18, -20, -201, +-188, -346, -233, -345, -151, -194, 13, 68, +171, 337, 225, 463, 150, 354, -14, 78, +-172, -241, -230, -450, -191, -397, -120, -111, +-28, 226, 92, 437, 197, 396, 251, 103, +218, -273, 79, -508, -99, -490, -210, -210, +-190, 201, -65, 519, 58, 568, 108, 323, +81, -90, -8, -435, -124, -497, -167, -266, +-96, 92, 45, 388, 195, 463, 253, 266, +157, -76, -31, -383, -201, -511, -269, -398, +-187, -101, 12, 217, 179, 390, 228, 362, +173, 192, 43, -8, -111, -116, -200, -103, +-168, -38, -65, 19, 53, 55, 155, 43, +169, -18, 85, -95, -50, -172, -190, -207, +-248, -172, -169, -70, 9, 84, 218, 243, +377, 326, 361, 293, 131, 134, -163, -97, +-376, -280, -410, -317, -224, -200, 71, 17, +290, 206, 315, 243, 161, 105, -67, -86, +-224, -212, -235, -206, -118, -43, 64, 162, +191, 247, 191, 189, 99, 28, -15, -170, +-87, -270, -85, -210, -24, -40, 49, 157, +96, 273, 75, 222, -20, 54, -131, -130, +-224, -253, -256, -235, -154, -83, 68, 94, +297, 216, 405, 267, 325, 199, 73, 16, +-217, -168, -367, -292, -295, -309, -57, -169, +181, 49, 270, 227, 187, 316, 26, 269, +-115, 68, -199, -163, -217, -308, -173, -294, +-80, -101, 50, 163, 194, 329, 289, 320, +245, 148, 78, -112, -98, -311, -191, -324, +-160, -161, -12, 63, 148, 229, 176, 237, +29, 92, -203, -87, -364, -184, -304, -145, +-46, -5, 261, 123, 446, 166, 377, 122, +81, 13, -238, -103, -381, -157, -304, -138, +-55, -62, 215, 42, 319, 135, 241, 199, +82, 197, -78, 110, -187, -55, -221, -245, +-180, -362, -80, -299, 51, -71, 168, 190, +197, 342, 93, 316, -77, 124, -188, -118, +-198, -266, -87, -246, 116, -87, 277, 146, +321, 322, 241, 326, 41, 149, -200, -105, +-355, -303, -354, -362, -210, -288, 17, -114, +193, 91, 245, 220, 196, 236, 56, 144, +-114, -15, -203, -125, -163, -99, -8, 24, +189, 145, 309, 184, 255, 116, 56, -1, +-179, -101, -308, -159, -255, -168, -81, -132, +101, -83, 193, -38, 153, 7, 14, 46, +-138, 87, -203, 155, -138, 196, 1, 146, +109, 27, 148, -104, 147, -202, 111, -193, +61, -85, 31, 55, 10, 163, -28, 179, +-83, 81, -110, -65, -106, -171, -94, -178, +-88, -75, -76, 81, -35, 188, 30, 184, +102, 68, 149, -109, 136, -250, 52, -265, +-41, -129, -50, 109, 27, 329, 113, 394, +130, 263, 54, -3, -78, -264, -203, -384, +-235, -307, -161, -107, -53, 123, 34, 286, +82, 279, 81, 111, 49, -101, 32, -239, +46, -250, 80, -132, 112, 44, 99, 182, +42, 234, -26, 205, -78, 103, -91, -41, +-61, -165, -20, -221, -28, -185, -80, -57, +-113, 85, -86, 171, -4, 160, 90, 63, +158, -72, 143, -163, 47, -166, -35, -79, +-44, 64, -2, 185, 37, 202, 41, 107, +15, -34, -24, -147, -65, -169, -82, -75, +-38, 66, 25, 147, 40, 137, 12, 53, +-44, -88, -108, -218, -120, -249, -44, -161, +76, 16, 164, 204, 187, 314, 138, 291, +37, 152, -81, -35, -154, -189, -122, -247, +-15, -199, 103, -73, 138, 55, 33, 125, +-122, 98, -201, 3, -162, -100, -37, -136, +94, -79, 146, 39, 114, 155, 53, 221, +-4, 191, -28, 79, -18, -54, -14, -152, +-3, -176, 18, -115, 29, -33, 32, 14, +43, 20, 28, -13, -31, -53, -99, -51, +-144, -1, -132, 63, -66, 119, 22, 130, +110, 99, 161, 58, 151, 24, 99, -18, +26, -68, -51, -127, -95, -182, -95, -173, +-79, -80, -45, 40, 24, 134, 93, 171, +118, 139, 73, 64, -29, -11, -130, -63, +-155, -80, -96, -70, -19, -44, 50, -5, +111, 30, 139, 68, 116, 93, 44, 78, +-70, 0, -174, -100, -153, -159, 13, -130, +201, -34, 271, 70, 165, 117, -58, 93, +-270, 40, -363, 2, -296, -7, -84, 0, +183, 3, 344, -10, 330, -28, 181, -43, +-33, -42, -197, -14, -206, 22, -102, 45, +-12, 37, 37, -17, 66, -74, 66, -89, +54, -51, 30, 20, -14, 99, -46, 142, +-50, 122, -49, 60, -36, -25, -1, -113, +26, -164, 32, -141, 31, -74, 8, 17, +-7, 108, 13, 151, 51, 115, 74, 32, +46, -59, -34, -120, -93, -119, -82, -47, +-31, 46, 26, 108, 73, 117, 65, 76, +-2, -7, -85, -81, -124, -111, -96, -98, +-24, -52, 78, -1, 184, 24, 217, 39, +144, 78, 12, 99, -126, 79, -229, 25, +-219, -50, -70, -125, 119, -137, 209, -69, +145, 35, 0, 128, -123, 157, -156, 88, +-90, -30, 5, -127, 57, -166, 67, -107, +59, 24, 32, 124, 16, 141, 25, 84, +25, -19, 25, -96, 29, -108, 2, -56, +-29, 24, -31, 92, -42, 99, -90, 55, +-136, -22, -134, -98, -46, -128, 106, -100, +218, -39, 222, 38, 130, 102, -8, 124, +-104, 112, -107, 67, -52, -10, 0, -81, +34, -99, 32, -70, -13, 1, -68, 81, +-100, 93, -88, 11, -32, -111, 41, -216, +103, -215, 119, -84, 69, 113, -18, 276, +-78, 332, -73, 235, 2, 45, 99, -139, +128, -239, 65, -199, -38, -59, -117, 70, +-123, 105, -66, 39, -6, -94, 12, -198, +8, -192, 2, -83, 8, 72, 44, 224, +89, 312, 113, 296, 101, 163, 30, -40, +-84, -233, -168, -330, -159, -295, -65, -133, +76, 85, 188, 243, 186, 255, 64, 115, +-103, -96, -218, -263, -203, -281, -55, -138, +145, 101, 264, 292, 213, 335, 19, 213, +-188, -2, -273, -194, -185, -238, 4, -130, +165, 29, 221, 125, 163, 103, 27, -32, +-82, -180, -102, -233, -56, -152, 8, 27, +54, 225, 49, 328, -8, 272, -70, 102, +-98, -93, -90, -214, -64, -214, -27, -118, +34, -12, 89, 56, 101, 61, 81, 24, +47, -10, 16, -12, 7, -1, 20, 13, +32, 29, 23, 34, -20, 15, -85, -13, +-129, -33, -138, -36, -92, -9, 11, 53, +107, 113, 124, 116, 72, 40, 2, -104, +-20, -241, 21, -284, 72, -173, 75, 50, +33, 273, -32, 363, -77, 270, -64, 41, +-2, -197, 47, -304, 42, -223, -30, -14, +-137, 185, -210, 246, -180, 145, -40, -36, +140, -184, 238, -207, 212, -103, 112, 40, +12, 125, -29, 126, -7, 52, 11, -40, +-24, -72, -89, -26, -128, 31, -123, 60, +-76, 50, -9, 5, 47, -42, 91, -46, +123, -19, 124, 10, 72, 26, -16, 23, +-110, 13, -164, -2, -113, -28, 26, -65, +158, -83, 191, -81, 100, -57, -64, -13, +-179, 59, -161, 137, -44, 182, 89, 156, +162, 69, 117, -43, -7, -125, -117, -154, +-158, -135, -117, -72, -3, 15, 120, 79, +171, 95, 141, 60, 57, -39, -40, -142, +-86, -170, -65, -90, -13, 58, 32, 220, +46, 294, 10, 225, -55, 45, -97, -156, +-89, -276, -31, -227, 34, -57, 59, 121, +55, 211, 37, 157, 17, -27, 20, -222, +27, -311, 0, -240, -20, -33, 1, 208, +20, 360, 11, 339, -7, 166, -24, -50, +-16, -187, 5, -208, -2, -120, -27, -2, +-36, 61, -24, 36, 17, -38, 62, -123, +55, -148, 24, -61, 28, 80, 42, 187, +22, 223, -27, 161, -68, 18, -74, -103, +-38, -162, 3, -162, 18, -99, 7, -6, +-8, 65, -19, 116, -22, 118, -17, 57, +10, -23, 56, -70, 103, -86, 116, -63, +63, -8, -26, 42, -84, 42, -88, -3, +-49, -55, 13, -74, 58, -33, 38, 40, +-33, 91, -91, 81, -62, 38, 63, 9, +184, 20, 188, 44, 56, 48, -133, -18, +-245, -142, -191, -250, -24, -257, 120, -130, +156, 108, 89, 328, -8, 396, -70, 260, +-73, -7, -4, -243, 97, -328, 128, -232, +46, -16, -90, 194, -188, 262, -163, 176, +-9, -9, 143, -191, 179, -277, 103, -217, +-19, -59, -96, 115, -71, 225, 6, 234, +58, 146, 70, 21, 47, -90, -14, -137, +-68, -104, -82, -20, -45, 53, 16, 83, +52, 65, 43, 5, 3, -61, -67, -114, +-132, -138, -136, -124, -67, -53, 46, 51, +177, 152, 248, 199, 191, 180, 44, 95, +-86, -9, -127, -70, -84, -71, -24, -50, +14, -31, 22, -36, -2, -86, -39, -160, +-44, -191, -26, -130, -16, 7, -3, 166, +3, 271, -1, 264, 40, 146, 136, -2, +216, -111, 192, -136, 49, -95, -140, -35, +-255, -4, -232, 0, -122, -28, -16, -67, +58, -72, 111, -23, 129, 31, 87, 64, +4, 75, -89, 45, -128, -6, -70, -37, +53, -37, 150, -17, 175, 33, 129, 69, +51, 72, -12, 52, -55, 21, -90, -28, +-77, -66, -29, -98, -6, -113, -30, -108, +-77, -73, -118, -6, -105, 87, -18, 152, +93, 159, 173, 120, 198, 36, 154, -70, +58, -140, -62, -133, -157, -66, -188, 27, +-130, 94, -2, 98, 130, 32, 187, -48, +147, -84, 35, -51, -110, 8, -211, 61, +-179, 78, -51, 50, 71, -8, 129, -70, +118, -120, 55, -125, 5, -74, 20, -1, +72, 82, 95, 151, 56, 172, -28, 133, +-94, 50, -111, -70, -77, -148, -4, -136, +49, -53, 13, 42, -89, 92, -160, 28, +-140, -114, -38, -223, 102, -213, 210, -75, +229, 149, 153, 344, 41, 393, -50, 249, +-91, -4, -74, -214, -20, -286, 29, -216, +36, -66, -19, 66, -93, 86, -104, 15, +-23, -78, 72, -134, 103, -104, 58, 18, +-37, 144, -115, 212, -99, 199, 16, 97, +140, -43, 187, -128, 145, -154, 46, -130, +-69, -60, -153, 19, -157, 79, -103, 116, +-48, 113, -11, 45, 23, -55, 57, -150, +78, -194, 68, -164, 29, -41, -10, 115, +-16, 230, 17, 254, 79, 181, 113, 27, +66, -122, -32, -189, -113, -160, -137, -74, +-78, 24, 28, 86, 102, 77, 99, 12, +31, -63, -72, -98, -132, -76, -110, -21, +-46, 37, 26, 104, 107, 142, 161, 133, +148, 75, 59, -16, -69, -118, -176, -157, +-181, -119, -65, -41, 106, 30, 198, 58, +139, 31, -3, -6, -115, -11, -148, 12, +-90, 50, 13, 75, 88, 57, 114, -8, +115, -73, 93, -96, 50, -54, -21, 26, +-113, 85, -169, 75, -133, 14, -27, -60, +101, -94, 165, -55, 112, 49, -24, 129, +-147, 126, -192, 28, -123, -115, 22, -222, +148, -219, 196, -86, 157, 111, 52, 277, +-72, 320, -140, 216, -106, 9, -25, -194, +40, -303, 75, -259, 85, -97, 55, 94, +-2, 205, -62, 180, -111, 50, -112, -100, +-17, -198, 130, -181, 220, -42, 169, 130, +-12, 245, -193, 263, -237, 164, -125, -19, +62, -180, 209, -254, 214, -212, 71, -80, +-113, 64, -232, 132, -212, 115, -64, 18, +111, -100, 200, -147, 159, -85, 23, 32, +-95, 160, -99, 234, -22, 202, 54, 86, +95, -55, 80, -170, 27, -203, -6, -155, +-9, -65, 0, 36, 13, 89, -7, 62, +-63, -5, -103, -49, -112, -62, -85, -19, +21, 54, 140, 121, 163, 152, 94, 132, +-1, 48, -89, -63, -125, -155, -85, -187, +-2, -150, 74, -67, 98, 42, 57, 144, +8, 179, -8, 124, 3, 26, 21, -94, +17, -184, -33, -173, -91, -59, -107, 69, +-69, 160, 15, 149, 107, 42, 158, -76, +160, -120, 101, -70, 2, 65, -69, 181, +-68, 187, -21, 94, 13, -64, -27, -233, +-131, -313, -208, -251, -175, -96, -38, 89, +128, 227, 228, 265, 218, 197, 130, 80, +23, -34, -73, -87, -133, -75, -125, -23, +-57, 22, 11, 23, 51, -34, 67, -99, +65, -138, 47, -124, 32, -39, 3, 69, +-53, 126, -81, 114, -48, 54, 17, -20, +92, -41, 138, 6, 108, 84, 15, 123, +-95, 82, -190, -39, -198, -163, -84, -233, +86, -210, 215, -80, 226, 108, 99, 247, +-93, 270, -246, 157, -283, -49, -179, -238, +45, -290, 278, -176, 393, 49, 317, 256, +76, 310, -198, 180, -338, -58, -269, -266, +-57, -323, 146, -177, 227, 74, 178, 278, +37, 305, -138, 145, -233, -110, -180, -297, +-7, -304, 204, -140, 329, 87, 254, 255, +26, 275, -203, 151, -305, -13, -244, -127, +-65, -153, 102, -101, 170, -11, 144, 39, +55, 33, -61, 6, -141, -4, -139, -18, +-58, -46, 67, -78, 185, -75, 224, -24, +157, 87, 7, 212, -149, 275, -212, 212, +-131, 24, 49, -218, 208, -386, 234, -366, +103, -161, -113, 125, -268, 322, -269, 303, +-136, 87, 50, -166, 207, -293, 253, -203, +169, 59, 6, 330, -165, 424, -263, 274, +-207, -57, -10, -379, 216, -498, 337, -345, +289, -25, 96, 274, -148, 400, -325, 299, +-343, 35, -211, -249, -20, -385, 157, -305, +268, -60, 271, 228, 199, 434, 89, 433, +-49, 235, -171, -61, -206, -324, -142, -449, +-10, -379, 130, -165, 181, 107, 102, 310, +-45, 343, -164, 202, -169, -18, -60, -207, +68, -257, 121, -149, 86, 28, -18, 185, +-112, 239, -108, 158, -19, 1, 74, -124, +125, -180, 105, -139, 40, -30, -11, 57, +-21, 70, -6, 36, 7, -25, -5, -61, +-21, -29, -17, 33, -3, 80, 7, 95, +1, 50, -29, -36, -43, -88, -14, -76, +32, -17, 70, 49, 99, 79, 89, 41, +26, -40, -62, -123, -132, -141, -151, -76, +-95, 51, 11, 173, 101, 228, 114, 157, +67, -2, 17, -150, -14, -207, -34, -153, +-46, -29, -56, 78, -47, 105, 5, 64, +90, -24, 149, -98, 145, -90, 63, -10, +-49, 83, -136, 145, -167, 128, -108, 55, +47, -21, 196, -69, 246, -80, 167, -56, +-23, -53, -243, -76, -350, -85, -296, -55, +-126, 18, 104, 118, 301, 189, 358, 173, +256, 66, 42, -90, -186, -198, -311, -190, +-271, -77, -101, 69, 117, 175, 265, 166, +272, 58, 153, -71, -40, -142, -226, -131, +-275, -35, -139, 78, 101, 142, 310, 127, +361, 45, 191, -70, -106, -146, -368, -167, +-462, -140, -324, -71, -19, 21, 285, 130, +445, 229, 402, 261, 178, 188, -119, 40, +-336, -141, -380, -277, -237, -283, 6, -156, +209, 16, 282, 146, 205, 169, 9, 79, +-187, -55, -254, -122, -159, -77, 31, 55, +232, 193, 344, 236, 299, 155, 99, -3, +-145, -163, -315, -261, -356, -241, -249, -138, +-33, -17, 165, 70, 256, 129, 231, 148, +132, 144, 7, 122, -98, 76, -158, -3, +-155, -91, -94, -154, -12, -158, 64, -95, +114, 12, 104, 110, 49, 147, -2, 102, +-32, 6, -47, -95, -42, -146, -28, -102, +-7, 3, 20, 96, 34, 128, 26, 88, +11, -20, -5, -112, 7, -128, 60, -65, +119, 40, 137, 123, 90, 129, -21, 63, +-138, -46, -201, -149, -197, -168, -120, -87, +8, 40, 99, 148, 121, 187, 100, 114, +61, -21, 21, -143, 15, -183, 28, -122, +27, 16, 8, 147, -26, 207, -55, 152, +-63, 10, -67, -135, -69, -200, -52, -180, +-9, -84, 56, 30, 141, 99, 195, 114, +168, 92, 58, 47, -88, -3, -194, -34, +-185, -45, -75, -33, 59, 4, 132, 60, +112, 111, 28, 107, -47, 9, -70, -140, +-44, -262, -3, -280, 23, -147, 38, 92, +46, 293, 19, 356, -39, 246, -100, 15, +-123, -196, -92, -265, 1, -175, 123, 6, +211, 166, 206, 183, 93, 63, -73, -106, +-192, -217, -188, -205, -54, -71, 123, 83, +220, 175, 159, 172, -6, 100, -154, 21, +-201, -17, -142, -18, -13, 4, 105, 7, +147, -24, 97, -68, 7, -95, -81, -91, +-123, -53, -98, -12, -26, 4, 47, 24, +94, 57, 104, 101, 99, 142, 87, 152, +31, 81, -80, -54, -174, -192, -199, -264, +-131, -217, 18, -58, 171, 125, 231, 235, +171, 220, 39, 94, -73, -47, -105, -117, +-60, -93, 14, -13, 83, 63, 83, 68, +7, 4, -81, -86, -129, -135, -136, -115, +-98, -32, -28, 51, 46, 103, 94, 111, +103, 95, 74, 75, 46, 66, 25, 47, +12, 1, 9, -74, -5, -155, -57, -204, +-115, -194, -125, -116, -70, 2, 28, 118, +141, 193, 209, 202, 195, 150, 97, 73, +-31, 3, -126, -48, -140, -69, -84, -52, +-16, -31, 14, -41, -6, -73, -64, -105, +-95, -115, -60, -81, 19, 10, 94, 111, +147, 167, 154, 153, 94, 86, -8, -8, +-112, -73, -175, -81, -146, -35, -35, 30, +92, 75, 166, 41, 149, -55, 39, -142, +-88, -161, -159, -111, -140, -6, -30, 89, +115, 133, 203, 123, 196, 82, 91, 31, +-60, 0, -160, -12, -149, -8, -71, -2, +27, -4, 92, -14, 77, -32, -9, -65, +-111, -104, -172, -122, -143, -106, -33, -28, +110, 105, 227, 221, 250, 253, 138, 181, +-29, 16, -147, -170, -176, -271, -102, -236, +37, -95, 131, 69, 112, 162, -12, 135, +-150, 40, -193, -48, -99, -63, 59, -4, +186, 81, 218, 113, 160, 66, 75, -37, +10, -123, -43, -135, -105, -64, -173, 33, +-192, 99, -145, 80, -60, -8, 23, -89, +97, -94, 143, -22, 138, 93, 89, 169, +18, 136, -42, 14, -43, -129, -2, -215, +30, -183, 12, -52, -47, 92, -91, 173, +-56, 152, 24, 48, 70, -73, 65, -130, +25, -93, -35, 4, -61, 94, -31, 128, +35, 95, 94, 27, 116, -25, 82, -41, +11, -40, -62, -46, -94, -59, -80, -91, +-50, -117, -33, -107, -19, -49, -9, 32, +2, 131, 12, 200, 17, 210, 19, 165, +37, 83, 56, -43, 47, -160, 6, -229, +-48, -226, -79, -157, -62, -39, -15, 66, +49, 116, 107, 100, 120, 50, 79, 25, +16, 52, -41, 117, -65, 184, -36, 190, +8, 87, 17, -90, 3, -271, -18, -378, +-26, -347, -26, -184, -45, 23, -81, 188, +-77, 260, -15, 218, 82, 110, 159, 17, +164, -16, 78, 1, -48, 44, -163, 61, +-207, 19, -145, -75, -14, -168, 122, -213, +201, -165, 163, -33, 38, 139, -62, 274, +-74, 310, -22, 202, 57, -16, 97, -251, +66, -385, -6, -354, -76, -162, -119, 106, +-100, 325, -39, 384, 24, 264, 63, 32, +57, -196, -7, -311, -70, -246, -82, -49, +-43, 154, 22, 260, 84, 224, 102, 63, +57, -135, -26, -262, -89, -264, -97, -135, +-41, 72, 43, 247, 108, 298, 120, 202, +84, 8, 23, -183, -38, -263, -76, -186, +-77, 1, -41, 174, 38, 220, 109, 96, +106, -121, 25, -296, -74, -302, -139, -125, +-127, 149, -51, 367, 25, 405, 67, 241, +75, -12, 47, -222, 6, -296, -31, -210, +-51, -29, -41, 111, 11, 129, 57, 27, +59, -128, 7, -231, -58, -198, -80, -38, +-38, 174, 20, 345, 61, 390, 71, 278, +62, 57, 59, -183, 61, -340, 38, -352, +-2, -241, -39, -70, -61, 75, -51, 127, +-14, 94, -8, 35, -36, 0, -60, 27, +-59, 117, -39, 197, 19, 201, 77, 108, +79, -43, 21, -192, -39, -258, -52, -227, +-11, -131, 39, -36, 54, 18, 13, 21, +-56, 31, -101, 82, -58, 175, 57, 256, +161, 264, 180, 157, 110, -40, -17, -253, +-147, -378, -204, -358, -132, -202, 14, 28, +143, 241, 189, 343, 138, 308, 12, 178, +-106, 0, -146, -162, -102, -252, -35, -259, +1, -204, 2, -105, -15, 10, -39, 99, +-39, 141, 2, 146, 70, 129, 119, 110, +133, 104, 110, 105, 58, 87, -20, 23, +-105, -73, -164, -174, -163, -245, -105, -252, +10, -187, 140, -91, 212, 20, 188, 121, +99, 192, -16, 226, -117, 232, -177, 181, +-166, 80, -78, -51, 49, -175, 135, -259, +133, -264, 43, -198, -82, -93, -163, 20, +-138, 111, -24, 166, 109, 196, 186, 209, +182, 201, 107, 164, -3, 88, -107, -28, +-157, -158, -160, -255, -135, -282, -84, -224, +-16, -110, 50, 3, 124, 81, 169, 108, +147, 105, 81, 108, 11, 126, -60, 126, +-98, 93, -80, 13, -21, -105, 47, -211, +87, -234, 53, -169, -31, -45, -97, 87, +-99, 179, -29, 201, 73, 186, 115, 161, +74, 135, -6, 95, -72, 26, -117, -86, +-125, -212, -92, -302, -30, -306, 12, -220, +20, -69, 0, 78, -28, 163, -31, 166, +36, 123, 153, 69, 253, 33, 268, 32, +187, 52, 45, 61, -105, 48, -216, 14, +-235, -30, -160, -70, -47, -80, 33, -61, +66, -16, 38, 42, -43, 77, -122, 50, +-139, -24, -95, -110, -10, -163, 78, -143, +159, -32, 205, 112, 184, 216, 117, 222, +45, 135, -49, -14, -147, -150, -208, -209, +-210, -174, -148, -98, -28, -22, 91, 20, +179, 30, 222, 30, 199, 70, 127, 149, +69, 223, 3, 235, -72, 162, -99, 7, +-88, -163, -107, -270, -150, -268, -196, -187, +-212, -82, -142, -5, 22, 24, 197, 24, +302, 36, 281, 76, 150, 129, -9, 158, +-115, 137, -140, 62, -95, -24, -21, -79, +30, -95, 27, -78, -13, -47, -53, -33, +-45, -30, 13, -13, 97, 30, 154, 74, +140, 111, 62, 102, -37, 31, -133, -66, +-184, -131, -165, -147, -101, -104, -27, -21, +42, 57, 67, 80, 56, 60, 48, 19, +67, -16, 105, -37, 131, -27, 100, 6, +9, 38, -105, 68, -190, 102, -188, 110, +-77, 81, 68, 32, 165, -34, 161, -100, +57, -125, -76, -114, -139, -90, -106, -66, +-8, -54, 83, -61, 98, -52, 49, -8, +-12, 58, -72, 124, -90, 162, -47, 136, +11, 60, 43, -22, 62, -70, 67, -73, +68, -26, 72, 29, 65, 60, 30, 54, +-9, 35, -49, 15, -66, 3, -52, -2, +-50, 2, -90, -20, -116, -72, -98, -136, +-45, -179, 13, -194, 62, -159, 86, -79, +82, 21, 50, 121, 28, 215, 32, 269, +52, 262, 75, 197, 97, 96, 70, -17, +-12, -101, -109, -124, -166, -89, -156, -41, +-82, -15, 10, -33, 92, -89, 127, -148, +94, -155, 34, -87, -1, 39, -22, 161, +-37, 218, -63, 175, -111, 52, -157, -111, +-132, -236, -28, -264, 104, -189, 177, -60, +150, 81, 53, 182, -38, 223, -66, 214, +0, 194, 114, 166, 193, 120, 185, 54, +82, -20, -83, -104, -221, -175, -273, -214, +-222, -225, -103, -225, 24, -196, 95, -125, +112, -18, 102, 106, 74, 212, 43, 251, +25, 201, 1, 87, -27, -33, -52, -108, +-74, -109, -89, -49, -71, 28, -20, 74, +48, 82, 110, 71, 147, 53, 135, 37, +86, 28, 16, 13, -47, -20, -82, -71, +-72, -121, -47, -161, -41, -170, -68, -139, +-108, -73, -120, 14, -53, 97, 60, 142, +143, 141, 147, 95, 102, 30, 37, -14, +-5, 7, 7, 73, 32, 141, 7, 148, +-58, 65, -128, -89, -157, -243, -122, -311, +-25, -245, 92, -86, 178, 105, 180, 243, +108, 268, 18, 185, -41, 51, -58, -88, +-45, -195, -56, -242, -115, -218, -188, -139, +-192, -22, -86, 110, 98, 220, 263, 262, +330, 229, 272, 149, 122, 62, -50, -3, +-152, -28, -171, -43, -145, -89, -106, -175, +-63, -269, -29, -326, 8, -284, 47, -135, +61, 72, 31, 253, -11, 336, -33, 284, +-16, 152, 25, 16, 62, -63, 65, -62, +41, 3, -3, 62, -55, 72, -82, 17, +-49, -81, 17, -173, 99, -200, 166, -142, +163, -20, 70, 113, -47, 205, -140, 205, +-182, 109, -150, -53, -60, -209, 21, -295, +44, -277, -21, -160, -127, 4, -164, 140, +-65, 217, 139, 243, 361, 239, 439, 222, +281, 195, -45, 129, -357, 5, -493, -151, +-371, -283, -54, -346, 284, -309, 440, -186, +336, -22, 63, 101, -192, 148, -305, 122, +-244, 72, -74, 32, 95, 34, 183, 76, +182, 125, 98, 128, -47, 75, -199, -31, +-274, -146, -222, -215, -52, -186, 141, -70, +266, 93, 275, 221, 171, 243, 17, 141, +-99, -31, -133, -197, -87, -269, -13, -202, +19, -48, -40, 89, -151, 135, -228, 66, +-171, -66, 24, -144, 260, -80, 411, 102, +397, 309, 201, 425, -80, 367, -318, 126, +-410, -185, -328, -418, -124, -473, 64, -342, +155, -93, 135, 126, 44, 208, -46, 140, +-74, 6, -45, -103, 40, -106, 165, -3, +254, 132, 232, 194, 107, 144, -89, 6, +-269, -126, -330, -168, -245, -77, -81, 93, +90, 252, 204, 310, 234, 238, 166, 74, +30, -108, -105, -257, -168, -335, -149, -339, +-67, -287, 25, -195, 74, -65, 56, 70, +0, 166, -56, 198, -52, 171, 18, 108, +125, 65, 225, 84, 252, 155, 130, 216, +-94, 216, -304, 128, -405, -44, -337, -234, +-110, -336, 146, -301, 305, -150, 300, 29, +151, 144, -53, 124, -200, -7, -234, -163, +-133, -241, 42, -196, 176, -40, 206, 149, +145, 275, 16, 276, -99, 179, -137, 52, +-75, -25, 44, -20, 145, 63, 150, 138, +67, 136, -71, 30, -219, -151, -285, -332, +-228, -417, -104, -358, 39, -173, 168, 69, +229, 262, 206, 329, 146, 266, 67, 119, +-8, -42, -76, -138, -155, -121, -231, -25, +-240, 85, -168, 151, -26, 142, 145, 59, +278, -38, 313, -86, 266, -72, 175, -40, +59, -25, -78, -57, -205, -133, -290, -215, +-300, -225, -229, -141, -104, 25, 15, 208, +101, 334, 150, 342, 162, 245, 142, 86, +104, -70, 36, -178, -54, -207, -132, -173, +-170, -103, -156, -26, -64, 43, 58, 87, +141, 111, 151, 110, 100, 74, 26, -4, +-13, -95, -5, -161, 13, -174, 3, -127, +-29, -37, -69, 52, -82, 109, -55, 117, +6, 85, 60, 45, 52, 36, -28, 65, +-121, 106, -169, 117, -134, 66, -26, -59, +90, -207, 126, -305, 95, -292, 38, -161, +-3, 55, -9, 259, 2, 360, -2, 316, +2, 164, 14, -30, 11, -167, -6, -194, +-15, -123, -32, -38, -34, 13, -3, 1, +28, -57, 28, -120, 20, -135, 4, -97, +-38, -30, -101, 41, -143, 102, -140, 146, +-77, 174, 17, 192, 96, 188, 132, 137, +132, 47, 106, -57, 83, -140, 66, -164, +27, -132, -55, -81, -141, -44, -196, -53, +-192, -105, -117, -158, 18, -152, 125, -79, +148, 47, 85, 180, -14, 269, -92, 259, +-107, 164, -77, 24, -31, -101, 10, -165, +52, -130, 101, -18, 167, 123, 206, 225, +167, 246, 33, 152, -149, -37, -295, -250, +-323, -398, -217, -425, -27, -314, 127, -113, +172, 91, 107, 217, 3, 243, -82, 181, +-98, 95, -53, 46, 8, 74, 48, 155, +62, 220, 44, 206, 24, 97, 28, -68, +64, -208, 97, -254, 93, -205, 27, -117, +-79, -66, -181, -97, -224, -189, -195, -267, +-113, -247, -11, -99, 85, 142, 142, 374, +153, 496, 105, 465, 20, 321, -64, 125, +-98, -37, -82, -122, -20, -134, 57, -124, +113, -128, 125, -165, 114, -211, 55, -229, +-51, -191, -165, -112, -237, -19, -257, 55, +-211, 93, -111, 82, -7, 54, 49, 54, +67, 83, 82, 130, 126, 182, 184, 206, +229, 175, 219, 101, 155, 15, 49, -71, +-71, -138, -187, -170, -258, -181, -267, -181, +-210, -151, -90, -96, 54, -33, 134, 21, +116, 40, 18, 14, -100, -30, -169, -59, +-130, -30, -14, 77, 116, 234, 186, 362, +158, 390, 56, 283, -48, 78, -125, -155, +-136, -326, -66, -387, 40, -339, 114, -237, +136, -121, 101, -27, 36, 37, -30, 88, +-82, 147, -118, 187, -135, 187, -142, 145, +-129, 69, -117, -25, -126, -80, -136, -68, +-78, -4, 74, 73, 294, 129, 467, 137, +464, 90, 258, 9, -50, -76, -324, -158, +-436, -226, -370, -264, -218, -262, -86, -218, +-25, -128, -45, -3, -80, 129, -50, 234, +63, 297, 206, 306, 314, 270, 304, 195, +182, 103, 20, -1, -102, -92, -148, -152, +-107, -161, -25, -122, 30, -55, 17, -20, +-44, -45, -128, -117, -214, -198, -273, -255, +-256, -238, -175, -141, -44, 8, 120, 169, +266, 310, 322, 388, 272, 385, 125, 313, +-46, 191, -151, 37, -153, -113, -86, -233, +25, -300, 115, -299, 132, -225, 71, -94, +-39, 47, -169, 144, -262, 157, -291, 69, +-251, -83, -156, -215, -33, -247, 75, -145, +172, 65, 237, 290, 239, 420, 185, 390, +120, 213, 51, -36, -12, -235, -71, -304, +-117, -228, -150, -67, -155, 91, -139, 160, +-94, 127, -60, 13, -64, -117, -80, -213, +-75, -237, -57, -191, -16, -88, 47, 30, +107, 127, 140, 181, 158, 196, 153, 186, +120, 177, 49, 165, -51, 136, -147, 77, +-185, -21, -152, -147, -62, -261, 33, -316, +66, -284, -3, -169, -120, -5, -210, 141, +-204, 213, -107, 196, 42, 109, 166, -11, +203, -114, 146, -159, 51, -121, -35, -23, +-64, 100, -44, 202, -15, 239, -5, 190, +9, 83, 9, -48, -6, -154, -36, -191, +-95, -143, -174, -57, -196, 24, -143, 57, +-43, 23, 52, -60, 108, -125, 104, -132, +75, -59, 42, 59, 29, 160, 45, 190, +70, 140, 70, 36, 52, -60, 3, -99, +-71, -65, -152, 6, -210, 64, -226, 73, +-180, 39, -97, -16, -3, -58, 69, -59, +89, -34, 52, -18, 1, -21, -40, -54, +-46, -110, -13, -148, 53, -118, 124, -11, +190, 151, 204, 301, 137, 365, 6, 298, +-141, 123, -258, -101, -283, -275, -224, -329, +-145, -247, -109, -93, -90, 46, -65, 91, +-18, 42, 63, -61, 172, -135, 249, -121, +249, -17, 163, 116, 22, 214, -120, 224, +-186, 142, -165, 21, -79, -63, 9, -79, +43, -33, 8, 30, -48, 62, -115, 41, +-177, -13, -194, -70, -135, -103, -29, -95, +101, -64, 201, -45, 221, -55, 143, -92, +14, -134, -113, -136, -172, -68, -137, 60, +-33, 205, 81, 315, 153, 349, 132, 280, +41, 132, -73, -43, -161, -189, -216, -271, +-232, -254, -216, -160, -148, -33, -34, 67, +96, 112, 191, 76, 216, -19, 142, -128, +7, -182, -124, -156, -181, -42, -146, 118, +-29, 253, 112, 299, 200, 246, 176, 107, +59, -62, -99, -189, -228, -230, -282, -183, +-238, -76, -125, 38, 14, 112, 114, 126, +145, 85, 109, 16, 44, -47, -15, -80, +-40, -82, -50, -67, -54, -46, -62, -24, +-61, 5, -66, 37, -66, 71, -64, 94, +-61, 97, -42, 69, 6, 21, 52, -38, +75, -83, 65, -95, 39, -63, 2, -1, +-27, 78, -47, 127, -47, 113, -40, 27, +-36, -100, -34, -215, -24, -249, -14, -170, +5, 7, -1, 201, -53, 316, -138, 282, +-198, 114, -201, -113, -125, -293, -14, -341, +80, -230, 124, -8, 131, 222, 106, 360, +93, 352, 100, 205, 103, -12, 74, -209, +23, -315, -77, -298, -196, -176, -280, 3, +-287, 164, -209, 233, -55, 192, 90, 62, +164, -96, 130, -204, -2, -205, -177, -105, +-275, 42, -230, 154, -53, 181, 167, 109, +330, -14, 352, -112, 236, -123, 34, -48, +-159, 85, -279, 191, -281, 208, -176, 121, +-12, -20, 109, -153, 116, -210, 4, -180, +-149, -91, -254, -3, -250, 47, -144, 37, +21, -9, 160, -51, 219, -60, 185, -26, +92, 40, -25, 110, -102, 148, -111, 144, +-64, 92, -11, 9, 20, -68, 0, -105, +-66, -85, -161, -26, -218, 29, -209, 45, +-117, 12, 40, -53, 209, -104, 295, -105, +257, -46, 108, 39, -79, 115, -225, 147, +-261, 127, -207, 70, -104, 3, -4, -65, +52, -117, 30, -143, -36, -136, -122, -99, +-177, -29, -160, 46, -72, 102, 46, 112, +175, 92, 244, 64, 219, 53, 122, 58, +-1, 68, -115, 47, -151, -11, -108, -89, +-54, -152, -45, -166, -89, -114, -160, -22, +-175, 60, -112, 92, -14, 64, 43, -2, +24, -65, -67, -83, -150, -39, -159, 46, +-75, 129, 78, 163, 235, 134, 301, 55, +262, -37, 141, -106, -21, -117, -173, -81, +-248, -31, -251, -1, -186, 5, -75, -9, +31, -20, 51, -20, -26, -16, -165, -37, +-274, -63, -275, -71, -126, -29, 107, 67, +324, 197, 416, 289, 339, 280, 132, 143, +-91, -70, -258, -262, -313, -334, -259, -256, +-156, -77, -82, 104, -34, 196, -21, 158, +-24, 23, -16, -127, 11, -208, 27, -181, +42, -66, 45, 76, 28, 172, -11, 187, +-32, 142, -40, 80, -19, 46, 22, 48, +62, 64, 72, 59, 32, 11, -79, -67, +-222, -135, -341, -165, -367, -145, -273, -105, +-70, -77, 133, -82, 251, -85, 245, -57, +148, 21, 22, 119, -47, 203, -38, 219, +36, 166, 118, 77, 141, 12, 65, -10, +-73, 6, -223, 19, -304, 3, -286, -49, +-201, -103, -110, -129, -39, -110, -22, -73, +-46, -56, -66, -77, -44, -121, 11, -143, +99, -98, 175, 20, 201, 167, 168, 275, +119, 293, 67, 219, 28, 97, -6, -6, +-51, -40, -123, -4, -184, 56, -234, 74, +-265, 11, -285, -133, -289, -293, -272, -391, +-199, -366, -77, -224, 75, -19, 231, 155, +352, 234, 387, 194, 351, 85, 261, -16, +133, -33, -4, 57, -114, 227, -220, 382, +-308, 434, -352, 332, -333, 100, -257, -185, +-136, -410, -36, -499, 9, -437, -2, -272, +-26, -96, -31, 5, 9, -3, 59, -82, +93, -153, 110, -137, 117, -6, 121, 205, +149, 405, 154, 521, 92, 521, -43, 425, +-202, 271, -327, 91, -340, -100, -247, -289, +-113, -459, -22, -572, 0, -570, -39, -434, +-74, -188, -77, 77, -45, 265, -2, 306, +54, 213, 114, 56, 187, -52, 240, -40, +223, 109, 104, 310, -77, 459, -258, 459, +-350, 287, -312, -4, -168, -291, -29, -471, +31, -497, -7, -402, -84, -257, -128, -137, +-73, -69, 54, -34, 176, 15, 213, 110, +152, 235, 26, 338, -86, 366, -141, 303, +-128, 175, -91, 40, -80, -54, -119, -87, +-174, -75, -201, -57, -150, -70, -33, -123, +97, -198, 186, -255, 225, -255, 187, -189, +81, -70, -62, 60, -195, 162, -279, 206, +-252, 187, -131, 121, 23, 56, 133, 31, +158, 77, 88, 164, -19, 240, -141, 233, +-235, 115, -253, -96, -191, -315, -92, -467, +32, -479, 126, -339, 139, -94, 89, 154, +29, 313, -37, 320, -60, 184, -12, -15, +76, -170, 136, -194, 128, -52, 12, 197, +-160, 430, -302, 516, -349, 390, -299, 78, +-184, -298, -83, -587, -20, -683, 13, -555, +39, -261, 74, 78, 150, 335, 226, 429, +253, 355, 187, 174, 43, -15, -135, -141, +-253, -152, -276, -53, -214, 113, -122, 265, +-38, 334, -1, 269, -9, 78, -57, -188, +-104, -422, -122, -540, -79, -487, 3, -276, +97, 19, 148, 274, 138, 398, 67, 348, +-22, 174, -103, -20, -135, -130, -98, -110, +-9, 16, 55, 154, 49, 212, -58, 147, +-215, -12, -328, -189, -313, -293, -185, -268, +6, -131, 180, 51, 280, 192, 275, 224, +192, 138, 51, -24, -76, -183, -142, -261, +-140, -215, -110, -53, -99, 163, -141, 333, +-179, 378, -151, 279, -54, 82, 53, -130, +126, -269, 92, -299, -45, -230, -207, -122, +-289, -30, -239, 5, -37, 3, 217, -8, +385, 21, 372, 84, 192, 155, -60, 195, +-245, 187, -308, 129, -262, 52, -159, -13, +-55, -39, -6, -36, 1, -42, -31, -88, +-90, -180, -140, -282, -134, -333, -79, -282, +21, -118, 128, 122, 193, 349, 178, 475, +99, 436, -25, 253, -125, 4, -150, -206, +-86, -291, -8, -232, 19, -76, -57, 86, +-192, 179, -282, 152, -252, 20, -123, -148, +52, -269, 186, -295, 218, -214, 154, -69, +47, 77, -84, 169, -180, 197, -194, 170, +-120, 139, -2, 130, 127, 153, 199, 171, +173, 150, 49, 58, -125, -93, -300, -258, +-389, -372, -349, -396, -193, -315, -11, -162, +117, 7, 141, 130, 111, 187, 87, 189, +108, 175, 148, 172, 154, 175, 74, 161, +-56, 109, -172, 25, -226, -49, -218, -68, +-153, -30, -88, 32, -49, 50, -48, -34, +-71, -217, -110, -413, -126, -508, -102, -420, +-20, -150, 83, 191, 176, 459, 224, 543, +212, 432, 121, 195, -16, -37, -155, -161, +-249, -135, -257, -5, -142, 151, 25, 235, +146, 200, 144, 38, 17, -192, -187, -416, +-350, -547, -392, -538, -297, -376, -123, -116, +73, 156, 221, 357, 299, 441, 301, 407, +250, 305, 160, 192, 61, 113, -61, 83, +-190, 87, -294, 81, -335, 27, -300, -76, +-179, -209, -33, -335, 67, -423, 85, -445, +29, -387, -91, -253, -194, -67, -208, 127, +-105, 288, 89, 383, 301, 404, 410, 361, +372, 278, 199, 183, -32, 105, -236, 47, +-345, 10, -370, -32, -318, -90, -226, -171, +-138, -254, -96, -322, -79, -351, -71, -344, +-25, -288, 69, -185, 173, -31, 218, 150, +195, 320, 117, 425, 26, 430, -34, 323, +-36, 144, -6, -20, 31, -86, 22, -32, +-50, 90, -177, 182, -300, 154, -362, -17, +-333, -272, -246, -502, -135, -606, -28, -528, +79, -292, 172, 24, 248, 312, 281, 480, +253, 492, 159, 369, 48, 173, -62, -17, +-147, -132, -187, -142, -163, -55, -118, 71, +-89, 167, -101, 174, -140, 89, -194, -72, +-210, -254, -169, -407, -80, -472, 23, -427, +127, -253, 206, 18, 240, 318, 209, 543, +132, 608, 27, 471, -77, 189, -164, -123, +-211, -330, -217, -354, -186, -199, -141, 38, +-87, 221, -37, 256, 17, 128, 52, -103, +53, -331, 1, -453, -91, -423, -162, -256, +-135, -18, -29, 212, 110, 364, 215, 416, +234, 375, 151, 273, 31, 146, -101, 20, +-206, -91, -241, -174, -203, -213, -148, -210, +-96, -165, -84, -99, -112, -35, -131, -10, +-93, -33, -27, -88, 51, -127, 120, -111, +176, -16, 221, 124, 240, 258, 192, 329, +83, 318, -70, 227, -218, 94, -319, -41, +-338, -145, -297, -203, -200, -214, -72, -196, +45, -162, 96, -124, 89, -88, 35, -58, +-33, -21, -89, 36, -102, 96, -73, 139, +-6, 147, 79, 122, 161, 81, 184, 55, +151, 59, 87, 88, 21, 119, -59, 118, +-148, 70, -243, -16, -316, -114, -347, -208, +-298, -277, -184, -310, -40, -290, 84, -219, +174, -83, 203, 93, 170, 258, 100, 349, +39, 344, 3, 243, 6, 91, 15, -47, +11, -102, -18, -62, -57, 39, -108, 136, +-156, 166, -196, 77, -208, -114, -178, -332, +-111, -476, -58, -480, -26, -329, -11, -75, +7, 179, 48, 346, 130, 393, 207, 346, +255, 264, 250, 202, 161, 162, -23, 108, +-232, -5, -403, -172, -457, -339, -373, -422, +-191, -369, -4, -202, 133, -3, 178, 134, +151, 155, 86, 75, 20, -24, -32, -58, +-50, 10, -53, 143, -39, 270, -5, 317, +44, 252, 67, 98, 68, -69, 33, -193, +-36, -232, -121, -188, -185, -95, -236, -22, +-255, -4, -231, -59, -154, -152, -46, -220, +84, -203, 202, -87, 291, 109, 313, 322, +249, 457, 95, 442, -100, 283, -292, 37, +-401, -212, -379, -367, -235, -370, -47, -228, +136, -9, 258, 192, 275, 284, 166, 230, +-22, 54, -245, -170, -406, -349, -422, -403, +-272, -308, -23, -99, 245, 163, 427, 396, +460, 516, 330, 469, 89, 276, -182, -1, +-366, -266, -408, -422, -302, -406, -121, -240, +37, -2, 87, 197, 46, 270, -43, 183, +-121, -7, -152, -204, -115, -316, -37, -292, +63, -131, 139, 99, 181, 313, 180, 434, +150, 421, 88, 276, 9, 50, -85, -182, +-179, -347, -258, -383, -286, -279, -259, -84, +-173, 109, -60, 209, 50, 172, 116, 23, +129, -157, 72, -269, -15, -253, -82, -97, +-90, 145, -27, 363, 99, 456, 211, 378, +241, 153, 151, -131, -18, -343, -206, -399, +-330, -287, -357, -72, -283, 137, -136, 231, +31, 187, 146, 47, 166, -96, 79, -164, +-61, -133, -178, -45, -195, 40, -115, 70, +37, 48, 191, 9, 279, -2, 255, 27, +146, 92, -10, 147, -141, 151, -206, 98, +-206, 18, -190, -62, -183, -118, -194, -142, +-189, -148, -148, -143, -66, -121, 34, -83, +138, -35, 205, 21, 218, 65, 172, 77, +84, 66, -24, 49, -82, 50, -61, 91, +5, 168, 50, 248, 41, 268, -40, 189, +-159, 13, -284, -216, -360, -420, -352, -526, +-231, -489, -36, -317, 179, -56, 314, 204, +318, 386, 203, 447, 69, 396, -17, 250, +-39, 69, -29, -83, -21, -170, -37, -194, +-71, -161, -131, -95, -195, -32, -234, 1, +-197, 5, -90, -13, 48, -33, 138, -32, +143, 2, 77, 72, 5, 158, -39, 215, +-49, 192, -52, 75, -42, -119, -43, -323, +-59, -459, -82, -453, -78, -274, -36, 44, +53, 398, 150, 667, 198, 749, 145, 602, +8, 259, -167, -177, -302, -568, -362, -808, +-313, -831, -177, -627, 2, -256, 149, 158, +228, 501, 229, 699, 182, 728, 107, 586, +38, 334, -22, 47, -79, -220, -136, -437, +-162, -569, -166, -592, -154, -490, -125, -270, +-61, 25, 5, 319, 61, 525, 86, 580, +67, 476, 3, 244, -62, -51, -97, -324, +-77, -510, -15, -580, 73, -518, 141, -298, +159, 50, 97, 447, -10, 789, -102, 953, +-148, 831, -155, 412, -127, -208, -105, -835, +-115, -1253, -154, -1301, -160, -940, -124, -276, +-36, 474, 99, 1060, 251, 1293, 340, 1111, +303, 602, 149, -48, -44, -613, -203, -906, +-267, -852, -238, -519, -142, -54, -41, 373, +29, 613, 51, 596, 39, 365, 1, 23, +-58, -310, -130, -538, -167, -606, -154, -503, +-71, -251, 63, 85, 206, 421, 265, 668, +194, 736, 15, 573, -177, 217, -297, -208, +-278, -562, -118, -725, 117, -634, 304, -319, +362, 93, 254, 442, 21, 600, -257, 528, +-463, 262, -534, -104, -445, -434, -243, -603, +30, -561, 301, -325, 484, 26, 532, 368, +457, 589, 255, 615, -29, 443, -317, 137, +-515, -188, -600, -439, -528, -529, -297, -437, +27, -209, 338, 73, 534, 319, 548, 438, +380, 390, 82, 197, -217, -66, -412, -320, +-458, -481, -390, -477, -221, -301, 2, -19, +211, 281, 336, 515, 338, 605, 210, 504, +16, 233, -170, -125, -278, -466, -296, -663, +-223, -635, -113, -387, -7, 2, 74, 398, +123, 637, 138, 617, 134, 347, 113, -49, +72, -402, 1, -552, -73, -441, -122, -137, +-117, 201, -97, 423, -87, 437, -101, 238, +-112, -67, -105, -311, -37, -384, 81, -297, +174, -114, 176, 87, 89, 230, -50, 268, +-174, 218, -225, 121, -161, 8, -28, -113, +135, -212, 261, -248, 282, -198, 171, -72, +-39, 104, -263, 271, -400, 332, -401, 238, +-250, 33, -16, -188, 230, -333, 378, -328, +386, -173, 237, 65, -34, 275, -316, 349, +-474, 237, -449, -12, -260, -275, 24, -420, +333, -371, 533, -115, 545, 263, 342, 594, +-11, 696, -399, 501, -665, 74, -695, -452, +-467, -881, -79, -999, 324, -728, 583, -171, +630, 480, 443, 994, 107, 1157, -255, 890, +-509, 299, -582, -410, -457, -969, -173, -1142, +194, -861, 501, -259, 625, 428, 505, 928, +174, 1043, -284, 732, -690, 134, -866, -514, +-716, -961, -310, -1020, 223, -676, 709, -85, +969, 535, 873, 965, 448, 1036, -139, 719, +-664, 132, -952, -496, -890, -921, -514, -975, +20, -659, 490, -102, 765, 495, 763, 900, +471, 929, 5, 581, -440, 5, -716, -587, +-742, -976, -528, -1002, -144, -642, 248, -22, +530, 645, 616, 1096, 508, 1146, 252, 779, +-54, 128, -288, -566, -377, -1017, -325, -1052, +-181, -688, -44, -105, 23, 458, -14, 767, +-85, 697, -123, 309, -91, -181, 0, -547, +110, -639, 204, -411, 253, 29, 232, 473, +138, 732, -25, 712, -190, 417, -305, -34, +-312, -461, -199, -708, 3, -704, 202, -452, +308, -55, 249, 319, 38, 518, -244, 479, +-458, 235, -493, -102, -309, -376, 14, -436, +348, -264, 550, 46, 557, 361, 361, 535, +50, 468, -265, 204, -463, -107, -462, -343, +-267, -433, 15, -344, 242, -131, 296, 80, +159, 182, -127, 140, -386, -9, -476, -183, +-342, -280, -60, -228, 261, -21, 525, 262, +629, 499, 516, 586, 226, 463, -140, 162, +-439, -181, -604, -427, -572, -527, -370, -477, +-76, -308, 201, -92, 374, 84, 408, 203, +291, 284, 56, 317, -173, 270, -301, 147, +-293, -42, -216, -249, -90, -385, 64, -382, +201, -240, 262, 13, 239, 309, 177, 525, +100, 563, -12, 431, -140, 178, -254, -152, +-309, -462, -288, -626, -167, -590, 12, -379, +150, -44, 191, 309, 156, 530, 68, 510, +-42, 254, -141, -136, -182, -506, -152, -684, +-48, -536, 101, -91, 256, 477, 348, 949, +344, 1130, 222, 914, 17, 352, -227, -362, +-431, -990, -526, -1299, -497, -1178, -353, -700, +-114, -59, 141, 522, 340, 839, 422, 810, +422, 506, 346, 102, 216, -205, 64, -270, +-85, -102, -221, 163, -346, 341, -423, 303, +-410, 26, -328, -368, -154, -679, 95, -732, +384, -456, 592, 69, 620, 640, 462, 998, +162, 957, -219, 501, -596, -239, -825, -995, +-788, -1449, -531, -1382, -129, -759, 298, 246, +642, 1267, 783, 1887, 698, 1866, 480, 1205, +226, 107, -37, -1016, -288, -1717, -503, -1793, +-650, -1314, -747, -493, -729, 340, -519, 874, +-107, 999, 401, 813, 878, 487, 1179, 201, +1169, 50, 770, 0, 78, -48, -698, -153, +-1316, -340, -1572, -554, -1331, -670, -629, -554, +340, -197, 1238, 287, 1751, 727, 1660, 951, +994, 831, -33, 379, -1070, -233, -1740, -776, +-1801, -1052, -1238, -952, -270, -489, 725, 164, +1420, 753, 1587, 1069, 1231, 1026, 512, 632, +-276, 16, -868, -583, -1130, -942, -1021, -976, +-635, -700, -140, -213, 313, 283, 594, 594, +675, 647, 552, 479, 304, 191, -2, -72, +-273, -197, -418, -165, -434, -47, -353, 59, +-201, 71, -17, -24, 162, -166, 278, -251, +352, -209, 358, -47, 276, 158, 111, 322, +-101, 341, -312, 157, -467, -161, -498, -448, +-361, -583, -99, -487, 199, -142, 419, 346, +512, 768, 428, 950, 170, 805, -152, 333, +-394, -316, -511, -879, -463, -1137, -230, -1001, +125, -495, 437, 219, 583, 842, 526, 1099, +280, 912, -103, 371, -470, -318, -672, -866, +-614, -1018, -365, -716, -23, -113, 311, 527, +534, 928, 566, 915, 400, 509, 137, -85, +-117, -601, -318, -812, -396, -638, -342, -183, +-181, 306, -21, 589, 97, 540, 190, 203, +234, -254, 209, -595, 109, -636, -37, -345, +-188, 139, -330, 585, -370, 757, -270, 569, +-27, 106, 277, -404, 523, -703, 603, -625, +445, -190, 100, 397, -294, 825, -612, 833, +-740, 375, -620, -355, -248, -1024, 225, -1293, +617, -988, 780, -219, 617, 680, 162, 1321, +-363, 1423, -706, 941, -742, 110, -477, -713, +12, -1196, 516, -1139, 793, -597, 719, 143, +344, 739, -188, 960, -652, 722, -844, 130, +-656, -533, -191, -937, 316, -899, 649, -434, +702, 255, 463, 864, 31, 1089, -391, 826, +-593, 210, -537, -463, -264, -891, 102, -888, +408, -494, 491, 61, 315, 475, 29, 564, +-207, 336, -317, -23, -276, -299, -125, -348, +79, -157, 199, 135, 201, 336, 109, 330, +-15, 123, -120, -158, -185, -334, -151, -319, +-34, -147, 49, 111, 51, 316, 10, 317, +23, 135, 58, -74, 104, -211, 161, -232, +179, -98, 102, 114, -69, 217, -258, 122, +-387, -111, -407, -357, -264, -483, -7, -361, +272, 6, 437, 465, 414, 786, 233, 821, +5, 530, -185, 3, -278, -584, -250, -986, +-109, -1015, 67, -636, 200, 0, 218, 668, +114, 1111, -65, 1129, -249, 660, -384, -134, +-355, -939, -147, -1415, 145, -1322, 377, -662, +480, 303, 417, 1204, 178, 1667, -145, 1452, +-402, 637, -503, -407, -390, -1260, -120, -1585, +211, -1236, 435, -382, 452, 559, 240, 1198, +-105, 1312, -389, 857, -485, 19, -380, -819, +-89, -1300, 273, -1258, 547, -735, 569, 95, +362, 929, 6, 1439, -397, 1415, -689, 881, +-742, 35, -498, -812, -39, -1345, 449, -1366, +799, -885, 854, -102, 590, 657, 78, 1106, +-464, 1098, -824, 680, -889, 37, -616, -579, +-82, -952, 465, -950, 784, -586, 775, -14, +494, 549, 18, 898, -461, 916, -736, 607, +-708, 92, -418, -442, 24, -790, 439, -823, +655, -562, 594, -149, 320, 272, -48, 575, +-366, 668, -522, 534, -467, 238, -241, -109, +61, -401, 291, -552, 374, -524, 292, -319, +96, -7, -144, 308, -316, 509, -348, 516, +-250, 319, -60, 19, 159, -269, 307, -446, +358, -444, 294, -252, 153, 40, -45, 308, +-235, 432, -359, 360, -404, 113, -343, -210, +-168, -467, 107, -520, 433, -315, 627, 72, +562, 489, 218, 751, -239, 708, -639, 338, +-840, -226, -706, -759, -273, -1015, 283, -858, +771, -352, 1006, 304, 871, 862, 354, 1063, +-303, 794, -836, 208, -1046, -400, -865, -790, +-366, -803, 259, -418, 758, 139, 915, 547, +680, 635, 166, 410, -359, -35, -680, -471, +-672, -645, -385, -488, 29, -132, 382, 258, +544, 506, 457, 491, 201, 256, -88, -23, +-292, -182, -378, -136, -322, 40, -136, 156, +80, 81, 206, -160, 224, -467, 132, -648, +-12, -482, -154, 42, -225, 661, -202, 1033, +-101, 919, 52, 311, 206, -522, 315, -1175, +338, -1310, 220, -783, 12, 214, -204, 1170, +-330, 1596, -363, 1303, -288, 389, -87, -775, +144, -1608, 287, -1684, 287, -1009, 159, 97, +-31, 1163, -239, 1692, -348, 1403, -321, 470, +-145, -616, 119, -1354, 359, -1439, 501, -846, +472, 114, 243, 969, -118, 1297, -468, 960, +-629, 176, -537, -613, -182, -1048, 273, -944, +598, -342, 647, 451, 407, 991, -31, 998, +-490, 477, -782, -310, -773, -983, -469, -1228, +67, -929, 625, -194, 953, 648, 908, 1210, +522, 1293, -69, 913, -625, 209, -916, -547, +-827, -1029, -414, -1101, 158, -819, 621, -297, +747, 286, 506, 708, 41, 816, -439, 596, +-675, 170, -561, -249, -149, -504, 350, -527, +706, -308, 725, 62, 372, 356, -192, 404, +-722, 219, -972, -71, -773, -321, -186, -381, +561, -184, 1115, 173, 1227, 502, 823, 631, +54, 438, -770, -34, -1353, -573, -1442, -921, +-977, -915, -167, -501, 683, 156, 1265, 769, +1395, 1092, 987, 979, 244, 418, -481, -339, +-929, -923, -971, -1090, -618, -781, -51, -88, +439, 695, 606, 1190, 451, 1162, 81, 604, +-303, -272, -547, -1064, -549, -1400, -287, -1152, +137, -425, 513, 496, 674, 1195, 563, 1325, +239, 830, -188, -18, -521, -822, -625, -1244, +-463, -1086, -106, -379, 308, 559, 586, 1299, +606, 1506, 350, 1085, -75, 189, -502, -821, +-730, -1541, -675, -1676, -380, -1169, 59, -214, +496, 782, 746, 1401, 740, 1406, 473, 835, +42, -43, -407, -821, -684, -1149, -709, -906, +-507, -241, -121, 518, 318, 1008, 627, 1001, +719, 533, 557, -139, 212, -695, -208, -886, +-534, -652, -672, -157, -594, 332, -335, 570, +-19, 432, 252, 13, 440, -441, 505, -709, +438, -637, 240, -183, 10, 438, -196, 919, +-333, 1095, -365, 901, -275, 328, -75, -403, +147, -953, 277, -1128, 270, -913, 127, -381, +-74, 250, -267, 721, -332, 881, -227, 703, +-28, 268, 161, -217, 298, -570, 343, -710, +250, -621, 38, -342, -168, 25, -280, 387, +-258, 657, -130, 742, 39, 617, 176, 329, +249, -61, 211, -456, 73, -704, -98, -696, +-232, -457, -327, -98, -338, 226, -204, 375, +34, 321, 263, 135, 424, -82, 467, -190, +376, -85, 151, 166, -129, 367, -390, 381, +-520, 187, -458, -154, -244, -483, 69, -603, +362, -420, 467, 33, 365, 549, 139, 815, +-95, 646, -282, 121, -336, -550, -238, -1062, +-59, -1111, 136, -603, 258, 238, 242, 1042, +120, 1411, -42, 1104, -156, 261, -174, -687, +-54, -1318, 117, -1314, 213, -625, 177, 391, +17, 1191, -201, 1402, -355, 906, -345, -98, +-169, -1086, 72, -1528, 315, -1234, 448, -358, +397, 699, 187, 1410, -83, 1433, -297, 803, +-360, -162, -263, -982, -67, -1240, 147, -882, +305, -195, 296, 505, 113, 898, -144, 756, +-355, 212, -426, -322, -278, -591, 17, -533, +311, -183, 465, 242, 440, 439, 249, 323, +-16, 3, -240, -312, -347, -409, -291, -206, +-82, 180, 134, 553, 245, 669, 218, 377, +87, -183, -129, -669, -326, -873, -359, -716, +-211, -202, 41, 458, 318, 895, 494, 881, +477, 446, 242, -170, -89, -654, -383, -809, +-490, -597, -358, -103, -78, 429, 231, 704, +423, 611, 364, 268, 74, -151, -284, -476, +-481, -541, -422, -316, -112, 36, 309, 336, +634, 478, 685, 390, 395, 72, -131, -326, +-631, -616, -840, -671, -649, -466, -149, -44, +475, 481, 906, 926, 897, 1058, 452, 783, +-206, 201, -792, -503, -1038, -1134, -815, -1399, +-218, -1095, 467, -323, 961, 604, 1041, 1363, +671, 1627, 40, 1202, -562, 222, -894, -915, +-802, -1751, -355, -1904, 219, -1245, 656, -15, +789, 1305, 569, 2167, 99, 2165, -392, 1280, +-712, -123, -751, -1497, -460, -2298, 6, -2170, +429, -1168, 665, 251, 694, 1501, 500, 2117, +135, 1859, -257, 851, -540, -458, -617, -1523, +-458, -1947, -140, -1580, 242, -569, 550, 684, +652, 1648, 452, 1924, 52, 1429, -387, 408, +-730, -744, -793, -1594, -485, -1785, 70, -1231, +637, -242, 968, 712, 942, 1264, 521, 1261, +-134, 759, -732, 18, -1008, -613, -851, -852, +-342, -650, 287, -202, 775, 240, 912, 481, +662, 426, 125, 155, -446, -118, -781, -239, +-770, -172, -469, 55, 3, 276, 461, 274, +734, 20, 738, -331, 497, -600, 102, -618, +-287, -321, -548, 180, -629, 668, -522, 892, +-256, 685, 75, 164, 397, -369, 623, -698, +672, -706, 473, -336, 81, 223, -358, 626, +-710, 685, -839, 407, -636, -116, -136, -639, +487, -871, 963, -699, 1091, -237, 769, 315, +107, 737, -633, 850, -1147, 596, -1180, 98, +-696, -407, 87, -680, 861, -619, 1314, -286, +1232, 186, 596, 631, -290, 806, -1062, 585, +-1429, 77, -1211, -516, -454, -996, 523, -1130, +1292, -792, 1517, -100, 1133, 684, 305, 1267, +-600, 1377, -1232, 946, -1339, 145, -874, -752, +-87, -1387, 648, -1422, 1074, -865, 1051, 9, +584, 897, -92, 1458, -616, 1368, -807, 675, +-663, -270, -271, -1096, 186, -1493, 481, -1257, +549, -508, 409, 406, 154, 1133, -36, 1384, +-76, 1077, -62, 419, -68, -320, -121, -889, +-260, -1069, -413, -841, -395, -404, -147, 84, +241, 507, 612, 690, 791, 611, 630, 450, +172, 247, -398, -48, -848, -334, -921, -519, +-528, -634, 146, -623, 813, -379, 1167, 62, +1028, 570, 403, 983, -438, 1055, -1104, 667, +-1312, -37, -958, -802, -187, -1346, 640, -1344, +1167, -726, 1162, 232, 657, 1146, -89, 1643, +-713, 1423, -957, 552, -723, -560, -120, -1444, +550, -1741, 913, -1266, 790, -212, 290, 916, +-319, 1609, -764, 1586, -817, 845, -460, -268, +117, -1233, 603, -1623, 797, -1256, 642, -285, +198, 792, -340, 1453, -711, 1461, -749, 842, +-435, -187, 49, -1146, 508, -1543, 807, -1243, +815, -449, 477, 505, -23, 1223, -459, 1402, +-726, 989, -769, 187, -503, -644, -20, -1139, +438, -1144, 704, -703, 720, 12, 461, 698, +31, 1031, -406, 927, -669, 466, -623, -209, +-263, -799, 226, -987, 651, -763, 858, -261, +691, 373, 158, 868, -442, 935, -839, 571, +-931, 3, -663, -500, -60, -757, 580, -711, +952, -389, 930, 106, 530, 500, -76, 575, +-587, 435, -794, 259, -631, 18, -162, -240, +392, -365, 731, -378, 741, -377, 430, -290, +-87, -44, -572, 286, -771, 563, -606, 688, +-186, 558, 313, 134, 703, -449, 772, -908, +473, -991, -52, -619, -545, 51, -779, 740, +-629, 1134, -146, 1008, 440, 363, 879, -465, +972, -1015, 623, -1036, 35, -578, -501, 177, +-818, 875, -826, 1081, -512, 642, -34, -147, +389, -838, 610, -1089, 592, -781, 380, -29, +75, 795, -224, 1231, -395, 999, -363, 229, +-173, -658, 52, -1242, 274, -1268, 449, -663, +493, 324, 355, 1183, 79, 1503, -250, 1193, +-528, 405, -684, -560, -611, -1317, -239, -1541, +292, -1178, 739, -441, 925, 397, 756, 1085, +271, 1375, -399, 1165, -920, 577, -971, -160, +-547, -834, 142, -1207, 837, -1093, 1271, -533, +1161, 238, 437, 950, -515, 1288, -1257, 1065, +-1502, 352, -1125, -570, -259, -1330, 746, -1560, +1451, -1130, 1517, -224, 961, 790, 99, 1514, +-671, 1604, -1095, 1038, -1040, 137, -555, -743, +79, -1297, 551, -1263, 754, -715, 678, 2, +372, 594, -1, 897, -263, 820, -373, 470, +-340, 48, -237, -327, -135, -576, -25, -631, +117, -559, 225, -401, 254, -101, 266, 285, +279, 601, 190, 790, 27, 775, -116, 461, +-188, -74, -155, -600, -62, -914, 31, -878, +116, -480, 142, 134, 67, 707, -77, 995, +-165, 831, -182, 269, -157, -437, -12, -1003, +209, -1194, 340, -857, 369, -123, 351, 669, +268, 1205, 64, 1293, -182, 856, -364, 58, +-424, -717, -338, -1133, -162, -1093, 79, -619, +377, 116, 562, 763, 504, 1012, 265, 811, +-42, 282, -401, -362, -665, -896, -614, -1102, +-272, -843, 191, -188, 659, 536, 948, 1038, +863, 1215, 410, 969, -159, 246, -639, -625, +-901, -1195, -816, -1278, -408, -844, 141, 28, +648, 946, 882, 1460, 719, 1322, 301, 526, +-156, -613, -580, -1517, -784, -1778, -567, -1291, +-74, -170, 423, 1131, 804, 1899, 893, 1794, +572, 956, 27, -310, -445, -1476, -724, -1875, +-693, -1328, -330, -214, 91, 947, 353, 1688, +456, 1602, 352, 688, 75, -565, -162, -1531, +-141, -1760, 47, -1157, 229, -72, 333, 1012, +232, 1655, -81, 1491, -383, 577, -503, -485, +-311, -1185, 162, -1365, 628, -933, 804, 10, +665, 900, 238, 1242, -446, 1027, -1032, 424, +-1098, -359, -711, -943, -98, -1069, 630, -771, +1193, -225, 1262, 336, 837, 659, 146, 671, +-541, 445, -989, 117, -1026, -173, -619, -322, +57, -352, 672, -261, 981, -38, 909, 207, +523, 349, -84, 421, -686, 374, -945, 91, +-785, -332, -404, -632, 82, -694, 556, -525, +812, -133, 703, 367, 376, 680, 49, 626, +-248, 294, -428, -109, -372, -362, -143, -325, +166, -51, 412, 298, 499, 485, 422, 325, +140, -105, -318, -514, -720, -715, -839, -631, +-640, -204, -204, 388, 440, 734, 1080, 677, +1336, 362, 1055, -73, 388, -472, -442, -615, +-1177, -459, -1505, -110, -1198, 257, -335, 457, +737, 446, 1571, 343, 1799, 169, 1308, -83, +291, -288, -917, -361, -1814, -412, -1928, -414, +-1227, -207, -55, 145, 1170, 429, 1920, 556, +1828, 477, 1019, 173, -112, -269, -1141, -631, +-1595, -683, -1269, -351, -443, 187, 484, 655, +1215, 865, 1372, 714, 865, 164, 55, -522, +-706, -924, -1164, -896, -1081, -535, -511, 57, +239, 643, 882, 897, 1178, 686, 950, 178, +379, -373, -233, -760, -739, -804, -923, -444, +-620, 133, -73, 651, 412, 912, 733, 842, +787, 439, 450, -186, -68, -781, -444, -1076, +-605, -956, -558, -455, -302, 215, 58, 804, +378, 1108, 535, 964, 549, 371, 472, -387, +292, -979, 23, -1161, -262, -827, -459, -107, +-508, 648, -399, 1131, -84, 1149, 339, 660, +635, -118, 654, -777, 401, -1073, -40, -910, +-529, -336, -833, 321, -718, 698, -250, 707, +359, 385, 918, -102, 1190, -452, 961, -483, +299, -261, -456, 65, -975, 321, -1122, 373, +-839, 221, -176, -2, 554, -166, 965, -148, +992, 36, 696, 178, 155, 139, -427, -23, +-813, -245, -845, -431, -530, -453, -27, -252, +496, 102, 867, 447, 958, 616, 677, 529, +161, 188, -326, -247, -728, -546, -924, -592, +-730, -392, -240, 35, 351, 539, 806, 833, +952, 742, 771, 313, 300, -337, -316, -957, +-783, -1218, -879, -966, -604, -254, -97, 669, +512, 1319, 944, 1380, 960, 892, 616, -27, +78, -1080, -476, -1640, -807, -1338, -783, -410, +-453, 692, 22, 1550, 465, 1713, 705, 1059, +656, -72, 357, -1194, -31, -1801, -340, -1531, +-471, -614, -391, 440, -183, 1255, 98, 1495, +464, 996, 690, 116, 602, -628, 322, -999, +-30, -905, -452, -360, -802, 257, -787, 584, +-405, 624, 110, 423, 629, 0, 925, -332, +839, -334, 431, -167, -150, -44, -656, 18, +-814, 22, -536, -66, 13, -187, 565, -193, +917, -18, 848, 267, 361, 472, -265, 464, +-765, 263, -963, -86, -733, -487, -146, -673, +469, -499, 815, -99, 851, 336, 542, 699, +-4, 796, -444, 446, -556, -171, -381, -667, +-32, -922, 384, -869, 657, -388, 579, 315, +240, 812, -151, 973, -430, 824, -529, 332, +-456, -344, -226, -822, 85, -923, 340, -668, +441, -120, 377, 485, 257, 845, 117, 858, +-59, 489, -201, -140, -211, -692, -114, -938, +35, -822, 245, -333, 421, 314, 401, 755, +195, 841, -97, 615, -356, 127, -477, -377, +-368, -586, -61, -483, 254, -199, 440, 200, +408, 478, 132, 429, -211, 123, -413, -274, +-335, -598, -29, -650, 347, -390, 680, 67, +782, 554, 538, 866, 80, 783, -378, 314, +-639, -295, -687, -796, -514, -976, -97, -676, +362, -8, 609, 711, 554, 1130, 270, 1006, +-82, 362, -404, -504, -549, -1206, -373, -1387, +86, -899, 601, 57, 915, 981, 891, 1440, +489, 1284, -183, 571, -797, -440, -1064, -1219, +-901, -1359, -341, -881, 438, -84, 999, 718, +1058, 1222, 699, 1175, 74, 578, -638, -227, +-1069, -904, -926, -1252, -302, -1152, 442, -604, +1052, 218, 1268, 1022, 947, 1483, 241, 1419, +-581, 813, -1151, -192, -1178, -1276, -732, -1948, +27, -1814, 830, -891, 1265, 466, 1116, 1786, +548, 2435, -188, 2005, -897, 695, -1231, -946, +-972, -2284, -362, -2653, 367, -1813, 1011, -224, +1270, 1348, 1051, 2310, 500, 2280, -176, 1260, +-720, -222, -979, -1452, -910, -1944, -486, -1569, +154, -627, 628, 431, 814, 1218, 838, 1433, +582, 1042, -32, 370, -623, -278, -868, -768, +-829, -1003, -537, -907, 96, -557, 835, -97, +1289, 363, 1294, 738, 859, 899, 66, 754, +-858, 321, -1525, -225, -1568, -705, -919, -937, +113, -731, 1062, -137, 1642, 501, 1630, 914, +862, 954, -313, 558, -1237, -129, -1605, -799, +-1374, -1165, -551, -1027, 589, -458, 1508, 241, +1851, 796, 1484, 1071, 518, 934, -605, 440, +-1443, -108, -1737, -520, -1317, -762, -370, -706, +663, -388, 1410, -7, 1617, 338, 1140, 569, +159, 551, -857, 318, -1470, -15, -1429, -361, +-740, -590, 283, -554, 1307, -263, 1901, 163, +1635, 544, 633, 652, -561, 407, -1487, 7, +-1834, -402, -1438, -682, -400, -588, 789, -126, +1581, 398, 1670, 754, 1093, 786, 152, 421, +-821, -169, -1464, -651, -1434, -846, -795, -720, +112, -307, 982, 184, 1542, 481, 1554, 564, +1024, 506, 177, 338, -724, 141, -1399, -15, +-1572, -186, -1175, -400, -378, -617, 558, -713, +1349, -521, 1632, 39, 1268, 762, 457, 1251, +-505, 1249, -1272, 723, -1517, -265, -1102, -1352, +-193, -1929, 762, -1621, 1384, -549, 1468, 844, +1032, 1948, 267, 2197, -610, 1450, -1180, 90, +-1126, -1318, -676, -2146, -119, -1943, 441, -888, +809, 408, 734, 1450, 337, 1800, -13, 1283, +-245, 277, -352, -658, -176, -1187, 145, -1102, +342, -497, 311, 163, 74, 552, -219, 665, +-364, 424, -292, -63, -36, -351, 364, -299, +730, -116, 728, 148, 332, 337, -210, 210, +-718, -108, -1041, -349, -909, -453, -302, -356, +428, 18, 1006, 482, 1291, 715, 1081, 625, +428, 271, -319, -204, -847, -601, -1076, -759, +-924, -582, -380, -112, 285, 328, 794, 486, +1002, 415, 824, 200, 408, -134, -104, -412, +-632, -378, -950, -34, -837, 314, -382, 495, +169, 485, 724, 214, 1113, -246, 1026, -596, +548, -665, -43, -458, -597, -13, -976, 515, +-958, 814, -520, 737, 75, 348, 604, -271, +925, -879, 865, -1109, 478, -894, -56, -339, +-557, 443, -813, 1131, -685, 1376, -265, 1094, +261, 371, 785, -525, 1062, -1208, 853, -1406, +330, -1053, -305, -230, -920, 707, -1222, 1249, +-995, 1229, -342, 771, 486, -72, 1220, -965, +1514, -1325, 1160, -1024, 361, -360, -615, 410, +-1416, 999, -1577, 1085, -989, 632, -3, -46, +1005, -596, 1695, -789, 1664, -563, 822, -64, +-318, 452, -1238, 732, -1645, 577, -1338, 114, +-396, -335, 710, -621, 1439, -706, 1530, -497, +1003, -75, 103, 293, -769, 433, -1323, 426, +-1268, 334, -583, 143, 252, -47, 859, -100, +1178, -90, 1082, -112, 498, -129, -276, -80, +-740, 12, -816, 102, -615, 179, -174, 191, +329, 68, 642, -151, 611, -404, 321, -569, +21, -524, -229, -272, -383, 130, -325, 575, +-73, 838, 163, 822, 256, 597, 282, 195, +244, -329, 68, -748, -95, -895, -110, -806, +-60, -498, -35, 50, 35, 612, 129, 912, +141, 883, 64, 533, -19, -66, -30, -705, +17, -1133, 28, -1076, 26, -492, 56, 317, +64, 1004, -8, 1367, -17, 1220, 107, 513, +163, -414, 97, -1087, 60, -1329, -1, -1116, +-131, -480, -239, 309, -199, 862, 2, 977, +237, 716, 399, 298, 462, -154, 395, -523, +153, -600, -219, -389, -468, -139, -504, 66, +-407, 241, -156, 313, 237, 235, 578, 139, +666, 140, 490, 154, 218, 52, -107, -150, +-495, -354, -764, -516, -650, -626, -252, -486, +158, 21, 582, 623, 980, 1019, 1037, 1081, +676, 652, 127, -196, -442, -1027, -956, -1436, +-1173, -1218, -936, -351, -367, 801, 336, 1607, +932, 1663, 1228, 960, 1119, -288, 518, -1525, +-307, -2027, -905, -1527, -1064, -313, -838, 1053, +-272, 1898, 494, 1824, 1008, 905, 992, -424, +634, -1530, 118, -1834, -399, -1207, -705, -60, +-646, 1020, -342, 1594, -25, 1396, 253, 542, +436, -448, 395, -1140, 221, -1338, 83, -934, +17, -136, -43, 573, -75, 910, -70, 882, +-88, 524, -110, -64, -86, -560, 16, -708, +218, -560, 347, -205, 345, 251, 293, 600, +116, 712, -241, 541, -524, 90, -504, -438, +-321, -738, -128, -717, 225, -462, 613, -1, +749, 527, 617, 758, 329, 547, -70, 106, +-522, -389, -803, -737, -715, -652, -367, -155, +114, 465, 589, 931, 899, 1000, 907, 532, +544, -257, -44, -937, -559, -1238, -839, -996, +-870, -191, -590, 723, 7, 1207, 580, 1096, +849, 416, 840, -572, 620, -1299, 208, -1327, +-253, -670, -556, 403, -630, 1399, -524, 1749, +-290, 1253, 8, 172, 369, -1023, 643, -1756, +686, -1604, 539, -747, 215, 312, -249, 1217, +-652, 1546, -802, 1037, -600, 67, -128, -766, +434, -1204, 848, -1180, 913, -635, 582, 182, +-8, 808, -555, 1073, -791, 1032, -672, 725, +-211, 219, 392, -364, 768, -859, 747, -1102, +416, -1044, -108, -685, -619, -4, -796, 791, +-537, 1286, -77, 1242, 407, 696, 767, -190, +785, -1117, 419, -1570, -50, -1241, -379, -354, +-523, 698, -447, 1528, -143, 1724, 231, 1125, +463, 41, 381, -987, 143, -1575, -49, -1533, +-191, -855, -267, 133, -189, 945, 35, 1262, +190, 1026, 163, 415, 139, -281, 111, -818, +28, -973, -20, -643, 61, -70, 213, 400, +240, 668, 134, 733, 23, 509, -137, 54, +-323, -286, -434, -401, -334, -447, -45, -395, +244, -227, 455, -86, 559, 17, 463, 147, +143, 276, -267, 363, -479, 366, -451, 188, +-257, -113, 79, -339, 444, -430, 675, -340, +648, 37, 347, 472, -109, 614, -602, 448, +-891, 12, -829, -603, -427, -970, 196, -813, +813, -231, 1146, 567, 992, 1218, 427, 1272, +-273, 633, -904, -375, -1128, -1320, -775, -1731, +-72, -1272, 647, -112, 1093, 1197, 1052, 2055, +558, 2025, -141, 1066, -757, -439, -1033, -1861, +-751, -2515, -138, -2047, 419, -703, 759, 918, +743, 2171, 308, 2526, -225, 1804, -521, 256, +-527, -1389, -235, -2344, 292, -2311, 646, -1366, +634, 191, 410, 1743, 28, 2535, -413, 2208, +-621, 1021, -523, -533, -243, -1897, 121, -2519, +429, -2114, 433, -846, 252, 713, 95, 1866, +-146, 2217, -325, 1709, -167, 508, 116, -866, +263, -1734, 319, -1789, 348, -1133, 210, -30, +-53, 1095, -238, 1674, -286, 1467, -242, 718, +-171, -288, -86, -1225, 92, -1610, 222, -1297, +166, -537, 89, 372, 157, 1138, 164, 1436, +37, 1134, -13, 392, 29, -465, 6, -1093, +-61, -1270, -73, -958, -19, -245, 28, 608, +120, 1219, 203, 1310, 166, 920, 54, 220, +-81, -587, -191, -1192, -240, -1330, -225, -957, +-67, -307, 107, 350, 167, 879, 164, 1073, +178, 849, 208, 390, 175, -104, 174, -502, +275, -698, 185, -661, -108, -428, -357, -63, +-466, 318, -474, 559, -356, 637, 37, 551, +579, 228, 824, -248, 645, -607, 251, -770, +-158, -751, -620, -404, -937, 194, -703, 647, +-59, 799, 534, 739, 887, 410, 974, -208, +759, -712, 169, -789, -516, -530, -877, -68, +-810, 432, -518, 743, -104, 750, 435, 369, +792, -260, 649, -675, 274, -673, -69, -487, +-374, -152, -593, 332, -504, 592, -88, 391, +320, -8, 501, -299, 541, -404, 451, -270, +175, 91, -205, 461, -383, 621, -276, 453, +-88, 59, 81, -323, 235, -541, 242, -481, +-2, -181, -370, 115, -542, 210, -436, 67, +-167, -157, 218, -282, 710, -213, 1045, 102, +917, 573, 408, 828, -200, 604, -801, 60, +-1195, -559, -1095, -1074, -457, -1139, 345, -540, +1012, 408, 1410, 1160, 1265, 1436, 497, 1102, +-483, 187, -1253, -910, -1579, -1656, -1360, -1692, +-531, -983, 602, 161, 1474, 1277, 1761, 1858, +1453, 1620, 664, 691, -398, -453, -1344, -1352, +-1666, -1703, -1271, -1304, -475, -278, 450, 783, +1269, 1334, 1538, 1313, 1068, 807, 236, -92, +-509, -931, -1094, -1224, -1378, -914, -1025, -307, +-130, 327, 687, 816, 1142, 906, 1278, 516, +985, -76, 230, -514, -609, -610, -1050, -446, +-956, -89, -547, 383, 39, 692, 615, 582, +888, 135, 671, -346, 133, -705, -314, -865, +-558, -603, -646, 78, -406, 748, 9, 1032, +319, 903, 458, 369, 489, -447, 442, -1109, +283, -1222, 101, -706, -36, 200, -203, 1050, +-328, 1429, -454, 1122, -506, 230, -304, -871, +68, -1590, 420, -1519, 664, -742, 697, 397, +393, 1430, -146, 1795, -570, 1272, -809, 183, +-748, -946, -222, -1650, 467, -1576, 918, -759, +1064, 357, 837, 1236, 212, 1556, -499, 1162, +-919, 204, -1037, -761, -779, -1298, -146, -1312, +469, -757, 814, 171, 888, 1021, 595, 1383, +46, 1171, -466, 489, -759, -450, -787, -1260, +-416, -1567, 256, -1194, 838, -245, 1111, 825, +992, 1609, 408, 1852, -377, 1292, -1034, -30, +-1338, -1416, -1139, -2171, -405, -2121, 538, -1237, +1212, 341, 1412, 1907, 1114, 2652, 346, 2293, +-579, 1057, -1257, -643, -1379, -2125, -929, -2718, +-116, -2176, 741, -768, 1334, 838, 1464, 2002, +1037, 2392, 216, 1849, -644, 567, -1309, -842, +-1496, -1794, -1105, -2068, -313, -1625, 574, -608, +1260, 604, 1507, 1556, 1219, 1960, 485, 1732, +-461, 947, -1302, -201, -1597, -1360, -1263, -2051, +-496, -1969, 549, -1254, 1533, -83, 1923, 1257, +1570, 2147, 670, 2168, -530, 1388, -1660, 83, +-2145, -1320, -1730, -2233, -666, -2221, 599, -1372, +1710, -45, 2221, 1293, 1788, 2137, 579, 2185, +-792, 1444, -1763, 181, -2048, -1101, -1566, -1914, +-338, -2033, 1122, -1438, 2067, -284, 2118, 927, +1367, 1739, 129, 1911, -1215, 1319, -2147, 135, +-2112, -1127, -1186, -1919, 144, -1913, 1369, -1074, +2072, 262, 1987, 1461, 1038, 2088, -351, 1896, +-1440, 847, -1913, -588, -1659, -1680, -739, -1991, +513, -1448, 1571, -321, 1977, 854, 1651, 1550, +729, 1517, -486, 793, -1493, -277, -2005, -1158, +-1772, -1443, -828, -1127, 378, -347, 1413, 614, +1993, 1251, 1876, 1347, 1035, 1047, -148, 406, +-1158, -427, -1809, -1056, -1840, -1241, -1104, -1112, +56, -639, 1127, 168, 1811, 863, 1914, 1156, +1270, 1106, 85, 652, -1068, -160, -1858, -923, +-2013, -1273, -1374, -1153, -170, -540, 1083, 346, +1912, 1064, 2039, 1338, 1424, 1122, 319, 503, +-828, -251, -1694, -790, -1896, -979, -1298, -898, +-263, -519, 770, -65, 1554, 144, 1762, 205, +1178, 346, 123, 469, -773, 479, -1299, 486, +-1407, 420, -924, 53, 9, -445, 799, -792, +1115, -888, 1027, -632, 616, -22, -26, 657, +-558, 1119, -760, 1092, -610, 484, -248, -364, +104, -1024, 376, -1312, 566, -1056, 483, -225, +130, 751, -133, 1287, -166, 1275, -292, 801, +-394, -84, -208, -973, -25, -1314, 25, -1041, +201, -435, 394, 294, 377, 919, 257, 1111, +168, 838, -24, 289, -200, -332, -201, -760, +-168, -806, -140, -589, -29, -262, 27, 194, +-1, 571, 10, 566, 41, 322, 56, 6, +143, -324, 156, -497, 85, -375, 65, -68, +24, 311, -110, 700, -134, 760, 38, 325, +164, -152, 168, -518, 228, -893, 158, -968, +-100, -519, -340, 88, -442, 555, -341, 875, +-81, 929, 207, 640, 465, 158, 560, -423, +441, -870, 113, -925, -243, -672, -425, -253, +-437, 418, -294, 1038, 17, 1130, 336, 723, +474, 55, 350, -739, 155, -1360, -10, -1381, +-224, -670, -357, 366, -256, 1243, -88, 1661, +39, 1384, 109, 364, 146, -904, 130, -1744, +113, -1822, 147, -1084, 204, 199, 218, 1408, +100, 2042, -118, 1824, -249, 771, -333, -675, +-356, -1789, -222, -2177, 86, -1762, 402, -587, +529, 854, 447, 1899, 213, 2233, -91, 1714, +-355, 556, -528, -792, -439, -1894, -135, -2302, +209, -1731, 483, -454, 560, 908, 383, 1948, +74, 2339, -234, 1693, -470, 245, -523, -1278, +-230, -2305, 170, -2448, 414, -1479, 544, 201, +523, 1804, 192, 2696, -281, 2479, -590, 1150, +-651, -682, -476, -2220, -94, -2859, 290, -2290, +584, -733, 731, 1021, 604, 2263, 263, 2581, +-22, 1819, -271, 383, -555, -975, -660, -1832, +-476, -1994, -236, -1397, 43, -367, 417, 584, +675, 1210, 677, 1403, 502, 1224, 121, 797, +-355, 159, -697, -598, -759, -1220, -535, -1477, +-62, -1336, 515, -769, 895, 259, 893, 1322, +573, 1897, -25, 1770, -636, 973, -951, -298, +-858, -1589, -439, -2232, 146, -1886, 688, -798, +955, 604, 814, 1795, 377, 2282, -199, 1793, +-711, 543, -910, -852, -688, -1850, -205, -2143, +375, -1570, 847, -346, 1012, 942, 769, 1767, +162, 1893, -538, 1282, -987, 241, -1015, -846, +-614, -1634, -1, -1742, 679, -1124, 1125, -186, +1006, 751, 444, 1444, -240, 1561, -795, 1077, +-1032, 312, -858, -577, -225, -1311, 528, -1449, +1005, -1010, 1043, -324, 700, 477, 144, 1115, +-471, 1270, -902, 957, -903, 290, -576, -526, +-82, -1067, 402, -1144, 660, -820, 647, -237, +517, 464, 252, 1005, -159, 1100, -468, 788, +-516, 286, -474, -273, -302, -753, 87, -971, +468, -783, 649, -398, 660, 6, 438, 402, +20, 657, -387, 684, -665, 539, -783, 262, +-551, -81, -69, -379, 332, -550, 621, -604, +778, -510, 601, -268, 188, 99, -217, 498, +-491, 755, -643, 769, -522, 538, -138, 105, +256, -400, 573, -818, 767, -945, 678, -706, +297, -169, -219, 442, -648, 818, -975, 828, +-1047, 542, -636, -11, 120, -635, 827, -931, +1298, -736, 1435, -270, 1021, 320, 120, 920, +-779, 1195, -1422, 899, -1631, 251, -1185, -500, +-164, -1125, 933, -1352, 1668, -1113, 1811, -456, +1226, 456, 129, 1193, -1008, 1431, -1863, 1110, +-2006, 372, -1269, -563, -50, -1281, 1144, -1389, +1974, -905, 2043, -55, 1272, 916, 126, 1566, +-934, 1472, -1694, 664, -1814, -369, -1142, -1219, +-100, -1602, 795, -1320, 1390, -471, 1481, 557, +986, 1288, 163, 1392, -591, 896, -1028, 98, +-1141, -669, -918, -1150, -325, -1060, 350, -496, +830, 158, 1028, 693, 977, 958, 645, 826, +66, 404, -503, -114, -831, -501, -921, -625, +-709, -523, -226, -326, 278, -116, 623, 27, +782, 78, 666, 63, 284, 54, -188, 106, +-472, 282, -562, 498, -485, 554, -162, 398, +243, 77, 516, -405, 585, -859, 401, -1049, +131, -796, -150, -169, -414, 538, -547, 1127, +-418, 1398, -100, 1046, 171, 142, 383, -825, +570, -1452, 502, -1605, 136, -1138, -286, -171, +-497, 852, -528, 1545, -407, 1691, -26, 1209, +505, 296, 795, -625, 658, -1208, 320, -1395, +-55, -1166, -516, -591, -809, 120, -676, 705, +-228, 1025, 211, 1105, 521, 911, 656, 414, +515, -221, 112, -819, -333, -1190, -555, -1263, +-421, -954, -107, -182, 165, 775, 397, 1428, +566, 1602, 440, 1308, 124, 540, -133, -524, +-354, -1406, -531, -1753, -509, -1525, -326, -824, +-100, 140, 226, 1004, 612, 1477, 745, 1418, +619, 967, 311, 339, -175, -380, -635, -969, +-827, -1117, -722, -925, -326, -634, 293, -219, +808, 357, 938, 771, 753, 855, 282, 780, +-353, 577, -845, 129, -931, -395, -618, -679, +-84, -719, 449, -659, 739, -409, 719, -26, +471, 272, 22, 419, -325, 512, -382, 529, +-337, 406, -306, 259, -148, 89, 118, -230, +273, -558, 299, -762, 377, -750, 409, -482, +214, -29, -151, 521, -474, 1004, -628, 1134, +-577, 797, -371, 157, 107, -560, 726, -1189, +978, -1397, 746, -991, 319, -206, -192, 648, +-708, 1373, -933, 1648, -592, 1254, -12, 298, +411, -819, 616, -1641, 593, -1885, 324, -1472, +-103, -432, -418, 879, -343, 1859, -76, 2103, +91, 1608, 170, 469, 186, -930, -29, -1924, +-348, -2126, -423, -1545, -205, -330, 106, 1030, +484, 1875, 847, 1928, 853, 1280, 394, 61, +-231, -1198, -766, -1819, -995, -1621, -874, -805, +-444, 294, 173, 1205, 697, 1533, 881, 1176, +729, 364, 413, -558, 8, -1117, -452, -1070, +-661, -562, -531, 142, -248, 702, 44, 851, +313, 617, 469, 93, 441, -483, 281, -798, +39, -700, -216, -306, -358, 162, -360, 525, +-197, 687, -8, 584, 108, 243, 183, -198, +201, -479, 96, -503, -73, -383, -138, -182, +-49, 168, 93, 508, 278, 543, 375, 279, +238, -6, -36, -296, -242, -623, -386, -684, +-427, -331, -199, 131, 185, 534, 353, 824, +265, 747, 102, 240, -122, -334, -344, -747, +-287, -890, 5, -625, 337, -5, 600, 683, +610, 1084, 240, 982, -272, 449, -641, -327, +-757, -1025, -506, -1355, 80, -1145, 589, -416, +792, 513, 703, 1193, 292, 1386, -349, 1095, +-777, 376, -769, -579, -517, -1194, -84, -1187, +440, -743, 722, -22, 719, 724, 529, 1100, +184, 962, -229, 355, -452, -452, -465, -995, +-430, -1035, -212, -722, 136, -104, 253, 670, +249, 1112, 310, 966, 227, 450, -56, -170, +-212, -681, -186, -899, -163, -707, -113, -165, +58, 422, 232, 706, 322, 641, 293, 326, +108, -139, -96, -513, -170, -551, -236, -320, +-213, 50, -45, 373, 76, 380, 112, 78, +180, -273, 203, -511, 5, -482, -232, -100, +-233, 518, -221, 996, -207, 1032, 55, 594, +436, -168, 616, -949, 576, -1382, 371, -1259, +-44, -590, -548, 290, -885, 1044, -944, 1390, +-604, 1111, 86, 353, 763, -438, 1109, -958, +1117, -1099, 680, -809, -182, -146, -975, 491, +-1323, 809, -1200, 834, -556, 598, 460, 153, +1298, -269, 1515, -509, 1224, -584, 472, -541, +-671, -422, -1561, -255, -1614, 14, -1036, 293, +-175, 533, 839, 796, 1594, 882, 1592, 533, +876, -51, -191, -613, -1136, -1135, -1579, -1444, +-1374, -1128, -610, -205, 482, 829, 1411, 1586, +1657, 1895, 1279, 1568, 557, 594, -486, -724, +-1452, -1865, -1764, -2397, -1347, -2090, -548, -1041, +419, 343, 1357, 1657, 1841, 2515, 1580, 2493, +717, 1646, -369, 327, -1321, -1122, -1871, -2217, +-1719, -2514, -845, -2019, 394, -955, 1456, 426, +1980, 1638, 1816, 2177, 978, 2013, -236, 1275, +-1342, 170, -1929, -897, -1801, -1552, -1077, -1676, +3, -1331, 1096, -651, 1805, 151, 1822, 760, +1202, 1075, 241, 1211, -766, 1124, -1496, 653, +-1682, 26, -1309, -478, -501, -964, 553, -1371, +1498, -1323, 1818, -796, 1437, -31, 605, 758, +-456, 1345, -1400, 1514, -1867, 1184, -1616, 428, +-662, -445, 568, -1086, 1554, -1330, 1906, -1140, +1548, -545, 579, 137, -665, 616, -1591, 893, +-1814, 922, -1343, 616, -347, 167, 798, -199, +1596, -424, 1696, -621, 1125, -718, 155, -517, +-860, -143, -1506, 135, -1441, 356, -796, 601, +55, 708, 828, 493, 1208, 110, 1027, -215, +469, -392, -193, -456, -721, -441, -907, -293, +-623, -62, -92, 50, 395, 66, 691, 121, +670, 209, 332, 272, -133, 366, -517, 391, +-649, 200, -507, -113, -194, -404, 170, -632, +516, -659, 610, -395, 350, 62, -35, 487, +-295, 740, -389, 718, -381, 440, -175, 84, +299, -272, 642, -598, 517, -668, 128, -522, +-200, -418, -561, -303, -918, 10, -769, 400, +-64, 704, 598, 948, 962, 1049, 1142, 733, +973, 53, 223, -730, -722, -1393, -1301, -1638, +-1408, -1263, -1175, -417, -522, 595, 509, 1456, +1454, 1813, 1852, 1450, 1636, 595, 979, -393, +8, -1220, -1149, -1576, -2005, -1346, -2158, -712, +-1660, 81, -720, 778, 551, 1158, 1852, 1145, +2589, 843, 2429, 324, 1535, -231, 155, -612, +-1383, -819, -2571, -873, -2881, -691, -2198, -339, +-795, 43, 921, 367, 2392, 625, 3010, 775, +2544, 760, 1270, 546, -351, 208, -1900, -155, +-2807, -572, -2662, -988, -1580, -1092, -72, -838, +1377, -371, 2359, 289, 2520, 1047, 1779, 1542, +492, 1478, -810, 846, -1698, -85, -1975, -1034, +-1638, -1730, -806, -1881, 231, -1291, 1013, -187, +1355, 907, 1305, 1658, 871, 1919, 195, 1539, +-403, 616, -721, -492, -837, -1331, -816, -1686, +-546, -1597, -179, -1045, 137, -106, 471, 818, +769, 1423, 879, 1659, 766, 1438, 471, 696, +-22, -300, -688, -1236, -1226, -1862, -1378, -1900, +-1073, -1255, -400, -126, 499, 1153, 1384, 2127, +1856, 2377, 1612, 1760, 787, 522, -312, -1005, +-1427, -2308, -2135, -2764, -1985, -2173, -1063, -839, +201, 810, 1423, 2239, 2211, 2888, 2142, 2423, +1213, 1076, -111, -564, -1368, -1962, -2148, -2698, +-2066, -2460, -1191, -1331, 41, 194, 1199, 1490, +1883, 2215, 1771, 2258, 1021, 1586, 46, 432, +-856, -681, -1370, -1424, -1292, -1798, -798, -1766, +-153, -1203, 487, -368, 885, 378, 821, 1026, +539, 1584, 251, 1759, -120, 1401, -448, 683, +-486, -170, -329, -1029, -244, -1689, -160, -1907, +116, -1523, 338, -674, 337, 327, 303, 1197, +312, 1696, 200, 1714, -68, 1293, -343, 473, +-457, -455, -376, -1144, -210, -1479, -21, -1465, +244, -1063, 450, -364, 385, 402, 162, 989, +38, 1270, -105, 1238, -342, 922, -393, 291, +-193, -408, -9, -835, 92, -979, 255, -886, +459, -495, 533, -5, 406, 297, 46, 399, +-392, 373, -716, 162, -923, -78, -889, -71, +-366, 145, 457, 371, 1095, 532, 1367, 498, +1235, 197, 532, -315, -505, -870, -1365, -1181, +-1716, -1024, -1409, -513, -534, 166, 588, 932, +1556, 1532, 1922, 1541, 1467, 952, 460, 77, +-624, -848, -1543, -1600, -1971, -1859, -1516, -1452, +-391, -504, 707, 650, 1445, 1667, 1698, 2163, +1228, 1857, 184, 841, -814, -435, -1333, -1621, +-1313, -2376, -767, -2201, 178, -1055, 1025, 436, +1355, 1685, 1016, 2374, 154, 2268, -688, 1187, +-1142, -479, -1220, -1854, -803, -2417, 96, -2201, +955, -1218, 1234, 364, 1030, 1809, 571, 2387, +-150, 2153, -837, 1344, -1029, -8, -799, -1442, +-479, -2182, -94, -2104, 380, -1484, 667, -413, +671, 901, 608, 1857, 520, 2047, 285, 1570, +-69, 685, -473, -472, -892, -1556, -1147, -2024, +-1026, -1675, -568, -789, 107, 335, 902, 1342, +1594, 1842, 1808, 1679, 1376, 916, 497, -190, +-544, -1112, -1537, -1540, -2133, -1478, -2032, -954, +-1292, -94, -150, 662, 1096, 1058, 2052, 1148, +2403, 927, 2026, 478, 1047, 33, -297, -377, +-1658, -761, -2552, -1010, -2630, -1009, -1886, -800, +-585, -406, 940, 255, 2322, 1071, 3009, 1649, +2690, 1750, 1537, 1295, -65, 284, -1695, -1015, +-2879, -2069, -3104, -2537, -2257, -2164, -827, -894, +693, 740, 2044, 2088, 2833, 2846, 2671, 2673, +1716, 1466, 411, -235, -966, -1692, -2097, -2522, +-2603, -2552, -2406, -1759, -1598, -427, -300, 875, +1128, 1729, 2215, 2012, 2726, 1747, 2498, 1019, +1481, 101, -63, -689, -1649, -1219, -2750, -1531, +-2961, -1516, -2248, -1039, -877, -253, 822, 530, +2286, 1199, 2851, 1642, 2466, 1600, 1472, 1002, +77, 97, -1390, -808, -2279, -1467, -2310, -1688, +-1802, -1355, -945, -631, 217, 207, 1281, 925, +1845, 1341, 1853, 1383, 1455, 1071, 768, 487, +-102, -162, -984, -702, -1649, -1062, -1851, -1240, +-1515, -1118, -813, -662, 166, -42, 1231, 611, +1894, 1208, 1897, 1470, 1393, 1261, 501, 674, +-648, -172, -1649, -1080, -2063, -1677, -1812, -1736, +-992, -1209, 250, -185, 1436, 1010, 2066, 1899, +2012, 2180, 1248, 1759, -69, 663, -1408, -843, +-2136, -2103, -2009, -2612, -1118, -2316, 271, -1286, +1586, 361, 2233, 2035, 1988, 2944, 911, 2765, +-563, 1775, -1769, 256, -2260, -1505, -1888, -2815, +-718, -3036, 749, -2234, 1799, -795, 2143, 858, +1775, 2239, 707, 2884, -608, 2548, -1534, 1384, +-1868, -80, -1640, -1417, -879, -2340, 132, -2514, +1014, -1886, 1562, -824, 1605, 417, 1141, 1499, +442, 2008, -370, 1940, -1148, 1440, -1499, 525, +-1345, -473, -914, -1152, -194, -1482, 695, -1456, +1326, -957, 1462, -253, 1186, 312, 535, 699, +-414, 904, -1248, 847, -1586, 534, -1404, 118, +-749, -123, 226, -175, 1163, -271, 1648, -389, +1518, -296, 870, -159, -112, -244, -1081, -380, +-1675, -227, -1706, 84, -1087, 269, -53, 455, +933, 777, 1606, 887, 1782, 582, 1246, 104, +204, -366, -775, -890, -1452, -1318, -1811, -1323, +-1536, -837, -565, -148, 530, 580, 1240, 1286, +1551, 1689, 1420, 1513, 714, 888, -282, 81, +-1029, -762, -1314, -1514, -1121, -1803, -519, -1414, +189, -655, 695, 135, 859, 933, 628, 1568, +202, 1677, -133, 1172, -315, 369, -364, -459, +-238, -1184, -76, -1618, -37, -1519, -12, -917, +49, -52, 32, 833, 52, 1509, 187, 1751, +230, 1453, 52, 634, -191, -419, -315, -1312, +-328, -1819, -226, -1820, 129, -1182, 610, -82, +868, 1017, 722, 1784, 251, 2019, -352, 1515, +-943, 438, -1311, -767, -1174, -1735, -570, -2128, +208, -1714, 969, -682, 1580, 594, 1751, 1725, +1312, 2274, 460, 1941, -539, 921, -1503, -342, +-2123, -1532, -2142, -2336, -1475, -2230, -255, -1257, +1136, -87, 2273, 999, 2798, 2000, 2484, 2372, +1383, 1777, -251, 747, -1938, -266, -3061, -1364, +-3215, -2229, -2430, -2252, -940, -1557, 934, -647, +2622, 521, 3521, 1854, 3381, 2620, 2296, 2451, +568, 1637, -1435, 365, -3136, -1170, -3947, -2510, +-3665, -3115, -2338, -2718, -232, -1477, 2028, 180, +3736, 1883, 4400, 3144, 3761, 3421, 1878, 2651, +-607, 1188, -2856, -673, -4300, -2434, -4487, -3437, +-3207, -3402, -892, -2463, 1566, -793, 3384, 1156, +4182, 2705, 3711, 3423, 2006, 3192, -205, 2005, +-2112, 213, -3344, -1563, -3554, -2793, -2558, -3214, +-858, -2681, 767, -1317, 1967, 375, 2584, 1807, +2327, 2668, 1236, 2758, -80, 2005, -986, 665, +-1334, -751, -1295, -1778, -858, -2201, -85, -2079, +487, -1424, 404, -334, -93, 697, -473, 1239, +-597, 1452, -496, 1489, 109, 1116, 1155, 438, +1897, -34, 1810, -388, 1024, -904, -286, -1243, +-1908, -1154, -3108, -961, -3117, -685, -1904, -54, +46, 749, 2164, 1264, 3755, 1395, 4078, 1282, +2855, 866, 562, 53, -1895, -781, -3716, -1266, +-4326, -1430, -3458, -1285, -1387, -757, 1096, -34, +3086, 670, 4016, 1213, 3692, 1441, 2184, 1313, +73, 877, -1856, 119, -3128, -739, -3468, -1371, +-2725, -1679, -1193, -1589, 488, -928, 1893, 115, +2807, 1118, 2927, 1831, 2220, 2056, 948, 1562, +-548, 477, -1810, -784, -2550, -1787, -2683, -2217, +-2055, -1918, -746, -952, 761, 385, 1976, 1587, +2684, 2196, 2664, 2009, 1779, 1167, 336, -23, +-1150, -1146, -2247, -1787, -2636, -1740, -2280, -1166, +-1294, -315, 142, 483, 1528, 891, 2281, 908, +2279, 744, 1718, 477, 726, 327, -474, 438, +-1443, 511, -1941, 224, -1946, -333, -1481, -1041, +-644, -1748, 364, -2023, 1264, -1503, 1811, -311, +1912, 1185, 1519, 2523, 652, 3116, -427, 2579, +-1303, 1132, -1864, -698, -2069, -2315, -1609, -3179, +-549, -3000, 519, -1871, 1270, -220, 1748, 1336, +1794, 2342, 1207, 2595, 328, 2115, -453, 1113, +-1121, -55, -1560, -1061, -1532, -1687, -1065, -1882, +-390, -1601, 286, -897, 928, -44, 1402, 719, +1390, 1332, 856, 1573, 149, 1260, -533, 602, +-1177, -65, -1443, -676, -989, -1084, -188, -990, +451, -509, 905, -87, 1098, 171, 691, 337, +-176, 297, -839, -9, -983, -293, -793, -270, +-239, 44, 704, 418, 1425, 724, 1340, 916, +658, 846, -208, 371, -1116, -357, -1763, -1063, +-1696, -1582, -906, -1747, 221, -1323, 1228, -391, +1778, 745, 1810, 1799, 1308, 2430, 269, 2348, +-815, 1534, -1397, 98, -1574, -1529, -1494, -2697, +-906, -3036, 33, -2472, 732, -1054, 1118, 730, +1370, 2273, 1293, 3179, 842, 3132, 282, 2091, +-297, 491, -879, -1210, -1280, -2616, -1321, -3286, +-1032, -3023, -536, -1985, 159, -382, 936, 1409, +1494, 2860, 1617, 3575, 1308, 3310, 659, 1999, +-265, 20, -1269, -2024, -1918, -3562, -1917, -4049, +-1314, -3181, -308, -1269, 907, 1076, 1917, 3173, +2195, 4263, 1740, 3871, 841, 2194, -405, -146, +-1629, -2446, -2225, -4020, -2003, -4267, -1177, -3091, +30, -962, 1271, 1427, 2006, 3385, 1969, 4311, +1330, 3927, 313, 2315, -871, -58, -1808, -2415, +-2059, -4006, -1590, -4413, -652, -3477, 471, -1376, +1430, 1236, 1912, 3437, 1804, 4523, 1109, 4174, +54, 2472, -1000, -90, -1792, -2600, -2085, -4153, +-1669, -4314, -737, -3146, 291, -949, 1213, 1537, +1817, 3285, 1809, 3772, 1254, 3179, 439, 1718, +-439, -235, -1176, -1849, -1559, -2549, -1496, -2470, +-1060, -1859, -427, -845, 257, 264, 784, 967, +984, 1197, 916, 1282, 755, 1257, 529, 927, +163, 450, -215, 40, -402, -400, -511, -910, +-704, -1208, -866, -1193, -821, -974, -631, -529, +-350, 183, 175, 843, 870, 1160, 1423, 1249, +1669, 1231, 1511, 893, 867, 191, -172, -576, +-1322, -1174, -2217, -1609, -2507, -1747, -2048, -1389, +-983, -546, 411, 577, 1832, 1649, 2847, 2271, +3004, 2278, 2235, 1634, 882, 386, -768, -1069, +-2351, -2121, -3220, -2535, -3025, -2309, -2008, -1397, +-493, 9, 1228, 1317, 2622, 2146, 3204, 2469, +2855, 2163, 1707, 1175, 98, -84, -1501, -1234, +-2612, -2155, -2898, -2580, -2335, -2195, -1202, -1150, +153, 201, 1418, 1537, 2265, 2473, 2440, 2680, +1967, 2098, 1077, 843, -1, -717, -1060, -1979, +-1830, -2525, -2094, -2380, -1873, -1591, -1260, -270, +-304, 1092, 783, 1980, 1718, 2273, 2226, 1988, +2075, 1127, 1318, -87, 205, -1200, -1008, -1943, +-1947, -2185, -2272, -1772, -1894, -748, -976, 521, +197, 1642, 1269, 2258, 1890, 2140, 1885, 1308, +1306, 11, 427, -1335, -455, -2157, -1230, -2182, +-1689, -1537, -1592, -426, -1079, 885, -361, 1878, +582, 2105, 1493, 1597, 1827, 769, 1492, -148, +733, -1098, -409, -1749, -1640, -1762, -2281, -1343, +-2027, -750, -1069, 71, 385, 1024, 1920, 1727, +2801, 2016, 2604, 1870, 1386, 1193, -480, 49, +-2262, -1231, -3277, -2268, -3226, -2691, -2031, -2364, +-12, -1364, 1958, 123, 3125, 1671, 3341, 2725, +2600, 3044, 935, 2602, -1051, 1420, -2522, -214, +-3123, -1769, -2864, -2840, -1792, -3187, -188, -2746, +1337, -1566, 2265, 126, 2507, 1805, 2129, 2936, +1152, 3320, -171, 2859, -1294, 1521, -1866, -302, +-1905, -1885, -1454, -2858, -581, -3105, 344, -2457, +962, -1054, 1218, 500, 1095, 1704, 645, 2358, +168, 2381, -149, 1779, -354, 785, -407, -243, +-271, -1016, -140, -1467, -137, -1627, -186, -1463, +-283, -958, -415, -341, -369, 201, -61, 763, +300, 1320, 617, 1513, 940, 1308, 1055, 956, +723, 396, 103, -447, -546, -1194, -1152, -1554, +-1532, -1589, -1420, -1338, -822, -674, 82, 303, +1096, 1178, 1857, 1661, 2024, 1805, 1529, 1548, +496, 741, -810, -381, -1923, -1294, -2412, -1796, +-2131, -1904, -1140, -1459, 297, -436, 1686, 711, +2567, 1504, 2636, 1824, 1786, 1694, 258, 1008, +-1373, -46, -2535, -934, -2878, -1364, -2267, -1426, +-904, -1102, 730, -410, 2150, 296, 2871, 695, +2596, 835, 1470, 756, -126, 484, -1735, 174, +-2781, -14, -2847, -81, -2000, -118, -591, -186, +1024, -296, 2357, -435, 2889, -509, 2453, -456, +1230, -219, -425, 234, -1976, 747, -2841, 1044, +-2727, 970, -1784, 494, -352, -251, 1154, -1013, +2218, -1515, 2494, -1489, 2037, -777, 1057, 384, +-199, 1509, -1306, 2178, -1914, 2103, -2048, 1159, +-1743, -389, -965, -1950, 14, -2885, 812, -2802, +1401, -1651, 1799, 232, 1752, 2169, 1166, 3395, +290, 3449, -598, 2285, -1319, 282, -1814, -1837, +-1921, -3270, -1424, -3621, -536, -2847, 313, -1106, +1056, 947, 1716, 2456, 1918, 3136, 1465, 2990, +762, 1954, 6, 369, -909, -1063, -1707, -2027, +-1941, -2462, -1627, -2241, -1033, -1440, -160, -363, +893, 738, 1605, 1550, 1701, 1871, 1416, 1765, +905, 1279, 93, 421, -793, -455, -1259, -1021, +-1216, -1311, -979, -1319, -669, -930, -161, -403, +358, -23, 510, 321, 456, 693, 524, 842, +556, 784, 426, 811, 353, 801, 363, 455, +186, -43, -249, -499, -705, -986, -1032, -1382, +-1218, -1431, -1160, -1106, -684, -450, 128, 412, +931, 1219, 1550, 1799, 1918, 2067, 1796, 1800, +1070, 934, -81, -231, -1338, -1373, -2327, -2328, +-2735, -2797, -2398, -2451, -1288, -1323, 344, 229, +1987, 1868, 3129, 3154, 3382, 3580, 2561, 2936, +842, 1385, -1279, -659, -3075, -2595, -3828, -3826, +-3318, -3956, -1850, -2885, 164, -897, 2171, 1327, +3411, 3122, 3409, 4037, 2309, 3745, 576, 2303, +-1235, 287, -2523, -1676, -2862, -3107, -2257, -3605, +-1062, -3024, 257, -1632, 1274, 140, 1701, 1778, +1520, 2759, 939, 2884, 243, 2307, -306, 1140, +-588, -374, -657, -1619, -595, -2126, -466, -2033, +-387, -1539, -361, -659, -255, 362, -67, 1066, +143, 1301, 387, 1220, 634, 972, 714, 590, +486, 148, 39, -231, -425, -500, -733, -707, +-752, -837, -481, -789, -35, -497, 372, -91, +526, 318, 380, 677, 17, 821, -397, 620, +-672, 187, -674, -265, -325, -548, 298, -524, +895, -176, 1120, 331, 882, 739, 289, 801, +-523, 472, -1256, -131, -1492, -860, -1158, -1405, +-535, -1382, 205, -753, 949, 190, 1367, 1119, +1240, 1779, 750, 1906, 179, 1378, -406, 373, +-900, -753, -1079, -1649, -945, -2038, -662, -1824, +-310, -1116, 82, -140, 448, 859, 680, 1587, +755, 1850, 711, 1684, 591, 1180, 358, 400, +-44, -441, -502, -1109, -889, -1511, -1160, -1596, +-1188, -1317, -842, -777, -196, -99, 481, 619, +1052, 1194, 1454, 1421, 1449, 1316, 940, 1003, +117, 512, -767, -74, -1461, -544, -1713, -845, +-1394, -1002, -681, -925, 140, -686, 857, -494, +1270, -262, 1267, 100, 858, 420, 234, 673, +-329, 995, -725, 1270, -895, 1265, -768, 949, +-439, 354, -124, -551, 36, -1574, 43, -2298, +-10, -2402, 0, -1806, 162, -576, 422, 1036, +626, 2536, 638, 3348, 421, 3147, -10, 1980, +-617, 189, -1149, -1728, -1284, -3162, -971, -3599, +-357, -2927, 406, -1458, 1080, 368, 1312, 2078, +978, 3092, 321, 3059, -396, 2207, -1011, 918, +-1254, -573, -909, -1831, -198, -2318, 476, -2033, +921, -1337, 952, -418, 474, 538, -245, 1133, +-873, 1214, -1205, 973, -1063, 609, -417, 250, +453, 23, 1190, -54, 1518, -75, 1243, -135, +433, -302, -593, -583, -1462, -791, -1904, -716, +-1723, -389, -862, 68, 267, 642, 1145, 1133, +1638, 1165, 1663, 698, 1072, 76, 99, -479, +-711, -891, -1156, -970, -1306, -561, -1040, 133, +-431, 652, 133, 772, 428, 600, 458, 148, +340, -551, 148, -1091, -55, -1035, -115, -453, +71, 300, 355, 1085, 423, 1743, 277, 1750, +88, 874, -328, -336, -974, -1373, -1321, -2199, +-1124, -2428, -682, -1564, -30, -58, 941, 1292, +1741, 2327, 1847, 2847, 1371, 2324, 491, 867, +-707, -726, -1826, -1972, -2362, -2724, -2130, -2678, +-1231, -1652, 48, -54, 1286, 1438, 2076, 2411, +2152, 2711, 1500, 2152, 432, 781, -663, -817, +-1513, -1971, -1844, -2455, -1534, -2220, -850, -1160, +-96, 428, 595, 1744, 999, 2272, 928, 2064, +568, 1238, 192, -83, -176, -1380, -459, -2010, +-430, -1828, -165, -1116, 59, -69, 149, 1055, +98, 1712, -150, 1597, -564, 996, -882, 229, +-861, -601, -541, -1235, 9, -1337, 762, -918, +1505, -267, 1791, 371, 1316, 902, 290, 1178, +-905, 986, -2048, 407, -2747, -169, -2518, -610, +-1350, -1005, 261, -1094, 1847, -603, 3028, 87, +3276, 559, 2358, 910, 634, 1111, -1328, 852, +-2969, 226, -3741, -392, -3317, -840, -1881, -1044, +76, -890, 2043, -407, 3388, 266, 3603, 881, +2686, 1125, 979, 944, -1082, 524, -2825, -98, +-3553, -837, -3131, -1241, -1848, -1003, -38, -405, +1739, 230, 2803, 865, 2796, 1274, 1855, 1071, +409, 352, -1048, -435, -2053, -1005, -2260, -1204, +-1630, -881, -525, -131, 563, 718, 1293, 1310, +1471, 1343, 1069, 809, 249, 34, -585, -759, +-1066, -1396, -1171, -1503, -965, -940, -417, -138, +268, 528, 668, 1102, 772, 1461, 832, 1277, +651, 716, 104, 204, -414, -308, -675, -934, +-896, -1307, -1089, -1244, -866, -996, -276, -548, +218, 238, 588, 1064, 944, 1538, 1068, 1563, +797, 1160, 285, 393, -280, -496, -878, -1202, +-1338, -1482, -1408, -1243, -1076, -633, -460, 61, +281, 634, 969, 939, 1370, 892, 1312, 621, +896, 341, 246, 118, -569, -50, -1303, -139, +-1613, -198, -1368, -335, -769, -541, -34, -673, +715, -610, 1227, -347, 1215, 64, 710, 551, +31, 947, -637, 1058, -1166, 870, -1190, 474, +-625, -47, 114, -531, 703, -768, 1031, -765, +886, -646, 170, -409, -758, -93, -1374, 125, +-1441, 213, -987, 290, -142, 422, 880, 567, +1678, 661, 1783, 668, 1115, 565, 21, 250, +-1183, -329, -2163, -964, -2356, -1374, -1594, -1470, +-358, -1185, 915, -402, 1948, 722, 2337, 1740, +1892, 2303, 872, 2261, -439, 1565, -1729, 301, +-2425, -1238, -2296, -2554, -1628, -3148, -599, -2818, +647, -1667, 1659, 70, 2031, 1969, 1838, 3413, +1326, 3899, 480, 3247, -593, 1633, -1450, -503, +-1799, -2570, -1805, -3941, -1640, -4157, -1051, -3158, +-41, -1282, 835, 930, 1367, 2899, 1770, 4070, +1879, 4078, 1327, 2937, 374, 1060, -458, -985, +-1200, -2723, -1922, -3751, -2259, -3705, -1921, -2581, +-1123, -882, -250, 841, 631, 2339, 1521, 3287, +2127, 3226, 2184, 2259, 1725, 1006, 888, -241, +-257, -1482, -1513, -2380, -2483, -2532, -2839, -2111, +-2486, -1476, -1500, -600, -71, 559, 1437, 1654, +2527, 2339, 2871, 2570, 2386, 2285, 1150, 1325, +-465, -138, -1832, -1587, -2534, -2578, -2490, -2860, +-1744, -2302, -503, -960, 726, 737, 1406, 2068, +1430, 2543, 1001, 2218, 303, 1290, -385, -65, +-744, -1274, -644, -1687, -187, -1337, 279, -660, +433, 146, 284, 821, -50, 933, -588, 468, +-1148, -185, -1275, -717, -934, -889, -371, -561, +408, 108, 1201, 861, 1561, 1470, 1381, 1566, +851, 986, 95, 66, -795, -848, -1511, -1628, +-1799, -2013, -1680, -1714, -1193, -829, -368, 260, +587, 1244, 1323, 1932, 1627, 2139, 1508, 1720, +994, 799, 217, -251, -591, -1168, -1222, -1820, +-1487, -1957, -1376, -1454, -1010, -614, -473, 219, +106, 989, 533, 1546, 695, 1582, 691, 1140, +671, 592, 627, 86, 498, -456, 265, -900, +-89, -994, -609, -858, -1195, -761, -1557, -606, +-1535, -211, -1144, 256, -367, 635, 689, 1010, +1626, 1353, 2063, 1407, 1924, 1007, 1257, 260, +131, -573, -1147, -1345, -2103, -1963, -2530, -2034, +-2388, -1260, -1530, -103, -138, 918, 1202, 1839, +2106, 2408, 2473, 2025, 2179, 934, 1192, -133, +-126, -1077, -1310, -1876, -2148, -2014, -2471, -1399, +-2153, -563, -1229, 200, -5, 902, 1039, 1394, +1673, 1491, 1924, 1251, 1748, 834, 1022, 334, +-60, -252, -967, -900, -1538, -1408, -1894, -1577, +-1827, -1394, -1129, -864, -100, 29, 766, 1067, +1353, 1815, 1631, 2002, 1341, 1653, 538, 861, +-362, -223, -1075, -1221, -1456, -1693, -1331, -1568, +-713, -1055, -8, -313, 453, 452, 682, 895, +629, 874, 242, 600, -286, 288, -633, 12, +-598, -111, -275, 38, 102, 329, 400, 457, +578, 295, 524, -46, 157, -438, -310, -815, +-670, -1022, -990, -834, -1218, -280, -1049, 325, +-429, 749, 287, 994, 832, 1030, 1248, 741, +1470, 295, 1219, 34, 465, -92, -450, -341, +-1282, -594, -1933, -675, -2134, -808, -1635, -1037, +-661, -914, 366, -289, 1296, 476, 1995, 1208, +2137, 1912, 1594, 2240, 579, 1801, -553, 733, +-1561, -568, -2263, -1817, -2383, -2737, -1806, -2968, +-768, -2276, 361, -824, 1386, 858, 2105, 2271, +2145, 3156, 1471, 3272, 444, 2399, -629, 778, +-1508, -909, -1941, -2168, -1791, -2848, -1176, -2762, +-324, -1837, 504, -489, 1011, 711, 1134, 1488, +902, 1792, 342, 1657, -226, 1200, -497, 629, +-524, 203, -421, 0, -189, -214, 49, -598, +85, -984, -58, -1247, -292, -1388, -510, -1221, +-514, -564, -361, 378, -177, 1264, 142, 1875, +506, 2004, 633, 1564, 570, 723, 515, -248, +310, -1060, -182, -1496, -673, -1556, -1012, -1347, +-1323, -901, -1383, -320, -895, 189, -85, 612, +682, 1083, 1329, 1507, 1726, 1655, 1574, 1471, +871, 968, -51, 107, -926, -977, -1617, -1928, +-1959, -2411, -1779, -2252, -1106, -1425, -292, -121, +407, 1268, 1034, 2314, 1469, 2691, 1473, 2273, +1109, 1233, 616, -66, 51, -1264, -627, -2018, +-1216, -2075, -1478, -1494, -1478, -594, -1343, 305, +-984, 991, -275, 1301, 597, 1142, 1321, 611, +1737, 28, 1728, -332, 1254, -449, 374, -413, +-731, -187, -1644, 206, -2098, 460, -2064, 398, +-1444, 219, -294, 38, 872, -263, 1509, -607, +1596, -724, 1273, -574, 543, -345, -321, -68, +-929, 370, -1150, 870, -1006, 1149, -576, 1127, +-45, 917, 340, 495, 452, -207, 294, -1006, +-74, -1562, -413, -1696, -528, -1424, -458, -757, +-245, 255, 110, 1313, 476, 2000, 673, 2107, +622, 1670, 316, 792, -139, -347, -559, -1376, +-850, -1923, -972, -1897, -859, -1416, -540, -611, +-116, 345, 316, 1142, 611, 1511, 704, 1449, +723, 1115, 658, 619, 379, 39, -25, -480, +-396, -756, -772, -786, -1174, -744, -1358, -679, +-1127, -491, -601, -239, 61, -32, 803, 255, +1464, 683, 1711, 1027, 1366, 1143, 626, 1060, +-295, 698, -1210, 11, -1817, -755, -1922, -1322, +-1546, -1615, -821, -1519, 127, -872, 1062, 139, +1636, 1069, 1744, 1690, 1450, 1960, 766, 1698, +-222, 811, -1194, -359, -1790, -1364, -1953, -1981, +-1673, -2034, -868, -1429, 175, -360, 1063, 832, +1672, 1796, 1890, 2189, 1526, 1907, 633, 1061, +-444, -144, -1447, -1306, -2139, -1989, -2163, -2045, +-1505, -1483, -480, -429, 626, 717, 1571, 1587, +2094, 2051, 1964, 1936, 1171, 1153, 7, 79, +-1111, -858, -1903, -1595, -2270, -2015, -2022, -1839, +-1115, -1089, 2, -74, 927, 954, 1635, 1816, +2013, 2280, 1802, 2107, 1031, 1294, 21, 143, +-920, -1034, -1632, -2015, -2033, -2451, -1991, -2090, +-1417, -1127, -511, 54, 418, 1202, 1260, 2006, +1860, 2159, 1948, 1676, 1472, 827, 599, -100, +-442, -871, -1376, -1313, -2009, -1335, -2164, -993, +-1664, -523, -595, -90, 590, 309, 1417, 584, +1744, 632, 1524, 566, 737, 471, -269, 317, +-1004, 154, -1278, 30, -1159, -30, -656, 15, +152, 33, 760, -130, 740, -337, 271, -495, +-258, -730, -686, -870, -948, -566, -803, 62, +-194, 688, 505, 1269, 973, 1686, 1135, 1583, +969, 896, 454, -52, -340, -969, -1136, -1681, +-1579, -2010, -1521, -1789, -1090, -1027, -422, -16, +414, 894, 1133, 1576, 1461, 1982, 1404, 1929, +1013, 1350, 324, 516, -501, -278, -1218, -1039, +-1602, -1715, -1552, -1970, -1144, -1688, -490, -1144, +326, -447, 1056, 507, 1416, 1498, 1405, 2098, +1097, 2224, 459, 1984, -342, 1269, -1018, 39, +-1495, -1326, -1771, -2349, -1670, -2831, -1022, -2675, +18, -1731, 1046, -122, 1785, 1604, 2159, 2882, +2016, 3422, 1133, 3044, -267, 1700, -1535, -198, +-2338, -1931, -2621, -3022, -2169, -3326, -1013, -2705, +332, -1216, 1394, 514, 2022, 1803, 2114, 2536, +1604, 2734, 752, 2222, -96, 1134, -807, 7, +-1315, -858, -1593, -1558, -1635, -2072, -1438, -2127, +-1039, -1668, -423, -955, 403, -123, 1282, 915, +1941, 2007, 2173, 2634, 1922, 2505, 1069, 1792, +-299, 655, -1653, -820, -2552, -2190, -2867, -2890, +-2506, -2771, -1410, -1954, 122, -589, 1502, 963, +2390, 2169, 2696, 2714, 2308, 2573, 1295, 1811, +37, 594, -1096, -698, -1982, -1677, -2468, -2181, +-2310, -2175, -1565, -1647, -567, -719, 412, 323, +1234, 1191, 1749, 1735, 1793, 1905, 1392, 1664, +772, 1019, 69, 141, -652, -692, -1188, -1312, +-1368, -1659, -1264, -1626, -1026, -1177, -707, -448, +-293, 396, 181, 1183, 655, 1653, 1016, 1649, +1149, 1223, 1034, 474, 694, -436, 189, -1205, +-367, -1548, -884, -1380, -1220, -790, -1251, 43, +-960, 862, -470, 1364, 54, 1333, 523, 792, +772, 12, 674, -718, 422, -1220, 234, -1291, +105, -789, -28, 85, -65, 918, 23, 1442, +-3, 1541, -258, 1108, -589, 175, -858, -889, +-989, -1652, -882, -1922, -432, -1622, 256, -747, +918, 454, 1341, 1561, 1431, 2241, 1197, 2288, +600, 1665, -317, 545, -1189, -777, -1695, -1919, +-1847, -2525, -1654, -2471, -954, -1776, 99, -516, +1034, 981, 1662, 2190, 1968, 2803, 1756, 2750, +989, 1970, -63, 568, -1081, -1021, -1814, -2286, +-2055, -2904, -1765, -2757, -1089, -1873, -179, -461, +749, 1062, 1400, 2230, 1664, 2742, 1536, 2531, +1011, 1699, 247, 445, -479, -888, -1021, -1873, +-1363, -2272, -1462, -2112, -1263, -1450, -799, -392, +-180, 707, 459, 1455, 997, 1769, 1325, 1702, +1347, 1205, 1030, 387, 476, -376, -197, -840, +-875, -1061, -1392, -1064, -1582, -792, -1379, -390, +-842, -110, -131, 42, 579, 230, 1110, 410, +1345, 503, 1212, 673, 775, 937, 251, 961, +-285, 633, -813, 150, -1111, -461, -1079, -1166, +-911, -1597, -709, -1509, -300, -1022, 272, -242, +688, 715, 863, 1479, 893, 1728, 744, 1462, +353, 850, -146, 77, -517, -646, -758, -1104, +-881, -1130, -720, -758, -285, -282, 140, 73, +344, 322, 338, 409, 202, 199, -48, -146, +-292, -276, -324, -128, -79, 122, 234, 448, +460, 880, 648, 1137, 698, 899, 336, 264, +-341, -483, -941, -1219, -1301, -1769, -1428, -1818, +-1182, -1252, -482, -269, 429, 822, 1184, 1715, +1667, 2177, 1842, 2078, 1539, 1392, 687, 334, +-445, -705, -1445, -1504, -2103, -1969, -2330, -1937, +-1917, -1412, -897, -637, 305, 225, 1333, 1064, +2091, 1664, 2364, 1840, 1893, 1589, 857, 996, +-322, 170, -1402, -711, -2161, -1395, -2335, -1650, +-1830, -1435, -837, -893, 291, -166, 1262, 579, +1900, 1083, 2039, 1208, 1564, 1034, 630, 653, +-401, 149, -1287, -319, -1870, -638, -1961, -779, +-1502, -710, -656, -466, 311, -146, 1172, 223, +1713, 578, 1743, 740, 1259, 641, 457, 372, +-396, -10, -1113, -444, -1562, -724, -1580, -694, +-1161, -416, -541, -34, 73, 366, 604, 667, +1005, 700, 1141, 437, 984, 64, 711, -243, +435, -403, 50, -370, -486, -177, -980, 57, +-1259, 227, -1377, 218, -1294, -18, -860, -316, +-117, -454, 696, -417, 1394, -224, 1834, 215, +1856, 787, 1366, 1120, 479, 1037, -546, 674, +-1410, 109, -1925, -649, -2061, -1354, -1847, -1658, +-1251, -1467, -356, -910, 582, -112, 1383, 810, +2022, 1608, 2394, 2004, 2238, 1913, 1473, 1412, +325, 558, -1036, -528, -2397, -1550, -3301, -2230, +-3340, -2425, -2468, -2056, -902, -1113, 1005, 198, +2708, 1526, 3664, 2534, 3579, 2939, 2433, 2567, +627, 1470, -1232, -72, -2672, -1637, -3308, -2754, +-2936, -3098, -1790, -2572, -397, -1290, 841, 379, +1723, 1901, 2039, 2822, 1752, 2893, 1113, 2099, +428, 689, -175, -867, -667, -2073, -948, -2567, +-978, -2234, -918, -1228, -829, 113, -617, 1350, +-210, 2055, 252, 2014, 590, 1324, 777, 280, +819, -751, 633, -1438, 282, -1575, -46, -1133, +-290, -329, -519, 475, -633, 1013, -532, 1146, +-344, 845, -223, 267, -81, -300, 152, -676, +321, -793, 313, -627, 237, -265, 150, 99, +-18, 338, -236, 457, -326, 504, -204, 502, +41, 428, 253, 274, 369, 64, 339, -248, +32, -682, -482, -1057, -851, -1151, -919, -882, +-732, -265, -227, 594, 527, 1433, 1142, 1947, +1358, 1896, 1187, 1193, 605, 27, -335, -1221, +-1253, -2180, -1753, -2537, -1704, -2112, -1164, -1019, +-270, 380, 737, 1645, 1541, 2417, 1839, 2498, +1514, 1886, 776, 791, -85, -429, -967, -1412, +-1640, -1930, -1774, -1922, -1351, -1477, -658, -772, +133, 25, 896, 720, 1384, 1147, 1430, 1298, +1084, 1239, 460, 962, -211, 485, -771, -62, +-1142, -536, -1208, -862, -913, -993, -442, -920, +16, -616, 427, -146, 759, 263, 884, 484, +777, 615, 500, 652, 115, 463, -315, 162, +-680, -32, -891, -167, -889, -343, -664, -412, +-273, -289, 169, -112, 586, 52, 867, 270, +896, 451, 676, 403, 307, 147, -152, -147, +-600, -437, -899, -688, -1010, -697, -934, -363, +-615, 151, -53, 634, 561, 984, 998, 1104, +1194, 861, 1094, 257, 632, -453, -72, -988, +-758, -1263, -1237, -1257, -1396, -878, -1136, -192, +-490, 517, 297, 1016, 929, 1247, 1179, 1207, +1045, 884, 641, 329, 32, -273, -581, -727, +-855, -995, -744, -1097, -477, -934, -167, -506, +203, -15, 422, 426, 328, 794, 74, 948, +-112, 810, -199, 485, -251, 81, -270, -311, +-128, -537, 121, -542, 269, -382, 285, -113, +348, 151, 409, 253, 262, 190, -49, 43, +-362, -178, -711, -398, -1033, -455, -1130, -304, +-842, -22, -178, 322, 699, 673, 1479, 934, +1896, 977, 1795, 732, 1098, 254, -121, -368, +-1467, -1033, -2442, -1573, -2716, -1775, -2197, -1501, +-967, -768, 666, 261, 2147, 1372, 2917, 2301, +2760, 2714, 1815, 2370, 392, 1330, -1121, -130, +-2279, -1660, -2722, -2862, -2357, -3360, -1411, -2948, +-245, -1697, 863, 15, 1679, 1674, 1970, 2900, +1731, 3427, 1239, 3055, 654, 1902, -76, 415, +-829, -1034, -1377, -2240, -1664, -2930, -1723, -2916, +-1468, -2320, -851, -1376, 13, -179, 915, 1156, +1691, 2308, 2168, 2946, 2158, 3022, 1558, 2584, +575, 1515, -532, -125, -1622, -1798, -2459, -3009, +-2681, -3675, -2227, -3628, -1312, -2550, -121, -683, +1232, 1266, 2359, 2900, 2847, 4025, 2631, 4189, +1923, 3133, 815, 1274, -637, -760, -2047, -2581, +-2858, -3807, -2973, -4009, -2542, -3107, -1554, -1486, +-40, 308, 1507, 1857, 2550, 2862, 2972, 3075, +2810, 2481, 1971, 1430, 546, 313, -1025, -708, +-2217, -1467, -2796, -1760, -2751, -1653, -2036, -1362, +-756, -938, 594, -377, 1540, 183, 2012, 622, +2035, 961, 1524, 1195, 670, 1234, -103, 1014, +-614, 582, -931, 73, -1059, -415, -969, -854, +-782, -1120, -637, -1069, -433, -754, -60, -355, +319, 57, 565, 445, 755, 678, 846, 673, +691, 517, 359, 330, 80, 150, -117, -4, +-288, -85, -402, -90, -423, -83, -461, -128, +-594, -230, -731, -353, -650, -458, -352, -510, +37, -462, 497, -267, 1031, 87, 1375, 521, +1301, 906, 877, 1127, 262, 1098, -528, 773, +-1279, 164, -1682, -596, -1613, -1239, -1176, -1560, +-518, -1510, 208, -1086, 887, -350, 1347, 463, +1464, 1089, 1260, 1418, 879, 1432, 365, 1146, +-222, 672, -758, 140, -1168, -381, -1392, -832, +-1366, -1158, -1117, -1316, -648, -1252, 42, -931, +807, -364, 1404, 384, 1730, 1136, 1718, 1612, +1266, 1661, 415, 1300, -616, 567, -1554, -389, +-2088, -1227, -2038, -1652, -1464, -1582, -505, -1083, +668, -287, 1654, 560, 2032, 1155, 1774, 1316, +1103, 1068, 135, 537, -907, -121, -1576, -680, +-1618, -910, -1206, -776, -554, -424, 201, 16, +846, 435, 1121, 650, 1021, 554, 691, 251, +259, -90, -212, -386, -633, -556, -899, -504, +-889, -256, -657, 40, -274, 267, 180, 393, +584, 398, 758, 282, 726, 122, 579, 11, +318, -22, -54, -23, -343, -35, -494, -81, +-550, -201, -555, -391, -525, -537, -479, -524, +-349, -336, -106, -7, 224, 419, 612, 807, +1029, 980, 1241, 862, 1078, 499, 596, -13, +-99, -518, -904, -866, -1575, -979, -1826, -831, +-1546, -485, -849, -88, 61, 264, 963, 532, +1662, 657, 1909, 618, 1545, 475, 783, 274, +-54, 14, -836, -258, -1404, -422, -1473, -403, +-1029, -255, -443, -70, 27, 132, 378, 279, +529, 182, 379, -183, 108, -543, -9, -689, +101, -611, 322, -245, 584, 442, 807, 1181, +837, 1545, 475, 1360, -273, 745, -1101, -187, +-1651, -1250, -1841, -1981, -1581, -1994, -770, -1397, +392, -469, 1432, 642, 2101, 1624, 2314, 2015, +1975, 1720, 1038, 1022, -229, 163, -1425, -720, +-2212, -1386, -2441, -1572, -2035, -1293, -1092, -795, +81, -223, 1104, 403, 1818, 932, 2094, 1142, +1813, 1071, 1053, 878, 139, 510, -695, -54, +-1344, -564, -1652, -851, -1469, -986, -948, -984, +-315, -752, 325, -350, 862, 57, 1089, 406, +935, 714, 600, 947, 290, 1041, 23, 937, +-216, 621, -358, 142, -337, -418, -268, -990, +-305, -1423, -413, -1489, -499, -1116, -493, -459, +-309, 308, 100, 1045, 606, 1522, 945, 1539, +1002, 1127, 795, 462, 345, -275, -242, -898, +-752, -1237, -1045, -1226, -1039, -918, -701, -416, +-137, 164, 401, 643, 780, 861, 894, 829, +649, 612, 175, 215, -224, -235, -461, -486, +-520, -481, -375, -359, -85, -136, 156, 163, +264, 312, 234, 188, 135, -49, 11, -250, +-90, -382, -161, -368, -129, -158, -44, 155, +12, 432, 22, 554, 38, 485, 16, 290, +-13, 37, -12, -214, 30, -354, 69, -356, +112, -327, 129, -303, 90, -201, 20, -82, +-48, -65, -165, -25, -327, 169, -410, 339, +-292, 349, -47, 344, 206, 376, 448, 271, +626, 29, 608, -159, 361, -252, -2, -342, +-364, -429, -662, -447, -794, -368, -662, -245, +-293, -121, 159, 62, 512, 332, 716, 554, +747, 627, 503, 583, 47, 426, -372, 131, +-612, -211, -665, -478, -452, -601, 13, -549, +474, -365, 694, -168, 617, -23, 231, 74, +-309, 99, -749, 50, -886, 49, -641, 194, +-62, 412, 566, 568, 963, 598, 990, 464, +675, 110, 122, -411, -430, -884, -788, -1116, +-816, -1042, -571, -662, -228, -41, 62, 609, +290, 1029, 345, 1125, 237, 951, 177, 534, +282, -36, 359, -488, 332, -657, 265, -664, +111, -599, -252, -408, -650, -183, -845, -95, +-790, -90, -544, -13, -96, 162, 487, 372, +972, 589, 1133, 773, 992, 837, 657, 675, +140, 244, -514, -344, -1080, -901, -1340, -1308, +-1268, -1458, -868, -1238, -157, -644, 644, 181, +1271, 1013, 1576, 1607, 1488, 1802, 979, 1542, +143, 836, -753, -159, -1422, -1092, -1670, -1668, +-1425, -1807, -796, -1473, 8, -672, 769, 307, +1316, 1047, 1475, 1394, 1211, 1395, 681, 1028, +62, 348, -568, -339, -1043, -747, -1206, -900, +-1014, -916, -621, -746, -158, -377, 331, -5, +790, 240, 986, 470, 851, 760, 595, 920, +381, 787, 23, 490, -406, 137, -606, -393, +-599, -1036, -663, -1400, -676, -1286, -432, -870, +-60, -235, 228, 640, 520, 1466, 850, 1830, +1029, 1622, 853, 968, 383, -1, -171, -1053, +-642, -1849, -976, -2122, -1005, -1737, -608, -768, +15, 443, 514, 1488, 753, 2108, 722, 2130, +389, 1440, -166, 224, -668, -1035, -858, -1916, +-650, -2191, -126, -1759, 551, -737, 1186, 507, +1500, 1576, 1286, 2120, 599, 1903, -345, 1016, +-1339, -147, -2096, -1223, -2247, -1958, -1681, -2077, +-621, -1458, 704, -357, 2049, 789, 2918, 1664, +2865, 2082, 1918, 1894, 482, 1108, -1070, -21, +-2360, -1097, -2965, -1794, -2659, -1976, -1622, -1646, +-240, -865, 1061, 143, 1981, 1006, 2285, 1434, +1949, 1414, 1194, 1073, 366, 511, -389, -104, +-994, -496, -1303, -537, -1197, -379, -861, -237, +-466, -171, -96, -207, 203, -401, 350, -661, +380, -753, 351, -547, 355, -78, 426, 535, +536, 1123, 606, 1482, 628, 1477, 481, 1075, +2, 348, -691, -524, -1222, -1286, -1439, -1735, +-1357, -1783, -889, -1428, -16, -733, 930, 148, +1563, 967, 1762, 1481, 1551, 1607, 934, 1396, +34, 889, -835, 203, -1326, -397, -1355, -768, +-1091, -955, -659, -964, -92, -773, 458, -539, +745, -396, 742, -214, 616, 93, 402, 371, +110, 597, -109, 865, -136, 1026, -41, 864, +46, 453, 84, -37, 87, -550, 10, -994, +-187, -1175, -477, -1000, -651, -578, -573, -78, +-288, 407, 123, 776, 617, 914, 970, 788, +988, 477, 711, 76, 311, -327, -201, -626, +-696, -726, -904, -610, -698, -295, -326, 146, +-3, 571, 234, 810, 382, 757, 286, 410, +11, -129, -169, -722, -101, -1189, 85, -1304, +319, -931, 611, -216, 857, 570, 774, 1284, +304, 1767, -328, 1727, -907, 1107, -1353, 210, +-1480, -686, -1114, -1489, -378, -2000, 425, -1964, +1121, -1416, 1593, -615, 1687, 282, 1350, 1156, +712, 1779, -20, 1963, -664, 1715, -1104, 1124, +-1279, 297, -1189, -584, -925, -1296, -589, -1677, +-196, -1685, 241, -1367, 607, -792, 853, -114, +1040, 482, 1134, 929, 1068, 1221, 858, 1287, +482, 1099, -98, 767, -757, 367, -1300, -134, +-1616, -673, -1632, -1071, -1282, -1241, -644, -1203, +201, -964, 1081, -523, 1740, 53, 2019, 618, +1937, 1036, 1443, 1268, 570, 1309, -413, 1085, +-1185, 573, -1724, -87, -2018, -727, -1942, -1267, +-1409, -1596, -611, -1543, 237, -1090, 1084, -397, +1916, 402, 2428, 1171, 2389, 1673, 1849, 1737, +937, 1410, -346, 780, -1735, -104, -2720, -1054, +-2980, -1739, -2547, -1975, -1495, -1758, 14, -1082, +1568, -2, 2629, 1168, 2933, 2003, 2525, 2245, +1560, 1860, 278, 915, -939, -383, -1774, -1609, +-2118, -2297, -1996, -2247, -1470, -1547, -664, -426, +216, 813, 968, 1781, 1477, 2160, 1689, 1892, +1539, 1142, 1028, 131, 310, -874, -430, -1591, +-1056, -1884, -1389, -1733, -1315, -1159, -941, -317, +-406, 537, 195, 1238, 728, 1701, 1055, 1776, +1196, 1388, 1146, 687, 837, -112, 303, -904, +-305, -1562, -913, -1891, -1400, -1759, -1576, -1230, +-1287, -461, -596, 436, 339, 1341, 1302, 1988, +2034, 2114, 2182, 1717, 1615, 955, 551, -89, +-633, -1247, -1715, -2122, -2350, -2380, -2195, -2030, +-1293, -1210, -75, -41, 1124, 1183, 2010, 2020, +2274, 2241, 1787, 1888, 796, 1070, -324, -27, +-1231, -1026, -1721, -1607, -1664, -1736, -1083, -1478, +-212, -871, 570, -112, 1075, 505, 1267, 871, +1097, 1043, 585, 1024, 12, 798, -354, 456, +-489, 105, -469, -239, -333, -566, -180, -834, +-114, -960, -128, -871, -161, -575, -170, -155, +-85, 314, 145, 753, 461, 1017, 749, 992, +903, 710, 799, 274, 412, -241, -129, -725, +-660, -999, -1051, -992, -1146, -773, -893, -395, +-397, 104, 203, 590, 781, 901, 1108, 976, +1071, 852, 791, 549, 408, 74, -77, -462, +-550, -872, -821, -1079, -806, -1107, -589, -908, +-211, -425, 245, 203, 645, 758, 807, 1153, +674, 1344, 336, 1208, -46, 714, -430, 41, +-697, -595, -689, -1104, -363, -1394, 105, -1340, +551, -952, 823, -395, 790, 182, 447, 697, +-12, 1062, -417, 1197, -637, 1074, -647, 736, +-452, 276, -112, -232, 281, -715, 572, -1068, +659, -1191, 549, -1072, 323, -727, 27, -190, +-250, 415, -416, 906, -444, 1209, -349, 1279, +-133, 1003, 123, 395, 277, -289, 300, -871, +274, -1310, 210, -1470, 111, -1177, 53, -529, +44, 187, 36, 797, 16, 1243, -17, 1388, +-65, 1118, -144, 553, -227, -55, -237, -559, +-120, -922, 73, -1104, 270, -1027, 440, -722, +540, -336, 472, 43, 268, 423, 18, 744, +-246, 893, -522, 839, -677, 602, -633, 202, +-419, -247, -73, -597, 423, -759, 888, -692, +1107, -397, 1023, -4, 714, 309, 214, 428, +-401, 316, -992, 17, -1321, -313, -1266, -524, +-846, -515, -194, -236, 575, 224, 1232, 645, +1505, 870, 1319, 841, 847, 514, 227, -61, +-414, -652, -897, -1017, -1043, -1062, -881, -804, +-541, -322, -157, 226, 150, 659, 335, 822, +447, 685, 481, 352, 457, -7, 443, -277, +432, -400, 342, -360, 176, -192, -14, -16, +-244, 49, -476, -15, -593, -121, -578, -181, +-446, -161, -204, -53, 88, 166, 383, 429, +682, 550, 927, 441, 998, 172, 782, -201, +293, -614, -327, -896, -882, -908, -1245, -658, +-1296, -215, -912, 314, -153, 774, 653, 1032, +1291, 1039, 1636, 806, 1513, 400, 875, -83, +27, -550, -709, -917, -1226, -1110, -1464, -1118, +-1252, -961, -680, -625, -4, -117, 589, 462, +1050, 978, 1269, 1335, 1176, 1465, 863, 1291, +488, 785, 54, 45, -429, -745, -875, -1404, +-1114, -1804, -1098, -1831, -869, -1420, -466, -664, +112, 240, 736, 1109, 1218, 1776, 1438, 2045, +1377, 1802, 974, 1099, 291, 124, -441, -895, +-1037, -1709, -1397, -2077, -1383, -1891, -987, -1229, +-392, -277, 214, 695, 779, 1387, 1195, 1621, +1303, 1396, 1106, 825, 783, 113, 417, -507, +-45, -849, -565, -871, -918, -665, -1041, -370, +-1058, -95, -921, 70, -467, 73, 192, -31, +793, -89, 1233, -10, 1500, 172, 1429, 380, +912, 550, 103, 586, -691, 395, -1277, -3, +-1538, -448, -1335, -788, -616, -930, 306, -797, +1062, -392, 1497, 103, 1521, 513, 999, 777, +102, 826, -744, 600, -1244, 215, -1352, -132, +-977, -392, -205, -577, 610, -620, 1118, -511, +1260, -352, 1082, -198, 633, -5, 23, 225, +-468, 433, -679, 571, -651, 611, -521, 508, +-333, 256, -120, -99, 30, -484, 97, -787, +186, -898, 321, -788, 470, -498, 575, -87, +622, 366, 564, 743, 357, 935, 42, 903, +-285, 678, -554, 300, -664, -181, -563, -648, +-324, -964, -90, -1055, 123, -919, 316, -600, +404, -163, 384, 296, 374, 657, 392, 840, +389, 857, 340, 750, 264, 541, 150, 251, +-48, -89, -320, -442, -514, -773, -548, -1036, +-469, -1153, -329, -1037, -85, -649, 191, -63, +385, 571, 533, 1110, 702, 1420, 787, 1382, +737, 1008, 560, 412, 278, -271, -140, -879, +-628, -1242, -1036, -1339, -1196, -1224, -1037, -886, +-582, -350, 66, 206, 796, 652, 1335, 983, +1511, 1144, 1369, 1026, 984, 666, 371, 217, +-290, -210, -795, -558, -1090, -754, -1214, -769, +-1109, -654, -788, -494, -342, -324, 167, -152, +729, 13, 1256, 189, 1583, 400, 1565, 600, +1213, 691, 565, 608, -276, 359, -1081, -16, +-1568, -433, -1605, -758, -1223, -855, -539, -675, +285, -284, 962, 169, 1261, 543, 1183, 724, +898, 639, 524, 290, 150, -192, -101, -609, +-183, -820, -232, -797, -321, -528, -410, -59, +-472, 451, -492, 813, -373, 928, -62, 784, +359, 431, 721, -49, 917, -527, 862, -849, +569, -913, 154, -737, -215, -421, -420, -60, +-438, 268, -344, 455, -151, 429, 58, 240, +143, 52, 53, -28, -53, -15, -60, 52, +15, 194, 170, 340, 442, 323, 705, 88, +805, -232, 650, -509, 294, -717, -152, -822, +-580, -722, -912, -402, -989, 7, -732, 353, +-241, 617, 282, 823, 764, 926, 1098, 817, +1140, 513, 879, 129, 471, -301, 28, -791, +-369, -1218, -643, -1397, -732, -1251, -653, -802, +-422, -105, -106, 694, 233, 1372, 565, 1740, +829, 1685, 875, 1157, 670, 260, 288, -756, +-167, -1612, -571, -2074, -760, -1996, -663, -1374, +-329, -344, 133, 793, 605, 1659, 900, 2015, +922, 1834, 709, 1168, 345, 161, -100, -841, +-492, -1462, -687, -1603, -644, -1371, -490, -864, +-280, -203, 13, 362, 367, 637, 654, 655, +815, 574, 892, 470, 869, 357, 613, 279, +145, 263, -372, 211, -796, 11, -1102, -342, +-1172, -720, -844, -994, -158, -1070, 608, -868, +1236, -369, 1607, 286, 1639, 881, 1207, 1240, +397, 1235, -466, 824, -1120, 163, -1525, -494, +-1588, -963, -1178, -1128, -388, -922, 412, -433, +1050, 116, 1549, 511, 1803, 669, 1605, 589, +1022, 307, 297, -84, -437, -409, -1166, -531, +-1685, -466, -1727, -297, -1279, -68, -566, 182, +274, 378, 1140, 452, 1774, 392, 1893, 242, +1573, 44, 989, -188, 179, -416, -703, -580, +-1299, -632, -1443, -548, -1202, -340, -655, -73, +100, 210, 759, 495, 1082, 711, 1064, 733, +791, 562, 348, 320, -100, 34, -368, -345, +-358, -708, -174, -867, 66, -825, 254, -687, +316, -444, 208, -73, 4, 309, -166, 565, +-206, 689, -130, 699, 71, 593, 314, 395, +492, 147, 553, -118, 495, -351, 293, -522, +6, -652, -244, -750, -369, -745, -424, -577, +-386, -290, -206, 31, 75, 377, 349, 744, +565, 996, 706, 975, 761, 713, 644, 345, +390, -85, 100, -575, -163, -981, -430, -1144, +-671, -1072, -749, -852, -612, -492, -359, 8, +1, 538, 457, 955, 905, 1183, 1170, 1179, +1183, 923, 975, 431, 585, -213, 47, -843, +-509, -1275, -938, -1402, -1125, -1212, -1052, -764, +-709, -166, -146, 444, 469, 916, 963, 1133, +1275, 1062, 1318, 789, 1033, 419, 483, -27, +-105, -507, -579, -867, -878, -987, -901, -918, +-594, -725, -104, -372, 364, 129, 666, 584, +776, 789, 632, 750, 288, 572, -52, 256, +-232, -162, -263, -496, -169, -592, 33, -502, +319, -326, 529, -103, 553, 117, 416, 232, +201, 200, -77, 80, -350, -40, -473, -120, +-383, -151, -227, -126, -50, -44, 198, 56, +483, 115, 678, 99, 747, 25, 707, -74, +554, -161, 251, -197, -118, -168, -448, -95, +-658, 10, -721, 117, -592, 152, -249, 73, +213, -66, 629, -184, 925, -258, 994, -276, +803, -175, 462, 55, 113, 294, -225, 392, +-491, 323, -543, 135, -381, -156, -192, -492, +-14, -693, 163, -614, 296, -288, 356, 145, +392, 568, 438, 828, 483, 775, 460, 400, +353, -152, 161, -706, -81, -1076, -358, -1112, +-592, -795, -639, -259, -430, 333, -14, 836, +506, 1098, 944, 1029, 1157, 711, 1051, 293, +632, -144, 5, -551, -622, -860, -993, -1013, +-966, -998, -649, -844, -157, -572, 419, -192, +922, 276, 1111, 737, 965, 1067, 683, 1196, +358, 1113, -58, 797, -462, 273, -689, -347, +-675, -917, -542, -1319, -323, -1477, 70, -1349, +581, -913, 936, -247, 1017, 457, 913, 1012, +665, 1334, 174, 1354, -416, 1025, -781, 442, +-807, -173, -605, -677, -253, -1021, 187, -1130, +585, -968, 760, -639, 718, -267, 562, 121, +357, 498, 141, 766, 1, 874, -33, 838, +-37, 627, -94, 202, -149, -340, -220, -825, +-300, -1139, -243, -1246, 9, -1079, 292, -577, +525, 127, 722, 741, 799, 1132, 611, 1329, +260, 1270, -76, 851, -348, 207, -517, -402, +-481, -898, -227, -1306, 120, -1512, 368, -1362, +480, -905, 491, -328, 403, 287, 191, 903, +-56, 1360, -178, 1471, -114, 1227, 48, 764, +259, 201, 440, -385, 494, -886, 342, -1190, +28, -1260, -297, -1148, -470, -903, -447, -526, +-220, -31, 178, 506, 670, 987, 1019, 1317, +1032, 1405, 724, 1170, 238, 609, -330, -168, +-830, -953, -1064, -1528, -896, -1724, -443, -1493, +117, -885, 667, -62, 1098, 731, 1268, 1268, +1122, 1451, 752, 1278, 324, 810, -122, 177, +-544, -433, -811, -879, -821, -1115, -644, -1133, +-387, -939, -64, -585, 309, -131, 586, 337, +740, 701, 818, 887, 810, 916, 665, 775, +419, 436, 143, -15, -129, -434, -375, -748, +-493, -932, -463, -937, -344, -741, -188, -396, +46, 25, 332, 435, 527, 734, 541, 837, +458, 725, 318, 424, 121, 13, -59, -398, +-74, -663, 67, -689, 213, -512, 288, -233, +308, 67, 231, 285, 74, 308, -103, 133, +-209, -89, -192, -237, -43, -292, 142, -237, +258, -37, 289, 203, 287, 322, 202, 312, +62, 250, -18, 114, 28, -101, 134, -286, +228, -377, 282, -427, 318, -440, 284, -352, +168, -161, 36, 69, 4, 309, 51, 522, +62, 605, 7, 479, -46, 175, -108, -222, +-186, -610, -241, -867, -153, -882, 100, -627, +423, -160, 712, 389, 934, 860, 1023, 1100, +873, 1021, 425, 614, -179, -20, -764, -705, +-1190, -1249, -1340, -1503, -1109, -1371, -476, -859, +393, -86, 1172, 740, 1649, 1387, 1756, 1674, +1480, 1538, 816, 1017, -66, 218, -865, -667, +-1347, -1387, -1450, -1765, -1170, -1743, -588, -1335, +170, -614, 877, 241, 1331, 1005, 1452, 1492, +1266, 1605, 809, 1331, 177, 756, -466, 19, +-901, -701, -1048, -1203, -917, -1357, -537, -1188, +40, -788, 646, -261, 1064, 263, 1164, 637, +992, 796, 582, 760, 22, 569, -504, 274, +-793, -49, -771, -326, -500, -515, -117, -597, +310, -565, 669, -412, 836, -149, 749, 143, +543, 376, 337, 507, 96, 506, -176, 337, +-337, 43, -396, -266, -424, -492, -401, -603, +-231, -563, 59, -347, 390, -55, 693, 166, +891, 308, 890, 389, 687, 340, 304, 155, +-138, -9, -498, -82, -660, -142, -594, -184, +-375, -102, -90, 49, 230, 101, 464, 24, +524, -104, 465, -288, 404, -554, 304, -760, +169, -703, 123, -352, 169, 189, 151, 799, +75, 1322, -11, 1511, -120, 1189, -252, 406, +-313, -591, -253, -1500, -110, -2025, 79, -1957, +328, -1294, 559, -254, 701, 844, 705, 1657, +590, 1912, 368, 1550, 65, 771, -234, -147, +-443, -945, -601, -1389, -695, -1342, -628, -901, +-319, -292, 127, 273, 579, 629, 991, 673, +1269, 448, 1255, 111, 927, -174, 376, -299, +-246, -233, -831, -31, -1225, 184, -1279, 281, +-965, 200, -406, -55, 258, -366, 850, -568, +1230, -566, 1312, -383, 1118, -80, 708, 258, +222, 497, -176, 528, -433, 380, -603, 165, +-661, -27, -597, -179, -425, -280, -209, -318, +41, -316, 340, -341, 647, -375, 836, -324, +854, -150, 725, 89, 479, 341, 100, 556, +-296, 629, -538, 486, -576, 189, -463, -145, +-246, -455, 6, -681, 247, -724, 394, -574, +434, -333, 427, -72, 438, 212, 421, 468, +317, 610, 153, 608, -20, 491, -225, 243, +-400, -125, -462, -513, -348, -781, -65, -839, +271, -677, 508, -340, 619, 99, 607, 503, +448, 720, 155, 690, -85, 472, -178, 147, +-173, -184, -105, -418, 12, -494, 92, -442, +80, -328, -22, -203, -103, -85, -77, 4, +78, 71, 301, 120, 502, 168, 589, 207, +498, 197, 224, 108, -103, -13, -372, -106, +-481, -158, -388, -168, -115, -104, 241, 7, +547, 64, 672, 7, 582, -124, 296, -274, +-49, -393, -324, -412, -453, -278, -424, -19, +-246, 289, 30, 543, 329, 657, 542, 585, +638, 337, 593, -26, 427, -384, 177, -646, +-77, -784, -263, -768, -346, -559, -342, -212, +-224, 161, -38, 478, 142, 687, 238, 712, +252, 532, 220, 205, 173, -170, 155, -496, +201, -654, 254, -587, 278, -360, 248, -75, +160, 203, 18, 377, -135, 354, -225, 171, +-194, -33, -85, -192, 47, -304, 143, -306, +190, -155, 144, 31, 34, 127, -31, 150, +22, 139, 153, 47, 331, -98, 489, -188, +545, -173, 411, -107, 129, -9, -198, 123, +-459, 243, -556, 249, -441, 116, -192, -98, +105, -328, 341, -534, 448, -620, 424, -493, +361, -171, 281, 224, 175, 590, 112, 831, +145, 829, 138, 535, 31, 56, -111, -452, +-225, -859, -325, -1043, -362, -913, -237, -533, +63, -45, 371, 423, 555, 750, 615, 830, +595, 667, 433, 354, 118, 4, -203, -282, +-393, -460, -489, -543, -490, -532, -335, -433, +-10, -312, 328, -204, 553, -45, 674, 184, +702, 417, 564, 587, 264, 663, -90, 590, +-371, 335, -561, -65, -633, -509, -545, -862, +-298, -1017, 49, -941, 429, -641, 730, -160, +884, 378, 845, 808, 621, 1039, 238, 1044, +-169, 808, -476, 346, -648, -212, -706, -700, +-601, -1019, -316, -1140, 77, -997, 427, -589, +666, -55, 782, 426, 750, 770, 551, 923, +259, 840, -43, 554, -295, 192, -478, -157, +-534, -440, -449, -609, -249, -648, -2, -605, +230, -499, 397, -322, 499, -80, 506, 180, +431, 431, 301, 637, 150, 717, -11, 599, +-169, 325, -311, -28, -392, -399, -384, -706, +-251, -823, -24, -713, 253, -461, 512, -155, +671, 175, 674, 441, 512, 545, 192, 494, +-188, 388, -507, 237, -660, 29, -605, -155, +-326, -235, 89, -270, 460, -304, 647, -301, +636, -259, 462, -244, 202, -245, -63, -189, +-218, -65, -192, 93, -49, 289, 65, 499, +117, 637, 105, 616, -6, 425, -213, 81, +-345, -356, -294, -770, -107, -1022, 147, -1026, +452, -785, 720, -345, 830, 215, 700, 757, +406, 1118, 30, 1193, -373, 970, -739, 486, +-917, -146, -845, -748, -569, -1165, -161, -1303, +337, -1107, 780, -605, 1038, 41, 1063, 617, +882, 990, 522, 1095, 70, 900, -365, 467, +-664, -19, -800, -402, -764, -643, -567, -742, +-235, -688, 125, -540, 423, -377, 613, -204, +700, 35, 654, 332, 490, 627, 244, 834, +-17, 870, -251, 666, -421, 222, -463, -351, +-331, -844, -99, -1085, 150, -1004, 352, -641, +457, -122, 391, 339, 189, 559, -46, 492, +-242, 245, -336, -24, -253, -153, -43, -64, +209, 218, 402, 536, 470, 712, 405, 608, +241, 216, -2, -359, -240, -928, -353, -1323, +-313, -1405, -201, -1135, -24, -574, 196, 124, +354, 808, 376, 1332, 311, 1595, 202, 1531, +58, 1146, -113, 501, -235, -275, -257, -1015, +-176, -1543, -38, -1749, 132, -1581, 276, -1067, +328, -330, 270, 427, 183, 1035, 96, 1374, +24, 1391, -6, 1103, -3, 622, -42, 86, +-133, -390, -238, -744, -281, -917, -226, -894, +-39, -710, 242, -453, 539, -164, 730, 139, +697, 386, 406, 490, -40, 471, -527, 383, +-883, 228, -943, 17, -610, -142, 7, -184, +667, -140, 1130, -67, 1253, 12, 948, 41, +294, -29, -472, -176, -1043, -314, -1229, -387, +-986, -348, -431, -168, 247, 109, 826, 350, +1110, 478, 987, 480, 593, 347, 138, 107, +-271, -126, -564, -265, -599, -321, -362, -333, +-54, -302, 143, -247, 267, -210, 322, -179, +251, -81, 81, 105, -50, 320, -116, 488, +-168, 573, -199, 512, -123, 267, 45, -94, +247, -440, 416, -696, 510, -799, 465, -686, +274, -391, -1, -41, -257, 288, -439, 549, +-483, 671, -408, 615, -246, 452, -30, 243, +198, -2, 359, -256, 437, -419, 446, -475, +398, -474, 270, -440, 117, -337, -39, -203, +-201, -78, -333, 33, -372, 182, -316, 367, +-159, 548, 71, 654, 291, 656, 404, 501, +409, 159, 308, -340, 115, -840, -96, -1176, +-227, -1212, -265, -900, -213, -273, -94, 491, +69, 1146, 220, 1461, 310, 1331, 297, 761, +202, -77, 69, -894, -58, -1397, -163, -1438, +-200, -1016, -161, -296, -65, 475, 33, 1027, +119, 1192, 180, 949, 201, 445, 157, -118, +75, -540, -14, -700, -60, -583, -43, -314, +32, -54, 116, 86, 158, 72, 119, -71, +21, -240, -100, -301, -189, -177, -217, 96, +-136, 422, 43, 679, 248, 755, 375, 593, +385, 234, 276, -209, 91, -592, -127, -793, +-276, -769, -297, -553, -212, -234, -98, 66, +24, 243, 126, 260, 174, 169, 162, 52, +173, -10, 216, 57, 247, 254, 241, 476, +186, 607, 29, 575, -206, 335, -432, -96, +-530, -590, -457, -990, -219, -1167, 114, -1055, +456, -660, 690, -93, 728, 488, 560, 933, +271, 1136, -65, 1043, -353, 709, -523, 252, +-529, -208, -402, -576, -222, -747, -69, -711, +44, -542, 131, -327, 208, -95, 287, 106, +411, 231, 547, 274, 624, 300, 566, 326, +354, 323, -11, 233, -463, 71, -899, -148, +-1163, -398, -1146, -619, -825, -675, -257, -509, +472, -155, 1156, 298, 1578, 751, 1620, 1022, +1292, 994, 634, 665, -189, 145, -952, -460, +-1464, -959, -1621, -1191, -1394, -1115, -869, -821, +-157, -369, 570, 132, 1130, 557, 1410, 817, +1400, 936, 1088, 916, 541, 749, -84, 455, +-631, 111, -1012, -253, -1132, -598, -973, -855, +-588, -934, -112, -823, 329, -559, 674, -216, +897, 149, 907, 452, 696, 633, 362, 666, +-14, 575, -432, 387, -787, 147, -941, -109, +-853, -330, -554, -462, -52, -455, 562, -300, +1112, -29, 1385, 270, 1249, 480, 714, 499, +-53, 277, -847, -138, -1434, -596, -1604, -926, +-1263, -987, -558, -707, 277, -127, 1024, 569, +1497, 1150, 1522, 1432, 1097, 1316, 414, 814, +-271, 72, -811, -689, -1086, -1261, -1023, -1503, +-667, -1355, -205, -861, 213, -178, 509, 497, +650, 1011, 595, 1236, 391, 1114, 129, 697, +-90, 143, -235, -374, -288, -715, -246, -817, +-119, -664, 11, -340, 108, 1, 163, 210, +195, 283, 184, 245, 151, 134, 108, 21, +19, 20, -134, 103, -261, 162, -313, 135, +-293, 49, -187, -109, 43, -297, 308, -397, +481, -308, 521, -90, 448, 159, 229, 346, +-107, 395, -437, 242, -606, -34, -580, -293, +-369, -405, -3, -336, 409, -84, 675, 245, +715, 492, 552, 517, 221, 327, -222, -18, +-605, -398, -807, -670, -790, -689, -547, -466, +-94, -97, 437, 279, 887, 568, 1098, 657, +982, 534, 584, 278, 27, 15, -562, -199, +-974, -324, -1064, -338, -847, -275, -444, -221, +68, -193, 536, -173, 797, -125, 785, -39, +559, 109, 215, 283, -120, 418, -339, 454, +-368, 364, -237, 144, -50, -134, 89, -358, +145, -453, 107, -412, 23, -248, -55, -6, +-95, 201, -89, 274, -14, 217, 62, 91, +58, -63, -11, -195, -81, -234, -165, -150, +-200, 1, -87, 138, 181, 225, 459, 251, +637, 207, 658, 101, 483, -22, 83, -118, +-419, -171, -822, -192, -987, -184, -909, -156, +-587, -113, -80, -68, 433, -15, 765, 46, +892, 114, 841, 167, 644, 187, 340, 168, +30, 125, -220, 60, -402, -14, -567, -82, +-680, -113, -670, -127, -520, -134, -295, -141, +10, -126, 368, -92, 666, -28, 796, 54, +758, 153, 568, 223, 266, 234, -90, 152, +-406, 9, -609, -147, -663, -236, -592, -234, +-412, -135, -173, 11, 78, 155, 311, 209, +503, 150, 567, -8, 497, -168, 352, -256, +167, -212, -55, -53, -234, 194, -306, 414, +-290, 492, -260, 371, -227, 115, -194, -221, +-182, -550, -210, -764, -189, -747, -44, -516, +212, -151, 512, 265, 797, 682, 941, 972, +823, 1029, 415, 834, -174, 455, -789, -62, +-1265, -618, -1456, -1056, -1262, -1218, -723, -1073, +17, -679, 754, -135, 1329, 433, 1598, 839, +1477, 971, 999, 840, 317, 539, -417, 180, +-1044, -113, -1427, -260, -1452, -264, -1135, -194, +-583, -122, 62, -120, 675, -217, 1094, -357, +1217, -446, 1035, -431, 645, -297, 150, -45, +-326, 275, -671, 554, -810, 711, -751, 729, +-545, 603, -280, 345, -5, 19, 229, -306, +396, -586, 464, -764, 447, -777, 378, -620, +273, -329, 109, 47, -59, 424, -175, 678, +-255, 731, -366, 591, -450, 318, -443, -32, +-356, -342, -211, -495, 29, -448, 332, -281, +604, -68, 740, 124, 704, 244, 511, 227, +194, 100, -228, -48, -630, -128, -843, -141, +-821, -79, -626, 34, -269, 164, 157, 223, +463, 182, 545, 44, 466, -121, 311, -268, +151, -339, 34, -307, 26, -141, 110, 107, +172, 356, 113, 494, -38, 498, -271, 345, +-568, 53, -793, -311, -784, -590, -536, -699, +-86, -596, 477, -303, 978, 134, 1215, 549, +1113, 799, 685, 789, 56, 530, -596, 79, +-1081, -396, -1259, -734, -1055, -823, -571, -656, +26, -265, 592, 202, 965, 560, 982, 675, +683, 559, 223, 282, -249, -57, -606, -338, +-699, -428, -507, -322, -157, -108, 177, 95, +409, 225, 479, 234, 334, 115, 7, -74, +-305, -216, -475, -236, -502, -143, -356, 5, +-20, 168, 319, 282, 480, 263, 456, 104, +313, -99, 68, -259, -172, -336, -282, -284, +-234, -84, -114, 187, 3, 412, 57, 512, +15, 448, -145, 218, -339, -119, -436, -449, +-346, -658, -78, -679, 320, -499, 715, -163, +934, 227, 853, 542, 482, 689, -87, 626, +-684, 385, -1129, 56, -1271, -242, -1067, -422, +-564, -438, 87, -302, 716, -68, 1148, 142, +1273, 238, 1060, 196, 591, 60, -9, -122, +-583, -275, -979, -318, -1086, -206, -931, -12, +-576, 199, -112, 360, 326, 422, 585, 341, +652, 171, 571, -29, 366, -194, 85, -298, +-131, -292, -235, -215, -255, -110, -208, -15, +-96, 73, 11, 104, 49, 90, 6, 58, +-61, 45, -143, 11, -240, -27, -309, -42, +-267, -13, -124, 3, 73, 24, 302, 81, +529, 164, 629, 189, 547, 154, 311, 76, +-21, -35, -390, -198, -683, -347, -818, -420, +-752, -373, -517, -234, -184, -17, 159, 226, +449, 434, 610, 528, 636, 492, 558, 335, +394, 109, 161, -120, -67, -273, -266, -345, +-435, -336, -543, -250, -553, -137, -486, -81, +-353, -70, -173, -50, 54, -13, 281, 26, +457, 105, 544, 230, 539, 343, 406, 381, +165, 338, -100, 232, -327, 85, -515, -81, +-590, -236, -508, -352, -323, -422, -98, -446, +168, -423, 392, -334, 463, -164, 362, 77, +181, 344, -23, 569, -202, 692, -313, 671, +-294, 490, -187, 183, -79, -157, 11, -432, +116, -589, 163, -621, 117, -538, 39, -363, +-14, -141, -78, 69, -139, 260, -154, 428, +-103, 536, -36, 523, 18, 379, 57, 133, +98, -142, 76, -390, -34, -513, -165, -444, +-237, -196, -248, 94, -175, 316, -1, 378, +235, 252, 406, -21, 432, -289, 311, -428, +80, -358, -226, -110, -496, 231, -610, 505, +-539, 601, -368, 474, -118, 184, 165, -182, +365, -474, 427, -607, 416, -554, 335, -379, +179, -131, -2, 119, -143, 328, -260, 444, +-344, 483, -377, 444, -343, 339, -248, 153, +-101, -75, 59, -308, 193, -473, 235, -539, +183, -469, 75, -283, -18, -25, -51, 207, +-1, 363, 80, 400, 144, 340, 137, 206, +41, 54, -145, -67, -340, -117, -473, -117, +-491, -91, -362, -54, -89, -16, 208, -14, +419, -52, 483, -92, 399, -101, 183, -79, +-71, -25, -252, 63, -299, 174, -240, 247, +-122, 231, -11, 133, 51, -17, 28, -187, +-69, -318, -198, -342, -295, -237, -311, -44, +-203, 176, 11, 357, 289, 434, 522, 390, +594, 248, 451, 44, 143, -163, -252, -314, +-606, -397, -795, -434, -739, -417, -476, -321, +-80, -158, 340, 49, 658, 299, 746, 555, +590, 723, 249, 715, -157, 525, -507, 181, +-677, -237, -640, -616, -446, -809, -171, -759, +118, -494, 340, -122, 458, 232, 456, 438, +337, 443, 128, 278, -105, 57, -329, -121, +-482, -160, -497, -43, -363, 174, -150, 354, +96, 408, 309, 292, 409, 43, 339, -272, +136, -505, -122, -559, -341, -409, -464, -151, +-438, 129, -256, 320, 15, 342, 244, 167, +385, -80, 419, -273, 332, -307, 154, -164, +-44, 138, -235, 472, -376, 704, -451, 707, +-471, 464, -444, 32, -336, -429, -164, -782, +52, -907, 304, -775, 544, -431, 671, -24, +649, 317, 453, 499, 110, 518, -283, 399, +-607, 234, -795, 106, -777, 78, -573, 129, +-285, 192, -10, 177, 207, 62, 314, -149, +319, -406, 271, -614, 242, -652, 259, -483, +296, -155, 269, 230, 165, 562, -36, 716, +-343, 628, -670, 329, -849, -62, -824, -410, +-606, -585, -217, -522, 270, -247, 683, 136, +905, 491, 878, 693, 625, 667, 223, 403, +-216, -9, -596, -436, -810, -761, -818, -897, +-652, -789, -373, -467, -33, -40, 274, 374, +469, 695, 502, 853, 403, 806, 238, 583, +63, 293, -102, 14, -205, -218, -225, -381, +-198, -444, -178, -440, -169, -428, -173, -427, +-196, -395, -237, -310, -224, -153, -107, 82, +81, 383, 243, 668, 354, 851, 409, 844, +363, 629, 173, 234, -71, -226, -284, -634, +-445, -864, -549, -840, -524, -553, -339, -141, +-69, 257, 160, 517, 323, 559, 408, 344, +356, -8, 153, -333, -86, -496, -265, -449, +-364, -174, -372, 227, -231, 605, 12, 808, +227, 789, 311, 536, 269, 132, 111, -299, +-125, -629, -342, -810, -428, -813, -389, -668, +-257, -410, -70, -118, 129, 172, 265, 420, +315, 607, 279, 687, 176, 655, 22, 521, +-146, 322, -295, 68, -381, -182, -397, -368, +-336, -459, -188, -480, 19, -437, 208, -338, +342, -198, 384, -56, 323, 80, 159, 206, +-46, 308, -230, 352, -340, 335, -373, 267, +-344, 169, -288, 52, -234, -56, -214, -136, +-179, -178, -75, -196, 106, -192, 331, -167, +560, -103, 694, -1, 649, 113, 399, 207, +1, 269, -461, 259, -859, 152, -1080, -19, +-1042, -180, -757, -286, -305, -318, 182, -267, +592, -144, 823, 0, 833, 113, 645, 187, +354, 246, 65, 306, -157, 364, -322, 391, +-402, 356, -399, 219, -375, -34, -398, -364, +-418, -664, -394, -830, -321, -791, -177, -546, +87, -138, 415, 312, 690, 679, 790, 872, +676, 872, 362, 692, -91, 406, -576, 82, +-913, -219, -981, -481, -770, -667, -361, -748, +143, -696, 575, -509, 772, -178, 671, 232, +363, 613, -17, 835, -340, 842, -538, 619, +-550, 221, -404, -244, -209, -600, -62, -743, +45, -647, 113, -367, 145, 17, 170, 358, +217, 553, 251, 548, 244, 375, 159, 103, +-15, -153, -244, -321, -455, -351, -592, -254, +-593, -63, -449, 125, -202, 238, 67, 236, +295, 138, 435, -26, 485, -187, 431, -277, +297, -239, 123, -97, -58, 103, -255, 285, +-415, 404, -483, 408, -468, 286, -400, 71, +-262, -159, -93, -344, 56, -438, 162, -419, +238, -285, 274, -83, 279, 138, 243, 318, +164, 405, 61, 376, -50, 255, -183, 79, +-297, -97, -363, -210, -372, -223, -332, -164, +-245, -74, -145, 8, -55, 48, 28, 32, +121, -1, 208, 0, 289, 70, 348, 183, +363, 283, 294, 300, 122, 190, -133, -56, +-404, -368, -631, -621, -738, -684, -682, -496, +-459, -90, -135, 401, 203, 823, 473, 1022, +620, 907, 604, 507, 455, -26, 225, -527, +-17, -854, -224, -924, -356, -725, -421, -371, +-434, -2, -412, 284, -371, 448, -319, 462, +-221, 376, -64, 269, 139, 211, 351, 191, +531, 189, 616, 166, 560, 92, 344, -72, +5, -288, -385, -490, -723, -599, -912, -578, +-869, -403, -608, -105, -203, 249, 238, 546, +601, 713, 765, 701, 712, 522, 486, 222, +151, -91, -211, -336, -484, -457, -597, -445, +-535, -307, -363, -114, -150, 64, 34, 173, +140, 204, 124, 141, 37, 20, -34, -108, +-55, -178, -60, -166, -25, -57, 60, 110, +158, 300, 209, 442, 197, 472, 131, 351, +19, 125, -145, -140, -335, -366, -485, -485, +-539, -451, -524, -300, -425, -108, -204, 37, +110, 92, 427, 51, 669, -20, 764, -37, +663, 71, 371, 309, -30, 605, -427, 818, +-706, 817, -816, 544, -747, 43, -519, -565, +-202, -1088, 90, -1342, 290, -1221, 367, -767, +340, -135, 258, 488, 176, 953, 109, 1152, +69, 1067, 35, 788, -14, 445, -94, 113, +-193, -165, -312, -380, -423, -539, -486, -670, +-462, -749, -339, -721, -116, -539, 163, -212, +447, 230, 665, 686, 743, 1014, 627, 1084, +325, 873, -120, 416, -602, -184, -988, -757, +-1148, -1104, -1021, -1125, -619, -812, -41, -245, +561, 432, 1006, 996, 1168, 1267, 998, 1163, +558, 726, -19, 66, -557, -616, -911, -1104, +-998, -1238, -833, -1003, -497, -478, -117, 161, +192, 714, 352, 1005, 353, 975, 244, 656, +117, 186, 38, -274, 41, -565, 113, -620, +197, -442, 214, -134, 124, 191, -84, 416, +-350, 478, -569, 357, -657, 130, -596, -123, +-384, -321, -77, -412, 232, -364, 446, -211, +523, -7, 454, 176, 284, 292, 78, 305, +-89, 229, -189, 106, -228, 11, -251, -16, +-279, 35, -318, 129, -342, 218, -325, 226, +-226, 111, -44, -120, 175, -379, 362, -570, +466, -598, 443, -416, 290, -48, 51, 379, +-203, 718, -414, 837, -526, 690, -513, 311, +-404, -169, -253, -574, -83, -755, 80, -658, +213, -314, 314, 142, 395, 545, 409, 752, +317, 703, 128, 418, -117, 0, -374, -396, +-560, -637, -626, -676, -555, -525, -364, -236, +-97, 99, 162, 359, 353, 495, 435, 515, +400, 441, 270, 302, 105, 152, -52, 21, +-173, -90, -261, -191, -303, -269, -296, -316, +-245, -317, -174, -269, -92, -155, -17, 10, +30, 186, 31, 320, 12, 387, -3, 372, +1, 286, 26, 148, 87, 3, 154, -123, +168, -206, 82, -242, -74, -228, -255, -176, +-399, -81, -457, 35, -387, 147, -207, 218, +29, 248, 240, 212, 368, 114, 379, -8, +281, -95, 97, -129, -99, -94, -246, -12, +-323, 74, -345, 109, -302, 80, -225, -10, +-150, -112, -75, -174, 17, -137, 92, -7, +152, 175, 188, 337, 184, 418, 142, 357, +85, 168, 9, -96, -67, -341, -136, -493, +-217, -499, -318, -359, -387, -98, -386, 199, +-306, 455, -155, 607, 62, 614, 284, 457, +429, 193, 436, -120, 318, -404, 103, -578, +-151, -579, -362, -426, -447, -166, -393, 130, +-241, 377, -77, 497, 54, 478, 113, 350, +91, 184, 5, 32, -72, -57, -89, -86, +-54, -85, -2, -98, 55, -144, 80, -222, +35, -298, -75, -329, -186, -262, -254, -87, +-250, 166, -174, 430, -27, 638, 139, 713, +256, 621, 265, 373, 174, 29, 12, -334, +-189, -617, -370, -741, -444, -677, -392, -444, +-244, -99, -44, 245, 168, 476, 302, 547, +307, 470, 203, 278, 45, 63, -133, -82, +-271, -101, -311, -26, -246, 90, -129, 170, +5, 149, 126, 21, 192, -153, 165, -307, +73, -362, -44, -278, -161, -75, -277, 157, +-352, 328, -351, 363, -283, 262, -182, 69, +-45, -127, 120, -242, 280, -214, 388, -58, +427, 163, 367, 355, 201, 448, -42, 391, +-298, 206, -504, -45, -604, -272, -584, -413, +-455, -430, -253, -347, -29, -201, 150, -45, +255, 88, 296, 168, 301, 217, 280, 264, +257, 330, 227, 388, 166, 413, 32, 359, +-173, 203, -411, -64, -633, -375, -777, -639, +-757, -751, -541, -652, -165, -333, 276, 131, +678, 605, 926, 931, 927, 1010, 658, 782, +200, 302, -316, -279, -765, -771, -1042, -1033, +-1041, -979, -760, -620, -315, -64, 144, 501, +520, 913, 716, 1059, 679, 908, 455, 518, +160, 32, -119, -405, -312, -666, -378, -703, +-326, -540, -233, -259, -170, 39, -172, 255, +-228, 341, -299, 304, -311, 185, -226, 41, +-44, -58, 196, -75, 441, -10, 614, 105, +638, 235, 468, 325, 154, 328, -224, 224, +-585, 35, -842, -198, -905, -403, -765, -515, +-484, -485, -126, -305, 255, -15, 555, 281, +688, 488, 643, 549, 464, 455, 196, 240, +-90, 6, -318, -149, -432, -175, -435, -91, +-360, 48, -258, 139, -163, 105, -119, -60, +-143, -284, -186, -467, -177, -497, -95, -319, +64, 41, 285, 465, 495, 805, 588, 934, +516, 800, 281, 429, -92, -66, -522, -537, +-858, -842, -1000, -912, -911, -741, -599, -396, +-118, 15, 400, 379, 804, 632, 979, 724, +889, 660, 560, 477, 82, 239, -419, -10, +-801, -215, -964, -336, -880, -358, -592, -306, +-189, -197, 201, -66, 469, 48, 554, 119, +472, 154, 270, 149, 32, 125, -159, 93, +-256, 67, -269, 42, -220, 21, -153, 0, +-112, -10, -115, -9, -138, 11, -168, 51, +-180, 110, -136, 159, -38, 178, 69, 157, +171, 104, 243, 20, 249, -73, 179, -163, +63, -231, -91, -264, -266, -244, -412, -185, +-482, -84, -461, 66, -340, 246, -140, 398, +92, 486, 291, 496, 402, 416, 400, 238, +294, 21, 103, -177, -119, -318, -298, -381, +-378, -363, -368, -296, -292, -210, -183, -129, +-91, -58, -58, 11, -56, 110, -29, 252, +29, 414, 88, 540, 145, 577, 182, 493, +158, 286, 55, -19, -92, -334, -236, -547, +-327, -602, -329, -513, -231, -309, -75, -55, +70, 170, 140, 310, 119, 372, 23, 376, +-108, 347, -228, 296, -287, 220, -260, 86, +-146, -97, 23, -288, 179, -423, 260, -436, +261, -283, 196, 6, 73, 344, -96, 599, +-255, 659, -364, 481, -422, 131, -415, -270, +-313, -572, -154, -662, -1, -507, 116, -191, +203, 161, 238, 418, 220, 506, 165, 429, +88, 274, 0, 117, -81, 28, -155, 23, +-212, 60, -253, 55, -278, -19, -281, -160, +-254, -319, -209, -424, -141, -405, -51, -255, +50, 1, 143, 284, 238, 517, 321, 630, +336, 616, 248, 481, 80, 260, -156, -7, +-436, -268, -663, -493, -723, -636, -589, -664, +-295, -548, 92, -289, 461, 83, 661, 477, +628, 793, 384, 935, 6, 864, -388, 578, +-640, 157, -659, -290, -462, -635, -153, -793, +156, -750, 357, -565, 373, -292, 206, 6, +-36, 254, -235, 415, -338, 520, -331, 581, +-206, 589, -33, 526, 79, 389, 84, 174, +33, -100, -37, -395, -101, -631, -113, -739, +-37, -677, 71, -460, 125, -123, 84, 256, +-30, 570, -195, 736, -357, 730, -444, 551, +-397, 253, -234, -70, -13, -316, 207, -433, +374, -400, 417, -229, 322, 14, 133, 230, +-81, 342, -281, 301, -419, 122, -465, -132, +-421, -362, -317, -478, -154, -397, 42, -124, +210, 253, 301, 601, 308, 804, 227, 766, +62, 473, -148, 12, -325, -463, -424, -800, +-416, -864, -289, -632, -61, -188, 188, 313, +357, 706, 374, 858, 239, 730, -4, 371, +-287, -75, -528, -443, -617, -601, -512, -531, +-251, -278, 81, 52, 385, 331, 541, 441, +484, 377, 248, 189, -64, -26, -354, -181, +-531, -204, -544, -107, -388, 57, -121, 203, +153, 261, 318, 189, 324, 33, 188, -142, +-39, -264, -271, -278, -408, -159, -408, 49, +-285, 266, -76, 402, 160, 418, 325, 310, +359, 114, 257, -116, 45, -298, -221, -387, +-441, -367, -539, -257, -486, -79, -298, 113, +-21, 283, 259, 399, 444, 445, 454, 403, +296, 290, 37, 133, -240, -41, -462, -204, +-551, -305, -483, -327, -303, -283, -77, -200, +141, -87, 284, 23, 308, 104, 235, 160, +118, 204, -15, 237, -136, 263, -210, 270, +-236, 247, -253, 181, -251, 73, -203, -60, +-126, -181, -60, -258, 10, -263, 80, -195, +116, -71, 93, 61, 49, 158, 5, 190, +-46, 156, -105, 66, -135, -34, -134, -99, +-136, -97, -150, -15, -136, 125, -88, 260, +-48, 340, -35, 340, -9, 241, 10, 52, +-16, -151, -60, -303, -67, -361, -52, -312, +-42, -169, -14, 11, 29, 168, 26, 253, +-39, 250, -134, 175, -217, 82, -270, 8, +-255, -20, -141, -6, 30, 44, 162, 90, +211, 102, 180, 64, 73, 0, -92, -53, +-235, -60, -286, -21, -241, 55, -143, 141, +-18, 191, 78, 156, 78, 38, -19, -138, +-137, -299, -221, -381, -241, -331, -172, -146, +-17, 142, 147, 441, 253, 647, 271, 678, +189, 532, 5, 250, -220, -86, -403, -375, +-490, -528, -461, -527, -312, -402, -94, -221, +138, -50, 325, 64, 418, 133, 382, 184, +214, 247, -43, 332, -302, 427, -491, 478, +-550, 429, -457, 251, -222, -21, 63, -314, +296, -541, 413, -636, 386, -558, 198, -328, +-87, -18, -351, 278, -478, 492, -442, 571, +-271, 515, -33, 361, 172, 157, 253, -53, +190, -207, 22, -279, -175, -272, -315, -204, +-318, -88, -179, 37, 36, 131, 228, 169, +317, 157, 259, 115, 72, 74, -180, 51, +-388, 55, -479, 72, -436, 80, -282, 49, +-62, -25, 128, -120, 217, -189, 199, -199, +122, -130, 23, 3, -50, 169, -59, 315, +-20, 389, 17, 370, 23, 280, -29, 144, +-131, -20, -261, -184, -365, -312, -396, -404, +-323, -444, -159, -404, 43, -256, 216, -13, +326, 292, 346, 588, 273, 789, 128, 806, +-37, 617, -184, 254, -285, -188, -329, -587, +-319, -820, -273, -830, -195, -620, -111, -263, +-34, 143, 34, 481, 90, 674, 113, 687, +107, 550, 91, 312, 72, 53, 43, -162, +8, -288, -51, -332, -126, -300, -197, -215, +-264, -108, -316, -14, -308, 71, -220, 137, +-68, 178, 100, 198, 248, 210, 327, 197, +292, 157, 138, 90, -74, 3, -273, -97, +-401, -171, -426, -199, -325, -164, -139, -74, +54, 51, 194, 169, 246, 252, 192, 256, +60, 174, -94, 44, -199, -86, -227, -185, +-186, -205, -96, -126, 4, 23, 52, 174, +31, 276, -34, 285, -121, 187, -221, 11, +-266, -174, -204, -298, -61, -294, 100, -152, +247, 74, 334, 297, 310, 448, 159, 456, +-59, 295, -288, 15, -484, -271, -600, -470, +-576, -508, -392, -371, -116, -102, 171, 211, +422, 468, 571, 578, 559, 514, 385, 308, +116, 36, -192, -221, -470, -386, -623, -417, +-601, -311, -442, -112, -194, 112, 71, 288, +275, 376, 351, 348, 287, 210, 135, 2, +-46, -206, -209, -346, -286, -362, -252, -244, +-131, -23, 9, 230, 123, 445, 180, 533, +160, 447, 51, 215, -99, -71, -228, -331, +-301, -471, -316, -436, -256, -234, -136, 40, +-13, 281, 79, 399, 148, 358, 183, 181, +162, -49, 87, -239, -1, -297, -84, -200, +-155, 4, -203, 222, -209, 365, -182, 363, +-135, 220, -75, -4, 8, -212, 75, -320, +88, -266, 55, -79, 8, 153, -48, 333, +-109, 383, -155, 260, -159, 2, -140, -292, +-102, -501, -50, -541, 4, -366, 35, -28, +57, 362, 82, 682, 100, 837, 82, 755, +34, 449, -44, 13, -149, -417, -264, -729, +-343, -839, -351, -717, -277, -399, -154, 1, +7, 362, 184, 593, 323, 653, 362, 545, +312, 330, 199, 97, 36, -79, -156, -172, +-312, -177, -409, -138, -449, -116, -425, -143, +-322, -193, -149, -226, 52, -202, 237, -90, +379, 114, 430, 353, 357, 537, 173, 587, +-58, 472, -281, 201, -443, -146, -489, -458, +-398, -632, -218, -611, -9, -398, 163, -62, +262, 289, 253, 539, 157, 620, 30, 514, +-81, 267, -167, -40, -205, -298, -188, -423, +-139, -392, -96, -234, -55, -7, -12, 206, +21, 329, 37, 330, 46, 229, 44, 64, +26, -96, -11, -195, -58, -207, -104, -136, +-141, -6, -162, 127, -155, 213, -125, 226, +-80, 169, -35, 56, 12, -71, 52, -181, +81, -234, 97, -208, 91, -103, 49, 46, +-15, 206, -79, 340, -131, 408, -171, 366, +-186, 222, -178, 6, -164, -226, -145, -417, +-113, -504, -56, -466, 24, -297, 117, -30, +213, 265, 279, 502, 264, 620, 154, 584, +-33, 401, -260, 115, -454, -191, -532, -427, +-446, -519, -229, -449, 45, -250, 299, 9, +449, 245, 421, 368, 219, 342, -68, 196, +-324, 0, -472, -169, -450, -240, -251, -185, +23, -23, 246, 177, 358, 335, 331, 380, +171, 293, -73, 109, -292, -109, -400, -294, +-371, -384, -234, -353, -42, -223, 128, -47, +196, 121, 140, 240, 28, 290, -83, 272, +-159, 207, -167, 126, -80, 50, 71, -19, +194, -75, 227, -107, 162, -116, 0, -102, +-214, -61, -392, -2, -456, 54, -392, 96, +-218, 113, 29, 82, 271, 22, 397, -36, +373, -66, 222, -64, -4, -33, -230, 16, +-379, 68, -392, 94, -265, 88, -61, 66, +148, 54, 295, 63, 328, 89, 224, 121, +19, 127, -212, 72, -408, -44, -513, -188, +-471, -314, -291, -366, -29, -297, 235, -113, +437, 134, 522, 369, 460, 521, 263, 527, +-3, 376, -270, 118, -473, -151, -563, -356, +-508, -432, -340, -362, -115, -179, 118, 46, +305, 238, 389, 329, 358, 299, 230, 166, +53, -16, -140, -189, -297, -295, -363, -298, +-333, -188, -224, -4, -50, 196, 133, 350, +250, 421, 247, 386, 147, 246, -1, 38, +-155, -170, -254, -324, -245, -388, -144, -356, +-1, -237, 115, -75, 160, 92, 107, 219, +-28, 283, -191, 287, -302, 248, -307, 176, +-205, 89, -19, -2, 202, -81, 358, -135, +389, -162, 304, -160, 130, -123, -99, -55, +-321, 22, -472, 82, -505, 118, -442, 127, +-299, 113, -99, 80, 123, 47, 313, 23, +431, 14, 461, 10, 389, -6, 202, -39, +-35, -76, -254, -95, -400, -86, -453, -39, +-413, 46, -291, 142, -118, 210, 34, 211, +141, 135, 189, 1, 182, -146, 126, -260, +66, -287, 39, -199, 22, -19, -10, 183, +-42, 337, -80, 387, -122, 309, -155, 129, +-158, -77, -128, -232, -85, -282, -39, -218, +5, -81, 22, 49, 18, 110, -7, 81, +-18, -23, -13, -144, -1, -191, 19, -116, +55, 76, 82, 319, 83, 520, 46, 583, +-22, 462, -119, 166, -226, -217, -297, -568, +-301, -774, -226, -770, -84, -548, 92, -180, +264, 225, 361, 567, 346, 766, 217, 764, +10, 577, -211, 275, -368, -60, -399, -363, +-294, -552, -113, -582, 81, -461, 222, -241, +244, 16, 143, 243, -26, 382, -186, 394, +-274, 298, -257, 140, -115, -27, 85, -151, +243, -188, 300, -153, 240, -85, 83, -17, +-127, 35, -304, 57, -365, 51, -310, 51, +-170, 77, 16, 108, 183, 122, 251, 103, +189, 41, 45, -63, -94, -177, -188, -253, +-196, -250, -110, -157, 44, 1, 181, 171, +222, 301, 158, 350, 9, 302, -195, 178, +-362, 21, -410, -120, -312, -209, -115, -234, +117, -213, 319, -166, 413, -98, 352, -19, +170, 55, -67, 121, -268, 177, -377, 210, +-360, 201, -227, 146, -50, 62, 97, -24, +180, -79, 176, -88, 91, -57, -31, -5, +-116, 32, -134, 16, -107, -58, -40, -166, +58, -253, 132, -263, 142, -166, 83, 26, +-10, 269, -122, 485, -223, 584, -264, 518, +-228, 304, -142, 2, -37, -304, 69, -535, +168, -623, 223, -558, 212, -365, 152, -100, +74, 166, -6, 377, -98, 504, -192, 524, +-246, 439, -270, 275, -253, 67, -179, -146, +-58, -318, 78, -409, 198, -402, 276, -298, +286, -132, 202, 40, 49, 180, -119, 256, +-234, 259, -267, 209, -225, 137, -118, 67, +9, 10, 91, -31, 108, -63, 49, -96, +-58, -125, -153, -132, -173, -111, -100, -61, +26, 14, 162, 94, 260, 142, 265, 139, +169, 96, -9, 33, -201, -22, -339, -53, +-381, -43, -313, -7, -155, 30, 29, 43, +176, 23, 241, -21, 222, -67, 142, -91, +32, -71, -44, -13, -57, 56, -22, 118, +22, 152, 33, 134, 4, 73, -80, -2, +-203, -74, -307, -134, -344, -169, -286, -167, +-119, -126, 104, -52, 324, 47, 472, 159, +506, 262, 410, 319, 191, 302, -87, 195, +-348, 14, -522, -188, -563, -347, -481, -414, +-300, -364, -68, -209, 153, -1, 314, 184, +384, 280, 354, 276, 250, 194, 102, 82, +-26, 2, -108, 0, -140, 67, -135, 148, +-117, 179, -91, 119, -85, -34, -119, -232, +-159, -402, -171, -471, -143, -396, -94, -190, +-9, 74, 118, 303, 241, 431, 308, 435, +318, 342, 256, 200, 120, 63, -71, -23, +-255, -53, -369, -62, -413, -95, -376, -168, +-249, -259, -63, -338, 123, -358, 238, -277, +284, -97, 265, 133, 172, 349, 54, 485, +-27, 503, -62, 407, -67, 233, -53, 28, +-32, -164, -58, -296, -154, -351, -251, -344, +-285, -295, -239, -207, -125, -84, 57, 50, +285, 169, 438, 255, 455, 294, 357, 271, +168, 191, -104, 86, -378, -16, -534, -92, +-527, -133, -415, -141, -230, -129, 11, -114, +242, -99, 383, -75, 407, -39, 371, 25, +284, 120, 122, 212, -51, 258, -195, 233, +-306, 130, -395, -35, -421, -214, -339, -348, +-184, -373, -10, -260, 176, -45, 340, 207, +427, 413, 401, 497, 272, 415, 90, 186, +-127, -117, -325, -396, -417, -551, -392, -514, +-272, -303, -101, 5, 93, 306, 245, 505, +294, 527, 238, 370, 128, 107, -1, -159, +-118, -345, -183, -400, -170, -321, -101, -153, +-44, 30, 2, 159, 36, 200, 40, 173, +24, 112, 17, 60, 50, 36, 76, 43, +70, 51, 40, 31, -19, -33, -116, -126, +-219, -211, -265, -234, -209, -177, -74, -50, +90, 116, 243, 270, 321, 342, 291, 298, +161, 153, -20, -44, -184, -234, -300, -352, +-309, -348, -223, -224, -84, -20, 47, 200, +123, 365, 146, 411, 122, 321, 68, 129, +29, -109, 24, -326, 36, -451, 50, -433, +33, -280, -30, -49, -145, 188, -263, 369, +-299, 446, -248, 393, -101, 234, 109, 36, +319, -142, 457, -263, 451, -311, 301, -286, +45, -209, -257, -97, -501, 24, -593, 132, +-508, 215, -277, 265, 22, 260, 311, 183, +500, 37, 510, -133, 362, -269, 117, -327, +-120, -285, -286, -136, -339, 82, -267, 287, +-131, 400, 8, 379, 102, 228, 113, -1, +38, -224, -69, -362, -136, -378, -121, -270, +-46, -90, 71, 89, 203, 204, 267, 239, +232, 199, 94, 109, -80, 10, -239, -50, +-331, -62, -297, -39, -161, -3, 15, 36, +161, 67, 239, 71, 240, 35, 145, -28, +-25, -106, -179, -186, -245, -245, -213, -245, +-101, -163, 42, 6, 192, 224, 263, 426, +227, 529, 106, 480, -57, 275, -201, -43, +-283, -385, -266, -628, -157, -676, -13, -512, +112, -194, 186, 178, 196, 478, 148, 613, +54, 545, -39, 318, -78, 24, -86, -229, +-64, -368, -46, -365, -38, -249, -44, -83, +-75, 66, -89, 152, -58, 155, 25, 97, +128, 26, 209, -21, 234, -42, 162, -33, +-3, 3, -189, 42, -322, 57, -374, 49, +-302, 26, -113, -3, 152, -35, 368, -64, +456, -88, 415, -99, 243, -87, -19, -44, +-288, 28, -457, 110, -479, 173, -378, 190, +-173, 144, 80, 38, 285, -94, 367, -197, +333, -236, 229, -192, 99, -69, -53, 95, +-157, 229, -176, 277, -144, 221, -95, 82, +-54, -97, -12, -249, -15, -317, -67, -273, +-101, -142, -91, 29, -35, 187, 47, 281, +157, 295, 254, 243, 276, 146, 202, 27, +82, -89, -70, -177, -220, -230, -318, -253, +-321, -245, -228, -186, -106, -75, 32, 58, +158, 183, 220, 281, 208, 323, 143, 285, +76, 172, 9, 17, -45, -141, -60, -263, +-37, -316, -28, -290, -36, -188, -51, -36, +-60, 118, -73, 232, -92, 278, -68, 247, +-20, 147, 26, 9, 65, -126, 103, -215, +136, -226, 116, -163, 59, -59, -3, 56, +-64, 146, -129, 177, -160, 141, -134, 60, +-65, -31, 7, -98, 83, -127, 159, -112, +179, -69, 135, -1, 41, 77, -69, 138, +-173, 163, -251, 150, -241, 95, -150, -2, +-6, -129, 152, -240, 283, -290, 327, -256, +265, -143, 119, 29, -51, 215, -218, 338, +-335, 345, -343, 245, -254, 77, -97, -96, +72, -206, 215, -214, 302, -135, 288, -15, +212, 86, 91, 112, -46, 44, -177, -81, +-263, -193, -286, -238, -249, -191, -174, -59, +-49, 116, 120, 268, 274, 344, 365, 326, +362, 231, 279, 102, 101, -29, -137, -135, +-340, -207, -461, -249, -457, -271, -335, -267, +-107, -233, 154, -157, 354, -34, 450, 121, +434, 273, 295, 385, 72, 427, -154, 382, +-308, 243, -347, 43, -291, -165, -150, -339, +15, -444, 126, -452, 175, -361, 151, -193, +80, 11, -23, 206, -96, 343, -95, 395, +-35, 356, 46, 241, 110, 84, 131, -74, +97, -194, 18, -252, -78, -251, -139, -201, +-154, -117, -102, -20, 6, 63, 98, 118, +141, 145, 104, 141, 32, 100, -58, 31, +-135, -39, -156, -86, -119, -96, -38, -62, +62, 2, 146, 71, 183, 118, 164, 121, +103, 69, 41, -24, -21, -125, -79, -182, +-114, -179, -129, -126, -120, -41, -125, 58, +-118, 128, -87, 153, -38, 145, 27, 128, +105, 104, 187, 70, 242, 29, 249, -27, +210, -113, 129, -206, -8, -271, -160, -272, +-275, -185, -331, -15, -312, 186, -233, 352, +-83, 417, 78, 350, 203, 165, 260, -80, +245, -301, 180, -410, 88, -372, 22, -214, +-1, -2, -7, 187, -19, 288, -40, 273, +-83, 158, -145, 9, -202, -108, -207, -154, +-129, -125, -15, -49, 119, 26, 222, 71, +260, 65, 218, 12, 110, -55, -12, -91, +-116, -77, -166, -27, -148, 33, -74, 87, +14, 117, 72, 110, 78, 63, 52, 1, +16, -54, -27, -97, -49, -126, -56, -131, +-36, -107, -21, -52, -12, 25, 5, 112, +23, 188, 47, 228, 62, 206, 67, 112, +57, -35, 25, -182, -18, -273, -57, -282, +-78, -203, -71, -54, -38, 119, 5, 250, +56, 288, 78, 220, 74, 81, 38, -73, +-19, -196, -67, -250, -110, -217, -113, -117, +-71, 6, 6, 116, 97, 188, 175, 217, +225, 202, 212, 149, 125, 63, -16, -38, +-170, -136, -314, -222, -383, -271, -344, -256, +-178, -172, 63, -45, 306, 90, 491, 196, +533, 243, 413, 222, 162, 155, -132, 70, +-381, 5, -533, -12, -536, 6, -379, 25, +-119, 6, 147, -58, 356, -151, 456, -241, +438, -296, 296, -275, 102, -167, -70, -5, +-196, 157, -248, 279, -229, 346, -153, 356, +-84, 315, -53, 238, -28, 131, -2, -5, +24, -172, 56, -351, 116, -502, 185, -564, +220, -496, 190, -286, 118, 26, -3, 361, +-149, 617, -254, 713, -280, 612, -203, 342, +-70, -7, 88, -314, 224, -503, 273, -538, +216, -431, 76, -232, -78, -25, -198, 122, +-247, 198, -207, 219, -81, 200, 74, 173, +212, 151, 287, 129, 275, 91, 180, 27, +25, -65, -125, -176, -237, -275, -284, -328, +-250, -309, -148, -212, -3, -45, 124, 168, +215, 368, 253, 496, 228, 510, 145, 394, +40, 153, -71, -160, -159, -453, -203, -631, +-189, -640, -123, -465, -50, -154, 31, 192, +105, 467, 156, 598, 183, 553, 165, 360, +124, 97, 59, -141, -14, -288, -94, -327, +-165, -279, -212, -181, -207, -85, -152, -28, +-57, -8, 53, 7, 156, 40, 243, 95, +268, 158, 234, 207, 151, 211, 26, 158, +-98, 50, -199, -82, -228, -198, -200, -258, +-131, -241, -36, -161, 68, -47, 138, 76, +151, 171, 122, 206, 85, 177, 44, 105, +-12, 16, -43, -71, -48, -139, -39, -158, +-31, -126, -22, -57, 13, 20, 34, 89, +54, 137, 76, 149, 95, 121, 75, 59, +11, -22, -54, -100, -99, -158, -140, -180, +-161, -164, -122, -106, -37, -12, 59, 91, +141, 175, 208, 225, 247, 231, 224, 180, +166, 77, 75, -50, -41, -164, -185, -239, +-307, -265, -351, -233, -307, -148, -192, -32, +-9, 88, 212, 187, 392, 249, 469, 264, +419, 230, 272, 153, 48, 37, -195, -97, +-368, -212, -440, -285, -393, -303, -267, -249, +-77, -127, 132, 23, 294, 161, 385, 252, +410, 276, 364, 237, 231, 143, 44, 27, +-152, -75, -316, -139, -421, -160, -427, -145, +-315, -113, -121, -82, 108, -56, 300, -35, +417, -12, 411, 23, 289, 80, 109, 150, +-66, 202, -189, 210, -241, 170, -206, 83, +-109, -52, 5, -198, 88, -309, 121, -347, +93, -297, 26, -171, -39, 1, -82, 183, +-74, 334, -36, 412, 35, 391, 101, 280, +141, 106, 140, -102, 94, -304, 25, -447, +-47, -496, -91, -431, -93, -261, -51, -19, +19, 254, 87, 494, 119, 625, 96, 602, +25, 422, -76, 117, -156, -241, -192, -558, +-146, -742, -36, -733, 95, -532, 219, -193, +291, 194, 294, 524, 216, 714, 91, 728, +-46, 568, -166, 288, -251, -32, -277, -312, +-234, -506, -144, -593, -25, -568, 99, -446, +223, -260, 294, -46, 296, 174, 235, 375, +123, 517, -17, 569, -161, 513, -252, 356, +-269, 119, -215, -150, -100, -389, 51, -544, +186, -575, 262, -475, 274, -281, 224, -48, +131, 166, 5, 320, -98, 388, -164, 366, +-188, 275, -177, 157, -137, 44, -67, -44, +1, -109, 61, -147, 107, -157, 136, -155, +158, -149, 174, -133, 188, -103, 186, -57, +147, 3, 61, 63, -49, 114, -182, 152, +-293, 170, -354, 157, -328, 117, -206, 62, +-30, 4, 164, -63, 313, -137, 389, -201, +373, -237, 272, -228, 130, -165, -7, -45, +-85, 115, -98, 279, -69, 397, -48, 421, +-57, 324, -123, 118, -220, -153, -304, -423, +-313, -607, -214, -635, -21, -481, 249, -185, +518, 176, 696, 514, 700, 739, 518, 778, +198, 607, -201, 282, -576, -113, -812, -482, +-823, -731, -615, -789, -242, -646, 190, -347, +570, 20, 776, 354, 759, 565, 548, 601, +206, 472, -151, 235, -417, -25, -509, -220, +-418, -292, -219, -235, 14, -104, 195, 29, +266, 106, 202, 89, 61, -21, -78, -169, +-142, -269, -107, -267, 21, -149, 186, 48, +293, 256, 297, 396, 187, 408, 1, 287, +-210, 72, -363, -163, -383, -328, -276, -371, +-76, -294, 143, -135, 330, 43, 423, 176, +399, 220, 270, 177, 98, 85, -77, -14, +-210, -82, -270, -103, -261, -79, -202, -33, +-133, 1, -50, 3, 47, -18, 137, -37, +219, -25, 277, 28, 301, 114, 264, 187, +171, 206, 33, 139, -127, -19, -277, -223, +-358, -393, -342, -456, -231, -366, -50, -130, +158, 196, 345, 502, 442, 673, 413, 634, +267, 389, 44, 7, -183, -398, -355, -697, +-409, -787, -332, -642, -146, -313, 89, 90, +309, 450, 441, 663, 438, 683, 308, 520, +94, 238, -134, -76, -321, -334, -402, -477, +-353, -491, -200, -396, 5, -223, 192, -23, +324, 157, 353, 280, 291, 329, 172, 302, +40, 216, -78, 86, -148, -58, -153, -186, +-108, -266, -51, -283, -5, -233, 30, -132, +38, 2, 30, 139, 26, 245, 38, 292, +67, 266, 90, 175, 114, 36, 118, -121, +93, -250, 32, -318, -31, -313, -72, -242, +-93, -116, -91, 32, -55, 167, 3, 264, +52, 307, 90, 289, 115, 224, 121, 122, +101, -4, 59, -138, 26, -263, -2, -351, +-23, -374, -44, -321, -48, -189, -39, 7, +-32, 222, -17, 386, 13, 449, 49, 396, +82, 235, 118, 4, 146, -219, 151, -355, +122, -374, 66, -281, -9, -112, -101, 59, +-166, 172, -199, 194, -168, 127, -77, 5, +51, -103, 179, -150, 266, -113, 290, -7, +240, 126, 125, 236, -26, 278, -163, 222, +-238, 77, -232, -112, -147, -281, -5, -384, +154, -383, 269, -271, 313, -77, 253, 132, +112, 294, -72, 363, -240, 325, -330, 195, +-310, 25, -176, -128, 37, -211, 265, -202, +432, -119, 481, -14, 392, 64, 181, 78, +-86, 25, -320, -68, -442, -148, -431, -169, +-285, -104, -57, 23, 186, 165, 354, 267, +393, 286, 326, 197, 197, 30, 50, -150, +-80, -284, -150, -328, -149, -266, -105, -123, +-48, 49, 5, 193, 45, 274, 57, 275, +55, 200, 52, 76, 62, -58, 66, -169, +62, -243, 52, -268, 30, -235, 3, -154, +-21, -45, -22, 76, 5, 193, 50, 282, +99, 319, 124, 293, 106, 203, 50, 54, +-20, -126, -98, -295, -155, -412, -167, -448, +-101, -378, 19, -210, 154, 17, 268, 246, +322, 424, 293, 499, 175, 439, 6, 260, +-159, 21, -273, -206, -296, -357, -227, -391, +-83, -307, 80, -147, 211, 21, 271, 133, +260, 164, 181, 113, 68, 19, -43, -67, +-110, -98, -108, -62, -56, 26, 22, 126, +93, 190, 138, 181, 138, 108, 82, -2, +-6, -114, -98, -195, -156, -213, -166, -171, +-114, -95, -9, -21, 130, 39, 257, 72, +332, 83, 321, 83, 218, 85, 45, 86, +-153, 74, -298, 37, -341, -16, -275, -79, +-114, -131, 97, -148, 298, -109, 405, -26, +384, 73, 247, 150, 48, 170, -159, 111, +-307, -1, -349, -125, -267, -214, -94, -232, +110, -161, 295, -25, 403, 125, 394, 234, +278, 263, 100, 197, -81, 67, -229, -82, +-299, -195, -275, -239, -174, -202, -45, -104, +84, 12, 186, 98, 248, 132, 252, 119, +219, 76, 166, 17, 88, -29, -2, -51, +-87, -56, -148, -61, -183, -60, -182, -49, +-115, -23, 2, 17, 134, 68, 242, 108, +300, 118, 268, 80, 146, -4, -14, -110, +-151, -189, -230, -199, -229, -128, -131, -2, +29, 135, 181, 227, 259, 229, 248, 132, +162, -31, 27, -191, -95, -277, -153, -254, +-117, -121, -19, 72, 100, 244, 200, 315, +233, 257, 173, 87, 44, -129, -100, -306, +-208, -373, -237, -304, -184, -120, -60, 107, +100, 291, 239, 367, 319, 316, 310, 158, +228, -39, 99, -211, -26, -304, -119, -289, +-168, -177, -159, -25, -99, 115, -29, 197, +30, 203, 67, 132, 84, 14, 88, -110, +85, -193, 83, -211, 83, -156, 72, -49, +53, 80, 25, 191, 8, 251, 4, 235, +20, 153, 53, 32, 97, -93, 123, -192, +104, -239, 28, -230, -79, -175, -175, -110, +-222, -47, -199, 10, -94, 63, 86, 113, +284, 167, 413, 217, 436, 240, 334, 209, +137, 116, -105, -28, -305, -185, -397, -307, +-354, -345, -197, -287, 29, -151, 250, 18, +388, 169, 397, 242, 293, 216, 121, 120, +-68, 13, -219, -67, -288, -89, -264, -50, +-153, 20, -8, 72, 135, 68, 243, 5, +301, -83, 308, -157, 268, -177, 190, -126, +85, -15, -35, 112, -152, 200, -243, 211, +-294, 143, -295, 17, -228, -123, -96, -225, +75, -254, 243, -199, 381, -78, 457, 59, +462, 168, 381, 221, 224, 207, 16, 130, +-205, 15, -388, -100, -484, -177, -474, -191, +-354, -134, -140, -32, 130, 80, 385, 160, +553, 172, 586, 102, 487, -30, 275, -177, +13, -272, -230, -276, -376, -180, -397, -5, +-309, 197, -147, 343, 36, 375, 176, 283, +245, 100, 249, -113, 212, -277, 150, -340, +91, -287, 46, -150, 18, 11, -9, 125, +-38, 156, -76, 102, -108, 6, -122, -75, +-97, -96, -29, -42, 71, 68, 182, 183, +270, 250, 299, 224, 249, 103, 128, -84, +-29, -277, -178, -415, -266, -440, -259, -335, +-157, -122, 4, 137, 183, 372, 317, 509, +352, 509, 266, 369, 96, 121, -86, -166, +-219, -407, -257, -534, -186, -508, -36, -349, +133, -106, 258, 141, 305, 325, 260, 394, +146, 343, 19, 206, -69, 42, -112, -103, +-109, -183, -88, -190, -63, -144, -48, -86, +-39, -35, -13, -7, 43, 4, 125, 9, +218, 27, 291, 55, 308, 81, 239, 86, +103, 58, -60, -5, -206, -86, -296, -153, +-293, -176, -197, -147, -41, -62, 115, 56, +241, 167, 308, 234, 291, 242, 204, 186, +85, 80, -26, -56, -107, -187, -145, -278, +-124, -308, -57, -281, 34, -198, 113, -74, +162, 69, 171, 207, 144, 310, 96, 349, +45, 313, -3, 207, -35, 52, -54, -122, +-75, -277, -99, -372, -114, -382, -95, -312, +-29, -179, 72, -10, 204, 161, 326, 287, +392, 344, 366, 323, 250, 241, 64, 118, +-149, -25, -325, -159, -398, -256, -354, -300, +-221, -288, -47, -232, 122, -142, 243, -26, +288, 95, 266, 192, 217, 252, 168, 270, +138, 250, 116, 183, 96, 77, 63, -50, +7, -172, -72, -266, -158, -312, -227, -301, +-248, -227, -210, -105, -115, 40, 23, 166, +170, 250, 287, 272, 344, 230, 334, 141, +268, 33, 159, -58, 44, -109, -51, -124, +-104, -112, -116, -89, -103, -74, -88, -83, +-82, -106, -77, -120, -61, -95, -32, -20, +19, 91, 102, 200, 195, 271, 257, 263, +260, 160, 197, -9, 89, -182, -36, -299, +-120, -310, -132, -204, -76, -12, 9, 189, +88, 313, 128, 302, 101, 155, 6, -81, +-98, -313, -150, -445, -121, -419, -15, -234, +127, 61, 250, 361, 306, 554, 264, 567, +141, 399, -26, 103, -167, -226, -227, -485, +-178, -590, -47, -519, 112, -304, 239, -30, +286, 220, 225, 381, 78, 418, -94, 327, +-226, 158, -267, -28, -193, -176, -28, -246, +163, -230, 311, -158, 377, -54, 329, 45, +182, 105, -14, 114, -189, 90, -275, 48, +-250, 4, -123, -28, 54, -43, 207, -46, +279, -43, 246, -49, 135, -67, -9, -85, +-133, -79, -187, -42, -146, 22, -40, 94, +87, 155, 178, 181, 210, 155, 185, 71, +124, -36, 59, -125, 11, -173, -4, -169, +9, -115, 14, -38, -11, 25, -70, 43, +-135, 18, -173, -36, -152, -83, -56, -90, +112, -37, 296, 64, 437, 189, 474, 286, +389, 311, 187, 230, -89, 53, -347, -176, +-508, -387, -525, -518, -390, -518, -129, -369, +191, -98, 472, 219, 624, 490, 599, 632, +415, 598, 128, 389, -175, 65, -403, -277, +-484, -530, -400, -622, -182, -525, 79, -280, +292, 23, 402, 280, 380, 412, 239, 385, +41, 234, -134, 33, -216, -129, -196, -196, +-93, -147, 51, -17, 182, 124, 234, 197, +197, 154, 104, -2, 5, -208, -80, -379, +-123, -434, -107, -337, -50, -104, 22, 193, +84, 450, 121, 571, 137, 505, 135, 274, +127, -46, 113, -354, 87, -546, 44, -556, +-5, -383, -65, -100, -122, 192, -154, 392, +-140, 445, -84, 340, 4, 127, 119, -108, +232, -275, 310, -324, 322, -252, 269, -105, +165, 53, 16, 158, -151, 179, -289, 118, +-349, 13, -319, -76, -208, -106, -32, -73, +178, 5, 357, 92, 454, 145, 440, 132, +322, 51, 132, -69, -79, -177, -248, -241, +-320, -239, -290, -169, -178, -42, -28, 103, +122, 219, 223, 273, 244, 258, 187, 178, +92, 52, -2, -89, -67, -200, -91, -253, +-60, -235, 9, -161, 87, -55, 150, 50, +179, 133, 164, 166, 115, 143, 47, 80, +-20, 13, -87, -38, -139, -60, -163, -58, +-150, -41, -107, -30, -38, -32, 54, -57, +173, -93, 290, -111, 373, -88, 396, -23, +332, 76, 177, 172, -32, 232, -247, 226, +-419, 140, -495, -6, -430, -158, -236, -271, +33, -309, 296, -254, 481, -119, 541, 49, +466, 189, 283, 252, 63, 227, -133, 125, +-254, -12, -279, -131, -222, -189, -125, -170, +-37, -83, 19, 30, 56, 120, 74, 154, +99, 129, 138, 55, 195, -38, 244, -118, +249, -149, 182, -124, 50, -64, -114, -2, +-256, 44, -332, 59, -307, 41, -184, 1, +12, -36, 224, -52, 392, -34, 464, 2, +422, 50, 262, 93, 32, 116, -196, 104, +-362, 58, -425, -13, -365, -83, -191, -136, +52, -161, 288, -153, 447, -108, 485, -40, +388, 31, 180, 77, -81, 95, -316, 85, +-443, 54, -418, 19, -242, -2, 27, -2, +308, 24, 513, 59, 577, 81, 469, 71, +216, 27, -104, -49, -391, -141, -565, -228, +-572, -270, -406, -243, -117, -145, 200, 2, +459, 171, 602, 311, 600, 377, 447, 340, +207, 207, -39, 14, -228, -176, -337, -313, +-360, -356, -307, -296, -209, -153, -103, 8, +-3, 132, 87, 180, 167, 151, 238, 71, +296, -13, 322, -65, 303, -60, 224, -3, +92, 68, -66, 105, -200, 92, -278, 36, +-272, -36, -197, -94, -77, -114, 51, -99, +143, -61, 166, -36, 139, -43, 100, -80, +76, -108, 77, -96, 111, -16, 151, 124, +159, 279, 107, 378, 3, 363, -128, 209, +-232, -46, -267, -318, -206, -509, -57, -548, +131, -419, 296, -159, 378, 143, 341, 375, +201, 462, 1, 394, -190, 217, -306, 3, +-309, -160, -205, -223, -35, -184, 140, -88, +270, 8, 320, 50, 279, 28, 159, -39, +17, -109, -91, -139, -146, -102, -139, -7, +-80, 116, -1, 209, 62, 228, 81, 161, +61, 36, 17, -110, -27, -226, -48, -270, +-26, -218, 27, -93, 90, 60, 137, 187, +158, 256, 143, 238, 98, 148, 39, 16, +-15, -116, -42, -209, -45, -230, -40, -185, +-36, -99, -48, -1, -70, 78, -86, 114, +-78, 105, -37, 63, 43, 20, 145, -7, +242, -7, 301, 19, 299, 53, 227, 72, +96, 57, -56, -2, -191, -87, -283, -163, +-309, -198, -265, -176, -156, -97, -15, 14, +133, 128, 250, 199, 318, 204, 322, 144, +263, 49, 151, -49, 13, -113, -119, -130, +-204, -103, -230, -53, -197, 0, -110, 28, +10, 29, 128, 20, 215, 19, 249, 27, +220, 46, 126, 54, 2, 33, -123, -26, +-216, -111, -255, -191, -215, -214, -93, -159, +86, -25, 256, 154, 371, 318, 397, 398, +317, 355, 145, 188, -72, -49, -271, -282, +-388, -434, -396, -463, -284, -362, -94, -168, +118, 57, 285, 237, 369, 333, 352, 329, +255, 248, 114, 127, -32, 8, -148, -83, +-203, -129, -197, -135, -148, -111, -71, -84, +26, -62, 123, -47, 192, -37, 209, -32, +179, -16, 106, 13, 7, 52, -98, 89, +-179, 111, -206, 102, -167, 61, -72, -10, +61, -85, 189, -135, 274, -132, 294, -74, +241, 25, 125, 120, -17, 169, -147, 143, +-231, 46, -256, -95, -209, -215, -109, -259, +14, -199, 127, -53, 209, 129, 243, 272, +221, 317, 151, 236, 67, 57, -3, -156, +-51, -316, -77, -367, -78, -286, -66, -103, +-60, 118, -62, 289, -51, 361, -23, 311, +27, 166, 96, -24, 169, -188, 217, -284, +215, -296, 157, -234, 53, -121, -74, -3, +-188, 89, -253, 136, -238, 145, -146, 121, +0, 83, 154, 46, 270, 30, 307, 31, +263, 42, 152, 41, 12, 18, -123, -40, +-209, -124, -225, -217, -173, -275, -82, -265, +25, -174, 120, -19, 173, 171, 173, 339, +137, 433, 79, 414, 25, 283, -16, 69, +-33, -161, -39, -351, -39, -444, -44, -425, +-49, -301, -45, -122, -24, 63, 20, 205, +78, 281, 139, 285, 178, 234, 169, 152, +104, 63, -2, -20, -115, -87, -201, -139, +-224, -168, -168, -173, -41, -151, 116, -105, +253, -35, 318, 39, 288, 98, 168, 122, +-3, 109, -168, 66, -275, 16, -293, -29, +-218, -41, -73, -24, 99, 8, 238, 33, +303, 38, 273, 10, 169, -37, 24, -85, +-105, -101, -177, -77, -176, -13, -117, 58, +-27, 107, 60, 101, 110, 38, 113, -64, +80, -157, 32, -200, -7, -157, -28, -36, +-21, 130, 3, 274, 36, 343, 58, 295, +57, 146, 33, -65, 0, -261, -31, -382, +-44, -381, -44, -264, -36, -69, -18, 129, +4, 269, 27, 306, 57, 239, 85, 96, +107, -60, 111, -176, 91, -204, 45, -145, +-11, -23, -73, 105, -123, 196, -147, 202, +-130, 124, -78, -12, -5, -150, 77, -241, +152, -244, 202, -161, 202, -18, 153, 123, +77, 210, -13, 206, -101, 119, -167, -13, +-186, -126, -159, -174, -94, -133, -8, -27, +82, 107, 150, 203, 181, 215, 169, 130, +126, -9, 61, -158, -8, -255, -58, -269, +-82, -189, -85, -53, -76, 92, -64, 190, +-42, 218, -11, 172, 32, 79, 75, -25, +110, -98, 125, -127, 120, -103, 88, -50, +33, 17, -39, 65, -103, 83, -142, 59, +-142, 12, -100, -45, -20, -86, 75, -100, +157, -68, 195, -9, 191, 60, 137, 110, +40, 128, -75, 88, -164, 1, -209, -105, +-194, -183, -117, -206, 1, -149, 125, -31, +218, 118, 248, 243, 212, 302, 125, 267, +9, 156, -104, -8, -178, -176, -204, -306, +-176, -359, -110, -329, -28, -222, 51, -72, +125, 91, 177, 234, 202, 335, 199, 367, +162, 335, 82, 233, -28, 83, -144, -100, +-236, -275, -273, -403, -242, -442, -142, -377, +14, -216, 176, -2, 297, 218, 337, 378, +288, 440, 159, 379, -9, 224, -171, 21, +-275, -168, -287, -297, -222, -319, -106, -245, +37, -107, 161, 34, 235, 130, 247, 146, +199, 97, 106, 5, 1, -78, -93, -119, +-145, -91, -151, -8, -128, 102, -86, 183, +-26, 203, 33, 150, 74, 47, 98, -85, +104, -193, 93, -246, 72, -222, 46, -141, +24, -30, 5, 72, -20, 153, -51, 186, +-70, 172, -77, 115, -66, 49, -41, -14, +-11, -63, 18, -99, 44, -109, 61, -101, +67, -75, 62, -50, 53, -20, 40, 9, +26, 42, 13, 68, 6, 95, 1, 115, +-14, 125, -42, 97, -57, 32, -61, -70, +-55, -173, -37, -246, -7, -247, 28, -171, +59, -23, 76, 147, 78, 292, 66, 341, +43, 275, 13, 107, -6, -94, -18, -268, +-25, -343, -26, -295, -19, -136, -11, 57, +1, 214, 3, 271, -1, 225, -6, 98, +-9, -49, -4, -163, 10, -190, 20, -138, +24, -36, 22, 54, 11, 103, -3, 85, +-1, 22, 12, -54, 26, -88, 39, -65, +54, 13, 57, 105, 46, 172, 14, 174, +-35, 108, -79, -22, -107, -163, -112, -272, +-82, -301, -32, -238, 14, -96, 48, 73, +72, 226, 94, 306, 126, 303, 152, 216, +159, 81, 140, -59, 81, -159, -24, -208, +-146, -198, -262, -147, -338, -76, -332, -18, +-233, 18, -59, 31, 156, 43, 342, 65, +440, 102, 421, 133, 293, 148, 93, 117, +-115, 48, -278, -59, -352, -164, -322, -236, +-223, -230, -100, -150, 23, -18, 118, 119, +161, 224, 167, 251, 154, 195, 127, 73, +97, -65, 60, -178, 17, -225, -30, -204, +-84, -114, -139, 1, -163, 104, -146, 157, +-94, 160, -10, 116, 91, 51, 169, -19, +200, -69, 167, -91, 80, -77, -29, -52, +-126, -27, -183, -20, -174, -16, -107, -12, +-5, -1, 109, 14, 195, 46, 204, 81, +142, 108, 26, 100, -106, 58, -199, -15, +-218, -88, -170, -149, -68, -165, 49, -135, +147, -55, 203, 42, 198, 130, 138, 170, +58, 161, -31, 103, -108, 17, -148, -81, +-140, -145, -105, -164, -57, -128, -9, -62, +34, 17, 71, 81, 96, 120, 96, 115, +88, 78, 71, 21, 40, -28, 10, -66, +-14, -79, -45, -72, -79, -41, -112, -11, +-136, 10, -135, 15, -91, 20, -6, 22, +112, 39, 226, 59, 284, 84, 256, 89, +137, 60, -51, -18, -245, -115, -374, -204, +-394, -237, -277, -199, -47, -80, 208, 89, +406, 260, 482, 357, 403, 342, 190, 203, +-80, -8, -327, -226, -461, -368, -446, -395, +-300, -292, -71, -102, 162, 111, 315, 259, +362, 308, 308, 248, 179, 125, 22, -16, +-111, -114, -192, -146, -197, -107, -144, -42, +-65, 17, 5, 33, 45, 13, 35, -31, +-3, -63, -36, -68, -48, -32, -25, 28, +38, 89, 104, 102, 155, 68, 170, -3, +128, -68, 41, -108, -62, -90, -158, -19, +-199, 85, -177, 168, -121, 192, -45, 127, +34, -3, 72, -158, 72, -279, 57, -320, +47, -246, 55, -84, 76, 121, 89, 288, +95, 370, 77, 333, 19, 204, -55, 21, +-120, -143, -167, -248, -177, -266, -144, -218, +-86, -139, -20, -67, 46, -9, 95, 26, +132, 55, 155, 89, 156, 145, 135, 205, +99, 242, 37, 210, -34, 109, -99, -48, +-159, -209, -202, -332, -199, -372, -154, -314, +-80, -161, 9, 27, 98, 197, 174, 307, +218, 345, 215, 296, 171, 184, 90, 39, +-30, -98, -156, -205, -239, -260, -259, -269, +-201, -222, -76, -126, 72, 8, 189, 139, +244, 247, 209, 296, 107, 276, -30, 173, +-161, 18, -240, -150, -233, -273, -153, -333, +-24, -304, 112, -196, 203, -27, 229, 150, +197, 296, 115, 360, 13, 338, -83, 231, +-162, 74, -212, -105, -214, -254, -174, -334, +-91, -325, 33, -252, 157, -125, 239, 15, +267, 135, 215, 200, 84, 214, -73, 176, +-210, 123, -285, 67, -262, 23, -150, -10, +21, -32, 187, -52, 281, -74, 271, -109, +177, -136, 7, -146, -170, -125, -276, -83, +-278, -16, -185, 62, -18, 143, 155, 196, +263, 211, 274, 170, 179, 90, 14, -25, +-150, -145, -270, -240, -294, -259, -201, -194, +-31, -53, 155, 114, 303, 260, 342, 321, +250, 270, 68, 103, -141, -115, -303, -313, +-358, -407, -299, -364, -150, -187, 37, 61, +184, 300, 247, 436, 237, 425, 156, 268, +36, 41, -55, -186, -81, -330, -58, -354, +-4, -255, 36, -85, 29, 95, -31, 206, +-126, 226, -207, 153, -213, 33, -147, -90, +-30, -162, 122, -164, 254, -89, 300, 20, +264, 113, 156, 150, 5, 131, -137, 59, +-228, -27, -252, -91, -197, -92, -103, -35, +-3, 53, 83, 117, 125, 124, 108, 51, +59, -78, 2, -229, -39, -325, -41, -315, +-5, -174, 44, 51, 91, 297, 100, 469, +56, 507, -23, 379, -115, 125, -191, -176, +-197, -413, -130, -512, -9, -438, 134, -235, +245, 25, 262, 245, 174, 358, 7, 323, +-174, 169, -295, -32, -309, -190, -210, -258, +-16, -208, 191, -67, 326, 116, 353, 258, +256, 304, 58, 226, -158, 65, -320, -129, +-371, -285, -285, -353, -102, -298, 99, -147, +251, 53, 298, 220, 230, 306, 82, 281, +-85, 166, -215, 0, -246, -148, -176, -228, +-45, -203, 107, -97, 228, 47, 251, 162, +175, 212, 34, 171, -125, 57, -238, -92, +-264, -213, -201, -262, -69, -214, 66, -95, +147, 64, 163, 205, 118, 285, 25, 271, +-56, 174, -76, 23, -32, -126, 54, -233, +142, -263, 175, -214, 126, -93, -7, 49, +-179, 164, -314, 210, -363, 186, -309, 96, +-139, -17, 95, -117, 299, -162, 412, -145, +414, -76, 294, 9, 96, 88, -116, 126, +-276, 123, -344, 79, -319, 25, -221, -29, +-68, -58, 84, -69, 178, -63, 206, -60, +173, -54, 76, -52, -35, -39, -112, -20, +-133, 15, -93, 55, -4, 97, 92, 121, +167, 122, 184, 91, 119, 46, -4, -9, +-144, -62, -265, -109, -302, -134, -228, -139, +-76, -119, 102, -81, 246, -22, 298, 40, +252, 94, 130, 118, -25, 114, -146, 86, +-194, 57, -173, 27, -86, 10, 24, 3, +94, 3, 102, -13, 55, -51, -34, -107, +-115, -151, -144, -170, -108, -139, -23, -59, +86, 56, 173, 158, 215, 216, 189, 210, +96, 150, -31, 56, -147, -32, -234, -94, +-257, -113, -206, -105, -109, -83, 4, -73, +115, -74, 184, -78, 203, -58, 183, -9, +128, 76, 57, 169, -5, 240, -68, 248, +-118, 180, -157, 37, -194, -131, -212, -276, +-180, -345, -101, -317, 20, -194, 168, -18, +293, 160, 354, 280, 327, 318, 197, 269, +0, 160, -215, 25, -392, -92, -461, -173, +-386, -194, -207, -162, 27, -98, 257, -30, +403, 23, 418, 46, 318, 41, 139, 10, +-59, -24, -224, -47, -321, -38, -316, 3, +-217, 72, -79, 146, 63, 199, 177, 199, +217, 134, 169, 2, 76, -161, -29, -309, +-109, -387, -134, -358, -98, -209, -11, 24, +95, 280, 156, 468, 147, 522, 70, 408, +-69, 161, -220, -152, -302, -423, -285, -563, +-164, -517, 35, -305, 250, 3, 397, 299, +424, 493, 310, 516, 98, 378, -148, 136, +-362, -118, -472, -305, -432, -377, -276, -339, +-61, -217, 162, -66, 324, 68, 377, 153, +331, 187, 207, 180, 50, 153, -96, 114, +-194, 64, -224, -4, -186, -73, -126, -135, +-67, -169, -19, -162, 4, -105, 2, -15, +5, 82, 21, 145, 50, 161, 95, 120, +142, 45, 165, -40, 148, -100, 75, -118, +-38, -90, -159, -31, -251, 30, -278, 64, +-215, 65, -98, 33, 41, -9, 165, -47, +237, -55, 229, -32, 164, 16, 69, 59, +-35, 87, -115, 78, -150, 33, -144, -38, +-102, -108, -60, -149, -24, -134, 11, -66, +37, 39, 57, 137, 90, 200, 114, 198, +105, 128, 67, 3, 11, -131, -65, -227, +-139, -247, -191, -195, -195, -84, -140, 46, +-47, 158, 63, 214, 173, 211, 235, 161, +226, 90, 164, 16, 62, -43, -65, -88, +-173, -120, -230, -144, -225, -158, -160, -160, +-60, -128, 38, -62, 113, 33, 135, 133, +103, 216, 55, 250, 11, 229, -29, 151, +-36, 38, -8, -82, 24, -170, 39, -211, +35, -201, 4, -151, -41, -70, -90, 13, +-119, 83, -105, 116, -61, 113, -15, 85, +23, 44, 50, 0, 60, -29, 64, -36, +73, -18, 74, 10, 70, 37, 43, 46, +-4, 34, -58, -1, -111, -43, -155, -78, +-158, -92, -110, -77, -34, -32, 54, 19, +127, 64, 150, 88, 125, 84, 63, 55, +-14, 17, -69, -22, -82, -45, -67, -47, +-29, -29, 5, -6, 16, 17, 3, 24, +-21, 7, -50, -30, -58, -66, -31, -87, +19, -76, 74, -29, 112, 51, 107, 137, +62, 199, -12, 205, -95, 149, -151, 36, +-161, -100, -129, -224, -55, -295, 36, -291, +105, -208, 137, -72, 122, 79, 65, 203, +3, 279, -44, 300, -62, 268, -46, 188, +-10, 88, 14, -21, 16, -136, -11, -247, +-65, -329, -122, -357, -146, -315, -131, -203, +-55, -26, 61, 178, 171, 359, 238, 458, +242, 448, 171, 323, 56, 119, -69, -110, +-172, -297, -225, -401, -225, -397, -189, -299, +-123, -143, -49, 22, 16, 151, 68, 220, +119, 237, 154, 209, 181, 156, 189, 97, +162, 42, 92, -16, -19, -75, -148, -135, +-249, -179, -296, -195, -276, -171, -188, -101, +-51, 7, 84, 123, 191, 209, 247, 230, +240, 181, 171, 72, 74, -55, -24, -154, +-97, -185, -131, -134, -131, -20, -104, 105, +-63, 186, -39, 183, -27, 89, -20, -71, +-21, -232, -22, -333, 0, -320, 36, -184, +76, 40, 106, 275, 113, 447, 89, 493, +39, 390, -28, 165, -88, -114, -123, -356, +-132, -491, -109, -487, -53, -348, 3, -123, +43, 118, 54, 298, 35, 368, 1, 322, +-24, 191, -27, 28, 6, -105, 59, -166, +110, -139, 129, -47, 107, 57, 36, 114, +-71, 99, -185, 9, -268, -117, -286, -224, +-211, -259, -66, -195, 112, -43, 273, 139, +362, 286, 346, 342, 236, 286, 57, 140, +-135, -40, -292, -190, -373, -255, -360, -229, +-250, -137, -89, -31, 78, 41, 216, 53, +291, 23, 287, -13, 230, -15, 135, 34, +26, 128, -81, 219, -175, 255, -243, 193, +-266, 34, -244, -173, -175, -357, -66, -449, +68, -396, 193, -204, 286, 68, 314, 328, +259, 488, 132, 494, -37, 349, -204, 98, +-309, -173, -334, -369, -267, -429, -128, -350, +36, -171, 175, 39, 256, 206, 251, 278, +172, 245, 49, 132, -74, 1, -157, -101, +-175, -141, -140, -113, -74, -40, 2, 34, +61, 78, 80, 74, 64, 29, 23, -38, +-21, -94, -45, -113, -40, -84, -12, -16, +29, 71, 55, 148, 52, 190, 19, 176, +-29, 108, -78, 3, -113, -113, -123, -216, +-99, -272, -40, -259, 45, -174, 123, -34, +176, 126, 181, 258, 132, 327, 37, 304, +-74, 195, -172, 35, -222, -122, -220, -229, +-161, -252, -55, -196, 64, -87, 159, 25, +204, 92, 186, 93, 109, 39, 2, -33, +-87, -82, -139, -75, -139, -7, -96, 94, +-29, 185, 39, 216, 82, 170, 80, 59, +47, -80, -9, -199, -68, -260, -97, -245, +-88, -157, -54, -24, -7, 104, 39, 185, +81, 207, 99, 174, 92, 108, 58, 29, +14, -44, -34, -96, -82, -120, -118, -125, +-126, -119, -112, -97, -74, -53, -17, 6, +48, 74, 109, 141, 148, 191, 148, 200, +113, 156, 42, 66, -43, -52, -119, -171, +-167, -255, -182, -278, -155, -226, -89, -116, +3, 28, 92, 164, 161, 253, 187, 269, +163, 217, 95, 115, 7, -5, -73, -110, +-134, -167, -169, -169, -165, -127, -128, -61, +-64, 8, 8, 58, 74, 80, 115, 71, +121, 42, 98, 5, 59, -32, 14, -62, +-26, -73, -65, -58, -86, -19, -83, 34, +-57, 90, -12, 130, 34, 142, 53, 114, +48, 41, 20, -59, -17, -155, -55, -215, +-77, -215, -78, -153, -53, -43, -15, 85, +31, 188, 75, 230, 105, 208, 98, 135, +64, 37, 20, -58, -30, -126, -77, -159, +-105, -154, -116, -124, -103, -81, -76, -34, +-29, 18, 31, 72, 83, 131, 108, 184, +102, 210, 66, 188, 5, 103, -66, -35, +-115, -191, -129, -312, -100, -354, -28, -293, +65, -134, 137, 83, 161, 295, 125, 425, +50, 430, -52, 303, -155, 83, -223, -156, +-235, -344, -185, -427, -79, -376, 49, -215, +175, -10, 258, 175, 272, 289, 221, 309, +124, 242, -6, 122, -138, -7, -242, -111, +-287, -161, -276, -159, -194, -125, -60, -74, +81, -19, 187, 22, 235, 49, 212, 61, +141, 59, 40, 47, -54, 30, -116, 12, +-134, -1, -111, -3, -56, 9, 0, 26, +32, 36, 17, 28, -23, -1, -67, -54, +-87, -112, -67, -146, -6, -134, 79, -69, +149, 38, 170, 154, 142, 238, 60, 255, +-56, 188, -170, 47, -236, -120, -229, -261, +-154, -325, -34, -287, 99, -152, 198, 37, +234, 220, 193, 336, 94, 347, -30, 244, +-143, 63, -210, -134, -212, -281, -155, -334, +-61, -274, 32, -125, 106, 55, 148, 205, +147, 281, 113, 260, 62, 151, -6, -3, +-72, -145, -129, -226, -150, -222, -142, -142, +-106, -16, -42, 108, 36, 196, 100, 216, +141, 169, 147, 68, 111, -44, 26, -138, +-80, -191, -154, -192, -174, -143, -137, -65, +-51, 21, 50, 93, 136, 141, 164, 160, +133, 154, 58, 126, -40, 81, -134, 20, +-195, -48, -197, -121, -129, -189, -29, -231, +80, -228, 171, -169, 213, -51, 197, 102, +136, 253, 45, 353, -55, 366, -161, 273, +-233, 89, -251, -138, -212, -336, -122, -442, +5, -417, 135, -267, 233, -35, 264, 198, +229, 365, 129, 412, -11, 332, -151, 161, +-245, -34, -257, -193, -197, -265, -91, -244, +48, -156, 167, -47, 223, 42, 200, 83, +114, 79, -6, 43, -135, 8, -229, -6, +-240, 12, -179, 51, -71, 89, 51, 100, +165, 77, 234, 26, 229, -38, 164, -101, +69, -141, -53, -145, -167, -118, -237, -64, +-239, 4, -188, 75, -109, 133, -13, 162, +85, 157, 148, 117, 175, 52, 174, -30, +147, -104, 73, -149, -29, -154, -112, -120, +-159, -57, -174, 11, -146, 68, -86, 102, +-10, 108, 42, 90, 72, 57, 95, 21, +93, -5, 54, -22, 14, -36, -10, -45, +-15, -51, -22, -57, -28, -55, -37, -40, +-62, -13, -100, 21, -114, 53, -88, 72, +-30, 77, 35, 66, 113, 40, 176, 12, +181, -8, 125, -19, 40, -29, -60, -43, +-150, -61, -208, -79, -198, -84, -137, -72, +-54, -32, 28, 33, 100, 108, 137, 162, +122, 173, 67, 128, 14, 40, -35, -70, +-65, -164, -57, -204, -17, -168, 27, -70, +50, 52, 47, 151, 32, 188, -15, 148, +-83, 42, -135, -87, -145, -182, -113, -198, +-48, -126, 38, 10, 117, 150, 142, 230, +117, 218, 61, 112, 4, -41, -38, -181, +-49, -245, -21, -204, 18, -68, 27, 99, +11, 224, -32, 249, -99, 156, -167, -22, +-199, -204, -158, -309, -43, -290, 103, -142, +238, 85, 310, 295, 286, 403, 155, 363, +-34, 185, -203, -71, -310, -310, -330, -439, +-240, -411, -76, -238, 112, 15, 245, 253, +285, 395, 231, 392, 94, 254, -79, 40, +-209, -166, -260, -293, -213, -310, -100, -224, +39, -71, 153, 81, 196, 182, 160, 200, +71, 150, -32, 59, -105, -29, -131, -82, +-98, -86, -28, -50, 31, -4, 62, 30, +55, 41, 6, 26, -58, -3, -118, -30, +-129, -40, -86, -36, -9, -19, 82, 1, +157, 18, 181, 27, 139, 31, 50, 31, +-32, 31, -105, 29, -161, 22, -182, 1, +-161, -25, -105, -55, -32, -79, 48, -83, +136, -55, 187, 0, 183, 68, 137, 126, +69, 152, -21, 133, -128, 67, -215, -36, +-242, -144, -216, -225, -131, -245, 0, -194, +143, -79, 244, 75, 264, 227, 219, 328, +130, 344, -5, 265, -139, 107, -233, -95, +-270, -281, -252, -399, -177, -411, -42, -310, +107, -121, 209, 108, 252, 312, 238, 428, +166, 422, 35, 294, -108, 86, -209, -141, +-260, -318, -253, -399, -163, -356, -21, -206, +127, -1, 228, 190, 265, 309, 236, 325, +124, 242, -42, 92, -191, -70, -287, -187, +-307, -231, -247, -203, -105, -124, 66, -30, +201, 47, 276, 86, 284, 91, 217, 74, +94, 65, -55, 71, -167, 88, -222, 93, +-226, 70, -175, 5, -87, -88, -16, -185, +23, -244, 43, -237, 66, -147, 78, 2, +80, 163, 87, 280, 96, 310, 89, 243, +63, 103, 20, -58, -30, -185, -103, -241, +-178, -208, -216, -113, -205, -2, -145, 82, +-51, 110, 50, 83, 141, 24, 189, -33, +198, -54, 175, -36, 119, 18, 39, 82, +-45, 129, -107, 131, -133, 84, -140, 7, +-123, -77, -100, -149, -91, -179, -91, -161, +-84, -104, -54, -29, 10, 46, 89, 107, +183, 141, 262, 142, 289, 121, 245, 82, +133, 40, -33, 3, -216, -25, -368, -47, +-429, -70, -389, -98, -251, -123, -57, -140, +140, -137, 297, -104, 369, -36, 340, 59, +240, 166, 99, 252, -26, 288, -111, 251, +-158, 144, -164, -13, -151, -178, -137, -306, +-126, -359, -112, -321, -77, -196, -35, -16, +26, 167, 109, 297, 191, 341, 239, 287, +218, 161, 121, 0, -18, -144, -164, -236, +-255, -249, -254, -186, -174, -74, -41, 44, +100, 133, 193, 173, 208, 156, 132, 88, +7, -1, -134, -83, -240, -136, -256, -147, +-168, -109, -4, -35, 165, 57, 264, 143, +281, 198, 200, 197, 43, 137, -124, 27, +-244, -107, -280, -231, -232, -301, -118, -288, +41, -185, 176, -15, 235, 174, 208, 320, +111, 374, -21, 312, -147, 156, -218, -38, +-205, -204, -134, -292, -20, -274, 95, -166, +165, -18, 172, 103, 117, 149, 32, 109, +-47, 14, -114, -87, -126, -140, -84, -110, +-25, 1, 18, 144, 38, 257, 38, 284, +4, 212, -56, 63, -93, -113, -85, -253, +-35, -308, 34, -269, 98, -160, 139, -29, +128, 74, 64, 125, -12, 127, -84, 95, +-128, 64, -139, 54, -105, 75, -41, 108, +23, 125, 71, 98, 86, 22, 54, -86, +-4, -189, -63, -250, -84, -244, -60, -172, +-13, -51, 46, 80, 93, 179, 96, 220, +66, 202, 11, 135, -51, 48, -112, -24, +-155, -63, -147, -73, -86, -60, 2, -42, +92, -28, 152, -25, 165, -30, 120, -37, +36, -33, -58, -15, -143, 9, -192, 30, +-187, 49, -138, 58, -40, 58, 75, 52, +170, 49, 220, 40, 205, 20, 129, -10, +10, -48, -124, -94, -222, -131, -255, -139, +-206, -111, -99, -43, 32, 53, 155, 145, +225, 212, 206, 227, 121, 182, -3, 80, +-117, -48, -193, -169, -202, -247, -130, -264, +-14, -212, 94, -112, 167, 12, 170, 129, +105, 214, 2, 247, -89, 227, -141, 162, +-147, 64, -107, -43, -44, -130, 15, -190, +62, -209, 78, -182, 72, -114, 44, -24, +-4, 70, -30, 140, -20, 171, -3, 154, +9, 94, 7, 12, -4, -64, -31, -116, +-56, -120, -57, -80, -32, -14, -3, 51, +15, 97, 26, 100, 37, 65, 20, 5, +-11, -52, -29, -89, -35, -92, -26, -61, +3, -5, 38, 42, 67, 65, 53, 54, +7, 17, -48, -28, -106, -52, -139, -44, +-116, -5, -40, 47, 55, 94, 130, 114, +181, 94, 172, 35, 91, -43, -26, -119, +-135, -166, -209, -168, -230, -124, -190, -50, +-80, 38, 50, 117, 152, 170, 212, 188, +215, 168, 154, 113, 50, 34, -57, -57, +-125, -141, -160, -201, -156, -217, -118, -181, +-66, -93, -12, 24, 27, 143, 47, 233, +53, 261, 34, 211, 24, 98, 34, -47, +55, -182, 83, -267, 96, -266, 71, -183, +8, -46, -84, 103, -162, 219, -205, 262, +-197, 222, -139, 112, -37, -29, 91, -154, +197, -223, 245, -217, 233, -143, 142, -27, +2, 88, -131, 160, -212, 172, -220, 129, +-168, 52, -80, -34, 20, -94, 91, -114, +127, -92, 123, -41, 86, 21, 32, 60, +-14, 69, -37, 46, -41, 10, -48, -30, +-45, -55, -48, -62, -63, -41, -75, -4, +-68, 40, -20, 75, 52, 90, 119, 78, +171, 44, 174, -9, 113, -67, 0, -115, +-127, -134, -227, -115, -269, -63, -227, 10, +-102, 87, 54, 142, 202, 159, 289, 128, +289, 62, 196, -19, 28, -88, -152, -134, +-270, -143, -307, -115, -242, -60, -89, -2, +87, 49, 212, 87, 250, 106, 211, 102, +108, 80, -36, 45, -157, 3, -220, -41, +-202, -78, -125, -98, -11, -92, 110, -65, +183, -24, 172, 17, 107, 50, 8, 62, +-79, 55, -130, 35, -131, 22, -84, 14, +-21, 19, 31, 33, 62, 38, 61, 18, +28, -23, -28, -78, -65, -122, -69, -138, +-36, -111, 36, -42, 114, 56, 144, 142, +118, 192, 39, 182, -62, 121, -156, 24, +-214, -76, -200, -145, -120, -161, -15, -128, +88, -65, 163, -6, 194, 32, 156, 43, +70, 35, -14, 19, -71, 16, -91, 40, +-70, 78, -24, 106, 28, 106, 35, 65, +-2, -15, -59, -115, -119, -202, -151, -238, +-126, -199, -55, -92, 50, 52, 147, 189, +213, 277, 226, 280, 173, 199, 74, 62, +-44, -90, -150, -208, -214, -252, -224, -216, +-166, -114, -75, 10, 13, 114, 82, 162, +112, 150, 96, 85, 62, -3, 27, -82, +2, -118, -14, -102, -16, -38, -4, 49, +11, 123, 22, 155, 19, 132, -7, 61, +-43, -35, -80, -129, -86, -185, -64, -187, +-34, -128, 4, -28, 42, 74, 66, 145, +76, 169, 68, 141, 48, 77, 3, -2, +-50, -68, -87, -100, -94, -91, -79, -59, +-38, -20, 24, 9, 81, 26, 104, 22, +104, 12, 85, 11, 33, 25, -38, 42, +-101, 52, -142, 38, -151, 1, -137, -56, +-86, -111, -3, -138, 76, -117, 138, -48, +185, 53, 197, 151, 160, 211, 74, 208, +-25, 139, -131, 18, -233, -110, -290, -203, +-269, -228, -170, -178, -24, -70, 132, 56, +274, 160, 338, 203, 292, 171, 164, 77, +-3, -39, -178, -137, -317, -182, -366, -161, +-293, -79, -134, 33, 65, 137, 252, 197, +372, 196, 362, 140, 220, 46, 12, -66, +-183, -156, -341, -203, -397, -193, -323, -138, +-150, -48, 56, 53, 242, 140, 365, 188, +381, 188, 258, 137, 60, 51, -136, -49, +-278, -131, -343, -176, -303, -161, -170, -90, +-11, 10, 118, 98, 210, 154, 242, 157, +204, 105, 110, 23, 3, -58, -71, -113, +-114, -120, -136, -87, -116, -37, -80, 2, +-59, 19, -55, 5, -35, -20, 3, -31, +46, -2, 100, 64, 161, 146, 192, 205, +164, 212, 73, 141, -43, -3, -165, -176, +-269, -319, -302, -380, -236, -330, -102, -182, +68, 29, 225, 234, 328, 374, 328, 405, +220, 323, 45, 160, -136, -28, -270, -190, +-318, -279, -271, -283, -141, -215, 10, -107, +131, 7, 203, 90, 216, 127, 167, 128, +73, 114, -35, 88, -102, 60, -123, 31, +-107, 7, -65, -21, -18, -57, 6, -99, +-1, -125, -22, -125, -30, -92, -23, -34, +8, 44, 55, 120, 101, 177, 125, 190, +113, 156, 65, 82, -6, -15, -102, -116, +-184, -190, -217, -222, -182, -199, -98, -122, +11, -9, 123, 102, 208, 190, 222, 232, +170, 213, 80, 130, -21, 12, -118, -109, +-180, -195, -182, -219, -130, -172, -55, -72, +29, 53, 97, 155, 127, 200, 100, 173, +38, 86, -17, -31, -53, -129, -72, -175, +-50, -157, 7, -86, 61, 9, 73, 84, +55, 117, 18, 100, -46, 49, -115, -9, +-140, -40, -111, -31, -41, 13, 40, 60, +126, 83, 182, 59, 162, -11, 78, -109, +-14, -185, -94, -203, -147, -140, -152, -16, +-95, 128, -16, 236, 36, 266, 60, 201, +70, 61, 51, -106, 6, -232, -34, -267, +-26, -202, 8, -65, 43, 101, 77, 230, +93, 273, 53, 210, -34, 68, -121, -100, +-167, -231, -169, -289, -119, -250, -20, -127, +89, 41, 158, 189, 174, 274, 144, 271, +76, 195, -29, 72, -119, -56, -148, -155, +-116, -196, -47, -178, 37, -117, 105, -43, +121, 22, 56, 60, -45, 65, -131, 44, +-176, 15, -164, -2, -79, 8, 61, 38, +200, 77, 271, 109, 266, 110, 188, 68, +38, -6, -149, -101, -291, -188, -341, -229, +-301, -205, -190, -123, -19, 2, 152, 131, +261, 228, 288, 255, 252, 211, 172, 114, +62, -3, -44, -107, -112, -168, -151, -170, +-173, -128, -174, -68, -147, -15, -107, 13, +-66, 21, -12, 22, 68, 32, 146, 59, +206, 100, 235, 129, 215, 124, 132, 70, +-3, -25, -140, -136, -229, -215, -262, -228, +-226, -158, -129, -26, -2, 131, 106, 246, +168, 270, 175, 189, 127, 35, 40, -137, +-43, -256, -93, -274, -82, -183, -22, -18, +50, 157, 100, 265, 106, 266, 54, 159, +-35, -12, -122, -181, -168, -275, -157, -261, +-94, -144, 0, 27, 101, 182, 166, 264, +165, 247, 105, 141, 21, -6, -72, -142, +-133, -214, -130, -206, -65, -129, 22, -21, +93, 72, 135, 116, 129, 112, 58, 70, +-44, 16, -127, -23, -165, -36, -160, -25, +-106, 1, -12, 23, 87, 36, 150, 29, +172, 8, 149, -20, 81, -46, -15, -68, +-97, -79, -129, -80, -114, -59, -73, -14, +-10, 50, 52, 114, 84, 160, 76, 163, +44, 115, 0, 19, -50, -98, -92, -199, +-96, -238, -58, -197, 3, -81, 61, 73, +107, 208, 126, 267, 101, 226, 38, 94, +-25, -79, -75, -228, -103, -293, -107, -249, +-76, -101, -22, 91, 26, 259, 56, 331, +72, 279, 63, 121, 22, -82, -29, -253, +-51, -333, -40, -297, -11, -155, 29, 39, +74, 206, 92, 284, 66, 255, 12, 136, +-43, -19, -99, -150, -143, -206, -136, -175, +-75, -75, 4, 43, 81, 130, 146, 146, +178, 92, 145, -1, 63, -91, -24, -140, +-96, -118, -148, -38, -155, 61, -114, 133, +-47, 150, 18, 98, 80, 1, 121, -98, +124, -156, 90, -150, 37, -77, -20, 25, +-63, 117, -87, 168, -81, 155, -51, 76, +-14, -34, 14, -134, 32, -184, 37, -167, +32, -93, 23, 6, 19, 104, 13, 171, +8, 182, 6, 134, 3, 48, -4, -45, +-16, -117, -44, -151, -66, -141, -64, -93, +-34, -23, 8, 41, 54, 83, 90, 93, +98, 78, 65, 47, 11, 13, -38, -10, +-72, -11, -89, 4, -74, 19, -31, 22, +19, 1, 58, -42, 77, -92, 65, -133, +27, -141, -26, -95, -66, -3, -76, 105, +-53, 197, -10, 244, 40, 225, 75, 133, +81, -4, 54, -144, 15, -244, -26, -275, +-62, -225, -76, -116, -62, 19, -28, 140, +12, 207, 38, 205, 49, 145, 40, 51, +11, -38, -26, -96, -40, -109, -21, -82, +20, -33, 59, 12, 90, 37, 90, 35, +47, 13, -22, -25, -83, -56, -126, -65, +-147, -45, -132, -6, -66, 37, 25, 69, +107, 85, 159, 81, 181, 57, 151, 15, +76, -26, -5, -63, -61, -85, -103, -86, +-131, -65, -128, -30, -93, 12, -59, 49, +-26, 70, 19, 66, 66, 42, 84, 6, +88, -26, 90, -44, 84, -34, 56, -2, +20, 36, -13, 60, -53, 60, -97, 26, +-114, -33, -94, -97, -51, -135, -3, -127, +49, -69, 87, 20, 93, 106, 73, 157, +39, 163, -8, 116, -50, 31, -74, -59, +-67, -121, -31, -138, 22, -114, 70, -62, +94, 2, 82, 52, 40, 72, -21, 63, +-74, 41, -102, 17, -101, 3, -79, -3, +-38, -7, 16, -15, 64, -25, 91, -35, +99, -36, 91, -24, 59, 6, 11, 45, +-31, 76, -58, 83, -73, 59, -77, 6, +-58, -57, -27, -110, 0, -127, 21, -96, +38, -26, 41, 49, 25, 101, 2, 115, +-12, 91, -16, 34, -3, -31, 27, -68, +60, -60, 77, -19, 65, 36, 27, 76, +-23, 73, -81, 24, -135, -56, -161, -137, +-147, -179, -91, -157, 0, -68, 107, 58, +202, 182, 249, 264, 229, 267, 150, 181, +33, 37, -102, -118, -214, -240, -270, -297, +-253, -268, -174, -167, -57, -24, 74, 114, +189, 211, 247, 245, 226, 218, 147, 140, +44, 35, -61, -70, -139, -147, -160, -181, +-118, -168, -54, -114, 6, -37, 59, 42, +89, 106, 69, 132, 16, 116, -39, 70, +-79, 12, -97, -47, -70, -84, 2, -86, +89, -57, 143, -13, 157, 29, 128, 49, +53, 44, -53, 21, -144, -8, -187, -32, +-181, -39, -134, -15, -43, 24, 67, 54, +155, 67, 185, 56, 170, 19, 116, -35, +26, -80, -66, -103, -120, -97, -133, -60, +-119, -5, -85, 49, -30, 90, 26, 109, +71, 98, 100, 63, 113, 19, 100, -22, +58, -54, -1, -79, -53, -92, -90, -90, +-105, -71, -98, -37, -60, 12, -2, 65, +54, 116, 92, 144, 109, 134, 94, 83, +39, -2, -33, -98, -86, -177, -109, -215, +-97, -191, -52, -101, 24, 30, 94, 159, +130, 252, 131, 278, 104, 224, 40, 97, +-48, -64, -123, -216, -159, -308, -162, -318, +-125, -243, -43, -103, 58, 64, 135, 209, +173, 293, 176, 297, 142, 223, 70, 100, +-16, -37, -91, -149, -141, -210, -167, -204, +-151, -140, -99, -48, -28, 40, 34, 97, +81, 110, 102, 80, 101, 19, 83, -42, +58, -69, 32, -60, 14, -25, 0, 27, +-16, 76, -33, 98, -49, 84, -72, 39, +-96, -16, -102, -63, -76, -86, -23, -82, +48, -51, 120, -8, 168, 27, 162, 35, +104, 22, 21, -3, -66, -21, -139, -19, +-164, 2, -127, 36, -55, 71, 18, 80, +82, 56, 118, 5, 101, -55, 37, -99, +-31, -107, -75, -74, -88, -9, -67, 66, +-6, 123, 67, 134, 103, 95, 92, 21, +55, -62, 0, -124, -61, -145, -100, -119, +-96, -52, -68, 24, -30, 77, 11, 96, +50, 84, 69, 52, 65, 18, 51, 1, +37, 9, 21, 29, 11, 41, 4, 31, +-4, -7, -26, -66, -60, -123, -87, -156, +-87, -147, -64, -91, -18, -2, 42, 91, +100, 158, 129, 184, 112, 168, 64, 115, +7, 42, -56, -27, -112, -76, -132, -101, +-103, -104, -52, -92, 4, -73, 59, -50, +100, -22, 104, 7, 73, 38, 38, 63, +18, 76, -6, 73, -34, 53, -51, 18, +-64, -14, -90, -39, -105, -50, -84, -47, +-30, -32, 38, -10, 115, 15, 191, 30, +229, 34, 198, 34, 109, 27, -18, 12, +-167, -9, -298, -36, -344, -60, -291, -75, +-158, -75, 26, -55, 219, -11, 358, 45, +393, 93, 320, 115, 171, 109, -21, 71, +-203, 10, -320, -54, -339, -94, -265, -94, +-129, -59, 29, -9, 160, 36, 225, 54, +218, 32, 149, -20, 57, -77, -24, -108, +-73, -94, -88, -33, -69, 54, -33, 134, +1, 179, 9, 168, 5, 96, -1, -15, +-14, -114, -29, -163, -21, -152, 12, -93, +44, -8, 57, 68, 57, 104, 33, 83, +-14, 20, -57, -54, -66, -104, -48, -113, +-18, -71, 21, 4, 65, 87, 86, 144, +69, 160, 31, 133, -12, 76, -59, 8, +-95, -55, -96, -106, -57, -140, -10, -159, +34, -158, 69, -139, 88, -93, 76, -10, +44, 100, 18, 204, 4, 277, -14, 286, +-24, 214, -25, 71, -31, -104, -44, -265, +-48, -357, -42, -347, -25, -231, -7, -47, +17, 148, 48, 291, 76, 346, 81, 295, +64, 160, 35, -12, 4, -164, -33, -256, +-58, -263, -60, -196, -44, -79, -36, 45, +-32, 137, -16, 172, 1, 157, 7, 103, +19, 28, 42, -40, 61, -79, 60, -86, +54, -60, 48, -20, 24, 20, -25, 46, +-69, 46, -96, 20, -105, -27, -91, -73, +-37, -95, 37, -83, 95, -38, 125, 29, +139, 101, 116, 149, 56, 150, -22, 101, +-89, 17, -135, -83, -153, -164, -129, -195, +-61, -166, 20, -83, 90, 25, 140, 121, +164, 174, 147, 170, 100, 111, 35, 25, +-35, -59, -106, -119, -158, -134, -178, -113, +-154, -68, -96, -21, -14, 23, 76, 58, +152, 82, 193, 95, 187, 102, 136, 97, +61, 65, -25, 2, -104, -80, -157, -159, +-162, -206, -129, -200, -73, -128, -4, -3, +63, 140, 96, 250, 93, 282, 71, 220, +49, 85, 20, -76, -5, -211, -12, -273, +-1, -234, 0, -116, -6, 38, -14, 164, +-25, 216, -46, 175, -57, 62, -39, -74, +-2, -167, 34, -183, 72, -118, 101, 1, +86, 125, 28, 198, -39, 190, -89, 100, +-110, -37, -97, -163, -45, -224, 30, -200, +99, -102, 135, 35, 133, 159, 88, 228, +8, 211, -76, 115, -128, -18, -142, -136, +-113, -201, -61, -196, 2, -126, 57, -24, +89, 82, 90, 151, 79, 167, 62, 136, +40, 75, 13, 2, -9, -62, -25, -106, +-42, -120, -61, -111, -65, -81, -55, -40, +-41, 13, -28, 64, -2, 105, 33, 117, +57, 98, 69, 57, 75, 5, 64, -43, +33, -77, -6, -83, -27, -65, -38, -38, +-49, -7, -56, 10, -40, 10, -19, -2, +-6, -11, 14, -9, 41, 13, 49, 49, +38, 82, 27, 92, 20, 72, 5, 19, +-8, -49, -15, -110, -18, -138, -28, -129, +-28, -80, -13, -12, 10, 51, 27, 89, +39, 97, 46, 84, 38, 56, 17, 28, +-8, 14, -40, 13, -69, 7, -89, -14, +-82, -50, -41, -92, 24, -122, 93, -126, +151, -88, 171, -10, 142, 79, 66, 149, +-40, 171, -140, 134, -206, 55, -226, -36, +-176, -110, -62, -136, 75, -98, 179, -20, +225, 65, 202, 115, 113, 108, -12, 45, +-114, -49, -156, -129, -136, -156, -73, -114, +15, -19, 90, 88, 113, 164, 70, 176, +-5, 121, -80, 15, -132, -95, -138, -162, +-76, -158, 24, -87, 123, 20, 187, 122, +198, 178, 142, 162, 37, 79, -76, -41, +-155, -150, -189, -210, -170, -202, -106, -135, +-16, -29, 65, 76, 123, 154, 149, 192, +141, 179, 100, 128, 44, 57, -15, -17, +-63, -81, -97, -130, -110, -154, -103, -153, +-75, -119, -36, -63, 19, 8, 78, 86, +122, 150, 138, 176, 114, 156, 53, 94, +-22, 5, -93, -85, -144, -147, -159, -166, +-119, -133, -48, -63, 31, 23, 105, 95, +156, 139, 156, 141, 109, 99, 44, 31, +-22, -43, -78, -95, -111, -119, -106, -115, +-71, -81, -41, -28, -15, 30, 15, 67, +42, 84, 53, 80, 58, 58, 70, 24, +70, -11, 47, -33, 15, -39, -21, -28, +-58, -14, -88, 0, -89, 9, -58, 2, +-7, -10, 42, -22, 84, -24, 99, -16, +74, -1, 20, 7, -38, 2, -85, -8, +-104, -26, -76, -42, -9, -33, 64, 7, +123, 75, 139, 142, 112, 183, 44, 163, +-47, 80, -132, -56, -180, -209, -169, -326, +-102, -355, -4, -273, 103, -99, 180, 119, +197, 316, 149, 424, 67, 409, -26, 272, +-102, 64, -143, -151, -132, -302, -79, -356, +-14, -305, 41, -178, 76, -30, 76, 92, +39, 153, -5, 147, -24, 106, -23, 60, +-2, 36, 31, 39, 62, 62, 61, 76, +27, 55, -17, -13, -58, -106, -90, -188, +-98, -224, -71, -187, -21, -86, 33, 49, +81, 177, 108, 252, 106, 249, 76, 164, +36, 39, -7, -87, -44, -174, -72, -195, +-92, -154, -96, -77, -84, -5, -56, 42, +-13, 60, 37, 52, 94, 39, 139, 32, +158, 48, 137, 70, 78, 82, -8, 65, +-100, 13, -171, -61, -195, -132, -167, -169, +-95, -157, 5, -90, 107, 12, 168, 112, +180, 176, 142, 177, 68, 127, -25, 37, +-96, -55, -118, -123, -97, -145, -49, -116, +6, -56, 51, 17, 66, 73, 44, 99, +9, 93, -26, 60, -48, 17, -57, -29, +-35, -56, 1, -74, 35, -76, 56, -68, +62, -46, 51, -8, 25, 36, 3, 78, +-7, 107, -12, 114, -16, 96, -24, 47, +-27, -15, -40, -78, -54, -117, -62, -130, +-54, -112, -27, -70, 14, -16, 67, 42, +115, 81, 143, 102, 140, 100, 98, 85, +26, 60, -63, 18, -137, -27, -187, -71, +-187, -100, -137, -111, -54, -88, 41, -38, +127, 26, 180, 89, 177, 124, 127, 121, +54, 71, -21, -12, -78, -90, -111, -141, +-98, -138, -62, -83, -25, 12, 5, 106, +16, 168, 4, 174, -18, 116, -26, 14, +-7, -96, 25, -167, 61, -174, 92, -125, +109, -39, 85, 47, 31, 111, -42, 121, +-107, 86, -149, 25, -147, -30, -88, -54, +-5, -39, 73, 7, 128, 54, 139, 78, +103, 58, 36, -7, -33, -83, -89, -142, +-107, -150, -85, -102, -32, -4, 30, 109, +76, 195, 87, 219, 66, 163, 20, 53, +-38, -79, -79, -189, -84, -238, -66, -211, +-18, -113, 34, 16, 78, 143, 91, 222, +76, 232, 38, 168, -11, 56, -48, -66, +-71, -165, -72, -207, -49, -190, -12, -125, +27, -29, 48, 64, 60, 134, 53, 159, +33, 145, 0, 93, -24, 27, -33, -33, +-35, -74, -30, -88, -15, -79, -3, -53, +-3, -26, -4, -8, 2, 5, 4, 9, +17, 19, 33, 28, 51, 44, 59, 59, +42, 65, 11, 46, -25, -1, -63, -52, +-94, -96, -98, -106, -71, -76, -28, -20, +36, 52, 94, 105, 131, 128, 127, 97, +94, 30, 37, -56, -28, -126, -75, -155, +-103, -131, -101, -57, -77, 35, -43, 110, +-2, 145, 29, 130, 53, 81, 63, 9, +69, -48, 66, -84, 54, -82, 35, -56, +3, -25, -34, -1, -64, -1, -83, -11, +-85, -20, -60, -18, -12, 5, 36, 36, +82, 68, 104, 78, 94, 68, 49, 30, +-8, -18, -58, -62, -88, -88, -88, -81, +-63, -49, -15, 1, 37, 40, 71, 54, +92, 46, 80, 23, 42, 2, -8, -18, +-44, -17, -70, -5, -78, 9, -66, 16, +-43, 9, -11, -5, 18, -22, 46, -28, +71, -24, 84, -4, 83, 27, 60, 47, +32, 56, -16, 36, -65, 6, -104, -32, +-120, -62, -107, -71, -70, -54, -13, -22, +53, 9, 108, 33, 141, 41, 141, 32, +116, 28, 58, 23, -7, 30, -75, 34, +-127, 37, -151, 19, -147, -18, -109, -66, +-45, -110, 35, -120, 105, -95, 157, -34, +176, 47, 147, 120, 80, 165, -15, 149, +-93, 86, -144, -7, -157, -88, -121, -135, +-49, -137, 35, -90, 95, -22, 121, 44, +103, 75, 45, 70, -22, 41, -72, -3, +-75, -29, -47, -31, 5, -2, 58, 31, +89, 53, 78, 51, 24, 20, -41, -22, +-104, -63, -135, -81, -109, -73, -38, -35, +56, 13, 139, 44, 189, 58, 169, 44, +90, 24, -22, -1, -129, -15, -193, -10, +-198, 2, -140, 19, -38, 18, 80, 6, +166, -14, 191, -32, 163, -39, 78, -37, +-21, -17, -105, -1, -142, 17, -129, 25, +-72, 25, 3, 20, 62, 17, 94, 27, +75, 33, 20, 30, -32, 14, -74, -17, +-80, -49, -45, -79, 24, -78, 91, -53, +138, -2, 138, 51, 79, 90, -12, 98, +-118, 63, -196, 5, -208, -61, -148, -99, +-41, -92, 85, -41, 197, 36, 238, 97, +210, 126, 118, 96, -8, 22, -124, -71, +-199, -141, -210, -154, -157, -112, -55, -23, +47, 73, 121, 144, 153, 161, 121, 112, +66, 25, 12, -71, -28, -122, -45, -123, +-28, -72, -5, 4, 5, 68, 5, 94, +-22, 65, -57, 2, -75, -72, -67, -121, +-21, -110, 45, -50, 116, 49, 150, 133, +144, 181, 82, 155, -15, 68, -103, -47, +-170, -148, -183, -196, -129, -183, -31, -109, +73, -5, 158, 94, 194, 159, 153, 161, +77, 116, -23, 40, -116, -27, -165, -78, +-156, -93, -96, -75, -9, -47, 81, -15, +132, 1, 147, 10, 116, 12, 42, 7, +-22, 6, -74, 5, -98, 18, -93, 24, +-58, 36, -16, 40, 19, 37, 44, 28, +46, 3, 37, -25, 20, -61, 3, -91, +1, -104, 5, -90, 12, -41, 8, 27, +6, 107, -14, 163, -36, 181, -48, 149, +-50, 69, -27, -33, 10, -131, 49, -188, +77, -195, 82, -151, 58, -75, 1, -1, +-50, 60, -92, 86, -99, 99, -65, 97, +2, 103, 77, 114, 129, 114, 140, 93, +97, 32, 19, -62, -77, -173, -154, -262, +-174, -288, -148, -236, -66, -100, 38, 70, +138, 235, 191, 329, 181, 328, 119, 233, +24, 71, -67, -94, -131, -218, -142, -256, +-103, -213, -48, -115, 20, -4, 65, 74, +83, 106, 62, 78, 29, 30, -9, -18, +-32, -38, -30, -22, -15, 13, 17, 49, +44, 58, 49, 44, 37, 7, 15, -34, +-9, -50, -35, -39, -37, 6, -43, 51, +-42, 76, -35, 54, -33, -12, -23, -98, +-7, -173, 20, -190, 52, -138, 91, -17, +117, 130, 113, 250, 93, 303, 33, 253, +-44, 127, -124, -49, -181, -207, -198, -303, +-157, -305, -71, -216, 32, -76, 146, 73, +219, 179, 230, 222, 192, 198, 98, 126, +-19, 44, -130, -31, -192, -74, -205, -92, +-158, -81, -74, -63, 18, -54, 106, -47, +146, -40, 131, -19, 88, 11, 27, 50, +-36, 92, -70, 108, -53, 103, -27, 63, +15, 13, 47, -50, 46, -101, 22, -134, +-21, -137, -67, -103, -94, -44, -74, 28, +-27, 94, 41, 138, 118, 149, 145, 123, +127, 74, 66, -3, -22, -74, -112, -124, +-165, -138, -165, -117, -118, -66, -24, 7, +65, 61, 137, 88, 178, 80, 156, 48, +95, 12, 17, -20, -53, -22, -114, -10, +-132, 18, -126, 36, -102, 31, -52, 4, +-7, -40, 39, -75, 90, -90, 123, -64, +132, -10, 126, 50, 103, 100, 33, 108, +-36, 76, -102, 3, -153, -70, -170, -122, +-143, -129, -81, -82, -2, -2, 83, 85, +138, 143, 160, 159, 147, 121, 92, 35, +40, -57, -17, -136, -67, -167, -103, -156, +-109, -97, -102, -17, -82, 60, -33, 115, +17, 136, 69, 129, 108, 91, 118, 37, +105, -18, 57, -72, -10, -107, -83, -129, +-124, -113, -135, -72, -103, -5, -22, 68, +68, 125, 145, 157, 174, 141, 145, 84, +68, -5, -35, -98, -128, -165, -190, -190, +-185, -151, -136, -75, -42, 27, 62, 114, +145, 167, 187, 170, 175, 131, 126, 68, +50, -3, -18, -55, -75, -88, -113, -99, +-116, -99, -115, -98, -98, -84, -73, -69, +-33, -30, 11, 25, 62, 92, 117, 153, +152, 182, 165, 169, 136, 100, 74, -3, +-7, -112, -102, -195, -167, -216, -197, -176, +-171, -77, -107, 32, -10, 126, 87, 168, +149, 155, 173, 100, 144, 18, 86, -51, +16, -95, -51, -99, -94, -73, -102, -43, +-76, -8, -44, 9, 9, 19, 44, 22, +54, 37, 48, 56, 20, 72, -6, 76, +-21, 51, -21, 3, -14, -59, 1, -114, +18, -146, 20, -145, 27, -93, 16, -22, +5, 61, -2, 123, -9, 159, -14, 156, +-11, 117, -7, 61, -18, -6, -18, -63, +-18, -106, -17, -130, 15, -130, 51, -108, +80, -63, 89, -14, 80, 37, 28, 69, +-42, 85, -109, 82, -166, 58, -162, 32, +-107, 7, -14, -1, 113, 2, 222, 12, +266, 21, 227, 9, 127, -17, -39, -68, +-193, -115, -287, -142, -306, -126, -229, -65, +-79, 21, 90, 119, 225, 190, 297, 213, +270, 175, 160, 83, 28, -27, -121, -131, +-215, -187, -224, -191, -166, -135, -64, -46, +54, 44, 140, 106, 162, 120, 139, 94, +64, 37, -27, -19, -90, -51, -132, -52, +-130, -20, -83, 16, -7, 45, 59, 43, +122, 16, 155, -28, 136, -64, 93, -72, +22, -53, -54, -2, -114, 56, -154, 96, +-162, 95, -129, 52, -60, -12, 8, -87, +96, -129, 165, -130, 186, -78, 169, 6, +112, 90, 26, 150, -65, 159, -135, 118, +-177, 36, -172, -57, -119, -125, -55, -153, +37, -129, 120, -75, 165, 4, 162, 70, +121, 108, 43, 103, -49, 62, -109, 3, +-139, -57, -121, -87, -59, -78, 13, -35, +88, 30, 132, 81, 134, 105, 80, 82, +3, 26, -87, -53, -147, -120, -146, -146, +-99, -118, -11, -41, 88, 55, 154, 139, +165, 173, 120, 137, 37, 51, -69, -66, +-135, -155, -160, -191, -125, -145, -43, -37, +49, 93, 123, 193, 146, 222, 113, 169, +36, 43, -47, -102, -106, -213, -127, -250, +-84, -191, -21, -72, 53, 73, 101, 181, +111, 220, 77, 176, 14, 73, -50, -45, +-95, -137, -96, -163, -64, -119, -10, -29, +57, 69, 95, 128, 104, 134, 72, 80, +19, -5, -40, -95, -78, -146, -93, -145, +-86, -93, -55, -9, -22, 72, 17, 124, +54, 130, 75, 96, 87, 40, 87, -21, +77, -54, 46, -61, 14, -33, -33, 3, +-82, 27, -113, 23, -132, -4, -127, -42, +-90, -81, -26, -101, 48, -88, 120, -41, +170, 31, 173, 100, 158, 152, 103, 163, +27, 136, -52, 69, -125, -12, -180, -90, +-199, -148, -173, -168, -120, -149, -35, -94, +57, -21, 132, 48, 200, 101, 225, 121, +202, 115, 136, 76, 48, 26, -68, -25, +-171, -60, -228, -73, -243, -60, -193, -28, +-97, 9, 14, 40, 126, 55, 205, 47, +230, 20, 200, -21, 136, -55, 26, -77, +-86, -67, -169, -40, -209, -2, -187, 41, +-115, 73, -16, 80, 83, 64, 160, 34, +182, -3, 151, -40, 96, -62, 5, -74, +-73, -61, -122, -32, -139, 8, -119, 41, +-58, 61, 9, 59, 57, 35, 92, 0, +92, -35, 69, -62, 51, -64, 20, -44, +-9, -3, -29, 34, -41, 63, -59, 63, +-55, 43, -42, 9, -34, -24, -3, -39, +23, -28, 35, 2, 50, 31, 53, 39, +39, 25, 10, -14, -12, -60, -39, -100, +-35, -103, -12, -68, 6, 4, 28, 85, +37, 148, 17, 170, -14, 137, -38, 61, +-59, -30, -64, -108, -38, -149, -9, -152, +34, -110, 70, -54, 88, 0, 85, 40, +65, 67, 25, 75, -13, 75, -36, 79, +-62, 81, -74, 66, -66, 32, -65, -21, +-60, -79, -43, -134, -6, -156, 34, -138, +92, -71, 132, 24, 139, 121, 122, 181, +67, 185, -10, 128, -85, 30, -143, -76, +-167, -154, -144, -181, -78, -141, -8, -59, +75, 36, 126, 103, 134, 127, 111, 98, +59, 37, 2, -31, -41, -76, -57, -80, +-52, -46, -29, 11, 0, 68, 13, 94, +26, 79, 20, 23, -3, -41, -33, -101, +-59, -127, -70, -115, -58, -69, -17, -5, +34, 57, 87, 106, 124, 127, 133, 116, +118, 82, 67, 35, -9, -8, -92, -55, +-151, -92, -179, -117, -156, -117, -92, -98, +-5, -59, 88, -9, 149, 45, 164, 92, +132, 118, 66, 115, -5, 91, -63, 52, +-89, 17, -90, -19, -52, -41, -9, -61, +25, -74, 40, -84, 20, -90, -9, -85, +-40, -57, -53, -5, -37, 61, 2, 121, +59, 156, 88, 148, 99, 98, 68, 8, +15, -86, -39, -157, -82, -173, -101, -132, +-87, -46, -40, 50, 17, 123, 67, 148, +97, 120, 82, 46, 54, -41, 8, -109, +-40, -127, -67, -100, -66, -38, -50, 22, +-13, 62, 24, 71, 40, 54, 46, 23, +42, 1, 21, -8, 5, 6, -6, 27, +-15, 41, -13, 28, 0, -6, -4, -58, +-10, -103, -16, -127, -31, -109, -34, -50, +-20, 31, 2, 113, 23, 165, 51, 167, +64, 120, 54, 34, 44, -56, 7, -130, +-29, -156, -56, -136, -69, -77, -61, 0, +-33, 72, 4, 114, 28, 114, 51, 76, +48, 20, 13, -34, -12, -69, -34, -81, +-39, -60, -18, -26, 21, 11, 53, 38, +73, 54, 66, 49, 24, 34, -26, 14, +-74, -2, -110, -13, -99, -14, -55, -18, +10, -22, 76, -34, 120, -45, 113, -56, +73, -53, 14, -36, -48, 3, -88, 57, +-87, 113, -61, 145, -10, 139, 43, 90, +66, 7, 58, -96, 38, -185, -8, -230, +-44, -207, -56, -124, -39, 6, -10, 141, +31, 245, 51, 275, 45, 222, 28, 101, +-12, -49, -44, -181, -49, -249, -43, -240, +-11, -158, 26, -37, 54, 88, 51, 168, +40, 186, 9, 147, -36, 74, -54, -11, +-53, -74, -32, -100, 5, -90, 34, -55, +49, -16, 40, 7, 21, 18, -17, 15, +-39, 11, -42, 11, -34, 24, -4, 36, +28, 47, 43, 44, 42, 29, 25, 0, +-6, -28, -39, -52, -53, -64, -55, -64, +-36, -46, -1, -21, 34, 9, 63, 34, +77, 60, 58, 74, 27, 78, -14, 61, +-53, 26, -71, -24, -72, -68, -55, -102, +-20, -106, 18, -76, 50, -14, 66, 52, +67, 106, 43, 122, 12, 95, -21, 31, +-46, -42, -47, -103, -37, -121, -15, -91, +3, -24, 10, 51, 14, 110, 2, 124, +-2, 91, -5, 18, 2, -57, 12, -112, +25, -120, 39, -89, 40, -25, 25, 39, +-1, 81, -30, 84, -49, 60, -59, 19, +-39, -20, -13, -42, 24, -37, 49, -18, +54, 5, 48, 11, 29, 0, -4, -24, +-27, -43, -44, -48, -45, -24, -32, 22, +-8, 74, 9, 107, 30, 106, 38, 61, +33, -7, 21, -82, 9, -129, -14, -135, +-26, -95, -39, -26, -51, 51, -48, 102, +-31, 118, -3, 89, 37, 37, 72, -13, +88, -40, 78, -45, 58, -21, 4, 9, +-54, 29, -98, 19, -121, -13, -110, -54, +-69, -77, -10, -79, 49, -47, 98, 8, +117, 67, 99, 107, 73, 122, 18, 102, +-34, 55, -58, -10, -67, -67, -63, -102, +-52, -101, -41, -84, -31, -53, -12, -16, +5, 22, 20, 50, 51, 72, 72, 79, +82, 76, 80, 52, 53, 14, 7, -36, +-46, -74, -95, -94, -124, -87, -118, -54, +-78, 5, -27, 63, 38, 100, 99, 104, +128, 78, 121, 24, 93, -37, 34, -88, +-20, -106, -64, -93, -93, -51, -99, -7, +-72, 32, -43, 52, -10, 55, 29, 42, +49, 28, 55, 18, 63, 18, 50, 23, +40, 27, 26, 14, 13, -14, -9, -51, +-31, -79, -59, -96, -81, -83, -86, -46, +-72, 7, -40, 57, 20, 94, 77, 103, +128, 86, 146, 46, 135, 1, 75, -37, +-12, -52, -102, -56, -170, -44, -191, -27, +-154, -9, -82, -5, 23, -9, 119, -18, +177, -19, 186, -11, 152, 13, 73, 41, +-17, 74, -98, 94, -152, 93, -159, 55, +-125, -3, -77, -75, -22, -132, 25, -160, +59, -142, 93, -84, 121, 9, 136, 106, +128, 184, 91, 210, 30, 177, -55, 83, +-138, -42, -196, -160, -220, -226, -183, -230, +-90, -161, 34, -47, 155, 79, 241, 172, +258, 207, 204, 175, 101, 100, -30, 4, +-135, -72, -188, -109, -191, -99, -141, -62, +-73, -16, -8, 2, 43, -9, 68, -41, +72, -67, 65, -68, 65, -23, 64, 58, +68, 147, 62, 200, 33, 195, -24, 116, +-91, -18, -135, -166, -141, -262, -113, -270, +-37, -184, 49, -36, 126, 124, 166, 232, +150, 253, 81, 173, -6, 34, -99, -113, +-150, -201, -149, -202, -94, -113, -13, 21, +73, 148, 124, 204, 135, 173, 98, 63, +33, -76, -41, -187, -87, -220, -104, -169, +-76, -46, -33, 91, 24, 189, 62, 208, +72, 152, 50, 37, 7, -87, -41, -175, +-61, -191, -60, -138, -27, -34, 21, 74, +63, 151, 80, 167, 82, 126, 49, 44, +1, -37, -44, -99, -87, -115, -103, -96, +-82, -47, -46, 2, 2, 35, 47, 42, +67, 30, 65, 8, 51, -10, 31, -20, +13, -7, 0, 19, -10, 50, -13, 65, +-8, 60, -5, 32, -13, -8, -23, -52, +-32, -84, -36, -101, -28, -92, -2, -66, +25, -27, 45, 16, 56, 56, 38, 77, +13, 84, -7, 72, -30, 58, -32, 41, +-19, 28, -8, 9, 10, -11, 24, -37, +17, -65, 2, -97, -12, -114, -37, -109, +-43, -70, -29, -8, -6, 70, 26, 132, +48, 165, 43, 151, 26, 97, -3, 11, +-19, -74, -33, -134, -27, -140, -11, -100, +7, -26, 26, 43, 41, 87, 28, 80, +9, 34, -20, -32, -44, -82, -56, -95, +-36, -58, -20, 15, 11, 100, 33, 152, +38, 150, 32, 82, 29, -21, 6, -129, +1, -190, -5, -190, -5, -121, -1, -9, +2, 111, -5, 189, -7, 200, -15, 143, +-27, 49, -36, -59, -24, -140, -7, -173, +14, -146, 19, -82, 18, -4, 12, 55, +5, 95, 11, 102, 14, 88, 24, 64, +33, 41, 22, 20, 9, 2, -13, -29, +-45, -61, -66, -92, -73, -105, -61, -96, +-27, -58, 22, -4, 55, 58, 75, 105, +71, 126, 39, 109, 8, 67, -27, 15, +-53, -30, -47, -63, -31, -66, -5, -53, +17, -30, 30, -11, 28, 6, 9, 7, +-12, 5, -34, -2, -52, -6, -49, -8, +-29, -5, -2, 1, 25, 17, 50, 31, +66, 44, 76, 48, 78, 50, 41, 33, +-3, 1, -55, -46, -106, -86, -125, -111, +-111, -105, -70, -64, 0, 6, 70, 75, +134, 127, 157, 136, 139, 105, 64, 32, +-27, -49, -114, -114, -166, -133, -163, -106, +-110, -39, -26, 37, 71, 97, 131, 118, +165, 100, 132, 46, 71, -13, -8, -60, +-84, -78, -125, -73, -125, -46, -105, -21, +-49, -4, 8, -2, 51, 0, 68, 4, +80, 21, 67, 48, 55, 81, 41, 95, +18, 80, -5, 35, -37, -26, -69, -93, +-73, -133, -73, -137, -53, -94, -30, -25, +2, 49, 39, 100, 63, 113, 78, 83, +70, 30, 44, -30, 13, -61, -16, -56, +-38, -21, -50, 24, -47, 66, -45, 74, +-31, 50, 0, 0, 8, -52, 26, -94, +34, -104, 19, -82, 10, -36, 0, 11, +-8, 52, -2, 70, 10, 71, 22, 58, +22, 47, 16, 33, -8, 21, -29, 0, +-44, -24, -56, -57, -46, -86, -22, -105, +23, -92, 67, -50, 93, 20, 99, 88, +61, 137, 10, 136, -35, 89, -81, 4, +-96, -84, -96, -153, -75, -171, -37, -129, +17, -37, 59, 73, 92, 174, 104, 221, +84, 203, 59, 111, 35, -14, -21, -140, +-58, -227, -98, -256, -118, -208, -107, -107, +-68, 22, -8, 138, 60, 214, 107, 229, +132, 185, 108, 95, 62, -4, -15, -92, +-73, -140, -107, -146, -97, -112, -58, -60, +-2, -3, 49, 34, 72, 46, 60, 33, +34, 12, -28, -7, -57, -3, -60, 17, +-37, 53, 17, 79, 59, 85, 70, 52, +59, -11, 17, -85, -39, -140, -82, -160, +-90, -125, -73, -43, -10, 61, 69, 147, +124, 192, 146, 167, 107, 88, 32, -27, +-59, -132, -136, -196, -169, -189, -161, -123, +-99, -17, -6, 89, 79, 162, 152, 176, +168, 138, 140, 57, 80, -28, 9, -94, +-58, -117, -98, -100, -103, -54, -95, -7, +-64, 32, -31, 41, -15, 23, 18, -4, +29, -18, 39, -18, 60, 1, 60, 27, +57, 52, 42, 55, 23, 39, -2, 3, +-31, -30, -56, -54, -73, -51, -69, -31, +-42, -3, -5, 16, 33, 22, 43, 8, +52, -12, 36, -35, 26, -39, 16, -27, +-9, 7, -18, 39, -19, 61, -27, 64, +-14, 46, -16, 7, -8, -30, -7, -51, +5, -48, 18, -33, 44, -4, 56, 18, +52, 25, 39, 4, 11, -26, -41, -57, +-73, -64, -112, -48, -109, -8, -81, 41, +-27, 88, 44, 114, 107, 109, 160, 69, +184, 14, 146, -48, 77, -93, -29, -119, +-126, -111, -198, -83, -217, -39, -188, 4, +-118, 42, -11, 63, 90, 72, 179, 71, +221, 65, 192, 50, 134, 39, 36, 24, +-62, 12, -126, -14, -165, -43, -159, -80, +-126, -107, -68, -117, -5, -101, 58, -56, +104, 17, 120, 96, 119, 159, 93, 180, +49, 156, -6, 81, -73, -18, -108, -122, +-129, -185, -110, -191, -57, -132, 1, -32, +75, 79, 124, 153, 125, 172, 94, 124, +21, 34, -54, -67, -107, -129, -116, -138, +-89, -86, -30, -1, 38, 90, 72, 140, +92, 127, 63, 58, -1, -34, -55, -119, +-91, -155, -77, -129, -19, -46, 45, 58, +103, 145, 108, 171, 87, 137, 19, 48, +-60, -54, -124, -135, -155, -157, -140, -123, +-70, -52, 23, 24, 108, 80, 154, 89, +168, 63, 114, 14, 54, -18, -28, -24, +-100, 4, -130, 47, -132, 83, -106, 75, +-44, 27, 6, -55, 57, -137, 88, -186, +100, -173, 77, -99, 44, 20, 2, 133, +-35, 210, -48, 214, -46, 153, -36, 46, +-20, -60, -15, -136, 5, -157, 5, -123, +3, -54, 0, 12, -11, 57, 3, 64, +14, 40, 25, -3, 36, -34, 21, -44, +-4, -20, -24, 18, -31, 58, -35, 78, +-23, 76, -4, 44, 3, -1, 24, -49, +20, -78, 6, -87, -4, -68, -23, -40, +-21, 0, -5, 36, 8, 61, 26, 65, +29, 55, 26, 29, -1, 4, -28, -22, +-44, -42, -40, -54, -13, -49, 15, -37, +42, -16, 49, -2, 39, 18, 19, 31, +-17, 43, -32, 46, -43, 49, -46, 43, +-14, 26, 7, -8, 28, -53, 34, -103, +12, -131, -18, -130, -27, -89, -17, -15, +10, 88, 39, 176, 59, 225, 49, 209, +34, 126, -17, -3, -64, -138, -103, -240, +-115, -266, -86, -212, -29, -91, 37, 50, +104, 169, 124, 223, 124, 205, 75, 118, +18, 10, -44, -83, -87, -124, -106, -113, +-88, -61, -56, 0, -27, 46, -3, 51, +17, 23, 13, -25, 25, -55, 17, -54, +22, -16, 45, 38, 61, 93, 70, 112, +58, 83, 14, 11, -40, -72, -96, -140, +-121, -158, -120, -120, -86, -31, -30, 68, +38, 152, 98, 176, 128, 145, 123, 62, +71, -38, 4, -123, -56, -161, -101, -145, +-102, -79, -75, 5, -38, 83, 20, 122, +55, 120, 70, 73, 61, 11, 25, -50, +-22, -85, -53, -93, -66, -67, -61, -19, +-33, 34, 3, 76, 29, 96, 55, 83, +50, 47, 32, -11, 9, -65, -17, -106, +-27, -116, -35, -97, -26, -45, -11, 23, +-2, 91, 13, 132, 14, 138, 0, 101, +-18, 36, -36, -44, -41, -105, -33, -139, +-11, -126, 0, -80, 24, -8, 40, 58, +45, 107, 53, 121, 41, 102, 11, 58, +-11, 11, -50, -37, -66, -75, -80, -95, +-82, -92, -77, -79, -43, -49, 0, -12, +51, 36, 93, 78, 123, 111, 113, 123, +84, 105, 21, 55, -38, -14, -103, -84, +-131, -132, -129, -152, -94, -129, -31, -79, +34, -7, 76, 56, 110, 103, 89, 120, +44, 111, -13, 80, -64, 45, -91, 7, +-71, -26, -37, -55, 2, -73, 45, -92, +68, -95, 70, -86, 62, -50, 16, 5, +-33, 66, -70, 110, -94, 128, -90, 109, +-73, 57, -43, -13, -9, -76, 30, -116, +73, -116, 104, -82, 114, -17, 92, 48, +39, 94, -28, 100, -90, 73, -134, 21, +-148, -31, -115, -66, -58, -71, 11, -53, +78, -17, 106, 14, 103, 31, 81, 25, +25, 15, -31, -1, -65, -6, -76, 0, +-59, 19, -22, 35, 7, 42, 17, 32, +10, 1, -7, -42, -17, -75, -19, -89, +-16, -72, -2, -32, 15, 23, 24, 69, +31, 96, 18, 87, 2, 53, -29, 5, +-53, -38, -52, -66, -39, -66, -25, -45, +3, -14, 23, 9, 41, 27, 45, 25, +40, 13, 17, -5, -1, -16, -34, -16, +-57, 1, -70, 19, -69, 31, -53, 30, +-17, 19, 13, -7, 51, -32, 64, -48, +60, -41, 35, -22, 3, 10, -32, 38, +-55, 61, -70, 59, -56, 31, -28, -10, +4, -48, 24, -75, 29, -77, 10, -53, +-1, -10, -16, 37, -28, 78, -23, 90, +-14, 77, -5, 38, 14, -11, 18, -58, +15, -82, 1, -80, -21, -51, -33, -10, +-33, 31, -27, 56, -19, 63, -9, 46, +-4, 20, -1, -13, 5, -35, 5, -43, +7, -32, 0, -15, -1, 1, -1, 12, +-12, 18, -16, 14, -24, 15, -29, 18, +-24, 25, -21, 21, -10, 10, 7, -10, +10, -30, 2, -53, 0, -65, -13, -54, +-30, -18, -32, 35, -28, 88, -15, 117, +4, 111, 9, 64, 17, -7, 16, -83, +3, -129, -21, -137, -40, -99, -58, -30, +-56, 48, -35, 104, 2, 123, 31, 100, +49, 48, 51, -18, 40, -65, 10, -83, +-20, -64, -56, -27, -78, 13, -80, 31, +-59, 26, -29, -4, 18, -38, 47, -56, +58, -39, 54, 6, 32, 64, 1, 108, +-21, 120, -47, 82, -52, 5, -47, -89, +-40, -160, -32, -184, -16, -143, -10, -52, +-3, 65, 3, 160, 11, 203, 18, 178, +29, 99, 30, -15, 20, -111, -10, -164, +-46, -154, -73, -100, -84, -16, -73, 60, +-47, 106, -14, 106, 29, 70, 55, 14, +69, -36, 64, -66, 29, -61, -15, -38, +-51, -4, -75, 23, -81, 41, -68, 43, +-53, 38, -30, 26, 3, 14, 23, -1, +38, -11, 38, -26, 26, -45, 18, -63, +3, -66, -15, -55, -34, -19, -49, 27, +-52, 78, -49, 108, -34, 114, -18, 88, +-2, 37, 8, -31, 20, -94, 21, -132, +3, -127, -20, -91, -38, -32, -41, 26, +-22, 79, -6, 105, 19, 107, 30, 77, +29, 29, 14, -20, -12, -55, -56, -75, +-85, -69, -97, -46, -79, -16, -34, 9, +25, 29, 66, 29, 94, 18, 86, -2, +52, -12, -9, -9, -69, 8, -111, 27, +-116, 47, -98, 53, -52, 40, -2, 1, +45, -46, 67, -88, 64, -102, 33, -89, +2, -42, -35, 23, -55, 88, -64, 126, +-63, 130, -55, 92, -38, 29, -26, -40, +-3, -91, 26, -112, 44, -94, 49, -51, +43, 0, 21, 33, -7, 44, -46, 33, +-86, 13, -110, -5, -114, -1, -87, 18, +-34, 45, 21, 67, 61, 70, 79, 38, +81, -19, 66, -84, 32, -128, -6, -143, +-39, -109, -63, -39, -83, 51, -84, 124, +-80, 157, -66, 139, -44, 78, -22, -6, +9, -79, 39, -126, 53, -129, 65, -92, +55, -26, 30, 41, -4, 91, -33, 107, +-60, 91, -80, 44, -78, -12, -68, -61, +-47, -90, -30, -93, -16, -64, -1, -21, +6, 25, 12, 60, 15, 81, 13, 76, +19, 56, 9, 20, 10, -16, -1, -42, +-17, -51, -32, -50, -39, -39, -50, -26, +-60, -13, -64, -7, -61, -4, -49, -4, +-14, 5, 6, 21, 43, 49, 57, 70, +62, 74, 48, 51, 18, 14, -30, -37, +-72, -88, -101, -118, -98, -108, -82, -67, +-41, -1, -8, 64, 34, 107, 54, 107, +55, 75, 28, 22, -9, -32, -47, -67, +-72, -67, -79, -37, -59, 6, -48, 44, +-22, 62, 3, 41, 26, -1, 31, -48, +26, -76, 12, -82, 2, -50, -14, 8, +-33, 67, -46, 101, -55, 103, -72, 67, +-71, 6, -57, -57, -36, -97, -8, -107, +18, -79, 40, -30, 52, 29, 51, 70, +39, 86, 18, 70, -18, 38, -53, -2, +-79, -31, -93, -44, -98, -39, -90, -27, +-67, -8, -31, 0, -3, 0, 31, -10, +60, -16, 71, -21, 66, -9, 47, 18, +11, 48, -21, 66, -50, 73, -76, 57, +-93, 19, -99, -31, -102, -74, -81, -108, +-52, -116, -17, -93, 20, -41, 52, 23, +73, 87, 75, 127, 66, 134, 38, 102, +1, 47, -49, -16, -89, -70, -110, -101, +-114, -95, -105, -66, -84, -24, -55, 12, +-9, 31, 21, 22, 60, 3, 74, -16, +76, -22, 65, -7, 42, 32, 2, 77, +-51, 105, -101, 96, -134, 57, -150, -15, +-127, -97, -88, -157, -12, -170, 54, -137, +110, -55, 132, 45, 116, 128, 59, 167, +-23, 158, -111, 99, -162, 18, -185, -56, +-151, -96, -87, -103, 9, -75, 85, -31, +141, 10, 144, 29, 96, 27, 12, 9, +-84, -9, -153, -18, -179, 0, -173, 29, +-113, 54, -33, 64, 46, 53, 100, 12, +120, -41, 105, -83, 59, -96, -7, -77, +-69, -26, -112, 36, -127, 87, -128, 105, +-94, 89, -59, 38, -18, -29, 25, -85, +57, -106, 77, -94, 69, -47, 43, 19, +3, 81, -49, 110, -93, 103, -119, 59, +-117, -5, -89, -69, -50, -106, 3, -109, +46, -74, 71, -15, 57, 51, 26, 97, +-16, 115, -59, 96, -77, 51, -86, -9, +-77, -64, -55, -104, -24, -116, 9, -98, +26, -48, 27, 9, 11, 62, 0, 97, +-12, 109, -25, 90, -33, 51, -39, 1, +-42, -47, -52, -81, -62, -87, -54, -78, +-42, -56, -24, -25, -7, 14, 12, 44, +29, 62, 32, 67, 27, 65, 1, 50, +-31, 30, -67, 2, -77, -29, -83, -56, +-79, -74, -56, -81, -20, -69, 9, -38, +25, 9, 26, 51, 24, 82, 1, 96, +-28, 87, -55, 50, -58, 4, -56, -41, +-39, -74, -18, -88, 3, -74, 10, -40, +1, -1, -18, 27, -34, 48, -67, 51, +-74, 39, -71, 17, -39, -4, -10, -22, +24, -24, 43, -14, 48, 2, 26, 18, +-12, 31, -47, 29, -73, 15, -104, -7, +-102, -26, -84, -46, -48, -57, -8, -55, +26, -35, 53, -3, 59, 35, 47, 67, +25, 81, -18, 73, -60, 50, -104, 12, +-111, -30, -107, -66, -79, -76, -44, -70, +2, -47, 48, -17, 68, 14, 67, 32, +45, 40, -5, 38, -52, 29, -96, 19, +-108, 13, -96, 9, -74, 4, -39, -9, +-2, -21, 33, -40, 42, -51, 39, -46, +16, -21, -25, 11, -49, 45, -67, 69, +-65, 67, -56, 32, -40, -12, -18, -57, +-3, -86, 4, -84, -1, -41, -11, 19, +-23, 78, -45, 109, -49, 102, -46, 53, +-37, -19, -26, -88, -17, -128, -4, -124, +-6, -72, 2, 4, -3, 81, -14, 125, +-24, 127, -41, 82, -50, 15, -60, -51, +-65, -93, -63, -100, -45, -70, -21, -20, +0, 29, 22, 52, 37, 53, 29, 28, +3, -1, -42, -20, -73, -13, -93, 8, +-96, 38, -78, 62, -42, 62, 6, 25, +43, -30, 62, -87, 47, -125, 1, -129, +-53, -85, -97, -12, -112, 69, -109, 132, +-70, 164, -18, 140, 39, 77, 71, -3, +77, -77, 54, -129, 12, -137, -53, -106, +-96, -51, -120, 8, -115, 57, -102, 74, +-68, 59, -31, 21, 10, -13, 41, -32, +55, -22, 57, 16, 43, 62, 18, 91, +-7, 97, -51, 64, -93, -5, -135, -94, +-145, -160, -136, -189, -96, -162, -36, -79, +41, 42, 100, 150, 131, 218, 114, 232, +65, 183, -25, 73, -104, -53, -175, -157, +-193, -211, -163, -205, -96, -137, -2, -39, +74, 55, 113, 123, 105, 146, 64, 120, +-1, 67, -78, 10, -122, -33, -136, -55, +-109, -49, -66, -28, -15, -8, 34, -6, +51, -12, 38, -26, 8, -35, -26, -28, +-43, 1, -62, 35, -60, 64, -51, 79, +-38, 68, -28, 24, -22, -31, -16, -81, +-31, -106, -29, -100, -24, -53, -8, 13, +1, 80, -2, 121, -3, 126, -18, 89, +-51, 26, -71, -45, -80, -106, -69, -142, +-55, -130, -28, -79, 10, -7, 37, 63, +47, 123, 24, 144, -5, 124, -47, 71, +-83, 4, -99, -65, -103, -115, -76, -129, +-43, -106, 2, -57, 39, 6, 53, 58, +49, 85, 26, 84, -15, 65, -63, 27, +-94, -9, -104, -29, -96, -32, -71, -26, +-39, -11, -6, 0, 30, -2, 31, -18, +29, -27, 2, -28, -16, -17, -37, 5, +-42, 43, -46, 69, -52, 75, -56, 55, +-54, 15, -56, -36, -55, -81, -48, -98, +-24, -82, -6, -46, 18, 12, 27, 64, +30, 94, 14, 88, -19, 59, -52, 12, +-64, -28, -72, -48, -61, -45, -54, -30, +-37, -10, -42, 4, -35, 0, -42, -24, +-34, -45, -26, -50, -8, -31, 26, 8, +61, 64, 70, 112, 51, 133, 0, 114, +-69, 56, -146, -31, -187, -117, -183, -172, +-137, -179, -60, -141, 28, -53, 107, 51, +148, 136, 137, 177, 84, 173, -2, 118, +-76, 36, -142, -45, -156, -104, -139, -134, +-99, -123, -47, -82, 1, -30, 32, 14, +34, 50, 26, 65, 6, 62, -11, 46, +-25, 32, -30, 17, -25, 1, -19, -11, +-33, -23, -40, -37, -54, -42, -57, -40, +-61, -29, -54, -12, -39, 19, -27, 47, +-8, 63, 2, 60, 13, 40, 8, 1, +-2, -42, -11, -73, -24, -83, -36, -70, +-52, -29, -59, 23, -64, 72, -72, 99, +-61, 102, -34, 71, -10, 15, 8, -46, +12, -90, 19, -113, 9, -105, -4, -65, +-27, -5, -48, 51, -58, 96, -70, 118, +-55, 106, -49, 61, -37, 9, -36, -45, +-29, -87, -24, -106, -15, -94, -4, -65, +18, -24, 26, 21, 27, 64, 4, 87, +-17, 92, -61, 79, -108, 48, -138, 2, +-135, -36, -98, -65, -44, -82, 27, -82, +92, -55, 114, -18, 113, 18, 65, 50, +-4, 71, -96, 66, -156, 42, -182, 8, +-157, -25, -106, -50, -27, -52, 46, -38, +99, -16, 101, 11, 80, 33, 29, 37, +-28, 27, -92, 7, -125, -18, -118, -39, +-91, -41, -48, -27, -9, -1, 20, 21, +33, 38, 29, 42, 16, 33, -13, 14, +-35, -6, -62, -27, -69, -39, -71, -38, +-63, -31, -45, -23, -18, -6, -3, 13, +7, 33, 10, 48, 19, 59, 13, 53, +-5, 32, -35, 3, -64, -30, -77, -72, +-86, -99, -74, -98, -59, -72, -22, -30, +7, 35, 32, 95, 45, 130, 32, 128, +4, 101, -34, 44, -66, -27, -87, -85, +-87, -117, -66, -123, -36, -99, -12, -52, +7, 3, 13, 45, 9, 73, -22, 83, +-46, 75, -54, 52, -46, 29, -22, 6, +-5, -12, 14, -28, 12, -39, -1, -50, +-30, -57, -59, -55, -82, -38, -96, -14, +-78, 16, -41, 44, 3, 64, 40, 66, +64, 56, 57, 29, 22, -9, -28, -39, +-61, -59, -95, -68, -101, -53, -100, -21, +-66, 13, -23, 36, 11, 54, 30, 52, +33, 30, 24, -1, -4, -22, -26, -34, +-42, -35, -53, -22, -47, 2, -46, 23, +-40, 36, -44, 36, -42, 18, -39, -16, +-31, -42, -28, -56, -6, -48, 14, -24, +40, 16, 28, 54, 7, 81, -37, 83, +-70, 56, -101, 6, -109, -42, -95, -75, +-63, -86, -11, -76, 40, -39, 71, 7, +70, 46, 36, 64, -11, 64, -62, 43, +-96, 11, -104, -15, -79, -28, -42, -30, +-9, -15, 15, 5, 28, 19, 9, 17, +-18, 4, -55, -17, -63, -36, -62, -47, +-34, -40, -1, -23, 27, 5, 36, 38, +17, 65, -9, 71, -46, 61, -76, 37, +-94, 5, -86, -35, -62, -61, -31, -73, +-2, -68, 21, -49, 22, -19, 14, 11, +-3, 39, -10, 58, -10, 64, -18, 51, +-18, 30, -26, 4, -33, -19, -55, -41, +-68, -49, -79, -43, -83, -27, -68, -7, +-37, 14, 10, 28, 46, 34, 71, 32, +73, 24, 47, 7, 0, -8, -50, -23, +-91, -36, -113, -46, -121, -39, -98, -19, +-56, 9, -8, 38, 28, 64, 43, 74, +52, 64, 28, 37, 2, 0, -35, -53, +-47, -98, -56, -116, -55, -100, -45, -62, +-31, 2, -24, 66, -23, 113, -23, 132, +-22, 119, -19, 72, -6, 10, 5, -48, +4, -87, -9, -108, -28, -101, -44, -74, +-61, -44, -72, -14, -66, 24, -54, 55, +-11, 74, 21, 85, 57, 89, 62, 78, +47, 54, 0, 15, -41, -36, -85, -86, +-118, -121, -125, -135, -99, -117, -64, -68, +-14, 5, 31, 78, 71, 129, 85, 151, +63, 144, 22, 101, -20, 29, -53, -50, +-84, -111, -103, -147, -93, -142, -75, -100, +-41, -33, -16, 39, 14, 102, 15, 131, +16, 119, 3, 72, -9, 11, -20, -53, +-25, -96, -25, -101, -16, -73, -11, -22, +-4, 37, -2, 76, -15, 84, -42, 55, +-70, 7, -77, -45, -76, -86, -52, -92, +-20, -56, 20, 2, 53, 65, 62, 105, +54, 110, 17, 71, -28, 6, -80, -64, +-109, -113, -112, -128, -82, -100, -36, -38, +16, 34, 54, 94, 66, 126, 51, 111, +19, 63, -29, 2, -77, -51, -100, -84, +-100, -85, -66, -62, -33, -30, 12, -2, +45, 19, 56, 27, 43, 22, 15, 15, +-16, 14, -52, 15, -68, 27, -78, 39, +-68, 43, -51, 26, -31, -2, -14, -36, +1, -67, 3, -81, 5, -67, 2, -36, +1, 4, -8, 45, -15, 76, -14, 82, +-17, 66, -20, 31, -28, -13, -29, -52, +-33, -68, -37, -62, -37, -39, -38, -6, +-32, 29, -34, 47, -21, 48, -17, 37, +-3, 10, 10, -25, 26, -41, 17, -39, +13, -24, 0, -5, -9, 22, -37, 39, +-63, 41, -84, 24, -81, 1, -68, -21, +-52, -32, -26, -29, 3, -15, 39, -3, +59, 8, 66, 12, 54, 11, 18, 2, +-21, -6, -62, -7, -85, 0, -99, 12, +-87, 24, -68, 26, -37, 16, -9, -7, +23, -31, 34, -51, 37, -52, 20, -34, +9, 3, -3, 40, -11, 69, -21, 79, +-41, 61, -52, 20, -65, -30, -63, -72, +-56, -88, -36, -71, -13, -31, 13, 16, +34, 59, 39, 79, 33, 67, 6, 31, +-27, -13, -59, -50, -75, -64, -73, -52, +-39, -19, -7, 21, 22, 51, 31, 56, +32, 38, 11, -1, -19, -40, -46, -65, +-63, -65, -58, -39, -44, 6, -14, 50, +10, 75, 22, 75, 14, 50, -6, 3, +-26, -46, -41, -78, -39, -81, -23, -63, +3, -24, 20, 22, 30, 60, 18, 71, +-7, 62, -53, 35, -80, -6, -87, -42, +-62, -60, -31, -59, 13, -38, 50, -8, +67, 21, 61, 35, 27, 39, -17, 28, +-58, 7, -79, -15, -79, -27, -53, -31, +-18, -23, 8, -6, 18, 14, 9, 25, +-5, 30, -25, 28, -35, 21, -44, 6, +-33, -9, -17, -23, 18, -35, 31, -44, +36, -39, 12, -24, -18, -5, -44, 17, +-59, 46, -61, 66, -45, 71, -21, 56, +-9, 29, 1, -12, 3, -55, -1, -89, +-9, -99, -20, -83, -25, -46, -14, 3, +4, 56, 18, 97, 30, 110, 18, 93, +-5, 60, -46, 15, -71, -29, -92, -64, +-86, -81, -66, -80, -29, -65, 12, -44, +51, -19, 80, 3, 82, 23, 63, 44, +24, 63, -20, 73, -58, 75, -84, 66, +-98, 42, -93, -3, -78, -54, -49, -97, +-11, -122, 21, -119, 46, -83, 58, -24, +67, 44, 51, 103, 31, 137, -11, 136, +-45, 105, -80, 47, -97, -19, -100, -76, +-85, -108, -51, -116, -5, -99, 41, -62, +73, -13, 87, 32, 75, 62, 45, 78, +-5, 81, -51, 65, -83, 40, -98, 10, +-102, -18, -87, -44, -50, -62, -5, -62, +42, -48, 66, -26, 81, 8, 64, 41, +36, 57, -2, 54, -31, 34, -59, 0, +-76, -31, -89, -51, -84, -51, -57, -37, +-19, -7, 20, 28, 46, 54, 59, 62, +55, 48, 44, 18, 18, -16, -11, -45, +-43, -58, -71, -54, -77, -34, -71, -4, +-45, 24, -18, 40, 11, 42, 20, 33, +28, 15, 18, -3, 15, -16, 0, -18, +-11, -11, -19, -4, -15, 5, -14, 10, +-9, 9, -7, 1, -20, -7, -34, -20, +-46, -30, -42, -30, -28, -26, -8, -10, +16, 13, 40, 34, 56, 50, 50, 56, +29, 50, -15, 30, -47, -2, -80, -40, +-87, -69, -82, -81, -52, -74, -18, -47, +21, -5, 44, 37, 61, 71, 59, 90, +37, 87, 12, 59, -8, 19, -22, -20, +-33, -53, -45, -74, -61, -77, -67, -71, +-65, -55, -46, -32, -22, -3, 9, 28, +48, 60, 70, 85, 86, 94, 79, 87, +55, 65, -3, 23, -58, -31, -112, -87, +-129, -128, -113, -142, -73, -117, -23, -62, +29, 13, 62, 88, 76, 145, 69, 165, +40, 141, 13, 77, -17, -6, -34, -85, +-41, -140, -30, -155, -20, -123, -21, -58, +-29, 17, -39, 81, -34, 113, -27, 108, +-6, 77, 9, 23, 29, -32, 40, -73, +41, -86, 24, -72, 8, -36, -22, 7, +-46, 44, -53, 61, -46, 60, -24, 43, +-5, 14, 12, -14, 17, -31, 17, -40, +4, -41, -8, -35, -20, -26, -26, -18, +-15, -10, -6, 2, 4, 21, 5, 40, +4, 55, -5, 60, -8, 52, -16, 31, +-6, 0, -7, -33, -6, -60, -10, -75, +-8, -69, -14, -47, -24, -15, -36, 16, +-40, 38, -25, 52, -6, 55, 20, 49, +45, 39, 55, 25, 49, 11, 25, -7, +-8, -27, -35, -49, -55, -65, -75, -71, +-72, -63, -56, -40, -14, -3, 20, 44, +47, 84, 53, 103, 50, 95, 27, 61, +9, 10, -11, -43, -27, -83, -32, -103, +-34, -94, -34, -58, -31, -9, -19, 35, +-10, 61, 3, 68, 5, 57, 14, 35, +24, 9, 26, -14, 27, -27, 15, -30, +-5, -23, -34, -16, -48, -14, -52, -16, +-33, -19, -12, -20, 18, -15, 45, -4, +61, 13, 52, 33, 25, 45, -16, 48, +-54, 43, -81, 24, -92, -5, -68, -34, +-32, -56, 20, -67, 64, -63, 88, -45, +88, -18, 64, 19, 18, 52, -26, 69, +-52, 72, -70, 59, -65, 30, -58, -5, +-43, -37, -27, -58, -2, -64, 6, -56, +19, -36, 24, -9, 39, 17, 57, 35, +65, 44, 60, 41, 34, 30, -10, 14, +-63, -1, -103, -13, -120, -17, -102, -16, +-69, -13, -21, -8, 36, -7, 88, -10, +125, -16, 124, -17, 86, -12, 22, -4, +-33, 7, -87, 21, -101, 37, -99, 43, +-67, 37, -33, 22, 1, 1, 29, -28, +57, -51, 65, -63, 51, -60, 28, -41, +-3, -8, -22, 28, -35, 60, -38, 73, +-30, 65, -19, 42, -11, 6, 5, -34, +22, -64, 31, -76, 38, -68, 13, -38, +-5, 0, -26, 33, -34, 58, -42, 68, +-37, 62, -31, 40, -7, 11, 11, -21, +28, -47, 43, -60, 46, -60, 37, -48, +18, -25, -6, 1, -28, 25, -33, 41, +-41, 49, -34, 48, -24, 40, -16, 22, +-5, 0, -1, -22, 9, -40, 23, -51, +34, -49, 27, -37, 23, -16, 8, 6, +4, 23, -3, 30, -12, 32, -21, 26, +-25, 17, -32, 6, -25, -1, -12, -5, +-1, -5, 14, -7, 7, -8, 2, -10, +4, -17, 11, -21, 12, -20, 12, -16, +6, -7, 5, 4, 8, 15, 3, 26, +5, 32, -5, 30, -15, 24, -34, 15, +-38, 2, -34, -13, -14, -25, -10, -34, +-5, -36, 1, -36, 13, -29, 33, -16, +45, 8, 46, 37, 38, 61, 22, 76, +-5, 74, -26, 54, -50, 15, -69, -32, +-83, -76, -85, -105, -56, -109, -11, -86, +43, -38, 82, 23, 113, 82, 108, 124, +88, 139, 33, 120, -25, 71, -76, -1, +-106, -75, -112, -133, -85, -157, -48, -138, +1, -89, 44, -22, 63, 50, 74, 106, +65, 136, 41, 134, 13, 99, -7, 44, +-19, -15, -19, -66, -21, -97, -30, -103, +-30, -86, -37, -53, -33, -14, -28, 21, +-7, 46, 19, 55, 50, 54, 61, 44, +70, 28, 56, 14, 24, 0, -23, -15, +-69, -26, -96, -31, -92, -34, -61, -31, +-18, -20, 35, -5, 73, 11, 99, 25, +95, 34, 62, 37, 18, 33, -40, 18, +-85, -5, -105, -27, -97, -37, -66, -40, +-14, -36, 25, -21, 63, 1, 83, 23, +89, 43, 70, 56, 40, 58, -6, 48, +-46, 25, -77, -9, -91, -45, -76, -73, +-54, -86, -17, -80, 17, -49, 49, -5, +77, 45, 84, 88, 62, 110, 32, 102, +-4, 66, -40, 14, -60, -43, -71, -89, +-52, -115, -20, -110, 16, -72, 34, -17, +51, 38, 39, 81, 18, 100, -14, 91, +-37, 59, -37, 14, -24, -29, -4, -58, +17, -67, 41, -59, 50, -39, 48, -17, +18, 4, -16, 19, -44, 25, -60, 26, +-53, 26, -34, 24, -2, 21, 25, 17, +37, 14, 29, 4, 33, -13, 19, -28, +4, -38, -15, -43, -20, -35, -15, -16, +2, 6, 9, 27, 12, 42, 2, 46, +-18, 37, -26, 20, -32, 2, -22, -15, +-3, -24, 11, -22, 15, -14, 25, -6, +31, 2, 25, 8, 7, 10, -21, 3, +-29, -5, -29, -12, -11, -15, 7, -10, +26, 0, 25, 9, 20, 18, -7, 25, +-26, 29, -40, 29, -51, 24, -42, 7, +-15, -11, 20, -24, 55, -37, 78, -46, +74, -47, 54, -39, 15, -22, -32, 5, +-70, 36, -88, 58, -75, 70, -46, 71, +-15, 57, 18, 26, 51, -13, 54, -49, +56, -76, 36, -87, 21, -75, 5, -47, +-9, -6, -23, 36, -24, 64, -18, 73, +-18, 64, -25, 43, -38, 16, -36, -10, +-21, -24, 2, -28, 30, -18, 55, -6, +63, 1, 58, 0, 30, -8, -3, -23, +-29, -39, -58, -45, -74, -33, -74, -8, +-39, 26, 4, 62, 48, 87, 66, 93, +67, 80, 42, 45, 8, -5, -17, -57, +-35, -100, -37, -124, -32, -119, -28, -85, +-18, -32, 5, 27, 16, 84, 19, 122, +8, 132, 3, 112, 11, 72, 21, 18, +31, -39, 33, -83, 18, -104, -20, -104, +-44, -89, -66, -58, -58, -23, -40, 12, +-11, 44, 20, 68, 60, 83, 85, 86, +93, 76, 66, 54, 19, 16, -26, -33, +-68, -79, -89, -111, -85, -119, -62, -95, +-26, -48, 15, 14, 48, 77, 73, 122, +81, 135, 60, 111, 34, 53, -4, -22, +-29, -89, -52, -127, -57, -128, -54, -91, +-24, -26, -4, 43, 17, 96, 29, 115, +33, 96, 34, 46, 26, -16, 9, -67, +-3, -92, -13, -83, -20, -48, -16, 3, +-14, 50, -3, 76, 6, 70, 6, 39, +4, -3, 2, -42, 7, -65, 6, -65, +8, -43, -4, -7, -1, 27, -6, 48, +-5, 54, -5, 47, -5, 29, -9, 5, +-5, -17, -2, -31, 13, -33, 28, -30, +27, -21, 18, -15, -2, -9, -16, -3, +-25, 5, -29, 17, -34, 29, -22, 34, +-9, 33, 8, 22, 30, 8, 40, -12, +49, -31, 35, -44, 16, -44, -2, -33, +-13, -8, -29, 22, -36, 40, -41, 41, +-32, 29, -14, 4, 8, -24, 28, -43, +42, -42, 42, -27, 29, 0, 17, 28, +-4, 45, -10, 46, -23, 32, -34, 9, +-32, -18, -19, -39, 2, -43, 14, -27, +22, -3, 24, 17, 29, 27, 15, 20, +3, 1, -15, -22, -25, -40, -31, -43, +-24, -26, -13, 9, 10, 53, 20, 87, +28, 92, 36, 67, 31, 20, 22, -43, +5, -99, -18, -128, -39, -119, -47, -75, +-44, -12, -29, 54, -8, 105, 9, 127, +33, 111, 44, 63, 54, 7, 48, -42, +34, -74, 6, -87, -15, -75, -40, -46, +-45, -10, -49, 17, -44, 30, -32, 30, +-9, 23, 16, 16, 40, 15, 54, 17, +55, 22, 48, 22, 21, 14, -4, -3, +-23, -25, -41, -43, -50, -50, -54, -47, +-37, -33, -6, -10, 32, 19, 50, 46, +60, 59, 45, 55, 25, 38, -7, 11, +-33, -21, -46, -50, -37, -59, -28, -52, +-4, -33, 22, -8, 39, 17, 48, 36, +30, 42, 10, 34, -10, 17, -24, -3, +-35, -19, -29, -28, -13, -29, 10, -23, +32, -10, 33, 1, 29, 10, 15, 15, +-5, 16, -22, 14, -27, 8, -22, -1, +-4, -6, 2, -9, 14, -11, 20, -10, +19, -6, 5, 2, -20, 13, -37, 19, +-38, 21, -18, 21, -2, 19, 20, 12, +31, -2, 34, -17, 29, -28, 9, -31, +-6, -26, -16, -14, -29, 4, -40, 22, +-34, 35, -19, 33, 14, 21, 26, 5, +31, -11, 27, -25, 27, -24, 15, -14, +11, 1, 3, 13, -10, 19, -22, 16, +-42, 5, -45, -11, -38, -25, -21, -30, +0, -23, 22, -3, 47, 21, 72, 38, +79, 47, 58, 42, 18, 21, -34, -11, +-74, -40, -100, -58, -96, -59, -67, -42, +-10, -11, 35, 24, 80, 52, 98, 63, +97, 52, 69, 28, 20, 2, -34, -22, +-69, -36, -87, -36, -82, -26, -50, -14, +-13, -2, 22, 5, 40, 8, 40, 4, +39, -3, 33, -3, 22, 9, 15, 22, +13, 36, 1, 45, -7, 36, -23, 9, +-28, -25, -41, -55, -45, -72, -45, -71, +-26, -44, 0, -1, 40, 43, 73, 78, +83, 91, 77, 74, 44, 36, 0, -13, +-41, -62, -68, -91, -78, -90, -70, -64, +-53, -19, -17, 27, 28, 63, 64, 81, +80, 74, 72, 45, 52, 7, 24, -31, +0, -53, -29, -59, -41, -54, -52, -42, +-54, -18, -52, 6, -37, 24, -2, 36, +27, 49, 46, 56, 55, 51, 61, 36, +55, 10, 40, -22, 7, -52, -31, -79, +-59, -89, -73, -74, -70, -35, -44, 12, +-8, 58, 29, 90, 56, 100, 59, 81, +58, 41, 39, -10, 17, -55, -12, -80, +-32, -81, -40, -62, -34, -31, -22, 0, +-7, 22, 5, 32, 7, 28, 9, 15, +14, 6, 16, 6, 20, 16, 23, 27, +22, 30, 24, 19, 12, -2, -8, -35, +-25, -68, -39, -90, -37, -85, -31, -56, +-10, -3, 8, 58, 31, 109, 40, 131, +43, 116, 31, 66, 15, -5, -5, -76, +-22, -126, -32, -141, -26, -116, -18, -60, +-8, 10, -2, 69, 1, 105, 12, 107, +21, 80, 27, 33, 29, -17, 29, -50, +22, -60, 5, -47, -9, -24, -28, -1, +-36, 14, -47, 13, -39, 2, -20, -12, +14, -20, 42, -14, 59, 3, 54, 25, +40, 49, 11, 60, -16, 47, -35, 16, +-52, -13, -53, -41, -35, -54, -10, -50, +16, -28, 41, 0, 44, 27, 36, 39, +19, 35, 1, 20, -9, 2, -18, -11, +-18, -13, -14, -3, -3, 18, 1, 33, +5, 36, -3, 22, -7, -5, -9, -36, +-10, -56, -2, -61, 12, -42, 22, -4, +27, 36, 27, 64, 21, 72, 12, 57, +-7, 28, -24, -12, -33, -48, -26, -68, +-14, -61, 2, -39, 13, -9, 18, 17, +20, 33, 12, 30, 12, 16, 8, 1, +7, -3, 2, 2, -3, 16, -5, 27, +-4, 28, -6, 14, -14, -14, -25, -47, +-27, -75, -14, -85, 8, -70, 31, -27, +42, 33, 46, 87, 34, 114, 19, 105, +-6, 63, -31, -1, -47, -71, -55, -123, +-39, -136, -16, -109, 19, -50, 46, 20, +59, 80, 51, 113, 34, 110, 9, 68, +-14, 9, -39, -45, -53, -78, -51, -87, +-35, -66, -15, -27, 11, 13, 38, 42, +48, 50, 53, 36, 45, 9, 31, -18, +10, -35, -18, -35, -43, -17, -60, 10, +-62, 36, -51, 44, -19, 35, 14, 14, +52, -13, 75, -38, 82, -52, 66, -50, +36, -31, -12, -1, -50, 30, -77, 47, +-77, 53, -57, 46, -28, 32, 10, 10, +43, -9, 68, -21, 71, -27, 57, -25, +25, -18, -7, -9, -29, -3, -39, 1, +-35, 11, -32, 22, -24, 32, -15, 39, +-3, 41, 11, 37, 24, 27, 24, 10, +28, -11, 24, -31, 21, -41, 14, -43, +6, -36, -6, -21, -19, 4, -28, 29, +-32, 53, -19, 66, -8, 67, 7, 49, +15, 19, 21, -15, 25, -45, 26, -65, +20, -68, 10, -56, 3, -30, -5, 5, +-8, 42, -12, 65, -13, 72, -14, 62, +-18, 39, -22, 7, -14, -28, 2, -55, +24, -67, 33, -61, 32, -46, 33, -25, +24, 1, 11, 23, -12, 40, -28, 48, +-36, 43, -30, 29, -21, 10, -8, -14, +11, -40, 26, -59, 29, -65, 22, -62, +16, -45, 11, -15, 4, 19, -3, 42, +-1, 51, 2, 42, 9, 18, 4, -15, +-3, -44, -9, -60, -13, -54, -18, -32, +-21, -3, -12, 19, 3, 30, 23, 22, +33, 1, 36, -24, 30, -41, 17, -43, +0, -29, -15, -2, -21, 30, -21, 53, +-18, 52, -19, 28, -11, -11, 0, -52, +16, -79, 24, -80, 28, -53, 25, -9, +28, 38, 23, 72, 12, 84, -1, 66, +-17, 26, -28, -21, -38, -55, -33, -65, +-14, -46, 8, -8, 21, 35, 26, 63, +26, 70, 20, 53, 8, 16, -8, -25, +-20, -50, -25, -52, -18, -28, -8, 11, +11, 54, 20, 84, 25, 89, 11, 68, +-9, 32, -22, -11, -25, -44, -21, -59, +-14, -49, 1, -23, 19, 12, 34, 39, +33, 54, 24, 52, 8, 38, -10, 22, +-28, 12, -34, 2, -22, 1, 1, 6, +17, 12, 20, 10, 22, 0, 20, -17, +11, -26, -10, -27, -23, -19, -21, -1, +-4, 23, 12, 44, 25, 53, 32, 46, +30, 24, 19, -8, -7, -36, -31, -53, +-43, -56, -36, -44, -24, -17, -4, 13, +24, 33, 55, 38, 62, 33, 46, 17, +23, -7, 0, -28, -22, -37, -43, -42, +-49, -38, -41, -33, -16, -24, 6, -21, +26, -16, 36, -12, 41, -3, 39, 7, +27, 20, 15, 31, 3, 36, -6, 21, +-18, -9, -26, -49, -29, -84, -24, -106, +-18, -104, -13, -77, -4, -29, 16, 26, +37, 73, 54, 97, 57, 94, 45, 63, +27, 14, -7, -41, -35, -84, -55, -109, +-57, -104, -48, -76, -30, -32, -4, 9, +29, 38, 56, 50, 63, 48, 54, 31, +35, 12, 14, 0, -6, -4, -23, 1, +-35, 12, -35, 16, -31, 15, -22, 2, +-9, -21, 6, -46, 18, -57, 20, -52, +21, -27, 22, 11, 21, 57, 14, 96, +5, 113, -5, 103, -11, 72, -15, 25, +-13, -27, -6, -69, -2, -85, 0, -77, +3, -47, 10, -8, 13, 35, 11, 69, +0, 87, -3, 83, -3, 65, 7, 40, +15, 18, 20, 2, 20, -7, 14, -9, +5, -3, -11, -2, -21, -4, -25, -11, +-23, -13, -15, -10, 2, 1, 22, 21, +36, 43, 36, 58, 28, 61, 15, 46, +3, 23, -11, -4, -23, -28, -21, -46, +-14, -46, 0, -31, 8, -5, 15, 18, +14, 32, 8, 35, -6, 27, -15, 5, +-13, -13, -8, -25, 6, -28, 19, -22, +31, -8, 33, 2, 24, 12, 5, 9, +-19, -2, -37, -16, -46, -28, -40, -35, +-17, -37, 15, -34, 42, -20, 59, -11, +60, -8, 51, -9, 21, -14, -9, -24, +-38, -29, -53, -28, -50, -22, -32, -15, +-7, -8, 18, -4, 36, -4, 41, -10, +36, -18, 25, -29, 13, -36, 0, -38, +-13, -28, -22, -17, -21, -4, -14, 0, +-10, 0, -9, -8, -9, -15, 3, -24, +17, -25, 29, -18, 34, -6, 36, 7, +28, 20, 15, 22, -4, 14, -20, -4, +-30, -23, -38, -38, -37, -46, -20, -41, +8, -21, 32, 7, 44, 35, 40, 51, +34, 55, 28, 46, 17, 30, 1, 8, +-12, -8, -17, -16, -21, -13, -22, -6, +-23, 2, -17, 8, -13, 13, -5, 10, +4, 6, 23, 9, 45, 24, 58, 45, +53, 67, 31, 82, 5, 82, -22, 62, +-47, 28, -69, -14, -71, -50, -47, -75, +-6, -74, 31, -44, 58, 5, 76, 54, +81, 92, 60, 113, 18, 111, -20, 85, +-47, 46, -58, 0, -59, -36, -44, -55, +-18, -59, 15, -50, 34, -30, 39, -5, +36, 19, 37, 32, 35, 42, 22, 48, +8, 47, 0, 39, -9, 26, -22, 4, +-33, -20, -37, -44, -28, -60, -17, -61, +-1, -46, 23, -21, 48, 10, 62, 31, +55, 43, 33, 38, 4, 18, -17, -14, +-40, -44, -52, -65, -51, -67, -32, -53, +-5, -30, 24, -5, 43, 15, 51, 21, +43, 13, 24, -6, 5, -29, -5, -49, +-9, -57, -13, -55, -16, -44, -11, -33, +3, -24, 12, -16, 12, -15, 12, -16, +6, -11, 3, -6, 0, -3, 2, 0, +4, 0, 6, -12, 5, -28, 3, -46, +6, -57, 16, -59, 17, -44, 13, -21, +7, 6, 2, 31, -3, 42, -12, 35, +-18, 15, -20, -14, -8, -39, 4, -50, +14, -39, 25, -16, 37, 12, 38, 38, +22, 53, 2, 47, -11, 27, -21, 0, +-33, -25, -36, -38, -29, -32, -10, -9, +9, 22, 21, 50, 26, 70, 32, 72, +33, 60, 25, 34, 12, 8, 3, -16, +2, -33, -2, -35, -13, -16, -25, 7, +-24, 29, -19, 46, -17, 57, -10, 58, +11, 53, 35, 42, 48, 32, 47, 19, +36, 11, 27, 3, 10, 1, -14, 3, +-39, 9, -49, 15, -47, 22, -38, 25, +-23, 26, -1, 21, 26, 14, 47, 5, +57, 2, 57, 4, 56, 13, 42, 25, +14, 31, -19, 26, -43, 17, -58, 0, +-61, -19, -52, -36, -34, -40, -2, -32, +29, -12, 57, 8, 71, 23, 73, 29, +55, 27, 24, 11, -11, -11, -37, -31, +-50, -40, -48, -41, -42, -31, -28, -19, +-5, -11, 19, -10, 34, -12, 35, -21, +32, -29, 29, -32, 25, -27, 23, -18, +14, -5, 2, 0, -10, -9, -20, -28, +-30, -49, -31, -67, -26, -68, -15, -54, +0, -25, 23, 6, 46, 31, 61, 42, +55, 35, 37, 3, 10, -41, -17, -78, +-38, -97, -48, -96, -42, -72, -29, -32, +-7, 13, 15, 49, 33, 66, 44, 58, +44, 34, 32, 5, 15, -21, 2, -41, +-6, -48, -13, -42, -20, -29, -25, -18, +-27, -8, -24, -3, -14, 3, 3, 7, +21, 17, 38, 29, 50, 42, 55, 48, +51, 47, 28, 36, -6, 19, -41, -4, +-62, -22, -68, -30, -57, -26, -28, -14, +11, 6, 46, 26, 69, 41, 77, 47, +64, 49, 35, 45, -1, 42, -33, 41, +-57, 43, -61, 44, -51, 40, -31, 28, +-8, 11, 12, -11, 30, -30, 42, -45, +48, -39, 43, -15, 32, 23, 22, 60, +11, 93, -4, 105, -23, 96, -39, 62, +-45, 15, -39, -33, -23, -68, 0, -80, +23, -65, 47, -36, 61, 5, 62, 45, +43, 71, 15, 77, -20, 65, -47, 33, +-59, -2, -51, -31, -27, -46, 2, -51, +25, -42, 39, -28, 47, -11, 45, 4, +28, 17, 2, 21, -17, 18, -23, 8, +-18, -4, -10, -21, 1, -39, 11, -54, +12, -61, 5, -60, -3, -47, -1, -25, +7, 5, 15, 32, 13, 50, 14, 45, +19, 19, 22, -21, 8, -66, -10, -106, +-23, -123, -23, -112, -17, -68, -9, -12, +11, 41, 34, 82, 42, 97, 33, 76, +16, 28, -2, -34, -16, -90, -28, -128, +-39, -130, -33, -101, -8, -53, 24, 8, +39, 63, 44, 94, 42, 96, 36, 73, +13, 32, -16, -16, -36, -60, -42, -88, +-38, -95, -32, -84, -12, -55, 15, -16, +41, 30, 53, 69, 53, 98, 45, 108, +32, 101, 4, 72, -28, 23, -53, -32, +-62, -79, -56, -110, -38, -112, -13, -83, +21, -26, 60, 44, 78, 111, 78, 154, +59, 162, 29, 131, -8, 71, -43, 0, +-68, -61, -67, -101, -47, -104, -23, -74, +1, -22, 27, 32, 49, 72, 56, 88, +46, 83, 26, 64, 10, 43, 1, 22, +-2, 18, -6, 26, -12, 35, -13, 32, +-23, 18, -30, -12, -28, -48, -16, -73, +-4, -76, 13, -53, 33, -4, 56, 54, +67, 108, 56, 132, 31, 119, 3, 72, +-26, 5, -48, -59, -58, -100, -52, -108, +-29, -84, -4, -41, 21, 6, 40, 39, +53, 50, 53, 33, 37, 6, 15, -18, +-5, -23, -12, -13, -16, 7, -12, 23, +-4, 29, 5, 18, 3, -13, -3, -55, +-12, -88, -14, -103, -9, -91, -1, -52, +12, 0, 34, 47, 53, 78, 54, 77, +39, 45, 16, -6, -6, -53, -29, -86, +-47, -96, -54, -80, -42, -44, -14, -8, +16, 19, 38, 31, 50, 26, 57, 6, +51, -14, 31, -29, 7, -33, -5, -30, +-14, -17, -26, -5, -37, 2, -34, 0, +-20, -8, -4, -15, 8, -16, 21, -11, +37, 5, 47, 18, 48, 22, 38, 15, +22, 1, 4, -20, -15, -36, -30, -41, +-37, -28, -31, -1, -18, 31, 2, 53, +20, 61, 39, 48, 51, 20, 48, -14, +29, -38, 9, -49, -3, -40, -8, -11, +-16, 33, -21, 70, -19, 89, -13, 81, +-2, 49, 4, 2, 12, -40, 19, -68, +28, -67, 32, -39, 31, 12, 27, 61, +18, 94, 4, 101, -16, 84, -31, 44, +-39, -2, -33, -42, -18, -63, 7, -60, +33, -34, 55, 3, 63, 41, 54, 62, +27, 65, -6, 48, -35, 18, -46, -12, +-42, -28, -26, -28, 0, -15, 29, 2, +53, 19, 61, 28, 49, 25, 26, 10, +-4, -7, -32, -23, -45, -31, -36, -31, +-13, -20, 16, -6, 35, 9, 46, 14, +43, 14, 35, 7, 16, 1, -7, -1, +-25, 0, -28, -1, -16, -5, 1, -12, +14, -22, 21, -39, 24, -53, 16, -59, +6, -49, 1, -27, 3, 9, 6, 45, +11, 71, 16, 74, 18, 53, 18, 8, +11, -47, -1, -96, -13, -121, -14, -120, +-7, -87, 7, -31, 18, 34, 28, 83, +30, 105, 25, 94, 12, 55, 0, -1, +-10, -52, -13, -88, -7, -96, 5, -78, +19, -45, 33, -8, 36, 24, 26, 43, +11, 45, -4, 32, -16, 19, -21, 6, +-15, -2, 2, -8, 20, -11, 38, -17, +46, -21, 39, -24, 19, -20, 2, -13, +-9, 5, -13, 30, -14, 56, -10, 66, +2, 58, 14, 27, 23, -14, 23, -56, +17, -77, 11, -75, 10, -45, 14, 4, +22, 64, 28, 111, 28, 127, 20, 101, +4, 47, -11, -24, -21, -83, -25, -114, +-24, -108, -9, -66, 14, 2, 40, 68, +59, 112, 65, 121, 55, 98, 33, 50, +1, -5, -31, -51, -48, -74, -48, -70, +-35, -42, -16, -7, 7, 26, 34, 46, +57, 47, 68, 35, 57, 21, 34, 8, +15, -2, -1, -6, -20, -6, -30, -9, +-29, -16, -17, -26, -6, -33, 9, -36, +28, -26, 46, -7, 56, 18, 55, 42, +40, 59, 25, 52, 9, 29, -12, -10, +-33, -50, -43, -84, -34, -98, -14, -88, +7, -53, 32, -6, 56, 43, 74, 76, +74, 87, 59, 75, 32, 43, 0, -1, +-32, -47, -55, -83, -63, -99, -50, -93, +-23, -68, 8, -32, 42, 7, 70, 40, +87, 61, 85, 62, 64, 54, 28, 38, +-9, 14, -40, -9, -62, -27, -67, -44, +-47, -55, -17, -56, 15, -46, 43, -33, +66, -17, 76, 1, 69, 23, 47, 42, +19, 57, -1, 58, -18, 52, -29, 33, +-32, 7, -21, -26, -5, -51, 10, -65, +19, -62, 27, -46, 29, -16, 28, 17, +26, 46, 28, 62, 29, 67, 24, 58, +14, 40, 3, 15, -3, -7, -7, -26, +-12, -35, -10, -39, -3, -34, 10, -22, +21, -5, 28, 15, 33, 35, 33, 52, +24, 67, 13, 66, 7, 52, 6, 24, +8, -11, 7, -47, 4, -69, 2, -75, +7, -60, 8, -23, 6, 24, 10, 64, +24, 92, 30, 98, 35, 76, 34, 30, +31, -24, 24, -74, 12, -99, -3, -93, +-14, -59, -13, -10, -7, 43, 0, 79, +11, 88, 29, 67, 40, 32, 37, -9, +24, -44, 18, -66, 16, -61, 15, -39, +13, -5, 12, 22, 14, 35, 13, 30, +3, 16, -9, -9, -15, -30, -9, -39, +-2, -28, 13, -8, 32, 16, 56, 31, +70, 33, 65, 21, 41, -1, 13, -29, +-17, -47, -39, -53, -53, -41, -45, -21, +-19, 2, 20, 18, 55, 28, 74, 26, +78, 14, 70, -5, 47, -15, 12, -17, +-14, -12, -28, -8, -28, -2, -22, -2, +-9, -5, 5, -13, 20, -19, 27, -20, +28, -8, 27, 4, 35, 18, 43, 30, +43, 37, 38, 28, 28, 10, 10, -13, +-12, -29, -30, -38, -36, -34, -30, -17, +-11, 8, 18, 27, 50, 44, 69, 46, +75, 33, 66, 9, 38, -11, 2, -27, +-26, -30, -39, -24, -35, -5, -17, 17, +6, 35, 35, 41, 53, 37, 60, 25, +49, 8, 31, -14, 12, -26, 2, -31, +-2, -24, 3, -9, 6, 10, 16, 19, +21, 26, 20, 31, 12, 33, 8, 28, +12, 21, 19, 12, 30, 3, 39, -10, +47, -23, 45, -37, 28, -41, -1, -35, +-25, -21, -34, 2, -27, 35, -9, 66, +19, 84, 52, 78, 77, 52, 81, 9, +65, -42, 36, -89, 3, -114, -24, -113, +-36, -76, -34, -16, -13, 51, 14, 102, +40, 126, 52, 111, 55, 67, 45, 6, +26, -53, 7, -98, -1, -113, 0, -99, +13, -62, 28, -16, 33, 31, 31, 58, +20, 64, 7, 53, -9, 34, -13, 13, +-8, -5, 13, -19, 35, -26, 54, -31, +62, -36, 58, -42, 37, -43, 12, -41, +-13, -26, -23, -3, -19, 26, -2, 53, +17, 69, 35, 62, 48, 34, 49, -6, +36, -42, 16, -71, 1, -80, -7, -65, +-4, -31, 14, 6, 33, 43, 43, 65, +44, 61, 38, 34, 25, 2, 5, -27, +-7, -40, -11, -38, -4, -21, 11, -1, +34, 17, 51, 24, 61, 21, 51, 8, +32, -9, 8, -20, -8, -19, -18, -7, +-13, 12, 0, 27, 21, 38, 37, 36, +48, 21, 53, -2, 47, -19, 33, -29, +17, -27, 2, -13, -9, 9, -5, 26, +1, 39, 9, 36, 16, 23, 28, 3, +37, -13, 45, -21, 43, -17, 42, -9, +36, 8, 27, 22, 14, 28, 4, 27, +-10, 23, -17, 11, -15, -2, -4, -11, +14, -11, 40, -11, 63, -6, 73, 0, +64, 9, 49, 10, 28, 9, 5, 7, +-18, 10, -32, 10, -26, 8, -6, 4, +19, 1, 42, -8, 63, -14, 65, -18, +59, -20, 45, -20, 30, -7, 11, 7, +2, 19, -6, 26, -2, 27, 4, 15, +17, -2, 21, -21, 23, -35, 25, -47, +32, -44, 41, -30, 48, -6, 52, 20, +50, 42, 39, 53, 20, 47, 1, 24, +-17, -7, -27, -45, -24, -74, -6, -84, +19, -72, 54, -43, 79, 1, 87, 44, +80, 75, 59, 81, 28, 66, -2, 30, +-27, -13, -35, -57, -31, -82, -13, -84, +8, -63, 38, -35, 58, 0, 66, 28, +61, 45, 54, 46, 43, 37, 34, 20, +26, 4, 18, -5, 9, -7, 0, -12, +-4, -17, -9, -26, -5, -37, 3, -45, +19, -41, 37, -27, 65, -1, 83, 31, +85, 62, 65, 77, 38, 70, 7, 41, +-19, 0, -39, -41, -43, -66, -31, -71, +1, -52, 34, -15, 62, 28, 75, 56, +78, 64, 62, 49, 37, 22, 13, -10, +0, -28, -7, -29, -5, -14, 5, 8, +21, 29, 35, 38, 38, 32, 29, 12, +15, -16, 11, -43, 14, -48, 23, -31, +30, 6, 42, 43, 50, 67, 56, 68, +45, 49, 32, 12, 14, -31, 1, -65, +-12, -73, -13, -57, -3, -20, 19, 22, +38, 57, 52, 72, 61, 63, 65, 34, +57, 2, 42, -28, 24, -42, 6, -44, +-6, -31, -11, -14, -9, 3, 2, 8, +17, 10, 30, 6, 45, 3, 56, 9, +60, 24, 55, 35, 46, 38, 29, 28, +13, 6, -3, -27, -9, -57, -12, -77, +-4, -73, 9, -49, 28, -3, 41, 46, +59, 81, 65, 91, 61, 75, 45, 32, +29, -19, 13, -66, 2, -93, -4, -94, +-3, -66, 7, -25, 21, 19, 40, 49, +51, 61, 57, 51, 49, 28, 37, 0, +20, -24, 14, -39, 8, -37, 10, -28, +11, -14, 24, -4, 36, 2, 49, 3, +50, 1, 44, -1, 29, 1, 17, 5, +5, 11, -1, 13, 0, 11, 8, 1, +21, -11, 35, -22, 48, -25, 57, -24, +62, -13, 54, 2, 36, 21, 19, 30, +10, 29, 5, 13, 5, -4, 1, -20, +6, -31, 15, -35, 32, -28, 44, -12, +54, 11, 55, 28, 59, 39, 49, 41, +39, 33, 24, 14, 12, -6, -5, -25, +-13, -34, -13, -35, 3, -27, 21, -14, +40, 3, 56, 19, 65, 31, 69, 32, +64, 30, 46, 24, 21, 18, 1, 10, +-15, 3, -14, -8, -4, -14, 11, -20, +22, -22, 38, -27, 48, -24, 57, -13, +54, 6, 51, 25, 40, 47, 29, 63, +16, 66, 14, 47, 7, 19, 1, -17, +-4, -53, 3, -77, 15, -80, 35, -62, +52, -22, 65, 24, 68, 62, 66, 82, +53, 81, 30, 58, 4, 21, -20, -18, +-31, -48, -25, -63, 3, -60, 34, -41, +67, -14, 82, 9, 87, 22, 73, 23, +52, 20, 17, 13, -7, 8, -26, 6, +-23, 13, -8, 14, 23, 10, 49, 0, +62, -15, 61, -36, 56, -52, 42, -55, +27, -36, 12, -4, 5, 32, 8, 58, +19, 69, 31, 59, 38, 31, 40, -10, +32, -49, 22, -73, 14, -72, 16, -53, +25, -21, 39, 13, 44, 41, 49, 51, +40, 49, 27, 31, 10, 3, 5, -22, +-1, -31, 7, -31, 25, -22, 53, -12, +70, -2, 76, 1, 58, 1, 33, -7, +5, -10, -15, -8, -25, 0, -18, 11, +3, 25, 32, 30, 64, 28, 81, 16, +80, -2, 61, -22, 35, -34, 3, -37, +-11, -28, -16, -12, -5, 8, 10, 22, +29, 31, 42, 28, 52, 19, 48, 8, +40, -2, 29, -8, 26, -5, 26, 1, +35, 7, 40, 5, 43, -3, 33, -17, +18, -26, 0, -32, -8, -26, -8, -10, +5, 18, 26, 44, 53, 67, 77, 70, +88, 54, 83, 19, 54, -19, 16, -57, +-19, -79, -35, -83, -38, -59, -14, -23, +14, 24, 49, 64, 70, 89, 86, 87, +81, 65, 61, 32, 25, -6, 4, -44, +-4, -64, 1, -67, 12, -52, 25, -29, +30, 1, 33, 21, 32, 32, 30, 33, +29, 32, 27, 28, 30, 25, 35, 19, +44, 12, 50, -3, 50, -17, 36, -34, +20, -42, 4, -42, 4, -31, 8, -9, +17, 22, 25, 42, 41, 51, 49, 42, +53, 19, 44, -13, 36, -38, 22, -51, +21, -48, 26, -29, 38, 7, 43, 40, +42, 57, 33, 47, 21, 18, 12, -22, +4, -53, 2, -70, 9, -63, 27, -33, +46, 12, 69, 50, 74, 74, 71, 67, +52, 36, 30, -6, 0, -45, -12, -70, +-18, -64, -11, -37, 2, -1, 24, 31, +40, 52, 59, 45, 67, 21, 69, -14, +57, -39, 44, -45, 29, -33, 22, -8, +11, 22, 3, 40, -4, 42, -9, 26, +-5, -3, 9, -34, 30, -48, 49, -45, +67, -25, 78, 4, 81, 33, 68, 44, +47, 39, 11, 17, -18, -9, -38, -35, +-28, -49, -8, -42, 22, -14, 44, 16, +66, 41, 71, 45, 72, 31, 59, 5, +42, -22, 21, -39, 10, -40, 7, -27, +17, -3, 24, 19, 26, 32, 23, 28, +18, 12, 14, -8, 10, -20, 15, -23, +27, -13, 48, 5, 63, 26, 73, 37, +70, 32, 59, 9, 33, -19, 8, -46, +-15, -55, -20, -45, -17, -17, 2, 15, +21, 44, 46, 58, 63, 53, 74, 30, +69, 3, 57, -23, 38, -34, 23, -34, +11, -20, 9, -3, 6, 15, 6, 19, +5, 14, 5, 2, 15, -11, 29, -16, +43, -3, 45, 17, 51, 35, 55, 40, +59, 38, 45, 21, 29, -1, 4, -25, +-10, -40, -17, -43, -7, -27, 5, -5, +29, 20, 45, 30, 61, 28, 65, 16, +60, 5, 46, -10, 35, -17, 20, -11, +8, 10, 3, 26, 10, 34, 19, 27, +23, 10, 25, -19, 27, -45, 30, -62, +31, -60, 38, -42, 40, -9, 44, 26, +41, 57, 41, 70, 35, 69, 27, 52, +11, 25, 5, -9, -1, -36, 5, -54, +10, -62, 27, -66, 38, -57, 48, -38, +50, -13, 53, 18, 45, 50, 37, 71, +28, 82, 18, 76, 9, 52, 7, 11, +9, -37, 10, -78, 15, -100, 19, -101, +31, -76, 39, -32, 47, 20, 49, 59, +50, 83, 43, 80, 39, 58, 29, 25, +21, -11, 8, -37, 1, -48, -2, -51, +14, -45, 25, -33, 39, -18, 43, -5, +45, 10, 39, 21, 35, 33, 27, 39, +25, 41, 18, 37, 14, 23, 16, -5, +24, -33, 28, -54, 26, -60, 22, -52, +19, -27, 24, 5, 28, 42, 36, 64, +37, 70, 40, 55, 36, 25, 37, -14, +27, -43, 20, -59, 8, -54, 6, -36, +6, -10, 21, 12, 34, 32, 44, 43, +42, 42, 40, 29, 35, 14, 30, 3, +21, -1, 16, -3, 14, -5, 17, -7, +24, -11, 30, -18, 37, -25, 37, -24, +30, -12, 20, 5, 16, 26, 14, 42, +20, 53, 25, 48, 36, 31, 40, 8, +42, -12, 37, -34, 33, -43, 18, -40, +10, -27, 5, -11, 11, 9, 18, 21, +34, 28, 40, 28, 45, 24, 42, 15, +38, 9, 31, 0, 24, -6, 16, -11, +14, -11, 18, -13, 26, -14, 39, -19, +44, -17, 43, -10, 28, 2, 16, 9, +6, 14, 5, 15, 4, 17, 12, 15, +22, 10, 43, 1, 59, -4, 70, -11, +62, -11, 42, -11, 15, -12, -2, -16, +-16, -17, -19, -19, -11, -16, 8, -11, +33, 0, 56, 10, 68, 24, 72, 29, +61, 28, 42, 17, 21, 1, 4, -15, +-7, -28, -9, -39, -1, -43, 10, -39, +27, -25, 35, -6, 41, 14, 36, 25, +37, 26, 39, 18, 45, 9, 46, -2, +49, -10, 42, -16, 36, -17, 19, -19, +2, -16, -16, -13, -21, -12, -14, -15, +3, -11, 24, -5, 58, 1, 86, 10, +94, 21, 85, 23, 63, 20, 29, 11, +-8, 0, -37, -14, -50, -25, -39, -34, +-12, -31, 24, -20, 58, -3, 86, 13, +90, 28, 79, 31, 53, 27, 27, 16, +1, 3, -9, -9, -17, -12, -11, -13, +1, -7, 20, 0, 29, 6, 35, 9, +34, 9, 33, 3, 35, -3, 39, -3, +43, 2, 45, 7, 42, 14, 31, 17, +18, 17, 1, 14, -12, 5, -17, -4, +-7, -11, 7, -12, 31, -4, 47, 4, +66, 12, 67, 13, 59, 9, 37, 1, +17, -2, -3, -7, -7, -4, -6, 4, +5, 16, 18, 24, 30, 29, 36, 21, +41, 0, 39, -25, 32, -42, 22, -46, +19, -36, 22, -18, 31, 10, 35, 37, +33, 57, 27, 58, 14, 44, 8, 15, +2, -16, 3, -43, 6, -52, 16, -47, +26, -30, 40, -10, 45, 8, 48, 18, +38, 24, 25, 24, 11, 19, 7, 10, +7, 2, 18, -6, 28, -10, 34, -15, +34, -20, 31, -29, 24, -31, 11, -29, +-1, -19, -4, -6, 9, 12, 24, 26, +41, 35, 52, 31, 61, 23, 52, 8, +32, -7, 7, -25, -10, -37, -19, -44, +-18, -39, -7, -30, 15, -16, 33, 0, +49, 15, 56, 22, 63, 27, 55, 30, +43, 29, 24, 20, 13, 7, 0, -13, +-7, -33, -7, -53, -2, -61, 1, -54, +6, -31, 17, -2, 35, 29, 51, 56, +62, 72, 68, 67, 62, 48, 46, 14, +21, -22, -3, -54, -26, -70, -36, -69, +-38, -50, -19, -23, 9, 10, 45, 38, +74, 56, 89, 63, 84, 57, 67, 40, +39, 21, 9, -5, -20, -26, -39, -39, +-41, -45, -26, -45, -6, -31, 19, -12, +45, 10, 63, 32, 68, 51, 64, 59, +57, 58, 37, 42, 18, 18, -1, -11, +-10, -33, -22, -46, -22, -46, -18, -36, +0, -17, 20, 5, 41, 29, 53, 45, +67, 48, 67, 39, 55, 28, 32, 10, +12, -5, -15, -17, -27, -24, -28, -29, +-12, -25, 4, -18, 26, -3, 45, 8, +56, 18, 58, 21, 47, 22, 31, 18, +13, 11, 5, -2, -1, -8, -3, -14, +3, -20, 16, -19, 24, -8, 26, 3, +21, 12, 15, 16, 9, 15, 12, 6, +16, -6, 28, -19, 38, -25, 43, -25, +37, -19, 30, -6, 17, 8, 4, 16, +-9, 20, -13, 18, -6, 9, 6, -4, +23, -16, 39, -24, 50, -27, 49, -26, +37, -16, 22, -7, 12, 2, 4, 7, +1, 8, 2, 4, 16, 1, 21, -2, +26, -4, 28, -5, 28, -3, 11, 3, +0, 6, -2, 3, 10, -3, 21, -12, +34, -19, 41, -22, 47, -22, 45, -17, +35, -2, 12, 12, -7, 23, -21, 27, +-22, 26, -14, 15, 5, 1, 26, -12, +42, -18, 55, -21, 58, -17, 51, -5, +32, 10, 13, 17, -8, 18, -20, 11, +-20, 2, -10, -9, 3, -12, 18, -5, +31, 7, 39, 16, 41, 26, 42, 29, +33, 26, 22, 10, 8, -10, 5, -30, +8, -37, 13, -35, 18, -20, 20, 3, +21, 28, 14, 42, 11, 45, 11, 35, +18, 15, 18, -10, 20, -27, 30, -35, +41, -28, 38, -13, 31, 4, 19, 19, +8, 28, -5, 25, -5, 18, -5, 5, +8, -3, 14, -5, 21, -3, 26, -4, +34, -5, 33, -8, 28, -10, 21, -13, +15, -10, 12, -5, 18, 7, 25, 20, +27, 30, 22, 29, 16, 22, 2, 5, +-9, -19, -11, -41, -6, -50, 2, -48, +13, -31, 38, -8, 61, 15, 76, 31, +68, 41, 47, 38, 18, 25, -9, 5, +-34, -10, -48, -22, -44, -29, -29, -31, +-7, -28, 25, -28, 59, -26, 75, -21, +73, -11, 72, -1, 59, 21, 27, 45, +-6, 57, -24, 54, -35, 35, -47, 0, +-42, -36, -31, -69, -5, -85, 20, -79, +45, -49, 66, -9, 83, 35, 82, 68, +67, 82, 41, 72, 7, 44, -34, 3, +-59, -36, -66, -61, -52, -64, -34, -53, +4, -30, 39, -3, 71, 18, 90, 25, +96, 26, 76, 21, 41, 15, 9, 9, +-18, 5, -39, 3, -51, 5, -47, -1, +-26, -15, 0, -27, 25, -28, 43, -25, +60, -12, 65, 8, 57, 30, 47, 43, +36, 42, 20, 28, -6, 6, -16, -22, +-19, -44, -24, -52, -26, -41, -9, -17, +15, 15, 30, 42, 42, 60, 50, 61, +54, 42, 48, 10, 36, -17, 15, -38, +-6, -47, -17, -45, -22, -30, -16, -7, +-4, 17, 4, 35, 14, 44, 26, 41, +39, 34, 31, 20, 27, 7, 20, -6, +14, -17, 5, -28, 7, -29, 7, -25, +5, -11, 5, 4, 9, 21, 8, 31, +5, 38, 1, 34, 3, 21, 4, -1, +14, -21, 15, -35, 21, -34, 25, -26, +32, -9, 34, 10, 27, 29, 15, 35, +0, 27, -3, 9, -5, -9, -12, -27, +-13, -40, 4, -41, 22, -26, 25, -8, +33, 11, 41, 22, 39, 29, 25, 22, +12, 12, 5, -2, -4, -12, -7, -17, +-12, -14, -7, -13, 4, -11, 11, -13, +16, -13, 28, -15, 36, -10, 22, -3, +14, 6, 16, 13, 20, 21, 12, 21, +8, 13, 8, -2, 4, -16, 0, -27, +2, -30, 3, -27, 4, -14, 5, 0, +18, 12, 26, 15, 40, 14, 38, 6, +30, -3, 16, -12, 6, -14, -10, -6, +-24, 9, -26, 18, -20, 22, -5, 18, +22, 6, 39, -6, 44, -15, 48, -24, +50, -23, 22, -12, -5, 4, -21, 18, +-26, 25, -27, 20, -18, 14, 1, 4, +17, -4, 38, -9, 48, -6, 51, 1, +39, 10, 16, 17, -8, 18, -17, 7, +-8, -9, -12, -21, -11, -24, 5, -20, +22, -6, 25, 12, 22, 31, 23, 40, +13, 38, 5, 25, 5, 8, 15, -13, +21, -27, 20, -29, 21, -22, 14, -12, +7, 2, -9, 12, -17, 13, -18, 9, +-9, 8, 0, 6, 16, 7, 42, 14, +54, 23, 50, 20, 43, 11, 20, -2, +-9, -19, -28, -39, -26, -48, -34, -41, +-27, -20, -6, 9, 25, 38, 42, 57, +50, 62, 48, 46, 30, 18, 10, -18, +-1, -48, -2, -67, -2, -64, -4, -45, +4, -16, 10, 12, 21, 33, 14, 36, +2, 31, -1, 18, -1, 4, -1, -9, +7, -13, 34, -10, 45, -5, 42, -7, +35, -12, 24, -22, 1, -32, -25, -37, +-33, -31, -33, -14, -23, 14, -8, 44, +17, 61, 46, 58, 63, 41, 55, 6, +32, -32, 18, -64, 3, -77, -16, -69, +-25, -41, -23, -6, -12, 29, -3, 52, +21, 57, 27, 44, 23, 24, 15, 1, +16, -18, 12, -26, 10, -22, 18, -15, +20, -8, 14, -2, 8, -2, 2, -12, +-2, -20, -11, -19, -11, -5, -11, 13, +4, 34, 12, 51, 17, 59, 26, 46, +34, 17, 24, -18, 5, -45, 5, -61, +2, -58, -4, -40, -3, -9, 6, 20, +10, 41, 7, 48, 17, 43, 17, 28, +8, 10, -3, -6, -2, -13, 9, -15, +19, -10, 23, -6, 18, -5, 24, -11, +24, -15, 10, -16, -4, -9, -9, 3, +-12, 21, -24, 37, -9, 43, 7, 36, +19, 18, 27, -4, 35, -25, 33, -43, +24, -45, 17, -32, 7, -8, -1, 12, +-2, 30, -7, 35, -11, 31, -15, 18, +-2, 0, 4, -19, 13, -24, 13, -20, +18, -9, 26, 3, 36, 10, 35, 7, +20, 4, 12, -4, 2, -10, -14, -16, +-19, -12, -15, -3, -15, 10, -23, 17, +-1, 15, 23, 5, 35, -4, 34, -11, +36, -15, 37, -15, 26, -8, 10, 3, +-11, 12, -17, 11, -18, 4, -27, -9, +-26, -19, -7, -26, 17, -21, 21, -6, +32, 14, 41, 27, 35, 35, 24, 30, +19, 14, 11, -10, -12, -34, -21, -51, +-19, -52, -13, -40, 0, -15, 9, 12, +15, 36, 16, 47, 25, 49, 18, 38, +15, 15, 12, -7, 6, -22, -1, -30, +1, -30, 5, -26, 0, -17, 1, -9, +5, 1, -8, 11, -12, 19, -6, 22, +9, 25, 8, 24, 27, 21, 39, 12, +35, 5, 20, -4, 14, -15, 5, -25, +-18, -26, -34, -24, -35, -17, -17, -6, +6, 7, 18, 17, 31, 26, 39, 33, +43, 36, 23, 32, 9, 27, -3, 18, +-24, 4, -35, -12, -23, -26, 2, -39, +11, -45, 21, -40, 29, -23, 25, 1, +15, 25, 3, 43, -3, 58, -12, 60, +-1, 48, 6, 28, 12, 8, 22, -15, +24, -33, 13, -46, -3, -51, -11, -50, +-25, -40, -23, -24, -1, -3, 15, 22, +29, 49, 39, 71, 49, 81, 32, 73, +19, 48, -3, 8, -32, -38, -50, -81, +-38, -105, -14, -104, 4, -78, 26, -32, +44, 25, 51, 77, 47, 111, 21, 116, +-1, 87, -18, 34, -17, -23, -24, -70, +-14, -97, 10, -99, 21, -76, 20, -42, +24, -3, 28, 33, 7, 55, -8, 62, +-3, 56, -1, 39, 2, 18, 5, -3, +21, -22, 27, -39, 29, -47, 13, -51, +-4, -48, -9, -37, -11, -15, -8, 11, +-2, 37, 14, 56, 16, 62, 17, 50, +26, 28, 24, -6, 12, -42, 1, -69, +5, -76, 1, -63, 7, -32, 12, 6, +11, 37, 5, 55, 4, 60, 3, 45, +-7, 22, -8, -7, 2, -25, 6, -33, +16, -30, 21, -21, 31, -8, 29, 1, +31, 7, 10, 6, -10, 5, -16, 2, +-19, 4, -24, 10, -16, 16, 6, 15, +12, 12, 15, 5, 36, -5, 46, -15, +37, -18, 17, -15, 13, -2, 0, 9, +-5, 19, -12, 22, -23, 20, -24, 4, +-19, -16, -5, -33, 11, -37, 34, -26, +42, -2, 35, 28, 36, 55, 30, 63, +13, 54, -11, 29, -18, -3, -29, -39, +-32, -65, -17, -72, -1, -56, 17, -28, +31, 7, 41, 37, 30, 56, 21, 56, +20, 43, 12, 23, 2, 2, -7, -15, +-4, -22, -7, -21, 4, -17, 3, -14, +-2, -16, -4, -21, -1, -23, -1, -20, +8, -10, 28, 4, 29, 27, 20, 44, +31, 50, 31, 44, 15, 25, -8, -6, +-10, -36, -18, -60, -20, -68, -11, -57, +2, -31, 15, 3, 19, 33, 18, 52, +14, 51, 18, 35, 16, 14, 4, -11, +10, -24, 9, -25, 2, -15, -6, -5, +8, 7, 11, 11, -6, 9, -15, -3, +-14, -17, -7, -25, -1, -26, 17, -19, +24, 1, 23, 24, 30, 41, 30, 41, +27, 32, 12, 12, -2, -10, -20, -30, +-23, -41, -18, -38, -18, -25, -10, -7, +1, 13, 12, 25, 20, 28, 34, 22, +40, 11, 32, -1, 34, -7, 24, -8, +5, -1, -19, 5, -21, 8, -27, 4, +-32, -5, -26, -14, -7, -20, 18, -22, +38, -13, 51, 4, 49, 23, 41, 35, +27, 40, -1, 35, -14, 20, -28, -3, +-37, -23, -43, -35, -16, -36, 12, -27, +23, -9, 30, 11, 34, 31, 29, 42, +13, 41, 6, 32, -3, 21, -14, 5, +-8, -10, -1, -23, 10, -28, 13, -30, +15, -24, 3, -14, -6, 1, -11, 16, +-16, 30, -9, 40, 9, 44, 29, 39, +32, 28, 33, 8, 31, -16, 13, -41, +1, -57, -15, -60, -27, -48, -34, -22, +-15, 13, 7, 42, 22, 66, 30, 74, +32, 65, 26, 38, 11, 4, 2, -30, +-9, -55, -18, -67, -11, -61, -5, -42, +16, -14, 24, 15, 25, 37, 11, 45, +10, 48, 0, 42, -20, 29, -24, 7, +-6, -11, 12, -23, 14, -28, 23, -31, +34, -28, 23, -18, 11, -5, -9, 7, +-21, 22, -32, 30, -23, 34, -9, 28, +14, 16, 34, 2, 33, -12, 29, -27, +24, -33, 16, -29, -8, -16, -28, 4, +-27, 24, -24, 36, -6, 39, 16, 28, +32, 13, 29, -7, 28, -26, 24, -38, +5, -37, -8, -24, -15, -4, -18, 20, +-20, 42, -9, 47, 7, 40, 15, 24, +23, 6, 20, -17, 21, -32, 13, -37, +11, -28, 2, -13, 2, 9, 1, 26, +-12, 35, -20, 34, -13, 25, -5, 10, +-5, -4, 2, -16, 19, -18, 23, -9, +29, 5, 29, 14, 31, 19, 13, 18, +-5, 15, -19, 5, -27, -4, -26, -12, +-26, -13, -18, -7, 0, 3, 22, 11, +32, 19, 33, 22, 44, 18, 36, 8, +22, 2, 1, 0, -11, 1, -29, 2, +-38, 7, -38, 9, -35, 7, -20, 3, +1, -1, 25, -6, 43, -6, 53, 0, +50, 12, 31, 22, 16, 32, -9, 33, +-32, 25, -52, 9, -57, -6, -47, -22, +-19, -29, 15, -26, 34, -12, 46, 8, +52, 28, 49, 38, 27, 38, -2, 28, +-18, 6, -32, -20, -32, -34, -27, -33, +-10, -20, 2, -4, 18, 18, 24, 36, +22, 44, 19, 36, 9, 19, 1, -4, +-3, -22, -7, -31, -13, -30, -13, -21, +4, -3, 8, 16, 5, 35, -3, 42, +4, 38, 3, 26, 3, 13, 7, -2, +3, -13, -5, -19, -11, -18, -8, -17, +-4, -11, -4, -1, 0, 7, 3, 13, +18, 22, 24, 32, 22, 38, 9, 35, +-1, 25, -15, 11, -28, -7, -28, -26, +-25, -36, -17, -35, -5, -20, 11, 1, +24, 21, 32, 37, 43, 46, 32, 45, +16, 35, -6, 15, -18, -4, -32, -21, +-36, -28, -28, -27, -21, -14, -15, 5, +-5, 22, 10, 32, 26, 33, 35, 26, +33, 19, 20, 12, 16, 9, 1, 7, +-16, 7, -36, 9, -43, 8, -45, 1, +-36, -3, -14, -7, 9, -5, 24, 2, +36, 10, 48, 17, 47, 28, 25, 35, +1, 32, -28, 19, -40, 3, -47, -14, +-39, -20, -28, -18, -4, -7, 19, 10, +26, 27, 30, 34, 26, 33, 12, 23, +-2, 5, -10, -15, -16, -21, -23, -15, +-15, 3, -8, 23, 2, 40, 2, 48, +0, 45, -10, 27, -14, -2, -6, -32, +-1, -49, 2, -47, 6, -27, 12, 4, +17, 37, 10, 64, -3, 76, -22, 65, +-26, 41, -32, 10, -30, -18, -23, -36, +-7, -36, 4, -23, 9, -5, 14, 14, +16, 25, 8, 26, -1, 23, -8, 15, +-12, 11, -19, 13, -15, 21, -17, 30, +-9, 36, -11, 32, -10, 17, -14, -5, +-10, -24, -5, -38, -3, -39, 2, -27, +8, 0, 11, 31, 10, 59, 5, 72, +-3, 69, -25, 52, -36, 24, -40, -10, +-34, -31, -29, -39, -14, -33, 2, -18, +19, 1, 33, 18, 31, 34, 19, 38, +2, 36, -15, 26, -30, 18, -43, 13, +-43, 11, -37, 9, -20, 9, -5, 6, +9, 1, 16, -3, 20, -4, 18, -3, +7, 3, -5, 15, -19, 29, -33, 38, +-38, 43, -36, 38, -25, 26, -20, 8, +-8, -5, 2, -16, 16, -16, 16, -9, +11, 3, 0, 15, -9, 28, -18, 34, +-29, 33, -32, 27, -28, 20, -24, 15, +-18, 11, -10, 6, 3, 6, 3, 6, +4, 7, -1, 6, -4, 6, -12, 6, +-15, 9, -17, 14, -19, 21, -18, 26, +-20, 30, -23, 29, -21, 25, -16, 15, +-10, 6, -10, 0, -5, 1, -7, 6, +-2, 12, -4, 18, -10, 23, -22, 24, +-31, 22, -32, 13, -32, 8, -27, 4, +-17, 7, -9, 15, -1, 24, 7, 32, +8, 38, -5, 35, -16, 24, -31, 8, +-35, -11, -36, -25, -29, -28, -20, -21, +-5, -3, 7, 22, 4, 50, -2, 64, +-6, 65, -17, 54, -30, 34, -42, 8, +-40, -15, -36, -31, -21, -34, -8, -25, +6, -8, 8, 11, 4, 31, -1, 40, +-11, 44, -25, 41, -39, 32, -48, 23, +-45, 20, -40, 19, -29, 18, -18, 11, +0, 6, 4, 2, 6, -3, 1, -7, +-6, -6, -17, -3, -28, 9, -39, 26, +-46, 41, -45, 49, -39, 50, -33, 43, +-23, 31, -14, 13, -2, 0, -1, -6, +-1, -4, -7, 1, -12, 9, -25, 15, +-38, 21, -48, 21, -48, 16, -43, 9, +-37, 8, -26, 9, -9, 22, 0, 40, +2, 53, -1, 54, -3, 45, -20, 30, +-32, 4, -41, -26, -40, -43, -45, -45, +-45, -32, -35, -8, -20, 25, -10, 57, +-6, 81, -7, 86, -5, 76, -12, 51, +-19, 20, -30, -12, -34, -33, -43, -42, +-47, -39, -47, -26, -39, -3, -33, 23, +-26, 45, -13, 56, -1, 63, -1, 66, +-9, 61, -19, 44, -27, 24, -44, 4, +-56, -17, -64, -34, -54, -39, -44, -30, +-28, -8, -14, 18, -4, 48, 2, 72, +-2, 86, -16, 82, -32, 58, -46, 22, +-52, -11, -57, -38, -51, -47, -45, -41, +-29, -17, -23, 15, -19, 47, -17, 66, +-16, 74, -23, 65, -31, 46, -35, 22, +-36, 1, -37, -15, -36, -20, -35, -17, +-29, -6, -34, 8, -39, 22, -45, 31, +-40, 38, -37, 39, -30, 38, -23, 34, +-15, 30, -15, 24, -21, 17, -29, 6, +-36, -3, -51, -7, -61, -6, -61, -2, +-48, 10, -37, 26, -25, 39, -20, 50, +-15, 53, -20, 44, -27, 28, -38, 10, +-47, -3, -55, -7, -58, -2, -52, 6, +-41, 19, -33, 33, -28, 43, -30, 40, +-32, 33, -41, 20, -45, 8, -48, 0, +-47, 2, -44, 9, -35, 20, -30, 32, +-30, 44, -33, 47, -38, 42, -48, 27, +-54, 9, -56, -3, -49, -6, -50, -3, +-42, 4, -37, 15, -28, 29, -31, 38, +-35, 43, -42, 43, -45, 38, -51, 30, +-56, 26, -57, 23, -51, 21, -52, 19, +-52, 16, -49, 6, -36, 1, -37, 1, +-39, 6, -40, 13, -36, 25, -39, 36, +-44, 47, -52, 53, -55, 51, -57, 36, +-55, 20, -51, 4, -46, -6, -40, -12, +-32, -6, -32, 6, -36, 22, -50, 36, +-59, 41, -65, 36, -63, 32, -61, 25, +-55, 20, -45, 19, -36, 24, -30, 32, +-31, 38, -40, 36, -49, 27, -63, 15, +-69, 3, -75, -11, -68, -16, -58, -7, +-46, 13, -41, 35, -36, 57, -34, 70, +-36, 70, -45, 55, -56, 35, -64, 12, +-66, -9, -69, -22, -66, -19, -63, -8, +-53, 12, -57, 33, -59, 49, -57, 55, +-48, 53, -46, 41, -44, 29, -41, 17, +-37, 13, -45, 14, -57, 18, -66, 18, +-73, 18, -84, 16, -86, 15, -79, 9, +-60, 8, -46, 12, -34, 24, -28, 39, +-26, 50, -32, 53, -46, 51, -66, 41, +-83, 26, -97, 10, -100, -5, -92, -15, +-71, -13, -56, 0, -39, 20, -31, 38, +-29, 54, -35, 59, -43, 56, -61, 46, +-76, 30, -83, 12, -84, 2, -84, -3, +-77, 1, -69, 12, -65, 25, -63, 30, +-55, 33, -50, 35, -47, 34, -54, 32, +-60, 30, -63, 29, -65, 32, -75, 33, +-80, 29, -79, 25, -77, 20, -78, 12, +-73, 10, -66, 11, -56, 13, -58, 22, +-60, 35, -60, 40, -58, 45, -69, 47, +-76, 42, -77, 33, -75, 24, -79, 15, +-75, 8, -68, 3, -60, 5, -60, 7, +-60, 14, -65, 25, -67, 35, -73, 40, +-71, 45, -76, 48, -75, 46, -75, 37, +-69, 25, -67, 12, -66, 1, -66, -7, +-66, -5, -73, 5, -75, 22, -74, 38, +-75, 55, -82, 63, -82, 61, -79, 48, +-72, 29, -72, 10, -70, -2, -68, -5, +-65, 2, -69, 16, -72, 33, -75, 47, +-79, 51, -86, 43, -89, 32, -89, 19, +-82, 8, -81, 6, -73, 17, -65, 30, +-58, 45, -64, 56, -68, 57, -73, 43, +-77, 19, -88, -5, -91, -20, -88, -23, +-82, -8, -80, 16, -74, 45, -68, 65, +-63, 75, -73, 74, -80, 58, -84, 30, +-82, 2, -86, -13, -85, -11, -80, -3, +-70, 10, -68, 28, -72, 41, -81, 43, +-86, 36, -94, 24, -95, 18, -97, 18, +-89, 28, -79, 40, -67, 54, -63, 61, +-61, 56, -64, 36, -74, 11, -93, -12, +-107, -28, -112, -30, -108, -14, -102, 15, +-88, 51, -74, 82, -65, 99, -67, 94, +-67, 72, -71, 37, -80, 2, -98, -25, +-100, -37, -96, -30, -95, -5, -96, 22, +-88, 47, -83, 65, -84, 69, -88, 56, +-82, 37, -79, 19, -79, 12, -87, 11, +-85, 18, -81, 26, -81, 36, -91, 42, +-97, 42, -101, 33, -104, 19, -106, 7, +-98, 3, -89, 5, -80, 15, -75, 28, +-69, 44, -74, 55, -79, 61, -94, 60, +-106, 51, -114, 31, -113, 18, -112, 8, +-104, 4, -92, 1, -79, 6, -72, 15, +-70, 26, -74, 35, -79, 42, -87, 44, +-97, 48, -114, 50, -119, 47, -115, 37, +-106, 27, -100, 19, -88, 13, -77, 8, +-71, 7, -72, 8, -71, 13, -76, 21, +-91, 33, -112, 44, -121, 51, -123, 51, +-118, 48, -113, 42, -94, 32, -76, 21, +-66, 15, -68, 9, -69, 7, -74, 4, +-90, 7, -111, 16, -121, 30, -125, 44, +-124, 55, -116, 59, -97, 58, -84, 49, +-75, 36, -74, 20, -74, 5, -84, -4, +-96, -7, -108, -2, -109, 13, -112, 34, +-112, 54, -111, 65, -104, 67, -100, 57, +-95, 42, -92, 20, -85, 4, -85, -4, +-84, -3, -87, 7, -91, 22, -102, 38, +-109, 48, -116, 47, -122, 42, -127, 32, +-115, 20, -98, 15, -86, 22, -80, 33, +-68, 40, -65, 43, -75, 44, -97, 38, +-113, 22, -128, 3, -140, -10, -142, -16, +-123, -6, -101, 17, -82, 43, -68, 66, +-57, 83, -61, 83, -78, 69, -101, 40, +-116, 11, -135, -14, -144, -29, -140, -30, +-121, -13, -103, 12, -86, 37, -72, 54, +-63, 66, -71, 67, -84, 59, -101, 46, +-113, 36, -126, 25, -131, 20, -132, 19, +-121, 18, -111, 13, -98, 8, -91, 4, +-86, 4, -86, 7, -85, 16, -88, 36, +-94, 57, -106, 73, -113, 80, -123, 75, +-126, 58, -128, 29, -120, 0, -114, -22, +-105, -30, -94, -25, -79, -3, -75, 25, +-79, 51, -87, 68, -97, 74, -113, 69, +-130, 55, -139, 33, -133, 15, -125, 4, +-113, 1, -99, 8, -80, 22, -77, 33, +-81, 39, -90, 36, -96, 31, -108, 21, +-119, 18, -126, 19, -121, 24, -117, 31, +-114, 41, -108, 44, -96, 44, -93, 38, +-94, 29, -98, 18, -97, 15, -102, 15, +-107, 22, -111, 30, -114, 39, -120, 40, +-120, 34, -116, 25, -107, 18, -104, 14, +-99, 17, -96, 26, -94, 40, -100, 53, +-105, 64, -117, 62, -123, 49, -128, 28, +-124, 8, -116, -9, -103, -15, -93, -10, +-81, 8, -82, 30, -90, 54, -105, 66, +-115, 68, -126, 58, -133, 43, -133, 24, +-119, 9, -107, 4, -95, 7, -86, 12, +-78, 20, -87, 28, -103, 36, -119, 40, +-128, 40, -135, 37, -136, 37, -126, 35, +-106, 34, -94, 33, -87, 30, -83, 24, +-82, 15, -95, 8, -107, 7, -117, 9, +-117, 19, -122, 31, -124, 46, -119, 54, +-110, 55, -106, 47, -104, 37, -105, 25, +-102, 13, -102, 1, -96, -1, -97, 9, +-99, 24, -106, 35, -111, 45, -120, 48, +-125, 47, -128, 41, -123, 34, -116, 27, +-103, 21, -92, 16, -80, 13, -77, 14, +-82, 16, -98, 18, -112, 22, -129, 26, +-140, 36, -144, 44, -131, 50, -118, 51, +-100, 45, -81, 32, -67, 20, -71, 7, +-82, -2, -97, -4, -112, 2, -132, 16, +-139, 32, -138, 47, -125, 57, -115, 55, +-99, 47, -85, 31, -73, 17, -78, 7, +-86, 8, -97, 12, -108, 23, -124, 31, +-134, 39, -135, 39, -127, 33, -120, 21, +-107, 13, -92, 9, -79, 14, -76, 24, +-74, 38, -83, 52, -99, 58, -121, 52, +-134, 37, -138, 11, -131, -8, -126, -14, +-115, -6, -101, 11, -85, 33, -76, 51, +-69, 62, -77, 63, -92, 54, -113, 33, +-126, 13, -139, 1, -142, 0, -137, 7, +-121, 24, -107, 39, -91, 50, -77, 48, +-68, 37, -74, 22, -85, 7, -100, -1, +-114, 4, -131, 19, -136, 38, -134, 56, +-129, 67, -124, 64, -112, 51, -99, 27, +-83, -1, -74, -24, -69, -27, -72, -13, +-80, 11, -98, 38, -115, 66, -134, 79, +-147, 73, -151, 52, -140, 27, -119, 1, +-93, -14, -74, -16, -57, -2, -51, 16, +-57, 34, -77, 45, -102, 52, -133, 49, +-155, 38, -165, 22, -154, 12, -131, 10, +-100, 16, -75, 24, -54, 35, -50, 39, +-55, 35, -73, 25, -97, 17, -125, 8, +-143, 6, -150, 10, -141, 21, -124, 34, +-105, 49, -90, 55, -76, 50, -72, 37, +-72, 21, -78, 5, -88, -5, -102, -10, +-108, -4, -113, 11, -116, 32, -121, 48, +-120, 57, -114, 54, -103, 45, -97, 29, +-85, 15, -76, 5, -75, 3, -83, 4, +-87, 9, -97, 18, -110, 30, -124, 38, +-127, 43, -125, 40, -115, 34, -103, 24, +-83, 19, -69, 14, -67, 15, -77, 16, +-85, 19, -99, 25, -114, 32, -127, 33, +-126, 33, -120, 28, -108, 24, -98, 18, +-82, 15, -72, 14, -72, 17, -81, 22, +-88, 28, -99, 35, -107, 40, -118, 40, +-118, 34, -117, 25, -111, 19, -106, 13, +-97, 11, -91, 12, -81, 18, -79, 25, +-78, 35, -88, 43, -95, 46, -103, 36, +-108, 27, -119, 19, -119, 12, -115, 8, +-104, 11, -93, 16, -79, 27, -73, 34, +-72, 36, -80, 35, -86, 29, -98, 19, +-109, 12, -121, 10, -119, 16, -112, 23, +-99, 33, -89, 38, -75, 41, -73, 37, +-77, 25, -83, 9, -89, -1, -100, -5, +-109, 0, -113, 13, -106, 31, -99, 47, +-93, 59, -93, 61, -87, 50, -87, 29, +-89, 8, -94, -7, -93, -10, -94, -7, +-93, 9, -94, 27, -91, 42, -92, 51, +-95, 49, -99, 37, -99, 22, -102, 7, +-96, 1, -94, 7, -84, 20, -81, 34, +-77, 47, -83, 52, -90, 47, -100, 31, +-105, 6, -107, -15, -103, -26, -97, -22, +-85, -2, -77, 28, -73, 57, -76, 74, +-74, 79, -88, 69, -99, 44, -106, 10, +-103, -14, -105, -27, -100, -27, -91, -17, +-79, 6, -74, 28, -74, 46, -78, 54, +-86, 57, -97, 50, -103, 38, -105, 27, +-98, 22, -93, 18, -84, 18, -82, 17, +-78, 14, -77, 6, -81, 0, -87, -4, +-90, -3, -95, 7, -97, 25, -96, 47, +-92, 64, -89, 69, -83, 66, -83, 49, +-77, 23, -76, -4, -77, -22, -85, -30, +-88, -24, -94, -7, -96, 16, -97, 37, +-93, 52, -89, 60, -80, 57, -75, 43, +-69, 30, -71, 17, -69, 7, -76, 1, +-85, 1, -97, 3, -98, 8, -105, 14, +-103, 20, -98, 26, -86, 33, -80, 36, +-72, 40, -65, 39, -62, 38, -71, 31, +-80, 20, -90, 10, -91, 3, -98, -2, +-97, 1, -97, 6, -85, 18, -82, 28, +-79, 37, -75, 38, -69, 36, -69, 30, +-73, 22, -73, 12, -70, 9, -79, 12, +-87, 14, -92, 15, -90, 16, -97, 16, +-94, 18, -92, 18, -79, 21, -71, 22, +-61, 24, -55, 26, -51, 29, -59, 25, +-72, 22, -89, 17, -104, 12, -114, 4, +-108, 3, -99, 7, -80, 16, -65, 27, +-51, 36, -49, 39, -48, 35, -59, 26, +-73, 16, -92, 6, -104, 1, -107, 3, +-99, 10, -91, 19, -73, 27, -61, 32, +-55, 33, -57, 23, -55, 13, -67, 5, +-75, 3, -86, 7, -89, 15, -89, 25, +-83, 34, -81, 38, -78, 37, -74, 27, +-73, 15, -77, 5, -74, -1, -71, -2, +-63, 7, -66, 18, -66, 28, -70, 33, +-70, 35, -83, 31, -88, 22, -93, 10, +-90, 6, -82, 6, -72, 16, -65, 28, +-57, 34, -55, 34, -56, 31, -65, 20, +-74, 7, -90, -5, -88, -9, -94, 0, +-94, 16, -88, 31, -71, 45, -61, 50, +-51, 48, -49, 37, -53, 23, -62, 4, +-70, -12, -76, -17, -80, -11, -91, -2, +-86, 9, -81, 23, -71, 35, -70, 40, +-62, 39, -58, 31, -52, 27, -57, 25, +-65, 20, -66, 13, -68, 9, -78, 5, +-82, 1, -83, -2, -75, -4, -74, 0, +-67, 12, -67, 22, -56, 35, -58, 45, +-60, 50, -64, 46, -66, 37, -74, 20, +-78, 1, -73, -13, -68, -18, -68, -15, +-67, -6, -65, 6, -55, 20, -62, 35, +-69, 46, -73, 44, -66, 36, -69, 25, +-63, 14, -59, 3, -55, -2, -54, -2, +-57, 2, -67, 6, -72, 11, -76, 15, +-76, 19, -76, 21, -67, 23, -64, 22, +-51, 21, -49, 21, -46, 22, -53, 19, +-63, 15, -76, 11, -78, 9, -78, 4, +-75, 1, -66, 3, -55, 12, -51, 22, +-50, 30, -58, 33, -59, 31, -64, 23, +-68, 15, -78, 7, -70, 1, -68, -2, +-60, 1, -53, 10, -51, 20, -54, 26, +-55, 29, -61, 26, -62, 19, -62, 9, +-62, 2, -68, 1, -61, 3, -57, 3, +-48, 9, -56, 19, -58, 25, -57, 23, +-57, 21, -66, 18, -63, 13, -59, 8, +-60, 7, -59, 8, -54, 11, -56, 13, +-56, 15, -58, 15, -55, 14, -62, 16, +-63, 18, -67, 16, -54, 13, -53, 12, +-56, 15, -53, 11, -48, 10, -53, 9, +-57, 10, -61, 13, -64, 16, -65, 16, +-62, 20, -65, 22, -57, 22, -58, 20, +-54, 18, -54, 11, -49, 7, -52, 7, +-51, 8, -55, 9, -58, 14, -61, 19, +-67, 20, -66, 16, -55, 16, -58, 16, +-57, 14, -50, 11, -38, 13, -44, 14, +-44, 14, -52, 12, -55, 12, -62, 7, +-66, 4, -66, 3, -61, 8, -58, 15, +-53, 26, -49, 34, -48, 36, -51, 32, +-50, 25, -58, 11, -56, -1, -63, -12, +-57, -16, -52, -11, -44, 5, -46, 19, +-47, 33, -50, 40, -56, 41, -55, 29, +-57, 13, -64, 0, -55, -9, -44, -16, +-36, -11, -41, 2, -35, 17, -43, 25, +-50, 29, -62, 24, -60, 13, -61, 4, +-61, 0, -53, -4, -37, 1, -34, 12, +-37, 22, -38, 29, -42, 31, -58, 21, +-60, 7, -66, -6, -59, -12, -53, -13, +-42, -3, -42, 10, -32, 25, -33, 35, +-41, 37, -52, 32, -61, 21, -66, 5, +-65, -4, -66, -8, -54, -7, -37, 0, +-25, 11, -29, 22, -23, 28, -36, 25, +-51, 20, -65, 10, -67, 0, -68, -7, +-66, -4, -55, 1, -35, 12, -22, 24, +-26, 33, -29, 31, -27, 22, -41, 8, +-51, -5, -61, -13, -65, -14, -68, -8, +-55, 3, -51, 17, -41, 31, -34, 40, +-32, 42, -32, 33, -36, 19, -41, 2, +-44, -12, -49, -19, -49, -17, -53, -9, +-51, 5, -59, 18, -44, 30, -40, 35, +-43, 37, -44, 27, -35, 17, -34, 6, +-37, -3, -40, -8, -42, -8, -39, -7, +-39, -2, -43, 7, -39, 15, -47, 19, +-46, 20, -47, 17, -42, 16, -51, 12, +-45, 11, -40, 9, -34, 10, -31, 13, +-35, 17, -39, 15, -37, 11, -41, 8, +-53, 7, -63, 1, -58, -2, -52, 1, +-40, 9, -42, 16, -27, 24, -18, 27, +-19, 27, -29, 21, -34, 15, -47, 4, +-61, -7, -60, -13, -57, -11, -50, -6, +-38, 3, -28, 14, -13, 23, -15, 27, +-25, 27, -40, 23, -40, 15, -54, 4, +-58, -2, -55, -3, -48, 2, -38, 8, +-30, 13, -28, 15, -26, 13, -27, 8, +-33, 3, -42, -1, -42, 0, -49, 7, +-41, 18, -45, 27, -38, 32, -31, 27, +-27, 20, -36, 7, -34, -8, -32, -23, +-44, -26, -45, -20, -35, -5, -33, 15, +-33, 34, -33, 45, -24, 49, -27, 41, +-33, 26, -48, 5, -43, -18, -45, -33, +-45, -33, -39, -24, -34, -7, -30, 13, +-22, 30, -19, 43, -25, 48, -29, 36, +-30, 20, -38, 4, -36, -8, -43, -18, +-40, -21, -41, -14, -35, -4, -29, 2, +-21, 9, -29, 16, -31, 24, -23, 23, +-29, 20, -34, 14, -28, 13, -28, 13, +-33, 14, -40, 9, -34, 2, -36, -9, +-30, -15, -35, -16, -28, -13, -25, -9, +-27, 6, -26, 25, -22, 38, -25, 43, +-32, 43, -31, 31, -32, 14, -38, -3, +-39, -18, -49, -28, -40, -27, -35, -17, +-27, 0, -28, 17, -16, 32, -13, 40, +-11, 39, -16, 28, -28, 16, -34, 4, +-46, -6, -58, -12, -52, -11, -44, -7, +-36, 1, -24, 7, 3, 10, 5, 14, +3, 14, -9, 9, -13, 5, -26, 2, +-48, 2, -60, 1, -51, 2, -40, 3, +-34, 6, -17, 7, -4, 8, -3, 8, +1, 11, -16, 12, -27, 9, -38, 6, +-40, 7, -49, 8, -45, 9, -38, 6, +-26, 3, -14, 2, -11, 5, -9, 4, +-13, 6, -25, 7, -23, 7, -19, 6, +-23, 9, -36, 9, -21, 8, -20, 5, +-22, 3, -30, 0, -30, -3, -28, -2, +-32, 3, -33, 6, -22, 9, -9, 14, +-11, 21, -7, 21, -2, 19, -21, 15, +-31, 7, -40, -6, -39, -13, -48, -12, +-45, -4, -42, 5, -23, 14, -2, 22, +3, 28, 4, 28, 0, 24, -7, 13, +-18, 1, -39, -11, -49, -17, -46, -18, +-39, -9, -42, -1, -17, 9, -1, 17, +5, 23, 9, 22, 9, 19, -2, 13, +-24, 8, -38, 2, -44, -2, -45, -5, +-49, -3, -42, 0, -16, 5, -7, 7, +1, 11, 2, 13, 6, 16, -5, 16, +-12, 15, -28, 11, -38, 7, -34, 0, +-32, -5, -28, -8, -19, -10, -10, -8, +-5, 2, -7, 8, -6, 15, -13, 21, +-13, 25, -27, 21, -21, 15, -15, 3, +-17, -5, -19, -11, -10, -10, -10, -6, +-22, -3, -22, 1, -21, 9, -17, 14, +-17, 17, -23, 16, -10, 15, -7, 12, +-6, 12, -11, 9, -10, 8, -22, 6, +-26, 5, -27, 1, -30, -1, -25, -2, +-22, -1, -12, -3, 0, 1, 4, 9, +-1, 16, -8, 19, -8, 21, -19, 17, +-18, 7, -26, -4, -22, -9, -10, -13, +-4, -12, -11, -6, -9, 6, -5, 15, +-13, 19, -14, 17, -16, 14, -17, 8, +-15, 4, -18, 0, -8, -2, -7, 2, +-9, 8, -16, 15, -9, 20, -19, 19, +-25, 13, -19, 3, -16, -1, -12, -7, +-6, -12, -2, -8, -1, 0, 5, 8, +1, 17, -16, 23, -20, 25, -26, 17, +-18, 7, -19, 0, -18, -3, -10, -4, +0, -3, 2, 1, 3, 7, 5, 12, +-9, 13, -17, 9, -13, 4, -19, 3, +-27, 5, -30, 5, -12, 7, -2, 10, +3, 17, -2, 20, 7, 18, 9, 13, +-6, 5, -13, -6, -16, -13, -21, -15, +-23, -11, -16, -5, -15, 9, -11, 23, +-1, 33, -2, 38, 2, 35, -2, 21, +-1, 5, -4, -11, -5, -19, -10, -23, +-12, -20, -14, -11, -12, 3, -1, 17, +-9, 30, -19, 35, -10, 30, -2, 20, +-2, 9, -8, -1, 2, -8, 5, -12, +11, -9, 2, -4, -2, 3, -4, 8, +-17, 11, -22, 9, -19, 8, -20, 7, +-18, 7, 0, 6, 14, 10, 20, 14, +24, 18, 11, 17, 7, 11, -5, 3, +-22, -6, -37, -15, -35, -17, -25, -13, +-10, -4, 5, 10, 14, 25, 31, 37, +32, 43, 14, 34, 3, 19, -8, -1, +-22, -18, -34, -31, -25, -34, -18, -29, +-3, -11, 5, 13, 15, 34, 24, 42, +18, 43, 8, 34, 3, 19, 1, -1, +-15, -13, -22, -21, -12, -23, -6, -17, +6, -6, 7, 3, 10, 15, 9, 20, +10, 19, 1, 13, -2, 6, 0, 2, +-2, 4, 2, 7, 3, 11, 5, 14, +8, 14, 4, 7, 2, 0, -1, -8, +-8, -14, -18, -16, -4, -13, 4, -1, +5, 16, 7, 31, 14, 42, 19, 43, +15, 32, 5, 16, -5, -3, -5, -24, +-9, -36, -11, -37, -4, -24, -5, -5, +4, 17, 13, 32, 20, 40, 18, 39, +18, 29, 12, 13, 5, 0, 0, -11, +-11, -16, -11, -14, -5, -7, 1, 1, +5, 11, 4, 14, 9, 13, 17, 5, +22, 1, 5, 1, 3, 3, 8, 7, +6, 14, 3, 19, 5, 20, 10, 14, +10, 4, 10, -6, 6, -15, 4, -20, +-1, -17, -6, -9, 6, 3, 11, 15, +13, 28, 15, 33, 24, 30, 22, 20, +16, 5, 7, -11, 0, -18, -1, -19, +-8, -15, -10, -6, -5, 8, 8, 17, +19, 22, 23, 21, 26, 16, 23, 8, +23, 0, 10, -4, 0, -2, -3, -2, +-5, 3, -8, 10, 0, 15, 11, 13, +12, 9, 17, 3, 20, -1, 23, -7, +20, -8, 10, -7, 12, 2, 12, 12, +8, 18, 2, 20, 5, 25, 1, 22, +2, 13, 5, 1, 3, -10, 13, -20, +21, -18, 22, -11, 23, -2, 25, 9, +21, 20, 12, 28, 8, 31, -3, 26, +-6, 17, -10, 4, -3, -6, 9, -12, +17, -11, 18, -9, 27, -3, 38, 5, +28, 13, 18, 13, 11, 14, 4, 13, +1, 11, -6, 7, -4, 6, 4, 5, +16, 6, 21, 3, 31, 2, 31, 1, +23, -1, 22, -5, 16, -4, 8, -1, +1, 5, -1, 12, 0, 22, 7, 25, +14, 24, 14, 16, 25, 7, 28, -6, +27, -12, 17, -15, 10, -14, 11, -10, +12, 4, 7, 17, 2, 27, 13, 29, +16, 27, 18, 17, 23, 5, 21, -7, +18, -16, 16, -18, 16, -13, 14, -8, +18, 1, 15, 12, 19, 21, 24, 24, +18, 21, 15, 13, 14, 7, 12, 1, +7, -3, 6, -6, 8, -5, 15, -2, +26, 1, 27, 1, 35, 3, 35, 4, +29, 7, 21, 7, 14, 8, 5, 9, +-1, 8, 4, 5, 8, 3, 20, 0, +25, 0, 26, -4, 36, -5, 41, -5, +32, 2, 16, 9, 9, 18, 0, 21, +-1, 20, 0, 12, 6, 5, 22, -4, +31, -10, 35, -11, 33, -6, 33, -1, +23, 8, 15, 16, 10, 18, 7, 16, +11, 14, 10, 8, 16, 3, 22, 0, +22, -1, 18, -3, 22, -1, 25, 2, +17, 9, 13, 13, 11, 15, 20, 13, +24, 13, 20, 12, 17, 11, 21, 5, +24, 0, 16, -4, 17, -6, 16, -9, +20, -7, 24, -4, 24, 2, 29, 7, +33, 11, 34, 13, 27, 19, 23, 22, +10, 18, 6, 5, 13, -6, 16, -14, +21, -18, 22, -17, 25, -7, 31, 0, +35, 9, 30, 16, 26, 21, 29, 21, +22, 20, 15, 15, 7, 8, 8, -3, +17, -13, 23, -18, 27, -15, 30, -10, +35, -2, 31, 4, 34, 12, 30, 15, +22, 16, 19, 12, 16, 10, 16, 7, +13, 5, 12, 2, 15, 0, 27, -3, +30, -2, 26, -1, 30, -1, 31, 0, +31, 3, 28, 1, 25, 5, 18, 10, +17, 12, 15, 14, 10, 14, 15, 9, +15, 4, 22, -1, 31, -4, 34, -6, +34, -7, 35, -6, 36, -1, 30, 4, +23, 11, 10, 14, 8, 16, 11, 14, +11, 9, 15, 5, 21, 1, 30, -4, +36, -3, 38, -1, 31, 2, 28, 5, +26, 12, 18, 13, 14, 11, 13, 6, +15, 3, 15, 1, 22, 1, 25, -1, +28, -2, 34, -1, 35, 5, 36, 9, +31, 10, 22, 9, 19, 8, 20, 2, +21, -2, 19, -6, 22, -2, 21, 2, +28, 9, 26, 12, 21, 11, 29, 4, +35, 1, 32, -1, 27, -5, 30, -7, +29, -5, 28, 0, 27, 10, 24, 14, +21, 14, 16, 12, 16, 11, 21, 2, +25, -7, 24, -11, 30, -10, 40, -5, +40, 2, 38, 7, 31, 13, 31, 12, +28, 10, 16, 6, 9, 1, 12, -5, +15, -5, 18, -4, 31, 0, 37, 5, +39, 12, 40, 15, 39, 15, 35, 8, +22, 0, 15, -7, 14, -13, 20, -17, +20, -12, 23, -2, 29, 9, 34, 17, +40, 21, 40, 17, 36, 11, 30, 4, +26, -2, 16, -9, 12, -12, 17, -11, +17, -3, 23, 4, 29, 8, 35, 11, +35, 13, 33, 13, 30, 9, 28, 1, +26, -2, 20, -2, 25, -1, 28, -2, +27, 1, 29, 3, 31, 1, 30, -3, +31, -6, 32, -7, 23, -2, 21, 1, +26, 2, 32, 3, 34, 10, 31, 15, +31, 16, 32, 10, 30, 1, 26, -9, +29, -12, 25, -13, 17, -12, 21, -10, +27, -3, 29, 5, 32, 11, 40, 13, +42, 16, 36, 15, 31, 11, 29, 3, +25, -4, 16, -11, 14, -13, 21, -10, +23, -7, 26, -5, 35, 3, 42, 11, +37, 17, 33, 17, 29, 14, 28, 6, +21, 3, 20, -2, 22, -4, 20, -4, +23, -5, 35, -9, 42, -6, 38, -4, +36, -1, 33, 4, 27, 6, 30, 2, +31, 5, 25, 10, 22, 12, 27, 8, +29, 3, 30, -8, 32, -11, 32, -11, +33, -11, 31, -10, 30, -1, 30, 7, +28, 15, 26, 19, 27, 18, 29, 10, +26, 4, 31, -7, 38, -19, 39, -23, +36, -19, 33, -14, 32, -3, 30, 5, +26, 11, 23, 15, 29, 16, 30, 11, +31, 6, 35, -3, 35, -9, 36, -16, +39, -15, 36, -12, 26, -5, 23, -1, +22, 6, 23, 11, 24, 10, 26, 3, +35, 3, 39, 3, 36, 0, 38, -3, +39, 0, 28, 2, 20, 4, 23, -1, +22, -6, 19, -7, 23, -5, 30, -8, +37, -5, 41, 0, 41, 9, 36, 15, +33, 16, 31, 8, 28, 1, 22, -8, +22, -13, 25, -15, 27, -11, 28, -8, +32, 0, 39, 6, 38, 10, 37, 10, +35, 9, 29, 3, 24, -4, 27, -8, +28, -7, 24, -2, 24, 1, 31, -1, +40, -3, 42, 1, 35, 3, 33, -4, +33, -5, 32, -4, 27, -4, 25, -3, +27, 1, 30, 3, 31, 5, 33, 3, +38, 1, 37, -1, 35, -4, 35, -6, +31, 1, 22, 1, 19, -2, 24, -3, +32, 0, 35, 1, 32, 3, 36, 1, +42, 0, 39, 0, 32, 1, 29, -6, +28, -6, 23, -1, 19, 3, 24, 3, +30, 5, 36, 0, 43, -3, 49, -1, +43, -1, 30, -8, 28, -8, 30, -8, +18, 2, 11, 7, 20, 7, 29, 7, +32, 11, 41, 6, 48, -1, 43, -6, +35, -8, 34, -10, 31, -8, 20, -8, +15, -4, 25, 0, 29, 6, 27, 7, +35, 9, 44, 2, 45, -5, 45, -3, +41, -2, 31, -10, 25, -12, 26, -10, +24, -7, 22, -4, 27, -1, 34, 0, +41, 6, 44, 7, 44, 4, 39, 2, +29, 1, 25, -6, 24, -5, 15, -5, +14, -7, 28, -6, 38, 2, 38, 2, +43, 3, 49, 2, 43, 0, 33, -2, +26, -1, 25, -9, 23, -10, 20, -7, +27, -4, 39, -3, 38, -1, 36, 0, +45, 2, 48, 1, 34, -1, 25, 0, +27, 6, 20, 5, 9, -1, 19, -6, +38, -10, 41, -13, 38, -9, 50, -5, +56, 0, 39, 4, 30, 8, 30, 9, +19, 9, 8, -4, 18, -13, 31, -11, +30, -7, 33, -9, 47, 0, 52, 8, +41, 11, 35, 10, 34, 4, 27, -2, +16, -3, 18, -9, 25, -16, 30, -14, +40, -6, 48, -5, 48, -1, 47, 1, +45, 0, 40, -1, 31, 0, 24, -2, +21, -2, 23, -1, 26, -1, 30, 1, +35, 0, 39, -9, 45, -9, 44, -3, +38, -2, 30, -4, 28, 0, 28, 2, +26, 6, 28, 4, 29, 1, 33, 0, +38, 1, 41, -5, 42, -8, 37, -8, +30, -8, 30, -10, 34, -6, 28, -8, +26, -6, 38, 0, 46, 6, 39, 10, +34, 14, 38, 6, 33, -1, 23, -3, +23, -9, 27, -19, 21, -15, 21, -7, +39, -2, 50, 1, 44, 2, 45, 3, +51, 10, 41, 4, 27, -6, 23, -6, +18, -2, 14, -3, 18, -2, 28, -2, +35, -4, 42, -7, 53, -8, 58, -11, +53, -8, 41, -6, 31, -3, 26, 3, +23, 8, 15, 4, 11, 4, 22, 2, +40, -6, 50, -16, 51, -12, 51, -9, +49, -3, 38, -2, 29, -1, 23, 1, +13, 6, 12, 2, 25, -1, 37, -1, +40, 0, 43, -2, 51, -1, 55, -8, +45, -10, 34, -11, 28, -11, 25, -9, +24, -3, 25, -2, 26, 4, 32, 9, +43, 4, 50, -8, 51, -7, 47, -8, +41, -10, 37, -9, 35, -8, 29, -6, +25, 2, 26, 1, 31, -4, 35, -6, +43, -7, 46, -10, 43, -3, 43, -2, +47, -4, 39, 1, 25, 8, 23, 3, +30, -4, 33, -14, 36, -17, 46, -10, +47, -3, 38, -3, 37, 4, 38, 10, +26, 6, 20, -1, 29, -3, 32, -5, +29, -3, 38, -6, 51, -7, 50, -3, +44, 0, 45, -4, 36, -2, 20, -1, +20, -8, 28, -7, 24, 4, 21, 3, +41, -3, 56, -5, 54, -4, 52, -6, +52, -5, 41, -10, 26, -5, 20, 6, +16, 5, 15, -3, 20, 1, 33, -1, +47, -6, 51, -8, 51, -8, 54, -7, +50, 3, 33, 6, 23, 4, 20, 2, +18, -2, 21, -11, 30, -7, 39, -7, +41, -11, 48, -6, 58, 1, 55, -1, +41, -2, 35, -5, 34, -7, 25, -7, +22, -9, 34, -14, 39, -6, 36, 3, +44, 3, 57, -1, 46, -3, 34, -9, +42, -13, 45, -15, 28, -15, 24, -10, +41, -3, 40, 1, 33, 6, 46, 4, +55, -4, 42, -8, 35, -3, 42, -5, +34, -9, 20, -9, 22, -3, 34, 0, +35, 0, 32, -7, 44, -6, 57, -2, +54, -4, 48, -7, 46, 3, 36, 4, +21, 0, 18, -2, 23, -6, 27, -13, +30, -11, 41, -11, 56, -6, 60, 2, +49, 5, 43, 4, 39, 11, 28, 3, +19, -8, 23, -10, 26, -6, 30, -7, +42, -8, 55, -8, 54, -5, 51, -1, +48, -5, 42, -11, 32, -5, 27, -1, +26, -1, 25, 3, 32, 5, 45, 0, +47, -2, 44, -7, 50, -12, 51, -13, +39, -12, 32, -10, 34, 2, 28, 7, +22, 4, 30, 5, 38, 7, 36, -5, +41, -11, 53, -10, 51, -3, 35, -1, +36, -2, 46, -9, 38, -5, 28, -2, +33, -10, 39, -13, 36, -7, 40, -6, +48, 0, 44, 5, 37, 3, 39, -2, +44, -5, 39, -8, 30, -9, 29, -10, +43, -12, 47, -9, 40, 6, 39, 3, +46, -4, 43, -1, 31, 2, 29, -4, +29, -5, 25, -6, 26, -2, 38, 3, +47, 1, 41, -4, 44, -1, 57, -5, +54, -11, 38, -10, 32, -5, 31, -5, +23, -1, 21, 0, 28, -3, 36, -6, +42, -7, 53, -10, 61, -3, 58, -2, +49, -5, 39, 0, 34, 6, 26, -2, +14, -7, 13, -10, 28, -10, 44, -8, +46, -4, 50, -4, 61, 3, 60, 5, +45, 0, 37, -7, 34, -7, 23, -14, +18, -13, 31, -3, 35, 4, 31, 2, +41, 3, 58, -1, 57, -5, 48, -12, +44, -17, 41, -14, 34, -2, 29, 0, +29, 2, 27, 9, 29, 9, 39, -3, +48, -11, 46, -17, 48, -15, 48, -8, +40, -2, 37, -2, 38, 6, 33, 5, +27, 1, 34, 0, 38, -3, 35, -12, +39, -10, 47, -5, 48, -3, 42, -6, +42, -7, 42, -6, 35, -1, 31, -6, +37, -11, 42, -4, 40, 4, 41, 0, +46, 0, 45, 0, 36, -2, 29, -8, +33, -12, 38, -17, 35, -10, 36, -2, +46, 3, 45, 8, 38, 9, 45, -2, +49, -7, 36, -7, 26, -10, 33, -11, +33, -2, 22, 5, 26, 7, 46, 0, +51, -7, 45, -9, 51, -6, 54, -13, +37, -12, 28, 2, 32, 9, 25, 7, +16, 8, 28, 0, 47, -9, 48, -13, +46, -15, 56, -18, 56, -10, 44, -7, +40, -2, 36, 7, 24, 7, 19, -2, +29, 0, 35, 1, 33, -6, 41, -10, +54, -8, 52, -4, 43, 2, 39, -4, +37, -8, 32, -2, 28, 1, 33, -8, +36, -3, 32, 4, 34, 3, 42, 0, +43, -1, 34, -7, 37, -8, 45, -8, +40, -4, 33, 2, 32, 8, 35, 3, +32, 2, 34, 1, 41, -10, 42, -18, +37, -12, 41, -6, 48, -1, 39, -1, +32, -1, 41, 2, 44, 0, 37, -12, +37, -13, 42, -6, 39, -4, 39, -6, +47, -2, 49, -6, 41, -8, 38, -6, +39, -6, 33, -11, 30, -10, 38, -9, +44, 0, 42, 11, 42, 10, 45, 0, +40, 0, 34, -2, 34, -11, 31, -17, +26, -13, 30, -6, 41, 2, 45, 1, +46, 4, 45, 9, 45, 5, 40, -8, +39, -11, 37, -11, 30, -10, 26, -6, +32, -1, 40, -3, 42, -2, 42, -4, +46, -4, 48, 0, 43, 1, 35, -4, +33, 3, 35, 6, 32, -4, 31, -13, +41, -13, 45, -16, 40, -15, 43, -9, +47, -1, 42, 7, 33, 11, 39, 4, +44, 3, 33, 3, 28, -9, 39, -20, +47, -16, 39, -13, 38, -7, 43, -2, +41, 2, 37, -2, 42, -2, 45, -6, +36, -1, 33, 2, 37, -4, 41, -5, +40, 3, 38, -1, 39, -8, 40, -11, +41, -11, 36, -11, 35, -7, 41, -10, +42, -4, 37, 7, 39, 7, 44, 0, +40, -1, 40, -8, 48, -13, 47, -11, +33, -4, 28, -3, 35, -2, 32, -1, +27, 0, 34, -3, 44, -7, 43, -10, +46, 0, 51, 3, 49, -3, 42, -4, +36, 2, 33, -3, 28, -8, 22, -13, +29, -15, 40, -11, 48, -3, 49, -1, +49, 6, 52, 5, 50, -1, 40, -7, +33, -8, 31, -14, 27, -15, 28, -8, +35, 0, 43, 1, 42, 2, 46, -3, +54, -3, 51, -5, 41, -13, 35, -13, +34, -1, 31, 2, 30, 1, 31, 2, +34, 3, 38, -3, 43, -8, 46, -14, +44, -11, 45, -8, 45, -6, 42, -2, +39, 5, 40, 1, 34, -7, 32, -8, +43, -6, 41, -12, 32, -10, 39, -4, +48, 1, 44, 2, 36, -1, 41, -7, +45, -4, 37, -6, 33, -11, 43, -11, +46, -3, 34, -1, 37, 3, 45, 3, +37, -1, 30, -7, 40, -9, 44, -13, +39, -8, 38, -5, 43, -4, 45, 0, +41, 6, 38, -2, 42, -6, 40, -5, +32, -2, 31, -3, 35, -1, 33, 0, +29, 5, 35, 1, 48, -12, 50, -15, +44, -5, 45, -6, 43, -6, 38, 0, +34, 4, 34, 5, 29, 3, 30, -8, +44, -14, 50, -14, 45, -13, 46, -10, +49, -2, 45, -2, 39, -3, 37, 2, +32, 3, 27, -5, 31, -7, 41, -7, +44, -6, 46, -5, 50, -2, 47, -1, +38, 2, 34, -4, 35, -13, 31, -13, +30, -4, 35, 0, 36, 7, 35, 8, +43, 6, 52, 2, 44, -4, 38, -12, +38, -13, 35, -14, 30, -10, 27, 3, +33, 10, 36, 3, 39, 3, 44, 5, +46, 3, 37, -6, 35, -10, 39, -10, +38, -1, 32, 2, 28, 1, 32, 1, +36, 4, 37, -5, 38, -9, 42, -5, +40, 1, 35, 2, 38, 7, 40, 6, +36, 3, 32, -2, 34, -9, 41, -15, +39, -13, 38, -16, 43, -11, 46, 3, +41, 9, 41, 3, 42, 2, 38, -1, +38, -6, 40, -10, 39, -13, 36, -13, +42, -1, 43, 1, 38, -4, 43, -7, +50, -8, 44, -11, 34, -3, 34, 3, +31, 3, 28, 5, 33, 8, 39, 6, +44, 1, 42, -8, 44, -12, 45, -9, +41, -6, 35, -12, 35, -4, 32, 6, +28, 5, 35, 2, 38, 2, 37, 0, +42, 0, 46, -3, 46, -5, 44, -3, +41, 1, 35, -5, 34, -5, 34, -5, +33, -10, 36, -12, 39, -4, 44, -1, +45, 1, 43, 3, 42, 4, 41, 3, +38, -1, 39, -10, 40, -10, 35, -4, +38, -4, 39, -6, 39, -2, 41, -2, +39, -5, 37, -7, 41, -8, 44, -10, +43, -4, 44, -2, 45, 3, 43, 7, +39, 2, 40, -7, 39, -7, 34, -11, +35, -18, 41, -17, 44, -7, 38, 1, +37, 9, 44, 6, 43, 3, 39, 2, +40, -4, 47, -16, 42, -12, 38, -6, +43, -6, 38, -4, 33, -1, 38, -4, +40, -2, 34, -5, 35, -7, 42, -6, +49, -3, 50, -3, 46, 3, 45, 5, +42, -1, 34, -5, 29, -5, 28, -11, +28, -11, 31, -6, 34, 3, 36, 9, +47, 9, 50, -1, 52, -3, 53, -2, +44, -4, 32, -9, 24, -3, 25, -2, +28, 0, 27, 3, 28, 1, 42, -3, +51, -2, 49, -7, 53, -9, 54, -3, +44, 0, 36, -2, 35, 0, 36, -4, +34, -7, 28, -6, 31, -2, 40, -3, +40, 0, 40, -2, 47, -3, 55, -1, +49, -2, 39, -8, 40, -4, 39, -4, +33, -6, 33, -5, 40, 2, 37, 2, +33, 3, 42, 0, 46, -6, 45, -9, +42, -8, 42, -9, 46, -3, 39, 0, +37, -2, 44, -3, 41, 4, 34, 1, +37, -1, 36, -2, 34, -1, 37, 0, +38, 0, 42, -5, 43, -4, 43, -4, +45, -8, 45, -8, 39, -1, 39, -2, +40, -3, 38, 4, 38, 8, 32, 2, +33, -2, 42, -9, 44, -15, 45, -14, +50, -11, 49, -6, 43, 5, 43, 6, +41, 4, 35, 4, 30, 6, 23, -2, +29, -7, 40, -13, 41, -9, 45, -3, +54, -1, 52, -3, 48, 1, 46, -3, +42, -8, 36, -9, 31, -8, 37, -9, +39, 0, 34, 6, 35, 6, 46, 0, +52, -7, 47, -15, 46, -15, 49, -14, +42, -9, 32, 2, 31, 13, 36, 13, +34, 9, 37, 1, 47, -5, 45, -9, +37, -13, 40, -21, 47, -14, 43, -5, +38, -1, 41, 3, 42, 10, 41, 4, +46, -1, 44, -1, 39, -5, 42, -7, +39, -3, 33, -5, 34, -3, 35, -2, +34, -5, 40, -7, 44, 1, 41, 1, +45, 1, 43, 7, 41, 10, 45, 3, +38, 2, 30, -3, 34, -4, 30, -5, +28, -10, 37, -12, 41, -2, 43, 0, +48, 2, 52, 4, 51, 6, 48, -1, +46, -4, 45, -7, 40, -10, 31, -14, +35, -14, 39, -14, 41, -9, 47, -7, +48, -5, 54, 2, 56, 8, 49, 2, +51, -2, 48, -4, 37, -9, 34, -16, +42, -18, 38, -17, 33, -8, 39, 1, +44, 5, 44, 9, 46, 12, 46, 5, +49, -2, 47, -7, 45, -11, 44, -15, +37, -9, 34, -4, 34, 0, 34, -1, +37, -1, 36, 1, 42, 1, 51, -7, +51, -5, 49, 4, 48, 6, 44, -1, +43, -4, 47, -10, 37, -13, 29, -14, +36, -12, 34, -10, 36, -2, 46, 6, +45, 11, 49, 13, 54, 9, 49, -3, +48, -8, 41, -12, 34, -17, 33, -15, +31, -6, 28, 2, 31, 11, 38, 11, +41, 10, 44, 5, 49, 0, 51, -12, +57, -15, 49, -13, 45, -8, 44, -6, +33, 0, 31, 0, 33, 1, 30, -2, +35, -1, 37, 1, 40, 5, 48, 1, +53, 1, 53, 1, 53, -3, 50, -10, +40, -11, 37, -13, 33, -10, 25, -8, +33, -2, 36, 9, 32, 18, 42, 12, +52, 7, 52, 2, 50, -6, 54, -17, +48, -18, 37, -18, 41, -14, 37, -8, +33, 0, 39, 4, 41, 9, 45, 7, +47, 5, 48, -1, 51, -8, 50, -14, +44, -11, 41, -10, 42, -11, 41, -9, +39, 0, 41, 6, 39, 7, 42, 3, +44, 2, 41, -3, 50, -8, 48, -15, +45, -12, 50, -7, 41, -4, 42, -3, +47, 1, 41, 0, 40, -1, 46, -5, +43, -6, 42, -3, 45, 3, 32, 2, +38, 3, 50, 2, 37, 0, 39, -10, +51, -13, 46, -17, 49, -13, 50, -8, +43, 1, 46, 10, 42, 15, 39, 7, +44, 0, 42, -7, 37, -16, 40, -24, +44, -17, 41, -10, 44, -1, 43, 11, +46, 23, 47, 20, 38, 12, 43, -1, +43, -9, 32, -15, 35, -18, 36, -20, +38, -8, 43, 2, 42, 7, 49, 6, +56, 6, 48, 2, 46, -4, 53, -12, +48, -11, 39, -11, 44, -7, 43, -5, +35, -1, 39, -2, 40, -6, 41, -10, +43, -5, 43, 0, 45, 5, 42, 8, +48, 12, 48, 10, 43, 5, 47, -7, +40, -13, 33, -18, 37, -21, 36, -18, +33, -6, 41, 3, 49, 10, 49, 14, +56, 17, 57, 9, 48, 0, 49, -11, +42, -17, 31, -19, 33, -15, 26, -8, +26, 2, 37, 7, 43, 10, 51, 10, +53, 9, 57, 1, 57, -4, 49, -10, +46, -11, 38, -10, 36, -11, 37, -11, +35, -1, 36, 2, 38, 2, 42, 2, +42, 2, 52, -1, 55, 1, 42, 3, +46, 4, 51, 1, 41, -2, 38, -6, +39, -7, 37, -12, 34, -15, 37, -13, +48, -4, 45, 1, 47, 10, 52, 14, +51, 15, 50, 6, 46, -6, 45, -19, +44, -20, 38, -19, 28, -13, 35, -9, +51, 2, 43, 11, 47, 15, 57, 12, +44, 6, 48, -9, 53, -19, 42, -22, +44, -15, 39, -6, 31, 5, 38, 13, +38, 19, 35, 13, 40, 5, 44, -3, +40, -9, 46, -14, 46, -11, 40, -2, +45, 8, 38, 10, 40, 8, 45, 3, +33, 1, 40, -6, 41, -12, 35, -11, +48, -3, 47, 0, 41, 7, 52, 9, +49, 7, 36, -1, 44, -9, 45, -15, +31, -12, 40, -9, 41, 0, 33, 9, +47, 17, 45, 17, 37, 14, 46, 4, +39, -9, 42, -23, 51, -26, 43, -20, +40, -8, 45, 1, 49, 9, 46, 12, +48, 15, 47, 8, 41, -2, 41, -10, +37, -13, 40, -19, 41, -16, 41, -5, +45, 7, 43, 8, 47, 9, 50, 8, +44, 2, 50, -7, 48, -12, 39, -12, +42, -7, 40, -7, 40, -2, 39, 2, +43, 7, 42, 2, 40, -4, 53, -9, +52, -8, 48, -10, 53, -5, 48, 4, +40, 12, 37, 10, 37, 6, 30, 1, +32, -7, 41, -18, 36, -16, 42, -8, +48, 1, 45, 5, 58, 15, 55, 21, +41, 21, 42, 8, 37, -6, 31, -19, +32, -22, 31, -22, 29, -12, 36, 1, +49, 13, 50, 18, 55, 21, 58, 13, +54, 1, 53, -12, 41, -17, 37, -20, +32, -15, 27, -7, 35, 4, 33, 9, +40, 11, 51, 7, 47, 0, 56, -10, +63, -13, 53, -12, 46, -5, 47, 2, +38, 10, 29, 11, 31, 8, 27, 1, +29, -4, 40, -14, 39, -16, 51, -13, +59, -3, 54, 7, 55, 15, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_48000_2ch_16b.c b/USDK/example_sources/i2s/src/birds_48000_2ch_16b.c new file mode 100644 index 0000000..9bb76a1 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_48000_2ch_16b.c @@ -0,0 +1,34985 @@ +#include +int sample_size=139916; + +SECTION(".sdram.data") +short sample[]={ +1, 1, -2, 0, 0, 1, 1, 0, +-1, 2, -2, 2, 0, -1, 1, -1, +2, 0, 1, 2, -4, 4, -3, 5, +-4, 1, -1, 2, 0, -2, 2, -1, +2, 0, 0, 2, -2, 0, 1, -2, +2, -1, 1, -1, 2, 1, -1, 1, +-2, 2, -3, -1, 3, -1, 1, -2, +2, 0, 2, 0, -1, 2, -3, 3, +-4, 3, -3, 4, -2, 0, 2, 0, +1, -2, 1, -1, -2, -1, 0, 0, +3, -3, 5, -3, 4, -4, 3, -3, +1, -2, 1, -3, 3, -2, 2, 0, +2, 1, 0, -3, 4, -5, 2, -6, +3, 0, 0, 1, 0, 2, 1, 1, +-3, 1, -5, 2, -3, 0, 1, 0, +1, -1, 3, 0, 0, -2, 0, 1, +-3, 1, -3, 2, 0, -1, 4, -2, +3, -1, -2, 2, -5, 4, -5, 2, +1, 1, 2, -1, 2, 2, -2, 0, +-1, 0, -1, -3, 1, 0, 0, 3, +0, 1, 3, -4, 4, -6, 2, -2, +0, -2, 2, 0, 2, 0, 2, 3, +-3, 1, -3, 0, -1, -1, 2, -3, +5, -4, 5, -1, 2, 1, -1, -1, +-1, 0, -2, -1, 2, -1, 4, -2, +4, 0, 0, -1, -1, -1, -1, -3, +3, -2, 3, 1, -1, 3, -1, 3, +-3, 0, -2, 0, -1, -3, 4, -1, +3, -3, 5, -1, 1, -2, -1, -1, +-1, -2, 1, -1, 3, 0, 3, 0, +2, 1, -3, -1, -1, 0, 0, -3, +2, 1, 0, 2, 0, 2, 0, -2, +1, -1, -4, 2, -5, 4, 0, 3, +-1, 1, 0, 1, -1, -3, 1, -3, +1, -1, 1, 3, -2, 3, 0, 1, +1, -2, 0, -1, -2, 2, -2, 1, +1, 0, 3, -1, 4, -2, 0, -4, +2, -2, 1, -3, 4, -3, 5, -2, +2, 2, -2, 0, -1, -2, 2, -3, +1, -2, 3, 1, 0, 1, -2, 4, +-4, 2, -4, 3, -5, 1, 2, 0, +2, -1, 0, 2, -1, 0, 1, -3, +1, -1, 0, 1, 0, 4, -4, 3, +-1, 2, -2, -1, 0, 0, 0, -2, +4, -4, 6, -5, 5, -1, -1, 2, +-4, 1, 1, -1, 0, -1, 2, 2, +0, 0, -1, 2, -4, 3, -4, 3, +-3, -1, 3, -2, 4, -3, 3, -2, +3, -3, 1, -2, -1, 1, -2, 2, +-1, 3, -1, -2, 3, -2, 0, -3, +1, -1, 1, 1, -1, 3, -4, 4, +-3, 2, -1, -1, -1, -1, 1, 1, +-1, -2, 4, -2, 3, -1, -1, 2, +-3, 1, -1, 2, -3, 2, -2, 2, +0, 3, -4, 4, -5, 3, -1, -1, +1, 0, -1, 0, 2, 1, -1, -1, +1, 1, -1, 0, -2, 2, -2, 2, +0, 1, -1, 2, -3, 2, -1, 1, +-3, 0, 0, 2, 0, -1, 1, 1, +-1, 1, -1, 1, -2, 0, 0, 1, +0, 0, 0, 1, 1, 2, -1, 0, +-1, 0, 1, -3, 4, -2, 2, -2, +3, 0, 0, -1, 0, 0, 1, -1, +1, -1, 2, -2, 2, -1, 1, 1, +-1, -2, 2, 0, -1, -1, 2, -1, +3, -3, 3, -1, 1, -1, 0, 1, +-2, 0, 0, -1, 3, -1, -1, 0, +-1, 3, -2, 1, -2, 1, -1, 0, +1, 0, 1, -3, 4, -1, 0, 1, +-4, 2, -2, 3, -2, 2, -2, 2, +-2, 3, -3, 4, -5, 0, 1, 1, +-2, 1, -2, 4, -2, 2, -2, 2, +-2, 0, 1, -1, 0, -1, 1, -1, +2, 1, -3, 2, -4, 5, -5, 4, +-5, 4, -4, 2, 0, 2, -2, -1, +2, -2, 3, -1, -2, 0, 0, 0, +1, -1, 1, 0, 1, -1, 1, 1, +-3, 0, 1, 1, 0, 1, -1, 1, +1, -2, 2, -1, -1, -1, 2, -2, +3, 0, -3, 3, -2, 4, -2, -1, +1, -1, 1, 0, -1, 3, -4, 2, +2, 2, -1, -1, 1, -1, 4, -2, +-1, -1, 1, 2, 0, 1, -1, 1, +1, -4, 6, -4, 2, -2, 2, 1, +0, 1, -2, 2, 0, -2, 3, -1, +-2, 4, -5, 4, 0, 1, -1, -2, +3, 0, 0, 0, -4, 4, -4, 2, +-1, 2, -3, 1, 0, 2, -2, 2, +-5, 3, -3, 5, -5, 3, -3, 3, +0, -1, 2, 0, -2, -1, 1, 1, +-1, -1, 1, -2, 5, -4, 2, -2, +0, 1, 0, 0, -3, 2, -4, 2, +0, 3, -4, 1, 0, 1, 0, 1, +-3, 3, -4, 2, 1, 1, -1, 0, +0, 1, -1, 3, -5, 1, 0, 1, +0, -1, 1, -1, 2, -3, 5, 0, +-3, 2, -2, 3, -3, 2, -3, 1, +2, 0, 2, -2, 1, -2, 2, -1, +1, 1, -3, -1, 5, -2, 3, -5, +3, -2, 4, -2, 0, 0, -2, 0, +3, -1, 1, 0, 0, -1, 4, -2, +-1, -1, -1, 3, -1, 2, -2, 2, +-1, -1, 4, 0, -2, 0, -1, 3, +-2, 4, -4, 1, 1, -1, 5, -3, +0, 0, -3, 1, 2, 0, -1, -3, +4, 2, 0, 0, -1, -1, 2, 0, +-1, 2, -5, 4, -2, 3, -2, 4, +-5, 2, -1, 3, -3, 1, -2, 0, +2, -1, 0, 3, -5, 4, -3, 5, +-6, 4, -6, 3, -2, 3, -3, 2, +-3, 4, -3, 3, -3, 2, -3, 0, +0, 4, -6, 4, -4, 5, -3, 4, +-5, 3, -2, 0, 0, 1, -4, 3, +-4, 4, -2, 5, -6, 1, 0, 0, +2, -4, 2, -4, 4, -4, 6, -2, +0, -3, 3, -2, 3, -3, -1, -2, +4, -1, 1, -2, 0, 0, 3, -3, +2, 0, -4, 1, 1, 1, -1, 0, +-2, 2, 1, 1, -1, 0, -1, -1, +2, -1, 0, 1, -4, 4, -1, 6, +-6, 3, -4, 5, -2, 2, -2, 0, +0, -1, 4, -1, 0, -2, 3, -3, +5, -2, -1, -1, 2, 2, -1, 2, +-4, 3, 0, -1, 3, -1, -1, -3, +3, -2, 3, 0, -2, 1, 0, 1, +1, 0, -2, 0, 1, -1, 1, 1, +-3, 0, 3, 0, 0, 1, -2, 2, +-1, 0, 1, -1, 0, -2, 3, -1, +2, -1, -1, 0, 1, 2, -3, 1, +-2, 2, 0, 0, 0, -1, 0, -2, +3, 1, -4, 2, -3, 3, -2, 3, +-4, 0, 1, -1, 2, 0, -3, 2, +-1, -3, 6, -3, -1, -1, 0, 2, +0, -1, -2, 0, 0, 0, 2, -4, +2, -4, 5, -3, 3, -1, -2, -3, +4, -1, 0, -1, -2, 2, -1, 1, +0, 0, 0, -4, 6, -4, 3, -4, +3, -6, 8, -4, 2, -1, -1, 1, +1, -1, 2, -1, -1, -1, 2, 3, +-4, 1, -2, 2, 1, 2, -4, 4, +-5, 5, -3, 4, -5, 3, -1, -2, +6, -2, -1, -2, 1, 2, 0, 0, +-1, -1, 3, -3, 5, -1, -2, 0, +2, -1, 3, -1, -2, 0, 2, 1, +0, 0, -2, 3, -1, 1, 0, 3, +-5, 2, 1, 1, 0, -1, -1, 1, +1, 2, -1, 1, -3, 2, -1, 2, +-1, 1, -2, -1, 4, 0, 0, -3, +2, 1, 1, 2, -4, 2, -2, 1, +1, 3, -5, 3, -3, 0, 4, -2, +0, -2, 1, 2, -1, 2, -3, 1, +0, -1, 3, 0, -2, -2, 4, -2, +3, -2, -3, 1, 0, 1, -1, 0, +-2, -1, 2, -1, 1, 2, -5, -1, +3, 0, -1, 2, -5, 4, -2, 1, +-1, 1, -4, 2, -1, 2, -2, 1, +-4, 1, 1, 1, -1, -2, 1, -2, +3, -2, 1, -1, -1, -2, 4, 1, +-4, 3, -6, 6, -3, 4, -6, 2, +0, -1, 3, -4, 2, -2, 4, -6, +8, -5, 2, -4, 4, -1, 2, -2, +1, -3, 4, -2, 2, 2, -6, 5, +-4, 4, -2, 3, -5, 1, 2, 1, +1, -2, 2, -3, 5, -3, 4, 0, +-4, 2, 0, 2, -1, 0, -1, -1, +6, -3, 3, -5, 3, -2, 3, -1, +1, 0, -1, 0, 2, 3, -3, 0, +1, -1, 4, -1, -1, 0, 0, 0, +3, 0, -1, 1, 0, -1, 4, 0, +-2, -1, 2, 0, 2, -1, -2, 2, +-2, 2, -1, 3, -4, -1, 3, -1, +3, 0, -2, -1, 3, -1, 1, -2, +0, -1, 2, -3, 2, 1, -2, -2, +3, -1, 0, -1, -3, 3, -2, 4, +-5, 3, -3, 0, 3, -3, 2, -1, +-1, -2, 5, -3, 1, -4, 2, 0, +2, -1, -1, 0, -1, -2, 2, -1, +-1, -1, -1, 0, 1, 3, -6, 2, +-2, 3, 0, -2, 0, -2, 2, -2, +2, 2, -4, 1, 0, 1, 1, -1, +-2, -2, 2, -1, 3, -2, -1, 1, +0, 1, 2, 0, -3, -1, 2, 2, +-2, 1, -3, 2, 1, 1, 1, -1, +-1, -2, 4, -3, 3, -2, 0, -1, +4, 0, 1, -2, 2, -2, 3, -1, +1, 0, -2, 0, 3, 1, -1, -1, +2, -2, 5, -2, -1, -1, 2, -2, +4, -3, 2, -2, 1, -1, 4, 0, +-2, -2, 2, 0, 2, -1, 0, -2, +5, -5, 7, -5, 2, -3, 4, -4, +6, -4, 1, -2, 3, 2, -1, 1, +-3, 3, -1, 2, -2, 2, -3, -1, +4, -2, 3, -3, 2, -3, 5, -2, +-1, 0, -2, 1, 1, -1, 0, 1, +-1, -2, 5, -2, -1, -1, -2, 3, +-2, 2, -3, 1, 0, -1, 3, -1, +-2, 3, -4, 2, 0, 2, -5, 1, +0, 1, 1, -2, -1, 1, -1, 0, +0, 1, -3, 0, 0, 2, -1, 3, +-6, 3, -2, 3, -2, -1, -1, -1, +1, 0, 0, 3, -5, 0, 1, 2, +-2, 0, -3, -1, 4, -3, 2, -3, +1, -2, 5, -4, 4, -4, 1, -4, +5, 0, -2, -1, 0, 1, 2, 0, +-1, 1, -2, 1, 0, 4, -5, 2, +-1, -1, 5, -1, -1, 0, 0, 2, +0, 0, -2, 2, 0, 0, 2, 1, +-3, 3, -2, 4, -2, 3, -4, 1, +1, -1, 3, -2, 1, -1, 3, -3, +5, -2, 1, -4, 6, -2, 2, -1, +-1, 2, 1, -1, 3, -3, 3, -3, +4, -1, 1, 1, -1, -1, 5, -2, +3, -4, 3, -1, 1, 0, -1, 3, +-4, 2, 0, 3, -3, 1, -2, 1, +1, 2, -3, 0, 0, 0, 2, 2, +-4, 4, -5, 2, 0, 3, -5, 1, +-1, 1, 1, -2, 1, -3, 2, -1, +1, 0, -3, 1, -1, 0, 1, 2, +-5, 2, -1, 2, -1, -2, 1, -2, +3, -4, 4, -2, -1, -1, 1, 1, +0, 0, -2, -2, 3, -1, 0, -1, +-1, 2, -1, 0, 0, 0, -1, -1, +0, 3, -4, 2, -3, 4, -1, 2, +-2, -1, 0, 0, 1, -1, -1, 0, +0, -1, 2, 2, -4, 2, -1, 1, +1, -2, -1, 0, -1, 0, 2, 0, +-1, -1, 3, -1, 2, 1, -4, 2, +0, 3, -2, 2, -2, 1, 2, -2, +3, 2, -5, 3, -2, 3, -2, 1, +-2, 2, 0, 2, -2, 0, 0, -1, +3, -2, 1, 0, -2, 0, 4, 0, +0, -1, 0, 2, 0, 0, 1, -1, +1, 0, 2, 1, 1, -2, 3, -4, +5, -1, -2, 1, -1, 2, 1, -2, +3, -2, 2, -1, 1, 2, -4, 2, +-3, 2, -1, 0, 0, -1, 2, 0, +0, 0, -1, 1, -2, 1, -2, 5, +-7, 3, 0, 1, 1, -4, 3, -5, +4, -2, 0, 2, -5, 4, -3, 2, +0, -1, 0, -3, 3, -1, 0, -3, +2, -2, 2, -1, 0, 1, -1, -1, +0, 1, -3, 1, -2, -1, 2, -1, +0, 0, -2, 3, -3, 3, -4, 3, +-4, 1, 0, 1, -2, 0, 0, 3, +-2, 2, -4, 3, -3, 2, 0, 0, +-1, 0, 0, 0, 1, 1, -2, -1, +1, 0, 1, -4, 3, -3, 4, -3, +4, -1, 0, -1, 3, -2, 2, -2, +-2, 2, -1, 3, -2, 0, 1, 0, +1, 0, -1, 2, -3, 0, 3, 0, +0, -1, 0, 4, -2, 4, -4, 1, +-1, 1, 1, 0, 1, -1, 2, -3, +5, -1, 0, -1, 0, 2, -2, 1, +-1, 2, 0, 0, 1, 2, -3, 3, +-3, 4, -4, 6, -7, 4, -1, 1, +2, -3, 1, 2, -2, 2, -3, 4, +-4, 2, 1, 0, 2, -4, 3, -2, +2, 0, -1, 1, -2, 1, 0, -2, +4, -2, 1, -1, -1, 5, -6, 3, +-3, 1, -1, 1, -2, 3, -4, 2, +-1, 1, -2, 3, -5, 3, -1, 1, +-2, 1, -2, 5, -5, 4, -4, 2, +-1, -3, 3, -2, 1, -2, 1, 0, +2, -2, 2, -4, 3, -2, 2, -3, +2, -3, 4, -5, 4, -2, 1, -3, +3, -1, 1, -2, 0, 0, -1, 1, +-1, 2, -2, 1, -1, 0, 1, 0, +-1, 0, 0, 2, -2, 0, 2, -2, +3, -3, 1, 1, -3, 2, -2, 1, +-1, 0, 1, 0, 1, -1, 0, -2, +2, -2, 2, -4, 4, -2, 1, 0, +1, 1, -1, -2, 2, -1, 2, -3, +2, -2, 3, -1, 1, 0, -2, 4, +-4, 4, -3, 3, -3, 1, 1, 2, +-1, -1, 2, -2, 3, -3, 2, -1, +0, -1, 1, 0, 1, -1, 2, -1, +2, 0, -1, -1, 2, -2, 2, -2, +1, 2, -1, -1, 3, -1, 1, -1, +0, 1, 0, -1, 1, 0, 0, 2, +-1, 1, -1, 2, -2, 0, -1, 2, +-2, -1, 2, -1, 3, -4, 4, -3, +3, -3, 2, -2, 1, -3, 2, 0, +-1, 3, -3, 1, 0, 2, -5, 4, +-8, 8, -7, 4, -2, 3, -3, 2, +-1, 2, -2, 0, -2, 1, -1, 1, +-1, -1, 2, -1, 2, -2, 2, -1, +0, -3, 1, 1, -3, 1, -1, 2, +0, 0, -1, 0, 0, -1, 0, -1, +-1, 1, -1, 0, 2, 0, 0, -1, +1, 1, -1, -1, -2, 3, -3, 2, +-1, 2, 1, -2, 3, -2, 2, -1, +0, -1, 1, -2, 2, -2, 3, 1, +-1, 2, -3, 4, -3, -1, 1, -2, +3, -4, 3, -1, 1, 1, -1, 1, +-1, -1, 2, -3, 3, -2, 3, -3, +5, -2, 2, -2, 1, 1, 0, -3, +2, -2, 1, -1, 2, 0, 1, -1, +1, 0, -1, 2, -3, 3, -3, 3, +-1, 0, 3, -1, 1, 0, -1, 3, +-3, 0, 0, 0, -1, 2, -2, 2, +2, -3, 4, -2, -1, 3, -5, 3, +-1, 0, 0, -2, 3, 0, 1, -2, +0, 2, -5, 5, -7, 5, -4, 2, +-1, 1, -2, 4, -5, 4, -4, 1, +-1, -4, 5, -5, 5, -6, 5, -2, +3, -4, 3, -3, 1, -1, -1, 1, +-1, 1, 1, -1, 1, 0, -2, 2, +-3, 4, -5, 3, -4, 3, -1, -1, +3, -2, 1, -2, 2, 0, 0, -2, +-1, 0, 0, 1, -1, 0, 0, 3, +-4, 5, -6, 7, -6, 2, -1, 0, +2, -3, 4, -4, 4, -4, 3, 0, +-2, 0, 2, -4, 6, -6, 5, -3, +3, -1, 1, -2, 2, -1, 0, -1, +0, 1, 1, -2, 2, 2, -3, 4, +-3, 2, -2, 1, -2, 3, -2, 4, +-3, 2, -2, 3, -1, -1, 2, -2, +2, -2, 1, 1, -1, 1, 1, 0, +0, -1, 1, 0, 0, -1, 1, -1, +3, -2, 1, -3, 4, -2, 3, -4, +2, 1, -1, 0, 0, 1, 0, 1, +-3, 6, -7, 6, -5, 2, 0, 0, +0, 1, -1, 1, 1, -3, 4, -2, +0, 0, -1, 3, -3, 1, -1, 0, +1, -2, 1, 1, -2, 1, -1, 0, +-1, 2, -3, 2, -2, 3, -2, 1, +-2, 3, -4, 2, -1, 2, -2, 0, +-1, 1, 0, -2, 1, -2, 1, 0, +-2, 1, -1, 2, -1, 0, 0, 0, +1, -3, 2, 0, -2, 1, -1, 2, +-1, -1, 0, 1, 1, -1, 2, -3, +2, -2, 1, 0, -1, 3, -4, 3, +-3, 4, -3, 1, -2, 2, -2, 2, +-2, 5, -5, 4, -4, 5, -3, 1, +-1, -2, 3, -3, 3, -4, 4, -2, +3, -2, 0, 3, -3, -1, 2, -4, +5, -5, 4, -1, 1, 0, 1, -1, +0, -1, 0, 0, -1, 1, 0, -1, +2, 0, 1, -2, 2, 1, -2, 0, +-1, -1, 2, -3, 3, -1, 2, -1, +2, -1, 1, 0, -1, 0, 0, 0, +0, -1, 1, 1, 0, 1, -2, 3, +-2, 0, 1, -1, 0, 0, 0, -1, +4, -3, 3, -1, -1, 1, 0, -3, +3, -3, 2, -2, 2, 1, -1, 0, +0, 1, 0, -2, 0, 0, -1, 0, +0, 1, -1, 3, -3, 3, -3, 2, +-1, -4, 4, -4, 4, -4, 3, -1, +1, 0, 0, 3, -5, 2, -3, 3, +-3, 1, -1, 0, 1, 1, -1, 1, +-1, 0, 1, -3, 2, -1, -1, 0, +1, 2, -2, 0, -1, 0, 1, -3, +0, -1, -1, 0, 2, -2, 3, -1, +1, -1, 1, -1, 1, -3, 1, 1, +-3, 4, -3, 3, 1, -3, 5, -2, +-1, 1, -4, 3, -2, 1, 1, -2, +3, -2, 3, -3, 1, 0, -2, 1, +-2, 3, -3, 1, 0, 0, 2, -3, +2, -1, 0, 1, -3, 3, -3, 2, +-1, 0, 2, 1, -1, 1, -2, 3, +-2, -1, 0, 1, 0, -1, 2, -1, +2, -1, 1, 2, -3, 2, 0, -2, +3, -2, 1, -1, 2, -2, 3, -3, +1, 2, -4, 2, -1, 2, -2, 0, +1, 0, 2, -1, -2, 2, -2, 1, +-1, -2, 1, -1, 1, -1, 1, 1, +0, -1, 0, 2, -3, 1, -2, 2, +-1, 0, 2, -2, 2, -2, 2, 0, +-2, 3, -5, 3, -2, 2, -1, -1, +1, 0, 1, -2, 1, 1, -3, 1, +-2, 1, 0, -1, 1, -1, 2, -1, +1, -3, 3, -4, 4, -4, 2, -1, +0, -1, 2, 0, 0, -2, 1, -2, +3, -4, 2, -1, 0, 1, 0, 1, +-1, -1, 1, -2, 1, 0, -1, -1, +1, -1, 2, -2, 1, 1, -1, 0, +0, 0, 0, -3, 4, -4, 4, -4, +3, -2, 3, -3, 3, -1, -1, 4, +-4, 2, 0, -1, 2, -3, 2, 2, +-2, 2, -3, 2, 0, 0, 0, 0, +-1, 1, -1, 2, -2, 2, -3, 3, +-3, 5, -3, 0, 0, 0, 2, -3, +3, -3, 4, -3, 2, 0, -1, 0, +1, -2, 4, -3, 2, 1, -2, 4, +-3, 0, 0, -1, 2, -3, 2, 1, +-2, 1, -2, 4, -2, 1, -1, 0, +1, -1, 1, 0, 0, 1, -1, 2, +-2, 3, -3, 2, -2, 3, -1, -2, +2, -1, 1, -1, 0, 0, 1, -3, +5, -5, 6, -6, 5, -4, 3, 0, +-1, 1, -2, 3, -2, 1, -2, 3, +-2, 0, 0, 2, -3, 3, -4, 5, +-3, 3, -2, 1, -2, 4, -3, 2, +-2, 0, -1, -1, 1, 0, 1, -4, +4, -2, 2, 0, -2, 2, -2, 0, +1, -1, 0, 0, 0, 1, 0, 0, +-1, -1, 1, -1, 1, -3, 1, 1, +-1, 2, -3, 4, -4, 1, 1, -1, +1, -1, 0, 0, 0, 0, 1, -2, +3, -2, 1, 0, -1, 2, -2, 0, +0, 2, -2, 1, -1, 0, 2, -2, +2, -1, 0, 0, -1, 3, -3, 3, +-3, 2, 1, 0, 0, -1, 0, 1, +0, -1, 0, 0, 1, -2, 3, 0, +1, -1, 1, -1, 2, -2, 1, -2, +2, -1, 2, -2, 1, 0, 1, -1, +0, 1, -2, 1, -1, 1, -1, 0, +1, 1, 0, 1, -2, 3, -4, 3, +-3, 1, -1, 0, 0, -1, 3, -2, +3, -4, 2, 0, -2, 1, -2, 3, +-3, 2, -2, 2, -2, 1, -2, 3, +-3, 3, -5, 2, -1, 1, 0, -1, +1, 0, 0, -1, 1, 0, -1, -2, +1, -1, 2, -1, 0, 0, 0, 0, +1, -1, 0, -1, 1, -2, 2, -1, +1, -3, 3, 0, 0, -1, -1, 1, +0, -1, 0, 0, 0, 0, 1, 1, +-1, 0, -1, 1, 0, 2, -3, 1, +-2, 2, 0, 0, -1, 3, -2, 0, +1, 0, 0, -1, 0, 0, 2, -2, +2, -1, 0, 1, 0, 0, -2, 2, +-3, 1, 0, 0, 2, -4, 4, 0, +1, -1, 0, -2, 3, -3, 2, 0, +-1, 1, 0, 0, 0, 1, -1, 0, +0, 1, -1, -1, 1, 0, 1, -1, +0, 2, -1, 0, 2, -1, -1, 1, +-5, 6, -5, 5, -3, 0, 1, 0, +1, 0, -1, 1, -1, -1, 1, 1, +-1, -1, 1, -1, 3, -1, -1, 1, +-2, 1, 0, 1, -2, 2, -1, -1, +2, -1, -1, 1, -2, 4, -3, 0, +-1, 1, 1, -2, 2, -2, 2, -3, +3, -2, 2, -3, 1, -1, 0, 2, +-2, 0, 0, 1, 0, -1, 0, 1, +-2, 1, -1, 1, 0, -2, 1, 1, +-1, 4, -5, 5, -6, 6, -5, 5, +-5, 4, -3, 1, 0, 2, -2, 1, +-2, 2, -1, 0, 0, -1, 0, -2, +2, 0, 0, 0, -1, 0, -1, 3, +-3, 2, -1, 1, 0, 0, 0, 1, +-1, -1, 2, 0, 0, -3, 3, -4, +5, -6, 5, -3, 2, 0, 1, -2, +3, -4, 5, -4, 3, -1, 0, -2, +3, -1, 1, -1, 0, 0, 2, -4, +4, -4, 2, 1, -2, 4, -3, 3, +-2, 3, -2, 4, -4, 3, -4, 5, +-4, 3, -3, 3, -1, 0, 0, 1, +-1, 0, -1, 2, -2, 1, -1, -1, +2, 0, 0, 0, -1, 1, 0, -1, +0, 3, -5, 3, -2, 3, -2, 2, +-3, 3, -2, 2, -2, 3, -4, 2, +-1, 1, 0, 1, -1, 0, 0, 1, +-1, 0, 0, 0, -1, 1, -2, 3, +-2, 0, 0, 2, -2, 3, -4, 3, +-2, 2, -2, 1, -1, 0, 2, -2, +2, -1, 1, -3, 2, 0, -1, -1, +0, -1, 3, -4, 3, -2, 2, -1, +-1, 2, -2, 2, -1, -2, 1, -1, +2, -2, 1, 1, -2, 1, -1, 1, +0, -2, 1, -1, 0, 0, 0, 1, +-1, 1, -2, 1, -1, 2, -2, 2, +-3, 3, -1, 0, 1, 1, -2, 1, +-1, 3, -3, 2, -3, 3, -1, 1, +0, 0, 0, 1, -1, 2, -3, 4, +-4, 2, 0, 1, 0, -1, 1, 1, +1, -3, 2, -3, 4, -4, 3, -1, +1, 0, 1, 0, 0, 1, 0, -1, +2, -1, 1, -1, 0, 2, 0, -2, +3, -2, 3, -4, 2, -1, 1, 0, +0, 0, 1, -1, 3, -2, 1, -1, +1, -2, 2, -1, 1, -4, 4, -2, +2, -2, 0, 2, -1, 1, -1, 0, +0, -2, 3, -2, 2, -1, 0, 0, +1, 1, -1, 0, -1, 0, 2, -4, +3, -2, 1, 0, 0, 1, -1, -1, +0, 1, -1, 1, -1, -1, 2, -1, +1, 0, -3, 4, -4, 3, -3, 3, +-3, 0, 1, 0, 0, 0, -1, 1, +0, -2, 3, -3, 2, -1, -1, 2, +-3, 3, -2, 1, 0, 1, -1, 0, +-1, 1, 0, -1, -1, 2, -3, 3, +-2, 1, 0, 0, 1, -1, 1, -2, +3, -4, 4, -3, 3, -4, 4, -2, +1, -1, 0, 1, -1, -1, 1, 1, +0, 0, -1, 1, 1, -1, 2, -2, +2, -3, 2, -2, 2, 0, -1, 0, +-1, 3, -2, 2, -3, 2, 0, -2, +3, -3, 2, -2, 2, -1, 1, 0, +0, -1, 3, -3, 3, -2, -1, 3, +-2, 0, 1, -2, 4, -5, 5, -2, +0, 0, -1, 1, 0, 0, 0, -1, +2, -2, 3, -2, 0, 1, -1, 0, +0, 1, -1, -1, 2, -1, 1, -1, +-1, 2, -1, 0, 1, 0, 0, -1, +1, -1, 2, 0, 0, -1, 0, 1, +-1, 1, -3, 3, -1, -2, 3, -2, +2, -1, 0, 1, -1, 0, -1, 1, +-2, 2, -2, 2, -2, 3, -3, 3, +-3, 2, -2, -2, 4, -3, 2, -3, +1, 1, 0, -1, 0, 0, -1, 1, +-1, 0, 0, -1, 0, 0, -1, 3, +-3, 1, 0, 0, 1, -1, -1, 2, +-3, 3, -3, 4, -4, 0, 1, -1, +3, -1, -1, 0, -1, 0, 0, -1, +1, 0, 1, -2, 1, 1, 0, -2, +2, -1, 1, -2, 1, 0, 2, -1, +1, -2, 1, -2, 2, -1, -1, 1, +-3, 2, -1, 1, 0, -2, 1, 2, +-2, 2, -3, 3, -2, -1, 2, -2, +3, -2, 2, -1, 2, -1, 1, -3, +2, -1, 1, -1, 0, 1, -1, 1, +-1, 2, -2, 1, -1, 2, -2, 1, +0, -1, 2, -1, 0, 3, -5, 4, +-4, 3, -3, 5, -6, 4, -3, 3, +-1, -1, 1, 1, 0, -1, 1, -1, +1, -2, 2, -1, 1, 0, -1, 1, +0, 0, 0, -2, 1, 0, -1, 0, +-1, 2, -1, 0, 0, 1, -1, -1, +0, 0, 0, 0, -1, 1, -1, 2, +-2, 3, -4, 4, -3, 0, 1, 0, +-1, 0, -1, 2, -1, 0, -1, 3, +-2, 0, 0, -1, 2, -3, 3, -3, +3, -2, 2, -4, 4, -3, 4, -5, +3, -2, 2, -3, 3, -2, 2, -3, +3, -1, 0, -1, 0, 0, 1, -1, +2, -3, 3, -2, 2, -1, 1, 2, +-3, 2, -3, 5, -5, 3, -3, 2, +0, 0, 1, -1, 2, -3, 4, -4, +3, 0, -1, 2, -2, 3, -2, 1, +-1, 3, -4, 4, -4, 4, -4, 1, +1, -1, 1, -2, 2, 0, 0, 1, +-3, 2, -1, 2, -1, -1, 2, -1, +3, -3, 1, 2, -2, 0, 0, -2, +3, -5, 5, -3, 2, -1, 1, 0, +0, -1, 1, -1, 2, -2, 2, -4, +3, -1, 1, -2, 2, -1, 1, -2, +1, 0, -1, 2, -3, 4, -5, 4, +-4, 3, -2, 2, -3, 2, -2, 2, +-1, -1, 0, 1, 0, -2, 2, -1, +1, -3, 3, -2, 2, -2, 0, 1, +-2, 1, 0, -1, 1, -1, 1, -2, +2, 0, -1, 0, 0, 1, 0, -2, +1, 0, 1, -2, 2, -3, 3, -4, +2, 0, -1, 2, -3, 3, -3, 3, +-3, 1, -1, 1, 0, -1, 0, 2, +-2, 0, 0, 2, -2, 1, -1, 1, +0, 0, 0, 0, -1, 2, -2, 1, +-1, 0, 0, -1, 0, 3, -3, 1, +-1, 2, 0, -1, 1, -2, 2, -1, +1, -1, 1, -3, 3, -2, 0, 1, +-2, 0, 1, 0, 0, 0, -1, 2, +-1, 0, 0, 2, -2, 0, -1, 1, +0, 0, 0, 0, 2, -1, 0, 0, +-2, 3, -3, 2, -2, 1, 2, -3, +1, 1, -1, 1, 0, -1, 2, -3, +3, 0, -2, 3, -4, 4, -3, 1, +0, -2, 2, 0, 0, -2, 2, -1, +1, -2, 1, 2, -2, 2, -3, 3, +-2, 2, -4, 3, -2, 0, 2, -3, +3, -1, 0, -1, -1, 1, 1, -4, +5, -5, 4, -4, 4, 0, -2, 1, +-1, 1, 0, -1, -1, 1, -1, 2, +-2, 1, -1, 0, 2, -4, 5, -4, +4, -6, 4, -1, 2, -1, -1, 3, +-2, 1, -1, 1, -1, 0, -1, 0, +0, 0, 1, -2, 2, 0, 1, -2, +-1, 3, -2, 0, 0, 1, -1, 0, +0, 2, 0, 0, -1, -1, 3, -5, +6, -6, 4, -1, 0, 2, -3, 4, +-3, 1, 0, 1, -1, 0, -2, 3, +-1, 0, 1, -1, 0, -1, 1, 0, +-1, 2, -4, 2, -1, 3, -3, 3, +-3, 5, -3, 0, 0, 1, -1, 0, +0, 1, 0, -1, 0, 0, 2, -2, +3, -3, 2, 0, -1, 2, -3, 4, +-3, 2, -1, 1, 0, -2, 2, -1, +2, -4, 5, -5, 4, -4, 2, -1, +1, -1, 0, 0, -1, 2, -2, -1, +3, -1, 2, -3, 2, -1, 2, -2, +0, 0, 1, -2, 2, -1, 1, -1, +1, 0, 0, 0, 1, -2, 1, 0, +0, -1, 1, 0, 0, -1, 0, 4, +-5, 2, -1, -1, 3, -3, 1, 0, +0, 1, -2, 2, -2, 0, 1, -3, +1, 2, -3, 2, -2, 2, 0, 0, +-3, 5, -5, 4, -4, 4, -4, 3, +-3, 4, -4, 2, -1, 0, 1, -1, +0, -2, 1, 1, -2, 1, -1, 2, +-1, -1, 0, 2, -3, 2, -3, 3, +-1, 0, -1, 0, 1, 0, 0, 0, +-1, 2, 0, -2, 2, -2, 2, -2, +1, 1, -1, 0, 0, 1, -1, -1, +1, 1, -1, 1, -1, 0, 1, -1, +1, -3, 3, -1, 2, -4, 3, -2, +3, -3, 2, -1, 1, -1, 1, 2, +-2, 1, -1, 1, 1, -1, 1, -1, +1, 0, 1, -2, 1, 1, -1, -2, +3, -2, 2, -2, 1, 1, 0, -2, +1, 0, -1, 2, -3, 2, -1, 0, +2, -5, 4, -3, 3, -3, 2, -2, +2, -2, 1, -1, 2, -4, 4, -1, +-1, 1, -2, 2, -1, -1, 1, -2, +1, 0, 0, -1, 1, 1, -2, 0, +0, 1, 0, -3, 3, -1, 2, -3, +3, -3, 4, -3, 2, -1, 1, -1, +1, -2, 2, -2, 4, -5, 5, -4, +4, -5, 3, 0, 0, -2, 2, -1, +1, -1, 1, 2, -3, 2, -2, 1, +0, -1, 1, -3, 3, -1, 0, -1, +0, 0, 1, -2, 1, 0, 1, -3, +4, -4, 5, -4, 2, 1, -2, 3, +-3, 2, -3, 2, -1, 1, -1, 2, +-1, -1, 2, 0, -1, -1, 2, 0, +0, -1, -1, 3, -2, 2, -2, 2, +-1, 0, 0, -2, 2, 0, 0, -1, +2, -2, 5, -6, 5, -3, 2, -2, +1, 1, -2, 1, -1, 2, -2, 0, +1, 0, 0, 1, -1, 0, 1, -1, +0, -2, 2, 2, -4, 3, -3, 5, +-4, 2, -2, 1, 1, -2, 3, -3, +4, -3, 1, 1, -2, 2, -2, 0, +-1, 2, 0, -1, -1, 3, -3, 3, +-2, 2, -1, -3, 3, -1, 0, -2, +3, -4, 4, -2, 0, 0, -2, 3, +-3, 1, -1, 2, -2, 1, -1, 3, +-2, -1, 1, -2, 3, -4, 2, -1, +0, 0, 0, 0, 0, 0, 0, -1, +0, 1, 1, -3, 3, -1, -1, 1, +-2, 5, -5, 2, 0, 0, 1, -3, +2, 0, 0, 2, -3, 0, 2, 0, +0, 0, -1, 2, -1, -1, 1, 0, +0, 0, -1, 2, 0, -2, 1, 0, +1, -2, 2, -1, 1, -1, 2, -3, +2, -1, 1, -1, 1, 2, -2, -2, +3, 0, 0, -2, 1, 0, 1, -1, +0, 1, -1, 1, -2, 1, 0, 2, +-2, 0, -2, 3, -2, 2, -3, 3, +-1, -1, 0, 2, -3, 3, -3, 5, +-3, 0, 1, -1, 0, 1, -2, 2, +-2, 4, -2, 1, 0, 1, -1, -1, +1, 1, -1, -1, 0, 0, 2, -1, +-1, 2, -1, 0, 0, 0, 0, 1, +-1, 3, -4, 4, -2, -1, 1, -1, +2, -4, 4, -2, 1, -3, 4, -2, +2, -2, 2, 0, 0, 1, -4, 4, +-3, 4, -3, 0, 1, 0, 1, -2, +1, 1, -1, 1, -3, 3, -2, 1, +0, 0, 0, 0, 0, 2, -3, 2, +-1, 0, 1, -1, 1, -1, 2, 1, +-2, 0, 0, 2, -2, -1, 1, 1, +-2, 2, -3, 3, -1, 1, -2, 3, +-2, 3, -3, 1, 0, -1, 2, -1, +0, 1, 1, -4, 4, -2, 1, -1, +0, 1, -1, -1, 2, -1, 0, -1, +2, -2, 1, -1, 0, 0, 2, 1, +-2, -1, 2, 0, 1, -4, 4, -2, +2, -1, -3, 4, -3, 3, -2, 1, +0, -1, 1, -1, -1, 2, -2, 1, +-1, 1, 0, -1, 1, 1, 0, -3, +3, 0, -1, -1, 3, -2, 3, -3, +2, -1, 2, 1, -3, 1, -1, 2, +-2, -1, 1, 0, 1, -3, 3, -3, +6, -6, 3, -1, -1, 2, -4, 6, +-5, 3, 0, -2, 2, -1, 1, -1, +1, 1, 0, -3, 3, 0, -1, 0, +0, 2, -2, 0, 1, -1, 2, -3, +1, -1, 2, 0, 0, -2, 3, -2, +2, -1, -1, 1, 1, -2, 0, 3, +-4, 3, -2, 2, -1, 0, -1, 3, +-4, 3, -2, 2, -2, 1, 0, -1, +1, 1, -2, -1, 2, -1, 1, -3, +3, -1, 3, -3, 1, 0, 0, 1, +-3, 3, -3, 3, -3, 1, 0, -2, +4, -2, 0, 1, -2, 0, 1, 0, +0, -2, 2, 0, 0, -2, 2, 0, +-1, 1, -2, 2, -2, 2, -2, 0, +1, 0, -1, -2, 3, -1, 1, -2, +0, 0, 2, -2, 0, 1, 0, 0, +-1, 3, -4, 3, -2, 2, -1, -1, +1, -1, 0, 2, -2, 0, 1, 0, +-1, -2, 4, -1, 0, -2, 0, 4, +-2, 1, -1, -1, 3, -2, 0, 0, +1, -1, 3, -6, 6, -4, 3, -2, +-2, 3, -1, 0, -1, 0, 0, -1, +2, 0, -1, -1, 3, -1, 0, 0, +-1, 1, -1, 2, -3, 0, 1, 1, +0, -2, 1, 2, -3, 1, -1, 0, +1, -3, 2, -2, 4, -3, 2, -1, +-1, 2, -2, 3, -3, 2, 0, -2, +3, -2, 3, -4, 2, 1, -3, 2, +-2, 4, -4, 2, -1, 2, -2, 1, +-1, -2, 4, -3, 2, -3, 3, 0, +0, -2, 2, -1, 2, -1, -2, 3, +-2, 1, 0, 1, 0, -1, 0, 1, +-2, 3, -1, 1, -1, 0, 0, -1, +1, 1, -1, -2, 3, 0, -1, -2, +2, -1, 2, -3, 3, -2, 2, 0, +-2, 3, -2, 2, -1, -2, 4, -3, +2, -3, 1, 2, -1, 1, -3, 3, +-1, 0, 1, 0, -1, -1, 2, 0, +-1, 1, -1, 3, -4, 6, -6, 4, +-2, 2, -3, -1, 3, -1, 2, -5, +3, 0, 0, 1, -3, 3, -3, 3, +-4, 3, -2, 1, 0, -1, 0, 0, +1, -2, 1, 1, -1, 0, -1, 2, +-1, 0, 1, 3, -4, 1, 1, 0, +2, -3, 0, 2, -2, 4, -4, 1, +1, 2, -3, 1, -2, 3, -2, 1, +-2, 3, -1, 0, 0, -1, 3, -3, +2, -1, -1, 1, 0, 1, -2, 2, +-1, 2, -2, 4, -5, 2, 0, 1, +0, -4, 5, -1, 1, -3, 2, -2, +4, -4, 2, -2, 2, -1, -1, -1, +1, 1, -1, -1, 0, 0, 2, -2, +0, 0, 2, -3, 3, -1, 0, -1, +1, 0, 0, -2, 2, 0, -2, 3, +-3, 1, 0, 2, -3, 1, 0, 2, +-3, 0, 0, 4, -4, 2, -4, 3, +-1, 0, -1, 0, 1, 0, 0, -1, +2, -1, 2, -3, 1, -1, 3, -3, +1, 1, -2, 1, -1, 3, -3, 0, +0, 3, -4, 3, -3, 2, -2, 2, +-2, 0, 1, 0, -1, -2, 3, -1, +1, -2, 0, 3, -3, 1, -2, 1, +2, -3, 1, 0, -1, 2, -2, 3, +-3, 1, 1, -1, 0, 3, -4, 2, +-2, 4, -3, 0, 1, 0, 0, -3, +3, 1, -2, 2, -3, 2, 1, 0, +-1, -1, 2, 0, 1, -3, 3, -2, +3, -2, 0, 1, 0, 0, -1, 3, +-3, 2, -1, 2, -2, 2, -1, 3, +-3, 1, 1, -2, 3, -1, 0, -3, +4, 0, -1, -1, 1, 2, -1, 0, +-1, 1, 0, -1, 0, 0, 0, 3, +-5, 4, -3, 2, -1, -1, -1, 2, +-1, 1, -2, 2, 1, -3, 3, -2, +2, -3, 4, -1, 0, -2, 2, 0, +0, 1, -1, 0, 1, 0, -1, -2, +3, -1, 0, -2, 2, 0, 2, -5, +3, -3, 5, -4, 2, -1, 1, -1, +0, 1, -2, 1, 0, 0, -2, 2, +0, -1, 1, 0, 0, -2, 2, 1, +-2, 0, 1, 1, -1, -2, 2, -1, +1, 1, -3, 0, 2, -1, 2, -3, +2, -1, 1, -2, 0, 3, -3, 2, +-3, 3, -1, -1, 1, 0, -1, 1, +-3, 4, -4, 3, -1, 1, -1, 3, +-3, 1, -2, 5, -5, 2, 0, 0, +1, -4, 4, -2, 1, -1, 0, 0, +1, -1, -1, 0, 0, 0, 0, 0, +0, 1, 0, 0, -2, 4, -4, 3, +-4, 4, -2, -1, 3, -2, 0, 0, +-1, 4, -4, 2, -1, -2, 3, -1, +0, 0, 1, 2, -2, -1, 1, 2, +-2, 1, -2, 2, -1, 1, -1, 2, +0, -2, 2, -2, 1, 0, -1, 1, +-2, 1, 2, -3, 3, -2, 3, -5, +5, -3, 3, -6, 6, -3, 1, 0, +-2, 4, -2, 1, 0, -3, 3, -2, +2, -2, 2, 1, -3, 1, -1, 2, +0, -1, -1, 1, 1, -1, 0, 1, +-1, 0, 1, 0, 0, -1, 1, -1, +1, -1, 0, -1, 0, 2, -3, 2, +-2, 4, -4, 1, 0, 3, -4, 3, +-4, 5, -3, 2, -1, -2, 4, -2, +1, -1, -2, 2, -1, 0, 0, 0, +0, -1, 2, -1, 1, -3, 2, 1, +-1, -1, 1, 0, -1, 1, 0, 0, +1, -2, 0, -2, 4, 0, -2, 0, +-1, 5, -6, 5, -5, 6, -4, 2, +-2, 2, 0, -1, 0, -1, 1, 0, +0, -1, 1, -2, 4, -3, 1, 2, +-2, 1, 0, 1, -2, 1, -1, 4, +-5, 2, -2, 4, -4, 3, -3, 3, +-1, 1, -1, -1, 2, 0, -2, 1, +-1, 3, -1, -2, 2, -2, 4, -3, +1, 1, -2, 2, -1, 0, 1, -4, +5, -4, 3, -2, 1, -1, 0, 2, +-3, 2, -2, 4, -4, 0, 2, 1, +0, -2, 1, 0, 1, -1, -1, 1, +0, 0, 0, -2, 3, 0, 0, 0, +-1, 2, -1, 1, -3, 5, -4, 2, +-2, 2, -1, -1, 2, -1, 1, -2, +3, -1, 1, 0, 0, 0, 0, 3, +-5, 3, -2, 3, -2, -1, 1, 1, +-1, -1, 0, 0, 2, -4, 4, -5, +5, -4, 2, -1, 0, 0, 2, -3, +3, -2, 2, -2, 0, 1, 0, -3, +4, -1, -1, 1, -1, 2, 0, -4, +5, -4, 4, -1, 0, 0, 1, 0, +-1, -2, 4, -1, 2, -3, 1, 0, +1, -2, 2, -2, 3, -4, 4, -3, +4, -4, 2, 0, -2, 3, -3, 2, +-2, 1, 1, -3, 2, 1, -2, -1, +2, 0, -1, -1, 1, 0, 0, 0, +-1, 2, 0, 0, 0, -2, 2, 0, +-1, -1, 2, -2, 3, -4, 3, -2, +2, -2, 1, 0, 0, -1, 1, 0, +0, -1, 1, 0, -1, 0, 1, -2, +2, -1, 0, 0, 1, 1, -1, -1, +1, 2, -2, -1, 1, -1, 2, -2, +1, 0, 1, 0, -1, 0, 1, -1, +2, 0, -3, 5, -5, 4, -3, 1, +1, -4, 4, -1, 0, 1, -2, 5, +-6, 4, -3, 2, 0, -2, 2, -1, +2, 1, -3, 1, -1, 3, -3, 2, +-3, 4, -3, 2, -2, 2, -1, -1, +0, -1, 2, -4, 4, -4, 2, -1, +1, -1, 1, -2, 3, -3, 2, 1, +-3, 1, -1, 3, -3, 1, 0, 1, +-1, -2, 1, 0, 0, 1, -3, 3, +-3, 5, -4, 2, -2, 2, -1, 1, +-2, 3, -3, 2, -3, 4, -2, 0, +-1, 2, -3, 2, 0, 0, 1, -3, +3, -2, 1, 1, -2, 1, -1, 3, +-4, 1, 1, 0, 0, -1, -1, 4, +-3, 2, -2, 2, -1, 1, -1, 1, +-1, 1, -1, 0, 0, 0, 1, -1, +0, 1, -1, 0, 1, 0, 0, -3, +4, -1, 1, -2, 2, 0, 0, 0, +-1, 1, -1, 3, -4, 3, -2, 3, +-3, -1, 2, -2, 4, -4, 2, 1, +-2, 3, -4, 6, -4, 3, -2, -1, +2, -4, 4, -2, 0, 1, -1, 0, +1, 0, 0, -2, 2, 1, -2, 0, +0, 2, -3, 1, 1, -1, 2, -4, +1, 0, 0, 2, -3, 2, 0, 1, +0, -2, 1, 0, 1, -2, 1, -1, +2, -2, 2, 0, -1, 0, 0, 3, +-3, 0, 1, -2, 3, -3, 4, -5, +5, -4, 2, -2, 1, 4, -7, 5, +-4, 5, -4, 1, -1, 1, 2, -3, +3, -2, 2, -2, 1, -3, 4, -2, +2, -3, 1, 0, 1, -1, 1, -1, +1, -1, 1, 2, -3, 2, -2, 3, +-4, 2, 0, 1, -1, 0, -2, 0, +2, -1, 1, -4, 4, -2, 2, -3, +2, 1, -2, 0, -1, 1, 1, -2, +1, -2, 3, -1, 1, 1, -2, 1, +0, -2, 2, -3, 3, -4, 3, 0, +-1, 0, 0, 2, -2, -2, 3, -1, +1, -2, 0, 0, 0, 2, -2, 2, +-2, 3, -3, 1, 0, 2, -1, -2, +2, -1, 1, 0, -1, 4, -4, 2, +0, 0, 2, -3, 3, -2, 1, 0, +-1, 0, 1, -3, 3, -5, 5, -1, +0, -2, 1, 2, -2, 0, 1, -2, +4, -6, 5, -3, 2, 0, 0, -1, +2, -2, 3, -3, 3, -3, 3, -5, +6, -3, 1, -1, -1, 4, -3, 2, +-2, 1, -1, -1, 2, -2, 2, -2, +1, -1, 2, 0, 0, -1, 1, -2, +2, -5, 6, -3, 2, -3, 2, 0, +1, 1, -1, 2, -3, 1, 0, 1, +-1, -1, 1, -1, 2, 1, -3, 1, +0, 1, 0, -2, 1, 2, -3, 1, +-1, 1, 0, 0, -1, 0, 0, 0, +0, 2, -2, 2, -2, -1, 3, -3, +4, -5, 3, -2, 2, -1, 0, 1, +-2, -1, 3, -2, 1, -2, 2, -1, +1, -2, 3, -3, 2, -2, 1, -2, +4, 0, -2, 0, 0, 2, -2, 1, +0, 0, 0, -2, 2, 1, 0, 1, +-2, -1, 3, -1, 0, 1, -4, 2, +0, -3, 4, -3, 2, -2, 1, 0, +0, -1, 3, 0, -2, -1, 2, 1, +0, 0, -1, 0, 0, 2, -3, 2, +-2, 3, -3, 1, 1, 1, -2, -1, +1, -1, 3, -1, -1, 1, -1, 1, +0, 1, -1, 0, 0, -1, 1, 0, +0, 0, -1, -1, 1, -3, 5, -1, +-2, -1, 1, 3, -2, 1, -1, -1, +1, -2, 2, 0, -1, 3, -5, 3, +-2, 4, -4, 2, -2, 2, 0, -2, +2, -1, 1, -2, 1, 0, 1, -1, +0, -1, 1, -1, 2, 0, -3, 2, +-3, 4, -3, 3, -3, 1, 0, 1, +-1, -2, 5, -3, 1, -3, 1, 1, +-1, 1, -2, 1, 1, 0, 0, -1, +0, 2, -2, 2, -2, 3, -2, 1, +-3, 5, -5, 5, -4, 3, -3, 0, +1, 1, -1, 1, -1, 2, -2, 0, +1, -3, 3, -4, 3, -5, 7, -3, +0, -2, 2, 0, 1, -3, 3, -2, +1, -2, 3, -1, 1, 0, -2, 1, +0, 2, -3, 2, -2, 0, 1, -2, +4, -3, 3, -5, 4, -1, 2, -1, +0, 1, -3, 1, 2, -1, 1, 0, +-2, 2, -1, 2, -1, 0, -1, 2, +-4, 2, 1, 0, -1, -1, 0, 3, +-2, 2, -2, 0, 2, -3, 3, -2, +2, -1, 1, -2, 3, -2, 2, -1, +0, 2, -2, 1, 0, 1, -1, -1, +1, 1, -1, 1, 0, 0, -1, 0, +0, 2, -2, 1, -1, -1, 4, -1, +0, -2, 1, 1, -1, 0, 1, 0, +-1, -2, 2, 0, 0, 2, -4, 4, +-2, 2, -1, -1, 1, -1, 1, -2, +2, 0, 1, -3, 2, -1, 1, 0, +0, 0, -1, -1, 2, 1, -4, 4, +-4, 2, 1, -4, 6, -5, 3, 0, +-2, 0, 2, 2, -4, 1, -1, 3, +-2, 0, 0, 0, 0, 0, 0, 2, +-2, 2, -3, 0, 2, -2, 1, -1, +-1, 2, -3, 3, -2, 3, -2, -2, +2, 0, 0, 1, 0, 0, -2, 0, +2, 1, -2, 2, -5, 4, -1, 2, +-1, -2, 4, -2, 0, -2, 4, -1, +0, -1, 0, 1, 0, 1, -2, 0, +1, -3, 4, -4, 4, -4, 3, -3, +3, -1, 1, 0, -1, -1, 3, -4, +5, -3, 1, -4, 5, -2, 2, -2, +1, 0, -1, 1, 0, -1, 2, -4, +2, -4, 6, -1, -1, -1, 1, 1, +-2, 2, -2, 2, -1, -1, 1, -1, +2, 0, -2, 0, 1, -2, 4, -3, +1, -2, 2, -2, 2, 0, -1, 0, +-1, 2, -1, 0, 2, 1, -3, 0, +2, 0, 0, -1, -1, 0, 1, 1, +-2, 2, -1, 1, -1, -2, 5, -3, +2, -3, 1, 0, 2, -1, 0, 0, +-1, 1, 0, 1, -1, 1, -2, 2, +-1, -1, 3, -3, 1, 0, -1, 0, +3, -1, -1, -2, 3, 0, 0, 0, +-1, 2, -3, 2, -2, 3, -2, 2, +-4, 1, 2, 0, -1, -1, 1, -1, +3, -4, 4, -2, 1, -2, 1, 0, +1, 0, 0, 0, 0, -3, 4, -2, +2, -3, 3, -4, 4, -2, 1, -2, +2, -1, 0, -1, 1, 3, -5, 1, +1, 0, 1, 1, -3, 4, -4, 3, +-2, 1, 1, -1, -1, -1, 2, 1, +-2, 1, -3, 2, 0, 0, 0, 0, +-1, -2, 3, -2, 1, 0, -1, 1, +-1, 0, 2, -1, 1, -1, 0, 0, +1, 2, -3, -2, 4, -3, 2, -2, +0, 4, -6, 4, -3, 2, 0, 1, +-1, -2, 3, -3, 3, -2, 1, 1, +-2, 1, 1, 0, -1, 0, -2, 3, +0, 0, 0, -1, 1, -2, 4, -3, +1, 1, -2, 3, -2, 1, 1, -2, +2, -3, 3, -5, 8, -4, 1, -4, +4, -2, 2, -1, 1, 0, -1, -1, +1, 0, 1, -1, -2, 0, 3, -1, +0, 0, -2, 3, -2, 1, 0, 0, +1, -3, 2, -1, 3, -1, 1, -2, +-1, 0, 2, 1, -4, 4, -4, 2, +0, 1, -1, 0, 0, 1, -3, 2, +0, 3, -5, 0, 1, -1, 3, -1, +-1, 1, -1, 2, -3, 4, -5, 4, +-4, 1, 1, 0, 1, -1, -1, 0, +2, -2, 2, -2, 1, -1, 2, 1, +-1, 0, 1, -2, 1, -3, 4, -2, +2, -1, -1, -1, 3, 0, -1, -1, +1, 1, -2, 4, -4, 6, -7, 3, +-2, 1, 3, -2, -1, -2, 2, 1, +1, -1, -1, -3, 4, -4, 5, -2, +1, -3, 2, -1, 2, 0, 0, 0, +-3, -1, 4, 0, 0, 0, -1, -1, +2, 0, -2, 1, 0, 0, -1, -3, +6, -2, 0, -1, 1, -2, 4, -4, +3, -2, 1, 0, 1, 0, 0, 2, +-4, 2, -1, 0, 2, -2, 0, 0, +-1, 2, -1, 2, -3, 0, 1, -1, +2, -3, 4, -4, 1, -2, 3, 0, +-1, 1, -4, 0, 5, -1, -1, -1, +-1, 3, -4, 4, -3, 4, -4, 1, +-1, 1, -1, 3, -6, 5, -3, 2, +1, -2, 0, -1, 0, 1, 0, 2, +-2, 1, -1, 0, 2, -2, 2, 1, +-4, 2, 0, 1, -2, 3, -2, 0, +0, -2, 3, -2, 2, -1, -3, 1, +2, 3, -4, 1, -2, 0, 2, 0, +-1, 1, -2, 1, -2, 4, -3, 2, +-2, -1, 2, -3, 6, -4, 2, -3, +2, -2, 3, 1, -3, 1, -1, 2, +-2, 0, 2, 0, -4, 2, -2, 4, +-3, 3, -5, 1, 2, -1, 1, -2, +1, 1, -2, 0, 2, -1, 1, -3, +1, -1, 3, 0, -3, 3, -4, 3, +1, 0, 0, -2, 2, -4, 5, -4, +5, -4, 2, -2, 1, -1, 3, -1, +-2, -2, 3, 0, 1, -1, 0, 0, +1, -1, 1, 0, 1, 1, -3, -1, +3, -3, 4, -4, 1, 0, -1, 3, +-3, 3, -3, 1, -2, 2, 0, 1, +-2, 2, -4, 2, 1, 0, -1, 0, +0, -1, 2, 0, 0, -1, 0, 0, +0, -1, 4, -3, 0, -3, 4, -1, +1, 1, -4, 3, -1, 1, -1, 0, +1, 0, -1, -1, 1, 2, -2, 2, +-5, 4, -1, 2, -3, 1, -1, 0, +1, 2, -3, 4, -4, 4, -5, 5, +-3, 4, -5, 4, -4, 2, 1, 3, +-6, 2, 0, -1, 4, -5, 5, -2, +0, 0, 0, 0, 2, 0, -3, -2, +5, -4, 5, -5, 2, -2, 2, -2, +3, -3, 3, -4, 2, -1, 2, 1, +-2, 2, -4, 3, 0, 1, -1, -2, +3, -5, 6, -3, 2, 0, 0, 1, +-2, 0, 2, 1, -3, 1, 0, 1, +0, 1, -4, 5, -5, 6, -6, 4, +-3, 3, -4, 2, 0, 1, 0, 0, +-3, 1, 2, 0, 0, 2, -4, 3, +-2, 3, -2, 2, -1, 0, -1, -3, +6, -6, 6, -6, 2, -3, 5, 0, +-2, 0, -1, 3, -2, 1, 0, 0, +0, -2, 3, -3, 4, 0, -3, 2, +-1, 3, -2, 2, -3, 1, 0, -2, +2, -1, 2, -1, -2, 1, 0, 1, +0, 2, -4, 0, 3, -2, 3, -2, +1, -1, 1, 0, 2, -2, 1, -2, +-1, -1, 4, 0, -3, 1, -2, 2, +0, 2, -3, 2, -2, 0, 1, -1, +2, 0, -3, 2, -1, 1, 2, -1, +-1, 0, 0, 0, 1, 0, -1, 0, +0, 1, -1, 1, -2, 5, -6, 2, +2, -3, 5, -4, 1, -3, 5, -2, +2, -3, 2, -1, 1, -3, 4, -1, +0, 0, -2, 2, 1, 1, -2, -1, +1, -1, 1, 1, -1, 1, -1, 1, +-2, 3, -2, 2, -3, 1, 0, 1, +-1, 4, -6, 3, -1, 2, 0, 0, +-1, 1, -2, 2, -1, 1, -1, 2, +-4, 1, 3, -1, 2, -3, 1, 0, +0, 3, -4, 4, -4, 3, -4, 4, +-3, 4, -4, 3, -4, 3, -1, 3, +-3, 0, 0, 0, 1, 2, -3, 2, +-3, 3, -2, 0, 1, 1, -3, 1, +0, 1, 1, -1, 0, -1, 2, 0, +0, -1, 1, 1, -3, 2, 0, 1, +0, -1, -2, 1, 2, 0, 0, -3, +3, -3, 3, -1, 0, 0, 0, 1, +-2, 2, 1, 0, 0, -1, 0, 0, +1, 2, -3, 0, 0, 0, 1, -1, +2, -3, 2, -3, 3, -1, 2, 0, +-2, -1, 4, -3, 3, -4, 1, -1, +2, -2, 2, -3, 4, -4, 2, -2, +3, -2, 3, -3, 1, -1, 2, 1, +-1, -1, 1, -2, 1, 1, -2, 2, +-3, 2, -1, 0, 2, 2, -4, 2, +0, -2, 5, -4, 2, -2, 2, -1, +3, -4, 4, -3, 2, -3, 5, -4, +4, -2, -2, 1, 1, 0, 1, -1, +0, -3, 3, -3, 4, -4, 3, -4, +3, -4, 5, -2, -1, 2, -3, 2, +1, 1, -2, 0, 0, 1, 0, -1, +1, 0, -1, 0, 0, 0, 2, 0, +-3, 1, 0, 1, 2, -2, 0, 0, +0, 1, -1, 2, -2, 2, -3, 2, +0, 2, -3, 3, -3, 0, 2, 0, +-1, 1, -1, -1, 2, -2, 3, -1, +-1, 2, -4, 3, 0, 1, 0, -4, +4, -3, 4, -2, 0, -2, 3, -2, +2, 0, -1, 2, -4, 2, -2, 3, +-1, 1, -2, -1, 3, -2, 1, -1, +1, -3, 2, -1, 1, 2, -2, 2, +-3, 1, 2, -1, 0, -1, -1, 0, +1, 1, -2, 1, -3, 4, -5, 4, +-3, 4, -4, 2, -1, 0, 4, -2, +1, -2, 1, 2, -2, 4, -5, 5, +-5, 3, -2, 1, -1, 2, -6, 5, +-3, 2, -2, 1, -2, 0, 2, -2, +1, 0, -1, 2, -2, 2, 0, 0, +1, -1, 0, -1, 2, 1, -3, 1, +-1, 0, 1, 0, -1, 1, 0, -1, +0, -1, 1, 1, -3, 1, -1, 2, +0, 1, -3, 2, 1, -1, 1, -1, +2, -2, 1, -2, 3, -3, 4, -4, +2, -3, 3, 0, -2, 1, -2, 1, +0, 1, -1, 0, 1, 0, 0, -1, +2, 1, -1, 1, -2, 1, 2, -1, +0, -2, 1, -1, 1, -1, 0, -1, +0, -1, -1, 0, 1, 1, -3, 1, +1, -1, 2, -1, 0, 0, 0, 2, +-1, 1, -1, 2, -4, 4, -3, 4, +-4, 3, -5, 2, -1, 2, -2, 0, +-1, 0, 1, -1, 1, -1, 2, -3, +2, -4, 7, -5, 4, -3, 0, 3, +-3, 6, -7, 4, -2, -1, 1, -2, +2, -1, -2, 1, -1, 0, 0, 2, +-5, 3, -2, 3, -2, 3, -4, 5, +-2, 3, -2, 1, 0, 1, 0, -2, +2, 0, -2, 3, -6, 2, 0, 0, +-1, -2, 1, -3, 3, -2, 1, 0, +0, -1, 1, -2, 5, 0, -2, 2, +-2, 1, 1, 1, -3, 1, -1, 0, +1, -4, 3, -3, 1, -1, -1, 1, +0, 0, -1, -1, 2, 0, 0, 1, +-2, 2, 0, 1, 0, 0, 2, -2, +3, -5, 6, -5, 3, -3, 2, -4, +4, -3, -1, 1, -2, 2, -3, 2, +-1, 2, -3, 4, -4, 4, -1, 3, +-3, 2, -2, 1, 2, -3, 3, -4, +3, -2, 0, 1, -2, 2, -3, 1, +-2, 1, -1, 2, -4, 2, 0, 2, +-1, 2, -2, 1, 0, 1, 2, -1, +1, 0, 0, 0, 1, -1, -1, 0, +-2, 1, -2, 2, -3, 1, -2, 1, +-1, 2, -2, 4, -4, 4, -3, 3, +1, -1, 2, -2, 2, 1, -1, 2, +-2, 1, -1, 0, 0, 0, -2, 1, +-3, 1, 0, -1, 1, -2, 0, 1, +-1, 3, -2, 2, 0, -1, 3, -2, +4, 0, -1, 2, -3, 4, -4, 4, +-4, 1, 1, -3, 3, -4, 2, -2, +0, 0, 0, -2, 3, -4, 4, -4, +5, -4, 4, -2, 2, -1, 3, -1, +-1, 3, -2, 3, -3, 1, -1, 2, +-3, 2, -4, 2, -1, 1, -2, 0, +1, -1, 2, -2, 3, -2, 3, -2, +4, -3, 5, -2, 2, 0, 0, 1, +0, 1, -3, 1, -2, 1, -2, 1, +-3, 2, -3, 1, -2, 1, 0, 2, +-3, 2, 0, 3, -1, 2, 0, -1, +3, -1, 3, -1, 0, 0, -3, 2, +-2, 2, -5, 3, -6, 4, -4, 2, +-2, -1, 2, -2, 1, 0, 1, 1, +1, 1, 0, 1, 2, 0, 1, -2, +2, 0, 0, 2, -4, 2, -3, 1, +-2, 0, 0, -2, -2, 0, -1, 3, +-4, 4, -4, 3, 1, 1, 0, 1, +1, 1, 0, 2, -2, 3, -3, 3, +-3, 2, -3, 2, -4, 2, -4, 0, +-1, 0, -2, 0, 0, 0, 1, -2, +3, -1, 2, 0, 2, -1, 5, -2, +2, -2, 4, -2, 1, 1, -4, 5, +-6, 3, -4, 1, -3, 3, -7, 4, +-4, 3, -1, 0, 1, -2, 5, -2, +1, 2, -2, 3, 0, 2, -1, 3, +-3, 4, -6, 4, -3, 2, -3, 0, +-2, -2, 1, -1, -2, 2, -3, 3, +-3, 2, 0, 2, -1, 3, -2, 6, +-2, 6, -4, 4, -2, 4, -4, 3, +-4, 1, -1, -1, -2, -1, 0, -2, +-1, 0, -2, 2, 0, -1, 0, 0, +2, 2, 0, 1, 2, 1, 1, 2, +-1, 3, -2, 3, -6, 4, -4, 3, +-4, -1, -2, -2, 1, -2, 1, -5, +3, -3, 3, -1, 1, 1, 0, 2, +3, -2, 5, -2, 1, 3, -2, 5, +-3, 1, -3, 1, -2, 2, -5, 2, +-5, 3, -5, 3, -2, 0, -1, 2, +-2, 4, -3, 5, -2, 3, 1, 1, +2, 0, 3, -1, 1, -1, 1, 0, +-2, 2, -5, 2, -4, 1, -2, 0, +-3, 1, -2, 2, 0, 0, 0, 2, +-1, 3, 2, -1, 5, -3, 4, -2, +4, -2, 2, -2, 1, -2, -2, 1, +-3, 2, -5, 2, -5, 1, -1, -1, +1, -3, 4, -4, 4, -1, 4, -1, +4, -3, 6, -2, 4, 0, 0, -1, +0, -1, -1, 1, -4, 1, -5, 2, +-4, 3, -5, 0, -1, -1, 2, 0, +0, 1, 1, 2, 2, 2, 0, 2, +1, 1, 0, 2, -1, 3, -3, 0, +-4, 2, -4, 3, -6, -1, -1, -3, +2, -3, 1, -1, 1, 1, 2, 0, +3, -1, 4, -1, 4, 0, 3, 0, +-1, 2, -1, 2, -2, 0, -5, 2, +-4, 1, -3, -1, -2, 0, -4, 4, +-2, 3, -3, 3, -1, 3, 3, 0, +3, 0, 3, 1, 1, 1, 0, 0, +-1, 0, -2, 0, -3, -1, -3, -1, +-1, -2, 0, -2, -1, 0, 3, -2, +4, -2, 4, 1, 3, 1, 2, 1, +2, 1, 0, 0, 1, 0, -3, 2, +-5, 1, -3, -1, -2, 0, -3, 1, +-4, 0, 0, 1, 1, -1, 4, -3, +6, 0, 2, 2, 2, -1, 3, 0, +1, 1, -2, 0, -3, 1, -3, 0, +-4, -2, -2, -1, -1, 0, -2, 0, +1, -2, 4, -2, 7, -3, 4, -1, +3, 3, 1, 1, 0, -1, 2, -1, +-1, -1, -2, -1, -3, 0, -4, 1, +-4, 0, -3, 1, 0, 1, 0, 0, +1, 1, 5, -2, 6, -4, 5, 0, +2, 1, 1, -2, 2, -2, -2, 2, +-6, 3, -7, 0, -1, -3, 1, -4, +2, -3, 2, 0, 2, -1, 4, -1, +4, 1, 4, -1, 5, -1, 0, 3, +-3, 5, -5, 2, -6, 1, -3, -1, +-3, -1, -4, 3, -6, 4, -1, -1, +2, 0, 3, 1, 4, 0, 3, 0, +5, -1, 4, -1, 1, 2, -4, 2, +-2, -2, -2, -2, -3, -1, -2, -3, +-1, -2, -1, 1, -1, 1, 0, 1, +3, 0, 5, -2, 6, -2, 5, 0, +2, -2, 3, -4, 2, -5, 3, -6, +1, -3, -4, 3, -6, 1, -4, -1, +1, 1, 1, -1, 4, -3, 7, -2, +7, -2, 5, -1, 3, 2, 0, 0, +1, -5, 2, -3, -1, 0, -6, 0, +-5, 2, -3, 0, -3, -1, 0, 2, +1, 1, 4, -1, 4, 0, 3, 3, +2, 1, 0, 0, -1, 3, -3, 0, +-4, -1, -4, 0, -2, -3, -2, -3, +-1, 1, -1, 0, 1, 0, 2, 1, +5, 0, 5, -1, 4, 1, 4, 0, +1, -1, 0, 0, -1, -1, -3, -1, +-5, 0, -3, -2, -1, -5, 2, -4, +3, -1, 3, -1, 3, 1, 3, 3, +2, 3, -1, 5, -2, 5, -2, 0, +-2, -2, -1, -2, -1, -4, -3, -2, +-4, 2, -4, 1, -3, 2, -3, 5, +-1, 2, 3, -1, 6, -1, 7, -1, +3, 2, -3, 5, -3, 0, -1, -2, +-2, 0, -5, 0, -5, 0, -5, 2, +-3, -1, 2, -5, 6, -2, 4, 1, +2, 3, 1, 4, 2, 1, 5, -5, +4, -1, -1, 1, -4, -2, -4, -1, +-4, 1, -5, -1, -3, -2, 2, -1, +2, -1, 2, 2, 3, 1, 6, -2, +5, -1, 4, 2, 1, 1, -3, 2, +-5, 4, -7, 2, -7, 0, -6, 1, +-4, 1, -4, 1, -2, 2, 2, -1, +6, -5, 9, -3, 9, -2, 6, -3, +4, -1, 3, -2, 1, -4, -2, 0, +-5, 2, -6, -1, -4, -2, 0, -2, +2, -4, 3, -3, 6, -1, 6, -2, +6, -1, 6, 1, 4, 0, 0, 0, +-1, 2, -3, 1, -6, 1, -7, 1, +-3, -4, 1, -8, 4, -4, 4, -3, +4, -2, 4, 1, 5, 0, 6, -1, +5, -1, 6, -2, 3, -2, -2, 2, +-4, -1, -2, -5, -1, -4, -1, -4, +1, -5, 2, -1, 0, 3, -1, 4, +-1, 5, 1, 5, 2, 2, 1, 3, +1, 1, 1, -3, -1, 1, -6, 3, +-9, 2, -8, 3, -8, 4, -6, 1, +-1, -1, 3, 1, 3, 0, 4, 0, +7, 0, 6, -1, 3, 0, 1, 2, +-2, 0, -4, 0, -5, 1, -5, -1, +-5, -1, -4, 3, -5, 5, -4, 1, +3, 0, 6, 0, 5, 0, 4, 1, +5, 0, 4, -3, 0, 1, -4, 6, +-11, 4, -10, 4, -9, 5, -9, 2, +-4, -1, 1, -2, 5, -3, 5, -2, +7, -1, 8, -1, 3, 1, 2, 1, +3, -2, 0, -1, -5, 4, -8, 3, +-8, 1, -7, 1, -3, -1, 0, -3, +1, 1, 4, -1, 7, -4, 9, -1, +7, 0, 4, 0, 0, 2, -1, 1, +-1, -2, -5, 3, -10, 5, -9, 3, +-8, 2, -6, 4, -4, 1, 0, 0, +4, 0, 7, -4, 11, -5, 10, -3, +7, -4, 5, -3, 2, 0, -3, -1, +-5, 2, -8, 5, -9, 2, -6, -1, +-2, 1, 1, -1, 4, -1, 4, 4, +3, 2, 6, -3, 6, 1, 2, 2, +-2, -1, -1, -1, -1, -3, -3, -3, +-5, 1, -5, 0, -3, -2, 0, 1, +2, 1, 3, -2, 6, 1, 6, 1, +4, -1, 4, 0, 3, 0, -1, -1, +-5, 2, -6, 2, -5, -4, -3, -3, +-3, 3, -4, 2, -2, 0, 2, 1, +6, -1, 5, 1, 3, 3, 5, -1, +4, -3, 3, -1, 1, -2, -4, -1, +-6, 1, -4, -2, -3, -3, -3, 1, +-1, 2, -1, 1, 1, 2, 7, -2, +10, -6, 9, -2, 6, 0, 2, 0, +-3, 1, -4, 2, -5, -1, -7, 1, +-6, 0, -2, -3, -1, -1, 1, 0, +4, -3, 5, 0, 5, 3, 4, 0, +4, 0, 3, 2, -1, 2, -5, 3, +-7, 2, -5, -1, -5, -2, -5, 2, +-4, 1, -3, 1, -1, 4, 2, 0, +4, 0, 5, 3, 4, 1, 4, -2, +3, 2, -2, 3, -5, -1, -4, 0, +-5, -1, -4, -4, -1, -3, 0, 0, +-1, 1, 0, 2, 4, 1, 5, 0, +3, 5, 1, 5, 0, 1, 0, 0, +-1, 1, -5, 0, -8, 2, -7, 2, +-6, 0, -6, 2, -3, 3, 1, -1, +3, -1, 5, 3, 5, 1, 5, -1, +5, 0, 4, 0, 0, -1, -3, 0, +-3, -1, -4, -3, -4, -3, -1, -2, +-2, 0, -3, 3, 1, 2, 4, -2, +5, 2, 6, 1, 6, -3, 5, -1, +2, 0, -1, 0, -6, 1, -7, 2, +-5, -2, -6, 1, -7, 4, -2, -2, +3, -3, 4, 1, 7, -3, 8, -3, +6, 3, 3, 1, 2, -1, 0, 0, +0, -3, -2, -3, -5, 0, -5, -2, +-2, -3, -2, -1, 2, -2, 6, -4, +6, 1, 5, 2, 4, 0, 4, 2, +3, 0, 2, -1, -2, 3, -8, 4, +-7, -2, -4, -2, -3, -1, -4, -1, +-2, 1, -1, 4, -1, 4, 1, 3, +4, 3, 5, -2, 5, 0, 3, 2, +-1, -2, -1, -3, -2, 0, -5, -2, +-4, -3, -3, 1, -3, -3, 2, -5, +5, 1, 3, 3, 1, 2, 4, 4, +4, 2, 1, 0, 2, 1, 1, -2, +-2, -3, -4, 0, -5, 1, -6, 0, +-6, 0, 0, -1, 3, -3, 3, 0, +6, 0, 8, -3, 5, 3, 1, 6, +-1, 2, -3, 3, -5, 4, -5, 0, +-6, -2, -4, 0, -2, -4, -1, -2, +0, 1, 2, -2, 6, -3, 7, -2, +10, -5, 11, -5, 6, -1, 3, -2, +0, -2, -3, 1, -5, -1, -3, -4, +-5, 1, -6, 3, -5, 2, -3, 2, +3, -3, 10, -7, 11, -3, 7, 0, +5, -1, 2, 1, -2, 3, -4, 1, +-6, 1, -6, 1, -4, -3, -5, 1, +-5, 3, -3, -1, 2, -2, 5, 0, +5, -2, 8, -4, 8, 1, 2, 2, +-2, 4, -3, 4, -7, 2, -6, -1, +-4, 0, -5, 1, -6, 0, -2, 1, +2, -2, 4, -4, 7, -1, 8, -2, +7, -3, 6, 1, 2, 2, -1, -1, +0, -2, -1, -2, -3, -2, -6, 1, +-6, 3, -5, -1, -2, -1, 3, 0, +4, -1, 3, 1, 3, 5, 2, 2, +1, 0, 1, 2, -2, 2, -7, 2, +-7, 3, -5, -3, -4, -5, 0, -3, +3, -6, 3, -3, 4, 1, 4, -1, +7, -3, 8, -1, 6, 0, 3, -1, +1, -1, 2, -4, 0, -2, -5, 2, +-7, 2, -5, 0, -5, 3, -4, 3, +0, -1, 4, -1, 6, 0, 6, -1, +6, -1, 5, 0, 4, -2, 1, 0, +-3, 2, -6, 0, -6, 1, -9, 5, +-8, 2, -5, 0, -1, 1, 2, -2, +4, -1, 6, 0, 6, -3, 6, -1, +3, 2, -1, 0, -3, 0, -5, 2, +-7, 1, -7, 0, -6, 2, -4, 0, +-3, 0, 0, 3, 1, 1, 3, 0, +5, 1, 4, 2, 2, 1, -1, 4, +-4, 4, -5, 1, -6, 3, -7, 4, +-8, 1, -6, 2, -4, 4, -3, 2, +-1, 3, 2, 4, 3, 2, 3, 1, +5, 2, 4, 0, -1, 1, -2, 2, +-3, -1, -5, 0, -6, 3, -6, 1, +-4, -2, -1, -1, 4, -1, 2, 0, +2, 4, 3, 2, 4, -2, 3, 1, +2, -1, 1, -3, -2, 1, -6, 3, +-7, -2, -5, -2, -2, -2, 0, -4, +1, 0, 0, 3, 2, -2, 6, -3, +7, -2, 9, -7, 8, -5, 4, 1, +-1, -2, -2, -2, -2, 0, -5, 0, +-5, 1, -5, 4, -3, 1, 0, 0, +4, 0, 7, -3, 6, 1, 4, 2, +4, -2, 6, -5, 5, -2, 1, -3, +0, -5, 0, -2, -3, 1, -6, 2, +-6, 5, -3, 3, 1, -2, 4, 0, +5, 2, 3, -1, 4, 0, 2, 1, +1, -3, 0, -1, -4, 1, -4, -3, +-4, -2, -4, 1, -4, -1, -2, -1, +1, -1, 5, -6, 7, -3, 5, 3, +0, 2, 1, -2, 4, -2, 3, -3, +-1, -2, -3, 1, -4, 0, -5, 0, +-5, 3, -2, 0, 0, -1, -1, 4, +2, 2, 4, 0, 4, 1, 6, 0, +6, -4, 4, -2, 3, -1, 0, -3, +-1, -3, 2, -6, 3, -6, 2, -4, +3, -3, 5, -3, 2, 1, 3, 2, +4, -1, 3, 2, 0, 5, -1, 1, +-1, 0, -4, 2, -4, 0, -5, -2, +-3, -2, 0, -6, 3, -8, 5, -4, +4, -1, 2, -1, 2, 1, 3, 1, +3, -2, 2, 0, 2, 1, -2, -1, +-3, 0, -2, -2, -4, -1, -4, 1, +-3, 0, 0, -3, 2, 0, 2, 3, +1, 2, 0, 4, 2, 3, 1, 1, +1, 2, -1, 3, -2, -1, -2, 0, +-4, 3, -4, -1, -1, -3, 1, -1, +2, -1, 2, 0, 2, 2, 4, -1, +5, -3, 7, -1, 5, -2, 1, 0, +-3, 4, -3, -1, -3, -4, -1, 0, +-3, 1, -5, 0, -2, 2, -2, 1, +0, -1, 2, 1, 3, 0, 3, -1, +1, 2, -2, 4, -3, 0, -2, -2, +0, -2, -1, -3, -5, 1, -6, 3, +-3, -2, 1, -3, 1, 2, 1, 1, +0, 2, 3, 3, 2, 0, 3, -2, +3, 0, 0, -1, 0, -2, 0, -3, +2, -5, 2, -3, -2, 3, -4, 4, +-2, 0, 2, 0, 5, -1, 5, 0, +3, 3, 1, 3, 1, 2, -2, 5, +-5, 3, -2, -2, -1, -1, -1, -1, +-2, -2, 0, 0, -1, 2, -2, 2, +-2, 5, -3, 5, 1, -1, 5, -5, +7, -5, 6, -6, 4, -4, -2, 3, +-7, 2, -7, 0, -3, 0, -3, -1, +-2, -3, 1, 0, 0, 1, -1, 1, +1, 1, 4, -3, 3, -3, 3, 0, +0, -1, 0, -2, -1, 0, -3, 1, +-3, -2, -1, -2, 2, 0, -1, 0, +0, 0, 5, -1, 4, -1, 3, 2, +4, -1, 5, -2, 1, 3, -2, 4, +-1, -1, 0, -1, -1, 1, 0, -2, +1, -2, 1, 0, 3, -3, 6, -5, +5, 0, 4, 1, 0, 2, -1, 4, +1, 0, 0, -2, -1, 2, -3, 1, +-4, 0, -5, 2, -5, 1, -4, 1, +-5, 3, -2, 0, 1, -3, 1, 1, +1, -1, 1, -3, 2, -1, -1, 0, +-2, 0, -3, 1, -5, 2, -4, 0, +-4, 0, -3, 2, -4, 2, -4, 3, +-2, 2, 1, -2, 5, -1, 3, 1, +3, -1, 4, 0, 2, 1, 2, -1, +1, 0, -2, 6, -6, 4, -4, 3, +-1, 3, -2, 3, 1, 1, 2, 2, +3, 1, 4, -1, 4, 1, 4, 1, +1, 0, 1, 0, 1, -1, 0, -2, +-1, 1, -4, 2, -4, 1, -4, 1, +-2, 1, -1, 0, -3, 2, -1, 2, +-1, 0, -3, 2, -3, 3, -6, 3, +-7, 3, -7, 2, -4, -1, -6, 1, +-7, 3, -5, -1, -3, -2, 0, -1, +1, -2, 2, -1, -1, 4, -1, 0, +3, -4, 6, -4, 5, -1, 1, 0, +0, 1, 1, 0, 1, -1, 2, -1, +5, -3, 6, -3, 5, -1, 6, -1, +8, -3, 6, -1, 8, -2, 7, -2, +3, 2, 1, 2, 1, -1, 2, -1, +0, -2, 4, -6, 3, -2, 0, 0, +0, -2, 1, -2, 0, 2, -2, 0, +-1, 0, -1, 1, -2, -2, -2, -1, +-4, 2, -7, 2, -7, 0, -7, 2, +-6, 0, -6, -1, -3, 0, -4, -1, +-2, -1, -1, 2, -3, 3, -3, 2, +-3, 2, -1, 2, -2, 1, -1, 1, +0, 1, 0, 0, 0, 2, 1, 1, +3, -2, 4, 1, 3, 3, 4, 0, +6, 0, 6, 4, 2, 4, 3, 2, +5, 1, 4, 0, 5, -1, 3, 1, +1, 2, 0, 1, -1, 2, 0, 2, +-2, 2, -1, 2, -2, 2, 0, -2, +1, -1, -1, 1, -5, 3, -8, 4, +-7, 1, -6, -1, -8, 1, -8, 1, +-7, -4, -3, -5, -1, -4, -4, -1, +-7, 3, -7, -1, 1, -6, 1, -3, +-1, 0, -2, 0, -3, 3, -5, 6, +-7, 4, -3, 2, -3, 4, -2, 2, +1, 1, 2, 1, 5, -2, 8, -2, +8, 1, 6, 2, 7, 1, 6, 4, +3, 3, 6, -1, 9, -4, 11, -5, +10, -3, 4, 0, 6, -1, 3, 0, +1, 3, -1, 4, -1, 2, 0, 1, +1, -1, 2, -2, -2, 0, -3, 1, +-5, 0, -6, 0, -7, -1, -7, -3, +-5, -4, -7, 0, -10, 2, -12, 4, +-13, 5, -10, 1, -8, -1, -4, -1, +-2, -3, -4, 0, -4, 1, -5, -1, +-2, -2, -2, 2, -5, 3, -3, 1, +0, 0, 3, 2, 0, 3, 2, 3, +7, 0, 9, -2, 9, 3, 7, 3, +8, 0, 10, 1, 8, 1, 9, -2, +10, -3, 9, 0, 7, -1, 7, -3, +10, -3, 8, -2, 6, -1, 4, 1, +4, 1, -1, 2, -2, 3, -3, 2, +-6, 0, -4, 0, -6, -2, -8, 0, +-9, 2, -12, 0, -11, 1, -11, 0, +-10, -1, -8, 0, -10, 2, -9, 2, +-10, 1, -9, 3, -10, 3, -11, 3, +-9, 3, -9, 2, -6, 1, -5, 0, +-1, 0, 0, 1, -1, 4, 1, 4, +3, 2, 6, 2, 8, 1, 11, -1, +12, -1, 12, -1, 12, 0, 8, 4, +5, 5, 7, 1, 8, -1, 10, 1, +9, -1, 10, -2, 10, -1, 9, -2, +9, -1, 5, 1, 4, 0, 1, -2, +1, -1, -2, -1, -6, -1, -7, 0, +-10, 1, -13, 3, -15, 4, -13, 1, +-12, 0, -12, 1, -12, 3, -14, 2, +-12, 0, -9, -3, -7, -6, -5, -6, +-6, -4, -6, -3, -7, -3, -4, -2, +-2, -3, -3, 1, -2, 5, -3, 3, +3, 0, 8, -1, 10, -1, 11, 0, +10, 0, 12, 0, 11, 1, 9, 4, +8, 3, 8, 2, 10, 2, 12, -3, +17, -3, 14, 1, 11, 1, 14, -4, +14, -2, 11, 2, 3, 4, 1, 3, +0, 0, -1, -1, -3, 1, -9, 2, +-8, -1, -8, -2, -8, -2, -8, -2, +-10, -1, -11, 1, -11, -4, -7, -5, +-8, -2, -12, -2, -13, -1, -14, 1, +-16, 1, -15, -1, -12, -1, -10, -2, +-9, -1, -4, -2, -2, -4, 4, -4, +5, -1, 4, 1, 7, 0, 7, 0, +11, -1, 10, -1, 11, 2, 9, 2, +10, -2, 15, -1, 15, -2, 16, -1, +16, 0, 17, 0, 18, -1, 17, -1, +16, 1, 14, -2, 13, -3, 13, -3, +8, -4, 6, -3, 1, -1, -2, -1, +-5, -1, -6, -1, -7, 1, -12, 1, +-8, -1, -9, -2, -10, -1, -12, 1, +-14, -1, -16, 0, -19, 2, -19, 1, +-19, -2, -18, 0, -17, 0, -14, -2, +-12, -1, -10, 0, -6, -2, -1, -3, +1, -2, 5, -3, 4, -2, 7, -1, +8, -3, 10, -3, 11, -1, 9, -2, +15, -4, 15, -2, 18, -3, 19, -3, +21, -2, 22, -3, 22, -3, 23, 0, +18, 1, 16, 2, 14, 3, 8, 2, +8, 0, 8, -2, 4, 0, 0, 1, +-2, 0, 0, -4, -1, -4, -1, -1, +-7, 1, -10, 2, -11, 3, -16, 2, +-15, 0, -18, 1, -20, 3, -25, 3, +-25, 3, -23, 1, -21, -3, -16, -2, +-17, 2, -17, 3, -15, 5, -13, 4, +-7, -1, -2, -3, 1, 0, 0, 0, +-1, 1, 4, 0, 4, 0, 7, 0, +8, 0, 11, 2, 12, 2, 14, 1, +21, 0, 20, 1, 22, 1, 23, -2, +25, -2, 22, -1, 19, -2, 18, -1, +12, 1, 9, 1, 8, 0, 4, 2, +3, 2, 1, 0, 1, 0, 1, -1, +-1, -2, -2, -1, -8, 1, -10, 0, +-14, -1, -16, 0, -20, 0, -24, 1, +-23, 1, -25, 0, -22, -1, -21, -1, +-17, -3, -14, -1, -15, 1, -14, 3, +-12, 0, -9, 1, -8, 1, -6, -1, +-4, 2, -5, 3, -3, 2, 2, -1, +7, -1, 10, 1, 10, 2, 17, -2, +22, -4, 26, -1, 24, 1, 23, -1, +27, -3, 24, -2, 22, -1, 17, 1, +16, 0, 14, 0, 10, 3, 9, 3, +7, 1, 9, 0, 8, 0, 5, -1, +5, -3, 2, -3, 0, -3, -7, 1, +-14, 4, -19, 1, -20, -3, -17, -2, +-24, 2, -26, 3, -27, 3, -25, 2, +-22, 1, -22, 4, -18, 3, -19, 1, +-15, 0, -12, -1, -12, 0, -13, 4, +-15, 5, -12, 1, -5, -2, -1, -2, +3, -1, 6, -1, 13, -2, 17, -2, +17, 2, 19, 3, 20, 0, 25, -1, +23, 1, 22, 1, 19, 1, 19, 0, +21, -3, 19, -3, 20, -2, 16, -1, +16, 1, 13, 1, 13, -2, 15, -3, +10, -1, 4, 1, 0, -1, -3, -3, +-5, -3, -12, -2, -15, -1, -18, -2, +-20, -1, -21, 0, -23, 1, -21, 0, +-22, -1, -15, -4, -15, -4, -16, -1, +-18, 1, -20, 1, -19, 2, -20, 0, +-15, -2, -11, -3, -8, -3, -4, -1, +-3, 2, 0, 2, 5, 1, 10, 0, +15, 2, 15, 3, 16, 4, 16, 3, +19, 1, 20, 2, 15, 5, 17, 2, +17, 0, 21, -1, 21, -2, 23, -3, +23, 1, 18, 2, 17, 1, 14, 2, +12, 2, 6, 3, 2, 2, -2, 3, +-9, 1, -9, -1, -11, -1, -15, 0, +-17, 1, -19, 1, -20, 2, -21, 0, +-17, -2, -17, -2, -19, -2, -17, -2, +-21, -1, -21, 1, -25, 2, -23, 0, +-20, -2, -19, 0, -14, 0, -12, -1, +-5, -1, -2, 0, 3, 0, 6, 3, +7, 3, 11, 3, 12, 2, 14, 1, +17, -1, 17, -1, 20, -1, 20, -2, +21, -1, 22, -1, 22, -1, 25, 1, +22, 1, 24, 1, 21, 2, 21, 0, +18, 0, 12, 1, 8, 1, 2, 0, +1, -1, -4, -1, -8, 0, -10, 1, +-13, 0, -13, 0, -14, -1, -14, 0, +-17, 2, -20, 1, -18, -1, -21, -1, +-22, -1, -24, 0, -25, -1, -22, -3, +-24, -1, -20, 0, -20, -2, -13, -1, +-9, -2, -4, -3, 2, -2, 2, 0, +5, 3, 2, 4, 6, 2, 11, -2, +11, 0, 13, 2, 12, 0, 16, 0, +19, 0, 21, -1, 26, -2, 26, -2, +30, -3, 29, -2, 26, 0, 24, 1, +17, 1, 18, -2, 14, -5, 14, -4, +6, 1, -2, 2, -2, 1, -6, 1, +-5, 0, -7, 0, -9, 2, -12, 3, +-14, -1, -13, 0, -18, 3, -24, 3, +-26, 2, -27, 0, -24, -3, -24, -4, +-21, -4, -21, -2, -21, 1, -17, 1, +-16, 1, -9, 2, -11, 5, -7, 4, +-4, 0, 3, -4, 9, -6, 7, -4, +10, -3, 10, -3, 13, -2, 15, 0, +14, 1, 19, 1, 21, 1, 24, 0, +27, -1, 27, -1, 28, -2, 25, -2, +24, 0, 17, 1, 13, 0, 12, -1, +9, -1, 8, 0, 0, 4, -1, 3, +-1, -1, 3, -6, 4, -4, -2, -1, +-8, 3, -15, 4, -17, 1, -19, 1, +-23, 1, -23, -1, -25, -3, -23, -2, +-23, -2, -24, 0, -20, 1, -21, 2, +-17, 3, -16, 2, -12, 2, -9, 2, +-10, 2, -5, 1, -6, 0, -1, -1, +1, -1, 2, -1, 7, -1, 11, -4, +17, -4, 20, -3, 24, -4, 28, -4, +27, -1, 26, 2, 23, 0, 23, 1, +20, 3, 14, 2, 15, 0, 14, -2, +16, -4, 13, -3, 11, 0, 8, 1, +5, 2, 4, 2, 0, 1, 2, -1, +-3, 0, -7, -1, -9, -1, -15, 0, +-17, 0, -21, -2, -21, -2, -20, -4, +-21, -3, -19, 0, -21, 1, -20, 3, +-19, 3, -17, 0, -11, -2, -12, -1, +-8, -2, -10, -2, -8, -1, -5, -5, +-2, -6, 3, -2, 0, 1, 5, 0, +10, -2, 16, -2, 19, 0, 18, 1, +22, 0, 21, -1, 22, -1, 22, -1, +20, -1, 20, -2, 18, -3, 19, -3, +16, -1, 13, 2, 13, 1, 10, 2, +11, 3, 7, 2, 8, -1, 7, -2, +2, -2, 0, -2, -8, -1, -10, 0, +-16, 1, -18, -1, -17, -3, -17, -3, +-17, -1, -19, 1, -19, 2, -19, 2, +-16, -3, -10, -5, -13, -2, -13, -1, +-13, -2, -15, 2, -16, 4, -17, 2, +-9, -1, -6, -3, 2, -5, 5, -1, +4, 3, 8, 2, 9, 1, 17, 1, +15, 0, 18, -1, 18, 0, 16, -1, +18, -2, 16, -1, 16, -1, 17, -2, +17, -2, 20, -3, 19, -4, 20, -1, +15, 1, 12, 0, 13, -2, 8, -1, +7, -2, 0, -1, -3, 0, -7, -1, +-10, -1, -11, 1, -17, 1, -14, -1, +-14, -1, -14, 1, -17, 4, -18, 4, +-16, 1, -17, 0, -14, 0, -16, 1, +-20, 2, -19, 1, -19, 1, -15, 1, +-15, 2, -12, 3, -8, 4, -7, 4, +1, 1, 3, 1, 8, 1, 7, 4, +6, 5, 8, 4, 7, 4, 11, 2, +10, 2, 11, 3, 10, 3, 12, 1, +17, 0, 16, -2, 20, -2, 20, -1, +16, 2, 14, 3, 10, 3, 8, 4, +1, 5, -3, 3, -1, -1, -4, -1, +-4, 1, -10, 1, -7, 0, -10, 0, +-9, -1, -7, -2, -8, -4, -6, -3, +-11, -1, -13, -2, -13, -4, -13, -3, +-16, 0, -18, -1, -14, -2, -16, 1, +-16, 2, -10, -2, -7, -1, -3, 0, +-2, 0, 2, 0, 5, -1, 5, -1, +9, -1, 6, 0, 8, 0, 6, 1, +7, -1, 12, -4, 15, -5, 19, -3, +16, -1, 19, -2, 19, 0, 18, -1, +17, 0, 14, 0, 14, 0, 10, -1, +9, -2, 8, -2, 3, -1, 2, 0, +0, -2, -1, 1, -5, 2, -6, -2, +0, -5, -3, -3, -3, 0, -8, 2, +-11, 2, -11, -1, -12, -4, -13, -2, +-15, -2, -14, -3, -16, -1, -15, -1, +-10, -4, -7, -3, -3, 0, -5, 1, +-6, 3, -5, 4, -6, 4, -4, 4, +-6, 5, -2, 5, -1, 4, 0, 2, +6, 1, 4, 1, 8, 2, 8, 4, +8, 4, 10, 3, 14, -1, 18, -1, +15, 0, 15, 0, 14, -2, 13, -1, +9, 3, 0, 3, 1, 1, 2, -2, +4, -1, 3, 2, -1, 2, 1, 1, +-1, 0, 0, -2, -1, -3, -3, -4, +-2, -4, -9, -2, -10, 0, -15, 1, +-13, 0, -12, 0, -15, 2, -13, 1, +-14, -1, -9, -1, -8, -2, -5, -3, +0, -3, -1, -2, -1, -1, -4, 1, +-2, -1, 0, -4, 0, -2, 2, 0, +-2, 1, 2, 2, 5, 2, 7, 1, +12, 2, 10, 1, 15, -2, 13, -3, +15, -4, 14, -4, 12, -2, 11, 1, +6, 2, 5, 3, 3, 2, 5, -2, +8, -3, 6, -3, 7, -2, 4, -3, +4, -1, 2, 2, -4, 4, -4, 5, +-8, 3, -8, 1, -9, -2, -10, -4, +-8, -3, -11, -3, -6, -4, -6, -3, +-5, -1, -6, 1, -7, 0, -5, -1, +-4, -5, 0, -8, -2, -4, -5, -1, +-5, 0, -5, 2, -4, 4, -4, 1, +0, -2, 4, -3, 4, -2, 7, -2, +9, -4, 14, -5, 14, -2, 10, 3, +8, 4, 5, 3, 9, -1, 7, -2, +7, -2, 4, -1, 6, -2, 9, -3, +10, -2, 12, -2, 9, 0, 8, -1, +7, -4, 5, -5, 5, -4, 0, -4, +0, -2, -2, -1, -5, -2, -3, -1, +-8, 2, -8, 3, -9, 1, -9, -1, +-7, -1, -9, -1, -6, 2, -9, 6, +-7, 4, -8, 6, -10, 5, -11, 3, +-12, 2, -9, 0, -6, -4, -1, -4, +1, -1, 0, 2, 1, 4, 2, 4, +6, 0, 8, -4, 7, -3, 8, -4, +5, -4, 8, -2, 8, -2, 7, 0, +7, 3, 4, 4, 4, 3, 2, 1, +7, -2, 5, -2, 5, 0, 5, 3, +1, 5, 3, 4, 3, -1, 5, -2, +1, 1, -5, -1, -3, -4, -5, -4, +-4, -2, -2, -2, -2, 1, -1, 3, +-4, 1, -4, 1, -6, 0, -6, -3, +-5, -2, -7, -1, -6, -3, -6, 0, +-6, 4, -8, 5, -6, 2, -3, 1, +-4, -1, -3, -3, -1, -3, 2, -3, +5, 0, 4, 4, 3, 2, 5, -2, +8, -3, 6, -4, 6, -7, 8, -9, +8, -8, 9, -3, 3, 4, 5, 5, +7, 4, 5, 4, 6, 3, 3, -2, +6, -4, 4, -5, 5, -8, 6, -5, +3, 0, 2, 4, -1, 3, 1, -2, +3, -6, 1, -5, 2, -5, 0, -6, +-1, -1, -2, 1, -4, 4, -6, 7, +-7, 8, -5, 2, -7, 0, -8, -1, +-9, -4, -8, -2, -5, 2, -6, 6, +-4, 6, -5, 8, -4, 6, -3, 2, +-1, -1, 2, -5, 0, -6, 0, -2, +-2, 1, -3, 5, -1, 8, -1, 5, +4, 0, 5, -3, 5, -5, 7, -6, +3, -3, 6, -1, 4, 1, 5, 7, +0, 10, -1, 5, 4, 0, 2, -5, +5, -8, 4, -8, 2, -4, 0, 1, +-1, 1, 3, 2, 3, 4, 0, 7, +-2, 6, -6, 0, -5, -4, -6, -2, +-7, 1, -7, 5, -7, 7, -5, 4, +-3, 0, 1, -2, -1, -3, 0, -6, +0, -8, 1, -8, 1, -5, -2, 2, +-1, 7, -2, 8, -2, 7, -3, 1, +-1, -7, 2, -7, -1, -5, 0, -4, +2, -2, 4, 0, 6, 4, 2, 7, +3, 6, 4, -2, 5, -7, 6, -7, +2, -6, 3, -4, 1, 0, 3, 3, +2, 5, 2, 5, 4, 2, 0, -1, +1, -4, 2, -9, 3, -8, 4, -1, +1, 5, -1, 7, -1, 6, 0, 1, +1, -3, -1, -2, -4, -3, -6, -5, +-6, -3, -6, 2, -5, 7, -4, 10, +-2, 9, -1, 3, -3, -2, 0, -7, +-2, -8, -1, -6, -1, -1, -5, 3, +-4, 7, -6, 11, -4, 8, -2, 3, +0, -2, 2, -7, 0, -9, 3, -5, +1, 0, 0, 5, 2, 8, 0, 9, +0, 7, -2, 4, -3, -2, -1, -6, +-2, -5, 1, -4, 2, -1, 5, 4, +4, 6, 4, 3, 6, -2, 8, -7, +8, -11, 5, -10, 3, -9, 0, -6, +1, -2, 4, 4, 2, 7, 2, 6, +0, -1, 1, -7, 0, -9, -1, -7, +1, -6, 0, -2, 0, 5, -3, 9, +-7, 10, -3, 8, -3, 1, 0, -7, +-2, -9, -2, -9, -3, -3, -5, 5, +1, 7, 0, 9, -1, 10, -2, 5, +-2, -4, 2, -8, 3, -12, 4, -11, +3, -4, 0, 4, 1, 7, 0, 10, +0, 9, 1, 1, 1, -3, 1, -5, +0, -8, 2, -8, 3, -1, 3, 4, +2, 9, 4, 10, 2, 3, 1, -3, +1, -7, 0, -11, 3, -8, 1, -2, +0, 0, 2, 5, -2, 12, -4, 13, +-4, 5, 1, -2, 0, -7, -6, -8, +-5, -7, -4, -2, 0, 4, 1, 7, +2, 4, 5, 0, -3, 3, -4, -3, +-2, -10, 2, -11, 3, -8, -1, 0, +-5, 10, -5, 13, -1, 7, 3, 2, +3, -4, 1, -11, 2, -13, 1, -9, +2, -6, 2, 2, 2, 11, 1, 14, +-4, 14, -5, 10, -3, -2, -1, -10, +3, -9, 3, -8, 1, -2, 2, 7, +-3, 10, 0, 10, 1, 9, 2, 4, +0, -4, -4, -8, -2, -9, -3, -4, +-2, 5, 2, 9, 0, 10, -1, 9, +-2, 1, -1, -5, 0, -5, -3, -6, +-2, -8, -4, -3, -4, 3, -1, 7, +-1, 11, 1, 11, -3, 5, -6, -2, +-7, -7, -6, -10, -3, -7, 2, -3, +3, 2, 3, 7, 0, 10, -2, 6, +1, -1, 0, -6, 3, -13, 3, -12, +1, -5, 1, 2, -2, 8, 1, 11, +5, 7, 3, 3, 4, 0, -2, -8, +0, -14, 4, -11, 3, -3, 6, 4, +4, 9, 5, 9, 2, 5, -1, 0, +4, -5, 2, -10, 1, -8, -1, -7, +-3, -5, 2, 3, 0, 13, 0, 13, +2, 5, 1, -4, 0, -13, -4, -13, +-1, -9, 1, -4, -1, 4, -3, 11, +-5, 10, -5, 8, -2, 6, -1, -4, +2, -14, 4, -16, 0, -13, 1, -5, +-1, 8, -1, 12, 1, 11, 0, 9, +0, 0, 0, -9, 1, -12, 3, -13, +4, -12, 8, -1, 4, 9, 0, 10, +4, 9, 0, 5, 6, -6, 8, -12, +7, -12, 3, -9, -4, -3, -1, 3, +1, 10, 1, 16, 0, 17, -4, 6, +-4, -4, -4, -11, 0, -15, 6, -12, +6, -3, 6, 1, 0, 7, -6, 13, +-3, 8, -2, 3, -1, -3, -2, -13, +-3, -17, -3, -8, -3, 1, -1, 7, +5, 12, 2, 7, 2, -2, 0, -4, +-5, -8, 1, -13, 1, -10, 2, -3, +-3, 6, -7, 13, -1, 13, 2, 4, +7, -1, 7, -6, 1, -10, 0, -8, +-4, -5, -1, -2, 6, 4, 5, 12, +7, 11, 2, 8, -1, 2, -2, -9, +1, -16, 8, -12, 6, -5, 2, 3, +-1, 10, -2, 9, 2, 7, 4, 6, +3, -1, 3, -12, -2, -14, -3, -13, +-2, -6, -1, 7, 1, 16, -5, 16, +-7, 9, -5, 1, -7, -8, -2, -9, +2, -12, 3, -12, 2, -4, -6, 7, +-5, 13, -3, 12, 1, 6, 6, -5, +0, -11, -2, -11, -5, -10, -4, -4, +4, 3, 5, 6, 6, 11, 1, 13, +-4, 7, 0, -5, 4, -13, 10, -17, +8, -11, 0, 1, 0, 6, -3, 10, +2, 11, 9, 4, 9, -1, 5, -1, +-4, -8, -5, -13, 1, -8, 0, 2, +4, 9, 4, 13, -1, 10, -1, 1, +-6, -2, -2, -7, 1, -11, 0, -10, +-1, -2, -10, 3, -11, 13, -5, 17, +-2, 11, 3, 5, -3, -4, -8, -12, +-7, -13, -7, -6, 2, -2, 1, 5, +0, 12, -4, 12, -8, 8, -1, 4, +1, -7, 5, -14, 7, -13, 1, -9, +-1, 2, -4, 13, -1, 14, 7, 8, +3, 9, 1, 1, -2, -10, -1, -13, +5, -13, 6, -9, 10, 4, 6, 14, +-1, 13, -2, 12, -4, 6, -1, -4, +4, -8, 2, -10, 1, -9, -6, -2, +-8, 8, -1, 11, 0, 13, 4, 11, +1, -3, -4, -13, -3, -13, -3, -13, +2, -7, 5, 1, 1, 4, -3, 10, +-13, 15, -10, 9, -3, -1, -1, -6, +3, -14, -3, -15, -4, -4, -5, 6, +-1, 10, 6, 13, 4, 9, 0, 3, +-6, 1, -8, -7, 2, -14, 7, -10, +7, -3, 7, 4, -3, 15, -3, 14, +2, 2, 10, -5, 13, -8, 6, -11, +2, -10, 0, -5, -2, 0, 3, 7, +5, 11, 7, 8, 4, 3, -3, -4, +0, -14, -1, -14, 3, -7, 5, -1, +-2, 6, -5, 12, -9, 10, -6, 7, +1, 7, -1, -1, -1, -9, -8, -12, +-10, -10, -4, -4, -5, 10, 0, 16, +-2, 13, -8, 9, -6, -1, -7, -10, +2, -11, 7, -11, 7, -12, 6, -2, +-3, 7, -5, 12, -1, 10, 4, 4, +11, -7, 6, -12, 2, -12, 3, -11, +1, -5, 8, 3, 11, 5, 10, 9, +4, 12, -4, 3, -1, -7, 4, -11, +8, -15, 11, -9, 2, 2, -2, 5, +-1, 6, -1, 9, 6, 5, 5, -1, +3, -3, -5, -7, -10, -12, -4, -7, +0, 1, 3, 8, 0, 13, -6, 7, +-6, -3, -8, -5, -4, -6, 2, -10, +-1, -7, 0, -3, -7, 1, -9, 9, +-2, 14, 1, 6, 9, -2, 4, -6, +-5, -12, -5, -11, -4, -5, 4, 0, +7, 5, 2, 12, 0, 11, -5, 7, +0, 2, 7, -8, 10, -14, 12, -8, +1, -1, -4, 3, -1, 9, 2, 9, +9, 5, 7, 4, 3, 0, -1, -7, +-9, -6, -1, -9, 5, -8, 8, 4, +6, 12, -6, 11, -5, 8, -8, 4, +-5, -5, 3, -7, -1, -5, -5, -6, +-9, -3, -11, 6, -4, 10, -3, 13, +1, 9, 1, -5, -6, -10, -6, -9, +-7, -7, -1, -2, 2, 6, -1, 5, +-2, 4, -6, 8, -5, 5, 3, -2, +4, -3, 4, -9, 0, -11, -1, -3, +2, 4, 3, 6, 13, 5, 13, 4, +5, 0, 1, -1, -4, -5, 0, -8, +7, -7, 7, -2, 8, 4, 0, 10, +-4, 13, -1, 6, 1, -1, 11, -6, +5, -9, -2, -4, -7, -1, -9, -1, +-1, 5, 1, 11, 2, 8, -1, 3, +-9, -3, -5, -12, -3, -12, -3, -3, +2, 0, -4, 3, -7, 9, -10, 7, +-8, 3, 4, 1, 5, -5, 4, -12, +-2, -10, -9, -9, -3, -5, 3, 2, +8, 8, 9, 7, -4, 8, -5, 3, +-3, -6, 2, -6, 10, -7, 8, -9, +9, -3, 2, 6, -3, 9, 2, 10, +3, 5, 11, -6, 11, -11, 2, -6, +0, -5, -2, -5, 7, 0, 11, 4, +4, 9, 1, 11, -7, 5, -6, -5, +0, -9, 3, -11, 5, -7, -2, 0, +-6, 3, -7, 4, -7, 8, 1, 5, +3, -1, 1, -5, -2, -9, -10, -10, +-8, -4, -5, 2, 2, 2, 6, 6, +-4, 6, -6, -1, -5, -1, -5, 0, +2, -3, 0, -4, -1, -2, -1, -3, +-3, 4, 5, 9, 7, 6, 9, 2, +6, -1, -2, -9, 1, -10, 0, -3, +5, -1, 10, 0, 8, 5, 6, 8, +-1, 5, 0, 2, 9, -7, 9, -12, +10, -7, 0, 0, -9, 4, -8, 9, +-7, 10, 2, 5, 5, 3, 2, -1, +-1, -8, -6, -11, -2, -10, 2, -8, +1, 3, 0, 11, -9, 9, -12, 7, +-8, 3, -4, -7, 5, -8, 2, -5, +-5, -7, -7, -4, -9, 2, -3, 7, +2, 10, 3, 9, 3, 3, -8, -1, +-8, -2, -4, -5, 0, -2, 7, 2, +3, 3, 2, 3, 0, 7, 0, 4, +8, -1, 8, -4, 9, -8, 6, -10, +-3, -2, 1, 1, 6, 1, 10, 5, +11, 6, 2, 2, 1, -2, -4, -3, +-5, -6, 2, -8, 4, -5, 5, 0, +-2, 7, -8, 9, -4, 4, -2, 0, +2, 1, -1, -3, -10, -4, -8, -5, +-9, -6, -2, -3, 5, 6, 0, 8, +-1, 4, -7, 0, -8, -6, -3, -9, +0, -8, 9, -6, 4, -3, -3, 4, +-2, 6, -5, 6, 3, 7, 6, 2, +3, -5, -1, -4, -9, -3, -4, -2, +3, 4, 7, 7, 12, 4, 7, 3, +2, 3, 1, -3, 2, -7, 10, -9, +11, -13, 8, -6, 2, 6, -8, 11, +-5, 14, -4, 13, -1, 3, 2, -4, +-3, -4, -7, -5, -6, -7, -1, -2, +6, 2, 1, 6, -3, 11, -9, 6, +-11, -4, -1, -8, -1, -8, 1, -7, +-3, -1, -8, 2, -7, 3, -8, 9, +-1, 9, 4, 2, 1, -1, -1, -5, +-9, -9, -6, -6, 1, 0, 1, 6, +5, 8, 0, 9, -2, 4, -2, 3, +0, 1, 7, -7, 9, -10, 7, -8, +3, -2, -4, 8, -1, 14, 4, 9, +8, 1, 10, -2, 1, -6, -3, -6, +-4, -1, -3, -1, 3, 2, 0, 9, +-2, 10, -4, 8, -6, 6, -2, 1, +-2, -6, -2, -6, -1, -5, -10, -3, +-6, 2, -4, 4, 0, 5, 2, 10, +-7, 8, -7, -2, -10, -6, -9, -7, +-2, -5, -3, 3, -1, 8, -2, 6, +-6, 7, -2, 5, -3, -1, 2, -2, +4, -4, -2, -8, -1, -7, -2, 1, +3, 4, 8, 8, 8, 10, 7, 2, +2, -4, 0, -6, 3, -9, 3, -7, +6, 1, 3, 5, -2, 7, -1, 12, +-4, 10, 1, 2, 5, -2, 3, -7, +1, -8, -5, -4, -4, 0, -1, 4, +-2, 9, 2, 11, -4, 7, -7, 3, +-7, -4, -7, -12, 2, -11, -1, -4, +-1, 1, -2, 6, -8, 9, -3, 5, +-2, 1, 0, 1, 1, -5, -5, -8, +-5, -6, -5, -7, -2, -2, 7, 7, +4, 10, 4, 6, 1, 1, -1, -5, +0, -9, 1, -7, 9, -7, 7, -3, +0, 6, 0, 10, -3, 11, -2, 12, +4, 4, 4, -8, 8, -13, 3, -12, +2, -8, 5, 1, 2, 8, 7, 7, +4, 6, 0, 5, -2, -1, -5, -6, +-1, -7, 1, -9, -1, -5, 0, 4, +-7, 8, -6, 11, -4, 10, -4, 4, +-1, 0, -7, -3, -6, -10, -6, -10, +-4, -4, 4, 0, 2, 7, 0, 12, +-3, 5, -5, -4, -1, -6, -2, -6, +-1, -5, 0, 0, -3, 2, 0, 3, +-1, 9, 1, 10, 6, 5, 4, -1, +4, -8, 1, -13, -1, -11, 5, -2, +5, 3, 7, 9, 6, 11, -1, 6, +1, 4, -3, 1, 0, -5, 4, -8, +-1, -3, -1, 0, -4, 2, 0, 10, +1, 10, 0, 4, 4, 1, -2, -6, +-6, -10, -3, -9, -3, -6, 1, 0, +-2, 10, -2, 10, -1, 6, -8, 7, +-6, 0, -4, -10, 1, -12, 3, -9, +-3, -4, -6, 4, -4, 9, -1, 8, +6, 5, 6, 1, 3, -7, 0, -11, +-2, -13, 4, -9, 2, 2, 1, 10, +1, 11, -2, 9, 0, 5, 2, -2, +5, -6, 7, -5, -2, -6, -1, -4, +-1, 3, -1, 7, 6, 11, 4, 12, +3, 6, -1, -3, -4, -7, -1, -11, +-1, -12, 5, -4, 4, 4, -4, 11, +-5, 13, -5, 9, -1, -1, 3, -8, +2, -12, 2, -12, -6, -5, -8, 1, +-4, 3, -2, 8, 1, 10, 0, 5, +-3, 0, -3, -6, -4, -13, 1, -13, +4, -7, 3, 0, 4, 9, -4, 14, +-2, 8, 1, 2, 1, -1, 4, -7, +-1, -12, 3, -10, 3, -6, 0, 0, +7, 9, 8, 8, 8, 2, 9, -1, +3, -7, 3, -11, 2, -12, 5, -7, +3, 1, -5, 10, -2, 13, -1, 8, +0, 7, 2, 0, 1, -8, 0, -12, +-1, -10, -2, -7, 0, 1, -2, 10, +-1, 11, -1, 9, -3, 2, 1, -8, +-1, -12, -2, -12, -1, -11, -2, -3, +-1, 8, -6, 14, -6, 13, -2, 10, +-3, 0, 2, -8, 3, -9, -1, -11, +-1, -7, -3, -1, 2, 7, 2, 10, +0, 14, 3, 7, 0, -4, 1, -7, +1, -10, 1, -10, 5, -5, 4, 2, +4, 8, 1, 13, -2, 12, 4, 3, +2, -4, 3, -11, 6, -19, 4, -12, +2, -3, 1, 3, 4, 10, 2, 13, +-1, 8, 0, -1, 0, -7, 0, -16, +5, -17, 2, -9, 1, -2, -2, 7, +-5, 14, -4, 12, -5, 4, 1, -3, +0, -8, -2, -13, 0, -11, -2, -5, +-3, 2, 1, 11, 1, 10, 5, 6, +1, 2, -2, -4, 0, -13, -1, -14, +5, -7, 2, -3, 1, 6, 3, 9, +3, 8, 6, 6, 7, -2, 6, -10, +7, -15, 0, -11, -1, -4, -2, 5, +-4, 16, -2, 16, -2, 10, 3, 2, +4, -9, 3, -11, 3, -11, 1, -9, +0, -6, 2, 2, 0, 8, -1, 12, +-3, 14, -2, 2, 0, -7, -4, -11, +-2, -12, -5, -8, -6, 1, -1, 10, +-1, 9, 0, 12, -1, 10, -5, 0, +-6, -3, -6, -8, -2, -11, 0, -7, +-3, 1, 1, 8, -2, 12, -1, 13, +4, 2, 6, -7, 4, -10, -2, -13, +-1, -9, 2, -2, 2, 6, 4, 11, +2, 14, -1, 9, 0, 3, -2, -2, +1, -12, 3, -16, 4, -9, 2, -3, +-2, 8, 1, 15, 3, 13, 2, 6, +2, -2, 0, -9, -1, -17, 0, -11, +-1, -4, -1, 5, -6, 12, -5, 14, +-2, 11, -4, 2, 1, -5, 3, -16, +4, -18, 0, -10, -3, -4, -1, 6, +-1, 12, 1, 11, 3, 8, -2, 0, +-2, -9, 0, -16, 1, -14, 3, -9, +2, -1, 2, 12, -2, 13, -2, 14, +2, 9, 2, -2, 4, -12, 5, -13, +0, -11, 0, -9, 2, 4, 2, 13, +3, 13, 0, 12, 3, 4, -1, -6, +-2, -10, 1, -10, 1, -10, 3, -4, +2, 7, 0, 9, 1, 12, 0, 9, +1, 0, -1, -5, -8, -11, -4, -11, +-5, -8, -2, 4, -1, 10, -1, 14, +-1, 15, -7, 7, -5, 1, -5, -6, +-7, -10, -3, -10, -3, -3, -4, 5, +-2, 10, 0, 14, 3, 8, 2, -1, +3, -5, 1, -12, -4, -12, 0, -8, +3, -1, 2, 9, 0, 15, 0, 17, +1, 5, 2, -2, 2, -11, 5, -16, +1, -13, 2, -8, 5, 0, 1, 8, +3, 15, 3, 11, 4, 4, 2, -4, +-1, -12, 0, -14, -2, -10, -1, -5, +3, 4, 1, 10, 2, 11, 0, 9, +-1, 2, 0, -10, 1, -19, 5, -14, +-2, -9, -5, 3, -2, 11, -2, 14, +-1, 12, -1, 7, -1, -2, -1, -14, +-1, -14, -1, -11, -2, -5, -5, 7, +1, 14, 0, 16, -1, 15, 0, 6, +-2, -4, 0, -14, 0, -14, 3, -13, +5, -6, 3, 6, 3, 12, -1, 19, +-5, 14, 0, 4, 1, -8, 2, -14, +0, -15, 1, -10, 4, 1, 1, 9, +4, 15, 3, 14, -2, 3, 0, -6, +1, -14, 3, -19, 5, -17, 4, -8, +3, 3, -3, 9, -2, 17, 1, 12, +0, 1, 1, -5, -2, -13, -5, -15, +-6, -11, -1, 0, 1, 8, -1, 17, +-4, 19, -4, 10, -8, 3, -4, -9, +4, -18, 5, -14, 3, -6, -3, 4, +-4, 13, -4, 18, -1, 14, 6, 6, +2, -2, -2, -14, -2, -16, -1, -14, +5, -8, 10, 3, 10, 12, 5, 14, +-2, 6, 3, 0, 3, -10, 3, -15, +6, -14, 2, -10, -6, 1, -6, 9, +-1, 15, 3, 13, 4, 5, 7, -6, +2, -15, -9, -12, -6, -10, 0, -8, +4, 5, 3, 12, -3, 16, -8, 15, +-11, 9, -5, -4, 2, -13, -1, -11, +-4, -12, -4, -3, -6, 8, -1, 14, +4, 15, 8, 8, 3, -2, -1, -12, +-2, -14, -5, -14, 3, -8, 6, 5, +2, 10, -3, 16, -6, 18, -5, 7, +1, -2, 5, -10, 7, -14, 0, -16, +-2, -5, 0, 6, -1, 13, 4, 20, +4, 12, 0, 4, -8, -5, -9, -13, +0, -18, 6, -12, 5, 0, 4, 8, +-4, 17, -9, 19, -5, 10, 1, -1, +6, -14, 5, -21, 2, -17, -6, -6, +-9, 7, -2, 12, 3, 15, 5, 7, +4, 1, -3, -5, -4, -17, 2, -18, +6, -13, 5, -4, 2, 1, 4, 12, +-2, 16, -4, 11, 1, 4, 2, -6, +-1, -14, -2, -16, 2, -13, 3, -1, +1, 12, 6, 16, 7, 13, 1, 7, +0, -1, -2, -11, -4, -11, -1, -13, +3, -6, 2, 5, -3, 12, 0, 15, +2, 10, 0, 4, 4, -10, 5, -16, +-1, -14, -2, -15, 1, -6, 4, 8, +-1, 15, -1, 17, 0, 11, -4, -1, +-3, -14, 0, -17, 1, -18, 2, -11, +3, 4, 1, 10, -3, 16, -2, 12, +3, 5, 1, -7, 3, -14, 4, -15, +-2, -14, -4, -2, -2, 5, 3, 10, +5, 15, 5, 11, 3, 3, -4, -4, +-8, -10, -2, -14, 4, -11, 7, 0, +5, 7, 1, 14, -2, 16, -5, 7, +3, -1, 6, -13, 3, -16, 0, -15, +-6, -3, -7, 4, 0, 11, 6, 18, +7, 10, 1, 3, -3, -6, -5, -14, +-6, -17, 3, -11, 6, -2, -1, 7, +-6, 17, -8, 16, -5, 6, 4, -2, +11, -14, 8, -18, -3, -14, -7, -9, +-4, 2, -2, 13, 4, 19, 6, 12, +2, 7, -8, -3, -8, -14, -1, -15, +4, -14, 11, -7, 7, 4, -4, 14, +-7, 14, 1, 10, 7, 5, 8, -8, +5, -15, -1, -14, -9, -12, -6, -1, +5, 10, 8, 15, 7, 14, 0, 9, +-6, -3, -5, -18, 6, -18, 13, -17, +7, -4, -5, 8, -8, 14, -10, 15, +-4, 14, 4, 8, 6, -7, 2, -14, +-7, -16, -8, -15, -4, -4, 5, 5, +12, 11, 7, 14, -2, 9, -8, 3, +-11, -4, -5, -9, 4, -16, 7, -11, +1, 3, -10, 9, -7, 19, -3, 19, +2, 10, 6, -2, 3, -8, -8, -12, +-12, -12, -1, -5, 10, 0, 11, 10, +7, 15, 2, 8, -6, 0, -1, -8, +6, -17, 10, -18, 7, -11, -1, 1, +-6, 7, -6, 15, 1, 17, 5, 13, +0, 4, -3, -9, -4, -16, -6, -16, +-2, -6, 3, 1, 7, 10, 1, 16, +-6, 13, -6, 8, -7, -3, 0, -13, +5, -16, 4, -13, 0, -6, -3, 6, +-5, 19, -6, 20, -2, 10, 6, 2, +1, -11, -4, -14, -3, -13, -3, -9, +1, 2, 4, 10, 5, 16, 0, 12, +-2, 8, 0, -3, 4, -15, 4, -16, +6, -13, 1, -5, -4, 7, -3, 14, +-2, 17, -2, 18, -4, 9, 2, -7, +0, -15, -1, -16, 1, -14, 2, -2, +3, 7, 3, 16, -2, 19, -6, 12, +-7, 0, -3, -10, 1, -14, 2, -19, +6, -9, 1, 2, -4, 10, -7, 16, +-1, 13, 4, 3, 4, -7, 4, -13, +0, -19, -4, -16, -2, -3, 2, 7, +2, 13, 4, 15, -1, 11, -7, 5, +-8, -6, 2, -13, 8, -15, 4, -7, +2, 0, -2, 5, -4, 14, 1, 12, +7, 10, 3, 5, -3, -4, -9, -11, +-8, -11, -4, -7, 8, -1, 14, 9, +7, 14, 0, 9, -5, 2, -3, -5, +1, -12, 4, -10, 3, -7, -2, -3, +-9, 4, -6, 16, -5, 15, 2, 10, +8, 1, 2, -11, -8, -12, -13, -10, +-5, -5, 2, 1, 7, 11, 4, 14, +-4, 9, -9, 4, -4, -5, 3, -11, +6, -10, 3, -10, -1, -5, -6, 5, +-8, 10, 5, 11, 13, 8, 7, 7, +-2, -4, -10, -8, -11, -12, -2, -9, +8, 3, 8, 11, 0, 15, -4, 10, +-5, 7, -4, -2, 6, -9, 12, -14, +9, -15, -3, -5, -9, 6, -7, 12, +-1, 16, 7, 12, 8, 3, -3, -5, +-11, -8, -10, -10, -4, -10, 5, -2, +8, 3, 4, 10, -7, 11, -7, 7, +1, -4, 6, -11, 8, -12, 2, -12, +-7, -4, -10, 0, -3, 6, 4, 11, +9, 9, 6, 4, -2, 1, -10, -7, +-6, -16, 7, -17, 13, -6, 8, 2, +2, 10, -2, 14, -4, 5, 4, -2, +11, -8, 8, -10, 1, -13, 0, -8, +-3, -1, -3, 7, 2, 15, 8, 9, +7, 3, 1, -3, 0, -9, -3, -14, +1, -12, 7, -7, 4, 3, -5, 13, +-8, 16, -6, 10, -4, 6, -1, -3, +3, -12, 2, -12, -4, -9, -4, -1, +-4, 6, -3, 12, 1, 10, 2, 9, +-2, 2, -4, -7, -4, -10, -3, -11, +-2, -7, 2, 0, 5, 8, -1, 12, +-4, 14, -5, 8, -1, -3, 2, -10, +6, -12, 7, -14, 1, -5, -2, 6, +-2, 10, -1, 13, 4, 9, 7, 0, +4, -9, -1, -9, -3, -12, 4, -10, +5, -1, 5, 5, 5, 8, 1, 8, +-3, 4, 0, -4, 6, -10, 6, -13, +6, -14, 1, -5, -8, 5, -9, 9, +0, 13, 3, 10, 2, 5, -3, 0, +-10, -5, -11, -9, -7, -6, 1, 4, +1, 5, 0, 9, -2, 8, -6, 6, +-8, 3, 0, -2, 4, -7, 1, -8, +-5, -3, -7, -1, -4, 5, 0, 12, +9, 9, 9, 2, 3, -3, -3, -11, +-3, -13, 2, -9, 8, -3, 10, 2, +4, 9, -3, 8, -4, 5, 0, 6, +1, -2, 7, -7, 6, -12, -1, -10, +-4, -6, -1, 5, 3, 12, 5, 9, +5, 7, -3, 1, -10, -8, -7, -11, +2, -7, 4, -4, 3, 3, -3, 9, +-8, 10, -10, 5, -2, 5, 4, -1, +2, -8, 1, -10, -4, -10, -9, -1, +-7, 6, 3, 11, 5, 10, 1, 9, +-5, 1, -6, -6, -5, -9, 4, -11, +11, -8, 7, 1, 0, 6, -6, 8, +-6, 12, -1, 6, 8, -3, 10, -6, +0, -4, -8, -9, -4, -3, 2, 4, +4, 10, 5, 12, 3, 6, -1, -1, +-5, -6, -1, -6, 5, -11, 7, -7, +4, 0, -2, 4, -9, 8, -5, 10, +2, 6, 2, 1, 1, -3, -3, -8, +-7, -9, -8, -4, 0, -1, 7, 2, +5, 9, -2, 8, -5, 3, -7, -3, +-3, -7, 2, -10, 5, -8, 3, -1, +-3, 4, -5, 10, -4, 7, 2, 3, +7, -1, 8, -9, 5, -12, 0, -8, +-2, -4, 0, -1, 5, 4, 7, 10, +2, 7, -1, 4, -1, 1, -2, -6, +0, -5, 2, -4, 4, -2, 2, 0, +0, 8, -3, 11, -5, 9, -1, 6, +1, -3, 0, -6, -3, -5, -5, -3, +-4, 0, -2, 5, 0, 6, 3, 6, +-1, 6, -4, 0, -4, -7, -2, -8, +1, -9, 1, -5, 1, 4, -2, 4, +-3, 8, -6, 9, -5, 5, 0, -6, +5, -6, 2, -4, -5, -7, -4, -3, +1, 2, 3, 7, 1, 11, 0, 11, +-3, 2, -4, -4, -2, -7, 5, -10, +8, -8, 9, -2, 7, 0, 1, 3, +0, 4, 4, 2, 6, 0, 4, -7, +7, -13, 6, -14, 0, -1, -4, 4, +2, 6, 3, 9, -1, 7, -3, 2, +-4, -3, -3, -7, 2, -10, 6, -4, +2, -1, -3, 3, -7, 9, -6, 8, +-2, 1, 3, -1, 5, -6, -1, -8, +-5, -6, -5, -2, -4, 1, 1, 4, +5, 8, 0, 6, -7, 6, -11, 2, +-4, -2, 0, -4, 2, -1, 3, -2, +-1, 0, -2, 4, 0, 4, 4, 6, +3, 4, 4, -3, 2, -9, -3, -6, +-2, -5, 5, -1, 8, 7, 3, 10, +-2, 5, -4, 3, -5, 0, 0, -6, +7, -5, 6, -5, 0, 1, -8, 5, +-9, 8, -4, 5, 2, 5, 7, 2, +4, -7, -5, -5, -8, -2, -7, -2, +-3, 2, 2, 7, -1, 7, -7, 8, +-10, 6, -7, -2, 0, -8, 7, -9, +9, -10, 3, -4, -7, 3, -6, 2, +2, 3, 4, 3, 8, -1, 6, -8, +3, -7, -1, -9, 2, -8, 5, -1, +6, 2, 5, 3, 3, 5, -2, 3, +-2, -3, 6, -4, 7, -5, 6, -6, +2, -3, -2, 2, -2, 1, 0, 6, +4, 6, 3, 1, 1, -1, 0, -4, +-2, -5, -5, -2, -2, 4, 2, 0, +1, 2, -2, 4, -2, 3, -3, 2, +-2, 1, -2, -4, -1, -7, -1, -4, +-2, -3, 1, 1, -2, 5, -2, 5, +2, -2, 1, -2, 0, -6, 1, -7, +2, -5, -1, 0, -2, 0, 1, 0, +3, 4, 2, 0, 4, -1, 5, -6, +3, -6, 2, -4, 2, -2, 1, -3, +3, -1, 6, 4, 3, 5, -2, 4, +0, 0, 5, -5, 1, -3, -1, 2, +-4, 1, -3, 4, -2, 5, 0, 6, +-2, 5, -3, 6, -1, 0, 0, -4, +-1, -2, -3, -6, 1, -2, 1, 1, +0, 2, 2, 0, 0, 3, -3, 2, +-2, 0, -5, 0, -4, -3, 0, -5, +2, -2, 1, 0, -1, 3, -1, 5, +-1, 4, -3, 1, -4, -3, 1, -3, +-1, -4, 0, -1, 0, 0, 0, -2, +6, 0, 6, 2, 4, 3, -1, -1, +-2, -2, 3, -6, 2, -4, 1, 3, +3, 3, 2, 1, 3, 3, 0, 2, +-1, -1, 4, -4, 7, -5, 5, -6, +1, -5, 1, -2, 0, 1, 0, 10, +-2, 5, 2, -2, 2, -3, -1, -4, +-2, -4, -4, -1, -1, 2, 1, 0, +-1, 6, -6, 7, -8, 4, -6, 2, +0, 1, 0, -2, -4, 0, -4, 1, +-4, 0, -3, 0, 0, 1, 4, -1, +7, -2, 2, 2, -5, 0, -7, 0, +-5, -2, 6, -3, 7, -3, 4, 1, +4, 1, 1, 0, 0, 2, 2, -1, +3, -3, 4, -3, 5, -6, 0, -4, +-1, 5, -1, 5, 3, 1, 8, -1, +3, -3, 1, -5, 2, -4, 3, -4, +4, -4, 1, 1, 0, 2, -1, 4, +-6, 5, -5, 9, -6, 3, -5, 2, +-5, 2, -7, -1, -5, 1, 0, 1, +3, 2, -3, 3, -4, 4, -4, 1, +0, -2, -1, -1, -2, -2, -2, -1, +-3, 2, 0, 1, 0, 1, -1, 3, +3, 0, 4, -2, 1, -2, -3, 1, +-4, -3, 4, -1, 5, -1, 2, 3, +-1, 7, -2, 4, 0, -2, 3, -5, +5, -5, 7, -6, 7, -3, 1, -1, +1, 0, -4, 5, -1, 8, 2, 4, +-3, 3, -3, 1, -3, -4, -1, -5, +1, -1, 1, 1, 1, 0, 3, 1, +1, -4, -1, 0, -5, 4, -3, 3, +-1, 0, -3, -2, -2, -4, 1, -2, +-1, 3, 0, 2, 2, -1, 0, -2, +3, -2, -4, -1, -6, 4, -5, 2, +-1, 1, 2, 1, 1, 1, 1, -1, +1, 2, 0, 4, -1, -5, 2, -4, +2, -2, 1, 2, 0, 2, -2, 3, +2, 2, 1, 2, 1, 2, 5, -3, +0, -3, 0, 1, 2, 0, -2, 2, +-2, 5, -1, 0, 4, 0, 2, 1, +-1, -1, 0, -5, 1, 1, -3, 2, +-5, 2, -5, 4, -2, 0, 4, 1, +0, 0, 0, -2, 1, -5, 0, -2, +2, -2, 0, -3, -4, 1, -1, 2, +-2, -1, 0, 1, 2, 1, 0, -2, +4, -3, 1, -4, 0, -5, 1, -5, +5, 2, 3, 3, -1, 4, -5, 4, +-2, 1, 2, -1, 0, -1, 3, -2, +0, -4, 2, 0, 3, -1, 1, 0, +2, 3, 3, 1, 4, -4, 5, -3, +-1, 0, -4, 1, 0, -1, 3, -4, +4, -4, 1, 2, 0, 3, 2, -1, +0, 0, -3, -2, 1, -1, -4, 4, +-4, 5, -5, 2, -6, 0, 4, 0, +2, -4, 0, 1, -4, 2, -1, -4, +3, -5, -1, 1, -5, 1, -1, 1, +1, 5, -2, 4, -4, 2, -3, 1, +2, -2, 1, -2, -4, 2, -1, -3, +2, -1, 2, 4, 0, 7, -6, 2, +-1, 1, 2, -2, 3, -5, 5, -3, +3, -4, 5, -3, 2, 1, -1, 2, +-1, -2, 5, 2, 2, 4, -2, 1, +-5, 0, -6, 1, 2, -2, 1, 1, +2, 2, 2, -2, -1, 0, 1, 3, +-3, 2, -5, -2, 1, -2, 2, -5, +1, -1, -7, 7, -9, 8, -5, 6, +-2, 2, 0, -1, -1, -4, 0, 0, +1, -2, 2, -2, -3, 0, 1, 1, +0, 3, -2, 5, 0, 1, -4, -1, +0, 1, 1, -1, -1, -3, 3, -3, +2, 1, 4, -2, 3, 1, 0, 2, +1, 0, 2, -2, 6, -6, 5, -8, +2, -4, 1, 3, 2, 1, -1, 4, +-5, 4, 1, 0, 1, -3, 6, -2, +2, -4, -1, -4, 2, 0, -1, 2, +-1, 1, -1, 1, 2, -1, 3, -4, +-1, 1, -5, -1, -3, 1, 1, 0, +2, -3, 1, -3, -4, 3, -4, 7, +-1, 4, -2, 3, 0, -1, -3, -2, +-3, 0, 0, 2, -5, -1, 3, 1, +2, 2, 0, 1, 0, 1, -4, 3, +0, -2, 4, -3, 3, -1, 0, -3, +2, 0, 1, 3, 1, 4, -1, -2, +0, -1, 7, -3, 2, -2, 0, 0, +0, -5, 1, -5, 7, 0, 2, 1, +2, -2, 3, 1, -1, -1, 2, -3, +-3, 0, -4, 2, 0, -3, 4, -3, +4, -3, 0, -2, -1, 3, 1, -1, +6, -5, 0, -4, 0, 2, -3, 0, +-4, 5, -2, 6, -7, 1, 0, 0, +4, 1, -1, 1, -3, 3, -7, 3, +-2, -3, 3, -4, 1, -1, 2, 2, +1, 3, 0, 4, 0, -3, 0, -5, +1, -2, 7, -2, 4, -3, 0, -1, +1, -1, -2, -2, 4, 5, -2, 3, +0, -1, 4, -1, 0, -1, -1, -2, +-3, 0, -1, 1, 4, -2, 5, -1, +1, -1, -1, -1, -1, 0, 0, 0, +0, -3, -3, 1, -2, 4, -1, 3, +-5, 2, -2, 2, -2, -2, 3, -2, +6, 0, 0, -4, 1, -2, -3, -2, +2, -4, 3, -3, 1, 2, 2, 2, +2, 1, -1, 1, -3, -2, -1, -1, +-1, 3, 2, 3, -1, -1, -3, 1, +1, 2, -2, 4, -1, 3, 0, -1, +1, -7, 8, -5, 4, -4, 3, -4, +1, 2, -1, 2, 4, 1, -1, 0, +1, -1, 4, -6, 5, -4, 2, -2, +-1, -3, -3, 1, 1, 4, 3, 1, +-3, -1, 1, -1, -2, -1, -1, 1, +1, 1, -2, -1, 3, -4, 2, 0, +-2, 0, 0, -1, -1, 0, 5, -2, +6, -5, 2, -5, -2, 0, -3, -2, +2, -1, 6, -4, 6, -4, 2, -1, +5, 2, -2, -1, -2, -2, 1, -2, +0, -3, 7, 1, -1, 2, -3, 0, +0, -3, 3, -1, 5, -2, 0, 4, +-2, 3, 1, -1, -1, -2, -4, 2, +-4, 3, -1, 1, 5, 3, 4, -1, +-6, 0, -6, 3, -3, 2, -3, 2, +2, 2, -2, -3, 5, -5, 3, 1, +-6, 6, -5, 5, -5, 3, 3, 0, +1, -2, -7, 4, -6, 3, -3, 1, +0, -1, 2, -1, 3, -4, 3, -1, +4, 2, -2, -2, -4, -1, 1, -1, +3, -1, 5, 1, -1, 4, -4, -2, +3, -2, 0, 0, 2, -1, 1, 0, +0, 2, 2, -1, 0, -5, 1, -2, +3, -4, 8, -2, 6, -2, 4, -4, +0, -7, 2, -1, 1, 1, -5, 2, +-3, 4, -1, -2, 5, -4, 4, 0, +-5, 0, -1, -4, 2, -2, 5, -3, +6, -3, -2, -1, 2, 0, 2, -4, +0, -2, 2, -1, 4, -5, 7, -3, +3, -1, -4, -3, -5, -3, 5, 2, +3, 0, 3, 3, -3, 4, -6, -1, +1, 0, -4, 2, -1, 1, 3, -2, +2, -1, 4, 0, -5, 2, -7, 5, +0, 1, 5, -4, 4, 1, -2, 1, +-3, -1, 1, 1, 2, -1, -1, -2, +1, 0, 4, 2, 1, -1, 0, 3, +-9, 1, -1, -2, 1, 0, 1, 3, +1, 3, -5, 4, -3, 3, -2, -2, +-2, -1, 0, 1, 2, 1, 2, -2, +2, -3, -1, -4, -4, 1, 1, 4, +1, 2, -2, 3, -3, 4, -4, 0, +2, -1, -5, 3, -3, -1, 6, -2, +3, -1, 6, 1, -5, 2, -9, 7, +-4, 2, -1, -2, 3, -1, 3, -1, +3, 0, -1, 0, -3, 2, -5, -2, +3, 1, 8, 1, 2, -2, 0, -3, +-4, -3, 1, -5, 6, -1, 2, 2, +5, -2, -1, 1, -4, 2, -4, 1, +-6, 0, 3, 2, 7, -3, 5, -3, +-4, 2, -6, 2, -3, 0, 4, -1, +4, 0, -3, 1, -1, 3, -4, 1, +0, -2, -2, 0, 0, 1, 5, 0, +0, 4, -3, 4, -6, 2, -5, 2, +0, 2, -2, 2, -1, 2, 1, 1, +2, -4, 1, 0, -4, 0, 0, -4, +8, -3, 6, 3, -4, 1, -3, -1, +-2, 1, 0, 0, 3, 2, -4, 3, +0, 2, -2, 0, -2, 4, -3, 0, +-4, -2, 5, -2, 8, -3, 2, -3, +0, 1, 0, 1, -2, 1, -6, 6, +-7, 4, -3, 2, 4, 2, 2, 0, +-1, -5, -1, -3, -1, -2, 7, 0, +0, 5, -1, 2, 1, -4, -3, 1, +-1, 4, -4, -1, 5, 0, 8, -1, +3, -1, -5, 0, -7, 2, -1, -2, +7, -3, 10, -2, 3, -4, 2, -1, +-2, 3, -5, 3, 1, -3, 2, -2, +10, -5, 7, -2, -3, 2, -3, 1, +-4, -2, 5, -1, 7, -1, 0, -1, +1, 2, -3, 0, -3, 0, -1, -1, +4, 2, 3, 2, 3, 4, -3, 0, +-5, -5, -1, -1, -1, 3, 4, 4, +-2, 3, -3, 1, 2, -4, -2, 1, +-1, 4, -1, 0, 4, -2, 7, 0, +-1, -1, -4, 1, -4, 5, -1, 3, +1, 3, 0, 2, 1, -1, 1, -1, +0, 5, -7, 3, -2, 1, -1, 3, +5, 1, 6, 0, -3, 4, -4, 3, +-4, 0, 1, 3, 2, 4, -3, 2, +2, 0, 2, -2, 0, -5, 3, -2, +6, -1, 8, -1, 7, -3, 2, -4, +-3, -3, 0, 0, 2, 3, 4, -1, +4, 0, 1, -2, 5, -1, -3, 0, +-2, 3, -1, 0, 2, -2, 8, 0, +0, -2, 1, 0, 1, 2, 1, 1, +4, -2, 3, 2, 0, 2, 1, -1, +0, -1, -2, -1, 2, -1, 4, 3, +6, 2, 6, -2, -2, 0, 0, -2, +2, -2, 2, 2, 4, 3, 1, 0, +3, 3, -1, 2, -2, -1, 0, 3, +2, 2, 7, -4, 5, -3, 1, 1, +-3, 0, 4, 1, 3, 0, 3, 0, +4, 0, 3, 1, 6, -1, -4, 1, +-5, 3, -1, 1, 0, 1, 7, 2, +2, 5, -3, 4, -3, 5, -5, 1, +0, -1, 4, 0, 10, -2, 7, -3, +1, 1, -5, 3, -2, 2, 7, 3, +7, 0, 8, -4, 1, -4, 3, -3, +2, -3, 1, 2, 9, 1, 7, -1, +7, 1, 2, 1, -4, -1, 1, -2, +5, 0, 9, -4, 6, 0, 0, 4, +-2, 3, 0, 0, 4, 0, 7, -2, +10, 0, 2, 5, -2, 2, -5, -2, +-3, -2, 10, 0, 7, 1, 7, 5, +1, 1, -2, -1, -1, 2, -3, 2, +3, -1, 9, -1, 9, 0, 3, -2, +1, 0, 1, 2, 5, 1, 11, -3, +8, -4, 6, -5, 2, -3, 2, 3, +2, 4, 0, 3, 8, 1, 9, -3, +7, -4, 6, -2, 1, -5, 9, -5, +8, -5, 11, -5, 10, -4, 7, 2, +6, -1, 5, -4, 6, -3, 7, -4, +10, -3, 7, -3, 6, -4, 5, -3, +3, 2, 7, 4, 5, 1, 8, -3, +10, -5, 4, -3, 2, 2, -3, 3, +1, 2, 7, 2, 8, -2, 11, -3, +4, 0, 2, 4, 2, 0, 4, -1, +4, 1, 5, 0, 6, 2, 3, 3, +2, 3, -1, 3, 7, 2, 10, -1, +6, 0, 2, 1, 0, -2, 5, -4, +8, 2, 8, 3, 8, 4, 5, 4, +3, 0, 2, -2, 1, -1, 7, -1, +12, -5, 12, -3, 6, -1, 4, 1, +2, 5, 6, 5, 4, 1, 5, 1, +6, 2, 1, -1, 4, 0, 3, 0, +9, -2, 14, -1, 8, 4, 4, 2, +2, 0, 5, -1, 5, -4, 6, -2, +7, 2, 7, 4, 7, 4, 2, 5, +3, -1, 5, -1, 8, 0, 11, -2, +7, -7, 11, -5, 9, -4, 8, -2, +9, 3, 9, 0, 14, -1, 11, -3, +9, -4, 3, -2, 3, 2, 7, 1, +10, 1, 10, 1, 8, 2, 6, 2, +3, 3, 4, 0, 8, -6, 12, -4, +14, -1, 4, 4, 0, 5, 2, 5, +4, 3, 11, 4, 8, 2, 6, -1, +5, -2, 4, -4, 9, -3, 9, 0, +13, 4, 12, 3, 7, 3, 0, 4, +1, 3, 4, 0, 12, -2, 15, -4, +9, -4, 8, 0, 7, -1, 11, -2, +14, -1, 13, -1, 12, -5, 9, -4, +6, -1, 4, 1, 9, 1, 15, 1, +12, 0, 9, 0, 9, 2, 8, 2, +6, 0, 8, -3, 13, -5, 10, -1, +12, 2, 7, 0, 9, 1, 11, 1, +10, -1, 11, 0, 4, 3, 6, -1, +9, -4, 7, 3, 6, 5, 5, 5, +10, 3, 13, 0, 9, 0, 4, 1, +7, -1, 12, -3, 10, -1, 11, 1, +9, 2, 10, 2, 13, 2, 8, -1, +10, 1, 7, -1, 11, -2, 11, -1, +6, 2, 9, 2, 9, 0, 12, 2, +12, 1, 10, 3, 10, 2, 7, 0, +6, -3, 9, -2, 15, -1, 16, 1, +14, 4, 10, 4, 6, 3, 8, 2, +9, -1, 12, -2, 11, 1, 9, 1, +10, 1, 7, 2, 9, 5, 11, 1, +15, -2, 15, -5, 13, -7, 12, -6, +13, -6, 16, -3, 13, -1, 15, 4, +10, 7, 8, 7, 7, 1, 9, -4, +14, -2, 10, 3, 10, 6, 8, 6, +5, 4, 14, -3, 16, -4, 17, -3, +17, -2, 13, -1, 12, -1, 8, -5, +10, 1, 8, 6, 11, 4, 16, 2, +15, 0, 13, 0, 7, -1, 11, 3, +8, 1, 13, 1, 15, 3, 9, 5, +12, 2, 11, 3, 13, 2, 15, -2, +16, -2, 15, -2, 8, -1, 10, 0, +12, -1, 14, -3, 18, -1, 15, 1, +16, 0, 12, -2, 11, -3, 10, -3, +12, -1, 16, 2, 15, 2, 15, 4, +11, 4, 12, 1, 13, -1, 17, -2, +18, -5, 18, -3, 15, 3, 7, 4, +7, 3, 14, 2, 22, -1, 17, -2, +15, 0, 13, -4, 12, -4, 15, -3, +15, -2, 18, -1, 18, 6, 11, 9, +8, 7, 5, 5, 11, 0, 17, -2, +17, -3, 19, 1, 13, 3, 13, 5, +11, 4, 14, 1, 18, -1, 20, -1, +19, -3, 11, -4, 12, -2, 11, -1, +14, 2, 17, 5, 12, 4, 14, 1, +12, 2, 13, 0, 12, -1, 13, -1, +21, -2, 16, 0, 15, 3, 17, 3, +16, 2, 18, 4, 15, 1, 16, -1, +13, 1, 16, 1, 15, -1, 12, 2, +13, 5, 11, 6, 14, 2, 19, -2, +20, -3, 15, -3, 13, -2, 17, -6, +19, -3, 21, -1, 25, -1, 21, -1, +19, 0, 18, 1, 15, 1, 18, 2, +19, -1, 17, 1, 13, 4, 13, 4, +15, 2, 17, 1, 20, -1, 22, -3, +17, -5, 19, -6, 17, -6, 16, -5, +23, -3, 21, 0, 19, 6, 14, 4, +16, 0, 17, -3, 17, -2, 21, -2, +17, 4, 15, 8, 13, 7, 13, 7, +14, 6, 14, 7, 17, 5, 16, 1, +19, -5, 20, -5, 14, -2, 19, -1, +18, 0, 21, 2, 22, 0, 20, -2, +21, -2, 15, -4, 19, -3, 21, -6, +26, -4, 26, 1, 18, 7, 17, 6, +15, 4, 18, 3, 19, 0, 22, -1, +24, -3, 18, -4, 19, -4, 19, -1, +20, 1, 24, 1, 20, 1, 20, -4, +20, -10, 21, -6, 19, -3, 18, -2, +25, -1, 22, 2, 17, 4, 16, 4, +18, 3, 21, 0, 24, 2, 17, 1, +17, -1, 21, 1, 21, 4, 20, 4, +20, 3, 23, 3, 18, -2, 19, -2, +19, -1, 19, -4, 24, -8, 25, -5, +21, -1, 18, 1, 24, 2, 25, 2, +18, -1, 21, -3, 20, -1, 17, 1, +22, 2, 23, 0, 28, 2, 23, 4, +21, 5, 15, 4, 15, 4, 23, 2, +19, -2, 19, 0, 16, 2, 16, 0, +23, -2, 23, 1, 22, 2, 18, 1, +19, -1, 15, -1, 12, -2, 25, -3, +27, -1, 26, 4, 20, 9, 15, 5, +21, 2, 23, 0, 28, -1, 24, -3, +27, -2, 25, 0, 18, -2, 25, -2, +28, -1, 26, 0, 23, -2, 22, -6, +22, -6, 20, -2, 21, 1, 20, 2, +17, 1, 26, 1, 25, 1, 21, 3, +22, 3, 22, 0, 24, -3, 24, -4, +26, 0, 24, 4, 23, 8, 22, 6, +19, 3, 22, 0, 28, -6, 27, -8, +28, -8, 27, -8, 25, -5, 23, -3, +23, -3, 29, -3, 24, -2, 29, -3, +25, -6, 22, -3, 26, -1, 21, 2, +23, 5, 22, 7, 23, 8, 25, 4, +24, 2, 27, -1, 24, -3, 28, -6, +32, -5, 26, -3, 28, -1, 23, 2, +21, 1, 22, -3, 29, -4, 30, -3, +21, -4, 25, -5, 19, -2, 21, 0, +28, 1, 26, 7, 24, 7, 23, 2, +29, -1, 24, 1, 20, 1, 31, -1, +30, 1, 25, 5, 21, 7, 18, 4, +24, 2, 25, 1, 26, -3, 24, -6, +26, -6, 23, -2, 17, -1, 23, -1, +27, 2, 27, 2, 26, -1, 26, -1, +24, 0, 26, 1, 27, 0, 26, 3, +23, 5, 27, 6, 26, 5, 24, 6, +28, 5, 26, 0, 27, -1, 23, -4, +23, -3, 28, -4, 30, -3, 31, -2, +24, -4, 27, -5, 32, -4, 26, -4, +31, -5, 30, -4, 25, -2, 24, 2, +20, 5, 28, 5, 32, 2, 39, 3, +26, 3, 17, 0, 26, -2, 27, 0, +29, 4, 26, 3, 27, 2, 21, 1, +19, 2, 24, 0, 24, -3, 33, -7, +33, -9, 21, -6, 22, -3, 24, 0, +30, 3, 32, 4, 28, 5, 26, 4, +21, 2, 28, 2, 24, 2, 28, 3, +34, 3, 29, 4, 25, 4, 25, 3, +31, -1, 31, -3, 29, -2, 27, -4, +24, -5, 26, -2, 27, -3, 25, -3, +31, 0, 29, 1, 26, 0, 26, -4, +31, -5, 34, -4, 28, 0, 29, 3, +27, 5, 26, 10, 30, 9, 25, 9, +23, 6, 26, 3, 25, -3, 27, -6, +30, -6, 35, -5, 32, -3, 28, -3, +30, -4, 25, -6, 33, -7, 33, -6, +27, -4, 26, -2, 26, -1, 26, 4, +23, 8, 28, 10, 30, 10, 26, 6, +31, 1, 28, -2, 29, -1, 33, 0, +31, 0, 33, 3, 29, 4, 31, 1, +27, -2, 25, -5, 32, -6, 28, -6, +31, -4, 27, -2, 24, 0, 25, 0, +28, 1, 31, 3, 29, 3, 36, 3, +31, 3, 20, 2, 25, 1, 28, 2, +33, 6, 37, 7, 33, 3, 31, 2, +25, 0, 28, -3, 26, -5, 33, -6, +37, -3, 24, 0, 20, 1, 22, -1, +29, -2, 36, -3, 34, -2, 27, -1, +24, -2, 27, -2, 30, 1, 28, 3, +38, 4, 38, 6, 30, 6, 30, 3, +30, 2, 32, 2, 30, -1, 31, -2, +28, 0, 28, 3, 31, 4, 26, 1, +28, -3, 32, -7, 30, -9, 32, -10, +32, -8, 36, -5, 33, 0, 26, 6, +25, 9, 21, 8, 34, 9, 33, 9, +24, 7, 25, 3, 24, 4, 26, 5, +27, 5, 36, 6, 36, 4, 31, 2, +27, -1, 17, -2, 23, -4, 35, -5, +35, -6, 31, -5, 23, 0, 23, 3, +23, 3, 31, 2, 40, 0, 34, -2, +35, -1, 22, 2, 19, 6, 30, 10, +35, 12, 37, 8, 31, 5, 29, 5, +25, 4, 24, 0, 33, -3, 34, -6, +34, -5, 34, -2, 24, -2, 29, -3, +37, -7, 40, -9, 35, -8, 30, -7, +34, -5, 31, -2, 32, 1, 32, 5, +30, 8, 32, 11, 32, 9, 30, 3, +31, 1, 33, -1, 31, 0, 25, 1, +33, 1, 36, 2, 32, 1, 32, 0, +23, -4, 28, -7, 33, -11, 37, -10, +33, -7, 28, 0, 31, 3, 22, 3, +28, 4, 38, 1, 38, 0, 40, 1, +29, 4, 24, 4, 27, 4, 33, 4, +37, 6, 33, 9, 35, 8, 29, 1, +27, -7, 34, -11, 35, -11, 39, -7, +34, -6, 33, -5, 30, -4, 31, -3, +36, -3, 30, -2, 35, -2, 39, -2, +30, -2, 29, 2, 25, 7, 29, 9, +35, 8, 40, 4, 41, 3, 32, 2, +32, 0, 26, -4, 26, -3, 37, -3, +38, -2, 33, 0, 26, -2, 27, -4, +29, -6, 34, -7, 37, -7, 31, -3, +29, -3, 30, -1, 23, 5, 29, 7, +38, 9, 39, 9, 32, 7, 25, 3, +30, 2, 29, 2, 37, 3, 36, 3, +30, 5, 34, 5, 28, 3, 28, -3, +36, -8, 40, -14, 40, -16, 33, -13, +32, -8, 32, 0, 33, 3, 36, 4, +25, 2, 30, 2, 32, 3, 31, 4, +31, 4, 30, 6, 32, 7, 23, 10, +27, 12, 32, 7, 37, 3, 44, -3, +30, -5, 23, -7, 27, -7, 33, -5, +38, -3, 32, -3, 35, -1, 27, -2, +24, -4, 34, -5, 33, -6, 44, -5, +39, -2, 25, 3, 22, 7, 30, 9, +39, 10, 37, 9, 37, 6, 32, 1, +28, -5, 33, -7, 36, -4, 38, 1, +39, 2, 33, 0, 27, -3, 26, -5, +37, -7, 37, -9, 34, -10, 36, -9, +28, -4, 30, 0, 32, 4, 33, 7, +36, 7, 34, 8, 28, 6, 24, 2, +31, 2, 38, 4, 31, 5, 32, 5, +30, 6, 29, 6, 34, 2, 32, -2, +31, -6, 29, -10, 34, -11, 30, -10, +30, -6, 40, -3, 34, -1, 30, 0, +29, -1, 30, -1, 34, 0, 34, -1, +36, -1, 33, 3, 31, 10, 32, 15, +22, 14, 34, 8, 38, 4, 31, 3, +28, 1, 23, -2, 31, -4, 32, -4, +34, -1, 30, -1, 32, -3, 38, -5, +30, -5, 27, -8, 34, -9, 38, -9, +39, -7, 37, -1, 37, 5, 31, 9, +30, 9, 34, 7, 29, 6, 36, 5, +32, 2, 26, -1, 28, -1, 31, 2, +35, 3, 33, 1, 35, -2, 32, -4, +25, -5, 27, -9, 29, -12, 35, -10, +42, -2, 31, 4, 23, 6, 23, 6, +30, 6, 34, 2, 35, 0, 38, 1, +31, 1, 33, 3, 32, 6, 30, 8, +37, 8, 37, 8, 29, 7, 20, -1, +28, -8, 37, -11, 33, -9, 36, -8, +33, -7, 31, -3, 39, -4, 33, -6, +35, -3, 30, -2, 31, -2, 29, -2, +28, 1, 39, 6, 35, 11, 29, 16, +22, 15, 21, 9, 35, 2, 40, -3, +35, -3, 27, -3, 27, -5, 30, -4, +27, -1, 36, 0, 38, -3, 35, -7, +30, -8, 18, -6, 25, -2, 33, -1, +39, 2, 30, 6, 24, 6, 30, 6, +27, 5, 33, 3, 41, 3, 37, 2, +33, 3, 25, 4, 22, 6, 31, 7, +37, 5, 39, 1, 29, -3, 28, -6, +28, -9, 26, -9, 31, -8, 34, -6, +36, -1, 30, 4, 25, 6, 24, 3, +31, 0, 37, 0, 29, 0, 29, -1, +36, 1, 32, 7, 32, 8, 31, 7, +34, 4, 37, 4, 32, 2, 31, -3, +27, -7, 31, -6, 26, -5, 21, -5, +32, -5, 37, -3, 35, -2, 29, -2, +24, -5, 28, -7, 34, -6, 38, 0, +32, 7, 29, 10, 30, 10, 21, 9, +25, 9, 34, 3, 42, -1, 37, 1, +26, 1, 25, 0, 25, -1, 35, 2, +34, 3, 30, 1, 35, -6, 30, -10, +24, -10, 27, -9, 32, -4, 34, 0, +29, 2, 28, 6, 25, 6, 27, 3, +34, 3, 27, 2, 31, 0, 37, 1, +32, 5, 24, 7, 26, 8, 32, 7, +30, 5, 32, 3, 30, -2, 28, -8, +29, -10, 24, -9, 20, -6, 28, -1, +33, -1, 35, -3, 30, -5, 31, -4, +29, -2, 29, -2, 37, 0, 32, 3, +33, 7, 28, 12, 17, 15, 21, 13, +32, 8, 39, 1, 35, -6, 30, -9, +29, -7, 25, -6, 30, -5, 32, -4, +35, -6, 39, -6, 32, -5, 26, -5, +25, -7, 38, -7, 35, -4, 26, 0, +29, 1, 29, 2, 33, 5, 30, 7, +25, 6, 27, 4, 29, 4, 29, 3, +25, 3, 29, 3, 34, 4, 26, 3, +26, 0, 28, -4, 32, -8, 34, -8, +24, -8, 19, -7, 22, -4, 30, 1, +28, 5, 26, 5, 28, 3, 25, 1, +22, 1, 24, 1, 34, 0, 41, 0, +38, 6, 25, 11, 17, 13, 24, 10, +38, 5, 34, 1, 31, -6, 27, -13, +22, -14, 22, -10, 25, -7, 34, -3, +35, -1, 30, 1, 22, 1, 21, 0, +33, -3, 38, -6, 34, -5, 33, -3, +26, 3, 21, 10, 21, 13, 23, 12, +28, 8, 29, 2, 28, 0, 21, -2, +30, -5, 35, -5, 30, -1, 24, -2, +24, -4, 29, -6, 27, -8, 30, -10, +32, -8, 25, -2, 26, 1, 22, 3, +24, 3, 33, 2, 28, 1, 24, 2, +20, 2, 24, 2, 30, 3, 31, 5, +32, 9, 25, 11, 27, 9, 29, 3, +30, -3, 33, -8, 33, -11, 25, -11, +14, -10, 18, -10, 28, -8, 29, -1, +29, 4, 24, 6, 25, 4, 30, 3, +27, -1, 30, -3, 31, -1, 28, 5, +20, 6, 20, 7, 28, 9, 27, 10, +26, 6, 24, 1, 21, -1, 24, -5, +28, -7, 23, -7, 23, -6, 25, -5, +28, -3, 25, -3, 29, -4, 32, -4, +29, -4, 28, -4, 24, -1, 26, 4, +27, 7, 25, 8, 19, 3, 17, 1, +23, 3, 24, 1, 29, 0, 32, 2, +29, 4, 30, 4, 25, 5, 22, 4, +28, -1, 30, -7, 27, -10, 16, -8, +16, -7, 20, -6, 21, -2, 23, 0, +22, 2, 25, 3, 27, 1, 30, 0, +30, 1, 30, 3, 30, 4, 21, 7, +18, 7, 24, 7, 26, 6, 25, 4, +20, 0, 22, -6, 26, -11, 27, -10, +25, -7, 18, -5, 23, -3, 21, -1, +17, 3, 23, 0, 32, -5, 33, -6, +26, -4, 22, -4, 25, -2, 29, 7, +28, 12, 22, 13, 16, 11, 15, 8, +12, 2, 15, -1, 22, -3, 28, -5, +28, -6, 27, -5, 28, -2, 29, 1, +33, 2, 31, 0, 23, -3, 20, -5, +17, -6, 14, -6, 16, -5, 18, -3, +21, 0, 17, 4, 18, 5, 25, 6, +29, 8, 32, 13, 19, 15, 16, 14, +17, 9, 16, 5, 16, -1, 15, -5, +18, -5, 17, -5, 20, -4, 24, -4, +24, -2, 24, 0, 18, 1, 15, 2, +18, 1, 24, -3, 29, -7, 21, -7, +19, -4, 19, 0, 25, 5, 33, 10, +29, 16, 27, 18, 17, 14, 8, 6, +8, -4, 16, -12, 24, -18, 23, -17, +17, -10, 16, 1, 19, 8, 27, 12, +32, 14, 26, 14, 22, 7, 18, -4, +15, -8, 11, -9, 19, -12, 23, -11, +17, -4, 11, 5, 12, 9, 22, 9, +28, 11, 28, 12, 25, 10, 26, 2, +25, -5, 22, -12, 23, -17, 25, -14, +19, -8, 16, -3, 18, 0, 21, 2, +26, 3, 20, 2, 16, 1, 17, -4, +24, -8, 27, -12, 26, -12, 25, -7, +20, 1, 15, 7, 20, 12, 24, 16, +27, 14, 26, 11, 17, 5, 12, -3, +14, -10, 19, -13, 16, -18, 16, -16, +15, -12, 16, -4, 23, 4, 27, 11, +33, 12, 32, 8, 23, 6, 13, 0, +9, -4, 19, -8, 21, -5, 14, 1, +10, 4, 8, 3, 13, 3, 14, 4, +17, 4, 23, 1, 24, -1, 25, -2, +20, -3, 22, -3, 22, -3, 20, -2, +15, -2, 15, 1, 18, 1, 17, -1, +19, -4, 18, -6, 17, -5, 18, -3, +15, 0, 14, 1, 18, 4, 14, 9, +11, 12, 13, 9, 24, 3, 32, -3, +29, -3, 20, -1, 11, 1, 11, 2, +13, -1, 13, -4, 13, -9, 13, -7, +7, -3, 6, 0, 15, 1, 28, 1, +31, 2, 28, 2, 22, 0, 20, -2, +24, 1, 20, 6, 12, 12, 5, 12, +3, 8, 4, 2, 6, -4, 12, -10, +19, -15, 22, -14, 20, -9, 17, -2, +22, 5, 24, 12, 16, 15, 12, 11, +10, 4, 14, -1, 15, -4, 14, -1, +12, 0, 11, 1, 13, 1, 11, 1, +12, 6, 12, 6, 15, 4, 12, 2, +10, 2, 16, 0, 22, -2, 24, -3, +21, -3, 18, -5, 20, -4, 19, 1, +16, 6, 12, 8, 7, 4, 2, -1, +-7, -4, -2, -5, 8, -6, 19, -2, +24, 2, 24, 7, 23, 13, 20, 16, +21, 14, 20, 8, 16, 6, 7, 1, +0, -2, -3, -6, 1, -10, 9, -14, +13, -15, 12, -11, 13, -5, 19, 0, +27, 4, 30, 8, 26, 7, 21, 3, +14, -1, 8, -3, 9, -4, 13, 0, +12, 4, 11, 7, 9, 9, 11, 7, +16, 2, 18, -5, 16, -9, 8, -11, +10, -11, 10, -9, 11, -1, 15, 4, +18, 4, 19, 5, 16, 6, 17, 4, +21, 4, 21, 3, 14, -3, 7, -10, +3, -14, 3, -14, 3, -11, 8, 0, +10, 9, 14, 16, 16, 19, 21, 15, +28, 9, 28, 4, 25, 0, 10, -7, +4, -10, 1, -9, -1, -7, -3, -6, +-4, -7, -1, -6, 6, -6, 15, -5, +22, 0, 27, 5, 29, 6, 29, 5, +20, 6, 12, 9, 8, 8, 6, 9, +-2, 10, -5, 12, -4, 10, 5, 4, +14, -5, 18, -15, 21, -19, 18, -20, +16, -16, 12, -9, 13, 1, 14, 5, +13, 6, 9, 5, 7, 3, 11, 3, +16, 4, 18, 4, 14, 3, 13, 4, +9, 2, 2, 3, -3, 1, -4, -1, +0, -3, 6, -3, 9, 0, 18, 0, +27, 0, 32, 2, 28, 3, 19, 3, +15, 4, 8, 2, 2, 0, -9, -3, +-11, -10, -9, -19, 0, -25, 11, -24, +19, -16, 24, -1, 24, 14, 23, 26, +22, 30, 22, 28, 18, 19, 8, 9, +-2, -4, -4, -10, -2, -13, 4, -10, +7, -7, 7, -8, 6, -7, 7, -8, +10, -3, 13, 1, 17, 5, 13, 3, +9, 0, 6, -6, 9, -10, 14, -9, +20, -5, 21, 3, 13, 14, 5, 22, +-1, 23, 0, 18, 3, 7, 1, -5, +-3, -19, 0, -26, 7, -24, 16, -16, +26, -6, 31, 4, 28, 13, 19, 16, +13, 13, 9, 8, 5, 5, -2, -1, +-10, -9, -16, -19, -7, -26, 4, -27, +11, -18, 14, -5, 15, 9, 20, 25, +20, 33, 21, 33, 20, 24, 15, 13, +6, 0, -1, -10, -3, -15, 0, -13, +4, -10, 2, -7, -3, -6, -3, -7, +3, -7, 11, -8, 15, -6, 15, -3, +14, 2, 8, 5, 9, 5, 12, 2, +18, 2, 18, 4, 9, 9, 0, 15, +-5, 16, 0, 14, 3, 6, 3, -6, +1, -19, 4, -24, 6, -22, 9, -13, +16, -4, 19, 6, 18, 14, 14, 12, +9, 6, 11, 0, 14, -4, 10, -5, +3, -4, -7, -3, -7, -4, -7, -9, +-4, -11, -1, -11, 4, -7, 13, 0, +19, 10, 24, 18, 24, 20, 26, 21, +18, 14, 10, 9, 2, 1, -4, -3, +-8, -8, -13, -12, -16, -15, -11, -19, +1, -23, 13, -23, 17, -14, 17, -3, +18, 8, 17, 17, 16, 23, 12, 19, +10, 11, 3, 2, -3, -3, -6, -3, +-1, -2, 7, 3, 8, 6, 8, 4, +4, -3, 6, -11, 7, -18, 11, -19, +8, -13, 1, -4, 1, -1, 7, 0, +15, 3, 19, 4, 21, 5, 17, 6, +8, 10, -1, 11, -8, 10, -13, 1, +-15, -9, -20, -18, -15, -24, -4, -21, +13, -8, 26, 10, 33, 24, 34, 33, +28, 32, 22, 25, 8, 11, -3, -2, +-15, -14, -24, -22, -27, -27, -20, -28, +-6, -26, 12, -21, 24, -12, 23, -2, +21, 9, 23, 14, 22, 20, 15, 19, +2, 17, -11, 9, -17, 1, -15, -4, +-6, -1, 2, 7, 8, 11, 12, 13, +7, 7, 3, 0, 1, -12, 1, -18, +-5, -21, -10, -18, -7, -11, 3, 0, +14, 9, 22, 13, 25, 15, 22, 12, +17, 6, 8, 3, -1, 2, -8, -4, +-14, -11, -21, -18, -26, -20, -18, -18, +2, -11, 20, 3, 30, 18, 30, 29, +29, 32, 25, 27, 14, 15, 5, 1, +-8, -11, -18, -17, -28, -19, -27, -18, +-14, -18, 4, -18, 19, -17, 18, -13, +16, -5, 14, 3, 12, 13, 10, 19, +6, 23, 0, 22, -6, 18, -8, 9, +-2, -1, 5, -5, 12, -7, 10, -5, +2, -2, -5, -3, -8, -9, -4, -14, +-7, -14, -6, -10, -1, -5, 11, 4, +18, 11, 19, 14, 21, 9, 16, 3, +10, -2, 3, -6, -4, -2, -12, 4, +-21, 8, -23, 4, -19, -1, -9, -10, +7, -18, 21, -21, 26, -12, 23, 4, +17, 19, 13, 29, 7, 30, 2, 23, +-6, 11, -12, 1, -17, -9, -8, -18, +-1, -22, 5, -23, 7, -26, 4, -28, +3, -22, 0, -11, 3, 5, 4, 21, +4, 36, 2, 39, 4, 34, 8, 21, +11, 5, 10, -11, 7, -19, 1, -20, +-6, -14, -14, -3, -19, 3, -19, 5, +-13, 1, -5, -3, 3, -6, 18, -5, +26, -4, 29, 1, 21, 4, 10, 4, +6, 2, -1, 3, -10, 7, -20, 9, +-23, 12, -22, 9, -13, 0, -1, -14, +11, -24, 18, -27, 13, -18, 7, -2, +7, 14, 11, 30, 14, 38, 7, 36, +-3, 24, -8, 6, -7, -14, 2, -27, +3, -33, 4, -31, -1, -27, -7, -20, +-10, -12, -9, -3, 0, 6, 7, 11, +12, 17, 10, 21, 12, 23, 17, 14, +21, 4, 16, -7, 4, -12, -6, -10, +-15, -5, -19, 4, -17, 9, -11, 7, +-3, -3, 0, -12, 4, -20, 12, -21, +19, -16, 20, -4, 11, 10, 3, 22, +-3, 25, -5, 19, -3, 11, -6, 4, +-8, -1, -8, -9, -2, -15, -1, -18, +1, -20, 2, -21, 0, -14, -3, -1, +-4, 16, 6, 31, 13, 39, 14, 37, +13, 23, 12, 3, 12, -17, 11, -29, +3, -34, -8, -27, -21, -18, -27, -7, +-30, 1, -21, 2, -4, 1, 9, -1, +18, 2, 23, 6, 29, 14, 28, 19, +25, 19, 11, 15, -9, 10, -26, 2, +-31, -6, -24, -9, -16, -7, -6, -5, +5, -8, 14, -13, 19, -16, 23, -17, +22, -14, 16, -3, 3, 5, -6, 12, +-13, 17, -14, 15, -10, 6, -2, -5, +5, -9, 8, -7, 11, -2, 8, 1, +6, 3, -4, 1, -12, -3, -18, -6, +-19, -4, -14, 1, -1, 9, 12, 16, +21, 19, 29, 20, 28, 14, 24, 7, +13, -4, -8, -11, -24, -17, -33, -23, +-32, -27, -25, -30, -16, -29, 0, -24, +15, -11, 27, 10, 34, 32, 35, 48, +32, 56, 13, 47, -6, 26, -20, -3, +-24, -27, -23, -41, -22, -42, -15, -32, +-5, -17, 9, 0, 19, 12, 24, 18, +22, 16, 15, 12, 6, 4, -4, -3, +-8, -9, -5, -13, -4, -16, -5, -15, +-6, -11, 0, -3, 8, 13, 8, 25, +5, 30, -4, 23, -6, 11, -12, -7, +-10, -22, -4, -31, 5, -28, 11, -10, +7, 13, 6, 32, 10, 36, 17, 31, +14, 20, -1, 5, -13, -12, -17, -25, +-18, -35, -15, -37, -14, -34, -8, -27, +-2, -14, 5, 3, 12, 25, 18, 42, +21, 55, 13, 54, 5, 41, -2, 17, +0, -10, -2, -32, -5, -40, -13, -35, +-19, -23, -12, -10, -4, 1, 0, 9, +2, 8, 7, 1, 9, -3, 12, -1, +17, 1, 20, 5, 17, 7, 6, 6, +-8, 3, -16, -5, -14, -8, -12, -5, +-15, 2, -16, 6, -11, 9, -5, 8, +9, 6, 17, 2, 24, 2, 19, 5, +7, 11, 0, 11, -4, 7, -2, 2, +-7, -6, -8, -14, -12, -20, -9, -18, +-2, -13, 7, -3, 11, 2, 8, 4, +6, -2, 2, -9, -2, -9, -5, -6, +-6, 5, -1, 16, 3, 27, 5, 30, +12, 30, 11, 25, 8, 15, 0, 1, +-4, -13, -7, -21, -14, -26, -17, -30, +-20, -33, -17, -27, -7, -19, 8, -2, +20, 18, 26, 36, 28, 45, 22, 45, +10, 29, -1, 5, -10, -21, -15, -42, +-22, -46, -26, -36, -24, -15, -11, 7, +6, 27, 16, 36, 21, 35, 22, 27, +21, 15, 15, 2, 9, -10, 3, -19, +-7, -24, -15, -27, -21, -28, -14, -20, +-5, -8, 5, 8, 7, 19, 6, 22, +6, 14, 5, 3, 4, -10, 1, -18, +-1, -15, -4, 0, -7, 20, -8, 33, +-3, 38, 5, 32, 8, 21, 6, 3, +4, -13, 2, -25, 1, -30, -5, -29, +-12, -25, -15, -16, -12, -11, 1, -4, +5, 7, 9, 20, 10, 27, 10, 30, +12, 23, 11, 11, 8, -2, 0, -16, +-9, -22, -18, -15, -24, -2, -18, 11, +-10, 21, -5, 20, -2, 12, 2, 1, +9, -5, 13, -6, 17, -1, 13, 7, +6, 13, -3, 15, -13, 12, -16, 6, +-17, -5, -11, -13, -12, -20, -13, -19, +-9, -18, 1, -12, 12, -6, 16, 3, +16, 15, 10, 27, 5, 37, 2, 40, +-2, 39, -5, 21, -5, -1, -5, -24, +-7, -38, -9, -41, -5, -32, -4, -14, +-5, 6, -5, 20, -2, 26, 2, 23, +3, 12, 4, 2, 0, -7, 2, -9, +3, -7, 1, -1, -3, 3, -5, 7, +-8, 12, -13, 17, -10, 21, -7, 21, +-3, 21, -3, 11, -5, -3, -4, -20, +2, -32, 10, -33, 12, -20, 6, 1, +1, 24, -5, 41, -7, 44, -7, 37, +-9, 18, -8, -7, -9, -32, -7, -43, +-11, -39, -5, -28, 1, -13, 4, 5, +2, 22, -4, 35, -1, 44, 1, 47, +3, 45, 1, 32, -2, 14, -2, -11, +-4, -30, -6, -39, -9, -35, -13, -24, +-15, -6, -19, 11, -16, 22, -8, 27, +-1, 21, 6, 10, 8, -1, 14, -6, +16, -7, 17, -2, 6, 6, -7, 13, +-19, 11, -26, 7, -25, 7, -26, 6, +-17, 9, -6, 10, 2, 9, 9, 2, +20, -3, 24, -10, 18, -11, 7, -8, +-7, 0, -17, 11, -22, 19, -24, 21, +-23, 14, -17, 4, -7, -9, 5, -16, +12, -13, 14, -2, 8, 5, 3, 8, +-11, 10, -22, 12, -26, 12, -23, 12, +-15, 16, -8, 18, 6, 21, 14, 21, +20, 15, 21, 1, 14, -10, -1, -17, +-20, -20, -31, -19, -39, -14, -35, -5, +-23, 1, -13, 8, 0, 11, 16, 13, +30, 15, 38, 20, 30, 23, 14, 23, +-10, 15, -29, 4, -43, -7, -51, -13, +-43, -11, -32, -4, -12, 7, 5, 14, +21, 20, 31, 19, 29, 15, 20, 5, +3, 1, -14, 1, -27, 4, -36, 6, +-38, 4, -30, -2, -17, -11, -3, -10, +9, -10, 17, -4, 18, 6, 13, 17, +-3, 24, -13, 23, -19, 16, -20, 8, +-20, 4, -22, 5, -17, 7, -6, 9, +10, 9, 16, 4, 14, 0, 3, -5, +-8, -5, -17, -3, -22, 3, -23, 7, +-24, 6, -21, 2, -18, -5, -10, -11, +5, -14, 18, -6, 19, 9, 10, 25, +0, 34, -6, 38, -14, 33, -19, 20, +-24, 4, -27, -11, -27, -18, -25, -20, +-17, -15, -6, -11, 10, -5, 13, 3, +13, 14, 7, 26, -1, 36, -4, 37, +-13, 29, -18, 13, -22, -10, -23, -27, +-24, -36, -27, -34, -21, -24, -11, -3, +-2, 21, 2, 44, 0, 52, 3, 47, +1, 36, -2, 20, -8, 6, -13, -3, +-17, -10, -24, -17, -26, -17, -30, -16, +-22, -13, -8, -6, 1, 8, 7, 22, +7, 33, 2, 37, -9, 31, -20, 14, +-25, -8, -24, -26, -23, -33, -23, -24, +-21, -5, -11, 19, 2, 38, 11, 51, +9, 53, -1, 45, -15, 30, -29, 8, +-36, -11, -38, -26, -36, -35, -34, -36, +-27, -28, -15, -10, 6, 15, 21, 44, +23, 67, 13, 72, 0, 58, -14, 30, +-32, -7, -45, -39, -53, -62, -49, -63, +-39, -42, -27, -8, -10, 24, 9, 54, +19, 75, 19, 79, 16, 66, 9, 44, +-9, 18, -31, -13, -48, -37, -58, -55, +-52, -56, -41, -45, -25, -21, -12, 12, +5, 46, 17, 71, 19, 79, 15, 66, +0, 33, -19, -5, -44, -38, -59, -55, +-59, -55, -43, -34, -19, 2, -4, 41, +8, 68, 14, 80, 11, 73, 5, 49, +-8, 18, -29, -15, -50, -43, -62, -62, +-58, -65, -43, -50, -14, -18, 10, 22, +27, 61, 33, 88, 21, 97, 2, 78, +-21, 35, -43, -15, -64, -61, -70, -85, +-64, -81, -47, -50, -23, -5, 3, 44, +21, 82, 29, 101, 22, 98, 3, 72, +-20, 35, -42, -5, -57, -38, -64, -61, +-60, -66, -45, -56, -21, -30, -4, 9, +6, 53, 4, 84, 1, 91, -6, 71, +-15, 33, -25, -12, -36, -53, -40, -76, +-43, -72, -30, -40, -16, 5, -1, 57, +0, 94, -11, 106, -17, 92, -22, 55, +-30, 9, -43, -36, -54, -70, -52, -87, +-39, -76, -19, -43, -4, 5, 6, 53, +12, 89, 4, 110, -8, 109, -24, 78, +-39, 28, -56, -33, -70, -85, -65, -106, +-55, -92, -34, -49, -14, 10, 4, 74, +15, 120, 16, 136, 4, 117, -20, 67, +-40, 4, -57, -52, -69, -85, -67, -94, +-51, -76, -30, -34, -8, 19, 6, 68, +11, 104, 3, 113, -13, 95, -40, 55, +-62, 0, -69, -54, -70, -90, -59, -101, +-35, -82, -5, -25, 14, 46, 26, 111, +20, 148, -2, 147, -30, 105, -58, 38, +-84, -36, -97, -97, -89, -125, -65, -117, +-30, -71, 6, -5, 31, 64, 40, 113, +32, 138, 8, 128, -25, 89, -59, 30, +-87, -33, -102, -84, -96, -110, -73, -100, +-41, -61, -8, 1, 15, 64, 27, 116, +22, 140, 3, 128, -26, 81, -51, 13, +-71, -53, -84, -93, -82, -98, -66, -73, +-38, -22, -10, 35, 11, 85, 17, 110, +2, 106, -24, 76, -52, 33, -72, -14, +-76, -51, -77, -71, -69, -70, -48, -49, +-18, -13, 10, 36, 20, 78, 18, 103, +-3, 104, -30, 85, -60, 49, -82, 3, +-89, -46, -83, -79, -66, -85, -42, -62, +-9, -17, 12, 30, 16, 68, 6, 85, +-12, 87, -36, 69, -56, 38, -75, 2, +-81, -28, -72, -44, -53, -42, -31, -29, +-14, -9, -6, 17, -14, 41, -31, 67, +-51, 80, -62, 74, -68, 50, -69, 17, +-64, -14, -47, -35, -25, -40, -10, -26, +-7, 1, -12, 33, -22, 59, -43, 69, +-66, 59, -84, 31, -85, 3, -75, -19, +-56, -30, -33, -29, -16, -16, -4, 5, +-2, 29, -10, 50, -25, 62, -48, 64, +-77, 53, -95, 38, -98, 18, -81, -1, +-55, -20, -29, -27, -13, -19, -4, 0, +-3, 26, -18, 45, -36, 51, -57, 44, +-77, 31, -91, 10, -90, -10, -75, -21, +-52, -13, -24, 7, 0, 31, 12, 51, +7, 57, -20, 50, -56, 32, -87, 12, +-109, -7, -113, -20, -102, -24, -74, -11, +-45, 11, -11, 32, 17, 46, 28, 54, +21, 61, -11, 59, -55, 47, -101, 22, +-127, -10, -130, -37, -112, -46, -81, -38, +-45, -14, -13, 15, 12, 46, 20, 71, +11, 84, -15, 76, -53, 46, -89, 11, +-113, -17, -113, -26, -97, -23, -70, -10, +-44, 6, -19, 25, -5, 42, -4, 53, +-18, 50, -41, 36, -64, 19, -84, 3, +-95, -7, -92, -17, -72, -23, -53, -17, +-35, 9, -23, 38, -11, 64, -13, 75, +-34, 69, -60, 49, -82, 19, -94, -9, +-99, -34, -94, -41, -81, -28, -58, -1, +-36, 31, -19, 58, -11, 67, -13, 67, +-30, 58, -52, 40, -71, 16, -86, -7, +-95, -21, -100, -28, -85, -18, -64, -4, +-42, 15, -31, 33, -30, 50, -37, 60, +-43, 59, -52, 41, -66, 15, -79, -6, +-88, -14, -84, -6, -69, 7, -46, 27, +-33, 47, -34, 63, -50, 63, -63, 45, +-74, 15, -82, -13, -90, -27, -93, -24, +-78, -9, -60, 11, -40, 32, -28, 45, +-23, 56, -29, 57, -41, 50, -60, 35, +-85, 22, -103, 11, -108, -4, -100, -12, +-81, -12, -59, 1, -44, 18, -35, 35, +-35, 45, -41, 48, -55, 41, -67, 30, +-76, 19, -80, 15, -77, 15, -73, 20, +-68, 28, -62, 29, -56, 25, -59, 12, +-67, -3, -76, -12, -80, -7, -79, 9, +-71, 30, -64, 49, -55, 61, -48, 62, +-50, 51, -53, 29, -61, 3, -67, -14, +-75, -21, -76, -8, -76, 15, -78, 38, +-80, 51, -80, 57, -81, 56, -75, 42, +-68, 19, -67, -6, -66, -23, -61, -28, +-51, -16, -45, 7, -39, 36, -44, 61, +-56, 79, -78, 83, -101, 65, -111, 28, +-111, -14, -101, -43, -86, -50, -65, -29, +-49, 4, -37, 40, -32, 66, -35, 83, +-45, 78, -61, 54, -82, 21, -99, -7, +-110, -15, -106, -9, -92, 5, -79, 20, +-68, 30, -65, 32, -62, 31, -62, 23, +-55, 10, -49, 2, -54, 9, -69, 23, +-81, 40, -82, 51, -83, 53, -85, 49, +-92, 41, -96, 29, -91, 8, -76, -12, +-62, -22, -53, -13, -52, 8, -56, 28, +-61, 43, -69, 51, -83, 51, -100, 39, +-105, 18, -97, -5, -75, -16, -55, -11, +-43, 14, -46, 46, -55, 67, -68, 70, +-85, 56, -104, 31, -119, 1, -121, -23, +-111, -35, -87, -22, -61, 10, -39, 47, +-29, 74, -33, 83, -48, 70, -69, 44, +-93, 13, -115, -10, -125, -22, -119, -20, +-104, -3, -86, 22, -69, 47, -59, 57, +-50, 53, -50, 37, -56, 18, -68, -1, +-80, -11, -91, -7, -97, 8, -87, 33, +-79, 59, -76, 76, -81, 70, -84, 49, +-85, 17, -86, -12, -86, -32, -85, -35, +-80, -21, -75, 12, -76, 52, -77, 81, +-76, 85, -75, 62, -74, 29, -79, -5, +-79, -25, -83, -27, -86, -8, -87, 21, +-85, 56, -84, 80, -87, 79, -90, 53, +-90, 13, -82, -21, -78, -38, -72, -35, +-68, -16, -68, 23, -77, 65, -88, 98, +-98, 108, -101, 89, -97, 47, -92, -4, +-85, -40, -80, -56, -75, -47, -74, -21, +-76, 19, -86, 64, -98, 98, -108, 104, +-107, 82, -98, 42, -83, 1, -68, -26, +-58, -34, -50, -23, -50, 8, -64, 48, +-95, 77, -122, 84, -138, 62, -134, 25, +-117, -14, -93, -40, -65, -47, -43, -29, +-30, 10, -30, 53, -44, 92, -73, 108, +-111, 96, -143, 55, -153, 8, -143, -30, +-115, -47, -84, -42, -58, -16, -42, 21, +-35, 57, -42, 87, -67, 97, -90, 77, +-112, 38, -122, -1, -126, -30, -119, -41, +-104, -33, -84, -9, -62, 27, -48, 64, +-49, 90, -64, 92, -86, 73, -103, 39, +-107, 2, -106, -28, -105, -41, -110, -37, +-107, -14, -100, 19, -85, 54, -70, 79, +-65, 90, -65, 85, -70, 64, -71, 41, +-77, 17, -88, -6, -104, -27, -116, -37, +-122, -30, -120, -12, -113, 13, -102, 40, +-90, 66, -71, 85, -52, 94, -49, 85, +-59, 56, -75, 15, -91, -21, -105, -45, +-111, -47, -116, -29, -119, 6, -116, 47, +-107, 88, -95, 114, -82, 107, -68, 70, +-64, 16, -63, -33, -68, -66, -74, -75, +-85, -57, -93, -10, -99, 50, -101, 108, +-104, 144, -110, 138, -107, 95, -95, 27, +-79, -43, -69, -96, -63, -117, -67, -98, +-80, -37, -98, 49, -113, 132, -118, 178, +-110, 179, -99, 136, -87, 62, -72, -22, +-63, -93, -62, -129, -74, -119, -86, -64, +-110, 19, -134, 105, -150, 159, -144, 170, +-115, 141, -79, 82, -50, 6, -34, -69, +-32, -112, -49, -109, -78, -62, -106, 6, +-127, 79, -146, 132, -148, 155, -127, 138, +-91, 91, -62, 28, -47, -40, -47, -90, +-63, -104, -89, -76, -120, -21, -138, 40, +-135, 91, -108, 128, -78, 141, -53, 123, +-40, 74, -47, 12, -68, -39, -99, -67, +-135, -66, -164, -46, -171, -15, -152, 22, +-105, 63, -50, 92, -5, 101, 11, 87, +-6, 63, -47, 36, -98, 11, -146, -13, +-183, -30, -195, -31, -178, -20, -127, 4, +-66, 28, -12, 49, 12, 59, 2, 63, +-37, 61, -83, 50, -129, 30, -166, 6, +-182, -11, -171, -17, -127, -7, -74, 7, +-29, 26, -13, 46, -20, 64, -47, 76, +-87, 76, -126, 57, -152, 28, -163, 1, +-155, -20, -129, -32, -96, -36, -62, -22, +-43, 8, -36, 51, -43, 92, -54, 113, +-76, 104, -99, 76, -120, 36, -131, -7, +-129, -44, -125, -67, -119, -65, -115, -33, +-102, 19, -85, 70, -63, 106, -45, 118, +-35, 108, -38, 77, -51, 32, -78, -17, +-110, -58, -138, -73, -161, -59, -164, -19, +-148, 28, -113, 74, -77, 107, -42, 121, +-18, 107, -12, 66, -29, 7, -65, -48, +-108, -76, -145, -71, -161, -38, -158, 9, +-134, 60, -101, 105, -66, 132, -45, 129, +-35, 92, -42, 32, -63, -26, -90, -67, +-115, -83, -130, -72, -136, -42, -130, 8, +-113, 65, -86, 117, -61, 146, -49, 141, +-50, 100, -57, 43, -72, -15, -92, -62, +-111, -92, -123, -95, -125, -63, -122, -2, +-110, 67, -97, 117, -77, 138, -60, 127, +-47, 94, -40, 44, -46, -10, -68, -57, +-98, -80, -127, -67, -144, -27, -145, 25, +-137, 71, -123, 103, -98, 116, -63, 111, +-33, 82, -15, 31, -23, -27, -53, -69, +-97, -83, -137, -62, -156, -14, -155, 38, +-130, 91, -102, 131, -71, 144, -42, 116, +-22, 60, -30, -8, -60, -59, -97, -85, +-131, -82, -153, -50, -157, -2, -135, 55, +-92, 105, -45, 136, -14, 131, -6, 94, +-26, 41, -68, -8, -121, -47, -158, -72, +-169, -77, -156, -51, -125, 3, -83, 67, +-34, 119, 1, 136, 9, 121, -22, 79, +-75, 24, -132, -36, -170, -80, -186, -89, +-173, -59, -130, 1, -71, 68, -15, 118, +18, 134, 21, 121, -16, 85, -72, 34, +-134, -26, -178, -71, -196, -91, -186, -74, +-146, -26, -87, 34, -23, 89, 22, 128, +31, 143, 5, 126, -43, 80, -106, 15, +-159, -51, -192, -94, -190, -95, -163, -61, +-116, -5, -64, 58, -21, 109, 8, 134, +13, 124, -9, 85, -52, 27, -101, -27, +-146, -59, -171, -58, -171, -34, -143, 3, +-105, 40, -64, 70, -29, 86, -8, 81, +-6, 57, -25, 23, -56, -7, -95, -20, +-130, -16, -158, -8, -161, 5, -142, 23, +-105, 47, -62, 65, -23, 68, 1, 54, +-1, 29, -25, 6, -65, -6, -105, -6, +-138, -1, -158, 11, -162, 25, -141, 37, +-97, 36, -45, 27, -7, 15, 11, 6, +4, 11, -27, 27, -70, 44, -116, 50, +-146, 45, -158, 30, -148, 11, -123, -7, +-80, -21, -36, -19, -8, 2, -7, 37, +-26, 68, -58, 80, -95, 67, -124, 41, +-143, 14, -136, -7, -112, -21, -79, -21, +-48, -8, -27, 19, -22, 49, -36, 71, +-63, 74, -93, 57, -114, 30, -126, 2, +-121, -23, -104, -42, -74, -39, -50, -13, +-39, 35, -41, 83, -47, 114, -63, 114, +-85, 82, -103, 29, -114, -31, -106, -77, +-89, -92, -70, -62, -58, 0, -54, 75, +-65, 132, -80, 144, -88, 110, -86, 47, +-81, -24, -75, -77, -67, -95, -60, -70, +-55, -6, -60, 71, -71, 131, -83, 147, +-89, 117, -99, 56, -104, -16, -99, -77, +-82, -109, -58, -102, -39, -53, -31, 33, +-42, 122, -60, 178, -80, 180, -92, 130, +-100, 42, -100, -55, -94, -137, -79, -171, +-64, -138, -53, -47, -47, 75, -51, 184, +-63, 240, -81, 217, -95, 127, -102, -1, +-95, -119, -77, -195, -54, -198, -40, -123, +-36, 8, -43, 143, -59, 232, -76, 247, +-95, 185, -106, 69, -110, -62, -101, -162, +-85, -205, -57, -172, -33, -75, -21, 53, +-21, 167, -34, 229, -56, 220, -85, 150, +-111, 44, -126, -69, -117, -150, -96, -174, +-71, -130, -47, -37, -25, 77, -20, 169, +-28, 203, -47, 168, -71, 82, -99, -20, +-120, -105, -121, -145, -101, -126, -61, -48, +-28, 58, -11, 151, -13, 190, -30, 159, +-61, 74, -95, -29, -119, -110, -127, -145, +-115, -119, -91, -42, -58, 61, -24, 149, +1, 190, 3, 165, -11, 87, -45, -13, +-87, -94, -131, -134, -150, -122, -135, -63, +-100, 26, -57, 113, -27, 165, -8, 166, +-2, 112, -9, 29, -34, -57, -66, -115, +-99, -129, -121, -92, -125, -15, -108, 78, +-76, 155, -46, 186, -25, 158, -21, 76, +-27, -23, -43, -108, -62, -143, -81, -121, +-91, -50, -94, 47, -91, 136, -85, 180, +-73, 161, -54, 85, -35, -16, -21, -96, +-22, -128, -32, -101, -54, -29, -75, 59, +-91, 128, -94, 152, -90, 122, -84, 50, +-74, -33, -61, -94, -41, -112, -26, -81, +-17, -13, -21, 65, -30, 128, -49, 154, +-76, 134, -103, 69, -116, -16, -116, -91, +-100, -130, -71, -117, -41, -53, -13, 40, +3, 125, 4, 178, -13, 176, -42, 116, +-81, 14, -111, -93, -126, -163, -118, -166, +-92, -100, -63, 15, -29, 134, -5, 210, +6, 221, -5, 158, -29, 41, -61, -85, +-91, -176, -114, -198, -120, -139, -110, -25, +-86, 98, -51, 187, -15, 217, 11, 183, +13, 95, -6, -16, -43, -112, -81, -161, +-109, -151, -119, -85, -117, 12, -96, 106, +-60, 166, -23, 174, 4, 130, 11, 50, +-1, -41, -28, -113, -62, -136, -94, -101, +-113, -23, -113, 67, -92, 137, -64, 161, +-35, 126, -13, 48, -8, -41, -16, -110, +-29, -130, -41, -88, -58, -4, -73, 87, +-87, 146, -87, 153, -77, 106, -60, 24, +-46, -60, -35, -111, -29, -111, -29, -63, +-29, 16, -39, 92, -54, 138, -72, 136, +-82, 88, -79, 13, -67, -60, -51, -106, +-39, -108, -31, -62, -27, 10, -30, 86, +-41, 137, -56, 145, -71, 107, -78, 37, +-81, -39, -71, -96, -54, -117, -26, -92, +-9, -30, -9, 49, -21, 117, -45, 146, +-69, 128, -89, 66, -92, -15, -79, -86, +-59, -120, -41, -104, -24, -43, -9, 42, +-4, 120, -18, 157, -46, 138, -72, 70, +-89, -21, -90, -98, -76, -134, -54, -114, +-35, -45, -20, 47, -15, 130, -18, 168, +-29, 144, -45, 73, -60, -19, -67, -100, +-66, -139, -64, -124, -58, -60, -47, 29, +-34, 111, -30, 156, -28, 148, -34, 96, +-43, 18, -52, -63, -54, -119, -55, -126, +-56, -83, -54, -6, -55, 80, -54, 148, +-53, 171, -49, 142, -46, 63, -42, -40, +-36, -128, -28, -163, -29, -131, -37, -46, +-49, 59, -60, 148, -68, 188, -75, 165, +-73, 83, -62, -26, -34, -115, -6, -155, +12, -135, 7, -65, -16, 30, -49, 116, +-82, 164, -103, 161, -105, 103, -85, 17, +-56, -63, -26, -109, 0, -120, 20, -91, +17, -27, -7, 49, -41, 110, -73, 134, +-98, 114, -109, 63, -95, -1, -66, -58, +-27, -87, 2, -83, 18, -46, 10, 9, +-16, 62, -52, 93, -77, 94, -91, 70, +-94, 29, -83, -19, -56, -53, -18, -55, +10, -28, 20, 13, 7, 48, -21, 64, +-60, 56, -96, 32, -117, -6, -104, -42, +-64, -54, -18, -34, 18, 7, 29, 51, +15, 85, -19, 91, -51, 65, -82, 20, +-103, -30, -110, -66, -95, -72, -61, -48, +-17, -5, 24, 41, 41, 78, 32, 92, +-3, 83, -50, 54, -96, 11, -116, -34, +-117, -64, -95, -73, -57, -60, -11, -25, +24, 25, 37, 74, 28, 102, 0, 96, +-35, 64, -73, 14, -98, -38, -106, -78, +-93, -85, -63, -62, -23, -16, 8, 33, +21, 66, 18, 78, 4, 71, -22, 52, +-52, 23, -69, -6, -77, -24, -75, -33, +-70, -37, -61, -39, -48, -33, -26, -17, +-6, 11, 8, 50, 11, 84, 0, 100, +-21, 90, -52, 54, -79, -2, -98, -65, +-99, -109, -85, -114, -54, -74, -16, 1, +15, 85, 26, 145, 20, 159, -2, 122, +-37, 43, -63, -51, -79, -125, -81, -150, +-79, -124, -66, -55, -48, 34, -23, 114, +-3, 162, 8, 161, 10, 111, -1, 29, +-24, -57, -62, -122, -92, -151, -102, -133, +-81, -68, -42, 23, 1, 116, 26, 175, +25, 180, 0, 129, -39, 36, -73, -72, +-86, -160, -71, -191, -46, -149, -19, -48, +-7, 71, -6, 165, -17, 198, -33, 163, +-51, 78, -60, -27, -58, -115, -48, -154, +-33, -135, -18, -69, -4, 16, -5, 86, +-18, 123, -39, 121, -52, 89, -59, 36, +-54, -19, -48, -61, -39, -78, -28, -73, +-20, -51, -10, -16, -11, 24, -20, 64, +-39, 87, -51, 81, -50, 48, -39, 3, +-30, -35, -20, -55, -12, -54, -16, -33, +-30, -2, -49, 28, -64, 42, -70, 31, +-61, 6, -35, -11, 4, -7, 32, 16, +40, 43, 20, 59, -19, 52, -68, 19, +-113, -34, -134, -87, -123, -110, -76, -84, +-19, -15, 39, 69, 79, 135, 89, 161, +64, 135, 9, 60, -66, -42, -136, -134, +-174, -181, -166, -163, -117, -89, -45, 10, +36, 106, 101, 176, 132, 200, 113, 163, +47, 78, -48, -32, -134, -135, -188, -201, +-196, -211, -153, -162, -72, -57, 24, 82, +101, 204, 140, 269, 121, 251, 59, 156, +-30, 6, -116, -151, -173, -269, -184, -301, +-147, -225, -76, -69, 5, 108, 67, 243, +99, 296, 98, 255, 64, 141, 1, -14, +-67, -159, -120, -239, -143, -236, -135, -168, +-100, -60, -45, 59, 16, 155, 63, 209, +73, 207, 48, 150, -1, 54, -50, -50, +-91, -138, -104, -192, -89, -192, -51, -131, +-10, -23, 16, 97, 19, 180, -4, 199, +-38, 157, -62, 71, -60, -27, -41, -109, +-12, -143, 10, -123, 16, -66, -2, -6, +-36, 34, -67, 51, -79, 52, -67, 51, +-45, 53, -15, 56, 9, 53, 16, 40, +1, 3, -16, -55, -29, -107, -35, -127, +-41, -100, -48, -33, -58, 50, -64, 122, +-56, 165, -39, 161, -6, 101, 28, 2, +47, -97, 31, -160, -12, -168, -69, -125, +-104, -50, -98, 38, -62, 115, -20, 160, +13, 153, 33, 101, 34, 20, 17, -60, +-19, -120, -48, -145, -68, -131, -71, -75, +-62, 1, -41, 80, -13, 137, 4, 153, +10, 124, 5, 52, -6, -37, -25, -115, +-40, -156, -47, -140, -46, -66, -48, 38, +-44, 129, -40, 170, -35, 144, -28, 54, +-11, -63, 19, -153, 37, -175, 37, -120, +12, -9, -25, 113, -72, 188, -112, 184, +-132, 102, -113, -24, -57, -147, 19, -219, +87, -208, 123, -115, 118, 26, 62, 164, +-29, 248, -128, 248, -188, 164, -196, 23, +-145, -131, -58, -249, 34, -290, 101, -234, +127, -95, 117, 81, 75, 235, 12, 321, +-65, 304, -130, 188, -175, 5, -183, -182, +-149, -310, -72, -334, 27, -253, 114, -98, +163, 84, 160, 240, 105, 323, 8, 311, +-100, 210, -186, 47, -214, -132, -189, -274, +-120, -336, -28, -309, 69, -189, 140, -1, +163, 204, 132, 358, 53, 403, -42, 316, +-126, 119, -171, -126, -175, -339, -139, -439, +-81, -381, -8, -189, 56, 70, 93, 301, +101, 418, 89, 380, 55, 210, -10, -25, +-77, -236, -127, -345, -145, -315, -132, -173, +-87, 10, -26, 162, 36, 229, 74, 204, +83, 112, 72, 1, 46, -82, 5, -111, +-47, -89, -93, -43, -124, -3, -124, 13, +-93, 5, -35, -12, 23, -16, 66, 0, +83, 28, 77, 53, 45, 61, -12, 45, +-63, 3, -91, -45, -96, -71, -92, -64, +-70, -32, -34, 5, 11, 26, 42, 25, +52, 12, 47, -4, 34, -9, 13, 11, +-27, 48, -70, 82, -103, 83, -109, 33, +-87, -56, -38, -147, 17, -194, 64, -161, +86, -55, 75, 88, 32, 216, -36, 276, +-96, 233, -126, 92, -114, -97, -70, -254, +-3, -316, 56, -262, 85, -116, 66, 70, +24, 228, -20, 305, -58, 279, -89, 156, +-100, -19, -78, -180, -40, -271, 6, -273, +42, -189, 62, -46, 61, 109, 43, 224, +9, 259, -33, 201, -74, 77, -102, -67, +-105, -182, -83, -231, -39, -196, 10, -89, +65, 47, 100, 156, 96, 195, 50, 154, +-17, 63, -77, -42, -112, -123, -118, -152, +-95, -121, -46, -45, 6, 36, 44, 89, +59, 100, 65, 76, 57, 31, 36, -15, +1, -54, -36, -78, -72, -79, -103, -57, +-117, -18, -105, 22, -57, 57, 15, 84, +89, 97, 132, 78, 127, 25, 74, -47, +0, -115, -74, -149, -137, -134, -170, -74, +-153, 18, -90, 119, -8, 188, 69, 193, +120, 126, 140, 8, 118, -119, 60, -207, +-22, -223, -99, -159, -153, -35, -170, 102, +-145, 203, -84, 229, 0, 165, 81, 41, +144, -89, 159, -177, 128, -194, 61, -144, +-21, -46, -107, 62, -177, 131, -205, 136, +-175, 86, -89, 15, 26, -46, 145, -77, +227, -76, 236, -46, 147, 0, -11, 42, +-170, 62, -260, 48, -265, 11, -188, -28, +-56, -61, 90, -75, 199, -63, 229, -22, +186, 42, 89, 103, -24, 127, -122, 95, +-181, 23, -199, -62, -171, -135, -104, -169, +-7, -146, 96, -63, 172, 53, 203, 153, +173, 195, 84, 165, -48, 83, -172, -15, +-242, -108, -227, -170, -144, -184, -22, -136, +103, -46, 190, 51, 206, 123, 146, 158, +48, 159, -52, 121, -126, 44, -163, -59, +-152, -151, -106, -193, -37, -181, 31, -121, +83, -25, 115, 87, 127, 185, 116, 226, +70, 185, -13, 80, -119, -47, -194, -157, +-204, -219, -140, -219, -31, -151, 90, -23, +177, 119, 198, 213, 149, 221, 50, 158, +-56, 56, -133, -61, -159, -161, -145, -207, +-91, -171, -20, -76, 50, 28, 97, 97, +115, 123, 98, 124, 51, 104, -8, 54, +-60, -21, -90, -86, -96, -116, -69, -110, +-27, -84, 18, -43, 46, 16, 58, 84, +54, 124, 37, 109, 5, 47, -25, -25, +-30, -79, -18, -104, -7, -92, -11, -46, +-15, 20, -21, 76, -26, 86, -29, 44, +-11, -16, 25, -55, 63, -62, 79, -39, +54, 3, 0, 52, -63, 89, -99, 88, +-94, 34, -46, -47, 12, -116, 56, -143, +70, -121, 51, -55, 17, 37, -7, 136, +-11, 201, -6, 191, -2, 103, -6, -26, +-13, -145, -31, -221, -48, -233, -50, -173, +-20, -50, 28, 93, 69, 204, 83, 247, +66, 220, 30, 141, -22, 26, -70, -101, +-99, -212, -93, -275, -55, -265, 4, -180, +59, -39, 98, 128, 106, 280, 85, 367, +43, 341, -17, 193, -77, -33, -112, -263, +-105, -418, -72, -444, -23, -328, 29, -103, +86, 157, 127, 364, 135, 452, 104, 400, +48, 229, -25, -4, -105, -232, -159, -390, +-166, -436, -113, -356, -26, -181, 70, 43, +149, 256, 193, 404, 181, 438, 114, 335, +8, 120, -108, -132, -186, -339, -197, -435, +-136, -393, -39, -236, 66, -11, 139, 211, +164, 352, 134, 363, 72, 257, 5, 90, +-37, -78, -54, -203, -67, -257, -75, -233, +-75, -149, -57, -38, -32, 59, 10, 119, +67, 144, 126, 141, 155, 110, 137, 58, +68, -6, -31, -61, -126, -98, -184, -117, +-177, -111, -113, -78, -6, -21, 108, 37, +189, 77, 205, 86, 154, 71, 60, 47, +-41, 19, -120, -10, -153, -35, -121, -45, +-42, -43, 37, -43, 73, -53, 70, -60, +40, -39, 11, 7, -3, 57, 10, 90, +43, 101, 73, 88, 73, 43, 31, -25, +-35, -95, -103, -131, -132, -116, -108, -65, +-32, -4, 59, 45, 137, 72, 174, 73, +156, 56, 80, 29, -19, 5, -90, -4, +-121, -3, -107, -13, -67, -46, -9, -83, +43, -101, 77, -87, 85, -38, 77, 38, +61, 118, 41, 169, 15, 158, -8, 79, +-19, -40, -29, -151, -41, -214, -50, -202, +-43, -115, -20, 17, 22, 147, 67, 219, +105, 201, 118, 98, 103, -43, 65, -160, +4, -205, -65, -166, -123, -62, -133, 63, +-95, 152, -22, 169, 55, 103, 120, -13, +154, -118, 139, -160, 83, -125, 13, -35, +-41, 67, -71, 133, -75, 138, -58, 80, +-20, -12, 17, -100, 43, -147, 49, -135, +45, -72, 39, 3, 40, 62, 50, 92, +57, 92, 54, 70, 33, 32, 1, -14, +-37, -55, -65, -80, -75, -87, -50, -77, +-7, -55, 41, -17, 82, 33, 111, 79, +125, 103, 105, 91, 49, 53, -22, -2, +-76, -57, -106, -95, -108, -108, -76, -91, +-9, -46, 62, 10, 120, 57, 150, 85, +141, 90, 98, 71, 29, 29, -42, -28, +-99, -80, -118, -103, -99, -92, -38, -54, +36, -4, 96, 45, 128, 76, 130, 78, +96, 49, 32, 0, -28, -47, -58, -71, +-54, -64, -33, -41, 2, -6, 34, 34, +57, 66, 56, 69, 30, 36, -1, -22, +-15, -81, -11, -114, 2, -111, 32, -72, +72, 6, 105, 111, 104, 192, 67, 202, +-3, 120, -77, -26, -125, -183, -124, -291, +-73, -309, 9, -216, 100, -26, 176, 199, +215, 370, 189, 410, 112, 298, -3, 74, +-119, -180, -207, -384, -232, -467, -175, -394, +-42, -187, 119, 82, 250, 321, 310, 447, +275, 425, 157, 276, -9, 45, -161, -200, +-245, -385, -238, -449, -156, -374, -24, -189, +106, 43, 195, 252, 232, 378, 217, 389, +157, 280, 63, 89, -33, -122, -114, -283, +-157, -348, -164, -315, -121, -205, -30, -53, +79, 103, 167, 224, 205, 276, 192, 251, +133, 163, 45, 46, -54, -77, -120, -192, +-133, -268, -94, -273, -25, -194, 54, -60, +112, 82, 129, 193, 104, 251, 52, 244, +5, 163, -21, 27, -19, -121, 3, -230, +31, -263, 45, -216, 50, -121, 51, -4, +41, 120, 7, 214, -33, 237, -54, 176, +-49, 56, -12, -78, 48, -182, 117, -229, +165, -208, 166, -115, 104, 27, 4, 162, +-98, 226, -168, 196, -179, 90, -119, -47, +1, -166, 135, -224, 238, -194, 268, -84, +219, 66, 98, 184, -45, 213, -165, 147, +-225, 25, -209, -108, -114, -207, 37, -235, +183, -166, 270, -15, 262, 144, 178, 236, +47, 219, -83, 112, -165, -36, -166, -172, +-102, -249, -3, -229, 89, -110, 144, 59, +153, 192, 114, 222, 53, 150, -9, 22, +-44, -102, -47, -181, -19, -184, 24, -105, +65, 18, 84, 123, 79, 155, 52, 101, +8, 1, -31, -94, -44, -148, -24, -144, +9, -82, 50, 18, 85, 112, 113, 154, +117, 124, 82, 40, 19, -59, -35, -138, +-64, -173, -68, -144, -41, -59, 12, 48, +77, 133, 116, 153, 121, 100, 95, 1, +54, -96, 10, -153, -15, -149, -17, -78, +-3, 33, 17, 126, 27, 145, 22, 86, +4, -24, -4, -128, 12, -177, 53, -153, +96, -64, 124, 59, 123, 161, 92, 190, +29, 132, -56, 17, -124, -106, -141, -189, +-93, -204, -1, -153, 111, -52, 205, 60, +248, 146, 210, 173, 105, 141, -28, 68, +-141, -25, -191, -110, -164, -163, -75, -163, +41, -114, 152, -36, 216, 43, 212, 98, +138, 109, 34, 81, -60, 27, -101, -33, +-82, -68, -20, -64, 54, -32, 108, -4, +116, 3, 69, -14, 4, -46, -44, -85, +-48, -105, -15, -80, 48, 2, 115, 106, +160, 179, 156, 185, 95, 120, 0, 3, +-91, -137, -138, -255, -126, -303, -56, -245, +38, -93, 131, 94, 197, 244, 211, 310, +163, 277, 76, 155, -17, -21, -90, -195, +-128, -304, -127, -310, -77, -222, 6, -86, +95, 56, 152, 166, 173, 227, 157, 221, +112, 150, 50, 45, -13, -60, -50, -141, +-60, -198, -48, -220, -30, -191, -11, -101, +3, 21, 31, 122, 73, 177, 126, 179, +174, 135, 192, 52, 161, -51, 72, -139, +-49, -176, -159, -155, -204, -101, -174, -52, +-77, -14, 57, 21, 196, 54, 293, 77, +312, 82, 238, 75, 98, 63, -67, 36, +-206, -22, -268, -104, -233, -173, -100, -191, +75, -149, 228, -61, 307, 46, 288, 151, +175, 218, 24, 208, -109, 116, -187, -24, +-176, -160, -87, -243, 41, -246, 149, -170, +197, -42, 174, 92, 108, 184, 20, 193, +-49, 117, -74, -3, -44, -110, 24, -167, +91, -162, 121, -98, 106, 1, 60, 90, +-6, 132, -49, 103, -58, 19, -19, -82, +50, -154, 111, -173, 136, -130, 123, -38, +81, 76, 25, 170, -19, 202, -50, 152, +-51, 29, -21, -124, 37, -247, 89, -295, +115, -245, 106, -108, 78, 71, 37, 229, +-5, 303, -25, 263, -19, 119, 23, -67, +71, -226, 96, -301, 92, -277, 73, -171, +32, -29, -10, 105, -40, 181, -51, 179, +-26, 121, 27, 42, 93, -24, 154, -69, +186, -97, 162, -110, 87, -109, -26, -97, +-129, -74, -176, -46, -141, -3, -34, 59, +98, 118, 209, 139, 265, 105, 233, 35, +112, -51, -22, -129, -118, -181, -146, -187, +-103, -138, -20, -46, 69, 54, 137, 126, +155, 152, 125, 128, 75, 67, 23, -23, +-6, -121, -4, -192, 30, -200, 72, -142, +93, -45, 68, 53, 15, 126, -51, 158, +-88, 132, -61, 42, 17, -80, 123, -172, +207, -194, 233, -142, 185, -49, 80, 51, +-59, 126, -165, 150, -197, 104, -150, -3, +-38, -122, 106, -193, 233, -179, 292, -97, +264, 7, 156, 93, 17, 140, -115, 129, +-190, 54, -187, -59, -108, -154, 23, -180, +156, -133, 239, -46, 252, 44, 188, 110, +61, 129, -61, 81, -140, -21, -152, -128, +-90, -182, 23, -153, 136, -57, 211, 59, +211, 150, 141, 180, 40, 128, -60, 3, +-123, -152, -130, -267, -65, -287, 44, -200, +148, -40, 206, 130, 212, 254, 154, 292, +57, 225, -40, 68, -112, -128, -128, -291, +-80, -363, 5, -327, 95, -206, 170, -32, +197, 153, 174, 298, 110, 354, 22, 293, +-54, 126, -83, -88, -61, -282, -16, -399, +27, -403, 60, -285, 84, -75, 90, 157, +87, 328, 80, 373, 81, 284, 87, 106, +80, -94, 39, -257, -12, -333, -59, -301, +-91, -180, -78, -24, -20, 104, 74, 163, +171, 151, 234, 101, 221, 36, 144, -26, +37, -68, -68, -84, -143, -72, -163, -52, +-113, -47, -4, -58, 129, -70, 223, -67, +239, -45, 180, -17, 85, 19, -26, 59, +-110, 90, -126, 92, -64, 54, 43, -11, +143, -78, 186, -130, 151, -159, 73, -160, +-24, -128, -98, -61, -110, 20, -41, 92, +71, 138, 177, 153, 229, 134, 198, 75, +105, -22, -10, -136, -113, -228, -173, -267, +-153, -236, -57, -149, 85, -22, 214, 120, +280, 238, 259, 286, 171, 238, 43, 105, +-95, -66, -187, -221, -195, -320, -116, -343, +11, -281, 143, -139, 225, 43, 241, 205, +207, 297, 133, 298, 29, 216, -60, 69, +-108, -104, -113, -260, -69, -352, 0, -350, +76, -254, 139, -96, 178, 78, 161, 220, +102, 298, 33, 292, -15, 199, -39, 40, +-33, -138, 2, -279, 41, -343, 75, -316, +88, -212, 66, -54, 31, 113, 25, 237, +32, 279, 47, 232, 65, 114, 69, -34, +62, -164, 55, -245, 33, -262, 2, -211, +-8, -114, -1, -6, 26, 79, 60, 119, +98, 127, 120, 115, 116, 81, 81, 27, +26, -44, -29, -113, -50, -161, -34, -187, +-4, -190, 54, -149, 112, -60, 145, 55, +154, 156, 129, 206, 60, 188, -11, 112, +-59, -6, -75, -139, -40, -251, 30, -300, +100, -255, 140, -136, 138, 9, 90, 131, +27, 208, -23, 228, -23, 179, 17, 70, +70, -63, 113, -173, 107, -231, 56, -233, +-4, -198, -52, -134, -67, -41, -19, 70, +60, 159, 152, 199, 223, 187, 216, 136, +128, 47, 3, -81, -121, -221, -199, -319, +-184, -327, -72, -242, 105, -92, 265, 82, +343, 242, 302, 339, 162, 323, -15, 183, +-161, -34, -237, -244, -203, -370, -75, -384, +72, -298, 204, -139, 268, 51, 241, 211, +162, 282, 73, 246, -20, 136, -75, 13, +-78, -90, -45, -164, 10, -210, 61, -219, +82, -182, 71, -117, 56, -51, 50, 14, +57, 91, 70, 165, 101, 197, 120, 160, +110, 59, 79, -69, 16, -180, -58, -251, +-91, -266, -84, -214, -44, -105, 45, 23, +140, 122, 207, 166, 231, 158, 191, 122, +97, 70, 2, 0, -75, -82, -127, -156, +-133, -204, -86, -218, 8, -196, 110, -134, +188, -31, 217, 92, 190, 197, 128, 236, +65, 195, 0, 90, -36, -41, -34, -165, +-28, -258, -17, -289, -6, -252, -5, -158, +9, -42, 58, 67, 109, 153, 165, 213, +217, 231, 233, 195, 188, 98, 81, -50, +-61, -215, -195, -350, -269, -415, -247, -381, +-122, -230, 69, 10, 282, 270, 422, 459, +437, 501, 337, 374, 146, 113, -87, -204, +-266, -477, -342, -620, -305, -578, -152, -351, +45, -16, 224, 308, 346, 512, 375, 545, +296, 401, 161, 129, 20, -181, -86, -434, +-137, -543, -139, -479, -114, -278, -78, -20, +-20, 206, 51, 338, 117, 351, 178, 249, +245, 69, 272, -122, 244, -252, 152, -283, +-3, -228, -156, -130, -250, -28, -271, 53, +-204, 90, -32, 73, 176, 17, 351, -35, +433, -52, 391, -27, 230, 12, 18, 34, +-177, 22, -298, -26, -296, -100, -170, -174, +20, -209, 188, -170, 285, -54, 280, 90, +203, 197, 105, 223, 16, 156, -51, 16, +-55, -145, -12, -266, 27, -296, 50, -217, +47, -64, 23, 93, 11, 180, 35, 173, +62, 89, 89, -26, 114, -126, 122, -169, +99, -141, 61, -61, 19, 24, -11, 65, +-4, 45, 13, -11, 13, -70, 11, -105, +36, -100, 63, -63, 85, -6, 103, 44, +109, 65, 102, 46, 86, -8, 47, -65, +-12, -100, -35, -108, -10, -97, 30, -67, +66, -20, 88, 30, 78, 58, 61, 51, +40, 14, 14, -36, 19, -86, 72, -119, +133, -120, 157, -89, 138, -27, 71, 41, +-21, 86, -101, 82, -135, 30, -114, -45, +-18, -115, 122, -162, 235, -167, 281, -119, +260, -29, 177, 71, 55, 137, -49, 142, +-124, 82, -153, -17, -126, -124, -67, -206, +-5, -237, 79, -195, 169, -90, 239, 36, +289, 131, 284, 172, 203, 153, 66, 83, +-78, -14, -200, -116, -259, -197, -234, -232, +-129, -206, 16, -135, 181, -40, 329, 60, +394, 148, 373, 200, 275, 185, 103, 99, +-93, -34, -245, -168, -343, -260, -331, -285, +-194, -237, 13, -124, 232, 23, 412, 149, +485, 210, 423, 191, 254, 115, 24, 12, +-185, -86, -317, -164, -332, -208, -248, -205, +-94, -159, 92, -85, 247, -4, 326, 66, +344, 118, 299, 144, 187, 128, 72, 65, +-39, -31, -140, -123, -196, -188, -197, -214, +-157, -200, -55, -139, 76, -42, 196, 63, +293, 140, 336, 168, 305, 144, 204, 74, +65, -21, -80, -126, -190, -208, -241, -240, +-213, -209, -132, -126, -1, -21, 167, 72, +302, 137, 364, 162, 349, 138, 239, 68, +71, -31, -83, -127, -212, -197, -260, -228, +-196, -217, -66, -153, 74, -44, 201, 80, +283, 171, 300, 195, 250, 151, 136, 56, +2, -61, -109, -167, -148, -232, -125, -232, +-62, -170, 28, -76, 116, 16, 149, 84, +151, 125, 136, 138, 100, 118, 86, 57, +80, -38, 47, -135, 4, -211, -29, -243, +-53, -226, -33, -144, 19, -9, 74, 137, +118, 231, 135, 237, 121, 152, 90, 10, +66, -140, 49, -258, 30, -310, 14, -281, +22, -171, 18, -16, 12, 129, 34, 219, +60, 242, 74, 198, 91, 89, 86, -66, +66, -228, 65, -335, 41, -344, 7, -253, +5, -94, 34, 92, 75, 246, 120, 313, +133, 262, 109, 106, 61, -96, 1, -265, +-52, -344, -85, -322, -53, -211, 32, -51, +124, 108, 195, 206, 225, 218, 183, 151, +112, 41, 29, -67, -65, -148, -118, -190, +-107, -187, -63, -141, 2, -75, 82, -11, +142, 30, 194, 47, 225, 50, 210, 45, +145, 28, 54, 5, -40, -19, -120, -45, +-162, -73, -148, -109, -79, -143, 33, -156, +172, -131, 267, -70, 297, 19, 279, 107, +208, 169, 81, 184, -60, 130, -186, 12, +-256, -137, -224, -267, -123, -331, 5, -301, +146, -181, 286, 0, 376, 184, 389, 308, +305, 326, 140, 226, -56, 35, -227, -179, +-343, -344, -371, -409, -261, -349, -38, -183, +213, 30, 408, 217, 500, 319, 459, 299, +323, 173, 114, -7, -141, -177, -345, -283, +-416, -299, -354, -229, -189, -109, 47, 12, +288, 93, 472, 120, 531, 101, 429, 58, +188, 14, -78, -18, -269, -41, -347, -61, +-301, -80, -155, -103, 31, -126, 191, -137, +284, -118, 281, -70, 222, 0, 163, 77, +117, 140, 64, 164, 12, 136, -46, 54, +-119, -70, -174, -208, -181, -311, -126, -337, +8, -262, 203, -99, 364, 109, 429, 299, +375, 392, 208, 342, -20, 152, -223, -118, +-347, -367, -358, -504, -228, -477, 0, -295, +236, -22, 403, 245, 454, 414, 363, 426, +179, 286, -33, 50, -215, -191, -302, -364, +-251, -421, -100, -353, 75, -194, 223, 1, +291, 169, 265, 260, 179, 251, 73, 164, +-35, 31, -94, -101, -88, -198, -42, -234, +19, -199, 76, -117, 110, -29, 118, 30, +108, 46, 73, 32, 32, 12, 7, -1, +17, 1, 41, 20, 68, 40, 90, 32, +85, -22, 50, -106, 6, -183, -35, -216, +-48, -189, -2, -100, 71, 23, 141, 148, +187, 227, 175, 224, 98, 134, 5, -14, +-78, -169, -125, -283, -102, -325, -12, -282, +112, -155, 214, 16, 253, 175, 200, 270, +79, 274, -55, 184, -140, 33, -164, -133, +-106, -265, 16, -321, 141, -286, 236, -175, +266, -31, 212, 97, 112, 170, 8, 184, +-105, 147, -178, 80, -167, -2, -80, -80, +50, -142, 171, -183, 230, -205, 223, -199, +171, -151, 86, -58, 3, 67, -48, 179, +-41, 241, -10, 220, 9, 114, 13, -47, +1, -213, -13, -328, 16, -343, 66, -246, +115, -76, 177, 100, 213, 220, 194, 259, +121, 211, 4, 99, -129, -49, -211, -183, +-223, -263, -151, -274, 8, -224, 207, -133, +378, -14, 440, 112, 362, 210, 167, 240, +-80, 180, -289, 45, -373, -117, -325, -252, +-155, -314, 78, -278, 278, -150, 394, 24, +404, 174, 301, 234, 141, 186, -11, 68, +-153, -64, -243, -157, -257, -188, -196, -160, +-68, -95, 98, -31, 237, 6, 314, 9, +315, -1, 245, 3, 124, 32, -18, 59, +-117, 53, -162, 13, -163, -50, -124, -116, +-54, -162, 23, -169, 124, -122, 216, -35, +257, 55, 251, 108, 189, 112, 78, 81, +-43, 31, -135, -29, -186, -92, -162, -142, +-86, -167, 13, -157, 114, -119, 199, -60, +250, 18, 250, 102, 199, 161, 107, 161, +-10, 104, -126, 4, -190, -106, -200, -200, +-145, -255, -27, -248, 114, -170, 246, -38, +333, 105, 313, 210, 194, 239, 37, 188, +-122, 73, -215, -81, -210, -226, -124, -302, +7, -279, 133, -168, 199, -20, 198, 108, +155, 172, 101, 165, 53, 106, -3, 18, +-47, -61, -64, -107, -50, -115, -4, -108, +55, -97, 96, -91, 129, -76, 132, -37, +77, 18, 1, 69, -49, 94, -51, 81, +-3, 27, 66, -47, 107, -109, 117, -131, +98, -112, 58, -66, 4, -25, -31, -11, +-21, -23, 18, -37, 59, -24, 82, 17, +76, 67, 55, 94, 36, 71, 5, -9, +-16, -118, -4, -206, 36, -224, 84, -151, +123, -10, 121, 130, 75, 197, 14, 159, +-57, 39, -106, -105, -94, -207, -9, -218, +111, -135, 218, 5, 250, 128, 186, 168, +53, 104, -94, -23, -195, -148, -213, -211, +-125, -188, 33, -92, 197, 34, 298, 134, +296, 165, 191, 111, 46, 6, -88, -99, +-175, -162, -192, -171, -124, -141, 1, -93, +129, -31, 208, 37, 209, 87, 155, 113, +65, 109, -25, 76, -93, 6, -99, -87, +-36, -180, 56, -231, 129, -205, 148, -107, +105, 27, 28, 141, -42, 191, -90, 157, +-81, 58, -6, -66, 105, -157, 186, -175, +198, -114, 130, -22, 24, 37, -70, 30, +-124, -28, -119, -96, -56, -126, 54, -89, +146, 8, 188, 132, 168, 210, 105, 186, +28, 48, -34, -147, -68, -305, -68, -350, +-35, -264, 9, -84, 42, 121, 56, 265, +71, 291, 87, 200, 106, 41, 117, -116, +109, -205, 66, -213, -4, -162, -84, -98, +-144, -54, -134, -27, -55, -1, 57, 38, +161, 92, 220, 144, 201, 158, 133, 107, +44, -18, -27, -179, -52, -300, -48, -315, +-40, -212, -41, -40, -46, 134, -44, 241, +-5, 243, 73, 149, 175, 6, 251, -119, +257, -166, 168, -137, 4, -80, -170, -51, +-275, -67, -266, -105, -140, -121, 63, -85, +249, 13, 345, 156, 311, 277, 169, 304, +-17, 191, -165, -38, -222, -291, -170, -458, +-48, -471, 78, -320, 157, -55, 159, 225, +109, 421, 44, 459, 0, 331, -9, 88, +18, -165, 43, -346, 50, -408, 38, -345, +8, -200, -11, -23, -12, 132, -14, 215, +-12, 212, 11, 152, 41, 73, 90, 8, +133, -43, 148, -86, 120, -128, 52, -168, +-40, -195, -122, -194, -151, -143, -109, -31, +-14, 124, 86, 263, 166, 316, 194, 243, +166, 74, 101, -132, 22, -302, -47, -377, +-86, -324, -107, -167, -108, 28, -68, 186, +2, 248, 95, 216, 188, 131, 234, 38, +205, -42, 121, -98, -11, -145, -144, -177, +-228, -192, -218, -184, -106, -135, 60, -27, +214, 120, 294, 245, 273, 294, 153, 228, +-13, 69, -158, -124, -206, -283, -145, -367, +-22, -337, 104, -198, 170, 6, 146, 210, +61, 331, -32, 334, -90, 229, -67, 53, +18, -160, 110, -337, 159, -403, 138, -323, +51, -122, -43, 117, -107, 284, -113, 320, +-47, 225, 48, 30, 131, -173, 160, -280, +123, -243, 44, -94, -32, 77, -87, 161, +-93, 114, -47, -25, 33, -169, 111, -220, +145, -126, 129, 74, 67, 266, -11, 335, +-75, 208, -96, -75, -74, -373, -10, -529, +62, -445, 111, -135, 127, 259, 100, 540, +49, 574, 3, 332, -22, -78, -31, -468, +-16, -650, -3, -543, 12, -191, 28, 232, +38, 515, 39, 533, 41, 300, 41, -59, +42, -371, 46, -490, 41, -371, 33, -76, +12, 240, -22, 396, -59, 309, -68, 48, +-36, -246, 32, -415, 99, -374, 140, -135, +140, 198, 95, 459, 28, 499, -42, 269, +-88, -120, -95, -478, -66, -633, -33, -513, +2, -170, 38, 241, 83, 545, 133, 603, +161, 386, 152, 7, 104, -349, 24, -518, +-85, -451, -181, -209, -216, 66, -156, 248, +-27, 271, 123, 153, 234, -26, 273, -153, +226, -150, 98, -30, -61, 115, -173, 177, +-187, 112, -121, -52, -11, -227, 79, -331, +117, -301, 105, -134, 58, 109, -1, 317, +-19, 394, 19, 312, 77, 112, 113, -119, +88, -303, 8, -388, -87, -351, -154, -202, +-179, -3, -123, 179, 6, 289, 154, 307, +268, 231, 303, 88, 240, -80, 98, -223, +-73, -284, -230, -253, -311, -148, -284, -17, +-156, 86, 23, 119, 199, 89, 309, 29, +336, -10, 285, 8, 157, 69, -9, 124, +-163, 120, -266, 27, -299, -153, -244, -342, +-121, -436, 53, -354, 230, -95, 343, 248, +352, 526, 253, 620, 74, 475, -123, 116, +-262, -326, -303, -671, -233, -766, -77, -566, +102, -153, 225, 301, 264, 629, 211, 717, +105, 538, -8, 161, -104, -258, -154, -551, +-142, -620, -75, -462, 5, -167, 70, 148, +94, 365, 90, 418, 72, 303, 48, 98, +17, -98, 0, -206, 3, -203, 10, -121, +4, -20, -28, 34, -59, 22, -68, -42, +-39, -103, 16, -110, 91, -39, 155, 80, +179, 192, 125, 231, -2, 159, -136, -7, +-204, -196, -169, -317, -45, -313, 121, -184, +246, 16, 273, 213, 162, 325, -41, 303, +-229, 148, -297, -68, -207, -250, -13, -333, +189, -295, 300, -164, 276, 21, 130, 202, +-57, 313, -183, 296, -178, 166, -76, -22, +45, -196, 108, -296, 85, -294, 4, -201, +-77, -42, -108, 135, -60, 233, 69, 214, +191, 107, 234, -18, 169, -96, 22, -95, +-134, -51, -212, 6, -196, 53, -105, 33, +27, -71, 126, -196, 155, -249, 122, -172, +58, 31, 1, 250, -8, 377, 11, 366, +34, 208, 38, -74, 1, -363, -72, -519, +-125, -467, -111, -216, -34, 107, 74, 349, +155, 443, 172, 387, 116, 189, 20, -62, +-76, -253, -106, -311, -65, -238, -1, -106, +40, -25, 34, -9, -8, -5, -50, -4, +-44, 22, 6, 104, 86, 223, 154, 306, +161, 282, 95, 90, -14, -208, -124, -458, +-179, -565, -156, -489, -86, -219, 4, 163, +90, 496, 147, 656, 158, 569, 148, 270, +119, -96, 69, -391, -14, -547, -122, -509, +-213, -306, -242, -49, -190, 176, -74, 303, +93, 311, 258, 247, 348, 162, 311, 45, +161, -65, -53, -132, -236, -174, -309, -198, +-258, -190, -113, -153, 59, -73, 167, 48, +169, 139, 103, 184, 20, 206, -2, 189, +50, 107, 118, -5, 130, -136, 66, -245, +-74, -278, -234, -239, -312, -146, -247, 9, +-44, 186, 197, 297, 361, 312, 365, 211, +221, 41, -7, -115, -215, -219, -299, -277, +-229, -253, -63, -143, 109, -4, 195, 123, +154, 197, 34, 209, -94, 187, -165, 126, +-127, -12, 9, -171, 163, -264, 261, -253, +233, -143, 75, 19, -125, 165, -275, 254, +-311, 250, -200, 106, 16, -107, 218, -261, +328, -269, 292, -140, 123, 52, -88, 188, +-238, 220, -272, 145, -170, -24, 10, -202, +159, -264, 235, -162, 211, 39, 93, 232, +-64, 299, -182, 220, -227, 45, -171, -167, +-37, -333, 105, -353, 207, -217, 242, -1, +183, 203, 46, 311, -103, 304, -218, 214, +-233, 65, -136, -116, 5, -255, 122, -317, +186, -291, 167, -179, 79, -7, -11, 186, +-65, 351, -64, 412, -27, 307, -11, 79, +-37, -197, -61, -428, -79, -511, -75, -396, +-19, -126, 81, 216, 182, 482, 241, 544, +210, 397, 79, 111, -87, -205, -236, -425, +-319, -456, -300, -317, -170, -71, 30, 159, +239, 256, 358, 204, 335, 77, 205, -50, +29, -94, -143, -16, -255, 119, -259, 236, +-169, 251, -39, 96, 54, -191, 78, -454, +66, -567, 58, -448, 61, -109, 77, 299, +102, 614, 108, 725, 63, 550, -31, 130, +-136, -335, -209, -653, -188, -702, -89, -470, +38, -85, 148, 273, 212, 503, 191, 523, +84, 314, -50, 4, -136, -250, -123, -347, +-46, -267, 24, -91, 46, 54, 35, 141, +-21, 154, -97, 69, -121, -58, -53, -122, +88, -88, 239, 26, 298, 154, 205, 190, +22, 127, -193, 9, -370, -142, -421, -279, +-306, -303, -75, -196, 210, 8, 423, 231, +459, 352, 356, 323, 167, 203, -87, 41, +-319, -136, -431, -239, -410, -244, -249, -175, +-14, -74, 178, -11, 286, -18, 310, -22, +217, 31, 66, 119, -43, 223, -107, 300, +-109, 282, -46, 147, -1, -76, -20, -344, +-52, -516, -107, -474, -159, -240, -133, 79, +-36, 366, 107, 501, 270, 445, 343, 245, +262, -43, 99, -294, -106, -377, -312, -284, +-406, -117, -345, 44, -168, 133, 102, 141, +339, 106, 401, 51, 301, -5, 100, -2, +-144, 56, -309, 75, -316, 20, -207, -79, +8, -169, 227, -200, 288, -149, 192, -48, +31, 101, -147, 266, -248, 332, -205, 242, +-72, 55, 110, -142, 261, -288, 257, -328, +95, -267, -97, -114, -241, 103, -281, 284, +-181, 312, -11, 209, 150, 58, 270, -90, +278, -180, 146, -193, -20, -122, -151, 16, +-223, 150, -207, 159, -125, 49, -28, -80, +87, -163, 156, -170, 119, -90, 50, 36, +7, 170, -34, 275, -51, 249, -18, 80, +23, -114, 67, -232, 85, -257, 18, -187, +-93, -74, -163, 42, -189, 160, -153, 219, +-44, 163, 80, 62, 191, 1, 271, -35, +261, -59, 147, -88, 7, -120, -141, -108, +-277, -32, -340, 20, -300, 35, -155, 73, +67, 116, 269, 119, 355, 68, 319, -18, +162, -79, -65, -50, -241, -15, -288, -37, +-212, -54, -34, -29, 141, -7, 194, 6, +112, 4, -57, 8, -210, 73, -238, 131, +-109, 88, 95, 0, 292, -36, 368, -51, +260, -61, 19, -68, -251, -69, -437, -20, +-435, 63, -243, 74, 29, 21, 273, 8, +395, 15, 362, 5, 205, -11, -9, -23, +-202, -1, -277, 77, -230, 101, -143, 24, +-58, -58, 12, -114, 57, -157, 85, -147, +108, -61, 115, 73, 131, 249, 131, 343, +62, 244, -55, 25, -162, -197, -236, -373, +-236, -415, -165, -276, -72, -20, 56, 293, +198, 526, 275, 509, 261, 259, 184, -56, +53, -349, -74, -521, -187, -477, -300, -254, +-333, 61, -234, 371, -82, 503, 67, 389, +214, 163, 304, -85, 330, -287, 282, -343, +114, -239, -127, -49, -313, 170, -415, 284, +-402, 195, -238, 3, 12, -163, 273, -258, +454, -220, 430, -37, 198, 181, -72, 361, +-284, 398, -377, 196, -294, -134, -90, -379, +121, -465, 270, -369, 260, -93, 79, 228, +-110, 463, -210, 519, -204, 320, -80, -53, +86, -349, 181, -469, 199, -418, 124, -197, +-48, 107, -202, 358, -233, 479, -159, 401, +-27, 133, 105, -147, 162, -324, 164, -399, +108, -344, -25, -145, -157, 101, -178, 315, +-102, 415, 5, 324, 87, 113, 98, -98, +55, -275, 1, -364, -64, -282, -124, -85, +-105, 139, -8, 307, 106, 321, 164, 178, +125, 0, 27, -153, -57, -251, -123, -220, +-185, -89, -189, 48, -103, 152, 27, 173, +121, 87, 156, -2, 152, -39, 148, -47, +117, -15, 15, 36, -125, 34, -223, -6, +-249, -42, -216, -89, -133, -97, -12, -29, +151, 52, 294, 102, 325, 124, 209, 76, +33, -8, -118, -51, -225, -63, -277, -55, +-247, -2, -127, 48, 36, 40, 149, 6, +160, -47, 128, -97, 100, -78, 59, 6, +-14, 87, -84, 155, -117, 176, -100, 105, +-63, -10, -56, -118, -49, -202, -2, -207, +64, -106, 91, 19, 77, 129, 36, 195, +12, 180, -2, 99, -49, 19, -102, -60, +-99, -120, -53, -107, -24, -60, -9, -27, +11, -12, 64, -17, 116, -30, 112, 10, +41, 76, -45, 120, -116, 153, -157, 159, +-146, 89, -85, -31, 20, -157, 135, -256, +190, -252, 130, -151, 5, -26, -111, 100, +-171, 228, -158, 291, -78, 256, 40, 150, +152, 0, 184, -141, 105, -230, -13, -280, +-111, -278, -164, -156, -165, 41, -115, 227, +-40, 349, 56, 363, 128, 245, 134, 39, +94, -205, 41, -410, -9, -443, -40, -273, +-64, 7, -94, 280, -85, 453, -49, 432, +-37, 230, -45, -71, -31, -354, 11, -476, +72, -357, 117, -81, 104, 206, 63, 399, +11, 401, -64, 210, -136, -72, -141, -315, +-91, -406, -12, -271, 58, 7, 66, 266, +21, 398, -2, 343, 2, 109, 1, -184, +11, -390, 16, -427, 3, -254, -27, 46, +-71, 314, -112, 432, -75, 374, 24, 152, +106, -129, 151, -329, 142, -376, 43, -254, +-110, -11, -241, 224, -315, 324, -247, 275, +-38, 95, 191, -129, 341, -289, 371, -319, +245, -205, 14, 33, -212, 283, -364, 401, +-367, 354, -201, 171, 6, -93, 133, -333, +179, -445, 135, -394, 37, -175, -25, 129, +-31, 369, -3, 452, 59, 372, 82, 152, +12, -130, -74, -350, -140, -426, -179, -312, +-138, -47, -36, 237, 43, 393, 113, 379, +156, 198, 113, -96, 32, -367, -47, -480, +-132, -368, -157, -67, -91, 294, -6, 528, +92, 538, 171, 322, 144, -43, 29, -405, +-99, -584, -234, -500, -294, -197, -195, 190, +-9, 468, 176, 505, 305, 310, 302, -12, +166, -321, -4, -450, -184, -345, -299, -74, +-265, 232, -142, 431, -8, 407, 121, 185, +184, -109, 141, -355, 57, -435, -52, -318, +-150, -78, -157, 172, -74, 355, 29, 383, +133, 247, 170, 32, 104, -168, -8, -286, +-133, -270, -231, -145, -223, 16, -106, 183, +21, 283, 124, 245, 177, 90, 152, -101, +74, -275, -27, -337, -117, -242, -135, -48, +-87, 192, -39, 396, -1, 434, 21, 277, +19, 19, 4, -268, -16, -448, -48, -419, +-48, -221, -3, 47, 49, 310, 76, 423, +63, 320, 14, 94, -42, -168, -94, -355, +-144, -347, -131, -161, -42, 74, 56, 300, +110, 416, 116, 333, 71, 109, 9, -166, +-52, -421, -111, -507, -127, -361, -88, -100, +-28, 204, 24, 468, 59, 552, 54, 420, +39, 147, 23, -215, -18, -497, -63, -531, +-68, -364, -50, -76, -34, 269, -21, 493, +-15, 474, 9, 271, 44, -68, 50, -394, +22, -491, -1, -346, -32, -81, -82, 241, +-122, 469, -121, 450, -55, 242, 65, -67, +163, -374, 167, -476, 95, -325, -24, -73, +-143, 207, -217, 409, -213, 391, -130, 194, +21, -60, 160, -310, 184, -404, 109, -254, +12, -18, -64, 205, -105, 370, -96, 355, +-49, 162, 24, -67, 68, -287, 34, -400, +-64, -289, -142, -58, -153, 157, -104, 329, +-4, 365, 101, 210, 182, 0, 215, -211, +157, -358, -11, -303, -187, -90, -267, 117, +-245, 283, -156, 344, -25, 220, 94, 15, +162, -182, 159, -335, 57, -318, -55, -110, +-79, 99, -36, 248, 5, 323, 34, 240, +28, 50, -17, -129, -71, -280, -134, -313, +-172, -159, -117, 29, 12, 159, 103, 257, +129, 267, 98, 161, 50, 24, 20, -139, +-14, -273, -73, -261, -97, -167, -59, -76, +-46, 63, -75, 224, -85, 297, -51, 281, +10, 159, 73, -50, 74, -209, 39, -268, +27, -282, 2, -191, -58, 13, -87, 197, +-58, 291, 2, 263, 75, 104, 78, -72, +-9, -160, -95, -202, -144, -172, -194, -31, +-183, 123, -66, 202, 102, 188, 247, 63, +295, -88, 202, -150, 34, -156, -114, -127, +-253, -24, -326, 108, -262, 181, -112, 183, +39, 95, 156, -43, 174, -122, 110, -130, +64, -113, 20, -50, -48, 61, -75, 143, +-56, 160, -43, 89, -27, -50, -51, -156, +-108, -163, -96, -115, -23, -23, 19, 114, +57, 223, 101, 241, 84, 139, 29, -52, +-45, -228, -144, -278, -179, -210, -97, -71, +-1, 108, 68, 264, 116, 306, 94, 204, +24, -2, -44, -206, -129, -287, -172, -218, +-91, -51, 3, 137, 36, 288, 41, 313, +12, 175, -42, -70, -48, -306, -31, -409, +-8, -321, 69, -87, 119, 190, 61, 419, +-37, 502, -132, 375, -215, 81, -195, -248, +-97, -478, 2, -505, 116, -332, 208, -51, +170, 236, 34, 429, -98, 433, -188, 239, +-173, -29, -69, -253, 31, -331, 102, -226, +140, -12, 64, 192, -91, 317, -203, 279, +-225, 64, -141, -204, 20, -388, 154, -403, +190, -226, 156, 72, 51, 331, -104, 467, +-213, 425, -212, 191, -117, -113, 33, -327, +138, -387, 138, -270, 74, -40, -21, 154, +-138, 234, -225, 193, -204, 43, -95, -134, +55, -199, 181, -138, 218, 16, 159, 197, +51, 281, -79, 226, -200, 95, -246, -69, +-199, -222, -85, -265, 47, -201, 135, -89, +126, 34, 62, 112, -18, 107, -105, 96, +-153, 97, -107, 71, 5, 50, 116, 35, +175, -6, 133, -58, 14, -95, -122, -118, +-234, -80, -289, 19, -225, 88, -72, 91, +100, 59, 232, -14, 248, -83, 145, -88, +6, -44, -106, 45, -173, 151, -163, 185, +-83, 104, 11, -23, 58, -152, 29, -229, +-60, -188, -127, -55, -123, 112, -76, 252, +1, 274, 100, 142, 167, -56, 161, -236, +87, -328, -47, -275, -174, -82, -223, 157, +-199, 364, -146, 439, -63, 320, 45, 83, +133, -167, 170, -355, 128, -416, 30, -320, +-59, -123, -118, 101, -167, 258, -166, 286, +-83, 209, 34, 109, 117, 16, 136, -55, +77, -74, -30, -59, -123, -34, -191, -35, +-199, -72, -107, -113, 45, -100, 171, -33, +218, 47, 149, 116, -3, 160, -151, 164, +-249, 123, -280, 31, -202, -75, -13, -135, +162, -138, 249, -104, 231, -62, 115, 0, +-42, 89, -182, 169, -285, 185, -291, 116, +-167, -4, 4, -129, 135, -228, 203, -278, +191, -228, 95, -42, -16, 222, -126, 413, +-204, 446, -181, 314, -76, 72, 22, -200, +76, -426, 68, -521, -5, -415, -86, -133, +-138, 165, -140, 348, -50, 385, 120, 309, +236, 170, 234, 23, 123, -101, -86, -145, +-299, -91, -404, -38, -369, -65, -195, -145, +76, -200, 308, -187, 391, -87, 307, 51, +101, 196, -139, 339, -282, 395, -298, 282, +-219, 59, -60, -162, 82, -304, 114, -327, +43, -264, -57, -154, -133, 0, -122, 161, +-22, 214, 99, 180, 180, 131, 195, 87, +96, 66, -84, 39, -241, -33, -323, -102, +-295, -115, -160, -121, 0, -126, 123, -75, +215, 26, 242, 120, 177, 173, 60, 130, +-60, 29, -165, -38, -225, -79, -238, -110, +-219, -92, -121, -15, 27, 64, 143, 122, +198, 119, 187, 59, 93, 24, -36, 20, +-141, -23, -206, -79, -194, -112, -85, -133, +32, -120, 72, -72, 55, -6, -17, 106, +-92, 259, -112, 320, -79, 242, -1, 92, +116, -97, 181, -262, 122, -334, -15, -314, +-169, -194, -292, 18, -315, 194, -214, 245, +-45, 210, 159, 149, 307, 77, 315, 40, +199, 19, 8, -11, -201, -17, -340, -44, +-359, -134, -269, -213, -90, -201, 114, -107, +238, 41, 223, 179, 124, 232, -14, 205, +-134, 138, -184, 15, -152, -98, -52, -108, +62, -48, 117, 26, 65, 60, -52, 6, +-169, -110, -234, -186, -209, -201, -78, -148, +89, 18, 229, 236, 283, 377, 194, 395, +-6, 259, -227, 8, -355, -219, -349, -345, +-211, -358, 7, -254, 213, -55, 313, 125, +260, 223, 64, 229, -163, 133, -306, 26, +-324, -14, -208, -19, -9, -10, 174, 18, +247, 16, 196, -30, 36, -87, -156, -135, +-261, -150, -234, -68, -113, 56, 53, 141, +173, 201, 183, 198, 101, 121, -60, 25, +-238, -67, -315, -151, -246, -169, -96, -124, +86, -81, 244, -35, 295, 44, 229, 110, +78, 163, -130, 194, -298, 145, -340, 48, +-285, -53, -157, -159, -1, -236, 123, -214, +189, -119, 198, 3, 119, 131, -15, 188, +-94, 151, -106, 99, -101, 51, -68, 15, +-31, 37, -20, 68, -17, 45, -65, -28, +-153, -141, -193, -277, -141, -324, -36, -219, +99, -19, 232, 235, 281, 450, 238, 497, +99, 369, -140, 120, -364, -198, -441, -444, +-385, -507, -217, -400, 17, -185, 229, 81, +355, 273, 351, 342, 193, 331, -52, 225, +-228, 71, -302, -43, -287, -110, -169, -152, +-7, -149, 110, -122, 154, -93, 87, -35, +-63, 38, -172, 73, -176, 99, -94, 122, +41, 98, 179, 64, 225, 27, 158, -26, +-13, -68, -258, -76, -435, -85, -416, -92, +-235, -60, 31, -12, 298, 41, 447, 107, +423, 135, 225, 120, -94, 93, -406, 27, +-545, -62, -472, -123, -253, -138, 32, -112, +266, -32, 369, 63, 340, 118, 174, 155, +-81, 147, -268, 66, -306, -32, -231, -107, +-111, -143, 10, -107, 86, -21, 104, 56, +56, 105, -54, 119, -142, 56, -130, -54, +-59, -126, 13, -135, 63, -60, 69, 73, +55, 173, 15, 198, -59, 149, -143, 23, +-172, -137, -128, -237, -71, -225, -24, -107, +29, 81, 82, 231, 110, 264, 65, 202, +-54, 59, -145, -118, -165, -243, -132, -250, +-78, -147, 9, 17, 117, 161, 166, 209, +119, 175, -26, 93, -189, -29, -263, -137, +-233, -174, -153, -138, -30, -45, 117, 49, +240, 107, 247, 128, 116, 128, -86, 95, +-245, 19, -280, -56, -244, -103, -153, -99, +8, -57, 172, -11, 243, 35, 173, 85, +-9, 105, -191, 72, -275, -6, -249, -73, +-155, -91, 2, -63, 190, -13, 285, 31, +239, 77, 51, 90, -193, 54, -343, -19, +-354, -93, -264, -105, -87, -55, 141, 15, +316, 77, 331, 113, 176, 114, -68, 68, +-277, -22, -347, -105, -304, -132, -161, -72, +64, 18, 260, 93, 319, 138, 203, 126, +-43, 61, -297, -41, -418, -151, -367, -206, +-193, -154, 59, -28, 319, 101, 439, 198, +352, 236, 85, 184, -237, 73, -443, -77, +-468, -208, -353, -232, -135, -163, 131, -58, +322, 49, 341, 136, 193, 170, -34, 160, +-220, 115, -260, 32, -184, -26, -66, -30, +68, -40, 151, -58, 117, -68, -32, -87, +-228, -82, -348, -53, -287, -24, -93, 18, +118, 102, 284, 159, 382, 151, 326, 118, +93, 49, -206, -41, -464, -94, -549, -139, +-424, -171, -181, -124, 92, -34, 345, 49, +472, 126, 399, 182, 155, 170, -148, 127, +-386, 52, -444, -72, -349, -143, -192, -139, +34, -106, 239, -35, 299, 51, 200, 81, +7, 73, -171, 43, -237, -30, -193, -83, +-96, -43, 29, 26, 153, 90, 165, 146, +31, 104, -148, -12, -301, -120, -320, -211, +-181, -236, 16, -114, 201, 90, 331, 268, +329, 376, 160, 328, -105, 114, -345, -117, +-463, -298, -398, -396, -210, -311, -10, -94, +193, 124, 317, 281, 285, 316, 141, 195, +-45, 35, -193, -61, -239, -124, -182, -108, +-90, -15, -6, 34, 59, 23, 50, -24, +-43, -124, -141, -179, -213, -109, -193, 25, +-71, 161, 71, 289, 187, 320, 259, 217, +243, 73, 96, -104, -119, -258, -310, -284, +-419, -216, -393, -130, -245, -14, -51, 92, +160, 137, 309, 168, 322, 180, 214, 130, +38, 87, -134, 63, -238, -20, -244, -109, +-196, -170, -117, -219, -18, -204, 42, -114, +26, -20, -16, 83, -48, 216, -50, 285, +-9, 257, 29, 189, 47, 66, 56, -79, +37, -168, -39, -239, -127, -267, -188, -186, +-207, -49, -161, 62, -53, 154, 57, 209, +144, 194, 192, 164, 142, 92, 13, -38, +-137, -124, -253, -146, -277, -157, -195, -130, +-63, -62, 71, 16, 172, 91, 190, 140, +100, 108, -30, 43, -143, 25, -220, 5, +-204, -13, -122, 1, -28, 17, 59, 28, +105, 32, 87, -16, 20, -84, -70, -86, +-153, -35, -185, 5, -125, 39, -25, 62, +72, 50, 161, 40, 155, 5, 52, -42, +-96, -30, -245, 32, -322, 76, -277, 63, +-125, 10, 58, -62, 211, -110, 280, -113, +218, -94, 68, -22, -112, 117, -275, 218, +-310, 227, -235, 149, -119, 25, 15, -93, +124, -174, 162, -211, 104, -194, -1, -75, +-108, 93, -162, 201, -121, 222, -53, 167, +2, 57, 59, -66, 56, -185, -3, -252, +-81, -203, -152, -33, -158, 154, -84, 251, +20, 257, 63, 166, 60, 15, 29, -149, +-51, -274, -133, -275, -178, -119, -156, 98, +-30, 244, 113, 273, 180, 204, 175, 61, +99, -98, -45, -214, -224, -248, -350, -142, +-378, 38, -274, 166, -62, 180, 153, 120, +306, 30, 370, -67, 302, -127, 113, -135, +-133, -74, -344, 55, -426, 148, -371, 135, +-227, 71, -57, -6, 110, -70, 220, -104, +209, -98, 107, -46, -6, 60, -69, 172, +-78, 187, -64, 124, -51, 34, -36, -76, +-47, -168, -100, -210, -179, -190, -213, -74, +-156, 107, -36, 237, 93, 251, 177, 191, +185, 72, 129, -87, 28, -205, -111, -258, +-206, -204, -201, -35, -118, 131, -38, 200, +-10, 183, -27, 108, -70, -14, -101, -115, +-115, -142, -90, -90, 17, 58, 147, 219, +211, 256, 192, 179, 77, 25, -88, -167, +-243, -320, -352, -368, -377, -289, -283, -76, +-79, 216, 125, 422, 259, 465, 300, 371, +230, 150, 106, -132, -44, -366, -209, -490, +-288, -434, -262, -197, -183, 98, -97, 316, +-21, 416, 47, 379, 77, 197, 86, -34, +46, -236, -18, -330, -27, -247, -19, -48, +-23, 140, -22, 259, -42, 265, -56, 143, +-62, -62, -98, -250, -156, -338, -178, -268, +-116, -48, -40, 179, 40, 328, 122, 352, +170, 227, 184, 9, 118, -215, -33, -350, +-172, -322, -259, -127, -285, 120, -250, 293, +-164, 338, -32, 239, 93, 26, 188, -188, +182, -320, 94, -296, 13, -114, -63, 128, +-119, 311, -132, 348, -101, 245, -33, 42, +12, -179, -26, -318, -120, -323, -194, -187, +-189, 25, -134, 201, -23, 272, 127, 216, +251, 82, 293, -67, 194, -171, -7, -171, +-207, -84, -324, 46, -340, 144, -276, 153, +-152, 73, 7, -40, 137, -121, 181, -134, +128, -61, 42, 74, -8, 186, -30, 224, +-48, 153, -65, -22, -55, -203, -38, -310, +-51, -294, -109, -146, -166, 86, -172, 294, +-125, 391, -46, 356, 34, 171, 116, -86, +178, -293, 176, -395, 88, -355, -58, -171, +-194, 50, -242, 225, -210, 322, -131, 310, +-39, 188, 53, 35, 101, -95, 52, -181, +-43, -161, -129, -81, -138, -11, -63, 57, +29, 91, 104, 49, 146, -19, 115, -76, +12, -107, -135, -66, -259, 43, -308, 130, +-251, 170, -114, 172, 11, 76, 131, -62, +217, -166, 218, -218, 150, -170, 19, -24, +-115, 113, -189, 178, -220, 183, -224, 106, +-189, -32, -87, -127, 32, -145, 98, -82, +124, 69, 80, 187, 17, 197, -26, 130, +-82, 3, -109, -154, -81, -256, -15, -257, +42, -176, 33, -8, -40, 168, -132, 240, +-171, 229, -154, 177, -124, 70, -19, -31, +110, -90, 180, -114, 170, -91, 52, -41, +-94, -41, -189, -84, -214, -89, -182, -65, +-98, -9, 25, 101, 113, 213, 124, 299, +63, 334, -59, 234, -139, 6, -146, -238, +-133, -413, -89, -477, -20, -397, 63, -192, +117, 71, 108, 345, 43, 508, -35, 475, +-89, 310, -141, 94, -187, -117, -174, -272, +-112, -335, -26, -309, 52, -204, 73, -64, +67, 30, 56, 84, 36, 157, -6, 220, +-46, 247, -61, 220, -58, 135, -62, 24, +-103, -88, -148, -196, -141, -274, -91, -246, +-41, -113, 7, 41, 53, 152, 101, 185, +125, 142, 91, 67, 6, -24, -75, -104, +-134, -115, -171, -32, -181, 83, -166, 145, +-90, 142, 23, 74, 112, -22, 125, -99, +73, -149, 2, -151, -72, -74, -140, 45, +-171, 116, -122, 110, 7, 59, 120, 2, +130, -20, 53, 5, -75, 35, -175, 85, +-221, 138, -198, 114, -84, -9, 84, -167, +219, -283, 214, -305, 77, -206, -95, -43, +-219, 141, -240, 323, -182, 407, -75, 327, +85, 146, 189, -64, 166, -228, 35, -284, +-121, -245, -191, -150, -173, -6, -105, 139, +-25, 185, 54, 144, 111, 71, 70, -9, +-42, -51, -136, -56, -167, -61, -95, -38, +4, 19, 71, 52, 121, 48, 134, 42, +95, 30, -32, 13, -177, 10, -256, -31, +-247, -81, -165, -78, -75, -56, 26, -44, +155, -14, 224, 26, 196, 62, 88, 106, +-44, 121, -131, 95, -179, 89, -186, 100, +-158, 59, -79, -7, 21, -88, 56, -181, +24, -229, -44, -230, -107, -188, -117, -64, +-93, 132, -30, 292, 86, 365, 196, 341, +229, 199, 137, 5, -25, -168, -190, -310, +-298, -347, -312, -240, -259, -66, -132, 92, +28, 191, 138, 203, 165, 138, 122, 55, +61, -34, 22, -95, 7, -63, 6, 17, +2, 75, 0, 95, -23, 54, -97, -22, +-194, -77, -265, -104, -260, -99, -180, -38, +-50, 56, 94, 102, 225, 86, 298, 10, +268, -96, 145, -153, -26, -134, -180, -52, +-259, 90, -252, 251, -181, 345, -77, 318, +16, 168, 69, -62, 44, -285, -25, -413, +-94, -427, -108, -311, -49, -87, 43, 157, +146, 343, 213, 406, 207, 339, 115, 190, +-54, 30, -233, -103, -352, -182, -372, -187, +-273, -143, -100, -92, 105, -63, 267, -68, +319, -72, 257, -38, 89, 24, -94, 105, +-212, 176, -237, 211, -167, 191, -57, 110, +46, -13, 95, -124, 53, -168, -31, -142, +-111, -72, -134, 18, -91, 84, -24, 102, +52, 73, 80, -13, 55, -110, -4, -161, +-90, -145, -140, -71, -134, 47, -62, 166, +52, 245, 135, 277, 159, 223, 107, 84, +-9, -77, -148, -218, -287, -309, -330, -309, +-264, -232, -112, -92, 79, 87, 219, 236, +294, 293, 277, 265, 169, 178, 15, 44, +-150, -76, -253, -151, -264, -175, -211, -120, +-116, -17, -35, 57, 40, 89, 87, 77, +73, 13, 26, -68, -35, -122, -54, -143, +-35, -105, -7, 7, 30, 108, 70, 163, +103, 183, 88, 151, 6, 84, -93, 22, +-183, -30, -230, -64, -222, -57, -166, -55, +-51, -97, 88, -146, 209, -174, 242, -167, +186, -72, 88, 78, -19, 227, -110, 348, +-162, 376, -156, 256, -93, 37, -22, -193, +-1, -372, -33, -407, -69, -283, -76, -78, +-61, 145, -13, 313, 49, 322, 117, 185, +156, -16, 121, -206, 25, -288, -81, -212, +-139, -36, -153, 161, -130, 327, -83, 360, +-26, 230, 30, 20, 41, -199, -8, -346, +-57, -338, -69, -212, -41, -41, 6, 136, +49, 233, 89, 193, 92, 68, 47, -62, +-60, -147, -165, -112, -194, 22, -152, 164, +-58, 272, 47, 290, 112, 163, 126, -61, +66, -287, -55, -442, -175, -445, -233, -279, +-185, -31, -83, 224, 46, 435, 162, 501, +226, 405, 227, 207, 120, -40, -52, -250, +-203, -350, -291, -345, -286, -263, -198, -107, +-51, 56, 120, 161, 224, 206, 227, 186, +114, 108, -49, 33, -164, -28, -206, -80, +-146, -83, -28, -42, 108, -6, 216, 16, +213, 27, 100, 11, -71, 0, -215, 19, +-265, 42, -243, 72, -143, 104, -2, 86, +131, 2, 222, -120, 208, -239, 128, -294, +32, -233, -44, -68, -81, 150, -103, 364, +-93, 471, -54, 404, -14, 192, 9, -95, +-20, -351, -58, -464, -72, -407, -69, -224, +-41, 18, -9, 221, 57, 293, 127, 226, +148, 84, 101, -61, 2, -123, -81, -74, +-127, 39, -137, 162, -103, 230, -36, 196, +35, 59, 54, -119, -11, -270, -120, -334, +-206, -281, -198, -147, -105, 10, 42, 147, +215, 221, 341, 215, 353, 157, 200, 84, +-63, 29, -316, 11, -444, 27, -420, 39, +-276, 29, -60, -8, 152, -83, 268, -175, +244, -246, 103, -260, -51, -192, -119, -46, +-87, 132, 5, 285, 86, 370, 129, 355, +91, 229, -30, 44, -183, -134, -290, -256, +-263, -281, -120, -219, 50, -114, 174, -9, +219, 62, 187, 72, 88, 34, -43, -11, +-131, -34, -149, -12, -89, 54, -9, 121, +42, 166, 82, 181, 96, 149, 84, 74, +34, -23, -48, -119, -124, -200, -172, -236, +-178, -229, -134, -181, -47, -75, 92, 63, +220, 180, 276, 254, 236, 265, 105, 196, +-28, 85, -137, -27, -198, -106, -186, -125, +-116, -82, -17, -35, 41, -22, 28, -51, +-23, -123, -78, -186, -78, -175, -29, -75, +44, 93, 141, 285, 198, 398, 202, 370, +121, 208, -25, -37, -156, -276, -232, -393, +-226, -349, -171, -178, -94, 49, -2, 219, +51, 255, 55, 160, 17, -11, -28, -182, +-16, -245, 26, -157, 92, 20, 141, 208, +138, 321, 92, 288, -24, 133, -166, -71, +-286, -250, -326, -316, -255, -235, -116, -66, +45, 99, 175, 199, 235, 187, 223, 76, +128, -61, 5, -166, -88, -183, -124, -79, +-100, 94, -61, 242, -15, 306, 17, 251, +23, 90, -4, -111, -58, -286, -100, -380, +-105, -338, -73, -181, -15, 14, 46, 184, +110, 280, 167, 278, 187, 204, 154, 92, +71, -21, -21, -87, -106, -93, -155, -70, +-174, -52, -153, -44, -84, -57, -8, -76, +57, -75, 92, -50, 105, 12, 115, 101, +122, 170, 115, 178, 80, 121, 22, 10, +-40, -122, -105, -221, -148, -243, -159, -169, +-117, -10, -11, 176, 100, 310, 175, 343, +183, 249, 125, 54, 15, -180, -121, -369, +-225, -445, -250, -370, -172, -163, -9, 100, +154, 326, 255, 443, 269, 413, 176, 258, +21, 41, -152, -160, -265, -278, -270, -283, +-178, -195, -42, -81, 59, 16, 95, 65, +75, 53, 12, 6, -49, -34, -78, -35, +-51, 11, 42, 92, 117, 163, 142, 187, +90, 153, -11, 64, -111, -59, -209, -169, +-255, -233, -230, -230, -130, -148, 14, -21, +123, 104, 183, 190, 193, 213, 158, 156, +102, 40, 6, -88, -65, -182, -92, -191, +-90, -104, -72, 33, -87, 164, -89, 237, +-71, 206, -42, 79, -1, -90, 33, -233, +88, -286, 138, -217, 143, -72, 113, 74, +47, 176, -3, 200, -26, 146, -48, 62, +-50, -2, -45, -16, -19, 23, -5, 66, +-13, 53, -22, -21, -18, -124, 21, -220, +62, -247, 84, -173, 100, -23, 97, 155, +71, 283, 19, 296, -47, 194, -81, 37, +-72, -116, -33, -202, -3, -185, 19, -94, +36, 20, 40, 104, 35, 103, 17, 22, +6, -77, 5, -144, -2, -145, -32, -68, +-71, 65, -89, 195, -68, 273, -15, 263, +45, 155, 84, -9, 105, -177, 89, -307, +20, -351, -68, -289, -145, -145, -163, 46, +-131, 231, -64, 346, 3, 356, 53, 266, +81, 94, 62, -108, 12, -263, -39, -327, +-64, -288, -40, -155, 12, 15, 48, 157, +57, 234, 24, 228, -44, 140, -128, 19, +-185, -79, -184, -134, -114, -126, 13, -69, +134, -4, 203, 47, 216, 66, 161, 49, +52, 12, -63, -19, -155, -37, -174, -39, +-125, -15, -36, 9, 55, 23, 110, 35, +127, 32, 83, 15, -1, 0, -84, -18, +-133, -30, -103, -26, -14, -12, 93, -6, +198, 5, 236, 24, 197, 32, 84, 29, +-59, 18, -150, 0, -173, -2, -101, 14, +-1, 23, 79, 26, 120, 26, 85, 0, +15, -48, -54, -96, -84, -125, -30, -111, +65, -48, 157, 34, 187, 111, 140, 165, +60, 169, -49, 111, -120, 25, -147, -59, +-119, -115, -41, -123, 11, -97, 32, -65, +14, -27, -21, 5, -29, 8, -14, 6, +34, 18, 88, 51, 122, 97, 125, 128, +65, 113, -23, 59, -120, -13, -190, -101, +-206, -168, -190, -172, -136, -119, -60, -31, +31, 62, 106, 116, 145, 125, 153, 100, +125, 43, 76, -26, 14, -67, -60, -65, +-111, -40, -124, -6, -110, 16, -88, 20, +-72, 16, -60, 9, -53, -7, -35, -9, +-19, 13, 13, 35, 74, 45, 138, 44, +171, 24, 148, -9, 89, -48, 9, -94, +-72, -122, -133, -113, -154, -68, -114, 5, +-24, 102, 62, 194, 107, 243, 101, 222, +58, 121, -6, -37, -65, -202, -75, -321, +-21, -350, 95, -262, 216, -79, 275, 136, +242, 305, 134, 377, -28, 330, -193, 187, +-302, 1, -305, -174, -192, -278, -14, -287, +167, -219, 283, -111, 321, 4, 286, 97, +181, 153, 44, 176, -80, 166, -156, 124, +-168, 68, -147, 1, -104, -78, -45, -143, +11, -173, 57, -163, 63, -111, 64, -28, +63, 52, 70, 114, 77, 150, 41, 145, +0, 103, -38, 46, -68, -19, -80, -76, +-84, -106, -49, -112, 3, -93, 39, -45, +48, 17, 9, 63, -25, 87, -64, 73, +-102, 13, -113, -55, -116, -100, -71, -113, +-2, -71, 67, 19, 129, 114, 160, 184, +169, 197, 116, 132, 4, 20, -122, -95, +-236, -192, -272, -234, -246, -196, -167, -107, +-29, 0, 109, 99, 220, 152, 253, 156, +218, 137, 143, 93, 52, 38, -20, 4, +-95, -11, -145, -33, -145, -63, -125, -103, +-84, -144, -31, -147, 36, -107, 121, -35, +186, 68, 211, 167, 178, 201, 123, 155, +53, 47, -25, -87, -81, -174, -103, -166, +-76, -81, -22, 62, 29, 200, 56, 242, +72, 161, 82, -13, 77, -212, 62, -334, +46, -314, 35, -172, 43, 33, 49, 228, +38, 314, 27, 253, 25, 100, 26, -58, +6, -138, -17, -97, -36, 18, -42, 130, +-38, 163, -37, 67, -23, -147, 17, -373, +70, -475, 97, -381, 92, -99, 64, 269, +15, 577, -47, 702, -104, 581, -138, 242, +-121, -183, -53, -530, 27, -675, 77, -581, +87, -304, 64, 29, 18, 294, -37, 415, +-86, 360, -96, 180, -71, -13, -37, -137, +-26, -153, -28, -71, -23, 50, -13, 143, +14, 155, 36, 71, 49, -76, 55, -219, +27, -294, -23, -273, -80, -155, -114, 18, +-92, 188, -45, 296, 24, 306, 82, 218, +123, 75, 139, -62, 86, -144, 8, -152, +-77, -97, -125, -18, -114, 35, -76, 26, +1, -44, 83, -142, 150, -221, 184, -226, +149, -126, 85, 60, 5, 278, -58, 430, +-72, 447, -64, 317, -9, 75, 56, -204, +114, -416, 145, -483, 124, -392, 88, -179, +31, 68, -24, 236, -56, 280, -69, 208, +-36, 66, 19, -65, 82, -107, 135, -46, +144, 82, 128, 200, 70, 221, -6, 117, +-74, -71, -114, -279, -91, -415, -34, -393, +42, -213, 104, 52, 127, 312, 104, 456, +33, 424, -50, 243, -111, -20, -125, -268, +-79, -388, -9, -339, 60, -166, 101, 69, +93, 270, 40, 343, -43, 280, -116, 109, +-156, -116, -138, -294, -75, -352, 0, -287, +70, -122, 113, 91, 114, 261, 80, 331, +26, 289, -36, 140, -79, -49, -104, -189, +-123, -244, -135, -207, -131, -87, -107, 49, +-57, 131, 20, 141, 108, 69, 188, -49, +232, -132, 208, -145, 110, -90, -27, 31, +-168, 162, -257, 229, -256, 205, -161, 96, +-14, -63, 130, -194, 224, -242, 225, -211, +151, -107, 47, 28, -38, 122, -65, 147, +-34, 114, 27, 41, 81, -25, 96, -46, +67, -32, -5, 2, -68, 43, -95, 57, +-70, 33, 14, -4, 106, -43, 185, -70, +214, -63, 183, -40, 106, -23, 2, -3, +-69, 8, -87, 5, -52, 14, 12, 40, +52, 64, 66, 79, 41, 70, -13, 21, +-55, -37, -74, -80, -29, -106, 50, -91, +133, -37, 182, 16, 167, 43, 122, 44, +35, 13, -58, -24, -125, -35, -160, -19, +-138, 21, -99, 78, -60, 101, -19, 66, +22, -5, 73, -80, 90, -122, 86, -99, +72, -21, 44, 75, 23, 152, -25, 153, +-74, 57, -107, -93, -129, -228, -137, -287, +-138, -231, -103, -67, -27, 151, 63, 345, +143, 429, 166, 348, 141, 131, 81, -134, +-16, -357, -110, -456, -174, -389, -160, -185, +-82, 75, 12, 290, 73, 373, 76, 303, +40, 130, -28, -68, -95, -219, -110, -264, +-45, -184, 80, -27, 201, 130, 252, 213, +218, 189, 119, 88, -4, -36, -121, -138, +-189, -180, -175, -144, -100, -53, -13, 34, +41, 73, 64, 48, 81, -13, 122, -59, +161, -57, 183, 2, 187, 102, 170, 204, +113, 245, 7, 187, -112, 40, -199, -147, +-208, -304, -147, -367, -53, -309, 59, -144, +173, 76, 253, 266, 268, 348, 208, 300, +106, 151, -3, -42, -87, -200, -142, -260, +-167, -205, -125, -54, -46, 119, 37, 233, +89, 238, 97, 134, 83, -48, 47, -233, +-2, -333, -56, -313, -75, -177, -37, 32, +14, 229, 59, 341, 75, 338, 61, 220, +35, 40, -26, -116, -91, -196, -138, -189, +-136, -105, -94, -5, -59, 47, -28, 31, +-12, -55, 14, -170, 42, -227, 52, -177, +75, -32, 98, 179, 102, 378, 65, 467, +-22, 398, -104, 180, -160, -124, -171, -390, +-148, -510, -103, -468, -16, -278, 58, -6, +114, 224, 134, 333, 123, 305, 116, 163, +91, -2, 46, -94, -20, -91, -84, -18, +-112, 89, -116, 151, -80, 106, -11, -15, +71, -166, 149, -277, 168, -276, 134, -166, +65, -7, -6, 147, -42, 238, -54, 220, +-23, 120, 37, -1, 95, -93, 125, -101, +106, -27, 62, 68, 16, 141, -14, 154, +-21, 76, -22, -67, -7, -214, 15, -318, +24, -328, 28, -216, 30, -35, 53, 170, +86, 349, 116, 427, 128, 366, 114, 200, +76, -29, 11, -250, -68, -372, -131, -369, +-160, -252, -147, -54, -90, 141, -16, 241, +58, 229, 113, 125, 129, -29, 104, -144, +65, -169, 26, -107, -1, 27, -12, 166, +-16, 231, -28, 201, -55, 95, -88, -53, +-125, -180, -131, -228, -112, -199, -68, -116, +-5, -15, 55, 53, 100, 72, 109, 64, +94, 42, 63, 28, 22, 50, -11, 92, +-53, 121, -89, 118, -103, 62, -101, -44, +-75, -151, -45, -227, -9, -246, 19, -187, +35, -64, 43, 76, 37, 192, 52, 248, +84, 219, 116, 132, 127, 25, 93, -74, +29, -128, -54, -126, -134, -93, -181, -55, +-177, -35, -105, -42, -4, -57, 95, -55, +180, -18, 226, 54, 242, 147, 203, 216, +127, 220, 34, 142, -52, -1, -106, -161, +-139, -280, -131, -310, -81, -240, -6, -91, +73, 88, 115, 227, 135, 275, 134, 236, +107, 131, 65, 6, 7, -92, -23, -135, +-23, -124, -2, -79, 27, -27, 40, -2, +57, -10, 50, -35, 12, -63, -37, -72, +-76, -41, -69, 19, -33, 92, 11, 161, +54, 195, 76, 174, 78, 104, 44, -9, +-11, -139, -49, -230, -61, -256, -37, -214, +-15, -103, -6, 41, -4, 160, -7, 219, +-17, 202, -36, 113, -38, 1, -7, -84, +32, -122, 47, -93, 29, -14, -7, 58, +-35, 83, -58, 50, -68, -37, -59, -128, +-24, -167, 21, -146, 45, -67, 42, 60, +24, 174, 6, 222, -11, 198, -27, 104, +-47, -21, -46, -107, -33, -145, -12, -138, +8, -80, 29, -6, 62, 33, 86, 35, +88, 11, 63, -25, 28, -32, 5, -4, +-16, 31, -39, 80, -47, 125, -43, 116, +-15, 56, 15, -33, 42, -124, 66, -179, +87, -174, 103, -125, 81, -39, 48, 72, +20, 151, 6, 167, 16, 136, 31, 67, +45, -11, 60, -62, 59, -82, 25, -71, +-32, -25, -74, 15, -87, 14, -73, -11, +-21, -45, 40, -73, 116, -60, 172, -13, +182, 43, 141, 101, 63, 135, -21, 107, +-97, 33, -136, -46, -136, -113, -96, -143, +-22, -115, 33, -53, 55, 23, 57, 99, +43, 133, 29, 116, 16, 62, 18, -16, +20, -91, 18, -133, 7, -133, -30, -96, +-52, -17, -56, 74, -49, 141, -35, 172, +-23, 149, -9, 70, -6, -28, -14, -113, +-25, -168, -33, -167, -15, -107, 16, -30, +49, 37, 84, 83, 96, 84, 91, 56, +51, 29, -13, 3, -82, -1, -141, 26, +-163, 53, -155, 58, -105, 40, -17, -6, +75, -66, 148, -111, 181, -131, 170, -120, +134, -63, 78, 18, 23, 90, -27, 141, +-57, 155, -67, 122, -79, 60, -81, -15, +-73, -89, -46, -130, -5, -119, 43, -77, +87, -23, 128, 32, 153, 60, 147, 56, +112, 29, 66, -17, 27, -51, -10, -44, +-39, -6, -62, 39, -66, 81, -50, 100, +-34, 75, -23, 24, -6, -42, 15, -102, +39, -116, 53, -88, 72, -47, 104, 0, +133, 44, 148, 56, 117, 42, 54, 21, +-33, -1, -127, 0, -202, 28, -241, 58, +-210, 70, -114, 57, 12, 6, 128, -72, +199, -141, 226, -178, 208, -162, 139, -75, +43, 48, -56, 158, -116, 229, -145, 228, +-158, 150, -150, 27, -124, -101, -73, -186, +-27, -195, 7, -134, 44, -46, 88, 40, +130, 94, 144, 81, 123, 22, 78, -38, +12, -75, -58, -65, -121, -5, -150, 69, +-126, 128, -61, 150, 7, 117, 38, 35, +48, -56, 40, -132, 26, -174, 14, -167, +15, -123, 45, -59, 87, 15, 116, 77, +104, 115, 50, 139, -10, 145, -64, 117, +-101, 70, -104, 13, -78, -48, -11, -101, +57, -136, 101, -153, 110, -141, 101, -97, +94, -40, 65, 30, 29, 107, -1, 170, +-14, 193, -6, 170, -3, 94, -6, -21, +5, -127, 21, -197, 30, -211, 18, -148, +-6, -31, -23, 85, -24, 156, -1, 166, +18, 113, 56, 30, 106, -46, 136, -93, +120, -90, 53, -42, -35, 5, -110, 24, +-152, 10, -154, -24, -112, -47, -27, -34, +69, 12, 117, 73, 116, 125, 82, 120, +36, 46, -7, -61, -46, -159, -66, -202, +-56, -154, -24, -36, -1, 101, 1, 206, +-6, 230, -7, 151, -12, 10, -13, -130, +-23, -217, -27, -211, -15, -117, -10, 12, +-14, 129, -16, 193, 0, 174, 28, 91, +45, -11, 46, -96, 34, -138, 13, -122, +-7, -77, -43, -33, -69, 10, -69, 41, +-48, 58, -10, 73, 25, 82, 60, 78, +85, 62, 98, 23, 88, -44, 58, -117, +31, -156, 9, -149, -18, -89, -40, 12, +-56, 113, -48, 178, -12, 184, 25, 121, +56, 11, 77, -97, 96, -169, 93, -186, +70, -138, 35, -48, 9, 43, 6, 112, +14, 134, 19, 104, 18, 49, 17, -3, +4, -36, -21, -48, -33, -41, -16, -28, +23, -16, 69, -10, 92, -17, 87, -25, +61, -16, 19, 1, -29, 17, -66, 31, +-67, 38, -43, 29, -5, 15, 23, 2, +33, -7, 35, 0, 26, 15, 9, 18, +-12, 10, -25, -7, -18, -31, -8, -55, +4, -67, 12, -63, 0, -38, -15, 4, +-45, 35, -78, 55, -93, 71, -78, 75, +-27, 67, 37, 54, 105, 32, 144, 0, +130, -30, 60, -64, -58, -97, -173, -108, +-229, -96, -212, -71, -117, -25, 21, 28, +159, 74, 239, 112, 223, 127, 122, 107, +-32, 68, -167, 27, -232, -22, -206, -63, +-98, -82, 46, -89, 161, -83, 202, -63, +159, -46, 64, -24, -29, 14, -79, 51, +-74, 80, -35, 104, 21, 102, 55, 67, +45, 16, 7, -46, -27, -101, -23, -113, +33, -83, 110, -27, 174, 47, 190, 97, +140, 91, 30, 38, -109, -45, -211, -134, +-234, -175, -163, -139, -22, -48, 146, 76, +290, 198, 356, 254, 314, 230, 172, 137, +-21, -13, -189, -164, -279, -257, -280, -279, +-187, -227, -38, -107, 117, 34, 214, 152, +227, 228, 168, 233, 70, 173, -22, 85, +-86, -15, -104, -105, -72, -152, -15, -154, +29, -120, 39, -58, 13, 7, -26, 46, +-57, 64, -68, 66, -55, 42, -11, 15, +47, -1, 78, -13, 66, -15, 9, -8, +-56, -8, -99, -8, -99, 6, -67, 21, +-10, 30, 62, 39, 102, 32, 85, 3, +20, -29, -68, -73, -142, -109, -172, -108, +-149, -75, -69, -25, 47, 43, 160, 114, +205, 161, 182, 170, 105, 132, -5, 49, +-107, -50, -180, -142, -200, -210, -160, -221, +-71, -160, 32, -54, 110, 66, 159, 170, +163, 218, 124, 196, 70, 124, 7, 20, +-39, -80, -50, -134, -38, -139, -15, -109, +9, -62, 32, -18, 31, 12, 16, 33, +9, 40, 19, 40, 53, 55, 96, 74, +113, 73, 97, 42, 54, -16, -7, -87, +-57, -142, -75, -154, -47, -122, 17, -49, +99, 52, 152, 140, 146, 181, 93, 174, +16, 118, -66, 33, -116, -51, -112, -122, +-66, -164, 14, -163, 92, -126, 132, -69, +121, -1, 78, 64, 17, 109, -43, 130, +-69, 125, -61, 94, -29, 51, 9, 10, +17, -29, -10, -56, -47, -72, -72, -84, +-67, -94, -32, -95, 35, -85, 93, -55, +121, 2, 102, 70, 26, 130, -69, 169, +-148, 169, -177, 116, -150, 28, -75, -66, +11, -141, 79, -171, 113, -147, 99, -86, +48, -10, -8, 54, -60, 80, -100, 64, +-113, 27, -92, -14, -39, -34, 20, -12, +71, 32, 90, 74, 74, 103, 34, 93, +-17, 34, -57, -51, -73, -133, -61, -178, +-36, -158, -4, -79, 24, 21, 40, 116, +51, 167, 62, 146, 60, 71, 54, -23, +45, -104, 30, -126, 6, -75, -18, 10, +-31, 88, -27, 125, -4, 95, 19, 4, +39, -105, 61, -181, 76, -186, 80, -104, +75, 22, 57, 135, 23, 202, -15, 187, +-40, 92, -48, -32, -25, -131, 40, -168, +109, -118, 149, -10, 138, 90, 73, 139, +-19, 120, -102, 29, -146, -85, -130, -169, +-49, -189, 62, -123, 149, 5, 190, 128, +175, 203, 105, 210, 13, 140, -73, 21, +-127, -94, -134, -168, -97, -179, -48, -127, +-15, -50, 4, 20, 12, 72, 24, 87, +53, 63, 87, 31, 102, 9, 98, -2, +58, 6, -21, 24, -112, 25, -180, 15, +-207, -3, -180, -40, -93, -74, 24, -82, +135, -66, 202, -22, 187, 42, 91, 89, +-35, 101, -148, 81, -209, 21, -198, -61, +-117, -119, -1, -133, 105, -88, 171, 12, +154, 124, 78, 195, -20, 198, -116, 122, +-170, -26, -153, -182, -78, -283, 21, -293, +107, -192, 146, -12, 124, 173, 65, 299, +-1, 322, -58, 229, -70, 63, -39, -107, +14, -226, 55, -251, 63, -182, 31, -70, +-19, 32, -42, 89, -29, 83, 24, 32, +103, -14, 157, -25, 144, 1, 75, 56, +-30, 103, -126, 103, -153, 48, -93, -39, +20, -127, 145, -168, 226, -134, 216, -52, +136, 53, 27, 138, -84, 158, -160, 108, +-171, 18, -129, -78, -52, -140, 49, -136, +134, -77, 185, 6, 208, 85, 183, 129, +111, 122, 18, 78, -76, 17, -156, -45, +-199, -87, -188, -101, -133, -96, -35, -76, +78, -42, 148, -5, 165, 38, 147, 81, +105, 105, 49, 106, -4, 85, -53, 44, +-92, -14, -110, -63, -113, -93, -112, -103, +-82, -84, -28, -52, 15, -18, 45, 19, +63, 47, 66, 61, 53, 65, 30, 60, +-16, 45, -55, 27, -58, 1, -38, -36, +-17, -65, 5, -76, 22, -71, 17, -42, +-13, 6, -65, 46, -113, 66, -124, 66, +-92, 37, -37, -7, 42, -38, 135, -45, +202, -30, 214, 7, 162, 46, 51, 57, +-73, 37, -165, -14, -228, -78, -236, -115, +-176, -104, -61, -54, 65, 27, 169, 111, +224, 155, 224, 145, 186, 84, 114, -18, +22, -117, -46, -170, -66, -174, -68, -123, +-77, -27, -97, 72, -103, 136, -79, 158, +-13, 130, 68, 64, 145, -8, 209, -74, +219, -113, 155, -108, 47, -69, -53, -23, +-114, 26, -124, 56, -95, 57, -39, 37, +34, 7, 99, -24, 110, -36, 65, -28, +8, -16, -27, 1, -34, 21, -19, 29, +11, 25, 42, 27, 71, 25, 73, 17, +40, 8, -2, -15, -33, -52, -53, -83, +-63, -99, -54, -85, -29, -27, 11, 55, +45, 129, 46, 175, 16, 164, -2, 88, +-9, -15, -15, -114, -18, -183, -8, -189, +10, -133, 21, -47, 17, 45, -15, 111, +-39, 120, -37, 88, -33, 46, -40, 10, +-33, -12, -14, -11, 5, -5, 16, -8, +16, -18, 10, -39, 21, -61, 33, -57, +16, -30, -5, 6, -20, 43, -34, 61, +-47, 44, -49, 5, -43, -28, -21, -44, +14, -24, 33, 26, 41, 75, 54, 98, +60, 77, 38, 2, 3, -103, -35, -184, +-59, -208, -50, -152, -18, -27, 13, 122, +40, 239, 57, 281, 54, 220, 46, 75, +42, -92, 36, -223, 19, -275, -7, -227, +-50, -102, -81, 37, -66, 147, -19, 192, +35, 162, 90, 89, 126, 16, 121, -34, +87, -52, 33, -46, -27, -42, -64, -53, +-61, -72, -38, -89, -5, -79, 20, -21, +15, 60, -7, 131, -19, 168, -9, 146, +24, 65, 87, -40, 144, -126, 160, -162, +130, -128, 51, -45, -70, 42, -183, 97, +-244, 99, -237, 47, -144, -22, 15, -67, +177, -73, 282, -28, 301, 45, 208, 100, +51, 107, -107, 71, -221, -1, -258, -81, +-194, -126, -70, -120, 46, -73, 128, -2, +145, 56, 95, 78, 26, 68, -29, 35, +-59, 1, -44, -11, 4, 1, 39, 21, +30, 40, -14, 42, -80, 12, -125, -32, +-107, -67, -41, -90, 53, -90, 143, -56, +179, -11, 129, 33, 27, 71, -82, 86, +-165, 86, -192, 83, -158, 66, -80, 27, +35, -19, 151, -73, 206, -129, 183, -157, +98, -148, -13, -101, -109, -11, -146, 95, +-125, 177, -66, 211, 15, 183, 70, 95, +73, -17, 44, -111, 12, -171, -15, -176, +-21, -128, 2, -60, 41, 7, 84, 59, +109, 76, 79, 69, 6, 56, -67, 39, +-120, 23, -136, 19, -98, 16, -18, 11, +76, 5, 164, -12, 196, -37, 155, -61, +67, -85, -36, -102, -126, -94, -160, -54, +-110, 11, -7, 93, 104, 168, 173, 204, +155, 180, 67, 95, -33, -33, -121, -159, +-161, -234, -125, -230, -27, -149, 88, -20, +180, 98, 213, 164, 162, 164, 63, 96, +-52, -3, -150, -77, -191, -88, -155, -44, +-63, 32, 47, 92, 129, 96, 145, 45, +99, -41, 31, -128, -31, -166, -60, -133, +-36, -45, 13, 71, 48, 160, 49, 178, +16, 122, -49, 26, -110, -74, -133, -139, +-110, -135, -33, -71, 82, 19, 180, 97, +207, 130, 153, 102, 31, 28, -100, -61, +-185, -133, -200, -154, -153, -117, -62, -42, +34, 51, 97, 128, 118, 157, 108, 134, +74, 75, 27, -3, -11, -74, -46, -108, +-64, -102, -59, -62, -47, -9, -38, 26, +-23, 24, -3, -1, 12, -36, 25, -63, +30, -49, 25, 7, 29, 82, 49, 150, +59, 176, 55, 129, 28, 28, -22, -96, +-76, -208, -109, -257, -110, -217, -71, -107, +5, 41, 80, 177, 127, 241, 146, 215, +134, 119, 88, -14, 21, -129, -47, -172, +-100, -136, -117, -42, -91, 70, -43, 135, +15, 124, 70, 49, 95, -62, 89, -166, +65, -200, 35, -149, 12, -33, 10, 108, +14, 215, 12, 235, 11, 171, 10, 55, +-4, -78, -24, -164, -41, -169, -52, -111, +-30, -32, 25, 31, 81, 44, 116, 10, +121, -33, 81, -60, 8, -46, -58, 22, +-94, 110, -88, 172, -51, 184, -3, 128, +28, 17, 52, -102, 71, -194, 63, -236, +28, -206, -13, -118, -43, -9, -50, 100, +-31, 179, -8, 200, 9, 168, 18, 96, +14, -7, -11, -99, -21, -145, -7, -138, +17, -76, 36, 21, 30, 103, -3, 127, +-43, 87, -74, -14, -96, -133, -86, -201, +-34, -183, 40, -83, 106, 73, 130, 218, +98, 283, 34, 245, -33, 117, -98, -55, +-143, -197, -137, -252, -85, -215, -15, -111, +56, 10, 104, 90, 116, 108, 95, 78, +44, 18, -28, -30, -79, -32, -79, 3, +-48, 55, -10, 105, 17, 119, 24, 84, +26, 18, 30, -66, 25, -146, 17, -189, +20, -183, 24, -133, 5, -39, -19, 74, +-27, 167, -9, 220, 34, 209, 62, 130, +60, 14, 38, -92, 18, -157, -5, -158, +-18, -100, -10, -23, 7, 38, 24, 60, +32, 34, 17, -18, -7, -56, -6, -59, +8, -18, 22, 56, 42, 122, 75, 139, +99, 102, 91, 23, 43, -70, -31, -134, +-86, -140, -97, -97, -80, -21, -46, 51, +6, 80, 49, 66, 70, 18, 78, -45, +74, -78, 63, -53, 60, 10, 49, 81, +12, 135, -39, 135, -83, 71, -116, -29, +-129, -134, -104, -203, -50, -193, 25, -109, +98, 9, 132, 122, 120, 193, 89, 189, +46, 118, -11, 16, -68, -80, -115, -129, +-137, -119, -117, -75, -69, -22, -25, 24, +11, 44, 36, 42, 45, 29, 36, 19, +30, 17, 45, 16, 70, 4, 81, -25, +44, -53, -37, -62, -122, -42, -169, 1, +-168, 51, -113, 76, -17, 67, 83, 27, +148, -35, 158, -84, 121, -90, 65, -44, +14, 32, -33, 95, -77, 105, -108, 61, +-106, -18, -77, -99, -33, -135, 9, -101, +54, -15, 111, 79, 155, 142, 151, 139, +98, 66, 29, -36, -49, -121, -118, -153, +-149, -118, -126, -37, -52, 55, 47, 120, +118, 134, 144, 93, 141, 31, 123, -27, +83, -74, 23, -87, -37, -72, -87, -50, +-96, -19, -89, 19, -77, 45, -36, 54, +39, 53, 114, 34, 152, 2, 148, -22, +104, -28, 38, -17, -30, 16, -91, 48, +-122, 49, -92, 16, -35, -39, 9, -101, +31, -132, 42, -102, 43, -24, 36, 76, +26, 157, 8, 177, 0, 125, 13, 26, +19, -74, -3, -127, -28, -108, -45, -38, +-57, 35, -62, 70, -57, 39, -38, -45, +1, -129, 44, -162, 57, -110, 53, 21, +46, 173, 25, 273, -19, 279, -66, 173, +-99, -7, -96, -180, -56, -279, -10, -277, +24, -183, 53, -48, 59, 66, 23, 130, +-27, 137, -52, 103, -38, 67, 3, 55, +38, 58, 25, 62, -13, 46, -42, -11, +-52, -93, -39, -159, -2, -181, 47, -147, +69, -60, 60, 41, 21, 117, -27, 149, +-46, 131, -32, 80, -9, 32, 18, 5, +38, -4, 34, -5, 14, -20, -12, -58, +-27, -100, -12, -129, 36, -127, 76, -68, +82, 37, 56, 143, 12, 204, -33, 192, +-56, 108, -50, -19, -15, -135, 39, -200, +72, -181, 72, -78, 49, 48, 20, 141, +-1, 162, -5, 101, 8, -12, 25, -119, +36, -166, 23, -132, -15, -22, -42, 110, +-35, 188, -1, 174, 43, 75, 69, -65, +67, -175, 33, -200, -10, -127, -47, 6, +-65, 141, -45, 203, -8, 152, 24, 27, +43, -111, 49, -197, 45, -182, 34, -73, +5, 74, -40, 185, -85, 201, -100, 108, +-82, -37, -33, -156, 38, -190, 92, -119, +104, 17, 69, 138, 10, 178, -50, 112, +-78, -28, -72, -168, -49, -227, -22, -172, +-2, -22, 2, 149, 0, 256, 4, 248, +7, 132, 17, -42, 33, -195, 43, -250, +32, -187, -1, -49, -61, 93, -122, 165, +-138, 134, -94, 29, -5, -83, 104, -141, +185, -108, 188, 15, 115, 160, -9, 246, +-129, 223, -188, 79, -155, -134, -60, -317, +47, -388, 114, -302, 107, -78, 44, 192, +-30, 395, -60, 445, -24, 309, 65, 47, +141, -217, 155, -371, 101, -354, -8, -176, +-129, 75, -205, 268, -203, 306, -120, 165, +16, -89, 145, -310, 219, -366, 222, -223, +166, 72, 63, 389, -41, 554, -103, 470, +-103, 155, -59, -260, -14, -589, 0, -671, +-15, -464, -38, -66, -56, 354, -41, 598, +15, 558, 100, 272, 177, -112, 204, -402, +151, -449, 40, -239, -73, 101, -155, 385, +-195, 456, -186, 258, -118, -119, -13, -486, +86, -659, 144, -527, 148, -132, 95, 354, +18, 705, -56, 761, -94, 500, -68, 42, +15, -404, 94, -650, 102, -598, 39, -292, +-66, 97, -158, 370, -193, 405, -156, 207, +-56, -98, 77, -327, 175, -345, 194, -148, +135, 177, 40, 467, -47, 547, -100, 359, +-107, -16, -88, -410, -43, -640, 4, -594, +20, -312, 3, 70, -22, 402, -28, 548, +-13, 445, 7, 163, 29, -143, 53, -335, +68, -339, 68, -178, 36, 44, -7, 229, +-34, 302, -38, 220, -45, 19, -68, -205, +-84, -345, -72, -342, -26, -203, 41, 14, +107, 231, 150, 378, 156, 394, 95, 267, +-15, 38, -111, -210, -140, -369, -95, -382, +-9, -255, 64, -36, 87, 195, 74, 341, +33, 327, -29, 161, -63, -78, -34, -279, +29, -330, 88, -219, 105, -8, 72, 219, +9, 359, -56, 325, -102, 121, -115, -146, +-67, -350, 34, -391, 133, -241, 177, 17, +143, 268, 44, 408, -63, 357, -144, 117, +-169, -188, -113, -406, 2, -440, 108, -267, +143, 32, 111, 315, 40, 471, -23, 430, +-56, 193, -62, -130, -46, -384, -3, -459, +40, -335, 49, -78, 18, 178, -27, 330, +-55, 323, -63, 159, -60, -71, -45, -236, +10, -252, 84, -117, 134, 91, 124, 250, +52, 279, -49, 176, -135, -33, -182, -267, +-177, -390, -95, -332, 41, -120, 164, 153, +192, 362, 129, 407, 24, 290, -79, 69, +-145, -190, -144, -370, -83, -373, 22, -212, +119, 26, 135, 232, 62, 324, -47, 276, +-120, 125, -127, -75, -66, -252, 32, -316, +131, -234, 182, -51, 130, 142, -4, 261, +-134, 275, -191, 189, -164, 25, -68, -166, +44, -298, 135, -291, 180, -147, 166, 66, +85, 243, -13, 314, -75, 269, -101, 108, +-109, -125, -116, -323, -91, -377, -13, -253, +88, -15, 152, 227, 165, 363, 129, 355, +56, 213, -37, -29, -120, -266, -159, -379, +-110, -314, 14, -122, 118, 93, 152, 239, +118, 269, 38, 202, -70, 66, -154, -91, +-169, -189, -82, -183, 88, -95, 230, 14, +251, 83, 148, 95, -21, 76, -188, 48, +-273, 2, -243, -47, -101, -64, 109, -50, +278, -24, 294, -11, 170, -2, -4, 27, +-156, 75, -232, 99, -213, 64, -121, -1, +7, -69, 131, -123, 183, -147, 150, -119, +77, -25, 6, 104, -59, 204, -107, 206, +-126, 106, -94, -28, -9, -148, 67, -211, +86, -180, 48, -64, -5, 90, -65, 201, +-106, 205, -97, 84, -27, -88, 84, -208, +181, -221, 191, -125, 94, 41, -47, 219, +-175, 320, -253, 275, -246, 90, -131, -160, +46, -345, 210, -378, 276, -263, 204, -49, +48, 191, -105, 377, -191, 416, -187, 277, +-96, 23, 30, -232, 133, -381, 159, -376, +88, -232, -34, -3, -104, 231, -96, 377, +-48, 356, 15, 176, 54, -75, 48, -279, +20, -349, -1, -265, -18, -67, -5, 158, +39, 316, 67, 328, 44, 179, -8, -53, +-64, -253, -74, -325, -23, -247, 36, -70, +76, 130, 90, 267, 55, 284, -35, 175, +-115, -9, -146, -182, -100, -266, 39, -227, +194, -103, 259, 53, 228, 190, 119, 253, +-71, 217, -256, 96, -338, -65, -277, -214, +-97, -289, 142, -247, 295, -107, 293, 87, +174, 268, -9, 347, -178, 284, -238, 99, +-157, -138, 11, -327, 192, -367, 267, -234, +179, -5, -10, 223, -201, 347, -342, 302, +-359, 112, -217, -130, 25, -302, 275, -322, +434, -169, 418, 72, 227, 267, -24, 333, +-250, 240, -392, 34, -391, -187, -228, -319, +14, -312, 220, -179, 302, 27, 225, 207, +51, 281, -120, 238, -212, 115, -194, -26, +-57, -140, 121, -191, 248, -175, 252, -103, +114, 3, -96, 89, -259, 133, -315, 146, +-267, 118, -113, 40, 94, -67, 249, -155, +294, -193, 236, -156, 86, -40, -80, 106, +-183, 229, -203, 275, -143, 201, -21, 22, +98, -183, 153, -322, 133, -333, 39, -187, +-79, 57, -157, 288, -167, 407, -104, 343, +36, 103, 177, -215, 237, -457, 213, -497, +120, -310, -20, 44, -137, 405, -175, 614, +-155, 582, -83, 287, 14, -166, 66, -581, +53, -763, 27, -636, 9, -253, 16, 231, +57, 616, 109, 761, 139, 604, 124, 205, +49, -255, -75, -573, -162, -621, -184, -409, +-155, -49, -82, 284, 9, 448, 80, 395, +123, 148, 141, -169, 110, -390, 55, -402, +20, -193, -1, 126, -47, 401, -78, 497, +-72, 378, -41, 99, -13, -243, -7, -496, +-29, -549, -53, -377, -44, -54, -23, 262, +6, 440, 65, 424, 138, 265, 161, 33, +100, -187, -22, -297, -123, -265, -152, -123, +-118, 46, -68, 156, -13, 168, 41, 108, +45, 28, -3, -58, -67, -132, -85, -160, +-19, -134, 102, -49, 183, 63, 177, 159, +112, 208, 6, 212, -133, 164, -269, 29, +-315, -162, -217, -320, -12, -354, 178, -231, +277, -12, 272, 224, 178, 377, 27, 384, +-130, 226, -239, -65, -229, -359, -79, -496, +91, -389, 165, -94, 146, 248, 88, 497, +-2, 536, -89, 349, -135, 9, -108, -369, +-1, -612, 123, -580, 156, -287, 91, 101, +3, 423, -72, 559, -115, 454, -117, 186, +-71, -142, 35, -416, 178, -481, 235, -274, +159, 66, 42, 337, -61, 442, -162, 326, +-237, 21, -238, -322, -159, -571, 8, -598, +205, -316, 314, 176, 306, 617, 244, 816, +116, 707, -91, 299, -291, -244, -381, -701, +-317, -920, -125, -780, 89, -304, 221, 281, +274, 702, 246, 821, 120, 622, -60, 199, +-187, -244, -204, -562, -113, -653, 30, -443, +116, -42, 123, 324, 106, 498, 39, 446, +-111, 210, -240, -99, -259, -356, -155, -497, +41, -429, 248, -138, 351, 222, 322, 487, +180, 560, -75, 417, -346, 107, -473, -245, +-379, -537, -117, -662, 179, -504, 356, -113, +361, 326, 233, 643, 18, 698, -201, 473, +-301, 83, -244, -333, -97, -655, 74, -722, +168, -461, 155, -10, 102, 430, 51, 677, +-30, 627, -108, 333, -127, -74, -102, -461, +-56, -679, 6, -587, 65, -222, 123, 234, +182, 589, 165, 675, 54, 464, -96, 71, +-216, -364, -250, -681, -161, -718, -2, -415, +162, 91, 296, 579, 311, 831, 147, 704, +-102, 268, -287, -285, -344, -753, -232, -934, +11, -714, 255, -150, 388, 513, 378, 974, +194, 1017, -114, 626, -372, -19, -459, -674, +-350, -1074, -93, -1041, 201, -572, 400, 151, +455, 799, 342, 1095, 82, 935, -207, 413, +-388, -254, -413, -800, -275, -979, -22, -746, +215, -214, 349, 395, 357, 784, 222, 791, +-31, 460, -255, -53, -345, -548, -301, -784, +-141, -635, 77, -211, 257, 309, 336, 711, +297, 779, 132, 501, -95, 30, -281, -462, +-354, -794, -304, -774, -144, -406, 71, 102, +277, 554, 387, 765, 322, 646, 106, 280, +-159, -170, -362, -561, -423, -731, -299, -550, +-44, -131, 251, 299, 468, 590, 489, 646, +277, 449, -66, 86, -396, -316, -586, -621, +-545, -682, -296, -448, 93, -61, 485, 302, +695, 540, 602, 586, 275, 442, -152, 151, +-529, -188, -677, -447, -533, -504, -188, -348, +245, -109, 594, 106, 648, 247, 388, 305, +-25, 262, -425, 105, -657, -98, -579, -238, +-227, -245, 235, -149, 639, -24, 784, 111, +573, 240, 131, 331, -349, 303, -712, 109, +-794, -166, -553, -403, -117, -519, 347, -485, +677, -279, 704, 76, 454, 463, 104, 733, +-243, 739, -490, 444, -510, -19, -305, -457, +-14, -731, 262, -755, 408, -486, 333, -36, +108, 398, -139, 656, -361, 618, -454, 314, +-306, -77, 14, -377, 357, -502, 575, -402, +559, -90, 306, 258, -51, 475, -406, 480, +-653, 248, -649, -112, -381, -430, 12, -594, +384, -548, 603, -262, 577, 170, 367, 531, +69, 699, -265, 628, -513, 319, -527, -112, +-329, -507, -34, -739, 260, -713, 431, -401, +409, 62, 227, 479, -47, 733, -325, 721, +-451, 431, -366, -22, -131, -481, 148, -770, +357, -747, 408, -402, 317, 90, 111, 541, +-165, 797, -367, 724, -390, 348, -261, -181, +-47, -664, 192, -876, 334, -699, 321, -223, +179, 320, -54, 741, -284, 872, -360, 630, +-250, 124, -35, -428, 202, -795, 364, -819, +376, -501, 231, 0, -21, 474, -293, 756, +-437, 723, -383, 387, -194, -86, 53, -493, +287, -674, 407, -586, 365, -278, 198, 122, +-52, 445, -282, 583, -358, 488, -257, 209, +-75, -131, 131, -379, 289, -462, 311, -399, +189, -199, -8, 65, -202, 280, -316, 383, +-278, 349, -126, 184, 56, -28, 215, -180, +306, -275, 291, -324, 190, -242, 34, -49, +-134, 146, -254, 285, -285, 328, -235, 239, +-119, 67, 45, -110, 177, -291, 236, -386, +219, -281, 121, -49, -31, 178, -149, 333, +-174, 358, -114, 229, 5, 25, 139, -171, +202, -326, 147, -339, 8, -176, -177, 43, +-334, 217, -366, 288, -211, 231, 68, 91, +334, -59, 483, -194, 447, -278, 220, -237, +-103, -94, -386, 82, -524, 233, -440, 295, +-159, 275, 169, 184, 379, 6, 412, -221, +261, -382, 0, -416, -233, -328, -349, -105, +-304, 165, -94, 371, 177, 498, 338, 471, +348, 243, 221, -68, -21, -319, -271, -478, +-400, -483, -388, -296, -221, -54, 78, 161, +343, 344, 443, 378, 381, 237, 195, 69, +-94, -53, -345, -146, -437, -152, -352, -80, +-112, -39, 182, 2, 363, 45, 370, -4, +246, -82, 21, -73, -226, -19, -369, 17, +-336, 68, -155, 98, 113, 86, 314, 91, +346, 80, 246, 20, 68, -26, -160, -41, +-337, -84, -355, -150, -214, -180, 30, -158, +279, -53, 394, 117, 325, 242, 152, 272, +-70, 218, -305, 89, -437, -86, -368, -246, +-131, -320, 162, -253, 384, -51, 424, 157, +309, 260, 113, 260, -123, 168, -334, 14, +-402, -154, -297, -282, -73, -296, 166, -171, +305, 27, 309, 188, 224, 278, 69, 289, +-153, 194, -321, 28, -337, -164, -194, -310, +49, -334, 278, -225, 374, -46, 318, 133, +147, 266, -118, 296, -380, 215, -486, 62, +-369, -110, -86, -215, 237, -211, 445, -137, +478, -35, 344, 72, 67, 141, -269, 137, +-495, 77, -501, -13, -300, -84, 32, -84, +332, -57, 471, -44, 432, -9, 236, 62, +-98, 109, -417, 96, -529, 40, -381, -38, +-67, -82, 269, -79, 476, -94, 470, -99, +284, -21, -42, 100, -397, 160, -589, 136, +-494, 67, -170, -7, 225, -38, 517, -48, +594, -82, 453, -93, 141, -39, -275, 22, +-623, 10, -679, -53, -428, -81, -13, -26, +384, 90, 609, 179, 582, 191, 355, 154, +11, 81, -361, -49, -573, -237, -494, -376, +-212, -339, 98, -132, 331, 125, 407, 314, +327, 398, 141, 347, -103, 166, -327, -92, +-384, -348, -235, -463, -3, -348, 211, -65, +334, 217, 326, 399, 200, 437, 1, 266, +-238, -43, -390, -337, -351, -520, -166, -496, +47, -219, 229, 185, 337, 500, 331, 640, +218, 561, 13, 211, -221, -254, -375, -610, +-361, -750, -219, -617, -13, -207, 216, 295, +402, 664, 439, 823, 263, 681, -59, 210, +-377, -341, -536, -703, -470, -815, -202, -651, +154, -218, 482, 298, 637, 689, 511, 856, +143, 675, -280, 184, -565, -336, -604, -680, +-401, -807, -70, -669, 273, -253, 523, 272, +559, 708, 327, 896, -39, 699, -350, 189, +-489, -360, -416, -740, -172, -872, 124, -684, +369, -180, 486, 441, 369, 908, 48, 997, +-289, 626, -472, -22, -462, -638, -271, -988, +28, -982, 315, -601, 497, 73, 509, 769, +301, 1157, -47, 1050, -356, 507, -516, -226, +-490, -853, -291, -1143, 15, -1023, 316, -528, +520, 214, 528, 904, 302, 1213, -39, 1016, +-339, 434, -501, -297, -465, -898, -231, -1135, +84, -959, 355, -422, 486, 320, 399, 944, +116, 1147, -204, 869, -422, 272, -458, -406, +-277, -899, 39, -1017, 341, -743, 501, -170, +452, 486, 187, 919, -182, 928, -489, 533, +-598, -60, -445, -614, -76, -907, 336, -818, +611, -385, 642, 228, 398, 767, -16, 990, +-417, 780, -638, 244, -591, -373, -284, -840, +132, -989, 456, -758, 566, -233, 434, 380, +115, 832, -237, 951, -463, 693, -479, 195, +-263, -322, 75, -686, 369, -782, 495, -586, +407, -170, 122, 276, -227, 566, -471, 611, +-519, 410, -345, 76, -13, -260, 316, -489, +489, -527, 468, -354, 250, -32, -75, 298, +-344, 508, -431, 525, -322, 353, -72, 72, +194, -243, 327, -490, 293, -565, 132, -442, +-96, -176, -295, 136, -350, 390, -234, 493, +-1, 446, 247, 277, 388, 12, 357, -238, +202, -369, -22, -369, -266, -254, -424, -45, +-413, 150, -230, 235, 45, 225, 297, 122, +397, -57, 324, -187, 149, -199, -72, -127, +-270, 22, -336, 222, -228, 320, -9, 244, +220, 81, 331, -125, 262, -308, 71, -352, +-139, -256, -313, -103, -380, 90, -282, 269, +-45, 302, 228, 195, 416, 74, 434, -21, +273, -79, 23, -78, -227, -71, -402, -96, +-435, -104, -280, -72, 1, -67, 284, -54, +445, 44, 419, 176, 217, 244, -77, 204, +-348, 53, -500, -148, -443, -271, -166, -269, +214, -196, 512, -53, 618, 179, 478, 372, +128, 389, -289, 210, -609, -71, -712, -325, +-520, -435, -78, -359, 384, -176, 666, 76, +681, 349, 424, 498, -15, 403, -427, 120, +-641, -193, -579, -406, -235, -438, 222, -293, +531, -59, 573, 185, 380, 378, 21, 423, +-357, 265, -586, -8, -580, -233, -333, -344, +86, -320, 460, -180, 606, 7, 525, 177, +273, 291, -74, 301, -384, 162, -537, -33, +-500, -177, -267, -247, 72, -236, 327, -122, +390, 49, 311, 177, 143, 229, -72, 205, +-243, 78, -303, -87, -224, -203, -24, -244, +195, -183, 297, -14, 258, 164, 124, 224, +-63, 196, -249, 116, -353, -28, -330, -165, +-165, -212, 88, -159, 298, -34, 374, 127, +311, 201, 153, 124, -51, 3, -219, -80, +-294, -123, -253, -107, -115, -22, 39, 75, +133, 142, 148, 152, 109, 43, 47, -137, +-9, -220, -49, -154, -57, -3, -38, 144, +-10, 239, 7, 233, 33, 126, 68, -55, +63, -272, 19, -392, -42, -307, -92, -57, +-100, 218, -44, 397, 25, 418, 66, 280, +79, 45, 62, -216, -5, -421, -77, -466, +-89, -313, -18, -30, 107, 246, 189, 400, +156, 399, 26, 269, -117, 69, -237, -165, +-290, -366, -221, -434, -31, -316, 208, -67, +388, 200, 395, 393, 206, 445, -58, 335, +-270, 89, -376, -225, -352, -492, -174, -564, +86, -389, 313, -48, 390, 335, 267, 607, +13, 623, -218, 377, -323, -14, -303, -422, +-165, -683, 57, -649, 274, -340, 380, 100, +319, 526, 97, 742, -175, 620, -366, 233, +-415, -231, -320, -617, -101, -762, 174, -576, +403, -163, 500, 328, 388, 734, 93, 857, +-240, 593, -464, 86, -528, -441, -407, -808, +-120, -875, 223, -618, 483, -139, 563, 420, +426, 864, 120, 974, -214, 685, -459, 145, +-536, -410, -418, -811, -146, -936, 171, -739, +419, -261, 509, 333, 397, 808, 141, 962, +-146, 714, -362, 206, -439, -339, -327, -730, +-87, -866, 163, -662, 329, -157, 364, 419, +250, 813, 34, 855, -194, 508, -354, -63, +-370, -582, -215, -866, 45, -833, 289, -435, +442, 211, 447, 781, 263, 1037, -54, 875, +-361, 338, -551, -351, -541, -882, -298, -1081, +72, -915, 398, -372, 568, 345, 539, 898, +302, 1089, -40, 895, -350, 371, -525, -282, +-492, -779, -257, -980, 46, -844, 291, -364, +430, 259, 401, 722, 211, 890, -44, 747, +-275, 302, -431, -294, -408, -749, -194, -911, +78, -722, 302, -204, 433, 420, 417, 851, +251, 956, -14, 728, -307, 169, -507, -510, +-510, -968, -328, -1024, -55, -692, 245, -79, +479, 562, 555, 939, 434, 954, 133, 625, +-246, 11, -527, -619, -574, -929, -399, -828, +-77, -411, 281, 162, 539, 655, 581, 841, +362, 696, -53, 269, -467, -308, -677, -754, +-598, -844, -261, -590, 203, -138, 618, 379, +812, 749, 686, 821, 248, 590, -319, 137, +-763, -377, -904, -725, -692, -776, -210, -564, +340, -165, 747, 311, 873, 676, 659, 778, +177, 576, -351, 149, -693, -318, -751, -648, +-531, -737, -122, -558, 321, -142, 633, 354, +694, 715, 464, 781, 44, 519, -365, 64, +-617, -403, -635, -713, -408, -778, -13, -545, +393, -72, 663, 434, 672, 745, 396, 744, +-35, 461, -430, 33, -656, -372, -647, -622, +-383, -652, 43, -430, 463, -20, 694, 371, +634, 555, 304, 493, -149, 256, -534, -61, +-695, -324, -561, -455, -176, -429, 307, -196, +658, 164, 718, 438, 444, 481, -42, 347, +-524, 94, -779, -215, -696, -450, -309, -532, +217, -429, 649, -131, 809, 252, 635, 511, +198, 563, -322, 455, -693, 199, -770, -148, +-538, -434, -107, -579, 337, -543, 613, -312, +631, 45, 406, 356, 23, 528, -346, 553, +-533, 385, -472, 73, -217, -266, 103, -500, +332, -554, 395, -391, 290, -70, 68, 258, +-179, 479, -331, 522, -325, 349, -177, 11, +51, -323, 236, -499, 292, -496, 230, -322, +103, 1, -61, 344, -196, 552, -232, 548, +-163, 353, -30, 26, 105, -298, 166, -508, +126, -586, 35, -479, -55, -167, -109, 228, +-110, 496, -54, 576, 41, 474, 134, 193, +170, -146, 117, -399, 11, -518, -86, -445, +-136, -135, -135, 250, -89, 468, -19, 471, +43, 287, 69, -48, 64, -377, 35, -565, +-2, -563, -12, -318, 33, 165, 89, 616, +103, 771, 78, 643, 2, 297, -108, -173, +-193, -597, -215, -799, -184, -734, -69, -387, +111, 146, 248, 587, 273, 737, 191, 604, +32, 279, -127, -129, -196, -465, -190, -604, +-128, -508, -1, -182, 134, 268, 173, 597, +110, 631, -15, 395, -147, 26, -200, -384, +-152, -710, -66, -782, 42, -543, 174, -48, +248, 518, 224, 900, 123, 905, -37, 590, +-199, 106, -265, -428, -232, -832, -160, -913, +-49, -644, 94, -148, 212, 384, 251, 709, +193, 687, 62, 416, -62, 56, -140, -301, +-177, -518, -172, -483, -111, -222, -11, 128, +115, 412, 211, 483, 193, 317, 82, 44, +-36, -243, -122, -470, -191, -549, -210, -391, +-130, -58, 54, 302, 250, 556, 320, 612, +216, 461, 15, 152, -184, -221, -317, -538, +-327, -664, -204, -522, 32, -179, 298, 201, +454, 482, 380, 582, 124, 473, -158, 181, +-350, -168, -413, -438, -345, -518, -162, -369, +100, -94, 351, 162, 457, 316, 367, 388, +149, 328, -79, 116, -260, -142, -365, -315, +-353, -339, -193, -230, 62, -60, 272, 90, +340, 228, 250, 331, 64, 276, -129, 61, +-249, -162, -277, -297, -209, -311, -32, -203, +189, -29, 315, 138, 289, 297, 164, 378, +0, 271, -158, 45, -291, -191, -342, -344, +-257, -365, -58, -249, 142, -89, 257, 88, +286, 292, 230, 390, 95, 308, -61, 112, +-186, -105, -251, -259, -203, -294, -65, -236, +59, -132, 123, 38, 163, 236, 158, 322, +70, 268, -71, 117, -200, -83, -254, -261, +-197, -350, -63, -326, 89, -209, 250, 23, +372, 292, 361, 480, 181, 493, -79, 312, +-317, 2, -463, -312, -465, -496, -315, -522, +-50, -390, 253, -103, 479, 244, 527, 485, +385, 507, 112, 334, -185, 60, -406, -200, +-479, -337, -368, -344, -97, -236, 222, -28, +433, 201, 432, 323, 222, 272, -75, 104, +-343, -132, -489, -308, -425, -335, -130, -227, +250, -43, 528, 197, 609, 426, 455, 491, +96, 331, -313, 16, -598, -316, -693, -522, +-542, -527, -155, -358, 298, -72, 612, 275, +699, 560, 530, 607, 170, 392, -222, 47, +-532, -275, -662, -480, -511, -512, -132, -366, +253, -116, 503, 194, 570, 439, 415, 484, +86, 317, -271, 67, -548, -178, -626, -370, +-401, -416, 19, -304, 405, -70, 625, 221, +630, 434, 381, 436, -33, 244, -446, -23, +-718, -286, -706, -473, -374, -477, 87, -276, +451, 51, 640, 367, 614, 542, 354, 510, +-45, 281, -409, -22, -600, -317, -526, -509, +-225, -521, 134, -327, 392, -34, 469, 226, +342, 406, 64, 430, -238, 285, -438, 58, +-429, -158, -188, -306, 159, -303, 404, -144, +453, 40, 325, 172, 75, 243, -208, 168, +-412, -30, -452, -203, -319, -270, -65, -231, +191, -84, 345, 122, 363, 255, 282, 314, +142, 273, -28, 104, -200, -106, -307, -232, +-290, -263, -175, -249, -26, -166, 112, -37, +214, 97, 241, 216, 185, 261, 61, 196, +-79, 68, -161, -54, -156, -151, -112, -207, +-62, -172, -5, -65, 44, 79, 88, 199, +122, 205, 123, 102, 82, -32, 23, -101, +-63, -127, -157, -124, -194, -101, -145, -52, +-39, 32, 84, 92, 166, 92, 168, 74, +112, 100, 28, 121, -51, 74, -98, -25, +-91, -135, -63, -195, -28, -159, 0, -86, +13, -22, 26, 51, 45, 129, 53, 159, +40, 130, 7, 68, -63, -28, -120, -78, +-121, -64, -72, -67, 23, -116, 162, -103, +249, 3, 216, 121, 89, 193, -101, 166, +-282, 56, -345, -65, -261, -167, -100, -262, +100, -269, 261, -101, 295, 159, 225, 345, +103, 384, -42, 268, -144, 41, -165, -199, +-167, -350, -145, -381, -55, -285, 55, -51, +121, 203, 154, 355, 123, 354, 3, 227, +-139, 7, -218, -198, -186, -296, -31, -314, +186, -228, 341, -14, 349, 239, 174, 389, +-117, 393, -381, 245, -484, -43, -386, -340, +-109, -514, 219, -516, 435, -303, 458, 89, +296, 480, 30, 685, -208, 618, -328, 275, +-323, -223, -187, -610, 7, -733, 151, -558, +218, -151, 220, 343, 128, 688, -20, 707, +-139, 413, -217, -64, -224, -491, -115, -676, +57, -556, 203, -201, 303, 227, 275, 546, +89, 610, -120, 400, -252, 40, -321, -307, +-284, -498, -114, -475, 81, -266, 231, 19, +327, 240, 315, 347, 176, 317, 2, 200, +-168, 42, -307, -95, -349, -188, -266, -241, +-79, -222, 159, -135, 339, -8, 353, 113, +225, 221, 28, 285, -179, 226, -310, 47, +-288, -184, -143, -346, 45, -329, 204, -151, +271, 72, 201, 260, 18, 388, -158, 354, +-236, 108, -216, -188, -136, -394, 7, -417, +164, -253, 257, 9, 251, 215, 143, 319, +-41, 326, -199, 193, -266, -1, -266, -144, +-177, -208, 12, -192, 211, -91, 325, -7, +319, -15, 154, -37, -104, 4, -293, 67, +-350, 119, -286, 149, -94, 137, 159, 81, +335, -22, 374, -164, 264, -265, 40, -197, +-185, -3, -317, 183, -354, 260, -279, 207, +-91, 21, 116, -227, 271, -372, 358, -330, +335, -102, 166, 237, -80, 547, -289, 618, +-374, 364, -309, -107, -119, -573, 122, -787, +310, -637, 356, -225, 242, 280, 17, 726, +-236, 883, -387, 581, -335, -26, -112, -579, +151, -842, 343, -715, 393, -274, 290, 287, +66, 734, -207, 872, -408, 594, -421, -2, +-246, -584, 11, -886, 235, -791, 330, -355, +286, 239, 160, 713, 10, 858, -133, 643, +-215, 153, -191, -425, -87, -801, 31, -767, +87, -363, 74, 181, 50, 612, 42, 744, +11, 529, -43, 83, -87, -440, -83, -783, +-21, -721, 49, -278, 75, 266, 77, 648, +75, 757, 39, 518, -15, 42, -61, -432, +-106, -682, -126, -601, -77, -240, -23, 199, +-4, 480, 40, 509, 112, 295, 160, -65, +169, -339, 106, -380, -51, -226, -206, 10, +-283, 218, -262, 315, -123, 221, 93, 4, +274, -198, 360, -249, 312, -133, 86, 45, +-222, 179, -413, 179, -400, 60, -228, -116, +40, -260, 293, -277, 433, -112, 408, 172, +199, 414, -142, 499, -440, 347, -528, -34, +-368, -445, -38, -676, 298, -644, 493, -330, +475, 195, 247, 709, -110, 929, -401, 740, +-473, 170, -305, -533, 1, -1013, 266, -1046, +350, -614, 252, 142, 61, 919, -145, 1281, +-245, 1021, -180, 255, -23, -671, 114, -1319, +177, -1337, 135, -692, 24, 316, -77, 1218, +-136, 1558, -142, 1116, -66, 100, 52, -989, +111, -1641, 103, -1510, 49, -620, -22, 609, +-58, 1557, -36, 1776, 3, 1146, 43, -47, +92, -1214, 91, -1799, -11, -1540, -156, -575, +-232, 648, -190, 1532, -47, 1676, 118, 1038, +238, -56, 281, -1068, 241, -1523, 103, -1251, +-120, -432, -327, 547, -392, 1230, -282, 1299, +-72, 761, 144, -91, 292, -846, 352, -1179, +303, -977, 114, -335, -171, 439, -376, 973, +-374, 1019, -209, 600, 21, -48, 220, -629, +311, -893, 265, -771, 125, -291, -81, 332, +-271, 760, -313, 775, -182, 417, 4, -89, +153, -515, 228, -684, 211, -555, 133, -198, +25, 273, -100, 624, -202, 637, -212, 336, +-157, -76, -80, -385, 19, -495, 125, -400, +199, -194, 227, 83, 186, 371, 56, 475, +-108, 315, -235, 11, -280, -226, -231, -326, +-82, -301, 109, -194, 261, -16, 314, 241, +237, 424, 46, 358, -170, 81, -299, -213, +-284, -387, -122, -418, 115, -297, 307, -30, +333, 304, 179, 548, -74, 518, -296, 214, +-371, -199, -262, -500, -33, -557, 208, -378, +366, -22, 359, 352, 192, 563, -50, 472, +-243, 135, -306, -267, -234, -530, -113, -500, +2, -201, 121, 201, 205, 523, 187, 605, +84, 372, -29, -71, -99, -479, -92, -664, +-45, -570, -13, -223, 6, 225, 27, 589, +12, 703, -37, 505, -80, 79, -75, -348, +20, -560, 137, -539, 153, -330, 69, -5, +-12, 328, -73, 498, -127, 407, -143, 104, +-97, -227, 3, -397, 128, -345, 178, -147, +102, 109, -17, 363, -109, 480, -161, 335, +-156, -21, -71, -375, 69, -553, 226, -472, +299, -193, 196, 147, -38, 432, -264, 570, +-380, 448, -347, 88, -164, -293, 102, -509, +361, -469, 487, -221, 383, 106, 83, 368, +-232, 477, -413, 362, -409, 32, -239, -332, +30, -533, 282, -481, 376, -206, 244, 179, +-38, 508, -279, 647, -336, 519, -183, 133, +85, -354, 321, -690, 406, -738, 297, -481, +18, -14, -317, 479, -499, 786, -403, 752, +-104, 377, 191, -192, 340, -659, 315, -815, +175, -604, -20, -117, -181, 437, -202, 802, +-70, 781, 105, 367, 170, -243, 78, -731, +-93, -847, -205, -554, -200, -3, -97, 552, +52, 866, 176, 787, 210, 305, 129, -334, +-33, -781, -165, -830, -150, -502, -13, 15, +129, 500, 178, 743, 103, 673, -72, 295, +-235, -220, -297, -584, -222, -626, -10, -394, +242, -54, 367, 267, 304, 459, 115, 464, +-131, 296, -314, 2, -322, -285, -168, -404, +47, -328, 221, -163, 250, -1, 138, 152, +-18, 256, -151, 278, -212, 201, -159, 28, +-21, -134, 112, -195, 196, -164, 183, -135, +92, -97, -5, 6, -82, 136, -165, 205, +-229, 162, -223, 43, -109, -76, 105, -146, +301, -172, 371, -161, 300, -53, 105, 148, +-199, 299, -466, 300, -533, 146, -334, -88, +76, -300, 487, -390, 644, -332, 480, -139, +111, 154, -337, 400, -677, 467, -704, 314, +-371, 20, 180, -270, 699, -411, 876, -370, +587, -178, 38, 104, -507, 350, -859, 427, +-832, 283, -383, -10, 256, -301, 779, -452, +903, -423, 534, -225, -67, 95, -512, 421, +-670, 581, -537, 493, -138, 204, 315, -162, +564, -463, 489, -596, 123, -509, -305, -223, +-475, 173, -355, 483, -119, 553, 129, 372, +320, 67, 363, -219, 257, -380, 34, -346, +-215, -152, -279, 106, -152, 299, -46, 314, +-35, 129, -40, -136, -33, -297, 17, -288, +85, -158, 110, 31, 143, 196, 212, 285, +166, 280, -39, 162, -247, -35, -356, -180, +-301, -209, -92, -211, 118, -190, 241, -114, +320, 27, 276, 208, 51, 332, -202, 300, +-343, 124, -320, -95, -114, -299, 157, -395, +309, -287, 330, -11, 222, 302, -27, 478, +-304, 385, -452, 62, -407, -316, -154, -531, +211, -466, 473, -142, 531, 283, 381, 586, +49, 616, -344, 308, -597, -190, -600, -608, +-323, -713, 132, -461, 529, -4, 672, 444, +522, 681, 125, 613, -363, 256, -685, -227, +-679, -568, -339, -603, 181, -359, 611, 7, +738, 320, 545, 476, 109, 431, -401, 207, +-735, -117, -747, -370, -435, -431, 87, -321, +580, -91, 782, 151, 658, 325, 302, 395, +-179, 348, -609, 155, -787, -126, -625, -357, +-173, -457, 363, -392, 701, -185, 702, 75, +408, 318, -51, 493, -494, 506, -711, 290, +-606, -67, -205, -383, 317, -548, 695, -521, +723, -310, 398, 23, -99, 379, -531, 633, +-723, 639, -618, 341, -235, -101, 275, -499, +671, -718, 753, -657, 474, -310, -25, 182, +-475, 633, -676, 845, -602, 676, -298, 189, +130, -400, 513, -834, 678, -914, 552, -578, +171, 24, -269, 641, -546, 1009, -585, 945, +-421, 458, -104, -265, 262, -919, 531, -1203, +577, -972, 342, -309, -54, 512, -388, 1137, +-515, 1299, -430, 921, -151, 159, 216, -699, +489, -1289, 531, -1320, 300, -748, -106, 163, +-471, 971, -596, 1327, -457, 1077, -122, 353, +282, -527, 573, -1197, 587, -1320, 326, -783, +-69, 160, -387, 1012, -464, 1368, -324, 1111, +-94, 379, 139, -501, 293, -1160, 242, -1331, +39, -918, -164, -121, -249, 670, -162, 1072, +45, 999, 195, 586, 226, 14, 212, -492, +125, -754, -51, -688, -203, -356, -256, 69, +-205, 371, -53, 460, 58, 397, 46, 218, +28, -58, 56, -331, 56, -471, 58, -394, +96, -149, 112, 144, 122, 393, 82, 537, +-81, 521, -255, 276, -282, -130, -197, -527, +-45, -704, 134, -596, 224, -299, 210, 90, +143, 463, -3, 694, -168, 657, -194, 342, +-106, -115, 20, -493, 158, -631, 217, -509, +131, -205, -5, 181, -132, 519, -221, 652, +-201, 452, -113, 1, -33, -471, 55, -756, +149, -696, 159, -311, 114, 247, 96, 763, +97, 1014, 70, 807, -11, 184, -148, -548, +-270, -1069, -268, -1140, -145, -695, 10, 69, +139, 797, 235, 1168, 252, 1006, 153, 389, +-32, -379, -196, -944, -220, -1066, -81, -676, +95, 32, 172, 680, 170, 963, 119, 774, +-32, 236, -254, -365, -387, -774, -341, -858, +-112, -545, 210, 41, 461, 575, 532, 815, +418, 711, 121, 318, -298, -167, -621, -539, +-669, -749, -413, -679, 42, -276, 474, 229, +649, 580, 536, 715, 203, 581, -256, 214, +-623, -200, -652, -562, -316, -755, 185, -588, +581, -125, 647, 346, 408, 648, 21, 701, +-385, 464, -659, 37, -614, -405, -267, -729, +183, -742, 514, -373, 554, 153, 339, 560, +75, 709, -130, 596, -302, 269, -376, -146, +-300, -520, -103, -701, 128, -556, 258, -173, +228, 219, 172, 466, 161, 528, 46, 422, +-196, 184, -397, -137, -403, -443, -199, -566, +115, -414, 362, -106, 488, 243, 493, 517, +287, 604, -154, 465, -613, 126, -794, -338, +-573, -750, -65, -850, 435, -570, 716, -33, +723, 556, 456, 940, -56, 949, -597, 597, +-847, 8, -650, -667, -145, -1124, 384, -1056, +723, -513, 758, 227, 476, 880, -46, 1147, +-596, 922, -911, 330, -788, -433, -290, -1115, +318, -1304, 776, -841, 921, 4, 695, 877, +165, 1412, -461, 1335, -896, 692, -892, -252, +-484, -1183, 74, -1683, 527, -1436, 745, -541, +667, 585, 319, 1468, -161, 1728, -551, 1263, +-651, 304, -465, -775, -136, -1548, 192, -1661, +432, -1020, 512, 52, 419, 1058, 164, 1575, +-164, 1399, -419, 634, -500, -387, -393, -1266, +-159, -1609, 102, -1219, 316, -292, 470, 750, +464, 1482, 240, 1593, -94, 1030, -377, 44, +-514, -1000, -445, -1654, -215, -1572, 84, -808, +400, 272, 595, 1232, 521, 1681, 208, 1397, +-210, 525, -604, -560, -738, -1411, -527, -1623, +-127, -1086, 331, -105, 733, 865, 859, 1434, +596, 1369, 62, 714, -540, -203, -917, -996, +-866, -1360, -453, -1103, 109, -379, 652, 429, +930, 982, 784, 1101, 296, 781, -316, 204, +-793, -391, -895, -831, -571, -928, -19, -629, +519, -116, 823, 383, 776, 687, 399, 718, +-140, 523, -619, 155, -838, -301, -709, -660, +-289, -733, 247, -497, 668, -58, 832, 392, +675, 642, 255, 650, -258, 417, -666, -9, +-855, -458, -715, -709, -252, -631, 323, -263, +751, 207, 869, 549, 634, 635, 153, 476, +-360, 146, -752, -244, -860, -547, -580, -610, +-39, -394, 489, -33, 796, 306, 753, 476, +397, 434, -73, 253, -511, 14, -789, -223, +-737, -370, -334, -323, 200, -139, 661, 57, +851, 182, 654, 194, 204, 125, -299, 56, +-744, 15, -921, -40, -671, -91, -155, -101, +420, -116, 880, -142, 968, -103, 622, 4, +97, 170, -468, 359, -932, 435, -1000, 272, +-635, -63, -50, -423, 611, -675, 1062, -660, +972, -349, 473, 153, -163, 660, -785, 939, +-1097, 801, -859, 280, -256, -376, 462, -871, +1042, -999, 1110, -689, 630, -72, -52, 579, +-702, 985, -1127, 939, -1034, 439, -471, -288, +262, -869, 915, -1053, 1193, -758, 901, -91, +266, 618, -414, 1062, -972, 1075, -1148, 605, +-791, -163, -91, -850, 631, -1177, 1068, -1012, +978, -397, 470, 355, -161, 895, -718, 1094, +-1006, 857, -816, 245, -225, -433, 429, -898, +853, -973, 864, -604, 506, 13, 8, 536, +-440, 816, -763, 791, -788, 404, -451, -176, +49, -674, 473, -890, 693, -700, 644, -180, +391, 389, 71, 776, -307, 897, -647, 679, +-723, 133, -477, -504, -85, -959, 323, -1001, +620, -601, 687, 23, 519, 603, 137, 954, +-377, 947, -755, 527, -750, -134, -426, -742, +65, -1000, 551, -767, 807, -225, 687, 346, +264, 757, -299, 842, -763, 552, -870, 13, +-565, -543, -22, -834, 512, -688, 839, -236, +805, 244, 422, 614, -135, 750, -617, 570, +-846, 140, -733, -376, -330, -727, 187, -720, +632, -403, 848, 17, 722, 399, 277, 656, +-269, 673, -721, 399, -910, -73, -717, -517, +-203, -694, 399, -566, 874, -242, 1016, 140, +697, 479, 68, 671, -588, 595, -1020, 238, +-1037, -252, -602, -621, 71, -701, 722, -501, +1086, -141, 973, 274, 452, 639, -220, 778, +-807, 577, -1073, 92, -848, -467, -258, -809, +419, -776, 915, -451, 1022, 33, 689, 541, +83, 881, -589, 848, -1062, 419, -1051, -241, +-547, -822, 172, -1007, 812, -747, 1138, -214, +976, 396, 415, 897, -299, 1054, -915, 754, +-1180, 121, -902, -590, -223, -1058, 498, -1029, +964, -578, 1010, 36, 665, 629, 101, 993, +-496, 944, -946, 493, -985, -172, -552, -798, +93, -1038, 634, -765, 923, -195, 884, 428, +507, 897, -86, 996, -701, 644, -1092, -24, +-1039, -733, -517, -1138, 219, -1000, 857, -403, +1160, 338, 1033, 939, 499, 1166, -267, 912, +-974, 272, -1304, -474, -1059, -1018, -342, -1124, +485, -733, 1068, -91, 1251, 517, 956, 895, +247, 899, -600, 547, -1224, 27, -1356, -479, +-891, -802, -26, -766, 835, -431, 1375, 9, +1386, 466, 806, 767, -159, 742, -1082, 464, +-1584, 19, -1405, -495, -594, -841, 462, -840, +1308, -548, 1617, -21, 1236, 595, 309, 958, +-758, 929, -1511, 573, -1591, -51, -953, -705, +80, -1031, 1068, -919, 1640, -458, 1500, 234, +676, 839, -453, 1018, -1413, 767, -1755, 204, +-1288, -495, -277, -953, 804, -933, 1573, -535, +1687, 84, 1037, 727, -69, 1035, -1114, 866, +-1653, 351, -1431, -347, -593, -921, 416, -1059, +1202, -756, 1485, -180, 1139, 500, 302, 993, +-638, 1033, -1280, 639, -1336, -14, -800, -677, +32, -1013, 763, -873, 1154, -390, 1123, 227, +654, 754, -107, 938, -822, 680, -1138, 137, +-967, -473, -442, -872, 192, -827, 703, -411, +952, 120, 887, 604, 472, 860, -176, 720, +-739, 281, -972, -256, -814, -711, -346, -829, +246, -559, 733, -150, 976, 271, 838, 616, +271, 688, -483, 468, -1005, 120, -1052, -259, +-649, -517, 24, -489, 688, -296, 1092, -78, +1055, 178, 525, 368, -297, 370, -970, 236, +-1177, 17, -881, -234, -247, -354, 455, -280, +956, -136, 1079, 55, 762, 286, 103, 402, +-575, 334, -961, 121, -921, -172, -524, -412, +48, -445, 561, -312, 851, -102, 802, 175, +385, 412, -199, 480, -641, 360, -775, 93, +-602, -211, -196, -403, 244, -433, 566, -337, +697, -126, 562, 169, 168, 421, -270, 522, +-553, 413, -632, 128, -499, -221, -215, -508, +142, -619, 494, -521, 703, -182, 591, 302, +212, 688, -214, 805, -531, 615, -665, 148, +-549, -426, -201, -831, 259, -924, 668, -652, +794, -42, 526, 601, 11, 948, -480, 920, +-783, 501, -804, -181, -504, -782, 52, -1025, +673, -838, 1068, -240, 977, 510, 414, 979, +-301, 1006, -883, 624, -1160, -62, -1000, -764, +-389, -1122, 439, -980, 1132, -388, 1334, 427, +910, 1038, 105, 1140, -706, 773, -1248, 92, +-1301, -677, -776, -1177, 96, -1151, 960, -588, +1442, 271, 1255, 1016, 494, 1260, -416, 960, +-1146, 302, -1452, -495, -1138, -1114, -326, -1270, +623, -866, 1328, -66, 1455, 752, 901, 1185, +-4, 1093, -858, 586, -1382, -125, -1328, -772, +-662, -1080, 292, -918, 1121, -345, 1492, 374, +1174, 869, 315, 936, -649, 603, -1329, 51, +-1491, -516, -1013, -872, -79, -854, 888, -469, +1487, 114, 1481, 639, 849, 870, -128, 741, +-1010, 376, -1484, -86, -1364, -527, -661, -773, +311, -714, 1103, -416, 1440, 6, 1168, 388, +353, 599, -605, 613, -1248, 434, -1338, 87, +-840, -313, 53, -560, 907, -547, 1372, -311, +1267, 40, 582, 396, -398, 617, -1191, 553, +-1481, 194, -1152, -315, -325, -751, 596, -845, +1236, -533, 1428, 11, 1075, 604, 247, 1030, +-662, 1041, -1260, 574, -1322, -153, -844, -864, +-92, -1224, 610, -1022, 1103, -415, 1196, 313, +733, 916, -58, 1149, -777, 870, -1148, 231, +-1027, -475, -453, -970, 282, -1000, 910, -574, +1216, 37, 994, 610, 266, 947, -608, 866, +-1219, 387, -1307, -248, -809, -786, 18, -995, +813, -740, 1312, -192, 1311, 415, 698, 888, +-262, 984, -1072, 632, -1369, 28, -1082, -586, +-362, -975, 478, -920, 1083, -469, 1228, 139, +843, 709, 82, 995, -688, 823, -1079, 323, +-979, -280, -504, -795, 147, -995, 708, -757, +945, -225, 795, 385, 339, 875, -271, 993, +-742, 688, -855, 134, -642, -471, -232, -934, +286, -1004, 703, -615, 816, 6, 610, 621, +159, 1004, -368, 940, -695, 472, -707, -168, +-497, -786, -92, -1102, 394, -882, 687, -265, +650, 421, 363, 948, -76, 1083, -459, 733, +-595, 93, -512, -595, -247, -1070, 167, -1046, +516, -527, 582, 153, 414, 708, 102, 968, +-244, 825, -455, 352, -472, -234, -347, -727, +-79, -886, 240, -613, 405, -123, 397, 316, +282, 584, 70, 633, -169, 446, -308, 115, +-352, -265, -285, -536, -65, -524, 187, -290, +320, -30, 337, 188, 242, 353, -2, 411, +-268, 321, -410, 100, -380, -178, -159, -356, +189, -351, 430, -252, 459, -111, 320, 83, +0, 292, -399, 398, -576, 326, -428, 121, +-107, -128, 284, -301, 553, -341, 509, -285, +217, -149, -152, 75, -505, 280, -609, 324, +-345, 241, 52, 98, 380, -74, 570, -169, +474, -174, 123, -165, -209, -103, -428, 14, +-492, 82, -297, 88, 36, 111, 267, 97, +367, 43, 308, 0, 73, -88, -139, -183, +-227, -176, -249, -81, -152, 42, 73, 189, +212, 293, 212, 265, 150, 131, 20, -85, +-130, -329, -191, -436, -195, -347, -159, -123, +-30, 168, 102, 407, 162, 467, 196, 340, +187, 96, 76, -213, -45, -428, -122, -426, +-188, -247, -186, 27, -77, 276, 32, 368, +85, 294, 123, 131, 107, -94, 35, -295, +-17, -338, -46, -223, -79, -27, -47, 173, +20, 262, 20, 234, 15, 162, 55, 55, +54, -84, 1, -187, -21, -200, -43, -152, +-73, -83, -58, -32, -33, 13, -24, 94, +50, 190, 136, 234, 127, 183, 69, 56, +10, -90, -84, -219, -165, -298, -160, -272, +-113, -120, 0, 119, 173, 314, 262, 364, +182, 245, 38, 25, -102, -190, -226, -316, +-263, -316, -175, -196, 2, 17, 208, 215, +344, 292, 281, 242, 72, 96, -130, -72, +-253, -165, -297, -179, -228, -147, -62, -66, +129, 38, 283, 102, 309, 122, 179, 106, +1, 39, -110, -12, -193, -37, -252, -80, +-234, -123, -123, -116, 50, -50, 225, 60, +301, 171, 248, 207, 145, 164, 5, 67, +-177, -102, -322, -284, -338, -361, -215, -275, +23, -34, 252, 260, 347, 438, 316, 419, +207, 257, 0, -21, -261, -344, -426, -523, +-411, -475, -205, -217, 103, 156, 350, 443, +437, 498, 391, 377, 189, 152, -144, -152, +-410, -391, -467, -443, -342, -330, -93, -87, +197, 168, 370, 284, 381, 276, 247, 229, +-4, 125, -251, -40, -327, -165, -254, -218, +-98, -197, 122, -102, 290, 1, 294, 84, +161, 167, -44, 213, -258, 138, -326, -33, +-225, -191, -67, -273, 92, -231, 250, -61, +320, 155, 249, 329, 86, 392, -106, 272, +-235, -15, -260, -313, -222, -471, -167, -439, +-31, -200, 171, 132, 307, 386, 301, 468, +190, 356, 25, 81, -152, -217, -287, -386, +-344, -382, -263, -206, -29, 76, 243, 301, +377, 365, 353, 275, 211, 59, -29, -190, +-290, -346, -446, -362, -418, -243, -185, -10, +174, 244, 444, 381, 500, 369, 363, 229, +76, 4, -299, -208, -569, -324, -589, -337, +-333, -229, 113, -16, 518, 186, 664, 280, +523, 260, 183, 148, -276, -11, -662, -151, +-746, -230, -468, -204, 45, -67, 559, 116, +787, 232, 633, 223, 226, 122, -292, -26, +-749, -185, -880, -291, -548, -269, 60, -121, +667, 93, 992, 289, 850, 346, 315, 253, +-339, 95, -895, -104, -1122, -297, -830, -374, +-145, -293, 600, -97, 1104, 158, 1141, 341, +658, 344, -60, 246, -713, 85, -1122, -147, +-1071, -337, -507, -380, 252, -266, 860, -14, +1112, 258, 865, 363, 246, 305, -437, 183, +-944, -27, -1075, -266, -673, -378, 45, -321, +687, -105, 1032, 190, 955, 354, 432, 290, +-286, 146, -860, -17, -1078, -212, -805, -310, +-165, -247, 503, -70, 939, 170, 1022, 323, +653, 239, -22, 32, -663, -109, -1019, -196, +-948, -229, -442, -146, 239, 6, 773, 166, +1008, 276, 835, 216, 284, 12, -382, -146, +-861, -186, -981, -182, -675, -118, -97, 10, +445, 138, 783, 236, 841, 239, 550, 85, +18, -122, -478, -225, -764, -232, -730, -175, +-384, -26, 78, 150, 462, 267, 696, 294, +661, 165, 306, -89, -163, -271, -532, -284, +-700, -193, -586, -18, -223, 183, 179, 273, +505, 231, 686, 80, 604, -154, 257, -312, +-174, -260, -533, -77, -706, 131, -590, 304, +-269, 328, 132, 178, 530, -37, 762, -248, +635, -377, 221, -304, -263, -76, -638, 148, +-758, 292, -549, 308, -114, 170, 374, -21, +743, -155, 783, -234, 453, -205, -69, -42, +-538, 130, -783, 206, -696, 182, -327, 57, +155, -110, 583, -210, 790, -229, 650, -178, +224, -15, -260, 203, -604, 328, -690, 309, +-521, 157, -175, -70, 239, -261, 581, -341, +674, -314, 464, -159, 92, 109, -278, 334, +-528, 392, -582, 273, -418, 25, -105, -230, +263, -363, 534, -343, 571, -205, 373, 51, +48, 330, -297, 456, -524, 369, -522, 107, +-319, -221, 22, -438, 381, -450, 576, -307, +492, -49, 201, 286, -176, 510, -485, 484, +-567, 234, -399, -131, -90, -428, 259, -501, +529, -365, 562, -111, 350, 215, 15, 489, +-315, 531, -520, 329, -499, -14, -293, -355, +9, -526, 317, -466, 494, -251, 448, 38, +218, 341, -96, 522, -379, 480, -481, 255, +-363, -73, -105, -365, 189, -482, 424, -412, +474, -207, 307, 94, 6, 387, -312, 517, +-495, 417, -454, 115, -228, -266, 71, -523, +365, -546, 519, -357, 438, 3, 157, 411, +-185, 662, -439, 630, -486, 316, -319, -172, +-35, -591, 262, -724, 452, -560, 440, -179, +223, 288, -85, 630, -354, 684, -455, 446, +-361, 5, -150, -445, 103, -655, 348, -543, +476, -214, 380, 200, 115, 531, -175, 624, +-368, 455, -415, 85, -309, -359, -100, -654, +171, -637, 399, -359, 431, 47, 237, 434, +-47, 636, -282, 588, -396, 321, -344, -97, +-161, -480, 95, -618, 357, -478, 504, -158, +406, 202, 114, 436, -210, 466, -442, 325, +-512, 41, -406, -285, -161, -454, 160, -389, +469, -156, 590, 144, 442, 370, 126, 412, +-192, 305, -422, 100, -511, -187, -424, -418, +-165, -452, 193, -303, 482, -37, 559, 239, +390, 386, 67, 368, -292, 252, -549, 45, +-595, -211, -381, -361, 28, -330, 458, -166, +707, 68, 649, 249, 290, 283, -219, 214, +-641, 84, -795, -113, -599, -278, -138, -292, +389, -168, 748, 38, 786, 230, 478, 294, +-50, 229, -553, 106, -806, -63, -714, -238, +-325, -298, 204, -219, 648, -49, 830, 154, +663, 267, 216, 228, -329, 106, -748, -39, +-861, -194, -603, -280, -83, -218, 467, -47, +829, 174, 844, 340, 494, 322, -79, 152, +-610, -50, -879, -246, -770, -392, -327, -369, +251, -170, 723, 106, 896, 360, 676, 449, +146, 313, -437, 75, -827, -159, -881, -353, +-574, -409, -7, -246, 576, 43, 932, 312, +895, 447, 449, 343, -197, 54, -726, -249, +-944, -464, -801, -523, -318, -336, 310, 53, +805, 447, 965, 678, 723, 631, 158, 288, +-434, -168, -791, -529, -857, -707, -625, -631, +-127, -281, 431, 183, 781, 547, 809, 678, +504, 500, 25, 122, -390, -232, -632, -460, +-675, -522, -437, -353, -1, -20, 381, 309, +577, 503, 549, 466, 298, 201, -54, -128, +-347, -381, -536, -519, -526, -466, -257, -207, +131, 139, 448, 443, 600, 589, 501, 488, +165, 202, -228, -111, -542, -370, -674, -509, +-503, -455, -66, -236, 388, 53, 666, 308, +671, 409, 384, 320, -59, 134, -476, -53, +-735, -207, -687, -285, -285, -245, 239, -102, +631, 89, 781, 241, 624, 287, 171, 229, +-370, 101, -770, -61, -862, -240, -561, -379, +2, -389, 540, -233, 846, 30, 822, 292, +425, 465, -175, 484, -675, 343, -873, 72, +-696, -275, -185, -548, 399, -591, 770, -377, +822, -19, 519, 333, -54, 555, -608, 561, +-862, 346, -764, -40, -340, -454, 253, -677, +720, -579, 876, -207, 709, 259, 233, 623, +-371, 745, -771, 571, -826, 143, -578, -396, +-112, -800, 389, -854, 694, -527, 729, 12, +472, 519, -17, 803, -468, 766, -645, 425, +-565, -93, -282, -578, 144, -797, 501, -635, +633, -197, 510, 288, 146, 618, -319, 684, +-613, 464, -641, 50, -442, -407, -50, -714, +393, -683, 672, -327, 690, 154, 441, 555, +-22, 730, -469, 592, -696, 207, -665, -264, +-398, -660, 49, -770, 476, -486, 708, 14, +672, 477, 353, 732, -121, 660, -510, 278, +-679, -218, -610, -641, -281, -819, 173, -596, +516, -70, 625, 465, 508, 798, 191, 804, +-189, 456, -445, -73, -518, -553, -414, -827, +-156, -759, 147, -353, 364, 173, 472, 590, +418, 755, 173, 595, -146, 200, -397, -235, +-528, -556, -457, -643, -151, -435, 237, -40, +537, 346, 637, 568, 454, 520, 37, 225, +-389, -145, -665, -425, -690, -525, -391, -393, +106, -75, 531, 263, 736, 463, 670, 448, +307, 219, -197, -96, -607, -317, -774, -377, +-631, -285, -204, -80, 298, 145, 666, 267, +781, 257, 573, 144, 107, -18, -386, -121, +-704, -120, -745, -90, -467, -78, 1, -59, +435, -41, 677, -34, 664, 7, 386, 82, +-43, 161, -436, 232, -654, 211, -616, 41, +-326, -181, 90, -332, 462, -356, 666, -235, +606, 4, 284, 254, -176, 425, -574, 428, +-736, 204, -578, -143, -168, -418, 322, -502, +695, -363, 785, -55, 531, 287, 26, 530, +-488, 562, -792, 324, -764, -95, -415, -479, +120, -659, 605, -561, 840, -224, 725, 206, +282, 562, -288, 708, -716, 560, -832, 152, +-611, -321, -130, -648, 408, -699, 782, -459, +834, -34, 522, 404, -28, 677, -543, 661, +-799, 350, -741, -128, -392, -553, 127, -730, +595, -590, 804, -193, 673, 300, 240, 680, +-280, 765, -634, 521, -717, 50, -528, -467, +-109, -790, 376, -766, 671, -419, 656, 110, +356, 605, -85, 831, -464, 695, -618, 290, +-524, -235, -227, -677, 172, -818, 484, -602, +554, -141, 388, 373, 97, 714, -205, 745, +-398, 484, -438, 44, -332, -430, -104, -736, +186, -724, 378, -398, 388, 87, 280, 515, +103, 719, -131, 642, -342, 318, -430, -139, +-348, -564, -84, -765, 230, -619, 413, -199, +418, 282, 294, 624, 39, 713, -276, 526, +-482, 135, -470, -334, -233, -693, 127, -741, +422, -449, 514, 13, 410, 434, 136, 671, +-231, 649, -511, 378, -556, -63, -360, -523, +5, -765, 371, -637, 542, -236, 486, 236, +269, 611, -49, 746, -359, 593, -493, 199, +-429, -320, -220, -744, 53, -822, 279, -534, +380, -61, 364, 422, 229, 737, -17, 760, +-233, 497, -329, 35, -305, -471, -181, -765, +27, -694, 217, -358, 319, 81, 295, 476, +117, 666, -126, 595, -284, 297, -322, -146, +-260, -545, -67, -685, 186, -520, 367, -166, +397, 249, 262, 575, -15, 675, -291, 517, +-428, 138, -402, -331, -219, -670, 76, -713, +347, -469, 455, -59, 376, 375, 141, 656, +-142, 673, -332, 437, -380, 17, -317, -424, +-133, -670, 113, -615, 291, -323, 348, 88, +293, 464, 142, 638, -64, 569, -250, 284, +-380, -151, -365, -553, -157, -708, 130, -577, +335, -225, 405, 238, 325, 610, 97, 739, +-186, 609, -403, 219, -440, -315, -251, -710, +70, -788, 319, -561, 413, -105, 341, 398, +121, 713, -155, 756, -363, 512, -426, 8, +-297, -512, -1, -772, 272, -702, 380, -349, +325, 156, 165, 575, -58, 760, -249, 673, +-343, 290, -295, -258, -92, -686, 151, -812, +276, -607, 252, -154, 154, 340, 6, 684, +-142, 787, -225, 575, -213, 85, -100, -447, +80, -765, 211, -747, 218, -407, 136, 89, +12, 516, -119, 735, -204, 664, -209, 282, +-142, -248, 1, -651, 164, -748, 251, -518, +220, -70, 120, 378, -2, 658, -129, 684, +-227, 425, -245, -42, -162, -496, -14, -711, +130, -617, 212, -271, 232, 172, 182, 526, +64, 665, -98, 545, -232, 187, -263, -282, +-177, -622, -10, -666, 168, -433, 283, -26, +269, 388, 129, 628, -89, 614, -292, 352, +-375, -79, -273, -491, -41, -660, 214, -531, +387, -197, 403, 206, 261, 508, 14, 595, +-254, 448, -445, 117, -452, -268, -275, -515, +0, -518, 260, -315, 429, -6, 434, 285, +253, 446, -45, 439, -327, 265, -452, -19, +-364, -280, -104, -412, 191, -373, 398, -197, +413, 37, 227, 239, -78, 357, -355, 351, +-471, 202, -364, -29, -74, -241, 253, -352, +468, -324, 477, -179, 280, 22, -41, 213, +-340, 329, -493, 319, -430, 173, -177, -51, +150, -247, 401, -326, 471, -273, 344, -113, +76, 99, -210, 265, -412, 317, -449, 236, +-303, 29, -27, -217, 260, -351, 454, -317, +475, -153, 303, 89, 10, 314, -288, 403, +-488, 329, -505, 114, -296, -192, 49, -429, +370, -460, 518, -302, 429, -33, 150, 262, +-172, 447, -410, 445, -475, 284, -317, 0, +-6, -301, 309, -449, 475, -386, 426, -181, +185, 80, -120, 299, -372, 379, -490, 301, +-422, 96, -170, -171, 168, -354, 444, -348, +537, -185, 404, 45, 121, 250, -198, 351, +-437, 308, -522, 146, -397, -91, -91, -303, +262, -369, 479, -274, 464, -90, 261, 108, +-30, 262, -304, 324, -468, 282, -429, 146, +-195, -64, 134, -246, 400, -309, 488, -271, +368, -152, 104, 37, -208, 223, -447, 329, +-513, 318, -378, 161, -70, -103, 282, -311, +518, -367, 520, -286, 306, -66, -28, 219, +-345, 415, -514, 434, -473, 263, -231, -70, +117, -403, 409, -538, 492, -440, 350, -163, +70, 219, -212, 523, -382, 595, -381, 419, +-224, 66, 35, -336, 275, -579, 368, -559, +288, -335, 89, 13, -141, 353, -304, 522, +-317, 465, -197, 234, 3, -74, 207, -326, +321, -410, 286, -330, 131, -135, -73, 106, +-243, 282, -298, 323, -232, 236, -94, 64, +64, -123, 205, -251, 271, -279, 235, -212, +115, -61, -41, 122, -182, 253, -259, 292, +-258, 234, -181, 90, -17, -99, 187, -257, +337, -324, 354, -270, 238, -95, 7, 116, +-251, 260, -423, 307, -443, 241, -288, 64, +27, -147, 371, -283, 554, -292, 489, -164, +201, 54, -180, 232, -488, 298, -577, 257, +-405, 98, -28, -134, 378, -321, 593, -376, +514, -280, 188, -57, -229, 200, -537, 376, +-584, 427, -369, 336, 14, 92, 400, -219, +603, -453, 528, -511, 232, -366, -146, -68, +-441, 262, -525, 499, -401, 548, -147, 356, +151, -14, 369, -397, 405, -602, 280, -523, +72, -203, -130, 213, -257, 553, -284, 656, +-225, 446, -75, 3, 119, -464, 249, -732, +281, -648, 223, -248, 75, 261, -130, 658, +-294, 778, -353, 540, -278, 40, -80, -486, +165, -797, 355, -741, 411, -334, 303, 205, +74, 628, -171, 782, -345, 597, -387, 140, +-277, -381, -47, -731, 193, -749, 340, -419, +340, 84, 199, 514, -16, 717, -222, 619, +-337, 250, -304, -229, -129, -608, 106, -722, +300, -506, 369, -57, 281, 392, 70, 655, +-173, 655, -341, 376, -356, -70, -222, -487, +-13, -711, 190, -637, 311, -275, 296, 194, +149, 552, -50, 696, -210, 579, -260, 221, +-187, -223, -42, -563, 106, -684, 211, -521, +232, -129, 142, 284, -18, 550, -185, 610, +-279, 423, -254, 43, -126, -337, 43, -568, +207, -569, 314, -304, 305, 102, 174, 440, +-29, 597, -222, 521, -327, 196, -297, -231, +-169, -558, 7, -675, 183, -513, 301, -101, +296, 354, 171, 660, -24, 721, -206, 480, +-296, 16, -267, -443, -132, -722, 63, -720, +260, -395, 355, 97, 290, 522, 83, 728, +-174, 626, -364, 241, -402, -236, -276, -589, +-31, -696, 254, -489, 450, -45, 445, 401, +235, 656, -69, 637, -337, 331, -462, -127, +-399, -511, -177, -678, 126, -574, 391, -209, +474, 244, 328, 558, 58, 632, -209, 456, +-376, 98, -386, -279, -234, -514, 10, -537, +254, -340, 375, 4, 311, 315, 117, 453, +-102, 401, -259, 185, -297, -110, -207, -343, +-51, -418, 119, -314, 249, -60, 270, 232, +161, 401, -4, 387, -148, 226, -221, -29, +-207, -278, -128, -404, -3, -361, 135, -173, +219, 88, 191, 290, 84, 334, -37, 248, +-128, 88, -164, -87, -136, -199, -65, -209, +26, -135, 107, -14, 132, 98, 99, 125, +42, 82, -17, 35, -71, -12, -95, -48, +-99, -60, -84, -63, -29, -60, 63, -36, +135, -1, 153, 39, 114, 105, 19, 163, +-91, 151, -173, 64, -190, -73, -114, -209, +40, -269, 178, -211, 220, -64, 152, 120, +-1, 277, -166, 312, -250, 196, -213, -3, +-76, -198, 125, -302, 295, -254, 322, -83, +191, 112, -20, 244, -221, 259, -331, 142, +-305, -47, -165, -203, 43, -257, 240, -187, +326, -25, 262, 139, 106, 220, -71, 192, +-201, 79, -231, -68, -166, -170, -54, -172, +73, -90, 166, 29, 169, 136, 91, 169, +-16, 107, -109, 2, -150, -96, -127, -152, +-68, -140, 22, -76, 132, 11, 199, 97, +173, 141, 70, 117, -62, 52, -171, -11, +-216, -52, -191, -71, -92, -62, 73, -31, +226, 12, 266, 45, 182, 38, 21, -10, +-145, -56, -250, -69, -254, -56, -147, -20, +36, 42, 219, 112, 296, 160, 230, 144, +66, 47, -118, -86, -248, -175, -268, -192, +-174, -153, -8, -54, 159, 75, 249, 172, +221, 194, 96, 118, -62, -28, -181, -147, +-205, -162, -138, -100, -16, 1, 107, 124, +189, 198, 196, 167, 112, 44, -26, -125, +-150, -258, -210, -256, -195, -126, -112, 41, +11, 190, 139, 275, 227, 232, 237, 81, +154, -96, 12, -228, -135, -243, -235, -123, +-250, 38, -171, 150, -25, 198, 133, 156, +245, 30, 254, -110, 151, -201, -21, -201, +-190, -93, -272, 59, -221, 159, -68, 184, +121, 147, 274, 51, 306, -63, 182, -142, +-37, -166, -242, -117, -342, -10, -289, 85, +-108, 118, 119, 112, 297, 74, 345, -1, +239, -74, 31, -116, -179, -118, -306, -56, +-298, 44, -165, 112, 25, 139, 182, 132, +261, 59, 236, -59, 116, -156, -43, -199, +-173, -158, -228, -25, -192, 124, -84, 207, +39, 212, 141, 134, 195, -25, 178, -177, +91, -246, -26, -217, -126, -79, -183, 113, +-178, 237, -106, 238, 8, 150, 123, -5, +204, -163, 203, -223, 115, -174, -26, -53, +-162, 104, -239, 201, -219, 164, -110, 42, +50, -95, 209, -200, 286, -201, 232, -82, +78, 81, -98, 218, -233, 277, -274, 197, +-202, 16, -49, -158, 115, -264, 224, -269, +235, -160, 148, 6, 9, 149, -132, 227, +-215, 207, -192, 91, -79, -41, 59, -121, +172, -135, 210, -87, 149, 4, 16, 82, +-132, 110, -226, 87, -214, 8, -106, -90, +40, -146, 173, -147, 245, -98, 209, 2, +82, 117, -65, 192, -180, 211, -228, 159, +-187, 27, -67, -120, 78, -217, 186, -247, +215, -186, 152, -40, 32, 125, -101, 234, +-199, 248, -212, 146, -122, -36, 22, -188, +151, -245, 216, -198, 193, -44, 90, 156, +-47, 292, -164, 296, -227, 159, -203, -82, +-92, -313, 51, -406, 162, -328, 209, -101, +179, 199, 88, 435, -24, 488, -123, 336, +-178, 34, -153, -307, -58, -527, 39, -520, +104, -291, 120, 66, 81, 402, 9, 566, +-55, 485, -91, 195, -81, -186, -20, -495, +51, -579, 95, -391, 96, -22, 51, 355, +-26, 572, -93, 532, -126, 243, -116, -168, +-54, -518, 40, -637, 113, -455, 140, -55, +122, 379, 56, 646, -32, 621, -98, 320, +-126, -118, -111, -508, -48, -683, 24, -553, +76, -175, 104, 268, 86, 576, 23, 616, +-37, 384, -72, 7, -85, -349, -53, -546, +13, -497, 62, -213, 76, 161, 65, 435, +22, 499, -30, 340, -56, 35, -66, -274, +-55, -462, -17, -460, 12, -252, 17, 73, +30, 357, 45, 478, 44, 410, 40, 182, +24, -110, -23, -343, -63, -441, -65, -369, +-50, -148, -16, 128, 44, 321, 80, 370, +64, 280, 16, 83, -52, -141, -100, -293, +-77, -319, -3, -212, 71, -4, 127, 209, +132, 319, 52, 293, -68, 148, -160, -72, +-186, -275, -125, -366, -1, -301, 121, -100, +195, 157, 189, 352, 91, 397, -55, 279, +-164, 43, -201, -218, -155, -389, -27, -394, +116, -235, 194, 28, 186, 277, 102, 397, +-35, 342, -159, 146, -205, -108, -159, -303, +-43, -355, 81, -254, 149, -47, 152, 175, +109, 305, 22, 291, -79, 157, -130, -41, +-109, -214, -48, -282, 25, -229, 71, -89, +74, 91, 53, 236, 15, 277, -41, 211, +-82, 71, -74, -101, -29, -241, 29, -288, +71, -243, 68, -114, 34, 72, 10, 242, +-8, 320, -34, 292, -37, 165, -13, -31, +-2, -212, -17, -315, -41, -314, -50, -199, +-22, -4, 37, 177, 82, 273, 95, 271, +87, 169, 40, 4, -41, -137, -109, -209, +-132, -203, -106, -104, -29, 41, 64, 154, +117, 193, 114, 162, 64, 56, -25, -82, +-112, -192, -141, -238, -97, -194, 11, -59, +137, 114, 199, 249, 161, 306, 52, 255, +-95, 99, -222, -105, -249, -287, -157, -371, +-3, -304, 152, -110, 243, 121, 224, 304, +113, 366, -33, 272, -160, 61, -207, -169, +-153, -331, -40, -336, 81, -171, 169, 73, +174, 276, 87, 356, -37, 266, -150, 35, +-207, -219, -167, -391, -42, -399, 109, -212, +228, 90, 265, 347, 184, 460, 19, 387, +-157, 144, -281, -165, -292, -392, -171, -459, +13, -343, 181, -73, 279, 218, 256, 390, +116, 387, -66, 233, -202, -8, -241, -227, +-168, -330, -21, -288, 114, -123, 188, 96, +181, 248, 87, 264, -47, 171, -154, 20, +-192, -128, -151, -210, -45, -197, 73, -107, +151, 28, 178, 147, 149, 189, 50, 150, +-78, 66, -166, -28, -183, -110, -127, -156, +-16, -158, 100, -105, 178, -8, 190, 91, +106, 151, -51, 166, -181, 132, -219, 54, +-160, -49, -24, -149, 138, -197, 239, -156, +229, -42, 115, 70, -65, 140, -222, 154, +-264, 106, -181, 13, -16, -82, 156, -132, +240, -106, 206, -7, 86, 90, -82, 120, +-223, 84, -240, 8, -123, -88, 52, -148, +203, -138, 261, -60, 193, 58, 37, 162, +-137, 174, -261, 86, -266, -29, -139, -121, +42, -153, 194, -100, 258, 11, 206, 113, +67, 165, -76, 128, -176, -10, -206, -166, +-144, -232, -25, -180, 83, -33, 144, 151, +147, 279, 93, 289, 10, 174, -71, -37, +-136, -259, -153, -361, -101, -279, -8, -71, +83, 163, 158, 321, 178, 329, 114, 182, +1, -55, -110, -280, -191, -371, -204, -264, +-128, -13, 1, 249, 132, 397, 215, 357, +207, 148, 111, -134, -23, -369, -150, -452, +-225, -324, -196, -33, -77, 269, 63, 444, +172, 416, 204, 209, 136, -73, 10, -313, +-107, -417, -173, -335, -161, -93, -73, 186, +42, 361, 133, 362, 173, 195, 137, -58, +40, -273, -64, -363, -140, -300, -182, -97, +-153, 162, -45, 336, 85, 347, 182, 211, +216, -15, 162, -220, 45, -308, -82, -269, +-185, -134, -218, 64, -151, 228, -31, 262, +80, 170, 161, 14, 179, -138, 117, -204, +21, -162, -65, -64, -128, 56, -132, 161, +-72, 191, 7, 118, 73, -3, 109, -113, +90, -172, 36, -158, -19, -90, -78, -8, +-113, 80, -80, 154, -13, 159, 39, 102, +77, 18, 92, -63, 70, -113, 31, -124, +-10, -103, -55, -43, -83, 52, -79, 125, +-64, 129, -40, 73, 14, -14, 74, -91, +116, -120, 132, -101, 85, -40, -24, 62, +-130, 150, -183, 154, -175, 76, -89, -32, +62, -122, 203, -148, 262, -106, 205, -31, +38, 52, -156, 125, -275, 131, -283, 53, +-171, -47, 34, -106, 232, -107, 317, -51, +264, 27, 97, 75, -123, 93, -282, 84, +-304, 31, -202, -48, -14, -92, 190, -89, +306, -57, 290, -13, 159, 17, -46, 26, +-231, 38, -309, 53, -272, 42, -142, 17, +56, 4, 235, 1, 308, -9, 267, -20, +137, -31, -57, -26, -231, -4, -302, 6, +-252, -9, -102, -24, 89, -17, 228, 0, +258, 19, 191, 33, 41, 37, -133, 36, +-230, 32, -215, 5, -109, -32, 53, -47, +192, -31, 230, -11, 173, -5, 55, -10, +-105, -15, -233, -5, -255, 7, -176, 19, +-31, 37, 136, 56, 240, 55, 239, 25, +162, -21, 27, -62, -134, -65, -223, -29, +-196, 4, -97, 15, 30, 21, 133, 11, +155, -18, 105, -45, 23, -48, -71, -20, +-129, 47, -106, 104, -29, 96, 56, 51, +123, 4, 127, -48, 62, -92, -18, -91, +-86, -67, -137, -27, -126, 23, -46, 34, +41, 10, 99, 3, 116, 26, 80, 48, +24, 67, -21, 74, -58, 44, -68, -2, +-36, -47, -3, -104, 0, -135, 3, -103, +4, -35, -2, 31, 8, 78, 29, 94, +36, 83, 30, 64, 15, 31, -21, -16, +-48, -46, -43, -47, -24, -36, 10, -26, +52, -18, 57, -7, 16, 9, -31, 18, +-66, -2, -80, -32, -47, -38, 23, -15, +87, 26, 114, 66, 94, 91, 23, 94, +-59, 70, -115, 7, -128, -84, -83, -145, +2, -141, 72, -92, 95, -24, 83, 45, +45, 86, -11, 99, -51, 93, -53, 54, +-32, 3, -2, -10, 30, -6, 38, -21, +22, -39, -1, -54, -31, -63, -56, -44, +-60, -5, -48, 17, -18, 37, 43, 63, +102, 58, 111, 16, 83, -23, 33, -39, +-46, -26, -122, 13, -149, 38, -114, 33, +-24, 20, 78, 6, 123, -32, 104, -72, +55, -79, -13, -45, -79, 13, -94, 68, +-55, 88, 6, 74, 71, 48, 98, 0, +60, -63, -9, -104, -62, -97, -90, -49, +-84, 26, -40, 92, 23, 121, 86, 110, +119, 57, 87, -35, 10, -133, -56, -183, +-99, -163, -118, -71, -80, 54, 5, 159, +88, 209, 136, 192, 129, 102, 56, -34, +-45, -149, -122, -197, -155, -169, -124, -77, +-30, 32, 71, 104, 130, 129, 133, 105, +69, 32, -30, -48, -89, -88, -88, -81, +-53, -26, 9, 51, 72, 95, 80, 93, +30, 63, -41, 10, -93, -66, -89, -124, +-28, -134, 38, -96, 77, -25, 89, 50, +49, 100, -22, 115, -64, 109, -57, 74, +-21, 5, 36, -67, 83, -98, 65, -87, +-2, -49, -68, -5, -113, 31, -109, 55, +-46, 61, 39, 28, 109, -39, 143, -87, +107, -84, 18, -36, -62, 32, -101, 98, +-101, 137, -51, 139, 19, 85, 60, -32, +60, -157, 34, -217, -12, -189, -50, -93, +-48, 35, -22, 145, 17, 210, 55, 201, +55, 103, 26, -53, 7, -176, -6, -208, +-24, -139, -28, -11, -23, 113, -25, 188, +-25, 184, -19, 89, -9, -76, 14, -215, +44, -248, 57, -162, 50, -2, 27, 159, +-12, 252, -49, 246, -59, 143, -53, -31, +-39, -199, 0, -270, 47, -211, 67, -68, +57, 91, 35, 197, -3, 211, -49, 138, +-82, 15, -92, -114, -63, -188, 6, -159, +73, -56, 112, 54, 121, 132, 77, 151, +-18, 102, -105, 20, -152, -66, -145, -131, +-67, -138, 53, -73, 145, 17, 170, 86, +125, 125, 17, 110, -103, 47, -174, -32, +-168, -104, -76, -142, 68, -109, 179, -26, +200, 60, 134, 123, 3, 136, -139, 83, +-215, -3, -187, -85, -75, -136, 74, -124, +195, -54, 228, 35, 160, 99, 25, 119, +-123, 79, -221, 5, -221, -60, -136, -100, +0, -97, 150, -45, 246, 26, 235, 78, +126, 98, -25, 76, -171, 24, -257, -24, +-233, -55, -113, -76, 52, -72, 199, -47, +260, -20, 207, 11, 67, 47, -105, 75, +-226, 80, -235, 74, -143, 39, 3, -29, +155, -88, 249, -105, 217, -85, 80, -29, +-88, 42, -224, 88, -267, 97, -194, 69, +-41, 1, 134, -75, 268, -100, 290, -71, +178, -13, -3, 50, -182, 89, -288, 85, +-269, 52, -138, 0, 40, -62, 198, -89, +277, -66, 230, -22, 83, 13, -89, 33, +-217, 31, -247, 20, -164, 10, -19, -5, +130, -17, 239, -12, 250, 3, 142, 8, +-24, 6, -174, -3, -256, -8, -231, 0, +-110, 5, 47, -8, 189, -20, 263, -22, +221, -19, 83, -8, -78, 10, -208, 28, +-248, 43, -176, 49, -34, 27, 116, -14, +227, -45, 243, -58, 139, -59, -24, -38, +-180, -3, -266, 32, -231, 62, -85, 73, +101, 55, 248, 17, 295, -14, 208, -48, +22, -80, -176, -84, -305, -59, -304, -13, +-162, 45, 55, 95, 245, 111, 332, 93, +281, 44, 109, -33, -117, -110, -298, -139, +-354, -118, -251, -50, -35, 42, 190, 118, +333, 139, 346, 101, 214, 21, -20, -79, +-247, -139, -363, -132, -315, -62, -126, 41, +116, 135, 297, 162, 344, 108, 243, 4, +31, -108, -198, -181, -333, -178, -311, -94, +-142, 39, 91, 162, 270, 214, 320, 167, +238, 46, 59, -89, -153, -182, -301, -193, +-311, -117, -186, 10, 19, 136, 208, 198, +292, 160, 253, 38, 124, -99, -46, -187, +-190, -191, -250, -110, -211, 18, -89, 138, +70, 204, 186, 175, 210, 60, 162, -75, +70, -155, -48, -157, -156, -97, -208, 0, +-183, 80, -78, 114, 66, 91, 176, 19, +217, -62, 184, -87, 75, -46, -79, 16, +-211, 61, -265, 67, -208, 34, -43, -19, +152, -58, 269, -65, 267, -23, 163, 47, +-7, 89, -188, 61, -300, -16, -277, -98, +-114, -136, 103, -97, 260, -4, 299, 105, +213, 182, 32, 180, -166, 77, -293, -71, +-292, -182, -160, -202, 54, -118, 240, 26, +303, 152, 229, 202, 67, 154, -120, 21, +-261, -130, -296, -218, -207, -195, -22, -74, +177, 85, 291, 198, 281, 219, 172, 158, +0, 36, -188, -100, -304, -188, -295, -188, +-167, -113, 32, -4, 214, 87, 295, 130, +257, 118, 124, 65, -60, -14, -220, -85, +-279, -108, -216, -79, -52, -16, 137, 63, +247, 136, 233, 151, 129, 96, -22, -16, +-173, -142, -255, -230, -214, -229, -74, -131, +96, 31, 218, 205, 238, 305, 165, 274, +34, 128, -111, -64, -211, -233, -221, -297, +-147, -222, -22, -51, 109, 134, 187, 255, +184, 252, 111, 124, 3, -62, -102, -226, +-162, -288, -158, -221, -92, -52, 19, 146, +124, 297, 171, 340, 148, 246, 69, 46, +-40, -177, -137, -336, -180, -378, -160, -288, +-73, -89, 57, 157, 161, 345, 191, 398, +151, 294, 56, 80, -65, -162, -154, -334, +-178, -367, -134, -245, -28, -15, 92, 220, +159, 347, 152, 307, 93, 125, -1, -120, +-94, -316, -147, -367, -139, -247, -64, -20, +48, 224, 137, 379, 163, 358, 126, 171, +40, -80, -76, -283, -164, -362, -182, -280, +-125, -82, -7, 137, 119, 285, 189, 305, +174, 175, 87, -26, -37, -184, -150, -255, +-195, -216, -150, -81, -41, 91, 88, 211, +176, 241, 180, 165, 107, 18, -7, -120, +-118, -193, -175, -197, -153, -133, -72, -18, +25, 95, 103, 161, 133, 162, 115, 99, +65, 0, 4, -79, -50, -110, -79, -101, +-85, -60, -74, 9, -39, 74, 10, 95, +53, 67, 83, 2, 84, -59, 46, -87, +-8, -78, -55, -49, -84, 2, -75, 65, +-24, 106, 40, 97, 87, 51, 96, -9, +58, -61, -9, -89, -68, -91, -108, -62, +-121, -5, -81, 62, 8, 103, 95, 98, +145, 45, 148, -28, 95, -88, -1, -116, +-99, -98, -164, -32, -169, 61, -101, 139, +10, 168, 113, 109, 169, -11, 159, -122, +90, -182, -8, -178, -99, -100, -159, 22, +-156, 133, -80, 192, 30, 163, 117, 55, +152, -63, 129, -130, 59, -141, -38, -87, +-131, 10, -173, 98, -130, 135, -29, 106, +75, 19, 145, -84, 155, -138, 103, -128, +12, -68, -84, 16, -155, 98, -169, 137, +-105, 121, 14, 65, 127, -9, 188, -72, +176, -97, 95, -83, -32, -58, -159, -32, +-225, -10, -188, 8, -57, 28, 99, 56, +208, 70, 224, 72, 142, 58, 0, 11, +-137, -54, -222, -98, -213, -97, -99, -54, +63, 24, 187, 90, 226, 109, 163, 72, +24, -4, -116, -99, -206, -153, -221, -126, +-138, -34, 25, 91, 181, 198, 246, 224, +201, 148, 68, 4, -90, -153, -204, -260, +-240, -269, -178, -166, -28, 15, 141, 199, +232, 296, 208, 267, 103, 135, -35, -50, +-150, -209, -199, -284, -162, -238, -56, -80, +75, 119, 166, 249, 175, 260, 106, 158, +-7, -14, -112, -185, -161, -279, -137, -251, +-56, -105, 55, 106, 153, 271, 175, 311, +109, 218, -4, 34, -115, -171, -174, -308, +-158, -319, -80, -198, 34, 14, 146, 229, +196, 341, 152, 296, 45, 133, -75, -74, +-168, -248, -184, -320, -119, -248, -16, -72, +90, 132, 167, 276, 165, 286, 77, 168, +-40, -7, -128, -162, -149, -252, -102, -235, +-19, -113, 66, 57, 129, 194, 140, 242, +79, 176, -24, 37, -112, -100, -150, -189, +-115, -207, -33, -140, 54, -3, 124, 127, +162, 196, 129, 176, 21, 81, -99, -45, +-161, -142, -150, -176, -84, -140, 6, -44, +93, 78, 156, 164, 160, 169, 81, 100, +-36, -15, -123, -117, -156, -162, -135, -139, +-59, -72, 41, 36, 122, 148, 167, 190, +151, 135, 58, 22, -65, -91, -149, -173, +-167, -181, -122, -124, -33, -21, 74, 105, +160, 194, 174, 191, 90, 109, -36, 1, +-117, -98, -130, -161, -93, -163, -19, -105, +55, -19, 96, 67, 93, 120, 39, 123, +-39, 77, -73, 19, -53, -29, -18, -63, +12, -66, 24, -41, 9, -7, -1, 25, +8, 52, -2, 45, -12, 10, 22, -27, +58, -61, 31, -89, -31, -78, -71, -21, +-71, 51, -34, 119, 15, 160, 57, 143, +89, 65, 92, -38, 30, -148, -63, -217, +-118, -206, -115, -116, -64, 10, 18, 142, +86, 234, 117, 225, 120, 121, 75, -18, +-18, -136, -103, -202, -135, -178, -109, -75, +-45, 53, 29, 149, 84, 169, 119, 97, +118, -18, 53, -113, -43, -166, -104, -159, +-116, -73, -93, 55, -30, 157, 57, 206, +125, 185, 146, 96, 93, -25, -24, -136, +-138, -216, -181, -235, -140, -166, -40, -33, +80, 117, 169, 232, 189, 273, 121, 210, +-13, 64, -136, -118, -173, -266, -130, -310, +-45, -215, 59, -22, 139, 178, 150, 303, +95, 301, -4, 168, -112, -56, -160, -268, +-122, -366, -38, -293, 63, -74, 149, 184, +167, 355, 110, 373, 8, 233, -112, -32, +-196, -305, -172, -440, -63, -365, 60, -120, +151, 198, 182, 438, 132, 480, 10, 307, +-122, -3, -191, -335, -159, -540, -46, -507, +85, -255, 172, 113, 177, 441, 99, 579, +-29, 463, -148, 171, -198, -175, -148, -450, +-23, -538, 110, -383, 194, -69, 192, 244, +102, 428, -38, 405, -160, 203, -209, -77, +-164, -309, -37, -406, 110, -305, 197, -42, +193, 241, 114, 411, -11, 405, -136, 219, +-197, -75, -165, -336, -69, -457, 44, -398, +128, -177, 154, 115, 116, 343, 37, 419, +-49, 327, -104, 116, -105, -113, -62, -258, +-5, -279, 41, -193, 61, -37, 52, 109, +26, 174, -2, 140, -26, 54, -45, -43, +-50, -114, -37, -124, -4, -74, 39, 1, +67, 70, 71, 120, 56, 128, 17, 102, +-44, 41, -94, -41, -101, -121, -70, -161, +-13, -160, 50, -125, 89, -30, 94, 110, +77, 215, 31, 229, -40, 160, -91, 32, +-98, -111, -72, -223, -14, -255, 61, -184, +100, -15, 87, 170, 52, 270, -6, 246, +-73, 121, -97, -59, -69, -224, -26, -290, +16, -231, 49, -69, 64, 131, 66, 287, +55, 304, 20, 178, -28, -15, -65, -189, +-87, -282, -91, -258, -56, -124, 15, 66, +91, 234, 132, 292, 110, 208, 31, 44, +-60, -111, -124, -227, -131, -268, -73, -192, +8, -27, 67, 146, 100, 255, 101, 266, +57, 168, -4, 11, -46, -141, -76, -243, +-97, -257, -90, -159, -49, 1, 30, 150, +129, 235, 173, 223, 122, 108, 15, -48, +-99, -163, -190, -217, -200, -187, -97, -63, +66, 104, 203, 215, 239, 231, 151, 152, +-7, 2, -148, -148, -227, -242, -210, -252, +-92, -159, 60, 23, 180, 190, 231, 257, +182, 228, 47, 126, -96, -26, -180, -161, +-202, -225, -148, -207, -19, -109, 115, 32, +195, 141, 193, 169, 97, 145, -39, 74, +-133, -28, -166, -120, -142, -159, -45, -131, +80, -40, 141, 77, 117, 153, 50, 156, +-26, 101, -76, 15, -77, -97, -44, -176, +2, -174, 36, -92, 36, 22, 15, 123, +1, 161, 2, 129, 10, 69, 9, -3, +-17, -84, -45, -139, -42, -127, -15, -72, +25, -3, 73, 67, 89, 118, 51, 126, +-10, 90, -68, 4, -112, -112, -102, -178, +-30, -148, 44, -45, 83, 80, 93, 194, +73, 220, 27, 129, -23, -26, -68, -175, +-91, -263, -66, -231, -17, -74, 13, 113, +40, 237, 86, 251, 110, 153, 65, -6, +-20, -134, -96, -200, -130, -194, -110, -103, +-44, 38, 55, 133, 154, 146, 181, 113, +108, 51, -22, -27, -146, -95, -209, -128, +-168, -117, -38, -44, 107, 57, 206, 130, +217, 155, 124, 133, -45, 44, -206, -87, +-269, -187, -191, -215, -12, -160, 160, -25, +252, 143, 242, 241, 121, 231, -71, 132, +-228, -22, -254, -179, -154, -256, -8, -211, +115, -75, 188, 99, 194, 219, 115, 223, +-13, 126, -124, -6, -183, -145, -181, -231, +-108, -195, 21, -59, 155, 85, 238, 185, +219, 214, 84, 152, -106, 34, -253, -90, +-287, -182, -183, -202, 18, -128, 211, -14, +292, 87, 231, 155, 65, 174, -133, 121, +-259, 18, -244, -82, -107, -159, 68, -176, +194, -112, 222, 1, 153, 100, 20, 170, +-110, 181, -180, 104, -174, -28, -95, -148, +20, -214, 113, -196, 155, -81, 157, 62, +102, 174, -19, 221, -136, 179, -178, 44, +-147, -105, -65, -186, 50, -176, 146, -81, +170, 59, 111, 156, -3, 152, -106, 71, +-144, -48, -112, -152, -41, -175, 41, -83, +95, 60, 91, 170, 50, 193, 6, 116, +-38, -19, -69, -127, -59, -159, -22, -119, +8, -11, 17, 100, 17, 129, 28, 63, +37, -24, 11, -91, -27, -110, -27, -51, +-8, 50, -19, 117, -29, 120, 3, 62, +41, -38, 50, -110, 33, -112, 3, -57, +-22, 27, -37, 108, -53, 114, -56, 32, +-26, -66, 21, -131, 63, -153, 96, -100, +104, 34, 65, 164, -5, 211, -89, 156, +-159, 37, -164, -97, -80, -187, 58, -201, +182, -123, 216, 25, 135, 158, -5, 180, +-142, 96, -227, -4, -201, -93, -54, -148, +119, -129, 219, -14, 212, 116, 94, 182, +-72, 153, -181, 49, -194, -71, -137, -150, +-17, -163, 121, -115, 182, -13, 143, 88, +55, 129, -38, 111, -108, 62, -130, -15, +-99, -77, -42, -75, 28, -37, 85, -16, +112, 0, 108, 39, 68, 60, -4, 50, +-79, 22, -127, -2, -141, -23, -107, -46, +-17, -92, 95, -123, 176, -73, 182, 26, +111, 109, 2, 169, -114, 207, -215, 158, +-230, 13, -116, -158, 57, -277, 190, -302, +251, -198, 215, 1, 69, 213, -122, 357, +-259, 357, -272, 186, -158, -86, 30, -323, +200, -445, 282, -376, 246, -107, 93, 248, +-106, 495, -249, 523, -282, 320, -201, -54, +-32, -435, 158, -630, 273, -529, 259, -173, +132, 283, -46, 606, -192, 633, -254, 367, +-202, -70, -55, -494, 108, -677, 203, -504, +206, -88, 133, 359, 10, 640, -116, 622, +-185, 295, -176, -174, -111, -571, -1, -718, +123, -540, 201, -111, 194, 356, 109, 661, +-21, 696, -152, 441, -224, -5, -196, -446, +-79, -683, 79, -629, 206, -301, 230, 157, +132, 529, -19, 648, -134, 473, -174, 77, +-131, -368, -23, -638, 86, -594, 127, -254, +88, 220, 6, 603, -63, 691, -64, 444, +-11, -11, 34, -465, 39, -720, 19, -631, +-20, -232, -63, 266, -64, 622, -12, 666, +51, 392, 84, -55, 77, -444, 35, -607, +-25, -467, -76, -78, -96, 356, -76, 574, +-30, 474, 31, 139, 98, -266, 134, -539, +103, -528, 16, -236, -84, 178, -163, 511, +-172, 564, -88, 307, 49, -96, 179, -424, +231, -533, 162, -359, 6, 23, -146, 380, +-234, 510, -228, 360, -106, 18, 80, -344, +220, -516, 259, -410, 196, -89, 43, 289, +-134, 531, -250, 497, -265, 208, -165, -182, +16, -497, 188, -572, 271, -359, 247, 27, +114, 387, -70, 580, -207, 517, -246, 201, +-186, -231, -43, -562, 120, -625, 206, -403, +189, -1, 101, 396, -17, 630, -107, 596, +-133, 289, -120, -172, -71, -555, 21, -667, +102, -480, 124, -100, 112, 320, 72, 606, +-11, 617, -102, 347, -157, -76, -152, -459, +-67, -631, 73, -513, 177, -181, 191, 217, +126, 521, 13, 606, -106, 434, -181, 78, +-183, -308, -105, -570, 27, -588, 133, -353, +170, 18, 151, 369, 90, 583, -8, 568, +-107, 303, -181, -101, -189, -459, -85, -618, +73, -517, 174, -195, 195, 209, 156, 539, +34, 653, -119, 478, -207, 61, -194, -391, +-85, -663, 80, -646, 188, -343, 177, 123, +104, 550, 6, 742, -108, 610, -175, 189, +-153, -329, -72, -690, 44, -723, 147, -445, +173, 9, 128, 448, 53, 693, -44, 645, +-143, 307, -182, -173, -142, -566, -36, -672, +104, -483, 197, -124, 186, 269, 103, 577, +-13, 654, -134, 430, -203, 2, -175, -427, +-57, -661, 95, -601, 203, -291, 205, 123, +121, 509, 6, 709, -118, 593, -213, 186, +-214, -304, -113, -647, 40, -690, 179, -424, +246, 9, 210, 414, 91, 648, -65, 617, +-201, 283, -253, -198, -186, -573, -32, -656, +141, -447, 246, -66, 236, 321, 132, 578, +-15, 619, -166, 391, -256, -38, -222, -455, +-74, -649, 108, -565, 239, -272, 259, 112, +179, 467, 40, 651, -127, 575, -262, 249, +-277, -193, -152, -545, 28, -655, 177, -495, +266, -152, 277, 256, 183, 569, 6, 648, +-184, 442, -316, 30, -324, -403, -183, -647, +51, -598, 276, -300, 403, 116, 368, 491, +156, 675, -151, 559, -400, 189, -477, -259, +-328, -580, -2, -644, 333, -440, 505, -72, +456, 312, 211, 573, -145, 596, -442, 359, +-525, -20, -356, -366, -20, -555, 326, -515, +512, -276, 459, 66, 213, 385, -121, 567, +-399, 518, -478, 238, -328, -139, -41, -457, +254, -597, 425, -504, 398, -204, 210, 180, +-42, 511, -262, 648, -357, 507, -299, 142, +-137, -268, 70, -562, 256, -637, 334, -452, +277, -78, 144, 339, -32, 620, -218, 646, +-338, 381, -322, -55, -161, -471, 95, -701, +330, -646, 425, -305, 345, 189, 114, 621, +-195, 805, -430, 648, -451, 202, -254, -343, +63, -734, 357, -820, 483, -570, 378, -77, +99, 453, -213, 780, -403, 761, -382, 418, +-195, -96, 63, -542, 305, -732, 406, -608, +289, -235, 55, 239, -148, 591, -266, 669, +-271, 463, -155, 72, 11, -354, 152, -633, +230, -633, 202, -373, 93, 34, 0, 426, +-54, 651, -109, 614, -142, 337, -128, -90, +-86, -497, 8, -695, 149, -596, 244, -265, +246, 168, 167, 546, -2, 699, -224, 556, +-372, 172, -350, -287, -142, -630, 183, -692, +449, -450, 502, -23, 337, 413, 20, 677, +-343, 654, -566, 355, -508, -91, -199, -506, +226, -705, 563, -601, 616, -243, 374, 195, +-15, 553, -398, 698, -611, 562, -519, 182, +-172, -299, 247, -666, 561, -748, 622, -499, +385, -31, -13, 471, -380, 794, -582, 786, +-521, 406, -216, -190, 168, -727, 472, -940, +588, -723, 444, -169, 100, 480, -258, 911, +-474, 929, -488, 521, -302, -119, 1, -706, +303, -962, 494, -766, 480, -219, 254, 406, +-51, 824, -307, 859, -448, 518, -401, -26, +-172, -555, 112, -848, 342, -779, 458, -375, +393, 166, 160, 629, -119, 852, -333, 752, +-413, 368, -322, -171, -107, -677, 136, -949, +338, -838, 420, -372, 316, 259, 79, 810, +-163, 1067, -320, 882, -350, 309, -242, -423, +-41, -1020, 178, -1200, 339, -843, 373, -91, +255, 711, 45, 1238, -169, 1245, -309, 696, +-330, -172, -233, -983, -45, -1407, 186, -1228, +366, -493, 396, 464, 271, 1221, 54, 1470, +-173, 1108, -330, 264, -365, -690, -275, -1361, +-71, -1467, 195, -946, 406, -9, 454, 920, +331, 1453, 90, 1399, -195, 763, -431, -217, +-519, -1116, -388, -1552, -61, -1356, 322, -587, +571, 444, 598, 1299, 405, 1620, 44, 1295, +-361, 435, -635, -629, -642, -1430, -367, -1651, +69, -1217, 477, -283, 711, 778, 677, 1498, +376, 1597, -86, 1073, -518, 136, -743, -875, +-662, -1520, -291, -1536, 216, -938, 646, 36, +831, 976, 703, 1511, 284, 1454, -285, 846, +-759, -127, -908, -1082, -657, -1585, -121, -1450, +475, -767, 895, 221, 976, 1146, 665, 1636, +51, 1504, -629, 781, -1041, -279, -982, -1266, +-511, -1749, 163, -1559, 797, -757, 1133, 371, +997, 1382, 428, 1859, -341, 1614, -979, 714, +-1170, -540, -830, -1618, -152, -2023, 574, -1592, +1075, -511, 1133, 821, 711, 1861, 3, 2164, +-694, 1548, -1074, 229, -965, -1235, -468, -2189, +169, -2204, 728, -1302, 1019, 162, 913, 1596, +454, 2383, -177, 2152, -734, 994, -966, -587, +-792, -1911, -352, -2422, 203, -1903, 732, -606, +1003, 906, 853, 2022, 357, 2287, -271, 1613, +-784, 287, -966, -1119, -777, -2029, -308, -2079, +320, -1282, 876, -24, 1066, 1187, 802, 1917, +232, 1887, -431, 1086, -928, -138, -1044, -1267, +-739, -1861, -124, -1714, 598, -883, 1108, 268, +1138, 1297, 680, 1819, -52, 1607, -758, 738, +-1142, -411, -1047, -1364, -516, -1768, 269, -1455, +977, -561, 1256, 516, 981, 1355, 315, 1667, +-453, 1307, -1009, 425, -1137, -590, -809, -1330, +-135, -1543, 632, -1166, 1120, -345, 1086, 572, +612, 1263, -62, 1475, -686, 1107, -1010, 308, +-902, -590, -434, -1259, 205, -1457, 751, -1080, +942, -259, 739, 656, 290, 1310, -225, 1455, +-629, 1001, -767, 143, -621, -762, -247, -1341, +248, -1383, 651, -859, 769, 10, 588, 842, +218, 1310, -216, 1239, -567, 674, -702, -124, +-559, -819, -160, -1181, 328, -1100, 650, -593, +697, 143, 513, 770, 152, 1077, -288, 988, +-613, 543, -688, -84, -496, -667, -89, -1007, +376, -987, 692, -577, 737, 57, 493, 647, +26, 991, -466, 966, -758, 560, -737, -47, +-389, -622, 168, -982, 657, -979, 831, -558, +644, 104, 198, 681, -316, 977, -665, 899, +-699, 486, -421, -102, 33, -658, 436, -984, +613, -922, 540, -473, 279, 135, -62, 645, +-333, 925, -426, 890, -351, 524, -162, -23, +71, -567, 267, -931, 363, -974, 339, -642, +198, -66, -11, 524, -196, 944, -301, 1040, +-306, 751, -189, 161, 16, -529, 209, -1062, +332, -1185, 354, -805, 227, -85, -16, 661, +-256, 1182, -390, 1259, -356, 792, -156, -40, +123, -872, 358, -1357, 455, -1309, 368, -690, +102, 237, -221, 1066, -426, 1474, -415, 1284, +-214, 538, 79, -428, 350, -1201, 473, -1502, +382, -1204, 124, -372, -191, 621, -420, 1301, +-432, 1449, -228, 1018, 88, 161, 375, -748, +489, -1308, 354, -1328, 56, -816, -252, 54, +-450, 874, -423, 1275, -157, 1152, 186, 580, +413, -233, 444, -910, 260, -1174, -66, -977, +-345, -414, -428, 337, -309, 919, -36, 1056, +267, 784, 419, 248, 362, -356, 158, -786, +-122, -872, -360, -641, -398, -190, -234, 330, +11, 671, 261, 686, 426, 482, 390, 161, +187, -211, -63, -485, -301, -562, -427, -448, +-341, -198, -89, 131, 191, 365, 398, 436, +433, 408, 271, 276, 24, 22, -211, -239, +-374, -392, -376, -432, -196, -339, 61, -122, +263, 117, 339, 308, 274, 459, 123, 464, +-45, 271, -200, -38, -294, -342, -271, -550, +-133, -562, 57, -336, 215, 23, 279, 408, +253, 690, 176, 686, 31, 345, -175, -149, +-341, -580, -360, -791, -210, -692, 43, -276, +285, 270, 426, 698, 439, 850, 289, 641, +-29, 172, -376, -346, -557, -708, -491, -810, +-190, -605, 206, -147, 487, 347, 565, 669, +468, 764, 173, 602, -255, 205, -579, -282, +-644, -672, -436, -831, -33, -683, 376, -217, +597, 348, 604, 769, 401, 920, -11, 716, +-462, 184, -707, -459, -652, -935, -319, -1060, +176, -725, 572, -24, 691, 681, 568, 1064, +252, 1061, -211, 646, -605, -84, -703, -817, +-503, -1197, -117, -1077, 309, -507, 588, 300, +628, 946, 465, 1180, 130, 974, -280, 373, +-565, -439, -610, -1070, -436, -1216, -79, -856, +330, -148, 588, 652, 613, 1151, 420, 1130, +42, 678, -387, -50, -654, -801, -646, -1212, +-385, -1059, 25, -471, 420, 287, 651, 933, +637, 1156, 369, 880, -66, 296, -482, -399, +-714, -970, -687, -1097, -405, -721, 63, -105, +547, 487, 832, 915, 771, 951, 385, 586, +-175, 47, -683, -492, -921, -859, -780, -844, +-305, -471, 320, 4, 832, 456, 1000, 772, +744, 754, 164, 428, -489, 5, -933, -435, +-983, -739, -626, -709, -19, -390, 607, 15, +1012, 413, 979, 704, 484, 686, -219, 386, +-801, -34, -1050, -456, -886, -711, -357, -645, +332, -332, 896, 67, 1074, 463, 758, 714, +90, 644, -601, 317, -1003, -97, -971, -499, +-539, -719, 105, -637, 691, -301, 962, 119, +812, 505, 307, 722, -321, 635, -751, 295, +-804, -142, -542, -540, -128, -741, 313, -619, +631, -251, 695, 185, 478, 555, 62, 745, +-362, 603, -590, 208, -577, -243, -406, -630, +-105, -790, 280, -595, 567, -131, 599, 349, +387, 713, 17, 831, -377, 576, -612, 69, +-600, -445, -388, -827, -29, -890, 369, -533, +609, 48, 566, 562, 276, 870, -144, 860, +-485, 445, -569, -138, -442, -616, -200, -872, +143, -786, 450, -325, 501, 252, 306, 657, +21, 808, -250, 648, -390, 188, -343, -319, +-190, -645, 9, -750, 220, -546, 316, -71, +239, 412, 82, 666, -74, 676, -198, 438, +-236, -18, -195, -444, -127, -659, -18, -649, +123, -393, 199, 70, 166, 486, 86, 659, +-22, 603, -142, 349, -214, -83, -219, -471, +-154, -651, -18, -632, 112, -365, 141, 103, +107, 518, 65, 672, 4, 610, -75, 334, +-142, -141, -171, -561, -119, -719, -12, -618, +62, -250, 89, 279, 90, 662, 42, 723, +-35, 531, -89, 135, -105, -385, -59, -711, +34, -710, 76, -459, 19, -9, -66, 481, +-115, 721, -95, 635, 1, 365, 100, -44, +126, -490, 78, -711, -32, -623, -191, -333, +-294, 110, -249, 525, -74, 689, 143, 573, +298, 285, 282, -141, 104, -567, -113, -715, +-295, -547, -391, -182, -328, 263, -122, 614, +102, 673, 271, 453, 341, 77, 260, -344, +65, -644, -157, -625, -344, -329, -409, 55, +-298, 408, -82, 585, 165, 501, 370, 217, +405, -101, 231, -385, -41, -533, -304, -420, +-458, -135, -407, 135, -183, 329, 84, 411, +299, 325, 394, 128, 306, -77, 77, -253, +-197, -357, -419, -278, -484, -109, -351, 33, +-101, 164, 163, 265, 362, 256, 403, 157, +243, 51, -26, -93, -274, -236, -425, -260, +-411, -189, -243, -104, -41, 41, 127, 206, +255, 282, 288, 245, 210, 143, 86, -42, +-69, -243, -247, -301, -359, -249, -359, -135, +-260, 52, -40, 250, 235, 310, 413, 235, +425, 105, 265, -81, -56, -264, -403, -293, +-589, -193, -555, -62, -321, 102, 76, 227, +464, 232, 622, 144, 498, 57, 168, -74, +-281, -196, -675, -177, -796, -84, -601, -25, +-190, 38, 321, 106, 711, 100, 758, 73, +466, 77, -23, 40, -556, -38, -889, -43, +-832, -54, -449, -128, 91, -163, 605, -114, +843, -17, 673, 140, 237, 314, -269, 323, +-701, 175, -869, -8, -666, -244, -229, -478, +262, -494, 664, -251, 794, 119, 565, 484, +107, 681, -407, 538, -819, 137, -911, -283, +-614, -631, -107, -749, 415, -507, 792, -15, +815, 474, 455, 777, -81, 755, -603, 355, +-937, -191, -895, -591, -491, -766, 62, -665, +571, -249, 840, 287, 731, 684, 309, 795, +-234, 582, -724, 92, -944, -408, -754, -690, +-260, -729, 292, -491, 696, -5, 809, 476, +559, 704, 51, 650, -480, 336, -823, -155, +-844, -547, -506, -623, 58, -460, 567, -132, +782, 260, 635, 496, 212, 474, -311, 267, +-716, -29, -835, -321, -612, -395, -129, -248, +388, -68, 663, 90, 578, 217, 241, 209, +-175, 91, -535, 6, -669, -28, -502, -66, +-171, -54, 183, 3, 441, -24, 425, -80, +134, -95, -179, -80, -366, -22, -411, 101, +-268, 190, -22, 160, 147, 112, 223, 66, +210, -75, 18, -233, -232, -264, -317, -210, +-239, -105, -97, 73, 86, 259, 203, 323, +161, 303, 44, 209, -101, -43, -291, -326, +-382, -460, -257, -420, -41, -224, 159, 134, +305, 457, 264, 550, 28, 462, -190, 224, +-338, -220, -463, -621, -425, -696, -165, -469, +137, -64, 356, 402, 438, 716, 278, 691, +-43, 430, -330, 0, -531, -522, -606, -823, +-432, -702, -70, -324, 284, 140, 526, 583, +564, 781, 318, 630, -97, 286, -450, -138, +-664, -579, -685, -769, -435, -610, 25, -262, +471, 137, 717, 509, 642, 691, 227, 607, +-311, 357, -707, -40, -858, -495, -722, -745, +-272, -677, 306, -405, 720, 18, 810, 506, +546, 832, 9, 823, -564, 513, -922, -37, +-949, -662, -641, -1025, -95, -971, 485, -542, +860, 135, 872, 840, 507, 1211, -96, 1073, +-680, 527, -1017, -267, -1007, -1034, -639, -1370, +-11, -1120, 623, -440, 986, 438, 942, 1180, +502, 1421, -192, 1056, -838, 320, -1161, -563, +-1047, -1261, -528, -1401, 206, -955, 835, -170, +1100, 688, 899, 1286, 294, 1312, -466, 812, +-1060, 51, -1246, -743, -946, -1278, -277, -1255, +469, -739, 990, 32, 1086, 818, 710, 1290, +11, 1207, -717, 670, -1163, -72, -1151, -841, +-706, -1317, -38, -1230, 583, -660, 926, 136, +886, 912, 492, 1338, -97, 1223, -669, 652, +-1007, -148, -963, -941, -562, -1394, -6, -1252, +482, -632, 785, 220, 804, 1017, 482, 1433, +-58, 1250, -598, 568, -942, -317, -927, -1107, +-562, -1477, -42, -1215, 466, -450, 811, 475, +826, 1219, 478, 1465, -88, 1094, -671, 287, +-1026, -586, -972, -1241, -569, -1403, -16, -955, +510, -151, 843, 639, 850, 1165, 506, 1258, +-89, 840, -703, 127, -1061, -561, -1020, -1034, +-631, -1150, -54, -814, 526, -206, 910, 430, +928, 930, 541, 1114, -104, 868, -743, 323, +-1097, -303, -1023, -891, -584, -1181, 27, -968, +594, -378, 929, 325, 902, 943, 481, 1232, +-203, 1020, -834, 402, -1107, -368, -958, -1043, +-489, -1323, 127, -1027, 668, -331, 938, 472, +827, 1116, 346, 1349, -315, 1018, -851, 285, +-1062, -544, -905, -1218, -463, -1436, 91, -1018, +597, -177, 904, 679, 856, 1289, 416, 1435, +-228, 991, -813, 133, -1127, -757, -1059, -1400, +-619, -1498, 53, -918, 725, 16, 1132, 870, +1058, 1403, 490, 1427, -331, 834, -1034, -82, +-1343, -921, -1152, -1444, -526, -1409, 302, -718, +1015, 236, 1298, 998, 994, 1391, 245, 1274, +-603, 610, -1222, -289, -1390, -1032, -1035, -1428, +-291, -1237, 548, -458, 1159, 458, 1264, 1093, +805, 1341, -5, 1095, -827, 362, -1333, -488, +-1330, -1104, -846, -1351, -68, -1057, 721, -243, +1169, 607, 1085, 1114, 570, 1219, -159, 902, +-857, 206, -1242, -542, -1163, -1046, -676, -1201, +50, -863, 737, -113, 1078, 600, 948, 970, +446, 1024, -251, 730, -886, 120, -1182, -507, +-1017, -885, -485, -977, 201, -691, 770, -69, +982, 522, 780, 830, 275, 872, -370, 643, +-916, 136, -1107, -410, -884, -794, -358, -944, +277, -727, 758, -155, 889, 437, 667, 811, +175, 951, -441, 772, -909, 244, -1017, -386, +-758, -847, -262, -1052, 288, -849, 672, -248, +765, 436, 557, 897, 119, 1040, -400, 798, +-790, 224, -883, -409, -657, -876, -218, -1059, +262, -816, 604, -178, 691, 492, 497, 900, +67, 970, -438, 704, -766, 155, -773, -444, +-512, -864, -106, -998, 315, -738, 556, -140, +517, 507, 272, 907, -69, 973, -399, 699, +-581, 161, -554, -444, -369, -902, -122, -1075, +113, -811, 278, -159, 331, 534, 260, 971, +78, 1060, -163, 803, -377, 226, -486, -463, +-465, -1005, -311, -1194, -67, -897, 159, -201, +295, 554, 336, 1064, 247, 1202, 21, 903, +-251, 235, -471, -544, -553, -1139, -452, -1332, +-214, -954, 83, -155, 374, 671, 531, 1208, +441, 1313, 128, 921, -287, 137, -637, -712, +-762, -1309, -614, -1411, -258, -921, 200, -43, +594, 809, 735, 1352, 541, 1414, 89, 928, +-447, 56, -852, -843, -947, -1456, -698, -1547, +-211, -981, 337, 5, 750, 970, 841, 1569, +556, 1602, 20, 985, -555, -52, -954, -1082, +-1014, -1717, -710, -1676, -161, -897, 443, 265, +860, 1273, 894, 1779, 555, 1590, -19, 725, +-637, -447, -1048, -1391, -1073, -1794, -711, -1492, +-71, -527, 610, 652, 1016, 1496, 977, 1739, +530, 1327, -169, 366, -857, -725, -1243, -1491, +-1160, -1706, -625, -1272, 171, -271, 879, 809, +1185, 1493, 972, 1635, 338, 1181, -459, 225, +-1105, -796, -1353, -1449, -1100, -1593, -410, -1140, +450, -186, 1084, 809, 1206, 1418, 809, 1516, +77, 1047, -705, 141, -1223, -769, -1276, -1346, +-847, -1468, -98, -1017, 654, -99, 1072, 798, +1016, 1334, 533, 1405, -172, 938, -782, 61, +-1075, -797, -1016, -1317, -602, -1385, 56, -913, +649, -29, 921, 827, 815, 1323, 374, 1345, +-230, 829, -727, -26, -968, -804, -906, -1247, +-518, -1297, 65, -841, 576, 10, 820, 801, +718, 1234, 305, 1239, -226, 775, -656, -8, +-869, -719, -812, -1152, -472, -1218, 22, -797, +448, -10, 669, 714, 635, 1127, 329, 1155, +-112, 726, -486, 4, -730, -652, -785, -1048, +-549, -1122, -111, -736, 322, -21, 627, 635, +706, 1018, 473, 1067, 18, 699, -458, 59, +-802, -542, -888, -961, -639, -1095, -157, -789, +364, -151, 758, 485, 846, 970, 527, 1164, +-34, 895, -577, 259, -947, -438, -1010, -1010, +-677, -1277, -97, -1033, 477, -353, 880, 466, +930, 1146, 533, 1412, -107, 1075, -690, 312, +-1065, -545, -1077, -1218, -658, -1454, -12, -1082, +597, -245, 988, 675, 958, 1327, 454, 1443, +-238, 964, -807, 110, -1104, -742, -1001, -1309, +-496, -1387, 154, -903, 684, -41, 945, 817, +810, 1347, 304, 1348, -311, 802, -788, -34, +-1020, -821, -892, -1313, -417, -1342, 162, -804, +634, 86, 890, 912, 774, 1366, 294, 1291, +-292, 690, -786, -165, -1046, -919, -913, -1341, +-418, -1234, 181, -593, 668, 268, 900, 952, +757, 1262, 272, 1090, -332, 472, -830, -298, +-1037, -897, -837, -1166, -336, -991, 212, -402, +643, 296, 857, 831, 720, 1074, 250, 929, +-336, 406, -818, -248, -1020, -791, -820, -1061, +-313, -919, 241, -393, 683, 248, 901, 772, +733, 1057, 201, 926, -431, 389, -910, -286, +-1052, -805, -771, -1021, -221, -843, 331, -329, +743, 287, 904, 769, 670, 979, 85, 799, +-552, 266, -955, -319, -995, -723, -664, -873, +-119, -716, 398, -259, 748, 280, 829, 686, +522, 845, -55, 676, -582, 216, -866, -284, +-847, -621, -518, -775, -34, -651, 376, -224, +636, 280, 688, 615, 427, 737, -66, 591, +-524, 191, -756, -250, -727, -548, -455, -685, +-30, -588, 370, -200, 605, 246, 590, 533, +294, 639, -144, 526, -503, 183, -664, -196, +-585, -476, -284, -619, 65, -514, 291, -155, +379, 212, 341, 407, 159, 489, -83, 428, +-274, 180, -394, -105, -419, -292, -311, -414, +-140, -405, 15, -229, 163, -21, 292, 147, +313, 328, 179, 461, -58, 407, -305, 206, +-466, -74, -465, -404, -313, -625, -112, -556, +111, -282, 355, 95, 478, 530, 357, 802, +57, 698, -293, 276, -557, -257, -616, -732, +-479, -914, -218, -658, 148, -131, 507, 402, +654, 818, 494, 918, 95, 581, -388, 19, +-734, -508, -780, -850, -567, -847, -218, -458, +221, 74, 643, 512, 812, 770, 597, 767, +93, 438, -484, -52, -889, -492, -946, -774, +-675, -760, -189, -409, 402, 74, 872, 477, +962, 743, 602, 761, -53, 448, -705, -67, +-1048, -530, -969, -803, -559, -764, 26, -379, +599, 129, 933, 519, 883, 733, 471, 716, +-173, 401, -795, -87, -1092, -526, -949, -745, +-485, -687, 128, -368, 710, 67, 1042, 435, +920, 682, 355, 742, -383, 490, -974, -2, +-1180, -482, -901, -785, -274, -799, 391, -483, +840, 35, 946, 508, 691, 807, 158, 844, +-471, 507, -931, -81, -1015, -606, -716, -878, +-188, -816, 358, -402, 745, 150, 874, 594, +669, 818, 140, 765, -495, 396, -935, -151, +-1007, -625, -672, -850, -65, -744, 511, -324, +817, 203, 796, 596, 473, 799, -61, 729, +-590, 339, -877, -208, -809, -659, -445, -858, +41, -706, 436, -252, 624, 274, 606, 647, +377, 795, -31, 691, -469, 292, -739, -238, +-738, -666, -471, -848, -34, -691, 390, -243, +616, 262, 588, 650, 348, 830, -60, 700, +-485, 276, -703, -281, -636, -743, -349, -902, +36, -646, 342, -128, 473, 397, 449, 751, +271, 819, -39, 551, -349, 81, -525, -407, +-538, -758, -390, -789, -87, -478, 247, -7, +442, 413, 481, 669, 360, 699, 43, 486, +-344, 76, -594, -378, -617, -719, -400, -789, +-26, -496, 313, 0, 485, 455, 466, 740, +265, 762, -74, 440, -397, -82, -544, -556, +-481, -795, -268, -696, 6, -267, 226, 247, +331, 585, 342, 686, 237, 516, 6, 133, +-237, -253, -390, -488, -432, -564, -349, -435, +-150, -121, 89, 204, 295, 404, 415, 472, +362, 402, 106, 194, -219, -84, -428, -359, +-468, -531, -379, -490, -174, -220, 99, 123, +331, 409, 421, 553, 320, 475, 89, 185, +-151, -181, -347, -462, -473, -574, -467, -436, +-304, -81, -7, 279, 329, 451, 557, 459, +556, 333, 278, 66, -168, -221, -572, -393, +-785, -435, -705, -319, -297, -61, 269, 167, +721, 297, 830, 376, 523, 367, -43, 187, +-573, -87, -832, -324, -745, -451, -371, -416, +155, -204, 578, 78, 662, 322, 463, 496, +132, 480, -257, 220, -530, -141, -547, -419, +-398, -561, -176, -479, 80, -158, 285, 219, +401, 477, 397, 585, 223, 483, -72, 130, +-360, -273, -546, -549, -546, -642, -301, -481, +67, -81, 353, 325, 494, 582, 467, 661, +195, 500, -225, 80, -513, -387, -532, -648, +-372, -676, -139, -466, 106, -14, 291, 457, +360, 698, 304, 683, 135, 414, -112, -49, +-331, -501, -405, -756, -347, -726, -226, -385, +-40, 180, 199, 658, 390, 812, 413, 678, +210, 313, -107, -274, -335, -799, -422, -937, +-388, -654, -236, -104, -20, 513, 191, 925, +336, 893, 360, 458, 246, -156, 1, -692, +-259, -911, -389, -691, -434, -185, -420, 402, +-211, 798, 166, 737, 489, 316, 590, -141, +413, -463, 40, -592, -363, -443, -662, -70, +-711, 282, -447, 392, 8, 312, 433, 138, +679, -60, 664, -169, 318, -159, -230, -70, +-632, 15, -726, 12, -585, -49, -247, -61, +191, -27, 541, 35, 683, 114, 533, 198, +109, 207, -353, 48, -626, -174, -676, -281, +-499, -259, -101, -145, 325, 45, 550, 244, +563, 344, 394, 233, 3, 10, -433, -162, +-613, -256, -523, -259, -294, -126, 15, 99, +271, 231, 376, 167, 393, 45, 295, -25, +28, -90, -250, -85, -397, -4, -435, 56, +-380, 88, -203, 27, 78, -159, 370, -245, +550, -112, 527, 84, 237, 224, -239, 300, +-622, 273, -736, 31, -572, -293, -166, -446, +327, -389, 686, -170, 776, 177, 518, 481, +-35, 560, -606, 358, -878, -43, -758, -407, +-366, -572, 161, -484, 635, -219, 795, 141, +618, 506, 215, 644, -338, 429, -772, 53, +-829, -302, -545, -546, -57, -570, 440, -352, +691, 29, 621, 387, 343, 575, -54, 534, +-488, 251, -736, -167, -589, -498, -190, -628, +173, -462, 419, -41, 500, 349, 361, 557, +94, 566, -173, 328, -370, -120, -411, -526, +-305, -636, -136, -412, 57, -13, 216, 372, +249, 522, 208, 387, 177, 122, 91, -190, +-112, -411, -321, -357, -405, -73, -345, 199, +-173, 304, 81, 214, 339, -15, 476, -271, +412, -329, 146, -101, -229, 182, -547, 341, +-661, 338, -477, 140, -44, -198, 387, -467, +609, -495, 581, -226, 325, 227, -81, 601, +-508, 625, -751, 311, -640, -107, -248, -524, +234, -764, 620, -597, 698, -125, 472, 397, +102, 796, -363, 825, -751, 457, -781, -82, +-437, -623, 94, -963, 584, -854, 786, -318, +593, 343, 126, 875, -368, 1103, -704, 861, +-769, 148, -451, -703, 115, -1277, 570, -1273, +709, -664, 497, 301, 21, 1206, -437, 1602, +-625, 1252, -531, 276, -236, -922, 164, -1758, +497, -1742, 541, -878, 264, 458, -136, 1662, +-444, 2049, -506, 1394, -288, 79, 29, -1283, +275, -2085, 402, -1870, 326, -676, 32, 906, +-297, 2028, -460, 2109, -371, 1102, -75, -448, +241, -1724, 392, -2127, 332, -1488, 102, -75, +-201, 1410, -402, 2133, -396, 1695, -204, 379, +91, -1073, 340, -1942, 402, -1786, 231, -672, +-74, 785, -313, 1780, -391, 1836, -310, 920, +-74, -505, 201, -1655, 354, -1942, 322, -1212, +113, 202, -167, 1539, -358, 2021, -385, 1456, +-211, 197, 96, -1186, 333, -2037, 367, -1849, +188, -681, -85, 837, -295, 1943, -389, 2092, +-306, 1208, -27, -309, 284, -1704, 441, -2256, +353, -1701, 42, -327, -312, 1238, -501, 2232, +-435, 2133, -180, 1024, 156, -592, 484, -1967, +592, -2365, 346, -1588, -83, -103, -500, 1409, +-743, 2247, -580, 1984, -80, 766, 418, -775, +702, -1894, 675, -2076, 316, -1261, -217, 126, +-675, 1398, -839, 1925, -577, 1476, -4, 346, +548, -825, 785, -1497, 627, -1439, 200, -735, +-266, 253, -599, 1051, -700, 1255, -489, 799, +-54, 47, 374, -547, 611, -797, 543, -665, +215, -269, -131, 160, -351, 436, -462, 463, +-427, 272, -202, 22, 98, -142, 325, -207, +417, -202, 301, -126, 32, -34, -151, 1, +-203, 93, -269, 221, -277, 205, -142, 75, +17, -57, 126, -176, 199, -242, 230, -196, +191, -25, 77, 231, -61, 349, -226, 222, +-397, -16, -406, -236, -187, -380, 146, -339, +444, -73, 534, 291, 376, 525, 67, 466, +-320, 149, -622, -248, -632, -524, -331, -606, +130, -406, 540, 53, 707, 502, 531, 702, +76, 588, -391, 199, -630, -277, -605, -634, +-347, -734, 66, -488, 441, -38, 602, 416, +494, 739, 172, 755, -239, 406, -533, -115, +-538, -573, -330, -810, -66, -735, 231, -351, +490, 200, 547, 702, 329, 971, -94, 800, +-499, 221, -636, -427, -458, -891, -104, -1036, +309, -736, 628, -102, 626, 624, 279, 1148, +-201, 1137, -637, 590, -813, -207, -488, -926, +161, -1262, 671, -1041, 780, -368, 493, 490, +-20, 1178, -518, 1362, -776, 921, -665, 53, +-191, -853, 445, -1401, 822, -1311, 688, -654, +228, 284, -311, 1161, -710, 1533, -689, 1186, +-323, 333, 74, -725, 444, -1508, 681, -1528, +527, -861, 63, 153, -365, 1161, -568, 1655, +-513, 1322, -209, 387, 175, -706, 387, -1473, +396, -1557, 273, -927, 21, 124, -233, 1126, +-320, 1585, -242, 1229, -79, 322, 91, -617, +164, -1216, 91, -1281, -20, -791, -1, 46, +91, 859, 96, 1188, 47, 913, -42, 311, +-199, -383, -260, -876, -160, -872, -38, -503, +127, -50, 361, 433, 407, 757, 142, 684, +-187, 289, -391, -171, -443, -503, -270, -545, +57, -333, 304, -118, 391, 106, 331, 370, +120, 408, -157, 192, -379, 12, -408, -113, +-191, -191, 86, -156, 242, -97, 266, -62, +199, -18, 79, 9, -72, 48, -202, 140, +-216, 192, -124, 153, -18, 33, 68, -126, +136, -255, 144, -283, 85, -185, 33, 45, +-22, 297, -131, 372, -186, 268, -145, 56, +-62, -244, 112, -424, 280, -280, 239, -20, +82, 173, -86, 287, -293, 228, -376, 29, +-207, -157, 77, -283, 357, -227, 522, 79, +363, 348, -90, 314, -488, 76, -621, -172, +-474, -366, -21, -387, 504, -164, 743, 177, +631, 439, 203, 480, -441, 270, -902, -90, +-853, -426, -351, -566, 342, -395, 883, -38, +966, 281, 563, 465, -88, 506, -712, 368, +-1031, 61, -830, -315, -203, -583, 516, -605, +976, -430, 933, -106, 448, 361, -184, 790, +-718, 882, -920, 588, -691, 1, -196, -716, +381, -1173, 811, -1065, 822, -457, 452, 442, +-57, 1251, -524, 1436, -739, 895, -603, -62, +-275, -1064, 111, -1628, 513, -1339, 706, -357, +518, 755, 154, 1515, -200, 1575, -520, 834, +-608, -317, -409, -1238, -118, -1527, 230, -1103, +544, -187, 575, 768, 372, 1274, 74, 1137, +-303, 502, -583, -307, -564, -884, -296, -944, +77, -561, 403, -29, 544, 440, 476, 649, +235, 515, -136, 183, -475, -126, -577, -314, +-410, -327, -70, -172, 279, -17, 443, 0, +431, -19, 324, 42, 68, 120, -249, 201, +-449, 258, -478, 192, -287, -6, 60, -238, +314, -428, 392, -451, 374, -193, 239, 218, +-22, 508, -291, 549, -464, 352, -438, -64, +-146, -483, 195, -620, 349, -428, 401, -57, +356, 357, 95, 618, -201, 529, -362, 151, +-421, -267, -315, -543, -41, -540, 247, -209, +441, 185, 447, 423, 234, 490, -47, 307, +-277, -99, -459, -402, -497, -445, -239, -297, +186, 7, 486, 335, 579, 497, 431, 395, +23, 71, -408, -305, -624, -512, -562, -483, +-224, -239, 223, 153, 572, 517, 702, 641, +474, 450, -55, 18, -548, -452, -745, -692, +-578, -634, -111, -275, 395, 297, 677, 733, +675, 761, 377, 479, -160, -27, -627, -620, +-740, -909, -503, -713, -26, -196, 478, 425, +689, 882, 567, 871, 258, 432, -166, -164, +-516, -701, -598, -920, -465, -619, -179, -26, +254, 496, 605, 786, 627, 673, 412, 174, +98, -366, -311, -641, -664, -567, -743, -185, +-506, 276, 19, 535, 626, 454, 955, 103, +843, -311, 344, -531, -349, -384, -925, 42, +-1108, 461, -767, 601, -15, 387, 765, -129, +1205, -691, 1104, -881, 477, -503, -379, 188, +-1071, 839, -1281, 1165, -884, 879, -80, 29, +738, -925, 1215, -1469, 1174, -1287, 647, -401, +-204, 739, -999, 1582, -1301, 1679, -1023, 912, +-331, -345, 532, -1455, 1171, -1866, 1272, -1367, +836, -213, 60, 1046, -769, 1845, -1309, 1741, +-1250, 763, -585, -524, 317, -1496, 1049, -1795, +1340, -1269, 1033, -147, 257, 956, -598, 1571, +-1174, 1517, -1234, 797, -734, -255, 80, -1103, +804, -1446, 1146, -1178, 993, -420, 424, 445, +-255, 1061, -753, 1249, -957, 923, -809, 205, +-324, -547, 278, -1031, 737, -1092, 915, -686, +773, 10, 326, 616, -274, 925, -764, 882, +-972, 478, -831, -109, -300, -602, 451, -815, +1019, -679, 1096, -299, 695, 113, 57, 442, +-617, 602, -1103, 554, -1077, 341, -506, 41, +249, -274, 842, -505, 1078, -591, 881, -524, +309, -249, -401, 190, -897, 591, -1005, 788, +-741, 723, -157, 330, 548, -291, 1032, -850, +1059, -1062, 604, -803, -100, -166, -747, 579, +-1135, 1125, -1030, 1207, -364, 708, 520, -163, +1126, -980, 1165, -1352, 664, -1126, -130, -384, +-877, 585, -1193, 1306, -874, 1401, -119, 842, +653, -94, 1063, -982, 912, -1409, 317, -1212, +-384, -460, -845, 539, -862, 1275, -438, 1344, +205, 799, 689, -31, 753, -813, 443, -1235, +-42, -1084, -483, -445, -652, 360, -444, 967, +-16, 1090, 364, 722, 538, 87, 442, -539, +105, -903, -266, -858, -445, -459, -362, 105, +-100, 613, 154, 848, 294, 697, 314, 234, +180, -289, -63, -659, -225, -750, -200, -525, +-81, -88, 13, 395, 73, 738, 81, 730, +18, 361, -8, -129, 32, -534, 48, -722, +68, -602, 95, -197, 30, 308, -117, 670, +-255, 703, -258, 401, -73, -74, 170, -505, +370, -711, 448, -584, 277, -168, -73, 335, +-397, 683, -591, 674, -549, 330, -174, -130, +399, -523, 800, -711, 768, -547, 351, -91, +-221, 390, -703, 663, -891, 616, -665, 276, +-48, -197, 659, -539, 976, -602, 776, -400, +270, -21, -359, 378, -847, 569, -861, 473, +-417, 154, 154, -241, 587, -475, 740, -436, +538, -219, 76, 55, -378, 320, -569, 416, +-424, 269, -113, 20, 157, -181, 318, -287, +305, -227, 83, -40, -143, 101, -155, 145, +-32, 111, 79, -4, 140, -106, 131, -76, +-10, 13, -231, 92, -360, 155, -265, 120, +41, -43, 376, -194, 531, -248, 452, -210, +156, -39, -282, 188, -622, 339, -700, 374, +-475, 228, 42, -85, 628, -343, 926, -472, +773, -486, 243, -253, -412, 181, -893, 575, +-990, 778, -630, 654, 55, 150, 765, -465, +1133, -930, 924, -1090, 277, -712, -466, 141, +-1005, 969, -1062, 1407, -593, 1268, 94, 438, +699, -719, 1011, -1560, 843, -1710, 257, -1048, +-399, 206, -794, 1385, -802, 1940, -475, 1660, +20, 539, 461, -936, 675, -1931, 575, -2003, +212, -1213, -176, 150, -405, 1480, -462, 2112, +-340, 1788, -65, 679, 204, -746, 334, -1799, +290, -2032, 131, -1424, -15, -199, -112, 1135, +-172, 1943, -139, 1885, -21, 1044, 48, -229, +46, -1392, 34, -1965, -9, -1716, -53, -727, +0, 585, 86, 1612, 121, 1944, 122, 1479, +52, 391, -72, -854, -172, -1713, -249, -1844, +-247, -1214, -61, -100, 208, 1020, 374, 1731, +388, 1741, 250, 998, -49, -143, -369, -1163, +-515, -1711, -465, -1617, -208, -860, 237, 294, +609, 1347, 658, 1839, 394, 1591, -63, 676, +-467, -563, -623, -1600, -552, -1997, -254, -1572, +230, -434, 602, 958, 626, 1964, 387, 2140, +42, 1384, -301, -37, -506, -1479, -468, -2261, +-261, -2078, -5, -982, 248, 633, 418, 1989, +418, 2415, 251, 1758, 9, 302, -205, -1319, +-338, -2314, -386, -2247, -285, -1174, -46, 444, +200, 1855, 354, 2388, 383, 1832, 275, 451, +56, -1141, -184, -2177, -330, -2177, -326, -1213, +-233, 262, -103, 1611, 75, 2190, 269, 1761, +364, 569, 321, -855, 188, -1851, -13, -1961, +-250, -1210, -435, 46, -476, 1258, -325, 1842, +1, 1565, 390, 635, 684, -535, 677, -1438, +309, -1642, -225, -1114, -674, -151, -853, 853, +-657, 1436, -132, 1339, 506, 702, 953, -176, +947, -971, 461, -1307, -271, -1065, -858, -434, +-1022, 342, -706, 992, -70, 1216, 577, 928, +948, 271, 880, -484, 373, -1033, -300, -1176, +-761, -864, -859, -182, -550, 650, 41, 1235, +527, 1264, 680, 742, 562, -98, 205, -936, +-246, -1403, -493, -1262, -476, -553, -285, 444, +29, 1287, 303, 1563, 345, 1106, 232, 137, +85, -881, -86, -1510, -183, -1484, -157, -787, +-134, 282, -88, 1239, 53, 1645, 139, 1299, +116, 353, 79, -740, 37, -1471, -25, -1554, +-78, -978, -123, 31, -104, 1053, 8, 1602, +105, 1412, 121, 588, 94, -461, 28, -1277, +-73, -1553, -141, -1146, -141, -216, -69, 788, +54, 1421, 146, 1423, 179, 784, 166, -175, +38, -1019, -153, -1425, -249, -1196, -234, -433, +-122, 473, 86, 1148, 273, 1343, 323, 920, +252, 101, 54, -688, -232, -1171, -414, -1191, +-366, -674, -173, 134, 104, 833, 398, 1164, +483, 992, 301, 397, 26, -321, -244, -882, +-443, -1087, -446, -806, -255, -170, 53, 496, +350, 927, 463, 957, 362, 568, 160, -29, +-78, -570, -318, -889, -450, -842, -394, -417, +-177, 169, 106, 658, 356, 868, 469, 690, +402, 252, 175, -226, -135, -634, -394, -821, +-516, -628, -447, -163, -166, 327, 210, 680, +485, 735, 560, 461, 402, 47, 95, -351, +-220, -654, -488, -674, -604, -346, -431, 95, +-59, 446, 299, 615, 550, 510, 591, 179, +379, -176, 45, -436, -305, -527, -616, -385, +-668, -78, -376, 216, 28, 402, 384, 424, +652, 260, 683, 30, 403, -161, -59, -307, +-519, -342, -769, -224, -699, -67, -349, 75, +165, 211, 655, 281, 877, 252, 708, 157, +219, 6, -395, -156, -839, -266, -892, -332, +-550, -290, 27, -78, 601, 187, 882, 381, +756, 468, 324, 349, -256, 26, -714, -304, +-773, -537, -481, -598, -70, -346, 330, 115, +576, 499, 568, 694, 344, 613, -2, 204, +-319, -305, -444, -635, -384, -727, -234, -537, +-42, -60, 150, 442, 287, 721, 339, 723, +277, 414, 98, -99, -80, -512, -205, -710, +-309, -677, -342, -341, -230, 180, -25, 594, +199, 777, 386, 671, 445, 232, 333, -320, +51, -706, -304, -823, -547, -608, -561, -84, +-356, 489, 35, 854, 470, 857, 723, 433, +652, -206, 260, -702, -285, -887, -704, -696, +-796, -152, -544, 450, -26, 812, 533, 814, +830, 415, 738, -201, 334, -651, -243, -770, +-717, -570, -826, -82, -554, 436, -55, 662, +447, 593, 724, 313, 680, -151, 363, -518, +-130, -565, -571, -389, -720, -74, -539, 294, +-149, 458, 303, 372, 620, 193, 648, -63, +397, -302, -41, -354, -468, -255, -645, -76, +-523, 174, -192, 321, 267, 253, 590, 106, +543, -49, 263, -209, -65, -253, -388, -158, +-526, -12, -362, 162, -64, 262, 224, 179, +402, 0, 345, -161, 131, -241, -39, -149, +-176, 38, -280, 165, -233, 214, -108, 161, +-10, -31, 102, -226, 202, -274, 235, -178, +243, 53, 139, 308, -120, 359, -348, 166, +-419, -97, -343, -322, -94, -411, 264, -243, +556, 75, 642, 346, 389, 475, -137, 372, +-607, 13, -801, -381, -683, -564, -206, -464, +443, -132, 904, 285, 991, 564, 621, 572, +-143, 332, -876, -74, -1174, -488, -982, -674, +-321, -523, 578, -142, 1216, 307, 1295, 641, +825, 683, -89, 393, -1054, -68, -1509, -498, +-1247, -739, -416, -662, 642, -266, 1400, 275, +1496, 718, 974, 852, 3, 585, -1067, 54, +-1647, -504, -1408, -871, -549, -861, 515, -465, +1347, 135, 1580, 709, 1122, 995, 175, 818, +-832, 281, -1458, -377, -1449, -887, -820, -995, +169, -662, 1048, -83, 1433, 539, 1224, 961, +539, 931, -358, 485, -1091, -126, -1351, -697, +-1058, -964, -340, -746, 489, -260, 1096, 251, +1276, 696, 951, 842, 216, 574, -582, 131, +-1115, -310, -1238, -653, -863, -673, -94, -395, +702, -70, 1189, 231, 1227, 465, 743, 494, +-98, 372, -872, 181, -1240, -110, -1115, -360, +-531, -423, 298, -409, 974, -319, 1218, -50, +952, 260, 284, 501, -491, 628, -1006, 483, +-1071, 77, -712, -350, -104, -680, 526, -799, +938, -554, 955, -33, 579, 538, -10, 948, +-559, 953, -858, 487, -813, -190, -492, -807, +2, -1134, 515, -938, 831, -287, 804, 448, +490, 1016, -9, 1216, -552, 843, -859, 58, +-800, -728, -476, -1209, 22, -1181, 589, -627, +937, 177, 884, 900, 475, 1281, -140, 1132, +-728, 477, -1029, -384, -919, -1087, -412, -1366, +314, -1040, 915, -241, 1126, 611, 876, 1204, +232, 1357, -560, 916, -1092, 47, -1122, -821, +-678, -1345, 55, -1305, 769, -671, 1124, 234, +973, 975, 424, 1308, -287, 1112, -854, 424, +-1034, -413, -739, -1016, -154, -1219, 413, -906, +778, -181, 855, 539, 579, 984, 68, 1043, +-413, 636, -705, -4, -723, -548, -456, -898, +-34, -900, 364, -449, 624, 172, 650, 626, +432, 823, 77, 670, -321, 197, -628, -282, +-660, -595, -417, -699, -73, -464, 300, -10, +631, 349, 743, 545, 524, 505, 67, 189, +-422, -122, -747, -275, -801, -352, -538, -279, +11, -73, 618, 71, 967, 142, 892, 170, +426, 108, -269, 53, -866, 71, -1082, 34, +-835, -38, -194, -73, 583, -170, 1102, -245, +1117, -127, 645, 47, -143, 184, -882, 327, +-1213, 303, -1010, 87, -369, -121, 477, -322, +1133, -458, 1266, -308, 820, 28, 8, 307, +-814, 487, -1273, 473, -1170, 183, -561, -189, +337, -448, 1126, -570, 1392, -439, 1002, -46, +178, 359, -723, 611, -1305, 622, -1303, 293, +-741, -187, 159, -518, 1020, -647, 1420, -526, +1165, -135, 417, 350, -513, 684, -1219, 692, +-1361, 350, -906, -144, -96, -551, 769, -713, +1321, -563, 1254, -147, 636, 348, -220, 689, +-967, 725, -1286, 403, -1034, -130, -368, -571, +441, -735, 1055, -584, 1194, -156, 841, 339, +175, 670, -567, 729, -1061, 440, -1070, -102, +-688, -579, -80, -748, 612, -598, 1106, -207, +1117, 302, 656, 700, -62, 764, -760, 491, +-1171, -2, -1153, -521, -652, -786, 219, -691, +1058, -333, 1407, 194, 1155, 688, 439, 849, +-507, 616, -1308, 140, -1542, -419, -1076, -845, +-125, -880, 904, -504, 1551, 78, 1516, 676, +828, 1031, -214, 886, -1182, 328, -1635, -368, +-1381, -965, -533, -1156, 555, -813, 1385, -116, +1591, 685, 1155, 1253, 280, 1231, -733, 619, +-1436, -251, -1505, -1021, -967, -1379, -69, -1133, +874, -361, 1458, 597, 1437, 1324, 860, 1446, +-63, 889, -999, -41, -1526, -955, -1418, -1484, +-723, -1336, 312, -593, 1224, 391, 1616, 1245, +1364, 1557, 524, 1159, -619, 267, -1490, -757, +-1667, -1464, -1144, -1499, -132, -892, 984, 63, +1667, 1028, 1583, 1585, 799, 1412, -324, 607, +-1268, -423, -1646, -1283, -1325, -1608, -411, -1204, +706, -286, 1453, 743, 1521, 1483, 968, 1567, +16, 956, -935, -34, -1441, -1014, -1303, -1568, +-630, -1443, 297, -722, 1062, 290, 1349, 1189, +1085, 1590, 368, 1314, -512, 505, -1116, -478, +-1202, -1268, -827, -1562, -135, -1206, 613, -350, +1085, 662, 1091, 1421, 661, 1574, -39, 1058, +-699, 108, -1033, -897, -951, -1551, -505, -1565, +158, -871, 763, 258, 1010, 1271, 845, 1719, +377, 1404, -239, 440, -785, -716, -993, -1538, +-774, -1687, -249, -1056, 361, 69, 829, 1130, +991, 1648, 746, 1396, 153, 504, -512, -561, +-935, -1287, -986, -1409, -639, -927, 21, -39, +714, 820, 1089, 1204, 985, 1026, 468, 446, +-274, -279, -928, -795, -1183, -922, -902, -678, +-207, -175, 597, 352, 1140, 675, 1187, 725, +699, 504, -114, 107, -863, -300, -1227, -581, +-1081, -658, -448, -514, 441, -169, 1137, 273, +1292, 631, 874, 758, 98, 581, -718, 159, +-1226, -352, -1199, -790, -620, -919, 247, -612, +973, -42, 1260, 571, 1028, 995, 357, 961, +-484, 480, -1077, -194, -1182, -828, -819, -1132, +-130, -885, 636, -215, 1122, 516, 1127, 1022, +715, 1093, 29, 635, -712, -112, -1179, -767, +-1151, -1097, -659, -935, 128, -309, 892, 420, +1309, 922, 1209, 1025, 599, 667, -320, 23, +-1135, -603, -1458, -969, -1166, -914, -369, -438, +617, 230, 1360, 759, 1524, 934, 1053, 734, +124, 228, -881, -396, -1506, -839, -1482, -893, +-845, -543, 139, 20, 1084, 553, 1617, 853, +1488, 749, 687, 298, -417, -235, -1320, -661, +-1687, -794, -1381, -523, -444, -45, 746, 386, +1633, 652, 1801, 619, 1176, 283, 44, -136, +-1121, -442, -1828, -546, -1720, -400, -812, -75, +447, 211, 1507, 352, 1921, 369, 1454, 232, +319, 14, -922, -136, -1727, -221, -1762, -232, +-995, -138, 187, -46, 1260, 6, 1788, 76, +1505, 158, 513, 210, -654, 194, -1455, 100, +-1600, -50, -1050, -226, -57, -339, 923, -298, +1469, -121, 1355, 125, 635, 360, -306, 477, +-1039, 358, -1289, 22, -976, -327, -270, -519, +488, -494, 1011, -235, 1078, 133, 653, 442, +6, 589, -563, 452, -863, 80, -771, -296, +-359, -519, 117, -522, 507, -285, 695, 67, +549, 364, 167, 497, -195, 422, -406, 158, +-434, -171, -292, -388, -98, -430, 99, -309, +279, -51, 318, 223, 194, 386, 86, 388, +-1, 208, -119, -61, -178, -280, -185, -372, +-189, -302, -83, -114, 107, 123, 186, 326, +211, 362, 247, 194, 155, -42, -60, -227, +-226, -286, -309, -201, -287, -36, -113, 141, +107, 240, 277, 193, 384, 17, 336, -172, +103, -238, -156, -148, -366, 34, -468, 223, +-324, 283, 10, 166, 302, -46, 467, -263, +490, -369, 297, -274, -60, -6, -415, 302, +-579, 457, -456, 363, -135, 83, 203, -270, +491, -509, 610, -481, 429, -206, 61, 197, +-309, 535, -566, 601, -562, 365, -275, -45, +87, -476, 392, -709, 564, -586, 493, -171, +199, 316, -154, 675, -444, 749, -516, 467, +-317, -19, -43, -487, 192, -778, 410, -720, +462, -319, 246, 187, -13, 628, -196, 818, +-352, 603, -368, 144, -173, -324, 66, -684, +248, -765, 365, -480, 330, 7, 144, 484, +-101, 761, -309, 676, -381, 282, -242, -181, +3, -572, 217, -752, 354, -561, 360, -111, +171, 360, -118, 704, -317, 719, -351, 372, +-232, -83, -10, -484, 214, -703, 319, -575, +295, -186, 157, 250, -59, 584, -244, 629, +-292, 345, -218, -41, -71, -346, 123, -501, +260, -408, 263, -108, 163, 167, 27, 324, +-123, 341, -224, 161, -215, -59, -118, -146, +4, -174, 112, -136, 176, -5, 172, 50, +123, 22, 45, 24, -41, 24, -112, 24, +-151, 77, -169, 89, -138, 8, -12, -76, +162, -131, 256, -168, 254, -103, 187, 66, +-3, 188, -236, 209, -346, 127, -314, -54, +-174, -203, 100, -212, 362, -115, 422, 53, +310, 200, 110, 221, -173, 105, -427, -104, +-473, -278, -311, -289, -20, -130, 309, 125, +523, 354, 509, 397, 300, 215, -55, -103, +-436, -397, -619, -522, -513, -412, -200, -75, +228, 345, 603, 625, 686, 619, 446, 319, +25, -159, -408, -595, -683, -785, -636, -617, +-275, -157, 212, 390, 588, 796, 687, 862, +502, 542, 110, -50, -342, -671, -649, -997, +-630, -860, -313, -367, 124, 309, 472, 894, +613, 1074, 525, 778, 227, 147, -190, -584, +-524, -1068, -604, -1054, -443, -582, -99, 126, +308, 799, 587, 1114, 618, 909, 433, 346, +58, -335, -383, -905, -651, -1067, -647, -740, +-382, -125, 102, 539, 585, 954, 782, 924, +667, 551, 287, -24, -268, -624, -722, -938, +-820, -823, -568, -385, -59, 200, 521, 699, +851, 884, 777, 704, 407, 261, -110, -288, +-607, -705, -821, -794, -659, -575, -213, -135, +310, 364, 670, 659, 738, 670, 544, 471, +140, 90, -351, -317, -679, -544, -700, -573, +-430, -395, 18, -50, 450, 278, 685, 478, +666, 543, 367, 408, -128, 84, -557, -262, +-722, -495, -588, -566, -193, -400, 314, -28, +658, 347, 710, 606, 488, 643, 43, 372, +-449, -70, -733, -466, -689, -699, -333, -640, +178, -268, 583, 228, 726, 610, 601, 727, +220, 540, -315, 122, -702, -345, -748, -644, +-485, -651, -22, -383, 468, 35, 753, 414, +711, 591, 360, 495, -172, 184, -622, -170, +-778, -410, -603, -455, -172, -308, 369, -51, +742, 207, 753, 353, 422, 304, -93, 124, +-574, -69, -783, -201, -605, -225, -151, -155, +361, -36, 693, 67, 686, 104, 355, 82, +-126, 23, -541, -47, -679, -50, -482, 12, +-64, 50, 378, 47, 618, 15, 526, -60, +197, -143, -162, -161, -437, -116, -526, -19, +-352, 139, 2, 254, 320, 210, 465, 82, +400, -62, 170, -229, -109, -311, -324, -243, +-390, -97, -281, 99, -41, 272, 189, 290, +327, 189, 331, 53, 195, -125, -4, -285, +-156, -298, -234, -178, -240, -25, -135, 138, +29, 249, 151, 239, 209, 151, 215, 17, +150, -151, 58, -249, -50, -228, -173, -130, +-236, 15, -172, 151, -28, 213, 122, 210, +246, 137, 286, -6, 211, -147, 41, -223, +-165, -208, -302, -105, -258, 33, -93, 143, +92, 216, 254, 225, 318, 121, 235, -31, +60, -134, -119, -190, -247, -180, -251, -76, +-143, 37, 18, 117, 171, 175, 254, 164, +239, 91, 159, 23, 18, -42, -158, -101, +-258, -111, -226, -93, -97, -76, 72, -22, +238, 80, 304, 160, 234, 188, 63, 177, +-143, 93, -278, -54, -261, -180, -116, -245, +72, -222, 227, -84, 265, 115, 177, 281, +15, 334, -141, 265, -216, 103, -149, -110, +-9, -297, 92, -369, 126, -305, 102, -113, +27, 151, -57, 364, -85, 455, -60, 400, +-2, 181, 66, -157, 90, -455, 26, -574, +-56, -472, -96, -151, -92, 291, -54, 634, +10, 717, 68, 503, 93, 28, 102, -504, +55, -811, -34, -769, -105, -391, -125, 196, +-124, 720, -94, 919, -5, 706, 127, 160, +223, -487, 210, -921, 93, -932, -83, -546, +-230, 64, -303, 661, -254, 973, -72, 848, +185, 341, 362, -328, 347, -839, 161, -977, +-93, -717, -308, -155, -392, 483, -296, 901, +-75, 916, 186, 523, 359, -119, 357, -715, +184, -1000, -44, -846, -236, -311, -320, 369, +-264, 879, -118, 993, 70, 651, 233, -19, +292, -710, 215, -1071, 66, -938, -94, -391, +-193, 344, -201, 924, -141, 1062, -39, 700, +95, -5, 188, -719, 182, -1083, 127, -935, +56, -375, -18, 350, -76, 902, -111, 1005, +-127, 615, -98, -51, -27, -679, 80, -980, +204, -795, 273, -230, 220, 408, 66, 826, +-133, 845, -306, 452, -321, -153, -160, -671, +88, -853, 332, -613, 463, -73, 366, 480, +90, 768, -216, 694, -424, 310, -412, -238, +-173, -669, 136, -746, 362, -455, 453, 60, +344, 549, 86, 759, -179, 619, -339, 203, +-341, -324, -177, -702, 64, -727, 247, -400, +328, 113, 296, 593, 152, 817, -45, 660, +-190, 214, -251, -326, -204, -727, -67, -782, +93, -467, 205, 60, 241, 574, 188, 833, +55, 728, -76, 328, -160, -223, -174, -676, +-100, -791, 21, -552, 101, -82, 128, 441, +107, 759, 38, 726, -29, 418, -41, -48, +-17, -512, 1, -722, 15, -576, -12, -207, +-62, 235, -86, 582, -60, 657, 22, 470, +136, 121, 194, -296, 139, -564, -7, -543, +-195, -321, -321, 15, -271, 362, -62, 529, +177, 463, 363, 245, 377, -69, 167, -359, +-159, -475, -435, -396, -515, -172, -324, 123, +56, 346, 402, 409, 550, 340, 418, 142, +46, -140, -361, -352, -582, -428, -546, -355, +-237, -126, 208, 141, 521, 335, 551, 430, +328, 347, -46, 78, -420, -219, -570, -431, +-445, -501, -142, -352, 203, -43, 437, 258, +447, 455, 265, 477, -27, 251, -298, -111, +-403, -407, -316, -545, -122, -461, 91, -153, +258, 202, 286, 432, 184, 474, 32, 276, +-107, -86, -173, -395, -139, -498, -60, -386, +13, -114, 55, 204, 41, 401, 13, 377, +25, 156, 66, -158, 86, -396, 111, -407, +102, -219, -8, 43, -162, 271, -235, 348, +-180, 220, -28, -31, 176, -274, 339, -386, +368, -278, 226, -7, -40, 249, -304, 362, +-401, 298, -309, 60, -67, -232, 246, -410, +481, -408, 500, -207, 280, 141, -53, 427, +-356, 499, -488, 371, -385, 63, -84, -305, +285, -521, 541, -510, 547, -294, 326, 85, +-40, 445, -410, 598, -573, 526, -430, 246, +-68, -180, 330, -512, 605, -585, 606, -443, +328, -101, -95, 334, -483, 605, -637, 624, +-445, 425, -30, 11, 380, -418, 629, -609, +607, -545, 305, -255, -127, 197, -471, 571, +-611, 684, -465, 548, -91, 187, 317, -281, +574, -599, 569, -636, 322, -411, -44, 27, +-376, 478, -560, 701, -499, 655, -188, 357, +220, -118, 496, -523, 540, -673, 340, -539, +-10, -149, -344, 325, -515, 632, -438, 673, +-164, 454, 170, 43, 396, -374, 416, -603, +229, -577, -56, -298, -286, 121, -357, 469, +-273, 612, -81, 528, 119, 227, 218, -173, +190, -477, 72, -597, -50, -488, -127, -164, +-138, 223, -100, 516, -43, 632, 2, 487, +9, 106, -13, -313, -24, -598, -3, -662, +41, -461, 62, -49, 29, 382, -25, 639, +-92, 624, -143, 325, -164, -137, -112, -525, +19, -678, 161, -566, 232, -236, 183, 187, +41, 520, -144, 608, -293, 419, -322, 35, +-206, -365, 7, -602, 249, -602, 387, -381, +341, -2, 112, 371, -187, 568, -395, 524, +-422, 242, -265, -177, 9, -533, 315, -675, +490, -562, 415, -215, 143, 226, -177, 555, +-408, 635, -447, 431, -276, 11, 38, -436, +337, -708, 458, -688, 381, -364, 159, 117, +-116, 530, -338, 713, -382, 577, -229, 140, +17, -377, 241, -732, 358, -790, 329, -483, +188, 71, -8, 573, -181, 816, -254, 711, +-223, 238, -97, -376, 75, -796, 244, -867, +327, -554, 284, 49, 139, 629, -46, 896, +-200, 770, -280, 282, -232, -354, -36, -783, +202, -827, 347, -520, 351, 34, 209, 572, +0, 815, -186, 703, -275, 309, -236, -218, +-77, -599, 129, -663, 263, -445, 296, -56, +213, 344, 54, 583, -80, 586, -152, 373, +-184, 22, -150, -300, -45, -447, 92, -401, +200, -207, 245, 68, 205, 318, 82, 454, +-68, 431, -217, 238, -280, -18, -217, -214, +-50, -315, 159, -293, 314, -129, 321, 82, +179, 246, -46, 337, -256, 314, -353, 181, +-288, 20, -95, -110, 122, -211, 292, -237, +323, -157, 200, -24, -19, 125, -234, 276, +-341, 348, -303, 288, -135, 132, 85, -91, +244, -319, 278, -422, 200, -333, 21, -97, +-190, 221, -330, 494, -310, 564, -163, 382, +40, 32, 217, -368, 276, -639, 206, -615, +32, -317, -168, 120, -315, 530, -336, 711, +-204, 555, 22, 166, 208, -293, 281, -648, +222, -720, 60, -468, -137, -33, -285, 394, +-318, 634, -234, 574, -30, 260, 166, -154, +256, -504, 232, -644, 110, -512, -58, -189, +-177, 187, -227, 453, -217, 488, -115, 312, +39, 13, 140, -303, 177, -498, 189, -487, +114, -304, -6, -23, -109, 243, -188, 372, +-225, 334, -178, 160, -32, -102, 152, -329, +294, -407, 315, -342, 206, -176, 12, 51, +-208, 243, -374, 300, -359, 221, -162, 38, +142, -171, 411, -297, 511, -315, 396, -233, +86, -68, -275, 113, -513, 230, -512, 251, +-269, 160, 132, 1, 526, -151, 701, -258, +545, -297, 156, -233, -294, -72, -605, 125, +-626, 292, -348, 353, 119, 263, 539, 52, +730, -214, 606, -435, 229, -472, -228, -280, +-552, 59, -594, 419, -356, 622, 26, 531, +382, 187, 565, -260, 512, -623, 267, -691, +-60, -396, -300, 113, -386, 590, -304, 812, +-99, 654, 119, 192, 257, -345, 294, -714, +248, -739, 135, -374, 5, 195, -104, 664, +-184, 820, -202, 606, -134, 135, -38, -367, +76, -668, 190, -628, 250, -270, 218, 223, +99, 611, -69, 715, -228, 496, -289, 78, +-239, -334, -89, -540, 115, -466, 269, -176, +303, 198, 239, 501, 55, 563, -201, 359, +-373, 28, -366, -270, -212, -405, -1, -324, +228, -89, 371, 174, 354, 366, 155, 400, +-154, 254, -407, 21, -484, -185, -371, -288, +-103, -248, 218, -106, 444, 50, 461, 194, +264, 275, -62, 244, -406, 134, -578, -14, +-496, -172, -207, -261, 159, -257, 442, -187, +532, -26, 378, 182, 40, 302, -325, 300, +-554, 202, -552, -8, -321, -249, 40, -389, +376, -397, 517, -256, 436, 21, 156, 273, +-215, 384, -473, 360, -511, 171, -350, -134, +-67, -383, 252, -487, 445, -419, 409, -164, +200, 151, -73, 363, -311, 415, -397, 286, +-322, -5, -130, -317, 114, -503, 308, -499, +363, -285, 253, 49, 52, 329, -168, 450, +-307, 366, -305, 86, -186, -254, 17, -496, +239, -547, 370, -364, 333, -29, 141, 283, +-107, 450, -287, 404, -337, 150, -225, -168, +-9, -406, 250, -489, 426, -376, 408, -105, +200, 172, -99, 331, -336, 344, -408, 207, +-279, -21, 12, -215, 321, -310, 491, -303, +450, -195, 211, -29, -115, 133, -393, 242, +-452, 264, -265, 192, 35, 58, 321, -99, +474, -242, 436, -319, 210, -273, -87, -106, +-313, 112, -377, 317, -275, 427, -59, 360, +185, 138, 385, -139, 433, -374, 303, -471, +61, -359, -208, -81, -372, 252, -379, 514, +-210, 583, 76, 412, 359, 90, 481, -258, +373, -516, 100, -555, -213, -340, -420, 38, +-398, 444, -186, 698, 82, 668, 314, 379, +394, -68, 288, -506, 50, -727, -179, -626, +-286, -229, -251, 331, -140, 793, -32, 915, +79, 666, 175, 145, 197, -470, 152, -877, +71, -861, -49, -452, -172, 193, -283, 794, +-311, 1028, -202, 813, 24, 277, 261, -392, +393, -875, 356, -893, 120, -497, -203, 114, +-463, 691, -562, 930, -423, 712, -72, 213, +319, -349, 569, -744, 548, -742, 267, -362, +-148, 147, -516, 561, -679, 695, -579, 468, +-214, 58, 243, -321, 571, -539, 632, -485, +411, -187, 12, 141, -400, 349, -649, 372, +-627, 199, -369, -38, 29, -192, 409, -238, +596, -184, 533, -59, 247, 39, -130, 60, +-467, 29, -636, -30, -559, -68, -255, -32, +167, 23, 510, 44, 646, 34, 529, -29, +171, -124, -289, -175, -631, -161, -720, -102, +-492, 5, -34, 109, 451, 141, 733, 93, +705, -12, 373, -135, -148, -215, -590, -221, +-760, -166, -593, -54, -150, 83, 362, 166, +692, 153, 723, 68, 447, -59, -9, -182, +-436, -244, -641, -225, -558, -137, -224, 5, +220, 137, 522, 179, 593, 128, 447, 28, +130, -95, -220, -200, -427, -228, -423, -173, +-238, -57, 41, 99, 292, 205, 400, 189, +341, 92, 167, -45, -43, -203, -179, -281, +-224, -218, -157, -42, -19, 183, 95, 346, +151, 332, 150, 143, 104, -127, 45, -378, +24, -466, 41, -301, 37, 32, 0, 379, +-42, 588, -99, 515, -116, 181, -61, -237, +66, -559, 205, -619, 272, -348, 235, 106, +70, 520, -156, 725, -335, 592, -365, 171, +-196, -301, 97, -613, 354, -628, 463, -313, +364, 167, 79, 564, -282, 713, -515, 543, +-488, 121, -235, -321, 157, -578, 482, -563, +560, -257, 356, 192, -23, 538, -403, 646, +-597, 491, -501, 121, -161, -270, 254, -490, +537, -477, 534, -240, 255, 109, -139, 393, +-484, 501, -587, 412, -413, 164, -68, -116, +295, -295, 507, -329, 450, -229, 161, -35, +-194, 155, -468, 271, -539, 303, -349, 228, +-10, 76, 282, -69, 428, -180, 366, -242, +130, -217, -175, -104, -402, 52, -440, 207, +-283, 306, -26, 292, 185, 156, 296, -54, +280, -267, 123, -393, -77, -356, -207, -155, +-261, 116, -233, 346, -130, 437, 11, 334, +122, 64, 175, -261, 188, -489, 135, -508, +30, -301, -123, 27, -260, 331, -289, 486, +-198, 419, -26, 148, 177, -202, 329, -477, +340, -557, 181, -391, -72, -73, -303, 230, +-409, 407, -323, 410, -94, 224, 214, -77, +443, -356, 455, -488, 271, -415, -11, -190, +-293, 67, -464, 264, -419, 338, -176, 255, +152, 57, 440, -168, 559, -338, 425, -366, +123, -237, -231, -45, -491, 127, -532, 235, +-341, 215, 14, 86, 399, -72, 657, -209, +620, -262, 296, -181, -137, -37, -492, 88, +-630, 159, -487, 137, -127, 23, 328, -97, +664, -160, 697, -158, 422, -74, -16, 56, +-421, 146, -643, 161, -555, 96, -213, -41, +205, -164, 532, -197, 641, -144, 480, -17, +115, 145, -288, 242, -520, 226, -495, 117, +-277, -47, 34, -206, 324, -281, 495, -213, +447, -26, 232, 195, -50, 335, -303, 332, +-418, 192, -365, -27, -181, -242, 73, -360, +312, -306, 427, -78, 371, 231, 172, 458, +-102, 489, -358, 309, -455, -8, -370, -322, +-134, -497, 167, -455, 378, -176, 426, 245, +305, 592, 63, 683, -216, 476, -407, 62, +-440, -378, -315, -644, -61, -617, 223, -301, +379, 184, 373, 623, 241, 792, 4, 614, +-268, 181, -462, -320, -451, -664, -247, -693, +54, -408, 302, 58, 397, 507, 323, 743, +104, 658, -165, 298, -356, -167, -404, -545, +-285, -678, -53, -497, 158, -99, 266, 320, +232, 598, 122, 631, -15, 397, -141, 2, +-223, -383, -236, -596, -161, -546, -41, -250, +83, 137, 165, 432, 175, 540, 115, 428, +3, 128, -139, -219, -229, -458, -218, -510, +-101, -347, 50, -42, 165, 252, 200, 413, +121, 390, -11, 211, -129, -51, -183, -293, +-155, -421, -57, -389, 66, -205, 146, 57, +147, 265, 93, 334, -9, 263, -101, 79, +-126, -157, -87, -335, -6, -370, 66, -268, +117, -79, 122, 135, 86, 264, 6, 241, +-94, 115, -134, -58, -86, -218, 8, -280, +112, -228, 170, -113, 149, 32, 78, 142, +-36, 149, -148, 81, -192, -9, -110, -95, +54, -141, 207, -121, 269, -74, 196, -38, +39, 2, -131, 34, -246, 34, -234, 23, +-86, 15, 125, -4, 304, -28, 331, -57, +187, -86, -48, -92, -233, -52, -289, 26, +-202, 96, 2, 118, 203, 86, 314, 14, +278, -78, 102, -146, -110, -155, -234, -85, +-229, 45, -112, 166, 52, 194, 185, 119, +223, 12, 161, -88, 30, -152, -108, -126, +-163, -18, -148, 93, -66, 159, 58, 154, +150, 68, 147, -37, 67, -87, -42, -77, +-131, -17, -146, 70, -69, 131, 36, 124, +104, 73, 126, 5, 71, -64, -30, -77, +-135, -24, -171, 44, -108, 104, 18, 141, +132, 110, 153, 31, 98, -31, 1, -67, +-113, -68, -190, -23, -186, 51, -93, 111, +62, 136, 173, 115, 185, 55, 107, -17, +-21, -65, -155, -81, -241, -55, -224, 4, +-124, 63, 38, 109, 208, 127, 271, 110, +176, 61, -9, -16, -197, -88, -312, -113, +-307, -93, -167, -38, 57, 53, 268, 146, +346, 190, 222, 157, -9, 46, -248, -101, +-395, -205, -348, -206, -130, -121, 134, 18, +328, 171, 369, 254, 215, 212, -56, 67, +-289, -125, -383, -274, -298, -298, -63, -197, +176, -16, 316, 177, 292, 293, 121, 278, +-86, 134, -218, -82, -236, -284, -169, -377, +-39, -308, 91, -117, 147, 113, 136, 296, +82, 349, 17, 232, -3, 3, -27, -244, +-78, -400, -111, -390, -100, -222, -53, 30, +30, 250, 140, 345, 201, 271, 186, 64, +98, -181, -54, -346, -204, -372, -254, -248, +-176, -33, 11, 173, 208, 287, 299, 256, +256, 102, 122, -90, -56, -247, -241, -310, +-296, -248, -178, -89, 18, 96, 198, 227, +297, 235, 259, 133, 89, -16, -113, -150, +-227, -226, -214, -210, -92, -105, 80, 23, +212, 114, 238, 138, 130, 94, -28, 27, +-148, -26, -178, -58, -107, -60, 26, -43, +152, -39, 189, -32, 121, -13, -4, 9, +-113, 47, -151, 92, -111, 110, -25, 77, +100, 3, 184, -84, 152, -136, 39, -114, +-75, -27, -137, 84, -146, 170, -87, 191, +17, 124, 114, 15, 167, -97, 136, -162, +29, -131, -85, -26, -161, 92, -162, 179, +-94, 194, 4, 128, 93, 28, 144, -67, +144, -119, 57, -94, -62, -11, -142, 75, +-171, 128, -139, 141, -48, 91, 50, 2, +117, -55, 150, -53, 122, -13, 21, 37, +-103, 70, -181, 74, -200, 61, -134, 22, +-18, -19, 96, -29, 172, 0, 174, 43, +100, 60, -29, 47, -160, 19, -235, -8, +-213, -21, -108, -14, 30, 6, 156, 38, +230, 68, 186, 69, 47, 41, -109, -20, +-227, -78, -262, -90, -187, -59, -25, -4, +130, 60, 219, 124, 211, 136, 113, 71, +-30, -35, -166, -133, -243, -195, -210, -165, +-95, -50, 47, 81, 154, 183, 185, 206, +149, 128, 60, -17, -38, -166, -133, -254, +-186, -227, -175, -111, -104, 31, 16, 151, +139, 203, 216, 153, 223, 30, 140, -92, +-25, -180, -200, -216, -298, -178, -264, -93, +-108, 14, 128, 116, 321, 159, 366, 131, +260, 68, 37, -36, -224, -161, -389, -242, +-365, -247, -173, -157, 103, 5, 348, 161, +440, 250, 330, 235, 85, 107, -197, -94, +-386, -273, -388, -359, -217, -312, 47, -121, +298, 130, 436, 307, 371, 344, 140, 242, +-133, 13, -331, -231, -380, -380, -257, -380, +-17, -220, 239, 42, 384, 283, 352, 393, +166, 325, -93, 116, -285, -128, -324, -329, +-211, -393, -19, -278, 174, -34, 291, 223, +271, 374, 130, 361, -66, 191, -217, -57, +-238, -274, -149, -365, -14, -274, 127, -47, +206, 192, 177, 348, 66, 362, -50, 198, +-144, -47, -175, -252, -104, -336, 8, -239, +95, -19, 143, 202, 137, 331, 59, 323, +-59, 169, -152, -60, -174, -237, -126, -280, +-6, -176, 132, 26, 201, 230, 154, 315, +28, 263, -108, 112, -215, -88, -229, -238, +-131, -266, 33, -145, 188, 60, 258, 249, +192, 333, 19, 279, -173, 96, -289, -121, +-277, -269, -137, -304, 66, -185, 225, 38, +281, 264, 203, 382, 23, 330, -175, 129, +-300, -119, -298, -312, -168, -367, 46, -250, +235, -12, 294, 246, 214, 397, 43, 368, +-159, 169, -302, -98, -305, -303, -141, -385, +86, -303, 240, -71, 245, 184, 122, 340, +-40, 354, -171, 210, -211, -25, -132, -240, +15, -362, 128, -320, 145, -138, 62, 74, +-59, 234, -144, 296, -126, 226, -14, 50, +115, -136, 178, -260, 120, -285, -20, -188, +-165, -21, -235, 115, -182, 184, -22, 176, +169, 73, 294, -48, 272, -137, 102, -189, +-127, -166, -287, -74, -316, 16, -206, 64, +12, 78, 229, 56, 347, 24, 317, -24, +147, -76, -92, -115, -289, -114, -352, -79, +-261, -30, -58, 29, 166, 71, 320, 85, +357, 71, 262, 9, 52, -93, -180, -163, +-349, -161, -378, -102, -239, -9, 25, 80, +296, 148, 455, 150, 433, 65, 215, -52, +-111, -157, -395, -203, -497, -161, -359, -53, +-46, 71, 278, 175, 474, 203, 463, 138, +247, 15, -72, -114, -331, -197, -432, -201, +-357, -114, -114, 27, 179, 159, 368, 225, +383, 188, 253, 81, 48, -48, -154, -166, +-298, -211, -333, -144, -233, -21, -29, 114, +180, 220, 311, 229, 340, 153, 224, 26, +-2, -109, -236, -192, -367, -175, -343, -86, +-168, 51, 84, 193, 300, 262, 383, 212, +293, 73, 72, -76, -177, -188, -347, -203, +-369, -120, -222, 25, 9, 190, 220, 279, +324, 230, 284, 90, 117, -75, -103, -195, +-257, -194, -291, -98, -204, 32, -53, 162, +85, 219, 179, 177, 206, 62, 131, -60, +10, -128, -88, -117, -150, -54, -172, 18, +-141, 80, -70, 106, 6, 86, 96, 52, +164, 27, 154, -17, 76, -53, -29, -54, +-133, -62, -200, -56, -199, -14, -115, 35, +25, 85, 162, 121, 230, 96, 195, 11, +73, -80, -104, -144, -239, -152, -263, -104, +-178, -6, -23, 91, 148, 147, 260, 137, +250, 49, 118, -61, -72, -142, -224, -167, +-270, -130, -197, -44, -52, 37, 118, 93, +237, 102, 249, 68, 140, 7, -36, -74, +-178, -125, -228, -127, -183, -97, -72, -47, +76, 1, 194, 52, 216, 106, 150, 107, +34, 24, -105, -73, -201, -153, -203, -191, +-108, -156, 40, -51, 177, 84, 234, 176, +174, 187, 49, 97, -80, -62, -180, -211, +-208, -276, -130, -208, 20, -36, 161, 134, +221, 233, 184, 240, 77, 114, -52, -77, +-157, -221, -212, -287, -167, -216, -29, -35, +130, 144, 225, 241, 223, 247, 143, 138, +4, -40, -155, -181, -255, -243, -236, -215, +-104, -88, 84, 94, 252, 213, 314, 254, +212, 203, 19, 52, -157, -108, -263, -202, +-262, -230, -145, -164, 40, -14, 200, 128, +282, 232, 252, 258, 118, 174, -58, 30, +-216, -100, -297, -183, -245, -215, -90, -160, +99, -18, 263, 144, 336, 260, 256, 283, +42, 190, -192, 29, -344, -132, -344, -254, +-196, -269, 26, -148, 237, 70, 357, 279, +320, 372, 142, 318, -103, 123, -317, -144, +-392, -344, -286, -381, -64, -245, 157, 21, +310, 308, 348, 478, 243, 449, 26, 198, +-212, -154, -365, -429, -368, -512, -215, -366, +33, -37, 266, 343, 367, 575, 306, 552, +122, 272, -121, -148, -325, -518, -363, -639, +-229, -463, -29, -61, 147, 396, 238, 661, +227, 623, 143, 300, 33, -183, -97, -589, +-215, -714, -252, -513, -190, -65, -74, 424, +76, 697, 208, 639, 254, 288, 199, -200, +68, -600, -109, -724, -272, -521, -322, -95, +-227, 385, -30, 677, 190, 621, 336, 282, +323, -167, 154, -552, -76, -685, -261, -507, +-344, -122, -294, 314, -110, 589, 125, 572, +300, 295, 344, -115, 251, -464, 53, -595, +-168, -469, -314, -163, -347, 191, -242, 440, +2, 477, 270, 304, 402, 9, 337, -284, +131, -453, -115, -420, -312, -237, -369, 17, +-261, 248, -27, 373, 216, 348, 344, 174, +316, -81, 149, -291, -71, -374, -229, -331, +-258, -150, -182, 89, -46, 273, 102, 339, +194, 263, 188, 83, 130, -125, 48, -279, +-47, -316, -115, -224, -124, -47, -87, 131, +-47, 242, 4, 269, 68, 207, 133, 56, +162, -114, 121, -240, 24, -268, -78, -179, +-157, -21, -191, 158, -149, 288, -22, 303, +142, 193, 242, -7, 242, -222, 145, -326, +-23, -270, -207, -82, -298, 166, -240, 338, +-87, 361, 94, 238, 259, 4, 327, -239, +234, -360, 29, -294, -187, -98, -323, 155, +-316, 354, -155, 391, 64, 251, 246, 32, +333, -203, 268, -358, 64, -321, -172, -144, +-309, 101, -296, 328, -161, 412, 30, 305, +203, 85, 277, -174, 221, -361, 67, -374, +-107, -221, -233, 34, -248, 292, -140, 428, +16, 367, 149, 161, 206, -103, 159, -344, +33, -429, -99, -309, -174, -77, -171, 183, +-88, 392, 32, 439, 117, 305, 131, 43, +79, -257, -21, -442, -106, -434, -124, -252, +-78, 36, -11, 327, 47, 490, 70, 431, +46, 166, -4, -183, -45, -451, -40, -518, +0, -354, 19, -37, -2, 298, -36, 496, +-67, 442, -58, 190, 9, -151, 92, -434, +113, -522, 70, -360, -6, -39, -106, 270, +-181, 439, -164, 413, -44, 199, 114, -125, +221, -377, 216, -466, 99, -357, -78, -85, +-227, 198, -273, 371, -200, 381, -34, 210, +181, -70, 347, -307, 342, -408, 165, -338, +-98, -110, -338, 164, -439, 333, -325, 331, +-43, 177, 273, -84, 487, -299, 484, -341, +245, -238, -115, -25, -430, 214, -572, 316, +-440, 237, -82, 55, 314, -172, 562, -316, +581, -271, 351, -87, -60, 126, -455, 265, +-633, 258, -519, 109, -175, -88, 251, -234, +570, -258, 632, -125, 416, 74, 43, 207, +-340, 225, -592, 134, -589, -38, -310, -170, +111, -191, 472, -117, 627, 29, 510, 154, +172, 187, -221, 127, -493, 15, -556, -106, +-397, -146, -74, -85, 276, 25, 506, 111, +528, 131, 327, 96, -3, 17, -316, -62, +-503, -92, -492, -52, -276, 35, 65, 105, +381, 124, 535, 89, 450, 9, 167, -71, +-167, -100, -413, -76, -495, -2, -381, 83, +-105, 121, 209, 115, 439, 53, 488, -30, +333, -75, 37, -69, -275, -28, -481, 36, +-491, 71, -286, 47, 37, 4, 345, -24, +524, -22, 479, 7, 201, 55, -176, 81, +-468, 51, -549, -18, -386, -104, -54, -146, +294, -90, 502, 33, 480, 158, 242, 214, +-97, 147, -394, -9, -519, -166, -397, -265, +-99, -217, 210, -41, 419, 163, 449, 295, +262, 273, -49, 87, -308, -160, -423, -331, +-370, -348, -136, -182, 161, 82, 356, 301, +366, 364, 211, 252, -28, 2, -231, -271, +-322, -406, -279, -347, -108, -127, 110, 152, +245, 334, 236, 351, 128, 217, -14, -35, +-130, -281, -184, -363, -158, -285, -77, -99, +15, 127, 86, 276, 131, 278, 132, 143, +73, -52, -11, -213, -81, -258, -132, -190, +-144, -63, -82, 81, 20, 171, 109, 153, +157, 68, 144, -22, 69, -93, -34, -94, +-127, -56, -182, -44, -162, -33, -74, -22, +53, -21, 190, 10, 266, 83, 203, 131, +32, 131, -167, 66, -311, -69, -309, -210, +-139, -271, 111, -192, 309, -6, 382, 215, +282, 346, 37, 317, -239, 142, -414, -114, +-395, -348, -174, -423, 140, -284, 386, 2, +460, 303, 335, 462, 57, 413, -255, 177, +-454, -147, -453, -396, -239, -472, 86, -333, +369, -21, 499, 314, 424, 508, 168, 486, +-175, 244, -456, -112, -542, -402, -377, -522, +-34, -417, 324, -103, 537, 280, 520, 530, +270, 551, -95, 352, -408, -7, -545, -366, +-449, -542, -155, -474, 199, -198, 442, 170, +503, 447, 373, 530, 91, 408, -234, 96, +-449, -239, -474, -428, -323, -429, -56, -262, +246, 12, 469, 271, 496, 398, 314, 369, +1, 193, -316, -48, -515, -248, -501, -334, +-262, -304, 97, -148, 405, 72, 529, 240, +434, 314, 158, 279, -192, 136, -459, -61, +-518, -232, -364, -315, -72, -256, 246, -100, +464, 80, 470, 241, 259, 301, -46, 229, +-313, 68, -448, -120, -396, -261, -182, -291, +91, -192, 302, -18, 382, 151, 315, 246, +118, 231, -125, 113, -306, -53, -353, -198, +-260, -255, -77, -196, 133, -62, 288, 90, +318, 188, 202, 184, 8, 106, -165, -17, +-260, -135, -262, -181, -172, -147, -25, -73, +131, 33, 238, 109, 250, 116, 164, 82, +8, 16, -153, -50, -257, -92, -257, -102, +-151, -90, 20, -42, 181, 22, 259, 62, +227, 77, 105, 75, -66, 29, -212, -43, +-257, -73, -189, -89, -42, -77, 121, -19, +232, 41, 229, 69, 117, 56, -36, 3, +-160, -47, -197, -54, -136, -30, -22, 14, +79, 55, 127, 62, 122, 22, 84, -47, +34, -103, -28, -101, -99, -30, -134, 67, +-104, 136, -21, 146, 78, 80, 146, -36, +152, -132, 90, -166, -9, -127, -114, -4, +-178, 128, -144, 191, -27, 176, 93, 75, +159, -56, 159, -147, 93, -168, -21, -97, +-125, 28, -163, 128, -127, 163, -37, 143, +68, 61, 146, -51, 162, -123, 110, -114, +5, -60, -106, 12, -150, 79, -117, 98, +-55, 79, 30, 34, 132, -12, 172, -34, +115, -28, 19, -24, -63, 1, -128, 21, +-136, 8, -75, 2, -1, 3, 58, 12, +105, 36, 126, 54, 98, 49, 30, 28, +-54, -4, -115, -49, -142, -84, -134, -78, +-65, -30, 65, 40, 184, 107, 223, 124, +161, 87, 11, 23, -163, -64, -266, -134, +-235, -148, -91, -102, 97, 1, 231, 108, +259, 159, 185, 152, 25, 91, -161, -30, +-265, -149, -248, -209, -148, -189, 17, -83, +195, 63, 289, 203, 249, 270, 109, 212, +-94, 39, -279, -162, -339, -310, -238, -350, +-17, -237, 216, 9, 342, 267, 299, 406, +119, 382, -125, 161, -303, -155, -316, -409, +-188, -495, -8, -357, 168, -40, 272, 285, +237, 471, 95, 452, -63, 220, -182, -119, +-239, -403, -201, -504, -81, -373, 80, -71, +218, 245, 261, 430, 169, 422, -20, 219, +-196, -97, -264, -361, -205, -444, -49, -332, +147, -63, 266, 233, 212, 389, 38, 356, +-129, 157, -218, -116, -180, -316, -31, -357, +122, -222, 181, 24, 130, 240, 2, 311, +-134, 213, -165, 12, -86, -181, 37, -262, +142, -198, 162, -26, 73, 152, -46, 239, +-109, 187, -121, 38, -96, -123, -23, -225, +55, -197, 92, -56, 106, 112, 102, 222, +63, 239, -33, 144, -146, -14, -194, -179, +-142, -274, -12, -221, 144, -65, 254, 123, +230, 277, 71, 314, -110, 200, -224, -11, +-241, -226, -139, -340, 32, -294, 177, -93, +229, 169, 192, 360, 96, 391, -37, 223, +-157, -59, -230, -304, -206, -398, -87, -296, +67, -50, 201, 212, 274, 373, 233, 364, +86, 188, -103, -55, -262, -243, -324, -315, +-235, -254, -16, -111, 217, 54, 364, 204, +351, 271, 169, 237, -92, 130, -300, -25, +-370, -177, -277, -266, -42, -257, 210, -151, +340, 23, 314, 203, 165, 304, -42, 281, +-223, 150, -311, -77, -270, -270, -114, -321, +101, -243, 268, -71, 300, 143, 206, 285, +41, 288, -141, 178, -271, -9, -270, -187, +-143, -279, 17, -262, 152, -146, 246, 34, +252, 197, 143, 270, -25, 237, -184, 103, +-294, -90, -289, -249, -127, -296, 109, -230, +297, -60, 356, 143, 252, 265, 4, 272, +-271, 150, -406, -53, -324, -219, -81, -287, +195, -230, 374, -62, 370, 127, 176, 237, +-117, 219, -345, 97, -386, -62, -234, -181, +13, -216, 248, -155, 359, -23, 287, 113, +82, 174, -133, 154, -272, 80, -318, -41, +-241, -145, -45, -178, 189, -141, 334, -47, +326, 85, 182, 168, -60, 174, -307, 107, +-412, -32, -303, -153, -42, -196, 241, -152, +419, -45, 392, 87, 141, 186, -186, 198, +-396, 109, -393, -31, -210, -158, 60, -202, +302, -151, 382, -37, 259, 112, 24, 202, +-183, 185, -287, 90, -268, -37, -127, -144, +58, -183, 176, -139, 214, -39, 195, 64, +109, 129, -37, 158, -163, 140, -204, 58, +-179, -38, -80, -114, 85, -172, 218, -176, +227, -102, 121, 47, -30, 198, -162, 265, +-198, 232, -126, 105, -2, -94, 119, -288, +169, -358, 110, -228, 4, 24, -70, 259, +-84, 401, -61, 357, -10, 128, 41, -173, +52, -394, 37, -407, 9, -216, -29, 63, +-46, 316, -16, 445, 44, 347, 75, 65, +57, -224, -1, -377, -71, -360, -103, -189, +-84, 78, -18, 317, 64, 393, 127, 265, +148, 21, 79, -198, -39, -298, -123, -276, +-149, -120, -132, 99, -54, 231, 87, 231, +190, 129, 181, -13, 92, -119, -38, -156, +-170, -112, -223, -14, -142, 55, 34, 66, +183, 36, 211, 9, 119, 3, -9, 11, +-127, 22, -204, 12, -154, -32, 1, -94, +129, -123, 170, -67, 146, 53, 53, 153, +-91, 183, -185, 119, -161, -41, -62, -216, +60, -265, 149, -172, 159, 5, 84, 190, +-38, 280, -134, 232, -157, 48, -98, -172, +4, -301, 105, -271, 152, -103, 109, 111, +15, 258, -77, 275, -138, 135, -151, -75, +-104, -221, 12, -255, 150, -162, 209, 4, +149, 160, 22, 221, -115, 167, -226, 39, +-233, -98, -106, -176, 63, -171, 193, -113, +257, -21, 209, 104, 34, 191, -164, 174, +-280, 91, -284, -21, -158, -154, 74, -230, +288, -203, 369, -78, 258, 112, -12, 265, +-294, 287, -421, 163, -331, -37, -80, -241, +236, -355, 434, -273, 392, -31, 153, 226, +-149, 387, -377, 342, -427, 117, -259, -156, +43, -368, 308, -398, 410, -202, 320, 98, +85, 324, -190, 401, -377, 298, -370, 41, +-180, -248, 84, -405, 298, -347, 365, -116, +267, 164, 47, 366, -195, 410, -356, 257, +-347, -45, -165, -342, 88, -442, 313, -321, +417, -53, 315, 247, 44, 446, -262, 459, +-450, 239, -413, -125, -155, -434, 187, -552, +422, -414, 467, -46, 293, 369, -41, 632, +-355, 605, -471, 277, -346, -221, -73, -644, +239, -763, 441, -508, 399, 34, 155, 598, +-132, 866, -331, 713, -366, 219, -229, -421, +23, -886, 242, -904, 324, -461, 243, 222, +57, 828, -111, 1025, -203, 696, -210, 16, +-139, -698, -12, -1063, 115, -888, 176, -263, +160, 495, 80, 1018, -26, 1035, -96, 507, +-117, -275, -89, -886, -27, -1060, 21, -715, +31, 1, 11, 709, 9, 1054, 37, 843, +77, 193, 93, -534, 55, -956, -27, -884, +-136, -375, -205, 322, -155, 841, -6, 894, +152, 460, 245, -192, 225, -712, 83, -850, +-108, -544, -232, 39, -252, 582, -166, 806, +-4, 592, 150, 69, 237, -473, 226, -770, +119, -658, -31, -192, -149, 371, -230, 721, +-265, 677, -177, 290, 25, -247, 221, -672, +338, -737, 323, -426, 140, 100, -141, 593, +-362, 776, -415, 559, -280, 58, 2, -475, +282, -793, 421, -724, 366, -292, 141, 291, +-144, 741, -353, 834, -388, 513, -244, -61, +-7, -591, 207, -835, 319, -693, 290, -233, +118, 342, -101, 747, -222, 798, -225, 466, +-148, -71, -22, -550, 88, -785, 129, -651, +115, -204, 87, 326, 56, 680, 30, 694, +-23, 395, -126, -62, -198, -476, -166, -642, +-60, -511, 96, -166, 257, 228, 303, 489, +180, 530, -46, 356, -266, 57, -363, -252, +-250, -457, -11, -467, 216, -278, 332, 20, +276, 297, 95, 451, -103, 429, -238, 222, +-255, -84, -136, -356, 28, -463, 120, -356, +151, -105, 149, 206, 94, 431, 19, 451, +-50, 251, -119, -69, -172, -322, -155, -414, +-45, -339, 113, -107, 248, 191, 270, 394, +161, 391, -38, 205, -278, -19, -399, -225, +-268, -371, 24, -373, 289, -193, 430, 97, +393, 335, 124, 424, -250, 356, -484, 141, +-465, -176, -214, -446, 148, -513, 455, -337, +548, -3, 359, 355, -25, 582, -405, 560, +-568, 247, -442, -229, -115, -605, 282, -711, +555, -497, 541, -28, 260, 525, -108, 865, +-411, 752, -579, 262, -481, -346, -114, -817, +289, -938, 537, -631, 570, 8, 375, 687, +-20, 1035, -433, 903, -647, 365, -568, -349, +-211, -937, 260, -1112, 592, -774, 637, -78, +389, 656, -30, 1105, -421, 1066, -604, 538, +-511, -249, -192, -927, 207, -1176, 477, -921, +513, -277, 338, 508, 24, 1118, -282, 1220, +-435, 736, -403, -78, -229, -854, 32, -1247, +286, -1123, 399, -495, 328, 414, 138, 1148, +-79, 1326, -251, 909, -350, 101, -314, -761, +-124, -1304, 102, -1253, 244, -627, 292, 267, +257, 1037, 110, 1330, -87, 1035, -223, 289, +-271, -594, -231, -1192, -114, -1215, 23, -712, +147, 47, 248, 768, 291, 1156, 215, 1023, +21, 443, -212, -300, -380, -871, -380, -1037, +-213, -792, 70, -235, 362, 420, 504, 896, +391, 972, 59, 622, -301, 35, -498, -549, +-454, -897, -196, -866, 154, -485, 424, 102, +471, 661, 307, 925, 24, 795, -294, 326, +-458, -280, -335, -761, -69, -920, 141, -678, +275, -139, 318, 464, 181, 855, -41, 871, +-171, 511, -191, -63, -133, -597, -37, -858, +23, -749, 48, -317, 88, 253, 107, 721, +80, 875, 52, 622, -11, 76, -131, -508, +-166, -831, -85, -778, 33, -378, 156, 221, +235, 727, 156, 881, -63, 604, -254, 31, +-306, -534, -171, -826, 110, -728, 347, -294, +397, 271, 244, 713, -74, 802, -412, 509, +-543, -13, -350, -512, 54, -730, 449, -594, +620, -217, 462, 227, 74, 556, -370, 620, +-661, 412, -608, 49, -223, -318, 268, -536, +610, -506, 664, -292, 415, 21, -26, 345, +-444, 547, -663, 519, -588, 254, -243, -119, +203, -481, 569, -656, 689, -530, 490, -165, +63, 298, -368, 671, -615, 749, -618, 483, +-360, -34, 79, -585, 476, -867, 622, -726, +477, -240, 159, 343, -193, 787, -441, 875, +-500, 530, -386, -62, -123, -608, 192, -852, +397, -673, 427, -189, 325, 320, 126, 651, +-157, 692, -398, 409, -471, -57, -369, -437, +-111, -585, 218, -457, 455, -143, 495, 180, +338, 370, 29, 374, -319, 246, -512, 56, +-465, -117, -250, -215, 58, -237, 339, -200, +468, -134, 401, -62, 186, 70, -86, 236, +-317, 349, -416, 339, -363, 162, -187, -131, +54, -418, 260, -542, 373, -436, 381, -120, +253, 297, -1, 634, -278, 692, -436, 396, +-440, -114, -302, -570, -16, -748, 332, -582, +571, -155, 551, 339, 282, 685, -112, 687, +-489, 361, -685, -110, -577, -477, -188, -585, +306, -454, 672, -159, 760, 176, 519, 403, +20, 452, -526, 336, -849, 119, -766, -119, +-339, -316, 245, -393, 754, -346, 943, -195, +677, 44, 69, 306, -561, 489, -916, 485, +-843, 258, -388, -107, 241, -438, 770, -604, +931, -532, 635, -220, 76, 228, -480, 593, +-823, 699, -794, 491, -380, 64, 198, -383, +664, -658, 840, -657, 625, -396, 116, 57, +-423, 485, -775, 696, -784, 622, -405, 275, +181, -186, 666, -540, 847, -676, 642, -548, +91, -178, -510, 280, -826, 614, -746, 684, +-304, 493, 306, 71, 752, -398, 786, -692, +439, -720, -87, -449, -546, 54, -703, 561, +-520, 832, -127, 760, 302, 331, 569, -286, +563, -769, 324, -907, -41, -671, -395, -118, +-571, 515, -464, 915, -157, 898, 211, 476, +502, -161, 558, -728, 338, -946, -48, -750, +-395, -223, -529, 422, -410, 852, -133, 875, +176, 527, 409, -64, 444, -621, 264, -866, +13, -711, -201, -261, -347, 280, -367, 705, +-242, 804, -14, 542, 225, 56, 383, -441, +364, -729, 182, -694, -70, -374, -311, 81, +-422, 483, -330, 678, -89, 599, 190, 295, +398, -104, 412, -466, 196, -661, -105, -607, +-317, -298, -389, 116, -282, 485, -29, 722, +223, 688, 340, 333, 276, -204, 88, -680, +-126, -882, -241, -707, -216, -205, -110, 424, +17, 900, 114, 992, 153, 599, 117, -87, +27, -728, -51, -1076, -87, -934, -86, -325, +-47, 425, 11, 949, 64, 1063, 78, 714, +50, 37, -12, -635, -68, -1020, -89, -979, +-79, -496, -15, 186, 86, 731, 147, 982, +124, 867, 55, 379, -43, -290, -179, -798, +-254, -988, -155, -792, 42, -239, 209, 394, +293, 834, 274, 962, 110, 698, -163, 119, +-375, -489, -387, -884, -191, -928, 92, -579, +323, 28, 423, 574, 331, 882, 77, 870, +-203, 475, -381, -120, -398, -633, -252, -901, +7, -831, 249, -395, 366, 191, 378, 671, +298, 923, 82, 837, -234, 377, -479, -240, +-518, -773, -356, -1037, -26, -875, 388, -330, +691, 336, 688, 869, 354, 1111, -162, 890, +-650, 259, -864, -454, -653, -988, -120, -1165, +469, -864, 848, -200, 861, 533, 493, 1073, +-114, 1217, -679, 858, -927, 131, -734, -638, +-224, -1195, 351, -1300, 773, -840, 876, -25, +586, 806, 25, 1364, -519, 1384, -813, 787, +-771, -160, -389, -1057, 171, -1557, 617, -1407, +770, -624, 610, 428, 205, 1325, -291, 1693, +-624, 1329, -646, 386, -404, -706, -32, -1522, +301, -1758, 471, -1219, 449, -136, 281, 971, +43, 1684, -171, 1743, -293, 1069, -331, -63, +-308, -1173, -212, -1819, -34, -1734, 218, -912, +451, 298, 497, 1376, 324, 1931, 24, 1706, +-313, 746, -592, -534, -637, -1604, -374, -2053, +61, -1648, 486, -496, 731, 890, 661, 1888, +299, 2101, -201, 1439, -641, 156, -825, -1213, +-656, -2098, -204, -2091, 355, -1161, 795, 284, +869, 1565, 541, 2176, 23, 1922, -493, 855, +-843, -595, -845, -1790, -472, -2247, 86, -1779, +601, -539, 874, 935, 775, 2005, 375, 2254, +-151, 1601, -653, 246, -916, -1245, -788, -2217, +-339, -2291, 248, -1378, 768, 180, 987, 1654, +780, 2386, 261, 2131, -393, 977, -945, -637, +-1087, -1978, -718, -2440, -44, -1852, 644, -454, +1082, 1123, 1053, 2145, 552, 2236, -180, 1412, +-832, -3, -1133, -1417, -934, -2176, -339, -2014, +387, -1031, 947, 395, 1116, 1621, 825, 2118, +191, 1757, -536, 684, -1060, -693, -1123, -1775, +-678, -2102, 62, -1551, 763, -336, 1132, 1031, +1015, 1899, 465, 1944, -276, 1216, -887, -27, +-1104, -1260, -833, -1908, -216, -1720, 447, -839, +904, 367, 991, 1367, 672, 1736, 79, 1395, +-519, 527, -880, -544, -888, -1350, -533, -1563, +49, -1154, 588, -310, 860, 651, 801, 1325, +436, 1420, -113, 963, -621, 143, -867, -743, +-764, -1312, -343, -1322, 206, -791, 647, 60, +854, 865, 753, 1282, 324, 1173, -270, 610, +-730, -196, -893, -927, -731, -1228, -270, -1024, +337, -453, 843, 284, 1032, 904, 774, 1140, +147, 930, -562, 388, -1044, -308, -1108, -878, +-674, -1082, 110, -884, 850, -356, 1213, 352, +1051, 918, 407, 1089, -446, 836, -1085, 269, +-1223, -435, -829, -965, -68, -1061, 713, -731, +1147, -111, 1079, 566, 561, 985, -197, 971, +-846, 573, -1103, -44, -909, -616, -371, -907, +322, -830, 885, -440, 1069, 133, 825, 642, +241, 839, -469, 720, -997, 360, -1103, -134, +-753, -568, -84, -760, 651, -674, 1124, -347, +1104, 115, 600, 521, -181, 722, -887, 682, +-1192, 402, -994, -41, -385, -464, 416, -738, +1060, -775, 1211, -512, 835, -1, 125, 515, +-663, 828, -1174, 869, -1146, 581, -634, 10, +126, -615, 858, -1006, 1220, -982, 1030, -533, +416, 154, -370, 789, -1032, 1109, -1234, 993, +-888, 426, -196, -366, 605, -990, 1203, -1190, +1247, -900, 699, -210, -130, 579, -901, 1091, +-1296, 1143, -1087, 739, -372, 8, 499, -732, +1146, -1137, 1239, -1074, 733, -574, -55, 163, +-756, 788, -1120, 1056, -964, 944, -346, 488, +359, -202, 828, -782, 925, -1022, 618, -906, +62, -459, -443, 179, -692, 733, -647, 1021, +-361, 960, 18, 500, 336, -197, 519, -811, +514, -1131, 314, -1050, 37, -497, -215, 301, +-413, 972, -505, 1288, -396, 1090, -109, 367, +224, -552, 484, -1229, 572, -1420, 430, -1000, +96, -86, -284, 875, -549, 1438, -597, 1399, +-402, 723, -27, -305, 374, -1171, 629, -1512, +629, -1225, 365, -382, -62, 655, -479, 1350, +-702, 1436, -617, 919, -245, -9, 230, -902, +604, -1340, 731, -1213, 529, -593, 74, 298, +-388, 1020, -651, 1219, -644, 903, -364, 252, +77, -490, 456, -949, 617, -946, 535, -589, +239, -37, -142, 514, -441, 788, -569, 690, +-473, 356, -166, -69, 190, -416, 436, -531, +546, -448, 454, -283, 125, -28, -265, 252, +-499, 410, -533, 408, -363, 314, -20, 134, +329, -105, 517, -321, 485, -476, 246, -465, +-87, -218, -351, 131, -477, 412, -428, 570, +-187, 530, 124, 246, 346, -150, 452, -473, +409, -646, 149, -566, -195, -201, -409, 235, +-454, 547, -342, 667, -66, 536, 247, 179, +427, -225, 434, -555, 271, -717, -33, -563, +-316, -131, -439, 307, -392, 599, -187, 716, +106, 563, 351, 147, 438, -343, 344, -706, +88, -809, -207, -540, -376, -33, -388, 452, +-265, 779, 1, 824, 282, 493, 388, -60, +317, -576, 149, -896, -90, -851, -311, -382, +-362, 241, -243, 697, -37, 909, 177, 777, +304, 274, 290, -340, 164, -800, -26, -969, +-206, -722, -262, -137, -208, 441, -115, 825, +33, 950, 209, 677, 265, 74, 186, -527, +73, -938, -62, -1020, -209, -620, -254, 68, +-161, 656, -16, 988, 130, 977, 224, 506, +217, -199, 121, -789, -11, -1087, -143, -929, +-213, -320, -188, 368, -102, 842, 22, 1039, +165, 819, 257, 192, 237, -486, 119, -927, +-70, -1055, -243, -734, -304, -69, -226, 578, +-53, 982, 166, 1034, 335, 629, 344, -53, +198, -666, -30, -1049, -265, -1037, -407, -527, +-359, 205, -135, 766, 161, 1035, 404, 925, +485, 406, 349, -268, 46, -790, -309, -1030, +-556, -870, -539, -321, -236, 314, 195, 786, +528, 990, 625, 807, 441, 284, 36, -303, +-414, -769, -669, -999, -586, -824, -225, -266, +228, 364, 555, 821, 622, 1010, 421, 812, +53, 282, -331, -349, -565, -881, -557, -1122, +-330, -877, 26, -234, 381, 481, 574, 1023, +526, 1216, 279, 915, -88, 220, -455, -575, +-655, -1204, -566, -1371, -212, -911, 253, -39, +596, 814, 668, 1372, 474, 1423, 83, 858, +-387, -80, -709, -1001, -685, -1562, -364, -1467, +87, -687, 509, 356, 726, 1215, 614, 1633, +236, 1415, -219, 558, -582, -536, -715, -1415, +-551, -1749, -147, -1322, 324, -306, 642, 794, +684, 1566, 465, 1768, 66, 1227, -385, 127, +-696, -1023, -714, -1775, -433, -1815, 36, -1034, +504, 191, 761, 1275, 706, 1861, 358, 1733, +-160, 853, -629, -423, -816, -1516, -657, -1998, +-236, -1616, 295, -520, 715, 725, 827, 1626, +597, 1925, 116, 1433, -439, 286, -805, -948, +-806, -1755, -480, -1863, 41, -1187, 585, -11, +879, 1085, 762, 1719, 321, 1709, -241, 994, +-703, -134, -850, -1170, -619, -1756, -140, -1657, +390, -827, 745, 319, 754, 1248, 442, 1703, +-15, 1542, -444, 716, -665, -416, -573, -1357, +-277, -1778, 58, -1478, 353, -534, 523, 587, +478, 1414, 278, 1717, 20, 1344, -246, 397, +-446, -692, -489, -1499, -367, -1743, -97, -1249, +253, -214, 521, 835, 579, 1501, 427, 1621, +107, 1114, -295, 142, -587, -858, -651, -1536, +-479, -1634, -99, -1043, 371, -33, 700, 921, +740, 1526, 499, 1608, 50, 1053, -469, 50, +-831, -990, -844, -1700, -482, -1753, 108, -1028, +668, 118, 963, 1179, 855, 1817, 366, 1796, +-293, 1004, -821, -256, -1015, -1433, -798, -2061, +-216, -1819, 474, -774, 930, 565, 991, 1642, +682, 2119, 98, 1759, -547, 615, -965, -814, +-986, -1910, -618, -2238, -5, -1606, 619, -268, +1013, 1128, 1018, 2057, 598, 2217, -98, 1458, +-773, 20, -1143, -1424, -1058, -2266, -508, -2165, +292, -1117, 977, 383, 1255, 1635, 1010, 2236, +322, 1990, -518, 884, -1137, -613, -1279, -1800, +-888, -2236, -113, -1763, 712, -543, 1227, 826, +1230, 1792, 721, 2117, -96, 1626, -860, 394, +-1247, -983, -1125, -1876, -555, -2030, 243, -1383, +928, -162, 1224, 1068, 1033, 1838, 425, 1952, +-365, 1280, -995, 51, -1209, -1155, -955, -1882, +-335, -1907, 444, -1156, 1061, 69, 1235, 1206, +906, 1907, 220, 1940, -556, 1144, -1115, -174, +-1229, -1381, -864, -2058, -145, -1963, 667, -1035, +1226, 337, 1281, 1564, 808, 2216, -3, 1996, +-840, 871, -1348, -627, -1302, -1839, -720, -2339, +189, -1890, 1066, -598, 1497, 932, 1284, 2052, +532, 2373, -456, 1708, -1274, 273, -1550, -1250, +-1170, -2236, -307, -2345, 719, -1458, 1456, 77, +1551, 1536, 976, 2348, -9, 2235, -1001, 1150, +-1545, -459, -1396, -1814, -663, -2403, 343, -2030, +1204, -777, 1502, 808, 1121, 1973, 320, 2311, +-573, 1712, -1216, 368, -1296, -1100, -818, -2021, +-88, -2104, 622, -1333, 1090, -2, 1110, 1232, +693, 1857, 43, 1761, -601, 985, -998, -217, +-989, -1236, -629, -1649, -43, -1442, 602, -721, +1012, 267, 987, 1065, 602, 1399, -16, 1250, +-682, 633, -1060, -226, -964, -924, -507, -1245, +135, -1153, 756, -612, 1065, 161, 927, 787, +445, 1127, -235, 1124, -856, 664, -1091, -69, +-863, -692, -325, -1066, 362, -1114, 944, -726, +1104, -65, 778, 557, 157, 1036, -534, 1223, +-1006, 906, -1021, 218, -609, -525, 19, -1149, +644, -1416, 1001, -1082, 911, -294, 467, 625, +-135, 1413, -710, 1698, -998, 1208, -828, 187, +-331, -929, 260, -1746, 759, -1848, 954, -1113, +731, 80, 209, 1249, -372, 1996, -799, 1900, +-885, 950, -600, -373, -93, -1545, 437, -2129, +781, -1787, 776, -690, 461, 617, 3, 1714, +-467, 2206, -779, 1748, -739, 520, -369, -868, +118, -1920, 541, -2239, 747, -1623, 639, -344, +278, 1080, -183, 2151, -588, 2352, -751, 1504, +-564, 42, -151, -1433, 291, -2391, 604, -2337, +665, -1225, 443, 364, 60, 1793, -345, 2546, +-633, 2205, -638, 865, -337, -804, 81, -2108, +433, -2546, 608, -1882, 522, -439, 206, 1129, +-178, 2253, -473, 2446, -582, 1540, -420, 32, +-46, -1384, 307, -2258, 463, -2224, 413, -1210, +218, 255, -34, 1514, -236, 2186, -336, 1972, +-298, 904, -128, -476, 54, -1581, 142, -2084, +192, -1744, 226, -658, 171, 642, 44, 1634, +-86, 1997, -228, 1529, -326, 422, -239, -782, +-16, -1663, 187, -1921, 327, -1362, 362, -228, +210, 918, -64, 1694, -308, 1843, -417, 1198, +-316, 43, -38, -1070, 222, -1762, 337, -1774, +328, -1004, 186, 171, -56, 1208, -250, 1770, +-302, 1632, -234, 757, -65, -402, 140, -1321, +261, -1723, 258, -1425, 144, -494, -42, 583, +-187, 1341, -219, 1594, -172, 1200, -52, 275, +120, -700, 214, -1332, 156, -1460, 37, -992, +-68, -117, -131, 728, -103, 1287, -20, 1401, +42, 907, 73, 3, 66, -824, 1, -1322, +-56, -1345, -57, -769, -33, 141, 18, 918, +92, 1357, 87, 1293, -12, 616, -85, -330, +-102, -1052, -93, -1333, -28, -1071, 87, -334, +162, 452, 167, 991, 96, 1211, -67, 920, +-228, 156, -242, -566, -122, -935, 27, -993, +153, -667, 224, -47, 204, 485, 97, 785, +-70, 882, -240, 609, -284, 44, -154, -451, +36, -742, 182, -802, 268, -531, 258, -82, +106, 317, -120, 698, -296, 893, -339, 628, +-218, 93, 30, -386, 264, -766, 352, -894, +277, -607, 99, -122, -127, 378, -317, 870, +-371, 1037, -241, 649, 34, 10, 289, -575, +362, -983, 240, -991, 51, -541, -133, 83, +-280, 690, -288, 1094, -140, 975, 39, 382, +161, -296, 227, -848, 201, -1097, 79, -816, +-44, -196, -110, 400, -167, 868, -196, 1066, +-130, 755, 20, 107, 156, -516, 202, -950, +160, -1017, 62, -634, -46, -44, -136, 511, +-173, 965, -144, 1060, -63, 644, 47, -16, +144, -640, 184, -1095, 165, -1102, 88, -565, +-55, 163, -203, 796, -257, 1195, -194, 1102, +-58, 461, 128, -362, 268, -1042, 270, -1329, +150, -976, -32, -158, -203, 619, -258, 1128, +-177, 1274, -62, 828, 63, -56, 203, -858, +246, -1275, 140, -1191, -2, -533, -122, 351, +-201, 975, -177, 1219, -76, 1027, 7, 322, +89, -552, 191, -1103, 202, -1192, 110, -782, +1, 13, -117, 725, -220, 1027, -209, 996, +-104, 577, 18, -203, 170, -860, 296, -1031, +252, -799, 59, -248, -140, 437, -273, 834, +-281, 835, -144, 590, 40, 83, 191, -545, +307, -848, 291, -707, 77, -317, -178, 186, +-308, 577, -298, 637, -159, 473, 66, 205, +240, -211, 286, -540, 219, -524, 47, -284, +-174, -13, -286, 237, -218, 332, -54, 256, +112, 186, 203, 89, 178, -112, 81, -240, +-17, -201, -105, -132, -157, -52, -120, 39, +-19, 77, 49, 126, 56, 208, 46, 159, +50, 0, 49, -91, 31, -140, 3, -196, +-25, -161, -57, -61, -95, 26, -92, 171, +-29, 305, 50, 252, 101, 72, 121, -99, +90, -254, -6, -316, -105, -222, -150, -82, +-134, 91, -63, 314, 45, 403, 127, 246, +161, 23, 144, -173, 47, -333, -104, -341, +-193, -194, -186, -31, -132, 159, -11, 358, +153, 366, 232, 187, 170, -30, 48, -240, +-72, -376, -162, -309, -185, -130, -138, 53, +-42, 291, 90, 461, 178, 338, 165, 16, +107, -275, 26, -453, -98, -409, -187, -129, +-170, 173, -107, 359, -15, 438, 115, 303, +185, -47, 147, -356, 71, -446, -14, -310, +-109, 2, -134, 281, -94, 315, -64, 217, +-13, 105, 74, -92, 103, -293, 84, -289, +78, -122, 46, 78, -33, 253, -93, 251, +-127, 65, -151, -58, -85, -72, 56, -141, +178, -190, 235, -112, 189, 10, 18, 143, +-163, 257, -236, 180, -228, -10, -154, -59, +22, -78, 199, -212, 251, -250, 192, -85, +73, 116, -56, 292, -136, 326, -163, 105, +-177, -127, -137, -167, -12, -209, 125, -262, +220, -106, 243, 140, 150, 277, -17, 330, +-154, 211, -242, -108, -273, -278, -183, -218, +20, -195, 218, -146, 324, 75, 295, 250, +136, 283, -53, 250, -202, 47, -318, -219, +-351, -248, -194, -152, 89, -153, 317, -59, +404, 149, 333, 213, 120, 183, -143, 152, +-351, -8, -440, -171, -360, -131, -97, -92, +234, -137, 462, -61, 490, 75, 309, 118, +7, 179, -288, 204, -480, 53, -511, -92, +-340, -131, 8, -222, 383, -253, 602, -63, +544, 125, 240, 214, -145, 295, -456, 231, +-611, -21, -523, -180, -183, -214, 253, -250, +566, -164, 635, 35, 433, 133, 23, 175, +-386, 243, -599, 155, -582, -30, -370, -93, +13, -126, 445, -209, 690, -181, 611, -71, +267, 22, -183, 176, -552, 293, -691, 207, +-563, 63, -200, -36, 288, -215, 680, -339, +740, -238, 439, -62, -61, 99, -527, 306, +-725, 376, -571, 197, -188, -5, 233, -154, +547, -320, 607, -362, 380, -206, 8, -5, +-322, 212, -488, 395, -431, 357, -222, 142, +15, -48, 227, -235, 382, -396, 385, -331, +197, -103, -72, 101, -306, 269, -397, 364, +-283, 250, -43, 41, 176, -118, 288, -248, +264, -293, 110, -191, -84, -57, -185, 59, +-162, 215, -68, 295, 16, 211, 24, 81, +-19, -51, -42, -231, 11, -322, 109, -256, +163, -118, 117, 93, -7, 325, -136, 382, +-194, 244, -159, 49, -70, -187, 39, -370, +151, -340, 189, -177, 109, -15, 5, 199, +-54, 374, -93, 313, -111, 112, -90, -55, +-72, -194, -36, -276, 89, -233, 200, -136, +169, 22, 40, 232, -85, 294, -174, 166, +-184, 60, -99, -30, 22, -171, 139, -205, +188, -123, 90, -83, -79, -14, -139, 132, +-69, 152, 48, 99, 122, 146, 75, 139, +-73, -27, -175, -169, -151, -263, -41, -322, +115, -162, 234, 137, 222, 308, 77, 368, +-135, 355, -305, 95, -279, -273, -67, -453, +120, -433, 178, -230, 188, 154, 146, 415, +31, 378, -52, 261, -90, 91, -159, -203, +-218, -376, -168, -285, -53, -137, 86, 15, +263, 185, 378, 222, 295, 151, 12, 129, +-331, 72, -528, -76, -446, -162, -149, -203, +207, -229, 507, -102, 591, 110, 310, 209, +-150, 258, -472, 274, -573, 100, -455, -167, +-96, -303, 329, -319, 527, -226, 456, 27, +229, 246, -91, 292, -376, 256, -466, 140, +-359, -82, -119, -234, 165, -258, 355, -235, +368, -95, 236, 132, -1, 227, -257, 198, +-343, 183, -246, 81, -109, -107, 36, -220, +196, -250, 238, -221, 127, -31, 24, 193, +-23, 245, -93, 225, -149, 171, -134, -34, +-105, -236, -68, -242, 33, -194, 159, -123, +192, 80, 109, 244, -13, 202, -113, 126, +-174, 82, -181, -45, -92, -164, 67, -203, +166, -219, 127, -113, 34, 123, -19, 234, +-48, 214, -82, 205, -88, 64, -63, -223, +-45, -329, -19, -225, 57, -105, 129, 102, +105, 350, 25, 332, -36, 77, -86, -133, +-145, -265, -119, -283, 35, -106, 144, 94, +69, 187, -54, 242, -71, 156, -33, -114, +3, -243, 63, -131, 97, -13, 20, 91, +-115, 216, -194, 136, -138, -89, 39, -165, +199, -150, 221, -138, 113, 25, -78, 251, +-267, 282, -276, 166, -76, -40, 124, -315, +201, -393, 193, -167, 82, 73, -108, 252, +-210, 431, -154, 369, -36, -2, 79, -342, +126, -488, 52, -444, -23, -98, -24, 363, +-25, 560, -42, 474, -10, 205, -3, -241, +-64, -588, -67, -561, 8, -294, 56, 78, +83, 516, 96, 704, 0, 430, -146, -20, +-172, -394, -76, -631, 41, -572, 140, -185, +160, 267, 59, 594, -95, 669, -206, 355, +-202, -159, -64, -522, 110, -637, 181, -489, +142, -31, 50, 470, -75, 661, -169, 519, +-154, 159, -73, -322, 8, -646, 77, -591, +108, -264, 73, 181, 8, 569, -39, 646, +-85, 363, -128, -47, -128, -424, -48, -643, +91, -535, 171, -131, 115, 309, 5, 598, +-73, 641, -160, 376, -222, -81, -130, -527, +69, -781, 194, -667, 198, -159, 98, 448, +-84, 831, -240, 861, -249, 486, -125, -214, +59, -869, 212, -1082, 232, -754, 133, -43, +-33, 726, -242, 1170, -354, 1031, -212, 355, +54, -537, 221, -1154, 268, -1169, 230, -647, +56, 168, -198, 956, -362, 1290, -356, 925, +-173, 107, 121, -718, 367, -1196, 418, -1087, +263, -422, -36, 407, -357, 998, -509, 1120, +-408, 685, -131, -89, 222, -770, 500, -1066, +497, -857, 204, -173, -164, 578, -434, 935, +-529, 831, -369, 395, -18, -261, 312, -812, +491, -903, 463, -530, 182, 102, -234, 708, +-516, 915, -536, 585, -321, -19, 54, -605, +417, -911, 547, -687, 376, -32, 11, 625, +-370, 972, -568, 841, -446, 150, -74, -741, +327, -1208, 532, -980, 405, -207, 26, 769, +-354, 1396, -527, 1260, -424, 441, -78, -680, +337, -1589, 550, -1678, 434, -780, 68, 570, +-363, 1667, -621, 1977, -532, 1236, -155, -227, +304, -1584, 624, -2180, 619, -1729, 268, -337, +-234, 1329, -643, 2346, -770, 2191, -502, 917, +52, -897, 573, -2272, 788, -2484, 617, -1499, +139, 235, -409, 1939, -756, 2686, -760, 2052, +-427, 418, 118, -1424, 598, -2585, 759, -2419, +563, -1040, 140, 764, -334, 2179, -685, 2567, +-751, 1666, -502, -51, -41, -1656, 444, -2436, +736, -2055, 710, -659, 372, 1009, -169, 2112, +-672, 2209, -858, 1266, -658, -294, -201, -1636, +357, -2141, 790, -1682, 822, -440, 426, 1045, +-148, 1956, -636, 1873, -831, 960, -631, -376, +-160, -1529, 333, -1888, 649, -1345, 648, -258, +337, 931, -89, 1692, -442, 1596, -606, 746, +-486, -361, -155, -1265, 162, -1580, 338, -1136, +387, -230, 292, 692, 59, 1325, -170, 1381, +-285, 746, -294, -192, -224, -940, -101, -1281, +18, -1105, 107, -410, 198, 452, 270, 1053, +232, 1204, 52, 842, -208, 95, -426, -652, +-474, -1074, -309, -1081, 22, -626, 396, 116, +603, 765, 468, 1084, 49, 999, -399, 464, +-649, -315, -575, -920, -185, -1139, 289, -946, +543, -322, 486, 537, 209, 1168, -175, 1256, +-479, 784, -497, -38, -250, -842, 56, -1291, +281, -1217, 357, -591, 229, 393, -17, 1214, +-205, 1421, -283, 985, -243, 154, -89, -752, +67, -1353, 143, -1359, 174, -749, 136, 220, +-6, 1108, -150, 1479, -213, 1173, -210, 353, +-122, -626, 32, -1317, 156, -1406, 241, -896, +255, 9, 77, 967, -241, 1499, -442, 1288, +-405, 481, -195, -486, 119, -1212, 422, -1420, +524, -997, 337, -94, -51, 892, -465, 1449, +-697, 1290, -584, 537, -147, -433, 385, -1213, +722, -1450, 673, -982, 265, 0, -252, 1009, +-644, 1504, -797, 1225, -595, 345, -38, -689, +529, -1396, 751, -1395, 610, -661, 222, 405, +-279, 1254, -642, 1476, -693, 918, -487, -149, +-103, -1083, 355, -1389, 654, -1023, 625, -204, +308, 731, -156, 1317, -550, 1222, -675, 501, +-532, -469, -213, -1173, 228, -1245, 616, -738, +667, 43, 343, 834, -113, 1301, -480, 1116, +-630, 349, -478, -580, -117, -1254, 220, -1331, +412, -739, 420, 177, 202, 1012, -124, 1467, +-313, 1238, -300, 316, -192, -777, -72, -1485, +19, -1513, 52, -811, 56, 312, 80, 1264, +117, 1639, 130, 1297, 67, 301, -99, -895, +-288, -1648, -366, -1607, -285, -829, -80, 323, +219, 1290, 469, 1656, 445, 1328, 150, 410, +-217, -752, -513, -1564, -611, -1595, -377, -930, +62, 64, 406, 992, 548, 1498, 466, 1375, +129, 692, -308, -287, -599, -1162, -628, -1514, +-355, -1196, 112, -446, 467, 423, 543, 1163, +421, 1492, 129, 1212, -306, 403, -646, -619, +-648, -1428, -309, -1633, 160, -1148, 510, -205, +600, 871, 407, 1680, -1, 1797, -435, 1093, +-666, -133, -590, -1366, -227, -2028, 257, -1765, +573, -717, 553, 619, 265, 1754, -126, 2206, +-437, 1648, -548, 278, -454, -1234, -182, -2179, +187, -2133, 451, -1154, 464, 281, 295, 1621, +22, 2330, -306, 1979, -547, 682, -573, -864, +-374, -1997, 17, -2293, 479, -1569, 744, -158, +616, 1256, 171, 2155, -392, 2195, -857, 1230, +-968, -321, -581, -1699, 150, -2328, 847, -1952, +1139, -720, 845, 788, 85, 1970, -771, 2382, +-1304, 1719, -1216, 202, -494, -1380, 498, -2282, +1236, -2191, 1358, -1147, 805, 399, -179, 1749, +-1119, 2332, -1513, 1899, -1151, 577, -250, -1015, +726, -2076, 1338, -2160, 1308, -1326, 611, 48, +-392, 1401, -1152, 2140, -1332, 1911, -944, 818, +-185, -642, 637, -1807, 1167, -2111, 1119, -1415, +517, -116, -257, 1170, -816, 1919, -1053, 1818, +-952, 856, -453, -542, 274, -1638, 861, -1842, +1049, -1138, 793, 9, 208, 1039, -493, 1541, +-1040, 1315, -1172, 466, -796, -563, -64, -1226, +750, -1193, 1276, -573, 1147, 210, 393, 748, +-512, 855, -1148, 567, -1307, 84, -885, -351, +-44, -567, 796, -477, 1248, -138, 1080, 177, +351, 244, -490, 145, -1002, 74, -1064, 62, +-724, 47, -116, 25, 502, -11, 875, -76, +845, -161, 414, -235, -169, -214, -598, -11, +-762, 285, -663, 444, -321, 348, 130, 40, +485, -312, 601, -495, 448, -421, 136, -175, +-175, 188, -395, 541, -486, 589, -427, 254, +-274, -192, -79, -499, 164, -565, 396, -326, +493, 83, 418, 417, 185, 545, -194, 401, +-611, 18, -852, -355, -738, -506, -252, -425, +398, -130, 891, 252, 1046, 461, 765, 404, +16, 197, -872, -93, -1366, -375, -1261, -444, +-646, -248, 330, 29, 1258, 239, 1596, 348, +1178, 299, 217, 87, -925, -136, -1735, -236, +-1780, -237, -999, -146, 277, 25, 1447, 132, +1929, 109, 1534, 82, 442, 86, -921, 48, +-1926, 0, -2056, -25, -1254, -68, 133, -108, +1474, -111, 2101, -102, 1747, -40, 616, 98, +-816, 216, -1915, 231, -2167, 144, -1453, -22, +-52, -174, 1393, -227, 2109, -233, 1797, -202, +731, -55, -641, 187, -1758, 380, -2075, 418, +-1456, 268, -207, -19, 1117, -319, 1861, -535, +1678, -586, 790, -361, -367, 140, -1383, 672, +-1794, 923, -1390, 704, -416, 76, 674, -641, +1443, -1052, 1538, -992, 933, -485, -46, 339, +-980, 1110, -1483, 1350, -1328, 879, -629, -62, +263, -1011, 1013, -1460, 1325, -1163, 1020, -314, +270, 661, -532, 1357, -1104, 1436, -1274, 809, +-919, -235, -169, -1193, 626, -1568, 1146, -1136, +1198, -179, 725, 761, -115, 1324, -979, 1341, +-1434, 764, -1207, -186, -426, -1035, 498, -1373, +1192, -1080, 1369, -338, 859, 488, -130, 1053, +-1038, 1159, -1401, 817, -1137, 173, -410, -533, +502, -1020, 1165, -1069, 1211, -675, 669, -56, +-122, 528, -829, 922, -1194, 1029, -1056, 738, +-462, 97, 346, -602, 993, -1056, 1136, -1133, +732, -778, 12, -65, -724, 740, -1159, 1317, +-1075, 1383, -520, 805, 267, -203, 962, -1154, +1179, -1645, 774, -1469, -3, -632, -756, 566, +-1153, 1618, -1022, 2014, -485, 1461, 209, 171, +846, -1212, 1153, -2067, 884, -2053, 132, -1140, +-694, 346, -1174, 1759, -1130, 2424, -653, 1977, +88, 601, 871, -1072, 1317, -2269, 1103, -2446, +287, -1547, -729, 15, -1418, 1615, -1403, 2560, +-746, 2346, 193, 1063, 1052, -686, 1459, -2149, +1150, -2650, 254, -1949, -785, -454, -1473, 1195, +-1464, 2418, -765, 2627, 237, 1606, 1071, -129, +1411, -1764, 1106, -2648, 282, -2373, -682, -1053, +-1356, 684, -1431, 2124, -852, 2701, 109, 2074, +985, 497, 1379, -1257, 1119, -2430, 333, -2540, +-607, -1525, -1270, 121, -1359, 1631, -825, 2423, +64, 2214, 873, 1060, 1245, -541, 1011, -1865, +272, -2350, -577, -1833, -1084, -603, -1060, 798, +-601, 1879, 57, 2236, 646, 1633, 920, 303, +726, -1111, 142, -2022, -450, -2104, -733, -1335, +-682, -14, -351, 1349, 99, 2165, 350, 2008, +342, 966, 281, -420, 123, -1601, -175, -2115, +-293, -1697, -161, -580, -83, 702, -111, 1709, +-134, 2007, -163, 1386, -78, 222, 180, -929, +334, -1692, 253, -1775, 83, -1121, -150, -61, +-401, 1029, -508, 1750, -423, 1685, -121, 858, +365, -247, 653, -1205, 455, -1695, 58, -1465, +-241, -613, -500, 488, -643, 1387, -459, 1652, +-45, 1156, 336, 209, 572, -752, 549, -1356, +191, -1364, -279, -809, -561, 35, -601, 826, +-437, 1231, -85, 1093, 327, 536, 581, -189, +539, -786, 161, -1014, -363, -845, -625, -413, +-492, 149, -211, 653, 71, 882, 333, 768, +403, 385, 189, -124, -105, -560, -289, -783, +-312, -764, -154, -464, 50, 63, 79, 572, +-26, 842, -81, 810, -74, 466, -31, -90, +78, -617, 140, -911, 47, -850, -98, -407, +-219, 219, -306, 725, -232, 943, 18, 775, +222, 261, 267, -333, 197, -775, 4, -948, +-237, -691, -349, -76, -308, 484, -169, 787, +39, 847, 207, 567, 250, 0, 208, -537, +71, -865, -167, -858, -369, -398, -407, 234, +-261, 642, 12, 798, 250, 716, 337, 298, +300, -292, 124, -748, -204, -855, -491, -530, +-519, 6, -298, 413, 41, 636, 341, 689, +440, 442, 312, -16, 64, -432, -225, -680, +-463, -643, -517, -295, -334, 112, 1, 415, +334, 638, 484, 648, 346, 329, 47, -147, +-219, -586, -412, -817, -504, -633, -375, -129, +-38, 369, 290, 730, 430, 864, 320, 558, +55, -91, -146, -669, -234, -916, -335, -761, +-376, -233, -210, 409, 26, 821, 173, 865, +284, 524, 320, -92, 190, -639, -8, -829, +-237, -667, -520, -244, -623, 306, -333, 718, +133, 771, 468, 472, 604, -24, 494, -494, +106, -721, -384, -635, -731, -295, -773, 173, +-430, 598, 145, 780, 582, 579, 688, 64, +518, -464, 113, -741, -387, -700, -703, -376, +-709, 120, -431, 589, 52, 840, 480, 712, +588, 185, 435, -435, 163, -796, -201, -815, +-504, -534, -557, -13, -403, 549, -144, 924, +151, 935, 337, 472, 361, -262, 310, -869, +163, -1124, -116, -925, -386, -253, -520, 582, +-506, 1186, -306, 1353, 69, 885, 444, -161, +645, -1181, 572, -1593, 180, -1294, -385, -391, +-806, 783, -871, 1624, -569, 1702, 9, 995, +624, -250, 943, -1433, 802, -1889, 257, -1449, +-469, -370, -1006, 917, -1052, 1791, -633, 1789, +29, 1005, 694, -202, 1048, -1387, 875, -1939, +275, -1527, -468, -452, -1020, 767, -1098, 1673, +-692, 1822, -32, 1129, 640, -13, 1050, -1137, +948, -1809, 390, -1623, -343, -665, -979, 508, +-1226, 1405, -883, 1708, -116, 1257, 673, 279, +1161, -773, 1115, -1511, 488, -1601, -417, -961, +-1132, 52, -1340, 977, -913, 1512, -3, 1440, +900, 784, 1282, -179, 999, -1136, 251, -1707, +-615, -1520, -1180, -623, -1168, 532, -609, 1492, +210, 1883, 874, 1487, 1021, 410, 635, -943, +23, -2009, -525, -2193, -829, -1295, -773, 236, +-400, 1653, 89, 2367, 474, 2084, 607, 828, +468, -909, 173, -2306, -158, -2658, -448, -1749, +-592, 34, -509, 1811, -241, 2711, 110, 2388, +419, 1023, 545, -868, 425, -2434, 139, -2842, +-223, -1890, -575, -71, -729, 1780, -526, 2769, +-74, 2418, 358, 1010, 618, -779, 649, -2255, +387, -2713, -107, -1843, -599, -131, -839, 1543, +-691, 2460, -234, 2218, 281, 975, 631, -595, +718, -1847, 503, -2321, 50, -1679, -448, -209, +-781, 1209, -796, 1950, -472, 1863, 34, 965, +498, -372, 760, -1446, 709, -1828, 349, -1416, +-195, -355, -734, 819, -996, 1505, -770, 1517, +-196, 913, 390, -84, 805, -987, 914, -1413, +575, -1256, -83, -532, -687, 444, -982, 1117, +-874, 1251, -393, 911, 225, 200, 684, -612, +857, -1133, 696, -1154, 212, -658, -383, 160, +-812, 856, -925, 1104, -681, 885, -172, 310, +385, -410, 815, -950, 946, -1057, 597, -654, +-92, 88, -694, 748, -980, 1002, -927, 808, +-490, 258, 184, -430, 746, -894, 967, -914, +775, -516, 214, 144, -421, 759, -834, 971, +-966, 675, -776, 60, -244, -555, 394, -869, +863, -764, 1039, -322, 763, 275, 50, 772, +-703, 879, -1136, 520, -1181, -86, -773, -605, +89, -806, 1002, -643, 1414, -218, 1126, 305, +329, 706, -631, 774, -1347, 488, -1483, -22, +-958, -532, -2, -780, 947, -648, 1451, -268, +1282, 201, 513, 639, -500, 828, -1263, 619, +-1445, 111, -1049, -476, -254, -861, 686, -816, +1342, -419, 1330, 121, 687, 682, -207, 1004, +-1004, 810, -1407, 215, -1187, -472, -439, -984, +450, -1013, 1107, -536, 1271, 103, 818, 695, +-13, 1102, -752, 965, -1131, 285, -1079, -466, +-578, -965, 165, -1061, 754, -643, 954, 34, +744, 605, 244, 971, -290, 963, -661, 442, +-844, -270, -728, -775, -256, -961, 271, -733, +570, -181, 669, 351, 570, 727, 210, 905, +-261, 670, -633, 56, -807, -527, -659, -819, +-202, -784, 295, -422, 629, 106, 735, 538, +546, 750, 100, 673, -405, 282, -792, -239, +-891, -592, -559, -635, 25, -417, 517, -86, +776, 201, 766, 378, 403, 438, -199, 361, +-722, 142, -929, -123, -749, -292, -237, -344, +357, -329, 733, -234, 777, -48, 512, 176, +30, 400, -469, 507, -765, 349, -756, 15, +-461, -267, 12, -468, 450, -566, 664, -420, +618, -55, 358, 346, -68, 664, -527, 729, +-793, 418, -726, -64, -373, -487, 127, -798, +579, -838, 783, -450, 654, 175, 247, 759, +-313, 1096, -792, 927, -918, 272, -647, -469, +-145, -1030, 422, -1265, 836, -911, 861, -38, +503, 859, -52, 1386, -631, 1331, -996, 635, +-910, -363, -434, -1188, 177, -1566, 724, -1263, +997, -290, 828, 823, 280, 1513, -412, 1579, +-972, 943, -1131, -174, -806, -1170, -155, -1623, +585, -1438, 1111, -598, 1135, 585, 638, 1464, +-164, 1642, -970, 1132, -1388, 154, -1145, -876, +-386, -1504, 502, -1520, 1202, -903, 1395, 162, +886, 1159, -87, 1581, -1006, 1315, -1463, 545, +-1270, -436, -502, -1234, 471, -1514, 1196, -1167, +1364, -311, 893, 703, -8, 1383, -889, 1426, +-1331, 890, -1166, 34, -513, -829, 305, -1361, +953, -1340, 1181, -768, 862, 151, 121, 1027, +-647, 1443, -1075, 1226, -1028, 524, -556, -366, +121, -1130, 687, -1471, 926, -1189, 761, -339, +238, 692, -397, 1391, -799, 1449, -800, 894, +-488, -16, -47, -919, 351, -1453, 578, -1358, +574, -629, 337, 382, -59, 1169, -422, 1406, +-563, 1049, -480, 279, -292, -566, -37, -1162, +278, -1292, 515, -866, 505, -52, 237, 737, +-149, 1172, -476, 1135, -590, 650, -438, -91, +-124, -779, 206, -1173, 451, -1115, 509, -548, +292, 280, -111, 936, -431, 1181, -474, 981, +-306, 388, -104, -387, 84, -1025, 259, -1265, +320, -960, 198, -197, -19, 658, -196, 1194, +-260, 1234, -216, 800, -125, 19, -40, -843, +50, -1382, 140, -1294, 156, -606, 64, 350, +-65, 1168, -129, 1489, -107, 1141, -54, 294, +-36, -685, -54, -1420, -52, -1565, -16, -961, +6, 123, 22, 1155, 78, 1663, 133, 1394, +70, 489, -108, -597, -258, -1453, -286, -1733, +-173, -1152, 42, 52, 250, 1180, 314, 1735, +187, 1524, -48, 560, -266, -678, -376, -1527, +-313, -1696, -63, -1121, 230, 66, 337, 1232, +218, 1730, 24, 1428, -164, 472, -312, -727, +-305, -1509, -118, -1546, 100, -958, 232, 88, +231, 1166, 75, 1624, -127, 1270, -226, 382, +-216, -677, -136, -1413, 19, -1435, 179, -829, +220, 125, 99, 1090, -116, 1535, -276, 1176, +-245, 273, -86, -729, 62, -1388, 188, -1351, +260, -673, 159, 288, -103, 1148, -344, 1477, +-403, 1017, -214, 55, 115, -872, 327, -1355, +318, -1177, 171, -438, -66, 470, -329, 1144, +-448, 1282, -317, 776, 18, -111, 373, -890, +471, -1183, 207, -881, -153, -205, -354, 461, +-395, 879, -288, 916, -19, 502, 297, -157, +453, -654, 328, -746, -31, -454, -380, -7, +-493, 303, -351, 401, -71, 350, 215, 132, +375, -156, 370, -272, 221, -158, -78, 68, +-414, 250, -531, 183, -339, -106, -31, -306, +213, -313, 356, -232, 378, 2, 235, 372, +-45, 609, -325, 549, -453, 184, -383, -387, +-164, -808, 98, -787, 290, -440, 355, 84, +296, 667, 132, 1004, -102, 880, -329, 352, +-456, -431, -389, -1097, -140, -1197, 149, -736, +368, -11, 469, 777, 375, 1312, 66, 1237, +-306, 579, -568, -370, -599, -1228, -329, -1533, +109, -1093, 448, -171, 578, 848, 479, 1563, +132, 1576, -308, 837, -581, -315, -595, -1387, +-380, -1847, -1, -1423, 356, -353, 529, 895, +506, 1821, 281, 1927, -105, 1108, -456, -221, +-614, -1481, -542, -2116, -239, -1780, 177, -642, +502, 789, 644, 1946, 536, 2267, 105, 1521, +-439, 100, -730, -1364, -671, -2288, -371, -2203, +73, -1111, 495, 456, 694, 1856, 586, 2501, +207, 2016, -286, 596, -629, -1081, -665, -2292, +-439, -2488, -78, -1564, 278, 13, 523, 1580, +587, 2515, 400, 2312, -22, 1023, -450, -674, +-612, -2020, -486, -2487, -234, -1833, 47, -392, +335, 1133, 531, 2163, 473, 2296, 167, 1384, +-185, -148, -417, -1530, -482, -2196, -387, -1929, +-181, -869, 83, 516, 354, 1676, 519, 2164, +435, 1713, 116, 490, -271, -922, -524, -1905, +-527, -2070, -341, -1368, -61, -105, 304, 1213, +600, 2058, 540, 2035, 145, 1089, -265, -384, +-490, -1685, -495, -2194, -296, -1731, 1, -585, +265, 807, 410, 1942, 338, 2235, 63, 1461, +-196, 18, -278, -1397, -214, -2165, -90, -1953, +3, -919, 31, 457, 55, 1674, 75, 2208, +25, 1713, -19, 428, 39, -1005, 93, -1975, +24, -2058, -122, -1228, -239, 76, -233, 1309, +-78, 2033, 101, 1872, 208, 829, 261, -561, +225, -1650, 25, -1998, -261, -1459, -440, -324, +-369, 861, -86, 1683, 200, 1828, 343, 1134, +370, -69, 275, -1149, 9, -1689, -329, -1529, +-526, -726, -462, 343, -171, 1208, 188, 1582, +431, 1309, 496, 448, 389, -586, 85, -1315, +-336, -1485, -653, -1029, -664, -121, -322, 800, +197, 1346, 587, 1339, 674, 744, 488, -211, +97, -1052, -392, -1380, -746, -1079, -730, -308, +-324, 566, 234, 1146, 615, 1203, 661, 720, +420, -88, 36, -820, -346, -1125, -604, -906, +-617, -305, -327, 398, 130, 884, 470, 948, +551, 603, 411, 24, 115, -534, -234, -826, +-494, -738, -575, -356, -404, 118, -4, 522, +400, 739, 575, 654, 480, 271, 191, -211, +-172, -575, -442, -715, -549, -591, -469, -224, +-151, 250, 270, 661, 519, 831, 505, 603, +322, 55, 31, -496, -281, -793, -495, -769, +-544, -437, -384, 107, -24, 657, 344, 946, +533, 764, 516, 152, 324, -519, -7, -871, +-376, -825, -640, -460, -651, 117, -333, 694, +163, 992, 553, 812, 691, 175, 565, -573, +182, -993, -351, -928, -781, -481, -836, 175, +-435, 797, 186, 1108, 665, 935, 801, 264, +574, -616, 75, -1168, -476, -1111, -814, -603, +-762, 121, -310, 838, 301, 1224, 694, 1065, +696, 412, 400, -466, -20, -1116, -411, -1191, +-650, -769, -632, -113, -303, 586, 190, 1079, +539, 1101, 594, 645, 436, -73, 140, -744, +-228, -1062, -537, -917, -668, -445, -510, 166, +-51, 720, 451, 993, 685, 844, 593, 323, +275, -317, -148, -759, -526, -869, -723, -674, +-614, -220, -158, 346, 401, 743, 697, 807, +643, 548, 355, 60, -66, -422, -476, -670, +-719, -673, -676, -454, -273, -24, 320, 424, +709, 657, 707, 632, 419, 370, -35, -49, +-496, -432, -730, -658, -631, -662, -240, -359, +293, 136, 650, 542, 618, 738, 318, 674, +-49, 284, -375, -266, -533, -692, -456, -858, +-213, -665, 104, -112, 357, 494, 405, 862, +289, 910, 121, 567, -90, -99, -301, -722, +-392, -995, -321, -858, -117, -335, 140, 362, +301, 867, 310, 983, 247, 711, 104, 132, +-138, -527, -336, -940, -353, -933, -221, -541, +-34, 62, 140, 630, 267, 931, 334, 850, +281, 416, 59, -197, -231, -729, -421, -954, +-414, -765, -224, -256, 50, 348, 304, 824, +469, 962, 443, 657, 162, 58, -229, -545, +-492, -931, -508, -922, -297, -479, 21, 184, +292, 761, 446, 1013, 438, 778, 236, 162, +-76, -477, -345, -883, -478, -927, -430, -524, +-209, 154, 85, 727, 344, 958, 497, 741, +459, 128, 214, -512, -155, -823, -499, -773, +-619, -411, -426, 184, -65, 708, 268, 862, +497, 599, 529, 28, 296, -545, -64, -767, +-347, -628, -462, -294, -389, 189, -171, 655, +84, 788, 268, 529, 327, 53, 275, -459, +155, -770, -18, -708, -218, -355, -337, 112, +-289, 570, -127, 839, 55, 734, 208, 263, +285, -353, 247, -810, 103, -897, -109, -606, +-286, -67, -305, 538, -168, 954, 12, 944, +162, 486, 243, -216, 218, -825, 89, -1038, +-89, -776, -228, -185, -248, 492, -144, 953, +12, 956, 145, 505, 202, -154, 161, -710, +56, -918, -59, -700, -144, -184, -156, 381, +-91, 735, -14, 728, 35, 404, 59, -46, +53, -431, 32, -614, 38, -537, 60, -258, +51, 105, -16, 412, -108, 532, -159, 437, +-139, 202, -69, -104, 33, -401, 152, -555, +226, -487, 190, -211, 40, 187, -137, 537, +-216, 655, -174, 479, -105, 92, -31, -354, +67, -683, 134, -728, 147, -427, 137, 99, +81, 583, -14, 795, -88, 659, -163, 235, +-236, -310, -203, -729, -31, -817, 191, -537, +354, -7, 334, 526, 111, 799, -153, 703, +-340, 309, -430, -210, -328, -634, 2, -749, +364, -504, 541, -43, 451, 408, 110, 641, +-312, 564, -574, 256, -579, -134, -339, -457, +99, -563, 550, -391, 762, -52, 604, 268, +120, 451, -463, 435, -822, 225, -789, -63, +-424, -310, 136, -444, 703, -385, 989, -127, +788, 189, 182, 400, -517, 435, -971, 287, +-979, 17, -552, -272, 124, -469, 770, -462, +1090, -210, 899, 148, 250, 413, -533, 490, +-1033, 363, -1027, 80, -567, -231, 131, -446, +767, -484, 1046, -290, 839, 52, 241, 329, +-470, 429, -922, 374, -907, 184, -519, -90, +42, -327, 588, -430, 889, -344, 785, -91, +326, 180, -274, 326, -730, 345, -824, 260, +-586, 73, -153, -158, 374, -346, 789, -398, +827, -245, 459, 23, -108, 227, -604, 334, +-793, 372, -630, 259, -243, -20, 249, -321, +666, -489, 752, -424, 459, -133, -6, 192, +-420, 392, -621, 473, -547, 401, -282, 104, +60, -294, 392, -556, 573, -553, 502, -289, +209, 103, -175, 410, -461, 534, -526, 491, +-417, 254, -185, -159, 175, -549, 526, -662, +632, -432, 431, -32, 36, 325, -372, 543, +-597, 569, -571, 355, -349, -41, 20, -433, +439, -613, 684, -485, 601, -147, 235, 203, +-237, 432, -589, 481, -668, 341, -488, 94, +-130, -164, 318, -376, 658, -431, 679, -277, +368, -54, -97, 121, -480, 275, -616, 375, +-496, 340, -217, 180, 139, -80, 460, -363, +588, -490, 445, -396, 107, -166, -259, 155, +-495, 472, -524, 579, -357, 419, -32, 94, +349, -318, 596, -638, 553, -638, 218, -331, +-236, 110, -560, 518, -609, 695, -386, 544, +30, 173, 467, -278, 681, -654, 548, -720, +132, -414, -365, 57, -662, 469, -613, 675, +-317, 582, 100, 243, 528, -175, 731, -525, +549, -654, 100, -480, -391, -102, -706, 300, +-678, 562, -341, 569, 121, 349, 552, 14, +772, -341, 614, -572, 131, -537, -413, -272, +-740, 87, -684, 420, -315, 571, 129, 462, +490, 185, 681, -155, 562, -458, 130, -556, +-356, -397, -616, -95, -570, 236, -295, 480, +63, 512, 376, 339, 558, 50, 509, -262, +194, -471, -234, -488, -541, -331, -591, -45, +-364, 280, 52, 492, 447, 507, 626, 328, +524, 1, 173, -340, -307, -539, -669, -533, +-682, -309, -337, 85, 161, 453, 554, 609, +681, 510, 512, 188, 115, -219, -350, -524, +-653, -622, -644, -458, -346, -56, 87, 373, +469, 604, 644, 568, 550, 274, 231, -155, +-193, -473, -542, -568, -655, -463, -476, -133, +-85, 312, 339, 573, 601, 527, 593, 266, +326, -97, -84, -407, -460, -520, -623, -435, +-485, -160, -126, 252, 261, 550, 504, 538, +517, 287, 301, -74, -46, -420, -365, -570, +-506, -462, -402, -162, -106, 266, 208, 622, +385, 642, 378, 318, 216, -145, -16, -547, +-222, -694, -341, -503, -315, -87, -122, 393, +107, 755, 221, 747, 232, 306, 198, -296, +102, -731, -50, -816, -194, -525, -265, 10, +-212, 572, -60, 915, 85, 826, 169, 303, +206, -392, 181, -905, 75, -994, -69, -625, +-185, 22, -220, 686, -150, 1091, -13, 995, +96, 402, 128, -379, 124, -1000, 127, -1194, +83, -841, -52, -98, -178, 691, -190, 1211, +-109, 1216, -12, 648, 69, -224, 139, -1008, +200, -1383, 180, -1146, 13, -376, -197, 561, +-281, 1288, -213, 1500, -61, 1011, 124, 14, +266, -984, 285, -1536, 171, -1427, -52, -689, +-295, 378, -375, 1320, -227, 1694, 22, 1261, +238, 227, 349, -871, 292, -1565, 90, -1586, +-152, -888, -340, 218, -367, 1219, -176, 1694, +87, 1393, 255, 416, 326, -725, 286, -1493, +85, -1607, -178, -1003, -339, 69, -340, 1075, +-184, 1596, 55, 1425, 242, 575, 337, -561, +330, -1384, 154, -1546, -148, -1036, -390, -83, +-435, 873, -265, 1422, 39, 1366, 304, 690, +425, -313, 392, -1109, 177, -1365, -168, -1076, +-449, -350, -500, 530, -295, 1146, 58, 1263, +345, 880, 427, 116, 352, -709, 170, -1204, +-116, -1177, -390, -669, -480, 125, -325, 861, +-9, 1218, 277, 1068, 401, 457, 378, -374, +233, -1036, -42, -1224, -333, -877, -464, -157, +-377, 618, -112, 1118, 203, 1123, 394, 615, +393, -162, 252, -835, 23, -1119, -224, -900, +-380, -269, -386, 457, -234, 933, 45, 971, +303, 566, 393, -90, 330, -671, 164, -904, +-87, -703, -325, -180, -416, 389, -323, 730, +-84, 717, 198, 370, 358, -148, 326, -560, +172, -671, -17, -462, -171, -42, -241, 372, +-216, 564, -115, 492, 20, 215, 101, -170, +111, -480, 118, -541, 131, -345, 107, -3, +40, 331, -66, 488, -192, 419, -250, 198, +-185, -113, -35, -401, 135, -487, 264, -339, +304, -77, 226, 204, 9, 404, -267, 418, +-412, 270, -345, 47, -135, -216, 139, -422, +382, -444, 472, -279, 357, -8, 48, 284, +-353, 470, -603, 463, -523, 275, -187, -64, +235, -435, 584, -599, 678, -466, 428, -144, +-53, 245, -549, 563, -805, 622, -631, 376, +-114, -44, 447, -474, 790, -690, 772, -540, +365, -150, -243, 257, -728, 572, -857, 660, +-571, 401, 8, -59, 589, -454, 863, -644, +714, -553, 235, -191, -341, 231, -751, 511, +-817, 592, -495, 433, 81, 49, 612, -358, +808, -574, 626, -537, 207, -274, -288, 89, +-688, 369, -776, 495, -481, 459, 30, 224, +499, -134, 743, -418, 671, -505, 311, -401, +-189, -163, -625, 123, -815, 383, -634, 534, +-113, 461, 473, 152, 817, -221, 791, -496, +430, -590, -138, -452, -680, -102, -930, 320, +-732, 629, -152, 665, 503, 386, 878, -81, +829, -521, 445, -749, -106, -650, -618, -248, +-868, 282, -725, 707, -243, 808, 340, 509, +733, -29, 780, -549, 519, -830, 82, -727, +-380, -281, -704, 289, -738, 745, -442, 864, +54, 532, 498, -62, 698, -579, 611, -821, +308, -717, -94, -287, -472, 282, -676, 732, +-580, 850, -214, 537, 216, -38, 521, -539, +607, -780, 456, -717, 134, -340, -232, 204, +-503, 651, -559, 814, -356, 606, -10, 98, +311, -442, 484, -760, 446, -758, 222, -430, +-58, 85, -282, 555, -393, 807, -357, 710, +-171, 245, 83, -321, 282, -686, 354, -768, +294, -556, 149, -80, -49, 423, -260, 724, +-392, 731, -357, 410, -153, -100, 139, -521, +389, -717, 480, -651, 365, -292, 85, 202, +-257, 563, -516, 688, -552, 540, -314, 134, +108, -315, 493, -597, 638, -654, 492, -434, +149, -8, -261, 381, -581, 587, -646, 563, +-405, 274, 28, -131, 450, -420, 662, -548, +570, -485, 242, -173, -173, 220, -517, 455, +-626, 494, -448, 347, -83, 52, 310, -247, +555, -451, 524, -508, 275, -338, -29, 5, +-296, 325, -451, 506, -400, 500, -173, 274, +100, -79, 299, -423, 347, -633, 256, -568, +109, -215, -47, 236, -192, 591, -247, 713, +-180, 500, -53, 41, 62, -442, 124, -768, +130, -779, 125, -405, 116, 172, 57, 664, +-35, 862, -99, 661, -118, 154, -117, -407, +-98, -795, -35, -857, 99, -519, 232, 61, +240, 589, 109, 843, -60, 718, -179, 271, +-219, -268, -179, -682, -61, -823, 118, -583, +268, -66, 271, 440, 123, 721, -60, 685, +-189, 341, -229, -137, -177, -524, -68, -692, +84, -557, 251, -166, 315, 261, 199, 542, +10, 586, -150, 356, -264, -23, -296, -334, +-189, -499, 25, -501, 266, -280, 424, 77, +371, 368, 124, 484, -166, 394, -372, 142, +-426, -129, -284, -349, 4, -488, 310, -426, +490, -148, 437, 171, 168, 398, -153, 487, +-373, 379, -426, 111, -287, -194, -22, -466, +240, -591, 398, -452, 390, -98, 197, 298, +-73, 590, -267, 649, -320, 428, -247, 30, +-85, -419, 113, -770, 266, -809, 298, -444, +195, 148, 43, 671, -87, 909, -170, 779, +-193, 308, -146, -359, -62, -936, 56, -1108, +186, -763, 245, -61, 210, 681, 109, 1130, +-34, 1084, -180, 567, -249, -224, -224, -969, +-105, -1305, 94, -1047, 273, -317, 318, 553, +240, 1180, 99, 1285, -78, 834, -236, 26, +-308, -816, -265, -1329, -113, -1260, 125, -630, +339, 264, 420, 1032, 331, 1350, 112, 1100, +-161, 384, -403, -523, -495, -1244, -340, -1425, +28, -959, 411, -79, 606, 811, 523, 1345, +205, 1309, -208, 690, -521, -260, -593, -1103, +-393, -1450, 20, -1146, 461, -337, 683, 601, +545, 1244, 148, 1334, -265, 842, -510, -21, +-537, -866, -336, -1314, 51, -1183, 443, -549, +607, 298, 469, 973, 129, 1201, -235, 934, +-444, 296, -434, -472, -249, -1045, 37, -1163, +333, -794, 484, -122, 396, 570, 134, 1015, +-150, 1053, -324, 668, -327, -6, -194, -698, +-7, -1102, 184, -1052, 315, -589, 317, 114, +178, 789, -20, 1151, -172, 1040, -221, 488, +-183, -299, -91, -1009, 38, -1317, 171, -1053, +254, -326, 237, 553, 126, 1218, -19, 1369, +-125, 909, -181, 17, -194, -917, -135, -1465, +21, -1349, 208, -619, 314, 374, 285, 1195, +151, 1492, -31, 1106, -226, 195, -347, -809, +-287, -1436, -46, -1402, 247, -733, 439, 240, +423, 1070, 215, 1411, -79, 1101, -346, 274, +-467, -649, -332, -1244, 33, -1281, 400, -750, +555, 103, 437, 853, 122, 1189, -245, 1010, +-486, 382, -484, -414, -221, -988, 196, -1108, +541, -763, 611, -106, 370, 565, -32, 953, +-392, 932, -539, 519, -434, -132, -125, -722, +272, -977, 583, -802, 627, -298, 364, 306, +-50, 761, -408, 886, -561, 616, -466, 50, +-168, -540, 226, -863, 565, -787, 671, -379, +471, 171, 64, 622, -341, 781, -568, 577, +-543, 104, -288, -407, 99, -714, 471, -685, +665, -351, 590, 119, 258, 495, -177, 624, +-510, 471, -605, 108, -452, -311, -101, -581, +336, -568, 659, -293, 705, 92, 450, 395, +3, 498, -440, 379, -659, 86, -568, -256, +-227, -467, 214, -446, 574, -226, 696, 73, +534, 306, 169, 376, -254, 275, -541, 56, +-576, -183, -374, -320, -25, -313, 356, -195, +619, -11, 653, 160, 438, 222, 52, 177, +-360, 96, -626, -11, -612, -137, -312, -216, +148, -211, 550, -144, 744, -33, 669, 87, +319, 174, -193, 205, -604, 152, -711, 5, +-502, -162, -98, -262, 340, -260, 670, -158, +769, 9, 577, 176, 137, 266, -354, 232, +-677, 83, -710, -114, -455, -266, 5, -302, +504, -208, 838, -31, 843, 147, 471, 252, +-110, 253, -618, 135, -830, -56, -678, -227, +-214, -294, 360, -237, 783, -97, 866, 70, +590, 218, 88, 287, -415, 212, -700, 18, +-661, -191, -328, -317, 133, -320, 534, -198, +720, 8, 627, 228, 289, 361, -146, 320, +-497, 114, -616, -148, -447, -349, -72, -417, +345, -321, 620, -89, 642, 188, 401, 393, +20, 425, -340, 257, -531, -38, -469, -323, +-178, -488, 199, -472, 492, -271, 586, 51, +448, 370, 169, 541, -135, 469, -378, 183, +-482, -189, -359, -498, -43, -636, 312, -535, +539, -190, 556, 278, 387, 639, 95, 706, +-249, 462, -518, 23, -537, -453, -267, -785, +159, -809, 519, -475, 650, 102, 514, 655, +203, 911, -164, 749, -465, 260, -536, -351, +-316, -849, 72, -1006, 404, -715, 538, -88, +447, 582, 217, 981, -44, 924, -250, 451, +-330, -210, -235, -788, -18, -1055, 196, -872, +313, -287, 307, 428, 214, 929, 86, 994, +-37, 621, -140, -11, -167, -643, -94, -1027, +42, -979, 169, -477, 244, 248, 240, 827, +152, 1017, 15, 768, -116, 181, -159, -503, +-96, -987, 49, -1044, 199, -627, 275, 90, +226, 753, 80, 1034, -76, 837, -157, 276, +-121, -417, -1, -943, 141, -1040, 231, -646, +227, 55, 132, 712, 10, 993, -82, 779, +-110, 221, -56, -408, 50, -860, 137, -927, +172, -546, 171, 98, 130, 659, 53, 856, +-29, 619, -73, 105, -69, -421, 4, -742, +121, -746, 215, -409, 228, 131, 152, 587, +18, 717, -106, 481, -153, 29, -86, -423, +87, -672, 266, -622, 332, -295, 230, 175, +31, 568, -161, 661, -241, 405, -160, -58, +47, -493, 281, -684, 406, -555, 345, -181, +125, 268, -124, 605, -288, 646, -287, 336, +-113, -154, 162, -550, 381, -673, 434, -498, +316, -124, 91, 293, -142, 580, -297, 590, +-295, 303, -120, -130, 164, -477, 386, -607, +436, -491, 315, -179, 104, 193, -119, 465, +-276, 533, -285, 371, -119, 35, 153, -321, +368, -538, 419, -538, 307, -335, 102, -5, +-122, 329, -263, 537, -255, 515, -87, 249, +167, -151, 379, -490, 430, -625, 282, -521, +29, -214, -193, 200, -275, 560, -203, 682, +-6, 478, 238, 37, 416, -427, 408, -720, +203, -731, -70, -442, -240, 52, -239, 548, +-120, 814, 60, 715, 259, 281, 396, -299, +364, -765, 178, -913, -53, -690, -212, -187, +-241, 408, -142, 859, 40, 947, 245, 595, +409, -44, 426, -670, 253, -1011, -38, -950, +-273, -511, -333, 153, -206, 789, 29, 1091, +293, 892, 489, 288, 499, -435, 279, -976, +-64, -1124, -330, -811, -397, -155, -251, 584, +23, 1076, 317, 1083, 526, 595, 553, -156, +350, -839, -9, -1161, -339, -995, -462, -418, +-327, 331, -30, 942, 303, 1130, 554, 784, +616, 78, 411, -641, 22, -1065, -340, -1038, +-474, -581, -346, 120, -51, 773, 279, 1075, +512, 859, 551, 237, 371, -471, 75, -952, +-202, -1035, -337, -685, -282, -31, -78, 650, +143, 1031, 303, 920, 395, 368, 391, -360, +254, -925, 29, -1084, -161, -770, -249, -114, +-215, 603, -85, 1044, 120, 986, 336, 444, +470, -318, 426, -926, 204, -1092, -83, -771, +-290, -132, -328, 555, -207, 986, 33, 942, +317, 425, 529, -294, 523, -844, 287, -979, +-42, -684, -291, -114, -369, 485, -258, 838, +-5, 778, 287, 343, 490, -247, 497, -706, +310, -813, 30, -551, -190, -69, -270, 415, +-216, 688, -75, 620, 120, 251, 308, -242, +400, -628, 360, -712, 227, -458, 64, -15, +-99, 407, -217, 637, -246, 561, -136, 199, +91, -276, 333, -634, 472, -703, 463, -446, +295, 0, 10, 425, -260, 658, -385, 597, +-313, 249, -68, -243, 275, -636, 544, -747, +594, -538, 407, -111, 90, 351, -224, 663, +-416, 692, -399, 411, -161, -71, 209, -536, +516, -779, 607, -699, 456, -337, 161, 160, +-155, 587, -365, 767, -382, 614, -189, 184, +135, -355, 430, -763, 550, -840, 451, -557, +216, -57, -53, 451, -263, 772, -338, 757, +-226, 398, 25, -156, 304, -660, 490, -874, +505, -697, 330, -244, 38, 279, -223, 683, +-347, 790, -285, 531, -64, 31, 244, -481, +489, -799, 539, -770, 364, -407, 73, 105, +-180, 547, -293, 751, -253, 624, -94, 215, +144, -296, 365, -701, 460, -805, 379, -544, +191, -61, -19, 406, -179, 689, -245, 678, +-186, 362, -6, -129, 234, -575, 424, -766, +458, -614, 311, -213, 58, 231, -162, 551, +-261, 628, -203, 428, -21, 49, 215, -340, +394, -582, 425, -572, 281, -336, 44, -10, +-136, 274, -191, 426, -133, 410, -1, 247, +189, -5, 346, -265, 377, -414, 259, -407, +65, -290, -110, -108, -195, 122, -156, 330, +-2, 419, 220, 343, 382, 116, 390, -175, +243, -417, 25, -524, -167, -455, -230, -190, +-134, 182, 66, 488, 279, 583, 399, 417, +355, 55, 175, -352, -18, -630, -141, -663, +-159, -414, -70, 27, 91, 459, 238, 670, +314, 559, 295, 182, 183, -267, 29, -590, +-88, -674, -110, -476, -53, -62, 52, 374, +163, 613, 261, 552, 291, 235, 212, -174, +58, -499, -61, -625, -86, -501, -37, -155, +46, 264, 144, 546, 243, 568, 284, 324, +220, -72, 81, -444, -37, -640, -90, -578, +-64, -261, 16, 183, 127, 545, 235, 655, +292, 454, 262, 25, 144, -428, 4, -693, +-99, -672, -115, -363, -53, 115, 54, 544, +171, 708, 274, 537, 320, 113, 282, -357, +162, -657, -7, -684, -153, -436, -210, -8, +-145, 409, 13, 621, 234, 552, 430, 244, +498, -163, 378, -496, 110, -624, -195, -512, +-372, -205, -319, 178, -94, 473, 190, 560, +437, 403, 570, 65, 501, -314, 244, -571, +-89, -605, -330, -394, -381, -11, -255, 380, +-11, 602, 289, 551, 552, 239, 639, -204, +483, -575, 125, -714, -268, -542, -508, -123, +-473, 358, -190, 676, 229, 691, 613, 378, +775, -142, 611, -627, 180, -843, -300, -685, +-586, -228, -533, 342, -193, 767, 255, 849, +613, 531, 739, -61, 576, -665, 198, -983, +-224, -858, -490, -356, -477, 299, -216, 825, +155, 979, 476, 675, 637, 51, 565, -618, +296, -1025, -61, -965, -344, -475, -429, 196, +-283, 748, 11, 960, 326, 739, 542, 177, +558, -473, 380, -914, 95, -942, -175, -542, +-342, 67, -325, 594, -132, 838, 138, 717, +369, 269, 494, -317, 464, -759, 276, -846, +19, -548, -195, -23, -291, 470, -253, 716, +-79, 634, 173, 259, 399, -247, 488, -650, +415, -746, 230, -491, -6, -23, -213, 422, +-323, 641, -272, 559, -59, 214, 244, -241, +483, -598, 551, -682, 424, -456, 170, -26, +-124, 393, -352, 607, -402, 539, -225, 227, +106, -199, 423, -565, 589, -690, 536, -498, +298, -75, -27, 362, -292, 616, -402, 591, +-319, 296, -57, -162, 292, -578, 564, -742, +617, -557, 434, -113, 100, 361, -225, 651, +-428, 634, -427, 319, -193, -163, 208, -579, +567, -726, 681, -539, 503, -111, 148, 343, +-209, 600, -422, 566, -414, 282, -194, -121, +164, -470, 491, -623, 620, -515, 489, -189, +191, 203, -118, 463, -304, 505, -324, 361, +-202, 79, 33, -261, 304, -529, 494, -597, +494, -427, 315, -73, 53, 304, -172, 555, +-286, 603, -261, 405, -108, -9, 140, -468, +390, -761, 498, -757, 406, -425, 179, 119, +-53, 627, -217, 873, -263, 748, -178, 273, +18, -370, 250, -898, 417, -1060, 434, -760, +299, -101, 97, 614, -97, 1048, -224, 1028, +-242, 551, -119, -204, 93, -907, 310, -1220, +428, -1006, 395, -349, 235, 460, 30, 1054, +-138, 1176, -225, 784, -196, 35, -57, -752, +142, -1215, 313, -1158, 393, -610, 360, 200, +241, 918, 52, 1223, -155, 984, -290, 310, +-269, -509, -81, -1129, 191, -1276, 435, -861, +540, -63, 452, 759, 181, 1232, -161, 1149, +-406, 544, -427, -312, -211, -1052, 151, -1340, +489, -1022, 635, -233, 534, 644, 234, 1205, +-140, 1210, -427, 655, -478, -202, -277, -972, +86, -1307, 446, -1050, 649, -316, 605, 537, +334, 1111, -56, 1165, -406, 683, -552, -108, +-419, -831, -47, -1176, 407, -1015, 733, -404, +758, 373, 481, 936, 19, 1050, -446, 700, +-702, 48, -591, -616, -145, -997, 419, -955, +835, -502, 897, 169, 577, 730, 26, 925, +-492, 714, -765, 193, -663, -416, -206, -838, +410, -883, 866, -546, 928, 20, 608, 551, +75, 792, -448, 659, -753, 240, -689, -273, +-271, -650, 324, -722, 802, -481, 931, -55, +666, 356, 160, 566, -369, 494, -703, 209, +-688, -136, -340, -398, 198, -474, 695, -357, +910, -116, 717, 140, 246, 303, -264, 308, +-607, 183, -662, 5, -410, -161, 56, -265, +547, -268, 836, -170, 756, -24, 371, 110, +-108, 181, -477, 171, -630, 89, -505, -21, +-128, -123, 361, -189, 745, -190, 815, -125, +535, -22, 78, 71, -344, 132, -603, 139, +-599, 97, -297, 18, 190, -92, 625, -201, +808, -242, 655, -182, 256, -48, -194, 103, +-512, 220, -582, 253, -394, 170, -10, -14, +419, -241, 708, -389, 696, -364, 408, -168, +11, 104, -327, 333, -504, 413, -457, 306, +-184, 38, 206, -292, 540, -518, 647, -504, +495, -253, 189, 103, -121, 405, -347, 518, +-424, 395, -305, 93, -16, -278, 316, -555, +528, -585, 531, -340, 356, 48, 91, 394, +-193, 553, -386, 472, -390, 184, -179, -206, +151, -536, 443, -632, 556, -439, 448, -61, +190, 325, -106, 555, -323, 541, -382, 293, +-245, -97, 46, -472, 354, -652, 503, -536, +445, -187, 250, 222, 16, 512, -204, 575, +-334, 398, -291, 40, -76, -362, 210, -620, +413, -600, 454, -311, 340, 92, 129, 433, +-117, 580, -300, 484, -323, 170, -154, -250, +127, -581, 368, -645, 449, -412, 348, -9, +139, 376, -87, 578, -238, 518, -249, 225, +-105, -187, 113, -544, 290, -649, 338, -438, +250, -33, 98, 358, -36, 557, -102, 489, +-101, 195, -32, -192, 77, -515, 165, -610, +185, -401, 156, 8, 104, 386, 46, 553, +1, 453, -24, 149, -25, -227, 5, -525, +73, -603, 142, -395, 179, 14, 163, 407, +101, 591, 4, 498, -79, 184, -100, -222, +-35, -555, 93, -673, 215, -501, 271, -89, +225, 376, 99, 665, -58, 642, -165, 336, +-176, -122, -73, -554, 101, -779, 261, -674, +336, -261, 299, 284, 158, 708, -45, 802, +-212, 536, -279, 39, -207, -489, 5, -845, +272, -845, 445, -461, 453, 138, 289, 673, +1, 902, -288, 722, -425, 225, -338, -379, +-58, -843, 302, -957, 546, -648, 556, -36, +338, 586, 0, 926, -306, 840, -438, 385, +-352, -236, -92, -764, 250, -971, 510, -755, +550, -202, 368, 429, 69, 839, -228, 853, +-402, 501, -379, -43, -164, -566, 158, -859, +456, -785, 572, -381, 435, 167, 125, 617, +-204, 783, -403, 619, -400, 210, -193, -278, +130, -667, 433, -789, 557, -586, 444, -144, +155, 346, -167, 676, -376, 714, -382, 459, +-205, 20, 66, -438, 347, -734, 511, -732, +463, -420, 220, 56, -82, 490, -306, 709, +-364, 639, -250, 313, -15, -157, 249, -585, +429, -781, 438, -656, 274, -267, 32, 234, +-182, 640, -287, 789, -258, 609, -109, 149, +91, -412, 260, -814, 346, -877, 328, -568, +209, 3, 23, 593, -152, 925, -257, 840, +-253, 372, -125, -291, 94, -848, 296, -1032, +401, -756, 374, -145, 212, 530, -44, 960, +-274, 949, -359, 508, -265, -163, -28, -766, +234, -1030, 415, -836, 449, -288, 324, 361, +69, 830, -206, 934, -381, 635, -367, 64, +-154, -531, 144, -897, 374, -883, 461, -500, +403, 86, 191, 616, -105, 881, -338, 772, +-383, 329, -235, -268, 22, -754, 264, -926, +410, -709, 429, -179, 297, 429, 56, 837, +-195, 877, -346, 546, -333, -34, -148, -619, +107, -950, 332, -870, 465, -411, 447, 225, +244, 754, -68, 956, -339, 749, -444, 202, +-317, -451, -16, -922, 308, -997, 512, -640, +533, -1, 340, 625, 0, 976, -323, 906, +-470, 430, -376, -242, -92, -803, 247, -1026, +476, -815, 517, -241, 364, 424, 79, 882, +-222, 952, -390, 617, -357, 11, -156, -601, +122, -956, 352, -912, 436, -476, 356, 161, +176, 700, -37, 926, -217, 771, -293, 273, +-228, -359, -71, -828, 116, -943, 279, -666, +361, -101, 323, 497, 188, 859, -4, 846, +-199, 466, -305, -127, -271, -662, -101, -903, +122, -764, 312, -300, 391, 288, 341, 730, +177, 840, -56, 589, -258, 82, -337, -461, +-273, -795, -102, -788, 137, -447, 356, 79, +455, 557, 384, 771, 171, 646, -117, 242, +-365, -270, -454, -657, -330, -745, -36, -512, +310, -75, 551, 379, 563, 648, 336, 619, +-35, 316, -377, -112, -543, -476, -451, -621, +-143, -496, 248, -167, 557, 212, 641, 474, +451, 507, 70, 314, -320, 1, -555, -298, +-535, -461, -261, -423, 164, -204, 549, 84, +710, 309, 554, 384, 148, 286, -293, 64, +-558, -179, -554, -345, -293, -371, 121, -226, +504, 19, 672, 233, 539, 331, 179, 292, +-221, 118, -470, -124, -487, -305, -286, -351, +51, -257, 382, -43, 562, 195, 496, 318, +218, 287, -123, 148, -352, -52, -387, -239, +-241, -319, 14, -271, 271, -121, 416, 78, +385, 233, 189, 271, -70, 212, -236, 95, +-243, -84, -129, -257, 31, -323, 174, -254, +245, -96, 231, 109, 131, 278, -23, 329, +-122, 251, -110, 58, -33, -206, 48, -411, +117, -423, 143, -246, 116, 38, 56, 326, +-33, 486, -98, 423, -66, 165, 42, -196, +128, -516, 144, -614, 105, -411, 31, -10, +-49, 393, -97, 635, -86, 596, -3, 273, +108, -203, 170, -611, 141, -751, 64, -541, +-11, -70, -65, 434, -85, 731, -73, 697, +-27, 355, 42, -167, 121, -639, 170, -821, +155, -619, 84, -141, -6, 400, -102, 761, +-178, 765, -156, 414, -20, -126, 150, -626, +269, -858, 283, -695, 171, -204, -19, 376, +-196, 782, -276, 832, -220, 499, -35, -61, +192, -597, 342, -878, 348, -774, 205, -320, +-13, 274, -203, 726, -292, 853, -251, 619, +-80, 125, 159, -432, 343, -806, 385, -838, +272, -523, 57, 9, -165, 536, -306, 827, +-308, 768, -151, 403, 109, -138, 339, -641, +425, -874, 332, -731, 109, -298, -126, 253, +-281, 702, -309, 844, -186, 629, 54, 166, +280, -372, 374, -771, 324, -838, 157, -551, +-49, -50, -194, 458, -227, 771, -159, 756, +-13, 430, 151, -78, 238, -562, 225, -805, +145, -702, 36, -301, -51, 225, -83, 645, +-87, 778, -64, 584, 1, 133, 71, -392, +108, -748, 129, -766, 130, -453, 91, 58, +27, 548, -44, 786, -104, 675, -123, 274, +-57, -263, 59, -705, 153, -823, 176, -577, +132, -89, 51, 439, -51, 770, -123, 756, +-115, 421, -39, -84, 54, -564, 117, -806, +124, -697, 72, -311, 14, 185, -15, 597, +-37, 751, -48, 601, -26, 232, 20, -221, +56, -598, 65, -742, 47, -589, 14, -215, +-11, 228, -25, 578, -16, 712, 22, 579, +72, 218, 79, -240, 32, -614, -32, -757, +-83, -604, -71, -208, 18, 267, 126, 648, +167, 793, 117, 621, 20, 165, -83, -379, +-156, -781, -136, -873, -3, -593, 162, -43, +246, 534, 207, 893, 78, 879, -73, 465, +-169, -181, -176, -756, -91, -996, 59, -793, +210, -231, 269, 426, 209, 886, 72, 960, +-84, 601, -179, -41, -173, -660, -87, -965, +47, -837, 197, -347, 286, 279, 241, 764, +87, 904, -72, 642, -159, 94, -159, -479, +-98, -815, 11, -780, 140, -406, 227, 117, +224, 553, 133, 732, 19, 599, -77, 206, +-132, -254, -139, -569, -76, -624, 44, -414, +158, -50, 214, 285, 196, 468, 103, 474, +-39, 303, -131, 2, -128, -279, -84, -410, +-16, -391, 87, -246, 172, -16, 171, 204, +97, 340, 8, 367, -61, 252, -90, 21, +-88, -202, -62, -337, 6, -366, 96, -267, +141, -55, 110, 180, 49, 354, -16, 402, +-70, 270, -86, 14, -66, -232, -26, -391, +31, -420, 103, -279, 121, -6, 65, 272, +4, 441, -29, 430, -63, 223, -97, -76, +-84, -328, -17, -463, 67, -431, 129, -203, +128, 135, 73, 412, 8, 504, -63, 381, +-134, 95, -152, -237, -73, -471, 47, -514, +149, -340, 196, -2, 162, 349, 69, 528, +-42, 452, -135, 186, -193, -141, -165, -401, +-43, -494, 113, -368, 225, -80, 247, 232, +188, 423, 71, 406, -70, 212, -197, -42, +-249, -246, -165, -354, 18, -335, 193, -181, +282, 51, 281, 250, 203, 326, 39, 266, +-150, 127, -268, -39, -253, -201, -114, -310, +87, -302, 255, -159, 309, 52, 273, 223, +165, 291, -17, 266, -204, 167, -274, 0, +-197, -194, -44, -331, 128, -342, 255, -207, +296, 16, 251, 214, 110, 331, -90, 357, +-237, 246, -237, -6, -127, -276, 18, -420, +160, -382, 247, -177, 246, 95, 149, 296, +-7, 373, -147, 320, -194, 120, -129, -150, +-29, -320, 60, -312, 128, -184, 166, -16, +134, 124, 45, 188, -38, 174, -92, 116, +-110, 31, -88, -57, -40, -95, 19, -84, +90, -77, 154, -95, 144, -90, 44, -25, +-86, 78, -181, 161, -180, 189, -84, 151, +45, 53, 154, -93, 207, -244, 140, -316, +-44, -239, -195, -29, -216, 210, -120, 368, +24, 382, 141, 243, 167, -28, 105, -340, +11, -533, -89, -487, -143, -198, -109, 207, +-25, 539, 46, 640, 74, 460, 66, 63, +38, -402, 21, -721, 4, -705, -39, -347, +-69, 175, -56, 621, -13, 788, 35, 600, +74, 153, 89, -355, 70, -728, 16, -786, +-62, -471, -92, 49, -43, 509, 36, 743, +94, 666, 112, 301, 86, -177, 15, -566, +-48, -730, -63, -572, -35, -139, 15, 318, +63, 590, 101, 617, 109, 402, 77, 10, +27, -371, -14, -568, -44, -524, -73, -258, +-60, 111, 24, 391, 128, 469, 184, 371, +161, 147, 85, -130, -28, -351, -136, -424, +-168, -321, -92, -89, 54, 159, 173, 322, +208, 366, 147, 289, 37, 105, -65, -147, +-117, -361, -93, -422, -31, -300, 27, -64, +69, 186, 91, 371, 84, 423, 61, 312, +45, 71, 1, -217, -79, -435, -133, -465, +-128, -300, -50, -34, 74, 241, 173, 450, +176, 497, 98, 350, -25, 62, -170, -289, +-238, -551, -176, -572, -38, -358, 97, -24, +199, 349, 218, 627, 129, 642, -2, 364, +-143, -78, -261, -515, -268, -750, -149, -644, +28, -259, 200, 220, 302, 623, 243, 783, +59, 589, -130, 136, -276, -374, -325, -734, +-225, -778, -29, -476, 143, 15, 238, 486, +253, 770, 182, 736, 64, 381, -88, -145, +-248, -615, -340, -825, -306, -675, -133, -237, +125, 287, 371, 698, 472, 833, 360, 605, +67, 102, -292, -440, -531, -791, -515, -809, +-242, -479, 147, 56, 461, 560, 563, 827, +415, 751, 110, 344, -220, -225, -432, -686, +-451, -838, -295, -633, -25, -163, 258, 372, +455, 746, 481, 793, 333, 496, 51, -20, +-280, -517, -500, -765, -488, -674, -237, -318, +145, 150, 486, 553, 614, 722, 443, 580, +79, 194, -296, -257, -512, -574, -474, -647, +-207, -486, 148, -150, 403, 267, 469, 593, +340, 669, 92, 470, -160, 80, -334, -349, +-366, -628, -252, -655, -27, -442, 196, -41, +337, 425, 371, 720, 255, 686, 6, 362, +-262, -110, -408, -527, -379, -710, -189, -615, +93, -294, 327, 179, 418, 607, 325, 741, +90, 539, -189, 142, -393, -290, -434, -594, +-311, -648, -67, -461, 206, -101, 401, 332, +446, 618, 294, 587, -12, 325, -362, -16, +-584, -333, -555, -511, -268, -473, 151, -272, +507, 25, 640, 333, 460, 470, 36, 364, +-421, 150, -686, -59, -640, -249, -316, -354, +140, -311, 514, -147, 639, 72, 473, 256, +101, 306, -298, 213, -578, 74, -629, -66, +-407, -201, -3, -275, 393, -221, 604, -59, +566, 122, 283, 231, -139, 233, -528, 153, +-696, 30, -528, -107, -108, -222, 356, -254, +658, -168, 671, -3, 366, 144, -123, 218, +-533, 228, -688, 170, -520, 34, -93, -131, +370, -259, 640, -296, 610, -203, 318, -16, +-107, 162, -449, 272, -560, 311, -435, 229, +-113, 19, 274, -202, 515, -320, 498, -318, +292, -186, -8, 27, -304, 202, -444, 295, +-380, 308, -160, 188, 130, -45, 359, -230, +409, -286, 290, -259, 93, -147, -135, 49, +-308, 217, -341, 288, -241, 259, -53, 102, +160, -123, 318, -259, 332, -258, 214, -182, +33, -40, -170, 145, -330, 263, -371, 249, +-233, 127, 21, -60, 252, -215, 361, -242, +314, -169, 132, -61, -133, 77, -351, 211, +-409, 241, -276, 150, -19, 0, 210, -143, +308, -209, 253, -174, 87, -89, -115, 6, +-262, 111, -287, 183, -208, 171, -70, 91, +77, -5, 163, -81, 159, -120, 95, -146, +20, -159, -85, -117, -202, 5, -254, 160, +-201, 264, -64, 264, 100, 156, 228, -26, +240, -238, 134, -392, -55, -379, -274, -170, +-384, 144, -285, 408, -42, 491, 202, 346, +344, 47, 309, -264, 94, -474, -154, -496, +-316, -293, -346, 53, -220, 374, 16, 519, +217, 434, 275, 173, 218, -147, 79, -392, +-78, -472, -171, -360, -210, -99, -195, 213, +-98, 426, 59, 437, 167, 260, 206, -7, +205, -262, 128, -411, -18, -386, -172, -202, +-256, 62, -228, 310, -93, 429, 89, 352, +231, 128, 290, -140, 236, -362, 83, -442, +-111, -324, -270, -67, -306, 230, -198, 450, +-6, 460, 183, 257, 314, -40, 318, -317, +178, -483, -32, -430, -257, -179, -393, 132, +-327, 389, -92, 494, 173, 373, 358, 96, +399, -195, 244, -420, -46, -490, -331, -321, +-479, -1, -384, 299, -80, 471, 241, 440, +408, 196, 387, -127, 185, -376, -131, -468, +-384, -344, -448, -39, -311, 271, -36, 426, +233, 373, 343, 151, 261, -116, 82, -292, +-110, -341, -258, -251, -316, -41, -258, 172, +-98, 268, 80, 238, 189, 127, 194, -9, +129, -119, 31, -186, -111, -205, -246, -145, +-294, -10, -208, 119, -43, 192, 110, 202, +193, 136, 176, 20, 79, -106, -67, -223, +-200, -256, -249, -135, -199, 61, -67, 213, +69, 268, 145, 196, 136, 16, 73, -164, +-10, -267, -95, -265, -160, -102, -180, 169, +-119, 332, -7, 288, 87, 110, 122, -125, +112, -310, 80, -321, -18, -168, -148, 50, +-202, 271, -145, 378, -23, 251, 102, -19, +189, -235, 178, -323, 71, -266, -69, -80, +-188, 117, -219, 243, -135, 286, 29, 199, +182, -8, 238, -191, 165, -251, 14, -213, +-118, -102, -203, 52, -211, 182, -100, 240, +87, 208, 226, 68, 226, -122, 108, -241, +-51, -237, -163, -147, -190, -7, -141, 146, +-22, 258, 99, 276, 141, 164, 102, -40, +34, -228, -32, -315, -70, -286, -51, -143, +-43, 85, -74, 308, -82, 418, -39, 335, +29, 65, 75, -245, 84, -424, 43, -417, +-26, -227, -103, 84, -173, 363, -153, 459, +-40, 343, 67, 71, 101, -232, 76, -394, +8, -344, -69, -174, -102, 23, -117, 215, +-115, 308, -72, 242, -8, 87, 40, -71, +54, -181, 46, -194, 2, -127, -58, -45, +-130, 46, -198, 137, -177, 154, -58, 69, +92, -38, 176, -103, 150, -106, 38, -41, +-108, 43, -222, 81, -272, 84, -205, 55, +-41, -39, 107, -140, 174, -140, 155, -50, +71, 40, -36, 117, -115, 165, -174, 144, +-200, 79, -152, -9, -67, -145, 20, -260, +104, -249, 162, -127, 153, 32, 77, 208, +-46, 356, -186, 362, -260, 202, -231, -47, +-117, -309, 36, -471, 176, -411, 258, -173, +240, 120, 131, 386, -51, 522, -263, 435, +-368, 154, -306, -206, -124, -509, 116, -602, +333, -413, 426, -58, 313, 314, 32, 603, +-276, 666, -448, 409, -397, -44, -174, -474, +87, -722, 281, -670, 359, -315, 276, 167, +96, 582, -82, 789, -238, 673, -311, 253, +-268, -270, -156, -696, -19, -875, 160, -681, +319, -175, 322, 410, 173, 859, -58, 992, +-274, 701, -375, 79, -315, -600, -147, -1051, +30, -1073, 189, -629, 271, 95, 241, 785, +135, 1165, -22, 1063, -196, 500, -334, -267, +-374, -923, -298, -1209, -80, -987, 218, -347, +432, 427, 429, 1036, 182, 1238, -186, 920, +-482, 212, -567, -586, -429, -1158, -115, -1256, +256, -807, 477, -22, 450, 754, 214, 1223, +-103, 1184, -372, 656, -517, -114, -493, -825, +-293, -1209, 45, -1094, 369, -543, 511, 209, +437, 881, 144, 1207, -277, 1031, -574, 451, +-617, -278, -443, -921, -76, -1228, 347, -1013, +565, -392, 498, 358, 246, 992, -107, 1244, +-433, 975, -576, 339, -520, -396, -313, -992, +45, -1214, 417, -954, 572, -342, 489, 388, +235, 999, -161, 1244, -548, 994, -697, 376, +-551, -386, -200, -1046, 253, -1334, 598, -1078, +655, -364, 432, 524, 51, 1214, -341, 1411, +-622, 1039, -662, 259, -438, -629, -38, -1288, +401, -1438, 664, -1010, 611, -165, 282, 751, +-134, 1342, -494, 1392, -658, 921, -513, 83, +-146, -799, 221, -1344, 438, -1349, 459, -810, +270, 70, -2, 909, -207, 1332, -334, 1223, +-372, 667, -272, -154, -51, -926, 143, -1290, +244, -1128, 274, -548, 172, 252, -29, 942, +-209, 1223, -310, 1046, -287, 500, -116, -264, +97, -934, 183, -1196, 134, -972, 45, -390, +-71, 334, -181, 914, -175, 1111, -82, 885, +-17, 335, 33, -337, 70, -861, 21, -1038, +-59, -833, -81, -336, -102, 277, -149, 798, +-135, 1032, -50, 900, 42, 449, 123, -195, +139, -802, 17, -1113, -157, -994, -251, -499, +-259, 192, -212, 842, -43, 1184, 177, 1028, +262, 467, 184, -235, 8, -848, -193, -1132, +-334, -954, -327, -417, -215, 258, -68, 829, +135, 1060, 306, 880, 308, 395, 133, -222, +-100, -778, -316, -1029, -473, -856, -436, -388, +-159, 197, 191, 728, 424, 983, 471, 855, +263, 445, -124, -112, -455, -663, -582, -974, +-460, -892, -133, -486, 249, 93, 465, 675, +433, 1012, 255, 952, -64, 538, -388, -100, +-491, -752, -402, -1116, -242, -1007, 44, -476, +356, 252, 448, 894, 330, 1185, 111, 974, +-205, 358, -478, -381, -502, -960, -309, -1121, +-30, -783, 269, -169, 442, 435, 349, 842, +96, 914, -131, 603, -287, 77, -339, -395, +-254, -669, -123, -683, -13, -423, 106, -43, +206, 276, 212, 496, 122, 545, -3, 353, +-144, 72, -294, -137, -346, -302, -230, -407, +-34, -354, 138, -210, 238, -46, 228, 189, +106, 407, -44, 441, -178, 345, -303, 170, +-314, -137, -197, -448, -51, -553, 93, -437, +216, -159, 232, 235, 72, 546, -128, 573, +-245, 383, -289, 99, -224, -266, -26, -542, +105, -545, 74, -343, 22, -39, -38, 293, +-114, 500, -121, 486, -58, 313, -29, 59, +-62, -219, -70, -407, -83, -410, -92, -270, +-24, -65, 37, 143, -21, 267, -112, 279, +-131, 228, -110, 140, -28, 23, 86, -93, +87, -184, -21, -248, -130, -267, -199, -178, +-219, 12, -131, 213, 27, 347, 115, 382, +91, 276, 27, 15, -52, -280, -134, -448, +-116, -448, -55, -302, -62, -4, -90, 306, +-63, 486, -27, 526, -32, 398, -28, 72, +6, -304, 13, -549, -11, -606, -23, -459, +-44, -127, -92, 270, -124, 567, -111, 707, +-89, 621, -28, 248, 95, -245, 136, -640, +66, -847, -35, -757, -179, -321, -292, 266, +-240, 750, -70, 988, 64, 875, 155, 370, +208, -299, 109, -809, -70, -1009, -152, -864, +-216, -386, -277, 260, -164, 793, 3, 1018, +58, 880, 108, 417, 145, -212, 49, -732, +-120, -976, -195, -902, -209, -482, -181, 169, +-59, 750, 77, 1039, 137, 966, 113, 522, +21, -158, -158, -779, -310, -1080, -288, -1015, +-146, -563, 12, 178, 159, 836, 244, 1137, +158, 1066, -73, 595, -280, -174, -383, -852, +-367, -1162, -193, -1080, 77, -595, 249, 193, +294, 896, 228, 1206, 8, 1100, -270, 594, +-436, -190, -456, -869, -364, -1184, -111, -1118, +198, -647, 347, 121, 347, 843, 225, 1225, +-63, 1197, -378, 748, -505, -12, -440, -754, +-265, -1201, -4, -1257, 240, -862, 290, -107, +206, 699, 119, 1244, -66, 1329, -280, 927, +-366, 181, -366, -650, -304, -1242, -101, -1369, +155, -993, 302, -203, 328, 708, 204, 1339, +-102, 1467, -404, 1054, -464, 214, -336, -763, +-165, -1446, 51, -1575, 219, -1132, 206, -200, +78, 912, -9, 1643, -52, 1699, -100, 1143, +-164, 107, -263, -1041, -307, -1736, -222, -1711, +-37, -1061, 164, 30, 286, 1155, 287, 1772, +101, 1680, -182, 996, -360, -107, -377, -1196, +-309, -1754, -186, -1656, 2, -974, 165, 145, +243, 1253, 245, 1821, 182, 1685, -13, 944, +-298, -174, -507, -1229, -527, -1766, -344, -1661, +-4, -968, 361, 157, 507, 1231, 385, 1777, +120, 1663, -258, 952, -562, -141, -593, -1193, +-432, -1793, -177, -1701, 141, -944, 399, 192, +473, 1278, 362, 1872, 94, 1722, -301, 899, +-645, -253, -722, -1320, -550, -1894, -166, -1713, +347, -857, 665, 305, 615, 1361, 304, 1881, +-160, 1624, -611, 798, -792, -257, -660, -1259, +-363, -1796, 41, -1563, 429, -749, 634, 281, +570, 1227, 276, 1701, -179, 1448, -668, 697, +-954, -255, -846, -1198, -400, -1650, 192, -1336, +741, -562, 942, 360, 661, 1227, 47, 1609, +-611, 1269, -1031, 454, -1052, -496, -639, -1303, +-2, -1568, 566, -1106, 885, -223, 826, 713, +370, 1409, -268, 1513, -785, 946, -1029, 26, +-919, -929, -439, -1558, 203, -1485, 708, -728, +913, 300, 746, 1210, 210, 1688, -454, 1440, +-951, 537, -1084, -560, -808, -1411, -252, -1737, +393, -1353, 835, -383, 936, 754, 651, 1571, +38, 1753, -590, 1271, -991, 305, -1080, -792, +-778, -1608, -155, -1807, 494, -1279, 939, -219, +993, 921, 592, 1706, -83, 1821, -737, 1202, +-1144, 122, -1145, -973, -653, -1667, 113, -1720, +736, -1114, 983, -57, 838, 1000, 344, 1601, +-332, 1581, -859, 990, -1043, 50, -855, -869, +-357, -1425, 234, -1433, 667, -886, 781, -16, +534, 771, 59, 1179, -427, 1146, -739, 742, +-760, 108, -489, -490, -37, -836, 353, -844, +458, -562, 324, -164, 44, 186, -289, 423, +-495, 507, -466, 421, -223, 244, 85, 80, +320, -26, 333, -106, 110, -168, -226, -233, +-513, -296, -596, -298, -433, -239, -130, -102, +235, 145, 560, 375, 577, 479, 251, 514, +-208, 419, -602, 122, -812, -237, -775, -489, +-434, -636, 101, -664, 564, -478, 730, -109, +546, 325, 160, 734, -294, 962, -691, 849, +-850, 448, -689, -119, -295, -691, 181, -1024, +545, -989, 608, -667, 384, -161, -15, 427, +-449, 892, -692, 1059, -634, 893, -367, 443, +1, -161, 373, -689, 507, -995, 327, -965, +-33, -552, -378, 76, -573, 645, -569, 943, +-363, 832, -40, 376, 313, -181, 517, -642, +406, -837, 57, -644, -307, -122, -559, 471, +-611, 874, -431, 897, -115, 472, 184, -204, +350, -803, 325, -1141, 113, -1054, -133, -433, +-301, 452, -385, 1195, -310, 1496, -135, 1177, +-5, 358, 67, -535, 62, -1235, -48, -1589, +-180, -1307, -213, -415, -147, 572, -47, 1253, +66, 1493, 112, 1141, -13, 342, -187, -482, +-254, -1078, -257, -1245, -164, -808, -16, -22, +46, 650, 14, 984, -65, 866, -150, 288, +-197, -412, -148, -857, -74, -984, -12, -684, +19, 84, -10, 902, -78, 1320, -136, 1232, +-141, 609, -147, -340, -181, -1146, -166, -1572, +-100, -1482, -26, -740, 54, 397, 63, 1334, +-62, 1748, -218, 1554, -306, 729, -285, -421, +-171, -1348, -14, -1749, 148, -1505, 232, -593, +197, 605, 47, 1545, -149, 1878, -306, 1444, +-467, 347, -610, -925, -596, -1840, -353, -2059, +41, -1439, 482, -184, 791, 1178, 737, 2131, +336, 2308, -194, 1543, -682, 187, -995, -1168, +-986, -2107, -694, -2325, -203, -1664, 306, -387, +650, 1029, 799, 2086, 664, 2309, 208, 1584, +-375, 290, -819, -1028, -982, -1924, -813, -2027, +-333, -1278, 266, -66, 661, 1127, 709, 1916, +489, 1901, 44, 1032, -489, -206, -856, -1298, +-916, -1899, -663, -1779, -201, -942, 305, 268, +690, 1379, 812, 1948, 559, 1738, 11, 844, +-571, -330, -939, -1294, -942, -1676, -631, -1371, +-102, -574, 461, 389, 723, 1128, 591, 1344, +188, 985, -338, 233, -776, -594, -871, -1130, +-565, -1159, -29, -707, 473, 69, 758, 913, +696, 1442, 216, 1344, -445, 702, -994, -209, +-1176, -1146, -855, -1736, -189, -1619, 505, -877, +987, 166, 1083, 1180, 647, 1806, -165, 1779, +-893, 1109, -1266, 56, -1237, -1011, -765, -1700, +15, -1754, 732, -1186, 1095, -201, 1035, 901, +611, 1666, -70, 1731, -803, 1148, -1317, 210, +-1372, -816, -911, -1610, -197, -1783, 487, -1241, +999, -262, 1112, 805, 750, 1650, 150, 1916, +-440, 1474, -932, 546, -1151, -548, -934, -1527, +-406, -2031, 132, -1766, 508, -862, 697, 299, +578, 1331, 172, 1854, -271, 1688, -561, 1016, +-686, 71, -578, -876, -252, -1441, 75, -1438, +292, -951, 404, -172, 384, 601, 154, 1045, +-236, 1066, -601, 737, -796, 155, -691, -497, +-328, -882, 83, -862, 432, -549, 658, -37, +624, 536, 287, 937, -189, 1003, -602, 690, +-855, 80, -901, -569, -651, -1053, -193, -1250, +279, -1014, 680, -342, 878, 469, 715, 1136, +181, 1490, -486, 1317, -986, 647, -1181, -194, +-990, -953, -464, -1442, 220, -1412, 808, -851, +1052, -14, 853, 785, 341, 1255, -339, 1205, +-954, 730, -1176, 74, -967, -578, -517, -978, +40, -885, 594, -386, 885, 203, 735, 650, +263, 734, -289, 432, -734, -23, -938, -460, +-775, -733, -293, -614, 264, -152, 629, 360, +646, 765, 371, 905, -83, 594, -576, -40, +-854, -622, -774, -962, -415, -955, 48, -535, +415, 127, 577, 759, 516, 1158, 216, 1097, +-196, 525, -521, -221, -699, -837, -704, -1210, +-480, -1174, -29, -639, 396, 131, 592, 853, +558, 1351, 254, 1371, -302, 846, -815, 31, +-962, -801, -734, -1380, -211, -1419, 448, -962, +874, -215, 828, 630, 461, 1259, -94, 1375, +-734, 994, -1163, 320, -1194, -418, -818, -953, +-116, -1110, 678, -891, 1215, -384, 1228, 271, +740, 764, -101, 894, -1034, 699, -1591, 272, +-1475, -222, -808, -533, 119, -600, 961, -492, +1337, -200, 1113, 147, 437, 359, -409, 424, +-1107, 379, -1413, 159, -1178, -101, -481, -206, +385, -194, 1061, -120, 1243, 39, 841, 143, +56, 68, -819, -89, -1455, -255, -1464, -385, +-894, -328, -47, 2, 841, 415, 1433, 738, +1384, 908, 694, 735, -287, 147, -1158, -542, +-1645, -1048, -1552, -1319, -873, -1196, 66, -587, +909, 305, 1383, 1145, 1268, 1663, 641, 1646, +-195, 1049, -920, 68, -1308, -940, -1231, -1630, +-703, -1783, 23, -1338, 629, -455, 932, 562, +812, 1351, 270, 1655, -399, 1424, -829, 764, +-924, -141, -690, -966, -155, -1397, 430, -1347, +732, -877, 667, -118, 295, 669, -267, 1162, +-761, 1223, -961, 866, -801, 263, -395, -342, +142, -803, 639, -1029, 860, -912, 719, -487, +299, 72, -260, 579, -790, 877, -1087, 899, +-1053, 652, -672, 215, -48, -281, 569, -670, +954, -824, 1012, -709, 721, -390, 133, 34, +-528, 435, -992, 689, -1158, 762, -1059, 604, +-701, 214, -132, -270, 465, -673, 933, -884, +1086, -766, 822, -303, 308, 308, -256, 832, +-726, 1106, -971, 974, -941, 407, -721, -356, +-439, -1009, -72, -1370, 323, -1309, 556, -694, +623, 293, 643, 1182, 474, 1655, 66, 1638, +-371, 1069, -685, 67, -840, -952, -813, -1661, +-576, -1879, -253, -1481, 83, -579, 419, 449, +626, 1309, 607, 1806, 418, 1764, 117, 1177, +-241, 296, -532, -627, -707, -1393, -739, -1715, +-555, -1508, -178, -939, 208, -148, 409, 709, +422, 1332, 306, 1559, 68, 1355, -224, 739, +-409, -60, -392, -763, -201, -1246, 58, -1368, +202, -1002, 139, -316, -63, 385, -305, 907, +-494, 1097, -543, 861, -376, 343, -95, -213, +193, -662, 480, -857, 626, -658, 487, -142, +167, 436, -169, 859, -495, 916, -733, 527, +-796, -122, -659, -743, -375, -1152, -35, -1145, +239, -636, 390, 163, 496, 904, 542, 1319, +466, 1308, 293, 879, 17, 159, -377, -584, +-775, -1103, -1001, -1298, -1005, -1068, -758, -462, +-223, 201, 398, 688, 806, 947, 971, 891, +920, 521, 559, 114, -25, -141, -613, -317, +-1050, -420, -1219, -338, -975, -202, -347, -183, +327, -179, 799, -70, 980, 86, 744, 250, +161, 383, -459, 379, -893, 265, -1033, 103, +-784, -150, -243, -424, 379, -530, 846, -446, +994, -191, 767, 224, 199, 624, -527, 797, +-1141, 694, -1373, 351, -1085, -195, -423, -763, +288, -1090, 888, -1056, 1212, -697, 1041, -46, +458, 706, -270, 1232, -888, 1384, -1187, 1149, +-1061, 534, -541, -285, 132, -1007, 674, -1422, +911, -1389, 730, -914, 164, -192, -529, 514, +-1050, 1022, -1132, 1214, -698, 1049, 14, 617, +715, 76, 1175, -432, 1191, -761, 670, -812, +-243, -675, -1136, -452, -1628, -127, -1520, 226, +-843, 462, 124, 602, 973, 652, 1453, 519, +1438, 250, 833, -76, -169, -484, -1089, -861, +-1543, -956, -1463, -680, -883, -100, 3, 601, +840, 1155, 1317, 1334, 1269, 1058, 713, 360, +-155, -565, -950, -1324, -1359, -1623, -1302, -1429, +-824, -763, -93, 289, 607, 1298, 1035, 1803, +1090, 1708, 745, 1094, 145, 108, -424, -922, +-775, -1636, -892, -1787, -809, -1299, -507, -359, +-72, 670, 287, 1404, 466, 1585, 460, 1207, +287, 435, 55, -528, -136, -1313, -298, -1509, +-336, -1049, -180, -182, 33, 783, 166, 1481, +177, 1545, 84, 948, -142, 5, -420, -965, +-575, -1677, -584, -1758, -455, -1105, -91, -36, +421, 1038, 826, 1758, 952, 1836, 734, 1272, +264, 321, -330, -726, -919, -1485, -1283, -1650, +-1252, -1241, -837, -486, -212, 351, 479, 971, +1106, 1137, 1378, 865, 1107, 393, 471, -61, +-278, -404, -988, -512, -1403, -325, -1301, -8, +-747, 218, -3, 249, 676, 38, 1072, -337, +1009, -607, 551, -563, -74, -232, -673, 245, +-1050, 742, -1003, 1039, -557, 898, 56, 359, +646, -292, 1000, -844, 932, -1112, 447, -912, +-231, -344, -880, 253, -1333, 654, -1332, 823, +-786, 727, 44, 364, 834, -131, 1385, -504, +1490, -606, 1046, -448, 231, -125, -689, 215, +-1486, 438, -1869, 470, -1613, 276, -854, -68, +92, -362, 1000, -501, 1644, -472, 1803, -232, +1395, 164, 545, 517, -491, 690, -1405, 651, +-1898, 401, -1849, -44, -1299, -573, -396, -957, +578, -1011, 1350, -697, 1731, -102, 1580, 590, +957, 1128, 136, 1332, -659, 1115, -1301, 521, +-1642, -272, -1531, -1022, -1024, -1511, -303, -1593, +507, -1200, 1170, -393, 1462, 575, 1378, 1410, +947, 1950, 214, 2018, -586, 1434, -1216, 318, +-1558, -962, -1516, -2047, -1057, -2616, -288, -2415, +573, -1421, 1319, 112, 1726, 1704, 1534, 2836, +787, 3140, -152, 2443, -1017, 897, -1645, -963, +-1795, -2545, -1375, -3388, -569, -3153, 354, -1830, +1190, 110, 1721, 1996, 1675, 3281, 1058, 3527, +121, 2553, -889, 691, -1668, -1375, -1902, -2984, +-1506, -3588, -623, -2933, 451, -1298, 1314, 740, +1676, 2527, 1463, 3421, 778, 3149, -151, 1884, +-1004, -3, -1476, -1897, -1498, -3064, -1043, -3164, +-179, -2311, 684, -778, 1144, 994, 1185, 2402, +902, 2999, 256, 2661, -559, 1528, -1096, -34, +-1147, -1502, -843, -2440, -312, -2644, 351, -2119, +861, -981, 956, 504, 663, 1860, 179, 2556, +-370, 2391, -851, 1534, -1017, 234, -751, -1170, +-223, -2159, 253, -2370, 583, -1785, 790, -602, +708, 741, 268, 1713, -249, 2027, -586, 1643, +-733, 736, -671, -303, -362, -1150, 41, -1621, +317, -1484, 417, -753, 387, 138, 165, 795, +-162, 1120, -317, 1065, -239, 646, -71, 77, +126, -430, 265, -741, 210, -711, -27, -382, +-328, -8, -574, 292, -656, 474, -466, 374, +-67, 42, 352, -237, 726, -373, 940, -382, +769, -179, 240, 201, -392, 564, -915, 748, +-1189, 625, -1091, 214, -572, -264, 187, -679, +811, -972, 1104, -986, 1005, -647, 542, -82, +-104, 546, -699, 1077, -1006, 1300, -917, 1121, +-518, 633, 39, -34, 567, -724, 819, -1216, +678, -1391, 254, -1217, -281, -656, -714, 125, +-818, 790, -524, 1220, -18, 1400, 439, 1201, +685, 629, 623, -90, 279, -746, -171, -1157, +-536, -1208, -720, -954, -664, -517, -350, 2, +104, 474, 525, 776, 742, 882, 666, 822, +313, 604, -187, 274, -662, -64, -953, -344, +-886, -583, -438, -782, 172, -840, 660, -680, +891, -368, 828, 10, 448, 490, -121, 1018, +-583, 1313, -788, 1194, -822, 747, -665, 35, +-255, -858, 221, -1602, 499, -1869, 584, -1523, +566, -630, 383, 520, 70, 1556, -195, 2190, +-338, 2166, -403, 1345, -452, -1, -478, -1340, +-419, -2223, -246, -2388, 37, -1741, 377, -510, +640, 839, 735, 1867, 624, 2233, 295, 1802, +-181, 830, -704, -261, -1088, -1180, -1142, -1633, +-851, -1459, -285, -872, 416, -176, 1041, 483, +1407, 902, 1389, 902, 896, 603, -6, 267, +-995, 15, -1670, -165, -1830, -268, -1509, -285, +-740, -248, 353, -204, 1430, -158, 2058, -94, +2004, 23, 1342, 195, 273, 311, -952, 273, +-1948, 139, -2331, -15, -1985, -200, -1022, -353, +258, -331, 1450, -117, 2194, 149, 2213, 394, +1515, 552, 398, 464, -831, 142, -1851, -231, +-2294, -587, -1975, -812, -1037, -689, 168, -291, +1274, 162, 1995, 618, 2109, 976, 1554, 996, +500, 660, -734, 147, -1744, -427, -2201, -955, +-1973, -1264, -1129, -1220, 59, -759, 1218, 32, +1989, 857, 2161, 1454, 1633, 1706, 513, 1471, +-776, 693, -1748, -379, -2176, -1408, -1973, -2116, +-1128, -2179, 114, -1497, 1285, -353, 2013, 952, +2100, 2126, 1453, 2660, 274, 2289, -971, 1241, +-1871, -166, -2156, -1601, -1705, -2553, -668, -2668, +567, -1995, 1574, -780, 2034, 640, 1787, 1829, +920, 2437, -234, 2355, -1280, 1599, -1913, 371, +-1935, -867, -1328, -1718, -288, -2073, 830, -1871, +1605, -1098, 1789, -29, 1403, 922, 600, 1505, +-363, 1640, -1144, 1283, -1490, 535, -1346, -331, +-814, -1020, -113, -1326, 509, -1108, 846, -455, +881, 281, 700, 826, 329, 1073, -99, 865, +-390, 202, -485, -520, -434, -948, -302, -1042, +-159, -775, -24, -108, 81, 687, 132, 1209, +119, 1317, 54, 1012, -1, 282, -28, -662, +-34, -1375, -9, -1604, 44, -1316, 122, -567, +163, 410, 63, 1241, -143, 1649, -308, 1485, +-335, 816, -263, -66, -154, -841, 26, -1291, +253, -1310, 388, -917, 379, -277, 283, 371, +95, 781, -170, 858, -409, 680, -545, 368, +-549, 14, -369, -247, -34, -280, 312, -139, +550, -19, 625, -38, 514, -153, 233, -280, +-85, -378, -341, -455, -544, -393, -683, -31, +-642, 499, -372, 870, 5, 1002, 328, 927, +528, 544, 628, -112, 622, -817, 457, -1345, +134, -1488, -221, -1127, -517, -416, -738, 395, +-829, 1104, -724, 1492, -399, 1420, 107, 955, +649, 259, 1007, -491, 1016, -1007, 700, -1125, +168, -964, -429, -653, -873, -201, -1051, 221, +-935, 431, -540, 486, 4, 493, 529, 473, +880, 442, 936, 375, 708, 227, 271, 30, +-294, -206, -780, -496, -996, -737, -861, -775, +-442, -590, 89, -268, 540, 90, 785, 441, +803, 745, 582, 873, 131, 731, -390, 397, +-741, 41, -844, -284, -717, -547, -381, -669, +109, -631, 598, -525, 878, -339, 844, -15, +529, 312, -1, 509, -607, 628, -1010, 690, +-1020, 543, -689, 155, -171, -274, 445, -553, +1010, -690, 1228, -659, 951, -365, 362, 78, +-322, 438, -941, 636, -1288, 611, -1258, 283, +-868, -191, -203, -564, 568, -725, 1192, -607, +1459, -143, 1277, 476, 722, 915, -7, 1011, +-706, 761, -1220, 174, -1391, -586, -1155, -1173, +-684, -1371, -150, -1129, 404, -474, 898, 405, +1161, 1146, 1143, 1503, 910, 1417, 488, 895, +-70, 42, -600, -826, -1005, -1341, -1259, -1370, +-1267, -982, -954, -325, -364, 376, 322, 845, +958, 979, 1467, 785, 1638, 310, 1255, -224, +434, -528, -490, -539, -1271, -337, -1718, 47, +-1630, 477, -998, 707, -94, 584, 770, 146, +1329, -482, 1436, -1053, 1102, -1293, 420, -1093, +-427, -489, -1085, 419, -1274, 1347, -987, 1914, +-365, 1925, 372, 1339, 951, 255, 1132, -983, +856, -1929, 247, -2356, -474, -2155, -1064, -1291, +-1295, 1, -1094, 1230, -548, 1987, 233, 2161, +1022, 1800, 1537, 1040, 1587, 87, 1107, -789, +236, -1358, -725, -1480, -1510, -1242, -1876, -847, +-1691, -409, -1060, 5, -180, 279, 760, 398, +1480, 500, 1769, 661, 1699, 863, 1296, 1044, +476, 1121, -531, 932, -1315, 352, -1752, -555, +-1837, -1514, -1532, -2214, -884, -2439, -44, -2068, +802, -1055, 1496, 458, 1898, 2035, 1901, 3167, +1460, 3502, 641, 2909, -395, 1475, -1354, -436, +-1950, -2316, -2093, -3628, -1808, -3952, -1106, -3213, +-123, -1671, 832, 285, 1582, 2165, 2080, 3400, +2171, 3706, 1652, 3162, 675, 1932, -365, 195, +-1312, -1585, -2087, -2828, -2333, -3284, -1870, -3003, +-1032, -2054, -139, -603, 780, 922, 1650, 2103, +2180, 2707, 2145, 2657, 1596, 1972, 722, 870, +-394, -313, -1559, -1303, -2321, -1963, -2411, -2172, +-1913, -1851, -924, -1116, 413, -192, 1647, 714, +2345, 1445, 2397, 1804, 1821, 1684, 658, 1144, +-718, 352, -1786, -526, -2260, -1226, -2063, -1504, +-1281, -1344, -209, -854, 817, -160, 1573, 537, +1859, 1005, 1575, 1165, 889, 1010, 77, 585, +-725, 19, -1330, -526, -1535, -928, -1342, -1071, +-868, -901, -238, -508, 437, -19, 1039, 497, +1372, 959, 1345, 1195, 1100, 1110, 647, 738, +-95, 206, -943, -391, -1566, -982, -1790, -1428, +-1544, -1548, -836, -1284, 120, -726, 1014, 55, +1614, 928, 1807, 1664, 1524, 2091, 815, 2125, +-49, 1616, -767, 551, -1276, -772, -1533, -1971, +-1374, -2803, -842, -3043, -257, -2480, 199, -1184, +588, 504, 859, 2162, 902, 3377, 837, 3746, +839, 3138, 771, 1697, 474, -275, 50, -2252, +-470, -3555, -1164, -3879, -1778, -3287, -1952, -1834, +-1649, 197, -866, 2048, 337, 3080, 1621, 3252, +2585, 2689, 2963, 1509, 2523, 66, 1278, -1175, +-391, -1945, -2000, -2113, -3088, -1728, -3333, -1122, +-2730, -524, -1459, 42, 202, 493, 1765, 714, +2819, 813, 3203, 915, 2847, 999, 1790, 991, +318, 825, -1150, 433, -2298, -146, -2935, -782, +-2904, -1362, -2189, -1703, -1007, -1611, 407, -1066, +1740, -254, 2626, 671, 2891, 1510, 2544, 1975, +1591, 1889, 170, 1295, -1285, 349, -2353, -724, +-2857, -1585, -2707, -1955, -1829, -1743, -430, -1049, +1015, -39, 2091, 992, 2623, 1656, 2458, 1702, +1592, 1176, 368, 288, -805, -653, -1718, -1291, +-2152, -1414, -1888, -1020, -1113, -253, -199, 600, +639, 1128, 1227, 1142, 1380, 752, 1100, 129, +523, -539, -117, -927, -529, -862, -591, -501, +-419, 8, -162, 530, 113, 774, 239, 562, +62, 99, -287, -398, -555, -758, -617, -735, +-412, -271, 10, 351, 494, 878, 902, 1187, +1109, 1079, 984, 464, 515, -441, -156, -1236, +-879, -1625, -1385, -1513, -1461, -990, -1150, -168, +-528, 763, 341, 1481, 1142, 1756, 1553, 1598, +1519, 1076, 1095, 295, 386, -493, -417, -1133, +-1074, -1570, -1427, -1676, -1422, -1384, -1043, -843, +-346, -148, 435, 619, 1003, 1257, 1217, 1637, +1101, 1716, 740, 1401, 229, 717, -315, -79, +-721, -837, -801, -1452, -621, -1715, -392, -1507, +-158, -983, 153, -320, 396, 342, 337, 847, +53, 1091, -143, 1054, -130, 827, -23, 551, +204, 335, 579, 181, 832, 83, 688, -61, +184, -364, -513, -770, -1155, -1169, -1467, -1509, +-1385, -1557, -889, -1050, 36, -107, 1104, 1045, +1873, 2198, 2138, 2888, 1829, 2664, 943, 1643, +-343, 154, -1648, -1520, -2559, -2885, -2690, -3385, +-1926, -2865, -571, -1526, 932, 225, 2151, 1792, +2717, 2725, 2473, 2846, 1537, 2153, 189, 863, +-1162, -516, -2108, -1513, -2408, -1895, -2023, -1657, +-1059, -1000, 184, -173, 1228, 581, 1770, 962, +1766, 818, 1238, 425, 331, 34, -523, -333, +-966, -576, -986, -493, -705, -117, -211, 376, +294, 774, 520, 853, 368, 625, 3, 233, +-378, -321, -680, -940, -728, -1246, -377, -1108, +269, -695, 946, -79, 1415, 680, 1464, 1249, +987, 1390, 120, 1169, -878, 640, -1740, -156, +-2152, -1000, -1892, -1555, -1085, -1586, 12, -1036, +1186, -125, 2144, 858, 2526, 1661, 2212, 1973, +1317, 1536, 17, 463, -1344, -840, -2318, -1952, +-2639, -2471, -2247, -2121, -1240, -967, 49, 547, +1226, 1910, 1991, 2702, 2194, 2658, 1855, 1717, +1115, 201, 194, -1305, -652, -2318, -1213, -2575, +-1410, -2021, -1290, -895, -944, 320, -503, 1256, +-105, 1694, 220, 1514, 441, 852, 570, 123, +716, -375, 893, -529, 961, -272, 832, 206, +533, 496, 86, 413, -481, 27, -1046, -609, +-1391, -1286, -1449, -1658, -1275, -1517, -831, -844, +-68, 256, 807, 1424, 1493, 2228, 1872, 2464, +1904, 2084, 1531, 1158, 754, -67, -264, -1253, +-1242, -2141, -1904, -2472, -2111, -2194, -1886, -1545, +-1311, -756, -419, 130, 633, 1017, 1493, 1710, +1943, 2101, 2005, 2146, 1701, 1874, 1033, 1325, +204, 480, -587, -626, -1266, -1686, -1702, -2423, +-1779, -2749, -1582, -2549, -1145, -1742, -412, -537, +464, 775, 1219, 2027, 1720, 2929, 1919, 3148, +1728, 2623, 1182, 1593, 403, 281, -475, -1119, +-1292, -2337, -1858, -3017, -2012, -2944, -1681, -2217, +-963, -1080, -52, 233, 860, 1411, 1545, 2092, +1839, 2216, 1680, 1896, 1128, 1236, 350, 471, +-427, -104, -1006, -483, -1256, -752, -1156, -860, +-782, -875, -269, -964, 222, -1073, 529, -1047, +544, -880, 320, -510, 5, 113, -210, 864, +-186, 1564, 57, 2064, 360, 2159, 607, 1747, +739, 931, 647, -160, 276, -1312, -239, -2203, +-699, -2649, -1032, -2615, -1185, -1993, -1077, -864, +-686, 431, -106, 1606, 545, 2484, 1109, 2843, +1440, 2579, 1513, 1779, 1297, 603, 763, -652, +22, -1671, -731, -2307, -1379, -2500, -1768, -2147, +-1760, -1314, -1343, -259, -618, 698, 278, 1331, +1107, 1600, 1632, 1551, 1784, 1202, 1575, 674, +1055, 272, 371, 92, -281, -19, -798, -169, +-1185, -381, -1420, -720, -1375, -1121, -1067, -1458, +-683, -1628, -262, -1434, 315, -726, 987, 341, +1472, 1457, 1692, 2387, 1711, 2833, 1436, 2585, +737, 1686, -267, 317, -1301, -1236, -2104, -2495, +-2492, -3099, -2334, -2986, -1555, -2210, -286, -937, +1120, 495, 2247, 1696, 2819, 2425, 2699, 2582, +1926, 2209, 697, 1425, -705, 452, -1922, -425, +-2580, -1057, -2518, -1495, -1854, -1724, -807, -1635, +385, -1332, 1432, -942, 1995, -408, 1949, 283, +1429, 936, 652, 1454, -178, 1807, -814, 1860, +-1093, 1501, -1030, 784, -687, -137, -202, -1059, +172, -1736, 285, -2020, 217, -1849, 72, -1277, +-120, -455, -300, 400, -246, 1091, 143, 1431, +598, 1424, 837, 1234, 877, 904, 738, 415, +283, -73, -394, -391, -959, -637, -1240, -903, +-1260, -1099, -979, -1150, -393, -1066, 351, -736, +1008, -109, 1429, 655, 1538, 1346, 1215, 1781, +522, 1782, -240, 1265, -895, 369, -1380, -667, +-1479, -1534, -1120, -1928, -514, -1713, 194, -1050, +913, -155, 1336, 801, 1252, 1528, 819, 1662, +238, 1143, -413, 299, -930, -535, -1018, -1147, +-664, -1332, -111, -925, 429, -100, 789, 740, +788, 1254, 459, 1277, -11, 807, -491, 3, +-827, -857, -871, -1483, -598, -1601, -102, -1134, +491, -264, 979, 682, 1192, 1441, 1058, 1765, +612, 1522, -24, 787, -674, -171, -1164, -1023, +-1325, -1531, -1104, -1561, -611, -1117, 27, -359, +659, 415, 1111, 994, 1278, 1264, 1174, 1149, +782, 654, 147, 0, -497, -572, -938, -935, +-1127, -975, -1011, -664, -559, -146, 16, 384, +446, 803, 643, 921, 670, 670, 497, 194, +132, -321, -191, -769, -257, -987, -142, -832, +9, -370, 220, 206, 452, 694, 468, 923, +183, 829, -194, 509, -576, 83, -911, -306, +-976, -533, -670, -544, -149, -388, 484, -192, +1124, -80, 1468, -64, 1317, -61, 757, -67, +20, -68, -684, 31, -1183, 287, -1339, 563, +-1062, 726, -488, 702, 133, 450, 632, 2, +885, -508, 827, -942, 526, -1185, 127, -1103, +-219, -688, -375, -93, -307, 478, -59, 935, +231, 1202, 447, 1193, 517, 877, 345, 388, +-101, -96, -625, -507, -994, -826, -1141, -997, +-958, -969, -386, -830, 402, -623, 1157, -300, +1719, 166, 1894, 667, 1521, 1113, 665, 1422, +-406, 1441, -1406, 1078, -2097, 404, -2264, -414, +-1806, -1221, -827, -1795, 340, -1951, 1382, -1595, +2053, -789, 2187, 265, 1786, 1243, 985, 1874, +-31, 2019, -929, 1615, -1453, 732, -1623, -330, +-1424, -1177, -845, -1591, -133, -1496, 390, -970, +691, -216, 815, 469, 729, 869, 516, 881, +381, 542, 339, 18, 259, -450, 160, -648, +51, -492, -198, -17, -566, 567, -810, 995, +-847, 1071, -739, 768, -461, 115, 0, -761, +500, -1509, 890, -1743, 1101, -1399, 1076, -655, +777, 336, 275, 1308, -256, 1892, -696, 1859, +-974, 1269, -998, 290, -723, -746, -321, -1426, +32, -1558, 343, -1240, 600, -611, 703, 155, +662, 760, 553, 985, 333, 805, 18, 360, +-259, -159, -417, -526, -491, -610, -467, -389, +-353, 38, -214, 480, -65, 747, 108, 738, +288, 433, 451, -109, 575, -666, 586, -989, +433, -958, 126, -666, -248, -216, -576, 308, +-765, 747, -755, 891, -491, 733, -56, 444, +377, 98, 753, -244, 966, -441, 873, -406, +544, -234, 113, -9, -417, 161, -876, 150, +-1013, -36, -824, -278, -471, -537, -4, -732, +491, -654, 789, -241, 820, 388, 706, 1058, +536, 1570, 254, 1683, -104, 1289, -380, 410, +-499, -752, -575, -1832, -641, -2456, -560, -2413, +-305, -1650, -8, -344, 237, 1046, 469, 2092, +699, 2558, 833, 2348, 779, 1494, 566, 306, +219, -801, -224, -1520, -643, -1747, -940, -1530, +-1034, -1021, -843, -440, -437, 18, 27, 250, +472, 318, 813, 330, 983, 418, 934, 645, +679, 974, 327, 1234, -19, 1246, -354, 869, +-621, 112, -685, -818, -578, -1699, -465, -2308, +-390, -2398, -275, -1801, -105, -664, 127, 694, +439, 1930, 797, 2723, 1086, 2851, 1152, 2289, +893, 1157, 341, -296, -362, -1635, -1038, -2487, +-1479, -2696, -1566, -2278, -1250, -1324, -551, -117, +374, 997, 1173, 1740, 1596, 1984, 1613, 1726, +1240, 1113, 514, 377, -356, -305, -974, -767, +-1150, -926, -1008, -820, -680, -611, -227, -402, +159, -223, 351, -105, 404, -108, 384, -146, +320, -45, 278, 212, 301, 505, 316, 736, +207, 871, -33, 804, -256, 469, -395, -60, +-470, -593, -442, -979, -226, -1084, 107, -873, +390, -434, 557, 80, 562, 513, 327, 757, +-61, 725, -384, 424, -588, -1, -630, -312, +-415, -417, 30, -331, 521, -83, 861, 287, +939, 608, 764, 696, 368, 504, -199, 69, +-747, -475, -1096, -940, -1175, -1179, -978, -1149, +-501, -782, 150, -118, 792, 650, 1268, 1268, +1463, 1569, 1318, 1469, 868, 1019, 195, 369, +-557, -390, -1161, -1073, -1498, -1409, -1518, -1310, +-1170, -1007, -525, -646, 227, -249, 973, 142, +1537, 461, 1646, 705, 1255, 900, 609, 1061, +-76, 1165, -692, 1081, -1061, 709, -1046, 64, +-742, -721, -371, -1464, -10, -1923, 272, -1953, +370, -1503, 289, -621, 132, 472, 2, 1447, +-26, 2041, 109, 2116, 377, 1636, 663, 797, +785, -127, 653, -915, 254, -1397, -363, -1456, +-1042, -1190, -1463, -767, -1423, -289, -986, 121, +-257, 359, 638, 438, 1436, 446, 1834, 438, +1718, 475, 1133, 519, 243, 528, -689, 497, +-1382, 401, -1634, 144, -1394, -262, -786, -692, +-21, -1053, 653, -1227, 1027, -1119, 1076, -744, +829, -187, 362, 513, -94, 1163, -346, 1505, +-442, 1438, -412, 1031, -208, 404, 93, -277, +287, -831, 267, -1141, 134, -1124, -17, -825, +-179, -401, -324, -25, -341, 231, -201, 327, +-3, 324, 181, 307, 373, 289, 515, 285, +496, 329, 354, 379, 161, 342, -93, 205, +-386, -27, -543, -277, -469, -462, -284, -552, +-133, -581, 76, -517, 337, -390, 430, -263, +347, -78, 241, 200, 112, 496, -65, 761, +-163, 977, -130, 978, -60, 719, -25, 303, +50, -227, 153, -828, 151, -1263, 31, -1364, +-52, -1179, -61, -757, -130, -138, -258, 528, +-262, 1052, -98, 1340, 57, 1312, 208, 993, +418, 493, 563, -50, 498, -541, 284, -892, +35, -1037, -215, -952, -443, -687, -587, -370, +-570, -36, -424, 292, -200, 537, 81, 622, +381, 610, 596, 518, 680, 341, 625, 146, +431, 2, 136, -100, -182, -167, -415, -197, +-527, -247, -516, -318, -402, -413, -210, -520, +9, -559, 187, -415, 262, -136, 276, 219, +257, 651, 189, 1040, 177, 1183, 283, 1025, +365, 659, 287, 98, 106, -594, -123, -1241, +-417, -1590, -711, -1515, -811, -1062, -651, -384, +-291, 402, 200, 1119, 675, 1508, 976, 1475, +1050, 1124, 876, 583, 454, -44, -70, -559, +-564, -887, -907, -1048, -1006, -1026, -835, -807, +-456, -500, 6, -149, 428, 262, 765, 628, +932, 846, 766, 916, 357, 838, -31, 527, +-286, 67, -460, -353, -484, -617, -294, -723, +-31, -620, 127, -315, 150, 17, 88, 184, +-10, 152, -101, 23, -129, -160, -22, -270, +153, -157, 286, 180, 353, 572, 347, 891, +244, 969, 88, 665, -106, 59, -336, -646, +-484, -1275, -450, -1575, -261, -1287, -47, -555, +143, 299, 343, 1075, 520, 1567, 490, 1508, +249, 936, 24, 109, -77, -710, -155, -1216, +-255, -1226, -234, -843, -57, -267, 96, 389, +77, 865, 13, 941, 3, 639, -36, 140, +-129, -386, -83, -736, 138, -798, 293, -596, +302, -184, 285, 303, 236, 689, 49, 843, +-172, 747, -286, 406, -294, -28, -264, -415, +-169, -708, 6, -849, 164, -722, 241, -370, +273, 20, 280, 352, 213, 581, 75, 677, +-71, 584, -134, 331, -119, 33, -78, -187, +-49, -358, -28, -461, 7, -399, 66, -201, +97, 6, 74, 162, 48, 244, 26, 198, +11, 103, -35, -8, -95, -172, -75, -300, +64, -230, 200, -71, 239, 60, 205, 246, +154, 473, 63, 573, -112, 488, -268, 275, +-314, -104, -250, -554, -123, -894, 29, -1010, +182, -883, 327, -461, 381, 168, 315, 769, +185, 1163, 28, 1281, -106, 1084, -181, 563, +-226, -110, -245, -724, -153, -1145, 6, -1293, +108, -1062, 126, -545, 143, 29, 168, 521, +149, 878, 92, 973, 19, 727, -30, 313, +-34, -65, -25, -306, -29, -395, -3, -300, +37, -103, 67, 89, 61, 154, 31, 39, +50, -187, 64, -400, -36, -510, -139, -474, +-116, -251, -84, 106, -83, 506, 5, 822, +216, 959, 391, 843, 398, 498, 275, -35, +122, -641, -46, -1083, -224, -1230, -331, -1086, +-353, -653, -316, 38, -219, 706, -59, 1097, +104, 1153, 253, 915, 401, 408, 499, -156, +473, -547, 352, -728, 189, -686, -8, -388, +-210, 10, -409, 225, -565, 228, -631, 120, +-555, -41, -308, -226, 100, -274, 522, -102, +807, 191, 906, 446, 797, 558, 488, 477, +56, 214, -340, -108, -606, -391, -742, -563, +-742, -563, -553, -365, -251, -117, 66, 75, +369, 232, 599, 337, 678, 307, 622, 185, +513, 106, 358, 69, 96, 30, -231, -28, +-470, -71, -622, -104, -702, -118, -602, -152, +-267, -179, 168, -129, 532, -24, 741, 51, +735, 79, 491, 93, 132, 75, -150, 56, +-329, 33, -407, 15, -329, 23, -80, 76, +168, 98, 221, 68, 133, 20, 58, -70, +-31, -180, -170, -209, -225, -147, -135, -121, +64, -96, 281, 3, 389, 121, 317, 145, +212, 130, 166, 149, 85, 168, -63, 134, +-168, 55, -217, -31, -320, -109, -404, -124, +-341, -116, -153, -139, 71, -185, 315, -172, +551, -138, 683, -109, 598, 4, 356, 215, +103, 372, -163, 406, -437, 387, -616, 243, +-627, -54, -476, -341, -193, -449, 127, -427, +410, -297, 561, -69, 525, 143, 364, 241, +168, 235, -18, 111, -114, -120, -62, -268, +27, -212, 56, 16, 39, 308, -10, 573, +-167, 670, -374, 523, -479, 133, -450, -413, +-323, -928, -62, -1210, 373, -1147, 868, -724, +1175, 10, 1120, 808, 785, 1412, 258, 1654, +-437, 1451, -1128, 757, -1515, -242, -1450, -1191, +-1013, -1774, -361, -1800, 414, -1258, 1163, -317, +1587, 682, 1579, 1416, 1212, 1637, 595, 1296, +-132, 511, -774, -415, -1184, -1107, -1295, -1295, +-1095, -956, -644, -252, -98, 564, 354, 1146, +683, 1249, 883, 808, 896, -9, 692, -916, +367, -1537, 47, -1624, -165, -1112, -274, -157, +-314, 906, -292, 1709, -250, 1999, -210, 1702, +-164, 863, -142, -271, -185, -1333, -161, -1961, +33, -2004, 276, -1499, 398, -632, 496, 379, +627, 1237, 611, 1662, 417, 1605, 148, 1161, +-190, 473, -550, -266, -760, -791, -779, -1015, +-661, -963, -437, -695, -81, -330, 332, -40, +649, 162, 836, 292, 921, 277, 825, 189, +510, 196, 130, 310, -226, 365, -561, 335, +-813, 255, -835, 118, -640, -109, -360, -349, +-79, -522, 186, -596, 401, -530, 547, -325, +622, -48, 616, 174, 575, 319, 468, 404, +274, 434, 33, 394, -252, 334, -587, 269, +-844, 202, -911, 101, -774, -115, -465, -454, +-53, -776, 429, -910, 906, -860, 1212, -592, +1187, -67, 899, 607, 502, 1139, 22, 1370, +-546, 1266, -1020, 833, -1230, 137, -1181, -658, +-884, -1284, -342, -1527, 321, -1329, 871, -838, +1184, -159, 1264, 592, 1098, 1192, 638, 1384, +40, 1150, -480, 635, -856, 16, -1031, -537, +-939, -898, -613, -976, -157, -744, 319, -296, +663, 126, 781, 394, 659, 492, 395, 438, +99, 250, -135, 28, -223, -145, -172, -248, +-59, -235, 53, -119, 106, 37, 42, 160, +-91, 250, -238, 270, -328, 198, -312, 12, +-161, -214, 100, -384, 395, -463, 615, -444, +669, -288, 542, 5, 256, 314, -100, 566, +-407, 705, -561, 664, -578, 408, -480, 40, +-260, -374, 40, -750, 302, -924, 466, -807, +541, -484, 534, -54, 439, 446, 218, 856, +-43, 998, -248, 825, -396, 472, -489, 8, +-481, -502, -353, -895, -65, -976, 310, -755, +587, -372, 693, 98, 605, 553, 309, 859, +-107, 919, -459, 733, -636, 279, -571, -284, +-273, -732, 122, -984, 420, -1006, 572, -663, +586, -5, 397, 661, 55, 1119, -241, 1252, +-379, 956, -441, 259, -421, -538, -219, -1171, +129, -1444, 368, -1230, 427, -566, 441, 293, +380, 1059, 144, 1493, -123, 1401, -266, 803, +-318, -57, -254, -829, -79, -1293, 100, -1308, +182, -862, 205, -108, 178, 613, 56, 1031, +-114, 1042, -221, 661, -217, 57, -89, -502, +153, -814, 398, -828, 556, -504, 553, 59, +369, 624, 40, 934, -369, 860, -734, 413, +-884, -220, -754, -787, -383, -1122, 158, -1088, +684, -613, 1023, 171, 1103, 884, 935, 1268, +520, 1240, -59, 815, -646, 80, -1033, -692, +-1106, -1202, -859, -1273, -379, -909, 150, -288, +594, 382, 865, 895, 891, 1096, 646, 870, +272, 344, -43, -226, -213, -630, -308, -805, +-329, -691, -218, -311, -60, 144, 25, 503, +18, 668, -43, 577, -147, 222, -225, -184, +-189, -476, 16, -613, 325, -555, 599, -256, +710, 140, 640, 438, 421, 580, 32, 548, +-450, 324, -786, -16, -833, -289, -680, -451, +-375, -469, 44, -325, 457, -91, 728, 103, +792, 250, 655, 328, 362, 245, -23, 56, +-338, -86, -418, -134, -330, -155, -176, -87, +-14, 52, 110, 146, 143, 146, 82, 121, +-41, 51, -154, -80, -184, -202, -111, -267, +39, -268, 226, -208, 403, -89, 499, 56, +516, 260, 408, 486, 107, 600, -290, 486, +-578, 203, -695, -151, -656, -522, -443, -819, +-96, -904, 286, -676, 585, -193, 737, 401, +716, 891, 527, 1109, 224, 990, -44, 591, +-243, -18, -405, -657, -487, -1090, -446, -1182, +-326, -921, -193, -379, -21, 295, 204, 842, +405, 1106, 508, 1042, 530, 674, 429, 80, +199, -508, -84, -887, -319, -974, -419, -769, +-368, -350, -198, 161, 35, 580, 242, 766, +331, 671, 285, 413, 103, 91, -128, -230, +-285, -456, -299, -465, -179, -308, 57, -139, +350, -19, 568, 53, 605, 79, 412, 62, +64, 77, -307, 131, -559, 220, -626, 304, +-499, 322, -227, 186, 94, -55, 352, -307, +493, -534, 484, -666, 363, -590, 252, -279, +150, 123, 12, 504, -108, 777, -150, 848, +-183, 648, -245, 263, -286, -195, -238, -595, +-115, -777, 16, -722, 119, -534, 200, -288, +321, 26, 441, 308, 466, 479, 370, 539, +210, 541, -16, 468, -301, 324, -557, 109, +-632, -173, -457, -454, -179, -648, 78, -704, +345, -629, 560, -400, 545, -55, 367, 353, +196, 716, 58, 910, -93, 826, -207, 505, +-217, 61, -158, -408, -90, -750, -37, -837, +-13, -656, -34, -315, -61, 92, -72, 402, +-28, 504, 87, 405, 267, 218, 431, 9, +466, -134, 375, -130, 202, -41, -75, 34, +-374, 81, -533, 90, -561, -22, -471, -181, +-208, -266, 165, -246, 465, -160, 642, 4, +699, 181, 553, 257, 182, 246, -234, 202, +-473, 104, -523, -60, -445, -162, -243, -179, +63, -163, 342, -132, 466, -66, 409, -20, +246, 25, 32, 145, -187, 270, -337, 288, +-355, 201, -215, 54, 18, -195, 254, -479, +435, -653, 505, -598, 398, -291, 154, 233, +-136, 781, -376, 1095, -495, 1054, -469, 668, +-296, -5, -27, -791, 265, -1374, 484, -1523, +563, -1154, 466, -399, 253, 497, 0, 1241, +-241, 1600, -403, 1438, -404, 782, -211, -111, +65, -869, 260, -1231, 319, -1161, 264, -718, +56, -75, -202, 509, -334, 757, -300, 590, +-151, 160, 112, -255, 449, -466, 681, -429, +626, -136, 317, 343, -60, 781, -418, 900, +-695, 657, -788, 149, -596, -486, -175, -1050, +298, -1285, 667, -1118, 832, -644, 731, 43, +429, 774, 59, 1268, -288, 1350, -500, 1090, +-534, 568, -411, -84, -188, -673, 63, -1033, +253, -1127, 336, -940, 299, -519, 194, -32, +81, 372, -44, 656, -137, 784, -126, 672, +-25, 401, 49, 118, 85, -115, 136, -299, +176, -364, 130, -302, 50, -181, -23, -80, +-138, -38, -242, -47, -262, -66, -195, -51, +-54, -29, 145, 29, 329, 131, 439, 232, +431, 250, 311, 196, 108, 115, -136, 13, +-335, -94, -415, -157, -376, -156, -236, -132, +12, -89, 246, -61, 343, -63, 312, -75, +211, -70, 41, -73, -123, -52, -175, 46, +-91, 174, 80, 244, 275, 276, 383, 308, +288, 255, 61, 121, -197, -31, -436, -199, +-594, -398, -550, -542, -272, -587, 116, -531, +464, -327, 715, 27, 823, 429, 718, 761, +418, 965, -12, 938, -434, 631, -715, 133, +-788, -394, -694, -850, -458, -1110, -101, -1078, +286, -774, 565, -303, 698, 225, 740, 694, +641, 947, 373, 943, 63, 731, -192, 377, +-440, -48, -643, -378, -693, -535, -552, -556, +-280, -463, 41, -262, 353, -72, 576, -4, +642, 5, 553, 0, 373, -12, 131, 16, +-104, 145, -259, 314, -304, 463, -288, 532, +-234, 461, -142, 237, -70, -83, -32, -407, +1, -667, 33, -779, 67, -720, 154, -502, +274, -179, 370, 193, 385, 511, 327, 716, +207, 789, -16, 730, -306, 532, -505, 203, +-527, -176, -419, -508, -214, -723, 33, -811, +256, -731, 397, -490, 438, -144, 370, 187, +242, 429, 140, 568, 81, 599, 11, 509, +-68, 334, -109, 187, -146, 79, -203, -42, +-274, -170, -322, -263, -304, -383, -190, -535, +-4, -646, 245, -648, 504, -511, 662, -194, +681, 301, 574, 822, 339, 1203, -26, 1324, +-414, 1126, -717, 565, -876, -236, -853, -1025, +-610, -1555, -198, -1683, 284, -1354, 731, -645, +1022, 212, 1060, 965, 822, 1436, 418, 1515, +-49, 1161, -490, 533, -801, -134, -869, -667, +-713, -965, -434, -955, -97, -677, 221, -296, +446, 45, 539, 252, 497, 288, 376, 175, +267, 33, 177, -29, 106, 48, 50, 235, +-28, 454, -174, 570, -357, 484, -485, 196, +-501, -226, -417, -667, -229, -956, 77, -934, +393, -614, 630, -120, 730, 399, 669, 810, +444, 954, 90, 787, -290, 413, -535, -39, +-596, -437, -531, -634, -349, -563, -76, -310, +185, 5, 330, 248, 357, 320, 289, 187, +175, -56, 72, -304, 11, -448, -21, -370, +-3, -55, 70, 358, 122, 688, 98, 821, +-14, 671, -148, 258, -239, -291, -284, -778, +-273, -1039, -147, -958, 55, -560, 242, 8, +351, 552, 367, 889, 330, 914, 228, 635, +49, 178, -103, -288, -140, -570, -156, -591, +-187, -382, -147, -51, -47, 256, -17, 387, +-65, 274, -98, -9, -97, -318, -73, -504, +19, -478, 228, -216, 468, 198, 618, 619, +581, 856, 361, 784, 5, 400, -412, -175, +-759, -716, -877, -1004, -727, -969, -405, -624, +4, -24, 418, 596, 751, 947, 893, 922, +818, 614, 577, 120, 249, -394, -116, -709, +-468, -734, -705, -514, -740, -123, -596, 297, +-371, 544, -113, 547, 139, 354, 353, 57, +510, -261, 606, -469, 615, -478, 522, -316, +335, -50, 93, 249, -188, 457, -479, 483, +-682, 348, -759, 113, -696, -170, -477, -428, +-103, -519, 353, -417, 805, -205, 1096, 64, +1083, 360, 772, 549, 266, 527, -320, 338, +-850, 51, -1122, -275, -1033, -545, -676, -642, +-203, -545, 295, -272, 693, 115, 886, 489, +849, 710, 631, 724, 314, 532, -30, 161, +-334, -277, -533, -640, -588, -818, -515, -762, +-357, -461, -169, -23, 30, 395, 219, 670, +396, 745, 533, 603, 571, 287, 473, -93, +246, -394, -59, -495, -363, -410, -562, -230, +-595, -53, -433, 89, -149, 152, 143, 97, +360, -27, 450, -97, 395, -72, 245, 7, +61, 116, -90, 227, -124, 301, -77, 288, +-33, 191, -1, 20, 27, -192, -5, -381, +-107, -482, -223, -479, -247, -347, -132, -88, +59, 215, 247, 460, 391, 572, 456, 513, +371, 306, 151, 45, -133, -194, -377, -349, +-476, -365, -375, -242, -166, -83, 33, 18, +209, 44, 338, 6, 345, -71, 212, -147, +31, -149, -99, -57, -135, 107, -100, 294, +-14, 450, 85, 503, 134, 417, 98, 206, +-7, -103, -121, -455, -180, -742, -161, -841, +-68, -727, 80, -410, 186, 60, 202, 544, +153, 878, 94, 1006, 37, 894, -15, 517, +-28, -10, 2, -489, 2, -812, -55, -934, +-93, -796, -111, -442, -119, -21, -89, 333, +-3, 550, 95, 570, 170, 420, 223, 210, +259, 29, 254, -67, 164, -53, -12, 28, +-220, 68, -355, 12, -371, -136, -283, -331, +-105, -507, 141, -562, 351, -423, 448, -101, +416, 293, 282, 631, 71, 830, -186, 799, +-374, 515, -419, 71, -342, -376, -174, -705, +86, -834, 339, -746, 448, -460, 385, -48, +234, 358, 41, 619, -180, 682, -342, 566, +-380, 288, -305, -73, -154, -370, 64, -501, +303, -462, 485, -263, 535, 35, 413, 296, +127, 410, -241, 343, -554, 126, -705, -150, +-621, -371, -299, -465, 161, -377, 578, -111, +836, 221, 841, 464, 565, 547, 119, 448, +-354, 197, -757, -110, -949, -370, -810, -492, +-402, -441, 117, -266, 608, -59, 932, 132, +944, 262, 645, 294, 172, 239, -301, 152, +-639, 60, -761, -19, -644, -63, -340, -96, +33, -120, 331, -116, 489, -104, 494, -113, +371, -85, 162, 1, -52, 98, -178, 174, +-183, 206, -127, 153, -55, 36, 24, -90, +52, -207, -3, -272, -90, -212, -125, -39, +-94, 158, -20, 313, 79, 364, 189, 265, +246, 49, 222, -189, 148, -387, 61, -485, +-19, -394, -84, -118, -118, 202, -133, 421, +-148, 507, -154, 440, -134, 200, -111, -134, +-56, -405, 68, -507, 219, -423, 338, -174, +424, 146, 451, 396, 324, 495, 52, 407, +-257, 121, -512, -246, -668, -516, -636, -580, +-409, -427, -84, -87, 268, 328, 593, 640, +779, 722, 754, 546, 559, 156, 240, -318, +-147, -672, -521, -783, -762, -634, -794, -270, +-608, 201, -254, 593, 164, 730, 516, 576, +701, 219, 673, -202, 469, -527, 196, -609, +-66, -428, -260, -67, -352, 340, -324, 617, +-222, 613, -116, 345, -48, -61, -14, -477, +-11, -763, -27, -792, -2, -543, 98, -99, +254, 410, 394, 814, 449, 981, 370, 877, +152, 537, -159, 23, -438, -540, -585, -967, +-587, -1125, -439, -987, -147, -585, 206, -10, +499, 582, 657, 1022, 631, 1162, 430, 951, +129, 477, -166, -93, -383, -594, -469, -888, +-407, -890, -253, -619, -82, -205, 59, 194, +150, 453, 174, 499, 162, 357, 157, 122, +191, -100, 231, -221, 222, -181, 149, 13, +37, 242, -111, 368, -287, 323, -425, 109, +-432, -219, -287, -533, -69, -691, 174, -612, +401, -302, 524, 154, 493, 572, 346, 777, +122, 729, -131, 471, -319, 59, -393, -370, +-381, -615, -299, -608, -134, -422, 57, -139, +197, 143, 268, 304, 284, 308, 247, 202, +190, 38, 133, -99, 62, -114, -10, -23, +-89, 74, -202, 143, -319, 163, -339, 82, +-247, -75, -103, -220, 59, -301, 247, -289, +406, -153, 463, 70, 408, 267, 264, 371, +49, 367, -201, 235, -413, -5, -516, -258, +-470, -417, -303, -439, -50, -327, 216, -97, +396, 187, 451, 423, 413, 531, 310, 476, +149, 259, -23, -57, -157, -363, -247, -565, +-305, -595, -316, -430, -287, -124, -205, 203, +-55, 439, 131, 531, 291, 461, 399, 265, +444, 29, 372, -175, 194, -296, -3, -310, +-173, -241, -330, -139, -413, -37, -365, 35, +-251, 59, -133, 58, 26, 50, 204, 34, +314, 33, 358, 73, 365, 125, 315, 145, +183, 136, 17, 100, -146, 16, -279, -100, +-356, -206, -364, -282, -309, -299, -180, -226, +22, -90, 225, 60, 366, 200, 430, 289, +401, 288, 254, 216, 41, 122, -143, 31, +-245, -38, -277, -58, -241, -46, -142, -59, +-35, -132, 43, -237, 90, -337, 104, -386, +67, -322, 9, -107, -7, 227, 48, 574, +128, 802, 200, 809, 241, 555, 194, 91, +49, -438, -126, -853, -269, -1013, -360, -867, +-359, -476, -248, 23, -68, 490, 117, 797, +289, 848, 409, 641, 428, 288, 349, -91, +202, -404, 7, -554, -184, -491, -310, -268, +-368, 12, -354, 247, -256, 335, -96, 224, +60, -23, 192, -275, 291, -431, 325, -412, +286, -182, 203, 194, 89, 566, -58, 779, +-178, 746, -221, 455, -194, -27, -139, -545, +-62, -908, 32, -997, 112, -786, 136, -339, +95, 194, 16, 637, -73, 860, -133, 812, +-117, 528, 5, 132, 192, -209, 371, -391, +446, -405, 353, -286, 93, -109, -245, 13, +-558, 12, -748, -95, -713, -234, -422, -307, +41, -243, 519, -36, 882, 254, 1015, 549, +851, 739, 420, 724, -128, 488, -629, 86, +-951, -393, -987, -813, -729, -1031, -287, -978, +191, -656, 587, -134, 798, 442, 772, 893, +531, 1084, 197, 969, -90, 588, -277, 68, +-373, -420, -373, -744, -297, -827, -203, -661, +-115, -332, -31, 25, 47, 293, 116, 420, +200, 381, 281, 207, 308, -1, 264, -130, +172, -131, 40, -25, -122, 130, -263, 257, +-331, 283, -285, 175, -144, -46, 26, -305, +147, -494, 195, -532, 170, -408, 86, -157, +-24, 158, -68, 440, -12, 591, 75, 570, +161, 391, 223, 106, 205, -179, 67, -372, +-128, -447, -294, -406, -391, -257, -391, -63, +-260, 88, -23, 168, 248, 189, 493, 160, +624, 101, 546, 49, 265, 22, -96, 17, +-403, 34, -578, 48, -579, 17, -390, -49, +-79, -98, 238, -118, 468, -119, 548, -84, +451, -18, 224, 42, -46, 67, -317, 55, +-509, 7, -502, -38, -276, -46, 29, -22, +305, 23, 512, 107, 563, 212, 399, 267, +115, 227, -152, 93, -380, -125, -537, -371, +-543, -549, -380, -591, -143, -467, 119, -172, +397, 246, 637, 641, 734, 867, 632, 869, +350, 648, -46, 228, -450, -305, -771, -779, +-914, -1046, -803, -1048, -445, -785, 40, -303, +537, 275, 938, 790, 1101, 1101, 921, 1115, +448, 830, -136, 337, -664, -232, -977, -745, +-944, -1055, -601, -1054, -137, -754, 300, -279, +617, 237, 712, 663, 534, 871, 209, 814, +-69, 541, -245, 152, -335, -236, -295, -501, +-100, -582, 118, -493, 221, -279, 193, -6, +92, 218, -55, 312, -188, 269, -221, 127, +-144, -40, -8, -149, 132, -147, 229, -34, +221, 131, 113, 258, -15, 261, -71, 116, +-52, -128, 13, -361, 88, -475, 119, -424, +73, -212, -33, 116, -168, 440, -281, 610, +-300, 568, -201, 349, -3, 17, 231, -328, +425, -570, 504, -637, 427, -515, 205, -238, +-93, 98, -357, 382, -492, 552, -460, 575, +-289, 448, -37, 206, 197, -86, 344, -345, +370, -499, 285, -516, 122, -411, -56, -213, +-176, 27, -200, 235, -124, 369, 3, 416, +113, 368, 157, 242, 145, 85, 78, -72, +-38, -207, -158, -275, -217, -277, -209, -258, +-146, -225, -20, -161, 138, -68, 268, 48, +336, 194, 332, 348, 236, 454, 69, 459, +-113, 336, -264, 86, -371, -233, -386, -516, +-270, -670, -71, -643, 132, -431, 297, -86, +380, 304, 339, 620, 207, 756, 43, 661, +-110, 370, -213, -17, -208, -383, -111, -623, +9, -662, 103, -482, 148, -154, 111, 177, +-20, 398, -179, 472, -282, 382, -270, 157, +-141, -96, 86, -270, 347, -326, 551, -243, +607, -46, 468, 176, 135, 329, -303, 366, +-662, 259, -804, 9, -694, -291, -387, -516, +37, -592, 453, -468, 730, -146, 776, 275, +598, 644, 275, 833, -69, 762, -337, 424, +-490, -80, -490, -573, -337, -881, -120, -920, +41, -685, 120, -241, 139, 270, 107, 676, +60, 852, 72, 775, 150, 491, 231, 89, +286, -313, 287, -601, 178, -695, -47, -572, +-309, -289, -520, 33, -596, 297, -480, 440, +-188, 428, 177, 288, 499, 99, 684, -65, +670, -162, 446, -189, 78, -164, -285, -114, +-508, -68, -528, -35, -382, -10, -140, 16, +117, 50, 293, 84, 328, 113, 221, 129, +39, 116, -131, 63, -218, -14, -186, -95, +-31, -183, 179, -240, 339, -220, 365, -119, +256, 22, 32, 169, -252, 291, -477, 353, +-521, 319, -368, 182, -104, -27, 194, -244, +445, -407, 568, -480, 508, -430, 284, -248, +-38, 24, -339, 304, -498, 515, -467, 594, +-281, 505, -8, 275, 269, -28, 435, -324, +419, -527, 249, -578, 14, -470, -207, -255, +-356, 0, -393, 224, -290, 366, -58, 411, +198, 371, 365, 278, 423, 156, 396, 21, +267, -111, 35, -232, -212, -324, -381, -362, +-447, -330, -410, -238, -286, -99, -90, 88, +150, 292, 373, 435, 499, 461, 498, 374, +384, 197, 173, -41, -82, -277, -312, -437, +-445, -462, -447, -341, -309, -128, -75, 74, +141, 204, 248, 263, 244, 245, 168, 150, +55, 35, -44, -27, -73, -27, 5, -3, +148, 15, 269, 15, 289, -14, 177, -72, +-41, -143, -304, -194, -511, -186, -561, -102, +-433, 28, -179, 149, 152, 227, 468, 262, +663, 231, 680, 119, 530, -34, 244, -154, +-93, -211, -385, -208, -566, -154, -601, -77, +-492, 7, -285, 82, -59, 105, 159, 62, +337, 17, 441, 24, 460, 55, 408, 80, +275, 103, 85, 100, -97, 35, -239, -71, +-340, -172, -373, -240, -319, -226, -205, -99, +-59, 72, 92, 195, 217, 244, 255, 218, +203, 105, 116, -61, 56, -194, 63, -232, +122, -155, 180, 6, 175, 168, 84, 244, +-106, 211, -342, 75, -521, -133, -548, -318, +-394, -363, -98, -238, 256, -8, 570, 236, +752, 409, 735, 441, 500, 297, 96, 15, +-344, -288, -679, -473, -797, -468, -654, -291, +-296, 2, 128, 316, 462, 511, 607, 488, +524, 258, 268, -77, -39, -390, -253, -557, +-314, -498, -239, -233, -83, 127, 99, 435, +251, 585, 313, 522, 231, 270, 24, -66, +-222, -364, -406, -519, -443, -489, -315, -317, +-71, -83, 206, 145, 428, 298, 509, 332, +425, 285, 230, 226, 13, 162, -168, 76, +-296, -18, -349, -122, -314, -259, -195, -390, +-49, -434, 61, -348, 115, -131, 140, 166, +133, 448, 101, 610, 101, 592, 157, 382, +218, 29, 218, -345, 146, -600, 8, -655, +-186, -501, -386, -181, -501, 193, -470, 480, +-300, 574, -44, 458, 245, 194, 512, -119, +666, -362, 645, -437, 465, -319, 173, -79, +-201, 165, -549, 310, -735, 303, -697, 150, +-475, -71, -135, -255, 226, -320, 505, -242, +632, -43, 580, 194, 385, 355, 127, 371, +-126, 234, -323, -9, -404, -270, -357, -434, +-242, -447, -99, -304, 66, -34, 190, 266, +220, 479, 191, 535, 138, 419, 51, 161, +-54, -156, -98, -424, -68, -562, -9, -541, +47, -364, 108, -73, 138, 237, 92, 468, +-16, 572, -137, 533, -232, 356, -283, 74, +-257, -242, -110, -493, 147, -600, 398, -527, +520, -294, 476, 24, 291, 326, -15, 507, +-363, 495, -605, 303, -634, 28, -450, -221, +-116, -348, 277, -287, 587, -69, 700, 175, +567, 327, 245, 302, -157, 81, -500, -257, +-658, -554, -568, -651, -264, -467, 125, -36, +451, 488, 595, 903, 515, 1033, 249, 779, +-88, 186, -372, -526, -509, -1069, -432, -1259, +-158, -1030, 168, -422, 391, 369, 446, 1039, +333, 1330, 80, 1141, -228, 553, -455, -215, +-488, -881, -289, -1224, 48, -1130, 379, -622, +579, 115, 581, 787, 372, 1139, 1, 1067, +-395, 619, -665, -43, -710, -688, -522, -1080, +-159, -1075, 268, -688, 626, -68, 809, 562, +761, 979, 472, 1055, 21, 798, -433, 300, +-728, -287, -790, -767, -641, -979, -320, -885, +96, -541, 471, -50, 661, 433, 642, 758, +467, 848, 195, 683, -109, 315, -347, -124, +-428, -484, -352, -672, -182, -642, -9, -401, +106, -53, 145, 267, 109, 447, 19, 431, +-70, 254, -95, 24, -26, -169, 116, -263, +264, -206, 328, -28, 278, 156, 136, 247, +-89, 210, -331, 52, -482, -162, -477, -337, +-336, -406, -99, -332, 175, -96, 410, 218, +545, 467, 525, 570, 355, 507, 111, 263, +-121, -102, -311, -448, -427, -648, -421, -644, +-320, -444, -182, -111, -27, 249, 128, 530, +249, 654, 321, 590, 349, 368, 319, 58, +223, -254, 84, -493, -83, -604, -250, -550, +-380, -335, -410, -22, -329, 283, -182, 484, +1, 522, 205, 388, 388, 141, 477, -114, +448, -289, 309, -329, 79, -216, -201, -20, +-440, 129, -542, 162, -472, 82, -260, -81, +17, -248, 280, -309, 456, -218, 488, -6, +385, 260, 186, 486, -64, 568, -285, 455, +-406, 176, -392, -192, -255, -539, -19, -739, +224, -722, 362, -496, 367, -119, 238, 318, +25, 685, -190, 844, -320, 746, -334, 436, +-215, 19, 10, -387, 228, -671, 347, -752, +353, -613, 241, -312, 18, 46, -232, 340, +-382, 493, -377, 501, -233, 399, -7, 224, +228, 25, 379, -134, 365, -224, 201, -264, +-20, -275, -192, -247, -270, -174, -246, -74, +-125, 48, 47, 184, 194, 278, 241, 291, +178, 228, 43, 109, -116, -33, -245, -146, +-282, -209, -172, -231, 52, -200, 280, -115, +393, -13, 343, 77, 164, 146, -75, 181, +-280, 174, -371, 129, -336, 50, -198, -35, +-6, -93, 167, -124, 260, -129, 269, -106, +219, -74, 117, -42, -20, 9, -136, 72, +-174, 113, -145, 141, -82, 155, -4, 124, +59, 51, 78, -34, 60, -129, 34, -211, +3, -231, -35, -179, -53, -77, -39, 58, +-18, 185, 2, 250, 40, 253, 96, 206, +136, 102, 141, -39, 92, -168, -10, -249, +-131, -287, -235, -282, -280, -201, -230, -33, +-78, 178, 106, 362, 261, 451, 362, 397, +370, 201, 242, -72, 13, -329, -204, -487, +-326, -483, -340, -309, -262, -31, -102, 245, +97, 424, 234, 444, 255, 306, 185, 74, +56, -157, -72, -309, -140, -339, -134, -239, +-75, -53, 45, 135, 191, 248, 244, 244, +157, 135, -12, -9, -176, -132, -291, -198, +-320, -180, -236, -92, -53, 19, 175, 117, +351, 178, 408, 167, 343, 92, 170, 1, +-63, -65, -273, -104, -398, -109, -398, -88, +-249, -61, 0, -27, 229, 6, 345, 23, +324, 33, 191, 53, 2, 85, -177, 110, +-274, 102, -238, 59, -75, -3, 124, -60, +255, -115, 275, -162, 195, -179, 36, -154, +-148, -77, -278, 47, -312, 179, -246, 276, +-96, 301, 83, 223, 211, 59, 262, -137, +258, -311, 192, -394, 68, -324, -36, -125, +-72, 106, -80, 293, -90, 383, -96, 335, +-107, 165, -152, -61, -200, -267, -182, -365, +-64, -315, 119, -171, 307, 19, 448, 218, +479, 339, 349, 327, 72, 220, -246, 61, +-489, -122, -596, -280, -544, -358, -334, -331, +-17, -188, 313, 21, 538, 213, 583, 347, +454, 394, 211, 310, -79, 121, -322, -92, +-400, -271, -290, -378, -89, -365, 82, -238, +147, -53, 83, 137, -59, 285, -179, 349, +-205, 303, -121, 153, 44, -54, 241, -234, +395, -311, 434, -275, 339, -146, 129, 42, +-145, 223, -391, 316, -517, 276, -496, 106, +-342, -140, -80, -361, 201, -453, 392, -359, +441, -86, 360, 288, 221, 595, 96, 667, +4, 458, -86, 57, -168, -401, -232, -733, +-284, -776, -312, -507, -283, -52, -159, 398, +64, 663, 310, 658, 449, 435, 445, 106, +339, -222, 144, -439, -99, -460, -291, -312, +-371, -91, -331, 103, -182, 206, -4, 218, +94, 154, 114, 19, 102, -126, 58, -182, +17, -134, 39, -20, 114, 135, 178, 276, +182, 319, 89, 239, -78, 53, -226, -218, +-310, -490, -315, -623, -202, -530, 7, -222, +225, 229, 383, 661, 437, 891, 339, 813, +92, 439, -218, -135, -476, -698, -569, -994, +-439, -920, -120, -536, 278, 25, 587, 574, +660, 883, 465, 824, 99, 461, -299, -29, +-591, -442, -649, -612, -447, -505, -100, -206, +239, 142, 475, 356, 555, 323, 457, 107, +220, -139, -62, -296, -301, -286, -448, -101, +-450, 145, -297, 320, -53, 356, 192, 243, +349, 44, 368, -141, 257, -262, 67, -295, +-139, -223, -276, -88, -264, 18, -126, 80, +36, 122, 141, 136, 165, 117, 120, 95, +48, 81, -9, 57, -35, 23, -29, -18, +-10, -74, -24, -147, -80, -200, -130, -197, +-127, -138, -60, -27, 46, 123, 133, 252, +163, 296, 163, 252, 148, 129, 114, -61, +57, -241, -47, -319, -199, -280, -329, -149, +-346, 40, -231, 212, -20, 300, 214, 294, +373, 191, 395, -11, 278, -248, 81, -416, +-105, -434, -190, -272, -172, 33, -143, 367, +-145, 605, -145, 628, -109, 383, -41, -46, +41, -473, 124, -723, 179, -695, 195, -398, +166, 28, 86, 393, 6, 576, -25, 552, +-41, 356, -98, 72, -150, -176, -155, -291, +-133, -273, -82, -180, -4, -71, 50, 2, +63, 7, 76, -36, 93, -77, 115, -77, +172, 3, 208, 159, 145, 288, -2, 304, +-178, 212, -332, 21, -393, -219, -305, -376, +-111, -350, 119, -182, 324, 30, 425, 215, +395, 290, 251, 209, 24, 33, -223, -142, +-396, -242, -444, -215, -355, -65, -113, 130, +207, 288, 438, 359, 470, 283, 307, 56, +24, -211, -277, -406, -453, -478, -424, -397, +-207, -148, 86, 186, 306, 455, 377, 547, +308, 417, 165, 121, 2, -201, -151, -416, +-254, -448, -275, -264, -208, 54, -67, 333, +112, 432, 237, 294, 218, -39, 72, -395, +-111, -561, -244, -463, -249, -155, -88, 250, +165, 602, 372, 746, 439, 602, 319, 207, +52, -284, -244, -668, -448, -812, -517, -688, +-454, -351, -248, 101, 73, 534, 395, 791, +575, 760, 551, 464, 361, 36, 54, -377, +-263, -655, -446, -706, -425, -515, -243, -159, +-8, 242, 169, 547, 206, 641, 122, 501, +-15, 200, -131, -168, -155, -479, -78, -607, +48, -502, 175, -217, 280, 134, 310, 427, +234, 564, 77, 496, -148, 249, -380, -67, +-518, -326, -473, -456, -248, -421, 62, -243, +323, -11, 430, 192, 370, 306, 191, 281, +-8, 148, -104, 3, -77, -103, -4, -151, +43, -97, 34, 24, -30, 113, -117, 134, +-171, 91, -181, -31, -170, -175, -173, -266, +-163, -288, -58, -220, 144, -52, 382, 154, +576, 334, 624, 475, 441, 502, 74, 350, +-332, 72, -668, -255, -826, -577, -738, -766, +-453, -710, -74, -423, 313, 18, 616, 496, +761, 839, 755, 913, 568, 710, 195, 285, +-209, -244, -484, -677, -607, -858, -601, -772, +-453, -475, -223, -44, -21, 368, 115, 604, +201, 615, 279, 448, 356, 176, 398, -102, +362, -288, 238, -341, 66, -274, -120, -128, +-291, 21, -425, 112, -477, 130, -404, 84, +-247, -8, -42, -92, 184, -115, 391, -84, +506, -8, 484, 93, 311, 171, 32, 192, +-229, 164, -393, 80, -422, -45, -282, -153, +-53, -210, 120, -229, 177, -204, 158, -112, +76, 19, -21, 145, -60, 240, -51, 275, +-8, 217, 49, 81, 71, -71, 53, -192, +53, -246, 68, -198, 43, -63, 8, 73, +-46, 157, -152, 165, -220, 82, -178, -46, +-99, -118, -27, -112, 93, -67, 212, 14, +228, 104, 159, 133, 52, 84, -49, -9, +-110, -107, -114, -142, -83, -71, -12, 53, +96, 163, 150, 229, 97, 200, -34, 41, +-186, -196, -310, -410, -356, -499, -243, -399, +19, -120, 328, 248, 552, 584, 585, 767, +399, 709, 81, 399, -236, -81, -482, -581, +-593, -918, -514, -946, -294, -648, -32, -151, +197, 362, 371, 742, 441, 851, 398, 635, +275, 224, 101, -165, -54, -387, -155, -389, +-198, -205, -205, 11, -205, 119, -223, 80, +-241, -110, -184, -377, -65, -512, 73, -389, +239, -86, 402, 306, 468, 697, 378, 907, +191, 824, -29, 483, -244, -46, -409, -610, +-502, -989, -472, -1069, -292, -871, -8, -423, +271, 152, 448, 656, 483, 954, 368, 973, +146, 693, -109, 245, -287, -179, -317, -504, +-234, -674, -101, -619, -8, -375, 15, -69, +24, 199, 80, 330, 145, 265, 155, 89, +132, -74, 68, -175, -67, -160, -207, 24, +-243, 288, -170, 466, -61, 456, 78, 246, +204, -107, 232, -459, 166, -653, 82, -633, +24, -430, -38, -96, -116, 259, -221, 491, +-334, 557, -355, 492, -244, 323, -21, 101, +265, -99, 543, -245, 669, -335, 555, -354, +260, -303, -149, -210, -563, -84, -798, 53, +-746, 151, -470, 204, -75, 219, 360, 196, +669, 161, 723, 138, 515, 104, 144, 34, +-213, -71, -412, -213, -419, -366, -301, -442, +-107, -368, 88, -137, 195, 201, 210, 499, +147, 600, 19, 477, -131, 217, -229, -105, +-266, -399, -213, -538, 16, -476, 325, -276, +498, -18, 444, 224, 242, 371, -29, 410, +-320, 361, -506, 206, -528, -38, -395, -261, +-168, -384, 57, -395, 232, -284, 363, -98, +455, 81, 427, 229, 269, 343, 79, 366, +-106, 283, -241, 140, -293, -58, -308, -273, +-357, -413, -369, -436, -235, -324, 6, -56, +279, 269, 502, 474, 576, 499, 431, 354, +98, 36, -251, -328, -435, -540, -381, -528, +-193, -312, 6, 64, 149, 449, 171, 662, +95, 619, -12, 322, -107, -142, -186, -573, +-204, -780, -120, -713, 37, -408, 245, 51, +417, 519, 437, 825, 273, 854, -22, 592, +-342, 127, -558, -371, -559, -737, -372, -849, +-90, -673, 206, -262, 402, 227, 440, 587, +344, 674, 180, 491, -25, 166, -219, -144, +-305, -323, -232, -328, -36, -188, 144, -1, +210, 120, 148, 123, -23, 50, -222, -48, +-355, -119, -351, -117, -202, -56, 66, 18, +335, 93, 459, 156, 440, 148, 316, 75, +109, -4, -130, -75, -330, -133, -441, -146, +-431, -113, -283, -40, -78, 86, 119, 200, +271, 205, 303, 111, 221, -37, 90, -223, +-31, -357, -95, -332, -47, -137, 73, 177, +150, 485, 135, 597, -14, 437, -256, 92, +-427, -327, -438, -674, -293, -747, -15, -491, +319, -53, 508, 417, 485, 764, 329, 801, +93, 487, -128, -3, -246, -476, -277, -768, +-264, -741, -202, -422, -116, 18, -39, 419, +63, 659, 133, 642, 106, 407, 39, 97, +-5, -204, -14, -452, 47, -569, 173, -529, +230, -357, 156, -61, 2, 295, -199, 564, +-347, 631, -343, 471, -207, 128, -39, -247, +113, -473, 231, -482, 276, -293, 261, 14, +167, 263, -21, 308, -236, 164, -363, -77, +-323, -312, -135, -408, 155, -277, 412, 36, +480, 419, 285, 714, -81, 746, -419, 452, +-607, -67, -555, -624, -259, -993, 123, -997, +434, -637, 621, -61, 650, 530, 448, 921, +90, 966, -295, 693, -629, 249, -763, -208, +-608, -567, -264, -752, 117, -704, 447, -411, +608, 32, 522, 436, 291, 644, 5, 574, +-264, 251, -402, -188, -368, -545, -230, -657, +-38, -449, 190, 17, 327, 539, 288, 875, +110, 848, -153, 459, -378, -131, -443, -722, +-299, -1130, -20, -1172, 269, -762, 464, -14, +496, 797, 357, 1344, 79, 1395, -236, 949, +-463, 177, -528, -687, -417, -1327, -206, -1447, +36, -1018, 264, -241, 419, 620, 418, 1251, +286, 1392, 127, 994, -53, 208, -248, -682, +-377, -1327, -375, -1459, -241, -1012, -18, -120, +206, 879, 300, 1551, 260, 1619, 125, 1071, +-72, 94, -225, -963, -260, -1672, -188, -1771, +-59, -1239, 98, -243, 217, 858, 249, 1640, +231, 1826, 157, 1354, -6, 389, -231, -688, +-423, -1456, -469, -1659, -312, -1254, -25, -390, +242, 589, 412, 1276, 447, 1421, 319, 1020, +81, 256, -176, -589, -359, -1206, -395, -1340, +-279, -928, -102, -136, 72, 728, 227, 1339, +274, 1468, 172, 1032, 8, 158, -129, -834, +-189, -1535, -128, -1666, 15, -1188, 103, -280, +97, 739, 51, 1517, -11, 1765, -75, 1376, +-106, 477, -102, -587, -108, -1392, -104, -1641, +-49, -1289, 19, -496, 90, 444, 180, 1166, +240, 1392, 167, 1071, -3, 368, -138, -430, +-216, -1006, -232, -1152, -177, -878, -102, -299, +-39, 400, 71, 950, 216, 1130, 250, 895, +179, 326, 86, -399, -43, -968, -178, -1137, +-216, -900, -182, -381, -168, 261, -122, 788, +-31, 988, 40, 836, 130, 417, 267, -129, +345, -568, 272, -723, 83, -601, -193, -276, +-459, 154, -521, 491, -377, 547, -151, 323, +106, -56, 339, -444, 455, -643, 454, -497, +354, -79, 80, 386, -290, 728, -538, 822, +-594, 588, -487, 105, -207, -428, 175, -841, +460, -975, 551, -732, 464, -237, 232, 304, +-57, 766, -296, 969, -443, 751, -497, 256, +-399, -253, -122, -645, 231, -782, 511, -558, +586, -123, 419, 295, 54, 594, -367, 648, +-654, 390, -713, 1, -517, -358, -101, -668, +365, -762, 668, -493, 755, -11, 661, 487, +326, 893, -198, 1011, -677, 703, -917, 136, +-877, -455, -554, -947, -39, -1149, 448, -918, +776, -395, 885, 222, 694, 794, 264, 1098, +-192, 999, -516, 610, -694, 71, -682, -518, +-459, -931, -147, -955, 135, -647, 346, -169, +440, 365, 384, 732, 257, 752, 137, 506, +-16, 118, -195, -339, -297, -665, -291, -680, +-222, -419, -80, 1, 92, 481, 148, 812, +87, 792, 11, 464, -74, -52, -148, -633, +-79, -1009, 87, -986, 142, -623, 99, -36, +37, 619, -71, 1058, -141, 1084, -92, 762, +-19, 229, 18, -385, 87, -859, 89, -993, +-58, -794, -156, -369, -142, 153, -162, 575, +-155, 743, -11, 643, 122, 351, 164, -19, +217, -343, 227, -525, 115, -513, -18, -309, +-108, 25, -207, 360, -279, 558, -263, 557, +-229, 343, -181, -43, -63, -475, 65, -790, +159, -834, 271, -537, 383, 1, 371, 582, +245, 1008, 93, 1106, -138, 805, -424, 189, +-582, -529, -541, -1075, -398, -1218, -164, -901, +142, -274, 333, 412, 361, 901, 373, 991, +359, 672, 235, 159, 107, -327, 4, -605, +-201, -551, -414, -260, -478, 66, -427, 333, +-291, 453, -62, 333, 130, 43, 192, -248, +224, -485, 224, -618, 148, -519, 142, -212, +216, 196, 172, 681, -11, 1065, -179, 1065, +-290, 679, -363, 66, -364, -667, -308, -1315, +-226, -1586, -88, -1333, 107, -612, 295, 394, +432, 1333, 501, 1828, 445, 1733, 229, 1097, +-101, 52, -405, -1048, -545, -1753, -497, -1818, +-316, -1253, -129, -269, 4, 752, 122, 1408, +200, 1502, 183, 1070, 116, 249, 106, -653, +107, -1199, 70, -1185, 71, -718, 80, 25, +10, 781, -84, 1200, -178, 1108, -334, 578, +-452, -215, -403, -997, -226, -1411, 35, -1292, +319, -729, 501, 146, 529, 1053, 439, 1604, +190, 1620, -193, 1108, -467, 135, -525, -957, +-466, -1671, -310, -1794, -60, -1339, 185, -388, +318, 718, 317, 1498, 200, 1734, 14, 1387, +-158, 511, -241, -519, -197, -1253, -69, -1522, +72, -1287, 201, -560, 253, 376, 144, 1119, +-56, 1441, -229, 1237, -355, 518, -362, -416, +-205, -1150, -26, -1446, 88, -1205, 185, -449, +246, 531, 195, 1290, 76, 1531, -24, 1177, +-99, 326, -95, -677, -23, -1392, 16, -1562, +20, -1136, 9, -221, -83, 828, -262, 1525, +-399, 1586, -403, 1024, -252, 50, 39, -963, +379, -1589, 632, -1578, 705, -943, 546, 104, +175, 1134, -291, 1671, -728, 1527, -984, 818, +-887, -229, -464, -1229, 91, -1714, 579, -1500, +842, -723, 794, 362, 449, 1325, -34, 1690, +-444, 1344, -621, 534, -522, -463, -251, -1305, +64, -1574, 312, -1152, 393, -313, 291, 617, +49, 1297, -281, 1409, -569, 924, -659, 87, +-483, -814, -54, -1432, 481, -1406, 858, -725, +908, 240, 639, 1152, 92, 1717, -582, 1562, +-1023, 649, -1033, -570, -718, -1617, -203, -2098, +347, -1727, 685, -590, 736, 843, 588, 1988, +278, 2398, -149, 1845, -491, 497, -617, -1050, +-544, -2179, -258, -2486, 160, -1797, 481, -373, +573, 1164, 416, 2229, 9, 2430, -474, 1664, +-767, 246, -747, -1215, -425, -2169, 92, -2337, +592, -1624, 835, -257, 779, 1168, 497, 2131, +20, 2341, -508, 1660, -857, 352, -916, -1031, +-677, -2032, -213, -2321, 291, -1735, 625, -481, +695, 885, 502, 1849, 132, 2135, -217, 1632, +-390, 553, -378, -602, -237, -1491, -59, -1869, +50, -1511, 61, -593, 57, 403, 64, 1166, +17, 1531, -56, 1316, -68, 612, -80, -207, +-138, -860, -115, -1202, 0, -1071, 60, -541, +22, 43, -9, 478, 19, 698, 66, 638, +142, 386, 200, 131, 141, -30, -36, -78, +-285, -46, -514, -22, -559, -94, -374, -276, +-78, -504, 222, -678, 452, -650, 529, -321, +465, 207, 336, 783, 128, 1281, -169, 1454, +-442, 1115, -621, 335, -690, -668, -556, -1572, +-199, -2011, 223, -1794, 512, -1003, 580, 105, +456, 1226, 221, 1984, -28, 2049, -257, 1441, +-401, 444, -342, -601, -132, -1334, 63, -1527, +166, -1216, 156, -629, 18, -2, -207, 475, +-391, 611, -411, 410, -253, 153, 53, 22, +410, 46, 591, 238, 513, 478, 308, 590, +32, 522, -313, 234, -618, -298, -750, -916, +-673, -1316, -350, -1304, 177, -900, 602, -190, +715, 636, 591, 1321, 273, 1683, -188, 1543, +-540, 860, -609, -69, -486, -878, -230, -1379, +115, -1455, 341, -1057, 386, -337, 376, 396, +270, 856, -29, 866, -387, 488, -635, 1, +-666, -364, -424, -461, -11, -191, 385, 306, +622, 740, 644, 893, 456, 612, 142, -59, +-196, -803, -503, -1295, -656, -1377, -583, -992, +-404, -259, -179, 556, 102, 1231, 346, 1533, +441, 1273, 366, 610, 197, -139, 78, -794, +67, -1133, 68, -985, -16, -497, -209, 52, +-473, 467, -669, 554, -638, 248, -385, -199, +3, -484, 439, -510, 747, -229, 827, 325, +691, 877, 293, 1145, -260, 984, -703, 398, +-933, -411, -955, -1165, -651, -1608, -38, -1486, +549, -783, 895, 188, 930, 1079, 529, 1618, +-113, 1575, -567, 928, -784, -1, -814, -855, +-508, -1395, 37, -1391, 511, -804, 808, 89, +861, 925, 541, 1352, -47, 1182, -640, 551, +-1088, -323, -1204, -1169, -824, -1566, -121, -1287, +606, -495, 1122, 506, 1226, 1348, 878, 1694, +232, 1437, -475, 683, -999, -303, -1145, -1145, +-891, -1557, -365, -1459, 244, -885, 676, -15, +762, 786, 569, 1228, 173, 1246, -305, 802, +-591, 34, -568, -624, -320, -926, 73, -859, +411, -410, 490, 213, 344, 667, 79, 822, +-288, 629, -635, 125, -706, -440, -450, -772, +-12, -811, 445, -604, 680, -133, 580, 423, +283, 770, -114, 851, -559, 618, -822, 88, +-697, -414, -267, -691, 237, -721, 635, -414, +826, 85, 770, 500, 431, 755, -179, 776, +-846, 402, -1265, -301, -1266, -953, -806, -1222, +-12, -1098, 803, -605, 1317, 207, 1350, 1096, +962, 1729, 314, 1767, -435, 1147, -1032, 151, +-1259, -914, -1085, -1701, -666, -1924, -159, -1597, +378, -807, 798, 267, 918, 1222, 703, 1708, +239, 1608, -264, 1000, -567, 117, -611, -692, +-440, -1124, -114, -1115, 193, -723, 335, -31, +333, 631, 242, 919, 27, 753, -314, 208, +-621, -464, -716, -937, -546, -1112, -172, -935, +318, -308, 818, 584, 1060, 1338, 837, 1693, +242, 1538, -435, 810, -905, -265, -1023, -1212, +-823, -1737, -424, -1794, 55, -1360, 476, -519, +669, 461, 609, 1255, 384, 1576, -20, 1381, +-478, 873, -654, 219, -492, -442, -162, -880, +261, -935, 631, -637, 718, -193, 447, 157, +-63, 293, -617, 180, -1023, -78, -1106, -285, +-830, -350, -282, -247, 408, 37, 1049, 425, +1424, 790, 1335, 943, 742, 787, -134, 379, +-989, -230, -1556, -873, -1585, -1281, -1065, -1335, +-306, -1009, 446, -346, 1068, 425, 1295, 1038, +990, 1347, 409, 1284, -219, 843, -749, 195, +-877, -380, -608, -765, -257, -898, 116, -759, +447, -508, 441, -235, 76, 51, -295, 162, +-493, 76, -521, 77, -269, 267, 156, 497, +436, 692, 551, 791, 566, 613, 355, 152, +-66, -406, -465, -959, -686, -1377, -687, -1348, +-495, -818, -178, -53, 179, 749, 442, 1425, +472, 1661, 274, 1307, 11, 552, -176, -378, +-235, -1192, -142, -1530, 66, -1301, 274, -692, +289, 95, 72, 796, -204, 1114, -483, 997, +-766, 640, -830, 146, -499, -470, 68, -910, +640, -911, 1103, -577, 1232, -84, 843, 439, +134, 769, -610, 776, -1199, 529, -1372, 121, +-1113, -354, -643, -603, 29, -478, 768, -284, +1137, -140, 1042, 66, 733, 129, 246, -30, +-427, -98, -887, -14, -858, 101, -529, 329, +-84, 663, 319, 810, 437, 585, 228, 79, +-109, -617, -431, -1286, -604, -1536, -445, -1287, +-12, -650, 442, 375, 822, 1454, 1045, 2048, +856, 2006, 191, 1368, -643, 199, -1294, -1146, +-1582, -2129, -1394, -2468, -691, -2078, 255, -947, +1061, 594, 1579, 1915, 1629, 2602, 1089, 2483, +238, 1519, -588, 40, -1268, -1394, -1620, -2325, +-1408, -2501, -759, -1935, -32, -799, 625, 627, +1049, 1823, 1027, 2355, 690, 2167, 304, 1363, +-90, 150, -400, -1084, -468, -1922, -389, -2093, +-288, -1598, -139, -696, -74, 269, -273, 1031, +-532, 1467, -524, 1466, -255, 1014, 190, 407, +779, -143, 1278, -620, 1314, -874, 809, -840, +24, -651, -861, -392, -1628, -144, -1905, 37, +-1611, 184, -917, 346, 55, 508, 1112, 581, +1895, 544, 2145, 403, 1818, 123, 923, -156, +-338, -345, -1480, -520, -2177, -576, -2348, -497, +-1839, -380, -766, -177, 390, 81, 1376, 286, +2040, 444, 2074, 524, 1477, 487, 612, 345, +-349, 174, -1292, 76, -1797, -22, -1702, -184, +-1281, -381, -656, -586, 154, -732, 837, -749, +1112, -564, 1108, -108, 991, 475, 708, 1006, +259, 1385, -252, 1409, -726, 974, -1035, 201, +-1113, -724, -989, -1564, -662, -2001, -154, -1815, +407, -1064, 848, 1, 1024, 1138, 971, 1993, +746, 2223, 342, 1824, -144, 948, -637, -239, +-1050, -1398, -1199, -2142, -1026, -2282, -658, -1769, +-149, -718, 476, 574, 959, 1689, 1091, 2227, +979, 2058, 658, 1304, 84, 166, -458, -988, +-726, -1694, -848, -1782, -808, -1356, -510, -555, +-224, 400, -73, 1100, 163, 1238, 360, 919, +253, 374, 139, -266, 261, -751, 345, -795, +344, -412, 422, 162, 406, 657, 79, 898, +-422, 769, -940, 258, -1420, -451, -1544, -1119, +-1042, -1495, -149, -1347, 819, -676, 1678, 322, +2111, 1346, 1862, 1995, 1045, 2032, -75, 1417, +-1269, 270, -2230, -1018, -2543, -2008, -2064, -2423, +-1024, -2071, 332, -1005, 1702, 345, 2565, 1509, +2553, 2237, 1716, 2338, 351, 1643, -1155, 396, +-2284, -887, -2628, -1871, -2137, -2270, -984, -1846, +483, -818, 1750, 351, 2360, 1369, 2127, 1976, +1158, 1906, -193, 1196, -1396, 128, -2012, -1014, +-1947, -1853, -1279, -2025, -213, -1496, 821, -471, +1429, 762, 1505, 1784, 1112, 2173, 410, 1773, +-390, 725, -1050, -562, -1343, -1581, -1142, -2019, +-486, -1823, 293, -1042, 843, 51, 1077, 1064, +901, 1759, 245, 1932, -578, 1466, -1090, 524, +-1139, -544, -792, -1407, -113, -1887, 638, -1868, +1090, -1210, 1129, -98, 795, 1026, 139, 1844, +-601, 2109, -1092, 1701, -1214, 795, -976, -295, +-388, -1334, 316, -2060, 750, -2117, 830, -1507, +671, -626, 285, 400, -186, 1463, -457, 2095, +-438, 2087, -277, 1593, -104, 694, 90, -469, +236, -1527, 203, -2149, 16, -2197, -249, -1658, +-492, -604, -546, 654, -393, 1741, -149, 2337, +173, 2164, 510, 1292, 637, 59, 521, -1225, +362, -2099, 175, -2174, -150, -1513, -462, -373, +-607, 900, -696, 1838, -690, 2110, -438, 1614, +-76, 477, 180, -863, 348, -1868, 479, -2240, +537, -1884, 550, -814, 478, 674, 244, 1986, +-78, 2678, -453, 2518, -827, 1451, -966, -186, +-755, -1783, -362, -2848, 30, -3040, 397, -2270, +664, -788, 669, 1001, 494, 2511, 310, 3181, +57, 2865, -310, 1735, -594, 64, -656, -1683, +-546, -2887, -320, -3094, 70, -2292, 500, -771, +656, 1001, 525, 2327, 284, 2755, -94, 2296, +-594, 1109, -940, -450, -939, -1778, -679, -2434, +-214, -2248, 448, -1318, 1095, 48, 1410, 1408, +1234, 2257, 672, 2358, -80, 1724, -874, 493, +-1506, -917, -1755, -1978, -1573, -2417, -1014, -2162, +-127, -1295, 885, -50, 1666, 1163, 1986, 1964, +1815, 2251, 1143, 1987, 67, 1198, -1029, 180, +-1815, -780, -2079, -1518, -1698, -1879, -906, -1819, +-41, -1397, 788, -781, 1405, -125, 1493, 593, +1046, 1299, 417, 1780, -153, 1950, -585, 1806, +-724, 1277, -546, 339, -281, -824, -94, -1865, +-1, -2544, -41, -2713, -222, -2224, -448, -1113, +-540, 354, -338, 1827, 124, 2937, 629, 3344, +983, 2898, 1117, 1691, 929, 10, 345, -1707, +-482, -2967, -1221, -3476, -1579, -3160, -1510, -2027, +-1082, -327, -335, 1379, 550, 2621, 1284, 3246, +1651, 3115, 1586, 2150, 1122, 615, 311, -968, +-658, -2173, -1431, -2790, -1780, -2719, -1679, -1967, +-1133, -794, -277, 461, 579, 1537, 1184, 2172, +1459, 2226, 1388, 1769, 965, 955, 364, -27, +-209, -951, -752, -1592, -1212, -1786, -1402, -1538, +-1284, -956, -945, -219, -373, 453, 373, 959, +1040, 1226, 1470, 1215, 1626, 991, 1401, 636, +741, 216, -228, -200, -1261, -664, -2032, -1163, +-2244, -1471, -1806, -1429, -821, -1098, 504, -459, +1782, 582, 2482, 1708, 2365, 2364, 1584, 2365, +291, 1724, -1217, 488, -2359, -997, -2735, -2321, +-2337, -3157, -1270, -3064, 315, -1926, 1942, -247, +2886, 1453, 2794, 2898, 1833, 3620, 321, 3200, +-1370, 1798, -2724, -46, -3185, -1841, -2518, -3114, +-1035, -3473, 678, -2821, 2137, -1386, 2954, 377, +2795, 1908, 1656, 2782, -11, 2830, -1592, 2064, +-2613, 740, -2778, -669, -2050, -1688, -681, -2022, +825, -1713, 1948, -979, 2379, -12, 2029, 821, +1024, 1111, -298, 901, -1479, 451, -2066, -109, +-1903, -559, -1156, -592, -105, -263, 894, 141, +1475, 544, 1520, 812, 1154, 671, 496, 236, +-369, -259, -1128, -825, -1406, -1222, -1260, -1145, +-901, -681, -266, -9, 545, 731, 1093, 1329, +1196, 1615, 1007, 1401, 586, 599, 3, -477, +-500, -1308, -845, -1715, -1111, -1764, -1169, -1261, +-863, -204, -270, 897, 438, 1655, 1074, 1935, +1373, 1648, 1202, 951, 676, 58, -55, -932, +-800, -1737, -1284, -2026, -1364, -1769, -1069, -1133, +-493, -207, 184, 855, 801, 1754, 1250, 2244, +1336, 2191, 943, 1544, 205, 473, -615, -771, +-1234, -1912, -1409, -2547, -1065, -2457, -404, -1754, +276, -614, 810, 688, 1062, 1747, 949, 2341, +545, 2362, -26, 1772, -606, 814, -982, -196, +-993, -1149, -643, -1896, -78, -2138, 486, -1802, +877, -1108, 945, -249, 559, 662, -132, 1390, +-680, 1686, -878, 1528, -836, 1069, -556, 466, +-5, -192, 566, -733, 844, -945, 774, -891, +452, -745, -65, -473, -614, -169, -865, -36, +-693, -27, -267, 12, 181, 125, 519, 332, +661, 649, 470, 953, -15, 1032, -496, 836, +-756, 402, -761, -285, -488, -1050, -2, -1614, +557, -1800, 1043, -1506, 1207, -776, 844, 221, +73, 1269, -777, 2031, -1427, 2256, -1651, 1905, +-1288, 1012, -471, -205, 473, -1359, 1281, -2112, +1702, -2319, 1548, -1947, 889, -1096, -7, 14, +-909, 1125, -1596, 1958, -1790, 2206, -1376, 1832, +-484, 1113, 573, 230, 1394, -708, 1679, -1512, +1333, -1947, 526, -1815, -383, -1213, -1092, -485, +-1447, 266, -1352, 1068, -816, 1652, -27, 1744, +738, 1416, 1207, 805, 1265, 7, 945, -732, +337, -1244, -374, -1532, -931, -1494, -1116, -1046, +-941, -408, -598, 222, -220, 853, 131, 1334, +414, 1475, 581, 1320, 606, 916, 542, 230, +457, -532, 308, -1094, 52, -1412, -203, -1500, +-399, -1254, -629, -630, -836, 172, -855, 859, +-708, 1288, -435, 1432, 41, 1258, 666, 789, +1181, 140, 1390, -465, 1265, -847, 785, -974, +-23, -934, -886, -804, -1494, -539, -1746, -165, +-1581, 149, -965, 360, -45, 540, 853, 694, +1484, 830, 1761, 849, 1592, 621, 928, 225, +-62, -187, -1053, -578, -1681, -916, -1706, -1095, +-1211, -1002, -455, -638, 382, -183, 1081, 199, +1327, 555, 1037, 941, 445, 1101, -196, 894, +-715, 576, -937, 269, -782, -146, -347, -550, +183, -744, 629, -781, 839, -728, 691, -564, +207, -330, -428, -91, -959, 137, -1177, 334, +-1012, 497, -488, 605, 281, 632, 1061, 637, +1588, 642, 1644, 502, 1144, 150, 229, -275, +-847, -737, -1803, -1224, -2334, -1511, -2215, -1393, +-1412, -897, -88, -111, 1376, 784, 2527, 1529, +3018, 1982, 2655, 2007, 1462, 1476, -254, 526, +-1990, -581, -3259, -1583, -3652, -2137, -2946, -2086, +-1365, -1549, 559, -660, 2348, 391, 3582, 1207, +3801, 1525, 2847, 1457, 1095, 1122, -882, 585, +-2596, 71, -3606, -278, -3588, -486, -2508, -515, +-736, -431, 1106, -422, 2485, -536, 3089, -721, +2790, -859, 1721, -763, 249, -350, -1195, 308, +-2198, 1088, -2475, 1769, -1971, 2064, -891, 1784, +403, 951, 1474, -270, 1909, -1541, 1603, -2444, +781, -2764, -307, -2391, -1334, -1284, -1848, 236, +-1617, 1649, -798, 2608, 290, 2851, 1359, 2297, +2088, 1194, 2154, -65, 1456, -1162, 234, -1847, +-1124, -2015, -2283, -1745, -2890, -1186, -2663, -572, +-1602, -80, -27, 346, 1605, 806, 2837, 1190, +3339, 1457, 2947, 1661, 1733, 1652, 23, 1226, +-1701, 389, -3003, -738, -3585, -1903, -3255, -2714, +-2019, -2925, -245, -2428, 1538, -1229, 2908, 365, +3477, 1887, 3052, 3054, 1834, 3613, 243, 3276, +-1300, 2056, -2400, 355, -2790, -1438, -2474, -3018, +-1618, -3915, -432, -3764, 751, -2641, 1533, -911, +1776, 1009, 1595, 2663, 1112, 3617, 488, 3597, +-51, 2667, -405, 1164, -632, -517, -795, -1947, +-928, -2783, -1000, -2863, -907, -2226, -607, -1135, +-181, 55, 366, 1074, 989, 1715, 1419, 1862, +1433, 1561, 1140, 977, 636, 266, -201, -418, +-1187, -874, -1850, -1048, -1991, -999, -1651, -697, +-796, -214, 438, 183, 1613, 446, 2308, 630, +2326, 625, 1624, 399, 365, 87, -1035, -224, +-2151, -516, -2681, -703, -2415, -704, -1368, -490, +111, -64, 1562, 497, 2558, 1021, 2793, 1362, +2188, 1360, 945, 933, -559, 202, -1911, -713, +-2717, -1678, -2736, -2327, -2023, -2327, -858, -1710, +455, -621, 1665, 789, 2508, 2138, 2739, 3012, +2251, 3243, 1185, 2727, -91, 1423, -1305, -355, +-2335, -2094, -2889, -3425, -2683, -4046, -1841, -3675, +-653, -2335, 765, -355, 2120, 1762, 2919, 3442, +2989, 4267, 2432, 4076, 1258, 2896, -306, 1026, +-1684, -1014, -2604, -2750, -3032, -3760, -2768, -3806, +-1796, -2986, -507, -1591, 783, 71, 1947, 1586, +2691, 2568, 2726, 2925, 2123, 2716, 1126, 1941, +-10, 799, -1027, -314, -1740, -1209, -2085, -1806, +-2064, -1996, -1737, -1806, -1212, -1347, -499, -677, +366, 27, 1200, 563, 1846, 992, 2254, 1403, +2295, 1561, 1829, 1321, 937, 908, -201, 386, +-1435, -348, -2561, -1080, -3229, -1480, -3121, -1524, +-2199, -1246, -673, -617, 1126, 225, 2765, 949, +3779, 1325, 3784, 1304, 2728, 884, 993, 160, +-930, -603, -2665, -1058, -3785, -1053, -3829, -701, +-2801, -138, -1161, 539, 671, 1058, 2332, 1115, +3312, 762, 3277, 265, 2432, -298, 1121, -898, +-411, -1263, -1767, -1197, -2516, -825, -2560, -332, +-2076, 237, -1229, 763, -155, 1076, 941, 1160, +1777, 1094, 2103, 857, 1912, 440, 1353, -51, +529, -551, -422, -1021, -1257, -1367, -1729, -1468, +-1800, -1294, -1517, -868, -915, -243, -87, 482, +764, 1192, 1402, 1775, 1671, 2047, 1533, 1862, +1069, 1260, 396, 329, -331, -766, -941, -1727, +-1304, -2299, -1380, -2362, -1226, -1869, -878, -964, +-330, 46, 302, 937, 823, 1622, 1148, 1973, +1274, 1889, 1152, 1496, 776, 966, 286, 385, +-211, -197, -650, -765, -1013, -1316, -1293, -1760, +-1375, -2005, -1089, -1972, -504, -1551, 106, -697, +696, 466, 1309, 1707, 1673, 2753, 1527, 3248, +1030, 2942, 398, 1885, -360, 343, -1147, -1378, +-1683, -2883, -1764, -3707, -1391, -3553, -733, -2478, +33, -838, 784, 944, 1359, 2430, 1582, 3215, +1393, 3103, 925, 2243, 297, 938, -386, -448, +-943, -1518, -1250, -2041, -1280, -2003, -1015, -1484, +-504, -673, 59, 102, 518, 574, 816, 713, +911, 674, 802, 524, 548, 284, 203, 97, +-154, 135, -416, 299, -531, 333, -533, 202, +-466, -15, -380, -315, -309, -588, -208, -676, +-32, -615, 208, -376, 450, 124, 716, 640, +968, 816, 989, 649, 610, 285, -87, -252, +-847, -825, -1499, -1134, -1876, -987, -1714, -403, +-920, 461, 243, 1278, 1402, 1787, 2255, 1828, +2535, 1254, 2098, 144, 1085, -1094, -246, -2068, +-1638, -2540, -2722, -2381, -3071, -1612, -2567, -382, +-1450, 979, 57, 2039, 1652, 2575, 2804, 2657, +3130, 2261, 2712, 1318, 1742, 86, 345, -1104, +-1126, -2140, -2221, -2821, -2721, -2885, -2634, -2381, +-2024, -1412, -1040, -85, 101, 1270, 1168, 2310, +1879, 2903, 2084, 2913, 1965, 2285, 1655, 1245, +1055, 47, 232, -1151, -558, -2078, -1213, -2486, +-1747, -2432, -2032, -1995, -1960, -1222, -1533, -315, +-804, 517, 113, 1207, 1010, 1656, 1731, 1811, +2204, 1758, 2287, 1542, 1907, 1176, 1155, 710, +170, 137, -908, -596, -1826, -1388, -2338, -2111, +-2411, -2667, -2153, -2831, -1556, -2344, -575, -1238, +625, 265, 1692, 1958, 2425, 3475, 2807, 4333, +2720, 4210, 2025, 3104, 819, 1194, -568, -1170, +-1868, -3413, -2893, -4837, -3405, -5078, -3175, -4179, +-2206, -2320, -716, 137, 1004, 2489, 2541, 4042, +3438, 4534, 3486, 4022, 2797, 2684, 1548, 855, +-32, -925, -1529, -2192, -2522, -2771, -2923, -2734, +-2803, -2242, -2154, -1506, -1049, -791, 210, -201, +1279, 353, 2017, 897, 2336, 1368, 2172, 1812, +1597, 2165, 814, 2171, -39, 1672, -890, 782, +-1533, -359, -1780, -1608, -1666, -2616, -1321, -3033, +-799, -2786, -155, -1944, 474, -603, 938, 924, +1200, 2179, 1317, 2861, 1307, 2912, 1070, 2329, +563, 1206, -107, -98, -757, -1195, -1241, -1903, +-1482, -2142, -1431, -1907, -1101, -1368, -483, -698, +278, 11, 911, 615, 1276, 959, 1396, 1130, +1224, 1248, 685, 1192, -45, 892, -641, 480, +-949, 46, -996, -407, -816, -825, -472, -1143, +-75, -1254, 276, -1063, 505, -624, 499, -120, +290, 346, 36, 736, -193, 941, -353, 874, +-276, 606, 101, 318, 508, 154, 749, 127, +820, 113, 631, 23, 38, -174, -762, -495, +-1401, -923, -1745, -1318, -1692, -1434, -1074, -1092, +42, -311, 1305, 727, 2331, 1775, 2804, 2514, +2509, 2629, 1469, 1947, -42, 589, -1661, -1055, +-2949, -2482, -3490, -3262, -3098, -3162, -1900, -2186, +-200, -611, 1595, 1093, 2965, 2460, 3562, 3156, +3303, 3003, 2276, 2107, 672, 776, -1061, -672, +-2390, -1888, -3051, -2473, -3030, -2333, -2356, -1701, +-1180, -786, 121, 195, 1210, 890, 1970, 1115, +2289, 1034, 2048, 827, 1397, 592, 669, 457, +84, 500, -402, 584, -800, 522, -1028, 236, +-1158, -282, -1349, -995, -1540, -1729, -1457, -2141, +-1003, -2012, -260, -1330, 674, -189, 1683, 1177, +2511, 2363, 2879, 3040, 2618, 3024, 1662, 2248, +159, 886, -1526, -681, -2969, -2131, -3793, -3205, +-3726, -3545, -2689, -2977, -900, -1714, 1132, -88, +2845, 1585, 3827, 2870, 3902, 3392, 3009, 3048, +1312, 2002, -671, 605, -2350, -790, -3317, -1900, +-3374, -2468, -2481, -2346, -974, -1702, 594, -838, +1795, 48, 2352, 765, 2100, 1106, 1181, 1090, +49, 863, -882, 559, -1360, 366, -1245, 321, +-600, 295, 270, 253, 1006, 195, 1365, -32, +1217, -447, 502, -861, -542, -1152, -1464, -1275, +-1905, -1109, -1804, -617, -1248, 83, -283, 859, +872, 1491, 1844, 1767, 2289, 1628, 2128, 1087, +1470, 233, 499, -632, -590, -1275, -1570, -1632, +-2122, -1608, -2074, -1135, -1556, -355, -783, 446, +97, 1033, 883, 1241, 1332, 1064, 1388, 602, +1185, -50, 830, -681, 421, -935, 48, -721, +-212, -236, -379, 355, -499, 886, -584, 1139, +-683, 1001, -764, 469, -762, -378, -613, -1235, +-340, -1775, 40, -1852, 522, -1411, 991, -467, +1279, 710, 1278, 1729, 990, 2342, 479, 2374, +-145, 1760, -711, 661, -1076, -586, -1199, -1657, +-1125, -2272, -901, -2321, -516, -1834, -59, -923, +358, 155, 679, 1078, 885, 1639, 980, 1760, +962, 1437, 813, 833, 496, 194, 136, -315, +-229, -657, -693, -755, -1118, -587, -1214, -345, +-1037, -241, -845, -249, -547, -270, 36, -327, +675, -390, 1066, -306, 1226, -52, 1259, 231, +1116, 547, 705, 909, 103, 1122, -507, 1056, +-973, 817, -1285, 472, -1389, -56, -1195, -745, +-785, -1382, -271, -1736, 323, -1768, 932, -1490, +1304, -881, 1336, 16, 1113, 996, 703, 1866, +167, 2463, -334, 2521, -670, 1919, -867, 933, +-945, -215, -842, -1488, -587, -2504, -293, -2824, +-15, -2491, 251, -1732, 457, -617, 479, 602, +389, 1550, 388, 2119, 520, 2324, 627, 2058, +601, 1398, 473, 647, 168, -58, -396, -714, +-1069, -1291, -1512, -1727, -1606, -1970, -1370, -1956, +-713, -1627, 322, -922, 1380, 99, 2089, 1227, +2274, 2193, 1857, 2727, 898, 2630, -307, 1874, +-1408, 655, -2111, -705, -2197, -1834, -1711, -2437, +-870, -2428, 118, -1867, 1048, -870, 1656, 226, +1798, 1011, 1498, 1360, 792, 1305, -78, 897, +-812, 360, -1285, 31, -1426, -20, -1084, 92, +-388, 295, 253, 489, 667, 443, 912, 14, +937, -651, 671, -1249, 237, -1588, -205, -1617, +-595, -1215, -833, -317, -811, 793, -589, 1656, +-239, 2073, 183, 2015, 557, 1452, 712, 532, +674, -422, 611, -1145, 513, -1474, 283, -1370, +-63, -1035, -409, -667, -743, -277, -1016, 80, +-1077, 199, -852, 143, -420, 199, 109, 422, +667, 680, 1155, 927, 1408, 1116, 1311, 1094, +907, 781, 337, 199, -289, -553, -886, -1264, +-1291, -1694, -1386, -1770, -1169, -1517, -780, -954, +-354, -163, 71, 661, 497, 1292, 897, 1635, +1140, 1715, 1175, 1522, 1070, 1032, 874, 420, +519, -111, -14, -581, -593, -1058, -1073, -1422, +-1400, -1584, -1550, -1601, -1480, -1416, -1151, -917, +-567, -170, 227, 669, 1097, 1496, 1828, 2142, +2285, 2430, 2336, 2270, 1872, 1648, 915, 631, +-332, -595, -1602, -1780, -2608, -2686, -3033, -3063, +-2757, -2778, -1859, -1898, -555, -620, 879, 795, +2109, 2028, 2872, 2821, 2996, 3001, 2405, 2565, +1275, 1694, -2, 550, -1153, -703, -2054, -1733, +-2478, -2283, -2258, -2406, -1546, -2154, -673, -1522, +183, -676, 912, 142, 1401, 890, 1531, 1510, +1298, 1827, 833, 1850, 330, 1675, -49, 1241, +-266, 543, -358, -250, -415, -989, -445, -1561, +-425, -1863, -436, -1828, -558, -1470, -650, -847, +-530, -64, -250, 743, 87, 1412, 509, 1745, +925, 1663, 1113, 1315, 1050, 814, 822, 96, +392, -686, -267, -1188, -863, -1314, -1117, -1211, +-1056, -912, -822, -390, -406, 193, 162, 602, +591, 765, 645, 685, 417, 365, 163, -6, +-67, -238, -279, -321, -285, -268, 19, -20, +430, 330, 701, 581, 787, 666, 677, 591, +263, 314, -402, -139, -1026, -645, -1385, -1124, +-1407, -1430, -1119, -1399, -544, -1023, 220, -354, +1030, 595, 1616, 1593, 1756, 2253, 1493, 2354, +946, 1879, 170, 919, -684, -372, -1295, -1687, +-1512, -2623, -1391, -2836, -1002, -2271, -434, -1173, +117, 120, 491, 1345, 663, 2188, 678, 2381, +606, 1913, 542, 1035, 529, 108, 536, -639, +488, -1117, 267, -1220, -119, -939, -575, -539, +-947, -262, -1123, -143, -1076, -142, -835, -214, +-400, -246, 201, -101, 776, 249, 1169, 727, +1332, 1140, 1191, 1289, 715, 1122, 62, 655, +-552, -94, -996, -896, -1127, -1474, -883, -1711, +-443, -1512, 19, -891, 412, -102, 601, 642, +520, 1241, 275, 1480, -4, 1256, -276, 787, +-426, 282, -395, -247, -209, -654, 107, -755, +480, -654, 786, -483, 882, -254, 722, -87, +310, -80, -263, -76, -843, 2, -1292, 71, +-1465, 157, -1232, 375, -618, 603, 178, 634, +953, 448, 1569, 140, 1798, -215, 1488, -533, +813, -713, 46, -720, -679, -513, -1260, -114, +-1445, 308, -1210, 554, -793, 605, -325, 513, +180, 244, 569, -154, 678, -478, 593, -600, +420, -521, 231, -215, 123, 216, 157, 571, +305, 757, 476, 753, 507, 468, 279, -53, +-166, -585, -701, -971, -1221, -1125, -1519, -947, +-1393, -457, -877, 176, -94, 800, 826, 1214, +1644, 1258, 2036, 976, 1959, 490, 1505, -169, +677, -808, -400, -1112, -1385, -1052, -1971, -796, +-2122, -395, -1860, 108, -1190, 491, -258, 622, +684, 548, 1447, 356, 1896, 151, 1900, 57, +1468, 58, 770, 73, -34, 107, -772, 129, +-1263, 30, -1418, -191, -1248, -414, -839, -599, +-311, -707, 162, -627, 508, -326, 666, 87, +614, 528, 484, 931, 393, 1144, 303, 1037, +188, 627, 148, 38, 120, -563, -6, -994, +-163, -1188, -311, -1123, -520, -761, -702, -180, +-676, 377, -443, 755, -144, 935, 191, 885, +555, 612, 834, 238, 900, -82, 715, -297, +379, -371, -8, -324, -359, -265, -622, -293, +-715, -363, -623, -368, -414, -257, -117, -71, +173, 163, 323, 444, 326, 659, 318, 684, +286, 488, 125, 167, -58, -162, -76, -416, +5, -556, 38, -535, 67, -354, 143, -86, +118, 146, -66, 245, -253, 211, -360, 84, +-379, -53, -288, -121, -74, -80, 163, 64, +358, 263, 471, 403, 424, 398, 233, 237, +27, -37, -105, -341, -193, -576, -224, -645, +-166, -513, -55, -230, 28, 117, 35, 443, +-15, 626, -45, 603, -68, 402, -134, 88, +-174, -240, -60, -449, 146, -437, 258, -259, +302, -24, 373, 208, 403, 370, 230, 361, +-59, 172, -293, -138, -465, -442, -568, -599, +-512, -576, -278, -375, 0, 9, 231, 496, +410, 900, 523, 1066, 514, 906, 381, 448, +174, -162, -44, -753, -227, -1210, -345, -1360, +-382, -1075, -317, -508, -180, 128, -50, 763, +50, 1243, 118, 1344, 175, 1095, 197, 626, +191, 3, 156, -629, 89, -1037, -2, -1125, +-71, -934, -56, -523, -1, -3, 15, 461, +0, 730, 29, 715, 62, 436, -8, 85, +-147, -206, -227, -381, -241, -325, -212, -19, +-101, 360, 122, 614, 369, 606, 516, 270, +526, -292, 377, -859, 113, -1210, -182, -1198, +-391, -741, -498, 40, -496, 862, -353, 1453, +-114, 1614, 113, 1271, 245, 560, 318, -283, +363, -1049, 335, -1481, 199, -1420, 42, -955, +-27, -321, -35, 315, -92, 814, -159, 1015, +-136, 862, -73, 505, -102, 124, -141, -197, +-43, -386, 66, -409, 67, -291, 55, -110, +125, 68, 139, 153, 49, 103, -18, -33, +-19, -191, 16, -328, 95, -350, 224, -193, +323, 65, 309, 348, 147, 599, -149, 684, +-488, 512, -743, 189, -833, -170, -673, -521, +-262, -771, 301, -786, 878, -569, 1313, -219, +1437, 204, 1135, 588, 510, 803, -267, 777, +-1042, 553, -1645, 188, -1790, -236, -1347, -615, +-556, -821, 263, -789, 995, -550, 1548, -170, +1663, 288, 1241, 737, 565, 991, -65, 924, +-592, 580, -950, 96, -1004, -457, -760, -955, +-390, -1194, -28, -1059, 205, -626, 244, -40, +176, 579, 115, 1064, 75, 1275, 37, 1152, +127, 710, 370, 52, 593, -581, 643, -989, +543, -1116, 286, -982, -172, -633, -701, -188, +-1070, 200, -1150, 462, -942, 598, -473, 654, +150, 659, 730, 603, 1099, 457, 1194, 224, +1005, -97, 599, -464, 104, -775, -333, -924, +-619, -882, -717, -658, -611, -248, -369, 262, +-135, 706, -38, 937, -25, 928, -26, 705, +-58, 331, -96, -91, -5, -412, 290, -544, +655, -516, 908, -381, 957, -207, 776, -64, +346, -5, -266, -26, -885, -96, -1316, -136, +-1463, -97, -1257, 27, -713, 212, 24, 445, +742, 673, 1308, 771, 1605, 659, 1494, 335, +1038, -142, 408, -659, -274, -1080, -888, -1321, +-1219, -1274, -1196, -864, -968, -178, -614, 592, +-129, 1273, 357, 1696, 631, 1697, 678, 1261, +635, 514, 553, -366, 401, -1158, 218, -1607, +57, -1642, -49, -1326, -142, -743, -234, -25, +-308, 642, -344, 1107, -310, 1284, -214, 1155, +-117, 813, -86, 358, -48, -119, 66, -509, +212, -695, 302, -695, 342, -593, 394, -434, +439, -259, 398, -111, 236, 10, 17, 111, +-166, 190, -311, 308, -482, 454, -622, 537, +-607, 506, -422, 383, -175, 154, 100, -167, +373, -469, 580, -646, 702, -670, 724, -527, +628, -244, 435, 49, 221, 276, -58, 402, +-433, 413, -750, 325, -856, 201, -820, 79, +-711, -11, -419, -43, 44, -30, 486, -22, +811, -43, 1058, -87, 1146, -178, 962, -288, +551, -337, 37, -272, -535, -112, -1023, 113, +-1230, 347, -1113, 507, -765, 499, -246, 313, +342, 54, 785, -214, 980, -438, 940, -510, +713, -366, 335, -102, -65, 164, -350, 387, +-464, 502, -413, 408, -270, 130, -130, -189, +-24, -448, 50, -573, 36, -529, -55, -336, +-73, -44, 42, 292, 133, 555, 151, 672, +211, 635, 334, 468, 360, 192, 247, -151, +122, -476, -9, -696, -198, -729, -419, -597, +-534, -378, -480, -124, -261, 155, 79, 368, +431, 473, 649, 533, 651, 592, 483, 599, +200, 504, -171, 303, -515, -21, -659, -437, +-553, -837, -271, -1081, 87, -1089, 476, -817, +763, -309, 792, 298, 530, 819, 91, 1104, +-364, 1110, -727, 867, -866, 468, -699, 33, +-271, -310, 234, -507, 647, -579, 876, -583, +868, -531, 587, -451, 97, -382, -401, -288, +-692, -114, -719, 100, -551, 290, -228, 491, +190, 701, 580, 852, 762, 882, 650, 771, +306, 465, -103, -31, -454, -636, -688, -1243, +-711, -1676, -465, -1727, -23, -1319, 442, -552, +793, 431, 942, 1399, 860, 2059, 555, 2199, +78, 1783, -457, 911, -865, -180, -1038, -1171, +-977, -1817, -682, -1973, -181, -1604, 391, -865, +832, -42, 1052, 645, 1045, 1052, 850, 1108, +493, 843, 61, 437, -322, 92, -586, -84, +-745, -73, -796, 68, -706, 211, -488, 212, +-185, 33, 99, -303, 318, -718, 503, -1078, +708, -1175, 851, -900, 845, -319, 729, 401, +513, 1094, 128, 1613, -393, 1772, -886, 1424, +-1224, 628, -1310, -310, -1079, -1139, -588, -1696, +30, -1827, 702, -1446, 1292, -685, 1617, 194, +1566, 930, 1159, 1330, 462, 1331, -397, 1000, +-1114, 473, -1470, -98, -1436, -525, -1061, -722, +-418, -686, 278, -466, 785, -158, 1025, 114, +985, 288, 670, 328, 229, 215, -133, 10, +-333, -197, -375, -328, -240, -343, 46, -216, +294, 2, 372, 242, 249, 449, -8, 556, +-329, 511, -623, 345, -732, 105, -566, -195, +-184, -492, 269, -694, 720, -720, 1049, -580, +1088, -328, 809, -2, 349, 367, -185, 662, +-690, 772, -990, 697, -945, 503, -642, 215, +-249, -141, 164, -449, 506, -629, 674, -663, +601, -545, 385, -283, 156, 21, -13, 273, +-120, 430, -153, 458, -76, 325, 48, 81, +112, -138, 99, -259, 79, -250, 43, -96, +-56, 167, -186, 421, -256, 536, -290, 417, +-294, 78, -205, -385, -3, -832, 255, -1077, +518, -967, 756, -496, 843, 169, 724, 837, +456, 1329, 79, 1464, -434, 1140, -965, 468, +-1255, -341, -1177, -1053, -828, -1461, -294, -1474, +387, -1089, 1057, -395, 1462, 392, 1452, 999, +1121, 1274, 624, 1191, 38, 821, -610, 279, +-1137, -280, -1298, -707, -1101, -895, -732, -828, +-247, -582, 336, -237, 787, 134, 911, 436, +803, 573, 633, 546, 397, 396, 128, 182, +-68, -50, -155, -233, -232, -325, -305, -345, +-298, -309, -258, -226, -247, -95, -250, 62, +-187, 233, -52, 363, 126, 409, 322, 352, +500, 210, 591, -10, 557, -272, 426, -491, +227, -588, -45, -511, -325, -270, -486, 54, +-508, 346, -460, 575, -387, 667, -194, 554, +109, 278, 391, -32, 560, -305, 613, -511, +562, -613, 367, -573, 73, -373, -207, -72, +-366, 227, -405, 440, -358, 549, -205, 497, +28, 288, 230, 30, 342, -165, 342, -257, +236, -228, 63, -125, -110, -52, -219, -46, +-246, -100, -143, -169, 34, -225, 204, -210, +324, -87, 387, 148, 366, 414, 247, 593, +73, 608, -145, 442, -357, 112, -466, -318, +-430, -697, -285, -898, -54, -808, 220, -430, +464, 68, 560, 487, 501, 756, 366, 824, +211, 637, 25, 263, -179, -120, -306, -392, +-333, -537, -287, -525, -195, -371, -75, -159, +15, 7, 74, 115, 149, 191, 244, 228, +298, 206, 318, 176, 335, 180, 317, 151, +213, 62, 7, -65, -222, -202, -398, -314, +-456, -313, -405, -193, -264, -33, -22, 127, +281, 283, 534, 352, 623, 245, 521, 16, +265, -216, -34, -359, -245, -383, -334, -251, +-325, 11, -192, 317, 10, 557, 171, 634, +230, 465, 221, 93, 166, -319, 63, -661, +-37, -871, -129, -849, -171, -526, -112, -23, +39, 485, 208, 903, 342, 1141, 398, 1050, +319, 611, 119, -7, -110, -602, -311, -1035, +-430, -1209, -404, -1046, -222, -578, 61, 43, +311, 592, 479, 907, 533, 929, 453, 721, +230, 374, -48, -10, -241, -305, -339, -409, +-363, -335, -282, -214, -98, -154, 89, -177, +211, -242, 311, -309, 370, -312, 314, -189, +228, 77, 185, 428, 105, 763, -102, 931, +-329, 807, -443, 430, -467, -85, -359, -648, +-75, -1133, 319, -1300, 664, -1048, 854, -492, +816, 182, 524, 819, 74, 1243, -410, 1300, +-794, 967, -949, 357, -833, -314, -488, -836, +45, -1085, 626, -1037, 1052, -683, 1140, -127, +890, 414, 413, 756, -138, 826, -608, 641, +-878, 266, -844, -170, -532, -499, -85, -587, +345, -436, 666, -144, 756, 160, 545, 369, +129, 387, -286, 198, -526, -75, -475, -268, +-155, -294, 282, -164, 657, 56, 795, 275, +625, 386, 177, 265, -373, -54, -844, -382, +-1051, -543, -867, -492, -347, -250, 307, 153, +881, 587, 1225, 826, 1215, 750, 810, 415, +148, -81, -502, -581, -913, -893, -964, -907, +-718, -675, -283, -278, 169, 203, 480, 616, +589, 814, 519, 804, 343, 652, 114, 369, +-52, 19, -108, -313, -102, -564, -63, -723, +23, -762, 102, -642, 92, -369, 25, -38, +-10, 286, -22, 588, -8, 802, 40, 857, +50, 741, 13, 486, -38, 83, -56, -372, +-43, -735, 51, -973, 195, -1076, 273, -920, +288, -465, 272, 117, 193, 647, 48, 1044, +-72, 1241, -157, 1136, -264, 715, -334, 88, +-275, -538, -128, -991, 56, -1158, 241, -1010, +384, -615, 404, -104, 313, 370, 198, 665, +74, 690, -5, 505, -5, 250, 43, 40, +41, -63, -26, -21, -100, 87, -188, 152, +-309, 110, -397, -64, -337, -348, -100, -634, +215, -754, 523, -634, 787, -305, 901, 150, +771, 617, 381, 944, -108, 1031, -553, 848, +-863, 432, -957, -108, -800, -603, -397, -913, +128, -1003, 603, -857, 873, -484, 881, 22, +652, 468, 286, 739, -93, 801, -356, 656, +-402, 326, -210, -85, 37, -413, 182, -554, +238, -483, 188, -230, -17, 121, -311, 409, +-471, 501, -450, 348, -323, 5, -85, -418, +297, -735, 733, -789, 1013, -550, 1021, -79, +785, 491, 359, 961, -200, 1134, -750, 964, +-1115, 501, -1202, -124, -1009, -736, -526, -1128, +114, -1169, 703, -865, 1105, -338, 1237, 226, +1054, 666, 603, 865, 104, 789, -287, 491, +-528, 120, -581, -184, -448, -323, -247, -300, +-130, -166, -128, -2, -147, 105, -142, 104, +-85, -14, 43, -227, 236, -449, 498, -528, +741, -422, 839, -173, 718, 191, 481, 631, +160, 954, -303, 992, -769, 752, -1030, 294, +-1049, -303, -874, -853, -475, -1146, 95, -1121, +640, -798, 1044, -277, 1250, 289, 1162, 712, +813, 871, 322, 758, -177, 469, -594, 136, +-835, -119, -835, -197, -648, -121, -343, -10, +-47, 50, 152, 24, 219, -181, 215, -521, +253, -776, 359, -777, 482, -546, 588, -126, +633, 446, 548, 1017, 296, 1365, -58, 1340, +-426, 950, -765, 281, -963, -493, -948, -1157, +-694, -1537, -263, -1553, 274, -1165, 807, -435, +1157, 384, 1224, 1012, 1025, 1329, 656, 1327, +158, 987, -376, 424, -773, -167, -949, -614, +-942, -819, -731, -756, -322, -524, 140, -245, +452, 2, 604, 154, 681, 171, 633, 70, +457, -53, 255, -104, 142, -23, 37, 163, +-123, 401, -258, 600, -313, 655, -338, 506, +-358, 167, -298, -310, -135, -802, 38, -1093, +172, -1075, 317, -760, 474, -219, 562, 408, +494, 886, 346, 1101, 168, 1052, -51, 762, +-281, 294, -439, -210, -487, -614, -451, -851, +-281, -877, -16, -730, 220, -432, 396, -8, +549, 429, 613, 695, 489, 741, 225, 596, +-46, 307, -296, -43, -507, -369, -589, -572, +-432, -557, -56, -327, 320, -31, 566, 230, +647, 422, 553, 483, 264, 344, -117, 76, +-388, -198, -499, -401, -484, -472, -323, -391, +-11, -200, 320, 28, 530, 249, 619, 413, +580, 486, 327, 428, -53, 250, -372, 1, +-521, -247, -521, -434, -342, -516, 2, -458, +302, -254, 448, 45, 487, 307, 461, 445, +291, 444, -15, 323, -286, 83, -412, -193, +-410, -382, -264, -417, 34, -285, 364, -30, +544, 232, 523, 383, 351, 399, 75, 277, +-186, 49, -359, -207, -399, -373, -310, -410, +-130, -339, 75, -192, 238, -9, 352, 143, +373, 247, 285, 351, 153, 412, 41, 351, +-32, 194, -53, 49, -19, -112, 14, -322, +-36, -482, -106, -486, -136, -372, -146, -214, +-126, -18, -25, 196, 144, 363, 257, 425, +312, 417, 342, 363, 311, 250, 207, 80, +95, -81, 0, -236, -105, -406, -188, -523, +-219, -514, -266, -389, -312, -176, -246, 135, +-71, 435, 120, 603, 289, 614, 482, 486, +583, 204, 499, -149, 331, -416, 186, -508, +25, -419, -200, -198, -377, 62, -468, 231, +-527, 237, -493, 84, -294, -136, -4, -322, +294, -351, 569, -151, 755, 198, 752, 513, +614, 687, 398, 672, 82, 412, -271, -58, +-562, -576, -702, -931, -698, -990, -536, -723, +-241, -247, 85, 285, 354, 741, 532, 982, +643, 895, 687, 509, 631, 11, 466, -412, +197, -640, -163, -651, -525, -455, -763, -137, +-773, 168, -580, 329, -232, 312, 169, 145, +491, -77, 666, -218, 683, -216, 593, -87, +390, 111, 102, 320, -173, 436, -347, 389, +-405, 189, -382, -97, -288, -402, -137, -609, +18, -623, 162, -432, 298, -88, 408, 291, +436, 586, 344, 690, 196, 561, -4, 237, +-233, -150, -413, -443, -434, -530, -293, -415, +-73, -175, 180, 93, 409, 290, 553, 348, +567, 238, 421, 29, 125, -184, -221, -315, +-487, -326, -590, -197, -512, 22, -255, 255, +71, 423, 349, 458, 529, 349, 586, 129, +516, -135, 306, -392, 45, -562, -161, -581, +-285, -419, -340, -140, -317, 193, -189, 510, +-18, 692, 84, 647, 107, 393, 109, 24, +148, -356, 200, -591, 200, -587, 187, -389, +206, -127, 248, 157, 206, 382, 74, 414, +-87, 242, -268, 14, -431, -163, -476, -276, +-322, -272, -36, -100, 267, 171, 522, 369, +628, 408, 498, 276, 219, 12, -41, -303, +-207, -545, -296, -597, -255, -426, -86, -85, +95, 312, 206, 618, 215, 705, 129, 577, +-62, 268, -256, -175, -313, -608, -183, -801, +63, -679, 291, -351, 451, 73, 515, 498, +394, 766, 116, 741, -123, 458, -208, 30, +-224, -386, -249, -640, -195, -655, -68, -486, +27, -204, 23, 129, 10, 395, 65, 488, +110, 417, 142, 257, 233, 84, 368, -23, +430, -79, 373, -118, 222, -150, -33, -170, +-331, -212, -539, -277, -616, -319, -573, -280, +-371, -113, -7, 140, 386, 408, 664, 626, +814, 739, 792, 658, 565, 362, 190, -87, +-184, -583, -460, -976, -601, -1089, -557, -876, +-379, -431, -183, 136, -6, 682, 151, 1033, +241, 1054, 254, 783, 264, 340, 310, -124, +347, -480, 399, -648, 429, -641, 334, -512, +78, -302, -272, -89, -590, 45, -812, 95, +-845, 148, -611, 222, -152, 283, 374, 320, +808, 344, 1069, 308, 1106, 191, 865, 27, +397, -153, -177, -311, -695, -411, -1000, -441, +-1011, -407, -751, -293, -329, -123, 154, 55, +523, 214, 698, 359, 724, 461, 633, 482, +453, 410, 220, 276, 3, 119, -200, -69, +-383, -283, -468, -466, -427, -559, -306, -567, +-141, -491, 26, -326, 159, -73, 236, 233, +322, 520, 398, 714, 387, 772, 327, 680, +244, 430, 104, 69, -116, -311, -293, -616, +-350, -801, -370, -815, -361, -659, -251, -377, +-38, -26, 198, 330, 378, 616, 483, 750, +506, 713, 427, 532, 257, 266, 46, -42, +-138, -327, -273, -502, -325, -514, -326, -418, +-305, -285, -227, -126, -95, 22, 60, 91, +231, 85, 429, 79, 559, 91, 548, 131, +425, 203, 204, 304, -104, 359, -380, 325, +-539, 219, -568, 40, -455, -216, -213, -499, +63, -705, 302, -764, 505, -624, 598, -287, +549, 176, 390, 627, 171, 956, -57, 1052, +-274, 830, -439, 340, -498, -235, -425, -714, +-250, -974, -46, -944, 163, -642, 387, -162, +554, 323, 582, 655, 444, 728, 232, 566, +1, 257, -237, -98, -439, -375, -527, -473, +-449, -396, -265, -192, -18, 83, 257, 311, +481, 405, 566, 347, 495, 172, 325, -70, +99, -281, -160, -392, -351, -395, -383, -275, +-287, -54, -143, 166, 7, 287, 122, 318, +158, 266, 163, 162, 138, 56, 94, -33, +98, -113, 166, -134, 233, -95, 239, -61, +182, -63, 29, -72, -206, -75, -414, -106, +-525, -124, -503, -88, -261, 8, 149, 136, +531, 258, 750, 308, 790, 257, 597, 132, +197, -20, -219, -149, -523, -224, -657, -213, +-602, -130, -359, -36, -55, 11, 199, 10, +404, -58, 503, -172, 419, -249, 242, -194, +102, 5, 4, 265, -72, 523, -80, 696, +-23, 683, 4, 416, -34, -43, -123, -549, +-206, -943, -259, -1118, -235, -979, -80, -521, +158, 95, 389, 681, 537, 1093, 558, 1208, +428, 964, 166, 472, -119, -85, -341, -553, +-495, -852, -524, -912, -401, -730, -185, -399, +75, -41, 329, 249, 478, 431, 478, 472, +387, 377, 230, 220, 53, 95, -83, 11, +-140, -25, -140, -8, -124, 37, -116, 45, +-136, -16, -165, -121, -155, -247, -98, -354, +-6, -405, 116, -362, 268, -208, 443, 58, +554, 369, 528, 623, 335, 726, 7, 626, +-383, 339, -689, -55, -769, -442, -640, -704, +-336, -746, 108, -572, 548, -242, 818, 109, +836, 358, 636, 444, 311, 390, -71, 243, +-405, 73, -591, -36, -588, -48, -412, 13, +-147, 72, 102, 62, 267, -47, 358, -199, +351, -318, 232, -349, 82, -278, -12, -99, +-53, 137, -55, 338, 18, 431, 142, 394, +206, 256, 154, 34, 8, -206, -191, -376, +-354, -409, -428, -312, -380, -109, -165, 134, +186, 317, 519, 373, 712, 292, 727, 89, +530, -159, 174, -316, -249, -336, -605, -259, +-752, -125, -635, 79, -331, 282, 11, 380, +296, 325, 470, 163, 492, -26, 403, -200, +250, -316, 76, -327, -32, -208, -53, -25, +-59, 153, -95, 259, -104, 255, -107, 152, +-141, 9, -171, -134, -166, -243, -96, -266, +39, -173, 209, 9, 352, 191, 398, 307, +342, 310, 211, 218, 24, 60, -141, -104, +-233, -216, -266, -258, -235, -248, -126, -192, +2, -114, 67, -58, 86, -9, 97, 63, +95, 174, 64, 280, 43, 358, 82, 377, +166, 306, 239, 130, 251, -120, 190, -380, +74, -584, -93, -661, -284, -577, -412, -330, +-432, 2, -337, 345, -145, 639, 112, 811, +373, 771, 568, 538, 616, 186, 511, -206, +309, -574, 31, -832, -244, -862, -430, -658, +-528, -293, -531, 124, -388, 501, -138, 726, +93, 711, 287, 477, 491, 159, 582, -125, +478, -306, 296, -336, 107, -234, -130, -73, +-360, 41, -443, 49, -387, -45, -257, -164, +-48, -247, 185, -237, 338, -121, 352, 79, +271, 309, 134, 454, -52, 443, -207, 298, +-256, 112, -203, -77, -57, -251, 132, -354, +301, -352, 411, -297, 412, -218, 248, -110, +-40, 16, -351, 143, -592, 257, -648, 316, +-460, 282, -107, 185, 279, 56, 630, -59, +840, -136, 782, -142, 485, -79, 82, 10, +-338, 60, -680, 10, -824, -120, -716, -259, +-370, -349, 102, -336, 498, -157, 683, 151, +676, 490, 476, 712, 131, 706, -202, 456, +-398, 39, -408, -410, -262, -722, -49, -765, +144, -555, 274, -195, 291, 160, 151, 384, +-65, 392, -221, 226, -290, 29, -230, -72, +-18, -33, 229, 134, 379, 345, 396, 457, +292, 358, 83, 45, -137, -370, -276, -780, +-304, -1014, -217, -892, -67, -409, 56, 237, +113, 828, 128, 1189, 123, 1181, 84, 794, +26, 166, 35, -492, 126, -967, 211, -1089, +204, -865, 104, -419, -44, 96, -217, 528, +-373, 730, -420, 667, -304, 398, -59, 29, +223, -267, 448, -392, 571, -353, 546, -192, +360, 40, 77, 229, -245, 300, -544, 256, +-671, 115, -551, -99, -275, -303, 65, -412, +433, -392, 689, -235, 682, 8, 463, 285, +147, 511, -203, 589, -509, 453, -639, 165, +-501, -184, -168, -502, 197, -640, 465, -544, +566, -278, 477, 64, 207, 387, -115, 558, +-336, 497, -432, 248, -389, -48, -230, -289, +-30, -408, 169, -383, 347, -212, 478, 47, +499, 262, 381, 350, 135, 294, -171, 158, +-421, -4, -556, -148, -552, -266, -383, -305, +-117, -213, 145, -63, 375, 34, 559, 107, +619, 193, 530, 225, 364, 168, 111, 73, +-236, 2, -529, -59, -633, -111, -569, -142, +-374, -108, -91, -16, 174, 65, 352, 97, +439, 55, 410, -76, 269, -247, 163, -327, +141, -243, 68, 16, -45, 381, -65, 677, +-78, 719, -203, 472, -318, -5, -308, -551, +-270, -935, -232, -994, -77, -698, 165, -168, +379, 425, 528, 851, 595, 970, 534, 783, +303, 371, -30, -135, -335, -543, -518, -708, +-543, -631, -441, -387, -258, -72, -69, 205, +66, 352, 173, 348, 257, 220, 309, 67, +334, -45, 319, -86, 255, -70, 164, -25, +83, 14, 11, 9, -87, -5, -207, -5, +-333, -2, -450, 8, -499, 18, -427, -27, +-210, -111, 127, -167, 469, -158, 687, -100, +728, 20, 632, 207, 443, 353, 170, 347, +-154, 207, -455, 36, -675, -132, -759, -261, +-699, -322, -505, -293, -160, -187, 292, -71, +663, 5, 790, 50, 738, 121, 608, 229, +365, 306, 39, 316, -256, 279, -475, 156, +-589, -53, -575, -304, -460, -498, -288, -556, +-38, -440, 242, -173, 399, 157, 436, 461, +444, 624, 394, 567, 262, 305, 96, -34, +-79, -325, -260, -487, -384, -476, -383, -303, +-264, -47, -63, 202, 135, 343, 234, 357, +240, 298, 155, 145, -5, -77, -147, -291, +-160, -415, -55, -437, 62, -331, 172, -81, +281, 229, 317, 500, 267, 673, 130, 659, +-125, 409, -407, 8, -547, -425, -493, -774, +-308, -924, -10, -777, 359, -392, 598, 96, +565, 536, 356, 835, 109, 928, -137, 750, +-310, 378, -318, -50, -189, -431, -26, -705, +126, -775, 233, -618, 223, -340, 73, -44, +-150, 244, -353, 416, -460, 402, -373, 299, +-61, 213, 329, 153, 647, 94, 796, 72, +687, 70, 365, 34, -65, -90, -486, -263, +-769, -423, -861, -527, -767, -506, -501, -315, +-60, 13, 470, 378, 878, 677, 1030, 805, +900, 707, 514, 420, 2, 35, -441, -376, +-679, -669, -703, -754, -577, -675, -368, -482, +-142, -182, 62, 174, 234, 466, 393, 640, +518, 665, 517, 529, 393, 265, 208, -40, +-9, -310, -191, -484, -318, -524, -429, -439, +-451, -275, -330, -75, -145, 120, 42, 271, +248, 372, 426, 385, 458, 312, 351, 175, +186, 8, -22, -167, -198, -295, -255, -333, +-228, -318, -162, -252, -66, -92, 23, 130, +65, 313, 61, 415, 50, 399, 65, 219, +87, -64, 69, -284, 51, -390, 72, -372, +45, -205, -19, 40, -26, 232, -19, 278, +-39, 218, -54, 83, -29, -60, 17, -140, +36, -145, 45, -91, 37, 22, -20, 141, +-73, 181, -78, 101, -7, -43, 110, -162, +217, -226, 283, -222, 236, -135, 56, 40, +-152, 203, -305, 266, -375, 213, -309, 95, +-128, -18, 48, -110, 207, -152, 363, -114, +423, -17, 370, 62, 241, 86, 8, 62, +-260, -25, -425, -173, -445, -266, -339, -263, +-121, -172, 168, 51, 384, 350, 417, 547, +300, 554, 117, 413, -42, 107, -138, -289, +-226, -610, -249, -760, -144, -712, 7, -443, +139, -39, 241, 357, 297, 694, 263, 887, +93, 794, -191, 446, -445, 15, -494, -439, +-322, -787, -37, -866, 267, -682, 512, -364, +626, 45, 525, 474, 243, 743, -78, 771, +-383, 588, -614, 240, -679, -195, -549, -555, +-220, -712, 224, -640, 604, -374, 779, 1, +690, 350, 384, 586, -53, 639, -443, 491, +-570, 211, -475, -130, -293, -447, -27, -666, +244, -661, 335, -416, 245, -58, 148, 285, +79, 532, -28, 611, -124, 503, -146, 269, +-111, -1, -48, -224, 58, -352, 184, -393, +241, -380, 225, -278, 127, -105, -94, 60, +-298, 155, -357, 216, -308, 243, -158, 198, +78, 145, 294, 123, 405, 107, 415, 62, +342, -27, 142, -157, -142, -281, -363, -347, +-458, -327, -407, -229, -217, -45, 34, 174, +285, 335, 441, 401, 402, 359, 220, 231, +48, 41, -77, -149, -196, -288, -263, -316, +-249, -240, -184, -122, -75, 0, 67, 91, +245, 129, 382, 119, 378, 81, 239, 33, +-13, 8, -290, 2, -442, -9, -424, -48, +-255, -55, 10, -19, 280, 16, 455, 55, +473, 98, 361, 99, 149, 18, -136, -106, +-372, -226, -484, -279, -473, -211, -281, -33, +62, 181, 377, 362, 556, 428, 583, 315, +413, 58, 67, -224, -312, -421, -589, -460, +-665, -308, -497, -74, -145, 169, 285, 377, +630, 462, 754, 342, 633, 92, 287, -142, +-167, -319, -550, -415, -730, -369, -632, -187, +-337, 36, 4, 247, 322, 399, 542, 428, +587, 316, 449, 136, 236, -92, 28, -342, +-213, -521, -433, -526, -493, -322, -403, 13, +-212, 360, 82, 562, 375, 560, 483, 385, +380, 75, 151, -271, -116, -488, -285, -534, +-311, -443, -232, -204, -31, 126, 228, 381, +413, 501, 441, 533, 297, 383, 24, 58, +-344, -269, -679, -493, -753, -599, -505, -503, +-47, -224, 480, 59, 883, 306, 965, 517, +697, 573, 254, 456, -207, 267, -610, 6, +-821, -290, -807, -501, -664, -586, -357, -579, +131, -405, 608, -68, 926, 288, 1037, 591, +808, 758, 274, 688, -285, 405, -720, 20, +-954, -409, -859, -736, -516, -785, -109, -585, +295, -260, 638, 134, 824, 486, 756, 651, +433, 597, -18, 389, -405, 119, -582, -161, +-544, -374, -333, -469, -50, -418, 138, -255, +225, -57, 246, 118, 189, 218, 133, 241, +100, 210, 27, 135, -42, 47, -52, 30, +-62, 51, -39, 31, 53, -33, 32, -118, +-112, -237, -146, -302, -60, -259, 46, -159, +143, -2, 142, 200, 39, 365, -48, 397, +-57, 331, 0, 201, 118, 16, 242, -177, +239, -334, 80, -410, -135, -359, -322, -224, +-384, -66, -309, 119, -166, 281, 60, 339, +293, 291, 420, 192, 483, 46, 441, -63, +178, -86, -154, -77, -363, -76, -479, -84, +-473, -101, -283, -163, -61, -237, 138, -240, +365, -128, 470, 83, 389, 326, 229, 499, +8, 543, -233, 401, -342, 99, -276, -255, +-119, -548, 68, -676, 190, -571, 143, -258, +37, 91, -12, 336, -58, 450, -70, 468, +-33, 392, -26, 232, 4, 47, 109, -130, +232, -269, 289, -331, 174, -329, -101, -283, +-334, -180, -403, -49, -341, 70, -96, 153, +267, 232, 443, 309, 383, 377, 250, 401, +44, 280, -187, 27, -320, -259, -356, -518, +-295, -690, -86, -658, 199, -415, 420, -52, +530, 352, 427, 703, 43, 857, -379, 753, +-577, 404, -525, -88, -274, -520, 78, -754, +403, -755, 608, -533, 553, -112, 268, 314, +-50, 526, -359, 473, -614, 234, -598, -31, +-277, -193, 126, -225, 491, -115, 702, 119, +564, 329, 193, 356, -183, 183, -499, -80, +-606, -336, -426, -512, -145, -555, 113, -401, +372, -78, 524, 283, 457, 592, 275, 752, +11, 663, -318, 318, -489, -129, -430, -529, +-249, -783, 17, -746, 285, -400, 420, 66, +386, 484, 208, 704, -29, 634, -211, 332, +-320, -104, -343, -527, -194, -722, 82, -564, +326, -184, 477, 276, 433, 693, 104, 846, +-301, 624, -542, 125, -557, -475, -314, -932, +89, -996, 437, -659, 614, -88, 603, 566, +353, 1061, -45, 1116, -386, 742, -619, 104, +-682, -603, -482, -1114, -111, -1217, 329, -875, +714, -183, 797, 639, 573, 1240, 236, 1373, +-178, 1010, -550, 280, -646, -571, -539, -1244, +-391, -1491, -105, -1186, 267, -446, 481, 419, +555, 1124, 502, 1451, 227, 1281, -81, 671, +-253, -134, -345, -899, -301, -1337, -80, -1232, +79, -676, 59, 67, 29, 733, -2, 1075, +-96, 989, -114, 568, -46, -61, 12, -676, +120, -951, 287, -789, 396, -351, 370, 246, +206, 788, -70, 991, -402, 790, -643, 289, +-640, -394, -393, -1006, -31, -1178, 356, -866, +665, -253, 709, 484, 480, 1091, 168, 1280, +-190, 990, -526, 362, -613, -406, -450, -1071, +-161, -1341, 227, -1070, 540, -393, 554, 420, +350, 1080, 67, 1334, -315, 1061, -610, 396, +-595, -420, -399, -1103, -106, -1334, 322, -1022, +678, -352, 793, 438, 709, 1089, 411, 1309, +-95, 1034, -587, 435, -860, -344, -898, -1057, +-679, -1311, -224, -1059, 284, -500, 683, 251, +868, 950, 793, 1246, 493, 1082, 53, 622, +-364, -65, -600, -774, -625, -1180, -448, -1152, +-127, -729, 180, -47, 353, 644, 390, 1102, +272, 1203, 6, 879, -227, 208, -299, -518, +-271, -1012, -127, -1130, 153, -849, 409, -305, +482, 325, 340, 809, 82, 942, -166, 748, +-336, 350, -395, -161, -357, -580, -247, -670, +-95, -487, 76, -184, 225, 190, 312, 454, +356, 430, 316, 234, 147, -30, -3, -332, +-53, -474, -119, -346, -199, -116, -208, 149, +-217, 443, -255, 544, -166, 431, 51, 260, +244, -7, 361, -350, 360, -529, 198, -504, +11, -389, -114, -170, -214, 114, -237, 304, +-166, 381, -76, 379, 1, 254, 115, 89, +239, -28, 277, -124, 210, -199, 69, -169, +-110, -37, -280, 87, -370, 126, -309, 68, +-163, -39, -20, -186, 173, -351, 364, -404, +425, -257, 400, 46, 332, 413, 133, 684, +-151, 746, -353, 626, -487, 348, -554, -115, +-444, -615, -220, -914, 15, -978, 293, -807, +525, -390, 587, 146, 504, 649, 329, 1028, +99, 1134, -122, 876, -298, 400, -440, -132, +-514, -650, -470, -992, -328, -1010, -107, -736, +173, -278, 444, 226, 617, 652, 579, 880, +349, 813, 63, 462, -232, -33, -473, -487, +-518, -741, -369, -680, -144, -335, 140, 148, +416, 604, 481, 835, 321, 694, 49, 257, +-294, -294, -540, -781, -520, -1005, -326, -850, +-37, -385, 370, 272, 720, 930, 775, 1247, +547, 1085, 169, 562, -285, -153, -680, -834, +-855, -1205, -773, -1131, -436, -673, 54, 8, +466, 673, 705, 1060, 768, 1047, 630, 693, +311, 140, -108, -440, -505, -891, -748, -1019, +-724, -737, -424, -187, 49, 413, 504, 894, +720, 1066, 628, 817, 290, 271, -160, -389, +-514, -936, -647, -1118, -533, -875, -209, -308, +155, 425, 419, 1010, 581, 1153, 601, 854, +407, 265, 75, -465, -269, -1024, -567, -1085, +-681, -686, -489, -33, -174, 638, 105, 1035, +374, 979, 505, 519, 381, -162, 159, -789, +-35, -1072, -178, -920, -201, -404, -119, 322, +-30, 970, 60, 1246, 135, 1036, 122, 407, +41, -372, -88, -1006, -243, -1313, -309, -1160, +-251, -510, -123, 346, 51, 994, 240, 1286, +391, 1162, 454, 632, 398, -74, 214, -727, +-47, -1167, -281, -1167, -431, -698, -465, -26, +-401, 624, -296, 1061, -120, 1042, 106, 603, +246, -6, 340, -638, 470, -1029, 508, -893, +400, -319, 198, 376, -115, 949, -439, 1139, +-579, 811, -571, 146, -496, -641, -260, -1316, +80, -1495, 331, -1029, 498, -151, 601, 843, +511, 1633, 217, 1875, -110, 1439, -359, 484, +-482, -685, -405, -1649, -175, -2038, 81, -1741, +266, -835, 263, 385, 104, 1450, -88, 1976, +-263, 1793, -313, 972, -194, -148, 7, -1136, +286, -1670, 542, -1554, 560, -789, 371, 277, +74, 1141, -369, 1484, -780, 1212, -835, 440, +-582, -536, -213, -1303, 287, -1509, 762, -1067, +914, -175, 757, 843, 383, 1614, -197, 1757, +-738, 1208, -950, 241, -839, -855, -437, -1744, +226, -2008, 792, -1488, 966, -387, 769, 891, +263, 1858, -378, 2116, -823, 1568, -884, 408, +-625, -931, -202, -1866, 280, -2030, 701, -1398, +872, -178, 710, 1154, 291, 2002, -237, 2057, +-678, 1330, -878, 26, -783, -1351, -392, -2230, +196, -2308, 698, -1497, 836, -14, 622, 1529, +224, 2508, -246, 2577, -575, 1701, -575, 200, +-359, -1312, -79, -2277, 249, -2407, 438, -1685, +307, -437, 54, 839, -166, 1704, -380, 1868, +-401, 1358, -137, 493, 161, -395, 393, -1000, +593, -1075, 551, -688, 139, -117, -353, 413, +-700, 652, -902, 464, -795, 38, -306, -391, +307, -659, 810, -580, 1075, -178, 950, 276, +469, 644, -122, 885, -626, 820, -940, 420, +-951, -107, -639, -603, -178, -890, 260, -817, +598, -492, 710, -65, 500, 370, 129, 601, +-156, 519, -294, 294, -252, 54, -5, -137, +231, -119, 242, 78, 76, 203, -187, 186, +-502, 89, -662, -97, -503, -338, -194, -517, +131, -549, 524, -359, 837, 42, 845, 493, +570, 837, 129, 923, -394, 633, -834, 67, +-983, -559, -771, -1029, -296, -1103, 241, -686, +611, 32, 705, 759, 561, 1247, 225, 1263, +-188, 769, -453, -33, -487, -887, -365, -1471, +-140, -1517, 155, -1006, 425, -98, 513, 942, +377, 1698, 97, 1841, -235, 1373, -522, 472, +-646, -576, -545, -1392, -294, -1756, 19, -1605, +323, -937, 521, -4, 557, 800, 445, 1294, +251, 1424, 57, 1137, -140, 609, -332, 72, +-454, -451, -464, -803, -381, -798, -274, -641, +-140, -565, 47, -448, 227, -181, 359, 127, +445, 424, 443, 740, 314, 993, 77, 1041, +-190, 771, -403, 192, -512, -499, -441, -1108, +-192, -1495, 58, -1428, 178, -799, 205, 151, +169, 1076, 33, 1726, -145, 1847, -218, 1304, +-170, 267, -81, -893, 87, -1797, 361, -2088, +536, -1573, 473, -451, 225, 827, -210, 1855, +-703, 2246, -949, 1785, -864, 657, -521, -704, +39, -1856, 614, -2325, 918, -1799, 909, -556, +700, 784, 268, 1810, -342, 2203, -803, 1686, +-941, 452, -826, -889, -436, -1804, 174, -1953, +675, -1264, 832, -66, 672, 1137, 256, 1909, +-307, 1895, -729, 1042, -809, -240, -654, -1406, +-319, -2091, 219, -2009, 708, -1086, 892, 325, +834, 1664, 512, 2451, -149, 2367, -789, 1392, +-1049, -110, -993, -1552, -642, -2440, 2, -2497, +584, -1648, 790, -191, 720, 1240, 470, 2130, +-5, 2279, -432, 1653, -538, 465, -491, -767, +-351, -1613, 43, -1858, 468, -1374, 605, -309, +479, 798, 137, 1493, -373, 1583, -803, 981, +-928, -74, -726, -1037, -270, -1572, 288, -1539, +728, -815, 908, 348, 806, 1340, 498, 1793, +87, 1695, -328, 1042, -626, -29, -708, -1086, +-617, -1732, -419, -1779, -132, -1197, 77, -204, +44, 756, -82, 1303, -112, 1331, -36, 924, +238, 239, 689, -414, 992, -694, 937, -541, +551, -166, -109, 244, -882, 527, -1483, 499, +-1661, 145, -1361, -366, -721, -830, 124, -1019, +1034, -762, 1679, -185, 1760, 481, 1351, 1098, +616, 1410, -375, 1177, -1284, 563, -1646, -121, +-1415, -706, -819, -1031, -33, -1003, 651, -728, +947, -319, 833, 172, 390, 518, -245, 556, +-707, 425, -750, 224, -477, -43, 3, -186, +590, -63, 1001, 199, 1032, 472, 709, 644, +46, 527, -823, 101, -1485, -425, -1658, -909, +-1366, -1240, -652, -1213, 329, -731, 1188, 45, +1645, 883, 1629, 1528, 1162, 1714, 369, 1398, +-503, 709, -1150, -198, -1416, -1080, -1382, -1575, +-1064, -1470, -434, -933, 282, -284, 784, 349, +1013, 860, 988, 1036, 694, 837, 257, 462, +-184, 58, -581, -303, -786, -438, -731, -287, +-570, -49, -316, 127, 62, 215, 370, 143, +513, -34, 569, -174, 443, -296, 100, -345, +-223, -183, -436, 66, -606, 231, -651, 351, +-462, 381, -132, 241, 162, 85, 400, -2, +601, -154, 621, -245, 423, -46, 148, 227, +-174, 299, -506, 206, -702, 0, -743, -293, +-683, -536, -430, -662, -5, -614, 341, -295, +559, 234, 781, 767, 828, 1162, 508, 1304, +76, 1057, -295, 447, -695, -353, -989, -1140, +-941, -1652, -653, -1666, -271, -1184, 229, -333, +691, 622, 825, 1332, 655, 1652, 396, 1578, +53, 1077, -350, 271, -568, -529, -535, -1080, +-418, -1267, -239, -1057, -25, -570, 84, -28, +84, 415, 26, 628, -88, 538, -155, 271, +-25, 21, 219, -110, 356, -73, 400, 115, +378, 357, 48, 560, -517, 587, -871, 316, +-930, -194, -825, -752, -414, -1171, 272, -1270, +852, -938, 1156, -230, 1177, 648, 770, 1416, +-44, 1782, -893, 1568, -1435, 871, -1519, -46, +-1125, -916, -383, -1518, 465, -1693, 1154, -1344, +1445, -551, 1226, 372, 592, 1077, -247, 1374, +-1017, 1254, -1462, 807, -1417, 166, -811, -456, +106, -824, 853, -841, 1245, -583, 1210, -206, +585, 144, -362, 362, -1039, 412, -1247, 344, +-1098, 249, -591, 145, 184, 11, 910, -136, +1300, -203, 1194, -187, 580, -216, -277, -287, +-1031, -217, -1505, 56, -1497, 386, -907, 629, +-43, 730, 714, 660, 1244, 331, 1397, -233, +1014, -807, 311, -1167, -365, -1210, -949, -858, +-1362, -114, -1305, 756, -746, 1395, -57, 1647, +503, 1470, 863, 824, 880, -127, 554, -1068, +106, -1672, -273, -1725, -476, -1264, -476, -479, +-364, 444, -221, 1204, -49, 1539, 121, 1457, +123, 1019, -92, 285, -276, -495, -312, -1022, +-264, -1221, -59, -1096, 279, -644, 476, -3, +430, 623, 268, 1050, -1, 1090, -370, 786, +-595, 339, -559, -252, -482, -840, -407, -1067, +-159, -918, 164, -603, 346, -79, 405, 603, +359, 1118, 190, 1313, 59, 1210, 20, 788, +-82, 91, -233, -723, -313, -1465, -437, -1819, +-652, -1640, -662, -1088, -384, -205, -110, 980, +196, 2003, 679, 2431, 980, 2246, 854, 1494, +503, 284, 26, -1056, -593, -2167, -1136, -2755, +-1313, -2583, -1070, -1705, -550, -391, 104, 1084, +666, 2325, 920, 2905, 907, 2702, 699, 1807, +264, 379, -249, -1137, -602, -2241, -787, -2660, +-784, -2304, -518, -1314, -148, -32, 98, 1216, +239, 2065, 282, 2199, 101, 1652, -118, 664, +-60, -506, 111, -1441, 161, -1738, 223, -1409, +207, -649, -99, 373, -485, 1275, -730, 1619, +-826, 1345, -664, 631, -217, -310, 338, -1167, +845, -1621, 1137, -1513, 1006, -893, 445, 37, +-305, 1001, -1064, 1678, -1659, 1789, -1712, 1308, +-1110, 453, -200, -483, 759, -1207, 1610, -1511, +1989, -1341, 1671, -776, 825, 13, -291, 706, +-1479, 1066, -2344, 1072, -2445, 714, -1796, 86, +-729, -467, 581, -731, 1820, -678, 2437, -262, +2323, 374, 1638, 877, 376, 1037, -1103, 780, +-2146, 90, -2589, -726, -2475, -1296, -1629, -1525, +-196, -1342, 1154, -621, 2029, 415, 2388, 1355, +2049, 2015, 1053, 2186, -155, 1660, -1261, 599, +-2078, -588, -2293, -1601, -1799, -2264, -803, -2388, +350, -1808, 1262, -692, 1678, 532, 1540, 1582, +900, 2292, 1, 2434, -782, 1919, -1188, 963, +-1141, -206, -747, -1347, -195, -2075, 330, -2150, +652, -1683, 607, -872, 184, 71, -384, 917, +-814, 1526, -963, 1719, -732, 1368, -125, 704, +617, 53, 1228, -494, 1464, -831, 1118, -827, +307, -550, -653, -196, -1527, 77, -2075, 119, +-2076, -79, -1478, -275, -404, -310, 843, -231, +1875, -26, 2363, 368, 2160, 835, 1347, 1152, +189, 1190, -993, 950, -1911, 375, -2332, -516, +-2186, -1397, -1598, -1927, -706, -1993, 349, -1497, +1256, -461, 1775, 755, 1909, 1798, 1628, 2433, +922, 2403, 51, 1702, -749, 633, -1406, -611, +-1816, -1828, -1879, -2532, -1512, -2473, -728, -1790, +202, -542, 1006, 986, 1566, 2090, 1722, 2456, +1340, 2214, 524, 1350, -425, -48, -1205, -1406, +-1613, -2172, -1529, -2229, -974, -1605, -121, -390, +772, 1040, 1337, 2145, 1302, 2574, 745, 2183, +-95, 952, -996, -809, -1650, -2385, -1743, -3184, +-1175, -3009, -159, -1825, 948, 155, 1836, 2247, +2159, 3716, 1660, 4115, 520, 3214, -815, 1217, +-1961, -1231, -2568, -3385, -2375, -4525, -1429, -4216, +-81, -2623, 1216, -263, 2087, 2245, 2249, 4038, +1627, 4433, 506, 3462, -697, 1547, -1591, -827, +-1854, -2835, -1463, -3723, -646, -3328, 318, -1895, +1023, 105, 1143, 1963, 686, 3001, -102, 2859, +-896, 1642, -1371, -103, -1261, -1724, -537, -2664, +466, -2531, 1321, -1367, 1764, 309, 1549, 1901, +632, 2862, -589, 2780, -1635, 1740, -2211, 156, +-2115, -1558, -1360, -2801, -244, -3035, 937, -2379, +1870, -1124, 2127, 550, 1574, 2086, 597, 2868, +-458, 2823, -1475, 2081, -2056, 788, -1786, -642, +-873, -1774, 138, -2381, 933, -2316, 1400, -1643, +1373, -665, 717, 428, -244, 1370, -1004, 1827, +-1418, 1821, -1461, 1485, -1005, 745, -187, -197, +642, -934, 1239, -1391, 1461, -1537, 1242, -1253, +627, -627, -205, 166, -982, 972, -1496, 1503, +-1700, 1573, -1543, 1224, -963, 444, -105, -638, +725, -1502, 1312, -1813, 1577, -1632, 1421, -928, +864, 239, 177, 1457, -416, 2244, -945, 2311, +-1427, 1645, -1635, 481, -1381, -918, -856, -2177, +-288, -2760, 412, -2459, 1131, -1471, 1418, 3, +1176, 1626, 773, 2736, 391, 2955, -97, 2424, +-675, 1292, -1085, -297, -1250, -1816, -1235, -2710, +-956, -2805, -389, -2201, 240, -1079, 702, 366, +933, 1729, 914, 2503, 682, 2550, 310, 2045, +-119, 1101, -506, -138, -759, -1317, -856, -2067, +-763, -2226, -419, -1847, 43, -1101, 304, -151, +261, 853, 121, 1628, -39, 1980, -236, 1945, +-276, 1520, -38, 642, 290, -439, 494, -1346, +501, -1947, 322, -2152, -26, -1793, -575, -832, +-1205, 412, -1535, 1432, -1338, 2006, -785, 2197, +85, 1871, 1266, 920, 2204, -267, 2298, -1182, +1599, -1802, 406, -2125, -1068, -1816, -2456, -930, +-3214, 31, -2958, 830, -1778, 1509, -101, 1912, +1711, 1855, 3217, 1398, 3706, 698, 2910, -166, +1257, -1069, -818, -1799, -2821, -2179, -3966, -2083, +-3855, -1437, -2704, -352, -763, 864, 1491, 1919, +3206, 2610, 3854, 2745, 3409, 2140, 1921, 905, +-234, -547, -2278, -1899, -3602, -2928, -3879, -3270, +-2997, -2621, -1264, -1201, 740, 448, 2503, 1993, +3525, 3130, 3389, 3412, 2134, 2745, 328, 1415, +-1437, -255, -2829, -1813, -3473, -2780, -3027, -3022, +-1691, -2568, -75, -1424, 1437, 31, 2625, 1260, +3046, 2137, 2475, 2620, 1260, 2388, -207, 1498, +-1703, 457, -2792, -533, -3003, -1468, -2330, -2064, +-1123, -2067, 237, -1571, 1462, -811, 2374, 45, +2632, 899, 1957, 1606, 721, 1967, -508, 1812, +-1626, 1209, -2459, 385, -2510, -562, -1730, -1506, +-597, -2075, 593, -1952, 1678, -1249, 2228, -303, +1916, 731, 951, 1712, -161, 2233, -1120, 1996, +-1828, 1129, -2069, -26, -1588, -1112, -530, -1862, +587, -2133, 1383, -1755, 1723, -704, 1551, 537, +822, 1447, -355, 1918, -1468, 1906, -1930, 1265, +-1742, 236, -1140, -693, -89, -1365, 1112, -1655, +1772, -1321, 1704, -572, 1171, 169, 260, 803, +-875, 1164, -1798, 955, -2126, 335, -1785, -169, +-894, -427, 306, -545, 1426, -355, 2052, 246, +2018, 885, 1378, 1091, 225, 747, -1134, 24, +-2111, -834, -2375, -1620, -2013, -2059, -1097, -1826, +199, -820, 1341, 684, 1952, 2165, 2056, 3112, +1586, 3221, 551, 2380, -580, 670, -1425, -1443, +-1913, -3224, -1931, -4069, -1410, -3795, -552, -2439, +346, -214, 1030, 2183, 1366, 3858, 1357, 4340, +1018, 3643, 436, 2000, -207, -174, -800, -2215, +-1245, -3503, -1324, -3754, -1027, -2942, -615, -1318, +-164, 470, 408, 1782, 866, 2493, 947, 2662, +788, 2096, 518, 896, 59, -249, -506, -902, +-900, -1279, -992, -1446, -856, -1189, -547, -680, +-48, -265, 462, 60, 668, 375, 622, 585, +535, 676, 254, 757, -242, 781, -601, 623, +-763, 322, -832, -53, -666, -475, -215, -863, +255, -1041, 582, -911, 736, -554, 631, -69, +328, 488, -15, 958, -373, 1150, -686, 1027, +-836, 600, -853, -5, -728, -511, -371, -782, +134, -874, 597, -732, 911, -343, 971, 67, +772, 293, 371, 355, -198, 336, -742, 320, +-1096, 345, -1310, 295, -1314, 219, -906, 290, +-159, 339, 672, 113, 1343, -270, 1599, -629, +1362, -918, 781, -1062, -41, -948, -958, -511, +-1620, 263, -1806, 1136, -1560, 1683, -916, 1780, +25, 1535, 920, 881, 1507, -168, 1649, -1253, +1216, -2032, 413, -2327, -364, -2004, -977, -1140, +-1377, 10, -1388, 1212, -1010, 2185, -462, 2567, +92, 2220, 582, 1358, 903, 256, 953, -904, +730, -1834, 329, -2228, -121, -2034, -450, -1403, +-577, -500, -662, 527, -789, 1355, -797, 1679, +-593, 1543, -331, 1166, -26, 606, 491, -105, +1053, -689, 1281, -845, 1135, -698, 757, -545, +113, -341, -793, -26, -1665, 91, -2129, -97, +-2076, -230, -1525, -183, -444, -104, 997, 108, +2229, 556, 2798, 946, 2622, 1048, 1677, 947, +101, 592, -1596, -73, -2863, -777, -3386, -1275, +-2963, -1532, -1638, -1451, 124, -919, 1783, -73, +2911, 759, 3125, 1378, 2342, 1676, 911, 1534, +-695, 1010, -2019, 316, -2659, -382, -2432, -961, +-1493, -1257, -199, -1221, 998, -952, 1746, -536, +1767, -49, 1003, 379, -129, 663, -1084, 794, +-1576, 776, -1449, 677, -637, 553, 524, 335, +1472, 44, 1907, -193, 1713, -421, 774, -683, +-678, -837, -2076, -806, -2938, -626, -2998, -284, +-2145, 154, -464, 512, 1581, 799, 3244, 1059, +3951, 1081, 3572, 773, 2107, 344, -185, -95, +-2499, -533, -4081, -872, -4636, -1059, -4021, -1103, +-2284, -937, 127, -549, 2551, -85, 4290, 394, +4832, 940, 4044, 1480, 2189, 1754, -274, 1599, +-2699, 1062, -4418, 202, -4952, -887, -4120, -1888, +-2152, -2421, 276, -2370, 2481, -1765, 4048, -646, +4490, 733, 3519, 1958, 1572, 2707, -655, 2754, +-2625, 2132, -3778, 1106, -3747, -140, -2624, -1407, +-855, -2281, 992, -2486, 2394, -2167, 2927, -1508, +2429, -580, 1132, 387, -446, 1152, -1804, 1666, +-2445, 1883, -2071, 1778, -904, 1499, 511, 1105, +1677, 481, 2200, -328, 1826, -1132, 697, -1822, +-719, -2308, -2035, -2407, -2850, -1961, -2688, -1039, +-1578, 157, 26, 1427, 1709, 2514, 3021, 3113, +3467, 3050, 2812, 2378, 1248, 1211, -662, -322, +-2352, -1884, -3532, -3047, -3849, -3578, -3052, -3404, +-1465, -2534, 368, -1061, 2092, 735, 3325, 2386, +3649, 3495, 3002, 3943, 1670, 3611, -5, 2378, +-1604, 558, -2765, -1266, -3392, -2759, -3267, -3746, +-2230, -3909, -681, -3071, 816, -1562, 2046, 107, +2782, 1647, 2739, 2876, 1983, 3484, 843, 3203, +-300, 2203, -1224, 911, -1886, -465, -2146, -1727, +-1856, -2490, -1162, -2587, -329, -2197, 419, -1446, +928, -366, 1140, 724, 1083, 1418, 767, 1709, +313, 1743, 71, 1422, 69, 727, -69, -25, +-437, -559, -682, -899, -757, -1073, -912, -958, +-991, -567, -631, -128, 47, 260, 590, 626, +924, 809, 1234, 605, 1264, 113, 647, -345, +-316, -664, -1126, -914, -1636, -906, -1763, -393, +-1267, 423, -181, 1116, 1040, 1576, 1953, 1808, +2278, 1519, 1830, 567, 614, -658, -990, -1755, +-2425, -2552, -3198, -2802, -3005, -2283, -1822, -1100, +20, 437, 1947, 1970, 3406, 3097, 3976, 3531, +3362, 3154, 1662, 1987, -565, 285, -2734, -1498, +-4251, -2951, -4584, -3768, -3633, -3700, -1781, -2727, +533, -1178, 2762, 523, 4141, 2096, 4268, 3311, +3378, 3823, 1798, 3392, -241, 2225, -2217, 708, +-3465, -922, -3752, -2423, -3237, -3403, -2094, -3563, +-545, -2922, 1026, -1716, 2164, -178, 2691, 1441, +2676, 2760, 2148, 3398, 1238, 3196, 152, 2276, +-915, 865, -1768, -745, -2247, -2127, -2314, -2895, +-1982, -2896, -1312, -2132, -421, -837, 581, 523, +1518, 1626, 2153, 2319, 2367, 2363, 2119, 1639, +1326, 456, 104, -702, -1150, -1537, -2074, -1866, +-2601, -1614, -2626, -905, -2019, 63, -963, 1006, +257, 1570, 1467, 1597, 2465, 1203, 2930, 560, +2641, -225, 1642, -963, 231, -1372, -1217, -1411, +-2409, -1259, -3144, -896, -3225, -245, -2517, 437, +-1134, 923, 506, 1359, 2061, 1787, 3328, 1889, +3848, 1482, 3233, 720, 1644, -287, -323, -1452, +-2184, -2434, -3592, -2900, -4110, -2725, -3532, -1882, +-2118, -472, -247, 1208, 1723, 2695, 3277, 3571, +3928, 3612, 3535, 2807, 2232, 1318, 354, -524, +-1549, -2257, -2892, -3395, -3326, -3678, -2933, -3109, +-2003, -1869, -751, -296, 566, 1215, 1634, 2341, +2200, 2874, 2210, 2754, 1722, 2075, 893, 1058, +18, 19, -699, -796, -1214, -1307, -1449, -1510, +-1361, -1464, -1105, -1302, -795, -1121, -358, -899, +169, -567, 632, -120, 992, 424, 1165, 1084, +1055, 1796, 711, 2271, 277, 2198, -254, 1629, +-871, 767, -1277, -402, -1283, -1752, -1011, -2766, +-530, -3079, 198, -2699, 910, -1721, 1189, -262, +1008, 1325, 630, 2538, 125, 3090, -482, 2975, +-925, 2184, -982, 816, -830, -676, -617, -1840, +-162, -2522, 448, -2600, 814, -1954, 816, -844, +701, 263, 503, 1201, 103, 1858, -353, 1877, +-638, 1240, -746, 426, -797, -274, -814, -888, +-685, -1263, -340, -1116, 119, -543, 533, 130, +839, 743, 1076, 1163, 1147, 1174, 889, 756, +347, 116, -238, -593, -783, -1224, -1350, -1498, +-1708, -1301, -1548, -828, -971, -193, -340, 592, +272, 1259, 921, 1533, 1402, 1503, 1552, 1285, +1464, 842, 1157, 196, 571, -516, -191, -1113, +-911, -1484, -1469, -1660, -1838, -1656, -1897, -1332, +-1604, -654, -1045, 144, -302, 921, 624, 1650, +1551, 2137, 2157, 2248, 2347, 2025, 2150, 1452, +1487, 503, 338, -699, -959, -1930, -1977, -2906, +-2664, -3363, -3058, -3142, -2867, -2180, -1875, -586, +-305, 1289, 1317, 2983, 2613, 4090, 3428, 4299, +3557, 3476, 2794, 1799, 1249, -262, -549, -2220, +-2138, -3719, -3284, -4391, -3780, -3953, -3381, -2567, +-2084, -784, -293, 977, 1421, 2469, 2600, 3336, +3044, 3369, 2842, 2745, 2053, 1712, 760, 450, +-614, -748, -1625, -1582, -2117, -2020, -2067, -2142, +-1526, -1961, -793, -1539, -110, -952, 468, -227, +707, 508, 510, 1128, 287, 1627, 388, 1919, +562, 1883, 614, 1527, 723, 889, 759, 85, +415, -678, -160, -1323, -734, -1819, -1303, -2030, +-1791, -1843, -1893, -1294, -1383, -507, -384, 364, +755, 1126, 1684, 1679, 2232, 2017, 2236, 2061, +1612, 1712, 531, 1018, -647, 149, -1574, -778, +-2111, -1675, -2238, -2344, -1862, -2572, -959, -2288, +145, -1487, 1009, -255, 1550, 1093, 1851, 2234, +1711, 3032, 1120, 3268, 413, 2657, -251, 1271, +-935, -471, -1491, -2140, -1688, -3350, -1580, -3712, +-1222, -3044, -593, -1566, 243, 279, 1050, 2011, +1563, 3173, 1719, 3374, 1581, 2560, 1105, 1137, +258, -386, -717, -1630, -1444, -2256, -1789, -2088, +-1745, -1301, -1294, -289, -601, 546, 114, 892, +727, 689, 1152, 200, 1258, -254, 1110, -513, +874, -417, 509, 191, 16, 1102, -427, 1764, +-693, 1788, -836, 1151, -944, 44, -998, -1337, +-940, -2635, -729, -3242, -327, -2781, 208, -1413, +745, 434, 1197, 2260, 1529, 3525, 1529, 3815, +1027, 3009, 270, 1314, -485, -743, -1191, -2515, +-1755, -3489, -1915, -3387, -1563, -2323, -838, -750, +65, 862, 908, 2064, 1462, 2466, 1635, 2059, +1349, 1155, 623, 76, -198, -829, -751, -1203, +-965, -959, -870, -297, -415, 442, 175, 898, +562, 868, 589, 350, 219, -523, -431, -1453, +-1103, -1994, -1521, -1831, -1539, -1015, -1005, 204, +126, 1499, 1493, 2509, 2571, 2967, 3083, 2696, +2823, 1636, 1618, 27, -314, -1644, -2351, -2887, +-3924, -3416, -4595, -3163, -4029, -2183, -2296, -639, +104, 1062, 2489, 2405, 4290, 3113, 5037, 3140, +4471, 2507, 2769, 1365, 354, 6, -2158, -1291, +-3999, -2246, -4652, -2580, -4149, -2312, -2754, -1710, +-787, -887, 1197, 79, 2588, 925, 3154, 1448, +2931, 1680, 2079, 1673, 907, 1369, -191, 814, +-955, 233, -1310, -247, -1244, -666, -979, -973, +-778, -1044, -735, -988, -794, -959, -812, -832, +-635, -531, -220, -182, 389, 218, 1121, 690, +1792, 1097, 2107, 1397, 1914, 1572, 1266, 1440, +232, 911, -1055, 114, -2277, -786, -2960, -1610, +-2875, -2172, -2037, -2299, -622, -1861, 910, -889, +2087, 377, 2714, 1555, 2728, 2346, 2001, 2595, +700, 2214, -630, 1228, -1616, -136, -2197, -1435, +-2221, -2179, -1555, -2187, -479, -1613, 526, -676, +1214, 373, 1433, 1167, 1125, 1425, 509, 1124, +-192, 456, -786, -258, -1042, -724, -818, -825, +-282, -535, 326, 91, 912, 797, 1251, 1217, +1061, 1154, 418, 625, -330, -197, -1014, -1079, +-1570, -1739, -1751, -1859, -1398, -1335, -699, -385, +169, 704, 1099, 1613, 1864, 2037, 2134, 1879, +1841, 1226, 1151, 194, 147, -929, -992, -1660, +-1906, -1757, -2308, -1358, -2176, -645, -1595, 249, +-661, 1054, 451, 1415, 1455, 1152, 2051, 457, +2077, -282, 1592, -865, 748, -1179, -210, -1009, +-973, -353, -1361, 452, -1361, 1124, -1077, 1517, +-600, 1463, -135, 872, 133, -79, 245, -1051, +303, -1778, 283, -2079, 175, -1790, 142, -934, +261, 193, 461, 1239, 653, 1976, 677, 2248, +411, 1944, -26, 1128, -514, 72, -1009, -886, +-1365, -1562, -1342, -1919, -952, -1870, -368, -1309, +361, -411, 1038, 403, 1377, 917, 1311, 1226, +1006, 1330, 542, 1064, -59, 530, -605, 47, +-888, -263, -858, -407, -664, -364, -500, -197, +-419, -43, -356, -32, -219, -210, 11, -501, +197, -803, 343, -969, 600, -810, 935, -318, +1018, 361, 739, 1101, 347, 1705, -86, 1925, +-676, 1686, -1274, 1066, -1487, 114, -1246, -1034, +-777, -1988, -191, -2401, 476, -2263, 1054, -1711, +1310, -787, 1134, 354, 686, 1331, 175, 1915, +-312, 2181, -658, 2146, -753, 1716, -576, 987, +-274, 130, -20, -797, 66, -1646, 40, -2211, +-3, -2440, -107, -2301, -272, -1658, -353, -555, +-208, 722, 103, 1922, 410, 2811, 654, 3087, +795, 2628, 698, 1563, 354, 124, -109, -1346, +-530, -2432, -854, -2862, -1044, -2621, -1029, -1847, +-786, -719, -293, 521, 369, 1517, 950, 1992, +1170, 1901, 1064, 1406, 733, 730, 163, 63, +-461, -415, -834, -607, -926, -604, -835, -541, +-518, -492, 30, -461, 572, -398, 865, -335, +861, -295, 516, -169, -100, 90, -763, 353, +-1216, 506, -1294, 559, -900, 571, -131, 511, +703, 296, 1360, 31, 1701, -82, 1625, -63, +1057, -55, 106, -97, -883, -238, -1621, -507, +-2034, -755, -1990, -844, -1405, -794, -470, -579, +474, -95, 1209, 599, 1649, 1241, 1736, 1612, +1519, 1666, 1069, 1368, 493, 679, -115, -246, +-695, -1133, -1223, -1785, -1611, -2031, -1738, -1785, +-1599, -1148, -1183, -321, -471, 515, 377, 1222, +1162, 1628, 1793, 1632, 2130, 1323, 2047, 841, +1540, 260, 696, -272, -395, -593, -1467, -742, +-2141, -860, -2276, -945, -1982, -904, -1382, -768, +-496, -630, 480, -406, 1224, 15, 1607, 542, +1680, 1007, 1492, 1335, 1117, 1512, 627, 1455, +68, 1064, -447, 366, -802, -472, -1100, -1242, +-1425, -1812, -1548, -2102, -1309, -1978, -832, -1353, +-261, -367, 443, 672, 1174, 1541, 1651, 2144, +1788, 2345, 1661, 2007, 1245, 1189, 461, 152, +-546, -851, -1433, -1653, -1960, -2099, -2073, -2077, +-1713, -1609, -924, -820, 25, 101, 845, 916, +1438, 1457, 1707, 1637, 1573, 1437, 1096, 1002, +403, 523, -314, 23, -941, -460, -1356, -800, +-1386, -979, -999, -1050, -400, -1008, 178, -774, +649, -330, 945, 175, 982, 646, 755, 1078, +319, 1295, -220, 1102, -691, 608, -995, 43, +-1065, -509, -806, -992, -230, -1236, 409, -1063, +960, -526, 1342, 82, 1303, 523, 817, 798, +157, 944, -496, 847, -1060, 464, -1368, -13, +-1385, -407, -1171, -695, -675, -841, 77, -777, +797, -527, 1254, -172, 1467, 221, 1451, 565, +1043, 810, 301, 929, -332, 828, -669, 513, +-961, 128, -1307, -299, -1350, -774, -975, -1153, +-519, -1265, -98, -1047, 422, -555, 928, 75, +1171, 723, 1137, 1287, 964, 1605, 734, 1503, +367, 956, -175, 181, -688, -583, -982, -1218, +-1170, -1595, -1227, -1561, -965, -1153, -448, -548, +104, 147, 576, 857, 950, 1382, 1114, 1537, +1028, 1354, 759, 899, 344, 243, -162, -452, +-592, -1049, -808, -1406, -794, -1361, -605, -993, +-304, -522, 12, 36, 244, 683, 329, 1181, +237, 1327, 45, 1149, -125, 739, -146, 158, +-77, -496, 2, -1043, 181, -1307, 433, -1209, +552, -780, 475, -136, 279, 550, -67, 1089, +-479, 1324, -724, 1137, -748, 571, -655, -156, +-428, -780, -78, -1117, 234, -1075, 390, -665, +459, -51, 491, 488, 434, 776, 328, 783, +233, 490, 177, 19, 144, -367, 95, -520, +-55, -429, -342, -124, -666, 270, -922, 553, +-1072, 553, -1002, 257, -582, -182, 99, -629, +833, -927, 1469, -860, 1810, -417, 1693, 177, +1229, 751, 476, 1170, -536, 1245, -1507, 890, +-2109, 233, -2244, -497, -1897, -1072, -1080, -1325, +16, -1202, 1127, -730, 1973, -57, 2297, 575, +2057, 993, 1417, 1143, 505, 978, -528, 545, +-1388, 43, -1841, -347, -1885, -609, -1553, -753, +-846, -701, 32, -471, 795, -206, 1261, -3, +1390, 171, 1154, 340, 604, 463, -4, 514, +-402, 502, -551, 403, -502, 224, -264, 2, +13, -299, 134, -633, 62, -823, -151, -815, +-441, -649, -657, -267, -666, 328, -405, 917, +82, 1266, 660, 1281, 1170, 950, 1426, 286, +1242, -563, 549, -1312, -382, -1690, -1151, -1551, +-1572, -936, -1632, -47, -1258, 895, -443, 1629, +538, 1875, 1289, 1511, 1607, 664, 1506, -345, +1002, -1180, 127, -1660, -812, -1670, -1349, -1129, +-1388, -211, -1052, 707, -420, 1326, 343, 1479, +939, 1129, 1161, 442, 976, -348, 494, -1024, +-82, -1297, -632, -1015, -997, -356, -949, 367, +-515, 908, 29, 1120, 508, 961, 814, 428, +817, -312, 504, -947, 19, -1254, -444, -1141, +-661, -623, -561, 132, -355, 867, -118, 1341, +241, 1344, 587, 851, 625, 79, 368, -656, +37, -1133, -290, -1234, -595, -894, -724, -246, +-501, 394, -17, 811, 409, 945, 631, 759, +709, 289, 594, -300, 271, -738, -126, -857, +-454, -673, -679, -237, -730, 355, -545, 842, +-210, 974, 147, 761, 426, 334, 577, -204, +553, -712, 383, -994, 178, -978, 10, -704, +-122, -266, -218, 211, -272, 619, -285, 877, +-287, 914, -271, 737, -183, 424, -61, 44, +54, -316, 181, -564, 316, -663, 380, -641, +389, -533, 357, -393, 207, -228, -43, 11, +-252, 261, -365, 409, -478, 501, -541, 629, +-374, 677, -37, 514, 217, 207, 331, -60, +393, -286, 425, -567, 350, -781, 158, -780, +-22, -661, -82, -474, -129, -146, -282, 226, +-371, 513, -279, 726, -154, 863, -103, 842, +2, 652, 202, 354, 335, 3, 336, -365, +268, -701, 161, -947, 12, -1039, -186, -921, +-357, -616, -340, -196, -187, 277, -34, 748, +143, 1089, 345, 1186, 409, 1058, 300, 761, +103, 276, -176, -351, -431, -876, -505, -1121, +-390, -1157, -204, -1044, 1, -674, 247, -120, +512, 372, 660, 712, 595, 907, 371, 926, +87, 771, -231, 474, -534, 96, -716, -256, +-733, -493, -552, -555, -242, -494, 55, -387, +334, -234, 660, -76, 842, -62, 729, -167, +494, -202, 224, -103, -154, 80, -496, 358, +-623, 707, -628, 938, -564, 922, -338, 618, +-8, 35, 208, -644, 250, -1146, 225, -1367, +212, -1268, 169, -794, 120, -66, 226, 657, +461, 1155, 586, 1308, 466, 1094, 190, 603, +-186, -15, -640, -558, -1034, -851, -1194, -830, +-1050, -563, -634, -175, -37, 190, 653, 388, +1286, 351, 1614, 119, 1526, -153, 1110, -336, +457, -359, -371, -185, -1118, 116, -1492, 415, +-1452, 646, -1155, 696, -754, 441, -261, -11, +320, -414, 803, -675, 1019, -821, 1074, -773, +1057, -461, 880, 0, 533, 429, 148, 724, +-207, 782, -549, 634, -893, 388, -1164, 20, +-1233, -423, -1065, -711, -651, -721, -12, -548, +688, -259, 1195, 120, 1444, 523, 1448, 768, +1090, 729, 417, 458, -251, 54, -743, -418, +-1052, -821, -1090, -976, -861, -847, -487, -458, +-83, 110, 202, 688, 266, 1108, 238, 1288, +201, 1099, 130, 509, 128, -263, 311, -947, +609, -1403, 829, -1535, 832, -1229, 560, -528, +60, 324, -576, 1016, -1195, 1398, -1559, 1433, +-1477, 1115, -1007, 488, -304, -239, 505, -825, +1225, -1160, 1647, -1172, 1662, -873, 1277, -411, +599, 65, -162, 492, -810, 745, -1173, 752, +-1186, 578, -937, 333, -521, 62, -58, -216, +243, -422, 317, -477, 288, -410, 233, -300, +182, -110, 215, 162, 364, 379, 546, 416, +652, 339, 582, 184, 321, -86, -72, -385, +-558, -571, -1041, -571, -1299, -365, -1161, -8, +-703, 354, -44, 647, 700, 789, 1281, 673, +1468, 319, 1248, -112, 721, -525, 19, -841, +-649, -926, -1041, -735, -1049, -335, -736, 139, +-223, 544, 318, 794, 668, 854, 665, 657, +397, 256, 26, -167, -374, -461, -669, -591, +-643, -597, -273, -476, 220, -199, 655, 115, +928, 286, 931, 328, 628, 315, 112, 237, +-445, 73, -836, -95, -960, -184, -829, -196, +-497, -156, -69, -83, 327, -5, 593, 69, +653, 130, 488, 121, 257, 78, 127, 43, +95, -13, 75, -102, 73, -148, 106, -145, +96, -136, -66, -100, -357, -24, -594, 55, +-673, 94, -627, 95, -404, 57, 54, 15, +545, -3, 885, 25, 1058, 90, 1002, 165, +659, 221, 155, 187, -336, 18, -754, -221, +-1042, -440, -1071, -638, -755, -729, -243, -581, +220, -178, 594, 320, 907, 775, 989, 1114, +730, 1240, 301, 1006, -100, 406, -456, -350, +-719, -1025, -746, -1471, -523, -1598, -135, -1282, +288, -597, 596, 214, 712, 929, 637, 1381, +368, 1438, -16, 1136, -377, 591, -643, -49, +-737, -548, -576, -773, -188, -764, 254, -624, +581, -411, 733, -215, 713, -125, 501, -178, +175, -276, -110, -242, -289, -7, -393, 332, +-422, 689, -313, 1039, -127, 1219, -19, 1047, +-17, 522, -25, -192, -34, -958, -35, -1595, +51, -1893, 247, -1725, 497, -1111, 688, -179, +685, 854, 490, 1687, 196, 2090, -186, 1935, +-603, 1281, -911, 329, -1001, -632, -870, -1342, +-547, -1645, -95, -1514, 419, -1021, 926, -375, +1263, 194, 1278, 601, 999, 750, 562, 614, +28, 372, -531, 208, -954, 98, -1104, 64, +-1025, 167, -812, 311, -450, 310, 79, 116, +595, -192, 877, -548, 929, -850, 827, -985, +579, -872, 220, -526, -119, -15, -315, 534, +-328, 991, -244, 1204, -167, 1097, -93, 735, +-30, 223, -65, -326, -220, -770, -377, -965, +-419, -914, -332, -687, -128, -375, 248, -57, +727, 168, 1101, 288, 1215, 353, 1050, 399, +630, 412, -5, 398, -730, 386, -1307, 317, +-1504, 151, -1344, -76, -955, -321, -341, -590, +433, -765, 1103, -740, 1465, -559, 1496, -290, +1236, 93, 741, 541, 138, 835, -382, 854, +-723, 664, -913, 363, -978, -24, -865, -404, +-597, -651, -300, -682, -26, -528, 277, -284, +576, -28, 762, 155, 825, 229, 827, 213, +764, 139, 557, 55, 183, 52, -248, 106, +-599, 164, -870, 209, -1006, 192, -878, 5, +-530, -296, -129, -514, 268, -564, 651, -467, +909, -243, 981, 125, 895, 512, 662, 736, +276, 689, -156, 425, -511, 17, -752, -440, +-812, -790, -635, -909, -294, -748, 95, -335, +443, 215, 649, 702, 655, 998, 462, 1015, +143, 708, -187, 118, -423, -534, -490, -1028, +-321, -1247, 28, -1120, 410, -646, 726, 55, +847, 763, 652, 1253, 194, 1325, -353, 981, +-830, 354, -1067, -352, -975, -958, -595, -1304, +-1, -1239, 654, -746, 1096, -50, 1173, 569, +964, 979, 551, 1089, 38, 828, -375, 273, +-580, -301, -580, -707, -353, -876, -29, -772, +140, -401, 118, 81, 9, 462, -204, 638, +-457, 602, -492, 381, -173, -3, 363, -390, +905, -614, 1319, -606, 1463, -391, 1183, -10, +480, 362, -428, 544, -1280, 516, -1860, 318, +-1978, -6, -1549, -358, -658, -568, 417, -571, +1352, -375, 1957, -68, 2156, 250, 1853, 471, +1064, 548, 80, 469, -774, 231, -1393, -112, +-1717, -424, -1605, -589, -1080, -627, -361, -511, +344, -223, 896, 133, 1191, 401, 1246, 568, +1092, 624, 738, 511, 288, 235, -140, -95, +-475, -376, -654, -577, -670, -641, -562, -566, +-309, -374, 31, -110, 276, 199, 318, 464, +291, 594, 315, 543, 269, 378, 90, 177, +-22, -92, 35, -386, 94, -538, 112, -480, +217, -361, 341, -224, 255, -29, 4, 168, +-197, 247, -341, 244, -442, 227, -367, 177, +-147, 93, 68, 32, 283, 12, 480, -59, +566, -165, 534, -244, 404, -293, 187, -326, +-48, -248, -249, -53, -353, 164, -298, 341, +-121, 439, 60, 402, 174, 207, 254, -73, +262, -372, 134, -557, -3, -538, -17, -351, +-16, -88, -82, 230, -79, 494, 95, 547, +307, 385, 386, 117, 389, -147, 381, -362, +229, -458, -68, -402, -289, -217, -382, -22, +-414, 133, -381, 220, -278, 202, -91, 79, +166, -55, 424, -97, 663, -57, 831, 37, +788, 161, 527, 272, 171, 239, -184, 40, +-487, -235, -653, -484, -623, -662, -479, -653, +-299, -361, -45, 82, 262, 474, 520, 747, +687, 871, 748, 715, 686, 298, 485, -209, +205, -636, -12, -882, -166, -856, -357, -608, +-513, -258, -539, 146, -461, 510, -291, 672, +-56, 577, 195, 341, 468, 67, 687, -172, +718, -332, 602, -350, 436, -252, 223, -98, +-48, 72, -308, 178, -462, 134, -466, -18, +-333, -147, -135, -257, 46, -341, 202, -303, +307, -89, 304, 150, 263, 319, 241, 440, +185, 489, 145, 377, 185, 128, 236, -122, +260, -323, 260, -488, 179, -617, 9, -623, +-195, -494, -387, -251, -502, 57, -473, 374, +-301, 635, -23, 810, 320, 826, 666, 587, +938, 176, 1037, -258, 870, -659, 440, -1006, +-117, -1123, -653, -931, -1020, -508, -1062, 23, +-798, 570, -366, 997, 209, 1157, 796, 1007, +1130, 605, 1166, 63, 959, -498, 485, -886, +-136, -1024, -658, -942, -913, -671, -827, -209, +-444, 278, 97, 571, 621, 661, 914, 636, +879, 467, 617, 151, 231, -114, -249, -229, +-648, -241, -734, -237, -498, -218, -133, -209, +249, -249, 631, -323, 898, -347, 866, -256, +535, -38, 137, 295, -157, 616, -385, 777, +-543, 717, -507, 470, -322, 23, -131, -532, +70, -989, 304, -1165, 492, -1009, 559, -565, +519, 68, 447, 716, 361, 1190, 176, 1296, +-113, 980, -350, 329, -423, -418, -396, -1030, +-280, -1327, 18, -1223, 417, -726, 657, 2, +636, 691, 444, 1127, 154, 1189, -178, 868, +-443, 240, -503, -459, -282, -1002, 136, -1205, +574, -985, 903, -427, 995, 212, 738, 730, +185, 1008, -500, 910, -1077, 479, -1264, -75, +-959, -515, -278, -742, 547, -717, 1226, -471, +1521, -82, 1358, 262, 800, 393, 18, 299, +-713, 90, -1151, -147, -1179, -342, -778, -340, +-64, -92, 697, 315, 1227, 679, 1305, 805, +843, 579, 75, 94, -628, -517, -1072, -1119, +-1113, -1480, -623, -1375, 220, -769, 1017, 115, +1497, 1003, 1548, 1652, 1146, 1885, 374, 1556, +-548, 737, -1305, -299, -1616, -1247, -1363, -1882, +-648, -1987, 251, -1516, 1054, -691, 1559, 240, +1585, 1044, 1107, 1507, 379, 1502, -299, 1122, +-770, 526, -926, -104, -698, -616, -207, -882, +276, -870, 571, -671, 643, -409, 466, -163, +76, 60, -331, 185, -546, 178, -514, 104, +-242, 77, 236, 103, 767, 177, 1134, 277, +1215, 354, 989, 350, 472, 215, -224, -16, +-857, -281, -1214, -527, -1249, -707, -993, -693, +-454, -485, 275, -197, 941, 91, 1365, 375, +1520, 594, 1365, 669, 881, 581, 220, 348, +-385, 54, -801, -235, -993, -461, -949, -577, +-664, -535, -232, -383, 158, -144, 403, 132, +546, 321, 625, 329, 599, 195, 464, 7, +338, -193, 313, -340, 301, -368, 216, -195, +133, 139, 44, 483, -184, 657, -464, 632, +-592, 404, -571, -18, -452, -501, -163, -877, +296, -1038, 720, -942, 923, -597, 954, -115, +911, 380, 694, 757, 245, 983, -211, 1035, +-433, 863, -475, 493, -499, 54, -463, -376, +-272, -801, -57, -1110, 38, -1189, 123, -1032, +303, -716, 475, -229, 549, 364, 608, 905, +696, 1239, 678, 1311, 465, 1119, 164, 667, +-154, 21, -504, -655, -804, -1143, -916, -1367, +-756, -1277, -380, -883, 81, -292, 553, 286, +964, 725, 1179, 930, 1141, 860, 888, 591, +480, 234, 27, -80, -373, -242, -647, -240, +-745, -200, -684, -155, -478, -132, -137, -188, +196, -345, 413, -504, 559, -545, 686, -411, +745, -115, 647, 271, 438, 654, 244, 888, +42, 914, -217, 704, -412, 271, -458, -308, +-378, -796, -207, -1034, 2, -1034, 199, -804, +341, -343, 423, 189, 457, 575, 392, 769, +244, 750, 146, 526, 109, 181, 71, -130, +35, -327, 5, -381, 1, -326, 21, -227, +4, -129, -31, -71, -30, -74, 12, -130, +107, -148, 230, -87, 340, 64, 414, 242, +407, 380, 296, 408, 112, 289, -92, 41, +-222, -249, -242, -499, -142, -643, 105, -570, +369, -266, 506, 154, 538, 502, 453, 687, +186, 660, -174, 404, -469, -61, -569, -568, +-440, -880, -149, -893, 257, -630, 674, -143, +929, 466, 935, 908, 673, 1013, 196, 796, +-302, 325, -641, -311, -734, -868, -583, -1141, +-253, -1051, 197, -609, 617, 54, 794, 697, +698, 1066, 452, 1074, 154, 721, -126, 94, +-326, -634, -318, -1154, -53, -1234, 275, -855, +495, -179, 577, 563, 479, 1130, 208, 1314, +-147, 1053, -487, 367, -653, -510, -538, -1224, +-175, -1511, 322, -1356, 783, -784, 1035, 87, +1000, 951, 690, 1477, 209, 1519, -289, 1108, +-637, 345, -720, -518, -604, -1195, -369, -1451, +8, -1261, 434, -738, 699, -62, 714, 588, +556, 976, 338, 982, 78, 713, -187, 302, +-257, -141, -102, -489, 75, -610, 216, -517, +327, -301, 299, -69, 178, 139, 67, 251, +-55, 205, -165, 45, -166, -96, -62, -161, +63, -193, 194, -159, 354, -40, 478, 123, +476, 234, 381, 268, 274, 220, 174, 123, +52, -28, -101, -223, -235, -378, -323, -440, +-375, -407, -315, -267, -104, -22, 163, 197, +427, 335, 653, 407, 735, 395, 638, 253, +433, 67, 192, -84, -43, -214, -261, -338, +-405, -406, -400, -355, -295, -253, -145, -170, +46, -72, 219, 114, 303, 274, 343, 328, +411, 318, 472, 304, 475, 256, 456, 127, +393, -67, 190, -294, -86, -460, -304, -531, +-459, -524, -488, -447, -356, -223, -176, 109, +54, 429, 370, 619, 624, 663, 716, 587, +689, 365, 557, -3, 328, -415, 62, -691, +-169, -780, -313, -681, -364, -426, -353, -58, +-317, 308, -249, 549, -96, 569, 155, 401, +414, 169, 588, -57, 698, -219, 762, -276, +684, -202, 411, -54, 44, 104, -332, 143, +-660, 32, -811, -145, -703, -317, -373, -460, +100, -489, 572, -297, 884, 54, 997, 436, +901, 715, 627, 809, 277, 649, -111, 272, +-490, -208, -702, -634, -673, -888, -466, -899, +-158, -664, 192, -284, 485, 120, 624, 467, +639, 674, 610, 634, 519, 434, 326, 206, +103, -14, -117, -226, -345, -339, -521, -311, +-554, -210, -421, -136, -174, -140, 128, -163, +448, -164, 732, -144, 899, -112, 882, 18, +639, 225, 242, 386, -164, 423, -509, 363, +-741, 202, -747, -52, -518, -300, -169, -463, +232, -501, 615, -423, 858, -220, 908, 26, +801, 221, 551, 306, 178, 308, -214, 216, +-500, 29, -612, -148, -566, -220, -429, -184, +-210, -103, 116, -2, 463, 102, 716, 202, +822, 208, 736, 96, 459, -57, 112, -187, +-202, -322, -442, -418, -526, -387, -422, -247, +-191, -30, 68, 220, 289, 435, 487, 519, +617, 484, 535, 334, 262, 87, -12, -200, +-201, -424, -274, -537, -166, -537, 57, -426, +241, -247, 335, -28, 346, 159, 265, 279, +106, 318, -59, 317, -153, 285, -150, 244, +-49, 173, 125, 71, 301, -39, 394, -192, +372, -397, 226, -573, -9, -607, -212, -509, +-242, -264, -110, 101, 65, 488, 232, 746, +377, 792, 418, 600, 326, 225, 137, -213, +-133, -599, -368, -805, -417, -767, -258, -481, +54, -65, 426, 348, 718, 617, 800, 679, +602, 511, 170, 137, -296, -323, -568, -678, +-604, -785, -487, -631, -186, -248, 296, 235, +703, 671, 840, 921, 770, 883, 506, 510, +61, -48, -359, -591, -565, -972, -502, -1075, +-219, -863, 97, -410, 307, 124, 414, 583, +399, 806, 250, 779, 53, 564, -59, 266, +-23, -21, 89, -211, 199, -298, 295, -319, +333, -299, 225, -308, -39, -366, -344, -427, +-529, -387, -487, -239, -208, 8, 194, 329, +567, 672, 844, 886, 925, 844, 678, 553, +249, 111, -122, -394, -435, -864, -675, -1088, +-687, -989, -433, -635, -50, -163, 300, 324, +536, 683, 637, 831, 562, 721, 357, 385, +178, -2, 98, -289, 78, -433, 76, -427, +68, -242, 13, 11, -133, 196, -327, 234, +-439, 131, -444, -90, -330, -337, -25, -504, +419, -509, 815, -326, 1026, -16, 1017, 345, +771, 645, 283, 797, -320, 726, -790, 449, +-1024, -1, -1015, -471, -712, -787, -179, -906, +392, -857, 859, -605, 1119, -166, 1096, 276, +810, 587, 378, 723, -61, 706, -408, 540, +-580, 285, -564, -5, -450, -251, -262, -411, +8, -477, 234, -449, 320, -363, 326, -265, +331, -181, 338, -64, 309, 82, 266, 235, +269, 345, 242, 411, 97, 423, -105, 360, +-283, 178, -377, -110, -348, -380, -257, -537, +-133, -564, 76, -490, 330, -286, 514, 4, +579, 279, 542, 441, 426, 493, 227, 427, +-24, 228, -244, -26, -370, -233, -377, -381, +-311, -482, -205, -436, -19, -243, 218, 10, +409, 242, 523, 418, 531, 464, 415, 370, +237, 164, 39, -110, -140, -369, -222, -528, +-221, -527, -214, -374, -179, -106, -59, 161, +114, 361, 244, 454, 312, 418, 365, 243, +353, 14, 215, -154, 40, -226, -53, -228, +-61, -189, -61, -104, -81, -56, -81, -92, +-76, -161, -77, -170, -16, -152, 108, -99, +220, 60, 321, 302, 403, 492, 412, 546, +334, 458, 155, 213, -115, -120, -376, -469, +-515, -748, -481, -849, -291, -679, 16, -310, +390, 112, 699, 456, 817, 670, 726, 735, +450, 611, 53, 317, -331, -36, -601, -285, +-700, -427, -567, -487, -230, -453, 167, -310, +463, -136, 607, 6, 618, 95, 483, 129, +237, 120, 6, 82, -139, 78, -207, 123, +-170, 184, -58, 208, 30, 196, 38, 110, +-25, -36, -114, -194, -161, -346, -117, -466, +37, -468, 271, -333, 515, -159, 671, 52, +643, 290, 420, 471, 88, 517, -269, 462, +-573, 305, -742, 75, -695, -155, -395, -341, +52, -472, 466, -533, 745, -490, 844, -353, +728, -118, 440, 155, 96, 395, -195, 549, +-366, 599, -407, 476, -328, 198, -187, -127, +-65, -422, 21, -631, 74, -690, 76, -533, +62, -207, 117, 179, 261, 494, 436, 672, +569, 649, 585, 414, 425, 24, 93, -384, +-315, -667, -660, -739, -840, -582, -800, -270, +-530, 129, -55, 503, 523, 745, 978, 729, +1141, 463, 1026, 59, 677, -335, 118, -639, +-460, -777, -795, -651, -827, -297, -641, 116, +-309, 439, 68, 626, 356, 595, 510, 341, +513, -25, 377, -338, 213, -522, 101, -517, +13, -305, -18, 11, 77, 306, 175, 476, +130, 469, -15, 263, -168, -62, -311, -393, +-391, -586, -313, -586, -92, -404, 173, -97, +414, 254, 569, 529, 577, 628, 452, 548, +247, 319, -20, 21, -278, -248, -410, -418, +-389, -517, -256, -517, -65, -386, 117, -185, +239, -1, 286, 164, 248, 308, 141, 382, +49, 390, 22, 339, 44, 244, 87, 98, +145, -57, 202, -219, 201, -370, 89, -469, +-88, -469, -222, -380, -282, -220, -279, 27, +-182, 289, 9, 474, 213, 528, 357, 478, +425, 306, 409, 36, 304, -245, 130, -424, +-66, -466, -215, -388, -270, -224, -234, -35, +-143, 125, -32, 217, 78, 231, 164, 147, +204, 37, 180, -46, 127, -93, 79, -110, +37, -68, 0, 31, 9, 127, 101, 165, +209, 127, 228, 50, 147, -58, 27, -172, +-102, -270, -212, -299, -261, -260, -215, -151, +-101, 3, 26, 157, 174, 280, 342, 353, +439, 337, 422, 213, 312, 68, 121, -90, +-82, -253, -227, -345, -307, -311, -294, -244, +-190, -169, -105, -43, -59, 85, 46, 129, +195, 126, 286, 156, 326, 175, 363, 159, +341, 120, 222, 95, 72, 45, -87, -64, +-250, -203, -353, -287, -370, -304, -308, -269, +-158, -161, 63, -7, 309, 148, 486, 273, +528, 329, 467, 227, 321, 54, 70, -58, +-194, -109, -361, -145, -418, -98, -363, 18, +-206, 63, 7, 6, 228, -102, 375, -194, +385, -244, 300, -225, 193, -117, 78, 93, +-54, 293, -157, 384, -196, 363, -189, 250, +-134, 52, -23, -174, 91, -342, 180, -423, +247, -355, 250, -170, 180, 13, 71, 125, +-53, 206, -145, 216, -185, 131, -190, 31, +-104, -27, 76, -45, 266, -24, 416, 36, +448, 83, 279, 92, -15, 26, -277, -96, +-463, -231, -543, -329, -406, -359, -65, -256, +321, -35, 652, 212, 839, 446, 758, 592, +421, 560, -60, 335, -580, 4, -934, -377, +-948, -685, -666, -806, -172, -696, 433, -387, +917, 52, 1081, 480, 927, 750, 541, 824, +-1, 676, -568, 351, -941, -48, -954, -420, +-626, -710, -109, -803, 417, -661, 769, -362, +823, -6, 586, 315, 174, 527, -256, 582, +-510, 471, -476, 245, -250, 58, 11, -45, +260, -118, 448, -187, 463, -218, 275, -266, +-19, -380, -277, -478, -406, -435, -395, -196, +-255, 153, -2, 519, 261, 815, 415, 927, +435, 710, 352, 225, 193, -351, 2, -855, +-149, -1119, -224, -1016, -240, -613, -211, -64, +-134, 528, -18, 938, 82, 979, 110, 725, +103, 346, 142, -126, 188, -529, 185, -677, +160, -603, 117, -433, 35, -191, -71, 74, +-167, 252, -210, 340, -173, 360, -76, 299, +52, 142, 174, -23, 249, -155, 295, -246, +285, -266, 125, -172, -152, -29, -351, 50, +-364, 76, -259, 78, -77, 39, 190, -35, +455, -44, 562, -5, 461, 47, 221, 101, +-62, 141, -329, 135, -535, 76, -572, -49, +-409, -207, -167, -281, 96, -281, 370, -252, +547, -135, 559, 107, 457, 298, 284, 370, +77, 380, -131, 299, -312, 107, -397, -112, +-361, -302, -267, -424, -167, -397, -67, -278, +25, -144, 110, 13, 222, 182, 349, 243, +413, 224, 397, 224, 340, 232, 202, 191, +-27, 114, -238, 38, -357, -63, -398, -216, +-389, -409, -341, -498, -242, -432, -83, -268, +92, -55, 279, 216, 487, 463, 643, 591, +665, 579, 531, 435, 267, 194, -88, -102, +-478, -382, -775, -607, -851, -705, -713, -642, +-421, -398, 6, -14, 447, 405, 732, 695, +827, 749, 751, 572, 491, 235, 127, -148, +-208, -477, -468, -618, -599, -515, -495, -232, +-223, 89, 11, 341, 141, 419, 175, 284, +84, 32, -40, -213, -69, -371, -5, -396, +167, -231, 410, 59, 529, 338, 431, 455, +244, 392, 11, 206, -324, -13, -655, -191, +-799, -276, -706, -288, -412, -264, 29, -193, +519, -117, 912, -75, 1061, -32, 879, 101, +400, 289, -205, 443, -728, 471, -1021, 318, +-983, 10, -597, -316, -24, -526, 486, -582, +799, -444, 876, -132, 677, 241, 264, 475, +-148, 497, -441, 349, -632, 102, -659, -193, +-461, -404, -127, -442, 233, -364, 554, -182, +706, 109, 590, 405, 295, 547, -29, 522, +-301, 355, -454, 84, -452, -233, -335, -510, +-196, -701, -83, -746, 31, -583, 166, -244, +317, 194, 454, 623, 482, 967, 349, 1103, +145, 910, -62, 386, -291, -262, -461, -844, +-469, -1233, -386, -1284, -287, -946, -107, -361, +154, 273, 370, 822, 490, 1120, 536, 1094, +459, 805, 244, 366, -14, -134, -249, -538, +-424, -762, -461, -826, -354, -718, -220, -440, +-102, -58, 47, 286, 191, 493, 237, 536, +217, 474, 239, 307, 283, 62, 271, -135, +196, -175, 71, -133, -83, -108, -216, -84, +-352, -75, -500, -126, -522, -219, -357, -252, +-122, -202, 155, -71, 509, 130, 793, 369, +835, 547, 628, 560, 234, 362, -247, -15, +-644, -420, -847, -684, -847, -732, -618, -587, +-202, -218, 230, 265, 583, 637, 823, 771, +812, 705, 510, 431, 120, -6, -204, -431, +-456, -712, -570, -793, -483, -651, -279, -316, +-72, 96, 93, 501, 199, 757, 232, 766, +210, 566, 170, 254, 115, -117, 55, -465, +30, -671, 33, -689, 18, -507, -30, -215, +-120, 50, -235, 226, -285, 363, -235, 427, +-130, 422, 47, 395, 289, 320, 459, 147, +428, -87, 235, -325, 0, -543, -235, -641, +-437, -571, -480, -370, -310, -95, -43, 236, +218, 516, 440, 658, 541, 664, 409, 567, +72, 346, -286, -50, -511, -504, -575, -801, +-462, -830, -154, -672, 255, -345, 583, 112, +680, 553, 554, 802, 297, 808, -81, 568, +-500, 146, -729, -300, -684, -637, -462, -761, +-119, -625, 258, -270, 538, 149, 669, 501, +652, 657, 460, 568, 96, 281, -314, -81, +-597, -380, -682, -521, -589, -507, -348, -392, +-4, -151, 327, 149, 514, 379, 531, 494, +462, 531, 313, 419, 28, 152, -291, -129, +-482, -358, -506, -545, -374, -604, -128, -466, +151, -228, 355, 49, 352, 337, 175, 566, +14, 629, -85, 532, -159, 299, -145, -37, +-31, -377, 65, -576, 84, -566, 69, -406, +50, -179, 23, 51, -30, 251, -104, 331, +-163, 304, -186, 236, -164, 163, -70, 62, +80, -25, 202, -81, 272, -135, 311, -167, +252, -184, 62, -201, -136, -198, -273, -113, +-385, 7, -426, 151, -317, 320, -77, 428, +188, 346, 374, 97, 458, -175, 432, -372, +247, -444, -49, -389, -304, -191, -439, 85, +-424, 306, -238, 372, 22, 329, 227, 214, +346, 48, 315, -122, 103, -247, -122, -318, +-246, -308, -318, -179, -289, -21, -95, 113, +118, 230, 266, 307, 403, 279, 425, 183, +225, 54, -67, -111, -337, -251, -539, -304, +-551, -278, -345, -191, -73, -34, 172, 99, +353, 161, 394, 191, 328, 224, 249, 212, +160, 154, 67, 77, -45, -38, -242, -197, +-442, -338, -500, -383, -429, -318, -254, -132, +45, 107, 353, 308, 515, 408, 504, 405, +353, 272, 123, 59, -103, -147, -285, -333, +-386, -450, -370, -398, -255, -186, -87, 40, +105, 225, 263, 337, 302, 319, 187, 179, +-34, 23, -252, -116, -334, -207, -219, -205, +30, -146, 287, -65, 408, 39, 319, 153, +121, 186, -81, 151, -285, 75, -427, -47, +-442, -212, -373, -304, -214, -241, 49, -83, +323, 75, 535, 203, 638, 319, 528, 363, +201, 288, -206, 105, -561, -113, -757, -343, +-707, -519, -424, -556, -26, -401, 365, -90, +647, 276, 701, 588, 503, 711, 146, 586, +-258, 269, -549, -106, -590, -466, -415, -674, +-151, -614, 115, -348, 295, -49, 332, 244, +238, 474, 49, 482, -121, 299, -159, 70, +-118, -154, -88, -321, -53, -282, 10, -110, +76, 47, 97, 168, 46, 244, -44, 186, +-114, 17, -145, -160, -162, -323, -159, -391, +-71, -279, 111, -43, 281, 188, 370, 399, +349, 525, 156, 486, -175, 269, -462, -52, +-573, -377, -520, -611, -329, -673, -22, -535, +283, -194, 469, 240, 542, 602, 515, 742, +368, 652, 137, 354, -171, -82, -558, -480, +-834, -633, -805, -510, -541, -267, -176, -41, +253, 110, 640, 189, 828, 202, 786, 201, +548, 203, 168, 229, -252, 246, -604, 178, +-823, -16, -829, -268, -592, -486, -223, -606, +147, -541, 456, -290, 643, 74, 666, 440, +559, 738, 342, 856, 29, 723, -301, 350, +-598, -163, -805, -655, -739, -973, -360, -1026, +69, -798, 348, -336, 507, 224, 547, 756, +412, 1092, 159, 1095, -75, 752, -236, 225, +-342, -325, -368, -763, -271, -963, -79, -891, +121, -583, 203, -137, 101, 300, -80, 551, +-186, 618, -157, 548, -18, 347, 152, 51, +244, -197, 203, -295, 82, -242, -10, -75, +-43, 96, -81, 150, -169, 36, -305, -174, +-421, -396, -391, -521, -170, -467, 163, -188, +484, 261, 650, 709, 554, 936, 240, 852, +-124, 516, -380, 12, -512, -522, -582, -924, +-537, -1037, -286, -846, 61, -433, 340, 55, +520, 490, 569, 754, 410, 795, 90, 647, +-230, 355, -425, -1, -448, -297, -343, -432, +-201, -425, -39, -279, 157, -84, 288, -18, +272, -122, 152, -213, -30, -216, -238, -163, +-322, 41, -184, 402, 63, 708, 235, 782, +220, 620, 45, 198, -131, -350, -207, -776, +-187, -958, -80, -918, 38, -605, 60, -51, +19, 505, -7, 874, 2, 981, 61, 795, +98, 356, -36, -167, -256, -625, -319, -870, +-189, -812, 39, -478, 280, 9, 409, 496, +351, 796, 150, 755, -154, 397, -463, -130, +-591, -582, -509, -781, -328, -640, -23, -220, +392, 306, 661, 674, 627, 740, 371, 518, +-16, 97, -400, -335, -583, -582, -523, -602, +-301, -447, -51, -127, 106, 226, 204, 459, +297, 520, 294, 406, 151, 126, -91, -172, +-375, -367, -512, -473, -344, -421, 23, -158, +411, 177, 656, 417, 560, 538, 127, 463, +-355, 189, -635, -179, -654, -548, -455, -775, +-176, -639, 33, -160, 204, 373, 373, 761, +458, 875, 444, 616, 318, 51, 15, -533, +-323, -890, -486, -859, -442, -465, -214, 109, +67, 621, 126, 864, -30, 757, -173, 373, +-244, -145, -189, -646, 44, -894, 307, -774, +442, -372, 438, 159, 305, 669, 84, 924, +-150, 793, -391, 356, -588, -208, -606, -661, +-455, -826, -205, -688, 140, -320, 436, 194, +476, 612, 354, 747, 231, 587, 78, 200, +-63, -281, -149, -637, -267, -745, -318, -575, +-173, -104, -1, 475, 85, 865, 102, 914, +-36, 606, -277, -33, -372, -723, -264, -1129, +-12, -1101, 339, -634, 587, 119, 543, 829, +278, 1221, -23, 1189, -270, 686, -445, -100, +-538, -824, -494, -1237, -292, -1212, -26, -709, +228, 58, 429, 794, 426, 1286, 185, 1297, +-85, 749, -271, -117, -341, -952, -166, -1460, +134, -1369, 269, -724, 261, 197, 191, 1081, +-34, 1581, -270, 1437, -348, 753, -418, -198, +-482, -1140, -342, -1637, -59, -1432, 244, -704, +570, 242, 717, 1130, 532, 1537, 199, 1282, +-120, 557, -400, -361, -539, -1120, -524, -1364, +-442, -1046, -283, -378, -63, 443, 134, 1087, +310, 1265, 419, 978, 359, 381, 177, -395, +-20, -1061, -151, -1329, -132, -1101, -52, -462, +-83, 318, -161, 933, -202, 1206, -249, 1087, +-214, 597, -48, -63, 79, -658, 155, -994, +281, -943, 305, -553, 148, -38, -13, 457, +-160, 785, -348, 728, -417, 319, -281, -211, +-42, -664, 215, -815, 368, -482, 315, 108, +126, 653, -94, 1004, -239, 965, -236, 452, +-205, -251, -211, -871, -144, -1283, -27, -1239, +71, -694, 194, 85, 268, 848, 192, 1386, +59, 1393, -90, 868, -237, 90, -192, -715, +-5, -1277, 39, -1297, -9, -806, -13, -81, +-115, 658, -228, 1130, -139, 1113, -64, 672, +-99, 31, 1, -685, 151, -1218, 197, -1246, +331, -746, 443, 35, 223, 837, -106, 1404, +-305, 1453, -501, 956, -612, 161, -452, -689, +-190, -1385, 16, -1603, 211, -1250, 348, -545, +363, 305, 360, 1104, 364, 1512, 248, 1352, +12, 807, -201, 33, -345, -756, -482, -1181, +-570, -1081, -484, -667, -262, -81, -42, 482, +214, 702, 483, 577, 568, 344, 516, 40, +437, -318, 162, -479, -265, -370, -527, -121, +-650, 186, -710, 448, -503, 465, -90, 258, +255, -1, 554, -277, 750, -514, 590, -529, +180, -270, -193, 64, -496, 333, -703, 477, +-655, 428, -343, 201, 91, -27, 493, -211, +697, -391, 602, -438, 247, -250, -192, 32, +-505, 277, -615, 457, -547, 455, -256, 274, +156, 45, 389, -204, 405, -457, 357, -540, +178, -445, -133, -272, -361, 27, -460, 386, +-413, 578, -106, 582, 292, 503, 508, 253, +542, -132, 368, -449, -92, -609, -555, -625, +-718, -436, -646, -100, -424, 212, -60, 432, +304, 536, 560, 482, 702, 265, 652, -34, +366, -295, -37, -394, -435, -326, -754, -152, +-866, 42, -646, 173, -153, 214, 355, 188, +631, 86, 631, -80, 410, -200, 9, -253, +-383, -229, -536, -84, -451, 127, -180, 289, +241, 417, 569, 461, 626, 298, 446, -28, +9, -380, -566, -672, -912, -773, -885, -565, +-602, -145, -120, 361, 435, 829, 825, 1047, +972, 872, 857, 378, 442, -282, -114, -879, +-590, -1153, -916, -1013, -995, -531, -720, 114, +-225, 702, 265, 1033, 639, 1013, 754, 619, +525, 32, 146, -471, -149, -758, -305, -765, +-345, -450, -289, -1, -125, 322, 83, 468, +168, 380, 133, 61, 76, -255, -64, -383, +-259, -370, -342, -159, -303, 250, -136, 612, +223, 786, 563, 757, 586, 407, 323, -244, +-69, -897, -483, -1368, -694, -1503, -577, -1067, +-288, -100, 76, 978, 464, 1792, 652, 2059, +536, 1619, 263, 611, -70, -627, -385, -1676, +-564, -2143, -602, -1846, -494, -938, -177, 242, +240, 1270, 544, 1782, 652, 1620, 572, 872, +323, -161, -56, -1014, -479, -1360, -722, -1162, +-612, -476, -294, 428, 50, 1106, 370, 1269, +481, 910, 274, 163, -3, -684, -164, -1314, +-262, -1516, -259, -1163, -114, -305, 55, 698, +205, 1453, 311, 1787, 266, 1535, 128, 719, +-34, -315, -292, -1216, -520, -1772, -523, -1756, +-355, -1109, -73, -96, 290, 917, 500, 1600, +416, 1680, 219, 1124, 23, 185, -168, -833, +-197, -1556, -63, -1624, 29, -957, 92, 157, +139, 1230, -10, 1804, -259, 1656, -386, 856, +-431, -335, -409, -1493, -227, -2169, 102, -2081, +491, -1235, 799, 113, 849, 1496, 616, 2411, +182, 2515, -355, 1775, -779, 449, -924, -1058, +-833, -2253, -533, -2682, -38, -2136, 419, -826, +612, 741, 560, 1949, 347, 2334, 45, 1853, +-165, 789, -191, -531, -113, -1632, 76, -1977, +318, -1437, 344, -310, 89, 911, -274, 1709, +-650, 1741, -903, 1056, -878, -75, -580, -1291, +-44, -2073, 661, -1999, 1265, -1100, 1470, 300, +1155, 1704, 426, 2487, -448, 2312, -1202, 1291, +-1542, -218, -1308, -1754, -683, -2709, 38, -2620, +691, -1510, 1074, 183, 989, 1831, 557, 2775, +78, 2644, -323, 1526, -592, -158, -603, -1789, +-348, -2742, 68, -2620, 497, -1520, 636, 124, +340, 1750, -111, 2711, -475, 2593, -746, 1543, +-766, 20, -387, -1505, 175, -2484, 663, -2489, +923, -1577, 799, -174, 372, 1256, -143, 2133, +-643, 2049, -926, 1191, -775, 53, -325, -964, +190, -1470, 657, -1237, 845, -496, 573, 321, +41, 870, -437, 910, -758, 422, -824, -245, +-569, -749, -139, -935, 334, -694, 801, -51, +1045, 666, 857, 1093, 346, 1135, -274, 767, +-865, 44, -1202, -739, -1041, -1185, -443, -1160, +273, -705, 784, 18, 883, 665, 569, 928, +99, 812, -228, 408, -346, -197, -320, -685, +-151, -760, 81, -419, 218, 151, 271, 719, +238, 992, 2, 794, -329, 213, -533, -563, +-577, -1256, -414, -1471, 7, -1050, 488, -193, +760, 790, 729, 1535, 430, 1732, -22, 1275, +-420, 381, -606, -590, -576, -1374, -405, -1744, +-181, -1503, 94, -703, 417, 327, 596, 1243, +453, 1765, 113, 1602, -243, 768, -568, -247, +-705, -1099, -467, -1633, -21, -1507, 355, -697, +605, 247, 654, 937, 429, 1317, 134, 1214, +-73, 635, -322, -11, -623, -505, -763, -899, +-650, -980, -385, -617, 5, -99, 503, 263, +831, 413, 765, 395, 480, 254, 199, 77, +-57, -2, -278, 103, -418, 314, -469, 461, +-424, 372, -326, -24, -217, -593, -6, -1045, +272, -1195, 366, -935, 278, -214, 230, 721, +207, 1473, 109, 1821, 6, 1582, -93, 658, +-190, -559, -161, -1556, -35, -2092, -4, -1923, +-51, -984, -99, 244, -255, 1274, -393, 1922, +-264, 1923, -10, 1206, 230, 153, 514, -870, +634, -1629, 440, -1736, 171, -1150, -82, -291, +-386, 617, -604, 1383, -643, 1532, -577, 941, +-351, 31, 105, -791, 555, -1242, 731, -1119, +655, -482, 386, 341, -60, 1057, -467, 1347, +-606, 951, -529, 57, -339, -862, -14, -1448, +330, -1515, 482, -964, 469, 117, 395, 1285, +167, 1955, -222, 1862, -523, 1055, -607, -156, +-549, -1320, -270, -2059, 233, -2109, 586, -1370, +624, -114, 528, 1079, 277, 1816, -127, 2006, +-424, 1570, -518, 617, -448, -440, -219, -1295, +75, -1694, 290, -1441, 365, -761, 297, -4, +86, 690, -197, 1096, -403, 957, -435, 478, +-294, 0, 2, -396, 354, -553, 563, -300, +503, 107, 292, 398, 30, 548, -356, 452, +-687, 30, -621, -514, -323, -890, -132, -947, +101, -672, 417, -161, 455, 468, 244, 1006, +101, 1165, -59, 889, -277, 387, -243, -188, +23, -656, 233, -770, 353, -566, 359, -246, +130, 98, -269, 316, -664, 210, -905, -86, +-824, -371, -381, -546, 255, -411, 849, 35, +1226, 541, 1289, 994, 969, 1290, 252, 1150, +-605, 509, -1211, -381, -1487, -1223, -1408, -1727, +-775, -1690, 156, -1199, 846, -349, 1223, 716, +1304, 1487, 892, 1689, 159, 1506, -461, 960, +-831, 76, -925, -727, -660, -1155, -197, -1248, +229, -992, 568, -365, 675, 306, 430, 690, +10, 736, -466, 480, -871, 55, -875, -373, +-476, -646, 42, -585, 620, -216, 1108, 271, +1169, 787, 770, 1140, 146, 1069, -499, 573, +-972, -136, -1170, -902, -1082, -1521, -706, -1675, +-194, -1279, 349, -450, 949, 564, 1304, 1352, +1094, 1691, 644, 1622, 251, 1094, -292, 215, +-896, -619, -1117, -1181, -943, -1419, -609, -1217, +-136, -626, 313, 32, 574, 534, 795, 789, +881, 738, 578, 474, 133, 138, -235, -146, +-620, -193, -839, -44, -689, 39, -342, 47, +15, 95, 325, 57, 521, -148, 543, -360, +349, -445, 62, -352, -92, -132, -167, 139, +-291, 465, -313, 702, -239, 581, -281, 189, +-263, -182, -48, -509, 74, -716, 123, -545, +357, -109, 551, 292, 513, 669, 384, 852, +64, 588, -468, 86, -785, -427, -784, -921, +-703, -1141, -379, -831, 232, -196, 660, 501, +774, 1144, 769, 1415, 560, 1100, 129, 471, +-312, -256, -602, -976, -646, -1399, -471, -1318, +-188, -780, 158, -36, 421, 654, 400, 1149, +160, 1294, -123, 944, -343, 230, -314, -473, +-31, -913, 217, -1027, 373, -711, 490, -76, +367, 499, 30, 831, -291, 851, -616, 475, +-799, -174, -583, -769, -214, -1029, 131, -902, +651, -467, 1030, 274, 773, 1115, 236, 1509, +-194, 1200, -741, 549, -1152, -153, -913, -959, +-325, -1561, 214, -1518, 759, -941, 1116, -116, +991, 748, 442, 1269, -326, 1295, -997, 1023, +-1199, 455, -915, -343, -380, -856, 291, -815, +910, -509, 1151, -127, 902, 215, 314, 270, +-343, 64, -792, -152, -931, -343, -744, -416, +-277, -139, 258, 348, 718, 736, 1002, 950, +847, 912, 222, 509, -480, -164, -948, -899, +-1101, -1453, -849, -1534, -206, -1023, 580, -155, +1192, 773, 1302, 1576, 792, 1899, 50, 1466, +-538, 498, -981, -521, -1151, -1290, -837, -1714, +-285, -1605, 175, -872, 522, 102, 738, 911, +713, 1433, 433, 1543, 35, 1119, -253, 314, +-354, -486, -403, -1027, -353, -1237, -127, -1081, +26, -638, 11, -45, 1, 531, -48, 844, +-113, 866, -25, 747, 76, 526, 122, 180, +293, -224, 420, -516, 234, -675, -39, -769, +-205, -722, -444, -460, -584, -39, -279, 462, +130, 917, 294, 1136, 432, 975, 469, 500, +147, -127, -246, -802, -433, -1290, -502, -1349, +-398, -941, -5, -198, 487, 639, 799, 1330, +863, 1678, 667, 1467, 90, 665, -760, -403, +-1404, -1360, -1524, -1987, -1142, -1998, -289, -1214, +791, 17, 1565, 1228, 1833, 2169, 1616, 2475, +759, 1897, -469, 707, -1386, -725, -1826, -2064, +-1884, -2728, -1338, -2424, -273, -1443, 733, -47, +1408, 1507, 1718, 2571, 1427, 2722, 639, 2076, +-162, 852, -815, -669, -1202, -1947, -1098, -2567, +-678, -2419, -168, -1523, 370, -177, 626, 1186, +453, 2229, 205, 2526, 42, 1902, -166, 748, +-238, -513, 30, -1636, 332, -2246, 364, -2046, +243, -1206, 70, -117, -215, 969, -530, 1774, +-624, 2046, -426, 1707, -140, 837, 168, -241, +553, -1207, 790, -1866, 665, -1913, 294, -1319, +-210, -460, -749, 470, -1046, 1330, -924, 1728, +-443, 1488, 296, 946, 1036, 305, 1362, -428, +1167, -960, 624, -1141, -187, -1122, -1045, -839, +-1573, -314, -1686, 151, -1387, 477, -589, 737, +481, 848, 1402, 705, 1985, 427, 2048, 164, +1428, -80, 383, -327, -695, -482, -1622, -430, +-2118, -316, -1981, -337, -1396, -297, -594, -100, +335, -48, 1267, -82, 1904, 141, 1980, 504, +1638, 745, 1045, 896, 48, 871, -1085, 487, +-1689, -131, -1803, -774, -1781, -1317, -1322, -1589, +-253, -1455, 748, -874, 1293, 106, 1723, 1158, +1890, 1931, 1356, 2334, 452, 2159, -381, 1151, +-1160, -347, -1708, -1739, -1736, -2738, -1287, -3013, +-499, -2296, 424, -806, 1100, 949, 1382, 2390, +1349, 3034, 964, 2805, 280, 1883, -389, 393, +-819, -1273, -1034, -2374, -1062, -2625, -807, -2233, +-296, -1278, 170, 26, 489, 1182, 766, 1805, +813, 1812, 476, 1379, 61, 689, -172, -116, +-292, -719, -333, -890, -224, -777, -83, -573, +-75, -226, -100, 140, -117, 192, -228, 29, +-327, -117, -257, -255, -46, -259, 236, -40, +505, 284, 714, 662, 856, 936, 788, 855, +370, 505, -267, 76, -884, -470, -1313, -1028, +-1408, -1272, -1125, -1203, -541, -856, 289, -115, +1163, 678, 1700, 1127, 1710, 1325, 1260, 1252, +505, 759, -392, 93, -1244, -485, -1733, -958, +-1593, -1170, -995, -973, -248, -576, 528, -128, +1126, 421, 1255, 912, 924, 1076, 354, 803, +-329, 209, -884, -401, -924, -799, -492, -915, +45, -663, 570, -150, 926, 343, 804, 757, +274, 1032, -367, 893, -996, 397, -1410, -125, +-1292, -611, -640, -1013, 235, -1123, 1060, -925, +1605, -489, 1658, 175, 1154, 795, 227, 1074, +-787, 1081, -1507, 864, -1656, 407, -1178, -40, +-347, -386, 489, -694, 1130, -747, 1338, -546, +961, -391, 206, -294, -596, -144, -1203, -39, +-1325, 47, -794, 269, 126, 486, 1017, 572, +1680, 672, 1845, 714, 1201, 555, -46, 272, +-1354, -143, -2294, -642, -2514, -1034, -1866, -1237, +-578, -1199, 950, -846, 2248, -195, 2804, 613, +2411, 1323, 1302, 1624, -192, 1431, -1710, 984, +-2648, 362, -2611, -462, -1779, -1115, -527, -1355, +864, -1329, 2001, -1032, 2395, -433, 1919, 230, +927, 727, -261, 1019, -1433, 1096, -2181, 916, +-2162, 483, -1391, -94, -157, -610, 1106, -911, +1971, -1009, 2194, -781, 1751, -156, 799, 529, +-382, 1009, -1460, 1238, -2120, 1009, -2143, 228, +-1515, -700, -511, -1318, 536, -1518, 1464, -1347, +2065, -771, 2028, 201, 1361, 1281, 451, 1998, +-457, 2126, -1255, 1720, -1671, 787, -1558, -547, +-1104, -1812, -497, -2578, 159, -2660, 742, -1947, +1054, -594, 992, 920, 710, 2164, 387, 2808, +77, 2672, -174, 1854, -328, 492, -337, -1126, +-263, -2318, -338, -2655, -495, -2318, -501, -1465, +-434, -73, -342, 1357, 3, 2116, 523, 2143, +803, 1668, 783, 759, 689, -354, 417, -1238, +-139, -1602, -615, -1459, -799, -935, -846, -133, +-683, 627, -192, 1001, 332, 976, 619, 676, +701, 209, 571, -220, 213, -398, -215, -372, +-543, -255, -641, -22, -396, 143, 54, 31, +406, -152, 571, -266, 652, -343, 534, -252, +-34, 49, -787, 396, -1121, 685, -959, 851, +-582, 736, 45, 288, 943, -333, 1607, -902, +1502, -1146, 797, -1000, -24, -715, -874, -259, +-1688, 496, -2002, 1134, -1525, 1274, -567, 1085, +447, 738, 1423, 165, 2208, -521, 2298, -1021, +1501, -1191, 223, -1073, -1092, -721, -2137, -152, +-2551, 520, -2160, 1004, -1196, 1133, 40, 996, +1306, 606, 2172, -5, 2284, -603, 1772, -1025, +914, -1169, -128, -847, -1115, -196, -1724, 403, +-1804, 852, -1469, 1118, -871, 994, -102, 500, +646, -121, 1158, -721, 1373, -1117, 1262, -1112, +834, -754, 271, -190, -241, 452, -667, 893, +-906, 1031, -858, 1006, -703, 724, -533, 140, +-168, -448, 299, -821, 566, -960, 700, -906, +797, -718, 616, -316, 166, 304, -177, 796, +-393, 873, -680, 773, -822, 655, -586, 299, +-155, -147, 229, -355, 494, -446, 651, -540, +670, -552, 395, -451, -125, -238, -519, -24, +-564, 86, -488, 229, -509, 528, -382, 740, +73, 638, 454, 447, 457, 273, 383, -87, +444, -586, 346, -945, -28, -971, -265, -726, +-216, -404, -245, 56, -421, 681, -464, 1108, +-374, 1107, -306, 849, -189, 467, 106, -72, +550, -645, 930, -1061, 997, -1196, 769, -925, +471, -379, 25, 123, -728, 581, -1425, 986, +-1612, 1059, -1318, 796, -692, 390, 244, -117, +1260, -558, 1917, -701, 1940, -656, 1356, -504, +350, -160, -766, 138, -1596, 137, -1908, 74, +-1694, 109, -1026, 62, -63, 25, 897, 246, +1526, 596, 1672, 760, 1347, 606, 599, 198, +-345, -276, -1111, -736, -1462, -1201, -1358, -1496, +-849, -1298, -91, -523, 636, 494, 1071, 1377, +1104, 2038, 779, 2334, 252, 1872, -283, 604, +-686, -906, -823, -2118, -671, -2864, -376, -2860, +-73, -1899, 181, -331, 384, 1329, 540, 2620, +554, 3130, 394, 2813, 184, 1834, -11, 298, +-213, -1435, -400, -2680, -480, -3096, -457, -2790, +-450, -1808, -379, -308, -80, 1231, 325, 2465, +653, 3111, 920, 2860, 1010, 1816, 665, 433, +-30, -967, -658, -2216, -1047, -2966, -1221, -2827, +-1038, -1895, -504, -608, 84, 750, 617, 1968, +1107, 2675, 1300, 2607, 1032, 1966, 503, 969, +-134, -338, -823, -1589, -1272, -2322, -1244, -2490, +-870, -2119, -365, -1186, 173, 23, 648, 1131, +926, 1966, 956, 2330, 802, 2035, 511, 1266, +62, 330, -477, -619, -895, -1392, -1011, -1794, +-888, -1799, -661, -1425, -309, -730, 185, 78, +707, 775, 1114, 1252, 1306, 1474, 1196, 1417, +669, 1066, -221, 481, -1095, -183, -1636, -765, +-1752, -1112, -1337, -1171, -447, -1050, 552, -772, +1343, -262, 1835, 313, 1907, 631, 1383, 706, +342, 752, -853, 706, -1828, 472, -2235, 201, +-1878, -1, -874, -125, 417, -206, 1500, -340, +1982, -479, 1795, -526, 1068, -535, 13, -559, +-1016, -486, -1667, -191, -1750, 241, -1244, 650, +-318, 947, 715, 1134, 1536, 1214, 1824, 963, +1371, 244, 354, -616, -798, -1288, -1647, -1717, +-1858, -1819, -1411, -1446, -592, -590, 394, 498, +1382, 1419, 1927, 1941, 1700, 2065, 916, 1726, +-72, 841, -1111, -238, -1831, -1065, -1765, -1701, +-998, -2107, -31, -1890, 796, -1097, 1326, -170, +1377, 703, 816, 1451, -30, 1846, -613, 1756, +-869, 1289, -933, 560, -625, -289, 73, -1000, +750, -1384, 1102, -1444, 1059, -1269, 541, -851, +-331, -193, -1121, 452, -1524, 873, -1442, 1149, +-799, 1229, 188, 942, 1062, 464, 1600, 23, +1746, -423, 1397, -783, 568, -854, -492, -724, +-1369, -513, -1782, -207, -1778, 39, -1393, 104, +-527, 161, 542, 274, 1255, 329, 1509, 409, +1494, 536, 1161, 586, 499, 583, -234, 464, +-835, 28, -1202, -590, -1233, -1068, -981, -1304, +-576, -1280, -68, -897, 403, -203, 628, 577, +655, 1282, 668, 1696, 640, 1607, 445, 1091, +114, 365, -163, -409, -265, -1094, -340, -1491, +-461, -1407, -443, -955, -342, -386, -394, 190, +-484, 588, -341, 642, 4, 506, 384, 421, +756, 360, 1073, 312, 1199, 441, 1052, 593, +586, 487, -199, 223, -1117, -173, -1855, -815, +-2118, -1406, -1815, -1596, -1054, -1400, 124, -906, +1564, -71, 2614, 975, 2732, 1849, 2086, 2245, +1026, 2049, -373, 1371, -1857, 413, -2810, -713, +-2848, -1702, -2068, -2121, -762, -1978, 713, -1531, +1908, -846, 2461, 19, 2231, 798, 1339, 1267, +120, 1438, -990, 1394, -1638, 1193, -1681, 892, +-1153, 508, -235, 30, 679, -498, 1165, -989, +1105, -1371, 614, -1650, -197, -1712, -1060, -1327, +-1489, -548, -1241, 357, -486, 1267, 485, 2012, +1380, 2297, 1944, 2064, 1979, 1453, 1407, 534, +341, -572, -931, -1577, -2052, -2234, -2677, -2426, +-2578, -2129, -1756, -1434, -475, -455, 937, 697, +2199, 1723, 2976, 2326, 2992, 2464, 2243, 2152, +952, 1392, -591, 325, -2077, -794, -3142, -1751, +-3387, -2409, -2690, -2580, -1330, -2079, 292, -1084, +1815, -12, 2889, 990, 3211, 1925, 2676, 2442, +1479, 2226, -18, 1585, -1447, 811, -2495, -205, +-2890, -1266, -2461, -1931, -1346, -2102, 7, -1866, +1196, -1220, 1972, -262, 2164, 721, 1746, 1461, +905, 1815, -65, 1716, -851, 1209, -1289, 389, +-1419, -512, -1238, -1183, -633, -1517, 158, -1427, +613, -801, 696, 87, 781, 791, 831, 1185, +550, 1280, 137, 968, -48, 223, -193, -665, +-611, -1323, -1077, -1548, -1178, -1348, -867, -761, +-364, 238, 268, 1361, 1044, 2060, 1702, 2150, +1902, 1752, 1569, 843, 801, -507, -306, -1825, +-1592, -2602, -2702, -2718, -3138, -2275, -2576, -1283, +-1157, 208, 630, 1780, 2353, 2812, 3664, 3111, +4047, 2842, 3183, 1957, 1405, 461, -735, -1163, +-2815, -2405, -4328, -3124, -4752, -3228, -3851, -2602, +-1808, -1383, 766, 76, 3108, 1464, 4617, 2568, +4940, 3201, 3947, 3143, 1902, 2376, -538, 1197, +-2716, -158, -4213, -1592, -4697, -2800, -3991, -3373, +-2255, -3203, 21, -2410, 2187, -1092, 3693, 553, +4222, 2141, 3687, 3272, 2279, 3666, 442, 3241, +-1373, 2058, -2759, 325, -3418, -1540, -3295, -3046, +-2452, -3812, -1006, -3584, 621, -2377, 1896, -564, +2618, 1333, 2761, 2860, 2263, 3614, 1265, 3321, +107, 2077, -929, 278, -1663, -1530, -1986, -2794, +-1966, -3234, -1674, -2766, -1037, -1410, -156, 444, +651, 2071, 1249, 2907, 1693, 2820, 1936, 1946, +1816, 538, 1240, -1042, 367, -2295, -545, -2744, +-1441, -2325, -2232, -1380, -2594, -169, -2317, 1094, +-1472, 1961, -240, 2138, 1168, 1793, 2435, 1188, +3231, 466, 3281, -249, 2446, -803, 922, -1100, +-832, -1213, -2457, -1292, -3674, -1332, -4037, -1193, +-3262, -839, -1595, -297, 415, 459, 2328, 1373, +3781, 2204, 4321, 2702, 3677, 2671, 2119, 1970, +143, 606, -1859, -1155, -3411, -2799, -4063, -3840, +-3743, -4074, -2603, -3353, -860, -1639, 1053, 557, +2632, 2573, 3528, 4089, 3531, 4747, 2700, 4133, +1416, 2440, -55, 321, -1583, -1785, -2741, -3467, +-3102, -4189, -2785, -3862, -2024, -2732, -773, -1086, +741, 602, 1947, 1910, 2555, 2669, 2583, 2780, +2048, 2335, 1024, 1616, -181, 752, -1204, -202, +-1890, -906, -2161, -1184, -1831, -1358, -981, -1546, +-24, -1511, 772, -1242, 1324, -865, 1433, -372, +1026, 278, 426, 1021, -60, 1637, -401, 1955, +-520, 1915, -340, 1453, -88, 631, 41, -308, +51, -1162, -82, -1856, -360, -2163, -621, -1862, +-709, -1193, -507, -398, 52, 560, 800, 1431, +1386, 1836, 1586, 1770, 1342, 1359, 594, 647, +-581, -237, -1762, -1043, -2433, -1526, -2405, -1523, +-1709, -1061, -367, -358, 1352, 422, 2768, 1115, +3310, 1440, 2928, 1281, 1758, 721, -55, -115, +-2044, -974, -3457, -1600, -3845, -1824, -3210, -1473, +-1764, -578, 181, 539, 2159, 1553, 3579, 2247, +3965, 2403, 3281, 1916, 1831, 885, -35, -461, +-1880, -1734, -3162, -2537, -3537, -2802, -3045, -2489, +-1893, -1471, -359, -79, 1107, 1165, 2095, 2116, +2485, 2661, 2333, 2597, 1730, 2013, 894, 1172, +92, 167, -547, -871, -1020, -1682, -1305, -2189, +-1401, -2407, -1394, -2267, -1322, -1790, -1069, -1014, +-532, 56, 186, 1264, 877, 2396, 1503, 3204, +2073, 3383, 2304, 2800, 1918, 1516, 1041, -262, +-93, -2099, -1377, -3455, -2515, -4010, -3049, -3668, +-2810, -2426, -1903, -593, -514, 1257, 1000, 2721, +2199, 3515, 2866, 3424, 2901, 2558, 2253, 1243, +1108, -153, -193, -1285, -1396, -1972, -2246, -2193, +-2526, -2018, -2272, -1581, -1612, -1047, -648, -501, +377, 61, 1161, 612, 1663, 1159, 1959, 1664, +1960, 1953, 1523, 1958, 778, 1642, -28, 868, +-856, -270, -1681, -1429, -2224, -2363, -2251, -2879, +-1804, -2727, -954, -1823, 249, -408, 1525, 1129, +2423, 2377, 2686, 3008, 2298, 2918, 1366, 2105, +94, 731, -1253, -741, -2298, -1875, -2653, -2455, +-2274, -2360, -1422, -1653, -311, -662, 855, 266, +1768, 933, 2126, 1230, 1814, 1147, 1043, 842, +230, 528, -370, 346, -753, 309, -900, 313, +-771, 273, -516, 69, -363, -421, -361, -1065, +-446, -1570, -510, -1753, -435, -1497, -182, -713, +236, 451, 800, 1595, 1405, 2349, 1843, 2508, +1838, 2031, 1169, 1053, 33, -190, -1125, -1396, +-2118, -2233, -2819, -2472, -2847, -2096, -2020, -1293, +-627, -330, 925, 620, 2285, 1361, 3108, 1653, +3183, 1551, 2506, 1345, 1220, 1066, -321, 605, +-1686, 127, -2582, -270, -2859, -763, -2485, -1306, +-1657, -1661, -574, -1799, 644, -1662, 1619, -1056, +1987, -74, 1856, 950, 1515, 1849, 1030, 2491, +432, 2584, -126, 1982, -500, 897, -768, -333, +-1079, -1461, -1340, -2291, -1366, -2627, -1170, -2342, +-801, -1503, -222, -360, 472, 725, 1106, 1458, +1590, 1826, 1780, 1872, 1502, 1477, 880, 774, +136, 204, -643, -99, -1260, -377, -1482, -696, +-1361, -926, -985, -1065, -399, -1136, 87, -1094, +315, -898, 477, -479, 528, 131, 294, 715, +95, 1179, 293, 1518, 670, 1629, 906, 1474, +1020, 1079, 980, 429, 522, -381, -433, -1145, +-1551, -1791, -2329, -2279, -2529, -2357, -2170, -1876, +-1244, -990, 197, 168, 1775, 1476, 3012, 2650, +3597, 3336, 3318, 3266, 2143, 2413, 321, 952, +-1672, -832, -3245, -2520, -3949, -3679, -3730, -4022, +-2671, -3422, -921, -1937, 1050, 71, 2621, 2013, +3482, 3447, 3570, 4024, 2850, 3525, 1463, 2215, +-199, 523, -1698, -1254, -2676, -2590, -2922, -3007, +-2467, -2615, -1506, -1766, -372, -637, 604, 459, +1319, 1079, 1696, 1184, 1555, 1007, 1063, 651, +688, 306, 487, 249, 183, 540, -190, 950, +-369, 1094, -479, 814, -849, 217, -1325, -704, +-1444, -1879, -1162, -2829, -748, -2993, -173, -2250, +700, -810, 1611, 1009, 2136, 2730, 2162, 3853, +1722, 4031, 801, 3079, -437, 1235, -1637, -905, +-2456, -2807, -2622, -3994, -2047, -4075, -952, -3038, +314, -1235, 1394, 788, 2020, 2417, 2140, 3179, +1793, 2968, 972, 2023, -98, 709, -991, -577, +-1490, -1496, -1605, -1777, -1257, -1370, -456, -669, +379, -52, 856, 486, 1008, 801, 911, 583, +429, -10, -318, -545, -873, -863, -1026, -898, +-920, -494, -554, 249, 172, 961, 995, 1393, +1525, 1462, 1658, 1139, 1386, 459, 632, -436, +-475, -1164, -1571, -1417, -2286, -1330, -2434, -1052, +-2014, -537, -1042, 64, 409, 482, 1909, 682, +2788, 747, 2853, 685, 2340, 543, 1266, 425, +-319, 346, -1767, 278, -2479, 139, -2531, -106, +-2118, -295, -1178, -424, 103, -668, 1156, -887, +1605, -855, 1547, -652, 1210, -415, 667, -89, +29, 345, -411, 757, -424, 1044, -159, 1201, +46, 1254, 95, 1139, 55, 666, -174, -64, +-649, -720, -1084, -1309, -1177, -1880, -879, -2084, +-293, -1688, 474, -905, 1227, 0, 1673, 933, +1631, 1790, 1157, 2340, 417, 2345, -385, 1734, +-1028, 763, -1369, -246, -1350, -1181, -986, -1837, +-412, -1977, 97, -1683, 345, -1165, 414, -533, +453, 98, 385, 583, 208, 863, 165, 990, +298, 1006, 412, 936, 448, 806, 442, 635, +317, 456, -7, 234, -459, -86, -872, -513, +-1126, -1006, -1166, -1398, -965, -1554, -488, -1509, +197, -1189, 816, -494, 1175, 392, 1353, 1236, +1390, 1955, 1120, 2350, 515, 2192, -210, 1627, +-839, 856, -1297, -178, -1550, -1307, -1462, -2148, +-942, -2608, -211, -2712, 393, -2327, 796, -1417, +1101, -147, 1224, 1260, 949, 2537, 390, 3344, +-76, 3415, -345, 2728, -539, 1440, -558, -204, +-285, -1886, 23, -3166, 97, -3633, 31, -3208, +-91, -2071, -369, -502, -634, 1077, -591, 2264, +-316, 2801, 24, 2580, 467, 1747, 888, 674, +1077, -299, 1029, -989, 732, -1281, 155, -1166, +-490, -824, -907, -451, -1063, -171, -1024, -73, +-749, -127, -277, -231, 180, -269, 475, -103, +576, 247, 471, 611, 253, 904, 93, 1077, +77, 993, 123, 575, 165, -13, 278, -521, +439, -868, 406, -1072, 111, -1071, -277, -766, +-672, -264, -1011, 148, -1127, 389, -958, 515, +-600, 466, -133, 323, 415, 263, 974, 231, +1395, 193, 1566, 286, 1453, 424, 1039, 344, +361, 92, -425, -159, -1146, -463, -1696, -819, +-1994, -1073, -1925, -1098, -1433, -807, -648, -267, +283, 328, 1255, 914, 2068, 1387, 2462, 1490, +2302, 1186, 1655, 684, 694, 97, -452, -523, +-1579, -976, -2320, -1161, -2486, -1127, -2167, -872, +-1445, -506, -391, -221, 732, 16, 1608, 309, +2026, 595, 1914, 748, 1429, 783, 807, 848, +117, 902, -557, 699, -923, 221, -934, -274, +-898, -682, -850, -1099, -580, -1431, -265, -1424, +-188, -1043, -180, -430, 17, 226, 290, 839, +478, 1443, 692, 1819, 993, 1662, 1127, 1101, +888, 399, 409, -420, -154, -1255, -768, -1789, +-1303, -1833, -1539, -1423, -1390, -679, -912, 123, +-167, 793, 670, 1319, 1287, 1512, 1493, 1247, +1324, 771, 865, 259, 185, -282, -580, -702, +-1149, -901, -1250, -966, -940, -880, -467, -569, +110, -180, 752, 146, 1158, 480, 1090, 807, +643, 985, 38, 887, -630, 508, -1216, 49, +-1435, -362, -1143, -776, -496, -1062, 256, -1013, +967, -687, 1512, -220, 1692, 334, 1381, 817, +739, 1065, -35, 1103, -858, 918, -1540, 417, +-1807, -243, -1617, -807, -1124, -1149, -419, -1190, +392, -961, 1056, -548, 1408, 16, 1536, 587, +1466, 966, 1038, 1114, 277, 1058, -453, 760, +-880, 293, -1095, -158, -1214, -557, -1089, -905, +-676, -1066, -291, -972, -88, -671, 167, -256, +550, 146, 803, 529, 836, 866, 806, 994, +779, 873, 659, 628, 396, 325, 25, -4, +-412, -316, -877, -643, -1316, -978, -1560, -1145, +-1380, -1059, -769, -768, 24, -222, 817, 516, +1482, 1205, 1828, 1702, 1723, 1840, 1206, 1408, +420, 487, -492, -610, -1338, -1603, -1812, -2236, +-1715, -2258, -1192, -1611, -466, -456, 381, 885, +1170, 1953, 1500, 2434, 1240, 2272, 703, 1481, +129, 249, -502, -1030, -1014, -2007, -1068, -2414, +-657, -2088, -83, -1154, 416, 68, 779, 1232, +896, 1967, 656, 2000, 186, 1417, -273, 503, +-626, -473, -854, -1180, -885, -1392, -682, -1140, +-276, -542, 221, 189, 647, 697, 893, 784, +942, 539, 779, 128, 469, -348, 138, -708, +-192, -667, -542, -173, -808, 446, -911, 852, +-926, 987, -817, 831, -460, 267, 66, -528, +569, -1135, 965, -1378, 1194, -1205, 1230, -590, +1074, 248, 653, 1008, -6, 1520, -688, 1576, +-1226, 1010, -1574, 62, -1646, -809, -1320, -1387, +-607, -1576, 275, -1249, 1068, -462, 1629, 480, +1878, 1199, 1708, 1491, 1111, 1350, 288, 796, +-572, -44, -1370, -844, -1879, -1325, -1879, -1394, +-1464, -1051, -793, -390, 90, 334, 998, 869, +1609, 1118, 1772, 1034, 1539, 682, 1008, 253, +259, -156, -536, -489, -1111, -673, -1351, -667, +-1300, -454, -961, -175, -389, -49, 158, -48, +495, -3, 685, 43, 744, 24, 586, 139, +318, 447, 156, 682, 116, 734, 106, 649, +73, 353, -19, -142, -192, -674, -438, -1093, +-700, -1277, -805, -1145, -676, -713, -404, -59, +16, 692, 565, 1291, 1003, 1496, 1146, 1283, +1044, 783, 714, 159, 131, -454, -559, -959, +-1078, -1186, -1240, -1029, -1036, -667, -594, -289, +-64, 91, 472, 407, 864, 540, 941, 492, +723, 345, 355, 196, -94, 158, -481, 209, +-642, 199, -547, 154, -243, 148, 141, 22, +404, -279, 475, -554, 423, -695, 228, -742, +-119, -654, -467, -330, -648, 152, -645, 590, +-478, 913, -138, 1067, 324, 913, 736, 491, +914, 38, 814, -352, 500, -716, 72, -896, +-347, -774, -631, -568, -749, -379, -725, -68, +-563, 262, -284, 443, 59, 544, 406, 592, +638, 511, 642, 348, 482, 163, 262, -76, +15, -304, -194, -402, -286, -418, -287, -368, +-246, -203, -168, -25, -43, 84, 92, 126, +136, 83, 27, 15, -138, -11, -192, -39, +-145, -70, -98, 37, -3, 275, 203, 404, +377, 398, 387, 396, 289, 282, 202, -83, +106, -501, -94, -713, -343, -745, -501, -702, +-499, -464, -337, -28, -77, 334, 137, 536, +231, 708, 236, 799, 181, 666, 82, 382, +23, 126, 75, -87, 179, -299, 232, -482, +219, -614, 179, -683, 109, -698, -44, -658, +-295, -460, -548, -91, -700, 333, -701, 750, +-520, 1085, -153, 1208, 332, 1083, 795, 768, +1090, 275, 1120, -340, 880, -891, 388, -1272, +-283, -1471, -890, -1408, -1196, -1068, -1201, -516, +-944, 175, -431, 852, 198, 1392, 724, 1753, +1017, 1829, 1017, 1496, 728, 802, 302, -76, +-132, -982, -557, -1740, -842, -2179, -771, -2175, +-395, -1652, 45, -712, 447, 344, 735, 1306, +752, 2046, 458, 2313, 2, 1958, -472, 1150, +-859, 185, -1014, -730, -855, -1426, -452, -1708, +128, -1496, 791, -959, 1277, -362, 1388, 135, +1153, 444, 631, 512, -164, 419, -955, 314, +-1382, 245, -1420, 308, -1227, 580, -764, 834, +-41, 800, 650, 506, 1024, 20, 1105, -658, +1047, -1330, 806, -1679, 332, -1579, -156, -1065, +-403, -218, -503, 735, -628, 1517, -664, 1889, +-483, 1700, -252, 1052, -135, 193, -43, -657, +125, -1258, 278, -1397, 305, -1086, 306, -514, +393, 89, 422, 519, 244, 655, 28, 510, +-53, 163, -124, -221, -230, -424, -184, -381, +-38, -139, -67, 282, -278, 697, -460, 828, +-504, 640, -425, 263, -232, -215, 73, -695, +475, -1009, 861, -1024, 1064, -713, 987, -194, +670, 314, 207, 706, -356, 934, -908, 855, +-1240, 458, -1206, -29, -885, -412, -440, -605, +43, -569, 493, -318, 798, 41, 925, 368, +880, 544, 644, 498, 292, 259, -24, -96, +-232, -456, -337, -728, -362, -870, -361, -763, +-362, -310, -361, 286, -367, 759, -346, 1079, +-249, 1224, -119, 1072, 25, 617, 257, -11, +525, -662, 697, -1172, 782, -1440, 809, -1453, +661, -1119, 280, -435, -213, 304, -693, 913, +-1084, 1415, -1302, 1624, -1285, 1356, -996, 794, +-421, 193, 333, -421, 1056, -992, 1539, -1316, +1669, -1287, 1416, -968, 826, -509, 37, -63, +-718, 316, -1246, 602, -1459, 735, -1310, 736, +-849, 670, -263, 577, 259, 445, 652, 227, +835, -77, 721, -405, 422, -712, 163, -924, +35, -929, 42, -708, 140, -327, 199, 181, +151, 688, 10, 941, -233, 893, -570, 675, +-850, 281, -886, -231, -631, -577, -183, -625, +338, -473, 815, -200, 1102, 135, 1075, 410, +708, 502, 141, 345, -400, -42, -753, -479, +-871, -770, -719, -828, -333, -577, 78, -21, +327, 621, 446, 1078, 452, 1217, 235, 1022, +-112, 538, -308, -164, -315, -854, -281, -1236, +-153, -1249, 141, -1007, 414, -515, 494, 192, +444, 808, 300, 1065, 30, 1021, -273, 746, +-455, 254, -477, -267, -416, -607, -301, -700, +-133, -569, 51, -274, 190, 76, 274, 336, +319, 416, 319, 337, 291, 162, 259, -83, +195, -333, 45, -432, -156, -337, -316, -204, +-373, -67, -371, 150, -354, 365, -268, 447, +-58, 433, 165, 409, 283, 330, 339, 109, +372, -173, 296, -397, 79, -587, -129, -750, +-231, -763, -230, -545, -144, -199, -5, 225, +131, 725, 217, 1088, 207, 1112, 96, 859, +-67, 443, -243, -103, -397, -663, -486, -1035, +-451, -1087, -259, -867, 70, -479, 434, -20, +718, 422, 850, 710, 781, 737, 480, 551, +31, 250, -398, -82, -724, -286, -927, -262, +-933, -104, -680, 97, -273, 289, 118, 366, +422, 223, 643, -100, 744, -461, 673, -751, +478, -905, 263, -846, 67, -477, -122, 139, +-255, 763, -275, 1207, -233, 1425, -269, 1337, +-433, 880, -614, 158, -672, -632, -556, -1294, +-281, -1683, 132, -1737, 649, -1405, 1131, -665, +1362, 296, 1262, 1149, 906, 1695, 361, 1878, +-333, 1634, -1044, 977, -1584, 73, -1798, -799, +-1592, -1391, -1010, -1632, -226, -1539, 588, -1060, +1328, -281, 1808, 473, 1856, 977, 1484, 1192, +830, 1091, 39, 698, -734, 179, -1314, -297, +-1578, -597, -1488, -617, -1102, -405, -542, -103, +70, 191, 624, 357, 965, 284, 1008, 38, +833, -267, 571, -532, 254, -618, -48, -444, +-179, -93, -117, 310, -56, 681, -116, 892, +-187, 860, -247, 590, -429, 142, -673, -354, +-726, -752, -579, -980, -366, -971, -20, -686, +533, -232, 1096, 211, 1403, 549, 1389, 777, +1065, 856, 457, 714, -318, 373, -1057, 11, +-1581, -265, -1733, -507, -1473, -674, -925, -611, +-206, -381, 594, -158, 1253, 63, 1541, 273, +1467, 374, 1154, 374, 639, 345, -8, 236, +-558, 27, -891, -171, -1066, -250, -1054, -198, +-800, -100, -438, -32, -113, 68, 194, 178, +487, 101, 659, -127, 656, -245, 549, -228, +408, -241, 266, -200, 110, 50, -78, 371, +-240, 550, -300, 566, -324, 463, -394, 218, +-429, -200, -361, -667, -258, -922, -160, -861, +17, -576, 272, -138, 490, 412, 609, 901, +625, 1132, 494, 1043, 240, 656, -46, 55, +-352, -605, -642, -1133, -747, -1352, -590, -1144, +-317, -583, 1, 141, 372, 826, 638, 1300, +587, 1418, 288, 1105, -41, 426, -311, -400, +-478, -1091, -444, -1446, -186, -1369, 180, -872, +499, -83, 659, 746, 625, 1344, 379, 1493, +-71, 1143, -577, 458, -921, -335, -990, -1051, +-801, -1481, -396, -1422, 162, -875, 727, -59, +1082, 744, 1096, 1349, 824, 1586, 405, 1294, +-81, 534, -534, -350, -779, -1056, -766, -1485, +-632, -1517, -447, -1043, -180, -256, 82, 512, +215, 1113, 247, 1427, 313, 1300, 420, 780, +443, 125, 366, -484, 327, -956, 316, -1153, +160, -1008, -159, -618, -479, -127, -704, 332, +-825, 658, -764, 806, -478, 742, -46, 476, +392, 108, 712, -215, 835, -437, 780, -550, +604, -475, 320, -219, -2, 47, -265, 218, +-466, 343, -643, 396, -710, 256, -601, -62, +-402, -361, -203, -510, 36, -507, 337, -341, +609, -2, 769, 428, 784, 758, 618, 861, +286, 733, -93, 386, -442, -163, -733, -736, +-871, -1117, -771, -1223, -491, -1031, -120, -483, +302, 305, 689, 984, 883, 1354, 798, 1429, +477, 1144, 31, 437, -382, -425, -648, -1045, +-718, -1321, -573, -1344, -242, -1032, 150, -350, +467, 403, 657, 905, 666, 1112, 426, 1077, +-7, 753, -419, 217, -687, -294, -801, -622, +-692, -763, -286, -740, 259, -568, 680, -264, +881, 99, 877, 387, 637, 547, 189, 606, +-301, 550, -689, 343, -896, 43, -860, -265, +-583, -536, -171, -707, 251, -671, 571, -421, +721, -64, 683, 305, 460, 641, 111, 859, +-228, 795, -416, 447, -434, 11, -317, -387, +-94, -737, 161, -903, 291, -767, 236, -423, +76, -13, -147, 404, -412, 716, -560, 764, +-412, 563, -57, 265, 295, -10, 584, -244, +823, -386, 855, -349, 559, -199, 50, -140, +-473, -160, -889, -112, -1100, -68, -1000, -110, +-594, -84, -18, 118, 538, 327, 933, 448, +1068, 506, 884, 446, 440, 218, -69, -111, +-468, -451, -704, -685, -771, -698, -632, -518, +-282, -233, 153, 114, 476, 450, 568, 619, +482, 571, 291, 404, 8, 216, -304, -15, +-473, -282, -430, -429, -279, -363, -101, -233, +116, -170, 340, -97, 473, -2, 491, 56, +444, 105, 313, 188, 30, 254, -354, 296, +-679, 308, -813, 213, -747, -14, -525, -289, +-151, -509, 324, -577, 722, -456, 884, -208, +876, 168, 786, 585, 530, 792, 52, 678, +-474, 378, -880, -57, -1115, -579, -1090, -912, +-753, -870, -236, -544, 277, -53, 707, 508, +984, 932, 1002, 1058, 741, 821, 362, 258, +3, -440, -346, -993, -650, -1230, -751, -1088, +-580, -569, -275, 178, 1, 899, 181, 1338, +267, 1359, 263, 969, 162, 277, -19, -553, +-145, -1238, -101, -1545, 29, -1422, 145, -868, +293, 25, 431, 908, 383, 1429, 158, 1552, +-88, 1303, -313, 652, -550, -242, -717, -1008, +-678, -1391, -414, -1367, -28, -1030, 383, -453, +723, 284, 870, 926, 750, 1195, 412, 1071, +1, 700, -349, 164, -537, -391, -524, -746, +-360, -792, -152, -591, 26, -248, 122, 120, +100, 385, -16, 451, -153, 290, -214, 17, +-147, -225, 58, -351, 358, -292, 641, -30, +746, 276, 594, 477, 225, 527, -268, 348, +-731, -59, -985, -471, -949, -686, -663, -700, +-202, -502, 322, -74, 757, 450, 948, 838, +830, 930, 453, 679, 9, 193, -311, -367, +-463, -853, -451, -1081, -281, -921, -53, -431, +86, 183, 94, 734, 21, 1063, -63, 1060, +-132, 736, -171, 230, -150, -327, -11, -806, +231, -1057, 451, -968, 520, -599, 386, -146, +80, 276, -290, 578, -537, 680, -531, 612, +-312, 466, -12, 270, 297, 88, 516, -2, +467, -44, 150, -151, -201, -332, -480, -529, +-728, -697, -749, -744, -328, -624, 324, -322, +859, 176, 1197, 766, 1253, 1222, 829, 1383, +-4, 1198, -829, 691, -1332, -31, -1503, -790, +-1345, -1385, -805, -1649, 45, -1507, 890, -1023, +1420, -266, 1554, 601, 1341, 1278, 768, 1574, +-74, 1509, -842, 1115, -1220, 445, -1190, -314, +-897, -917, -413, -1204, 152, -1191, 553, -950, +638, -523, 536, 24, 356, 501, 77, 748, +-195, 764, -266, 624, -151, 376, -4, 78, +143, -195, 282, -365, 322, -378, 206, -290, +5, -159, -219, 8, -428, 160, -559, 221, +-548, 207, -380, 110, -99, -95, 207, -295, +463, -358, 638, -299, 682, -180, 548, -9, +297, 179, 60, 367, -140, 504, -377, 488, +-607, 341, -671, 175, -551, -37, -357, -303, +-134, -484, 111, -542, 311, -544, 412, -479, +441, -297, 445, -63, 439, 178, 371, 421, +205, 636, -8, 765, -193, 722, -351, 489, +-477, 183, -511, -130, -483, -472, -459, -748, +-385, -851, -160, -804, 184, -664, 532, -392, +785, 6, 898, 414, 842, 723, 595, 927, +206, 1030, -210, 929, -600, 558, -979, 78, +-1224, -337, -1125, -762, -663, -1155, -49, -1274, +539, -1044, 999, -621, 1201, -104, 1056, 464, +660, 969, 205, 1259, -215, 1240, -565, 930, +-774, 437, -768, -120, -570, -619, -265, -901, +37, -948, 249, -842, 339, -581, 319, -208, +197, 110, 39, 303, -36, 422, -22, 466, +21, 433, 105, 355, 257, 281, 367, 244, +311, 214, 86, 110, -230, -45, -539, -215, +-733, -477, -733, -760, -512, -822, -95, -634, +371, -367, 704, -20, 836, 439, 822, 869, +655, 1102, 270, 1089, -246, 822, -655, 355, +-840, -221, -850, -804, -668, -1231, -252, -1348, +255, -1115, 603, -611, 713, 32, 661, 653, +473, 1115, 138, 1302, -223, 1156, -456, 714, +-540, 107, -503, -488, -305, -910, 38, -1083, +346, -987, 471, -601, 426, -77, 279, 332, +64, 553, -156, 655, -300, 594, -329, 370, +-262, 130, -150, -54, -38, -202, 53, -273, +113, -243, 131, -199, 140, -182, 160, -180, +164, -167, 163, -102, 182, 25, 149, 168, +11, 311, -162, 443, -307, 486, -435, 363, +-505, 71, -419, -287, -194, -589, 80, -752, +381, -718, 682, -417, 817, 72, 655, 550, +293, 873, -91, 955, -423, 714, -659, 208, +-695, -348, -513, -772, -236, -952, 16, -842, +188, -484, 272, 18, 301, 506, 263, 789, +137, 786, 41, 543, 116, 141, 260, -279, +292, -532, 240, -541, 143, -356, -113, -36, +-521, 277, -834, 401, -886, 299, -693, 61, +-289, -223, 264, -460, 786, -548, 1102, -390, +1160, -7, 930, 416, 434, 717, -201, 836, +-787, 711, -1166, 288, -1207, -272, -891, -737, +-353, -999, 218, -987, 675, -681, 904, -203, +846, 312, 562, 745, 167, 930, -191, 862, +-384, 653, -402, 314, -330, -141, -168, -499, +61, -646, 189, -683, 120, -636, -12, -444, +-109, -158, -205, 115, -248, 344, -146, 513, +54, 587, 224, 508, 330, 312, 384, 89, +336, -111, 167, -282, -39, -373, -196, -341, +-295, -254, -329, -178, -273, -99, -153, -24, +-45, 11, 16, 17, 47, 41, 82, 137, +128, 247, 174, 301, 203, 341, 199, 355, +156, 214, 99, -67, 51, -310, -27, -481, +-145, -606, -231, -566, -264, -328, -307, -47, +-319, 214, -212, 459, -27, 609, 153, 589, +350, 410, 525, 133, 548, -124, 426, -283, +216, -385, -88, -426, -439, -345, -646, -174, +-610, -53, -406, 3, -134, 73, 150, 158, +386, 200, 505, 202, 455, 237, 243, 259, +-26, 156, -209, -26, -257, -143, -228, -225, +-151, -318, -3, -311, 181, -146, 273, 48, +209, 168, 54, 230, -127, 223, -303, 113, +-426, -67, -396, -215, -159, -262, 201, -199, +483, -55, 564, 157, 485, 367, 294, 472, +-13, 416, -334, 189, -492, -158, -475, -486, +-371, -659, -181, -653, 87, -486, 292, -158, +342, 255, 293, 567, 193, 685, 38, 633, +-91, 452, -102, 169, -40, -139, 18, -343, +41, -410, -2, -389, -127, -324, -252, -241, +-282, -198, -196, -179, -19, -126, 214, -19, +426, 151, 530, 420, 462, 698, 210, 782, +-127, 641, -417, 365, -609, -44, -680, -573, +-540, -1021, -194, -1185, 211, -1031, 555, -621, +797, -23, 837, 613, 573, 1102, 111, 1320, +-326, 1185, -622, 722, -782, 83, -758, -530, +-497, -989, -102, -1185, 225, -1045, 422, -614, +542, -75, 588, 411, 499, 741, 295, 831, +81, 681, -104, 363, -283, -9, -455, -319, +-553, -457, -506, -423, -328, -280, -105, -77, +128, 140, 371, 285, 545, 283, 546, 143, +391, -59, 182, -233, -43, -333, -270, -316, +-416, -156, -391, 88, -234, 290, -54, 398, +104, 415, 203, 305, 174, 50, 31, -248, +-121, -436, -193, -452, -147, -316, -3, -79, +197, 196, 375, 402, 459, 448, 390, 303, +158, 6, -180, -341, -512, -575, -720, -575, +-712, -363, -450, -9, -13, 416, 450, 798, +793, 939, 901, 737, 702, 274, 257, -283, +-253, -812, -656, -1164, -851, -1166, -776, -779, +-431, -160, 44, 471, 449, 957, 665, 1171, +686, 1057, 502, 652, 138, 86, -250, -452, +-464, -778, -467, -835, -356, -656, -176, -312, +48, 57, 201, 283, 207, 313, 148, 202, +78, -7, -16, -190, -59, -198, 40, -21, +183, 231, 212, 484, 129, 653, 21, 605, +-127, 315, -341, -112, -476, -563, -368, -920, +-69, -1029, 189, -850, 305, -449, 351, 60, +332, 546, 178, 866, -41, 958, -174, 826, +-186, 531, -125, 188, 5, -117, 164, -355, +231, -507, 138, -560, -81, -569, -342, -562, +-565, -505, -620, -352, -406, -127, 11, 147, +458, 486, 829, 831, 1039, 1025, 941, 966, +504, 700, -109, 258, -705, -320, -1149, -874, +-1275, -1195, -995, -1225, -434, -984, 195, -514, +728, 59, 1012, 572, 962, 925, 667, 1052, +283, 928, -83, 645, -329, 297, -393, -78, +-344, -408, -263, -606, -173, -686, -137, -670, +-219, -543, -334, -332, -330, -94, -194, 144, +36, 362, 369, 506, 729, 562, 924, 525, +849, 378, 533, 133, 71, -107, -426, -264, +-863, -359, -1138, -410, -1109, -357, -745, -208, +-222, -91, 287, -17, 745, 73, 1065, 135, +1057, 129, 737, 144, 326, 183, -49, 178, +-398, 157, -665, 146, -753, 82, -666, -25, +-462, -108, -200, -199, 82, -279, 342, -269, +511, -192, 505, -111, 357, 7, 193, 132, +62, 198, -84, 219, -222, 214, -251, 170, +-166, 102, -53, 37, 33, -49, 94, -132, +85, -161, -35, -169, -213, -207, -311, -196, +-254, -81, -80, 56, 142, 142, 372, 227, +545, 324, 561, 296, 407, 113, 139, -94, +-215, -260, -594, -410, -817, -459, -748, -318, +-431, -31, 10, 291, 458, 554, 751, 654, +771, 544, 564, 261, 238, -162, -135, -584, +-455, -815, -592, -798, -539, -563, -353, -132, +-77, 374, 232, 749, 447, 877, 458, 764, +274, 427, 20, -40, -164, -434, -231, -647, +-201, -661, -105, -482, 39, -159, 156, 148, +167, 294, 76, 286, -62, 188, -181, 17, +-223, -154, -160, -175, -2, -25, 231, 183, +434, 356, 463, 460, 265, 396, -62, 123, +-383, -256, -578, -593, -570, -769, -356, -725, +-33, -481, 278, -76, 524, 392, 654, 724, +573, 820, 269, 709, -80, 439, -318, 47, +-463, -332, -536, -551, -436, -580, -155, -459, +123, -249, 262, -35, 281, 101, 228, 131, +125, 92, 27, 47, -25, 18, -16, 59, +54, 198, 165, 343, 240, 400, 176, 356, +-56, 198, -366, -86, -603, -411, -678, -652, +-561, -736, -220, -632, 303, -342, 788, 46, +1011, 445, 933, 747, 630, 825, 149, 694, +-422, 441, -899, 85, -1133, -308, -1061, -582, +-681, -691, -97, -671, 475, -526, 861, -261, +992, 38, 863, 312, 510, 509, 69, 574, +-303, 530, -530, 410, -596, 212, -510, -28, +-337, -257, -166, -440, -36, -532, 45, -532, +86, -435, 105, -225, 146, 59, 260, 329, +428, 542, 526, 659, 453, 591, 215, 349, +-132, 31, -495, -307, -768, -574, -868, -659, +-762, -586, -427, -385, 75, -75, 565, 249, +881, 480, 982, 585, 867, 551, 506, 381, +-27, 160, -543, -73, -870, -311, -936, -484, +-754, -525, -420, -459, -34, -291, 328, -67, +563, 155, 589, 364, 449, 510, 280, 523, +140, 408, 6, 216, -101, -39, -153, -283, +-214, -432, -300, -493, -341, -463, -315, -297, +-255, -53, -140, 181, 48, 347, 248, 388, +398, 328, 478, 224, 474, 87, 347, -60, +95, -138, -230, -148, -490, -128, -575, -79, +-496, -46, -309, -86, -50, -128, 212, -126, +375, -127, 425, -90, 386, 24, 242, 178, +19, 316, -175, 388, -288, 347, -324, 205, +-248, -4, -37, -230, 162, -385, 186, -424, +95, -398, 34, -303, 8, -89, -32, 123, +-26, 248, 34, 339, 52, 395, 6, 344, +-35, 213, -62, 68, -96, -72, -100, -203, +-55, -298, 10, -323, 98, -274, 228, -189, +325, -118, 279, -24, 75, 95, -188, 197, +-389, 276, -451, 324, -360, 303, -138, 221, +141, 104, 356, -57, 436, -236, 397, -375, +272, -423, 66, -375, -153, -228, -303, -18, +-348, 205, -291, 370, -122, 419, 118, 373, +285, 256, 284, 42, 152, -190, -27, -290, +-196, -276, -273, -226, -219, -149, -56, -44, +179, 54, 409, 121, 508, 128, 407, 79, +147, 57, -177, 81, -460, 74, -632, 24, +-639, -15, -431, -50, -34, -71, 381, -85, +658, -89, 774, -56, 714, -2, 409, 34, +-51, 67, -450, 101, -682, 77, -739, 16, +-599, 4, -278, 5, 110, -63, 433, -128, +609, -130, 628, -82, 512, -11, 266, 63, +-70, 137, -384, 207, -550, 236, -540, 177, +-399, 45, -160, -116, 150, -263, 421, -357, +525, -354, 450, -264, 288, -86, 65, 163, +-214, 398, -442, 519, -505, 454, -385, 243, +-142, -10, 156, -243, 411, -411, 525, -439, +456, -324, 249, -120, -43, 87, -346, 205, +-552, 201, -585, 140, -450, 73, -186, -27, +193, -89, 590, -32, 818, 89, 771, 194, +484, 264, 14, 219, -508, 51, -871, -163, +-967, -381, -814, -551, -440, -549, 86, -348, +604, -71, 965, 245, 1071, 572, 878, 759, +419, 709, -160, 483, -691, 150, -1010, -226, +-1005, -562, -711, -769, -284, -775, 137, -578, +477, -260, 671, 63, 679, 350, 507, 571, +228, 674, -56, 618, -258, 435, -351, 211, +-317, 7, -164, -216, -2, -446, 23, -593, +-87, -646, -189, -618, -233, -486, -238, -208, +-151, 187, 69, 618, 302, 941, 449, 1031, +514, 858, 486, 464, 318, -89, 13, -664, +-338, -1078, -615, -1210, -733, -1011, -685, -560, +-477, 10, -141, 586, 206, 1020, 444, 1147, +576, 967, 602, 593, 489, 110, 288, -396, +75, -775, -149, -911, -370, -828, -493, -602, +-508, -285, -466, 103, -365, 460, -180, 662, +39, 697, 239, 620, 411, 416, 537, 108, +561, -198, 418, -448, 137, -591, -162, -562, +-397, -401, -574, -220, -644, 3, -507, 256, +-192, 394, 147, 402, 423, 379, 606, 287, +599, 103, 347, -56, -20, -168, -337, -286, +-552, -359, -605, -307, -424, -194, -87, -78, +246, 36, 504, 142, 625, 231, 533, 304, +277, 334, -37, 287, -369, 172, -647, 0, +-721, -216, -564, -453, -274, -607, 76, -579, +434, -343, 681, 17, 736, 397, 612, 711, +360, 865, 24, 764, -348, 388, -644, -130, +-741, -611, -622, -946, -381, -1058, -67, -816, +282, -283, 553, 293, 625, 748, 511, 1022, +321, 996, 93, 624, -171, 100, -372, -372, +-388, -689, -264, -772, -120, -610, 22, -313, +166, 27, 228, 303, 154, 394, 12, 291, +-115, 112, -189, -34, -188, -108, -76, -66, +135, 70, 353, 230, 447, 333, 398, 306, +254, 102, 18, -209, -296, -498, -555, -640, +-620, -587, -484, -354, -226, 23, 88, 433, +412, 713, 656, 758, 716, 581, 559, 232, +262, -190, -101, -527, -449, -663, -637, -606, +-582, -379, -353, -23, -47, 340, 261, 577, +443, 582, 423, 371, 259, 41, 56, -303, +-118, -563, -189, -623, -126, -429, 6, -64, +113, 333, 160, 649, 161, 747, 120, 559, +13, 193, -159, -210, -298, -541, -318, -711, +-230, -656, -78, -417, 153, -97, 424, 197, +578, 402, 502, 489, 261, 469, -18, 371, +-288, 215, -517, 35, -620, -133, -514, -251, +-225, -332, 138, -371, 446, -325, 638, -192, +676, -52, 504, 79, 144, 222, -250, 324, +-539, 325, -686, 214, -646, 42, -391, -141, +-5, -244, 362, -230, 622, -118, 726, 64, +632, 255, 347, 345, -52, 284, -451, 86, +-723, -199, -772, -475, -630, -650, -355, -626, +32, -387, 456, 4, 754, 444, 834, 827, +727, 1032, 462, 952, 39, 585, -435, 26, +-791, -576, -956, -1044, -886, -1265, -571, -1221, +-105, -863, 364, -227, 756, 505, 960, 1104, +869, 1433, 540, 1417, 135, 1033, -268, 363, +-608, -415, -761, -1076, -701, -1423, -521, -1369, +-281, -954, 6, -274, 243, 424, 351, 897, +379, 1059, 389, 924, 349, 527, 248, 25, +138, -325, 33, -415, -92, -320, -246, -152, +-416, -6, -568, -5, -617, -157, -509, -343, +-269, -424, 56, -352, 404, -109, 674, 291, +794, 689, 735, 875, 472, 773, 62, 438, +-351, -61, -674, -581, -900, -929, -950, -991, +-737, -774, -318, -322, 168, 217, 605, 652, +896, 892, 956, 886, 746, 632, 317, 227, +-177, -207, -593, -583, -838, -793, -855, -775, +-626, -561, -237, -217, 148, 202, 406, 550, +516, 701, 483, 666, 308, 478, 80, 169, +-89, -177, -176, -439, -212, -551, -182, -506, +-112, -360, -81, -150, -115, 71, -150, 245, +-142, 312, -85, 287, 40, 258, 200, 231, +323, 163, 347, 40, 233, -72, 29, -164, +-158, -291, -302, -410, -393, -377, -353, -215, +-181, -37, 13, 150, 185, 346, 336, 456, +393, 410, 295, 261, 74, 46, -179, -178, +-360, -330, -382, -389, -264, -351, -59, -183, +189, 48, 385, 210, 428, 264, 310, 245, +104, 158, -143, 4, -374, -129, -508, -182, +-478, -161, -278, -113, 37, -56, 363, 16, +599, 85, 685, 120, 590, 151, 308, 208, +-102, 231, -486, 168, -711, -2, -727, -230, +-534, -460, -175, -599, 199, -559, 436, -299, +526, 123, 535, 567, 482, 867, 364, 903, +209, 657, 40, 216, -165, -268, -438, -695, +-682, -933, -709, -907, -484, -661, -153, -297, +219, 119, 596, 502, 811, 747, 756, 837, +524, 788, 214, 571, -148, 187, -462, -260, +-608, -651, -556, -877, -340, -902, -23, -732, +259, -362, 397, 149, 377, 630, 223, 898, +-2, 878, -191, 616, -245, 217, -135, -220, +91, -551, 316, -661, 436, -526, 395, -267, +198, -12, -96, 188, -375, 274, -521, 240, +-494, 177, -345, 150, -134, 101, 115, -14, +352, -159, 533, -260, 627, -280, 585, -167, +376, 73, 63, 338, -276, 492, -596, 435, +-753, 157, -609, -259, -259, -624, 64, -728, +290, -519, 441, -137, 491, 290, 424, 647, +291, 804, 146, 669, -9, 310, -212, -120, +-412, -503, -455, -737, -309, -759, -97, -548, +103, -165, 279, 270, 340, 604, 236, 741, +71, 635, -45, 332, -118, -55, -158, -381, +-130, -523, -44, -481, 40, -318, 83, -107, +108, 89, 128, 189, 94, 187, -48, 167, +-217, 175, -276, 142, -205, 78, -83, 22, +81, -39, 298, -93, 428, -97, 315, -49, +21, -21, -276, -44, -481, -114, -520, -198, +-332, -233, 15, -150, 346, 59, 524, 331, +485, 523, 254, 512, -33, 307, -271, -27, +-462, -372, -561, -579, -468, -561, -221, -364, +80, -57, 380, 278, 580, 493, 559, 469, +313, 278, -35, 33, -355, -224, -541, -398, +-531, -381, -354, -174, -120, 98, 93, 332, +257, 442, 344, 370, 317, 143, 196, -144, +18, -409, -192, -550, -367, -484, -399, -265, +-249, 0, -17, 261, 193, 501, 325, 606, +314, 514, 143, 293, -96, 18, -309, -280, +-435, -519, -424, -598, -268, -493, -25, -269, +224, -10, 442, 231, 559, 395, 476, 433, +184, 341, -180, 208, -502, 85, -715, -46, +-719, -168, -473, -234, -82, -264, 310, -254, +618, -155, 738, -14, 590, 94, 251, 154, +-106, 172, -391, 102, -568, -6, -594, -54, +-444, -43, -171, 2, 105, 78, 292, 141, +382, 125, 392, 39, 284, -68, 54, -155, +-201, -216, -355, -220, -365, -161, -242, -55, +-18, 73, 236, 190, 404, 275, 394, 284, +197, 203, -101, 74, -378, -74, -563, -233, +-584, -343, -377, -347, 29, -230, 455, -37, +722, 191, 773, 395, 622, 475, 270, 392, +-219, 171, -637, -157, -815, -508, -772, -721, +-582, -675, -243, -379, 211, 89, 631, 623, +855, 998, 840, 1027, 623, 723, 240, 172, +-220, -500, -590, -1075, -732, -1315, -677, -1138, +-496, -610, -192, 107, 185, 785, 482, 1222, +639, 1340, 661, 1077, 493, 469, 124, -242, +-285, -823, -529, -1147, -540, -1136, -345, -786, +-28, -260, 276, 245, 415, 616, 345, 797, +147, 737, -70, 468, -223, 104, -263, -203, +-175, -354, -12, -372, 154, -270, 310, -63, +417, 140, 364, 194, 129, 87, -178, -101, +-404, -277, -486, -370, -441, -294, -245, -64, +135, 207, 540, 428, 702, 549, 592, 541, +357, 359, 51, 42, -306, -289, -567, -550, +-618, -692, -480, -624, -212, -349, 105, 10, +382, 352, 593, 595, 686, 622, 561, 421, +247, 152, -125, -91, -471, -304, -700, -407, +-673, -347, -382, -217, 10, -71, 346, 91, +571, 211, 645, 241, 514, 213, 228, 144, +-82, 3, -334, -119, -512, -151, -556, -162, +-410, -188, -113, -139, 241, -19, 546, 67, +654, 116, 484, 174, 139, 194, -209, 157, +-436, 139, -471, 126, -325, 44, -99, -109, +87, -279, 155, -420, 150, -469, 154, -384, +140, -159, 98, 181, 97, 532, 104, 726, +30, 692, -62, 482, -112, 118, -165, -313, +-223, -635, -240, -775, -215, -743, -103, -491, +108, -45, 277, 398, 325, 678, 314, 751, +223, 580, -5, 224, -233, -129, -321, -397, +-275, -553, -147, -502, 6, -230, 118, 74, +152, 270, 72, 371, -91, 338, -191, 128, +-169, -147, -96, -337, -16, -390, 82, -278, +179, -25, 240, 258, 252, 425, 226, 421, +146, 274, -61, 37, -383, -196, -615, -354, +-615, -421, -445, -367, -138, -178, 263, 76, +547, 297, 579, 403, 447, 375, 234, 205, +-12, -57, -216, -302, -353, -428, -388, -347, +-271, -87, -82, 217, 39, 440, 60, 491, +-21, 317, -176, -11, -285, -361, -254, -597, +-75, -628, 247, -412, 568, -23, 668, 377, +525, 668, 213, 747, -212, 556, -590, 184, +-758, -228, -746, -576, -590, -738, -275, -659, +119, -390, 469, -18, 688, 364, 694, 628, +505, 664, 222, 487, -119, 177, -444, -155, +-594, -397, -514, -519, -295, -508, -23, -321, +215, -46, 312, 202, 227, 415, 19, 538, +-181, 449, -265, 158, -224, -171, -67, -436, +162, -568, 295, -451, 278, -114, 246, 256, +205, 509, 50, 524, -134, 279, -287, -67, +-460, -331, -546, -434, -436, -363, -186, -118, +163, 190, 514, 387, 641, 408, 526, 290, +328, 54, 59, -238, -258, -445, -426, -474, +-382, -365, -252, -164, -103, 141, 34, 436, +130, 557, 163, 513, 61, 377, -108, 116, +-106, -254, 48, -560, 149, -655, 212, -556, +283, -316, 224, 35, 25, 389, -149, 581, +-225, 538, -253, 337, -290, 63, -283, -214, +-106, -365, 190, -321, 397, -187, 463, -40, +417, 137, 207, 290, -93, 310, -307, 170, +-383, -83, -338, -374, -204, -566, -91, -570, +34, -364, 274, 47, 497, 536, 560, 895, +471, 990, 157, 761, -342, 234, -689, -383, +-696, -855, -438, -1081, -11, -1020, 391, -671, +522, -189, 426, 287, 291, 705, 155, 943, +15, 910, -97, 700, -185, 398, -221, -14, +-180, -466, -116, -785, -8, -872, 134, -724, +160, -370, 59, 51, -15, 362, -12, 517, +50, 528, 107, 376, 44, 109, -45, -115, +1, -180, 80, -162, 97, -125, 128, -24, +124, 112, 2, 207, -121, 231, -159, 137, +-175, -82, -185, -328, -175, -512, -139, -591, +-10, -465, 215, -95, 446, 339, 616, 672, +579, 860, 196, 796, -294, 448, -567, -22, +-596, -444, -442, -705, -196, -760, -31, -654, +71, -406, 223, -29, 362, 334, 446, 517, +467, 550, 306, 481, -20, 241, -320, -94, +-504, -344, -493, -429, -248, -283, 20, 74, +146, 423, 225, 559, 272, 413, 202, 10, +105, -517, 9, -923, -174, -990, -330, -649, +-305, 2, -131, 711, 125, 1177, 326, 1236, +326, 862, 242, 199, 163, -472, -21, -954, +-240, -1115, -347, -883, -405, -389, -401, 153, +-221, 590, 73, 780, 358, 672, 531, 366, +443, -17, 137, -375, -112, -571, -191, -538, +-144, -325, -41, 33, -49, 446, -221, 691, +-338, 676, -285, 429, -125, -55, 121, -609, +341, -950, 365, -951, 232, -599, 60, 26, +-80, 653, -92, 998, -63, 987, -155, 619, +-261, -33, -229, -624, -114, -831, 69, -665, +286, -274, 317, 201, 106, 581, -149, 689, +-309, 432, -333, -89, -225, -606, -62, -888, +154, -813, 365, -360, 393, 312, 286, 901, +180, 1185, -38, 1078, -358, 559, -515, -203, +-492, -891, -393, -1271, -158, -1184, 120, -652, +258, 28, 339, 588, 431, 944, 415, 971, +293, 614, 92, 68, -236, -434, -507, -739, +-500, -702, -331, -312, -115, 217, 118, 644, +193, 780, 67, 516, -53, -28, -66, -592, +35, -978, 201, -1014, 267, -605, 214, 79, +142, 731, 48, 1136, -65, 1199, -167, 869, +-304, 218, -423, -535, -400, -1123, -219, -1352, +80, -1101, 388, -409, 491, 436, 331, 1091, +82, 1347, -150, 1068, -291, 294, -189, -584, +46, -1161, 149, -1294, 165, -916, 169, -66, +72, 856, -40, 1417, -137, 1450, -356, 905, +-529, -69, -437, -1062, -200, -1707, 148, -1770, +575, -1103, 783, 49, 675, 1136, 427, 1805, +68, 1888, -322, 1251, -515, 124, -558, -962, +-588, -1653, -455, -1762, -105, -1214, 212, -261, +387, 719, 483, 1420, 444, 1543, 238, 1014, +-30, 148, -215, -673, -199, -1218, -51, -1285, +61, -808, 148, -31, 206, 714, 117, 1184, +-85, 1214, -310, 800, -499, 99, -511, -661, +-303, -1207, 28, -1353, 430, -1040, 725, -322, +684, 543, 425, 1207, 152, 1434, -144, 1147, +-367, 435, -373, -397, -314, -990, -297, -1184, +-188, -969, -25, -411, 63, 238, 141, 714, +188, 898, 99, 707, 6, 229, 29, -282, +122, -648, 277, -766, 378, -547, 271, -64, +73, 454, -102, 789, -329, 806, -516, 483, +-510, -12, -376, -457, -154, -755, 139, -801, +362, -547, 470, -120, 504, 330, 378, 640, +111, 630, -111, 358, -241, 37, -298, -227, +-221, -390, -56, -327, 71, -22, 146, 302, +147, 478, 21, 454, -184, 180, -344, -254, +-363, -654, -218, -910, 37, -933, 322, -630, +531, -15, 557, 734, 434, 1367, 292, 1653, +101, 1390, -212, 604, -495, -413, -642, -1342, +-712, -1914, -621, -1906, -273, -1295, 181, -308, +560, 754, 732, 1602, 614, 1959, 390, 1692, +225, 955, 23, -28, -179, -1003, -252, -1624, +-304, -1652, -403, -1120, -396, -267, -250, 557, +-98, 1076, 18, 1182, 125, 875, 186, 278, +217, -337, 269, -716, 278, -807, 188, -602, +70, -119, -41, 398, -122, 680, -133, 685, +-114, 435, -127, -40, -197, -554, -279, -837, +-245, -732, -88, -300, 94, 248, 272, 681, +343, 864, 231, 728, 98, 288, 39, -300, +-35, -807, -114, -1045, -150, -884, -166, -332, +-137, 399, -12, 1042, 171, 1334, 273, 1123, +178, 484, -117, -364, -441, -1186, -558, -1660, +-413, -1483, -105, -723, 312, 270, 656, 1164, +660, 1673, 408, 1590, 153, 964, -77, 33, +-267, -900, -357, -1484, -404, -1461, -431, -901, +-377, -115, -239, 601, -60, 1018, 136, 1006, +335, 618, 453, 54, 440, -458, 378, -723, +291, -640, 84, -239, -186, 267, -367, 631, +-434, 700, -409, 460, -314, 19, -201, -492, +-102, -901, 3, -1008, 144, -691, 315, -61, +480, 598, 539, 1056, 368, 1237, 37, 1043, +-227, 445, -361, -355, -420, -1057, -374, -1413, +-208, -1302, -21, -753, 89, 42, 126, 820, +168, 1331, 213, 1357, 150, 874, -32, 154, +-167, -562, -153, -1097, -12, -1187, 179, -762, +306, -99, 276, 463, 87, 798, -173, 829, +-389, 485, -444, -59, -322, -498, -126, -668, +69, -495, 238, -107, 329, 238, 315, 453, +256, 535, 210, 418, 131, 111, -67, -209, +-329, -465, -487, -678, -453, -690, -268, -386, +21, 36, 359, 479, 581, 943, 519, 1165, +216, 907, -161, 276, -469, -466, -571, -1132, +-410, -1471, -89, -1300, 218, -717, 380, 110, +407, 1007, 387, 1579, 288, 1558, 70, 1046, +-166, 242, -326, -626, -417, -1254, -441, -1416, +-362, -1130, -148, -512, 143, 235, 364, 786, +415, 954, 333, 815, 244, 432, 198, -74, +127, -421, 17, -465, -118, -279, -312, -14, +-484, 261, -511, 428, -410, 305, -194, -102, +151, -534, 482, -747, 608, -673, 502, -357, +301, 131, 116, 633, -69, 960, -240, 1023, +-341, 755, -350, 207, -269, -413, -141, -938, +-6, -1216, 131, -1069, 177, -553, 76, 87, +-18, 689, 2, 1089, 83, 1063, 184, 616, +286, 35, 334, -458, 226, -702, -68, -626, +-408, -383, -603, -128, -575, 118, -348, 276, +-4, 295, 358, 243, 631, 151, 684, 47, +471, -5, 88, -63, -294, -189, -549, -233, +-650, -166, -536, -111, -170, -32, 257, 100, +546, 182, 704, 268, 635, 390, 202, 332, +-373, 74, -734, -205, -782, -477, -561, -667, +-92, -561, 470, -243, 820, 127, 773, 570, +388, 881, -133, 766, -547, 310, -709, -231, +-610, -696, -258, -886, 247, -719, 642, -257, +770, 394, 651, 988, 271, 1138, -342, 747, +-926, -20, -1160, -941, -954, -1573, -374, -1545, +452, -913, 1204, 161, 1528, 1421, 1316, 2274, +622, 2273, -373, 1453, -1256, 52, -1639, -1570, +-1467, -2783, -866, -3036, 7, -2226, 888, -586, +1439, 1345, 1460, 2847, 976, 3370, 229, 2713, +-456, 1114, -934, -779, -1180, -2333, -1022, -3037, +-415, -2653, 283, -1433, 750, 123, 933, 1533, +786, 2328, 303, 2248, -318, 1465, -804, 284, +-937, -991, -598, -1859, 40, -1892, 588, -1190, +842, -90, 814, 1000, 451, 1607, -138, 1548, +-530, 849, -585, -257, -557, -1191, -486, -1533, +-247, -1328, 13, -606, 149, 474, 324, 1288, +594, 1391, 684, 1031, 490, 406, 202, -458, +-118, -1098, -444, -1135, -594, -696, -545, 13, +-456, 668, -350, 874, -172, 626, 89, 106, +434, -527, 727, -993, 779, -998, 623, -495, +351, 382, -89, 1343, -599, 1821, -879, 1507, +-889, 560, -770, -751, -409, -2015, 213, -2633, +768, -2272, 1073, -932, 1141, 938, 825, 2480, +103, 3086, -679, 2629, -1196, 1259, -1312, -598, +-980, -2233, -314, -3072, 449, -2852, 1111, -1620, +1438, 149, 1188, 1791, 493, 2835, -277, 2838, +-956, 1678, -1411, -7, -1361, -1538, -773, -2511, +81, -2501, 903, -1400, 1390, 248, 1315, 1729, +751, 2418, -30, 1983, -749, 737, -1124, -695, +-1012, -1953, -580, -2558, -40, -1949, 519, -412, +884, 1248, 828, 2484, 447, 2881, -48, 2154, +-546, 556, -861, -1330, -779, -2845, -322, -3369, +280, -2673, 791, -1037, 1028, 1011, 825, 2796, +200, 3613, -517, 3172, -1016, 1624, -1190, -508, +-935, -2397, -257, -3344, 557, -3130, 1164, -1852, +1370, 58, 1062, 1810, 288, 2716, -602, 2559, +-1225, 1546, -1413, 96, -1073, -1265, -289, -2021, +538, -1874, 1127, -1043, 1378, 27, 1077, 1094, +334, 1793, -379, 1630, -938, 701, -1342, -413, +-1223, -1370, -484, -1901, 366, -1684, 939, -783, +1228, 393, 1117, 1523, 479, 2202, -369, 2041, +-939, 1130, -1046, -117, -733, -1293, -176, -2046, +376, -2153, 754, -1544, 797, -374, 440, 856, +-71, 1680, -472, 1871, -704, 1370, -739, 392, +-486, -556, 89, -1111, 762, -1191, 1115, -753, +972, -18, 466, 571, -226, 830, -899, 702, +-1282, 104, -1165, -574, -559, -881, 217, -843, +826, -510, 1152, 109, 1106, 730, 648, 1071, +3, 1069, -551, 655, -934, -36, -1032, -637, +-665, -1017, -9, -1120, 511, -676, 789, 62, +836, 561, 473, 854, -153, 937, -598, 510, +-774, -228, -759, -765, -422, -981, 204, -887, +786, -402, 1042, 344, 905, 1017, 471, 1434, +-128, 1387, -784, 755, -1275, -212, -1305, -1187, +-801, -1865, 2, -1952, 772, -1347, 1258, -198, +1367, 1046, 1075, 1867, 404, 2096, -429, 1646, +-1075, 570, -1386, -616, -1320, -1403, -752, -1722, +138, -1555, 873, -766, 1254, 283, 1284, 1044, +877, 1399, 133, 1246, -600, 516, -1061, -310, +-1091, -896, -713, -1197, -225, -997, 203, -369, +607, 259, 801, 782, 644, 1167, 350, 1015, +26, 385, -329, -123, -483, -437, -367, -768, +-217, -817, -83, -493, 83, -149, 188, 85, +169, 176, 16, 76, -218, -56, -290, -27, +-79, 168, 193, 476, 377, 795, 559, 891, +622, 631, 329, 164, -187, -405, -662, -1052, +-1001, -1548, -1049, -1559, -648, -993, 31, -161, +638, 670, 1006, 1436, 1158, 1850, 1006, 1603, +404, 918, -396, 74, -927, -810, -1070, -1386, +-854, -1394, -336, -1040, 184, -535, 488, 114, +599, 632, 444, 762, 60, 645, -250, 350, +-316, -138, -175, -482, 131, -415, 433, -34, +503, 472, 350, 828, 88, 818, -339, 504, +-801, -31, -903, -782, -608, -1381, -161, -1434, +390, -1057, 893, -465, 1021, 358, 708, 1150, +161, 1509, -366, 1443, -718, 1093, -832, 454, +-578, -308, -26, -841, 458, -1036, 670, -979, +628, -752, 341, -468, -131, -290, -684, -203, +-1074, -22, -923, 268, -256, 562, 468, 926, +1059, 1322, 1497, 1388, 1421, 990, 620, 305, +-458, -605, -1325, -1667, -1846, -2357, -1798, -2235, +-1073, -1477, -35, -332, 995, 1054, 1804, 2217, +2043, 2667, 1638, 2335, 747, 1354, -494, -28, +-1566, -1369, -1940, -2185, -1769, -2308, -1207, -1801, +-109, -799, 1122, 379, 1752, 1330, 1657, 1743, +1131, 1511, 320, 845, -588, 93, -1233, -557, +-1376, -939, -1024, -914, -364, -521, 310, -40, +794, 273, 999, 401, 868, 325, 461, 61, +-30, -206, -441, -299, -716, -155, -833, 162, +-658, 408, -162, 419, 258, 211, 350, -118, +457, -525, 663, -836, 549, -673, 195, -74, +29, 507, -74, 908, -343, 1159, -568, 1044, +-638, 406, -645, -529, -532, -1322, -219, -1739, +262, -1649, 796, -962, 1125, 162, 1109, 1374, +827, 2189, 269, 2240, -534, 1580, -1215, 454, +-1439, -892, -1213, -2000, -685, -2413, -14, -2033, +648, -1124, 1162, 35, 1344, 1211, 1124, 2017, +653, 2173, 28, 1686, -735, 721, -1322, -414, +-1390, -1343, -1040, -1777, -408, -1610, 459, -1041, +1151, -254, 1288, 589, 994, 1140, 484, 1183, +-159, 856, -750, 412, -1058, -62, -967, -478, +-598, -608, -142, -448, 405, -256, 913, -98, +1005, 72, 679, 195, 280, 157, -121, 7, +-571, -28, -850, 36, -806, 9, -608, -65, +-330, -56, 160, -7, 717, 44, 1000, 130, +926, 231, 602, 236, 133, 179, -415, 114, +-913, -89, -1072, -411, -854, -655, -538, -692, +-107, -504, 539, -120, 1113, 398, 1353, 933, +1168, 1231, 504, 1117, -362, 618, -1053, -136, +-1477, -946, -1480, -1526, -897, -1621, -54, -1222, +609, -452, 1084, 549, 1393, 1483, 1303, 1969, +828, 1852, 221, 1171, -475, 93, -1120, -1101, +-1391, -2030, -1284, -2313, -929, -1861, -317, -845, +363, 483, 866, 1740, 1180, 2419, 1270, 2329, +1075, 1570, 648, 275, 68, -1163, -572, -2071, +-1137, -2211, -1423, -1836, -1294, -1003, -883, 190, +-349, 1186, 343, 1588, 1051, 1548, 1457, 1202, +1497, 610, 1267, 4, 684, -429, -251, -694, +-1142, -801, -1637, -763, -1732, -689, -1391, -642, +-585, -562, 343, -371, 1079, -31, 1595, 491, +1769, 1104, 1428, 1602, 661, 1721, -277, 1333, +-1108, 518, -1581, -565, -1582, -1657, -1178, -2393, +-544, -2499, 130, -1881, 656, -657, 944, 734, +1082, 1883, 1134, 2588, 991, 2679, 638, 2005, +172, 746, -404, -609, -1007, -1701, -1363, -2322, +-1403, -2330, -1287, -1767, -963, -809, -258, 287, +707, 1128, 1625, 1565, 2225, 1621, 2249, 1283, +1601, 719, 455, 221, -920, -156, -2142, -515, +-2718, -762, -2449, -792, -1532, -790, -234, -842, +1132, -718, 2177, -372, 2642, 77, 2359, 554, +1248, 958, -296, 1176, -1585, 1118, -2276, 770, +-2242, 170, -1396, -531, -104, -1016, 1007, -1102, +1679, -908, 1838, -493, 1314, 54, 255, 519, +-743, 731, -1310, 631, -1525, 305, -1349, -65, +-624, -320, 392, -468, 1201, -506, 1553, -232, +1425, 264, 884, 574, 132, 717, -599, 799, +-1152, 572, -1379, -25, -1161, -674, -652, -1115, +-137, -1294, 353, -1139, 749, -636, 816, 70, +705, 838, 694, 1457, 605, 1617, 316, 1321, +27, 734, -288, -34, -744, -797, -1110, -1372, +-1134, -1593, -822, -1359, -247, -761, 446, 16, +953, 758, 1122, 1244, 1030, 1352, 638, 1025, +-40, 375, -643, -338, -926, -881, -938, -1093, +-629, -882, 5, -248, 699, 501, 1120, 958, +1046, 1090, 496, 889, -302, 201, -1095, -674, +-1610, -1342, -1571, -1675, -891, -1488, 205, -679, +1290, 436, 2049, 1428, 2274, 2075, 1719, 2134, +478, 1522, -893, 532, -1953, -603, -2512, -1710, +-2352, -2283, -1406, -2158, -17, -1611, 1297, -651, +2162, 604, 2361, 1596, 1821, 2044, 718, 2055, +-581, 1526, -1600, 457, -1927, -618, -1575, -1234, +-803, -1481, 257, -1426, 1224, -966, 1539, -254, +1249, 353, 669, 688, -228, 870, -1210, 865, +-1666, 507, -1460, -18, -874, -346, 32, -497, +1151, -556, 1964, -402, 2088, 11, 1611, 468, +670, 705, -633, 643, -1892, 366, -2556, -39, +-2385, -564, -1538, -1016, -295, -1095, 1096, -803, +2237, -285, 2665, 469, 2257, 1172, 1206, 1404, +-188, 1221, -1512, 746, -2357, -72, -2463, -954, +-1728, -1454, -406, -1489, 991, -1050, 2054, -153, +2455, 838, 1902, 1472, 537, 1611, -1007, 1156, +-2141, 109, -2572, -1063, -2114, -1847, -776, -1989, +1022, -1337, 2519, -28, 3060, 1387, 2523, 2370, +1186, 2615, -603, 2038, -2285, 675, -3170, -1140, +-3011, -2667, -1985, -3328, -321, -3051, 1481, -1908, +2691, -43, 2982, 1972, 2440, 3420, 1175, 3918, +-467, 3336, -1803, 1698, -2369, -470, -2117, -2440, +-1172, -3770, 61, -4062, 961, -3132, 1257, -1344, +1092, 758, 596, 2628, -101, 3644, -643, 3561, +-689, 2554, -316, 928, 189, -882, 664, -2275, +935, -2924, 774, -2840, 201, -2013, -566, -631, +-1263, 754, -1546, 1759, -1217, 2270, -422, 2165, +556, 1480, 1394, 455, 1747, -573, 1517, -1375, +872, -1791, -38, -1664, -998, -1082, -1593, -310, +-1587, 493, -1155, 1187, -479, 1534, 356, 1405, +1086, 880, 1381, 103, 1171, -740, 688, -1275, +232, -1379, -164, -1186, -571, -592, -809, 276, +-761, 945, -645, 1287, -599, 1327, -476, 886, +-166, 114, 269, -547, 724, -959, 1124, -1183, +1348, -1009, 1263, -431, 839, 142, 75, 568, +-933, 811, -1842, 724, -2271, 472, -2078, 222, +-1253, -71, 122, -273, 1601, -274, 2546, -216, +2728, -252, 2223, -308, 1014, -304, -602, -296, +-1915, -204, -2578, 59, -2620, 366, -1939, 643, +-601, 835, 926, 740, 2102, 328, 2523, -194, +2085, -639, 1055, -1027, -214, -1203, -1370, -851, +-1978, -216, -1805, 302, -1059, 854, -78, 1399, +914, 1392, 1579, 817, 1585, 175, 1001, -448, +143, -1155, -792, -1553, -1569, -1385, -1781, -865, +-1187, -122, -109, 667, 891, 1227, 1584, 1499, +1851, 1417, 1445, 883, 498, 129, -536, -567, +-1405, -1151, -1868, -1526, -1655, -1471, -949, -1017, +-110, -340, 752, 464, 1463, 1133, 1687, 1464, +1369, 1524, 757, 1215, 34, 449, -743, -372, +-1370, -905, -1524, -1252, -1153, -1466, -585, -1277, +-47, -663, 563, -56, 1124, 397, 1261, 918, +1003, 1395, 671, 1475, 252, 1160, -352, 679, +-947, 86, -1257, -639, -1166, -1337, -782, -1775, +-280, -1730, 331, -1162, 948, -385, 1225, 393, +1089, 1262, 783, 1953, 344, 1966, -319, 1421, +-1003, 696, -1332, -168, -1159, -1079, -678, -1723, +-113, -1899, 547, -1603, 1177, -938, 1318, -126, +865, 663, 263, 1358, -279, 1765, -823, 1632, +-1127, 1072, -977, 356, -530, -375, 87, -1000, +734, -1357, 1045, -1314, 897, -900, 507, -388, +-19, 9, -585, 342, -884, 623, -798, 755, +-495, 699, -105, 613, 337, 598, 688, 466, +741, 43, 509, -472, 222, -795, -83, -961, +-493, -1043, -746, -841, -594, -311, -283, 300, +-11, 854, 328, 1163, 601, 1104, 574, 908, +367, 614, 155, -56, -95, -880, -370, -1257, +-552, -1194, -573, -1044, -430, -650, -204, 124, +23, 838, 304, 1172, 677, 1140, 927, 877, +849, 545, 483, 122, -68, -378, -699, -745, +-1228, -891, -1416, -946, -1114, -989, -433, -839, +362, -327, 1117, 361, 1619, 1036, 1621, 1588, +1175, 1831, 414, 1600, -577, 823, -1461, -296, +-1903, -1448, -1841, -2373, -1208, -2663, -62, -2128, +1114, -1017, 1847, 445, 1978, 1905, 1486, 2866, +545, 3050, -456, 2419, -1258, 1101, -1709, -585, +-1581, -2121, -904, -3050, -62, -3141, 742, -2335, +1383, -929, 1523, 635, 1079, 2072, 324, 2833, +-529, 2552, -1208, 1675, -1348, 641, -894, -530, +-154, -1488, 493, -1709, 847, -1392, 916, -1041, +694, -594, 195, 6, -350, 352, -701, 363, +-762, 374, -521, 551, -87, 757, 390, 823, +765, 805, 801, 721, 375, 383, -232, -268, +-692, -1034, -927, -1602, -821, -1717, -246, -1343, +506, -592, 1015, 324, 1179, 1218, 964, 1863, +334, 1901, -474, 1307, -1222, 446, -1682, -349, +-1424, -940, -499, -1304, 506, -1329, 1357, -938, +1970, -445, 1850, -102, 883, 188, -306, 422, +-1280, 492, -1993, 531, -2159, 663, -1496, 731, +-334, 698, 836, 673, 1862, 434, 2492, -213, +2241, -901, 1143, -1396, -210, -1769, -1433, -1759, +-2361, -1085, -2598, 42, -1936, 1224, -771, 2149, +470, 2532, 1627, 2257, 2412, 1351, 2470, -10, +1803, -1385, 685, -2296, -529, -2632, -1529, -2409, +-2190, -1512, -2334, -126, -1729, 1174, -642, 2045, +385, 2438, 1246, 2242, 1914, 1454, 2042, 320, +1532, -774, 678, -1515, -254, -1821, -1045, -1732, +-1509, -1273, -1578, -541, -1198, 210, -473, 723, +240, 998, 724, 1173, 1035, 1146, 1054, 771, +621, 252, 29, -102, -334, -334, -506, -599, +-563, -735, -335, -634, 132, -475, 473, -337, +484, -211, 267, -145, -59, -23, -454, 271, +-793, 581, -835, 718, -520, 784, 7, 822, +599, 621, 1058, 175, 1177, -349, 916, -887, +360, -1283, -323, -1368, -882, -1116, -1182, -579, +-1177, 121, -834, 880, -262, 1485, 317, 1662, +771, 1369, 1009, 731, 977, -13, 751, -669, +437, -1195, 77, -1440, -309, -1262, -638, -769, +-871, -187, -1049, 267, -1125, 589, -949, 811, +-400, 821, 485, 658, 1417, 470, 2030, 323, +2138, 203, 1664, -31, 589, -348, -854, -556, +-2201, -714, -2985, -843, -2926, -760, -2054, -406, +-568, 13, 1237, 327, 2862, 591, 3727, 754, +3477, 727, 2157, 618, 219, 445, -1771, 219, +-3317, 64, -3892, -116, -3191, -428, -1556, -729, +316, -901, 1908, -1001, 2910, -1015, 3044, -742, +2233, -123, 824, 644, -578, 1322, -1528, 1763, +-1887, 1908, -1672, 1621, -951, 757, -30, -393, +599, -1449, 731, -2247, 522, -2549, 132, -2175, +-257, -1258, -396, -62, -278, 1184, -42, 2157, +312, 2514, 733, 2254, 983, 1626, 927, 739, +595, -292, 23, -1252, -685, -1890, -1263, -2067, +-1510, -1966, -1471, -1686, -1140, -1064, -424, -186, +477, 743, 1186, 1707, 1697, 2498, 2094, 2752, +2064, 2411, 1368, 1609, 293, 318, -858, -1293, +-2042, -2658, -2970, -3394, -3102, -3405, -2303, -2596, +-928, -1146, 717, 518, 2409, 2122, 3673, 3373, +3908, 3871, 2956, 3403, 1214, 2078, -836, 289, +-2801, -1499, -4079, -2960, -4119, -3774, -2973, -3616, +-1079, -2517, 1099, -880, 2966, 820, 3915, 2218, +3719, 3003, 2545, 3009, 745, 2345, -1184, 1276, +-2680, 63, -3325, -1058, -3036, -1870, -1991, -2181, +-478, -1968, 1086, -1453, 2182, -766, 2530, 20, +2218, 764, 1450, 1357, 377, 1669, -719, 1565, +-1436, 1117, -1613, 496, -1426, -226, -1088, -945, +-613, -1448, -11, -1570, 513, -1238, 784, -468, +988, 436, 1270, 1153, 1307, 1603, 873, 1607, +253, 979, -355, -52, -1058, -1067, -1736, -1837, +-1998, -2191, -1643, -1868, -832, -806, 208, 639, +1335, 2008, 2329, 2932, 2779, 3142, 2381, 2449, +1239, 823, -258, -1235, -1786, -2963, -3035, -3937, +-3508, -3938, -2874, -2857, -1413, -936, 329, 1274, +2034, 3103, 3421, 4168, 3982, 4284, 3353, 3294, +1775, 1467, -155, -573, -2028, -2359, -3538, -3642, +-4210, -4118, -3713, -3531, -2262, -2169, -383, -589, +1545, 1013, 3229, 2362, 4182, 3104, 4030, 3266, +2938, 2906, 1279, 2002, -709, 774, -2635, -484, +-3870, -1674, -4120, -2737, -3543, -3378, -2275, -3326, +-372, -2629, 1705, -1386, 3234, 281, 3936, 2085, +3937, 3591, 3143, 4295, 1448, 3949, -643, 2656, +-2376, 669, -3471, -1592, -3933, -3533, -3573, -4567, +-2282, -4359, -435, -3038, 1358, -1016, 2718, 1230, +3480, 3169, 3505, 4244, 2701, 4075, 1257, 2799, +-350, 894, -1670, -1135, -2536, -2787, -2933, -3638, +-2759, -3462, -1966, -2311, -806, -559, 365, 1278, +1431, 2662, 2313, 3222, 2734, 2932, 2537, 1847, +1869, 150, 834, -1569, -493, -2667, -1762, -2961, +-2653, -2565, -3067, -1521, -2815, -13, -1759, 1400, +-230, 2336, 1324, 2740, 2674, 2523, 3509, 1699, +3439, 540, 2419, -650, 780, -1659, -1070, -2362, +-2727, -2619, -3761, -2295, -3793, -1521, -2754, -522, +-1037, 618, 796, 1724, 2423, 2466, 3557, 2688, +3744, 2438, 2895, 1744, 1450, 672, -209, -531, +-1895, -1626, -3132, -2470, -3423, -2852, -2795, -2680, +-1660, -2041, -299, -1024, 1073, 168, 2092, 1348, +2476, 2434, 2288, 3112, 1766, 3079, 1060, 2507, +225, 1587, -663, 270, -1365, -1267, -1697, -2570, +-1796, -3369, -1781, -3575, -1426, -3046, -680, -1859, +129, -337, 914, 1271, 1765, 2698, 2347, 3613, +2267, 3815, 1684, 3193, 807, 1883, -365, 260, +-1562, -1373, -2338, -2788, -2552, -3643, -2192, -3667, +-1274, -2916, -37, -1643, 1209, -102, 2148, 1430, +2405, 2679, 1951, 3391, 1149, 3301, 164, 2460, +-895, 1180, -1576, -268, -1616, -1634, -1294, -2622, +-833, -2942, -195, -2504, 436, -1533, 763, -330, +804, 880, 707, 1871, 486, 2331, 233, 2018, +137, 1178, 152, 206, 38, -764, -252, -1534, +-595, -1769, -923, -1335, -1114, -494, -931, 328, +-328, 1034, 463, 1590, 1240, 1657, 1823, 1096, +1956, 152, 1460, -832, 401, -1607, -935, -2009, +-2107, -1846, -2736, -1156, -2674, -182, -1830, 897, +-289, 1775, 1422, 2098, 2682, 1875, 3195, 1333, +2875, 637, 1833, -185, 374, -944, -1162, -1330, +-2360, -1424, -2803, -1471, -2540, -1418, -1920, -1151, +-1007, -744, 156, -265, 1157, 374, 1702, 1219, +1936, 2070, 1958, 2674, 1720, 2805, 1291, 2280, +725, 1109, -28, -505, -906, -2245, -1781, -3700, +-2529, -4425, -2891, -4107, -2636, -2746, -1731, -622, +-275, 1801, 1479, 3893, 3071, 5121, 4038, 5198, +4086, 4011, 3089, 1740, 1172, -968, -1148, -3305, +-3114, -4779, -4261, -5142, -4486, -4216, -3641, -2265, +-1711, 5, 689, 2000, 2675, 3337, 3764, 3773, +3881, 3330, 3071, 2291, 1519, 1004, -282, -270, +-1709, -1310, -2373, -1915, -2310, -2053, -1770, -1863, +-985, -1491, -186, -1006, 335, -446, 501, 50, +495, 419, 444, 839, 393, 1352, 481, 1722, +800, 1787, 1210, 1548, 1351, 1036, 942, 245, +149, -801, -763, -1816, -1780, -2402, -2656, -2417, +-2771, -1982, -1926, -1198, -530, -70, 1059, 1193, +2605, 2135, 3619, 2579, 3547, 2614, 2360, 2160, +529, 1167, -1421, -166, -3036, -1516, -3802, -2570, +-3418, -3085, -2121, -2880, -407, -1963, 1351, -554, +2721, 1014, 3189, 2288, 2709, 2945, 1683, 2918, +383, 2160, -960, 886, -1848, -434, -1955, -1509, +-1488, -2194, -877, -2284, -364, -1763, 35, -980, +261, -233, 217, 435, 99, 863, 237, 933, +609, 910, 1003, 948, 1306, 942, 1400, 884, +1114, 811, 409, 571, -599, 20, -1664, -725, +-2461, -1447, -2701, -1988, -2210, -2142, -1021, -1796, +516, -1017, 1901, 116, 2818, 1397, 3092, 2468, +2596, 2946, 1431, 2694, -29, 1872, -1367, 588, +-2246, -943, -2525, -2196, -2319, -2822, -1714, -2833, +-749, -2292, 305, -1224, 1105, 125, 1540, 1213, +1628, 1806, 1469, 2039, 1162, 1946, 725, 1556, +222, 970, -228, 325, -609, -195, -924, -614, +-1116, -1078, -1211, -1538, -1163, -1837, -845, -1847, +-339, -1562, 148, -949, 614, 51, 1069, 1230, +1296, 2229, 1175, 2759, 852, 2653, 464, 1942, +45, 734, -286, -706, -440, -1878, -486, -2500, +-553, -2570, -677, -2085, -826, -1128, -965, -52, +-1026, 796, -836, 1344, -321, 1542, 397, 1309, +1248, 881, 2068, 598, 2512, 477, 2408, 413, +1746, 371, 444, 220, -1261, -233, -2779, -948, +-3724, -1697, -3875, -2233, -3002, -2288, -1216, -1689, +936, -539, 2911, 901, 4235, 2341, 4490, 3391, +3590, 3608, 1815, 2812, -423, 1240, -2539, -678, +-3895, -2457, -4174, -3610, -3408, -3861, -1825, -3120, +102, -1486, 1792, 476, 2799, 2011, 2898, 2835, +2249, 3008, 1265, 2442, 243, 1200, -654, -153, +-1188, -1119, -1223, -1626, -900, -1616, -529, -1080, +-361, -357, -370, 178, -413, 372, -421, 166, +-356, -269, -99, -611, 403, -707, 1004, -462, +1436, 256, 1517, 1274, 1230, 2052, 619, 2179, +-245, 1648, -1152, 568, -1798, -872, -2010, -2216, +-1733, -3004, -995, -2978, 3, -2063, 931, -559, +1605, 1047, 1925, 2358, 1758, 3056, 1187, 2930, +459, 2001, -341, 604, -1150, -829, -1698, -1982, +-1781, -2491, -1410, -2222, -691, -1454, 190, -478, +980, 495, 1445, 1200, 1466, 1449, 1099, 1232, +488, 725, -230, 157, -880, -290, -1256, -469, +-1185, -367, -674, -70, 62, 203, 770, 241, +1277, 84, 1345, -199, 821, -558, -76, -766, +-960, -675, -1623, -388, -1883, 2, -1461, 451, +-416, 790, 791, 856, 1772, 765, 2349, 594, +2335, 222, 1614, -269, 317, -646, -1147, -799, +-2234, -732, -2652, -498, -2452, -143, -1665, 207, +-371, 386, 960, 393, 1850, 269, 2245, 77, +2209, -102, 1671, -223, 713, -208, -294, -60, +-1021, 150, -1409, 368, -1522, 510, -1375, 566, +-1019, 492, -551, 158, -68, -320, 354, -760, +684, -1114, 972, -1258, 1177, -1043, 1118, -471, +750, 241, 262, 878, -180, 1411, -534, 1714, +-732, 1542, -726, 929, -568, 158, -340, -523, +-141, -1094, -74, -1536, -118, -1645, -219, -1363, +-310, -852, -192, -248, 191, 346, 619, 823, +983, 1134, 1310, 1305, 1356, 1338, 877, 1146, +44, 753, -779, 321, -1423, -149, -1861, -787, +-1966, -1415, -1535, -1673, -590, -1560, 484, -1277, +1298, -792, 1790, -82, 1983, 639, 1677, 1217, +848, 1622, -42, 1756, -582, 1542, -912, 1107, +-1212, 576, -1241, -51, -848, -733, -433, -1354, +-313, -1779, -188, -1924, 152, -1835, 419, -1507, +502, -799, 678, 269, 953, 1415, 1015, 2317, +748, 2798, 316, 2759, -121, 2098, -574, 853, +-1013, -660, -1222, -2009, -1040, -2894, -594, -3127, +-79, -2629, 394, -1547, 698, -189, 714, 1108, +493, 2043, 166, 2444, -145, 2304, -249, 1717, +-31, 841, 317, -77, 527, -790, 544, -1246, +401, -1421, 108, -1271, -357, -938, -885, -583, +-1208, -247, -1171, 59, -855, 348, -332, 538, +365, 587, 1001, 630, 1333, 643, 1326, 499, +1027, 272, 485, 146, -129, 95, -609, -40, +-841, -189, -802, -287, -560, -486, -284, -710, +-97, -763, 1, -688, -32, -500, -235, -147, +-443, 310, -379, 751, -13, 1042, 462, 1112, +910, 922, 1294, 510, 1447, 0, 1152, -508, +456, -853, -390, -932, -1172, -811, -1753, -517, +-1963, -93, -1704, 287, -1033, 451, -173, 383, +637, 200, 1270, -67, 1633, -365, 1635, -426, +1346, -102, 973, 419, 542, 847, -14, 1055, +-564, 1020, -945, 642, -1234, -75, -1482, -910, +-1561, -1564, -1365, -1790, -928, -1579, -302, -1040, +476, -192, 1326, 808, 2070, 1632, 2437, 2026, +2271, 1934, 1590, 1453, 513, 633, -764, -368, +-1904, -1190, -2597, -1635, -2721, -1713, -2298, -1467, +-1401, -934, -180, -246, 1058, 346, 1955, 751, +2332, 999, 2244, 1021, 1756, 904, 918, 785, +-37, 572, -794, 233, -1285, -96, -1566, -362, +-1574, -631, -1257, -887, -768, -1011, -283, -977, +235, -791, 758, -406, 1075, 100, 1086, 594, +956, 1052, 750, 1403, 373, 1465, -109, 1115, +-495, 455, -737, -288, -831, -972, -657, -1515, +-276, -1746, 41, -1491, 212, -801, 354, 85, +409, 925, 237, 1532, -56, 1764, -235, 1493, +-287, 751, -327, -167, -283, -944, -11, -1424, +384, -1521, 609, -1182, 611, -485, 518, 287, +352, 837, 47, 1083, -286, 1058, -490, 788, +-607, 348, -720, -69, -760, -315, -631, -467, +-380, -608, -30, -680, 432, -709, 868, -725, +1110, -566, 1178, -122, 1080, 450, 693, 971, +63, 1387, -553, 1565, -1046, 1326, -1421, 684, +-1524, -234, -1204, -1260, -576, -2097, 82, -2404, +633, -2020, 1039, -1067, 1239, 241, 1136, 1572, +767, 2473, 400, 2671, 184, 2143, -38, 1030, +-349, -323, -566, -1466, -655, -2091, -798, -2158, +-980, -1701, -947, -802, -637, 184, -216, 917, +251, 1303, 805, 1276, 1303, 897, 1516, 394, +1370, -44, 884, -273, 169, -263, -583, -118, +-1189, 8, -1499, -12, -1374, -186, -888, -482, +-291, -753, 255, -779, 683, -559, 850, -121, +681, 540, 398, 1150, 174, 1357, -25, 1100, +-151, 548, -60, -149, 175, -886, 329, -1372, +261, -1361, 22, -929, -248, -238, -540, 537, +-806, 1129, -789, 1301, -414, 1046, 1, 531, +262, -128, 461, -775, 608, -1133, 537, -1086, +312, -702, 182, -174, 159, 299, 95, 664, +33, 883, 65, 832, 58, 510, -139, 137, +-456, -118, -692, -322, -814, -469, -867, -446, +-711, -356, -207, -318, 477, -302, 1038, -266, +1342, -156, 1420, 39, 1238, 294, 656, 587, +-184, 814, -877, 845, -1276, 638, -1492, 303, +-1419, -84, -927, -592, -260, -1072, 240, -1226, +589, -1057, 963, -696, 1213, -156, 1095, 508, +761, 1068, 513, 1309, 223, 1220, -329, 868, +-854, 291, -964, -345, -878, -836, -894, -1087, +-754, -1057, -275, -751, 253, -255, 613, 251, +877, 592, 992, 693, 828, 585, 438, 320, +15, -12, -322, -259, -536, -303, -594, -184, +-463, -19, -239, 133, -92, 254, -40, 249, +6, 49, 66, -198, 81, -340, 93, -368, +190, -308, 310, -152, 301, 111, 189, 361, +75, 420, -89, 285, -304, 98, -411, -69, +-339, -229, -241, -340, -115, -258, 154, -21, +463, 181, 588, 322, 541, 437, 381, 407, +35, 139, -459, -233, -890, -501, -1033, -643, +-806, -695, -341, -563, 158, -193, 670, 304, +1106, 706, 1232, 900, 1020, 909, 653, 735, +157, 345, -526, -186, -1210, -652, -1557, -877, +-1444, -867, -1030, -718, -424, -463, 334, -123, +1052, 234, 1456, 470, 1496, 557, 1270, 573, +803, 524, 112, 402, -622, 220, -1175, 7, +-1453, -145, -1355, -218, -887, -285, -251, -352, +350, -395, 801, -394, 994, -398, 905, -386, +593, -239, 177, 20, -186, 329, -416, 642, +-458, 852, -286, 887, 3, 705, 237, 290, +330, -203, 212, -609, -88, -845, -428, -899, +-663, -764, -712, -445, -548, -86, -157, 194, +377, 398, 880, 470, 1176, 383, 1137, 270, +709, 253, 72, 320, -548, 363, -1025, 388, +-1214, 379, -1021, 169, -566, -305, -83, -855, +308, -1206, 641, -1253, 879, -1018, 821, -491, +492, 294, 159, 1098, -85, 1590, -347, 1593, +-552, 1222, -529, 622, -272, -165, 2, -945, +74, -1395, 32, -1336, 61, -911, 143, -370, +119, 159, 55, 560, 95, 683, 123, 517, +-2, 169, -128, -168, -130, -312, -88, -190, +-30, 155, 38, 532, 70, 778, 91, 824, +133, 567, 135, -41, 65, -772, -60, -1294, +-183, -1452, -283, -1275, -322, -755, -223, 36, +6, 789, 227, 1295, 329, 1521, 343, 1393, +293, 889, 175, 262, -26, -252, -199, -659, +-251, -959, -255, -1000, -273, -837, -214, -718, +-31, -642, 104, -401, 100, -16, 118, 350, +253, 745, 320, 1162, 248, 1388, 149, 1280, +21, 876, -194, 229, -397, -542, -506, -1184, +-471, -1528, -245, -1583, 45, -1291, 244, -616, +422, 142, 666, 705, 740, 1046, 483, 1192, +57, 1099, -328, 789, -656, 397, -889, 51, +-850, -210, -505, -385, -34, -514, 357, -606, +612, -650, 734, -735, 691, -811, 457, -693, +148, -336, -80, 152, -215, 712, -334, 1290, +-402, 1662, -355, 1573, -273, 1042, -260, 270, +-281, -609, -216, -1437, -79, -1970, 76, -1988, +239, -1502, 461, -669, 722, 339, 865, 1294, +727, 1931, 358, 2034, -69, 1569, -564, 745, +-1051, -189, -1238, -1043, -1014, -1574, -622, -1621, +-221, -1215, 254, -556, 756, 172, 1060, 793, +1098, 1079, 951, 992, 631, 664, 144, 194, +-406, -277, -814, -575, -913, -609, -714, -388, +-436, -77, -170, 215, 36, 431, 107, 446, +57, 217, 4, -130, 56, -412, 161, -565, +253, -556, 366, -279, 553, 172, 717, 504, +724, 681, 484, 733, -3, 558, -582, 134, +-1113, -376, -1500, -756, -1522, -929, -1049, -893, +-275, -606, 507, -58, 1147, 616, 1597, 1149, +1682, 1304, 1346, 1076, 761, 536, 102, -218, +-612, -994, -1213, -1509, -1430, -1559, -1246, -1169, +-848, -451, -441, 448, -45, 1253, 285, 1665, +435, 1608, 444, 1152, 502, 400, 659, -488, +788, -1213, 809, -1566, 747, -1523, 558, -1091, +114, -405, -525, 320, -1120, 914, -1526, 1259, +-1666, 1268, -1440, 953, -839, 432, 71, -92, +1023, -516, 1686, -798, 1927, -882, 1780, -754, +1269, -440, 426, -51, -491, 294, -1174, 495, +-1513, 510, -1607, 389, -1395, 179, -832, -94, +-139, -280, 464, -274, 884, -131, 1112, 63, +1140, 232, 912, 321, 451, 292, -41, 156, +-369, -71, -531, -314, -600, -468, -526, -523, +-291, -485, -45, -277, 47, 65, 66, 384, +68, 582, -27, 680, -111, 669, -69, 432, +38, 21, 100, -372, 218, -621, 378, -732, +379, -683, 209, -386, 55, 75, -41, 424, +-197, 568, -333, 577, -324, 424, -224, 100, +-133, -292, -83, -534, -32, -535, 19, -371, +18, -86, -16, 281, -15, 591, 93, 713, +275, 613, 424, 315, 472, -146, 402, -613, +210, -854, -107, -884, -408, -745, -618, -376, +-708, 145, -630, 589, -358, 844, 25, 933, +332, 834, 528, 508, 646, 88, 583, -232, +251, -442, -113, -611, -219, -738, -172, -689, +-157, -489, -104, -295, 45, -104, 118, 148, +-33, 410, -231, 593, -302, 658, -315, 626, +-291, 531, -125, 385, 187, 209, 442, -66, +549, -394, 481, -643, 260, -777, -39, -814, +-311, -766, -439, -578, -388, -240, -172, 165, +116, 590, 365, 966, 451, 1156, 305, 1161, +-25, 952, -396, 495, -642, -111, -750, -705, +-699, -1172, -353, -1436, 222, -1376, 779, -987, +1144, -423, 1258, 226, 1094, 859, 624, 1223, +-40, 1258, -748, 1049, -1319, 649, -1589, 126, +-1462, -339, -1027, -564, -426, -584, 311, -523, +982, -413, 1365, -260, 1449, -169, 1375, -241, +1103, -392, 517, -382, -201, -174, -775, 132, +-1197, 506, -1486, 904, -1458, 1179, -1050, 1119, +-460, 705, 119, 122, 583, -459, 907, -973, +1065, -1325, 998, -1379, 806, -1072, 562, -547, +302, 53, 32, 616, -258, 998, -503, 1155, +-662, 1065, -742, 752, -785, 336, -773, -37, +-722, -311, -525, -506, -90, -658, 439, -713, +893, -652, 1209, -529, 1392, -376, 1326, -156, +854, 182, 168, 508, -436, 699, -947, 781, +-1377, 749, -1540, 517, -1331, 136, -880, -241, +-321, -499, 222, -623, 742, -586, 1159, -408, +1281, -212, 1114, -56, 806, 49, 505, 126, +150, 171, -237, 192, -528, 229, -716, 304, +-890, 356, -1008, 307, -932, 156, -682, -14, +-347, -188, 18, -400, 410, -523, 791, -471, +1009, -292, 1045, -63, 985, 193, 828, 423, +547, 525, 114, 449, -380, 238, -819, -60, +-1195, -318, -1492, -432, -1550, -446, -1237, -318, +-655, -16, 127, 322, 994, 477, 1773, 416, +2195, 276, 2068, 97, 1459, -153, 507, -350, +-589, -392, -1564, -325, -2124, -205, -2128, -68, +-1676, 88, -921, 185, 38, 215, 986, 220, +1536, 189, 1577, 118, 1322, 47, 850, 25, +238, 66, -301, 87, -625, 17, -747, -94, +-721, -188, -531, -264, -299, -385, -121, -455, +-42, -351, 0, -132, 54, 116, 100, 390, +189, 685, 325, 898, 452, 876, 444, 578, +255, 85, -36, -509, -289, -1012, -410, -1299, +-416, -1275, -288, -877, -26, -184, 251, 599, +439, 1187, 444, 1393, 224, 1238, -135, 787, +-471, 118, -698, -564, -771, -1020, -494, -1075, +91, -824, 639, -424, 893, 42, 945, 437, +843, 635, 459, 568, -109, 284, -629, -66, +-912, -337, -942, -432, -757, -313, -397, -70, +44, 234, 389, 511, 464, 642, 344, 530, +257, 187, 260, -213, 267, -545, 277, -764, +355, -799, 372, -626, 159, -312, -185, 78, +-494, 450, -710, 728, -914, 824, -963, 765, +-668, 610, -127, 317, 461, -103, 943, -518, +1266, -776, 1315, -854, 998, -797, 334, -568, +-371, -161, -882, 237, -1233, 534, -1311, 707, +-978, 709, -382, 537, 205, 265, 637, 6, +906, -226, 955, -392, 726, -404, 320, -278, +-67, -115, -324, 34, -479, 107, -513, 84, +-429, -36, -241, -198, -57, -314, 61, -339, +201, -178, 284, 136, 247, 427, 144, 623, +92, 754, 43, 714, -74, 390, -156, -96, +-141, -493, -139, -769, -215, -959, -194, -965, +-25, -717, 132, -263, 256, 211, 374, 582, +406, 858, 268, 1020, 27, 970, -176, 716, +-351, 335, -460, -93, -469, -519, -406, -879, +-251, -1132, 6, -1205, 298, -911, 512, -337, +643, 265, 608, 810, 448, 1227, 225, 1305, +-80, 954, -402, 352, -638, -250, -702, -733, +-644, -986, -513, -887, -231, -527, 175, -78, +468, 325, 591, 604, 731, 615, 808, 314, +580, -69, 154, -337, -227, -513, -520, -507, +-793, -229, -880, 148, -617, 458, -232, 646, +76, 646, 314, 383, 530, 19, 585, -279, +473, -509, 325, -613, 152, -508, -88, -275, +-315, -54, -341, 92, -235, 170, -150, 211, +-92, 184, -27, 174, 1, 236, -62, 311, +-120, 316, -43, 254, 126, 163, 275, -16, +307, -298, 235, -551, 120, -679, -35, -641, +-217, -447, -336, -217, -274, 96, -121, 509, +53, 822, 208, 854, 339, 660, 392, 412, +206, 126, -168, -263, -511, -647, -665, -838, +-645, -766, -393, -507, 142, -210, 756, 111, +1107, 402, 1043, 575, 689, 574, 154, 366, +-513, 93, -1076, -63, -1281, -140, -1093, -220, +-664, -200, -101, -31, 552, 128, 1050, 129, +1185, 60, 951, -56, 551, -240, 89, -392, +-379, -417, -659, -269, -671, -1, -518, 277, +-345, 493, -166, 602, -55, 544, -47, 332, +-49, 22, 25, -266, 197, -486, 389, -609, +553, -557, 678, -340, 640, -46, 347, 203, +-108, 353, -547, 396, -858, 296, -982, 111, +-839, 5, -452, -29, 57, 3, 466, 106, +720, 177, 823, 113, 693, -66, 361, -272, +-22, -483, -269, -605, -388, -513, -369, -222, +-177, 166, 51, 584, 105, 882, -27, 940, +-185, 710, -315, 233, -388, -323, -331, -821, +-125, -1129, 198, -1109, 519, -711, 701, -94, +685, 506, 506, 938, 222, 1127, -149, 964, +-457, 478, -606, -126, -624, -567, -514, -712, +-322, -702, -145, -562, -26, -228, 121, 136, +251, 278, 344, 225, 417, 171, 465, 156, +485, 115, 419, 112, 265, 192, 44, 285, +-268, 310, -608, 177, -844, -87, -899, -417, +-725, -705, -341, -799, 78, -631, 417, -257, +707, 235, 884, 700, 867, 994, 656, 1002, +353, 685, 26, 160, -355, -374, -672, -749, +-809, -962, -719, -941, -503, -578, -267, -40, +-44, 383, 180, 639, 361, 772, 410, 713, +412, 396, 406, -52, 323, -369, 181, -490, +74, -483, 15, -375, -73, -128, -168, 142, +-211, 248, -291, 211, -419, 138, -481, 34, +-407, -33, -243, -7, -37, 44, 215, 117, +459, 162, 625, 94, 652, -108, 596, -292, +413, -391, 63, -450, -321, -347, -590, 2, +-640, 383, -517, 630, -353, 769, -203, 751, +-29, 471, 117, -56, 173, -592, 180, -975, +169, -1162, 168, -1075, 194, -689, 230, -68, +302, 660, 401, 1280, 439, 1587, 281, 1491, +-99, 1012, -516, 240, -857, -692, -1045, -1467, +-972, -1834, -570, -1750, -21, -1229, 482, -384, +893, 543, 1127, 1303, 1131, 1734, 901, 1738, +476, 1319, -113, 607, -669, -202, -956, -958, +-987, -1431, -856, -1504, -579, -1246, -200, -715, +143, -23, 327, 616, 410, 993, 492, 1042, +529, 845, 457, 511, 342, 98, 292, -281, +213, -491, 17, -433, -244, -254, -411, -139, +-498, -42, -618, 43, -639, 26, -446, -93, +-163, -195, 49, -202, 273, -106, 547, 53, +721, 235, 677, 350, 490, 380, 311, 316, +137, 150, -89, -29, -328, -166, -496, -241, +-571, -248, -627, -203, -648, -134, -512, -74, +-216, -51, 142, -33, 486, -23, 787, -27, +913, -29, 808, 9, 584, 127, 264, 259, +-164, 351, -586, 379, -817, 331, -865, 186, +-725, -72, -417, -375, -67, -561, 235, -610, +443, -554, 529, -355, 486, -35, 362, 264, +230, 422, 110, 505, -17, 514, -110, 373, +-112, 181, -72, 84, -88, 33, -170, -40, +-285, -128, -349, -216, -350, -344, -283, -506, +-86, -604, 162, -599, 353, -442, 463, -102, +531, 364, 477, 809, 282, 1111, 49, 1189, +-145, 972, -330, 442, -484, -256, -463, -923, +-305, -1391, -174, -1479, -101, -1163, -23, -560, +62, 167, 134, 840, 209, 1241, 316, 1224, +405, 863, 395, 360, 262, -141, 94, -497, +-27, -590, -166, -443, -355, -196, -496, -29, +-516, 1, -476, -107, -311, -306, -9, -450, +299, -415, 519, -195, 614, 178, 577, 628, +400, 997, 158, 1095, -83, 835, -335, 311, +-553, -366, -576, -1013, -402, -1401, -209, -1360, +7, -878, 296, -152, 471, 577, 401, 1137, +197, 1347, 28, 1125, -85, 589, -225, -61, +-329, -609, -288, -931, -100, -971, 97, -747, +243, -310, 360, 177, 419, 478, 299, 566, +16, 558, -211, 420, -348, 140, -456, -98, +-480, -188, -372, -205, -222, -241, -51, -257, +226, -237, 545, -210, 719, -159, 694, -58, +502, 123, 175, 334, -177, 458, -444, 461, +-609, 373, -672, 187, -617, -59, -476, -336, +-251, -532, 35, -565, 345, -490, 610, -358, +725, -140, 667, 176, 489, 464, 266, 615, +17, 634, -246, 509, -471, 230, -570, -76, +-580, -317, -551, -451, -402, -470, -156, -405, +49, -277, 221, -134, 430, -32, 597, 36, +614, 137, 504, 277, 352, 378, 146, 382, +-100, 330, -320, 225, -467, 74, -566, -99, +-609, -254, -576, -323, -451, -334, -172, -338, +209, -329, 564, -280, 800, -173, 892, -2, +772, 208, 441, 453, 5, 684, -452, 787, +-823, 645, -978, 288, -876, -145, -534, -603, +12, -976, 576, -1075, 904, -841, 896, -383, +629, 152, 150, 640, -447, 996, -904, 1062, +-953, 764, -620, 264, -88, -220, 528, -580, +1047, -766, 1237, -664, 967, -330, 329, 14, +-465, 248, -1156, 334, -1560, 214, -1517, -21, +-949, -208, -43, -250, 868, -112, 1516, 164, +1740, 463, 1440, 629, 717, 587, -137, 306, +-879, -159, -1353, -645, -1381, -978, -982, -1048, +-415, -779, 114, -218, 525, 448, 721, 989, +664, 1235, 478, 1156, 256, 720, 44, 17, +-81, -664, -54, -1046, 7, -1106, 8, -901, +-48, -432, -189, 149, -377, 545, -479, 695, +-437, 680, -264, 484, 43, 187, 371, -52, +563, -154, 547, -188, 381, -192, 157, -133, +-77, -53, -262, -65, -304, -179, -236, -286, +-132, -291, -14, -213, 20, -81, -42, 166, +-82, 459, -78, 653, -116, 669, -111, 502, +57, 167, 307, -265, 457, -640, 461, -820, +352, -794, 79, -572, -316, -172, -651, 264, +-773, 597, -644, 754, -280, 716, 220, 475, +684, 127, 907, -193, 793, -442, 440, -565, +-1, -485, -450, -247, -803, 33, -900, 260, +-698, 335, -289, 246, 179, 64, 584, -132, +796, -300, 771, -338, 535, -167, 153, 93, +-216, 302, -436, 440, -507, 486, -484, 390, +-368, 143, -217, -206, -76, -504, 48, -652, +151, -639, 247, -477, 336, -179, 398, 199, +414, 516, 352, 677, 200, 648, -29, 443, +-318, 159, -567, -106, -678, -340, -635, -476, +-426, -444, -36, -284, 378, -119, 617, -7, +655, 82, 545, 134, 309, 113, 3, 61, +-230, 63, -344, 115, -361, 156, -294, 169, +-155, 176, -27, 120, 30, -1, 29, -130, +-4, -241, -44, -299, -38, -271, 65, -170, +215, -51, 319, 55, 310, 131, 202, 148, +14, 101, -234, 53, -438, 34, -433, 70, +-226, 156, 25, 226, 245, 250, 392, 194, +383, 36, 178, -204, -146, -473, -448, -685, +-588, -716, -509, -503, -184, -86, 304, 397, +725, 819, 909, 1046, 814, 959, 448, 591, +-123, 35, -714, -563, -1117, -979, -1193, -1075, +-924, -884, -360, -468, 353, 111, 953, 666, +1223, 954, 1134, 915, 760, 606, 184, 88, +-423, -445, -836, -773, -929, -804, -789, -564, +-502, -115, -109, 396, 277, 766, 498, 856, +513, 642, 396, 189, 221, -356, 25, -818, +-137, -1036, -174, -897, -89, -470, 19, 103, +52, 670, 22, 1040, -18, 1060, -87, 758, +-179, 275, -192, -270, -110, -726, -35, -907, +16, -783, 77, -479, 128, -77, 147, 308, +153, 543, 146, 557, 123, 378, 84, 87, +24, -200, -76, -360, -201, -327, -292, -149, +-304, 97, -229, 345, -77, 491, 114, 454, +280, 216, 388, -142, 369, -472, 197, -665, +-40, -682, -245, -537, -386, -240, -408, 162, +-256, 525, -5, 720, 227, 743, 379, 626, +426, 380, 335, 13, 125, -339, -111, -525, +-288, -558, -399, -541, -433, -449, -356, -233, +-206, -35, -33, 34, 168, 124, 374, 319, +499, 443, 519, 451, 430, 449, 260, 426, +61, 272, -163, 11, -430, -245, -667, -465, +-764, -626, -695, -688, -447, -621, -29, -393, +457, -30, 824, 334, 968, 604, 882, 736, +586, 706, 137, 501, -333, 175, -697, -126, +-860, -310, -780, -397, -525, -411, -163, -326, +227, -187, 477, -108, 443, -134, 239, -165, +57, -147, -45, -72, -62, 76, 63, 304, +309, 567, 497, 737, 485, 717, 242, 483, +-152, 88, -574, -385, -913, -828, -1065, -1116, +-909, -1108, -430, -770, 235, -217, 869, 384, +1283, 900, 1350, 1206, 1021, 1160, 387, 790, +-336, 271, -904, -275, -1154, -764, -1034, -1033, +-665, -974, -186, -641, 289, -200, 586, 225, +589, 556, 392, 694, 150, 603, -73, 343, +-209, 41, -169, -178, 56, -253, 312, -210, +436, -132, 371, -80, 124, -47, -244, -63, +-594, -132, -817, -163, -824, -103, -524, 20, +1, 171, 518, 344, 871, 474, 995, 453, +834, 248, 417, -67, -132, -391, -626, -671, +-887, -841, -829, -766, -526, -389, -114, 155, +324, 700, 661, 1110, 721, 1247, 473, 1015, +88, 449, -305, -293, -595, -981, -637, -1408, +-411, -1449, -63, -1086, 282, -421, 551, 332, +637, 958, 506, 1339, 242, 1369, -68, 1026, +-367, 450, -562, -177, -586, -703, -440, -996, +-174, -1021, 121, -809, 324, -418, 362, 14, +281, 304, 152, 423, 41, 469, -5, 413, +7, 258, 16, 135, 28, 96, 66, 94, +76, 112, 1, 123, -129, 63, -255, -101, +-349, -341, -364, -568, -286, -681, -134, -619, +93, -389, 358, -14, 524, 423, 530, 787, +444, 966, 320, 898, 144, 594, -94, 157, +-345, -318, -524, -747, -615, -964, -646, -889, +-544, -612, -268, -233, 89, 195, 411, 518, +673, 605, 846, 534, 827, 391, 567, 191, +183, -10, -202, -122, -567, -132, -815, -91, +-812, -64, -594, -69, -325, -118, -98, -203, +129, -305, 389, -385, 596, -356, 652, -150, +565, 185, 388, 500, 177, 710, -49, 802, +-288, 700, -470, 310, -533, -254, -550, -767, +-540, -1084, -412, -1127, -132, -857, 235, -302, +588, 403, 822, 1041, 860, 1382, 680, 1304, +282, 843, -215, 130, -632, -655, -883, -1271, +-959, -1505, -794, -1272, -362, -684, 186, 67, +655, 812, 936, 1328, 954, 1409, 695, 1074, +269, 520, -199, -114, -569, -716, -712, -1102, +-644, -1149, -493, -906, -289, -482, -40, 9, +174, 442, 313, 716, 387, 767, 409, 629, +391, 416, 370, 202, 303, 2, 144, -135, +-84, -215, -326, -307, -555, -426, -725, -500, +-747, -498, -552, -417, -161, -213, 278, 74, +636, 365, 896, 607, 988, 726, 787, 666, +360, 470, -114, 194, -542, -130, -867, -443, +-962, -652, -763, -690, -376, -578, 5, -382, +263, -143, 435, 130, 534, 366, 516, 451, +388, 400, 252, 334, 166, 294, 76, 239, +-56, 151, -178, 56, -274, -43, -398, -192, +-505, -395, -500, -563, -385, -606, -188, -510, +99, -298, 419, -2, 658, 316, 747, 586, +688, 751, 452, 777, 38, 664, -392, 403, +-670, -15, -772, -461, -693, -791, -408, -962, +-29, -947, 287, -685, 482, -208, 530, 333, +430, 772, 251, 1007, 63, 986, -118, 698, +-240, 197, -248, -355, -178, -736, -116, -862, +-60, -746, 29, -395, 102, 76, 93, 457, +42, 637, 22, 585, 50, 304, 63, -83, +4, -397, -82, -547, -127, -510, -134, -260, +-138, 108, -85, 429, 56, 606, 212, 591, +291, 368, 315, 34, 310, -283, 175, -515, +-118, -598, -431, -495, -596, -261, -579, -10, +-426, 212, -158, 385, 217, 448, 585, 356, +763, 183, 664, 45, 367, -47, 23, -125, +-275, -169, -519, -145, -638, -96, -501, -81, +-160, -103, 145, -96, 262, -49, 268, -13, +228, 7, 92, 53, -110, 90, -218, 53, +-157, 3, 14, 30, 221, 110, 364, 202, +410, 291, 349, 298, 104, 180, -296, -58, +-636, -373, -770, -657, -702, -774, -436, -664, +17, -350, 535, 128, 903, 634, 971, 984, +750, 1088, 358, 921, -129, 465, -617, -158, +-927, -739, -894, -1120, -571, -1195, -156, -919, +250, -385, 580, 213, 706, 706, 558, 953, +218, 884, -147, 566, -365, 149, -414, -227, +-339, -449, -99, -471, 244, -317, 457, -67, +439, 138, 270, 172, -36, 29, -440, -162, +-730, -306, -734, -359, -484, -248, -77, 46, +408, 379, 829, 597, 1021, 630, 920, 468, +533, 163, -57, -166, -662, -413, -1098, -551, +-1247, -558, -1035, -441, -482, -261, 219, -48, +810, 182, 1148, 367, 1205, 492, 942, 566, +370, 525, -301, 330, -812, 25, -1045, -340, +-966, -685, -611, -834, -142, -684, 290, -314, +579, 163, 634, 627, 476, 874, 243, 793, +39, 442, -100, -50, -148, -502, -120, -734, +-65, -682, -22, -426, -4, -59, -71, 295, +-204, 487, -287, 471, -279, 309, -196, 80, +-10, -115, 231, -196, 412, -172, 497, -85, +452, 17, 292, 81, 101, 56, -105, -50, +-353, -179, -554, -265, -615, -272, -557, -188, +-399, -25, -70, 200, 395, 430, 739, 574, +801, 594, 673, 469, 429, 188, 40, -215, +-386, -626, -693, -922, -798, -1038, -696, -914, +-423, -477, -27, 192, 388, 856, 675, 1319, +729, 1464, 572, 1218, 289, 595, -35, -219, +-344, -972, -538, -1448, -544, -1525, -442, -1216, +-299, -618, -70, 124, 232, 791, 494, 1179, +620, 1252, 561, 1061, 351, 642, 58, 97, +-277, -367, -583, -651, -722, -802, -630, -857, +-371, -776, -53, -529, 296, -174, 634, 190, +806, 535, 717, 863, 433, 1039, 73, 894, +-301, 454, -622, -108, -778, -660, -698, -1058, +-458, -1128, -176, -824, 130, -261, 447, 371, +680, 858, 719, 1023, 570, 846, 332, 415, +47, -119, -301, -534, -598, -677, -719, -606, +-682, -425, -486, -164, -90, 105, 361, 280, +641, 356, 678, 384, 511, 352, 195, 245, +-147, 76, -351, -124, -370, -291, -271, -352, +-110, -309, 55, -182, 126, -2, 92, 162, +29, 229, -34, 135, -78, -70, -106, -227, +-116, -213, -38, -52, 135, 207, 273, 513, +301, 708, 239, 592, 84, 146, -149, -459, +-352, -979, -415, -1180, -332, -962, -152, -382, +76, 393, 252, 1067, 280, 1337, 237, 1129, +218, 562, 171, -159, 49, -778, -104, -1061, +-226, -954, -264, -568, -223, -58, -166, 384, +-68, 614, 116, 622, 265, 465, 225, 202, +60, -89, -72, -342, -125, -498, -94, -500, +57, -317, 225, 20, 256, 384, 159, 617, +-30, 637, -296, 440, -487, 45, -456, -435, +-274, -775, -27, -817, 265, -586, 492, -166, +544, 320, 489, 702, 409, 870, 171, 770, +-268, 405, -657, -115, -804, -588, -764, -851, +-534, -833, -67, -539, 490, -44, 853, 490, +872, 849, 629, 864, 292, 549, -41, 69, +-319, -422, -495, -750, -578, -781, -571, -546, +-478, -176, -296, 194, -6, 418, 351, 456, +624, 429, 689, 407, 569, 351, 340, 250, +53, 98, -241, -184, -403, -549, -405, -797, +-410, -825, -471, -649, -446, -282, -290, 204, +-45, 639, 282, 880, 637, 914, 876, 795, +885, 553, 647, 196, 167, -246, -447, -672, +-923, -998, -1065, -1143, -950, -1025, -679, -632, +-232, -46, 303, 589, 758, 1076, 1065, 1256, +1155, 1126, 915, 753, 392, 198, -268, -395, +-886, -801, -1205, -957, -1065, -914, -636, -673, +-171, -289, 268, 61, 597, 285, 653, 443, +520, 545, 440, 521, 400, 391, 245, 265, +-19, 156, -294, 8, -517, -175, -625, -330, +-578, -411, -378, -418, -81, -362, 192, -248, +342, -86, 384, 96, 413, 253, 457, 347, +423, 380, 207, 366, -118, 291, -390, 128, +-562, -74, -623, -252, -499, -400, -211, -458, +89, -344, 329, -116, 526, 86, 599, 242, +461, 352, 201, 356, -67, 249, -321, 105, +-501, -51, -524, -219, -367, -362, -85, -428, +194, -356, 359, -124, 390, 206, 289, 512, +81, 673, -133, 588, -220, 259, -162, -187, +-71, -581, -30, -796, 7, -754, 77, -456, +116, 0, 89, 470, 49, 773, 15, 801, +-77, 581, -219, 194, -279, -254, -192, -603, +-33, -739, 164, -611, 364, -246, 433, 184, +331, 482, 155, 593, -52, 513, -282, 215, +-471, -174, -555, -445, -477, -538, -221, -449, +130, -176, 438, 126, 632, 313, 658, 425, +428, 456, 10, 319, -333, 83, -455, -123, +-428, -282, -291, -357, -102, -318, 15, -240, +51, -145, 82, 3, 89, 117, 69, 130, +78, 113, 106, 128, 132, 192, 171, 297, +208, 343, 156, 233, -18, 16, -246, -235, +-416, -465, -448, -570, -314, -491, -60, -281, +221, 8, 404, 272, 393, 385, 253, 399, +102, 405, -39, 324, -179, 125, -265, -39, +-263, -132, -162, -262, 25, -380, 216, -328, +324, -147, 303, -2, 131, 64, -144, 79, +-392, 42, -477, -37, -341, -62, -84, 39, +157, 230, 343, 412, 457, 489, 434, 374, +278, 54, 79, -372, -102, -736, -260, -854, +-401, -651, -482, -204, -430, 326, -192, 756, +131, 895, 343, 673, 419, 223, 455, -237, +353, -545, 63, -625, -190, -488, -307, -204, +-350, 127, -256, 345, -23, 370, 162, 285, +239, 167, 268, -18, 177, -217, -76, -302, +-319, -283, -402, -198, -346, -13, -149, 219, +186, 356, 485, 349, 592, 205, 492, -45, +182, -281, -206, -398, -467, -393, -552, -229, +-461, 103, -190, 407, 91, 492, 232, 397, +290, 205, 282, -74, 178, -364, 58, -543, +-25, -534, -124, -351, -178, -89, -106, 184, +-26, 454, -7, 634, 63, 616, 132, 425, +54, 129, -48, -241, -65, -583, -91, -723, +-119, -616, -67, -349, -19, -12, 3, 296, +62, 477, 112, 488, 113, 345, 110, 133, +79, -13, -32, -53, -133, -65, -138, -83, +-91, -75, -35, -45, 86, -43, 209, -108, +154, -199, -84, -243, -322, -233, -418, -201, +-338, -108, -71, 117, 328, 411, 652, 629, +681, 677, 405, 535, -33, 209, -438, -231, +-606, -658, -506, -895, -300, -824, -79, -495, +108, -58, 163, 345, 169, 600, 272, 628, +366, 449, 284, 173, 90, -52, -95, -138, +-228, -110, -269, -48, -186, 10, -39, 24, +59, -60, 60, -193, -9, -295, -58, -359, +-43, -350, -21, -178, -21, 104, 29, 360, +110, 539, 176, 607, 270, 500, 313, 242, +142, -85, -165, -395, -423, -563, -562, -551, +-485, -437, -160, -239, 250, 57, 531, 323, +571, 455, 385, 444, 114, 269, -91, -12, +-234, -231, -362, -340, -406, -338, -318, -99, +-184, 302, 2, 527, 285, 462, 512, 222, +532, -171, 380, -617, 77, -836, -293, -684, +-516, -254, -510, 288, -353, 740, -98, 901, +192, 711, 380, 250, 393, -260, 247, -556, +9, -591, -218, -484, -291, -249, -175, 66, +0, 262, 134, 288, 206, 267, 193, 238, +103, 168, -13, 34, -136, -184, -215, -385, +-223, -395, -224, -233, -242, -30, -210, 200, +-55, 390, 206, 392, 437, 247, 550, 101, +573, -24, 474, -115, 175, -127, -280, -149, +-712, -266, -983, -397, -984, -424, -657, -297, +-126, -9, 400, 351, 831, 624, 1087, 723, +989, 623, 595, 344, 175, -29, -229, -356, +-659, -541, -949, -591, -973, -583, -771, -538, +-366, -391, 161, -105, 617, 270, 866, 642, +834, 897, 536, 925, 145, 683, -186, 196, +-431, -393, -545, -821, -420, -906, -117, -680, +152, -308, 268, 23, 224, 198, 54, 244, +-170, 237, -379, 219, -453, 227, -215, 276, +236, 322, 572, 306, 670, 179, 578, -60, +313, -315, -53, -480, -403, -559, -685, -585, +-796, -490, -607, -202, -191, 244, 288, 681, +721, 916, 911, 886, 675, 623, 139, 112, +-363, -541, -644, -1000, -651, -1039, -368, -730, +74, -236, 413, 306, 484, 714, 357, 839, +179, 657, 12, 277, -158, -102, -292, -350, +-356, -475, -357, -475, -232, -322, 22, -113, +269, 41, 441, 182, 506, 331, 362, 362, +64, 212, -186, -20, -337, -206, -383, -258, +-261, -141, -67, 99, 63, 333, 160, 381, +198, 137, 59, -302, -163, -694, -228, -822, +-107, -583, 104, -18, 331, 679, 430, 1205, +279, 1273, -14, 795, -263, -13, -399, -794, +-399, -1283, -300, -1334, -155, -900, 37, -155, +222, 576, 320, 1025, 351, 1057, 298, 714, +77, 224, -229, -205, -398, -487, -328, -573, +-102, -453, 159, -223, 346, -11, 309, 152, +14, 260, -326, 249, -504, 121, -456, -40, +-208, -195, 136, -296, 430, -243, 612, 8, +635, 322, 407, 506, 1, 499, -414, 300, +-738, -82, -863, -512, -669, -771, -217, -739, +271, -417, 621, 98, 765, 616, 677, 905, +427, 818, 130, 397, -186, -167, -472, -647, +-642, -876, -639, -767, -429, -337, -53, 245, +271, 700, 398, 840, 349, 673, 202, 303, +92, -178, 114, -637, 209, -880, 242, -801, +107, -444, -209, 85, -514, 616, -560, 926, +-314, 885, 32, 533, 285, 13, 358, -507, +258, -843, 80, -854, -16, -512, 37, 24, +111, 463, 73, 645, -65, 585, -189, 292, +-191, -144, -56, -466, 126, -518, 245, -320, +238, 67, 124, 462, -71, 604, -297, 436, +-394, 70, -307, -376, -145, -699, 73, -709, +351, -441, 547, -21, 560, 431, 414, 716, +121, 723, -245, 528, -497, 186, -528, -240, +-421, -580, -273, -726, -90, -681, 100, -406, +242, 66, 321, 539, 329, 842, 252, 830, +114, 426, -18, -171, -70, -677, 7, -950, +132, -855, 121, -317, -99, 439, -430, 1019, +-676, 1162, -646, 792, -316, 37, 123, -755, +472, -1263, 659, -1301, 686, -772, 573, 143, +334, 995, 4, 1457, -356, 1382, -675, 737, +-865, -237, -808, -1092, -454, -1500, 70, -1357, +501, -701, 683, 251, 608, 1090, 359, 1454, +102, 1236, -54, 577, -156, -239, -282, -927, +-357, -1271, -297, -1134, -127, -554, 66, 213, +152, 835, 37, 1108, -209, 997, -372, 531, +-277, -179, 49, -840, 442, -1132, 761, -970, +826, -440, 473, 313, -153, 1012, -693, 1319, +-946, 1067, -917, 353, -673, -544, -242, -1298, +287, -1617, 740, -1310, 1004, -435, 985, 685, +647, 1599, 83, 1963, -510, 1622, -915, 634, +-952, -630, -644, -1672, -177, -2149, 311, -1860, +655, -867, 688, 416, 445, 1524, 104, 2098, +-237, 1876, -495, 937, -517, -261, -223, -1271, +231, -1816, 587, -1665, 702, -849, 516, 226, +63, 1157, -442, 1656, -773, 1466, -821, 660, +-576, -345, -147, -1210, 358, -1688, 794, -1506, +996, -674, 909, 425, 523, 1402, -106, 1943, +-723, 1754, -1083, 843, -1072, -397, -609, -1498, +112, -2083, 690, -1904, 950, -1000, 901, 270, +540, 1409, 31, 1991, -351, 1798, -574, 954, +-722, -175, -665, -1187, -338, -1720, 89, -1574, +513, -833, 826, 220, 799, 1164, 425, 1587, +-71, 1331, -542, 588, -768, -329, -567, -1146, +-176, -1550, 117, -1304, 282, -542, 301, 384, +158, 1175, -9, 1549, -103, 1293, -106, 519, +-9, -387, 111, -1117, 152, -1436, 132, -1127, +86, -335, -31, 500, -192, 1072, -302, 1194, +-377, 742, -386, -52, -211, -749, 65, -1116, +323, -1045, 521, -441, 541, 417, 295, 1051, +-88, 1317, -424, 1173, -600, 513, -517, -439, +-197, -1252, 160, -1640, 369, -1446, 397, -707, +230, 269, -67, 1129, -312, 1633, -394, 1565, +-326, 901, -159, -8, 55, -813, 268, -1329, +420, -1358, 453, -890, 364, -175, 142, 562, +-202, 1101, -535, 1176, -698, 710, -681, -57, +-497, -767, -90, -1155, 488, -1049, 959, -440, +1069, 424, 805, 1169, 259, 1484, -411, 1169, +-963, 280, -1166, -763, -913, -1512, -284, -1745, +403, -1328, 826, -303, 931, 864, 746, 1612, +330, 1750, -132, 1313, -452, 359, -580, -754, +-573, -1478, -401, -1571, 3, -1116, 439, -313, +628, 535, 562, 1168, 313, 1392, -97, 1090, +-506, 390, -666, -426, -458, -1100, -10, -1398, +407, -1165, 653, -475, 669, 376, 461, 1123, +127, 1528, -260, 1310, -629, 504, -811, -469, +-660, -1230, -247, -1521, 233, -1197, 671, -400, +966, 524, 872, 1261, 372, 1547, -215, 1123, +-671, 95, -888, -921, -707, -1459, -217, -1487, +310, -968, 706, 97, 765, 1256, 417, 1895, +-95, 1762, -574, 929, -862, -333, -664, -1481, +-60, -2021, 487, -1870, 771, -1134, 795, 58, +482, 1311, -35, 2029, -426, 1934, -676, 1197, +-804, 134, -591, -890, -177, -1539, 112, -1641, +403, -1182, 690, -318, 639, 614, 308, 1234, +-94, 1305, -538, 855, -760, 88, -496, -685, +21, -1141, 456, -1120, 684, -597, 577, 279, +91, 1091, -495, 1454, -917, 1215, -1071, 409, +-797, -654, -106, -1470, 675, -1722, 1228, -1368, +1375, -432, 1015, 811, 279, 1691, -575, 1817, +-1314, 1290, -1654, 256, -1350, -936, -527, -1665, +430, -1617, 1197, -911, 1534, 165, 1291, 1155, +535, 1578, -415, 1290, -1170, 451, -1423, -643, +-1056, -1435, -242, -1534, 607, -1074, 1144, -228, +1195, 807, 747, 1529, 27, 1607, -641, 1106, +-1006, 216, -985, -730, -602, -1358, -3, -1511, +527, -1141, 816, -268, 875, 695, 639, 1221, +103, 1220, -484, 740, -810, -125, -702, -908, +-205, -1194, 437, -918, 895, -107, 872, 908, +369, 1529, -326, 1484, -927, 791, -1163, -434, +-887, -1669, -241, -2261, 538, -2004, 1186, -958, +1435, 617, 1217, 2037, 690, 2688, -50, 2417, +-927, 1288, -1624, -362, -1695, -1893, -1059, -2762, +-32, -2664, 1003, -1539, 1658, 166, 1640, 1727, +1002, 2664, 16, 2604, -970, 1446, -1492, -251, +-1321, -1814, -673, -2733, 196, -2480, 1036, -1125, +1495, 615, 1402, 2115, 790, 2861, -208, 2444, +-1225, 1034, -1803, -711, -1715, -2232, -1043, -3040, +23, -2687, 1132, -1350, 1800, 351, 1834, 1967, +1316, 2993, 371, 2945, -619, 1881, -1308, 206, +-1669, -1525, -1497, -2657, -723, -2797, 88, -1947, +590, -441, 952, 1070, 1063, 1973, 709, 2046, +181, 1375, -182, 232, -394, -822, -465, -1257, +-402, -1011, -345, -340, -238, 388, -9, 768, +144, 624, 159, 95, 160, -570, 44, -1021, +-144, -925, -95, -330, 100, 444, 132, 1150, +63, 1495, -36, 1221, -278, 467, -504, -474, +-476, -1385, -187, -1969, 286, -1866, 757, -984, +935, 336, 687, 1606, 127, 2428, -518, 2448, +-1034, 1549, -1241, -2, -1040, -1637, -481, -2682, +291, -2727, 988, -1783, 1307, -255, 1189, 1233, +762, 2220, 177, 2436, -433, 1767, -932, 514, +-1143, -728, -987, -1517, -548, -1722, 54, -1349, +621, -457, 924, 574, 881, 1196, 519, 1171, +-49, 601, -527, -255, -604, -1065, -309, -1432, +72, -1059, 379, -81, 532, 1086, 407, 1978, +97, 2162, -171, 1490, -365, 140, -548, -1458, +-618, -2653, -435, -2908, -14, -2119, 535, -608, +1025, 1144, 1160, 2594, 804, 3154, 124, 2578, +-636, 1155, -1197, -586, -1229, -2043, -670, -2756, +109, -2557, 743, -1500, 1118, 75, 1141, 1561, +767, 2397, 107, 2327, -671, 1416, -1285, -42, +-1418, -1496, -986, -2308, -120, -2144, 858, -1117, +1527, 319, 1604, 1577, 1096, 2212, 250, 2046, +-590, 1144, -1124, -214, -1269, -1478, -1124, -2135, +-703, -2066, -84, -1387, 424, -274, 784, 968, +1045, 1939, 895, 2251, 309, 1753, -240, 623, +-509, -716, -507, -1778, -212, -2219, 131, -1805, +205, -610, 101, 754, -87, 1719, -460, 2043, +-746, 1592, -614, 482, -293, -825, 4, -1739, +396, -1923, 762, -1453, 894, -510, 862, 607, +586, 1465, -38, 1799, -654, 1542, -966, 831, +-1063, -39, -889, -863, -447, -1448, -2, -1567, +366, -1181, 630, -503, 615, 219, 378, 849, +125, 1167, -90, 999, -189, 567, -81, 124, +146, -273, 327, -421, 371, -222, 135, 21, +-415, 112, -942, 80, -1120, -184, -938, -632, +-460, -893, 193, -847, 828, -527, 1310, 159, +1479, 1009, 1238, 1582, 635, 1714, -212, 1357, +-1072, 396, -1649, -889, -1763, -1829, -1309, -2145, +-308, -1878, 797, -954, 1482, 398, 1659, 1596, +1359, 2162, 568, 1899, -339, 1014, -954, -84, +-1244, -1097, -1160, -1737, -652, -1716, 56, -988, +744, 53, 1280, 895, 1356, 1412, 822, 1497, +45, 941, -641, -38, -1194, -911, -1336, -1377, +-851, -1385, -95, -900, 555, -38, 1003, 776, +1113, 1231, 813, 1284, 334, 884, -85, 175, +-391, -489, -563, -880, -537, -915, -347, -637, +-58, -197, 205, 228, 281, 478, 201, 440, +61, 124, -164, -226, -360, -366, -284, -302, +36, -39, 377, 409, 679, 821, 853, 916, +613, 601, 23, 21, -527, -664, -896, -1255, +-1036, -1416, -811, -1064, -332, -427, 154, 367, +572, 1154, 810, 1572, 724, 1412, 439, 838, +174, 94, -94, -634, -344, -1093, -386, -1182, +-282, -951, -224, -418, -214, 173, -233, 482, +-288, 522, -227, 411, 42, 165, 314, -61, +407, -65, 413, 103, 330, 340, 68, 598, +-229, 599, -407, 163, -462, -466, -374, -1008, +-134, -1270, 121, -1130, 257, -628, 289, 180, +254, 1045, 82, 1506, -214, 1415, -504, 991, +-609, 365, -371, -425, 65, -1078, 407, -1326, +576, -1250, 594, -820, 425, -82, 132, 543, +-188, 908, -509, 1032, -763, 781, -794, 311, +-558, -140, -154, -530, 327, -658, 789, -399, +1041, -93, 877, 19, 320, 156, -333, 293, +-776, 169, -860, -9, -602, -41, -214, -68, +126, -38, 396, 59, 527, 40, 475, -36, +320, -136, 126, -332, -120, -334, -338, -3, +-415, 284, -370, 457, -192, 730, 171, 797, +465, 371, 481, -261, 374, -818, 177, -1181, +-95, -1243, -203, -982, -166, -361, -195, 585, +-180, 1441, -62, 1765, -48, 1598, -92, 1052, +33, 31, 245, -1110, 401, -1793, 502, -1916, +432, -1537, 144, -712, -164, 335, -339, 1260, +-379, 1713, -335, 1660, -263, 1238, -145, 448, +42, -508, 187, -1248, 237, -1590, 308, -1469, +359, -884, 256, -52, 125, 702, 23, 1264, +-143, 1535, -220, 1255, -163, 527, -180, -271, +-239, -988, -236, -1414, -198, -1389, -86, -1060, +70, -437, 163, 444, 262, 1183, 430, 1527, +467, 1581, 284, 1267, 82, 450, -107, -572, +-404, -1467, -687, -2070, -765, -2062, -576, -1349, +-177, -221, 198, 1061, 458, 2106, 683, 2436, +712, 1992, 403, 1029, 39, -265, -222, -1569, +-513, -2353, -682, -2400, -514, -1786, -229, -590, +-27, 842, 147, 2012, 246, 2604, 240, 2373, +167, 1324, 36, -161, -53, -1592, -18, -2542, +30, -2691, 27, -1963, 18, -600, -57, 978, +-237, 2270, -382, 2779, -406, 2404, -282, 1374, +60, -96, 465, -1588, 690, -2524, 721, -2592, +507, -1887, -24, -754, -637, 508, -1062, 1638, +-1165, 2286, -841, 2195, -191, 1435, 523, 374, +1159, -687, 1576, -1550, 1497, -1896, 900, -1618, +42, -873, -951, 119, -1814, 933, -2084, 1277, +-1699, 1192, -870, 723, 301, -9, 1508, -647, +2282, -883, 2379, -705, 1854, -265, 848, 339, +-425, 861, -1582, 969, -2259, 609, -2402, -88, +-2052, -845, -1082, -1306, 390, -1335, 1759, -880, +2549, 22, 2693, 1027, 2138, 1720, 972, 1841, +-390, 1315, -1595, 324, -2406, -770, -2519, -1683, +-1905, -2183, -889, -1933, 296, -927, 1466, 314, +2261, 1357, 2448, 2079, 2001, 2241, 909, 1652, +-477, 577, -1592, -604, -2204, -1690, -2177, -2314, +-1445, -2197, -330, -1497, 804, -378, 1677, 955, +1913, 1970, 1437, 2301, 579, 1985, -318, 1115, +-1031, -120, -1333, -1164, -1124, -1605, -521, -1603, +279, -1244, 920, -526, 1019, 138, 676, 508, +157, 679, -598, 636, -1335, 438, -1425, 257, +-805, 159, 111, 194, 1133, 347, 1998, 461, +2132, 374, 1328, 108, -21, -291, -1425, -878, +-2501, -1424, -2839, -1585, -2221, -1279, -868, -507, +763, 549, 2218, 1522, 2984, 2211, 2796, 2398, +1850, 1814, 395, 601, -1293, -753, -2590, -1869, +-2937, -2488, -2362, -2369, -1238, -1599, 100, -500, +1324, 698, 2023, 1660, 2023, 2009, 1463, 1726, +536, 1031, -419, 157, -1023, -640, -1188, -1112, +-956, -1137, -395, -731, 229, -58, 564, 471, +449, 600, 48, 420, -374, -30, -627, -592, +-594, -863, -296, -734, 166, -355, 661, 222, +1004, 845, 1093, 1157, 918, 1040, 398, 703, +-388, 242, -1063, -267, -1358, -629, -1316, -824, +-896, -865, -92, -731, 667, -541, 1028, -321, +1088, -30, 944, 223, 581, 433, 142, 744, +-263, 1046, -626, 1026, -777, 730, -586, 347, +-255, -225, 76, -886, 423, -1291, 554, -1357, +343, -1055, 91, -384, -47, 404, -208, 999, +-341, 1229, -334, 1071, -263, 549, -146, -185, +185, -821, 650, -1102, 936, -863, 929, -146, +580, 692, -83, 1300, -739, 1433, -1122, 965, +-1212, 3, -976, -1176, -455, -2091, 166, -2273, +721, -1649, 1136, -453, 1308, 949, 1127, 2130, +645, 2727, -45, 2545, -815, 1606, -1305, 141, +-1252, -1397, -823, -2445, -251, -2719, 339, -2272, +752, -1253, 824, 105, 621, 1383, 281, 2133, +-112, 2159, -451, 1577, -619, 687, -528, -239, +-209, -1020, 184, -1418, 501, -1304, 634, -848, +520, -251, 214, 337, -169, 728, -498, 762, +-677, 497, -711, 197, -621, -54, -444, -274, +-171, -350, 240, -316, 656, -267, 886, -181, +951, -71, 870, 106, 590, 391, 92, 667, +-550, 807, -1114, 685, -1500, 248, -1671, -415, +-1351, -1080, -447, -1454, 630, -1436, 1492, -1016, +2026, -180, 2078, 839, 1447, 1695, 333, 2128, +-807, 1960, -1733, 1210, -2200, 97, -1958, -1118, +-1167, -2122, -138, -2587, 965, -2330, 1772, -1433, +1873, -115, 1348, 1335, 534, 2445, -357, 2840, +-1027, 2472, -1216, 1466, -948, 67, -400, -1349, +160, -2368, 520, -2724, 602, -2396, 377, -1549, +-80, -390, -458, 893, -476, 1975, -153, 2539, +311, 2562, 738, 2046, 930, 952, 764, -445, +310, -1672, -347, -2448, -1006, -2742, -1318, -2482, +-1215, -1572, -826, -240, -115, 1105, 784, 2225, +1529, 2995, 1878, 3192, 1645, 2524, 831, 1062, +-221, -695, -1127, -2360, -1719, -3613, -1845, -3949, +-1374, -3088, -553, -1312, 219, 802, 846, 2727, +1306, 3943, 1489, 3991, 1343, 2849, 896, 970, +310, -1025, -262, -2626, -788, -3483, -1180, -3333, +-1294, -2216, -1189, -584, -968, 997, -503, 2091, +224, 2541, 956, 2334, 1554, 1520, 1858, 394, +1573, -653, 782, -1344, -141, -1557, -1060, -1395, +-1853, -966, -2109, -365, -1679, 151, -810, 460, +299, 678, 1395, 830, 2038, 809, 2033, 642, +1414, 473, 272, 238, -1006, -159, -1932, -575, +-2202, -941, -1698, -1207, -595, -1130, 669, -687, +1690, -89, 2167, 649, 1930, 1433, 1011, 1831, +-334, 1615, -1643, 963, -2446, 38, -2384, -1008, +-1475, -1837, -133, -2118, 1225, -1736, 2242, -906, +2538, 32, 1954, 958, 684, 1737, -701, 1982, +-1659, 1554, -2126, 876, -2118, 262, -1447, -413, +-203, -1048, 1005, -1337, 1662, -1302, 1757, -1105, +1420, -843, 644, -525, -395, -83, -1162, 445, +-1311, 974, -1003, 1434, -437, 1699, 292, 1675, +823, 1273, 831, 449, 460, -709, 43, -1903, +-354, -2639, -691, -2667, -699, -2081, -333, -906, +128, 704, 547, 2215, 814, 3065, 734, 3042, +416, 2317, 73, 1046, -306, -632, -652, -2160, +-743, -2937, -527, -2901, -195, -2253, 108, -1076, +369, 466, 463, 1899, 348, 2664, 246, 2514, +180, 1734, 51, 762, 2, -320, 89, -1413, +109, -1989, -28, -1794, -207, -1257, -355, -726, +-414, -88, -301, 590, -135, 1019, 10, 1227, +303, 1315, 623, 1199, 641, 890, 449, 359, +283, -427, 25, -1218, -377, -1792, -671, -2090, +-747, -1900, -614, -1068, -251, 181, 190, 1505, +551, 2611, 807, 3077, 808, 2653, 520, 1546, +144, -62, -231, -1925, -635, -3351, -904, -3768, +-871, -3202, -620, -1856, -255, 106, 234, 2207, +779, 3666, 1180, 3988, 1261, 3200, 909, 1648, +243, -240, -512, -2044, -1192, -3201, -1590, -3279, +-1529, -2456, -1050, -1223, -282, 100, 603, 1260, +1359, 1930, 1809, 1910, 1796, 1423, 1247, 880, +293, 402, -799, -55, -1763, -374, -2293, -437, +-2075, -433, -1136, -629, 125, -939, 1295, -1097, +2006, -1002, 2042, -690, 1505, -208, 515, 467, +-680, 1228, -1590, 1736, -1872, 1793, -1576, 1422, +-867, 668, 115, -308, 1065, -1214, 1662, -1793, +1717, -1905, 1111, -1523, 29, -758, -968, 94, +-1493, 811, -1587, 1310, -1315, 1413, -590, 1087, +377, 674, 1137, 372, 1539, 39, 1602, -318, +1273, -550, 604, -707, -221, -847, -1013, -935, +-1590, -964, -1826, -783, -1653, -244, -1040, 474, +-82, 1099, 953, 1568, 1761, 1820, 2189, 1586, +2158, 799, 1524, -233, 342, -1316, -938, -2235, +-1870, -2574, -2274, -2161, -2143, -1125, -1493, 310, +-446, 1738, 679, 2731, 1616, 2973, 2134, 2315, +2027, 941, 1414, -662, 569, -1969, -362, -2655, +-1207, -2631, -1678, -1934, -1585, -739, -1080, 590, +-380, 1626, 345, 2103, 859, 2018, 999, 1459, +814, 549, 479, -466, 148, -1238, -60, -1448, +-73, -1094, 33, -512, 109, 29, 67, 440, +-197, 570, -600, 253, -856, -327, -813, -698, +-519, -651, -78, -294, 465, 298, 1052, 1024, +1457, 1616, 1392, 1778, 876, 1335, 106, 334, +-807, -890, -1654, -1978, -2043, -2740, -1757, -2893, +-913, -2122, 208, -614, 1259, 1081, 1915, 2565, +1989, 3510, 1489, 3547, 630, 2606, -255, 1018, +-1046, -817, -1634, -2506, -1734, -3550, -1317, -3659, +-635, -2887, 98, -1476, 715, 201, 991, 1806, +849, 3053, 525, 3495, 268, 2934, 182, 1742, +315, 331, 475, -1124, 422, -2273, 85, -2669, +-514, -2286, -1189, -1459, -1659, -479, -1749, 436, +-1435, 1042, -692, 1225, 516, 1138, 1873, 928, +2781, 581, 2915, 246, 2306, 115, 990, 89, +-859, 40, -2597, -71, -3516, -282, -3418, -510, +-2440, -706, -817, -952, 1005, -1131, 2495, -975, +3302, -445, 3216, 251, 2188, 982, 603, 1657, +-962, 2013, -2140, 1886, -2633, 1305, -2276, 299, +-1340, -902, -292, -1882, 634, -2418, 1266, -2405, +1463, -1843, 1302, -936, 847, 181, 194, 1420, +-355, 2346, -610, 2614, -624, 2381, -432, 1731, +-43, 575, 301, -765, 326, -1781, 147, -2349, +-32, -2485, -230, -2072, -390, -1235, -412, -360, +-343, 478, -295, 1376, -135, 2139, 366, 2495, +989, 2367, 1351, 1809, 1357, 868, 1017, -445, +270, -1867, -760, -2815, -1729, -3054, -2315, -2804, +-2335, -2033, -1675, -617, -407, 991, 1189, 2274, +2696, 3232, 3582, 3671, 3454, 3134, 2226, 1769, +177, 119, -2050, -1579, -3672, -3131, -4248, -4010, +-3669, -3790, -2002, -2648, 270, -1047, 2403, 693, +3837, 2264, 4246, 3321, 3476, 3618, 1775, 3107, +-352, 1991, -2354, 615, -3626, -814, -3757, -2147, +-2903, -3072, -1410, -3321, 385, -2925, 1902, -2002, +2666, -606, 2663, 985, 2066, 2291, 1001, 3067, +-208, 3273, -1080, 2744, -1415, 1521, -1299, 43, +-986, -1349, -762, -2484, -634, -3052, -485, -2838, +-257, -1934, 143, -612, 711, 764, 1306, 1854, +1677, 2394, 1537, 2271, 876, 1579, -73, 549, +-1052, -510, -1840, -1286, -2192, -1607, -1889, -1392, +-976, -761, 221, -40, 1369, 641, 2216, 1166, +2436, 1150, 1813, 552, 526, -115, -918, -618, +-2032, -1076, -2546, -1314, -2337, -1040, -1390, -327, +-9, 450, 1358, 1056, 2411, 1564, 2835, 1924, +2358, 1759, 1140, 987, -319, -17, -1679, -1027, +-2721, -2030, -3080, -2720, -2548, -2701, -1311, -2033, +200, -912, 1638, 567, 2807, 2057, 3380, 3151, +3036, 3658, 1869, 3301, 347, 2040, -1202, 344, +-2598, -1407, -3412, -3038, -3349, -4085, -2604, -4129, +-1313, -3220, 401, -1611, 2121, 415, 3374, 2429, +3827, 3946, 3430, 4550, 2230, 4036, 383, 2588, +-1586, 579, -2974, -1575, -3509, -3293, -3337, -4103, +-2525, -3955, -1084, -2974, 598, -1339, 1916, 526, +2656, 2110, 2944, 3120, 2744, 3429, 1836, 2956, +502, 1796, -605, 266, -1333, -1221, -1955, -2285, +-2340, -2728, -2185, -2555, -1657, -1789, -948, -570, +-40, 684, 959, 1631, 1823, 2131, 2408, 2040, +2575, 1399, 2203, 465, 1340, -569, 165, -1419, +-1138, -1774, -2346, -1648, -3150, -1142, -3228, -316, +-2460, 580, -1125, 1264, 483, 1623, 2181, 1597, +3501, 1181, 3849, 480, 3172, -343, 1878, -1107, +118, -1646, -1928, -1866, -3576, -1736, -4302, -1202, +-3976, -307, -2594, 674, -484, 1514, 1739, 2145, +3512, 2346, 4404, 1928, 4172, 1071, 2869, 43, +831, -1001, -1462, -1876, -3361, -2402, -4262, -2440, +-4074, -1948, -2980, -1078, -1164, -31, 954, 992, +2674, 1806, 3545, 2341, 3529, 2447, 2753, 2008, +1358, 1285, -344, 499, -1772, -452, -2542, -1458, +-2699, -2205, -2316, -2642, -1456, -2711, -419, -2164, +493, -1049, 1151, 266, 1514, 1572, 1597, 2743, +1457, 3378, 1107, 3139, 590, 2206, 72, 928, +-385, -537, -817, -1946, -1148, -2867, -1339, -3080, +-1419, -2699, -1301, -1840, -803, -584, -30, 764, +765, 1801, 1505, 2394, 2015, 2571, 2032, 2249, +1545, 1423, 656, 383, -460, -546, -1451, -1271, +-2097, -1785, -2258, -1930, -1835, -1635, -878, -1150, +280, -641, 1300, 84, 2025, 1002, 2232, 1653, +1797, 1821, 962, 1648, 19, 1164, -978, 342, +-1812, -699, -2109, -1662, -1766, -2049, -1044, -1673, +-103, -890, 988, 97, 1912, 1306, 2231, 2265, +1881, 2323, 1161, 1458, 215, 111, -892, -1325, +-1840, -2472, -2225, -2866, -2038, -2272, -1471, -890, +-493, 806, 779, 2206, 1861, 2880, 2389, 2774, +2310, 1929, 1673, 542, 663, -853, -405, -1861, +-1329, -2368, -1944, -2276, -2017, -1656, -1615, -781, +-1051, 85, -429, 704, 282, 1019, 966, 1139, +1359, 1115, 1405, 1040, 1341, 1026, 1271, 988, +1084, 816, 664, 459, 47, -231, -722, -1237, +-1615, -2190, -2384, -2743, -2694, -2777, -2435, -2143, +-1578, -753, -150, 1037, 1567, 2709, 3042, 3885, +3803, 4162, 3742, 3288, 2846, 1512, 1112, -680, +-1101, -2747, -3107, -4106, -4375, -4437, -4655, -3694, +-3805, -2001, -1919, 112, 451, 1954, 2549, 3184, +3966, 3643, 4533, 3247, 3966, 2212, 2326, 878, +248, -531, -1646, -1739, -3042, -2451, -3700, -2609, +-3433, -2346, -2380, -1724, -995, -763, 330, 347, +1435, 1286, 2191, 1884, 2449, 2179, 2233, 2123, +1760, 1591, 1037, 704, 63, -243, -907, -1106, +-1647, -1809, -2126, -2104, -2292, -1810, -1964, -1143, +-1171, -396, -157, 412, 918, 1170, 1895, 1561, +2445, 1522, 2399, 1235, 1826, 797, 878, 306, +-364, -80, -1613, -346, -2308, -598, -2281, -894, +-1791, -1163, -1043, -1292, -41, -1194, 1026, -848, +1680, -264, 1677, 563, 1349, 1478, 1017, 2056, +582, 2119, 35, 1837, -402, 1150, -686, 16, +-879, -1174, -951, -2091, -955, -2635, -907, -2600, +-686, -1885, -266, -707, 213, 617, 677, 1807, +1117, 2583, 1496, 2722, 1733, 2243, 1547, 1327, +791, 170, -190, -928, -1082, -1665, -1836, -2020, +-2224, -2023, -1972, -1616, -1271, -936, -435, -272, +527, 234, 1435, 654, 1907, 1083, 1992, 1433, +1846, 1585, 1329, 1562, 436, 1303, -539, 712, +-1280, -154, -1707, -1118, -1841, -1913, -1699, -2245, +-1229, -2092, -448, -1545, 355, -578, 990, 567, +1484, 1407, 1731, 1779, 1577, 1836, 1106, 1608, +452, 1049, -290, 316, -950, -324, -1338, -754, +-1414, -1044, -1239, -1292, -823, -1382, -207, -1127, +420, -648, 786, -192, 831, 221, 703, 628, +434, 904, 33, 960, -282, 843, -319, 654, +-166, 462, 67, 238, 325, -70, 511, -351, +550, -502, 285, -639, -346, -788, -1070, -804, +-1526, -709, -1584, -626, -1217, -478, -443, -129, +627, 396, 1675, 955, 2335, 1452, 2332, 1812, +1678, 1819, 674, 1236, -523, 148, -1726, -1080, +-2522, -2146, -2624, -2814, -2153, -2798, -1256, -1963, +-25, -577, 1198, 918, 2045, 2272, 2489, 3217, +2480, 3299, 1864, 2448, 790, 1040, -401, -619, +-1422, -2182, -2163, -3158, -2504, -3305, -2293, -2585, +-1544, -1074, -487, 731, 639, 2082, 1685, 2662, +2411, 2615, 2561, 1979, 2135, 760, 1295, -546, +114, -1369, -1188, -1578, -2126, -1315, -2416, -803, +-2206, -249, -1657, 237, -699, 426, 516, 154, +1477, -263, 1903, -419, 1933, -291, 1638, 60, +1061, 690, 423, 1439, -167, 1889, -674, 1729, +-1023, 984, -1218, -160, -1350, -1473, -1398, -2575, +-1242, -3065, -834, -2727, -146, -1588, 736, 54, +1555, 1744, 2169, 3057, 2468, 3626, 2188, 3257, +1331, 2054, 163, 360, -1167, -1388, -2443, -2777, +-3112, -3437, -2863, -3141, -2002, -2001, -804, -448, +634, 995, 1962, 1910, 2726, 2175, 2761, 1850, +2153, 1068, 1097, 163, -116, -433, -1184, -609, +-1798, -502, -1739, -169, -1177, 209, -538, 302, +-8, 103, 357, -249, 385, -794, 96, -1330, +-232, -1452, -369, -1122, -317, -494, -106, 378, +338, 1295, 995, 1926, 1523, 2103, 1604, 1791, +1282, 1045, 617, 57, -366, -932, -1476, -1710, +-2327, -2071, -2610, -1956, -2279, -1463, -1488, -711, +-387, 134, 849, 801, 1950, 1125, 2589, 1166, +2658, 1018, 2281, 771, 1439, 523, 242, 311, +-937, 190, -1786, 161, -2272, 21, -2396, -299, +-2070, -667, -1338, -1012, -446, -1232, 357, -1239, +990, -1060, 1475, -623, 1781, 95, 1799, 774, +1510, 1177, 969, 1411, 297, 1527, -381, 1372, +-969, 937, -1389, 382, -1546, -203, -1348, -767, +-910, -1198, -494, -1455, -168, -1572, 136, -1488, +381, -1161, 550, -631, 748, 48, 991, 778, +1142, 1443, 1080, 1994, 870, 2255, 610, 2040, +188, 1427, -473, 559, -1129, -446, -1522, -1433, +-1690, -2224, -1682, -2604, -1329, -2416, -494, -1727, +506, -747, 1245, 315, 1666, 1280, 1863, 1960, +1750, 2224, 1230, 2079, 583, 1638, 63, 1042, +-435, 389, -954, -277, -1334, -882, -1505, -1347, +-1503, -1662, -1321, -1774, -879, -1652, -193, -1351, +555, -872, 1189, -179, 1594, 647, 1726, 1444, +1582, 2102, 1168, 2508, 519, 2525, -209, 2043, +-793, 1036, -1173, -298, -1361, -1604, -1276, -2669, +-906, -3315, -448, -3221, -136, -2348, -16, -1074, +34, 347, 163, 1793, 418, 2871, 766, 3264, +1152, 3033, 1519, 2258, 1608, 973, 1142, -525, +273, -1801, -617, -2618, -1423, -2910, -2131, -2562, +-2431, -1603, -2087, -407, -1190, 684, -37, 1491, +1118, 1869, 1994, 1820, 2320, 1430, 1994, 773, +1128, 75, 124, -425, -602, -744, -972, -927, +-1032, -867, -754, -556, -325, -235, -18, -44, +-2, 82, -242, 103, -540, -67, -745, -282, +-801, -356, -627, -266, -140, -18, 555, 397, +1251, 868, 1761, 1139, 1880, 1004, 1486, 560, +753, 33, -88, -547, -1012, -1107, -1870, -1361, +-2237, -1243, -2027, -916, -1608, -414, -1040, 241, +-143, 840, 839, 1195, 1514, 1258, 1877, 984, +2076, 413, 2005, -170, 1513, -567, 687, -811, +-237, -799, -1118, -439, -1878, -4, -2315, 214, +-2254, 245, -1758, 178, -1019, 19, -96, -183, +899, -338, 1649, -361, 1961, -143, 1959, 247, +1731, 569, 1191, 728, 360, 758, -421, 577, +-850, 137, -1106, -360, -1374, -683, -1481, -783, +-1291, -694, -957, -429, -616, -121, -177, 72, +458, 156, 1160, 207, 1661, 284, 1795, 427, +1626, 603, 1228, 687, 555, 643, -293, 486, +-1058, 120, -1575, -448, -1762, -955, -1627, -1219, +-1243, -1246, -622, -1017, 191, -456, 904, 373, +1277, 1200, 1435, 1769, 1400, 1916, 1013, 1551, +425, 721, -30, -370, -382, -1409, -722, -2075, +-898, -2193, -858, -1717, -721, -746, -504, 408, +-187, 1423, 159, 2084, 474, 2222, 642, 1777, +587, 870, 397, -268, 184, -1336, -85, -2023, +-331, -2112, -395, -1646, -286, -866, -103, 42, +116, 934, 407, 1531, 669, 1639, 706, 1391, +437, 967, -74, 420, -685, -162, -1165, -644, +-1379, -972, -1264, -1163, -764, -1244, 27, -1166, +850, -847, 1448, -304, 1737, 330, 1668, 903, +1188, 1356, 404, 1597, -447, 1465, -1181, 970, +-1669, 280, -1811, -492, -1559, -1227, -946, -1718, +-158, -1808, 531, -1499, 979, -846, 1204, 57, +1183, 916, 932, 1437, 617, 1550, 332, 1289, +64, 735, -139, 118, -280, -333, -502, -579, +-797, -667, -1004, -635, -1110, -554, -1071, -494, +-738, -451, -176, -404, 415, -266, 1043, 45, +1625, 425, 1819, 726, 1517, 930, 924, 972, +139, 728, -811, 221, -1657, -388, -1998, -928, +-1749, -1239, -1146, -1185, -336, -748, 535, -9, +1159, 812, 1384, 1391, 1294, 1478, 957, 1010, +406, 136, -182, -831, -620, -1561, -842, -1791, +-785, -1371, -457, -384, -16, 798, 350, 1714, +499, 2107, 414, 1890, 210, 1076, -65, -67, +-347, -1129, -458, -1848, -346, -2069, -174, -1695, +-52, -839, 110, 172, 290, 979, 393, 1395, +432, 1395, 473, 1059, 457, 569, 322, 117, +77, -199, -237, -324, -512, -247, -678, -146, +-752, -193, -717, -331, -465, -485, -28, -661, +403, -731, 686, -566, 823, -232, 802, 191, +603, 707, 293, 1149, -10, 1277, -239, 1120, +-432, 782, -536, 265, -489, -344, -362, -888, +-251, -1259, -145, -1315, -37, -1058, 37, -684, +101, -268, 170, 208, 211, 613, 277, 819, +384, 891, 370, 915, 252, 859, 163, 648, +71, 279, -81, -156, -246, -554, -381, -906, +-495, -1143, -538, -1099, -426, -771, -212, -311, +-44, 185, 71, 645, 216, 928, 344, 950, +382, 700, 398, 226, 437, -303, 383, -633, +215, -652, 80, -417, -34, -4, -278, 475, +-552, 785, -637, 697, -611, 258, -607, -336, +-497, -931, -168, -1330, 186, -1309, 376, -876, +484, -207, 619, 580, 716, 1304, 688, 1662, +588, 1562, 421, 1159, 85, 520, -379, -257, +-755, -958, -951, -1454, -1047, -1657, -1042, -1449, +-805, -919, -356, -296, 97, 320, 508, 864, +947, 1158, 1323, 1122, 1427, 910, 1193, 648, +790, 354, 287, 41, -372, -265, -1070, -515, +-1539, -655, -1669, -716, -1492, -726, -994, -608, +-234, -334, 542, -26, 1111, 213, 1426, 425, +1446, 608, 1146, 646, 621, 472, 102, 222, +-292, 54, -592, -32, -766, -41, -712, 71, +-502, 213, -308, 198, -154, -44, -76, -440, +-132, -821, -254, -1028, -266, -968, -122, -601, +149, 28, 544, 724, 956, 1245, 1204, 1459, +1217, 1334, 944, 899, 333, 276, -439, -374, +-1131, -933, -1632, -1212, -1840, -1119, -1584, -827, +-873, -500, 50, -84, 906, 342, 1492, 502, +1685, 402, 1463, 331, 946, 386, 305, 436, +-318, 486, -734, 605, -778, 655, -569, 402, +-360, -110, -235, -657, -201, -1108, -301, -1381, +-499, -1338, -601, -910, -460, -229, -112, 486, +332, 1069, 790, 1446, 1200, 1548, 1446, 1295, +1353, 690, 855, -60, 103, -706, -724, -1127, +-1488, -1295, -1956, -1205, -1892, -871, -1273, -380, +-342, 70, 563, 367, 1202, 599, 1485, 795, +1367, 842, 899, 719, 322, 542, -116, 317, +-391, -12, -559, -356, -538, -628, -357, -835, +-200, -938, -110, -863, -44, -607, -88, -169, +-238, 349, -318, 765, -292, 1029, -216, 1134, +-36, 924, 244, 387, 521, -171, 744, -577, +827, -887, 659, -1036, 310, -888, -46, -530, +-351, -145, -660, 173, -861, 411, -790, 585, +-560, 702, -395, 703, -232, 547, 89, 300, +431, 8, 603, -326, 649, -661, 652, -864, +564, -792, 370, -461, 113, -72, -110, 232, +-245, 470, -364, 607, -483, 516, -491, 251, +-402, 43, -375, -38, -358, -80, -210, -83, +-3, 18, 141, 128, 339, 109, 635, -21, +819, -187, 768, -414, 556, -615, 274, -584, +-63, -333, -424, -4, -696, 370, -753, 761, +-637, 964, -467, 871, -262, 571, -18, 153, +166, -300, 230, -641, 256, -799, 297, -777, +339, -583, 393, -309, 432, -46, 409, 186, +364, 353, 298, 397, 91, 396, -251, 433, +-565, 453, -781, 432, -925, 428, -945, 355, +-739, 73, -287, -348, 274, -754, 763, -1052, +1061, -1155, 1077, -935, 893, -380, 693, 317, +449, 905, 66, 1247, -302, 1266, -528, 937, +-739, 407, -967, -105, -1065, -487, -981, -728, +-767, -802, -411, -714, 88, -513, 637, -273, +1144, -41, 1495, 152, 1564, 298, 1337, 399, +847, 444, 113, 449, -706, 413, -1387, 300, +-1800, 99, -1858, -148, -1512, -407, -821, -612, +39, -687, 828, -527, 1354, -95, 1560, 399, +1430, 672, 965, 685, 374, 507, -86, 80, +-417, -520, -708, -933, -839, -912, -693, -580, +-399, -86, -178, 502, -109, 987, -164, 1143, +-260, 922, -291, 443, -219, -110, 5, -588, +418, -926, 884, -1066, 1090, -957, 926, -625, +590, -217, 263, 169, -120, 532, -577, 810, +-910, 899, -1011, 807, -976, 616, -840, 319, +-506, -58, -32, -398, 378, -650, 608, -859, +722, -929, 805, -750, 869, -412, 847, -1, +662, 486, 289, 883, -214, 958, -678, 742, +-995, 371, -1169, -70, -1151, -476, -849, -692, +-347, -615, 178, -253, 670, 199, 1088, 532, +1258, 683, 1055, 587, 583, 159, 2, -475, +-517, -1008, -773, -1269, -722, -1135, -456, -538, +-97, 333, 211, 1176, 356, 1779, 316, 1888, +100, 1359, -211, 432, -456, -550, -559, -1396, +-512, -1890, -255, -1813, 189, -1253, 599, -442, +808, 424, 864, 1090, 822, 1365, 588, 1318, +151, 1024, -298, 500, -654, -72, -953, -464, +-1131, -629, -1041, -631, -711, -512, -285, -344, +161, -187, 578, -59, 891, -4, 1082, -7, +1142, 66, 994, 203, 634, 265, 151, 276, +-390, 297, -876, 255, -1148, 86, -1188, -98, +-1060, -167, -757, -143, -279, -121, 253, -71, +653, 51, 862, 133, 939, 71, 871, -81, +612, -222, 246, -337, -24, -396, -136, -328, +-213, -96, -350, 221, -480, 488, -559, 613, +-602, 614, -579, 499, -467, 235, -285, -117, +-3, -433, 355, -620, 610, -617, 703, -474, +705, -325, 620, -159, 415, 53, 182, 177, +-10, 149, -195, 122, -363, 221, -459, 381, +-533, 509, -649, 569, -693, 527, -583, 353, +-408, 28, -231, -448, 35, -922, 425, -1200, +838, -1222, 1191, -956, 1411, -379, 1363, 368, +955, 1058, 243, 1504, -605, 1544, -1351, 1135, +-1803, 446, -1935, -276, -1775, -883, -1241, -1211, +-338, -1136, 664, -797, 1499, -407, 2075, -29, +2263, 259, 1906, 358, 1109, 352, 204, 355, +-593, 374, -1241, 394, -1654, 440, -1715, 437, +-1501, 286, -1146, 13, -648, -306, -10, -635, +614, -866, 1049, -848, 1270, -580, 1362, -169, +1344, 279, 1123, 680, 663, 906, 78, 849, +-485, 520, -975, 66, -1363, -334, -1503, -566, +-1298, -590, -883, -408, -437, -98, 61, 169, +625, 292, 1066, 253, 1234, 86, 1181, -115, +996, -243, 659, -263, 205, -119, -176, 183, +-365, 460, -476, 554, -641, 467, -847, 221, +-1018, -192, -1067, -625, -913, -873, -512, -826, +75, -472, 701, 86, 1226, 619, 1544, 972, +1573, 1087, 1294, 877, 731, 350, -14, -312, +-737, -842, -1299, -1097, -1603, -1083, -1568, -807, +-1215, -270, -690, 310, -115, 689, 445, 868, +916, 903, 1197, 750, 1255, 461, 1151, 178, +873, -99, 395, -399, -141, -663, -541, -870, +-848, -988, -1126, -867, -1207, -494, -950, 3, +-493, 550, 1, 1038, 520, 1287, 943, 1204, +1057, 812, 838, 189, 439, -464, -20, -957, +-418, -1216, -614, -1192, -554, -808, -297, -201, +61, 359, 402, 754, 576, 901, 479, 717, +129, 305, -356, -144, -797, -493, -983, -559, +-800, -288, -331, 156, 260, 560, 806, 742, +1107, 581, 1058, 127, 725, -457, 221, -1025, +-339, -1340, -766, -1150, -883, -523, -691, 227, +-327, 949, 57, 1502, 339, 1603, 433, 1165, +304, 391, 8, -473, -297, -1176, -450, -1488, +-388, -1318, -146, -772, 223, -71, 620, 599, +888, 1018, 926, 1018, 677, 669, 129, 187, +-527, -290, -1003, -641, -1180, -698, -1080, -433, +-733, -32, -217, 326, 310, 588, 700, 659, +901, 479, 943, 126, 843, -259, 548, -571, +107, -742, -260, -731, -433, -516, -521, -178, +-592, 166, -544, 489, -387, 712, -251, 756, +-151, 668, -8, 535, 182, 319, 380, -3, +537, -341, 575, -627, 431, -905, 166, -1115, +-70, -1043, -228, -645, -325, -37, -308, 667, +-171, 1321, -19, 1673, 89, 1544, 89, 964, +-76, 129, -275, -747, -332, -1451, -267, -1771, +-159, -1578, 57, -890, 372, 26, 558, 855, +504, 1412, 374, 1554, 237, 1173, -14, 401, +-337, -457, -515, -1089, -457, -1287, -271, -982, +-59, -293, 170, 490, 338, 1075, 249, 1252, +-102, 928, -450, 194, -620, -649, -589, -1275, +-297, -1462, 246, -1168, 834, -495, 1250, 375, +1367, 1170, 1093, 1616, 450, 1583, -400, 1103, +-1279, 288, -1950, -628, -2081, -1324, -1569, -1605, +-659, -1480, 356, -964, 1281, -166, 1897, 583, +2027, 1055, 1678, 1234, 988, 1112, 140, 716, +-666, 212, -1232, -248, -1476, -565, -1443, -707, +-1172, -714, -689, -631, -150, -435, 279, -145, +606, 139, 875, 380, 1024, 573, 1006, 653, +862, 552, 602, 276, 214, -103, -232, -416, +-629, -584, -919, -633, -1095, -513, -1083, -177, +-782, 243, -242, 558, 332, 687, 760, 618, +976, 368, 954, -36, 686, -495, 285, -839, +-78, -884, -318, -604, -435, -153, -457, 342, +-391, 767, -233, 917, -36, 725, 88, 379, +104, 10, 42, -358, -65, -619, -98, -613, +26, -418, 205, -232, 304, -70, 298, 103, +170, 184, -57, 130, -259, 36, -328, -1, +-254, 73, -85, 248, 128, 479, 292, 638, +358, 571, 330, 241, 167, -269, -150, -832, +-485, -1223, -685, -1257, -687, -905, -434, -228, +44, 595, 563, 1288, 912, 1582, 994, 1397, +780, 853, 294, 126, -320, -646, -793, -1230, +-987, -1393, -967, -1130, -721, -653, -190, -121, +447, 421, 863, 821, 948, 928, 801, 767, +449, 479, -101, 199, -627, -11, -839, -222, +-722, -414, -464, -455, -151, -396, 227, -395, +570, -398, 702, -229, 602, 76, 374, 355, +64, 545, -282, 652, -540, 613, -622, 385, +-505, -9, -272, -444, -93, -723, -3, -758, +133, -613, 324, -313, 442, 162, 499, 643, +535, 848, 445, 722, 168, 447, -174, 62, +-471, -426, -711, -787, -811, -811, -691, -558, +-416, -194, -44, 218, 408, 619, 801, 826, +947, 685, 803, 321, 447, -85, -15, -475, +-450, -771, -708, -794, -712, -490, -492, -46, +-165, 329, 157, 565, 406, 655, 502, 584, +416, 384, 176, 91, -152, -231, -461, -490, +-587, -628, -424, -676, -52, -609, 326, -331, +574, 81, 647, 440, 492, 702, 128, 847, +-241, 738, -393, 423, -354, 83, -259, -248, +-155, -553, -54, -713, -27, -715, -91, -627, +-198, -429, -307, -120, -273, 189, 9, 430, +423, 624, 797, 726, 1048, 698, 1033, 548, +639, 295, -51, -27, -824, -345, -1429, -625, +-1650, -836, -1402, -891, -770, -735, 82, -388, +921, 28, 1485, 443, 1605, 785, 1292, 918, +682, 777, -56, 478, -679, 161, -975, -121, +-924, -322, -646, -369, -292, -304, 4, -299, +131, -388, 39, -464, -158, -465, -250, -386, +-158, -162, 72, 214, 405, 629, 789, 922, +1057, 1022, 991, 898, 539, 495, -120, -100, +-751, -674, -1239, -1077, -1443, -1244, -1179, -1064, +-511, -518, 222, 189, 724, 778, 929, 1111, +861, 1092, 558, 699, 164, 92, -107, -552, +-146, -1002, 0, -966, 183, -474, 266, 120, +161, 658, -157, 1061, -582, 1066, -932, 558, +-1077, -182, -920, -827, -405, -1223, 321, -1234, +987, -827, 1413, -168, 1482, 499, 1122, 964, +436, 1098, -340, 942, -982, 570, -1312, 72, +-1229, -335, -800, -473, -239, -386, 262, -226, +582, -105, 641, -105, 453, -254, 161, -500, +-53, -719, -115, -743, -38, -410, 133, 265, +329, 1024, 423, 1583, 313, 1766, 47, 1447, +-264, 645, -562, -412, -783, -1456, -786, -2178, +-506, -2287, -59, -1722, 358, -709, 636, 467, +734, 1504, 609, 2079, 289, 2026, -24, 1423, +-134, 465, -68, -536, 27, -1186, 48, -1332, +-19, -1075, -167, -561, -410, 43, -672, 453, +-750, 464, -548, 170, -166, -175, 282, -401, +727, -432, 1053, -195, 1108, 272, 843, 772, +360, 1042, -175, 946, -650, 551, -1001, 1, +-1134, -620, -942, -1154, -481, -1332, 8, -1055, +381, -494, 670, 136, 837, 697, 751, 1017, +425, 986, 49, 662, -199, 205, -302, -221, +-314, -460, -261, -458, -178, -298, -85, -109, +0, 34, 6, 125, -87, 145, -173, 61, +-145, -114, -23, -258, 99, -265, 173, -187, +238, -119, 305, 16, 284, 246, 143, 413, +-24, 451, -125, 421, -175, 306, -231, 89, +-270, -109, -253, -275, -189, -475, -67, -606, +91, -553, 202, -394, 237, -169, 211, 127, +131, 409, 22, 634, -74, 755, -135, 649, +-132, 339, -41, -13, 66, -350, 149, -614, +213, -683, 196, -515, 30, -207, -223, 103, +-419, 288, -481, 297, -401, 207, -174, 48, +164, -141, 489, -185, 668, -1, 640, 224, +427, 389, 70, 500, -324, 447, -605, 142, +-707, -281, -638, -655, -383, -911, 55, -927, +511, -593, 772, -13, 747, 563, 479, 981, +45, 1145, -444, 980, -815, 493, -874, -169, +-592, -726, -117, -973, 397, -945, 812, -722, +967, -279, 778, 252, 354, 607, -154, 663, +-640, 507, -935, 256, -891, -2, -553, -189, +-114, -215, 270, -60, 514, 141, 564, 219, +427, 118, 188, -118, -10, -444, -56, -713, +-1, -742, 64, -469, 148, 46, 193, 662, +53, 1154, -268, 1327, -587, 1064, -773, 373, +-789, -517, -594, -1286, -154, -1660, 463, -1507, +1049, -859, 1373, 76, 1313, 1017, 874, 1620, +158, 1636, -640, 1103, -1284, 275, -1576, -590, +-1424, -1263, -870, -1469, -99, -1117, 629, -412, +1126, 353, 1288, 954, 1083, 1188, 593, 964, +0, 389, -508, -322, -787, -918, -755, -1145, +-454, -902, -69, -336, 207, 361, 307, 992, +269, 1291, 82, 1068, -207, 447, -402, -324, +-390, -1019, -227, -1391, 49, -1270, 415, -687, +731, 125, 812, 855, 601, 1278, 163, 1313, +-388, 936, -858, 249, -1063, -489, -936, -1017, +-522, -1198, 53, -1007, 590, -529, 909, 71, +939, 632, 704, 978, 294, 987, -198, 717, +-639, 314, -839, -161, -697, -600, -343, -830, +37, -796, 359, -592, 573, -303, 588, 49, +365, 404, 39, 656, -223, 735, -378, 669, +-479, 497, -482, 238, -284, -100, 66, -464, +367, -770, 490, -897, 474, -785, 350, -487, +109, -56, -171, 431, -347, 808, -371, 916, +-326, 763, -286, 462, -184, 102, 11, -279, +180, -541, 258, -555, 328, -405, 387, -259, +284, -134, 29, 10, -174, 79, -258, 2, +-328, -116, -403, -93, -346, 75, -123, 273, +96, 457, 234, 617, 380, 625, 497, 380, +427, -17, 184, -406, -88, -720, -334, -913, +-527, -874, -574, -589, -453, -185, -228, 212, +42, 570, 299, 836, 488, 908, 587, 743, +558, 451, 376, 140, 102, -193, -202, -499, +-508, -688, -704, -732, -698, -663, -528, -510, +-249, -297, 128, -27, 496, 274, 681, 571, +647, 795, 486, 864, 256, 757, -36, 454, +-300, -11, -418, -518, -412, -900, -397, -1031, +-363, -851, -215, -421, -6, 76, 112, 468, +169, 691, 284, 699, 374, 484, 316, 195, +189, -32, 119, -206, 69, -331, -65, -341, +-260, -244, -372, -118, -353, -20, -290, 58, +-226, 141, -100, 177, 104, 117, 287, 19, +352, -22, 297, -16, 209, -16, 127, -46, +17, -88, -94, -143, -121, -171, -82, -108, +-66, 34, -105, 188, -189, 326, -300, 402, +-346, 347, -238, 158, -16, -127, 243, -423, +474, -616, 610, -624, 592, -466, 389, -186, +37, 188, -343, 554, -630, 763, -781, 757, +-738, 549, -429, 173, 60, -244, 496, -568, +715, -719, 692, -672, 469, -445, 114, -129, +-216, 179, -358, 396, -318, 461, -220, 404, +-143, 293, -81, 154, -24, -4, 2, -127, +-32, -195, -88, -218, -64, -210, 74, -162, +224, -86, 315, -5, 370, 64, 333, 107, +96, 113, -276, 84, -557, 41, -638, -6, +-533, -27, -257, -15, 118, 3, 460, 32, +657, 90, 648, 120, 444, 59, 94, -58, +-335, -149, -699, -184, -813, -188, -622, -143, +-218, -8, 287, 195, 705, 328, 825, 292, +595, 128, 160, -74, -292, -286, -616, -431, +-705, -382, -534, -141, -172, 179, 231, 477, +496, 660, 519, 592, 347, 248, 83, -228, +-184, -659, -372, -923, -397, -902, -266, -569, +-67, -46, 143, 533, 319, 1000, 389, 1168, +298, 978, 105, 533, -107, -62, -340, -669, +-546, -1086, -562, -1183, -324, -985, 32, -557, +328, 23, 502, 564, 568, 910, 491, 1025, +279, 905, 22, 581, -197, 161, -386, -265, +-542, -605, -615, -794, -587, -805, -426, -660, +-84, -389, 376, -14, 746, 372, 885, 642, +797, 748, 511, 671, 68, 386, -399, 3, +-755, -341, -921, -586, -846, -651, -546, -466, +-99, -99, 391, 282, 802, 548, 980, 618, +815, 461, 334, 87, -271, -400, -750, -803, +-946, -925, -802, -704, -344, -213, 264, 424, +766, 1014, 966, 1317, 798, 1202, 332, 697, +-258, -67, -752, -849, -994, -1394, -928, -1539, +-582, -1217, -71, -524, 433, 291, 790, 979, +940, 1371, 847, 1368, 504, 972, 36, 316, +-366, -373, -620, -871, -732, -1039, -670, -888, +-418, -516, -117, -24, 85, 437, 198, 668, +260, 581, 253, 273, 221, -87, 237, -382, +260, -535, 225, -449, 163, -126, 96, 282, +-57, 601, -278, 752, -423, 681, -432, 362, +-392, -112, -344, -561, -232, -872, -55, -984, +115, -835, 246, -448, 388, 56, 516, 533, +533, 880, 451, 1026, 314, 953, 65, 672, +-285, 226, -589, -273, -755, -710, -802, -996, +-720, -1039, -443, -812, 0, -413, 475, 67, +825, 526, 957, 822, 820, 869, 427, 695, +-85, 386, -504, 37, -696, -274, -659, -497, +-426, -555, -48, -429, 308, -229, 410, -50, +243, 121, -27, 225, -282, 171, -479, 36, +-515, -25, -300, -19, 108, -5, 545, 73, +833, 204, 855, 271, 602, 201, 172, 14, +-329, -213, -782, -378, -1026, -426, -950, -345, +-585, -140, -76, 154, 396, 429, 690, 542, +749, 461, 560, 241, 190, -68, -182, -381, +-365, -567, -336, -581, -167, -437, 104, -166, +386, 188, 463, 525, 224, 711, -180, 684, +-537, 476, -765, 142, -792, -245, -528, -566, +-48, -726, 432, -685, 739, -470, 843, -165, +736, 107, 414, 302, 19, 446, -271, 512, +-417, 476, -469, 397, -419, 302, -269, 153, +-111, -42, -41, -265, -76, -513, -163, -723, +-210, -778, -131, -629, 82, -310, 337, 116, +545, 547, 680, 860, 681, 963, 470, 816, +89, 450, -307, 23, -648, -335, -909, -612, +-986, -779, -792, -752, -416, -557, 7, -296, +429, -22, 757, 243, 844, 466, 701, 569, +493, 542, 292, 453, 56, 339, -197, 154, +-390, -106, -510, -342, -597, -464, -624, -497, +-525, -466, -312, -338, -66, -119, 177, 136, +415, 327, 595, 393, 615, 379, 473, 327, +251, 190, 18, -19, -200, -196, -353, -261, +-384, -218, -307, -116, -191, 6, -114, 108, +-102, 137, -129, 48, -148, -111, -125, -230, +-38, -254, 93, -192, 230, -45, 349, 161, +433, 363, 434, 487, 296, 465, 52, 286, +-235, 2, -509, -299, -691, -553, -662, -668, +-391, -570, -1, -283, 328, 67, 494, 375, +497, 580, 350, 639, 83, 541, -181, 294, +-306, -34, -296, -324, -210, -505, -65, -586, +124, -537, 283, -331, 331, -39, 239, 232, +30, 437, -214, 550, -390, 517, -431, 338, +-338, 97, -142, -128, 71, -329, 199, -481, +227, -505, 219, -361, 199, -138, 145, 51, +69, 203, 19, 337, 12, 408, 13, 359, +-5, 210, -42, 28, -105, -119, -224, -211, +-348, -238, -386, -198, -318, -116, -188, -53, +1, -37, 217, -52, 368, -88, 440, -100, +511, -26, 566, 118, 454, 262, 159, 383, +-191, 446, -504, 394, -751, 206, -881, -72, +-842, -397, -633, -707, -283, -877, 159, -796, +623, -458, 1009, 63, 1197, 645, 1102, 1078, +737, 1207, 170, 994, -476, 492, -1018, -168, +-1302, -766, -1299, -1120, -1022, -1172, -500, -942, +150, -482, 749, 96, 1127, 592, 1199, 897, +980, 994, 535, 874, -38, 560, -553, 138, +-861, -307, -937, -675, -791, -858, -435, -819, +12, -588, 362, -220, 548, 203, 583, 528, +432, 661, 111, 624, -197, 436, -333, 142, +-327, -138, -267, -319, -147, -404, 12, -398, +96, -297, 81, -116, 81, 87, 150, 232, +175, 270, 127, 230, 91, 147, 69, 28, +-36, -95, -216, -151, -390, -150, -525, -152, +-570, -143, -445, -81, -132, 39, 303, 163, +733, 245, 1004, 278, 1005, 253, 687, 123, +109, -96, -530, -291, -1005, -373, -1226, -370, +-1175, -305, -807, -141, -185, 96, 469, 315, +953, 451, 1164, 469, 1042, 342, 634, 113, +113, -130, -357, -337, -684, -465, -798, -460, +-661, -308, -347, -70, -21, 170, 178, 361, +246, 477, 220, 462, 112, 271, -39, -51, +-123, -360, -64, -545, 95, -567, 260, -396, +340, -57, 276, 317, 95, 575, -100, 659, +-263, 576, -389, 339, -420, -12, -321, -380, +-183, -654, -59, -775, 94, -731, 261, -504, +337, -102, 288, 363, 195, 724, 120, 901, +51, 879, -27, 632, -82, 207, -110, -248, +-154, -603, -249, -821, -336, -857, -321, -675, +-189, -357, 2, -22, 203, 291, 361, 550, +388, 689, 295, 682, 132, 531, -70, 277, +-254, -14, -327, -275, -263, -458, -137, -513, +-29, -423, 67, -264, 166, -127, 193, -41, +80, 14, -95, 50, -190, 101, -219, 203, +-235, 333, -154, 415, 71, 384, 284, 233, +353, 19, 307, -191, 175, -363, -41, -467, +-271, -449, -420, -304, -440, -117, -305, 57, +-67, 222, 151, 345, 265, 361, 303, 281, +270, 155, 119, 0, -99, -163, -267, -275, +-318, -282, -264, -194, -113, -45, 109, 131, +313, 285, 373, 352, 268, 283, 44, 67, +-243, -230, -486, -487, -543, -602, -392, -540, +-125, -302, 182, 98, 435, 549, 540, 848, +473, 881, 267, 674, -30, 280, -347, -215, +-584, -659, -640, -910, -469, -904, -132, -667, +268, -295, 616, 82, 749, 394, 541, 624, +87, 738, -362, 700, -655, 516, -758, 223, +-626, -109, -257, -390, 200, -560, 558, -608, +739, -526, 742, -312, 542, -60, 134, 108, +-364, 173, -741, 209, -871, 258, -757, 315, +-437, 371, 38, 391, 493, 313, 731, 121, +705, -146, 485, -426, 150, -632, -217, -673, +-485, -517, -567, -205, -443, 170, -157, 472, +158, 605, 371, 575, 449, 425, 357, 187, +60, -56, -316, -232, -557, -354, -589, -416, +-459, -380, -168, -262, 235, -131, 590, 24, +761, 214, 720, 367, 488, 413, 91, 345, +-382, 202, -774, 14, -940, -197, -827, -385, +-495, -450, -45, -365, 403, -198, 694, 24, +747, 294, 585, 490, 278, 490, -59, 327, +-293, 94, -395, -173, -414, -417, -328, -536, +-144, -476, 45, -259, 170, 31, 205, 308, +115, 512, -70, 564, -237, 387, -314, 51, +-295, -266, -153, -456, 103, -496, 359, -348, +505, -34, 495, 282, 355, 441, 128, 396, +-151, 179, -453, -130, -697, -398, -764, -503, +-598, -391, -254, -102, 131, 258, 436, 568, +585, 700, 565, 570, 425, 205, 244, -255, +48, -669, -163, -899, -322, -829, -356, -465, +-298, 46, -224, 549, -152, 909, -89, 984, +-77, 733, -117, 248, -126, -306, -29, -741, +175, -900, 396, -777, 511, -444, 439, 21, +204, 471, -68, 712, -282, 670, -444, 434, +-550, 114, -506, -195, -304, -404, -66, -476, +151, -394, 380, -176, 537, 60, 484, 201, +232, 264, -66, 289, -289, 217, -416, 56, +-441, -63, -344, -94, -103, -108, 200, -129, +422, -123, 482, -117, 396, -127, 185, -110, +-123, -44, -426, 64, -579, 208, -528, 339, +-332, 373, -97, 284, 99, 99, 264, -143, +403, -376, 481, -501, 476, -480, 398, -316, +224, -22, -67, 310, -382, 525, -597, 531, +-702, 345, -727, 33, -570, -291, -194, -483, +236, -445, 577, -187, 835, 183, 943, 485, +777, 571, 358, 406, -151, 40, -599, -402, +-899, -730, -995, -807, -860, -618, -487, -209, +20, 311, 506, 766, 842, 1004, 957, 961, +814, 640, 429, 134, -99, -413, -599, -871, +-873, -1107, -839, -1020, -598, -662, -251, -178, +180, 344, 540, 790, 647, 1005, 530, 936, +314, 645, 27, 214, -275, -245, -412, -593, +-316, -751, -141, -709, -32, -493, -7, -192, +-60, 84, -161, 293, -240, 397, -210, 367, +-35, 263, 226, 171, 441, 97, 538, 26, +530, -24, 385, -69, 70, -137, -345, -200, +-741, -236, -1009, -243, -1010, -183, -682, -47, +-123, 102, 472, 206, 930, 248, 1132, 226, +1034, 156, 678, 71, 168, -11, -354, -72, +-756, -99, -953, -120, -954, -168, -771, -207, +-424, -196, 12, -131, 417, -35, 661, 96, +703, 261, 624, 403, 486, 439, 249, 324, +-44, 89, -255, -187, -369, -424, -494, -575, +-587, -582, -516, -400, -304, -85, -78, 237, +133, 488, 363, 626, 540, 595, 560, 416, +417, 173, 186, -99, -90, -379, -360, -575, +-507, -642, -453, -584, -284, -371, -95, -29, +109, 309, 279, 562, 321, 714, 237, 694, +123, 451, 2, 72, -147, -303, -282, -575, +-295, -661, -176, -547, -19, -306, 117, -17, +217, 246, 236, 400, 146, 411, 26, 315, +-47, 154, -80, -4, -101, -110, -96, -166, +-86, -184, -102, -147, -121, -69, -107, 7, +-63, 58, -4, 83, 57, 72, 104, 25, +140, -29, 164, -70, 165, -79, 140, -66, +62, -31, -81, 41, -217, 128, -297, 168, +-327, 151, -290, 100, -155, -3, 23, -135, +160, -213, 262, -198, 325, -138, 295, -61, +168, 19, 12, 84, -150, 125, -286, 146, +-322, 141, -241, 110, -108, 57, 14, -7, +95, -70, 111, -132, 84, -174, 40, -165, +-16, -96, -61, -12, -56, 42, -22, 77, +15, 123, 66, 157, 90, 137, 38, 83, +-30, 31, -59, -25, -98, -88, -143, -132, +-135, -169, -75, -204, -25, -191, -4, -100, +9, 26, 43, 160, 110, 299, 153, 395, +127, 382, 56, 230, -22, -25, -96, -308, +-151, -521, -179, -598, -168, -514, -111, -270, +-19, 90, 51, 446, 107, 685, 175, 729, +180, 542, 77, 181, -54, -213, -122, -520, +-137, -677, -113, -634, -54, -406, 19, -77, +74, 243, 80, 455, 19, 504, -45, 403, +-55, 197, -60, -45, -91, -221, -92, -263, +-13, -193, 96, -66, 170, 64, 183, 111, +141, 60, 51, -20, -80, -85, -212, -119, +-290, -84, -273, 0, -175, 43, -36, 19, +110, -15, 239, -7, 308, 40, 293, 126, +183, 227, 11, 300, -139, 286, -200, 137, +-201, -126, -197, -403, -171, -588, -107, -626, +-43, -483, -22, -171, -2, 229, 67, 578, +164, 752, 238, 702, 278, 479, 288, 163, +226, -167, 51, -402, -200, -482, -439, -455, +-604, -401, -601, -325, -380, -226, -29, -105, +293, 58, 516, 260, 613, 453, 544, 593, +325, 618, 55, 457, -197, 147, -417, -193, +-523, -466, -467, -598, -324, -537, -167, -335, +33, -97, 249, 92, 351, 157, 300, 84, +201, -7, 101, 0, -40, 88, -164, 239, +-175, 446, -96, 580, -19, 490, 42, 197, +82, -190, 58, -573, -36, -847, -136, -900, +-198, -688, -235, -258, -243, 249, -182, 639, +-5, 811, 254, 774, 502, 567, 640, 225, +568, -121, 243, -333, -229, -410, -658, -428, +-906, -400, -887, -305, -537, -172, 26, -35, +523, 109, 802, 252, 853, 340, 670, 321, +281, 182, -163, -6, -520, -148, -728, -184, +-729, -114, -501, 23, -119, 175, 264, 258, +515, 198, 576, -25, 454, -316, 191, -506, +-93, -487, -248, -307, -259, -22, -250, 330, +-238, 608, -123, 634, 45, 421, 111, 121, +89, -187, 113, -447, 139, -573, 51, -476, +-66, -189, -63, 125, 22, 315, 65, 380, +69, 363, 103, 215, 116, -50, 7, -256, +-193, -298, -339, -247, -354, -163, -292, -65, +-152, 17, 125, 82, 441, 166, 602, 259, +553, 339, 356, 380, 57, 293, -268, 44, +-506, -277, -592, -570, -525, -754, -347, -709, +-125, -402, 109, 56, 330, 509, 481, 825, +516, 889, 444, 690, 276, 330, 22, -78, +-247, -443, -435, -671, -474, -707, -352, -594, +-151, -386, 4, -126, 106, 147, 159, 386, +113, 541, 17, 587, 12, 519, 92, 341, +140, 73, 164, -218, 187, -436, 140, -519, +4, -469, -117, -324, -200, -115, -299, 111, +-390, 257, -363, 272, -185, 192, 45, 89, +236, 42, 398, 89, 511, 190, 441, 267, +180, 253, -103, 66, -284, -284, -365, -618, +-350, -743, -258, -612, -143, -251, -24, 247, +79, 678, 130, 859, 152, 742, 206, 397, +237, -17, 171, -317, 26, -469, -109, -528, +-201, -480, -242, -319, -192, -150, -46, -24, +112, 119, 168, 284, 130, 403, 58, 431, +-31, 362, -112, 210, -117, 34, -67, -136, +-15, -292, 44, -400, 125, -418, 181, -356, +185, -218, 144, -15, 17, 189, -191, 340, +-381, 412, -446, 377, -329, 236, -27, 62, +344, -76, 597, -150, 626, -172, 417, -190, +35, -231, -347, -264, -555, -247, -579, -169, +-460, -3, -209, 232, 104, 435, 353, 502, +506, 402, 563, 161, 457, -128, 192, -344, +-129, -420, -416, -365, -582, -221, -526, -46, +-273, 75, 27, 114, 267, 130, 414, 181, +426, 235, 295, 237, 82, 171, -133, 59, +-271, -92, -296, -267, -221, -386, -63, -354, +137, -173, 270, 50, 258, 230, 145, 330, +-19, 322, -193, 187, -279, -9, -225, -160, +-86, -204, 68, -148, 194, -40, 234, 60, +171, 99, 63, 55, -33, -53, -96, -144, +-115, -144, -85, -54, -8, 65, 79, 176, +95, 239, 10, 194, -93, 46, -138, -106, +-134, -184, -83, -201, 46, -156, 199, -45, +265, 85, 200, 157, 67, 144, -63, 61, +-143, -34, -159, -98, -123, -127, -67, -111, +-19, -22, 20, 112, 56, 195, 97, 183, +123, 100, 103, -21, 2, -158, -124, -261, +-172, -283, -105, -204, 36, -44, 187, 148, +285, 306, 244, 369, 69, 306, -141, 128, +-278, -90, -325, -271, -283, -360, -144, -330, +81, -187, 296, 8, 393, 168, 348, 245, +188, 227, -38, 130, -260, 7, -364, -77, +-302, -93, -100, -48, 165, 21, 372, 86, +383, 115, 203, 72, -39, -49, -263, -197, +-427, -298, -458, -316, -290, -242, -6, -76, +273, 167, 484, 407, 612, 546, 598, 539, +402, 400, 46, 128, -357, -243, -667, -568, +-811, -721, -747, -685, -457, -477, -6, -136, +438, 230, 756, 523, 880, 681, 771, 645, +468, 432, 96, 166, -269, -84, -577, -310, +-720, -434, -642, -416, -419, -326, -161, -203, +86, -34, 267, 85, 352, 65, 359, -5, +319, -2, 299, 68, 332, 183, 320, 342, +173, 474, -50, 466, -294, 277, -543, -46, +-711, -421, -691, -707, -473, -787, -96, -624, +355, -279, 716, 141, 883, 503, 861, 674, +611, 628, 136, 453, -347, 233, -643, -12, +-758, -217, -698, -315, -431, -339, -68, -362, +224, -363, 414, -293, 503, -123, 444, 119, +274, 347, 87, 477, -79, 472, -176, 319, +-156, 38, -80, -243, -34, -399, -36, -399, +-73, -259, -130, -15, -153, 217, -85, 330, +66, 284, 245, 113, 351, -80, 299, -218, +116, -289, -102, -260, -288, -111, -361, 47, +-264, 138, -39, 225, 223, 314, 428, 328, +469, 257, 299, 94, -3, -185, -328, -477, +-556, -635, -554, -604, -307, -343, 60, 138, +400, 612, 593, 840, 539, 775, 288, 448, +-6, -67, -253, -530, -377, -737, -312, -694, +-160, -449, -62, -62, 47, 298, 210, 494, +300, 522, 241, 368, 105, 65, -70, -216, +-231, -377, -305, -417, -265, -268, -96, 67, +177, 396, 421, 574, 498, 548, 436, 269, +269, -195, -13, -639, -328, -915, -554, -927, +-671, -586, -629, 30, -361, 665, 70, 1102, +540, 1216, 919, 957, 1045, 436, 787, -164, +249, -705, -330, -1068, -731, -1143, -875, -937, +-788, -543, -515, -52, -123, 448, 244, 851, +493, 1044, 660, 947, 712, 580, 577, 117, +286, -259, -74, -480, -447, -554, -655, -494, +-575, -367, -334, -279, -67, -251, 215, -191, +424, -30, 436, 200, 308, 433, 138, 581, +-39, 577, -201, 423, -300, 179, -279, -118, +-77, -378, 211, -462, 365, -384, 322, -282, +150, -172, -106, -25, -333, 60, -341, 71, +-143, 112, 101, 176, 275, 220, 292, 286, +130, 286, -76, 107, -176, -129, -145, -279, +-23, -357, 100, -312, 146, -85, 143, 161, +129, 306, 66, 356, -28, 244, -105, -45, +-171, -299, -186, -392, -92, -360, 55, -203, +183, 37, 274, 256, 268, 417, 121, 458, +-65, 285, -198, 27, -254, -133, -202, -225, +-69, -292, 54, -253, 175, -159, 317, -92, +358, 5, 229, 125, 39, 197, -125, 234, +-268, 221, -328, 78, -271, -139, -141, -311, +14, -374, 146, -250, 200, 68, 203, 392, +232, 561, 271, 554, 253, 329, 162, -82, +44, -487, -86, -729, -248, -752, -415, -520, +-463, -156, -327, 188, -86, 494, 170, 713, +410, 725, 548, 568, 487, 320, 276, -43, +35, -421, -170, -657, -279, -751, -248, -707, +-133, -424, -20, 34, 73, 460, 115, 711, +80, 703, 21, 458, -28, 154, -102, -114, +-178, -392, -162, -577, -42, -512, 153, -250, +379, 35, 521, 277, 479, 467, 324, 540, +98, 405, -230, 66, -537, -339, -652, -637, +-573, -692, -368, -467, -53, -43, 245, 393, +424, 678, 512, 716, 513, 473, 391, 36, +259, -383, 192, -611, 91, -572, -68, -287, +-239, 76, -427, 350, -591, 465, -587, 382, +-435, 79, -171, -276, 226, -457, 619, -406, +796, -199, 771, 56, 610, 270, 256, 411, +-191, 442, -520, 275, -650, -18, -606, -216, +-361, -280, -10, -301, 303, -230, 448, -45, +373, 108, 174, 133, 6, 56, -116, -93, +-224, -217, -181, -162, 25, 60, 223, 332, +312, 538, 315, 563, 210, 335, 14, -73, +-181, -521, -314, -847, -332, -873, -193, -564, +25, -60, 173, 481, 207, 924, 141, 1102, +44, 909, -12, 367, -33, -370, -32, -1046, +41, -1378, 172, -1237, 268, -660, 313, 231, +308, 1153, 194, 1713, -55, 1647, -402, 968, +-729, -115, -809, -1231, -512, -1951, 0, -1981, +530, -1291, 962, -92, 1111, 1195, 838, 2050, +269, 2128, -344, 1416, -791, 204, -898, -1035, +-666, -1835, -254, -1956, 190, -1389, 533, -331, +631, 803, 482, 1551, 195, 1674, -149, 1210, +-420, 378, -445, -508, -218, -1164, 95, -1412, +389, -1169, 596, -484, 587, 338, 262, 966, +-226, 1230, -617, 1068, -760, 505, -622, -247, +-212, -894, 352, -1203, 795, -999, 914, -325, +696, 500, 256, 1118, -258, 1298, -692, 881, +-886, -14, -713, -955, -251, -1533, 227, -1536, +589, -890, 867, 209, 917, 1269, 564, 1873, +27, 1815, -415, 1093, -740, -46, -857, -1180, +-601, -1918, -121, -1978, 279, -1321, 515, -245, +585, 815, 468, 1540, 255, 1723, 35, 1291, +-147, 444, -200, -469, -102, -1104, -7, -1236, +45, -888, 89, -277, 57, 390, -101, 891, +-280, 985, -377, 607, -329, -61, -72, -731, +302, -1130, 628, -1057, 771, -505, 678, 335, +359, 1122, -87, 1491, -541, 1256, -830, 528, +-798, -415, -488, -1228, -56, -1559, 386, -1284, +732, -555, 804, 360, 574, 1140, 163, 1443, +-243, 1162, -506, 466, -535, -384, -345, -1092, +1, -1351, 372, -1069, 555, -397, 470, 441, +179, 1151, -200, 1421, -517, 1149, -578, 486, +-359, -363, 42, -1133, 471, -1491, 723, -1277, +670, -613, 389, 259, 5, 1046, -402, 1405, +-660, 1161, -672, 450, -469, -400, -127, -1030, +283, -1137, 637, -683, 831, 81, 786, 801, +464, 1174, -8, 992, -438, 300, -734, -550, +-803, -1192, -552, -1437, -151, -1185, 169, -456, +397, 467, 565, 1223, 610, 1582, 539, 1467, +386, 917, 116, 127, -189, -643, -375, -1207, +-429, -1435, -403, -1277, -293, -807, -156, -178, +-77, 483, 3, 988, 169, 1167, 392, 1005, +594, 586, 691, 34, 564, -435, 206, -631, +-234, -547, -603, -264, -793, 65, -736, 220, +-442, 92, -19, -191, 445, -469, 820, -604, +931, -458, 709, -35, 259, 512, -270, 1011, +-705, 1252, -841, 1044, -633, 446, -220, -331, +223, -1085, 557, -1549, 666, -1465, 586, -898, +417, -107, 149, 709, -203, 1312, -492, 1461, +-602, 1157, -494, 551, -162, -197, 214, -821, +410, -1136, 413, -1149, 295, -861, 92, -264, +-57, 388, -50, 815, 29, 984, 102, 900, +138, 526, 86, -3, -18, -471, -79, -783, +-145, -849, -252, -639, -318, -271, -290, 143, +-94, 532, 310, 737, 671, 655, 710, 369, +513, 18, 215, -274, -192, -414, -527, -399, +-578, -290, -417, -121, -191, 19, 61, 51, +251, 54, 361, 124, 421, 166, 348, 116, +121, 61, -122, 49, -299, 36, -360, 12, +-178, 17, 136, 33, 361, 25, 453, -37, +387, -150, 97, -252, -217, -244, -369, -132, +-450, -11, -434, 112, -183, 254, 188, 318, +480, 249, 680, 153, 659, 51, 349, -105, +-83, -219, -441, -192, -623, -140, -525, -128, +-216, -79, 91, -29, 325, -29, 451, -8, +425, 48, 306, 84, 202, 169, 47, 282, +-168, 265, -349, 149, -418, 77, -354, -25, +-153, -238, 128, -451, 357, -578, 436, -554, +365, -287, 292, 152, 243, 548, 114, 824, +-88, 918, -238, 698, -348, 186, -414, -407, +-354, -884, -208, -1095, -27, -964, 219, -556, +451, 16, 534, 622, 511, 1051, 395, 1130, +161, 868, -69, 332, -224, -317, -348, -814, +-374, -995, -281, -855, -245, -456, -234, 32, +-74, 390, 157, 559, 353, 565, 560, 395, +651, 117, 462, -102, 150, -201, -110, -208, +-301, -129, -360, -1, -282, 109, -197, 136, +-152, 23, -135, -199, -140, -384, -27, -451, +224, -352, 412, -39, 470, 403, 476, 753, +363, 867, 123, 696, -93, 232, -262, -397, +-395, -938, -403, -1170, -305, -976, -202, -402, +-30, 280, 199, 828, 353, 1129, 413, 1059, +401, 568, 291, -103, 145, -634, 4, -891, +-187, -854, -310, -574, -256, -172, -153, 249, +-86, 623, 21, 796, 124, 659, 160, 319, +194, -58, 222, -421, 191, -705, 131, -748, +42, -482, -83, -19, -140, 463, -121, 800, +-120, 794, -114, 399, -42, -158, 69, -610, +206, -857, 349, -765, 427, -253, 402, 436, +194, 926, -254, 1025, -688, 671, -772, -68, +-522, -794, -116, -1137, 383, -1078, 823, -636, +1007, 194, 863, 1033, 425, 1384, -185, 1173, +-706, 556, -952, -299, -910, -1050, -571, -1357, +-35, -1184, 494, -596, 859, 265, 963, 1004, +685, 1288, 147, 1124, -318, 569, -539, -257, +-520, -965, -285, -1237, 64, -1069, 322, -523, +409, 291, 310, 1037, 46, 1378, -288, 1187, +-491, 500, -466, -455, -265, -1270, 50, -1617, +474, -1365, 902, -561, 1049, 523, 774, 1470, +196, 1880, -480, 1551, -1065, 620, -1288, -523, +-1038, -1505, -447, -1951, 277, -1592, 915, -589, +1255, 572, 1194, 1468, 765, 1767, 75, 1305, +-574, 336, -880, -709, -794, -1474, -458, -1593, +4, -934, 403, 89, 530, 1014, 364, 1608, +49, 1563, -247, 776, -377, -329, -262, -1302, +17, -1893, 328, -1771, 571, -900, 649, 273, +499, 1339, 153, 2029, -286, 1967, -691, 1110, +-873, -67, -680, -1131, -191, -1807, 342, -1806, +739, -1123, 902, -105, 708, 898, 207, 1509, +-287, 1448, -560, 812, -631, -101, -457, -995, +-37, -1449, 369, -1198, 584, -445, 664, 474, +564, 1302, 191, 1705, -257, 1422, -578, 536, +-779, -628, -811, -1607, -537, -2006, -3, -1778, +643, -1049, 1167, 91, 1261, 1325, 915, 2100, +396, 2118, -198, 1485, -836, 479, -1195, -608, +-1065, -1478, -654, -1838, -195, -1553, 283, -848, +700, -94, 925, 554, 938, 1005, 755, 1091, +400, 859, -57, 539, -492, 184, -754, -185, +-755, -453, -574, -588, -290, -603, 105, -487, +486, -337, 655, -185, 635, 84, 539, 418, +314, 662, -57, 815, -400, 821, -580, 484, +-583, -125, -381, -788, -3, -1372, 413, -1590, +687, -1167, 682, -282, 421, 723, 52, 1639, +-299, 2124, -502, 1863, -458, 965, -256, -227, +-62, -1372, 168, -2085, 418, -2138, 457, -1574, +266, -556, 82, 581, -84, 1378, -281, 1630, +-300, 1433, -70, 902, 201, 231, 405, -298, +514, -561, 365, -596, 0, -484, -340, -379, +-560, -368, -654, -411, -525, -483, -182, -516, +269, -336, 762, 106, 1092, 666, 1057, 1183, +656, 1452, 21, 1293, -698, 689, -1184, -234, +-1207, -1214, -823, -1834, -161, -1808, 611, -1223, +1141, -300, 1175, 724, 815, 1451, 238, 1569, +-368, 1158, -784, 470, -849, -277, -584, -860, +-71, -1039, 509, -755, 908, -217, 929, 315, +530, 677, -118, 709, -751, 316, -1133, -308, +-1090, -834, -516, -1049, 360, -817, 1111, -96, +1463, 807, 1316, 1439, 679, 1586, -148, 1168, +-789, 210, -1179, -927, -1271, -1768, -907, -2043, +-214, -1612, 457, -556, 948, 686, 1157, 1660, +969, 2125, 478, 1892, -103, 956, -596, -297, +-768, -1370, -476, -1897, 29, -1710, 413, -964, +569, 4, 437, 918, -19, 1442, -579, 1277, +-936, 579, -915, -201, -419, -784, 470, -1011, +1371, -729, 1851, -56, 1692, 632, 890, 1016, +-347, 936, -1551, 404, -2239, -370, -2163, -1061, +-1345, -1346, -46, -1100, 1231, -467, 2061, 334, +2326, 1085, 1984, 1503, 985, 1384, -402, 783, +-1598, -105, -2191, -976, -2039, -1480, -1156, -1482, +143, -1032, 1286, -154, 1864, 898, 1726, 1577, +921, 1584, -148, 1001, -920, 4, -1150, -1054, +-942, -1691, -434, -1697, 169, -1110, 635, -44, +897, 1102, 951, 1803, 640, 1875, -36, 1357, +-697, 337, -989, -792, -877, -1560, -460, -1830, +156, -1594, 727, -844, 968, 131, 819, 906, +422, 1335, -48, 1423, -410, 1094, -535, 430, +-470, -266, -289, -751, 22, -933, 384, -810, +597, -439, 531, 52, 164, 439, -352, 537, +-658, 316, -542, -106, -161, -494, 278, -648, +665, -507, 769, -91, 492, 489, 117, 965, +-148, 1096, -354, 869, -465, 349, -383, -398, +-229, -1090, -52, -1358, 228, -1164, 505, -651, +547, 57, 351, 719, 20, 1076, -339, 1038, +-496, 624, -327, 6, 5, -473, 309, -639, +556, -580, 641, -294, 451, 240, 100, 695, +-205, 730, -454, 408, -682, -101, -754, -728, +-512, -1250, 17, -1333, 592, -882, 963, -56, +1007, 905, 748, 1680, 270, 1929, -219, 1535, +-530, 661, -617, -416, -522, -1398, -315, -2004, +-83, -2019, 85, -1386, 199, -306, 292, 807, +329, 1563, 234, 1789, 62, 1465, -10, 675, +115, -295, 320, -1063, 422, -1369, 377, -1114, +180, -399, -187, 427, -581, 994, -768, 1150, +-713, 845, -474, 85, -55, -884, 461, -1631, +871, -1806, 1054, -1240, 985, -98, 665, 1132, +177, 2066, -375, 2504, -853, 2179, -1038, 994, +-835, -573, -418, -1872, 70, -2619, 576, -2697, +864, -2004, 753, -743, 402, 637, 19, 1721, +-311, 2242, -420, 2133, -204, 1533, 156, 693, +453, -126, 572, -737, 408, -1096, 31, -1248, +-357, -1207, -664, -1016, -784, -782, -596, -489, +-222, -48, 172, 459, 597, 863, 974, 1106, +1107, 1242, 983, 1247, 644, 978, 43, 445, +-664, -191, -1114, -862, -1214, -1485, -1047, -1814, +-612, -1677, 29, -1145, 674, -359, 1126, 573, +1288, 1394, 1146, 1813, 753, 1771, 162, 1314, +-495, 542, -975, -299, -1117, -998, -910, -1415, +-434, -1427, 138, -1082, 615, -555, 884, 31, +886, 563, 627, 866, 217, 884, -209, 724, +-554, 414, -684, -27, -560, -404, -272, -597, +162, -628, 661, -454, 919, -100, 786, 252, +457, 503, 70, 648, -375, 619, -748, 340, +-898, -123, -813, -622, -490, -997, 49, -1087, +618, -844, 1067, -341, 1295, 331, 1127, 991, +610, 1348, -4, 1276, -601, 906, -1104, 363, +-1239, -306, -926, -940, -445, -1310, 58, -1324, +638, -1065, 1091, -591, 1143, 82, 903, 755, +550, 1142, 29, 1171, -563, 921, -879, 476, +-810, -47, -535, -485, -172, -704, 273, -692, +678, -532, 864, -323, 744, -121, 348, 94, +-163, 261, -586, 260, -785, 168, -693, 125, +-296, 101, 258, 64, 763, 32, 1032, -24, +923, -115, 499, -153, 2, -84, -397, 0, +-699, 103, -852, 259, -747, 258, -421, 8, +13, -271, 490, -438, 886, -492, 1038, -402, +862, -159, 445, 165, -45, 465, -457, 635, +-672, 594, -670, 401, -541, 149, -357, -230, +-42, -639, 404, -793, 796, -685, 977, -423, +903, 20, 533, 524, -86, 837, -694, 837, +-1076, 532, -1163, -11, -876, -586, -256, -966, +460, -1078, 1108, -814, 1592, -108, 1711, 716, +1353, 1304, 564, 1534, -528, 1228, -1569, 391, +-2157, -623, -2210, -1500, -1757, -2005, -721, -1900, +752, -1164, 2122, -65, 2961, 1101, 3092, 2060, +2378, 2451, 951, 2104, -777, 1152, -2369, -203, +-3356, -1593, -3352, -2547, -2376, -2817, -788, -2269, +1006, -962, 2535, 600, 3342, 1914, 3237, 2751, +2286, 2829, 708, 2015, -995, 617, -2206, -930, +-2652, -2222, -2365, -2787, -1424, -2478, -75, -1564, +1102, -240, 1651, 1216, 1637, 2151, 1269, 2270, +594, 1849, -167, 996, -597, -187, -584, -1175, +-357, -1638, -27, -1638, 315, -1228, 421, -543, +194, 155, -218, 718, -636, 984, -899, 837, +-741, 523, -76, 295, 806, 55, 1544, -183, +1838, -160, 1501, 5, 559, -3, -713, -117, +-1844, -292, -2405, -629, -2178, -943, -1190, -964, +304, -604, 1840, 80, 2899, 857, 3108, 1517, +2367, 1871, 850, 1651, -1027, 798, -2614, -333, +-3346, -1341, -3082, -2068, -1966, -2346, -193, -1958, +1751, -1021, 3099, 202, 3435, 1474, 2880, 2330, +1561, 2484, -262, 2052, -1866, 1059, -2630, -326, +-2572, -1553, -1883, -2220, -686, -2283, 588, -1760, +1471, -752, 1797, 379, 1599, 1264, 1012, 1766, +320, 1771, -246, 1251, -646, 397, -780, -565, +-583, -1275, -253, -1460, 9, -1231, 209, -675, +365, 163, 413, 922, 349, 1286, 270, 1255, +131, 866, -189, 108, -534, -785, -640, -1437, +-542, -1693, -327, -1456, 157, -699, 850, 322, +1370, 1349, 1482, 2090, 1218, 2134, 552, 1502, +-402, 519, -1289, -675, -1885, -1827, -2019, -2469, +-1484, -2376, -396, -1668, 836, -474, 1890, 974, +2462, 2141, 2280, 2608, 1437, 2313, 180, 1319, +-1201, -65, -2152, -1408, -2228, -2353, -1544, -2494, +-443, -1716, 861, -448, 1951, 841, 2246, 1877, +1651, 2299, 502, 1855, -870, 709, -2044, -689, +-2444, -1883, -1788, -2435, -380, -2115, 1234, -1067, +2593, 401, 3204, 1850, 2666, 2689, 1155, 2602, +-712, 1710, -2394, 241, -3385, -1388, -3260, -2582, +-2046, -2969, -246, -2486, 1599, -1270, 2978, 316, +3415, 1759, 2786, 2604, 1319, 2635, -451, 1937, +-1803, 756, -2359, -534, -2223, -1553, -1498, -2056, +-249, -1957, 1039, -1368, 1770, -503, 1803, 400, +1249, 1023, 289, 1233, -703, 1148, -1309, 820, +-1369, 312, -945, -203, -101, -550, 933, -706, +1670, -760, 1724, -610, 1175, -186, 411, 216, +-407, 433, -1236, 601, -1750, 633, -1615, 331, +-902, -151, 54, -484, 893, -657, 1423, -756, +1574, -596, 1232, -176, 511, 209, -189, 539, +-641, 859, -855, 1007, -725, 869, -249, 430, +160, -177, 326, -769, 472, -1253, 512, -1498, +238, -1287, -145, -582, -390, 291, -520, 996, +-499, 1489, -242, 1596, 151, 1113, 595, 323, +1000, -419, 1143, -1013, 934, -1345, 489, -1245, +-36, -730, -554, -81, -973, 440, -1188, 787, +-1109, 915, -726, 743, -194, 279, 370, -296, +888, -690, 1184, -812, 1229, -708, 1156, -371, +884, 162, 363, 765, -153, 1161, -530, 1091, +-855, 696, -1120, 176, -1205, -563, -1052, -1405, +-686, -1909, -96, -1823, 678, -1280, 1444, -368, +1900, 891, 1833, 2120, 1390, 2795, 673, 2726, +-370, 1930, -1367, 537, -1798, -1169, -1729, -2754, +-1453, -3667, -840, -3578, 163, -2587, 1162, -923, +1768, 1127, 1880, 3011, 1583, 4133, 991, 4183, +183, 3180, -658, 1324, -1226, -1009, -1374, -3164, +-1224, -4456, -883, -4549, -384, -3500, 163, -1541, +649, 875, 1025, 3010, 1249, 4204, 1315, 4282, +1192, 3327, 806, 1504, 263, -637, -359, -2432, +-1150, -3527, -1900, -3739, -2147, -3024, -1753, -1651, +-900, 28, 341, 1600, 1806, 2623, 2964, 2951, +3392, 2691, 2914, 1878, 1533, 610, -382, -721, +-2298, -1755, -3709, -2419, -4159, -2604, -3387, -2187, +-1579, -1322, 778, -137, 3073, 1148, 4593, 2080, +4786, 2490, 3619, 2417, 1482, 1694, -1065, 413, +-3342, -890, -4638, -1850, -4557, -2425, -3174, -2429, +-947, -1675, 1526, -504, 3631, 655, 4737, 1619, +4438, 2102, 2825, 1918, 424, 1269, -2005, 402, +-3679, -496, -4180, -1174, -3472, -1436, -1717, -1317, +469, -1008, 2300, -531, 3385, 80, 3615, 556, +2852, 701, 1203, 674, -670, 698, -2118, 674, +-2883, 438, -2831, 167, -1986, 23, -580, -204, +979, -636, 2153, -1033, 2572, -1140, 2279, -1031, +1497, -787, 364, -231, -844, 627, -1687, 1421, +-1952, 1854, -1706, 1820, -1014, 1293, 18, 358, +1041, -777, 1690, -1820, 1852, -2456, 1578, -2339, +888, -1491, -122, -351, -1086, 799, -1651, 1802, +-1736, 2311, -1352, 2105, -517, 1318, 574, 297, +1567, -589, 2131, -1230, 2042, -1591, 1430, -1503, +509, -951, -654, -343, -1765, -21, -2322, 148, +-2162, 294, -1491, 324, -348, 337, 1159, 496, +2362, 772, 2754, 1089, 2429, 1154, 1501, 734, +106, 74, -1264, -630, -2110, -1518, -2320, -2315, +-1945, -2392, -1068, -1711, 43, -644, 1089, 721, +1859, 2171, 2138, 3121, 1790, 3181, 962, 2269, +-27, 621, -847, -1155, -1260, -2557, -1231, -3386, +-913, -3307, -495, -2131, -43, -408, 418, 1196, +774, 2441, 918, 3049, 873, 2743, 704, 1703, +383, 279, -32, -1155, -410, -2140, -659, -2490, +-683, -2268, -530, -1443, -335, -162, -60, 1010, +397, 1672, 869, 1878, 1051, 1690, 970, 1061, +681, 188, 86, -648, -587, -1220, -981, -1392, +-1023, -1275, -770, -1008, -274, -556, 279, 17, +700, 526, 997, 887, 1101, 1099, 846, 1178, +322, 1024, -194, 562, -624, -68, -875, -620, +-739, -1050, -275, -1386, 262, -1415, 675, -980, +813, -321, 594, 284, 163, 795, -239, 1132, +-533, 1200, -626, 1015, -392, 600, 73, 94, +533, -239, 875, -431, 1031, -688, 811, -905, +256, -897, -310, -755, -714, -639, -901, -480, +-844, -113, -537, 449, -77, 977, 371, 1300, +676, 1370, 786, 1207, 803, 797, 786, 113, +580, -713, 195, -1479, -109, -1951, -262, -1940, +-490, -1516, -814, -807, -916, 172, -663, 1196, +-280, 1965, 157, 2331, 715, 2144, 1180, 1376, +1306, 260, 1139, -866, 783, -1792, 229, -2352, +-429, -2321, -970, -1697, -1335, -729, -1428, 374, +-1081, 1287, -350, 1755, 576, 1859, 1433, 1625, +1864, 981, 1720, 112, 1207, -624, 424, -1054, +-584, -1262, -1362, -1292, -1602, -1024, -1473, -484, +-1058, 60, -250, 308, 737, 330, 1417, 428, +1613, 484, 1424, 330, 952, 305, 332, 579, +-319, 748, -821, 577, -955, 263, -833, -114, +-708, -710, -494, -1381, -89, -1774, 303, -1705, +554, -1130, 760, -248, 908, 711, 839, 1732, +591, 2538, 354, 2574, 135, 1850, -117, 792, +-393, -493, -627, -1961, -776, -3040, -769, -3229, +-491, -2639, -115, -1427, 124, 254, 336, 1903, +684, 3069, 974, 3471, 1008, 2859, 952, 1496, +841, -43, 504, -1499, -14, -2674, -535, -3100, +-993, -2616, -1344, -1619, -1453, -382, -1280, 964, +-849, 1952, -104, 2246, 889, 1999, 1898, 1297, +2625, 251, 2737, -709, 2099, -1205, 875, -1144, +-652, -704, -2124, -235, -3119, 93, -3318, 261, +-2635, 128, -1261, -319, 512, -774, 2307, -942, +3548, -816, 3815, -332, 3057, 588, 1521, 1585, +-366, 2186, -2087, 2285, -3118, 1786, -3221, 560, +-2462, -1123, -1105, -2682, 462, -3509, 1827, -3371, +2614, -2459, 2614, -926, 1888, 1039, 723, 2857, +-511, 3897, -1446, 3897, -1787, 2927, -1499, 1272, +-705, -646, 345, -2363, 1166, -3544, 1437, -3803, +1241, -2966, 682, -1525, -236, -44, -1174, 1295, +-1634, 2226, -1486, 2536, -790, 2303, 378, 1633, +1614, 776, 2356, 53, 2436, -443, 1901, -843, +763, -1192, -810, -1432, -2330, -1586, -3163, -1632, +-3068, -1426, -2204, -949, -666, -143, 1398, 1005, +3345, 2044, 4274, 2582, 3904, 2623, 2565, 2134, +509, 1062, -1849, -344, -3714, -1688, -4422, -2683, +-3865, -3166, -2288, -2950, -52, -2007, 2290, -587, +3990, 989, 4469, 2350, 3698, 3109, 1971, 3001, +-306, 2117, -2381, 893, -3485, -407, -3480, -1669, +-2658, -2378, -1198, -2244, 597, -1681, 2111, -987, +2909, -93, 2959, 791, 2258, 1213, 885, 1198, +-672, 1013, -1851, 611, -2337, 30, -2077, -396, +-1236, -546, -68, -455, 1038, -179, 1674, 158, +1728, 477, 1385, 563, 869, 220, 190, -308, +-584, -691, -1145, -958, -1300, -1116, -1086, -903, +-634, -264, -57, 381, 509, 808, 882, 1126, +1043, 1247, 1111, 1099, 1095, 795, 854, 358, +338, -159, -255, -639, -748, -1108, -1208, -1487, +-1603, -1616, -1555, -1491, -932, -1151, -119, -494, +663, 505, 1528, 1518, 2281, 2253, 2483, 2665, +2075, 2528, 1231, 1640, 9, 299, -1395, -1179, +-2527, -2612, -3084, -3573, -3005, -3635, -2200, -2786, +-753, -1316, 1001, 525, 2704, 2441, 3984, 3853, +4471, 4232, 3800, 3494, 1989, 1896, -377, -99, +-2685, -2074, -4477, -3631, -5212, -4178, -4511, -3492, +-2628, -2008, -163, -240, 2468, 1463, 4676, 2706, +5694, 3170, 5237, 2785, 3535, 1788, 951, 514, +-1907, -680, -4217, -1530, -5383, -2015, -5140, -2109, +-3550, -1729, -1121, -1006, 1420, -150, 3482, 679, +4634, 1293, 4650, 1635, 3622, 1644, 1770, 1252, +-484, 567, -2406, -238, -3462, -1010, -3611, -1571, +-2967, -1802, -1664, -1666, -106, -1128, 1243, -150, +2164, 1057, 2590, 2019, 2566, 2494, 2062, 2377, +1103, 1509, 80, 48, -678, -1547, -1314, -2843, +-1933, -3439, -2116, -3102, -1668, -1909, -1061, -107, +-458, 1901, 461, 3481, 1554, 4034, 2319, 3519, +2566, 2195, 2352, 243, 1657, -1851, 476, -3355, +-933, -3933, -2152, -3624, -2906, -2526, -3054, -894, +-2430, 843, -1081, 2231, 562, 3050, 2050, 3223, +3185, 2742, 3670, 1740, 3216, 464, 2000, -773, +372, -1718, -1416, -2327, -2923, -2533, -3614, -2260, +-3418, -1668, -2507, -918, -942, -75, 927, 803, +2497, 1598, 3392, 2133, 3524, 2304, 2902, 2115, +1607, 1581, -29, 767, -1515, -251, -2483, -1322, +-2844, -2148, -2615, -2581, -1725, -2584, -438, -2116, +681, -1230, 1495, -73, 2105, 1135, 2283, 2105, +1854, 2686, 1125, 2791, 398, 2334, -361, 1350, +-1102, 48, -1559, -1220, -1598, -2194, -1288, -2737, +-728, -2713, -75, -2122, 560, -1149, 1084, 40, +1375, 1195, 1411, 2053, 1215, 2480, 780, 2361, +135, 1684, -585, 647, -1206, -517, -1559, -1595, +-1487, -2274, -938, -2276, -28, -1638, 924, -638, +1601, 537, 1933, 1627, 1848, 2182, 1232, 1991, +204, 1150, -898, -101, -1783, -1371, -2273, -2267, +-2117, -2531, -1303, -1979, -173, -707, 981, 865, +1996, 2235, 2607, 3049, 2558, 3113, 1846, 2330, +746, 803, -430, -1072, -1494, -2740, -2257, -3763, +-2486, -3945, -2096, -3188, -1249, -1468, -242, 696, +726, 2569, 1564, 3823, 2175, 4263, 2372, 3603, +2015, 1992, 1319, 45, 559, -1720, -274, -2987, +-1124, -3498, -1713, -3166, -1901, -2193, -1833, -918, +-1601, 258, -1083, 1065, -220, 1533, 763, 1707, +1541, 1615, 2104, 1482, 2525, 1410, 2494, 1209, +1800, 794, 789, 194, -211, -645, -1341, -1652, +-2525, -2519, -3205, -3016, -3071, -2974, -2247, -2171, +-939, -689, 624, 1048, 2198, 2683, 3445, 3883, +3927, 4252, 3509, 3618, 2374, 2047, 670, -137, +-1333, -2309, -3045, -3911, -3975, -4671, -4027, -4371, +-3147, -2898, -1341, -673, 861, 1541, 2709, 3244, +3784, 4154, 3966, 3987, 3300, 2820, 1895, 1081, +30, -731, -1767, -2153, -2998, -2939, -3458, -3024, +-3082, -2390, -1870, -1271, -223, -109, 1291, 850, +2393, 1547, 2910, 1864, 2643, 1689, 1721, 1214, +600, 665, -422, 77, -1316, -440, -1938, -760, +-2011, -962, -1484, -1081, -717, -1036, -37, -828, +654, -497, 1327, -117, 1551, 272, 1237, 661, +829, 981, 524, 1104, 137, 1002, -295, 770, +-528, 459, -581, 27, -595, -508, -573, -1023, +-522, -1386, -415, -1481, -237, -1319, -69, -951, +170, -314, 556, 537, 915, 1333, 1094, 1889, +1136, 2080, 1021, 1809, 632, 1128, 64, 156, +-514, -966, -1069, -1952, -1464, -2452, -1502, -2379, +-1220, -1827, -749, -874, -65, 303, 758, 1334, +1431, 1975, 1788, 2185, 1851, 1966, 1603, 1399, +999, 601, 143, -285, -693, -1021, -1327, -1476, +-1724, -1695, -1785, -1618, -1419, -1206, -762, -657, +-51, -137, 602, 371, 1163, 788, 1525, 975, +1581, 1041, 1347, 1106, 886, 1035, 371, 747, +-38, 408, -378, 89, -724, -333, -1056, -908, +-1248, -1433, -1195, -1646, -950, -1514, -573, -1159, +-11, -608, 715, 160, 1302, 986, 1516, 1601, +1527, 1859, 1412, 1777, 960, 1450, 231, 928, +-455, 126, -1041, -864, -1548, -1661, -1692, -2096, +-1317, -2240, -688, -1956, -22, -1076, 666, 103, +1201, 1124, 1349, 1831, 1194, 2174, 929, 1976, +568, 1270, 151, 385, -195, -401, -449, -949, +-594, -1216, -575, -1222, -491, -1014, -460, -691, +-429, -421, -331, -285, -213, -201, -51, -8, +282, 323, 721, 717, 1114, 1126, 1385, 1438, +1371, 1484, 954, 1128, 216, 346, -660, -692, +-1461, -1683, -1956, -2365, -1977, -2512, -1508, -1985, +-591, -839, 616, 632, 1748, 2001, 2462, 2889, +2578, 2997, 2088, 2227, 1137, 852, -100, -683, +-1410, -2027, -2420, -2849, -2800, -2919, -2505, -2198, +-1625, -899, -259, 527, 1262, 1647, 2419, 2294, +2918, 2394, 2771, 1845, 2031, 778, 808, -331, +-545, -1088, -1621, -1484, -2284, -1521, -2516, -1112, +-2155, -432, -1239, 124, -155, 355, 817, 322, +1652, 140, 2084, -96, 1829, -221, 1272, -53, +840, 363, 374, 842, -204, 1217, -627, 1307, +-849, 941, -1078, 172, -1265, -771, -1176, -1657, +-824, -2213, -402, -2175, 2, -1547, 463, -572, +1008, 553, 1442, 1600, 1593, 2246, 1524, 2292, +1212, 1816, 532, 1014, -351, 64, -1076, -859, +-1504, -1514, -1640, -1726, -1418, -1588, -906, -1258, +-293, -752, 302, -143, 784, 350, 1087, 641, +1225, 806, 1173, 856, 862, 791, 388, 729, +37, 679, -99, 513, -210, 247, -350, -56, +-369, -437, -302, -848, -410, -1103, -650, -1116, +-727, -924, -635, -590, -491, -158, -215, 281, +236, 571, 749, 645, 1218, 620, 1564, 610, +1679, 584, 1492, 566, 971, 612, 109, 596, +-865, 353, -1639, -115, -2175, -711, -2416, -1280, +-2096, -1664, -1216, -1761, -122, -1453, 989, -683, +2079, 318, 2873, 1163, 2972, 1733, 2352, 2037, +1318, 1870, 85, 1199, -1210, 375, -2245, -359, +-2640, -924, -2365, -1208, -1655, -1231, -721, -1096, +282, -849, 1137, -600, 1551, -490, 1473, -446, +1162, -285, 824, 39, 433, 484, 64, 1057, +-20, 1630, 112, 1966, 133, 1940, 62, 1461, +5, 516, -260, -679, -800, -1800, -1291, -2603, +-1513, -2900, -1468, -2587, -1044, -1714, -187, -529, +873, 671, 1867, 1706, 2566, 2436, 2705, 2710, +2188, 2489, 1173, 1923, -77, 1165, -1257, 238, +-2107, -804, -2503, -1758, -2464, -2456, -1999, -2838, +-1110, -2851, -32, -2370, 872, -1314, 1523, 97, +2053, 1483, 2304, 2657, 2017, 3476, 1401, 3584, +797, 2816, 112, 1480, -790, -39, -1597, -1557, +-1995, -2834, -2043, -3468, -1782, -3267, -1102, -2408, +-113, -1177, 812, 166, 1382, 1345, 1631, 2123, +1621, 2369, 1210, 2142, 504, 1611, -44, 924, +-271, 226, -389, -357, -391, -811, -142, -1147, +111, -1339, 54, -1380, -222, -1272, -574, -1010, +-972, -563, -1224, 52, -1125, 701, -649, 1204, +157, 1431, 1117, 1338, 1852, 967, 2130, 412, +2008, -199, 1468, -720, 482, -979, -584, -870, +-1292, -533, -1634, -134, -1777, 254, -1637, 478, +-1101, 372, -436, 7, 8, -436, 258, -838, +554, -1022, 922, -747, 1222, -60, 1450, 727, +1651, 1418, 1721, 1842, 1418, 1744, 626, 1102, +-471, 150, -1575, -858, -2456, -1703, -2917, -2185, +-2800, -2142, -2049, -1574, -790, -696, 709, 277, +2106, 1187, 3041, 1834, 3303, 2011, 2923, 1730, +2036, 1160, 817, 406, -517, -393, -1697, -975, +-2435, -1257, -2631, -1350, -2454, -1227, -2020, -857, +-1232, -424, -143, -124, 861, 106, 1580, 417, +2168, 771, 2538, 992, 2351, 1022, 1639, 936, +771, 760, -124, 384, -1067, -199, -1823, -738, +-2111, -1048, -1906, -1158, -1398, -1104, -785, -843, +-137, -406, 510, 62, 958, 433, 1068, 732, +1073, 951, 1169, 985, 1151, 867, 912, 666, +632, 302, 313, -207, -184, -653, -735, -945, +-1152, -1116, -1452, -1078, -1573, -732, -1316, -231, +-718, 246, 6, 691, 759, 1011, 1444, 1039, +1833, 821, 1706, 477, 1070, 47, 265, -383, +-392, -711, -831, -871, -1011, -809, -843, -549, +-401, -221, 48, 82, 266, 349, 214, 530, +37, 568, -154, 495, -386, 386, -558, 253, +-433, 90, -37, -104, 402, -317, 823, -517, +1182, -700, 1254, -819, 953, -749, 426, -427, +-195, 86, -729, 688, -1035, 1261, -1200, 1593, +-1219, 1464, -912, 869, -415, -43, -44, -1077, +266, -1916, 688, -2253, 1036, -1954, 1124, -1060, +1082, 168, 1030, 1332, 884, 2126, 516, 2371, +-83, 1964, -714, 965, -1205, -258, -1571, -1244, +-1767, -1797, -1574, -1909, -899, -1547, 14, -779, +866, 131, 1551, 818, 1993, 1082, 2034, 1060, +1586, 880, 800, 498, -36, 18, -765, -266, +-1314, -302, -1577, -293, -1524, -287, -1236, -228, +-778, -192, -208, -199, 369, -172, 875, -126, +1211, -48, 1269, 92, 1057, 226, 695, 282, +286, 237, -93, 98, -379, -74, -552, -167, +-625, -161, -600, -103, -468, 49, -306, 266, +-194, 336, -91, 225, 50, 75, 159, -126, +173, -378, 201, -526, 353, -488, 520, -300, +567, -58, 504, 142, 381, 292, 203, 381, +-74, 342, -421, 215, -704, 136, -811, 102, +-751, 78, -547, 128, -184, 193, 268, 97, +683, -136, 926, -387, 838, -685, 441, -948, +6, -954, -328, -678, -565, -193, -528, 495, +-132, 1208, 322, 1657, 558, 1731, 589, 1375, +439, 567, 46, -465, -512, -1377, -976, -1971, +-1105, -2103, -891, -1693, -481, -854, 98, 166, +833, 1098, 1425, 1694, 1553, 1866, 1260, 1600, +712, 912, -22, 34, -742, -699, -1235, -1128, +-1426, -1225, -1235, -993, -724, -520, -145, 28, +383, 482, 825, 673, 995, 519, 821, 147, +500, -244, 149, -576, -188, -737, -318, -566, +-186, -83, -2, 564, 118, 1150, 186, 1384, +134, 1192, -82, 689, -372, -79, -584, -970, +-594, -1612, -408, -1744, -118, -1432, 229, -830, +544, -40, 655, 759, 562, 1316, 410, 1444, +196, 1149, -47, 673, -137, 203, -91, -237, +-80, -535, -90, -522, -74, -298, -132, -133, +-247, -102, -337, -145, -444, -302, -481, -568, +-279, -776, 47, -784, 285, -501, 508, 76, +810, 759, 944, 1320, 730, 1623, 395, 1562, +152, 1117, -92, 391, -440, -468, -745, -1257, +-854, -1731, -872, -1795, -897, -1570, -760, -1111, +-372, -374, 75, 451, 491, 1038, 983, 1362, +1467, 1536, 1645, 1494, 1445, 1204, 1021, 772, +368, 236, -548, -398, -1461, -1023, -2019, -1535, +-2131, -1843, -1843, -1811, -1141, -1353, -130, -527, +901, 471, 1672, 1351, 2032, 1889, 1936, 1998, +1476, 1622, 819, 793, 69, -199, -646, -975, +-1107, -1364, -1232, -1356, -1169, -951, -1032, -285, +-750, 328, -340, 616, -7, 516, 186, 158, +366, -263, 586, -605, 756, -701, 832, -405, +841, 183, 772, 795, 601, 1290, 317, 1493, +-103, 1180, -585, 419, -946, -506, -1125, -1359, +-1151, -1890, -959, -1864, -569, -1289, -121, -382, +314, 592, 706, 1370, 982, 1725, 1111, 1544, +1089, 897, 866, 48, 491, -653, 108, -1027, +-261, -1054, -610, -675, -848, -14, -960, 529, +-995, 735, -874, 625, -564, 189, -171, -445, +276, -920, 704, -1033, 928, -815, 937, -284, +852, 452, 645, 1103, 317, 1420, 63, 1293, +-81, 757, -266, 42, -480, -641, -619, -1174, +-697, -1346, -732, -1026, -680, -436, -504, 84, +-212, 454, 105, 695, 412, 655, 773, 310, +1098, -38, 1182, -157, 1025, -91, 730, 55, +216, 271, -513, 519, -1113, 560, -1344, 207, +-1293, -373, -1028, -888, -533, -1191, 112, -1165, +719, -737, 1071, 9, 1064, 844, 783, 1473, +353, 1651, -122, 1316, -459, 592, -532, -327, +-370, -1170, -47, -1659, 318, -1663, 529, -1206, +456, -395, 166, 546, -226, 1302, -615, 1642, +-868, 1519, -935, 1025, -793, 300, -348, -493, +324, -1176, 890, -1514, 1181, -1362, 1236, -882, +996, -348, 439, 196, -180, 724, -583, 1030, +-753, 1011, -747, 828, -552, 635, -254, 420, +-57, 141, -65, -187, -186, -556, -304, -918, +-383, -1143, -330, -1164, -40, -978, 433, -532, +954, 148, 1407, 851, 1629, 1366, 1431, 1587, +770, 1438, -243, 922, -1342, 180, -2143, -553, +-2408, -1070, -2181, -1317, -1524, -1291, -429, -955, +811, -436, 1720, 19, 2211, 325, 2401, 554, +2141, 694, 1308, 689, 235, 624, -614, 575, +-1176, 441, -1625, 190, -1884, -76, -1712, -352, +-1213, -650, -747, -831, -350, -806, 247, -629, +980, -330, 1445, 74, 1585, 462, 1619, 714, +1479, 792, 983, 686, 264, 418, -439, 60, +-1073, -293, -1567, -537, -1724, -604, -1518, -475, +-1112, -200, -600, 103, 11, 332, 634, 425, +1109, 341, 1306, 105, 1220, -168, 1002, -360, +748, -416, 397, -338, -14, -139, -257, 111, +-301, 315, -414, 459, -703, 498, -985, 349, +-1110, 71, -1083, -169, -943, -336, -616, -457, +-10, -476, 748, -314, 1383, 2, 1782, 310, +1965, 460, 1809, 474, 1171, 404, 180, 131, +-857, -352, -1731, -738, -2314, -801, -2429, -633, +-1983, -294, -1090, 264, -45, 878, 929, 1242, +1753, 1248, 2248, 946, 2200, 362, 1667, -408, +830, -1173, -158, -1696, -1023, -1766, -1489, -1402, +-1556, -771, -1299, 98, -756, 1111, -130, 1873, +272, 2110, 400, 1914, 415, 1357, 358, 423, +197, -660, -5, -1551, -62, -2087, 147, -2203, +487, -1815, 756, -979, 869, 60, 739, 1036, +280, 1742, -393, 2024, -1047, 1816, -1510, 1165, +-1597, 247, -1207, -633, -503, -1223, 234, -1424, +893, -1217, 1446, -685, 1722, -18, 1497, 537, +798, 743, -10, 583, -648, 253, -1153, -142, +-1429, -555, -1204, -764, -585, -553, 39, -41, +517, 510, 821, 966, 832, 1245, 569, 1200, +211, 731, -158, -71, -499, -894, -664, -1432, +-540, -1607, -223, -1431, 136, -875, 417, -57, +572, 716, 600, 1221, 486, 1390, 287, 1174, +88, 668, -137, 141, -423, -277, -699, -542, +-866, -540, -861, -321, -666, -98, -321, 6, +144, -54, 677, -273, 1105, -513, 1282, -606, +1231, -538, 987, -336, 475, 55, -281, 570, +-1027, 958, -1485, 1076, -1571, 988, -1349, 748, +-837, 352, -61, -127, 698, -548, 1098, -809, +1148, -939, 1049, -1023, 788, -1022, 299, -813, +-181, -421, -357, 15, -290, 492, -221, 1042, +-171, 1474, -78, 1542, -84, 1269, -342, 824, +-690, 206, -829, -591, -715, -1306, -424, -1676, +73, -1668, 695, -1320, 1183, -683, 1348, 73, +1177, 744, 793, 1176, 321, 1286, -195, 1068, +-689, 640, -1018, 219, -1117, -57, -1053, -195, +-880, -227, -604, -186, -262, -166, 76, -252, +411, -444, 739, -671, 992, -837, 1131, -831, +1181, -539, 1131, 16, 852, 634, 252, 1120, +-540, 1398, -1270, 1396, -1782, 1025, -1983, 349, +-1772, -377, -1156, -930, -272, -1272, 654, -1378, +1420, -1153, 1926, -655, 2073, -95, 1776, 390, +1122, 736, 323, 904, -461, 927, -1110, 816, +-1479, 525, -1588, 132, -1536, -204, -1245, -461, +-711, -634, -138, -628, 394, -468, 943, -266, +1376, -42, 1483, 178, 1321, 264, 1045, 173, +625, 49, 38, 9, -524, 17, -909, 30, +-1173, 85, -1315, 215, -1187, 352, -794, 338, +-369, 160, -17, -24, 372, -211, 754, -475, +971, -670, 1061, -612, 1069, -340, 880, -5, +464, 317, -19, 610, -418, 769, -685, 676, +-850, 372, -928, -20, -879, -416, -698, -685, +-448, -684, -171, -463, 159, -187, 491, 111, +703, 388, 796, 495, 850, 428, 867, 325, +770, 193, 503, 5, 92, -155, -391, -263, +-873, -356, -1247, -392, -1381, -344, -1231, -280, +-848, -170, -293, 37, 367, 242, 996, 407, +1423, 593, 1551, 728, 1358, 677, 864, 437, +162, 72, -547, -387, -1022, -881, -1196, -1230, +-1155, -1249, -947, -939, -595, -414, -150, 262, +307, 955, 651, 1426, 788, 1532, 782, 1296, +673, 775, 406, 60, 77, -641, -132, -1150, +-237, -1407, -359, -1363, -449, -1008, -414, -465, +-330, 108, -233, 596, -37, 918, 223, 1036, +400, 928, 417, 621, 319, 284, 145, 54, +-124, -127, -413, -300, -557, -403, -523, -485, +-328, -592, 88, -617, 614, -530, 922, -388, +885, -135, 647, 223, 260, 538, -284, 751, +-807, 830, -1101, 694, -1115, 394, -901, 84, +-522, -214, 8, -501, 631, -616, 1108, -487, +1248, -311, 1121, -198, 794, -59, 244, 72, +-338, 64, -714, -32, -918, -42, -1014, 39, +-905, 98, -580, 202, -161, 453, 284, 637, +659, 561, 809, 371, 687, 123, 373, -314, +62, -803, -74, -1036, -106, -959, -136, -673, +-98, -213, -29, 331, -73, 789, -164, 1028, +-149, 952, -102, 586, -174, 119, -314, -307, +-344, -613, -198, -650, 52, -381, 281, -3, +487, 297, 650, 438, 573, 331, 234, -44, +-92, -513, -270, -848, -400, -888, -465, -543, +-380, 88, -181, 771, 54, 1304, 241, 1511, +292, 1264, 194, 593, -36, -322, -327, -1168, +-493, -1657, -415, -1691, -179, -1291, 146, -533, +554, 385, 878, 1154, 939, 1526, 744, 1449, +345, 1000, -206, 315, -765, -396, -1180, -898, +-1346, -1041, -1179, -831, -692, -395, -34, 117, +590, 537, 1043, 665, 1248, 449, 1177, 43, +888, -364, 496, -658, 94, -718, -305, -443, +-672, 89, -885, 665, -931, 1072, -920, 1159, +-814, 885, -544, 297, -188, -475, 169, -1148, +542, -1442, 937, -1301, 1249, -824, 1307, -106, +1029, 704, 548, 1308, -5, 1431, -647, 1094, +-1278, 513, -1606, -157, -1501, -748, -1064, -1056, +-423, -995, 296, -623, 930, -104, 1333, 363, +1376, 662, 1025, 746, 486, 567, -26, 179, +-450, -206, -726, -433, -770, -536, -612, -516, +-361, -293, -128, 28, 52, 263, 187, 408, +228, 502, 141, 494, 42, 374, 57, 186, +76, -55, 12, -304, -11, -506, 39, -650, +68, -699, 77, -552, 120, -211, 173, 200, +139, 583, -3, 871, -131, 987, -165, 874, +-205, 531, -307, 26, -355, -523, -314, -983, +-250, -1193, -91, -1074, 214, -679, 459, -120, +518, 471, 519, 942, 475, 1152, 284, 1042, +17, 668, -204, 162, -363, -332, -468, -680, +-528, -812, -516, -726, -377, -481, -162, -184, +15, 94, 144, 301, 282, 388, 417, 377, +495, 331, 520, 269, 491, 189, 381, 90, +164, -17, -193, -101, -588, -175, -815, -280, +-813, -371, -670, -342, -402, -205, 10, -38, +425, 163, 674, 378, 762, 497, 724, 474, +503, 337, 127, 85, -233, -256, -454, -532, +-567, -590, -593, -459, -457, -249, -164, 36, +139, 388, 349, 661, 499, 688, 580, 464, +460, 155, 96, -131, -311, -414, -572, -638, +-700, -666, -718, -482, -500, -222, -22, 7, +503, 268, 861, 589, 1006, 783, 984, 725, +719, 535, 164, 287, -488, -86, -980, -532, +-1229, -844, -1266, -907, -1052, -777, -547, -505, +116, -96, 737, 378, 1225, 791, 1495, 1005, +1436, 956, 1010, 682, 331, 262, -379, -210, +-955, -623, -1341, -860, -1466, -846, -1235, -609, +-690, -269, -53, 72, 483, 371, 878, 573, +1107, 600, 1112, 480, 869, 311, 454, 106, +-6, -131, -399, -295, -675, -323, -827, -295, +-814, -270, -585, -193, -196, -17, 199, 152, +491, 227, 649, 292, 621, 381, 362, 354, +-17, 153, -337, -90, -520, -286, -571, -479, +-439, -642, -85, -598, 323, -279, 618, 161, +791, 569, 802, 900, 543, 1072, 52, 927, +-467, 425, -861, -229, -1103, -798, -1121, -1182, +-834, -1302, -312, -1074, 294, -540, 860, 128, +1279, 751, 1406, 1192, 1157, 1362, 640, 1228, +37, 806, -584, 192, -1100, -445, -1280, -961, +-1084, -1253, -719, -1222, -316, -884, 149, -376, +574, 186, 772, 717, 700, 1051, 502, 1040, +311, 734, 157, 315, 43, -115, 3, -486, +34, -651, 42, -541, -46, -267, -197, 26, +-389, 256, -579, 350, -632, 271, -513, 67, +-310, -152, -41, -308, 324, -337, 669, -211, +838, -4, 834, 179, 687, 293, 392, 325, +37, 253, -275, 124, -512, 43, -624, 69, +-608, 153, -538, 206, -471, 152, -360, -28, +-162, -305, 46, -638, 242, -903, 492, -923, +768, -624, 919, -74, 847, 602, 612, 1232, +285, 1635, -167, 1658, -705, 1219, -1099, 395, +-1151, -576, -918, -1416, -538, -1934, -58, -2003, +452, -1542, 824, -676, 886, 287, 672, 1120, +380, 1677, 153, 1804, -2, 1473, -89, 883, +-65, 261, 56, -295, 111, -719, -39, -914, +-324, -913, -593, -878, -743, -860, -754, -769, +-575, -530, -155, -151, 411, 334, 896, 898, +1157, 1432, 1188, 1710, 990, 1562, 527, 996, +-120, 138, -744, -836, -1157, -1674, -1250, -2074, +-1048, -1890, -619, -1195, -58, -190, 472, 862, +804, 1641, 884, 1907, 753, 1617, 467, 891, +140, -30, -84, -850, -188, -1322, -235, -1350, +-205, -955, -103, -276, -63, 436, -151, 930, +-222, 1080, -201, 878, -184, 403, -178, -182, +-59, -694, 186, -958, 366, -880, 384, -524, +355, -71, 325, 356, 205, 708, 22, 882, +-115, 781, -172, 489, -208, 174, -245, -98, +-232, -335, -181, -501, -149, -547, -130, -509, +-54, -458, 100, -390, 251, -223, 321, 49, +342, 352, 355, 627, 318, 829, 164, 866, +-54, 685, -224, 346, -357, -65, -473, -489, +-471, -823, -275, -925, 3, -773, 242, -488, +429, -169, 514, 175, 419, 501, 193, 691, +-48, 695, -244, 576, -360, 409, -360, 200, +-227, -42, 5, -259, 231, -395, 357, -427, +392, -376, 322, -282, 89, -164, -212, -32, +-408, 77, -459, 149, -385, 192, -188, 216, +73, 229, 299, 246, 442, 249, 518, 213, +475, 151, 268, 84, -35, -22, -318, -186, +-492, -343, -533, -433, -417, -448, -151, -376, +150, -192, 362, 82, 452, 379, 401, 611, +224, 727, 10, 700, -159, 509, -285, 164, +-328, -256, -227, -633, -54, -876, 98, -918, +223, -719, 301, -305, 262, 219, 133, 712, +12, 1038, -68, 1108, -153, 903, -230, 475, +-246, -70, -195, -611, -147, -1005, -116, -1123, +-7, -944, 170, -563, 309, -62, 378, 454, +432, 852, 437, 1054, 281, 1050, -15, 822, +-316, 412, -568, -48, -756, -480, -787, -854, +-575, -1056, -159, -986, 301, -716, 715, -331, +1004, 157, 1036, 656, 756, 981, 287, 1073, +-212, 972, -675, 699, -1007, 267, -1060, -248, +-809, -684, -380, -925, 102, -962, 542, -819, +832, -494, 888, -62, 719, 346, 384, 653, +-22, 829, -385, 826, -614, 631, -650, 329, +-506, 21, -258, -229, -2, -399, 190, -476, +286, -463, 295, -370, 247, -240, 188, -121, +124, -19, 47, 100, -42, 267, -139, 430, +-222, 499, -284, 477, -299, 403, -230, 223, +-96, -74, 63, -363, 236, -538, 385, -591, +436, -500, 349, -245, 170, 90, -49, 395, +-293, 595, -507, 615, -614, 438, -527, 168, +-271, -106, 18, -321, 248, -421, 410, -384, +484, -248, 444, -57, 329, 135, 182, 255, +6, 285, -166, 257, -294, 216, -398, 182, +-488, 149, -533, 77, -463, -37, -280, -160, +-66, -287, 152, -427, 421, -502, 723, -404, +889, -126, 788, 251, 464, 618, -1, 887, +-548, 967, -1040, 784, -1312, 334, -1223, -279, +-765, -871, -92, -1238, 607, -1251, 1164, -899, +1406, -260, 1217, 494, 650, 1125, -107, 1419, +-839, 1303, -1327, 808, -1399, 67, -1058, -663, +-411, -1109, 349, -1172, 967, -876, 1250, -291, +1118, 384, 632, 875, -36, 1003, -683, 773, +-1158, 288, -1318, -276, -1071, -704, -514, -835, +133, -637, 729, -194, 1144, 317, 1235, 717, +951, 890, 406, 788, -189, 435, -695, -67, +-1049, -515, -1199, -749, -1069, -751, -706, -567, +-276, -227, 149, 168, 572, 457, 899, 563, +1019, 540, 911, 432, 636, 243, 265, 27, +-181, -119, -652, -151, -1048, -126, -1243, -124, +-1188, -147, -890, -153, -375, -171, 237, -220, +784, -211, 1158, -71, 1261, 151, 1014, 362, +486, 521, -149, 590, -731, 517, -1138, 294, +-1236, -18, -992, -340, -549, -587, -79, -699, +343, -637, 671, -392, 773, -26, 601, 370, +283, 690, -49, 833, -359, 741, -575, 455, +-605, 79, -450, -286, -197, -579, 69, -721, +233, -636, 245, -355, 169, -2, 9, 335, +-201, 606, -324, 709, -290, 587, -205, 297, +-140, -52, -38, -375, 95, -559, 124, -539, +19, -355, -110, -56, -173, 301, -183, 562, +-181, 605, -111, 466, 25, 184, 113, -183, +72, -478, -47, -566, -155, -464, -222, -213, +-274, 155, -312, 497, -294, 656, -202, 595, +-81, 358, 35, 12, 159, -321, 235, -541, +202, -586, 68, -432, -105, -118, -271, 239, +-367, 512, -334, 611, -214, 523, -106, 304, +-60, 12, -66, -271, -105, -440, -161, -436, +-231, -308, -245, -100, -162, 146, -19, 330, +125, 373, 246, 304, 317, 175, 252, 31, +44, -65, -212, -83, -447, -51, -631, -20, +-704, -9, -625, -24, -410, -73, -135, -145, +133, -167, 354, -73, 482, 94, 471, 252, +324, 395, 110, 489, -130, 421, -355, 188, +-505, -119, -561, -413, -568, -619, -532, -626, +-426, -403, -247, -54, -37, 319, 176, 624, +354, 734, 418, 607, 331, 347, 146, 44, +-46, -259, -239, -476, -425, -504, -520, -366, +-482, -164, -378, 51, -256, 244, -120, 329, +-5, 262, 28, 112, -41, -32, -133, -102, +-177, -65, -126, 76, -17, 253, 97, 388, +191, 415, 195, 275, 38, -31, -235, -412, +-490, -716, -623, -796, -618, -593, -504, -187, +-290, 319, -28, 809, 207, 1091, 326, 987, +304, 576, 174, 78, -17, -377, -224, -730, +-392, -860, -438, -671, -343, -264, -179, 150, +-55, 409, -11, 483, -69, 391, -237, 164, +-444, -113, -534, -264, -444, -185, -191, 57, +186, 356, 536, 619, 682, 698, 551, 464, +183, 15, -355, -465, -914, -878, -1279, -1137, +-1299, -1033, -963, -519, -352, 182, 354, 832, +935, 1318, 1212, 1486, 1089, 1185, 602, 520, +-108, -234, -815, -861, -1306, -1232, -1443, -1221, +-1207, -848, -699, -272, -91, 324, 430, 765, +723, 919, 756, 764, 579, 410, 261, 11, +-103, -283, -411, -384, -566, -281, -567, -47, +-493, 197, -422, 324, -369, 290, -331, 117, +-317, -149, -296, -400, -207, -497, -26, -396, +215, -149, 441, 180, 528, 491, 429, 668, +168, 638, -184, 435, -581, 129, -935, -194, +-1102, -421, -1004, -487, -668, -413, -225, -258, +202, -71, 549, 105, 739, 256, 671, 355, +395, 380, 39, 331, -313, 250, -635, 149, +-842, -8, -857, -204, -711, -345, -460, -399, +-151, -404, 140, -295, 331, -2, 391, 383, +297, 673, 58, 811, -208, 762, -385, 447, +-492, -83, -552, -624, -493, -1002, -298, -1128, +-71, -901, 103, -330, 238, 396, 279, 1031, +136, 1414, -145, 1409, -417, 960, -598, 182, +-673, -646, -621, -1228, -426, -1388, -140, -1105, +132, -478, 303, 285, 349, 890, 306, 1127, +155, 961, -96, 497, -351, -94, -506, -583, +-542, -757, -512, -556, -431, -91, -313, 450, +-214, 856, -152, 919, -99, 573, -61, -56, +-6, -719, 80, -1193, 154, -1303, 168, -963, +135, -230, 54, 654, -105, 1392, -311, 1749, +-522, 1605, -721, 993, -838, 82, -753, -862, +-472, -1542, -125, -1734, 204, -1414, 503, -717, +666, 142, 577, 904, 267, 1335, -108, 1347, +-430, 1017, -679, 471, -801, -108, -735, -523, +-512, -669, -249, -577, -35, -340, 93, -91, +140, 71, 103, 105, -15, 34, -157, -65, +-223, -93, -185, 11, -125, 187, -57, 353, +42, 491, 114, 552, 31, 430, -206, 137, +-450, -202, -599, -476, -691, -638, -702, -643, +-511, -447, -143, -99, 225, 279, 476, 569, +630, 707, 626, 672, 372, 494, -94, 199, +-592, -141, -945, -424, -1046, -571, -893, -562, +-558, -409, -126, -128, 279, 201, 530, 473, +575, 600, 439, 545, 139, 337, -241, 87, +-576, -136, -761, -322, -752, -430, -537, -380, +-145, -193, 253, 33, 460, 245, 403, 391, +135, 403, -233, 270, -556, 77, -700, -115, +-620, -254, -384, -279, -62, -154, 265, 69, +466, 271, 451, 368, 213, 349, -186, 223, +-635, -27, -953, -323, -985, -515, -685, -502, +-137, -322, 457, -23, 857, 375, 962, 740, +749, 861, 218, 692, -482, 366, -1080, -36, +-1392, -484, -1405, -844, -1114, -928, -515, -731, +267, -360, 961, 118, 1325, 612, 1295, 938, +929, 992, 307, 819, -428, 487, -1048, 54, +-1380, -380, -1394, -687, -1176, -829, -780, -785, +-273, -557, 231, -192, 619, 213, 841, 551, +901, 755, 783, 809, 491, 696, 111, 417, +-274, 60, -642, -272, -933, -513, -1059, -638, +-997, -611, -795, -420, -490, -122, -106, 188, +305, 431, 637, 539, 781, 485, 717, 320, +502, 133, 183, -18, -191, -145, -499, -206, +-665, -149, -702, -29, -647, 33, -504, 39, +-334, 44, -190, 35, -57, -43, 66, -149, +154, -151, 200, -22, 221, 147, 208, 276, +170, 377, 108, 412, -13, 303, -200, 78, +-379, -152, -500, -350, -553, -481, -512, -440, +-357, -218, -126, 76, 74, 341, 195, 528, +245, 548, 219, 370, 92, 79, -97, -192, +-255, -362, -315, -387, -287, -276, -198, -71, +-63, 188, 65, 394, 136, 445, 113, 342, +24, 157, -99, -75, -263, -302, -452, -426, +-561, -375, -533, -175, -404, 88, -164, 324, +178, 457, 472, 457, 580, 326, 523, 101, +350, -151, 90, -328, -199, -367, -419, -262, +-568, -50, -677, 218, -716, 424, -643, 424, +-447, 212, -180, -82, 106, -333, 383, -476, +611, -440, 706, -185, 639, 222, 451, 595, +185, 775, -173, 723, -575, 474, -884, 50, +-1012, -462, -957, -828, -751, -892, -383, -694, +78, -309, 494, 219, 779, 701, 918, 913, +846, 805, 542, 494, 92, 102, -381, -274, +-759, -522, -940, -535, -871, -305, -613, 31, +-280, 295, 20, 397, 224, 335, 307, 86, +300, -287, 241, -579, 140, -611, 17, -359, +-53, 81, -29, 580, 4, 985, -26, 1136, +-87, 915, -146, 379, -280, -296, -457, -898, +-511, -1269, -387, -1283, -196, -916, -9, -281, +198, 433, 403, 1021, 490, 1306, 405, 1225, +227, 855, 6, 324, -256, -217, -515, -649, +-651, -883, -619, -869, -436, -631, -137, -282, +175, 57, 391, 336, 489, 509, 476, 543, +308, 472, -11, 363, -370, 220, -620, 63, +-693, -77, -578, -202, -292, -303, 113, -314, +494, -227, 682, -96, 635, 48, 392, 194, +-14, 300, -485, 286, -807, 153, -885, -8, +-751, -106, -416, -158, 104, -175, 632, -92, +933, 119, 912, 332, 603, 399, 91, 316, +-498, 145, -952, -96, -1102, -364, -925, -501, +-504, -412, 44, -179, 565, 89, 907, 378, +967, 609, 723, 613, 249, 371, -298, 37, +-745, -270, -975, -517, -919, -593, -610, -407, +-174, -21, 240, 387, 541, 667, 651, 720, +543, 517, 308, 115, 62, -355, -154, -710, +-307, -810, -352, -627, -301, -217, -226, 314, +-187, 790, -175, 1026, -171, 931, -159, 564, +-131, 31, -64, -533, 76, -932, 275, -1011, +451, -761, 513, -320, 447, 178, 261, 643, +-53, 960, -442, 985, -754, 701, -897, 251, +-833, -203, -565, -571, -152, -774, 309, -724, +695, -445, 919, -68, 910, 281, 653, 537, +208, 622, -297, 511, -717, 279, -918, 22, +-860, -207, -570, -338, -154, -325, 222, -203, +450, -26, 519, 148, 439, 250, 203, 231, +-102, 126, -341, 2, -432, -93, -373, -132, +-188, -97, 110, -3, 442, 115, 614, 224, +490, 278, 138, 243, -278, 114, -639, -66, +-888, -250, -904, -371, -621, -369, -136, -212, +359, 37, 742, 294, 982, 502, 997, 596, +682, 510, 120, 239, -431, -128, -811, -466, +-996, -653, -950, -637, -631, -427, -179, -66, +218, 379, 499, 742, 660, 853, 643, 691, +408, 341, 67, -90, -219, -504, -406, -775, +-496, -797, -416, -542, -156, -117, 137, 321, +300, 661, 325, 828, 244, 725, 40, 372, +-241, -40, -452, -357, -518, -543, -484, -553, +-330, -338, -20, -20, 349, 229, 604, 342, +671, 332, 563, 202, 293, -16, -80, -205, +-416, -235, -608, -75, -646, 167, -545, 370, +-356, 462, -142, 405, 60, 171, 232, -189, +337, -526, 333, -678, 241, -594, 140, -332, +71, 43, 30, 459, 22, 775, 39, 850, +18, 687, -119, 348, -330, -103, -520, -536, +-613, -765, -566, -739, -345, -511, 13, -138, +392, 283, 679, 596, 794, 703, 684, 611, +375, 369, -12, 56, -382, -256, -685, -486, +-827, -557, -706, -446, -403, -202, -89, 102, +184, 382, 428, 558, 538, 592, 403, 480, +135, 243, -85, -80, -229, -388, -322, -591, +-291, -653, -113, -541, 114, -243, 242, 145, +228, 503, 105, 762, -98, 846, -316, 678, +-463, 277, -456, -184, -300, -549, -61, -752, +194, -760, 408, -517, 497, -70, 435, 387, +248, 664, -28, 700, -320, 516, -528, 172, +-595, -232, -518, -547, -287, -615, 21, -398, +293, 2, 473, 424, 534, 742, 416, 847, +120, 651, -224, 183, -487, -402, -637, -911, +-642, -1156, -453, -1024, -115, -570, 249, 71, +522, 742, 647, 1252, 602, 1408, 398, 1164, +74, 614, -302, -76, -619, -710, -767, -1108, +-730, -1194, -571, -993, -303, -559, 55, -23, +380, 447, 546, 723, 604, 807, 598, 748, +453, 584, 155, 357, -168, 120, -406, -100, +-562, -284, -651, -427, -646, -541, -508, -575, +-267, -481, -14, -278, 196, -22, 398, 277, +569, 581, 603, 762, 457, 721, 209, 502, +-59, 167, -325, -236, -542, -574, -637, -715, +-565, -611, -388, -322, -185, 52, 33, 396, +260, 618, 396, 649, 361, 459, 197, 122, +16, -210, -127, -438, -246, -543, -279, -474, +-171, -224, -7, 103, 80, 348, 84, 454, +57, 449, -24, 350, -156, 164, -257, -34, +-292, -143, -266, -151, -166, -121, -17, -99, +114, -88, 179, -107, 183, -169, 126, -242, +39, -245, -38, -116, -90, 123, -119, 388, +-115, 632, -86, 780, -81, 705, -111, 388, +-149, -61, -180, -511, -232, -873, -273, -1019, +-230, -864, -78, -456, 112, 76, 282, 589, +395, 936, 387, 1014, 243, 797, 20, 358, +-205, -124, -390, -475, -472, -616, -440, -545, +-332, -272, -210, 79, -91, 316, 16, 351, +88, 208, 110, -58, 98, -348, 112, -510, +150, -444, 186, -158, 209, 249, 202, 657, +94, 927, -128, 934, -385, 627, -597, 98, +-715, -467, -671, -909, -448, -1116, -123, -1007, +233, -600, 554, -22, 746, 548, 732, 934, +527, 1047, 186, 862, -219, 452, -587, -22, +-803, -404, -810, -601, -643, -583, -368, -382, +-37, -104, 271, 133, 451, 245, 474, 221, +368, 83, 183, -54, -25, -97, -204, -65, +-312, 31, -331, 205, -265, 362, -158, 358, +-68, 194, -8, -22, 29, -231, 12, -407, +-54, -443, -129, -283, -157, -2, -147, 274, +-116, 456, -46, 499, 63, 372, 148, 92, +150, -232, 108, -470, 43, -540, -80, -417, +-254, -140, -367, 219, -374, 524, -308, 657, +-182, 587, 16, 351, 207, 7, 279, -340, +237, -565, 124, -595, -37, -438, -218, -169, +-340, 122, -362, 344, -290, 454, -143, 426, +40, 258, 179, 32, 226, -129, 185, -172, +53, -127, -159, -28, -356, 91, -406, 176, +-304, 167, -134, 57, 39, -115, 188, -265, +269, -327, 222, -283, 51, -137, -153, 73, +-303, 280, -384, 413, -389, 443, -282, 357, +-68, 178, 157, -17, 295, -149, 311, -211, +214, -229, 30, -188, -184, -105, -360, -55, +-424, -73, -371, -109, -278, -106, -176, -57, +-42, 49, 114, 207, 209, 369, 251, 480, +261, 499, 199, 394, 44, 160, -125, -142, +-234, -420, -325, -622, -417, -697, -452, -600, +-380, -349, -251, -10, -96, 349, 90, 619, +305, 717, 451, 646, 466, 461, 365, 202, +170, -76, -84, -279, -355, -373, -570, -391, +-680, -358, -646, -287, -476, -209, -206, -138, +84, -61, 318, 63, 454, 224, 490, 374, +422, 485, 248, 536, 29, 483, -193, 280, +-395, -30, -529, -330, -547, -534, -469, -629, +-331, -576, -133, -364, 79, -58, 227, 231, +301, 422, 312, 507, 243, 485, 92, 364, +-72, 174, -189, -22, -259, -158, -272, -199, +-227, -189, -159, -175, -129, -161, -137, -118, +-130, -62, -88, -50, -39, -39, 4, 46, +53, 174, 93, 251, 109, 265, 85, 249, +40, 192, -25, 62, -104, -94, -193, -211, +-266, -263, -301, -245, -291, -177, -223, -76, +-108, 48, 28, 161, 138, 215, 232, 193, +264, 139, 199, 106, 42, 70, -144, 16, +-308, -27, -418, -44, -424, -57, -327, -97, +-166, -133, 4, -128, 161, -96, 274, -37, +311, 78, 259, 213, 126, 285, -76, 253, +-302, 156, -465, 30, -495, -121, -403, -259, +-235, -309, -15, -218, 198, -34, 318, 129, +311, 215, 216, 249, 83, 229, -76, 123, +-219, -43, -287, -161, -275, -170, -225, -112, +-159, -28, -93, 57, -82, 116, -142, 113, +-179, 40, -112, -60, 32, -118, 198, -89, +355, 22, 428, 146, 334, 245, 89, 293, +-218, 214, -522, -8, -771, -271, -846, -458, +-672, -517, -296, -419, 154, -145, 595, 251, +906, 620, 944, 829, 654, 805, 141, 540, +-400, 93, -825, -438, -1028, -884, -954, -1089, +-617, -985, -147, -603, 317, -41, 635, 551, +723, 1018, 570, 1213, 252, 1075, -109, 657, +-399, 109, -503, -408, -412, -808, -218, -994, +-31, -913, 89, -646, 90, -310, -33, 34, +-200, 343, -301, 572, -283, 683, -150, 691, +81, 621, 341, 476, 518, 255, 506, -37, +282, -337, -97, -577, -506, -744, -793, -808, +-861, -698, -689, -417, -321, -43, 148, 341, +573, 676, 810, 900, 797, 934, 547, 769, +138, 455, -322, 62, -717, -341, -905, -683, +-808, -880, -486, -870, -93, -676, 259, -369, +513, -18, 599, 323, 475, 610, 214, 756, +-45, 713, -247, 540, -384, 319, -455, 78, +-409, -177, -251, -398, -61, -507, 66, -494, +136, -415, 190, -311, 193, -156, 130, 58, +36, 240, -43, 337, -149, 390, -261, 398, +-329, 296, -303, 111, -196, -45, -34, -121, +149, -170, 286, -198, 338, -148, 281, -34, +131, 55, -85, 48, -310, -13, -497, -61, +-603, -117, -570, -203, -357, -255, 1, -186, +384, 23, 659, 293, 737, 539, 604, 706, +302, 730, -92, 546, -486, 130, -774, -419, +-882, -924, -795, -1235, -527, -1250, -143, -926, +260, -309, 600, 461, 813, 1176, 838, 1609, +643, 1640, 279, 1264, -147, 568, -546, -297, +-843, -1107, -959, -1627, -845, -1741, -530, -1453, +-97, -824, 319, -4, 614, 795, 753, 1364, +726, 1582, 534, 1459, 220, 1044, -121, 419, +-444, -256, -688, -791, -774, -1086, -649, -1176, +-388, -1092, -91, -811, 195, -383, 404, 70, +477, 465, 415, 776, 311, 999, 176, 1094, +7, 995, -165, 676, -283, 216, -364, -264, +-409, -716, -375, -1110, -273, -1301, -152, -1168, +-28, -776, 130, -256, 277, 320, 353, 880, +356, 1270, 313, 1375, 191, 1202, -31, 797, +-270, 221, -427, -416, -486, -972, -477, -1309, +-377, -1365, -178, -1161, 52, -723, 237, -101, +347, 564, 396, 1072, 389, 1325, 313, 1344, +146, 1110, -72, 602, -254, -69, -394, -695, +-525, -1122, -591, -1324, -488, -1299, -246, -986, +23, -390, 294, 324, 560, 915, 711, 1276, +629, 1418, 368, 1267, 49, 751, -302, 18, +-671, -672, -903, -1161, -853, -1406, -566, -1358, +-154, -967, 299, -332, 709, 360, 908, 959, +802, 1365, 441, 1481, -8, 1246, -397, 720, +-677, 42, -805, -660, -721, -1241, -434, -1539, +-87, -1478, 232, -1080, 475, -443, 607, 296, +562, 969, 345, 1435, 63, 1619, -163, 1455, +-291, 944, -388, 237, -445, -479, -397, -1105, +-249, -1555, -104, -1691, 11, -1416, 140, -817, +275, -80, 346, 660, 316, 1291, 219, 1672, +104, 1681, -29, 1292, -194, 652, -349, -58, +-406, -732, -325, -1280, -167, -1588, -13, -1538, +118, -1157, 204, -574, 188, 102, 66, 764, +-44, 1278, -59, 1517, -51, 1420, -47, 1035, +22, 471, 147, -165, 217, -750, 174, -1172, +51, -1338, -144, -1222, -381, -885, -551, -394, +-526, 176, -307, 720, -3, 1114, 295, 1260, +508, 1144, 562, 815, 442, 309, 247, -289, +41, -829, -162, -1154, -340, -1204, -424, -1003, +-410, -572, -347, 17, -232, 591, -79, 986, +59, 1134, 119, 1039, 147, 718, 186, 202, +256, -352, 316, -762, 334, -966, 265, -982, +90, -787, -145, -382, -383, 98, -543, 506, +-575, 803, -462, 944, -258, 858, 5, 587, +298, 213, 523, -211, 578, -620, 466, -891, +253, -931, -21, -773, -280, -469, -395, -55, +-322, 391, -165, 765, -49, 967, -1, 948, +-6, 724, -61, 343, -139, -114, -145, -565, +-45, -914, 93, -1044, 211, -905, 313, -558, +378, -97, 324, 396, 125, 822, -151, 1050, +-396, 986, -530, 668, -519, 207, -343, -277, +-38, -685, 283, -937, 471, -935, 471, -661, +341, -232, 141, 209, -90, 586, -317, 847, +-452, 891, -437, 662, -258, 263, 1, -172, +248, -558, 408, -818, 437, -873, 339, -677, +125, -283, -134, 174, -332, 569, -373, 834, +-322, 922, -260, 780, -189, 394, -62, -84, +68, -489, 149, -785, 227, -943, 347, -874, +457, -556, 445, -127, 312, 271, 94, 602, +-193, 831, -538, 888, -818, 773, -876, 518, +-680, 178, -296, -179, 194, -502, 693, -759, +1044, -921, 1113, -926, 873, -741, 395, -412, +-198, 4, -758, 464, -1119, 902, -1170, 1221, +-882, 1298, -331, 1083, 309, 636, 835, 30, +1082, -660, 1002, -1284, 617, -1637, 26, -1615, +-568, -1250, -938, -597, -960, 256, -672, 1096, +-187, 1703, 365, 1930, 827, 1720, 1017, 1130, +842, 274, 380, -683, -165, -1505, -618, -1950, +-917, -1922, -997, -1485, -805, -733, -359, 209, +168, 1097, 601, 1706, 859, 1903, 935, 1654, +799, 1056, 456, 274, 70, -548, -221, -1259, +-416, -1651, -592, -1610, -702, -1233, -696, -664, +-595, 27, -443, 725, -198, 1250, 165, 1468, +547, 1361, 837, 993, 981, 433, 986, -226, +831, -834, 489, -1240, -46, -1364, -683, -1200, +-1204, -787, -1421, -194, -1303, 448, -909, 1013, +-285, 1376, 440, 1408, 1010, 1091, 1239, 524, +1157, -174, 906, -885, 558, -1434, 136, -1602, +-273, -1296, -524, -649, -590, 140, -583, 913, +-588, 1507, -578, 1708, -521, 1381, -455, 655, +-354, -205, -95, -980, 366, -1514, 886, -1656, +1263, -1318, 1415, -608, 1278, 214, 789, 934, +7, 1415, -847, 1533, -1538, 1230, -1905, 605, +-1842, -96, -1325, -679, -435, -1080, 607, -1243, +1526, -1108, 2020, -701, 1961, -184, 1413, 247, +549, 559, -409, 799, -1195, 935, -1558, 884, +-1450, 649, -1000, 345, -416, 52, 185, -272, +676, -645, 922, -962, 860, -1072, 594, -941, +267, -656, -50, -237, -316, 334, -483, 926, +-483, 1311, -335, 1362, -124, 1115, 69, 649, +241, 11, 391, -672, 466, -1198, 425, -1423, +272, -1303, 35, -908, -258, -348, -553, 267, +-767, 809, -821, 1167, -665, 1243, -291, 1042, +263, 680, 859, 241, 1304, -256, 1443, -725, +1229, -1027, 695, -1093, -82, -969, -935, -687, +-1634, -233, -1951, 303, -1776, 770, -1133, 1053, +-153, 1123, 918, 987, 1772, 643, 2157, 118, +2006, -465, 1382, -939, 440, -1175, -583, -1155, +-1412, -904, -1855, -425, -1876, 195, -1493, 770, +-786, 1123, 106, 1201, 930, 1042, 1469, 666, +1606, 111, 1385, -480, 937, -916, 371, -1098, +-231, -1046, -767, -798, -1098, -367, -1207, 134, +-1142, 540, -905, 785, -432, 880, 187, 822, +744, 619, 1108, 332, 1306, 18, 1347, -301, +1105, -566, 534, -721, -222, -785, -945, -751, +-1531, -569, -1876, -226, -1795, 184, -1191, 546, +-216, 825, 836, 997, 1730, 958, 2301, 658, +2383, 208, 1858, -233, 811, -613, -464, -916, +-1649, -1037, -2491, -904, -2777, -571, -2374, -134, +-1378, 321, -80, 713, 1194, 961, 2193, 987, +2746, 762, 2716, 351, 2079, -96, 989, -451, +-282, -690, -1470, -768, -2363, -630, -2758, -331, +-2545, -18, -1786, 205, -703, 337, 457, 393, +1501, 349, 2285, 221, 2664, 84, 2527, 3, +1877, -8, 818, -26, -429, -77, -1619, -96, +-2499, -63, -2874, -61, -2616, -120, -1768, -145, +-555, -82, 762, -13, 1934, 21, 2745, 66, +2968, 133, 2517, 188, 1474, 178, 102, 111, +-1280, 27, -2345, -56, -2842, -128, -2666, -170, +-1888, -163, -740, -100, 506, -9, 1595, 80, +2341, 151, 2568, 184, 2196, 175, 1324, 105, +214, -26, -871, -147, -1742, -192, -2211, -182, +-2138, -169, -1574, -131, -736, 3, 165, 163, +1007, 210, 1678, 175, 2031, 168, 1942, 181, +1412, 117, 561, -7, -412, -76, -1306, -78, +-1936, -105, -2130, -186, -1823, -274, -1090, -297, +-132, -238, 850, -138, 1700, -5, 2241, 182, +2302, 422, 1808, 618, 862, 646, -323, 504, +-1491, 265, -2370, -59, -2705, -466, -2368, -840, +-1435, -1005, -138, -909, 1190, -619, 2263, -165, +2857, 396, 2844, 918, 2156, 1215, 912, 1189, +-578, 886, -1950, 411, -2907, -163, -3236, -745, +-2786, -1154, -1618, -1228, -29, -986, 1537, -574, +2744, -90, 3359, 392, 3233, 769, 2318, 943, +822, 888, -837, 675, -2273, 403, -3219, 117, +-3468, -178, -2866, -456, -1549, -651, 88, -728, +1644, -706, 2843, -583, 3429, -343, 3208, 6, +2223, 392, 773, 702, -787, 878, -2158, 900, +-3058, 726, -3248, 351, -2675, -133, -1527, -590, +-112, -906, 1280, -1025, 2377, -912, 2960, -572, +2919, -67, 2264, 476, 1148, 882, -179, 1041, +-1438, 956, -2400, 656, -2877, 179, -2740, -363, +-2021, -797, -896, -978, 396, -905, 1634, -640, +2590, -237, 3035, 241, 2828, 669, 1987, 889, +679, 862, -821, 665, -2171, 341, -3051, -85, +-3229, -519, -2668, -825, -1489, -904, 24, -769, +1551, -472, 2763, -49, 3368, 416, 3187, 806, +2229, 993, 734, 917, -922, 629, -2311, 193, +-3132, -323, -3216, -789, -2563, -1058, -1324, -1032, +171, -751, 1582, -321, 2630, 181, 3091, 663, +2867, 1000, 2005, 1084, 702, 898, -757, 535, +-2022, 99, -2802, -375, -2956, -804, -2475, -1055, +-1458, -1052, -129, -839, 1235, -467, 2367, 33, +3025, 548, 3015, 940, 2301, 1148, 1052, 1120, +-452, 827, -1892, 355, -2923, -171, -3263, -679, +-2832, -1088, -1764, -1247, -301, -1103, 1249, -750, +2527, -273, 3237, 285, 3218, 839, 2466, 1234, +1135, 1341, -443, 1145, -1874, 730, -2851, 173, +-3172, -469, -2781, -1064, -1798, -1412, -499, -1421, +847, -1152, 2019, -663, 2800, 2, 3011, 730, +2590, 1334, 1658, 1652, 389, 1625, -976, 1269, +-2181, 597, -2938, -313, -3084, -1238, -2623, -1897, +-1640, -2119, -252, -1869, 1339, -1158, 2731, -74, +3538, 1129, 3552, 2102, 2788, 2564, 1349, 2400, +-517, 1655, -2355, 466, -3614, -913, -3973, -2115, +-3427, -2791, -2108, -2752, -238, -2051, 1767, -859, +3342, 574, 4077, 1898, 3826, 2737, 2677, 2861, +883, 2288, -1110, 1223, -2773, -105, -3689, -1410, +-3688, -2343, -2825, -2650, -1326, -2320, 428, -1521, +2003, -434, 3042, 738, 3345, 1709, 2889, 2236, +1801, 2232, 360, 1748, -1096, 934, -2234, -36, +-2812, -973, -2760, -1688, -2136, -2024, -1094, -1895, +170, -1374, 1406, -614, 2342, 270, 2771, 1142, +2636, 1780, 1986, 2001, 854, 1791, -577, 1229, +-1911, 366, -2773, -649, -3037, -1524, -2687, -2043, +-1690, -2153, -196, -1822, 1417, -1015, 2712, 124, +3429, 1250, 3412, 2073, 2605, 2469, 1116, 2351, +-692, 1660, -2350, 502, -3470, -819, -3804, -1937, +-3279, -2613, -1976, -2746, -189, -2286, 1660, -1250, +3125, 151, 3917, 1524, 3874, 2516, 2974, 2975, +1370, 2820, -549, 2011, -2301, 688, -3522, -803, +-3997, -2081, -3637, -2907, -2464, -3128, -736, -2656, +1138, -1552, 2760, -79, 3847, 1381, 4164, 2499, +3563, 3105, 2138, 3059, 222, 2288, -1750, 974, +-3339, -495, -4182, -1791, -4074, -2736, -3043, -3126, +-1325, -2784, 690, -1778, 2541, -413, 3807, 987, +4216, 2155, 3698, 2881, 2353, 2969, 470, 2343, +-1497, 1175, -3039, -189, -3806, -1426, -3700, -2357, +-2797, -2831, -1321, -2672, 409, -1860, 1996, -659, +3088, 579, 3492, 1669, 3184, 2505, 2231, 2849, +798, 2505, -782, 1581, -2132, 357, -2986, -936, +-3215, -2123, -2761, -2949, -1722, -3123, -325, -2518, +1140, -1294, 2401, 220, 3208, 1732, 3368, 2993, +2767, 3643, 1467, 3348, -205, 2165, -1829, 490, +-3030, -1294, -3570, -2906, -3275, -3941, -2180, -3963, +-539, -2900, 1220, -1141, 2699, 826, 3615, 2628, +3742, 3904, 2966, 4239, 1412, 3412, -480, 1705, +-2197, -298, -3343, -2128, -3699, -3510, -3204, -4112, +-1969, -3633, -282, -2187, 1443, -337, 2799, 1402, +3529, 2785, 3532, 3600, 2764, 3571, 1316, 2629, +-461, 1117, -2066, -473, -3119, -1843, -3464, -2854, +-3065, -3315, -1993, -3002, -478, -1953, 1112, -567, +2442, 804, 3293, 2035, 3479, 2958, 2888, 3239, +1601, 2710, -57, 1587, -1668, 201, -2865, -1244, +-3414, -2524, -3197, -3305, -2251, -3288, -800, -2446, +813, -1064, 2245, 513, 3213, 2020, 3507, 3166, +3024, 3588, 1819, 3061, 163, 1770, -1527, 135, +-2806, -1506, -3432, -2886, -3303, -3638, -2410, -3430, +-897, -2321, 854, -729, 2375, 957, 3365, 2488, +3637, 3519, 3089, 3673, 1740, 2856, -83, 1369, +-1881, -369, -3169, -2020, -3675, -3289, -3327, -3833, +-2182, -3407, -477, -2092, 1363, -314, 2854, 1469, +3666, 2959, 3668, 3879, 2843, 3906, 1308, 2909, +-573, 1193, -2272, -724, -3359, -2460, -3663, -3757, +-3153, -4257, -1907, -3695, -205, -2199, 1493, -234, +2793, 1736, 3503, 3371, 3522, 4320, 2801, 4270, +1427, 3157, -272, 1304, -1855, -781, -2985, -2663, +-3501, -4008, -3327, -4479, -2414, -3857, -907, -2288, +808, -260, 2326, 1718, 3383, 3318, 3787, 4241, +3377, 4178, 2166, 3067, 434, 1266, -1389, -688, +-2867, -2416, -3680, -3656, -3676, -4090, -2852, -3506, +-1343, -2077, 513, -276, 2216, 1446, 3370, 2838, +3770, 3646, 3380, 3592, 2207, 2656, 482, 1174, +-1325, -456, -2705, -1963, -3371, -3080, -3295, -3500, +-2500, -3089, -1119, -1978, 521, -458, 1965, 1123, +2897, 2483, 3203, 3351, 2868, 3461, 1896, 2711, +458, 1319, -1048, -343, -2217, -1970, -2879, -3249, +-2950, -3789, -2348, -3370, -1166, -2115, 280, -358, +1628, 1506, 2639, 3083, 3124, 3968, 2971, 3889, +2135, 2836, 737, 1083, -882, -931, -2283, -2747, +-3144, -3954, -3316, -4230, -2705, -3474, -1384, -1877, +323, 161, 1940, 2166, 3072, 3681, 3531, 4331, +3242, 3947, 2191, 2644, 557, 749, -1205, -1328, +-2598, -3116, -3359, -4171, -3369, -4242, -2580, -3345, +-1144, -1695, 549, 349, 2019, 2310, 2950, 3734, +3223, 4320, 2848, 3925, 1865, 2600, 475, 658, +-952, -1426, -2085, -3188, -2731, -4219, -2809, -4244, +-2258, -3256, -1210, -1545, 61, 507, 1247, 2467, +2162, 3848, 2679, 4279, 2666, 3701, 2077, 2318, +1034, 439, -225, -1554, -1450, -3190, -2372, -4064, +-2775, -4005, -2577, -3076, -1786, -1490, -499, 460, +948, 2355, 2178, 3706, 2947, 4185, 3118, 3742, +2548, 2514, 1300, 700, -277, -1383, -1805, -3193, +-2929, -4218, -3352, -4265, -2927, -3419, -1785, -1831, +-191, 287, 1500, 2431, 2839, 3960, 3485, 4524, +3317, 4120, 2396, 2843, 913, 840, -786, -1477, +-2269, -3435, -3188, -4498, -3346, -4521, -2744, -3607, +-1557, -1901, -53, 361, 1455, 2615, 2656, 4148, +3278, 4616, 3199, 4106, 2460, 2765, 1213, 717, +-298, -1589, -1768, -3439, -2834, -4360, -3264, -4330, +-2986, -3442, -2101, -1766, -771, 424, 779, 2520, +2212, 3908, 3166, 4358, 3421, 3940, 2968, 2693, +1858, 704, 262, -1541, -1420, -3353, -2696, -4297, +-3305, -4308, -3197, -3407, -2380, -1666, -984, 591, +640, 2740, 2094, 4131, 3041, 4464, 3271, 3826, +2753, 2355, 1623, 213, 142, -2068, -1369, -3718, +-2483, -4313, -2931, -3969, -2683, -2835, -1873, -981, +-644, 1209, 765, 3006, 1960, 3900, 2613, 3890, +2641, 3137, 2147, 1684, 1192, -256, -102, -2105, +-1364, -3299, -2185, -3655, -2430, -3282, -2194, -2269, +-1509, -699, -414, 1095, 828, 2552, 1849, 3266, +2404, 3260, 2429, 2686, 1938, 1526, 993, -110, +-217, -1720, -1396, -2789, -2216, -3185, -2501, -3018, +-2215, -2264, -1432, -870, -301, 862, 951, 2349, +2007, 3188, 2590, 3386, 2567, 2949, 2013, 1717, +1010, -152, -306, -1999, -1615, -3253, -2517, -3786, +-2786, -3573, -2429, -2447, -1535, -511, -245, 1619, +1171, 3256, 2346, 4066, 2943, 3990, 2829, 2993, +2117, 1167, 955, -1034, -475, -2921, -1874, -4010, +-2809, -4170, -3051, -3449, -2611, -1906, -1611, 179, +-210, 2184, 1337, 3517, 2600, 4005, 3200, 3710, +3009, 2619, 2208, 836, 975, -1150, -535, -2708, +-1987, -3543, -2938, -3670, -3149, -3081, -2683, -1759, +-1691, 15, -316, 1666, 1217, 2766, 2523, 3263, +3198, 3155, 3127, 2342, 2432, 939, 1218, -609, +-349, -1843, -1875, -2602, -2911, -2882, -3263, -2577, +-2917, -1627, -1928, -292, -484, 965, 1112, 1872, +2470, 2404, 3253, 2462, 3252, 1898, 2529, 853, +1278, -284, -280, -1201, -1821, -1830, -2919, -2122, +-3264, -1913, -2866, -1180, -1880, -212, -470, 620, +1106, 1218, 2435, 1640, 3127, 1767, 3057, 1410, +2339, 689, 1145, -59, -322, -680, -1764, -1246, +-2756, -1666, -3019, -1656, -2605, -1174, -1714, -503, +-463, 157, 1010, 868, 2287, 1572, 2979, 1934, +2935, 1738, 2280, 1137, 1163, 351, -263, -543, +-1731, -1477, -2839, -2163, -3202, -2270, -2772, -1769, +-1749, -909, -336, 88, 1250, 1163, 2618, 2113, +3334, 2537, 3210, 2261, 2326, 1513, 922, 545, +-698, -580, -2212, -1708, -3246, -2457, -3476, -2557, +-2833, -2092, -1540, -1284, 66, -244, 1688, 940, +2965, 1980, 3535, 2527, 3202, 2472, 2140, 1963, +699, 1108, -881, -62, -2347, -1316, -3305, -2233, +-3421, -2560, -2767, -2363, -1574, -1752, -28, -742, +1600, 534, 2875, 1683, 3420, 2369, 3164, 2505, +2264, 2137, 934, 1309, -623, 130, -2121, -1106, +-3140, -2039, -3381, -2422, -2863, -2263, -1761, -1681, +-270, -709, 1358, 525, 2684, 1616, 3335, 2217, +3164, 2313, 2286, 1990, 924, 1191, -632, -3, +-2016, -1190, -2930, -2032, -3155, -2415, -2632, -2298, +-1465, -1647, 21, -555, 1434, 716, 2477, 1812, +2923, 2455, 2637, 2540, 1692, 2095, 403, 1137, +-871, -191, -1900, -1466, -2504, -2313, -2516, -2656, +-1906, -2505, -876, -1751, 280, -472, 1385, 895, +2232, 1954, 2551, 2606, 2191, 2775, 1284, 2288, +111, 1181, -1082, -187, -2051, -1458, -2592, -2433, +-2508, -2914, -1772, -2729, -583, -1872, 732, -557, +1928, 889, 2812, 2155, 3043, 2974, 2355, 3122, +936, 2490, -641, 1199, -1957, -407, -2889, -1937, +-3233, -3061, -2701, -3480, -1382, -3009, 211, -1721, +1635, 22, 2721, 1790, 3267, 3183, 3024, 3808, +1926, 3419, 291, 2090, -1294, 204, -2404, -1752, +-2951, -3289, -2942, -3991, -2209, -3654, -859, -2365, +586, -442, 1683, 1595, 2393, 3204, 2697, 3984, +2361, 3741, 1356, 2537, 61, 719, -1061, -1196, +-1826, -2788, -2224, -3727, -2153, -3742, -1519, -2826, +-518, -1279, 457, 517, 1195, 2188, 1716, 3344, +1916, 3677, 1579, 3148, 743, 1933, -213, 252, +-945, -1548, -1425, -2989, -1608, -3659, -1351, -3450, +-647, -2480, 157, -894, 767, 987, 1190, 2614, +1429, 3547, 1300, 3631, 672, 2843, -188, 1290, +-908, -641, -1319, -2363, -1412, -3434, -1134, -3624, +-483, -2903, 281, -1444, 853, 408, 1158, 2150, +1251, 3258, 1105, 3464, 631, 2780, -68, 1375, +-710, -424, -1059, -2055, -1095, -3002, -936, -3112, +-584, -2444, -79, -1158, 390, 414, 611, 1795, +635, 2597, 639, 2666, 602, 2037, 404, 903, +61, -408, -220, -1509, -319, -2098, -314, -2092, +-331, -1572, -351, -680, -270, 337, -148, 1152, +-131, 1519, -145, 1422, 26, 994, 309, 366, +431, -294, 415, -778, 459, -932, 462, -759, +230, -377, -139, 61, -382, 387, -512, 449, +-628, 251, -651, -86, -422, -408, 34, -564, +465, -452, 715, -71, 800, 441, 765, 906, +486, 1138, -69, 972, -651, 391, -958, -419, +-921, -1190, -679, -1695, -298, -1732, 252, -1155, +870, -105, 1246, 1012, 1148, 1870, 677, 2258, +75, 1994, -539, 1025, -1099, -344, -1417, -1611, +-1209, -2428, -516, -2595, 259, -1993, 819, -730, +1219, 817, 1441, 2158, 1155, 2865, 365, 2710, +-448, 1725, -906, 230, -1111, -1358, -1168, -2595, +-887, -3072, -174, -2588, 641, -1321, 1088, 268, +1106, 1751, 921, 2778, 543, 2983, -136, 2223, +-872, 821, -1162, -697, -884, -1965, -428, -2699, +-66, -2599, 350, -1692, 914, -401, 1198, 871, +878, 1881, 329, 2368, -39, 2110, -392, 1229, +-885, 114, -1076, -891, -743, -1592, -247, -1868, +67, -1672, 277, -1048, 503, -174, 659, 670, +658, 1225, 519, 1428, 383, 1393, 325, 1125, +237, 549, -24, -216, -396, -846, -681, -1201, +-840, -1398, -987, -1418, -1046, -1046, -724, -335, +49, 389, 918, 974, 1563, 1474, 1927, 1758, +1912, 1544, 1368, 895, 314, 83, -927, -768, +-1950, -1570, -2421, -2044, -2299, -1955, -1677, -1388, +-533, -547, 956, 469, 2231, 1485, 2817, 2169, +2696, 2286, 1922, 1830, 561, 920, -1004, -265, +-2249, -1408, -2840, -2199, -2650, -2488, -1737, -2172, +-373, -1247, 1092, 46, 2324, 1311, 2962, 2248, +2780, 2666, 1863, 2393, 464, 1446, -1078, 127, +-2384, -1226, -3057, -2290, -2900, -2762, -1957, -2503, +-490, -1619, 1124, -372, 2517, 969, 3337, 2096, +3352, 2708, 2499, 2623, 977, 1872, -840, 698, +-2473, -595, -3505, -1799, -3664, -2669, -2834, -2862, +-1195, -2213, 728, -998, 2383, 353, 3435, 1617, +3718, 2606, 3131, 2953, 1736, 2411, -124, 1171, +-1906, -331, -3072, -1717, -3398, -2669, -2910, -2892, +-1729, -2298, -86, -1058, 1519, 462, 2514, 1810, +2766, 2599, 2472, 2633, 1768, 1976, 635, 827, +-653, -514, -1602, -1694, -2001, -2379, -1980, -2357, +-1610, -1690, -840, -678, 145, 373, 999, 1270, +1545, 1846, 1802, 1916, 1758, 1488, 1338, 824, +569, 107, -365, -599, -1229, -1167, -1811, -1438, +-1985, -1441, -1646, -1296, -789, -910, 378, -212, +1456, 538, 2122, 1111, 2322, 1561, 2019, 1863, +1157, 1721, -137, 967, -1401, -119, -2185, -1168, +-2367, -1978, -2021, -2403, -1190, -2250, 49, -1368, +1332, 70, 2154, 1499, 2326, 2386, 2027, 2604, +1416, 2242, 510, 1270, -525, -215, -1317, -1656, +-1681, -2427, -1745, -2394, -1622, -1833, -1158, -958, +-307, 156, 595, 1216, 1266, 1784, 1763, 1715, +2112, 1304, 1999, 860, 1324, 381, 339, -193, +-710, -692, -1681, -952, -2316, -1083, -2325, -1256, +-1678, -1300, -545, -938, 751, -269, 1866, 453, +2518, 1163, 2528, 1789, 1849, 2008, 642, 1596, +-716, 691, -1793, -421, -2305, -1440, -2188, -2059, +-1485, -2109, -292, -1593, 1016, -605, 1926, 576, +2280, 1500, 2158, 1845, 1516, 1670, 364, 1124, +-846, 291, -1687, -637, -2089, -1319, -2054, -1493, +-1514, -1189, -525, -665, 630, -117, 1625, 455, +2200, 1010, 2310, 1266, 2000, 1022, 1247, 542, +156, 143, -936, -255, -1745, -798, -2219, -1215, +-2315, -1153, -1911, -761, -996, -365, 241, 47, +1454, 598, 2353, 1099, 2825, 1256, 2738, 1056, +1985, 691, 699, 251, -720, -269, -1950, -837, +-2783, -1282, -2986, -1390, -2408, -1157, -1134, -705, +439, -96, 1861, 629, 2793, 1289, 3065, 1624, +2576, 1509, 1399, 986, -102, 156, -1456, -779, +-2313, -1514, -2524, -1764, -2083, -1420, -1103, -623, +176, 357, 1365, 1207, 2106, 1652, 2292, 1490, +1981, 714, 1164, -368, -13, -1268, -1141, -1655, +-1823, -1480, -2004, -804, -1793, 270, -1145, 1372, +-56, 1958, 1169, 1783, 2038, 1023, 2401, -1, +2339, -1036, 1732, -1815, 468, -2041, -1049, -1593, +-2168, -653, -2669, 375, -2619, 1159, -1919, 1583, +-531, 1629, 1120, 1289, 2406, 627, 2996, -166, +2906, -820, 2193, -1188, 901, -1287, -712, -1174, +-2091, -796, -2781, -157, -2701, 501, -1978, 966, +-753, 1194, 734, 1148, 1992, 777, 2586, 153, +2409, -537, 1684, -1078, 622, -1273, -582, -1038, +-1582, -515, -1999, 126, -1712, 795, -939, 1276, +31, 1306, 955, 880, 1596, 259, 1698, -386, +1183, -1014, 314, -1434, -501, -1407, -1043, -972, +-1271, -339, -1105, 379, -492, 1101, 334, 1591, +987, 1620, 1299, 1231, 1289, 575, 948, -230, +271, -1036, -487, -1616, -996, -1771, -1119, -1461, +-936, -817, -551, -51, -38, 685, 518, 1277, +1019, 1527, 1267, 1375, 1117, 1019, 642, 586, +66, 50, -497, -540, -982, -983, -1173, -1235, +-910, -1409, -358, -1412, 217, -1043, 761, -313, +1268, 583, 1466, 1425, 1106, 2002, 367, 2118, +-425, 1648, -1110, 636, -1536, -664, -1431, -1789, +-781, -2352, 118, -2251, 970, -1573, 1565, -459, +1720, 824, 1364, 1807, 654, 2106, -197, 1755, +-977, 1068, -1494, 272, -1536, -551, -1026, -1227, +-210, -1456, 525, -1242, 1044, -922, 1372, -632, +1325, -180, 748, 469, -30, 985, -526, 1190, +-719, 1260, -796, 1239, -677, 834, -208, -39, +367, -969, 677, -1523, 665, -1674, 524, -1536, +289, -1038, -101, -119, -470, 924, -583, 1581, +-392, 1712, -86, 1505, 176, 1053, 373, 308, +553, -584, 635, -1240, 479, -1480, 175, -1467, +-51, -1286, -190, -798, -387, 12, -533, 875, +-417, 1470, -165, 1701, -45, 1582, 4, 1087, +209, 197, 547, -882, 742, -1696, 678, -1889, +478, -1519, 234, -837, -98, 71, -482, 1089, +-717, 1716, -726, 1549, -555, 881, -264, 199, +99, -427, 438, -1018, 715, -1229, 902, -820, +866, -168, 526, 282, 30, 525, -371, 661, +-629, 545, -802, 116, -799, -353, -483, -552, +11, -474, 419, -281, 690, -36, 913, 304, +971, 657, 664, 795, 74, 570, -483, 69, +-818, -442, -955, -814, -830, -1060, -377, -1051, +252, -575, 734, 253, 936, 1011, 892, 1402, +616, 1411, 165, 1005, -307, 147, -612, -888, +-671, -1616, -475, -1714, -140, -1228, 148, -393, +309, 554, 373, 1353, 300, 1657, 53, 1271, +-199, 462, -192, -321, 77, -900, 342, -1188, +424, -983, 388, -327, 297, 334, 15, 587, +-456, 481, -817, 227, -804, -106, -505, -425, +-103, -509, 357, -193, 836, 388, 1168, 845, +1109, 902, 626, 600, -42, 104, -613, -514, +-1008, -1157, -1193, -1470, -1038, -1170, -489, -424, +220, 348, 780, 966, 1110, 1461, 1220, 1654, +983, 1251, 381, 352, -275, -580, -707, -1199, +-934, -1530, -993, -1654, -735, -1348, -214, -476, +276, 591, 575, 1319, 746, 1613, 790, 1676, +602, 1390, 241, 501, -121, -688, -348, -1476, +-451, -1631, -439, -1471, -300, -1145, -76, -433, +71, 608, 56, 1392, 17, 1476, 53, 1121, +75, 786, 49, 403, 122, -282, 330, -1019, +468, -1257, 402, -995, 268, -745, 125, -586, +-191, -107, -700, 681, -1051, 1216, -968, 1210, +-570, 977, -37, 742, 568, 253, 1161, -619, +1500, -1433, 1379, -1610, 780, -1167, -62, -572, +-882, 13, -1537, 776, -1833, 1509, -1549, 1575, +-707, 899, 336, 149, 1211, -307, 1739, -716, +1831, -1116, 1437, -1068, 654, -425, -296, 234, +-1134, 388, -1638, 234, -1717, 219, -1409, 300, +-760, 120, 134, -203, 1028, -130, 1613, 337, +1717, 532, 1456, 206, 927, -131, 101, -155, +-907, -231, -1655, -567, -1840, -695, -1584, -292, +-998, 206, -22, 310, 1144, 232, 1926, 353, +1997, 531, 1464, 390, 555, 8, -544, -186, +-1522, -123, -1984, -201, -1727, -534, -930, -699, +49, -439, 979, -71, 1705, 138, 1935, 445, +1414, 939, 381, 1152, -637, 768, -1346, 85, +-1748, -508, -1686, -974, -1006, -1363, 0, -1436, +837, -925, 1319, 9, 1531, 883, 1437, 1394, +931, 1564, 116, 1426, -682, 911, -1230, 52, +-1467, -838, -1359, -1397, -871, -1537, -122, -1393, +591, -1048, 1042, -423, 1207, 421, 1066, 1124, +617, 1439, 51, 1457, -399, 1274, -649, 786, +-763, -19, -678, -838, -310, -1361, 128, -1524, +295, -1359, 204, -869, 99, -118, 38, 646, +-43, 1154, -107, 1301, -2, 1119, 218, 691, +338, 129, 239, -461, -2, -883, -210, -954, +-287, -744, -299, -464, -279, -148, -119, 284, +191, 662, 439, 733, 410, 545, 157, 289, +-137, -25, -375, -402, -582, -655, -661, -612, +-432, -342, 87, 14, 619, 354, 899, 574, +898, 572, 699, 320, 354, -53, -174, -375, +-768, -543, -1134, -498, -1144, -253, -935, 108, +-549, 458, 95, 592, 827, 411, 1281, 56, +1289, -274, 982, -501, 501, -602, -84, -484, +-680, -124, -1083, 321, -1137, 607, -867, 639, +-438, 494, -9, 282, 365, 32, 669, -279, +771, -540, 562, -582, 250, -493, 81, -437, +6, -325, -193, -36, -439, 347, -483, 605, +-379, 676, -358, 704, -320, 673, -15, 369, +466, -197, 778, -697, 706, -895, 390, -869, +41, -726, -368, -388, -894, 108, -1203, 498, +-917, 643, -185, 649, 484, 595, 911, 450, +1211, 213, 1282, -45, 856, -232, -66, -377, +-957, -530, -1307, -624, -1208, -590, -1005, -383, +-614, -2, 137, 380, 903, 604, 1122, 684, +814, 618, 545, 330, 431, -130, 103, -476, +-412, -536, -604, -436, -369, -261, -226, 54, +-440, 393, -536, 477, -219, 233, 72, -99, +45, -296, 82, -366, 442, -377, 721, -257, +562, 70, 215, 427, 74, 559, -21, 427, +-374, 219, -786, 35, -810, -224, -460, -513, +-129, -563, 57, -310, 318, -8, 696, 173, +837, 295, 529, 400, 40, 380, -278, 177, +-491, -159, -765, -460, -869, -529, -486, -375, +169, -156, 622, 126, 759, 515, 738, 799, +584, 720, 176, 337, -367, -126, -710, -584, +-721, -922, -563, -932, -352, -582, -91, -58, +213, 439, 453, 734, 492, 709, 395, 454, +312, 150, 299, -113, 258, -283, 77, -238, +-202, 32, -410, 243, -589, 154, -785, -116, +-790, -419, -452, -718, 81, -836, 542, -584, +870, 2, 1068, 677, 982, 1164, 527, 1288, +-73, 1014, -588, 442, -915, -262, -1041, -945, +-940, -1346, -572, -1223, -72, -718, 342, -195, +622, 210, 796, 549, 781, 781, 532, 800, +194, 607, -15, 396, -160, 280, -410, 118, +-645, -212, -657, -621, -511, -898, -368, -918, +-203, -786, 86, -530, 455, 29, 710, 808, +801, 1376, 767, 1423, 611, 1042, 263, 452, +-297, -277, -908, -1056, -1278, -1602, -1244, -1653, +-897, -1175, -320, -343, 469, 538, 1269, 1245, +1659, 1701, 1493, 1766, 953, 1286, 174, 383, +-762, -593, -1553, -1370, -1833, -1846, -1491, -1918, +-710, -1419, 203, -424, 1014, 680, 1504, 1511, +1498, 1905, 1009, 1833, 310, 1276, -349, 300, +-814, -750, -1010, -1444, -921, -1630, -587, -1409, +-193, -853, 110, -47, 292, 676, 373, 984, +385, 903, 400, 675, 381, 393, 290, 34, +151, -294, -24, -369, -211, -181, -398, -16, +-516, -86, -429, -278, -202, -375, -27, -365, +108, -315, 258, -161, 327, 208, 226, 661, +124, 901, 200, 794, 318, 444, 305, 14, +212, -475, 47, -984, -283, -1222, -723, -962, +-1034, -382, -943, 230, -498, 705, 98, 1013, +760, 1140, 1354, 973, 1644, 492, 1426, -116, +660, -615, -346, -894, -1204, -1006, -1788, -984, +-1946, -727, -1529, -268, -659, 200, 329, 574, +1162, 891, 1758, 1137, 1998, 1151, 1652, 778, +862, 164, 33, -406, -759, -876, -1514, -1220, +-1953, -1297, -1836, -1009, -1300, -415, -558, 272, +306, 828, 1238, 1172, 1964, 1190, 2127, 837, +1646, 295, 781, -237, -141, -647, -1022, -862, +-1733, -830, -1977, -551, -1611, -114, -879, 315, +-49, 601, 787, 635, 1488, 435, 1793, 159, +1576, -151, 978, -481, 238, -658, -499, -560, +-1128, -250, -1504, 124, -1505, 446, -1097, 709, +-427, 798, 321, 537, 1036, 83, 1563, -288, +1678, -552, 1272, -737, 453, -744, -434, -504, +-1085, -116, -1472, 255, -1486, 514, -1050, 565, +-341, 439, 397, 333, 957, 222, 1189, -46, +1113, -309, 795, -340, 290, -248, -245, -196, +-619, -111, -676, 94, -531, 258, -431, 199, +-357, 31, -159, -97, 96, -263, 219, -441, +187, -429, 231, -193, 394, 145, 437, 546, +354, 951, 282, 1069, 194, 699, -30, 51, +-334, -593, -571, -1168, -667, -1524, -635, -1408, +-421, -774, -29, 178, 434, 1110, 865, 1686, +1079, 1712, 981, 1225, 605, 426, 16, -468, +-645, -1247, -1133, -1635, -1306, -1467, -1089, -879, +-489, -143, 326, 564, 1077, 1077, 1496, 1242, +1478, 1065, 1010, 652, 169, 100, -738, -434, +-1306, -741, -1389, -847, -1124, -856, -661, -654, +3, -176, 715, 323, 1107, 590, 1059, 650, +786, 593, 440, 419, 38, 142, -276, -166, +-379, -388, -339, -391, -369, -213, -519, -22, +-632, 67, -580, 2, -390, -179, -82, -313, +370, -294, 861, -184, 1222, 4, 1287, 360, +1010, 824, 434, 1061, -344, 797, -1098, 184, +-1545, -472, -1579, -1060, -1195, -1465, -464, -1414, +409, -762, 1210, 234, 1686, 1089, 1677, 1561, +1233, 1627, 470, 1226, -440, 374, -1163, -705, +-1452, -1598, -1274, -1849, -800, -1405, -159, -580, +561, 377, 1050, 1233, 1098, 1667, 794, 1519, +327, 870, -149, -32, -500, -918, -668, -1575, +-550, -1702, -213, -1119, 109, -105, 307, 837, +297, 1410, 150, 1594, 26, 1353, -75, 547, +-131, -594, -60, -1442, 93, -1709, 255, -1459, +293, -752, 145, 255, -36, 1232, -197, 1761, +-386, 1594, -473, 932, -363, 83, -140, -811, +115, -1504, 355, -1748, 595, -1429, 732, -575, +666, 470, 449, 1265, 175, 1644, -200, 1587, +-672, 1112, -1012, 309, -1032, -614, -781, -1342, +-427, -1713, 73, -1672, 784, -1120, 1459, -212, +1685, 711, 1357, 1468, 700, 1848, -115, 1719, +-977, 1191, -1621, 305, -1768, -786, -1379, -1665, +-624, -2036, 260, -1879, 1046, -1250, 1557, -218, +1676, 992, 1297, 1876, 511, 2119, -366, 1850, +-983, 1149, -1241, 18, -1272, -1186, -997, -1973, +-331, -2132, 400, -1705, 832, -845, 1063, 259, +1132, 1272, 848, 1842, 174, 1907, -575, 1491, +-978, 625, -1029, -382, -903, -1212, -503, -1749, +235, -1797, 966, -1248, 1260, -343, 1039, 537, +566, 1169, -18, 1525, -695, 1527, -1180, 997, +-1126, 90, -610, -701, 32, -1141, 595, -1299, +1027, -1149, 1201, -563, 923, 266, 245, 835, +-535, 944, -1000, 868, -1005, 695, -718, 226, +-278, -436, 253, -863, 732, -814, 974, -480, +892, -188, 565, 77, 142, 449, -394, 669, +-868, 515, -961, 232, -701, 68, -317, -47, +105, -241, 522, -430, 793, -407, 790, -227, +587, -172, 299, -219, -113, -111, -547, 187, +-767, 466, -693, 570, -415, 568, -65, 528, +267, 284, 546, -166, 644, -560, 485, -809, +191, -904, -93, -764, -282, -385, -397, 129, +-422, 592, -305, 875, -60, 994, 180, 870, +315, 491, 367, 96, 404, -272, 377, -711, +164, -1022, -99, -998, -226, -738, -269, -423, +-338, -96, -359, 363, -213, 876, 66, 1129, +295, 1048, 341, 783, 314, 419, 332, -32, +264, -597, 20, -1095, -183, -1209, -117, -1013, +87, -720, 98, -305, -47, 226, -118, 741, +-161, 1070, -354, 1124, -568, 1031, -496, 815, +-67, 352, 429, -234, 734, -778, 935, -1241, +990, -1483, 722, -1385, 57, -959, -768, -257, +-1275, 575, -1295, 1351, -1056, 1856, -599, 1896, +165, 1446, 968, 566, 1384, -508, 1275, -1338, +916, -1797, 481, -1986, -172, -1724, -890, -913, +-1231, 101, -1108, 936, -744, 1492, -365, 1837, +70, 1882, 660, 1440, 1143, 646, 1240, -192, +1027, -991, 676, -1687, 147, -2091, -550, -2037, +-1204, -1498, -1490, -628, -1306, 391, -803, 1428, +-125, 2235, 625, 2521, 1342, 2196, 1772, 1361, +1711, 230, 1141, -1006, 214, -2102, -765, -2680, +-1478, -2562, -1773, -1912, -1629, -888, -1072, 376, +-233, 1592, 612, 2405, 1172, 2611, 1393, 2245, +1378, 1443, 1081, 346, 461, -801, -216, -1698, +-662, -2210, -858, -2263, -971, -1808, -955, -1032, +-685, -219, -277, 572, 44, 1350, 264, 1893, +559, 1996, 801, 1780, 794, 1378, 642, 657, +537, -346, 354, -1295, -72, -2007, -576, -2435, +-831, -2376, -800, -1691, -749, -554, -662, 723, +-309, 1868, 239, 2647, 704, 2827, 941, 2279, +1004, 1143, 938, -222, 647, -1424, 119, -2222, +-427, -2557, -780, -2361, -945, -1562, -941, -418, +-732, 611, -388, 1357, 24, 1889, 457, 2110, +847, 1822, 1059, 1105, 1014, 279, 727, -483, +332, -1144, -101, -1601, -573, -1762, -935, -1564, +-1146, -963, -1166, -192, -869, 396, -318, 848, +276, 1294, 830, 1507, 1293, 1238, 1500, 713, +1281, 331, 741, 45, 164, -409, -469, -885, +-1224, -1094, -1762, -1114, -1783, -1101, -1353, -996, +-671, -643, 116, -59, 1001, 577, 1790, 1176, +2131, 1701, 1883, 1934, 1246, 1692, 465, 1045, +-464, 154, -1476, -851, -2161, -1874, -2201, -2619, +-1805, -2669, -1115, -1994, -105, -913, 1073, 390, +1971, 1716, 2242, 2713, 2063, 3092, 1676, 2708, +948, 1637, -149, 180, -1228, -1266, -1949, -2345, +-2226, -2877, -2127, -2786, -1659, -1959, -752, -636, +414, 605, 1409, 1449, 2005, 1928, 2279, 2083, +2275, 1786, 1754, 1000, 601, 155, -745, -311, +-1777, -553, -2402, -797, -2638, -959, -2264, -981, +-1252, -957, 55, -955, 1234, -880, 2079, -581, +2543, -75, 2429, 575, 1641, 1300, 462, 1815, +-699, 1903, -1632, 1636, -2146, 1069, -2118, 193, +-1586, -845, -699, -1760, 281, -2261, 1078, -2263, +1475, -1888, 1434, -1214, 1079, -292, 515, 778, +-66, 1774, -405, 2355, -487, 2451, -407, 2265, +-229, 1736, -55, 708, 10, -607, -108, -1812, +-402, -2645, -632, -3030, -582, -2922, -319, -2182, +40, -848, 458, 719, 928, 2156, 1216, 3207, +1110, 3633, 704, 3287, 212, 2200, -319, 638, +-912, -1054, -1369, -2603, -1407, -3665, -1029, -3863, +-549, -3152, -84, -1826, 439, -254, 993, 1335, +1369, 2763, 1352, 3639, 989, 3583, 479, 2749, +-84, 1557, -666, 181, -1141, -1280, -1297, -2542, +-1095, -3226, -743, -3181, -322, -2608, 184, -1736, +619, -547, 805, 900, 827, 2261, 763, 3105, +593, 3265, 337, 2932, 93, 2179, -99, 835, +-349, -906, -627, -2410, -809, -3298, -790, -3593, +-617, -3293, -371, -2230, -33, -525, 392, 1257, +773, 2670, 929, 3587, 777, 3794, 448, 3093, +209, 1654, 68, -128, -136, -1799, -295, -2993, +-273, -3524, -258, -3245, -462, -2136, -774, -539, +-893, 1037, -764, 2160, -495, 2626, -5, 2459, +757, 1716, 1504, 584, 1880, -512, 1779, -1208, +1157, -1401, 145, -1184, -989, -708, -1914, -91, +-2326, 430, -2145, 569, -1474, 330, -472, -84, +621, -503, 1475, -762, 1919, -741, 1902, -416, +1492, 171, 858, 815, 106, 1315, -571, 1575, +-993, 1459, -1204, 919, -1227, 119, -1049, -784, +-767, -1607, -471, -2091, -182, -2118, 134, -1732, +464, -1013, 767, -6, 1039, 1112, 1264, 2016, +1327, 2489, 1205, 2483, 833, 1992, 114, 1118, +-794, 56, -1638, -1093, -2220, -2119, -2468, -2662, +-2196, -2648, -1223, -2281, 191, -1585, 1539, -452, +2626, 934, 3309, 2093, 3217, 2803, 2250, 3174, +724, 3052, -894, 2136, -2326, 613, -3426, -1018, +-3802, -2462, -3176, -3508, -1818, -3829, -156, -3247, +1495, -1935, 2896, -216, 3753, 1599, 3758, 3089, +2871, 3807, 1377, 3585, -423, 2597, -2232, 1112, +-3569, -570, -4085, -2089, -3618, -3044, -2288, -3218, +-452, -2681, 1456, -1607, 3038, -191, 3950, 1181, +3938, 2097, 2942, 2445, 1145, 2259, -874, 1549, +-2514, 450, -3511, -677, -3780, -1486, -3168, -1849, +-1678, -1766, 202, -1174, 1858, -162, 3078, 851, +3741, 1510, 3475, 1760, 2151, 1560, 301, 792, +-1405, -386, -2721, -1488, -3568, -2138, -3606, -2271, +-2570, -1804, -832, -684, 999, 784, 2533, 2097, +3495, 2921, 3608, 3100, 2758, 2507, 1239, 1134, +-470, -685, -1972, -2369, -3045, -3469, -3481, -3768, +-3096, -3173, -1893, -1816, -288, -70, 1204, 1695, +2409, 3142, 3168, 3858, 3217, 3641, 2502, 2677, +1256, 1296, -238, -292, -1747, -1862, -2940, -3065, +-3421, -3629, -3068, -3499, -2028, -2736, -493, -1465, +1235, 141, 2654, 1814, 3328, 3167, 3168, 3872, +2322, 3750, 912, 2817, -799, 1279, -2207, -505, +-2915, -2167, -2910, -3368, -2287, -3790, -1085, -3265, +439, -2044, 1762, -619, 2487, 716, 2554, 1907, +2081, 2758, 1131, 2882, -105, 2304, -1257, 1503, +-1956, 713, -2154, -224, -1940, -1222, -1243, -1912, +-176, -2155, 875, -2066, 1622, -1680, 1977, -947, +1887, 60, 1320, 1076, 412, 1749, -544, 1909, +-1335, 1650, -1835, 1115, -1854, 293, -1359, -648, +-620, -1200, 131, -1138, 833, -769, 1432, -338, +1729, 194, 1521, 673, 961, 703, 283, 211, +-427, -366, -1065, -728, -1392, -967, -1379, -1039, +-1140, -662, -760, 141, -303, 963, 251, 1468, +780, 1632, 1094, 1554, 1192, 1156, 1201, 353, +1100, -635, 772, -1412, 218, -1824, -417, -1970, +-1009, -1854, -1530, -1294, -1851, -354, -1779, 573, +-1311, 1264, -512, 1761, 532, 2060, 1620, 1999, +2445, 1510, 2696, 780, 2330, 54, 1439, -641, +174, -1347, -1183, -1932, -2280, -2191, -2926, -2081, +-3029, -1704, -2446, -1116, -1218, -273, 339, 825, +1745, 1912, 2730, 2658, 3156, 2970, 2883, 2881, +1994, 2285, 727, 1085, -652, -497, -1847, -2039, +-2642, -3231, -2896, -3893, -2505, -3876, -1585, -3085, +-434, -1570, 678, 339, 1517, 2168, 1997, 3569, +2123, 4362, 1858, 4339, 1346, 3380, 747, 1749, +66, -115, -630, -1900, -1186, -3338, -1512, -4131, +-1690, -4119, -1737, -3362, -1534, -2081, -959, -512, +-150, 1085, 685, 2442, 1455, 3357, 2064, 3703, +2382, 3440, 2205, 2653, 1483, 1501, 451, 89, +-573, -1372, -1458, -2568, -2133, -3298, -2445, -3531, +-2301, -3252, -1727, -2430, -821, -1159, 230, 271, +1208, 1608, 1977, 2731, 2478, 3481, 2581, 3729, +2134, 3377, 1228, 2384, 135, 931, -922, -700, +-1922, -2314, -2700, -3667, -2889, -4425, -2343, -4326, +-1359, -3353, -275, -1718, 877, 332, 2014, 2439, +2778, 4120, 2771, 4948, 2115, 4740, 1229, 3535, +232, 1591, -904, -684, -1916, -2808, -2419, -4254, +-2342, -4685, -1869, -4098, -1089, -2721, -44, -870, +963, 1080, 1578, 2672, 1805, 3463, 1781, 3415, +1467, 2765, 847, 1676, 106, 326, -500, -911, +-961, -1688, -1326, -1961, -1454, -1912, -1243, -1635, +-787, -1105, -267, -447, 261, 109, 752, 455, +1142, 712, 1282, 978, 1118, 1154, 744, 1123, +266, 937, -235, 672, -686, 295, -940, -223, +-946, -806, -773, -1234, -529, -1329, -277, -1153, +-24, -855, 251, -374, 532, 347, 782, 1044, +940, 1359, 907, 1275, 675, 1009, 316, 600, +-157, -22, -720, -728, -1217, -1183, -1449, -1235, +-1322, -1043, -871, -731, -150, -221, 629, 431, +1226, 935, 1562, 1109, 1621, 1045, 1330, 874, +696, 557, -57, 63, -744, -467, -1289, -868, +-1680, -1118, -1776, -1197, -1474, -1048, -918, -670, +-256, -147, 570, 423, 1542, 1002, 2280, 1460, +2449, 1570, 2072, 1291, 1312, 748, 232, 56, +-1044, -629, -2156, -1191, -2772, -1521, -2801, -1507, +-2258, -1189, -1174, -698, 255, -135, 1575, 391, +2409, 763, 2705, 952, 2514, 1055, 1833, 1171, +797, 1182, -251, 974, -1121, 622, -1752, 189, +-2081, -413, -2038, -1168, -1676, -1831, -1141, -2169, +-501, -2134, 199, -1749, 932, -883, 1564, 442, +1952, 1786, 2018, 2711, 1801, 3136, 1325, 3059, +555, 2369, -477, 1010, -1554, -709, -2276, -2237, +-2469, -3294, -2221, -3770, -1526, -3503, -438, -2432, +700, -826, 1536, 885, 1963, 2368, 2001, 3425, +1648, 3795, 977, 3314, 219, 2137, -347, 637, +-635, -812, -683, -2001, -628, -2806, -673, -3085, +-829, -2734, -1012, -1896, -1091, -855, -993, 175, +-671, 1114, -69, 1874, 799, 2283, 1699, 2245, +2279, 1896, 2382, 1384, 1954, 671, 1060, -221, +-149, -1059, -1426, -1601, -2431, -1871, -2862, -1940, +-2658, -1738, -1962, -1234, -885, -534, 427, 234, +1606, 961, 2326, 1547, 2541, 1897, 2333, 1925, +1713, 1632, 745, 1046, -309, 266, -1172, -538, +-1693, -1199, -1901, -1606, -1815, -1702, -1436, -1486, +-895, -1026, -352, -475, 146, 42, 668, 493, +1172, 759, 1529, 811, 1635, 821, 1542, 892, +1277, 936, 751, 883, -19, 751, -856, 565, +-1548, 210, -1991, -432, -2139, -1190, -1863, -1767, +-1127, -2012, -157, -1942, 816, -1536, 1605, -703, +2038, 505, 2085, 1707, 1837, 2505, 1294, 2762, +515, 2506, -321, 1783, -1081, 621, -1759, -781, +-2285, -1974, -2299, -2631, -1691, -2755, -803, -2366, +92, -1479, 1083, -262, 2071, 920, 2571, 1712, +2336, 2055, 1618, 2036, 695, 1631, -444, 879, +-1623, 42, -2334, -582, -2305, -857, -1732, -922, +-913, -888, 38, -719, 983, -471, 1601, -318, +1676, -313, 1302, -323, 730, -228, 106, -72, +-483, 110, -878, 415, -973, 821, -743, 1145, +-291, 1262, 223, 1166, 543, 834, 513, 267, +203, -467, -186, -1229, -512, -1822, -720, -2102, +-648, -1968, -226, -1385, 372, -428, 857, 706, +1152, 1722, 1258, 2356, 992, 2561, 266, 2295, +-643, 1485, -1307, 277, -1557, -945, -1468, -1836, +-1079, -2360, -379, -2521, 468, -2170, 1094, -1323, +1310, -300, 1260, 631, 1076, 1391, 691, 1974, +101, 2262, -374, 2127, -541, 1613, -629, 861, +-865, 7, -1071, -915, -961, -1830, -687, -2484, +-466, -2603, -173, -2176, 433, -1343, 1111, -211, +1475, 1106, 1543, 2300, 1459, 2941, 1083, 2878, +233, 2261, -779, 1193, -1525, -257, -1922, -1671, +-2091, -2560, -1920, -2815, -1186, -2597, -72, -1899, +993, -676, 1812, 730, 2362, 1771, 2487, 2272, +2001, 2347, 988, 2005, -240, 1260, -1375, 267, +-2224, -651, -2577, -1250, -2288, -1511, -1487, -1515, +-405, -1306, 715, -946, 1666, -491, 2204, -69, +2136, 223, 1529, 515, 596, 864, -393, 1150, +-1165, 1265, -1476, 1213, -1382, 993, -987, 554, +-362, -93, 319, -752, 821, -1269, 961, -1605, +759, -1650, 332, -1335, -217, -743, -760, -77, +-1037, 516, -882, 1001, -437, 1384, 96, 1536, +640, 1343, 1137, 910, 1400, 450, 1270, 33, +816, -427, 147, -920, -621, -1223, -1306, -1198, +-1710, -1027, -1726, -843, -1422, -606, -904, -244, +-195, 162, 689, 458, 1435, 691, 1782, 991, +1827, 1271, 1693, 1376, 1295, 1286, 545, 1031, +-286, 569, -953, -192, -1509, -1089, -2011, -1867, +-2207, -2391, -1892, -2533, -1256, -2135, -568, -1216, +214, -8, 1253, 1247, 2255, 2392, 2748, 3197, +2718, 3323, 2311, 2699, 1450, 1557, 153, 200, +-1257, -1199, -2399, -2458, -3119, -3301, -3346, -3481, +-2915, -2932, -1811, -1838, -377, -489, 1007, 851, +2144, 2002, 2906, 2785, 3181, 3030, 2833, 2724, +1958, 2041, 852, 1116, -245, 61, -1251, -959, +-2114, -1764, -2649, -2255, -2664, -2486, -2233, -2460, +-1634, -2044, -899, -1200, 70, -113, 1117, 948, +1917, 1783, 2359, 2362, 2534, 2585, 2440, 2298, +1935, 1573, 1036, 673, -52, -178, -1163, -919, +-2154, -1492, -2800, -1747, -2894, -1688, -2480, -1567, +-1680, -1467, -588, -1219, 625, -718, 1645, -66, +2250, 614, 2444, 1343, 2293, 2121, 1856, 2695, +1190, 2724, 420, 2150, -313, 1133, -930, -162, +-1447, -1588, -1892, -2827, -2194, -3449, -2219, -3261, +-1857, -2449, -1132, -1245, -192, 200, 847, 1635, +1855, 2685, 2573, 3020, 2731, 2661, 2314, 1887, +1566, 916, 661, -109, -294, -978, -1189, -1495, +-1827, -1569, -2064, -1342, -1946, -1073, -1643, -820, +-1274, -548, -822, -310, -330, -215, 193, -148, +765, 165, 1377, 712, 1902, 1178, 2231, 1440, +2298, 1550, 1965, 1461, 1210, 1036, 163, 284, +-987, -512, -2030, -1120, -2798, -1542, -3158, -1824, +-3002, -1816, -2255, -1432, -1037, -863, 369, -334, +1691, 233, 2791, 966, 3522, 1680, 3562, 2067, +2846, 2085, 1668, 1849, 326, 1326, -1032, 474, +-2306, -598, -3155, -1605, -3325, -2289, -2886, -2532, +-2075, -2299, -1006, -1642, 181, -676, 1269, 453, +2099, 1441, 2495, 2001, 2473, 2141, 2145, 1949, +1632, 1444, 949, 611, 96, -293, -739, -880, +-1370, -1117, -1820, -1185, -2117, -1106, -2091, -855, +-1738, -516, -1266, -214, -702, -37, 58, 50, +933, 120, 1623, 238, 2038, 403, 2297, 567, +2316, 691, 1910, 758, 1098, 709, 110, 530, +-869, 284, -1753, -26, -2455, -380, -2792, -648, +-2569, -760, -1929, -815, -1084, -864, -122, -840, +956, -635, 1981, -323, 2644, -40, 2807, 299, +2575, 781, 2064, 1273, 1212, 1548, 84, 1487, +-1067, 1166, -1992, 690, -2628, 18, -2958, -770, +-2821, -1446, -2158, -1801, -1110, -1832, 74, -1670, +1168, -1279, 2099, -579, 2826, 228, 3116, 903, +2754, 1503, 1939, 2061, 967, 2337, -138, 2100, +-1379, 1479, -2455, 639, -2953, -436, -2861, -1589, +-2376, -2407, -1588, -2660, -579, -2457, 486, -1869, +1367, -878, 1947, 331, 2212, 1334, 2256, 1890, +2073, 2082, 1641, 2039, 947, 1711, 83, 1124, +-777, 476, -1582, -131, -2279, -730, -2700, -1345, +-2623, -1819, -2017, -1975, -1018, -1788, 176, -1342, +1327, -645, 2221, 293, 2696, 1268, 2639, 1872, +2039, 1929, 1094, 1608, 125, 1034, -697, 289, +-1339, -440, -1698, -905, -1677, -985, -1412, -757, +-1125, -400, -765, -64, -282, 102, 153, 65, +385, -181, 528, -569, 747, -816, 967, -733, +1078, -383, 1124, 92, 1166, 653, 1061, 1244, +671, 1657, 31, 1610, -676, 1112, -1333, 433, +-1930, -224, -2291, -835, -2128, -1361, -1442, -1664, +-513, -1647, 484, -1349, 1456, -936, 2238, -453, +2568, 164, 2306, 903, 1571, 1555, 657, 1871, +-238, 1883, -1033, 1730, -1615, 1246, -1833, 319, +-1666, -725, -1330, -1529, -970, -1962, -531, -2095, +35, -1908, 559, -1325, 805, -478, 855, 358, +1028, 1000, 1280, 1374, 1250, 1535, 964, 1514, +715, 1247, 439, 813, -110, 372, -842, -12, +-1391, -423, -1630, -833, -1732, -1076, -1673, -1120, +-1267, -1111, -470, -1024, 491, -705, 1305, -267, +1834, 77, 2052, 370, 1909, 723, 1343, 980, +560, 999, -196, 886, -750, 843, -1135, 810, +-1395, 629, -1388, 330, -1091, -6, -710, -393, +-437, -888, -230, -1473, -16, -1972, 205, -2135, +430, -1870, 708, -1163, 1048, -86, 1278, 1196, +1301, 2394, 1132, 3158, 775, 3285, 276, 2731, +-326, 1579, -966, 90, -1558, -1400, -1972, -2613, +-2071, -3276, -1775, -3266, -1110, -2665, -217, -1680, +803, -472, 1744, 778, 2384, 1794, 2536, 2410, +2170, 2646, 1496, 2507, 629, 1977, -386, 1199, +-1400, 343, -2068, -527, -2285, -1363, -2124, -1972, +-1659, -2224, -971, -2167, -204, -1866, 464, -1295, +1029, -516, 1497, 278, 1760, 1008, 1763, 1653, +1565, 2074, 1217, 2169, 655, 1990, -83, 1556, +-793, 849, -1310, -91, -1692, -1038, -1965, -1785, +-1913, -2275, -1478, -2407, -830, -2121, -102, -1451, +689, -512, 1479, 460, 2045, 1237, 2233, 1792, +1987, 2099, 1455, 2089, 745, 1717, -129, 1111, +-1046, 468, -1721, -234, -1971, -1014, -1947, -1660, +-1710, -1968, -1204, -1989, -454, -1762, 261, -1188, +753, -310, 1136, 541, 1524, 1162, 1804, 1607, +1745, 1839, 1385, 1699, 903, 1245, 287, 722, +-521, 184, -1366, -372, -1986, -872, -2249, -1242, +-2087, -1470, -1509, -1527, -641, -1342, 338, -877, +1225, -243, 1854, 454, 2074, 1111, 1908, 1535, +1469, 1632, 746, 1401, -151, 899, -915, 210, +-1290, -515, -1380, -1046, -1331, -1270, -1095, -1242, +-589, -943, -27, -374, 298, 263, 448, 713, +539, 875, 550, 825, 435, 563, 312, 31, +301, -607, 347, -967, 324, -868, 242, -471, +169, 42, 35, 654, -194, 1226, -462, 1387, +-713, 978, -854, 244, -829, -498, -650, -1134, +-340, -1525, 66, -1447, 506, -845, 872, -16, +1052, 641, 1001, 995, 771, 1092, 413, 881, +-26, 380, -472, -159, -824, -470, -912, -455, +-801, -257, -621, -4, -326, 229, 108, 357, +474, 304, 583, 21, 466, -398, 265, -689, +70, -721, -134, -577, -269, -299, -221, 103, +-19, 580, 173, 913, 276, 921, 380, 685, +505, 353, 409, -62, -8, -516, -464, -781, +-711, -676, -813, -338, -911, -44, -873, 151, +-474, 288, 141, 306, 580, 113, 846, -207, +1171, -449, 1424, -440, 1284, -177, 731, 184, +49, 512, -584, 729, -1156, 751, -1585, 521, +-1726, 99, -1518, -372, -1009, -695, -355, -807, +329, -701, 1032, -396, 1661, 5, 1957, 376, +1828, 574, 1397, 528, 752, 297, -69, 8, +-953, -220, -1606, -342, -1902, -407, -1912, -316, +-1659, 10, -1060, 385, -244, 561, 515, 542, +1089, 486, 1477, 335, 1713, -33, 1686, -467, +1349, -746, 826, -863, 278, -829, -242, -598, +-787, -187, -1347, 262, -1758, 664, -1822, 966, +-1578, 1046, -1185, 854, -651, 479, 80, 42, +937, -420, 1645, -816, 2026, -976, 2117, -832, +1912, -521, 1377, -178, 553, 166, -383, 513, +-1238, 729, -1872, 677, -2266, 450, -2392, 171, +-2063, -120, -1330, -422, -423, -642, 469, -658, +1354, -473, 2116, -188, 2519, 220, 2490, 688, +2098, 986, 1407, 967, 404, 678, -728, 243, +-1704, -322, -2375, -907, -2729, -1261, -2730, -1279, +-2213, -1042, -1214, -569, -52, 55, 1009, 649, +1930, 1092, 2639, 1340, 2901, 1345, 2601, 1084, +1811, 645, 774, 96, -306, -502, -1305, -1031, +-2057, -1330, -2433, -1368, -2400, -1167, -2053, -730, +-1465, -152, -705, 375, 109, 741, 881, 927, +1513, 915, 1934, 772, 2074, 564, 2009, 387, +1717, 281, 1150, 204, 399, 103, -424, -101, +-1285, -459, -2090, -870, -2562, -1218, -2533, -1426, +-2084, -1343, -1368, -857, -400, -37, 770, 814, +1802, 1490, 2402, 1934, 2521, 1982, 2246, 1493, +1631, 636, 711, -278, -285, -1026, -1023, -1469, +-1374, -1555, -1489, -1318, -1503, -863, -1387, -313, +-1090, 136, -705, 385, -452, 507, -261, 565, +82, 522, 570, 427, 1023, 408, 1364, 441, +1663, 393, 1821, 267, 1621, 158, 1036, 21, +298, -195, -514, -442, -1360, -609, -2019, -696, +-2324, -735, -2260, -646, -1867, -397, -1194, -68, +-340, 274, 570, 584, 1410, 781, 2045, 794, +2372, 628, 2381, 392, 2094, 129, 1451, -109, +510, -247, -474, -298, -1343, -294, -2057, -266, +-2545, -277, -2639, -315, -2216, -283, -1432, -171, +-542, -32, 389, 99, 1338, 235, 2056, 275, +2330, 141, 2190, -78, 1802, -255, 1243, -314, +517, -194, -209, 132, -746, 554, -1082, 931, +-1345, 1133, -1582, 1028, -1712, 541, -1652, -200, +-1487, -972, -1242, -1575, -742, -1893, 110, -1812, +1165, -1274, 2182, -459, 2926, 402, 3193, 1169, +2877, 1738, 1969, 2009, 616, 1951, -923, 1582, +-2310, 1000, -3264, 284, -3679, -477, -3522, -1213, +-2751, -1891, -1469, -2348, 15, -2390, 1404, -1981, +2546, -1216, 3361, -184, 3679, 979, 3349, 2032, +2482, 2663, 1291, 2764, -120, 2392, -1628, 1583, +-2915, 431, -3656, -795, -3767, -1752, -3303, -2283, +-2277, -2400, -798, -2124, 795, -1449, 2122, -526, +3060, 344, 3555, 951, 3474, 1297, 2709, 1406, +1435, 1272, 57, 965, -1155, 629, -2127, 402, +-2810, 251, -3028, 96, -2718, -118, -1983, -389, +-1001, -682, 62, -978, 1065, -1228, 1850, -1297, +2322, -1097, 2440, -649, 2218, -58, 1703, 518, +935, 1002, -17, 1321, -986, 1411, -1725, 1244, +-2099, 894, -2108, 477, -1833, 69, -1341, -310, +-599, -615, 262, -818, 924, -937, 1251, -990, +1379, -1023, 1390, -986, 1193, -798, 864, -465, +568, -67, 389, 419, 182, 1020, -157, 1591, +-574, 1905, -1010, 1904, -1428, 1612, -1819, 969, +-2017, -12, -1789, -1113, -1049, -2046, -9, -2639, +1102, -2721, 2152, -2187, 2941, -1131, 3225, 168, +2786, 1393, 1704, 2277, 294, 2592, -1203, 2259, +-2572, 1453, -3486, 437, -3648, -553, -3071, -1187, +-1980, -1290, -583, -985, 906, -545, 2170, -141, +2930, 133, 3153, 151, 2878, -123, 2169, -501, +1145, -730, -52, -699, -1144, -421, -1943, -4, +-2410, 507, -2570, 1031, -2336, 1373, -1703, 1393, +-855, 1174, -21, 834, 739, 360, 1461, -257, +1951, -895, 2049, -1376, 1834, -1680, 1473, -1804, +1032, -1636, 492, -1089, -131, -301, -748, 547, +-1281, 1333, -1718, 1926, -1992, 2161, -2012, 1956, +-1742, 1400, -1177, 631, -370, -201, 588, -922, +1523, -1424, 2176, -1695, 2432, -1668, 2295, -1388, +1797, -1011, 1010, -616, 67, -202, -857, 244, +-1546, 688, -1876, 1110, -1933, 1473, -1774, 1708, +-1404, 1738, -823, 1512, -198, 948, 290, 101, +674, -855, 1077, -1734, 1434, -2374, 1543, -2619, +1413, -2318, 1215, -1504, 966, -393, 506, 754, +-116, 1759, -662, 2412, -1075, 2533, -1449, 2113, +-1750, 1339, -1822, 411, -1587, -466, -1098, -1125, +-438, -1505, 335, -1604, 1134, -1460, 1790, -1132, +2139, -742, 2157, -344, 1883, 65, 1320, 444, +505, 751, -379, 994, -1168, 1105, -1811, 1011, +-2256, 739, -2366, 373, -2021, 26, -1344, -225, +-543, -331, 310, -334, 1228, -306, 1994, -302, +2296, -378, 2093, -593, 1626, -880, 1028, -1082, +272, -1036, -532, -635, -1149, 66, -1437, 916, +-1478, 1695, -1414, 2200, -1269, 2266, -959, 1797, +-517, 839, -89, -337, 273, -1414, 665, -2210, +1099, -2603, 1372, -2435, 1375, -1692, 1213, -655, +976, 383, 621, 1278, 132, 1936, -418, 2181, +-906, 1979, -1295, 1468, -1594, 795, -1705, 71, +-1505, -590, -986, -1103, -282, -1437, 467, -1563, +1200, -1468, 1845, -1156, 2194, -707, 2083, -163, +1534, 422, 714, 924, -199, 1275, -1086, 1482, +-1823, 1491, -2178, 1220, -2043, 707, -1564, 108, +-871, -468, -54, -1017, 787, -1436, 1445, -1589, +1778, -1426, 1793, -1007, 1571, -435, 1107, 186, +427, 754, -312, 1155, -946, 1306, -1356, 1188, +-1553, 837, -1525, 398, -1235, -11, -747, -345, +-159, -583, 448, -643, 943, -526, 1235, -359, +1337, -258, 1243, -223, 933, -209, 477, -252, +-22, -359, -496, -422, -893, -285, -1096, 58, +-1012, 494, -771, 893, -512, 1217, -272, 1350, +-46, 1122, 116, 538, 183, -229, 235, -981, +339, -1564, 488, -1836, 632, -1681, 827, -1102, +980, -325, 887, 442, 504, 1077, -18, 1458, +-565, 1469, -1155, 1139, -1671, 678, -1847, 235, +-1575, -180, -1011, -537, -303, -743, 510, -780, +1315, -666, 1906, -497, 2090, -344, 1856, -166, +1326, 86, 592, 289, -250, 334, -1056, 279, +-1609, 200, -1748, 124, -1542, 36, -1177, -25, +-752, -2, -254, 126, 226, 271, 568, 342, +740, 310, 870, 211, 1034, 49, 1141, -164, +1135, -349, 1016, -489, 748, -548, 241, -480, +-416, -337, -1059, -197, -1595, -27, -1931, 169, +-1891, 349, -1345, 510, -440, 657, 509, 734, +1281, 679, 1776, 531, 1907, 298, 1611, -66, +967, -527, 197, -916, -482, -1119, -947, -1114, +-1162, -900, -1098, -453, -783, 167, -313, 777, +147, 1197, 414, 1356, 443, 1242, 320, 824, +124, 184, -149, -494, -405, -993, -503, -1185, +-351, -1060, 18, -695, 430, -181, 732, 340, +884, 689, 871, 770, 599, 602, 80, 290, +-482, -38, -856, -240, -1041, -298, -1077, -261, +-893, -163, -463, -33, 52, 46, 431, 13, +611, -106, 705, -216, 763, -216, 668, -101, +393, 67, 70, 205, -176, 325, -356, 401, +-490, 351, -516, 164, -377, -43, -163, -161, +-6, -204, 76, -245, 113, -280, 85, -227, +-44, -156, -158, -206, -134, -348, -22, -409, +80, -352, 201, -250, 332, -101, 364, 192, +270, 609, 134, 986, 33, 1209, -48, 1235, +-125, 1044, -153, 577, -121, -158, -121, -993, +-202, -1649, -330, -2016, -416, -2091, -388, -1804, +-231, -1114, 49, -150, 421, 806, 784, 1563, +991, 2099, 936, 2373, 585, 2263, 90, 1812, +-374, 1130, -737, 291, -969, -651, -985, -1593, +-722, -2360, -289, -2783, 101, -2763, 379, -2285, +610, -1394, 751, -198, 731, 1119, 580, 2213, +370, 2817, 135, 2889, -142, 2502, -439, 1731, +-643, 719, -701, -294, -650, -1086, -505, -1554, +-252, -1766, 70, -1780, 346, -1600, 534, -1248, +659, -822, 704, -370, 601, 112, 397, 620, +169, 1066, -95, 1336, -424, 1402, -798, 1299, +-1091, 1061, -1167, 674, -950, 214, -521, -169, +33, -417, 651, -603, 1218, -713, 1555, -705, +1522, -637, 1130, -587, 495, -561, -230, -528, +-916, -480, -1444, -371, -1673, -159, -1527, 152, +-1071, 534, -457, 982, 168, 1379, 700, 1545, +1064, 1375, 1225, 894, 1144, 181, 855, -655, +496, -1405, 186, -1854, -55, -1860, -281, -1410, +-446, -608, -525, 300, -584, 1058, -702, 1482, +-801, 1470, -775, 1024, -663, 297, -498, -469, +-196, -1078, 323, -1341, 912, -1160, 1385, -617, +1668, 85, 1713, 797, 1438, 1338, 823, 1497, +-7, 1224, -867, 678, -1599, 5, -2092, -687, +-2254, -1242, -1993, -1527, -1319, -1493, -406, -1205, +539, -757, 1395, -274, 2091, 181, 2442, 604, +2290, 984, 1714, 1246, 959, 1349, 138, 1315, +-719, 1136, -1451, 753, -1879, 152, -1976, -522, +-1854, -1136, -1536, -1635, -997, -1914, -322, -1805, +337, -1315, 955, -613, 1533, 172, 1950, 962, +2068, 1579, 1828, 1817, 1268, 1657, 469, 1222, +-425, 640, -1215, -35, -1761, -671, -1998, -1056, +-1867, -1085, -1405, -927, -792, -746, -194, -477, +335, -86, 793, 233, 1125, 320, 1252, 315, +1203, 377, 1092, 453, 915, 422, 584, 358, +102, 333, -383, 278, -772, 116, -1085, -107, +-1305, -320, -1336, -507, -1098, -622, -650, -602, +-143, -419, 311, -119, 708, 221, 985, 480, +1040, 632, 926, 693, 775, 606, 561, 368, +237, 135, -78, 5, -273, -94, -415, -179, +-614, -210, -815, -221, -913, -318, -886, -475, +-771, -613, -539, -668, -137, -579, 421, -323, +973, 54, 1339, 528, 1488, 1037, 1429, 1375, +1116, 1403, 512, 1141, -271, 676, -1005, 51, +-1500, -626, -1721, -1172, -1653, -1419, -1236, -1364, +-525, -1113, 254, -715, 867, -229, 1260, 204, +1493, 454, 1533, 562, 1296, 612, 847, 642, +308, 642, -245, 629, -759, 574, -1156, 465, +-1380, 310, -1402, 63, -1197, -272, -787, -569, +-242, -729, 346, -789, 873, -761, 1184, -647, +1238, -472, 1122, -304, 899, -177, 565, -84, +198, 33, -88, 217, -308, 436, -546, 630, +-805, 764, -1016, 860, -1159, 848, -1217, 650, +-1105, 289, -738, -94, -171, -425, 453, -696, +1051, -895, 1558, -980, 1850, -928, 1799, -770, +1382, -538, 695, -289, -97, -38, -845, 215, +-1438, 453, -1803, 608, -1897, 688, -1728, 696, +-1329, 608, -760, 480, -98, 380, 573, 289, +1178, 195, 1634, 143, 1871, 75, 1874, -86, +1565, -343, 913, -631, 70, -933, -712, -1207, +-1322, -1329, -1745, -1188, -1865, -790, -1591, -207, +-1025, 494, -398, 1197, 160, 1772, 624, 2047, +968, 1935, 1104, 1492, 1003, 821, 806, 2, +657, -814, 518, -1425, 301, -1665, 53, -1521, +-131, -1156, -277, -699, -471, -207, -698, 202, +-840, 364, -796, 314, -627, 210, -411, 193, +-135, 294, 218, 500, 526, 757, 661, 972, +678, 1062, 694, 947, 694, 602, 554, 122, +309, -329, 75, -709, -107, -983, -307, -1078, +-519, -998, -634, -853, -616, -700, -541, -510, +-453, -264, -294, 3, -55, 264, 177, 569, +315, 890, 375, 1143, 424, 1263, 481, 1221, +523, 999, 524, 637, 432, 157, 220, -426, +-107, -968, -498, -1300, -830, -1425, -981, -1426, +-915, -1218, -683, -749, -295, -175, 185, 293, +629, 628, 937, 867, 1051, 989, 902, 957, +468, 764, -110, 492, -620, 259, -907, 78, +-962, -148, -838, -389, -560, -541, -123, -582, +334, -576, 603, -534, 639, -412, 559, -197, +422, 18, 206, 135, -46, 165, -234, 134, +-274, 55, -214, -46, -153, -86, -124, -34, +-81, 98, -77, 236, -195, 300, -349, 266, +-366, 171, -249, 24, -107, -192, 96, -344, +402, -298, 701, -148, 816, -43, 718, 75, +502, 208, 213, 232, -159, 112, -507, -48, +-683, -164, -677, -246, -581, -308, -451, -351, +-278, -357, -86, -289, 81, -109, 211, 113, +354, 348, 516, 619, 647, 878, 680, 972, +610, 829, 443, 518, 162, 107, -175, -363, +-460, -800, -619, -1058, -650, -1112, -557, -994, +-378, -740, -158, -371, 53, 50, 200, 474, +242, 845, 200, 1106, 153, 1230, 124, 1184, +94, 933, 61, 481, 75, -80, 170, -649, +311, -1068, 399, -1212, 373, -1050, 237, -665, +12, -157, -306, 362, -662, 743, -917, 854, +-973, 663, -835, 302, -552, -85, -150, -383, +297, -524, 690, -451, 952, -192, 1033, 156, +848, 474, 447, 676, 52, 687, -203, 490, +-358, 191, -472, -147, -486, -490, -415, -742, +-383, -812, -456, -712, -519, -471, -444, -139, +-274, 232, -115, 575, 77, 802, 400, 854, +736, 725, 884, 466, 806, 91, 591, -365, +287, -795, -74, -1051, -427, -1117, -656, -996, +-678, -641, -524, -77, -322, 546, -161, 1058, +-23, 1348, 92, 1353, 132, 1057, 76, 475, +1, -232, -7, -846, 90, -1214, 218, -1295, +342, -1110, 476, -731, 565, -280, 499, 84, +266, 280, -21, 352, -289, 349, -512, 335, +-641, 345, -599, 419, -411, 527, -176, 557, +14, 416, 143, 154, 250, -131, 315, -385, +287, -588, 220, -709, 204, -664, 205, -473, +152, -266, 82, -155, 98, -67, 156, 64, +128, 184, 6, 250, -94, 345, -149, 502, +-248, 599, -392, 532, -463, 355, -406, 188, +-324, 11, -254, -233, -110, -483, 141, -583, +340, -522, 397, -421, 405, -328, 431, -157, +411, 128, 309, 386, 188, 526, 68, 584, +-78, 583, -253, 434, -420, 113, -560, -260, +-611, -524, -556, -655, -457, -624, -323, -354, +-102, 100, 168, 582, 359, 952, 427, 1102, +417, 946, 370, 514, 260, -90, 104, -690, +-17, -1151, -35, -1369, -9, -1277, -26, -865, +-56, -211, -45, 518, -43, 1120, -126, 1465, +-259, 1513, -366, 1224, -412, 670, -402, -7, +-291, -653, -57, -1113, 212, -1256, 395, -1070, +492, -628, 570, -91, 596, 357, 468, 628, +160, 678, -190, 519, -446, 215, -558, -111, +-549, -364, -412, -465, -143, -405, 178, -222, +422, -8, 544, 177, 556, 346, 436, 471, +215, 517, -49, 479, -320, 352, -551, 120, +-620, -176, -505, -492, -313, -760, -106, -922, +142, -938, 398, -800, 547, -527, 540, -149, +426, 250, 301, 580, 199, 791, 94, 942, +-30, 1054, -122, 1052, -148, 842, -171, 461, +-294, -17, -493, -580, -626, -1181, -597, -1662, +-448, -1801, -250, -1538, 44, -966, 425, -236, +742, 558, 827, 1243, 726, 1582, 555, 1464, +314, 1029, -29, 491, -377, -38, -575, -470, +-631, -684, -637, -618, -607, -375, -446, -84, +-173, 138, 84, 258, 234, 258, 318, 115, +405, -117, 461, -318, 388, -490, 203, -662, +19, -739, -151, -641, -337, -383, -472, -67, +-440, 286, -273, 679, -86, 1049, 82, 1290, +258, 1335, 397, 1166, 417, 843, 299, 406, +96, -139, -142, -677, -388, -1114, -541, -1429, +-528, -1596, -369, -1513, -95, -1152, 251, -595, +525, 32, 640, 642, 656, 1158, 578, 1452, +297, 1456, -152, 1234, -501, 887, -634, 477, +-689, 101, -719, -159, -566, -281, -188, -363, +221, -455, 483, -533, 681, -583, 945, -597, +1113, -553, 961, -443, 549, -290, 82, -119, +-418, 7, -983, 86, -1432, 130, -1508, 170, +-1201, 245, -686, 417, -75, 684, 584, 935, +1143, 1032, 1400, 903, 1302, 549, 977, 2, +602, -608, 249, -1109, -58, -1355, -300, -1302, +-467, -945, -603, -363, -745, 217, -869, 553, +-912, 586, -860, 395, -720, 62, -438, -296, +-23, -517, 451, -427, 883, -40, 1194, 493, +1318, 979, 1236, 1281, 940, 1302, 445, 985, +-136, 351, -650, -443, -1021, -1136, -1249, -1586, +-1267, -1755, -1027, -1637, -611, -1204, -160, -526, +252, 200, 566, 742, 717, 1067, 664, 1206, +440, 1113, 166, 808, -31, 412, -117, 75, +-137, -146, -105, -250, 11, -258, 174, -204, +237, -171, 169, -194, 81, -278, 39, -376, +-38, -417, -206, -410, -357, -356, -397, -215, +-383, -31, -384, 85, -316, 154, -108, 212, +164, 258, 342, 290, 413, 350, 468, 440, +456, 502, 258, 472, -53, 318, -264, 54, +-287, -268, -168, -534, 43, -698, 314, -708, +551, -529, 611, -208, 415, 146, 50, 460, +-315, 641, -618, 624, -865, 442, -977, 188, +-844, -41, -502, -239, -78, -370, 354, -379, +765, -259, 1062, -100, 1143, 18, 970, 89, +616, 162, 182, 222, -257, 213, -612, 164, +-766, 131, -674, 140, -436, 152, -164, 155, +68, 166, 204, 204, 160, 228, -73, 162, +-368, -34, -535, -288, -497, -513, -315, -706, +1, -818, 452, -733, 895, -412, 1114, 21, +1050, 465, 779, 850, 370, 1075, -150, 1033, +-686, 751, -1081, 337, -1248, -125, -1220, -525, +-1033, -761, -670, -783, -156, -593, 392, -258, +830, 65, 1114, 317, 1218, 464, 1107, 427, +773, 169, 301, -198, -159, -504, -528, -664, +-815, -642, -990, -416, -948, -52, -704, 315, +-398, 627, -151, 757, 64, 616, 288, 305, +463, -11, 528, -263, 530, -395, 537, -349, +493, -156, 326, 59, 126, 156, -2, 112, +-123, -56, -284, -282, -388, -486, -383, -573, +-358, -484, -362, -221, -347, 104, -256, 369, +-95, 528, 85, 522, 252, 360, 384, 143, +479, -22, 510, -120, 442, -131, 283, -71, +137, 6, 67, 30, 6, -14, -134, -107, +-305, -238, -397, -321, -437, -286, -474, -162, +-446, -22, -255, 116, 45, 211, 329, 261, +534, 257, 678, 203, 725, 143, 574, 126, +234, 135, -160, 93, -493, 6, -729, -79, +-827, -182, -769, -328, -544, -406, -188, -371, +210, -273, 555, -140, 819, 73, 987, 338, +962, 561, 689, 715, 273, 781, -164, 719, +-606, 493, -980, 125, -1157, -341, -1094, -761, +-855, -1019, -501, -1086, -79, -926, 354, -504, +709, 54, 919, 539, 962, 843, 856, 935, +647, 817, 361, 526, 46, 181, -244, -112, +-458, -269, -585, -246, -637, -99, -627, 31, +-553, 98, -435, 116, -330, 33, -227, -149, +-100, -364, 69, -509, 262, -549, 456, -504, +642, -389, 809, -171, 898, 112, 824, 394, +553, 626, 136, 786, -317, 865, -721, 794, +-1032, 545, -1187, 179, -1099, -226, -773, -640, +-337, -958, 84, -1072, 471, -942, 833, -638, +1082, -268, 1099, 113, 900, 457, 592, 674, +232, 682, -178, 524, -588, 309, -834, 120, +-847, -69, -702, -231, -489, -294, -210, -264, +105, -198, 343, -106, 429, -8, 392, 47, +340, 49, 314, 5, 283, -70, 233, -160, +201, -204, 163, -173, 33, -88, -190, 24, +-412, 140, -570, 186, -662, 126, -663, 1, +-511, -133, -181, -205, 224, -157, 554, 31, +781, 279, 927, 494, 903, 590, 626, 503, +185, 217, -237, -210, -568, -662, -808, -987, +-911, -1035, -806, -787, -502, -351, -143, 138, +127, 614, 272, 965, 357, 1044, 357, 821, +233, 442, 76, 41, 34, -310, 122, -532, +217, -561, 286, -391, 359, -103, 393, 193, +258, 380, -33, 413, -337, 290, -582, 49, +-780, -281, -871, -602, -765, -748, -497, -650, +-150, -354, 249, 37, 635, 452, 898, 827, +977, 1047, 891, 986, 679, 666, 335, 211, +-118, -228, -564, -556, -840, -742, -903, -761, +-828, -595, -627, -301, -256, -15, 208, 195, +555, 348, 706, 478, 731, 519, 677, 450, +493, 333, 191, 180, -106, -66, -309, -379, +-455, -642, -589, -767, -641, -710, -550, -497, +-356, -157, -146, 250, 86, 613, 369, 793, +621, 761, 727, 593, 694, 361, 576, 94, +379, -121, 122, -184, -147, -171, -384, -182, +-552, -218, -599, -264, -541, -358, -443, -462, +-307, -515, -101, -492, 92, -395, 180, -221, +196, -18, 199, 133, 191, 231, 161, 318, +143, 394, 193, 456, 322, 537, 419, 606, +406, 608, 301, 499, 132, 277, -144, -48, +-523, -422, -851, -752, -980, -960, -888, -966, +-626, -772, -230, -461, 236, -129, 673, 172, +951, 363, 999, 382, 850, 266, 547, 111, +124, -33, -307, -135, -623, -132, -777, -11, +-770, 168, -621, 338, -377, 499, -98, 621, +164, 653, 354, 571, 440, 392, 443, 131, +397, -204, 315, -574, 226, -873, 164, -1017, +120, -1031, 65, -915, -22, -653, -162, -292, +-364, 60, -592, 345, -803, 557, -899, 680, +-772, 712, -399, 724, 136, 742, 698, 721, +1188, 653, 1489, 531, 1459, 343, 1049, 70, +406, -266, -270, -634, -844, -944, -1241, -1088, +-1372, -1037, -1166, -818, -720, -443, -228, 35, +193, 467, 528, 745, 721, 846, 691, 764, +484, 499, 275, 148, 150, -174, 49, -377, +-58, -403, -101, -278, -44, -92, 31, 108, +34, 318, -14, 471, -39, 505, -74, 444, +-181, 352, -308, 219, -325, 32, -236, -182, +-137, -398, -60, -605, 49, -778, 204, -858, +321, -788, 337, -558, 289, -226, 268, 145, +230, 511, 97, 815, -92, 942, -219, 862, +-267, 652, -326, 374, -407, 59, -423, -224, +-301, -384, -102, -408, 60, -350, 190, -269, +371, -181, 541, -101, 537, -67, 360, -101, +167, -178, 17, -248, -153, -266, -364, -221, +-502, -135, -466, -26, -346, 97, -266, 253, +-175, 389, 43, 419, 279, 332, 366, 213, +354, 79, 369, -88, 321, -243, 102, -314, +-155, -288, -274, -216, -259, -122, -217, -18, +-162, 71, -63, 109, 56, 101, 94, 80, +32, 76, -34, 38, -43, -57, -13, -142, +49, -199, 176, -272, 337, -340, 428, -309, +382, -165, 210, 23, -44, 209, -315, 400, +-545, 547, -688, 590, -699, 521, -567, 371, +-338, 169, -71, -55, 220, -274, 522, -492, +768, -668, 891, -761, 895, -738, 782, -594, +542, -335, 199, 24, -199, 448, -611, 837, +-953, 1070, -1133, 1090, -1137, 900, -964, 541, +-619, 70, -151, -391, 309, -723, 665, -864, +909, -815, 1043, -609, 1012, -329, 806, -68, +504, 114, 191, 195, -111, 206, -402, 195, +-611, 213, -703, 288, -726, 432, -691, 567, +-566, 599, -391, 498, -218, 281, -35, -47, +151, -446, 322, -784, 500, -928, 671, -849, +754, -589, 715, -182, 584, 271, 365, 638, +40, 843, -331, 863, -636, 673, -786, 322, +-766, -57, -636, -358, -462, -530, -250, -552, +-6, -426, 198, -220, 324, -5, 383, 147, +409, 193, 411, 124, 372, 3, 283, -106, +190, -160, 121, -123, 26, 6, -118, 181, +-250, 329, -306, 395, -327, 355, -350, 236, +-339, 55, -239, -153, -59, -317, 141, -384, +321, -368, 456, -303, 493, -206, 367, -109, +98, -44, -224, -19, -514, -14, -700, -30, +-701, -44, -464, -35, -42, 1, 419, 60, +801, 147, 1031, 248, 1054, 339, 830, 410, +374, 449, -196, 423, -706, 281, -1045, 29, +-1197, -280, -1124, -584, -807, -848, -333, -1011, +137, -997, 520, -758, 805, -339, 945, 143, +908, 594, 720, 934, 441, 1095, 114, 1022, +-189, 749, -411, 365, -546, -29, -603, -370, +-562, -604, -410, -692, -200, -633, -14, -463, +118, -250, 226, -40, 298, 142, 272, 275, +149, 317, 31, 267, -18, 157, -25, 28, +-24, -99, -4, -183, 69, -204, 181, -177, +223, -107, 128, -2, -26, 116, -167, 222, +-318, 323, -460, 409, -448, 461, -241, 455, +26, 366, 236, 160, 376, -158, 444, -510, +399, -796, 231, -945, -2, -914, -192, -668, +-278, -233, -284, 270, -246, 684, -181, 916, +-110, 939, -51, 769, 0, 449, 63, 89, +166, -179, 308, -285, 432, -248, 466, -145, +390, -14, 218, 98, -55, 114, -397, 11, +-673, -143, -775, -295, -711, -426, -532, -499, +-233, -482, 155, -395, 504, -283, 700, -137, +735, 63, 653, 295, 459, 508, 180, 696, +-99, 844, -284, 889, -350, 794, -332, 577, +-256, 261, -137, -123, -16, -496, 51, -784, +32, -963, -71, -1035, -210, -958, -325, -740, +-374, -457, -325, -154, -174, 178, 58, 491, +340, 694, 626, 747, 831, 688, 858, 564, +698, 384, 420, 177, 36, 0, -438, -83, +-864, -86, -1090, -70, -1121, -84, -994, -134, +-665, -220, -128, -340, 489, -443, 999, -483, +1292, -449, 1331, -348, 1102, -172, 592, 40, +-107, 236, -779, 374, -1224, 441, -1385, 431, +-1251, 350, -807, 220, -162, 58, 462, -110, +902, -239, 1128, -283, 1127, -237, 885, -106, +450, 74, -43, 248, -461, 348, -750, 332, +-894, 202, -854, -16, -608, -277, -231, -517, +160, -653, 474, -642, 656, -496, 673, -272, +514, -8, 199, 255, -171, 472, -447, 611, +-547, 675, -473, 673, -257, 597, 47, 452, +333, 253, 501, 26, 517, -221, 407, -478, +209, -703, -36, -809, -296, -781, -504, -667, +-593, -490, -562, -235, -455, 59, -264, 294, +21, 450, 309, 568, 522, 653, 664, 671, +735, 633, 644, 552, 358, 435, 4, 277, +-295, 76, -532, -149, -706, -369, -725, -557, +-541, -713, -237, -823, 70, -863, 322, -815, +479, -661, 497, -368, 373, 25, 172, 437, +-37, 838, -208, 1188, -306, 1345, -310, 1212, +-225, 865, -79, 403, 91, -143, 233, -694, +314, -1069, 334, -1193, 292, -1110, 164, -863, +-20, -457, -184, 40, -292, 493, -334, 804, +-303, 944, -232, 899, -173, 647, -106, 232, +-11, -230, 80, -600, 131, -800, 166, -784, +208, -562, 225, -212, 188, 145, 96, 396, +-36, 466, -158, 366, -200, 193, -121, 35, +61, -54, 276, -27, 436, 141, 481, 363, +344, 489, 11, 439, -401, 223, -741, -103, +-940, -464, -964, -756, -741, -892, -272, -828, +258, -606, 668, -304, 913, 13, 1007, 303, +922, 493, 652, 552, 287, 557, -29, 578, +-253, 564, -443, 469, -605, 351, -667, 227, +-595, 30, -463, -231, -326, -447, -161, -581, +32, -653, 188, -641, 284, -513, 380, -313, +465, -104, 435, 85, 262, 245, 70, 361, +-44, 416, -125, 415, -204, 358, -210, 250, +-129, 102, -44, -45, 14, -150, 89, -201, +175, -199, 199, -124, 122, 12, -38, 138, +-221, 209, -364, 217, -435, 163, -442, 32, +-358, -157, -143, -336, 140, -448, 362, -486, +508, -437, 622, -277, 637, -15, 466, 275, +170, 492, -99, 591, -284, 544, -411, 342, +-463, 29, -387, -280, -211, -473, -54, -491, +7, -330, 21, -41, 36, 275, -2, 505, +-129, 566, -240, 429, -188, 153, 14, -153, +232, -395, 395, -520, 530, -507, 603, -399, +498, -274, 203, -176, -116, -118, -330, -105, +-476, -111, -586, -37, -582, 159, -406, 411, +-165, 644, 4, 822, 110, 866, 260, 715, +416, 392, 442, -26, 345, -456, 245, -806, +152, -996, -24, -1009, -239, -846, -351, -545, +-324, -188, -240, 137, -155, 412, -62, 619, +46, 702, 129, 640, 123, 474, 48, 258, +15, 31, 70, -165, 125, -299, 120, -318, +119, -202, 167, 0, 182, 189, 77, 311, +-90, 339, -209, 235, -282, -10, -358, -310, +-396, -543, -319, -642, -135, -596, 59, -410, +210, -95, 327, 261, 399, 522, 383, 624, +268, 588, 102, 432, -48, 180, -157, -71, +-222, -230, -230, -275, -177, -207, -79, -38, +24, 152, 92, 260, 105, 264, 78, 185, +17, 8, -67, -223, -139, -402, -178, -483, +-185, -489, -173, -413, -109, -234, 26, -16, +178, 178, 295, 359, 365, 531, 379, 641, +310, 660, 147, 585, -77, 397, -303, 115, +-479, -206, -547, -515, -468, -746, -275, -803, +-18, -676, 258, -446, 460, -171, 516, 122, +446, 350, 296, 455, 81, 465, -132, 430, +-241, 356, -246, 248, -224, 133, -218, 8, +-205, -137, -176, -305, -133, -452, -59, -520, +46, -458, 164, -287, 281, -64, 358, 178, +335, 407, 211, 539, 57, 503, -82, 333, +-211, 110, -286, -110, -250, -316, -152, -448, +-76, -439, -4, -306, 93, -146, 158, -9, +152, 116, 114, 195, 59, 177, -29, 67, +-110, -60, -148, -152, -167, -182, -164, -129, +-77, -5, 70, 153, 169, 318, 178, 433, +138, 420, 61, 265, -45, 31, -105, -221, +-76, -446, -12, -576, 44, -555, 118, -387, +188, -142, 169, 110, 35, 315, -138, 428, +-265, 416, -314, 284, -281, 98, -174, -60, +-23, -183, 125, -290, 208, -321, 196, -243, +134, -108, 79, 33, 34, 201, -8, 380, +-14, 487, 21, 478, 46, 363, 30, 156, +0, -108, -13, -343, -18, -483, -24, -497, +-20, -386, 7, -185, 26, 17, -6, 146, +-95, 181, -200, 138, -266, 62, -257, 9, +-158, 24, 26, 102, 239, 211, 380, 297, +399, 317, 318, 251, 179, 127, 22, -15, +-108, -137, -189, -214, -226, -231, -197, -207, +-101, -175, -7, -136, 15, -87, 5, -31, +30, 34, 56, 129, 14, 230, -58, 274, +-80, 239, -59, 169, -69, 76, -89, -53, +-23, -172, 124, -225, 237, -216, 253, -183, +215, -136, 152, -93, 36, -70, -122, -49, +-236, 7, -251, 86, -212, 165, -170, 261, +-105, 351, 2, 380, 120, 342, 214, 264, +273, 132, 282, -45, 220, -229, 90, -407, +-85, -583, -273, -726, -431, -784, -514, -739, +-491, -559, -321, -220, -11, 226, 326, 677, +560, 1064, 663, 1290, 655, 1240, 507, 916, +217, 421, -116, -152, -370, -705, -514, -1104, +-580, -1256, -582, -1173, -502, -926, -326, -564, +-103, -156, 111, 224, 322, 530, 554, 751, +728, 872, 718, 870, 513, 729, 216, 478, +-125, 171, -516, -159, -850, -458, -944, -649, +-743, -703, -362, -657, 79, -541, 511, -374, +838, -188, 943, -23, 786, 116, 449, 260, +63, 407, -285, 521, -562, 555, -723, 497, +-721, 375, -573, 211, -362, 16, -111, -150, +198, -231, 489, -245, 628, -244, 604, -251, +512, -289, 346, -374, 56, -445, -249, -432, +-403, -309, -409, -81, -367, 250, -266, 603, +-79, 835, 111, 874, 198, 739, 165, 441, +80, 19, -2, -403, -76, -682, -144, -762, +-171, -655, -97, -387, 77, -16, 265, 370, +392, 663, 461, 765, 453, 657, 288, 387, +-56, 4, -459, -417, -763, -745, -923, -884, +-908, -817, -649, -566, -156, -157, 411, 300, +885, 666, 1192, 880, 1268, 928, 1040, 786, +537, 498, -92, 173, -665, -133, -1064, -396, +-1252, -566, -1201, -609, -890, -565, -395, -463, +113, -299, 527, -80, 846, 142, 1046, 324, +1019, 435, 725, 441, 303, 328, -74, 117, +-356, -121, -587, -308, -722, -379, -658, -313, +-420, -122, -155, 132, 55, 362, 224, 481, +340, 433, 338, 232, 198, -54, 7, -335, +-117, -540, -124, -614, -65, -532, 4, -322, +102, -46, 236, 247, 309, 484, 246, 599, +108, 576, -15, 429, -145, 161, -317, -198, +-456, -532, -457, -739, -315, -785, -90, -664, +165, -359, 400, 55, 546, 436, 539, 691, +360, 779, 71, 680, -212, 430, -404, 130, +-475, -138, -401, -340, -180, -459, 109, -496, +318, -492, 369, -471, 298, -421, 159, -326, +-37, -167, -242, 77, -350, 370, -307, 634, +-157, 799, 21, 805, 178, 622, 282, 280, +322, -131, 294, -527, 182, -828, 16, -953, +-122, -847, -215, -561, -290, -194, -310, 193, +-217, 550, -51, 796, 82, 863, 136, 757, +135, 534, 107, 234, 33, -111, -87, -415, +-187, -609, -193, -671, -112, -599, -9, -421, +103, -188, 232, 43, 335, 231, 369, 335, +339, 341, 263, 284, 146, 224, -5, 188, +-165, 185, -330, 221, -496, 264, -624, 267, +-665, 209, -595, 79, -416, -137, -123, -385, +245, -587, 577, -698, 769, -713, 820, -601, +747, -344, 532, 6, 213, 376, -103, 724, +-327, 986, -434, 1093, -425, 1027, -339, 774, +-252, 351, -204, -156, -181, -630, -157, -995, +-116, -1178, -30, -1128, 97, -860, 225, -454, +316, 8, 340, 431, 265, 709, 103, 810, +-62, 745, -167, 544, -221, 262, -237, 0, +-185, -177, -63, -251, 83, -210, 199, -80, +264, 58, 281, 127, 253, 101, 176, -20, +65, -201, -42, -382, -118, -496, -170, -487, +-212, -333, -244, -81, -247, 181, -208, 376, +-163, 458, -157, 421, -155, 282, -82, 90, +50, -85, 179, -184, 301, -201, 422, -168, +482, -125, 417, -71, 252, -15, 60, 10, +-117, 15, -269, 43, -366, 94, -352, 121, +-251, 97, -160, 29, -101, -61, -26, -168, +52, -269, 66, -329, 31, -304, 19, -183, +49, -11, 80, 156, 79, 300, 67, 384, +75, 353, 81, 243, 25, 122, -62, -5, +-93, -142, -83, -244, -99, -285, -118, -292, +-71, -281, 30, -239, 121, -158, 176, -38, +201, 133, 200, 323, 183, 461, 124, 521, +-4, 495, -165, 357, -280, 122, -335, -148, +-363, -396, -339, -578, -208, -652, -5, -602, +160, -460, 263, -252, 359, 0, 453, 252, +468, 452, 373, 587, 211, 643, 11, 590, +-229, 427, -488, 198, -681, -36, -714, -237, +-564, -363, -288, -387, 51, -314, 417, -193, +738, -63, 901, 47, 845, 99, 619, 67, +300, -22, -78, -116, -441, -175, -676, -187, +-760, -145, -751, -33, -667, 135, -470, 318, +-181, 453, 121, 498, 376, 441, 570, 287, +678, 39, 665, -257, 515, -499, 277, -604, +33, -560, -170, -383, -307, -100, -344, 226, +-271, 505, -145, 655, -17, 619, 72, 399, +64, 79, -41, -255, -170, -551, -273, -741, +-345, -744, -347, -553, -227, -254, 7, 84, +267, 419, 474, 679, 605, 792, 638, 743, +517, 564, 221, 299, -143, -21, -433, -351, +-605, -620, -670, -762, -602, -751, -402, -607, +-118, -371, 190, -84, 456, 206, 630, 426, +680, 522, 575, 506, 324, 427, 11, 323, +-272, 211, -498, 103, -645, 8, -661, -87, +-535, -218, -318, -391, -49, -555, 234, -630, +470, -575, 606, -394, 613, -103, 496, 262, +296, 593, 64, 767, -159, 748, -350, 571, +-469, 293, -476, -32, -373, -318, -206, -491, +-23, -546, 150, -507, 290, -398, 365, -266, +359, -142, 293, -8, 198, 144, 80, 285, +-70, 396, -228, 474, -334, 489, -363, 417, +-340, 268, -289, 65, -193, -175, -47, -407, +101, -568, 213, -639, 302, -620, 387, -504, +435, -296, 407, -35, 321, 254, 224, 530, +93, 729, -106, 807, -331, 764, -514, 596, +-610, 299, -598, -73, -485, -428, -298, -700, +-63, -846, 162, -819, 319, -621, 412, -319, +470, 10, 477, 315, 413, 536, 316, 623, +210, 575, 85, 429, -56, 235, -198, 25, +-328, -169, -427, -303, -488, -347, -520, -318, +-490, -237, -349, -120, -124, 14, 113, 126, +341, 183, 556, 176, 710, 125, 736, 68, +615, 23, 383, 4, 88, 20, -256, 66, +-606, 98, -844, 85, -891, 29, -765, -58, +-511, -158, -143, -237, 303, -279, 716, -291, +966, -247, 980, -136, 779, -4, 431, 115, +-8, 245, -461, 390, -800, 486, -923, 484, +-844, 401, -613, 241, -257, -9, 167, -288, +527, -501, 718, -604, 743, -605, 644, -504, +433, -307, 138, -63, -152, 157, -353, 317, +-449, 423, -463, 489, -387, 517, -226, 492, +-44, 405, 84, 247, 142, 14, 156, -272, +133, -550, 58, -754, -34, -840, -80, -774, +-54, -543, 11, -188, 70, 205, 128, 551, +212, 786, 294, 876, 294, 810, 199, 615, +80, 339, -50, 45, -229, -216, -400, -416, +-460, -541, -419, -585, -349, -554, -251, -467, +-92, -356, 92, -242, 222, -125, 289, -10, +350, 85, 419, 167, 431, 277, 347, 421, +225, 548, 114, 620, -20, 637, -207, 571, +-395, 367, -505, 21, -508, -381, -441, -730, +-326, -964, -138, -1045, 93, -937, 260, -637, +320, -221, 336, 207, 330, 569, 250, 829, +120, 958, 40, 935, 46, 781, 81, 540, +91, 245, 64, -88, 3, -421, -110, -701, +-295, -878, -490, -929, -588, -856, -553, -673, +-418, -389, -197, -35, 125, 320, 495, 606, +777, 807, 877, 921, 819, 910, 648, 757, +347, 486, -74, 153, -487, -184, -755, -479, +-855, -682, -823, -756, -650, -699, -334, -562, +43, -405, 361, -257, 544, -126, 586, -13, +515, 102, 351, 252, 130, 452, -63, 656, +-158, 787, -162, 791, -134, 648, -106, 358, +-49, -49, 21, -479, 40, -799, -8, -927, +-52, -860, -54, -630, -47, -294, -51, 70, +-31, 365, 30, 530, 79, 561, 62, 490, +6, 368, -23, 233, -41, 114, -103, 28, +-181, -36, -181, -112, -92, -207, 17, -293, +115, -350, 215, -387, 311, -389, 351, -323, +293, -191, 160, -21, 13, 169, -130, 372, +-268, 550, -358, 666, -337, 683, -237, 582, +-126, 361, -34, 43, 27, -326, 39, -669, +8, -886, -26, -908, -22, -739, 37, -428, +130, -40, 219, 332, 278, 599, 282, 702, +218, 636, 104, 440, -21, 189, -135, -41, +-208, -205, -207, -285, -161, -270, -128, -179, +-124, -66, -133, 30, -139, 93, -139, 101, +-112, 48, -19, -44, 133, -138, 262, -191, +309, -166, 307, -74, 274, 55, 170, 183, +1, 268, -143, 269, -205, 168, -203, -13, +-161, -221, -92, -393, -15, -466, 38, -414, +51, -255, 23, -22, -28, 238, -75, 457, +-91, 579, -82, 591, -52, 500, 22, 322, +137, 95, 232, -140, 265, -338, 243, -473, +176, -550, 66, -576, -66, -544, -193, -454, +-292, -322, -338, -152, -329, 72, -281, 341, +-186, 599, -23, 791, 170, 882, 318, 833, +401, 623, 443, 251, 428, -225, 313, -675, +118, -976, -90, -1079, -278, -975, -452, -656, +-562, -165, -530, 358, -371, 753, -173, 938, +24, 892, 214, 624, 354, 203, 402, -239, +365, -568, 290, -701, 212, -626, 146, -379, +78, -29, 12, 315, -33, 530, -104, 557, +-241, 427, -380, 194, -445, -87, -440, -341, +-388, -487, -263, -489, -53, -373, 192, -184, +384, 39, 489, 249, 536, 400, 527, 462, +427, 424, 258, 304, 90, 144, -56, -18, +-215, -164, -381, -276, -515, -327, -583, -309, +-575, -256, -490, -199, -339, -132, -122, -56, +138, 4, 379, 41, 568, 78, 697, 136, +741, 198, 662, 239, 466, 270, 183, 303, +-139, 324, -441, 301, -662, 209, -760, 47, +-726, -150, -575, -336, -342, -491, -56, -586, +226, -573, 441, -443, 559, -232, 573, 9, +488, 226, 340, 365, 162, 396, -27, 343, +-197, 256, -304, 169, -339, 106, -320, 87, +-255, 110, -141, 155, -3, 173, 100, 110, +138, -33, 139, -203, 142, -361, 122, -484, +54, -519, -18, -423, -50, -221, -55, 4, +-63, 187, -73, 293, -74, 308, -60, 234, +-49, 116, -41, 26, 8, 20, 106, 107, +194, 241, 223, 352, 208, 367, 145, 236, +30, -38, -102, -392, -217, -714, -298, -889, +-331, -847, -289, -586, -167, -152, -18, 367, +112, 823, 206, 1062, 266, 1031, 265, 766, +191, 345, 98, -131, 35, -540, -12, -779, +-60, -813, -82, -671, -66, -423, -32, -150, +-9, 76, -18, 210, -53, 244, -83, 210, +-107, 171, -143, 154, -155, 145, -96, 141, +9, 156, 100, 188, 161, 208, 200, 188, +203, 137, 156, 69, 83, -20, 31, -143, +16, -291, 10, -418, -8, -485, -35, -476, +-79, -381, -140, -194, -202, 37, -244, 236, +-240, 362, -176, 405, -79, 372, 22, 286, +140, 189, 269, 116, 359, 84, 375, 82, +342, 83, 275, 59, 157, 5, -20, -73, +-210, -172, -366, -270, -481, -338, -552, -365, +-526, -363, -356, -337, -96, -285, 158, -183, +361, -8, 507, 222, 572, 473, 531, 708, +388, 880, 200, 915, 42, 756, -81, 413, +-220, -56, -372, -570, -478, -1019, -524, -1292, +-533, -1316, -499, -1084, -362, -645, -88, -95, +263, 460, 576, 922, 806, 1203, 936, 1264, +884, 1125, 594, 828, 150, 433, -294, 15, +-658, -360, -907, -658, -994, -858, -873, -941, +-565, -899, -183, -757, 156, -555, 426, -323, +632, -79, 717, 158, 650, 379, 493, 575, +321, 738, 133, 854, -70, 882, -238, 786, +-327, 575, -356, 274, -364, -96, -344, -487, +-266, -813, -151, -999, -52, -1024, 34, -904, +114, -670, 162, -363, 158, -26, 125, 306, +88, 590, 60, 789, 48, 886, 60, 861, +106, 706, 173, 445, 220, 123, 196, -210, +97, -507, -51, -713, -212, -782, -359, -716, +-456, -558, -462, -347, -337, -103, -107, 148, +152, 369, 388, 534, 565, 639, 613, 666, +472, 577, 182, 376, -153, 106, -435, -187, +-625, -468, -685, -679, -564, -759, -267, -684, +103, -481, 433, -206, 675, 84, 787, 347, +720, 541, 478, 634, 151, 617, -176, 522, +-443, 382, -630, 204, -725, -14, -704, -243, +-573, -434, -378, -563, -145, -630, 143, -615, +443, -483, 677, -232, 804, 75, 817, 363, +700, 586, 445, 705, 79, 681, -314, 499, +-647, 212, -863, -96, -930, -375, -805, -579, +-500, -635, -118, -509, 236, -250, 502, 49, +658, 321, 684, 516, 580, 570, 376, 437, +148, 156, -26, -155, -142, -392, -224, -496, +-252, -440, -213, -241, -167, 29, -164, 259, +-199, 358, -232, 296, -246, 118, -246, -85, +-208, -226, -86, -251, 120, -134, 329, 90, +484, 314, 574, 425, 582, 387, 480, 216, +280, -34, 17, -291, -246, -469, -442, -493, +-550, -373, -585, -184, -542, 8, -411, 164, +-223, 253, -22, 252, 169, 179, 355, 82, +509, 4, 578, -38, 529, -33, 384, 9, +167, 58, -106, 93, -366, 101, -514, 75, +-516, 22, -413, -50, -230, -139, 14, -223, +259, -260, 424, -227, 453, -136, 353, -30, +181, 76, -19, 173, -214, 234, -341, 226, +-356, 152, -290, 46, -199, -56, -96, -129, +32, -166, 168, -160, 250, -114, 257, -44, +240, 26, 240, 88, 219, 137, 137, 159, +26, 152, -82, 122, -202, 66, -341, -27, +-452, -140, -479, -221, -393, -247, -219, -223, +0, -142, 248, -10, 497, 131, 658, 215, +665, 211, 526, 134, 294, 19, 14, -86, +-284, -131, -534, -101, -655, -19, -616, 82, +-479, 160, -292, 170, -57, 98, 183, -19, +350, -126, 422, -178, 435, -151, 399, -50, +305, 73, 157, 148, 8, 144, -107, 72, +-192, -42, -262, -162, -294, -237, -263, -233, +-187, -153, -119, -21, -71, 128, -9, 254, +79, 322, 176, 318, 247, 251, 295, 147, +336, 29, 325, -101, 200, -233, -5, -324, +-198, -337, -360, -290, -498, -206, -557, -85, +-463, 64, -236, 189, 32, 255, 248, 264, +402, 232, 497, 163, 499, 81, 401, 20, +263, -8, 154, -2, 66, 20, -41, 30, +-170, 8, -279, -42, -355, -121, -436, -223, +-533, -315, -558, -361, -447, -337, -239, -249, +17, -114, 304, 61, 575, 248, 756, 404, +808, 500, 713, 545, 493, 546, 193, 485, +-133, 343, -442, 134, -676, -107, -778, -360, +-713, -614, -510, -823, -243, -926, 34, -884, +302, -690, 517, -364, 601, 56, 541, 505, +377, 878, 134, 1082, -169, 1076, -447, 861, +-597, 478, -571, 19, -389, -391, -122, -641, +189, -684, 496, -543, 702, -287, 730, -18, +591, 164, 325, 193, -35, 53, -407, -183, +-667, -398, -745, -504, -660, -456, -465, -251, +-215, 72, 44, 434, 257, 723, 376, 847, +392, 785, 347, 572, 283, 251, 215, -121, +134, -467, 52, -708, 6, -801, -5, -743, +-34, -545, -102, -237, -149, 104, -154, 393, +-159, 578, -189, 636, -193, 562, -138, 369, +-58, 105, 8, -160, 67, -361, 151, -458, +233, -448, 239, -355, 164, -208, 86, -27, +41, 154, -12, 287, -80, 352, -102, 347, +-66, 274, -36, 143, -75, -17, -152, -162, +-207, -268, -232, -322, -224, -306, -124, -205, +107, -40, 375, 139, 567, 295, 628, 408, +557, 446, 348, 373, 16, 197, -362, -36, +-674, -274, -825, -472, -806, -608, -645, -635, +-348, -525, 46, -309, 412, -34, 643, 251, +731, 500, 728, 667, 625, 723, 380, 661, +49, 486, -236, 231, -416, -38, -551, -272, +-617, -441, -511, -524, -260, -520, -16, -455, +148, -359, 270, -240, 360, -111, 348, -10, +209, 60, 40, 132, -53, 215, -68, 285, +-71, 324, -62, 338, -1, 338, 74, 332, +70, 303, -16, 234, -103, 125, -153, -27, +-190, -228, -227, -457, -206, -656, -84, -767, +86, -756, 225, -591, 336, -280, 420, 106, +429, 474, 336, 752, 171, 882, -21, 842, +-199, 656, -340, 369, -437, 47, -476, -243, +-444, -454, -349, -576, -230, -611, -100, -553, +62, -415, 249, -228, 409, -29, 514, 158, +597, 306, 643, 382, 554, 368, 293, 273, +-34, 128, -333, -35, -605, -177, -817, -248, +-860, -217, -690, -106, -388, 45, -73, 204, +219, 327, 488, 363, 671, 292, 689, 124, +553, -102, 357, -324, 156, -481, -48, -539, +-226, -484, -322, -320, -328, -83, -285, 173, +-249, 394, -228, 540, -192, 563, -149, 451, +-107, 252, -39, 23, 81, -191, 217, -351, +343, -418, 434, -374, 441, -246, 328, -95, +121, 20, -126, 82, -346, 104, -471, 105, +-461, 106, -318, 142, -96, 234, 127, 332, +269, 363, 294, 287, 212, 102, 74, -173, +-59, -470, -141, -691, -139, -754, -48, -623, +86, -319, 173, 83, 174, 471, 96, 736, +-37, 800, -184, 658, -275, 368, -266, 25, +-154, -281, 16, -471, 180, -493, 289, -363, +323, -145, 270, 71, 135, 207, -28, 233, +-153, 152, -217, -11, -221, -184, -170, -282, +-89, -264, -3, -139, 67, 51, 101, 250, +102, 399, 83, 437, 46, 338, -19, 131, +-91, -115, -133, -330, -122, -473, -72, -514, +-12, -431, 52, -237, 134, 12, 204, 251, +208, 439, 168, 546, 124, 537, 63, 406, +-36, 195, -136, -34, -192, -247, -207, -412, +-210, -482, -192, -432, -128, -290, -31, -103, +54, 79, 115, 215, 163, 272, 178, 232, +134, 110, 52, -49, -15, -194, -48, -283, +-52, -290, -37, -203, 4, -23, 64, 205, +101, 405, 77, 521, 16, 539, -27, 461, +-53, 287, -91, 42, -118, -220, -108, -443, +-88, -590, -88, -651, -101, -616, -93, -487, +-43, -290, 37, -62, 132, 158, 234, 335, +318, 439, 343, 456, 289, 412, 158, 356, +-23, 311, -203, 269, -336, 221, -421, 153, +-444, 40, -368, -142, -213, -369, -32, -574, +143, -690, 293, -666, 399, -495, 450, -217, +415, 102, 290, 380, 105, 535, -98, 533, +-283, 395, -403, 192, -409, 6, -296, -110, +-100, -130, 110, -56, 282, 76, 378, 197, +362, 260, 205, 242, -45, 132, -286, -59, +-455, -295, -531, -501, -486, -621, -298, -635, +-6, -531, 309, -302, 571, 22, 731, 363, +748, 644, 602, 805, 304, 804, -67, 635, +-421, 338, -690, -11, -809, -337, -741, -560, +-507, -624, -172, -529, 190, -315, 480, -48, +621, 196, 600, 347, 438, 368, 185, 264, +-77, 74, -285, -144, -408, -333, -431, -449, +-367, -461, -247, -355, -88, -152, 91, 107, +251, 385, 376, 629, 461, 779, 477, 786, +396, 632, 218, 327, -17, -69, -264, -468, +-491, -780, -662, -929, -707, -875, -575, -635, +-307, -280, 4, 86, 305, 376, 565, 544, +714, 579, 700, 497, 532, 335, 267, 147, +-35, -21, -321, -141, -531, -209, -604, -225, +-526, -186, -341, -114, -102, -25, 155, 63, +359, 121, 442, 123, 396, 76, 248, 5, +32, -62, -183, -99, -317, -92, -325, -48, +-219, 5, -47, 50, 145, 62, 311, 23, +394, -59, 350, -147, 198, -198, -3, -197, +-213, -139, -394, -35, -504, 83, -502, 188, +-377, 263, -164, 292, 64, 273, 266, 215, +427, 130, 526, 20, 534, -99, 452, -206, +311, -282, 129, -311, -72, -290, -257, -223, +-391, -133, -467, -45, -492, 20, -473, 48, +-395, 45, -236, 44, -12, 74, 232, 142, +449, 242, 581, 343, 581, 404, 454, 373, +236, 230, -29, -2, -273, -267, -426, -492, +-461, -605, -374, -568, -193, -393, 14, -139, +178, 115, 240, 294, 175, 352, 33, 300, +-89, 194, -144, 95, -116, 44, -8, 53, +146, 97, 293, 134, 378, 122, 355, 42, +229, -88, 30, -223, -224, -316, -476, -330, +-639, -261, -674, -130, -585, 27, -369, 163, +-48, 256, 305, 304, 612, 303, 835, 253, +924, 169, 823, 55, 540, -83, 151, -221, +-257, -324, -622, -364, -863, -333, -905, -228, +-754, -70, -499, 89, -206, 218, 103, 301, +380, 322, 548, 290, 594, 241, 574, 201, +491, 160, 329, 104, 122, 24, -83, -88, +-274, -224, -436, -359, -541, -457, -530, -495, +-373, -452, -136, -324, 97, -127, 296, 94, +444, 299, 475, 468, 375, 579, 195, 615, +10, 563, -134, 429, -237, 228, -288, -16, +-256, -280, -167, -525, -87, -692, -42, -739, +-9, -649, 33, -444, 74, -148, 108, 182, +129, 468, 145, 648, 150, 690, 131, 588, +79, 374, 8, 113, -49, -144, -85, -365, +-112, -508, -135, -540, -146, -473, -133, -341, +-116, -157, -129, 58, -150, 243, -126, 359, +-48, 403, 56, 370, 181, 261, 324, 118, +442, 0, 493, -66, 449, -76, 304, -48, +86, -27, -187, -65, -490, -172, -731, -323, +-822, -464, -747, -535, -532, -487, -214, -306, +145, -14, 469, 326, 696, 622, 782, 794, +739, 814, 589, 689, 346, 446, 51, 145, +-215, -164, -406, -449, -504, -669, -511, -776, +-452, -753, -336, -620, -180, -396, -24, -103, +96, 199, 181, 430, 230, 555, 225, 565, +151, 477, 55, 333, 0, 193, -1, 100, +24, 53, 58, 22, 107, -25, 146, -104, +133, -225, 54, -374, -44, -509, -131, -566, +-225, -501, -311, -317, -325, -53, -231, 239, +-62, 509, 120, 700, 271, 764, 387, 684, +442, 488, 379, 222, 202, -70, -10, -359, +-205, -597, -376, -722, -498, -711, -523, -575, +-415, -335, -198, -28, 32, 286, 224, 531, +388, 644, 498, 613, 494, 457, 383, 224, +240, -23, 92, -208, -79, -279, -260, -250, +-382, -179, -398, -112, -347, -77, -277, -87, +-169, -117, -10, -137, 138, -110, 218, -18, +238, 122, 227, 250, 168, 315, 47, 303, +-78, 221, -146, 92, -146, -35, -103, -101, +-30, -116, 74, -116, 190, -118, 244, -141, +197, -205, 94, -291, -26, -346, -171, -304, +-318, -148, -401, 98, -354, 377, -184, 612, +26, 741, 215, 707, 375, 488, 459, 126, +393, -289, 203, -669, -30, -934, -247, -1009, +-400, -857, -456, -511, -387, -51, -190, 419, +67, 796, 285, 996, 419, 965, 471, 714, +427, 319, 276, -108, 50, -472, -176, -719, +-339, -810, -444, -730, -505, -523, -475, -271, +-329, -26, -118, 192, 89, 371, 292, 485, +495, 524, 628, 500, 606, 416, 450, 262, +236, 52, -5, -176, -260, -374, -476, -494, +-583, -512, -558, -429, -449, -269, -297, -77, +-90, 80, 145, 151, 309, 138, 365, 83, +367, 23, 343, -1, 273, 57, 161, 203, +51, 383, -18, 515, -81, 537, -171, 414, +-234, 156, -222, -183, -201, -526, -202, -790, +-167, -903, -72, -840, 39, -621, 134, -287, +200, 105, 225, 484, 194, 785, 92, 966, +-36, 988, -118, 844, -124, 553, -67, 164, +23, -253, 124, -612, 208, -831, 226, -882, +128, -772, -64, -524, -279, -202, -447, 105, +-517, 350, -446, 516, -208, 580, 138, 534, +452, 417, 635, 273, 672, 108, 557, -71, +292, -225, -55, -304, -373, -307, -575, -251, +-622, -157, -541, -36, -343, 83, -48, 155, +234, 165, 392, 135, 425, 82, 372, 24, +252, -19, 90, -48, -86, -57, -219, -52, +-261, -35, -234, -16, -175, 4, -74, 36, +50, 77, 146, 92, 190, 65, 186, 13, +164, -46, 142, -101, 89, -134, -14, -121, +-117, -50, -196, 56, -270, 145, -322, 184, +-299, 159, -185, 66, -7, -79, 185, -215, +357, -276, 484, -253, 503, -151, 371, 12, +123, 182, -149, 280, -371, 279, -504, 195, +-513, 57, -371, -93, -129, -193, 114, -215, +304, -188, 401, -145, 369, -117, 225, -133, +31, -179, -155, -192, -265, -134, -265, 8, +-169, 221, -16, 456, 134, 622, 216, 632, +223, 455, 154, 124, 4, -275, -166, -637, +-284, -860, -312, -885, -236, -691, -69, -341, +132, 48, 302, 384, 383, 611, 335, 676, +189, 567, 2, 341, -181, 89, -313, -118, +-349, -241, -282, -259, -148, -190, -6, -76, +97, 29, 143, 70, 133, 24, 84, -79, +40, -191, 50, -272, 122, -277, 208, -178, +238, 2, 195, 186, 99, 312, -57, 359, +-257, 321, -424, 201, -491, 46, -445, -87, +-307, -156, -101, -156, 154, -116, 400, -65, +536, -26, 536, -9, 446, -12, 286, -11, +77, 13, -133, 68, -314, 134, -443, 178, +-477, 180, -409, 124, -255, 15, -43, -121, +165, -236, 321, -285, 388, -231, 340, -88, +212, 97, 67, 262, -84, 368, -217, 378, +-274, 273, -239, 94, -151, -86, -46, -208, +64, -256, 165, -218, 224, -101, 207, 39, +145, 132, 84, 162, 10, 134, -105, 48, +-223, -70, -270, -166, -231, -204, -142, -180, +-17, -94, 153, 35, 306, 173, 344, 279, +260, 319, 110, 264, -68, 138, -253, -21, +-397, -171, -418, -269, -280, -276, -59, -183, +152, -28, 328, 129, 448, 223, 444, 224, +309, 138, 110, -12, -77, -182, -221, -311, +-338, -358, -414, -317, -395, -217, -292, -91, +-176, 47, -57, 171, 92, 263, 247, 313, +357, 330, 397, 318, 377, 273, 338, 181, +266, 54, 125, -79, -43, -201, -188, -303, +-311, -379, -420, -423, -496, -442, -501, -432, +-412, -393, -253, -307, -54, -163, 175, 37, +409, 268, 582, 487, 632, 650, 554, 713, +407, 647, 218, 468, -18, 226, -242, -45, +-366, -295, -385, -469, -371, -547, -354, -560, +-310, -528, -227, -460, -142, -376, -77, -284, +21, -163, 170, -3, 296, 177, 350, 362, +360, 521, 339, 601, 279, 570, 174, 448, +42, 261, -60, 47, -112, -137, -161, -240, +-213, -257, -237, -228, -251, -196, -273, -194, +-279, -219, -256, -259, -179, -296, -44, -292, +114, -189, 273, 0, 422, 201, 521, 374, +521, 497, 420, 525, 244, 430, 14, 262, +-249, 87, -492, -64, -628, -171, -606, -212, +-460, -201, -236, -167, 33, -124, 288, -89, +448, -81, 463, -88, 372, -74, 229, -27, +50, 54, -115, 167, -191, 300, -177, 396, +-137, 400, -92, 285, -48, 66, -30, -205, +-43, -453, -65, -607, -49, -593, 26, -386, +107, -45, 155, 328, 196, 626, 204, 776, +136, 730, 23, 504, -81, 182, -165, -142, +-220, -398, -238, -540, -216, -550, -156, -462, +-82, -325, -15, -179, 50, -44, 110, 67, +162, 155, 215, 225, 254, 278, 245, 297, +191, 284, 116, 245, 26, 174, -65, 88, +-132, 7, -148, -56, -133, -110, -133, -157, +-155, -197, -175, -235, -197, -281, -219, -313, +-213, -302, -153, -242, -29, -137, 124, 3, +268, 151, 409, 275, 525, 355, 550, 375, +459, 344, 279, 282, 43, 199, -210, 87, +-447, -53, -624, -204, -677, -360, -597, -515, +-429, -629, -192, -645, 88, -531, 336, -283, +496, 49, 537, 393, 466, 674, 340, 832, +194, 816, 22, 618, -130, 301, -208, -57, +-237, -407, -254, -698, -251, -863, -207, -873, +-124, -738, -26, -479, 60, -114, 142, 292, +205, 646, 205, 871, 140, 913, 38, 751, +-70, 420, -159, 11, -192, -373, -143, -640, +-26, -731, 108, -639, 220, -420, 281, -157, +257, 71, 152, 221, -4, 275, -190, 250, +-371, 193, -482, 139, -489, 110, -383, 102, +-177, 111, 87, 125, 378, 122, 643, 99, +779, 61, 735, -4, 540, -93, 216, -191, +-188, -281, -565, -339, -819, -334, -894, -256, +-766, -109, -477, 100, -102, 328, 272, 503, +540, 576, 638, 539, 578, 398, 404, 175, +188, -64, 4, -260, -115, -382, -165, -424, +-149, -386, -100, -303, -55, -200, -34, -82, +-36, 35, -55, 141, -93, 257, -141, 380, +-161, 460, -140, 467, -91, 395, -16, 246, +78, 25, 166, -207, 228, -397, 248, -508, +227, -513, 181, -405, 99, -233, -35, -48, +-179, 134, -278, 283, -310, 362, -270, 370, +-181, 345, -63, 287, 81, 188, 210, 73, +285, -35, 318, -125, 311, -186, 233, -220, +90, -245, -76, -271, -226, -299, -330, -326, +-381, -334, -372, -268, -274, -112, -120, 125, +17, 405, 127, 662, 222, 797, 272, 749, +263, 520, 221, 156, 186, -259, 177, -618, +166, -825, 116, -861, 29, -745, -72, -520, +-196, -243, -332, 17, -418, 218, -400, 360, +-302, 457, -185, 505, -51, 495, 110, 434, +247, 317, 298, 143, 273, -63, 230, -247, +206, -387, 192, -471, 173, -483, 159, -421, +129, -315, 26, -194, -145, -66, -317, 61, +-446, 180, -505, 279, -477, 350, -352, 368, +-123, 321, 159, 210, 393, 49, 542, -128, +609, -266, 553, -339, 361, -341, 94, -266, +-182, -145, -419, -18, -567, 88, -600, 163, +-495, 198, -269, 214, 16, 234, 301, 247, +524, 222, 607, 148, 530, 21, 340, -166, +75, -376, -213, -532, -448, -571, -554, -476, +-513, -246, -359, 76, -127, 407, 136, 658, +350, 769, 444, 712, 419, 510, 320, 226, +174, -70, 7, -323, -146, -493, -249, -553, +-295, -510, -294, -390, -232, -223, -121, -27, +-12, 163, 66, 307, 125, 383, 162, 385, +162, 323, 143, 211, 110, 83, 60, -22, +1, -84, -50, -107, -73, -95, -54, -59, +-17, -16, 16, 20, 52, 47, 59, 62, +11, 51, -59, 10, -126, -64, -192, -149, +-242, -222, -239, -250, -159, -202, -3, -50, +177, 178, 327, 412, 419, 579, 413, 622, +296, 499, 113, 217, -87, -143, -261, -496, +-371, -753, -397, -837, -332, -722, -197, -460, +-27, -113, 135, 258, 230, 572, 232, 752, +178, 780, 111, 685, 35, 472, -29, 163, +-55, -181, -58, -485, -56, -703, -49, -793, +-32, -726, -12, -516, -8, -205, -26, 141, +-30, 428, -12, 586, 6, 595, 32, 460, +78, 216, 103, -62, 82, -280, 32, -395, +-28, -400, -81, -306, -113, -151, -126, 7, +-111, 135, -65, 213, -6, 220, 62, 171, +129, 90, 159, -7, 144, -111, 103, -198, +50, -250, -2, -256, -38, -210, -57, -108, +-65, 18, -87, 120, -130, 171, -166, 151, +-186, 70, -188, -41, -153, -132, -67, -160, +60, -104, 206, 26, 338, 187, 429, 315, +457, 368, 391, 326, 238, 188, 42, -15, +-179, -229, -386, -398, -530, -506, -588, -535, +-555, -475, -434, -327, -248, -123, -20, 96, +219, 311, 408, 499, 518, 615, 558, 630, +514, 548, 386, 388, 210, 179, 12, -52, +-170, -263, -301, -428, -381, -520, -403, -533, +-358, -477, -267, -353, -151, -170, -12, 47, +131, 260, 239, 433, 294, 525, 294, 524, +241, 434, 132, 270, -27, 53, -198, -150, +-325, -282, -380, -335, -355, -314, -233, -211, +-23, -50, 220, 99, 421, 197, 541, 241, +568, 227, 475, 141, 265, 10, 1, -117, +-251, -203, -456, -228, -583, -176, -603, -54, +-506, 98, -321, 248, -118, 351, 56, 372, +206, 291, 317, 129, 356, -79, 342, -273, +318, -405, 286, -449, 228, -388, 143, -241, +52, -47, -19, 148, -98, 309, -205, 401, +-302, 409, -351, 340, -348, 222, -303, 75, +-221, -82, -104, -227, 43, -331, 178, -377, +257, -359, 298, -273, 322, -132, 309, 34, +234, 170, 124, 252, 16, 263, -85, 191, +-194, 59, -287, -79, -315, -177, -284, -212, +-238, -179, -172, -92, -53, 16, 106, 102, +252, 152, 336, 153, 364, 104, 344, 31, +250, -38, 75, -113, -128, -191, -296, -240, +-402, -247, -444, -219, -402, -152, -236, -38, +19, 101, 251, 229, 396, 302, 459, 295, +422, 202, 267, 56, 31, -106, -217, -248, +-390, -329, -449, -320, -409, -230, -268, -103, +-32, 40, 221, 171, 410, 257, 493, 284, +454, 258, 303, 177, 81, 64, -159, -52, +-359, -171, -468, -288, -481, -363, -408, -368, +-256, -324, -39, -225, 187, -60, 362, 146, +454, 347, 460, 516, 387, 622, 245, 622, +55, 502, -141, 282, -291, -6, -385, -315, +-422, -571, -371, -721, -221, -734, -30, -612, +146, -379, 282, -95, 363, 179, 355, 389, +257, 505, 106, 525, -47, 478, -165, 402, +-241, 319, -261, 258, -205, 212, -101, 168, +-4, 94, 73, -27, 122, -196, 118, -387, +71, -555, 21, -659, -8, -667, -16, -570, +-18, -359, 0, -70, 50, 240, 97, 517, +111, 742, 103, 885, 78, 911, 15, 802, +-82, 576, -177, 258, -252, -130, -302, -530, +-300, -858, -212, -1043, -51, -1052, 136, -859, +309, -500, 442, -49, 493, 399, 435, 767, +278, 976, 53, 976, -187, 788, -385, 460, +-486, 60, -471, -335, -362, -632, -196, -785, +-2, -773, 178, -600, 287, -314, 305, 1, +259, 274, 166, 458, 42, 513, -72, 441, +-132, 287, -116, 114, -67, -45, -13, -152, +51, -200, 108, -206, 108, -204, 58, -203, +5, -201, -35, -192, -71, -151, -91, -69, +-81, 39, -54, 151, -34, 235, -43, 243, +-64, 165, -90, 24, -116, -135, -117, -263, +-60, -309, 53, -258, 185, -123, 292, 58, +336, 231, 310, 342, 218, 347, 81, 256, +-81, 100, -225, -84, -310, -266, -322, -385, +-282, -413, -197, -364, -74, -259, 43, -116, +120, 44, 155, 173, 165, 253, 148, 276, +97, 251, 13, 174, -67, 70, -115, -38, +-137, -122, -129, -156, -61, -123, 62, -43, +188, 52, 276, 148, 306, 219, 273, 235, +175, 171, 26, 46, -139, -114, -274, -263, +-358, -373, -390, -424, -369, -398, -304, -283, +-203, -94, -87, 121, 31, 333, 151, 502, +280, 593, 394, 578, 457, 473, 458, 297, +406, 77, 297, -135, 134, -286, -66, -373, +-259, -407, -404, -377, -487, -299, -500, -208, +-444, -123, -323, -21, -165, 84, 7, 186, +166, 272, 287, 332, 346, 352, 347, 327, +304, 265, 221, 166, 121, 51, 35, -48, +-19, -112, -37, -157, -23, -175, -8, -169, +-19, -151, -68, -138, -150, -131, -255, -130, +-353, -116, -397, -74, -354, -7, -208, 88, +12, 205, 260, 338, 480, 442, 621, 485, +643, 430, 540, 273, 333, 35, 41, -243, +-288, -510, -582, -715, -772, -799, -813, -735, +-685, -527, -414, -216, -57, 151, 321, 505, +648, 784, 856, 927, 904, 907, 768, 726, +471, 408, 81, 1, -316, -413, -650, -742, +-871, -938, -922, -961, -786, -815, -499, -528, +-144, -175, 214, 170, 530, 439, 756, 581, +827, 576, 720, 462, 485, 295, 188, 115, +-116, -24, -383, -95, -541, -105, -563, -92, +-472, -75, -328, -84, -163, -124, 9, -193, +158, -260, 235, -292, 231, -273, 200, -205, +169, -117, 128, -17, 63, 78, -8, 153, +-60, 196, -90, 233, -107, 272, -93, 293, +-34, 276, 45, 214, 96, 101, 105, -68, +83, -262, 28, -441, -53, -554, -140, -561, +-192, -434, -184, -208, -118, 68, -17, 344, +94, 565, 182, 674, 217, 638, 179, 474, +83, 217, -25, -66, -113, -322, -169, -489, +-191, -544, -160, -481, -78, -333, 24, -141, +111, 46, 186, 187, 249, 266, 252, 285, +173, 262, 47, 216, -79, 176, -201, 144, +-298, 128, -335, 104, -277, 67, -139, 17, +23, -33, 164, -77, 266, -111, 307, -124, +267, -114, 161, -87, 21, -66, -111, -48, +-215, -38, -270, -26, -268, -15, -203, 7, +-90, 34, 39, 72, 167, 136, 281, 207, +362, 261, 378, 287, 317, 297, 175, 262, +-24, 177, -238, 38, -422, -127, -533, -296, +-535, -429, -426, -499, -236, -483, -16, -362, +196, -158, 369, 78, 467, 286, 487, 439, +423, 502, 300, 459, 138, 314, -29, 127, +-166, -58, -252, -195, -290, -253, -285, -242, +-231, -185, -145, -104, -52, -25, 22, 7, +70, -1, 75, -51, 39, -119, -16, -179, +-55, -188, -65, -147, -47, -60, -3, 72, +69, 225, 160, 346, 240, 383, 290, 330, +289, 181, 222, -43, 87, -296, -80, -499, +-249, -602, -390, -568, -471, -399, -454, -136, +-331, 155, -137, 406, 94, 565, 313, 577, +471, 451, 511, 220, 420, -48, 232, -305, +5, -499, -214, -595, -371, -567, -429, -422, +-392, -204, -280, 45, -125, 270, 54, 434, +226, 494, 371, 445, 463, 293, 475, 92, +381, -109, 198, -264, -29, -348, -263, -341, +-478, -255, -629, -125, -653, 12, -526, 121, +-277, 183, 18, 182, 306, 144, 524, 71, +618, -17, 565, -108, 408, -167, 206, -179, +6, -142, -155, -51, -252, 71, -269, 205, +-226, 320, -164, 390, -112, 365, -70, 250, +-46, 74, -43, -121, -64, -307, -97, -430, +-113, -449, -87, -367, -24, -198, 58, 13, +149, 211, 234, 346, 294, 415, 303, 407, +264, 331, 184, 208, 76, 94, -46, -3, +-153, -90, -220, -160, -259, -204, -279, -215, +-289, -196, -281, -135, -247, -50, -185, 65, +-86, 186, 65, 278, 245, 303, 409, 261, +511, 158, 527, 9, 445, -149, 265, -283, +18, -350, -235, -325, -428, -192, -536, 7, +-546, 223, -453, 395, -263, 491, -30, 476, +179, 331, 320, 87, 393, -185, 401, -408, +325, -535, 176, -536, 3, -426, -135, -224, +-229, 17, -260, 239, -216, 377, -110, 425, +12, 398, 96, 321, 122, 197, 94, 37, +33, -113, -46, -244, -108, -350, -137, -435, +-116, -456, -45, -404, 59, -273, 156, -92, +223, 112, 245, 301, 208, 441, 108, 496, +-36, 431, -177, 277, -295, 69, -371, -140, +-378, -323, -291, -438, -122, -478, 99, -432, +319, -314, 485, -149, 550, 7, 486, 119, +308, 201, 52, 242, -221, 231, -444, 166, +-551, 84, -521, -5, -385, -79, -200, -126, +0, -144, 175, -139, 289, -92, 326, -18, +293, 40, 221, 75, 131, 76, 56, 50, +8, -15, -6, -94, -4, -168, 5, -190, +2, -153, -23, -68, -74, 43, -142, 155, +-215, 244, -274, 272, -293, 218, -257, 93, +-150, -53, 0, -193, 160, -280, 291, -287, +377, -204, 396, -61, 334, 118, 207, 283, +72, 384, -26, 405, -98, 332, -155, 192, +-199, 16, -218, -152, -228, -294, -240, -370, +-247, -377, -211, -312, -126, -193, -11, -38, +116, 133, 244, 287, 343, 394, 361, 421, +302, 383, 203, 297, 103, 194, -1, 75, +-100, -29, -180, -94, -231, -119, -252, -137, +-243, -170, -194, -210, -115, -252, -24, -262, +64, -234, 136, -155, 160, -30, 141, 147, +101, 314, 60, 432, 26, 482, 10, 464, +29, 378, 78, 237, 128, 76, 145, -85, +112, -215, 18, -319, -115, -394, -250, -443, +-339, -442, -373, -394, -351, -292, -275, -146, +-140, 32, 32, 229, 208, 417, 373, 565, +510, 630, 590, 595, 568, 452, 443, 242, +233, -25, -29, -317, -314, -586, -563, -762, +-713, -808, -737, -713, -635, -490, -436, -186, +-167, 161, 127, 473, 399, 677, 588, 719, +670, 618, 646, 398, 537, 117, 349, -179, +95, -419, -178, -546, -407, -557, -537, -473, +-560, -341, -488, -178, -334, -23, -122, 113, +90, 195, 249, 230, 333, 240, 355, 245, +323, 228, 244, 177, 153, 100, 77, 7, +8, -86, -91, -191, -213, -294, -320, -383, +-372, -426, -369, -419, -310, -352, -185, -230, +7, -60, 221, 147, 392, 357, 479, 524, +472, 615, 387, 628, 243, 541, 78, 376, +-80, 139, -213, -144, -322, -430, -387, -657, +-395, -808, -349, -858, -265, -777, -156, -555, +-31, -215, 93, 175, 206, 556, 280, 851, +313, 1023, 306, 1031, 272, 882, 215, 587, +142, 209, 55, -181, -37, -525, -127, -789, +-210, -941, -270, -937, -299, -795, -287, -533, +-234, -193, -132, 191, -7, 557, 111, 851, +184, 1001, 211, 985, 209, 816, 197, 521, +182, 156, 145, -223, 84, -544, 2, -758, +-78, -817, -156, -741, -216, -549, -238, -279, +-204, 42, -131, 358, -41, 601, 51, 719, +124, 704, 153, 581, 128, 363, 78, 95, +38, -170, 33, -367, 44, -468, 60, -457, +59, -376, 41, -259, -3, -133, -77, -18, +-155, 81, -191, 159, -157, 233, -77, 311, +19, 402, 95, 443, 145, 402, 148, 264, +98, 47, 15, -226, -58, -492, -100, -681, +-119, -735, -118, -623, -90, -388, -31, -87, +31, 202, 78, 436, 115, 571, 167, 602, +204, 524, 199, 386, 144, 227, 56, 65, +-55, -97, -174, -257, -258, -398, -287, -506, +-255, -553, -191, -556, -116, -497, -45, -374, +18, -190, 65, 14, 115, 218, 177, 397, +250, 537, 319, 631, 344, 641, 304, 548, +191, 346, 21, 79, -185, -236, -379, -551, +-515, -814, -545, -942, -455, -889, -267, -669, +-23, -337, 227, 45, 423, 409, 513, 679, +500, 821, 404, 787, 258, 608, 71, 348, +-128, 78, -294, -185, -378, -396, -380, -520, +-327, -557, -243, -523, -145, -449, -53, -340, +4, -201, 42, -28, 92, 147, 185, 325, +294, 479, 391, 596, 456, 642, 465, 584, +371, 403, 147, 130, -162, -184, -468, -491, +-690, -724, -784, -840, -708, -788, -467, -563, +-107, -199, 257, 202, 526, 572, 648, 846, +629, 971, 489, 920, 264, 696, 10, 351, +-214, -40, -349, -400, -386, -692, -340, -860, +-237, -892, -86, -762, 70, -489, 189, -121, +241, 266, 235, 621, 182, 890, 76, 1002, +-52, 934, -150, 701, -175, 372, -153, 6, +-104, -333, -43, -617, 19, -787, 32, -819, +-11, -730, -66, -561, -83, -332, -52, -52, +13, 254, 109, 551, 204, 773, 267, 896, +261, 885, 196, 736, 92, 451, -12, 77, +-103, -328, -166, -677, -191, -903, -185, -980, +-170, -889, -176, -648, -192, -291, -188, 107, +-129, 488, -35, 762, 78, 902, 201, 886, +326, 719, 404, 421, 393, 55, 297, -305, +152, -583, -4, -727, -160, -753, -285, -662, +-362, -488, -377, -266, -343, -61, -266, 104, +-144, 220, 24, 318, 195, 411, 311, 472, +349, 490, 329, 458, 269, 371, 159, 205, +25, -29, -92, -305, -153, -537, -177, -692, +-194, -751, -204, -705, -193, -552, -173, -330, +-162, -78, -133, 177, -50, 386, 90, 547, +235, 653, 350, 696, 407, 636, 391, 485, +277, 252, 93, -30, -101, -334, -257, -619, +-358, -826, -405, -905, -385, -827, -310, -621, +-187, -308, -49, 47, 87, 408, 209, 709, +312, 897, 379, 923, 393, 790, 345, 515, +240, 145, 89, -245, -101, -601, -288, -830, +-422, -871, -465, -727, -438, -467, -364, -131, +-243, 198, -64, 454, 141, 581, 328, 575, +471, 478, 561, 342, 570, 205, 464, 75, +271, -28, 33, -117, -206, -185, -435, -254, +-607, -320, -672, -360, -606, -318, -440, -202, +-214, -44, 38, 141, 284, 309, 487, 431, +600, 472, 612, 418, 527, 267, 370, 93, +152, -67, -87, -187, -304, -256, -450, -260, +-507, -203, -478, -105, -376, -10, -219, 45, +-42, 81, 94, 92, 183, 102, 238, 117, +288, 156, 317, 194, 310, 236, 261, 245, +187, 184, 82, 50, -72, -149, -255, -363, +-406, -541, -453, -616, -400, -556, -272, -327, +-91, 28, 120, 429, 291, 767, 367, 969, +351, 978, 280, 783, 169, 406, 25, -80, +-100, -550, -158, -918, -151, -1118, -143, -1132, +-147, -951, -142, -621, -108, -177, -52, 298, +15, 720, 72, 1032, 112, 1187, 134, 1149, +121, 903, 79, 491, 12, -31, -57, -547, +-111, -974, -127, -1231, -102, -1268, -33, -1069, +41, -682, 81, -182, 88, 323, 81, 729, +61, 984, 10, 1040, -49, 895, -86, 573, +-79, 163, -56, -258, -27, -585, 19, -778, +86, -819, 137, -703, 145, -457, 109, -154, +45, 126, -34, 338, -129, 450, -205, 489, +-237, 450, -221, 352, -181, 214, -113, 72, +-9, -78, 120, -230, 223, -377, 262, -510, +255, -587, 230, -576, 196, -469, 136, -274, +62, 13, -24, 336, -103, 644, -175, 858, +-227, 936, -249, 866, -243, 658, -216, 322, +-176, -103, -126, -532, -71, -902, 8, -1137, +98, -1206, 177, -1096, 237, -811, 298, -361, +336, 169, 319, 693, 247, 1121, 150, 1384, +40, 1448, -98, 1297, -245, 936, -360, 405, +-409, -182, -410, -744, -369, -1193, -275, -1464, +-113, -1489, 79, -1252, 261, -782, 409, -184, +501, 429, 507, 965, 403, 1314, 216, 1422, +-10, 1260, -216, 886, -373, 400, -451, -69, +-435, -477, -326, -772, -169, -918, -15, -925, +105, -822, 183, -641, 223, -398, 226, -100, +205, 264, 175, 639, 155, 962, 127, 1157, +79, 1170, 4, 962, -81, 550, -162, -16, +-231, -616, -277, -1101, -275, -1383, -209, -1402, +-115, -1159, -22, -704, 65, -147, 157, 422, +218, 882, 234, 1176, 217, 1283, 193, 1202, +157, 952, 88, 574, -1, 118, -79, -361, +-137, -777, -198, -1096, -251, -1268, -267, -1262, +-209, -1051, -97, -670, 34, -167, 164, 367, +276, 855, 335, 1227, 309, 1399, 205, 1328, +57, 1020, -99, 528, -257, -80, -380, -686, +-426, -1201, -372, -1525, -244, -1591, -73, -1387, +110, -965, 280, -383, 407, 279, 472, 907, +482, 1412, 438, 1702, 348, 1740, 191, 1507, +-25, 1028, -269, 342, -488, -438, -657, -1202, +-762, -1825, -770, -2178, -642, -2186, -379, -1826, +-33, -1141, 345, -229, 702, 745, 976, 1617, +1082, 2206, 1006, 2410, 765, 2203, 398, 1635, +-54, 802, -519, -134, -904, -1014, -1146, -1701, +-1208, -2079, -1078, -2119, -759, -1831, -306, -1278, +203, -551, 676, 217, 1039, 922, 1228, 1457, +1215, 1757, 1001, 1793, 622, 1560, 134, 1090, +-382, 468, -826, -201, -1132, -842, -1240, -1346, +-1136, -1651, -841, -1691, -419, -1450, 66, -953, +537, -293, 919, 425, 1135, 1086, 1142, 1575, +962, 1810, 649, 1732, 269, 1359, -135, 768, +-501, 77, -791, -626, -964, -1220, -1005, -1623, +-920, -1783, -734, -1681, -452, -1326, -82, -769, +321, -82, 705, 656, 1014, 1327, 1205, 1831, +1225, 2076, 1047, 2014, 679, 1628, 184, 965, +-380, 103, -937, -808, -1382, -1609, -1606, -2170, +-1548, -2384, -1219, -2209, -671, -1650, 11, -786, +733, 247, 1362, 1247, 1772, 2054, 1869, 2516, +1642, 2535, 1124, 2092, 394, 1275, -420, 227, +-1162, -858, -1686, -1762, -1909, -2329, -1798, -2447, +-1389, -2120, -748, -1425, -2, -523, 709, 421, +1268, 1230, 1610, 1790, 1680, 2028, 1462, 1921, +1015, 1521, 437, 911, -165, 190, -700, -547, +-1094, -1184, -1300, -1646, -1288, -1845, -1092, -1748, +-764, -1375, -355, -791, 84, -78, 482, 639, +776, 1238, 944, 1632, 996, 1747, 941, 1579, +753, 1168, 452, 591, 92, -78, -260, -721, +-582, -1254, -841, -1596, -982, -1716, -966, -1598, +-809, -1239, -544, -672, -193, 18, 214, 717, +613, 1339, 909, 1761, 1064, 1910, 1068, 1737, +920, 1265, 606, 552, 158, -272, -342, -1075, +-790, -1723, -1113, -2081, -1265, -2090, -1202, -1735, +-920, -1074, -459, -211, 80, 699, 594, 1502, +994, 2033, 1232, 2211, 1273, 2010, 1109, 1461, +762, 652, 290, -269, -223, -1136, -708, -1814, +-1088, -2176, -1283, -2166, -1241, -1777, -999, -1075, +-610, -171, -129, 759, 388, 1561, 830, 2087, +1103, 2232, 1181, 1972, 1078, 1355, 806, 505, +405, -413, -27, -1224, -417, -1799, -720, -2017, +-920, -1872, -972, -1404, -875, -720, -667, 54, +-387, 784, -61, 1361, 287, 1692, 591, 1720, +790, 1476, 853, 998, 787, 368, 607, -314, +363, -917, 91, -1344, -174, -1511, -408, -1410, +-574, -1069, -654, -548, -648, 52, -571, 610, +-442, 1029, -257, 1261, -45, 1269, 175, 1081, +377, 724, 547, 267, 652, -215, 675, -649, +598, -994, 425, -1187, 186, -1186, -94, -993, +-379, -620, -618, -127, -748, 424, -753, 931, +-635, 1294, -409, 1426, -100, 1312, 224, 955, +495, 406, 656, -237, 685, -857, 595, -1341, +414, -1593, 196, -1552, -19, -1242, -203, -693, +-344, -6, -423, 690, -455, 1259, -451, 1596, +-419, 1622, -348, 1353, -213, 848, -7, 190, +241, -482, 470, -1043, 632, -1395, 687, -1502, +616, -1344, 407, -967, 112, -421, -193, 190, +-438, 755, -589, 1181, -643, 1398, -591, 1352, +-434, 1045, -227, 531, -32, -118, 146, -759, +304, -1259, 427, -1514, 488, -1469, 495, -1112, +450, -526, 355, 175, 190, 837, -31, 1316, +-257, 1529, -449, 1450, -571, 1107, -603, 564, +-530, -60, -372, -671, -143, -1156, 120, -1457, +367, -1526, 551, -1342, 657, -924, 661, -354, +535, 284, 299, 908, 3, 1391, -286, 1649, +-533, 1615, -705, 1294, -758, 734, -658, 41, +-448, -694, -184, -1321, 102, -1699, 392, -1762, +643, -1507, 792, -977, 818, -260, 730, 511, +539, 1199, 239, 1650, -128, 1801, -495, 1633, +-785, 1179, -973, 508, -1013, -253, -867, -977, +-552, -1528, -138, -1801, 288, -1774, 665, -1448, +930, -875, 1046, -131, 985, 662, 774, 1383, +450, 1882, 60, 2083, -345, 1948, -702, 1465, +-961, 683, -1077, -270, -1015, -1216, -775, -1976, +-380, -2391, 96, -2395, 565, -1950, 935, -1117, +1151, -46, 1172, 1048, 984, 1971, 604, 2544, +107, 2666, -409, 2309, -854, 1517, -1169, 430, +-1312, -751, -1226, -1799, -918, -2532, -437, -2802, +136, -2563, 718, -1833, 1203, -744, 1500, 491, +1529, 1636, 1274, 2489, 794, 2886, 173, 2734, +-483, 2072, -1072, 1023, -1485, -200, -1643, -1384, +-1513, -2318, -1143, -2840, -608, -2835, 22, -2331, +664, -1436, 1206, -289, 1555, 919, 1667, 1972, +1515, 2680, 1110, 2929, 504, 2681, -197, 1993, +-876, 943, -1405, -292, -1697, -1492, -1700, -2452, +-1406, -3019, -875, -3086, -204, -2627, 494, -1704, +1104, -453, 1527, 893, 1701, 2106, 1585, 2968, +1202, 3317, 616, 3057, -76, 2245, -772, 1020, +-1346, -397, -1679, -1744, -1716, -2764, -1450, -3258, +-918, -3150, -210, -2479, 528, -1392, 1162, -82, +1574, 1190, 1702, 2203, 1530, 2796, 1098, 2889, +484, 2485, -202, 1678, -853, 611, -1361, -540, +-1628, -1574, -1623, -2327, -1344, -2664, -820, -2539, +-137, -1973, 567, -1086, 1175, -9, 1584, 1066, +1711, 1942, 1515, 2455, 1044, 2529, 411, 2172, +-268, 1444, -893, 463, -1375, -608, -1611, -1557, +-1556, -2232, -1251, -2512, -778, -2362, -177, -1805, +460, -932, 1020, 138, 1413, 1206, 1578, 2062, +1498, 2561, 1177, 2609, 652, 2194, 8, 1362, +-628, 258, -1164, -922, -1513, -1913, -1628, -2536, +-1480, -2696, -1079, -2375, -485, -1606, 190, -517, +833, 666, 1358, 1699, 1687, 2391, 1742, 2650, +1477, 2411, 940, 1710, 221, 682, -540, -442, +-1208, -1433, -1667, -2084, -1826, -2297, -1640, -2070, +-1162, -1469, -502, -643, 219, 226, 863, 959, +1330, 1443, 1551, 1628, 1521, 1553, 1274, 1261, +849, 812, 294, 274, -281, -255, -759, -706, +-1086, -1052, -1269, -1266, -1294, -1307, -1113, -1125, +-754, -743, -303, -227, 145, 325, 556, 842, +886, 1221, 1079, 1380, 1082, 1256, 930, 877, +696, 354, 395, -196, 39, -671, -329, -1007, +-639, -1148, -845, -1078, -939, -816, -936, -453, +-795, -70, -515, 271, -165, 558, 172, 756, +464, 826, 703, 765, 858, 609, 889, 400, +785, 148, 597, -123, 354, -384, 69, -574, +-257, -687, -563, -718, -794, -664, -930, -514, +-952, -279, -837, 12, -578, 314, -209, 564, +183, 722, 516, 750, 796, 650, 989, 422, +1035, 113, 922, -213, 703, -462, 415, -590, +68, -605, -333, -531, -720, -387, -1010, -188, +-1186, 9, -1233, 159, -1100, 236, -745, 280, +-222, 312, 374, 327, 947, 313, 1409, 299, +1643, 283, 1581, 245, 1220, 146, 623, -41, +-99, -287, -835, -552, -1448, -772, -1802, -911, +-1826, -903, -1522, -713, -929, -322, -152, 202, +669, 752, 1384, 1225, 1853, 1536, 1990, 1609, +1758, 1386, 1190, 873, 403, 132, -447, -684, +-1230, -1423, -1823, -1953, -2107, -2189, -1992, -2051, +-1516, -1529, -788, -689, 99, 322, 1013, 1321, +1769, 2149, 2198, 2661, 2225, 2736, 1860, 2287, +1165, 1368, 210, 137, -822, -1158, -1698, -2283, +-2258, -3033, -2416, -3226, -2111, -2773, -1366, -1756, +-330, -394, 764, 1057, 1680, 2327, 2273, 3204, +2434, 3498, 2122, 3123, 1376, 2140, 352, 768, +-733, -750, -1663, -2173, -2266, -3257, -2430, -3776, +-2120, -3592, -1393, -2733, -378, -1354, 698, 308, +1635, 2000, 2270, 3397, 2467, 4213, 2183, 4255, +1486, 3493, 499, 2064, -590, 220, -1574, -1729, +-2276, -3434, -2546, -4539, -2327, -4828, -1663, -4221, +-687, -2823, 420, -877, 1453, 1283, 2245, 3295, +2626, 4740, 2497, 5302, 1881, 4861, 930, 3501, +-160, 1477, -1245, -861, -2150, -3092, -2675, -4778, +-2697, -5541, -2216, -5254, -1317, -4002, -167, -2037, +1049, 307, 2092, 2619, 2752, 4474, 2926, 5489, +2580, 5478, 1731, 4497, 531, 2733, -759, 475, +-1913, -1916, -2750, -4000, -3132, -5375, -2926, -5753, +-2135, -5107, -945, -3572, 373, -1382, 1615, 1126, +2619, 3469, 3186, 5156, 3141, 5857, 2487, 5484, +1412, 4160, 99, 2082, -1272, -401, -2468, -2812, +-3204, -4656, -3295, -5602, -2765, -5522, -1766, -4496, +-432, -2699, 1026, -406, 2310, 1963, 3156, 3943, +3401, 5150, 3018, 5396, 2086, 4685, 759, 3160, +-747, 1029, -2148, -1315, -3177, -3377, -3615, -4735, +-3377, -5178, -2521, -4685, -1182, -3365, 420, -1437, +1996, 770, 3220, 2790, 3859, 4224, 3815, 4847, +3080, 4609, 1735, 3561, 35, 1866, -1673, -202, +-3084, -2229, -3964, -3779, -4153, -4581, -3570, -4545, +-2303, -3709, -633, -2189, 1110, -231, 2674, 1778, +3804, 3376, 4261, 4267, 3909, 4365, 2826, 3687, +1254, 2313, -526, 473, -2220, -1431, -3514, -2959, +-4127, -3805, -3944, -3912, -3033, -3305, -1613, -2079, +71, -457, 1725, 1179, 3039, 2478, 3767, 3214, +3775, 3330, 3088, 2857, 1876, 1855, 345, 498, +-1260, -917, -2615, -2073, -3451, -2776, -3614, -2930, +-3115, -2565, -2070, -1714, -642, -504, 929, 799, +2301, 1893, 3191, 2594, 3460, 2825, 3090, 2552, +2152, 1788, 809, 620, -655, -700, -1957, -1873, +-2858, -2661, -3207, -2947, -2954, -2662, -2174, -1846, +-1019, -625, 284, 740, 1523, 1917, 2494, 2673, +2983, 2909, 2897, 2618, 2271, 1823, 1230, 658, +-26, -649, -1264, -1779, -2280, -2513, -2843, -2776, +-2819, -2561, -2238, -1844, -1246, -719, -44, 559, +1153, 1679, 2118, 2407, 2646, 2673, 2628, 2453, +2095, 1737, 1167, 602, 38, -666, -1081, -1748, +-1952, -2420, -2398, -2606, -2366, -2303, -1882, -1524, +-1036, -381, -11, 851, 984, 1839, 1754, 2392, +2122, 2453, 2054, 2066, 1607, 1280, 889, 199, +36, -944, -800, -1835, -1456, -2304, -1781, -2349, +-1748, -2001, -1433, -1287, -909, -268, -229, 840, +524, 1751, 1178, 2266, 1587, 2365, 1701, 2054, +1540, 1344, 1110, 302, 428, -846, -401, -1787, +-1146, -2308, -1627, -2377, -1813, -2043, -1671, -1317, +-1184, -290, -431, 832, 405, 1745, 1128, 2246, +1616, 2303, 1826, 1979, 1685, 1290, 1195, 293, +500, -791, -250, -1677, -943, -2166, -1475, -2241, +-1730, -1945, -1660, -1300, -1306, -348, -750, 699, +-53, 1570, 678, 2070, 1300, 2163, 1673, 1880, +1714, 1237, 1454, 295, 951, -736, 283, -1532, +-436, -1914, -1066, -1871, -1480, -1476, -1580, -776, +-1416, 113, -1062, 960, -529, 1476, 130, 1559, +752, 1291, 1169, 772, 1330, 89, 1289, -629, +1095, -1168, 712, -1361, 182, -1168, -371, -716, +-815, -128, -1109, 500, -1236, 1054, -1154, 1383, +-834, 1389, -340, 1082, 219, 557, 727, -59, +1070, -694, 1200, -1238, 1091, -1569, 776, -1572, +312, -1255, -238, -693, -755, -4, -1067, 718, +-1123, 1353, -973, 1742, -663, 1774, -235, 1423, +252, 774, 647, -40, 834, -840, 854, -1476, +806, -1792, 681, -1693, 442, -1181, 121, -402, +-176, 430, -408, 1117, -613, 1539, -794, 1627, +-899, 1322, -852, 690, -645, -84, -344, -784, +-7, -1297, 378, -1554, 769, -1505, 1079, -1105, +1201, -440, 1063, 292, 730, 934, 304, 1410, +-173, 1653, -652, 1568, -1033, 1144, -1234, 468, +-1201, -287, -967, -1003, -597, -1569, -132, -1860, +388, -1767, 877, -1293, 1229, -542, 1354, 334, +1232, 1153, 901, 1757, 417, 1989, -140, 1785, +-726, 1187, -1244, 347, -1572, -579, -1620, -1403, +-1358, -1957, -826, -2104, -123, -1786, 661, -1069, +1390, -117, 1872, 888, 2010, 1769, 1791, 2301, +1252, 2337, 465, 1846, -439, 950, -1291, -168, +-1931, -1294, -2265, -2209, -2216, -2682, -1755, -2585, +-979, -1965, -47, -960, 882, 237, 1702, 1425, +2286, 2370, 2482, 2872, 2227, 2809, 1606, 2226, +717, 1233, -316, -21, -1346, -1320, -2178, -2410, +-2591, -3058, -2517, -3119, -2024, -2570, -1185, -1530, +-91, -173, 1046, 1248, 1972, 2458, 2488, 3181, +2542, 3253, 2158, 2670, 1368, 1579, 298, 182, +-814, -1279, -1729, -2476, -2296, -3133, -2419, -3121, +-2059, -2492, -1281, -1382, -301, -4, 690, 1393, +1533, 2484, 2059, 3016, 2150, 2913, 1800, 2236, +1127, 1116, 306, -248, -543, -1574, -1306, -2562, +-1782, -2961, -1872, -2720, -1597, -1912, -1048, -705, +-336, 667, 429, 1884, 1119, 2675, 1564, 2872, +1667, 2464, 1447, 1580, 969, 389, 325, -882, +-391, -1971, -1021, -2634, -1413, -2770, -1483, -2357, +-1252, -1488, -793, -297, -193, 1000, 461, 2133, +1013, 2848, 1310, 2985, 1317, 2514, 1047, 1499, +566, 136, -35, -1321, -664, -2548, -1186, -3252, +-1422, -3261, -1319, -2578, -919, -1327, -296, 242, +446, 1804, 1153, 3025, 1612, 3603, 1678, 3407, +1356, 2506, 737, 1098, -84, -567, -948, -2150, +-1637, -3304, -1944, -3768, -1831, -3473, -1362, -2511, +-597, -1061, 334, 641, 1222, 2259, 1848, 3412, +2077, 3870, 1901, 3559, 1398, 2556, 605, 1029, +-357, -739, -1273, -2379, -1929, -3507, -2185, -3897, +-2012, -3509, -1466, -2426, -617, -856, 397, 894, +1341, 2436, 2004, 3432, 2247, 3695, 2050, 3254, +1455, 2193, 578, 684, -422, -984, -1350, -2428, +-2018, -3346, -2283, -3603, -2110, -3202, -1556, -2200, +-708, -708, 276, 959, 1247, 2417, 2024, 3364, +2440, 3675, 2408, 3294, 1922, 2261, 1026, 721, +-99, -1001, -1228, -2496, -2143, -3463, -2642, -3754, +-2633, -3330, -2120, -2228, -1200, -641, -37, 1096, +1134, 2544, 2079, 3407, 2599, 3591, 2616, 3117, +2128, 2023, 1225, 483, 97, -1154, -1011, -2478, +-1858, -3226, -2303, -3364, -2320, -2898, -1914, -1833, +-1132, -317, -150, 1260, 825, 2515, 1587, 3211, +1994, 3289, 2006, 2742, 1626, 1597, 914, 68, +47, -1454, -757, -2600, -1341, -3181, -1628, -3135, +-1613, -2493, -1288, -1336, -702, 134, 14, 1560, +694, 2577, 1205, 3036, 1469, 2931, 1436, 2290, +1080, 1190, 469, -181, -229, -1487, -855, -2414, +-1274, -2827, -1434, -2741, -1314, -2141, -890, -1083, +-238, 226, 469, 1467, 1085, 2364, 1492, 2789, +1599, 2697, 1370, 2075, 820, 991, 74, -301, +-683, -1508, -1301, -2382, -1684, -2774, -1764, -2620, +-1530, -1952, -1001, -880, -249, 367, 585, 1495, +1324, 2288, 1819, 2621, 2018, 2468, 1876, 1859, +1350, 900, 534, -212, -358, -1202, -1148, -1907, +-1740, -2263, -2092, -2229, -2101, -1784, -1675, -1017, +-918, -123, -29, 707, 841, 1364, 1588, 1807, +2084, 1925, 2193, 1672, 1829, 1128, 1115, 442, +251, -282, -617, -940, -1398, -1424, -1949, -1622, +-2096, -1486, -1784, -1078, -1134, -512, -330, 90, +509, 628, 1257, 995, 1774, 1149, 1907, 1063, +1642, 790, 1104, 426, 409, 59, -357, -265, +-1068, -511, -1592, -660, -1805, -708, -1648, -658, +-1206, -550, -580, -394, 143, -186, 867, 67, +1459, 310, 1772, 526, 1713, 680, 1341, 731, +778, 648, 102, 429, -617, 134, -1244, -178, +-1600, -462, -1612, -684, -1351, -764, -926, -685, +-380, -495, 248, -260, 844, -6, 1214, 254, +1295, 487, 1179, 611, 931, 592, 568, 496, +105, 370, -362, 202, -689, -43, -830, -306, +-853, -491, -779, -534, -602, -500, -335, -426, +-28, -253, 224, 39, 373, 346, 453, 526, +500, 544, 487, 453, 386, 306, 223, 62, +95, -259, 0, -524, -111, -604, -236, -515, +-321, -333, -332, -95, -308, 201, -284, 516, +-225, 719, -97, 738, 47, 596, 182, 365, +293, 55, 375, -305, 409, -649, 370, -865, +246, -894, 54, -760, -174, -492, -378, -97, +-492, 376, -519, 801, -461, 1085, -317, 1175, +-73, 1049, 212, 671, 452, 92, 589, -536, +617, -1038, 529, -1334, 328, -1383, 39, -1117, +-268, -545, -480, 188, -570, 866, -558, 1355, +-451, 1586, -273, 1512, -81, 1061, 117, 311, +281, -531, 366, -1258, 389, -1739, 369, -1874, +328, -1591, 258, -918, 144, 18, 14, 992, +-87, 1788, -183, 2216, -304, 2184, -436, 1684, +-499, 787, -459, -366, -365, -1514, -238, -2357, +-60, -2709, 187, -2509, 463, -1776, 676, -592, +781, 811, 814, 2082, 726, 2895, 451, 3102, +0, 2672, -521, 1653, -963, 213, -1241, -1315, +-1331, -2561, -1164, -3268, -694, -3306, -45, -2662, +612, -1436, 1152, 108, 1521, 1642, 1630, 2843, +1397, 3465, 870, 3357, 191, 2550, -517, 1230, +-1157, -372, -1615, -1954, -1779, -3170, -1606, -3718, +-1164, -3490, -506, -2557, 307, -1104, 1122, 656, +1746, 2373, 2064, 3605, 1999, 4035, 1520, 3598, +679, 2420, -365, 701, -1333, -1248, -2025, -2999, +-2346, -4078, -2222, -4225, -1602, -3468, -600, -2022, +531, -143, 1512, 1830, 2203, 3460, 2517, 4310, +2329, 4181, 1601, 3185, 497, 1583, -663, -363, +-1637, -2344, -2323, -3877, -2624, -4529, -2378, -4142, +-1597, -2918, -483, -1154, 683, 895, 1686, 2889, +2420, 4292, 2742, 4678, 2470, 4030, 1614, 2625, +439, 744, -739, -1373, -1737, -3294, -2480, -4464, +-2796, -4567, -2491, -3727, -1612, -2228, -451, -304, +718, 1735, 1778, 3406, 2602, 4260, 2914, 4160, +2517, 3254, 1546, 1770, 326, -63, -881, -1872, +-1954, -3207, -2727, -3765, -2923, -3498, -2406, -2519, +-1361, -1040, -112, 626, 1115, 2084, 2170, 2980, +2857, 3161, 2911, 2637, 2256, 1553, 1122, 160, +-173, -1186, -1425, -2174, -2450, -2617, -3009, -2458, +-2893, -1748, -2111, -643, -899, 572, 474, 1584, +1764, 2189, 2740, 2317, 3159, 1936, 2880, 1126, +1962, 80, 660, -913, -748, -1628, -1995, -1957, +-2861, -1884, -3177, -1423, -2825, -672, -1887, 157, +-608, 865, 747, 1312, 1968, 1444, 2863, 1264, +3240, 851, 2940, 319, 2028, -181, 747, -539, +-659, -696, -1976, -650, -2977, -462, -3403, -244, +-3092, -86, -2133, -3, -790, -1, 701, -63, +2104, -166, 3140, -227, 3512, -158, 3099, 57, +2053, 321, 636, 529, -905, 648, -2287, 661, +-3207, 509, -3423, 129, -2877, -390, -1753, -814, +-311, -977, 1179, -928, 2431, -720, 3149, -298, +3142, 329, 2419, 901, 1204, 1125, -206, 989, +-1537, 685, -2527, 272, -2944, -320, -2653, -930, +-1736, -1216, -456, -1056, 874, -652, 1972, -172, +2600, 387, 2624, 970, 2012, 1302, 875, 1159, +-490, 640, -1730, -23, -2540, -694, -2743, -1284, +-2278, -1593, -1192, -1434, 282, -802, 1712, 105, +2704, 1044, 3052, 1789, 2688, 2120, 1644, 1896, +94, 1145, -1563, 24, -2846, -1255, -3430, -2336, +-3217, -2839, -2251, -2583, -707, -1684, 1090, -357, +2650, 1170, 3557, 2573, 3650, 3378, 2950, 3250, +1599, 2285, -139, 830, -1902, -807, -3258, -2354, +-3868, -3391, -3642, -3530, -2651, -2713, -1118, -1284, +646, 326, 2283, 1800, 3440, 2861, 3872, 3203, +3534, 2687, 2553, 1520, 1114, 137, -560, -1044, +-2157, -1816, -3298, -2117, -3770, -1909, -3587, -1234, +-2833, -383, -1549, 282, 101, 601, 1741, 686, +2998, 676, 3737, 582, 3922, 434, 3417, 379, +2157, 513, 380, 655, -1461, 571, -2987, 221, +-4004, -251, -4339, -749, -3786, -1226, -2365, -1530, +-440, -1411, 1526, -799, 3183, 79, 4266, 955, +4509, 1658, 3761, 2027, 2176, 1874, 171, 1180, +-1817, 161, -3407, -869, -4282, -1692, -4230, -2145, +-3267, -2064, -1690, -1435, 137, -479, 1866, 505, +3156, 1342, 3758, 1890, 3598, 1995, 2749, 1597, +1430, 851, -98, 11, -1522, -744, -2551, -1320, +-3055, -1591, -3010, -1476, -2438, -1053, -1431, -477, +-191, 120, 1040, 665, 2051, 1061, 2713, 1219, +2864, 1106, 2395, 787, 1364, 323, 33, -237, +-1249, -790, -2227, -1168, -2732, -1256, -2617, -1046, +-1858, -581, -666, 66, 640, 772, 1737, 1309, +2405, 1478, 2491, 1233, 1933, 671, 878, -97, +-345, -916, -1401, -1544, -2045, -1740, -2146, -1417, +-1692, -709, -815, 172, 236, 1026, 1173, 1651, +1760, 1830, 1877, 1484, 1511, 721, 743, -220, +-252, -1091, -1206, -1698, -1842, -1914, -1993, -1688, +-1619, -1067, -797, -210, 295, 693, 1374, 1453, +2114, 1928, 2308, 2035, 1965, 1751, 1163, 1105, +22, 206, -1211, -790, -2193, -1700, -2613, -2320, +-2393, -2488, -1659, -2152, -551, -1375, 770, -260, +1961, 998, 2617, 2115, 2544, 2770, 1889, 2793, +900, 2223, -270, 1194, -1425, -131, -2246, -1475, +-2442, -2448, -1983, -2763, -1113, -2402, -87, -1556, +946, -430, 1774, 764, 2161, 1734, 1984, 2184, +1331, 2047, 464, 1478, -397, 696, -1158, -133, +-1705, -849, -1890, -1291, -1666, -1398, -1124, -1232, +-419, -895, 335, -452, 1037, -2, 1595, 377, +1900, 692, 1848, 985, 1423, 1192, 724, 1192, +-97, 968, -928, 581, -1692, 40, -2226, -679, +-2288, -1412, -1829, -1843, -1021, -1770, -36, -1266, +1015, -462, 1950, 547, 2521, 1565, 2566, 2213, +2083, 2183, 1203, 1510, 77, 483, -1104, -616, +-2068, -1586, -2605, -2144, -2653, -2040, -2186, -1287, +-1262, -201, -66, 843, 1143, 1593, 2123, 1910, +2690, 1723, 2702, 1073, 2120, 159, 1052, -742, +-275, -1368, -1574, -1621, -2511, -1561, -2849, -1281, +-2499, -767, -1545, -32, -175, 750, 1327, 1384, +2515, 1833, 3009, 2115, 2725, 2044, 1756, 1372, +274, 141, -1374, -1272, -2704, -2516, -3284, -3365, +-3025, -3558, -2047, -2805, -506, -1113, 1263, 1070, +2711, 3080, 3420, 4386, 3325, 4696, 2554, 3880, +1203, 2021, -518, -466, -2129, -2878, -3177, -4543, +-3489, -5097, -3123, -4528, -2173, -2999, -735, -816, +928, 1509, 2377, 3388, 3265, 4437, 3495, 4565, +3087, 3820, 2058, 2366, 516, 495, -1212, -1416, +-2669, -3025, -3501, -4056, -3600, -4301, -2980, -3681, +-1705, -2338, 17, -542, 1774, 1399, 3100, 3098, +3684, 4125, 3436, 4204, 2439, 3343, 879, 1747, +-902, -237, -2473, -2162, -3433, -3568, -3555, -4128, +-2844, -3729, -1476, -2454, 213, -599, 1838, 1359, +3026, 2927, 3493, 3794, 3136, 3803, 2039, 2931, +432, 1341, -1241, -555, -2554, -2254, -3282, -3368, +-3307, -3717, -2573, -3253, -1197, -2047, 433, -381, +1859, 1301, 2837, 2593, 3294, 3280, 3080, 3278, +2094, 2606, 537, 1397, -1075, -61, -2332, -1434, +-3111, -2473, -3288, -3021, -2705, -2961, -1417, -2295, +225, -1178, 1750, 198, 2837, 1623, 3347, 2801, +3124, 3377, 2106, 3179, 507, 2282, -1199, 864, +-2534, -890, -3247, -2594, -3280, -3689, -2606, -3808, +-1280, -2995, 383, -1500, 1902, 401, 2922, 2293, +3313, 3601, 3038, 3902, 2136, 3202, 744, 1819, +-869, 114, -2296, -1556, -3161, -2788, -3325, -3249, +-2851, -2852, -1822, -1795, -350, -467, 1299, 776, +2680, 1724, 3393, 2279, 3328, 2312, 2631, 1761, +1396, 810, -272, -161, -1975, -903, -3159, -1438, +-3496, -1764, -3065, -1686, -2076, -1113, -599, -309, +1175, 400, 2650, 943, 3323, 1376, 3158, 1555, +2392, 1292, 1152, 687, -443, 63, -1961, -430, +-2866, -843, -2963, -1117, -2375, -1100, -1277, -802, +111, -436, 1412, -148, 2209, 81, 2360, 281, +1928, 414, 1034, 455, -57, 454, -1006, 460, +-1582, 477, -1674, 482, -1303, 424, -624, 251, +131, -10, 715, -309, 1017, -624, 1015, -937, +731, -1125, 286, -1040, -135, -675, -394, -166, +-472, 384, -415, 936, -252, 1357, -43, 1453, +97, 1150, 115, 565, 49, -127, -47, -779, +-182, -1285, -320, -1524, -345, -1418, -189, -995, +79, -360, 370, 348, 654, 964, 877, 1356, +912, 1485, 658, 1346, 166, 933, -439, 278, +-1026, -471, -1486, -1108, -1642, -1517, -1313, -1673, +-556, -1517, 354, -985, 1193, -176, 1859, 654, +2185, 1296, 1911, 1672, 1000, 1722, -185, 1373, +-1259, 667, -2020, -163, -2358, -861, -2136, -1287, +-1300, -1399, -104, -1207, 1042, -777, 1874, -233, +2273, 288, 2160, 651, 1515, 798, 422, 780, +-776, 662, -1660, 436, -2024, 120, -1924, -165, +-1477, -318, -685, -386, 370, -442, 1312, -400, +1771, -174, 1729, 108, 1363, 245, 746, 262, +-123, 274, -979, 243, -1462, 64, -1505, -175, +-1235, -287, -733, -243, -61, -152, 645, -44, +1164, 131, 1335, 319, 1175, 410, 774, 356, +231, 197, -361, 3, -877, -166, -1189, -305, +-1182, -435, -853, -514, -366, -430, 130, -165, +601, 137, 985, 367, 1107, 572, 887, 782, +473, 843, 79, 622, -291, 186, -669, -310, +-872, -752, -750, -1038, -454, -1071, -224, -833, +-55, -387, 167, 161, 379, 676, 425, 974, +333, 943, 290, 659, 396, 292, 462, -54, +300, -311, 36, -400, -170, -304, -374, -112, +-653, 37, -889, 56, -855, -67, -533, -263, +-124, -427, 317, -482, 796, -398, 1156, -147, +1196, 258, 921, 678, 471, 889, -120, 790, +-792, 471, -1272, 40, -1347, -436, -1102, -842, +-690, -1017, -130, -879, 560, -477, 1112, 57, +1287, 565, 1163, 896, 865, 965, 374, 791, +-240, 437, -757, -30, -1006, -503, -974, -837, +-778, -969, -494, -910, -141, -675, 230, -303, +486, 92, 559, 409, 534, 645, 518, 837, +501, 940, 375, 849, 110, 563, -181, 190, +-390, -203, -558, -642, -697, -1099, -704, -1405, +-468, -1356, -73, -931, 286, -296, 551, 401, +759, 1106, 827, 1686, 609, 1869, 155, 1480, +-297, 664, -597, -245, -746, -1052, -694, -1714, +-430, -2082, -64, -1881, 270, -1086, 471, -47, +510, 866, 407, 1550, 216, 2001, 39, 2060, +-100, 1566, -257, 666, -357, -288, -292, -1099, +-93, -1731, 55, -2065, 75, -1938, 105, -1372, +185, -561, 183, 341, 74, 1234, -20, 1930, +-33, 2195, -14, 1968, -48, 1344, -90, 446, +-76, -575, -30, -1477, -27, -2032, -109, -2132, +-201, -1770, -190, -1017, -94, -30, 0, 950, +99, 1692, 293, 2049, 566, 1964, 692, 1438, +533, 583, 203, -388, -146, -1245, -503, -1807, +-859, -1959, -1031, -1658, -858, -952, -456, -8, +-22, 898, 437, 1535, 892, 1833, 1119, 1778, +975, 1313, 638, 489, 256, -433, -187, -1135, +-627, -1507, -906, -1600, -954, -1419, -821, -922, +-545, -207, -119, 489, 382, 1000, 750, 1289, +918, 1377, 940, 1251, 790, 904, 385, 384, +-185, -209, -683, -774, -987, -1234, -1093, -1507, +-920, -1509, -425, -1180, 218, -574, 733, 178, +992, 931, 1056, 1535, 854, 1815, 306, 1678, +-337, 1159, -766, 357, -926, -572, -872, -1382, +-609, -1825, -157, -1836, 337, -1480, 652, -818, +772, 95, 766, 1028, 578, 1646, 175, 1783, +-261, 1526, -534, 998, -660, 247, -683, -607, +-534, -1318, -251, -1650, 1, -1569, 188, -1190, +362, -629, 517, 62, 537, 758, 393, 1254, +239, 1409, 165, 1274, 75, 991, -87, 574, +-243, -33, -335, -697, -406, -1142, -535, -1288, +-653, -1282, -611, -1176, -339, -813, 70, -153, +545, 565, 1018, 1079, 1276, 1359, 1169, 1458, +773, 1296, 198, 789, -482, 45, -1118, -678, +-1507, -1185, -1520, -1420, -1188, -1385, -597, -1062, +150, -470, 877, 229, 1376, 791, 1534, 1087, +1391, 1159, 1024, 1065, 446, 751, -253, 197, +-874, -390, -1289, -781, -1453, -962, -1395, -1034, +-1115, -940, -552, -556, 211, 30, 954, 571, +1479, 950, 1674, 1202, 1533, 1252, 1066, 922, +290, 267, -595, -416, -1294, -953, -1615, -1344, +-1590, -1501, -1306, -1228, -741, -524, 71, 322, +909, 1014, 1482, 1456, 1636, 1616, 1443, 1399, +1019, 797, 336, -5, -516, -757, -1237, -1293, +-1581, -1512, -1563, -1380, -1276, -957, -702, -366, +110, 273, 910, 853, 1441, 1237, 1620, 1332, +1476, 1176, 1041, 864, 337, 429, -471, -113, +-1125, -662, -1447, -1064, -1457, -1244, -1257, -1217, +-864, -992, -275, -559, 410, 32, 1015, 639, +1393, 1112, 1505, 1330, 1367, 1241, 947, 886, +273, 381, -510, -166, -1172, -668, -1535, -1007, +-1565, -1067, -1255, -849, -620, -475, 147, -83, +790, 251, 1193, 499, 1298, 625, 1070, 616, +583, 478, 53, 247, -358, 6, -633, -161, +-740, -273, -617, -400, -330, -493, -88, -429, +-30, -221, -29, -32, 80, 94, 184, 269, +191, 484, 211, 534, 320, 342, 404, 87, +299, -82, 44, -234, -142, -439, -206, -558, +-289, -459, -418, -218, -446, 0, -259, 181, +14, 363, 153, 496, 129, 481, 134, 319, +263, 93, 328, -154, 211, -406, 96, -611, +107, -675, 111, -560, -26, -292, -232, 57, +-308, 410, -252, 689, -259, 837, -341, 796, +-261, 550, 37, 164, 295, -252, 346, -614, +306, -864, 323, -931, 359, -803, 253, -552, +-49, -259, -339, 94, -428, 511, -369, 859, +-329, 981, -314, 904, -128, 742, 241, 478, +465, 29, 394, -527, 275, -947, 236, -1091, +119, -1007, -154, -764, -348, -352, -301, 185, +-152, 663, -82, 910, -82, 904, -25, 727, +110, 444, 174, 88, 94, -268, -7, -490, +-2, -524, 121, -445, 191, -367, 76, -279, +-84, -117, -126, 87, -116, 230, -167, 318, +-217, 427, -131, 504, 44, 413, 148, 150, +182, -125, 210, -330, 195, -495, 85, -588, +-44, -462, -80, -81, -30, 347, 18, 587, +11, 598, -64, 457, -177, 175, -270, -231, +-327, -623, -312, -766, -182, -557, 79, -119, +408, 356, 671, 765, 739, 1015, 583, 942, +269, 464, -135, -239, -554, -843, -837, -1168, +-830, -1225, -575, -990, -215, -387, 148, 452, +473, 1145, 650, 1391, 569, 1213, 308, 793, +42, 212, -126, -480, -189, -1061, -169, -1216, +-68, -901, 71, -387, 78, 77, -94, 463, +-286, 738, -350, 724, -302, 344, -228, -157, +-61, -443, 305, -454, 704, -323, 841, -93, +655, 257, 313, 591, -55, 679, -507, 446, +-1001, 25, -1253, -424, -1077, -786, -595, -926, +-38, -736, 543, -297, 1155, 173, 1557, 538, +1481, 762, 1036, 788, 453, 552, -208, 129, +-983, -259, -1691, -438, -1949, -416, -1587, -287, +-862, -102, -76, 92, 721, 196, 1472, 125, +1910, -86, 1783, -318, 1180, -459, 379, -475, +-417, -359, -1133, -97, -1598, 283, -1590, 658, +-1135, 866, -489, 814, 150, 558, 714, 238, +1108, -100, 1202, -489, 961, -855, 534, -1003, +84, -850, -322, -525, -640, -200, -774, 108, +-716, 439, -576, 713, -377, 785, -88, 621, +201, 348, 398, 93, 523, -107, 585, -251, +600, -291, 529, -193, 310, -25, -24, 58, +-393, -21, -701, -202, -860, -387, -853, -538, +-667, -628, -254, -533, 336, -141, 895, 483, +1166, 1089, 1098, 1446, 778, 1451, 254, 1088, +-447, 360, -1133, -624, -1438, -1584, -1197, -2187, +-646, -2216, -41, -1634, 611, -518, 1211, 861, +1466, 2087, 1166, 2777, 490, 2752, -154, 2006, +-591, 670, -922, -943, -1112, -2343, -952, -3085, +-470, -2990, 2, -2100, 227, -620, 312, 1042, +423, 2367, 534, 3001, 509, 2847, 417, 1981, +435, 595, 498, -930, 356, -2124, -39, -2651, +-477, -2441, -808, -1633, -1051, -468, -1187, 742, +-1024, 1701, -489, 2204, 247, 2138, 941, 1502, +1450, 498, 1652, -544, 1445, -1381, 868, -1899, +69, -1980, -770, -1515, -1427, -610, -1724, 413, +-1621, 1264, -1140, 1825, -393, 1971, 432, 1563, +1107, 652, 1452, -435, 1448, -1328, 1167, -1833, +666, -1874, 43, -1421, -525, -532, -869, 515, +-950, 1364, -901, 1776, -788, 1691, -584, 1141, +-308, 264, -27, -674, 234, -1355, 527, -1604, +850, -1438, 1065, -937, 1054, -197, 849, 604, +503, 1211, 7, 1459, -644, 1329, -1255, 908, +-1553, 306, -1468, -356, -1080, -969, -465, -1405, +277, -1509, 961, -1208, 1395, -601, 1517, 93, +1360, 732, 933, 1261, 332, 1543, -261, 1373, +-747, 785, -1126, 59, -1336, -569, -1272, -1046, +-966, -1333, -530, -1269, 0, -796, 613, -120, +1172, 461, 1448, 841, 1332, 1021, 957, 952, +414, 588, -291, 46, -1004, -475, -1431, -844, +-1442, -1001, -1104, -887, -485, -509, 322, -11, +1058, 472, 1409, 896, 1316, 1197, 936, 1200, +386, 839, -318, 276, -981, -306, -1288, -866, +-1195, -1336, -894, -1510, -463, -1273, 114, -761, +703, -174, 1048, 445, 1068, 1046, 942, 1420, +706, 1409, 229, 1133, -368, 777, -752, 344, +-854, -217, -865, -756, -813, -1057, -539, -1133, +-60, -1118, 380, -1004, 641, -676, 774, -160, +807, 370, 623, 789, 222, 1105, -163, 1317, +-372, 1319, -466, 1027, -505, 503, -462, -113, +-316, -715, -125, -1233, 2, -1574, 67, -1618, +116, -1299, 160, -661, 193, 144, 242, 935, +315, 1580, 384, 1969, 423, 1974, 381, 1509, +210, 664, -83, -334, -445, -1259, -796, -1974, +-1000, -2317, -986, -2140, -750, -1460, -298, -475, +307, 584, 911, 1543, 1322, 2217, 1409, 2412, +1177, 2069, 705, 1346, 41, 424, -731, -573, +-1375, -1491, -1601, -2113, -1362, -2296, -834, -2032, +-175, -1423, 525, -582, 1117, 372, 1374, 1283, +1206, 1984, 775, 2295, 258, 2141, -300, 1590, +-776, 773, -1011, -214, -948, -1224, -662, -2023, +-268, -2378, 130, -2222, 435, -1649, 581, -766, +580, 306, 480, 1345, 295, 2065, 75, 2292, +-97, 2001, -155, 1306, -179, 385, -241, -541, +-270, -1298, -208, -1757, -138, -1807, -144, -1432, +-169, -814, -106, -211, 38, 277, 150, 681, +215, 971, 290, 1040, 378, 916, 388, 765, +290, 658, 165, 494, 46, 191, -148, -217, +-428, -649, -637, -1043, -665, -1348, -587, -1458, +-494, -1279, -294, -794, 122, -77, 646, 734, +1020, 1440, 1133, 1866, 1051, 1928, 783, 1622, +265, 980, -425, 81, -1050, -885, -1411, -1674, +-1461, -2106, -1233, -2129, -713, -1758, 22, -1030, +749, -31, 1262, 1007, 1495, 1810, 1447, 2207, +1116, 2158, 542, 1685, -160, 856, -819, -155, +-1269, -1102, -1442, -1772, -1383, -2059, -1106, -1914, +-581, -1393, 137, -646, 871, 151, 1385, 858, +1583, 1367, 1526, 1607, 1203, 1585, 549, 1361, +-307, 986, -1077, 472, -1539, -123, -1669, -728, +-1519, -1305, -1074, -1782, -357, -2018, 426, -1880, +1009, -1348, 1291, -510, 1353, 526, 1247, 1623, +909, 2498, 377, 2875, -142, 2650, -454, 1891, +-640, 725, -856, -650, -996, -1955, -895, -2885, +-672, -3215, -510, -2883, -326, -1980, 44, -721, +514, 634, 833, 1833, 990, 2675, 1120, 3012, +1138, 2778, 828, 2024, 258, 972, -313, -137, +-809, -1171, -1250, -2036, -1511, -2591, -1401, -2667, +-939, -2239, -322, -1474, 328, -542, 986, 517, +1483, 1591, 1611, 2418, 1363, 2756, 868, 2561, +193, 1934, -580, 960, -1226, -274, -1529, -1532, +-1472, -2467, -1175, -2868, -685, -2692, -12, -1999, +724, -888, 1237, 422, 1385, 1625, 1265, 2460, +968, 2782, 500, 2524, -74, 1743, -588, 645, +-882, -495, -954, -1475, -944, -2199, -872, -2528, +-655, -2333, -296, -1672, 67, -782, 340, 171, +604, 1107, 920, 1899, 1149, 2336, 1132, 2300, +884, 1853, 482, 1094, -77, 128, -771, -876, +-1369, -1700, -1624, -2177, -1516, -2215, -1126, -1817, +-456, -1083, 431, -201, 1257, 644, 1719, 1330, +1737, 1704, 1398, 1635, 763, 1204, -68, 660, +-884, 155, -1458, -299, -1671, -674, -1501, -826, +-1003, -694, -294, -444, 464, -276, 1101, -208, +1484, -153, 1520, -101, 1209, -102, 671, -134, +21, -80, -675, 94, -1260, 328, -1540, 530, +-1453, 644, -1052, 634, -436, 478, 253, 191, +864, -163, 1299, -516, 1505, -784, 1396, -827, +893, -619, 151, -301, -531, -4, -976, 291, +-1244, 600, -1350, 770, -1126, 626, -544, 286, +133, 35, 659, -95, 995, -246, 1142, -404, +1031, -395, 612, -211, 49, -56, -406, -47, +-661, -84, -762, -94, -722, -110, -506, -143, +-158, -123, 140, 38, 248, 313, 236, 571, +232, 717, 265, 754, 274, 685, 289, 474, +396, 58, 519, -497, 445, -979, 117, -1257, +-325, -1359, -769, -1295, -1177, -967, -1426, -357, +-1287, 378, -695, 1075, 152, 1680, 1006, 2076, +1738, 2095, 2191, 1689, 2122, 960, 1443, 19, +390, -1053, -757, -2078, -1844, -2761, -2647, -2909, +-2833, -2519, -2254, -1617, -1115, -278, 249, 1239, +1577, 2561, 2656, 3412, 3208, 3653, 2956, 3187, +1927, 1986, 445, 265, -1117, -1535, -2444, -3025, +-3255, -3940, -3323, -4103, -2546, -3426, -1128, -2017, +477, -171, 1880, 1721, 2875, 3279, 3272, 4182, +2887, 4253, 1786, 3493, 341, 2026, -1042, 148, +-2126, -1734, -2773, -3248, -2851, -4146, -2264, -4267, +-1183, -3537, 47, -2033, 1174, -127, 2061, 1684, +2536, 3078, 2432, 3896, 1740, 3966, 690, 3171, +-396, 1686, -1350, -55, -2052, -1617, -2263, -2745, +-1811, -3251, -889, -3040, 108, -2195, 936, -991, +1527, 230, 1749, 1211, 1441, 1813, 693, 1931, +-164, 1577, -852, 979, -1286, 380, -1361, -84, +-970, -375, -246, -466, 467, -369, 962, -208, +1229, -155, 1242, -238, 911, -383, 261, -559, +-487, -744, -1115, -849, -1511, -733, -1626, -375, +-1372, 116, -746, 617, 110, 1071, 984, 1417, +1699, 1581, 2145, 1484, 2191, 1084, 1693, 427, +684, -381, -539, -1174, -1635, -1837, -2415, -2302, +-2796, -2436, -2592, -2076, -1671, -1246, -262, -105, +1171, 1159, 2296, 2336, 2975, 3183, 3054, 3460, +2382, 3034, 1091, 1959, -384, 427, -1674, -1308, +-2595, -2899, -3004, -3982, -2729, -4253, -1777, -3621, +-448, -2235, 854, -375, 1841, 1609, 2363, 3314, +2409, 4357, 2027, 4468, 1247, 3636, 196, 2135, +-813, 272, -1439, -1652, -1658, -3238, -1686, -4075, +-1572, -4025, -1149, -3267, -450, -2038, 214, -461, +681, 1237, 1076, 2619, 1462, 3349, 1611, 3405, +1373, 2973, 921, 2149, 428, 943, -196, -469, +-980, -1710, -1637, -2495, -1857, -2804, -1640, -2745, +-1173, -2324, -540, -1471, 269, -331, 1130, 774, +1737, 1634, 1889, 2251, 1644, 2621, 1142, 2603, +415, 2056, -475, 1124, -1286, 79, -1740, -999, +-1761, -2047, -1471, -2802, -936, -2983, -149, -2536, +723, -1590, 1348, -320, 1592, 1070, 1530, 2286, +1195, 3027, 576, 3109, -192, 2501, -844, 1362, +-1209, -28, -1314, -1362, -1198, -2366, -814, -2832, +-237, -2672, 302, -1932, 648, -854, 854, 285, +967, 1300, 911, 2024, 648, 2282, 288, 2037, +-48, 1430, -337, 631, -590, -250, -778, -1087, +-846, -1663, -797, -1859, -624, -1698, -307, -1219, +105, -476, 486, 365, 780, 1098, 988, 1567, +1063, 1711, 923, 1509, 570, 949, 108, 144, +-395, -688, -874, -1334, -1218, -1688, -1319, -1719, +-1176, -1403, -829, -731, -302, 125, 375, 918, +1054, 1524, 1499, 1865, 1605, 1836, 1415, 1407, +981, 704, 313, -94, -489, -858, -1232, -1531, +-1721, -1981, -1852, -2043, -1623, -1700, -1071, -1111, +-251, -394, 650, 462, 1378, 1379, 1800, 2092, +1920, 2405, 1747, 2303, 1226, 1797, 372, 929, +-626, -208, -1430, -1404, -1846, -2351, -1959, -2802, +-1832, -2696, -1338, -2081, -472, -1053, 484, 223, +1218, 1452, 1650, 2288, 1868, 2600, 1815, 2461, +1345, 1932, 582, 1057, -138, 17, -693, -919, +-1192, -1588, -1578, -2014, -1635, -2200, -1363, -2036, +-978, -1506, -546, -753, 16, 86, 681, 982, +1226, 1833, 1517, 2377, 1631, 2421, 1570, 2035, +1178, 1324, 490, 326, -234, -784, -874, -1712, +-1460, -2239, -1880, -2340, -1927, -2067, -1606, -1465, +-1085, -618, -425, 264, 407, 1013, 1262, 1581, +1858, 1944, 2118, 2028, 2163, 1774, 1936, 1255, +1218, 573, 115, -227, -971, -1039, -1825, -1658, +-2463, -1986, -2767, -1980, -2495, -1596, -1626, -895, +-454, -80, 713, 645, 1750, 1182, 2528, 1514, +2773, 1579, 2382, 1332, 1589, 912, 646, 485, +-319, 95, -1198, -297, -1855, -650, -2193, -892, +-2130, -1027, -1670, -1102, -977, -1050, -262, -800, +408, -434, 1074, -60, 1655, 299, 1929, 677, +1758, 1009, 1301, 1179, 764, 1190, 149, 1107, +-541, 917, -1125, 594, -1451, 127, -1527, -482, +-1432, -1144, -1194, -1716, -783, -2058, -253, -2070, +291, -1695, 805, -919, 1295, 185, 1681, 1356, +1833, 2294, 1682, 2833, 1227, 2889, 463, 2365, +-510, 1256, -1433, -149, -2074, -1429, -2347, -2370, +-2250, -2949, -1725, -3039, -748, -2510, 460, -1458, +1486, -203, 2113, 958, 2371, 1913, 2267, 2584, +1722, 2787, 789, 2449, -256, 1729, -1139, 797, +-1752, -251, -2083, -1310, -2046, -2146, -1586, -2557, +-824, -2514, -4, -2090, 713, -1324, 1300, -284, +1712, 869, 1811, 1894, 1504, 2542, 890, 2688, +176, 2295, -484, 1442, -1052, 297, -1457, -930, +-1583, -1984, -1370, -2572, -886, -2568, -243, -2013, +459, -1040, 1077, 131, 1428, 1223, 1418, 1944, +1101, 2133, 556, 1853, -112, 1248, -722, 413, +-1083, -454, -1125, -1079, -903, -1330, -483, -1278, +57, -1022, 516, -606, 685, -138, 588, 216, +374, 404, 114, 519, -169, 604, -345, 607, +-261, 476, 22, 312, 271, 233, 372, 158, +350, -39, 206, -307, -103, -503, -516, -574, +-815, -589, -834, -614, -578, -532, -162, -222, +319, 212, 779, 555, 1120, 769, 1207, 944, +940, 1020, 382, 790, -259, 260, -810, -291, +-1214, -687, -1385, -964, -1207, -1147, -704, -1086, +-98, -696, 454, -171, 932, 235, 1267, 520, +1292, 751, 965, 865, 482, 797, 38, 619, +-346, 482, -661, 411, -803, 297, -786, 71, +-722, -232, -619, -591, -416, -990, -174, -1377, +-4, -1614, 133, -1533, 372, -1064, 682, -247, +894, 787, 968, 1836, 963, 2649, 818, 2982, +402, 2681, -180, 1766, -692, 361, -1076, -1269, +-1398, -2723, -1556, -3654, -1375, -3870, -861, -3293, +-181, -1995, 498, -245, 1120, 1566, 1618, 3004, +1850, 3812, 1691, 3894, 1173, 3239, 448, 1965, +-309, 387, -967, -1118, -1445, -2299, -1650, -3031, +-1493, -3223, -1041, -2837, -519, -2036, -37, -1062, +426, -56, 790, 931, 881, 1784, 754, 2294, +632, 2357, 606, 2129, 565, 1756, 431, 1180, +283, 367, 168, -497, -22, -1132, -367, -1508, +-724, -1780, -973, -1967, -1135, -1891, -1190, -1531, +-1033, -1040, -640, -495, -96, 198, 500, 1078, +1071, 1933, 1556, 2515, 1849, 2724, 1823, 2542, +1432, 1896, 766, 778, -83, -636, -1011, -1991, +-1829, -2976, -2344, -3414, -2439, -3209, -2052, -2394, +-1261, -1135, -241, 332, 851, 1686, 1797, 2617, +2365, 3010, 2465, 2875, 2153, 2270, 1525, 1314, +694, 243, -230, -702, -1091, -1405, -1714, -1873, +-2043, -2091, -2140, -2013, -1995, -1687, -1519, -1231, +-784, -712, 38, -92, 867, 619, 1683, 1300, +2333, 1849, 2600, 2211, 2373, 2272, 1729, 1948, +812, 1266, -331, 317, -1555, -740, -2495, -1730, +-2876, -2426, -2741, -2649, -2191, -2384, -1233, -1731, +49, -776, 1344, 299, 2260, 1233, 2613, 1828, +2498, 2051, 2046, 1964, 1263, 1608, 229, 1060, +-768, 449, -1424, -111, -1688, -582, -1696, -943, +-1549, -1208, -1194, -1381, -641, -1445, -131, -1323, +144, -957, 338, -423, 660, 146, 993, 724, +1131, 1287, 1103, 1625, 1089, 1567, 1063, 1179, +794, 681, 238, 181, -349, -343, -814, -814, +-1233, -1022, -1598, -928, -1724, -740, -1512, -601, +-1086, -458, -526, -241, 177, -38, 928, 93, +1511, 222, 1824, 402, 1912, 570, 1791, 671, +1338, 693, 560, 655, -269, 521, -947, 248, +-1503, -52, -1944, -288, -2085, -510, -1807, -754, +-1238, -904, -613, -868, 13, -700, 713, -510, +1424, -256, 1911, 155, 2043, 621, 1918, 955, +1629, 1102, 1108, 1132, 281, 1030, -688, 716, +-1525, 194, -2101, -373, -2448, -861, -2515, -1204, +-2106, -1346, -1182, -1257, -21, -947, 1088, -465, +2051, 108, 2773, 651, 3020, 1034, 2596, 1182, +1620, 1130, 414, 883, -799, 449, -1900, -43, +-2649, -429, -2798, -661, -2335, -747, -1494, -665, +-505, -420, 519, -112, 1408, 109, 1917, 196, +1934, 165, 1591, 49, 1115, -104, 619, -230, +65, -249, -514, -105, -951, 130, -1121, 343, +-1087, 493, -1020, 550, -917, 502, -627, 319, +-128, 10, 372, -297, 701, -432, 879, -428, +1001, -418, 1008, -410, 773, -308, 352, -131, +-51, -23, -329, -20, -556, -16, -783, 68, +-890, 206, -758, 351, -504, 479, -305, 592, +-125, 654, 169, 594, 517, 367, 724, -9, +743, -452, 693, -884, 593, -1234, 350, -1367, +27, -1174, -213, -713, -354, -85, -492, 631, +-602, 1305, -575, 1748, -450, 1807, -360, 1483, +-278, 909, -92, 176, 151, -662, 343, -1405, +498, -1817, 671, -1842, 763, -1589, 648, -1106, +391, -386, 121, 444, -173, 1154, -511, 1624, +-795, 1805, -911, 1658, -846, 1222, -652, 574, +-310, -178, 156, -885, 566, -1390, 811, -1598, +968, -1464, 1012, -1019, 796, -387, 325, 254, +-190, 752, -589, 1044, -880, 1092, -1033, 859, +-939, 389, -622, -126, -253, -457, 110, -542, +509, -492, 822, -345, 831, -49, 608, 326, +449, 558, 366, 519, 132, 309, -249, 65, +-516, -209, -566, -525, -548, -760, -576, -796, +-508, -610, -213, -290, 152, 60, 377, 424, +474, 785, 525, 1005, 516, 960, 387, 696, +111, 324, -193, -82, -357, -479, -346, -782, +-288, -923, -234, -868, -126, -620, 32, -266, +118, 54, 84, 276, 28, 413, 52, 467, +121, 443, 90, 333, -2, 193, 7, 119, +98, 125, 134, 129, 81, 112, -7, 90, +-53, 12, -59, -169, -132, -395, -277, -554, +-342, -642, -266, -649, -156, -484, -57, -132, +124, 255, 401, 567, 597, 794, 584, 890, +429, 732, 254, 330, 31, -97, -318, -388, +-639, -568, -717, -663, -590, -584, -421, -301, +-218, 68, 27, 322, 272, 397, 466, 363, +557, 244, 537, 35, 444, -187, 287, -337, +83, -397, -115, -356, -298, -205, -455, 29, +-537, 262, -495, 439, -328, 521, -65, 497, +217, 401, 405, 257, 450, 32, 391, -264, +235, -536, -10, -710, -247, -748, -395, -655, +-408, -446, -288, -125, -97, 281, 115, 667, +322, 921, 453, 981, 471, 854, 395, 574, +229, 181, 20, -232, -161, -576, -314, -798, +-476, -891, -596, -864, -602, -751, -518, -552, +-397, -266, -196, 61, 122, 372, 485, 666, +792, 969, 981, 1219, 1049, 1301, 974, 1155, +700, 800, 250, 267, -276, -382, -829, -1067, +-1335, -1663, -1660, -2021, -1687, -2051, -1371, -1733, +-770, -1062, -15, -116, 787, 885, 1554, 1741, +2113, 2360, 2256, 2673, 1915, 2541, 1229, 1931, +355, 1001, -607, -67, -1501, -1164, -2107, -2165, +-2305, -2882, -2123, -3145, -1613, -2899, -818, -2210, +119, -1143, 949, 209, 1562, 1623, 1999, 2797, +2196, 3507, 1994, 3638, 1406, 3140, 637, 2055, +-152, 594, -935, -943, -1646, -2308, -2075, -3264, +-2100, -3598, -1784, -3266, -1238, -2417, -509, -1244, +319, 69, 1068, 1313, 1589, 2260, 1874, 2758, +1909, 2777, 1620, 2381, 1043, 1680, 327, 769, +-394, -229, -1055, -1121, -1580, -1739, -1826, -2051, +-1688, -2055, -1250, -1744, -638, -1164, 71, -421, +769, 326, 1291, 913, 1488, 1258, 1339, 1372, +913, 1240, 330, 861, -242, 356, -644, -74, +-827, -352, -813, -505, -608, -514, -222, -365, +216, -137, 487, 44, 530, 105, 450, 55, +287, -50, -17, -191, -400, -362, -674, -506, +-720, -522, -621, -373, -478, -122, -227, 157, +197, 441, 649, 703, 939, 871, 1046, 886, +1041, 718, 918, 424, 602, 106, 99, -202, +-482, -533, -1011, -839, -1401, -1022, -1574, -1041, +-1503, -946, -1202, -757, -679, -425, 39, 54, +825, 608, 1463, 1099, 1859, 1414, 2027, 1515, +1905, 1376, 1391, 938, 555, 263, -368, -451, +-1176, -1048, -1823, -1456, -2274, -1594, -2355, -1407, +-1968, -957, -1229, -373, -334, 210, 589, 668, +1447, 917, 2104, 976, 2405, 892, 2285, 694, +1800, 451, 1066, 266, 183, 159, -741, 83, +-1529, 3, -2047, -109, -2268, -276, -2174, -529, +-1720, -828, -976, -1057, -94, -1100, 769, -941, +1495, -608, 1994, -100, 2156, 559, 1933, 1188, +1429, 1577, 789, 1696, 58, 1559, -683, 1126, +-1282, 437, -1626, -318, -1705, -955, -1563, -1403, +-1265, -1637, -861, -1609, -360, -1322, 205, -860, +750, -343, 1187, 135, 1473, 555, 1610, 918, +1599, 1182, 1346, 1324, 777, 1370, 47, 1286, +-618, 1012, -1187, 559, -1664, -4, -1933, -623, +-1852, -1220, -1386, -1673, -690, -1867, 46, -1738, +747, -1313, 1365, -697, 1768, -35, 1856, 599, +1625, 1154, 1133, 1523, 479, 1647, -218, 1584, +-863, 1395, -1364, 1069, -1610, 596, -1597, 14, +-1382, -602, -946, -1187, -295, -1678, 413, -2002, +1013, -2041, 1418, -1718, 1591, -1096, 1526, -314, +1184, 541, 573, 1383, -157, 2018, -844, 2283, +-1393, 2175, -1690, 1754, -1615, 1082, -1182, 237, +-551, -637, 111, -1364, 717, -1836, 1239, -2038, +1562, -1972, 1526, -1619, 1158, -1000, 663, -243, +167, 498, -357, 1134, -856, 1586, -1225, 1756, +-1414, 1631, -1424, 1266, -1228, 719, -793, 90, +-180, -469, 462, -839, 1012, -1017, 1465, -1045, +1757, -938, 1723, -719, 1307, -450, 645, -213, +-95, -59, -811, 58, -1409, 217, -1749, 386, +-1729, 494, -1405, 571, -926, 676, -359, 758, +286, 712, 898, 522, 1283, 262, 1378, -36, +1283, -382, 1066, -756, 744, -1064, 330, -1216, +-123, -1180, -517, -967, -777, -565, -889, -8, +-887, 564, -812, 1059, -717, 1459, -597, 1683, +-417, 1596, -181, 1188, 65, 593, 301, -78, +554, -797, 842, -1467, 1124, -1900, 1269, -1970, +1210, -1697, 983, -1176, 601, -467, 29, 370, +-664, 1176, -1288, 1740, -1708, 1968, -1901, 1899, +-1855, 1578, -1516, 1016, -848, 278, 30, -485, +880, -1139, 1556, -1604, 2041, -1829, 2281, -1786, +2140, -1486, 1607, -959, 843, -283, 29, 425, +-788, 1066, -1558, 1545, -2095, 1756, -2239, 1668, +-2037, 1346, -1648, 864, -1067, 264, -262, -379, +611, -936, 1299, -1309, 1726, -1488, 1951, -1494, +1978, -1325, 1720, -957, 1166, -418, 496, 167, +-118, 702, -659, 1185, -1152, 1561, -1534, 1687, +-1716, 1492, -1693, 1034, -1519, 419, -1230, -277, +-802, -963, -196, -1487, 528, -1709, 1241, -1595, +1851, -1215, 2280, -663, 2407, -13, 2128, 625, +1455, 1097, 497, 1310, -588, 1290, -1649, 1092, +-2491, 742, -2889, 281, -2746, -196, -2166, -596, +-1287, -873, -180, -980, 992, -887, 1978, -644, +2571, -337, 2733, -18, 2495, 257, 1864, 434, +900, 486, -177, 410, -1121, 270, -1856, 164, +-2340, 118, -2438, 94, -2063, 83, -1327, 94, +-452, 79, 394, -15, 1125, -168, 1670, -308, +1910, -373, 1772, -356, 1340, -300, 779, -215, +197, -60, -360, 144, -843, 284, -1181, 305, +-1295, 256, -1203, 206, -995, 171, -666, 133, +-211, 64, 273, -28, 680, -103, 965, -132, +1092, -142, 1046, -172, 833, -181, 457, -129, +-20, -52, -490, 7, -836, 73, -1008, 133, +-1009, 129, -859, 41, -544, -54, -85, -86, +388, -59, 771, -11, 1049, 53, 1157, 162, +1008, 293, 637, 346, 156, 271, -349, 112, +-793, -114, -1123, -387, -1278, -605, -1149, -676, +-740, -593, -236, -365, 197, -6, 569, 397, +918, 727, 1153, 927, 1110, 958, 826, 750, +535, 321, 305, -199, -24, -644, -459, -897, +-757, -953, -844, -864, -909, -615, -1008, -203, +-955, 240, -616, 544, -155, 674, 219, 689, +548, 615, 969, 461, 1322, 275, 1348, 101, +1089, -78, 728, -281, 289, -461, -278, -560, +-866, -564, -1269, -492, -1413, -357, -1353, -147, +-1110, 120, -633, 355, -8, 491, 561, 535, +968, 498, 1222, 366, 1305, 193, 1174, 67, +870, -27, 427, -154, -87, -300, -534, -420, +-849, -491, -1060, -488, -1155, -424, -1051, -328, +-749, -156, -332, 119, 87, 397, 440, 580, +748, 679, 974, 702, 1025, 609, 854, 395, +561, 121, 252, -159, -51, -432, -367, -701, +-654, -919, -791, -961, -746, -776, -610, -475, +-445, -130, -204, 287, 113, 718, 385, 1006, +529, 1070, 529, 932, 436, 627, 312, 213, +146, -189, -73, -467, -251, -607, -282, -661, +-211, -650, -135, -573, -79, -458, 15, -353, +161, -273, 244, -150, 204, 88, 110, 416, +34, 749, -86, 1003, -268, 1104, -380, 965, +-388, 565, -355, 8, -268, -572, -58, -1076, +209, -1376, 424, -1367, 560, -1039, 629, -461, +608, 218, 409, 813, 69, 1201, -230, 1329, +-395, 1152, -526, 696, -671, 103, -678, -479, +-486, -946, -207, -1175, 27, -1081, 232, -716, +427, -214, 563, 288, 586, 665, 485, 851, +296, 835, 23, 613, -259, 260, -420, -65, +-432, -250, -327, -306, -132, -271, 111, -189, +293, -128, 377, -138, 351, -222, 179, -325, +-94, -379, -369, -353, -543, -242, -580, -39, +-475, 234, -277, 485, -55, 623, 151, 653, +319, 624, 484, 551, 628, 413, 658, 214, +551, -7, 422, -250, 317, -541, 141, -843, +-124, -1050, -433, -1105, -718, -989, -900, -691, +-941, -228, -873, 337, -715, 891, -424, 1276, +-32, 1402, 384, 1315, 758, 1094, 1074, 746, +1317, 259, 1357, -276, 1111, -722, 665, -1022, +178, -1228, -350, -1368, -946, -1355, -1472, -1108, +-1726, -678, -1616, -156, -1237, 435, -682, 1022, +14, 1450, 765, 1620, 1350, 1541, 1625, 1249, +1644, 768, 1419, 152, 918, -478, 225, -977, +-457, -1284, -951, -1395, -1203, -1291, -1260, -997, +-1169, -604, -865, -168, -379, 277, 107, 635, +430, 790, 564, 732, 582, 552, 541, 359, +473, 227, 380, 178, 302, 226, 288, 374, +287, 536, 229, 570, 83, 413, -113, 56, +-340, -470, -571, -1039, -766, -1472, -843, -1639, +-744, -1493, -520, -1062, -232, -448, 76, 225, +377, 863, 630, 1381, 790, 1688, 842, 1748, +806, 1587, 704, 1263, 483, 812, 171, 248, +-121, -401, -378, -1038, -664, -1552, -925, -1885, +-995, -1979, -860, -1776, -626, -1279, -356, -600, +-56, 127, 272, 821, 554, 1414, 704, 1791, +728, 1880, 705, 1712, 658, 1347, 560, 826, +413, 221, 229, -374, 34, -907, -194, -1332, +-497, -1577, -853, -1574, -1112, -1327, -1152, -910, +-1009, -418, -727, 92, -276, 568, 318, 894, +881, 990, 1243, 924, 1366, 786, 1267, 568, +966, 315, 525, 136, 69, 61, -343, 47, +-689, 38, -882, -26, -900, -155, -844, -301, +-781, -463, -668, -666, -504, -848, -325, -896, +-100, -763, 229, -484, 639, -115, 1009, 306, +1229, 737, 1285, 1091, 1191, 1239, 861, 1143, +260, 883, -409, 499, -915, -8, -1242, -517, +-1433, -844, -1382, -948, -1049, -905, -564, -747, +-63, -453, 386, -78, 736, 248, 911, 442, +904, 516, 808, 486, 711, 343, 582, 113, +382, -127, 168, -292, -32, -371, -259, -375, +-522, -263, -764, -2, -939, 297, -1008, 490, +-905, 559, -625, 539, -220, 425, 232, 207, +647, -63, 945, -321, 1070, -502, 1022, -584, +853, -606, 588, -569, 237, -426, -106, -215, +-345, -5, -532, 221, -748, 477, -951, 676, +-1048, 713, -990, 569, -772, 295, -452, -8, +-45, -267, 485, -469, 1020, -555, 1347, -431, +1453, -146, 1433, 145, 1179, 361, 572, 464, +-222, 381, -913, 111, -1366, -202, -1617, -418, +-1675, -499, -1442, -476, -876, -366, -144, -164, +559, 81, 1142, 253, 1517, 291, 1600, 251, +1394, 211, 974, 204, 392, 252, -258, 358, +-845, 438, -1241, 403, -1364, 254, -1234, 36, +-911, -246, -458, -581, 32, -855, 479, -956, +862, -877, 1100, -667, 1066, -334, 841, 72, +590, 449, 311, 718, -64, 867, -445, 932, +-695, 923, -821, 786, -909, 497, -964, 144, +-850, -192, -527, -483, -163, -703, 166, -820, +576, -836, 1057, -727, 1377, -484, 1437, -205, +1260, -10, 848, 92, 242, 136, -424, 132, +-1005, 114, -1427, 122, -1609, 183, -1501, 320, +-1118, 534, -584, 760, -49, 935, 430, 999, +832, 882, 1096, 553, 1170, 49, 1103, -562, +971, -1188, 771, -1696, 480, -1968, 92, -1944, +-302, -1599, -621, -944, -859, -84, -1039, 804, +-1134, 1554, -1094, 2049, -895, 2237, -550, 2103, +-171, 1661, 194, 991, 600, 250, 1014, -439, +1306, -1002, 1398, -1388, 1327, -1560, 1071, -1539, +610, -1391, 1, -1169, -650, -884, -1203, -550, +-1565, -207, -1695, 134, -1572, 493, -1132, 869, +-437, 1228, 287, 1507, 871, 1635, 1274, 1570, +1480, 1313, 1412, 888, 1085, 318, 634, -339, +170, -980, -277, -1498, -686, -1810, -903, -1895, +-875, -1767, -727, -1443, -612, -955, -484, -383, +-250, 215, 22, 801, 218, 1305, 319, 1681, +408, 1914, 485, 1964, 500, 1776, 453, 1350, +349, 712, 193, -84, -19, -925, -207, -1661, +-307, -2174, -307, -2360, -237, -2161, -165, -1615, +-106, -830, -57, 52, -13, 873, -24, 1501, +-92, 1843, -162, 1824, -180, 1489, -87, 1005, +89, 490, 262, -42, 344, -519, 336, -820, +274, -899, 177, -822, 84, -683, -46, -511, +-192, -301, -265, -71, -207, 115, -112, 225, +-72, 275, -62, 266, -72, 186, -88, 65, +-85, -36, -40, -98, 15, -120, 38, -88, +90, 16, 177, 174, 240, 336, 211, 415, +145, 361, 61, 203, -83, 16, -221, -162, +-269, -323, -211, -411, -125, -372, -37, -222, +66, -48, 181, 94, 296, 170, 308, 171, +180, 86, -21, -75, -184, -241, -269, -314, +-315, -277, -335, -197, -287, -75, -80, 135, +186, 388, 351, 570, 391, 649, 364, 616, +283, 466, 105, 234, -117, -35, -288, -326, +-337, -588, -312, -755, -286, -799, -195, -698, +3, -472, 240, -198, 367, 62, 370, 311, +292, 527, 180, 651, 49, 665, -141, 580, +-329, 398, -422, 172, -390, -26, -285, -203, +-135, -369, 59, -466, 257, -450, 404, -343, +412, -170, 329, 33, 236, 208, 114, 296, +-67, 274, -228, 171, -294, 34, -336, -126, +-357, -306, -330, -425, -273, -373, -157, -175, +51, 36, 300, 216, 469, 389, 554, 511, +590, 494, 582, 363, 462, 226, 152, 94, +-241, -87, -563, -280, -774, -383, -935, -386, +-991, -365, -832, -380, -460, -378, 4, -265, +406, -65, 750, 104, 1066, 222, 1243, 347, +1167, 446, 895, 453, 552, 376, 123, 254, +-379, 101, -857, -69, -1176, -238, -1273, -357, +-1200, -351, -1001, -233, -670, -115, -213, -24, +238, 104, 604, 241, 907, 287, 1090, 195, +1081, 3, 910, -207, 689, -364, 455, -454, +177, -467, -155, -364, -475, -143, -674, 138, +-757, 419, -771, 654, -728, 782, -637, 770, +-520, 621, -353, 365, -109, 42, 131, -293, +314, -599, 468, -845, 629, -986, 786, -983, +887, -824, 869, -524, 694, -122, 422, 313, +95, 713, -263, 1017, -622, 1177, -920, 1155, +-1087, 914, -1111, 483, -990, -22, -703, -481, +-269, -828, 180, -1014, 509, -1010, 752, -811, +962, -471, 1072, -110, 970, 160, 688, 314, +345, 368, 28, 326, -259, 218, -533, 129, +-711, 127, -732, 209, -652, 335, -528, 445, +-332, 498, -87, 462, 75, 298, 134, 5, +178, -332, 251, -637, 321, -863, 360, -952, +366, -869, 314, -642, 207, -319, 73, 39, +-35, 369, -116, 626, -214, 783, -303, 831, +-309, 776, -209, 642, -74, 441, 21, 198, +65, -44, 90, -267, 127, -449, 147, -550, +138, -561, 125, -508, 90, -381, -6, -199, +-116, -45, -190, 27, -263, 28, -348, -24, +-376, -105, -287, -178, -108, -205, 100, -139, +312, 51, 510, 330, 631, 633, 627, 899, +538, 1044, 407, 1000, 177, 765, -152, 378, +-454, -114, -640, -632, -721, -1063, -714, -1344, +-608, -1431, -412, -1308, -160, -1005, 83, -600, +263, -167, 390, 249, 447, 631, 382, 956, +256, 1192, 223, 1320, 300, 1324, 350, 1187, +313, 899, 269, 478, 253, -26, 150, -541, +-105, -1001, -389, -1319, -574, -1402, -678, -1231, +-746, -902, -726, -530, -576, -161, -337, 148, +-92, 328, 121, 382, 349, 379, 617, 366, +867, 399, 1006, 509, 1000, 661, 829, 801, +507, 868, 105, 769, -358, 495, -852, 127, +-1227, -288, -1302, -706, -1064, -1033, -648, -1181, +-150, -1141, 365, -937, 810, -621, 1033, -287, +958, 7, 656, 248, 244, 397, -173, 458, +-500, 513, -638, 591, -570, 657, -337, 705, +-36, 749, 212, 761, 351, 678, 377, 435, +308, 44, 149, -410, -51, -840, -195, -1204, +-205, -1444, -94, -1452, 24, -1186, 107, -730, +147, -194, 103, 375, -49, 902, -241, 1249, +-385, 1333, -455, 1195, -427, 922, -287, 568, +-52, 172, 211, -200, 425, -473, 573, -591, +665, -566, 680, -472, 558, -344, 343, -205, +119, -129, -106, -153, -366, -235, -643, -348, +-847, -462, -930, -482, -882, -344, -716, -42, +-423, 379, 9, 822, 470, 1151, 834, 1282, +1034, 1171, 1099, 798, 1022, 243, 747, -335, +326, -837, -87, -1205, -395, -1324, -669, -1152, +-892, -792, -929, -384, -762, -2, -524, 331, +-309, 601, -68, 753, 194, 755, 399, 670, +477, 550, 460, 370, 435, 116, 388, -131, +262, -309, 73, -431, -43, -511, -57, -485, +-49, -312, -57, -63, -44, 141, 23, 240, +66, 251, 21, 192, -101, 69, -225, -95, +-327, -251, -462, -335, -578, -297, -558, -152, +-341, 44, -30, 240, 270, 388, 554, 462, +824, 464, 1001, 388, 940, 249, 660, 88, +300, -95, -54, -310, -410, -499, -759, -591, +-976, -607, -986, -596, -814, -530, -568, -340, +-283, -23, 69, 351, 427, 684, 684, 922, +766, 1055, 746, 1025, 649, 763, 424, 308, +85, -227, -229, -754, -380, -1168, -423, -1355, +-433, -1251, -344, -865, -97, -298, 150, 294, +219, 776, 177, 1065, 92, 1115, -51, 922, +-261, 549, -428, 97, -453, -306, -335, -540, +-117, -583, 128, -516, 389, -404, 632, -255, +768, -83, 715, 73, 490, 181, 197, 223, +-114, 233, -407, 243, -641, 222, -722, 135, +-621, -8, -445, -169, -271, -292, -89, -339, +114, -312, 241, -200, 236, 4, 156, 260, +112, 458, 153, 526, 201, 470, 245, 321, +332, 94, 444, -186, 477, -450, 364, -610, +152, -636, -115, -566, -371, -417, -600, -188, +-782, 92, -856, 371, -764, 606, -549, 767, +-307, 841, -29, 793, 290, 579, 604, 221, +827, -214, 887, -647, 847, -991, 762, -1168, +599, -1133, 312, -868, -13, -402, -310, 162, +-586, 691, -810, 1087, -928, 1263, -914, 1151, +-809, 794, -644, 309, -443, -212, -187, -683, +171, -994, 566, -1077, 886, -905, 1073, -520, +1177, -40, 1191, 412, 992, 765, 539, 948, +-30, 905, -545, 669, -1007, 313, -1375, -116, +-1502, -561, -1315, -896, -890, -1021, -360, -939, +207, -716, 730, -402, 1101, 1, 1219, 460, +1083, 852, 782, 1061, 373, 1083, -53, 947, +-413, 649, -655, 221, -772, -240, -711, -624, +-458, -888, -147, -1011, 115, -934, 323, -638, +494, -221, 571, 180, 505, 483, 335, 663, +100, 704, -170, 579, -444, 291, -627, -74, +-690, -398, -657, -603, -523, -659, -292, -542, +10, -265, 321, 77, 599, 388, 800, 621, +864, 721, 778, 655, 584, 453, 341, 167, +59, -121, -218, -302, -439, -328, -585, -239, +-658, -105, -660, 2, -575, 20, -466, -63, +-367, -245, -233, -530, -46, -833, 128, -981, +259, -876, 410, -540, 582, -30, 679, 580, +652, 1161, 561, 1569, 458, 1723, 289, 1590, +28, 1187, -247, 576, -435, -134, -551, -789, +-645, -1261, -692, -1516, -621, -1556, -428, -1388, +-195, -1034, 44, -564, 278, -85, 467, 325, +561, 604, 541, 729, 444, 729, 292, 659, +106, 549, -97, 436, -276, 370, -358, 363, +-336, 366, -273, 323, -198, 219, -76, 42, +68, -206, 171, -476, 232, -689, 280, -768, +303, -675, 260, -461, 153, -213, 15, 34, +-134, 243, -272, 338, -378, 277, -444, 103, +-457, -88, -385, -216, -223, -248, -23, -181, +151, -22, 286, 209, 403, 440, 472, 594, +462, 648, 397, 604, 306, 453, 192, 218, +51, -39, -76, -275, -168, -454, -254, -547, +-342, -551, -393, -484, -401, -373, -388, -252, +-330, -145, -204, -71, -50, -46, 73, -61, +179, -84, 314, -72, 426, 1, 423, 138, +316, 315, 199, 489, 105, 615, -4, 660, +-121, 616, -181, 491, -161, 292, -126, 43, +-111, -195, -82, -367, -37, -473, -17, -531, +-36, -541, -45, -512, -17, -476, 39, -447, +94, -403, 99, -315, 52, -194, 6, -64, +-29, 102, -94, 336, -161, 592, -165, 782, +-126, 861, -81, 851, -4, 741, 126, 508, +235, 183, 249, -158, 204, -457, 163, -678, +126, -786, 68, -754, 14, -598, -39, -396, +-112, -210, -172, -49, -181, 76, -177, 151, +-222, 189, -253, 197, -194, 181, -95, 154, +-22, 134, 56, 139, 198, 158, 343, 165, +401, 156, 382, 183, 334, 246, 224, 277, +10, 224, -226, 102, -390, -59, -473, -239, +-490, -407, -416, -531, -244, -568, -21, -494, +199, -348, 370, -187, 452, -20, 415, 139, +290, 254, 156, 304, 52, 322, -32, 365, +-93, 448, -96, 519, -78, 501, -119, 377, +-187, 185, -237, -59, -283, -362, -348, -665, +-366, -863, -274, -890, -83, -753, 146, -493, +371, -144, 567, 238, 675, 564, 665, 758, +540, 815, 320, 764, 33, 621, -274, 385, +-531, 86, -695, -218, -742, -458, -676, -607, +-520, -657, -285, -595, 4, -428, 296, -179, +516, 103, 636, 347, 662, 479, 596, 472, +438, 335, 206, 106, -52, -149, -288, -349, +-485, -448, -621, -439, -642, -306, -524, -64, +-324, 222, -88, 475, 158, 636, 402, 668, +595, 561, 688, 329, 655, 17, 500, -297, +270, -547, -3, -710, -305, -764, -581, -667, +-746, -426, -767, -121, -687, 160, -523, 381, +-244, 537, 131, 623, 476, 624, 702, 534, +811, 365, 797, 144, 625, -118, 302, -389, +-56, -620, -354, -779, -576, -822, -694, -706, +-651, -403, -432, 53, -141, 548, 132, 946, +347, 1153, 461, 1117, 439, 831, 295, 357, +101, -197, -107, -704, -285, -1051, -373, -1164, +-319, -1022, -148, -679, 70, -238, 280, 186, +427, 505, 469, 686, 371, 739, 133, 676, +-188, 502, -495, 240, -699, -46, -769, -274, +-670, -396, -383, -428, 28, -387, 445, -261, +779, -61, 987, 150, 1012, 295, 811, 327, +409, 240, -52, 54, -429, -170, -708, -326, +-882, -339, -890, -217, -686, -24, -368, 190, +-70, 393, 178, 508, 392, 449, 521, 215, +492, -106, 345, -414, 176, -636, 48, -724, +-45, -637, -123, -398, -159, -97, -129, 202, +-37, 496, 72, 750, 152, 874, 188, 826, +167, 645, 75, 390, -59, 79, -182, -273, +-291, -618, -384, -889, -410, -1040, -324, -1038, +-149, -845, 31, -471, 196, -14, 368, 413, +493, 778, 486, 1060, 362, 1189, 233, 1098, +129, 795, -6, 364, -170, -98, -258, -521, +-257, -855, -270, -1060, -332, -1109, -367, -995, +-324, -744, -260, -399, -209, -21, -111, 339, +85, 653, 327, 901, 509, 1056, 598, 1099, +607, 1023, 533, 810, 346, 432, 79, -73, +-172, -590, -350, -1015, -433, -1294, -445, -1392, +-411, -1254, -323, -865, -181, -305, -56, 287, +-42, 768, -103, 1056, -129, 1131, -90, 1009, +-55, 732, -15, 375, 124, 9, 340, -305, +508, -515, 561, -596, 564, -584, 542, -518, +421, -388, 165, -192, -138, 17, -379, 192, +-549, 327, -683, 425, -772, 468, -747, 419, +-586, 287, -358, 139, -109, 31, 153, -71, +397, -213, 576, -368, 668, -485, 671, -569, +588, -645, 429, -670, 224, -560, 28, -276, +-119, 136, -217, 592, -270, 1005, -295, 1307, +-305, 1416, -317, 1253, -309, 820, -266, 210, +-227, -442, -192, -1016, -119, -1416, 2, -1581, +129, -1500, 247, -1194, 343, -704, 379, -131, +327, 398, 223, 806, 121, 1066, 32, 1169, +-45, 1127, -86, 960, -68, 701, -25, 406, +7, 122, 27, -139, 14, -374, -76, -570, +-224, -729, -351, -859, -414, -933, -417, -891, +-352, -711, -202, -421, 39, -67, 311, 291, +527, 610, 662, 846, 703, 957, 625, 914, +426, 729, 158, 444, -130, 126, -392, -146, +-593, -336, -714, -466, -721, -551, -588, -552, +-346, -437, -78, -243, 170, -39, 395, 125, +560, 212, 604, 207, 513, 114, 323, -48, +85, -246, -138, -436, -292, -528, -345, -426, +-299, -115, -178, 317, -12, 729, 142, 1016, +230, 1137, 240, 1047, 167, 726, 10, 228, +-192, -330, -352, -840, -408, -1217, -368, -1371, +-274, -1263, -137, -949, 64, -542, 291, -114, +462, 310, 533, 710, 536, 1008, 464, 1105, +290, 993, 55, 755, -161, 456, -336, 128, +-493, -182, -591, -430, -565, -588, -414, -621, +-197, -510, 32, -293, 247, -48, 404, 136, +455, 221, 414, 210, 313, 128, 153, -13, +-59, -216, -251, -447, -347, -613, -345, -610, +-286, -407, -192, -65, -70, 316, 63, 655, +212, 903, 356, 1020, 438, 956, 424, 686, +339, 280, 219, -142, 54, -480, -152, -662, +-359, -675, -523, -576, -627, -441, -615, -320, +-444, -235, -158, -183, 149, -155, 399, -152, +558, -164, 597, -140, 501, -38, 279, 127, +-20, 308, -312, 463, -504, 565, -524, 630, +-365, 701, -95, 756, 191, 694, 424, 461, +558, 108, 552, -294, 390, -703, 115, -1084, +-197, -1351, -458, -1394, -606, -1169, -606, -735, +-481, -187, -285, 400, -75, 924, 126, 1247, +312, 1308, 453, 1173, 504, 931, 454, 606, +365, 201, 275, -221, 145, -568, -54, -796, +-262, -922, -428, -966, -563, -907, -643, -696, +-562, -346, -294, 78, 26, 506, 285, 864, +489, 1060, 642, 1035, 660, 804, 491, 411, +186, -83, -150, -581, -430, -964, -579, -1139, +-548, -1062, -359, -745, -96, -262, 173, 281, +397, 771, 504, 1097, 465, 1181, 322, 1030, +125, 695, -115, 231, -341, -272, -464, -693, +-459, -945, -379, -1001, -270, -875, -127, -629, +27, -325, 143, -3, 219, 289, 293, 488, +344, 578, 324, 579, 245, 505, 158, 355, +66, 163, -56, -12, -188, -143, -266, -232, +-241, -276, -153, -256, -63, -165, 22, -36, +120, 63, 204, 104, 225, 109, 142, 102, +-22, 73, -185, 29, -296, 6, -370, 3, +-414, -26, -357, -91, -183, -165, 18, -218, +184, -243, 360, -252, 570, -236, 715, -156, +693, 15, 532, 211, 324, 336, 77, 367, +-244, 338, -582, 279, -833, 199, -949, 116, +-932, 42, -775, -6, -461, -19, -29, -20, +406, -35, 732, -72, 912, -130, 970, -215, +903, -297, 673, -339, 299, -335, -105, -308, +-421, -285, -618, -258, -725, -196, -709, -67, +-532, 134, -284, 373, -72, 612, 123, 814, +324, 937, 442, 945, 404, 790, 280, 440, +167, -66, 63, -609, -62, -1061, -177, -1356, +-236, -1465, -243, -1345, -220, -996, -158, -478, +-58, 136, 33, 762, 106, 1279, 179, 1566, +238, 1571, 259, 1314, 242, 866, 186, 299, +60, -314, -107, -861, -236, -1204, -296, -1271, +-314, -1103, -298, -777, -202, -370, -10, 23, +209, 322, 365, 514, 435, 608, 417, 606, +294, 524, 90, 375, -136, 184, -332, -3, +-467, -162, -512, -308, -464, -438, -338, -500, +-152, -434, 55, -229, 228, 64, 342, 346, +387, 536, 376, 611, 352, 575, 332, 417, +269, 152, 142, -149, -3, -410, -108, -583, +-178, -634, -266, -554, -356, -386, -380, -190, +-310, 4, -200, 178, -98, 300, -3, 353, +81, 341, 131, 266, 124, 141, 84, 11, +58, -66, 69, -50, 76, 45, 68, 147, +88, 204, 146, 225, 186, 209, 156, 100, +78, -109, 9, -333, -27, -485, -64, -530, +-123, -462, -174, -304, -204, -111, -240, 57, +-269, 161, -242, 207, -159, 235, -66, 275, +34, 316, 183, 342, 369, 363, 500, 362, +493, 296, 371, 137, 194, -113, -24, -401, +-274, -619, -470, -677, -519, -574, -444, -370, +-312, -106, -134, 172, 93, 386, 303, 478, +401, 457, 360, 354, 227, 180, 67, -36, +-62, -223, -137, -317, -178, -310, -191, -248, +-142, -168, -20, -49, 93, 136, 120, 345, +96, 484, 74, 497, 45, 382, -4, 160, +-38, -110, -30, -358, -27, -550, -60, -661, +-92, -638, -77, -450, -43, -142, -35, 194, +-31, 468, 2, 629, 66, 657, 138, 558, +188, 359, 176, 109, 102, -149, 2, -411, +-92, -646, -168, -747, -208, -650, -199, -416, +-154, -141, -89, 146, 6, 440, 142, 692, +266, 823, 304, 774, 257, 561, 186, 251, +114, -71, 14, -335, -125, -507, -260, -591, +-339, -607, -346, -553, -302, -421, -213, -237, +-65, -52, 102, 106, 217, 236, 257, 329, +262, 382, 250, 402, 185, 371, 51, 255, +-80, 78, -109, -84, -45, -178, 18, -198, +31, -174, 40, -141, 62, -103, 56, -49, +-4, 22, -91, 82, -164, 108, -211, 94, +-225, 59, -181, 47, -71, 71, 56, 76, +131, 18, 142, -69, 140, -133, 151, -167, +139, -182, 61, -180, -58, -162, -149, -130, +-163, -79, -113, 2, -38, 107, 37, 205, +91, 259, 124, 258, 125, 220, 102, 160, +70, 62, 21, -74, -57, -200, -112, -253, +-78, -204, 12, -73, 79, 92, 85, 230, +52, 295, -23, 267, -129, 153, -223, -11, +-258, -167, -238, -276, -192, -331, -95, -308, +87, -192, 287, -43, 383, 44, 352, 26, +252, -51, 119, -123, -39, -153, -192, -132, +-290, -45, -298, 124, -219, 340, -77, 528, +91, 630, 228, 627, 291, 502, 276, 260, +193, -36, 54, -323, -91, -561, -217, -716, +-310, -761, -343, -708, -274, -572, -118, -353, +41, -72, 151, 222, 214, 470, 249, 639, +248, 718, 189, 698, 85, 571, -10, 347, +-85, 77, -167, -183, -212, -401, -178, -551, +-113, -592, -86, -511, -79, -358, -15, -180, +100, 17, 189, 224, 205, 385, 180, 443, +153, 389, 107, 250, 20, 58, -88, -147, +-178, -321, -227, -416, -221, -394, -166, -260, +-79, -42, 54, 223, 198, 477, 288, 624, +282, 606, 216, 436, 130, 151, 15, -189, +-158, -496, -350, -697, -443, -760, -411, -668, +-313, -420, -176, -71, 19, 292, 235, 559, +397, 658, 476, 604, 473, 457, 389, 243, +233, -23, 26, -272, -174, -412, -309, -423, +-368, -351, -385, -242, -359, -116, -263, 8, +-120, 103, 29, 160, 159, 211, 277, 290, +370, 377, 396, 412, 335, 370, 209, 265, +52, 105, -141, -131, -349, -435, -504, -723, +-540, -886, -443, -859, -237, -648, 27, -310, +289, 85, 505, 472, 618, 780, 592, 937, +430, 907, 172, 713, -125, 408, -388, 68, +-552, -226, -593, -420, -511, -501, -348, -493, +-153, -424, 69, -309, 270, -165, 391, -26, +435, 62, 426, 84, 359, 63, 232, 24, +83, -9, -58, -16, -177, 10, -285, 60, +-358, 128, -350, 216, -241, 303, -75, 337, +65, 268, 165, 97, 243, -121, 281, -318, +232, -450, 94, -492, -85, -431, -237, -263, +-328, -25, -348, 218, -280, 404, -144, 476, +12, 403, 163, 214, 282, 0, 353, -161, +370, -245, 324, -251, 217, -161, 81, 6, +-26, 184, -81, 291, -118, 281, -173, 161, +-229, -43, -235, -291, -184, -510, -129, -597, +-102, -513, -50, -302, 33, -23, 87, 289, +90, 578, 70, 760, 34, 757, -39, 559, +-141, 247, -203, -82, -153, -364, -23, -564, +103, -642, 211, -578, 345, -403, 480, -181, +508, 37, 391, 207, 192, 300, -34, 318, +-269, 284, -480, 237, -604, 210, -615, 197, +-548, 170, -414, 119, -198, 54, 75, -28, +322, -153, 491, -316, 553, -458, 517, -530, +414, -525, 255, -440, 51, -265, -174, -14, +-354, 260, -441, 499, -413, 677, -308, 777, +-153, 774, 30, 635, 194, 375, 304, 63, +365, -247, 389, -523, 323, -724, 141, -811, +-69, -779, -227, -632, -334, -383, -415, -84, +-456, 190, -427, 389, -312, 499, -117, 526, +120, 478, 327, 367, 439, 226, 463, 94, +443, -12, 374, -93, 243, -134, 61, -133, +-112, -118, -232, -116, -279, -108, -250, -72, +-170, -23, -94, 11, -76, 18, -92, -5, +-96, -55, -88, -116, -112, -170, -153, -208, +-144, -212, -65, -154, 67, -28, 225, 139, +368, 292, 438, 379, 414, 378, 329, 295, +213, 149, 63, -18, -150, -144, -398, -207, +-575, -216, -624, -174, -564, -67, -420, 71, +-184, 151, 117, 134, 422, 66, 674, 0, +824, -64, 828, -132, 649, -191, 314, -214, +-112, -202, -507, -177, -804, -140, -977, -60, +-981, 43, -789, 124, -412, 190, 54, 269, +482, 347, 790, 370, 941, 315, 910, 197, +710, 69, 399, -45, 29, -155, -344, -268, +-644, -357, -795, -400, -752, -397, -549, -345, +-259, -238, 43, -78, 329, 104, 579, 284, +714, 439, 673, 553, 469, 571, 163, 449, +-174, 206, -459, -72, -650, -314, -714, -493, +-632, -595, -456, -595, -216, -481, 80, -293, +373, -80, 561, 124, 604, 301, 549, 426, +456, 492, 332, 515, 169, 511, 4, 462, +-133, 331, -238, 118, -319, -129, -371, -351, +-380, -532, -373, -655, -356, -685, -288, -594, +-156, -402, 23, -158, 207, 98, 339, 316, +404, 452, 420, 492, 366, 463, 226, 406, +36, 335, -163, 240, -305, 131, -353, 30, +-313, -53, -210, -135, -62, -236, 123, -356, +282, -468, 363, -532, 360, -527, 286, -444, +160, -278, 0, -35, -180, 256, -325, 544, +-380, 778, -380, 917, -356, 912, -280, 727, +-150, 381, -9, -44, 105, -454, 181, -799, +236, -1033, 280, -1096, 311, -947, 315, -631, +295, -226, 242, 190, 159, 550, 49, 785, +-82, 845, -235, 739, -384, 524, -469, 258, +-483, -20, -405, -256, -232, -388, -7, -371, +225, -235, 427, -46, 550, 138, 567, 269, +477, 307, 268, 228, -15, 47, -276, -197, +-475, -439, -609, -618, -645, -677, -546, -582, +-333, -333, -64, 0, 208, 324, 442, 570, +610, 704, 675, 717, 617, 601, 460, 373, +237, 85, -34, -179, -313, -352, -514, -415, +-611, -392, -605, -300, -511, -160, -345, -14, +-123, 98, 125, 164, 347, 176, 482, 111, +526, -20, 480, -166, 360, -255, 193, -263, +4, -204, -166, -100, -292, 50, -375, 224, +-404, 371, -350, 440, -234, 399, -123, 247, +-35, 16, 60, -221, 167, -397, 252, -472, +304, -445, 330, -330, 315, -136, 256, 119, +147, 378, 17, 556, -113, 590, -268, 477, +-416, 265, -471, 4, -400, -263, -277, -492, +-127, -639, 45, -668, 234, -549, 391, -293, +461, 35, 448, 339, 362, 548, 222, 636, +45, 602, -135, 466, -270, 237, -359, -48, +-415, -313, -423, -479, -361, -523, -229, -459, +-42, -310, 144, -112, 292, 90, 411, 256, +480, 363, 482, 400, 395, 360, 200, 223, +-50, 15, -286, -187, -463, -308, -559, -339, +-547, -308, -434, -226, -244, -83, 3, 103, +269, 263, 490, 331, 585, 294, 552, 195, +412, 67, 219, -54, 18, -137, -195, -162, +-374, -161, -466, -162, -468, -166, -392, -155, +-244, -128, -54, -100, 136, -55, 287, 36, +368, 185, 391, 344, 357, 457, 230, 472, +14, 371, -233, 165, -413, -95, -479, -328, +-442, -473, -316, -505, -119, -433, 140, -276, +403, -74, 582, 114, 612, 218, 502, 214, +267, 124, -29, 11, -295, -65, -469, -73, +-494, -9, -398, 112, -244, 262, -56, 386, +147, 432, 284, 369, 273, 198, 128, -66, +-66, -378, -231, -654, -315, -809, -284, -789, +-139, -599, 69, -276, 278, 135, 431, 567, +512, 911, 490, 1082, 318, 1027, 57, 759, +-197, 323, -380, -190, -480, -657, -489, -983, +-419, -1130, -299, -1088, -158, -854, -23, -459, +122, 23, 252, 480, 343, 835, 397, 1048, +432, 1101, 424, 976, 340, 684, 189, 278, +-32, -172, -288, -597, -510, -920, -648, -1059, +-665, -980, -556, -717, -347, -350, -83, 42, +210, 389, 482, 639, 657, 741, 710, 675, +649, 475, 495, 228, 282, 10, 55, -147, +-173, -233, -398, -260, -585, -244, -719, -212, +-753, -173, -675, -134, -501, -95, -241, -64, +94, -42, 456, -16, 775, 36, 990, 115, +1028, 190, 868, 237, 533, 243, 97, 212, +-349, 148, -720, 59, -947, -63, -1014, -211, +-908, -349, -626, -426, -242, -398, 160, -272, +496, -84, 702, 117, 785, 305, 761, 458, +620, 543, 388, 521, 116, 391, -179, 189, +-451, -39, -654, -254, -749, -419, -720, -520, +-589, -567, -374, -558, -93, -483, 247, -319, +579, -82, 798, 179, 862, 404, 797, 571, +610, 672, 323, 687, -3, 594, -341, 406, +-622, 170, -788, -72, -838, -276, -750, -420, +-548, -494, -290, -520, -15, -523, 242, -517, +451, -468, 606, -336, 682, -129, 636, 107, +482, 325, 284, 515, 95, 669, -89, 746, +-266, 681, -390, 464, -459, 162, -444, -126, +-355, -342, -236, -474, -102, -525, 10, -499, +71, -411, 109, -292, 146, -159, 151, -31, +141, 78, 129, 154, 129, 213, 163, 281, +209, 361, 231, 414, 193, 401, 106, 317, +-1, 176, -126, -4, -252, -200, -363, -390, +-440, -566, -441, -694, -364, -724, -234, -596, +-45, -324, 167, 23, 324, 382, 419, 707, +459, 946, 445, 1035, 378, 940, 223, 668, +20, 269, -157, -186, -265, -592, -325, -871, +-335, -988, -285, -968, -200, -844, -103, -625, +-8, -323, 79, 21, 130, 347, 141, 620, +108, 817, 52, 921, 29, 909, 29, 767, +23, 496, 21, 130, 26, -264, 31, -594, +36, -783, 44, -810, 32, -692, 5, -480, +-23, -225, -56, 17, -79, 209, -87, 322, +-84, 352, -85, 313, -76, 242, -57, 183, +-34, 148, 5, 119, 44, 68, 89, 3, +130, -60, 162, -101, 180, -118, 184, -108, +154, -92, 73, -86, -36, -100, -158, -127, +-273, -150, -349, -162, -354, -147, -287, -85, +-153, 40, 35, 210, 228, 383, 400, 497, +517, 512, 504, 400, 364, 190, 138, -66, +-131, -319, -392, -529, -586, -663, -670, -678, +-606, -565, -380, -347, -57, -72, 286, 228, +572, 496, 766, 677, 795, 738, 627, 681, +318, 514, -58, 244, -400, -97, -659, -436, +-807, -663, -766, -732, -513, -641, -159, -430, +180, -142, 443, 162, 588, 421, 599, 572, +456, 581, 197, 446, -65, 207, -260, -65, +-350, -306, -322, -456, -185, -498, 11, -432, +174, -290, 252, -91, 226, 137, 106, 356, +-63, 510, -235, 551, -382, 476, -427, 314, +-330, 111, -147, -106, 94, -308, 318, -463, +473, -538, 548, -516, 512, -387, 367, -181, +157, 34, -82, 198, -327, 286, -520, 315, +-605, 296, -570, 231, -450, 121, -269, 7, +-21, -61, 249, -51, 493, 18, 653, 107, +676, 165, 576, 162, 351, 101, 38, -7, +-269, -139, -516, -285, -668, -414, -681, -483, +-545, -449, -291, -311, 41, -95, 335, 126, +518, 289, 568, 379, 487, 422, 317, 425, +90, 379, -125, 293, -292, 184, -374, 80, +-341, -17, -220, -106, -67, -209, 81, -333, +179, -467, 205, -552, 189, -522, 134, -366, +44, -133, -40, 114, -120, 352, -182, 551, +-199, 665, -176, 644, -124, 485, -52, 216, +43, -94, 140, -364, 233, -538, 307, -587, +327, -526, 266, -394, 130, -221, -48, -8, +-244, 216, -400, 388, -502, 445, -515, 403, +-399, 308, -174, 206, 118, 111, 402, 11, +603, -90, 680, -179, 634, -229, 466, -242, +191, -223, -125, -198, -417, -173, -629, -133, +-720, -46, -676, 91, -525, 229, -291, 306, +-14, 297, 229, 217, 420, 88, 549, -66, +581, -226, 517, -345, 370, -381, 177, -312, +-24, -152, -191, 78, -310, 320, -365, 480, +-344, 507, -258, 422, -124, 279, 30, 110, +164, -73, 213, -264, 191, -409, 116, -460, +-18, -411, -163, -316, -280, -222, -336, -130, +-294, -24, -160, 93, 26, 198, 234, 276, +411, 312, 502, 301, 490, 241, 369, 164, +164, 94, -75, 37, -290, -28, -434, -99, +-492, -142, -428, -146, -259, -137, -59, -146, +153, -167, 327, -186, 406, -173, 374, -114, +241, -15, 37, 90, -155, 177, -310, 234, +-413, 264, -412, 267, -312, 232, -131, 150, +93, 25, 305, -98, 455, -193, 497, -252, +436, -295, 295, -324, 101, -328, -98, -287, +-281, -192, -424, -50, -461, 121, -385, 294, +-255, 443, -82, 538, 85, 568, 202, 525, +277, 398, 285, 176, 253, -93, 191, -346, +82, -539, -40, -655, -123, -691, -159, -641, +-170, -517, -164, -329, -150, -97, -127, 157, +-95, 384, -16, 555, 87, 660, 158, 717, +213, 722, 246, 629, 258, 422, 257, 137, +191, -162, 58, -444, -93, -684, -248, -844, +-373, -873, -419, -765, -409, -548, -364, -275, +-269, 23, -114, 316, 91, 547, 280, 670, +412, 689, 486, 650, 497, 570, 459, 446, +355, 257, 209, 30, 38, -187, -171, -360, +-379, -500, -501, -603, -532, -638, -499, -585, +-403, -455, -270, -283, -85, -85, 144, 107, +353, 266, 483, 367, 501, 436, 423, 493, +296, 528, 156, 509, 3, 428, -165, 301, +-297, 142, -358, -55, -356, -285, -286, -502, +-160, -657, -46, -719, 16, -676, 63, -518, +112, -273, 168, 4, 186, 256, 146, 455, +97, 600, 87, 672, 111, 646, 133, 518, +148, 332, 131, 121, 79, -88, 2, -285, +-87, -442, -195, -544, -324, -587, -451, -560, +-534, -446, -506, -263, -356, -74, -127, 90, +145, 226, 400, 360, 601, 478, 732, 549, +751, 547, 622, 485, 356, 379, 25, 227, +-292, 32, -527, -192, -638, -419, -626, -625, +-523, -745, -350, -732, -124, -580, 106, -333, +309, -50, 396, 218, 352, 448, 261, 608, +161, 650, 57, 556, -52, 364, -148, 162, +-201, -1, -185, -122, -115, -206, -12, -240, +91, -239, 156, -231, 174, -227, 143, -210, +95, -168, 25, -113, -86, -55, -195, 16, +-274, 128, -292, 247, -214, 313, -75, 298, +74, 238, 207, 158, 305, 72, 366, -17, +380, -115, 296, -221, 130, -322, -66, -390, +-265, -416, -402, -391, -458, -314, -425, -166, +-333, 65, -192, 367, 0, 659, 206, 849, +366, 877, 440, 731, 412, 435, 292, 33, +145, -397, -10, -771, -139, -993, -203, -1016, +-233, -843, -205, -527, -103, -132, 20, 252, +120, 539, 153, 686, 106, 696, 8, 602, +-109, 423, -220, 190, -293, -52, -307, -236, +-252, -332, -135, -349, 17, -319, 207, -249, +380, -141, 484, -10, 506, 119, 430, 229, +311, 307, 173, 327, 0, 296, -191, 218, +-360, 95, -496, -87, -570, -306, -561, -517, +-487, -658, -338, -682, -140, -575, 75, -338, +298, -3, 504, 382, 656, 730, 676, 962, +556, 1017, 354, 880, 113, 572, -136, 155, +-366, -284, -542, -658, -603, -900, -528, -980, +-368, -896, -147, -671, 111, -336, 317, 34, +434, 370, 445, 620, 377, 767, 255, 794, +80, 690, -138, 463, -344, 156, -451, -168, +-431, -453, -309, -642, -136, -708, 52, -638, +230, -451, 385, -183, 479, 105, 462, 363, +342, 541, 138, 606, -108, 549, -310, 392, +-430, 174, -471, -69, -445, -296, -359, -469, +-211, -538, -5, -490, 215, -336, 372, -119, +446, 116, 446, 318, 380, 427, 268, 415, +143, 295, 1, 107, -163, -105, -285, -266, +-337, -312, -308, -221, -234, -36, -161, 161, +-100, 296, -46, 335, 3, 259, 40, 67, +67, -202, 76, -467, 66, -623, 71, -622, +118, -464, 180, -187, 210, 150, 197, 471, +129, 709, 40, 812, -20, 768, -81, 594, +-143, 314, -190, -25, -221, -356, -201, -612, +-133, -753, -60, -763, -17, -653, 3, -437, +16, -154, 55, 145, 118, 396, 173, 547, +193, 565, 171, 456, 142, 270, 91, 57, +20, -129, -73, -269, -205, -337, -319, -323, +-350, -216, -294, -46, -162, 129, 20, 274, +194, 380, 340, 436, 444, 415, 467, 301, +404, 94, 235, -166, -25, -435, -296, -660, +-503, -785, -596, -763, -581, -586, -471, -287, +-267, 81, 1, 452, 295, 758, 550, 929, +680, 930, 655, 752, 509, 450, 263, 87, +-13, -273, -265, -577, -480, -782, -599, -857, +-593, -790, -467, -592, -238, -291, 25, 63, +234, 403, 354, 676, 392, 837, 375, 862, +302, 729, 171, 461, 20, 99, -115, -287, +-194, -619, -206, -837, -188, -912, -145, -843, +-100, -637, -82, -337, -58, 8, -11, 346, +50, 628, 106, 812, 145, 880, 160, 816, +177, 638, 194, 388, 175, 95, 97, -207, +-40, -480, -186, -677, -305, -773, -372, -757, +-375, -646, -318, -460, -190, -234, -8, 12, +199, 253, 403, 453, 553, 577, 579, 613, +470, 576, 267, 468, 13, 303, -242, 105, +-466, -78, -616, -217, -640, -313, -529, -375, +-309, -397, -27, -369, 261, -304, 479, -228, +582, -151, 576, -54, 470, 70, 296, 214, +75, 341, -155, 416, -356, 417, -468, 349, +-485, 214, -428, 35, -309, -152, -164, -309, +-4, -395, 154, -396, 291, -303, 379, -147, +400, 28, 352, 175, 237, 262, 96, 281, +-37, 251, -164, 181, -272, 72, -326, -60, +-307, -181, -222, -253, -87, -273, 50, -239, +164, -163, 243, -57, 252, 61, 208, 181, +123, 278, 20, 323, -93, 293, -198, 193, +-247, 62, -227, -55, -155, -128, -75, -167, +2, -179, 75, -172, 147, -152, 183, -131, +187, -124, 182, -136, 147, -154, 88, -149, +20, -89, -48, 43, -97, 223, -142, 402, +-186, 524, -193, 558, -150, 494, -77, 343, +4, 112, 65, -184, 93, -495, 98, -744, +75, -864, 40, -826, -7, -656, -42, -397, +-24, -69, 27, 300, 117, 658, 217, 929, +273, 1057, 263, 1008, 172, 797, -3, 463, +-213, 51, -423, -380, -609, -773, -681, -1065, +-604, -1191, -372, -1111, -18, -837, 376, -414, +736, 76, 971, 538, 1016, 884, 856, 1065, +519, 1067, 65, 886, -424, 551, -852, 133, +-1107, -259, -1115, -533, -902, -652, -530, -638, +-84, -532, 346, -379, 705, -208, 901, -50, +898, 62, 735, 109, 460, 103, 144, 92, +-155, 117, -383, 191, -518, 275, -552, 329, +-515, 324, -418, 271, -275, 174, -108, 34, +55, -135, 180, -297, 284, -412, 361, -450, +387, -395, 367, -267, 285, -97, 146, 67, +-12, 194, -158, 274, -273, 308, -324, 292, +-307, 224, -245, 118, -148, 4, -37, -84, +76, -130, 167, -135, 198, -129, 177, -115, +125, -96, 84, -61, 51, -9, 23, 45, +-2, 87, -37, 111, -79, 122, -109, 123, +-120, 116, -130, 78, -120, 1, -100, -94, +-53, -169, 28, -213, 107, -212, 157, -177, +159, -125, 124, -64, 61, 7, -9, 85, +-55, 153, -81, 201, -80, 221, -53, 220, +-8, 212, 50, 203, 102, 164, 117, 78, +83, -43, 32, -169, -17, -268, -49, -320, +-68, -310, -92, -240, -118, -132, -145, -26, +-152, 50, -146, 86, -120, 76, -83, 7, +-34, -90, 46, -147, 157, -113, 286, 13, +390, 192, 423, 382, 355, 533, 224, 600, +68, 543, -113, 371, -300, 112, -468, -189, +-559, -494, -529, -737, -399, -849, -204, -824, +25, -697, 247, -500, 403, -229, 472, 94, +484, 425, 443, 707, 326, 900, 140, 970, +-53, 901, -210, 692, -301, 376, -345, 4, +-382, -376, -378, -703, -333, -910, -244, -944, +-115, -810, 37, -551, 179, -236, 302, 73, +395, 328, 451, 503, 457, 582, 383, 563, +241, 456, 50, 291, -151, 116, -308, -30, +-413, -124, -457, -178, -443, -212, -372, -233, +-231, -224, -56, -176, 108, -107, 230, -46, +297, -8, 309, 31, 297, 84, 260, 132, +186, 152, 90, 134, -19, 72, -84, -16, +-101, -104, -97, -158, -93, -166, -100, -137, +-102, -81, -110, 6, -123, 116, -124, 213, +-117, 264, -128, 238, -122, 145, -60, 26, +53, -72, 191, -130, 288, -152, 324, -159, +319, -151, 269, -116, 165, -60, 17, -6, +-147, 19, -290, 15, -372, -3, -359, -10, +-261, 5, -121, 34, 10, 45, 121, 33, +195, 28, 227, 57, 217, 111, 150, 156, +48, 175, -57, 154, -106, 99, -99, 11, +-87, -93, -89, -204, -83, -307, -53, -374, +-16, -361, 22, -240, 61, -40, 106, 171, +138, 328, 134, 409, 121, 414, 104, 350, +51, 216, -63, 19, -193, -207, -265, -388, +-266, -470, -212, -435, -123, -306, -13, -128, +101, 68, 200, 249, 271, 395, 284, 478, +237, 468, 134, 346, 17, 144, -82, -70, +-147, -234, -179, -331, -191, -383, -179, -400, +-151, -369, -93, -283, -17, -153, 41, 8, +59, 168, 52, 301, 60, 389, 87, 443, +114, 465, 121, 414, 112, 248, 80, -16, +22, -292, -35, -505, -85, -619, -126, -633, +-163, -526, -174, -303, -114, -5, 8, 307, +143, 582, 229, 760, 251, 774, 219, 610, +128, 320, -11, -5, -163, -311, -282, -579, +-355, -771, -349, -822, -257, -689, -96, -405, +90, -48, 227, 296, 293, 560, 294, 702, +253, 705, 187, 573, 95, 341, -6, 50, +-80, -240, -103, -455, -97, -529, -90, -451, +-105, -275, -133, -76, -164, 105, -189, 253, +-161, 349, -68, 359, 64, 262, 192, 81, +279, -130, 330, -315, 322, -431, 222, -451, +26, -377, -204, -227, -403, -28, -509, 206, +-479, 446, -321, 620, -68, 659, 196, 543, +425, 318, 573, 47, 599, -222, 492, -463, +254, -638, -43, -712, -315, -661, -511, -479, +-601, -198, -566, 116, -427, 400, -220, 613, +31, 730, 267, 748, 441, 653, 508, 433, +461, 103, 338, -272, 168, -601, -10, -810, +-174, -871, -309, -793, -377, -592, -349, -296, +-233, 60, -77, 415, 72, 703, 174, 865, +220, 867, 196, 724, 127, 495, 57, 224, +-15, -68, -79, -360, -133, -607, -148, -747, +-96, -752, -15, -632, 45, -429, 67, -190, +79, 47, 91, 256, 96, 422, 83, 526, +51, 543, 5, 464, -57, 313, -116, 141, +-166, -6, -189, -124, -177, -222, -148, -302, +-82, -344, 27, -326, 162, -241, 268, -116, +305, 0, 280, 81, 216, 136, 133, 187, +12, 232, -130, 255, -261, 234, -324, 171, +-311, 83, -240, -11, -124, -100, 8, -195, +120, -305, 180, -404, 197, -431, 190, -340, +146, -156, 58, 54, -51, 244, -130, 393, +-161, 483, -142, 497, -93, 431, -33, 292, +36, 104, 103, -95, 169, -249, 221, -318, +233, -324, 187, -319, 83, -332, -34, -334, +-154, -288, -261, -192, -338, -73, -361, 47, +-319, 165, -199, 289, -8, 409, 191, 500, +350, 530, 432, 463, 433, 304, 354, 99, +204, -103, 20, -277, -173, -430, -338, -566, +-445, -642, -464, -602, -368, -439, -199, -203, +-22, 47, 138, 272, 283, 451, 389, 569, +423, 606, 373, 553, 257, 406, 101, 175, +-74, -81, -214, -280, -289, -381, -312, -412, +-295, -414, -240, -377, -143, -273, -37, -108, +52, 68, 109, 208, 131, 289, 128, 311, +123, 282, 132, 227, 141, 158, 138, 66, +114, -54, 77, -172, 37, -242, -32, -249, +-117, -221, -201, -189, -273, -164, -313, -121, +-283, -37, -160, 91, 10, 230, 166, 334, +284, 376, 374, 358, 409, 299, 353, 195, +212, 42, 12, -151, -193, -340, -375, -464, +-476, -478, -447, -383, -320, -236, -153, -96, +16, 21, 183, 128, 326, 216, 406, 260, +385, 246, 285, 199, 145, 147, -1, 118, +-109, 124, -183, 151, -231, 149, -249, 83, +-227, -30, -159, -144, -81, -237, -7, -323, +64, -393, 117, -411, 145, -340, 150, -179, +138, 44, 104, 266, 41, 419, -45, 468, +-98, 420, -88, 319, -59, 185, -35, 19, +-15, -162, 12, -301, 31, -356, 42, -326, +48, -243, 37, -149, 6, -73, -24, -15, +-18, 57, 14, 165, 41, 282, 41, 352, +19, 354, -24, 299, -95, 205, -157, 61, +-182, -135, -178, -356, -156, -547, -91, -645, +52, -601, 232, -409, 374, -123, 440, 183, +433, 447, 348, 643, 169, 752, -69, 742, +-314, 586, -514, 299, -638, -54, -639, -383, +-500, -619, -263, -739, 21, -750, 285, -658, +498, -461, 620, -179, 631, 143, 540, 432, +358, 622, 111, 676, -139, 604, -313, 455, +-389, 269, -395, 59, -356, -160, -266, -343, +-133, -443, -17, -437, 56, -353, 86, -231, +76, -114, 32, -29, -23, 28, -40, 83, +-9, 139, 47, 167, 103, 146, 158, 107, +211, 100, 235, 134, 216, 171, 147, 175, +60, 135, -42, 61, -140, -24, -199, -108, +-217, -187, -211, -260, -205, -326, -183, -357, +-134, -310, -69, -186, 3, -31, 61, 108, +92, 220, 106, 317, 127, 403, 145, 461, +147, 450, 137, 353, 118, 190, 100, -1, +77, -190, 49, -362, 20, -506, -31, -602, +-118, -625, -224, -550, -284, -366, -271, -105, +-218, 169, -162, 398, -76, 560, 58, 671, +192, 728, 276, 690, 284, 530, 252, 280, +189, -4, 100, -279, 12, -515, -53, -684, +-95, -772, -130, -776, -155, -672, -168, -444, +-162, -129, -141, 185, -121, 426, -88, 574, +-31, 641, 80, 631, 225, 540, 339, 387, +377, 197, 321, -1, 208, -166, 43, -266, +-170, -308, -385, -330, -546, -350, -607, -348, +-542, -296, -331, -192, -16, -72, 333, 34, +610, 117, 753, 180, 761, 225, 635, 245, +388, 225, 39, 152, -336, 41, -637, -69, +-798, -136, -781, -145, -612, -108, -350, -50, +-49, 20, 256, 102, 501, 193, 630, 252, +617, 233, 472, 123, 247, -48, -10, -221, +-230, -350, -357, -406, -383, -391, -322, -310, +-199, -163, -32, 41, 137, 257, 250, 414, +257, 462, 158, 397, 6, 259, -148, 94, +-255, -57, -292, -175, -246, -244, -136, -261, +15, -221, 197, -123, 355, 5, 435, 109, +408, 140, 282, 103, 100, 39, -91, -24, +-247, -87, -354, -144, -401, -174, -391, -165, +-314, -112, -176, -16, -7, 103, 151, 193, +260, 221, 324, 198, 341, 167, 316, 149, +258, 121, 163, 68, 38, 4, -111, -50, +-236, -90, -310, -136, -333, -194, -318, -261, +-272, -321, -186, -339, -63, -283, 85, -151, +222, 19, 313, 183, 334, 318, 296, 419, +228, 476, 140, 469, 53, 372, -27, 196, +-94, -16, -129, -208, -131, -346, -111, -423, +-101, -444, -123, -406, -179, -303, -234, -143, +-249, 47, -218, 224, -140, 338, -24, 359, +129, 306, 296, 225, 438, 135, 519, 29, +489, -89, 346, -182, 123, -227, -127, -230, +-351, -212, -508, -180, -570, -135, -524, -77, +-370, 6, -136, 129, 143, 278, 398, 395, +555, 422, 577, 356, 466, 230, 278, 67, +59, -132, -166, -340, -376, -493, -533, -543, +-580, -484, -498, -330, -316, -121, -94, 86, +119, 245, 295, 341, 430, 386, 517, 388, +526, 340, 461, 242, 320, 116, 123, 0, +-93, -80, -288, -137, -434, -189, -533, -240, +-587, -280, -577, -290, -458, -259, -241, -196, +14, -111, 250, -14, 451, 99, 627, 228, +733, 361, 732, 456, 607, 465, 373, 367, +80, 191, -228, -14, -499, -216, -692, -394, +-777, -518, -752, -559, -625, -500, -409, -346, +-124, -136, 183, 78, 429, 249, 565, 358, +595, 422, 554, 456, 482, 449, 366, 385, +201, 272, 17, 123, -130, -45, -228, -210, +-295, -348, -341, -449, -368, -509, -378, -505, +-368, -415, -303, -250, -183, -54, -36, 131, +118, 278, 257, 385, 379, 445, 466, 452, +493, 399, 436, 281, 296, 109, 109, -79, +-82, -228, -237, -309, -350, -338, -425, -326, +-450, -263, -403, -151, -288, -24, -146, 81, +8, 140, 146, 151, 251, 132, 322, 114, +367, 117, 389, 136, 350, 147, 239, 119, +82, 44, -75, -57, -212, -164, -324, -263, +-388, -337, -394, -356, -336, -297, -226, -155, +-81, 44, 74, 240, 197, 382, 266, 447, +283, 433, 285, 358, 276, 240, 242, 93, +185, -73, 116, -241, 36, -377, -63, -445, +-173, -437, -294, -371, -408, -265, -481, -115, +-487, 73, -398, 259, -212, 382, 49, 412, +318, 359, 534, 247, 657, 100, 668, -37, +573, -129, 366, -171, 62, -177, -272, -156, +-534, -97, -664, -18, -672, 42, -570, 51, +-375, 25, -112, -2, 149, -18, 355, -33, +490, -50, 541, -56, 501, -45, 370, -16, +190, 30, 13, 88, -138, 131, -253, 129, +-338, 78, -363, 9, -321, -51, -233, -92, +-137, -114, -51, -108, 23, -54, 83, 42, +136, 134, 154, 181, 144, 165, 132, 85, +136, -42, 147, -172, 140, -254, 125, -271, +95, -232, 27, -145, -83, -13, -202, 148, +-277, 285, -291, 355, -255, 339, -193, 256, +-81, 125, 72, -34, 225, -192, 331, -310, +353, -367, 298, -355, 182, -256, 30, -71, +-120, 143, -231, 308, -271, 383, -253, 365, +-191, 266, -108, 95, -14, -111, 68, -300, +104, -429, 85, -456, 28, -379, -24, -216, +-54, -9, -45, 193, 9, 358, 102, 472, +223, 525, 321, 508, 352, 406, 300, 220, +179, -31, -11, -296, -245, -515, -463, -646, +-612, -675, -654, -593, -577, -393, -381, -99, +-92, 218, 225, 476, 505, 616, 681, 614, +729, 486, 646, 277, 450, 49, 185, -148, +-85, -284, -302, -347, -445, -327, -489, -233, +-447, -104, -335, 18, -190, 103, -44, 146, +67, 154, 109, 137, 106, 104, 92, 52, +87, -17, 84, -90, 83, -144, 100, -165, +120, -155, 133, -129, 126, -93, 100, -44, +51, 22, -20, 97, -93, 167, -148, 217, +-168, 235, -173, 218, -173, 169, -151, 87, +-101, -28, -27, -158, 55, -260, 139, -302, +204, -269, 241, -165, 252, -13, 219, 141, +128, 240, -20, 263, -184, 218, -328, 114, +-408, -34, -398, -187, -304, -290, -138, -303, +56, -227, 243, -97, 390, 52, 475, 187, +474, 275, 362, 303, 168, 281, -51, 220, +-230, 122, -352, 1, -414, -122, -415, -214, +-358, -258, -242, -256, -88, -219, 80, -148, +218, -47, 302, 65, 343, 159, 344, 204, +305, 197, 217, 139, 86, 39, -67, -68, +-208, -145, -311, -176, -351, -163, -324, -115, +-260, -27, -170, 92, -50, 204, 97, 271, +228, 278, 282, 233, 261, 138, 189, 1, +105, -154, 42, -286, 5, -367, -19, -381, +-34, -317, -36, -173, -35, 23, -38, 203, +-64, 319, -127, 359, -208, 329, -271, 230, +-263, 80, -177, -76, -21, -189, 161, -239, +308, -227, 402, -163, 441, -71, 411, 19, +281, 86, 64, 128, -178, 148, -370, 149, +-480, 123, -504, 73, -437, -2, -298, -86, +-111, -160, 96, -210, 282, -227, 416, -201, +461, -128, 401, -24, 269, 91, 116, 182, +-27, 235, -147, 241, -240, 203, -298, 140, +-297, 78, -227, 39, -98, 12, 33, -20, +113, -53, 141, -86, 134, -129, 118, -192, +89, -257, 44, -294, -12, -293, -69, -241, +-105, -134, -100, 20, -53, 192, -5, 349, +15, 471, 13, 539, 20, 534, 49, 434, +73, 246, 78, 2, 61, -254, 30, -488, +-2, -647, -26, -692, -39, -617, -63, -436, +-94, -183, -98, 103, -53, 359, 25, 530, +98, 583, 146, 525, 152, 387, 113, 209, +36, 28, -60, -129, -156, -235, -242, -286, +-285, -284, -245, -238, -101, -170, 103, -98, +294, -28, 409, 37, 420, 90, 338, 121, +188, 132, 2, 119, -205, 79, -399, 22, +-510, -31, -483, -68, -322, -83, -94, -79, +131, -63, 305, -28, 401, 20, 419, 69, +359, 96, 231, 92, 47, 64, -155, 23, +-322, -14, -395, -42, -355, -52, -244, -37, +-104, 0, 37, 45, 178, 83, 305, 96, +387, 62, 382, -29, 271, -154, 101, -262, +-67, -316, -199, -295, -296, -196, -351, -21, +-346, 192, -283, 389, -169, 514, -18, 530, +137, 426, 249, 217, 284, -55, 255, -318, +200, -501, 149, -571, 85, -531, -2, -394, +-85, -185, -134, 51, -129, 267, -91, 419, +-46, 488, -26, 470, -34, 377, -42, 232, +-26, 59, 3, -117, 18, -281, 18, -408, +1, -469, -10, -451, -2, -362, 19, -222, +33, -54, 14, 124, -15, 288, -13, 415, +35, 486, 87, 485, 96, 410, 60, 277, +13, 105, -16, -81, -39, -251, -61, -386, +-84, -468, -108, -486, -105, -425, -61, -291, +17, -118, 85, 47, 105, 179, 76, 266, +27, 295, -8, 273, -26, 211, -41, 133, +-70, 61, -87, 12, -63, -1, 8, 29, +95, 84, 141, 120, 134, 119, 93, 84, +42, 16, -10, -89, -63, -226, -112, -366, +-153, -465, -170, -490, -138, -421, -53, -260, +46, -34, 113, 212, 134, 431, 117, 587, +89, 649, 52, 596, -4, 424, -86, 177, +-171, -87, -209, -305, -173, -436, -82, -471, +20, -421, 106, -314, 168, -181, 215, -45, +250, 68, 248, 139, 198, 170, 76, 167, +-79, 149, -206, 131, -270, 116, -286, 79, +-288, 10, -275, -77, -231, -153, -141, -193, +-17, -190, 104, -136, 182, -39, 214, 87, +233, 212, 254, 310, 269, 346, 256, 293, +196, 150, 91, -40, -26, -219, -121, -344, +-194, -393, -258, -364, -314, -265, -347, -120, +-330, 43, -249, 182, -120, 253, 1, 237, +85, 153, 155, 44, 238, -41, 324, -74, +370, -49, 353, 26, 272, 129, 150, 228, +15, 281, -118, 261, -246, 149, -361, -44, +-446, -273, -465, -464, -377, -559, -193, -546, +28, -433, 229, -238, 380, 14, 475, 279, +513, 501, 471, 637, 322, 660, 69, 567, +-220, 378, -463, 135, -606, -121, -635, -359, +-565, -552, -407, -663, -175, -659, 120, -531, +428, -304, 678, -31, 798, 232, 760, 448, +587, 584, 330, 621, 34, 546, -281, 370, +-579, 133, -797, -111, -882, -310, -801, -429, +-570, -455, -247, -403, 91, -297, 391, -164, +631, -23, 783, 100, 810, 177, 691, 184, +450, 136, 143, 76, -159, 40, -392, 37, +-533, 64, -583, 120, -561, 191, -458, 249, +-277, 259, -47, 206, 167, 88, 305, -90, +365, -295, 361, -464, 310, -549, 226, -535, +123, -437, 2, -279, -119, -80, -199, 134, +-207, 330, -150, 480, -76, 568, -10, 587, +38, 547, 76, 456, 109, 310, 127, 111, +113, -137, 57, -407, -22, -647, -90, -796, +-117, -814, -102, -697, -85, -461, -75, -131, +-56, 240, -7, 579, 64, 812, 124, 886, +158, 791, 146, 550, 112, 220, 74, -126, +56, -422, 43, -622, 18, -704, -20, -658, +-54, -494, -65, -249, -70, 11, -77, 225, +-96, 361, -121, 418, -125, 408, -85, 351, +3, 267, 98, 173, 169, 77, 214, -11, +244, -87, 248, -155, 203, -228, 110, -308, +-20, -375, -159, -397, -264, -346, -304, -225, +-274, -55, -212, 128, -128, 291, -27, 407, +94, 460, 221, 433, 319, 330, 357, 186, +318, 39, 231, -80, 123, -153, 20, -182, +-96, -187, -223, -190, -341, -201, -401, -215, +-371, -222, -273, -218, -127, -209, 37, -179, +197, -101, 339, 28, 449, 189, 498, 346, +447, 465, 300, 517, 92, 491, -129, 388, +-315, 217, -441, -9, -496, -261, -476, -485, +-380, -620, -212, -627, 9, -512, 232, -307, +387, -58, 446, 187, 424, 384, 356, 500, +240, 509, 78, 406, -98, 215, -243, -12, +-322, -208, -332, -335, -266, -375, -150, -333, +-18, -220, 89, -56, 158, 134, 194, 302, +197, 396, 148, 385, 48, 272, -59, 99, +-127, -89, -134, -254, -97, -366, -49, -401, +-15, -352, 6, -237, 18, -87, 18, 60, +-4, 167, -44, 217, -81, 221, -85, 214, +-41, 226, 40, 246, 134, 244, 199, 199, +208, 111, 162, -18, 87, -179, -2, -350, +-105, -485, -220, -537, -304, -477, -321, -297, +-266, -33, -159, 245, -36, 463, 74, 575, +146, 570, 189, 463, 210, 280, 207, 59, +160, -161, 85, -335, 10, -428, -47, -434, +-75, -372, -92, -272, -111, -154, -136, -33, +-151, 88, -146, 198, -119, 280, -79, 318, +-42, 307, -6, 255, 34, 190, 76, 127, +104, 54, 107, -37, 80, -133, 27, -213, +-33, -275, -69, -319, -71, -342, -54, -331, +-35, -280, -9, -177, 25, -20, 64, 169, +85, 349, 63, 478, -6, 536, -96, 520, +-164, 432, -195, 272, -177, 56, -132, -179, +-62, -388, 24, -531, 125, -582, 203, -546, +218, -441, 165, -288, 54, -103, -78, 92, +-203, 269, -270, 395, -263, 451, -193, 449, +-80, 401, 58, 325, 204, 227, 307, 102, +323, -53, 243, -214, 92, -345, -79, -423, +-226, -435, -313, -384, -331, -270, -282, -108, +-180, 70, -39, 225, 106, 322, 198, 334, +218, 257, 165, 124, 74, -13, -22, -112, +-93, -155, -115, -142, -98, -82, -46, 15, +19, 121, 100, 202, 163, 230, 176, 200, +120, 118, 6, 4, -115, -118, -214, -228, +-269, -314, -279, -370, -241, -370, -158, -297, +-44, -150, 92, 43, 214, 238, 286, 394, +288, 479, 245, 479, 177, 393, 96, 236, +18, 33, -55, -168, -110, -316, -143, -379, +-146, -356, -128, -268, -113, -153, -110, -42, +-125, 47, -139, 109, -135, 141, -99, 140, +-32, 103, 55, 47, 156, 1, 249, -22, +337, -23, 384, -11, 369, 13, 270, 42, +114, 72, -57, 96, -219, 99, -341, 60, +-410, -22, -405, -122, -331, -202, -197, -230, +-33, -198, 123, -119, 246, -10, 310, 110, +322, 220, 293, 292, 239, 295, 161, 221, +66, 92, -23, -58, -100, -190, -150, -279, +-178, -311, -185, -288, -171, -220, -137, -112, +-73, 27, 11, 170, 107, 277, 190, 315, +238, 289, 241, 218, 204, 116, 147, 0, +59, -110, -39, -196, -135, -241, -190, -231, +-194, -172, -146, -86, -62, -7, 29, 45, +116, 75, 168, 95, 185, 107, 166, 102, +118, 76, 47, 33, -32, -12, -81, -45, +-84, -64, -47, -69, 8, -65, 57, -50, +92, -14, 99, 38, 70, 87, 5, 109, +-74, 91, -143, 49, -175, 3, -155, -29, +-78, -50, 53, -68, 199, -84, 321, -90, +385, -83, 376, -61, 293, -31, 141, 1, +-51, 40, -250, 88, -399, 135, -467, 166, +-434, 165, -329, 110, -175, 7, 3, -111, +180, -203, 333, -244, 426, -223, 454, -151, +417, -39, 337, 103, 218, 241, 78, 332, +-68, 342, -214, 258, -335, 101, -413, -82, +-432, -249, -391, -363, -289, -411, -131, -389, +52, -287, 227, -113, 362, 102, 449, 295, +466, 417, 399, 444, 265, 386, 100, 267, +-54, 114, -181, -46, -274, -182, -328, -267, +-333, -289, -287, -253, -221, -185, -143, -115, +-69, -68, 17, -45, 106, -23, 192, 18, +259, 78, 295, 139, 301, 185, 259, 202, +171, 186, 47, 134, -76, 49, -186, -47, +-269, -130, -313, -167, -303, -138, -236, -52, +-143, 50, -50, 119, 26, 123, 81, 70, +121, -20, 146, -122, 162, -210, 173, -261, +177, -249, 161, -159, 119, -17, 51, 136, +-50, 255, -172, 311, -289, 301, -364, 242, +-372, 161, -307, 69, -169, -25, 10, -110, +198, -175, 338, -211, 407, -217, 379, -207, +264, -191, 83, -168, -129, -119, -309, -38, +-418, 64, -422, 163, -347, 237, -207, 277, +-41, 274, 124, 232, 250, 156, 300, 52, +270, -63, 181, -167, 70, -232, -41, -236, +-135, -188, -192, -118, -205, -50, -181, 3, +-141, 38, -88, 56, -36, 59, -3, 44, +13, 23, 11, 14, 4, 29, -7, 56, +-18, 75, -30, 72, -37, 41, -30, -2, +-21, -37, 3, -49, 34, -38, 75, -12, +94, 22, 96, 56, 89, 77, 59, 75, +5, 40, -84, -27, -182, -105, -269, -172, +-310, -208, -304, -208, -254, -179, -161, -126, +-44, -56, 91, 32, 212, 137, 296, 244, +323, 328, 292, 370, 214, 366, 102, 316, +-1, 210, -85, 59, -148, -119, -200, -296, +-231, -438, -236, -514, -231, -515, -218, -445, +-208, -321, -185, -164, -135, 16, -47, 205, +80, 383, 215, 518, 344, 588, 423, 577, +443, 494, 382, 341, 249, 126, 58, -126, +-169, -373, -371, -568, -503, -667, -527, -644, +-463, -508, -324, -291, -151, -39, 21, 198, +167, 379, 258, 484, 291, 493, 271, 409, +218, 263, 155, 105, 117, -28, 117, -124, +129, -175, 124, -189, 74, -180, -6, -161, +-107, -144, -223, -126, -331, -111, -407, -98, +-407, -76, -322, -28, -160, 55, 50, 160, +261, 249, 431, 294, 511, 280, 501, 215, +400, 113, 237, -12, 25, -144, -192, -252, +-364, -304, -452, -290, -429, -223, -325, -128, +-163, -34, 21, 43, 201, 102, 338, 146, +409, 177, 399, 194, 299, 194, 132, 171, +-60, 123, -221, 50, -317, -45, -329, -156, +-258, -253, -127, -299, 45, -277, 228, -179, +376, -22, 431, 146, 370, 273, 212, 327, +3, 295, -197, 191, -351, 34, -420, -140, +-388, -278, -259, -339, -50, -306, 187, -193, +399, -35, 517, 115, 519, 223, 402, 270, +211, 259, -11, 202, -224, 105, -378, -5, +-452, -98, -425, -147, -309, -152, -120, -128, +90, -88, 274, -47, 391, -15, 427, 9, +404, 22, 332, 28, 222, 22, 73, 6, +-84, -8, -204, -12, -267, -4, -278, 7, +-263, 15, -228, 19, -170, 29, -83, 49, +24, 74, 132, 86, 230, 77, 297, 47, +339, 1, 352, -53, 333, -102, 272, -129, +155, -129, -5, -92, -186, -24, -334, 56, +-425, 116, -438, 128, -385, 81, -279, -10, +-118, -115, 79, -202, 286, -234, 439, -199, +512, -93, 487, 70, 395, 250, 267, 394, +116, 461, -47, 421, -207, 282, -321, 82, +-376, -133, -367, -321, -314, -452, -236, -506, +-145, -481, -54, -381, 44, -230, 148, -57, +251, 110, 324, 254, 338, 367, 309, 441, +253, 465, 187, 429, 97, 331, -25, 179, +-160, 0, -270, -180, -312, -329, -294, -425, +-235, -452, -173, -407, -104, -296, -24, -141, +60, 24, 134, 163, 168, 254, 170, 286, +139, 261, 116, 194, 99, 109, 88, 33, +64, -23, 15, -46, -40, -32, -92, 7, +-122, 44, -143, 50, -166, 16, -187, -54, +-190, -142, -148, -223, -64, -273, 42, -265, +126, -191, 177, -60, 202, 105, 210, 259, +193, 361, 124, 386, 6, 332, -134, 214, +-242, 57, -283, -102, -266, -235, -197, -319, +-108, -341, -8, -301, 79, -207, 155, -89, +196, 29, 173, 137, 89, 222, -34, 274, +-128, 286, -184, 248, -185, 162, -162, 40, +-122, -96, -67, -217, 6, -300, 87, -328, +138, -290, 141, -191, 95, -50, 38, 110, +-12, 257, -47, 353, -69, 370, -96, 318, +-127, 210, -149, 67, -138, -89, -103, -232, +-75, -337, -66, -381, -66, -355, -41, -272, +13, -147, 76, -9, 125, 124, 137, 236, +126, 313, 97, 344, 67, 324, 18, 253, +-50, 142, -135, 12, -218, -111, -258, -212, +-247, -285, -189, -314, -125, -288, -60, -203, +3, -83, 84, 44, 165, 146, 212, 203, +214, 201, 166, 154, 97, 82, 28, 5, +-32, -51, -88, -70, -153, -44, -213, 17, +-249, 79, -235, 109, -175, 91, -103, 27, +-47, -61, -1, -145, 63, -195, 140, -198, +203, -157, 218, -78, 178, 21, 105, 117, +22, 181, -47, 201, -109, 183, -158, 142, +-200, 101, -210, 64, -162, 25, -67, -24, +37, -84, 101, -153, 120, -221, 97, -269, +73, -286, 44, -262, 4, -176, -57, -29, +-116, 155, -134, 336, -95, 471, -11, 522, +74, 470, 134, 327, 161, 114, 165, -138, +153, -382, 108, -569, 24, -654, -95, -606, +-209, -427, -275, -162, -269, 133, -200, 401, +-110, 590, -12, 662, 88, 596, 186, 407, +268, 135, 300, -158, 270, -402, 173, -548, +57, -569, -40, -478, -89, -310, -112, -102, +-138, 110, -153, 290, -139, 404, -76, 438, +-5, 394, 54, 295, 73, 170, 68, 41, +63, -87, 75, -203, 88, -292, 77, -341, +47, -342, 3, -297, -23, -210, -26, -105, +-9, 5, 12, 114, 17, 215, 20, 289, +38, 320, 81, 298, 120, 234, 117, 149, +65, 59, -3, -29, -44, -113, -62, -178, +-67, -220, -71, -230, -70, -208, -32, -164, +35, -112, 117, -54, 159, 6, 151, 66, +108, 117, 53, 149, 15, 151, -9, 119, +-21, 73, -39, 28, -41, -8, -21, -31, +37, -41, 103, -34, 137, -11, 122, 19, +69, 43, 17, 45, -29, 22, -71, -14, +-120, -46, -166, -55, -178, -49, -124, -41, +2, -38, 147, -44, 271, -62, 346, -83, +373, -96, 358, -91, 285, -54, 142, 21, +-64, 123, -276, 225, -435, 298, -509, 308, +-480, 238, -373, 101, -207, -62, -9, -211, +210, -310, 419, -342, 572, -303, 626, -201, +549, -66, 386, 62, 177, 147, -22, 179, +-211, 168, -374, 137, -492, 103, -526, 82, +-451, 71, -292, 58, -94, 31, 78, -10, +208, -59, 292, -118, 338, -174, 340, -215, +287, -215, 190, -162, 70, -65, -24, 57, +-67, 172, -68, 256, -52, 297, -53, 291, +-68, 236, -88, 144, -106, 19, -124, -123, +-154, -252, -184, -342, -190, -377, -130, -356, +-12, -283, 129, -165, 244, -9, 303, 165, +319, 319, 293, 418, 230, 444, 120, 392, +-15, 276, -162, 118, -276, -53, -332, -211, +-322, -329, -275, -390, -220, -379, -153, -298, +-71, -173, 43, -41, 162, 71, 256, 157, +297, 213, 283, 234, 237, 215, 165, 167, +67, 106, -59, 44, -201, -9, -310, -51, +-352, -87, -312, -123, -217, -151, -101, -159, +17, -138, 115, -89, 193, -22, 237, 51, +231, 120, 162, 181, 50, 219, -65, 218, +-150, 171, -200, 84, -232, -30, -233, -154, +-209, -260, -146, -324, -58, -343, 54, -310, +152, -216, 206, -64, 222, 121, 210, 300, +175, 434, 101, 490, 0, 460, -116, 348, +-216, 173, -284, -36, -305, -238, -273, -396, +-211, -471, -143, -452, -75, -352, -8, -207, +62, -57, 118, 69, 144, 155, 149, 201, +151, 203, 165, 176, 176, 137, 170, 109, +127, 101, 50, 114, -54, 134, -166, 140, +-274, 117, -364, 59, -411, -25, -409, -126, +-344, -232, -227, -325, -59, -381, 113, -377, +256, -296, 342, -149, 381, 28, 380, 198, +330, 337, 233, 426, 93, 448, -49, 395, +-181, 276, -282, 120, -341, -42, -357, -176, +-336, -268, -287, -311, -207, -309, -98, -280, +21, -229, 118, -153, 173, -60, 200, 29, +221, 108, 234, 171, 229, 219, 194, 243, +135, 240, 55, 201, -33, 128, -125, 33, +-214, -63, -288, -134, -336, -170, -337, -178, +-277, -164, -150, -128, 5, -72, 158, -9, +257, 43, 315, 76, 322, 86, 275, 76, +175, 54, 35, 30, -93, 6, -182, -16, +-208, -30, -182, -31, -122, -14, -57, 11, +-4, 29, 35, 28, 56, 14, 57, -7, +37, -30, 8, -39, -7, -29, 1, 0, +33, 47, 68, 102, 82, 146, 65, 153, +15, 105, -39, 9, -80, -119, -98, -246, +-97, -339, -66, -367, 1, -319, 96, -193, +183, 0, 224, 219, 209, 418, 128, 545, +28, 566, -77, 470, -156, 282, -204, 38, +-205, -221, -150, -437, -57, -565, 56, -586, +152, -500, 222, -324, 237, -94, 195, 142, +118, 328, 37, 436, -31, 453, -87, 385, +-119, 250, -116, 76, -78, -97, -8, -229, +64, -291, 107, -277, 115, -198, 87, -82, +43, 49, -8, 160, -51, 217, -80, 206, +-85, 135, -57, 26, 16, -95, 113, -193, +206, -238, 260, -213, 256, -132, 211, -20, +121, 92, 19, 178, -104, 213, -219, 196, +-302, 133, -325, 47, -274, -38, -169, -102, +-26, -128, 116, -114, 235, -77, 316, -38, +355, -2, 344, 23, 283, 34, 181, 32, +63, 28, -37, 27, -101, 30, -139, 32, +-160, 27, -170, 16, -174, -8, -159, -39, +-129, -69, -82, -84, -28, -81, 22, -50, +74, -4, 136, 38, 193, 71, 230, 88, +227, 81, 191, 51, 137, 11, 81, -27, +47, -42, 8, -27, -30, 9, -81, 52, +-119, 83, -142, 86, -156, 56, -165, -6, +-171, -87, -148, -172, -100, -235, -10, -246, +100, -197, 199, -100, 259, 22, 274, 150, +252, 253, 203, 306, 118, 302, 9, 241, +-101, 139, -184, 21, -215, -89, -198, -171, +-142, -213, -74, -210, -17, -172, 21, -112, +43, -48, 50, 4, 43, 41, 17, 57, +-8, 51, -16, 24, 3, -9, 50, -33, +94, -41, 121, -27, 105, 1, 69, 47, +9, 107, -50, 165, -111, 200, -167, 198, +-194, 152, -191, 64, -137, -49, -54, -167, +36, -267, 111, -329, 156, -331, 173, -264, +172, -144, 145, 6, 85, 157, -11, 271, +-113, 319, -185, 295, -221, 211, -208, 90, +-168, -40, -116, -149, -52, -213, 26, -212, +107, -152, 160, -52, 157, 56, 107, 144, +37, 189, -17, 188, -52, 141, -78, 63, +-107, -33, -136, -136, -133, -216, -112, -255, +-67, -244, -39, -195, -18, -117, 10, -18, +52, 91, 106, 195, 138, 274, 139, 312, +96, 297, 10, 230, -96, 124, -188, -2, +-259, -122, -288, -213, -282, -263, -217, -268, +-90, -229, 72, -154, 228, -61, 326, 17, +345, 67, 277, 88, 151, 95, 2, 95, +-151, 95, -292, 94, -386, 92, -398, 90, +-316, 84, -165, 65, 9, 35, 144, -9, +218, -64, 233, -109, 198, -129, 140, -127, +37, -116, -79, -96, -194, -69, -254, -41, +-227, -14, -141, 19, -34, 64, 54, 115, +123, 161, 179, 200, 219, 220, 211, 196, +137, 118, -12, -8, -179, -155, -310, -287, +-375, -368, -381, -372, -346, -290, -263, -139, +-118, 48, 89, 239, 297, 388, 452, 454, +505, 409, 455, 276, 339, 90, 182, -102, +2, -261, -193, -360, -386, -384, -513, -333, +-548, -222, -478, -77, -322, 73, -143, 189, +45, 251, 205, 258, 346, 224, 439, 159, +450, 70, 365, -25, 201, -110, 14, -168, +-143, -178, -242, -133, -287, -52, -279, 40, +-232, 117, -135, 166, -9, 178, 114, 136, +177, 35, 171, -101, 108, -233, 20, -319, +-55, -332, -111, -265, -125, -130, -111, 43, +-61, 219, 26, 359, 138, 435, 246, 427, +294, 337, 250, 181, 142, -5, 0, -180, +-124, -311, -220, -378, -295, -384, -323, -340, +-288, -255, -159, -134, 18, 0, 197, 118, +323, 202, 375, 256, 358, 279, 288, 274, +175, 237, 32, 164, -122, 63, -264, -50, +-344, -145, -333, -208, -229, -231, -87, -216, +62, -159, 186, -74, 292, 17, 355, 89, +342, 128, 255, 124, 98, 76, -64, -2, +-198, -75, -279, -106, -283, -92, -228, -42, +-132, 34, -12, 116, 112, 176, 238, 194, +316, 156, 330, 63, 279, -60, 179, -172, +82, -234, -11, -231, -90, -164, -164, -56, +-215, 70, -230, 175, -196, 227, -129, 209, +-45, 128, 35, 6, 90, -125, 126, -228, +164, -273, 205, -246, 226, -162, 218, -37, +174, 100, 145, 222, 123, 305, 96, 345, +50, 335, -30, 270, -110, 159, -193, 20, +-253, -125, -274, -270, -266, -402, -229, -500, +-163, -533, -58, -481, 95, -338, 250, -118, +381, 150, 456, 416, 467, 635, 427, 760, +335, 757, 195, 622, 3, 369, -204, 42, +-390, -297, -501, -585, -526, -767, -462, -809, +-326, -713, -147, -511, 58, -241, 276, 59, +464, 344, 577, 561, 578, 671, 458, 670, +277, 571, 55, 394, -157, 164, -349, -86, +-488, -317, -526, -494, -462, -588, -294, -580, +-71, -469, 150, -281, 323, -57, 417, 168, +433, 359, 387, 481, 282, 517, 139, 471, +-21, 349, -159, 171, -249, -20, -284, -190, +-277, -317, -253, -401, -218, -442, -185, -427, +-121, -356, -30, -235, 86, -77, 195, 96, +269, 263, 318, 400, 348, 494, 347, 525, +296, 470, 167, 325, -20, 118, -198, -102, +-340, -299, -412, -440, -452, -502, -446, -480, +-375, -392, -240, -261, -48, -107, 148, 47, +304, 171, 393, 245, 416, 278, 393, 292, +335, 296, 229, 287, 69, 258, -118, 196, +-276, 94, -377, -36, -413, -171, -406, -295, +-348, -395, -236, -443, -86, -408, 98, -278, +253, -77, 355, 141, 380, 325, 324, 440, +205, 465, 45, 396, -125, 247, -270, 48, +-385, -161, -427, -337, -378, -434, -257, -435, +-79, -350, 81, -201, 213, -16, 292, 167, +320, 317, 296, 418, 219, 460, 103, 426, +-36, 310, -171, 137, -275, -58, -312, -241, +-297, -396, -261, -505, -217, -545, -156, -499, +-69, -370, 37, -175, 113, 51, 162, 270, +180, 445, 186, 559, 197, 601, 173, 555, +126, 419, 37, 216, -76, -18, -187, -241, +-281, -420, -339, -532, -348, -561, -318, -507, +-232, -384, -99, -212, 66, -17, 225, 172, +314, 316, 340, 394, 299, 404, 225, 362, +116, 280, -12, 179, -146, 69, -260, -42, +-327, -144, -344, -219, -302, -258, -237, -270, +-170, -262, -96, -227, -11, -156, 98, -60, +215, 42, 293, 140, 339, 224, 342, 279, +324, 296, 268, 273, 137, 213, -45, 118, +-264, 0, -459, -125, -597, -244, -661, -337, +-626, -386, -478, -374, -237, -301, 74, -180, +385, -22, 645, 157, 799, 327, 809, 443, +680, 485, 426, 448, 104, 343, -245, 184, +-540, -2, -745, -178, -806, -320, -729, -410, +-545, -439, -272, -409, 29, -332, 316, -223, +529, -93, 628, 53, 618, 196, 508, 319, +322, 410, 104, 454, -135, 429, -323, 321, +-435, 146, -460, -61, -399, -265, -290, -430, +-143, -515, 14, -490, 160, -354, 272, -132, +330, 124, 324, 355, 278, 501, 203, 526, +118, 437, 19, 254, -77, 10, -153, -242, +-195, -439, -207, -539, -204, -531, -177, -425, +-147, -248, -93, -28, -41, 182, 17, 349, +83, 464, 139, 526, 207, 520, 275, 441, +326, 304, 355, 129, 338, -62, 271, -252, +154, -423, -21, -557, -203, -636, -385, -635, +-524, -532, -592, -339, -578, -90, -459, 178, +-251, 437, 27, 654, 330, 787, 606, 809, +798, 703, 880, 479, 825, 169, 639, -173, +340, -495, -26, -743, -400, -879, -702, -880, +-887, -734, -918, -458, -787, -97, -532, 282, +-170, 614, 203, 831, 541, 896, 785, 808, +891, 590, 866, 270, 704, -106, 435, -465, +115, -725, -207, -838, -469, -802, -646, -633, +-729, -366, -680, -44, -518, 278, -261, 551, +24, 727, 293, 776, 512, 694, 655, 509, +701, 261, 636, -17, 470, -295, 220, -533, +-53, -696, -300, -769, -476, -731, -568, -575, +-576, -322, -500, -13, -325, 302, -87, 580, +184, 788, 410, 881, 547, 817, 609, 598, +568, 268, 451, -107, 250, -457, 4, -713, +-233, -841, -416, -825, -506, -667, -500, -383, +-414, -39, -253, 283, -54, 521, 143, 643, +316, 646, 424, 541, 462, 361, 412, 145, +294, -70, 134, -257, -22, -389, -164, -445, +-264, -431, -306, -361, -302, -249, -243, -106, +-156, 50, -43, 208, 73, 345, 150, 434, +182, 448, 189, 373, 178, 224, 177, 38, +138, -161, 65, -350, -16, -490, -86, -535, +-106, -459, -121, -286, -134, -53, -138, 187, +-117, 394, -62, 526, 1, 557, 40, 478, +54, 302, 49, 62, 44, -186, 53, -384, +70, -503, 86, -525, 89, -445, 85, -283, +72, -81, 56, 115, -2, 277, -94, 392, +-199, 438, -280, 401, -298, 295, -271, 160, +-189, 25, -60, -100, 92, -206, 242, -283, +349, -323, 388, -324, 363, -286, 248, -222, +85, -142, -110, -43, -291, 73, -407, 198, +-459, 316, -428, 408, -335, 461, -184, 460, +-3, 379, 177, 218, 310, 2, 377, -237, +364, -472, 280, -666, 152, -769, 9, -742, +-128, -575, -243, -293, -317, 63, -330, 436, +-264, 761, -161, 978, -38, 1048, 58, 940, +131, 656, 172, 244, 146, -224, 78, -678, +-19, -1045, -124, -1259, -196, -1273, -217, -1073, +-165, -687, -51, -163, 70, 423, 187, 970, +262, 1373, 285, 1555, 234, 1475, 99, 1135, +-82, 580, -270, -97, -415, -772, -494, -1335, +-471, -1674, -362, -1712, -179, -1437, 34, -907, +241, -225, 411, 483, 510, 1100, 516, 1518, +420, 1661, 227, 1514, -15, 1113, -249, 541, +-458, -97, -592, -687, -648, -1141, -575, -1396, +-389, -1423, -140, -1225, 140, -839, 390, -333, +580, 210, 673, 711, 632, 1094, 477, 1292, +243, 1283, -43, 1082, -325, 715, -566, 220, +-711, -325, -750, -820, -671, -1178, -493, -1341, +-245, -1289, 37, -1032, 316, -605, 566, -69, +729, 496, 797, 995, 740, 1336, 569, 1459, +311, 1346, 1, 1022, -320, 532, -617, -56, +-861, -656, -980, -1170, -942, -1513, -748, -1629, +-424, -1484, -50, -1091, 352, -509, 713, 164, +971, 826, 1079, 1388, 1003, 1757, 763, 1851, +401, 1635, -27, 1137, -435, 441, -758, -338, +-962, -1074, -1024, -1647, -947, -1970, -723, -1980, +-391, -1665, -1, -1061, 370, -269, 684, 567, +900, 1308, 999, 1846, 965, 2093, 779, 2002, +479, 1581, 82, 892, -339, 48, -714, -815, +-979, -1548, -1082, -2023, -1020, -2159, -814, -1936, +-463, -1385, -18, -601, 458, 284, 868, 1118, +1109, 1759, 1176, 2096, 1061, 2063, 802, 1677, +416, 1028, -54, 235, -521, -577, -895, -1284, +-1117, -1760, -1159, -1923, -1022, -1769, -730, -1351, +-331, -747, 113, -59, 553, 615, 921, 1181, +1148, 1559, 1185, 1700, 1051, 1589, 762, 1250, +378, 738, -69, 126, -521, -512, -884, -1089, +-1117, -1512, -1163, -1718, -1023, -1672, -721, -1365, +-293, -825, 185, -130, 630, 605, 983, 1258, +1178, 1723, 1198, 1920, 1028, 1800, 684, 1367, +233, 690, -258, -121, -685, -925, -996, -1573, +-1148, -1955, -1122, -2017, -910, -1744, -543, -1172, +-66, -390, 437, 459, 863, 1225, 1140, 1786, +1228, 2053, 1133, 1982, 868, 1579, 448, 918, +-67, 106, -564, -723, -955, -1435, -1159, -1909, +-1175, -2068, -1007, -1892, -670, -1412, -229, -703, +265, 119, 718, 913, 1051, 1556, 1210, 1952, +1166, 2042, 942, 1799, 590, 1261, 150, 523, +-310, -295, -731, -1068, -1027, -1676, -1140, -2012, +-1063, -2011, -821, -1671, -466, -1052, -41, -257, +390, 577, 772, 1310, 1020, 1815, 1111, 2004, +1028, 1843, 782, 1365, 427, 661, 17, -135, +-383, -886, -711, -1483, -927, -1816, -996, -1819, +-907, -1504, -680, -953, -338, -268, 26, 445, +378, 1075, 665, 1515, 851, 1692, 924, 1585, +852, 1224, 657, 668, 368, 8, 31, -646, +-302, -1200, -583, -1558, -786, -1658, -872, -1476, +-829, -1045, -653, -429, -374, 280, -34, 956, +309, 1467, 592, 1710, 767, 1650, 818, 1300, +761, 713, 575, -15, 299, -747, -29, -1337, +-330, -1667, -543, -1681, -663, -1390, -679, -857, +-593, -177, -420, 530, -180, 1135, 71, 1529, +290, 1633, 458, 1440, 526, 1001, 497, 394, +377, -287, 210, -920, 29, -1391, -151, -1616, +-298, -1556, -382, -1213, -382, -636, -307, 72, +-186, 774, -59, 1337, 55, 1658, 140, 1678, +197, 1389, 215, 839, 194, 131, 135, -604, +67, -1224, 6, -1605, -31, -1676, -47, -1442, +-70, -970, -90, -345, -129, 334, -169, 937, +-199, 1345, -219, 1490, -217, 1371, -186, 1038, +-112, 555, 21, 5, 182, -518, 337, -935, +457, -1179, 497, -1216, 447, -1045, 296, -712, +82, -280, -169, 189, -427, 616, -648, 918, +-768, 1044, -757, 983, -618, 748, -376, 369, +-77, -85, 248, -513, 544, -818, 770, -942, +885, -879, 866, -646, 698, -279, 415, 151, +52, 546, -319, 823, -652, 925, -905, 833, +-1025, 570, -1007, 194, -826, -222, -513, -607, +-121, -889, 286, -1004, 637, -923, 889, -665, +1029, -276, 1022, 182, 862, 632, 560, 980, +160, 1159, -259, 1138, -650, 909, -948, 496, +-1117, -40, -1122, -597, -968, -1061, -661, -1344, +-245, -1392, 226, -1192, 667, -767, 991, -181, +1164, 468, 1159, 1056, 978, 1475, 628, 1634, +156, 1498, -359, 1084, -816, 466, -1154, -261, +-1297, -969, -1223, -1526, -940, -1820, -495, -1783, +25, -1422, 556, -799, 999, -17, 1267, 789, +1300, 1474, 1094, 1906, 697, 2002, 191, 1743, +-353, 1173, -835, 387, -1178, -487, -1317, -1290, +-1222, -1866, -919, -2111, -455, -1991, 84, -1535, +606, -807, 1014, 78, 1256, 957, 1281, 1667, +1100, 2084, 729, 2145, 221, 1849, -325, 1240, +-816, 418, -1161, -484, -1311, -1311, -1253, -1922, +-995, -2212, -579, -2133, -65, -1699, 483, -971, +944, -54, 1250, 896, 1353, 1702, 1237, 2227, +920, 2380, 434, 2128, -122, 1494, -664, 573, +-1118, -467, -1399, -1435, -1421, -2158, -1177, -2508, +-720, -2419, -156, -1892, 440, -1020, 986, 35, +1373, 1090, 1503, 1951, 1348, 2459, 950, 2526, +373, 2150, -272, 1401, -877, 401, -1304, -668, +-1492, -1607, -1417, -2251, -1073, -2503, -508, -2319, +185, -1726, 843, -826, 1322, 217, 1550, 1215, +1491, 1996, 1151, 2421, 601, 2415, -74, 1977, +-732, 1188, -1264, 183, -1566, -856, -1561, -1734, +-1253, -2289, -709, -2428, -46, -2134, 628, -1453, +1209, -513, 1601, 515, 1700, 1433, 1479, 2072, +982, 2327, 313, 2166, -411, 1625, -1068, 805, +-1539, -137, -1730, -1030, -1613, -1717, -1211, -2086, +-594, -2086, 121, -1730, 825, -1091, 1368, -284, +1667, 548, 1685, 1259, 1434, 1740, 970, 1923, +358, 1782, -308, 1340, -916, 673, -1365, -85, +-1590, -801, -1562, -1367, -1297, -1700, -824, -1740, +-227, -1471, 405, -948, 974, -272, 1396, 433, +1596, 1044, 1536, 1457, 1228, 1603, 736, 1455, +156, 1047, -434, 465, -947, -174, -1316, -757, +-1467, -1185, -1367, -1386, -1037, -1323, -561, -1016, +-24, -541, 485, -1, 904, 509, 1165, 912, +1223, 1145, 1094, 1159, 792, 949, 392, 579, +-33, 136, -394, -306, -637, -679, -766, -920, +-795, -987, -714, -872, -537, -600, -308, -225, +-80, 167, 112, 498, 282, 727, 422, 825, +532, 764, 583, 554, 565, 251, 481, -75, +353, -368, 186, -587, -10, -690, -218, -651, +-421, -486, -582, -242, -684, 28, -691, 269, +-580, 448, -369, 541, -97, 529, 202, 411, +490, 219, 742, 8, 892, -174, 895, -304, +743, -377, 452, -376, 88, -295, -300, -155, +-649, -4, -908, 105, -1028, 156, -988, 161, +-790, 128, -472, 62, -70, -14, 354, -64, +738, -58, 1034, 10, 1188, 120, 1173, 232, +970, 303, 603, 306, 102, 226, -460, 54, +-995, -192, -1387, -448, -1561, -641, -1494, -726, +-1175, -676, -630, -477, 93, -135, 860, 294, +1504, 715, 1895, 1035, 1964, 1183, 1684, 1120, +1091, 837, 260, 358, -651, -249, -1480, -872, +-2077, -1374, -2315, -1646, -2140, -1630, -1565, -1315, +-700, -728, 291, 43, 1230, 865, 1978, 1578, +2406, 2044, 2429, 2169, 2008, 1911, 1219, 1295, +235, 401, -771, -620, -1661, -1580, -2316, -2301, +-2607, -2659, -2461, -2573, -1881, -2021, -973, -1061, +120, 141, 1204, 1367, 2086, 2398, 2614, 3046, +2700, 3179, 2327, 2740, 1539, 1767, 465, 418, +-693, -1047, -1730, -2345, -2472, -3239, -2775, -3572, +-2589, -3257, -1934, -2312, -948, -912, 190, 661, +1287, 2121, 2150, 3213, 2628, 3726, 2634, 3540, +2160, 2682, 1281, 1327, 170, -265, -975, -1811, +-1934, -3043, -2542, -3728, -2691, -3719, -2343, -3022, +-1549, -1775, -448, -197, 735, 1433, 1768, 2822, +2460, 3715, 2697, 3946, 2423, 3469, 1698, 2350, +640, 771, -546, -977, -1644, -2577, -2444, -3748, +-2756, -4266, -2526, -4009, -1831, -3000, -820, -1423, +338, 449, 1454, 2288, 2310, 3754, 2696, 4543, +2541, 4485, 1893, 3598, 899, 2046, -255, 93, +-1354, -1920, -2192, -3609, -2605, -4636, -2509, -4797, +-1921, -4070, -957, -2598, 177, -641, 1278, 1469, +2130, 3340, 2570, 4592, 2498, 4977, 1934, 4449, +991, 3114, -158, 1194, -1307, -985, -2227, -3020, +-2718, -4495, -2685, -5118, -2119, -4793, -1136, -3598, +91, -1735, 1317, 487, 2314, 2662, 2896, 4336, +2938, 5172, 2417, 5042, 1429, 4009, 149, 2254, +-1194, 64, -2344, -2161, -3075, -3971, -3231, -5001, +-2794, -5093, -1836, -4283, -513, -2732, 949, -689, +2266, 1484, 3174, 3352, 3485, 4541, 3148, 4877, +2226, 4365, 873, 3102, -665, 1274, -2121, -783, +-3202, -2646, -3679, -3961, -3443, -4518, -2555, -4252, +-1192, -3221, 390, -1608, 1921, 284, 3115, 2086, +3745, 3440, 3695, 4091, 2952, 3950, 1646, 3085, +9, 1663, -1632, -63, -2965, -1750, -3751, -3039, +-3865, -3674, -3271, -3589, -2067, -2854, -472, -1598, +1208, -33, 2657, 1521, 3619, 2713, 3917, 3326, +3508, 3314, 2467, 2710, 984, 1593, -669, 148, +-2176, -1308, -3266, -2453, -3750, -3090, -3564, -3145, +-2746, -2616, -1438, -1580, 111, -227, 1630, 1160, +2843, 2277, 3537, 2907, 3578, 2961, 2960, 2444, +1796, 1431, 329, 108, -1171, -1219, -2426, -2238, +-3205, -2750, -3379, -2693, -2912, -2090, -1921, -1043, +-604, 236, 798, 1441, 2047, 2289, 2894, 2614, +3165, 2382, 2815, 1662, 1966, 597, 814, -606, +-449, -1674, -1620, -2359, -2487, -2533, -2860, -2192, +-2681, -1420, -2011, -363, -998, 777, 174, 1761, +1292, 2381, 2162, 2524, 2618, 2188, 2579, 1447, +2058, 424, 1161, -703, 77, -1704, -977, -2354, +-1801, -2539, -2265, -2259, -2304, -1569, -1928, -572, +-1189, 554, -244, 1565, 722, 2247, 1503, 2482, +1961, 2247, 2034, 1587, 1716, 621, 1086, -468, +275, -1451, -546, -2114, -1228, -2332, -1639, -2099, +-1709, -1471, -1430, -553, -880, 483, -177, 1399, +534, 1988, 1106, 2158, 1428, 1924, 1453, 1344, +1197, 498, 706, -464, 83, -1324, -534, -1879, +-1006, -2040, -1265, -1836, -1273, -1320, -1023, -541, +-569, 377, -11, 1227, 537, 1810, 984, 2034, +1252, 1884, 1257, 1374, 979, 577, 498, -357, +-70, -1226, -605, -1831, -1037, -2036, -1285, -1824, +-1278, -1267, -997, -462, -491, 460, 115, 1290, +703, 1799, 1169, 1876, 1426, 1575, 1396, 997, +1083, 234, 559, -581, -62, -1255, -677, -1609, +-1189, -1584, -1493, -1237, -1514, -680, -1258, -23, +-788, 619, -182, 1109, 463, 1326, 1038, 1241, +1424, 913, 1554, 427, 1407, -129, 1018, -642, +482, -992, -101, -1095, -653, -940, -1103, -586, +-1368, -125, -1382, 349, -1168, 748, -802, 976, +-328, 956, 187, 687, 656, 252, 973, -243, +1107, -701, 1083, -1022, 925, -1111, 638, -926, +254, -512, -140, 38, -479, 619, -730, 1104, +-892, 1374, -938, 1350, -849, 1030, -625, 477, +-314, -199, 29, -871, 360, -1408, 646, -1688, +850, -1640, 917, -1260, 824, -612, 581, 181, +249, 962, -123, 1585, -482, 1926, -762, 1915, +-900, 1526, -875, 810, -706, -91, -447, -993, +-135, -1724, 202, -2136, 522, -2115, 770, -1648, +887, -842, 869, 133, 716, 1095, 438, 1848, +47, 2210, -388, 2091, -782, 1532, -1060, 666, +-1169, -325, -1070, -1243, -742, -1889, -249, -2128, +320, -1914, 860, -1301, 1269, -426, 1442, 522, +1325, 1353, 924, 1909, 326, 2058, -358, 1758, +-981, 1094, -1422, 220, -1611, -699, -1511, -1502, +-1132, -2020, -516, -2108, 213, -1720, 911, -951, +1453, 12, 1743, 972, 1706, 1764, 1329, 2223, +691, 2206, -67, 1680, -813, 782, -1429, -269, +-1809, -1279, -1877, -2060, -1590, -2428, -999, -2262, +-226, -1601, 572, -614, 1275, 492, 1781, 1515, +1987, 2251, 1818, 2535, 1293, 2299, 549, 1591, +-277, 570, -1070, -565, -1710, -1605, -2051, -2356, +-2011, -2663, -1599, -2456, -905, -1769, -39, -720, +849, 502, 1583, 1658, 2015, 2511, 2051, 2893, +1710, 2724, 1075, 2024, 274, 901, -568, -443, +-1333, -1739, -1877, -2711, -2053, -3149, -1818, -2960, +-1256, -2182, -489, -954, 370, 485, 1186, 1835, +1775, 2804, 1993, 3204, 1812, 2970, 1300, 2146, +545, 888, -324, -541, -1147, -1830, -1725, -2719, +-1916, -3049, -1700, -2769, -1163, -1941, -438, -737, +362, 605, 1101, 1802, 1611, 2588, 1743, 2820, +1498, 2492, 985, 1681, 337, 525, -368, -748, +-1021, -1845, -1470, -2530, -1609, -2697, -1419, -2324, +-961, -1461, -313, -268, 402, 994, 1031, 2044, +1438, 2662, 1566, 2732, 1405, 2252, 975, 1309, +339, 59, -368, -1255, -982, -2328, -1379, -2906, +-1502, -2882, -1335, -2284, -896, -1219, -279, 133, +374, 1501, 914, 2572, 1265, 3101, 1358, 2988, +1155, 2274, 700, 1091, 118, -335, -450, -1717, +-892, -2741, -1124, -3180, -1098, -2961, -811, -2144, +-342, -883, 207, 584, 703, 1936, 1036, 2868, +1113, 3192, 917, 2856, 518, 1935, 5, 613, +-518, -844, -936, -2134, -1155, -2987, -1147, -3219, +-915, -2785, -483, -1774, 96, -385, 696, 1099, +1176, 2351, 1442, 3103, 1454, 3230, 1194, 2727, +684, 1671, 6, 240, -724, -1260, -1354, -2474, +-1743, -3151, -1778, -3202, -1468, -2647, -881, -1561, +-104, -114, 742, 1371, 1485, 2519, 1941, 3100, +2010, 3085, 1697, 2499, 1066, 1390, 222, -53, +-667, -1470, -1417, -2513, -1882, -3010, -2006, -2927, +-1767, -2287, -1187, -1164, -358, 239, 548, 1596, +1337, 2566, 1853, 2954, 2005, 2757, 1796, 2061, +1261, 953, 487, -404, -387, -1696, -1174, -2578, +-1722, -2886, -1949, -2649, -1829, -1939, -1356, -833, +-614, 478, 247, 1674, 1067, 2466, 1694, 2748, +2020, 2537, 1956, 1881, 1513, 852, 773, -360, +-120, -1468, -996, -2233, -1678, -2551, -2035, -2414, +-2010, -1846, -1598, -922, -848, 181, 89, 1226, +986, 2002, 1660, 2373, 2005, 2286, 1980, 1770, +1551, 926, 798, -100, -90, -1107, -901, -1872, +-1522, -2241, -1893, -2162, -1912, -1666, -1512, -828, +-766, 185, 109, 1135, 903, 1811, 1512, 2111, +1866, 2006, 1862, 1509, 1444, 697, 697, -236, +-149, -1071, -901, -1665, -1464, -1947, -1771, -1864, +-1738, -1402, -1317, -678, -620, 111, 148, 821, +826, 1391, 1336, 1731, 1603, 1727, 1548, 1367, +1157, 790, 538, 144, -129, -500, -728, -1074, +-1206, -1460, -1492, -1554, -1462, -1351, -1085, -921, +-467, -372, 200, 202, 802, 730, 1266, 1132, +1496, 1319, 1395, 1248, 957, 971, 334, 584, +-312, 132, -875, -347, -1296, -776, -1493, -1051, +-1385, -1118, -973, -1008, -384, -778, 229, -453, +754, -48, 1159, 383, 1399, 751, 1371, 978, +1055, 1046, 549, 976, 4, 768, -518, 424, +-994, -13, -1329, -457, -1382, -840, -1132, -1093, +-696, -1160, -199, -1017, 317, -700, 797, -256, +1127, 267, 1201, 777, 1019, 1147, 685, 1281, +272, 1172, -172, 854, -622, 359, -965, -244, +-1082, -827, -958, -1239, -681, -1383, -350, -1253, +33, -887, 455, -333, 806, 334, 951, 979, +874, 1437, 666, 1580, 388, 1381, 32, 902, +-363, 237, -685, -518, -829, -1237, -793, -1738, +-659, -1855, -472, -1555, -216, -934, 106, -125, +402, 760, 569, 1559, 601, 2061, 586, 2101, +554, 1670, 434, 896, 188, -57, -82, -1029, +-273, -1839, -403, -2273, -538, -2189, -653, -1610, +-647, -706, -509, 323, -299, 1305, -83, 2055, +141, 2362, 380, 2112, 594, 1378, 720, 361, +708, -722, 569, -1668, 349, -2279, 85, -2394, +-216, -1955, -508, -1063, -702, 61, -723, 1173, +-614, 2062, -450, 2539, -250, 2456, -1, 1792, +259, 711, 440, -519, 505, -1652, 491, -2474, +441, -2784, 350, -2460, 213, -1563, 58, -314, +-88, 1003, -226, 2122, -362, 2806, -481, 2876, +-538, 2277, -519, 1146, -427, -239, -257, -1569, +-12, -2572, 279, -3023, 537, -2777, 722, -1862, +807, -512, 772, 942, 590, 2195, 262, 3004, +-152, 3157, -570, 2559, -915, 1340, -1126, -179, +-1136, -1659, -913, -2817, -497, -3401, 15, -3230, +531, -2305, 968, -863, 1271, 754, 1359, 2227, +1176, 3277, 747, 3651, 182, 3219, -395, 2079, +-908, 510, -1273, -1169, -1399, -2626, -1260, -3547, +-919, -3706, -439, -3069, 141, -1787, 739, -146, +1197, 1516, 1418, 2858, 1415, 3588, 1209, 3533, +774, 2714, 129, 1354, -549, -242, -1092, -1776, +-1445, -2948, -1612, -3459, -1518, -3178, -1094, -2228, +-428, -890, 298, 585, 964, 1957, 1520, 2915, +1867, 3198, 1860, 2765, 1443, 1793, 738, 518, +-63, -845, -821, -2053, -1479, -2814, -1932, -2920, +-2017, -2379, -1648, -1376, -927, -141, -79, 1099, +754, 2104, 1485, 2630, 1979, 2550, 2058, 1909, +1680, 883, 986, -286, 153, -1338, -701, -2062, +-1453, -2333, -1939, -2097, -2017, -1380, -1672, -360, +-992, 662, -104, 1433, 803, 1866, 1567, 1940, +2049, 1600, 2149, 878, 1796, 1, 1032, -754, +46, -1258, -934, -1507, -1752, -1487, -2283, -1163, +-2378, -591, -1941, 36, -1054, 522, 48, 823, +1156, 979, 2097, 991, 2679, 827, 2699, 533, +2119, 233, 1106, 6, -115, -185, -1352, -387, +-2412, -554, -3025, -634, -2978, -658, -2267, -679, +-1074, -649, 345, -469, 1738, -138, 2828, 238, +3341, 605, 3151, 977, 2280, 1272, 899, 1297, +-712, 972, -2208, 425, -3232, -219, -3558, -933, +-3109, -1598, -1978, -1920, -381, -1727, 1336, -1127, +2777, -292, 3613, 700, 3670, 1687, 2931, 2325, +1521, 2348, -258, 1796, -1988, 854, -3270, -339, +-3846, -1574, -3601, -2483, -2562, -2751, -906, -2349, +971, -1442, 2596, -196, 3622, 1182, 3887, 2326, +3340, 2866, 2022, 2701, 219, 1961, -1590, 802, +-2968, -602, -3689, -1908, -3649, -2690, -2801, -2760, +-1276, -2220, 502, -1219, 2048, 110, 3060, 1448, +3431, 2343, 3089, 2561, 2050, 2168, 582, 1310, +-930, 119, -2157, -1136, -2894, -2037, -2986, -2296, +-2419, -1930, -1363, -1118, -95, -38, 1117, 1072, +2030, 1865, 2455, 2059, 2342, 1639, 1776, 806, +888, -195, -172, -1130, -1152, -1757, -1788, -1855, +-1968, -1383, -1777, -526, -1297, 407, -550, 1160, +328, 1582, 1063, 1588, 1466, 1142, 1557, 352, +1412, -473, 1010, -1028, 365, -1208, -351, -1087, +-955, -736, -1377, -205, -1582, 331, -1476, 605, +-1014, 528, -297, 276, 489, 53, 1196, -80, +1728, -110, 1939, 43, 1698, 393, 1008, 756, +32, 877, -1014, 625, -1911, 45, -2439, -695, +-2410, -1379, -1777, -1810, -666, -1817, 660, -1274, +1879, -225, 2709, 1039, 2941, 2099, 2512, 2639, +1484, 2539, 55, 1794, -1467, 526, -2695, -979, +-3291, -2296, -3138, -3008, -2313, -2914, -992, -2105, +584, -835, 2072, 626, 3097, 1957, 3413, 2786, +3006, 2844, 1995, 2187, 570, 1114, -1008, -96, +-2374, -1236, -3205, -2064, -3375, -2351, -2912, -2064, +-1899, -1374, -473, -506, 1073, 376, 2382, 1138, +3177, 1641, 3386, 1775, 3019, 1532, 2063, 1019, +605, 379, -1053, -298, -2513, -946, -3480, -1419, +-3817, -1565, -3416, -1362, -2251, -906, -549, -281, +1290, 431, 2872, 1080, 3894, 1475, 4115, 1520, +3414, 1227, 1915, 661, -12, -62, -1903, -773, +-3350, -1287, -4052, -1497, -3841, -1382, -2765, -963, +-1112, -309, 699, 411, 2250, 1004, 3218, 1344, +3433, 1401, 2908, 1173, 1782, 674, 327, 5, +-1063, -622, -2049, -1045, -2482, -1253, -2387, -1250, +-1824, -984, -902, -452, 122, 176, 930, 697, +1362, 1045, 1449, 1226, 1249, 1179, 799, 835, +221, 256, -272, -382, -546, -906, -605, -1237, +-509, -1330, -269, -1115, 45, -570, 273, 167, +294, 859, 146, 1318, -56, 1472, -245, 1290, +-395, 754, -459, -28, -373, -811, -139, -1362, +159, -1544, 422, -1318, 586, -761, 611, -43, +479, 651, 217, 1171, -69, 1379, -282, 1197, +-389, 709, -411, 125, -377, -389, -276, -784, +-145, -1005, -65, -980, -55, -725, -53, -374, +16, -46, 177, 232, 392, 501, 620, 754, +790, 916, 801, 927, 580, 787, 117, 506, +-518, 47, -1180, -594, -1650, -1293, -1749, -1795, +-1407, -1873, -667, -1456, 339, -597, 1399, 566, +2212, 1768, 2522, 2660, 2219, 2917, 1374, 2359, +201, 1089, -1047, -542, -2128, -2088, -2790, -3143, +-2821, -3404, -2181, -2760, -1066, -1356, 250, 384, +1536, 1932, 2557, 2884, 3056, 3066, 2880, 2523, +2086, 1443, 840, 108, -645, -1127, -2070, -1927, +-3072, -2192, -3385, -2054, -2927, -1656, -1766, -1013, +-104, -159, 1660, 725, 3040, 1457, 3698, 1996, +3503, 2293, 2458, 2155, 729, 1417, -1231, 155, +-2837, -1293, -3687, -2523, -3653, -3215, -2775, -3150, +-1215, -2195, 667, -455, 2357, 1572, 3407, 3196, +3604, 3928, 2999, 3642, 1787, 2392, 222, 416, +-1371, -1736, -2619, -3359, -3204, -4012, -3037, -3644, +-2259, -2415, -1090, -604, 280, 1310, 1635, 2796, +2640, 3548, 3000, 3496, 2674, 2684, 1828, 1302, +647, -293, -701, -1761, -1945, -2870, -2736, -3425, +-2885, -3243, -2413, -2339, -1420, -955, -80, 628, +1319, 2154, 2418, 3290, 2957, 3705, 2838, 3274, +2087, 2114, 832, 494, -649, -1255, -1978, -2762, +-2858, -3674, -3111, -3777, -2656, -3061, -1548, -1689, +-35, 45, 1467, 1768, 2583, 3123, 3101, 3840, +2922, 3770, 2040, 2879, 624, 1314, -930, -573, +-2181, -2331, -2877, -3575, -2951, -4059, -2364, -3637, +-1184, -2341, 280, -495, 1606, 1393, 2493, 2901, +2834, 3741, 2601, 3724, 1777, 2843, 501, 1374, +-868, -273, -1975, -1751, -2630, -2815, -2759, -3275, +-2297, -3038, -1264, -2224, 94, -1045, 1411, 317, +2387, 1674, 2850, 2739, 2701, 3229, 1922, 3024, +645, 2201, -814, 879, -2036, -763, -2730, -2341, +-2814, -3346, -2292, -3459, -1235, -2719, 131, -1367, +1452, 317, 2403, 1952, 2824, 2994, 2644, 3105, +1879, 2397, 698, 1197, -627, -192, -1790, -1423, +-2548, -2139, -2752, -2167, -2361, -1616, -1467, -751, +-261, 161, 1017, 886, 2083, 1275, 2652, 1296, +2578, 993, 1936, 461, 892, -131, -362, -603, +-1549, -882, -2324, -968, -2485, -819, -2081, -403, +-1228, 147, -79, 622, 1079, 914, 1910, 1013, +2217, 858, 1982, 397, 1259, -221, 193, -723, +-909, -961, -1731, -940, -2093, -688, -1915, -245, +-1214, 276, -166, 662, 913, 761, 1685, 616, +1947, 354, 1669, 21, 932, -317, -84, -522, +-1074, -503, -1716, -320, -1817, -87, -1385, 165, +-581, 400, 348, 507, 1110, 424, 1473, 243, +1368, 10, 844, -295, 95, -591, -601, -707, +-1022, -565, -1068, -254, -773, 112, -258, 488, +309, 809, 728, 919, 855, 728, 673, 276, +261, -274, -258, -734, -713, -983, -960, -1005, +-903, -795, -529, -367, 18, 168, 574, 633, +1073, 906, 1415, 997, 1419, 968, 963, 808, +155, 461, -713, -32, -1449, -554, -1961, -994, +-2070, -1310, -1601, -1464, -619, -1326, 564, -788, +1615, 55, 2340, 918, 2578, 1579, 2154, 1929, +1136, 1855, -154, 1279, -1372, 353, -2244, -610, +-2570, -1365, -2263, -1779, -1401, -1760, -262, -1330, +852, -665, 1712, 43, 2108, 661, 1960, 1076, +1381, 1218, 546, 1154, -353, 980, -1117, 703, +-1569, 283, -1607, -227, -1272, -691, -711, -1041, +-29, -1259, 633, -1263, 1079, -960, 1198, -408, +1009, 239, 636, 837, 184, 1258, -314, 1374, +-735, 1138, -903, 651, -777, 95, -484, -384, +-196, -721, 60, -873, 325, -826, 489, -613, +400, -347, 151, -131, -35, 12, -85, 125, +-118, 229, -198, 310, -148, 353, 109, 369, +294, 391, 222, 371, 92, 248, 79, 80, +47, -26, -179, -85, -422, -182, -416, -333, +-233, -430, -75, -432, 57, -429, 230, -423, +368, -297, 350, -18, 185, 301, -1, 563, +-132, 726, -216, 749, -223, 581, -93, 253, +149, -125, 390, -444, 499, -618, 463, -590, +306, -401, -16, -154, -432, 100, -741, 279, +-825, 271, -727, 72, -499, -164, -97, -313, +461, -334, 934, -212, 1110, 84, 1050, 481, +844, 788, 424, 875, -191, 741, -749, 389, +-1044, -181, -1099, -796, -968, -1212, -593, -1297, +-23, -1067, 519, -582, 851, 71, 930, 741, +779, 1223, 431, 1348, -11, 1104, -392, 618, +-600, 54, -589, -477, -359, -869, -42, -995, +197, -813, 297, -481, 277, -158, 128, 124, +-134, 344, -372, 470, -401, 491, -211, 432, +17, 345, 190, 259, 340, 129, 436, -64, +354, -346, 73, -665, -225, -832, -361, -746, +-343, -489, -255, -95, -143, 465, -2, 1052, +163, 1410, 228, 1328, 111, 853, -59, 188, +-101, -552, -13, -1292, 72, -1785, 66, -1757, +54, -1208, 117, -414, 135, 379, -2, 1135, +-166, 1750, -181, 1914, -63, 1509, 31, 792, +52, 24, 127, -725, 233, -1389, 209, -1760, +53, -1673, -101, -1209, -162, -547, -163, 220, +-161, 971, -119, 1478, 16, 1640, 183, 1498, +301, 1051, 336, 320, 311, -480, 256, -1123, +121, -1522, -113, -1641, -349, -1424, -539, -867, +-646, -120, -568, 623, -275, 1235, 185, 1625, +682, 1684, 1019, 1399, 1095, 815, 911, 22, +461, -787, -207, -1406, -912, -1736, -1395, -1744, +-1487, -1407, -1214, -748, -646, 125, 137, 947, +921, 1523, 1458, 1814, 1652, 1775, 1455, 1343, +882, 611, 95, -237, -679, -1015, -1288, -1570, +-1664, -1841, -1687, -1764, -1267, -1310, -551, -565, +200, 295, 887, 1069, 1436, 1595, 1687, 1843, +1484, 1770, 843, 1289, 8, 487, -737, -387, +-1262, -1133, -1483, -1653, -1299, -1859, -779, -1667, +-112, -1094, 497, -314, 907, 505, 1032, 1238, +833, 1725, 387, 1810, -96, 1485, -423, 851, +-544, 28, -495, -834, -323, -1518, -65, -1823, +175, -1726, 271, -1265, 228, -445, 148, 571, +41, 1413, -93, 1842, -163, 1868, -99, 1505, +32, 730, 122, -287, 167, -1200, 200, -1749, +173, -1858, 48, -1577, -108, -977, -249, -160, +-350, 680, -350, 1278, -204, 1506, 52, 1432, +362, 1171, 645, 768, 779, 224, 669, -367, +293, -857, -226, -1164, -723, -1316, -1084, -1326, +-1185, -1122, -921, -630, -316, 59, 480, 773, +1203, 1371, 1575, 1706, 1511, 1688, 1064, 1307, +296, 571, -629, -381, -1398, -1210, -1751, -1708, +-1636, -1860, -1162, -1653, -407, -1037, 495, -121, +1253, 785, 1637, 1435, 1601, 1789, 1213, 1820, +575, 1436, -209, 720, -976, -134, -1475, -950, +-1610, -1600, -1456, -1957, -1041, -1878, -361, -1308, +468, -435, 1185, 498, 1554, 1341, 1567, 1922, +1317, 2068, 794, 1702, 54, 896, -724, -95, +-1341, -988, -1636, -1653, -1587, -1960, -1278, -1781, +-726, -1155, 5, -318, 736, 470, 1310, 1109, +1616, 1574, 1606, 1707, 1287, 1369, 689, 734, +-99, 60, -881, -560, -1440, -1092, -1638, -1419, +-1509, -1413, -1123, -1061, -446, -489, 390, 128, +1082, 677, 1436, 1071, 1433, 1207, 1134, 1018, +642, 591, 48, 110, -498, -290, -863, -592, +-1005, -760, -910, -718, -635, -489, -288, -194, +95, 62, 475, 232, 734, 300, 828, 319, +754, 295, 511, 222, 153, 122, -255, -4, +-644, -116, -875, -147, -837, -177, -534, -254, +-89, -226, 339, -83, 678, 35, 877, 98, +869, 190, 612, 322, 163, 379, -296, 241, +-585, 16, -702, -128, -686, -221, -492, -334, +-196, -442, 9, -447, 71, -278, 135, -22, +280, 176, 388, 333, 352, 440, 275, 465, +252, 446, 231, 364, 121, 174, -108, -48, +-368, -244, -508, -418, -489, -540, -432, -637, +-368, -658, -200, -486, 54, -148, 208, 218, +208, 565, 243, 873, 422, 1036, 512, 912, +301, 491, 36, -38, 12, -504, 42, -848, +-189, -1019, -517, -929, -595, -582, -433, -90, +-293, 365, -214, 620, -35, 639, 235, 509, +418, 319, 446, 87, 418, -141, 420, -267, +423, -222, 288, -100, -1, -37, -319, -1, +-525, 98, -589, 165, -603, 130, -564, 88, +-319, 62, 143, -31, 599, -228, 859, -441, +876, -538, 715, -484, 405, -335, -46, -42, +-485, 380, -731, 769, -754, 989, -568, 955, +-264, 652, 12, 201, 269, -289, 502, -763, +572, -1072, 439, -1091, 255, -833, 158, -455, +114, -110, -21, 238, -184, 645, -240, 941, +-268, 993, -362, 876, -449, 676, -398, 380, +-187, -107, 59, -730, 241, -1232, 404, -1411, +521, -1238, 550, -727, 513, 10, 352, 792, +67, 1427, -218, 1671, -448, 1374, -640, 625, +-771, -282, -782, -1043, -593, -1464, -256, -1464, +126, -976, 567, -101, 979, 779, 1108, 1245, +872, 1187, 399, 791, -123, 191, -583, -550, +-976, -1149, -1165, -1243, -988, -813, -507, -107, +83, 622, 603, 1182, 888, 1382, 889, 1098, +658, 409, 308, -410, -23, -1092, -298, -1487, +-466, -1468, -467, -980, -372, -145, -278, 731, +-191, 1375, -153, 1614, -152, 1353, -111, 677, +24, -153, 282, -901, 566, -1388, 733, -1433, +778, -1015, 670, -280, 339, 519, -90, 1085, +-510, 1206, -934, 886, -1261, 289, -1221, -359, +-729, -861, -57, -1028, 515, -759, 1016, -162, +1465, 534, 1594, 1043, 1249, 1137, 573, 818, +-229, 229, -1034, -519, -1703, -1187, -1993, -1473, +-1688, -1260, -856, -651, 187, 108, 1142, 807, +1844, 1362, 2209, 1632, 2051, 1406, 1240, 737, +7, -100, -1163, -825, -1954, -1351, -2238, -1659, +-1981, -1581, -1247, -1001, -221, -138, 792, 717, +1529, 1418, 1861, 1823, 1718, 1797, 1095, 1248, +217, 285, -573, -757, -1067, -1561, -1247, -1969, +-1144, -1844, -776, -1177, -241, -178, 245, 854, +528, 1602, 608, 1834, 518, 1492, 313, 715, +84, -210, -71, -972, -112, -1368, -54, -1272, +24, -729, 41, 14, -49, 684, -250, 1095, +-494, 1076, -670, 567, -673, -187, -447, -831, +17, -1180, 629, -1179, 1156, -771, 1344, -19, +1188, 832, 762, 1438, 27, 1538, -861, 1127, +-1505, 390, -1686, -467, -1470, -1214, -918, -1598, +-91, -1467, 794, -808, 1400, 138, 1561, 1003, +1365, 1500, 907, 1490, 254, 1005, -408, 177, +-871, -786, -1028, -1504, -911, -1648, -690, -1259, +-432, -511, -109, 397, 213, 1187, 430, 1646, +573, 1652, 705, 1130, 766, 298, 656, -466, +407, -1023, 114, -1363, -251, -1419, -688, -1154, +-1041, -671, -1130, -148, -900, 354, -427, 861, +151, 1241, 761, 1373, 1259, 1288, 1411, 1002, +1170, 472, 638, -289, -117, -1105, -931, -1672, +-1492, -1811, -1590, -1567, -1240, -959, -602, -69, +194, 835, 970, 1465, 1455, 1712, 1515, 1565, +1220, 1073, 625, 399, -197, -246, -969, -709, +-1384, -958, -1357, -1007, -1047, -933, -608, -790, +-92, -606, 402, -384, 732, -65, 873, 374, +869, 821, 747, 1139, 527, 1269, 242, 1159, +-33, 783, -286, 144, -554, -618, -826, -1249, +-1016, -1541, -1008, -1432, -705, -990, -190, -384, +333, 267, 766, 879, 1085, 1262, 1209, 1305, +1033, 1075, 592, 695, 52, 222, -424, -305, +-780, -806, -961, -1120, -914, -1190, -700, -1055, +-447, -713, -183, -189, 88, 431, 302, 1026, +502, 1385, 744, 1330, 929, 923, 918, 321, +776, -313, 579, -876, 204, -1265, -434, -1323, +-1091, -978, -1457, -386, -1500, 220, -1300, 706, +-832, 1019, -62, 1128, 826, 986, 1519, 644, +1858, 199, 1884, -273, 1551, -712, 758, -1071, +-320, -1288, -1273, -1231, -1839, -865, -2041, -310, +-1905, 353, -1306, 1044, -284, 1603, 799, 1842, +1633, 1655, 2088, 1048, 2084, 166, 1599, -780, +711, -1557, -381, -2022, -1347, -2110, -1946, -1731, +-2100, -935, -1792, 39, -1087, 962, -102, 1699, +932, 2116, 1661, 2118, 1872, 1669, 1662, 892, +1180, -5, 482, -901, -372, -1648, -1135, -2035, +-1503, -2008, -1463, -1634, -1159, -941, -627, -51, +50, 800, 624, 1420, 908, 1774, 901, 1848, +748, 1582, 510, 994, 149, 243, -214, -491, +-412, -1111, -443, -1556, -379, -1764, -297, -1630, +-227, -1146, -113, -450, -11, 285, 42, 950, +137, 1455, 297, 1696, 443, 1563, 512, 1075, +475, 433, 322, -191, 42, -731, -343, -1161, +-699, -1374, -928, -1289, -959, -984, -695, -589, +-184, -133, 376, 335, 850, 759, 1158, 1114, +1243, 1283, 1063, 1192, 605, 918, 3, 513, +-597, -19, -1101, -599, -1368, -1129, -1304, -1448, +-964, -1458, -431, -1223, 184, -814, 764, -227, +1207, 483, 1385, 1170, 1283, 1658, 975, 1840, +461, 1733, -215, 1292, -832, 488, -1242, -543, +-1400, -1541, -1322, -2251, -1027, -2495, -511, -2217, +154, -1400, 792, -130, 1231, 1244, 1425, 2301, +1420, 2759, 1174, 2560, 587, 1766, -164, 543, +-794, -805, -1252, -1865, -1560, -2348, -1584, -2207, +-1186, -1561, -460, -623, 299, 346, 891, 1072, +1313, 1399, 1496, 1341, 1310, 1020, 767, 581, +93, 177, -474, -119, -888, -297, -1177, -384, +-1207, -425, -885, -459, -379, -554, 94, -681, +447, -675, 693, -467, 835, -166, 808, 191, +579, 600, 254, 952, -23, 1126, -224, 1067, +-421, 779, -573, 335, -539, -169, -359, -642, +-192, -1004, -93, -1194, -34, -1134, 11, -859, +55, -489, 80, -58, 123, 406, 222, 786, +373, 992, 539, 997, 638, 840, 596, 616, +400, 333, 68, -8, -376, -310, -824, -514, +-1106, -664, -1080, -757, -797, -775, -402, -714, +56, -555, 558, -282, 962, 63, 1086, 410, +927, 753, 641, 1034, 302, 1112, -126, 939, +-496, 612, -588, 172, -462, -329, -353, -775, +-325, -1082, -264, -1198, -129, -1082, -55, -753, +-101, -318, -103, 134, 38, 570, 241, 952, +405, 1151, 511, 1120, 586, 932, 579, 630, +355, 200, -55, -318, -457, -790, -726, -1064, +-838, -1154, -808, -1141, -617, -947, -253, -537, +207, -27, 611, 475, 817, 914, 783, 1221, +632, 1359, 435, 1288, 122, 968, -243, 423, +-499, -260, -607, -896, -631, -1346, -593, -1579, +-448, -1537, -165, -1137, 150, -457, 370, 291, +479, 904, 518, 1296, 502, 1455, 384, 1330, +131, 914, -155, 357, -341, -150, -405, -557, +-369, -884, -261, -1085, -82, -1070, 142, -894, +273, -659, 211, -314, 66, 201, -6, 746, +-36, 1113, -133, 1259, -222, 1203, -149, 876, +4, 235, 71, -511, 92, -1090, 166, -1376, +253, -1344, 279, -976, 227, -307, 135, 465, +47, 1025, -73, 1222, -253, 1110, -427, 710, +-489, 106, -427, -472, -315, -846, -171, -958, +84, -787, 380, -402, 533, 70, 531, 463, +492, 656, 440, 697, 329, 627, 195, 405, +77, 66, -103, -240, -419, -436, -768, -568, +-1030, -710, -1167, -756, -1131, -585, -822, -307, +-178, -23, 703, 338, 1581, 785, 2229, 1154, +2450, 1290, 2071, 1147, 1131, 784, -141, 217, +-1504, -522, -2695, -1257, -3371, -1775, -3275, -1962, +-2425, -1762, -1028, -1154, 683, -232, 2388, 806, +3600, 1725, 3974, 2334, 3477, 2473, 2259, 2089, +536, 1254, -1351, 128, -2985, -1075, -3953, -2086, +-4007, -2644, -3152, -2605, -1627, -2022, 208, -1077, +1958, 98, 3203, 1295, 3662, 2173, 3309, 2483, +2269, 2256, 743, 1630, -869, 696, -2133, -420, +-2816, -1397, -2856, -1922, -2259, -1952, -1172, -1596, +71, -958, 1143, -138, 1870, 686, 2177, 1277, +1977, 1452, 1272, 1252, 294, 797, -603, 198, +-1215, -383, -1537, -815, -1541, -1026, -1156, -949, +-462, -599, 274, -119, 841, 361, 1197, 726, +1322, 890, 1120, 838, 619, 609, 29, 225, +-485, -271, -901, -725, -1192, -955, -1240, -966, +-969, -849, -464, -541, 102, -36, 652, 490, +1122, 847, 1379, 998, 1323, 991, 961, 838, +366, 494, -336, 30, -982, -383, -1422, -650, +-1536, -775, -1265, -806, -661, -752, 39, -602, +628, -364, 1075, -98, 1345, 142, 1274, 349, +845, 586, 285, 826, -188, 929, -563, 868, +-866, 704, -948, 407, -753, -56, -473, -552, +-233, -931, 53, -1142, 370, -1200, 519, -1038, +432, -621, 289, -112, 211, 326, 119, 683, +-40, 943, -151, 1031, -109, 953, 30, 777, +160, 576, 231, 352, 227, 85, 118, -225, +-69, -571, -270, -924, -463, -1212, -602, -1365, +-614, -1342, -496, -1073, -303, -498, -42, 324, +292, 1149, 631, 1765, 842, 2117, 928, 2121, +973, 1643, 906, 763, 594, -267, 85, -1242, +-480, -1997, -1053, -2346, -1562, -2198, -1817, -1660, +-1648, -861, -1129, 95, -423, 998, 435, 1600, +1418, 1862, 2267, 1843, 2619, 1548, 2322, 991, +1537, 289, 488, -336, -731, -779, -1937, -1142, +-2797, -1437, -3051, -1477, -2624, -1253, -1625, -919, +-278, -506, 1212, 43, 2534, 672, 3262, 1221, +3171, 1572, 2364, 1670, 1094, 1454, -401, 910, +-1858, 153, -2876, -669, -3099, -1357, -2557, -1711, +-1507, -1664, -194, -1265, 1114, -585, 2096, 210, +2474, 906, 2176, 1331, 1405, 1366, 443, 1034, +-508, 490, -1255, -102, -1615, -621, -1506, -943, +-1051, -988, -475, -748, 81, -299, 554, 229, +851, 686, 917, 967, 762, 1030, 454, 832, +169, 375, 7, -243, -140, -841, -368, -1264, +-589, -1423, -669, -1291, -629, -851, -572, -144, +-455, 653, -147, 1284, 315, 1567, 767, 1526, +1091, 1269, 1255, 803, 1212, 134, 881, -510, +234, -909, -574, -1076, -1261, -1158, -1652, -1188, +-1747, -1052, -1567, -736, -1052, -399, -218, -92, +723, 317, 1484, 839, 1909, 1299, 2009, 1503, +1814, 1455, 1254, 1273, 374, 927, -578, 316, +-1392, -423, -1983, -1048, -2246, -1485, -2057, -1758, +-1462, -1836, -620, -1613, 331, -1082, 1271, -390, +1981, 359, 2265, 1167, 2109, 1882, 1595, 2244, +817, 2178, -101, 1785, -997, 1133, -1671, 219, +-1972, -796, -1918, -1618, -1618, -2101, -1121, -2278, +-414, -2139, 394, -1659, 1060, -910, 1454, -37, +1644, 845, 1670, 1631, 1465, 2199, 986, 2460, +319, 2346, -348, 1798, -893, 851, -1331, -271, +-1627, -1324, -1658, -2164, -1417, -2678, -1005, -2676, +-461, -2084, 201, -1127, 877, -97, 1419, 897, +1730, 1751, 1747, 2255, 1474, 2322, 1000, 2016, +393, 1453, -357, 718, -1158, -130, -1728, -995, +-1877, -1716, -1703, -2140, -1320, -2167, -680, -1810, +167, -1150, 943, -240, 1446, 779, 1701, 1625, +1718, 2054, 1385, 2025, 685, 1606, -135, 863, +-801, -81, -1253, -941, -1503, -1468, -1471, -1636, +-1088, -1465, -461, -957, 197, -249, 748, 462, +1126, 1055, 1237, 1392, 1066, 1346, 704, 948, +235, 381, -260, -248, -664, -914, -885, -1444, +-895, -1585, -754, -1283, -529, -701, -205, 5, +193, 741, 521, 1383, 683, 1727, 730, 1667, +738, 1285, 649, 707, 337, 9, -89, -692, +-371, -1263, -535, -1631, -756, -1741, -946, -1595, +-900, -1230, -622, -670, -251, 76, 155, 894, +606, 1587, 1011, 2024, 1223, 2154, 1217, 1894, +999, 1220, 543, 313, -87, -622, -749, -1463, +-1279, -2062, -1543, -2228, -1496, -1934, -1128, -1353, +-496, -653, 211, 133, 806, 921, 1210, 1498, +1380, 1746, 1291, 1733, 952, 1528, 431, 1077, +-118, 383, -570, -365, -876, -961, -1001, -1358, +-936, -1513, -699, -1352, -328, -899, 53, -297, +335, 285, 533, 692, 605, 802, 462, 629, +177, 322, -90, 11, -285, -260, -358, -365, +-223, -181, 116, 213, 465, 608, 636, 879, +645, 965, 534, 818, 217, 392, -307, -255, +-824, -903, -1121, -1398, -1135, -1694, -924, -1736, +-546, -1429, -65, -788, 394, 39, 753, 879, +1023, 1619, 1176, 2157, 1154, 2357, 984, 2150, +702, 1540, 283, 635, -266, -374, -821, -1348, +-1268, -2195, -1604, -2703, -1763, -2703, -1519, -2261, +-826, -1513, 36, -478, 842, 772, 1531, 1960, +1966, 2773, 1950, 3062, 1480, 2856, 736, 2172, +-95, 1020, -863, -430, -1403, -1781, -1564, -2667, +-1311, -2971, -764, -2698, -123, -1883, 411, -683, +716, 567, 765, 1519, 541, 1966, 71, 1901, +-486, 1434, -850, 739, -844, 4, -487, -561, +115, -767, 847, -600, 1516, -258, 1848, 61, +1665, 272, 1011, 331, 45, 202, -1069, -124, +-2060, -536, -2587, -829, -2492, -903, -1853, -795, +-830, -497, 360, -27, 1433, 470, 2164, 873, +2454, 1133, 2265, 1208, 1619, 1032, 706, 646, +-195, 192, -923, -252, -1411, -686, -1625, -962, +-1596, -948, -1371, -769, -968, -587, -438, -392, +125, -164, 590, -1, 893, 53, 1088, 88, +1169, 200, 1047, 377, 746, 632, 385, 966, +13, 1186, -381, 1084, -731, 706, -859, 199, +-718, -423, -503, -1119, -326, -1645, -89, -1766, +172, -1500, 293, -973, 244, -268, 122, 477, +-5, 1033, -134, 1301, -190, 1343, -56, 1189, +199, 866, 403, 501, 536, 205, 637, -66, +639, -329, 449, -524, 86, -667, -319, -861, +-675, -1074, -981, -1148, -1153, -981, -1077, -631, +-807, -207, -425, 296, 83, 875, 680, 1397, +1216, 1669, 1517, 1599, 1510, 1235, 1227, 682, +683, -9, -63, -740, -805, -1311, -1344, -1557, +-1562, -1477, -1400, -1176, -932, -717, -329, -139, +286, 389, 768, 648, 935, 655, 751, 564, +363, 466, -15, 375, -248, 320, -319, 354, +-208, 482, 107, 593, 510, 559, 794, 348, +791, -15, 498, -478, 42, -953, -466, -1310, +-960, -1464, -1323, -1385, -1437, -1045, -1242, -452, +-738, 260, -37, 944, 666, 1543, 1254, 1967, +1665, 2044, 1792, 1671, 1558, 941, 990, 58, +206, -836, -650, -1649, -1420, -2188, -1867, -2226, +-1836, -1735, -1408, -909, -712, 13, 124, 862, +869, 1460, 1324, 1667, 1429, 1498, 1192, 1078, +673, 515, 20, -49, -539, -452, -797, -628, +-750, -633, -551, -570, -272, -486, 72, -386, +372, -306, 483, -275, 397, -218, 259, -48, +157, 183, 26, 343, -144, 439, -262, 545, +-327, 586, -414, 446, -508, 182, -519, -65, +-376, -238, -89, -321, 247, -321, 568, -267, +845, -192, 1019, -94, 978, -6, 668, -4, +190, -110, -313, -244, -789, -331, -1176, -344, +-1318, -241, -1129, -2, -705, 351, -212, 744, +232, 1042, 628, 1150, 1000, 1052, 1199, 711, +1041, 101, 629, -685, 233, -1422, -84, -1873, +-428, -1965, -729, -1727, -773, -1127, -575, -154, +-366, 961, -216, 1863, 7, 2373, 262, 2499, +329, 2165, 180, 1273, 24, 64, -17, -1034, +-44, -1858, -126, -2395, -125, -2471, 30, -1980, +171, -1103, 229, -128, 337, 766, 472, 1450, +458, 1804, 294, 1792, 120, 1472, -62, 957, +-350, 371, -677, -195, -886, -691, -965, -1018, +-937, -1109, -694, -1020, -215, -864, 339, -637, +851, -282, 1291, 130, 1594, 431, 1608, 568, +1245, 639, 655, 661, 24, 554, -668, 343, +-1393, 185, -1899, 86, -1978, -76, -1695, -262, +-1247, -331, -668, -355, 149, -440, 1075, -487, +1766, -399, 2063, -213, 2045, 26, 1819, 299, +1342, 514, 518, 572, -492, 482, -1307, 311, +-1811, 57, -2122, -265, -2163, -515, -1726, -557, +-889, -378, -24, -72, 676, 239, 1302, 461, +1785, 556, 1830, 461, 1426, 175, 878, -215, +369, -585, -113, -797, -545, -746, -806, -463, +-833, -56, -734, 407, -642, 821, -560, 1003, +-478, 858, -401, 516, -297, 119, -137, -306, +80, -697, 359, -874, 661, -773, 878, -526, +911, -255, 754, 1, 528, 202, 280, 284, +-63, 282, -422, 288, -603, 321, -628, 341, +-633, 371, -604, 428, -470, 428, -261, 254, +-105, -54, -39, -368, 39, -667, 186, -914, +340, -971, 462, -788, 535, -442, 556, 26, +538, 544, 471, 925, 356, 1062, 183, 1027, +-116, 839, -499, 402, -800, -190, -948, -628, +-963, -804, -835, -863, -522, -804, -37, -514, +498, -67, 920, 297, 1129, 479, 1089, 533, +813, 461, 371, 226, -151, -61, -612, -233, +-831, -283, -756, -255, -489, -117, -144, 134, +179, 351, 418, 416, 513, 364, 360, 243, +-10, 15, -361, -285, -522, -516, -533, -603, +-462, -571, -238, -467, 199, -276, 645, 14, +815, 339, 707, 585, 517, 705, 296, 721, +-28, 658, -407, 494, -638, 205, -618, -163, +-480, -519, -362, -787, -205, -935, 38, -943, +232, -799, 271, -476, 241, -22, 231, 449, +209, 853, 139, 1136, 52, 1207, -23, 994, +-88, 557, -117, 36, -93, -479, -82, -934, +-69, -1185, 50, -1129, 194, -819, 183, -368, +63, 142, 10, 586, 21, 809, -61, 793, +-236, 635, -312, 376, -254, 39, -252, -243, +-313, -348, -234, -313, -7, -235, 203, -121, +370, 20, 597, 93, 843, 32, 887, -81, +658, -137, 302, -160, -155, -197, -719, -188, +-1180, -62, -1343, 143, -1222, 336, -882, 467, +-364, 537, 262, 511, 836, 343, 1179, 35, +1252, -355, 1103, -708, 789, -922, 407, -961, +30, -780, -299, -333, -504, 265, -588, 802, +-639, 1135, -666, 1216, -627, 1029, -525, 592, +-416, 5, -362, -567, -285, -970, -45, -1126, +301, -1024, 582, -730, 790, -332, 1002, 72, +1186, 391, 1183, 605, 898, 744, 406, 780, +-167, 673, -755, 493, -1296, 302, -1692, 66, +-1817, -249, -1565, -555, -1012, -771, -365, -874, +284, -840, 931, -651, 1456, -343, 1713, 28, +1702, 428, 1515, 790, 1167, 1016, 621, 1049, +-49, 902, -671, 607, -1164, 182, -1547, -326, +-1780, -792, -1766, -1100, -1442, -1194, -843, -1051, +-134, -675, 520, -138, 1070, 401, 1487, 813, +1687, 1022, 1593, 967, 1249, 680, 816, 308, +353, -70, -204, -405, -781, -549, -1178, -444, +-1358, -241, -1394, -66, -1282, 78, -956, 155, +-431, 98, 137, -66, 642, -212, 1062, -297, +1284, -325, 1215, -247, 941, -54, 539, 173, +28, 354, -454, 455, -739, 480, -802, 448, +-714, 333, -504, 131, -164, -81, 211, -228, +454, -319, 519, -384, 419, -410, 165, -366, +-147, -263, -403, -172, -552, -136, -565, -107, +-444, -3, -216, 133, 83, 219, 372, 297, +585, 454, 697, 613, 685, 643, 572, 545, +432, 376, 282, 152, 70, -154, -234, -523, +-584, -859, -884, -1050, -1096, -1074, -1186, -995, +-1054, -809, -672, -401, -153, 200, 441, 792, +1087, 1258, 1594, 1610, 1743, 1777, 1522, 1606, +1070, 1054, 472, 230, -235, -651, -920, -1436, +-1383, -2031, -1581, -2287, -1591, -2046, -1377, -1347, +-880, -438, -247, 471, 310, 1318, 759, 1956, +1156, 2147, 1420, 1864, 1403, 1298, 1136, 617, +755, -122, 282, -822, -250, -1317, -665, -1486, +-874, -1392, -959, -1153, -960, -790, -820, -324, +-534, 132, -221, 467, 22, 699, 211, 855, +361, 900, 436, 827, 464, 678, 469, 460, +432, 202, 371, -62, 294, -347, 199, -612, +123, -755, 70, -744, -12, -640, -145, -440, +-312, -130, -444, 201, -500, 401, -540, 442, +-581, 356, -539, 138, -380, -142, -154, -331, +82, -345, 308, -175, 548, 177, 765, 623, +895, 1000, 973, 1142, 978, 977, 786, 543, +376, -102, -135, -871, -670, -1538, -1192, -1853, +-1608, -1759, -1772, -1366, -1614, -753, -1182, 52, +-491, 891, 404, 1506, 1265, 1784, 1844, 1795, +2096, 1585, 2066, 1162, 1730, 582, 1032, -43, +88, -624, -814, -1114, -1515, -1462, -1999, -1632, +-2155, -1607, -1892, -1375, -1325, -937, -610, -374, +198, 222, 1003, 803, 1583, 1330, 1776, 1685, +1656, 1728, 1349, 1476, 846, 1045, 188, 467, +-418, -235, -821, -879, -1049, -1285, -1154, -1416, +-1098, -1293, -833, -913, -450, -373, -121, 94, +140, 356, 444, 452, 752, 382, 887, 143, +804, -99, 615, -167, 383, -28, 71, 262, +-298, 626, -596, 941, -727, 1060, -695, 893, +-528, 485, -247, -52, 93, -608, 409, -1054, +597, -1290, 598, -1278, 449, -1057, 234, -720, +-2, -361, -244, -14, -443, 308, -493, 603, +-368, 861, -197, 1060, -68, 1198, 46, 1232, +142, 1068, 188, 696, 192, 199, 173, -361, +139, -922, 96, -1359, 69, -1545, 81, -1477, +85, -1220, 22, -797, -58, -267, -90, 248, +-100, 683, -111, 1044, -96, 1291, -66, 1360, +-82, 1245, -192, 1000, -350, 640, -423, 150, +-350, -410, -184, -912, 45, -1248, 372, -1353, +791, -1223, 1128, -896, 1151, -407, 852, 145, +404, 594, -130, 844, -770, 874, -1372, 692, +-1680, 361, -1571, -12, -1129, -315, -511, -454, +171, -372, 834, -102, 1376, 233, 1677, 536, +1633, 769, 1287, 849, 792, 638, 199, 161, +-488, -396, -1107, -898, -1451, -1307, -1494, -1552, +-1334, -1506, -1010, -1115, -467, -491, 229, 218, +831, 944, 1170, 1595, 1261, 2009, 1140, 2063, +819, 1770, 357, 1195, -146, 403, -558, -477, +-787, -1288, -824, -1917, -682, -2241, -403, -2158, +-74, -1728, 203, -1079, 364, -292, 437, 539, +463, 1261, 370, 1739, 109, 1934, -194, 1860, +-394, 1527, -485, 980, -530, 334, -500, -305, +-304, -867, 47, -1289, 425, -1504, 744, -1465, +979, -1197, 1062, -804, 886, -350, 412, 124, +-235, 509, -826, 713, -1262, 753, -1562, 687, +-1606, 555, -1217, 392, -441, 258, 421, 198, +1098, 214, 1547, 261, 1780, 264, 1648, 175, +1086, 9, 338, -208, -324, -482, -840, -780, +-1216, -999, -1373, -1053, -1229, -918, -886, -637, +-547, -252, -254, 218, 61, 716, 383, 1138, +648, 1374, 842, 1392, 960, 1213, 985, 847, +903, 324, 707, -247, 382, -770, -76, -1172, +-570, -1379, -955, -1377, -1171, -1188, -1213, -807, +-1066, -296, -750, 195, -341, 589, 105, 911, +539, 1141, 893, 1178, 1086, 1002, 1103, 706, +991, 351, 766, -33, 435, -395, 72, -688, +-274, -868, -617, -887, -899, -770, -1009, -581, +-946, -338, -803, -49, -610, 229, -303, 417, +106, 519, 468, 611, 698, 663, 842, 556, +894, 308, 794, 59, 592, -141, 362, -355, +100, -557, -181, -602, -416, -441, -562, -201, +-637, 31, -670, 258, -637, 417, -534, 406, +-418, 233, -285, -7, -70, -221, 223, -350, +506, -367, 717, -270, 850, -74, 899, 176, +819, 391, 587, 487, 234, 445, -195, 296, +-622, 94, -934, -114, -1078, -297, -1067, -426, +-893, -474, -563, -422, -123, -281, 318, -106, +642, 73, 826, 253, 915, 383, 884, 409, +692, 362, 407, 273, 138, 120, -88, -68, +-325, -209, -571, -272, -718, -275, -739, -239, +-710, -170, -614, -80, -374, -9, -33, 31, +330, 82, 669, 156, 884, 218, 884, 250, +686, 249, 369, 198, -24, 71, -443, -107, +-735, -284, -750, -416, -549, -435, -276, -299, +57, -81, 421, 123, 628, 302, 561, 411, +319, 361, 53, 161, -205, -64, -457, -213, +-587, -266, -520, -209, -319, -40, -49, 185, +248, 368, 474, 409, 581, 274, 597, 49, +505, -177, 271, -401, -69, -582, -375, -603, +-541, -430, -608, -168, -615, 63, -477, 236, +-179, 394, 162, 513, 443, 514, 595, 414, +596, 309, 478, 222, 260, 103, -13, -59, +-247, -216, -413, -330, -517, -416, -556, -495, +-511, -532, -331, -464, -42, -298, 236, -111, +477, 77, 717, 293, 869, 493, 817, 608, +553, 604, 144, 484, -365, 271, -924, 22, +-1338, -206, -1382, -367, -1078, -409, -595, -317, +6, -134, 678, 48, 1247, 172, 1507, 205, +1406, 94, 1055, -148, 556, -413, -32, -577, +-583, -583, -965, -433, -1146, -139, -1141, 268, +-980, 655, -687, 886, -251, 949, 253, 853, +647, 576, 833, 172, 852, -233, 758, -551, +517, -751, 121, -826, -274, -781, -459, -632, +-402, -397, -214, -111, 40, 141, 301, 302, +440, 373, 351, 374, 61, 323, -315, 254, +-637, 196, -811, 189, -781, 256, -533, 358, +-134, 427, 297, 412, 633, 274, 765, 23, +694, -297, 523, -635, 333, -896, 153, -987, +14, -921, -51, -754, -46, -487, -31, -121, +-101, 256, -278, 548, -481, 764, -627, 950, +-673, 1073, -619, 1064, -456, 918, -171, 676, +180, 352, 494, -57, 718, -479, 829, -819, +814, -1054, 683, -1203, 434, -1254, 115, -1184, +-165, -996, -361, -700, -500, -309, -585, 181, +-595, 760, -502, 1357, -357, 1821, -257, 2015, +-205, 1885, -142, 1425, -44, 677, 81, -205, +219, -1030, 344, -1661, 477, -1959, 617, -1872, +696, -1504, 635, -982, 439, -407, 183, 95, +-59, 463, -290, 710, -528, 836, -710, 879, +-783, 907, -769, 910, -696, 828, -550, 684, +-297, 524, 39, 306, 348, -9, 574, -357, +756, -657, 897, -886, 916, -1049, 756, -1132, +491, -1069, 238, -809, 30, -420, -175, 6, +-380, 455, -571, 841, -743, 1012, -889, 955, +-979, 769, -951, 494, -746, 177, -389, -42, +50, -76, 555, 7, 1049, 115, 1391, 189, +1472, 146, 1288, -63, 905, -418, 425, -821, +-84, -1107, -572, -1168, -961, -1007, -1183, -654, +-1232, -148, -1137, 402, -912, 868, -578, 1152, +-188, 1202, 190, 1067, 552, 849, 888, 569, +1094, 226, 1088, -99, 908, -323, 640, -468, +331, -577, 0, -618, -316, -585, -564, -528, +-724, -493, -820, -502, -840, -532, -729, -514, +-492, -416, -229, -226, 10, 96, 297, 560, +627, 1086, 827, 1513, 803, 1684, 639, 1538, +414, 1107, 112, 434, -225, -388, -493, -1167, +-621, -1683, -600, -1841, -448, -1689, -206, -1283, +62, -694, 308, -58, 485, 468, 524, 804, +386, 962, 150, 1001, -116, 920, -410, 730, +-680, 523, -771, 349, -607, 157, -280, -43, +86, -185, 462, -287, 807, -384, 980, -440, +901, -431, 653, -413, 327, -406, -80, -371, +-487, -307, -720, -250, -762, -174, -740, -43, +-682, 120, -525, 275, -292, 414, -43, 558, +209, 666, 452, 665, 642, 556, 764, 381, +800, 137, 706, -163, 465, -445, 139, -639, +-206, -715, -520, -650, -709, -455, -712, -191, +-577, 67, -383, 240, -157, 277, 65, 174, +226, 3, 283, -164, 235, -269, 130, -233, +37, -27, -3, 282, 6, 595, 86, 826, +248, 896, 400, 771, 431, 459, 365, 16, +237, -459, -22, -872, -420, -1159, -773, -1260, +-911, -1141, -848, -831, -637, -374, -265, 174, +252, 708, 742, 1118, 1017, 1361, 1022, 1365, +804, 1073, 404, 559, -100, -38, -565, -616, +-849, -1034, -878, -1178, -676, -1065, -325, -735, +84, -254, 469, 222, 731, 550, 769, 705, +556, 684, 201, 501, -153, 223, -470, -59, +-742, -279, -859, -410, -720, -459, -384, -433, +34, -306, 463, -89, 820, 147, 977, 345, +888, 521, 610, 630, 226, 570, -210, 343, +-612, 37, -859, -300, -880, -600, -665, -749, +-295, -707, 80, -493, 344, -144, 489, 244, +496, 517, 345, 616, 96, 548, -123, 326, +-231, 20, -222, -267, -95, -459, 131, -479, +347, -306, 434, -57, 399, 189, 269, 405, +35, 519, -270, 460, -534, 268, -675, 20, +-685, -219, -584, -392, -355, -473, -34, -446, +240, -323, 399, -145, 529, 17, 669, 122, +722, 185, 641, 244, 474, 282, 271, 275, +16, 242, -290, 210, -578, 144, -804, -2, +-947, -202, -945, -383, -723, -474, -324, -452, +113, -295, 468, -12, 719, 342, 875, 648, +861, 789, 625, 704, 287, 390, -7, -81, +-241, -582, -426, -974, -501, -1139, -433, -1014, +-299, -641, -160, -115, -10, 453, 158, 925, +291, 1184, 334, 1202, 270, 1002, 113, 644, +-82, 193, -290, -296, -511, -711, -666, -969, +-623, -1087, -390, -1074, -56, -858, 345, -461, +772, -1, 1077, 431, 1111, 776, 881, 961, +522, 935, 104, 706, -392, 331, -868, -70, +-1142, -393, -1137, -565, -922, -553, -608, -373, +-262, -102, 101, 177, 416, 385, 607, 456, +682, 389, 682, 210, 624, -59, 505, -360, +336, -609, 176, -755, 87, -772, -8, -659, +-175, -396, -343, -4, -441, 415, -505, 781, +-583, 1075, -625, 1202, -571, 1072, -444, 757, +-280, 343, -37, -135, 272, -576, 586, -858, +863, -975, 1037, -960, 1038, -831, 900, -618, +635, -393, 175, -214, -397, -73, -868, 68, +-1127, 241, -1225, 436, -1150, 643, -832, 825, +-326, 953, 157, 993, 497, 904, 717, 659, +812, 283, 751, -155, 558, -596, 322, -973, +141, -1229, 35, -1324, -68, -1228, -172, -960, +-237, -615, -285, -212, -331, 237, -334, 614, +-279, 859, -182, 1020, -50, 1112, 73, 1114, +130, 1020, 118, 820, 88, 550, 52, 220, +-4, -192, -44, -647, 4, -1037, 104, -1305, +175, -1423, 196, -1351, 164, -1093, 80, -693, +-18, -212, -87, 272, -108, 686, -56, 1009, +14, 1229, 62, 1321, 91, 1262, 56, 1075, +-99, 777, -312, 357, -449, -157, -456, -650, +-362, -1008, -168, -1242, 162, -1295, 512, -1087, +706, -698, 737, -292, 662, 74, 434, 343, +75, 448, -281, 411, -538, 286, -676, 147, +-698, 87, -574, 154, -328, 323, -78, 546, +102, 747, 266, 867, 416, 856, 476, 658, +423, 261, 308, -265, 177, -823, 24, -1330, +-134, -1708, -241, -1855, -283, -1662, -297, -1132, +-254, -390, -124, 441, 50, 1267, 204, 1914, +288, 2212, 268, 2114, 170, 1654, 43, 936, +-106, 126, -258, -636, -360, -1251, -352, -1578, +-229, -1596, -52, -1402, 115, -1058, 273, -607, +397, -166, 423, 197, 332, 462, 179, 607, +30, 664, -112, 654, -280, 575, -436, 454, +-475, 363, -403, 304, -281, 268, -116, 240, +100, 206, 343, 140, 567, 7, 692, -193, +653, -426, 469, -661, 189, -876, -124, -992, +-424, -963, -687, -791, -847, -498, -821, -104, +-640, 343, -384, 791, -92, 1172, 212, 1396, +495, 1429, 699, 1263, 804, 898, 830, 374, +771, -218, 595, -780, 303, -1189, -91, -1388, +-487, -1397, -743, -1209, -863, -839, -916, -413, +-827, -26, -531, 301, -162, 543, 139, 735, +372, 885, 576, 949, 663, 933, 566, 870, +404, 690, 295, 358, 173, -59, -20, -488, +-208, -856, -305, -1081, -286, -1115, -202, -934, +-101, -550, 43, -96, 225, 294, 319, 567, +244, 690, 32, 623, -230, 411, -469, 137, +-657, -120, -739, -261, -597, -258, -224, -167, +197, -26, 520, 162, 735, 324, 883, 379, +885, 307, 658, 165, 331, -1, 97, -178, +-78, -319, -314, -381, -554, -364, -702, -283, +-769, -171, -798, -113, -752, -85, -565, -40, +-222, -34, 192, -56, 571, 13, 823, 154, +925, 305, 896, 475, 694, 601, 333, 601, +-9, 486, -196, 277, -312, -32, -429, -342, +-473, -562, -387, -678, -277, -676, -249, -551, +-228, -367, -108, -180, 39, -16, 106, 92, +128, 169, 122, 248, 48, 333, -87, 410, +-201, 472, -221, 494, -116, 455, 85, 312, +343, 54, 610, -222, 793, -430, 818, -559, +652, -579, 311, -443, -115, -185, -513, 106, +-832, 324, -1030, 422, -1067, 404, -957, 265, +-751, 12, -480, -258, -139, -450, 257, -539, +617, -500, 869, -339, 1059, -95, 1177, 175, +1127, 417, 875, 583, 499, 666, 78, 661, +-339, 559, -707, 393, -958, 204, -1053, -1, +-1016, -216, -871, -431, -649, -651, -392, -822, +-111, -907, 187, -907, 439, -791, 620, -514, +736, -115, 784, 350, 768, 801, 649, 1122, +397, 1274, 103, 1244, -99, 973, -225, 515, +-324, 56, -384, -339, -366, -635, -288, -766, +-235, -743, -269, -635, -352, -477, -412, -349, +-415, -342, -358, -401, -250, -429, -36, -390, +300, -279, 631, -49, 842, 324, 943, 776, +898, 1160, 646, 1364, 262, 1364, -111, 1150, +-402, 700, -606, 69, -696, -577, -655, -1092, +-519, -1404, -369, -1506, -226, -1356, -115, -982, +-70, -507, -55, -37, -4, 370, 114, 643, +274, 765, 410, 805, 481, 763, 487, 647, +402, 521, 251, 404, 125, 247, 47, 60, +-32, -134, -87, -312, -72, -454, -49, -547, +-136, -553, -347, -450, -564, -296, -705, -156, +-759, -5, -670, 125, -371, 169, 63, 154, +506, 135, 877, 97, 1100, 50, 1109, 7, +883, -44, 467, -58, -10, -14, -400, 43, +-663, 112, -792, 254, -779, 408, -634, 473, +-404, 422, -159, 266, 46, 17, 207, -287, +319, -585, 364, -785, 366, -791, 339, -614, +286, -341, 216, -38, 112, 272, -56, 496, +-214, 535, -288, 432, -301, 319, -317, 202, +-298, 59, -162, -27, 32, -23, 176, 3, +273, 9, 353, 10, 346, 9, 241, 21, +115, 29, 3, 13, -114, -14, -207, -76, +-240, -213, -237, -369, -236, -485, -212, -562, +-123, -518, -35, -284, 9, 59, 65, 405, +171, 731, 255, 933, 267, 916, 230, 719, +172, 400, 95, 8, -12, -349, -106, -579, +-119, -686, -73, -675, -44, -565, -50, -410, +-85, -262, -135, -108, -196, 51, -261, 190, +-288, 301, -215, 403, -41, 477, 158, 467, +340, 376, 483, 224, 524, 36, 399, -149, +183, -291, -2, -384, -145, -392, -295, -307, +-392, -185, -372, -64, -286, 70, -200, 201, +-126, 274, -38, 296, 57, 281, 129, 221, +182, 113, 259, -16, 324, -158, 287, -292, +141, -397, -18, -449, -105, -427, -158, -347, +-202, -200, -173, 19, -60, 266, 28, 481, +57, 658, 65, 749, 36, 696, -60, 509, +-157, 228, -181, -103, -131, -410, -46, -636, +46, -747, 149, -694, 223, -507, 235, -285, +207, -98, 178, 51, 109, 144, -9, 177, +-110, 167, -156, 158, -205, 202, -289, 301, +-329, 383, -262, 404, -115, 378, 47, 294, +196, 144, 315, -39, 389, -192, 378, -287, +253, -332, 70, -344, -56, -333, -107, -320, +-168, -318, -232, -294, -200, -237, -90, -145, +-58, -13, -135, 151, -203, 300, -172, 398, +-86, 430, -2, 415, 102, 381, 248, 331, +385, 275, 414, 231, 302, 171, 116, 25, +-54, -197, -199, -453, -316, -696, -363, -863, +-278, -871, -71, -687, 129, -336, 226, 105, +271, 514, 286, 809, 171, 936, -76, 856, +-305, 598, -429, 285, -498, -12, -503, -269, +-365, -451, -98, -523, 191, -517, 443, -477, +645, -407, 738, -270, 699, -37, 560, 231, +336, 469, 47, 647, -229, 724, -451, 619, +-622, 326, -726, -91, -727, -522, -635, -844, +-474, -975, -252, -884, 5, -590, 266, -146, +501, 329, 662, 713, 708, 919, 670, 925, +564, 749, 363, 446, 99, 86, -130, -260, +-307, -515, -454, -619, -526, -591, -497, -487, +-393, -299, -251, -47, -75, 166, 116, 263, +278, 284, 343, 231, 271, 93, 97, -67, +-76, -183, -186, -232, -258, -180, -271, -36, +-140, 114, 129, 235, 385, 323, 525, 331, +545, 216, 446, 38, 212, -124, -103, -232, +-401, -279, -583, -245, -612, -127, -537, 39, +-399, 200, -216, 288, -10, 297, 181, 223, +337, 59, 441, -169, 507, -372, 556, -496, +551, -535, 409, -467, 114, -282, -231, -28, +-549, 207, -810, 385, -934, 486, -816, 500, +-488, 444, -69, 363, 355, 289, 721, 246, +917, 218, 876, 157, 649, 31, 323, -179, +-12, -451, -265, -721, -386, -916, -424, -987, +-427, -853, -393, -504, -327, -43, -293, 397, +-283, 765, -212, 1002, -64, 1020, 113, 844, +294, 585, 471, 315, 589, 34, 586, -208, +444, -368, 218, -459, -31, -528, -251, -572, +-389, -550, -415, -429, -336, -229, -179, -12, +-11, 186, 93, 345, 130, 429, 100, 372, +-20, 198, -208, 6, -364, -121, -399, -174, +-297, -154, -118, -63, 111, 67, 404, 181, +688, 217, 827, 172, 776, 93, 602, 28, +336, -27, -26, -53, -420, -55, -708, -55, +-836, -77, -853, -118, -768, -175, -568, -239, +-298, -254, -15, -180, 242, -51, 435, 61, +557, 157, 609, 236, 584, 253, 480, 180, +352, 79, 235, 18, 110, -6, -26, -10, +-110, 19, -125, 78, -157, 122, -223, 131, +-293, 98, -376, 40, -471, -39, -514, -139, +-493, -251, -434, -352, -310, -423, -83, -436, +206, -364, 461, -208, 646, 10, 773, 251, +832, 482, 770, 636, 583, 663, 328, 559, +59, 363, -225, 118, -518, -121, -749, -291, +-840, -377, -813, -391, -719, -360, -532, -301, +-262, -250, 10, -220, 217, -188, 376, -125, +493, -32, 552, 95, 538, 232, 463, 337, +378, 381, 313, 349, 245, 251, 138, 124, +24, 25, -71, -27, -186, -30, -362, -2, +-510, 44, -550, 66, -531, 8, -508, -137, +-439, -317, -275, -477, -49, -585, 179, -594, +368, -479, 521, -237, 611, 83, 614, 418, +555, 697, 466, 874, 333, 915, 148, 804, +-61, 552, -237, 206, -359, -153, -462, -471, +-551, -712, -569, -845, -491, -828, -361, -682, +-201, -460, -29, -215, 135, 27, 255, 230, +294, 369, 273, 429, 244, 401, 234, 329, +218, 267, 192, 222, 185, 163, 227, 124, +262, 124, 207, 127, 72, 98, -64, 50, +-185, -1, -311, -59, -420, -117, -467, -173, +-451, -230, -419, -280, -374, -329, -283, -414, +-145, -504, 2, -537, 157, -485, 332, -353, +530, -108, 711, 261, 791, 661, 734, 976, +544, 1144, 239, 1120, -129, 859, -472, 417, +-747, -99, -896, -550, -859, -815, -636, -835, +-298, -648, 67, -321, 390, 30, 610, 259, +660, 289, 519, 112, 268, -219, -5, -594, +-245, -862, -405, -926, -445, -749, -354, -354, +-156, 183, 75, 738, 268, 1180, 403, 1436, +453, 1466, 392, 1270, 257, 877, 107, 371, +-53, -163, -221, -651, -364, -1059, -444, -1331, +-458, -1409, -403, -1282, -264, -979, -72, -539, +123, -15, 311, 488, 475, 864, 534, 1040, +463, 1007, 306, 770, 116, 383, -88, -60, +-268, -439, -376, -648, -394, -638, -353, -435, +-293, -96, -214, 316, -117, 677, 3, 887, +132, 880, 245, 656, 323, 256, 399, -235, +454, -722, 404, -1090, 232, -1256, 14, -1192, +-177, -910, -334, -469, -442, 56, -443, 564, +-318, 955, -171, 1142, -62, 1120, 34, 920, +110, 593, 117, 186, 63, -210, 20, -507, +28, -667, 57, -689, 67, -598, 71, -418, +79, -208, 88, -25, 87, 83, 99, 140, +142, 164, 210, 162, 261, 153, 241, 168, +130, 217, -58, 260, -292, 267, -541, 215, +-750, 107, -816, -52, -657, -215, -347, -346, +6, -405, 376, -367, 734, -253, 954, -112, +941, 33, 746, 158, 465, 201, 133, 162, +-238, 103, -550, 73, -690, 61, -669, 78, +-581, 129, -453, 183, -249, 189, 11, 138, +211, 45, 281, -72, 297, -175, 319, -230, +295, -218, 210, -153, 136, -64, 105, -1, +84, 13, 31, -32, -57, -108, -134, -169, +-166, -179, -187, -129, -218, -18, -209, 150, +-125, 321, -4, 430, 77, 438, 121, 380, +135, 266, 88, 116, -2, -41, -74, -179, +-122, -303, -145, -419, -103, -519, -12, -595, +80, -609, 164, -531, 273, -333, 372, -16, +379, 401, 286, 833, 163, 1162, 17, 1294, +-200, 1183, -458, 823, -652, 256, -698, -395, +-607, -972, -415, -1345, -128, -1473, 238, -1335, +558, -961, 712, -452, 692, 42, 547, 420, +298, 647, -11, 726, -285, 679, -417, 575, +-372, 504, -223, 483, -56, 504, 84, 550, +182, 566, 199, 458, 114, 216, -30, -122, +-151, -521, -232, -924, -283, -1221, -271, -1322, +-168, -1226, -17, -952, 107, -548, 183, -61, +232, 415, 270, 799, 272, 1026, 208, 1108, +87, 1076, -44, 928, -153, 672, -236, 372, +-273, 82, -227, -196, -96, -426, 46, -583, +156, -657, 240, -662, 283, -593, 248, -475, +137, -336, -13, -186, -140, -41, -209, 69, +-236, 154, -242, 252, -233, 340, -190, 387, +-109, 387, -12, 364, 63, 305, 140, 200, +235, 41, 307, -125, 310, -259, 234, -354, +117, -397, -8, -380, -138, -282, -261, -117, +-295, 91, -199, 283, -47, 433, 66, 521, +139, 518, 198, 366, 191, 77, 67, -242, +-97, -518, -189, -725, -221, -818, -241, -713, +-217, -424, -103, -40, 43, 339, 131, 661, +151, 859, 172, 882, 207, 742, 208, 504, +185, 226, 183, -69, 187, -343, 130, -560, +10, -692, -131, -765, -266, -776, -407, -698, +-515, -511, -527, -233, -429, 98, -240, 435, +24, 716, 309, 884, 541, 884, 687, 736, +714, 491, 610, 209, 415, -50, 174, -222, +-93, -299, -342, -289, -513, -228, -590, -189, +-593, -229, -541, -352, -441, -511, -309, -674, +-152, -784, 39, -773, 243, -591, 417, -248, +550, 225, 623, 745, 602, 1209, 481, 1529, +283, 1618, 36, 1431, -208, 1001, -389, 404, +-462, -281, -410, -922, -277, -1400, -120, -1633, +25, -1595, 140, -1308, 190, -868, 130, -369, +-25, 128, -193, 546, -318, 810, -397, 912, +-394, 908, -269, 795, -45, 595, 213, 370, +452, 170, 620, -11, 708, -154, 704, -240, +555, -262, 256, -233, -67, -191, -281, -161, +-411, -154, -522, -156, -563, -181, -480, -221, +-373, -248, -347, -243, -356, -210, -310, -140, +-211, -35, -68, 96, 154, 249, 457, 398, +766, 518, 968, 589, 991, 589, 811, 466, +453, 212, -23, -142, -506, -513, -875, -822, +-1042, -988, -976, -939, -722, -662, -366, -199, +-1, 342, 298, 832, 476, 1142, 527, 1211, +486, 1005, 407, 567, 309, 23, 211, -481, +127, -872, 33, -1113, -102, -1151, -247, -982, +-357, -665, -434, -283, -451, 117, -357, 493, +-161, 819, 53, 1045, 245, 1115, 409, 999, +491, 737, 429, 368, 269, -87, 89, -538, +-101, -867, -273, -1013, -364, -1001, -370, -833, +-329, -527, -226, -144, -60, 209, 111, 461, +237, 589, 332, 617, 382, 554, 340, 400, +227, 209, 102, 39, -42, -89, -228, -181, +-368, -199, -389, -168, -319, -114, -219, -50, +-90, 9, 64, 16, 194, -18, 251, -48, +220, -100, 135, -187, 35, -245, -72, -215, +-176, -150, -212, -92, -126, -16, 29, 108, +156, 237, 256, 321, 361, 361, 413, 385, +340, 383, 169, 315, -18, 198, -199, 63, +-376, -75, -523, -233, -585, -388, -552, -516, +-465, -597, -337, -620, -141, -569, 111, -442, +369, -228, 582, 82, 712, 429, 743, 738, +672, 927, 509, 946, 246, 774, -84, 452, +-381, 23, -557, -411, -633, -711, -644, -808, +-547, -712, -343, -466, -115, -126, 79, 189, +239, 382, 365, 423, 437, 344, 421, 183, +312, 4, 144, -143, -23, -239, -177, -283, +-337, -282, -439, -250, -394, -213, -219, -154, +-10, -40, 212, 152, 433, 379, 569, 593, +542, 737, 379, 748, 157, 577, -83, 257, +-320, -140, -507, -547, -587, -858, -535, -991, +-390, -926, -233, -703, -82, -365, 98, 7, +278, 337, 369, 580, 391, 727, 418, 750, +415, 654, 320, 488, 177, 268, 56, 5, +-75, -253, -242, -435, -384, -524, -446, -505, +-461, -389, -438, -193, -338, 24, -162, 196, +45, 266, 255, 236, 448, 147, 577, 20, +606, -107, 522, -189, 330, -198, 55, -165, +-225, -99, -446, -21, -584, 61, -613, 145, +-494, 220, -253, 284, 8, 346, 231, 385, +401, 335, 481, 187, 419, -26, 244, -248, +25, -452, -188, -591, -357, -603, -420, -467, +-353, -236, -195, 12, 22, 224, 283, 362, +500, 404, 562, 340, 477, 209, 300, 63, +33, -48, -289, -126, -531, -187, -604, -222, +-542, -192, -391, -95, -147, 34, 123, 191, +308, 384, 391, 569, 395, 640, 312, 555, +174, 321, 77, -41, 20, -485, -65, -897, +-158, -1157, -206, -1207, -239, -1028, -291, -654, +-287, -152, -181, 374, -11, 834, 185, 1147, +386, 1272, 519, 1193, 522, 965, 399, 637, +171, 227, -131, -212, -403, -588, -548, -860, +-575, -1018, -507, -1022, -334, -862, -89, -586, +127, -263, 276, 64, 372, 327, 400, 495, +342, 567, 248, 541, 154, 435, 26, 305, +-138, 193, -280, 82, -348, -22, -336, -104, +-236, -150, -59, -154, 158, -103, 356, -27, +488, 56, 510, 127, 382, 148, 110, 77, +-233, -89, -547, -292, -758, -486, -808, -608, +-670, -604, -366, -435, 24, -129, 417, 250, +743, 593, 939, 827, 942, 913, 738, 813, +377, 541, -45, 175, -417, -186, -685, -490, +-834, -670, -828, -702, -636, -600, -336, -408, +-38, -168, 224, 49, 448, 202, 566, 284, +545, 280, 468, 197, 393, 81, 283, 3, +103, -32, -100, -33, -298, -12, -480, 41, +-608, 99, -642, 108, -569, 57, -360, 14, +-12, 10, 380, 12, 690, 30, 857, 85, +851, 150, 617, 138, 198, 33, -249, -135, +-603, -316, -825, -470, -861, -537, -667, -467, +-302, -259, 105, 43, 445, 346, 650, 570, +679, 657, 552, 594, 316, 395, 18, 129, +-260, -138, -426, -342, -471, -441, -439, -429, +-316, -334, -95, -196, 124, -38, 251, 114, +318, 233, 356, 294, 319, 312, 193, 285, +53, 204, -69, 56, -214, -112, -343, -252, +-372, -372, -327, -451, -276, -430, -179, -314, +3, -167, 201, 4, 338, 183, 433, 335, +494, 427, 459, 466, 304, 446, 101, 371, +-102, 251, -297, 104, -441, -53, -491, -199, +-460, -299, -366, -342, -206, -316, -19, -245, +130, -154, 231, -91, 303, -80, 321, -118, +270, -179, 192, -240, 119, -263, 30, -185, +-58, -11, -96, 219, -98, 458, -88, 670, +-43, 772, 33, 726, 65, 553, 33, 293, +-3, -31, -30, -360, -102, -611, -198, -758, +-232, -794, -201, -704, -146, -488, -62, -213, +64, 74, 180, 324, 247, 504, 279, 576, +284, 517, 252, 348, 178, 129, 63, -78, +-84, -247, -234, -339, -349, -334, -399, -238, +-390, -96, -308, 56, -140, 177, 86, 272, +318, 333, 510, 334, 603, 274, 545, 181, +346, 70, 74, -84, -212, -253, -474, -401, +-649, -485, -681, -483, -568, -390, -356, -248, +-88, -72, 197, 120, 440, 279, 583, 371, +597, 401, 513, 400, 380, 369, 214, 301, +-4, 189, -228, 59, -379, -104, -435, -306, +-442, -508, -396, -622, -261, -599, -81, -440, +78, -163, 211, 182, 318, 510, 349, 714, +292, 738, 190, 564, 70, 258, -61, -79, +-147, -354, -169, -512, -163, -497, -146, -318, +-91, -95, 1, 67, 69, 133, 89, 112, +77, -1, 51, -164, 13, -304, -25, -326, +-64, -205, -97, 5, -110, 233, -94, 440, +-47, 577, 36, 587, 145, 479, 243, 278, +302, 37, 301, -191, 232, -361, 99, -477, +-66, -502, -236, -434, -394, -314, -502, -179, +-502, -42, -379, 80, -209, 152, -46, 179, +127, 161, 310, 119, 435, 93, 468, 115, +464, 151, 463, 195, 391, 244, 204, 255, +-9, 182, -192, 39, -390, -132, -595, -315, +-692, -462, -625, -518, -453, -441, -232, -264, +45, -44, 335, 164, 530, 334, 582, 430, +532, 421, 416, 337, 252, 225, 74, 111, +-85, 7, -185, -55, -225, -98, -245, -151, +-272, -223, -280, -296, -251, -372, -202, -417, +-149, -385, -66, -275, 43, -99, 139, 131, +215, 375, 266, 566, 272, 676, 237, 666, +211, 537, 176, 323, 81, 77, -41, -170, +-119, -395, -169, -562, -237, -643, -281, -626, +-236, -533, -131, -389, -44, -209, 31, -5, +113, 183, 159, 345, 125, 471, 40, 530, +-35, 507, -68, 423, -63, 298, -32, 133, +21, -43, 78, -195, 105, -288, 84, -325, +44, -305, 17, -230, 14, -107, 25, 10, +69, 76, 148, 83, 203, 55, 177, -4, +70, -109, -81, -216, -257, -281, -427, -261, +-541, -168, -548, -24, -445, 140, -259, 319, +-19, 470, 243, 540, 476, 528, 640, 443, +714, 277, 685, 51, 556, -169, 344, -366, +70, -523, -242, -611, -530, -609, -730, -536, +-817, -383, -785, -159, -614, 75, -311, 287, +45, 474, 379, 610, 657, 639, 821, 557, +803, 379, 620, 141, 321, -130, -37, -394, +-386, -597, -651, -669, -779, -596, -737, -421, +-517, -177, -173, 112, 193, 401, 500, 610, +703, 685, 731, 613, 563, 454, 277, 237, +-37, -41, -343, -337, -581, -556, -650, -669, +-541, -690, -326, -591, -62, -366, 220, -68, +452, 235, 576, 505, 582, 668, 473, 675, +238, 520, -72, 245, -356, -91, -568, -391, +-698, -548, -701, -528, -534, -342, -241, -53, +95, 257, 413, 482, 665, 542, 775, 401, +697, 109, 483, -233, 218, -518, -47, -663, +-268, -621, -400, -399, -446, -66, -412, 283, +-317, 543, -210, 682, -136, 681, -85, 537, +-22, 286, 49, 25, 113, -199, 188, -398, +268, -556, 284, -634, 215, -635, 107, -577, +-9, -436, -136, -207, -247, 84, -301, 383, +-270, 647, -159, 829, -2, 890, 147, 802, +268, 571, 362, 252, 407, -104, 369, -438, +246, -683, 77, -789, -127, -783, -352, -675, +-543, -465, -648, -198, -645, 51, -520, 251, +-289, 387, -2, 439, 297, 422, 563, 352, +735, 247, 746, 131, 604, 52, 378, 5, +112, -23, -184, -32, -446, -27, -595, -33, +-606, -52, -506, -71, -331, -93, -93, -118, +170, -146, 386, -166, 492, -185, 477, -191, +348, -175, 142, -110, -95, -1, -308, 127, +-444, 262, -449, 394, -323, 466, -140, 418, +46, 273, 224, 58, 352, -188, 352, -412, +221, -551, 46, -573, -96, -469, -198, -261, +-246, -7, -203, 237, -80, 440, 77, 563, +218, 564, 302, 468, 306, 306, 239, 87, +97, -172, -98, -401, -275, -547, -359, -585, +-370, -510, -346, -316, -252, -35, -68, 255, +115, 480, 201, 573, 214, 504, 184, 280, +101, -20, -6, -325, -65, -555, -52, -624, +15, -484, 111, -201, 211, 128, 282, 438, +286, 657, 201, 719, 17, 599, -201, 350, +-363, 34, -436, -271, -435, -509, -342, -638, +-165, -634, 20, -494, 156, -269, 245, -23, +281, 215, 231, 395, 120, 463, 6, 393, +-68, 221, -100, -11, -78, -239, -16, -404, +42, -449, 83, -334, 134, -70, 172, 255, +130, 544, 26, 740, -64, 766, -120, 578, +-190, 219, -253, -206, -240, -603, -149, -874, +-61, -953, 3, -835, 81, -549, 159, -149, +183, 245, 147, 519, 90, 650, 26, 647, +-25, 525, -55, 316, -73, 109, -63, -36, +-10, -96, 52, -88, 71, -53, 58, -29, +50, -46, 11, -125, -81, -270, -156, -424, +-180, -523, -190, -508, -174, -366, -78, -114, +56, 206, 156, 539, 228, 789, 284, 875, +273, 783, 172, 547, 54, 212, -41, -155, +-139, -453, -218, -641, -224, -718, -188, -691, +-160, -581, -132, -448, -102, -317, -97, -176, +-113, -17, -107, 161, -58, 360, 34, 585, +167, 783, 338, 893, 490, 866, 559, 699, +517, 388, 354, -26, 79, -455, -246, -816, +-543, -1053, -761, -1115, -839, -967, -731, -658, +-452, -248, -92, 191, 266, 578, 551, 833, +695, 933, 656, 864, 460, 631, 172, 296, +-122, -52, -336, -349, -429, -543, -395, -591, +-244, -504, -9, -322, 215, -103, 345, 90, +352, 197, 269, 205, 124, 128, -56, 4, +-235, -114, -350, -171, -364, -147, -315, -50, +-242, 113, -149, 295, -32, 443, 65, 507, +117, 479, 160, 357, 232, 155, 302, -113, +325, -402, 292, -643, 212, -801, 95, -865, +-50, -812, -215, -593, -359, -250, -407, 139, +-357, 516, -262, 843, -145, 1043, 2, 1070, +140, 922, 201, 622, 187, 239, 160, -156, +147, -491, 129, -724, 109, -820, 89, -776, +58, -611, 3, -385, -93, -153, -224, 54, +-333, 209, -370, 279, -332, 259, -212, 197, +-5, 138, 225, 96, 396, 80, 483, 115, +470, 195, 338, 280, 108, 321, -134, 301, +-328, 207, -455, 36, -481, -180, -391, -390, +-231, -534, -50, -590, 130, -551, 261, -425, +314, -216, 301, 31, 237, 254, 121, 409, +-9, 500, -99, 527, -151, 481, -180, 370, +-175, 224, -114, 74, -28, -74, 46, -192, +92, -272, 109, -324, 90, -356, 43, -359, +-20, -359, -93, -364, -162, -342, -209, -267, +-219, -140, -190, 37, -115, 279, 18, 547, +205, 783, 376, 916, 471, 896, 490, 700, +440, 361, 273, -71, -15, -528, -333, -915, +-585, -1140, -741, -1159, -785, -984, -666, -652, +-403, -232, -75, 202, 247, 570, 514, 822, +669, 938, 694, 914, 617, 755, 461, 502, +257, 214, 50, -70, -131, -314, -299, -490, +-434, -575, -498, -575, -490, -492, -439, -352, +-336, -196, -174, -52, 3, 75, 147, 162, +256, 194, 317, 192, 298, 172, 209, 130, +94, 62, 4, 1, -47, -28, -41, -7, +14, 60, 82, 169, 135, 297, 159, 408, +131, 453, 28, 375, -126, 158, -290, -175, +-422, -556, -492, -899, -481, -1107, -377, -1106, +-174, -858, 83, -405, 325, 167, 510, 742, +625, 1195, 643, 1422, 527, 1376, 298, 1088, +28, 615, -226, 64, -458, -461, -625, -868, +-671, -1113, -583, -1175, -407, -1059, -187, -799, +56, -454, 297, -89, 484, 259, 549, 553, +488, 760, 338, 847, 140, 814, -80, 664, +-259, 432, -341, 178, -319, -57, -229, -261, +-99, -406, 48, -464, 155, -463, 173, -444, +102, -412, -12, -357, -126, -288, -192, -191, +-184, -54, -109, 129, -15, 335, 56, 529, +94, 658, 91, 678, 39, 581, -45, 377, +-98, 88, -87, -235, -10, -499, 114, -651, +256, -673, 358, -575, 365, -378, 253, -128, +57, 104, -186, 264, -435, 341, -628, 342, +-721, 270, -673, 165, -479, 74, -170, 38, +183, 42, 514, 77, 771, 119, 894, 136, +837, 109, 605, 27, 249, -112, -167, -278, +-563, -413, -829, -485, -895, -466, -774, -353, +-503, -162, -137, 73, 230, 312, 501, 500, +627, 601, 592, 608, 404, 530, 126, 370, +-138, 143, -318, -104, -410, -332, -391, -517, +-253, -651, -49, -693, 136, -612, 264, -416, +325, -141, 294, 174, 152, 474, -50, 686, +-233, 762, -356, 685, -400, 461, -352, 131, +-202, -207, 17, -474, 239, -612, 398, -597, +448, -443, 376, -196, 215, 74, 8, 301, +-199, 434, -349, 448, -404, 348, -366, 174, +-274, -42, -153, -245, -31, -402, 65, -482, +124, -468, 170, -357, 210, -169, 233, 76, +252, 347, 267, 578, 236, 718, 121, 727, +-44, 598, -215, 339, -367, -1, -486, -367, +-517, -677, -419, -858, -236, -874, -34, -737, +153, -484, 305, -153, 397, 184, 410, 471, +346, 668, 241, 757, 117, 724, -8, 585, +-106, 358, -165, 79, -200, -210, -225, -461, +-237, -625, -230, -669, -203, -580, -163, -362, +-104, -51, -38, 266, 20, 515, 71, 635, +119, 589, 155, 376, 182, 59, 194, -267, +181, -521, 148, -640, 115, -583, 84, -357, +20, -48, -80, 258, -181, 480, -260, 566, +-330, 497, -368, 305, -337, 51, -235, -193, +-94, -359, 60, -406, 215, -339, 341, -194, +388, -12, 341, 154, 239, 270, 106, 312, +-27, 282, -120, 196, -160, 75, -167, -59, +-163, -187, -146, -294, -130, -371, -134, -390, +-140, -344, -110, -240, -57, -80, 6, 134, +86, 351, 167, 516, 195, 596, 157, 568, +75, 418, -25, 179, -121, -94, -171, -349, +-145, -535, -74, -613, 21, -564, 114, -422, +156, -224, 116, -8, 31, 195, -66, 346, +-152, 422, -199, 428, -181, 380, -99, 289, +6, 157, 110, 6, 189, -141, 199, -252, +125, -311, 3, -315, -138, -263, -271, -154, +-363, -18, -367, 96, -257, 150, -79, 138, +133, 76, 354, -24, 535, -118, 596, -173, +509, -164, 304, -80, 26, 67, -287, 227, +-558, 352, -701, 422, -688, 419, -542, 323, +-302, 148, -34, -64, 187, -272, 340, -442, +405, -554, 378, -578, 297, -507, 219, -369, +161, -186, 109, 31, 68, 247, 38, 409, +-22, 509, -142, 549, -270, 523, -373, 427, +-433, 287, -426, 116, -334, -61, -187, -221, +-17, -356, 150, -460, 285, -501, 356, -469, +358, -378, 313, -239, 228, -69, 125, 116, +25, 271, -56, 370, -118, 402, -174, 379, +-227, 313, -242, 226, -213, 134, -183, 47, +-162, -28, -122, -102, -62, -184, -11, -276, +19, -368, 46, -439, 78, -456, 93, -400, +97, -254, 117, -28, 166, 237, 229, 488, +261, 682, 234, 773, 168, 719, 69, 530, +-88, 248, -292, -82, -482, -408, -598, -662, +-626, -805, -558, -816, -376, -693, -98, -473, +210, -198, 469, 92, 633, 355, 687, 538, +645, 620, 497, 610, 263, 536, 7, 415, +-221, 263, -412, 113, -548, -17, -598, -138, +-556, -254, -438, -358, -260, -448, -55, -514, +124, -532, 269, -477, 372, -351, 385, -160, +293, 74, 167, 315, 55, 511, -47, 624, +-132, 647, -164, 578, -131, 432, -86, 231, +-61, 16, -36, -184, 1, -344, 24, -462, +25, -535, 17, -559, 16, -524, 6, -426, +-41, -270, -110, -66, -173, 154, -212, 366, +-207, 539, -136, 636, -16, 623, 123, 514, +235, 330, 293, 106, 276, -119, 186, -316, +61, -445, -75, -477, -198, -426, -255, -336, +-238, -218, -193, -85, -121, 32, -31, 102, +40, 127, 65, 127, 74, 116, 87, 98, +80, 81, 42, 82, 7, 105, -13, 142, +-56, 173, -103, 194, -125, 191, -116, 153, +-73, 70, 1, -46, 73, -179, 115, -304, +106, -407, 49, -462, -29, -440, -111, -338, +-163, -168, -169, 39, -130, 261, -49, 461, +55, 596, 157, 627, 235, 547, 243, 369, +175, 123, 61, -144, -77, -396, -208, -590, +-304, -678, -350, -635, -343, -491, -270, -269, +-145, 2, 7, 281, 153, 504, 277, 621, +356, 612, 357, 490, 300, 285, 219, 34, +99, -200, -61, -363, -207, -417, -311, -359, +-379, -225, -424, -68, -410, 74, -308, 157, +-142, 144, 48, 51, 241, -73, 417, -189, +534, -259, 545, -243, 424, -144, 212, 6, +-48, 166, -315, 308, -539, 390, -670, 397, +-671, 334, -536, 220, -310, 87, -47, -47, +217, -164, 449, -256, 604, -313, 630, -330, +529, -303, 355, -240, 143, -138, -100, -7, +-323, 125, -473, 220, -521, 262, -459, 244, +-319, 167, -137, 42, 43, -98, 169, -199, +198, -230, 133, -187, 21, -86, -76, 51, +-146, 187, -181, 290, -141, 328, -20, 282, +132, 171, 270, 37, 371, -99, 412, -218, +370, -284, 243, -284, 71, -236, -117, -168, +-307, -91, -475, -17, -584, 37, -602, 60, +-525, 62, -367, 65, -145, 69, 114, 69, +338, 72, 491, 88, 541, 101, 478, 104, +325, 94, 137, 78, -42, 60, -184, 37, +-265, 3, -268, -42, -207, -92, -123, -144, +-24, -186, 58, -212, 88, -202, 69, -149, +25, -58, -47, 45, -140, 140, -223, 209, +-275, 228, -281, 190, -234, 109, -114, 13, +59, -69, 232, -104, 365, -90, 440, -39, +426, 24, 316, 72, 127, 79, -87, 32, +-261, -54, -373, -143, -412, -205, -368, -214, +-256, -153, -133, -48, -23, 69, 60, 174, +118, 248, 141, 264, 132, 227, 116, 160, +92, 83, 66, 17, 49, -43, 28, -114, +-11, -194, -36, -261, -47, -315, -60, -342, +-85, -317, -105, -205, -112, -9, -114, 219, +-107, 425, -77, 565, -43, 598, -12, 490, +31, 257, 59, -47, 62, -342, 53, -558, +35, -640, 7, -576, -17, -377, -9, -92, +45, 199, 105, 419, 125, 518, 103, 485, +48, 345, -32, 141, -135, -84, -232, -265, +-288, -359, -298, -350, -281, -264, -216, -136, +-98, -3, 25, 110, 124, 182, 198, 194, +250, 160, 280, 109, 290, 57, 273, 7, +216, -21, 105, -30, -25, -31, -161, -38, +-299, -49, -397, -58, -429, -70, -400, -81, +-299, -80, -133, -50, 52, -7, 225, 39, +345, 85, 391, 130, 345, 153, 211, 146, +19, 98, -188, 20, -362, -68, -444, -161, +-404, -235, -260, -259, -37, -214, 210, -109, +414, 39, 504, 184, 455, 288, 297, 327, +77, 290, -178, 174, -405, 13, -513, -137, +-482, -237, -359, -263, -204, -216, -27, -107, +137, 15, 219, 104, 196, 137, 129, 119, +66, 57, 27, -32, 9, -117, 8, -163, +40, -157, 82, -119, 97, -76, 70, -27, +21, 56, -31, 149, -95, 223, -171, 294, +-209, 371, -184, 402, -129, 337, -62, 172, +7, -65, 66, -336, 96, -596, 87, -774, +39, -804, -28, -652, -95, -354, -136, 23, +-142, 393, -115, 677, -51, 819, 38, 796, +123, 622, 188, 360, 219, 93, 197, -126, +146, -270, 74, -336, -12, -338, -97, -313, +-172, -290, -250, -286, -327, -299, -373, -301, +-354, -265, -267, -174, -130, -26, 54, 162, +245, 354, 395, 507, 470, 575, 456, 547, +348, 420, 157, 211, -78, -31, -285, -246, +-400, -396, -414, -465, -345, -437, -214, -321, +-49, -147, 90, 29, 163, 161, 175, 227, +147, 230, 69, 166, -40, 46, -128, -89, +-172, -194, -172, -243, -135, -235, -68, -169, +24, -53, 137, 100, 239, 248, 299, 350, +299, 386, 251, 361, 142, 279, -41, 147, +-243, -15, -400, -167, -499, -276, -529, -336, +-455, -341, -285, -300, -56, -227, 176, -147, +374, -74, 502, -24, 522, 7, 429, 31, +260, 52, 55, 76, -137, 118, -271, 184, +-330, 247, -309, 299, -230, 330, -115, 337, +-1, 302, 61, 213, 44, 75, -25, -89, +-117, -270, -210, -456, -249, -614, -191, -697, +-40, -671, 145, -541, 307, -324, 423, -41, +471, 278, 412, 570, 244, 769, 10, 842, +-216, 798, -381, 651, -478, 408, -504, 111, +-441, -182, -308, -432, -169, -627, -63, -746, +35, -765, 156, -672, 262, -485, 329, -225, +382, 69, 424, 352, 421, 573, 338, 683, +171, 658, -41, 505, -259, 269, -461, 11, +-605, -199, -659, -321, -606, -343, -454, -286, +-240, -184, -2, -83, 227, -25, 413, -22, +530, -60, 563, -98, 504, -92, 394, -21, +257, 91, 89, 214, -88, 306, -231, 334, +-328, 273, -383, 125, -400, -62, -377, -218, +-318, -307, -244, -328, -159, -283, -73, -182, +15, -61, 112, 27, 209, 69, 276, 83, +322, 98, 347, 121, 320, 153, 234, 193, +108, 224, -24, 231, -152, 183, -268, 78, +-350, -54, -367, -181, -317, -291, -219, -349, +-110, -337, 2, -269, 111, -174, 176, -62, +185, 56, 174, 159, 153, 235, 103, 279, +40, 293, -22, 265, -79, 199, -133, 98, +-166, -16, -170, -120, -156, -192, -121, -219, +-57, -203, 15, -159, 78, -110, 137, -64, +174, -40, 173, -37, 138, -32, 84, 8, +25, 88, -24, 189, -63, 285, -98, 350, +-139, 346, -182, 235, -218, 33, -253, -205, +-256, -414, -195, -545, -89, -558, 35, -438, +168, -211, 293, 59, 374, 306, 373, 466, +280, 514, 131, 453, -37, 306, -185, 118, +-271, -59, -270, -182, -203, -238, -116, -221, +-47, -151, -1, -63, 1, 1, -58, 25, +-134, 7, -176, -61, -165, -152, -96, -227, +40, -244, 213, -192, 354, -67, 410, 108, +387, 288, 289, 421, 124, 469, -84, 412, +-296, 250, -455, 27, -520, -191, -500, -341, +-417, -409, -254, -385, -35, -273, 181, -109, +346, 40, 459, 134, 513, 167, 477, 163, +335, 134, 128, 87, -90, 42, -281, 17, +-405, 9, -451, -14, -410, -48, -298, -84, +-154, -109, -16, -125, 96, -117, 165, -75, +190, -9, 179, 63, 149, 127, 106, 183, +56, 219, 20, 226, -12, 202, -51, 150, +-92, 58, -115, -74, -122, -236, -109, -389, +-68, -491, -13, -505, 38, -401, 77, -187, +100, 106, 97, 412, 71, 656, 40, 759, +4, 689, -46, 456, -103, 110, -157, -270, +-203, -598, -224, -794, -207, -805, -150, -633, +-42, -337, 109, 20, 249, 366, 338, 633, +356, 756, 301, 717, 157, 538, -43, 268, +-230, -43, -348, -333, -363, -541, -273, -629, +-103, -589, 90, -448, 249, -237, 301, -8, +224, 184, 56, 303, -145, 358, -335, 357, +-455, 313, -443, 252, -288, 189, -47, 125, +209, 44, 424, -60, 540, -185, 519, -303, +375, -384, 166, -402, -56, -343, -240, -202, +-358, -4, -391, 194, -336, 328, -230, 368, +-129, 324, -72, 212, -43, 70, -26, -62, +-9, -136, 22, -141, 88, -85, 178, -9, +259, 54, 300, 86, 287, 79, 224, 29, +106, -58, -64, -152, -253, -224, -396, -264, +-462, -279, -442, -248, -342, -163, -174, -24, +28, 143, 224, 312, 389, 457, 486, 545, +489, 541, 397, 431, 224, 235, -14, -14, +-257, -265, -434, -469, -504, -583, -474, -596, +-354, -518, -157, -381, 78, -207, 262, -21, +339, 146, 319, 275, 227, 367, 93, 428, +-59, 438, -165, 390, -169, 286, -88, 151, +10, 0, 89, -141, 143, -249, 148, -299, +76, -284, -59, -221, -184, -143, -252, -84, +-260, -43, -216, -26, -116, -26, 33, -35, +185, -25, 277, 19, 302, 82, 273, 148, +184, 199, 37, 223, -126, 214, -254, 172, +-330, 96, -340, 4, -280, -90, -147, -177, +16, -255, 158, -302, 238, -301, 244, -254, +193, -163, 104, -31, 1, 128, -77, 274, +-94, 364, -52, 376, 23, 326, 92, 215, +124, 65, 99, -91, 15, -209, -114, -272, +-248, -291, -324, -273, -308, -230, -229, -172, +-120, -116, 17, -62, 162, -5, 259, 67, +274, 154, 245, 242, 211, 310, 170, 345, +109, 342, 43, 290, -7, 178, -56, 14, +-130, -173, -233, -352, -315, -492, -339, -576, +-303, -571, -218, -454, -64, -235, 138, 47, +323, 345, 434, 592, 452, 727, 379, 714, +219, 549, 6, 277, -221, -45, -405, -340, +-495, -549, -455, -631, -304, -584, -80, -431, +164, -224, 366, -12, 471, 163, 452, 273, +315, 324, 101, 322, -120, 277, -301, 192, +-395, 84, -371, -31, -224, -124, -19, -181, +169, -194, 296, -152, 329, -57, 251, 58, +81, 143, -118, 167, -296, 114, -393, 2, +-377, -144, -250, -273, -48, -330, 189, -281, +401, -140, 509, 49, 482, 235, 342, 363, +123, 385, -146, 290, -388, 115, -531, -86, +-536, -253, -423, -350, -222, -344, 18, -244, +248, -84, 401, 85, 437, 228, 364, 320, +218, 338, 50, 284, -101, 171, -194, 25, +-215, -134, -172, -274, -98, -376, -16, -417, +43, -391, 58, -288, 26, -126, -42, 46, +-117, 194, -162, 299, -144, 354, -73, 345, +28, 286, 137, 198, 244, 116, 320, 50, +343, -3, 294, -58, 177, -121, 22, -198, +-139, -287, -281, -360, -368, -394, -360, -369, +-274, -279, -156, -123, -29, 68, 103, 259, +192, 412, 204, 500, 164, 494, 117, 392, +81, 224, 64, 28, 77, -162, 105, -326, +128, -434, 114, -471, 51, -424, -55, -313, +-163, -161, -245, 6, -273, 173, -223, 318, +-101, 415, 50, 448, 180, 404, 262, 283, +262, 96, 178, -119, 44, -330, -88, -497, +-195, -585, -248, -552, -222, -392, -127, -136, +-10, 157, 89, 422, 160, 592, 195, 608, +191, 469, 155, 222, 110, -56, 77, -300, +56, -441, 20, -443, -27, -314, -74, -119, +-138, 58, -220, 152, -289, 135, -298, 31, +-245, -112, -144, -220, -2, -240, 169, -142, +321, 48, 413, 272, 432, 448, 383, 507, +269, 418, 107, 208, -74, -61, -228, -314, +-310, -481, -326, -524, -296, -441, -224, -288, +-113, -114, -8, 23, 63, 92, 115, 93, +161, 58, 193, 31, 205, 43, 208, 117, +202, 231, 177, 352, 112, 424, 19, 407, +-71, 282, -148, 72, -216, -194, -245, -463, +-201, -663, -91, -735, 37, -663, 147, -470, +231, -188, 266, 122, 244, 397, 171, 573, +69, 626, -43, 546, -141, 355, -205, 110, +-221, -126, -189, -304, -112, -389, -2, -375, +106, -281, 190, -126, 243, 39, 271, 173, +258, 240, 191, 227, 79, 142, -39, 6, +-142, -154, -227, -295, -285, -382, -282, -396, +-212, -325, -109, -178, 7, 21, 127, 229, +237, 404, 293, 497, 278, 495, 214, 402, +127, 244, 27, 46, -75, -161, -144, -334, +-150, -445, -110, -486, -60, -476, 1, -423, +62, -331, 92, -200, 70, -43, 20, 134, +-43, 312, -97, 465, -114, 556, -79, 551, +-7, 443, 77, 246, 175, -7, 255, -265, +283, -464, 251, -566, 183, -546, 92, -422, +-14, -237, -122, -42, -200, 115, -225, 208, +-208, 229, -170, 191, -120, 115, -38, 41, +62, -15, 148, -43, 201, -41, 237, -16, +244, 20, 211, 60, 151, 96, 91, 116, +58, 98, 45, 34, 40, -57, 33, -164, +28, -265, 18, -341, -17, -353, -84, -291, +-150, -159, -203, 7, -252, 165, -270, 275, +-222, 309, -120, 268, 9, 166, 161, 50, +324, -41, 472, -83, 565, -79, 592, -41, +539, -5, 407, 2, 206, -33, -57, -111, +-351, -204, -610, -277, -768, -296, -822, -259, +-750, -168, -533, -48, -195, 77, 182, 176, +532, 246, 795, 275, 922, 264, 880, 223, +684, 160, 391, 77, 64, -23, -225, -134, +-431, -251, -522, -339, -507, -376, -403, -347, +-253, -264, -105, -133, 8, 18, 74, 154, +100, 239, 109, 249, 114, 198, 121, 104, +155, -12, 211, -121, 251, -179, 257, -177, +255, -125, 231, -42, 168, 59, 77, 152, +-12, 212, -86, 218, -152, 155, -203, 30, +-231, -135, -234, -296, -212, -423, -141, -480, +-26, -448, 122, -323, 266, -131, 370, 87, +414, 279, 389, 400, 287, 434, 142, 382, +15, 270, -72, 132, -112, 9, -116, -84, +-72, -145, -4, -186, 35, -217, 12, -259, +-49, -304, -102, -332, -132, -331, -118, -279, +-36, -168, 110, 1, 264, 179, 369, 319, +400, 384, 345, 368, 195, 267, -6, 99, +-187, -98, -300, -266, -325, -353, -255, -350, +-87, -256, 115, -103, 277, 72, 353, 211, +331, 283, 215, 268, 46, 167, -131, -3, +-254, -191, -279, -344, -206, -426, -72, -415, +79, -318, 219, -161, 311, 6, 321, 148, +245, 225, 126, 234, 4, 181, -82, 101, +-114, 29, -92, -9, -24, -2, 65, 30, +140, 72, 166, 88, 141, 64, 63, -9, +-42, -108, -136, -215, -178, -306, -166, -365, +-93, -373, 32, -329, 173, -251, 292, -155, +375, -45, 419, 80, 387, 201, 288, 308, +160, 376, 33, 400, -102, 368, -216, 283, +-271, 150, -268, -12, -227, -177, -157, -317, +-60, -412, 49, -466, 151, -474, 222, -442, +269, -372, 313, -275, 361, -143, 375, 17, +350, 198, 303, 368, 226, 483, 90, 512, +-92, 443, -260, 281, -376, 49, -426, -188, +-396, -372, -270, -452, -87, -424, 104, -301, +268, -137, 391, 4, 456, 76, 444, 71, +364, 2, 252, -103, 138, -190, 22, -216, +-71, -159, -126, -45, -148, 93, -161, 210, +-156, 277, -116, 267, -58, 183, 0, 51, +68, -98, 138, -232, 170, -332, 171, -381, +163, -376, 154, -308, 122, -192, 84, -37, +67, 135, 59, 299, 36, 420, 0, 464, +-31, 404, -45, 230, -37, -22, -8, -301, +62, -547, 163, -714, 257, -753, 300, -656, +277, -429, 190, -128, 56, 184, -99, 447, +-225, 617, -264, 675, -209, 618, -82, 472, +84, 260, 263, 20, 402, -217, 450, -411, +383, -553, 246, -627, 85, -624, -66, -545, +-172, -405, -210, -229, -161, -37, -37, 137, +120, 278, 249, 361, 332, 380, 356, 340, +309, 268, 178, 172, 11, 71, -124, -21, +-199, -95, -216, -145, -178, -174, -94, -194, +21, -224, 146, -254, 247, -278, 313, -288, +336, -285, 319, -248, 266, -174, 191, -66, +110, 55, 30, 162, -41, 239, -93, 265, +-119, 242, -134, 177, -128, 100, -96, 20, +-39, -43, 23, -90, 88, -119, 141, -150, +175, -192, 197, -240, 211, -288, 198, -314, +154, -302, 124, -228, 116, -101, 94, 53, +50, 191, 30, 281, 36, 292, 34, 222, +6, 88, -19, -79, -18, -234, -9, -329, +-13, -335, -30, -260, -23, -127, 14, 10, +69, 125, 131, 191, 222, 199, 314, 146, +359, 57, 349, -43, 297, -133, 204, -199, +71, -236, -61, -238, -156, -226, -198, -209, +-192, -192, -130, -163, -34, -125, 69, -71, +151, -5, 212, 68, 265, 144, 298, 211, +296, 255, 259, 254, 222, 209, 181, 112, +134, -13, 93, -139, 71, -246, 47, -330, +4, -371, -43, -362, -74, -320, -106, -263, +-145, -206, -150, -151, -102, -102, -9, -41, +120, 38, 288, 142, 454, 254, 570, 355, +601, 410, 539, 393, 376, 286, 131, 95, +-138, -142, -367, -385, -507, -579, -533, -678, +-439, -642, -242, -491, 22, -261, 275, -3, +457, 235, 539, 399, 507, 453, 373, 394, +178, 241, -19, 41, -158, -163, -207, -326, +-163, -420, -33, -422, 143, -340, 321, -190, +434, -3, 445, 175, 345, 293, 151, 326, +-87, 277, -288, 159, -390, -4, -398, -183, +-304, -330, -127, -425, 89, -452, 264, -416, +365, -327, 396, -210, 375, -75, 323, 64, +273, 191, 250, 298, 243, 366, 243, 385, +214, 329, 147, 204, 47, 20, -68, -186, +-179, -382, -252, -526, -264, -587, -207, -538, +-98, -388, 41, -184, 183, 26, 285, 195, +342, 298, 357, 312, 345, 254, 321, 148, +294, 27, 250, -78, 201, -141, 157, -160, +88, -148, -10, -126, -100, -115, -140, -112, +-141, -114, -112, -111, -38, -114, 66, -110, +149, -97, 202, -85, 233, -84, 221, -80, +162, -68, 100, -54, 77, -29, 96, 17, +140, 86, 182, 158, 205, 202, 193, 187, +139, 110, 40, -32, -65, -208, -133, -383, +-159, -521, -147, -578, -79, -527, 53, -364, +202, -128, 324, 132, 384, 358, 376, 515, +299, 565, 181, 503, 47, 345, -72, 128, +-145, -113, -153, -338, -107, -509, -33, -610, +56, -637, 134, -601, 190, -499, 221, -336, +228, -127, 203, 94, 168, 304, 131, 466, +94, 554, 57, 547, 30, 451, 25, 284, +31, 62, 63, -166, 117, -360, 164, -477, +187, -520, 211, -494, 218, -420, 185, -317, +130, -213, 88, -124, 64, -56, 31, -20, +-14, 4, -41, 29, -30, 68, -1, 117, +45, 188, 112, 264, 220, 333, 346, 377, +434, 373, 452, 288, 395, 112, 267, -142, +74, -447, -149, -742, -342, -965, -425, -1051, +-379, -970, -228, -708, 4, -298, 296, 188, +575, 654, 738, 1002, 733, 1156, 590, 1091, +356, 830, 55, 423, -235, -44, -432, -485, +-497, -818, -451, -1002, -318, -1013, -122, -880, +99, -650, 289, -371, 409, -81, 457, 177, +442, 371, 370, 492, 258, 531, 153, 494, +80, 386, 46, 238, 46, 59, 73, -120, +94, -274, 81, -375, 22, -412, -79, -386, +-191, -305, -277, -204, -300, -106, -240, -33, +-81, 10, 154, 17, 406, 0, 592, -37, +680, -67, 651, -70, 501, -40, 280, 9, +48, 55, -159, 84, -286, 87, -287, 68, +-199, 24, -84, -35, 28, -111, 138, -179, +201, -232, 170, -262, 97, -272, 59, -266, +60, -236, 81, -174, 138, -75, 238, 49, +358, 186, 430, 307, 425, 382, 356, 375, +245, 281, 100, 97, -49, -152, -163, -414, +-226, -631, -242, -746, -209, -729, -116, -570, +14, -308, 144, 1, 261, 294, 356, 528, +402, 655, 403, 655, 362, 531, 293, 318, +214, 66, 133, -180, 61, -391, -7, -548, +-61, -627, -95, -629, -110, -553, -116, -419, +-100, -246, -66, -68, -11, 94, 68, 221, +157, 299, 238, 321, 308, 292, 364, 228, +365, 140, 295, 50, 188, -31, 89, -92, +-18, -138, -116, -171, -148, -200, -100, -210, +-5, -199, 103, -184, 203, -174, 265, -169, +253, -169, 152, -185, 15, -205, -106, -222, +-174, -214, -174, -170, -97, -67, 63, 90, +261, 277, 421, 447, 502, 553, 507, 566, +424, 457, 264, 231, 60, -89, -125, -434, +-233, -741, -247, -936, -195, -980, -92, -848, +50, -571, 196, -213, 291, 160, 310, 485, +282, 706, 231, 778, 162, 708, 92, 516, +62, 257, 68, -27, 93, -278, 113, -465, +120, -574, 116, -607, 96, -558, 65, -438, +45, -283, 54, -119, 101, 33, 188, 164, +287, 256, 367, 294, 391, 263, 336, 177, +195, 55, -15, -73, -242, -182, -411, -250, +-480, -259, -428, -214, -241, -119, 36, -4, +342, 96, 598, 144, 754, 128, 774, 42, +660, -90, 445, -229, 188, -339, -61, -396, +-252, -385, -349, -296, -377, -146, -345, 47, +-267, 229, -166, 360, -58, 416, 64, 386, +191, 269, 296, 90, 360, -120, 403, -329, +430, -496, 394, -586, 296, -572, 180, -467, +70, -293, -37, -86, -117, 127, -143, 305, +-100, 420, -21, 447, 50, 384, 105, 248, +143, 67, 150, -117, 115, -283, 65, -404, +28, -467, 21, -454, 41, -377, 99, -250, +171, -105, 230, 35, 273, 146, 297, 207, +284, 216, 221, 181, 137, 110, 53, 8, +-12, -92, -58, -163, -69, -187, -45, -177, +18, -137, 107, -78, 186, -9, 225, 42, +238, 55, 233, 27, 186, -42, 111, -130, +43, -223, 2, -283, -14, -295, 7, -253, +65, -168, 135, -37, 194, 112, 239, 235, +248, 299, 205, 283, 136, 193, 64, 49, +5, -110, -42, -251, -59, -339, -34, -356, +37, -300, 120, -189, 180, -53, 197, 58, +183, 116, 155, 111, 104, 51, 47, -36, +12, -120, 11, -169, 22, -182, 45, -146, +83, -72, 139, 23, 188, 99, 203, 126, +197, 100, 180, 35, 136, -42, 55, -118, +-38, -174, -110, -203, -148, -193, -158, -154, +-110, -101, -6, -50, 123, -13, 249, 1, +352, 4, 412, 14, 407, 27, 335, 38, +219, 38, 99, 24, -10, -11, -92, -64, +-133, -136, -131, -208, -97, -271, -46, -295, +5, -257, 48, -158, 76, -21, 97, 119, +129, 235, 172, 295, 228, 291, 297, 211, +358, 74, 377, -93, 345, -244, 271, -350, +171, -384, 50, -349, -84, -268, -190, -160, +-233, -52, -210, 44, -153, 98, -69, 106, +50, 81, 184, 44, 272, 10, 304, -5, +316, 1, 306, 17, 249, 26, 162, 17, +103, -7, 85, -52, 77, -108, 54, -172, +45, -216, 48, -231, 49, -203, 32, -142, +12, -68, 10, -7, 16, 24, 12, 29, +11, 11, 34, -21, 68, -55, 102, -63, +133, -36, 180, 25, 219, 99, 233, 156, +216, 161, 171, 102, 110, -6, 46, -146, +-22, -288, -92, -400, -122, -440, -96, -394, +-40, -266, 22, -92, 98, 94, 177, 248, +238, 337, 252, 344, 236, 283, 206, 166, +161, 13, 114, -142, 58, -273, 12, -350, +-6, -368, -6, -328, -19, -251, -42, -145, +-49, -28, -26, 82, 7, 167, 52, 209, +119, 199, 202, 139, 285, 55, 348, -33, +382, -102, 370, -152, 312, -172, 211, -162, +88, -130, -40, -96, -169, -78, -286, -87, +-353, -116, -345, -140, -263, -144, -123, -115, +54, -58, 270, 28, 469, 122, 603, 204, +643, 242, 600, 223, 488, 148, 302, 30, +67, -101, -150, -214, -291, -286, -361, -318, +-367, -312, -309, -281, -181, -224, -27, -157, +109, -93, 199, -33, 260, 30, 295, 100, +300, 176, 293, 244, 278, 275, 259, 256, +228, 176, 177, 56, 110, -86, 35, -226, +-44, -338, -110, -392, -164, -372, -188, -288, +-164, -173, -106, -53, -41, 46, 17, 99, +90, 106, 177, 86, 250, 60, 293, 32, +316, 14, 309, 11, 258, 19, 165, 22, +63, 8, -22, -26, -77, -78, -103, -128, +-99, -157, -40, -154, 50, -133, 115, -102, +133, -72, 130, -51, 115, -48, 70, -54, +10, -62, -11, -57, 15, -29, 63, 24, +120, 92, 177, 142, 223, 149, 223, 100, +178, 16, 117, -93, 80, -199, 73, -274, +69, -291, 68, -238, 84, -142, 99, -32, +72, 64, 0, 126, -72, 128, -107, 85, +-113, 24, -74, -29, 18, -69, 149, -91, +273, -95, 358, -85, 392, -75, 371, -78, +304, -81, 194, -77, 63, -56, -40, -19, +-94, 40, -118, 96, -119, 125, -113, 102, +-105, 34, -100, -72, -85, -200, -44, -316, +7, -388, 88, -379, 200, -285, 321, -117, +423, 84, 482, 282, 473, 433, 376, 504, +202, 476, 2, 345, -194, 129, -362, -133, +-466, -387, -472, -594, -373, -709, -214, -704, +-22, -580, 187, -364, 384, -86, 522, 211, +571, 470, 542, 631, 453, 665, 293, 571, +91, 371, -93, 113, -219, -155, -277, -377, +-280, -516, -212, -541, -92, -464, 35, -307, +129, -123, 173, 30, 173, 120, 126, 134, +49, 83, -13, -10, -24, -106, 20, -169, +98, -158, 188, -74, 294, 62, 373, 204, +377, 314, 291, 351, 151, 299, 8, 169, +-129, -9, -233, -193, -266, -351, -221, -450, +-125, -473, -5, -413, 117, -299, 224, -157, +284, -19, 303, 100, 283, 194, 225, 254, +150, 269, 79, 233, 23, 162, -36, 63, +-71, -45, -60, -149, -24, -224, 20, -255, +69, -225, 117, -140, 154, -17, 163, 103, +152, 176, 129, 179, 93, 107, 60, -11, +19, -157, -11, -285, -26, -366, -37, -367, +-47, -283, -46, -135, -21, 41, 16, 202, +44, 309, 87, 340, 149, 306, 202, 216, +232, 91, 233, -44, 219, -158, 165, -232, +83, -253, 8, -245, -44, -217, -62, -178, +-57, -138, -35, -97, 4, -54, 43, -9, +58, 27, 35, 62, -12, 92, -51, 115, +-82, 113, -81, 85, -34, 32, 49, -29, +157, -87, 262, -129, 342, -142, 379, -126, +365, -84, 306, -32, 204, 25, 87, 68, +-17, 89, -112, 74, -192, 26, -249, -47, +-271, -127, -265, -196, -240, -249, -172, -277, +-67, -268, 74, -203, 247, -89, 422, 60, +559, 214, 631, 348, 624, 437, 526, 455, +329, 380, 81, 217, -166, -4, -378, -248, +-518, -464, -572, -610, -520, -658, -387, -611, +-204, -471, 4, -264, 211, -18, 402, 220, +541, 414, 595, 543, 571, 594, 482, 561, +333, 440, 144, 254, -44, 18, -183, -231, +-285, -456, -343, -603, -327, -654, -233, -600, +-94, -453, 39, -241, 147, -1, 227, 215, +261, 364, 243, 415, 179, 379, 106, 274, +57, 142, 22, 15, 6, -79, 12, -131, +38, -138, 66, -122, 74, -101, 82, -91, +82, -106, 57, -136, 23, -175, 5, -195, +8, -181, 15, -126, 21, -50, 41, 38, +49, 122, 31, 184, -1, 204, -33, 176, +-50, 117, -48, 36, -5, -42, 78, -102, +179, -125, 284, -122, 362, -104, 377, -90, +323, -78, 200, -77, 41, -94, -130, -119, +-276, -136, -348, -121, -335, -77, -226, -4, +-69, 77, 88, 149, 226, 186, 323, 186, +352, 143, 304, 64, 210, -37, 120, -137, +38, -204, -28, -224, -58, -199, -51, -147, +-17, -77, 5, -8, 18, 49, 30, 75, +42, 77, 56, 56, 72, 22, 105, -16, +144, -51, 156, -73, 131, -86, 78, -90, +3, -98, -89, -94, -171, -74, -181, -37, +-125, 7, -23, 56, 125, 104, 291, 140, +425, 147, 475, 106, 424, 27, 284, -76, +79, -173, -137, -245, -318, -265, -440, -230, +-467, -144, -400, -40, -255, 58, -67, 127, +133, 139, 312, 91, 428, 3, 479, -81, +465, -134, 387, -135, 273, -82, 141, 14, +3, 115, -125, 187, -225, 208, -270, 171, +-274, 80, -245, -47, -162, -176, -43, -273, +82, -315, 174, -308, 230, -261, 255, -194, +251, -109, 224, -15, 176, 76, 120, 148, +75, 204, 30, 242, -4, 255, -12, 239, +0, 186, 19, 102, 20, -9, 20, -122, +6, -223, -34, -290, -82, -323, -126, -321, +-149, -289, -137, -230, -80, -147, 36, -58, +185, 33, 337, 123, 461, 215, 513, 287, +491, 327, 368, 318, 151, 260, -106, 149, +-328, -1, -458, -159, -500, -296, -442, -386, +-276, -423, -47, -391, 190, -297, 383, -154, +497, -3, 515, 130, 426, 221, 260, 264, +56, 256, -133, 197, -257, 108, -306, 7, +-281, -82, -188, -141, -41, -156, 125, -138, +256, -92, 332, -41, 349, 3, 292, 26, +172, 15, 3, -31, -173, -97, -306, -161, +-360, -201, -312, -192, -191, -124, -12, -5, +194, 124, 375, 236, 491, 301, 519, 300, +447, 217, 269, 61, 21, -132, -204, -308, +-357, -414, -425, -428, -382, -345, -240, -183, +-21, 28, 197, 226, 348, 360, 411, 392, +385, 320, 273, 159, 84, -46, -120, -235, +-245, -359, -280, -394, -256, -344, -172, -218, +-19, -56, 164, 109, 283, 230, 320, 282, +306, 265, 249, 197, 160, 98, 47, -12, +-49, -106, -106, -171, -131, -203, -126, -214, +-91, -196, -26, -158, 50, -105, 86, -54, +100, -5, 114, 51, 126, 102, 116, 131, +83, 132, 56, 111, 25, 73, -5, 27, +-15, -28, -10, -74, 6, -107, 37, -115, +69, -100, 86, -67, 79, -26, 68, 4, +48, 14, 3, 3, -32, -18, -49, -46, +-54, -73, -65, -99, -65, -105, -24, -90, +44, -53, 107, -10, 147, 32, 162, 72, +182, 105, 189, 127, 161, 136, 121, 136, +74, 115, 13, 69, -87, -11, -176, -101, +-198, -197, -177, -284, -131, -344, -55, -351, +60, -283, 186, -154, 262, 3, 274, 151, +237, 265, 162, 315, 62, 295, -63, 212, +-158, 103, -185, -5, -152, -86, -74, -119, +32, -99, 143, -52, 201, -14, 169, -8, +93, -42, 14, -102, -54, -177, -93, -237, +-98, -260, -46, -228, 38, -148, 130, -34, +207, 85, 236, 179, 220, 232, 151, 238, +43, 215, -63, 174, -132, 131, -142, 85, +-110, 40, -55, -7, 29, -60, 111, -130, +160, -211, 148, -294, 89, -360, 33, -374, +-17, -328, -61, -220, -97, -75, -100, 88, +-46, 236, 35, 344, 110, 387, 170, 365, +200, 282, 195, 160, 141, 35, 62, -70, +-3, -142, -59, -186, -101, -199, -134, -197, +-126, -195, -69, -199, 1, -200, 57, -194, +95, -179, 126, -140, 141, -68, 115, 35, +82, 136, 71, 216, 62, 268, 50, 297, +47, 287, 66, 240, 64, 161, 21, 66, +-29, -34, -76, -131, -120, -219, -161, -295, +-187, -351, -163, -386, -85, -381, 31, -326, +149, -216, 235, -73, 299, 88, 311, 247, +262, 380, 186, 460, 101, 468, 15, 394, +-79, 254, -149, 76, -179, -112, -179, -267, +-156, -371, -125, -405, -98, -378, -56, -301, +4, -195, 85, -81, 162, 11, 232, 67, +301, 99, 333, 119, 312, 138, 230, 147, +103, 148, -37, 143, -162, 126, -253, 79, +-300, 9, -295, -71, -235, -139, -156, -176, +-57, -178, 71, -136, 184, -68, 251, 5, +261, 46, 245, 51, 205, 18, 139, -40, +74, -108, 11, -157, -48, -158, -84, -103, +-88, -4, -55, 112, -4, 217, 43, 269, +73, 257, 69, 176, 45, 53, -19, -89, +-111, -219, -161, -304, -148, -318, -87, -258, +0, -147, 116, -15, 243, 103, 318, 189, +327, 219, 284, 195, 176, 114, 16, 8, +-167, -98, -307, -173, -369, -200, -348, -169, +-251, -92, -112, -3, 41, 78, 177, 135, +271, 157, 323, 129, 323, 69, 266, -14, +169, -88, 57, -134, -43, -153, -141, -149, +-213, -125, -224, -86, -180, -40, -98, 10, +-5, 60, 99, 111, 200, 145, 257, 164, +265, 157, 226, 121, 133, 49, 0, -55, +-147, -167, -257, -258, -301, -301, -279, -291, +-189, -223, -67, -110, 72, 30, 193, 165, +278, 270, 324, 318, 322, 303, 271, 227, +176, 116, 69, 3, -31, -101, -138, -185, +-237, -249, -294, -272, -316, -257, -296, -211, +-233, -150, -105, -74, 67, 9, 236, 93, +384, 163, 475, 212, 474, 232, 379, 202, +213, 132, 19, 38, -164, -51, -307, -121, +-374, -163, -364, -174, -269, -143, -126, -79, +20, -8, 153, 40, 236, 57, 244, 52, +177, 24, 75, -13, -22, -52, -109, -77, +-166, -91, -166, -87, -117, -72, -18, -40, +105, 2, 227, 46, 323, 88, 358, 128, +323, 169, 200, 183, 18, 157, -174, 88, +-348, -7, -467, -120, -490, -222, -415, -288, +-259, -291, -53, -235, 188, -132, 408, 1, +542, 127, 583, 210, 520, 219, 364, 163, +145, 69, -75, -27, -249, -103, -371, -135, +-427, -113, -414, -41, -350, 57, -237, 143, +-101, 189, 33, 176, 154, 111, 245, 8, +298, -99, 287, -189, 242, -238, 186, -247, +110, -216, 33, -153, -29, -72, -69, 5, +-92, 58, -90, 96, -49, 122, -4, 146, +10, 163, 0, 177, -36, 175, -85, 155, +-136, 106, -154, 32, -114, -54, -40, -145, +51, -224, 138, -273, 218, -270, 282, -216, +291, -122, 243, -23, 166, 68, 68, 133, +-54, 164, -190, 154, -293, 110, -345, 50, +-360, -7, -322, -37, -234, -38, -106, -11, +44, 27, 211, 60, 373, 80, 483, 87, +509, 67, 442, 24, 281, -33, 66, -91, +-162, -143, -361, -179, -479, -192, -501, -184, +-420, -152, -266, -105, -58, -31, 167, 62, +334, 164, 413, 244, 411, 289, 326, 297, +173, 260, -10, 173, -161, 41, -260, -105, +-308, -233, -278, -317, -183, -348, -52, -312, +66, -218, 156, -83, 221, 59, 226, 181, +162, 263, 54, 287, -59, 251, -139, 157, +-184, 40, -187, -76, -129, -165, -31, -222, +77, -224, 160, -172, 218, -77, 243, 31, +200, 130, 99, 204, -27, 231, -138, 199, +-214, 109, -256, -8, -249, -133, -186, -239, +-87, -297, 34, -271, 141, -163, 224, -6, +278, 155, 289, 288, 256, 364, 167, 351, +44, 250, -97, 77, -235, -112, -337, -281, +-387, -386, -376, -407, -299, -338, -170, -198, +-4, -26, 170, 142, 332, 279, 441, 367, +450, 387, 377, 337, 253, 232, 104, 98, +-59, -46, -204, -186, -293, -305, -337, -372, +-342, -367, -293, -292, -203, -165, -87, -11, +33, 141, 134, 252, 221, 301, 272, 282, +281, 211, 231, 101, 150, -20, 68, -116, +-26, -154, -128, -133, -204, -79, -223, -13, +-189, 43, -130, 79, -48, 79, 41, 50, +88, 2, 85, -46, 40, -86, -13, -109, +-54, -111, -82, -91, -86, -57, -61, -18, +7, 35, 97, 96, 169, 164, 219, 213, +239, 229, 204, 201, 114, 127, -18, 16, +-154, -111, -275, -231, -353, -312, -359, -328, +-305, -264, -189, -132, -33, 31, 131, 190, +272, 307, 369, 361, 401, 332, 338, 230, +191, 80, 17, -82, -149, -218, -274, -299, +-330, -310, -317, -257, -239, -152, -132, -28, +-14, 97, 84, 192, 145, 250, 172, 254, +149, 214, 87, 145, 28, 68, -7, -5, +-26, -73, -38, -131, -30, -173, 3, -185, +23, -173, 15, -129, -13, -62, -29, 20, +-19, 94, -12, 148, -13, 175, -12, 166, +-11, 122, -22, 46, -50, -33, -61, -87, +-47, -102, -43, -88, -50, -47, -40, 11, +5, 71, 53, 109, 78, 112, 86, 77, +81, 19, 63, -45, 28, -95, -9, -109, +-30, -97, -47, -62, -73, -21, -100, 23, +-126, 62, -138, 87, -140, 84, -118, 61, +-47, 35, 55, 16, 164, 5, 248, -5, +289, -6, 275, -5, 194, -1, 63, 0, +-98, 7, -258, 19, -364, 35, -390, 44, +-329, 48, -205, 56, -52, 55, 104, 28, +205, -29, 235, -87, 220, -137, 189, -166, +134, -168, 51, -134, -17, -60, -42, 49, +-56, 172, -80, 275, -110, 332, -133, 321, +-151, 245, -179, 120, -184, -15, -141, -135, +-41, -223, 76, -269, 168, -257, 233, -201, +256, -128, 212, -60, 112, -7, 1, 38, +-84, 75, -143, 116, -177, 155, -166, 195, +-125, 221, -69, 227, -16, 197, 16, 134, +23, 42, -7, -69, -56, -171, -95, -239, +-97, -252, -50, -214, 20, -144, 88, -64, +145, 24, 166, 98, 151, 149, 101, 168, +32, 159, -48, 134, -132, 103, -187, 73, +-205, 47, -182, 33, -119, 19, -39, -4, +20, -40, 50, -83, 59, -130, 51, -166, +28, -175, 22, -141, 42, -61, 63, 43, +81, 149, 88, 229, 81, 274, 52, 272, +-3, 223, -80, 132, -171, 17, -245, -97, +-274, -175, -253, -204, -179, -190, -70, -142, +50, -84, 153, -35, 214, -8, 234, 4, +211, 11, 157, 27, 79, 61, -15, 120, +-98, 197, -156, 269, -190, 302, -200, 270, +-176, 172, -123, 25, -63, -135, -18, -275, +22, -366, 55, -388, 82, -327, 99, -195, +108, -19, 106, 155, 78, 282, 36, 339, +-10, 321, -63, 248, -118, 146, -163, 36, +-178, -67, -150, -130, -92, -145, -16, -106, +53, -37, 104, 36, 123, 89, 98, 114, +51, 110, -9, 65, -80, -6, -148, -80, +-187, -135, -178, -165, -130, -155, -50, -112, +55, -43, 150, 35, 211, 113, 227, 191, +204, 258, 140, 290, 27, 266, -109, 194, +-233, 88, -317, -27, -353, -136, -328, -214, +-238, -247, -105, -234, 36, -189, 167, -120, +269, -32, 320, 61, 313, 143, 250, 199, +156, 237, 30, 247, -111, 215, -237, 135, +-319, 34, -349, -63, -338, -136, -285, -180, +-191, -190, -80, -158, 29, -91, 134, 0, +228, 91, 294, 168, 304, 211, 260, 224, +175, 199, 70, 139, -43, 60, -160, -24, +-262, -107, -337, -173, -369, -199, -343, -184, +-257, -136, -123, -73, 35, 2, 184, 79, +300, 151, 355, 202, 335, 229, 244, 230, +111, 203, -39, 147, -189, 69, -306, -13, +-363, -96, -359, -168, -297, -218, -177, -223, +-22, -185, 124, -115, 219, -27, 258, 71, +242, 163, 185, 231, 98, 255, -21, 231, +-138, 162, -223, 64, -254, -31, -230, -106, +-155, -139, -47, -129, 50, -82, 111, -16, +135, 53, 126, 108, 93, 129, 40, 110, +-30, 64, -98, 13, -154, -35, -181, -70, +-183, -92, -157, -92, -95, -63, -9, -2, +73, 76, 134, 149, 164, 201, 156, 213, +112, 185, 43, 118, -46, 33, -153, -58, +-242, -138, -284, -193, -264, -203, -189, -165, +-69, -88, 67, 9, 164, 110, 196, 195, +168, 239, 94, 233, -3, 178, -83, 93, +-131, -1, -138, -68, -117, -95, -68, -75, +-9, -29, 39, 19, 60, 51, 35, 47, +-21, 11, -88, -47, -153, -100, -191, -120, +-177, -91, -110, -12, -15, 102, 70, 215, +136, 293, 167, 312, 144, 260, 69, 148, +-27, -1, -108, -142, -170, -232, -211, -261, +-213, -244, -173, -186, -104, -102, -21, -4, +65, 85, 136, 157, 166, 213, 147, 259, +90, 287, 19, 276, -48, 223, -124, 125, +-194, -1, -236, -141, -241, -254, -207, -311, +-134, -294, -27, -210, 92, -81, 188, 66, +240, 196, 238, 276, 179, 286, 79, 239, +-47, 151, -170, 50, -266, -44, -313, -99, +-317, -103, -282, -66, -202, -17, -84, 30, +50, 74, 166, 105, 243, 111, 270, 85, +232, 37, 141, -24, 35, -79, -80, -116, +-197, -127, -294, -102, -344, -40, -326, 42, +-238, 131, -97, 210, 54, 252, 174, 240, +239, 171, 237, 69, 168, -31, 65, -102, +-53, -145, -165, -153, -243, -123, -263, -61, +-233, 21, -172, 94, -82, 134, 13, 133, +91, 101, 145, 47, 170, 1, 138, -21, +52, -19, -52, -3, -152, 32, -236, 73, +-280, 93, -268, 79, -200, 34, -94, -13, +22, -37, 128, -30, 191, -1, 198, 46, +158, 98, 92, 141, 15, 156, -71, 136, +-164, 74, -237, -23, -261, -124, -236, -195, +-187, -209, -124, -165, -40, -72, 33, 49, +92, 177, 145, 269, 175, 303, 148, 275, +61, 199, -52, 100, -170, -6, -265, -106, +-291, -175, -232, -182, -121, -133, -1, -52, +87, 30, 131, 89, 132, 107, 93, 94, +18, 65, -71, 32, -140, 13, -187, 11, +-207, 30, -185, 59, -126, 90, -56, 103, +7, 93, 51, 64, 68, 26, 56, -10, +30, -33, 0, -43, -41, -37, -87, -8, +-122, 35, -125, 77, -112, 93, -94, 72, +-62, 25, -16, -13, 18, -26, 21, -10, +-5, 28, -49, 64, -99, 83, -138, 84, +-155, 67, -145, 33, -103, 1, -53, -19, +-12, -15, 31, 11, 66, 51, 78, 84, +70, 97, 39, 88, -31, 60, -125, 16, +-195, -34, -217, -69, -201, -70, -153, -24, +-97, 38, -43, 99, -2, 140, 28, 147, +47, 110, 55, 46, 56, -27, 54, -74, +45, -73, 15, -44, -33, 2, -92, 48, +-153, 85, -219, 106, -276, 123, -300, 123, +-275, 92, -207, 37, -104, -27, 32, -69, +174, -74, 282, -57, 315, -32, 278, 17, +200, 85, 88, 151, -62, 189, -213, 189, +-341, 137, -449, 47, -522, -54, -518, -147, +-416, -195, -240, -184, -19, -121, 199, -22, +369, 100, 459, 204, 455, 268, 358, 285, +200, 262, 16, 216, -168, 155, -329, 64, +-429, -53, -448, -168, -403, -261, -320, -306, +-234, -290, -155, -214, -81, -100, -13, 36, +42, 166, 84, 268, 126, 335, 169, 353, +189, 323, 164, 272, 113, 210, 59, 129, +-13, 37, -107, -63, -185, -154, -245, -227, +-309, -279, -365, -314, -380, -301, -347, -226, +-283, -104, -189, 52, -59, 214, 96, 350, +251, 437, 377, 458, 436, 401, 416, 285, +291, 132, 71, -32, -184, -166, -404, -243, +-554, -266, -625, -245, -590, -180, -459, -90, +-267, 6, -49, 88, 164, 136, 328, 152, +404, 156, 382, 140, 282, 107, 123, 78, +-62, 59, -228, 42, -347, 35, -407, 40, +-398, 55, -312, 83, -172, 107, -23, 108, +98, 82, 161, 36, 146, -31, 65, -102, +-48, -161, -157, -200, -226, -198, -244, -144, +-221, -42, -162, 102, -66, 264, 34, 399, +102, 473, 140, 463, 143, 356, 88, 162, +-11, -74, -117, -301, -221, -460, -311, -505, +-358, -436, -357, -269, -317, -38, -232, 199, +-107, 378, 42, 474, 184, 477, 279, 403, +293, 288, 228, 154, 106, 10, -48, -125, +-201, -229, -316, -298, -379, -310, -393, -261, +-365, -159, -296, -21, -184, 122, -46, 229, +88, 294, 190, 320, 233, 294, 204, 222, +109, 120, -17, 4, -143, -102, -247, -168, +-301, -189, -307, -152, -288, -59, -234, 59, +-137, 162, -16, 236, 92, 257, 149, 217, +133, 136, 53, 24, -38, -92, -114, -187, +-171, -248, -210, -260, -234, -191, -252, -57, +-243, 98, -185, 239, -89, 341, 17, 390, +90, 380, 102, 314, 57, 202, -3, 82, +-51, -36, -76, -152, -84, -247, -92, -290, +-114, -284, -151, -232, -191, -139, -208, -35, +-196, 74, -173, 174, -154, 244, -136, 286, +-117, 316, -98, 313, -54, 269, 11, 196, +60, 95, 70, -33, 42, -157, -9, -245, +-60, -266, -86, -205, -99, -96, -118, 18, +-139, 130, -158, 229, -193, 279, -224, 265, +-232, 185, -221, 52, -185, -88, -130, -193, +-81, -238, -48, -198, -8, -78, 44, 70, +89, 205, 112, 293, 93, 316, 10, 275, +-111, 191, -222, 84, -284, -12, -278, -79, +-214, -127, -128, -141, -64, -108, -41, -38, +-48, 38, -65, 108, -94, 141, -149, 130, +-210, 89, -240, 29, -217, -38, -140, -86, +-30, -112, 71, -117, 129, -77, 118, 12, +40, 129, -70, 245, -152, 339, -188, 385, +-196, 384, -179, 327, -141, 205, -105, 49, +-84, -106, -77, -251, -96, -373, -141, -449, +-180, -469, -194, -400, -198, -242, -183, -31, +-135, 183, -70, 368, -8, 492, 30, 552, +37, 556, 22, 503, 7, 399, -5, 256, +-21, 90, -56, -84, -111, -239, -191, -375, +-270, -467, -328, -477, -348, -405, -318, -277, +-242, -120, -134, 28, -13, 151, 102, 272, +181, 379, 198, 446, 139, 462, 15, 429, +-128, 339, -254, 220, -348, 92, -375, -38, +-324, -143, -240, -212, -165, -256, -95, -271, +-24, -240, 31, -185, 74, -114, 96, -32, +75, 55, 25, 134, -31, 206, -95, 259, +-159, 290, -226, 308, -309, 291, -386, 230, +-417, 143, -391, 42, -315, -68, -179, -159, +-7, -215, 143, -223, 230, -181, 247, -114, +195, -39, 96, 58, -12, 166, -98, 245, +-159, 287, -220, 285, -285, 234, -333, 151, +-334, 63, -299, -22, -250, -72, -204, -90, +-176, -114, -151, -134, -110, -120, -57, -74, +-10, -11, 27, 51, 55, 98, 62, 142, +46, 184, 22, 197, -10, 186, -45, 177, +-81, 165, -134, 150, -194, 134, -242, 94, +-284, 21, -315, -63, -311, -138, -276, -185, +-246, -189, -225, -178, -187, -166, -132, -130, +-67, -56, 9, 38, 98, 147, 193, 268, +265, 394, 268, 508, 177, 553, 6, 477, +-206, 290, -402, 40, -525, -225, -563, -433, +-542, -538, -461, -534, -316, -425, -133, -227, +49, 9, 187, 239, 248, 420, 215, 495, +113, 464, -12, 364, -97, 224, -130, 64, +-160, -75, -205, -167, -240, -188, -255, -132, +-253, -31, -225, 75, -183, 156, -143, 181, +-114, 138, -102, 63, -116, -14, -130, -82, +-114, -126, -82, -138, -60, -117, -55, -48, +-65, 57, -70, 157, -57, 243, -42, 305, +-41, 325, -52, 297, -86, 223, -170, 94, +-267, -56, -321, -177, -310, -249, -251, -259, +-183, -203, -140, -106, -121, 2, -93, 110, +-45, 199, 11, 257, 52, 277, 46, 247, +-1, 175, -56, 97, -108, 35, -148, -9, +-167, -33, -187, -48, -230, -64, -277, -67, +-289, -53, -255, -34, -189, -14, -113, -2, +-57, 9, -9, 59, 31, 158, 20, 259, +-43, 317, -115, 302, -168, 211, -195, 83, +-190, -56, -162, -184, -128, -263, -81, -249, +-37, -157, -40, -24, -94, 106, -173, 184, +-252, 200, -301, 171, -288, 118, -210, 76, +-103, 82, -8, 126, 44, 184, 33, 235, +-22, 231, -101, 128, -182, -58, -237, -272, +-253, -431, -235, -457, -185, -331, -109, -80, +-26, 238, 38, 527, 54, 667, 13, 619, +-71, 409, -164, 117, -247, -156, -310, -332, +-350, -385, -371, -316, -348, -169, -251, -22, +-91, 88, 81, 155, 222, 183, 285, 181, +235, 180, 87, 183, -100, 192, -292, 183, +-446, 125, -524, 25, -509, -76, -395, -149, +-205, -183, -3, -154, 142, -70, 208, 45, +182, 161, 67, 233, -91, 227, -239, 159, +-339, 52, -361, -49, -310, -82, -230, -35, +-148, 58, -64, 150, 19, 204, 79, 194, +96, 130, 54, 26, -32, -89, -133, -169, +-231, -177, -305, -122, -328, -18, -304, 115, +-258, 233, -208, 302, -169, 289, -143, 180, +-121, 20, -91, -115, -62, -194, -26, -200, +27, -137, 54, -25, 33, 114, -13, 259, +-56, 371, -87, 400, -119, 328, -171, 166, +-245, -36, -312, -209, -344, -314, -353, -338, +-336, -261, -287, -102, -228, 83, -174, 225, +-105, 265, -8, 204, 102, 116, 198, 78, +236, 98, 197, 154, 98, 194, -34, 178, +-173, 105, -289, 11, -378, -65, -441, -90, +-460, -53, -429, 12, -361, 66, -253, 75, +-106, 21, 27, -92, 102, -197, 110, -235, +71, -160, 21, 23, -16, 238, -56, 403, +-112, 481, -165, 457, -193, 332, -191, 146, +-157, -55, -114, -222, -97, -315, -114, -308, +-169, -208, -256, -48, -320, 107, -305, 201, +-238, 217, -175, 171, -121, 87, -47, -3, +52, -58, 146, -57, 193, 5, 168, 97, +76, 180, -86, 234, -297, 249, -478, 195, +-554, 66, -521, -96, -410, -223, -249, -253, +-69, -171, 86, -14, 187, 157, 219, 299, +179, 355, 78, 294, -47, 139, -155, -52, +-219, -209, -243, -268, -239, -203, -214, -41, +-201, 151, -230, 286, -286, 316, -338, 250, +-368, 116, -345, -62, -235, -215, -66, -266, +112, -183, 260, -2, 343, 197, 345, 331, +263, 367, 103, 321, -111, 209, -329, 78, +-506, -32, -617, -111, -630, -168, -539, -199, +-395, -204, -233, -190, -69, -149, 59, -83, +120, 17, 126, 154, 109, 298, 88, 392, +75, 419, 68, 376, 58, 280, 25, 162, +-60, 50, -189, -48, -304, -131, -373, -203, +-409, -272, -408, -315, -353, -306, -253, -234, +-148, -100, -70, 88, -34, 279, -34, 418, +-47, 456, -55, 372, -40, 207, 7, 35, +63, -79, 96, -103, 91, -32, 37, 94, +-53, 197, -148, 206, -233, 93, -329, -108, +-411, -298, -422, -386, -366, -325, -302, -124, +-264, 133, -234, 341, -180, 412, -68, 322, +105, 121, 293, -65, 421, -136, 423, -59, +260, 125, -18, 315, -311, 397, -545, 317, +-652, 96, -600, -184, -433, -401, -233, -464, +-57, -337, 49, -71, 68, 228, 17, 417, +-50, 413, -94, 232, -110, -29, -103, -243, +-73, -311, -3, -200, 77, 50, 93, 351, +13, 570, -129, 601, -294, 418, -410, 83, +-419, -288, -326, -552, -178, -602, -34, -416, +38, -70, 3, 276, -101, 472, -201, 458, +-229, 275, -170, 10, -72, -203, -3, -264, +21, -152, 16, 68, -6, 287, -5, 404, +37, 377, 57, 231, -25, 27, -203, -146, +-392, -230, -510, -229, -520, -187, -426, -125, +-265, -45, -98, 50, 18, 145, 65, 220, +94, 261, 151, 261, 209, 213, 216, 112, +141, -16, -20, -133, -209, -186, -342, -151, +-377, -40, -338, 104, -288, 217, -275, 233, +-282, 138, -254, -13, -163, -139, -34, -172, +74, -78, 104, 106, 34, 277, -75, 350, +-142, 274, -132, 67, -55, -170, 43, -306, +91, -283, 46, -118, -61, 116, -181, 299, +-282, 343, -342, 233, -355, 33, -348, -157, +-324, -240, -264, -176, -160, 4, -22, 216, +111, 357, 184, 350, 185, 203, 126, 11, +21, -135, -106, -187, -210, -158, -244, -88, +-220, -8, -171, 71, -129, 129, -118, 141, +-145, 109, -202, 64, -267, 38, -292, 42, +-262, 67, -207, 60, -120, 2, 16, -68, +169, -90, 272, -35, 254, 92, 98, 225, +-120, 296, -278, 281, -316, 183, -283, 34, +-231, -115, -180, -203, -166, -200, -178, -110, +-184, 1, -178, 59, -162, 23, -138, -78, +-107, -157, -34, -129, 88, 32, 186, 270, +176, 491, 57, 581, -104, 492, -238, 266, +-280, -8, -233, -247, -173, -377, -157, -386, +-173, -288, -189, -123, -183, 24, -165, 92, +-152, 74, -126, -3, -68, -71, 4, -38, +67, 116, 107, 335, 68, 505, -57, 523, +-186, 368, -232, 127, -180, -105, -92, -276, +-65, -349, -140, -321, -243, -225, -269, -101, +-195, 11, -80, 67, -7, 69, -25, 61, +-90, 99, -123, 206, -107, 332, -69, 377, +-21, 280, 8, 89, -14, -95, -62, -203, +-107, -230, -142, -197, -176, -133, -201, -27, +-200, 106, -162, 200, -107, 218, -65, 162, +-50, 61, -56, -7, -86, 5, -145, 48, +-197, 75, -204, 65, -144, 29, -23, -2, +118, -9, 204, -21, 172, -56, 20, -72, +-188, -46, -366, 15, -455, 89, -428, 154, +-294, 192, -113, 210, 28, 190, 93, 120, +87, 22, 28, -83, -48, -162, -89, -174, +-84, -120, -54, -5, -14, 142, 18, 255, +8, 284, -72, 201, -190, 24, -305, -184, +-359, -317, -336, -308, -268, -179, -178, 2, +-85, 178, 3, 316, 95, 400, 173, 411, +189, 338, 123, 211, 9, 59, -85, -66, +-157, -140, -233, -203, -297, -278, -331, -338, +-322, -359, -249, -282, -124, -78, 12, 165, +100, 347, 104, 434, 58, 443, -16, 373, +-121, 251, -234, 117, -309, -19, -309, -134, +-217, -179, -52, -169, 128, -144, 238, -94, +238, -27, 177, 43, 89, 110, -32, 149, +-215, 111, -462, 13, -671, -75, -729, -118, +-609, -115, -327, -52, 48, 54, 370, 164, +510, 268, 468, 319, 350, 287, 211, 196, +58, 85, -96, -13, -262, -84, -424, -137, +-528, -161, -550, -164, -477, -156, -322, -131, +-146, -99, 11, -47, 144, 43, 243, 176, +271, 315, 217, 382, 106, 334, -61, 196, +-258, 12, -402, -126, -422, -180, -307, -184, +-103, -136, 109, -48, 249, 45, 257, 108, +135, 133, -56, 108, -237, 53, -361, 34, +-403, 73, -359, 101, -261, 82, -161, 6, +-70, -111, 20, -167, 72, -136, 77, -57, +63, 57, 54, 173, 65, 240, 70, 260, +21, 222, -75, 123, -200, -11, -335, -134, +-398, -179, -325, -133, -155, -39, -11, 33, +59, 58, 79, 62, 37, 72, -48, 90, +-124, 108, -183, 96, -194, 57, -135, 4, +-33, -56, 62, -67, 67, -25, -58, 25, +-232, 75, -321, 92, -256, 54, -96, -2, +64, -52, 168, -52, 184, 32, 125, 160, +25, 262, -127, 277, -298, 189, -423, 15, +-438, -178, -309, -296, -82, -296, 106, -197, +150, -48, 69, 57, -50, 94, -126, 132, +-117, 190, -55, 254, -12, 296, -18, 277, +-51, 182, -64, 42, -40, -92, -15, -195, +-66, -259, -196, -264, -302, -238, -285, -166, +-137, 0, 55, 187, 172, 326, 144, 404, +-14, 380, -206, 243, -297, 60, -246, -133, +-159, -265, -140, -286, -166, -219, -168, -110, +-104, 10, 33, 94, 183, 114, 281, 134, +286, 195, 180, 259, -12, 280, -220, 225, +-383, 74, -477, -88, -479, -214, -372, -299, +-227, -296, -120, -210, -41, -79, 43, 92, +142, 268, 213, 369, 216, 356, 166, 232, +73, 76, -39, -36, -119, -81, -178, -84, +-253, -84, -353, -100, -446, -135, -450, -146, +-296, -101, -15, -5, 246, 134, 357, 270, +291, 333, 111, 324, -74, 218, -170, 23, +-172, -147, -145, -227, -172, -216, -287, -118, +-404, -5, -397, 21, -216, -20, 50, -64, +254, -48, 316, 77, 266, 277, 154, 417, +-5, 408, -164, 255, -268, -23, -337, -307, +-393, -444, -389, -403, -295, -218, -128, 51, +72, 260, 250, 349, 341, 342, 301, 246, +101, 92, -165, -49, -318, -134, -313, -160, +-240, -124, -173, -50, -159, 6, -221, 12, +-279, -6, -216, -38, -17, -34, 215, 56, +340, 193, 268, 301, 78, 349, -81, 309, +-183, 145, -217, -97, -181, -294, -136, -370, +-128, -332, -173, -208, -247, -81, -267, 13, +-189, 114, -50, 227, 55, 320, 84, 362, +57, 312, -11, 172, -45, -3, -6, -155, +35, -231, -1, -236, -122, -189, -249, -89, +-270, 48, -160, 151, 8, 170, 113, 131, +77, 77, -61, 58, -197, 101, -231, 146, +-147, 114, -49, 30, -42, -68, -107, -154, +-183, -205, -225, -226, -178, -206, -52, -123, +66, 15, 134, 187, 171, 353, 142, 433, +31, 405, -87, 285, -170, 102, -239, -89, +-246, -218, -181, -269, -107, -241, -62, -134, +-67, -47, -103, -62, -121, -108, -106, -83, +-82, 6, -68, 140, -64, 253, -37, 267, +30, 206, 89, 142, 62, 66, -38, -30, +-142, -105, -209, -146, -160, -104, -34, 43, +11, 182, -43, 204, -107, 138, -129, 37, +-76, -32, -4, -36, -24, -55, -128, -138, +-187, -187, -154, -152, -91, -84, -35, -24, +-64, -22, -198, -77, -267, -54, -152, 141, +67, 392, 253, 548, 273, 527, 122, 332, +-63, 92, -169, -79, -140, -192, -53, -296, +-71, -382, -202, -393, -286, -300, -259, -154, +-191, -16, -142, 72, -132, 119, -152, 167, +-132, 234, -16, 288, 131, 262, 218, 157, +180, 41, 25, -28, -74, -35, -1, 2, +90, 29, 62, 54, -107, 87, -363, 96, +-529, 58, -475, -17, -242, -108, 12, -202, +122, -255, 72, -239, 14, -178, 55, -86, +116, 32, 68, 124, -64, 207, -193, 298, +-242, 340, -171, 328, -75, 257, -14, 79, +17, -123, -23, -200, -103, -146, -119, -12, +-85, 121, -53, 140, -23, 24, 16, -111, +33, -195, 10, -221, -71, -187, -214, -144, +-303, -90, -276, 31, -221, 149, -180, 177, +-142, 137, -83, 64, 78, 83, 297, 276, +431, 491, 396, 553, 157, 395, -196, 33, +-433, -379, -435, -647, -326, -717, -250, -599, +-246, -330, -278, 18, -247, 326, -64, 493, +187, 479, 374, 317, 430, 112, 267, -18, +-46, 1, -256, 90, -294, 90, -274, -20, +-240, -147, -202, -238, -158, -219, -104, -99, +-75, 29, -89, 147, -100, 211, -28, 166, +126, 94, 272, 72, 325, 67, 212, 35, +-57, -45, -349, -125, -535, -179, -521, -196, +-336, -126, -139, 22, -11, 150, 67, 192, +126, 167, 176, 124, 180, 109, 98, 106, +-62, 59, -237, -28, -311, -73, -236, -96, +-64, -111, 74, -66, 65, -1, -46, 82, +-109, 205, -85, 238, -41, 130, 15, -36, +87, -225, 50, -304, -144, -175, -348, 24, +-454, 128, -444, 109, -293, 8, -21, -76, +262, -20, 428, 134, 404, 243, 196, 281, +-53, 267, -179, 168, -188, 49, -183, -56, +-209, -164, -267, -231, -297, -235, -228, -198, +-88, -137, 53, -77, 120, -12, 85, 69, +-25, 137, -134, 179, -175, 142, -112, 69, +-11, 62, 56, 120, 78, 205, 1, 259, +-161, 208, -244, 55, -142, -145, 44, -288, +146, -286, 87, -202, -117, -116, -374, -57, +-475, -32, -291, -21, 76, 14, 389, 131, +402, 297, 84, 398, -298, 371, -453, 182, +-291, -88, 22, -264, 197, -330, 104, -293, +-177, -138, -410, 47, -371, 172, -78, 216, +212, 182, 288, 88, 154, -60, -50, -167, +-126, -127, -16, -5, 70, 134, -28, 231, +-197, 232, -333, 142, -370, -8, -242, -167, +-54, -293, 16, -342, -25, -225, -51, 25, +-40, 261, -4, 414, 74, 385, 121, 164, +90, -60, 51, -141, -2, -115, -110, -65, +-243, 7, -314, 49, -251, -37, -115, -135, +4, -145, 94, -112, 74, 38, -83, 239, +-183, 299, -143, 233, -56, 83, 12, -103, +0, -177, -118, -127, -204, -45, -92, 7, +142, -16, 291, -53, 258, -16, 6, 82, +-365, 156, -522, 186, -389, 170, -193, 60, +-24, -51, 51, -95, -18, -160, -51, -152, +87, -24, 274, 49, 305, 91, 132, 129, +-98, 82, -287, 18, -368, -11, -284, -46, +-142, -45, -96, 10, -175, 86, -245, 145, +-184, 157, -55, 104, 58, -68, 130, -249, +128, -273, 106, -136, 85, 82, 62, 273, +85, 322, 107, 220, 8, 43, -189, -90, +-359, -147, -421, -144, -350, -37, -183, 34, +-27, -3, 40, -18, 31, -43, -26, -102, +-99, -57, -136, 62, -124, 173, -64, 256, +46, 252, 175, 143, 286, -26, 318, -138, +209, -154, 27, -130, -166, -85, -369, -58, +-494, -90, -480, -98, -372, -21, -205, 138, +-17, 312, 110, 376, 109, 305, 34, 84, +-25, -202, -28, -343, 88, -309, 219, -190, +174, -19, 10, 107, -136, 123, -170, 57, +-34, -1, 76, 20, -23, 79, -233, 177, +-406, 263, -419, 222, -234, 118, 38, 4, +209, -178, 146, -308, -73, -307, -253, -231, +-256, -78, -56, 93, 187, 182, 309, 184, +286, 162, 90, 132, -156, 121, -225, 146, +-134, 94, -43, -97, -55, -257, -207, -301, +-415, -244, -484, -37, -279, 187, 127, 281, +435, 302, 426, 277, 150, 204, -202, 123, +-392, -4, -286, -191, -38, -385, 116, -478, +104, -393, -10, -196, -122, 16, -134, 206, +-14, 337, 124, 394, 156, 442, 63, 486, +-176, 389, -458, 102, -537, -211, -370, -486, +-108, -678, 137, -606, 260, -327, 210, -23, +91, 301, 60, 537, 132, 507, 211, 322, +169, 106, -38, -126, -304, -230, -506, -100, +-565, 78, -440, 112, -206, 42, 33, -109, +208, -289, 250, -297, 190, -104, 110, 119, +75, 287, 82, 327, 87, 219, 41, 78, +-103, -32, -296, -124, -407, -162, -348, -127, +-133, -54, 79, 48, 107, 155, -9, 187, +-141, 58, -180, -162, -24, -284, 245, -185, +344, 73, 155, 279, -185, 299, -474, 176, +-472, -33, -125, -217, 252, -189, 339, -6, +149, 128, -148, 126, -330, 34, -232, -59, +49, -73, 203, -14, 56, 61, -234, 160, +-405, 259, -322, 199, -44, -50, 191, -260, +209, -342, 93, -322, -8, -122, -41, 159, +-26, 261, -10, 150, -47, -24, -147, -95, +-168, 20, -24, 226, 79, 372, -11, 369, +-144, 215, -216, -58, -216, -340, -106, -444, +14, -345, 28, -150, -43, 99, -123, 283, +-80, 272, 110, 69, 270, -246, 258, -411, +82, -271, -121, 16, -269, 303, -331, 521, +-230, 519, -60, 264, 44, -60, 79, -217, +11, -154, -109, 4, -201, 121, -250, 76, +-155, -117, 36, -337, 157, -475, 215, -394, +208, -91, 103, 211, -26, 370, -138, 356, +-223, 222, -219, 88, -117, -33, -31, -57, +-54, 81, -111, 222, -149, 254, -135, 160, +33, -77, 266, -323, 319, -427, 160, -365, +-130, -198, -421, -14, -471, 141, -245, 218, +58, 249, 273, 263, 290, 168, 84, 0, +-167, -124, -234, -193, -94, -106, 80, 126, +152, 252, 78, 183, -122, 0, -295, -179, +-297, -259, -113, -168, 80, 75, 81, 263, +-59, 249, -174, 102, -157, -151, 38, -354, +284, -309, 376, -131, 235, 90, -65, 305, +-328, 352, -421, 220, -336, 70, -146, -13, +30, -47, 136, -79, 120, -83, -4, -70, +-76, -85, -68, -103, -25, -120, 56, -100, +84, -28, 53, 52, 24, 170, -29, 287, +-89, 299, -165, 223, -291, 66, -342, -87, +-205, -151, 67, -213, 298, -234, 339, -183, +211, -133, 13, -31, -140, 83, -162, 103, +-123, 119, -107, 128, -136, 93, -215, 112, +-202, 182, -36, 203, 70, 141, 51, 23, +16, -165, 15, -345, 60, -362, 130, -258, +203, -86, 219, 195, 75, 403, -126, 396, +-236, 193, -298, -152, -373, -379, -434, -361, +-361, -222, -129, 55, 128, 366, 338, 436, +468, 309, 441, 119, 249, -102, -14, -230, +-152, -196, -93, -110, -42, -15, -137, 110, +-306, 116, -453, -41, -479, -125, -257, -109, +148, -133, 429, -114, 382, -52, 107, -15, +-143, 53, -199, 145, -55, 248, 164, 345, +247, 338, 96, 244, -164, 155, -335, 45, +-274, -117, -26, -307, 192, -448, 215, -510, +44, -469, -206, -314, -361, -114, -306, 120, +-91, 346, 135, 432, 223, 425, 122, 423, +-74, 355, -169, 260, -66, 193, 164, 78, +373, -122, 376, -354, 111, -517, -234, -502, +-428, -319, -448, -145, -337, -99, -115, -126, +55, -136, 47, -43, -27, 223, -77, 521, +-72, 696, 51, 711, 257, 473, 417, 65, +411, -257, 206, -455, -117, -538, -386, -442, +-444, -264, -278, -73, -26, 111, 141, 174, +98, 114, -151, 56, -399, -24, -376, -143, +-48, -131, 323, 50, 457, 236, 301, 314, +6, 229, -245, 15, -245, -114, 25, -74, +241, 48, 202, 174, 14, 203, -180, 73, +-241, -125, -127, -273, 22, -334, 56, -337, +-68, -306, -202, -193, -207, 0, -139, 197, +-58, 334, -1, 393, 1, 368, 45, 293, +188, 201, 354, 55, 407, -146, 263, -291, +19, -271, -224, -145, -392, -57, -386, -87, +-281, -188, -169, -278, -31, -211, 32, 86, +-25, 442, -46, 648, 30, 575, 145, 199, +244, -270, 285, -560, 244, -649, 92, -516, +-126, -105, -260, 391, -278, 630, -243, 503, +-192, 168, -128, -184, -31, -377, 67, -319, +168, -47, 256, 302, 229, 483, 102, 316, +-64, -64, -251, -440, -269, -700, -75, -744, +93, -444, 129, 192, 89, 805, -7, 983, +-144, 723, -171, 259, -19, -253, 138, -616, +134, -674, -29, -395, -226, 76, -261, 410, +-111, 383, 64, 88, 163, -242, 164, -489, +100, -518, 38, -142, 53, 460, 148, 772, +163, 625, -23, 233, -289, -172, -423, -459, +-320, -571, -84, -475, 116, -192, 197, 164, +120, 404, -33, 391, -101, 233, -14, 58, +185, -195, 314, -345, 180, -202, -81, 41, +-232, 200, -253, 241, -196, 166, -98, 55, +12, -87, 91, -281, 109, -330, 127, -135, +167, 117, 117, 240, -75, 241, -332, 115, +-398, -104, -137, -261, 198, -291, 375, -164, +336, 122, 91, 358, -211, 435, -379, 437, +-313, 222, -57, -250, 156, -669, 216, -757, +159, -435, 18, 132, -118, 592, -197, 717, +-148, 455, 111, -113, 412, -680, 475, -843, +231, -436, -184, 258, -530, 849, -631, 1049, +-432, 674, -16, -128, 355, -891, 422, -1165, +173, -744, -181, 96, -360, 782, -218, 939, +139, 524, 498, -174, 650, -758, 447, -927, +-29, -525, -465, 251, -580, 901, -383, 1041, +-130, 623, -17, -126, -41, -835, -88, -1088, +-15, -685, 174, 55, 317, 659, 282, 851, +104, 524, -46, -61, -44, -434, 50, -463, +98, -276, -2, 25, -227, 281, -375, 314, +-299, 115, -88, -133, 107, -328, 239, -407, +272, -278, 223, -4, 192, 282, 177, 508, +82, 556, -119, 373, -359, 54, -532, -277, +-490, -491, -187, -565, 206, -460, 447, -122, +458, 275, 248, 473, -53, 405, -183, 132, +-73, -217, 104, -432, 199, -362, 132, -51, +-84, 316, -268, 551, -277, 478, -168, 127, +-48, -263, 51, -543, 122, -592, 152, -305, +111, 152, 25, 483, -33, 523, -65, 252, +-62, -179, 20, -512, 143, -564, 190, -348, +128, 42, -5, 463, -196, 660, -348, 501, +-264, 148, 36, -232, 328, -523, 475, -549, +370, -305, -2, 58, -423, 361, -600, 467, +-389, 304, 39, -44, 339, -369, 385, -531, +244, -502, -2, -216, -200, 273, -211, 642, +-28, 633, 183, 326, 242, -54, 171, -374, +78, -439, -42, -169, -192, 151, -284, 272, +-217, 186, -62, -105, -3, -432, 26, -540, +165, -467, 285, -265, 237, 136, 76, 592, +-79, 774, -152, 610, -153, 253, -54, -151, +132, -410, 200, -357, 53, -98, -172, 127, +-304, 146, -248, -99, -56, -432, 147, -629, +306, -541, 403, -160, 368, 298, 141, 610, +-143, 679, -292, 446, -350, 59, -329, -165, +-99, -133, 208, 33, 306, 158, 166, 52, +-37, -320, -135, -650, -88, -655, 25, -350, +101, 181, 91, 667, 21, 687, -44, 267, +-23, -241, 84, -615, 156, -589, 92, -84, +-28, 548, -51, 887, 52, 738, 130, 137, +84, -600, -44, -1023, -236, -893, -414, -373, +-394, 228, -137, 666, 176, 718, 385, 404, +422, -11, 293, -308, 90, -424, -39, -348, +-62, -90, -38, 224, 29, 362, 53, 247, +-39, -23, -143, -304, -161, -419, -94, -297, +15, 26, 104, 372, 179, 505, 191, 366, +59, 24, -139, -378, -287, -620, -316, -624, +-175, -374, 132, 122, 493, 607, 620, 801, +339, 622, -108, 166, -427, -346, -468, -675, +-180, -671, 262, -345, 547, 78, 475, 350, +80, 364, -377, 170, -602, -83, -462, -281, +-68, -262, 285, -26, 405, 204, 239, 299, +-89, 237, -238, -2, -46, -275, 305, -414, +543, -329, 479, -5, 78, 338, -416, 463, +-645, 323, -469, -14, -65, -439, 312, -691, +496, -490, 361, 81, -20, 625, -335, 815, +-376, 460, -168, -282, 172, -900, 492, -1043, +636, -583, 446, 307, -61, 1028, -568, 1091, +-752, 582, -550, -121, -90, -694, 390, -917, +645, -669, 550, -105, 187, 421, -181, 697, +-308, 627, -190, 242, -35, -278, 53, -754, +106, -936, 151, -639, 176, -54, 181, 515, +146, 879, 6, 910, -253, 617, -439, 91, +-291, -505, 116, -916, 424, -935, 388, -594, +106, -38, -181, 604, -318, 1001, -231, 798, +73, 173, 381, -486, 391, -924, 138, -881, +-30, -375, 39, 275, 136, 743, 87, 779, +-63, 368, -202, -206, -277, -631, -253, -705, +-74, -416, 163, 75, 210, 528, 42, 666, +-86, 458, -31, 78, 136, -290, 319, -473, +427, -403, 361, -175, 108, 44, -227, 95, +-432, -27, -335, -195, -9, -250, 283, -111, +339, 111, 181, 301, -76, 366, -310, 235, +-355, 12, -155, -157, 122, -250, 315, -224, +359, -65, 262, 151, 131, 281, 20, 218, +-106, 15, -189, -308, -109, -627, 82, -622, +212, -283, 207, 114, 163, 432, 102, 558, +-50, 427, -220, 164, -277, -82, -250, -266, +-175, -334, 44, -196, 378, 19, 576, 170, +457, 277, 91, 205, -324, -140, -501, -441, +-253, -460, 227, -254, 567, 27, 532, 205, +121, 231, -387, 155, -618, 11, -410, -118, +99, -108, 504, 28, 523, 137, 226, 128, +-145, 87, -328, 30, -192, -70, 160, -167, +465, -235, 471, -193, 135, -69, -308, 10, +-557, 34, -454, 23, -118, -70, 225, -222, +433, -313, 450, -123, 298, 334, 115, 707, +27, 742, 16, 359, 6, -312, -45, -896, +-97, -1023, -117, -563, -82, 204, -6, 715, +49, 705, 50, 261, 37, -338, 41, -672, +33, -563, 28, -156, 106, 362, 237, 769, +264, 724, 196, 185, 128, -417, 14, -751, +-176, -784, -294, -447, -228, 95, -53, 464, +139, 525, 340, 307, 465, 6, 363, -122, +79, -87, -191, -14, -290, 38, -213, 5, +-52, -93, 109, -245, 180, -381, 106, -359, +-33, -219, -128, -64, -108, 94, 59, 257, +290, 353, 464, 320, 497, 209, 379, 136, +140, 98, -165, 35, -403, -87, -451, -233, +-317, -351, -67, -457, 182, -467, 291, -319, +239, -121, 46, 71, -157, 240, -126, 302, +209, 307, 576, 296, 638, 197, 341, 0, +-140, -181, -592, -213, -731, -127, -363, -8, +270, 76, 701, 43, 700, -70, 377, -171, +-31, -261, -361, -249, -495, -133, -313, -48, +83, 5, 408, 94, 504, 209, 352, 224, +28, 83, -295, -69, -447, -134, -366, -171, +-36, -153, 432, -59, 749, 60, 729, 136, +462, 142, 58, 138, -394, 123, -679, 21, +-622, -189, -263, -392, 151, -423, 403, -269, +464, -67, 365, 103, 135, 193, -74, 182, +-121, 88, -14, -16, 156, 19, 266, 167, +273, 200, 238, 33, 166, -204, -7, -370, +-191, -387, -259, -249, -267, 36, -236, 323, +-58, 383, 240, 159, 468, -184, 486, -367, +283, -313, -15, -144, -212, 135, -199, 410, +-38, 339, 200, -38, 448, -392, 523, -522, +295, -326, -96, 105, -411, 454, -524, 514, +-385, 286, -16, -213, 419, -713, 645, -750, +495, -289, 120, 277, -181, 692, -308, 792, +-264, 440, -69, -238, 160, -829, 342, -943, +455, -584, 421, 14, 265, 632, 132, 948, +-8, 733, -191, 126, -257, -563, -172, -964, +-83, -855, 6, -365, 105, 247, 122, 679, +58, 669, -10, 285, -10, -149, 122, -403, +345, -396, 490, -194, 425, 21, 191, 127, +-13, 189, -42, 198, 21, 99, 40, -3, +3, -120, -95, -325, -244, -455, -289, -363, +-128, -123, 137, 151, 327, 334, 352, 364, +248, 218, 131, -58, 94, -306, 110, -386, +107, -249, 145, 26, 238, 274, 242, 358, +176, 246, 158, 26, 125, -192, -33, -340, +-267, -300, -448, -131, -435, -60, -192, -92, +125, -141, 370, -148, 527, -29, 573, 161, +451, 312, 233, 394, 32, 273, -107, -79, +-164, -436, -83, -559, 162, -422, 412, -130, +384, 226, 31, 506, -371, 551, -578, 297, +-476, -171, -65, -596, 475, -718, 837, -555, +801, -209, 393, 249, -114, 653, -410, 744, +-377, 402, -136, -101, 147, -468, 420, -669, +558, -617, 409, -245, 51, 211, -250, 471, +-335, 388, -238, 76, -64, -219, 166, -376, +409, -313, 475, -64, 255, 194, -47, 375, +-131, 396, -7, 174, 167, -108, 312, -303, +371, -448, 289, -495, 87, -299, -145, 23, +-258, 175, -216, 132, -130, 41, -21, -32, +154, -26, 319, 87, 357, 201, 250, 196, +98, 30, 61, -189, 178, -353, 310, -384, +353, -161, 348, 184, 269, 397, 7, 459, +-357, 347, -583, -39, -539, -535, -304, -814, +32, -702, 499, -341, 963, 105, 969, 515, +381, 638, -264, 390, -501, -17, -385, -356, +-91, -453, 312, -275, 637, -5, 615, 262, +229, 475, -201, 483, -366, 196, -254, -187, +-47, -416, 205, -520, 483, -566, 574, -480, +332, -232, -67, 83, -326, 323, -330, 411, +-182, 399, 12, 243, 228, -97, 350, -399, +283, -409, 190, -148, 267, 145, 428, 307, +451, 302, 318, 110, 124, -174, -95, -342, +-256, -305, -248, -112, -112, 29, 15, -12, +28, -87, -41, -89, -24, -67, 156, -12, +358, 76, 413, 121, 317, 35, 151, -198, +32, -378, 68, -321, 265, -53, 459, 291, +446, 581, 193, 656, -132, 386, -377, -109, +-495, -532, -365, -742, 27, -746, 407, -516, +554, -146, 507, 187, 299, 405, 26, 546, +-93, 534, 5, 281, 175, -75, 257, -389, +186, -581, 35, -501, -43, -154, 15, 201, +134, 376, 211, 296, 225, 4, 197, -352, +133, -520, 37, -324, -17, 65, 25, 389, +128, 555, 235, 414, 236, -16, 72, -395, +-107, -554, -104, -497, 93, -193, 360, 202, +536, 378, 490, 268, 172, -23, -223, -328, +-346, -386, -155, -186, 53, 12, 129, 121, +190, 114, 266, -64, 307, -121, 331, 106, +358, 330, 327, 339, 165, 155, -74, -147, +-166, -421, -29, -506, 103, -357, 82, -86, +-6, 132, -86, 219, -133, 149, -47, -11, +202, -161, 501, -256, 629, -283, 445, -212, +142, -23, 33, 186, 157, 276, 290, 302, +266, 334, 99, 236, -112, 1, -298, -243, +-357, -394, -214, -377, 41, -236, 219, -94, +282, 0, 350, 12, 437, -84, 393, -200, +186, -227, 22, -154, 17, -40, 118, 145, +277, 355, 426, 449, 435, 366, 293, 139, +55, -127, -253, -315, -469, -377, -463, -322, +-281, -217, 24, -116, 396, 24, 651, 115, +641, 81, 390, -18, 96, -158, -37, -251, +-3, -188, 111, -22, 290, 170, 454, 304, +404, 274, 120, 120, -207, -83, -397, -249, +-352, -309, -76, -280, 278, -157, 544, 87, +563, 283, 291, 223, -41, 7, -191, -162, +-129, -285, 76, -304, 331, -114, 493, 94, +472, 176, 281, 171, 22, 56, -180, -127, +-219, -265, -71, -335, 147, -276, 302, -10, +339, 333, 250, 477, 90, 336, -28, 82, +-46, -242, 54, -529, 229, -487, 336, -154, +295, 139, 195, 241, 132, 149, 117, -86, +154, -304, 208, -307, 176, -17, 3, 345, +-213, 490, -304, 305, -130, -129, 252, -556, +558, -673, 554, -415, 300, 24, 34, 405, +-104, 537, -62, 297, 197, -153, 532, -441, +612, -457, 354, -211, -2, 228, -260, 549, +-382, 523, -307, 179, -19, -350, 274, -767, +355, -796, 242, -449, 114, 65, 92, 454, +170, 552, 271, 356, 324, 5, 298, -248, +241, -238, 197, -44, 185, 136, 225, 171, +233, 64, 98, -120, -82, -264, -130, -255, +-102, -199, -138, -162, -180, -138, -93, -176, +71, -159, 267, 83, 549, 381, 769, 487, +657, 394, 281, 146, -12, -207, -77, -484, +5, -498, 158, -323, 280, -63, 192, 206, +-80, 303, -308, 176, -355, -36, -172, -281, +175, -485, 408, -451, 379, -139, 272, 231, +252, 436, 322, 469, 453, 307, 568, -5, +477, -218, 103, -244, -340, -182, -571, -64, +-473, -31, -104, -157, 373, -245, 721, -235, +747, -176, 410, -53, -137, 104, -584, 192, +-607, 144, -174, -24, 444, -165, 945, -138, +1079, 9, 735, 171, 120, 340, -381, 420, +-556, 241, -393, -93, -14, -412, 354, -633, +486, -680, 370, -556, 147, -298, -68, 41, +-199, 321, -157, 479, 81, 501, 339, 349, +447, 137, 465, -65, 473, -221, 378, -199, +148, -31, -84, 72, -193, 29, -178, -122, +-66, -334, 165, -527, 386, -532, 360, -246, +103, 159, -100, 437, -75, 457, 102, 244, +258, -41, 372, -228, 463, -215, 358, -17, +10, 199, -265, 275, -216, 142, 58, -133, +364, -345, 566, -388, 551, -243, 252, -7, +-188, 133, -437, 66, -282, -175, 129, -397, +472, -354, 571, -66, 432, 313, 139, 614, +-168, 567, -298, 168, -138, -269, 209, -500, +465, -439, 519, -88, 439, 306, 229, 385, +-42, 115, -147, -251, -23, -559, 159, -642, +250, -349, 202, 57, 65, 286, -47, 326, +-29, 201, 107, 14, 251, -29, 325, 64, +327, 161, 231, 167, 37, 35, -113, -167, +-77, -319, 161, -365, 461, -302, 571, -95, +367, 146, 49, 238, -164, 167, -198, -18, +-10, -270, 326, -388, 521, -277, 360, -36, +-49, 257, -396, 454, -442, 398, -204, 84, +178, -299, 556, -517, 756, -478, 641, -209, +319, 205, 92, 515, 102, 491, 206, 159, +253, -251, 195, -458, -43, -432, -401, -295, +-598, -84, -388, 105, 139, 127, 637, 26, +814, -74, 631, -120, 237, -126, -156, -75, +-305, 81, -56, 294, 428, 424, 746, 347, +666, 107, 222, -156, -331, -333, -621, -423, +-496, -494, -103, -517, 351, -358, 643, -88, +621, 172, 392, 447, 165, 575, 53, 393, +41, 49, 58, -239, 71, -355, 111, -252, +141, -48, 103, 109, 29, 136, -5, 15, +57, -155, 185, -272, 294, -277, 323, -164, +268, 7, 146, 109, 35, 116, 57, 120, +197, 172, 286, 190, 244, 96, 128, -101, +-25, -332, -161, -503, -161, -509, 14, -234, +277, 230, 513, 572, 596, 565, 454, 223, +163, -224, -100, -513, -231, -561, -204, -315, +-40, 168, 141, 514, 233, 462, 261, 141, +275, -207, 264, -424, 261, -416, 258, -237, +194, -27, 99, 132, 62, 157, 73, 16, +85, -104, 101, -100, 136, -85, 152, -39, +73, 76, -59, 167, -110, 201, -5, 163, +195, 23, 382, -89, 501, -142, 525, -231, +417, -291, 200, -254, -2, -185, -103, -99, +-133, 27, -151, 86, -109, 55, 36, -3, +205, -58, 303, -13, 338, 193, 324, 392, +223, 417, 48, 219, -76, -181, -34, -585, +163, -797, 412, -712, 575, -278, 540, 314, +274, 685, -97, 670, -364, 346, -380, -113, +-143, -499, 176, -610, 367, -354, 361, 88, +238, 407, 72, 399, -76, 98, -77, -296, +142, -569, 412, -566, 523, -200, 444, 354, +246, 717, 74, 683, 80, 316, 200, -188, +245, -569, 160, -612, -87, -381, -419, -74, +-537, 165, -237, 173, 284, -85, 650, -316, +668, -312, 404, -136, 62, 147, -145, 444, +-100, 581, 186, 443, 579, 97, 793, -263, +642, -466, 213, -473, -258, -315, -555, -120, +-596, 33, -379, 127, 58, 85, 473, -64, +577, -165, 414, -143, 205, -61, 55, 67, +-16, 252, 57, 397, 291, 331, 513, 38, +511, -353, 297, -659, 53, -679, -98, -384, +-158, 85, -153, 526, -59, 724, 89, 534, +193, 79, 214, -329, 205, -495, 191, -446, +171, -223, 167, 55, 216, 195, 301, 165, +279, -9, 75, -237, -149, -325, -150, -232, +87, -65, 400, 170, 582, 380, 467, 380, +98, 190, -230, -37, -286, -235, -75, -333, +238, -260, 400, -119, 292, 10, 49, 156, +-130, 206, -147, 78, 16, -58, 284, -157, +520, -274, 595, -333, 454, -290, 180, -173, +-41, 10, -92, 224, -14, 404, 91, 462, +110, 287, 23, -38, -92, -306, -130, -415, +-31, -347, 166, -82, 348, 218, 468, 308, +524, 167, 483, -77, 356, -313, 151, -429, +-98, -368, -271, -180, -245, 55, -76, 205, +100, 193, 239, 68, 342, -48, 334, -45, +204, 88, 93, 254, 65, 327, 75, 201, +135, -109, 250, -401, 323, -482, 288, -275, +156, 57, -5, 231, -101, 154, -86, -111, +-6, -463, 104, -629, 246, -371, 342, 144, +332, 597, 255, 804, 140, 675, 27, 234, +16, -279, 84, -621, 129, -688, 129, -470, +120, -88, 142, 254, 182, 431, 189, 402, +171, 154, 169, -205, 161, -511, 131, -617, +111, -483, 115, -128, 102, 354, 79, 710, +125, 736, 233, 475, 275, 26, 170, -495, +-14, -803, -134, -730, -102, -380, 35, 64, +215, 426, 385, 504, 448, 284, 372, -37, +267, -271, 216, -312, 193, -110, 164, 194, +83, 338, -73, 260, -239, 28, -290, -270, +-167, -481, 108, -461, 391, -250, 481, -6, +336, 141, 98, 167, -48, 133, 53, 98, +391, 97, 692, 138, 685, 198, 316, 158, +-222, -55, -606, -303, -603, -419, -245, -412, +271, -271, 688, 17, 772, 284, 508, 368, +92, 277, -266, 82, -422, -173, -265, -349, +115, -346, 455, -192, 576, 32, 473, 233, +207, 316, -80, 244, -186, 27, -43, -244, +236, -408, 466, -398, 514, -191, 347, 160, +70, 440, -149, 466, -215, 264, -152, -87, +-16, -420, 93, -516, 85, -350, 39, -86, +116, 140, 330, 267, 517, 242, 571, 90, +459, -95, 174, -224, -146, -268, -234, -216, +-33, -68, 230, 150, 349, 317, 297, 300, +147, 127, -21, -74, -122, -208, -134, -248, +-70, -172, 51, -47, 194, 17, 319, -15, +407, -66, 418, -88, 308, -76, 116, -40, +-21, -15, 6, 7, 158, 23, 315, 24, +371, 30, 260, 69, 6, 111, -210, 115, +-229, 49, -74, -54, 131, -150, 258, -211, +219, -189, 67, -91, 7, 9, 139, 55, +379, 38, 582, -51, 620, -131, 417, -119, +53, -36, -291, 58, -441, 136, -339, 151, +-55, 88, 305, -5, 587, -88, 616, -124, +334, -117, -61, -103, -269, -97, -170, -82, +101, -63, 375, -2, 510, 101, 407, 160, +140, 151, -82, 84, -118, -49, -23, -189, +53, -219, 70, -155, 98, -71, 161, -25, +249, -23, 367, -54, 466, -89, 423, -61, +184, 71, -109, 232, -254, 281, -160, 216, +87, 70, 319, -140, 412, -305, 300, -320, +19, -251, -180, -119, -138, 80, 19, 201, +153, 153, 248, 36, 286, -76, 289, -174, +345, -180, 423, -82, 399, 68, 217, 164, +-28, 123, -219, -5, -273, -88, -134, -102, +146, -60, 389, 48, 431, 154, 251, 171, +-17, 54, -170, -149, -104, -316, 141, -345, +384, -245, 458, -45, 325, 155, 79, 233, +-94, 176, -55, 13, 148, -184, 341, -235, +410, -72, 336, 115, 158, 246, -33, 336, +-103, 273, -32, -5, 92, -320, 181, -504, +185, -510, 94, -330, -27, -17, -79, 301, +-10, 466, 176, 403, 373, 109, 461, -256, +417, -432, 304, -323, 162, -79, 45, 191, +-14, 398, -4, 359, 63, 56, 135, -266, +193, -407, 220, -358, 170, -149, 29, 105, +-106, 263, -141, 281, -56, 159, 112, -101, +302, -330, 424, -353, 411, -216, 305, -16, +198, 193, 146, 327, 130, 269, 107, 52, +78, -155, 86, -189, 103, -82, 90, 21, +70, 37, 54, -18, 19, -108, -17, -178, +24, -151, 147, -57, 251, 40, 256, 78, +224, 21, 212, -60, 213, -23, 213, 96, +223, 174, 229, 176, 182, 116, 72, 1, +-38, -171, -102, -323, -84, -327, 49, -186, +233, -53, 383, 39, 421, 134, 273, 174, +-1, 81, -191, -17, -170, -12, 9, 19, +244, 41, 421, 68, 443, 67, 303, 15, +128, -49, 18, -135, -10, -224, 8, -244, +15, -174, 3, -96, 76, -20, 263, 117, +413, 245, 415, 227, 270, 76, 33, -60, +-200, -136, -254, -156, -42, -73, 296, 130, +511, 285, 483, 239, 230, 0, -113, -320, +-306, -532, -224, -504, 57, -238, 368, 137, +549, 428, 500, 469, 292, 263, 91, -65, +0, -312, -25, -345, -40, -199, -38, 4, +-20, 176, 57, 283, 244, 278, 445, 180, +469, 60, 257, -51, -74, -215, -287, -408, +-236, -516, 22, -456, 294, -248, 428, 57, +411, 365, 290, 535, 137, 502, 56, 254, +93, -121, 143, -400, 135, -394, 100, -164, +92, 155, 105, 413, 91, 434, 52, 160, +26, -269, 35, -612, 75, -679, 121, -445, +159, -61, 222, 287, 261, 467, 247, 448, +244, 246, 265, -23, 221, -204, 100, -228, +-14, -153, -55, -59, -38, 46, 11, 136, +105, 165, 199, 126, 247, 66, 258, -48, +235, -231, 157, -393, 72, -385, 37, -177, +44, 115, 86, 339, 158, 349, 202, 103, +146, -234, 66, -383, 76, -254, 144, 75, +182, 417, 178, 567, 144, 391, 116, 12, +148, -315, 232, -482, 289, -479, 233, -307, +57, -60, -149, 89, -250, 118, -165, 91, +75, 38, 332, -24, 513, 5, 533, 131, +334, 222, 21, 207, -208, 84, -219, -132, +6, -324, 353, -316, 590, -117, 541, 143, +182, 293, -265, 219, -505, -63, -395, -383, +-1, -532, 417, -370, 592, 45, 467, 443, +174, 601, -70, 471, -75, 122, 134, -295, +360, -518, 422, -443, 310, -181, 150, 99, +29, 275, -65, 273, -147, 99, -216, -114, +-221, -222, -75, -205, 205, -119, 486, 14, +586, 100, 439, 106, 171, 83, -20, 57, +-20, -1, 137, -47, 274, -45, 245, -43, +75, -49, -98, -25, -123, 4, -10, -39, +118, -117, 172, -158, 153, -109, 107, 20, +108, 176, 169, 284, 263, 273, 319, 104, +245, -177, 87, -442, -47, -546, -94, -387, +-25, -35, 154, 367, 356, 644, 456, 616, +367, 248, 122, -234, -130, -549, -269, -565, +-257, -293, -93, 101, 187, 348, 423, 284, +428, 6, 237, -285, 76, -377, 32, -202, +58, 110, 142, 362, 252, 423, 273, 242, +172, -64, 61, -281, 27, -316, 27, -172, +17, 50, 22, 185, 28, 141, 38, 5, +85, -152, 154, -289, 203, -312, 219, -164, +202, 55, 173, 228, 164, 351, 154, 382, +127, 262, 94, 12, 82, -226, 68, -381, +42, -416, 60, -281, 125, -26, 160, 189, +159, 292, 136, 268, 60, 74, -11, -193, +20, -347, 163, -288, 284, -80, 277, 192, +154, 395, -27, 396, -178, 152, -144, -187, +118, -400, 432, -392, 583, -196, 453, 87, +116, 323, -220, 336, -358, 112, -232, -188, +74, -385, 364, -395, 462, -200, 324, 94, +76, 312, -112, 348, -166, 205, -57, -6, +162, -161, 345, -169, 392, -52, 313, 85, +144, 123, -46, 50, -170, -99, -153, -270, +3, -345, 183, -230, 297, 3, 330, 214, +274, 321, 152, 237, 71, 11, 75, -198, +85, -243, 4, -109, -131, 113, -210, 252, +-141, 206, 96, 9, 394, -217, 560, -298, +475, -181, 182, 43, -128, 225, -193, 261, +8, 113, 244, -97, 315, -259, 206, -345, +21, -308, -127, -136, -174, 69, -93, 210, +52, 291, 151, 297, 232, 237, 324, 118, +363, -40, 270, -194, 58, -267, -158, -268, +-219, -203, -60, -57, 232, 94, 462, 164, +478, 122, 291, 12, 5, -77, -204, -59, +-221, -16, -129, 0, -41, 17, 30, -10, +70, -119, 98, -167, 176, -55, 304, 78, +379, 136, 335, 157, 235, 147, 143, 48, +72, -79, 31, -133, 9, -99, -38, -39, +-82, 28, -74, 53, -21, -10, 47, -89, +73, -150, 57, -209, 47, -188, 86, -10, +178, 154, 279, 175, 329, 121, 330, 65, +270, -20, 153, -90, 30, -55, -80, 65, +-164, 149, -162, 116, -31, 36, 165, -36, +295, -93, 263, -138, 114, -145, -74, -143, +-211, -154, -192, -169, -6, -154, 224, -67, +370, 71, 396, 194, 336, 238, 223, 218, +64, 147, -54, 54, -51, -52, 29, -99, +100, -37, 156, 62, 174, 89, 61, 32, +-179, -78, -346, -246, -274, -391, -43, -404, +209, -241, 413, 6, 511, 230, 430, 340, +226, 317, 76, 198, 63, 51, 75, -62, +24, -97, -56, -39, -95, 43, -57, 66, +-5, 9, 6, -51, 16, -116, 40, -205, +27, -256, 16, -198, 85, -84, 218, 38, +304, 154, 287, 215, 245, 201, 202, 95, +122, -74, 6, -199, -84, -155, -88, -16, +-25, 106, -7, 181, -37, 190, -30, 70, +22, -159, 80, -348, 129, -358, 185, -167, +215, 102, 153, 340, 53, 430, 56, 270, +133, -103, 167, -442, 127, -535, 67, -348, +38, 23, 41, 376, 48, 495, 21, 321, +-50, 7, -126, -280, -152, -380, -86, -228, +96, 59, 274, 259, 306, 293, 238, 185, +201, -43, 201, -289, 148, -383, 30, -278, +-50, -110, -29, 51, 13, 189, 29, 265, +19, 225, -52, 125, -177, 8, -230, -129, +-92, -228, 187, -208, 400, -101, 401, 0, +250, 76, 94, 115, 39, 107, 79, 44, +157, -8, 199, -16, 110, -16, -94, -55, +-256, -108, -276, -126, -174, -100, -21, -30, +100, 32, 163, 50, 170, 30, 155, 17, +171, -5, 214, -25, 209, 2, 149, 69, +84, 91, 62, 60, 81, 43, 70, 9, +5, -76, -89, -167, -179, -208, -224, -231, +-183, -208, -59, -89, 119, 119, 300, 308, +436, 379, 441, 310, 248, 145, -55, -71, +-318, -272, -405, -354, -228, -301, 146, -155, +460, -14, 515, 63, 304, 85, -22, 95, +-287, 58, -366, -13, -220, -29, 46, 19, +266, 88, 327, 160, 205, 224, -4, 208, +-148, 86, -181, -147, -88, -403, 94, -548, +243, -508, 270, -299, 209, 30, 128, 356, +25, 513, -108, 464, -180, 288, -94, 88, +61, -88, 176, -194, 201, -226, 100, -192, +-85, -124, -199, -66, -156, -55, 2, -66, +185, -49, 284, -31, 230, -14, 62, 47, +-45, 138, -27, 131, 33, 56, 97, 18, +158, -6, 116, -43, -50, -31, -213, 0, +-253, -27, -145, -52, 29, -53, 169, -78, +223, -102, 221, -52, 182, 20, 112, 79, +50, 134, 21, 142, -44, 26, -119, -139, +-66, -216, 77, -212, 140, -166, 32, -51, +-143, 126, -218, 249, -138, 309, 48, 315, +284, 210, 420, -16, 327, -262, 47, -439, +-253, -488, -361, -369, -200, -130, 80, 136, +286, 297, 345, 308, 244, 214, 32, 83, +-191, -31, -280, -37, -189, 50, -34, 120, +72, 119, 97, 34, 75, -149, 70, -349, +90, -421, 96, -337, 117, -113, 123, 164, +41, 363, -104, 401, -179, 260, -109, -26, +49, -294, 190, -351, 250, -172, 187, 119, +-16, 326, -249, 319, -343, 110, -225, -152, +-10, -349, 145, -358, 207, -131, 203, 173, +136, 329, 32, 282, -41, 92, -29, -165, +36, -349, 57, -361, 56, -188, 101, 47, +126, 187, 37, 178, -123, 89, -261, -5, +-317, -43, -272, 20, -120, 141, 122, 236, +339, 234, 408, 135, 313, -13, 127, -148, +-67, -293, -173, -433, -173, -460, -109, -319, +-28, -109, 48, 63, 103, 182, 90, 253, +30, 271, -30, 228, -82, 211, -114, 231, +-84, 214, -8, 114, 77, -20, 106, -167, +38, -299, -52, -370, -87, -374, -61, -311, +8, -172, 109, 4, 201, 123, 228, 207, +170, 274, 69, 256, -52, 142, -167, 43, +-227, -39, -225, -151, -188, -206, -148, -124, +-128, 11, -91, 93, 24, 167, 201, 214, +364, 164, 399, 12, 292, -169, 128, -320, +-27, -353, -146, -236, -216, -56, -259, 92, +-273, 151, -218, 105, -102, 5, 38, -26, +136, 38, 137, 132, 41, 179, -70, 157, +-84, 91, 23, 13, 154, -87, 237, -171, +243, -186, 165, -165, 33, -108, -141, -1, +-298, 89, -338, 76, -250, -17, -112, -117, +55, -144, 213, -83, 244, 14, 87, 89, +-135, 102, -213, 64, -132, 34, 11, 69, +177, 131, 299, 174, 227, 134, -25, -41, +-252, -271, -283, -391, -157, -352, 21, -169, +201, 123, 286, 363, 192, 410, -53, 245, +-316, -46, -455, -341, -370, -484, -128, -425, +104, -186, 231, 153, 250, 443, 201, 527, +135, 372, 130, 95, 158, -173, 74, -314, +-135, -292, -299, -144, -323, 16, -219, 86, +-81, 39, -4, -53, -2, -116, -18, -110, +13, -43, 83, 30, 125, 102, 114, 144, +65, 111, -21, 21, -77, -45, -70, -90, +-60, -113, -64, -96, -42, -54, -1, -19, +32, 30, 24, 114, -43, 184, -109, 195, +-97, 104, -5, -59, 72, -195, 92, -213, +54, -147, -61, -78, -222, -46, -292, -50, +-206, -106, -36, -147, 131, -55, 239, 124, +262, 271, 186, 336, 60, 310, -45, 180, +-102, 21, -154, -137, -236, -287, -309, -357, +-271, -310, -106, -194, 90, -44, 211, 139, +192, 287, 78, 323, -28, 209, -77, 5, +-88, -201, -69, -330, -50, -319, -55, -140, +-57, 84, -20, 220, 64, 257, 125, 196, +92, 72, 5, -31, -86, -65, -187, -66, +-255, -31, -242, 14, -136, 14, 20, -46, +142, -121, 166, -182, 103, -197, 16, -122, +-49, 16, -90, 131, -98, 142, -52, 63, +-8, -32, -13, -67, -23, -21, -2, 110, +-6, 253, -70, 295, -118, 198, -80, 3, +-9, -210, 20, -363, 16, -384, -28, -281, +-115, -121, -194, 16, -168, 86, -32, 96, +111, 102, 175, 133, 144, 174, 31, 205, +-94, 201, -134, 128, -99, -32, -54, -198, +-66, -296, -131, -301, -156, -223, -74, -65, +50, 97, 122, 192, 88, 215, -34, 175, +-155, 113, -188, 48, -89, -43, 34, -176, +52, -265, -7, -257, -40, -160, -43, -1, +-35, 178, -33, 272, -61, 217, -108, 76, +-109, -51, -19, -93, 94, -45, 127, 56, +49, 118, -71, 92, -159, -27, -174, -203, +-156, -359, -148, -372, -143, -206, -118, 48, +-49, 291, 62, 433, 188, 380, 252, 150, +204, -88, 63, -222, -101, -228, -240, -119, +-304, 53, -266, 159, -162, 127, -44, -17, +53, -226, 86, -363, 22, -296, -89, -36, +-160, 256, -155, 435, -102, 407, 16, 169, +181, -165, 286, -381, 240, -348, 49, -144, +-179, 89, -311, 259, -307, 285, -223, 133, +-109, -89, -36, -254, -59, -291, -131, -182, +-123, 37, -7, 229, 113, 305, 151, 234, +146, 22, 125, -214, 48, -321, -50, -257, +-118, -105, -146, 67, -166, 204, -181, 245, +-168, 140, -132, -9, -96, -73, -62, -52, +-25, 2, 10, 46, 49, 37, 69, -43, +40, -138, -22, -198, -74, -184, -116, -105, +-108, 0, -27, 101, 91, 200, 147, 259, +73, 234, -93, 123, -251, -45, -305, -175, +-255, -210, -149, -190, -35, -143, 27, -62, +22, -23, 20, -13, 53, 67, 75, 183, +44, 229, -10, 204, -41, 122, -55, -28, +-60, -172, -45, -259, -24, -264, -51, -180, +-118, -40, -208, 70, -294, 121, -291, 119, +-157, 75, 52, 36, 214, 38, 244, 99, +154, 175, 1, 177, -158, 69, -214, -81, +-125, -234, 18, -349, 109, -357, 127, -223, +72, 11, -96, 226, -374, 310, -588, 266, +-536, 144, -233, -35, 175, -167, 509, -163, +586, -60, 332, 49, -76, 126, -370, 132, +-423, 77, -262, 10, 9, -63, 219, -127, +206, -137, -17, -95, -303, -63, -481, -48, +-459, -36, -219, -16, 129, -10, 375, -18, +375, 12, 175, 99, -79, 181, -254, 223, +-260, 223, -127, 148, 49, 6, 141, -135, +89, -208, -51, -221, -199, -197, -314, -180, +-349, -180, -276, -151, -116, -54, 57, 85, +165, 214, 195, 317, 172, 351, 104, 264, +-6, 90, -96, -22, -133, -46, -136, -65, +-144, -114, -185, -163, -209, -226, -155, -302, +-48, -309, 24, -213, 34, -53, 3, 112, +-36, 264, -71, 375, -60, 426, 18, 392, +79, 270, 13, 84, -120, -118, -186, -302, +-174, -448, -144, -506, -114, -441, -48, -263, +37, -38, 89, 209, 107, 435, 127, 534, +83, 444, -84, 250, -277, 47, -363, -142, +-341, -291, -255, -367, -106, -353, 63, -273, +178, -145, 188, 17, 125, 199, 47, 346, +4, 400, -4, 324, -20, 152, -88, -48, +-174, -231, -229, -348, -281, -356, -302, -260, +-217, -141, -32, -24, 148, 109, 237, 236, +211, 304, 91, 316, -106, 269, -266, 151, +-243, -31, -75, -260, 69, -430, 57, -417, +-94, -252, -241, -53, -239, 151, -94, 312, +99, 361, 222, 307, 170, 191, -44, 25, +-266, -154, -335, -305, -235, -403, -58, -367, +94, -172, 167, 81, 153, 280, 64, 391, +-96, 365, -262, 200, -354, -23, -332, -207, +-198, -311, 8, -323, 225, -218, 346, -29, +286, 189, 63, 378, -185, 457, -323, 342, +-306, 72, -199, -266, -81, -568, -13, -685, +-46, -545, -142, -218, -173, 191, -51, 560, +150, 747, 259, 712, 172, 456, -27, 61, +-240, -299, -390, -506, -357, -585, -122, -535, +146, -360, 281, -136, 253, 109, 96, 354, +-129, 507, -336, 496, -420, 310, -342, -1, +-152, -264, 34, -367, 142, -323, 171, -152, +150, 73, 82, 225, -20, 278, -113, 224, +-202, 21, -286, -215, -297, -346, -165, -351, +49, -214, 222, 63, 258, 328, 120, 449, +-119, 410, -308, 219, -351, -63, -262, -308, +-98, -418, 62, -367, 136, -193, 90, 21, +8, 219, -35, 312, -67, 259, -104, 136, +-97, 9, -55, -121, -29, -197, -34, -175, +-95, -107, -212, -15, -292, 60, -228, 71, +-25, 51, 210, 71, 334, 100, 273, 93, +35, 55, -264, 8, -443, -35, -413, -65, +-219, -75, 9, -77, 179, -83, 232, -83, +154, -42, -44, 13, -274, 59, -391, 77, +-323, 49, -123, 15, 119, 35, 272, 79, +242, 104, 84, 112, -87, 53, -206, -61, +-259, -143, -220, -168, -110, -157, -10, -83, +18, 18, 0, 88, -55, 123, -141, 87, +-159, -21, -79, -76, 11, -2, 37, 113, +12, 185, -48, 156, -103, 22, -96, -147, +-32, -274, 7, -318, -15, -237, -62, -57, +-86, 119, -85, 243, -89, 301, -78, 297, +-45, 246, -34, 184, -84, 81, -161, -63, +-197, -220, -145, -389, -26, -526, 106, -512, +165, -308, 67, -15, -113, 289, -200, 546, +-153, 670, -54, 566, 38, 259, 60, -124, +-17, -404, -139, -465, -184, -305, -122, -25, +-66, 226, -58, 300, -50, 137, -45, -159, +-86, -422, -146, -529, -167, -423, -120, -116, +-18, 292, 119, 673, 228, 867, 217, 739, +57, 319, -155, -218, -288, -690, -310, -934, +-229, -788, -70, -307, 46, 263, -22, 674, +-195, 764, -313, 470, -286, -57, -97, -517, +196, -658, 463, -422, 525, 42, 322, 493, +-44, 700, -423, 558, -665, 132, -647, -339, +-398, -638, -54, -667, 257, -431, 417, -50, +319, 291, 15, 497, -289, 543, -408, 411, +-291, 162, -56, -93, 155, -253, 232, -305, +156, -279, -10, -222, -149, -147, -176, -67, +-154, 29, -175, 163, -203, 283, -167, 317, +-106, 251, -70, 112, -1, -76, 100, -225, +96, -250, -11, -149, -108, -6, -141, 94, +-130, 105, -92, -1, -28, -199, 38, -339, +76, -267, 64, -6, 28, 352, -29, 659, +-123, 735, -252, 541, -382, 167, -437, -334, +-344, -819, -128, -1038, 101, -893, 239, -449, +300, 169, 320, 737, 239, 995, 84, 870, +-50, 472, -145, 9, -292, -345, -446, -516, +-469, -491, -364, -306, -223, -87, -54, 69, +160, 144, 309, 115, 278, 41, 99, 17, +-89, 35, -187, 59, -182, 101, -107, 97, +1, 19, 80, -48, 65, -70, -77, -79, +-236, -74, -280, -61, -255, -56, -205, -5, +-105, 101, 40, 206, 141, 250, 132, 196, +56, 14, -6, -227, -39, -405, -88, -424, +-158, -247, -189, 43, -149, 315, -92, 470, +-69, 468, -58, 310, -43, 100, -93, -84, +-153, -263, -100, -468, 65, -590, 208, -502, +208, -209, 87, 195, -104, 572, -304, 786, +-426, 709, -392, 338, -216, -174, -25, -586, +113, -752, 198, -633, 179, -264, 37, 210, +-141, 556, -233, 617, -186, 423, -42, 92, +117, -208, 181, -357, 95, -339, -112, -227, +-309, -81, -391, 32, -315, 81, -109, 117, +60, 152, 106, 137, 67, 101, 6, 123, +-34, 129, -35, 43, -34, -80, -80, -193, +-172, -305, -227, -344, -188, -238, -47, -22, +134, 237, 265, 461, 284, 557, 143, 484, +-114, 278, -382, -37, -558, -393, -621, -695, +-556, -837, -324, -734, 24, -394, 372, 98, +623, 654, 725, 1084, 621, 1146, 282, 834, +-187, 289, -655, -373, -974, -941, -964, -1126, +-648, -888, -181, -391, 274, 175, 604, 606, +715, 741, 536, 595, 173, 293, -188, -65, +-452, -347, -597, -445, -548, -367, -302, -226, +-32, -54, 112, 144, 119, 294, 67, 354, +32, 377, 37, 378, 82, 294, 124, 84, +92, -239, -50, -539, -264, -681, -420, -636, +-457, -405, -348, -14, -121, 377, 116, 617, +252, 682, 218, 559, 55, 269, -135, -72, +-220, -350, -145, -528, -12, -548, 56, -378, +33, -68, -64, 269, -185, 543, -207, 651, +-71, 470, 62, 54, 49, -321, -97, -524, +-263, -631, -299, -560, -174, -239, 39, 165, +174, 498, 115, 716, -84, 691, -275, 382, +-314, -75, -172, -513, 60, -755, 232, -666, +231, -279, 109, 219, -13, 625, -104, 760, +-185, 592, -278, 174, -339, -326, -352, -645, +-291, -674, -139, -514, 55, -199, 224, 218, +294, 522, 232, 641, 47, 615, -172, 375, +-360, -76, -484, -522, -425, -774, -126, -727, +290, -365, 607, 173, 635, 646, 339, 831, +-187, 654, -735, 232, -1018, -229, -900, -551, +-473, -602, 16, -412, 376, -115, 546, 171, +566, 322, 464, 297, 237, 209, -51, 102, +-328, -42, -516, -120, -534, -109, -391, -82, +-196, -70, -66, -113, 9, -195, 72, -134, +128, 104, 208, 362, 237, 566, 98, 622, +-192, 367, -451, -134, -525, -605, -450, -892, +-240, -898, 60, -563, 296, 5, 399, 555, +389, 862, 263, 823, 40, 512, -201, 120, +-412, -164, -553, -236, -532, -187, -368, -183, +-157, -291, 71, -440, 282, -497, 379, -320, +259, 60, 19, 453, -220, 677, -402, 651, +-414, 372, -233, -76, 34, -478, 262, -595, +394, -346, 352, 86, 79, 469, -284, 624, +-563, 424, -686, -83, -601, -611, -282, -897, +163, -817, 456, -353, 446, 282, 239, 759, +-13, 911, -222, 755, -318, 346, -212, -114, +-17, -399, 66, -437, -1, -300, -97, -124, +-133, -35, -209, -47, -329, -86, -321, -123, +-158, -119, 52, -33, 245, 139, 372, 336, +318, 463, 43, 384, -278, 69, -485, -314, +-517, -549, -365, -522, -105, -246, 118, 156, +211, 491, 235, 653, 187, 584, 27, 263, +-180, -211, -319, -612, -328, -791, -248, -674, +-100, -231, 75, 354, 163, 749, 101, 786, +-55, 501, -175, -28, -226, -562, -233, -816, +-138, -701, -6, -296, 71, 292, 95, 810, +69, 990, -38, 785, -194, 281, -278, -367, +-254, -879, -117, -1005, 95, -748, 259, -219, +256, 397, 65, 830, -209, 858, -458, 492, +-584, -81, -514, -627, -289, -896, 61, -729, +456, -188, 694, 467, 643, 979, 299, 1133, +-215, 827, -741, 193, -994, -516, -775, -1110, +-269, -1348, 228, -1046, 542, -354, 577, 437, +290, 1111, -150, 1423, -429, 1154, -436, 407, +-258, -496, 0, -1177, 198, -1315, 206, -820, +60, 23, -86, 780, -246, 1123, -421, 922, +-470, 261, -357, -570, -104, -1105, 219, -1054, +497, -487, 591, 361, 412, 1177, 16, 1507, +-434, 1122, -704, 237, -684, -778, -494, -1540, +-223, -1663, 88, -1057, 299, -88, 306, 803, +207, 1308, 106, 1261, -30, 728, -125, 50, +-118, -465, -90, -683, -93, -571, -78, -232, +-55, 92, -136, 255, -267, 272, -353, 105, +-353, -196, -193, -385, 93, -327, 331, -133, +359, 143, 179, 441, -49, 576, -211, 496, +-236, 279, -149, -75, -76, -476, -74, -689, +-126, -647, -170, -403, -192, -5, -176, 387, +-146, 578, -85, 582, 81, 440, 273, 150, +339, -140, 212, -274, -37, -290, -325, -279, +-600, -222, -667, -122, -417, -29, -28, 48, +299, 153, 486, 268, 522, 295, 358, 187, +53, -10, -270, -239, -567, -415, -725, -382, +-662, -135, -385, 141, 4, 324, 352, 433, +530, 430, 492, 301, 312, 114, 82, -107, +-147, -330, -343, -449, -482, -424, -507, -326, +-422, -172, -262, 38, -38, 214, 153, 278, +226, 288, 168, 282, 132, 196, 198, 40, +214, -63, 96, -86, -119, -84, -355, -21, +-546, 85, -614, 92, -504, -44, -241, -206, +111, -317, 418, -297, 565, -106, 535, 148, +307, 332, -78, 400, -454, 326, -642, 99, +-602, -185, -428, -400, -198, -438, 27, -293, +284, -28, 519, 282, 546, 542, 321, 614, +-59, 433, -451, 82, -747, -292, -809, -563, +-535, -687, -69, -625, 359, -346, 612, 88, +616, 499, 387, 755, 1, 742, -395, 412, +-627, -77, -539, -459, -195, -558, 134, -378, +247, -77, 76, 144, -251, 225, -511, 174, +-450, 44, -26, -82, 422, -133, 572, -104, +402, -11, 75, 103, -254, 191, -455, 244, +-412, 201, -229, 22, -108, -200, -102, -325, +-150, -334, -102, -216, 70, 19, 212, 261, +193, 395, 67, 378, -68, 209, -224, -69, +-342, -312, -324, -395, -162, -312, 40, -117, +183, 152, 252, 342, 221, 317, 64, 168, +-197, 39, -445, -65, -467, -107, -271, -70, +-33, -53, 166, -72, 258, -83, 202, -105, +29, -108, -129, -14, -226, 97, -274, 165, +-271, 200, -237, 138, -116, -30, 111, -173, +320, -194, 345, -84, 166, 88, -102, 178, +-343, 192, -414, 179, -267, 85, -56, -49, +57, -107, 34, -139, -29, -186, -82, -179, +-122, -158, -88, -161, -26, -92, -24, 78, +-102, 241, -167, 337, -118, 351, 24, 258, +183, 62, 264, -134, 188, -202, -11, -140, +-196, -40, -269, 33, -261, 0, -236, -161, +-217, -269, -213, -226, -196, -95, -156, 104, +-29, 333, 146, 424, 224, 319, 190, 89, +139, -192, 134, -381, 123, -363, 79, -184, +-35, 37, -280, 233, -534, 378, -629, 449, +-511, 344, -203, 22, 185, -346, 483, -570, +523, -564, 284, -294, -92, 116, -390, 423, +-431, 520, -257, 387, -3, 77, 190, -242, +198, -424, 6, -426, -185, -219, -170, 104, +-73, 367, -44, 496, -54, 444, -97, 194, +-161, -100, -155, -275, -30, -329, 103, -254, +109, -82, 25, 67, -89, 139, -165, 120, +-157, -37, -103, -263, -83, -399, -140, -342, +-161, -40, -43, 364, 181, 626, 357, 656, +357, 479, 154, 139, -194, -155, -520, -270, +-676, -358, -632, -470, -395, -449, 11, -300, +485, -135, 784, 108, 722, 389, 360, 504, +-169, 417, -649, 215, -866, -131, -724, -511, +-313, -627, 111, -403, 397, -4, 527, 447, +495, 807, 279, 814, -60, 450, -402, -37, +-627, -470, -602, -749, -314, -732, 67, -439, +376, -79, 482, 190, 347, 331, 70, 330, +-202, 198, -409, 31, -573, -51, -559, -7, +-292, 86, 113, 166, 463, 215, 606, 172, +493, -6, 165, -219, -191, -327, -385, -262, +-403, -61, -346, 122, -296, 178, -240, 120, +-137, 1, -7, -130, 133, -181, 242, -152, +241, -85, 121, 25, 18, 150, -24, 234, +-95, 271, -156, 231, -220, 61, -320, -119, +-310, -177, -56, -134, 235, -50, 276, 62, +169, 116, 108, 44, 29, -49, -114, -75, +-257, -118, -417, -236, -584, -273, -554, -144, +-176, 27, 339, 160, 713, 306, 780, 407, +484, 395, -44, 302, -498, 122, -658, -141, +-566, -351, -303, -424, 36, -414, 295, -272, +353, 16, 201, 275, -76, 338, -360, 221, +-498, -11, -366, -255, -59, -337, 257, -179, +435, 93, 357, 314, 81, 445, -222, 437, +-390, 255, -344, -51, -81, -357, 224, -524, +355, -450, 264, -188, -12, 126, -366, 393, +-586, 457, -543, 198, -335, -210, -77, -466, +203, -479, 391, -247, 416, 158, 378, 493, +257, 593, -25, 498, -335, 248, -459, -85, +-428, -338, -345, -459, -121, -481, 201, -374, +403, -138, 354, 115, 71, 311, -308, 407, +-554, 370, -493, 198, -195, -59, 137, -274, +372, -312, 439, -161, 302, 72, 28, 269, +-194, 288, -276, 98, -301, -155, -279, -330, +-199, -384, -111, -254, -58, 62, 14, 374, +145, 503, 237, 438, 260, 219, 226, -85, +65, -306, -225, -353, -497, -297, -590, -233, +-447, -159, -124, -57, 252, 76, 509, 209, +533, 294, 312, 312, -52, 262, -354, 143, +-455, -21, -350, -127, -157, -161, 13, -190, +90, -209, 88, -142, 59, -38, 11, -3, +-26, -25, -36, -43, -35, -24, -45, 80, +-88, 241, -124, 330, -93, 326, -22, 222, +65, -23, 161, -303, 201, -415, 46, -358, +-285, -216, -546, 3, -531, 209, -228, 266, +196, 166, 524, 21, 585, -85, 376, -103, +16, -23, -346, 121, -514, 226, -411, 223, +-176, 129, 16, -28, 87, -227, 23, -373, +-118, -358, -169, -179, -56, 101, 86, 329, +190, 362, 242, 225, 198, 20, 52, -188, +-115, -297, -209, -244, -237, -84, -234, 136, +-213, 320, -175, 331, -96, 169, 66, -16, +231, -131, 250, -147, 135, -102, -15, -59, +-174, -44, -270, -65, -218, -130, -82, -170, +13, -118, 59, -17, 124, 106, 138, 221, +70, 275, -25, 247, -139, 176, -250, 82, +-245, -13, -87, -67, 81, -68, 149, -61, +110, -140, -46, -291, -218, -371, -237, -269, +-124, -13, 5, 296, 128, 485, 224, 426, +201, 150, 82, -170, -56, -356, -188, -368, +-286, -236, -319, 45, -230, 381, -52, 533, +138, 438, 270, 186, 279, -167, 161, -492, +-30, -591, -231, -455, -350, -145, -282, 248, +-54, 474, 112, 420, 76, 210, -22, -75, +-31, -368, 9, -453, 31, -277, 85, 19, +124, 316, 15, 516, -161, 505, -228, 264, +-178, -71, -79, -315, 83, -361, 207, -250, +129, -52, -106, 110, -322, 104, -369, -67, +-185, -273, 106, -397, 316, -319, 325, -15, +144, 368, -76, 650, -171, 680, -114, 423, +-28, 62, 2, -204, -79, -365, -250, -398, +-365, -300, -264, -183, 8, -110, 255, -33, +392, 62, 409, 142, 239, 188, -100, 177, +-403, 119, -494, -1, -393, -153, -188, -224, +71, -136, 249, 71, 280, 306, 222, 396, +108, 251, -40, 12, -159, -223, -189, -400, +-179, -358, -121, -86, 19, 131, 107, 188, +5, 153, -138, 31, -139, -161, -76, -298, +-11, -249, 100, 6, 155, 350, 65, 607, +-58, 636, -113, 315, -76, -259, 49, -750, +190, -908, 147, -665, -118, -51, -394, 613, +-480, 915, -283, 790, 115, 340, 444, -294, +443, -768, 114, -770, -290, -415, -491, 44, +-346, 413, 107, 539, 571, 404, 670, 167, +299, -44, -293, -203, -776, -289, -909, -262, +-601, -107, -26, 77, 489, 181, 676, 167, +546, 64, 288, -65, 60, -119, -103, -89, +-242, -33, -362, 66, -452, 187, -467, 210, +-291, 95, 67, -65, 393, -221, 512, -325, +393, -286, 111, -64, -211, 224, -380, 426, +-322, 435, -150, 213, 38, -120, 201, -335, +233, -335, 48, -241, -191, -121, -304, 13, +-269, 120, -106, 182, 122, 222, 261, 186, +236, 87, 128, 44, 43, 30, -34, -48, +-153, -144, -270, -202, -290, -262, -152, -238, +88, -66, 295, 139, 288, 252, -5, 276, +-407, 197, -616, 36, -432, -71, 102, -81, +679, -90, 895, -100, 599, -21, 4, 69, +-517, 79, -748, 58, -696, 29, -444, -82, +-96, -192, 242, -166, 519, -69, 603, 50, +371, 218, -42, 304, -424, 164, -629, -37, +-508, -174, -50, -316, 407, -374, 579, -160, +496, 201, 233, 482, -167, 622, -520, 525, +-646, 105, -550, -458, -259, -836, 155, -863, +477, -494, 537, 154, 397, 744, 168, 907, +-107, 598, -331, 54, -365, -459, -259, -695, +-163, -521, -76, -98, 23, 277, 113, 496, +173, 496, 162, 218, 55, -202, -86, -475, +-178, -455, -151, -168, 25, 231, 260, 517, +349, 546, 156, 278, -216, -198, -524, -644, +-577, -819, -335, -668, 86, -225, 402, 376, +430, 901, 230, 1110, -34, 873, -202, 246, +-171, -519, -25, -1075, 50, -1159, 78, -720, +132, -14, 70, 653, -127, 1072, -235, 1030, +-200, 448, -146, -323, -95, -875, 12, -1074, +150, -841, 227, -176, 186, 608, 25, 1084, +-178, 1052, -305, 527, -266, -235, -101, -836, +112, -994, 287, -719, 316, -168, 208, 474, +92, 939, 6, 930, -143, 451, -352, -161, +-485, -643, -451, -851, -249, -679, 93, -223, +427, 231, 566, 562, 449, 701, 157, 517, +-214, 67, -545, -391, -624, -649, -348, -634, +143, -341, 612, 117, 836, 552, 599, 787, +-67, 759, -762, 447, -1049, -98, -823, -636, +-278, -913, 355, -906, 821, -635, 833, -54, +437, 607, 22, 979, -250, 937, -477, 561, +-569, -44, -367, -646, -44, -954, 192, -788, +347, -214, 379, 463, 221, 913, -35, 896, +-269, 360, -409, -405, -368, -896, -138, -891, +143, -443, 303, 248, 295, 795, 190, 859, +67, 495, -55, -63, -185, -585, -298, -773, +-316, -549, -194, -130, -12, 252, 193, 486, +395, 459, 458, 229, 268, -2, -90, -100, +-418, -95, -556, -56, -430, -14, -118, -14, +189, -90, 339, -205, 278, -257, 56, -190, +-124, 38, -117, 335, 15, 483, 123, 367, +137, 84, 48, -254, -77, -497, -128, -445, +-97, -159, -79, 136, -122, 358, -135, 468, +-107, 327, -96, 25, -38, -236, 109, -425, +221, -518, 238, -348, 212, 53, 137, 415, +-29, 639, -250, 675, -404, 359, -384, -219, +-126, -632, 285, -758, 590, -695, 516, -336, +72, 283, -457, 732, -785, 796, -720, 606, +-239, 206, 358, -321, 660, -683, 584, -708, +257, -476, -134, -39, -300, 471, -144, 769, +27, 684, 30, 299, -25, -241, -85, -730, +-171, -870, -203, -584, -114, -109, 0, 345, +102, 721, 216, 828, 234, 592, 66, 187, +-112, -268, -150, -679, -152, -768, -148, -463, +-45, -82, 75, 197, 86, 395, 73, 410, +97, 220, 92, 47, 46, -58, -15, -168, +-116, -179, -177, -21, -125, 112, -65, 133, +-71, 147, -33, 112, 110, -46, 198, -197, +162, -256, 86, -319, -67, -286, -305, -21, +-410, 282, -263, 409, 26, 416, 340, 295, +520, -27, 383, -337, 22, -378, -275, -201, +-391, 21, -314, 225, -53, 311, 252, 209, +333, -3, 113, -192, -220, -313, -453, -325, +-457, -189, -192, 13, 229, 157, 513, 217, +487, 240, 244, 216, -57, 171, -279, 81, +-285, -98, -154, -254, -56, -200, -11, -20, +-15, 66, -69, 36, -31, -27, 174, -81, +335, -102, 251, -39, -51, 60, -385, 125, +-548, 111, -404, 33, -33, -40, 339, -10, +563, 104, 554, 175, 246, 143, -225, 29, +-538, -183, -565, -472, -406, -574, -120, -305, +282, 191, 602, 624, 615, 804, 332, 605, +-58, 77, -398, -457, -623, -706, -625, -646, +-322, -366, 150, 71, 520, 455, 673, 599, +542, 476, 100, 156, -419, -252, -669, -520, +-544, -471, -193, -201, 177, 72, 402, 248, +389, 287, 189, 140, -6, -27, -93, -23, +-106, 83, -86, 113, -19, 110, 60, 116, +92, 12, 45, -213, -80, -397, -190, -428, +-203, -276, -185, 47, -197, 359, -147, 481, +-24, 393, 117, 193, 320, -73, 523, -346, +514, -513, 271, -477, -41, -232, -329, 173, +-557, 624, -620, 837, -371, 667, 87, 295, +454, -113, 537, -597, 323, -989, -146, -999, +-643, -648, -772, -127, -375, 491, 268, 999, +772, 1058, 920, 626, 610, -12, -32, -509, +-599, -686, -752, -551, -541, -221, -156, 186, +281, 517, 573, 605, 510, 390, 152, -15, +-265, -416, -574, -688, -632, -702, -405, -391, +-31, 93, 317, 487, 552, 699, 618, 667, +464, 341, 125, -126, -234, -514, -488, -734, +-600, -675, -440, -238, 46, 369, 548, 807, +702, 885, 469, 609, -38, 92, -627, -444, +-977, -801, -843, -900, -276, -734, 473, -289, +1045, 318, 1110, 801, 667, 975, -9, 797, +-642, 270, -1038, -427, -1025, -921, -531, -1038, +236, -740, 890, -37, 1163, 748, 921, 1157, +197, 1071, -648, 586, -1148, -177, -1096, -902, +-552, -1253, 253, -1056, 883, -385, 994, 428, +608, 976, -13, 1094, -589, 774, -873, 122, +-722, -592, -213, -1083, 402, -1098, 833, -561, +903, 210, 607, 801, 84, 1104, -474, 1026, +-830, 493, -852, -223, -589, -750, -181, -980, +272, -907, 625, -517, 667, 77, 425, 644, +91, 923, -236, 820, -471, 407, -430, -191, +-138, -783, 202, -1074, 464, -896, 547, -254, +342, 644, -97, 1340, -549, 1436, -793, 857, +-717, -175, -329, -1183, 230, -1608, 660, -1295, +747, -472, 554, 487, 242, 1172, -151, 1324, +-507, 965, -582, 243, -360, -570, -38, -1072, +261, -1071, 462, -618, 430, 70, 167, 680, +-176, 908, -462, 693, -604, 211, -490, -255, +-120, -537, 294, -595, 564, -399, 674, -48, +580, 253, 180, 426, -336, 478, -637, 283, +-610, -91, -351, -365, 18, -414, 317, -312, +374, -123, 214, 117, 24, 321, -88, 380, +-151, 269, -177, 106, -132, -68, 11, -246, +191, -312, 296, -222, 246, -142, 59, -100, +-166, 11, -307, 154, -291, 281, -143, 392, +19, 338, 94, 24, 116, -324, 161, -489, +223, -431, 171, -161, -15, 248, -150, 573, +-163, 632, -189, 359, -200, -190, -91, -749, +21, -954, 65, -654, 164, -44, 314, 596, +316, 991, 149, 928, -53, 428, -240, -207, +-403, -684, -427, -859, -243, -663, 8, -173, +191, 397, 341, 802, 428, 853, 296, 469, +41, -180, -101, -767, -164, -1000, -267, -773, +-310, -197, -225, 422, -71, 796, 134, 824, +321, 533, 308, 39, 69, -435, -154, -620, +-200, -456, -104, -74, 42, 299, 133, 456, +84, 333, -20, 52, -57, -253, -64, -455, +-60, -418, 24, -189, 131, 79, 98, 294, +-36, 374, -129, 240, -179, 18, -181, -116, +-42, -126, 170, -65, 257, 9, 154, 34, +-29, 6, -167, -17, -169, -11, 15, 38, +235, 89, 284, 93, 151, 22, -64, -77, +-298, -146, -409, -173, -312, -184, -117, -141, +97, -16, 304, 106, 383, 204, 249, 297, +31, 298, -131, 134, -217, -70, -236, -209, +-135, -250, 60, -175, 228, -28, 276, 86, +201, 132, 42, 117, -183, 15, -383, -118, +-432, -179, -268, -146, 60, -73, 369, 58, +465, 224, 364, 260, 170, 121, -87, 2, +-328, -9, -413, -11, -337, -15, -181, -44, +34, -206, 229, -416, 316, -417, 334, -171, +350, 213, 240, 635, -50, 902, -339, 759, +-502, 220, -533, -442, -363, -975, 16, -1193, +385, -927, 540, -171, 444, 685, 152, 1181, +-192, 1136, -383, 605, -335, -192, -115, -814, +156, -929, 329, -573, 304, 14, 131, 492, +-89, 595, -293, 342, -370, -35, -263, -331, +-51, -383, 133, -171, 242, 136, 278, 354, +214, 378, 63, 165, -108, -177, -246, -445, +-294, -533, -176, -399, 31, -51, 190, 409, +242, 760, 185, 793, 13, 448, -173, -107, +-203, -639, -40, -961, 155, -923, 180, -484, +55, 206, -44, 855, -79, 1209, -154, 1088, +-190, 460, -97, -473, -29, -1237, -38, -1412, +52, -939, 238, -77, 316, 780, 240, 1243, +109, 1117, -54, 543, -215, -172, -263, -709, +-235, -905, -210, -740, -128, -313, 35, 193, +167, 569, 213, 699, 241, 556, 238, 188, +131, -202, -51, -436, -211, -524, -296, -493, +-242, -270, -57, 121, 113, 504, 169, 663, +151, 512, 75, 118, -65, -363, -163, -720, +-137, -749, -65, -414, 12, 124, 198, 677, +387, 979, 330, 807, 41, 248, -255, -381, +-450, -840, -509, -934, -359, -598, -33, -48, +304, 446, 504, 738, 526, 717, 387, 342, +106, -196, -259, -632, -517, -779, -521, -584, +-292, -66, 40, 588, 337, 1006, 436, 896, +261, 344, -37, -328, -278, -859, -367, -1045, +-249, -769, 77, -114, 442, 598, 579, 1040, +398, 1016, 32, 492, -368, -310, -657, -971, +-656, -1184, -370, -893, 6, -164, 349, 706, +580, 1202, 551, 1069, 297, 514, 13, -201, +-192, -783, -319, -882, -303, -471, -145, 84, +-9, 457, 63, 518, 141, 250, 193, -171, +141, -457, -20, -441, -228, -210, -354, 79, +-268, 291, 18, 325, 312, 199, 456, 72, +387, 28, 96, 7, -277, 14, -508, 17, +-469, -90, -172, -240, 261, -228, 597, -70, +642, 128, 334, 266, -208, 215, -682, -6, +-820, -226, -554, -345, -33, -293, 490, -7, +789, 316, 738, 434, 345, 333, -189, 101, +-584, -209, -672, -446, -499, -451, -162, -208, +237, 178, 522, 517, 590, 612, 449, 382, +142, -61, -242, -488, -534, -685, -644, -582, +-539, -207, -179, 260, 340, 572, 712, 615, +717, 401, 438, 15, 18, -346, -433, -500, +-690, -443, -588, -226, -267, 77, 75, 314, +346, 388, 465, 352, 376, 223, 201, 3, +30, -238, -178, -424, -331, -468, -284, -293, +-115, 77, 43, 475, 198, 665, 278, 499, +136, 80, -150, -388, -329, -723, -297, -766, +-92, -434, 169, 148, 313, 679, 272, 890, +135, 679, -16, 163, -160, -419, -205, -784, +-129, -777, -36, -416, 35, 163, 123, 704, +183, 877, 122, 597, -28, 85, -146, -469, +-161, -893, -107, -912, -38, -449, 22, 195, +46, 694, 18, 865, -17, 622, -8, 81, +47, -419, 98, -627, 131, -521, 126, -180, +47, 242, -47, 520, -87, 494, -65, 209, +-31, -162, -11, -440, 9, -474, -21, -234, +-128, 82, -194, 266, -162, 276, -93, 140, +20, -68, 201, -190, 355, -141, 353, -34, +222, 34, 41, 85, -138, 155, -247, 205, +-244, 221, -189, 185, -137, 42, -87, -216, +-31, -480, 52, -584, 141, -455, 177, -116, +118, 340, 12, 735, -33, 825, -31, 533, +-51, 30, -34, -435, 35, -692, 74, -663, +65, -391, 43, -40, -18, 270, -144, 457, +-216, 435, -148, 240, -15, 18, 125, -138, +267, -189, 289, -111, 95, 51, -163, 172, +-293, 138, -280, -53, -181, -267, -25, -380, +127, -359, 197, -148, 190, 224, 188, 508, +220, 515, 207, 300, 47, -37, -213, -350, +-414, -439, -456, -280, -301, -13, -36, 217, +195, 316, 314, 247, 318, 75, 238, -115, +119, -256, -16, -290, -167, -205, -275, -56, +-265, 85, -155, 185, 37, 235, 267, 207, +356, 88, 214, -52, -23, -155, -185, -224, +-257, -194, -245, 8, -122, 255, 48, 362, +170, 280, 204, 45, 155, -265, 43, -501, +-100, -478, -236, -188, -271, 176, -110, 445, +157, 510, 304, 280, 290, -154, 182, -495, +-32, -521, -261, -267, -265, 158, -77, 593, +22, 763, 10, 546, 31, 80, 58, -388, +11, -698, -19, -758, -10, -516, -110, -63, +-247, 318, -190, 464, 48, 439, 316, 280, +528, 27, 552, -137, 266, -113, -224, -17, +-619, 45, -746, 41, -572, -57, -145, -196, +344, -242, 654, -124, 655, 123, 348, 370, +-113, 447, -467, 281, -559, -106, -399, -527, +-109, -705, 192, -553, 410, -162, 447, 356, +330, 769, 181, 815, -7, 484, -272, -32, +-496, -527, -517, -786, -324, -642, -12, -199, +340, 284, 548, 600, 440, 645, 98, 424, +-258, 43, -463, -336, -416, -545, -113, -527, +267, -329, 482, -40, 432, 206, 171, 310, +-189, 287, -447, 224, -433, 162, -213, 94, +37, 23, 232, -60, 299, -187, 189, -309, +8, -306, -91, -160, -88, 53, -73, 230, +-75, 304, -80, 262, -66, 131, 24, -45, +183, -207, 272, -264, 190, -173, 9, -30, +-171, 78, -291, 136, -281, 96, -129, -14, +36, -83, 111, -66, 112, -21, 82, 17, +54, 76, 72, 119, 108, 107, 94, 98, +42, 91, -27, 35, -115, -46, -190, -103, +-171, -162, -66, -240, 9, -238, 12, -126, +2, 5, -10, 114, -10, 221, 55, 255, +142, 171, 169, 68, 137, 5, 62, -47, +-49, -80, -116, -30, -97, 51, -51, 56, +-33, -35, -54, -169, -117, -285, -163, -295, +-98, -142, 39, 113, 178, 322, 275, 371, +235, 311, 39, 163, -170, -89, -250, -327, +-175, -392, 15, -280, 229, -74, 272, 195, +74, 416, -154, 395, -260, 157, -255, -96, +-101, -260, 155, -341, 263, -313, 133, -132, +-46, 100, -140, 235, -171, 269, -121, 219, +58, 41, 220, -179, 210, -249, 102, -148, +10, -6, -93, 134, -216, 246, -238, 235, +-100, 109, 55, -26, 137, -135, 160, -229, +106, -252, -26, -183, -158, -77, -178, 43, +-69, 175, 56, 259, 109, 214, 115, 102, +89, -1, 15, -114, -61, -173, -72, -99, +-42, 27, -30, 97, -37, 87, -31, 11, +-32, -88, -66, -138, -58, -118, 41, -63, +164, 42, 196, 183, 110, 254, -48, 224, +-199, 103, -234, -106, -98, -324, 135, -421, +270, -334, 150, -111, -149, 175, -362, 409, +-330, 463, -83, 338, 303, 130, 619, -112, +562, -332, 113, -409, -388, -286, -663, -56, +-678, 163, -406, 295, 128, 256, 587, 56, +664, -162, 438, -277, 85, -263, -285, -133, +-492, 70, -407, 262, -138, 374, 129, 361, +324, 232, 383, 39, 227, -174, -52, -349, +-294, -461, -429, -465, -417, -330, -212, -71, +107, 259, 347, 539, 398, 660, 318, 562, +159, 236, -34, -205, -130, -551, -122, -635, +-139, -470, -176, -164, -146, 200, -64, 462, +-11, 458, 35, 238, 111, -57, 98, -305, +-39, -400, -119, -296, -54, -30, 73, 266, +172, 437, 221, 392, 156, 179, -49, -91, +-255, -330, -329, -426, -274, -315, -113, -69, +127, 191, 348, 369, 417, 375, 278, 198, +12, -51, -256, -273, -439, -388, -452, -350, +-254, -182, 73, 47, 365, 253, 447, 371, +294, 333, 47, 119, -169, -130, -294, -258, +-279, -234, -90, -79, 149, 152, 254, 349, +205, 351, 65, 138, -127, -152, -282, -414, +-280, -539, -123, -469, 72, -237, 234, 81, +295, 365, 175, 521, -45, 499, -205, 334, +-261, 108, -223, -131, -79, -314, 100, -362, +217, -278, 276, -119, 250, 68, 106, 204, +-55, 225, -165, 162, -298, 63, -398, -76, +-310, -211, -63, -270, 198, -255, 407, -173, +498, 7, 365, 213, 39, 332, -298, 355, +-527, 273, -560, 86, -296, -114, 135, -253, +482, -273, 620, -175, 501, -8, 127, 180, +-344, 271, -636, 161, -640, -118, -420, -375, +-31, -458, 383, -343, 595, -38, 547, 331, +321, 557, 22, 562, -260, 363, -433, 19, +-432, -330, -295, -506, -72, -396, 204, -97, +411, 183, 418, 319, 214, 247, -140, 9, +-456, -231, -538, -310, -359, -247, -16, -121, +337, 60, 570, 230, 586, 298, 376, 259, +57, 155, -288, 2, -584, -123, -668, -151, +-472, -126, -87, -86, 302, -35, 544, 20, +546, 69, 271, 95, -123, 70, -406, -36, +-480, -181, -311, -262, 45, -233, 370, -80, +501, 163, 411, 346, 121, 397, -253, 318, +-486, 122, -442, -145, -221, -348, 9, -347, +168, -207, 201, 1, 127, 208, 73, 266, +105, 159, 156, -18, 101, -190, -78, -297, +-276, -271, -382, -115, -308, 82, -46, 252, +291, 343, 508, 299, 438, 127, 136, -51, +-184, -147, -376, -154, -382, -125, -211, -95, +37, -86, 210, -78, 213, -32, 89, 39, +-69, 94, -174, 108, -174, 90, -74, 31, +77, -6, 200, -21, 242, -79, 201, -101, +71, -30, -107, 58, -243, 91, -289, 82, +-228, 40, -84, -68, 90, -141, 240, -99, +279, -20, 155, 58, -56, 141, -196, 198, +-185, 159, -111, -5, -12, -184, 138, -288, +215, -277, 113, -94, -65, 165, -164, 288, +-183, 209, -175, 44, -63, -100, 123, -177, +190, -99, 146, 89, 97, 203, 24, 176, +-62, 56, -85, -135, -28, -335, 16, -338, +-31, -91, -123, 210, -193, 364, -182, 362, +-66, 193, 89, -143, 241, -398, 327, -348, +234, -112, 22, 130, -164, 302, -260, 315, +-252, 137, -135, -137, 53, -336, 168, -362, +116, -208, 9, 49, -66, 252, -61, 326, +54, 234, 163, 55, 153, -16, 3, 15, +-186, 41, -248, 4, -158, -97, -13, -224, +98, -317, 115, -278, 55, -122, -43, 48, +-103, 202, -42, 321, 88, 333, 192, 214, +201, 59, 93, -95, -63, -241, -183, -258, +-210, -97, -125, 53, -20, 100, 36, 116, +24, 92, -58, -14, -127, -129, -97, -181, +47, -160, 197, -35, 231, 118, 178, 215, +71, 206, -109, 91, -249, -54, -193, -150, +13, -121, 170, -6, 204, 83, 133, 102, +-90, 46, -366, -47, -453, -155, -290, -195, +-16, -94, 266, 70, 495, 218, 549, 274, +349, 156, 10, -71, -299, -290, -505, -376, +-513, -205, -286, 137, 47, 413, 286, 462, +338, 284, 271, -77, 153, -469, 1, -632, +-161, -476, -297, -72, -316, 410, -162, 713, +96, 683, 361, 330, 488, -197, 363, -658, +-7, -780, -435, -543, -650, -111, -598, 336, +-349, 632, 103, 663, 588, 411, 799, 4, +643, -373, 251, -592, -203, -542, -556, -193, +-605, 238, -338, 513, -20, 546, 183, 346, +269, -55, 196, -470, -8, -646, -211, -596, +-283, -362, -184, 67, 1, 510, 225, 769, +413, 751, 432, 474, 271, 12, -21, -468, +-325, -722, -468, -666, -406, -373, -173, 39, +123, 386, 327, 491, 336, 338, 96, 80, +-231, -158, -394, -306, -340, -292, -132, -133, +159, 67, 421, 248, 521, 345, 393, 298, +138, 136, -157, -98, -464, -346, -599, -452, +-435, -323, -91, -84, 238, 202, 430, 449, +460, 504, 307, 294, -9, -66, -305, -366, +-429, -538, -388, -501, -219, -209, 35, 189, +316, 465, 461, 495, 352, 309, 103, -15, +-130, -330, -256, -387, -241, -202, -115, 29, +37, 244, 112, 352, 87, 239, -7, -23, +-155, -249, -255, -348, -207, -354, -11, -216, +257, 67, 419, 353, 375, 493, 194, 415, +-60, 181, -344, -123, -519, -401, -459, -542, +-234, -490, 9, -246, 257, 95, 462, 397, +472, 539, 294, 511, 66, 295, -129, -56, +-259, -308, -281, -339, -190, -211, -84, -32, +-27, 107, -4, 101, -37, -58, -88, -243, +-94, -316, -45, -255, 61, -48, 152, 217, +162, 389, 167, 441, 232, 350, 285, 145, +227, -89, 94, -194, -56, -134, -306, -107, +-589, -131, -691, -126, -550, -172, -214, -260, +242, -220, 653, -20, 778, 163, 523, 279, +96, 366, -256, 327, -425, 139, -349, -50, +-121, -176, 73, -249, 156, -210, 138, -63, +88, 47, 36, 52, -33, 61, -91, 99, +-138, 76, -140, 11, -70, -21, -7, -60, +21, -130, 26, -120, 3, -64, -38, -30, +-76, -12, -49, 0, 43, 18, 132, 45, +212, 130, 244, 220, 196, 268, 125, 248, +7, 119, -167, -73, -308, -273, -354, -431, +-308, -435, -206, -277, -44, -50, 134, 166, +198, 285, 157, 277, 99, 159, 38, 13, +21, -68, 74, -74, 149, -5, 170, 103, +96, 198, -30, 197, -177, 75, -289, -64, +-267, -182, -114, -264, 82, -261, 200, -188, +149, -117, -10, -41, -166, 92, -237, 228, +-168, 289, 8, 231, 208, 67, 330, -104, +296, -183, 121, -118, -115, 20, -301, 121, +-348, 154, -225, 113, 26, -15, 258, -158, +348, -229, 284, -194, 98, -90, -131, 83, +-297, 248, -364, 232, -331, 81, -188, -115, +49, -252, 263, -238, 332, -75, 277, 143, +130, 251, -96, 218, -269, 122, -254, 0, +-68, -100, 145, -118, 274, -58, 279, -18, +125, -21, -118, -9, -283, -15, -301, -50, +-235, -27, -170, 26, -81, 15, 90, -20, +258, -17, 335, -1, 302, 11, 111, 59, +-195, 120, -417, 126, -375, 67, -96, -5, +236, -74, 488, -155, 521, -156, 239, -92, +-214, -44, -609, 22, -752, 98, -531, 120, +-29, 58, 500, 42, 771, 67, 664, 36, +259, -15, -267, -62, -637, -99, -650, -78, +-368, -11, 42, 55, 386, 75, 527, 21, +447, -51, 184, -123, -132, -156, -350, -106, +-432, 18, -377, 163, -203, 274, 54, 333, +331, 257, 501, 27, 467, -227, 188, -397, +-249, -405, -598, -251, -685, -27, -454, 171, +50, 298, 571, 305, 810, 197, 662, 62, +241, -80, -268, -207, -681, -245, -753, -188, +-432, -82, 21, 46, 379, 181, 532, 260, +386, 196, 20, 19, -302, -137, -380, -205, +-243, -172, -19, -34, 224, 164, 377, 263, +333, 200, 135, 88, -113, -98, -319, -300, +-408, -395, -321, -355, -77, -198, 174, 61, +312, 373, 320, 542, 185, 458, -44, 218, +-238, -68, -288, -314, -191, -403, -22, -283, +154, -65, 268, 99, 238, 198, 85, 216, +-92, 82, -214, -92, -265, -173, -244, -200, +-110, -181, 110, -68, 295, 81, 345, 179, +242, 240, 12, 245, -251, 175, -379, 58, +-288, -98, -87, -238, 109, -279, 251, -186, +254, -29, 113, 116, -57, 224, -170, 204, +-197, 59, -115, -132, 62, -262, 196, -281, +190, -194, 106, 13, -14, 232, -147, 345, +-210, 382, -178, 307, -100, 64, -8, -184, +101, -348, 193, -432, 202, -359, 120, -63, +-41, 245, -232, 344, -310, 304, -214, 136, +0, -144, 260, -334, 401, -290, 293, -76, +25, 157, -203, 324, -287, 335, -233, 145, +-62, -138, 133, -319, 158, -311, 3, -165, +-137, 59, -157, 227, -80, 232, 37, 127, +156, 17, 193, -53, 78, -69, -69, -51, +-102, -47, -39, -81, 70, -112, 163, -103, +165, -46, 32, 45, -175, 88, -305, 79, +-286, 79, -145, 52, 72, 57, 242, 97, +263, 132, 149, 119, -44, 13, -206, -143, +-223, -284, -109, -316, 49, -224, 188, -56, +290, 130, 274, 246, 105, 229, -96, 132, +-253, 35, -368, -15, -355, -40, -168, -62, +77, -60, 263, -69, 352, -79, 301, -22, +60, 57, -214, 83, -305, 76, -227, 67, +-90, 8, 78, -45, 222, -38, 248, -16, +166, -3, 76, -15, -1, -66, -119, -150, +-241, -168, -268, -72, -192, 54, -70, 169, +77, 235, 208, 225, 226, 120, 122, -30, +12, -114, -48, -144, -85, -142, -84, -81, +-34, -8, 7, 22, 6, 47, 10, 49, +45, 20, 72, -15, 62, -6, -1, 4, +-101, -28, -172, -46, -149, -48, -37, -14, +83, 52, 129, 113, 83, 141, -28, 103, +-128, 2, -126, -109, 5, -165, 192, -157, +297, -85, 230, 39, 4, 161, -274, 238, +-427, 222, -343, 99, -81, -89, 219, -257, +406, -324, 358, -269, 100, -143, -180, 0, +-301, 142, -259, 270, -148, 327, -26, 282, +60, 161, 113, -33, 187, -239, 266, -343, +283, -293, 172, -102, -69, 111, -326, 278, +-473, 323, -440, 170, -231, -91, 72, -315, +353, -391, 489, -288, 424, 6, 197, 348, +-133, 515, -433, 428, -521, 138, -337, -253, +8, -540, 332, -560, 468, -330, 366, 72, +108, 488, -164, 695, -324, 550, -319, 153, +-170, -291, 3, -615, 106, -679, 169, -443, +177, -18, 89, 382, -35, 609, -128, 584, +-185, 298, -188, -90, -85, -420, 92, -578, +213, -483, 237, -136, 197, 277, 86, 518, +-79, 545, -210, 332, -230, -102, -145, -499, +-28, -623, 73, -444, 144, -55, 124, 384, +-10, 646, -159, 569, -191, 208, -90, -225, +61, -535, 189, -581, 238, -379, 172, -46, +45, 287, -61, 473, -124, 462, -157, 264, +-180, -7, -172, -232, -85, -359, 74, -351, +226, -210, 285, -4, 217, 184, 41, 311, +-161, 325, -278, 187, -273, -48, -197, -292, +-87, -423, 57, -335, 198, -62, 283, 249, +292, 468, 204, 498, 38, 294, -123, -47, +-226, -347, -272, -514, -244, -496, -120, -277, +45, 20, 172, 271, 224, 393, 158, 379, +-14, 261, -165, 74, -174, -86, -59, -192, +108, -254, 239, -240, 223, -139, 31, 28, +-208, 171, -321, 233, -267, 180, -91, 19, +144, -174, 311, -299, 305, -265, 153, -63, +-46, 184, -188, 359, -217, 403, -143, 254, +-41, -31, 20, -286, 51, -409, 65, -410, +50, -273, 37, -19, 42, 226, 8, 370, +-58, 388, -80, 277, -49, 64, 6, -141, +96, -243, 180, -263, 148, -201, -6, -65, +-155, 68, -236, 117, -231, 93, -109, 55, +69, -15, 201, -65, 231, -24, 149, 47, +17, 93, -76, 97, -97, 29, -100, -81, +-103, -134, -56, -96, 3, -20, 20, 47, +36, 87, 69, 62, 76, -4, 48, -51, +16, -56, -9, 13, -40, 96, -56, 149, +-37, 134, -19, 31, -28, -132, -41, -269, +-49, -287, -36, -180, 10, 2, 67, 169, +109, 254, 106, 236, 64, 148, 19, 50, +-17, -17, -50, -43, -105, -42, -171, -59, +-183, -117, -116, -159, -2, -146, 123, -89, +225, 17, 247, 158, 163, 231, 40, 178, +-60, 80, -137, -40, -173, -157, -137, -194, +-79, -129, -53, -10, -21, 92, 34, 146, +62, 114, 66, 2, 82, -94, 78, -119, +15, -56, -48, 57, -55, 152, -21, 164, +48, 74, 114, -54, 92, -151, -17, -188, +-129, -138, -195, -15, -180, 95, -53, 144, +109, 106, 182, 20, 150, -49, 71, -81, +-23, -96, -101, -71, -127, 2, -123, 55, +-105, 98, -28, 157, 102, 169, 206, 96, +233, -6, 159, -120, -7, -248, -184, -274, +-259, -136, -197, 69, -50, 227, 125, 269, +241, 161, 212, -65, 49, -258, -162, -279, +-332, -155, -364, 18, -193, 179, 126, 235, +416, 161, 495, 47, 314, -17, -18, -36, +-303, -27, -366, 39, -197, 91, 66, 49, +255, -59, 235, -192, 26, -269, -206, -254, +-306, -147, -248, 20, -104, 189, 67, 291, +191, 297, 205, 242, 154, 102, 94, -113, +27, -293, -30, -326, -35, -199, -7, 25, +-6, 254, -25, 358, -31, 255, -54, 17, +-88, -202, -62, -312, -11, -291, -13, -138, +-44, 80, -59, 219, -51, 212, -14, 91, +70, -91, 161, -212, 186, -181, 149, -19, +80, 182, -16, 314, -101, 316, -143, 161, +-137, -86, -89, -294, -24, -369, 36, -278, +60, -77, 35, 149, -13, 297, -64, 278, +-101, 114, -88, -106, -14, -282, 70, -339, +130, -246, 185, -27, 216, 242, 157, 447, +12, 496, -141, 341, -263, 20, -316, -328, +-228, -522, -25, -474, 179, -243, 274, 55, +208, 291, 29, 365, -129, 249, -162, 12, +-85, -217, 41, -314, 148, -218, 152, 9, +47, 250, -78, 375, -139, 307, -121, 95, +-41, -160, 52, -342, 97, -350, 95, -197, +69, 11, 13, 181, -58, 269, -106, 225, +-115, 52, -86, -129, -20, -220, 65, -204, +118, -83, 101, 96, 26, 227, -49, 228, +-73, 130, -37, 9, 22, -130, 69, -231, +91, -217, 79, -114, 44, 14, -13, 145, +-96, 242, -170, 224, -193, 111, -142, -42, +-34, -205, 85, -318, 173, -301, 195, -152, +158, 78, 83, 319, -24, 449, -112, 384, +-141, 149, -111, -148, -25, -381, 86, -437, +145, -294, 88, -39, -40, 195, -131, 312, +-154, 275, -116, 98, -28, -120, 45, -266, +62, -281, 60, -152, 70, 58, 85, 252, +95, 334, 91, 282, 57, 136, -19, -55, +-98, -210, -129, -266, -98, -216, -22, -97, +20, 20, -19, 77, -107, 62, -181, -15, +-152, -111, 24, -139, 261, -47, 415, 126, +381, 296, 170, 386, -125, 316, -363, 72, +-419, -231, -295, -426, -73, -407, 166, -202, +310, 87, 264, 305, 72, 336, -121, 163, +-214, -114, -205, -351, -120, -429, 23, -284, +157, 2, 229, 297, 258, 491, 240, 485, +114, 279, -128, -12, -372, -253, -481, -361, +-396, -306, -120, -134, 239, 52, 486, 161, +509, 150, 320, 43, -7, -72, -347, -120, +-514, -105, -419, -28, -153, 67, 153, 90, +382, 26, 415, -47, 250, -53, 34, 11, +-139, 130, -260, 250, -287, 245, -183, 79, +-9, -140, 156, -288, 256, -331, 220, -226, +43, 2, -161, 195, -272, 237, -246, 160, +-113, 17, 60, -155, 210, -233, 278, -159, +251, -16, 152, 109, 9, 200, -134, 218, +-223, 144, -204, 35, -97, -51, -5, -107, +39, -130, 42, -91, -10, -23, -70, 24, +-82, 34, -30, 3, 57, -41, 160, -59, +241, -34, 219, 8, 73, 44, -119, 53, +-262, 15, -279, -18, -158, 2, 28, 48, +192, 107, 252, 164, 173, 147, -4, 8, +-200, -186, -325, -327, -291, -340, -91, -192, +183, 82, 385, 349, 406, 454, 224, 343, +-77, 67, -312, -253, -361, -462, -249, -439, +-36, -220, 195, 76, 337, 341, 313, 472, +131, 382, -117, 113, -331, -169, -410, -352, +-297, -375, -58, -225, 193, 7, 362, 168, +388, 186, 268, 119, 57, 36, -157, -39, +-305, -58, -338, 8, -211, 96, 30, 124, +245, 79, 320, -4, 220, -109, -6, -198, +-237, -207, -359, -135, -317, -20, -129, 95, +122, 163, 342, 176, 449, 154, 397, 105, +185, 18, -134, -92, -422, -175, -542, -198, +-436, -146, -141, -31, 211, 106, 468, 194, +513, 205, 313, 152, -46, 43, -381, -87, +-519, -191, -393, -238, -66, -220, 310, -118, +550, 35, 512, 173, 180, 273, -265, 312, +-546, 223, -524, 21, -263, -179, 102, -303, +408, -321, 476, -200, 302, 30, 53, 221, +-146, 270, -268, 196, -293, 42, -235, -131, +-149, -235, -16, -211, 168, -90, 287, 66, +274, 206, 171, 254, 16, 181, -155, 54, +-239, -61, -164, -122, -15, -105, 108, -46, +174, -18, 134, -39, -25, -91, -205, -154, +-281, -177, -217, -128, -54, -14, 137, 149, +281, 325, 305, 404, 199, 328, 28, 148, +-117, -62, -186, -228, -185, -270, -118, -205, +-10, -132, 71, -95, 97, -83, 83, -83, +30, -96, -27, -51, -50, 82, -47, 225, +-29, 311, -2, 309, 18, 180, 1, -57, +-52, -257, -100, -295, -111, -185, -47, -8, +89, 159, 227, 227, 304, 177, 273, 70, +105, -44, -141, -143, -333, -217, -385, -237, +-298, -164, -113, -22, 100, 110, 246, 168, +272, 149, 191, 75, 30, -24, -138, -79, +-223, -51, -191, 31, -36, 125, 190, 210, +352, 232, 346, 129, 171, -61, -114, -240, +-405, -342, -535, -346, -399, -227, -83, -39, +249, 120, 478, 216, 511, 250, 315, 210, +-21, 98, -333, -45, -483, -154, -422, -185, +-189, -128, 112, 3, 353, 152, 446, 247, +350, 239, 105, 132, -175, -38, -362, -226, +-381, -341, -240, -321, -1, -187, 254, 6, +423, 180, 401, 277, 171, 272, -166, 192, +-448, 62, -567, -96, -450, -229, -99, -258, +321, -171, 586, -24, 590, 125, 360, 219, +-2, 196, -323, 73, -450, -56, -371, -133, +-172, -157, 75, -107, 255, -2, 261, 94, +125, 135, -47, 112, -159, 34, -172, -54, +-88, -103, 24, -98, 85, -31, 94, 39, +102, 61, 120, 28, 113, -28, 22, -84, +-147, -125, -305, -112, -345, -51, -201, 28, +97, 124, 397, 233, 529, 298, 427, 270, +138, 160, -212, -12, -483, -237, -562, -420, +-421, -451, -129, -346, 191, -151, 389, 103, +407, 328, 293, 420, 121, 365, -45, 216, +-173, 9, -253, -204, -261, -342, -174, -351, +2, -227, 204, -16, 338, 229, 317, 424, +122, 458, -157, 273, -373, -59, -425, -384, +-289, -562, -22, -502, 239, -213, 374, 182, +332, 490, 151, 558, -54, 380, -168, 40, +-154, -323, -83, -540, -32, -506, -14, -255, +0, 103, 45, 410, 107, 537, 105, 432, +10, 164, -115, -138, -189, -356, -163, -398, +-44, -271, 111, -57, 199, 146, 168, 253, +68, 226, -14, 78, -64, -121, -99, -243, +-99, -216, -39, -80, 49, 89, 105, 222, +114, 248, 70, 143, -38, -14, -161, -131, +-219, -195, -190, -199, -87, -107, 72, 45, +235, 161, 314, 208, 250, 211, 80, 139, +-98, -9, -205, -138, -228, -200, -174, -237, +-64, -219, 49, -115, 118, -4, 147, 86, +128, 180, 41, 240, -75, 208, -130, 111, +-108, 2, -64, -118, -5, -200, 51, -181, +78, -79, 92, 51, 112, 165, 91, 205, +-4, 141, -112, 4, -160, -141, -141, -249, +-64, -263, 32, -139, 79, 59, 70, 238, +61, 330, 61, 266, 35, 50, 0, -186, +-21, -320, -52, -333, -90, -212, -91, 30, +-50, 257, 7, 349, 85, 317, 150, 185, +142, -30, 61, -219, -42, -273, -120, -201, +-137, -61, -66, 77, 38, 130, 78, 52, +36, -88, -37, -182, -89, -192, -84, -97, +-28, 80, 62, 240, 154, 301, 195, 273, +133, 158, -8, -18, -138, -174, -193, -238, +-159, -211, -52, -126, 75, -19, 146, 42, +125, 44, 29, 24, -84, 8, -140, 18, +-110, 43, -22, 49, 84, 22, 164, -21, +166, -49, 66, -45, -77, -1, -168, 69, +-168, 121, -94, 114, 17, 57, 127, -25, +176, -105, 120, -142, -3, -90, -130, 19, +-208, 89, -169, 71, 10, -24, 210, -157, +280, -250, 182, -205, -19, -22, -225, 207, +-311, 377, -216, 414, -29, 282, 130, 12, +220, -249, 221, -358, 131, -298, 19, -118, +-55, 90, -104, 195, -136, 111, -126, -71, +-76, -201, -10, -223, 62, -122, 116, 85, +118, 280, 61, 339, -28, 246, -117, 64, +-151, -131, -76, -259, 74, -233, 185, -68, +187, 126, 95, 232, -42, 175, -180, -23, +-252, -242, -195, -350, -34, -301, 146, -117, +260, 134, 268, 333, 169, 390, -10, 300, +-191, 106, -276, -133, -231, -300, -115, -311, +3, -182, 93, 11, 137, 174, 137, 238, +126, 195, 110, 83, 64, -55, -8, -179, +-65, -240, -97, -219, -110, -125, -106, 29, +-92, 201, -68, 298, -30, 258, 12, 103, +58, -89, 112, -241, 146, -285, 121, -159, +58, 72, 19, 271, -2, 339, -36, 221, +-86, -51, -135, -340, -163, -474, -141, -378, +-48, -110, 84, 204, 195, 430, 224, 473, +149, 323, 11, 44, -106, -238, -146, -394, +-114, -355, -56, -143, -10, 130, 20, 299, +37, 273, 41, 99, 34, -109, 26, -245, +10, -246, -15, -125, -23, 41, 12, 158, +55, 192, 60, 146, 17, 26, -42, -99, +-79, -137, -78, -73, -27, 37, 43, 124, +63, 137, 7, 52, -62, -72, -76, -150, +-47, -150, 6, -98, 87, -35, 155, 25, +161, 81, 88, 106, -46, 93, -165, 67, +-182, 34, -94, 0, 25, -35, 110, -58, +111, -66, -6, -56, -161, -17, -189, 36, +-55, 77, 119, 72, 217, 20, 195, -50, +72, -102, -94, -99, -202, -35, -186, 47, +-54, 107, 117, 124, 218, 82, 182, -1, +40, -72, -111, -101, -195, -88, -169, -31, +-60, 37, 55, 57, 99, 20, 49, -22, +-40, -29, -88, -7, -67, 27, 11, 61, +101, 72, 162, 46, 171, -7, 120, -45, +24, -53, -86, -49, -170, -24, -193, 12, +-142, 34, -49, 4, 37, -59, 82, -110, +73, -118, 14, -59, -50, 76, -50, 232, +13, 307, 96, 264, 157, 113, 150, -120, +45, -346, -99, -433, -188, -343, -184, -130, +-105, 132, 18, 338, 149, 396, 224, 290, +201, 84, 76, -134, -100, -279, -261, -297, +-334, -189, -248, -5, -26, 170, 209, 271, +335, 268, 301, 155, 144, -35, -52, -231, +-196, -351, -233, -346, -162, -213, -17, 20, +138, 277, 222, 446, 195, 426, 73, 227, +-89, -60, -206, -335, -227, -465, -179, -358, +-112, -76, -26, 232, 84, 430, 184, 419, +245, 185, 240, -164, 143, -443, -18, -533, +-162, -393, -219, -63, -161, 312, -36, 554, +69, 552, 108, 307, 83, -74, 5, -406, +-103, -511, -167, -352, -133, -40, -23, 275, +120, 459, 235, 414, 239, 166, 118, -156, +-60, -416, -210, -511, -269, -401, -201, -133, +-25, 168, 147, 365, 225, 392, 207, 274, +115, 87, -23, -69, -153, -123, -203, -88, +-153, -27, -54, 23, 54, 55, 150, 46, +174, -7, 111, -76, -5, -150, -139, -201, +-236, -198, -229, -134, -112, -19, 68, 132, +257, 268, 387, 329, 356, 289, 144, 143, +-129, -68, -343, -252, -424, -323, -314, -259, +-63, -86, 193, 118, 325, 243, 283, 216, +111, 61, -97, -110, -229, -216, -236, -208, +-134, -64, 31, 130, 169, 240, 205, 222, +145, 107, 41, -73, -53, -230, -95, -267, +-74, -175, -11, -6, 55, 172, 96, 273, +80, 231, -3, 83, -106, -89, -198, -226, +-256, -262, -222, -167, -66, -2, 156, 145, +343, 238, 405, 265, 304, 183, 64, 10, +-204, -160, -360, -280, -328, -318, -135, -224, +103, -33, 253, 155, 249, 281, 128, 318, +-21, 221, -139, 15, -205, -190, -216, -312, +-175, -297, -92, -128, 24, 116, 156, 301, +268, 343, 284, 239, 173, 24, 1, -209, +-140, -338, -196, -297, -142, -126, 3, 80, +148, 229, 181, 243, 62, 122, -146, -47, +-331, -166, -358, -178, -188, -79, 90, 58, +348, 149, 455, 162, 334, 105, 44, 0, +-244, -105, -379, -156, -327, -144, -119, -83, +145, 11, 305, 102, 294, 175, 173, 208, +19, 175, -117, 68, -201, -96, -220, -267, +-176, -364, -84, -304, 36, -101, 150, 144, +202, 316, 144, 347, -3, 223, -142, 5, +-205, -195, -177, -278, -43, -219, 147, -53, +284, 163, 321, 321, 253, 334, 81, 188, +-143, -42, -320, -250, -373, -356, -297, -339, +-117, -224, 90, -41, 218, 135, 243, 231, +186, 232, 53, 141, -105, -5, -198, -117, +-183, -117, -64, -18, 114, 104, 271, 180, +308, 165, 194, 74, -14, -33, -219, -117, +-311, -163, -249, -167, -88, -134, 82, -89, +185, -47, 177, -6, 71, 33, -76, 66, +-184, 117, -192, 179, -98, 191, 32, 122, +119, 7, 149, -113, 147, -201, 116, -199, +69, -108, 37, 20, 18, 134, -9, 187, +-56, 142, -99, 20, -111, -109, -103, -184, +-92, -167, -88, -61, -76, 83, -39, 184, +19, 192, 86, 103, 139, -52, 150, -205, +99, -277, 5, -222, -57, -50, -34, 180, +46, 357, 120, 388, 129, 255, 59, 10, +-60, -237, -182, -376, -238, -347, -197, -188, +-101, 21, -8, 215, 58, 306, 87, 241, +75, 62, 45, -127, 32, -244, 46, -251, +76, -148, 108, 12, 108, 153, 64, 226, +3, 227, -55, 163, -89, 46, -85, -88, +-49, -186, -17, -222, -32, -177, -80, -56, +-112, 76, -95, 163, -26, 172, 61, 101, +137, -18, 163, -129, 106, -176, 11, -145, +-45, -43, -38, 92, 3, 193, 38, 200, +42, 114, 20, -16, -15, -129, -54, -175, +-82, -122, -65, 3, -6, 115, 37, 153, +35, 119, 2, 26, -53, -109, -111, -223, +-121, -250, -56, -176, 54, -21, 146, 158, +187, 289, 167, 318, 93, 234, -11, 78, +-114, -93, -156, -213, -108, -246, -5, -191, +103, -73, 141, 46, 57, 120, -87, 113, +-188, 38, -191, -62, -105, -130, 25, -122, +124, -41, 144, 73, 103, 173, 46, 223, +-5, 189, -28, 87, -20, -37, -14, -136, +-8, -178, 10, -146, 26, -68, 30, -6, +36, 21, 44, 14, 18, -23, -40, -56, +-102, -49, -143, -3, -137, 56, -81, 111, +-3, 132, 81, 113, 146, 75, 163, 41, +134, 9, 78, -33, 7, -81, -61, -137, +-96, -184, -95, -173, -81, -90, -53, 21, +5, 115, 73, 166, 115, 160, 104, 104, +34, 30, -68, -32, -146, -71, -149, -80, +-88, -68, -18, -43, 46, -7, 104, 25, +137, 60, 129, 88, 77, 91, -13, 43, +-125, -46, -186, -130, -117, -160, 55, -114, +218, -20, 270, 74, 172, 117, -29, 98, +-234, 51, -353, 10, -339, -7, -193, -4, +46, 3, 266, -1, 358, -16, 305, -32, +151, -44, -47, -41, -196, -14, -212, 19, +-122, 42, -30, 44, 23, 5, 57, -53, +69, -88, 61, -79, 48, -30, 20, 41, +-22, 111, -47, 143, -50, 121, -49, 65, +-40, -11, -10, -94, 21, -156, 31, -158, +33, -109, 23, -36, -1, 52, -5, 127, +20, 150, 55, 107, 74, 29, 49, -55, +-23, -115, -86, -126, -92, -73, -51, 13, +0, 86, 52, 119, 78, 107, 49, 54, +-21, -27, -95, -88, -124, -111, -97, -99, +-33, -57, 58, -9, 160, 20, 218, 31, +186, 60, 82, 93, -46, 96, -167, 64, +-240, 8, -202, -64, -53, -129, 120, -137, +208, -76, 163, 18, 36, 109, -91, 158, +-156, 126, -131, 28, -46, -77, 30, -150, +62, -161, 67, -85, 57, 39, 31, 126, +16, 142, 24, 95, 26, 3, 23, -79, +30, -112, 18, -86, -15, -21, -32, 55, +-31, 101, -50, 93, -98, 46, -138, -27, +-135, -96, -60, -128, 77, -109, 197, -57, +233, 10, 179, 79, 63, 118, -57, 123, +-115, 101, -96, 51, -42, -24, 3, -85, +34, -99, 34, -74, -4, -13, -56, 65, +-94, 101, -99, 52, -63, -49, -1, -163, +66, -231, 113, -191, 115, -49, 61, 133, +-20, 279, -76, 333, -78, 256, -19, 89, +73, -89, 129, -216, 103, -235, 19, -142, +-74, -3, -127, 91, -115, 99, -57, 24, +-4, -101, 12, -196, 9, -199, 3, -109, +4, 27, 28, 174, 71, 284, 104, 319, +114, 256, 85, 103, 5, -90, -101, -256, +-171, -332, -159, -296, -76, -151, 52, 49, +168, 215, 202, 270, 125, 187, -21, 11, +-164, -180, -230, -288, -175, -258, -19, -98, +163, 125, 265, 294, 221, 337, 51, 239, +-148, 49, -265, -146, -238, -242, -89, -194, +87, -57, 199, 76, 216, 132, 139, 82, +10, -52, -85, -185, -103, -233, -63, -168, +-4, -13, 45, 174, 58, 308, 21, 315, +-40, 201, -86, 22, -99, -142, -85, -225, +-60, -204, -24, -110, 33, -13, 85, 52, +102, 64, 88, 35, 59, -2, 27, -15, +8, -7, 11, 4, 25, 19, 32, 32, +18, 32, -26, 12, -86, -13, -127, -32, +-140, -37, -109, -19, -25, 31, 76, 94, +127, 124, 107, 93, 45, -7, -11, -147, +-16, -260, 28, -279, 73, -166, 76, 39, +40, 250, -19, 359, -69, 314, -77, 135, +-32, -99, 26, -270, 53, -294, 27, -167, +-53, 37, -152, 204, -212, 244, -182, 148, +-58, -17, 110, -165, 225, -215, 233, -149, +159, -18, 58, 92, -14, 136, -26, 108, +1, 27, 9, -51, -29, -70, -89, -26, +-127, 28, -127, 58, -90, 56, -30, 22, +26, -26, 71, -50, 107, -36, 128, -8, +115, 16, 57, 27, -27, 22, -113, 13, +-163, -1, -126, -23, -7, -58, 126, -80, +193, -84, 156, -70, 27, -40, -121, 11, +-188, 83, -141, 151, -25, 183, 95, 152, +162, 72, 127, -32, 18, -114, -93, -151, +-153, -147, -145, -104, -68, -30, 51, 47, +147, 89, 170, 92, 130, 48, 49, -48, +-40, -142, -85, -172, -72, -109, -26, 18, +20, 172, 46, 280, 34, 276, -18, 156, +-74, -28, -100, -201, -81, -280, -23, -213, +35, -52, 59, 113, 56, 206, 42, 182, +22, 36, 16, -155, 27, -288, 18, -299, +-12, -174, -17, 39, 7, 252, 20, 368, +10, 333, -6, 173, -23, -28, -20, -169, +1, -214, 4, -160, -17, -51, -34, 39, +-34, 60, -14, 16, 30, -59, 65, -133, +53, -145, 24, -62, 26, 68, 41, 173, +31, 222, -10, 194, -54, 80, -77, -51, +-62, -135, -22, -169, 10, -151, 17, -82, +5, 2, -8, 66, -19, 114, -22, 122, +-20, 75, -1, -1, 37, -56, 82, -82, +116, -81, 104, -45, 38, 9, -42, 47, +-87, 38, -87, -5, -51, -53, 5, -75, +53, -45, 51, 19, -5, 79, -72, 92, +-91, 62, -21, 22, 108, 9, 198, 25, +176, 47, 44, 46, -131, -17, -241, -130, +-212, -236, -70, -267, 81, -188, 156, 1, +132, 230, 47, 380, -34, 373, -77, 198, +-66, -55, 6, -259, 98, -328, 130, -244, +64, -52, -59, 155, -167, 259, -191, 226, +-92, 85, 68, -96, 171, -238, 167, -274, +80, -191, -32, -38, -97, 121, -74, 222, +-3, 239, 51, 170, 70, 57, 61, -54, +16, -126, -43, -131, -79, -75, -76, 6, +-32, 64, 24, 84, 53, 62, 44, 6, +8, -55, -53, -106, -119, -135, -144, -135, +-103, -89, -16, -4, 101, 96, 212, 175, +246, 201, 170, 170, 31, 86, -87, -10, +-127, -68, -94, -73, -37, -55, 5, -36, +23, -29, 13, -56, -19, -119, -46, -180, +-39, -184, -23, -108, -15, 25, -3, 170, +3, 268, -2, 272, 26, 177, 105, 40, +194, -79, 219, -135, 138, -123, -24, -71, +-187, -22, -262, -1, -220, -2, -115, -30, +-18, -66, 51, -74, 103, -35, 130, 19, +108, 54, 43, 75, -43, 65, -115, 25, +-120, -20, -43, -39, 73, -36, 155, -14, +175, 33, 135, 67, 64, 74, 1, 58, +-41, 33, -79, -8, -91, -49, -57, -81, +-16, -106, -8, -114, -38, -104, -82, -67, +-119, -4, -108, 82, -33, 147, 70, 162, +154, 137, 196, 73, 182, -21, 115, -110, +13, -146, -95, -118, -170, -47, -186, 38, +-125, 96, -7, 99, 118, 41, 184, -34, +167, -81, 81, -69, -46, -18, -171, 36, +-215, 74, -144, 74, -18, 38, 85, -18, +130, -74, 118, -120, 61, -127, 9, -85, +10, -21, 55, 54, 92, 126, 83, 170, +22, 161, -56, 110, -103, 20, -109, -90, +-71, -151, -3, -135, 48, -59, 24, 29, +-65, 89, -147, 60, -159, -56, -94, -183, +24, -235, 149, -176, 226, -16, 220, 196, +139, 360, 36, 391, -47, 257, -89, 27, +-82, -181, -36, -282, 14, -255, 40, -137, +17, 6, -50, 89, -107, 70, -92, -7, +-7, -90, 77, -135, 103, -105, 65, 5, +-19, 125, -101, 201, -118, 213, -40, 150, +84, 25, 171, -88, 182, -142, 123, -153, +26, -120, -79, -52, -154, 20, -159, 76, +-112, 112, -59, 120, -21, 72, 9, -14, +41, -109, 69, -177, 78, -193, 59, -138, +20, -10, -13, 132, -15, 233, 15, 255, +71, 195, 112, 62, 88, -85, 5, -176, +-82, -183, -134, -124, -124, -35, -47, 49, +50, 90, 106, 70, 96, 7, 33, -62, +-62, -97, -127, -84, -122, -36, -69, 16, +-6, 76, 66, 128, 135, 144, 166, 118, +132, 55, 39, -34, -80, -125, -176, -157, +-185, -124, -89, -54, 67, 16, 184, 55, +179, 47, 68, 9, -60, -12, -137, -6, +-141, 22, -71, 57, 24, 76, 89, 56, +113, -4, 116, -66, 100, -96, 65, -72, +9, -5, -71, 65, -148, 89, -166, 56, +-107, -9, 2, -72, 116, -94, 165, -50, +115, 46, -9, 124, -128, 134, -190, 62, +-160, -65, -44, -185, 91, -238, 178, -178, +192, -25, 136, 158, 32, 294, -81, 317, +-140, 216, -112, 27, -38, -165, 27, -289, +66, -290, 85, -172, 75, 4, 32, 157, +-23, 212, -77, 152, -117, 21, -107, -114, +-14, -199, 122, -186, 215, -66, 194, 95, +50, 220, -134, 269, -238, 225, -202, 85, +-58, -87, 114, -213, 224, -255, 202, -199, +62, -72, -108, 60, -225, 129, -228, 125, +-113, 51, 54, -61, 176, -140, 196, -128, +111, -42, -23, 74, -107, 185, -90, 236, +-16, 196, 54, 87, 93, -43, 87, -155, +40, -204, 1, -177, -10, -106, -6, -12, +7, 67, 12, 89, -20, 45, -73, -15, +-105, -52, -112, -62, -89, -23, 2, 43, +119, 108, 168, 147, 127, 147, 44, 94, +-43, -2, -111, -101, -121, -172, -70, -184, +9, -142, 76, -63, 98, 38, 64, 134, +16, 180, -7, 146, -3, 65, 14, -40, +24, -145, 2, -195, -53, -145, -99, -28, +-105, 86, -65, 163, 14, 150, 100, 54, +153, -59, 165, -117, 128, -98, 44, 2, +-41, 134, -77, 198, -55, 165, -8, 58, +12, -95, -35, -246, -132, -313, -206, -259, +-188, -123, -76, 48, 79, 193, 201, 264, +236, 239, 185, 148, 91, 35, -6, -56, +-89, -89, -136, -70, -123, -21, -60, 21, +4, 26, 45, -19, 64, -82, 68, -128, +56, -139, 39, -92, 25, 4, -13, 94, +-64, 128, -80, 108, -45, 49, 16, -19, +85, -42, 134, -7, 124, 65, 51, 117, +-48, 111, -147, 29, -208, -94, -172, -194, +-43, -237, 113, -195, 222, -65, 226, 109, +112, 240, -63, 275, -218, 195, -286, 21, +-238, -173, -73, -287, 154, -259, 338, -104, +392, 115, 280, 281, 44, 304, -205, 174, +-336, -45, -289, -245, -107, -328, 96, -237, +213, -23, 214, 201, 122, 316, -31, 263, +-180, 72, -234, -162, -162, -310, 5, -299, +199, -146, 324, 64, 283, 233, 94, 287, +-132, 205, -281, 56, -295, -79, -179, -148, +-3, -144, 129, -80, 171, 1, 139, 40, +55, 33, -52, 8, -133, -3, -148, -13, +-91, -35, 13, -67, 133, -82, 215, -60, +212, 9, 123, 122, -25, 231, -162, 275, +-212, 209, -139, 37, 22, -186, 182, -363, +243, -394, 169, -257, -11, -7, -200, 236, +-288, 343, -241, 255, -98, 30, 74, -193, +212, -294, 254, -209, 184, 25, 40, 287, +-121, 422, -243, 354, -253, 100, -125, -227, +85, -458, 271, -477, 341, -277, 267, 28, +78, 291, -146, 400, -315, 316, -352, 86, +-253, -186, -84, -363, 89, -364, 225, -194, +282, 64, 252, 316, 173, 456, 66, 410, +-63, 208, -173, -67, -207, -311, -156, -443, +-43, -410, 92, -241, 177, 2, 153, 232, +39, 349, -98, 308, -179, 142, -154, -63, +-42, -223, 72, -255, 121, -155, 95, 6, +6, 160, -93, 237, -123, 202, -64, 72, +28, -66, 101, -156, 127, -178, 92, -117, +30, -13, -13, 60, -21, 70, -8, 41, +6, -14, 0, -58, -17, -46, -21, 7, +-10, 60, 2, 92, 8, 88, -5, 29, +-34, -49, -42, -90, -13, -76, 29, -22, +65, 40, 94, 78, 98, 59, 56, -5, +-20, -88, -97, -141, -147, -127, -143, -44, +-76, 78, 24, 184, 103, 228, 115, 163, +74, 19, 26, -125, -6, -203, -28, -184, +-41, -89, -51, 29, -56, 98, -37, 99, +23, 47, 101, -37, 151, -100, 146, -91, +74, -19, -29, 67, -118, 135, -164, 143, +-147, 89, -39, 15, 116, -45, 226, -78, +238, -76, 142, -53, -43, -55, -244, -76, +-348, -85, -313, -63, -174, -3, 28, 86, +234, 169, 351, 193, 331, 136, 189, 12, +-24, -128, -221, -206, -315, -181, -267, -73, +-112, 62, 90, 167, 244, 178, 285, 96, +209, -26, 54, -119, -135, -148, -267, -102, +-252, 1, -91, 98, 134, 145, 318, 124, +362, 48, 218, -58, -48, -137, -309, -166, +-454, -155, -411, -104, -187, -29, 114, 64, +357, 165, 454, 245, 376, 256, 155, 178, +-119, 40, -324, -126, -386, -262, -286, -296, +-75, -207, 139, -53, 265, 93, 267, 171, +146, 148, -50, 43, -212, -75, -251, -122, +-155, -75, 19, 46, 207, 178, 331, 237, +331, 191, 188, 61, -36, -92, -236, -220, +-347, -267, -340, -217, -209, -111, -3, -3, +172, 74, 255, 128, 238, 148, 155, 146, +41, 130, -65, 96, -138, 35, -165, -46, +-136, -121, -68, -163, 7, -149, 74, -80, +116, 20, 104, 109, 54, 147, 5, 115, +-26, 32, -44, -64, -46, -135, -35, -135, +-20, -61, 2, 40, 26, 111, 34, 127, +25, 79, 11, -22, -4, -108, 2, -131, +46, -85, 103, 7, 137, 98, 121, 137, +46, 106, -67, 26, -163, -80, -206, -162, +-192, -163, -115, -82, 3, 35, 92, 138, +121, 188, 108, 144, 77, 31, 36, -96, +13, -174, 20, -171, 30, -84, 24, 50, +4, 162, -28, 207, -55, 153, -63, 25, +-66, -114, -70, -192, -61, -196, -30, -131, +20, -24, 91, 66, 166, 110, 197, 111, +154, 86, 45, 42, -90, -3, -190, -33, +-194, -45, -106, -38, 20, -10, 114, 37, +133, 90, 79, 120, -4, 82, -59, -31, +-68, -169, -39, -271, -2, -278, 22, -156, +36, 61, 46, 261, 31, 355, -15, 306, +-75, 126, -117, -96, -118, -243, -70, -252, +28, -139, 139, 34, 214, 172, 207, 184, +108, 79, -43, -77, -170, -198, -206, -225, +-123, -138, 35, 9, 180, 131, 217, 185, +123, 158, -35, 85, -163, 16, -201, -17, +-150, -19, -35, 1, 82, 10, 144, -11, +125, -51, 52, -86, -34, -97, -103, -81, +-123, -40, -86, -7, -17, 6, 49, 25, +93, 55, 104, 95, 100, 134, 93, 156, +60, 118, -26, 12, -130, -121, -193, -231, +-189, -264, -104, -190, 41, -32, 177, 134, +231, 234, 182, 228, 65, 122, -49, -13, +-104, -104, -86, -113, -26, -58, 46, 23, +93, 74, 70, 58, -8, -11, -87, -92, +-129, -135, -137, -120, -107, -47, -47, 33, +24, 91, 79, 112, 104, 104, 93, 86, +63, 71, 40, 63, 22, 41, 11, -6, +9, -76, -3, -151, -48, -200, -105, -202, +-129, -146, -97, -45, -22, 67, 81, 159, +175, 205, 214, 192, 180, 134, 80, 63, +-37, 0, -124, -47, -143, -69, -98, -57, +-32, -34, 9, -34, 9, -58, -32, -90, +-83, -113, -91, -110, -43, -64, 32, 27, +99, 117, 147, 167, 156, 157, 108, 100, +19, 15, -79, -57, -158, -85, -173, -62, +-106, -8, 11, 51, 118, 75, 171, 26, +142, -65, 36, -143, -81, -162, -154, -122, +-153, -31, -72, 64, 61, 123, 173, 133, +213, 107, 167, 63, 49, 19, -88, -4, +-165, -12, -147, -8, -75, -2, 16, -3, +85, -11, 90, -26, 27, -51, -67, -88, +-149, -116, -172, -121, -115, -89, -1, 0, +131, 126, 232, 226, 251, 253, 153, 192, +-1, 50, -124, -127, -177, -251, -145, -267, +-34, -174, 87, -24, 139, 113, 88, 166, +-38, 121, -160, 30, -193, -49, -109, -65, +35, -16, 164, 64, 220, 111, 190, 94, +114, 15, 43, -81, -10, -138, -59, -122, +-119, -45, -179, 44, -191, 100, -148, 83, +-71, 4, 7, -77, 77, -101, 131, -56, +147, 40, 119, 140, 63, 170, -4, 105, +-48, -19, -39, -147, 1, -217, 30, -185, +16, -67, -35, 69, -86, 161, -77, 171, +-10, 99, 54, -15, 73, -108, 56, -128, +10, -72, -43, 21, -61, 100, -31, 128, +30, 99, 87, 38, 116, -16, 98, -39, +42, -40, -30, -43, -82, -50, -93, -69, +-71, -100, -46, -119, -31, -102, -19, -47, +-9, 27, 0, 118, 10, 190, 16, 214, +17, 186, 27, 126, 48, 28, 57, -92, +38, -187, -6, -235, -55, -220, -79, -151, +-63, -42, -21, 57, 36, 112, 94, 110, +122, 67, 102, 30, 49, 32, -9, 75, +-54, 141, -63, 194, -28, 181, 10, 75, +17, -90, 5, -258, -15, -369, -26, -369, +-25, -247, -33, -60, -65, 116, -87, 233, +-61, 257, 10, 192, 100, 89, 164, 11, +163, -16, 85, -1, -30, 38, -142, 62, +-205, 39, -180, -36, -79, -128, 51, -198, +162, -207, 203, -134, 141, 2, 21, 160, +-65, 279, -75, 311, -30, 221, 43, 31, +93, -192, 84, -354, 27, -389, -41, -278, +-99, -57, -120, 187, -88, 356, -28, 376, +28, 249, 63, 34, 60, -179, 6, -303, +-58, -279, -84, -122, -64, 77, -12, 224, +51, 263, 97, 180, 96, 10, 43, -166, +-34, -268, -90, -263, -98, -146, -52, 41, +24, 216, 93, 298, 122, 255, 105, 106, +58, -85, -1, -230, -52, -257, -79, -153, +-75, 26, -38, 179, 35, 221, 103, 118, +114, -76, 52, -260, -40, -323, -117, -223, +-144, 2, -101, 250, -24, 402, 38, 383, +71, 205, 74, -29, 47, -220, 10, -296, +-26, -235, -48, -77, -50, 75, -14, 138, +38, 90, 65, -37, 47, -174, -11, -237, +-66, -178, -78, -19, -37, 176, 16, 336, +57, 393, 71, 316, 65, 133, 58, -93, +62, -282, 54, -364, 24, -323, -13, -196, +-45, -36, -62, 87, -50, 127, -15, 96, +-6, 42, -29, 3, -56, 11, -61, 80, +-52, 167, -16, 211, 45, 175, 85, 66, +70, -80, 11, -208, -42, -259, -52, -228, +-16, -142, 31, -51, 56, 10, 32, 23, +-26, 23, -86, 50, -95, 117, -24, 206, +88, 267, 171, 254, 177, 143, 109, -41, +-7, -239, -129, -368, -202, -376, -167, -264, +-47, -68, 88, 147, 175, 303, 182, 345, +108, 280, -14, 146, -115, -20, -146, -166, +-105, -250, -43, -262, -3, -220, 4, -137, +-7, -32, -29, 64, -44, 124, -28, 146, +22, 143, 84, 124, 123, 108, 133, 104, +111, 105, 65, 91, -4, 38, -83, -45, +-149, -140, -171, -220, -142, -259, -64, -232, +54, -158, 165, -65, 214, 38, 183, 128, +99, 192, -7, 224, -103, 234, -168, 199, +-178, 117, -122, 4, -13, -117, 95, -219, +145, -271, 116, -252, 20, -180, -94, -81, +-164, 23, -142, 107, -43, 160, 83, 191, +171, 207, 193, 207, 148, 185, 59, 135, +-46, 49, -128, -67, -161, -183, -158, -263, +-133, -281, -86, -227, -24, -124, 37, -17, +104, 65, 160, 104, 165, 108, 117, 104, +53, 115, -12, 129, -74, 122, -99, 84, +-77, 5, -21, -104, 41, -204, 85, -237, +69, -192, -2, -90, -76, 35, -107, 142, +-78, 196, 7, 198, 92, 180, 113, 157, +67, 132, -7, 94, -68, 32, -112, -68, +-127, -185, -107, -282, -54, -316, -3, -271, +20, -157, 15, -11, -8, 111, -32, 170, +-27, 162, 40, 121, 148, 71, 245, 36, +273, 30, 218, 46, 100, 60, -40, 57, +-166, 34, -236, -3, -220, -44, -134, -75, +-32, -79, 37, -59, 66, -17, 43, 37, +-27, 75, -106, 63, -141, 4, -120, -75, +-55, -143, 28, -166, 107, -114, 176, 5, +206, 135, 179, 221, 116, 221, 50, 144, +-34, 10, -126, -123, -195, -202, -216, -196, +-186, -136, -99, -62, 18, -2, 119, 26, +192, 29, 223, 32, 197, 72, 130, 145, +76, 216, 19, 239, -53, 193, -97, 71, +-92, -90, -92, -225, -122, -282, -165, -249, +-204, -164, -208, -68, -134, -2, 18, 24, +181, 24, 291, 32, 299, 63, 203, 112, +56, 151, -71, 155, -135, 111, -131, 32, +-77, -41, -9, -84, 32, -95, 27, -78, +-9, -49, -49, -34, -52, -31, -10, -22, +63, 11, 134, 53, 158, 93, 117, 115, +36, 88, -57, 12, -142, -76, -184, -132, +-167, -148, -110, -113, -43, -40, 25, 39, +64, 78, 63, 73, 50, 42, 52, 4, +77, -24, 113, -38, 131, -23, 96, 8, +12, 37, -93, 64, -179, 96, -200, 112, +-125, 94, 7, 55, 125, 2, 177, -64, +136, -113, 23, -125, -93, -111, -140, -88, +-106, -66, -17, -54, 72, -60, 102, -57, +68, -26, 13, 30, -45, 93, -88, 147, +-81, 161, -30, 119, 19, 43, 45, -29, +62, -71, 67, -74, 68, -34, 71, 18, +70, 55, 45, 59, 9, 44, -28, 25, +-60, 10, -64, 0, -48, -1, -53, 1, +-92, -22, -116, -70, -102, -129, -56, -173, +-3, -194, 47, -178, 79, -118, 88, -32, +71, 61, 40, 153, 27, 233, 35, 272, +54, 259, 75, 198, 96, 106, 79, 1, +12, -85, -79, -124, -150, -108, -170, -64, +-130, -26, -50, -16, 33, -45, 103, -101, +127, -152, 93, -154, 37, -93, 3, 19, +-18, 137, -32, 211, -51, 203, -86, 118, +-136, -20, -158, -166, -109, -256, 0, -256, +118, -175, 178, -54, 153, 76, 66, 173, +-23, 220, -67, 219, -34, 201, 63, 180, +160, 147, 201, 96, 163, 32, 47, -39, +-107, -116, -228, -179, -273, -214, -230, -225, +-127, -226, -5, -207, 79, -154, 109, -66, +109, 44, 92, 155, 62, 235, 38, 247, +22, 184, -2, 75, -27, -34, -50, -105, +-71, -114, -88, -66, -81, 5, -43, 61, +15, 82, 77, 78, 128, 65, 149, 48, +128, 35, 78, 27, 13, 12, -45, -18, +-80, -64, -77, -111, -53, -152, -39, -171, +-53, -158, -87, -112, -120, -41, -108, 42, +-29, 111, 76, 145, 146, 139, 148, 96, +108, 37, 49, -10, 1, -5, -2, 48, +25, 116, 27, 155, -17, 125, -83, 19, +-141, -131, -156, -263, -116, -310, -24, -244, +84, -100, 169, 76, 188, 219, 136, 273, +52, 228, -18, 118, -54, -11, -54, -131, +-44, -215, -64, -243, -124, -212, -190, -136, +-194, -29, -106, 93, 57, 201, 222, 258, +320, 249, 313, 189, 211, 108, 54, 33, +-91, -14, -162, -31, -169, -47, -143, -93, +-107, -173, -67, -260, -35, -321, -3, -307, +34, -197, 60, -19, 51, 168, 13, 302, +-22, 333, -32, 256, -10, 128, 29, 7, +62, -63, 66, -65, 46, -9, 9, 51, +-38, 76, -78, 47, -72, -30, -23, -125, +45, -192, 121, -193, 172, -123, 157, -6, +67, 116, -41, 202, -130, 211, -179, 137, +-168, -1, -97, -155, -12, -267, 41, -300, +30, -243, -52, -113, -144, 37, -159, 153, +-57, 219, 132, 243, 340, 240, 442, 226, +347, 205, 80, 159, -234, 66, -452, -70, +-475, -209, -285, -313, 32, -346, 324, -295, +441, -174, 337, -23, 89, 93, -157, 146, +-293, 133, -281, 89, -151, 45, 18, 27, +144, 48, 192, 95, 168, 131, 75, 123, +-63, 66, -201, -33, -273, -140, -238, -210, +-97, -201, 86, -113, 230, 29, 286, 171, +240, 247, 115, 218, -23, 95, -113, -68, +-131, -213, -84, -269, -16, -207, 20, -67, +-22, 67, -119, 134, -211, 103, -216, -6, +-91, -117, 120, -137, 321, -32, 425, 152, +378, 335, 183, 427, -76, 369, -301, 154, +-406, -132, -365, -373, -198, -476, -5, -417, +124, -224, 159, 10, 109, 172, 18, 203, +-56, 119, -73, -7, -44, -104, 32, -110, +146, -23, 242, 104, 251, 186, 167, 177, +9, 77, -178, -59, -309, -155, -319, -155, +-216, -47, -60, 114, 96, 256, 201, 310, +236, 253, 187, 112, 73, -57, -61, -209, +-150, -310, -169, -345, -122, -324, -37, -263, +41, -169, 75, -45, 53, 78, 1, 165, +-52, 198, -58, 180, -5, 125, 87, 74, +186, 67, 254, 116, 220, 185, 61, 224, +-152, 203, -331, 104, -406, -61, -336, -235, +-130, -333, 110, -316, 281, -192, 320, -26, +224, 112, 44, 151, -129, 76, -227, -65, +-219, -195, -102, -242, 61, -183, 179, -34, +207, 140, 158, 265, 45, 286, -71, 214, +-134, 97, -114, 1, -23, -34, 90, 6, +158, 91, 138, 146, 51, 128, -80, 21, +-216, -146, -284, -316, -246, -412, -141, -388, +-12, -249, 117, -36, 210, 176, 227, 306, +189, 321, 128, 236, 54, 92, -14, -53, +-76, -138, -148, -126, -222, -43, -246, 60, +-200, 137, -90, 156, 62, 106, 212, 15, +302, -63, 307, -87, 251, -66, 164, -37, +56, -25, -70, -54, -189, -121, -277, -201, +-306, -232, -265, -184, -165, -59, -46, 111, +51, 266, 119, 349, 156, 329, 161, 226, +141, 78, 106, -66, 45, -169, -36, -207, +-114, -187, -161, -130, -171, -60, -121, 9, +-14, 64, 91, 97, 150, 113, 146, 107, +95, 70, 26, -3, -12, -87, -8, -153, +10, -176, 9, -149, -14, -77, -50, 11, +-79, 81, -77, 117, -41, 112, 18, 77, +63, 42, 51, 36, -22, 62, -109, 101, +-165, 119, -154, 90, -74, -4, 42, -139, +118, -262, 120, -314, 80, -266, 27, -121, +-6, 83, -9, 266, 2, 359, -1, 328, +0, 201, 11, 23, 15, -128, 1, -197, +-11, -168, -21, -87, -36, -17, -29, 16, +3, -6, 29, -62, 28, -119, 21, -136, +8, -106, -24, -49, -80, 18, -130, 78, +-149, 126, -120, 159, -46, 181, 40, 194, +105, 183, 133, 130, 132, 46, 108, -50, +86, -131, 70, -165, 44, -146, -19, -101, +-102, -57, -171, -42, -202, -68, -179, -123, +-93, -162, 34, -147, 128, -75, 149, 41, +96, 164, 7, 258, -75, 272, -109, 207, +-94, 89, -56, -39, -15, -136, 23, -165, +62, -110, 110, 2, 171, 131, 206, 224, +175, 249, 63, 178, -101, 19, -255, -180, +-328, -347, -287, -429, -142, -395, 33, -254, +150, -58, 167, 119, 98, 223, 2, 243, +-78, 187, -100, 107, -67, 52, -10, 57, +35, 120, 59, 195, 57, 226, 35, 177, +22, 54, 33, -100, 69, -219, 98, -254, +95, -209, 39, -128, -55, -71, -155, -79, +-217, -151, -217, -239, -161, -273, -75, -206, +20, -33, 101, 197, 147, 399, 152, 498, +107, 467, 30, 340, -51, 162, -94, 0, +-93, -102, -51, -135, 18, -129, 85, -122, +121, -137, 125, -177, 108, -217, 48, -228, +-51, -191, -157, -119, -229, -34, -258, 40, +-233, 86, -156, 92, -54, 66, 24, 50, +58, 62, 69, 94, 88, 140, 132, 187, +185, 206, 228, 178, 224, 112, 173, 34, +84, -46, -24, -116, -136, -159, -227, -176, +-269, -183, -257, -176, -190, -141, -71, -88, +60, -30, 133, 20, 123, 40, 41, 21, +-69, -18, -155, -53, -160, -52, -80, 12, +40, 138, 148, 282, 189, 380, 145, 382, +48, 270, -47, 80, -120, -136, -140, -304, +-90, -383, 6, -364, 89, -283, 132, -178, +127, -77, 80, -2, 18, 50, -40, 98, +-86, 152, -118, 187, -134, 188, -142, 153, +-133, 89, -119, 3, -120, -66, -136, -82, +-121, -44, -33, 25, 134, 93, 338, 135, +478, 134, 459, 87, 269, 12, -12, -66, +-279, -142, -424, -209, -410, -255, -288, -268, +-149, -247, -52, -188, -24, -92, -55, 28, +-81, 147, -45, 240, 61, 297, 193, 307, +302, 280, 319, 217, 232, 136, 87, 43, +-49, -49, -132, -122, -143, -161, -87, -155, +-12, -111, 32, -49, 17, -20, -39, -41, +-115, -105, -195, -180, -261, -243, -272, -255, +-220, -196, -123, -79, 13, 67, 166, 212, +286, 332, 322, 392, 268, 383, 133, 317, +-27, 209, -138, 70, -161, -72, -117, -194, +-27, -278, 74, -308, 132, -279, 120, -189, +50, -61, -58, 65, -176, 148, -261, 158, +-291, 82, -263, -54, -185, -187, -75, -250, +31, -205, 124, -50, 205, 162, 246, 348, +229, 428, 174, 369, 114, 193, 51, -37, +-7, -224, -63, -303, -107, -257, -142, -123, +-156, 35, -150, 140, -122, 158, -78, 93, +-58, -24, -68, -140, -81, -220, -75, -237, +-58, -195, -23, -104, 33, 6, 92, 102, +130, 166, 152, 193, 159, 193, 144, 182, +103, 175, 29, 160, -66, 130, -151, 73, +-185, -18, -159, -133, -81, -243, 10, -309, +66, -305, 37, -228, -59, -91, -165, 60, +-220, 174, -188, 217, -85, 186, 54, 100, +166, -11, 204, -107, 159, -157, 75, -137, +-12, -59, -60, 50, -58, 158, -30, 228, +-10, 231, -2, 166, 11, 59, 8, -61, +-7, -156, -34, -191, -84, -153, -159, -77, +-198, 3, -171, 52, -92, 47, 3, -13, +80, -89, 112, -134, 99, -123, 71, -45, +41, 65, 29, 158, 42, 191, 67, 155, +72, 67, 61, -30, 29, -91, -30, -91, +-104, -38, -174, 28, -219, 71, -223, 70, +-175, 35, -98, -16, -11, -56, 60, -62, +90, -40, 68, -21, 22, -17, -23, -34, +-47, -76, -39, -128, 2, -148, 66, -104, +131, 3, 191, 154, 205, 293, 152, 364, +38, 324, -96, 186, -221, -15, -284, -205, +-264, -317, -192, -312, -130, -207, -105, -60, +-87, 58, -64, 91, -20, 45, 51, -48, +151, -126, 234, -135, 260, -62, 210, 58, +101, 171, -39, 230, -151, 207, -188, 115, +-155, 5, -72, -66, 8, -79, 43, -39, +17, 20, -33, 59, -91, 53, -154, 11, +-195, -43, -178, -88, -103, -105, 3, -88, +122, -59, 207, -45, 221, -55, 151, -89, +35, -129, -87, -141, -164, -97, -162, 4, +-87, 138, 19, 260, 116, 338, 157, 340, +118, 255, 28, 111, -77, -49, -158, -184, +-211, -266, -231, -265, -225, -193, -180, -79, +-90, 27, 28, 97, 139, 108, 208, 52, +208, -45, 125, -140, -2, -183, -122, -157, +-179, -57, -159, 89, -65, 224, 65, 295, +174, 280, 203, 186, 137, 36, 8, -112, +-136, -208, -243, -228, -282, -175, -238, -75, +-135, 30, -7, 104, 96, 128, 143, 103, +129, 45, 77, -19, 15, -66, -27, -84, +-44, -79, -51, -63, -55, -44, -62, -23, +-61, 3, -65, 33, -67, 64, -64, 89, +-63, 99, -54, 85, -22, 49, 25, -1, +62, -54, 75, -89, 62, -93, 37, -60, +3, -3, -24, 70, -45, 122, -49, 124, +-42, 64, -37, -43, -36, -162, -30, -241, +-21, -236, -10, -134, 7, 40, -3, 215, +-53, 316, -131, 291, -191, 148, -208, -58, +-157, -246, -60, -341, 40, -303, 105, -143, +131, 77, 126, 271, 102, 370, 93, 342, +100, 200, 104, 1, 79, -186, 38, -302, +-42, -316, -152, -232, -249, -83, -293, 84, +-269, 203, -169, 232, -21, 170, 105, 41, +165, -103, 133, -202, 17, -211, -145, -131, +-261, 2, -264, 122, -142, 182, 53, 157, +245, 62, 354, -52, 336, -123, 208, -117, +18, -39, -158, 84, -273, 185, -289, 213, +-211, 150, -67, 29, 70, -104, 129, -193, +80, -207, -49, -153, -185, -66, -262, 10, +-244, 49, -141, 36, 11, -6, 144, -46, +214, -62, 203, -40, 133, 12, 29, 79, +-67, 132, -114, 152, -101, 134, -52, 76, +-5, -2, 20, -71, 2, -105, -56, -90, +-143, -39, -208, 17, -221, 45, -168, 33, +-49, -18, 110, -77, 248, -111, 298, -96, +240, -34, 96, 45, -77, 114, -216, 146, +-262, 134, -227, 86, -141, 26, -43, -37, +33, -94, 51, -132, 11, -144, -57, -130, +-135, -89, -179, -22, -159, 47, -79, 99, +27, 113, 147, 98, 233, 72, 240, 55, +174, 54, 69, 64, -47, 65, -135, 34, +-147, -26, -101, -98, -53, -154, -44, -167, +-81, -124, -147, -42, -179, 40, -143, 87, +-57, 83, 21, 36, 46, -29, 1, -77, +-90, -78, -157, -29, -156, 52, -77, 128, +61, 162, 211, 144, 295, 79, 286, -6, +200, -82, 64, -119, -90, -106, -207, -64, +-255, -21, -245, 2, -178, 4, -74, -9, +25, -19, 55, -21, 0, -15, -119, -28, +-239, -53, -293, -72, -226, -60, -48, -1, +173, 102, 354, 220, 416, 294, 334, 278, +144, 153, -64, -41, -230, -228, -309, -329, +-290, -301, -203, -166, -117, 13, -61, 153, +-26, 198, -21, 134, -24, 1, -15, -134, +10, -207, 26, -189, 40, -92, 46, 39, +37, 147, 6, 190, -24, 170, -37, 116, +-37, 65, -10, 44, 29, 51, 64, 65, +72, 59, 38, 17, -57, -54, -187, -121, +-310, -161, -370, -158, -335, -125, -194, -89, +7, -76, 176, -84, 259, -83, 238, -51, +145, 23, 28, 113, -42, 195, -46, 222, +10, 188, 90, 111, 142, 37, 117, -4, +18, -7, -119, 12, -248, 19, -307, -2, +-283, -52, -204, -102, -120, -128, -49, -117, +-21, -82, -35, -58, -61, -63, -60, -98, +-26, -135, 37, -137, 120, -76, 183, 43, +200, 177, 168, 275, 124, 295, 75, 237, +37, 128, 5, 22, -29, -35, -86, -29, +-151, 23, -202, 69, -244, 66, -269, -10, +-286, -150, -289, -296, -274, -388, -213, -378, +-108, -264, 27, -83, 172, 96, 304, 212, +379, 229, 381, 158, 330, 51, 237, -28, +115, -28, -9, 63, -110, 220, -208, 367, +-293, 435, -346, 376, -347, 195, -298, -59, +-202, -306, -91, -463, -15, -495, 10, -405, +-6, -244, -27, -86, -31, 4, 4, 2, +51, -66, 86, -141, 105, -155, 116, -74, +117, 95, 131, 295, 156, 456, 146, 532, +73, 510, -58, 412, -204, 269, -321, 104, +-346, -71, -275, -246, -153, -409, -50, -539, +-1, -587, -13, -526, -55, -354, -79, -111, +-73, 124, -40, 278, 0, 305, 51, 219, +106, 75, 172, -38, 230, -59, 241, 42, +169, 220, 24, 393, -152, 480, -299, 424, +-353, 228, -296, -48, -158, -306, -31, -469, +30, -501, 5, -425, -64, -295, -122, -172, +-109, -92, -15, -50, 110, -18, 200, 41, +206, 140, 133, 256, 15, 344, -87, 366, +-139, 311, -133, 197, -99, 70, -78, -30, +-99, -81, -148, -84, -193, -65, -193, -57, +-123, -81, -7, -137, 109, -206, 188, -256, +225, -257, 196, -201, 108, -98, -19, 23, +-148, 129, -251, 194, -281, 205, -214, 165, +-85, 100, 53, 45, 142, 33, 156, 81, +90, 162, -7, 235, -118, 242, -216, 158, +-257, -16, -224, -225, -146, -402, -43, -491, +69, -449, 137, -286, 133, -51, 84, 171, +29, 313, -32, 326, -61, 213, -30, 34, +48, -130, 117, -204, 144, -141, 91, 48, +-46, 288, -205, 472, -319, 509, -348, 364, +-297, 69, -191, -278, -95, -557, -31, -681, +4, -615, 30, -386, 54, -76, 105, 212, +181, 391, 242, 423, 247, 322, 172, 148, +34, -23, -130, -139, -244, -157, -279, -80, +-236, 65, -156, 217, -71, 318, -14, 320, +1, 206, -22, -3, -69, -250, -110, -450, +-121, -542, -79, -488, -5, -299, 83, -31, +141, 220, 149, 375, 101, 389, 22, 269, +-59, 87, -121, -71, -132, -138, -84, -93, +0, 31, 56, 156, 52, 212, -37, 164, +-180, 29, -305, -138, -335, -266, -256, -296, +-102, -217, 76, -65, 219, 100, 287, 209, +268, 219, 187, 132, 57, -17, -64, -167, +-135, -255, -146, -241, -121, -123, -98, 67, +-114, 255, -161, 368, -179, 361, -133, 240, +-38, 49, 60, -143, 126, -268, 100, -301, +-16, -247, -170, -151, -274, -55, -279, -3, +-154, 7, 71, -3, 290, -4, 400, 35, +351, 97, 169, 161, -63, 195, -236, 189, +-306, 140, -280, 70, -194, 4, -91, -34, +-22, -39, 1, -35, -6, -53, -46, -110, +-103, -201, -142, -292, -133, -333, -82, -287, +7, -144, 107, 70, 182, 290, 192, 446, +142, 475, 43, 364, -70, 159, -143, -69, +-142, -238, -74, -291, -4, -224, 19, -79, +-45, 72, -168, 170, -269, 171, -276, 74, +-187, -78, -37, -217, 117, -293, 209, -279, +209, -182, 138, -43, 36, 87, -85, 169, +-175, 197, -198, 176, -143, 145, -43, 129, +78, 142, 175, 165, 201, 169, 138, 126, +5, 21, -161, -126, -316, -274, -390, -374, +-354, -397, -217, -331, -48, -198, 90, -40, +143, 92, 127, 169, 96, 193, 90, 183, +120, 173, 155, 173, 148, 175, 67, 159, +-53, 111, -162, 34, -221, -38, -227, -69, +-179, -49, -114, 6, -65, 51, -45, 30, +-53, -85, -80, -268, -115, -438, -126, -508, +-102, -420, -28, -177, 66, 137, 156, 408, +214, 538, 226, 498, 174, 319, 65, 87, +-67, -97, -186, -168, -259, -117, -250, 12, +-138, 154, 16, 233, 136, 213, 156, 82, +67, -120, -107, -337, -286, -502, -387, -562, +-370, -494, -252, -306, -81, -56, 96, 188, +227, 364, 298, 440, 304, 415, 264, 327, +186, 221, 98, 136, -5, 90, -124, 83, +-237, 89, -315, 70, -334, 7, -286, -96, +-168, -219, -34, -334, 61, -418, 87, -447, +50, -409, -48, -305, -159, -147, -215, 33, +-178, 202, -46, 329, 148, 396, 331, 400, +413, 354, 370, 276, 212, 189, 2, 115, +-197, 58, -322, 21, -370, -14, -350, -60, +-279, -125, -190, -202, -121, -276, -91, -331, +-78, -352, -70, -343, -28, -291, 56, -200, +155, -65, 213, 98, 211, 263, 156, 389, +73, 441, -4, 401, -40, 271, -31, 101, +0, -38, 32, -86, 22, -33, -40, 78, +-153, 173, -272, 175, -351, 55, -355, -162, +-294, -397, -200, -566, -99, -601, 0, -480, +96, -240, 180, 54, 249, 315, 280, 473, +262, 500, 184, 407, 83, 238, -20, 52, +-111, -89, -172, -150, -184, -119, -150, -21, +-110, 95, -88, 173, -102, 172, -138, 95, +-188, -50, -211, -217, -187, -370, -116, -460, +-24, -462, 73, -361, 162, -157, 222, 111, +239, 379, 200, 564, 126, 605, 29, 475, +-67, 221, -151, -70, -203, -292, -220, -368, +-202, -283, -165, -84, -119, 127, -70, 252, +-24, 238, 25, 94, 54, -125, 53, -332, +7, -449, -76, -438, -152, -305, -154, -97, +-78, 126, 43, 303, 163, 399, 234, 411, +219, 351, 129, 250, 16, 131, -105, 16, +-202, -86, -241, -166, -214, -208, -164, -216, +-113, -186, -83, -131, -94, -67, -124, -20, +-125, -12, -80, -44, -17, -95, 55, -128, +118, -112, 171, -29, 213, 96, 240, 226, +217, 313, 137, 333, 11, 282, -133, 175, +-258, 49, -331, -70, -335, -158, -291, -206, +-200, -214, -83, -198, 30, -168, 90, -133, +97, -99, 61, -70, 0, -42, -61, 2, +-99, 58, -98, 110, -63, 143, 2, 146, +81, 121, 158, 83, 185, 57, 162, 56, +107, 77, 47, 109, -20, 124, -98, 102, +-184, 41, -267, -44, -327, -135, -345, -219, +-294, -280, -188, -310, -56, -295, 62, -238, +154, -126, 200, 28, 191, 192, 138, 313, +73, 359, 24, 321, 1, 209, 8, 67, +15, -55, 11, -102, -15, -69, -50, 20, +-95, 116, -141, 168, -182, 129, -207, -11, +-201, -209, -157, -394, -95, -492, -51, -464, +-24, -307, -11, -70, 6, 165, 39, 329, +110, 392, 186, 367, 241, 296, 261, 227, +223, 183, 101, 147, -83, 83, -273, -36, +-417, -194, -456, -345, -379, -421, -215, -382, +-39, -241, 103, -56, 172, 96, 170, 161, +122, 125, 59, 33, 1, -45, -39, -51, +-51, 27, -53, 153, -39, 269, -9, 317, +37, 272, 64, 142, 71, -15, 52, -150, +2, -224, -72, -223, -145, -159, -199, -72, +-242, -14, -255, -6, -230, -60, -161, -146, +-64, -214, 54, -216, 167, -133, 262, 25, +312, 224, 297, 397, 202, 470, 42, 410, +-141, 239, -311, 6, -403, -220, -383, -363, +-257, -378, -87, -267, 87, -75, 223, 126, +283, 260, 237, 277, 100, 173, -90, -14, +-290, -217, -419, -366, -417, -401, -276, -311, +-50, -124, 200, 115, 392, 342, 468, 492, +403, 509, 221, 389, -26, 167, -257, -95, +-391, -319, -399, -432, -288, -397, -120, -239, +28, -20, 86, 172, 62, 267, -13, 226, +-94, 76, -145, -115, -143, -268, -91, -324, +-10, -260, 80, -89, 146, 125, 182, 319, +181, 431, 156, 431, 103, 316, 34, 120, +-49, -99, -136, -285, -220, -382, -275, -358, +-284, -226, -245, -38, -158, 130, -53, 211, +48, 175, 111, 42, 132, -126, 93, -250, +15, -275, -59, -180, -94, 16, -74, 243, +10, 411, 131, 453, 223, 350, 238, 130, +151, -131, -2, -331, -178, -402, -308, -327, +-359, -147, -324, 61, -214, 203, -62, 228, +80, 145, 162, 5, 157, -116, 66, -165, +-65, -131, -174, -51, -199, 31, -140, 69, +-13, 59, 136, 23, 251, -2, 281, 6, +222, 49, 102, 112, -42, 153, -154, 147, +-207, 94, -206, 21, -192, -54, -183, -110, +-191, -138, -194, -147, -171, -147, -112, -135, +-28, -107, 68, -69, 158, -22, 211, 29, +216, 67, 172, 77, 93, 67, -7, 51, +-75, 46, -76, 73, -23, 133, 33, 212, +55, 267, 20, 253, -69, 151, -183, -27, +-294, -239, -361, -423, -356, -523, -254, -503, +-84, -366, 117, -140, 276, 109, 334, 314, +276, 428, 151, 441, 38, 362, -26, 213, +-39, 47, -28, -88, -21, -168, -34, -194, +-62, -171, -113, -115, -172, -52, -224, -10, +-227, 6, -162, 0, -47, -20, 75, -35, +144, -29, 140, 6, 78, 71, 11, 150, +-34, 210, -48, 207, -52, 125, -47, -32, +-40, -225, -48, -393, -68, -476, -84, -424, +-74, -226, -29, 78, 54, 402, 144, 653, +197, 751, 166, 656, 58, 382, -99, -3, +-246, -395, -340, -698, -357, -843, -282, -796, +-143, -563, 22, -207, 153, 173, 226, 489, +232, 683, 195, 737, 129, 642, 62, 435, +4, 176, -48, -83, -103, -312, -148, -488, +-164, -584, -165, -585, -153, -479, -126, -275, +-68, -6, -6, 270, 48, 484, 82, 580, +82, 538, 39, 374, -26, 125, -79, -148, +-97, -381, -69, -530, -8, -580, 73, -517, +137, -320, 161, -10, 118, 353, 25, 693, +-70, 917, -131, 929, -156, 681, -147, 206, +-119, -389, -104, -938, -119, -1279, -155, -1296, +-161, -967, -131, -374, -59, 320, 55, 918, +196, 1254, 312, 1243, 340, 907, 254, 359, +92, -236, -84, -705, -218, -919, -268, -840, +-240, -530, -154, -105, -58, 303, 15, 573, +48, 631, 48, 485, 23, 205, -20, -120, +-82, -399, -143, -570, -169, -601, -150, -488, +-71, -251, 51, 56, 186, 370, 262, 621, +232, 738, 95, 667, -88, 408, -242, 34, +-308, -347, -248, -628, -76, -728, 141, -610, +307, -309, 363, 70, 278, 403, 80, 585, +-176, 573, -398, 382, -521, 70, -512, -268, +-380, -521, -168, -613, 91, -526, 332, -283, +490, 44, 532, 359, 472, 573, 303, 626, +54, 508, -221, 254, -442, -50, -572, -324, +-592, -498, -470, -518, -225, -393, 79, -166, +358, 94, 533, 318, 554, 434, 420, 410, +162, 255, -125, 24, -349, -221, -452, -419, +-442, -502, -342, -434, -165, -234, 43, 36, +228, 309, 337, 518, 342, 605, 234, 531, +62, 305, -119, -12, -247, -344, -299, -596, +-272, -680, -184, -566, -81, -285, 12, 89, +82, 439, 124, 642, 138, 623, 135, 389, +118, 33, 87, -317, 29, -528, -41, -521, +-102, -312, -125, 2, -111, 288, -93, 447, +-88, 419, -102, 219, -112, -63, -108, -295, +-54, -384, 50, -331, 151, -182, 187, 6, +142, 170, 33, 259, -96, 259, -197, 196, +-222, 102, -151, -3, -26, -114, 124, -207, +247, -248, 289, -217, 219, -118, 52, 31, +-162, 199, -338, 316, -419, 315, -372, 188, +-208, -13, 14, -211, 238, -336, 374, -332, +393, -199, 280, 14, 51, 224, -220, 343, +-424, 310, -486, 131, -391, -120, -181, -337, +95, -428, 371, -346, 540, -94, 547, 255, +371, 569, 60, 700, -302, 579, -596, 240, +-716, -227, -611, -690, -319, -976, 62, -950, +406, -609, 607, -62, 623, 534, 441, 996, +135, 1160, -203, 957, -463, 459, -581, -186, +-529, -781, -326, -1117, -15, -1071, 317, -673, +558, -67, 621, 547, 477, 962, 161, 1039, +-260, 757, -646, 221, -855, -385, -792, -864, +-485, -1049, -26, -876, 465, -421, 844, 160, +980, 694, 804, 1015, 372, 1014, -172, 692, +-653, 149, -937, -435, -929, -867, -640, -1000, +-171, -806, 306, -360, 654, 198, 801, 696, +697, 955, 366, 875, -73, 498, -470, -46, +-716, -587, -749, -956, -578, -1026, -245, -760, +128, -241, 435, 385, 601, 918, 591, 1172, +432, 1061, 169, 624, -107, -8, -305, -629, +-377, -1023, -331, -1062, -202, -756, -70, -239, +14, 306, 10, 691, -53, 777, -109, 549, +-120, 124, -69, -309, 23, -593, 124, -627, +208, -393, 252, 14, 238, 429, 163, 702, +23, 747, -134, 548, -265, 171, -324, -253, +-281, -587, -141, -735, 54, -665, 227, -396, +310, -24, 250, 317, 61, 510, -197, 502, +-418, 310, -506, 11, -408, -282, -156, -438, +164, -387, 437, -167, 572, 134, 535, 407, +333, 540, 44, 464, -248, 223, -445, -65, +-481, -300, -342, -424, -96, -399, 152, -239, +290, -28, 268, 134, 86, 184, -189, 116, +-408, -31, -475, -189, -351, -279, -97, -243, +198, -72, 462, 182, 616, 425, 592, 571, +396, 555, 82, 360, -245, 51, -491, -249, +-613, -452, -563, -528, -373, -478, -105, -327, +158, -129, 342, 45, 413, 168, 359, 254, +181, 309, -47, 308, -231, 237, -310, 104, +-283, -79, -206, -266, -88, -386, 53, -387, +184, -269, 256, -53, 253, 219, 203, 458, +140, 569, 54, 522, -58, 351, -176, 90, +-271, -220, -311, -491, -285, -628, -174, -596, +-10, -414, 129, -119, 188, 214, 176, 473, +112, 551, 18, 415, -84, 111, -161, -259, +-182, -569, -141, -684, -40, -516, 98, -102, +242, 421, 338, 880, 356, 1119, 276, 1034, +112, 623, -102, 5, -321, -646, -476, -1137, +-530, -1309, -481, -1118, -335, -648, -112, -55, +123, 485, 316, 812, 412, 847, 430, 623, +385, 263, 283, -81, 151, -267, 10, -232, +-124, -31, -246, 209, -358, 349, -424, 298, +-412, 44, -344, -316, -198, -630, 15, -750, +277, -596, 516, -191, 629, 343, 580, 815, +384, 1032, 83, 890, -273, 412, -614, -284, +-822, -978, -804, -1423, -593, -1439, -245, -976, +152, -130, 512, 853, 741, 1640, 772, 1960, +636, 1716, 420, 966, 183, -86, -58, -1094, +-288, -1717, -488, -1810, -629, -1423, -730, -708, +-753, 90, -631, 706, -329, 986, 108, 948, +578, 705, 982, 400, 1205, 162, 1145, 42, +756, -1, 122, -44, -595, -134, -1205, -294, +-1544, -493, -1483, -647, -1003, -641, -201, -416, +703, -22, 1441, 429, 1785, 798, 1602, 957, +949, 815, 1, 397, -965, -163, -1653, -686, +-1850, -1011, -1502, -1033, -720, -729, 227, -184, +1055, 421, 1535, 890, 1546, 1092, 1137, 986, +452, 591, -271, 20, -828, -538, -1112, -904, +-1081, -998, -783, -822, -348, -428, 105, 51, +456, 445, 645, 641, 661, 621, 514, 432, +275, 161, -8, -76, -259, -194, -406, -177, +-440, -76, -387, 34, -265, 80, -106, 32, +69, -88, 212, -209, 303, -253, 360, -183, +352, -22, 271, 167, 118, 318, -75, 349, +-272, 209, -433, -68, -506, -356, -441, -547, +-248, -570, 21, -378, 280, 4, 453, 457, +512, 813, 415, 951, 174, 809, -124, 388, +-360, -200, -495, -757, -500, -1092, -349, -1107, +-58, -788, 270, -207, 508, 456, 587, 950, +496, 1097, 248, 874, -108, 363, -448, -271, +-658, -804, -649, -1025, -457, -853, -163, -371, +160, 237, 429, 748, 570, 975, 537, 834, +351, 397, 106, -155, -126, -615, -311, -811, +-394, -679, -364, -289, -233, 177, -74, 520, +47, 604, 145, 410, 215, 28, 234, -381, +193, -634, 89, -613, -46, -318, -185, 129, +-319, 549, -373, 753, -311, 651, -124, 284, +148, -199, 412, -592, 582, -720, 578, -514, +371, -46, 34, 489, -327, 845, -613, 832, +-738, 422, -657, -236, -353, -890, 75, -1266, +480, -1178, 738, -629, 751, 182, 481, 956, +13, 1410, -450, 1371, -726, 859, -738, 82, +-497, -677, -59, -1161, 420, -1198, 746, -793, +787, -135, 546, 502, 105, 897, -385, 922, +-746, 572, -835, -21, -604, -610, -162, -947, +305, -906, 626, -499, 715, 122, 552, 727, +194, 1066, -227, 996, -523, 554, -600, -75, +-468, -641, -178, -932, 160, -846, 425, -451, +491, 61, 336, 452, 75, 574, -159, 413, +-299, 94, -308, -208, -211, -357, -36, -290, +136, -56, 210, 205, 190, 352, 96, 316, +-18, 116, -115, -143, -180, -321, -169, -338, +-70, -212, 26, 9, 61, 239, 30, 346, +8, 262, 34, 70, 66, -111, 112, -221, +163, -229, 180, -104, 116, 92, -31, 212, +-210, 167, -350, -20, -417, -256, -358, -442, +-171, -468, 85, -266, 326, 115, 446, 529, +405, 800, 235, 822, 25, 567, -159, 102, +-265, -445, -274, -887, -177, -1055, -19, -868, +134, -385, 221, 239, 202, 816, 85, 1150, +-84, 1103, -252, 647, -379, -80, -371, -835, +-206, -1352, 56, -1417, 301, -973, 450, -165, +474, 739, 348, 1443, 87, 1678, -207, 1324, +-425, 510, -503, -450, -398, -1235, -158, -1581, +148, -1357, 391, -651, 473, 235, 360, 970, +82, 1325, -235, 1196, -441, 621, -479, -189, +-347, -920, -65, -1314, 269, -1262, 531, -801, +585, -61, 432, 733, 139, 1320, -232, 1494, +-566, 1203, -745, 549, -693, -267, -394, -989, +49, -1388, 491, -1341, 802, -877, 861, -159, +649, 557, 209, 1040, -307, 1150, -713, 884, +-899, 355, -810, -254, -442, -751, 82, -992, +553, -903, 800, -525, 769, 8, 511, 527, +83, 871, -373, 941, -686, 724, -753, 295, +-575, -213, -220, -639, 198, -843, 533, -769, +665, -477, 565, -86, 298, 296, -41, 571, +-340, 669, -509, 573, -501, 325, -334, 9, +-67, -290, 190, -496, 345, -563, 364, -474, +251, -247, 56, 49, -163, 331, -317, 510, +-351, 523, -272, 360, -112, 93, 93, -185, +259, -394, 347, -470, 343, -380, 251, -153, +103, 121, -85, 346, -253, 434, -362, 355, +-404, 129, -358, -168, -213, -425, 16, -531, +316, -420, 565, -119, 634, 272, 458, 617, +83, 774, -336, 652, -682, 268, -842, -259, +-714, -748, -328, -1007, 178, -919, 658, -513, +960, 72, 981, 651, 656, 1017, 87, 1008, +-500, 625, -922, 51, -1043, -483, -835, -807, +-366, -803, 209, -460, 696, 51, 913, 474, +797, 643, 392, 536, -117, 199, -532, -241, +-716, -571, -617, -632, -311, -431, 72, -90, +389, 266, 542, 498, 482, 509, 265, 318, +-6, 55, -227, -144, -354, -182, -371, -61, +-264, 101, -69, 155, 116, 41, 215, -199, +222, -481, 136, -647, 5, -521, -130, -78, +-215, 501, -220, 947, -154, 1036, -32, 678, +117, -17, 246, -768, 331, -1263, 329, -1271, +207, -720, 14, 207, -188, 1102, -316, 1573, +-363, 1443, -328, 745, -182, -299, 35, -1274, +220, -1742, 305, -1525, 263, -744, 128, 308, +-52, 1247, -242, 1694, -345, 1444, -334, 627, +-197, -386, 36, -1187, 274, -1493, 451, -1195, +513, -433, 409, 467, 149, 1130, -198, 1280, +-501, 878, -631, 139, -546, -588, -234, -1023, +186, -1010, 531, -549, 664, 169, 546, 807, +214, 1067, -219, 846, -608, 242, -808, -489, +-746, -1052, -438, -1225, 59, -936, 579, -274, +921, 511, 956, 1108, 684, 1321, 190, 1122, +-368, 588, -789, -121, -929, -752, -747, -1086, +-319, -1074, 211, -778, 625, -290, 751, 248, +561, 662, 159, 822, -305, 695, -622, 349, +-659, -63, -405, -388, 35, -541, 474, -489, +741, -240, 701, 105, 353, 363, -166, 407, +-666, 251, -955, -9, -877, -262, -437, -388, +227, -302, 865, -25, 1218, 313, 1156, 570, +672, 617, -68, 384, -816, -69, -1346, -564, +-1460, -900, -1095, -947, -397, -644, 408, -80, +1064, 531, 1395, 976, 1288, 1104, 760, 836, +49, 232, -581, -458, -950, -956, -970, -1090, +-655, -820, -143, -212, 346, 521, 591, 1082, +547, 1241, 274, 931, -97, 239, -412, -586, +-575, -1212, -518, -1397, -244, -1091, 151, -397, +498, 451, 669, 1130, 607, 1354, 352, 1029, +-28, 316, -392, -484, -602, -1080, -593, -1257, +-372, -922, -14, -179, 358, 681, 595, 1327, +609, 1509, 388, 1157, 11, 378, -399, -561, +-682, -1344, -733, -1699, -556, -1503, -213, -815, +211, 127, 579, 980, 763, 1446, 728, 1379, +473, 835, 80, 31, -341, -718, -640, -1122, +-728, -1044, -614, -543, -328, 159, 74, 780, +447, 1066, 676, 913, 707, 413, 528, -208, +202, -705, -185, -887, -499, -705, -660, -274, +-640, 201, -449, 521, -163, 542, 112, 262, +335, -167, 472, -546, 503, -726, 418, -597, +228, -153, 17, 419, -175, 878, -314, 1088, +-368, 995, -321, 567, -173, -86, 37, -707, +213, -1071, 291, -1100, 246, -810, 98, -282, +-90, 293, -266, 719, -334, 881, -254, 755, +-80, 391, 103, -64, 250, -447, 335, -670, +322, -700, 185, -542, -21, -250, -197, 93, +-284, 420, -256, 661, -140, 743, 15, 647, +149, 405, 236, 65, 240, -311, 147, -616, +-5, -734, -153, -630, -264, -360, -339, -23, +-330, 256, -195, 377, 25, 326, 238, 161, +400, -42, 468, -179, 426, -148, 264, 48, +20, 279, -239, 398, -450, 341, -522, 117, +-434, -209, -225, -500, 65, -603, 341, -450, +465, -59, 408, 428, 221, 770, 0, 769, +-199, 417, -325, -157, -317, -757, -197, -1128, +-24, -1060, 152, -533, 259, 248, 247, 996, +143, 1396, -6, 1235, -128, 558, -182, -329, +-126, -1081, 24, -1407, 165, -1133, 217, -349, +154, 583, -8, 1251, -209, 1396, -351, 941, +-357, 39, -214, -913, 0, -1475, 231, -1424, +409, -804, 448, 147, 330, 1042, 105, 1496, +-140, 1341, -317, 675, -358, -223, -266, -970, +-89, -1245, 109, -982, 276, -389, 321, 282, +207, 788, -13, 897, -242, 558, -400, 16, +-410, -418, -235, -605, 45, -513, 312, -180, +460, 215, 456, 430, 306, 375, 69, 116, +-161, -201, -313, -400, -345, -354, -228, -81, +-17, 293, 166, 603, 249, 657, 215, 362, +96, -154, -98, -619, -294, -858, -371, -802, +-283, -429, -83, 161, 173, 708, 403, 947, +513, 787, 442, 316, 199, -250, -108, -672, +-377, -810, -491, -636, -398, -208, -161, 300, +127, 650, 366, 692, 428, 464, 268, 98, +-47, -275, -353, -521, -490, -522, -405, -289, +-112, 36, 275, 316, 596, 469, 704, 435, +524, 194, 96, -167, -409, -498, -769, -672, +-817, -628, -539, -370, -33, 51, 535, 536, +912, 934, 910, 1062, 532, 843, -58, 345, +-641, -289, -997, -919, -977, -1341, -574, -1332, +45, -845, 643, -53, 1018, 790, 1016, 1432, +643, 1623, 61, 1225, -503, 349, -860, -704, +-870, -1575, -543, -1944, -30, -1626, 460, -699, +751, 532, 756, 1654, 473, 2253, 17, 2079, +-423, 1188, -711, -113, -761, -1392, -528, -2222, +-114, -2294, 305, -1575, 593, -347, 706, 938, +639, 1861, 387, 2129, 29, 1654, -319, 621, +-558, -583, -616, -1538, -474, -1944, -193, -1679, +157, -836, 471, 306, 646, 1340, 582, 1894, +286, 1788, -112, 1095, -503, 72, -772, -958, +-774, -1659, -465, -1776, 47, -1263, 578, -367, +928, 544, 990, 1162, 714, 1327, 168, 1031, +-443, 416, -889, -262, -1006, -738, -758, -840, +-249, -592, 328, -169, 771, 235, 916, 471, +731, 456, 279, 234, -268, -38, -681, -211, +-818, -229, -674, -91, -321, 142, 129, 302, +526, 245, 746, -12, 737, -335, 520, -588, +165, -636, -205, -414, -485, 14, -619, 493, +-596, 834, -418, 854, -139, 517, 170, 3, +452, -455, 640, -718, 669, -699, 487, -359, +136, 155, -270, 569, -625, 705, -827, 546, +-770, 138, -432, -381, 105, -775, 659, -859, +1028, -614, 1073, -158, 735, 347, 122, 731, +-564, 856, -1084, 666, -1226, 240, -910, -249, +-264, -603, 491, -691, 1101, -507, 1353, -139, +1118, 309, 454, 686, -366, 802, -1066, 583, +-1420, 121, -1285, -425, -669, -904, 213, -1137, +1036, -982, 1487, -462, 1420, 248, 873, 930, +47, 1352, -753, 1333, -1274, 870, -1333, 117, +-909, -709, -195, -1333, 511, -1471, 991, -1076, +1116, -336, 844, 509, 275, 1221, -325, 1508, +-711, 1210, -802, 476, -621, -397, -245, -1132, +176, -1490, 461, -1312, 553, -672, 464, 164, +246, 920, 28, 1347, -71, 1296, -70, 836, +-61, 176, -75, -484, -137, -949, -274, -1064, +-413, -841, -406, -443, -201, 5, 142, 419, +503, 664, 754, 664, 754, 530, 460, 373, +-25, 153, -542, -132, -897, -376, -900, -534, +-514, -636, 105, -629, 734, -427, 1128, -45, +1126, 418, 688, 852, -47, 1078, -784, 932, +-1245, 426, -1266, -266, -819, -947, -74, -1382, +676, -1327, 1158, -752, 1191, 119, 785, 989, +119, 1569, -524, 1589, -907, 992, -903, 17, +-513, -963, 105, -1616, 675, -1698, 926, -1129, +763, -124, 294, 909, -268, 1574, -712, 1644, +-846, 1084, -616, 111, -128, -884, 391, -1520, +727, -1560, 783, -971, 548, 11, 100, 954, +-388, 1484, -715, 1455, -758, 896, -496, -29, +-64, -965, 379, -1498, 718, -1433, 856, -863, +700, -17, 298, 817, -162, 1337, -529, 1362, +-746, 904, -764, 149, -518, -617, -81, -1105, +359, -1182, 652, -864, 747, -263, 606, 421, +269, 912, -150, 1039, -515, 816, -689, 322, +-586, -312, -231, -827, 220, -987, 618, -798, +845, -364, 775, 210, 364, 738, -204, 967, +-675, 796, -917, 342, -884, -185, -533, -594, +60, -771, 629, -692, 954, -384, 945, 71, +610, 459, 67, 586, -453, 487, -756, 332, +-754, 143, -452, -104, 46, -305, 518, -374, +760, -379, 720, -374, 413, -284, -63, -58, +-523, 245, -761, 515, -687, 674, -359, 641, +89, 357, 524, -135, 775, -657, 716, -982, +367, -945, -131, -535, -569, 97, -778, 728, +-662, 1115, -250, 1074, 291, 569, 757, -190, +986, -839, 849, -1093, 391, -897, -159, -348, +-605, 375, -843, 954, -810, 1067, -509, 638, +-71, -86, 334, -753, 579, -1079, 623, -938, +482, -364, 228, 419, -64, 1058, -305, 1228, +-407, 826, -335, 52, -148, -745, 59, -1252, +263, -1282, 432, -774, 499, 106, 413, 974, +194, 1459, -100, 1407, -390, 873, -606, 38, +-692, -827, -554, -1419, -170, -1523, 321, -1144, +730, -462, 922, 310, 814, 980, 428, 1346, +-160, 1292, -740, 863, -1012, 223, -847, -454, +-340, -1000, 321, -1227, 932, -1027, 1286, -475, +1161, 238, 512, 901, -365, 1269, -1113, 1172, +-1489, 623, -1351, -193, -724, -1005, 182, -1509, +1049, -1481, 1538, -920, 1454, -30, 877, 887, +78, 1525, -635, 1618, -1063, 1145, -1094, 343, +-733, -498, -157, -1145, 364, -1357, 678, -1058, +758, -447, 607, 197, 291, 687, -44, 909, +-272, 807, -372, 483, -349, 95, -258, -261, +-162, -526, -68, -632, 53, -600, 178, -497, +245, -300, 255, 21, 272, 370, 274, 640, +179, 797, 28, 776, -106, 500, -183, 22, +-172, -482, -94, -844, -7, -940, 77, -717, +138, -232, 128, 349, 31, 819, -100, 1001, +-169, 790, -182, 256, -161, -394, -42, -939, +162, -1195, 313, -1015, 366, -435, 364, 313, +327, 955, 206, 1297, -8, 1220, -227, 711, +-379, -49, -423, -744, -343, -1125, -186, -1122, +24, -743, 295, -99, 520, 562, 560, 960, +404, 968, 151, 631, -151, 82, -480, -503, +-680, -952, -598, -1100, -277, -849, 145, -258, +583, 419, 903, 938, 940, 1195, 631, 1133, +123, 656, -378, -129, -759, -866, -916, -1264, +-764, -1240, -360, -777, 148, 40, 619, 891, +872, 1421, 789, 1416, 443, 834, 23, -158, +-389, -1150, -715, -1724, -755, -1687, -442, -1029, +30, 97, 476, 1262, 814, 1911, 898, 1816, +631, 1091, 141, -34, -326, -1193, -649, -1844, +-754, -1675, -553, -844, -155, 255, 189, 1240, +391, 1750, 455, 1514, 338, 613, 81, -541, +-148, -1462, -164, -1784, -6, -1382, 172, -468, +305, 579, 317, 1411, 118, 1697, -193, 1249, +-435, 298, -495, -635, -278, -1222, 165, -1364, +601, -987, 799, -152, 723, 727, 408, 1201, +-155, 1168, -797, 753, -1133, 84, -997, -609, +-560, -1026, 39, -1040, 709, -718, 1204, -206, +1272, 312, 914, 635, 302, 692, -354, 528, +-862, 243, -1066, -54, -888, -260, -376, -346, +262, -339, 771, -222, 993, -2, 895, 218, +536, 347, -14, 417, -590, 399, -921, 190, +-877, -185, -585, -530, -176, -692, 286, -653, +674, -421, 819, -12, 657, 439, 348, 690, +49, 626, -226, 327, -414, -48, -406, -325, +-231, -369, 39, -182, 309, 132, 470, 413, +492, 472, 369, 225, 63, -192, -368, -547, +-727, -717, -842, -645, -683, -281, -319, 266, +231, 674, 861, 740, 1284, 529, 1270, 172, +838, -240, 151, -547, -616, -605, -1250, -421, +-1506, -91, -1217, 247, -451, 446, 533, 459, +1389, 377, 1802, 242, 1604, 32, 867, -198, +-193, -329, -1264, -375, -1922, -424, -1866, -398, +-1151, -183, -64, 143, 1073, 410, 1848, 547, +1931, 518, 1344, 296, 369, -82, -676, -478, +-1427, -701, -1565, -608, -1083, -219, -274, 284, +571, 689, 1224, 866, 1384, 736, 968, 262, +243, -379, -492, -847, -1041, -953, -1193, -740, +-869, -288, -238, 292, 445, 762, 980, 890, +1178, 633, 930, 154, 403, -354, -163, -729, +-654, -829, -920, -579, -778, -84, -322, 444, +175, 814, 560, 926, 787, 750, 743, 308, +375, -284, -101, -813, -441, -1075, -598, -985, +-583, -563, -383, 41, -67, 627, 259, 1027, +479, 1099, 553, 759, 533, 116, 436, -566, +250, -1046, -5, -1152, -265, -820, -450, -162, +-510, 546, -441, 1055, -203, 1200, 174, 907, +524, 262, 680, -445, 591, -933, 291, -1076, +-139, -822, -580, -254, -837, 341, -732, 689, +-320, 725, 231, 474, 775, 38, 1140, -356, +1130, -508, 688, -402, -4, -138, -649, 158, +-1043, 353, -1109, 361, -807, 208, -191, 2, +491, -156, 921, -167, 1018, -18, 832, 148, +405, 176, -143, 70, -621, -111, -867, -317, +-794, -456, -454, -435, 20, -225, 499, 104, +847, 426, 967, 605, 776, 575, 332, 318, +-142, -77, -546, -431, -855, -598, -901, -549, +-617, -295, -127, 135, 414, 588, 816, 836, +953, 756, 813, 385, 420, -190, -136, -799, +-644, -1178, -887, -1145, -790, -686, -432, 96, +84, 915, 634, 1385, 972, 1343, 949, 851, +628, 0, 140, -980, -382, -1598, -751, -1499, +-832, -777, -624, 221, -229, 1170, 216, 1719, +572, 1581, 720, 809, 621, -267, 326, -1270, +-31, -1801, -320, -1584, -464, -785, -427, 192, +-258, 1036, -29, 1487, 283, 1321, 596, 629, +693, -178, 538, -768, 261, -1020, -71, -865, +-463, -344, -790, 228, -816, 559, -507, 635, +-51, 512, 442, 174, 832, -214, 933, -371, +717, -276, 270, -123, -274, -27, -701, 23, +-810, 20, -550, -62, -54, -177, 467, -206, +853, -83, 929, 164, 610, 405, 58, 496, +-491, 403, -869, 167, -949, -185, -659, -537, +-96, -672, 466, -501, 797, -138, 868, 265, +651, 623, 184, 809, -296, 644, -543, 140, +-510, -411, -276, -782, 76, -944, 452, -814, +666, -321, 574, 327, 265, 791, -98, 969, +-382, 887, -518, 517, -504, -85, -351, -642, +-88, -914, 192, -869, 388, -535, 439, 12, +363, 547, 252, 853, 123, 864, -38, 552, +-181, -9, -222, -563, -156, -888, -38, -921, +128, -631, 329, -76, 439, 488, 367, 805, +154, 826, -117, 589, -353, 134, -474, -339, +-405, -576, -149, -530, 158, -312, 383, 29, +457, 373, 316, 499, 12, 346, -283, 24, +-421, -342, -313, -617, -25, -649, 321, -416, +639, -8, 790, 448, 646, 803, 273, 870, +-175, 572, -523, 45, -678, -500, -664, -889, +-448, -956, -39, -611, 376, 20, 604, 683, +577, 1104, 339, 1080, 20, 587, -296, -182, +-518, -936, -509, -1372, -220, -1275, 251, -637, +696, 287, 934, 1082, 877, 1448, 500, 1293, +-112, 663, -706, -257, -1035, -1067, -1004, -1391, +-623, -1143, 39, -507, 721, 263, 1076, 932, +1000, 1269, 610, 1107, 11, 510, -642, -232, +-1055, -863, -988, -1225, -475, -1219, 209, -820, +839, -128, 1230, 659, 1190, 1281, 727, 1525, +14, 1304, -724, 643, -1183, -318, -1170, -1306, +-764, -1931, -84, -1882, 676, -1138, 1196, 47, +1236, 1334, 841, 2261, 218, 2372, -476, 1583, +-1055, 211, -1222, -1289, -902, -2404, -323, -2637, +348, -1847, 956, -405, 1260, 1085, 1150, 2137, +719, 2415, 114, 1798, -471, 549, -863, -787, +-994, -1707, -840, -1928, -388, -1443, 203, -540, +628, 431, 806, 1172, 847, 1444, 682, 1179, +190, 597, -416, -29, -794, -554, -878, -907, +-762, -1006, -399, -832, 240, -475, 901, -47, +1295, 374, 1306, 721, 943, 894, 261, 814, +-587, 473, -1328, -16, -1639, -501, -1347, -855, +-551, -917, 417, -585, 1222, 7, 1680, 572, +1610, 926, 896, 959, -182, 622, -1098, 13, +-1562, -633, -1527, -1086, -976, -1152, -10, -792, +1010, -175, 1689, 441, 1830, 891, 1365, 1079, +433, 907, -598, 444, -1388, -65, -1736, -460, +-1486, -724, -716, -762, 253, -538, 1094, -193, +1577, 146, 1530, 438, 916, 591, -37, 521, +-942, 288, -1476, -22, -1452, -341, -869, -571, +41, -587, 1014, -373, 1756, -8, 1875, 385, +1246, 639, 187, 596, -870, 298, -1614, -79, +-1827, -449, -1404, -687, -446, -600, 659, -191, +1473, 301, 1721, 680, 1364, 820, 593, 628, +-325, 148, -1137, -387, -1534, -746, -1330, -846, +-668, -674, 176, -272, 972, 179, 1510, 464, +1595, 561, 1201, 533, 482, 404, -356, 220, +-1109, 60, -1543, -81, -1497, -254, -999, -459, +-217, -647, 644, -710, 1356, -516, 1634, -9, +1358, 658, 669, 1177, -208, 1306, -1017, 993, +-1480, 249, -1413, -770, -809, -1650, 91, -1935, +921, -1457, 1424, -390, 1460, 894, 1059, 1914, +374, 2223, -436, 1673, -1076, 513, -1213, -831, +-903, -1884, -421, -2186, 103, -1604, 588, -491, +835, 680, 688, 1552, 311, 1792, -8, 1300, +-225, 383, -351, -511, -249, -1101, 38, -1205, +284, -793, 356, -148, 233, 359, -28, 621, +-275, 642, -367, 349, -276, -102, -34, -352, +331, -310, 690, -150, 771, 81, 487, 304, +10, 300, -484, 48, -897, -230, -1058, -402, +-779, -452, -158, -304, 503, 72, 1020, 494, +1287, 711, 1139, 654, 589, 363, -113, -63, +-683, -473, -1011, -724, -1060, -723, -754, -425, +-177, 41, 415, 389, 844, 487, 1002, 407, +832, 207, 458, -96, -3, -377, -498, -426, +-881, -172, -941, 181, -641, 424, -160, 517, +350, 428, 848, 110, 1135, -318, 998, -613, +548, -665, 5, -485, -513, -98, -912, 395, +-1016, 757, -735, 811, -216, 572, 318, 102, +750, -506, 949, -988, 812, -1099, 426, -850, +-69, -322, -533, 397, -799, 1057, -745, 1368, +-409, 1232, 55, 687, 552, -113, 964, -884, +1039, -1346, 719, -1359, 202, -911, -391, -103, +-945, 747, -1220, 1241, -1046, 1255, -491, 892, +255, 189, 989, -681, 1463, -1257, 1419, -1247, +877, -785, 57, -116, -839, 580, -1493, 1052, +-1557, 1068, -995, 636, -95, 13, 847, -524, +1575, -781, 1774, -680, 1244, -287, 243, 210, +-755, 615, -1448, 730, -1638, 472, -1206, 24, +-283, -371, 728, -625, 1411, -709, 1558, -545, +1168, -176, 394, 202, -455, 404, -1121, 440, +-1388, 397, -1071, 274, -334, 80, 400, -70, +916, -99, 1184, -90, 1095, -111, 588, -130, +-133, -95, -655, -15, -823, 71, -737, 147, +-429, 199, 31, 158, 457, 7, 667, -209, +578, -438, 299, -573, 24, -526, -208, -303, +-369, 51, -363, 469, -169, 781, 80, 859, +225, 731, 270, 451, 283, 24, 210, -457, +32, -794, -103, -895, -109, -804, -63, -528, +-40, -42, 13, 498, 104, 854, 150, 933, +107, 739, 23, 288, -34, -305, -18, -859, +23, -1167, 27, -1031, 27, -463, 54, 282, +68, 932, 9, 1327, -31, 1324, 56, 826, +159, -4, 136, -780, 77, -1233, 49, -1313, +-26, -1005, -151, -367, -242, 354, -202, 855, +-22, 986, 198, 781, 365, 414, 453, 1, +442, -390, 300, -607, 3, -534, -326, -301, +-494, -85, -496, 98, -392, 253, -154, 313, +206, 244, 538, 148, 673, 133, 565, 158, +331, 109, 59, -46, -274, -244, -621, -415, +-776, -556, -585, -627, -204, -445, 170, 41, +559, 596, 940, 983, 1064, 1104, 814, 834, +340, 147, -182, -681, -697, -1284, -1089, -1434, +-1148, -1019, -833, -102, -274, 945, 374, 1631, +920, 1671, 1213, 1067, 1177, -32, 721, -1237, +-23, -1966, -696, -1856, -1037, -995, -1014, 262, +-691, 1413, -91, 1969, 608, 1724, 1026, 805, +992, -424, 671, -1464, 207, -1852, -284, -1431, +-642, -452, -713, 621, -504, 1399, -200, 1609, +76, 1150, 318, 266, 446, -608, 380, -1187, +217, -1335, 88, -971, 25, -251, -30, 446, +-71, 850, -72, 932, -75, 729, -102, 269, +-107, -281, -68, -642, 54, -697, 243, -524, +349, -183, 346, 237, 302, 571, 167, 711, +-135, 619, -453, 275, -549, -219, -418, -624, +-251, -764, -37, -658, 327, -371, 655, 85, +747, 559, 619, 758, 359, 579, 4, 187, +-413, -268, -747, -658, -793, -748, -561, -436, +-173, 111, 287, 655, 692, 997, 927, 955, +887, 461, 534, -272, -6, -904, -498, -1224, +-798, -1105, -888, -479, -743, 397, -297, 1052, +292, 1232, 718, 906, 870, 143, 812, -764, +578, -1344, 188, -1312, -237, -705, -532, 267, +-631, 1236, -570, 1738, -384, 1522, -133, 697, +176, -414, 500, -1399, 682, -1809, 667, -1450, +503, -591, 186, 383, -243, 1208, -622, 1551, +-800, 1178, -684, 323, -308, -524, 202, -1072, +675, -1256, 924, -1012, 843, -366, 446, 374, +-117, 880, -592, 1081, -792, 1030, -692, 754, +-298, 303, 260, -230, 692, -725, 800, -1043, +604, -1108, 199, -925, -311, -472, -715, 225, +-774, 926, -488, 1310, -59, 1230, 387, 729, +736, -68, 817, -946, 551, -1517, 115, -1448, +-254, -796, -470, 141, -524, 1069, -373, 1671, +-58, 1655, 279, 987, 467, -30, 385, -970, +166, -1542, -19, -1592, -157, -1082, -254, -210, +-245, 647, -88, 1173, 123, 1226, 194, 851, +151, 238, 138, -388, 105, -850, 27, -972, +-20, -681, 40, -159, 181, 307, 252, 603, +181, 735, 78, 658, -39, 321, -205, -96, +-366, -333, -434, -413, -308, -448, -35, -391, +231, -236, 432, -101, 551, -6, 515, 106, +286, 231, -88, 329, -400, 381, -491, 322, +-409, 101, -194, -174, 131, -359, 462, -431, +672, -346, 665, -13, 419, 406, 24, 611, +-438, 536, -806, 235, -906, -287, -703, -808, +-240, -977, 357, -703, 893, -110, 1153, 632, +992, 1218, 482, 1296, -157, 774, -773, -118, +-1120, -1047, -980, -1658, -437, -1608, 253, -830, +848, 361, 1134, 1495, 989, 2125, 488, 1964, +-158, 1034, -728, -349, -1026, -1697, -856, -2465, +-330, -2302, 227, -1284, 635, 174, 807, 1573, +619, 2428, 142, 2424, -313, 1527, -537, 27, +-520, -1458, -249, -2329, 232, -2364, 608, -1611, +666, -269, 507, 1240, 215, 2321, -195, 2513, +-536, 1811, -618, 541, -468, -896, -190, -2055, +149, -2525, 428, -2120, 445, -980, 282, 461, +137, 1645, -55, 2197, -285, 2019, -284, 1165, +-40, -97, 185, -1248, 280, -1828, 329, -1717, +344, -1038, 206, -8, -37, 1035, -220, 1640, +-285, 1574, -262, 986, -197, 117, -135, -826, +-15, -1488, 158, -1567, 224, -1110, 142, -353, +91, 482, 161, 1162, 167, 1436, 52, 1198, +-15, 561, 19, -233, 25, -910, -33, -1253, +-78, -1181, -54, -715, -4, 23, 43, 784, +137, 1268, 205, 1297, 167, 927, 66, 294, +-57, -450, -169, -1073, -228, -1344, -246, -1166, +-162, -646, 16, -25, 140, 551, 168, 969, +164, 1061, 181, 812, 208, 384, 179, -71, +164, -453, 257, -674, 245, -696, 15, -540, +-255, -248, -422, 114, -478, 426, -459, 596, +-303, 635, 101, 526, 596, 212, 823, -228, +685, -574, 337, -749, -38, -783, -444, -576, +-844, -82, -905, 444, -475, 737, 142, 801, +636, 694, 915, 334, 971, -248, 767, -706, +240, -799, -406, -595, -827, -203, -871, 272, +-657, 643, -332, 790, 110, 641, 599, 169, +801, -402, 591, -700, 242, -661, -71, -486, +-352, -185, -573, 259, -561, 572, -240, 496, +181, 150, 439, -181, 531, -369, 527, -388, +395, -187, 102, 170, -240, 493, -383, 621, +-285, 469, -111, 115, 45, -251, 197, -501, +266, -540, 140, -334, -176, -29, -471, 181, +-535, 188, -387, 17, -122, -183, 244, -284, +698, -218, 1028, 57, 979, 488, 564, 803, +16, 734, -550, 315, -1038, -241, -1227, -797, +-935, -1163, -260, -1052, 466, -395, 1057, 482, +1410, 1160, 1303, 1435, 650, 1201, -250, 448, +-1044, -568, -1507, -1424, -1543, -1775, -1072, -1465, +-140, -611, 882, 485, 1576, 1440, 1755, 1873, +1439, 1604, 718, 755, -247, -302, -1175, -1193, +-1652, -1670, -1490, -1549, -871, -801, -59, 244, +790, 1063, 1424, 1381, 1495, 1246, 967, 706, +195, -140, -488, -911, -1037, -1224, -1363, -1009, +-1195, -485, -474, 108, 372, 635, 948, 923, +1236, 798, 1240, 332, 840, -205, 91, -552, +-660, -605, -1049, -448, -980, -127, -631, 305, +-117, 648, 443, 668, 829, 341, 839, -120, +458, -515, -47, -792, -392, -845, -590, -503, +-638, 154, -399, 757, -16, 1027, 285, 946, +439, 524, 487, -189, 472, -902, 370, -1250, +194, -1061, 51, -396, -82, 470, -234, 1178, +-342, 1429, -459, 1094, -508, 271, -341, -748, +-9, -1503, 329, -1622, 593, -1086, 717, -128, +599, 936, 188, 1678, -301, 1721, -640, 1052, +-826, 5, -726, -1013, -231, -1645, 409, -1619, +861, -940, 1057, 74, 962, 990, 511, 1503, +-164, 1450, -717, 804, -991, -151, -1014, -946, +-688, -1340, -80, -1284, 475, -748, 798, 103, +898, 917, 695, 1352, 228, 1294, -285, 804, +-649, 7, -811, -851, -703, -1443, -242, -1534, +391, -1040, 887, -115, 1114, 861, 1008, 1584, +500, 1860, -216, 1482, -873, 397, -1277, -952, +-1299, -1930, -851, -2248, -37, -1881, 789, -806, +1299, 727, 1401, 2078, 1078, 2661, 364, 2310, +-491, 1211, -1169, -327, -1407, -1800, -1138, -2641, +-488, -2540, 323, -1554, 1031, -87, 1435, 1294, +1410, 2181, 917, 2367, 139, 1760, -649, 559, +-1272, -747, -1506, -1688, -1244, -2068, -592, -1841, +227, -1064, 972, 27, 1432, 1075, 1466, 1771, +1053, 1960, 311, 1619, -569, 831, -1321, -239, +-1599, -1308, -1336, -2003, -688, -2048, 225, -1517, +1208, -566, 1841, 659, 1844, 1762, 1278, 2262, +330, 2008, -802, 1135, -1776, -115, -2145, -1390, +-1750, -2220, -796, -2267, 363, -1580, 1449, -425, +2140, 856, 2094, 1860, 1262, 2266, 5, 1970, +-1171, 1071, -1900, -150, -2024, -1274, -1491, -1951, +-338, -2033, 1013, -1512, 1971, -492, 2189, 656, +1682, 1536, 667, 1930, -571, 1703, -1707, 857, +-2257, -328, -1933, -1405, -952, -1984, 287, -1862, +1394, -1045, 2051, 184, 2051, 1323, 1309, 2013, +64, 2050, -1090, 1331, -1778, 76, -1891, -1165, +-1379, -1899, -386, -1915, 773, -1243, 1667, -157, +1977, 903, 1671, 1539, 857, 1559, -252, 975, +-1256, 23, -1895, -899, -1976, -1400, -1385, -1358, +-349, -862, 741, -38, 1602, 812, 2025, 1299, +1837, 1337, 1043, 1050, -46, 474, -1009, -288, +-1691, -939, -1917, -1223, -1489, -1198, -535, -926, +545, -318, 1415, 445, 1902, 978, 1855, 1171, +1168, 1081, 62, 639, -1004, -105, -1776, -834, +-2047, -1235, -1649, -1242, -673, -831, 523, -75, +1530, 712, 2047, 1222, 1934, 1325, 1221, 1021, +170, 409, -873, -281, -1671, -776, -1916, -971, +-1469, -938, -568, -650, 411, -212, 1254, 86, +1746, 172, 1624, 250, 867, 396, -114, 479, +-875, 478, -1321, 487, -1409, 423, -995, 98, +-162, -363, 638, -724, 1061, -888, 1104, -789, +862, -357, 359, 272, -235, 850, -644, 1169, +-758, 1023, -582, 407, -243, -373, 83, -989, +338, -1299, 538, -1171, 547, -530, 283, 392, +-43, 1106, -159, 1341, -191, 1157, -343, 585, +-378, -281, -178, -1049, -22, -1313, 21, -1062, +172, -520, 368, 141, 403, 771, 297, 1101, +212, 1007, 93, 603, -110, 45, -216, -497, +-190, -804, -167, -785, -135, -571, -31, -270, +27, 145, 4, 527, 0, 602, 36, 417, +43, 147, 94, -163, 166, -427, 133, -488, +74, -308, 64, -9, 15, 347, -111, 702, +-140, 775, 6, 409, 151, -54, 165, -400, +202, -752, 223, -998, 56, -824, -196, -297, +-385, 232, -440, 629, -317, 898, -72, 925, +192, 661, 438, 229, 557, -299, 499, -773, +254, -953, -94, -810, -353, -504, -446, -25, +-413, 636, -237, 1111, 65, 1097, 350, 691, +474, 74, 371, -655, 188, -1277, 37, -1452, +-145, -985, -327, -85, -331, 835, -186, 1482, +-41, 1658, 60, 1195, 117, 156, 147, -995, +130, -1744, 113, -1847, 138, -1255, 191, -132, +223, 1059, 169, 1876, -13, 2044, -188, 1458, +-280, 273, -350, -1033, -345, -1921, -197, -2172, +95, -1741, 388, -668, 525, 668, 479, 1724, +297, 2220, 24, 2009, -239, 1143, -455, -62, +-531, -1258, -363, -2105, -61, -2263, 251, -1591, +493, -383, 562, 869, 413, 1855, 137, 2337, +-155, 1976, -397, 809, -538, -646, -421, -1858, +-61, -2489, 266, -2256, 452, -1116, 556, 476, +510, 1901, 195, 2693, -243, 2547, -556, 1432, +-657, -222, -563, -1785, -265, -2732, 110, -2725, +427, -1711, 657, -109, 728, 1416, 550, 2398, +229, 2552, -26, 1796, -254, 477, -518, -804, +-665, -1693, -550, -2027, -326, -1708, -102, -867, +207, 91, 540, 860, 699, 1311, 655, 1392, +466, 1183, 101, 774, -338, 187, -670, -509, +-770, -1120, -625, -1447, -257, -1431, 263, -1083, +740, -324, 937, 708, 826, 1571, 455, 1932, +-125, 1691, -669, 898, -950, -280, -883, -1485, +-530, -2190, -9, -2062, 524, -1224, 891, 10, +932, 1260, 658, 2107, 190, 2228, -346, 1525, +-775, 291, -906, -968, -683, -1858, -243, -2150, +289, -1708, 759, -659, 1002, 571, 915, 1516, +485, 1929, -160, 1702, -742, 932, -1042, -74, +-964, -1039, -549, -1688, 24, -1730, 651, -1161, +1097, -307, 1078, 567, 631, 1290, 11, 1599, +-577, 1349, -951, 739, -1021, -24, -706, -840, +-49, -1404, 620, -1413, 1021, -972, 1046, -339, +747, 397, 254, 1030, -314, 1280, -796, 1109, +-955, 611, -771, -120, -385, -802, 90, -1144, +495, -1095, 673, -737, 639, -178, 516, 468, +278, 978, -93, 1117, -420, 886, -520, 458, +-496, -51, -413, -541, -151, -895, 240, -947, +537, -684, 665, -321, 648, 52, 427, 413, +43, 650, -341, 692, -616, 582, -776, 354, +-684, 49, -296, -256, 137, -474, 449, -585, +692, -593, 770, -469, 553, -224, 163, 122, +-208, 489, -467, 739, -629, 785, -589, 624, +-286, 272, 96, -182, 419, -628, 676, -913, +773, -907, 609, -597, 215, -67, -259, 485, +-648, 818, -954, 839, -1065, 608, -781, 143, +-138, -448, 564, -872, 1101, -883, 1409, -555, +1363, -75, 809, 490, -62, 1009, -861, 1190, +-1433, 886, -1635, 292, -1288, -397, -414, -1015, +627, -1334, 1447, -1256, 1831, -809, 1634, -49, +848, 776, -216, 1322, -1225, 1407, -1932, 1033, +-1989, 328, -1302, -534, -194, -1226, 930, -1421, +1805, -1084, 2124, -387, 1691, 500, 731, 1300, +-321, 1630, -1221, 1273, -1794, 420, -1757, -521, +-1069, -1267, -107, -1602, 727, -1371, 1318, -640, +1517, 309, 1205, 1105, 517, 1431, -249, 1202, +-820, 572, -1100, -181, -1120, -835, -834, -1181, +-255, -1019, 361, -484, 808, 119, 1015, 628, +1011, 932, 779, 906, 308, 590, -259, 126, +-682, -316, -892, -579, -895, -613, -626, -487, +-158, -299, 296, -108, 613, 23, 776, 76, +713, 68, 412, 53, -26, 75, -377, 189, +-532, 392, -558, 548, -409, 525, -65, 339, +294, 13, 528, -440, 586, -854, 425, -1048, +179, -874, -76, -350, -332, 306, -517, 903, +-518, 1324, -294, 1336, 4, 784, 225, -121, +422, -965, 578, -1489, 499, -1603, 167, -1190, +-232, -332, -469, 634, -531, 1379, -480, 1709, +-242, 1511, 212, 835, 657, -61, 796, -829, +596, -1277, 279, -1390, -71, -1150, -496, -621, +-793, 33, -739, 604, -369, 960, 63, 1102, +398, 1039, 612, 708, 638, 175, 412, -417, +6, -927, -384, -1219, -557, -1256, -426, -965, +-139, -276, 122, 612, 335, 1302, 531, 1595, +534, 1491, 287, 986, 7, 114, -205, -860, +-409, -1549, -544, -1753, -497, -1481, -325, -819, +-119, 66, 165, 889, 533, 1411, 738, 1492, +691, 1178, 484, 656, 114, 30, -358, -625, +-719, -1058, -829, -1097, -692, -895, -309, -624, +260, -245, 760, 282, 941, 712, 836, 856, +490, 818, -60, 696, -618, 399, -932, -81, +-872, -514, -513, -701, -6, -717, 474, -651, +736, -418, 732, -66, 536, 229, 150, 389, +-237, 483, -386, 539, -358, 483, -328, 341, +-275, 216, -86, 24, 156, -288, 277, -580, +299, -762, 369, -761, 417, -541, 284, -152, +-27, 338, -358, 834, -580, 1129, -627, 1042, +-525, 594, -274, -34, 226, -692, 778, -1237, +977, -1394, 767, -1028, 383, -323, -75, 464, +-564, 1186, -909, 1616, -813, 1521, -324, 868, +173, -128, 493, -1108, 632, -1745, 571, -1869, +305, -1434, -89, -471, -400, 736, -385, 1720, +-147, 2113, 48, 1865, 138, 1033, 196, -211, +132, -1409, -137, -2078, -397, -2056, -403, -1390, +-183, -226, 104, 1022, 448, 1832, 800, 1971, +901, 1504, 582, 507, 29, -724, -528, -1617, +-908, -1827, -991, -1397, -789, -527, -340, 486, +235, 1269, 704, 1532, 881, 1215, 766, 498, +491, -365, 145, -1008, -284, -1156, -611, -841, +-635, -252, -434, 385, -163, 790, 103, 831, +341, 565, 472, 67, 445, -464, 305, -782, +93, -750, -152, -434, -322, -3, -380, 384, +-299, 632, -116, 679, 35, 500, 128, 141, +191, -256, 198, -488, 98, -504, -59, -397, +-140, -227, -80, 67, 40, 415, 199, 576, +351, 430, 347, 153, 149, -96, -99, -383, +-270, -664, -397, -666, -426, -326, -224, 101, +133, 477, 343, 778, 308, 825, 170, 472, +-4, -75, -238, -542, -363, -838, -218, -860, +72, -523, 374, 79, 606, 705, 618, 1077, +302, 1021, -171, 587, -558, -96, -749, -798, +-673, -1266, -252, -1329, 308, -914, 684, -132, +797, 701, 665, 1253, 255, 1381, -337, 1105, +-755, 466, -795, -412, -598, -1093, -256, -1251, +229, -972, 621, -413, 748, 307, 674, 903, +457, 1114, 114, 889, -259, 287, -452, -456, +-466, -972, -442, -1057, -288, -823, 37, -334, +239, 369, 245, 970, 274, 1114, 311, 809, +158, 281, -105, -284, -215, -723, -185, -899, +-163, -727, -127, -248, 16, 314, 188, 663, +300, 700, 325, 496, 225, 120, 18, -311, +-129, -562, -182, -518, -243, -275, -206, 72, +-49, 368, 69, 398, 105, 146, 158, -184, +214, -450, 118, -536, -133, -339, -256, 140, +-218, 708, -229, 1051, -184, 991, 86, 541, +436, -168, 611, -894, 593, -1346, 439, -1346, +113, -851, -351, -68, -750, 708, -951, 1260, +-875, 1366, -443, 937, 228, 194, 817, -509, +1113, -966, 1127, -1102, 772, -876, 22, -306, +-776, 328, -1246, 727, -1318, 854, -972, 760, +-196, 446, 754, 16, 1398, -336, 1501, -527, +1198, -584, 503, -544, -538, -437, -1446, -295, +-1682, -68, -1285, 200, -578, 427, 307, 660, +1207, 873, 1685, 818, 1476, 402, 721, -143, +-271, -653, -1131, -1132, -1566, -1437, -1452, -1233, +-844, -468, 107, 504, 1088, 1318, 1634, 1811, +1550, 1841, 1068, 1298, 310, 263, -686, -958, +-1519, -1951, -1762, -2399, -1388, -2134, -676, -1224, +192, 25, 1095, 1281, 1735, 2269, 1795, 2624, +1247, 2194, 321, 1198, -668, -93, -1478, -1396, +-1895, -2302, -1695, -2508, -888, -2050, 246, -1104, +1279, 143, 1898, 1351, 1959, 2070, 1422, 2163, +420, 1727, -710, 865, -1597, -189, -1963, -1093, +-1725, -1604, -1011, -1666, -12, -1338, 1004, -725, +1725, 16, 1888, 634, 1465, 995, 666, 1171, +-275, 1210, -1125, 971, -1625, 438, -1636, -116, +-1194, -559, -409, -1011, 566, -1374, 1448, -1344, +1820, -896, 1574, -217, 901, 521, -29, 1154, +-991, 1494, -1682, 1430, -1867, 948, -1406, 177, +-422, -600, 707, -1136, 1580, -1331, 1906, -1158, +1629, -633, 819, 8, -312, 502, -1321, 812, +-1806, 950, -1673, 814, -1005, 444, 10, 39, +1025, -259, 1657, -452, 1678, -632, 1141, -719, +261, -550, -690, -208, -1397, 74, -1546, 277, +-1116, 498, -383, 688, 399, 657, 1013, 371, +1213, 17, 952, -255, 412, -401, -197, -456, +-690, -446, -909, -326, -727, -112, -267, 32, +216, 61, 580, 86, 727, 162, 578, 232, +208, 294, -220, 383, -546, 381, -648, 191, +-520, -97, -240, -368, 90, -595, 427, -680, +619, -527, 503, -156, 169, 273, -156, 609, +-338, 766, -395, 674, -369, 392, -154, 65, +286, -263, 626, -572, 573, -679, 234, -565, +-93, -444, -389, -371, -763, -175, -943, 173, +-577, 510, 122, 767, 675, 981, 983, 1041, +1142, 733, 1009, 116, 376, -604, -509, -1257, +-1170, -1623, -1411, -1488, -1331, -870, -953, 17, +-188, 930, 796, 1617, 1578, 1799, 1856, 1376, +1624, 571, 1025, -338, 159, -1128, -900, -1550, +-1812, -1469, -2188, -986, -1956, -290, -1278, 425, +-275, 967, 953, 1192, 2075, 1102, 2619, 786, +2400, 295, 1572, -216, 327, -579, -1093, -789, +-2313, -879, -2890, -783, -2606, -505, -1591, -152, +-120, 181, 1448, 457, 2633, 673, 3007, 785, +2472, 751, 1280, 548, -204, 240, -1667, -92, +-2671, -459, -2832, -869, -2111, -1100, -837, -998, +575, -661, 1787, -167, 2491, 490, 2448, 1167, +1667, 1564, 467, 1471, -737, 898, -1605, 57, +-1968, -832, -1801, -1561, -1175, -1906, -251, -1658, +635, -828, 1188, 242, 1380, 1164, 1246, 1758, +794, 1908, 165, 1509, -385, 657, -697, -366, +-822, -1201, -844, -1634, -670, -1679, -337, -1351, +-26, -628, 264, 284, 576, 1046, 815, 1511, +876, 1659, 751, 1403, 476, 708, 34, -205, +-570, -1086, -1118, -1747, -1378, -1966, -1253, -1600, +-774, -733, -42, 415, 816, 1539, 1562, 2273, +1867, 2328, 1554, 1665, 775, 505, -232, -899, +-1272, -2153, -2037, -2755, -2131, -2457, -1493, -1428, +-416, 18, 768, 1505, 1783, 2591, 2290, 2871, +2015, 2208, 1067, 886, -161, -623, -1319, -1911, +-2092, -2655, -2159, -2592, -1501, -1725, -426, -373, +711, 966, 1605, 1910, 1938, 2317, 1590, 2126, +809, 1352, -94, 258, -903, -740, -1366, -1413, +-1324, -1776, -905, -1811, -327, -1395, 278, -657, +767, 80, 906, 702, 709, 1280, 447, 1700, +168, 1717, -186, 1298, -464, 612, -485, -175, +-341, -968, -250, -1609, -196, -1907, 15, -1709, +277, -1050, 357, -155, 314, 739, 308, 1428, +300, 1747, 157, 1667, -102, 1218, -350, 444, +-456, -412, -395, -1073, -246, -1436, -83, -1508, +138, -1258, 380, -708, 457, -2, 300, 657, +112, 1108, 17, 1288, -136, 1212, -353, 895, +-396, 310, -218, -343, -34, -780, 65, -961, +186, -952, 378, -695, 518, -247, 509, 148, +313, 346, -63, 406, -454, 352, -737, 139, +-923, -78, -908, -82, -484, 106, 256, 319, +928, 493, 1298, 544, 1363, 376, 1002, -5, +180, -516, -771, -991, -1476, -1188, -1716, -983, +-1393, -498, -594, 124, 433, 827, 1381, 1439, +1897, 1612, 1731, 1228, 961, 499, -44, -349, +-999, -1167, -1741, -1740, -1954, -1829, -1393, -1353, +-331, -449, 678, 614, 1382, 1571, 1699, 2124, +1434, 2025, 586, 1259, -421, 127, -1133, -1032, +-1387, -2002, -1197, -2440, -565, -2000, 331, -826, +1070, 542, 1355, 1678, 1072, 2341, 315, 2353, +-509, 1541, -1034, 86, -1237, -1372, -1081, -2244, +-461, -2416, 432, -1951, 1092, -842, 1222, 664, +995, 1911, 560, 2389, -100, 2185, -761, 1496, +-1035, 332, -891, -1046, -604, -2004, -291, -2223, +120, -1882, 523, -1140, 690, -39, 657, 1148, +601, 1925, 513, 2038, 297, 1597, -24, 808, +-389, -230, -779, -1291, -1091, -1951, -1129, -1918, +-842, -1301, -323, -359, 349, 683, 1084, 1513, +1665, 1860, 1799, 1645, 1385, 929, 590, -86, +-358, -983, -1303, -1479, -2001, -1551, -2163, -1229, +-1728, -543, -849, 260, 277, 835, 1383, 1108, +2163, 1133, 2398, 891, 2018, 472, 1130, 62, +-83, -316, -1366, -679, -2350, -956, -2705, -1039, +-2330, -921, -1357, -652, -43, -200, 1365, 484, +2532, 1217, 3024, 1688, 2660, 1743, 1600, 1327, +146, 436, -1377, -749, -2616, -1815, -3155, -2448, +-2748, -2451, -1622, -1661, -234, -262, 1137, 1201, +2289, 2319, 2872, 2887, 2630, 2625, 1739, 1497, +549, -65, -722, -1467, -1848, -2376, -2512, -2638, +-2570, -2188, -2079, -1136, -1110, 144, 184, 1219, +1445, 1853, 2345, 2005, 2738, 1700, 2494, 1014, +1581, 169, 195, -583, -1296, -1114, -2481, -1457, +-2995, -1574, -2693, -1325, -1711, -713, -290, 36, +1280, 726, 2478, 1310, 2849, 1666, 2443, 1589, +1533, 1043, 277, 223, -1104, -629, -2109, -1310, +-2384, -1669, -2079, -1572, -1452, -1052, -524, -312, +570, 445, 1455, 1047, 1876, 1369, 1840, 1375, +1469, 1083, 852, 556, 68, -45, -757, -574, +-1457, -955, -1833, -1191, -1746, -1226, -1265, -966, +-524, -469, 433, 115, 1379, 717, 1919, 1246, +1897, 1470, 1450, 1294, 670, 790, -361, 52, +-1372, -800, -1979, -1492, -2011, -1780, -1524, -1580, +-589, -897, 601, 139, 1605, 1213, 2093, 1960, +2002, 2178, 1309, 1802, 129, 849, -1149, -509, +-2005, -1789, -2156, -2517, -1614, -2546, -519, -1937, +811, -721, 1862, 887, 2257, 2313, 1890, 2981, +842, 2732, -518, 1815, -1663, 448, -2230, -1171, +-2078, -2547, -1206, -3092, 120, -2687, 1337, -1597, +2021, -135, 2106, 1352, 1578, 2473, 500, 2898, +-696, 2485, -1530, 1394, -1861, 48, -1719, -1212, +-1109, -2167, -205, -2555, 682, -2222, 1343, -1382, +1651, -306, 1491, 832, 971, 1697, 303, 2032, +-454, 1909, -1160, 1427, -1494, 590, -1388, -343, +-1033, -1033, -447, -1413, 356, -1520, 1087, -1243, +1447, -639, 1403, -21, 1039, 439, 355, 759, +-536, 912, -1274, 838, -1583, 550, -1451, 163, +-914, -96, -63, -166, 855, -222, 1507, -353, +1660, -372, 1317, -227, 587, -159, -352, -286, +-1200, -379, -1697, -207, -1710, 81, -1170, 256, +-243, 410, 704, 696, 1422, 898, 1786, 751, +1605, 345, 840, -91, -157, -536, -975, -1022, +-1543, -1357, -1818, -1295, -1528, -830, -645, -197, +384, 469, 1115, 1135, 1493, 1619, 1538, 1651, +1117, 1223, 274, 540, -602, -224, -1157, -994, +-1314, -1622, -1068, -1791, -492, -1389, 161, -690, +648, 36, 858, 770, 729, 1424, 361, 1715, +-3, 1460, -234, 811, -353, 44, -343, -697, +-196, -1317, -63, -1640, -37, -1494, -13, -932, +46, -143, 39, 680, 33, 1366, 137, 1726, +238, 1649, 165, 1103, -54, 204, -249, -748, +-326, -1479, -323, -1859, -206, -1791, 132, -1177, +578, -171, 853, 862, 793, 1641, 425, 2018, +-105, 1806, -669, 1001, -1151, -98, -1328, -1154, +-1044, -1916, -424, -2111, 296, -1622, 991, -644, +1557, 529, 1764, 1599, 1451, 2227, 734, 2128, +-157, 1356, -1084, 240, -1852, -913, -2209, -1912, +-2013, -2417, -1245, -2071, -64, -1094, 1210, -25, +2250, 971, 2780, 1910, 2608, 2379, 1746, 2013, +358, 1113, -1243, 173, -2591, -791, -3248, -1785, +-3053, -2343, -2123, -2126, -651, -1418, 1087, -565, +2622, 521, 3485, 1755, 3474, 2561, 2633, 2566, +1180, 1956, -619, 930, -2387, -411, -3616, -1805, +-3973, -2827, -3406, -3108, -1988, -2538, 12, -1315, +2079, 223, 3664, 1793, 4382, 3019, 4018, 3458, +2548, 2972, 355, 1809, -1887, 215, -3642, -1530, +-4540, -2927, -4258, -3532, -2776, -3273, -558, -2281, +1676, -697, 3342, 1098, 4151, 2567, 3910, 3355, +2567, 3355, 580, 2525, -1345, 1034, -2806, -682, +-3572, -2139, -3359, -3024, -2187, -3176, -584, -2514, +872, -1195, 1960, 364, 2561, 1701, 2438, 2571, +1560, 2817, 336, 2340, -684, 1259, -1221, -75, +-1359, -1255, -1195, -1992, -674, -2219, 53, -2001, +510, -1330, 397, -312, -61, 645, -436, 1189, +-585, 1417, -565, 1508, -200, 1320, 649, 758, +1575, 187, 1964, -154, 1644, -523, 795, -1006, +-481, -1252, -1975, -1145, -3081, -968, -3187, -733, +-2224, -209, -545, 536, 1414, 1126, 3165, 1375, +4100, 1368, 3771, 1167, 2214, 646, -23, -157, +-2224, -879, -3802, -1286, -4327, -1430, -3600, -1315, +-1808, -872, 472, -224, 2514, 443, 3773, 1015, +4015, 1374, 3185, 1426, 1498, 1202, -463, 711, +-2134, -34, -3204, -811, -3466, -1377, -2808, -1668, +-1449, -1637, 115, -1130, 1495, -225, 2525, 748, +2982, 1537, 2702, 2008, 1809, 1963, 531, 1301, +-832, 225, -1927, -923, -2567, -1815, -2692, -2213, +-2177, -1995, -1053, -1196, 341, -10, 1579, 1192, +2439, 2017, 2782, 2205, 2418, 1747, 1373, 823, +-11, -297, -1341, -1276, -2294, -1804, -2636, -1747, +-2346, -1240, -1515, -477, -257, 301, 1100, 804, +2058, 933, 2364, 844, 2106, 639, 1433, 400, +430, 335, -664, 466, -1506, 502, -1942, 221, +-1963, -285, -1582, -924, -868, -1599, 39, -2013, +936, -1809, 1600, -947, 1913, 331, 1831, 1707, +1323, 2785, 446, 3102, -541, 2453, -1325, 1078, +-1842, -605, -2073, -2135, -1771, -3078, -890, -3162, +151, -2386, 965, -1000, 1525, 545, 1835, 1800, +1680, 2500, 1020, 2548, 212, 2002, -493, 1049, +-1106, -26, -1533, -970, -1576, -1602, -1223, -1874, +-634, -1755, -1, -1239, 605, -479, 1158, 281, +1464, 940, 1298, 1437, 743, 1559, 93, 1214, +-533, 602, -1131, -12, -1447, -582, -1157, -1022, +-446, -1082, 221, -720, 701, -268, 1041, 38, +1034, 241, 479, 354, -335, 255, -877, -47, +-982, -297, -811, -281, -344, -8, 487, 340, +1280, 641, 1470, 862, 1015, 925, 274, 678, +-551, 112, -1356, -576, -1818, -1192, -1628, -1629, +-854, -1741, 185, -1345, 1133, -513, 1713, 522, +1851, 1534, 1555, 2278, 771, 2477, -292, 2045, +-1116, 1021, -1481, -431, -1584, -1869, -1441, -2808, +-841, -3026, 27, -2479, 687, -1203, 1063, 432, +1327, 1934, 1368, 2969, 1057, 3282, 560, 2710, +41, 1449, -503, -101, -1011, -1625, -1316, -2803, +-1305, -3301, -1025, -3010, -573, -2069, 48, -637, +768, 1016, 1364, 2479, 1625, 3402, 1501, 3569, +1054, 2839, 347, 1317, -562, -586, -1447, -2400, +-1955, -3691, -1902, -4040, -1346, -3237, -443, -1532, +662, 603, 1689, 2653, 2193, 4026, 2010, 4231, +1361, 3202, 383, 1313, -820, -901, -1839, -2899, +-2241, -4151, -1963, -4229, -1190, -3113, -92, -1184, +1074, 1019, 1890, 2961, 2062, 4139, 1654, 4250, +858, 3255, -179, 1376, -1241, -896, -1948, -2918, +-2023, -4170, -1518, -4383, -639, -3458, 394, -1548, +1311, 847, 1851, 3007, 1904, 4331, 1445, 4487, +577, 3430, -432, 1395, -1328, -1059, -1937, -3164, +-2060, -4299, -1577, -4242, -698, -3080, 247, -1059, +1108, 1247, 1736, 3023, 1879, 3756, 1503, 3507, +823, 2471, 25, 820, -754, -947, -1338, -2164, +-1584, -2588, -1452, -2412, -1024, -1806, -440, -867, +191, 164, 710, 881, 964, 1164, 958, 1256, +828, 1298, 658, 1132, 395, 730, 26, 306, +-281, -60, -419, -486, -524, -948, -705, -1209, +-860, -1202, -842, -1020, -682, -663, -458, -60, +-70, 612, 534, 1051, 1144, 1212, 1550, 1262, +1671, 1180, 1425, 779, 766, 101, -208, -598, +-1267, -1148, -2127, -1563, -2508, -1755, -2257, -1550, +-1436, -908, -249, 46, 1086, 1105, 2294, 1954, +2998, 2339, 2906, 2194, 2076, 1495, 796, 305, +-725, -1035, -2205, -2039, -3137, -2506, -3175, -2436, +-2434, -1793, -1193, -624, 348, 695, 1868, 1716, +2912, 2307, 3203, 2461, 2717, 2043, 1588, 1076, +98, -84, -1382, -1147, -2481, -2028, -2912, -2545, +-2598, -2409, -1708, -1630, -516, -477, 727, 799, +1779, 1931, 2383, 2607, 2395, 2630, 1888, 1994, +1052, 806, 62, -631, -925, -1844, -1700, -2469, +-2071, -2491, -2006, -1968, -1591, -925, -859, 385, +104, 1495, 1084, 2126, 1871, 2261, 2246, 1907, +2050, 1072, 1348, -49, 342, -1090, -781, -1833, +-1739, -2178, -2238, -2000, -2140, -1252, -1504, -143, +-520, 1007, 568, 1908, 1467, 2300, 1932, 2053, +1860, 1224, 1311, 21, 507, -1230, -311, -2073, +-1054, -2247, -1592, -1812, -1700, -929, -1365, 240, +-798, 1379, -61, 2053, 846, 2029, 1608, 1459, +1820, 681, 1481, -166, 792, -1042, -225, -1692, +-1390, -1811, -2179, -1495, -2224, -1000, -1591, -347, +-463, 505, 978, 1328, 2270, 1852, 2852, 2024, +2503, 1816, 1315, 1152, -405, 97, -2080, -1084, +-3154, -2099, -3356, -2648, -2591, -2567, -963, -1883, +989, -700, 2533, 758, 3292, 2073, 3259, 2865, +2403, 3027, 799, 2544, -1027, 1439, -2420, -56, +-3081, -1522, -3011, -2627, -2236, -3158, -890, -3026, +626, -2241, 1812, -897, 2419, 725, 2469, 2160, +1999, 3059, 1035, 3315, -186, 2848, -1232, 1637, +-1816, -27, -1939, -1568, -1648, -2626, -958, -3106, +-73, -2882, 664, -1898, 1095, -474, 1224, 887, +1025, 1881, 584, 2395, 153, 2369, -138, 1816, +-334, 919, -414, -45, -321, -827, -174, -1336, +-126, -1590, -157, -1596, -214, -1301, -327, -767, +-429, -212, -338, 277, -37, 801, 294, 1312, +585, 1516, 886, 1361, 1064, 1059, 886, 626, +381, -71, -220, -856, -805, -1391, -1318, -1595, +-1556, -1557, -1349, -1258, -753, -597, 88, 309, +1023, 1125, 1772, 1610, 2046, 1800, 1754, 1687, +962, 1127, -173, 164, -1352, -830, -2182, -1518, +-2412, -1868, -1990, -1868, -993, -1368, 344, -399, +1625, 659, 2492, 1428, 2699, 1792, 2125, 1786, +878, 1330, -656, 449, -1994, -507, -2775, -1150, +-2794, -1418, -2018, -1392, -685, -1025, 819, -367, +2121, 281, 2840, 667, 2722, 825, 1837, 800, +461, 594, -1074, 300, -2351, 63, -2934, -51, +-2657, -92, -1696, -131, -333, -201, 1151, -307, +2357, -435, 2882, -507, 2585, -475, 1585, -298, +131, 68, -1398, 550, -2534, 939, -2912, 1062, +-2475, 846, -1432, 311, -60, -401, 1296, -1083, +2235, -1522, 2500, -1509, 2136, -911, 1306, 116, +186, 1203, -931, 1997, -1700, 2245, -2027, 1775, +-1990, 622, -1560, -876, -759, -2219, 133, -2937, +845, -2769, 1385, -1701, 1771, 1, 1807, 1827, +1370, 3162, 616, 3576, -222, 2929, -971, 1390, +-1547, -599, -1904, -2398, -1859, -3456, -1299, -3574, +-468, -2747, 308, -1120, 992, 779, 1623, 2259, +1934, 3042, 1669, 3136, 1056, 2483, 395, 1175, +-367, -289, -1224, -1450, -1833, -2197, -1916, -2473, +-1578, -2183, -1020, -1422, -224, -434, 748, 589, +1499, 1407, 1728, 1824, 1553, 1849, 1178, 1559, +576, 927, -252, 75, -986, -653, -1284, -1099, +-1190, -1331, -968, -1310, -684, -950, -231, -460, +276, -89, 507, 216, 470, 569, 479, 815, +562, 820, 515, 778, 387, 832, 356, 752, +355, 382, 163, -75, -243, -493, -667, -940, +-984, -1333, -1186, -1456, -1219, -1255, -938, -761, +-300, -30, 482, 771, 1161, 1443, 1675, 1904, +1939, 2066, 1753, 1742, 1058, 921, 6, -149, +-1157, -1209, -2141, -2136, -2682, -2727, -2626, -2694, +-1905, -1937, -602, -666, 967, 831, 2378, 2289, +3260, 3320, 3341, 3560, 2511, 2893, 931, 1467, +-1015, -396, -2770, -2234, -3744, -3572, -3640, -4049, +-2603, -3508, -947, -2032, 981, -23, 2665, 1945, +3523, 3418, 3309, 4074, 2214, 3684, 613, 2339, +-1067, 496, -2352, -1346, -2873, -2807, -2554, -3557, +-1613, -3393, -398, -2413, 734, -921, 1488, 725, +1707, 2101, 1443, 2838, 879, 2859, 239, 2302, +-274, 1245, -561, -137, -654, -1382, -626, -2045, +-519, -2123, -413, -1826, -377, -1197, -337, -287, +-208, 602, -28, 1146, 168, 1304, 395, 1214, +624, 988, 720, 646, 559, 241, 181, -132, +-260, -409, -622, -619, -781, -781, -679, -847, +-358, -724, 66, -412, 411, -34, 525, 340, +387, 670, 62, 822, -325, 682, -620, 314, +-711, -117, -519, -457, -42, -580, 566, -416, +1020, -18, 1102, 450, 807, 777, 229, 788, +-523, 472, -1210, -74, -1497, -742, -1278, -1313, +-754, -1463, -107, -1067, 602, -287, 1190, 607, +1383, 1394, 1130, 1875, 644, 1856, 118, 1289, +-420, 345, -879, -692, -1076, -1551, -992, -2004, +-756, -1949, -451, -1431, -102, -610, 259, 330, +555, 1179, 717, 1715, 754, 1846, 699, 1636, +583, 1147, 368, 427, 8, -351, -417, -999, +-792, -1429, -1082, -1607, -1217, -1480, -1071, -1081, +-606, -518, 28, 132, 626, 778, 1130, 1255, +1471, 1423, 1451, 1317, 1001, 1038, 267, 607, +-554, 69, -1268, -409, -1677, -737, -1619, -947, +-1121, -1002, -399, -848, 346, -628, 959, -461, +1289, -230, 1263, 107, 893, 403, 326, 634, +-216, 917, -623, 1207, -862, 1307, -863, 1131, +-633, 719, -311, 54, -60, -849, 48, -1762, +37, -2349, -12, -2391, -3, -1841, 135, -750, +369, 703, 584, 2161, 661, 3161, 544, 3367, +243, 2698, -236, 1325, -809, -423, -1223, -2124, +-1263, -3299, -937, -3587, -366, -2942, 333, -1618, +984, 40, 1309, 1681, 1144, 2861, 615, 3197, +-40, 2707, -677, 1707, -1151, 424, -1222, -942, +-798, -1981, -129, -2319, 483, -2027, 901, -1393, +982, -566, 620, 334, -17, 1005, -651, 1235, +-1096, 1112, -1209, 819, -878, 471, -178, 169, +620, -2, 1255, -57, 1519, -76, 1268, -131, +554, -273, -382, -522, -1246, -754, -1803, -781, +-1893, -557, -1391, -190, -422, 279, 575, 819, +1289, 1190, 1675, 1123, 1644, 660, 1089, 88, +198, -428, -593, -834, -1068, -995, -1292, -753, +-1211, -168, -759, 436, -174, 747, 264, 742, +457, 516, 445, 42, 326, -612, 147, -1093, +-43, -1062, -121, -563, 7, 117, 274, 833, +433, 1523, 358, 1862, 203, 1457, -20, 443, +-499, -643, -1082, -1552, -1323, -2267, -1112, -2418, +-708, -1631, -136, -259, 723, 1033, 1567, 2056, +1892, 2749, 1643, 2711, 1013, 1723, 59, 236, +-1077, -1143, -2006, -2186, -2376, -2773, -2096, -2646, +-1260, -1688, -94, -230, 1077, 1191, 1926, 2209, +2215, 2694, 1857, 2508, 1005, 1560, -27, 114, +-978, -1260, -1652, -2151, -1834, -2469, -1487, -2165, +-850, -1160, -157, 296, 494, 1578, 942, 2219, +999, 2202, 727, 1646, 371, 602, 35, -687, +-297, -1698, -487, -2032, -389, -1726, -136, -1019, +63, -41, 147, 998, 115, 1667, -77, 1679, +-434, 1203, -793, 534, -915, -219, -745, -939, +-362, -1345, 213, -1258, 933, -789, 1579, -180, +1786, 401, 1341, 888, 420, 1167, -670, 1063, +-1755, 583, -2584, 17, -2749, -425, -2050, -811, +-728, -1103, 785, -996, 2182, -434, 3141, 177, +3247, 587, 2368, 908, 803, 1108, -1004, 931, +-2620, 395, -3610, -203, -3638, -678, -2688, -982, +-1085, -1025, 780, -755, 2483, -242, 3518, 391, +3558, 926, 2661, 1125, 1101, 964, -785, 596, +-2501, 61, -3459, -620, -3415, -1157, -2537, -1187, +-1074, -752, 658, -171, 2143, 414, 2892, 983, +2722, 1286, 1800, 1048, 467, 383, -890, -350, +-1908, -915, -2292, -1196, -1940, -1060, -1041, -498, +18, 282, 907, 1001, 1413, 1390, 1427, 1261, +966, 700, 187, -21, -576, -749, -1039, -1352, +-1175, -1537, -1050, -1131, -636, -402, -7, 267, +520, 823, 728, 1301, 797, 1466, 823, 1149, +575, 617, 47, 160, -418, -315, -661, -893, +-858, -1282, -1067, -1285, -994, -1085, -520, -765, +10, -169, 384, 628, 725, 1288, 1015, 1589, +1045, 1517, 744, 1085, 265, 360, -254, -459, +-805, -1133, -1269, -1467, -1433, -1361, -1239, -883, +-763, -246, -118, 354, 564, 792, 1134, 961, +1397, 842, 1270, 578, 862, 325, 261, 122, +-485, -36, -1192, -128, -1587, -179, -1507, -276, +-1049, -453, -416, -625, 283, -673, 928, -543, +1280, -256, 1157, 143, 653, 592, 27, 949, +-588, 1061, -1107, 915, -1245, 583, -848, 126, +-174, -357, 446, -691, 888, -788, 1047, -733, +740, -595, -11, -349, -850, -61, -1385, 129, +-1451, 210, -1073, 277, -346, 390, 581, 527, +1438, 635, 1840, 676, 1554, 638, 727, 477, +-339, 100, -1434, -475, -2248, -1038, -2336, -1388, +-1622, -1472, -496, -1238, 685, -585, 1715, 410, +2297, 1422, 2176, 2128, 1445, 2363, 363, 2056, +-884, 1208, -1974, -64, -2456, -1481, -2258, -2634, +-1628, -3148, -695, -2878, 445, -1902, 1462, -390, +1986, 1370, 1964, 2920, 1612, 3801, 1006, 3755, +112, 2774, -864, 1088, -1555, -915, -1810, -2758, +-1803, -3961, -1658, -4179, -1165, -3359, -271, -1741, +613, 264, 1190, 2213, 1596, 3658, 1885, 4228, +1753, 3770, 1060, 2438, 179, 622, -555, -1239, +-1238, -2795, -1903, -3734, -2253, -3769, -2036, -2865, +-1363, -1370, -558, 244, 238, 1724, 1070, 2896, +1818, 3397, 2209, 2989, 2116, 1967, 1617, 811, +813, -335, -248, -1474, -1408, -2328, -2356, -2559, +-2817, -2245, -2680, -1705, -1974, -1002, -815, -35, +589, 1059, 1882, 1943, 2696, 2442, 2845, 2562, +2294, 2221, 1122, 1301, -365, -41, -1670, -1398, +-2441, -2410, -2582, -2859, -2109, -2621, -1121, -1670, +88, -201, 1058, 1307, 1473, 2299, 1372, 2533, +924, 2133, 271, 1238, -363, -11, -725, -1164, +-700, -1678, -335, -1485, 135, -926, 410, -219, +390, 512, 174, 947, -196, 834, -731, 320, +-1203, -278, -1263, -743, -940, -890, -432, -611, +258, -22, 1023, 670, 1504, 1301, 1512, 1611, +1148, 1348, 560, 616, -201, -251, -1010, -1066, +-1594, -1734, -1804, -2016, -1677, -1706, -1239, -901, +-508, 97, 372, 1036, 1135, 1759, 1560, 2127, +1615, 1998, 1326, 1353, 731, 414, -16, -528, +-738, -1325, -1275, -1869, -1489, -1949, -1387, -1487, +-1067, -723, -593, 52, -54, 776, 404, 1387, +653, 1640, 702, 1413, 682, 923, 663, 436, +607, -32, 471, -533, 247, -917, -81, -995, +-550, -872, -1096, -775, -1497, -668, -1586, -369, +-1356, 65, -809, 451, 52, 785, 1036, 1137, +1790, 1404, 2078, 1372, 1887, 952, 1252, 255, +227, -512, -958, -1230, -1922, -1845, -2451, -2102, +-2523, -1657, -2035, -661, -955, 366, 373, 1253, +1500, 2059, 2222, 2418, 2476, 1923, 2158, 898, +1255, -84, 48, -954, -1082, -1742, -1947, -2065, +-2421, -1688, -2380, -941, -1791, -202, -772, 477, +345, 1083, 1214, 1451, 1729, 1475, 1927, 1231, +1759, 846, 1124, 391, 145, -134, -760, -728, +-1365, -1262, -1772, -1550, -1936, -1529, -1615, -1223, +-804, -611, 138, 283, 878, 1219, 1390, 1852, +1631, 2002, 1389, 1699, 687, 1016, -153, 52, +-872, -937, -1352, -1580, -1464, -1692, -1109, -1383, +-451, -815, 143, -96, 512, 569, 692, 913, +623, 869, 271, 618, -217, 330, -587, 65, +-649, -100, -417, -50, -67, 196, 250, 422, +484, 427, 594, 206, 470, -127, 95, -490, +-331, -831, -660, -1021, -954, -878, -1195, -403, +-1148, 172, -684, 621, -12, 906, 571, 1046, +1010, 954, 1352, 597, 1462, 209, 1128, 13, +398, -105, -444, -339, -1214, -579, -1845, -667, +-2146, -757, -1875, -974, -1090, -1034, -132, -642, +775, 39, 1578, 728, 2098, 1401, 2087, 2015, +1509, 2233, 558, 1786, -484, 810, -1429, -378, +-2145, -1552, -2422, -2511, -2104, -2982, -1287, -2716, +-255, -1691, 756, -200, 1640, 1306, 2179, 2503, +2094, 3219, 1431, 3255, 485, 2450, -506, 989, +-1360, -597, -1876, -1868, -1911, -2677, -1492, -2909, +-788, -2413, 23, -1322, 706, -78, 1071, 931, +1123, 1564, 872, 1796, 350, 1661, -183, 1252, +-472, 726, -531, 288, -470, 54, -300, -105, +-55, -390, 93, -772, 51, -1086, -111, -1298, +-337, -1389, -521, -1180, -513, -554, -372, 311, +-210, 1144, 54, 1769, 407, 2026, 618, 1799, +606, 1156, 545, 292, 474, -575, 194, -1225, +-292, -1534, -719, -1544, -1024, -1335, -1311, -925, +-1404, -392, -1037, 95, -325, 489, 413, 903, +1054, 1338, 1565, 1619, 1743, 1621, 1405, 1353, +670, 805, -183, -42, -976, -1044, -1606, -1913, +-1946, -2390, -1854, -2332, -1314, -1701, -563, -601, +123, 695, 725, 1850, 1253, 2564, 1523, 2639, +1407, 2059, 1030, 1022, 571, -179, 47, -1270, +-575, -1984, -1143, -2114, -1446, -1675, -1495, -894, +-1414, -40, -1197, 698, -714, 1181, 35, 1299, +820, 1023, 1429, 491, 1759, -26, 1720, -339, +1289, -447, 510, -427, -496, -255, -1419, 88, +-1984, 402, -2144, 458, -1857, 315, -1050, 155, +86, -36, 1066, -344, 1549, -641, 1589, -721, +1287, -580, 635, -370, -170, -130, -802, 236, +-1116, 706, -1110, 1069, -824, 1169, -358, 1061, +106, 809, 393, 348, 444, -339, 270, -1064, +-74, -1562, -393, -1701, -524, -1495, -488, -957, +-331, -99, -47, 906, 309, 1731, 589, 2119, +685, 2011, 563, 1473, 237, 590, -188, -469, +-568, -1396, -837, -1908, -968, -1931, -904, -1553, +-652, -879, -285, -20, 123, 815, 477, 1370, +665, 1530, 712, 1373, 722, 1021, 635, 546, +360, 10, -13, -467, -356, -739, -694, -791, +-1071, -755, -1337, -712, -1277, -590, -898, -367, +-349, -153, 292, 42, 978, 349, 1539, 749, +1705, 1043, 1370, 1143, 700, 1076, -133, 784, +-998, 204, -1666, -513, -1942, -1120, -1784, -1507, +-1273, -1635, -513, -1359, 388, -625, 1200, 324, +1667, 1145, 1742, 1699, 1480, 1956, 888, 1777, +15, 1054, -923, -1, -1614, -1012, -1926, -1750, +-1891, -2086, -1432, -1884, -572, -1155, 378, -113, +1155, 973, 1691, 1827, 1892, 2187, 1602, 1973, +839, 1268, -141, 212, -1101, -921, -1895, -1761, +-2247, -2094, -1970, -1896, -1209, -1193, -223, -156, +784, 870, 1623, 1633, 2091, 2048, 2007, 1977, +1349, 1328, 318, 352, -761, -565, -1618, -1311, +-2148, -1864, -2254, -2023, -1776, -1637, -826, -842, +182, 110, 1002, 1045, 1642, 1824, 2004, 2266, +1875, 2178, 1244, 1526, 341, 517, -571, -580, +-1327, -1591, -1854, -2299, -2078, -2412, -1881, -1862, +-1252, -899, -399, 196, 451, 1240, 1226, 1983, +1808, 2178, 1979, 1816, 1659, 1091, 955, 235, +29, -556, -908, -1127, -1665, -1373, -2117, -1261, +-2112, -889, -1538, -458, -518, -64, 569, 302, +1356, 567, 1722, 637, 1641, 586, 1058, 509, +151, 389, -687, 233, -1171, 98, -1278, 0, +-1072, -28, -533, 26, 222, 26, 762, -131, +762, -324, 356, -468, -140, -668, -562, -862, +-875, -746, -939, -256, -578, 345, 67, 898, +663, 1414, 1029, 1716, 1133, 1531, 958, 869, +488, -3, -227, -856, -986, -1555, -1500, -1964, +-1598, -1942, -1321, -1429, -809, -567, -114, 355, +659, 1123, 1242, 1693, 1474, 2007, 1391, 1910, +1027, 1370, 408, 606, -347, -135, -1049, -833, +-1516, -1507, -1625, -1931, -1389, -1887, -904, -1483, +-236, -941, 525, -239, 1143, 677, 1427, 1566, +1405, 2098, 1135, 2228, 582, 2050, -149, 1496, +-821, 480, -1322, -790, -1668, -1911, -1788, -2627, +-1506, -2857, -766, -2502, 224, -1468, 1140, 66, +1799, 1642, 2149, 2828, 2077, 3398, 1389, 3213, +170, 2192, -1100, 546, -2026, -1190, -2542, -2521, +-2549, -3234, -1887, -3246, -723, -2449, 493, -985, +1436, 592, 2010, 1772, 2135, 2478, 1743, 2746, +997, 2437, 194, 1556, -517, 473, -1080, -440, +-1453, -1150, -1633, -1753, -1609, -2136, -1388, -2085, +-1001, -1620, -428, -960, 325, -203, 1141, 725, +1812, 1756, 2147, 2507, 2090, 2645, 1572, 2201, +526, 1360, -796, 173, -1941, -1215, -2654, -2377, +-2864, -2914, -2492, -2762, -1497, -2023, -103, -810, +1228, 625, 2176, 1862, 2654, 2587, 2580, 2721, +1913, 2302, 836, 1400, -310, 211, -1301, -934, +-2070, -1767, -2476, -2191, -2329, -2185, -1674, -1735, +-771, -924, 148, 37, 961, 908, 1570, 1538, +1834, 1864, 1677, 1861, 1211, 1502, 616, 827, +-41, 7, -697, -742, -1183, -1306, -1366, -1641, +-1296, -1663, -1095, -1326, -825, -715, -477, 37, +-60, 812, 384, 1433, 796, 1705, 1074, 1576, +1146, 1112, 1011, 392, 689, -447, 227, -1163, +-283, -1529, -774, -1461, -1144, -1010, -1279, -300, +-1134, 494, -756, 1140, -278, 1419, 196, 1224, +598, 645, 778, -81, 666, -742, 433, -1205, +252, -1313, 132, -936, 8, -180, -71, 637, +-20, 1253, 40, 1548, -80, 1441, -359, 865, +-658, -70, -887, -1024, -991, -1684, -887, -1922, +-492, -1680, 125, -941, 760, 131, 1231, 1215, +1434, 2020, 1356, 2351, 999, 2107, 320, 1337, +-557, 220, -1303, -993, -1721, -1996, -1847, -2527, +-1685, -2498, -1097, -1926, -158, -856, 769, 510, +1445, 1768, 1871, 2589, 1950, 2865, 1537, 2558, +714, 1634, -271, 258, -1182, -1187, -1830, -2316, +-2056, -2891, -1829, -2821, -1257, -2116, -461, -909, +419, 509, 1150, 1765, 1570, 2557, 1663, 2744, +1417, 2340, 855, 1451, 140, 258, -514, -956, +-1010, -1855, -1337, -2258, -1465, -2181, -1346, -1676, +-986, -791, -457, 258, 137, 1129, 696, 1630, +1131, 1790, 1362, 1622, 1317, 1086, 992, 318, +476, -376, -140, -813, -770, -1038, -1291, -1088, +-1563, -907, -1508, -551, -1137, -223, -547, -40, +127, 100, 745, 286, 1179, 432, 1349, 514, +1204, 679, 804, 925, 323, 981, -165, 725, +-666, 305, -1039, -207, -1127, -846, -1005, -1422, +-846, -1623, -618, -1400, -182, -880, 341, -121, +702, 761, 860, 1462, 897, 1728, 792, 1546, +482, 1043, 27, 358, -376, -350, -643, -912, +-829, -1171, -868, -1044, -633, -642, -210, -217, +164, 95, 343, 321, 344, 412, 234, 253, +21, -68, -225, -269, -347, -212, -226, -7, +61, 245, 321, 591, 511, 982, 676, 1134, +683, 849, 325, 250, -297, -436, -869, -1117, +-1239, -1678, -1420, -1870, -1333, -1537, -859, -763, +-74, 227, 738, 1189, 1350, 1899, 1732, 2205, +1834, 2023, 1513, 1352, 727, 376, -310, -592, +-1270, -1367, -1955, -1881, -2310, -2013, -2189, -1692, +-1488, -1061, -419, -304, 652, 498, 1535, 1233, +2171, 1719, 2357, 1836, 1903, 1595, 966, 1064, +-117, 325, -1144, -493, -1958, -1203, -2346, -1604, +-2162, -1594, -1455, -1239, -455, -663, 563, 32, +1402, 692, 1937, 1111, 2037, 1208, 1616, 1053, +785, 721, -170, 269, -1034, -186, -1689, -532, +-1988, -736, -1820, -775, -1227, -636, -385, -381, +497, -76, 1257, 269, 1724, 589, 1753, 739, +1342, 665, 636, 437, -158, 111, -872, -289, +-1404, -632, -1632, -749, -1460, -607, -981, -305, +-398, 57, 155, 419, 634, 678, 999, 703, +1142, 472, 1028, 130, 783, -174, 534, -368, +235, -408, -203, -288, -710, -79, -1096, 125, +-1301, 246, -1381, 193, -1272, -45, -856, -317, +-178, -451, 573, -432, 1245, -289, 1731, 47, +1907, 565, 1663, 1010, 1014, 1130, 114, 932, +-810, 540, -1540, -26, -1958, -738, -2060, -1371, +-1867, -1655, -1351, -1517, -560, -1052, 317, -366, +1102, 462, 1752, 1279, 2241, 1852, 2410, 2024, +2065, 1802, 1246, 1254, 149, 418, -1115, -590, +-2366, -1527, -3241, -2179, -3406, -2429, -2783, -2215, +-1511, -1501, 171, -391, 1899, 865, 3209, 1991, +3758, 2743, 3390, 2923, 2169, 2433, 471, 1357, +-1232, -72, -2579, -1519, -3272, -2619, -3115, -3094, +-2217, -2836, -960, -1884, 270, -452, 1277, 1083, +1906, 2309, 2015, 2930, 1648, 2806, 1039, 1972, +412, 651, -143, -784, -609, -1943, -911, -2530, +-987, -2416, -943, -1673, -878, -523, -756, 718, +-484, 1695, -70, 2121, 337, 1914, 622, 1200, +783, 225, 821, -723, 665, -1385, 354, -1596, +34, -1305, -207, -634, -422, 144, -599, 778, +-616, 1119, -471, 1094, -309, 723, -206, 171, +-66, -336, 150, -674, 313, -794, 323, -673, +256, -364, 184, -11, 64, 256, -132, 410, +-299, 483, -307, 509, -145, 491, 85, 405, +269, 256, 370, 59, 348, -224, 95, -617, +-366, -991, -770, -1160, -925, -1030, -853, -594, +-549, 103, 38, 922, 736, 1626, 1221, 1989, +1357, 1843, 1171, 1150, 635, 75, -215, -1081, +-1093, -2027, -1667, -2512, -1784, -2357, -1458, -1568, +-772, -366, 129, 917, 1026, 1952, 1663, 2500, +1829, 2448, 1473, 1823, 787, 807, -2, -320, +-817, -1269, -1508, -1847, -1800, -1981, -1579, -1706, +-1023, -1146, -334, -440, 403, 281, 1058, 858, +1424, 1191, 1413, 1301, 1078, 1237, 508, 989, +-115, 565, -655, 62, -1052, -401, -1227, -755, +-1091, -956, -711, -987, -270, -837, 136, -493, +503, -52, 787, 298, 884, 490, 786, 610, +542, 658, 201, 520, -193, 244, -559, 24, +-820, -102, -918, -249, -827, -393, -557, -391, +-175, -248, 232, -89, 609, 64, 864, 265, +906, 441, 730, 432, 414, 224, 12, -48, +-421, -312, -771, -576, -967, -733, -1007, -621, +-880, -242, -535, 238, 2, 671, 564, 985, +973, 1106, 1180, 926, 1150, 423, 816, -235, +222, -805, -445, -1162, -1000, -1300, -1336, -1168, +-1369, -711, -1036, -47, -403, 586, 321, 1027, +905, 1242, 1170, 1228, 1099, 976, 784, 507, +278, -56, -324, -545, -763, -871, -848, -1057, +-670, -1081, -414, -858, -118, -438, 222, 11, +420, 415, 350, 762, 121, 942, -73, 872, +-176, 612, -229, 261, -272, -121, -235, -430, +-49, -561, 173, -516, 277, -344, 287, -89, +348, 151, 410, 252, 303, 207, 30, 86, +-260, -99, -564, -320, -891, -455, -1115, -412, +-1076, -216, -697, 66, -22, 389, 792, 707, +1494, 938, 1885, 982, 1843, 782, 1302, 374, +283, -171, -972, -783, -2064, -1352, -2664, -1718, +-2614, -1731, -1902, -1329, -639, -568, 882, 407, +2206, 1425, 2907, 2278, 2822, 2703, 2047, 2498, +811, 1672, -599, 418, -1844, -1007, -2595, -2304, +-2667, -3162, -2102, -3331, -1142, -2718, -62, -1447, +937, 146, 1675, 1664, 1968, 2816, 1798, 3398, +1371, 3234, 862, 2347, 241, 1040, -470, -336, +-1095, -1590, -1502, -2551, -1703, -2995, -1703, -2844, +-1422, -2239, -837, -1356, -44, -260, 789, 965, +1536, 2085, 2064, 2814, 2232, 3053, 1906, 2858, +1145, 2190, 173, 957, -852, -631, -1828, -2093, +-2526, -3122, -2674, -3690, -2255, -3648, -1437, -2732, +-379, -1085, 852, 742, 2007, 2351, 2723, 3612, +2821, 4253, 2401, 3910, 1620, 2606, 504, 803, +-866, -1053, -2126, -2689, -2852, -3797, -2987, -4040, +-2655, -3333, -1866, -1940, -589, -288, 897, 1258, +2108, 2445, 2797, 3057, 2986, 2954, 2663, 2237, +1756, 1232, 396, 212, -1042, -719, -2153, -1428, +-2749, -1747, -2819, -1700, -2333, -1466, -1304, -1124, +-19, -655, 1076, -118, 1761, 357, 2068, 726, +1976, 1018, 1433, 1212, 638, 1231, -75, 1029, +-562, 643, -879, 178, -1045, -278, -1024, -703, +-865, -1034, -709, -1138, -576, -968, -334, -635, +34, -263, 362, 116, 578, 466, 752, 676, +846, 683, 739, 550, 449, 379, 163, 211, +-38, 55, -204, -55, -347, -94, -416, -85, +-426, -88, -476, -142, -609, -240, -731, -354, +-665, -451, -407, -507, -60, -485, 338, -347, +820, -71, 1254, 310, 1397, 703, 1179, 1008, +726, 1147, 121, 1059, -621, 718, -1298, 141, +-1673, -558, -1646, -1170, -1293, -1523, -724, -1563, +-65, -1288, 592, -714, 1137, 34, 1435, 733, +1430, 1220, 1188, 1448, 817, 1409, 333, 1123, +-207, 685, -706, 197, -1103, -287, -1355, -721, +-1403, -1061, -1250, -1272, -918, -1316, -391, -1153, +294, -772, 975, -195, 1476, 513, 1743, 1188, +1718, 1612, 1320, 1673, 573, 1385, -362, 776, +-1278, -72, -1937, -924, -2136, -1506, -1846, -1680, +-1167, -1451, -199, -891, 883, -123, 1727, 639, +2032, 1164, 1802, 1319, 1215, 1122, 365, 670, +-611, 78, -1392, -495, -1672, -853, -1471, -887, +-982, -661, -337, -300, 357, 112, 906, 479, +1124, 653, 1029, 561, 735, 290, 348, -26, +-84, -312, -493, -517, -812, -556, -929, -401, +-818, -135, -548, 122, -170, 306, 251, 402, +606, 393, 758, 283, 734, 135, 610, 24, +398, -19, 71, -23, -242, -27, -434, -52, +-526, -121, -557, -262, -549, -439, -519, -548, +-471, -513, -345, -331, -124, -31, 173, 355, +518, 733, 909, 957, 1200, 941, 1201, 695, +894, 280, 361, -209, -326, -639, -1064, -910, +-1634, -975, -1825, -819, -1566, -500, -948, -134, +-127, 199, 721, 468, 1445, 632, 1872, 653, +1808, 559, 1272, 403, 520, 199, -242, -51, +-941, -292, -1427, -427, -1476, -404, -1083, -271, +-540, -104, -81, 80, 274, 247, 501, 262, +487, 20, 263, -352, 42, -618, 1, -691, +135, -571, 346, -193, 587, 451, 795, 1138, +854, 1526, 598, 1447, -11, 975, -793, 212, +-1434, -752, -1782, -1647, -1807, -2074, -1408, -1874, +-552, -1233, 529, -344, 1464, 684, 2081, 1591, +2315, 2007, 2097, 1825, 1359, 1247, 252, 491, +-921, -331, -1857, -1079, -2373, -1522, -2384, -1526, +-1862, -1192, -928, -717, 152, -185, 1087, 391, +1763, 891, 2083, 1130, 1942, 1105, 1350, 957, +527, 696, -290, 245, -991, -287, -1495, -683, +-1652, -895, -1397, -998, -895, -974, -311, -750, +278, -382, 793, -3, 1072, 327, 1017, 621, +739, 867, 431, 1017, 170, 1022, -67, 848, +-269, 502, -366, 38, -328, -483, -267, -1007, +-301, -1408, -399, -1507, -486, -1226, -509, -670, +-404, 15, -112, 724, 338, 1314, 766, 1587, +992, 1453, 978, 997, 747, 361, 314, -314, +-227, -885, -706, -1218, -1011, -1254, -1073, -1025, +-856, -608, -392, -86, 140, 423, 579, 767, +852, 874, 868, 793, 579, 559, 137, 177, +-224, -235, -448, -476, -524, -493, -430, -396, +-183, -222, 72, 44, 230, 273, 264, 287, +205, 107, 102, -109, -10, -281, -100, -389, +-162, -365, -133, -174, -55, 111, 5, 381, +19, 538, 33, 531, 31, 391, 0, 179, +-18, -63, -2, -271, 39, -364, 74, -351, +114, -326, 129, -305, 97, -216, 33, -98, +-27, -62, -115, -56, -256, 71, -387, 269, +-388, 358, -220, 340, 14, 353, 245, 373, +465, 256, 625, 31, 620, -147, 415, -239, +92, -318, -248, -405, -552, -452, -758, -417, +-772, -317, -556, -203, -174, -83, 234, 106, +539, 359, 718, 557, 752, 626, 556, 595, +156, 474, -261, 233, -540, -82, -667, -368, +-607, -554, -301, -602, 160, -505, 542, -322, +701, -147, 606, -18, 250, 71, -245, 101, +-681, 61, -884, 36, -776, 126, -346, 316, +250, 500, 762, 596, 1012, 577, 946, 403, +603, 39, 82, -448, -424, -879, -767, -1107, +-835, -1078, -652, -787, -342, -268, -53, 352, +189, 859, 340, 1106, 319, 1094, 207, 867, +186, 440, 294, -88, 359, -492, 336, -653, +277, -667, 164, -623, -121, -481, -508, -262, +-785, -117, -848, -93, -722, -75, -439, 29, +15, 203, 555, 398, 985, 597, 1133, 767, +1022, 839, 741, 731, 308, 392, -268, -121, +-854, -663, -1245, -1116, -1349, -1404, -1182, -1433, +-731, -1134, -40, -535, 690, 235, 1262, 998, +1562, 1564, 1535, 1800, 1152, 1655, 453, 1124, +-385, 280, -1125, -650, -1583, -1381, -1641, -1763, +-1297, -1770, -667, -1367, 78, -588, 773, 312, +1287, 1005, 1480, 1364, 1306, 1426, 865, 1187, +316, 643, -272, -31, -806, -558, -1143, -822, +-1185, -917, -948, -901, -571, -712, -143, -364, +306, -21, 739, 212, 974, 415, 917, 676, +686, 892, 483, 881, 241, 657, -150, 366, +-499, 2, -611, -535, -601, -1112, -668, -1406, +-679, -1294, -469, -924, -126, -374, 157, 390, +409, 1212, 711, 1746, 973, 1794, 1003, 1403, +724, 681, 247, -262, -255, -1208, -675, -1893, +-976, -2122, -1019, -1793, -698, -954, -137, 149, +379, 1186, 687, 1919, 773, 2205, 616, 1919, +209, 1053, -319, -131, -733, -1238, -855, -1976, +-640, -2189, -161, -1802, 455, -901, 1064, 237, +1456, 1294, 1433, 1994, 963, 2102, 187, 1562, +-724, 589, -1603, -483, -2189, -1416, -2211, -2014, +-1638, -2063, -659, -1487, 546, -492, 1807, 580, +2758, 1461, 3000, 1996, 2419, 2056, 1264, 1581, +-143, 677, -1529, -388, -2580, -1305, -2977, -1857, +-2603, -1969, -1631, -1650, -364, -948, 861, -28, +1802, 824, 2259, 1346, 2157, 1469, 1596, 1275, +838, 855, 95, 292, -566, -238, -1078, -528, +-1310, -526, -1192, -376, -885, -244, -523, -176, +-176, -186, 125, -326, 311, -567, 377, -744, +369, -698, 345, -400, 368, 89, 448, 665, +548, 1184, 608, 1490, 629, 1485, 514, 1142, +125, 512, -497, -279, -1065, -1037, -1380, -1582, +-1440, -1809, -1226, -1690, -651, -1242, 212, -539, +1051, 281, 1590, 1014, 1762, 1477, 1588, 1611, +1069, 1455, 277, 1044, -569, 439, -1180, -171, +-1390, -610, -1269, -865, -963, -981, -524, -931, +13, -729, 499, -522, 746, -395, 748, -232, +640, 44, 461, 315, 202, 524, -43, 757, +-146, 981, -101, 997, -3, 733, 60, 319, +88, -138, 83, -609, 5, -1007, -175, -1175, +-442, -1039, -634, -676, -622, -224, -410, 235, +-78, 632, 354, 875, 785, 894, 1015, 708, +944, 392, 659, 16, 282, -350, -190, -622, +-654, -726, -899, -647, -782, -394, -455, -12, +-128, 403, 121, 721, 314, 826, 382, 671, +225, 288, -34, -229, -172, -771, -100, -1191, +69, -1312, 279, -1019, 538, -402, 801, 323, +859, 1013, 568, 1582, 31, 1827, -545, 1562, +-1047, 872, -1410, 33, -1464, -783, -1095, -1511, +-419, -1986, 323, -2003, 987, -1563, 1487, -864, +1704, -60, 1553, 772, 1080, 1490, 433, 1905, +-229, 1930, -780, 1612, -1144, 1022, -1281, 247, +-1194, -563, -958, -1234, -656, -1635, -309, -1717, +89, -1512, 465, -1065, 738, -461, 935, 145, +1085, 643, 1133, 1016, 1043, 1249, 835, 1280, +482, 1099, -45, 797, -653, 438, -1186, -2, +-1541, -505, -1669, -936, -1495, -1186, -1038, -1249, +-366, -1143, 444, -864, 1229, -422, 1788, 116, +2021, 630, 1952, 1017, 1537, 1247, 784, 1319, +-130, 1185, -921, 797, -1501, 224, -1894, -388, +-2042, -945, -1829, -1393, -1253, -1621, -500, -1504, +279, -1060, 1057, -421, 1831, 310, 2369, 1034, +2456, 1575, 2088, 1765, 1382, 1594, 361, 1143, +-916, 452, -2116, -415, -2850, -1252, -2955, -1807, +-2489, -1974, -1504, -1761, -128, -1160, 1327, -202, +2431, 892, 2917, 1784, 2771, 2223, 2095, 2126, +1034, 1520, -168, 491, -1203, -732, -1873, -1784, +-2126, -2326, -1990, -2239, -1513, -1606, -790, -603, +23, 543, 760, 1536, 1312, 2093, 1630, 2091, +1670, 1602, 1387, 788, 834, -172, 154, -1053, +-517, -1652, -1078, -1887, -1384, -1747, -1343, -1246, +-1032, -495, -567, 308, -25, 1006, 512, 1533, +910, 1794, 1130, 1675, 1204, 1191, 1100, 506, +768, -233, 263, -955, -297, -1555, -859, -1879, +-1331, -1815, -1572, -1395, -1436, -739, -926, 50, +-146, 900, 750, 1662, 1592, 2095, 2139, 2056, +2133, 1607, 1530, 868, 537, -103, -552, -1171, +-1570, -2025, -2265, -2379, -2337, -2195, -1713, -1583, +-668, -628, 475, 522, 1498, 1551, 2159, 2146, +2234, 2213, 1689, 1814, 754, 1033, -277, 22, +-1137, -920, -1662, -1526, -1739, -1740, -1349, -1617, +-615, -1180, 184, -515, 801, 155, 1168, 642, +1263, 925, 1041, 1053, 547, 1016, 22, 804, +-329, 492, -478, 168, -487, -149, -389, -457, +-239, -732, -134, -920, -114, -951, -139, -793, +-167, -478, -165, -78, -71, 355, 147, 755, +437, 1007, 710, 1015, 886, 795, 865, 425, +595, -30, 139, -507, -370, -879, -823, -1027, +-1112, -949, -1123, -712, -846, -343, -379, 120, +172, 568, 714, 874, 1069, 978, 1116, 907, +912, 684, 595, 309, 194, -178, -269, -641, +-660, -955, -840, -1100, -787, -1096, -572, -888, +-222, -440, 196, 137, 583, 665, 793, 1063, +752, 1307, 495, 1314, 151, 1005, -205, 448, +-538, -176, -726, -733, -655, -1170, -328, -1404, +105, -1340, 519, -993, 797, -490, 831, 44, +582, 541, 176, 938, -236, 1163, -538, 1175, +-664, 976, -613, 621, -397, 182, -71, -286, +290, -726, 560, -1054, 660, -1189, 586, -1118, +400, -854, 144, -413, -131, 139, -343, 661, +-442, 1043, -429, 1258, -313, 1253, -99, 938, +134, 360, 275, -269, 301, -811, 281, -1240, +233, -1467, 146, -1335, 70, -838, 46, -178, +42, 447, 31, 961, 9, 1311, -23, 1373, +-70, 1083, -143, 557, -221, -5, -244, -483, +-160, -846, 5, -1069, 192, -1092, 360, -893, +498, -560, 537, -205, 428, 143, 224, 489, +-7, 768, -251, 894, -507, 848, -666, 648, +-660, 302, -498, -114, -226, -480, 178, -709, +651, -759, 1005, -606, 1111, -286, 976, 72, +661, 336, 189, 428, -377, 324, -931, 58, +-1284, -253, -1322, -483, -1033, -549, -505, -392, +167, -28, 864, 406, 1368, 740, 1499, 887, +1262, 812, 808, 481, 235, -53, -357, -603, +-833, -975, -1040, -1081, -962, -922, -697, -542, +-346, -45, -14, 432, 224, 749, 369, 813, +459, 636, 480, 317, 457, -11, 443, -263, +437, -392, 372, -383, 232, -252, 64, -77, +-128, 36, -354, 33, -535, -54, -601, -145, +-561, -184, -423, -153, -194, -47, 75, 154, +346, 400, 621, 544, 868, 493, 1001, 285, +917, -22, 581, -398, 57, -749, -511, -930, +-984, -873, -1275, -604, -1286, -183, -924, 304, +-237, 735, 516, 1003, 1146, 1062, 1560, 910, +1634, 588, 1250, 165, 529, -282, -239, -687, +-859, -983, -1290, -1124, -1465, -1111, -1249, -960, +-730, -657, -107, -205, 458, 325, 922, 827, +1218, 1216, 1258, 1435, 1054, 1430, 734, 1147, +376, 598, -37, -110, -484, -828, -886, -1421, +-1108, -1792, -1114, -1853, -932, -1542, -604, -911, +-120, -104, 458, 726, 987, 1454, 1334, 1935, +1451, 2027, 1320, 1682, 893, 977, 249, 66, +-424, -870, -983, -1640, -1354, -2050, -1428, -1994, +-1161, -1505, -658, -708, -93, 214, 451, 1024, +939, 1516, 1254, 1606, 1288, 1322, 1082, 769, +783, 113, 450, -465, 38, -816, -444, -892, +-832, -748, -1011, -493, -1059, -221, -1030, -6, +-800, 90, -299, 50, 316, -50, 847, -87, +1242, -6, 1492, 160, 1465, 352, 1060, 520, +358, 596, -405, 497, -1040, 199, -1443, -211, +-1525, -594, -1170, -854, -422, -927, 420, -757, +1092, -368, 1489, 88, 1545, 473, 1141, 739, +363, 840, -474, 709, -1072, 389, -1350, 36, +-1263, -244, -761, -461, 1, -603, 714, -611, +1141, -500, 1260, -353, 1109, -212, 726, -41, +176, 167, -333, 370, -627, 524, -686, 606, +-603, 587, -463, 436, -277, 171, -85, -169, +39, -520, 98, -791, 179, -898, 299, -816, +439, -576, 549, -222, 612, 192, 609, 584, +489, 857, 248, 949, -54, 856, -348, 612, +-578, 244, -664, -202, -570, -632, -354, -937, +-134, -1056, 63, -978, 253, -733, 383, -366, +401, 59, 375, 456, 379, 734, 395, 857, +384, 848, 336, 739, 265, 544, 163, 281, +-5, -27, -251, -352, -465, -666, -553, -939, +-517, -1118, -420, -1137, -259, -935, -12, -513, +232, 49, 399, 628, 535, 1115, 692, 1409, +783, 1411, 761, 1119, 626, 614, 404, 0, +75, -612, -355, -1076, -795, -1304, -1111, -1327, +-1191, -1176, -997, -831, -561, -328, 34, 184, +709, 603, 1251, 925, 1498, 1123, 1451, 1104, +1188, 849, 718, 458, 108, 46, -467, -328, +-878, -618, -1119, -767, -1215, -765, -1113, -657, +-828, -511, -428, -355, 27, -197, 533, -43, +1045, 110, 1454, 289, 1620, 489, 1483, 647, +1077, 687, 433, 577, -352, 331, -1085, -18, +-1547, -403, -1629, -719, -1346, -857, -783, -761, +-45, -457, 673, -47, 1145, 350, 1269, 634, +1118, 729, 830, 590, 480, 239, 140, -207, +-93, -592, -178, -806, -218, -822, -292, -632, +-380, -250, -446, 226, -491, 645, -468, 888, +-299, 911, 27, 722, 415, 371, 737, -77, +915, -516, 880, -826, 638, -921, 268, -803, +-100, -541, -357, -217, -447, 110, -412, 367, +-291, 471, -96, 393, 84, 205, 141, 41, +53, -28, -48, -18, -66, 36, -9, 153, +106, 302, 322, 358, 588, 224, 776, -49, +780, -337, 570, -571, 213, -747, -199, -823, +-590, -716, -899, -424, -998, -48, -815, 285, +-400, 544, 85, 752, 550, 899, 944, 906, +1153, 720, 1089, 405, 800, 43, 413, -363, +7, -815, -358, -1208, -621, -1393, -729, -1304, +-691, -954, -519, -375, -250, 346, 57, 1049, +367, 1564, 663, 1773, 864, 1602, 858, 1036, +647, 185, 291, -749, -127, -1550, -514, -2032, +-739, -2069, -726, -1636, -489, -803, -105, 242, +343, 1213, 735, 1844, 932, 2018, 898, 1748, +678, 1079, 337, 141, -72, -787, -444, -1403, +-666, -1608, -676, -1475, -556, -1088, -387, -518, +-160, 79, 142, 500, 462, 662, 697, 642, +828, 562, 894, 465, 874, 361, 657, 284, +249, 265, -233, 237, -655, 104, -985, -173, +-1176, -527, -1095, -846, -657, -1043, 22, -1051, +715, -811, 1270, -327, 1604, 278, 1654, 833, +1317, 1200, 625, 1276, -190, 1003, -876, 454, +-1356, -180, -1602, -720, -1506, -1058, -999, -1110, +-239, -852, 479, -380, 1057, 122, 1520, 491, +1790, 661, 1693, 627, 1231, 413, 586, 73, +-86, -274, -767, -491, -1395, -524, -1752, -426, +-1671, -255, -1204, -38, -537, 191, 235, 372, +1037, 450, 1680, 414, 1914, 291, 1728, 122, +1280, -81, 635, -299, -172, -490, -930, -609, +-1370, -625, -1429, -525, -1176, -324, -668, -78, +23, 181, 661, 445, 1033, 669, 1103, 752, +934, 651, 585, 446, 153, 211, -218, -82, +-390, -446, -335, -752, -154, -870, 67, -824, +243, -700, 318, -491, 247, -169, 72, 197, +-111, 480, -203, 644, -188, 708, -71, 674, +139, 546, 356, 350, 505, 117, 553, -126, +501, -341, 327, -503, 69, -626, -183, -728, +-334, -765, -406, -674, -422, -453, -335, -169, +-127, 131, 138, 458, 383, 790, 575, 1003, +703, 979, 762, 748, 679, 418, 466, 39, +200, -402, -52, -829, -291, -1094, -538, -1138, +-721, -1014, -732, -779, -577, -419, -334, 52, +1, 538, 418, 927, 840, 1161, 1128, 1203, +1206, 1034, 1083, 656, 798, 112, 366, -498, +-153, -1024, -643, -1341, -993, -1390, -1129, -1175, +-1047, -751, -735, -202, -231, 365, 341, 831, +831, 1099, 1182, 1120, 1337, 932, 1229, 629, +848, 261, 304, -169, -217, -600, -630, -897, +-887, -987, -906, -922, -642, -754, -204, -455, +248, -15, 579, 443, 755, 735, 740, 793, +509, 693, 168, 488, -111, 161, -246, -226, +-260, -512, -170, -592, 11, -514, 271, -360, +492, -162, 567, 50, 486, 203, 315, 232, +89, 154, -178, 36, -403, -65, -470, -129, +-368, -151, -224, -125, -63, -50, 157, 43, +423, 108, 632, 112, 734, 58, 738, -27, +656, -117, 458, -182, 147, -195, -192, -156, +-482, -83, -664, 15, -722, 114, -619, 154, +-333, 97, 82, -26, 488, -146, 814, -230, +992, -277, 947, -254, 704, -114, 380, 116, +62, 320, -247, 392, -489, 325, -550, 157, +-416, -98, -238, -410, -75, -652, 91, -683, +239, -473, 328, -113, 368, 295, 402, 657, +448, 844, 484, 752, 459, 394, 363, -112, +194, -630, -21, -1016, -270, -1141, -514, -956, +-648, -530, -576, 5, -300, 533, 129, 940, +606, 1111, 983, 1001, 1159, 697, 1063, 312, +699, -90, 143, -472, -456, -785, -901, -977, +-1024, -1024, -845, -941, -475, -752, 15, -467, +547, -92, 973, 346, 1110, 763, 970, 1062, +713, 1192, 423, 1145, 57, 903, -335, 471, +-623, -81, -707, -643, -628, -1108, -483, -1401, +-244, -1473, 154, -1297, 622, -862, 937, -243, +1019, 407, 937, 939, 743, 1282, 356, 1385, +-190, 1197, -649, 741, -829, 165, -756, -368, +-521, -790, -172, -1063, 238, -1125, 594, -960, +757, -657, 732, -317, 600, 37, 421, 394, +218, 684, 51, 844, -26, 875, -31, 782, +-50, 521, -108, 87, -156, -413, -225, -848, +-299, -1133, -260, -1246, -46, -1136, 221, -743, +448, -124, 643, 502, 786, 958, 755, 1235, +504, 1345, 173, 1201, -124, 755, -367, 154, +-517, -402, -493, -860, -280, -1248, 39, -1491, +304, -1452, 448, -1115, 497, -616, 468, -67, +342, 507, 122, 1051, -93, 1411, -179, 1460, +-111, 1218, 37, 794, 229, 282, 408, -260, +497, -752, 425, -1102, 186, -1255, -131, -1227, +-384, -1071, -484, -807, -415, -429, -177, 39, +202, 532, 655, 974, 994, 1290, 1058, 1411, +832, 1269, 425, 842, -79, 186, -590, -558, +-967, -1219, -1054, -1636, -807, -1707, -359, -1420, +159, -829, 663, -68, 1069, 669, 1262, 1201, +1186, 1440, 888, 1372, 502, 1033, 100, 499, +-310, -95, -661, -609, -838, -961, -799, -1135, +-621, -1123, -382, -934, -87, -611, 258, -200, +536, 236, 702, 607, 795, 836, 829, 921, +762, 877, 582, 672, 340, 311, 87, -108, +-163, -480, -383, -759, -491, -928, -473, -947, +-371, -794, -237, -504, -50, -132, 206, 260, +446, 597, 552, 800, 521, 825, 431, 670, +292, 367, 107, -17, -58, -393, -81, -648, +37, -702, 182, -571, 269, -334, 309, -56, +282, 194, 172, 323, 12, 266, -140, 74, +-216, -122, -183, -246, -41, -292, 130, -246, +247, -74, 285, 154, 293, 302, 247, 325, +129, 285, 12, 202, -14, 41, 55, -161, +156, -311, 236, -384, 284, -428, 317, -441, +293, -370, 197, -206, 68, 1, 2, 220, +27, 435, 66, 584, 44, 582, -10, 401, +-58, 91, -118, -281, -191, -631, -241, -864, +-170, -893, 45, -692, 339, -297, 619, 201, +851, 680, 1000, 1014, 997, 1109, 754, 920, +281, 471, -283, -137, -809, -760, -1192, -1251, +-1341, -1497, -1173, -1418, -659, -1011, 110, -350, +889, 418, 1464, 1111, 1742, 1564, 1704, 1674, +1333, 1430, 654, 880, -166, 118, -885, -693, +-1332, -1358, -1459, -1738, -1258, -1781, -785, -1493, +-122, -912, 576, -152, 1126, 618, 1416, 1230, +1427, 1568, 1187, 1577, 730, 1267, 139, 718, +-451, 38, -868, -631, -1042, -1134, -978, -1351, +-697, -1279, -225, -983, 345, -540, 850, -39, +1131, 406, 1145, 696, 941, 802, 540, 750, +22, 569, -468, 300, -767, 2, -804, -265, +-606, -465, -281, -577, 102, -595, 480, -515, +755, -330, 835, -69, 714, 193, 521, 395, +332, 509, 112, 510, -143, 370, -314, 113, +-384, -179, -415, -419, -425, -567, -344, -607, +-132, -501, 155, -261, 458, 0, 727, 188, +896, 314, 893, 388, 720, 354, 388, 195, +-19, 26, -387, -62, -618, -113, -654, -172, +-518, -169, -290, -53, -14, 75, 276, 96, +475, 16, 524, -103, 471, -268, 415, -507, +335, -727, 211, -757, 125, -527, 145, -94, +173, 447, 127, 1000, 53, 1414, -28, 1493, +-133, 1129, -254, 389, -313, -528, -268, -1386, +-146, -1953, 14, -2046, 228, -1611, 458, -769, +638, 253, 719, 1194, 683, 1795, 553, 1884, +334, 1470, 51, 732, -224, -113, -422, -864, +-572, -1338, -680, -1403, -679, -1093, -484, -569, +-114, -7, 308, 446, 714, 678, 1073, 640, +1288, 400, 1242, 88, 933, -171, 433, -296, +-136, -257, -692, -90, -1124, 119, -1304, 260, +-1162, 265, -753, 110, -186, -162, 423, -434, +935, -583, 1251, -556, 1311, -380, 1139, -103, +779, 210, 332, 458, -68, 542, -344, 453, +-533, 268, -644, 75, -652, -87, -557, -213, +-384, -293, -182, -319, 51, -316, 326, -339, +613, -373, 811, -345, 866, -210, 786, -3, +606, 228, 315, 452, -62, 608, -392, 608, +-563, 428, -568, 141, -452, -165, -251, -449, +-20, -665, 208, -732, 367, -627, 430, -419, +430, -186, 431, 66, 439, 326, 397, 531, +278, 622, 125, 596, -37, 475, -226, 241, +-390, -95, -463, -457, -392, -734, -169, -845, +142, -766, 410, -521, 572, -154, 629, 255, +580, 586, 398, 733, 122, 673, -90, 463, +-176, 165, -177, -144, -125, -381, -23, -488, +71, -472, 99, -383, 39, -270, -62, -156, +-109, -55, -53, 20, 106, 79, 314, 123, +498, 167, 587, 204, 531, 205, 309, 138, +10, 28, -270, -71, -450, -136, -468, -169, +-316, -156, -32, -78, 298, 23, 565, 64, +672, 7, 598, -112, 351, -250, 33, -370, +-248, -421, -420, -351, -458, -157, -363, 113, +-158, 389, 113, 590, 377, 658, 558, 567, +639, 329, 599, -4, 456, -339, 235, -599, +-5, -756, -204, -796, -319, -679, -357, -411, +-311, -69, -173, 262, 4, 534, 160, 702, +240, 708, 252, 540, 225, 246, 182, -98, +153, -418, 180, -623, 233, -642, 271, -491, +273, -249, 226, 18, 130, 258, -7, 387, +-145, 344, -225, 172, -201, -17, -107, -168, +16, -283, 116, -323, 179, -231, 179, -55, +100, 85, 0, 139, -28, 152, 41, 129, +169, 33, 334, -100, 481, -186, 548, -180, +458, -124, 225, -43, -73, 69, -351, 195, +-529, 264, -536, 214, -379, 59, -131, -145, +140, -356, 349, -541, 447, -620, 431, -520, +374, -246, 307, 112, 215, 466, 127, 747, +122, 867, 155, 745, 114, 398, -2, -64, +-130, -522, -232, -880, -324, -1043, -364, -938, +-274, -612, -23, -173, 277, 274, 496, 638, +596, 824, 618, 787, 560, 573, 364, 263, +56, -53, -227, -303, -395, -462, -485, -540, +-498, -540, -388, -461, -123, -348, 205, -248, +462, -131, 616, 51, 698, 273, 682, 473, +515, 611, 222, 663, -102, 584, -361, 350, +-543, -10, -630, -420, -588, -777, -404, -986, +-116, -1004, 230, -827, 559, -472, 796, 6, +892, 489, 824, 854, 601, 1046, 246, 1046, +-131, 843, -431, 442, -614, -66, -701, -549, +-669, -906, -481, -1107, -159, -1116, 204, -887, +498, -459, 694, 33, 786, 462, 749, 771, +570, 919, 307, 869, 26, 634, -221, 309, +-417, -22, -525, -315, -514, -531, -388, -636, +-183, -642, 46, -590, 252, -483, 401, -315, +496, -93, 511, 146, 453, 380, 343, 585, +208, 708, 63, 677, -84, 487, -227, 196, +-343, -140, -399, -476, -373, -736, -240, -823, +-31, -718, 223, -491, 469, -215, 642, 87, +691, 362, 603, 523, 372, 533, 38, 454, +-304, 346, -562, 190, -666, -6, -591, -165, +-326, -235, 54, -267, 410, -300, 620, -307, +660, -273, 548, -245, 335, -247, 82, -231, +-135, -151, -229, -26, -169, 127, -34, 312, +67, 504, 116, 633, 111, 629, 29, 481, +-149, 198, -315, -185, -340, -590, -220, -912, +-19, -1054, 233, -979, 516, -706, 746, -276, +829, 244, 707, 742, 445, 1090, 106, 1202, +-261, 1060, -622, 683, -870, 138, -913, -450, +-754, -943, -452, -1243, -47, -1288, 414, -1046, +807, -559, 1037, 37, 1069, 573, 926, 944, +625, 1096, 224, 997, -196, 664, -537, 215, +-742, -199, -807, -500, -728, -684, -515, -743, +-199, -676, 131, -537, 407, -387, 592, -232, +691, -26, 682, 238, 566, 518, 366, 753, +125, 876, -108, 825, -308, 561, -443, 108, +-455, -421, -322, -860, -109, -1082, 122, -1030, +317, -732, 442, -272, 436, 192, 289, 498, +76, 559, -130, 408, -287, 155, -333, -71, +-227, -154, -26, -50, 206, 214, 389, 510, +468, 699, 432, 664, 307, 377, 106, -107, +-130, -655, -308, -1123, -353, -1390, -289, -1369, +-175, -1054, -4, -512, 198, 132, 347, 764, +380, 1268, 331, 1562, 239, 1587, 120, 1334, +-32, 833, -177, 164, -256, -557, -243, -1191, +-152, -1612, -19, -1749, 138, -1568, 271, -1096, +328, -427, 287, 278, 208, 883, 128, 1285, +53, 1424, 3, 1289, -5, 932, -8, 458, +-59, -29, -149, -450, -243, -761, -281, -916, +-237, -905, -82, -751, 163, -524, 442, -266, +670, 11, 748, 275, 604, 448, 270, 494, +-164, 454, -601, 362, -902, 211, -942, 16, +-647, -134, -99, -185, 520, -155, 1013, -92, +1252, -18, 1148, 38, 694, 23, 18, -77, +-659, -218, -1113, -335, -1222, -389, -973, -345, +-464, -180, 159, 72, 721, 307, 1068, 453, +1077, 495, 792, 425, 381, 244, -26, 11, +-377, -179, -598, -283, -580, -325, -344, -332, +-61, -303, 127, -253, 247, -215, 317, -191, +292, -126, 157, 16, 7, 212, -82, 396, +-132, 527, -181, 574, -195, 484, -112, 240, +45, -94, 231, -414, 392, -663, 498, -792, +497, -747, 367, -525, 136, -212, -117, 106, +-333, 390, -465, 599, -477, 673, -394, 601, +-241, 447, -43, 256, 169, 34, 331, -205, +422, -383, 449, -464, 430, -478, 348, -465, +212, -409, 72, -299, -73, -175, -222, -64, +-337, 39, -372, 177, -327, 345, -197, 517, +4, 634, 221, 670, 369, 591, 419, 361, +382, -28, 255, -508, 62, -940, -123, -1204, +-233, -1201, -265, -903, -221, -337, -118, 363, +27, 1007, 174, 1403, 284, 1441, 316, 1091, +264, 423, 158, -377, 35, -1065, -80, -1441, +-170, -1415, -200, -1005, -166, -345, -80, 371, +12, 932, 95, 1187, 160, 1085, 198, 701, +189, 187, 130, -298, 48, -616, -28, -696, +-61, -554, -41, -302, 29, -62, 107, 77, +156, 87, 137, -22, 62, -184, -47, -295, +-148, -265, -210, -83, -205, 198, -102, 492, +75, 704, 260, 752, 374, 596, 390, 273, +302, -131, 144, -507, -55, -750, -228, -806, +-303, -681, -270, -425, -175, -125, -67, 126, +44, 257, 133, 255, 174, 168, 163, 59, +168, -7, 205, 28, 241, 183, 247, 394, +222, 562, 130, 616, -51, 514, -276, 229, +-464, -195, -531, -645, -451, -1001, -232, -1165, +70, -1086, 390, -761, 640, -265, 740, 282, +656, 757, 435, 1064, 142, 1134, -162, 962, +-404, 612, -534, 184, -524, -235, -405, -570, +-240, -740, -94, -730, 18, -593, 102, -404, +177, -193, 243, 11, 333, 169, 458, 252, +575, 280, 625, 305, 554, 328, 352, 323, +21, 243, -390, 100, -805, -92, -1106, -317, +-1190, -543, -1014, -675, -604, -630, -8, -400, +674, -37, 1264, 391, 1602, 794, 1615, 1026, +1317, 1003, 735, 722, -11, 267, -747, -284, +-1309, -797, -1598, -1125, -1560, -1189, -1224, -1025, +-669, -699, 8, -259, 660, 197, 1153, 576, +1406, 812, 1415, 930, 1168, 931, 704, 809, +132, 568, -410, 263, -844, -65, -1095, -398, +-1110, -696, -896, -893, -513, -928, -74, -806, +329, -559, 649, -246, 873, 91, 927, 388, +784, 590, 505, 669, 175, 633, -192, 504, +-572, 307, -852, 78, -942, -155, -831, -349, +-544, -464, -85, -460, 477, -329, 1008, -95, +1342, 184, 1353, 418, 1003, 519, 381, 428, +-360, 137, -1051, -276, -1511, -682, -1588, -952, +-1235, -981, -583, -721, 183, -203, 894, 436, +1406, 1013, 1569, 1374, 1330, 1418, 784, 1117, +130, 535, -464, -179, -904, -848, -1099, -1323, +-1005, -1506, -670, -1357, -246, -915, 150, -298, +448, 338, 624, 867, 640, 1184, 505, 1218, +280, 965, 46, 513, -136, -3, -252, -451, +-288, -737, -244, -816, -128, -680, -6, -392, +90, -68, 149, 162, 186, 269, 195, 274, +170, 202, 137, 86, 90, 7, -9, 34, +-153, 114, -265, 163, -312, 137, -299, 63, +-218, -72, -31, -247, 217, -380, 421, -370, +515, -214, 507, 10, 396, 227, 159, 373, +-161, 385, -455, 226, -605, -30, -590, -274, +-419, -398, -108, -372, 277, -185, 590, 107, +723, 390, 669, 532, 459, 475, 113, 250, +-298, -86, -633, -431, -808, -672, -798, -696, +-599, -512, -212, -188, 273, 166, 730, 472, +1036, 644, 1088, 626, 864, 450, 439, 201, +-94, -33, -624, -219, -984, -327, -1067, -340, +-886, -284, -539, -230, -84, -199, 380, -182, +713, -151, 824, -91, 718, 11, 461, 163, +135, 319, -161, 430, -347, 452, -369, 367, +-255, 171, -82, -84, 60, -310, 137, -436, +133, -445, 68, -345, -13, -152, -72, 73, +-99, 234, -81, 272, -6, 208, 62, 90, +62, -51, 0, -179, -63, -236, -138, -188, +-199, -62, -165, 77, 18, 183, 286, 242, +521, 246, 654, 190, 649, 87, 474, -26, +107, -114, -354, -166, -754, -190, -965, -189, +-967, -169, -763, -133, -368, -93, 128, -49, +556, 2, 809, 61, 895, 123, 834, 169, +651, 187, 374, 171, 85, 135, -161, 79, +-342, 13, -498, -56, -633, -101, -694, -120, +-634, -129, -471, -136, -252, -140, 38, -124, +368, -92, 647, -34, 787, 39, 782, 130, +644, 205, 399, 240, 85, 203, -236, 96, +-493, -48, -638, -179, -659, -243, -578, -228, +-407, -132, -187, 2, 44, 139, 262, 207, +455, 180, 561, 58, 543, -99, 436, -222, +288, -255, 104, -177, -100, -6, -250, 227, +-307, 422, -291, 493, -263, 393, -234, 173, +-203, -125, -181, -439, -197, -694, -213, -787, +-147, -676, 29, -410, 281, -55, 560, 332, +814, 710, 941, 971, 846, 1035, 501, 882, +-18, 564, -592, 121, -1095, -393, -1406, -866, +-1422, -1164, -1110, -1201, -541, -990, 156, -589, +821, -77, 1337, 443, 1592, 821, 1519, 970, +1131, 888, 539, 643, -137, 318, -772, 9, +-1255, -199, -1480, -275, -1392, -248, -1036, -177, +-505, -117, 90, -122, 654, -212, 1058, -341, +1218, -436, 1112, -447, 804, -360, 375, -170, +-86, 104, -483, 396, -737, 618, -813, 728, +-727, 720, -528, 589, -284, 349, -30, 50, +192, -251, 362, -521, 452, -720, 463, -793, +416, -718, 340, -512, 223, -209, 63, 148, +-84, 480, -183, 692, -256, 730, -358, 606, +-443, 366, -453, 50, -389, -257, -277, -459, +-97, -492, 160, -384, 440, -205, 659, -10, +747, 156, 689, 250, 501, 224, 211, 107, +-173, -32, -558, -117, -807, -145, -852, -109, +-734, -22, -477, 98, -103, 198, 272, 222, +501, 158, 541, 21, 458, -131, 314, -266, +166, -336, 49, -323, 16, -196, 76, 16, +158, 258, 158, 441, 60, 513, -105, 465, +-342, 284, -616, -7, -803, -341, -783, -591, +-562, -698, -167, -625, 340, -389, 839, -12, +1159, 396, 1206, 707, 961, 828, 476, 724, +-129, 420, -708, -17, -1119, -443, -1258, -741, +-1074, -825, -645, -692, -103, -361, 437, 68, +861, 450, 1021, 655, 874, 646, 518, 468, +77, 182, -342, -129, -637, -363, -695, -427, +-515, -327, -196, -132, 121, 61, 360, 200, +477, 246, 425, 180, 187, 25, -133, -144, +-377, -237, -494, -222, -492, -121, -335, 18, +-20, 168, 296, 277, 468, 277, 474, 151, +372, -35, 175, -202, -65, -311, -240, -332, +-280, -229, -205, -13, -90, 236, 12, 429, +57, 512, 21, 456, -118, 258, -300, -41, +-424, -358, -403, -598, -222, -695, 93, -620, +478, -387, 805, -48, 943, 304, 820, 572, +457, 691, -68, 631, -621, 419, -1063, 121, +-1266, -169, -1179, -376, -813, -451, -259, -390, +351, -214, 882, 7, 1208, 177, 1261, 240, +1033, 189, 595, 61, 45, -106, -494, -254, +-905, -322, -1083, -257, -1023, -98, -772, 97, +-386, 276, 51, 396, 414, 414, 610, 315, +650, 151, 568, -32, 382, -185, 125, -289, +-93, -302, -214, -244, -255, -150, -239, -59, +-163, 28, -52, 92, 31, 104, 45, 83, +-2, 56, -64, 44, -140, 13, -228, -23, +-302, -43, -291, -22, -184, -1, -19, 12, +178, 45, 398, 115, 579, 180, 626, 185, +520, 145, 291, 70, -16, -33, -357, -182, +-641, -325, -802, -412, -796, -401, -632, -302, +-357, -133, -38, 85, 267, 304, 504, 471, +623, 531, 633, 482, 557, 333, 408, 126, +197, -89, -17, -246, -207, -331, -373, -350, +-503, -299, -559, -198, -537, -108, -454, -76, +-321, -68, -148, -46, 63, -12, 272, 24, +440, 92, 533, 203, 552, 316, 471, 377, +282, 366, 38, 295, -192, 179, -390, 35, +-545, -118, -588, -255, -498, -358, -327, -421, +-123, -446, 119, -431, 344, -365, 460, -232, +421, -32, 278, 210, 97, 446, -87, 624, +-239, 701, -319, 652, -287, 467, -186, 181, +-86, -133, -4, -396, 92, -563, 159, -624, +144, -584, 75, -457, 14, -267, -34, -64, +-97, 123, -147, 295, -151, 444, -101, 538, +-39, 527, 12, 405, 48, 190, 89, -61, +96, -306, 25, -478, -98, -508, -200, -364, +-247, -107, -240, 152, -157, 335, 11, 376, +229, 257, 394, 11, 439, -245, 356, -410, +172, -406, -90, -235, -370, 54, -566, 358, +-604, 560, -504, 590, -333, 436, -95, 155, +165, -182, 354, -455, 424, -599, 424, -581, +370, -446, 250, -236, 84, -1, -68, 218, +-186, 379, -287, 462, -355, 481, -377, 436, +-341, 335, -255, 165, -123, -42, 24, -261, +160, -433, 231, -528, 217, -518, 136, -397, +36, -190, -36, 49, -46, 248, 9, 375, +84, 399, 143, 343, 142, 223, 68, 82, +-89, -40, -275, -107, -426, -121, -498, -107, +-459, -77, -287, -41, -16, -11, 249, -18, +429, -55, 483, -92, 412, -102, 226, -85, +-10, -42, -206, 30, -295, 128, -280, 220, +-193, 252, -80, 205, 12, 98, 54, -47, +21, -203, -71, -320, -190, -344, -285, -259, +-318, -92, -249, 109, -83, 296, 156, 413, +407, 428, 572, 348, 574, 194, 399, -1, +96, -186, -269, -319, -595, -395, -785, -432, +-769, -426, -567, -356, -233, -223, 158, -48, +513, 163, 724, 403, 722, 623, 524, 738, +189, 698, -184, 506, -503, 186, -670, -197, +-660, -559, -506, -782, -269, -803, 1, -625, +241, -314, 403, 36, 471, 322, 437, 459, +305, 424, 106, 258, -108, 54, -315, -112, +-466, -164, -508, -83, -417, 104, -240, 294, +-22, 403, 199, 376, 363, 215, 407, -45, +307, -329, 107, -522, -131, -557, -333, -419, +-456, -186, -457, 75, -323, 279, -86, 358, +151, 264, 322, 52, 412, -168, 405, -302, +297, -291, 126, -129, -56, 159, -232, 466, +-365, 690, -442, 725, -470, 550, -461, 193, +-392, -239, -257, -625, -80, -865, 132, -891, +369, -704, 575, -363, 675, 10, 648, 319, +474, 491, 170, 525, -192, 435, -515, 286, +-741, 148, -813, 78, -706, 94, -474, 155, +-206, 198, 38, 163, 225, 43, 315, -157, +321, -393, 277, -594, 245, -662, 249, -553, +286, -291, 292, 54, 231, 398, 102, 647, +-118, 716, -419, 577, -706, 278, -853, -84, +-827, -403, -638, -577, -301, -552, 139, -337, +556, -2, 838, 350, 923, 614, 799, 712, +506, 605, 116, 311, -284, -81, -621, -468, +-810, -761, -825, -895, -688, -823, -449, -560, +-145, -182, 159, 213, 392, 555, 503, 786, +479, 861, 362, 759, 205, 530, 44, 262, +-105, 8, -201, -206, -226, -364, -204, -438, +-183, -445, -171, -430, -170, -429, -180, -418, +-212, -371, -242, -272, -208, -110, -84, 119, +90, 398, 239, 660, 344, 839, 404, 862, +390, 709, 254, 389, 35, -24, -180, -437, +-354, -752, -487, -887, -558, -792, -505, -493, +-320, -109, -71, 255, 143, 502, 300, 571, +397, 417, 392, 114, 249, -213, 29, -440, +-172, -504, -307, -377, -377, -76, -358, 302, +-210, 635, 17, 810, 217, 797, 307, 585, +289, 230, 170, -173, -29, -517, -252, -747, +-399, -832, -426, -775, -359, -602, -222, -351, +-44, -81, 137, 184, 261, 412, 314, 590, +292, 680, 211, 675, 82, 579, -72, 418, +-222, 206, -338, -35, -393, -249, -390, -397, +-320, -466, -175, -479, 16, -438, 192, -349, +324, -224, 383, -92, 356, 35, 237, 155, +57, 262, -129, 334, -276, 353, -355, 322, +-372, 252, -339, 159, -287, 51, -237, -49, +-216, -126, -192, -171, -117, -193, 28, -196, +220, -182, 437, -144, 625, -70, 702, 32, +615, 134, 358, 216, -16, 270, -441, 261, +-817, 170, -1054, 18, -1080, -138, -887, -255, +-521, -314, -74, -305, 356, -226, 685, -99, +845, 29, 817, 126, 629, 191, 360, 245, +91, 300, -121, 355, -285, 388, -385, 378, +-408, 291, -383, 108, -380, -166, -408, -472, +-417, -722, -385, -838, -312, -778, -176, -544, +64, -172, 364, 244, 637, 605, 781, 831, +747, 896, 535, 797, 176, 576, -268, 291, +-690, -4, -949, -273, -970, -506, -760, -671, +-385, -747, 77, -710, 498, -561, 746, -288, +740, 75, 521, 452, 187, 740, -151, 865, +-416, 798, -558, 544, -537, 158, -393, -268, +-214, -593, -75, -740, 28, -681, 99, -457, +137, -120, 157, 224, 191, 476, 234, 575, +255, 508, 232, 314, 137, 58, -32, -171, +-244, -321, -440, -354, -578, -278, -607, -113, +-510, 69, -310, 205, -63, 251, 174, 204, +354, 85, 458, -72, 483, -212, 420, -279, +293, -237, 133, -107, -32, 75, -212, 249, +-375, 378, -469, 422, -482, 357, -445, 195, +-356, -17, -213, -220, -58, -373, 72, -442, +166, -415, 236, -291, 272, -108, 281, 96, +258, 276, 196, 387, 107, 402, 10, 327, +-102, 189, -224, 20, -318, -132, -368, -219, +-371, -221, -332, -165, -254, -82, -162, -4, +-76, 44, 0, 42, 82, 12, 166, -8, +244, 22, 313, 106, 358, 213, 358, 294, +282, 295, 118, 187, -116, -38, -366, -323, +-588, -577, -721, -690, -725, -599, -581, -300, +-321, 129, -7, 573, 290, 909, 515, 1025, +627, 870, 600, 486, 463, -5, 254, -474, +30, -807, -172, -933, -317, -823, -399, -538, +-433, -190, -429, 123, -400, 350, -361, 464, +-308, 454, -212, 368, -66, 270, 119, 214, +315, 192, 491, 190, 601, 178, 603, 133, +471, 21, 214, -159, -126, -362, -480, -529, +-770, -606, -918, -568, -867, -400, -632, -129, +-269, 197, 138, 487, 504, 679, 728, 727, +762, 626, 630, 398, 374, 105, 47, -170, +-276, -371, -507, -463, -598, -442, -541, -315, +-388, -139, -194, 32, -13, 149, 114, 203, +145, 180, 86, 89, 4, -33, -44, -137, +-57, -183, -58, -156, -21, -48, 58, 106, +149, 282, 205, 423, 206, 478, 159, 408, +73, 230, -56, -6, -223, -242, -393, -421, +-507, -491, -541, -432, -520, -284, -424, -107, +-225, 29, 58, 90, 356, 67, 604, 1, +748, -42, 738, 1, 555, 162, 236, 414, +-145, 678, -493, 838, -727, 800, -817, 531, +-755, 72, -557, -485, -271, -994, 12, -1304, +229, -1311, 347, -1008, 365, -485, 312, 112, +232, 650, 160, 1022, 102, 1156, 67, 1055, +36, 796, -7, 482, -77, 172, -164, -96, +-269, -312, -379, -475, -463, -606, -488, -711, +-434, -755, -293, -691, -73, -495, 187, -180, +447, 230, 651, 651, 743, 976, 673, 1093, +442, 971, 72, 626, -370, 118, -789, -447, +-1074, -912, -1143, -1143, -965, -1090, -564, -762, +-26, -229, 530, 395, 959, 933, 1161, 1239, +1082, 1233, 751, 927, 254, 388, -279, -256, +-718, -833, -965, -1183, -982, -1218, -796, -948, +-478, -447, -128, 141, 164, 662, 334, 973, +367, 1016, 290, 795, 170, 400, 70, -47, +29, -416, 58, -610, 135, -596, 206, -399, +211, -109, 125, 189, -62, 402, -305, 481, +-525, 401, -644, 212, -640, -21, -506, -234, +-260, -376, 35, -411, 300, -332, 471, -176, +522, 13, 452, 179, 296, 288, 107, 309, +-57, 252, -166, 144, -217, 41, -240, -13, +-262, -1, -293, 67, -328, 158, -343, 228, +-318, 219, -220, 103, -52, -110, 149, -350, +330, -542, 448, -610, 467, -507, 372, -228, +183, 156, -51, 531, -276, 783, -450, 827, +-532, 646, -508, 279, -406, -163, -268, -544, +-113, -743, 40, -710, 172, -451, 274, -52, +359, 360, 412, 661, 391, 765, 276, 650, +88, 350, -142, -41, -377, -400, -551, -627, +-625, -683, -583, -575, -435, -337, -206, -30, +44, 250, 258, 435, 396, 514, 437, 503, +380, 417, 251, 284, 99, 147, -46, 26, +-160, -77, -246, -172, -296, -249, -304, -303, +-272, -322, -213, -302, -143, -233, -67, -109, +-3, 51, 33, 209, 30, 326, 12, 386, +-2, 377, -1, 306, 16, 187, 63, 52, +128, -74, 172, -170, 144, -227, 36, -242, +-119, -219, -283, -163, -408, -71, -457, 36, +-397, 140, -241, 210, -28, 246, 179, 231, +330, 159, 388, 49, 349, -52, 222, -114, +41, -126, -133, -81, -258, -1, -325, 76, +-345, 109, -311, 88, -242, 12, -171, -84, +-105, -160, -25, -167, 55, -87, 116, 60, +166, 228, 191, 364, 180, 419, 139, 349, +87, 174, 18, -67, -54, -300, -117, -465, +-185, -514, -275, -437, -359, -243, -396, 23, +-368, 290, -276, 503, -123, 619, 81, 607, +284, 457, 422, 217, 444, -69, 357, -342, +181, -539, -48, -600, -271, -517, -416, -324, +-443, -63, -358, 205, -209, 410, -61, 501, +56, 476, 112, 359, 99, 207, 26, 61, +-54, -38, -90, -80, -74, -86, -32, -87, +20, -111, 68, -165, 77, -240, 23, -306, +-81, -328, -183, -266, -250, -112, -256, 114, +-203, 360, -85, 575, 68, 700, 206, 690, +274, 538, 245, 270, 141, -59, -18, -386, +-204, -632, -369, -741, -443, -690, -409, -494, +-287, -190, -115, 139, 84, 399, 251, 531, +320, 532, 281, 413, 165, 220, 13, 29, +-150, -90, -273, -100, -312, -32, -260, 73, +-158, 159, -36, 168, 83, 80, 172, -70, +191, -230, 136, -342, 40, -353, -68, -244, +-176, -46, -281, 166, -350, 324, -355, 367, +-300, 292, -214, 128, -99, -61, 45, -206, +200, -247, 330, -165, 409, 8, 423, 213, +349, 377, 186, 449, -39, 393, -275, 227, +-474, 0, -590, -220, -604, -378, -520, -437, +-360, -399, -158, -291, 39, -148, 184, -7, +266, 106, 298, 173, 301, 217, 282, 260, +260, 320, 235, 376, 191, 412, 95, 391, +-69, 292, -277, 96, -496, -176, -685, -459, +-788, -676, -742, -751, -529, -644, -184, -351, +221, 69, 604, 515, 877, 859, 959, 1015, +809, 922, 459, 581, 0, 79, -465, -447, +-846, -854, -1061, -1046, -1031, -965, -768, -629, +-362, -123, 64, 406, 435, 827, 674, 1043, +723, 1007, 585, 738, 336, 321, 62, -125, +-178, -490, -333, -688, -377, -696, -326, -539, +-240, -282, -176, -4, -166, 215, -206, 328, +-274, 331, -316, 250, -287, 121, -171, -2, +18, -72, 245, -68, 465, 1, 617, 109, +641, 229, 500, 317, 229, 336, -111, 265, +-457, 114, -744, -90, -898, -300, -873, -460, +-692, -522, -411, -458, -73, -270, 275, 2, +549, 274, 683, 472, 663, 550, 523, 495, +296, 324, 31, 102, -213, -84, -379, -175, +-444, -158, -422, -59, -344, 69, -250, 142, +-163, 105, -120, -43, -136, -247, -178, -433, +-188, -509, -137, -417, -23, -152, 154, 224, +365, 601, 535, 864, 587, 929, 499, 771, +273, 418, -68, -37, -465, -479, -799, -794, +-981, -917, -973, -832, -769, -571, -394, -209, +80, 161, 537, 467, 863, 666, 982, 724, +878, 653, 573, 484, 140, 267, -327, 37, +-715, -166, -934, -304, -946, -359, -763, -341, +-438, -268, -58, -156, 279, -36, 495, 62, +553, 123, 473, 154, 291, 151, 71, 130, +-119, 101, -234, 75, -273, 52, -250, 31, +-191, 12, -134, -5, -109, -11, -118, -7, +-141, 14, -168, 52, -181, 106, -147, 153, +-62, 177, 36, 167, 133, 129, 215, 62, +256, -22, 231, -107, 149, -185, 34, -241, +-113, -264, -273, -242, -408, -188, -478, -99, +-473, 32, -384, 196, -219, 349, -11, 456, +194, 501, 348, 477, 413, 369, 384, 189, +270, -11, 88, -189, -116, -317, -285, -379, +-371, -371, -378, -316, -323, -239, -230, -162, +-131, -92, -70, -30, -57, 40, -53, 143, +-20, 280, 35, 428, 89, 541, 141, 578, +179, 514, 171, 344, 94, 83, -32, -216, +-171, -464, -285, -591, -339, -585, -311, -465, +-203, -260, -56, -25, 74, 177, 139, 306, +126, 368, 47, 379, -69, 358, -188, 317, +-270, 259, -286, 165, -225, 19, -98, -157, +62, -326, 196, -434, 262, -431, 262, -287, +205, -27, 100, 285, -50, 547, -205, 665, +-324, 584, -399, 323, -430, -37, -391, -388, +-276, -618, -126, -652, 11, -484, 117, -189, +198, 136, 236, 388, 228, 502, 185, 467, +121, 340, 42, 188, -36, 67, -108, 17, +-173, 33, -221, 64, -257, 50, -278, -22, +-282, -152, -259, -299, -220, -411, -164, -425, +-87, -326, 4, -125, 94, 133, 178, 383, +266, 565, 332, 638, 330, 604, 240, 471, +85, 266, -128, 22, -384, -221, -615, -438, +-725, -597, -669, -668, -462, -626, -144, -460, +221, -177, 530, 181, 672, 536, 615, 812, +384, 935, 40, 878, -329, 637, -598, 267, +-680, -150, -562, -514, -311, -742, -13, -797, +244, -698, 381, -498, 354, -236, 182, 36, +-42, 259, -226, 408, -330, 508, -343, 572, +-253, 593, -98, 559, 40, 462, 93, 300, +68, 77, 14, -187, -52, -453, -107, -654, +-111, -740, -40, -681, 60, -491, 122, -195, +104, 153, 18, 472, -119, 684, -277, 755, +-405, 678, -444, 465, -367, 175, -202, -116, +4, -329, 206, -433, 363, -409, 420, -266, +357, -48, 201, 166, 8, 313, -187, 341, +-350, 239, -446, 38, -461, -198, -406, -394, +-303, -480, -151, -394, 30, -145, 190, 197, +288, 531, 315, 764, 269, 813, 149, 639, +-31, 278, -220, -169, -363, -581, -432, -838, +-407, -850, -281, -616, -71, -207, 161, 256, +334, 644, 386, 843, 304, 808, 113, 551, +-137, 160, -393, -238, -576, -518, -610, -604, +-481, -503, -230, -257, 77, 48, 361, 311, +528, 435, 519, 408, 342, 261, 69, 62, +-218, -117, -446, -208, -555, -183, -519, -68, +-347, 86, -94, 213, 156, 261, 312, 198, +333, 59, 230, -104, 37, -235, -186, -288, +-359, -231, -425, -74, -376, 132, -233, 315, +-28, 415, 185, 411, 329, 304, 360, 124, +276, -88, 96, -267, -144, -373, -371, -386, +-513, -317, -533, -179, -428, -4, -219, 169, +45, 315, 294, 410, 450, 445, 456, 405, +318, 304, 88, 163, -169, 5, -397, -152, +-533, -272, -535, -325, -418, -315, -231, -259, +-19, -174, 172, -67, 291, 31, 308, 104, +243, 156, 138, 198, 17, 230, -101, 256, +-188, 270, -227, 263, -244, 224, -256, 147, +-243, 38, -189, -85, -118, -192, -58, -259, +6, -265, 72, -208, 113, -100, 104, 24, +66, 128, 25, 184, -17, 182, -69, 127, +-118, 35, -136, -52, -133, -103, -137, -95, +-150, -18, -140, 109, -98, 238, -55, 326, +-39, 350, -23, 297, 5, 156, 5, -33, +-32, -208, -66, -327, -65, -360, -51, -303, +-42, -169, -17, -4, 24, 146, 33, 240, +-12, 261, -95, 211, -179, 127, -245, 46, +-275, -7, -234, -20, -110, 1, 47, 50, +164, 91, 210, 103, 189, 72, 103, 14, +-40, -41, -189, -63, -276, -44, -275, 10, +-209, 88, -108, 162, 7, 191, 84, 145, +75, 30, -15, -132, -125, -284, -209, -374, +-243, -359, -208, -226, -91, 8, 66, 291, +199, 540, 269, 678, 261, 658, 166, 495, +-11, 226, -219, -84, -390, -354, -483, -513, +-480, -541, -372, -453, -189, -298, 25, -129, +226, 6, 370, 91, 422, 147, 361, 194, +191, 254, -48, 334, -287, 422, -471, 476, +-550, 451, -502, 318, -326, 92, -70, -180, +179, -429, 354, -594, 421, -632, 360, -521, +166, -292, -100, -4, -343, 268, -472, 473, +-461, 567, -330, 543, -121, 425, 92, 251, +229, 54, 244, -123, 146, -239, -24, -284, +-202, -265, -320, -197, -319, -90, -197, 26, +-3, 118, 186, 165, 302, 166, 301, 134, +179, 93, -31, 61, -260, 50, -424, 59, +-481, 75, -426, 79, -280, 48, -77, -19, +105, -106, 207, -177, 213, -204, 157, -166, +70, -67, -16, 75, -61, 227, -51, 345, +-11, 392, 20, 362, 22, 276, -26, 151, +-116, 1, -234, -152, -341, -279, -396, -375, +-369, -434, -255, -438, -81, -360, 101, -191, +247, 52, 335, 337, 344, 604, 275, 787, +144, 814, -7, 666, -149, 362, -256, -34, +-318, -431, -329, -728, -304, -853, -250, -782, +-174, -541, -97, -195, -28, 176, 34, 483, +87, 666, 112, 696, 110, 594, 96, 394, +81, 155, 58, -68, 29, -228, -10, -313, +-71, -330, -140, -287, -205, -203, -266, -105, +-314, -18, -314, 61, -245, 125, -116, 169, +38, 192, 186, 206, 296, 208, 329, 185, +256, 139, 94, 73, -104, -11, -282, -102, +-399, -170, -429, -199, -353, -175, -193, -103, +-10, 6, 143, 121, 232, 216, 236, 265, +156, 238, 22, 145, -116, 22, -204, -96, +-227, -185, -191, -207, -113, -145, -18, -16, +44, 128, 47, 244, 1, 294, -69, 255, +-157, 131, -242, -41, -263, -204, -192, -304, +-57, -292, 91, -163, 229, 41, 323, 252, +331, 415, 229, 473, 46, 390, -165, 176, +-368, -97, -529, -342, -609, -493, -560, -500, +-380, -360, -125, -112, 139, 176, 379, 427, +544, 565, 584, 556, 477, 411, 264, 181, +-5, -73, -288, -286, -521, -406, -631, -409, +-593, -299, -443, -114, -218, 93, 28, 264, +234, 364, 342, 371, 328, 279, 217, 109, +59, -90, -108, -265, -240, -363, -288, -350, +-243, -226, -128, -18, 1, 214, 109, 420, +173, 528, 176, 492, 102, 317, -28, 65, +-163, -197, -262, -401, -312, -480, -310, -406, +-243, -201, -130, 52, -17, 274, 69, 393, +136, 379, 178, 240, 177, 35, 124, -166, +45, -286, -35, -276, -108, -144, -169, 56, +-207, 250, -208, 370, -183, 364, -140, 238, +-87, 37, -14, -165, 57, -300, 90, -309, +75, -184, 36, 18, -10, 224, -63, 361, +-119, 374, -157, 240, -159, -1, -142, -273, +-109, -479, -63, -550, -11, -443, 25, -174, +46, 178, 68, 519, 91, 762, 99, 839, +75, 710, 26, 402, -47, -4, -144, -400, +-251, -700, -331, -835, -358, -775, -312, -533, +-214, -181, -83, 182, 76, 470, 234, 630, +341, 642, 359, 519, 307, 315, 202, 101, +55, -65, -122, -162, -277, -183, -382, -152, +-439, -120, -446, -124, -393, -163, -271, -208, +-99, -227, 85, -190, 252, -76, 380, 115, +430, 336, 377, 516, 224, 589, 17, 527, +-196, 325, -376, 24, -480, -294, -471, -540, +-355, -647, -178, -583, 13, -365, 167, -51, +259, 273, 260, 515, 182, 619, 67, 563, +-42, 372, -132, 101, -192, -172, -204, -364, +-175, -430, -128, -367, -91, -205, -53, 6, +-13, 201, 18, 322, 35, 338, 44, 265, +46, 125, 36, -32, 10, -154, -30, -211, +-74, -193, -114, -108, -146, 17, -162, 136, +-155, 213, -128, 228, -88, 183, -46, 86, +-3, -30, 37, -141, 68, -217, 90, -233, +98, -179, 83, -66, 38, 76, -22, 222, +-80, 343, -128, 407, -167, 378, -185, 261, +-182, 75, -170, -139, -155, -338, -133, -472, +-95, -505, -34, -430, 43, -247, 130, 9, +217, 279, 278, 496, 271, 614, 182, 603, +25, 464, -179, 224, -379, -60, -511, -319, +-517, -483, -388, -514, -166, -411, 88, -212, +315, 28, 449, 244, 431, 363, 262, 356, +5, 240, -248, 66, -428, -108, -485, -220, +-384, -232, -158, -139, 90, 29, 276, 211, +362, 345, 329, 380, 184, 302, -37, 139, +-250, -60, -381, -245, -397, -363, -309, -382, +-150, -304, 28, -160, 161, 4, 193, 151, +127, 250, 23, 291, -79, 274, -153, 216, +-173, 142, -114, 71, 14, 5, 149, -53, +222, -93, 213, -113, 121, -114, -47, -95, +-245, -53, -401, 2, -456, 53, -403, 93, +-255, 113, -38, 94, 197, 44, 363, -14, +403, -55, 323, -69, 151, -56, -65, -22, +-264, 26, -387, 72, -391, 94, -277, 89, +-94, 69, 103, 55, 259, 58, 331, 77, +290, 107, 141, 129, -66, 115, -273, 45, +-438, -72, -516, -205, -467, -318, -301, -366, +-63, -313, 184, -159, 389, 61, 507, 288, +507, 468, 381, 544, 164, 486, -88, 304, +-323, 55, -494, -186, -564, -365, -510, -432, +-360, -375, -158, -218, 59, -13, 250, 181, +367, 305, 388, 329, 315, 254, 175, 108, +5, -62, -171, -213, -307, -300, -363, -298, +-338, -200, -246, -35, -95, 150, 78, 309, +216, 404, 264, 417, 212, 337, 98, 176, +-45, -22, -181, -206, -259, -336, -243, -388, +-151, -360, -20, -256, 95, -111, 156, 45, +138, 178, 41, 262, -104, 291, -244, 277, +-316, 229, -293, 158, -184, 77, -7, -7, +197, -79, 347, -131, 393, -159, 337, -164, +200, -140, 3, -87, -212, -17, -395, 49, +-495, 97, -497, 123, -424, 126, -284, 111, +-99, 80, 105, 49, 286, 26, 410, 15, +461, 12, 433, 3, 305, -21, 101, -56, +-117, -85, -302, -96, -417, -80, -453, -32, +-411, 48, -300, 137, -142, 204, 4, 217, +114, 166, 178, 56, 192, -79, 161, -205, +101, -283, 55, -273, 36, -167, 19, 8, +-12, 192, -41, 334, -75, 388, -114, 334, +-148, 185, -161, -6, -144, -175, -107, -271, +-68, -269, -23, -179, 11, -47, 23, 64, +17, 111, -7, 81, -18, -12, -14, -127, +-4, -190, 11, -155, 39, -14, 71, 198, +86, 416, 75, 561, 31, 570, -37, 420, +-130, 130, -228, -224, -294, -549, -305, -756, +-250, -791, -132, -636, 21, -333, 188, 38, +320, 391, 369, 661, 320, 787, 179, 739, +-18, 544, -220, 261, -364, -47, -403, -331, +-324, -526, -168, -590, 13, -520, 171, -347, +249, -119, 217, 112, 94, 299, -67, 396, +-205, 386, -277, 289, -258, 142, -132, -12, +51, -135, 210, -187, 294, -170, 279, -115, +172, -50, -2, 7, -196, 46, -332, 57, +-363, 49, -300, 52, -168, 77, 3, 106, +163, 122, 247, 111, 221, 65, 105, -18, +-32, -125, -144, -218, -202, -262, -181, -233, +-83, -129, 63, 22, 185, 177, 223, 297, +171, 349, 46, 319, -135, 219, -311, 80, +-407, -61, -381, -170, -244, -226, -45, -231, +168, -204, 341, -157, 414, -93, 355, -21, +192, 48, -24, 110, -223, 164, -352, 202, +-384, 211, -305, 179, -154, 114, 4, 32, +125, -42, 186, -84, 171, -87, 90, -57, +-22, -9, -107, 29, -135, 25, -119, -29, +-72, -122, 10, -218, 96, -270, 144, -241, +132, -121, 67, 71, -22, 296, -126, 490, +-219, 583, -263, 536, -241, 360, -170, 95, +-77, -194, 21, -444, 117, -595, 196, -615, +226, -512, 202, -311, 142, -62, 70, 180, +-4, 373, -87, 495, -177, 529, -235, 471, +-265, 339, -267, 160, -224, -39, -134, -224, +-14, -358, 110, -417, 214, -391, 280, -286, +286, -132, 212, 27, 77, 161, -80, 244, +-205, 265, -263, 234, -254, 173, -186, 106, +-72, 45, 37, -2, 100, -37, 105, -66, +47, -97, -52, -124, -143, -133, -177, -118, +-130, -79, -25, -17, 100, 58, 216, 122, +274, 146, 247, 130, 137, 83, -35, 25, +-210, -24, -336, -53, -382, -46, -335, -15, +-204, 21, -35, 42, 120, 36, 219, 4, +242, -40, 202, -78, 117, -91, 16, -64, +-47, -8, -57, 56, -26, 113, 16, 150, +34, 144, 19, 96, -38, 29, -140, -39, +-253, -102, -329, -150, -339, -172, -263, -162, +-98, -120, 108, -50, 312, 40, 457, 143, +509, 241, 454, 308, 287, 319, 45, 256, +-210, 120, -426, -61, -548, -241, -555, -370, +-463, -414, -291, -359, -77, -216, 129, -26, +288, 153, 375, 264, 375, 288, 304, 238, +182, 141, 46, 43, -57, -8, -120, 11, +-141, 80, -134, 152, -117, 179, -93, 129, +-83, -2, -108, -181, -147, -352, -171, -458, +-161, -452, -125, -323, -71, -103, 20, 139, +142, 334, 250, 437, 308, 434, 319, 351, +270, 222, 157, 91, -8, -3, -189, -46, +-324, -57, -397, -72, -410, -118, -348, -193, +-215, -277, -39, -344, 129, -357, 235, -283, +281, -123, 275, 84, 205, 292, 96, 448, +3, 510, -48, 471, -67, 346, -65, 172, +-48, -18, -31, -188, -62, -302, -152, -351, +-244, -347, -285, -307, -259, -234, -171, -129, +-30, -7, 170, 112, 363, 209, 458, 274, +440, 295, 332, 261, 147, 182, -106, 85, +-360, -9, -521, -82, -541, -126, -459, -141, +-313, -135, -109, -121, 118, -108, 306, -92, +400, -67, 403, -29, 365, 34, 280, 123, +131, 208, -30, 256, -167, 245, -276, 168, +-365, 32, -421, -134, -396, -285, -285, -374, +-133, -353, 30, -220, 201, -11, 347, 220, +426, 409, 409, 496, 302, 443, 143, 259, +-48, -8, -249, -285, -385, -493, -420, -560, +-361, -462, -234, -233, -70, 57, 108, 327, +245, 505, 294, 532, 252, 405, 157, 175, +42, -78, -75, -283, -160, -391, -188, -381, +-148, -269, -83, -102, -35, 60, 7, 167, +36, 200, 40, 176, 27, 121, 15, 69, +38, 40, 70, 38, 76, 49, 59, 47, +22, 12, -44, -58, -139, -147, -230, -218, +-265, -233, -212, -180, -91, -67, 57, 83, +205, 233, 305, 329, 317, 331, 240, 239, +90, 77, -75, -108, -218, -271, -309, -360, +-305, -343, -224, -225, -97, -40, 28, 165, +109, 333, 144, 411, 137, 373, 96, 233, +47, 30, 24, -190, 26, -370, 39, -459, +50, -423, 32, -276, -25, -64, -126, 156, +-242, 336, -298, 436, -278, 429, -182, 318, +-10, 146, 189, -34, 370, -184, 469, -279, +439, -312, 292, -284, 56, -213, -222, -111, +-462, 0, -585, 104, -558, 188, -393, 248, +-138, 271, 141, 239, 386, 143, 519, -2, +497, -157, 347, -276, 120, -327, -100, -294, +-264, -169, -338, 24, -302, 225, -191, 367, +-59, 407, 55, 330, 116, 156, 101, -62, +19, -256, -78, -369, -136, -377, -124, -281, +-60, -119, 40, 52, 166, 177, 253, 235, +262, 226, 181, 163, 31, 71, -127, -12, +-265, -56, -334, -61, -293, -38, -168, -5, +-7, 31, 136, 62, 224, 74, 250, 52, +200, 3, 70, -63, -92, -137, -209, -208, +-247, -251, -201, -239, -93, -155, 39, 2, +179, 202, 259, 394, 245, 515, 156, 515, +13, 380, -133, 128, -245, -188, -289, -482, +-246, -661, -134, -662, -1, -489, 113, -192, +183, 151, 199, 440, 164, 599, 88, 588, +-7, 423, -65, 167, -85, -97, -81, -294, +-57, -381, -44, -350, -37, -232, -45, -78, +-73, 60, -89, 145, -69, 161, -4, 118, +90, 51, 176, -3, 230, -34, 219, -42, +120, -24, -45, 12, -211, 46, -327, 57, +-374, 49, -316, 29, -156, 3, 79, -26, +306, -54, 434, -79, 453, -96, 360, -97, +165, -77, -88, -29, -325, 41, -464, 116, +-479, 173, -391, 191, -212, 156, 19, 68, +230, -52, 349, -161, 362, -227, 293, -228, +186, -157, 59, -26, -79, 125, -163, 239, +-176, 277, -147, 227, -101, 105, -63, -58, +-23, -210, -5, -304, -42, -307, -87, -221, +-103, -80, -78, 79, -20, 213, 60, 287, +163, 294, 252, 245, 279, 159, 222, 51, +118, -59, -13, -150, -158, -211, -276, -244, +-333, -254, -299, -233, -200, -164, -86, -55, +43, 68, 157, 182, 217, 274, 215, 321, +161, 302, 98, 216, 37, 84, -22, -65, +-58, -200, -54, -290, -32, -317, -29, -277, +-37, -174, -51, -33, -60, 109, -70, 219, +-90, 274, -80, 265, -39, 192, 5, 76, +45, -55, 78, -166, 115, -227, 137, -218, +110, -152, 56, -54, -1, 52, -56, 138, +-117, 176, -157, 157, -150, 93, -98, 8, +-30, -67, 35, -115, 109, -126, 170, -104, +176, -60, 130, 4, 42, 76, -59, 134, +-155, 161, -238, 157, -255, 118, -196, 44, +-82, -64, 60, -180, 202, -265, 304, -290, +324, -241, 254, -129, 117, 31, -39, 203, +-194, 326, -317, 354, -352, 286, -299, 148, +-178, -18, -20, -156, 127, -221, 248, -199, +307, -113, 282, -1, 208, 89, 97, 113, +-29, 57, -152, -54, -245, -166, -285, -231, +-272, -224, -218, -138, -133, 7, 1, 168, +158, 293, 292, 347, 368, 322, 363, 233, +291, 116, 141, -6, -75, -110, -277, -186, +-423, -234, -475, -262, -420, -273, -270, -259, +-41, -218, 194, -139, 367, -21, 450, 122, +439, 263, 324, 372, 128, 424, -86, 407, +-259, 309, -342, 143, -333, -50, -250, -233, +-102, -376, 41, -454, 135, -447, 175, -357, +154, -203, 92, -16, -1, 168, -82, 311, +-104, 386, -68, 385, 3, 311, 74, 184, +122, 35, 128, -105, 89, -206, 13, -253, +-76, -252, -135, -208, -155, -134, -124, -46, +-33, 37, 62, 98, 128, 135, 134, 148, +82, 132, 12, 85, -73, 19, -139, -44, +-156, -86, -124, -97, -53, -70, 38, -15, +123, 50, 175, 103, 180, 126, 141, 105, +80, 40, 25, -53, -33, -140, -84, -184, +-115, -178, -129, -130, -121, -54, -123, 37, +-123, 112, -101, 148, -63, 151, -10, 138, +55, 120, 130, 95, 202, 62, 246, 23, +248, -31, 212, -110, 141, -196, 22, -262, +-121, -280, -239, -227, -316, -97, -330, 82, +-289, 260, -192, 386, -43, 413, 100, 328, +210, 148, 260, -78, 248, -285, 194, -402, +111, -395, 39, -276, 5, -91, -4, 101, +-11, 243, -25, 296, -48, 251, -94, 131, +-151, -5, -203, -110, -209, -153, -143, -133, +-43, -68, 78, 5, 189, 59, 251, 75, +252, 46, 183, -14, 75, -70, -36, -92, +-126, -72, -167, -24, -150, 31, -85, 81, +-2, 114, 60, 116, 82, 84, 65, 28, +37, -27, -2, -72, -36, -108, -52, -130, +-55, -129, -34, -104, -21, -53, -13, 17, +2, 97, 18, 171, 39, 220, 57, 224, +65, 168, 66, 55, 48, -88, 15, -212, +-26, -281, -60, -278, -78, -202, -73, -66, +-44, 94, -6, 227, 41, 288, 74, 258, +78, 152, 63, 12, 17, -123, -33, -219, +-77, -250, -113, -208, -112, -113, -74, 1, +-5, 104, 79, 177, 154, 213, 212, 212, +227, 177, 180, 112, 74, 24, -62, -69, +-205, -157, -330, -232, -384, -272, -346, -257, +-200, -183, 18, -70, 244, 56, 440, 165, +536, 232, 493, 240, 322, 198, 64, 127, +-201, 50, -415, -1, -540, -11, -536, 6, +-396, 25, -162, 12, 87, -39, 299, -120, +430, -207, 462, -276, 389, -298, 227, -246, +52, -126, -99, 28, -206, 173, -248, 282, +-232, 344, -164, 358, -95, 327, -60, 264, +-38, 174, -14, 61, 10, -79, 34, -240, +71, -402, 132, -525, 193, -563, 220, -488, +191, -293, 128, -10, 24, 301, -112, 561, +-224, 701, -281, 679, -254, 497, -153, 203, +-21, -116, 126, -373, 239, -519, 272, -534, +216, -431, 89, -250, -54, -56, -174, 93, +-240, 180, -235, 216, -150, 212, -14, 188, +126, 165, 240, 146, 291, 124, 269, 85, +177, 25, 34, -59, -106, -161, -217, -256, +-279, -319, -271, -326, -203, -266, -83, -144, +49, 32, 155, 231, 228, 403, 253, 505, +225, 507, 148, 400, 52, 185, -50, -98, +-139, -380, -193, -585, -203, -659, -161, -578, +-94, -352, -26, -42, 51, 267, 114, 498, +159, 601, 183, 554, 168, 381, 133, 142, +77, -88, 11, -251, -61, -323, -132, -312, +-189, -241, -217, -145, -197, -66, -138, -22, +-46, -7, 55, 7, 150, 37, 233, 86, +269, 144, 249, 196, 190, 216, 86, 190, +-31, 115, -141, 2, -215, -119, -226, -216, +-193, -260, -127, -239, -40, -165, 56, -62, +129, 52, 153, 149, 135, 201, 101, 197, +68, 147, 22, 71, -26, -12, -45, -90, +-48, -145, -38, -157, -31, -127, -24, -64, +7, 7, 30, 73, 46, 124, 67, 149, +87, 140, 94, 99, 56, 33, -7, -43, +-63, -112, -103, -162, -140, -180, -161, -166, +-132, -117, -59, -36, 29, 60, 111, 145, +177, 206, 232, 234, 245, 219, 211, 155, +150, 52, 63, -65, -46, -168, -179, -237, +-295, -265, -349, -244, -328, -177, -242, -77, +-100, 35, 94, 138, 291, 216, 429, 259, +468, 260, 403, 221, 260, 147, 53, 40, +-173, -84, -343, -194, -433, -271, -421, -304, +-328, -282, -180, -195, 11, -66, 193, 72, +324, 190, 393, 261, 409, 275, 363, 237, +244, 151, 75, 45, -107, -53, -269, -123, +-388, -156, -440, -156, -391, -132, -254, -101, +-58, -74, 150, -52, 318, -33, 419, -11, +415, 21, 310, 71, 149, 135, -19, 190, +-150, 213, -228, 194, -235, 136, -174, 36, +-74, -97, 27, -227, 96, -319, 121, -347, +94, -299, 33, -187, -27, -33, -75, 135, +-81, 287, -56, 390, -4, 414, 65, 355, +117, 229, 146, 57, 135, -137, 89, -318, +25, -447, -42, -496, -87, -449, -97, -311, +-69, -103, -11, 143, 56, 386, 107, 568, +117, 635, 82, 568, 7, 373, -86, 80, +-157, -250, -192, -543, -158, -727, -63, -752, +54, -610, 176, -334, 265, 15, 302, 358, +273, 614, 182, 737, 62, 708, -63, 537, +-171, 272, -249, -22, -278, -284, -247, -476, +-173, -580, -69, -589, 44, -510, 161, -362, +260, -176, 301, 24, 287, 225, 220, 402, +113, 524, -16, 569, -150, 522, -242, 389, +-271, 184, -241, -61, -154, -298, -26, -481, +114, -574, 219, -554, 272, -431, 269, -240, +217, -25, 129, 170, 13, 313, -86, 384, +-152, 378, -185, 308, -184, 204, -160, 95, +-107, 1, -41, -70, 19, -123, 72, -151, +111, -157, 137, -155, 157, -149, 172, -136, +186, -110, 189, -72, 167, -20, 103, 37, +12, 89, -100, 131, -221, 160, -312, 170, +-357, 153, -322, 114, -208, 63, -48, 10, +131, -50, 281, -118, 372, -182, 392, -227, +330, -239, 216, -209, 80, -131, -34, -7, +-92, 145, -96, 293, -69, 398, -49, 423, +-52, 346, -103, 173, -189, -65, -276, -322, +-322, -535, -281, -642, -155, -600, 49, -409, +306, -116, 545, 219, 700, 525, 704, 733, +549, 785, 273, 658, -84, 387, -447, 35, +-730, -325, -847, -619, -767, -778, -514, -765, +-146, -590, 250, -296, 589, 43, 774, 348, +770, 551, 599, 608, 302, 519, -34, 324, +-321, 83, -488, -134, -490, -266, -361, -286, +-161, -206, 50, -80, 206, 39, 266, 106, +211, 94, 85, 1, -49, -135, -132, -246, +-133, -282, -51, -219, 95, -69, 234, 125, +305, 305, 284, 409, 169, 401, -5, 281, +-200, 84, -350, -134, -390, -302, -320, -372, +-157, -335, 44, -214, 237, -51, 379, 102, +428, 200, 378, 217, 248, 166, 88, 79, +-73, -12, -199, -77, -264, -103, -270, -89, +-226, -50, -163, -10, -96, 6, -10, -4, +77, -26, 158, -38, 230, -19, 281, 34, +301, 114, 269, 183, 190, 208, 70, 164, +-74, 41, -221, -140, -330, -319, -363, -437, +-313, -443, -187, -316, -12, -73, 180, 231, +349, 508, 440, 669, 424, 653, 308, 458, +115, 130, -99, -249, -287, -580, -396, -767, +-395, -759, -287, -560, -98, -230, 120, 142, +318, 465, 439, 659, 445, 691, 342, 564, +157, 323, -55, 34, -248, -233, -377, -419, +-397, -497, -314, -471, -153, -360, 36, -192, +204, -8, 323, 156, 355, 272, 306, 326, +205, 315, 83, 250, -33, 143, -122, 13, +-158, -116, -142, -220, -93, -277, -42, -279, +-1, -225, 30, -130, 38, -7, 31, 120, +26, 225, 31, 285, 56, 285, 79, 225, +101, 117, 119, -22, 114, -163, 83, -270, +23, -321, -33, -311, -71, -246, -92, -133, +-94, 2, -69, 132, -18, 234, 32, 296, +71, 305, 102, 268, 119, 196, 119, 94, +95, -24, 56, -147, 26, -262, 0, -345, +-19, -375, -39, -342, -49, -242, -43, -81, +-36, 116, -27, 301, -8, 420, 22, 447, +55, 375, 85, 215, 118, 1, 145, -206, +152, -342, 132, -380, 85, -321, 24, -183, +-58, -18, -134, 119, -183, 191, -198, 184, +-154, 105, -63, -10, 56, -106, 174, -150, +258, -122, 291, -33, 262, 88, 174, 201, +44, 270, -96, 264, -201, 175, -245, 21, +-219, -154, -130, -301, 5, -387, 151, -384, +260, -287, 312, -115, 279, 79, 167, 247, +9, 347, -162, 358, -289, 280, -337, 140, +-287, -17, -144, -148, 57, -214, 266, -202, +423, -127, 482, -30, 426, 50, 258, 81, +22, 53, -218, -21, -389, -108, -454, -164, +-403, -160, -245, -83, -29, 39, 193, 169, +349, 264, 395, 290, 347, 224, 239, 83, +105, -85, -25, -232, -122, -317, -157, -316, +-139, -230, -93, -86, -40, 71, 8, 199, +44, 273, 57, 279, 56, 219, 52, 112, +58, -12, 66, -125, 64, -210, 59, -260, +46, -264, 24, -219, -1, -138, -22, -35, +-22, 76, 2, 184, 42, 270, 88, 316, +120, 308, 119, 247, 80, 133, 21, -22, +-48, -189, -116, -333, -162, -426, -164, -446, +-98, -375, 12, -222, 136, -16, 247, 199, +314, 379, 315, 485, 239, 484, 101, 369, +-59, 174, -200, -50, -286, -246, -292, -369, +-221, -389, -88, -311, 62, -167, 190, -9, +262, 110, 272, 163, 223, 144, 128, 70, +22, -19, -71, -84, -115, -95, -103, -51, +-51, 34, 21, 125, 88, 187, 133, 188, +144, 131, 105, 36, 33, -69, -55, -161, +-128, -211, -166, -204, -158, -153, -99, -81, +4, -14, 133, 40, 250, 71, 326, 82, +332, 83, 258, 84, 118, 86, -62, 82, +-229, 60, -326, 19, -333, -34, -248, -91, +-89, -136, 106, -148, 292, -111, 399, -37, +399, 54, 294, 133, 124, 172, -70, 146, +-240, 62, -338, -51, -336, -159, -233, -226, +-64, -227, 124, -153, 293, -27, 398, 112, +404, 220, 316, 265, 163, 229, -7, 127, +-162, -9, -269, -136, -301, -219, -255, -237, +-152, -188, -33, -93, 85, 13, 180, 94, +242, 130, 256, 125, 231, 92, 190, 40, +128, -10, 49, -42, -34, -54, -107, -57, +-157, -62, -185, -59, -181, -48, -119, -24, +-14, 11, 108, 58, 215, 99, 287, 119, +295, 104, 219, 45, 85, -45, -61, -139, +-174, -198, -235, -194, -226, -121, -134, -5, +12, 122, 157, 216, 248, 238, 261, 175, +207, 43, 98, -115, -28, -238, -124, -282, +-153, -230, -103, -91, -9, 89, 101, 245, +194, 314, 234, 274, 195, 135, 89, -60, +-44, -245, -164, -357, -232, -360, -227, -249, +-157, -58, -30, 149, 117, 306, 243, 367, +317, 322, 316, 183, 251, 3, 139, -167, +18, -281, -81, -310, -148, -246, -172, -121, +-145, 21, -83, 139, -20, 203, 33, 201, +66, 135, 83, 28, 88, -89, 86, -176, +83, -213, 84, -188, 79, -109, 66, 3, +44, 120, 19, 212, 6, 254, 4, 231, +20, 153, 50, 43, 90, -74, 120, -172, +116, -230, 65, -240, -25, -205, -124, -147, +-198, -88, -223, -31, -186, 20, -78, 68, +91, 114, 274, 164, 401, 211, 442, 239, +377, 225, 221, 159, 8, 43, -207, -101, +-354, -238, -398, -328, -329, -341, -170, -273, +41, -143, 244, 13, 379, 155, 405, 236, +331, 232, 187, 158, 14, 58, -149, -31, +-257, -84, -291, -82, -244, -35, -131, 31, +3, 74, 134, 68, 235, 12, 295, -68, +311, -142, 286, -178, 226, -156, 140, -75, +35, 40, -77, 149, -179, 211, -255, 204, +-297, 133, -294, 14, -234, -115, -118, -214, +35, -255, 193, -225, 333, -130, 430, -4, +469, 113, 442, 195, 343, 224, 184, 196, +-12, 117, -214, 10, -382, -96, -478, -171, +-485, -194, -398, -156, -227, -72, 7, 32, +257, 124, 465, 174, 578, 159, 575, 76, +461, -53, 258, -186, 16, -271, -210, -280, +-359, -204, -403, -55, -349, 131, -221, 293, +-54, 375, 102, 350, 208, 229, 251, 45, +245, -147, 207, -288, 149, -340, 95, -294, +51, -174, 24, -24, 0, 97, -26, 155, +-57, 136, -92, 61, -116, -28, -120, -88, +-87, -91, -19, -31, 75, 73, 177, 179, +262, 246, 299, 238, 272, 147, 179, -11, +44, -193, -103, -353, -222, -440, -275, -421, +-243, -295, -137, -86, 15, 153, 180, 368, +307, 501, 355, 520, 299, 418, 159, 215, +-11, -45, -161, -295, -248, -477, -245, -542, +-154, -479, -7, -312, 146, -84, 259, 142, +305, 315, 273, 392, 177, 365, 57, 255, +-39, 108, -97, -39, -115, -147, -102, -193, +-81, -181, -59, -133, -47, -80, -39, -34, +-15, -8, 34, 3, 106, 7, 191, 20, +268, 44, 310, 70, 287, 87, 193, 80, +55, 42, -95, -22, -223, -97, -298, -156, +-294, -176, -211, -153, -72, -82, 75, 23, +202, 132, 289, 212, 310, 246, 262, 226, +167, 156, 56, 49, -41, -79, -112, -196, +-145, -278, -128, -308, -70, -289, 12, -223, +90, -117, 146, 10, 172, 142, 163, 258, +129, 332, 82, 347, 36, 298, -7, 192, +-36, 48, -53, -112, -72, -258, -94, -358, +-112, -388, -108, -347, -64, -247, 13, -105, +119, 57, 243, 204, 346, 305, 394, 346, +362, 320, 255, 244, 87, 133, -108, 3, +-285, -125, -386, -227, -386, -288, -298, -301, +-154, -270, 10, -207, 156, -116, 255, -7, +288, 103, 266, 191, 222, 248, 175, 270, +144, 259, 123, 210, 105, 124, 82, 14, +42, -104, -18, -209, -95, -283, -173, -315, +-232, -296, -248, -225, -214, -114, -132, 19, +-10, 141, 126, 230, 247, 272, 326, 257, +347, 194, 316, 102, 240, 4, 135, -72, +31, -113, -54, -124, -103, -113, -116, -92, +-107, -75, -91, -78, -83, -97, -80, -117, +-71, -114, -51, -71, -19, 12, 35, 118, +116, 214, 201, 273, 257, 264, 263, 173, +212, 23, 120, -141, 5, -269, -93, -320, +-136, -271, -115, -131, -49, 59, 31, 231, +99, 322, 129, 294, 100, 153, 14, -64, +-85, -282, -145, -427, -139, -445, -64, -324, +59, -87, 187, 200, 281, 448, 304, 577, +245, 547, 122, 369, -32, 91, -162, -212, +-225, -460, -197, -583, -90, -557, 54, -395, +189, -155, 273, 95, 275, 295, 187, 407, +39, 408, -117, 306, -232, 146, -267, -25, +-205, -164, -62, -240, 115, -241, 268, -188, +361, -100, 368, -2, 278, 76, 120, 113, +-63, 110, -211, 84, -277, 44, -250, 4, +-135, -26, 26, -42, 176, -46, 267, -44, +271, -45, 196, -57, 73, -76, -58, -86, +-157, -72, -186, -31, -137, 30, -36, 96, +81, 153, 169, 180, 208, 166, 198, 100, +149, 4, 88, -88, 34, -153, 1, -178, +-2, -157, 12, -99, 13, -28, -14, 27, +-68, 43, -129, 22, -170, -25, -164, -73, +-99, -94, 34, -67, 203, 7, 362, 114, +462, 226, 464, 300, 364, 305, 166, 219, +-89, 53, -329, -157, -491, -357, -535, -496, +-450, -534, -247, -447, 33, -242, 323, 38, +544, 324, 635, 544, 575, 640, 388, 584, +120, 382, -159, 85, -379, -233, -481, -487, +-442, -614, -276, -583, -40, -407, 186, -143, +347, 130, 410, 334, 358, 419, 215, 371, +31, 224, -130, 39, -212, -115, -207, -192, +-127, -171, -2, -69, 131, 66, 219, 172, +229, 195, 171, 115, 80, -49, -10, -239, +-85, -388, -123, -434, -110, -352, -61, -150, +4, 118, 66, 376, 109, 542, 132, 561, +138, 423, 133, 169, 124, -132, 110, -400, +83, -556, 43, -554, -2, -398, -56, -144, +-111, 131, -148, 345, -151, 444, -114, 407, +-49, 253, 44, 38, 153, -166, 252, -296, +316, -321, 321, -247, 272, -111, 180, 36, +48, 143, -105, 182, -246, 148, -334, 61, +-346, -35, -284, -96, -159, -102, 15, -58, +208, 18, 367, 97, 453, 145, 446, 136, +349, 69, 185, -37, -9, -144, -187, -221, +-297, -249, -319, -218, -259, -131, -142, -5, +-1, 127, 134, 227, 224, 273, 245, 261, +199, 194, 115, 84, 25, -46, -46, -162, +-86, -236, -84, -253, -38, -214, 31, -133, +101, -33, 156, 61, 179, 135, 165, 166, +123, 149, 61, 94, -1, 31, -63, -22, +-118, -54, -155, -62, -162, -52, -140, -36, +-94, -29, -26, -34, 61, -59, 171, -92, +279, -111, 362, -95, 397, -44, 365, 40, +252, 134, 78, 208, -123, 239, -311, 206, +-449, 107, -494, -33, -418, -170, -235, -271, +12, -309, 258, -269, 447, -156, 537, -5, +512, 140, 380, 233, 187, 252, -12, 198, +-175, 89, -266, -38, -276, -141, -219, -190, +-130, -173, -47, -97, 9, 6, 47, 99, +68, 148, 86, 148, 115, 99, 158, 20, +212, -65, 250, -130, 244, -149, 176, -121, +54, -66, -97, -8, -233, 37, -321, 58, +-328, 51, -248, 19, -95, -18, 100, -46, +286, -49, 420, -26, 465, 9, 413, 54, +262, 93, 52, 115, -162, 108, -330, 72, +-418, 11, -404, -56, -288, -113, -91, -150, +139, -162, 341, -144, 464, -97, 481, -32, +384, 33, 194, 75, -45, 94, -271, 89, +-420, 65, -447, 31, -340, 6, -126, -5, +136, 5, 379, 34, 540, 66, 573, 82, +459, 70, 225, 29, -68, -39, -342, -123, +-532, -207, -590, -262, -498, -264, -277, -204, +12, -91, 292, 55, 505, 209, 612, 327, +593, 378, 448, 341, 229, 222, 0, 48, +-188, -132, -310, -276, -361, -351, -341, -338, +-268, -242, -172, -96, -76, 46, 14, 147, +95, 180, 168, 150, 234, 77, 289, -2, +319, -58, 315, -68, 262, -30, 160, 36, +21, 91, -120, 106, -230, 79, -284, 22, +-266, -45, -193, -96, -82, -114, 37, -102, +130, -69, 166, -40, 152, -36, 117, -62, +86, -97, 73, -110, 85, -79, 121, 12, +155, 148, 157, 288, 108, 377, 15, 370, +-105, 245, -211, 25, -265, -230, -244, -445, +-140, -550, 20, -514, 192, -343, 327, -81, +380, 191, 332, 390, 199, 462, 15, 403, +-165, 248, -288, 51, -321, -118, -257, -211, +-120, -213, 45, -145, 195, -50, 293, 27, +319, 50, 268, 22, 154, -42, 23, -106, +-80, -139, -139, -115, -147, -39, -106, 71, +-37, 174, 33, 229, 75, 211, 78, 127, +52, 3, 10, -130, -29, -231, -48, -270, +-30, -227, 16, -119, 74, 21, 124, 148, +153, 236, 155, 258, 127, 208, 79, 107, +24, -19, -22, -135, -43, -214, -45, -230, +-41, -190, -36, -114, -44, -24, -63, 57, +-82, 105, -86, 115, -65, 89, -13, 46, +70, 11, 165, -9, 251, -5, 302, 20, +301, 51, 240, 71, 127, 64, -12, 19, +-144, -54, -248, -132, -303, -185, -301, -197, +-238, -157, -127, -75, 6, 30, 141, 133, +248, 198, 314, 207, 326, 159, 285, 76, +195, -17, 74, -91, -55, -127, -161, -123, +-219, -88, -227, -39, -186, 7, -101, 29, +10, 29, 119, 21, 204, 19, 246, 24, +237, 40, 170, 53, 64, 48, -54, 12, +-160, -54, -233, -135, -254, -201, -206, -212, +-89, -157, 75, -34, 235, 129, 352, 287, +400, 386, 360, 387, 233, 278, 48, 84, +-153, -141, -315, -338, -400, -451, -388, -457, +-276, -354, -101, -175, 95, 33, 258, 208, +356, 316, 369, 341, 305, 291, 190, 192, +54, 77, -74, -25, -167, -98, -206, -132, +-195, -134, -148, -111, -79, -86, 9, -65, +100, -50, 174, -39, 208, -34, 199, -26, +153, -5, 74, 26, -21, 62, -115, 95, +-185, 112, -206, 102, -171, 65, -89, 1, +30, -69, 153, -124, 248, -140, 293, -108, +279, -32, 204, 63, 85, 140, -46, 170, +-160, 134, -233, 40, -256, -90, -218, -204, +-132, -258, -21, -226, 89, -114, 178, 48, +232, 206, 241, 304, 203, 305, 131, 202, +55, 25, -7, -169, -51, -315, -76, -368, +-79, -309, -69, -157, -60, 45, -62, 227, +-59, 340, -41, 354, -9, 271, 43, 119, +109, -56, 175, -200, 217, -285, 217, -298, +169, -247, 80, -149, -34, -38, -147, 58, +-231, 119, -257, 144, -213, 139, -109, 111, +31, 75, 171, 43, 273, 30, 307, 31, +273, 41, 179, 43, 53, 28, -77, -15, +-178, -84, -226, -169, -212, -246, -148, -280, +-59, -251, 40, -155, 125, -8, 173, 167, +175, 325, 146, 424, 95, 430, 42, 340, +-1, 166, -27, -46, -36, -248, -39, -394, +-39, -450, -45, -411, -49, -287, -45, -121, +-26, 50, 12, 187, 63, 269, 120, 291, +167, 260, 180, 194, 147, 113, 69, 32, +-34, -40, -135, -98, -207, -143, -224, -169, +-173, -173, -61, -155, 82, -117, 218, -57, +304, 12, 314, 74, 242, 114, 106, 121, +-56, 98, -198, 55, -283, 9, -291, -31, +-221, -41, -91, -27, 68, 2, 206, 28, +291, 40, 297, 25, 230, -11, 112, -58, +-22, -95, -129, -99, -182, -69, -173, -7, +-117, 58, -35, 105, 48, 106, 102, 58, +117, -29, 97, -123, 55, -188, 14, -192, +-17, -123, -29, 7, -17, 160, 6, 286, +37, 343, 57, 301, 59, 171, 40, -17, +10, -208, -21, -348, -40, -397, -45, -341, +-42, -196, -32, -8, -13, 165, 7, 280, +28, 305, 56, 243, 82, 114, 104, -31, +112, -152, 101, -205, 67, -181, 19, -91, +-36, 30, -91, 140, -132, 206, -147, 195, +-127, 115, -78, -11, -12, -139, 63, -231, +135, -252, 190, -197, 209, -81, 182, 57, +123, 169, 47, 219, -37, 190, -115, 97, +-171, -26, -186, -128, -162, -174, -105, -144, +-28, -55, 56, 67, 127, 174, 172, 222, +181, 187, 156, 83, 109, -53, 46, -184, +-16, -262, -60, -267, -82, -193, -86, -71, +-78, 65, -68, 169, -51, 217, -26, 200, +9, 132, 49, 37, 87, -52, 115, -109, +126, -126, 119, -100, 89, -51, 39, 11, +-26, 58, -88, 82, -133, 71, -147, 34, +-126, -17, -70, -65, 11, -95, 99, -96, +167, -59, 196, -3, 191, 61, 142, 107, +57, 129, -49, 102, -141, 32, -197, -64, +-209, -151, -167, -202, -77, -194, 37, -121, +147, -2, 225, 135, 248, 247, 215, 301, +138, 276, 34, 184, -74, 42, -156, -116, +-199, -255, -197, -341, -154, -357, -85, -303, +-10, -191, 62, -49, 129, 101, 176, 232, +201, 328, 202, 366, 176, 350, 114, 275, +21, 152, -86, -5, -187, -175, -256, -325, +-272, -422, -230, -438, -130, -366, 15, -215, +165, -19, 283, 186, 336, 348, 313, 433, +218, 417, 74, 308, -83, 137, -217, -50, +-288, -212, -279, -310, -211, -315, -102, -241, +30, -115, 147, 17, 224, 116, 250, 149, +224, 122, 152, 49, 58, -37, -38, -100, +-114, -118, -150, -77, -149, 7, -126, 108, +-87, 182, -33, 205, 23, 164, 65, 79, +91, -39, 104, -152, 100, -228, 86, -245, +64, -201, 40, -115, 21, -12, 3, 80, +-20, 153, -49, 185, -68, 178, -77, 131, +-72, 70, -52, 10, -26, -41, 2, -81, +28, -105, 50, -109, 63, -97, 67, -72, +62, -49, 54, -22, 42, 5, 29, 35, +16, 60, 8, 85, 4, 106, -4, 123, +-24, 119, -48, 82, -58, 13, -61, -84, +-54, -178, -38, -245, -11, -251, 21, -192, +52, -68, 72, 86, 79, 237, 74, 330, +58, 329, 33, 230, 7, 60, -8, -125, +-19, -278, -25, -343, -26, -304, -20, -168, +-13, 9, -3, 171, 4, 261, 1, 260, +-3, 178, -8, 47, -9, -85, -2, -175, +11, -188, 20, -136, 24, -43, 23, 43, +14, 97, 0, 97, -4, 50, 5, -20, +19, -76, 30, -87, 44, -47, 56, 32, +56, 116, 45, 174, 16, 175, -29, 120, +-71, 7, -101, -125, -114, -239, -99, -300, +-59, -283, -13, -189, 26, -44, 54, 112, +75, 243, 96, 308, 126, 304, 150, 227, +159, 106, 148, -26, 107, -131, 24, -194, +-85, -210, -197, -181, -294, -124, -346, -59, +-321, -10, -220, 20, -57, 31, 141, 42, +319, 60, 427, 94, 440, 124, 355, 146, +193, 137, -2, 91, -182, 12, -309, -90, +-354, -182, -313, -240, -219, -228, -106, -155, +8, -36, 102, 92, 154, 200, 167, 251, +162, 230, 142, 143, 116, 19, 87, -105, +51, -195, 10, -226, -33, -200, -83, -116, +-134, -11, -162, 88, -154, 148, -116, 165, +-50, 139, 40, 85, 128, 21, 185, -38, +198, -78, 155, -91, 71, -75, -30, -52, +-120, -28, -178, -20, -182, -17, -133, -14, +-49, -6, 54, 5, 154, 26, 208, 59, +193, 90, 123, 109, 11, 97, -110, 56, +-196, -11, -220, -79, -185, -139, -102, -165, +6, -152, 106, -96, 179, -11, 209, 79, +184, 148, 121, 172, 46, 156, -36, 99, +-106, 19, -146, -72, -144, -136, -116, -164, +-74, -146, -29, -93, 13, -23, 50, 46, +81, 97, 98, 123, 95, 111, 87, 74, +71, 21, 43, -24, 14, -61, -8, -78, +-34, -77, -65, -55, -96, -25, -124, 0, +-140, 13, -128, 16, -78, 20, 5, 23, +115, 39, 221, 58, 281, 81, 270, 90, +182, 74, 26, 16, -159, -69, -315, -160, +-396, -224, -375, -234, -235, -180, -13, -60, +220, 98, 401, 255, 481, 351, 431, 355, +258, 251, 18, 72, -228, -135, -410, -307, +-473, -394, -412, -375, -251, -253, -32, -68, +177, 125, 314, 258, 362, 308, 323, 264, +216, 159, 73, 29, -61, -81, -161, -140, +-203, -136, -184, -86, -124, -24, -51, 23, +11, 32, 45, 12, 37, -28, 3, -60, +-30, -70, -47, -46, -39, 3, 6, 64, +69, 102, 125, 95, 164, 50, 166, -18, +119, -75, 37, -109, -58, -92, -149, -30, +-197, 64, -188, 149, -144, 193, -81, 166, +-5, 71, 55, -64, 75, -202, 69, -297, +55, -316, 47, -237, 55, -86, 74, 102, +87, 264, 94, 360, 88, 358, 47, 267, +-18, 115, -84, -53, -139, -187, -174, -261, +-174, -261, -139, -211, -85, -138, -25, -72, +37, -16, 85, 19, 122, 46, 148, 73, +159, 116, 149, 172, 124, 224, 84, 241, +23, 195, -42, 93, -101, -54, -157, -202, +-199, -320, -204, -371, -170, -342, -110, -225, +-32, -58, 51, 112, 130, 248, 192, 327, +221, 341, 211, 283, 167, 175, 92, 42, +-17, -85, -135, -189, -223, -250, -260, -272, +-235, -249, -146, -181, -14, -73, 116, 53, +210, 170, 244, 260, 202, 297, 106, 276, +-19, 183, -143, 44, -228, -112, -245, -240, +-192, -318, -90, -329, 38, -266, 152, -140, +216, 23, 227, 182, 190, 308, 112, 361, +18, 341, -71, 249, -147, 110, -202, -53, +-219, -204, -197, -308, -142, -340, -47, -304, +73, -218, 179, -94, 246, 33, 266, 140, +217, 199, 100, 215, -44, 185, -177, 138, +-269, 86, -284, 40, -217, 6, -85, -20, +79, -39, 219, -56, 286, -79, 266, -112, +177, -136, 23, -146, -144, -130, -259, -96, +-289, -40, -233, 29, -106, 105, 61, 170, +202, 207, 276, 205, 264, 158, 164, 79, +10, -28, -142, -138, -258, -231, -299, -262, +-240, -223, -101, -113, 70, 36, 231, 187, +333, 295, 328, 319, 217, 243, 41, 76, +-151, -126, -299, -308, -358, -403, -319, -384, +-198, -246, -29, -31, 129, 203, 224, 382, +251, 451, 219, 388, 129, 218, 18, 3, +-59, -200, -81, -329, -62, -357, -14, -278, +30, -131, 37, 40, 0, 171, -77, 228, +-166, 204, -219, 115, -202, -1, -129, -108, +-16, -166, 125, -163, 248, -95, 299, 4, +279, 96, 196, 145, 66, 145, -75, 97, +-185, 20, -246, -56, -243, -98, -179, -84, +-91, -25, 1, 57, 80, 115, 123, 127, +115, 71, 74, -37, 22, -176, -24, -293, +-46, -336, -30, -274, 10, -110, 56, 109, +96, 329, 99, 476, 57, 508, -15, 397, +-99, 176, -176, -101, -204, -345, -166, -491, +-75, -495, 51, -365, 179, -149, 260, 88, +254, 274, 161, 361, 5, 322, -163, 182, +-283, -3, -316, -160, -253, -249, -100, -241, +98, -143, 263, 14, 349, 176, 339, 283, +222, 298, 32, 210, -165, 58, -315, -121, +-372, -269, -313, -349, -160, -326, 27, -212, +193, -38, 288, 139, 284, 265, 190, 310, +44, 262, -107, 144, -220, -10, -246, -146, +-187, -225, -71, -215, 67, -131, 195, -2, +255, 119, 224, 197, 123, 206, -20, 140, +-160, 21, -249, -116, -262, -221, -200, -262, +-80, -220, 48, -117, 134, 26, 165, 165, +143, 263, 73, 290, -16, 238, -71, 124, +-70, -20, -18, -151, 65, -240, 144, -263, +175, -218, 138, -111, 27, 19, -129, 136, +-272, 201, -352, 206, -352, 151, -257, 54, +-71, -50, 145, -132, 320, -163, 415, -142, +416, -78, 312, 0, 136, 76, -61, 120, +-229, 129, -327, 101, -342, 53, -287, 2, +-176, -41, -28, -62, 104, -69, 183, -63, +206, -60, 178, -54, 95, -53, -10, -43, +-92, -27, -132, -1, -120, 35, -58, 74, +31, 108, 115, 124, 176, 118, 181, 87, +116, 45, 4, -6, -125, -55, -243, -100, +-303, -129, -268, -140, -153, -131, 5, -104, +164, -61, 272, -4, 296, 53, 240, 99, +123, 118, -20, 115, -136, 89, -190, 63, +-186, 35, -123, 15, -22, 5, 65, 3, +104, -1, 93, -22, 36, -64, -49, -115, +-119, -154, -144, -170, -113, -144, -40, -76, +59, 26, 148, 128, 205, 199, 211, 221, +157, 190, 53, 119, -63, 31, -166, -46, +-240, -98, -257, -113, -211, -106, -124, -86, +-22, -74, 84, -73, 164, -78, 199, -71, +198, -40, 167, 19, 108, 103, 44, 187, +-13, 245, -71, 247, -116, 184, -152, 56, +-187, -98, -211, -241, -198, -331, -141, -342, +-49, -269, 77, -128, 212, 40, 314, 194, +356, 291, 321, 317, 199, 270, 20, 172, +-178, 48, -354, -65, -454, -151, -433, -193, +-306, -183, -113, -138, 109, -74, 305, -14, +415, 29, 413, 47, 316, 41, 153, 12, +-30, -19, -191, -44, -300, -45, -331, -17, +-272, 37, -158, 106, -27, 169, 100, 205, +192, 192, 215, 122, 166, -4, 81, -154, +-16, -293, -96, -379, -133, -379, -118, -276, +-55, -88, 40, 147, 127, 365, 161, 501, +136, 511, 53, 379, -79, 142, -218, -146, +-298, -400, -296, -551, -205, -547, -39, -393, +162, -133, 335, 157, 425, 396, 401, 521, +264, 495, 57, 342, -169, 113, -363, -119, +-469, -295, -448, -373, -320, -357, -133, -262, +76, -127, 258, 8, 361, 112, 371, 171, +303, 188, 178, 176, 32, 149, -100, 113, +-191, 67, -224, 5, -198, -59, -144, -119, +-89, -160, -39, -171, -4, -141, 5, -74, +1, 15, 8, 100, 24, 150, 52, 160, +94, 122, 138, 54, 163, -25, 158, -88, +107, -117, 14, -107, -98, -64, -202, -4, +-269, 44, -270, 68, -199, 62, -87, 30, +41, -9, 156, -45, 230, -56, 238, -41, +189, 0, 110, 43, 15, 76, -75, 88, +-132, 66, -153, 16, -138, -52, -97, -114, +-59, -149, -26, -136, 6, -78, 32, 15, +50, 110, 76, 182, 106, 208, 114, 174, +93, 86, 53, -38, -4, -156, -75, -234, +-142, -246, -190, -198, -198, -98, -155, 21, +-75, 131, 22, 201, 128, 219, 212, 191, +239, 134, 211, 66, 143, 0, 43, -51, +-74, -91, -172, -120, -227, -142, -230, -156, +-181, -162, -94, -143, -1, -93, 81, -16, +130, 76, 129, 165, 90, 230, 47, 250, +7, 224, -30, 149, -37, 46, -13, -66, +18, -154, 36, -204, 40, -210, 21, -179, +-15, -117, -59, -39, -102, 35, -120, 93, +-101, 117, -59, 112, -17, 86, 19, 49, +46, 8, 59, -23, 62, -37, 70, -28, +74, -5, 74, 22, 65, 42, 33, 45, +-12, 30, -62, -4, -110, -42, -152, -75, +-162, -91, -126, -84, -62, -49, 17, -2, +95, 43, 143, 77, 146, 90, 112, 78, +50, 49, -21, 13, -69, -22, -82, -44, +-71, -48, -39, -34, -4, -13, 15, 9, +11, 24, -7, 20, -32, -5, -56, -41, +-55, -72, -26, -88, 21, -75, 72, -32, +109, 40, 112, 120, 78, 186, 18, 210, +-59, 182, -127, 102, -160, -16, -156, -141, +-116, -246, -42, -299, 41, -288, 104, -210, +136, -87, 129, 53, 82, 175, 23, 259, +-27, 298, -57, 291, -59, 239, -35, 156, +-2, 62, 16, -40, 15, -146, -11, -248, +-60, -324, -115, -357, -143, -331, -141, -247, +-93, -103, 3, 79, 112, 264, 201, 406, +246, 467, 234, 432, 159, 303, 52, 112, +-63, -99, -161, -276, -219, -387, -229, -409, +-207, -345, -156, -219, -89, -65, -22, 78, +32, 178, 80, 228, 125, 236, 156, 207, +180, 157, 190, 103, 170, 52, 115, 0, +24, -54, -93, -110, -203, -159, -276, -189, +-297, -192, -261, -158, -168, -85, -39, 17, +84, 123, 184, 204, 242, 231, 248, 199, +198, 112, 115, -4, 22, -112, -60, -177, +-113, -176, -134, -108, -128, 4, -100, 117, +-62, 187, -40, 186, -28, 107, -21, -34, +-20, -187, -24, -306, -13, -342, 16, -272, +51, -107, 87, 111, 110, 319, 112, 461, +87, 491, 41, 395, -20, 195, -78, -60, +-116, -298, -132, -458, -124, -507, -84, -435, +-29, -265, 18, -44, 49, 169, 53, 317, +33, 368, 1, 323, -22, 205, -29, 55, +-5, -77, 40, -155, 91, -160, 125, -98, +125, 0, 88, 84, 10, 118, -92, 88, +-195, -3, -269, -119, -288, -219, -227, -260, +-103, -218, 57, -96, 216, 69, 333, 225, +368, 325, 316, 334, 190, 251, 17, 104, +-157, -62, -297, -195, -372, -254, -367, -236, +-278, -158, -136, -59, 19, 21, 160, 55, +262, 42, 298, 7, 274, -19, 211, -9, +119, 46, 19, 135, -80, 218, -167, 255, +-234, 212, -264, 82, -257, -102, -209, -287, +-125, -419, -11, -446, 112, -345, 221, -139, +297, 117, 312, 348, 258, 489, 143, 499, +-10, 379, -169, 162, -284, -92, -335, -306, +-310, -419, -212, -410, -69, -293, 79, -112, +197, 78, 260, 220, 249, 279, 177, 248, +65, 148, -51, 27, -139, -77, -176, -135, +-161, -133, -112, -82, -45, -9, 23, 52, +69, 81, 80, 70, 62, 25, 24, -37, +-17, -90, -43, -113, -44, -96, -24, -43, +12, 34, 45, 112, 58, 171, 44, 192, +8, 164, -38, 92, -82, -7, -113, -114, +-123, -209, -105, -267, -57, -269, 17, -208, +94, -95, 155, 50, 185, 189, 170, 292, +109, 330, 16, 289, -86, 179, -174, 30, +-221, -115, -223, -219, -178, -254, -89, -219, +20, -131, 120, -23, 187, 63, 205, 100, +169, 81, 86, 23, -12, -42, -91, -83, +-138, -76, -141, -16, -106, 74, -48, 165, +16, 214, 69, 199, 86, 122, 70, 3, +31, -123, -24, -220, -75, -263, -98, -240, +-88, -157, -58, -35, -15, 86, 28, 171, +69, 206, 95, 193, 99, 143, 80, 74, +43, 2, 2, -61, -43, -103, -87, -121, +-119, -125, -126, -120, -115, -101, -84, -64, +-35, -13, 23, 47, 82, 111, 131, 167, +152, 200, 142, 193, 101, 140, 31, 52, +-47, -58, -117, -168, -163, -248, -182, -279, +-167, -247, -117, -161, -39, -37, 47, 97, +123, 207, 175, 266, 186, 262, 155, 204, +89, 106, 8, -4, -67, -102, -125, -161, +-164, -173, -170, -145, -147, -90, -98, -25, +-33, 32, 32, 69, 88, 80, 119, 67, +120, 39, 97, 4, 62, -30, 20, -59, +-17, -73, -54, -65, -81, -36, -87, 8, +-74, 60, -42, 107, 3, 137, 40, 140, +54, 107, 47, 37, 21, -55, -12, -145, +-48, -207, -73, -222, -81, -182, -67, -96, +-36, 18, 3, 131, 45, 208, 84, 230, +107, 200, 96, 129, 65, 38, 24, -50, +-21, -116, -67, -154, -97, -159, -114, -139, +-112, -103, -93, -62, -63, -17, -14, 32, +41, 82, 87, 137, 108, 185, 103, 209, +73, 195, 21, 128, -45, 12, -100, -131, +-127, -262, -122, -342, -78, -344, -2, -257, +82, -94, 143, 110, 161, 302, 128, 422, +61, 437, -30, 339, -127, 152, -204, -70, +-237, -270, -220, -399, -149, -423, -41, -336, +79, -170, 191, 19, 261, 185, 272, 288, +228, 311, 145, 259, 30, 156, -94, 36, +-204, -72, -272, -143, -290, -165, -257, -150, +-164, -114, -35, -64, 92, -15, 187, 22, +234, 47, 219, 60, 161, 61, 73, 52, +-19, 37, -91, 20, -129, 5, -130, -3, +-98, -1, -44, 12, 5, 28, 32, 36, +19, 29, -17, 4, -59, -41, -85, -96, +-79, -138, -38, -146, 32, -110, 110, -32, +161, 74, 168, 177, 134, 245, 54, 254, +-53, 191, -159, 64, -229, -89, -238, -229, +-187, -314, -90, -316, 32, -231, 145, -79, +218, 100, 231, 256, 180, 346, 84, 343, +-30, 244, -135, 79, -203, -104, -217, -253, +-179, -329, -101, -312, -12, -206, 67, -47, +125, 114, 152, 234, 142, 285, 108, 252, +60, 148, -2, 6, -63, -128, -119, -215, +-148, -232, -148, -180, -127, -77, -80, 43, +-13, 147, 57, 209, 111, 211, 144, 158, +146, 62, 113, -41, 38, -129, -60, -185, +-139, -197, -173, -165, -161, -101, -100, -23, +-11, 52, 81, 111, 149, 148, 163, 161, +129, 153, 59, 126, -31, 86, -120, 31, +-184, -31, -205, -96, -164, -163, -80, -215, +17, -236, 115, -215, 188, -143, 214, -25, +193, 118, 135, 255, 51, 349, -40, 371, +-138, 303, -217, 153, -251, -49, -237, -251, +-177, -398, -78, -449, 43, -386, 159, -223, +241, -4, 264, 207, 232, 361, 144, 413, +18, 357, -114, 214, -219, 36, -262, -131, +-235, -240, -161, -267, -49, -222, 79, -131, +180, -31, 224, 46, 201, 83, 124, 81, +16, 50, -103, 16, -205, -5, -246, 1, +-217, 30, -138, 69, -30, 97, 82, 97, +182, 70, 237, 20, 229, -39, 170, -97, +85, -137, -24, -147, -135, -130, -217, -88, +-246, -29, -221, 36, -162, 99, -84, 144, +8, 164, 95, 154, 150, 115, 174, 55, +175, -20, 156, -91, 99, -140, 9, -157, +-79, -140, -138, -93, -169, -30, -170, 30, +-135, 78, -75, 105, -6, 108, 41, 91, +69, 61, 92, 27, 98, 1, 69, -17, +30, -30, -1, -41, -13, -47, -17, -53, +-24, -58, -29, -53, -38, -38, -62, -13, +-98, 18, -114, 49, -98, 69, -50, 77, +8, 73, 74, 54, 145, 27, 186, 4, +170, -12, 110, -21, 29, -30, -63, -43, +-146, -60, -204, -77, -206, -84, -158, -78, +-86, -50, -9, 1, 64, 68, 120, 132, +138, 171, 112, 168, 59, 118, 11, 34, +-34, -67, -63, -156, -62, -202, -29, -185, +13, -109, 44, -1, 50, 106, 43, 175, +21, 184, -31, 127, -93, 21, -138, -97, +-145, -182, -117, -200, -60, -143, 16, -26, +96, 109, 139, 207, 134, 237, 95, 182, +40, 61, -9, -83, -43, -200, -48, -246, +-20, -202, 16, -77, 28, 77, 16, 204, +-16, 254, -72, 205, -138, 67, -189, -110, +-194, -256, -130, -317, -13, -269, 122, -115, +243, 97, 309, 290, 294, 398, 187, 383, +19, 245, -149, 24, -272, -214, -333, -390, +-306, -447, -194, -370, -31, -182, 138, 56, +251, 268, 285, 394, 239, 398, 122, 285, +-37, 96, -173, -103, -250, -253, -248, -315, +-170, -285, -53, -176, 74, -29, 167, 104, +196, 188, 159, 200, 77, 155, -18, 73, +-92, -12, -129, -70, -118, -90, -62, -70, +2, -29, 46, 11, 65, 36, 47, 40, +-2, 23, -61, -4, -116, -29, -131, -40, +-98, -38, -33, -25, 49, -6, 128, 11, +176, 23, 173, 29, 113, 31, 29, 31, +-43, 31, -110, 29, -160, 22, -182, 3, +-168, -20, -122, -47, -57, -72, 13, -85, +93, -73, 164, -35, 191, 22, 174, 85, +126, 133, 62, 152, -22, 133, -121, 73, +-205, -19, -241, -120, -230, -205, -172, -246, +-66, -227, 65, -150, 187, -26, 258, 120, +259, 253, 211, 335, 126, 343, 1, 270, +-124, 130, -218, -52, -265, -232, -265, -366, +-219, -420, -120, -377, 18, -245, 145, -53, +224, 159, 253, 335, 235, 431, 168, 423, +50, 311, -84, 127, -188, -84, -248, -266, +-266, -379, -218, -393, -108, -305, 30, -141, +158, 51, 239, 216, 265, 315, 236, 325, +135, 251, -16, 118, -159, -34, -264, -157, +-308, -222, -287, -225, -193, -173, -43, -91, +108, -6, 220, 58, 281, 88, 283, 91, +222, 75, 113, 65, -24, 68, -140, 83, +-207, 94, -231, 85, -210, 45, -143, -28, +-62, -118, -5, -202, 26, -247, 44, -234, +65, -150, 77, -15, 80, 134, 84, 256, +94, 311, 94, 283, 79, 181, 47, 37, +5, -105, -45, -206, -116, -242, -183, -202, +-216, -113, -208, -11, -158, 72, -75, 109, +17, 97, 108, 50, 172, -8, 197, -47, +194, -52, 163, -24, 105, 30, 30, 88, +-47, 130, -105, 132, -131, 93, -140, 25, +-130, -52, -108, -125, -93, -171, -91, -176, +-90, -143, -79, -83, -43, -13, 20, 55, +93, 109, 180, 140, 255, 143, 289, 127, +264, 94, 180, 55, 44, 18, -121, -12, +-284, -34, -399, -54, -429, -76, -373, -102, +-238, -125, -58, -140, 124, -138, 275, -112, +361, -56, 359, 25, 288, 122, 171, 214, +41, 275, -59, 284, -127, 229, -162, 118, +-163, -30, -151, -181, -138, -300, -127, -357, +-117, -338, -89, -242, -52, -89, -6, 85, +62, 234, 141, 325, 210, 335, 241, 266, +210, 142, 116, -7, -12, -139, -148, -229, +-244, -253, -263, -210, -211, -118, -105, -6, +29, 91, 144, 155, 208, 174, 198, 144, +115, 75, -2, -7, -132, -82, -233, -133, +-261, -149, -200, -123, -65, -63, 100, 18, +225, 102, 282, 171, 265, 205, 165, 187, +13, 121, -138, 15, -245, -109, -280, -224, +-244, -295, -150, -299, -10, -226, 130, -88, +218, 86, 233, 247, 179, 352, 76, 368, +-48, 287, -159, 134, -219, -45, -207, -198, +-146, -287, -46, -286, 65, -204, 146, -73, +177, 56, 153, 136, 85, 143, 7, 84, +-64, -10, -120, -99, -125, -141, -85, -111, +-31, -13, 12, 118, 35, 234, 41, 286, +23, 254, -25, 146, -76, -10, -95, -166, +-76, -276, -24, -308, 40, -262, 98, -159, +137, -38, 134, 61, 82, 117, 13, 131, +-57, 110, -111, 77, -137, 56, -132, 58, +-89, 84, -28, 113, 29, 125, 72, 96, +86, 27, 60, -71, 9, -169, -48, -238, +-82, -254, -75, -212, -40, -120, 8, 0, +63, 115, 98, 193, 94, 221, 64, 199, +13, 137, -44, 57, -101, -13, -147, -56, +-157, -73, -117, -67, -45, -51, 40, -35, +116, -26, 160, -26, 162, -31, 114, -37, +36, -33, -50, -17, -131, 5, -185, 25, +-194, 44, -164, 56, -93, 59, 10, 56, +112, 51, 189, 48, 222, 37, 200, 17, +127, -11, 18, -46, -107, -88, -205, -125, +-253, -140, -234, -126, -153, -80, -40, -1, +81, 89, 184, 169, 228, 220, 198, 225, +115, 178, 1, 84, -106, -33, -182, -148, +-208, -231, -164, -266, -66, -242, 41, -168, +129, -64, 176, 51, 160, 153, 90, 223, +-6, 247, -88, 227, -138, 169, -149, 82, +-121, -17, -65, -104, -9, -169, 42, -205, +73, -203, 78, -162, 67, -92, 36, -7, +-8, 78, -30, 141, -21, 170, -5, 159, +7, 111, 9, 37, 2, -36, -17, -96, +-44, -124, -60, -110, -52, -62, -26, 0, +0, 58, 15, 98, 25, 101, 37, 71, +26, 18, -3, -37, -24, -79, -33, -95, +-34, -82, -16, -40, 13, 12, 46, 50, +68, 66, 50, 52, 8, 18, -43, -24, +-96, -50, -135, -49, -130, -21, -77, 25, +9, 72, 89, 107, 151, 112, 186, 82, +162, 22, 81, -51, -27, -120, -128, -164, +-201, -171, -230, -138, -210, -75, -130, 3, +-10, 82, 100, 144, 179, 181, 219, 186, +208, 160, 143, 105, 46, 31, -53, -53, +-119, -131, -155, -192, -162, -218, -135, -201, +-90, -138, -40, -40, 6, 71, 34, 175, +50, 246, 51, 259, 33, 206, 24, 101, +32, -32, 50, -160, 76, -252, 95, -277, +86, -227, 45, -120, -29, 16, -113, 147, +-177, 238, -208, 261, -194, 215, -139, 111, +-46, -18, 71, -137, 177, -213, 236, -227, +246, -180, 195, -86, 83, 26, -49, 120, +-160, 170, -219, 167, -217, 122, -166, 49, +-85, -30, 8, -88, 79, -114, 120, -102, +129, -63, 106, -6, 62, 43, 13, 67, +-24, 65, -39, 39, -42, 4, -48, -32, +-45, -55, -47, -63, -60, -47, -73, -15, +-74, 25, -46, 62, 15, 85, 80, 88, +139, 69, 177, 33, 168, -19, 105, -71, +0, -115, -117, -134, -214, -121, -265, -78, +-251, -15, -160, 57, -23, 119, 122, 155, +242, 153, 298, 113, 279, 47, 181, -27, +23, -89, -143, -132, -258, -144, -307, -124, +-273, -78, -154, -23, 8, 27, 154, 68, +237, 97, 245, 107, 195, 99, 90, 76, +-43, 43, -154, 4, -217, -36, -211, -72, +-151, -95, -55, -97, 59, -79, 155, -46, +188, -7, 156, 29, 85, 55, -8, 62, +-84, 54, -130, 35, -133, 23, -94, 15, +-36, 16, 15, 28, 53, 39, 65, 31, +51, 3, 9, -41, -41, -91, -68, -127, +-68, -137, -35, -110, 31, -48, 105, 42, +142, 125, 132, 182, 75, 193, -14, 155, +-106, 80, -184, -15, -218, -100, -188, -153, +-108, -159, -10, -126, 84, -68, 156, -12, +193, 27, 174, 42, 103, 39, 21, 26, +-45, 14, -84, 22, -88, 52, -61, 86, +-16, 108, 30, 105, 35, 66, 3, -6, +-48, -97, -105, -183, -146, -234, -143, -225, +-96, -153, -13, -34, 86, 101, 167, 218, +220, 284, 224, 276, 172, 198, 82, 72, +-26, -68, -129, -186, -199, -247, -228, -240, +-201, -168, -127, -59, -42, 52, 35, 134, +92, 164, 112, 145, 95, 82, 64, 1, +31, -74, 6, -115, -10, -112, -17, -66, +-11, 9, 3, 87, 16, 141, 24, 154, +15, 119, -12, 48, -46, -41, -79, -127, +-87, -182, -69, -191, -42, -149, -10, -65, +27, 33, 55, 114, 72, 161, 75, 165, +65, 128, 42, 64, -2, -9, -50, -68, +-85, -99, -95, -94, -85, -68, -54, -32, +-2, -1, 57, 20, 95, 27, 106, 18, +101, 10, 78, 13, 25, 27, -40, 43, +-98, 52, -138, 41, -151, 11, -144, -38, +-110, -92, -43, -131, 36, -135, 101, -96, +154, -20, 191, 76, 195, 162, 156, 213, +76, 209, -14, 149, -110, 43, -208, -77, +-278, -177, -288, -227, -229, -213, -114, -139, +26, -29, 170, 85, 291, 172, 338, 203, +292, 171, 176, 86, 26, -20, -137, -117, +-279, -174, -361, -178, -343, -125, -232, -32, +-66, 72, 118, 159, 282, 202, 378, 192, +360, 138, 231, 52, 41, -51, -142, -139, +-301, -195, -391, -203, -372, -168, -253, -100, +-73, -10, 115, 81, 275, 154, 374, 191, +378, 187, 263, 139, 84, 62, -101, -30, +-246, -111, -330, -166, -334, -175, -247, -133, +-105, -51, 34, 41, 144, 115, 220, 158, +242, 155, 204, 105, 120, 31, 20, -45, +-56, -103, -101, -123, -131, -104, -131, -62, +-100, -18, -70, 11, -57, 18, -53, 1, +-32, -22, 4, -31, 43, -5, 91, 53, +148, 128, 188, 191, 183, 217, 121, 185, +22, 83, -88, -66, -199, -223, -284, -340, +-299, -380, -231, -325, -108, -189, 47, 3, +197, 197, 308, 344, 342, 408, 279, 372, +142, 252, -29, 86, -185, -84, -289, -218, +-317, -285, -264, -280, -143, -216, -3, -118, +113, -12, 190, 73, 219, 120, 194, 130, +125, 123, 26, 104, -64, 79, -111, 52, +-123, 27, -104, 5, -64, -21, -21, -54, +4, -93, 3, -121, -16, -128, -29, -108, +-29, -65, -12, -1, 24, 73, 69, 139, +108, 184, 126, 188, 112, 154, 68, 86, +5, -2, -82, -96, -164, -173, -212, -216, +-206, -216, -147, -169, -58, -80, 46, 26, +146, 124, 215, 199, 220, 233, 171, 214, +90, 141, -2, 35, -94, -79, -165, -171, +-189, -218, -161, -204, -101, -136, -27, -31, +48, 82, 105, 167, 127, 201, 100, 173, +43, 94, -10, -13, -45, -110, -69, -167, +-64, -172, -23, -126, 34, -45, 70, 40, +70, 98, 50, 117, 12, 96, -48, 47, +-112, -6, -140, -38, -122, -37, -64, -2, +9, 44, 87, 77, 159, 78, 184, 37, +141, -39, 57, -129, -26, -192, -98, -202, +-146, -143, -155, -31, -109, 102, -36, 213, +22, 266, 51, 240, 67, 140, 66, -7, +39, -154, -6, -250, -36, -263, -24, -193, +8, -65, 40, 88, 72, 214, 93, 272, +73, 241, 4, 132, -82, -19, -147, -164, +-173, -261, -161, -288, -104, -233, -8, -110, +91, 45, 156, 182, 175, 267, 154, 279, +101, 224, 13, 122, -83, 1, -141, -107, +-142, -178, -99, -196, -29, -168, 47, -107, +107, -39, 122, 20, 66, 57, -25, 66, +-111, 51, -166, 25, -178, 3, -132, -1, +-27, 18, 109, 50, 224, 86, 275, 112, +263, 108, 189, 68, 54, 2, -118, -84, +-263, -169, -335, -222, -327, -222, -254, -170, +-122, -73, 44, 48, 188, 161, 272, 239, +287, 254, 251, 210, 178, 121, 79, 14, +-23, -86, -95, -155, -138, -176, -165, -151, +-177, -102, -167, -46, -136, -4, -99, 16, +-61, 21, -9, 22, 65, 31, 138, 55, +196, 92, 231, 123, 229, 131, 177, 100, +72, 29, -60, -69, -174, -166, -242, -225, +-261, -223, -221, -151, -131, -28, -14, 117, +90, 231, 157, 274, 179, 227, 154, 105, +86, -53, 3, -197, -65, -275, -96, -260, +-74, -158, -15, -1, 51, 159, 98, 261, +109, 273, 71, 192, -5, 45, -91, -120, +-153, -243, -170, -283, -139, -229, -70, -98, +21, 61, 111, 196, 167, 265, 167, 250, +114, 158, 40, 25, -46, -107, -117, -197, +-140, -219, -106, -177, -31, -88, 46, 11, +105, 87, 138, 118, 126, 110, 60, 71, +-34, 21, -115, -18, -159, -35, -167, -31, +-135, -10, -63, 13, 31, 30, 113, 36, +159, 25, 171, 4, 145, -22, 80, -46, +-8, -67, -87, -78, -126, -81, -122, -68, +-92, -35, -42, 18, 19, 79, 68, 134, +85, 166, 71, 158, 40, 106, -1, 15, +-47, -92, -88, -188, -99, -236, -73, -218, +-21, -132, 36, 1, 84, 142, 118, 241, +124, 266, 89, 204, 29, 71, -28, -89, +-74, -225, -101, -291, -109, -266, -88, -148, +-42, 23, 7, 194, 43, 309, 64, 325, +73, 237, 56, 73, 13, -114, -32, -263, +-51, -333, -42, -304, -16, -184, 18, -9, +61, 159, 90, 265, 84, 282, 44, 212, +-8, 83, -58, -59, -109, -167, -145, -207, +-135, -173, -79, -82, -7, 28, 65, 116, +128, 149, 172, 119, 169, 44, 111, -45, +29, -116, -47, -141, -109, -105, -152, -25, +-154, 66, -116, 131, -55, 152, 6, 113, +64, 30, 110, -66, 128, -137, 111, -162, +70, -127, 18, -45, -32, 49, -68, 128, +-88, 169, -81, 155, -54, 85, -20, -15, +8, -112, 27, -175, 36, -182, 36, -135, +28, -52, 21, 41, 18, 126, 12, 178, +8, 180, 6, 133, 3, 54, -3, -32, +-12, -104, -35, -145, -60, -150, -69, -120, +-53, -63, -19, 2, 21, 56, 63, 88, +93, 92, 97, 77, 67, 48, 18, 17, +-29, -7, -64, -13, -86, -2, -85, 13, +-56, 23, -11, 17, 33, -11, 65, -53, +77, -99, 63, -135, 28, -141, -21, -102, +-61, -21, -77, 77, -64, 170, -30, 231, +15, 244, 57, 194, 81, 90, 77, -41, +47, -165, 11, -250, -26, -275, -60, -231, +-76, -135, -67, -13, -40, 106, -3, 189, +28, 214, 45, 185, 48, 113, 34, 24, +3, -53, -29, -100, -40, -109, -22, -84, +15, -39, 51, 4, 83, 33, 95, 38, +71, 25, 16, -4, -48, -39, -98, -62, +-133, -63, -148, -40, -129, -3, -68, 36, +16, 66, 94, 84, 148, 84, 178, 68, +171, 34, 118, -6, 41, -42, -26, -73, +-72, -87, -109, -84, -132, -62, -128, -30, +-96, 9, -64, 44, -35, 67, 3, 70, +50, 54, 79, 24, 86, -9, 89, -35, +90, -44, 80, -29, 52, 2, 19, 37, +-11, 59, -47, 62, -89, 36, -113, -14, +-105, -74, -72, -123, -29, -138, 17, -110, +63, -44, 91, 40, 91, 115, 71, 159, +40, 163, -3, 123, -43, 48, -70, -36, +-73, -104, -50, -136, -6, -131, 43, -96, +81, -41, 94, 16, 77, 58, 35, 72, +-21, 63, -70, 43, -99, 20, -104, 5, +-88, -2, -57, -5, -11, -11, 39, -19, +76, -29, 95, -36, 99, -35, 89, -22, +58, 7, 14, 43, -26, 73, -53, 84, +-69, 70, -78, 29, -70, -28, -44, -84, +-16, -122, 7, -123, 25, -84, 39, -16, +41, 52, 26, 100, 4, 115, -10, 99, +-16, 52, -10, -9, 12, -57, 44, -69, +70, -47, 77, -2, 58, 48, 20, 79, +-27, 71, -81, 24, -131, -48, -159, -125, +-154, -174, -114, -172, -41, -112, 54, -6, +151, 113, 225, 217, 250, 274, 218, 258, +140, 169, 31, 34, -94, -109, -201, -226, +-263, -291, -266, -286, -210, -213, -115, -93, +2, 41, 120, 156, 213, 228, 249, 244, +218, 211, 143, 136, 48, 39, -49, -58, +-127, -135, -161, -176, -138, -178, -83, -142, +-25, -79, 28, -5, 73, 65, 89, 116, +62, 132, 12, 114, -38, 71, -76, 18, +-97, -37, -82, -78, -26, -89, 54, -72, +121, -36, 153, 6, 152, 39, 113, 50, +36, 41, -63, 18, -145, -8, -186, -31, +-184, -40, -149, -23, -75, 12, 24, 44, +119, 63, 176, 65, 184, 46, 159, 5, +100, -45, 14, -84, -69, -103, -119, -98, +-133, -66, -123, -17, -97, 34, -52, 77, +2, 104, 49, 108, 84, 86, 106, 50, +113, 9, 96, -27, 55, -56, 0, -79, +-48, -91, -85, -92, -103, -77, -103, -51, +-80, -10, -32, 38, 23, 87, 69, 129, +98, 145, 109, 128, 91, 77, 39, -3, +-28, -91, -80, -167, -107, -211, -104, -206, +-74, -144, -15, -35, 58, 89, 111, 198, +133, 267, 128, 274, 99, 213, 37, 92, +-43, -56, -115, -198, -154, -295, -165, -324, +-144, -280, -85, -173, 4, -26, 92, 125, +150, 242, 176, 301, 174, 291, 139, 217, +72, 103, -7, -23, -79, -131, -130, -200, +-162, -214, -163, -173, -129, -97, -71, -10, +-6, 63, 47, 104, 86, 108, 103, 76, +101, 19, 85, -38, 62, -67, 38, -65, +19, -39, 6, 5, -8, 54, -24, 90, +-38, 97, -54, 74, -77, 29, -98, -22, +-102, -64, -78, -85, -32, -84, 32, -59, +99, -21, 155, 16, 172, 35, 141, 31, +74, 13, -5, -10, -84, -22, -146, -17, +-164, 3, -129, 35, -64, 68, 4, 81, +66, 66, 110, 25, 116, -29, 74, -80, +8, -107, -48, -101, -81, -61, -87, 3, +-64, 71, -7, 123, 61, 135, 101, 105, +98, 42, 69, -35, 24, -103, -31, -140, +-82, -140, -103, -99, -90, -31, -62, 36, +-26, 80, 12, 96, 48, 85, 68, 57, +67, 25, 55, 4, 43, 3, 28, 19, +16, 36, 8, 40, 2, 23, -7, -18, +-30, -74, -61, -125, -86, -155, -88, -151, +-70, -106, -33, -29, 19, 59, 76, 133, +119, 176, 128, 183, 99, 155, 51, 99, +-2, 31, -60, -31, -111, -76, -132, -100, +-111, -105, -66, -96, -15, -80, 37, -60, +83, -36, 107, -10, 96, 17, 63, 45, +34, 66, 16, 76, -6, 73, -32, 55, +-49, 23, -60, -7, -81, -32, -103, -48, +-99, -50, -63, -42, -6, -25, 59, -3, +131, 19, 198, 31, 229, 34, 201, 34, +123, 28, 11, 16, -123, -2, -256, -26, +-336, -50, -330, -69, -248, -77, -106, -71, +71, -47, 244, -3, 364, 48, 393, 92, +331, 114, 202, 112, 31, 84, -145, 32, +-281, -28, -342, -78, -318, -99, -225, -85, +-90, -47, 54, -1, 168, 39, 225, 54, +221, 35, 162, -11, 79, -65, -1, -102, +-57, -106, -85, -68, -83, 4, -57, 85, +-22, 151, 5, 182, 9, 163, 5, 93, +-1, -9, -12, -103, -27, -158, -27, -161, +-2, -120, 31, -48, 52, 30, 59, 88, +53, 104, 24, 72, -21, 10, -59, -58, +-66, -103, -51, -115, -24, -82, 9, -18, +50, 59, 82, 124, 82, 157, 55, 154, +18, 117, -23, 60, -66, -3, -97, -60, +-96, -106, -61, -138, -18, -157, 24, -160, +59, -147, 83, -116, 86, -55, 63, 36, +33, 138, 14, 228, 1, 284, -16, 282, +-24, 211, -25, 80, -29, -80, -42, -234, +-48, -339, -46, -364, -34, -296, -17, -152, +1, 29, 26, 197, 55, 311, 78, 345, +81, 290, 65, 165, 38, 7, 11, -138, +-23, -239, -52, -270, -62, -233, -53, -144, +-39, -28, -35, 79, -29, 151, -13, 173, +2, 154, 7, 103, 17, 35, 38, -30, +58, -72, 62, -88, 56, -74, 52, -40, +41, -2, 9, 31, -38, 49, -75, 43, +-98, 16, -105, -28, -93, -71, -47, -94, +20, -89, 81, -55, 115, 1, 135, 68, +134, 127, 97, 156, 34, 141, -37, 86, +-96, 5, -136, -87, -153, -162, -134, -194, +-77, -177, -2, -110, 67, -15, 120, 82, +156, 153, 162, 180, 135, 157, 86, 92, +25, 12, -40, -64, -105, -119, -154, -134, +-178, -119, -164, -81, -119, -36, -51, 5, +31, 42, 111, 69, 170, 87, 196, 97, +181, 102, 130, 95, 60, 64, -19, 7, +-93, -67, -149, -143, -165, -196, -145, -210, +-102, -170, -44, -77, 22, 49, 76, 177, +98, 264, 91, 279, 70, 216, 50, 92, +24, -56, -1, -187, -13, -265, -5, -259, +1, -177, -3, -45, -9, 93, -17, 189, +-29, 215, -49, 162, -57, 53, -40, -72, +-6, -161, 28, -186, 62, -142, 94, -43, +99, 75, 61, 170, 0, 205, -58, 168, +-97, 68, -110, -61, -94, -171, -45, -224, +24, -205, 90, -121, 130, 2, 138, 124, +111, 209, 50, 231, -31, 177, -99, 69, +-136, -54, -139, -153, -108, -204, -59, -195, +-1, -131, 51, -38, 85, 61, 92, 136, +84, 167, 71, 155, 53, 111, 30, 47, +6, -19, -13, -74, -27, -110, -43, -120, +-61, -112, -65, -85, -57, -49, -45, -2, +-33, 47, -15, 89, 15, 115, 45, 112, +62, 87, 71, 45, 75, -3, 62, -46, +33, -77, -3, -84, -25, -69, -36, -45, +-45, -16, -55, 5, -50, 12, -30, 5, +-14, -6, -2, -12, 19, -6, 43, 16, +49, 50, 39, 81, 28, 92, 22, 79, +10, 38, -4, -22, -13, -85, -16, -127, +-21, -139, -30, -118, -26, -66, -10, -3, +11, 54, 27, 88, 38, 97, 46, 88, +42, 64, 25, 37, 4, 18, -23, 13, +-52, 12, -77, 2, -90, -21, -78, -57, +-37, -95, 24, -122, 87, -127, 143, -98, +171, -32, 157, 50, 103, 124, 14, 168, +-86, 162, -167, 110, -217, 31, -223, -51, +-167, -115, -59, -136, 67, -102, 167, -33, +220, 47, 217, 105, 154, 118, 47, 81, +-64, 4, -137, -83, -156, -143, -126, -153, +-63, -104, 19, -14, 88, 84, 114, 158, +83, 179, 17, 143, -54, 57, -113, -49, +-143, -134, -121, -170, -47, -142, 48, -64, +135, 37, 190, 128, 198, 178, 150, 167, +57, 97, -49, -9, -133, -117, -181, -193, +-186, -214, -148, -180, -77, -102, 7, 0, +77, 92, 127, 160, 149, 192, 143, 181, +108, 137, 58, 74, 3, 5, -46, -57, +-83, -109, -105, -144, -110, -157, -97, -147, +-68, -109, -30, -55, 21, 11, 76, 83, +118, 144, 138, 174, 125, 166, 78, 121, +12, 47, -57, -39, -116, -113, -154, -158, +-155, -163, -110, -125, -43, -58, 29, 21, +98, 89, 150, 134, 162, 145, 129, 117, +72, 62, 11, -7, -47, -68, -92, -106, +-114, -121, -101, -111, -68, -77, -41, -28, +-17, 26, 10, 63, 37, 82, 51, 84, +55, 68, 64, 42, 73, 8, 64, -21, +39, -36, 8, -38, -25, -26, -59, -14, +-87, -1, -91, 9, -67, 4, -23, -6, +24, -18, 66, -25, 96, -21, 94, -11, +60, 3, 7, 7, -45, 1, -87, -9, +-104, -25, -81, -41, -23, -37, 45, -7, +106, 50, 138, 115, 131, 168, 89, 183, +16, 143, -69, 51, -143, -81, -182, -221, +-169, -326, -109, -357, -21, -294, 78, -148, +160, 47, 199, 243, 179, 385, 116, 434, +34, 373, -49, 221, -113, 22, -144, -171, +-131, -305, -83, -356, -23, -318, 30, -209, +68, -74, 81, 51, 60, 134, 17, 157, +-15, 134, -26, 92, -20, 53, 2, 35, +33, 40, 61, 61, 63, 76, 35, 63, +-5, 10, -44, -72, -78, -156, -98, -213, +-91, -218, -56, -160, -8, -56, 41, 71, +84, 185, 108, 252, 107, 253, 82, 183, +46, 72, 7, -47, -30, -145, -59, -193, +-82, -184, -95, -130, -94, -56, -80, 5, +-52, 45, -12, 60, 34, 53, 86, 41, +131, 32, 156, 41, 150, 62, 110, 79, +42, 79, -42, 49, -124, -7, -180, -77, +-194, -139, -165, -170, -98, -158, -8, -101, +89, -9, 156, 86, 181, 160, 164, 184, +110, 159, 32, 95, -52, 7, -105, -73, +-117, -130, -94, -144, -50, -117, 1, -63, +45, 4, 66, 62, 54, 93, 24, 100, +-10, 78, -37, 43, -53, 0, -54, -38, +-29, -60, 4, -75, 35, -76, 55, -69, +62, -51, 55, -18, 34, 22, 10, 62, +-3, 96, -10, 113, -13, 111, -18, 85, +-25, 35, -28, -23, -41, -80, -54, -116, +-62, -130, -57, -118, -36, -83, -3, -37, +42, 17, 91, 63, 129, 91, 146, 104, +134, 97, 89, 82, 21, 58, -61, 19, +-130, -22, -181, -64, -193, -94, -159, -110, +-92, -102, -7, -65, 79, -13, 150, 48, +185, 101, 171, 126, 121, 119, 54, 71, +-16, -6, -70, -79, -107, -133, -107, -145, +-77, -111, -43, -37, -10, 56, 12, 133, +15, 176, 0, 167, -20, 106, -26, 10, +-8, -91, 20, -161, 54, -177, 83, -145, +106, -73, 101, 9, 63, 81, 4, 122, +-64, 114, -118, 74, -152, 16, -145, -32, +-90, -54, -14, -42, 59, -3, 117, 43, +141, 73, 124, 73, 72, 30, 7, -38, +-54, -106, -97, -149, -106, -146, -82, -96, +-32, -4, 25, 100, 71, 184, 88, 221, +76, 189, 41, 102, -9, -14, -60, -132, +-84, -214, -82, -239, -59, -197, -12, -100, +35, 19, 76, 137, 91, 215, 81, 236, +52, 194, 7, 102, -33, -10, -60, -116, +-75, -188, -67, -207, -42, -180, -6, -113, +28, -24, 47, 61, 59, 128, 56, 157, +40, 153, 12, 115, -16, 56, -30, -3, +-34, -52, -34, -81, -27, -88, -13, -76, +-3, -51, -3, -26, -4, -10, 1, 4, +3, 8, 11, 15, 27, 24, 42, 35, +57, 51, 56, 62, 35, 63, 5, 39, +-29, -6, -64, -53, -93, -94, -100, -108, +-78, -85, -44, -40, 10, 25, 69, 83, +114, 121, 135, 123, 120, 80, 84, 13, +29, -66, -30, -128, -74, -155, -101, -137, +-104, -75, -85, 10, -57, 86, -20, 136, +14, 143, 40, 115, 58, 59, 64, -6, +69, -55, 65, -85, 54, -82, 37, -59, +9, -31, -25, -5, -55, 1, -77, -7, +-87, -16, -79, -22, -45, -12, 0, 12, +45, 42, 85, 70, 104, 78, 96, 70, +57, 37, 5, -7, -44, -49, -80, -82, +-92, -88, -80, -70, -48, -32, 1, 15, +45, 45, 74, 54, 92, 45, 81, 24, +48, 5, 2, -15, -35, -20, -61, -10, +-78, 2, -74, 14, -58, 14, -34, 5, +-4, -9, 22, -24, 48, -28, 71, -24, +83, -7, 85, 22, 67, 42, 43, 56, +7, 47, -41, 22, -83, -9, -113, -44, +-119, -66, -102, -70, -66, -52, -13, -22, +48, 7, 100, 30, 136, 42, 144, 35, +130, 30, 89, 25, 29, 25, -31, 32, +-92, 35, -134, 36, -152, 15, -146, -19, +-112, -63, -55, -106, 18, -121, 86, -106, +140, -61, 173, 10, 168, 82, 126, 143, +53, 167, -35, 139, -101, 74, -146, -12, +-157, -86, -127, -132, -64, -141, 13, -106, +78, -47, 114, 18, 119, 65, 82, 76, +23, 64, -37, 30, -76, -9, -74, -30, +-47, -31, 0, -5, 51, 26, 84, 49, +87, 56, 49, 35, -9, -1, -69, -41, +-121, -73, -133, -81, -99, -68, -29, -30, +58, 14, 135, 43, 186, 58, 180, 48, +118, 30, 23, 9, -83, -12, -165, -14, +-202, -7, -187, 7, -121, 21, -23, 17, +86, 5, 164, -13, 191, -31, 173, -38, +105, -40, 14, -25, -72, -7, -130, 7, +-142, 22, -115, 25, -54, 24, 14, 19, +65, 17, 94, 27, 79, 33, 29, 31, +-19, 20, -63, -7, -83, -35, -67, -67, +-18, -83, 49, -72, 106, -42, 143, 8, +134, 56, 78, 91, -6, 99, -103, 70, +-183, 19, -212, -42, -179, -90, -95, -101, +14, -75, 131, -13, 217, 56, 237, 106, +202, 126, 113, 93, -3, 25, -112, -60, +-189, -131, -214, -156, -183, -134, -104, -66, +-3, 24, 79, 105, 137, 157, 151, 155, +113, 101, 62, 18, 13, -70, -25, -120, +-44, -126, -35, -89, -11, -22, 2, 44, +7, 88, -3, 88, -35, 46, -63, -16, +-76, -84, -64, -122, -20, -110, 40, -56, +107, 34, 146, 116, 151, 172, 114, 175, +32, 114, -56, 19, -131, -88, -181, -167, +-177, -198, -119, -177, -27, -105, 69, -10, +149, 83, 193, 151, 170, 166, 108, 138, +24, 75, -71, 6, -141, -49, -169, -88, +-146, -91, -85, -72, -3, -45, 80, -16, +129, 0, 147, 8, 130, 13, 68, 8, +3, 7, -50, 4, -88, 10, -99, 21, +-87, 26, -50, 38, -13, 40, 19, 37, +43, 29, 47, 7, 40, -18, 27, -49, +8, -81, 1, -100, 2, -103, 8, -76, +12, -24, 8, 42, 5, 115, -15, 164, +-35, 181, -47, 156, -51, 89, -36, -2, +-4, -97, 31, -169, 65, -197, 81, -185, +79, -129, 47, -58, -7, 9, -53, 62, +-91, 86, -100, 98, -74, 98, -19, 100, +52, 111, 110, 115, 141, 108, 129, 73, +74, 4, -3, -88, -93, -191, -158, -267, +-174, -288, -152, -244, -82, -126, 12, 27, +108, 186, 178, 303, 193, 340, 160, 299, +88, 180, -2, 25, -82, -122, -135, -227, +-141, -256, -106, -217, -57, -131, 6, -26, +54, 54, 80, 101, 76, 97, 47, 56, +15, 11, -19, -28, -33, -37, -29, -18, +-14, 15, 16, 48, 42, 58, 49, 48, +42, 19, 23, -22, 3, -46, -24, -49, +-38, -24, -38, 22, -45, 59, -41, 76, +-35, 50, -33, -11, -24, -90, -10, -163, +12, -192, 41, -163, 74, -74, 109, 59, +117, 186, 109, 279, 81, 299, 19, 235, +-52, 111, -125, -52, -179, -199, -199, -294, +-172, -314, -100, -250, -10, -134, 93, 6, +187, 128, 229, 202, 225, 222, 176, 186, +84, 116, -24, 40, -127, -29, -187, -70, +-207, -91, -177, -87, -106, -68, -24, -58, +63, -50, 130, -45, 146, -35, 123, -12, +80, 16, 23, 53, -35, 92, -69, 107, +-58, 107, -34, 75, -1, 31, 38, -23, +50, -78, 39, -117, 9, -140, -33, -131, +-74, -94, -94, -38, -74, 29, -31, 90, +29, 133, 103, 150, 142, 134, 139, 97, +100, 36, 29, -37, -56, -95, -133, -132, +-169, -136, -162, -113, -115, -63, -28, 4, +55, 56, 123, 85, 173, 86, 170, 60, +126, 29, 58, -6, -11, -24, -74, -19, +-122, -5, -132, 22, -125, 36, -103, 31, +-57, 8, -14, -32, 26, -67, 74, -88, +112, -81, 131, -39, 130, 14, 123, 70, +89, 106, 20, 106, -42, 71, -102, 3, +-150, -65, -170, -116, -154, -133, -103, -102, +-35, -37, 43, 45, 112, 116, 148, 154, +161, 155, 138, 107, 86, 25, 38, -60, +-14, -133, -61, -166, -97, -162, -110, -119, +-105, -47, -95, 26, -61, 90, -13, 127, +32, 137, 80, 123, 111, 84, 118, 34, +106, -17, 63, -67, 4, -101, -65, -126, +-114, -123, -133, -92, -127, -43, -74, 26, +8, 88, 89, 136, 154, 158, 174, 138, +145, 84, 76, 3, -18, -84, -107, -151, +-177, -189, -194, -173, -165, -116, -101, -33, +-4, 61, 87, 132, 157, 172, 188, 167, +174, 130, 130, 72, 61, 6, -5, -46, +-58, -80, -103, -98, -116, -98, -116, -100, +-111, -93, -91, -80, -66, -63, -27, -23, +13, 28, 60, 90, 112, 148, 147, 179, +164, 178, 152, 131, 103, 44, 39, -56, +-46, -151, -127, -208, -178, -212, -197, -164, +-167, -69, -108, 31, -19, 119, 73, 165, +137, 162, 171, 123, 162, 52, 116, -20, +58, -73, -9, -102, -65, -93, -99, -68, +-100, -39, -75, -8, -47, 8, 1, 18, +39, 21, 52, 31, 53, 49, 34, 65, +7, 77, -13, 70, -23, 39, -20, -9, +-13, -67, 2, -116, 18, -145, 19, -148, +26, -106, 21, -44, 8, 31, 2, 99, +-6, 143, -11, 164, -14, 146, -9, 106, +-8, 51, -19, -10, -18, -62, -17, -103, +-19, -128, 5, -132, 39, -119, 70, -83, +87, -39, 88, 8, 68, 51, 10, 74, +-53, 86, -115, 80, -166, 58, -164, 34, +-117, 10, -40, -1, 73, 1, 184, 7, +256, 19, 257, 18, 198, 2, 85, -29, +-74, -79, -207, -119, -289, -142, -307, -128, +-243, -74, -114, 1, 43, 92, 181, 169, +274, 209, 299, 204, 233, 143, 122, 51, +-5, -52, -140, -142, -218, -189, -225, -191, +-174, -143, -85, -63, 24, 22, 118, 90, +159, 120, 156, 112, 114, 73, 32, 16, +-45, -29, -99, -54, -134, -50, -130, -20, +-88, 13, -19, 42, 44, 46, 102, 27, +149, -9, 149, -50, 120, -71, 71, -69, +0, -42, -67, 10, -120, 62, -155, 97, +-162, 96, -136, 59, -75, 4, -13, -67, +61, -118, 140, -135, 180, -113, 184, -47, +156, 32, 95, 106, 13, 155, -70, 158, +-134, 120, -174, 46, -178, -41, -135, -110, +-80, -150, -5, -144, 82, -106, 143, -44, +169, 28, 155, 82, 111, 111, 35, 101, +-49, 62, -105, 8, -136, -48, -131, -84, +-81, -85, -18, -57, 53, -2, 112, 54, +139, 94, 124, 103, 66, 74, -6, 19, +-89, -55, -145, -117, -149, -145, -113, -129, +-41, -68, 52, 18, 129, 103, 167, 164, +153, 166, 100, 117, 14, 27, -81, -80, +-137, -158, -160, -191, -132, -154, -60, -61, +24, 58, 101, 164, 143, 219, 137, 207, +86, 125, 8, -4, -63, -133, -113, -225, +-126, -249, -84, -192, -27, -84, 41, 49, +93, 160, 112, 216, 97, 204, 46, 128, +-14, 23, -69, -82, -100, -151, -92, -160, +-60, -112, -9, -27, 53, 64, 91, 122, +105, 138, 85, 101, 41, 30, -13, -55, +-61, -125, -85, -151, -94, -135, -81, -77, +-51, 2, -21, 75, 15, 123, 51, 132, +71, 105, 85, 58, 88, -1, 84, -43, +64, -61, 33, -54, 2, -21, -46, 10, +-88, 28, -115, 22, -132, -4, -129, -38, +-99, -75, -44, -99, 23, -96, 90, -65, +151, -6, 175, 61, 170, 121, 148, 159, +90, 161, 20, 131, -53, 68, -120, -6, +-173, -79, -199, -138, -185, -166, -144, -161, +-79, -124, 8, -62, 85, 5, 153, 66, +209, 107, 225, 122, 200, 114, 139, 78, +60, 32, -43, -15, -146, -52, -211, -71, +-243, -69, -228, -46, -159, -14, -64, 19, +40, 45, 140, 55, 208, 46, 230, 21, +205, -17, 151, -49, 58, -74, -51, -74, +-137, -52, -196, -23, -207, 16, -168, 54, +-92, 77, 1, 79, 91, 62, 160, 34, +183, 0, 157, -35, 113, -58, 36, -72, +-46, -69, -102, -48, -134, -15, -136, 21, +-106, 48, -44, 63, 15, 57, 58, 34, +91, 2, 94, -30, 73, -58, 57, -66, +33, -55, 3, -23, -20, 15, -33, 47, +-46, 66, -61, 60, -53, 39, -42, 7, +-34, -23, -7, -39, 20, -32, 31, -7, +46, 23, 53, 38, 49, 36, 27, 11, +3, -29, -19, -71, -41, -103, -33, -102, +-12, -68, 4, -3, 25, 73, 37, 135, +26, 169, -2, 157, -27, 102, -47, 22, +-65, -61, -59, -123, -33, -153, -5, -149, +35, -109, 68, -57, 87, -7, 87, 32, +73, 61, 42, 74, 2, 75, -24, 76, +-45, 81, -69, 78, -73, 61, -65, 26, +-65, -24, -60, -77, -46, -129, -14, -155, +22, -148, 70, -100, 120, -19, 138, 73, +136, 151, 109, 189, 49, 177, -22, 115, +-90, 22, -143, -75, -166, -149, -152, -181, +-96, -156, -32, -89, 41, -2, 108, 75, +133, 119, 130, 123, 99, 84, 48, 25, +-3, -37, -42, -76, -57, -81, -54, -53, +-36, -3, -7, 53, 9, 88, 20, 92, +27, 57, 12, -1, -11, -60, -39, -110, +-61, -127, -70, -114, -59, -71, -23, -13, +24, 45, 72, 94, 114, 124, 132, 124, +130, 103, 102, 63, 45, 22, -29, -19, +-103, -61, -154, -94, -179, -117, -160, -118, +-105, -103, -29, -71, 58, -27, 129, 22, +162, 70, 157, 106, 112, 120, 48, 111, +-17, 85, -67, 49, -89, 17, -91, -17, +-59, -38, -18, -56, 15, -71, 39, -80, +32, -88, 7, -90, -20, -78, -47, -45, +-51, 8, -34, 69, 4, 123, 57, 155, +85, 151, 99, 112, 81, 36, 35, -53, +-15, -130, -62, -172, -93, -163, -101, -109, +-79, -24, -32, 63, 20, 126, 66, 148, +96, 125, 87, 61, 62, -18, 26, -90, +-21, -125, -57, -119, -69, -77, -62, -16, +-43, 34, -6, 66, 26, 70, 40, 54, +46, 25, 44, 4, 26, -8, 9, 0, +-2, 19, -11, 37, -16, 39, -8, 18, +1, -19, -6, -68, -10, -107, -16, -127, +-30, -111, -35, -59, -24, 13, -5, 90, +15, 151, 37, 172, 61, 152, 61, 90, +52, 6, 38, -75, 1, -137, -31, -156, +-55, -137, -69, -85, -64, -15, -43, 55, +-8, 104, 19, 119, 39, 99, 56, 54, +38, 1, 6, -44, -16, -73, -35, -80, +-39, -60, -21, -29, 15, 5, 46, 32, +68, 51, 74, 53, 48, 42, 2, 25, +-42, 8, -87, -6, -112, -14, -96, -14, +-54, -18, 6, -22, 67, -32, 114, -43, +120, -53, 91, -56, 43, -46, -15, -21, +-67, 22, -91, 74, -83, 123, -56, 147, +-7, 138, 42, 92, 66, 18, 60, -76, +46, -164, 10, -221, -31, -225, -53, -174, +-52, -76, -31, 50, -1, 170, 37, 255, +51, 274, 45, 223, 30, 113, -4, -23, +-39, -153, -48, -235, -48, -253, -29, -206, +5, -110, 38, 8, 56, 115, 49, 176, +38, 184, 8, 146, -34, 79, -53, 1, +-54, -63, -41, -96, -9, -98, 21, -74, +44, -36, 48, -6, 36, 12, 14, 18, +-21, 14, -39, 11, -42, 11, -36, 22, +-11, 34, 20, 45, 39, 47, 44, 37, +36, 16, 14, -12, -18, -36, -44, -56, +-54, -65, -54, -63, -36, -46, -4, -24, +28, 4, 56, 27, 76, 52, 69, 70, +43, 78, 11, 74, -29, 51, -60, 14, +-72, -32, -71, -72, -55, -102, -23, -107, +12, -83, 44, -30, 62, 32, 69, 88, +57, 120, 29, 115, 1, 75, -30, 10, +-48, -56, -46, -108, -36, -121, -16, -93, +2, -33, 8, 36, 15, 97, 7, 124, +-1, 112, -4, 60, -4, -12, 5, -77, +14, -118, 27, -118, 40, -86, 40, -26, +27, 33, 5, 76, -24, 87, -43, 71, +-58, 37, -52, -2, -29, -32, -2, -43, +33, -33, 51, -14, 54, 6, 48, 11, +31, 1, 1, -20, -22, -39, -40, -49, +-46, -37, -40, -2, -21, 46, -2, 89, +15, 111, 33, 100, 38, 54, 33, -9, +22, -79, 11, -125, -9, -138, -24, -111, +-33, -54, -47, 17, -52, 79, -43, 113, +-24, 114, 5, 79, 42, 29, 74, -15, +88, -40, 79, -46, 64, -27, 21, 1, +-36, 25, -80, 27, -113, 6, -121, -30, +-100, -64, -56, -80, 0, -76, 53, -43, +98, 8, 117, 63, 103, 102, 81, 121, +39, 112, -17, 77, -49, 22, -64, -36, +-67, -83, -60, -105, -50, -99, -40, -81, +-31, -52, -13, -18, 3, 17, 15, 44, +41, 67, 66, 78, 78, 79, 84, 67, +73, 39, 41, 0, -4, -46, -53, -78, +-97, -94, -124, -88, -121, -59, -87, -7, +-42, 48, 14, 90, 75, 106, 118, 95, +128, 59, 115, 5, 81, -51, 24, -93, +-24, -106, -64, -93, -91, -55, -101, -14, +-80, 24, -52, 48, -25, 56, 10, 50, +41, 36, 51, 24, 58, 17, 62, 19, +49, 24, 40, 27, 27, 15, 15, -9, +-4, -43, -24, -71, -48, -92, -72, -93, +-86, -69, -82, -27, -66, 22, -29, 66, +28, 97, 79, 103, 127, 87, 145, 51, +141, 10, 96, -29, 21, -48, -63, -56, +-139, -52, -185, -38, -185, -21, -140, -7, +-68, -5, 30, -10, 118, -18, 174, -19, +188, -14, 165, 6, 103, 31, 20, 61, +-59, 86, -125, 97, -160, 84, -153, 42, +-117, -15, -72, -81, -21, -133, 22, -159, +54, -147, 85, -101, 113, -22, 132, 69, +136, 152, 115, 203, 72, 205, 8, 156, +-73, 59, -146, -57, -198, -164, -220, -224, +-191, -234, -113, -180, -3, -83, 113, 34, +209, 136, 259, 197, 244, 202, 177, 156, +73, 79, -48, -9, -140, -76, -187, -109, +-193, -102, -153, -70, -91, -27, -30, 0, +24, -1, 58, -24, 72, -54, 70, -71, +65, -61, 65, -11, 64, 66, 68, 147, +63, 198, 39, 201, -8, 141, -70, 29, +-122, -109, -142, -225, -135, -277, -90, -249, +-13, -148, 65, -4, 133, 140, 166, 234, +152, 255, 92, 188, 14, 66, -74, -73, +-137, -177, -156, -213, -129, -170, -65, -65, +14, 63, 88, 168, 128, 205, 134, 169, +99, 66, 41, -61, -29, -171, -77, -220, +-103, -197, -92, -105, -56, 23, -10, 138, +40, 204, 67, 201, 71, 136, 47, 27, +7, -87, -38, -170, -59, -193, -63, -157, +-41, -71, 1, 32, 45, 120, 73, 166, +83, 159, 77, 106, 40, 28, -4, -45, +-45, -100, -85, -115, -103, -101, -89, -59, +-58, -11, -18, 25, 28, 42, 60, 38, +68, 22, 62, 2, 47, -13, 28, -20, +12, -6, 0, 18, -9, 47, -13, 64, +-10, 64, -5, 44, -9, 11, -18, -30, +-27, -66, -34, -92, -36, -101, -25, -89, +0, -63, 25, -27, 43, 12, 56, 50, +45, 73, 20, 84, 2, 78, -19, 65, +-34, 51, -28, 36, -16, 24, -5, 5, +12, -13, 24, -38, 18, -63, 4, -93, +-8, -112, -30, -114, -44, -88, -37, -40, +-20, 27, 5, 96, 35, 145, 49, 166, +42, 146, 25, 94, -2, 14, -17, -65, +-31, -126, -31, -144, -17, -120, -1, -61, +15, 9, 35, 65, 39, 91, 24, 72, +5, 25, -22, -36, -44, -82, -57, -96, +-40, -68, -25, -6, 0, 73, 26, 136, +38, 159, 35, 128, 32, 50, 24, -50, +3, -144, 1, -193, -5, -190, -5, -128, +-2, -27, 2, 85, -3, 171, -6, 205, +-10, 177, -20, 105, -32, 9, -34, -86, +-21, -151, -5, -173, 15, -144, 19, -85, +18, -13, 14, 44, 5, 86, 8, 103, +13, 96, 17, 77, 30, 55, 31, 34, +19, 16, 7, -2, -15, -31, -44, -60, +-64, -89, -73, -104, -66, -101, -42, -74, +2, -29, 41, 27, 64, 80, 78, 116, +64, 125, 33, 103, 5, 63, -27, 15, +-52, -27, -49, -60, -36, -67, -14, -59, +10, -39, 25, -20, 32, -2, 22, 8, +3, 6, -16, 4, -37, -3, -52, -6, +-50, -8, -32, -5, -8, -1, 17, 12, +41, 26, 61, 39, 70, 46, 80, 50, +70, 47, 31, 27, -9, -5, -58, -49, +-105, -85, -125, -110, -115, -109, -85, -79, +-25, -20, 40, 46, 104, 104, 149, 136, +157, 131, 125, 90, 49, 19, -34, -55, +-114, -114, -164, -133, -168, -114, -126, -58, +-57, 13, 35, 76, 105, 113, 151, 115, +161, 84, 116, 30, 58, -23, -17, -63, +-86, -78, -124, -74, -126, -50, -112, -26, +-68, -8, -13, -2, 34, -1, 61, 1, +74, 9, 79, 28, 63, 55, 54, 84, +40, 95, 19, 81, -2, 41, -29, -13, +-63, -76, -73, -123, -74, -141, -66, -122, +-43, -68, -22, -1, 12, 64, 43, 105, +65, 112, 78, 83, 72, 35, 49, -21, +21, -57, -7, -62, -30, -38, -46, 1, +-50, 44, -45, 73, -44, 71, -25, 42, +2, -5, 8, -53, 25, -92, 35, -105, +22, -90, 12, -51, 5, -7, -6, 35, +-6, 63, 2, 72, 14, 68, 23, 56, +22, 45, 15, 32, -7, 22, -27, 3, +-41, -18, -55, -48, -52, -76, -35, -99, +-3, -103, 43, -79, 77, -30, 97, 37, +96, 97, 57, 139, 11, 136, -30, 95, +-75, 20, -94, -62, -98, -134, -86, -171, +-58, -158, -15, -95, 33, -1, 68, 102, +96, 187, 103, 222, 84, 202, 60, 119, +41, 6, -8, -113, -48, -205, -82, -253, +-113, -240, -117, -168, -96, -62, -53, 58, +6, 157, 67, 219, 109, 228, 132, 188, +112, 107, 74, 16, 8, -70, -55, -127, +-95, -149, -108, -134, -84, -93, -42, -42, +11, 8, 55, 37, 72, 46, 60, 33, +39, 14, -17, -5, -54, -6, -60, 8, +-52, 37, -12, 68, 38, 85, 65, 79, +70, 38, 54, -23, 12, -91, -39, -140, +-80, -160, -90, -134, -80, -66, -35, 28, +40, 116, 100, 178, 140, 189, 139, 144, +89, 58, 15, -49, -69, -142, -138, -197, +-168, -191, -165, -135, -117, -41, -33, 60, +47, 141, 123, 177, 167, 165, 161, 110, +125, 31, 64, -45, -1, -100, -61, -117, +-98, -101, -103, -59, -98, -16, -75, 24, +-39, 42, -23, 33, 0, 9, 27, -11, +29, -20, 45, -15, 61, 5, 60, 29, +57, 52, 44, 55, 26, 43, 5, 12, +-22, -20, -47, -47, -66, -56, -75, -44, +-61, -21, -34, 3, 4, 18, 35, 21, +43, 8, 52, -11, 39, -33, 27, -40, +21, -33, 1, -7, -17, 26, -16, 51, +-24, 65, -24, 61, -13, 39, -16, 2, +-8, -32, -7, -51, 3, -49, 15, -37, +37, -12, 54, 11, 55, 25, 46, 18, +32, -7, -6, -37, -50, -61, -79, -63, +-114, -46, -109, -8, -84, 37, -38, 81, +26, 110, 88, 115, 139, 88, 180, 43, +174, -13, 126, -66, 52, -102, -49, -120, +-134, -109, -199, -82, -218, -42, -194, -2, +-138, 35, -45, 58, 53, 70, 139, 72, +208, 70, 216, 60, 178, 47, 117, 36, +22, 23, -65, 11, -124, -13, -163, -39, +-163, -73, -138, -101, -91, -116, -33, -112, +25, -84, 80, -30, 112, 42, 121, 113, +117, 165, 90, 180, 50, 157, 0, 89, +-63, 1, -101, -97, -124, -170, -125, -196, +-84, -169, -34, -94, 25, 7, 92, 103, +127, 161, 124, 170, 93, 123, 27, 41, +-44, -53, -98, -119, -118, -142, -103, -113, +-63, -44, 3, 41, 53, 115, 79, 143, +91, 117, 56, 48, -3, -38, -53, -116, +-88, -154, -85, -140, -37, -74, 20, 19, +82, 112, 111, 165, 103, 165, 71, 114, +0, 25, -70, -68, -127, -138, -155, -157, +-144, -129, -85, -66, -3, 5, 83, 65, +137, 90, 169, 80, 151, 43, 93, 0, +36, -22, -43, -22, -104, 7, -130, 47, +-132, 82, -113, 79, -59, 42, -9, -27, +37, -106, 76, -169, 96, -188, 96, -154, +68, -69, 37, 43, -3, 144, -36, 211, +-48, 216, -46, 164, -40, 70, -23, -31, +-18, -113, -5, -155, 9, -148, 2, -99, +4, -33, -3, 24, -10, 60, 4, 63, +14, 41, 23, 1, 36, -29, 27, -45, +5, -31, -17, 1, -29, 39, -33, 69, +-34, 80, -17, 71, -3, 37, 4, -5, +24, -49, 21, -76, 7, -88, 0, -74, +-17, -50, -26, -17, -12, 20, 0, 49, +15, 65, 28, 64, 29, 51, 24, 26, +-2, 3, -27, -21, -42, -40, -44, -53, +-22, -51, 4, -43, 30, -25, 49, -9, +46, 5, 35, 23, 12, 34, -21, 44, +-32, 46, -42, 49, -48, 44, -20, 31, +2, 3, 20, -36, 35, -82, 26, -120, +-1, -135, -23, -121, -26, -75, -13, 0, +12, 96, 39, 176, 59, 223, 51, 217, +40, 152, 2, 42, -47, -84, -85, -197, +-113, -261, -110, -256, -72, -185, -18, -66, +45, 64, 105, 171, 123, 222, 127, 212, +89, 141, 35, 43, -20, -51, -70, -112, +-99, -125, -103, -97, -79, -43, -49, 12, +-24, 49, -2, 50, 17, 25, 13, -20, +23, -51, 21, -58, 16, -33, 35, 13, +54, 66, 65, 106, 70, 108, 50, 69, +6, -1, -44, -78, -95, -139, -120, -159, +-122, -131, -98, -56, -50, 35, 8, 122, +71, 172, 114, 169, 131, 122, 114, 36, +59, -55, -2, -129, -57, -161, -99, -148, +-105, -91, -81, -15, -53, 62, -3, 112, +42, 127, 63, 103, 70, 51, 53, -7, +16, -60, -27, -87, -54, -93, -66, -69, +-63, -26, -41, 24, -6, 65, 19, 93, +45, 92, 57, 69, 43, 26, 26, -29, +2, -76, -19, -110, -28, -116, -35, -98, +-28, -51, -13, 10, -5, 75, 8, 121, +16, 141, 8, 124, -7, 77, -25, 9, +-38, -62, -41, -113, -31, -140, -11, -126, +-1, -85, 20, -20, 38, 44, 43, 94, +50, 120, 52, 115, 27, 84, 4, 41, +-21, -2, -55, -45, -67, -78, -80, -95, +-82, -92, -79, -82, -52, -56, -14, -24, +32, 18, 74, 60, 111, 95, 123, 119, +107, 121, 72, 96, 12, 46, -42, -18, +-102, -82, -130, -128, -131, -152, -107, -138, +-55, -100, 9, -39, 55, 26, 93, 78, +109, 112, 79, 120, 36, 107, -18, 77, +-64, 45, -91, 10, -76, -21, -45, -49, +-12, -67, 28, -85, 61, -96, 70, -93, +70, -77, 53, -36, 5, 17, -37, 72, +-71, 111, -93, 128, -92, 114, -78, 71, +-53, 8, -22, -54, 11, -102, 50, -121, +87, -107, 110, -65, 112, -2, 87, 56, +36, 95, -26, 100, -84, 78, -127, 32, +-149, -18, -131, -57, -84, -72, -26, -65, +40, -39, 92, -6, 107, 20, 101, 31, +78, 24, 25, 15, -27, 0, -61, -6, +-76, -3, -68, 12, -38, 30, -5, 40, +13, 40, 17, 24, 6, -10, -10, -49, +-17, -77, -19, -89, -16, -74, -5, -39, +12, 11, 21, 56, 30, 89, 26, 96, +11, 74, -8, 36, -38, -8, -55, -45, +-50, -68, -39, -65, -26, -46, 0, -17, +19, 5, 37, 23, 44, 28, 45, 19, +30, 5, 10, -11, -10, -18, -41, -13, +-59, 4, -70, 20, -69, 31, -56, 30, +-23, 22, 5, 0, 39, -24, 62, -44, +64, -47, 52, -35, 25, -12, -6, 18, +-37, 43, -57, 62, -70, 59, -58, 34, +-33, -4, -3, -40, 19, -69, 30, -79, +20, -68, 4, -35, -5, 7, -21, 50, +-28, 83, -22, 90, -14, 76, -6, 40, +12, -5, 18, -50, 16, -78, 8, -84, +-12, -67, -28, -33, -34, 7, -32, 40, +-25, 60, -18, 62, -8, 45, -4, 21, +-2, -10, 4, -32, 5, -43, 7, -37, +4, -22, -2, -7, 1, 6, -4, 15, +-14, 17, -17, 14, -25, 15, -29, 18, +-24, 25, -22, 22, -14, 13, 2, -3, +11, -22, 5, -42, 1, -61, -3, -64, +-18, -46, -32, -9, -32, 41, -28, 89, +-16, 116, 2, 114, 8, 77, 15, 16, +18, -56, 11, -113, -8, -138, -29, -128, +-46, -81, -60, -13, -54, 57, -33, 106, +1, 123, 28, 104, 47, 60, 52, -1, +46, -51, 24, -80, -4, -78, -35, -50, +-65, -13, -81, 20, -78, 32, -57, 24, +-29, -4, 14, -36, 44, -55, 56, -46, +57, -11, 43, 41, 15, 89, -8, 119, +-31, 112, -51, 65, -51, -12, -46, -98, +-40, -161, -33, -184, -18, -152, -11, -75, +-5, 30, 1, 129, 7, 191, 14, 199, +22, 154, 31, 67, 29, -38, 17, -121, +-12, -165, -45, -155, -71, -108, -83, -33, +-78, 41, -57, 94, -30, 111, 7, 92, +42, 48, 60, -3, 71, -46, 60, -67, +26, -60, -15, -38, -48, -7, -72, 19, +-82, 38, -73, 44, -59, 41, -44, 32, +-15, 21, 11, 9, 27, -4, 40, -13, +37, -28, 26, -45, 19, -62, 6, -66, +-11, -60, -28, -32, -45, 8, -51, 55, +-52, 95, -44, 113, -29, 110, -15, 79, +0, 29, 8, -34, 20, -92, 22, -130, +8, -131, -14, -104, -32, -54, -43, 1, +-32, 53, -16, 93, 1, 108, 23, 103, +31, 70, 28, 25, 14, -19, -9, -52, +-49, -73, -79, -73, -96, -55, -90, -28, +-60, -3, -9, 19, 41, 31, 75, 27, +95, 15, 84, -4, 51, -12, -4, -10, +-61, 5, -104, 22, -117, 42, -108, 53, +-76, 49, -30, 25, 16, -16, 54, -59, +69, -93, 61, -102, 32, -88, 3, -45, +-31, 14, -52, 76, -62, 118, -64, 133, +-60, 114, -47, 64, -33, 2, -21, -58, +4, -99, 29, -112, 45, -92, 49, -52, +44, -5, 26, 29, 1, 43, -31, 38, +-70, 22, -100, 2, -115, -6, -109, 4, +-75, 24, -24, 49, 25, 68, 61, 70, +78, 41, 82, -9, 72, -70, 44, -117, +9, -142, -25, -131, -50, -82, -71, -8, +-85, 74, -83, 134, -79, 158, -65, 138, +-45, 82, -25, 5, 1, -65, 32, -116, +48, -133, 61, -113, 64, -64, 46, 1, +21, 59, -11, 98, -36, 107, -62, 89, +-80, 45, -79, -6, -71, -53, -53, -84, +-35, -96, -22, -79, -8, -44, 3, -2, +7, 38, 14, 67, 14, 82, 14, 75, +19, 56, 10, 23, 10, -11, 3, -37, +-12, -50, -27, -52, -36, -45, -43, -34, +-54, -21, -62, -11, -63, -6, -61, -4, +-48, -4, -15, 4, 2, 18, 35, 43, +55, 65, 61, 75, 57, 64, 37, 36, +1, -4, -43, -53, -80, -97, -102, -119, +-98, -107, -83, -69, -46, -9, -15, 52, +23, 99, 50, 112, 57, 92, 45, 51, +14, -1, -22, -46, -54, -70, -75, -64, +-78, -34, -59, 6, -49, 41, -27, 62, +-3, 49, 19, 14, 31, -30, 29, -65, +21, -82, 8, -76, -1, -36, -18, 19, +-35, 72, -46, 101, -54, 104, -70, 74, +-73, 21, -62, -39, -46, -85, -21, -107, +4, -98, 27, -63, 45, -13, 53, 39, +50, 74, 38, 86, 19, 71, -13, 42, +-47, 6, -73, -24, -89, -42, -97, -43, +-96, -34, -83, -19, -56, -4, -24, 1, +1, -1, 33, -11, 60, -16, 71, -21, +68, -13, 54, 10, 24, 39, -9, 60, +-36, 71, -61, 69, -83, 46, -95, 6, +-100, -39, -101, -78, -81, -108, -54, -116, +-23, -99, 12, -55, 42, 2, 67, 63, +75, 112, 73, 135, 58, 126, 29, 88, +-8, 35, -55, -23, -90, -72, -110, -100, +-114, -97, -108, -73, -90, -36, -69, 0, +-29, 26, 6, 30, 36, 15, 68, -3, +75, -19, 76, -21, 64, -5, 43, 31, +7, 73, -41, 103, -90, 101, -123, 74, +-148, 19, -141, -56, -114, -126, -66, -167, +7, -166, 64, -126, 114, -46, 132, 46, +119, 123, 70, 164, -1, 165, -86, 122, +-145, 51, -180, -23, -176, -78, -132, -102, +-62, -98, 26, -67, 92, -26, 142, 11, +145, 29, 105, 28, 32, 13, -57, -4, +-133, -17, -171, -11, -182, 13, -156, 40, +-89, 59, -15, 64, 55, 49, 102, 9, +120, -40, 108, -80, 70, -96, 11, -86, +-48, -46, -98, 9, -121, 64, -131, 99, +-120, 104, -84, 79, -53, 28, -14, -34, +25, -85, 55, -106, 75, -98, 73, -61, +53, -3, 21, 59, -23, 101, -70, 112, +-104, 91, -122, 43, -113, -18, -86, -74, +-49, -106, 0, -110, 41, -81, 68, -29, +65, 32, 38, 82, 6, 111, -38, 111, +-68, 82, -80, 34, -86, -22, -74, -70, +-54, -105, -25, -116, 6, -102, 24, -59, +29, -7, 17, 44, 4, 84, -5, 106, +-18, 105, -28, 79, -35, 40, -40, -7, +-42, -50, -52, -81, -62, -87, -56, -80, +-45, -62, -31, -37, -13, -2, 1, 31, +21, 53, 31, 65, 32, 67, 23, 63, +-2, 48, -32, 30, -65, 4, -77, -25, +-82, -51, -82, -69, -67, -80, -37, -77, +-6, -58, 17, -22, 26, 22, 26, 58, +22, 85, 0, 96, -27, 88, -53, 55, +-58, 13, -57, -29, -47, -64, -27, -85, +-7, -85, 7, -62, 9, -27, -4, 6, +-20, 31, -36, 49, -67, 51, -74, 41, +-73, 21, -48, 1, -19, -17, 10, -25, +36, -20, 47, -8, 44, 7, 17, 22, +-19, 32, -49, 28, -73, 15, -103, -6, +-104, -23, -89, -42, -61, -55, -23, -58, +10, -47, 39, -22, 59, 11, 56, 45, +44, 72, 20, 81, -20, 72, -58, 51, +-100, 17, -111, -21, -109, -58, -92, -75, +-60, -75, -25, -61, 22, -36, 57, -7, +69, 19, 66, 34, 42, 40, -4, 38, +-47, 30, -89, 20, -109, 14, -101, 10, +-86, 7, -57, -2, -24, -14, 11, -27, +38, -44, 42, -51, 38, -45, 16, -21, +-22, 8, -46, 40, -64, 65, -68, 72, +-60, 48, -49, 10, -30, -32, -12, -70, +0, -89, 4, -78, -2, -35, -11, 21, +-22, 75, -43, 107, -50, 107, -47, 71, +-42, 9, -30, -59, -23, -111, -11, -133, +-4, -113, -5, -57, 3, 15, -4, 85, +-14, 124, -22, 129, -38, 93, -48, 34, +-57, -29, -64, -79, -65, -101, -58, -91, +-37, -55, -16, -7, 3, 35, 24, 53, +37, 53, 30, 31, 9, 3, -31, -17, +-65, -18, -86, -2, -98, 23, -90, 50, +-68, 66, -29, 55, 14, 15, 46, -36, +62, -88, 49, -124, 8, -131, -41, -98, +-87, -36, -108, 39, -114, 106, -95, 152, +-51, 162, -1, 124, 48, 61, 73, -13, +76, -80, 55, -128, 18, -138, -41, -114, +-86, -67, -114, -13, -120, 38, -110, 70, +-91, 72, -56, 48, -22, 12, 16, -17, +43, -32, 55, -22, 57, 12, 47, 55, +24, 85, 4, 99, -32, 82, -72, 33, +-113, -43, -142, -121, -144, -172, -131, -189, +-91, -156, -35, -77, 36, 34, 93, 137, +128, 207, 123, 234, 89, 210, 19, 130, +-63, 16, -132, -96, -188, -178, -189, -215, +-157, -200, -92, -133, -5, -43, 67, 45, +109, 112, 112, 145, 81, 134, 32, 92, +-40, 39, -100, -9, -130, -43, -133, -56, +-103, -46, -63, -26, -16, -8, 30, -6, +51, -10, 43, -22, 20, -33, -14, -34, +-35, -16, -51, 16, -64, 46, -57, 70, +-50, 79, -36, 65, -28, 23, -23, -27, +-15, -75, -28, -103, -31, -106, -26, -75, +-17, -20, -1, 44, 0, 99, -2, 126, +-4, 122, -22, 83, -52, 23, -70, -42, +-80, -99, -72, -138, -59, -138, -41, -101, +-6, -40, 24, 26, 44, 89, 43, 134, +17, 143, -10, 118, -50, 67, -83, 5, +-98, -58, -105, -108, -85, -129, -55, -117, +-19, -81, 23, -26, 47, 30, 54, 70, +45, 87, 20, 82, -19, 62, -63, 27, +-92, -7, -104, -27, -99, -32, -81, -29, +-51, -17, -24, -4, 13, 1, 33, -7, +31, -22, 25, -28, -1, -27, -17, -17, +-36, 3, -42, 38, -44, 65, -50, 76, +-55, 66, -55, 35, -55, -8, -56, -55, +-55, -90, -43, -97, -21, -78, -5, -43, +18, 10, 26, 59, 30, 91, 20, 93, +-6, 71, -41, 33, -59, -10, -69, -39, +-69, -49, -60, -42, -51, -27, -37, -8, +-42, 4, -35, 1, -41, -20, -37, -41, +-28, -51, -18, -41, 8, -14, 43, 31, +68, 83, 68, 121, 44, 133, -7, 110, +-71, 54, -142, -26, -184, -106, -187, -164, +-155, -181, -92, -162, -13, -99, 66, -5, +129, 87, 149, 153, 130, 180, 73, 169, +-6, 114, -74, 39, -136, -37, -157, -94, +-145, -130, -116, -131, -69, -103, -24, -57, +17, -11, 35, 27, 33, 56, 23, 66, +5, 61, -11, 46, -24, 33, -30, 20, +-28, 5, -18, -7, -27, -17, -37, -31, +-45, -40, -57, -42, -57, -38, -61, -27, +-52, -9, -39, 20, -28, 46, -10, 62, +0, 62, 10, 48, 12, 18, 2, -23, +-5, -58, -16, -79, -27, -82, -39, -63, +-54, -23, -59, 25, -64, 70, -72, 97, +-65, 104, -41, 83, -19, 37, 2, -20, +10, -69, 15, -102, 18, -114, 5, -98, +-6, -57, -29, -1, -48, 50, -56, 93, +-70, 116, -59, 113, -51, 78, -42, 31, +-36, -18, -34, -65, -27, -97, -22, -106, +-14, -90, -2, -62, 18, -23, 26, 18, +28, 59, 10, 84, -10, 92, -40, 86, +-88, 65, -124, 28, -142, -13, -127, -45, +-88, -69, -37, -83, 30, -81, 90, -57, +112, -23, 117, 11, 82, 41, 25, 66, +-55, 71, -129, 57, -171, 29, -179, -2, +-147, -32, -96, -52, -22, -51, 45, -38, +96, -19, 103, 6, 88, 29, 49, 38, +-4, 33, -60, 18, -112, -3, -125, -26, +-113, -41, -84, -40, -44, -25, -9, -1, +18, 20, 33, 36, 30, 42, 23, 37, +-2, 22, -24, 4, -47, -15, -67, -33, +-70, -40, -71, -37, -61, -30, -44, -23, +-19, -7, -5, 10, 6, 29, 9, 44, +16, 56, 19, 58, 5, 45, -14, 21, +-46, -6, -67, -39, -79, -77, -86, -100, +-74, -98, -61, -75, -30, -40, 1, 17, +23, 76, 43, 119, 41, 133, 22, 120, +-8, 86, -43, 27, -70, -38, -88, -89, +-87, -117, -68, -124, -41, -105, -18, -65, +2, -14, 11, 30, 14, 61, -2, 80, +-33, 82, -49, 70, -55, 48, -44, 27, +-22, 5, -6, -11, 12, -26, 14, -37, +4, -47, -17, -55, -47, -58, -69, -49, +-90, -30, -94, -6, -71, 22, -35, 47, +5, 65, 39, 66, 63, 58, 60, 36, +35, 1, -12, -30, -47, -51, -79, -66, +-100, -65, -101, -44, -96, -12, -59, 17, +-20, 38, 11, 54, 29, 53, 33, 35, +28, 6, 6, -16, -19, -30, -33, -36, +-49, -31, -51, -14, -47, 8, -45, 26, +-40, 37, -44, 36, -42, 20, -40, -11, +-32, -37, -31, -54, -15, -53, 3, -37, +28, -7, 39, 31, 23, 63, 0, 84, +-42, 81, -71, 54, -100, 8, -110, -37, +-99, -70, -75, -85, -31, -83, 19, -58, +58, -17, 75, 24, 62, 54, 26, 66, +-19, 62, -65, 41, -96, 11, -105, -13, +-85, -26, -52, -31, -19, -21, 5, -3, +26, 14, 22, 20, 1, 14, -28, -1, +-59, -21, -63, -38, -62, -47, -37, -41, +-5, -26, 21, -2, 37, 28, 26, 56, +5, 71, -25, 68, -58, 53, -83, 29, +-95, -3, -84, -39, -61, -62, -32, -73, +-6, -69, 18, -54, 24, -28, 18, 0, +6, 27, -9, 49, -9, 62, -13, 62, +-18, 47, -19, 26, -26, 2, -33, -19, +-53, -39, -67, -49, -75, -46, -84, -33, +-76, -16, -56, 4, -18, 21, 24, 31, +53, 34, 73, 31, 72, 23, 47, 7, +4, -7, -42, -21, -83, -33, -108, -44, +-120, -44, -113, -30, -80, -7, -40, 19, +5, 46, 31, 67, 45, 74, 52, 63, +29, 39, 6, 6, -28, -41, -46, -87, +-52, -114, -58, -111, -51, -86, -40, -40, +-28, 23, -24, 78, -23, 117, -23, 132, +-22, 120, -20, 78, -9, 22, 3, -34, +6, -75, -2, -102, -18, -108, -35, -91, +-48, -64, -66, -37, -71, -8, -66, 27, +-54, 55, -14, 73, 16, 84, 50, 89, +63, 83, 56, 65, 25, 36, -19, -6, +-55, -55, -96, -97, -122, -126, -124, -135, +-98, -116, -66, -72, -21, -6, 22, 63, +60, 117, 84, 146, 77, 151, 45, 129, +6, 77, -31, 5, -59, -65, -88, -117, +-103, -148, -93, -143, -78, -106, -47, -47, +-24, 19, 5, 82, 17, 123, 15, 130, +13, 103, -2, 53, -11, -4, -21, -62, +-25, -98, -25, -101, -17, -76, -12, -32, +-6, 23, -1, 66, -8, 85, -27, 73, +-56, 36, -74, -11, -78, -58, -74, -90, +-49, -90, -19, -55, 17, -2, 50, 57, +61, 99, 60, 113, 33, 91, -6, 38, +-52, -26, -94, -86, -113, -121, -108, -126, +-77, -94, -34, -35, 14, 31, 51, 88, +66, 123, 58, 120, 32, 83, -5, 29, +-55, -25, -88, -67, -104, -88, -94, -81, +-61, -57, -30, -28, 11, -2, 43, 17, +55, 27, 49, 24, 24, 17, -1, 14, +-36, 13, -60, 19, -72, 31, -77, 41, +-65, 42, -49, 24, -31, -2, -15, -34, +0, -63, 3, -80, 4, -74, 4, -50, +1, -16, -1, 22, -12, 58, -15, 80, +-14, 80, -17, 63, -20, 29, -28, -11, +-29, -48, -31, -67, -37, -66, -36, -49, +-39, -22, -34, 11, -34, 39, -31, 49, +-20, 47, -16, 34, -2, 8, 10, -24, +26, -40, 19, -41, 14, -28, 5, -13, +-5, 10, -20, 32, -49, 42, -71, 37, +-86, 18, -78, -3, -67, -23, -52, -32, +-28, -30, -2, -17, 31, -6, 55, 5, +64, 11, 64, 12, 39, 8, 5, -2, +-33, -7, -68, -6, -87, 1, -99, 12, +-88, 24, -71, 26, -44, 19, -18, 0, +12, -22, 31, -43, 37, -54, 33, -47, +15, -24, 7, 12, -5, 44, -11, 70, +-20, 79, -39, 64, -50, 29, -62, -17, +-65, -59, -60, -85, -48, -84, -26, -56, +-6, -16, 20, 27, 35, 64, 39, 79, +33, 67, 9, 34, -21, -6, -53, -43, +-71, -62, -78, -60, -58, -37, -24, -2, +4, 34, 27, 55, 32, 54, 31, 35, +10, -2, -17, -38, -42, -63, -62, -67, +-61, -49, -51, -12, -29, 31, -1, 64, +16, 78, 22, 70, 10, 41, -9, -4, +-27, -48, -41, -77, -40, -82, -28, -68, +-3, -36, 14, 6, 28, 46, 26, 69, +11, 69, -21, 56, -62, 26, -83, -13, +-86, -44, -62, -60, -34, -60, 5, -42, +43, -16, 63, 13, 67, 31, 46, 38, +9, 36, -32, 21, -66, 1, -81, -18, +-78, -28, -52, -31, -20, -24, 5, -9, +18, 10, 12, 22, 2, 29, -17, 30, +-29, 26, -40, 16, -42, 1, -31, -12, +-13, -25, 19, -36, 31, -44, 36, -40, +19, -28, -11, -10, -35, 8, -55, 33, +-61, 57, -57, 70, -37, 68, -17, 51, +-7, 24, 1, -15, 3, -54, -1, -87, +-7, -99, -17, -89, -24, -60, -21, -19, +-4, 30, 9, 76, 24, 105, 29, 108, +15, 88, -8, 56, -46, 14, -69, -26, +-90, -60, -90, -79, -73, -82, -46, -72, +-7, -55, 29, -33, 64, -10, 83, 9, +80, 27, 59, 47, 22, 64, -18, 73, +-54, 75, -80, 69, -96, 51, -97, 15, +-85, -31, -67, -76, -34, -109, -1, -125, +28, -114, 48, -76, 59, -20, 67, 43, +53, 98, 36, 133, 1, 139, -34, 119, +-65, 74, -92, 14, -99, -45, -98, -90, +-78, -112, -44, -115, -1, -96, 41, -62, +71, -17, 87, 26, 80, 56, 57, 74, +16, 82, -31, 75, -67, 55, -90, 30, +-100, 2, -101, -23, -83, -47, -49, -62, +-8, -62, 37, -50, 62, -32, 79, -3, +73, 30, 50, 52, 19, 58, -14, 49, +-39, 24, -64, -7, -78, -35, -89, -52, +-84, -51, -60, -39, -27, -14, 11, 19, +38, 46, 56, 61, 58, 58, 52, 37, +37, 7, 10, -24, -15, -48, -46, -58, +-71, -54, -77, -36, -74, -9, -52, 18, +-28, 36, 1, 43, 17, 39, 25, 26, +26, 8, 16, -7, 13, -17, -2, -17, +-11, -11, -19, -4, -16, 4, -14, 9, +-12, 10, -6, 4, -13, -3, -26, -12, +-39, -25, -47, -31, -39, -30, -26, -25, +-7, -9, 15, 12, 37, 32, 55, 48, +52, 55, 40, 54, 4, 40, -31, 16, +-61, -17, -85, -51, -87, -73, -79, -81, +-49, -73, -18, -47, 18, -9, 41, 30, +57, 64, 63, 86, 47, 91, 24, 75, +2, 43, -13, 5, -25, -29, -35, -58, +-47, -75, -61, -77, -67, -72, -66, -58, +-52, -38, -29, -12, -6, 16, 32, 45, +59, 73, 78, 90, 86, 93, 76, 84, +49, 61, -6, 21, -56, -29, -107, -81, +-129, -121, -120, -142, -90, -130, -46, -90, +2, -28, 45, 44, 68, 109, 77, 153, +65, 164, 38, 138, 13, 78, -15, 2, +-32, -72, -40, -129, -36, -155, -22, -142, +-20, -93, -23, -27, -34, 41, -38, 93, +-33, 114, -25, 106, -6, 76, 8, 27, +26, -24, 38, -66, 43, -85, 32, -81, +16, -55, -3, -17, -33, 22, -49, 51, +-53, 62, -44, 59, -23, 42, -6, 15, +10, -11, 17, -28, 18, -38, 10, -42, +-4, -38, -13, -31, -25, -23, -23, -16, +-13, -8, -4, 4, 4, 22, 5, 40, +5, 54, -4, 60, -6, 55, -15, 40, +-11, 14, -5, -17, -7, -45, -7, -67, +-10, -76, -8, -66, -15, -45, -24, -15, +-35, 14, -41, 35, -29, 49, -12, 55, +9, 52, 35, 44, 51, 33, 55, 20, +44, 6, 19, -11, -12, -29, -36, -50, +-54, -64, -74, -71, -74, -66, -64, -48, +-31, -19, 6, 22, 34, 64, 51, 94, +53, 104, 47, 90, 24, 55, 8, 7, +-10, -42, -26, -80, -31, -101, -34, -100, +-34, -73, -34, -31, -25, 14, -15, 48, +-6, 65, 5, 67, 5, 54, 15, 33, +24, 9, 26, -12, 28, -26, 18, -30, +3, -26, -23, -18, -43, -14, -52, -15, +-47, -17, -27, -20, -7, -20, 21, -14, +46, -4, 61, 12, 55, 31, 32, 43, +-3, 48, -41, 46, -69, 35, -90, 11, +-86, -16, -58, -41, -22, -59, 27, -67, +66, -62, 88, -46, 89, -22, 70, 11, +32, 44, -13, 65, -41, 72, -63, 68, +-70, 49, -63, 19, -55, -13, -41, -41, +-25, -59, -2, -64, 5, -57, 17, -40, +23, -16, 32, 9, 51, 29, 62, 41, +65, 44, 53, 38, 24, 26, -20, 11, +-68, -2, -104, -13, -120, -17, -106, -16, +-77, -14, -38, -9, 15, -7, 64, -8, +109, -13, 129, -17, 117, -16, 73, -11, +15, -3, -36, 8, -86, 20, -101, 35, +-101, 43, -78, 40, -44, 28, -14, 11, +15, -12, 40, -38, 63, -56, 63, -64, +48, -58, 26, -39, -3, -8, -21, 25, +-33, 55, -39, 72, -33, 69, -24, 53, +-15, 25, -6, -11, 13, -46, 24, -69, +34, -76, 37, -66, 13, -38, -4, -3, +-23, 28, -33, 53, -40, 67, -40, 66, +-35, 52, -22, 28, 2, -1, 15, -29, +32, -51, 44, -61, 46, -60, 38, -49, +21, -28, 0, -4, -24, 19, -32, 36, +-38, 47, -40, 49, -29, 46, -22, 35, +-13, 17, -4, -3, -1, -23, 9, -40, +21, -50, 34, -50, 29, -41, 25, -24, +15, -3, 4, 16, 2, 27, -6, 31, +-14, 31, -22, 25, -25, 16, -32, 6, +-26, -1, -13, -5, -5, -5, 11, -6, +11, -8, 3, -8, 2, -13, 6, -19, +12, -21, 12, -20, 12, -15, 6, -7, +5, 3, 9, 14, 3, 24, 5, 31, +-1, 31, -9, 27, -24, 20, -37, 11, +-38, -3, -30, -16, -12, -27, -10, -34, +-5, -36, 1, -36, 10, -31, 28, -20, +42, -2, 47, 25, 43, 49, 33, 69, +14, 77, -11, 71, -29, 49, -52, 11, +-69, -32, -82, -73, -87, -102, -65, -110, +-28, -97, 23, -60, 64, -8, 98, 50, +115, 99, 104, 131, 80, 138, 26, 116, +-26, 69, -74, 3, -103, -65, -113, -122, +-96, -154, -62, -150, -24, -114, 24, -60, +53, 6, 67, 69, 74, 115, 62, 138, +40, 133, 14, 100, -5, 51, -17, -4, +-20, -54, -18, -89, -28, -103, -29, -97, +-33, -74, -37, -41, -32, -5, -26, 26, +-5, 47, 19, 55, 48, 54, 60, 46, +69, 32, 64, 18, 38, 6, 2, -8, +-44, -21, -81, -28, -99, -32, -88, -34, +-57, -30, -17, -20, 32, -6, 68, 9, +95, 22, 101, 32, 76, 36, 41, 36, +-8, 28, -59, 10, -94, -12, -105, -30, +-95, -38, -64, -40, -16, -36, 21, -23, +56, -4, 79, 17, 89, 36, 81, 51, +57, 58, 24, 56, -21, 42, -53, 18, +-81, -14, -91, -47, -76, -73, -57, -85, +-24, -83, 9, -59, 38, -21, 67, 24, +84, 68, 78, 100, 52, 111, 24, 95, +-11, 58, -42, 9, -60, -44, -71, -86, +-56, -113, -29, -114, 7, -87, 28, -39, +44, 13, 49, 59, 31, 91, 11, 100, +-21, 86, -38, 54, -37, 12, -25, -27, +-6, -55, 12, -67, 35, -63, 48, -47, +51, -27, 37, -7, 3, 11, -25, 22, +-50, 25, -60, 26, -52, 26, -35, 24, +-5, 21, 20, 18, 37, 15, 31, 9, +32, -6, 28, -21, 12, -33, -2, -41, +-18, -42, -20, -32, -14, -14, 2, 6, +9, 26, 12, 40, 7, 46, -13, 41, +-23, 27, -30, 11, -30, -6, -15, -19, +2, -24, 12, -21, 16, -13, 25, -6, +31, 2, 26, 7, 13, 10, -15, 6, +-27, -2, -31, -9, -22, -14, -4, -14, +14, -7, 27, 2, 25, 10, 19, 18, +-6, 25, -25, 29, -37, 29, -50, 26, +-47, 14, -28, -4, 2, -18, 34, -29, +65, -41, 79, -47, 72, -46, 52, -38, +15, -22, -28, 2, -65, 31, -87, 54, +-82, 67, -59, 72, -29, 66, -3, 45, +32, 13, 54, -23, 55, -55, 55, -78, +35, -87, 22, -76, 7, -52, -6, -16, +-19, 24, -26, 55, -20, 71, -18, 71, +-19, 57, -29, 36, -39, 10, -35, -13, +-20, -24, 1, -28, 27, -20, 51, -8, +62, 0, 62, 1, 45, -4, 12, -14, +-13, -30, -39, -43, -63, -44, -76, -30, +-72, -6, -39, 26, 0, 59, 42, 84, +64, 93, 68, 87, 56, 62, 23, 21, +-3, -28, -25, -73, -37, -109, -36, -125, +-31, -117, -28, -84, -19, -36, 2, 18, +15, 72, 19, 113, 14, 132, 3, 125, +6, 96, 14, 54, 25, 1, 32, -50, +33, -87, 17, -104, -19, -104, -41, -92, +-63, -65, -63, -33, -47, -1, -25, 31, +3, 56, 35, 75, 70, 85, 88, 85, +92, 74, 63, 52, 20, 17, -22, -28, +-62, -72, -86, -105, -89, -120, -74, -109, +-45, -74, -9, -23, 28, 36, 55, 91, +77, 127, 80, 134, 60, 111, 36, 58, +1, -11, -23, -75, -46, -119, -56, -132, +-58, -113, -43, -64, -15, 0, 1, 60, +21, 103, 29, 115, 33, 95, 34, 49, +28, -8, 13, -58, 0, -88, -9, -90, +-18, -66, -19, -25, -15, 23, -12, 61, +0, 78, 6, 67, 6, 37, 4, -2, +2, -39, 7, -62, 5, -67, 9, -53, +1, -23, -4, 11, -2, 37, -7, 52, +-4, 53, -5, 45, -5, 27, -9, 5, +-5, -15, -3, -30, 8, -33, 25, -32, +28, -25, 24, -17, 10, -13, -8, -7, +-19, -1, -26, 7, -30, 19, -34, 29, +-23, 34, -10, 34, 3, 25, 25, 13, +36, -4, 47, -23, 45, -38, 28, -46, +10, -42, -5, -29, -15, -4, -30, 23, +-36, 40, -41, 42, -35, 32, -19, 12, +0, -14, 20, -37, 35, -45, 45, -37, +38, -19, 27, 7, 14, 32, -5, 46, +-10, 46, -21, 34, -33, 13, -33, -11, +-25, -34, -6, -44, 9, -37, 19, -17, +22, 5, 26, 21, 28, 27, 13, 18, +3, 0, -14, -21, -24, -38, -31, -44, +-27, -33, -18, -6, -1, 33, 17, 71, +22, 93, 32, 87, 36, 59, 30, 12, +21, -46, 6, -98, -15, -126, -36, -124, +-46, -90, -46, -36, -38, 26, -18, 81, +-2, 118, 17, 126, 36, 102, 46, 54, +54, 3, 48, -42, 36, -72, 10, -87, +-9, -80, -33, -57, -45, -25, -47, 5, +-49, 24, -40, 31, -27, 29, -4, 21, +18, 16, 40, 15, 54, 17, 55, 21, +51, 23, 31, 17, 4, 5, -14, -15, +-32, -34, -45, -47, -53, -50, -52, -45, +-34, -31, -4, -9, 31, 18, 48, 43, +60, 58, 51, 58, 33, 46, 8, 24, +-21, -4, -40, -34, -45, -55, -35, -58, +-26, -50, -2, -31, 22, -8, 37, 15, +49, 33, 36, 42, 16, 38, -2, 25, +-18, 7, -29, -10, -35, -23, -25, -29, +-10, -29, 13, -22, 32, -10, 33, 0, +30, 9, 19, 14, 2, 16, -17, 15, +-26, 11, -27, 4, -15, -3, -1, -7, +3, -10, 15, -11, 20, -10, 19, -6, +8, 1, -15, 11, -33, 18, -41, 20, +-28, 21, -10, 20, 6, 17, 26, 8, +32, -6, 34, -19, 28, -28, 9, -31, +-5, -27, -14, -17, -25, -1, -38, 16, +-37, 31, -29, 36, -5, 29, 21, 16, +27, 1, 31, -14, 27, -26, 27, -24, +16, -15, 11, -1, 6, 11, -7, 18, +-16, 18, -33, 11, -46, -2, -43, -17, +-35, -27, -17, -30, 2, -21, 23, -2, +46, 20, 69, 36, 80, 46, 66, 45, +36, 31, -11, 4, -54, -25, -87, -48, +-102, -60, -92, -57, -60, -38, -7, -9, +34, 23, 76, 50, 97, 63, 99, 57, +82, 37, 43, 13, -7, -10, -51, -29, +-76, -38, -89, -34, -78, -24, -47, -13, +-13, -2, 19, 5, 39, 8, 40, 6, +40, -1, 36, -5, 28, 2, 17, 15, +15, 27, 10, 40, 0, 45, -9, 34, +-23, 8, -28, -23, -39, -52, -45, -70, +-46, -74, -35, -57, -13, -22, 16, 20, +56, 58, 77, 85, 84, 90, 74, 70, +42, 34, 1, -11, -37, -57, -64, -88, +-77, -93, -74, -76, -62, -40, -38, 4, +1, 43, 41, 71, 70, 82, 80, 71, +71, 42, 52, 7, 26, -28, 5, -51, +-23, -59, -38, -56, -47, -48, -55, -31, +-53, -7, -50, 13, -29, 27, 4, 38, +29, 50, 46, 56, 54, 52, 61, 39, +57, 17, 46, -12, 22, -40, -14, -68, +-45, -86, -66, -87, -74, -65, -67, -26, +-40, 18, -6, 60, 28, 89, 54, 100, +59, 87, 60, 54, 47, 9, 27, -37, +4, -70, -22, -83, -36, -77, -40, -56, +-32, -26, -21, 2, -7, 22, 4, 32, +7, 30, 8, 18, 12, 8, 15, 5, +17, 10, 22, 21, 23, 30, 22, 28, +23, 16, 10, -5, -8, -35, -24, -66, +-38, -88, -38, -89, -35, -68, -19, -26, +-1, 29, 18, 83, 36, 121, 41, 131, +42, 109, 29, 58, 14, -8, -4, -73, +-20, -121, -31, -141, -29, -127, -21, -84, +-13, -21, -4, 40, -2, 86, 4, 109, +15, 103, 22, 74, 27, 30, 29, -16, +29, -48, 25, -60, 9, -52, -3, -32, +-21, -10, -32, 8, -41, 15, -47, 10, +-35, -1, -15, -14, 17, -20, 42, -14, +58, 2, 56, 21, 44, 44, 22, 59, +-7, 56, -26, 31, -44, 3, -55, -24, +-50, -46, -30, -55, -7, -48, 17, -27, +40, -1, 45, 24, 38, 38, 25, 38, +6, 26, -4, 10, -14, -5, -19, -13, +-18, -12, -12, 1, -2, 21, 1, 34, +5, 36, -2, 24, -7, 1, -8, -28, +-11, -51, -7, -61, 5, -55, 17, -28, +24, 10, 28, 44, 26, 67, 21, 72, +12, 57, -5, 31, -22, -5, -32, -40, +-30, -64, -19, -67, -6, -51, 8, -26, +14, 1, 20, 23, 19, 34, 12, 29, +12, 16, 8, 2, 7, -3, 4, 0, +-2, 11, -4, 24, -5, 29, -4, 24, +-8, 5, -17, -23, -27, -54, -26, -78, +-13, -85, 7, -71, 29, -33, 40, 21, +46, 74, 40, 108, 26, 113, 9, 88, +-18, 39, -36, -24, -51, -86, -54, -128, +-38, -135, -16, -109, 16, -56, 42, 8, +58, 67, 55, 106, 42, 116, 22, 93, +-1, 44, -22, -11, -44, -56, -54, -82, +-50, -86, -35, -65, -16, -30, 7, 8, +33, 37, 46, 50, 52, 44, 51, 22, +39, -4, 25, -26, 2, -37, -23, -32, +-46, -14, -60, 11, -62, 35, -54, 44, +-26, 38, 4, 21, 39, -3, 67, -28, +81, -46, 78, -53, 58, -46, 26, -25, +-19, 4, -52, 32, -77, 47, -78, 53, +-61, 48, -37, 36, -3, 18, 30, -2, +58, -16, 72, -24, 68, -27, 50, -24, +19, -16, -9, -8, -29, -3, -39, 1, +-36, 9, -33, 20, -27, 29, -19, 37, +-9, 41, 3, 40, 17, 34, 25, 23, +24, 6, 28, -14, 24, -32, 21, -41, +15, -43, 8, -38, -2, -27, -15, -6, +-24, 18, -32, 41, -28, 60, -15, 68, +-5, 65, 9, 45, 15, 17, 21, -14, +25, -42, 26, -63, 23, -69, 13, -62, +6, -42, -1, -14, -7, 21, -9, 52, +-13, 68, -13, 72, -14, 60, -18, 39, +-22, 10, -16, -23, -2, -50, 17, -65, +32, -65, 32, -54, 33, -38, 31, -16, +21, 8, 7, 27, -14, 41, -28, 48, +-36, 44, -31, 31, -23, 14, -13, -7, +4, -30, 20, -52, 29, -63, 27, -65, +20, -59, 15, -39, 10, -10, 3, 21, +-3, 42, -1, 51, 1, 45, 8, 26, +7, -3, -1, -33, -6, -54, -11, -60, +-14, -48, -20, -25, -20, 1, -11, 20, +3, 30, 22, 23, 32, 5, 36, -18, +33, -37, 23, -44, 9, -38, -8, -19, +-18, 9, -22, 38, -20, 55, -18, 50, +-19, 27, -12, -9, -2, -47, 13, -75, +22, -83, 27, -66, 27, -31, 26, 13, +28, 53, 20, 78, 10, 83, -3, 62, +-18, 24, -28, -20, -37, -52, -35, -65, +-20, -54, 1, -23, 17, 17, 24, 51, +27, 68, 25, 67, 18, 46, 5, 9, +-9, -28, -20, -50, -25, -53, -19, -33, +-12, 0, 5, 40, 17, 74, 23, 90, +22, 83, 3, 57, -13, 21, -23, -18, +-25, -46, -21, -59, -15, -50, -1, -28, +15, 4, 31, 32, 35, 50, 29, 55, +18, 47, 1, 32, -15, 19, -31, 10, +-33, 1, -21, 1, 0, 6, 16, 12, +20, 11, 22, 4, 21, -11, 17, -23, +2, -27, -17, -25, -24, -14, -18, 4, +-1, 27, 13, 45, 25, 53, 32, 47, +31, 29, 24, 0, 2, -28, -22, -47, +-39, -56, -42, -53, -32, -36, -20, -9, +0, 18, 27, 34, 55, 38, 63, 34, +49, 20, 29, -1, 7, -23, -13, -34, +-34, -41, -47, -41, -48, -36, -35, -30, +-11, -23, 8, -21, 27, -16, 36, -12, +40, -4, 41, 5, 31, 16, 20, 27, +8, 36, -1, 32, -10, 11, -21, -21, +-27, -58, -29, -88, -24, -107, -18, -104, +-14, -81, -6, -39, 10, 12, 30, 59, +47, 90, 58, 99, 53, 84, 41, 48, +19, 0, -13, -49, -37, -87, -55, -109, +-57, -105, -50, -82, -35, -43, -13, -3, +15, 28, 45, 46, 61, 51, 61, 43, +49, 25, 31, 9, 12, -1, -7, -4, +-22, 0, -34, 11, -36, 16, -32, 16, +-26, 8, -15, -10, -2, -33, 12, -52, +19, -57, 20, -48, 21, -22, 22, 13, +21, 56, 15, 93, 7, 112, -2, 108, +-9, 85, -13, 47, -15, 0, -10, -47, +-4, -77, -1, -85, 0, -73, 4, -44, +10, -8, 13, 32, 12, 64, 2, 85, +-3, 86, -4, 74, 1, 52, 12, 30, +17, 12, 21, -1, 19, -8, 13, -9, +5, -3, -10, -2, -20, -3, -25, -9, +-24, -13, -19, -12, -7, -5, 11, 9, +29, 30, 37, 48, 35, 60, 27, 60, +14, 45, 3, 24, -9, -1, -22, -24, +-22, -42, -17, -48, -6, -39, 5, -19, +11, 5, 16, 24, 13, 34, 6, 35, +-7, 26, -15, 5, -13, -12, -10, -24, +2, -28, 15, -25, 26, -14, 34, -3, +30, 7, 19, 13, -1, 6, -23, -4, +-38, -17, -46, -28, -41, -35, -21, -37, +8, -36, 34, -25, 55, -13, 61, -9, +58, -8, 42, -10, 12, -17, -15, -26, +-41, -29, -53, -28, -50, -22, -35, -16, +-12, -9, 11, -5, 31, -3, 40, -7, +40, -13, 32, -22, 21, -32, 10, -37, +-2, -37, -14, -27, -22, -17, -22, -5, +-15, 0, -11, 1, -9, -5, -10, -12, +-4, -20, 9, -26, 22, -23, 31, -15, +35, -4, 36, 8, 28, 20, 16, 22, +-1, 16, -17, 1, -27, -17, -35, -33, +-39, -43, -32, -46, -10, -35, 16, -14, +36, 13, 44, 38, 40, 51, 34, 55, +29, 48, 20, 34, 6, 14, -8, -3, +-15, -14, -19, -16, -21, -10, -23, -3, +-22, 3, -16, 9, -13, 13, -5, 10, +3, 6, 19, 8, 40, 19, 55, 37, +58, 58, 43, 76, 21, 84, -4, 77, +-28, 55, -51, 21, -70, -17, -71, -50, +-50, -74, -13, -76, 23, -53, 50, -12, +70, 35, 81, 75, 76, 104, 46, 115, +7, 106, -26, 78, -49, 41, -58, -1, +-59, -35, -47, -53, -24, -59, 6, -54, +29, -38, 38, -17, 38, 7, 36, 25, +38, 35, 33, 44, 20, 48, 7, 47, +0, 39, -8, 28, -20, 8, -30, -13, +-37, -36, -33, -55, -22, -63, -12, -56, +6, -39, 29, -13, 52, 14, 62, 32, +55, 43, 35, 39, 8, 22, -12, -6, +-33, -35, -49, -58, -53, -69, -45, -62, +-23, -46, 3, -23, 29, -1, 44, 16, +51, 21, 44, 14, 27, -3, 9, -24, +-3, -44, -8, -55, -11, -57, -15, -51, +-15, -39, -8, -30, 6, -22, 12, -15, +12, -15, 12, -16, 7, -12, 3, -7, +1, -4, 1, -1, 3, 1, 5, -5, +6, -18, 4, -34, 3, -49, 7, -58, +17, -58, 17, -44, 13, -23, 8, 1, +3, 26, -1, 40, -9, 40, -15, 26, +-20, 3, -17, -24, -4, -44, 6, -50, +15, -37, 25, -16, 36, 10, 39, 35, +26, 51, 8, 51, -7, 36, -16, 13, +-27, -12, -35, -32, -35, -38, -26, -29, +-7, -5, 10, 23, 21, 49, 25, 69, +31, 73, 34, 65, 29, 44, 18, 19, +6, -4, 2, -24, 1, -36, -4, -32, +-15, -12, -25, 9, -24, 29, -19, 45, +-17, 56, -13, 58, 2, 56, 26, 47, +43, 37, 50, 26, 43, 16, 34, 9, +25, 2, 8, 1, -14, 3, -38, 9, +-49, 14, -48, 21, -42, 24, -29, 26, +-13, 24, 11, 18, 35, 11, 51, 3, +57, 2, 57, 5, 56, 13, 43, 25, +18, 31, -12, 27, -37, 20, -53, 7, +-62, -10, -57, -28, -47, -39, -25, -39, +5, -28, 33, -9, 58, 9, 71, 23, +74, 29, 60, 28, 33, 16, 1, -3, +-27, -24, -45, -37, -51, -42, -46, -39, +-40, -28, -25, -17, -3, -11, 19, -10, +33, -12, 35, -19, 33, -27, 30, -32, +26, -30, 24, -23, 20, -12, 10, -2, +-1, -1, -12, -12, -21, -30, -30, -50, +-31, -66, -27, -69, -18, -58, -5, -34, +14, -5, 36, 21, 55, 38, 61, 42, +50, 28, 32, -6, 6, -47, -18, -80, +-38, -97, -48, -97, -44, -78, -33, -44, +-15, -2, 6, 35, 24, 60, 39, 66, +45, 51, 42, 27, 29, 1, 14, -23, +2, -41, -5, -48, -12, -44, -18, -32, +-24, -22, -27, -11, -26, -5, -21, 0, +-9, 4, 8, 9, 24, 19, 40, 30, +50, 42, 55, 48, 53, 48, 34, 39, +5, 25, -29, 5, -54, -15, -66, -27, +-66, -30, -50, -23, -20, -10, 16, 9, +47, 27, 68, 41, 77, 47, 68, 49, +44, 46, 12, 43, -20, 41, -46, 42, +-61, 44, -59, 44, -47, 38, -27, 26, +-6, 9, 12, -11, 29, -28, 40, -44, +47, -42, 46, -25, 37, 7, 27, 42, +18, 75, 6, 100, -9, 105, -26, 92, +-40, 58, -45, 14, -40, -30, -26, -64, +-5, -80, 16, -72, 38, -49, 56, -15, +64, 24, 57, 57, 36, 75, 8, 76, +-24, 62, -48, 31, -59, -1, -53, -28, +-33, -44, -6, -51, 18, -46, 34, -35, +44, -20, 48, -5, 41, 9, 22, 19, +-2, 21, -18, 18, -23, 8, -19, -3, +-12, -18, -2, -34, 8, -50, 13, -59, +9, -62, 1, -56, -3, -41, 1, -18, +9, 10, 15, 34, 13, 50, 14, 46, +18, 24, 23, -11, 14, -52, -3, -92, +-18, -118, -25, -122, -21, -99, -15, -52, +-6, -1, 14, 47, 35, 83, 42, 97, +35, 80, 20, 40, 3, -16, -12, -71, +-22, -114, -34, -134, -39, -121, -27, -88, +0, -40, 27, 17, 39, 66, 44, 94, +42, 97, 38, 79, 21, 44, -7, 1, +-29, -42, -41, -77, -40, -93, -37, -94, +-28, -78, -8, -49, 17, -12, 41, 30, +53, 66, 54, 95, 47, 107, 37, 105, +17, 87, -13, 48, -40, -1, -58, -50, +-62, -90, -53, -113, -35, -110, -12, -82, +19, -29, 56, 35, 76, 98, 80, 145, +68, 164, 44, 150, 12, 106, -22, 44, +-52, -20, -70, -72, -65, -104, -46, -103, +-24, -75, -2, -28, 22, 23, 44, 63, +56, 85, 52, 88, 37, 74, 18, 56, +6, 35, 0, 19, -2, 19, -7, 27, +-12, 35, -13, 33, -21, 21, -29, -3, +-30, -37, -21, -65, -10, -77, 3, -70, +20, -38, 39, 11, 60, 65, 67, 112, +56, 132, 33, 121, 7, 80, -20, 20, +-43, -41, -56, -88, -57, -109, -43, -100, +-20, -70, 3, -27, 26, 14, 42, 42, +53, 50, 53, 34, 39, 9, 20, -14, +-1, -24, -10, -18, -15, -2, -15, 16, +-9, 27, -1, 28, 6, 12, 2, -19, +-4, -58, -12, -88, -14, -103, -10, -95, +-3, -64, 7, -17, 24, 29, 45, 66, +56, 82, 50, 69, 33, 33, 12, -15, +-8, -57, -29, -86, -46, -96, -54, -84, +-47, -53, -23, -18, 5, 10, 29, 27, +44, 31, 53, 20, 57, 0, 48, -18, +28, -30, 6, -33, -5, -30, -13, -19, +-23, -7, -35, 1, -37, 2, -27, -4, +-12, -12, 1, -16, 11, -16, 25, -8, +39, 7, 47, 19, 48, 22, 39, 16, +25, 4, 9, -15, -9, -32, -24, -41, +-35, -37, -36, -18, -27, 10, -13, 38, +5, 56, 22, 61, 39, 48, 51, 22, +50, -9, 34, -34, 15, -47, 1, -46, +-6, -27, -11, 8, -19, 48, -21, 78, +-18, 90, -12, 78, -2, 47, 4, 4, +11, -35, 18, -64, 25, -70, 32, -53, +32, -12, 30, 36, 24, 76, 15, 99, +0, 99, -19, 79, -32, 41, -39, -1, +-34, -39, -21, -61, 0, -63, 24, -45, +47, -14, 61, 23, 62, 52, 47, 65, +19, 63, -12, 44, -37, 15, -46, -12, +-43, -27, -29, -29, -7, -19, 20, -4, +45, 13, 60, 25, 58, 28, 42, 20, +18, 5, -10, -10, -35, -24, -45, -31, +-37, -31, -17, -22, 10, -9, 30, 5, +43, 13, 46, 15, 40, 11, 29, 4, +9, 0, -12, -1, -27, 0, -28, -1, +-16, -5, -1, -11, 12, -19, 19, -34, +24, -49, 21, -58, 11, -56, 3, -42, +1, -16, 4, 18, 7, 50, 12, 72, +16, 74, 18, 56, 18, 16, 13, -33, +3, -82, -9, -114, -15, -124, -12, -110, +-2, -69, 10, -13, 20, 45, 29, 87, +30, 105, 26, 95, 14, 62, 2, 11, +-7, -38, -13, -77, -11, -96, -2, -90, +10, -67, 23, -34, 35, 0, 35, 27, +25, 44, 11, 45, -2, 34, -14, 22, +-20, 9, -19, 0, -6, -6, 11, -9, +28, -13, 42, -18, 46, -22, 36, -24, +17, -20, 2, -13, -8, 3, -13, 25, +-14, 51, -12, 65, -3, 64, 8, 45, +19, 10, 24, -29, 22, -64, 16, -78, +11, -73, 10, -44, 14, 0, 21, 56, +27, 103, 29, 127, 24, 115, 12, 75, +-3, 16, -16, -48, -23, -95, -26, -116, +-23, -105, -8, -63, 13, -1, 37, 61, +56, 106, 65, 122, 60, 110, 44, 73, +19, 24, -13, -25, -38, -61, -49, -76, +-47, -67, -34, -40, -16, -7, 5, 23, +29, 44, 52, 48, 66, 40, 64, 27, +46, 14, 25, 3, 10, -4, -6, -6, +-23, -6, -30, -9, -29, -16, -18, -25, +-8, -32, 5, -36, 22, -30, 40, -15, +52, 6, 57, 29, 51, 50, 35, 59, +22, 49, 7, 25, -13, -12, -32, -48, +-43, -81, -37, -97, -20, -94, -1, -68, +21, -28, 44, 18, 64, 58, 76, 82, +72, 86, 56, 71, 30, 41, 1, 0, +-29, -43, -52, -78, -63, -97, -57, -98, +-35, -80, -8, -51, 22, -16, 52, 19, +76, 47, 88, 62, 84, 61, 64, 54, +31, 40, -4, 18, -33, -4, -56, -21, +-68, -38, -59, -51, -34, -57, -6, -53, +23, -43, 48, -30, 68, -15, 76, 2, +70, 22, 51, 40, 24, 55, 4, 59, +-12, 55, -25, 43, -32, 22, -29, -5, +-16, -35, -1, -55, 12, -66, 19, -61, +27, -47, 29, -20, 28, 11, 26, 39, +27, 58, 29, 66, 27, 64, 20, 52, +10, 32, 1, 9, -4, -10, -7, -27, +-12, -35, -10, -39, -5, -35, 7, -25, +18, -11, 25, 7, 31, 26, 34, 42, +31, 58, 21, 68, 12, 64, 7, 50, +6, 23, 8, -9, 7, -43, 5, -66, +2, -75, 5, -69, 8, -42, 7, -2, +6, 40, 14, 74, 26, 95, 31, 97, +35, 74, 34, 32, 31, -18, 26, -66, +16, -95, 3, -99, -11, -76, -15, -37, +-11, 12, -5, 57, 2, 84, 14, 86, +30, 65, 40, 32, 38, -6, 26, -39, +19, -63, 17, -65, 15, -50, 14, -22, +12, 8, 12, 28, 15, 35, 12, 28, +2, 14, -9, -9, -15, -29, -10, -39, +-4, -32, 8, -15, 24, 7, 45, 26, +64, 34, 71, 30, 59, 16, 35, -7, +9, -32, -18, -48, -38, -53, -52, -43, +-48, -25, -28, -4, 5, 13, 41, 25, +66, 29, 77, 23, 77, 8, 66, -8, +42, -16, 10, -17, -14, -12, -27, -8, +-29, -3, -24, -2, -14, -3, -1, -9, +13, -16, 24, -21, 28, -17, 28, -5, +28, 6, 36, 19, 43, 30, 43, 37, +39, 30, 31, 15, 16, -6, -3, -24, +-23, -35, -34, -38, -35, -29, -26, -10, +-6, 12, 22, 29, 51, 44, 68, 46, +75, 35, 70, 14, 48, -6, 15, -22, +-15, -30, -34, -28, -40, -18, -30, 2, +-13, 22, 10, 37, 37, 41, 53, 37, +60, 26, 52, 12, 36, -9, 18, -23, +5, -30, -1, -29, 0, -19, 4, -2, +8, 13, 18, 20, 21, 27, 20, 31, +13, 33, 8, 29, 11, 23, 16, 15, +26, 7, 35, -3, 43, -16, 48, -28, +42, -39, 23, -40, -4, -34, -26, -20, +-34, 1, -29, 30, -14, 60, 10, 81, +40, 83, 68, 66, 82, 34, 77, -10, +57, -58, 29, -97, -1, -116, -25, -112, +-36, -77, -35, -23, -18, 39, 6, 90, +32, 122, 48, 122, 55, 92, 53, 43, +39, -14, 21, -66, 5, -103, -1, -113, +0, -99, 12, -66, 26, -24, 32, 21, +33, 52, 25, 64, 14, 60, -1, 45, +-12, 27, -13, 8, -5, -8, 16, -20, +36, -26, 53, -31, 62, -35, 60, -41, +44, -43, 22, -43, -2, -35, -20, -16, +-23, 7, -15, 35, 2, 58, 19, 69, +36, 61, 48, 35, 50, -2, 39, -35, +21, -64, 5, -80, -4, -75, -8, -50, +2, -16, 21, 18, 36, 50, 44, 66, +44, 60, 38, 34, 27, 5, 8, -23, +-5, -38, -11, -40, -8, -29, 2, -11, +21, 7, 41, 21, 55, 24, 61, 19, +49, 6, 32, -9, 9, -20, -6, -20, +-17, -11, -16, 6, -6, 22, 11, 34, +29, 39, 41, 32, 51, 15, 53, -6, +46, -21, 32, -29, 18, -27, 4, -15, +-8, 5, -7, 21, -1, 36, 6, 39, +12, 31, 21, 15, 31, -3, 39, -16, +45, -21, 43, -17, 42, -9, 37, 6, +29, 20, 17, 27, 8, 28, -4, 25, +-15, 18, -17, 5, -12, -6, 0, -11, +18, -11, 42, -11, 63, -6, 73, -1, +66, 8, 53, 10, 35, 9, 14, 7, +-7, 8, -27, 11, -32, 10, -22, 7, +-1, 4, 22, 0, 43, -8, 62, -14, +65, -18, 61, -19, 49, -21, 36, -13, +19, 1, 6, 13, -2, 22, -6, 27, +-1, 25, 6, 13, 18, -3, 21, -21, +23, -34, 25, -46, 29, -46, 38, -36, +45, -17, 51, 7, 52, 30, 48, 47, +35, 53, 17, 44, -1, 22, -17, -7, +-27, -42, -26, -71, -11, -84, 10, -78, +40, -57, 69, -21, 84, 21, 86, 57, +76, 79, 53, 80, 25, 63, -3, 29, +-26, -11, -35, -52, -33, -79, -19, -86, +-1, -72, 24, -49, 49, -19, 62, 12, +66, 34, 59, 47, 53, 45, 42, 36, +34, 20, 27, 5, 19, -4, 12, -6, +2, -10, -2, -15, -7, -21, -8, -30, +-3, -40, 6, -45, 22, -39, 39, -25, +65, -1, 82, 28, 86, 58, 71, 75, +47, 75, 20, 55, -7, 21, -29, -19, +-42, -52, -42, -70, -26, -69, 5, -49, +35, -14, 61, 26, 74, 53, 79, 64, +69, 55, 47, 33, 23, 4, 6, -21, +-3, -30, -8, -26, -3, -10, 7, 11, +22, 30, 35, 38, 38, 33, 32, 17, +18, -8, 12, -35, 12, -49, 19, -43, +25, -18, 34, 19, 44, 50, 51, 69, +56, 67, 45, 49, 33, 16, 17, -24, +4, -59, -8, -73, -14, -66, -9, -40, +5, -2, 27, 36, 42, 63, 54, 72, +62, 61, 65, 33, 58, 4, 44, -25, +28, -40, 11, -45, -2, -37, -10, -22, +-11, -6, -6, 6, 6, 9, 20, 10, +32, 5, 46, 3, 56, 9, 60, 22, +56, 33, 49, 38, 35, 33, 20, 18, +5, -9, -6, -39, -11, -65, -11, -78, +-2, -71, 10, -46, 28, -4, 40, 42, +56, 77, 65, 91, 63, 84, 53, 52, +36, 7, 23, -40, 8, -78, 0, -96, +-5, -91, -2, -62, 7, -24, 20, 16, +38, 46, 49, 60, 57, 56, 53, 38, +44, 13, 29, -11, 17, -31, 12, -40, +8, -36, 10, -27, 11, -14, 23, -4, +34, 1, 47, 3, 51, 2, 47, -1, +36, 0, 23, 2, 13, 7, 2, 12, +-1, 13, 1, 10, 9, 0, 21, -11, +34, -21, 46, -25, 55, -25, 61, -17, +59, -5, 46, 12, 28, 26, 16, 31, +8, 26, 5, 10, 5, -5, 1, -20, +5, -30, 13, -35, 28, -31, 40, -18, +51, 2, 54, 21, 57, 34, 57, 41, +46, 40, 36, 30, 22, 12, 12, -7, +-4, -24, -12, -33, -14, -36, -3, -30, +15, -19, 31, -5, 49, 11, 60, 25, +67, 32, 69, 32, 62, 29, 45, 24, +22, 18, 3, 11, -13, 5, -15, -5, +-9, -12, 5, -18, 16, -21, 29, -24, +42, -27, 51, -22, 57, -10, 54, 8, +51, 25, 41, 45, 31, 61, 18, 67, +14, 55, 10, 31, 4, 2, -2, -33, +-3, -63, 6, -80, 18, -78, 37, -59, +52, -21, 64, 22, 68, 58, 67, 79, +59, 84, 39, 69, 17, 39, -8, 3, +-25, -31, -32, -54, -20, -64, 7, -58, +36, -40, 66, -15, 81, 7, 88, 21, +78, 23, 61, 22, 32, 16, 4, 10, +-16, 6, -28, 8, -20, 14, -4, 14, +25, 9, 49, 0, 61, -13, 62, -32, +58, -49, 47, -56, 33, -46, 19, -21, +7, 12, 5, 42, 10, 63, 22, 69, +32, 57, 38, 30, 40, -7, 33, -44, +24, -70, 15, -75, 14, -62, 19, -37, +32, -6, 41, 25, 46, 46, 48, 52, +39, 48, 26, 30, 10, 4, 6, -20, +0, -30, 3, -32, 17, -26, 41, -17, +63, -7, 74, 0, 73, 2, 52, 0, +29, -8, 3, -10, -15, -8, -25, -1, +-21, 9, -3, 22, 21, 29, 52, 30, +74, 23, 83, 9, 75, -9, 55, -26, +29, -35, 1, -37, -11, -28, -16, -13, +-7, 5, 6, 19, 23, 29, 37, 31, +48, 24, 52, 14, 45, 4, 37, -4, +28, -8, 26, -4, 26, 1, 35, 7, +39, 6, 43, -1, 37, -13, 24, -23, +8, -30, -5, -31, -9, -21, -6, -2, +9, 24, 29, 48, 55, 68, 77, 70, +87, 57, 86, 26, 63, -9, 30, -45, +-6, -72, -28, -84, -39, -76, -32, -48, +-7, -12, 20, 32, 51, 67, 70, 89, +85, 88, 83, 69, 67, 40, 37, 7, +10, -30, -1, -57, -3, -68, 5, -63, +16, -46, 27, -23, 30, 4, 33, 21, +32, 32, 30, 33, 30, 32, 27, 29, +29, 26, 32, 22, 39, 17, 47, 7, +51, -7, 48, -21, 34, -36, 19, -42, +4, -42, 4, -33, 7, -14, 15, 14, +21, 36, 34, 49, 46, 49, 52, 34, +51, 9, 42, -20, 34, -41, 21, -51, +21, -48, 25, -31, 36, 1, 43, 33, +43, 54, 38, 54, 26, 34, 17, 1, +9, -34, 3, -59, 2, -71, 11, -61, +27, -32, 45, 10, 67, 45, 74, 71, +74, 72, 60, 50, 41, 14, 16, -25, +-7, -57, -14, -71, -18, -60, -10, -32, +3, 1, 23, 30, 38, 51, 56, 48, +66, 29, 70, -1, 63, -30, 51, -44, +38, -42, 26, -26, 20, -1, 9, 26, +3, 41, -4, 42, -9, 28, -6, 3, +4, -27, 23, -45, 41, -48, 59, -37, +72, -14, 81, 15, 79, 38, 65, 44, +44, 37, 10, 17, -16, -7, -37, -32, +-32, -47, -15, -47, 11, -26, 34, 2, +55, 29, 70, 45, 72, 42, 71, 26, +57, 1, 41, -23, 22, -39, 11, -41, +7, -31, 13, -10, 23, 12, 25, 28, +26, 32, 21, 23, 17, 6, 13, -12, +10, -21, 16, -23, 27, -13, 46, 3, +61, 23, 72, 35, 72, 36, 65, 20, +47, -5, 22, -31, -1, -51, -18, -54, +-20, -41, -16, -14, 2, 15, 20, 42, +42, 57, 60, 56, 72, 38, 73, 14, +63, -12, 49, -30, 32, -35, 19, -31, +10, -17, 9, -1, 6, 15, 6, 19, +5, 15, 4, 5, 12, -7, 23, -16, +38, -11, 44, 6, 47, 25, 52, 38, +57, 40, 58, 36, 44, 20, 29, -1, +6, -23, -8, -38, -17, -44, -11, -34, +-1, -15, 16, 8, 37, 26, 50, 31, +64, 26, 65, 14, 59, 4, 46, -10, +36, -17, 23, -13, 10, 5, 4, 22, +6, 32, 16, 32, 21, 21, 24, 1, +25, -27, 28, -49, 30, -63, 31, -60, +38, -43, 40, -14, 44, 19, 42, 49, +41, 67, 38, 71, 32, 63, 21, 43, +8, 15, 3, -16, -1, -39, 5, -55, +10, -62, 25, -66, 36, -60, 46, -44, +50, -22, 52, 4, 51, 34, 41, 60, +35, 76, 25, 82, 17, 73, 8, 49, +7, 11, 9, -33, 9, -72, 14, -96, +17, -104, 26, -89, 35, -56, 43, -9, +48, 35, 50, 67, 49, 85, 42, 78, +39, 57, 30, 27, 22, -6, 10, -33, +3, -46, -3, -51, 6, -49, 20, -40, +30, -27, 41, -14, 44, -2, 45, 12, +39, 22, 35, 33, 28, 39, 25, 41, +20, 39, 14, 30, 15, 8, 19, -19, +27, -43, 27, -57, 26, -60, 21, -49, +19, -25, 24, 5, 27, 39, 35, 61, +37, 70, 40, 62, 37, 39, 37, 5, +33, -28, 24, -50, 17, -60, 7, -51, +6, -34, 6, -10, 20, 11, 32, 29, +43, 42, 43, 44, 41, 35, 38, 21, +33, 8, 27, 1, 19, -2, 16, -3, +14, -5, 17, -7, 24, -11, 29, -17, +36, -24, 38, -26, 34, -17, 24, -3, +18, 15, 14, 33, 16, 46, 21, 53, +26, 46, 37, 29, 40, 8, 42, -10, +38, -31, 35, -42, 23, -42, 13, -33, +7, -20, 7, -2, 13, 14, 22, 23, +36, 28, 40, 28, 45, 24, 42, 16, +39, 10, 33, 2, 26, -4, 19, -10, +13, -11, 16, -12, 20, -13, 30, -15, +40, -19, 44, -16, 43, -10, 29, 2, +17, 8, 7, 13, 5, 15, 4, 16, +8, 16, 16, 13, 29, 6, 49, -1, +62, -6, 70, -11, 61, -11, 42, -11, +17, -12, 1, -15, -13, -17, -20, -19, +-16, -18, -3, -14, 18, -7, 41, 3, +60, 13, 69, 26, 72, 29, 61, 28, +44, 18, 24, 4, 7, -11, -4, -24, +-10, -35, -5, -42, 3, -42, 16, -35, +30, -20, 37, -2, 41, 16, 36, 25, +37, 26, 38, 19, 44, 11, 46, 1, +49, -7, 46, -14, 40, -17, 31, -18, +14, -19, -2, -15, -18, -13, -21, -12, +-14, -15, 1, -12, 19, -6, 48, -1, +78, 6, 93, 17, 92, 23, 77, 22, +53, 18, 20, 9, -13, -2, -39, -15, +-50, -25, -41, -34, -17, -32, 15, -23, +47, -9, 77, 6, 91, 22, 87, 31, +71, 30, 46, 25, 22, 14, -1, 2, +-9, -9, -17, -12, -12, -13, -2, -9, +15, -2, 27, 4, 32, 8, 36, 10, +33, 7, 34, 1, 36, -4, 40, -2, +43, 2, 45, 7, 43, 13, 33, 17, +22, 17, 7, 16, -7, 9, -17, 0, +-14, -7, -4, -13, 13, -10, 34, -3, +48, 5, 66, 12, 67, 13, 61, 10, +43, 3, 24, -1, 4, -5, -7, -7, +-7, -1, -4, 8, 9, 19, 20, 25, +31, 29, 36, 21, 41, 2, 40, -22, +34, -39, 25, -47, 19, -41, 20, -28, +26, -6, 34, 20, 34, 44, 33, 59, +25, 57, 14, 43, 8, 16, 2, -12, +3, -39, 4, -51, 12, -50, 21, -39, +33, -20, 43, -2, 46, 12, 47, 20, +36, 24, 24, 24, 11, 19, 7, 11, +6, 3, 14, -4, 25, -9, 32, -13, +35, -17, 33, -24, 30, -30, 21, -31, +9, -28, -2, -18, -4, -6, 8, 11, +21, 24, 38, 34, 49, 33, 59, 27, +59, 16, 44, 1, 23, -13, 1, -29, +-12, -39, -19, -44, -18, -39, -8, -30, +12, -18, 29, -3, 45, 11, 53, 20, +61, 25, 61, 29, 51, 30, 37, 27, +21, 18, 11, 4, -1, -14, -7, -33, +-7, -51, -3, -61, 0, -57, 4, -40, +12, -15, 25, 13, 43, 41, 55, 63, +64, 73, 68, 65, 61, 46, 46, 14, +23, -19, 1, -50, -22, -68, -34, -71, +-39, -59, -30, -37, -7, -9, 21, 21, +54, 44, 78, 58, 89, 63, 84, 57, +68, 41, 43, 24, 15, 1, -12, -21, +-34, -35, -42, -43, -36, -46, -19, -41, +1, -25, 25, -7, 48, 13, 64, 33, +68, 51, 64, 59, 60, 59, 43, 47, +25, 27, 6, 1, -6, -23, -15, -40, +-23, -47, -22, -44, -16, -33, 2, -15, +20, 5, 40, 27, 51, 43, 64, 49, +69, 42, 62, 33, 43, 19, 24, 3, +3, -10, -20, -19, -28, -25, -27, -29, +-12, -25, 3, -19, 23, -5, 42, 6, +53, 15, 59, 20, 53, 22, 40, 21, +24, 16, 10, 7, 4, -4, -2, -9, +-3, -14, 3, -20, 15, -20, 23, -10, +26, 0, 23, 9, 18, 15, 11, 16, +10, 12, 13, 2, 18, -9, 30, -21, +39, -25, 43, -25, 38, -20, 31, -9, +21, 5, 8, 14, -4, 19, -13, 20, +-11, 15, -3, 5, 10, -7, 26, -18, +40, -24, 50, -27, 49, -26, 39, -18, +25, -9, 15, -1, 6, 6, 3, 8, +0, 7, 7, 3, 18, 0, 22, -3, +26, -4, 28, -5, 28, -3, 13, 2, +1, 6, -3, 4, 5, 0, 16, -8, +27, -16, 37, -21, 43, -22, 47, -22, +44, -15, 34, -1, 12, 12, -5, 22, +-19, 27, -23, 27, -18, 20, -4, 7, +16, -6, 33, -15, 47, -19, 57, -21, +58, -15, 50, -4, 32, 10, 14, 17, +-5, 18, -18, 13, -21, 5, -15, -5, +-3, -12, 10, -10, 23, 0, 34, 10, +40, 18, 41, 27, 42, 29, 33, 26, +24, 12, 11, -6, 4, -25, 7, -36, +10, -37, 16, -30, 19, -12, 21, 11, +20, 32, 13, 43, 11, 45, 11, 35, +17, 17, 18, -6, 19, -23, 26, -34, +38, -33, 41, -21, 36, -6, 27, 9, +17, 22, 5, 28, -5, 25, -5, 18, +-5, 6, 6, -2, 13, -5, 19, -3, +24, -3, 30, -4, 35, -6, 31, -9, +26, -11, 20, -13, 14, -10, 12, -5, +18, 6, 24, 18, 27, 29, 24, 30, +19, 25, 9, 14, -5, -6, -10, -28, +-10, -45, -4, -51, 3, -47, 14, -30, +37, -9, 59, 13, 75, 28, 72, 39, +55, 40, 31, 32, 4, 15, -19, -2, +-41, -14, -49, -24, -42, -30, -28, -31, +-7, -28, 22, -28, 54, -26, 73, -23, +74, -14, 72, -6, 68, 9, 47, 32, +15, 51, -13, 58, -26, 52, -37, 32, +-47, -1, -42, -34, -33, -65, -11, -83, +13, -84, 36, -62, 57, -28, 75, 11, +85, 49, 79, 74, 62, 82, 37, 69, +5, 42, -33, 4, -57, -32, -67, -58, +-56, -65, -42, -58, -14, -41, 22, -17, +52, 7, 79, 21, 93, 26, 95, 26, +74, 21, 41, 15, 12, 9, -14, 6, +-34, 3, -48, 5, -51, 3, -38, -7, +-15, -21, 9, -28, 30, -28, 46, -24, +61, -10, 65, 8, 58, 29, 49, 42, +38, 44, 27, 33, 3, 16, -14, -9, +-17, -33, -21, -49, -25, -51, -24, -37, +-6, -13, 16, 16, 29, 41, 41, 59, +49, 62, 54, 49, 51, 22, 42, -6, +27, -28, 6, -43, -10, -48, -19, -43, +-22, -27, -15, -5, -4, 17, 3, 34, +12, 43, 22, 42, 37, 37, 35, 26, +28, 13, 25, 1, 18, -10, 12, -20, +4, -29, 7, -29, 7, -25, 5, -12, +5, 2, 8, 17, 9, 28, 7, 36, +2, 37, 2, 29, 3, 14, 7, -7, +15, -25, 15, -36, 21, -34, 25, -27, +31, -11, 35, 6, 29, 24, 20, 35, +6, 32, -3, 19, -3, 2, -7, -15, +-13, -31, -12, -41, 5, -40, 22, -26, +25, -10, 31, 8, 40, 19, 41, 28, +32, 26, 17, 17, 9, 6, 2, -6, +-5, -14, -8, -17, -12, -14, -7, -13, +3, -11, 10, -13, 15, -13, 23, -15, +36, -13, 30, -6, 17, 1, 14, 9, +18, 15, 19, 22, 11, 20, 8, 13, +8, -1, 5, -14, 0, -25, 2, -30, +2, -29, 4, -21, 3, -7, 10, 5, +20, 14, 29, 15, 41, 13, 38, 5, +30, -3, 17, -11, 8, -14, -5, -9, +-20, 4, -26, 15, -24, 20, -16, 22, +3, 15, 28, 3, 40, -7, 44, -16, +48, -24, 51, -24, 28, -14, 0, 0, +-17, 14, -25, 24, -27, 23, -25, 18, +-11, 11, 5, 1, 21, -5, 40, -9, +48, -6, 51, 1, 42, 9, 21, 16, +-1, 19, -17, 12, -12, -2, -8, -16, +-14, -23, -7, -24, 9, -18, 23, -4, +25, 13, 22, 31, 23, 40, 15, 39, +6, 29, 4, 15, 10, -4, 20, -21, +20, -29, 21, -27, 20, -20, 13, -10, +6, 3, -9, 12, -17, 13, -18, 9, +-12, 8, -3, 7, 8, 6, 29, 10, +50, 19, 53, 23, 49, 18, 40, 9, +17, -3, -10, -19, -28, -38, -26, -48, +-32, -44, -31, -28, -15, -3, 10, 25, +35, 48, 45, 61, 51, 59, 45, 41, +27, 14, 9, -19, -1, -47, -2, -66, +-1, -66, -5, -52, 1, -27, 7, 0, +16, 24, 21, 36, 9, 35, 1, 29, +-1, 16, -1, 3, -1, -9, 5, -13, +29, -11, 44, -6, 43, -6, 39, -10, +30, -16, 16, -27, -9, -35, -29, -37, +-33, -29, -33, -12, -23, 14, -9, 42, +13, 60, 40, 60, 60, 48, 61, 21, +43, -14, 24, -48, 14, -71, -3, -77, +-18, -65, -26, -37, -23, -5, -12, 28, +-5, 50, 16, 58, 27, 49, 25, 32, +18, 11, 14, -9, 16, -23, 10, -26, +11, -20, 19, -14, 20, -8, 14, -2, +9, -1, 3, -10, 0, -18, -9, -21, +-11, -12, -12, 3, -6, 22, 8, 40, +13, 54, 18, 58, 27, 44, 34, 17, +26, -16, 7, -41, 4, -59, 4, -61, +-2, -49, -4, -25, 0, 5, 9, 29, +9, 44, 8, 48, 18, 42, 17, 27, +9, 11, -2, -4, -4, -12, 6, -15, +15, -12, 23, -8, 20, -5, 19, -7, +26, -13, 21, -16, 8, -16, -5, -8, +-9, 3, -11, 19, -23, 35, -15, 43, +3, 40, 14, 27, 23, 7, 30, -12, +36, -32, 31, -45, 23, -44, 16, -30, +7, -8, -1, 10, -1, 28, -6, 35, +-9, 33, -15, 24, -9, 9, 1, -9, +7, -22, 14, -24, 13, -18, 19, -8, +26, 3, 35, 10, 36, 7, 23, 5, +14, -2, 7, -8, -7, -14, -18, -15, +-18, -9, -13, 1, -17, 12, -22, 17, +1, 15, 22, 5, 34, -3, 35, -10, +34, -14, 38, -16, 32, -12, 19, -3, +1, 8, -15, 13, -16, 10, -19, 2, +-27, -10, -26, -19, -9, -26, 14, -23, +21, -11, 27, 8, 39, 22, 39, 32, +30, 35, 21, 26, 18, 8, 7, -15, +-14, -36, -21, -51, -19, -52, -15, -43, +-3, -21, 6, 4, 14, 28, 14, 43, +21, 49, 24, 47, 16, 32, 15, 10, +11, -9, 6, -23, -1, -30, 0, -30, +5, -27, 2, -20, -1, -12, 6, -4, +-1, 6, -11, 15, -12, 20, -2, 23, +9, 25, 8, 24, 27, 21, 39, 13, +37, 6, 24, -1, 15, -11, 11, -22, +-6, -26, -26, -25, -36, -22, -32, -14, +-12, -4, 7, 8, 18, 17, 30, 25, +38, 32, 44, 36, 31, 34, 12, 29, +5, 23, -12, 12, -30, -2, -34, -16, +-18, -29, 4, -40, 11, -45, 20, -40, +29, -26, 26, -4, 19, 19, 6, 37, +0, 52, -8, 61, -10, 57, 3, 42, +6, 24, 14, 5, 22, -16, 24, -33, +15, -45, -1, -51, -9, -51, -20, -44, +-28, -31, -12, -14, 6, 7, 20, 31, +31, 55, 42, 74, 48, 81, 32, 73, +20, 50, 2, 15, -26, -27, -47, -69, +-46, -98, -25, -108, -6, -96, 11, -64, +32, -17, 46, 36, 52, 82, 46, 112, +22, 117, 2, 93, -16, 46, -18, -7, +-21, -54, -23, -87, -2, -101, 16, -93, +21, -66, 20, -34, 25, 2, 28, 35, +8, 55, -8, 62, -4, 58, -2, 44, +1, 26, 2, 6, 12, -12, 25, -30, +28, -42, 27, -48, 9, -51, -5, -47, +-9, -37, -11, -17, -8, 7, -5, 31, +9, 51, 17, 62, 14, 58, 22, 42, +27, 17, 22, -16, 9, -48, 1, -71, +5, -76, 1, -64, 6, -37, 12, -2, +12, 29, 7, 49, 3, 60, 5, 55, +0, 37, -10, 14, -6, -12, 3, -27, +6, -33, 16, -30, 20, -22, 30, -10, +30, -1, 31, 6, 22, 7, -2, 6, +-13, 4, -17, 2, -20, 5, -24, 11, +-15, 16, 6, 15, 12, 12, 13, 6, +31, -2, 45, -12, 44, -17, 26, -18, +14, -10, 10, 2, -3, 12, -5, 20, +-13, 22, -23, 20, -24, 5, -20, -13, +-8, -30, 6, -37, 25, -32, 42, -14, +38, 11, 35, 39, 35, 59, 28, 62, +10, 52, -12, 28, -18, -2, -27, -35, +-34, -61, -21, -72, -7, -64, 9, -42, +24, -12, 36, 20, 40, 44, 26, 58, +21, 55, 20, 42, 12, 23, 3, 4, +-7, -13, -4, -21, -7, -22, -1, -19, +6, -15, 0, -14, -3, -18, -4, -22, +-1, -23, -1, -19, 8, -10, 27, 3, +31, 23, 20, 41, 27, 49, 33, 48, +25, 36, 3, 12, -11, -17, -11, -44, +-20, -63, -19, -68, -11, -56, 1, -32, +14, -1, 19, 28, 19, 48, 15, 54, +15, 43, 20, 26, 10, 4, 5, -16, +11, -25, 8, -24, 1, -14, -6, -5, +6, 6, 13, 11, -2, 10, -13, 2, +-16, -12, -10, -22, -5, -26, 4, -25, +21, -15, 23, 5, 24, 26, 30, 41, +30, 41, 28, 34, 16, 17, 3, -3, +-13, -22, -24, -37, -20, -41, -18, -34, +-17, -21, -8, -3, 2, 15, 12, 25, +20, 28, 32, 23, 41, 14, 33, 2, +34, -5, 30, -8, 17, -5, -5, 2, +-22, 6, -21, 8, -28, 3, -32, -6, +-26, -14, -10, -19, 14, -22, 33, -16, +48, -3, 52, 15, 44, 30, 38, 38, +18, 40, -5, 32, -16, 17, -29, -5, +-37, -23, -43, -34, -22, -37, 7, -30, +20, -15, 28, 3, 32, 22, 34, 37, +24, 43, 10, 39, 5, 30, -5, 19, +-14, 5, -8, -9, -2, -22, 8, -27, +12, -30, 15, -27, 10, -19, -3, -8, +-7, 7, -13, 20, -16, 33, -7, 41, +10, 44, 29, 39, 32, 30, 32, 12, +34, -9, 19, -33, 6, -52, -7, -60, +-20, -57, -31, -41, -32, -14, -11, 18, +8, 44, 22, 66, 30, 74, 32, 68, +29, 46, 16, 16, 5, -17, -2, -44, +-15, -62, -16, -67, -10, -57, -2, -37, +18, -11, 24, 16, 25, 36, 13, 44, +9, 48, 6, 45, -13, 35, -25, 18, +-18, -2, 2, -16, 14, -25, 14, -29, +25, -31, 34, -28, 23, -18, 13, -6, +-5, 4, -18, 18, -29, 28, -29, 33, +-16, 33, -2, 24, 22, 12, 35, -1, +32, -14, 29, -28, 24, -33, 17, -30, +-3, -19, -26, -2, -28, 18, -26, 32, +-17, 39, 3, 36, 23, 23, 33, 8, +28, -11, 28, -27, 24, -38, 6, -38, +-7, -27, -14, -9, -17, 12, -20, 35, +-17, 47, 0, 45, 10, 35, 18, 19, +23, 2, 20, -19, 21, -32, 13, -37, +11, -30, 4, -17, 1, 2, 3, 21, +-6, 32, -18, 36, -19, 31, -10, 21, +-4, 7, -5, -6, 3, -16, 19, -18, +23, -10, 28, 3, 29, 12, 31, 18, +23, 19, 3, 17, -10, 11, -23, 2, +-27, -6, -26, -13, -26, -13, -18, -7, +-2, 2, 19, 10, 32, 17, 31, 22, +41, 21, 42, 13, 30, 5, 15, 1, +-3, 0, -14, 1, -31, 2, -38, 7, +-38, 9, -36, 7, -24, 4, -6, 0, +16, -4, 36, -7, 48, -4, 55, 4, +45, 15, 28, 24, 13, 33, -10, 33, +-31, 25, -50, 11, -57, -3, -51, -18, +-31, -28, 2, -29, 26, -20, 39, -4, +49, 15, 52, 32, 47, 39, 24, 38, +-2, 28, -17, 8, -31, -16, -33, -32, +-30, -35, -17, -26, -3, -12, 8, 5, +22, 25, 23, 39, 22, 44, 18, 35, +9, 18, 1, -3, -2, -20, -6, -30, +-11, -31, -16, -26, -4, -12, 8, 6, +8, 24, 2, 39, -3, 42, 5, 37, +3, 25, 3, 13, 7, 0, 4, -11, +-3, -18, -10, -19, -11, -17, -5, -15, +-5, -7, -2, 2, 0, 8, 5, 14, +19, 23, 24, 32, 23, 38, 11, 36, +1, 28, -9, 16, -24, 1, -29, -17, +-27, -32, -23, -37, -14, -32, -3, -16, +13, 3, 24, 21, 31, 36, 43, 45, +36, 46, 21, 39, 2, 23, -13, 5, +-24, -12, -36, -25, -34, -29, -26, -25, +-20, -12, -15, 6, -5, 21, 8, 31, +23, 34, 33, 28, 36, 22, 25, 15, +18, 10, 11, 8, -4, 7, -21, 7, +-38, 9, -43, 8, -45, 1, -38, -3, +-18, -7, 4, -6, 20, -1, 31, 7, +42, 13, 51, 21, 41, 31, 19, 35, +-4, 30, -30, 18, -40, 3, -47, -13, +-41, -20, -31, -19, -13, -11, 12, 3, +24, 20, 28, 31, 30, 35, 23, 31, +9, 20, -3, 2, -10, -16, -16, -21, +-23, -16, -17, -1, -10, 17, -1, 34, +3, 46, 1, 48, -3, 40, -13, 19, +-13, -9, -5, -36, -1, -49, 2, -47, +6, -30, 10, -2, 17, 29, 13, 56, +4, 74, -13, 73, -25, 56, -28, 31, +-33, 2, -29, -22, -22, -37, -7, -36, +4, -24, 8, -8, 13, 10, 17, 23, +12, 26, 4, 25, -5, 20, -9, 13, +-15, 11, -18, 14, -15, 22, -17, 30, +-9, 36, -11, 33, -10, 21, -13, 1, +-13, -17, -6, -33, -4, -40, -1, -36, +4, -20, 9, 7, 11, 35, 10, 60, +5, 72, -1, 70, -21, 56, -34, 33, +-40, 1, -37, -24, -32, -37, -24, -38, +-8, -29, 6, -13, 22, 4, 33, 19, +31, 34, 20, 38, 5, 37, -11, 29, +-25, 20, -39, 15, -44, 12, -42, 10, +-32, 9, -15, 9, -2, 5, 10, 0, +16, -3, 20, -4, 19, -3, 10, 1, +-2, 11, -13, 24, -28, 34, -36, 41, +-39, 42, -33, 35, -24, 22, -19, 6, +-7, -6, 2, -16, 15, -17, 17, -11, +13, 0, 5, 11, -6, 23, -13, 32, +-23, 34, -31, 32, -31, 25, -28, 19, +-24, 15, -18, 11, -11, 6, 2, 6, +3, 6, 4, 7, 1, 7, -3, 6, +-7, 6, -14, 7, -15, 10, -18, 15, +-19, 22, -18, 26, -20, 30, -23, 29, +-22, 26, -18, 18, -11, 9, -11, 2, +-7, 0, -5, 3, -6, 8, -1, 13, +-5, 19, -10, 23, -21, 24, -31, 23, +-32, 15, -32, 9, -30, 5, -21, 5, +-13, 11, -6, 19, 1, 27, 9, 34, +6, 38, -6, 34, -16, 24, -30, 10, +-35, -8, -36, -22, -32, -28, -24, -25, +-13, -13, 2, 6, 7, 32, 2, 55, +-2, 65, -7, 64, -17, 54, -29, 36, +-41, 12, -41, -10, -38, -27, -28, -34, +-14, -31, -2, -18, 9, -2, 7, 17, +3, 34, -2, 41, -11, 44, -24, 41, +-37, 33, -47, 24, -46, 20, -43, 19, +-34, 19, -25, 15, -11, 9, 3, 5, +4, 1, 6, -4, 1, -7, -6, -6, +-16, -4, -26, 6, -36, 21, -44, 37, +-47, 46, -42, 51, -37, 48, -30, 40, +-21, 27, -12, 10, -1, -1, -1, -6, +-1, -4, -6, 0, -10, 7, -20, 13, +-33, 19, -44, 22, -49, 19, -46, 13, +-41, 8, -36, 8, -24, 10, -9, 23, +0, 39, 2, 52, -1, 55, -1, 48, +-13, 37, -27, 17, -37, -11, -41, -34, +-41, -45, -46, -43, -44, -29, -34, -6, +-20, 24, -11, 54, -6, 78, -7, 86, +-5, 81, -9, 63, -15, 36, -24, 7, +-32, -20, -36, -36, -44, -42, -47, -38, +-47, -26, -40, -5, -34, 19, -28, 41, +-18, 53, -5, 60, 0, 65, -4, 65, +-13, 56, -21, 39, -30, 20, -46, 2, +-56, -18, -64, -33, -56, -39, -46, -33, +-34, -15, -18, 8, -9, 34, 0, 60, +2, 79, -6, 87, -19, 79, -34, 54, +-46, 20, -52, -10, -57, -36, -52, -47, +-48, -44, -35, -27, -24, 0, -21, 31, +-18, 56, -16, 70, -17, 73, -24, 62, +-31, 44, -35, 22, -36, 3, -37, -13, +-36, -20, -36, -19, -31, -11, -31, 1, +-36, 14, -42, 26, -45, 33, -39, 39, +-37, 39, -30, 38, -23, 34, -16, 31, +-14, 25, -19, 19, -26, 11, -32, 1, +-42, -5, -56, -7, -62, -5, -59, 0, +-46, 12, -36, 27, -25, 39, -21, 49, +-15, 53, -18, 47, -24, 34, -33, 18, +-43, 3, -50, -6, -57, -6, -57, 0, +-50, 8, -40, 20, -33, 33, -28, 43, +-30, 41, -31, 35, -38, 25, -44, 13, +-47, 3, -48, 0, -46, 4, -42, 12, +-34, 22, -30, 33, -30, 44, -33, 47, +-37, 43, -46, 31, -52, 14, -57, 1, +-52, -6, -50, -5, -48, -1, -40, 7, +-35, 18, -28, 30, -31, 38, -35, 43, +-41, 43, -44, 40, -49, 32, -54, 27, +-58, 24, -54, 22, -51, 20, -52, 19, +-52, 14, -47, 5, -36, 1, -37, 1, +-39, 5, -40, 11, -37, 22, -37, 32, +-42, 43, -48, 51, -54, 54, -56, 47, +-57, 32, -54, 17, -51, 3, -46, -6, +-41, -12, -33, -8, -32, 3, -34, 17, +-44, 31, -55, 40, -62, 39, -65, 34, +-62, 30, -60, 24, -54, 20, -45, 19, +-36, 24, -31, 31, -30, 37, -38, 37, +-45, 31, -57, 20, -66, 10, -72, -3, +-74, -14, -66, -15, -56, -5, -45, 14, +-41, 34, -37, 55, -34, 68, -35, 72, +-41, 61, -51, 44, -61, 24, -65, 3, +-67, -15, -68, -23, -66, -18, -62, -7, +-53, 12, -56, 31, -59, 47, -58, 54, +-51, 55, -46, 46, -45, 35, -43, 23, +-39, 15, -38, 13, -47, 15, -58, 18, +-66, 18, -72, 18, -83, 16, -86, 16, +-83, 11, -68, 8, -52, 10, -40, 16, +-31, 30, -27, 43, -26, 51, -33, 53, +-47, 51, -65, 41, -81, 28, -95, 13, +-100, -1, -97, -13, -80, -15, -63, -8, +-49, 8, -35, 26, -30, 42, -29, 56, +-36, 59, -43, 56, -59, 47, -74, 33, +-82, 16, -84, 5, -85, -2, -81, -2, +-73, 5, -67, 17, -65, 27, -62, 30, +-54, 33, -50, 35, -47, 34, -53, 32, +-59, 30, -63, 29, -63, 31, -70, 33, +-78, 32, -80, 27, -78, 24, -77, 18, +-78, 11, -73, 10, -66, 11, -57, 13, +-57, 19, -60, 32, -61, 39, -58, 43, +-62, 47, -73, 46, -77, 39, -76, 31, +-75, 23, -79, 14, -75, 8, -69, 3, +-61, 5, -60, 6, -59, 11, -63, 20, +-66, 31, -70, 37, -73, 42, -72, 46, +-76, 48, -75, 45, -75, 37, -69, 26, +-67, 14, -66, 3, -66, -5, -65, -7, +-69, -1, -75, 12, -75, 28, -74, 43, +-76, 58, -82, 63, -82, 61, -79, 49, +-73, 31, -72, 14, -71, 1, -69, -5, +-66, -2, -66, 8, -71, 23, -73, 38, +-76, 49, -80, 50, -86, 42, -89, 32, +-90, 20, -83, 10, -82, 5, -76, 13, +-68, 24, -60, 37, -59, 50, -66, 58, +-69, 55, -74, 39, -78, 17, -88, -5, +-91, -19, -89, -24, -83, -13, -81, 8, +-77, 34, -71, 57, -64, 70, -65, 76, +-76, 71, -81, 53, -84, 27, -82, 1, +-86, -13, -85, -12, -82, -5, -73, 5, +-68, 21, -69, 36, -76, 43, -83, 41, +-89, 32, -95, 22, -95, 18, -97, 18, +-89, 28, -80, 39, -69, 52, -63, 60, +-62, 59, -62, 46, -68, 24, -81, 1, +-99, -18, -109, -30, -112, -29, -108, -12, +-102, 15, -89, 48, -76, 78, -66, 97, +-66, 98, -67, 83, -69, 55, -74, 21, +-86, -9, -101, -30, -99, -37, -96, -28, +-95, -4, -96, 21, -89, 44, -84, 62, +-83, 70, -87, 62, -85, 46, -80, 28, +-78, 15, -81, 11, -88, 12, -84, 19, +-81, 26, -81, 36, -90, 42, -96, 43, +-100, 36, -103, 24, -106, 11, -103, 4, +-94, 3, -86, 8, -79, 18, -74, 30, +-69, 45, -74, 55, -78, 61, -91, 60, +-104, 55, -112, 38, -114, 23, -113, 13, +-110, 6, -100, 3, -88, 1, -77, 8, +-72, 16, -70, 26, -74, 34, -78, 41, +-85, 44, -93, 47, -108, 50, -118, 49, +-118, 43, -112, 33, -104, 24, -98, 18, +-86, 12, -77, 8, -71, 7, -72, 8, +-71, 12, -74, 18, -84, 28, -103, 39, +-118, 48, -123, 52, -122, 50, -117, 47, +-111, 41, -93, 31, -76, 21, -66, 16, +-67, 10, -69, 7, -71, 5, -82, 5, +-101, 11, -117, 21, -123, 35, -125, 47, +-123, 56, -114, 59, -97, 58, -85, 50, +-76, 38, -74, 24, -73, 9, -79, -1, +-90, -6, -102, -6, -109, 2, -109, 18, +-112, 38, -112, 56, -111, 65, -104, 67, +-101, 59, -96, 46, -93, 26, -87, 9, +-85, -1, -85, -5, -85, 0, -88, 11, +-93, 26, -103, 40, -109, 48, -116, 47, +-121, 43, -127, 34, -119, 23, -104, 15, +-90, 18, -83, 28, -75, 37, -65, 41, +-66, 44, -78, 44, -99, 37, -113, 22, +-127, 4, -138, -8, -143, -16, -130, -11, +-109, 7, -91, 31, -76, 53, -63, 74, +-56, 85, -63, 81, -81, 66, -102, 39, +-115, 12, -133, -11, -143, -27, -143, -32, +-129, -21, -111, 0, -95, 24, -80, 44, +-68, 58, -64, 67, -73, 66, -85, 58, +-101, 46, -112, 37, -124, 27, -130, 21, +-133, 19, -126, 19, -116, 16, -106, 11, +-95, 7, -90, 4, -86, 4, -86, 7, +-85, 16, -88, 34, -92, 54, -103, 70, +-111, 79, -119, 78, -125, 68, -127, 46, +-126, 18, -118, -7, -113, -25, -104, -30, +-94, -25, -80, -5, -75, 21, -78, 46, +-84, 64, -93, 73, -105, 72, -121, 64, +-135, 47, -138, 27, -131, 12, -124, 3, +-112, 1, -100, 8, -82, 21, -77, 31, +-79, 38, -87, 37, -93, 34, -101, 26, +-113, 19, -122, 18, -126, 20, -120, 25, +-117, 32, -114, 41, -109, 44, -98, 44, +-93, 40, -93, 32, -97, 22, -98, 16, +-98, 15, -104, 17, -108, 24, -111, 32, +-115, 40, -120, 40, -120, 35, -117, 26, +-109, 19, -105, 15, -101, 15, -97, 21, +-94, 32, -96, 45, -101, 57, -107, 65, +-118, 61, -123, 48, -128, 29, -125, 10, +-118, -6, -106, -14, -97, -13, -86, -1, +-80, 18, -84, 40, -94, 59, -108, 67, +-117, 67, -127, 57, -133, 43, -134, 26, +-122, 11, -110, 4, -99, 6, -90, 10, +-81, 16, -80, 23, -92, 31, -107, 37, +-121, 40, -129, 40, -135, 37, -136, 37, +-129, 35, -110, 34, -97, 34, -89, 31, +-85, 27, -81, 20, -86, 12, -99, 7, +-109, 7, -117, 10, -117, 19, -122, 30, +-124, 44, -121, 53, -112, 56, -107, 51, +-104, 42, -105, 32, -104, 20, -102, 9, +-101, -1, -96, 0, -97, 10, -99, 24, +-105, 34, -110, 44, -118, 48, -124, 48, +-127, 44, -126, 37, -121, 31, -112, 25, +-100, 20, -90, 15, -79, 13, -77, 14, +-81, 16, -95, 17, -108, 21, -124, 24, +-136, 32, -144, 41, -140, 47, -126, 51, +-114, 50, -96, 43, -79, 31, -67, 20, +-71, 8, -80, -1, -94, -4, -107, -1, +-125, 10, -137, 25, -140, 39, -134, 52, +-122, 57, -112, 54, -97, 45, -84, 30, +-73, 17, -77, 8, -84, 7, -94, 10, +-104, 19, -117, 28, -130, 35, -136, 40, +-133, 38, -125, 30, -118, 19, -106, 13, +-92, 9, -80, 13, -76, 22, -74, 34, +-79, 48, -92, 57, -110, 56, -128, 47, +-137, 28, -137, 5, -130, -10, -125, -14, +-115, -6, -102, 10, -87, 30, -78, 48, +-70, 60, -73, 64, -84, 60, -102, 45, +-119, 25, -130, 8, -141, 0, -142, 0, +-136, 8, -122, 23, -109, 37, -94, 49, +-81, 50, -70, 41, -70, 29, -79, 14, +-91, 3, -104, -1, -118, 7, -133, 22, +-136, 39, -134, 56, -129, 67, -125, 65, +-115, 55, -104, 36, -89, 11, -78, -14, +-71, -28, -69, -24, -73, -7, -83, 16, +-100, 41, -115, 66, -133, 79, -146, 75, +-151, 57, -145, 35, -128, 10, -105, -9, +-84, -17, -67, -12, -54, 3, -51, 20, +-59, 36, -78, 45, -101, 52, -130, 50, +-151, 41, -164, 26, -160, 15, -143, 10, +-116, 12, -90, 19, -67, 27, -52, 37, +-50, 39, -56, 34, -73, 25, -94, 18, +-120, 9, -139, 6, -149, 8, -146, 16, +-133, 27, -116, 40, -100, 52, -86, 55, +-75, 48, -72, 36, -72, 21, -77, 6, +-86, -4, -99, -10, -107, -7, -111, 4, +-114, 22, -118, 40, -121, 52, -119, 57, +-112, 53, -102, 43, -97, 28, -86, 16, +-77, 6, -74, 3, -81, 3, -85, 7, +-92, 13, -103, 24, -116, 33, -126, 40, +-127, 43, -124, 39, -114, 33, -103, 24, +-85, 19, -71, 15, -66, 14, -73, 16, +-81, 17, -91, 21, -105, 28, -119, 33, +-128, 33, -125, 32, -119, 28, -108, 24, +-99, 18, -84, 15, -74, 14, -71, 16, +-77, 20, -84, 25, -93, 31, -102, 37, +-110, 41, -119, 39, -118, 33, -117, 25, +-111, 19, -107, 14, -99, 11, -93, 11, +-84, 16, -79, 21, -78, 30, -81, 38, +-91, 45, -97, 45, -104, 34, -109, 27, +-119, 19, -119, 13, -116, 8, -107, 10, +-97, 14, -85, 22, -75, 31, -72, 35, +-74, 36, -81, 34, -88, 27, -99, 18, +-109, 12, -120, 10, -120, 15, -114, 21, +-103, 30, -93, 37, -82, 40, -72, 40, +-74, 34, -78, 21, -84, 7, -90, -2, +-100, -5, -109, -1, -113, 11, -108, 27, +-101, 43, -94, 55, -93, 62, -90, 58, +-86, 43, -87, 23, -90, 4, -94, -8, +-93, -10, -94, -7, -93, 7, -94, 24, +-92, 38, -91, 49, -93, 51, -98, 44, +-99, 31, -100, 17, -101, 4, -96, 1, +-94, 8, -84, 20, -81, 33, -77, 45, +-81, 52, -88, 50, -96, 39, -103, 19, +-106, -4, -106, -20, -102, -27, -95, -19, +-84, 1, -77, 29, -73, 56, -76, 72, +-73, 79, -83, 74, -96, 56, -104, 26, +-105, -2, -103, -20, -105, -28, -98, -26, +-90, -15, -79, 7, -74, 27, -74, 44, +-77, 53, -83, 57, -93, 54, -101, 44, +-105, 32, -103, 25, -96, 21, -91, 18, +-83, 18, -82, 17, -78, 14, -77, 7, +-80, 1, -86, -3, -89, -4, -93, 2, +-96, 15, -97, 34, -94, 54, -92, 66, +-88, 69, -83, 65, -83, 49, -77, 25, +-76, 0, -76, -19, -83, -29, -87, -28, +-91, -16, -95, 3, -97, 24, -96, 42, +-92, 54, -88, 60, -80, 57, -75, 44, +-69, 32, -71, 20, -69, 10, -73, 3, +-80, 0, -92, 2, -98, 5, -100, 10, +-106, 15, -102, 21, -97, 26, -86, 33, +-81, 36, -74, 40, -67, 39, -62, 39, +-67, 35, -75, 26, -85, 15, -90, 8, +-93, 1, -98, -2, -97, 1, -97, 6, +-86, 17, -82, 27, -80, 35, -76, 38, +-71, 37, -68, 33, -71, 27, -74, 18, +-71, 10, -71, 9, -80, 12, -87, 14, +-92, 15, -90, 16, -96, 16, -95, 18, +-93, 18, -86, 20, -74, 22, -68, 23, +-59, 24, -54, 27, -51, 29, -60, 25, +-72, 22, -87, 18, -101, 13, -113, 6, +-111, 2, -104, 5, -90, 11, -73, 21, +-60, 30, -50, 37, -49, 39, -48, 34, +-59, 26, -72, 17, -89, 7, -102, 2, +-108, 2, -102, 7, -96, 14, -84, 23, +-68, 29, -58, 33, -55, 32, -57, 22, +-55, 13, -66, 5, -74, 3, -84, 6, +-89, 12, -89, 21, -86, 30, -81, 36, +-80, 39, -77, 35, -73, 24, -74, 14, +-77, 5, -74, -1, -72, -2, -64, 5, +-65, 15, -66, 25, -69, 31, -69, 35, +-74, 34, -86, 29, -89, 19, -93, 9, +-89, 6, -82, 6, -73, 15, -66, 26, +-58, 33, -56, 34, -54, 33, -61, 26, +-68, 14, -80, 3, -91, -7, -88, -8, +-95, 1, -94, 16, -89, 30, -73, 43, +-63, 50, -54, 50, -49, 42, -50, 30, +-57, 15, -65, -3, -72, -15, -76, -16, +-82, -10, -91, -2, -86, 9, -82, 21, +-72, 33, -70, 39, -65, 40, -59, 35, +-55, 28, -52, 26, -60, 24, -66, 18, +-66, 12, -69, 9, -78, 5, -82, 1, +-84, -2, -76, -4, -75, -3, -69, 7, +-67, 17, -63, 27, -55, 39, -59, 47, +-60, 50, -64, 45, -66, 37, -73, 21, +-78, 4, -75, -10, -69, -17, -68, -17, +-67, -11, -68, -1, -61, 11, -55, 24, +-64, 38, -70, 46, -73, 44, -66, 36, +-69, 26, -65, 16, -60, 6, -57, -1, +-54, -3, -54, 0, -61, 4, -69, 7, +-73, 12, -76, 16, -76, 19, -76, 21, +-68, 23, -65, 22, -54, 21, -49, 21, +-47, 22, -48, 21, -57, 17, -67, 13, +-78, 10, -78, 8, -78, 4, -75, 1, +-67, 3, -56, 10, -52, 20, -49, 28, +-55, 32, -59, 33, -61, 28, -65, 20, +-71, 13, -78, 6, -69, 0, -68, -2, +-61, 1, -54, 9, -51, 18, -53, 25, +-54, 28, -58, 28, -62, 23, -62, 15, +-61, 6, -64, 1, -68, 1, -61, 3, +-57, 3, -48, 8, -54, 17, -59, 24, +-57, 24, -56, 22, -61, 20, -67, 16, +-61, 11, -59, 7, -60, 7, -59, 8, +-54, 11, -56, 13, -56, 15, -58, 15, +-55, 14, -59, 15, -62, 18, -66, 17, +-64, 15, -52, 12, -54, 13, -56, 15, +-53, 11, -48, 10, -52, 9, -56, 10, +-60, 12, -63, 15, -66, 16, -63, 17, +-64, 21, -63, 22, -57, 22, -58, 20, +-54, 18, -54, 11, -49, 7, -51, 7, +-52, 8, -53, 8, -57, 11, -59, 17, +-63, 20, -69, 19, -63, 16, -55, 16, +-58, 16, -57, 14, -51, 11, -39, 13, +-42, 14, -44, 14, -48, 13, -54, 12, +-57, 10, -64, 6, -66, 3, -65, 3, +-61, 9, -58, 15, -53, 25, -50, 33, +-47, 36, -51, 33, -49, 29, -55, 18, +-57, 5, -58, -5, -63, -14, -55, -16, +-51, -9, -44, 6, -46, 18, -47, 32, +-49, 39, -55, 42, -56, 35, -54, 20, +-62, 6, -62, -4, -52, -12, -41, -16, +-37, -9, -41, 3, -35, 17, -42, 24, +-49, 29, -59, 26, -62, 17, -59, 7, +-62, 2, -59, -2, -47, -4, -35, 4, +-34, 14, -37, 23, -38, 29, -41, 31, +-57, 23, -59, 10, -65, -3, -63, -10, +-56, -14, -48, -10, -41, 2, -40, 14, +-31, 28, -34, 36, -41, 37, -52, 32, +-60, 23, -66, 8, -65, -2, -67, -7, +-61, -8, -47, -4, -30, 4, -26, 14, +-28, 24, -23, 28, -37, 25, -51, 20, +-64, 11, -67, 2, -67, -6, -68, -6, +-61, -1, -46, 6, -28, 17, -22, 28, +-28, 34, -28, 30, -28, 21, -41, 8, +-50, -4, -60, -12, -64, -14, -69, -11, +-61, -2, -52, 10, -48, 24, -37, 35, +-33, 42, -32, 41, -32, 32, -36, 19, +-41, 3, -43, -10, -49, -18, -48, -18, +-53, -13, -51, -1, -56, 11, -55, 23, +-40, 32, -41, 36, -43, 36, -44, 26, +-35, 17, -34, 7, -37, -2, -39, -7, +-42, -8, -41, -8, -37, -5, -42, 1, +-41, 10, -41, 16, -47, 20, -46, 20, +-47, 17, -42, 16, -50, 13, -48, 11, +-41, 10, -37, 9, -31, 11, -32, 15, +-37, 17, -39, 14, -37, 10, -42, 8, +-53, 7, -63, 1, -59, -2, -54, 0, +-42, 7, -42, 13, -36, 21, -21, 26, +-18, 28, -21, 26, -31, 20, -35, 14, +-48, 3, -61, -7, -61, -13, -57, -12, +-53, -8, -41, -1, -34, 9, -20, 19, +-12, 25, -17, 27, -29, 26, -41, 22, +-40, 14, -54, 4, -58, -2, -55, -3, +-50, 0, -41, 6, -33, 11, -29, 15, +-27, 15, -26, 11, -27, 7, -35, 2, +-42, -1, -42, 0, -49, 6, -42, 17, +-44, 25, -41, 32, -33, 30, -28, 24, +-30, 15, -38, 2, -32, -13, -34, -25, +-45, -26, -45, -20, -35, -6, -33, 13, +-32, 31, -34, 43, -26, 49, -25, 46, +-29, 34, -39, 18, -48, -2, -42, -23, +-46, -34, -45, -33, -39, -24, -34, -9, +-31, 10, -24, 26, -19, 39, -22, 48, +-29, 43, -28, 29, -33, 14, -38, 1, +-37, -10, -43, -19, -40, -21, -41, -15, +-36, -5, -31, 1, -23, 7, -24, 13, +-33, 21, -27, 24, -23, 22, -32, 18, +-33, 13, -28, 13, -28, 13, -33, 14, +-40, 10, -35, 4, -36, -6, -32, -14, +-32, -16, -34, -15, -25, -12, -26, -6, +-27, 10, -26, 27, -22, 38, -25, 43, +-32, 43, -32, 34, -30, 19, -37, 3, +-37, -12, -45, -24, -47, -29, -38, -25, +-33, -13, -27, 3, -28, 18, -16, 32, +-13, 40, -12, 40, -13, 31, -25, 20, +-32, 9, -39, -2, -53, -9, -57, -12, +-50, -10, -42, -6, -35, 2, -23, 7, +2, 10, 5, 14, 4, 15, -5, 10, +-12, 6, -18, 3, -36, 2, -55, 2, +-59, 1, -48, 2, -39, 3, -33, 6, +-18, 7, -4, 8, -4, 8, 2, 10, +-9, 12, -23, 11, -33, 7, -39, 6, +-42, 7, -50, 8, -44, 9, -37, 6, +-26, 3, -15, 2, -11, 5, -10, 4, +-10, 5, -21, 7, -25, 7, -21, 6, +-18, 7, -28, 9, -35, 9, -20, 8, +-20, 5, -22, 3, -29, 1, -31, -3, +-28, -3, -30, 1, -34, 5, -30, 7, +-16, 10, -8, 16, -12, 22, -5, 21, +-3, 19, -20, 15, -30, 8, -39, -4, +-39, -12, -45, -13, -48, -8, -43, 0, +-37, 9, -15, 17, 0, 24, 3, 28, +4, 28, 0, 24, -6, 14, -15, 3, +-34, -8, -47, -15, -49, -19, -40, -14, +-42, -5, -36, 2, -10, 11, 0, 18, +6, 23, 9, 22, 9, 19, 1, 14, +-19, 9, -35, 4, -42, -1, -45, -4, +-46, -4, -50, -2, -34, 1, -13, 6, +-6, 7, 1, 11, 2, 13, 6, 16, +-2, 16, -10, 16, -21, 13, -36, 9, +-36, 4, -33, -2, -32, -6, -26, -8, +-18, -10, -9, -7, -5, 2, -7, 7, +-5, 14, -12, 19, -12, 25, -21, 23, +-27, 19, -17, 10, -16, 0, -18, -7, +-18, -11, -9, -10, -10, -6, -21, -3, +-23, 0, -21, 7, -19, 13, -15, 16, +-22, 17, -18, 16, -8, 14, -7, 12, +-7, 12, -11, 9, -10, 8, -21, 6, +-26, 5, -26, 2, -30, -1, -27, -2, +-23, -1, -19, -2, -6, -2, 2, 3, +4, 11, -3, 17, -8, 19, -8, 21, +-18, 18, -18, 9, -24, -2, -26, -8, +-15, -12, -6, -13, -6, -10, -12, -2, +-7, 9, -6, 16, -14, 19, -14, 17, +-16, 14, -18, 9, -14, 5, -19, 1, +-12, -2, -7, 0, -7, 5, -12, 10, +-15, 17, -9, 20, -21, 19, -25, 13, +-19, 3, -16, -1, -13, -5, -8, -11, +-3, -10, -1, -4, 1, 3, 7, 12, +-5, 19, -17, 24, -21, 24, -26, 16, +-18, 7, -18, 1, -19, -3, -12, -4, +-3, -4, 2, -1, 2, 4, 5, 9, +2, 13, -13, 12, -16, 8, -13, 4, +-19, 3, -26, 5, -31, 5, -17, 6, +-4, 9, 2, 14, 1, 19, 0, 20, +11, 17, 5, 11, -8, 3, -13, -7, +-16, -13, -21, -15, -23, -12, -18, -7, +-14, 4, -15, 18, -4, 29, -1, 36, +0, 38, 1, 32, -2, 18, -1, 3, +-4, -12, -5, -19, -9, -23, -12, -21, +-13, -14, -14, -2, -5, 11, -2, 24, +-15, 33, -17, 34, -8, 28, -1, 18, +-3, 8, -8, -1, 1, -7, 5, -12, +10, -10, 6, -6, -3, 0, -1, 6, +-9, 10, -20, 11, -21, 9, -19, 8, +-20, 7, -18, 7, -1, 6, 13, 9, +18, 13, 25, 17, 16, 18, 8, 14, +3, 8, -11, 0, -27, -9, -38, -16, +-34, -17, -25, -13, -11, -4, 4, 8, +12, 22, 26, 34, 35, 43, 22, 39, +8, 28, -1, 11, -12, -7, -26, -22, +-34, -32, -24, -34, -18, -29, -4, -13, +4, 9, 11, 30, 23, 40, 22, 44, +13, 40, 5, 29, 3, 12, -2, -5, +-18, -15, -21, -22, -12, -23, -7, -18, +5, -7, 7, 1, 9, 11, 10, 19, +10, 20, 7, 17, -2, 10, -1, 4, +-1, 2, -2, 4, 2, 7, 3, 11, +4, 14, 8, 15, 5, 9, 3, 2, +0, -4, -3, -11, -14, -15, -16, -16, +-1, -11, 4, 1, 5, 17, 7, 31, +13, 41, 19, 44, 17, 36, 9, 22, +-2, 6, -6, -14, -5, -30, -11, -38, +-9, -35, -4, -21, -5, -3, 4, 17, +12, 31, 19, 39, 19, 40, 18, 33, +16, 19, 7, 6, 4, -5, -4, -14, +-13, -16, -10, -13, -4, -6, 1, 1, +5, 11, 4, 14, 8, 14, 14, 8, +23, 2, 14, 1, 1, 2, 6, 4, +8, 9, 5, 15, 3, 19, 5, 20, +10, 14, 10, 5, 10, -4, 7, -13, +4, -19, 3, -19, -6, -14, -2, -4, +9, 7, 12, 18, 13, 30, 16, 33, +24, 30, 23, 21, 17, 8, 10, -8, +1, -17, 0, -19, -4, -17, -10, -12, +-9, -1, -2, 11, 11, 18, 19, 22, +23, 21, 26, 16, 23, 9, 24, 2, +15, -4, 2, -3, -2, -2, -4, 0, +-6, 6, -7, 12, 3, 15, 11, 13, +12, 9, 17, 3, 20, 0, 22, -6, +22, -8, 12, -8, 10, -3, 13, 7, +11, 15, 6, 19, 2, 21, 5, 25, +1, 21, 2, 13, 5, 2, 3, -8, +10, -18, 20, -20, 22, -14, 23, -7, +24, 3, 25, 13, 18, 22, 11, 29, +7, 31, -3, 26, -6, 18, -10, 6, +-6, -4, 6, -11, 15, -12, 18, -10, +20, -7, 33, 0, 37, 8, 25, 14, +17, 13, 11, 14, 4, 13, 2, 11, +-5, 8, -5, 6, 0, 5, 11, 6, +19, 5, 24, 2, 33, 2, 29, 1, +23, -2, 22, -5, 16, -4, 9, -1, +2, 4, -1, 10, 0, 19, 3, 24, +12, 25, 13, 21, 17, 13, 27, 4, +28, -8, 27, -12, 17, -15, 10, -14, +11, -11, 12, 0, 10, 13, 2, 24, +7, 29, 16, 29, 16, 24, 20, 13, +23, 3, 21, -8, 18, -16, 16, -18, +16, -14, 14, -9, 17, -2, 17, 8, +15, 18, 23, 23, 22, 24, 16, 19, +15, 11, 14, 6, 12, 1, 7, -3, +6, -6, 8, -5, 12, -3, 23, 0, +27, 1, 30, 2, 37, 3, 33, 5, +27, 7, 20, 7, 13, 8, 5, 9, +-1, 8, 3, 5, 7, 4, 16, 0, +25, 0, 24, -2, 30, -5, 39, -5, +40, -4, 29, 3, 15, 10, 9, 18, +0, 21, -1, 21, 0, 14, 3, 7, +16, 0, 28, -8, 34, -11, 34, -9, +33, -5, 32, 1, 21, 9, 15, 16, +10, 18, 7, 16, 11, 15, 10, 10, +13, 5, 20, 1, 23, 0, 20, -2, +18, -3, 24, 0, 24, 3, 16, 9, +13, 13, 11, 15, 18, 13, 24, 13, +21, 12, 18, 12, 18, 8, 24, 3, +21, -2, 15, -5, 17, -7, 16, -9, +20, -7, 24, -4, 24, 1, 28, 6, +32, 10, 35, 12, 30, 16, 25, 21, +19, 22, 7, 15, 8, 2, 14, -7, +16, -14, 21, -18, 22, -18, 24, -9, +29, -2, 34, 6, 33, 13, 27, 19, +28, 21, 28, 21, 20, 19, 14, 14, +7, 7, 8, -3, 16, -12, 22, -18, +26, -16, 28, -12, 34, -5, 33, 1, +31, 8, 34, 14, 27, 16, 21, 16, +19, 12, 16, 10, 16, 7, 13, 5, +12, 3, 13, 1, 22, -2, 31, -3, +27, -1, 27, -1, 31, -1, 31, 1, +31, 3, 28, 1, 25, 5, 19, 10, +17, 12, 17, 13, 11, 15, 13, 12, +15, 7, 16, 2, 26, -2, 32, -5, +34, -6, 34, -7, 35, -6, 36, -1, +31, 3, 25, 9, 14, 13, 7, 15, +10, 16, 11, 12, 12, 7, 16, 4, +23, 0, 31, -4, 36, -3, 38, -1, +32, 2, 28, 4, 28, 10, 21, 13, +15, 12, 13, 9, 14, 5, 15, 2, +16, 1, 23, 1, 25, -1, 28, -2, +34, -1, 35, 4, 36, 8, 34, 10, +25, 9, 20, 9, 19, 6, 21, 1, +20, -3, 19, -6, 22, -2, 21, 2, +27, 8, 28, 12, 21, 12, 26, 7, +33, 2, 35, 0, 29, -3, 28, -6, +30, -7, 29, -5, 28, 1, 27, 10, +24, 14, 22, 14, 17, 12, 15, 12, +19, 6, 24, -3, 25, -9, 25, -11, +33, -9, 41, -4, 40, 3, 38, 7, +31, 13, 31, 12, 30, 10, 20, 7, +10, 3, 10, -3, 14, -6, 15, -5, +21, -3, 33, 1, 37, 6, 39, 12, +40, 15, 39, 15, 37, 10, 25, 2, +17, -5, 13, -10, 17, -16, 21, -16, +20, -9, 25, 1, 30, 11, 35, 18, +40, 21, 40, 17, 37, 12, 31, 6, +28, 0, 21, -6, 12, -11, 15, -12, +17, -9, 18, -1, 24, 5, 30, 8, +35, 11, 35, 13, 33, 13, 31, 10, +28, 3, 28, -1, 22, -2, 21, -1, +27, -1, 28, -2, 27, 2, 29, 3, +31, 1, 30, -3, 31, -6, 33, -7, +26, -3, 20, 0, 24, 2, 29, 2, +34, 5, 33, 12, 31, 16, 31, 15, +32, 9, 30, 1, 26, -8, 28, -12, +27, -13, 19, -12, 18, -11, 25, -7, +28, 0, 29, 8, 34, 12, 41, 14, +42, 16, 36, 15, 31, 11, 29, 4, +26, -2, 19, -9, 13, -13, 18, -12, +22, -8, 24, -7, 28, -3, 37, 5, +42, 12, 37, 17, 33, 17, 29, 15, +28, 7, 23, 4, 19, 0, 22, -4, +21, -4, 20, -4, 26, -6, 38, -9, +42, -5, 38, -4, 36, -1, 34, 4, +28, 6, 29, 3, 32, 3, 28, 8, +22, 12, 24, 11, 28, 7, 29, 0, +30, -9, 32, -11, 32, -11, 33, -11, +31, -11, 30, -3, 30, 5, 29, 12, +27, 18, 26, 19, 28, 15, 28, 8, +26, 2, 32, -9, 38, -19, 39, -23, +37, -20, 33, -16, 32, -6, 31, 3, +28, 8, 24, 13, 25, 16, 30, 15, +30, 10, 32, 5, 35, -3, 35, -9, +36, -16, 39, -16, 38, -13, 29, -7, +23, -3, 23, 2, 22, 9, 24, 12, +24, 8, 27, 2, 36, 3, 39, 3, +36, 0, 37, -3, 40, -1, 32, 1, +22, 4, 21, 2, 24, -4, 20, -7, +19, -6, 24, -5, 31, -8, 37, -5, +41, 0, 41, 8, 37, 14, 34, 17, +32, 11, 30, 4, 25, -3, 21, -10, +23, -14, 25, -14, 27, -11, 28, -8, +32, 0, 39, 6, 39, 9, 37, 10, +36, 10, 32, 6, 26, -1, 24, -6, +28, -8, 27, -6, 24, -1, 24, 1, +31, -1, 39, -3, 43, 0, 37, 4, +33, -2, 33, -5, 33, -4, 30, -4, +26, -4, 25, -2, 28, 2, 30, 3, +31, 5, 33, 3, 38, 1, 38, -1, +35, -3, 35, -6, 34, -2, 27, 2, +20, 0, 20, -3, 26, -2, 33, 0, +35, 1, 32, 3, 35, 1, 41, 0, +41, 0, 34, 1, 30, -3, 29, -7, +27, -4, 21, 1, 20, 3, 25, 3, +30, 5, 36, 0, 42, -3, 49, -2, +46, 0, 34, -6, 27, -8, 30, -9, +26, -5, 14, 5, 12, 7, 22, 7, +29, 7, 32, 11, 40, 7, 48, 0, +45, -5, 37, -7, 34, -10, 33, -9, +27, -8, 16, -7, 17, -3, 27, 1, +29, 6, 27, 7, 35, 9, 43, 3, +45, -4, 45, -4, 43, -1, 36, -6, +27, -12, 25, -11, 26, -9, 23, -6, +22, -3, 27, -1, 34, 0, 40, 6, +44, 7, 44, 5, 42, 2, 33, 2, +26, -3, 25, -6, 22, -4, 13, -5, +16, -7, 29, -5, 38, 2, 38, 2, +42, 3, 49, 2, 46, 1, 37, -2, +29, -1, 25, -4, 25, -11, 22, -9, +20, -6, 29, -4, 39, -3, 38, -1, +36, 0, 43, 2, 49, 2, 40, 0, +27, -1, 26, 3, 26, 7, 16, 3, +9, -2, 22, -7, 39, -10, 41, -13, +38, -9, 47, -6, 57, -1, 46, 2, +31, 7, 31, 8, 27, 10, 14, 6, +8, -7, 21, -13, 31, -10, 30, -7, +32, -9, 45, -2, 53, 7, 45, 10, +36, 11, 35, 7, 32, 1, 23, -2, +15, -4, 20, -11, 26, -16, 30, -14, +39, -6, 47, -5, 48, -2, 47, 1, +46, 1, 43, -1, 36, 0, 28, 0, +23, -2, 21, -2, 23, -1, 26, -1, +30, 1, 35, 1, 38, -8, 44, -10, +45, -5, 41, -1, 34, -4, 28, -3, +28, 1, 27, 3, 26, 6, 28, 4, +29, 1, 33, 0, 37, 1, 40, -3, +42, -8, 40, -8, 33, -7, 29, -9, +32, -9, 33, -6, 27, -8, 27, -5, +38, 0, 46, 6, 40, 9, 34, 14, +37, 9, 36, 1, 27, -2, 21, -5, +25, -13, 26, -19, 20, -13, 23, -6, +40, -2, 50, 1, 45, 2, 44, 2, +50, 9, 46, 8, 32, -3, 24, -7, +21, -4, 16, -2, 14, -3, 19, -2, +29, -2, 35, -4, 41, -7, 51, -8, +58, -11, 56, -9, 46, -7, 35, -5, +28, -1, 25, 6, 21, 7, 13, 4, +11, 4, 22, 2, 39, -5, 49, -15, +51, -13, 51, -10, 51, -5, 44, -2, +33, -2, 27, -1, 20, 3, 12, 6, +13, 1, 26, -1, 37, -1, 40, 0, +42, -2, 48, -1, 55, -5, 51, -10, +39, -10, 31, -11, 27, -11, 25, -8, +24, -3, 25, -2, 26, 4, 31, 9, +41, 6, 49, -6, 51, -8, 49, -7, +44, -10, 39, -10, 37, -8, 34, -8, +28, -5, 25, 2, 26, 1, 31, -4, +34, -6, 41, -6, 46, -10, 44, -6, +42, -1, 45, -3, 46, -3, 35, 4, +23, 8, 24, 2, 30, -4, 33, -14, +35, -17, 44, -12, 48, -4, 41, -3, +36, 0, 39, 8, 35, 10, 22, 3, +21, -2, 30, -3, 32, -5, 29, -3, +37, -6, 49, -7, 52, -4, 45, 0, +44, -2, 43, -4, 29, 0, 18, -3, +22, -9, 28, -5, 23, 5, 21, 3, +39, -3, 55, -5, 55, -4, 52, -6, +53, -5, 48, -7, 34, -10, 23, -1, +19, 7, 15, 3, 15, -3, 20, 1, +32, -1, 46, -5, 51, -8, 51, -8, +53, -8, 54, -2, 43, 6, 28, 5, +22, 3, 19, 2, 18, -3, 21, -11, +30, -7, 38, -6, 41, -11, 45, -8, +55, 0, 58, 0, 48, -2, 37, -3, +35, -6, 33, -7, 23, -7, 23, -9, +34, -14, 39, -7, 36, 2, 40, 4, +55, 0, 53, -2, 37, -6, 36, -11, +45, -14, 42, -15, 25, -15, 25, -9, +41, -3, 41, 1, 33, 6, 42, 5, +55, -1, 48, -8, 35, -5, 38, -3, +41, -7, 29, -10, 19, -8, 23, -2, +34, 0, 35, 0, 32, -6, 41, -7, +55, -3, 56, -2, 50, -7, 47, -3, +44, 5, 31, 3, 19, -1, 19, -2, +23, -7, 27, -13, 29, -11, 39, -11, +53, -8, 61, -1, 54, 5, 45, 3, +42, 7, 36, 10, 25, -1, 19, -9, +24, -10, 26, -6, 30, -7, 40, -8, +53, -8, 55, -6, 52, -2, 50, -2, +46, -9, 38, -10, 30, -3, 27, -1, +26, -1, 25, 3, 32, 5, 44, 1, +48, -2, 44, -5, 47, -11, 52, -13, +46, -12, 35, -12, 32, -7, 34, 4, +27, 7, 22, 4, 30, 5, 38, 8, +36, -3, 38, -10, 49, -11, 55, -6, +43, -1, 32, -1, 40, -4, 46, -9, +36, -4, 28, -2, 33, -10, 39, -13, +36, -8, 38, -6, 46, -3, 47, 4, +40, 5, 37, 1, 41, -3, 44, -6, +37, -8, 29, -9, 29, -10, 42, -12, +47, -10, 41, 4, 38, 6, 43, -3, +47, -3, 37, 2, 29, 0, 30, -5, +28, -5, 25, -6, 26, -2, 38, 3, +47, 2, 42, -4, 41, -2, 53, -3, +58, -9, 46, -12, 34, -8, 32, -5, +29, -4, 22, 0, 21, 0, 28, -3, +36, -6, 41, -6, 50, -10, 60, -6, +60, -1, 54, -4, 44, -4, 37, 3, +33, 5, 24, -4, 13, -7, 13, -10, +27, -10, 43, -9, 46, -4, 48, -4, +57, 0, 63, 5, 54, 4, 40, -3, +36, -7, 32, -8, 21, -15, 18, -13, +31, -3, 35, 4, 31, 2, 37, 3, +53, 1, 60, -3, 52, -8, 46, -15, +43, -17, 40, -11, 33, -1, 29, 0, +29, 2, 27, 8, 28, 10, 36, 0, +46, -9, 47, -15, 46, -17, 49, -12, +45, -5, 38, -2, 37, -1, 38, 7, +33, 5, 27, 1, 33, 0, 38, -2, +36, -10, 36, -12, 43, -7, 49, -3, +46, -4, 41, -7, 43, -7, 41, -5, +35, -1, 31, -6, 36, -11, 42, -6, +41, 3, 40, 2, 44, -1, 47, 0, +42, 0, 33, -4, 29, -9, 34, -13, +38, -17, 35, -10, 35, -3, 45, 2, +47, 7, 39, 10, 41, 3, 49, -6, +45, -7, 31, -8, 27, -11, 34, -10, +32, -1, 22, 5, 25, 7, 43, 1, +52, -6, 46, -9, 47, -6, 55, -9, +48, -15, 31, -7, 29, 6, 32, 9, +23, 7, 16, 8, 27, 0, 45, -8, +49, -13, 45, -14, 52, -18, 59, -14, +50, -8, 41, -6, 40, 1, 34, 8, +22, 6, 19, -2, 29, 0, 35, 1, +33, -5, 38, -10, 51, -9, 55, -6, +47, 0, 41, 1, 38, -6, 36, -7, +31, -1, 28, 0, 33, -8, 36, -4, +32, 4, 33, 4, 40, 0, 44, 0, +38, -4, 33, -8, 41, -8, 45, -7, +38, -3, 32, 3, 32, 8, 35, 3, +32, 2, 33, 2, 39, -6, 43, -17, +39, -16, 37, -9, 45, -4, 47, 0, +36, -1, 33, -1, 42, 2, 44, 0, +38, -11, 36, -14, 41, -8, 41, -4, +38, -6, 43, -4, 49, -3, 47, -7, +39, -8, 38, -6, 39, -6, 33, -11, +30, -10, 36, -9, 43, -3, 43, 8, +41, 12, 44, 4, 44, -1, 37, 0, +34, -4, 34, -13, 30, -17, 26, -13, +29, -6, 40, 1, 45, 1, 46, 2, +45, 8, 45, 9, 43, -1, 39, -10, +39, -11, 36, -11, 29, -10, 26, -6, +32, -1, 39, -3, 42, -2, 42, -3, +44, -5, 48, -2, 46, 2, 40, -1, +33, -3, 34, 5, 35, 5, 32, -5, +31, -13, 40, -13, 45, -15, 41, -16, +41, -11, 46, -4, 46, 3, 37, 10, +33, 9, 42, 3, 43, 3, 32, 2, +28, -9, 38, -20, 47, -17, 41, -14, +37, -9, 42, -4, 43, 1, 39, 0, +38, -2, 44, -3, 44, -6, 35, 0, +33, 2, 37, -4, 41, -6, 41, 2, +38, 1, 39, -6, 39, -10, 41, -11, +40, -12, 35, -10, 36, -7, 42, -10, +42, -3, 37, 7, 38, 8, 44, 1, +41, -1, 39, -5, 45, -12, 50, -13, +42, -8, 29, -3, 30, -3, 35, -2, +31, -1, 27, 0, 33, -3, 43, -6, +44, -10, 44, -4, 50, 4, 51, 0, +46, -5, 39, -1, 35, 2, 32, -4, +27, -9, 22, -13, 29, -15, 39, -12, +47, -4, 49, -2, 48, 3, 51, 7, +52, 2, 47, -4, 37, -7, 33, -9, +30, -15, 27, -15, 28, -8, 34, 0, +42, 1, 43, 2, 43, -1, 51, -4, +54, -3, 47, -8, 38, -15, 35, -10, +34, 0, 31, 2, 30, 1, 31, 2, +33, 3, 37, -2, 41, -6, 46, -12, +45, -13, 44, -9, 45, -7, 44, -5, +41, 0, 39, 5, 40, 1, 34, -7, +31, -8, 41, -6, 44, -10, 34, -12, +34, -7, 44, -1, 48, 2, 41, 2, +36, -3, 42, -7, 45, -4, 37, -6, +33, -11, 41, -12, 47, -5, 38, -1, +33, 1, 42, 4, 44, 2, 33, -3, +31, -8, 42, -10, 44, -13, 39, -8, +38, -5, 42, -4, 45, -2, 43, 5, +38, 2, 40, -5, 43, -6, 37, -4, +31, -2, 32, -3, 35, -1, 33, 0, +29, 5, 34, 2, 46, -9, 51, -16, +46, -8, 44, -4, 45, -7, 41, -4, +36, 2, 34, 4, 34, 5, 29, 3, +30, -8, 42, -14, 50, -14, 46, -13, +45, -12, 48, -5, 48, -1, 42, -3, +38, -2, 36, 3, 31, 2, 27, -5, +31, -7, 40, -7, 44, -6, 45, -6, +49, -3, 49, -2, 43, 1, 35, 1, +34, -7, 34, -14, 30, -11, 30, -3, +35, 0, 36, 7, 35, 8, 40, 7, +51, 3, 48, -1, 39, -9, 38, -13, +37, -13, 34, -14, 29, -8, 27, 5, +33, 10, 36, 3, 39, 3, 43, 5, +47, 5, 41, -3, 34, -9, 37, -11, +39, -7, 37, 1, 30, 2, 28, 1, +32, 1, 36, 4, 37, -4, 38, -9, +41, -7, 42, 0, 36, 1, 36, 4, +40, 8, 39, 5, 35, 2, 32, -3, +35, -10, 41, -15, 39, -13, 38, -16, +42, -13, 46, -1, 43, 9, 40, 6, +42, 2, 41, 2, 37, -2, 38, -7, +40, -10, 39, -13, 36, -13, 41, -2, +44, 2, 39, -3, 40, -6, 48, -7, +49, -10, 39, -9, 33, 0, 34, 3, +30, 3, 28, 5, 33, 8, 38, 6, +44, 2, 43, -6, 43, -11, 45, -11, +44, -6, 38, -9, 34, -11, 35, -1, +31, 6, 28, 5, 35, 2, 38, 2, +37, 0, 41, 0, 45, -2, 46, -4, +45, -5, 43, 0, 39, -1, 34, -6, +34, -5, 34, -5, 33, -10, 36, -12, +39, -5, 43, -1, 45, 0, 44, 2, +42, 4, 42, 4, 40, 2, 38, -4, +40, -11, 39, -9, 35, -4, 38, -4, +39, -6, 39, -3, 41, -1, 40, -4, +37, -7, 38, -7, 43, -10, 44, -8, +43, -3, 44, -2, 45, 4, 43, 7, +39, 3, 40, -6, 40, -7, 35, -9, +34, -16, 38, -19, 43, -13, 43, -4, +36, 4, 38, 9, 44, 5, 43, 3, +39, 2, 39, -3, 46, -14, 45, -15, +38, -7, 41, -6, 42, -6, 35, -2, +34, -2, 39, -4, 39, -2, 34, -5, +35, -7, 41, -6, 48, -3, 51, -3, +47, 0, 45, 5, 44, 3, 39, -4, +32, -5, 28, -6, 28, -12, 28, -11, +31, -6, 34, 2, 35, 8, 44, 10, +50, 2, 50, -3, 54, -2, 50, -2, +40, -6, 29, -8, 24, -2, 25, -2, +28, 0, 27, 3, 27, 2, 38, -3, +50, -2, 50, -4, 50, -9, 55, -7, +51, -1, 41, -1, 35, -2, 35, 0, +36, -4, 34, -7, 29, -6, 29, -2, +38, -3, 41, -1, 39, 0, 43, -3, +51, -2, 55, 0, 46, -4, 39, -8, +40, -4, 39, -4, 33, -6, 32, -6, +39, 1, 39, 2, 33, 2, 37, 2, +45, -3, 46, -8, 45, -9, 41, -8, +43, -9, 46, -3, 40, 0, 36, -1, +43, -4, 43, 2, 36, 3, 35, -1, +38, -1, 34, -2, 35, -1, 37, 0, +38, 0, 42, -5, 43, -4, 43, -4, +45, -7, 46, -9, 41, -3, 38, 0, +40, -3, 39, -1, 38, 6, 37, 7, +31, 1, 34, -2, 42, -9, 44, -15, +44, -15, 49, -11, 50, -9, 45, 1, +42, 7, 43, 5, 39, 3, 34, 5, +29, 5, 23, -3, 29, -7, 40, -13, +41, -10, 43, -4, 52, -1, 54, -3, +49, -1, 47, 0, 45, -5, 41, -9, +34, -9, 31, -8, 37, -9, 39, 0, +35, 6, 34, 7, 42, 2, 51, -4, +50, -12, 45, -16, 48, -15, 48, -13, +39, -7, 31, 4, 31, 13, 36, 13, +34, 10, 35, 2, 45, -4, 47, -8, +40, -10, 37, -18, 44, -20, 47, -10, +41, -4, 38, -1, 41, 4, 42, 10, +41, 5, 45, -1, 46, -1, 40, -3, +41, -7, 42, -5, 36, -4, 33, -5, +35, -2, 35, -2, 34, -6, 40, -7, +44, 1, 41, 1, 44, 0, 45, 5, +41, 10, 44, 6, 44, 2, 33, 1, +31, -4, 34, -4, 29, -5, 28, -10, +37, -12, 41, -3, 42, 0, 47, 1, +51, 3, 52, 6, 49, 3, 47, -3, +46, -5, 45, -8, 38, -11, 31, -14, +35, -14, 39, -14, 40, -10, 46, -7, +48, -6, 51, -2, 57, 6, 53, 6, +49, 0, 51, -2, 46, -5, 36, -10, +34, -16, 42, -18, 39, -18, 33, -10, +37, -1, 43, 4, 44, 7, 45, 11, +46, 10, 47, 3, 49, -3, 46, -7, +45, -11, 44, -15, 38, -10, 34, -5, +34, -1, 33, 0, 36, -1, 37, 0, +37, 2, 45, -1, 52, -8, 51, -4, +49, 5, 48, 6, 44, -1, 42, -3, +47, -8, 42, -12, 30, -14, 32, -13, +37, -11, 33, -8, 39, 0, 47, 7, +45, 11, 49, 13, 54, 10, 50, -1, +48, -7, 44, -10, 36, -15, 33, -17, +33, -11, 30, -3, 28, 5, 32, 12, +39, 11, 41, 10, 44, 5, 49, 1, +50, -10, 56, -15, 53, -14, 45, -10, +46, -7, 40, -4, 31, 1, 32, 0, +33, 1, 30, -2, 35, -1, 37, 1, +39, 5, 46, 2, 52, 0, 53, 1, +53, 0, 53, -6, 47, -11, 38, -11, +37, -13, 32, -10, 25, -8, 32, -3, +37, 7, 32, 17, 38, 15, 49, 8, +53, 5, 51, -1, 51, -10, 54, -18, +45, -18, 37, -18, 41, -14, 37, -8, +33, -1, 38, 3, 41, 8, 43, 8, +47, 6, 47, 3, 49, -4, 51, -10, +49, -14, 43, -10, 41, -10, 42, -11, +41, -10, 39, -2, 41, 5, 40, 8, +40, 4, 44, 3, 42, 0, 43, -4, +51, -10, 47, -15, 46, -11, 50, -7, +42, -4, 41, -3, 47, 0, 43, 1, +39, 0, 43, -3, 46, -6, 41, -6, +44, -1, 43, 3, 31, 2, 39, 3, +50, 2, 39, 1, 36, -8, 49, -12, +49, -16, 46, -16, 52, -11, 47, -5, +43, 4, 46, 12, 41, 15, 39, 6, +44, 0, 43, -6, 38, -14, 38, -23, +44, -20, 42, -13, 42, -6, 44, 3, +43, 16, 47, 24, 46, 19, 38, 11, +43, -1, 44, -8, 33, -14, 34, -17, +36, -21, 36, -14, 41, -2, 43, 5, +43, 7, 52, 6, 55, 6, 47, 2, +46, -4, 53, -12, 50, -11, 40, -11, +42, -8, 45, -6, 38, -3, 36, -1, +40, -3, 40, -8, 42, -10, 43, -4, +43, 0, 45, 5, 42, 8, 46, 12, +50, 11, 44, 8, 45, -2, 45, -11, +36, -15, 34, -19, 38, -21, 35, -16, +33, -5, 41, 3, 49, 10, 49, 13, +54, 17, 59, 12, 51, 4, 48, -6, +48, -14, 37, -18, 31, -18, 33, -14, +25, -7, 26, 2, 36, 7, 42, 10, +49, 10, 53, 10, 55, 4, 59, -2, +53, -7, 48, -11, 44, -11, 37, -10, +36, -11, 37, -11, 35, -1, 36, 2, +37, 2, 41, 2, 42, 2, 46, 0, +56, -1, 50, 2, 41, 4, 49, 4, +50, 1, 40, -2, 38, -6, 39, -7, +37, -11, 35, -14, 34, -15, 44, -8, +48, -2, 44, 5, 50, 12, 52, 15, +51, 14, 50, 5, 46, -6, 45, -18, +44, -20, 40, -20, 31, -15, 29, -11, +46, -4, 50, 7, 41, 13, 52, 15, +55, 11, 43, 5, 48, -10, 53, -19, +43, -22, 43, -17, 42, -9, 32, 1, +34, 10, 40, 17, 36, 18, 36, 10, +42, 3, 44, -4, 40, -9, 46, -14, +47, -12, 40, -4, 44, 6, 41, 10, +36, 9, 45, 5, 40, 2, 33, -1, +43, -8, 39, -13, 36, -10, 48, -3, +48, 0, 41, 6, 49, 9, 53, 8, +40, 3, 38, -5, 48, -13, 39, -15, +31, -11, 42, -8, 40, 1, 33, 9, +46, 17, 47, 17, 37, 15, 44, 7, +43, -4, 38, -17, 48, -26, 49, -25, +41, -17, 41, -6, 46, 2, 49, 9, +46, 12, 48, 15, 48, 10, 42, 1, +41, -8, 39, -12, 37, -16, 41, -19, +40, -13, 42, -2, 45, 8, 43, 8, +47, 9, 50, 8, 44, 3, 48, -5, +51, -11, 41, -13, 40, -9, 42, -7, +40, -6, 40, -1, 39, 3, 44, 7, +42, 2, 40, -4, 51, -9, 54, -8, +48, -10, 52, -8, 52, 0, 44, 8, +38, 12, 37, 9, 36, 5, 29, 0, +33, -8, 41, -18, 37, -17, 40, -10, +48, -1, 45, 3, 52, 10, 60, 19, +48, 22, 40, 18, 42, 5, 36, -8, +31, -20, 32, -22, 31, -22, 29, -14, +33, -2, 46, 10, 51, 16, 51, 20, +58, 19, 56, 9, 54, -3, 52, -13, +40, -17, 37, -20, 33, -15, 27, -8, +34, 2, 34, 8, 35, 11, 48, 9, +49, 4, 48, -4, 60, -12, 62, -13, +52, -11, 46, -5, 47, 2, 40, 9, +30, 11, 30, 9, 29, 3, 26, -1, +35, -9, 40, -16, 41, -15, 55, -11, +58, -1, 54, 8, 55, 15, 55, 16, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/birds_8000_2ch_16b.c b/USDK/example_sources/i2s/src/birds_8000_2ch_16b.c new file mode 100644 index 0000000..111f294 --- /dev/null +++ b/USDK/example_sources/i2s/src/birds_8000_2ch_16b.c @@ -0,0 +1,5836 @@ +#include +int sample_size=23320; + +SECTION(".sdram.data") +short sample[]={ +0, 0, -1, 1, -1, 1, 0, 0, +1, 0, -1, 1, 0, 0, 2, -3, +2, -2, 0, 0, -1, 0, 0, 0, +-1, 1, 1, -1, 1, -1, 0, 0, +2, -2, 1, 0, 0, 0, 1, -2, +1, -1, -1, 1, -1, 1, 0, 0, +0, 0, 3, -3, 0, 1, -1, 1, +0, 1, 1, -1, 1, -1, -2, 1, +2, -2, 0, 1, -1, 0, 0, 0, +-2, 2, 0, 0, -1, 2, -1, 1, +0, 1, 1, -1, 1, -1, 1, -1, +0, 0, -1, 0, -1, 1, -3, 3, +0, 0, -3, 3, -1, 0, 1, 0, +0, 0, 0, 0, -1, 1, 1, -1, +1, 0, -1, 1, -2, 2, -3, 2, +1, -2, -1, 1, -2, 2, 0, 0, +0, 1, 1, -1, 2, -2, 1, 0, +-1, 1, 0, 0, 1, 0, -2, 2, +-2, 2, -4, 4, -3, 2, -4, 3, +1, -2, 3, -3, 0, 0, 0, 1, +-3, 3, 1, -1, 1, 0, 1, 0, +0, 0, 1, 0, 0, 0, -1, 1, +0, 0, 2, -2, 1, -1, 2, -3, +2, -2, -3, 3, 0, 0, 2, -1, +0, 1, -1, 2, 0, 0, -1, 1, +0, 0, 0, 0, 0, -1, -3, 2, +-1, 0, -1, 1, -1, 0, 4, -4, +-2, 2, 1, -1, 2, -1, 1, 0, +1, 0, 0, 1, 0, -1, 1, -1, +-2, 1, 2, -2, -1, 0, -1, 0, +1, -1, -1, 1, 1, -1, 1, -1, +2, -1, 2, -1, 4, -3, 1, 0, +0, 0, 2, -2, -1, 1, -1, 1, +-1, 1, -2, 2, 0, -1, 3, -3, +-1, 1, 0, 0, -1, 2, 2, -1, +3, -2, 2, -1, 0, 1, -2, 2, +0, 0, -1, 0, 0, -1, 1, -1, +-2, 1, -1, 0, 0, 0, 0, 0, +-1, 2, 0, 1, 1, 0, 1, -1, +1, 0, -1, 1, -1, 1, 0, 0, +1, -1, -1, 1, -2, 2, -2, 1, +1, -2, 2, -1, -1, 1, -1, 1, +1, 0, -2, 2, -2, 2, 1, -1, +0, 0, -2, 2, -3, 2, 0, -1, +3, -4, 0, 0, 0, 0, 0, 0, +1, -1, 2, -1, -1, 2, 1, -1, +1, -1, 1, -1, -1, 1, 2, -2, +0, 1, -5, 4, 1, -1, 0, 0, +0, 0, -1, 0, 1, -1, 0, 0, +1, -1, 2, -2, 0, 0, -1, 1, +0, 0, 0, 1, -4, 3, 3, -4, +0, 1, -2, 1, 0, 0, -3, 2, +3, -4, 2, -1, -2, 2, -1, 1, +1, -1, 2, -2, -2, 2, -1, 0, +0, 0, -3, 2, -1, 0, 0, 0, +0, -1, -1, 1, -3, 3, 1, -2, +2, -2, 0, 0, 1, -1, 1, 0, +-1, 1, 2, -2, 0, 1, 0, 0, +0, 0, -1, 1, 0, -1, 1, -1, +0, 0, 0, 0, 0, 0, -1, 1, +-1, 1, 1, -1, 0, 0, -1, 1, +0, 0, -1, 0, -1, 1, 1, -1, +2, -2, 1, -1, 0, -1, 2, -2, +1, -1, -1, 2, -1, 1, 2, -2, +0, 0, 0, 0, -2, 2, 2, -2, +2, -1, -4, 3, -1, 0, 1, -1, +0, 0, 0, 0, 0, -1, 0, 1, +-1, 1, 1, -1, 2, -2, -1, 1, +-1, 0, 0, 0, -3, 2, 1, -1, +1, -1, 1, -1, -1, 1, -1, 1, +0, 0, 1, -1, 1, -1, 0, 0, +-2, 2, 0, 0, 0, 0, -1, 0, +1, -1, 0, 0, -3, 3, -3, 2, +0, 0, -1, 1, 3, -3, 3, -2, +1, 0, -3, 4, -1, 1, 0, 1, +-3, 3, -1, 0, -2, 2, -1, 0, +2, -2, 0, 0, 0, 0, -1, 1, +-1, 2, -2, 2, 1, -1, 1, -1, +1, -1, 2, -2, 1, -1, 0, 0, +1, -1, -1, 1, -2, 1, 0, 0, +-2, 2, 1, -1, 2, -1, 0, 0, +0, 0, 1, -1, 2, -1, 1, -1, +1, 0, 0, 0, 0, 0, -1, 1, +-1, 1, 1, -1, -1, 1, -1, 1, +0, -1, 2, -2, -1, 1, 0, 0, +1, -1, -1, 1, -3, 3, 0, 0, +1, -1, -1, 1, -1, 1, -1, 1, +2, -3, 3, -3, 1, 0, -1, 1, +0, 0, -2, 2, 0, 0, 1, -1, +2, -2, 1, -1, -3, 3, 1, -1, +0, 0, 1, -1, 0, 0, -2, 1, +0, 0, -1, 1, 1, -1, 0, 1, +-1, 1, 0, 0, 0, 0, 0, 0, +-2, 1, 2, -2, 0, 0, 1, -1, +1, -1, -1, 1, 1, -1, 0, 0, +0, 1, -2, 2, 0, 0, 0, 0, +1, -2, 2, -1, 1, -1, 1, -1, +-1, 1, 0, 0, -3, 3, -1, 1, +-1, 1, 0, 0, 1, 0, 0, -1, +2, -2, 0, 0, 1, -1, 0, 0, +2, -2, 0, 0, 1, -1, 2, -3, +3, -3, 0, 1, 2, -2, 1, 0, +-1, 1, 0, 0, 1, -2, 1, -1, +-2, 2, 0, 0, -1, 1, 1, -1, +-1, 1, 0, 0, 0, 0, -1, 1, +0, 0, 0, 0, 2, -2, 0, 0, +-1, 1, -2, 2, -1, 1, 0, 0, +-1, 1, 2, -2, -1, 1, -1, 1, +0, 0, -1, 1, -2, 1, 1, -2, +1, -1, 1, -1, -1, 1, 1, -1, +1, -1, 1, -1, 0, 0, 0, 0, +1, -1, 0, 0, -2, 2, 1, -1, +-1, 1, 0, 0, 0, 0, 0, -1, +0, 1, -1, 0, 1, -1, 1, -1, +0, 0, 0, 0, 0, 0, 1, 0, +-1, 1, 1, -1, 0, 1, -1, 0, +1, -1, 0, 0, 0, 0, -2, 2, +0, 0, -1, 1, 0, 0, -2, 2, +-1, 0, -1, 1, 0, 0, 2, -2, +0, 0, 1, 0, -3, 3, 0, -1, +0, 0, -2, 2, 0, 0, -1, 1, +-1, 1, 0, 0, 1, -1, -2, 2, +1, -1, -2, 2, 0, 0, 1, -1, +1, -1, 2, -2, -1, 1, 1, -1, +0, 0, -1, 2, -2, 2, 1, -1, +-1, 1, -2, 1, 0, 0, -1, 1, +2, -2, 2, -2, 0, 0, 0, 0, +0, 0, -3, 2, 0, 0, 1, -1, +0, 0, -3, 3, 1, -1, -1, 2, +-2, 2, 1, -1, 1, 0, -1, 0, +0, 0, -1, 1, 0, 0, -1, 1, +2, -3, 1, -1, 1, -1, 2, -2, +1, -1, 0, 0, 0, 0, 2, -2, +1, -1, 0, 0, 1, -1, -1, 1, +-1, 1, -2, 2, 0, -1, 1, -1, +-1, 1, -2, 2, -2, 1, 0, 0, +-2, 2, 0, 0, 1, 0, -1, 1, +-1, 1, 0, 0, 0, 0, 0, 0, +0, 0, 2, -1, -2, 2, 2, -2, +0, 1, -1, 0, 2, -2, 0, 0, +1, -1, -1, 1, -1, 1, 1, -1, +1, -1, 2, -3, 2, -1, 0, 0, +3, -2, 0, 1, 0, 0, -1, 1, +1, -1, 2, -2, 1, -1, -1, 1, +1, -1, 0, 0, -1, 1, 0, 0, +0, -1, 0, 0, -2, 2, 1, -1, +-1, 1, 0, -1, -1, 1, -3, 3, +2, -2, 2, -2, 0, 0, 2, -2, +-1, 1, -1, 1, 2, -2, 0, 1, +0, 0, 0, 0, 0, 0, 1, -1, +0, 0, 0, 0, -1, 1, 0, 1, +-1, 1, 0, 0, 2, -2, 2, -2, +2, -2, 0, 0, 0, -1, 1, -1, +-1, 1, 1, -1, 0, 1, 1, -1, +-1, 1, 0, 0, 2, -2, 2, -2, +-1, 1, -1, 1, 0, 0, 1, -1, +-1, 1, 0, 0, 0, 0, 1, -1, +3, -3, 0, 1, 1, -1, -1, 1, +-1, 1, -1, 1, 0, 0, 2, -2, +-2, 2, 0, 0, 2, -2, 0, 0, +2, -2, 1, 0, -1, 1, 2, -2, +-2, 2, -2, 2, 0, 0, 0, 0, +0, 1, -1, 1, 1, -1, -2, 2, +0, 0, 0, 0, 2, -2, 1, -1, +1, -1, -2, 2, 0, 0, 1, -1, +-1, 1, -2, 2, -4, 3, 0, 0, +3, -3, 1, -1, 1, -1, -1, 1, +-3, 3, -1, 1, 2, -2, 1, 0, +-1, 1, 0, 0, 1, -1, 0, 1, +-1, 0, -1, 1, 0, -1, 2, -2, +-1, 1, -2, 2, -2, 1, 0, 0, +-3, 3, -2, 1, 0, 0, 0, 0, +1, -1, 0, 0, 1, -1, 2, -2, +3, -3, -1, 1, 1, -1, 3, -2, +2, -2, 1, -1, -1, 1, 0, 0, +-2, 2, 0, 0, 1, -1, -1, 0, +1, -1, -1, 1, -2, 2, -1, 2, +-3, 2, 0, 0, 0, 0, -1, 1, +2, -2, 1, -1, 0, 0, 0, -1, +0, 0, -3, 3, -1, 0, 2, -1, +-2, 1, -2, 2, -1, 1, 1, -1, +0, 0, 0, -1, 0, 0, 3, -3, +-2, 3, 0, 0, -2, 1, 0, 1, +-1, 0, -2, 2, 0, 0, -1, 0, +0, 1, -1, -1, 4, -3, -2, 2, +0, -1, 2, -1, -3, 2, 1, 1, +-3, 1, 0, 0, 1, 0, -3, 1, +0, 2, -4, 2, 3, -2, -1, 1, +-3, 2, 0, 2, -3, 1, -1, 3, +-4, 2, 1, -1, -2, 3, -1, -2, +3, 0, -4, 2, -2, 2, 0, 0, +-3, 1, 3, -1, -3, 0, 3, -2, +0, 0, -2, 1, 1, 2, -3, 0, +4, -1, -3, 1, -2, 2, 1, 1, +-2, -1, 4, 0, -3, 1, 2, 0, +0, 0, -2, -1, 4, -1, -4, 0, +3, -1, 0, -1, 0, -1, 2, 1, +-5, 1, 4, 0, -2, -1, 0, 0, +4, -2, -2, -1, 5, -1, -2, -1, +1, 1, 0, 0, -2, -1, 4, 1, +-2, -2, 3, 1, -3, 0, -1, 1, +2, 1, -4, -1, 4, 0, -3, -1, +2, -1, 0, 2, -5, 1, 7, -2, +-3, -2, 5, -1, -1, 0, 0, -3, +6, -1, -3, -3, 3, 2, -4, 2, +-2, 1, 3, 0, -6, 1, 5, 0, +-7, 3, 2, -1, 1, 0, -5, 0, +7, -1, -9, 3, 5, -2, 1, -1, +-4, 1, 5, 0, -5, -1, 5, 0, +-3, 0, 0, 0, 3, -1, -4, -1, +6, 0, -5, -1, 3, 0, -1, 1, +-4, 1, 4, 1, -5, -1, 3, 1, +-4, 2, -3, 1, 5, 0, -5, -1, +5, 0, -4, 0, 1, 0, 3, -1, +-3, -2, 6, 1, -6, 0, 1, 2, +0, -1, -1, -1, 4, 2, -5, -1, +5, 0, -4, 2, 1, -2, 6, -2, +-6, 0, 7, -1, -5, 1, 2, -1, +0, 2, -4, 0, 7, -1, -5, -1, +2, 1, -3, 1, 0, -3, 7, -2, +-6, 1, 5, 0, -3, 1, -1, 1, +3, -1, -7, 1, 4, 1, -7, 3, +0, 3, 0, 1, -3, 0, 4, 0, +-5, -1, 5, -2, 1, -2, -2, 2, +7, -2, -4, 0, 3, 1, -2, -1, +1, -1, 2, -1, -4, 1, 4, 1, +1, -4, 4, -1, -2, 1, 1, -4, +3, 0, -3, -1, 2, 2, -2, 1, +2, -1, 3, 0, -4, 0, 2, 1, +-3, -1, 0, 1, 2, -1, -1, -1, +2, 2, -3, 1, 1, 0, 1, -2, +-3, 0, 2, -1, -2, -1, 4, 0, +0, 0, 2, -1, 1, 1, -5, 1, +1, -1, -4, 1, 0, 1, 2, 0, +-2, 3, 4, 0, -2, 0, -2, 1, +-5, 2, -3, 0, 3, -1, 2, -1, +7, -2, 2, -1, 1, -2, -3, 1, +-6, 0, -2, 1, -1, 1, 4, 1, +4, 2, 0, 1, -2, 2, -7, 0, +-3, -3, -3, 2, 0, 2, 8, 0, +6, -1, 1, 1, -4, -1, -9, 1, +-6, 0, -2, 0, 5, 2, 9, -1, +7, -1, -1, 1, -10, 0, -10, 1, +-9, 2, 1, 1, 10, 1, 9, 1, +8, -1, -5, 0, -14, 2, -8, -3, +-4, -1, 8, 1, 10, 1, 13, -1, +1, 1, -9, -2, -11, -2, -13, -1, +4, -2, 10, 0, 16, -1, 13, -2, +-4, -1, -11, 0, -19, 0, -5, -2, +8, -2, 18, -3, 19, 1, 3, 0, +-6, 0, -21, 2, -18, 1, -2, 0, +8, 1, 23, 0, 13, 0, 1, 0, +-13, -1, -23, 0, -10, 0, -2, 1, +21, -2, 21, 0, 9, 1, -3, -1, +-24, 1, -19, 2, -11, 1, 11, 0, +23, 0, 17, -1, 9, -1, -15, -2, +-19, -1, -17, -1, -2, 0, 16, 3, +19, 0, 18, 1, -7, 2, -18, -1, +-21, 0, -15, 0, 9, 2, 18, -1, +24, 0, 8, 1, -12, 0, -19, 0, +-23, -2, -1, 0, 10, 1, 24, -1, +21, -1, -2, 0, -14, 2, -25, -1, +-14, 1, 4, -2, 18, -1, 26, 0, +9, 0, -3, 0, -21, 0, -21, 0, +-9, 2, 8, -3, 26, -1, 16, 0, +7, 0, -11, -1, -22, -1, -14, 0, +-3, -3, 17, 0, 21, -2, 13, 1, +1, 0, -18, -1, -15, -1, -13, -1, +5, 0, 17, 0, 17, -2, 12, -1, +-10, 0, -15, 1, -19, 2, -8, 2, +8, 4, 12, 1, 16, 1, -3, 3, +-8, -2, -13, -2, -13, 0, 4, 0, +10, -2, 19, -1, 8, 0, -2, -1, +-9, -1, -14, -3, -5, 2, -2, 4, +12, 1, 12, 0, 1, 1, -1, -2, +-14, 0, -7, -1, -1, -2, 5, 1, +14, -1, 6, -1, 3, 0, -10, 0, +-6, -4, -5, -1, 0, -1, 11, -1, +6, 0, 9, -3, -1, -2, -8, 1, +-9, 3, -6, 1, 6, -1, 6, -1, +5, 2, 2, 0, -3, -1, -4, 0, +-7, 0, 0, 1, 6, -4, 6, -1, +5, 0, 2, -4, -1, 0, -8, 2, +-4, 2, -1, 1, 3, -1, 4, 1, +2, -1, 1, 1, -7, 3, -1, -3, +-1, 0, 0, -1, 5, -1, 3, -1, +2, 0, 0, -1, -5, 2, -2, 0, +-3, 1, 1, 0, -1, 2, 2, 0, +6, -4, 1, -2, 0, 0, -3, 1, +-2, 1, 1, -1, 1, 0, 2, 0, +2, -2, -1, 2, -2, 0, 0, -1, +-1, 0, 2, -2, -1, 3, 1, 1, +0, 2, -1, 1, -2, 0, -4, 2, +-1, -1, 2, -1, 1, 0, 4, -2, +2, 0, 1, -1, -1, 0, -2, -1, +1, -2, 1, 0, 5, -3, 1, 2, +0, 0, 1, -2, -2, 0, 1, -2, +-1, 0, 2, 0, 2, 0, 2, -1, +1, -1, -3, 1, -2, 0, -1, -1, +0, 0, 3, -1, 3, 0, 1, 0, +-1, 0, -4, 2, -4, 1, -1, 0, +1, 1, 2, 0, 3, 1, -2, 2, +0, -2, -3, 0, -3, 0, 0, 1, +2, 0, 5, -1, 3, -1, 0, 0, +-4, 1, -5, 1, 0, -1, 3, -2, +5, -1, 4, -1, 2, -1, -1, 0, +-4, -1, -2, 0, 0, -1, 2, 1, +4, 0, 2, 0, 0, 1, -5, 1, +-4, 0, -3, 0, 1, 0, 6, -1, +3, 0, 1, 1, -2, 0, -4, 0, +-3, -1, 1, -2, 2, 1, 5, -1, +4, 0, 1, 0, -2, -1, -2, -1, +-3, 0, 0, 0, 3, 0, 6, -1, +2, 1, -2, 0, -2, -1, -4, 0, +-2, 1, -1, 3, 5, -2, 5, 0, +1, -1, -3, 1, -4, -1, -1, -2, +1, 0, 0, 3, 7, -2, 1, 1, +-3, 2, -2, -1, -4, 0, -2, 1, +0, 1, 4, 0, 3, 1, -1, 3, +-3, 1, -4, 1, -5, 2, -2, 1, +3, -1, 3, 1, 1, 2, -1, 1, +-4, 0, -2, -1, -2, 0, 3, -2, +1, 2, 3, -1, 3, -1, -3, 1, +-4, 1, -2, -2, -2, 2, 2, 0, +4, 0, 0, 3, -1, 0, -2, 0, +-4, 0, 0, -1, 2, -1, 1, 1, +2, 1, 0, 0, -1, -1, -2, 0, +-2, -1, 1, 0, 1, -1, 6, -3, +1, 1, 0, 0, 0, -1, -2, 0, +-2, 1, 1, 0, 2, 1, 3, -1, +2, -1, 1, -2, -2, -1, -1, -1, +0, -1, 4, -2, 3, 0, -1, 1, +2, -2, -3, 1, -3, 1, -3, 2, +2, -1, 2, 1, 1, 0, 2, -1, +-2, 0, -1, -1, 0, -2, 0, -1, +2, 0, 1, 0, 1, 0, 0, 0, +-3, 1, -4, 3, -2, 0, 1, 0, +1, 0, 4, -2, 1, 0, 1, -2, +-1, 0, -2, 0, -1, 2, 1, 0, +1, 1, 1, 0, 2, -3, 1, -1, +-3, 1, -2, 1, 0, 1, 2, -1, +5, -2, 0, 0, 1, -2, -3, 2, +-3, 1, 2, -1, -1, 2, 1, 1, +0, 1, -1, 0, 0, -1, -1, -2, +3, -2, 0, 0, 3, -1, 0, 1, +1, -1, 1, -1, -1, -1, 1, -1, +1, -1, 0, 1, 1, 0, 1, 0, +0, 0, -2, 0, 1, -2, -1, 1, +1, -1, 2, 0, 1, -1, 2, -1, +-2, 1, 1, -2, -1, 1, -2, 2, +0, 1, 4, -4, 0, 1, -1, 1, +-1, 0, -1, 0, -1, 1, 2, -1, +1, 0, -1, 2, 0, 0, -2, 1, +1, -2, 0, 0, 0, 0, 0, 1, +0, 1, 2, -2, -3, 2, -2, 0, +-1, 0, 1, -1, 0, 2, 0, 1, +2, 0, -3, 2, 0, -1, 0, -2, +-1, 0, 3, -2, 3, -1, 2, -1, +1, -1, -3, 2, -1, 0, -2, 1, +0, 0, 1, 0, 2, 0, 3, -2, +1, -2, -4, 3, -3, 1, -2, 2, +2, -1, 3, -1, 1, 0, 1, -1, +-2, 1, -2, 0, -2, 1, 0, 0, +1, 0, 0, 1, 2, -1, -1, 1, +-2, 0, -1, -1, -1, 0, 3, -2, +1, 1, 0, 1, -2, 2, -1, 0, +-1, 0, -1, 0, -1, 1, 1, 0, +6, -4, 2, 0, -1, 0, -1, 0, +-1, 0, -3, 2, 0, 1, 2, -1, +1, 1, -1, 1, -2, 1, -4, 2, +0, -2, 3, -3, 3, -2, 3, -1, +1, 0, -1, 1, -2, 0, 0, -1, +1, -1, 2, -2, 3, -1, 0, 2, +-2, 2, 0, -1, -2, 0, -1, 0, +0, -1, 2, -1, 1, 0, 3, -2, +1, 0, -2, 1, -4, 2, -1, -1, +1, 0, 3, -1, 2, 0, 3, -2, +-4, 3, -4, 2, -2, 1, 0, 0, +0, 1, 3, -2, 1, 1, -1, 1, +0, -1, -2, 0, -1, 0, -1, 1, +2, -1, 0, 1, 1, 0, -2, 1, +0, -1, -1, -1, 1, -2, 0, 1, +1, 0, 2, -1, 1, -1, -2, 1, +-1, 0, -1, 0, -1, 1, 0, 1, +3, -2, -1, 1, 0, 0, -2, 1, +-3, 2, 0, 0, -1, 1, 3, -2, +2, -1, 1, 0, 0, -1, -1, 0, +-2, 2, -1, 1, 1, 0, 1, -1, +3, -2, 1, 0, 1, -2, -1, 0, +-2, 2, 0, 0, 2, -2, 1, 0, +1, 0, 0, 0, -2, 1, 2, -2, +0, 0, -1, 1, 2, -1, 2, -2, +1, -1, 0, 0, 1, -1, 2, -3, +2, -1, 1, 0, 0, 0, -2, 2, +-1, 0, -2, 2, -1, 0, 2, -1, +0, 1, 3, -3, 2, -2, 0, 0, +2, -2, 2, -3, 0, 0, -1, 1, +0, 1, 1, -1, -1, 1, -1, 1, +0, -1, -2, 2, 0, 0, -1, 1, +1, -1, 1, -1, 0, 0, 0, 0, +0, 0, -2, 3, 0, -1, 1, 0, +-2, 1, 1, -1, -2, 2, 1, -1, +0, 1, 1, -1, 2, -1, 1, -1, +1, 0, 0, 1, -1, 1, 1, 0, +-1, 2, 0, 2, -1, 2, 2, -2, +3, -2, 1, 0, 2, 0, 1, 0, +2, -1, 1, 1, 1, 0, 3, -1, +0, 2, 0, 2, 3, 0, 4, -1, +4, -1, 3, 0, 3, 1, 2, 1, +3, 0, 5, -1, 4, 0, 7, -3, +7, -3, 7, -2, 5, 0, 5, 0, +4, 1, 4, 1, 5, 1, 6, -1, +5, 1, 5, 1, 7, -1, 4, 2, +9, -3, 9, -1, 7, 0, 7, 0, +5, 2, 8, 0, 7, 1, 10, -3, +10, -1, 9, 1, 10, -1, 8, 1, +8, 1, 10, 0, 10, 0, 9, 1, +11, 1, 11, 1, 9, 1, 14, -4, +11, 2, 10, 2, 14, -2, 11, 1, +12, 2, 12, 1, 14, -2, 13, 0, +14, 1, 14, 1, 15, -1, 13, 2, +13, 3, 16, -1, 13, 1, 15, 1, +17, 1, 14, 2, 16, -1, 20, -2, +16, 3, 17, -2, 19, -3, 17, 3, +15, 5, 18, -1, 21, -3, 20, 1, +19, 0, 21, -4, 20, -1, 20, 3, +20, 1, 21, -3, 21, 0, 21, 2, +19, 2, 19, -1, 21, 2, 24, 1, +25, -3, 21, 0, 23, 1, 23, 2, +25, -5, 26, -4, 23, 4, 27, -1, +25, -3, 24, -1, 25, 3, 24, 2, +23, -2, 25, -1, 26, 4, 26, 1, +28, -5, 27, 0, 28, 3, 24, 1, +27, -4, 27, 3, 28, 3, 28, -2, +27, -3, 30, 2, 26, 5, 31, -7, +28, -2, 27, 5, 31, 0, 28, -3, +28, 0, 30, 4, 30, 0, 27, -3, +29, 0, 33, 3, 29, 1, 31, -6, +29, 4, 27, 7, 29, -1, 28, -2, +31, 3, 29, 6, 31, -4, 34, -6, +31, 5, 31, 3, 31, -5, 31, -2, +32, 5, 32, 1, 34, -8, 32, 0, +33, 5, 33, -1, 31, -5, 31, 2, +31, 7, 33, -3, 35, -7, 30, 6, +32, 5, 32, -4, 32, -4, 33, 4, +34, 2, 34, -6, 33, -3, 32, 7, +31, 3, 32, -6, 33, -2, 32, 7, +30, 3, 32, -6, 35, -2, 32, 7, +31, -2, 31, -5, 31, 3, 33, 5, +31, -2, 35, -8, 31, 6, 30, 5, +32, -6, 29, -1, 32, 5, 31, 4, +31, -5, 29, -1, 33, 4, 31, 1, +29, -6, 31, 0, 30, 6, 31, -1, +30, -5, 29, 2, 31, 5, 28, 0, +29, -7, 31, 4, 29, 5, 32, -7, +31, -5, 29, 3, 28, 4, 28, -4, +25, -1, 30, 6, 29, 1, 27, -7, +31, -1, 26, 6, 27, -1, 29, -6, +25, 0, 28, 7, 28, -2, 25, -6, +28, 4, 25, 5, 24, -3, 29, -5, +23, 3, 27, 3, 26, -2, 21, -5, +27, 5, 24, 2, 22, -5, 27, -3, +22, 6, 21, 0, 29, -4, 17, -3, +23, 9, 17, 3, 20, -4, 23, 0, +23, 7, 17, -4, 24, 4, 16, -3, +23, 5, 24, -5, 19, -4, 24, -2, +20, 7, 16, -10, 25, 3, 14, 1, +17, 1, 22, -1, 16, -3, 16, 4, +21, 2, 10, -5, 24, 1, 12, 5, +13, -5, 19, 4, 11, 2, 13, 1, +22, 1, 5, -2, 18, 6, 12, 5, +9, -9, 22, 2, 11, 4, 12, -6, +18, 3, 11, -5, 12, 4, 17, 4, +0, -11, 23, 6, 4, 8, 13, -10, +15, -1, 8, 7, 7, -4, 21, 7, +-2, -16, 20, 10, 7, 5, 4, -8, +16, -3, 7, 10, 4, -9, 21, 4, +-5, -9, 15, 5, 10, 11, -1, -16, +15, 2, 7, 9, 1, -8, 19, 1, +-2, -3, 9, -3, 14, 16, -7, -19, +15, 3, 5, 10, 1, -10, 15, -3, +0, 5, -2, -8, 20, 19, -12, -20, +18, 0, -1, 15, -2, -7, 8, -4, +8, 7, -8, -12, 20, 20, -11, -17, +9, -2, 6, 16, -6, -10, 9, -3, +4, 9, -7, -12, 15, 16, -5, -8, +1, -12, 10, 22, -10, -10, 7, -2, +6, 8, -12, -10, 14, 13, -3, -3, +-2, -16, 13, 17, -7, -6, 2, -8, +7, 13, -10, -14, 10, 12, 4, 0, +-14, -17, 19, 19, -13, -3, 9, -10, +2, 6, -3, -2, -2, 1, 13, 14, +-19, -32, 21, 28, -12, -9, 6, -5, +5, -1, -4, 5, 0, -4, 8, 15, +-12, -25, 8, 19, 2, 8, -10, -20, +18, 13, -15, -7, 7, 11, 1, -2, +-2, -8, 1, -2, 7, 26, -14, -30, +14, 19, -7, -8, 0, 6, 10, 2, +-9, -14, 5, 9, -1, 14, -2, -15, +2, 1, 4, 12, -13, -7, 12, 18, +-15, -16, 6, 8, 2, 13, -9, -13, +4, 5, -5, 9, -5, 1, 3, 2, +-6, 4, -6, -10, 6, 33, -17, -22, +5, 14, -5, 1, -9, 8, 5, -2, +-11, 7, -4, -4, -4, 22, -3, -7, +-13, -2, 11, 19, -29, -4, 14, 16, +-23, -7, 4, 9, -14, 9, 1, 6, +-19, -9, 8, 20, -24, 1, 1, 3, +-10, 11, -17, -8, -1, 33, -20, -16, +-5, 19, -18, -6, -6, 34, -30, -20, +7, 39, -40, -27, 7, 48, -34, -20, +-6, 25, -24, -4, -11, 32, -27, -17, +-3, 31, -35, -14, -9, 35, -28, -2, +-22, 14, -14, -1, -27, 33, -26, -17, +-15, 38, -39, -14, -17, 40, -31, -8, +-29, 28, -29, -8, -24, 46, -44, -23, +-8, 44, -56, -15, -14, 40, -45, -6, +-31, 32, -39, -10, -27, 45, -47, -20, +-22, 38, -49, -4, -42, 34, -36, 10, +-51, 16, -33, 11, -55, 31, -38, 8, +-54, 15, -32, 27, -70, 3, -23, 38, +-75, 0, -33, 26, -60, 20, -48, 16, +-54, 11, -48, 30, -68, 8, -43, 31, +-66, 11, -57, 18, -54, 29, -71, 19, +-57, 11, -59, 38, -75, 3, -51, 40, +-73, 9, -68, 23, -57, 24, -77, 25, +-70, 13, -53, 30, -96, 15, -43, 24, +-95, 29, -60, 5, -77, 42, -76, 13, +-73, 19, -69, 28, -87, 21, -70, 23, +-79, 30, -88, 12, -62, 31, -95, 25, +-73, 15, -82, 31, -82, 20, -84, 20, +-79, 38, -96, 8, -76, 41, -90, 19, +-86, 17, -78, 32, -100, 22, -72, 23, +-99, 26, -74, 24, -108, 21, -64, 40, +-118, 4, -64, 43, -108, 20, -84, 22, +-83, 29, -96, 15, -86, 30, -89, 28, +-102, 23, -85, 25, -87, 33, -107, 12, +-68, 39, -119, 19, -68, 24, -106, 34, +-83, 12, -97, 31, -83, 31, -110, 17, +-74, 34, -103, 20, -92, 28, -75, 24, +-116, 27, -63, 16, -113, 43, -76, 3, +-99, 45, -82, 13, -97, 27, -75, 27, +-110, 28, -69, 18, -103, 39, -83, 12, +-87, 36, -90, 18, -82, 29, -96, 21, +-74, 36, -105, 8, -62, 50, -112, 1, +-58, 45, -106, 10, -63, 32, -100, 17, +-62, 32, -100, 10, -56, 32, -98, 14, +-64, 28, -88, 24, -70, 19, -85, 24, +-67, 30, -90, 11, -62, 37, -84, 12, +-70, 29, -68, 18, -80, 23, -66, 21, +-72, 24, -73, 15, -61, 24, -76, 25, +-66, 11, -62, 33, -76, 6, -54, 32, +-76, 12, -57, 25, -67, 14, -62, 31, +-70, 7, -51, 32, -73, 6, -45, 27, +-74, 13, -49, 23, -63, 11, -54, 30, +-63, 3, -51, 34, -62, 2, -48, 28, +-60, 8, -47, 19, -54, 13, -54, 19, +-48, 10, -57, 21, -45, 13, -53, 11, +-46, 19, -50, 10, -46, 17, -47, 10, +-45, 11, -50, 19, -46, 13, -48, 15, +-42, 9, -44, 18, -48, 7, -35, 16, +-54, 9, -34, 18, -51, 10, -33, 8, +-50, 19, -35, 6, -45, 17, -36, 5, +-39, 11, -34, 5, -37, 13, -40, 2, +-35, 19, -46, 6, -25, 10, -50, 11, +-24, 6, -45, 12, -24, 2, -47, 14, +-23, 1, -42, 15, -29, -3, -31, 16, +-39, -7, -17, 21, -54, -9, -6, 21, +-57, -11, -1, 21, -58, -14, -2, 26, +-57, -18, 3, 25, -62, -15, 0, 25, +-53, -16, -8, 25, -42, -19, -17, 27, +-36, -19, -23, 28, -24, -26, -27, 28, +-18, -27, -35, 36, -17, -32, -29, 38, +-21, -40, -19, 43, -33, -40, -9, 44, +-42, -40, 4, 41, -52, -39, 11, 44, +-59, -39, 19, 40, -59, -36, 19, 34, +-52, -36, 14, 33, -47, -34, 6, 37, +-37, -38, -5, 38, -22, -35, -22, 34, +0, -35, -35, 30, 9, -28, -39, 23, +16, -26, -43, 18, 19, -14, -45, 6, +18, 0, -42, -4, 16, 7, -31, -16, +6, 19, -26, -24, 11, 23, -29, -28, +11, 27, -26, -27, 8, 22, -15, -27, +2, 20, -14, -21, 6, 15, -18, -15, +8, 10, -12, -13, 8, 4, -10, -5, +3, 4, -6, -8, 4, 7, -3, -12, +-5, 15, 10, -20, -12, 20, 21, -32, +-11, 31, 14, -42, -1, 43, 7, -54, +6, 53, 0, -59, 14, 60, -8, -66, +34, 60, -29, -65, 52, 61, -40, -64, +63, 53, -45, -53, 67, 42, -46, -43, +74, 28, -50, -29, 70, 17, -34, -17, +55, -4, -9, 0, 26, -17, 15, 19, +5, -31, 37, 28, -13, -43, 60, 41, +-35, -56, 80, 51, -45, -67, 84, 62, +-45, -71, 82, 60, -38, -70, 80, 57, +-30, -67, 66, 51, -8, -58, 42, 38, +20, -42, 16, 19, 39, -19, -1, 2, +56, -7, -12, -13, 70, 4, -21, -24, +75, 13, -18, -31, 68, 12, -3, -24, +55, -4, 12, -9, 40, -20, 27, 10, +22, -38, 48, 30, -2, -58, 76, 49, +-20, -82, 90, 66, -30, -91, 95, 70, +-34, -87, 98, 61, -31, -80, 96, 48, +-18, -67, 79, 27, -1, -37, 51, 4, +25, -13, 40, -31, 40, 14, 24, -53, +58, 32, 7, -71, 74, 46, -2, -80, +75, 49, 3, -75, 62, 38, 19, -58, +55, 10, 34, -39, 38, -8, 46, -14, +23, -32, 65, 4, 6, -48, 73, 17, +3, -50, 75, 5, 13, -37, 71, -18, +16, -10, 61, -43, 27, 17, 46, -72, +48, 48, 23, -104, 69, 74, 7, -124, +78, 88, 4, -131, 82, 86, 3, -128, +87, 78, 4, -122, 77, 72, 17, -111, +60, 62, 31, -102, 55, 51, 33, -100, +64, 49, 24, -102, 65, 57, 21, -107, +70, 62, 14, -113, 86, 64, -5, -118, +110, 66, -24, -117, 120, 60, -26, -109, +120, 47, -28, -88, 120, 23, -16, -70, +102, 3, 13, -47, 61, -23, 56, -17, +21, -54, 92, 11, -11, -76, 120, 27, +-34, -89, 143, 34, -53, -93, 151, 35, +-47, -89, 131, 26, -20, -72, 100, 3, +15, -46, 67, -25, 55, -22, 21, -48, +112, -2, -37, -71, 167, 16, -83, -84, +192, 33, -96, -95, 199, 35, -101, -89, +197, 29, -88, -86, 175, 22, -52, -80, +132, 15, -4, -75, 90, 7, 28, -63, +59, 1, 58, -61, 30, -2, 91, -61, +-1, 2, 112, -66, -5, 2, 106, -69, +6, 10, 88, -76, 27, 16, 67, -84, +51, 27, 30, -89, 90, 30, -10, -89, +121, 31, -26, -94, 128, 35, -30, -95, +133, 34, -39, -92, 142, 29, -41, -90, +130, 33, -21, -95, 106, 36, 4, -99, +82, 42, 23, -101, 60, 43, 50, -102, +25, 45, 87, -104, -7, 44, 106, -99, +-12, 32, 100, -80, -7, 13, 102, -68, +-10, 2, 99, -52, -5, -12, 85, -39, +10, -19, 66, -33, 28, -23, 52, -37, +39, -11, 35, -51, 61, 4, 8, -65, +80, 19, -2, -75, 78, 25, 13, -83, +56, 33, 24, -81, 49, 26, 27, -69, +41, 15, 46, -63, 17, 8, 61, -49, +7, -7, 61, -29, 12, -29, 59, -11, +4, -44, 71, 7, -19, -56, 93, 13, +-30, -63, 91, 25, -21, -79, 75, 49, +-15, -99, 73, 67, -14, -113, 71, 72, +-7, -111, 56, 69, 0, -100, 54, 56, +-1, -89, 58, 41, -3, -67, 39, 26, +28, -56, 12, 10, 43, -34, 2, -7, +45, -20, 6, -24, 43, -2, -3, -37, +47, 12, -7, -41, 43, 8, 8, -33, +25, -3, 22, -24, 17, -7, 16, -15, +15, -11, 30, -10, -4, -28, 58, 7, +-34, -38, 72, 14, -31, -40, 50, 21, +-18, -41, 43, 29, -17, -55, 50, 29, +-16, -39, 28, -2, 24, 8, -23, -53, +67, 55, -53, -85, 77, 73, -49, -96, +63, 92, -40, -119, 63, 116, -45, -137, +68, 116, -50, -111, 59, 80, -28, -74, +30, 43, 8, -42, -13, 17, 48, -15, +-52, -5, 73, 3, -59, -11, 66, -10, +-43, 14, 41, -26, -22, 17, 32, -21, +-24, 18, 25, -36, -2, 61, -16, -100, +47, 129, -63, -145, 81, 128, -71, -108, +74, 75, -68, -66, 85, 70, -107, -93, +129, 121, -145, -128, 141, 117, -117, -84, +80, 48, -41, -19, 10, 13, 4, -19, +-7, 33, 3, -39, -7, 35, 20, -17, +-50, -3, 78, 25, -110, -37, 121, 50, +-124, -56, 100, 70, -85, -69, 54, 73, +-47, -55, 29, 45, -31, -28, 21, 26, +-22, -25, 3, 38, 6, -37, -38, 40, +43, -16, -68, 1, 65, 23, -73, -26, +58, 27, -64, -8, 46, 9, -61, 0, +58, 12, -77, -17, 70, 30, -78, -26, +53, 25, -45, -11, 11, 10, -12, 6, +-12, -3, 1, 17, -17, -21, 6, 44, +-32, -52, 32, 64, -59, -52, 42, 48, +-42, -32, 4, 29, 3, -24, -29, 36, +7, -43, -1, 58, -49, -47, 56, 35, +-82, 2, 43, -25, -25, 54, -33, -55, +42, 48, -68, -12, 36, -18, -19, 42, +-35, -38, 37, 26, -69, 14, 37, -36, +-45, 55, 5, -38, -12, 11, -18, 31, +0, -54, -28, 66, 6, -44, -32, 25, +5, 3, -25, -6, -19, 11, 14, 8, +-66, -9, 57, 17, -95, -6, 57, 11, +-59, -9, -6, 24, 17, -30, -78, 42, +66, -34, -91, 29, 32, -5, -27, -4, +-42, 22, 31, -16, -63, 15, 13, 4, +-28, -13, -26, 48, -13, -58, -9, 76, +-47, -64, 25, 43, -57, 15, -1, -61, +-9, 105, -51, -103, 16, 87, -37, -27, +-37, -20, 36, 56, -99, -46, 62, 29, +-80, 8, 6, -23, -14, 26, -55, 19, +26, -52, -67, 80, 19, -69, -61, 48, +21, 11, -74, -49, 40, 72, -90, -46, +46, 3, -77, 70, 10, -128, -25, 166, +-54, -150, 30, 129, -100, -66, 61, 15, +-109, 28, 56, -16, -101, -5, 48, 63, +-101, -113, 51, 168, -105, -159, 40, 137, +-75, -75, -2, 18, -35, 61, -26, -94, +-35, 115, -5, -109, -56, 118, -10, -100, +-16, 111, -80, -124, 70, 146, -161, -122, +115, 105, -158, -62, 74, 22, -102, 37, +19, -48, -62, 61, -9, -54, -39, 62, +-42, -36, -1, 47, -80, -41, 27, 44, +-81, -16, -1, 21, -35, -8, -44, 3, +-12, 13, -46, 10, -33, -5, -10, 9, +-67, -7, 11, 21, -66, 2, -20, -14, +-17, 42, -84, -50, 49, 92, -134, -93, +73, 90, -135, -63, 56, 62, -109, -28, +39, 17, -100, -13, 25, 27, -74, 4, +-30, -14, 8, 50, -130, -76, 92, 142, +-176, -150, 96, 163, -132, -152, 24, 143, +-60, -84, -25, 43, -37, 2, -32, -32, +-40, 80, -36, -71, -20, 65, -67, -41, +6, 36, -75, 8, -10, -15, -31, 19, +-74, -7, 30, 21, -101, -3, 11, 3, +-42, 1, -86, 18, 65, 13, -174, -18, +117, 40, -175, -58, 62, 111, -86, -102, +-43, 96, 24, -61, -138, 34, 96, 28, +-171, -48, 85, 51, -116, -23, -15, 23, +9, 16, -139, -22, 104, 23, -173, -3, +72, 30, -84, -37, -50, 60, 38, -69, +-139, 95, 74, -59, -121, 25, 14, 25, +-37, -50, -71, 101, 32, -107, -101, 94, +14, -46, -48, 15, -50, 65, 8, -127, +-72, 181, -15, -181, -11, 182, -94, -114, +49, 39, -110, 44, 22, -66, -59, 86, +-23, -49, -28, -6, -28, 70, -34, -61, +-33, 38, 10, 15, -98, -58, 64, 91, +-110, -39, -10, -21, 32, 87, -158, -97, +129, 80, -143, -8, -2, -56, 55, 86, +-172, -29, 136, -44, -132, 128, 18, -159, +-7, 133, -56, -25, -25, -57, 12, 95, +-84, -51, 5, -13, 13, 88, -127, -95, +107, 41, -110, 62, 2, -113, 44, 116, +-119, -54, 76, -17, -67, 73, -27, -38, +6, -48, -39, 142, -49, -173, 17, 171, +-38, -102, -43, 37, 54, -2, -79, 38, +26, -73, 16, 83, -79, -31, 50, -56, +-24, 158, -102, -174, 113, 102, -154, 39, +50, -143, -5, 175, -68, -104, 46, -25, +-6, 147, -55, -163, 68, 104, -28, 9, +-68, -104, 120, 149, -155, -109, 55, 23, +-2, 53, -116, -66, 101, 33, -81, 45, +-10, -112, 89, 135, -103, -94, 93, 47, +-30, -31, 8, 63, -30, -115, 49, 155, +-102, -135, 46, 61, -33, 24, -71, -59, +111, 42, -129, 11, 99, -62, -9, 87, +-15, -49, 62, -14, -26, 77, 22, -121, +-34, 145, 27, -130, -78, 88, 43, -41, +-58, 4, -10, 25, 50, -36, -48, 37, +42, -30, 50, 31, -29, -1, 48, -47, +37, 83, -85, -95, 99, 79, -110, -42, +6, 5, 42, 6, -120, 3, 88, 5, +1, -31, -52, 71, 147, -101, -77, 124, +81, -124, 24, 112, -49, -92, 58, 55, +-31, -7, -63, -49, 48, 70, -51, -43, +-26, -9, 90, 63, -91, -78, 157, 30, +-64, 42, 87, -99, 24, 96, -19, -36, +33, -63, -33, 161, 0, -216, -39, 189, +0, -101, -13, -27, 16, 136, 3, -176, +53, 110, 32, 9, 37, -125, 33, 170, +31, -148, -16, 76, 27, -4, -71, -16, +50, -11, -80, 50, 8, -76, 41, 68, +-60, -33, 120, -23, -48, 57, 93, -55, +41, 27, -38, 2, 109, -23, -74, 2, +12, 37, 10, -61, -93, 42, 81, 3, +-88, -43, 39, 48, 77, -10, -86, -50, +178, 73, -73, -35, 90, -34, 20, 76, +-40, -65, 53, -16, -38, 116, -62, -180, +77, 153, -103, -60, 64, -58, 0, 139, +13, -144, 58, 66, 35, 46, 0, -124, +92, 121, -42, -60, -5, -30, 62, 93, +-126, -84, 71, 12, -35, 65, -48, -125, +118, 144, -106, -134, 128, 95, 8, -49, +-5, -9, 92, 72, -33, -129, 26, 137, +-7, -94, -16, 21, -5, 43, -16, -89, +-1, 87, -10, -45, 50, -5, -16, 46, +49, -80, 58, 87, -40, -67, 84, 33, +-22, -14, -14, 9, 37, -24, -57, 44, +3, -48, 45, 14, -95, 35, 111, -67, +-24, 74, -15, -51, 132, 4, -93, 39, +85, -56, 27, 40, -107, -7, 151, -36, +-151, 79, 64, -93, 15, 57, -69, 6, +96, -79, -27, 120, 21, -123, 67, 86, +-31, -43, 48, 15, 13, -3, -39, -3, +36, 4, -28, -7, -19, 6, 20, 1, +-22, -17, 21, 28, 40, -36, -17, 32, +84, -44, -24, 42, 50, -31, -9, 6, +5, 29, -3, -48, -32, 32, 15, 19, +-37, -72, 14, 92, -7, -63, 25, 10, +15, 37, 54, -57, -17, 20, 101, 31, +-74, -74, 83, 86, -47, -67, -4, 18, +1, 23, -38, -37, 1, 10, 16, 28, +-42, -64, 83, 86, -28, -92, 66, 83, +17, -95, 37, 103, -5, -101, 40, 67, +-52, -7, 33, -61, -51, 104, 1, -105, +-18, 58, 1, -1, -5, -39, 35, 40, +15, -18, 26, -23, 49, 43, -1, -36, +37, 4, 11, 25, -38, -48, 48, 44, +-79, -19, 27, -14, -33, 30, -6, -22, +13, -13, 7, 47, 32, -80, 10, 69, +64, -42, -31, 10, 78, 3, -29, 3, +-4, -31, 48, 60, -97, -73, 61, 63, +-41, -44, -47, 21, 101, 0, -120, -21, +127, 28, -33, -40, 12, 39, 80, -26, +-49, -4, 63, 28, -16, -38, -4, 30, +6, -4, -11, -39, -23, 66, 21, -74, +-36, 58, 33, -32, -19, -6, 48, 34, +-35, -52, 80, 65, -48, -73, 64, 70, +-12, -50, -11, 22, 44, 13, -59, -45, +48, 61, -53, -48, 38, 17, -49, 23, +59, -68, -55, 98, 66, -111, -26, 91, +24, -52, 34, -4, -26, 56, 52, -85, +-17, 77, 8, -46, 22, 10, -45, 13, +55, -12, -74, -17, 70, 51, -71, -75, +61, 63, -34, -32, 26, -22, 27, 62, +-26, -74, 71, 46, -41, 6, 58, -62, +-22, 96, 19, -89, -12, 41, 7, 21, +-30, -66, 24, 70, -38, -33, 24, -34, +-10, 89, 14, -107, 11, 77, 28, -19, +-11, -37, 66, 67, -46, -63, 57, 29, +-19, 6, -24, -34, 50, 43, -102, -38, +96, 23, -104, -20, 81, 17, -56, -16, +59, 13, -20, -18, 46, 23, 3, -24, +12, 15, 31, 10, -38, -44, 49, 81, +-65, -93, 39, 73, -50, -22, 15, -41, +-19, 97, 10, -123, 1, 117, 12, -80, +21, 40, 9, -3, 26, -20, 7, 22, +3, -15, 13, 6, -24, -8, 14, 16, +-26, -43, 10, 59, -28, -68, 20, 59, +-8, -32, -3, -8, 54, 59, -65, -102, +117, 133, -95, -135, 90, 100, -31, -30, +-24, -59, 60, 137, -86, -177, 57, 156, +-31, -94, -20, 3, 50, 67, -59, -98, +60, 88, -22, -54, 26, 17, 3, 0, +17, 6, -4, -26, 10, 38, 2, -34, +-19, 9, 19, 25, -40, -45, 29, 48, +-34, -37, 31, 21, -31, -15, 45, 17, +-38, -20, 49, 26, -18, -29, 24, 24, +-5, -15, 10, 8, -13, 2, 14, -18, +-14, 30, -11, -42, 20, 46, -46, -36, +38, 26, -25, -14, 13, 7, 2, 4, +19, -5, -23, -2, 66, 10, -71, -18, +67, 25, -34, -18, -24, 11, 62, 5, +-98, -22, 86, 26, -66, -19, 11, 9, +33, 4, -60, -1, 75, -21, -31, 50, +3, -90, 64, 112, -87, -110, 96, 77, +-70, -20, 15, -37, 29, 71, -79, -74, +79, 52, -79, -14, 49, -11, -19, 5, +22, 22, -19, -68, 54, 111, -58, -133, +75, 118, -51, -78, 21, 23, 11, 27, +-47, -62, 54, 72, -67, -68, 43, 62, +-32, -54, 14, 44, 9, -37, -9, 31, +25, -37, -1, 48, -1, -64, 24, 73, +-23, -67, 17, 38, -3, -7, -18, -21, +9, 22, -2, 4, -33, -50, 68, 81, +-78, -90, 69, 60, -13, 3, -40, -76, +107, 141, -133, -164, 131, 150, -92, -102, +37, 43, 7, 3, -42, -32, 32, 39, +-11, -40, -19, 28, 35, -16, -25, 8, +3, -3, 41, 2, -52, -7, 63, 5, +-28, -2, -17, -5, 66, 8, -101, 0, +96, -23, -76, 57, 29, -96, 9, 123, +-33, -137, 46, 119, -37, -80, 31, 34, +-24, 19, 31, -49, -30, 57, 35, -42, +-19, 10, 4, 12, 18, -34, -37, 37, +40, -31, -43, 18, 39, -4, -41, -12, +35, 40, -29, -61, 23, 74, -1, -73, +-15, 58, 34, -32, -31, 1, 20, 22, +-3, -26, -22, 29, 34, -25, -29, 18, +13, -26, 6, 38, -28, -47, 44, 48, +-47, -49, 54, 43, -54, -43, 53, 55, +-42, -64, 35, 56, -8, -29, -19, -11, +46, 56, -57, -85, 50, 77, -24, -37, +-15, -27, 47, 86, -69, -121, 64, 117, +-36, -82, -2, 36, 33, 9, -33, -34, +23, 32, 17, -21, -46, 5, 65, -2, +-52, 4, 7, -3, 36, 2, -79, 5, +83, -11, -65, 10, 23, -2, 15, -2, +-41, 7, 45, 2, -25, -9, 0, 21, +32, -28, -46, 22, 53, -11, -47, -7, +30, 19, -21, -24, 6, 16, -10, 5, +4, -26, -2, 50, -4, -73, 24, 93, +-42, -100, 68, 93, -67, -71, 55, 31, +-28, 19, -13, -54, 37, 64, -53, -46, +32, 8, -2, 27, -40, -47, 67, 42, +-72, -16, 52, -4, -19, 24, -5, -23, +29, 5, -28, 21, 20, -53, -4, 72, +-23, -81, 35, 76, -52, -59, 46, 30, +-37, 6, 14, -44, 15, 64, -29, -58, +34, 19, -10, 41, -21, -94, 60, 112, +-81, -79, 68, 9, -43, 78, -10, -136, +39, 147, -60, -108, 54, 33, -43, 43, +33, -93, -28, 108, 30, -90, -23, 63, +13, -44, 17, 34, -45, -28, 50, 22, +-38, -3, -6, -21, 40, 39, -75, -31, +68, -3, -35, 49, -23, -87, 76, 106, +-104, -97, 102, 71, -69, -34, 20, 5, +25, 22, -58, -45, 69, 64, -65, -80, +34, 82, -4, -65, -34, 23, 61, 23, +-72, -68, 71, 83, -49, -73, 30, 38, +-17, 5, 13, -24, -22, 20, 32, 4, +-37, -28, 18, 39, 7, -28, -51, 5, +71, 23, -83, -35, 61, 30, -28, -9, +-11, -15, 43, 32, -60, -32, 63, 24, +-54, -6, 43, -13, -26, 25, 7, -30, +4, 28, -23, -14, 21, -6, -18, 30, +-2, -58, 16, 76, -25, -77, 16, 59, +5, -25, -28, -10, 50, 34, -58, -31, +51, 10, -31, 17, 3, -37, 15, 34, +-30, -17, 24, -11, -23, 35, 7, -45, +0, 43, -14, -29, 23, 18, -26, -14, +35, 13, -32, -14, 28, 9, -13, 1, +-5, -15, 17, 26, -35, -26, 37, 16, +-46, -3, 43, -14, -40, 19, 25, -12, +-14, 5, 1, 5, 26, -26, -37, 40, +52, -56, -55, 68, 45, -62, -41, 47, +28, -20, -20, -16, -3, 52, 16, -74, +-43, 78, 64, -66, -81, 43, 81, -16, +-57, -9, 24, 24, 16, -26, -55, 31, +67, -18, -72, 13, 47, 3, -29, -11, +4, 8, 9, -1, -23, -19, 29, 38, +-33, -52, 31, 46, -19, -20, 2, -21, +28, 60, -54, -87, 72, 94, -79, -76, +63, 50, -45, -19, 14, -2, 4, 16, +-29, -21, 35, 30, -42, -37, 39, 44, +-31, -45, 18, 36, 1, -22, -17, 8, +26, 1, -24, -5, 14, 7, -11, -15, +18, 29, -33, -57, 52, 76, -67, -73, +56, 43, -26, 12, -26, -70, 72, 109, +-97, -114, 88, 76, -48, -12, -8, -53, +58, 98, -87, -107, 78, 91, -46, -52, +-4, 13, 51, 16, -82, -35, 90, 41, +-82, -35, 49, 27, -14, -12, -22, -6, +35, 26, -34, -31, 13, 21, 13, 10, +-37, -46, 49, 72, -41, -74, 18, 49, +3, -2, -24, -43, 21, 73, -11, -79, +-9, 58, 16, -26, -20, 2, 1, 16, +22, -18, -38, 10, 48, -2, -41, -6, +36, 8, -24, -13, 14, 18, -5, -24, +-6, 16, 15, 2, -32, -31, 44, 54, +-51, -66, 45, 53, -22, -27, 4, -18, +21, 58, -39, -78, 45, 81, -44, -60, +33, 30, -21, 2, 5, -32, 8, 46, +-23, -50, 20, 47, -19, -32, 1, 19, +13, -7, -20, 4, 13, -6, 11, 13, +-29, -20, 45, 15, -37, -2, 19, -28, +8, 53, -33, -66, 29, 64, -21, -39, +1, -2, 15, 32, -26, -44, 14, 41, +6, -19, -20, -11, 26, 40, -17, -54, +6, 51, 15, -41, -28, 16, 32, 11, +-35, -37, 22, 57, -15, -62, -6, 54, +19, -30, -30, 3, 30, 19, -19, -19, +-3, 10, 28, 11, -38, -31, 42, 32, +-29, -25, 7, 15, 0, -10, 0, 24, +-27, -41, 42, 63, -55, -64, 46, 32, +-9, 19, -35, -79, 80, 121, -101, -131, +100, 105, -76, -52, 36, 3, 1, 31, +-32, -39, 46, 27, -46, -16, 36, 8, +-25, -10, 7, 18, 10, -27, -19, 27, +24, -22, -11, 9, 2, -4, 14, -3, +-18, 7, 10, -11, 0, 20, -14, -27, +11, 29, -2, -18, -19, -5, 38, 29, +-51, -43, 47, 41, -32, -21, 9, -2, +10, 23, -17, -33, 18, 30, -11, -21, +7, 11, 0, -14, -1, 17, 0, -23, +-5, 27, 7, -30, -3, 25, -9, -24, +22, 31, -37, -35, 39, 43, -31, -39, +17, 20, 0, 9, -15, -35, 20, 51, +-22, -49, 20, 29, -26, 3, 23, -26, +-25, 45, 11, -44, 7, 34, -25, -24, +41, 13, -45, -6, 40, 3, -26, -3, +18, 0, -11, -3, 16, 1, -28, 8, +24, -10, -21, 19, 1, -18, 15, 12, +-29, 6, 27, -24, -20, 41, 9, -48, +-1, 40, 2, -22, -3, 3, 2, 9, +9, -9, -19, -4, 31, 16, -31, -19, +16, 13, -4, 11, -10, -31, 11, 40, +-1, -31, -17, 6, 26, 25, -23, -47, +7, 50, 21, -38, -42, 14, 48, 14, +-36, -36, 20, 38, -5, -26, -5, 10, +-2, 11, 10, -21, -16, 15, 18, 4, +-18, -29, 12, 59, -14, -72, 19, 63, +-23, -29, 23, -19, -11, 60, -4, -79, +14, 69, -16, -30, 8, -20, 3, 58, +-10, -66, 4, 42, 17, -2, -42, -35, +57, 54, -59, -45, 45, 17, -23, 12, +0, -22, 13, 13, -13, 9, 10, -34, +-6, 45, 9, -40, -13, 21, 17, 0, +-16, -12, 16, 8, -7, -4, 7, -2, +-5, -6, 9, 21, -11, -34, 14, 36, +-8, -29, 3, 10, 5, 7, -1, -22, +-3, 24, 10, -20, -16, 13, 13, -2, +-12, 0, 11, 2, -12, -3, 14, 5, +-8, -11, 5, 3, 8, 9, -24, -22, +36, 33, -41, -33, 37, 21, -27, -2, +20, -19, -16, 28, 12, -19, -11, 2, +13, 13, -10, -21, 0, 21, 5, -7, +-13, -7, 21, 15, -25, -17, 31, 9, +-28, -5, 24, -4, -5, 2, -16, 0, +33, 1, -52, 7, 45, -1, -35, 2, +15, 2, 4, -11, -5, 17, -1, -30, +22, 35, -34, -36, 32, 34, -18, -21, +-3, 2, 22, 17, -38, -27, 33, 39, +-30, -36, 16, 38, -12, -28, 6, 20, +-2, -8, 0, -9, 3, 25, -4, -34, +0, 32, 7, -18, -13, -4, 12, 27, +-1, -43, -17, 44, 36, -37, -42, 22, +31, -5, -8, -6, -15, 10, 32, -15, +-23, 11, 7, -18, 19, 23, -29, -32, +27, 36, -12, -27, -13, 15, 34, 2, +-40, -23, 37, 35, -23, -40, 8, 35, +0, -16, -3, -7, 8, 26, -7, -38, +11, 33, -10, -16, 7, -6, -5, 30, +0, -39, -1, 32, 10, -15, -25, -2, +37, 12, -37, -13, 30, 1, -13, 11, +-6, -11, 16, 0, -16, 23, 8, -42, +0, 50, -2, -41, -2, 16, 17, 9, +-28, -28, 33, 30, -30, -17, 19, -2, +-2, 13, -8, -16, 9, 16, -11, -7, +8, 6, -7, -9, 8, 13, -13, -8, +16, -7, -14, 30, 5, -50, 5, 60, +-15, -52, 19, 29, -15, 0, 5, -26, +8, 42, -22, -43, 30, 38, -29, -32, +24, 24, -16, -13, 4, 1, 8, 13, +-17, -27, 20, 37, -16, -37, 6, 28, +5, -9, -11, -13, 15, 29, -15, -32, +7, 31, 2, -26, -7, 23, 2, -19, +5, 16, -16, -7, 22, -7, -21, 27, +13, -47, 0, 61, -20, -54, 32, 36, +-34, -9, 26, -19, -8, 39, -10, -49, +27, 45, -33, -35, 28, 23, -19, -8, +2, 3, 7, 5, -7, -15, 1, 24, +7, -30, -15, 34, 18, -30, -8, 14, +0, 3, 9, -18, -18, 32, 17, -30, +-17, 24, 10, -6, -8, -7, 0, 20, +8, -23, -12, 12, 23, -1, -25, -15, +25, 23, -17, -25, 9, 16, -1, -3, +-4, -7, 2, 13, -1, -7, 2, -5, +-4, 15, 14, -22, -21, 14, 24, 3, +-22, -19, 14, 28, 1, -25, -21, 15, +33, 7, -34, -31, 30, 44, -19, -44, +9, 25, 3, 3, -11, -35, 19, 55, +-24, -59, 22, 45, -18, -15, 8, -18, +6, 42, -22, -46, 30, 37, -31, -17, +21, 4, -10, -1, 3, 9, -2, -26, +6, 38, -14, -33, 13, 17, -8, 12, +-5, -36, 20, 45, -27, -35, 25, 12, +-13, 16, 0, -36, 13, 38, -16, -27, +12, 9, -4, 6, -4, -11, 4, 13, +-3, -7, -1, 5, 6, -9, -1, 6, +3, -9, -3, 3, 9, 5, -14, -15, +19, 19, -22, -12, 15, 4, -7, 9, +-4, -16, 16, 10, -13, -8, 10, 0, +-2, 2, -2, -4, 4, 4, -2, -6, +1, 11, 1, -19, 5, 19, -7, -17, +11, 8, -12, 4, 11, -14, -4, 11, +1, -4, 1, -5, -5, 14, 7, -12, +-7, 0, 6, 14, -12, -15, 10, 10, +-7, 10, -2, -28, 11, 39, -16, -35, +17, 14, -15, 19, 4, -42, 7, 52, +-12, -47, 11, 27, -5, -3, 5, -22, +5, 25, -4, -18, 0, 3, 6, 13, +-13, -18, 16, 14, -10, -5, 5, -9, +5, 14, -14, -9, 17, -1, -15, 12, +15, -22, -11, 19, 5, -3, -6, -12, +7, 28, -3, -39, 1, 36, 0, -20, +-5, 2, 7, 17, -10, -27, 10, 32, +-10, -29, 12, 19, -11, -11, 10, 3, +-8, 3, 3, -4, 0, 6, -1, -8, +5, 5, -3, -4, 1, 2, 4, 0, +-4, -8, 5, 17, -3, -29, -1, 42, +0, -45, 2, 35, -5, -14, 4, -12, +2, 34, -4, -51, 9, 50, -14, -35, +9, 19, 0, -7, -4, 0, 11, -5, +-11, 11, 8, -8, -4, -6, 5, 27, +-2, -56, 8, 69, -11, -64, 11, 42, +-9, -6, 1, -25, 8, 44, -12, -45, +12, 33, -6, -18, 2, 5, 3, -2, +-5, 7, 1, -8, -2, 9, 0, 0, +-1, -13, 4, 23, -6, -28, 7, 22, +-3, -13, 5, -2, -6, 14, 7, -18, +-9, 17, 12, -13, -9, 4, 6, 6, +-1, -15, 2, 17, 0, -20, 1, 18, +-3, -8, 3, -3, 2, 11, -4, -16, +6, 14, -8, -3, 2, -4, 4, 7, +-3, -8, 6, -3, -7, 17, 1, -22, +-2, 23, -2, -8, -2, -6, 4, 20, +-7, -23, 15, 7, -11, 7, 8, -21, +-5, 26, 1, -15, -3, -1, 5, 17, +-6, -25, 5, 23, -3, -9, 2, -6, +4, 11, -7, -2, 7, -14, -5, 30, +4, -42, 2, 35, -2, -17, 6, -11, +-3, 31, 2, -41, 0, 37, -2, -21, +2, 6, -2, 7, 5, -13, -3, 10, +5, -4, 2, -2, 0, 0, 7, 2, +-4, -9, 9, 13, -6, -11, 9, 9, +-4, -2, 8, -4, -7, 12, 10, -11, +-2, 8, 3, 0, 7, -6, -7, 16, +15, -21, -4, 16, 10, -10, 2, 1, +5, 10, 9, -18, 1, 17, 6, -9, +6, 0, 6, 6, 9, -5, 5, -5, +8, 16, 7, -27, 9, 24, 4, -9, +10, -8, 11, 23, 6, -32, 9, 27, +12, -18, 4, 5, 18, 5, 1, -2, +14, -3, 8, 9, 7, -9, 13, 3, +12, 11, 12, -25, 16, 29, 1, -21, +16, 10, 10, 5, 13, -10, 16, 9, +12, 4, 8, -18, 18, 26, 6, -26, +26, 13, 11, 3, 18, -19, 14, 26, +9, -28, 18, 20, 13, -9, 20, -2, +16, 10, 13, -16, 12, 17, 11, -16, +19, 14, 14, -7, 24, 2, 11, -3, +15, -2, 9, 0, 18, 1, 16, 2, +21, -5, 13, 7, 10, -9, 10, 7, +16, -2, 17, -11, 24, 19, 11, -29, +15, 25, 4, -17, 16, 0, 16, 11, +14, -17, 17, 20, 2, -14, 10, 6, +-1, 3, 19, -3, 12, 0, 14, 5, +6, -5, -2, 2, 8, 6, 2, -13, +22, 16, 3, -15, 7, 9, -4, 1, +-5, -10, 9, 16, 0, -16, 19, 10, +-8, -6, 1, 1, -13, 3, -2, -3, +2, 6, 3, -5, 2, 6, -16, -8, +-11, 12, -13, -11, 0, 5, 1, 0, +-7, -12, -9, 20, -30, -25, -5, 26, +-26, -20, 10, 12, -23, -2, -9, -6, +-28, 10, -23, -17, -14, 17, -22, -13, +-2, 7, -34, -3, -19, -4, -41, 6, +-22, -7, -19, 7, -22, -9, -19, 7, +-49, -6, -27, 7, -49, -6, -12, 4, +-36, -5, -22, 2, -46, -2, -50, 8, +-39, -6, -43, 7, -22, -4, -48, 3, +-37, 5, -61, -7, -48, 10, -40, -10, +-42, 2, -29, 4, -62, -11, -45, 17, +-68, -18, -44, 17, -44, -15, -49, 11, +-49, 0, -70, -3, -53, 10, -74, -10, +-33, 13, -61, -17, -47, 15, -70, -6, +-68, -4, -56, 10, -69, -19, -39, 24, +-72, -24, -53, 19, -82, -14, -66, 8, +-63, 2, -63, -9, -50, 14, -84, -15, +-56, 14, -92, -12, -54, 9, -74, 0, +-59, -2, -68, 5, -80, -10, -73, 13, +-78, -16, -56, 15, -73, -17, -60, 12, +-83, -8, -77, -2, -72, 10, -76, -19, +-56, 26, -86, -20, -65, 18, -91, -7, +-68, -4, -73, 10, -67, -18, -64, 19, +-85, -18, -70, 16, -91, -10, -64, 7, +-70, -3, -67, -7, -66, 10, -88, -18, +-69, 23, -86, -18, -58, 14, -79, -4, +-63, -5, -83, 13, -73, -18, -73, 20, +-72, -18, -55, 10, -78, -8, -63, 2, +-84, 3, -63, -11, -71, 14, -59, -20, +-65, 18, -75, -15, -65, 10, -80, -2, +-57, -2, -70, 9, -59, -9, -68, 11, +-71, -7, -63, 3, -69, 1, -55, -2, +-66, 7, -58, -5, -69, 6, -62, -3, +-63, 3, -56, -1, -56, 1, -58, -2, +-56, -1, -65, 1, -55, -1, -56, 1, +-52, -1, -53, 2, -59, 0, -51, -1, +-61, 2, -43, -4, -53, 1, -44, -2, +-53, 2, -51, -4, -48, 3, -50, -8, +-37, 5, -48, -9, -44, 6, -53, 1, +-45, -4, -46, 9, -43, -6, -38, 2, +-40, -3, -41, -5, -44, 4, -37, -4, +-43, 2, -30, 1, -41, -6, -35, 4, +-39, -4, -40, -1, -30, 5, -33, -13, +-33, 13, -35, -11, -35, 4, -38, 5, +-34, -5, -30, 9, -30, -8, -31, 5, +-34, 1, -32, -4, -30, 8, -30, -4, +-27, 7, -28, -2, -27, 0, -28, 1, +-25, -2, -22, -3, -21, -2, -25, 2, +-25, -4, -23, 5, -23, -10, -19, 6, +-22, -3, -20, -3, -20, 8, -25, -12, +-21, 13, -21, -8, -17, 2, -19, 6, +-19, -7, -22, 9, -21, 0, -18, -4, +-17, 10, -17, -5, -16, 3, -16, 3, +-16, -11, -16, 13, -12, -11, -14, 6, +-12, 3, -13, -10, -13, 9, -10, -10, +-14, 3, -9, 6, -11, -10, -12, 12, +-16, -4, -10, -1, -10, 6, -6, -10, +-7, 8, -10, -3, -8, -1, -10, 2, +-7, -2, -10, 3, -3, 1, -8, -4, +-5, 3, -5, -4, -6, -4, -2, 7, +-4, -11, -4, 12, -7, -6, -5, 2, +-5, 3, 0, -7, -3, 5, -1, 2, +-2, -8, -1, 8, -3, -8, -2, 2, +1, 6, -1, -13, 0, 17, -1, -14, +0, 5, 2, 3, 1, -14, 4, 18, +-3, -12, 4, 6, -4, 3, 2, -6, +3, 6, 0, 0, 4, -2, 0, 9, +1, -7, 1, 8, 3, 0, 5, -7, +4, 11, 2, -10, 3, 6, 5, -2, +4, -7, 7, 12, 1, -11, 6, 12, +0, -4, 5, -1, 3, 8, 4, -11, +9, 11, 2, -9, 8, 4, 3, -2, +7, -4, 6, 4, 4, -6, 7, 6, +3, -7, 5, 8, 4, -8, 7, 6, +4, -4, 6, 2, 1, 6, 7, -9, +5, 7, 5, -9, 6, 2, 5, 1, +4, -4, 2, 9, 4, -6, 3, 2, +6, 1, 1, -3, 5, 6, 4, -3, +-1, 4, 3, 2, -1, 1, 5, -1, +4, 4, 3, -8, 3, 9, -1, -5, +3, 3, 0, 5, 5, -12, 4, 11, +3, -14, 1, 10, 3, -7, 1, 0, +2, 5, 2, -7, 0, 6, 1, -4, +-2, 3, 2, -1, 1, 0, 2, -3, +-1, 5, -2, -3, 4, -1, -3, 2, +4, -5, 1, 2, 2, -5, 0, -1, +-2, 6, 0, -9, -2, 13, 0, -11, +1, 6, -1, -1, -3, -4, 1, 8, +-1, -12, 0, 10, 0, -7, 0, 0, +2, 1, -6, -2, 0, 3, -4, 1, +0, -2, 0, 4, 1, -6, 0, 1, +-3, 3, 0, -7, 1, 4, -4, -1, +0, 2, -2, 2, -2, -3, 0, 1, +-1, 0, -1, -3, -1, 7, 0, -10, +-1, 10, -3, -6, 1, 3, 1, -3, +2, -3, 2, 2, 1, -5, 1, 3, +-3, -2, 3, 2, -2, -1, 1, 4, +0, -4, 1, 5, -2, -4, 2, 6, +0, -7, 4, 8, 3, -13, 1, 12, +1, -10, 3, 6, 3, -5, 3, -1, +1, 5, 3, -7, -1, 8, 6, -8, +-3, 7, 6, -3, 0, 2, 3, 0, +2, 2, 4, -6, 1, 8, 3, -5, +3, 2, 3, 3, 5, -8, 3, 9, +5, -9, 5, 2, 5, 2, 2, -5, +2, 9, 3, -3, 4, -2, 2, 12, +2, -13, 3, 20, 4, -16, 2, 12, +9, -6, -1, 0, 6, 10, 2, -11, +9, 11, 6, -14, 7, 10, 6, -12, +6, 11, 6, -10, 6, 9, 4, -6, +9, 1, 6, -1, 7, -1, 3, 5, +7, -1, 3, 1, 9, 1, 1, -4, +7, 8, -1, -4, 7, 5, 5, -4, +4, -2, 5, 7, 3, -12, 9, 15, +6, -20, 11, 19, 6, -17, 12, 12, +5, -6, 11, 4, 7, 5, 9, -5, +5, 15, 5, -9, 6, 14, 3, -8, +4, 9, 7, -6, 2, -1, 6, 2, +-1, -8, 11, -1, 0, -7, 8, 2, +6, -6, 11, -3, 6, 3, 11, -5, +12, 9, 12, -6, 14, 12, 11, -1, +10, 7, 8, 12, 6, -5, 6, 23, +1, -14, 4, 20, -1, -14, 2, 5, +-2, -5, 1, -10, 3, -1, 2, -19, +7, 1, 5, -20, 13, 3, 9, -13, +19, 5, 12, -3, 19, 7, 15, 6, +15, 10, 16, 12, 13, 8, 9, 17, +6, 8, 3, 9, -3, 12, -7, -1, +-3, 7, -3, -19, -4, 0, -8, -17, +-2, -13, -2, -12, 4, -21, 11, -8, +16, -22, 16, 0, 22, -10, 24, 2, +22, 10, 23, 9, 22, 19, 16, 16, +14, 23, 8, 15, 6, 18, -5, 13, +-7, 9, -12, 4, -14, -5, -13, -9, +-15, -15, -9, -20, -7, -20, 2, -30, +5, -18, 14, -31, 17, -6, 26, -22, +27, 9, 27, -3, 30, 19, 25, 15, +26, 23, 15, 32, 12, 23, 3, 36, +-3, 14, -12, 28, -16, 3, -19, 7, +-21, -7, -19, -19, -14, -20, -13, -38, +-6, -22, 3, -46, 13, -24, 18, -34, +25, -18, 30, -13, 34, -4, 34, 10, +33, 16, 26, 29, 25, 29, 11, 41, +5, 36, -5, 36, -11, 31, -19, 17, +-21, 18, -27, -8, -25, -1, -26, -28, +-15, -26, -10, -41, -1, -40, 4, -37, +18, -41, 18, -26, 31, -25, 33, -12, +38, -1, 33, 12, 32, 22, 22, 33, +19, 35, 6, 46, -2, 40, -10, 42, +-23, 33, -25, 25, -28, 9, -25, -4, +-24, -14, -21, -27, -16, -28, -6, -48, +0, -35, 11, -51, 20, -32, 28, -40, +31, -18, 33, -12, 33, 0, 32, 17, +26, 15, 17, 45, 10, 28, 2, 50, +-11, 36, -16, 42, -26, 34, -27, 19, +-29, 17, -28, -8, -25, -5, -19, -31, +-13, -25, -3, -41, 4, -40, 14, -36, +21, -44, 30, -25, 28, -29, 29, 1, +29, -9, 27, 21, 17, 15, 10, 39, +3, 30, -4, 42, -14, 39, -19, 33, +-27, 35, -27, 16, -29, 15, -25, -1, +-19, -14, -13, -18, -9, -32, 4, -33, +11, -45, 19, -36, 20, -37, 28, -27, +27, -24, 26, -6, 20, -3, 20, 14, +13, 10, 8, 33, -5, 25, -8, 41, +-18, 29, -21, 37, -24, 25, -26, 22, +-23, 10, -22, 2, -17, -8, -11, -16, +-5, -25, 6, -32, 11, -34, 16, -33, +17, -31, 21, -23, 19, -20, 19, -4, +17, -7, 12, 14, 5, 14, -3, 28, +-6, 29, -10, 28, -11, 31, -18, 24, +-18, 25, -22, 15, -21, 13, -14, -2, +-9, -10, -6, -14, -3, -24, 4, -24, +11, -37, 14, -26, 15, -32, 12, -13, +18, -23, 13, -3, 11, -1, 6, 10, +4, 17, -2, 19, -7, 32, -11, 24, +-14, 30, -14, 21, -16, 21, -16, 12, +-14, 7, -11, -3, -11, -7, -5, -17, +0, -22, 6, -26, 7, -27, 9, -24, +13, -26, 14, -17, 10, -11, 10, 0, +7, 3, 3, 17, 2, 13, -3, 26, +-8, 24, -9, 27, -12, 25, -13, 20, +-13, 16, -12, 5, -11, 3, -7, -11, +-5, -10, -3, -21, 2, -20, 4, -27, +6, -22, 8, -21, 12, -19, 14, -13, +8, -4, 9, 2, 8, 6, 2, 17, +-1, 21, -2, 22, -8, 25, -9, 23, +-11, 18, -13, 19, -11, 5, -9, 4, +-8, -9, -5, -11, -4, -18, -1, -20, +3, -23, 5, -22, 8, -19, 6, -15, +9, -7, 6, -5, 6, 10, 7, 2, +5, 20, 2, 12, -2, 26, -6, 20, +-5, 19, -7, 17, -7, 8, -9, 8, +-10, -1, -10, -3, -6, -13, -4, -14, +-4, -18, 2, -19, 3, -21, 3, -14, +7, -14, 8, -7, 10, -5, 6, 6, +5, 8, 3, 16, 1, 16, 1, 17, +-3, 21, -4, 12, -4, 15, -7, 2, +-8, 11, -11, -6, -5, -1, -7, -17, +-3, -9, -6, -19, 2, -15, 2, -19, +4, -11, 4, -8, 7, -8, 7, 2, +7, -1, 7, 14, 3, 9, 1, 23, +-2, 13, 1, 17, -3, 10, -2, 11, +-3, 3, -7, 4, -5, -4, -6, -9, +-4, -10, -8, -13, -5, -8, -2, -18, +0, -6, 1, -14, 0, 2, 3, -7, +5, 7, 5, 1, 5, 14, 5, 8, +2, 16, 1, 13, 1, 11, 0, 12, +1, 1, -3, 9, -5, -2, -7, 2, +-7, -9, -2, -8, -7, -12, -3, -7, +-5, -13, -2, -5, -1, -10, 3, -3, +3, -2, 4, 2, 5, 6, 1, 9, +2, 14, 4, 6, 8, 11, 1, 5, +3, 13, -2, 0, 2, 7, -1, -9, +-2, 4, -3, -12, -3, -3, -4, -11, +-5, -6, -3, -7, -2, -11, 0, -1, +-3, -7, 5, 4, -3, -2, 3, 13, +1, -1, 7, 14, 3, 1, 5, 14, +3, 2, 7, 4, 4, 0, 0, 2, +1, 1, 0, -8, 1, -2, -3, -13, +2, -4, -5, -13, 1, -2, -8, -8, +2, -1, -4, -5, 1, 4, -3, 0, +4, 3, 3, 3, 1, 6, 6, 7, +1, 3, 7, 10, -3, 1, 7, 9, +-4, -3, 5, 6, -4, -7, 4, 0, +-5, -8, 1, -2, -5, -6, -3, -3, +-3, -4, -3, -4, 0, 0, -6, -2, +2, 4, -4, -1, 4, 7, -5, 3, +7, 7, -2, 3, 9, 5, 0, 2, +6, 5, 1, 0, 5, 0, -2, 3, +-1, -4, 3, 0, -4, -8, 3, 1, +-7, -10, 2, 3, -6, -11, 3, 3, +-8, -5, 5, 1, -3, -3, 4, 2, +-1, 4, 5, -2, 1, 10, 3, -4, +6, 11, 2, -7, 7, 10, -2, -6, +9, 4, -5, -4, 7, 0, -6, -3, +4, -4, -6, -1, 2, -7, -5, 2, +-2, -7, -4, 6, -3, -8, 1, 8, +-2, -8, 6, 8, -2, -6, 5, 12, +-3, -3, 11, 6, -2, 0, 8, 4, +-3, 4, 6, -2, 0, 4, 4, -8, +0, 6, -3, -9, -3, 10, -5, -12, +0, 10, -6, -14, 2, 9, -7, -10, +4, 7, -7, -4, 6, 3, -3, 0, +7, -1, 0, 4, 6, -3, 5, 5, +2, -3, 5, 9, 3, -11, 5, 12, +-1, -12, 6, 11, -6, -11, 3, 10, +-6, -9, 1, 7, -6, -5, 1, 2, +-4, -1, 0, -3, 0, 3, -1, -6, +2, 9, 1, -13, 5, 13, -1, -13, +9, 12, 2, -16, 11, 9, 2, -13, +8, 8, -2, -6, 4, 6, 0, -4, +1, 2, -1, 2, -2, -1, -3, 7, +-4, -6, -2, 12, -6, -9, 1, 13, +-4, -13, 4, 11, 0, -15, 5, 10, +3, -15, 7, 6, -1, -6, 7, -1, +2, -1, 0, 1, 4, 4, 1, -6, +3, 11, -2, -8, 1, 14, -4, -9, +-2, 18, -7, -8, 0, 15, -2, -11, +0, 11, -3, -5, 1, 1, 3, -4, +0, -4, 3, 1, 1, -8, 4, 4, +1, -11, 6, 6, 3, -13, 5, 10, +1, -10, 2, 10, 1, -5, 0, 8, +2, -1, -3, 7, -2, 4, -1, 3, +-2, 5, -2, -1, 2, 2, -3, -4, +3, 2, 0, -8, 2, 2, 4, -12, +1, 3, 5, -14, 5, 2, 2, -8, +4, 1, 6, -6, -1, 3, 3, 3, +-2, 1, -2, 11, -3, 1, -4, 12, +-2, -1, -1, 9, -3, -2, 0, 4, +0, -2, -1, -3, 6, -2, -2, -7, +5, -2, 0, -5, 3, -5, 7, -5, +-1, -2, 1, 1, 4, -4, -1, 4, +2, -1, 2, 4, -5, 5, 4, 0, +-3, 7, 1, -2, -2, 11, -3, -3, +0, 4, 2, -2, -4, -2, 5, 1, +-1, -7, -1, 3, 7, -11, -2, 2, +7, -10, 4, -2, 1, -1, 2, -3, +2, 6, -3, -7, 7, 9, -5, -5, +3, 7, -2, 4, -8, 4, 3, 6, +-1, -7, -4, 12, 0, -7, -2, 8, +-1, -8, 7, -1, -10, 3, 7, -8, +-2, 6, 2, -13, 5, 7, 0, -10, +1, 5, 4, -1, -4, 0, 1, 7, +3, -6, -9, 12, 10, -10, -6, 8, +2, -4, -1, 4, -3, 1, 2, -7, +0, 8, -6, -9, 7, 5, -5, -4, +-2, 1, 8, -1, -7, -4, 7, 5, +1, -10, 2, 6, 4, -7, -2, 8, +-3, -1, 8, -1, -8, 8, 3, -7, +-1, 11, -7, -8, 1, 11, -6, -5, +-3, 3, 1, 0, -4, -6, -3, 7, +5, -11, -7, 7, 8, -9, -6, 7, +0, -2, 2, 1, -2, 3, 1, -4, +5, 6, -4, -5, 3, 6, 0, -2, +-6, 1, 6, 2, -11, -3, 1, 5, +-3, -7, -8, 7, -2, -6, -2, 1, +-11, 1, 3, -4, -6, 3, -3, -5, +2, 5, -7, -6, 4, 3, -6, 1, +-2, 0, -1, 5, -2, -4, -5, 5, +1, -2, -10, 3, 0, -1, -9, 2, +-10, 3, -4, -4, -10, 3, -9, -6, +-4, 2, -11, -5, -9, 1, -4, -1, +-15, -3, 2, 2, -11, -6, -5, 7, +-6, -3, -8, 5, -7, -1, -5, 4, +-11, -1, -6, 3, -7, -1, -16, 3, +-5, 1, -16, -3, -9, 2, -16, 0, +-15, 0, -13, -2, -12, -1, -16, -4, +-7, -1, -18, -3, -13, 3, -9, -5, +-19, 5, -9, -1, -16, 4, -12, -1, +-11, 2, -14, 2, -15, -1, -10, 4, +-23, 0, -12, 4, -20, -2, -17, 0, +-15, -3, -20, -2, -17, -5, -17, -2, +-22, -2, -19, -1, -15, -5, -24, 0, +-15, 0, -22, -1, -18, 1, -19, 0, +-23, 5, -20, 1, -19, 5, -25, 1, +-19, 4, -22, -2, -23, 1, -18, -3, +-29, 2, -21, -1, -25, -3, -25, -1, +-24, -4, -24, -2, -26, -3, -21, -3, +-27, -1, -27, 1, -26, 3, -29, -1, +-23, 4, -24, -5, -26, 3, -26, 1, +-26, -1, -30, 5, -23, -5, -34, 7, +-27, -3, -31, 4, -31, -4, -28, 3, +-31, -5, -27, -1, -30, -2, -33, 2, +-30, -2, -29, -1, -31, -3, -29, 3, +-35, 0, -29, 2, -32, 1, -32, 1, +-31, 2, -32, -1, -31, 2, -31, -4, +-33, 7, -34, -8, -28, 5, -38, -7, +-30, 6, -37, -5, -33, 3, -32, -4, +-35, 1, -33, -1, -32, -2, -36, 3, +-35, -1, -34, 4, -36, -2, -34, 5, +-37, -1, -34, 2, -31, -4, -35, 1, +-36, -1, -35, 2, -36, -5, -33, 2, +-38, -4, -37, 5, -35, -4, -36, 1, +-34, -3, -39, 4, -36, 0, -35, -2, +-36, 4, -38, -4, -35, 7, -41, -1, +-35, 5, -37, -3, -38, 4, -36, -1, +-36, 0, -36, 0, -34, -3, -34, -1, +-35, -3, -34, 0, -37, -2, -33, -1, +-38, 1, -36, 1, -37, 1, -36, 2, +-38, 2, -37, 5, -36, -3, -32, 2, +-34, -5, -36, 5, -34, -4, -35, 2, +-33, -3, -37, 3, -32, -2, -33, -4, +-34, 3, -33, -7, -33, 5, -36, -3, +-33, 4, -33, -4, -34, 4, -33, -1, +-34, 3, -32, 0, -32, 0, -30, -2, +-35, 4, -30, -2, -34, 2, -32, 0, +-33, 2, -30, -3, -30, -1, -31, -1, +-32, 0, -31, 0, -29, -3, -29, 0, +-27, -5, -30, 3, -29, -2, -31, 4, +-27, -2, -29, 2, -25, -3, -28, 2, +-28, 0, -28, 2, -30, 2, -27, 0, +-27, -1, -26, 0, -26, -2, -25, -1, +-29, 1, -26, 0, -24, -3, -25, 0, +-25, 0, -27, 1, -23, 1, -21, -5, +-22, 3, -24, -2, -22, 5, -25, -3, +-20, 5, -25, -4, -18, 4, -25, -3, +-22, 6, -22, -5, -19, 3, -22, -5, +-21, 4, -22, -3, -21, 2, -17, -3, +-17, -4, -19, 3, -19, -2, -18, 3, +-18, -3, -17, 5, -20, -2, -14, 3, +-19, -2, -14, 4, -16, -4, -17, 5, +-17, -3, -13, 2, -18, -2, -11, -1, +-17, -3, -11, -1, -16, -2, -10, -3, +-14, -2, -11, 0, -17, -1, -6, -1, +-14, -4, -9, 5, -19, -1, -5, 3, +-13, -7, -6, 8, -15, -7, -4, 7, +-16, -6, -7, 8, -16, -4, -7, 5, +-12, -5, -5, 1, -12, -2, -5, -1, +-10, -2, -6, -2, -8, 0, -7, -2, +-11, 5, -9, 0, -7, 2, -6, -3, +-5, 3, -7, -4, 0, 1, -11, -1, +-2, 3, -13, 2, -5, 6, -9, -3, +1, 0, -10, -2, -1, 3, -12, -1, +3, -1, -11, -2, 2, 0, -10, -4, +4, 1, -9, -5, 6, 2, -9, -5, +1, 8, -11, -3, 4, 4, -9, -4, +6, 2, -9, -3, 3, 4, -6, -5, +3, 2, -6, -4, 2, 2, -7, -3, +3, 2, -8, -2, 3, 0, -5, -3, +-3, 5, -7, 1, -1, 0, -3, 0, +1, -2, -2, 1, 1, -4, -3, 4, +-2, -2, 2, 1, -4, -1, -1, 5, +-6, 0, 5, -3, -6, 0, 2, 1, +-3, -4, 5, -2, -6, -2, 1, 2, +-6, -1, 1, 2, -5, -1, 1, 2, +-7, 1, 5, -2, -7, 2, 4, -2, +-5, 1, 1, 0, -4, 0, 1, 0, +-4, -1, 3, -1, -4, -3, 3, -1, +-4, -3, 0, 2, -3, -4, 1, 1, +-5, -3, 4, -2, -6, 0, 2, -1, +-2, -4, 3, -2, -3, -2, 2, 0, +-1, -4, 2, 0, -1, -4, 3, -2, +1, -4, 0, -1, 2, -5, 1, -3, +2, -4, 0, -3, 3, -4, 3, -7, +2, -2, 2, -5, 3, -4, 3, -4, +6, -8, 2, -1, 2, -5, 2, 0, +5, -8, 6, -4, 6, -9, 3, -1, +6, -8, 5, -3, 6, -6, 8, -8, +10, -8, 5, -6, 8, -6, 5, -6, +9, -6, 10, -11, 11, -6, 9, -11, +14, -7, 8, -9, 12, -4, 10, -11, +16, -8, 10, -9, 17, -8, 11, -8, +16, -8, 16, -12, 18, -10, 14, -8, +19, -12, 19, -11, 22, -14, 20, -11, +19, -10, 23, -14, 19, -8, 23, -14, +24, -11, 25, -15, 25, -10, 26, -15, +28, -11, 27, -15, 31, -14, 30, -15, +30, -13, 32, -16, 32, -13, 31, -13, +36, -16, 38, -19, 37, -16, 37, -16, +37, -16, 37, -14, 35, -13, 39, -14, +39, -16, 40, -13, 41, -18, 50, -20, +45, -20, 46, -14, 45, -18, 49, -16, +46, -18, 54, -20, 51, -19, 54, -18, +51, -17, 55, -19, 51, -14, 53, -16, +54, -17, 60, -23, 58, -19, 61, -22, +60, -18, 59, -19, 62, -18, 62, -21, +65, -19, 65, -23, 66, -19, 66, -21, +67, -18, 69, -22, 70, -20, 70, -21, +69, -19, 71, -19, 75, -24, 75, -21, +75, -24, 76, -21, 78, -26, 79, -22, +76, -23, 80, -23, 79, -24, 80, -22, +81, -24, 83, -25, 84, -24, 83, -23, +84, -23, 82, -22, 87, -24, 85, -24, +88, -23, 86, -25, 88, -22, 87, -24, +88, -22, 89, -25, 89, -23, 88, -24, +91, -25, 87, -21, 88, -23, 89, -22, +92, -28, 89, -19, 88, -25, 93, -24, +91, -26, 92, -23, 90, -23, 90, -23, +92, -23, 93, -26, 95, -25, 92, -25, +94, -23, 90, -24, 93, -23, 93, -26, +92, -22, 95, -28, 93, -24, 89, -23, +92, -25, 91, -24, 90, -24, 91, -24, +88, -23, 92, -25, 89, -24, 87, -20, +89, -25, 90, -23, 89, -26, 88, -20, +85, -23, 89, -22, 85, -23, 88, -22, +85, -23, 85, -22, 85, -24, 82, -20, +83, -23, 83, -21, 80, -21, 84, -25, +79, -19, 82, -23, 79, -20, 79, -21, +79, -21, 77, -21, 77, -21, 75, -20, +76, -20, 74, -20, 75, -20, 75, -22, +74, -21, 75, -22, 71, -19, 72, -20, +70, -19, 71, -20, 70, -20, 68, -17, +68, -19, 67, -18, 68, -21, 67, -20, +63, -18, 61, -17, 62, -18, 63, -20, +61, -17, 59, -16, 59, -15, 60, -17, +62, -17, 61, -18, 61, -16, 59, -16, +60, -17, 57, -16, 57, -18, 54, -16, +52, -16, 49, -13, 51, -19, 50, -15, +49, -18, 46, -10, 48, -17, 48, -9, +50, -17, 52, -11, 51, -17, 51, -10, +48, -14, 51, -14, 46, -15, 47, -15, +42, -14, 39, -12, 35, -11, 37, -13, +34, -9, 37, -12, 38, -9, 43, -15, +45, -11, 43, -11, 44, -8, 45, -12, +41, -7, 41, -12, 39, -11, 33, -9, +31, -10, 28, -8, 24, -8, 25, -8, +28, -12, 27, -5, 31, -10, 35, -7, +35, -7, 41, -9, 39, -5, 44, -13, +35, -1, 35, -11, 29, -1, 25, -12, +22, -1, 18, -13, 16, 0, 14, -11, +16, 1, 19, -10, 24, -1, 28, -10, +31, 0, 36, -9, 35, -1, 36, -6, +31, 0, 29, -6, 25, -4, 17, -4, +13, -5, 9, -5, 7, -5, 4, -2, +10, -7, 12, -2, 18, -4, 26, -6, +27, -1, 31, -4, 33, -1, 33, -6, +28, 0, 22, -5, 16, 1, 8, -4, +4, -1, -4, -2, -5, -1, -3, -3, +-2, -1, 3, 1, 11, -4, 16, 2, +25, -6, 26, 3, 31, -8, 25, 4, +24, -6, 17, 1, 7, -3, -3, 6, +-5, -6, -8, -1, -13, -5, -13, 2, +-8, -5, -5, 3, 4, -3, 11, 0, +17, -2, 21, 0, 22, -1, 20, 0, +14, 0, 8, 0, -2, -1, -8, 1, +-15, -4, -20, 4, -21, -6, -22, 6, +-14, -9, -10, 7, -2, -9, 6, 6, +13, -10, 13, 8, 13, -6, 12, 7, +6, -7, 1, 4, -9, -5, -16, 2, +-25, 0, -28, 1, -29, -1, -26, -2, +-22, 2, -15, -5, -11, 8, -1, -6, +7, 4, 8, -6, 8, 6, 4, -5, +-2, 7, -9, -4, -16, 4, -23, -3, +-31, 2, -31, -4, -36, 3, -33, 0, +-25, -1, -23, 4, -12, -2, -5, 2, +-3, -2, 4, 2, 1, -3, -3, 5, +-6, -3, -18, 4, -23, 4, -27, -5, +-35, 4, -36, -3, -35, 1, -38, -5, +-25, 11, -32, -13, -16, 22, -15, -16, +-4, 10, -7, -4, -3, 6, -15, -5, +-12, 15, -25, -12, -23, 9, -38, 1, +-40, -1, -40, 3, -44, 6, -36, -9, +-34, 9, -31, 0, -27, 0, -17, 8, +-17, -4, -11, -1, -20, 13, -20, -5, +-25, 8, -32, 7, -35, -3, -39, 1, +-46, 13, -45, -17, -49, 24, -42, -13, +-39, 7, -39, 3, -34, 10, -29, -9, +-32, 26, -24, -16, -25, 9, -33, 7, +-35, -2, -35, 3, -50, 9, -44, -4, +-55, 4, -54, 16, -55, -18, -47, 26, +-57, -16, -33, 16, -59, -4, -26, 10, +-46, -5, -42, 13, -32, 2, -56, -3, +-38, 19, -55, -10, -59, 13, -57, 3, +-64, 9, -70, -8, -56, 34, -73, -31, +-54, 39, -66, -14, -54, 10, -59, 9, +-51, 3, -59, -1, -56, 17, -60, 0, +-61, -5, -64, 29, -67, -32, -73, 40, +-71, -22, -78, 25, -75, -7, -79, 25, +-72, -16, -76, 30, -69, -11, -71, 10, +-66, 14, -79, -16, -59, 41, -90, -48, +-54, 76, -106, -83, -48, 109, -116, -116, +-43, 136, -133, -130, -31, 139, -141, -117, +-29, 103, -139, -49, -31, 6, -125, 59, +-47, -109, -108, 178, -75, -217, -80, 260, +-101, -247, -79, 209, -74, -103, -151, -2, +17, 115, -231, -153, 39, 143, -180, -46, +-75, -42, -46, 121, -175, -102, -18, 37, +-133, 95, -97, -179, -62, 225, -123, -166, +-83, 74, -89, 45, -96, -88, -130, 83, +-12, 23, -225, -135, 58, 252, -240, -290, +22, 280, -182, -183, -26, 79, -166, 53, +-18, -126, -167, 176, -43, -153, -102, 118, +-126, -53, -31, 24, -159, 4, -46, 21, +-102, -33, -122, 58, -24, -30, -189, -15, +33, 108, -239, -174, 59, 243, -229, -236, +15, 205, -147, -123, -67, 56, -88, 9, +-90, -8, -88, -3, -81, 46, -60, -50, +-165, 45, 80, 26, -322, -112, 227, 234, +-437, -327, 295, 424, -461, -461, 281, 469, +-394, -398, 139, 292, -158, -117, -163, -50, +165, 211, -414, -272, 274, 266, -334, -146, +50, 9, -41, 127, -202, -159, 82, 123, +-164, 3, -76, -112, 18, 195, -187, -173, +16, 99, -82, 22, -118, -86, 6, 94, +-77, 3, -158, -129, 178, 277, -401, -354, +334, 374, -413, -290, 204, 169, -182, -2, +-70, -137, 85, 255, -307, -304, 277, 333, +-458, -316, 392, 321, -517, -324, 399, 372, +-459, -402, 312, 427, -346, -390, 218, 318, +-274, -199, 170, 107, -241, -35, 135, 38, +-193, -71, 62, 138, -99, -173, -58, 191, +43, -159, -199, 127, 170, -97, -267, 116, +170, -165, -184, 276, 40, -386, -39, 514, +-55, -598, -9, 648, -26, -630, -74, 585, +20, -498, -87, 435, 4, -382, -70, 368, +9, -345, -100, 315, 52, -230, -107, 118, +22, 26, -31, -142, -56, 240, 24, -292, +-56, 338, -12, -385, -19, 459, -24, -532, +-60, 600, 37, -602, -89, 528, -15, -366, +49, 161, -196, 58, 223, -239, -306, 382, +261, -460, -272, 497, 222, -495, -266, 472, +258, -398, -313, 278, 273, -91, -269, -132, +153, 376, -110, -572, -13, 693, 26, -685, +-113, 565, 126, -353, -235, 113, 293, 100, +-401, -234, 411, 260, -383, -181, 224, 10, +-45, 225, -206, -458, 369, 642, -508, -698, +470, 593, -375, -290, 104, -177, 184, 749, +-583, -1310, 917, 1753, -1239, -1979, 1389, 1944, +-1421, -1652, 1252, 1163, -986, -580, 627, 29, +-324, 392, 82, -604, 9, 588, -24, -391, +-48, 110, 59, 122, -22, -181, -180, -8, +474, 431, -888, -1005, 1290, 1575, -1661, -1969, +1871, 2075, -1908, -1857, 1733, 1374, -1393, -764, +925, 196, -418, 201, -69, -375, 454, 368, +-746, -277, 896, 238, -965, -321, 927, 545, +-836, -837, 673, 1071, -471, -1113, 230, 875, +34, -369, -294, -301, 548, 959, -746, -1420, +893, 1556, -955, -1323, 927, 829, -785, -244, +543, -236, -208, 491, -178, -502, 582, 370, +-947, -238, 1218, 254, -1317, -445, 1225, 732, +-885, -926, 360, 849, 320, -385, -976, -400, +1522, 1290, -1751, -1981, 1658, 2180, -1183, -1757, +506, 783, 249, 448, -807, -1545, 1077, 2122, +-921, -1984, 469, 1167, 195, 33, -775, -1188, +1147, 1894, -1102, -1894, 724, 1197, -16, -68, +-719, -1102, 1380, 1902, -1697, -2075, 1691, 1598, +-1302, -658, 748, -410, -92, 1262, -410, -1662, +742, 1565, -771, -1083, 632, 445, -307, 123, +13, -449, 268, 495, -337, -325, 297, 70, +-47, 139, -206, -217, 482, 163, -558, -25, +501, -94, -206, 110, -109, 25, 426, -293, +-477, 612, 342, -885, 84, 997, -537, -875, +973, 526, -1091, -36, 973, -461, -509, 802, +-6, -891, 546, 706, -830, -321, 933, -96, +-755, 393, 534, -461, -233, 294, 70, -2, +92, -252, -143, 305, 292, -90, -407, -362, +630, 881, -737, -1262, 796, 1325, -600, -983, +309, 291, 170, 551, -561, -1293, 902, 1696, +-947, -1649, 849, 1192, -520, -517, 242, -111, +11, 461, 3, -440, -110, 110, 376, 314, +-503, -578, 522, 503, -241, -58, -137, -589, +619, 1170, -881, -1424, 962, 1224, -687, -636, +323, -123, 149, 734, -399, -974, 522, 764, +-354, -254, 174, -315, 65, 663, -94, -648, +75, 279, 105, 255, -173, -713, 213, 886, +-36, -695, -152, 224, 425, 334, -521, -755, +549, 880, -337, -674, 117, 222, 205, 293, +-363, -695, 480, 854, -380, -737, 269, 424, +-30, -58, -94, -218, 232, 313, -180, -237, +148, 57, 15, 94, -53, -144, 131, 48, +-45, 121, 9, -256, 115, 260, -99, -93, +120, -191, -6, 471, -4, -619, 62, 548, +44, -279, -98, -84, 239, 398, -202, -552, +158, 492, 86, -273, -273, 1, 526, 205, +-565, -279, 570, 210, -341, -70, 157, -63, +119, 110, -189, -67, 239, -47, -48, 141, +-102, -161, 343, 70, -368, 103, 342, -300, +-39, 424, -256, -413, 652, 247, -798, 23, +833, -309, -521, 499, 163, -514, 327, 325, +-556, 2, 650, -372, -356, 652, 1, -754, +505, 630, -755, -327, 876, -66, -609, 421, +271, -648, 241, 688, -546, -557, 787, 306, +-690, -35, 552, -196, -202, 316, -13, -326, +271, 240, -296, -111, 344, -16, -204, 91, +175, -103, -55, 59, 110, 1, -75, -52, +166, 49, -95, 9, 62, -105, 164, 200, +-297, -263, 512, 258, -492, -198, 451, 94, +-157, -5, -59, -51, 348, 40, -379, 26, +360, -121, -86, 207, -109, -263, 365, 267, +-370, -228, 339, 165, -89, -103, -53, 46, +246, -19, -195, 0, 144, 14, 90, -47, +-196, 112, 348, -226, -260, 355, 185, -481, +69, 549, -198, -540, 375, 435, -336, -268, +310, 83, -104, 46, 12, -106, 140, 80, +-95, -25, 90, -11, 62, -34, -75, 160, +137, -344, -13, 512, -57, -579, 222, 512, +-234, -296, 265, -2, -118, 286, 47, -468, +98, 488, -71, -355, 60, 131, 109, 71, +-182, -165, 298, 95, -215, 109, 130, -371, +129, 563, -295, -597, 502, 429, -495, -112, +448, -249, -198, 516, -11, -582, 281, 401, +-343, -43, 340, -383, -94, 712, -149, -844, +476, 716, -603, -387, 645, -40, -415, 417, +159, -641, 203, 649, -387, -467, 492, 180, +-346, 103, 177, -293, 73, 340, -154, -249, +172, 68, 26, 119, -216, -253, 464, 290, +-529, -243, 529, 139, -308, -39, 83, -37, +237, 71, -435, -83, 616, 104, -621, -151, +619, 203, -472, -245, 355, 229, -158, -133, +35, -26, 132, 186, -188, -281, 242, 265, +-170, -122, 125, -110, 9, 342, -64, -489, +147, 494, -122, -350, 117, 111, -29, 142, +18, -342, 45, 411, -17, -358, 22, 216, +53, -54, -79, -74, 162, 128, -182, -107, +236, 44, -202, 22, 184, -57, -59, 44, +-40, -6, 206, -29, -289, 33, 373, -3, +-325, -43, 249, 71, -62, -45, -89, -54, +287, 179, -379, -297, 447, 348, -381, -303, +305, 155, -134, 49, 4, -247, 170, 367, +-253, -389, 345, 311, -329, -191, 326, 67, +-236, 12, 166, -38, -26, 26, -77, -19, +224, 42, -301, -105, 378, 181, -346, -227, +291, 201, -129, -94, -8, -76, 177, 246, +-240, -351, 266, 343, -163, -214, 53, 6, +111, 206, -186, -338, 219, 342, -119, -204, +-1, -35, 189, 292, -310, -473, 402, 518, +-357, -415, 275, 192, -89, 63, -63, -269, +221, 368, -267, -339, 279, 213, -184, -56, +110, -66, -8, 98, 3, -33, -20, -104, +128, 254, -200, -364, 283, 386, -254, -313, +198, 164, -41, 5, -71, -158, 182, 263, +-171, -315, 133, 319, -3, -311, -72, 297, +142, -291, -98, 283, 47, -267, 68, 218, +-111, -138, 134, 27, -44, 91, -47, -201, +184, 275, -236, -297, 252, 263, -143, -179, +15, 65, 173, 55, -284, -156, 369, 213, +-321, -230, 241, 209, -77, -183, -37, 167, +139, -177, -135, 216, 110, -261, -20, 286, +-15, -262, 34, 188, 49, -70, -136, -61, +256, 176, -276, -248, 248, 254, -90, -202, +-82, 114, 283, -15, -378, -63, 397, 106, +-270, -104, 100, 72, 116, -31, -243, 2, +307, 0, -233, 29, 117, -76, 55, 120, +-154, -139, 197, 128, -118, -78, 0, 11, +174, 55, -289, -105, 370, 129, -334, -135, +260, 132, -111, -146, -4, 174, 121, -211, +-162, 239, 183, -232, -141, 187, 117, -100, +-71, -2, 66, 88, -32, -128, 11, 117, +58, -57, -118, -27, 217, 107, -274, -159, +317, 169, -265, -151, 186, 104, -45, -48, +-77, -15, 210, 78, -276, -142, 307, 215, +-268, -276, 229, 314, -151, -319, 94, 278, +-13, -199, -19, 86, 48, 32, -32, -130, +17, 199, 27, -227, -52, 222, 85, -201, +-68, 177, 35, -153, 28, 141, -65, -127, +92, 120, -71, -103, 33, 80, 43, -43, +-94, 0, 128, 40, -104, -64, 66, 72, +1, -57, -47, 29, 82, 5, -48, -35, +-21, 48, 128, -42, -201, 17, 246, 15, +-223, -33, 148, 36, -5, -16, -138, -26, +264, 73, -301, -122, 290, 147, -209, -146, +106, 117, 15, -64, -86, -12, 119, 87, +-92, -156, 60, 207, -24, -227, 7, 217, +7, -181, 12, 118, -29, -45, 34, -22, +5, 69, -54, -84, 105, 64, -126, -13, +126, -48, -82, 98, 4, -117, 89, 99, +-156, -38, 178, -40, -147, 104, 104, -134, +-54, 120, 19, -57, -18, -25, 62, 103, +-114, -152, 139, 157, -101, -126, 24, 75, +76, -33, -156, 9, 190, -21, -140, 68, +-5, -124, 183, 179, -322, -215, 379, 211, +-330, -170, 187, 92, 21, 6, -229, -104, +360, 180, -380, -213, 304, 199, -184, -148, +63, 82, 20, -32, -39, 24, -26, -55, +121, 116, -196, -169, 204, 171, -148, -102, +46, -44, 87, 220, -209, -389, 275, 484, +-263, -472, 189, 347, -109, -140, 39, -79, +-15, 261, 26, -352, -93, 347, 172, -262, +-224, 139, 203, -28, -124, -46, 3, 73, +117, -70, -226, 63, 264, -68, -220, 93, +93, -121, 40, 135, -147, -115, 177, 66, +-155, 11, 50, -80, 72, 126, -181, -131, +199, 95, -141, -44, 22, -5, 93, 30, +-197, -33, 226, 28, -194, -33, 84, 64, +16, -124, -87, 191, 83, -245, -51, 253, +-32, -200, 107, 91, -176, 40, 158, -155, +-117, 228, 15, -221, 45, 150, -108, -43, +112, -61, -103, 122, 29, -123, 25, 63, +-93, 40, 88, -134, -100, 192, 65, -188, +-57, 132, -4, -33, 14, -58, -39, 101, +21, -84, -46, 2, 36, 102, -70, -179, +56, 201, -97, -149, 86, 45, -89, 74, +1, -159, 48, 201, -146, -179, 176, 106, +-229, -4, 185, -102, -142, 177, 20, -200, +19, 165, -70, -73, 2, -42, 52, 148, +-205, -196, 280, 181, -356, -92, 269, -45, +-159, 199, -65, -326, 206, 407, -360, -411, +350, 333, -298, -191, 104, 11, 30, 154, +-194, -260, 198, 292, -201, -253, 64, 174, +17, -92, -145, 37, 107, -8, -71, 9, +-97, -20, 177, 34, -292, -44, 247, 39, +-200, -21, 7, -10, 88, 56, -222, -86, +179, 94, -160, -69, 9, 21, 48, 22, +-157, -44, 97, 40, -74, -24, -72, 30, +96, -93, -151, 216, 39, -393, 31, 580, +-211, -733, 247, 791, -301, -720, 175, 497, +-115, -156, -48, -224, 54, 545, -111, -708, +-8, 669, 49, -435, -209, 94, 226, 238, +-303, -454, 209, 488, -173, -355, -12, 121, +80, 102, -210, -230, 143, 220, -135, -97, +-15, -53, 8, 139, -63, -102, -73, -26, +100, 158, -200, -193, 84, 67, -4, 177, +-224, -429, 259, 559, -310, -472, 114, 183, +15, 202, -257, -530, 271, 681, -288, -607, +65, 346, 71, 10, -316, -356, 343, 614, +-408, -725, 238, 692, -137, -538, -124, 320, +237, -115, -427, -20, 405, 46, -440, 44, +248, -188, -131, 331, -152, -426, 302, 445, +-553, -427, 616, 408, -770, -420, 735, 480, +-798, -570, 689, 635, -667, -639, 452, 545, +-332, -350, 39, 87, 116, 191, -392, -435, +491, 612, -701, -724, 751, 780, -927, -793, +916, 759, -968, -659, 759, 485, -597, -233, +229, -37, -20, 263, -244, -387, 256, 387, +-321, -295, 212, 172, -277, -60, 234, -8, +-339, 60, 250, -128, -219, 245, -43, -380, +186, 481, -407, -486, 347, 365, -283, -135, +-8, -134, 137, 340, -285, -412, 132, 322, +10, -126, -311, -82, 373, 182, -389, -85, +75, -226, 225, 693, -663, -1216, 864, 1661, +-1051, -1922, 951, 1950, -893, -1747, 661, 1380, +-560, -944, 329, 540, -233, -230, 15, 36, +44, 82, -170, -197, 105, 369, -121, -619, +0, 911, -42, -1155, 2, 1271, -113, -1218, +91, 1031, -151, -790, 41, 592, -31, -477, +-98, 426, 89, -363, -177, 196, 136, 109, +-191, -534, 107, 979, -104, -1330, -48, 1494, +86, -1425, -200, 1151, 129, -735, -106, 270, +-44, 169, 45, -537, -72, 814, -83, -1007, +145, 1139, -255, -1206, 142, 1197, -1, -1081, +-315, 821, 524, -416, -752, -81, 754, 568, +-732, -895, 518, 951, -343, -681, 44, 152, +184, 481, -515, -1017, 749, 1283, -1022, -1190, +1088, 762, -1054, -112, 725, -614, -297, 1268, +-306, -1742, 786, 1959, -1168, -1875, 1195, 1488, +-1026, -823, 570, -11, -110, 856, -386, -1506, +664, 1808, -840, -1689, 798, 1227, -733, -638, +594, 181, -601, -66, 666, 391, -956, -1055, +1314, 1826, -1790, -2405, 2127, 2556, -2307, -2192, +2109, 1410, -1638, -447, 841, -381, 3, 845, +-829, -859, 1383, 545, -1723, -145, 1780, -62, +-1746, -104, 1605, 635, -1504, -1326, 1326, 1864, +-1114, -1956, 724, 1470, -257, -495, -310, -670, +775, 1649, -1120, -2139, 1225, 2024, -1187, -1456, +1003, 755, -841, -262, 666, 182, -520, -475, +252, 872, 159, -1019, -788, 643, 1478, 269, +-2095, -1443, 2341, 2409, -2096, -2709, 1268, 2103, +-64, -704, -1253, -1057, 2273, 2576, -2760, -3337, +2553, 3096, -1794, -1982, 708, 420, 325, 1051, +-1073, -1981, 1356, 2166, -1228, -1675, 770, 785, +-185, 172, -409, -914, 856, 1293, -1096, -1278, +1026, 920, -633, -302, -96, -460, 1008, 1227, +-1905, -1817, 2483, 2039, -2536, -1776, 1981, 1025, +-985, 35, -157, -1087, 1027, 1800, -1366, -1942, +1092, 1501, -402, -698, -372, -108, 856, 585, +-855, -574, 374, 156, 338, 388, -963, -724, +1195, 636, -939, -136, 292, -537, 468, 1027, +-1030, -1044, 1156, 510, -817, 414, 143, -1349, +578, 1894, -1078, -1781, 1181, 1008, -892, 142, +361, -1231, 180, 1826, -537, -1709, 625, 966, +-524, 46, 392, -845, -409, 1065, 627, -617, +-948, -260, 1150, 1093, -1020, -1404, 439, 961, +473, 122, -1428, -1384, 2041, 2261, -2042, -2337, +1402, 1553, -378, -226, -621, -1082, 1197, 1856, +-1172, -1858, 666, 1222, -23, -363, -372, -245, +308, 312, 159, 133, -731, -793, 1068, 1269, +-954, -1274, 442, 773, 219, 12, -668, -757, +722, 1162, -397, -1114, -43, 709, 317, -183, +-212, -227, -203, 373, 722, -276, -1002, 64, +865, 91, -281, -82, -483, -112, 1142, 393, +-1386, -628, 1173, 691, -586, -535, -65, 193, +568, 201, -706, -520, 549, 654, -199, -568, +-101, 324, 254, -26, -185, -192, 31, 253, +152, -157, -186, -27, 108, 194, 88, -233, +-232, 110, 307, 143, -209, -422, 60, 603, +130, -591, -196, 380, 179, -32, -20, -323, +-95, 550, 175, -584, -59, 421, -116, -151, +349, -109, -408, 275, 317, -330, 41, 313, +-427, -309, 784, 370, -815, -496, 593, 610, +-81, -617, -374, 444, 678, -108, -546, -292, +151, 601, 453, -675, -846, 454, 974, 2, +-657, -520, 199, 911, 291, -1015, -430, 804, +304, -372, 149, -104, -515, 435, 744, -528, +-548, 398, 187, -173, 332, -8, -615, 60, +723, 11, -497, -89, 269, 46, 15, 163, +-64, -471, 93, 713, 24, -712, 5, 386, +23, 181, 52, -761, 55, 1097, -151, -1010, +404, 505, -450, 213, 404, -850, 4, 1147, +-432, -1012, 926, 539, -1045, 35, 939, -453, +-433, 569, -28, -395, 468, 78, -484, 181, +351, -247, 33, 103, -198, 160, 260, -383, +44, 455, -318, -326, 631, 61, -545, 218, +327, -416, 192, 480, -531, -432, 809, 338, +-668, -269, 463, 261, -45, -309, -128, 357, +279, -365, -123, 301, 57, -170, 117, 0, +-19, 162, -28, -278, 269, 322, -304, -287, +392, 182, -210, -42, 130, -89, 104, 157, +-115, -122, 208, -23, -78, 246, 95, -482, +42, 652, 5, -694, 113, 598, -83, -402, +262, 165, -280, 30, 432, -138, -327, 155, +291, -118, -1, 81, -127, -92, 349, 185, +-275, -343, 257, 532, -19, -683, 2, 739, +75, -649, 131, 417, -199, -80, 369, -271, +-215, 541, 84, -638, 277, 542, -377, -289, +452, -15, -123, 245, -151, -310, 560, 183, +-572, 71, 466, -324, 43, 456, -419, -379, +800, 107, -683, 260, 425, -570, 187, 682, +-564, -537, 873, 169, -670, 288, 377, -660, +193, 805, -482, -681, 722, 349, -546, 52, +398, -366, -46, 490, -45, -422, 188, 248, +-71, -70, 104, -23, 10, 20, 82, 37, +-4, -71, 73, 34, 66, 65, -36, -162, +126, 195, 41, -116, -108, -55, 358, 249, +-357, -380, 374, 393, -68, -273, -154, 65, +524, 154, -604, -305, 680, 346, -445, -271, +308, 124, -32, 39, 3, -150, 100, 181, +-1, -123, 89, 7, -70, 118, 256, -200, +-275, 217, 381, -163, -222, 69, 145, 24, +100, -85, -110, 109, 147, -112, 82, 137, +-198, -207, 411, 320, -338, -434, 256, 493, +93, -437, -317, 253, 620, 24, -625, -313, +619, 501, -333, -508, 123, 316, 226, 15, +-361, -360, 536, 576, -454, -571, 412, 350, +-157, -7, 26, -324, 230, 505, -299, -481, +439, 295, -385, -54, 412, -117, -276, 162, +251, -93, -80, -8, 19, 59, 176, -6, +-237, -124, 386, 250, -342, -283, 346, 163, +-148, 75, 25, -343, 222, 524, -301, -542, +422, 377, -327, -101, 263, -177, -31, 354, +-99, -378, 309, 270, -333, -105, 372, -36, +-207, 97, 91, -89, 148, 43, -235, -16, +337, 27, -223, -57, 125, 53, 105, 24, +-201, -167, 305, 328, -190, -442, 90, 432, +132, -290, -216, 64, 288, 168, -164, -306, +66, 301, 121, -164, -155, -36, 187, 204, +-56, -258, -27, 174, 172, 20, -179, -244, +203, 409, -92, -457, 45, 371, 81, -197, +-105, 4, 170, 145, -123, -200, 115, 171, +-5, -100, -25, 34, 89, -14, -9, 42, +-71, -100, 269, 142, -372, -137, 444, 74, +-303, 27, 111, -141, 200, 220, -387, -237, +483, 186, -323, -84, 76, -39, 276, 142, +-487, -194, 593, 177, -455, -109, 257, 22, +10, 40, -132, -36, 170, -47, -37, 192, +-90, -339, 221, 428, -187, -410, 89, 274, +136, -52, -316, -181, 473, 366, -473, -452, +422, 435, -253, -347, 116, 239, 42, -142, +-99, 74, 146, -24, -94, -25, 63, 77, +34, -136, -68, 166, 124, -153, -84, 76, +56, 31, 46, -139, -97, 202, 164, -204, +-140, 157, 108, -90, 1, 52, -59, -77, +138, 151, -125, -240, 121, 292, -48, -280, +26, 197, 26, -82, -12, -22, 34, 75, +-4, -83, 36, 47, -27, -12, 55, -4, +-19, 3, -8, 6, 105, -1, -174, -16, +273, 38, -289, -46, 295, 28, -210, 19, +137, -77, -14, 135, -56, -180, 152, 213, +-179, -246, 232, 273, -213, -293, 217, 281, +-145, -231, 89, 142, 16, -21, -71, -99, +137, 206, -127, -282, 120, 337, -59, -358, +34, 353, 10, -294, 2, 189, 21, -45, +-1, -108, 32, 229, -36, -272, 72, 252, +-68, -167, 93, 77, -75, -7, 91, -11, +-67, 4, 71, 13, -19, 6, -25, -51, +119, 128, -180, -172, 224, 199, -181, -155, +100, 98, 38, -17, -132, -20, 183, 44, +-109, -38, 0, 42, 150, -41, -224, 68, +233, -61, -134, 41, 23, 40, 90, -121, +-104, 193, 79, -177, 6, 84, -32, 98, +11, -268, 100, 399, -220, -385, 314, 281, +-300, -79, 211, -94, -50, 228, -89, -227, +166, 180, -138, -74, 60, 18, 38, 21, +-78, 17, 54, -42, 40, 86, -129, -72, +169, 69, -125, -3, 5, -45, 154, 141, +-289, -206, 351, 301, -321, -323, 215, 317, +-74, -204, -62, 82, 141, 91, -163, -178, +115, 227, -53, -135, -25, 22, 65, 154, +-99, -238, 93, 275, -96, -158, 59, 6, +-26, 227, -75, -368, 175, 466, -311, -398, +367, 296, -377, -114, 251, 26, -102, 18, +-79, 88, 137, -210, -134, 403, -26, -484, +164, 536, -308, -443, 279, 353, -199, -193, +-16, 129, 144, -61, -256, 103, 176, -98, +-105, 136, -57, -50, 55, -32, -43, 215, +-129, -312, 188, 388, -236, -269, 24, 99, +197, 201, -549, -371, 666, 457, -675, -279, +339, 11, 11, 369, -467, -578, 626, 654, +-691, -432, 421, 138, -219, 239, -82, -409, +100, 451, -144, -230, -38, 9, 41, 229, +-124, -234, -39, 114, 90, 219, -309, -510, +312, 790, -446, -821, 355, 740, -423, -441, +286, 164, -323, 146, 134, -262, -118, 309, +-116, -155, 130, 20, -324, 184, 242, -226, +-327, 247, 127, -94, -113, -7, -156, 137, +192, -57, -449, -88, 427, 424, -590, -687, +429, 932, -464, -888, 206, 717, -207, -324, +-3, 2, -118, 274, 23, -249, -218, 109, +109, 221, -212, -431, -40, 569, 66, -406, +-402, 132, 455, 339, -778, -734, 784, 1109, +-1031, -1220, 886, 1193, -893, -867, 437, 464, +-156, 80, -458, -461, 663, 718, -955, -617, +675, 355, -494, 100, -65, -404, 221, 564, +-480, -350, 182, 4, -45, 483, -431, -753, +458, 854, -604, -604, 238, 278, -119, 136, +-261, -323, 134, 380, -117, -155, -383, -100, +589, 443, -1025, -619, 946, 760, -1004, -700, +600, 642, -473, -468, 28, 383, 39, -234, +-396, 183, 385, -38, -666, -67, 564, 322, +-717, -576, 491, 951, -576, -1229, 363, 1503, +-523, -1567, 408, 1557, -638, -1335, 518, 1129, +-661, -871, 430, 770, -487, -691, 219, 740, +-263, -691, -24, 606, 14, -281, -331, -130, +321, 698, -584, -1146, 451, 1521, -554, -1591, +282, 1512, -288, -1204, 7, 901, -81, -543, +-71, 295, -152, -2, 130, -240, -424, 587, +411, -888, -639, 1187, 533, -1254, -694, 1139, +591, -705, -824, 164, 811, 466, -1073, -880, +957, 1086, -948, -918, 467, 549, -92, 14, +-628, -506, 1029, 935, -1540, -1102, 1558, 1103, +-1592, -814, 1132, 376, -768, 306, 59, -1039, +396, 1791, -1002, -2262, 1163, 2365, -1307, -1867, +902, 907, -473, 417, -353, -1673, 940, 2604, +-1597, -2859, 1712, 2512, -1724, -1644, 1246, 705, +-897, 16, 429, -172, -452, -178, 570, 941, +-1130, -1700, 1531, 2187, -1987, -2106, 1917, 1545, +-1712, -617, 1023, -263, -406, 876, -398, -996, +887, 769, -1449, -364, 1707, 179, -2091, -357, +2194, 995, -2359, -1794, 2124, 2468, -1852, -2587, +1189, 2074, -651, -942, 8, -369, 242, 1496, +-447, -2014, 322, 1902, -381, -1284, 419, 605, +-835, -189, 1179, 310, -1604, -814, 1539, 1433, +-1190, -1681, 241, 1333, 754, -292, -1833, -1071, +2358, 2348, -2479, -3007, 1883, 2854, -1073, -1881, +-5, 486, 780, 939, -1405, -1920, 1526, 2303, +-1512, -2031, 1134, 1343, -767, -421, 164, -463, +340, 1194, -948, -1616, 1240, 1719, -1366, -1415, +968, 797, -387, 55, -444, -853, 936, 1385, +-1099, -1379, 545, 836, 344, 138, -1519, -1165, +2328, 1910, -2703, -2053, 2279, 1577, -1427, -631, +225, -403, 712, 1193, -1332, -1456, 1280, 1208, +-886, -589, 169, -74, 357, 535, -673, -607, +466, 366, -33, 44, -635, -333, 1051, 362, +-1224, -47, 876, -440, -321, 883, -395, -992, +806, 665, -923, 73, 549, -920, -46, 1559, +-510, -1641, 696, 1112, -614, -91, 199, -1010, +152, 1798, -386, -1945, 259, 1471, -38, -611, +-201, -168, 67, 531, 356, -300, -1062, -326, +1582, 1004, -1731, -1287, 1214, 993, -270, -172, +-866, -814, 1656, 1567, -1918, -1761, 1523, 1370, +-821, -575, 72, -251, 317, 853, -383, -1067, +180, 1005, -76, -820, 188, 712, -601, -728, +1048, 826, -1332, -859, 1196, 749, -734, -460, +91, 97, 362, 257, -493, -485, 243, 592, +131, -601, -397, 596, 288, -579, 152, 569, +-781, -513, 1272, 394, -1426, -197, 1123, -14, +-524, 217, -169, -358, 681, 449, -899, -497, +797, 534, -523, -541, 212, 508, 3, -400, +-102, 231, 120, -48, -123, -81, 160, 102, +-216, -18, 263, -111, -238, 171, 131, -90, +50, -150, -233, 454, 374, -680, -401, 670, +344, -394, -209, -99, 87, 608, -18, -932, +67, 914, -163, -574, 280, 28, -271, 467, +119, -741, 206, 678, -545, -359, 788, -74, +-708, 396, 329, -528, 302, 432, -881, -249, +1217, 72, -1060, -40, 539, 114, 200, -260, +-747, 324, 920, -276, -574, 79, -13, 136, +648, -309, -928, 319, 836, -211, -380, 9, +-76, 129, 402, -188, -332, 100, 87, 17, +255, -133, -358, 140, 258, -118, 120, 70, +-421, -147, 649, 305, -566, -550, 416, 666, +-192, -596, 185, 213, -198, 314, 344, -871, +-241, 1133, 33, -1053, 409, 560, -689, 65, +843, -652, -519, 880, 86, -764, 476, 297, +-650, 201, 532, -603, 67, 682, -603, -547, +1094, 211, -1039, 72, 730, -295, -77, 311, +-332, -296, 638, 202, -427, -216, 233, 216, +78, -297, 12, 290, -179, -298, 661, 201, +-806, -156, 869, 54, -390, -36, -101, -52, +762, 89, -943, -225, 1030, 283, -586, -373, +283, 322, 146, -276, -146, 123, 191, -47, +99, -57, -34, 47, 92, -102, 233, 106, +-329, -219, 559, 275, -301, -368, 177, 297, +314, -201, -417, -36, 576, 191, -236, -325, +72, 235, 412, -84, -398, -231, 516, 456, +-177, -677, 112, 685, 196, -649, -5, 433, +89, -264, 210, 10, -85, 114, 173, -261, +155, 252, -86, -276, 314, 193, -14, -232, +21, 260, 279, -453, -90, 599, 135, -776, +301, 719, -235, -559, 389, 145, 45, 228, +-214, -589, 706, 646, -538, -553, 524, 220, +126, 12, -379, -168, 819, -4, -532, 265, +383, -636, 344, 761, -508, -705, 819, 296, +-404, 151, 191, -633, 476, 800, -509, -780, +764, 444, -358, -115, 289, -240, 137, 343, +4, -381, 203, 230, 106, -160, 97, 50, +46, -80, 276, 36, -147, -53, 374, -70, +-13, 134, 57, -258, 316, 221, -158, -183, +281, -8, 119, 123, -39, -278, 324, 259, +-6, -235, -6, 50, 446, 84, -377, -294, +598, 363, -191, -426, 129, 294, 371, -153, +-404, -122, 728, 287, -506, -432, 643, 351, +-285, -215, 321, -71, 46, 243, -25, -388, +404, 304, -323, -196, 618, -8, -420, 52, +530, -46, -215, -152, 273, 296, 38, -443, +125, 379, 68, -271, 146, 44, -13, 50, +220, -90, -32, -72, 213, 208, 23, -356, +76, 277, 205, -113, -179, -210, 493, 420, +-389, -538, 555, 378, -247, -126, 160, -225, +289, 398, -374, -457, 689, 260, -510, -27, +525, -248, -140, 348, 37, -389, 307, 286, +-256, -248, 438, 201, -242, -265, 315, 267, +-111, -254, 172, 81, 49, 110, -2, -347, +267, 427, -249, -410, 464, 189, -355, 33, +409, -280, -103, 361, 8, -372, 357, 249, +-417, -173, 603, 77, -430, -85, 372, 62, +-3, -65, -119, -31, 395, 103, -330, -212, +347, 193, -74, -118, 5, -75, 221, 234, +-144, -358, 157, 324, 61, -225, -79, 36, +216, 77, -60, -135, 27, 43, 205, 68, +-235, -208, 356, 231, -232, -195, 227, 51, +-31, 66, 19, -179, 109, 175, -59, -127, +123, -8, -7, 124, 22, -261, 127, 335, +-137, -406, 243, 403, -174, -378, 177, 267, +-7, -137, -39, -42, 164, 180, -118, -302, +124, 341, -13, -351, 59, 296, -44, -266, +175, 213, -211, -164, 257, 66, -96, 40, +-69, -192, 355, 308, -488, -385, 561, 350, +-396, -244, 184, 61, 144, 88, -331, -195, +479, 184, -431, -118, 360, 13, -214, 30, +169, -9, -124, -111, 189, 242, -212, -344, +241, 331, -159, -216, 52, -1, 140, 222, +-291, -402, 440, 471, -481, -465, 473, 387, +-362, -329, 238, 293, -78, -313, -35, 337, +119, -345, -136, 284, 114, -176, -43, 23, +-26, 102, 96, -177, -135, 159, 146, -89, +-124, -23, 72, 108, -8, -150, -67, 126, +119, -64, -159, -19, 144, 75, -107, -107, +24, 93, 53, -74, -126, 42, 124, -31, +-95, 32, -13, -58, 108, 84, -211, -120, +234, 131, -219, -144, 118, 114, -31, -70, +-93, -4, 146, 78, -203, -153, 184, 189, +-205, -187, 165, 137, -181, -64, 137, -30, +-131, 103, 36, -162, 21, 198, -167, -229, +242, 262, -357, -321, 369, 374, -401, -418, +319, 403, -277, -323, 139, 157, -66, 56, +-69, -290, 111, 463, -196, -549, 164, 501, +-176, -355, 81, 146, -69, 53, -4, -195, +-41, 241, 33, -213, -125, 138, 98, -57, +-119, 11, -7, -1, 78, 8, -223, -21, +218, 13, -213, 8, 37, -36, 85, 41, +-269, -23, 269, -20, -252, 62, 66, -90, +55, 77, -208, -40, 170, -7, -121, 23, +-85, 2, 180, -55, -300, 105, 241, -110, +-207, 49, 73, 63, -65, -183, 15, 249, +-87, -222, 52, 104, -49, 54, -105, -182, +204, 224, -357, -165, 354, 38, -344, 99, +183, -185, -102, 194, -31, -139, 19, 67, +-46, -16, -8, 31, -48, -86, 71, 163, +-198, -213, 206, 220, -227, -175, 85, 106, +41, -20, -226, -56, 291, 135, -330, -218, +216, 321, -150, -409, 24, 456, -20, -413, +-3, 269, -38, -41, 3, -192, 26, 359, +-132, -382, 143, 261, -153, -36, 1, -190, +148, 326, -321, -308, 361, 157, -287, 79, +33, -282, 205, 410, -468, -402, 516, 315, +-464, -185, 251, 109, -51, -99, -103, 178, +100, -272, -43, 345, -115, -318, 160, 205, +-166, -23, 47, -153, 74, 284, -165, -308, +143, 270, -71, -176, -84, 110, 128, -86, +-140, 138, -1, -219, 170, 326, -321, -395, +379, 442, -342, -433, 184, 404, -66, -349, +-73, 306, 81, -249, -50, 198, 0, -102, +22, -25, 12, 212, -116, -389, 161, 515, +-204, -487, 84, 306, 75, 33, -276, -366, +413, 603, -422, -590, 267, 359, -56, 37, +-239, -402, 391, 621, -473, -584, 416, 362, +-282, -39, 164, -213, -107, 348, 67, -298, +-125, 167, 88, 0, -66, -84, -42, 96, +162, 8, -238, -142, 256, 299, -238, -388, +130, 415, -117, -318, 67, 162, -96, 51, +120, -222, -105, 350, 50, -368, 29, 343, +-168, -260, 192, 211, -233, -166, 130, 161, +7, -118, -160, 56, 323, 62, -440, -166, +446, 258, -445, -264, 276, 240, -147, -176, +2, 156, 62, -184, 4, 308, -175, -444, +368, 590, -588, -639, 589, 624, -513, -485, +240, 305, 76, -62, -354, -176, 557, 445, +-675, -691, 686, 935, -763, -1081, 749, 1117, +-759, -966, 642, 674, -390, -276, 53, -68, +294, 280, -545, -268, 511, 105, -350, 138, +-13, -259, 297, 197, -416, 93, 339, -468, +-106, 804, -161, -906, 248, 763, -236, -411, +22, 36, 146, 214, -202, -211, 85, -5, +195, 356, -512, -659, 694, 842, -778, -838, +616, 738, -418, -599, 173, 526, 24, -484, +-167, 483, 300, -422, -486, 326, 624, -167, +-819, 51, 858, 1, -817, 67, 650, -191, +-416, 346, 221, -432, -131, 443, 99, -342, +-228, 205, 289, -19, -359, -147, 317, 327, +-190, -495, 35, 683, 95, -842, -204, 994, +170, -1078, -140, 1111, 5, -1055, 98, 949, +-173, -782, 210, 593, -199, -354, 136, 99, +-119, 210, 44, -537, -46, 884, -2, -1166, +57, 1341, -136, -1313, 229, 1080, -299, -642, +262, 95, -196, 468, 0, -912, 134, 1192, +-221, -1242, 175, 1106, 8, -791, -290, 380, +554, 93, -809, -523, 865, 860, -830, -976, +612, 830, -298, -387, -95, -229, 493, 878, +-850, -1313, 1015, 1378, -1011, -975, 697, 194, +-196, 763, -437, -1610, 1027, 2107, -1414, -2102, +1482, 1648, -1289, -881, 845, 78, -420, 539, +76, -787, 14, 649, 110, -200, -360, -350, +586, 778, -674, -874, 486, 548, -105, 161, +-486, -1053, 1103, 1862, -1667, -2341, 2085, 2380, +-2346, -2025, 2436, 1520, -2445, -1126, 2312, 1056, +-2123, -1302, 1760, 1672, -1254, -1827, 570, 1498, +212, -593, -1004, -686, 1617, 1963, -2008, -2785, +2041, 2885, -1852, -2254, 1493, 1194, -1121, -149, +810, -495, -564, 595, 275, -295, 115, -45, +-719, 58, 1397, 445, -2045, -1342, 2407, 2275, +-2337, -2805, 1785, 2645, -903, -1760, -138, 427, +1029, 948, -1677, -1956, 1952, 2382, -1935, -2202, +1647, 1577, -1157, -708, 477, -201, 311, 1002, +-1126, -1560, 1717, 1755, -1939, -1498, 1614, 806, +-821, 170, -210, -1137, 1103, 1775, -1548, -1818, +1341, 1218, -600, -156, -443, -1019, 1373, 1909, +-1884, -2223, 1807, 1862, -1195, -924, 229, -303, +781, 1475, -1606, -2247, 2013, 2399, -1965, -1893, +1486, 909, -768, 219, 43, -1083, 423, 1403, +-479, -1121, 108, 449, 472, 226, -992, -530, +1138, 300, -821, 348, 143, -1028, 580, 1328, +-1006, -1005, 911, 147, -384, 870, -325, -1532, +812, 1472, -841, -636, 398, -642, 256, 1825, +-763, -2402, 847, 2131, -510, -1160, -26, -65, +387, 1020, -342, -1339, -107, 1005, 673, -298, +-976, -328, 739, 527, 14, -214, -982, -411, +1703, 972, -1849, -1144, 1348, 817, -447, -138, +-426, -600, 917, 1114, -922, -1267, 593, 1117, +-263, -833, 193, 574, -439, -408, 830, 287, +-1062, -123, 904, -131, -355, 466, -392, -792, +1013, 1024, -1269, -1112, 1100, 1078, -672, -947, +237, 768, -30, -545, 126, 282, -427, 2, +731, -248, -853, 411, 694, -456, -282, 418, +-263, -365, 787, 378, -1149, -478, 1272, 607, +-1137, -652, 788, 517, -323, -182, -114, -262, +403, 649, -458, -817, 306, 685, -44, -311, +-166, -149, 223, 491, -88, -588, -127, 417, +289, -98, -286, -175, 113, 235, 121, -24, +-247, -374, 174, 749, 89, -873, -384, 598, +545, 37, -472, -821, 223, 1436, 43, -1625, +-129, 1284, -41, -541, 381, -297, -678, 902, +729, -1058, -466, 775, 10, -253, 379, -214, +-477, 415, 225, -323, 251, 69, -637, 101, +698, -25, -355, -299, -237, 710, 773, -977, +-972, 924, 737, -547, -183, 6, -393, 455, +734, -638, -713, 495, 418, -147, -69, -201, +-122, 365, 85, -295, 108, 77, -271, 115, +290, -148, -139, -13, -57, 264, 134, -430, +-24, 377, -212, -89, 386, -305, -316, 609, +-37, -652, 562, 373, -975, 116, 1028, -614, +-639, 914, -52, -906, 736, 614, -1078, -181, +923, -210, -335, 420, -396, -402, 925, 210, +-1022, 47, 668, -263, -66, 379, -479, -396, +757, 330, -675, -236, 367, 132, -38, -44, +-122, -21, 47, 45, 180, -18, -399, -46, +456, 125, -272, -174, -78, 142, 472, -32, +-730, -144, 763, 307, -571, -389, 258, 333, +51, -158, -218, -83, 230, 293, -116, -413, +-7, 422, 47, -366, 43, 310, -218, -309, +389, 365, -442, -441, 347, 473, -134, -420, +-81, 279, 184, -88, -127, -91, -24, 194, +174, -222, -183, 181, 24, -106, 259, 23, +-515, 53, 614, -118, -478, 145, 185, -132, +134, 54, -305, 78, 261, -234, -14, 354, +-272, -418, 468, 404, -460, -365, 285, 344, +-41, -386, -105, 463, 98, -523, 74, 461, +-271, -235, 371, -134, -277, 540, 26, -843, +283, 915, -463, -749, 433, 430, -181, -122, +-142, -27, 377, -55, -365, 300, 111, -566, +297, 666, -640, -507, 773, 102, -603, 395, +231, -798, 190, 941, -463, -777, 510, 361, +-331, 138, 66, -564, 170, 792, -264, -802, +255, 629, -184, -386, 168, 143, -221, 32, +321, -136, -375, 196, 319, -244, -104, 295, +-185, -348, 463, 370, -601, -327, 560, 193, +-339, 8, 59, -242, 186, 431, -279, -514, +221, 448, -37, -259, -149, -7, 262, 244, +-239, -384, 114, 378, 61, -258, -178, 80, +210, 52, -131, -82, 1, -12, 138, 174, +-216, -343, 252, 410, -249, -332, 252, 107, +-236, 188, 202, -452, -114, 604, -33, -588, +215, 433, -354, -230, 416, 72, -355, -24, +227, 80, -61, -174, -61, 202, 136, -106, +-159, -116, 176, 366, -191, -518, 198, 460, +-146, -178, 22, -246, 173, 634, -361, -830, +448, 737, -363, -395, 104, -62, 245, 455, +-556, -643, 720, 576, -661, -337, 420, 46, +-90, 165, -200, -240, 364, 202, -362, -123, +253, 74, -75, -85, -63, 123, 159, -127, +-180, 49, 189, 106, -181, -287, 212, 394, +-222, -374, 230, 199, -153, 59, 24, -322, +164, 492, -362, -516, 509, 403, -574, -207, +522, -11, -376, 187, 142, -305, 105, 367, +-351, -396, 502, 408, -584, -393, 526, 345, +-401, -243, 213, 90, -41, 83, -84, -233, +130, 315, -115, -304, 86, 197, -64, -37, +100, -129, -137, 250, 200, -293, -183, 265, +147, -186, -26, 99, -61, -40, 162, 23, +-173, -36, 171, 55, -101, -37, 47, -34, +46, 147, -128, -264, 208, 335, -255, -319, +223, 193, -116, 14, -97, -263, 302, 492, +-489, -658, 509, 720, -431, -684, 182, 562, +33, -382, -240, 180, 277, 0, -239, -136, +108, 214, -25, -249, 4, 268, -79, -305, +205, 362, -296, -425, 338, 448, -245, -392, +126, 257, 76, -75, -178, -78, 275, 149, +-222, -106, 178, -3, -39, 112, -14, -146, +104, 76, -99, 63, 121, -185, -111, 203, +150, -77, -233, -165, 347, 438, -488, -651, +563, 717, -604, -627, 478, 418, -328, -166, +36, -56, 160, 211, -384, -294, 431, 323, +-470, -332, 361, 345, -290, -350, 156, 333, +-69, -285, -21, 195, 64, -97, -50, 25, +6, -34, 136, 120, -242, -261, 389, 396, +-371, -468, 344, 427, -126, -292, -32, 104, +251, 76, -292, -187, 312, 223, -166, -188, +52, 122, 90, -43, -139, -35, 152, 106, +-128, -168, 86, 211, -93, -214, 70, 167, +-122, -69, 77, -42, -100, 130, 2, -159, +11, 113, -132, -5, 130, -116, -187, 210, +112, -246, -64, 217, -77, -151, 165, 90, +-254, -72, 269, 108, -212, -189, 123, 273, +27, -305, -109, 248, 216, -94, -208, -109, +250, 298, -183, -404, 210, 395, -134, -297, +154, 164, -79, -71, 87, 50, -43, -91, +76, 140, -84, -147, 100, 88, -81, 24, +-1, -134, 77, 201, -182, -192, 165, 119, +-121, -27, -76, -52, 207, 82, -368, -60, +321, 5, -237, 54, 1, -100, 145, 115, +-265, -109, 201, 99, -85, -96, -94, 115, +213, -130, -241, 109, 212, -37, -120, -89, +86, 225, -31, -313, 69, 282, -27, -130, +23, -100, 86, 313, -124, -411, 196, 343, +-138, -135, 77, -111, 62, 273, -136, -280, +173, 137, -127, 82, 32, -254, 52, 304, +-115, -219, 83, 60, -40, 76, -65, -115, +91, 35, -118, 115, 18, -245, 61, 282, +-195, -198, 218, 32, -201, 136, 67, -238, +66, 228, -186, -124, 189, -20, -92, 144, +-76, -194, 237, 158, -281, -62, 214, -57, +-17, 150, -166, -172, 303, 117, -256, -15, +120, -77, 102, 92, -213, -4, 211, -172, +-40, 377, -168, -514, 341, 521, -349, -390, +205, 175, 25, 42, -229, -185, 296, 227, +-233, -188, 66, 125, 69, -100, -127, 140, +27, -228, 131, 326, -314, -388, 382, 387, +-343, -317, 183, 194, 0, -55, -158, -76, +216, 178, -188, -255, 109, 305, -34, -344, +12, 373, -59, -365, 153, 308, -224, -193, +245, 28, -179, 163, 52, -319, 110, 394, +-218, -388, 274, 301, -239, -197, 177, 117, +-119, -92, 101, 136, -125, -212, 164, 274, +-174, -281, 124, 205, -21, -49, -116, -142, +229, 314, -285, -410, 261, 391, -169, -266, +31, 74, 100, 129, -195, -291, 230, 380, +-215, -386, 165, 328, -117, -218, 96, 75, +-113, 95, 151, -269, -185, 426, 197, -540, +-185, 587, 145, -525, -121, 367, 115, -125, +-132, -146, 152, 364, -146, -462, 89, 402, +9, -214, -121, -22, 217, 177, -263, -183, +242, 40, -181, 170, 95, -316, -26, 316, +-16, -170, 38, -28, -57, 137, 106, -69, +-185, -181, 291, 492, -381, -710, 413, 711, +-356, -452, 211, 13, -10, 470, -181, -839, +313, 986, -353, -863, 296, 527, -168, -81, +18, -338, 108, 617, -164, -705, 145, 601, +-50, -390, -82, 165, 205, -20, -284, 0, +278, -91, -207, 249, 81, -409, 31, 532, +-111, -590, 131, 579, -119, -505, 86, 382, +-67, -229, 44, 76, -1, 55, -98, -152, +247, 240, -426, -347, 595, 513, -721, -744, +815, 1008, -879, -1252, 960, 1387, -1030, -1351, +1070, 1109, -997, -682, 794, 148, -458, 360, +99, -706, 180, 787, -262, -596, 139, 227, +109, 156, -338, -377, 411, 338, -276, -73, +-19, -270, 315, 502, -474, -483, 393, 197, +-115, 230, -236, -619, 470, 810, -489, -746, +273, 490, 46, -196, -308, 18, 362, -44, +-188, 263, -137, -561, 442, 808, -579, -883, +485, 750, -205, -445, -139, 77, 435, 243, +-605, -430, 683, 466, -705, -383, 760, 236, +-825, -87, 871, -24, -812, 95, 620, -128, +-311, 148, -30, -156, 308, 156, -457, -136, +462, 85, -369, 10, 228, -163, -92, 369, +-31, -620, 120, 887, -204, -1120, 252, 1268, +-281, -1281, 262, 1152, -230, -904, 185, 597, +-172, -294, 174, 50, -187, 130, 163, -265, +-96, 418, -26, -611, 162, 868, -266, -1147, +314, 1380, -283, -1499, 228, 1434, -161, -1174, +122, 755, -100, -234, 100, -307, -96, 798, +114, -1174, -168, 1392, 290, -1413, -475, 1233, +689, -867, -859, 371, 912, 174, -817, -666, +573, 1023, -260, -1172, -69, 1094, 340, -800, +-562, 351, 739, 161, -917, -621, 1075, 905, +-1179, -922, 1125, 640, -856, -97, 363, -610, +269, 1324, -902, -1872, 1365, 2111, -1523, -1970, +1372, 1427, -968, -578, 448, -402, 62, 1290, +-462, -1868, 727, 2008, -867, -1716, 937, 1156, +-975, -602, 1046, 318, -1176, -483, 1405, 1089, +-1742, -1924, 2147, 2679, -2521, -3044, 2733, 2842, +-2653, -2113, 2219, 1083, -1486, -77, 579, -614, +307, 871, -1051, -787, 1580, 638, -1944, -715, +2194, 1192, -2383, -1989, 2466, 2785, -2356, -3170, +1962, 2824, -1287, -1711, 439, 136, 381, 1382, +-981, -2350, 1273, 2514, -1306, -2005, 1239, 1245, +-1247, -713, 1393, 720, -1591, -1200, 1637, 1795, +-1320, -2020, 562, 1548, 530, -381, -1665, -1142, +2509, 2502, -2808, -3241, 2507, 3145, -1741, -2303, +750, 1035, 220, 280, -1010, -1337, 1561, 1968, +-1858, -2131, 1885, 1853, -1596, -1201, 975, 271, +-90, 765, -863, -1657, 1583, 2136, -1795, -2005, +1382, 1237, -467, -53, -601, -1159, 1392, 1963, +-1567, -2068, 1050, 1431, -25, -297, -1125, -915, +2004, 1779, -2353, -2021, 2118, 1616, -1450, -757, +596, -232, 177, 1045, -699, -1456, 878, 1402, +-733, -969, 353, 354, 96, 206, -424, -517, +461, 498, -151, -221, -411, -116, 984, 263, +-1282, -64, 1108, -445, -487, 1020, -327, -1314, +953, 1063, -1094, -236, 684, -885, 57, 1828, +-723, -2163, 978, 1709, -715, -653, 137, -537, +379, 1351, -494, -1493, 143, 1013, 434, -256, +-825, -323, 691, 438, 11, -93, -978, -428, +1708, 756, -1791, -640, 1127, 84, -1, 661, +-1088, -1253, 1674, 1442, -1595, -1192, 1029, 670, +-393, -120, 46, -267, -120, 461, 436, -564, +-649, 700, 491, -936, 59, 1194, -744, -1338, +1197, 1233, -1171, -854, 674, 321, 16, 179, +-517, -496, 586, 587, -249, -530, -232, 476, +508, -509, -373, 629, -131, -714, 726, 659, +-1100, -405, 1066, 26, -668, 328, 134, -510, +283, 475, -450, -303, 416, 143, -349, -117, +392, 234, -568, -389, 746, 427, -768, -247, +530, -113, -92, 480, -363, -654, 629, 503, +-595, -83, 314, -421, 50, 744, -318, -717, +390, 344, -297, 191, 143, -606, -41, 679, +33, -345, -93, -249, 168, 832, -221, -1120, +262, 966, -305, -414, 356, -328, -348, 968, +221, -1286, 58, 1193, -413, -774, 689, 215, +-717, 282, 416, -572, 103, 646, -596, -573, +789, 455, -533, -364, -90, 294, 806, -211, +-1244, 42, 1191, 191, -644, -440, -149, 601, +812, -586, -1080, 394, 900, -117, -453, -115, +27, 195, 149, -116, -41, -20, -205, 70, +376, 56, -331, -331, 102, 597, 139, -650, +-221, 380, 101, 146, 98, -695, -166, 993, +-50, -861, 517, 339, -992, 327, 1178, -816, +-876, 888, 164, -529, 641, -61, -1125, 583, +1034, -813, -396, 696, -468, -344, 1090, -20, +-1149, 246, 591, -280, 306, 210, -1120, -151, +1486, 184, -1306, -276, 732, 344, -114, -277, +-276, 63, 318, 233, -125, -476, -72, 540, +78, -387, 157, 78, -507, 227, 782, -386, +-822, 312, 599, -46, -235, -258, -105, 421, +294, -330, -321, 9, 266, 395, -243, -680, +311, 706, -443, -471, 560, 99, -556, 205, +402, -296, -140, 154, -116, 95, 269, -277, +-272, 267, 151, -57, 7, -238, -98, 454, +57, -479, 121, 310, -372, -40, 591, -196, +-665, 287, 551, -225, -263, 49, -95, 166, +361, -345, -414, 459, 218, -506, 136, 490, +-477, -409, 605, 273, -452, -84, 63, -117, +360, 282, -602, -380, 534, 410, -211, -402, +-183, 411, 412, -480, -335, 595, -12, -693, +432, 691, -680, -524, 607, 194, -223, 203, +-275, -532, 638, 670, -680, -574, 392, 313, +82, -38, -492, -104, 656, 32, -508, 203, +160, -455, 201, 556, -386, -406, 322, 36, +-62, 410, -244, -743, 438, 834, -436, -671, +282, 338, -82, 9, -34, -258, 2, 372, +129, -394, -242, 387, 214, -406, -6, 434, +-325, -416, 623, 295, -742, -69, 610, -207, +-291, 436, -55, -537, 259, 474, -242, -264, +36, -14, 218, 276, -359, -455, 297, 525, +-47, -490, -258, 359, 487, -162, -546, -62, +438, 279, -239, -427, 51, 466, 77, -378, +-142, 193, 192, 28, -263, -198, 364, 246, +-444, -161, 454, -19, -350, 192, 160, -268, +32, 210, -150, -34, 142, -180, -18, 322, +-150, -328, 261, 197, -257, -3, 114, -141, +89, 168, -273, -69, 356, -90, -317, 191, +195, -161, -68, -5, -3, 218, 1, -349, +26, 300, -5, -63, -115, -258, 312, 512, +-496, -564, 550, 378, -406, -21, 92, -359, +283, 610, -547, -657, 592, 521, -401, -289, +77, 75, 224, 66, -370, -143, 330, 217, +-173, -343, 27, 521, 8, -680, 74, 727, +-196, -590, 238, 279, -123, 109, -126, -447, +412, 604, -596, -547, 596, 312, -403, -18, +103, -241, 195, 404, -418, -478, 535, 518, +-584, -558, 593, 591, -569, -574, 480, 447, +-290, -193, 10, -151, 313, 468, -570, -649, +677, 611, -586, -377, 352, 39, -78, 272, +-120, -441, 190, 424, -138, -272, 52, 80, +-8, 46, 52, -40, -172, -61, 289, 194, +-332, -255, 261, 182, -89, 12, -115, -257, +270, 453, -322, -515, 257, 412, -98, -191, +-103, -63, 284, 268, -423, -359, 474, 359, +-443, -304, 329, 248, -153, -224, -46, 208, +222, -155, -336, 19, 369, 206, -339, -472, +280, 699, -237, -814, 242, 778, -288, -619, +346, 409, -368, -226, 327, 116, -224, -60, +81, 22, 57, 52, -160, -162, 206, 286, +-206, -351, 169, 326, -103, -212, 19, 58, +81, 72, -194, -132, 306, 134, -406, -122, +473, 163, -492, -280, 465, 432, -394, -529, +271, 497, -116, -290, -71, -33, 257, 372, +-414, -604, 507, 662, -525, -552, 475, 348, +-375, -153, 247, 49, -125, -33, 15, 67, +79, -93, -148, 69, 178, -8, -161, -39, +91, 22, 15, 69, -126, -198, 191, 298, +-180, -312, 105, 213, 5, -41, -84, -138, +100, 254, -34, -277, -61, 218, 151, -133, +-167, 58, 121, -24, -29, 1, -51, 40, +76, -123, -52, 230, -14, -302, 41, 289, +-28, -155, -55, -59, 148, 279, -218, -402, +233, 370, -172, -205, 92, -22, -5, 212, +-40, -282, 70, 228, -86, -96, 123, -28, +-168, 81, 191, -56, -167, -4, 38, 33, +135, 28, -349, -176, 474, 373, -506, -531, +403, 582, -214, -506, 19, 332, 134, -125, +-156, -59, 124, 171, -17, -219, -32, 228, +53, -246, 11, 283, -100, -330, 167, 362, +-216, -339, 182, 256, -146, -132, 43, 8, +33, 74, -140, -99, 220, 62, -275, 4, +280, -60, -189, 76, 90, -49, 54, -8, +-88, 78, 79, -138, 64, 165, -224, -150, +360, 109, -424, -50, 348, -3, -241, 47, +33, -78, 109, 106, -279, -142, 348, 182, +-394, -208, 360, 198, -253, -133, 135, 25, +37, 102, -100, -198, 174, 226, -128, -167, +115, 67, -80, 26, 101, -59, -157, 9, +169, 94, -198, -197, 90, 243, -37, -185, +-112, 54, 155, 110, -201, -241, 183, 290, +-124, -254, 92, 162, 16, -73, -35, 29, +143, -47, -127, 100, 149, -142, -60, 127, +-42, -35, 135, -106, -227, 246, 166, -319, +-121, 293, -68, -178, 133, 23, -210, 98, +137, -136, -39, 66, -38, 83, 88, -251, +38, 358, -116, -354, 276, 233, -221, -26, +140, -201, 97, 368, -284, -430, 375, 365, +-377, -217, 201, 49, -115, 79, -22, -141, +-71, 159, 140, -185, -297, 272, 342, -430, +-277, 618, 171, -758, 36, 769, -79, -615, +139, 344, 15, -47, -71, -177, 134, 258, +-21, -206, -201, 80, 408, 14, -596, -3, +487, -138, -299, 354, -132, -553, 420, 648, +-632, -589, 588, 393, -390, -138, 194, -77, +-2, 169, 70, -122, -122, -30, 318, 210, +-310, -330, 258, 325, -52, -186, -171, -51, +280, 325, -348, -555, 190, 685, -99, -679, +-106, 546, 136, -335, -169, 114, 96, 38, +-23, -60, 5, -32, 30, 202, 92, -361, +-115, 430, 250, -384, -214, 244, 194, -91, +-62, 1, -94, -6, 205, 77, -339, -153, +303, 177, -328, -130, 209, 56, -223, -21, +220, 76, -347, -230, 528, 435, -696, -622, +894, 730, -918, -741, 945, 703, -762, -661, +617, 640, -364, -613, 141, 514, 110, -276, +-408, -123, 642, 603, -923, -1015, 972, 1198, +-944, -1052, 622, 602, -233, -28, -199, -453, +493, 635, -524, -473, 395, 72, -56, 341, +-149, -536, 297, 413, -161, -23, -31, -435, +237, 755, -291, -786, 114, 551, 146, -178, +-502, -150, 639, 299, -678, -221, 448, -29, +-176, 348, -137, -676, 393, 972, -556, -1239, +740, 1477, -821, -1685, 961, 1798, -940, -1765, +878, 1578, -632, -1270, 335, 920, -47, -619, +-171, 432, 172, -331, -104, 251, -134, -86, +266, -219, -369, 673, 291, -1178, -125, 1588, +-82, -1800, 286, 1775, -339, -1575, 373, 1299, +-250, -1095, 207, 971, -123, -902, 152, 758, +-196, -453, 231, -70, -238, 723, 111, -1335, +-11, 1752, -159, -1839, 137, 1608, -37, -1105, +-245, 506, 560, 82, -802, -575, 918, 940, +-769, -1172, 520, 1286, -110, -1263, -206, 1019, +523, -565, -726, -99, 909, 843, -1084, -1527, +1188, 1900, -1243, -1838, 1027, 1336, -674, -489, +51, -455, 548, 1267, -1085, -1680, 1341, 1677, +-1277, -1225, 962, 457, -397, 496, -155, -1451, +763, 2257, -1179, -2808, 1518, 2915, -1621, -2573, +1569, 1757, -1334, -703, 932, -403, -539, 1188, +136, -1451, 18, 1152, -49, -446, -170, -315, +375, 821, -484, -719, 322, 83, 209, 946, +-940, -1958, 1839, 2638, -2502, -2739, 2934, 2319, +-2884, -1693, 2539, 1128, -1939, -919, 1247, 1010, +-589, -1249, -119, 1184, 744, -654, -1447, -365, +1958, 1579, -2338, -2536, 2332, 2874, -2033, -2408, +1488, 1492, -871, -425, 428, -267, -96, 464, +-16, -205, 260, -86, -601, 53, 1233, 431, +-1928, -1317, 2493, 2184, -2678, -2730, 2263, 2580, +-1421, -1892, 207, 787, 899, 361, -1827, -1299, +2269, 1878, -2355, -2043, 2101, 1921, -1592, -1400, +952, 652, -111, 323, -672, -1232, 1409, 1920, +-1717, -2048, 1623, 1537, -1016, -605, 192, -468, +519, 1189, -865, -1382, 613, 859, -21, -27, +-800, -868, 1358, 1457, -1623, -1631, 1439, 1385, +-972, -821, 330, 172, 433, 611, -1154, -1265, +1833, 1760, -2119, -1763, 1988, 1309, -1229, -389, +170, -653, 845, 1314, -1301, -1322, 922, 593, +61, 357, -1254, -1112, 1863, 1067, -1670, -308, +610, -777, 628, 1460, -1436, -1282, 1336, 279, +-400, 1141, -749, -2070, 1516, 2070, -1327, -964, +432, -615, 760, 2044, -1439, -2613, 1307, 2158, +-443, -1034, -601, -202, 1115, 933, -854, -1061, +-147, 564, 1164, 26, -1684, -445, 1249, 433, +-123, -132, -1165, -262, 1957, 540, -1840, -479, +1007, 222, 153, 216, -948, -562, 1170, 898, +-789, -1080, 288, 1215, -39, -1287, 232, 1223, +-732, -974, 1072, 444, -1018, 149, 385, -773, +446, 1080, -1157, -1075, 1340, 748, -1021, -411, +445, 262, 31, -346, -124, 632, -48, -757, +334, 593, -359, -5, 134, -629, 272, 1082, +-512, -1057, 436, 584, -90, 31, -296, -435, +356, 331, -58, 75, -517, -589, 907, 748, +-869, -482, 296, -135, 494, 675, -1051, -822, +1058, 526, -460, 84, -322, -561, 881, 679, +-804, -268, 200, -341, 600, 906, -1084, -1101, +969, 873, -371, -347, -355, -267, 718, 689, +-599, -918, 76, 858, 401, -662, -530, 319, +210, 16, 308, -317, -628, 467, 536, -355, +-57, 49, -405, 378, 536, -656, -141, 718, +-528, -423, 1063, -27, -1069, 437, 474, -601, +388, 491, -1054, -263, 1112, 62, -596, -117, +-201, 332, 753, -592, -766, 626, 280, -420, +365, 24, -731, 322, 645, -378, -190, 118, +-221, 344, 298, -699, 80, 814, -654, -585, +1040, 225, -961, 53, 414, -65, 241, -150, +-615, 393, 410, -480, 222, 246, -917, 192, +1176, -661, -759, 881, -176, -800, 1180, 443, +-1681, -3, 1437, -330, -535, 481, -517, -451, +1196, 376, -1161, -266, 488, 177, 416, -26, +-1079, -199, 1172, 493, -778, -724, 190, 749, +207, -554, -241, 158, -4, 233, 254, -474, +-259, 441, -15, -217, 410, -52, -634, 195, +549, -108, -180, -163, -226, 495, 426, -672, +-343, 646, 95, -383, 44, 32, 80, 280, +-473, -403, 869, 325, -1007, -101, 710, -169, +-79, 350, -602, -402, 1036, 312, -1049, -205, +750, 129, -336, -183, 68, 346, -11, -555, +121, 698, -232, -692, 246, 541, -175, -268, +84, 2, -82, 204, 140, -282, -201, 277, +153, -208, 5, 125, -202, -43, 311, -43, +-245, 98, 70, -112, 95, 0, -79, 226, +-160, -519, 522, 755, -800, -805, 799, 605, +-472, -211, -63, -196, 539, 457, -746, -441, +563, 229, -119, 37, -372, -124, 643, -50, +-592, 449, 254, -856, 162, 1046, -423, -895, +399, 428, -108, 134, -281, -574, 570, 699, +-622, -523, 427, 178, -132, 131, -119, -251, +197, 149, -120, 96, -46, -314, 159, 401, +-164, -304, 82, 79, 0, 190, -17, -399, +-46, 507, 111, -508, -85, 419, -95, -272, +365, 84, -626, 103, 710, -265, -586, 351, +268, -354, 81, 267, -349, -143, 421, 32, +-351, 47, 181, -74, -55, 120, 0, -210, +-37, 366, 95, -511, -156, 570, 172, -449, +-202, 159, 226, 227, -286, -567, 304, 725, +-288, -659, 165, 404, 5, -101, -216, -136, +353, 216, -405, -174, 328, 73, -177, -16, +-21, 45, 190, -155, -308, 279, 343, -353, +-319, 342, 231, -259, -152, 155, 53, -80, +-20, 84, -31, -149, 45, 230, -113, -288, +173, 257, -266, -135, 286, -61, -259, 250, +127, -364, 12, 340, -125, -180, 113, -63, +-7, 278, -179, -351, 278, 254, -254, -11, +24, -258, 253, 426, -515, -399, 534, 191, +-375, 111, 21, -376, 249, 505, -374, -482, +219, 364, 34, -251, -279, 195, 291, -200, +-107, 201, -213, -114, 401, -85, -359, 348, +37, -583, 353, 678, -649, -588, 608, 348, +-342, -48, -96, -190, 368, 300, -462, -266, +262, 141, -38, 12, -155, -142, 134, 231, +-53, -290, -38, 322, -49, -331, 249, 296, +-503, -199, 576, 40, -448, 163, 76, -365, +301, 517, -613, -574, 639, 533, -552, -398, +337, 229, -271, -83, 278, -5, -446, 16, +518, 27, -510, -76, 290, 83, -22, -53, +-256, 17, 354, -29, -320, 137, 129, -317, +43, 489, -178, -566, 147, 491, -94, -274, +-33, 5, 44, 186, -55, -230, -49, 124, +70, 32, -116, -136, 46, 99, -39, 81, +8, -323, -78, 519, 119, -590, -160, 518, +76, -341, 42, 142, -208, 18, 244, -102, +-197, 124, -10, -115, 161, 111, -276, -137, +152, 182, 24, -228, -299, 242, 393, -215, +-395, 138, 200, -50, -55, -10, -71, 36, +18, -22, 63, 9, -161, -28, 118, 100, +1, -193, -221, 259, 365, -236, -477, 104, +457, 101, -472, -316, 438, 451, -490, -484, +432, 411, -360, -282, 102, 144, 157, -38, +-442, -55, 551, 145, -552, -238, 395, 322, +-244, -365, 112, 346, -97, -257, 105, 131, +-150, -7, 101, -73, -47, 101, -82, -80, +126, 29, -170, 22, 90, -70, -43, 109, +-52, -154, 53, 194, -62, -232, 2, 233, +29, -182, -90, 81, 107, 50, -127, -146, +86, 164, -23, -58, -101, -139, 208, 350, +-309, -467, 292, 423, -226, -202, 44, -105, +104, 369, -251, -481, 275, 397, -254, -181, +157, -63, -80, 218, -3, -242, 60, 169, +-125, -94, 199, 77, -274, -141, 309, 244, +-278, -303, 160, 271, 4, -138, -180, -47, +278, 239, -296, -379, 204, 454, -91, -449, +-39, 384, 112, -263, -143, 100, 143, 63, +-124, -208, 106, 299, -69, -327, 34, 298, +28, -232, -64, 155, 99, -79, -77, 16, +39, 42, 20, -77, -46, 94, 51, -82, +-9, 47, -17, -7, 46, -49, -10, 102, +-40, -152, 125, 176, -146, -158, 129, 64, +9, 96, -171, -284, 392, 424, -519, -451, +585, 346, -486, -136, 326, -84, -82, 236, +-84, -276, 207, 220, -194, -106, 156, -2, +-57, 73, 39, -96, -33, 76, 123, -2, +-165, -127, 233, 285, -171, -427, 106, 475, +60, -372, -149, 129, 253, 176, -221, -411, +197, 493, -83, -397, 45, 218, 21, -45, +5, -21, 38, 0, -32, 53, 117, -42, +-118, -47, 143, 180, -16, -269, -69, 252, +215, -141, -175, -1, 95, 87, 164, -84, +-332, 29, 476, 19, -358, -9, 211, -68, +57, 157, -140, -203, 175, 185, -6, -118, +-85, 69, 192, -62, -74, 97, -20, -145, +223, 167, -248, -164, 289, 162, -180, -185, +182, 241, -122, -281, 199, 245, -138, -122, +124, -68, 53, 251, -151, -329, 311, 290, +-284, -166, 296, 55, -162, -30, 147, 115, +-45, -230, 59, 293, 71, -213, -109, -17, +280, 322, -296, -588, 364, 717, -253, -670, +236, 486, -132, -248, 193, 48, -174, 64, +264, -97, -185, 90, 156, -91, 32, 128, +-86, -192, 207, 259, -144, -283, 166, 263, +-69, -187, 132, 85, -88, 22, 159, -124, +-51, 217, -13, -293, 241, 355, -333, -397, +476, 392, -394, -344, 341, 253, -117, -153, +31, 61, 119, 4, -78, -32, 110, 46, +2, -58, 41, 79, -5, -101, 149, 120, +-195, -114, 363, 74, -351, -5, 382, -81, +-200, 149, 83, -168, 160, 104, -216, 29, +286, -192, -124, 306, 28, -304, 179, 150, +-169, 105, 182, -368, 27, 530, -114, -545, +286, 448, -237, -340, 264, 328, -134, -462, +179, 673, -136, -852, 269, 849, -236, -646, +277, 269, -99, 135, 11, -470, 229, 633, +-275, -657, 376, 569, -233, -437, 154, 267, +131, -83, -269, -115, 529, 253, -542, -309, +604, 230, -395, -85, 292, -76, -21, 100, +-16, 3, 118, -234, 20, 433, -20, -517, +134, 383, -10, -108, -23, -222, 230, 423, +-207, -443, 244, 230, -3, 103, -129, -441, +417, 604, -426, -532, 472, 161, -195, 384, +12, -982, 357, 1380, -457, -1478, 594, 1171, +-395, -620, 279, -22, 43, 450, -99, -587, +206, 388, 7, -71, -91, -214, 342, 249, +-277, -95, 282, -204, 2, 419, -79, -507, +294, 384, -201, -216, 263, 58, -147, -63, +345, 145, -444, -314, 785, 396, -826, -411, +883, 266, -491, -94, 155, -143, 424, 313, +-661, -509, 945, 639, -840, -834, 914, 984, +-809, -1135, 1008, 1134, -973, -1021, 1061, 686, +-717, -294, 435, -123, 117, 327, -281, -345, +402, 107, -31, 153, -184, -380, 507, 340, +-303, -145, 84, -211, 461, 447, -606, -541, +691, 360, -250, -95, -17, -223, 400, 336, +-249, -310, 125, 83, 276, 117, -232, -258, +142, 144, 438, 96, -804, -471, 1247, 709, +-1134, -798, 1019, 542, -496, -113, 251, -524, +186, 1093, -290, -1611, 665, 1887, -799, -2048, +1218, 1988, -1293, -1877, 1516, 1609, -1307, -1366, +1275, 1038, -931, -786, 882, 477, -570, -218, +523, -176, -164, 581, 80, -1098, 227, 1470, +-119, -1713, 145, 1588, 222, -1256, -305, 676, +585, -160, -449, -306, 514, 531, -285, -703, +403, 776, -282, -973, 450, 1139, -237, -1339, +190, 1298, 250, -1079, -403, 519, 760, 129, +-681, -853, 757, 1324, -458, -1563, 426, 1366, +-82, -935, 0, 217, 455, 478, -674, -1162, +1178, 1549, -1241, -1708, 1342, 1437, -833, -913, +367, 77, 500, 746, -971, -1499, 1469, 1821, +-1312, -1725, 1115, 1040, -389, -57, -117, -1126, +855, 2028, -1118, -2541, 1449, 2367, -1255, -1727, +1191, 709, -758, 185, 659, -781, -386, 740, +595, -258, -673, -571, 1130, 1251, -1240, -1616, +1446, 1369, -1055, -727, 637, -228, 329, 1035, +-1098, -1615, 2077, 1726, -2540, -1605, 2990, 1317, +-2872, -1241, 2831, 1363, -2369, -1800, 2092, 2188, +-1413, -2370, 879, 1933, 72, -975, -769, -443, +1611, 1740, -1875, -2605, 2056, 2628, -1669, -2044, +1470, 1087, -1099, -422, 1207, 231, -1166, -648, +1268, 1187, -756, -1469, 71, 997, 1170, 107, +-2112, -1604, 2923, 2787, -2845, -3330, 2414, 2938, +-1345, -1943, 462, 617, 506, 505, -965, -1336, +1453, 1707, -1524, -1821, 1655, 1606, -1286, -1178, +840, 409, 94, 470, -815, -1327, 1472, 1721, +-1356, -1543, 900, 705, 121, 369, -858, -1333, +1401, 1685, -1148, -1406, 657, 541, 243, 422, +-842, -1229, 1397, 1583, -1452, -1604, 1482, 1286, +-1078, -858, 665, 232, 170, 426, -899, -1087, +1661, 1417, -1763, -1293, 1447, 591, -459, 323, +-392, -1083, 981, 1186, -633, -645, -173, -291, +1300, 945, -1761, -938, 1534, 133, -391, 923, +-749, -1609, 1509, 1305, -1144, -87, 109, -1558, +1286, 2703, -1967, -2805, 1827, 1708, -714, -37, +-414, -1471, 1128, 2082, -762, -1744, -162, 791, +1236, 63, -1444, -390, 766, 19, 751, 674, +-2068, -1273, 2682, 1338, -2019, -866, 636, 33, +967, 713, -1788, -1142, 1740, 1085, -818, -740, +-125, 260, 709, 114, -471, -398, -117, 584, +734, -792, -719, 974, 168, -1082, 793, 968, +-1444, -660, 1572, 208, -960, 163, 121, -344, +634, 261, -810, -75, 564, -48, -45, -85, +-221, 430, 187, -845, 200, 1024, -505, -827, +574, 291, -230, 290, -206, -596, 540, 425, +-460, 81, 152, -576, 196, 660, -169, -213, +-209, -576, 811, 1235, -1121, -1375, 917, 861, +-117, 27, -812, -843, 1440, 1154, -1326, -880, +605, 237, 355, 353, -925, -582, 855, 370, +-174, 56, -586, -395, 993, 408, -751, -113, +108, -316, 549, 638, -756, -761, 489, 721, +8, -637, -269, 571, 71, -467, 487, 215, +-937, 225, 867, -746, -122, 1122, -948, -1158, +1773, 827, -1814, -313, 1026, -133, 204, 325, +-1159, -273, 1339, 121, -635, -43, -495, 79, +1409, -105, -1587, -38, 997, 414, -7, -898, +-799, 1228, 1041, -1167, -695, 688, 101, -15, +338, -482, -394, 536, 175, -154, 39, -376, +34, 651, -405, -435, 845, -180, -992, 812, +676, -1039, -2, 687, -636, 77, 823, -813, +-379, 1132, -494, -877, 1317, 244, -1602, 414, +1145, -763, -148, 702, -880, -342, 1417, -70, +-1202, 328, 410, -377, 498, 298, -1023, -197, +911, 145, -275, -85, -494, -77, 992, 396, +-1026, -774, 700, 1026, -304, -964, 111, 564, +-198, 21, 411, -494, -509, 637, 331, -403, +58, -13, -449, 345, 610, -388, -481, 141, +179, 250, 31, -530, 9, 557, -291, -297, +574, -91, -613, 441, 249, -563, 369, 461, +-971, -189, 1220, -51, -1038, 177, 521, -109, +-3, -36, -280, 176, 216, -166, 11, 34, +-190, 212, 112, -430, 176, 592, -519, -610, +685, 554, -619, -413, 382, 321, -186, -266, +172, 305, -331, -330, 491, 334, -465, -194, +180, -2, 267, 238, -637, -347, 738, 369, +-541, -268, 225, 232, -11, -276, 92, 482, +-396, -665, 736, 779, -808, -652, 546, 409, +-10, -104, -457, 3, 648, -109, -386, 451, +-104, -731, 595, 827, -736, -493, 517, -94, +21, 803, -496, -1246, 746, 1364, -590, -1052, +239, 627, 184, -225, -370, 130, 351, -211, +-99, 433, -111, -481, 259, 369, -195, -9, +102, -319, 30, 570, -28, -518, -4, 332, +96, 18, -97, -272, 78, 512, -13, -590, +38, 682, -139, -637, 329, 588, -497, -342, +587, 59, -537, 341, 386, -599, -220, 780, +75, -686, -18, 539, -53, -275, 124, 153, +-316, -34, 478, 50, -669, 51, 649, -125, +-589, 327, 353, -393, -282, 431, 202, -240, +-399, 88, 467, 116, -613, -90, 386, 31, +-193, 205, -274, -319, 425, 454, -645, -384, +438, 341, -425, -159, 137, 98, -232, 40, +56, -25, -204, 87, -65, -13, 10, 43, +-315, 50, 108, -33, -174, 143, -270, -149, +249, 273, -550, -259, 216, 310, -242, -172, +-232, 73, 105, 189, -352, -302, -50, 419, +-29, -249, -433, 55, 283, 311, -641, -472, +350, 572, -568, -353, 102, 137, -161, 197, +-425, -296, 342, 386, -760, -256, 389, 248, +-540, -154, 34, 229, -246, -158, -62, 131, +-354, 128, 101, -306, -380, 560, -119, -535, +46, 444, -560, -74, 279, -207, -447, 534, +-127, -576, 63, 585, -496, -360, 145, 246, +-296, -24, -182, -20, 17, 164, -374, -168, +135, 284, -484, -234, 286, 252, -581, -68, +191, -40, -157, 297, -508, -388, 629, 527, +-1041, -438, 697, 379, -596, -140, -30, 39, +85, 138, -360, -103, 31, 137, -83, -17, +-140, 56, -212, -15, 315, 136, -734, -110, +614, 134, -574, 62, 38, -184, 203, 393, +-596, -352, 486, 272, -475, 55, 130, -276, +-93, 532, -89, -504, -57, 455, 8, -202, +-161, 86, 84, 67, -187, -10, 86, 24, +-146, 81, -32, -10, 106, 7, -385, 152, +462, -185, -566, 303, 359, -261, -170, 293, +-162, -188, 233, 192, -250, -80, -9, 85, +168, 16, -345, -4, 223, 112, -98, -125, +-154, 266, 151, -284, -91, 368, -213, -277, +373, 237, -515, -69, 333, 48, -159, 19, +-155, 75, 225, -56, -290, 74, 134, 87, +-118, -188, 14, 333, -108, -236, 22, 76, +-5, 276, -269, -502, 397, 679, -602, -585, +472, 461, -372, -238, 42, 198, 23, -164, +-138, 251, -58, -169, 59, 51, -166, 242, +-74, -403, 174, 484, -433, -275, 320, 10, +-252, 321, -131, -429, 248, 428, -461, -216, +278, 72, -244, 73, -35, -37, 1, 26, +-129, 29, -40, 62, -39, -123, -116, 224, +2, -147, -142, 29, 23, 205, -145, -289, +-47, 278, 43, -32, -327, -231, 338, 487, +-516, -512, 317, 406, -271, -120, -70, -108, +116, 303, -330, -306, 193, 263, -247, -111, +34, 19, -87, 100, -99, -120, 41, 165, +-243, -144, 216, 179, -416, -174, 332, 236, +-409, -252, 184, 283, -130, -194, -155, 35, +200, 268, -410, -562, 349, 823, -442, -857, +282, 707, -295, -338, 107, -39, -132, 341, +12, -390, -135, 246, 125, 67, -311, -337, +289, 501, -358, -423, 168, 166, -66, 266, +-219, -708, 325, 1105, -525, -1289, 504, 1261, +-559, -954, 411, 498, -347, 54, 117, -527, +-1, 888, -220, -1066, 274, 1154, -399, -1150, +367, 1138, -424, -1024, 353, 804, -341, -387, +182, -147, -68, 730, -139, -1162, 203, 1378, +-232, -1309, 63, 1073, 108, -741, -331, 455, +387, -208, -352, 18, 152, 176, 39, -354, +-222, 525, 261, -611, -240, 623, 161, -563, +-163, 529, 216, -541, -343, 650, 420, -758, +-419, 798, 294, -641, -127, 286, 1, 239, +-10, -773, 151, 1209, -325, -1427, 390, 1443, +-221, -1267, -174, 1007, 687, -705, -1071, 446, +1156, -232, -828, 93, 225, 31, 461, -170, +-917, 394, 1045, -674, -827, 979, 515, -1172, +-295, 1203, 363, -1006, -626, 661, 986, -240, +-1161, -148, 1118, 481, -805, -721, 408, 903, +37, -977, -409, 927, 826, -695, -1253, 334, +1745, 100, -2126, -435, 2294, 614, -2054, -570, +1463, 401, -568, -172, -359, 17, 1181, 73, +-1706, -88, 1992, 126, -2026, -198, 1993, 309, +-1875, -359, 1764, 301, -1536, -74, 1231, -262, +-724, 619, 123, -861, 605, 936, -1304, -817, +1976, 589, -2461, -318, 2768, 100, -2763, 52, +2532, -139, -2024, 214, 1413, -299, -688, 433, +13, -606, 681, 817, -1289, -1000, 1896, 1122, +-2368, -1114, 2744, 989, -2855, -747, 2750, 448, +-2313, -86, 1686, -314, -851, 779, 38, -1239, +759, 1632, -1342, -1861, 1830, 1919, -2131, -1834, +2457, 1693, -2681, -1515, 2917, 1274, -2885, -882, +2642, 299, -1949, 452, 1046, -1237, 113, 1917, +-1136, -2369, 2083, 2568, -2633, -2572, 3014, 2437, +-3023, -2192, 2953, 1840, -2603, -1350, 2254, 737, +-1643, -47, 1057, -661, -241, 1325, -469, -1892, +1285, 2317, -1814, -2582, 2330, 2679, -2508, -2664, +2716, 2610, -2688, -2523, 2750, 2360, -2516, -2007, +2238, 1396, -1526, -550, 755, -389, 280, 1253, +-1060, -1916, 1816, 2334, -2153, -2575, 2483, 2722, +-2514, -2840, 2643, 2921, -2487, -2909, 2357, 2715, +-1846, -2320, 1328, 1743, -527, -1053, -98, 314, +807, 436, -1234, -1198, 1758, 1937, -2075, -2629, +2520, 3164, -2690, -3486, 2786, 3541, -2431, -3346, +1929, 2952, -1108, -2438, 423, 1835, 278, -1189, +-672, 497, 1060, 180, -1252, -801, 1554, 1290, +-1748, -1675, 2032, 1998, -2157, -2350, 2286, 2695, +-2193, -2942, 2016, 2925, -1578, -2576, 1057, 1903, +-358, -1097, -305, 317, 978, 276, -1486, -688, +1898, 967, -2140, -1234, 2316, 1533, -2388, -1869, +2435, 2087, -2369, -2081, 2179, 1752, -1786, -1195, +1207, 552, -506, 1, -197, -434, 787, 764, +-1185, -1107, 1376, 1466, -1445, -1809, 1478, 2028, +-1580, -2111, 1740, 2069, -1925, -1992, 1985, 1906, +-1842, -1836, 1455, 1715, -941, -1519, 461, 1189, +-160, -790, 63, 351, -81, 20, 70, -324, +72, 530, -305, -713, 544, 863, -642, -1011, +611, 1084, -455, -1097, 344, 1001, -262, -878, +293, 735, -295, -639, 315, 563, -220, -537, +214, 489, -228, -459, 461, 440, -702, -478, +1011, 526, -1058, -549, 1006, 449, -667, -265, +447, 8, -197, 212, 221, -402, -133, 561, +105, -755, 279, 927, -632, -1057, 1179, 1078, +-1391, -1071, 1588, 1081, -1417, -1183, 1418, 1302, +-1280, -1393, 1477, 1383, -1500, -1323, 1689, 1220, +-1461, -1103, 1298, 873, -786, -541, 595, 116, +-310, 223, 474, -417, -393, 392, 436, -291, +50, 219, -438, -303, 1098, 463, -1250, -616, +1389, 584, -1025, -375, 944, 25, -732, 272, +1005, -424, -1073, 367, 1335, -221, -1096, 92, +937, -127, -411, 298, 220, -543, 100, 686, +-8, -655, 127, 393, 0, -11, 182, -395, +-119, 687, 256, -870, -59, 945, 34, -1007, +218, 1047, -149, -1086, 179, 1049, 104, -939, +-191, 725, 419, -473, -371, 202, 433, 31, +-288, -230, 326, 356, -216, -440, 271, 467, +-146, -478, 121, 450, 64, -395, -139, 283, +317, -146, -370, -24, 507, 186, -528, -339, +617, 444, -581, -514, 564, 528, -432, -545, +318, 568, -148, -619, 26, 650, 132, -634, +-225, 526, 310, -383, -301, 246, 219, -183, +-79, 146, -54, -91, 97, -64, -16, 304, +-142, -581, 294, 765, -355, -806, 243, 684, +-66, -491, -141, 295, 201, -178, -119, 110, +-94, -61, 289, -45, -412, 206, 344, -394, +-235, 515, 79, -518, -87, 374, 190, -146, +-395, -91, 546, 234, -616, -255, 518, 175, +-406, -88, 255, 61, -247, -132, 282, 257, +-371, -359, 419, 340, -379, -194, 217, -59, +-27, 324, -224, -530, 393, 626, -536, -643, +615, 641, -652, -675, 681, 743, -684, -792, +631, 756, -551, -623, 397, 416, -218, -235, +45, 96, 181, -5, -391, -110, 675, 286, +-941, -498, 1134, 664, -1194, -695, 1103, 550, +-886, -301, 707, 73, -492, 10, 400, 63, +-254, -218, 102, 313, 101, -265, -278, 67, +437, 185, -448, -403, 513, 522, -485, -556, +590, 547, -680, -520, 802, 468, -812, -382, +734, 250, -451, -95, 210, -52, 124, 153, +-244, -197, 339, 195, -335, -173, 392, 158, +-471, -150, 655, 126, -678, -72, 704, -19, +-473, 124, 281, -224, -37, 291, -77, -337, +151, 356, -107, -362, 151, 333, -82, -257, +141, 144, -75, -14, 54, -72, 10, 79, +-17, 20, 20, -213, 66, 477, -1, -761, +-22, 1002, 237, -1145, -393, 1162, 546, -1051, +-594, 820, 598, -469, -551, 9, 640, 539, +-648, -1133, 734, 1680, -625, -2066, 406, 2186, +-50, -1982, -339, 1452, 702, -682, -893, -193, +1052, 1000, -1006, -1600, 963, 1883, -802, -1818, +548, 1411, -173, -734, -334, -115, 948, 967, +-1468, -1639, 1896, 1946, -1990, -1756, 1798, 1073, +-1322, -40, 621, -1073, 105, 1940, -722, -2287, +1111, 1960, -1108, -1006, 824, -337, -296, 1734, +-284, -2837, 692, 3383, -902, -3242, 784, 2461, +-400, -1234, -111, -120, 674, 1223, -1033, -1768, +1047, 1623, -678, -891, -107, -120, 998, 998, +-1762, -1371, 2127, 1042, -1908, -75, 1199, -1190, +-171, 2285, -933, -2805, 1786, 2607, -2337, -1877, +2531, 1007, -2487, -446, 2394, 452, -2280, -986, +2189, 1725, -2026, -2229, 1660, 2139, -1176, -1350, +584, 68, -51, 1292, -303, -2278, 550, 2566, +-689, -2114, 857, 1173, -1120, -211, 1411, -291, +-1711, 92, 1857, 688, -1682, -1584, 1166, 2005, +-242, -1527, -854, 131, 1833, 1732, -2408, -3268, +2291, 3709, -1470, -2699, 185, 522, 1226, 1968, +-2196, -3755, 2477, 4132, -1957, -3026, 877, 977, +315, 1150, -1233, -2584, 1671, 2947, -1573, -2370, +1190, 1322, -631, -312, 71, -354, 470, 679, +-1010, -841, 1479, 966, -1746, -1013, 1655, 801, +-1000, -184, -64, -784, 1272, 1776, -2113, -2326, +2168, 2054, -1403, -902, 104, -739, 1151, 2208, +-1768, -2868, 1534, 2454, -532, -1180, -779, -329, +1801, 1371, -2138, -1469, 1617, 633, -481, 650, +-780, -1669, 1702, 1878, -1957, -1196, 1575, 32, +-840, 975, 57, -1319, 456, 845, -603, 193, +391, -1324, 105, 2045, -691, -2064, 1163, 1392, +-1337, -300, 1049, -846, -402, 1729, -447, -2159, +1149, 2048, -1447, -1395, 1252, 367, -713, 666, +191, -1254, -100, 1064, 546, -158, -1343, -1015, +1921, 1783, -1751, -1610, 647, 429, 1029, 1274, +-2512, -2623, 2950, 2848, -2068, -1716, 182, -219, +1714, 1915, -2612, -2438, 2031, 1533, -315, 206, +-1469, -1723, 2183, 2145, -1375, -1291, -515, -229, +2265, 1431, -2765, -1550, 1650, 557, 453, 874, +-2264, -1817, 2696, 1741, -1520, -816, -526, -239, +2139, 683, -2313, -240, 929, -726, 1192, 1464, +-2730, -1339, 2764, 257, -1279, 1231, -851, -2235, +2340, 2161, -2389, -1094, 1107, -222, 605, 935, +-1602, -650, 1306, -283, -5, 1096, -1349, -1130, +1789, 293, -1027, 908, -383, -1687, 1484, 1491, +-1501, -426, 492, -765, 786, 1184, -1391, -405, +845, -1140, 475, 2424, -1665, -2512, 1877, 1235, +-909, 700, -656, -2156, 1854, 2319, -1946, -1166, +851, -550, 735, 1827, -1882, -2012, 1939, 1152, +-962, 105, -374, -995, 1241, 1131, -1232, -684, +500, 166, 315, 14, -703, 177, 501, -457, +-39, 502, -269, -222, 141, -159, 267, 352, +-634, -226, 541, -66, 54, 247, -970, -169, +1674, -42, -1726, 121, 904, 73, 454, -405, +-1701, 598, 2047, -526, -1238, 345, -441, -308, +2034, 516, -2650, -755, 1817, 690, -5, -144, +-1806, -662, 2466, 1246, -1667, -1179, -106, 446, +1542, 497, -1704, -1008, 430, 766, 1270, -36, +-2120, -559, 1368, 594, 440, -212, -1993, -25, +2008, -234, -431, 775, -1701, -914, 2781, 198, +-2033, 1125, -227, -2206, 2568, 2273, -3704, -1235, +3007, -257, -1053, 1216, -1036, -1070, 2125, 15, +-1790, 1062, 372, -1298, 1209, 466, -2048, 856, +1555, -1684, 5, 1452, -1863, -371, 2848, -608, +-2393, 697, 678, 179, 1216, -1298, -2104, 1747, +1441, -1098, 226, -365, -1573, 1705, 1550, -2120, +-180, 1347, -1451, -20, 2041, -984, -1186, 1006, +-489, -117, 1667, -975, -1601, 1492, 376, -996, +1040, -131, -1704, 1284, 1327, -1824, -210, 1580, +-916, -703, 1593, -302, -1546, 804, 845, -574, +116, -216, -853, 896, 789, -1051, 8, 535, +-1081, 173, 1574, -534, -1053, 344, -174, 96, +1306, -195, -1524, -113, 899, 663, 5, -927, +-404, 835, 137, -448, 343, 110, -578, 56, +296, -175, 90, 182, -295, 4, 124, -547, +184, 833, -256, -332, 69, -1072, 367, 2388, +-668, -2450, 804, 999, -704, 1002, 430, -1848, +-36, 1114, -550, 368, 1010, -941, -1147, 320, +609, 653, 346, -982, -1149, 648, 1211, -517, +-227, 855, -1153, -1380, 2146, 1126, -1868, -120, +497, -1034, 1037, 1423, -1754, -972, 1182, 296, +-49, 240, -903, -395, 959, 369, -269, 126, +-664, -708, 1321, 957, -1234, -390, 595, -556, +427, 892, -1169, -325, 1218, -596, -414, 591, +-878, 176, 1606, -811, -1289, 289, -82, 657, +1326, -719, -1607, -348, 820, 1444, 299, -1131, +-709, -35, 354, 820, 402, -147, -695, -936, +393, 1082, 129, -18, -544, -1063, 573, 961, +-550, -224, 300, -337, 19, 114, -390, 97, +473, -112, -79, 82, -397, -399, 655, 873, +-320, -770, -135, 177, 256, 586, 106, -633, +-645, 310, 594, 26, -107, 75, -547, -351, +604, 569, -173, -869, -287, 931, 370, -704, +42, -76, -321, 564, 258, -470, 142, -152, +-282, 602, -86, -538, 458, 343, -471, -203, +-58, 391, 287, -274, -100, -66, -295, 584, +419, -690, -230, 423, 185, -286, -99, 519, +-97, -1092, 492, 1099, -631, -458, 253, -585, +244, 892, -585, -424, 467, 17, -346, -479, +265, 1372, -331, -1206, 417, 59, -359, 967, +173, -562, 393, -377, -980, 623, 1198, 72, +-595, -571, -512, 9, 1098, 745, -815, -765, +1, -209, 267, 795, -2, -516, -220, -167, +42, 303, 148, 99, 193, -309, -557, 343, +463, -226, 131, 156, -426, 273, 18, -567, +630, 397, -977, 70, 601, -230, 73, -54, +-657, 60, 704, 167, -225, -388, -258, 128, +404, 124, -60, -123, -293, -105, 546, 355, +-710, -405, 754, 325, -509, 135, -184, -508, +747, 537, -729, -19, 14, -376, 723, 185, +-845, 375, 363, -759, 341, 543, -681, -223, +677, 7, -358, -118, -104, 119, 481, 102, +-517, -402, 43, 422, 430, -31, -466, -158, +-25, -8, 547, 433, -733, -521, 721, 510, +-529, -516, 186, 324, 311, 180, -475, -470, +103, -100, 406, 646, -538, -431, 144, -251, +300, 138, -614, 383, 688, -134, -417, -764, +-212, 940, 847, 61, -874, -726, 368, 559, +127, -223, -154, 481, -114, -503, 322, -120, +-325, 597, 97, -365, 174, -143, -349, 85, +285, 131, -112, -225, -80, 164, 343, -363, +-494, 561, 233, -379, 478, -148, -1021, 712, +819, -724, -20, 303, -671, 313, 629, -519, +-25, 422, -535, -117, 533, -173, -140, 251, +-131, -77, 170, -142, -295, -125, 680, 486, +-894, -446, 608, -203, -42, 698, -307, -648, +231, 355, 21, -303, -192, 510, 189, -382, +-141, -103, 58, 495, 170, -176, -453, -269, +472, 18, -95, 764, -239, -933, 72, 146, +470, 478, -905, -269, 978, -278, -816, 306, +529, -94, -187, 160, -66, -459, 87, 374, +60, 249, -141, -712, -18, 366, 313, 543, +-454, -895, 335, 265, -205, 620, 258, -883, +-332, 653, 179, -389, -33, 73, 235, 342, +-620, -394, 616, -176, -88, 708, -426, -520, +444, -54, -182, 250, 121, -41, -325, -19, +368, -208, -49, 270, -263, -151, 167, 230, +195, -571, -387, 516, 278, 111, -57, -647, +-149, 499, 265, -33, -215, -11, -10, -239, +154, 289, -84, 13, -56, -87, 17, -226, +150, 619, -298, -607, 362, 239, -311, 92, +146, -276, 41, 276, -103, -217, 70, -40, +-88, 179, 110, -96, -36, -97, -90, 112, +79, -71, 34, 251, -40, -333, -101, 176, +191, 150, -85, -162, -30, 53, -8, 90, +139, -216, -217, 215, 279, 142, -414, -783, +463, 957, -301, -504, -17, -309, 274, 756, +-428, -699, 550, 153, -563, 405, 406, -456, +-108, 61, -127, 343, 161, -309, 46, 340, +-435, -535, 786, 725, -866, -470, 559, 105, +-82, -11, -244, 137, 254, -291, -42, 275, +-97, -304, 112, 129, -25, 168, -35, -583, +43, 763, 35, -695, -84, 418, -39, 17, +115, -345, 140, 431, -574, 3, 587, -557, +-103, 861, -276, -481, 265, -185, -155, 497, +186, -244, -49, -147, -256, 156, 321, -49, +-43, 7, -187, -72, 130, -54, -34, 231, +-23, -402, 177, 517, -385, -418, 479, 56, +-380, 317, 149, -205, 268, -120, -617, 266, +544, -111, -95, 13, -191, 38, 31, -251, +260, 560, -440, -710, 517, 495, -520, -85, +348, -353, -59, 535, -135, -458, 289, 160, +-428, 243, 404, -625, -43, 728, -392, -398, +434, -56, -30, 302, -491, -281, 735, 182, +-638, 7, 347, -229, -4, 258, -283, 9, +477, -405, -419, 661, 164, -622, 30, 183, +104, 403, -406, -610, 454, 142, -139, 534, +-237, -795, 279, 414, 44, 313, -468, -877, +610, 803, -303, -91, -155, -609, 368, 663, +-255, -141, 131, -366, -131, 544, 58, -373, +139, -45, -210, 497, -7, -596, 202, 275, +-116, 80, -125, -161, 205, 81, -57, -33, +-73, -162, 54, 518, 114, -686, -299, 328, +369, 263, -231, -576, -91, 492, 368, -295, +-359, 216, -12, -249, 459, 325, -572, -238, +198, -76, 371, 363, -648, -212, 487, -225, +-136, 365, -82, -45, 121, -247, -141, 84, +196, 308, -191, -560, 40, 483, 121, -142, +-114, -282, -28, 373, 118, -29, -4, -292, +-215, 154, 337, 219, -199, -206, -169, -275, +543, 809, -677, -855, 446, 256, 58, 631, +-545, -1058, 668, 552, -352, 406, -36, -905, +105, 539, 133, 169, -331, -652, 382, 716, +-426, -480, 481, 38, -319, 424, -132, -623, +593, 497, -745, -222, 482, 67, 8, 15, +-339, -111, 225, 202, 215, -119, -529, -75, +488, 130, -255, -6, 102, -134, -23, 115, +-108, -82, 315, 88, -489, -73, 473, -22, +-210, 78, -153, -42, 386, 41, -367, -133, +206, 238, 38, -188, -308, 17, 447, 144, +-205, -42, -341, -328, 713, 578, -603, -277, +283, -408, -154, 694, 142, -277, 66, -262, +-390, 247, 466, 161, -202, -460, -47, 494, +72, -430, 72, 350, -280, -280, 496, 310, +-534, -281, 261, -24, 141, 455, -340, -503, +288, 38, -103, 435, -99, -384, 233, -148, +-78, 602, -332, -598, 655, 269, -560, -85, +113, 192, 316, -315, -455, 214, 274, 25, +-3, -236, -149, 413, 157, -450, -104, 239, +46, 80, 45, -210, -66, 135, 10, 9, +3, -173, 115, 311, -203, -261, 132, 60, +-34, -87, 72, 367, -207, -434, 256, -17, +-114, 509, -120, -492, 258, 66, -187, 163, +113, 100, -258, -481, 522, 490, -574, -161, +419, 17, -323, -215, 287, 346, -118, -34, +-194, -392, 397, 468, -374, -272, 226, 137, +-94, -90, 128, -61, -341, 151, 545, -9, +-447, -263, 101, 278, 167, 11, -207, -290, +59, 288, 222, -64, -510, -128, 523, 231, +-139, -219, -343, 75, 576, 269, -517, -515, +353, 355, -167, 122, -9, -495, 109, 520, +-62, -353, -187, 59, 471, 265, -497, -453, +108, 183, 361, 341, -456, -618, 174, 369, +93, 183, -118, -543, 20, 508, 130, -105, +-327, -269, 439, 428, -321, -270, 80, 12, +4, 234, 87, -321, -190, 154, 206, 183, +-212, -566, 263, 712, -248, -658, 58, 338, +271, 40, -498, -316, 451, 185, -198, 294, +-16, -701, 23, 666, 131, -144, -288, -332, +308, 511, -176, -329, 11, 165, 64, -65, +-47, 42, 72, -31, -174, 23, 270, -85, +-258, 153, 152, -349, -40, 407, -34, -278, +38, -105, 20, 332, -163, -262, 328, 16, +-364, 138, 210, -93, 35, 83, -176, -40, +172, 45, -119, 82, 103, -89, -99, 23, +96, 70, -141, -29, 261, -23, -387, -167, +355, 314, -61, -165, -345, -396, 527, 576, +-279, -182, -142, -441, 314, 470, -63, 6, +-309, -321, 427, 173, -226, 234, -75, -331, +234, 308, -246, -173, 213, 68, -124, 233, +-54, -441, 169, 347, -4, -10, -300, -257, +360, 73, -23, 290, -380, -666, 481, 648, +-312, -411, 131, -43, -99, 381, 210, -492, +-366, 321, 391, 40, -144, -235, -231, 249, +402, 65, -235, -308, -30, 471, 149, -315, +-116, 19, 39, 307, 100, -430, -288, 156, +317, 290, -65, -665, -260, 477, 302, -53, +-15, -364, -316, 370, 451, -226, -409, 49, +323, 162, -228, -400, 126, 579, 0, -384, +-120, 118, 144, 105, -28, 26, -131, -196, +146, 326, -7, -218, -138, -87, 165, 403, +-128, -583, 86, 420, -49, -267, -10, 129, +113, -139, -211, -8, 138, 75, 187, 89, +-524, -437, 505, 595, -162, -278, -114, -97, +165, 328, -233, -198, 431, 105, -451, -41, +108, 155, 280, -287, -316, 350, 24, -284, +264, 85, -365, -59, 312, 71, -201, -174, +81, 98, -19, -60, -3, -22, 84, 109, +-235, -324, 358, 563, -349, -444, 251, -4, +-119, 514, -6, -344, 83, -287, -30, 887, +-151, -818, 317, 327, -294, 150, 109, -435, +30, 469, -10, -421, -23, 207, -100, -187, +262, 193, -236, -204, 75, 5, -39, 75, +131, 53, -46, -105, -298, -93, 518, 477, +-301, -450, -109, 168, 233, 177, 40, -100, +-389, -180, 498, 500, -335, -560, -6, 209, +408, 318, -713, -719, 726, 511, -442, -110, +96, -192, 50, 11, -2, 274, -64, -468, +61, 434, -71, -160, 108, -120, -85, 310, +2, -102, 46, -43, -94, 28, 259, 288, +-458, -380, 423, 182, -136, 99, -64, -196, +-45, -18, 258, 190, -274, -382, 108, 356, +35, -344, -136, 145, 315, 13, -505, -87, +455, 23, -138, 70, -112, 79, 18, -237, +253, 420, -314, -309, 46, 267, 288, -199, +-397, 216, 264, -109, -66, -101, -53, 296, +47, -498, 51, 430, -200, -292, 327, -28, +-313, 83, 101, -55, 158, -65, -197, 77, +-48, -57, 284, 92, -228, 58, -59, -213, +268, 402, -221, -173, 31, -137, 85, 385, +35, -153, -339, -322, 525, 637, -313, -585, +-177, 135, 533, 186, -533, -442, 325, 344, +-67, -149, -212, -313, 397, 597, -293, -432, +-54, -196, 308, 883, -239, -973, -15, 597, +187, 138, -176, -534, 47, 673, 78, -435, +-106, 129, 66, 238, -76, -516, 110, 411, +-12, -17, -224, -561, 359, 637, -237, -333, +-47, -307, 325, 649, -453, -651, 317, 280, +67, 243, -408, -619, 428, 841, -244, -612, +115, 194, -49, 494, -72, -888, 165, 901, +-25, -412, -229, -218, 311, 640, -129, -713, +-136, 254, 295, 292, -280, -691, 81, 387, +194, 202, -376, -758, 335, 810, -110, -467, +-235, 14, 534, 370, -561, -397, 247, 274, +190, 59, -448, -206, 422, 376, -210, -375, +-38, 204, 183, 308, -191, -923, 105, 1154, +-55, -899, 37, 211, -31, 289, 80, -611, +-180, 634, 146, -564, 88, 149, -269, 580, +116, -1174, 241, 1102, -414, -193, 266, -760, +29, 1281, -257, -1064, 305, 515, -148, 309, +-105, -1032, 241, 1271, -180, -808, 52, -144, +73, 1008, -295, -1616, 581, 1502, -580, -589, +53, -968, 705, 2070, -1152, -1994, 983, 875, +-327, 489, -479, -1419, 1058, 1761, -1084, -1212, +461, -36, 544, 1554, -1411, -2310, 1634, 1955, +-1017, -704, -131, -723, 1120, 1705, -1378, -1934, +848, 1252, 47, -51, -794, -1249, 1074, 1915, +-787, -1733, 56, 721, 751, 613, -1201, -1693, +1040, 2100, -368, -1654, -400, 683, 800, 438, +-603, -1158, 9, 1412, 521, -1169, -646, 591, +353, 268, 110, -1119, -490, 1531, 585, -1369, +-330, 782, -131, -157, 504, -538, -581, 1193, +371, -1625, 21, 1457, -497, -714, 859, -294, +-795, 1265, 243, -1917, 495, 2044, -1015, -1352, +1149, 59, -870, 1407, 169, -2441, 797, 2760, +-1554, -2226, 1611, 870, -897, 939, -200, -2566, +1178, 3183, -1659, -2572, 1520, 997, -838, 754, +-145, -2094, 1095, 2662, -1636, -2385, 1502, 1386, +-713, 56, -383, -1390, 1312, 2172, -1645, -2089, +1200, 1335, -181, -276, -804, -619, 1137, 1105, +-695, -1073, -141, 569, 763, 100, -742, -583, +51, 580, 869, -258, -1352, -194, 1057, 501, +-162, -452, -899, -193, 1760, 1305, -2144, -2190, +1834, 2212, -908, -1176, -264, -451, 1307, 2236, +-2063, -3667, 2417, 4261, -2226, -3502, 1422, 1403, +-136, 1397, -1327, -4008, 2571, 5520, -3121, -5384, +2663, 3442, -1332, -378, -400, -2697, 2085, 4681, +-3372, -5170, 3850, 4226, -3084, -2244, 1142, -148, +1217, 2208, -3030, -3295, 3767, 3418, -3419, -2866, +2243, 1992, -603, -819, -1027, -519, 2199, 1733, +-2675, -2467, 2475, 2585, -1762, -2275, 782, 1640, +220, -797, -1043, -257, 1590, 1249, -1787, -1995, +1573, 2296, -916, -2128, -30, 1497, 958, -637, +-1479, 14, 1412, 200, -892, -256, 260, 641, +284, -1222, -730, 1599, 986, -1534, -810, 1318, +144, -1166, 677, 894, -1194, -337, 1234, -429, +-813, 1078, -60, -1647, 1250, 2170, -2241, -2551, +2376, 2361, -1473, -1434, 44, -1, 1230, 1397, +-1943, -2322, 2075, 2740, -1745, -2745, 1136, 2501, +-453, -1945, -88, 1139, 417, -91, -702, -1093, +1132, 2314, -1652, -3307, 1949, 3663, -1801, -3257, +1226, 2209, -358, -870, -709, -662, 1791, 2104, +-2475, -3141, 2417, 3461, -1680, -3114, 676, 2339, +204, -1249, -767, -1, 1077, 1226, -1300, -2101, +1562, 2594, -1697, -2606, 1333, 2085, -345, -999, +-873, -289, 1733, 1210, -1962, -1483, 1680, 1148, +-1055, -570, 174, -83, 771, 540, -1371, -699, +1277, 492, -617, -149, -103, -91, 451, 201, +-397, -322, 163, 641, 78, -974, -291, 1200, +417, -1157, -363, 1009, 84, -735, 315, 307, +-636, 407, 641, -1350, -212, 2286, -552, -3005, +1346, 3260, -1832, -3073, 1831, 2379, -1359, -1342, +538, 44, 483, 1294, -1517, -2548, 2316, 3548, +-2685, -3950, 2537, 3577, -1964, -2509, 1133, 1367, +-169, -490, -886, -77, 1954, 672, -2839, -1199, +3266, 1359, -3051, -1014, 2241, 405, -1091, 38, +-50, -256, 863, 273, -1241, -282, 1325, 311, +-1439, -547, 1797, 958, -2347, -1462, 2894, 1797, +-3200, -1737, 2948, 1248, -1867, -369, 73, -525, +1878, 1198, -3340, -1454, 3987, 1497, -3777, -1338, +2810, 988, -1381, -481, 6, 57, 876, 108, +-1234, -155, 1228, 178, -1021, -300, 795, 454, +-808, -895, 1150, 1542, -1556, -2126, 1731, 2183, +-1687, -1678, 1595, 979, -1444, -325, 1035, -194, +-233, 721, -831, -1064, 1828, 1211, -2378, -1183, +2349, 1332, -2013, -1731, 1815, 2257, -1873, -2675, +1908, 2693, -1569, -2143, 763, 870, 283, 698, +-1227, -2068, 1851, 2753, -2190, -2997, 2432, 3075, +-2651, -3087, 2726, 2853, -2569, -2310, 2277, 1680, +-1931, -942, 1442, 158, -711, 685, -171, -1207, +983, 1421, -1580, -1438, 1877, 1435, -1827, -1214, +1486, 582, -1055, 213, 669, -856, -269, 1063, +-235, -1062, 754, 834, -1079, -463, 1116, -126, +-918, 657, 586, -880, -225, 753, -79, -418, +282, 183, -414, -36, 538, 76, -685, -178, +839, 440, -929, -606, 881, 531, -661, -160, +316, -251, 76, 451, -446, -577, 738, 691, +-854, -904, 762, 878, -529, -640, 272, 191, +-61, 248, -96, -725, 187, 1246, -229, -1670, +296, 1859, -432, -1667, 547, 1328, -472, -887, +211, 494, 84, 9, -284, -538, 398, 1062, +-449, -1441, 453, 1557, -453, -1461, 518, 1182, +-642, -902, 693, 472, -546, 45, 185, -672, +315, 1088, -838, -1219, 1239, 1117, -1401, -977, +1301, 917, -1028, -818, 696, 689, -371, -377, +17, -8, 406, 541, -855, -954, 1174, 1114, +-1207, -931, 934, 628, -519, -401, 125, 233, +172, -143, -337, 35, 337, 5, -193, -176, +-9, 456, 158, -802, -230, 927, 237, -750, +-197, 395, 127, -42, -53, -125, -32, 201, +161, -129, -302, 18, 362, 186, -248, -291, +11, 254, 238, -53, -440, -178, 643, 296, +-878, -263, 1013, 30, -892, 203, 513, -326, +-61, 108, -279, 255, 489, -532, -627, 414, +713, 42, -730, -579, 701, 996, -698, -1190, +734, 1263, -713, -1136, 501, 921, -75, -629, +-446, 444, 904, -332, -1177, 280, 1212, -236, +-985, 214, 509, -278, 135, 351, -785, -401, +1216, 264, -1275, -72, 1015, -56, -688, -52, +487, 181, -379, -30, 197, -505, 95, 1177, +-402, -1544, 629, 1508, -750, -1080, 701, 471, +-403, 347, -85, -1200, 526, 1917, -733, -2186, +710, 1888, -569, -1120, 356, 110, -59, 809, +-287, -1472, 575, 1647, -688, -1317, 533, 492, +-119, 507, -430, -1362, 916, 1809, -1232, -1776, +1332, 1276, -1123, -295, 513, -977, 361, 2207, +-1095, -2784, 1322, 2410, -1027, -1139, 454, -422, +165, 1713, -746, -2406, 1209, 2500, -1396, -2071, +1197, 1115, -683, 107, 71, -1126, 416, 1389, +-746, -925, 981, 196, -1146, 237, 1141, -283, +-910, 129, 529, 118, -129, -395, -294, 524, +821, -95, -1397, -922, 1801, 2138, -1849, -2843, +1545, 2684, -988, -1653, 262, 49, 520, 1682, +-1161, -2962, 1451, 3243, -1317, -2476, 909, 1065, +-530, 206, 495, -763, -902, 299, 1543, 926, +-2047, -2286, 2137, 3018, -1755, -2661, 990, 1287, +-9, 669, -951, -2477, 1618, 3501, -1814, -3337, +1577, 2165, -1058, -518, 433, -964, 160, 1936, +-654, -2275, 1014, 2057, -1192, -1534, 1097, 977, +-685, -522, 35, -57, 692, 911, -1342, -1885, +1717, 2423, -1589, -2143, 860, 1079, 258, 355, +-1326, -1644, 1895, 2356, -1701, -2134, 699, 1058, +755, 372, -1975, -1349, 2297, 1411, -1586, -578, +251, -623, 1070, 1525, -1859, -1553, 1800, 546, +-902, 1039, -409, -2405, 1488, 2837, -1886, -2277, +1614, 1100, -976, 109, 292, -1000, 239, 1398, +-523, -1342, 570, 958, -415, -427, 110, -112, +308, 563, -712, -732, 885, 427, -625, 464, +-81, -1626, 919, 2470, -1365, -2343, 1045, 1026, +-99, 975, -829, -2574, 1047, 2726, -361, -1296, +-795, -854, 1652, 2350, -1586, -2368, 503, 966, +1084, 965, -2333, -2311, 2558, 2311, -1628, -985, +35, -773, 1376, 1827, -1813, -1559, 1037, 420, +395, 642, -1425, -879, 1249, 331, 53, 485, +-1623, -937, 2400, 710, -1857, 29, 309, -757, +1306, 931, -2112, -542, 1858, 26, -956, 107, +-15, 169, 659, -501, -801, 476, 448, 35, +176, -829, -646, 1491, 689, -1580, -348, 1023, +-139, -135, 567, -478, -800, 521, 752, -170, +-452, -92, 82, -36, 163, 430, -232, -718, +162, 572, -3, -83, -225, -381, 416, 453, +-419, -240, 197, 75, 95, -162, -254, 368, +230, -409, -212, 152, 420, 409, -806, -1020, +973, 1255, -514, -585, -557, -941, 1698, 2523, +-2165, -2980, 1564, 1744, -147, 542, -1277, -2473, +1931, 2870, -1566, -1808, 674, 313, -3, 460, +-70, -286, -154, -237, 51, 317, 670, 254, +-1599, -1027, 1947, 1315, -1215, -784, -337, -199, +1797, 922, -2243, -772, 1389, -157, 204, 1176, +-1505, -1377, 1701, 460, -738, 939, -661, -1670, +1594, 1008, -1648, 616, 1027, -1950, -167, 1912, +-683, -593, 1369, -926, -1644, 1502, 1223, -914, +-187, -143, -888, 762, 1265, -483, -641, -471, +-524, 1463, 1246, -1736, -770, 997, -691, 400, +1973, -1563, -1909, 1791, 402, -989, 1386, -294, +-1993, 1275, 889, -1460, 1084, 881, -2459, -59, +2339, -498, -947, 520, -685, -193, 1597, -135, +-1524, 205, 873, -68, -181, -44, -368, -9, +813, 232, -1047, -469, 786, 557, 21, -350, +-912, -65, 1255, 477, -817, -631, -95, 467, +920, -66, -1193, -398, 814, 645, -116, -458, +-380, -148, 422, 780, -239, -994, 204, 619, +-395, 36, 544, -539, -394, 715, 19, -688, +222, 563, -143, -218, 20, -282, -265, 513, +751, -27, -814, -875, 73, 1327, 978, -724, +-1491, -530, 1103, 1376, -163, -1104, -643, 52, +785, 588, -219, -32, -512, -1163, 668, 1535, +-57, -405, -720, -1287, 868, 1930, -190, -1024, +-729, -349, 1058, 766, -433, -20, -641, -793, +1205, 706, -745, 38, -289, -479, 952, 347, +-715, -204, -159, 430, 941, -656, -996, 465, +220, -102, 847, 14, -1463, -137, 1293, -12, +-602, 519, -198, -849, 876, 455, -1223, 359, +919, -617, 57, -85, -1046, 787, 1174, -223, +-254, -1294, -942, 1980, 1381, -768, -720, -1063, +-429, 1351, 1134, 263, -972, -1831, 294, 1465, +209, 454, -203, -1889, -69, 1594, 177, -373, +-11, -317, -192, 152, 215, 97, -144, 15, +132, -107, -154, -135, 118, 320, -43, -4, +-12, -525, 74, 679, -197, -379, 358, 130, +-506, -189, 558, 245, -288, 25, -408, -416, +1116, 491, -1094, -269, 190, 170, 751, -355, +-753, 411, -137, 38, 877, -742, -637, 1027, +-292, -591, 902, -152, -647, 439, -12, 40, +328, -710, -197, 728, 24, -60, 68, -324, +-311, -133, 581, 618, -381, -40, -210, -1162, +404, 1376, 167, -175, -767, -916, 557, 532, +238, 557, -727, -666, 609, -374, -315, 1019, +169, -311, 3, -848, -289, 1021, 327, -165, +187, -461, -866, 55, 986, 789, -376, -1023, +-331, 492, 434, 131, -26, -287, -172, 114, +-223, -100, 800, 435, -881, -841, 390, 858, +118, -369, -149, -294, -161, 659, 287, -628, +36, 453, -445, -392, 356, 453, 223, -433, +-592, 143, 163, 427, 694, -935, -1026, 1039, +352, -811, 739, 628, -1248, -481, 878, 48, +-268, 547, -2, -730, 141, 475, -530, -344, +813, 342, -392, 90, -401, -664, 594, 281, +4, 935, -554, -1365, 499, 371, -201, 605, +31, -377, 142, -170, -412, -14, 377, 332, +86, 64, -418, -478, 210, 55, 137, 440, +-170, 9, 67, -669, -65, 309, 4, 564, +194, -618, -268, -17, 79, 205, 191, 170, +-328, -259, 251, -225, 51, 660, -386, -511, +393, -89, 40, 587, -546, -599, 711, 349, +-541, -328, 223, 509, 209, -445, -622, 45, +700, 389, -437, -719, 170, 918, -104, -780, +238, 309, -492, 77, 569, -128, -207, 2, +-271, 177, 359, -389, -124, 363, 18, 142, +-217, -822, 464, 1138, -394, -819, -45, -61, +416, 981, -253, -1174, -231, 530, 269, 212, +300, -517, -700, 558, 320, -379, 343, -286, +-454, 1089, 60, -1106, 157, 87, 84, 976, +-335, -1006, 140, 115, 355, 593, -625, -463, +456, 76, -154, -282, 96, 910, -290, -1012, +375, 271, -114, 475, -240, -424, 360, 23, +-397, -211, 519, 740, -478, -565, 187, -183, +-27, 259, 86, 605, -33, -1195, -243, 691, +521, 338, -605, -956, 452, 1003, -244, -846, +187, 603, -137, -87, -109, -491, 316, 618, +-256, -349, 206, 197, -435, -156, 636, -97, +-343, 280, -357, -23, 820, -203, -672, -247, +278, 985, -53, -1049, -73, 174, 205, 858, +-270, -1157, 327, 759, -357, -360, 117, 191, +287, 76, -353, -378, 64, 299, 55, 40, +146, -48, -313, -330, 191, 556, 77, -331, +-243, -27, 232, 133, -155, -112, 131, 260, +-154, -494, 158, 585, -125, -569, 72, 391, +69, 76, -228, -505, 198, 447, 7, -144, +-67, 14, -48, 68, 81, -193, -50, 131, +77, 22, -27, 19, -143, -9, 190, -212, +-122, 150, 136, 383, -178, -744, 127, 476, +-29, 47, -73, -317, 163, 275, -197, -228, +252, 387, -364, -541, 337, 445, -105, -225, +-140, 16, 301, 349, -426, -719, 490, 592, +-428, -19, 194, -316, 101, 153, -207, 115, +172, -194, -264, 70, 379, 99, -208, -90, +-9, -167, -81, 408, 159, -373, 150, 93, +-529, 291, 531, -530, -319, 313, 188, 317, +-53, -713, -227, 460, 391, -4, -173, -52, +-144, -125, 128, 55, 191, 141, -539, -102, +768, 14, -745, -189, 383, 370, 67, -195, +-311, -181, 455, 455, -639, -531, 599, 293, +-153, 224, -300, -538, 336, 283, -185, 286, +157, -619, -57, 431, -267, 203, 441, -749, +-229, 653, -108, -168, 361, 89, -560, -429, +555, 500, -253, -160, -148, -28, 404, -118, +-429, 259, 231, -279, 88, 288, -347, -211, +415, -28, -266, 263, -27, -353, 319, 343, +-500, -318, 524, 312, -373, -294, 175, 162, +-86, 95, -8, -200, 193, -40, -230, 384, +16, -481, 139, 232, 5, 269, -324, -807, +544, 1055, -510, -789, 161, 219, 388, 226, +-818, -335, 797, 189, -289, 33, -335, -253, +721, 427, -821, -352, 603, -107, -28, 617, +-558, -597, 658, 18, -267, 477, -143, -416, +175, -10, 132, 433, -384, -635, 263, 398, +81, 303, -260, -949, 175, 916, -52, -277, +65, -277, -180, 315, 258, -38, -196, -184, +34, 168, 150, 117, -345, -504, 502, 686, +-490, -541, 276, 308, -35, -190, -36, 92, +-131, 145, 393, -372, -532, 294, 453, 12, +-213, -110, -51, -198, 204, 513, -204, -410, +161, 1, -209, 349, 344, -484, -490, 391, +543, -111, -362, -124, -54, 179, 357, -230, +-286, 366, 98, -301, -158, -44, 341, 270, +-337, -151, 248, -101, -272, 228, 301, -151, +-158, -175, -59, 542, 192, -482, -260, -134, +286, 738, -132, -676, -244, -11, 528, 609, +-387, -510, -11, -141, 279, 590, -290, -352, +83, -254, 186, 616, -180, -423, -232, -154, +608, 608, -526, -497, 196, -40, -29, 402, +58, -295, -110, -26, 77, 293, 84, -435, +-289, 266, 334, 275, -165, -734, 41, 671, +-213, -334, 482, 161, -386, 6, -100, -458, +501, 890, -532, -825, 383, 352, -284, 115, +211, -386, -43, 462, -218, -386, 414, 199, +-316, -14, 19, -10, 113, -268, 37, 645, +-216, -660, 219, 299, -110, -58, -44, 88, +258, 56, -467, -531, 512, 880, -335, -785, +43, 413, 183, 98, -280, -659, 284, 896, +-184, -493, -50, -222, 334, 566, -505, -331, +481, -104, -275, 325, -29, -283, 253, 174, +-288, -116, 247, 28, -235, 144, 186, -238, +-54, 34, -24, 433, -66, -813, 284, 685, +-390, -18, 157, -710, 355, 922, -781, -513, +814, -60, -494, 316, 60, -163, 234, -120, +-280, 235, 172, -176, -38, 105, -78, -17, +92, -164, -40, 285, 74, -127, -152, -88, +31, -77, 278, 469, -447, -425, 303, -239, +56, 860, -397, -806, 463, 235, -173, 224, +-188, -287, 274, 166, -54, -130, -169, 132, +125, -33, 99, -64, -233, -14, 204, 172, +-152, -171, 122, 7, -48, 165, -89, -307, +203, 447, -199, -456, 63, 243, 61, 93, +-93, -409, 136, 642, -213, -680, 151, 451, +55, -132, -236, 25, 305, -64, -344, -46, +344, 369, -210, -679, -40, 784, 234, -583, +-273, 65, 208, 529, -161, -730, 178, 420, +-228, 27, 197, -260, -35, 297, -123, -194, +140, -79, -128, 366, 234, -341, -344, -76, +313, 492, -156, -469, -59, 31, 258, 379, +-303, -449, 134, 280, 108, -61, -262, -164, +272, 331, -159, -246, -30, -79, 206, 288, +-246, -134, 146, -196, -24, 358, -32, -298, +95, 128, -193, 135, 191, -477, 38, 687, +-374, -547, 520, 99, -288, 315, -50, -405, +79, 174, 135, 110, -174, -156, -46, -105, +186, 464, -56, -548, -166, 149, 208, 492, +-53, -750, -156, 334, 352, 276, -518, -447, +536, 199, -281, -42, -85, 115, 276, -121, +-210, -77, 49, 238, -12, -185, 172, 58, +-359, -103, 408, 229, -269, -144, 1, -192, +205, 421, -105, -286, -229, -14, 407, 219, +-296, -322, 84, 348, 137, -173, -405, -164, +604, 377, -519, -266, 65, -56, 510, 349, +-700, -425, 304, 154, 274, 301, -465, -518, +176, 281, 248, 104, -425, -275, 260, 218, +72, -62, -316, -182, 308, 396, -5, -352, +-396, 72, 562, 153, -397, -133, 44, 18, +279, 28, -369, -24, 166, 79, 103, -185, +-203, 231, 147, -174, -16, 105, -109, -77, +57, -58, 233, 376, -490, -600, 364, 476, +55, -181, -315, 23, 197, 19, 53, -128, +-146, 247, 74, -219, 55, 152, -242, -181, +404, 212, -406, -101, 213, -25, 41, 21, +-219, 16, 193, 80, 11, -225, -236, 259, +294, -189, -140, 148, -127, -138, 310, 28, +-294, 179, 183, -226, -124, -55, 106, 457, +-79, -556, 83, 249, -98, 121, 61, -232, +80, 141, -226, -61, 297, 27, -304, 47, +323, -92, -258, -36, 68, 279, 117, -448, +-124, 444, 37, -271, -13, -62, 58, 407, +-74, -455, 37, 144, -35, 101, 77, 80, +-112, -406, 88, 357, -120, 37, 147, -310, +-27, 283, -239, -221, 288, 242, -23, -173, +-298, -23, 279, 74, 10, 161, -327, -443, +509, 428, -580, -103, 429, -290, 23, 497, +-555, -411, 773, 102, -525, 123, 126, 35, +117, -461, -111, 642, 98, -280, -110, -320, +121, 660, 21, -600, -128, 274, 163, 126, +-14, -369, -164, 234, 357, 141, -382, -296, +253, 7, 51, 404, -317, -493, 389, 277, +-243, -84, 84, 30, 1, 61, -77, -275, +73, 446, 26, -361, -206, 63, 197, 250, +-79, -383, -90, 267, 49, 59, -3, -363, +-22, 333, -70, 68, 61, -491, -104, 516, +130, -163, -167, -156, 48, 162, 29, -28, +-11, 89, -145, -311, 197, 395, -28, -204, +-202, -23, 220, 58, 74, 46, -303, -136, +338, 161, -130, -120, -8, -9, 141, 160, +-101, -218, 96, 159, 24, -102, -37, 94, +30, -75, 205, 9, -382, 66, 400, -124, +-83, 215, -256, -314, 425, 288, -263, -72, +-54, -155, 254, 185, -205, -56, -55, 10, +241, -138, -323, 251, 194, -160, -93, -80, +-91, 233, 138, -158, -196, -9, 47, 66, +-34, -19, 84, 49, -265, -176, 143, 133, +104, 214, -351, -545, 214, 447, 107, 30, +-344, -421, 188, 416, 186, -138, -382, -133, +285, 219, -20, -99, -117, -104, 206, 228, +-158, -229, 228, 179, -251, -149, 376, 98, +-330, 6, 279, -71, 17, 19, -244, 54, +422, -41, -234, 24, -66, -123, 395, 215, +-368, -57, 85, -304, 233, 510, -245, -341, +17, 6, 157, 148, -171, -24, -1, -185, +112, 258, -190, -157, 106, -17, -129, 164, +63, -276, -41, 354, -132, -328, 127, 133, +-82, 118, -140, -232, 200, 149, -178, -11, +-44, -22, 147, -70, -170, 236, 83, -350, +-77, 277, 141, -2, -159, -311, 64, 481, +126, -484, -158, 346, 134, -70, -46, -228, +102, 316, -56, -125, 69, -103, 12, 125, +68, -32, -56, 35, 45, -107, 229, 56, +-448, 117, 523, -221, -206, 154, -141, 8, +290, -174, -101, 285, -136, -254, 167, 24, +33, 252, -295, -343, 326, 195, -221, 11, +11, -146, 64, 240, -204, -292, 218, 170, +-178, 127, -120, -327, 228, 190, -112, 131, +-280, -238, 351, 8, -136, 301, -238, -366, +295, 162, -104, 66, -173, -116, 238, 29, +-122, 45, -1, -79, 65, 159, -73, -224, +139, 108, -108, 191, 97, -412, 11, 370, +14, -194, -24, 105, 164, -117, -88, 111, +-61, -56, 305, 11, -212, 7, 6, -27, +182, 16, -28, 67, -163, -136, 221, 51, +-53, 123, -80, -158, 58, 24, 42, 41, +-139, 91, 117, -250, -63, 231, -87, -130, +124, 130, -203, -177, 162, 85, -176, 126, +11, -233, 94, 129, -247, 45, 188, -86, +-204, -30, 226, 200, -378, -306, 287, 304, +-20, -186, -319, 19, 387, 75, -249, -36, +95, -11, -77, -105, 200, 326, -255, -411, +256, 243, -106, 0, 28, -93, 118, 13, +-159, 66, 296, -55, -225, 25, 89, -49, +190, 12, -110, 236, -161, -572, 491, 641, +-395, -271, 107, -273, 246, 604, -392, -588, +402, 345, -208, 9, -110, -354, 358, 468, +-309, -220, -63, -206, 355, 420, -441, -279, +253, 0, -120, 203, -117, -343, 240, 468, +-346, -420, 139, 64, 55, 388, -282, -533, +211, 273, -56, 93, -281, -284, 442, 239, +-364, -22, -126, -274, 589, 446, -733, -295, +464, -82, -87, 366, -176, -410, 302, 361, +-191, -291, -61, 48, 359, 410, -239, -720, +-202, 517, 773, 101, -821, -654, 477, 825, +171, -634, -553, 210, 736, 331, -513, -764, +207, 801, 209, -414, -393, -117, 435, 466, +-251, -547, 54, 455, 102, -265, -109, 17, +-4, 231, 143, -390, -241, 382, 133, -164, +49, -193, -305, 510, 335, -520, -285, 86, +104, 646, -143, -1276, 214, 1368, -356, -761, +205, -270, 16, 1170, -397, -1486, 631, 1140, +-713, -354, 335, -596, 297, 1369, -891, -1546, +918, 876, -361, 412, -445, -1626, 1002, 2078, +-990, -1522, 455, 254, 410, 1089, -1046, -1848, +1156, 1651, -545, -622, -282, -710, 1015, 1691, +-1164, -1871, 853, 1150, -69, 163, -675, -1462, +1172, 2084, -1011, -1708, 394, 583, 443, 690, +-923, -1562, 892, 1767, -342, -1297, -325, 378, +721, 632, -647, -1361, 276, 1628, 39, -1411, +-213, 780, 198, 135, -92, -1009, -206, 1440, +421, -1249, -405, 684, -104, -130, 703, -260, +-1025, 593, 622, -956, 179, 1202, -982, -1089, +1195, 508, -838, 423, 53, -1381, 697, 1956, +-1212, -1810, 1252, 897, -793, 465, -63, -1734, +925, 2401, -1409, -2158, 1374, 1080, -884, 403, +199, -1708, 581, 2379, -1234, -2231, 1645, 1350, +-1477, -52, 743, -1171, 414, 1842, -1341, -1751, +1614, 1069, -983, -177, -22, -558, 793, 960, +-826, -994, 337, 746, 320, -389, -636, 45, +454, 186, 172, -226, -899, 57, 1316, 187, +-1107, -248, 227, -87, 986, 810, -2054, -1635, +2367, 2075, -1688, -1644, 134, 239, 1517, 1629, +-2586, -3124, 2658, 3617, -1973, -2981, 763, 1409, +581, 755, -1805, -2957, 2484, 4436, -2567, -4591, +2113, 3332, -1309, -1041, 85, -1647, 1416, 3952, +-2777, -5055, 3449, 4502, -3145, -2615, 1907, 293, +22, 1645, -2057, -2866, 3503, 3350, -3764, -3102, +2854, 2247, -1152, -1151, -616, 168, 2018, 662, +-2683, -1495, 2594, 2248, -1775, -2562, 683, 2220, +309, -1398, -909, 436, 1223, 492, -1303, -1282, +1251, 1785, -1054, -1865, 690, 1564, -41, -1041, +-794, 482, 1396, -53, -1334, -161, 598, 253, +298, -486, -866, 1003, 855, -1612, -450, 1922, +-171, -1709, 735, 1074, -1156, -298, 1223, -428, +-922, 1057, 183, -1604, 739, 2042, -1615, -2277, +2012, 2171, -1762, -1620, 885, 599, 221, 718, +-1181, -1979, 1704, 2780, -1772, -2900, 1484, 2476, +-996, -1796, 393, 1008, 298, -61, -836, -1051, +1069, 2084, -1018, -2755, 1043, 2983, -1165, -2796, +1203, 2184, -779, -1137, -43, -143, 1045, 1332, +-1751, -2200, 2020, 2697, -1763, -2783, 1135, 2338, +-197, -1360, -748, 157, 1465, 887, -1791, -1584, +1767, 1922, -1385, -1863, 743, 1329, -70, -434, +-497, -499, 970, 1125, -1371, -1252, 1421, 869, +-1035, -148, 332, -595, 280, 1112, -721, -1370, +870, 1455, -779, -1355, 344, 960, 193, -288, +-612, -457, 581, 1074, -187, -1588, -316, 2044, +562, -2368, -492, 2416, 105, -2231, 467, 1935, +-1007, -1480, 1174, 676, -810, 461, 86, -1625, +796, 2470, -1544, -2854, 1893, 2798, -1577, -2351, +821, 1621, 117, -811, -946, 47, 1721, 643, +-2322, -1204, 2678, 1436, -2528, -1189, 1932, 562, +-984, 169, -20, -802, 1061, 1302, -1994, -1639, +2709, 1712, -2999, -1468, 2857, 1042, -2343, -645, +1566, 409, -759, -310, 76, 234, 408, -34, +-845, -382, 1312, 945, -1869, -1446, 2391, 1672, +-2731, -1548, 2647, 1117, -2113, -504, 1068, -131, +241, 635, -1626, -949, 2585, 1128, -2969, -1238, +2636, 1268, -1794, -1179, 754, 1000, -15, -812, +-156, 654, -74, -486, 380, 275, -539, -57, +493, -191, -143, 547, -557, -1069, 1395, 1649, +-2083, -2064, 2438, 2174, -2419, -2032, 2234, 1812, +-1875, -1610, 1443, 1391, -745, -1076, 33, 595, +624, 75, -1142, -912, 1605, 1831, -1988, -2651, +2194, 3186, -2290, -3295, 2291, 2978, -2151, -2336, +1901, 1500, -1505, -598, 1050, -220, -409, 738, +-257, -831, 753, 626, -989, -406, 925, 337, +-841, -334, 679, 240, -607, -35, 427, -197, +-160, 420, -258, -648, 767, 803, -1102, -697, +1103, 253, -690, 369, 124, -904, 299, 1195, +-585, -1212, 669, 930, -709, -383, 518, -210, +-288, 531, 147, -416, -178, 44, 334, 255, +-243, -232, -8, -94, 399, 511, -554, -754, +467, 704, -260, -470, 14, 257, 83, -146, +-130, 12, 84, 303, -65, -752, 152, 1156, +-192, -1389, 326, 1458, -337, -1392, 345, 1163, +-175, -723, -122, 103, 460, 582, -829, -1200, +928, 1595, -881, -1675, 618, 1500, -397, -1238, +267, 983, -137, -670, 79, 179, 108, 457, +-315, -1050, 612, 1430, -890, -1586, 1051, 1570, +-1241, -1390, 1209, 1052, -1072, -599, 618, 102, +-59, 367, -443, -715, 760, 856, -736, -766, +679, 568, -579, -427, 610, 384, -570, -352, +322, 209, 0, 77, -378, -406, 471, 611, +-368, -565, 70, 312, 254, -65, -419, 72, +548, -350, -470, 666, 407, -773, -183, 607, +-118, -302, 434, -13, -687, 244, 662, -337, +-581, 263, 381, -66, -160, -129, -165, 242, +588, -227, -851, 69, 1051, 196, -1079, -466, +1076, 622, -887, -640, 470, 556, -65, -372, +-315, 80, 516, 250, -795, -453, 1007, 426, +-1034, -296, 833, 282, -451, -433, 144, 586, +176, -540, -393, 221, 546, 305, -685, -890, +803, 1334, -987, -1463, 964, 1240, -738, -797, +244, 303, 367, 132, -922, -471, 1349, 702, +-1387, -854, 1098, 1046, -530, -1316, -29, 1513, +487, -1361, -909, 759, 1157, 153, -1205, -1061, +987, 1661, -749, -1772, 606, 1376, -427, -632, +131, -220, 361, 987, -818, -1534, 1199, 1739, +-1353, -1495, 1187, 854, -739, -52, 128, -635, +338, 1073, -649, -1206, 766, 954, -650, -320, +241, -441, 329, 905, -617, -801, 449, 218, +59, 502, -506, -1024, 644, 1142, -517, -783, +197, 45, 128, 777, -388, -1317, 439, 1376, +-311, -1033, 165, 523, -145, -63, 313, -217, +-501, 306, 504, -309, -104, 433, -746, -836, +1803, 1406, -2622, -1825, 2772, 1724, -2185, -1048, +1130, 80, -63, 708, -622, -1014, 874, 891, +-861, -657, 878, 613, -989, -805, 1145, 965, +-1193, -797, 1019, 212, -636, 540, 185, -1011, +34, 826, 188, 37, -729, -1130, 1154, 1786, +-991, -1559, 216, 548, 853, 679, -1743, -1502, +2161, 1610, -2043, -1142, 1520, 549, -905, -259, +420, 356, -55, -489, -394, 180, 1035, 642, +-1621, -1450, 1786, 1501, -1290, -525, 240, -969, +970, 2064, -1840, -2065, 1889, 951, -1054, 697, +-281, -2038, 1362, 2459, -1699, -1897, 1299, 871, +-578, -39, -60, -308, 501, 438, -793, -810, +1016, 1499, -1110, -2024, 914, 1791, -379, -728, +-326, -586, 790, 1341, -755, -1145, 315, 348, +86, 197, 20, 176, -650, -1331, 1351, 2361, +-1476, -2314, 850, 1050, 34, 629, -408, -1617, +-87, 1434, 956, -527, -1328, -187, 717, 129, +455, 526, -1326, -1021, 1358, 753, -699, 184, +57, -1075, 39, 1185, 441, -380, -970, -727, +983, 1251, -402, -774, -297, -268, 447, 903, +99, -503, -894, -610, 1240, 1515, -888, -1554, +245, 825, 156, 59, -144, -555, 87, 498, +-338, -87, 806, -234, -1091, 61, 857, 688, +-314, -1563, -84, 1897, -1, -1350, 355, 212, +-429, 823, -148, -1223, 1199, 947, -1939, -402, +1694, 16, -469, 70, -923, 30, 1507, -112, +-1001, 15, 3, 282, 546, -637, -268, 762, +-427, -484, 787, -40, -485, 447, -116, -486, +461, 227, -298, 33, -36, -44, 122, -251, +112, 673, -362, -923, 361, 787, -231, -334, +253, -146, -495, 390, 657, -331, -384, 61, +-285, 287, 876, -588, -762, 690, -118, -514, +1068, 91, -1154, 445, 100, -884, 1295, 1002, +-1854, -710, 1099, 166, 277, 277, -1165, -334, +1081, 58, -509, 200, 196, -88, -334, -348, +424, 643, 29, -308, -902, -635, 1505, 1546, +-1238, -1719, 211, 968, 800, 228, -1028, -1119, +460, 1207, 187, -636, -161, 74, -545, -155, +1163, 797, -923, -1148, -235, 488, 1518, 883, +-1971, -1812, 1355, 1463, -224, -258, -588, -592, +794, 350, -619, 501, 425, -835, -287, 95, +108, 1099, 28, -1562, 70, 831, -490, 363, +893, -899, -810, 531, 106, -65, 830, 358, +-1337, -1300, 1207, 1854, -728, -1186, 421, -374, +-480, 1570, 598, -1458, -364, 375, -353, 425, +1118, -131, -1392, -796, 884, 1237, 119, -642, +-937, -448, 1013, 1107, -298, -953, -555, 343, +839, 132, -350, -210, -460, 62, 855, 9, +-539, 113, -251, -299, 861, 379, -902, -324, +510, 217, -116, -91, 34, -34, -114, 60, +137, 107, 8, -311, -208, 249, 352, 154, +-544, -512, 815, 428, -1063, -34, 942, -125, +-356, -217, -314, 623, 545, -490, -193, -134, +-183, 492, 73, -37, 452, -714, -708, 645, +286, 495, 376, -1510, -563, 1099, 19, 467, +573, -1518, -477, 985, -296, 360, 890, -911, +-508, 201, -531, 627, 1216, -421, -798, -512, +-289, 821, 1026, 10, -905, -908, 244, 607, +226, 646, -280, -1391, 211, 842, -407, 199, +771, -482, -799, -107, 333, 587, 269, -335, +-429, -133, 75, -1, 387, 664, -531, -1039, +303, 670, -53, 17, 8, -383, -83, 352, +5, -292, 255, 385, -415, -438, 281, 306, +80, -174, -271, 255, -8, -429, 596, 476, +-943, -423, 691, 475, -228, -554, 84, 340, +-237, 242, 130, -758, 418, 750, -869, -372, +646, 264, 136, -647, -692, 871, 438, -275, +382, -712, -923, 892, 691, 85, -79, -1068, +-245, 758, 143, 600, -19, -1441, 156, 777, +-345, 539, 284, -936, 66, 110, -396, 598, +448, -4, -299, -1330, 210, 1848, -265, -927, +324, -389, -286, 697, 137, 107, 218, -791, +-722, 315, 933, 887, -512, -1425, -174, 705, +441, 394, -186, -763, 41, 368, -392, -23, +816, 137, -655, -261, -71, -51, 634, 475, +-513, -377, 89, -192, -144, 547, 633, -375, +-668, 164, -203, -262, 1106, 240, -959, 347, +-29, -983, 611, 745, -179, 256, -483, -784, +398, 84, 299, 990, -633, -1046, 197, 38, +299, 759, -104, -588, -543, 89, 803, -84, +-411, 329, -135, -169, 387, -274, -375, 360, +281, -28, -107, -98, -106, -281, 179, 687, +-5, -557, -246, 26, 288, 355, -79, -391, +-169, 322, 233, -240, -100, -74, -48, 522, +46, -545, 99, 23, -243, 375, 278, -132, +-114, -310, -141, 183, 253, 424, -169, -733, +140, 406, -371, 115, 505, -401, -110, 536, +-546, -686, 770, 630, -383, -260, 16, -86, +-66, 81, 273, 43, -220, -12, -113, 43, +475, -285, -707, 274, 654, 305, -263, -847, +-240, 597, 422, 159, -167, -519, -92, 306, +-93, -97, 589, 173, -698, -213, 142, 28, +430, 74, -246, 122, -440, -297, 601, 55, +70, 391, -709, -482, 491, 131, 231, 156, +-453, 48, -72, -523, 610, 614, -415, -64, +-178, -559, 287, 508, 159, -13, -343, 56, +-182, -673, 724, 760, -639, -57, 226, -173, +-62, -580, 99, 955, 39, -72, -303, -912, +477, 842, -462, -431, 239, 654, 111, -1031, +-291, 714, 120, 29, 18, -458, 241, 399, +-619, -95, 554, -161, -46, 149, -404, 63, +467, -96, -239, -132, 61, 246, -125, 43, +208, -605, -3, 999, -363, -657, 425, -368, +-157, 927, -4, -156, -104, -945, 206, 841, +-178, 193, 201, -672, -232, 242, 100, 247, +81, -377, -92, 427, 26, -468, -124, 220, +338, 347, -374, -823, 66, 623, 450, 153, +-696, -482, 373, -337, 143, 1359, -197, -1146, +-82, -70, -10, 730, 504, -332, -608, -127, +-10, -65, 665, 532, -707, -813, 264, 896, +177, -688, -391, 44, 405, 712, -336, -949, +246, 552, -87, -51, -79, -58, 48, -143, +95, 140, 66, 307, -547, -725, 743, 538, +-348, 16, -127, -279, 257, 225, -260, -367, +402, 725, -468, -741, 195, 249, 250, 276, +-535, -384, 511, 219, -256, -229, 13, 455, +19, -463, 38, 171, 75, -47, -292, 143, +410, 141, -432, -893, 448, 1215, -348, -580, +86, -286, 88, 478, -90, -124, 174, 12, +-491, -376, 773, 674, -732, -459, 406, 29, +-4, 104, -333, 1, 525, 78, -556, -359, +470, 463, -357, -323, 276, 205, -201, -120, +19, -152, 282, 404, -454, -190, 312, -246, +-61, 153, 47, 436, -219, -693, 279, 393, +-167, -124, -15, 87, 247, 110, -505, -453, +578, 538, -358, -321, 70, 17, 95, 235, +-101, -269, 38, -33, -26, 314, 204, -157, +-464, -225, 461, 309, -81, -42, -367, -244, +496, 310, -253, -95, -102, -324, 249, 588, +-93, -341, -103, -239, 103, 512, -61, -271, +211, 31, -315, -211, -16, 403, 568, -106, +-821, -429, 649, 676, -372, -615, 151, 441, +13, -146, -109, -196, 227, 290, -472, -145, +639, 35, -448, -142, 52, 454, 140, -782, +-222, 723, 420, -122, -573, -462, 339, 438, +62, -57, -255, -54, 245, -178, -229, 411, +145, -492, -25, 434, 51, -238, -204, 60, +126, -77, 129, 117, -201, 53, 2, -233, +85, 108, 28, 69, -102, 123, -1, -511, +76, 571, -43, -192, -60, -292, 76, 484, +55, -126, -337, -597, 426, 978, -154, -584, +-258, -139, 331, 513, -185, -397, 157, 58, +-327, 150, 324, 116, -83, -728, -207, 932, +301, -366, -281, -281, 129, 280, 48, 158, +-222, -361, 240, 86, -179, 357, 119, -485, +-246, 19, 461, 694, -515, -939, 139, 423, +351, 315, -521, -560, 219, 255, 46, -38, +27, 377, -384, -931, 541, 957, -386, -243, +-3, -609, 242, 882, -264, -448, 152, -210, +-213, 523, 299, -320, -202, -85, -223, 258, +557, -40, -592, -361, 330, 566, -157, -376, +95, -44, -180, 358, 222, -402, -243, 365, +72, -499, 176, 718, -410, -646, 327, 183, +-60, 278, -206, -405, 119, 353, 128, -352, +-316, 342, 167, -280, 69, 298, -198, -415, +76, 377, 5, -80, -43, -265, 16, 408, +-61, -285, -65, 63, 295, -60, -491, 334, +280, -494, 102, 202, -392, 300, 239, -470, +40, 189, -193, 247, -39, -486, 263, 326, +-199, 186, -280, -647, 606, 581, -534, -9, +107, -493, 102, 434, -99, 98, 7, -572, +-119, 552, 186, -114, -199, -225, 87, 116, +-76, 192, 34, -215, -95, -119, 147, 484, +-234, -602, 89, 408, 146, -69, -431, -91, +529, -86, -523, 268, 223, -124, 112, -109, +-284, 111, 34, -47, 119, 159, 70, -243, +-468, 77, 446, 98, -186, -31, 31, -122, +-221, 120, 270, 1, -122, -81, -153, 19, +190, 180, -123, -387, -32, 416, -9, -247, +91, 39, -123, 100, -152, -188, 369, 226, +-369, -194, 123, 121, -54, -40, 2, -54, +94, 139, -292, -120, 211, 41, -34, -118, +-93, 388, 18, -520, -98, 199, 209, 362, +-248, -566, -15, 217, 220, 219, -267, -277, +103, 108, -114, -140, 255, 303, -422, -197, +260, -138, 16, 156, -188, 293, -18, -610, +260, 266, -317, 425, -34, -745, 425, 478, +-576, -24, 188, -213, 289, 192, -438, -32, +70, -170, 251, 254, -280, -102, 43, -162, +78, 264, -180, -124, 184, -110, -106, 286, +-145, -311, 209, 130, -61, 135, -193, -199, +181, -20, 35, 221, -347, -183, 433, 11, +-300, 103, -3, -205, 135, 354, -171, -413, +161, 266, -210, 12, 105, -299, 20, 527, +-42, -597, -106, 424, 66, -99, 154, -161, +-384, 187, 311, -23, -90, -83, -182, -115, +312, 461, -292, -513, 96, 128, 66, 255, +-109, -248, 20, -28, 66, 183, -164, -102, +126, -109, 19, 269, -152, -261, 34, -13, +214, 365, -364, -532, 319, 359, -197, -10, +89, -278, 0, 274, -3, -103, -98, -35, +178, -11, -148, 55, -2, -77, 147, 157, +-183, -334, 55, 292, 165, 28, -180, -388, +16, 392, 187, -157, -177, -144, 103, 327, +-73, -429, 47, 333, 119, -131, -289, -128, +279, 171, -1, 4, -213, -317, 305, 304, +-150, 36, 72, -448, 45, 437, -92, -240, +228, 118, -244, -278, 178, 289, -3, -56, +-24, -391, -18, 534, 205, -370, -149, 0, +51, 70, 158, 40, 34, -192, -271, 28, +372, 134, 110, -178, -611, -109, 751, 270, +-263, -270, -136, 15, 257, 9, 104, 42, +-191, -112, 171, -186, 184, 398, -196, -407, +191, 43, 28, 82, 4, -108, 45, 44, +11, -242, 125, 169, 0, 19, -37, -235, +261, -93, 0, 406, -162, -476, 465, -10, +-172, 253, -65, -245, 371, -97, -179, 108, +77, -92, 134, -155, -33, 306, 199, -642, +-97, 532, 237, -170, -15, -422, 185, 386, +-67, -99, 152, -257, 174, 0, -159, 201, +195, -324, 101, 20, 6, 16, 6, -133, +294, 102, -69, -298, 74, 65, 296, 129, +-79, -304, 10, -128, 451, 384, -326, -507, +251, 147, 65, -79, 183, -81, -135, 84, +145, -428, 369, 441, -215, -403, 160, -18, +301, 97, -49, -171, 56, -92, 220, 18, +10, 27, 35, -435, 238, 512, -97, -509, +244, -70, 1, 369, 226, -437, -4, -145, +159, 290, 216, -40, -163, -778, 495, 953, +-292, -647, 220, -190, 285, 445, -202, -430, +138, 26, 351, -70, -135, 88, 108, -371, +311, 292, 13, -238, -43, -278, 425, 537, +-133, -656, 86, 119, 226, 119, 26, -156, +57, -246, 74, 56, 296, 315, -127, -831, +264, 585, 62, -200, 117, -318, 258, 245, +-303, -215, 570, 65, -110, -334, -108, 375, +419, -461, -61, 106, 73, 85, 116, -370, +207, 198, 4, -147, 167, -12, 75, -208, +150, 172, 35, -198, 120, -32, 62, -59, +161, 17, -89, -157, 264, 31, 96, -70, +-110, -158, 339, 189, 88, -290, -97, 19, +274, 47, 91, -128, 1, -101, 93, 16, +170, 51, -52, -319, 166, 236, 123, -197, +-93, -73, 330, 107, 43, -193, -198, -53, +564, 138, -195, -203, 2, -141, 355, 257, +-91, -281, -22, -32, 269, 67, -10, -81, +53, -118, 84, 44, 160, -26, 43, -162, +-16, 116, 283, -201, 10, 162, -154, -303, +470, 166, -225, 40, 16, -478, 384, 529, +-196, -356, 83, -51, 166, 13, 121, 169, +-121, -392, 286, 178, -61, -54, 144, -21, +24, -117, -14, -35, 201, 179, 16, -314, +-20, 108, 31, -28, 325, -52, -188, 13, +-35, -259, 573, 423, -480, -434, 212, -33, +320, 415, -288, -582, 228, 253, 23, 29, +63, -197, 23, 8, -21, 86, 293, -112, +-171, -98, 111, 138, 150, -146, -75, 10, +190, -39, -157, -42, 369, 67, -250, -152, +68, 9, 325, 18, -303, 26, 247, -258, +47, 204, 44, 15, -165, -344, 455, 294, +-284, -78, 160, -215, 77, 172, -24, -57, +103, -114, -103, 30, 308, 46, -241, -185, +258, 181, -167, -254, 257, 223, -101, -198, +97, 9, 29, 66, 53, -93, -20, -4, +39, -85, 153, 184, -141, -239, 162, -1, +-19, 157, 18, -123, 55, -138, 77, 130, +-7, 95, 27, -358, 24, 200, 96, 100, +-70, -261, 98, -16, 74, 271, -129, -237, +107, -178, 157, 408, -237, -312, 240, -39, +49, 154, -203, -85, 227, -55, -9, -26, +0, 125, -52, -194, 236, 117, -266, -105, +218, 89, -23, -130, -18, 74, 131, 7, +-228, -190, 385, 285, -327, -262, 172, 46, +132, 94, -201, -115, 131, 31, -64, -86, +245, 172, -415, -185, 459, 39, -180, 13, +-135, 58, 264, -133, -80, -21, -46, 214, +21, -232, 211, 50, -414, 28, 425, 59, +-185, -134, -41, -10, 169, 227, -179, -311, +144, 233, -117, -152, 180, 129, -250, -136, +299, 134, -247, -71, 11, -74, 278, 257, +-374, -340, 257, 252, -72, -99, -31, 65, +-54, -135, 176, 208, -164, -150, -14, 39, +175, 94, -249, -186, 162, 258, -58, -210, +21, 107, -56, -10, 7, 29, 65, -33, +-172, 17, 184, 31, -91, 4, -122, 29, +220, -126, -216, 250, 55, -146, 72, -63, +-111, 237, -26, -140, 77, -23, -56, 165, +-85, -115, 129, 9, -88, 166, -117, -164, +184, 36, -172, 221, 19, -273, 65, 174, +-139, 17, 88, 17, -151, -79, 180, 93, +-196, 113, -6, -224, 191, 261, -382, -135, +273, 79, -88, 77, -197, -171, 283, 269, +-325, -145, 177, 24, -110, 107, 7, -44, +-30, 41, -63, -11, 63, 124, -165, -124, +80, 133, -52, 27, -74, -87, 1, 148, +-15, 17, -106, -143, 110, 305, -243, -218, +226, 126, -264, 35, 67, 25, 8, -37, +-180, 86, 143, 50, -222, -66, 141, 121, +-243, -47, 158, 116, -166, -42, -19, 9, +-1, 153, -108, -102, 22, 83, -132, 46, +38, 13, -101, 27, -33, 30, -90, 47, +36, 19, -172, 36, 49, 27, -44, 37, +-256, 34, 303, 24, -387, 67, 5, -78, +199, 261, -417, -221, 60, 100, 130, 278, +-363, -349, 28, 250, 174, 117, -510, -178, +326, 160, -282, 42, 7, 59, -145, -157, +57, 394, -203, -337, -87, 261, 110, 54, +-372, -167, 193, 293, -277, -157, 36, 217, +-140, -205, -110, 283, 31, -1, -210, -191, +-87, 373, 20, -179, -166, 138, -158, -52, +39, 125, -148, 48, -140, -4, -87, -4, +-26, 111, -136, 220, -159, -447, -45, 479, +-25, 74, -303, -390, 106, 390, -253, 105, +-60, -260, -2, 236, -383, 107, 153, -163, +-141, 251, -287, -54, 6, -15, -14, 192, +-261, 31, -194, -228, 214, 471, -439, -213, +-37, -11, 14, 251, -272, -68, -85, 33, +-68, 38, -124, 195, -242, -194, 45, 260, +-205, -45, -155, -8, -57, 209, -141, -120, +-164, 102, -91, 169, -154, -214, -42, 337, +-305, -158, 96, 121, -294, 96, -45, -75, +-163, 166, -81, -9, -121, 51, -260, 46, +47, 41, -144, 139, -347, -133, 132, 176, +-171, 95, -311, -91, 54, 71, -122, 201, +-246, -145, -50, 132, -54, 59, -341, 25, +135, 47, -253, 57, -276, 1, 232, 118, +-383, 58, -204, -175, 186, 402, -313, -186, +-194, -18, 26, 261, -51, -55, -430, -53, +188, 166, -184, 68, -294, -86, 95, 98, +-194, 134, -153, -84, -139, 57, 68, 161, +-343, -87, -56, 88, 66, 73, -348, -16, +-37, 98, 3, 10, -242, 18, -139, 104, +64, -1, -263, 41, -123, 34, 51, 89, +-248, 42, -114, -128, 34, 320, -230, -127, +-99, -68, -13, 335, -189, -207, -95, 84, +-56, 152, -120, -123, -149, 182, -16, -75, +-127, 95, -185, 28, 101, 64, -293, -67, +-10, 132, -49, 118, -175, -263, -86, 358, +-42, -117, -45, 35, -371, -10, 354, 223, +-483, -186, 101, 131, -135, 68, -12, -40, +-221, 90, -11, -46, -24, 148, -220, -86, +27, 120, -182, -51, 37, 101, -178, 26, +-87, -102, 7, 271, -163, -232, -6, 241, +-232, -124, 159, 120, -273, 25, -80, -65, +104, 204, -351, -192, 194, 267, -332, -193, +132, 186, -221, -51, -4, 48, -71, 46, +-192, -61, 144, 221, -291, -245, 30, 266, +-84, -123, -61, 94, -130, 30, -61, -115, +18, 292, -193, -236, -26, 122, -49, 38, +-77, 56, -85, -62, -125, -43, 65, 328, +-153, -311, -170, 117, 142, 115, -216, 17, +-75, -156, 12, 164, -156, 80, 56, -77, +-280, -110, 169, 355, -197, -241, -104, 24, +93, 178, -291, -153, 182, 167, -285, -138, +51, 151, -115, -43, 10, 64, -210, -90, +53, 127, -61, 56, -169, -180, 23, 198, +-82, 21, -97, -146, -13, 194, -140, -84, +15, 27, -67, 70, -170, -88, 70, 145, +-120, -91, -90, 77, -10, -15, -64, 23, +-144, 39, 115, -41, -278, 94, 50, -69, +20, 114, -220, -92, -38, 85, 128, 8, +-268, -48, -27, 139, 85, -179, -164, 245, +-120, -187, 112, 141, -160, -87, -60, 144, +-36, -109, 17, 20, -201, 176, 62, -261, +-26, 294, -231, -203, 204, 140, -257, -33, +54, -5, -76, 48, -20, -20, -106, 86, +-9, -120, -12, 117, -133, 51, -2, -134, +20, 77, -164, 143, 34, -202, -29, 85, +-95, 140, 16, -192, -93, 129, 47, -10, +-161, 30, 84, -77, -96, 130, -48, -91, +41, 45, -157, 71, 125, -149, -213, 196, +128, -106, -78, 19, -156, 23, 236, 57, +-293, -77, 111, -26, -30, 266, -48, -358, +-93, 184, 140, 215, -168, -474, -34, 411, +160, -85, -231, -124, 59, 79, 27, 118, +-33, -159, -155, 3, 215, 214, -186, -280, +0, 238, 86, -190, -150, 190, 94, -144, +-59, 24, -16, 126, -24, -198, 77, 185, +-150, -125, 106, 61, -57, 3, -4, -35, +-1, 10, -21, 57, -14, -102, 93, 59, +-200, 36, 174, -113, -39, 114, -128, -92, +192, 83, -189, -94, 180, 53, -177, 30, +117, -123, 2, 120, -83, -62, 96, -29, +-47, 23, 54, 19, -84, -93, 109, 61, +-48, 57, -10, -242, 78, 286, -94, -165, +125, -110, -71, 276, 24, -284, 28, 106, +60, 31, -132, -111, 142, 75, -4, -55, +-31, 19, 15, -68, 78, 83, 8, -128, +-82, 68, 187, -50, -113, 6, 84, -47, +27, -12, -40, 70, 102, -161, -4, 93, +0, -34, 29, -44, 129, -9, -136, -29, +130, 70, 72, -166, -66, 59, 69, 52, +80, -169, -5, 60, -7, 38, 138, -119, +-61, 0, 102, 68, 21, -127, -10, -5, +183, 93, -134, -205, 174, 156, -15, -167, +97, 85, 9, -54, 10, -160, 231, 282, +-191, -343, 234, 108, -25, 60, 105, -163, +-3, 21, 91, -12, 121, 26, -105, -157, +254, 100, -35, -79, 27, -31, 176, -3, +5, -53, 46, -2, 90, -43, 170, -2, +-120, -82, 202, 30, 138, -26, -100, -97, +182, 13, 190, 17, -150, -118, 239, 1, +123, 10, -63, -86, 211, -1, 69, -33, +51, -88, 123, 103, 159, -186, -94, 33, +345, -6, -59, -14, 78, -152, 217, 64, +24, 45, 158, -238, -38, 114, 347, -55, +-50, -25, 45, -135, 336, 94, -86, -59, +186, -130, 117, 109, 124, -181, 83, 93, +158, -93, 87, -74, 122, 28, 213, -5, +-95, -139, 369, -16, 34, 117, -12, -221, +343, -17, 66, 128, -29, -208, 345, 12, +36, 10, 86, -72, 200, -14, 118, -88, +84, 64, 199, -128, 112, 25, 48, -61, +293, -48, 40, 55, 54, -206, 313, 153, +72, -135, -35, -73, 436, 107, -70, -167, +127, -18, 313, 65, -27, -127, 158, -96, +253, 202, 28, -294, 130, 51, 261, 117, +16, -293, 190, 128, 141, -3, 150, -151, +93, -8, 185, 103, 151, -214, 89, 17, +160, 72, 191, -174, 112, 29, 19, -47, +411, 25, -120, -126, 245, -36, 208, 144, +-8, -310, 305, 185, -4, -116, 240, -46, +93, 19, 151, -102, 162, 32, 69, -46, +275, -89, -32, 26, 274, 23, 116, -226, +44, 202, 269, -187, 108, 30, 30, -42, +264, -69, 176, 117, -80, -290, 353, 227, +132, -159, -56, -47, 360, 50, 47, -124, +106, 99, 181, -183, 153, 68, 106, -9, +87, -89, 309, -53, -87, 78, 314, -80, +78, -127, 98, 114, 224, -30, 48, -186, +193, 144, 113, -59, 146, -135, 165, 124, +32, -150, 313, 38, 5, -1, 112, -153, +295, 151, -12, -164, 198, 45, 89, -58, +268, -2, -41, -13, 222, -75, 209, 6, +20, 15, 147, -96, 259, -10, 1, 53, +153, -113, 242, 7, 2, 3, 241, -68, +71, 47, 153, -133, 201, 102, 17, -86, +199, -26, 190, -9, 37, 29, 169, -107, +169, 9, 157, 48, 23, -138, 237, 66, +161, -43, 23, -18, 194, -56, 209, 53, +5, -72, 197, -35, 169, 79, 80, -152, +145, 84, 155, -28, 114, -105, 161, 100, +83, -70, 181, -61, 132, 39, 110, 33, +116, -188, 208, 142, 69, -30, 112, -132, +216, 89, 44, -10, 188, -72, 78, -35, +182, 127, 102, -186, 91, 60, 227, 35, +29, -116, 135, 52, 246, -14, -62, -66, +268, 43, 97, -53, 67, 10, 170, -44, +140, 8, 70, 10, 121, -108, 198, 125, +5, -121, 182, 16, 113, 39, 103, -97, +98, 38, 137, -1, 118, -50, 71, -21, +155, 66, 72, -119, 163, 44, 3, -11, +217, 8, 40, -103, 80, 108, 149, -75, +116, -7, -30, -23, 265, 24, 10, -4, +26, -90, 233, 50, 20, 37, 39, -128, +155, 17, 132, 124, -93, -195, 261, 49, +38, 89, -32, -150, 234, 44, 3, 12, +27, -38, 165, -4, 31, -35, -5, 63, +213, -99, -51, 45, 43, -34, 224, 13, +-136, -44, 149, -9, 115, 52, -75, -138, +137, 154, 36, -173, 45, 92, 12, 17, +91, -180, 37, 226, -15, -205, 122, 81, +-22, -22, 27, -6, 100, -43, -55, 26, +78, 19, 37, -149, -10, 203, 29, -192, +53, 65, -3, 6, -38, -22, 131, -11, +-86, -77, 16, 208, 78, -277, -44, 99, +-1, 136, 14, -263, 87, 144, -199, -17, +220, 1, -116, -115, -58, 125, 149, -35, +-132, -92, 25, 59, 1, 3, 36, -32, +-144, -57, 127, 80, -66, -43, -74, -42, +72, 31, -76, -25, 14, 51, -92, -159, +91, 182, -130, -122, 4, 20, 0, -24, +-50, 53, -54, -41, 11, -95, -41, 184, +-56, -167, -24, 23, -8, 77, -85, -112, +1, 88, -74, -116, 17, 152, -114, -169, +2, 93, -3, 3, -163, -87, 86, 92, +-91, -75, -118, 48, 93, -59, -145, 46, +-45, -14, 17, -59, -83, 101, -98, -129, +57, 137, -120, -160, -87, 141, 79, -68, +-191, -38, 5, 74, 11, -22, -186, -73, +60, 72, -63, 44, -155, -218, 92, 318, +-170, -268, 1, 90, -83, 110, -20, -239, +-75, 259, -100, -225, 67, 192, -201, -181, +55, 151, -110, -103, -40, 56, -39, -30, +-104, -22, 11, 103, -102, -165, -64, 138, +-7, -28, -95, -102, -55, 175, -41, -172, +-58, 126, -83, -67, -13, 27, -102, -17, +-30, 18, -55, 23, -103, -81, -3, 127, +-80, -111, -78, 66, -33, -14, -48, -55, +-95, 178, -41, -285, -38, 283, -77, -121, +-105, -89, 67, 225, -215, -215, 42, 134, +-55, -33, -153, -48, 49, 133, -118, -192, +-70, 254, -48, -280, 7, 279, -246, -179, +164, 36, -208, 106, -64, -146, 60, 112, +-213, -37, 49, -3, -125, 30, -45, -11, +-25, -16, -156, 45, 48, -16, -127, -31, +-59, 80, -66, -110, 32, 183, -292, -239, +231, 229, -329, -84, 122, -47, -207, 65, +52, 73, -144, -158, -70, 133, -3, -21, +-112, -5, -89, -25, -22, 72, -56, -39, +-147, 15, -9, -6, 2, 28, -264, -8, +140, 18, -188, -63, -35, 179, -107, -235, +35, 208, -186, -63, -33, -112, 26, 273, +-229, -306, 59, 209, -113, -7, -92, -111, +-22, 110, -117, -23, -29, 24, -93, -65, +-82, 76, -5, 41, -157, -150, 0, 163, +-77, -34, -130, -89, 53, 196, -242, -260, +154, 337, -308, -322, 135, 216, -165, -36, +-88, -84, 31, 157, -176, -177, 25, 189, +-138, -125, 20, 32, -187, 30, 100, 55, +-259, -181, 142, 245, -252, -155, 80, 55, +-151, -27, -1, 108, -140, -172, 75, 184, +-249, -124, 123, 75, -174, -23, -34, 11, +-47, 0, -64, 30, -69, -13, -66, -26, +-23, 71, -68, -10, -124, -99, 60, 183, +-110, -127, -153, 24, 165, 38, -278, 7, +73, -24, -87, -21, -49, 94, -67, -23, +-52, -136, -2, 252, -143, -161, 56, -12, +-140, 78, 33, 50, -109, -195, -50, 208, +40, -65, -176, -36, 49, 9, -70, 97, +-39, -92, -114, -27, 91, 173, -154, -171, +-38, 50, 37, 82, -96, -76, -99, -31, +106, 153, -182, -176, 25, 141, -36, -70, +-76, 22, 7, 62, -104, -148, 55, 228, +-142, -227, 63, 163, -111, -45, -11, -51, +17, 116, -167, -89, 126, 27, -156, 24, +23, 31, -53, -135, 0, 194, -93, -104, +29, -29, -65, 90, -14, -23, -41, -33, +-31, -22, 17, 161, -124, -209, 90, 99, +-130, 94, 36, -166, -64, 96, -9, 40, +-10, -90, -92, 49, 96, 18, -162, -33, +84, 16, -66, 14, -58, -18, 74, 27, +-154, -29, 118, 50, -152, -68, 78, 92, +-56, -85, -73, 47, 102, 11, -146, -21, +38, -17, 15, 70, -112, -63, 100, 23, +-143, -3, 94, 52, -80, -85, -39, 55, +65, 29, -81, -69, -14, 48, 15, -18, +-1, 35, -111, -39, 116, -18, -94, 117, +-18, -164, 52, 126, -92, -55, 50, 31, +-65, -34, 54, 14, -83, 40, 22, -76, +26, 85, -104, -71, 63, 59, -2, -25, +-98, -24, 69, 84, -18, -106, -55, 81, +29, -19, -20, -54, 1, 121, -37, -127, +-8, 68, 52, 35, -111, -79, 60, 44, +-14, 43, -35, -95, 4, 110, -15, -87, +14, 56, -35, -7, 19, -36, -50, 25, +112, 23, -177, -33, 106, -43, 32, 145, +-155, -129, 107, -10, 9, 148, -89, -142, +13, 42, 98, 12, -147, 37, 81, -96, +-22, 67, 22, 2, -60, -12, 20, -46, +87, 75, -184, -15, 165, -89, -60, 140, +-77, -102, 128, 41, -90, -9, -14, 6, +93, 2, -129, -16, 101, 41, -63, -72, +38, 86, -41, -54, 46, -17, -48, 63, +25, -18, 2, -74, -36, 115, 47, -52, +-30, -34, -20, 50, 51, 4, -34, -34, +-32, -13, 83, 99, -89, -142, 63, 138, +-65, -116, 88, 102, -98, -63, 52, 4, +13, 45, -58, -38, 52, 16, -57, 4, +82, -1, -115, 11, 118, -35, -88, 53, +38, -42, 9, 40, -57, -67, 99, 96, +-132, -66, 149, -11, -143, 52, 126, -21, +-70, -31, -13, 9, 86, 88, -96, -152, +48, 111, 3, -13, -7, -32, -23, 4, +46, 28, -43, -10, 27, -21, -17, 25, +-2, -12, 38, 23, -73, -36, 66, 15, +-25, 39, 10, -64, -49, 26, 103, 21, +-91, -13, 1, -59, 102, 131, -152, -144, +115, 131, -62, -104, 40, 72, -65, -6, +75, -70, -39, 108, -23, -81, 57, 21, +-46, 2, 22, 41, -40, -89, 75, 67, +-86, 39, 26, -128, 47, 123, -74, -42, +25, -13, 38, -8, -57, 46, 10, -19, +29, -44, -38, 86, 2, -80, 35, 67, +-52, -74, 20, 63, 33, 16, -102, -116, +125, 157, -87, -112, 9, 27, 38, 19, +-38, -5, -4, -20, 20, 8, -15, 51, +-27, -93, 39, 101, -52, -67, 35, 48, +-26, -42, 7, 17, 10, 50, -58, -125, +97, 172, -121, -159, 71, 102, 5, -16, +-74, -57, 68, 86, -48, -58, 26, 46, +-44, -93, 50, 147, -38, -114, -6, -2, +9, 100, 5, -77, -36, -18, 33, 54, +-14, 23, -38, -125, 64, 144, -64, -59, +0, -47, 74, 73, -123, -10, 85, -66, +-20, 65, -36, 19, 25, -91, -18, 80, +33, -10, -80, -46, 88, 53, -72, -44, +29, 49, -8, -52, -32, 34, 58, 3, +-91, -28, 75, 59, -62, -93, 44, 100, +-42, -46, -2, -46, 56, 107, -105, -90, +65, 35, 9, 15, -93, -23, 106, 9, +-87, 9, 38, -22, 8, 35, -84, -64, +139, 104, -146, -118, 55, 56, 62, 51, +-139, -124, 98, 122, -32, -79, -5, 64, +-35, -89, 81, 89, -101, -57, 74, 30, +-64, -19, 22, -19, 62, 127, -214, -245, +302, 261, -248, -148, 66, -6, 54, 85, +-50, -56, -31, 5, 10, -35, 108, 139, +-216, -202, 159, 136, -26, 21, -74, -121, +44, 94, -3, -5, 9, -27, -76, -5, +68, 37, -2, -6, -81, -44, 70, 65, +-13, -45, -49, 7, 45, 41, -34, -86, +22, 108, -55, -80, 63, 36, -41, -21, +-26, 20, 65, 17, -78, -91, 45, 129, +-22, -84, -4, -3, 7, 50, -30, -13, +34, -62, -30, 95, -7, -56, 4, -7, +25, 40, -66, -43, 44, 59, 16, -106, +-70, 131, 44, -93, 12, 19, -56, 20, +23, -7, 25, -1, -48, -39, 13, 85, +24, -83, -38, 46, -3, -21, 20, 34, +-12, -27, -30, -29, 50, 81, -42, -77, +-5, 46, 18, -26, -10, 39, -13, -48, +-16, 44, 60, -31, -88, 22, 63, -16, +-30, 0, 21, 25, -51, -56, 59, 86, +-36, -94, -11, 63, 31, -2, -40, -54, +48, 88, -66, -108, 72, 108, -59, -88, +35, 50, -28, -20, 20, 5, -17, 26, +-5, -72, 24, 109, -61, -93, 89, 58, +-105, -33, 74, 24, -25, 3, -10, -35, +-2, 38, 11, -2, 15, -9, -64, -40, +72, 87, -10, -63, -72, -17, 86, 61, +-22, -24, -58, -20, 63, 5, 4, 53, +-76, -73, 80, 20, -29, 63, -26, -96, +44, 55, -29, 6, 20, -40, -40, 34, +60, -12, -47, 6, -3, -25, 45, 50, +-41, -43, -15, -13, 78, 82, -98, -97, +55, 26, 18, 78, -78, -109, 91, 33, +-61, 63, 19, -67, -11, -4, 20, 57, +-15, -24, -28, -40, 86, 39, -100, 24, +47, -65, 18, 51, -48, -7, 19, -8, +20, -11, -18, 35, -22, -50, 66, 47, +-77, -22, 46, -14, 5, 31, -47, -17, +56, -7, -51, 18, 51, 1, -68, -42, +68, 82, -38, -61, -21, -40, 54, 166, +-40, -204, 11, 120, -33, -8, 88, 4, +-123, -74, 88, 89, -15, 3, -29, -100, +34, 88, -36, -4, 65, -45, -92, 28, +79, -3, -24, -12, -20, 29, 32, -42, +-35, -1, 58, 90, -88, -137, 81, 94, +-30, -23, -25, 4, 36, -22, -3, 5, +-28, 44, 26, -68, 10, 43, -46, -27, +50, 51, -18, -73, -16, 35, 29, 28, +-25, -48, 12, 39, -12, -52, 22, 93, +-17, -104, -4, 33, 35, 55, -46, -89, +34, 46, -17, 5, 1, 12, 11, -82, +-27, 124, 48, -81, -55, -25, 50, 98, +-42, -83, 50, 8, -59, 38, 52, -20, +-22, -22, -28, 37, 68, -8, -79, -42, +70, 64, -58, -42, 45, -6, -15, 29, +-22, -18, 48, -17, -39, 38, 2, -25, +10, 5, 15, 16, -54, -32, 52, 45, +-2, -36, -54, 1, 59, 45, -22, -73, +2, 65, -25, -26, 58, -25, -44, 48, +-16, -24, 73, -26, -77, 37, 43, 23, +-16, -90, 8, 75, -1, 32, -30, -124, +62, 122, -45, -60, 0, 6, 19, 10, +23, -15, -72, 12, 64, 5, 2, -22, +-50, 10, 17, 24, 60, -32, -97, 14, +58, 0, -12, 6, 21, 8, -60, -54, +53, 69, 22, -5, -86, -80, 69, 76, +4, 20, -26, -102, -32, 97, 86, -43, +-43, 17, -61, -20, 101, 7, -25, 37, +-79, -54, 88, 20, 8, 20, -79, -24, +54, -3, 14, 16, -24, 15, -31, -63, +62, 82, -21, -39, -32, -39, 22, 87, +32, -52, -51, -37, 15, 98, 32, -88, +-28, 30, -2, 13, 1, -9, 47, -15, +-82, 20, 66, 4, -20, -34, 4, 37, +-10, -15, 15, -15, 16, 23, -46, -12, +48, -10, -8, 18, -10, -10, -15, 2, +51, -4, -36, 14, -21, -31, 76, 28, +-60, 16, 1, -80, 30, 102, -2, -37, +-36, -65, 53, 108, -24, -64, 7, -21, +2, 44, -11, 12, 39, -80, -30, 100, +-33, -57, 81, 0, -51, 20, -11, 2, +46, -42, 8, 54, -89, -18, 83, -12, +-2, 16, -54, 0, 59, 9, -31, -52, +27, 59, -36, -9, 42, -50, 3, 39, +-38, 33, 24, -72, 15, 17, -15, 72, +2, -112, 27, 83, -32, -35, -2, 9, +49, -2, -42, -32, 42, 71, -32, -89, +15, 56, 4, 8, -14, -45, 30, 27, +-7, 29, -28, -40, -2, -18, 73, 107, +-70, -141, 26, 64, 52, 33, -66, -70, +11, 23, 47, 18, 15, -2, -83, -49, +77, 70, -21, -53, 3, 37, -22, -34, +72, 1, -32, 66, -62, -119, 89, 91, +-8, 8, -30, -93, 15, 88, 40, -31, +-68, -2, 41, -25, 27, 67, -23, -58, +-13, 2, 23, 51, -3, -63, -6, 38, +34, -12, -15, 8, -24, -6, 25, -15, +11, 55, -11, -73, 20, 36, -4, 31, +-9, -66, -7, 23, 43, 58, -4, -89, +-28, 47, 20, 20, -2, -46, 19, 35, +-38, -46, 100, 86, -110, -97, 47, 39, +15, 56, -18, -103, 37, 64, -19, 5, +3, -43, -26, 33, 71, -17, -45, 13, +22, -26, 20, 22, -47, 13, 21, -65, +34, 93, -2, -63, -22, -13, -4, 69, +52, -53, -67, -22, 70, 69, -7, -48, +-20, -13, -6, 44, 12, -20, 35, -16, +-37, 25, 37, -7, -20, -24, -9, 50, +25, -55, 0, 22, 40, 31, -66, -64, +34, 57, -1, -32, 6, 21, 40, -6, +-75, -42, 85, 100, -84, -120, 66, 84, +10, -7, -48, -61, 46, 88, -42, -62, +44, 28, -42, -18, 95, 11, -93, -12, +36, 4, 32, 13, -63, -19, 86, -16, +-51, 61, 31, -70, -26, 25, -1, 38, +45, -69, -20, 41, 0, 32, -20, -84, +40, 87, -36, -60, 32, 23, 33, 28, +-88, -80, 74, 118, -37, -109, 27, 29, +38, 73, -85, -113, 69, 64, -27, 14, +6, -60, 24, 31, 10, 45, -61, -95, +53, 87, 14, -55, -62, 13, 110, 31, +-94, -48, 18, 42, 43, -30, -41, 1, +25, 18, 27, 22, -44, -98, 9, 129, +9, -87, 7, -17, 39, 150, -61, -218, +36, 144, -21, -29, 10, -15, 48, 23, +-46, -48, -1, 68, -1, -52, 12, 18, +20, 25, 2, -64, -28, 46, 12, 39, +-2, -131, -4, 152, 59, -74, -56, -65, +4, 184, -1, -207, 10, 135, 17, -29, +0, -36, -2, 67, -49, -148, 83, 235, +-61, -202, 57, 59, -30, 76, -23, -183, +64, 246, -79, -167, 40, 8, 33, 82, +-44, -134, 42, 220, -89, -188, 35, 14, +104, 85, -73, -20, -75, -31, 102, 9, +-35, 23, -26, -92, 146, 189, -214, -178, +122, 42, -6, 63, -29, -65, 73, 51, +-118, -54, 92, 10, -18, 43, -17, 12, +21, -117, -31, 92, 48, -10, 15, 42, +-89, -74, 36, -75, 67, 209, -68, -98, +39, -41, -44, 46, -18, -111, 124, 236, +-96, -147, -6, -81, 42, 120, -57, -31, +107, 66, -99, -128, 13, 28, 69, 118, +-101, -129, 119, 81, -120, -100, 75, 89, +40, 66, -109, -242, 82, 200, -48, -21, +82, -49, -58, 35, -53, -133, 106, 246, +-65, -156, 37, -52, -18, 145, -57, -101, +116, 84, -118, -120, 68, 84, 27, 84, +-150, -189, 173, 106, -91, -36, 18, 145, +-4, -185, -27, -48, 99, 233, -141, -98, +82, -63, -48, -39, 96, 189, -113, -103, +27, -89, 40, 107, -104, 14, 206, -33, +-235, -107, 125, 194, -65, -135, 39, 85, +16, -116, -40, 106, -42, -9, 43, -80, +-11, 143, 18, -123, -57, -26, -2, 146, +65, -40, -79, -132, -7, 96, 35, 39, +22, 21, -93, -192, 15, 143, 38, 117, +-3, -191, -82, -83, 46, 300, 27, -123, +-46, -154, -130, 104, 218, 115, -101, -85, +-81, -125, 40, 133, -15, 107, 47, -260, +-54, 152, -125, 5, 247, 74, -244, -234, +9, 122, 156, 144, -92, -130, -131, -153, +87, 234, 54, 3, -88, -159, -114, 46, +179, 82, -75, -7, -126, -94, 70, -9, +55, 195, -102, -184, -46, 28, 53, 10, +1, 75, -95, -64, -8, -41, 100, 67, +-117, -7, -60, 4, 43, -96, 87, 166, +-206, -85, 36, -80, 97, 104, -124, 4, +-27, -8, 19, -137, 34, 150, -95, 29, +-49, -129, 45, 38, 0, 65, -102, -46, +37, 5, -44, -22, -49, 37, 40, 6, +-36, -44, -41, 25, -104, -25, 150, 64, +-92, -58, -96, 8, -1, -15, 73, 38, +-78, 27, -97, -94, 58, 30, -9, 56, +-121, -38, 81, -22, -58, 67, -116, -99, +66, 77, 23, 20, -120, -83, -68, 37, +66, 28, 38, -7, -208, -74, 53, 79, +59, 26, -171, -77, 26, -8, 18, 73, +-44, 44, -166, -167, 135, 78, 0, 87, +-184, -57, -28, -116, 129, 106, -11, 117, +-332, -186, 189, -68, 120, 221, -296, 47, +-16, -308, 109, 52, -3, 378, -213, -321, +24, -119, 106, 275, -151, 41, -77, -337, +124, 200, -173, 138, 4, -179, 21, -76, +-82, 191, -35, 15, -80, -199, 118, 80, +-128, 177, -157, -214, 186, -11, -120, 189, +-92, -76, 5, -155, 48, 190, -157, -49, +-11, -24, 76, -41, -136, 105, -54, -48, +19, -115, 35, 214, -171, -102, -2, -125, +72, 191, -130, -44, -40, -78, 7, -28, +17, 229, -151, -238, -6, -14, 117, 202, +-213, -58, -8, -203, 44, 148, -5, 155, +-168, -229, -11, -92, 139, 361, -198, -145, +-85, -282, 149, 288, -62, 135, -239, -312, +132, -22, 63, 303, -204, -89, -97, -241, +205, 189, -130, 121, -171, -219, 129, -2, +-33, 200, -137, -88, -2, -161, 37, 187, +-31, 47, -220, -209, 202, 73, -73, 159, +-150, -165, -6, -41, 72, 134, -32, 55, +-235, -215, 157, 71, -12, 175, -143, -138, +-63, -160, 199, 337, -256, -193, 28, -88, +11, 154, 22, 52, -220, -209, 158, 99, +-93, 86, -36, -68, -81, -81, 78, 114, +-37, 21, -171, -135, 102, 69, 18, 93, +-166, -119, -4, -29, 96, 138, -107, -85, +-88, 2, 20, -23, 90, 85, -203, -16, +-17, -127, 138, 102, -105, 126, -166, -295, +171, 189, -59, 46, -135, -195, 90, 274, +-118, -370, 111, 437, -188, -340, 51, 82, +47, 221, -148, -397, 32, 399, 6, -412, +8, 553, -186, -660, 146, 505, -25, -194, +-133, 38, 63, -120, -90, 202, 149, -124, +-256, 14, 142, -41, -25, 102, -132, -61, +152, -25, -190, 11, 135, 77, -187, -141, +173, 139, -158, -82, 14, 14, 7, 16, +-10, -29, -39, 47, -37, -56, 33, 14, +-39, 88, -39, -190, 6, 209, 45, -125, +-179, 26, 170, -5, -138, 38, 66, -11, +-133, -83, 105, 145, -10, -51, -182, -134, +192, 201, -112, -58, -9, -96, -73, 68, +164, 61, -163, -47, -61, -154, 208, 322, +-220, -261, 83, 100, -80, -73, 123, 134, +-135, -61, 10, -78, -31, -37, 201, 397, +-404, -579, 354, 343, -179, 15, -45, -145, +226, 151, -514, -346, 768, 727, -896, -961, +787, 853, -624, -551, 451, 302, -345, -198, +186, 161, -18, -75, -134, -96, 139, 219, +-131, -161, 134, 24, -170, -17, 106, 152, +-30, -235, -21, 169, -36, -82, 89, 96, +-98, -132, -1, 47, 65, 84, -57, -70, +-34, -101, 50, 236, -22, -197, -26, 27, +24, 111, -28, -124, 23, 26, -17, 44, +-43, -64, 105, 105, -140, -197, 55, 222, +56, -133, -109, 56, 29, -97, 54, 149, +-103, -51, 83, -139, -49, 186, -28, -49, +77, -57, -106, 18, 78, 61, -84, -73, +103, 58, -142, -43, 91, 26, -34, 15, +0, -81, -15, 159, -32, -188, 103, 121, +-169, 24, 139, -140, -93, 133, 81, -29, +-128, -47, 98, 16, 0, 51, -66, -54, +-10, 13, 62, 13, -24, -34, -15, 105, +-86, -247, 210, 375, -262, -363, 212, 243, +-175, -157, 146, 130, -60, -57, -153, -78, +350, 135, -372, -54, 204, 6, -87, -125, +122, 257, -196, -158, 165, -91, -112, 172, +112, -38, -105, 9, 5, -233, 127, 426, +-171, -354, 109, 204, -56, -225, 96, 338, +-152, -298, 126, 84, -22, 70, -50, -42, +65, -30, -55, -18, 92, 121, -131, -147, +123, 82, -27, 1, -49, -26, 36, -14, +73, 36, -99, 9, 39, -83, 76, 101, +-114, -95, 93, 153, -26, -246, 29, 263, +-51, -166, 64, 70, 27, -97, -65, 189, +38, -188, 64, 61, -52, 36, -8, 14, +77, -131, -19, 169, -38, -104, 67, 85, +4, -175, -12, 242, 19, -148, 15, 3, +23, -10, 4, 161, -21, -252, 95, 184, +-66, -66, 43, 35, 16, -87, 53, 148, +-90, -156, 100, 140, 23, -128, -12, 122, +-56, -111, 168, 116, -107, -130, 102, 112, +-84, -62, 159, -5, -101, 46, 49, -37, +83, 0, -43, 17, -9, -23, 125, 39, +-58, -62, 57, 89, -54, -133, 174, 161, +-79, -158, -23, 138, 148, -155, -43, 211, +6, -204, 8, 70, 173, 102, -202, -131, +196, -8, -39, 126, 51, -94, -5, 26, +4, -74, 182, 158, -202, -120, 190, -21, +-3, 64, 20, 44, -17, -137, 100, 70, +32, 33, -44, 2, 57, -115, 128, 116, +-121, 4, 121, -78, -10, 24, 138, 39, +-156, 9, 165, -102, 25, 70, 30, 78, +-54, -137, 86, 2, 178, 176, -263, -201, +301, 100, -147, -39, 215, 84, -193, -121, +219, 63, -18, 16, -15, 8, 83, -106, +54, 133, 0, -50, 1, -27, 124, 9, +16, 40, -69, -8, 170, -81, -15, 102, +9, -6, 44, -64, 96, -6, -34, 116, +57, -107, 43, 12, 77, 12, -46, 70, +80, -134, 100, 85, -68, 0, 68, -11, +114, -39, -28, 46, -22, 24, 153, -66, +40, 17, -89, 38, 131, -8, 56, -79, +42, 99, -82, -1, 139, -117, 134, 121, +-168, -46, 124, 6, 132, -56, -65, 139, +16, -169, 128, 130, 3, -93, 41, 82, +-25, -55, 155, -21, -2, 68, -56, -29, +166, -27, 22, -18, -40, 130, 71, -158, +90, 34, 38, 120, -118, -168, 245, 148, +-57, -170, 51, 227, -66, -222, 282, 149, +-195, -103, 160, 115, -70, -142, 248, 144, +-221, -126, 221, 99, -81, -65, 192, 45, +-174, -67, 203, 104, -18, -60, 23, -54, +18, 115, 117, -66, -30, 30, 7, -110, +161, 207, -95, -195, 111, 129, 3, -149, +69, 225, 9, -193, 48, 35, 12, 36, +111, 97, -56, -281, 102, 264, -12, -78, +95, -33, -46, -43, 135, 172, -95, -181, +192, 75, -107, -8, 162, 50, -155, -101, +305, 64, -211, 16, 142, -24, 8, -18, +74, 28, -24, 19, 53, -55, 53, 5, +37, 73, -36, -56, 137, -50, -67, 94, +138, 13, -112, -148, 210, 125, -133, 18, +170, -70, -103, -61, 174, 187, -83, -124, +68, -28, 59, 48, 23, 66, -17, -139, +83, 60, 67, 27, -70, 8, 72, -134, +101, 199, -62, -155, 42, 99, 65, -118, +28, 172, 13, -166, -30, 80, 175, -16, +-95, 76, 17, -199, 140, 222, -36, -113, +-24, 19, 114, -46, -3, 90, 39, 0, +-90, -144, 243, 180, -161, -95, 125, 44, +-67, -100, 196, 133, -150, -65, 110, 17, +-37, -113, 226, 265, -316, -283, 326, 167, +-141, -74, 155, 101, -175, -164, 237, 149, +-77, -79, 26, 48, -6, -76, 120, 93, +-26, -41, -72, -29, 185, 47, -50, 2, +-17, -60, 36, 108, 98, -128, -36, 132, +-71, -125, 222, 134, -128, -137, 66, 92, +-6, -8, 114, -32, -76, -26, 51, 108, +9, -119, 117, 96, -144, -128, 143, 179, +-9, -135, 34, 16, -47, 14, 107, 98, +13, -184, -73, 89, 138, 81, -39, -121, +43, 25, -46, -1, 154, 150, -120, -321, +131, 323, -87, -190, 139, 79, -60, -44, +-2, 32, 111, -22, -20, 65, -51, -186, +129, 280, -13, -242, -39, 94, 91, 37, +-14, -80, 51, 72, -62, -84, 147, 118, +-103, -125, 93, 68, -10, 33, 5, -118, +107, 136, -154, -87, 214, 19, -109, 22, +43, -28, 38, 47, 15, -74, 8, 77, +-2, -48, 70, 26, -14, -23, 20, 3, +2, 27, 91, -19, -66, -41, 44, 78, +42, -31, 18, -50, -24, 95, 15, -122, +153, 187, -202, -247, 206, 171, -86, 8, +123, -110, -170, 36, 236, 100, -144, -110, +120, 59, -112, -105, 219, 243, -172, -304, +111, 200, 12, -65, 17, 48, -6, -112, +22, 111, 66, -36, -29, -8, -37, -30, +169, 70, -142, -7, 104, -145, -21, 286, +53, -361, -28, 405, 44, -435, 6, 427, +69, -357, -116, 255, 202, -159, -169, 120, +217, -145, -230, 191, 267, -203, -130, 168, +5, -155, 100, 184, -66, -190, 87, 114, +-134, -6, 224, -31, -150, 4, 33, -9, +83, 93, -28, -147, 36, 67, -61, 81, +190, -140, -169, 79, 128, -10, -48, 19, +114, -21, -150, -71, 142, 208, -16, -232, +-51, 124, 71, -12, -37, 0, 86, -65, +-132, 109, 164, -151, -88, 276, 54, -506, +-26, 745, 66, -876, -6, 898, -26, -875, +91, 854, -40, -816, 36, 719, -3, -570, +7, 446, 46, -371, -73, 307, 66, -191, +1, 41, -32, 73, -26, -129, 160, 210, +-284, -379, 423, 572, -562, -676, 758, 678, +-869, -659, 919, 680, -825, -694, 746, 658, +-640, -587, 581, 528, -456, -486, 341, 431, +-281, -349, 309, 305, -343, -348, 328, 448, +-293, -544, 267, 620, -248, -714, 220, 832, +-145, -898, 78, 803, -9, -536, 18, 174, +23, 184, -69, -528, 117, 829, -46, -993, +-61, 940, 132, -714, -165, 463, 219, -284, +-304, 166, 310, -86, -224, 73, 76, -155, +74, 244, -227, -254, 436, 214, -700, -219, +978, 297, -1132, -402, 1216, 513, -1275, -658, +1332, 842, -1299, -981, 1154, 1007, -993, -909, +792, 747, -589, -574, 340, 413, -127, -274, +-119, 132, 318, 12, -457, -99, 518, 58, +-501, 66, 416, -137, -219, 79, 38, 65, +137, -234, -247, 463, 310, -785, -278, 1101, +184, -1239, -158, 1163, 137, -980, -196, 740, +225, -404, -339, -13, 313, 381, -248, -538, +102, 514, 59, -452, -298, 424, 606, -368, +-826, 233, 971, -89, -943, 46, 842, -128, +-598, 268, 262, -441, 202, 705, -800, -1087, +1325, 1522, -1788, -1836, 2027, 1924, -2190, -1843, +2048, 1689, -1770, -1480, 1305, 1141, -859, -653, +388, 128, 67, 283, -438, -546, 794, 714, +-1042, -837, 1282, 916, -1387, -991, 1479, 1113, +-1494, -1290, 1464, 1424, -1444, -1376, 1350, 1057, +-1221, -503, 836, -135, -463, 685, -6, -1038, +305, 1193, -561, -1137, 598, 809, -480, -245, +221, -383, 134, 898, -456, -1269, 759, 1564, +-864, -1762, 925, 1773, -870, -1622, 794, 1496, +-685, -1503, 587, 1572, -645, -1569, 739, 1512, +-982, -1436, 1030, 1280, -982, -901, 592, 338, +-112, 244, -540, -721, 1163, 1116, -1677, -1445, +1956, 1675, -1950, -1728, 1790, 1638, -1436, -1442, +1038, 1191, -554, -896, 115, 636, 224, -453, +-437, 393, 414, -405, -322, 502, -8, -579, +260, 559, -498, -294, 357, -228, -61, 945, +-441, -1628, 850, 2120, -1183, -2271, 1321, 2128, +-1266, -1713, 1057, 1138, -759, -466, 505, -125, +-319, 578, 176, -842, -88, 1002, -19, -1018, +19, 918, -115, -704, 151, 565, -398, -556, +630, 731, -1069, -958, 1371, 1221, -1653, -1340, +1617, 1254, -1381, -847, 829, 282, -185, 379, +-512, -988, 1079, 1557, -1505, -1917, 1617, 2051, +-1525, -1862, 1146, 1455, -722, -809, 141, 71, +275, 671, -715, -1190, 857, 1507, -953, -1545, +671, 1369, -366, -875, -96, 282, 303, 243, +-438, -426, 269, 347, -67, 30, -324, -553, +630, 1158, -974, -1474, 1025, 1357, -1009, -700, +698, -158, -455, 1045, 9, -1658, 218, 1977, +-461, -1814, 302, 1325, -178, -569, -179, -106, +324, 604, -510, -706, 275, 551, -13, -110, +-495, -315, 762, 678, -1035, -782, 912, 738, +-768, -482, 262, 245, 129, -10, -729, -43, +982, 95, -1274, -72, 1139, 120, -1064, -69, +597, 54, -266, 20, -317, 24, 594, -21, +-952, 104, 844, -165, -718, 369, 249, -490, +-105, 528, -106, -268, -90, -52, 111, 452, +-465, -676, 506, 873, -705, -816, 412, 578, +-261, 1, -239, -595, 410, 1185, -844, -1525, +981, 1789, -1324, -1784, 1197, 1572, -1071, -934, +359, 129, 303, 857, -1311, -1680, 1780, 2358, +-2092, -2517, 1570, 2275, -1016, -1540, 19, 743, +480, 91, -962, -625, 673, 930, -377, -741, +-427, 289, 871, 405, -1449, -933, 1418, 1364, +-1412, -1478, 844, 1428, -418, -1015, -390, 534, +801, 63, -1330, -491, 1266, 952, -1289, -1206, +792, 1304, -528, -932, -141, 361, 379, 341, +-755, -690, 446, 715, -222, -228, -491, -455, +828, 1315, -1349, -1873, 1249, 2034, -1151, -1475, +479, 545, -72, 606, -534, -1412, 578, 1838, +-628, -1619, 25, 1030, 471, -87, -1302, -706, +1508, 1230, -1630, -1118, 997, 671, -522, -32, +-255, -241, 417, 163, -572, 371, 79, -906, +211, 1370, -732, -1422, 698, 1218, -681, -634, +127, 32, 232, 589, -834, -909, 1004, 1112, +-1326, -1089, 1246, 1115, -1440, -1061, 1321, 1155, +-1491, -1172, 1195, 1172, -996, -820, 273, 298, +161, 403, -753, -837, 750, 1001, -727, -653, +157, 50, 254, 805, -850, -1473, 971, 1865, +-1132, -1668, 904, 1117, -835, -222, 338, -638, +133, 1502, -1020, -2110, 1594, 2533, -2193, -2491, +2123, 2112, -1855, -1322, 891, 465, 28, 418, +-1107, -1018, 1516, 1403, -1616, -1372, 988, 1117, +-327, -632, -498, 271, 768, -53, -785, 184, +196, -491, 376, 1024, -1107, -1501, 1392, 1877, +-1581, -1855, 1238, 1544, -868, -908, 132, 229, +394, 499, -1003, -1012, 1110, 1278, -1070, -1048, +531, 500, -97, 230, -386, -659, 355, 661, +-103, -116, -611, -618, 1170, 1302, -1632, -1526, +1533, 1328, -1321, -757, 830, 211, -499, 191, +-36, -307, 448, 360, -1074, -387, 1468, 533, +-1822, -612, 1575, 565, -944, -165, -288, -497, +1433, 1316, -2355, -1872, 2457, 2004, -2034, -1644, +1063, 1121, -205, -600, -511, 277, 650, -75, +-538, 76, 95, -209, 174, 463, -398, -629, +276, 614, -135, -280, -238, -290, 499, 981, +-854, -1433, 961, 1465, -1049, -1059, 906, 560, +-847, -224, 646, 218, -515, -392, 205, 592, +16, -591, -293, 354, 322, 61, -251, -395, +-125, 454, 458, -148, -774, -333, 702, 709, +-427, -640, -206, 29, 849, 1025, -1564, -2148, +2015, 2945, -2261, -3082, 1969, 2441, -1235, -1119, +-8, -549, 1254, 2062, -2248, -2890, 2502, 2758, +-2112, -1803, 1103, 554, -49, 402, -768, -727, +875, 477, -446, 69, -369, -601, 1002, 829, +-1274, -579, 920, -95, -206, 849, -686, -1297, +1262, 1269, -1462, -907, 1230, 459, -915, -148, +604, 48, -454, -131, 239, 208, 72, -104, +-591, -209, 1005, 517, -1146, -571, 770, 276, +-69, 169, -723, -476, 1135, 388, -972, 41, +224, -586, 672, 973, -1342, -1170, 1515, 1177, +-1274, -987, 718, 503, -91, 159, -435, -748, +646, 982, -563, -864, 326, 506, -141, -141, +68, -119, -82, 131, 97, 68, -62, -332, +-47, 368, 196, -112, -275, -292, 221, 480, +-51, -306, -96, -135, 131, 500, 32, -604, +-301, 342, 616, 144, -824, -714, 924, 1071, +-854, -1028, 649, 542, -270, 82, -134, -589, +528, 849, -791, -1009, 964, 1117, -903, -1176, +635, 1103, -198, -931, -27, 674, -91, -469, +651, 350, -1226, -386, 1544, 386, -1259, -175, +547, -363, 408, 944, -1073, -1210, 1258, 848, +-808, -12, 99, -890, 593, 1294, -808, -1041, +613, 326, -91, 327, -254, -640, 339, 551, +-13, -365, -361, 339, 655, -685, -429, 1176, +-174, -1436, 983, 1051, -1256, -132, 833, -918, +301, 1518, -1380, -1515, 1986, 944, -1626, -144, +587, -660, 850, 1192, -1912, -1458, 2365, 1476, +-1998, -1444, 1335, 1340, -548, -1189, 41, 792, +460, -186, -798, -624, 1179, 1319, -1256, -1758, +1245, 1743, -967, -1413, 730, 807, -268, -188, +-157, -384, 648, 716, -747, -932, 656, 998, +-304, -988, 175, 664, -72, -95, 178, -635, +-136, 1105, 204, -1282, -77, 1112, 24, -821, +221, 345, -322, 159, 554, -624, -592, 692, +683, -436, -403, -14, 56, 168, 542, -41, +-815, -289, 912, 429, -507, -481, 121, 391, +415, -287, -687, -119, 1041, 694, -1062, -1317, +1030, 1432, -509, -1033, -30, 140, 804, 674, +-1202, -1220, 1462, 1187, -1108, -840, 673, 252, +-24, 177, -161, -496, 334, 530, -294, -496, +632, 237, -735, 49, 770, -489, -222, 793, +-156, -974, 461, 688, -66, -123, -341, -691, +916, 1157, -867, -1154, 618, 484, 255, 252, +-897, -777, 1444, 700, -1139, -452, 656, 215, +182, -319, -445, 308, 596, -155, -130, -265, +-163, 348, 662, -71, -573, -601, 465, 1010, +95, -1078, -225, 617, 485, -69, -372, -621, +707, 1079, -780, -1374, 1112, 1106, -900, -589, +822, -105, -190, 400, -268, -464, 1113, 246, +-1350, -243, 1484, 307, -817, -593, 407, 595, +197, -373, -156, -262, 330, 696, 14, -824, +-110, 298, 705, 363, -786, -1026, 928, 1141, +-288, -921, -64, 256, 638, 277, -446, -686, +420, 617, 42, -481, 114, 196, -84, -154, +600, 74, -587, -168, 775, 92, -296, -125, +168, 2, 371, 41, -364, -408, 726, 796, +-567, -1180, 780, 900, -439, -211, 467, -718, +33, 1108, -100, -1164, 584, 832, -440, -539, +529, -93, -15, 763, 7, -1417, 315, 1332, +-34, -742, 142, -282, 330, 962, -440, -1350, +960, 1173, -681, -846, 472, 220, 319, 246, +-331, -654, 411, 581, 104, -382, 49, -13, +103, 74, 132, -51, 253, -212, -105, 300, +101, -548, 647, 742, -911, -1135, 1318, 1213, +-919, -1052, 785, 367, -183, 249, 125, -749, +276, 725, -187, -636, 578, 398, -527, -326, +790, 7, -369, 259, 207, -523, 369, 257, +-286, 188, 333, -760, 270, 880, -534, -783, +1065, 363, -837, -72, 603, -258, 243, 289, +-545, -268, 874, -52, -471, 276, 331, -557, +173, 561, -201, -562, 485, 314, -222, -132, +232, -158, 108, 148, 34, -45, 155, -293, +-60, 354, 399, -279, -276, -93, 292, 258, +123, -347, -46, 192, 67, -191, 322, 95, +-224, -41, 197, -255, 264, 447, -332, -623, +558, 484, -364, -302, 418, -109, -79, 453, +-71, -848, 554, 904, -631, -756, 765, 263, +-409, 169, 241, -578, 167, 647, -212, -555, +430, 138, -290, 231, 284, -546, 112, 447, +-305, -145, 596, -386, -333, 735, 13, -957, +591, 837, -697, -620, 670, 169, -246, 234, +155, -539, -33, 279, 211, 350, -135, -1057, +236, 1083, -153, -456, 287, -526, -168, 1048, +169, -986, 25, 439, -8, -22, 204, -140, +-263, -65, 434, 275, -245, -450, 122, 352, +66, -124, 137, -302, -271, 605, 456, -690, +-302, 343, 236, 126, -68, -538, 104, 656, +5, -681, -5, 577, 150, -377, -110, -56, +150, 358, 4, -296, -66, -205, 277, 560, +-314, -431, 350, -184, -54, 668, -318, -778, +844, 562, -995, -410, 774, 220, -22, 166, +-695, -776, 1196, 1093, -1166, -852, 1015, 241, +-783, 78, 693, 48, -408, -306, 51, 175, +403, 284, -551, -746, 530, 845, -324, -672, +290, 375, -286, -161, 362, 35, -321, -52, +380, 145, -457, -282, 588, 289, -474, -131, +218, -140, 86, 291, -112, -250, 48, 87, +-58, -39, 385, 128, -708, -232, 780, 174, +-395, -29, -122, -72, 519, 44, -542, 46, +288, -168, 167, 295, -563, -338, 702, 129, +-385, 329, -261, -729, 903, 692, -1163, -189, +980, -376, -531, 545, 51, -250, 331, -168, +-537, 372, 472, -330, -121, 197, -343, -82, +595, -26, -466, 151, 31, -260, 393, 315, +-584, -310, 481, 229, -283, -91, 126, -6, +-178, 34, 319, -58, -456, 177, 354, -310, +-51, 283, -409, -70, 704, -110, -752, 90, +443, 67, -88, -130, -147, 44, -3, 43, +313, 41, -617, -238, 525, 339, -176, -166, +-316, -154, 497, 329, -458, -114, 194, -320, +-68, 603, -41, -492, 15, 156, -65, 113, +-53, -137, 165, -12, -350, 202, 264, -299, +-93, 232, -206, 2, 236, -246, -146, 326, +-131, -196, 155, 33, -75, 84, -233, -170, +343, 324, -413, -419, 270, 276, -232, 106, +68, -397, -29, 346, -90, -47, -10, -74, +-24, -112, 78, 318, -430, -143, 571, -302, +-516, 580, -16, -405, 430, 82, -691, 36, +434, 88, -125, -45, -312, -311, 413, 747, +-417, -747, 74, 278, 126, 263, -300, -345, +136, 59, -102, 118, 20, 201, -187, -641, +185, 695, -295, -221, 184, -243, -98, 347, +-335, -128, 589, -32, -642, 147, 75, -305, +441, 495, -759, -365, 443, -86, -109, 590, +-259, -723, 296, 561, -461, -273, 420, 101, +-377, 45, -38, -84, 291, 51, -462, 131, +154, -251, 111, 280, -379, -178, 152, 129, +135, -17, -538, -168, 458, 486, -202, -605, +-341, 411, 558, 84, -637, -424, 297, 443, +-46, -124, -247, -91, 101, 79, 102, 161, +-443, -155, 304, -177, -18, 703, -460, -778, +464, 306, -282, 473, -230, -884, 506, 906, +-754, -691, 546, 589, -246, -374, -306, 115, +443, 156, -359, -129, -123, 94, 315, -151, +-388, 407, 64, -441, 144, 325, -458, -121, +436, 139, -376, -86, -12, -54, 177, 366, +-309, -440, 51, 363, 65, -88, -259, -42, +141, 142, -89, -70, -211, 22, 273, 164, +-327, -263, 11, 378, 124, -270, -292, 111, +137, 238, -158, -438, 26, 472, -53, -100, +-135, -236, 72, 394, -119, -142, 32, -14, +-284, 44, 341, 93, -322, 88, -177, -364, +492, 611, -695, -476, 350, 311, -40, -54, +-429, -112, 504, 415, -503, -447, 21, 309, +313, 43, -580, -84, 232, -48, 124, 361, +-536, -393, 377, 268, -122, 157, -396, -454, +534, 604, -633, -325, 301, 104, -105, 47, +-242, 40, 200, 112, -188, -253, -153, 307, +239, 92, -381, -402, 131, 456, -74, -25, +-85, -275, -109, 426, 43, -283, -36, 291, +-282, -212, 237, 134, -166, 215, -254, -430, +332, 551, -414, -276, 118, -69, -62, 571, +-132, -766, 28, 702, -169, -181, 139, -215, +-370, 391, 293, -106, -316, -84, 52, 165, +-82, 50, -24, -137, -125, 275, -32, -231, +-5, 258, -133, -123, -45, 83, 20, 105, +-202, -206, 122, 365, -242, -189, 65, -38, +-56, 294, -186, -153, 115, 28, -178, 44, +-34, 178, -20, -191, -93, 139, -72, 36, +26, 34, -175, 28, 5, -138, 6, 442, +-234, -414, 162, 180, -246, 277, 87, -419, +-141, 385, -66, -85, 37, -42, -137, 203, +-114, -206, 156, 267, -271, -48, -16, -224, +139, 582, -326, -595, 107, 448, -15, -79, +-223, -100, 129, 234, -169, -128, -30, 98, +26, 19, -223, 9, 142, 53, -133, 38, +-192, -65, 281, 187, -394, -116, 150, 97, +-106, -43, 9, 173, -196, -164, 142, 156, +-182, -39, 13, 108, -74, -71, -60, -29, +89, 361, -341, -507, 319, 483, -292, -161, +-33, -89, 140, 322, -297, -312, 182, 275, +-207, -110, 61, 68, -77, 29, -111, 1, +123, -6, -213, 186, 14, -292, 68, 363, +-230, -183, 123, 32, -149, 76, 78, 68, +-191, -167, 82, 216, -34, -67, -151, 17, +78, 16, -83, 19, 20, 128, -221, -241, +285, 297, -359, -141, 174, 77, -105, -93, +-45, 221, 40, -168, -148, 39, 42, 165, +61, -194, -338, 184, 367, -77, -309, 48, +18, 16, 82, -42, -131, 163, -47, -180, +69, 84, -82, 232, -93, -470, 129, 522, +-163, -303, 20, 93, -5, 58, -25, -77, +-98, 142, 101, -194, -122, 258, -16, -173, +54, 42, -126, 114, 24, -65, 32, -126, +-149, 382, 82, -417, -8, 258, -165, 34, +172, -212, -144, 268, -23, -169, 69, 63, +-79, 38, -87, -52, 199, 56, -271, -12, +96, -56, 127, 190, -348, -236, 278, 129, +-76, 130, -186, -257, 179, 136, -33, 187, +-208, -367, 245, 269, -156, 49, -95, -283, +275, 323, -409, -182, 330, 55, -171, 38, +-95, -78, 238, 150, -300, -207, 222, 256, +-177, -262, 117, 249, -99, -183, -3, 117, +90, -60, -202, 55, 231, -24, -246, -56, +168, 172, -60, -220, -123, 205, 224, -161, +-247, 165, 127, -144, -22, 53, -44, 97, +2, -166, 12, 97, -5, 83, -70, -234, +116, 280, -165, -207, 172, 94, -194, 11, +181, -70, -134, 85, -3, -70, 140, 82, +-224, -113, 157, 110, -11, -9, -130, -140, +140, 238, -50, -234, -69, 173, 110, -102, +-114, 54, 114, -37, -151, 75, 167, -130, +-148, 114, 82, 13, -21, -114, -70, 55, +173, 168, -275, -349, 291, 316, -208, -82, +75, -174, 12, 291, -21, -248, 11, 132, +-52, -51, 111, 68, -91, -141, -48, 185, +210, -141, -242, 34, 102, 76, 96, -138, +-179, 143, 131, -115, -30, 64, 1, -3, +-26, -60, 45, 121, -33, -131, 43, 112, +-89, -114, 173, 143, -220, -112, 208, -26, +-94, 180, -69, -162, 243, -77, -309, 359, +262, -434, -130, 239, 61, 73, -54, -308, +87, 398, -45, -362, -20, 223, 108, 2, +-158, -232, 217, 372, -220, -340, 166, 188, +-19, -18, -76, -82, 122, 101, -93, -98, +133, 124, -186, -173, 235, 199, -146, -153, +8, 31, 181, 118, -294, -221, 384, 212, +-323, -100, 190, -67, 14, 226, -82, -322, +83, 312, -19, -197, 71, -4, -100, 247, +110, -497, 37, 644, -144, -589, 237, 288, +-202, 107, 202, -374, -96, 343, -26, -105, +213, -128, -197, 204, 27, -145, 274, 21, +-329, 138, 156, -349, 227, 512, -431, -486, +450, 230, -215, 70, 20, -209, 158, 134, +-160, 8, 140, -98, 39, 108, -169, -135, +325, 206, -302, -313, 278, 383, -173, -363, +171, 217, -80, -14, 26, -164, 131, 242, +-141, -290, 155, 322, -27, -351, -7, 278, +107, -111, -86, -103, 121, 217, -12, -191, +-18, 38, 107, 89, -48, -101, 84, -27, +-76, 146, 213, -171, -228, 78, 258, 27, +-119, -117, 84, 181, -3, -270, 89, 303, +-83, -233, 142, 26, -27, 163, -7, -221, +100, 98, 11, 42, -57, -98, 178, 36, +-120, 15, 152, -18, -92, -23, 148, 11, +-34, 14, -3, -52, 150, 37, -123, -25, +165, 9, -72, -13, 82, -10, 57, 29, +-49, -75, 86, 76, 70, -54, -66, 12, +91, -55, 62, 122, -17, -138, -7, -2, +186, 165, -170, -234, 238, 143, -209, -35, +332, -38, -219, 43, 76, -73, 284, 55, +-401, -13, 449, -39, -207, -17, 78, 106, +131, -153, -142, 61, 231, 91, -131, -255, +159, 304, -71, -261, 157, 97, -61, 40, +23, -124, 193, 125, -198, -168, 236, 230, +-98, -271, 150, 157, -58, 32, 21, -240, +235, 326, -260, -298, 211, 118, 120, 94, +-206, -256, 194, 226, 98, -83, -146, -83, +142, 111, 73, -55, -59, 7, 77, -90, +46, 214, 47, -293, -22, 224, 94, -133, +25, 64, 18, -49, 25, -14, 63, 76, +69, -79, -139, -65, 347, 220, -319, -299, +318, 204, -117, -31, 73, -171, 43, 262, +40, -224, -14, 47, 120, 94, -26, -170, +-7, 149, 219, -131, -265, 77, 339, -2, +-167, -112, 104, 150, -4, -115, 136, 18, +-125, 52, 123, -138, 152, 155, -293, -123, +419, 27, -251, 13, 130, -13, 106, -5, +-166, -52, 297, 78, -248, -39, 277, -53, +-201, 36, 301, 76, -281, -206, 267, 180, +19, -57, -217, -78, 375, 74, -194, 16, +31, -125, 176, 94, -137, 41, 147, -212, +-50, 259, 50, -188, 77, 59, -70, 14, +77, -62, 68, 91, -36, -118, -34, 59, +260, 39, -283, -129, 249, 121, -70, -78, +46, 50, 6, -61, 3, 12, 142, 118, +-208, -258, 279, 271, -193, -162, 189, 28, +-143, 9, 181, 17, -79, -49, -2, 36, +166, -33, -178, -1, 207, 57, -100, -167, +53, 201, 73, -113, -109, -88, 176, 259, +-140, -299, 161, 165, -104, 13, 111, -139, +-32, 130, 7, -74, 79, 45, -66, -82, +77, 75, -8, 16, -22, -112, 85, 107, +-45, -35, -1, -2, 115, -37, -151, 64, +174, -27, -95, -45, 47, 53, 40, -11, +-69, -38, 134, 67, -148, -127, 197, 196, +-178, -213, 156, 97, -46, 99, -48, -263, +151, 288, -175, -184, 200, 26, -147, 51, +91, -27, 15, -64, -57, 137, 54, -166, +24, 149, -50, -104, 35, 31, 30, 35, +-31, -80, 18, 95, -1, -116, 46, 132, +-48, -105, -18, -7, 178, 136, -274, -202, +236, 174, -62, -92, -107, 17, 204, 26, +-181, -67, 129, 100, -80, -124, 75, 115, +-79, -75, 72, 22, -9, 17, -65, -56, +149, 80, -192, -106, 197, 139, -178, -161, +150, 140, -79, -78, -20, -19, 126, 91, +-172, -102, 124, 57, -7, -30, -81, 65, +57, -152, 59, 220, -156, -205, 134, 80, +4, 99, -146, -251, 194, 300, -160, -255, +110, 183, -116, -108, 129, 12, -116, 129, +62, -252, -12, 246, -5, -112, 4, -54, +1, 119, -26, -103, 65, 98, -103, -138, +59, 165, 49, -120, -160, 51, 160, -35, +-67, 64, -55, -41, 107, -77, -96, 191, +61, -185, -58, 67, 55, 32, -33, -31, +-17, -29, 25, 55, 3, -9, -39, -56, +-11, 87, 120, -68, -218, 33, 192, -20, +-75, 33, -55, -28, 80, -32, -19, 110, +-63, -121, 67, 28, -4, 82, -74, -111, +94, 24, -50, 102, -69, -180, 183, 190, +-270, -129, 260, 16, -183, 97, 52, -122, +63, 16, -130, 133, 113, -228, -43, 235, +-78, -193, 171, 136, -213, -50, 142, -53, +-7, 130, -146, -146, 197, 124, -151, -90, +32, 50, 62, -8, -124, -37, 144, 85, +-159, -137, 116, 159, -39, -93, -63, -46, +81, 164, -36, -161, -54, 69, 70, 16, +-33, -22, -49, -8, 81, 23, -81, 2, +43, -69, -9, 153, -50, -191, 60, 118, +-27, 83, -82, -298, 159, 386, -155, -301, +14, 125, 135, 41, -230, -110, 171, 78, +-50, 22, -72, -94, 75, 60, -17, 82, +-62, -211, 46, 212, 33, -79, -166, -68, +246, 127, -273, -75, 196, -39, -78, 162, +-79, -236, 173, 229, -213, -140, 160, 33, +-100, 50, 21, -98, 28, 121, -91, -84, +100, -18, -80, 127, 3, -139, 34, 41, +-36, 83, -16, -142, 36, 130, -34, -84, +-27, 19, 79, 77, -142, -170, 155, 192, +-146, -123, 70, 53, -18, -53, -3, 110, +-41, -154, 49, 144, -33, -84, -21, 4, +11, 94, -1, -180, -4, 237, -82, -231, +166, 167, -207, -66, 126, -32, -19, 98, +-91, -102, 112, 62, -102, -2, 46, -47, +-19, 86, -34, -94, 55, 85, -92, -68, +75, 92, -66, -156, 50, 227, -95, -248, +149, 194, -201, -85, 172, -40, -128, 142, +80, -179, -100, 139, 92, -36, -59, -58, +-50, 104, 120, -76, -164, 19, 127, 48, +-84, -83, -8, 80, 73, -25, -116, -40, +60, 75, -1, -57, -23, 19, -52, -5, +101, 16, -89, -12, -15, -31, 88, 85, +-117, -114, 83, 111, -76, -87, 52, 49, +-29, 7, -58, -42, 114, 50, -148, -36, +112, 16, -70, 24, -11, -102, 80, 202, +-157, -262, 170, 254, -178, -192, 166, 131, +-192, -73, 168, 2, -97, 92, -52, -163, +146, 172, -153, -104, 15, 10, 117, 57, +-173, -34, 38, -59, 160, 158, -306, -164, +245, 55, -60, 97, -124, -196, 152, 194, +-97, -126, 21, 68, -40, -53, 64, 95, +-85, -148, 58, 149, -71, -55, 68, -67, +-66, 116, 2, -21, 29, -125, -28, 182, +-34, -87, 54, -52, -65, 118, 31, -62, +-27, -24, -14, 77, 41, -59, -78, -10, +62, 107, -52, -187, 34, 208, -61, -138, +56, 36, -39, 26, -8, -32, 15, 31, +-18, -54, -16, 78, 46, -49, -106, -30, +124, 119, -109, -160, 8, 156, 91, -128, +-152, 92, 122, -58, -64, 21, -11, 12, +55, -33, -107, 30, 132, 2, -148, -52, +123, 86, -93, -94, 49, 66, -36, -12, +15, -46, -4, 82, -43, -67, 74, 5, +-83, 76, 13, -130, 70, 127, -102, -70, +25, -15, 74, 84, -121, -90, 54, 40, +22, 21, -65, -28, 42, -14, -30, 57, +18, -72, 6, 78, -88, -99, 169, 115, +-230, -82, 209, 48, -182, -45, 148, 86, +-144, -97, 108, 68, -63, -18, -19, -6, +95, 38, -177, -111, 215, 202, -212, -220, +149, 126, -76, 30, -19, -141, 84, 190, +-138, -183, 136, 144, -94, -64, 7, -22, +56, 81, -85, -92, 58, 91, -13, -108, +-36, 124, 51, -98, -34, 39, -18, -2, +64, 7, -79, -17, 33, -11, 17, 86, +-37, -136, -18, 107, 114, 0, -203, -113, +212, 159, -120, -124, -36, 45, 152, 23, +-163, -52, 79, 45, 15, -29, -42, 13, +8, -11, 15, 30, 10, -67, -50, 86, +50, -64, -10, 6, -16, 39, 4, -49, +25, 32, -24, -28, -12, 49, 53, -79, +-57, 86, 25, -70, 23, 43, -60, -26, +79, 18, -77, -9, 63, -15, -38, 54, +6, -88, 18, 97, -22, -56, 13, -28, +-4, 113, 12, -140, -31, 93, 42, -17, +-3, -37, -64, 32, 124, 4, -119, -30, +49, 19, 33, 23, -63, -64, 47, 64, +-16, -33, 23, -5, -53, 21, 67, -17, +-38, 26, -13, -47, 40, 53, -3, -12, +-82, -65, 158, 139, -163, -163, 100, 121, +-8, -49, -37, -12, 19, 43, 43, -51, +-94, 46, 111, -18, -92, -34, 69, 87, +-38, -118, 19, 127, -16, -126, 37, 108, +-27, -59, -16, -38, 91, 129, -145, -136, +130, 76, -51, -20, -32, 21, 75, -52, +-61, 64, 22, -45, 0, 40, 11, -30, +-44, -12, 77, 82, -72, -113, 37, 54, +7, 58, -55, -109, 107, 80, -156, -36, +198, 23, -173, -24, 84, -11, 52, 50, +-144, -42, 166, -22, -117, 62, 65, -36, +-32, -7, 28, -19, -11, 116, -18, -201, +56, 191, -53, -109, 17, 9, 39, 64, +-64, -102, 48, 105, 2, -61, -48, -11, +99, 61, -122, -83, 140, 70, -104, -59, +29, 39, 69, 1, -118, -58, 109, 96, +-52, -91, 15, 43, 7, 3, -16, -32, +47, 48, -80, -56, 84, 60, -35, -45, +-29, 5, 67, 47, -54, -81, 30, 68, +-1, -19, 1, -51, 10, 91, -36, -73, +86, 6, -103, 46, 70, -40, -3, 11, +-47, 3, 44, 12, 15, -5, -69, -60, +113, 131, -119, -156, 112, 126, -94, -76, +65, 43, -8, -18, -40, -21, 68, 49, +-52, -43, 30, 16, -13, -39, 34, 125, +-64, -215, 87, 216, -60, -114, 17, -40, +38, 150, -66, -176, 68, 132, -29, -51, +-30, -37, 98, 99, -124, -118, 104, 96, +-47, -62, 12, 46, -14, -45, 47, 27, +-52, 27, 6, -83, 77, 104, -124, -83, +108, 55, -34, -44, -43, 57, 82, -56, +-63, 22, 24, 37, 3, -81, -4, 106, +-8, -108, 23, 102, -20, -83, 17, 40, +-4, 19, -19, -60, 54, 73, -79, -64, +86, 57, -44, -70, -7, 71, 56, -44, +-69, -8, 69, 44, -59, -45, 63, 26, +-67, -6, 58, -4, -14, 22, -46, -49, +110, 63, -132, -45, 107, -1, -40, 44, +-16, -64, 49, 52, -46, -17, 28, -14, +10, 17, -42, 6, 62, -30, -49, 38, +10, -18, 47, -4, -85, 11, 93, 5, +-62, -20, 13, 14, 50, 10, -83, -49, +103, 64, -89, -52, 74, 12, -51, 30, +41, -60, -14, 52, -14, -9, 35, -53, +-39, 118, 38, -139, -28, 71, 48, 59, +-71, -178, 87, 206, -58, -143, 25, 45, +3, -12, 19, 45, -70, -75, 114, 41, +-92, 47, 23, -135, 64, 167, -104, -143, +94, 84, -37, -17, -12, -52, 56, 96, +-82, -94, 95, 53, -72, -3, 14, -23, +78, 23, -141, -33, 158, 66, -115, -102, +66, 111, -32, -96, 27, 76, -8, -52, +-41, 2, 121, 77, -172, -148, 163, 162, +-82, -116, -5, 48, 61, -1, -55, -37, +34, 80, -8, -122, 9, 115, -19, -43, +58, -54, -96, 81, 145, -25, -155, -66, +126, 113, -70, -84, 42, 22, -51, 20, +90, -31, -95, 32, 60, -46, 11, 55, +-59, -41, 74, 0, -46, 28, 27, -32, +-17, 20, 23, -18, -22, 32, 17, -34, +-3, 6, -6, 24, 28, -21, -49, -11, +50, 27, 6, 14, -99, -83, 185, 110, +-191, -65, 114, -10, 17, 45, -121, -25, +167, -3, -154, 0, 131, 16, -91, -29, +56, 24, -9, -26, -25, 44, 32, -45, +-7, 7, -18, 64, 15, -119, 37, 122, +-97, -79, 123, 24, -81, 18, 16, -44, +37, 38, -23, -2, -31, -49, 83, 67, +-66, -31, 5, -51, 56, 122, -70, -125, +42, 68, 1, -6, -18, -29, 30, 35, +-30, -57, 36, 87, -28, -94, 8, 56, +20, 1, -26, -37, 3, 49, 26, -55, +-32, 77, 22, -108, 3, 108, -12, -69, +13, 1, -10, 66, 8, -105, -2, 114, +-4, -99, 8, 73, -10, -27, 2, -17, +16, 45, -32, -46, 39, 36, -32, -24, +11, 28, 18, -42, -26, 44, 31, -43, +-29, 28, 32, 5, -43, -40, 46, 63, +-29, -41, -18, -9, 67, 63, -95, -80, +83, 64, -37, -37, -23, 23, 75, -7, +-91, -31, 79, 66, -36, -66, -20, 18, +82, 39, -125, -65, 142, 45, -126, 9, +68, -64, 28, 106, -125, -131, 182, 122, +-162, -69, 86, -13, 0, 78, -46, -91, +57, 51, -50, -6, 46, -16, -31, 11, +5, -10, 22, 8, -20, 10, -13, -42, +47, 52, -41, -17, 17, -56, 7, 93, +-10, -52, -3, -25, 5, 71, 6, -50, +-10, -8, -4, 53, 19, -69, -10, 67, +-19, -52, 31, 21, -13, 35, -19, -82, +22, 90, -4, -38, -21, -13, 13, 25, +24, 5, -60, -43, 80, 56, -88, -53, +90, 63, -87, -76, 60, 64, -11, -16, +-38, -30, 56, 30, -39, 16, 3, -52, +25, 40, -34, 3, 29, -40, 3, 41, +-45, -49, 81, 89, -86, -140, 58, 142, +-16, -76, -17, -14, 33, 74, -42, -90, +60, 74, -55, -60, 16, 37, 46, 3, +-90, -41, 84, 46, -38, -18, -8, -10, +37, 2, -50, 19, 73, -20, -84, -23, +63, 62, 10, -52, -103, -14, 156, 94, +-156, -118, 109, 80, -55, -17, 11, -21, +14, 29, -34, -12, 30, -8, -5, 34, +-41, -53, 77, 41, -83, 9, 55, -73, +-14, 98, -19, -62, 23, 1, -16, 38, +0, -29, 3, -3, -4, 27, 4, -57, +3, 85, -20, -116, 41, 109, -52, -57, +24, -19, 24, 78, -82, -94, 88, 86, +-54, -74, -3, 53, 29, -29, -34, 10, +13, -9, -16, 27, 14, -45, -11, 43, +-27, -22, 39, -1, -34, 34, -23, -76, +68, 115, -84, -133, 52, 100, -40, -32, +44, -36, -81, 64, 80, -61, -60, 53, +-3, -48, 32, 37, -54, -10, 34, -25, +-29, 43, 1, -41, 8, 21, -40, -7, +31, 2, -31, 4, -3, -18, -1, 33, +-13, -38, -12, 35, 2, -33, -16, 39, +-10, -44, -8, 47, -9, -25, -19, -9, +19, 42, -50, -73, 38, 82, -45, -72, +-1, 41, 8, 0, -56, -20, 46, 18, +-68, -1, 23, 6, -17, -36, -21, 72, +-10, -86, 10, 67, -51, -29, 26, -14, +-33, 42, -17, -42, 4, 17, -49, 31, +46, -71, -99, 80, 67, -49, -46, -4, +-43, 33, 49, -39, -63, 39, -19, -49, +26, 66, -48, -68, -23, 37, 29, 8, +-70, -41, 27, 40, -57, -8, 17, -19, +-31, 28, -44, -23, 50, 6, -89, 17, +5, -47, 29, 65, -105, -55, 40, 9, +-2, 48, -111, -74, 104, 45, -121, 18, +37, -75, -36, 88, -34, -58, 17, 17, +-89, 15, 74, -23, -129, 21, 76, -19, +-92, 22, 17, -29, -36, 47, -27, -71, +8, 84, -72, -80, 31, 53, -61, -10, +-11, -32, -21, 58, -18, -55, -49, 28, +20, 0, -69, -2, 7, -25, -26, 55, +-50, -63, 23, 42, -77, -17, 23, 1, +-57, -3, -4, 7, -45, -4, 6, -10, +-67, 32, 14, -52, -60, 71, 4, -60, +-58, 16, 15, 36, -52, -64, -37, 35, +32, 40, -127, -101, 83, 118, -120, -74, +36, 9, -62, 46, -10, -71, -26, 73, +-41, -71, 1, 72, -66, -67, 19, 49, +-76, -13, 20, -27, -62, 55, -17, -58, +-10, 48, -66, -23, 6, -9, -26, 46, +-75, -73, 54, 65, -99, -16, -8, -48, +16, 95, -101, -107, 42, 84, -61, -52, +-30, 32, -5, -21, -44, 10, -34, 12, +9, -38, -83, 67, 31, -85, -63, 86, +-34, -61, 26, 28, -103, -8, 56, 0, +-93, -11, 25, 23, -69, -35, 10, 39, +-48, -27, -25, -14, -8, 68, -54, -99, +-6, 90, -23, -46, -51, -3, 16, 27, +-63, -30, -6, 18, -21, 0, -53, -13, +19, 16, -76, 2, 14, -23, -40, 31, +-30, -14, -12, -20, -21, 47, -54, -44, +19, 17, -46, 10, -45, -23, 37, 26, +-91, -37, 22, 61, -37, -84, -29, 82, +-6, -40, -56, -30, 34, 99, -91, -129, +31, 109, -37, -53, -49, 4, 16, 22, +-35, -22, -39, 3, 16, 18, -58, -35, +14, 36, -53, -19, 14, -17, -45, 52, +-21, -60, 2, 43, -34, -19, -33, 5, +19, -3, -52, 7, -21, -9, 31, 4, +-88, 5, 38, -14, -42, 25, -25, -24, +4, 15, -35, -2, 2, -14, -36, 20, +2, -21, -17, 11, -32, -7, 16, -1, +-37, -5, -15, 17, -4, -25, -16, 18, +-32, 10, 8, -50, -17, 87, -52, -89, +62, 48, -90, 19, 27, -78, -5, 110, +-67, -93, 70, 47, -100, -1, 55, -17, +-41, 13, -23, -6, 31, 10, -61, -18, +20, 20, -11, -5, -34, -20, 29, 29, +-43, -16, -7, -19, 33, 63, -82, -103, +69, 107, -52, -71, -21, 11, 42, 45, +-59, -71, 17, 66, -2, -55, -22, 52, +5, -56, -16, 40, 7, 4, -35, -48, +22, 70, -11, -57, -31, 14, 41, 29, +-52, -55, 30, 51, -24, -31, 12, -9, +-13, 39, -20, -50, 50, 34, -84, -3, +64, -25, -22, 35, -46, -23, 77, -5, +-81, 32, 47, -46, -25, 40, 11, -30, +-14, 13, -6, 11, 25, -37, -42, 51, +29, -48, -5, 21, -16, 4, 8, -14, +8, -2, -19, 32, -11, -56, 46, 70, +-78, -53, 59, 14, -9, 44, -47, -96, +73, 114, -66, -87, 37, 34, -6, 13, +-26, -35, 50, 44, -74, -47, 78, 52, +-68, -36, 36, 3, -2, 36, -15, -65, +10, 72, 6, -61, -10, 32, -3, 2, +19, -25, -25, 30, 11, -12, -3, 2, +7, -7, -28, 33, 40, -50, -30, 41, +-2, -2, 36, -35, -55, 46, 43, -11, +-20, -34, -7, 58, 25, -27, -41, -41, +48, 106, -44, -125, 27, 88, 8, -29, +-38, -25, 55, 53, -49, -58, 33, 47, +-13, -33, 3, 23, 3, -25, -9, 36, +19, -41, -29, 31, 34, -13, -18, -5, +2, 5, 16, -4, -20, 15, 22, -30, +-24, 28, 35, 3, -42, -46, 37, 71, +-11, -64, -18, 30, 37, 9, -37, -36, +31, 39, -18, -32, 14, 15, -5, -8, +5, 0, 1, 1, -11, 3, 6, 8, +1, -14, -14, 14, 34, -3, -50, -8, +58, 16, -47, -13, 20, 0, 17, 23, +-49, -39, 63, 45, -52, -31, 22, 10, +21, 12, -50, -32, 68, 46, -58, -61, +32, 67, 5, -53, -32, 16, 46, 26, +-37, -61, 25, 59, 3, -40, -20, -5, +32, 48, -28, -74, 25, 64, -4, -32, +-12, -1, 27, 25, -31, -13, 28, -1, +-12, 24, -3, -20, 16, 7, -6, 14, +-3, -40, 20, 52, -29, -52, 34, 24, +-23, -2, 15, -32, 1, 40, -17, -41, +39, 20, -52, -1, 62, -12, -51, 15, +34, 10, -4, -23, -19, 54, 34, -41, +-26, 31, 14, 7, 10, -32, -21, 54, +24, -62, -8, 42, -4, -34, 20, -9, +-9, 7, -4, -28, 23, 7, -23, -5, +22, -16, 1, 16, -11, 2, 12, 6, +-7, 18, -2, 22, 3, -15, 4, 46, +-4, -21, 10, 13, 2, 10, -10, -28, +30, 26, -31, -56, 35, 25, -12, -29, +-9, -40, 41, 47, -46, -71, 44, 25, +-15, 20, -7, -43, 20, 57, -11, 7, +4, -22, 12, 75, -4, -33, 1, 27, +14, 18, -8, -15, 1, 11, 16, -12, +-22, -11, 33, -27, -16, -13, 7, -19, +13, -18, -22, -17, 37, 3, -26, -16, +18, 2, 18, 35, -35, -24, 49, 54, +-36, 22, 17, -25, 20, 89, -39, -55, +57, 43, -41, -7, 28, -23, 2, 8, +-15, -42, 30, 2, -13, -57, 12, 11, +1, -41, 12, -5, -13, -7, 26, 8, +-20, 0, 8, 32, 22, 11, -31, 12, +40, 47, -18, 0, -10, 21, 51, 15, +-57, -6, 49, -6, -9, 0, -18, -39, +45, 1, -35, -53, 27, 5, 6, -43, +-21, -16, 42, 23, -41, -46, 41, 40, +-11, 11, -11, -8, 42, 55, -55, 20, +58, -15, -28, 76, 10, -51, 20, 52, +-27, -32, 36, 9, -20, -30, 17, -17, +3, -7, -2, -64, 15, 48, -16, -99, +34, 84, -36, -92, 47, 76, -35, -17, +20, -10, 18, 92, -39, -72, 55, 91, +-35, -2, 12, -23, 28, 64, -32, -41, +30, -8, 5, 27, -18, -65, 36, 16, +-11, -27, -3, -25, 38, 1, -38, -21, +44, 10, -10, -16, 2, 22, 30, -5, +-30, 34, 41, -12, -20, 49, 18, -19, +7, 28, 0, -4, 17, 5, -4, -22, +22, 26, -12, -52, 24, 19, -3, -15, +13, -45, 6, 51, 13, -75, 4, 58, +13, -47, 13, 45, -6, -27, 37, 31, +-17, 5, 27, -11, 11, 51, -17, -47, +52, 57, -35, -57, 58, 40, -24, -36, +31, -13, 21, 32, -28, -77, 70, 64, +-52, -42, 56, -12, -2, 50, -2, -57, +38, 51, -8, -9, 17, -6, 19, 48, +0, -50, 26, 61, 13, -48, 0, 32, +36, -12, -5, -10, 16, 6, 34, -8, +-22, -18, 60, 14, -21, -19, 28, 5, +27, 6, -16, -8, 51, 19, -15, -9, +38, 27, 8, -27, 15, 50, 32, -41, +-8, 34, 48, 0, -4, -42, 26, 68, +25, -86, 2, 63, 33, -42, 14, -6, +14, 25, 25, -40, 16, 29, 19, -16, +27, 4, 6, 12, 39, -2, -5, 12, +49, -1, -3, 16, 29, -6, 31, 10, +-2, -3, 57, -7, -12, 10, 50, -28, +15, 31, 9, -56, 61, 47, -23, -43, +61, 5, 13, 20, 9, -47, 61, 46, +-19, -21, 48, 7, 20, 20, 10, -14, +41, 19, 21, -2, 14, -7, 53, 28, +-9, -42, 56, 50, 3, -42, 30, 17, +35, 2, 13, -34, 39, 33, 18, -40, +34, 25, 10, -20, 54, 10, -3, -9, +53, 2, 18, 16, 16, -27, 56, 42, +-11, -27, 62, 11, 3, 28, 35, -47, +37, 54, 5, -39, 60, 9, -3, 15, +52, -37, 13, 38, 34, -36, 26, 14, +26, 0, 39, -20, 7, 21, 52, -9, +2, -6, 44, 23, 28, -22, 12, 9, +58, 26, -6, -48, 54, 66, 18, -51, +24, 26, 42, 5, 19, -19, 30, 15, +42, -10, 14, 0, 39, -9, 37, 12, +1, -19, 70, 11, -12, -7, 52, -1, +29, -1, 6, -3, 62, 3, 5, -9, +30, 11, 52, -4, -2, -10, 55, 24, +20, -19, 14, 13, 53, 11, -3, -9, +50, 0, 23, 21, 18, -31, 47, 13, +9, 26, 33, -68, 37, 79, 6, -63, +49, 15, 18, 20, 24, -49, 36, 55, +14, -46, 37, 31, 23, -8, 24, -10, +33, 35, 21, -34, 28, 29, 28, 3, +23, -19, 29, 27, 32, -16, 20, -4, +25, 13, 39, -11, 2, -14, 54, 21, +5, -28, 29, 1, 51, 6, -14, -27, +69, 18, -2, -10, 30, -5, 45, 16, +-11, -9, 60, 10, 2, 5, 26, 3, +37, -2, 5, 18, 40, -26, 19, 27, +17, -13, 28, -9, 27, 19, 13, -37, +31, 24, 22, -12, 6, -24, 58, 38, +-20, -53, 56, 40, 11, -13, 5, -18, +62, 51, -33, -54, 70, 55, -12, -21, +27, 5, 35, 23, -7, -26, 47, 22, +2, -13, 20, 7, 28, -14, 7, 8, +24, -12, 24, -8, 7, 8, 26, -14, +23, 0, 0, 8, 41, -5, -6, 2, +29, 17, 20, -15, 9, 15, 30, -2, +13, 1, 11, 11, 27, -18, 18, 25, +-4, -33, 57, 15, -27, 1, 39, -38, +27, 50, -38, -54, 85, 30, -50, -4, +49, -25, 22, 35, -25, -35, 70, 33, +-28, -29, 34, 30, 19, -14, -5, 5, +29, 19, 6, -20, 3, 27, 24, -21, +8, 16, 6, -25, 29, 19, -8, -17, +25, -3, 12, 7, 1, -16, 32, 4, +-14, 5, 31, -2, -2, 0, 13, 11, +20, -4, -7, 0, 30, 19, -1, -20, +7, 19, 27, -1, -14, -17, 27, 31, +10, -41, -3, 21, 33, -6, -9, -26, +14, 35, 21, -39, -12, 15, 30, 10, +-3, -30, 7, 37, 15, -14, 5, -9, +7, 30, 19, -30, -5, 24, 15, -4, +16, -8, -13, 14, 34, -14, -10, 5, +7, -5, 25, 4, -21, -15, 32, 19, +-3, -26, 3, 13, 20, 8, -12, -23, +20, 33, 5, -17, -3, -3, 19, 34, +-8, -29, 14, 10, 8, 38, -5, -68, +24, 75, -11, -44, 14, -4, 10, 45, +0, -77, 15, 73, 5, -61, 6, 26, +11, -1, 12, -29, -6, 39, 25, -34, +-7, 23, 9, -9, 23, 11, -21, -15, +37, 21, -14, -3, 12, -23, 19, 44, +-13, -44, 21, 20, 9, 5, -5, -29, +16, 26, 5, -9, -8, -10, 27, 14, +-7, -6, 0, -8, 33, 19, -28, -19, +37, 14, -10, 6, 2, -13, 19, 36, +-10, -37, 12, 42, 10, -22, -3, -4, +12, 39, 5, -54, 0, 52, 12, -31, +-5, 15, 11, 1, 1, -4, 6, 11, +7, -12, -4, 24, 22, -18, -21, 22, +29, -5, -11, 10, 0, -3, 29, 18, +-40, -7, 46, 16, -31, 5, 14, 1, +11, 8, -14, -2, 20, 13, -14, -11, +13, 32, -13, -27, 19, 35, -20, -9, +12, 5, 9, 22, -29, -15, 37, 34, +-39, -8, 21, 16, -3, 8, -16, 8, +19, 4, -20, 22, 5, -7, 0, 16, +-18, 26, 2, -21, -4, 44, -21, -9, +14, 6, -26, 38, -2, -22, 3, 35, +-29, 3, 16, 6, -35, 30, 9, -7, +-19, 28, -14, 8, -1, 10, -28, 21, +0, 13, -27, 10, -8, 25, -19, 8, +-11, 3, -20, 43, -16, -22, -12, 40, +-36, 14, 4, -1, -47, 34, -2, 17, +-35, 1, -22, 35, -12, 17, -42, -15, +-1, 70, -48, -39, -11, 56, -37, 11, +-32, -3, -18, 59, -48, -28, -16, 61, +-41, -14, -32, 32, -26, 21, -45, 3, +-28, 38, -43, 7, -40, 27, -37, 15, +-44, 31, -43, 3, -39, 42, -55, 14, +-36, 14, -53, 38, -40, 5, -55, 24, +-43, 37, -57, 0, -50, 37, -48, 26, +-71, 5, -34, 48, -75, 3, -49, 28, +-55, 35, -78, 3, -36, 44, -86, 13, +-51, 24, -69, 38, -73, 10, -60, 39, +-76, 22, -63, 14, -74, 44, -66, 4, +-80, 43, -68, 21, -80, 22, -77, 35, +-71, 23, -82, 14, -76, 47, -77, 8, +-88, 27, -73, 48, -90, -8, -87, 60, +-77, 14, -100, 19, -73, 43, -99, 19, +-87, 22, -87, 45, -104, 17, -74, 25, +-114, 47, -72, 1, -111, 50, -83, 19, +-96, 20, -106, 49, -80, 5, -120, 48, +-74, 19, -121, 23, -84, 43, -105, 12, +-105, 27, -85, 49, -126, -9, -73, 62, +-132, 17, -81, 11, -116, 66, -107, -6, +-90, 44, -127, 33, -83, 16, -122, 37, +-94, 27, -112, 31, -105, 20, -110, 50, +-108, 6, -102, 41, -115, 30, -98, 18, +-123, 47, -87, 6, -126, 45, -95, 20, +-114, 27, -110, 37, -95, 10, -127, 48, +-80, 10, -131, 31, -82, 33, -126, 16, +-92, 34, -108, 27, -114, 20, -86, 36, +-136, 26, -70, 19, -140, 43, -81, 13, +-110, 30, -117, 31, -73, 13, -144, 41, +-61, 12, -136, 31, -82, 28, -102, 12, +-111, 39, -81, 11, -122, 33, -76, 21, +-119, 26, -82, 22, -108, 30, -99, 21, +-90, 29, -110, 24, -79, 20, -111, 31, +-80, 15, -104, 27, -91, 29, -92, 16, +-98, 27, -86, 32, -99, 4, -81, 39, +-98, 20, -84, 5, -95, 57, -83, -11, +-93, 38, -81, 32, -90, -6, -81, 51, +-82, 0, -96, 30, -68, 28, -99, 6, +-68, 34, -85, 10, -84, 22, -65, 21, +-98, 14, -58, 25, -93, 15, -65, 17, +-78, 20, -81, 20, -63, 15, -89, 23, +-60, 21, -86, 9, -66, 35, -68, 2, +-78, 19, -58, 32, -79, -9, -62, 43, +-69, 5, -68, 11, -60, 31, -67, -4, +-63, 29, -62, 9, -66, 15, -61, 19, +-64, 10, -57, 18, -60, 7, -58, 19, +-59, 9, -59, 17, -54, 10, -63, 17, +-54, 17, -58, 9, -55, 21, -50, 4, +-61, 21, -51, 16, -53, 5, -52, 22, +-47, 1, -52, 14, -46, 13, -51, 5, +-45, 16, -55, 11, -38, 9, -58, 10, +-33, 15, -56, 0, -41, 27, -43, -4, +-51, 21, -33, 8, -46, 1, -41, 21, +-40, 7, -50, 9, -30, 18, -49, 0, +-29, 12, -46, 15, -35, -2, -38, 23, +-39, 0, -32, 7, -38, 23, -36, -15, +-27, 34, -39, -14, -27, 16, -31, 16, +-35, -15, -21, 34, -45, -8, -17, 12, +-39, 16, -26, -6, -17, 13, -38, -1, +-13, 13, -40, 3, -13, 7, -25, 7, +-30, 0, -10, 18, -42, -5, -7, 20, +-31, -2, -15, 5, -16, 14, -32, -4, +-3, 19, -32, -8, -7, 14, -20, 5, +-17, -2, -12, 20, -22, -2, -12, 8, +-10, 7, -15, -1, -10, 9, -15, 9, +-14, 4, -5, 5, -18, 11, -2, 1, +-18, 7, -2, 15, -11, -8, -12, 24, +1, -3, -17, 5, 3, 17, -7, -9, +-9, 16, 8, 6, -20, -5, 16, 26, +-17, -17, 9, 22, -4, 1, 0, -5, +7, 21, -3, -7, 2, 9, 7, 18, +-5, -16, 14, 25, -2, -3, 6, 1, +11, 17, 2, -9, 11, 11, 11, 6, +0, -2, 20, 11, -2, 5, 18, 0, +9, 13, 4, 2, 24, 1, -4, 19, +25, -9, 6, 17, 16, -1, 16, 3, +8, 16, 20, -9, 9, 20, 19, -7, +19, 9, 9, 8, 27, -5, 13, 13, +22, -6, 18, 13, 13, 1, 26, 5, +10, 9, 23, 1, 17, 17, 20, -11, +28, 15, 15, 0, 28, -2, 19, 17, +22, -12, 30, 13, 12, 4, 34, -3, +14, 13, 27, -3, 26, 5, 15, 7, +32, 2, 14, 7, 31, 2, 24, 5, +21, 4, 33, 0, 20, 7, 28, 0, +31, 4, 17, 3, 36, 6, 19, -5, +35, 10, 21, -2, 27, 5, 29, 6, +26, -6, 30, 6, 29, 3, 26, -8, +35, 13, 21, -8, 33, 7, 24, 5, +33, -9, 29, 12, 30, -9, 29, 8, +32, -2, 31, -7, 31, 10, 31, -12, +28, 8, 33, -1, 24, -4, 37, 6, +24, -6, 35, 2, 27, 1, 35, -4, +29, 1, 34, -1, 27, 0, 36, -1, +26, 1, 38, -3, 24, 0, 36, 4, +28, -8, 35, 5, 32, -10, 34, 2, +29, -2, 33, -1, 32, -2, 34, -5, +30, 3, 32, -7, 36, 2, 26, -4, +38, 3, 28, -8, 43, -3, 26, 0, +38, -6, 30, 4, 35, -7, 35, -3, +32, 4, 30, -9, 42, 3, 21, -4, +49, -7, 22, 2, 44, -8, 25, 1, +41, -3, 32, -7, 38, 0, 38, -8, +34, -4, 39, -2, 36, -6, 31, 1, +40, -4, 30, -3, 41, -3, 34, -3, +33, -2, 40, -2, 29, -3, 46, -7, +32, -3, 43, -8, 37, -6, 39, -2, +33, -7, 45, 0, 29, -7, 46, 0, +29, -3, 47, -8, 32, 1, 44, -8, +32, 0, 41, -2, 38, -8, 39, -2, +39, -6, 41, -3, 30, -1, 47, -4, +29, -5, 49, -4, 31, -3, 42, -5, +40, -3, 35, -5, 46, -5, 32, -3, +45, -6, 33, 0, 42, -8, 40, -2, +37, -5, 41, -5, 36, 0, 38, -6, +40, -1, 34, -4, 47, -8, 29, 1, +45, -7, 31, 0, 40, -3, 35, 0, +39, -6, 40, -4, 41, -6, 39, -7, +39, 1, 35, -7, 42, 1, 35, -8, +41, 0, 37, -6, 41, -6, 38, 1, +40, -12, 39, 2, 39, -7, 38, -5, +44, -2, 32, -7, 44, 0, 35, -6, +42, -4, 40, -4, 37, -6, 43, -3, +33, -4, 46, -6, 36, -5, 41, -5, +40, -5, 37, -3, 43, -6, 36, 0, +38, -5, 41, -3, 39, -5, 43, -7, +37, -1, 41, -7, 35, 1, 40, -5, +34, -1, 39, 0, 34, -4, 39, 3, +37, -8, 42, -3, 39, -4, 42, -8, +35, 4, 41, -6, 34, -1, 41, 1, +37, -7, 40, -1, 40, -2, 38, -7, +44, -1, 39, -8, 39, -3, 44, -3, +35, -7, 47, 0, 32, -5, 41, 0, +39, -2, 33, -2, 49, -4, 31, -3, +47, -3, 37, -3, 40, -3, 43, -5, +34, 2, 44, -6, 37, 1, 42, -6, +42, -1, 34, -1, 48, -8, 36, 0, +46, -9, 38, 3, 40, -8, 44, -2, +39, -1, 38, -6, 43, 6, 32, -8, +49, 3, 39, -12, 47, -3, 46, -7, +37, -5, 49, 2, 33, -10, 48, 5, +40, -12, 40, 2, 47, -5, 29, -1, +53, -1, 34, -8, 43, 7, 45, -12, +33, 7, 50, -8, 37, -4, 48, -1, +41, -8, 44, 2, 46, -11, 41, 5, +42, -8, 47, -1, 41, -5, 43, -2, +41, 3, 39, -10, 51, 3, 38, -14, +45, 8, 41, -8, 40, -3, 51, 2, +31, -8, 53, 7, 38, -13, 44, 7, +45, -6, 38, -3, 51, 0, 38, -8, +50, 1, 39, -6, 40, 6, 43, -4, +39, 3, 46, -5, 39, 1, 42, 1, +45, -8, 45, 3, 40, -7, 48, 3, +39, -7, 49, 0, 40, -2, 39, -2, +48, 5, 31, -7, 55, 5, 34, -8, +48, 0, 46, -1, 31, -2, 61, -1, +}; \ No newline at end of file diff --git a/USDK/example_sources/i2s/src/main.c b/USDK/example_sources/i2s/src/main.c new file mode 100644 index 0000000..f12c454 --- /dev/null +++ b/USDK/example_sources/i2s/src/main.c @@ -0,0 +1,326 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "main.h" + +#include "i2s_api.h" + +/** + * @brief Main program. + * @param None + * @retval None + */ +#include "alc5651.c" +/* +extern void alc5651_init(void); +extern void alc5651_init_interface2(void); +extern void alc5651_reg_dump(void); +extern void alc5651_index_dump(void); +extern void alc5651_set_word_len(int len_idx); +*/ +i2s_t i2s_obj; + +#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096 +#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4 + +u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; +u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; + +#define SAMPLE_FILE +#define SAMPLE_FILE_RATE 44100 +#define SAMPLE_FILE_CHNUM 2 + +#define I2S_SCLK_PIN PC_1 +#define I2S_WS_PIN PC_0 +#define I2S_SD_PIN PC_2 + +#if defined(SAMPLE_FILE) +// no sample +// SR_96KHZ, +// SR_7p35KHZ, +// SR_29p4KHZ, +// SR_88p2KHZ +#if SAMPLE_FILE_RATE==8000 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_8000_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_8KHZ + #endif +#elif SAMPLE_FILE_RATE==11025 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_11025_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_11p02KHZ + #endif +#elif SAMPLE_FILE_RATE==16000 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_16000_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_16KHZ + #endif +#elif SAMPLE_FILE_RATE==22050 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_22050_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_22p05KHZ + #endif +#elif SAMPLE_FILE_RATE==24000 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_24000_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_24KHZ + #endif +#elif SAMPLE_FILE_RATE==32000 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_32000_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_32KHZ + #endif +#elif SAMPLE_FILE_RATE==44100 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_44100_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_44p1KHZ + #endif +#elif SAMPLE_FILE_RATE==48000 + #if SAMPLE_FILE_CHNUM==2 + #include "birds_48000_2ch_16b.c" + #undef SAMPLE_FILE_RATE + #define SAMPLE_FILE_RATE SR_48KHZ + #endif +#endif + +#if SAMPLE_FILE_CHNUM==2 + #undef SAMPLE_FILE_CHNUM + #define SAMPLE_FILE_CHNUM CH_STEREO +#endif + +int curr_cnt=0; +#else + +short test_sine16[16]={0, 12539/4, 23170/4, 30273/4, 32767/4, 30273/4, 23170/4, 12539/4, + 0, -12539/4, -23170/4, -30273/4, -32767/4, -30273/4, -23170/4, -12539/4}; +int test_sine24[16]={0, 12539*256/4, 23170*256/4, 30273*256/4, 32767*256/4, 30273*256/4, 23170*256/4, 12539*256/4, + 0, -12539*256/4, -23170*256/4, -30273*256/4, -32767*256/4, -30273*256/4, -23170*256/4, -12539*256/4}; + +extern void wait_ms(u32); + +#include +short remap_level_to_signed_16_bit(float val) +{ + val*=32767; + if(val>32767) val=32767; + if(val<-32768) val=-32768; + + return val; +} + +void generate_freq_16bit(short *buffer, int count, float freq, float sampling_rate) +{ + int pos; // sample number we're on + + for (pos = 0; pos < count; pos++) { + float a = 2 * 3.14159f * freq * pos / sampling_rate; + // convert from [-1.0,1.0] to [-32767,32767]: + buffer[pos] = remap_level_to_signed_16_bit(a); + } +} + +void gen_sound_sample16(short *buf, int buf_size, int channel_num) +{ + int i; + for (i = 0 ; i < buf_size ; i+=channel_num){ + buf[i] = test_sine16[(i/channel_num)%16]; + if(channel_num>=2) + buf[i+1] = test_sine16[(i/channel_num)%16]; + } +} + +void gen_sound_sample24(int *buf, int buf_size, int channel_num) +{ + int i; + for (i = 0 ; i < buf_size ; i+=channel_num){ + buf[i] = test_sine24[(i/channel_num)%16]&0xFFFFFF; + if(channel_num>=2) + //buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF; + buf[i+1] = test_sine24[(i/channel_num)%16]&0xFFFFFF; + } +} + +#if 0 +void test_delay(int sec) +{ + for(int i=0;i<166*1000*100*sec;i++) + asm(" nop"); +} +#endif + +int test_rate_list[12] = { + SR_8KHZ, + SR_16KHZ, + SR_24KHZ, + SR_32KHZ, + SR_48KHZ, + SR_96KHZ, + SR_7p35KHZ, + SR_11p02KHZ, + SR_22p05KHZ, + SR_29p4KHZ, + SR_44p1KHZ, + SR_88p2KHZ +}; +#endif + +void test_tx_complete(void *data, char *pbuf) +{ + int *ptx_buf; + + i2s_t *obj = (i2s_t *)data; + static u32 count=0; + //DBG_8195A_I2S_LVL(VERI_I2S_LVL, "I2S%d %s\n",pI2SDemoHnd->DevNum,__func__); + count++; + if ((count&1023) == 1023) + { + DBG_8195A_I2S_LVL(VERI_I2S_LVL, ",\n"); + } + + ptx_buf = i2s_get_tx_page(obj); + //ptx_buf = (int*)pbuf; +#if defined(SAMPLE_FILE) + _memcpy((void*)ptx_buf, (void*)&sample[curr_cnt], I2S_DMA_PAGE_SIZE); + curr_cnt+=(I2S_DMA_PAGE_SIZE/sizeof(short)); + if(curr_cnt >= sample_size*(obj->channel_num==CH_MONO?1:2)) { + curr_cnt = 0; + } +#else + if(obj->word_length == WL_16b){ + gen_sound_sample16((short*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(short), obj->channel_num==CH_MONO?1:2); + }else{ + gen_sound_sample24((int*)ptx_buf, I2S_DMA_PAGE_SIZE/sizeof(int), obj->channel_num==CH_MONO?1:2); + } +#endif + i2s_send_page(obj, (uint32_t*)ptx_buf); +} + +void test_rx_complete(void *data, char* pbuf) +{ + i2s_t *obj = (i2s_t *)data; + int *ptx_buf; + + static u32 count=0; + count++; + if ((count&1023) == 1023) + { + DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n"); + } + + ptx_buf = i2s_get_tx_page(obj); + _memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE); + i2s_recv_page(obj); // submit a new page for receive + i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback +} + +void main(void) +{ + int *ptx_buf; + int i,j; + + alc5651_init(); + alc5651_init_interface2(); // connect to ALC interface 2 + + // dump register + //alc5651_reg_dump(); + //alc5651_index_dump(); + + // I2S init + i2s_obj.channel_num = CH_MONO;//CH_STEREO; + i2s_obj.sampling_rate = SR_44p1KHZ; + i2s_obj.word_length = WL_16b; + i2s_obj.direction = I2S_DIR_TXRX; + i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN); + i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \ + I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE); + i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj); + i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj); + +#if defined(SAMPLE_FILE) + i2s_set_param(&i2s_obj,SAMPLE_FILE_CHNUM,SAMPLE_FILE_RATE,WL_16b); + for (i=0;i= sample_size*(i2s_obj.channel_num==CH_MONO?1:2)) { + curr_cnt = 0; + } + } + } +#else + // output freq, @ sampling rate + // 6kHz @ 96kHz + // 3kHz @ 48kHz + // 2kHz @ 32kHz + // 1.5kHz @ 24kHz + // 1kHz @ 16kHz + // 500Hz @ 8kHz + // 5512.5 Hz @ 88200Hz + // 2756.25 Hz @ 44100Hz + // 1837.5 Hz @ 29400Hz + // 1378.125 Hz @ 22050Hz + // 459.375 Hz @ 7350Hz + + // Stereo, 16bit + for(i=0;i<12;i++){ + i2s_set_param(&i2s_obj,CH_STEREO,test_rate_list[i],WL_16b); + // Start with fill all pages of DMA buffer + for (j=0;j +#include "PinNames.h" +#include "basic_types.h" +#include "diag.h" +#include + +#include "i2c_api.h" +#include "pinmap.h" + +//#define I2C_MTR_SDA PC_4//PB_3 +//#define I2C_MTR_SCL PC_5//PB_2 +#define I2C_MTR_SDA PB_3 +#define I2C_MTR_SCL PB_2 +#define I2C_BUS_CLK 100000 //hz + +#define I2C_ALC5651_ADDR (0x34/2) + +#define RT5651_PRIV_INDEX 0x6a +#define RT5651_PRIV_DATA 0x6c + +#if defined (__ICCARM__) +i2c_t alc5651_i2c; +#else +volatile i2c_t alc5651_i2c; +#define printf DBG_8195A +#endif + +static void alc5651_delay(void) +{ + int i; + + i=10000; + while (i) { + i--; + asm volatile ("nop\n\t"); + } +} + +void alc5651_reg_write(unsigned int reg, unsigned int value) +{ + char buf[4]; + buf[0] = (char)reg; + buf[1] = (char)(value>>8); + buf[2] = (char)(value&0xff); + + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1); + alc5651_delay(); +} + +void alc5651_reg_read(unsigned int reg, unsigned int *value) +{ + int tmp; + char *buf = (char*)&tmp; + + buf[0] = (char)reg; + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1); + alc5651_delay(); + + buf[0] = 0xaa; + buf[1] = 0xaa; + + i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1); + alc5651_delay(); + + *value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF); +} + +void alc5651_index_write(unsigned int reg, unsigned int value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_write(RT5651_PRIV_DATA, value); +} + +void alc5651_index_read(unsigned int reg, unsigned int *value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_read(RT5651_PRIV_DATA, value); +} + +void alc5651_reg_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec reg dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_reg_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_index_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec index dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_index_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_init(void) +{ + i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL); + i2c_frequency(&alc5651_i2c, I2C_BUS_CLK); +} + +void alc5651_set_word_len(int len_idx) // interface2 +{ + // 0: 16 1: 20 2: 24 3: 8 + unsigned int val; + alc5651_reg_read(0x71,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x71,val); + alc5651_reg_read(0x70,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x70,val); + +} + +void alc5651_init_interface1(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x27,0x3820); + alc5651_reg_write(0x77,0x0000); +} + +void alc5651_init_interface2(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x28,0x3030); + alc5651_reg_write(0x2F,0x0080); +} \ No newline at end of file diff --git a/USDK/example_sources/i2s_bypass/src/main.c b/USDK/example_sources/i2s_bypass/src/main.c new file mode 100644 index 0000000..95f681d --- /dev/null +++ b/USDK/example_sources/i2s_bypass/src/main.c @@ -0,0 +1,80 @@ +/* This is software bypass example */ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "main.h" + +#include "i2s_api.h" + +/** + * @brief Main program. + * @param None + * @retval None + */ +#include "alc5651.c" + +i2s_t i2s_obj; + +#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096 +#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4 + +u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; +u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; + +#define I2S_SCLK_PIN PC_1 +#define I2S_WS_PIN PC_0 +#define I2S_SD_PIN PC_2 + +void test_tx_complete(void *data, char *pbuf) +{ + return ; +} + +void test_rx_complete(void *data, char* pbuf) +{ + i2s_t *obj = (i2s_t *)data; + int *ptx_buf; + + static u32 count=0; + count++; + if ((count&1023) == 1023) + { + DBG_8195A_I2S_LVL(VERI_I2S_LVL, ".\n"); + } + + ptx_buf = i2s_get_tx_page(obj); + _memcpy((void*)ptx_buf, (void*)pbuf, I2S_DMA_PAGE_SIZE); + i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback + i2s_recv_page(obj); // submit a new page for receive +} + +void main(void) +{ + int *ptx_buf; + int i,j; + + alc5651_init(); + alc5651_init_interface2(); // connect to ALC interface 2 + + // dump register + //alc5651_reg_dump(); + //alc5651_index_dump(); + + // I2S init + i2s_obj.channel_num = CH_STEREO; + i2s_obj.sampling_rate = SR_44p1KHZ; + i2s_obj.word_length = WL_16b; + i2s_obj.direction = I2S_DIR_TXRX; + i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN); + i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \ + I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE); + i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj); + i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj); + + /* rx need clock, let tx out first */ + i2s_send_page(&i2s_obj, (uint32_t*)i2s_get_tx_page(&i2s_obj)); + i2s_recv_page(&i2s_obj); + + while(1); + +} diff --git a/USDK/example_sources/i2s_tx_and_rx_only/readme.txt b/USDK/example_sources/i2s_tx_and_rx_only/readme.txt new file mode 100644 index 0000000..050edb4 --- /dev/null +++ b/USDK/example_sources/i2s_tx_and_rx_only/readme.txt @@ -0,0 +1,15 @@ +Example Description + +This example describes how to use i2s by using mbed extend api + +Using TX only and RX only mode. +RX will fill buffer until full then switching to TX only mode to play buffer content. + +1.Plug ALC5651 shield to Ameba HDK + +2.Run the main function. + +3.Plug earphone to Green phone jack + +4.Plug audio source to Red phone jack + diff --git a/USDK/example_sources/i2s_tx_and_rx_only/src/alc5651.c b/USDK/example_sources/i2s_tx_and_rx_only/src/alc5651.c new file mode 100644 index 0000000..1ee3447 --- /dev/null +++ b/USDK/example_sources/i2s_tx_and_rx_only/src/alc5651.c @@ -0,0 +1,183 @@ +#include +#include "PinNames.h" +#include "basic_types.h" +#include "diag.h" +#include + +#include "i2c_api.h" +#include "pinmap.h" + +//#define I2C_MTR_SDA PC_4//PB_3 +//#define I2C_MTR_SCL PC_5//PB_2 +#define I2C_MTR_SDA PB_3 +#define I2C_MTR_SCL PB_2 +#define I2C_BUS_CLK 100000 //hz + +#define I2C_ALC5651_ADDR (0x34/2) + +#define RT5651_PRIV_INDEX 0x6a +#define RT5651_PRIV_DATA 0x6c + +#if defined (__ICCARM__) +i2c_t alc5651_i2c; +#else +volatile i2c_t alc5651_i2c; +#define printf DBG_8195A +#endif + +static void alc5651_delay(void) +{ + int i; + + i=10000; + while (i) { + i--; + asm volatile ("nop\n\t"); + } +} + +void alc5651_reg_write(unsigned int reg, unsigned int value) +{ + char buf[4]; + buf[0] = (char)reg; + buf[1] = (char)(value>>8); + buf[2] = (char)(value&0xff); + + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 3, 1); + alc5651_delay(); +} + +void alc5651_reg_read(unsigned int reg, unsigned int *value) +{ + int tmp; + char *buf = (char*)&tmp; + + buf[0] = (char)reg; + i2c_write(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 1, 1); + alc5651_delay(); + + buf[0] = 0xaa; + buf[1] = 0xaa; + + i2c_read(&alc5651_i2c, I2C_ALC5651_ADDR, &buf[0], 2, 1); + alc5651_delay(); + + *value= ((buf[0]&0xFF)<<8)|(buf[1]&0xFF); +} + +void alc5651_index_write(unsigned int reg, unsigned int value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_write(RT5651_PRIV_DATA, value); +} + +void alc5651_index_read(unsigned int reg, unsigned int *value) +{ + alc5651_reg_write(RT5651_PRIV_INDEX, reg); + alc5651_reg_read(RT5651_PRIV_DATA, value); +} + +void alc5651_reg_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec reg dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_reg_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_index_dump(void) +{ + int i; + unsigned int value; + + printf("alc5651 codec index dump\n\r"); + printf("------------------------\n\r"); + for(i=0;i<=0xff;i++){ + alc5651_index_read(i, &value); + printf("%02x : %04x\n\r", i, (unsigned short)value); + } + printf("------------------------\n\r"); +} + +void alc5651_init(void) +{ + i2c_init(&alc5651_i2c, I2C_MTR_SDA, I2C_MTR_SCL); + i2c_frequency(&alc5651_i2c, I2C_BUS_CLK); +} + +void alc5651_set_word_len(int len_idx) // interface2 +{ + // 0: 16 1: 20 2: 24 3: 8 + unsigned int val; + alc5651_reg_read(0x71,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x71,val); + alc5651_reg_read(0x70,&val); + val &= (~(0x3<<2)); + val |= (len_idx<<2); + alc5651_reg_write(0x70,val); + +} + +void alc5651_init_interface1(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x27,0x3820); + alc5651_reg_write(0x77,0x0000); +} + +void alc5651_init_interface2(void) +{ + alc5651_reg_write(0x00,0x0021); + alc5651_reg_write(0x63,0xE8FE); + alc5651_reg_write(0x61,0x5800); + alc5651_reg_write(0x62,0x0C00); + alc5651_reg_write(0x73,0x0000); + alc5651_reg_write(0x2A,0x4242); + alc5651_reg_write(0x45,0x2000); + alc5651_reg_write(0x02,0x4848); + alc5651_reg_write(0x8E,0x0019); + alc5651_reg_write(0x8F,0x3100); + alc5651_reg_write(0x91,0x0E00); + alc5651_index_write(0x3D,0x3E00); + alc5651_reg_write(0xFA,0x0011); + alc5651_reg_write(0x83,0x0800); + alc5651_reg_write(0x84,0xA000); + alc5651_reg_write(0xFA,0x0C11); + alc5651_reg_write(0x64,0x4010); + alc5651_reg_write(0x65,0x0C00); + alc5651_reg_write(0x61,0x5806); + alc5651_reg_write(0x62,0xCC00); + alc5651_reg_write(0x3C,0x004F); + alc5651_reg_write(0x3E,0x004F); + alc5651_reg_write(0x28,0x3030); + alc5651_reg_write(0x2F,0x0080); +} \ No newline at end of file diff --git a/USDK/example_sources/i2s_tx_and_rx_only/src/main.c b/USDK/example_sources/i2s_tx_and_rx_only/src/main.c new file mode 100644 index 0000000..2a64ef2 --- /dev/null +++ b/USDK/example_sources/i2s_tx_and_rx_only/src/main.c @@ -0,0 +1,94 @@ +/* This is RX only and TX only example */ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "main.h" + +#include "i2s_api.h" + +/** + * @brief Main program. + * @param None + * @retval None + */ +#include "alc5651.c" + +i2s_t i2s_obj; + +#define I2S_DMA_PAGE_SIZE 768 // 2 ~ 4096 +#define I2S_DMA_PAGE_NUM 4 // Vaild number is 2~4 + +u8 i2s_tx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; +u8 i2s_rx_buf[I2S_DMA_PAGE_SIZE*I2S_DMA_PAGE_NUM]; + +#define RECV_PAGE_NUM 50 +u8 recv_buf[I2S_DMA_PAGE_SIZE*RECV_PAGE_NUM]; + +#define I2S_SCLK_PIN PC_1 +#define I2S_WS_PIN PC_0 +#define I2S_SD_PIN PC_2 + +u32 count = 0; +void test_tx_complete(void *data, char *pbuf) +{ + i2s_t *obj = (i2s_t *)data; + int *ptx_buf; + + if(count < RECV_PAGE_NUM){ + ptx_buf = i2s_get_tx_page(obj); + _memcpy((void*)ptx_buf, (void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], I2S_DMA_PAGE_SIZE); + i2s_send_page(obj, (uint32_t*)ptx_buf); + count++; + }else{ + count = 0; + i2s_set_direction(obj, I2S_DIR_RX); + i2s_recv_page(obj); + } +} + +void test_rx_complete(void *data, char* pbuf) +{ + i2s_t *obj = (i2s_t *)data; + int *ptx_buf; + + if(count < RECV_PAGE_NUM){ + _memcpy((void*)&recv_buf[I2S_DMA_PAGE_SIZE*count], (void*)pbuf, I2S_DMA_PAGE_SIZE); + count++; + i2s_recv_page(obj); + }else{ + count = 1; + i2s_set_direction(obj, I2S_DIR_TX); + ptx_buf = i2s_get_tx_page(obj); + _memcpy((void*)ptx_buf, (void*)recv_buf, I2S_DMA_PAGE_SIZE); + i2s_send_page(obj, (uint32_t*)ptx_buf); // loopback + } +} + +void main(void) +{ + int *ptx_buf; + int i,j; + + alc5651_init(); + alc5651_init_interface2(); // connect to ALC interface 2 + + // dump register + //alc5651_reg_dump(); + //alc5651_index_dump(); + + // I2S init + i2s_obj.channel_num = CH_MONO; + i2s_obj.sampling_rate = SR_16KHZ; + i2s_obj.word_length = WL_16b; + i2s_obj.direction = I2S_DIR_RX; + i2s_init(&i2s_obj, I2S_SCLK_PIN, I2S_WS_PIN, I2S_SD_PIN); + i2s_set_dma_buffer(&i2s_obj, (char*)i2s_tx_buf, (char*)i2s_rx_buf, \ + I2S_DMA_PAGE_NUM, I2S_DMA_PAGE_SIZE); + i2s_tx_irq_handler(&i2s_obj, (i2s_irq_handler)test_tx_complete, (uint32_t)&i2s_obj); + i2s_rx_irq_handler(&i2s_obj, (i2s_irq_handler)test_rx_complete, (uint32_t)&i2s_obj); + + i2s_recv_page(&i2s_obj); + + while(1); + +} diff --git a/USDK/example_sources/log_uart_char_loopback/src/main.c b/USDK/example_sources/log_uart_char_loopback/src/main.c new file mode 100644 index 0000000..58e931e --- /dev/null +++ b/USDK/example_sources/log_uart_char_loopback/src/main.c @@ -0,0 +1,40 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "log_uart_api.h" + +log_uart_t uobj; + +void uart_send_string(log_uart_t *uobj, char *pstr) +{ + unsigned int i=0; + + while (*(pstr+i) != 0) { + log_uart_putc(uobj, *(pstr+i)); + i++; + } +} + +void main(void) +{ + // sample text + char rc; + // Initial Log UART: BaudRate=115200, 8-bits, No Parity, 1 Stop bit + log_uart_init(&uobj, 38400, 8, ParityNone, 1); + + uart_send_string(&uobj, "UART API Demo...\r\n"); + uart_send_string(&uobj, "Hello World!\r\n"); + while(1){ + uart_send_string(&uobj, "\r\n8195a$"); + rc = log_uart_getc(&uobj); + log_uart_putc(&uobj, rc); + } +} + diff --git a/USDK/example_sources/log_uart_loopback/src/main.c b/USDK/example_sources/log_uart_loopback/src/main.c new file mode 100644 index 0000000..74f7dc4 --- /dev/null +++ b/USDK/example_sources/log_uart_loopback/src/main.c @@ -0,0 +1,46 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "log_uart_api.h" + +char buf[100]="Hello World!\r\n";; +log_uart_t uobj; + +int uart_scan (char *buf) +{ + int i; + + for (i=0;i<100;i++) { + *(buf+i) = log_uart_getc(&uobj); + if ((*(buf+i) == 0x0A) || (*(buf+i) == 0x0D)) { + break; + } + } + + return i; +} + +void main(void) +{ + int ret; + + log_uart_init(&uobj, 38400, 8, ParityNone, 1); + log_uart_send(&uobj, buf, _strlen(buf), 100); + + while (1) { +// ret = log_uart_recv(&uobj, buf, 100, 2000); + ret = uart_scan(buf); + log_uart_send(&uobj, buf, ret, 1000); + log_uart_putc(&uobj, 0x0A); + log_uart_putc(&uobj, 0x0D); + } +} + + diff --git a/USDK/example_sources/log_uart_stream_loopback/src/main.c b/USDK/example_sources/log_uart_stream_loopback/src/main.c new file mode 100644 index 0000000..0ef41b5 --- /dev/null +++ b/USDK/example_sources/log_uart_stream_loopback/src/main.c @@ -0,0 +1,81 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "log_uart_api.h" + +#define BUF_SZ (1024*3) + +extern void wait_ms(int ms); + +char buf[BUF_SZ]="Hello World!\r\n";; +volatile uint32_t tx_busy=0; +volatile uint32_t rx_busy=0; +log_uart_t uobj; + +void uart_tx_done(uint32_t id) +{ + log_uart_t *uobj = (void*)id; + tx_busy = 0; +} + +void uart_rx_done(uint32_t id) +{ + log_uart_t *uobj = (void*)id; + rx_busy = 0; +} + +void main(void) +{ + int ret; + int i; + int timeout; + + log_uart_init(&uobj, 38400, 8, ParityNone, 1); + + log_uart_tx_comp_handler(&uobj, (void*)uart_tx_done, (uint32_t) &uobj); + log_uart_rx_comp_handler(&uobj, (void*)uart_rx_done, (uint32_t) &uobj); + + log_uart_send(&uobj, buf, _strlen(buf), 100); + + while (1) { + rx_busy = 1; + log_uart_recv_stream(&uobj, buf, BUF_SZ); + timeout = 2000; + ret = BUF_SZ; + while (rx_busy) { + wait_ms(1); + timeout--; + if (timeout == 0) { + // return value is the bytes received + ret = log_uart_recv_stream_abort(&uobj); + rx_busy = 0; + } + } + + if (ret > 0) { + buf[ret] = 0; // end of string + tx_busy = 1; + log_uart_send_stream(&uobj, buf, ret); + timeout = 2000; + while (tx_busy) { + wait_ms(1); + timeout--; + if (timeout == 0) { + tx_busy = 0; + // return value is the bytes transmitted + ret = log_uart_send_stream_abort(&uobj); + } + } + log_uart_putc(&uobj, 0x0d); + log_uart_putc(&uobj, 0x0a); + } + } +} + diff --git a/USDK/example_sources/nfc/readme.txt b/USDK/example_sources/nfc/readme.txt new file mode 100644 index 0000000..54246c8 --- /dev/null +++ b/USDK/example_sources/nfc/readme.txt @@ -0,0 +1,28 @@ +Example Description + +This example describes how to use nfc interface. + +Requirement Components: +1. nfc reader. + Ex. Smart phone which has NFC reader. In Android, you can use below app + + NFC Tag reader + https://play.google.com/store/apps/details?id=com.nxp.taginfolite + + NFC Tag reader & writer + https://play.google.com/store/apps/details?id=com.wakdev.wdnfc + + NFC tag writer + https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter + +2. Connect NFC antenna. + By default the NFC antenna is provided but not connected. + You can choose your desired antenna and weld it on the board + + +Verification Steps: +(a) Open nfc reader app, Tap phone on NFC antenna, then the ndef message content is text "HELLO WORLD!" +(b) Open nfc writer app, write something to the tag. (Ex. text message "abcdefg") + It'll also dump raw data on the log. +(c) Open nfc reader app, tap phone on NFC antenna, and check if the conten is exactly the same as previous move. + diff --git a/USDK/example_sources/nfc/src/main.c b/USDK/example_sources/nfc/src/main.c new file mode 100644 index 0000000..455b59d --- /dev/null +++ b/USDK/example_sources/nfc/src/main.c @@ -0,0 +1,220 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "cmsis_os.h" + +#include "diag.h" +#include "main.h" + +#include "nfc_api.h" +#include "flash_api.h" + +#define NFC_RESTORE_DEFAULT (0) + +#define NFC_MAX_PAGE_NUM 36 +nfctag_t nfctag; +unsigned int nfc_tag_content[NFC_MAX_PAGE_NUM]; +unsigned char nfc_tag_dirty[NFC_MAX_PAGE_NUM]; + +#define RTK_NFC_UID 0x58 +unsigned char nfc_default_uid[7] = { + RTK_NFC_UID, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 +}; + +osThreadId nfc_tid = 0; + +#define FLASH_APP_NFC_BASE 0x85000 +flash_t flash_nfc; + +void nfc_event_listener(void *arg, unsigned int event) { + switch(event) { + case NFC_EV_READER_PRESENT: + DiagPrintf("NFC_EV_READER_PRESENT\r\n"); + break; + case NFC_EV_READ: + DiagPrintf("NFC_EV_READ\r\n"); + break; + case NFC_EV_WRITE: + DiagPrintf("NFC_EV_WRITE\r\n"); + break; + case NFC_EV_ERR: + DiagPrintf("NFC_EV_ERR\r\n"); + break; + case NFC_EV_CACHE_READ: + DiagPrintf("NFC_EV_CACHE_READ\r\n"); + break; + } +} + +/** + * This callback function is called several times if tag is being written multiple pages. + * DO NOT put heavy task here otherwise it will block tag write and cause timeout failure. + **/ +void nfc_write_listener(void *arg, unsigned int page, unsigned int pgdat) { + nfc_tag_content[page] = pgdat; + nfc_tag_dirty[page] = 1; + if (nfc_tid) { + osSignalSet(nfc_tid, NFC_EV_WRITE); + } +} + +int is_valid_nfc_uid() { + int valid_content = 1; + + unsigned char uid[7]; + unsigned char bcc[2]; + + uid[0] = (unsigned char)((nfc_tag_content[0] & 0x000000FF) >> 0); + uid[1] = (unsigned char)((nfc_tag_content[0] & 0x0000FF00) >> 8); + uid[2] = (unsigned char)((nfc_tag_content[0] & 0x00FF0000) >> 16); + bcc[0] = (unsigned char)((nfc_tag_content[0] & 0xFF000000) >> 24); + uid[3] = (unsigned char)((nfc_tag_content[1] & 0x000000FF) >> 0); + uid[4] = (unsigned char)((nfc_tag_content[1] & 0x0000FF00) >> 8); + uid[5] = (unsigned char)((nfc_tag_content[1] & 0x00FF0000) >> 16); + uid[6] = (unsigned char)((nfc_tag_content[1] & 0xFF000000) >> 24); + bcc[1] = (unsigned char)((nfc_tag_content[2] & 0x000000FF) >> 0); + + // verify Block Check Character + if (bcc[0] != (0x88 ^ uid[0] ^ uid[1] ^ uid[2])) { + valid_content = 0; + } + if (bcc[1] != (uid[3] ^ uid[4] ^ uid[5] ^ uid[6])) { + valid_content = 0; + } + + return valid_content; +} + +unsigned int generate_default_tag_content() { + unsigned int page_size = 0; + + memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int)); + + // calculate Block Check Character + unsigned char bcc[2]; + bcc[0] = 0x88 ^ nfc_default_uid[0] ^ nfc_default_uid[1] ^ nfc_default_uid[2]; + bcc[1] = nfc_default_uid[3] ^ nfc_default_uid[4] ^ nfc_default_uid[5] ^ nfc_default_uid[6]; + + // generate header + nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[0]) << 0 | + ((unsigned int)nfc_default_uid[1]) << 8 | + ((unsigned int)nfc_default_uid[2]) << 16 | + ((unsigned int) bcc[0]) << 24; + nfc_tag_content[page_size++] = ((unsigned int)nfc_default_uid[3]) << 0 | + ((unsigned int)nfc_default_uid[4]) << 8 | + ((unsigned int)nfc_default_uid[5]) << 16 | + ((unsigned int)nfc_default_uid[6]) << 24; + nfc_tag_content[page_size++] = ((unsigned int) bcc[1]) << 0; + nfc_tag_content[page_size++] = 0x001211E1; + + // Init tag content as NDEF will-known text message "HELLO WORLD!" in little endian + nfc_tag_content[page_size++] = 0x01d11303; + nfc_tag_content[page_size++] = 0x6502540f; + nfc_tag_content[page_size++] = 0x4c45486e; + nfc_tag_content[page_size++] = 0x57204f4c; + nfc_tag_content[page_size++] = 0x444c524f; + nfc_tag_content[page_size++] = 0x0000fe21; + + return page_size; +} + +void nfc_load_tag_content_from_flash() { + int i, address, page_size; + + memset(nfc_tag_content, 0, NFC_MAX_PAGE_NUM * sizeof(unsigned int)); + memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM); + + for (i = 0, address = FLASH_APP_NFC_BASE; i < NFC_MAX_PAGE_NUM; i++, address+=4) { + flash_read_word(&flash_nfc, address, &nfc_tag_content[i]); + } + + if (!is_valid_nfc_uid() || NFC_RESTORE_DEFAULT) { + DiagPrintf("Invalid tag content, restore to default value\r\n"); + page_size = generate_default_tag_content(); + + // update to flash + flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE); + for (i = 0, address = FLASH_APP_NFC_BASE; i < page_size; i++, address += 4) { + flash_write_word(&flash_nfc, address, nfc_tag_content[i]); + } + } + +} + +void nfc_store_tag_content() { + int i, address; + int modified_page_count; + + // dump the modified tag content + modified_page_count = 0; + for (i = 4; i < NFC_MAX_PAGE_NUM && nfc_tag_dirty[i]; i++) { + modified_page_count++; + DiagPrintf("page:%02d data:%08x\r\n", i, nfc_tag_content[i]); + } + + // update to cache from page 4 + nfc_cache_write(&nfctag, &(nfc_tag_content[4]), 4, modified_page_count); + + modified_page_count += 4; // we also need update tag header to flash which has size 4 + flash_erase_sector(&flash_nfc, FLASH_APP_NFC_BASE); + for (i = 0, address = FLASH_APP_NFC_BASE; i < modified_page_count; i++, address += 4) { + flash_write_word(&flash_nfc, address, nfc_tag_content[i]); + } + +} + +void nfc_task(void const *arg) { + int i; + osEvent evt; + + nfc_load_tag_content_from_flash(); + + nfc_init(&nfctag, nfc_tag_content); + nfc_event(&nfctag, nfc_event_listener, NULL, 0xFF); + nfc_write(&nfctag, nfc_write_listener, NULL); + + osSignalClear(nfc_tid, NFC_EV_WRITE); + + while(1) { + evt = osSignalWait (0, 0xFFFFFFFF); // wait for any signal with max timeout + if (evt.status == osEventSignal && (evt.value.signals & NFC_EV_WRITE)) { + osDelay(300); + + nfc_store_tag_content(); + + memset(nfc_tag_dirty, 0, NFC_MAX_PAGE_NUM); + osSignalClear(nfc_tid, NFC_EV_WRITE); + } + } +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + osThreadDef(nfc_task, osPriorityRealtime, 1, 1024); + nfc_tid = osThreadCreate (osThread (nfc_task), NULL); + + DBG_INFO_MSG_OFF(_DBG_SPI_FLASH_); + + //3 3)Enable Schedule, Start Kernel +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + #ifdef PLATFORM_FREERTOS + vTaskStartScheduler(); + #endif +#else + RtlConsolTaskRom(NULL); +#endif + + while(1); +} + diff --git a/USDK/example_sources/pm_deepsleep/readme.txt b/USDK/example_sources/pm_deepsleep/readme.txt new file mode 100644 index 0000000..5503721 --- /dev/null +++ b/USDK/example_sources/pm_deepsleep/readme.txt @@ -0,0 +1,22 @@ +Example Description + +This example describes how to use deep sleep api. + +Requirement Components: + a LED + a push button + +Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5: + - PC_4 as input with internal pull-high, connect a push button to this pin and ground. + - PC_5 as output, connect a LED to this pin and ground. + +In this example, LED is turned on after device initialize. +User push the button to turn off LED and trigger device enter deep sleep mode for 10s. +If user press any key before sleep timeout, the system will resume. +LED is turned on again after device initialize. + +It can be easily measure power consumption in normal mode and deep sleep mode before/after push the putton. + +NOTE: You will see device resume immediately at first time. +It's because the log uart is a wakeup source and it buffered a wakeup event when DAP is used. +The symptom won't appear if you use power source on R43 and only power on module. \ No newline at end of file diff --git a/USDK/example_sources/pm_deepsleep/src/main.c b/USDK/example_sources/pm_deepsleep/src/main.c new file mode 100644 index 0000000..bf7a299 --- /dev/null +++ b/USDK/example_sources/pm_deepsleep/src/main.c @@ -0,0 +1,110 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_api.h" // mbed +#include "gpio_irq_api.h" // mbed +#include "sleep_ex_api.h" +#include "sys_api.h" +#include "diag.h" +#include "main.h" + +#define GPIO_LED_PIN PC_5 +#define GPIO_IRQ_PIN PC_4 + +// deep sleep can only be waked up by GPIOB_1 and GTimer +#define GPIO_WAKE_PIN PB_1 + +// NOTICE: The pull condition may differnet on your board +PinName pull_down_list[] = { + PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, + PB_0, PB_3, PB_4, PB_5, PB_6, PB_7, + PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, + PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, + PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_A, + PF_1, PF_2, PF_3, PF_4, PF_5 +}; + +// NOTICE: The pull condition may differnet on your board +PinName pull_up_list[] = { + PB_2, + PF_0, + PG_0, PG_1, PG_2, PG_3, PG_4, PG_5, PG_6, PG_7, + PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, + PI_0, PI_1, PI_2, PI_3, PI_4, PI_5, PI_6, PI_7, + PJ_0, PJ_1, PJ_2, PJ_3, PJ_4, PJ_5, PJ_6, + PK_0, PK_1, PK_2, PK_3, PK_4, PK_5, PK_6 +}; + +void gpio_pull_control() +{ + int i; + gpio_t gpio_obj; + + for (i=0; i < sizeof(pull_down_list) / sizeof(pull_down_list[0]); i++) { + gpio_init(&gpio_obj, pull_down_list[i]); + gpio_dir(&gpio_obj, PIN_INPUT); + gpio_mode(&gpio_obj, PullDown); + } + + for (i=0; i < sizeof(pull_up_list) / sizeof(pull_up_list[0]); i++) { + gpio_init(&gpio_obj, pull_up_list[i]); + gpio_dir(&gpio_obj, PIN_INPUT); + gpio_mode(&gpio_obj, PullUp); + } +} + +void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event) +{ + gpio_t *gpio_led; + gpio_led = (gpio_t *)id; + + printf("Enter deep sleep...Wait 10s or give rising edge at PB_1 to wakeup system.\r\n\r\n"); + + // turn off led + gpio_write(gpio_led, 0); + + // turn off log uart + sys_log_uart_off(); + + // initialize wakeup pin at PB_1 + gpio_t gpio_wake; + gpio_init(&gpio_wake, GPIO_WAKE_PIN); + gpio_dir(&gpio_wake, PIN_INPUT); + gpio_mode(&gpio_wake, PullDown); + + // Please note that the pull control is different in different board + // This example is a sample code for RTL Ameba Dev Board + gpio_pull_control(); + + // enter deep sleep + deepsleep_ex(DSLEEP_WAKEUP_BY_GPIO | DSLEEP_WAKEUP_BY_TIMER, 10000); +} + +void main(void) +{ + gpio_t gpio_led; + gpio_irq_t gpio_btn; + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + // Initial Push Button pin as interrupt source + gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led)); + gpio_irq_set(&gpio_btn, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_btn); + + // led on means system is in run mode + gpio_write(&gpio_led, 1); + printf("\r\nPush button at PC_4 to enter deep sleep\r\n"); + + while(1); +} diff --git a/USDK/example_sources/pm_deepstandby/readme.txt b/USDK/example_sources/pm_deepstandby/readme.txt new file mode 100644 index 0000000..554b71d --- /dev/null +++ b/USDK/example_sources/pm_deepstandby/readme.txt @@ -0,0 +1,18 @@ +Example Description + +This example describes how to use deep standby api. + +Requirement Components: + a LED + a push button + +Pin name PA_5 and PC_5 map to GPIOA_5 and GPIOC_5: + - PA_5 as input, connect a push button to this pin and 3v3. + - PC_5 as output, connect a LED to this pin and ground. + +In this example, LED is turned on after device initialize. +User push the button to turn off LED and trigger device enter deep standby mode for 10s. +If user press button before sleep timeout, the system will resume. +LED is turned on again after device initialize. + +It can be easily measure power consumption in normal mode and deep standby mode before/after push the putton. diff --git a/USDK/example_sources/pm_deepstandby/src/main.c b/USDK/example_sources/pm_deepstandby/src/main.c new file mode 100644 index 0000000..7588f82 --- /dev/null +++ b/USDK/example_sources/pm_deepstandby/src/main.c @@ -0,0 +1,105 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_api.h" // mbed +#include "sleep_ex_api.h" +#include "diag.h" +#include "main.h" + +#define GPIO_LED_PIN PC_5 +#define GPIO_PUSHBT_PIN PA_5 + +// NOTICE: The pull condition may differnet on your board +PinName pull_down_list[] = { + PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, + PB_0, PB_1, PB_3, PB_4, PB_5, PB_6, PB_7, + PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, + PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, + PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_A, + PF_1, PF_2, PF_3, PF_4, PF_5 +}; + +// NOTICE: The pull condition may differnet on your board +PinName pull_up_list[] = { + PB_2, + PF_0, + PG_0, PG_1, PG_2, PG_3, PG_4, PG_5, PG_6, PG_7, + PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, + PI_0, PI_1, PI_2, PI_3, PI_4, PI_5, PI_6, PI_7, + PJ_0, PJ_1, PJ_2, PJ_3, PJ_4, PJ_5, PJ_6, + PK_0, PK_1, PK_2, PK_3, PK_4, PK_5, PK_6 +}; + +void gpio_pull_control() +{ + int i; + gpio_t gpio_obj; + + for (i=0; i < sizeof(pull_down_list) / sizeof(pull_down_list[0]); i++) { + gpio_init(&gpio_obj, pull_down_list[i]); + gpio_dir(&gpio_obj, PIN_INPUT); + gpio_mode(&gpio_obj, PullDown); + } + + for (i=0; i < sizeof(pull_up_list) / sizeof(pull_up_list[0]); i++) { + gpio_init(&gpio_obj, pull_up_list[i]); + gpio_dir(&gpio_obj, PIN_INPUT); + gpio_mode(&gpio_obj, PullUp); + } +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + gpio_t gpio_led, gpio_btn; + int old_btn_state, new_btn_state; + + DBG_INFO_MSG_OFF(_DBG_GPIO_); + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + // Initial Push Button pin + gpio_init(&gpio_btn, GPIO_PUSHBT_PIN); + gpio_dir(&gpio_btn, PIN_INPUT); // Direction: Input + gpio_mode(&gpio_btn, PullDown); + + old_btn_state = new_btn_state = 0; + gpio_write(&gpio_led, 1); + + DiagPrintf("Push button to sleep...\r\n"); + while(1){ + new_btn_state = gpio_read(&gpio_btn); + + if (old_btn_state == 1 && new_btn_state == 0) { + gpio_write(&gpio_led, 0); + + DiagPrintf("Sleep 8s... (Or wakeup by pushing button)\r\n"); + //turn off log uart to avoid warning in gpio_pull_control() + sys_log_uart_off(); + // Please note that the pull control is different in different board + // This example is a sample code for RTL Ameba Dev Board + gpio_pull_control(); + standby_wakeup_event_add(STANDBY_WAKEUP_BY_STIMER, 8000, 0); + standby_wakeup_event_add(STANDBY_WAKEUP_BY_PA5, 0, 1); + deepstandby_ex(); + + DiagPrintf("This line should not be printed\r\n"); + } + old_btn_state = new_btn_state; + } +} + diff --git a/USDK/example_sources/pm_sleep/readme.txt b/USDK/example_sources/pm_sleep/readme.txt new file mode 100644 index 0000000..f3ece4e --- /dev/null +++ b/USDK/example_sources/pm_sleep/readme.txt @@ -0,0 +1,18 @@ +Example Description + +This example describes how to use sleep api. + +Requirement Components: + a LED + a push button + +Pin name PC_4 and PC_5 map to GPIOC_4 and GPIOC_5: + - PC_4 as input with internal pull-high, connect a push button to this pin and ground. + - PC_5 as output, connect a LED to this pin and ground. + +In this example, LED is turned on after device initialize. +User push the button to turn off LED and trigger device enter sleep mode for 10s. +If user push button before sleep timeout, the system will resume. +LED is turned on again after system resume without restart PC. + +It can be easily measure power consumption in normal mode and sleep mode before/after push the putton. diff --git a/USDK/example_sources/pm_sleep/src/main.c b/USDK/example_sources/pm_sleep/src/main.c new file mode 100644 index 0000000..814afb1 --- /dev/null +++ b/USDK/example_sources/pm_sleep/src/main.c @@ -0,0 +1,86 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "gpio_api.h" // mbed +#include "gpio_irq_api.h" // mbed +#include "sleep_ex_api.h" +#include "sys_api.h" +#include "diag.h" +#include "main.h" + +#define GPIO_LED_PIN PC_5 +#define GPIO_IRQ_PIN PC_4 + +int led_ctrl = 0; +gpio_t gpio_led; + +int put_to_sleep = 0; + +void gpio_demo_irq_handler (uint32_t id, gpio_irq_event event) +{ + gpio_t *gpio_led; + + gpio_led = (gpio_t *)id; + + if (led_ctrl == 1) { + led_ctrl = 0; + gpio_write(gpio_led, led_ctrl); + put_to_sleep = 1; + } else { + led_ctrl = 1; + gpio_write(gpio_led, led_ctrl); + } +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + gpio_irq_t gpio_btn; + int IsDramOn = 1; + + DBG_INFO_MSG_OFF(_DBG_GPIO_); + + // Init LED control pin + gpio_init(&gpio_led, GPIO_LED_PIN); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + + // Initial Push Button pin as interrupt source + gpio_irq_init(&gpio_btn, GPIO_IRQ_PIN, gpio_demo_irq_handler, (uint32_t)(&gpio_led)); + gpio_irq_set(&gpio_btn, IRQ_FALL, 1); + gpio_irq_enable(&gpio_btn); + + led_ctrl = 1; + gpio_write(&gpio_led, led_ctrl); + DBG_8195A("Push button to enter sleep\r\n"); + //system will hang when it tries to suspend SDRAM for 8711AF + if ( sys_is_sdram_power_on() == 0 ) { + IsDramOn = 0; + } + + put_to_sleep = 0; + while(1) { + if (put_to_sleep) { + DBG_8195A("Sleep 8s or push button to resume system...\r\n"); + sys_log_uart_off(); + sleep_ex_selective(SLP_GPIO | SLEEP_WAKEUP_BY_STIMER, 8000, 0, IsDramOn); // sleep_ex can't be put in irq handler + sys_log_uart_on(); + DBG_8195A("System resume\r\n"); + + put_to_sleep = 0; + led_ctrl = 1; + gpio_write(&gpio_led, led_ctrl); + } + } +} diff --git a/USDK/example_sources/pm_tickless/readme.txt b/USDK/example_sources/pm_tickless/readme.txt new file mode 100644 index 0000000..db99702 --- /dev/null +++ b/USDK/example_sources/pm_tickless/readme.txt @@ -0,0 +1,31 @@ +Example Description + +This example describes how to use freertos tickless with uart interruptable interface + +Requirement Components: + USBtoTTL adapter + +Connect to PC + - Connect Ground: connect to GND pin via USBtoTTL adapter + - Use UART1 + GPIOA_0 as UART1_RX connect to TX of USBtoTTL adapter + GPIOA_4 as UART1_TX connect to RX of USBtoTTL adapter + +We also need connect GPIOC_1 as gpio interrupt which parallel with log uart rx pin. + +In this example, freertos will enter/leave tickless automatically. +User can type continuous "Enter" in uart or log uart to wake system if system is in tickless. +System is keep awake until user type a command via uart. + +There are some features in this example: +(1) We replace tickless' sleep function with system sleep api which save more power. +(2) Freertos enter tickless if the wakelock bit map is 0. + It means there is no function require system keep awake. + By default there is WAKELOCK_OS keep system awake. + So we need release this WAKELOCK_OS enable tickless mode. +(3) We configure uart rx as gpio interrupt mode. This make uart can wake system. + +NOTICE: If you don't want loss any data from treating UART signal as GPIO interrupt, + you can set FREERTOS_PMU_TICKLESS_PLL_RESERVED to 1 in "platform_opt.h". + It will reserved PLL clock in tickless and UART can receive the whole data. + But it also cost more power consumption. diff --git a/USDK/example_sources/pm_tickless/src/main.c b/USDK/example_sources/pm_tickless/src/main.c new file mode 100644 index 0000000..b78d642 --- /dev/null +++ b/USDK/example_sources/pm_tickless/src/main.c @@ -0,0 +1,168 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "main.h" +#include + +#include "freertos_pmu.h" +#include "gpio_irq_api.h" +#include "serial_api.h" + +// select uart tx/rx pin with gpio interrupt function +#define UART_TX PA_4 +#define UART_RX PA_0 + +#define LOGUART_RX_WAKE PC_1 + +#define WAKELOCK_EXAMPLE WAKELOCK_USER_BASE + +serial_t mysobj; +volatile char rc = 0; + +extern void wlan_netowrk(void); +extern void console_init(void); + +char cmdbuf[128]; +int cmdbuf_index = 0; +void uart_irq_callback(uint32_t id, SerialIrq event) +{ + serial_t *sobj = (void*)id; + + if(event == RxIrq) { + acquire_wakelock(WAKELOCK_EXAMPLE); + + rc = serial_getc(sobj); + + if (rc == '\r' || rc == '\n') { + serial_putc(sobj, '\r'); + serial_putc(sobj, '\n'); + serial_putc(sobj, '#'); + serial_putc(sobj, ' '); + + if (cmdbuf_index != 0) { + + /* NOTICE: If you don't want loss any data from treating UART signal as GPIO interrupt, + * you can set FREERTOS_PMU_TICKLESS_PLL_RESERVED to 1 in "platform_opt.h". + * It will reserved PLL clock in tickless and UART can receive the whole data. + * But it also cost more power consumption. + **/ + + // process command + printf("cmd(%d): %s\r\n", cmdbuf_index, cmdbuf); + + // release wakelock and reset buf + cmdbuf_index = 0; + release_wakelock(WAKELOCK_EXAMPLE); + } + } + + if (!(rc == '\r' || rc == '\n' )) { + // receive command + serial_putc(sobj, rc); + cmdbuf[cmdbuf_index] = rc; + cmdbuf_index++; + cmdbuf[cmdbuf_index] = '\0'; + } + } +} + +void gpio_uart_rx_irq_callback(uint32_t id, gpio_irq_event event) +{ + acquire_wakelock(WAKELOCK_EXAMPLE); +} + +void pre_sleep_process_callback(unsigned int expected_idle_time) +{ + // For peripherals that need turned off before sleep, call disable or deinit peripheral here +} + +void post_sleep_process_callback(unsigned int expected_idle_time) +{ + // For peripherals that are turned off before sleep, call enable or init peripheral here +} + +void config_uart() +{ + // setup uart + serial_init(&mysobj, UART_TX, UART_RX); + serial_baud(&mysobj, 38400); + serial_format(&mysobj, 8, ParityNone, 1); + + serial_irq_handler(&mysobj, uart_irq_callback, (uint32_t)&mysobj); + serial_irq_set(&mysobj, RxIrq, 1); + serial_irq_set(&mysobj, TxIrq, 1); + + // config uart rx as gpio wakeup pin + gpio_irq_t gpio_rx_wake; + gpio_irq_init(&gpio_rx_wake, UART_RX, gpio_uart_rx_irq_callback, NULL); + gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_rx_wake); +} + +void gpio_loguart_rx_irq_callback (uint32_t id, gpio_irq_event event) +{ + /* WAKELOCK_LOGUART is also handled in log service. + * It is release after a complete command is sent. + **/ + acquire_wakelock(WAKELOCK_LOGUART); +} + +void config_loguart() +{ + /* Log uart RX pin doesn't support gpio interrupt. + * To make log uart wake system, we can parallel log uart RX with another gpio interrupt pin. + */ + gpio_irq_t gpio_rx_wake; + gpio_irq_init(&gpio_rx_wake, LOGUART_RX_WAKE, gpio_loguart_rx_irq_callback, NULL); + gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger + gpio_irq_enable(&gpio_rx_wake); +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + if ( rtl_cryptoEngine_init() != 0 ) { + DiagPrintf("crypto engine init failed\r\n"); + } + + /* Initialize log uart and at command service */ + console_init(); + + /* pre-processor of application example */ + pre_example_entry(); + + /* wlan intialization */ +#if defined(CONFIG_WIFI_NORMAL) && defined(CONFIG_NETWORK) + wlan_network(); +#endif + + // setup uart with capability of wakeup system + config_uart(); + + // setup log uart with capability of wakeup system + config_loguart(); + + // By default tickless is disabled because WAKELOCK_OS is locked. + // Release this wakelock to enable tickless + release_wakelock(WAKELOCK_OS); + + // Register pre/post sleep callback. They are called when system automatically enter/leave sleep. + register_sleep_callback_by_module(1, pre_sleep_process_callback, WAKELOCK_EXAMPLE); + register_sleep_callback_by_module(0, post_sleep_process_callback, WAKELOCK_EXAMPLE); + + /* Execute application example */ + example_entry(); + + /*Enable Schedule, Start Kernel*/ +#if defined(CONFIG_KERNEL) && !TASK_SCHEDULER_DISABLED + #ifdef PLATFORM_FREERTOS + vTaskStartScheduler(); + #endif +#else + RtlConsolTaskRom(NULL); +#endif +} diff --git a/USDK/example_sources/pwm-buzzer/readme.txt b/USDK/example_sources/pwm-buzzer/readme.txt new file mode 100644 index 0000000..f7d022d --- /dev/null +++ b/USDK/example_sources/pwm-buzzer/readme.txt @@ -0,0 +1,10 @@ +Example Description + +This example describes how to use pwm buzzer on extend board + +Requirement Components: + extend board, buzzer + +Connect extend board to 2v0 dap board, and connect buzzer on the extend board's buzzer pin, then the buzzer would play sound from Do to higher Do. + + \ No newline at end of file diff --git a/USDK/example_sources/pwm-buzzer/src/main.c b/USDK/example_sources/pwm-buzzer/src/main.c new file mode 100644 index 0000000..3f6cf4e --- /dev/null +++ b/USDK/example_sources/pwm-buzzer/src/main.c @@ -0,0 +1,63 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "pwmout_api.h" // mbed +#include "main.h" +#include "os_support.h" + +#define PWM_1 PC_0 +#define PWM_2 PC_1 +#define PWM_3 PC_2 +#define PWM_4 PC_3 + + + +pwmout_t pwm_led[4]; +PinName pwm_led_pin[4] = {PWM_1, PWM_2, PWM_3, PWM_4}; +float period[8] = {1.0/523, 1.0/587, 1.0/659, 1.0/698, 1.0/784, 1.0/880, 1.0/988, 1.0/1047}; + +extern void RtlMsleepOS(u32 ms); + +void pwm_delay(void) +{ + for(int i=0;i<1000000;i++) + asm(" nop"); +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +//int main_app(IN u16 argc, IN u8 *argv[]) +void main(void) +{ + int i; + + + pwmout_init(&pwm_led[3], pwm_led_pin[3]); + + + + while (1) { + + for(i=0; i<8; i++){ + pwmout_period(&pwm_led[3], period[i]); + pwmout_pulsewidth(&pwm_led[3], period[i]/2); + Mdelay(1000); + } + + +// wait_ms(20); +// RtlMsleepOS(25); + pwm_delay(); + } +} + diff --git a/USDK/example_sources/pwm/readme.txt b/USDK/example_sources/pwm/readme.txt new file mode 100644 index 0000000..022ca0f --- /dev/null +++ b/USDK/example_sources/pwm/readme.txt @@ -0,0 +1,13 @@ +Example Description + +This example describes how to use pwm + +Requirement Components: + 1~4 LED + +Connect LED to below PWM pins and ground, then the LED would gradually become brighter and then darker with different speed. + - connect a LED to PC_0 and ground + - connect a LED to PC_1 and ground + - connect a LED to PC_2 and ground + - connect a LED to PC_3 and ground + \ No newline at end of file diff --git a/USDK/example_sources/pwm/src/main.c b/USDK/example_sources/pwm/src/main.c new file mode 100644 index 0000000..98b01ee --- /dev/null +++ b/USDK/example_sources/pwm/src/main.c @@ -0,0 +1,94 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "pwmout_api.h" // mbed +#include "main.h" + +#define PWM_1 PC_0 +#define PWM_2 PC_1 +#define PWM_3 PC_2 +#define PWM_4 PC_3 +#define PWM_PERIOD 20000 +#define USE_FLOAT 0 + +#if USE_FLOAT +#define PWM_STEP (1.0/20.0) +float pwms[4]={0.0, 0.25, 0.5, 0.75}; +float steps[4]={PWM_STEP, PWM_STEP, PWM_STEP, PWM_STEP}; +#else +#define PWM_STEP (PWM_PERIOD/20) +int pwms[4]={0, PWM_PERIOD/4, PWM_PERIOD/2, PWM_PERIOD/4*3}; +int steps[4]={PWM_STEP,PWM_STEP,PWM_STEP,PWM_STEP}; +#endif + +pwmout_t pwm_led[4]; +PinName pwm_led_pin[4] = {PWM_1, PWM_2, PWM_3, PWM_4}; + +extern void RtlMsleepOS(u32 ms); + +void pwm_delay(void) +{ + for(int i=0;i<1000000;i++) + asm(" nop"); +} + +/** + * @brief Main program. + * @param None + * @retval None + */ +//int main_app(IN u16 argc, IN u8 *argv[]) +void main(void) +{ + int i; + + for (i=0; i<4; i++) { + pwmout_init(&pwm_led[i], pwm_led_pin[i]); + pwmout_period_us(&pwm_led[i], PWM_PERIOD); + } + + while (1) { +#if USE_FLOAT + for (i=0; i<4; i++) { + pwmout_write(&pwm_led[i], pwms[i]); + + pwms[i] += steps[i]; + if (pwms[i] >= 1.0) { + steps[i] = -PWM_STEP; + pwms[i] = 1.0; + } + + if (pwms[i] <= 0.0) { + steps[i] = PWM_STEP; + pwms[i] = 0.0; + } + } +#else + for (i=0; i<4; i++) { + pwmout_pulsewidth_us(&pwm_led[i], pwms[i]); + + pwms[i] += steps[i]; + if (pwms[i] >= PWM_PERIOD) { + steps[i] = -PWM_STEP; + pwms[i] = PWM_PERIOD; + } + + if (pwms[i] <= 0) { + steps[i] = PWM_STEP; + pwms[i] = 0; + } + } +#endif +// wait_ms(20); +// RtlMsleepOS(25); + pwm_delay(); + } +} + diff --git a/USDK/example_sources/rtc/readme.txt b/USDK/example_sources/rtc/readme.txt new file mode 100644 index 0000000..4194f46 --- /dev/null +++ b/USDK/example_sources/rtc/readme.txt @@ -0,0 +1,7 @@ +Example Description + +This example describes how to use the RTC API. The RTC function is implemented by a G-Timer. + +Behavior: +This example will print out the time information every secand. + diff --git a/USDK/example_sources/rtc/src/main.c b/USDK/example_sources/rtc/src/main.c new file mode 100644 index 0000000..8cadc02 --- /dev/null +++ b/USDK/example_sources/rtc/src/main.c @@ -0,0 +1,34 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "rtc_api.h" + + int main() + { + time_t seconds; + struct tm *timeinfo; + + rtc_init(); + rtc_write(1256729737); // Set RTC time to Wed, 28 Oct 2009 11:35:37 + + while(1) { + seconds = rtc_read(); + timeinfo = localtime(&seconds); + + DBG_8195A("Time as seconds since January 1, 1970 = %d\n", seconds); + + DBG_8195A("Time as a basic string = %s", ctime(&seconds)); + + DBG_8195A("Time as a custom formatted string = %d-%d-%d %d:%d:%d ", + timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, + timeinfo->tm_min,timeinfo->tm_sec); + + wait(1); + } + } + diff --git a/USDK/example_sources/sdio_device/readme.txt b/USDK/example_sources/sdio_device/readme.txt new file mode 100644 index 0000000..b1c0c51 --- /dev/null +++ b/USDK/example_sources/sdio_device/readme.txt @@ -0,0 +1,38 @@ +Example Description + + This loopback example describes how to use Ameba SDIO device APIs in spdio_api.c and spdio_api.h. + +How to build: + 1. copy src\main.c to project\realtek_ameba1_va0_example\src + 2. include lib\lib_sdiod.a for build, then re-build the project + +Requirement Components: + PC (running Linux kernel over 3.13) * 1 + Ameba EVB * 1 + +Pin assignment for SDIO device on Ameba EVB: +--------------|----------------|----------------------- +GPIO Pin name | SDIO pin name | Pin name on Ameba EVB 3V0 +--------------|----------------|----------------------- +GPIOA4 | SD_D0 | D5 +------------------------------------------------------- +GPIOA5 | SD_D1 | D2 +------------------------------------------------------- +GPIOA0 | SD_D2 | D17 +------------------------------------------------------- +GPIOA1 | SD_D3 | D16 +------------------------------------------------------- +GPIOA2 | SD_CMD | D7 +------------------------------------------------------- +GPIOA3 | SD_CLK | D6 +------------------------------------------------------- +GND | GND | GND +------------------------------------------------------- + +Set-up: + 1. Connect Ameba to PC via SDIO slot + 2. build this example and upload firmware to Ameba EVB + 3. build iNIC host SDK and run loopback test (refer to Run Loopback test.docx in iNIC source) + +Behaviour: + PC sends loopback packet to Ameba and Ameba will send back to PC whatever received diff --git a/USDK/example_sources/sdio_device/src/main.c b/USDK/example_sources/sdio_device/src/main.c new file mode 100644 index 0000000..cddf275 --- /dev/null +++ b/USDK/example_sources/sdio_device/src/main.c @@ -0,0 +1,138 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2015 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ +#include "FreeRTOS.h" +#include "task.h" +#include "diag.h" +#include "main.h" +#include "spdio_api.h" + +/** + * @brief Main program. + * @param None + * @retval None + */ +#define EX_SPDIO_STACKSIZE 2048 +#define EX_SPDIO_TX_BD_NUM 24 //n*2, 2 bd for one transaction +#define EX_SPDIO_RX_BD_NUM 20 +#define EX_SPDIO_RX_BUFSZ (SPDIO_RX_BUFSZ_ALIGN(2048+24)) //n*64, must be rounded to 64, extra 24 bytes for spdio header info + +struct spdio_t spdio_dev; + +/* +* param: pdata, package +*/ +char ex_spdio_tx(u8 *pdata, u16 size, u8 type){ + static int loop_cnt = 0; + struct spdio_buf_t *tx_buf = (struct spdio_buf_t *)malloc(sizeof(struct spdio_buf_t)); + memset((u8 *)tx_buf, 0, sizeof(struct spdio_buf_t)); + if(!tx_buf) + return FAIL; + tx_buf->buf_allocated = (u32)malloc(size + SPDIO_DMA_ALIGN_4); + if(!tx_buf->buf_allocated) + { + free((u8 *)tx_buf); + return FAIL; + } + tx_buf->size_allocated = size + SPDIO_DMA_ALIGN_4; + + tx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(tx_buf->buf_allocated), SPDIO_DMA_ALIGN_4); + + // copy data + memcpy((void*)tx_buf->buf_addr, pdata, size); + + tx_buf->buf_size = size; + tx_buf->type = SPDIO_RX_DATA_USER; // you can define your own data type in spdio_rx_data_t and spdio_tx_data_t + printf("loopback package, size = %d (cnt = %d) heap=%d\n", size, ++loop_cnt, xPortGetFreeHeapSize()); + // loopback + spdio_tx(&spdio_dev, tx_buf); + return SUCCESS; +} + +/*spdio rx done callback (HOST->Device), manage your package and buffer*/ +char ex_spdio_rx_done_cb(void *priv, void *pbuf, u8 *pdata, u16 size, u8 type){ + struct spdio_t *obj = (struct spdio_t *)priv; + struct spdio_buf_t* rx_buf = (struct spdio_buf_t*)pbuf; + + // handle package received + ex_spdio_tx(pdata, size, type); + + // manage rx_buf here + free((char *)rx_buf->buf_allocated); + + // assign new buffer for SPDIO RX + rx_buf->buf_allocated = (u32)malloc(obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4); + rx_buf->size_allocated = obj->rx_bd_bufsz + SPDIO_DMA_ALIGN_4; + + // this buffer must be 4 byte alignment + rx_buf->buf_addr = (u32)N_BYTE_ALIGMENT((u32)(rx_buf->buf_allocated), SPDIO_DMA_ALIGN_4); + + return SUCCESS; +} + +/*spdio tx done callback(Device->HOST), manage buffer*/ +// this API will be called after package have been moved to HOST +char ex_spdio_tx_done_cb(void *priv, void *pbuf){ + + struct spdio_buf_t* tx_buf = (struct spdio_buf_t*)pbuf; + + free((u8 *)tx_buf->buf_allocated); + free((u8 *)tx_buf); + return SUCCESS; +} + + +void ex_spdio_thread(void* param){ + + int i; + + spdio_dev.priv = NULL; + spdio_dev.rx_bd_num = EX_SPDIO_RX_BD_NUM; + spdio_dev.tx_bd_num = EX_SPDIO_TX_BD_NUM; + spdio_dev.rx_bd_bufsz = EX_SPDIO_RX_BUFSZ; + + spdio_dev.rx_buf = (struct spdio_buf_t *)malloc(spdio_dev.rx_bd_num*sizeof(struct spdio_buf_t)); + if(!spdio_dev.rx_buf){ + printf("malloc failed for spdio buffer structure!\n"); + return; + } + + for(i=0;i +#include +#include "device.h" +#include "main.h" +#include "spi_api.h" +#include "gpio_api.h" + +// SPI0 +#define SPI0_MOSI PC_2 +#define SPI0_MISO PC_3 +#define SPI0_SCLK PC_1 +#define SPI0_CS PC_0 + +#define GPIO_RESET PB_4 +#define GPIO_CS PB_5 + +//-------------------------------------------------------------------------------------------- + +#define READ_PL7223 0x4000 +#define WRITE_PL7223 0x8000 +#define DSPSTATUS_PL7223 0xF000 +#define DUM_PL7223 0x00 //Dummy Data + +unsigned char SPDAT; // simulate example code +unsigned char DSP_STATUS=0; +unsigned char Read_Data_PL7223[146]; // Read_Data; 256Bytes=1Page +unsigned char Write_Data_PL7223[146]; // Write_Data; 256Bytes=1Page +unsigned char Cmd_RD=0; + + +long EE_Temp = 0; +float VA_rms=0; +float IA_rms=0; +float PA=0; +float SA=0; +float QA=0; +float PF_A=0; +float Theta_A=0; +float Frequency=0; +int Sample_cnt0=0; +int ZCC_cnt=0; +int ZCC_Start=0; +int ZCC_Stop=0; + +void Initial_SPI_PL7223(void); +void SPI_PL7223_SEND(unsigned char); +void SPI__PL7223_Read_Status(void); +void SPI_PL7223_DELY(int); +void SPI_PL7223_Reset(void); +void SPI_PL7223_Read(unsigned char*, unsigned int, unsigned int); +void SPI_PL7223_Write(unsigned char*, unsigned int, unsigned int); +void SPI_PL7223_Masurement(void); +void SPI_PL7223_RelayControl(int); + +static spi_t spi0_master; +static gpio_t gpio_reset; +static gpio_t gpio_cs; + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + + gpio_init(&gpio_reset, GPIO_RESET); + gpio_mode(&gpio_reset, PullUp); + gpio_dir(&gpio_reset, PIN_OUTPUT); + + gpio_init(&gpio_cs, GPIO_CS); + gpio_mode(&gpio_cs, PullUp); + gpio_dir(&gpio_cs, PIN_OUTPUT); + + spi_init(&spi0_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); + spi_format(&spi0_master, 8, 3, 0); + spi_frequency(&spi0_master, 800000); + + do + { + SPI_PL7223_Reset(); + SPI_PL7223_Read(&Read_Data_PL7223[0],0x3860,1);//DSP version :20130322 ver02, 0x3860=0x04 + //DSP version :20141009 ver01, 0x3860=0x03 + }while( ((Read_Data_PL7223[0]) != 0x04) && ((Read_Data_PL7223[0]) != 0x03) ); + + SPI_PL7223_DELY(120000); + SPI_PL7223_RelayControl(0); // OFF + SPI_PL7223_DELY(120000); + + do{ + // As below is read DSP buffer process every time (144 byte) + SPI__PL7223_Read_Status(); + SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte + SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0 + SPI_PL7223_Masurement(); + + SPI_PL7223_DELY(600000); + SPI_PL7223_RelayControl(1); // ON + SPI_PL7223_DELY(120000); + + SPI__PL7223_Read_Status(); + SPI_PL7223_Read(&Read_Data_PL7223[0],0x3000,144); // 0x3000~0x308F //144 byte + SPI_PL7223_Read(&Read_Data_PL7223[144],0x3809,2); // Sample_cnt0 + SPI_PL7223_Masurement(); + + SPI_PL7223_DELY(600000); + SPI_PL7223_RelayControl(0); // OFF + SPI_PL7223_DELY(120000); + }while(1); +} + +//--------------------------------------------------------------------------------------------// +void SPI_PL7223_RelayControl(int sw) +{ + #define RELAY_MASK (1<<5) + SPI_PL7223_Read(&Read_Data_PL7223[0],0x380F,1); + if(!sw) + Read_Data_PL7223[0] &= (~RELAY_MASK); + else + Read_Data_PL7223[0] |= RELAY_MASK; + SPI_PL7223_Write(&Read_Data_PL7223[0],0x380F,1); +} + +//--------------------------------------------------------------------------------------------// +void SPI_PL7223_Reset(void) +{ + gpio_write(&gpio_cs, 0); + SPI_PL7223_DELY(500); //need delay 10ms + gpio_write(&gpio_reset, 1); + SPI_PL7223_DELY(500); //need delay 10ms + gpio_write(&gpio_reset, 0); + SPI_PL7223_DELY(500); //need delay 10ms + gpio_write(&gpio_reset, 1); + SPI_PL7223_DELY(500); //need delay 10ms + gpio_write(&gpio_cs, 1); + SPI_PL7223_DELY(300); +} + +//--------------------------------------------------------------------------------------------// +void SPI__PL7223_Read_Status(void) +{ + gpio_write(&gpio_cs, 0); + SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223 >> 8)& 0xFF); // RDSR command + SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command + + //check DSP flag state (byte) + do + { + SPI_PL7223_SEND(DUM_PL7223); + DSP_STATUS=SPDAT; + }while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready + gpio_write(&gpio_cs, 1); +} + +//--------------------------------------------------------------------------------------------// +void SPI_PL7223_Write(unsigned char* buf, unsigned int addr, unsigned int len) +{ + unsigned int i; + gpio_write(&gpio_cs, 0); + addr |= WRITE_PL7223; // Write command + SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address + SPI_PL7223_SEND((unsigned char)(addr & 0xFF));// Write low byte address + for (i = 0; i < len ; i++){ + SPI_PL7223_SEND(buf[i]); + } + gpio_write(&gpio_cs, 1); + SPI_PL7223_DELY(3); // for CS:Hi to Low need 100nsec, Delay-Time 27usec + +} +//--------------------------------------------------------------------------------------------// + +void SPI_PL7223_Read(unsigned char* buf, unsigned int addr, unsigned int len) +{ + static unsigned int i; + + gpio_write(&gpio_cs, 0); + + addr |= READ_PL7223; // Read command + SPI_PL7223_SEND((unsigned char)(addr >> 8)& 0xFF); // Write middle byte address + SPI_PL7223_SEND((unsigned char)(addr & 0x00FF)); // Write low byte address + + for(i=0;i> 8)& 0xFF); // RDSR command + SPI_PL7223_SEND((unsigned char)(DSPSTATUS_PL7223& 0x00FF)); // RDSR command + + do + { + SPI_PL7223_SEND(DUM_PL7223); + DSP_STATUS=SPDAT; + }while((DSP_STATUS & 0x80) == 0x00); // Bit7=1 is Ready + + gpio_write(&gpio_cs, 1); + +} + +//--------------------------------------------------------------------------------------------// + +void SPI_PL7223_Masurement(void) +{ + + //Vrms address : 0x3002~0x3003 + // VA_rms = (Read_Data_PL7223[3]*256+Read_Data_PL7223[2])/64; + EE_Temp = Read_Data_PL7223[3]; + EE_Temp = EE_Temp << 8; + EE_Temp += Read_Data_PL7223[2]; + VA_rms = (float)EE_Temp/64.00; + + + //Irms address : 0x3008~0x3009 + // IA_rms = Read_Data_PL7223[3]+Read_Data_PL7223[2]/256; + EE_Temp = Read_Data_PL7223[8]; + IA_rms = (float)EE_Temp/256.00; + EE_Temp = Read_Data_PL7223[9]; + IA_rms = IA_rms + (float)EE_Temp; + + + //Active address : 0x3078~0x307D + // PA = Read_Data_PL7223[124]*256+Read_Data_PL7223[123]; + EE_Temp = Read_Data_PL7223[124]; + EE_Temp = EE_Temp << 8; + EE_Temp += Read_Data_PL7223[123]; + PA = (float)EE_Temp; + + //PF Calculate + // SA = VA_rms*IA_rms; + SA = VA_rms*IA_rms; + // PF_A = PA/SA + PF_A = SA==0? 0: PA/SA; + Theta_A = acos(PF_A); + QA = SA * sin(Theta_A); + if(IA_rms==0) + Theta_A = 0; + else + Theta_A = Theta_A * (180.00/(3.141592653589)); + + /** Frequency = [Sample_cnt0/(ZCC_STOP-ZCC_START)]*[(ZCC_CNT-1)/2] */ + Sample_cnt0 = Read_Data_PL7223[145]; // Sample_cnt01 + Sample_cnt0 = Sample_cnt0 <<8; + Sample_cnt0 += Read_Data_PL7223[144]; // Sample_cnt00 + + ZCC_cnt = Read_Data_PL7223[91]; // ZCC_cnt1 + ZCC_cnt = ZCC_cnt <<8; + ZCC_cnt += Read_Data_PL7223[90]; // ZCC_cnt0 + + ZCC_Stop = Read_Data_PL7223[97]; // ZCC_STOP1 + ZCC_Stop = ZCC_Stop <<8; + ZCC_Stop += Read_Data_PL7223[96]; // ZCC_STOP0 + + ZCC_Start = Read_Data_PL7223[103]; // ZCC_START1 + ZCC_Start = ZCC_Start <<8; + ZCC_Start += Read_Data_PL7223[102]; // ZCC_START0 + + Frequency = (float)((float)Sample_cnt0 / (ZCC_Stop - ZCC_Start)) * (((float)ZCC_cnt - 1.0) / 2); + +#define UART_Display(name) printf(#name" %d.%d\n\r", (int)(name*1000)/1000, (int)(name*1000)%1000) + UART_Display(VA_rms); + UART_Display(IA_rms); + UART_Display(Frequency); + UART_Display(PA); + UART_Display(QA); + UART_Display(SA); + UART_Display(PF_A); + UART_Display(Theta_A); +} +//--------------------------------------------------------------------------------------------// +void SPI_PL7223_DELY(int dely_cnt) // MCUCLK 4MHz, Delay-Time 9usec/clock +{ + HalDelayUs(dely_cnt*20); +} + +//--------------------------------------------------------------------------------------------// +void SPI_PL7223_SEND(unsigned char spicmd) +{ + SPDAT = (char)spi_master_write(&spi0_master, (int)spicmd); +} +//--------------------------------------------------------------------------------------------// + + diff --git a/USDK/example_sources/spi_stream_twoboard/readme.txt b/USDK/example_sources/spi_stream_twoboard/readme.txt new file mode 100644 index 0000000..0f773ad --- /dev/null +++ b/USDK/example_sources/spi_stream_twoboard/readme.txt @@ -0,0 +1,25 @@ +Example Description + +This example describes how to use SPI stream read/write by mbed api. + + +The SPI Interface provides a "Serial Peripheral Interface" Master. + +This interface can be used for communication with SPI slave devices, +such as FLASH memory, LCD screens and other modules or integrated circuits. + + +In this example, we use config SPI_IS_AS_MASTER to decide if device is master or slave. + If SPI_IS_AS_MASTER is 1, then device is master. + If SPI_IS_AS_MASTER is 0, then device is slave. + +We connect wires as below: + master's MOSI (PC_2) connect to slave's MOSI (PC_2) + master's MISO (PC_3) connect to slave's MISO (PC_3) + master's SCLK (PC_1) connect to slave's SCLK (PC_1) + master's CS (PC_0) connect to slave's CS (PC_0) + +This example shows master sends data to slave. +We bootup slave first, and then bootup master. +Then log will presents that master sending data to slave. +To ensure the order is correct, we use a GPIO pin to notify the master that the slave device is ready to write or read data. \ No newline at end of file diff --git a/USDK/example_sources/spi_stream_twoboard/src/main.c b/USDK/example_sources/spi_stream_twoboard/src/main.c new file mode 100644 index 0000000..2ed93e7 --- /dev/null +++ b/USDK/example_sources/spi_stream_twoboard/src/main.c @@ -0,0 +1,211 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "main.h" +#include "spi_api.h" +#include "spi_ex_api.h" + +#define SPI_IS_AS_MASTER 1 +#define TEST_BUF_SIZE 2048 +#define SCLK_FREQ 1000000 +#define SPI_DMA_DEMO 0 +#define TEST_LOOP 100 +#define GPIO_SYNC_PIN PA_1 + +// SPI0 +#define SPI0_MOSI PC_2 +#define SPI0_MISO PC_3 +#define SPI0_SCLK PC_1 +#define SPI0_CS PC_0 + +_LONG_CALL_ extern +void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader); +extern void wait_ms(u32); + +char TestBuf[TEST_BUF_SIZE]; +volatile int MasterTxDone; +volatile int MasterRxDone; +volatile int SlaveTxDone; +volatile int SlaveRxDone; +gpio_t GPIO_Syc; + +void master_tr_done_callback(void *pdata, SpiIrq event) +{ + switch(event){ + case SpiRxIrq: + DBG_8195A("Master RX done!\n"); + MasterRxDone = 1; + gpio_write(&GPIO_Syc, 0); + break; + case SpiTxIrq: + DBG_8195A("Master TX done!\n"); + MasterTxDone = 1; + break; + default: + DBG_8195A("unknown interrput evnent!\n"); + } +} + +void slave_tr_done_callback(void *pdata, SpiIrq event) +{ + switch(event){ + case SpiRxIrq: + DBG_8195A("Slave RX done!\n"); + SlaveRxDone = 1; + gpio_write(&GPIO_Syc, 0); + break; + case SpiTxIrq: + DBG_8195A("Slave TX done!\n"); + SlaveTxDone = 1; + break; + default: + DBG_8195A("unknown interrput evnent!\n"); + } +} + +#if SPI_IS_AS_MASTER +spi_t spi_master; +#else +spi_t spi_slave; +#endif +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + int Counter = 0; + int i; + gpio_init(&GPIO_Syc, GPIO_SYNC_PIN); + gpio_write(&GPIO_Syc, 0);//Initialize GPIO Pin to low + gpio_dir(&GPIO_Syc, PIN_OUTPUT); // Direction: Output + gpio_mode(&GPIO_Syc, PullNone); // No pull + +#if SPI_IS_AS_MASTER + spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); + spi_frequency(&spi_master, SCLK_FREQ); + spi_format(&spi_master, 16, (SPI_SCLK_IDLE_LOW|SPI_SCLK_TOGGLE_MIDDLE) , 0); + // wait Slave ready + + while (Counter < TEST_LOOP) { + DBG_8195A("======= Test Loop %d =======\r\n", Counter); + + for (i=0;i\r\n"); + MasterTxDone = 0; + while(gpio_read(&GPIO_Syc) == 0); +#if SPI_DMA_DEMO + spi_master_write_stream_dma(&spi_master, TestBuf, TEST_BUF_SIZE); +#else + spi_master_write_stream(&spi_master, TestBuf, TEST_BUF_SIZE); +#endif + i=0; + DBG_8195A("SPI Master Wait Write Done...\r\n"); + while(MasterTxDone == 0) { + wait_ms(10); + i++; + } + DBG_8195A("SPI Master Write Done!\r\n"); + + DBG_8195A("SPI Master Read Test==>\r\n"); + + + _memset(TestBuf, 0, TEST_BUF_SIZE); + spi_flush_rx_fifo(&spi_master); + + MasterRxDone = 0; + while(gpio_read(&GPIO_Syc) == 0); +#if SPI_DMA_DEMO + spi_master_read_stream_dma(&spi_master, TestBuf, TEST_BUF_SIZE); +#else + spi_master_read_stream(&spi_master, TestBuf, TEST_BUF_SIZE); +#endif + i=0; + DBG_8195A("SPI Master Wait Read Done...\r\n"); + while(MasterRxDone == 0) { + wait_ms(10); + i++; + } + DBG_8195A("SPI Master Read Done!\r\n"); + __rtl_memDump_v1_00(TestBuf, TEST_BUF_SIZE, "SPI Master Read Data:"); + Counter++; + } + spi_free(&spi_master); + DBG_8195A("SPI Master Test <==\r\n"); + +#else + spi_init(&spi_slave, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); + spi_format(&spi_slave, 16, (SPI_SCLK_IDLE_LOW|SPI_SCLK_TOGGLE_MIDDLE) , 1); + + while (spi_busy(&spi_slave)) { + DBG_8195A("Wait SPI Bus Ready...\r\n"); + wait_ms(1000); + } + + while (Counter < TEST_LOOP) { + DBG_8195A("======= Test Loop %d =======\r\n", Counter); + _memset(TestBuf, 0, TEST_BUF_SIZE); + DBG_8195A("SPI Slave Read Test ==>\r\n"); + spi_irq_hook(&spi_slave, slave_tr_done_callback, (uint32_t)&spi_slave); + SlaveRxDone = 0; + spi_flush_rx_fifo(&spi_slave); +#if SPI_DMA_DEMO + spi_slave_read_stream_dma(&spi_slave, TestBuf, TEST_BUF_SIZE); +#else + spi_slave_read_stream(&spi_slave, TestBuf, TEST_BUF_SIZE); +#endif + gpio_write(&GPIO_Syc, 1); + i=0; + DBG_8195A("SPI Slave Wait Read Done...\r\n"); + while(SlaveRxDone == 0) { + wait_ms(100); + i++; + if (i>150) { + DBG_8195A("SPI Slave Wait Timeout\r\n"); + break; + } + } + + __rtl_memDump_v1_00(TestBuf, TEST_BUF_SIZE, "SPI Slave Read Data:"); + + // Slave Write Test + DBG_8195A("SPI Slave Write Test ==>\r\n"); + SlaveTxDone = 0; +#if SPI_DMA_DEMO + spi_slave_write_stream_dma(&spi_slave, TestBuf, TEST_BUF_SIZE); +#else + spi_slave_write_stream(&spi_slave, TestBuf, TEST_BUF_SIZE); +#endif + gpio_write(&GPIO_Syc, 1); + + i=0; + DBG_8195A("SPI Slave Wait Write Done...\r\n"); + while(SlaveTxDone == 0) { + wait_ms(100); + i++; + if (i> 200) { + DBG_8195A("SPI Slave Write Timeout...\r\n"); + break; + } + } + DBG_8195A("SPI Slave Write Done!\r\n"); + Counter++; + } + spi_free(&spi_slave); +#endif + + DBG_8195A("SPI Demo finished.\n"); + for(;;); +} diff --git a/USDK/example_sources/spi_twoboard/readme.txt b/USDK/example_sources/spi_twoboard/readme.txt new file mode 100644 index 0000000..1232a3e --- /dev/null +++ b/USDK/example_sources/spi_twoboard/readme.txt @@ -0,0 +1,24 @@ +Example Description + +This example describes how to use SPI read/write by mbed api. + + +The SPI Interface provides a "Serial Peripheral Interface" Master. + +This interface can be used for communication with SPI slave devices, +such as FLASH memory, LCD screens and other modules or integrated circuits. + + +In this example, we use config SPI_IS_AS_MASTER to decide if device is master or slave. + If SPI_IS_AS_MASTER is 1, then device is master. + If SPI_IS_AS_MASTER is 0, then device is slave. + +We connect wires as below: + master's MOSI (PC_2) connect to slave's MOSI (PC_2) + master's MISO (PC_3) connect to slave's MISO (PC_3) + master's SCLK (PC_1) connect to slave's SCLK (PC_1) + master's CS (PC_0) connect to slave's CS (PC_0) + +This example shows master sends data to slave. +We bootup slave first, and then bootup master. +Then log will presents that master sending data to slave. \ No newline at end of file diff --git a/USDK/example_sources/spi_twoboard/src/main.c b/USDK/example_sources/spi_twoboard/src/main.c new file mode 100644 index 0000000..8b15fa0 --- /dev/null +++ b/USDK/example_sources/spi_twoboard/src/main.c @@ -0,0 +1,64 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2014 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "main.h" +#include "spi_api.h" + +#define SPI_IS_AS_MASTER 1 + +// SPI0 +#define SPI0_MOSI PC_2 +#define SPI0_MISO PC_3 +#define SPI0_SCLK PC_1 +#define SPI0_CS PC_0 + +/** + * @brief Main program. + * @param None + * @retval None + */ +void main(void) +{ + int TestingTimes = 10; + int Counter = 0; + int TestData = 0; + +#if SPI_IS_AS_MASTER + spi_t spi_master; + + SPI0_IS_AS_SLAVE = 0; + spi_init(&spi_master, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); + + DBG_SSI_INFO("--------------------------------------------------------\n"); + for(Counter = 0, TestData=0xFF; Counter < TestingTimes; Counter++) { + spi_master_write(&spi_master, TestData); + DBG_SSI_INFO("Master write: %02X\n", TestData); + TestData--; + } + spi_free(&spi_master); + +#else + spi_t spi_slave; + + SPI0_IS_AS_SLAVE = 1; + spi_init(&spi_slave, SPI0_MOSI, SPI0_MISO, SPI0_SCLK, SPI0_CS); + + DBG_SSI_INFO("--------------------------------------------------------\n"); + for(Counter = 0, TestData=0xFF; Counter < TestingTimes; Counter++) { + DBG_SSI_INFO(ANSI_COLOR_CYAN"Slave read : %02X\n"ANSI_COLOR_RESET, + spi_slave_read(&spi_slave)); + TestData--; + } + spi_free(&spi_slave); +#endif + + DBG_SSI_INFO("SPI Demo finished.\n"); + for(;;); +} diff --git a/USDK/example_sources/uart/readme.txt b/USDK/example_sources/uart/readme.txt new file mode 100644 index 0000000..f4ac25f --- /dev/null +++ b/USDK/example_sources/uart/readme.txt @@ -0,0 +1,19 @@ +Example Description + +This example describes how to use UART to communicate with PC. + +Required Components: + USBtoTTL adapter + +Connect to PC + - Connect Ground: connect to GND pin via USBtoTTL adapter + - Use UART1 + GPIOA_6 as UART1_RX connect to TX of USBtoTTL adapter + GPIOA_7 as UART1_TX connect to RX of USBtoTTL adapter + +Open Super terminal or teraterm and +set baud rate to 38400, 1 stopbit, no parity, no flow contorl. + +This example shows: +User input will be received by demo board, and demo board will loopback the received character with a prompt string "8195a$". + diff --git a/USDK/example_sources/uart/src/main.c b/USDK/example_sources/uart/src/main.c new file mode 100644 index 0000000..5ae87b2 --- /dev/null +++ b/USDK/example_sources/uart/src/main.c @@ -0,0 +1,46 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +#include "device.h" +#include "serial_api.h" +#include "main.h" + +#define UART_TX PA_7 +#define UART_RX PA_6 + +void uart_send_string(serial_t *sobj, char *pstr) +{ + unsigned int i=0; + + while (*(pstr+i) != 0) { + serial_putc(sobj, *(pstr+i)); + i++; + } +} + +void main(void) +{ + // sample text + char rc; + serial_t sobj; + + // mbed uart test + serial_init(&sobj,UART_TX,UART_RX); + serial_baud(&sobj,38400); + serial_format(&sobj, 8, ParityNone, 1); + + uart_send_string(&sobj, "UART API Demo...\r\n"); + uart_send_string(&sobj, "Hello World!\r\n"); + while(1){ + uart_send_string(&sobj, "\r\n8195a$"); + rc = serial_getc(&sobj); + serial_putc(&sobj, rc); + } +} + diff --git a/USDK/example_sources/uart_auto_flow_ctrl/readme.txt b/USDK/example_sources/uart_auto_flow_ctrl/readme.txt new file mode 100644 index 0000000..49af1c2 --- /dev/null +++ b/USDK/example_sources/uart_auto_flow_ctrl/readme.txt @@ -0,0 +1,22 @@ +Example Description + +This example demo the function of Auto Flow control. +Please connect 2 board to run this example. + + +Required Components: + 2 EV boards + +Connect to 2 borads + +Board1 Board2 +PA6 <-----> PA7 +PA7 <-----> PA6 +PA5 <-----> PA3 +PA3 <-----> PA5 +GND <-----> GND + +This example shows: +The first powered board will be the TX side, the othse one will be the RX side. +The RX side will make some delay every 16-bytes received, by this way we can trigger the flow control mechanism. + diff --git a/USDK/example_sources/uart_auto_flow_ctrl/src/main.c b/USDK/example_sources/uart_auto_flow_ctrl/src/main.c new file mode 100644 index 0000000..7f810f5 --- /dev/null +++ b/USDK/example_sources/uart_auto_flow_ctrl/src/main.c @@ -0,0 +1,123 @@ +/* + * Routines to access hardware + * + * Copyright (c) 2013 Realtek Semiconductor Corp. + * + * This module is a confidential and proprietary property of RealTek and + * possession or use of this module requires written permission of RealTek. + */ + +// This example demo the function of Auto Flow control +// Please connect 2 board to run this example. +// Board1 <-----> Board2 +// PA6 <-----> PA7 +// PA7 <-----> PA6 +// PA5 <-----> PA3 +// PA3 <-----> PA5 +// GND <-----> GND + +// The first started board will be the TX side, the othse one will be the RX side +// The RX side will make some delay every 16-bytes received, +// by this way we can trigger the flow control mechanism. + +#include "device.h" +#include "serial_api.h" +#include "main.h" + +#define UART_TX PA_7 +#define UART_RX PA_6 + +void uart_send_string(serial_t *sobj, char *pstr) +{ + unsigned int i=0; + + while (*(pstr+i) != 0) { + serial_putc(sobj, *(pstr+i)); + i++; + } +} +#define UART_BUF_SIZE 1000 + +serial_t sobj; +unsigned char buffer[UART_BUF_SIZE]; + +void main(void) +{ + // sample text + char rc; + int i,j; + int rx_side=0; + + // mbed uart test + HAL_GPIO_PullCtrl(UART_RX, PullUp); + serial_init(&sobj,UART_TX,UART_RX); + serial_baud(&sobj,38400); + serial_format(&sobj, 8, ParityNone, 1); + serial_set_flow_control(&sobj, FlowControlNone, 0, 0); // Pin assignment is ignored + + for (i=0;i<1000;i++) { + // Tide Break + DBG_8195A("Wait peer ready...\r\n"); + serial_putc(&sobj, i+1); + if (serial_readable(&sobj)) { + rc = serial_getc(&sobj); + if (rc > i) { + rx_side = 1; + } else { + rx_side = 0; + } + break; + } + wait_ms(100); + } + + serial_clear_rx(&sobj); + // Enable flow control + serial_set_flow_control(&sobj, FlowControlRTSCTS, 0, 0); // Pin assignment is ignored + + if (rx_side) { + DBG_8195A("UART Flow Control: RX ==>\r\n"); + _memset(buffer, 0, UART_BUF_SIZE); + + i = 0; + j = 0; + while (1) { + if (serial_readable(&sobj)) { + buffer[i] = serial_getc(&sobj); + i++; + if (i == UART_BUF_SIZE) { + break; + } + + if ((i&0xf) == 0) { + // Make some delay to cause the RX FIFO full and then trigger flow controll + wait_ms(100); + DBG_8195A("UART RX got %d bytes\r\n", i); + } + j=0; + } else { + wait_ms(10); + j++; + if (j== 1000) { + DBG_8195A("UART RX Failed, Got %d bytes\r\n", i); + break; + } + } + + } + } else { + DBG_8195A("UART Flow Control: TX ==>\r\n"); + wait_ms(500); + for (i=0;i extract image1, boot head in elf +COMPILED_BOOT=1 +# COMPILED_BOOT_BIN if !defined -> use source startup boot +#COMPILED_BOOT_BIN=1 +# PADDINGSIZE defined -> image2 OTA +PADDINGSIZE =44k + +NMAPFILE = $(OBJ_DIR)/$(TARGET).nmap + +#FLASHER_PATH ?= flasher/ + +#RAM_IMAGE?= $(BIN_DIR)/ram.bin + +RAM1_IMAGE ?= $(BIN_DIR)/ram_1.bin +RAM1P_IMAGE ?= $(BIN_DIR)/ram_1.p.bin +RAM1R_IMAGE ?= $(BIN_DIR)/ram_1.r.bin + +RAM2_IMAGE = $(BIN_DIR)/ram_2.bin +RAM2P_IMAGE = $(BIN_DIR)/ram_2.p.bin +RAM2NS_IMAGE = $(BIN_DIR)/ram_2.ns.bin + +RAM3_IMAGE = $(BIN_DIR)/sdram.bin +RAM3P_IMAGE = $(BIN_DIR)/sdram.p.bin + +FLASH_IMAGE = $(BIN_DIR)/ram_all.bin +OTA_IMAGE = $(BIN_DIR)/ota.bin + +#all: FLASH_IMAGE = $(BIN_DIR)/ram_all.bin +#all: OTA_IMAGE = $(BIN_DIR)/ota.bin +mp: FLASH_IMAGE = $(BIN_DIR)/ram_all_mp.bin +mp: OTA_IMAGE = $(BIN_DIR)/ota_mp.bin + +TST_IMAGE = $(BIN_DIR)/ram_2.bin + +.PHONY: genbin1 genbin23 flashburn reset test readfullflash flashwebfs flash_OTA +.NOTPARALLEL: all mp genbin1 genbin23 flashburn reset test readfullflash _endgenbin flashwebfs flash_OTA + +all: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin +mp: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin + +genbin1: $(ELFFILE) $(RAM1P_IMAGE) + +genbin23: $(ELFFILE) $(OTA_IMAGE) $(FLASH_IMAGE) _endgenbin + + +_endgenbin: + @echo "-----------------------------------------------------------" + @echo "Image ($(OTA_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(OTA_IMAGE)) )) ) bytes" + @echo "Image ($(FLASH_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(FLASH_IMAGE)) )) ) bytes" + @echo "===========================================================" + +ifeq ($(FLASHER_TYPE), Jlink) + +reset: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_Reset.JLinkScript + +runram: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_RunRAM.JLinkScript + +readfullflash: + @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed 1000 $(FLASHER_PATH)RTL_FFlash.JLinkScript + + +flashburn: + @echo define call1>$(FLASHER_PATH)flash_file.jlink + @echo SetFirwareSize build/bin/ram_all.bin>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @echo define call2>>$(FLASHER_PATH)flash_file.jlink + @echo FlasherWrite build/bin/ram_all.bin 0 '$$'Image1Size>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @echo define call3>>$(FLASHER_PATH)flash_file.jlink + @echo FlasherWrite build/bin/ram_all.bin '$$'Image2Addr '$$'Image2Size>>$(FLASHER_PATH)flash_file.jlink + @echo end>>$(FLASHER_PATH)flash_file.jlink + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_wrflash.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +flashwebfs: + @echo define call1>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageSize = $(shell printf '0x%X\n' $$(stat --printf="%s" $(BIN_DIR)/WEBFiles.bin))>>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageAddr = 0x0D0000>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @echo define call2>>$(FLASHER_PATH)file_info.jlink + @echo FlasherWrite $(BIN_DIR)/WEBFiles.bin '$$'ImageAddr '$$'ImageSize>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_wrfile.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +flashespfs: + @echo define call1>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageSize = $(shell printf '0x%X\n' $$(stat --printf="%s" $(BIN_DIR)/webpages.espfs))>>$(FLASHER_PATH)file_info.jlink + @echo set '$$'ImageAddr = 0x0D0000>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @echo define call2>>$(FLASHER_PATH)file_info.jlink + @echo FlasherWrite $(BIN_DIR)/webpages.espfs '$$'ImageAddr '$$'ImageSize>>$(FLASHER_PATH)file_info.jlink + @echo end>>$(FLASHER_PATH)file_info.jlink + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_wrfile.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + + +flash_OTA: + @cmd /K start $(JLINK_PATH)$(JLINK_GDBSRV) -device Cortex-M3 -if SWD -ir -endian little -speed 1000 + @$(GDB) -x $(FLASHER_PATH)gdb_ota.jlink + #@taskkill /F /IM $(JLINK_GDBSRV) + +else + +flashburn: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(RAM1P_IMAGE) 0" \ + -c "rtl8710_flash_write $(RAM2P_IMAGE) 0xb000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +flashimage2p: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(RAM2P_IMAGE) 0xb000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +flashwebfs: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(BIN_DIR)/WEBFiles.bin 0xd0000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +flashespfs: + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" \ + -c "rtl8710_flash_write $(BIN_DIR)/webpages.espfs 0xd0000" \ + -c "rtl8710_reboot" -c "reset run" -c shutdown + +reset: +# @$(JLINK_PATH)$(JLINK_EXE) -Device CORTEX-M3 -If SWD -Speed $(FLASHER_SPEED) flasher/RTLreset.JLinkScript + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "rtl8710_reboot" -c shutdown + +runram: +# @$(JLINK_PATH)$(JLINK_GDB) -device Cortex-M3 -if SWD -ir -endian little -speed $(FLASHER_SPEED) +# @$(GDB) -x flasher/gdb_run_ram.jlink +# @taskkill.exe -F -IM $(JLINK_GDB) + @$(OPENOCD) -f interface/$(FLASHER).cfg -c "transport select swd" -f $(FLASHER_PATH)rtl8710.ocd -c "init" -c "adapter_khz $(FLASHER_SPEED)" -c "reset halt" \ + -c "load_image $(RAM1R_IMAGE) 0x10000bc8 bin" \ + -c "load_image $(RAM2_IMAGE) 0x10006000 bin" \ + -c "mww 0x40000210 0x20200113" \ + -c "reset run" -c shutdown + +endif + +$(NMAPFILE): $(ELFFILE) + @echo "===========================================================" + @echo "Build names map file" + @echo $@ + @$(NM) $< | sort > $@ +# @echo "===========================================================" + +$(FLASH_IMAGE): $(RAM1P_IMAGE) $(RAM2P_IMAGE) $(RAM3P_IMAGE) + @echo "===========================================================" + @echo "Make Flash image ($(FLASH_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(FLASH_IMAGE) + @cat $(RAM1P_IMAGE) > $(FLASH_IMAGE) +# @chmod 777 $(FLASH_IMAGE) +ifdef PADDINGSIZE + @$(PADDING) $(PADDINGSIZE) 0xFF $(FLASH_IMAGE) +endif + @cat $(RAM2P_IMAGE) >> $(FLASH_IMAGE) + @cat $(RAM3P_IMAGE) >> $(FLASH_IMAGE) +# @echo "Image ($(FLASH_IMAGE)) size $(shell printf '%d\n' $$(( $$(stat --printf="%s" $(FLASH_IMAGE)) )) ) bytes" +# @echo "===========================================================" +# @rm $(BIN_DIR)/ram_*.p.bin + +$(OTA_IMAGE): $(RAM2NS_IMAGE) $(RAM3_IMAGE) + @echo "===========================================================" + @echo "Make OTA image ($(OTA_IMAGE))" + @rm -f $(OTA_IMAGE) + @cat $(RAM2NS_IMAGE) > $(OTA_IMAGE) + @cat $(RAM3P_IMAGE) >> $(OTA_IMAGE) +# @chmod 777 $(OTA_IMAGE) + @$(CHCKSUM) $(OTA_IMAGE) || true +# @echo "===========================================================" + +$(RAM1P_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image1r ($(RAM1R_IMAGE))" +# @echo "===========================================================" .bootloader +ifdef COMPILED_BOOT + @mkdir -p $(BIN_DIR) + @rm -f $(RAM1_IMAGE) $(RAM1R_IMAGE) +ifdef COMPILED_BOOT_BIN + @$(eval RAM1_START_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_start $(NMAPFILE) | awk '{print $$1}')) + @$(eval RAM1_END_ADDR := $(shell grep _binary_build_bin_ram_1_r_bin_end $(NMAPFILE) | awk '{print $$1}')) +else + @$(eval RAM1_START_ADDR := $(shell grep __ram_image1_text_start__ $(NMAPFILE) | awk '{print $$1}')) + @$(eval RAM1_END_ADDR := $(shell grep __ram_image1_text_end__ $(NMAPFILE) | awk '{print $$1}')) +endif + $(if $(RAM1_START_ADDR),,$(error "Not found __ram_image1_text_start__!")) + $(if $(RAM1_END_ADDR),,$(error "Not found __ram_image1_text_end__!")) +ifeq ($(RAM1_START_ADDR),$(RAM1_END_ADDR)) +ifdef COMPILED_BOOT_BIN + $(OBJCOPY) --change-section-address .boot.head=0x10000ba8 -j .boot.head -j .bootloader -Obinary $(ELFFILE) $(RAM1P_IMAGE) +else +# $(OBJCOPY) -j .rom_ram -Obinary $(ELFFILE) $(RAM_IMAGE) + $(OBJCOPY) -j .ram.start.table -j .ram_image1.text -Obinary $(ELFFILE) $(RAM1R_IMAGE) + $(PICK) 0x$(RAM1_START_ADDR) 0x$(RAM1_END_ADDR) $(RAM1R_IMAGE) $(RAM1P_IMAGE) head+reset_offset 0x0B000 +endif +else + $(error "BOOT-image size = 0") +# $(error Flasher: COMPILE_BOOT = No) +endif +else + @if [ -s $(RAM1R_IMAGE) ]; then echo "Use external $(RAM1R_IMAGE)!"; fi +endif + +$(RAM2P_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image2p ($(RAM2P_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(RAM2_IMAGE) $(RAM2P_IMAGE) + @$(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + @$(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!")) + $(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!")) + @$(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE) + @$(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2P_IMAGE) body+reset_offset+sig + +$(RAM2NS_IMAGE):$(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image2ns ($(RAM2NS_IMAGE))" +# @echo "===========================================================" + mkdir -p $(BIN_DIR) + rm -f $(RAM2_IMAGE) $(RAM2NS_IMAGE) + $(eval RAM2_START_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + $(eval RAM2_END_ADDR = $(shell grep __ram_image2_text $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM2_START_ADDR),,$(error "Not found __ram_image2_text_start__!")) + $(if $(RAM2_END_ADDR),,$(error "Not found __ram_image2_text_end__!")) + $(OBJCOPY) -j .image2.start.table -j .ram_image2.text -j .ram_image2.rodata -j .ram.data -Obinary $(ELFFILE) $(RAM2_IMAGE) + $(PICK) 0x$(RAM2_START_ADDR) 0x$(RAM2_END_ADDR) $(RAM2_IMAGE) $(RAM2NS_IMAGE) body+reset_offset + +$(RAM3_IMAGE): $(ELFFILE) $(NMAPFILE) + @echo "===========================================================" + @echo "Create image3 (SDRAM, $(RAM3P_IMAGE))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) + @rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE) + @$(eval RAM3_START_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _start__ | awk '{print $$1}')) + @$(eval RAM3_END_ADDR = $(shell grep __sdram_data_ $(NMAPFILE) | grep _end__ | awk '{print $$1}')) + $(if $(RAM3_START_ADDR),,$(error "Not found __sdram_data_start__!")) + $(if $(RAM3_END_ADDR),,$(error "Not found __sdram_data_end__!")) +#ifneq ($(RAM3_START_ADDR),$(RAM3_END_ADDR)) + @echo $(RAM3_START_ADDR) $(RAM3_END_ADDR) + @$(OBJCOPY) -j .image3 -j .sdr_text -j .sdr_rodata -j .sdr_data -Obinary $(ELFFILE) $(RAM3_IMAGE) + $(PICK) 0x$(RAM3_START_ADDR) 0x$(RAM3_END_ADDR) $(RAM3_IMAGE) $(RAM3P_IMAGE) body+reset_offset +#else +# @rm -f $(RAM3_IMAGE) $(RAM3P_IMAGE) +# @echo "SDRAM not used (size = 0)" +#endif + +$(ELFFILE): + $(error Falsher: file $@ not found) + +clean: + @rm -f $(BIN_DIR)/*.bin + \ No newline at end of file diff --git a/USDK/flasher/RTL00ConsoleROM.JLinkScript b/USDK/flasher/RTL00ConsoleROM.JLinkScript new file mode 100644 index 0000000..5b85200 --- /dev/null +++ b/USDK/flasher/RTL00ConsoleROM.JLinkScript @@ -0,0 +1,6 @@ +h +loadbin flasher/RTL00Console_ROM.bin 0x10000ba8 +r +w4 0x40000210,0x4011117 +g +q \ No newline at end of file diff --git a/USDK/flasher/RTL00Console_ROM.bin b/USDK/flasher/RTL00Console_ROM.bin new file mode 100644 index 0000000..e83cb16 Binary files /dev/null and b/USDK/flasher/RTL00Console_ROM.bin differ diff --git a/USDK/flasher/RTL8710.jflash b/USDK/flasher/RTL8710.jflash new file mode 100644 index 0000000..a5d0547 --- /dev/null +++ b/USDK/flasher/RTL8710.jflash @@ -0,0 +1,119 @@ + AppVersion = 47812 +[GENERAL] + ConnectMode = 0 + CurrentFile = "fullflash.bin" + DataFileSAddr = 0x98000000 + GUIMode = 0 + HostName = "" + TargetIF = 1 + USBPort = 0 + USBSerialNo = 0x00000000 +[JTAG] + IRLen = 0 + MultipleTargets = 0 + NumDevices = 0 + Speed0 = 400 + Speed1 = 12000 + TAP_Number = 0 + UseAdaptive0 = 0 + UseAdaptive1 = 0 + UseMaxSpeed0 = 0 + UseMaxSpeed1 = 0 +[CPU] + CheckCoreID = 0 + ChipName = "RTL8710AF" + ClockSpeed = 0x00000000 + Core = 0x030000FF + CoreID = 0x00000000 + CoreIDMask = 0x0F000FFF + DeviceFamily = 0x00000003 + EndianMode = 0 + HasInternalFlash = 0 + InitStep0_Action = "Reset" + InitStep0_Comment = "Reset and Halt" + InitStep0_Value0 = 0x00000000 + InitStep0_Value1 = 0x00000005 + InitStep1_Action = "Go" + InitStep1_Comment = "" + InitStep1_Value0 = 0x00000000 + InitStep1_Value1 = 0x00000000 + InitStep2_Action = "Reset" + InitStep2_Comment = "Reset and halt target" + InitStep2_Value0 = 0x00000000 + InitStep2_Value1 = 0x00000005 + InitStep3_Action = "Write Register" + InitStep3_Comment = "Only T=1" + InitStep3_Value0 = 0x00000010 + InitStep3_Value1 = 0x01000000 + InitStep4_Action = "Write 32bit" + InitStep4_Comment = "Setup SystemCoreClock" + InitStep4_Value0 = 0x40000014 + InitStep4_Value1 = 0x00000001 + InitStep5_Action = "Delay" + InitStep5_Comment = "" + InitStep5_Value0 = 0x00000000 + InitStep5_Value1 = 0x00000005 + InitStep6_Action = "Write 32bit" + InitStep6_Comment = "Write Page Size" + InitStep6_Value0 = 0x1FFFFFF0 + InitStep6_Value1 = 0x00000100 + InitStep7_Action = "Write 32bit" + InitStep7_Comment = "Write Sector Size" + InitStep7_Value0 = 0x1FFFFFF4 + InitStep7_Value1 = 0x00001000 + InitStep8_Action = "Write 32bit" + InitStep8_Comment = "Write Block Size" + InitStep8_Value0 = 0x1FFFFFF8 + InitStep8_Value1 = 0x00010000 + InitStep9_Action = "Write 32bit" + InitStep9_Comment = "Write Block Count" + InitStep9_Value0 = 0x1FFFFFFC + InitStep9_Value1 = 0x00000010 + NumExitSteps = 0 + NumInitSteps = 10 + RAMAddr = 0x10000000 + RAMSize = 0x00010000 + ScriptFile = "" + UseAutoSpeed = 0x00000001 + UseRAM = 1 + UseScriptFile = 0 +[FLASH] + aSectorSel[0] = + AutoDetect = 1 + BankName = "" + BankSelMode = 1 + BaseAddr = 0x98000000 + CheckId = 3 + CustomRAMCode = "RTL8710AF.hex" + DeviceName = "Auto detected flash memory" + EndBank = 8191 + NumBanks = 1 + OrgNumBits = 16 + OrgNumChips = 1 + StartBank = 0 + UseCustomRAMCode = 1 +[PRODUCTION] + AutoPerformsErase = 1 + AutoPerformsHardLock = 0 + AutoPerformsHardUnlock = 0 + AutoPerformsProgram = 1 + AutoPerformsSecure = 0 + AutoPerformsSoftLock = 0 + AutoPerformsSoftUnlock = 1 + AutoPerformsStartApp = 0 + AutoPerformsUnsecure = 0 + AutoPerformsVerify = 1 + EnableProductionMode = 0 + EnableTargetPower = 0 + EraseType = 2 + ProductionDelay = 0x000001F4 + ProductionThreshold = 0x00000BB8 + ProgramSN = 0 + SerialFile = "" + SNAddr = 0x00000000 + SNInc = 0x00000001 + SNLen = 0x00000004 + SNListFile = "" + SNValue = 0x00000001 + TargetPowerDelay = 0x00000014 + VerifyType = 1 diff --git a/USDK/flasher/RTL8710AF.hex b/USDK/flasher/RTL8710AF.hex new file mode 100644 index 0000000..fd2dc4c --- /dev/null +++ b/USDK/flasher/RTL8710AF.hex @@ -0,0 +1,130 @@ +:100000007D0439057F05FF056506D506D706000086 +:10001000D44908707047D44800680005FBD0D14827 +:100020000078C0B2704710B5D048006850F44070F6 +:10003000CE490860CE48006850F01000CC490860F6 +:10004000CC480468062000F0B7F934F00600C9492E +:100050000860C848006850F00100C64908600020E8 +:10006000C54908600020C54908600120C4490860EE +:100070000220C44908600020C34908600020C34929 +:1000800008600020C249086010BD2DE9F04104005D +:100090000D001600B6B2002E01D1002048E0B6B225 +:1000A000112E01DB102006004FF4407000F084F99F +:1000B00080465FF4401000F07FF95FF4403000F0BC +:1000C0007BF95FF4402000F077F9032010FA08F084 +:1000D00010F44070AF490860B6B2AF480660032024 +:1000E000FFF796FF200CC0B2FFF792FF200AC0B2C4 +:1000F000FFF78EFF2000C0B2FFF78AFF01209E4964 +:100100000860002007003800310080B289B28842C0 +:1001100005D2FFF780FFBFB2E8557F1CF3E79F4889 +:100120000068C007FBD4002093490860300080B20B +:10013000BDE8F08138B54FF4407000F03DF905009E +:100140005FF4401000F038F95FF4403000F034F90B +:100150005FF4402000F030F90320A84010F4407014 +:100160008C49086003208C4908600120824908609E +:100170009F20FFF74DFFFFF74EFF0400FFF74BFFF7 +:1001800054EA00200400FFF746FF54EA0040040050 +:1001900082480068C007FBD400207749086020002F +:1001A00032BD38B54FF4407000F006F905005FF439 +:1001B000401000F001F95FF4403000F0FDF85FF40A +:1001C000402000F0F9F80320A84010F44070714975 +:1001D0000860012070490860012067490860052017 +:1001E000FFF716FFFFF717FF04006C480068C00711 +:1001F000FBD40020604908602000C0B232BD38B591 +:1002000004004FF4407000F0D7F805005FF4401090 +:1002100000F0D2F85FF4403000F0CEF85FF44020F8 +:1002200000F0CAF80120A84010F440705949086055 +:100230000120514908602000C0B2FFF7E9FE57488D +:100240000068C007FBD400204B49086031BD38B5B9 +:1002500004004FF4407000F0AFF805005FF4401068 +:1002600000F0AAF85FF4403000F0A6F85FF44020F8 +:1002700000F0A2F80120A84010F440704549086041 +:1002800001203D4908602020FFF7C2FE200CC0B2CB +:10029000FFF7BEFE200AC0B2FFF7BAFE2000C0B2D0 +:1002A000FFF7B6FE3D480068C007FBD40020324986 +:1002B000086031BD2DE9F04104000D001600B6B212 +:1002C000002E01D100204BE0B6B2B6F5807F02DDF2 +:1002D0004FF4807006004FF4407000F06DF88046D7 +:1002E0005FF4401000F068F85FF4403000F064F80C +:1002F0005FF4402000F060F8012010FA08F010F4DC +:1003000040702449086001201B4908600220FFF763 +:100310007FFE200CC0B2FFF77BFE200AC0B2FFF7C1 +:1003200077FE2000C0B2FFF773FE00200700380000 +:10033000310080B289B2884205D2BFB2E85DFFF7D2 +:1003400067FE7F1CF3E7154800684007FBD513489C +:100350000068C007FBD4002007490860300080B265 +:10036000BDE8F08160600040246000403002004041 +:1003700010020040C0020040086000402C600040B5 +:100380001060004014600040186000401C60004095 +:100390004C60004000600040046000402860004065 +:1003A00080B5FFF7FEFEC007FBD401BD80B5FFF7A7 +:1003B000F8FE8007FBD501BD90FAA0F0B0FA80F0FE +:1003C00070470000010051EA510151EA910151EAE0 +:1003D000111151EA112151EA1141064A7A441432AD +:1003E000DFF8B03203FB01F3DB0E52F823201000DC +:1003F000704700BF80030000DFF89C02006850F0E7 +:100400004070DFF894120860DFF89002006850F442 +:100410008070DFF888120860FF20DFF8841208601F +:10042000FF20DFF880120860704780B500F054F9B3 +:1004300001BD0120DFF870120860704780B571B609 +:1004400072B6FFF7F6FFFFF7D7FFFFF7EEFF01BD2C +:1004500080B5FFF7E8FDFFF7A3FFFFF76BFEFFF79F +:100460009FFF92480068FFF7ADFF914908609148EF +:100470000068FFF7A7FF9049086001BDF8B50400C8 +:100480000D0016008D4800688D49884204D18D48C2 +:1004900000688D49884209D08948884908608A489F +:1004A00088490860FFF7CAFFFFF7D2FF814800685C +:1004B00086490968864A12685143B1FBF0F27368B5 +:1004C00040271F807A4F3F689F700027DF70012709 +:1004D0001F7101275F7100279F710127DF710127BD +:1004E0001F7200275F7201279F7201271F6100277B +:1004F000DFF8DCC1DCF800C067451CD2DFF8CCC1F6 +:10050000DCF800C00CFB07FC5FF00C0E0EFB07FED6 +:100510009E44CEF814C05FF00C0C0CFB07FC9C440E +:10052000CCF818205FF00C0C0CFB07FC9C44CCF8BA +:100530001C007F1CDCE7F1BD2DE9F04704000D0035 +:1005400016007769D6F81080D6F80490002F14D0E2 +:10055000200000F0C0F8112F02D35FF0100A00E075 +:10056000BA46524692B249464046FFF78EFD1AEB14 +:100570000808D144B7EB0A07E8E7BDE8F0872DE9A2 +:10058000F84F04000D0016000020286077694848E5 +:100590000068B84638FA00F8D6F810904448006869 +:1005A00039FA00F9D6F804A0B8F1000F25D0B7F554 +:1005B000807F02D94FF4807B00E0BB46FFF7F0FE5E +:1005C0000620FFF71CFEFFF7F1FE5A4692B2514695 +:1005D0003648006800FB09F0FFF76CFEFFF7E0FE0D +:1005E0000420FFF70CFEFFF7DBFEDA44B7EB0B0746 +:1005F000B8F1010819F10109D6E7BDE8F18F2DE93D +:10060000F84304000D00160030692B490968C84002 +:10061000070070698046002028602648006800FBBB +:1006200007F08146B8F1000F1AD0200000F053F80F +:10063000FFF7B6FE0620FFF7E2FDFFF7B7FE4846DC +:10064000FFF705FEFFF7ACFE0420FFF7D8FDFFF72C +:10065000A7FE1848006810EB0909B8F10108E1E7A6 +:10066000BDE8F18310B504001448006814498842BD +:1006700004D1144800681449884209D010480F4931 +:10068000086011480F490860FFF7D8FEFFF7E0FE49 +:1006900010BD0000DDACC407300200401C02004069 +:1006A000200300402403004014000040F0FFFF1F1F +:1006B000E0FFFF1FF4FFFF1FE4FFFF1FE8FFFF1F26 +:1006C000AA55AA55ECFFFF1F55AA55AAF8FFFF1F10 +:1006D000FCFFFF1F7047704710B51E48006850F4BC +:1006E00040501C4908601C48006850F480501A496A +:1006F00008601A4800684006FBD5194804685FF492 +:100700004000FFF759FE34F44000154908601448D2 +:10071000006850F4801012490860002011490860F8 +:100720001148006850F080000F49086044200F49CC +:10073000086000200B49086003240320FFF73CFEFB +:1007400014FA00F010F0030007490860002008497F +:10075000086010BD3002004010020040143000401C +:10076000C0020040043000400C3000400030004027 +:1007700008300040000000000900000001000000F7 +:100780000A0000000D00000015000000020000003B +:100790001D0000000B0000000E0000001000000013 +:1007A0001200000016000000190000000300000005 +:1007B0001E000000080000000C00000014000000F3 +:1007C0001C0000000F0000001100000018000000D5 +:1007D00007000000130000001B00000017000000CD +:1007E000060000001A0000000500000004000000E0 +:0407F0001F000000E6 +:0400000500000000F7 +:00000001FF diff --git a/USDK/flasher/RTL_FFlash.JLinkScript b/USDK/flasher/RTL_FFlash.JLinkScript new file mode 100644 index 0000000..a9ed900 --- /dev/null +++ b/USDK/flasher/RTL_FFlash.JLinkScript @@ -0,0 +1,17 @@ +h +r +w4 0x40000230,0x0000D3C4 +w4 0x40000210,0x00200113 +w4 0x400002C0,0x00110001 +w4 0x40006008,0 +w4 0x4000602C,0 +w4 0x40006010,1 +w4 0x40006014,2 +w4 0x40006018,0 +w4 0x4000601C,0 +w4 0x4000604C,0 +savebin fullflash.bin 0x98000000 0x100000 +w4 0x40000210,0x211157 +r +g +q \ No newline at end of file diff --git a/USDK/flasher/RTL_RdROM.JLinkScript b/USDK/flasher/RTL_RdROM.JLinkScript new file mode 100644 index 0000000..d57dabd --- /dev/null +++ b/USDK/flasher/RTL_RdROM.JLinkScript @@ -0,0 +1,11 @@ +r0 +trst0 +r1 +trst1 +h +r +savebin bios-rom.bin 0x00000000 0x100000 +w4 0x40000210,0x211157 +r +g +q \ No newline at end of file diff --git a/USDK/flasher/RTL_Reset.JLinkScript b/USDK/flasher/RTL_Reset.JLinkScript new file mode 100644 index 0000000..196d12a --- /dev/null +++ b/USDK/flasher/RTL_Reset.JLinkScript @@ -0,0 +1,9 @@ +r0 +trst0 +r1 +trst1 +h +r +w4 0x40000210,0x111157 +g +q \ No newline at end of file diff --git a/USDK/flasher/RTL_RunRAM.JLinkScript b/USDK/flasher/RTL_RunRAM.JLinkScript new file mode 100644 index 0000000..5991456 --- /dev/null +++ b/USDK/flasher/RTL_RunRAM.JLinkScript @@ -0,0 +1,12 @@ +r0 +trst0 +r1 +trst1 +h +r +loadbin build/bin/ram_1.r.bin 0x10000bc8 +loadbin build/bin/ram_2.bin 0x10006000 +r +w4 0x40000210,0x20111157 +g +q \ No newline at end of file diff --git a/USDK/flasher/add_sample_bat/DAPLink-RTL00Console.bat b/USDK/flasher/add_sample_bat/DAPLink-RTL00Console.bat new file mode 100644 index 0000000..bc0d13c --- /dev/null +++ b/USDK/flasher/add_sample_bat/DAPLink-RTL00Console.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "load_ram_binary RTL00Console_ROM.bin 0x10000BA8" -c "exit" +rem -c "shutdown" + + diff --git a/USDK/flasher/add_sample_bat/DAPLink-RdFullFlash.bat b/USDK/flasher/add_sample_bat/DAPLink-RdFullFlash.bat new file mode 100644 index 0000000..5861662 --- /dev/null +++ b/USDK/flasher/add_sample_bat/DAPLink-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 5000" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/USDK/flasher/add_sample_bat/DAPLink-Reset.bat b/USDK/flasher/add_sample_bat/DAPLink-Reset.bat new file mode 100644 index 0000000..aceee70 --- /dev/null +++ b/USDK/flasher/add_sample_bat/DAPLink-Reset.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +@cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "restart_from_falsh" -c "shutdown" +rem + diff --git a/USDK/flasher/add_sample_bat/DAPLink_WrFullFlash.bat b/USDK/flasher/add_sample_bat/DAPLink_WrFullFlash.bat new file mode 100644 index 0000000..bd1cf72 --- /dev/null +++ b/USDK/flasher/add_sample_bat/DAPLink_WrFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/cmsis-dap.cfg -c "adapter_khz 3500" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "rtl8710_flash_auto_erase 1" -c "rtl8710_flash_auto_verify 1" -c "rtl8710_flash_write fullflash.bin 0" -c "shutdown" +pause + diff --git a/USDK/flasher/add_sample_bat/JLink-RTL00ConsoleROM.bat b/USDK/flasher/add_sample_bat/JLink-RTL00ConsoleROM.bat new file mode 100644 index 0000000..d8488c6 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLink-RTL00ConsoleROM.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +start JLink.exe -Device CORTEX-M3 -If SWD -Speed 4000 flasher\RTL00ConsoleROM.JLinkScript diff --git a/USDK/flasher/add_sample_bat/JLink-RdFullFlash.bat b/USDK/flasher/add_sample_bat/JLink-RdFullFlash.bat new file mode 100644 index 0000000..de5d955 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLink-RdFullFlash.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +JLink.exe -Device CORTEX-M3 -If SWD -Speed 10000 flasher/RTL_FFlash.JLinkScript diff --git a/USDK/flasher/add_sample_bat/JLink-Reset.bat b/USDK/flasher/add_sample_bat/JLink-Reset.bat new file mode 100644 index 0000000..51ea2a8 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLink-Reset.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +JLink.exe -Device CORTEX-M3 -If SWD -Speed 1000 flasher\RTL_Reset.JLinkScript diff --git a/USDK/flasher/add_sample_bat/JLink-RunRAM.bat b/USDK/flasher/add_sample_bat/JLink-RunRAM.bat new file mode 100644 index 0000000..4282a8e --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLink-RunRAM.bat @@ -0,0 +1,3 @@ +@echo off +call paths.bat +start JLink.exe -Device CORTEX-M3 -If SWD -Speed 4000 flasher\RTL_RunRAM.JLinkScript diff --git a/USDK/flasher/add_sample_bat/JLinkGDB-RdFullFlash.bat b/USDK/flasher/add_sample_bat/JLinkGDB-RdFullFlash.bat new file mode 100644 index 0000000..76865da --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkGDB-RdFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_rdflash.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/USDK/flasher/add_sample_bat/JLinkGDB-RunRAM.bat b/USDK/flasher/add_sample_bat/JLinkGDB-RunRAM.bat new file mode 100644 index 0000000..323aa3a --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkGDB-RunRAM.bat @@ -0,0 +1,15 @@ +@echo off +call paths.bat +@if exist build\obj\build.axf goto run +echo File 'build\obj\build.axf' not found! +echo Build project... +mingw32-make.exe -f Makefile all +@if not exist build\obj\build.axf goto err +:run +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_run_ram.jlink +taskkill /F /IM JLinkGDBServer.exe +goto end +:err +echo Error! +:end \ No newline at end of file diff --git a/USDK/flasher/add_sample_bat/JLinkGDB-WrFlash.bat b/USDK/flasher/add_sample_bat/JLinkGDB-WrFlash.bat new file mode 100644 index 0000000..c70f651 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkGDB-WrFlash.bat @@ -0,0 +1,21 @@ +@echo off +call paths.bat +@if %1x==x goto xxx +set img_file=%1 +goto run +:xxx +set img_file=build/bin/ram_all.bin +:run +echo define call1>flasher/flash_file.jlink +echo SetFirwareSize %img_file%>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +echo define call2>>flasher/flash_file.jlink +echo FlasherWrite %img_file% 0 $Image1Size>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +echo define call3>>flasher/flash_file.jlink +echo FlasherWrite %img_file% $Image2Addr $Image2Size>>flasher/flash_file.jlink +echo end>>flasher/flash_file.jlink +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 3500 +arm-none-eabi-gdb.exe -x flasher/gdb_wrflash.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/USDK/flasher/add_sample_bat/JLinkGDBServer.bat b/USDK/flasher/add_sample_bat/JLinkGDBServer.bat new file mode 100644 index 0000000..c356ac1 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkGDBServer.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_init.jlink +taskkill /F /IM JLinkGDBServer.exe + diff --git a/USDK/flasher/add_sample_bat/JLinkGDB_OTA.bat b/USDK/flasher/add_sample_bat/JLinkGDB_OTA.bat new file mode 100644 index 0000000..f64317e --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkGDB_OTA.bat @@ -0,0 +1,15 @@ +@echo off +call paths.bat +@if exist build\bin\ota.bin goto run +echo File 'build\obj\ota.bin' not found! +echo Build project... +mingw32-make.exe -f Makefile all +@if not exist build\bin\ota.bin goto err +:run +start start JLinkGDBServer.exe -device Cortex-M3 -if SWD -ir -endian little -speed 1000 +arm-none-eabi-gdb.exe -x flasher/gdb_ota.jlink +taskkill /F /IM JLinkGDBServer.exe +goto end +:err +echo Error! +:end \ No newline at end of file diff --git a/USDK/flasher/add_sample_bat/JLinkOCD-RdFullFlash.bat b/USDK/flasher/add_sample_bat/JLinkOCD-RdFullFlash.bat new file mode 100644 index 0000000..4708bea --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLinkOCD-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/Jlink.cfg -c "adapter_khz 3500" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 3900" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/USDK/flasher/add_sample_bat/JLink_RdFullFlash.bat b/USDK/flasher/add_sample_bat/JLink_RdFullFlash.bat new file mode 100644 index 0000000..450e141 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JLink_RdFullFlash.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +openocd -f interface/Jlink.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "adapter_khz 3500" -c "rtl8710_flash_read_id" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/USDK/flasher/add_sample_bat/JlinkOpenOCD.bat b/USDK/flasher/add_sample_bat/JlinkOpenOCD.bat new file mode 100644 index 0000000..6e354f6 --- /dev/null +++ b/USDK/flasher/add_sample_bat/JlinkOpenOCD.bat @@ -0,0 +1,4 @@ +@echo off +call paths.bat +taskkill /F /IM openocd.exe +start openocd -f interface\Jlink.cfg -f flasher\ameba1.cfg diff --git a/USDK/flasher/add_sample_bat/STLink-RdFullFlash.bat b/USDK/flasher/add_sample_bat/STLink-RdFullFlash.bat new file mode 100644 index 0000000..af82648 --- /dev/null +++ b/USDK/flasher/add_sample_bat/STLink-RdFullFlash.bat @@ -0,0 +1,7 @@ +@echo off +call paths.bat +cd flasher +openocd -f interface/stlink-v2.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "rtl8710_flash_read_id" -c "adapter_khz 5000" -c "rtl8710_flash_read ../fullflash.bin 0 1048576" -c "shutdown" +echo flash read fullflash.bin +pause + diff --git a/USDK/flasher/add_sample_bat/STLink-Reset.bat b/USDK/flasher/add_sample_bat/STLink-Reset.bat new file mode 100644 index 0000000..d4aeb47 --- /dev/null +++ b/USDK/flasher/add_sample_bat/STLink-Reset.bat @@ -0,0 +1,6 @@ +@echo off +call paths.bat +@cd flasher +openocd -f interface/stlink-v2.cfg -c "adapter_khz 1000" -f rtl8710.ocd -f cortex.ocd -c "init" -c "reset halt" -c "cortex_reboot" -c "shutdown" +rem + diff --git a/USDK/flasher/add_sample_bat/ameba_tools.py b/USDK/flasher/add_sample_bat/ameba_tools.py new file mode 100644 index 0000000..99e62c1 --- /dev/null +++ b/USDK/flasher/add_sample_bat/ameba_tools.py @@ -0,0 +1,40 @@ +import jlinkarm as jl + +def loaddll(dll_path): + jl.loadJLinkARMdll(dll_path) + jl.open() + if jl.is_connected == 0: + raise RuntimeError('Jlink not connected') + jl.exec_command('device Cortex-M3', 0, 0) + jl.exec_command('endian little', 0, 0) + jl.tif_select(1) + jl.set_speed(1000) + jl.clear_RESET() + jl.clear_TRST() + time.sleep(0.01) + jl.set_RESET() + jl.set_TRST() + jl.reset() + jl.halt() + jl.set_speed(3500) + +def ram_all(binfile, image1=True, image2=True): + bin = None + with file(binfile, 'rb') as f: + bin = f.read() + get_dword = lambda address: struct.unpack('= 2: + if sys.argv[1] == '-h': + print 'Usage: ldram.py ram_all.bin' + exit(0) + imgfilename = 'build/bin/ram_all.bin' + + if len(sys.argv) > 1: + if sys.argv[1]: + imgfilename = sys.argv[1] + try: + ff = open(imgfilename, "rb") + except: + print "Error file open " + imgfilename + exit(1) + jl.loadJLinkARMdll(dllfilename) + jl.open() + if jl.is_connected == 0: + raise RuntimeError('Jlink not connected') + jl.exec_command('device Cortex-M3', 0, 0) + jl.exec_command('endian little', 0, 0) + jl.tif_select(1) + jl.set_speed(1000) + jl.clear_RESET() + jl.clear_TRST() + time.sleep(0.01) + jl.set_RESET() + jl.set_TRST() + jl.reset() + jl.halt() + jl.set_speed(3500) + bin = ff.read() + get_dword = lambda address: struct.unpack('> 16) & 0x0ff) + if ($id == 0x1420c2) + printf "Flash ID = 0x%08x : MX25L8006E (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + else + printf "Flash ID = 0x%08x : (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + end + printf "RTL8710 flasher initialized\n" +else +printf "reinitializing RTL8710 flasher\n" +end +end +################## +# FlasherRdBlock # +################## +define FlasherRdBlock +#printf "FlashRdBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 3 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "read error, offset 0x%08x", $arg0 +end +end +################## +# FlasherWrBlock # +################## +define FlasherWrBlock +#printf "FlashWrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 4 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "write error, offset 0x%08x", $arg0 +end +end +################## +# FlasherVrBlock # +################## +define FlasherVrBlock +#printf "FlashVrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 5 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + set $status = {int}($rtl8710_flasher_buffer + 0x0C) + set $status = {int}($status + $arg0) + error "verify error, offset 0x%08x", $status +end +end +################# +# FlashSecErase # +################# +define FlashSecErase +#printf "FlashSecErase 0x%08x, 0x%08x\n", $rtl8710_flasher_buffer, $arg0 +set {int}($rtl8710_flasher_buffer + 0x04) = 2 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +end +################ +# FlasherWrite # +################ +define FlasherWrite +set $sector = 0 +set $offset = 0 +set $size = $arg2 +while $offset < $size + set $len = $size - $offset + if $len > $rtl8710_flasher_buffer_size + set $len = $rtl8710_flasher_buffer_size + end + set $flash_offset = $arg1 + $offset + printf "write offset 0x%08x\n", $flash_offset + set $parms1 = $rtl8710_flasher_buffer + 0x20 - $offset + set $parms2 = $offset + set $parms3 = $offset + $len + restore $arg0 binary $parms1 $parms2 $parms3 + if $rtl8710_flasher_auto_erase != 0 + set $count_i = $flash_offset + while $count_i < ($flash_offset + $len) + set $sector = $count_i/$rtl8710_flasher_sector_size + if $rtl8710_flasher_auto_erase_sector != $sector + set $parms1 = $sector * $rtl8710_flasher_sector_size + printf "erase sector %d at 0x%08x\n", $sector, $parms1 + FlashSecErase $parms1 + set $rtl8710_flasher_auto_erase_sector = $sector + end + set $count_i = $count_i + 1 + end + end + FlasherWrBlock $flash_offset $len + printf "write %d bytes at 0x%08x\n", $len, $flash_offset + if $rtl8710_flasher_auto_verify != 0 + printf "verify offset 0x%08x len %d\n", $flash_offset, $len + FlasherVrBlock $flash_offset $len + end + set $offset = $offset + $rtl8710_flasher_buffer_size +end +end +######################################### +InitJlink +SystemInit +SetClk166MHz +SPI_Init +GetOtaSize build/bin/ota.bin +if $ImageOtaSize != 0 + FlasherInit + FlasherLoad flasher/rtl8710_flasher.bin + set $FixOtaAddr = 0x80000 + set $pbuffer = $rtl8710_flasher_buffer + 0x20 + FlasherRdBlock 0x9000 0x1000 + set $ImageOtaAddr = {int}($pbuffer) + if $ImageOtaAddr != $FixOtaAddr + printf "ImageOtaAddr = 0x%08x - Invalid!\n", $ImageOtaAddr + set {int}($pbuffer) = $FixOtaAddr + set $Temp = $ImageOtaAddr & $FixOtaAddr + if $Temp != $FixOtaAddr + printf "FlashSecErase at 0x9000\n" + FlashSecErase 0x9000 + printf "Write offset 0x9000 4096 bytes\n" + FlasherWrBlock 0x9000 0x1000 + else + printf "Write offset 0x9000 4 bytes\n" + FlasherWrBlock 0x9000 0x0004 + end + end + FlasherWrite build/bin/ota.bin $FixOtaAddr $ImageOtaSize + restore build/bin/ota.bin binary $pbuffer 0 0x1000 + set {int}($pbuffer + 0x08) = 0x35393138 + set {int}($pbuffer + 0x0C) = 0x31313738 + FlasherWrBlock $FixOtaAddr 0x10 + FlashImagesInfo +end +monitor reset +SetBootFlash +monitor go +quit diff --git a/USDK/flasher/gdb_rdflash.jlink b/USDK/flasher/gdb_rdflash.jlink new file mode 100644 index 0000000..674ce48 --- /dev/null +++ b/USDK/flasher/gdb_rdflash.jlink @@ -0,0 +1,17 @@ +# GDB Jlink read fullflash +# Init +source -v flasher/gdb_flasher.jlink +InitJlink +SystemInit +SPI_Init +monitor speed 12000 +#FlashInfo +# Read FullFlash +printf "Read FullFlash:\n" +set $dumpstartaddr = $SPI_FLASH_BASE +set $dumpendaddr = $SPI_FLASH_BASE + 0x100000 +printf "Start addr of dumping = 0x%08x\n", $dumpstartaddr +printf "End addr of dumping = 0x%08x\n", $dumpendaddr +dump binary memory ../fullflash.bin $dumpstartaddr $dumpendaddr +printf "FullFlash saved in ./build/bin/fullflash.bin - OK.\n" +quit diff --git a/USDK/flasher/gdb_run_ram.jlink b/USDK/flasher/gdb_run_ram.jlink new file mode 100644 index 0000000..ad6a86d --- /dev/null +++ b/USDK/flasher/gdb_run_ram.jlink @@ -0,0 +1,11 @@ +# +# J-LINK GDB SERVER initialization +# +source -v flasher/gdb_flasher.jlink +InitJlink +load build/obj/build.axf +SetBootCall4 +monitor reset +monitor go +quit + diff --git a/USDK/flasher/gdb_wrflash.jlink b/USDK/flasher/gdb_wrflash.jlink new file mode 100644 index 0000000..4a4af92 --- /dev/null +++ b/USDK/flasher/gdb_wrflash.jlink @@ -0,0 +1,166 @@ +############### +# FlasherInit # +############### +define FlasherInit +set $rtl8710_flasher_capacity = 0 +set $rtl8710_flasher_auto_erase = 1 +set $rtl8710_flasher_auto_verify = 1 +set $rtl8710_flasher_firmware_ptr = 0x10001000 +set $rtl8710_flasher_buffer = 0x10008000 +#262144 +set $rtl8710_flasher_buffer_size = 421888 +set $rtl8710_flasher_sector_size = 4096 +set $rtl8710_flasher_auto_erase_sector = 0xFFFFFFFF +end +############### +# FlasherWait # +############### +define FlasherWait +set $fresult = {int}($rtl8710_flasher_buffer) +while ($fresult != 0) +set $fresult = {int}($rtl8710_flasher_buffer) +end +end +############### +# FlasherLoad # +############### +define FlasherLoad +if $rtl8710_flasher_capacity == 0 + printf "initializing RTL8710 flasher\n" + restore $arg0 binary $rtl8710_flasher_firmware_ptr 0 968 + monitor reset + set $pc = $rtl8710_flasher_firmware_ptr + set $sp = 0x1ffffffc + set {int}($rtl8710_flasher_buffer + 0x08) = 0 + set {int}($rtl8710_flasher_buffer + 0x00) = 1 + #continue + monitor go + FlasherWait + set $id = {int}($rtl8710_flasher_buffer + 0x0C) + if ($id == 0x1420c2) + set $rtl8710_flasher_capacity = 1 << (($id >> 16) & 0x0ff) + printf "Flash ID = 0x%08x : MX25L8006E (%d kbytes)\n", $id, $rtl8710_flasher_capacity>>10 + else + set $rtl8710_flasher_capacity = 1024*1024) + error "Flash ID = 0x%08x : ?\n", $id + end + printf "RTL8710 flasher initialized\n" +else +printf "reinitializing RTL8710 flasher\n" +end +end +################## +# FlasherWrBlock # +################## +define FlasherWrBlock +#printf "FlashWrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 4 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + error "write error, offset 0x%08x", $arg0 +end +end +################## +# FlasherVrBlock # +################## +define FlasherVrBlock +#printf "FlashVrBlock 0x%08x, 0x%08x\n", $arg0, $arg1 +set {int}($rtl8710_flasher_buffer + 0x04) = 5 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x14) = $arg1 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +set $status = {int}($rtl8710_flasher_buffer + 0x08) +if $status > 0 + set $status = {int}($rtl8710_flasher_buffer + 0x0C) + set $status = {int}($status + $arg0) + error "verify error, offset 0x%08x", $status +end +end +################# +# FlashSecErase # +################# +define FlashSecErase +#printf "FlashSecErase 0x%08x, 0x%08x\n", $rtl8710_flasher_buffer, $arg0 +set {int}($rtl8710_flasher_buffer + 0x04) = 2 +set {int}($rtl8710_flasher_buffer + 0x08) = 0 +set {int}($rtl8710_flasher_buffer + 0x10) = $arg0 +set {int}($rtl8710_flasher_buffer + 0x00) = 1 +FlasherWait +end +################ +# FlasherWrite # +################ +define FlasherWrite +set $sector = 0 +set $offset = 0 +set $size = $arg2 +while $offset < $size + set $len = $size - $offset + if $len > $rtl8710_flasher_buffer_size + set $len = $rtl8710_flasher_buffer_size + end + set $flash_offset = $arg1 + $offset + printf "write offset 0x%08x\n", $flash_offset + set $parms1 = $rtl8710_flasher_buffer + 0x20 - $offset - $arg1 + set $parms2 = $offset + $arg1 + set $parms3 = $offset + $len + $arg1 + restore $arg0 binary $parms1 $parms2 $parms3 + if $rtl8710_flasher_auto_erase != 0 + set $count_i = $flash_offset + while $count_i < ($flash_offset + $len) + set $sector = $count_i/$rtl8710_flasher_sector_size + if $rtl8710_flasher_auto_erase_sector != $sector + set $parms1 = $sector * $rtl8710_flasher_sector_size + printf "erase sector %d at 0x%08x\n", $sector, $parms1 + FlashSecErase $parms1 + set $rtl8710_flasher_auto_erase_sector = $sector + end + set $count_i = $count_i + 1 + end + end + FlasherWrBlock $flash_offset $len + printf "wrote %d bytes at 0x%08x\n", $len, $flash_offset + if $rtl8710_flasher_auto_verify != 0 + printf "verify offset 0x%08x len %d\n", $flash_offset, $len + FlasherVrBlock $flash_offset $len + end + set $offset = $offset + $rtl8710_flasher_buffer_size +end +end +######################################### +source -v flasher/gdb_flasher.jlink +source -v flasher/flash_file.jlink +InitJlink +SystemInit +SetClk166MHz +SPI_Init +FlashImagesInfo +#SetFirwareSize $wr_flile +call1 +if $FirmwareSize == 0 + error "FirmwareSize = 0!" +end +FlasherInit +FlasherLoad flasher/rtl8710_flasher.bin +if $Image1Size != 0 + printf "Write Image1 size %d to Flash addr 0x00000000:\n", $Image1Size + #FlasherWrite $wr_flile 0 $Image1Size + call2 + if $Image2Size != 0 && $Image2Addr >= $Image1Size + printf "Write Image2 size %d to Flash addr 0x%08x:\n", $Image2Size, $Image2Addr + #FlasherWrite $wr_flile $Image2Addr $Image2Size + call3 + end +end +FlashImagesInfo +monitor reset +SetBootFlash +monitor go +quit diff --git a/USDK/flasher/rtl8710.ocd b/USDK/flasher/rtl8710.ocd new file mode 100644 index 0000000..2f2b102 --- /dev/null +++ b/USDK/flasher/rtl8710.ocd @@ -0,0 +1,340 @@ +# +# OpenOCD script for RTL8710 +# Copyright (C) 2016 Rebane, rebane@alkohol.ee +# +set CHIPNAME rtl8195a +set CHIPSERIES ameba1 + +# Adapt based on what transport is active. + +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME rtl8710 +} + +if { [info exists ENDIAN] } { + set _ENDIAN $ENDIAN +} else { + set _ENDIAN little +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x800 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x2ba01477 +} + +swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_TARGETNAME + +$_TARGETNAME configure -work-area-phys 0x10001000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +# adapter_khz 500 +adapter_nsrst_delay 100 + +if {![using_hla]} { + cortex_m reset_config sysresetreq vectreset +} + +set rtl8710_flasher_firmware_ptr 0x10001000 +set rtl8710_flasher_buffer 0x10008000 +set rtl8710_flasher_buffer_size 262144 +set rtl8710_flasher_sector_size 4096 + +array set rtl8710_flasher_code { + 0 0xB671B57F 1 0x25FF4B58 2 0x6B196B1A 3 0x7040F042 4 0x69D96318 5 0xF4414E55 + 6 0x69D97480 7 0xF8D361DC 8 0xF8C32120 9 0xF8D35120 10 0xF8C31124 11 0x47B05124 + 12 0x47B04E4F 13 0x47984B4F 14 0x60104A4F 15 0x484F47B0 16 0x60012100 17 0x2C006804 + 18 0x4D4DD0FC 19 0xB93E682E 20 0x60264C49 21 0x47B04E46 22 0x47984B46 23 0xE7ED6020 + 24 0x2B01682B 25 0x4E42D109 26 0x4C4647B0 27 0x47A02006 28 0x47904A45 29 0x47A020C7 + 30 0x682AE00D 31 0xD10E2A02 32 0x47B04E3B 33 0x20064C3F 34 0x483F47A0 35 0x493F4780 + 36 0x68084D3F 37 0x47B047A8 38 0x47A02004 39 0x6828E7CE 40 0xD1132803 41 0x47A04C32 + 42 0x24004838 43 0x4E396805 44 0x68311960 45 0xD206428C 46 0x4B384A37 47 0x221018A1 + 48 0x34104798 49 0x4D2AE7F3 50 0xE7B847A8 51 0x29046829 52 0x2400D11B 53 0x6806482F + 54 0xD2B042B4 55 0x47A84D24 56 0x20064E28 57 0x4B2847B0 58 0x49284798 59 0x680A4B2A + 60 0x18A018E1 61 0xF44F4B2A 62 0x47987280 63 0x200447A8 64 0xF50447B0 65 0x47A87480 + 66 0x682CE7E4 67 0xD1232C05 68 0x47984B17 69 0x4D1F2400 70 0x4294682A 71 0x481BD28F + 72 0x68012210 73 0x18604E1D 74 0x47B04669 75 0x1B19682B 76 0xBF282910 77 0x23002110 + 78 0xD011428B 79 0xF81D4A16 80 0x18A05003 81 0x42B55CC6 82 0x3301D101 83 0x4A15E7F4 + 84 0x60112101 85 0xE7726054 86 0x25014E12 87 0xE76E6035 88 0x47A84D03 89 0xE7D63410 + 90 0x40000200 91 0x100011BD 92 0x100013DD 93 0x10001289 94 0x1000800C 95 0x10008000 + 96 0x10008004 97 0x1000130D 98 0x100013ED 99 0x10008010 100 0x10001335 101 0x10008014 + 102 0x10008020 103 0x10001221 104 0x10001375 105 0x10008008 106 0x6A5A4B03 107 0xD0FB0512 + 108 0x0060F893 109 0xBF004770 110 0x40006000 111 0x6B194B17 112 0xF4416B1A 113 0x63187040 + 114 0x69186919 115 0x0110F041 116 0xF8D36119 117 0x220000C0 118 0x0106F020 119 0x00C0F8D3 + 120 0x10C0F8C3 121 0x00C0F8D3 122 0x0101F040 123 0x00C0F8D3 124 0x10C0F8C3 125 0x43BCF503 + 126 0x609A6899 127 0x20016AD9 128 0x691962DA 129 0x69596118 130 0x61592102 131 0x619A6999 + 132 0x61DA69D9 133 0x64DA6CD9 134 0xBF004770 135 0x40000200 136 0x460EB570 137 0xB34A4614 + 138 0xF3C04B15 139 0x681A4507 140 0x7240F44F 141 0x685A601A 142 0xF3C02103 143 0x2C102207 + 144 0x2410BF28 145 0x605CB2C0 146 0x1060F883 147 0x5060F883 148 0xF8832101 149 0xF8832060 + 150 0x689A0060 151 0x60992500 152 0x47984B08 153 0x35015570 154 0x42A2B2AA 155 0x4804D3F8 + 156 0xF0116A81 157 0xD1FA0301 158 0x60836881 159 0xBD704620 160 0x40006000 161 0x100011A9 + 162 0x4C10B5F8 163 0x68232003 164 0x7340F44F 165 0x68636023 166 0x60602101 167 0x68A3229F + 168 0x60A14D0B 169 0x2060F884 170 0x460647A8 171 0x460747A8 172 0x040347A8 173 0x2707EA43 + 174 0x0006EA47 175 0x4B036AA1 176 0x0201F011 177 0x6899D1FA 178 0xBDF8609A 179 0x40006000 + 180 0x100011A9 181 0x4C0BB510 182 0x68232001 183 0x7340F44F 184 0x68636023 185 0x60602105 + 186 0x60A068A2 187 0xF8844A06 188 0x47901060 189 0x4B036AA1 190 0x0201F011 191 0x6899D1FA + 192 0xBD10609A 193 0x40006000 194 0x100011A9 195 0x21014B08 196 0xF44F681A 197 0x601A7280 + 198 0x6099689A 199 0x0060F883 200 0x48036A9A 201 0x0101F012 202 0x6883D1FA 203 0x47706081 + 204 0x40006000 205 0x21014B0E 206 0xF44F681A 207 0x601A7280 208 0x2220689A 209 0xF8836099 + 210 0xF3C02060 211 0xF3C04107 212 0xB2C02207 213 0x1060F883 214 0x2060F883 215 0x0060F883 + 216 0x4A036A99 217 0x0001F011 218 0x6893D1FA 219 0x47706090 220 0x40006000 221 0xB36AB530 + 222 0x25014B17 223 0xF44F681C 224 0x601C7480 225 0x2402689C 226 0xF883609D 227 0xF3C04060 + 228 0xF3C04507 229 0xB2C02407 230 0x5060F883 231 0x7F80F5B2 232 0xF44FBF28 233 0xF8837280 + 234 0xF8834060 235 0x20000060 236 0x4C095C0D 237 0xF8843001 238 0xB2855060 239 0xD3F74295 + 240 0x07496A99 241 0x6AA0D5FC 242 0xF0104B03 243 0xD1FA0101 244 0x60996898 245 0xBD304610 + 246 0x40006000 247 0x4B02B508 248 0x07C04798 249 0xBD08D4FB 250 0x100012D5 251 0x4B04B508 + 252 0xF0004798 253 0xB2C10002 254 0xD0F82900 255 0xBF00BD08 256 0x100012D5 +} + +set rtl8710_flasher_command_read_id 0 +set rtl8710_flasher_command_mass_erase 1 +set rtl8710_flasher_command_sector_erase 2 +set rtl8710_flasher_command_read 3 +set rtl8710_flasher_command_write 4 +set rtl8710_flasher_command_verify 5 + +set rtl8710_flasher_ready 0 +set rtl8710_flasher_capacity 0 +set rtl8710_flasher_auto_erase 0 +set rtl8710_flasher_auto_verify 0 +set rtl8710_flasher_auto_erase_sector 0xFFFFFFFF + +proc rtl8710_flasher_init {} { + global rtl8710_flasher_firmware_ptr + global rtl8710_flasher_buffer + global rtl8710_flasher_capacity + global rtl8710_flasher_ready + global rtl8710_flasher_code + + if {[expr {$rtl8710_flasher_ready == 0}]} { + echo "initializing RTL8710 flasher" + halt + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + array2mem rtl8710_flasher_code 32 $rtl8710_flasher_firmware_ptr [array size rtl8710_flasher_code] + reg faultmask 0x01 + reg sp 0x20000000 + reg pc $rtl8710_flasher_firmware_ptr + resume + rtl8710_flasher_wait + set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set rtl8710_flasher_capacity [expr {2 ** [expr {($id >> 16) & 0xFF}]}] + set rtl8710_flasher_ready 1 + echo "RTL8710 flasher initialized" + } + return "" +} + +proc rtl8710_flasher_mrw {reg} { + set value "" + mem2array value 32 $reg 1 + return $value(0) +} + +proc rtl8710_flasher_wait {} { + global rtl8710_flasher_buffer + while {[rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x00}]]} { } +} + +proc rtl8710_flasher_load_block {local_filename offset len} { + global rtl8710_flasher_buffer + load_image $local_filename [expr {$rtl8710_flasher_buffer + 0x20 - $offset}] bin [expr {$rtl8710_flasher_buffer + 0x20}] $len +} + +proc rtl8710_flasher_read_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_read + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + error "read error, offset $offset" + } +} + +proc rtl8710_flasher_write_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_write + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_write + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + error "write error, offset $offset" + } +} + +proc rtl8710_flasher_verify_block {offset len} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_verify + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_verify + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x14}] $len + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x08}]] + if {[expr {$status > 0}]} { + set status [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set status [expr {$status + $offset}] + error "verify error, offset $status" + } +} + +proc rtl8710_flash_read_id {} { + global rtl8710_flasher_buffer + global rtl8710_flasher_capacity + global rtl8710_flasher_command_read_id + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_read_id + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait + set id [rtl8710_flasher_mrw [expr {$rtl8710_flasher_buffer + 0x0C}]] + set manufacturer_id [format "0x%02X" [expr {$id & 0xFF}]] + set memory_type [format "0x%02X" [expr {($id >> 8) & 0xFF}]] + set memory_capacity [expr {2 ** [expr {($id >> 16) & 0xFF}]}] + echo "manufacturer ID: $manufacturer_id, memory type: $memory_type, memory capacity: $memory_capacity bytes" +} + +proc rtl8710_flash_mass_erase {} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_mass_erase + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_mass_erase + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait +} + +proc rtl8710_flash_sector_erase {offset} { + global rtl8710_flasher_buffer + global rtl8710_flasher_command_sector_erase + rtl8710_flasher_init + mww [expr {$rtl8710_flasher_buffer + 0x04}] $rtl8710_flasher_command_sector_erase + mww [expr {$rtl8710_flasher_buffer + 0x08}] 0x00000000 + mww [expr {$rtl8710_flasher_buffer + 0x10}] $offset + mww [expr {$rtl8710_flasher_buffer + 0x00}] 0x00000001 + rtl8710_flasher_wait +} + +proc rtl8710_flash_read {local_filename loc size} { + global rtl8710_flasher_buffer + global rtl8710_flasher_buffer_size + rtl8710_flasher_init + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "read offset $flash_offset" + rtl8710_flasher_read_block $flash_offset $len + dump_image _rtl8710_flasher.bin [expr {$rtl8710_flasher_buffer + 0x20}] $len + exec dd conv=notrunc if=_rtl8710_flasher.bin "of=$local_filename" bs=1 "seek=$offset" + echo "read $len bytes" + } +} + +proc rtl8710_flash_write {local_filename loc} { + global rtl8710_flasher_buffer_size + global rtl8710_flasher_sector_size + global rtl8710_flasher_auto_erase + global rtl8710_flasher_auto_verify + global rtl8710_flasher_auto_erase_sector + rtl8710_flasher_init + set sector 0 + set size [file size $local_filename] + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "write offset $flash_offset" + rtl8710_flasher_load_block $local_filename $offset $len + if {[expr {$rtl8710_flasher_auto_erase != 0}]} { + for {set i $flash_offset} {$i < [expr {$flash_offset + $len}]} {incr i} { + set sector [expr {$i / $rtl8710_flasher_sector_size}] + if {[expr {$rtl8710_flasher_auto_erase_sector != $sector}]} { + echo "erase sector $sector" + rtl8710_flash_sector_erase [expr {$sector * $rtl8710_flasher_sector_size}] + set rtl8710_flasher_auto_erase_sector $sector + } + } + } + rtl8710_flasher_write_block $flash_offset $len + echo "wrote $len bytes" + if {[expr {$rtl8710_flasher_auto_verify != 0}]} { + echo "verify offset $flash_offset" + rtl8710_flasher_verify_block $flash_offset $len + } + } +} + +proc rtl8710_flash_verify {local_filename loc} { + global rtl8710_flasher_buffer_size + rtl8710_flasher_init + set size [file size $local_filename] + for {set offset 0} {$offset < $size} {set offset [expr {$offset + $rtl8710_flasher_buffer_size}]} { + set len [expr {$size - $offset}] + if {[expr {$len > $rtl8710_flasher_buffer_size}]} { + set len $rtl8710_flasher_buffer_size + } + set flash_offset [expr {$loc + $offset}] + echo "read offset $flash_offset" + rtl8710_flasher_load_block $local_filename $offset $len + echo "verify offset $flash_offset" + rtl8710_flasher_verify_block $flash_offset $len + } +} + +proc rtl8710_flash_auto_erase {on} { + global rtl8710_flasher_auto_erase + if {[expr {$on != 0}]} { + set rtl8710_flasher_auto_erase 1 + echo "auto erase on" + } else { + set rtl8710_flasher_auto_erase 0 + echo "auto erase off" + } +} + +proc rtl8710_flash_auto_verify {on} { + global rtl8710_flasher_auto_verify + if {[expr {$on != 0}]} { + set rtl8710_flasher_auto_verify 1 + echo "auto verify on" + } else { + set rtl8710_flasher_auto_verify 0 + echo "auto verify off" + } +} + +proc rtl8710_reboot {} { + echo "# Set processor clock to default before system reset" + mww 0x40000014 0x00000021 + sleep 10 + echo "# Reboot (system reset)" + mww 0xE000ED0C 0x05FA0007 +} + diff --git a/USDK/flasher/rtl8710_flasher.bin b/USDK/flasher/rtl8710_flasher.bin new file mode 100644 index 0000000..6c7e36d Binary files /dev/null and b/USDK/flasher/rtl8710_flasher.bin differ diff --git a/USDK/paths.mk b/USDK/paths.mk new file mode 100644 index 0000000..f2ab592 --- /dev/null +++ b/USDK/paths.mk @@ -0,0 +1,44 @@ +#--------------------------- +# User defined (in userset.mk) +#--------------------------- +SDK_PATH ?= ../SDKRTLA/USDK/ +#GCC_PATH = d:/MCU/GNU_Tools_ARM_Embedded/5.2_2015q4/bin/# + or set in PATH +#OPENOCD_PATH = d:/MCU/OpenOCD/bin/# + or set in PATH +TOOLS_PATH ?= $(SDK_PATH)component/soc/realtek/8195a/misc/iar_utility/common/tools/ +FLASHER_TYPE ?= Jlink +#FLASHER_TYPE ?= OCD +FLASHER_PATH ?= $(SDK_PATH)flasher/ +JLINK_PATH ?= D:/MCU/SEGGER/JLink_V612i/ +JLINK_GDBSRV ?= JLinkGDBServer.exe +#--------------------------- +# Default +#--------------------------- +# Compilation tools +CROSS_COMPILE = $(GCC_PATH)arm-none-eabi- +AR = $(CROSS_COMPILE)ar +CC = $(CROSS_COMPILE)gcc +AS = $(CROSS_COMPILE)as +NM = $(CROSS_COMPILE)nm +LD = $(CROSS_COMPILE)gcc +GDB = $(CROSS_COMPILE)gdb +SIZE = $(CROSS_COMPILE)size +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +# TARGET dirs +TARGET ?= build +OBJ_DIR ?= $(TARGET)/obj +BIN_DIR ?= $(TARGET)/bin +ELFFILE ?= $(OBJ_DIR)/$(TARGET).axf + +# Make bunary tools +ifneq ($(shell uname), Linux) +EXE = .exe +endif +PICK = $(TOOLS_PATH)pick$(EXE) +PADDING = $(TOOLS_PATH)padding$(EXE) +CHCKSUM = $(TOOLS_PATH)checksum$(EXE) + +# openocd tools +OPENOCD = $(OPENOCD_PATH)openocd + diff --git a/USDK/sdkbuild.mk b/USDK/sdkbuild.mk new file mode 100644 index 0000000..51b918d --- /dev/null +++ b/USDK/sdkbuild.mk @@ -0,0 +1,93 @@ +include userset.mk +include $(SDK_PATH)paths.mk +include project.mk + +INCFLAGS = $(patsubst %,-I%,$(patsubst sdk/%,$(SDK_PATH)%,$(INCLUDES))) + +LIBFLAGS = $(addprefix -L,$(patsubst sdk/%,$(SDK_PATH)%,$(PATHLIBS))) $(addprefix -l,$(LIBS)) + +LFLAGS += -Wl,-Map=$(OBJ_DIR)/$(TARGET).map + +CFLAGS += $(INCFLAGS) + +SRC_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(ADD_SRC_C))) $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(SRC_C))) +DRAM_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(DRAM_C))) +BOOT_O = $(patsubst %.c,%.o,$(patsubst sdk/%,$(SDK_PATH)%,$(BOOT_C))) + +SRC_C_LIST = $(patsubst sdk/%,$(SDK_PATH)%,$(ADD_SRC_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(SRC_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(DRAM_C)) $(patsubst sdk/%,$(SDK_PATH)%,$(BOOT_C)) +OBJ_LIST = $(addprefix $(OBJ_DIR)/,$(patsubst %.c,%.o,$(SRC_C_LIST))) +DEPENDENCY_LIST = $(patsubst %.c,$(OBJ_DIR)/%.d,$(SRC_C_LIST)) + +TARGET ?= build +OBJ_DIR ?= $(TARGET)/obj +BIN_DIR ?= $(TARGET)/bin +ELFFILE ?= $(OBJ_DIR)/$(TARGET).axf + +all: prerequirement application +mp: prerequirement application + +.PHONY: build_info +build_info: + @echo \#define UTS_VERSION \"`date +%Y/%m/%d-%T`\" > .ver + @echo \#define RTL8195AFW_COMPILE_TIME \"`date +%Y/%m/%d-%T`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_DATE \"`date +%Y%m%d`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_BY \"`id -u -n`\" >> .ver + @echo \#define RTL8195AFW_COMPILE_HOST \"`$(HOSTNAME_APP)`\" >> .ver + @if [ -x /bin/dnsdomainname ]; then \ + echo \#define RTL8195AFW_COMPILE_DOMAIN \"`dnsdomainname`\"; \ + elif [ -x /bin/domainname ]; then \ + echo \#define RTL8195AFW_COMPILE_DOMAIN \"`domainname`\"; \ + else \ + echo \#define RTL8195AFW_COMPILE_DOMAIN ; \ + fi >> .ver + @echo \#define RTL195AFW_COMPILER \"gcc `$(CC) $(CFLAGS) -dumpversion | tr --delete '\r'`\" >> .ver + @mv -f .ver project/inc/$@.h + +.PHONY: application +application: build_info $(SRC_O) $(DRAM_O) $(BOOT_O) + @echo "===========================================================" + @echo "Link ($(TARGET))" +# @echo "===========================================================" + @mkdir -p $(BIN_DIR) $(OBJ_DIR) + @$(file > $(OBJ_DIR)/obj_list.lst,$(OBJ_LIST)) + @$(LD) $(LFLAGS) -o $(ELFFILE) @$(OBJ_DIR)/obj_list.lst $(LIBFLAGS) -T$(LDFILE) + @$(OBJDUMP) -d $(ELFFILE) > $(OBJ_DIR)/$(TARGET).asm + +.PHONY: prerequirement +#.NOTPARALLEL: prerequirement +prerequirement: +# @$(file >DEPENDENCY_LIST.txt,$(DEPENDENCY_LIST)) + @echo "===========================================================" + @echo "Compile ($(TARGET))" +# @echo "===========================================================" + @mkdir -p $(OBJ_DIR) + +$(SRC_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +$(DRAM_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(OBJCOPY) --prefix-alloc-sections .sdram $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +$(BOOT_O): %.o : %.c + @echo $< + @mkdir -p $(OBJ_DIR)/$(dir $@) + @$(CC) $(CFLAGS) $(INCFLAGS) -c $< -o $(OBJ_DIR)/$@ + @$(OBJCOPY) --prefix-alloc-sections .boot $(OBJ_DIR)/$@ + @$(CC) -MM $(CFLAGS) $(INCFLAGS) $< -MT $@ -MF $(OBJ_DIR)/$(patsubst %.o,%.d,$@) + +-include $(DEPENDENCY_LIST) + +VPATH:=$(OBJ_DIR) $(SDK_PATH) + +#.PHONY: clean +clean: + rm -rf $(OBJ_DIR) $(BIN_DIR) $(OBJ_DIR)/$(SDK_PATH) + + \ No newline at end of file diff --git a/USDK/sdkset.mk b/USDK/sdkset.mk new file mode 100644 index 0000000..aa8635d --- /dev/null +++ b/USDK/sdkset.mk @@ -0,0 +1,415 @@ +#============================================= +# USER CONFIG (in project.mk) +#============================================= +#USE_AT = 1 +#USE_FATFS = 1 +#USE_SDIOH = 1 +#USE_POLARSSL = 1 +#USE_P2P_WPS = 1 +#USE_MBED = 1 +#USE_GCC_LIB = 1 +#ifndef USE_AT +#USE_NEWCONSOLE = 1 +#USE_WIFI_API = 1 +#endif +#RTOSDIR=freertos_v8.1.2 +#RTOSDIR=freertos_v9.0.0 +#LWIPDIR=lwip_v1.4.1 +# ------------------------------------------------------------------- +# FLAGS +# ------------------------------------------------------------------- +CFLAGS = -DM3 -DCONFIG_PLATFORM_8195A -DGCC_ARMCM3 -DARDUINO_SDK -DF_CPU=166666666L -DNDEBUG +CFLAGS += -mcpu=cortex-m3 -mthumb -g2 -Os -std=gnu99 -Wall -Werror +CFLAGS += -fno-common -fmessage-length=0 -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-short-enums -fsigned-char +CFLAGS += -w -Wno-pointer-sign +ifdef USE_GCC_LIB +LFLAGS = -mcpu=cortex-m3 -mthumb -g -Os -nostartfiles --specs=nano.specs +else +LFLAGS = -mcpu=cortex-m3 -mthumb -g -Os -nostartfiles -nostdlib +endif +LFLAGS += -Wl,--gc-sections -Wl,--cref -Wl,--entry=Reset_Handler -Wl,--no-enum-size-warning -Wl,--no-wchar-size-warning -Wl,-nostdlib + +# LIBS +# ------------------------------------------------------------------- +LIBS = +ifdef USE_GCC_LIB +all: LIBS +=_wlan _platform_new _wps _websocket _xmodem _mdns gcc m c nosys +mp: LIBS +=_wlan_mp _platform_new _wps _websocket _xmodem _mdns gcc m c nosys +else +all: LIBS +=_wlan _platform_new _wps _websocket _xmodem _mdns +mp: LIBS +=_wlan_mp _platform_new _wps _websocket _xmodem _mdns +endif +# m c nosys gcc +PATHLIBS = sdk/component/soc/realtek/8195a/misc/bsp/lib/common/gcc +LDFILE = rlx8195A-symbol-v04-img2.ld +BOOTS = sdk/component/soc/realtek/8195a/misc/bsp/image + +# Include folder list +# ------------------------------------------------------------------- +INCLUDES = ../inc +INCLUDES += project/inc +INCLUDES += sdk/component/soc/realtek/common/bsp +INCLUDES += sdk/component/os/freertos +INCLUDES += sdk/component/os/freertos/$(RTOSDIR)/Source/include +INCLUDES += sdk/component/os/freertos/$(RTOSDIR)/Source/portable/GCC/ARM_CM3 +INCLUDES += sdk/component/os/os_dep/include +INCLUDES += sdk/component/soc/realtek/8195a/misc/os +INCLUDES += sdk/component/soc/realtek/8195a/misc/driver +INCLUDES += sdk/component/common/api/network/include +INCLUDES += sdk/component/common/api +INCLUDES += sdk/component/common/api/platform +INCLUDES += sdk/component/common/api/wifi +INCLUDES += sdk/component/common/api/wifi/rtw_wpa_supplicant/src +INCLUDES += sdk/component/common/network +INCLUDES += sdk/component/common/network/lwip/$(LWIPDIR)/port/realtek/freertos +INCLUDES += sdk/component/common/network/lwip/$(LWIPDIR)/src/include +INCLUDES += sdk/component/common/network/lwip/$(LWIPDIR)/src/include/lwip +INCLUDES += sdk/component/common/network/lwip/$(LWIPDIR)/src/include/ipv4 +INCLUDES += sdk/component/common/network/lwip/$(LWIPDIR)/port/realtek +INCLUDES += sdk/component/common/test +INCLUDES += sdk/component/soc/realtek/8195a/cmsis +INCLUDES += sdk/component/soc/realtek/8195a/cmsis/device +INCLUDES += sdk/component/soc/realtek/8195a/fwlib +INCLUDES += sdk/component/soc/realtek/8195a/fwlib/rtl8195a +INCLUDES += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/ +INCLUDES += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/include +INCLUDES += sdk/component/common/drivers +INCLUDES += sdk/component/common/drivers/i2s +INCLUDES += sdk/component/common/drivers/wlan/realtek/include +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/osdep +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hci +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hal +INCLUDES += sdk/component/common/drivers/wlan/realtek/src/hal/OUTSRC +INCLUDES += sdk/component/common/drivers/sdio/realtek/sdio_host/inc +INCLUDES += sdk/component/soc/realtek/8195a/fwlib/ram_lib/wlan/realtek/wlan_ram_map/rom +INCLUDES += sdk/component/common/network/ssl/ssl_ram_map/rom +#INCLUDES += sdk/component/common/media/codec +#INCLUDES += sdk/component/common/drivers/usb_class/host/uvc/inc +#INCLUDES += sdk/component/common/drivers/usb_class/device +#INCLUDES += sdk/component/common/drivers/usb_class/device/class +#INCLUDES += sdk/component/soc/realtek/8195a/fwlib/ram_lib/usb_otg/include + +# Source file list +# ------------------------------------------------------------------- +SRC_C = +DRAM_C = +BOOT_C = + +#bootloader +SRC_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/rtl_bios_data.c +BOOT_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/rtl_boot.c + +#cmsis +SRC_C += sdk/component/soc/realtek/8195a/cmsis/device/system_8195a.c + +#console new/old +ifdef USE_NEWCONSOLE +SRC_C += sdk/component/soc/realtek/8195a/misc/driver/rtl_console_new.c +else +SRC_C += sdk/component/common/api/at_cmd/log_service.c +SRC_C += sdk/component/soc/realtek/8195a/misc/driver/rtl_consol.c +endif +ifdef USE_AT +DRAM_C += sdk/component/common/api/at_cmd/atcmd_ethernet.c +DRAM_C += sdk/component/common/api/at_cmd/atcmd_lwip.c +DRAM_C += sdk/component/common/api/at_cmd/atcmd_sys.c +DRAM_C += sdk/component/common/api/at_cmd/atcmd_wifi.c +endif +#SRC_C += sdk/component/soc/realtek/8195a/misc/driver/low_level_io.c + +#network - api +ifdef USE_P2P_WPS +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_p2p_config.c +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_wps_config.c +endif +SRC_C += sdk/component/common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/wifi_eap_config.c +SRC_C += sdk/component/common/api/wifi/wifi_conf.c +SRC_C += sdk/component/common/api/wifi/wifi_ind.c +SRC_C += sdk/component/common/api/wifi/wifi_promisc.c +SRC_C += sdk/component/common/api/wifi/wifi_simple_config.c +SRC_C += sdk/component/common/api/wifi/wifi_util.c +SRC_C += sdk/component/common/api/lwip_netconf.c +ifdef USE_WIFI_API +SRC_C += sdk/component/common/api/wifi_api.c +SRC_C += sdk/component/common/api/wifi_api_scan.c +endif + +#network - lwip +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/api_lib.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/api_msg.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/err.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/netbuf.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/netdb.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/netifapi.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/sockets.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/api/tcpip.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/autoip.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/icmp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/igmp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/inet.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/inet_chksum.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/ip.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/ip_addr.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/ipv4/ip_frag.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/def.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/dhcp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/dns.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/init.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/lwip_timers.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/mem.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/memp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/netif.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/pbuf.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/raw.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/stats.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/sys.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/tcp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/tcp_in.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/tcp_out.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/core/udp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/src/netif/etharp.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/port/realtek/freertos/ethernetif.c +SRC_C += sdk/component/common/drivers/wlan/realtek/src/osdep/lwip_intf.c +SRC_C += sdk/component/common/network/lwip/$(LWIPDIR)/port/realtek/freertos/sys_arch.c +SRC_C += sdk/component/common/network/dhcp/dhcps.c +SRC_C += sdk/component/common/network/sntp/sntp.c +SRC_C += sdk/component/common/network/netbios/netbios.c + +#network - mdns +#SRC_C += sdk/component/common/network/mDNS/mDNSPlatform.c + +#os - freertos +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/portable/MemMang/heap_5.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/portable/GCC/ARM_CM3/port.c +SRC_C += sdk/component/os/freertos/cmsis_os.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/croutine.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/event_groups.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/list.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/queue.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/tasks.c +SRC_C += sdk/component/os/freertos/$(RTOSDIR)/Source/timers.c + +#os - osdep +SRC_C += sdk/component/os/os_dep/device_lock.c +SRC_C += sdk/component/os/freertos/freertos_service.c +#SRC_C += sdk/component/os/os_dep/mailbox.c +SRC_C += sdk/component/soc/realtek/8195a/misc/os/mailbox.c +#SRC_C += sdk/component/os/os_dep/osdep_api.c +SRC_C += sdk/component/os/os_dep/osdep_service.c +#SRC_C += sdk/component/soc/realtek/8195a/misc/os/ +SRC_C += sdk/component/os/os_dep/tcm_heap.c + +ifdef USE_MBED +#peripheral - api +INCLUDES += sdk/component/common/mbed/api +INCLUDES += sdk/component/common/mbed/hal +INCLUDES += sdk/component/common/mbed/hal_ext +INCLUDES += sdk/component/common/mbed/targets/hal/rtl8195a +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/analogin_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/dma_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/efuse_api.c +#SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/ethernet_api.c +#SRC_C += sdk/component/common/drivers/ethernet_mii/ethernet_mii.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/flash_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/gpio_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/gpio_irq_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/i2c_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/i2s_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/log_uart_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/nfc_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pinmap.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pinmap_common.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/port_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/pwmout_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/rtc_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/serial_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/sleep.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/spdio_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/spi_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/sys_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/timer_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/us_ticker.c +SRC_C += sdk/component/common/mbed/common/us_ticker_api.c +SRC_C += sdk/component/common/mbed/common/wait_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/wdt_api.c +SRC_C += sdk/component/common/mbed/targets/hal/rtl8195a/flash_eep.c +endif + +#peripheral - hal +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_32k.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_adc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_gdma.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_gpio.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_i2c.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_i2s.c +#SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_mii.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_nfc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pcm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pwm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_sdr_controller.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_ssi.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_timer.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_uart.c +ifdef USE_SDIOH +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_sdio_host.c +SRC_C += sdk/component/common/drivers/sdio/realtek/sdio_host/src/sd.c +SRC_C += sdk/component/common/drivers/sdio/realtek/sdio_host/src/sdio_host.c +endif + +#peripheral - osdep +#SRC_C += sdk/component/os/freertos/freertos_pmu.c +SRC_C += sdk/component/soc/realtek/8195a/misc/os/freertos_pmu_8195a.c + +#peripheral - rtl8195a +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_adc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gdma.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_gpio.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2c.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_i2s.c +#SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_mii.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_nfc.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_pwm.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_ssi.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_timer.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/rtl8195a/src/rtl8195a_uart.c + +#peripheral - wlan +#SRC_C += sdk/component/common/drivers/wlan/realtek/src/core/option/rtw_opt_skbuf.c + +#SDRAM +#DRAM_C += sdk/component/common/api/platform/stdlib_patch.c +#SDRAM - polarssl +ifdef USE_POLARSSL +INCLUDES += sdk/component/common/network/ssl/polarssl-1.3.8/include + +SRC_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/bignum.c + +DRAM_C += sdk/component/common/network/ssl/ssl_ram_map/rom/rom_ssl_ram_map.c +DRAM_C += sdk/component/common/network/ssl/ssl_ram_map/ssl_ram_map.c + +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/aes.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/aesni.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/arc4.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/asn1parse.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/asn1write.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/base64.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/blowfish.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/camellia.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ccm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/certs.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/cipher.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/cipher_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ctr_drbg.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/debug.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/des.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/dhm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecp.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecp_curves.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecdh.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ecdsa.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/entropy.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/entropy_poll.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/error.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/gcm.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/havege.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/hmac_drbg.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md2.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md4.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/md5.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/memory_buffer_alloc.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/net.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/oid.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/padlock.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pbkdf2.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pem.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs5.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs11.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkcs12.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pk.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pk_wrap.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkparse.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/pkwrite.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/platform.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ripemd160.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/rsa.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha1.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha256.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/sha512.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_cache.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_ciphersuites.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_cli.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_srv.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/ssl_tls.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/threading.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/timing.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/version.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/version_features.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_crt.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_crl.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_csr.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509_create.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509write_crt.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/x509write_csr.c +DRAM_C += sdk/component/common/network/ssl/polarssl-1.3.8/library/xtea.c +endif + +#utilities - FatFS +ifdef USE_FATFS +INCLUDES += sdk/component/common/file_system/fatfs +INCLUDES += sdk/component/common/file_system/fatfs/r0.10c/include +SRC_C += sdk/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/diskio.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/ff.c +SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c +ifdef USE_SDIOH +SRC_C += sdk/component/common/file_system/fatfs/disk_if/src/sdcard.c +endif +endif + +# Reversed SDK component +#ADD_SRC_C += sdk/component/soc/realtek/8195a/cmsis/device/app_start.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_dac.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_common.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_soc_ps_monitor.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_efuse.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_log_uart.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_pinmux.c +SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_misc.c +#ADD_SRC_C += sdk/component/soc/realtek/8195a/fwlib/src/hal_spi_flash_ram.c +# Component clib, ... +SRC_C += sdk/component/soc/realtek/8195a/fwlib/ram_lib/startup.c +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libc.c +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_libgloss_retarget.c +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_eabi_cast_ram.c +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/rtl_math_ram.c +#if +- nostdlib.. +ifndef USE_GCC_LIB +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/ram_pvvx_libc.c +endif +#if c_printf() float +SRC_C += sdk/component/soc/realtek/8195a/misc/rtl_std_lib/lib_rtlstd/c_stdio.c +# ------------------------------------------------------------------- +# Add Source file list +# ------------------------------------------------------------------- +ADD_SRC_C = +# ------------------------------------------------------------------- +# SAMPLES +# ------------------------------------------------------------------- +ifdef USE_AT +INCLUDES += sdk/component/common/utilities +ADD_SRC_C += sdk/component/common/api/network/src/wlan_network.c +ADD_SRC_C += sdk/component/common/api/wifi_interactive_mode.c +ADD_SRC_C += sdk/component/common/api/network/src/ping_test.c +ADD_SRC_C += sdk/component/common/utilities/webserver.c +ADD_SRC_C += sdk/component/common/utilities/tcptest.c +ADD_SRC_C += sdk/component/common/utilities/update.c +INCLUDES += sdk/component/common/example +INCLUDES += sdk/component/common/example/wlan_fast_connect +ADD_SRC_C += sdk/component/common/example/wlan_fast_connect/example_wlan_fast_connect.c +ADD_SRC_C += sdk/component/common/example/uart_atcmd/example_uart_atcmd.c +ADD_SRC_C += sdk/component/common/example/example_entry.c +ADD_SRC_C += sdk/component/common/application/xmodem/uart_fw_update.c +endif diff --git a/project.mk b/project.mk index a0cb30d..eb289e6 100644 --- a/project.mk +++ b/project.mk @@ -1,7 +1,8 @@ #============================================= # SDK CONFIG #============================================= -WEB_INA219_DRV = 1 +#WEB_INA219_DRV = 1 +#WEB_ADC_DRV = 1 #USE_AT = 1 #USE_FATFS = 1 #USE_SDIOH = 1 @@ -37,6 +38,11 @@ ADD_SRC_C += project/src/driver/i2c_drv.c ADD_SRC_C += project/src/ina219/ina219drv.c CFLAGS += -DWEB_INA219_DRV=1 endif +ifdef WEB_ADC_DRV +ADD_SRC_C += project/src/driver/adc_drv.c +ADD_SRC_C += project/src/adc_ws/adc_ws.c +CFLAGS += -DWEB_ADC_DRV=1 +endif #Web-������ INCLUDES += project/inc/web diff --git a/project/inc/driver/adc_drv.h b/project/inc/driver/adc_drv.h new file mode 100644 index 0000000..d0ee13d --- /dev/null +++ b/project/inc/driver/adc_drv.h @@ -0,0 +1,23 @@ +/* + * Simple ADC DRV (adc_drv.h) + * + * Created on: 19 июн. 2017 г. + * Author: pvvx + */ + +#ifndef _DRIVER_ADC_DRV_H_ +#define _DRIVER_ADC_DRV_H_ + +#include "rtl8195a.h" +#include "rtl8195a_adc.h" + +void ADCIrqInit(IRQ_FUN IrqFunc, u32 IrqData, u32 intr_enable); // intr_enable = bits: REG_ADC_INTR_EN - BIT_ADC_FIFO_RD_ERROR_EN | BIT_ADC_FIFO_RD_REQ_EN | BIT_ADC_FIFO_FULL_EN ... +void ADCIrqDeInit(void); + +void ADCInit(ADC_MODULE_SEL adc_idx); // RTL8711AM: adc_idx = ADC2_SEL = 2 +void ADCDeInit(void); +void ADCEnable(void); // ADC Start +void ADCDisable(void); // ADC Stop + + +#endif /* _DRIVER_ADC_DRV_H_ */ diff --git a/project/inc/user_config.h b/project/inc/user_config.h index bef91de..0e57909 100644 --- a/project/inc/user_config.h +++ b/project/inc/user_config.h @@ -11,7 +11,8 @@ #define WEB_DEBUG_FUNCTIONS 1 // =1 - включить в WEB отладочные функции, =0 отключить (остается только конфигурация WiFi) -// #define WEB_INA219_DRV 1 (set in project.mk) +// #define WEB_INA219_DRV 1 (set in project.mk !) +// #define WEB_ADC_DRV 1 (set in project.mk !) #endif // _user_config_h_ diff --git a/project/src/adc_ws/adc_ws.c b/project/src/adc_ws/adc_ws.c new file mode 100644 index 0000000..af6c988 --- /dev/null +++ b/project/src/adc_ws/adc_ws.c @@ -0,0 +1,211 @@ +/* + * ADC + Websocket + * + * Created on: 18 июн. 2017 г. + * Author: pvvx + */ + +#include + +#include "rtl8195a.h" +#include "device.h" +#include "PinNames.h" + +#include "basic_types.h" +#include "diag.h" +#include "osdep_api.h" + +#include "FreeRTOS.h" +#include "diag.h" + +//------------------------------------------------------------------------------ +#include "objects.h" +#include "PinNames.h" +#include "hal_adc.h" +#include "analogin_api.h" +#include "timer_api.h" +//#include "strproc.h" + +#include "web_srv.h" +#include "websock.h" +#include "driver/adc_drv.h" +#include "rtl8195a/rtl_libc.h" + + +//------------------------------------------------------------------------------ +#define ADC_USE_TIMER TIMER3 // если назначено, то для чтения ADC используется таймер + // иначе ADC int +//------------------------------------------------------------------------------ + + +#ifndef CONFIG_MBED_ENABLED +#define malloc pvPortMalloc +#define zalloc pvPortZalloc +#define free vPortFree +#endif + +//------------------------------------------------------------------------------ +typedef union _adc_data { + unsigned short us; +} ADC_DATA, *PADC_DATA; + +typedef struct _adc_drv { + signed char init; // флаг + unsigned char tmp; + + unsigned short count; // счетчик считанных значений + unsigned short overrun; // счет переполнений буфера + + unsigned short buf_idx; // объем буфера pbuf[buf_idx+1], максимальный индекс-номер замера + unsigned short buf_rx; // индекс-номер ещё не считанного замера + unsigned short buf_tx; // индекс-номер для записи следующего замера + PADC_DATA pbuf; +#ifdef ADC_USE_TIMER + gtimer_t timer; +#endif +} ADC_DRV, *PADC_DRV; + +#define mMIN(a, b) ((ab)?a:b) + +ADC_DRV adc_drv = { + .buf_idx = (1460*2 - 80)/(sizeof(ADC_DATA)/2) // циклический буфер на ~1420 замеров (см. sizeof(ADC_DATA)) + // Если шаг заполнения 1 ms -> буфер на 1.4 сек + // Оптимизация под TCP: (TCP_MSS*2 - 80)/2 = (1460*2 - 80)/2 = 1420 +}; + +void adc_int_handler(void *par) { + PADC_DRV p = par; // &adc_drv + if(p->pbuf) { +#ifndef ADC_USE_TIMER + int i = 4; + while(i--) +#endif + { + PADC_DATA pd = p->pbuf + p->buf_tx; + pd->us = HAL_ADC_READ32(REG_ADC_FIFO_READ); // 2 -> sample -> 24.4 kHz (if ADC irq!) +// (void)HAL_ADC_READ32(REG_ADC_FIFO_READ); // 4 sample -> 12.2 kHz (if ADC irq!) +// (void)HAL_ADC_READ32(REG_ADC_FIFO_READ); // 6 sample -> 8.133 kHz (if ADC irq!) +// (void)HAL_ADC_READ32(REG_ADC_FIFO_READ); // 8 sample -> 6.1 kHz (if ADC irq!) + + if(p->buf_tx >= p->buf_idx) p->buf_tx = 0; + else p->buf_tx++; + if(p->buf_rx == p->buf_tx) { + p->overrun++; // todo: if(p->overrun++ > 100000) deinit() ? + if(p->buf_rx >= p->buf_idx) p->buf_rx = 0; + else p->buf_rx++; + }; + } + /* Clear ADC Status */ + (void)HAL_ADC_READ32(REG_ADC_INTR_STS); + }; +} + +size_t adc_getdata(void *pd, uint16 cnt) +{ + PADC_DRV p = &adc_drv; + if(p->init <= 0) return 0; + unsigned short *pus = (unsigned short *) pd; + taskDISABLE_INTERRUPTS(); + uint16 buf_rx = p->buf_rx; + *pus++ = cnt; // кол-во замеров + *pus++ = p->count + p->overrun; // индекс замера для анализа пропусков на стороне приемника + // если не пропущено, то равен прошлому + кол-во считанных замеров в прошлом блоке + p->count += cnt; // p->overrun = 0; + unsigned char *puc = (unsigned char *) pus; + if(cnt) { + uint16 lend = buf_rx + cnt; + if(lend > p->buf_idx) { + lend -= p->buf_idx + 1; + p->buf_rx = lend; + } else { + p->buf_rx = lend; + lend = 0; + }; + size_t len = (cnt - lend) *sizeof(ADC_DATA); + if(len) memcpy(puc, (void *)(p->pbuf + buf_rx), len); + if(lend) memcpy(puc + len, (void *)p->pbuf, lend *sizeof(ADC_DATA)); + } + taskENABLE_INTERRUPTS(); + return cnt * sizeof(ADC_DATA) + 4; +} + +uint16 adc_chkdata(uint16 cnt) +{ + PADC_DRV p = &adc_drv; + if(p->init <= 0) return 0; + int len = p->buf_tx - p->buf_rx; + if(len < 0) len += p->buf_idx + 1; + if(cnt > (uint16)len) cnt = (uint16)len; + return cnt; +} + +int adc_ws(TCP_SERV_CONN *ts_conn, char cmd) +{ + PADC_DRV p = &adc_drv; + switch(cmd) { + case 'd': // deinit + if(p->init > 0) { +#ifdef ADC_USE_TIMER + gtimer_stop(&p->timer); + gtimer_deinit(&p->timer); + ADCDisable(); +#else + ADCDisable(); + ADCIrqDeInit(); +#endif + ADCDeInit(); + if(p->pbuf) { + free(p->pbuf); + p->pbuf = NULL; + } + p->init = -1; + return 0; + } + return 1; + case 'c': // get count + return adc_chkdata(p->buf_idx + 1); + case 'i': // init + return p->init; + default: // get_data + if(p->init <= 0) { + p->count = 0; + p->overrun = 0; +// p->errs = 0; + if(!p->pbuf) { + p->pbuf = zalloc((p->buf_idx + 1) * sizeof(ADC_DATA)); + if(!p->pbuf) { + error_printf("Error create buffer!\n"); + return -1; + }; + p->buf_tx = 0; + p->buf_rx = 0; + }; + ADCInit(ADC2_SEL); +#ifdef ADC_USE_TIMER + // Initial a periodical timer + gtimer_init(&p->timer, ADC_USE_TIMER); + gtimer_start_periodical(&p->timer, 1000, (void*)adc_int_handler, (uint32_t)p); + rtl_printf("ADC Timer Period = %u us\n", &p->timer.hal_gtimer_adp.TimerLoadValueUs); +#else + ADCIrqInit(adc_int_handler,(uint32)p, BIT_ADC_FIFO_FULL_EN); // BIT_ADC_FIFO_RD_REQ_EN ? +#endif + ADCEnable(); + p->init = 1; +// return 0; + } + case 'g': // get + { + uint32 i = adc_chkdata(p->buf_idx + 1); + if(i) { + WEB_SRV_CONN *web_conn = (WEB_SRV_CONN *)ts_conn->linkd; + i = mMIN((web_conn->msgbufsize / sizeof(ADC_DATA)), i); + if(websock_tx_frame(ts_conn, WS_OPCODE_BINARY | WS_FRAGMENT_FIN, web_conn->msgbuf, adc_getdata(web_conn->msgbuf, i)) != ERR_OK) + return -1; + } + return i; + } + } + return -1; +} + diff --git a/project/src/driver/adc_drv.c b/project/src/driver/adc_drv.c new file mode 100644 index 0000000..897ebee --- /dev/null +++ b/project/src/driver/adc_drv.c @@ -0,0 +1,198 @@ +/* + * Simple ADC DRV (adc_drv.c) + * Created on: 18 июн. 2017 г. + * Author: pvvx + */ + +#include + +#include "platform_autoconf.h" +#include "diag.h" +#include "rtl8195a_adc.h" +#include "hal_adc.h" +#include "driver/adc_drv.h" + +//------------------------------------------------------------------------------ + +void ADCIrqInit(IRQ_FUN IrqFunc, u32 IrqData, u32 intr_enable) { + IRQ_HANDLE IrqHandle = { + .IrqNum = ADC_IRQ, + .Priority = 5 + }; + IrqHandle.Data = IrqData; + IrqHandle.IrqFun = IrqFunc; + InterruptRegister(&IrqHandle); + InterruptEn(&IrqHandle); + HAL_ADC_WRITE32(REG_ADC_INTR_EN, intr_enable); +} + +void ADCIrqDeInit(void) { + IRQ_HANDLE IrqHandle = { + .IrqNum = ADC_IRQ, + .Priority = 5, + .Data = (u32)NULL, + .IrqFun = (IRQ_FUN) NULL + }; + HAL_ADC_WRITE32(REG_ADC_INTR_EN, 0); + InterruptUnRegister(&IrqHandle); +} + +void ADCEnable(void) { + /* Clear ADC Status */ + (void)HAL_ADC_READ32(REG_ADC_INTR_STS); + u32 AdcTempDat = HAL_ADC_READ32(REG_ADC_POWER); + AdcTempDat &= (~BIT_ADC_PWR_AUTO); + AdcTempDat |= 0x02; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + AdcTempDat |= 0x04; + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + AdcTempDat &= (~0x08); + HAL_ADC_WRITE32(REG_ADC_POWER, AdcTempDat); + /* */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, + HAL_ADC_READ32(REG_ADC_ANAPAR_AD0) | BIT_ADC_EN_MANUAL); + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, + HAL_ADC_READ32(REG_ADC_ANAPAR_AD1) | BIT_ADC_EN_MANUAL); +} + +void ADCDisable(void) { +#if ADC_USE_IRQ + HAL_ADC_WRITE32(REG_ADC_INTR_EN, 0); +#endif + + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, + HAL_ADC_READ32(REG_ADC_ANAPAR_AD0) & (~BIT_ADC_EN_MANUAL)); + + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, + HAL_ADC_READ32(REG_ADC_ANAPAR_AD1) & (~BIT_ADC_EN_MANUAL)); + + HAL_ADC_WRITE32(REG_ADC_POWER, + HAL_ADC_READ32(REG_ADC_POWER) + & (~(BIT_ADC_PWR_AUTO))); +} + +#ifdef CONFIG_SOC_PS_MODULE +static void ADCEnablePS(void) +{ + REG_POWER_STATE adcPwrState; + // To register a new peripheral device power state + adcPwrState.FuncIdx = ADC0; + adcPwrState.PwrState = ACT; + RegPowerState(adcPwrState); +} +#endif + +void ADCInit(ADC_MODULE_SEL adc_idx) { + /* ADC Function and Clock Enable */ + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2, + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2) | BIT25); + /* Turn on DAC active clock */ + ACTCK_ADC_CCTRL(ON); + /* Enable DAC0 module */ + ADC0_FCTRL(ON); + /* Enable ADC power cut ? */ +// ADCEnablePW(); + /* ADC Control register set-up*/ + HAL_ADC_WRITE32(REG_ADC_CONTROL, + BIT_CTRL_ADC_COMP_ONLY(ADC_FEATURE_DISABLED) // compare mode only enable (without FIFO enable) + | BIT_CTRL_ADC_ONESHOT(ADC_FEATURE_DISABLED) // one-shot mode enable + | BIT_CTRL_ADC_OVERWRITE(ADC_FEATURE_DISABLED) // overwrite mode enable + | BIT_CTRL_ADC_ENDIAN(ADC_DATA_ENDIAN_LITTLE) // endian selection + | BIT_CTRL_ADC_BURST_SIZE(8) // DMA operation threshold + | BIT_CTRL_ADC_THRESHOLD(8) // one shot mode threshold + | BIT_CTRL_ADC_DBG_SEL(ADC_DBG_SEL_DISABLE)); +#if 0 + /* ADC compare value and compare method setting*/ + switch (adc_idx) { + case ADC0_SEL: + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_L, + (HAL_ADC_READ32(REG_ADC_COMP_VALUE_L) + & (~(BIT_ADC_COMP_TH_0(0xFFFF)))) + | BIT_CTRL_ADC_COMP_TH_0(0) // ADC compare mode threshold + ); + break; + case ADC1_SEL: + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_L, + (HAL_ADC_READ32(REG_ADC_COMP_VALUE_L) + & (~(BIT_ADC_COMP_TH_1(0xFFFF)))) + | BIT_CTRL_ADC_COMP_TH_1(0) // ADC compare mode threshold + ); + break; + case ADC2_SEL: + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_H, + (HAL_ADC_READ32(REG_ADC_COMP_VALUE_H) + & (~(BIT_ADC_COMP_TH_2(0xFFFF)))) + | BIT_CTRL_ADC_COMP_TH_2(0) // ADC compare mode threshold + ); + break; + + case ADC3_SEL: + HAL_ADC_WRITE32(REG_ADC_COMP_VALUE_H, + (HAL_ADC_READ32(REG_ADC_COMP_VALUE_H) + & (~(BIT_ADC_COMP_TH_3(0xFFFF)))) + | BIT_CTRL_ADC_COMP_TH_3(0) // ADC compare mode threshold + ); + break; + } + /* ADC compare mode setting */ + HAL_ADC_WRITE32(REG_ADC_COMP_SET, + HAL_ADC_READ32(REG_ADC_COMP_SET) + & (~(1 << adc_idx))); // compare mode control : less than the compare threshold +#endif + /* ADC audio mode set-up */ + /* ADC enable manually setting */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, + HAL_ADC_READ32(REG_ADC_ANAPAR_AD0) +// & (~(BIT_ADC_AUDIO_EN))) +// & (~(BIT_ADC_EN_MANUAL)) + | BIT_ADC_AUDIO_EN // ADC audio mode enable + | BIT_ADC_EN_MANUAL // ADC enable manually + ); + /* ADC analog parameter 0 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD0, + (HAL_ADC_READ32(REG_ADC_ANAPAR_AD0) +// & (~BIT14) //ADC Input is internal? + | (BIT14)) + & (~(BIT3|BIT2))); + /* ADC analog parameter 1 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD1, + (HAL_ADC_READ32(REG_ADC_ANAPAR_AD1) & (~BIT1)) | (BIT2|BIT0)); + /* ADC analog parameter 2 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD2, 0x67884400); + /* ADC analog parameter 3 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD3, 0x77780039); + /* ADC analog parameter 4 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD4, 0x0004d501); + /* ADC analog parameter 5 */ + HAL_ADC_WRITE32(REG_ADC_ANAPAR_AD5, 0x1E010800); +#ifdef CONFIG_SOC_PS_MODULE + ADCEnablePS(); +#endif +} + +void ADCDeInit(void) { +#ifdef CONFIG_SOC_PS_MODULE + REG_POWER_STATE adcPwrState; + u8 HwState; + adcPwrState.FuncIdx = ADC0; + QueryRegPwrState(adcPwrState.FuncIdx, &(adcPwrState.PwrState), &HwState); + // if the power state isn't ACT, then switch the power state back to ACT first + if ((adcPwrState.PwrState != ACT) && (adcPwrState.PwrState != INACT)) { + ADCEnablePS(); + QueryRegPwrState(adcPwrState.FuncIdx, &(adcPwrState.PwrState), &HwState); + } + if (adcPwrState.PwrState == ACT) { + adcPwrState.PwrState = INACT; + RegPowerState(adcPwrState); + } +#endif + /* Turn on DAC active clock */ + ACTCK_ADC_CCTRL(OFF); + /* Enable DAC1 module */ + ADC0_FCTRL(OFF); + /* To release DAC delta sigma clock gating */ + HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2, + HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_SYSPLL_CTRL2) & (~(BIT25))); +} + diff --git a/project/src/web/web_int_callbacks.c b/project/src/web/web_int_callbacks.c index 72fd6ce..cbfc6d5 100644 --- a/project/src/web/web_int_callbacks.c +++ b/project/src/web/web_int_callbacks.c @@ -450,6 +450,16 @@ extern int ina219_ws(TCP_SERV_CONN *ts_conn, char cmd); else tcp_puts("%d", x); } } +#endif +#ifdef WEB_ADC_DRV + else ifcmp("adc") { + if(CheckSCB(SCB_WEBSOC)) { +extern int adc_ws(TCP_SERV_CONN *ts_conn, char cmd); + int x = adc_ws(ts_conn, cstr[6]); + if(x < 0) SetSCB(SCB_FCLOSE|SCB_DISCONNECT); + else tcp_puts("%d", x); + } + } #endif else ifcmp("cfg_") { cstr += 4; diff --git a/userset.mk b/userset.mk index 081445c..5807fd4 100644 --- a/userset.mk +++ b/userset.mk @@ -1,8 +1,8 @@ #============================================= # User defined #============================================= -SDK_PATH ?= ../RTL00MP3/RTL00_SDKV35a/ -#SDK_PATH ?= ../SDKRTLA/USD40a/ +#SDK_PATH = ../RTL00MP3/RTL00_SDKV35a/ +SDK_PATH = USDK/ #GCC_PATH = d:/MCU/GNU_Tools_ARM_Embedded/5.2_2015q4/bin/# + or set in PATH #OPENOCD_PATH = d:/MCU/OpenOCD/bin/# + or set in PATH TOOLS_PATH ?= $(SDK_PATH)component/soc/realtek/8195a/misc/iar_utility/common/tools/